HashMap 面试全攻略

HashMap 面试全攻略(Java)

面试问 HashMap,本质就是在问:你到底懂不懂数据结构 + 并发 + JDK 演进

这份文档就是冲着"高级 / 资深 Java 面试"来的。


1. HashMap 是什么?

  • 基于 数组 + 链表 + 红黑树 的 Key-Value 数据结构
  • 非线程安全
  • 允许 null keynull value
  • JDK 1.8 之后:链表长度 ≥ 8 且数组长度 ≥ 64 → 链表转红黑树

2. HashMap 的核心数据结构

text 复制代码
Node<K,V>[] table

JDK 1.7

复制代码
数组 + 链表(头插法)

JDK 1.8

复制代码
数组 + 链表 + 红黑树(尾插法)

3. put() 底层流程(高频)

  1. 判断 table 是否为空 → resize
  2. 计算 hash
  3. (n - 1) & hash 定位桶位
  4. 桶为空 → 直接插入
  5. 桶不为空:
    • key 相同 → 覆盖
    • 链表 → 尾插
    • 判断是否树化
  6. 判断是否需要扩容

👉 面试金句

HashMap 的性能核心在于 hash 的均匀性 + 扩容成本控制


4. hash 为什么要高 16 位异或?

java 复制代码
hash = h ^ (h >>> 16)

原因

  • HashMap 的数组长度较小
  • 直接取低位容易冲突
  • 高低位混合,减少 hash 冲突

5. resize 扩容机制(必问)

  • 默认容量:16
  • 扩容因子:0.75
  • 扩容后容量:2 倍

JDK 1.8 的优化点

  • 不再重新 hash
  • 利用 (hash & oldCap) 判断新位置
text 复制代码
0 → 原位置
1 → 原位置 + oldCap

👉 扩容时间复杂度:O(n)


6. 为什么负载因子是 0.75?

权衡三点:

  • 空间利用率
  • 冲突概率
  • resize 成本

0.75 是 经验最优解,不是拍脑袋


7. 链表转红黑树的条件

同时满足:

  • 链表长度 ≥ 8
  • table.length ≥ 64

否则:优先扩容而不是树化

👉 这是为了避免小数组下树化带来的额外性能损耗


8. 为什么 JDK 1.7 用头插法,1.8 改成尾插?

JDK 1.7 问题

  • 扩容时可能 链表成环
  • 多线程 put → 死循环 100% CPU

JDK 1.8 改进

  • 尾插法
  • 扩容时顺序不变
  • 解决死循环问题(但依然不线程安全)

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

典型问题

  1. 数据覆盖
  2. resize 并发导致数据丢失
  3. size 不准
  4. JDK 1.7 死循环

👉 面试官想听的是:结构性原因,不是"没加锁"


10. HashMap vs ConcurrentHashMap

对比点 HashMap ConcurrentHashMap
线程安全
锁粒度 CAS + synchronized
性能 略低
null key 支持 不支持

11. equals & hashCode 的关系(送分题)

规则:

  • equals 相等 → hashCode 必须相等
  • hashCode 相等 → equals 不一定相等

👉 写自定义 key 必须 重写 hashCode + equals


12. 常见面试连环追问

Q1:HashMap 查找复杂度?

  • 理想:O(1)
  • 最坏(链表):O(n)
  • 红黑树:O(log n)

Q2:为什么容量必须是 2 的幂?

  • (n - 1) & hash 等价于 % n
  • 位运算更快
  • 分布更均匀

Q3:Hash 冲突怎么解决?

  • 拉链法
  • 树化

13. 高频面试总结(直接背)

  • HashMap 本质是 空间换时间
  • JDK 1.8 的核心升级是:
    • 红黑树
    • 尾插法
    • 高效 resize
  • 面试重点永远在:
    • put / get
    • resize
    • 并发问题

14. 一句话总结(终极)

HashMap 的精髓不是 API,而是 在冲突、扩容、并发之间做工程权衡


相关推荐
moxiaoran57531 天前
Java设计模式的运用
java·开发语言·设计模式
编程(变成)小辣鸡1 天前
Redisson 知识点及使用场景
java·redisson
Chasing Aurora1 天前
C++后端开发之旅(一)
java·开发语言·c++
码农水水1 天前
美团Java后端Java面试被问:Kafka的零拷贝技术和PageCache优化
java·开发语言·后端·缓存·面试·kafka·状态模式
optimistic_chen1 天前
【Redis系列】Java操作Redis客户端
java·linux·redis·客户端·服务端
千金裘换酒1 天前
LeetCode 两数之和 Java
java·算法·leetcode
sunddy_x1 天前
Spring IOC 入门
java·spring
计算机毕设指导61 天前
基于微信小程序的考研资源共享系统【源码文末联系】
java·spring boot·后端·考研·微信小程序·小程序·maven
qq_165901691 天前
spring-cloud读取Nacos上的配置
java·spring cloud·springcloud