Java 常见面试题库

本文整理了 Java 后端开发中的常见面试题,帮助你在面试中脱颖而出。

一、Java 集合框架

1. ArrayList 和 LinkedList 的区别?

答:

ArrayList 底层是数组,查询快,按下标访问时间复杂度是 O(1),但中间插入和删除需要移动元素,效率较低。

LinkedList 底层是双向链表,查询慢,需要从头或尾遍历,时间复杂度是 O(n),但在已定位节点的情况下插入和删除较快。

实际开发中,大多数情况优先使用 ArrayList。

2. HashMap 和 Hashtable 的区别?

答:

HashMap 是非线程安全的,性能较高,允许 null key 和 null value。

Hashtable 是线程安全的,但使用 synchronized 修饰方法,性能较低,不允许 null key 和 null value。

现在一般不推荐使用 Hashtable,多线程场景推荐 ConcurrentHashMap。

3. HashMap 的底层原理?

答:

JDK 8 之后,HashMap 底层是数组 + 链表 + 红黑树。

put 时会先计算 key 的 hash 值,再根据 hash 值计算数组下标。如果该位置为空,直接放入;如果发生 hash 冲突,则使用链表或红黑树保存多个节点。当链表长度达到一定条件时,会转换成红黑树以提高查询效率。

4. HashMap 为什么线程不安全?

答:

HashMap 在多线程下同时 put、resize 或修改链表结构时,可能导致数据覆盖、数据丢失、结构异常等问题。

所以多线程环境不建议使用 HashMap,可以使用 ConcurrentHashMap。

5. HashSet 如何保证元素不重复?

答:

HashSet 底层基于 HashMap,它把元素作为 HashMap 的 key 存储。判断元素是否重复主要依赖 hashCode 和 equals 方法。如果两个对象 hashCode 相同,并且 equals 返回 true,就认为是重复元素。

6. 为什么重写 equals 必须重写 hashCode?

答:

因为 HashMap、HashSet 等哈希集合会先根据 hashCode 定位元素位置,再用 equals 判断是否相等。

如果两个对象 equals 相等,但 hashCode 不同,它们可能被放到不同位置,导致集合无法正确判断重复。

规范要求:

Text
如果两个对象 equals 相等,那么它们的 hashCode 必须相等。

7. ArrayList 默认容量是多少?

答:

JDK 8 中,ArrayList 创建时底层数组通常是空数组,第一次添加元素时才扩容到默认容量 10。之后容量不够时大约扩容为原容量的 1.5 倍。

8. HashMap 默认容量和负载因子是多少?

答:

默认初始容量是 16,默认负载因子是 0.75。

当元素数量超过容量乘以负载因子时,会触发扩容。

9. ConcurrentHashMap 为什么不允许 null?

答:

主要是为了避免并发场景下产生歧义。

例如 map.get(key) 返回 null 时,无法明确判断是 key 不存在,还是 value 本身就是 null。

在并发环境中,这种歧义会带来判断问题。

10. List、Set、Map 的区别?

答:

List 是有序、可重复的单列集合。

Set 是不允许重复的单列集合。

Map 是键值对集合,key 不允许重复,value 可以重复。