Java常用类库面试问答
1、String, StringBuffer, StringBuilder的区别
类 | 可变性 | 线程安全 | 性能 | 适用场景 |
String | 不可变 | ✅(天然安全) | 低(频繁操作需新建对象) | 常量字符串 |
StringBuffer | 可变 | ✅(同步方法) | 中等 | 多线程环境字符串操作 |
StringBuilder | 可变 | ❌ | 高 | 单线程环境字符串操作 |
2、 Error与Exception的区别
类别 | 继承关系 | 可恢复性 | 处理方式 | 示例 |
Error | Throwable子类 | ❌ 不可恢复 | 不应捕获(JVM级问题) | OutOfMemoryError |
Exception | Throwable子类 | ✅ 可恢复 | 需捕获或声明抛出 | IOException |
3、 常见的Error类
- OutOfMemoryError:内存耗尽
- StackOverflowError:栈溢出(如无限递归)
- NoClassDefFoundError:类定义缺失
- VirtualMachineError:JVM内部错误
4、常见的Exception
- 受检异常(Checked):
- IOException(文件操作)
- SQLException(数据库操作)
- ClassNotFoundException(类未找到)
- 非受检异常(Unchecked):
- NullPointerException(空指针)
- ArrayIndexOutOfBoundsException(数组越界)
- IllegalArgumentException(非法参数)
5、Java集合框架的核心接口有哪些?
- Collection(单元素集合)
- List:有序可重复(如 ArrayList)
- Set:无序唯一(如 HashSet)
- Queue:队列(如 LinkedList)
- Map(键值对集合)
- HashMap、TreeMap、ConcurrentHashMap
6、 ArrayList和LinkedList的区别
特性 | ArrayList | LinkedList |
底层结构 | 动态数组 | 双向链表 |
随机访问 | ✅ O(1) | ❌ O(n) |
插入/删除 | ❌ 尾部快,中间慢(需移动元素) | ✅ 任意位置快 O(1) |
内存占用 | 较小(仅存数据) | 较大(需存储前后节点引用) |
7、HashMap和TreeMap的区别
特性 | HashMap | TreeMap |
底层结构 | 数组+链表/红黑树(JDK8+) | 红黑树 |
排序 | ❌ 无序 | ✅ 按Key自然排序或自定义 |
性能 | O(1) 平均(哈希冲突影响) | O(log n)(树操作) |
允许null键 | ✅(1个) | ❌(需实现Comparable) |
8、HashSet和TreeSet的区别
特性 | HashSet(基于HashMap) | TreeSet(基于TreeMap) |
底层结构 | 哈希表 | 红黑树 |
排序 | ❌ 无序 | ✅ 元素自然排序 |
性能 | O(1) 平均 | O(log n) |
允许null元素 | ✅ | ❌(除非自定义比较器支持) |
9、ConcurrentHashMap 和 HashMap的区别
特性 | HashMap | ConcurrentHashMap |
线程安全 | ❌ | ✅ 分段锁/CAS(JDK7+) |
并发性能 | 不支持并发 | ✅ 高并发优化(锁粒度更细) |
允许null键值 | ✅ | ❌(设计约束) |
迭代器 | 快速失败(Fail-Fast) | 弱一致性(安全并发迭代) |
10、什么是LinkedHashMap?
LinkedHashMap 是 Java 中基于 HashMap 和双向链表的组合实现。
- 特点:
- 继承自HashMap,维护插入顺序或访问顺序(通过双向链表)。
- 支持按顺序迭代(如实现LRU缓存)。
- 示例:
Map<String, Integer> lmap = new LinkedHashMap<>(16, 0.75f, true); // 第三个参数true表示按访问顺序排序
11、 HashMap.put() 处理逻辑
1)计算Key的哈希值:hash = (key == null) ? 0 : hash(key)
2)根据(n-1) & hash确定桶位置(n为数组长度)。
3)桶为空:直接插入新节点。
4)桶非空:
- 若Key已存在(equals()匹配),更新Value。
- 若为树节点(红黑树),调用树插入方法。
- 若为链表,遍历到尾部插入(JDK8尾插法)。
5)链表转树:链表长度≥8且数组长度≥64时,链表转红黑树。
6)扩容:元素数超过容量×负载因子时,数组扩容2倍并重哈希。
12、 ConcurrentHashMap.put() 处理逻辑
1)计算Key的哈希值。
2)初始化桶数组:若数组为空,则延迟初始化(CAS操作)。
3)定位桶:(n-1) & hash 确定桶位置。
4)插入逻辑:
- 桶为空:CAS插入新节点。
- 桶非空:若桶为链表头:
- 同步锁(synchronized)链表头节点,遍历链表更新或插入。
- 若桶为红黑树根:同步锁根节点,执行树插入。
5)链表转树:链表长度≥8时,若数组长度<64则扩容;否则转红黑树。
6)计数:使用LongAdder(分片计数)统计元素数量,避免竞争。
#测试##测试面经##java学习##java#整理面试过程中的测试问答,常看常新,多多学习!有些问题是从其他人那里转载而来,会在文章下面注明出处,希望大家多多支持~~,觉得满意的话就送一朵小花花,谢谢! 内容目录:https://www.nowcoder.com/discuss/779856598809264128?sourceSSR=users