HashMap面试怎么面?
本文转载自微信公众号「Java时间屋」,试面作者Jack佳。试面转载本文请联系Java时间屋公众号。试面 1.HashMap的试面数据结构: 2.HashMap的hash函数设计: 3.Java1.8的Java1.7对比: 3.1 扰动的次数减少: 3.2 结构变化: 3.3 插入变化: 3.4 扩容的变化: 3.5 扩容的时间变化: 4.HashTable和Collections.synchronizedMap、以及ConcurrentHashMap可以实现线程安全的试面Map原理: 5.Map集合的顺序: 前言
HashMap是java面试的时候最常问的问题,其中牵扯的试面知识点很多,很适合考察面试的试面基础,我反正面试很多家这个问题确实是试面必问,不准备一番还真不好回答好。试面
1.HashMap的试面数据结构:
JDK1.8:数组+链表/红黑树 数据结构原理:链表长度>8&数组大小>=64=》转为红黑树存储;红黑树节点个数<6转为链表。tips:为什么不是试面小于8是为了防止频繁的结构转换增加开销。那为啥是试面8呢?发生hash碰撞的几率8次的概率为百万分之6,够了。源码库试面HashMap的试面数据插入原理:

重点说明:上面计算数组位置的方法是:通过 (n - 1) & hash计算应当存放在数组中的下标 index ;叫做位运算为啥(n-1)更接近于取模,为啥采用位运算是试面因为效率高,不存在二进制和十进制的转换。这里在补充一点HashMap初始化数组大小的问题,HashMap数组初始化大小为16,为啥呢?理论上来说2的整数次幂都可以,但是如果是2,4或者8就会有点小,添加不了多少数据就会扩容,影响性能,如果是32或者更大,就会浪费空间。所以16是一个经验值保留下来的。
2.HashMap的hash函数设计:
在HashMap中,首先是通过key的hashcode(32位的int值)然后让hashcode的高16位和低16位进行异或操作。为啥这样设计:1.上面的服务器租用hash函数也叫扰动函数,主要考虑尽可能降低hash碰撞,越分散越好。
2.算法一定要尽可能的高效,因为这是高频操作,因此采用位运算。
3.因为hashcode的范围是int类型,大概40亿的映射空间,如果只是hashcode,很少会出现碰撞,但是数组和内存是发放不下的,初始大小才16的数组只能进行取模运算/位运算来达到目的。
HashMap的数组长度要取2的整数幂,这样数组长度-1刚好"低位掩码",加上hash函数(扰动函数)降低碰撞。
3.Java1.8的Java1.7对比:
3.1 扰动的次数减少:
java1.8跟java1.7在这里的区别就hash函数里面是java8只扰动了一次,为了效率。java7在这里扰动了四次。免费源码下载
3.2 结构变化:
1.7里面的数组+链表===》数组+链表或红黑树。为什么这样做,前者的查询效率是n后者的查询效率是log2(n),所有当链表数据量大的时候会有效率问题。
3.3 插入变化:
链表的插入方式从头插法改成了尾插法,简单来说就是1.7中是往前面插入,1.8中是往后插入,这样做的目的是为了防止扩容的时候死循环。
3.4 扩容的变化:
扩容的时候1.7是重新hash定位新数组的位置,1.8则是采用更简单的逻辑判断,位置不变或索引+旧容量大小。为什么1.8能这样,计算数组的位置的掩码仅仅只是高位多了一个1。
3.5 扩容的时间变化:
在插入时,1.7先判断是否需要扩容再插入,1.8是插入以后再判断是不是需要扩容
4.HashTable和Collections.synchronizedMap、以及ConcurrentHashMap可以实现线程安全的Map原理:
我们都知道的是HashMap是线程不安全的,1.7版本的时候会产生死循环、数据丢失、数据覆盖的问题,1.8中解决了其中的两个问题,仍然会有数据覆盖的问题,就是多线程并发操作下的值覆盖。如果业务场景中需要线程安全,就要使用线程安全的Map类,一般我们使用的是ConcurrentHashMap。
ConcurrentHashMap:使用的分段锁,降低锁粒度,提高并发度和效率。1.8相对1.7也是提升了效率,成员变量之间使用了volatile修饰,避免了指令重排,保持内存可见。采用的CAS和synchronized结合实现赋值操作,只会锁住当前操作索引节点。

HashTable:直接在操作方法上synchronized关键字,锁住整个数组,效率会很低。SynchronizedMap:内部实现的对象锁实现。效率比HashTable会高点。
5.Map集合的顺序:
HashMap里面是无序的,所以只能循环遍历。LinkedHashMap:有序map,内部维护了一个单链表。单链表的before和after使其具有了有序的特性。TreeMap:内部通过Comprator比较器实现了排序。
总结
我上面的论述也是参考的网上我认为不错的针对HashMap的讲解,然后加入了我自己的理解,让大家能够更好的理解其中的原理内容,如果你有其他问题,欢迎关注我的公众号:Java时间屋 进行讨论。
相关文章
联想小新510si7(轻薄便携,细节出色,高效办公娱乐利器)
摘要:在当今信息高速发展的时代,人们对于笔记本电脑的要求越来越高。联想小新510si7作为一款性能强悍的高性能笔记本电脑,以其出色的表现和卓越的设计,成为了众多消费者眼中的首选。本文将从...2025-11-05
查询域名的建站历史有什么作用?查询域名建站历史用什么工具?很多米友喜欢使用聚查的建站历史查询功能,为什么大家购买域名要查询这个域名的历史建站信息呢?本文将给大家介绍相关知识。1、查询域名的建站历史有什2025-11-05
这段时间虽然因为疫情导致原本的一些工作有了延后,但是整体来说,大方向的事情还是基本成为定数。如果让我来选择今年要做的几件事情,我觉得有三股清流是需要关注的,也就是说不单单从技术层面来考虑,而是综合业务2025-11-05
现实世界中的机器学习解决方案很少只是构建和测试模型的问题。 到目前为止,从训练到优化,管理和自动化机器学习模型的生命周期是机器学习解决方案中最难解决的问题。 为了控制模型的生命周期,数据科学家需要能够2025-11-05- 摘要:电脑主板硬盘的分区是一个重要的步骤,它可以帮助我们更好地管理电脑上的数据。不正确的分区操作可能会导致数据丢失或硬盘损坏,因此学习正确的分区技巧非常重要。本文将为您详细介绍以电脑主板...2025-11-05
概念回顾首先我们回顾一下之前讲的基本概念:内存可见性「内存可见性,指的是线程之间的可见性,当一个线程修改了共享变量时,另一个线程可以读取到这个修改后的值」。重排序为优化程序性能,对原有的指令执行顺序进2025-11-05

最新评论