先附上优秀文章:

一个HashMap跟面试官扯了半个小时

阿里面试官没想到一个HashMap,我能跟他扯半小时

简单总结一些面试点出来:

HashMap的内部数据结构?

JDK1.8版本,内部使用数组 + 链表/红黑树

HashMap的数据插入原理?

  1. 判断数组是否为空,为空进行初始化;
  2. 不为空,计算 k 的 hash 值,通过(n - 1) & hash计算应当存放在数组中的下标 index;
  3. 查看 table[index] 是否存在数据,没有数据就构造一个Node节点存放在 table[index] 中;
  4. 存在数据,说明发生了hash冲突(存在二个节点key的hash值一样), 继续判断key是否相等,相等,用新的value替换原数据(onlyIfAbsent为false);
  5. 如果不相等,判断当前节点类型是不是树型节点,如果是树型节点,创造树型节点插入红黑树中;
  6. 如果不是树型节点,创建普通Node加入链表中;判断链表长度是否大于 8, 大于的话链表转换为红黑树;
  7. 插入完成之后判断当前节点数是否大于阈值,如果大于开始扩容为原数组的二倍。

HashMap的默认初始化长度是多少?为什么是这么大?

链表转红黑树的阀值是多少?为什么是这么大?

HashMap怎么设定初始容量大小?

1.8中做了哪些优化优化?

  1. 数组+链表改成了数组+链表或红黑树;
  2. 链表的插入方式从头插法改成了尾插法,简单说就是插入时,如果数组位置上已经有元素,1.7将新元素放到数组中,原始节点作为新节点的后继节点,1.8遍历链表,将元素放置到链表的最后;
  3. 扩容的时候1.7需要对原数组中的元素进行重新hash定位在新数组的位置,1.8采用更简单的判断逻辑,位置不变或索引+旧容量大小;
  4. 在插入时,1.7先判断是否需要扩容,再插入,1.8先进行插入,插入完成再判断是否需要扩容;

1.8中为什么要改为尾插法?

HashMap什么时候进行resize()?如何resize()?

HashMap的哈希函数怎么设计的?为什么这样设计?

HashMap是线程安全的吗?有什么解决方案么?


版权声明:文章转载请注明来源,如有侵权请联系博主删除!
最后修改:2020 年 05 月 11 日 11 : 06 AM
如果觉得我的文章对你有用,请随意赞赏
评论打卡也可以哦,您的鼓励是我最大的动力!