为了可以在面试回答中优雅而不失体面回答面试考点,该文章借鉴了不一样平台对知识点的描述。node
HashMap 是一种存取高效但不保证有序的经常使用容器。它的数据结构为“数组+链表”,是解决哈希冲突的产物,也就是咱们常说的链地址法。它实现了Map 接口采用K-V 键值对存储数据,并实现了浅拷贝和序列化。面试
HashMap 的默认初始大小为16,初始化大小必须为2的幂,最大大小为2的30次方。数组中存储的链表节点Entry 类实现于Map.Entry 接口,它实现了对节点的通用操做。HashMap 的阈值默认为“容量*0.75f”,当存储节点数量超过该值,则对map 进行扩容处理。算法
HashMap 提供了4种构造方法,分别是默认构造方法;能够指定初始容量的构造方法;能够指定初始容量和阈值的构造方法以及基于一个Map 的构造方法。虽然是构造函数,可是真正的初始化都是在第一次添加操做里面实现的。数组
在第一次添加操做中,HashMap 会先判断存储数组有没有初始化,若是没有先进行初始化操做,初始化过程当中会取比用户指定的容量大的最近的2 的幂次方数做为数组的初始容量,并更新扩容的阈值。安全
接着添加操做讲吧。添加操做的执行流程为:数据结构
获取节点的操做和添加差很少,也是并发
HashMap 的其余操做大同小异,再讲讲HashMap1.7 的问题还有1.7 和1.8 的差异。函数
HashMap 是一个并发不安全的容器,在迭代操做是采用的是fast-fail 机制;在并发添加操做中会出现丢失更新的问题;由于采用头插法在并发扩容时会产生环形链表的问题,致使CPU 到达100%,甚至宕机。工具
解决并发问题能够采用.net
Hash1.7 和1.8 最大的不一样在于1.8 采用了“数组+链表+红黑树”的数据结构,在链表长度超过8 时,把链表转化成红黑树来解决HashMap 因链表变长而查询变慢的问题;其次
回答顺序:数据结构+继承结构+基本字段+构造方法+添加操做+扩容操做+获取操做+并发问题+与1.8的区别
HashMap 做为最基本的容器,它自己的设计与1.7 1.8的差别性致使HashMap 成为面试中最最高频的考点。因此掌握HashMap 势在必行,可是想要在各类宽泛的回答中脱颖而出,就必须对hashMap 来龙去脉了然于胸。
这些问题都要围绕一个点来回答:减小哈希冲突。
(1)容量必须为2 的幂是为了增长取值的可能性。
2 的n次幂转化为二进制为1后面n个0,在计算下标的时候是hash&(length - 1),也就是&(n-1)个1:初始容量为4->100,length-1 -> 11。全部的二进制为都为1有什么好处?
能够看出&1保证了取值的平均。若是某一位为0 ,好比最后一位,那么它&出来下标就必定是个偶数,减小了HashMap 数组一半的取值,大大增长了冲突的可能。
(2)负载因子为0.75f 是空间与时间的均衡
(3)hash() 的意义在于使hash 结果不一样 hash 算法的好坏直接影响hash 结构的效率,坏的hash 算法极端状况下可能会使hash 结构的存取效率从O(1)退化到O(n)。1.8 之因此把9 次扰动降到2 次,是出于计算效率的考虑。
int 和 String 的好处在于hash 出来的值不会改变。若是是一个对象,那么他们可能会由于内部引用的改变而hashCode 值的改变,会致使存储重复的数据或找不到数据的状况。
不只仅是HashMap 的东西,根据你的回答,面试官会引出不少其余的问题,因此你在本身设计回答的过程当中能够有意识引导面试官问出你熟悉的内容,安排的明明白白。
这篇文章更多的是HashMap 面试怎么答,以及须要注意的知识点,但愿对你有所帮助。
HashMap 的东西太多,因我的能力有限不能一一道全,后面若是变强了我会从新补全
推荐一篇关于HashMap 1.8 的比较好的博客: HashMap 1.8 重大更新