Java面试题更新 2026-08-05

请比较 Java 中 ConcurrentHashMap 在 JDK 1.7 与 1.8 版本之间的主要区别。

技术原理方案权衡Java

考察说明

考查对 ConcurrentHashMap 版本演进的理解,包括数据结构、并发机制及性能优化。

回答思路

  1. 【回答框架 1】1.7 采用分段锁结构,由 Segment 数组构成,每个 Segment 继承 ReentrantLock,锁粒度较粗,并发度受 Segment 数量限制。1.8 废除 Segment,使用 Node 数组加 CAS 和 synchronized 实现,锁粒度细化到单个桶。
  2. 【回答框架 2】1.8 在链表长度超过阈值(8)时转为红黑树,树化后查找时间复杂度从 O(n) 变为 O(log n),减少哈希冲突严重时的性能退化。1.7 仅使用链表,无树化机制。
  3. 【回答框架 3】put 操作:1.8 首先通过 CAS 尝试插入空桶,失败则使用 synchronized 锁定头节点,避免锁竞争;1.7 始终通过锁定 Segment 实现。size() 方法:1.8 使用 baseCount 和 CounterCell 累加,比 1.7 遍历 Segment 更高效。
  4. 【回答框架 4】扩容机制:1.8 支持多线程协助扩容,通过 ForwardingNode 标记迁移中的桶,提高扩容效率;1.7 扩容时需锁定整个 Segment,效率较低。整体上 1.8 在并发性能、内存占用和极端场景下表现更优。
  5. 【关键点 1】1.7 使用 Segment 分段锁,1.8 使用 Node 数组 + CAS + synchronized。
  6. 【关键点 2】1.8 在链表长度超过阈值时转为红黑树,提升查找性能。
  7. 【关键点 3】1.8 的 size() 和扩容采用更高效的并发机制,支持多线程协助扩容。
  8. 【易错点 1】不能简单说 1.8 绝对更快,需考虑具体场景,如小数据量下可能差异不大。
  9. 【易错点 2】树化阈值 8 是基于泊松分布的工程权衡,但具体行为受哈希分布影响,不能断言一定触发。
  10. 【易错点 3】扩容时的 ForwardingNode 标记需要理解,否则可能误解 get 操作在扩容期间的行为。