Java工程师面试冲刺

 
 
1.#### 基本数据类型和引用类型

基本数据类型:8种,
byte,short,int,long,char,float,double,boolean

引用类型:除了基本数据类型其他的都是引用,即对象:类class、接口、数组

2.抽象类和接口
抽象类可以有构造方法,接口中不能有构造方法。
抽象类中可以有普通成员变量,接口中没有普通成员变量!!!!!!!(注意重点在 普通 即 非静态 和 变量!!!!)
抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
抽象类中的抽象方法的访问类型可以是public,protected,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型,由于private方法不能被覆写。
3.hashCode() 与 equals()

equals()相等的两个对象,hashcode()一定相等,equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashCode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)

equals和==的区别
对于基本类型,==是值是否相同
对于对象:==比较内存地址,equals方法不重写的话比较内存地址,如果重写以重写的为准,比如String的equals()方法

4.模式

单例模式
基本思路:static A = new A();懒汉式
public A getA() {}
private A() {}构造方法私有化

如果A需要做复杂的事情,则static A a = null;
private A() {}构造方法私有化
public synchronized A getA() {
if (a == null) a= new A();
return a;
}

工厂模式

简单工厂模型来讲解一下

//通过接口实现不同功能的实现类
interface Fruit{
void doMethod();
};
接口对应的实现:
public Apple implements Fruit() {
public void deMethod() {
//do thing
}
}
public Orange implements Fruit() {
public void deMethod() {
//do thing
}
}
工程类:
public FruitFactory{
public Fruit getFruit(String type) {
if (type.equals(“apple”)) return new Apple();
else if (type.equals(“orange)) return new Orange();
return null;
}
}

5.hashMap和hashTable区别,底层是如何实现的
hashMap底层是如何实现的呢?
HashMap是通过”拉链法”实现的哈希表【是通过“拉链法”解决哈希冲突】。它包括几个重要的成员变量:table, size, threshold, loadFactor, modCount。
table是一个Entry[]数组类型,而Entry实际上就是一个单向链表。哈希表的”key-value键值对”都是存储在Entry数组中的。
size是HashMap的大小,它是HashMap保存的键值对的数量
threshold是HashMap的阈值,用于判断是否需要调整HashMap的容量。threshold的值=”容量*加载因子”,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。
loadFactor就是加载因子
modCount是用来实现fail-fast机制的
fail-fase机制【fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。】
map是否是有序的,treeMap和treeSet
他们底层是数据结构的实现是:维护了一棵二叉树。 容器中添加元素的时候,他们有是怎么判断是否有相同元素的?我们都直到 TreeMap TreeSet 她们 都是 有序的存储数据。 为了维护 数据的唯一性。 再存入数据的时候,他们会调用元素中 实现的 Comparable 的 compareTo() 方法 或者 集合本身创建的时候 传入了 迭代器. 具体的实现是:调用比较方法,返回-1 的时候,添加到左子树,返回1 的时候 添加到 右子树。返回0 有相同数据 不添加该元素!
6.LinkedList,ArrayList区别

ArrayList基于数组实现

  • ArrayList 实际上是通过一个数组去保存数据的。当我们构造ArrayList时;若使用默认构造函数,则ArrayList的默认容量大小是10
  • 当ArrayList容量不足以容纳全部元素时,ArrayList会重新设置容量:新的容量=“(原始容量x3)/2 + 1”。
  • ArrayList的克隆函数,即是将全部元素克隆到一个数组中。
  • ArrayList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写入“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。
LinkedList基于双向链表实现
(01) LinkedList 实际上是通过双向链表去实现的。
它包含一个非常重要的内部类:Entry。Entry是双向链表节点所对应的数据结构,它包括的属性有:当前节点所包含的值,上一个节点,下一个节点
(02) 从LinkedList的实现方式中可以发现,它不存在LinkedList容量不足的问题
(03) LinkedList的克隆函数,即是将全部元素克隆到一个新的LinkedList对象中

7.ConcurrentHashMap和Hashtable主要区别就是围绕着锁的粒度以及如何锁
ConcurrentHashMap将hash表分为16个桶(默认值),诸如get,put,remove等常用操作只锁当前需要用到的桶。试想,原来只能一个线程进入,现在却能同时16个写线程进入(写线程才需要锁定,而读线程几乎不受限制,之后会提到),并发性的提升是显而易见的。
更令人惊讶的是ConcurrentHashMap的读取并发,因为在读取的大多数时候都没有用到锁定,所以读取操作几乎是完全的并发操作,而写操作锁定的粒度又非常细,比起之前又更加快速(这一点在桶更多时表现得更明显些)。只有在求size等操作时才需要锁定整个表。
ConcurrentHashMap将hash表分为16个桶(默认值),诸如get,put,remove等常用操作只锁当前需要用到的桶。试想,原来只能一个线程进入,现在却能同时16个写线程进入(写线程才需要锁定,而读线程几乎不受限制,之后会提到),并发性的提升是显而易见的。
更令人惊讶的是ConcurrentHashMap的读取并发,因为在读取的大多数时候都没有用到锁定,所以读取操作几乎是完全的并发操作,而写操作锁定的粒度又非常细,比起之前又更加快速(这一点在桶更多时表现得更明显些)。只有在求size等操作时才需要锁定整个表
了解:在迭代时,ConcurrentHashMap使用了不同于传统集合的快速失败迭代器(见之前的文章《JAVA API备忘—-集合》)的另一种迭代方式,我们称为弱一致迭代器。在这种迭代方式中,当iterator被创建后集合再发生改变就不再是抛出ConcurrentModificationException,取而代之的是在改变时new新的数据从而不影响原有的数据,iterator完成后再将头指针替换为新的数据,这样iterator线程可以使用原来老的数据,而写线程也可以并发的完成改变,更重要的,这保证了多个线程并发执行的连续性和扩展性,是性能提升的关键
8.Sring和StringBuffer,StringBuilder区别
String内部是final char[],另外String str = “123”直接分配到运行时常量池,内存中仅一份
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的
9.#### 字节流与字符流

字节流和字符流可以相互转换,以文件为例,字符流存储在硬盘上的也是二进制文件,只是二进制流可以按照编码转换为字符

IO流中一定要注意编码,否则就可以发生硬转码的情况

10.NIO相关知识点
Java NIO 由以下几个核心部分组成:
Channels(通道)
Buffers(缓存区)
Selectors(选择器)

选择器(Selectors):
Java NIO的选择器 允许一个单独的线程来监视多个输入通道 ,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道 :可以选择这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

其实NIO的核心是IO线程池,一定要记住这个关键点。


NIO本身是基于事件驱动思想来完成的,其主要想解决的是网络编程的大并发问题


11.递归读取文件夹下的文件
  1. public void traverseFolder2(String path){
  2. File file =newFile(path);
  3. if(file.exists()){
  4. File[] files = file.listFiles();
  5. if(files.length==0){
  6. System.out.println("文件夹是空的!");
  7. return;
  8. }else{
  9. for(File file2: files){
  10. if(file2.isDirectory()){
  11. System.out.println("文件夹:"+ file2.getAbsolutePath());
  12. traverseFolder2(file2.getAbsolutePath());
  13. }else{
  14. System.out.println("文件:"+ file2.getAbsolutePath());
  15. }
  16. }
  17. }
  18. }else{
  19. System.out.println("文件不存在!");
  20. }
  21. }

如果用非递归的方式的话,就要用到list了,然后list不为空进行循环了,如下:

 
 
  1. public void traverseFolder1(String path) {
  2. int fileNum = 0, folderNum = 0;
  3. File file = new File(path);
  4. if (file.exists()) {
  5. LinkedList<File> list = new LinkedList<File>();
  6. File[] files = file.listFiles();
  7. for (File file2 : files) {
  8. if (file2.isDirectory()) {
  9. System.out.println("文件夹:" + file2.getAbsolutePath());
  10. list.add(file2);
  11. fileNum++;
  12. } else {
  13. System.out.println("文件:" + file2.getAbsolutePath());
  14. folderNum++;
  15. }
  16. }
  17. File temp_file;
  18. while (!list.isEmpty()) {
  19. temp_file = list.removeFirst();
  20. files = temp_file.listFiles();
  21. for (File file2 : files) {
  22. if (file2.isDirectory()) {
  23. System.out.println("文件夹:" + file2.getAbsolutePath());
  24. list.add(file2);
  25. fileNum++;
  26. } else {
  27. System.out.println("文件:" + file2.getAbsolutePath());
  28. folderNum++;
  29. }
  30. }
  31. }
  32. } else {
  33. System.out.println("文件不存在!");
  34. }
  35. System.out.println("文件夹共有:" + folderNum + ",文件共有:" + fileNum);
  36. }
数据库隔离级别,举例说明
事务定义
事务(Transaction)是访问并可能更新数据库中各种 数据项的一个程序执行单元(unit)。事务通常由 高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的 用户程序的执行所引起,并用形如 begin transactionend transaction语句(或 函数调用)来界定。事务由事务开始( begin transaction)和事务结束( end transaction)之间执行的全体操作组成。 例如:在 关系数据库 中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。
数据库事务的四个特性及含义
  1. 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
  2. 一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
  3. 隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
  4. 持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值