系列文章目录
2023年Java面试题
目录
- 系列文章目录
- Java基础
- 一、String、StringBuffer、StringBuilder之间有什么区别?
- 二、抽象类能使用 final 修饰吗?
- 三、final、finally、finalize 有什么区别?
- 四、访问修饰符public,private,protected,以及不写(默认)时的区别?
- 五、方法重载和方法重写的区别
- 六、抽象类与接口的区别
- 七、List、Set、Map 之间的区别是什么?
- 八、HashMap 和 Hashtable 有什么区别?
- 九、HashMap 的实现原理?
- 十、HashSet 的实现原理?
- 十一、如何解决Hash冲突?
- 十二、ArrayList 和 LinkedList 的区别是什么?
- 十三、Array 和 ArrayList 有何区别?
- 十四、throw 和 throws 的区别?
- 十五、try-catch-finally 中哪个部分可以省略?
Java基础
一、String、StringBuffer、StringBuilder之间有什么区别?
它们的区别在于 String是final修饰的,是不可变的,每次操作都会生成新的 String 对象,然后再去引用这个新的 String 对象,
而 StringBuffer、StringBuilder 是在原有对象的基础上进行操作的,不会每次操作都生成新的对象,所以在经常需要改变字符串内容的情况下最好不要使用 String。
StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,
所以StringBuilder 的性能要高于 StringBuffer,在单线程环境下可以使用 StringBuilder,多线程环境下可以使用 StringBuffer。
二、抽象类能使用 final 修饰吗?
不能,抽象类就是让其他类继承的,如果使用 final 该类就不能被继承了,这样的话抽象类就没有存在的意义了
三、final、finally、finalize 有什么区别?
final:是修饰符,它可以修饰类,方法和变量,被final修饰的类不能被继承,被final修饰的方法不能被重写,被final修饰的变量不能被再次赋值
finally:是异常处理语句中的一部分,这部分可以省略,finally中的语句是一定会执行的,即使在这之前遇到return也会执行
finalize: 是 Object 类的一个方法,在垃圾回收器回收对象时就会调用对象的finalize方法。
四、访问修饰符public,private,protected,以及不写(默认)时的区别?
private 只能被自己访问
默认 可以被本类及同一个包中的类访问
protected 可以被本类、子类及同一个包中的类访问
public 可以被所有其他类访问
五、方法重载和方法重写的区别
重写
方法重写体现在类与类之间的继承关系上。 在Java中,子类继承父类,就会具备父类的所有特征,比如不是private修饰的方法和变量。
如果父类提供的方法不能满足子类的需求,子类就可以对父类的方法进行重写。方法重写的要求是方法名、参数列表必须相同。
重载
方法重载是指在一个类中定义多个同名的方法,它们的方法名相同,参数列表不同
可以是参数的个数不同,或者是类型不同,或者是顺序不同。
调用方法时通过传递给它们的不同参数的类型,或者是个数,或者是顺序来决定具体使用哪个方法。
六、抽象类与接口的区别
抽象类体现的是继承关系(extends),接口体现的是实现关系(implements),一个类可以实现多个接口,而类与类之间只能单继承,但是可以间接继承多个类。
抽象类中可以定义,普通方法,静态方法,抽象方法,而接口中只能有抽象方法。
抽象类中可以有构造方法,而接口中不可以有构造方法
抽象类中的抽象方法的权限修饰符可以是public,protected,但接口中的抽象方法只能是public类型的,并且默认就是public abstract。
七、List、Set、Map 之间的区别是什么?
List、Set、Map 的区别主要体现在两个方面:元素是否有序、是否允许元素重复。
List
元素有序,可重复
Set
HashSet
元素无序,不可重复
TreeSet
元素有序(二叉树排序),不可重复
Map
HashMap
元素无序,key必须唯一,value可重复
TreeMap
元素有序(二叉树排序),key必须唯一,value可重复
八、HashMap 和 Hashtable 有什么区别?
HashMap
HashMap的key和value,都允许为null。
HashMap是线程不安全的。在效率上要优于HashTable。
HashMap的底层是:数组+链表+红黑树。从jdk8开始如果链表长度达到8,并且数组长度到64链表则转变为红黑树,当链表长度低于6则将红黑树转回链表。
HashTable
HashTable是线程安全的,在效率上要低于HashMap。
HashTabl的key和value,都不允许为null。
九、HashMap 的实现原理?
HashMap 基于 Hash 算法实现的,在传入 key 的时候计算key的hash 值,根据 hash 值将 value 保存在对应的桶里。如果计算出的 hash 值相同时,就是出现了 hash 冲突,
HashMap 的做法是用链地址法解决hash冲突,之后用链表或红黑树存储相同 hash 值的 value。
十、HashSet 的实现原理?
HashSet 底层其实就是 HashMap,所以基本上HashSet 的所有操作,都是直接调用底层 HashMap 的方法来实现的。
十一、如何解决Hash冲突?
开放定址法
开放定址法就是当发生冲突时,就去寻找下一个空的散列地址,只要散列表足够大,总能找到空的散列地址。
再哈希法
再哈希法就是有多个不同的Hash函数,当发生冲突时,使用其他哈希函数计算Hash地址,直到没有冲突为止。
链地址法
链地址法就是当发生冲突时,以链表的形式进行追加元素。简单来说就是被分配到同一个索引上的元素用指针连接起来形成一个单向链表。
十二、ArrayList 和 LinkedList 的区别是什么?
ArrayList是基于动态数组实现的,内存地址是连续的而且有索引这个概念,比较适合做查询操作,
不适合做增删操作(尤其是在中间插入或删除元素,因为会导致后面的数据都要向前或者向后移动),
然后当存入的元素超过了ArrayList的长度时,还会进行扩容。就是会新建一个比旧数组大1.5倍左右的新数组,然后把旧数组中的数据拷贝到新数组中,重新引用新数组。
LinkedList是基于双向链表实现的,链表中的每一个元素都用指针的方式来记住它的前一个和后一个元素,当插入或者删除节点时,
只需要修改几个元素之间的引用关系就行了,不会造成数据的大量移动。所以比较适合做增删操作
不适合做查询操作,因为每一次查询元素时都需要从头节点开始一个一个往下遍历
十三、Array 和 ArrayList 有何区别?
数组可以存储基本数据类型和引用数据类型,ArrayList 只能存储引用数据类型。
数组的大小是指定的固定的,而 ArrayList 大小是可以自动扩容的。
十四、throw 和 throws 的区别?
throw:是真的抛出一个异常。
throws:是声明可能会抛出一个异常。
十五、try-catch-finally 中哪个部分可以省略?
catch 和 finally 都可以被省略,但是只能省略其中一个