记一次HashMap面试

从网上已经身边同事朋友的面试情况来看,面试HashMap几乎是必问的,网上也很多类似的文章,但是真面起来,发现还是有很多点可以深抠的。本篇就结合一次面试经历说一下之前没有注意的点吧。

HashMap的底层结构

这个相信不用我多说,大家都知道HashMap的底层是Node数组结构Node<K,V>[] table

扩容也不用我多说了,在size达到阈值(默认0.75的负载因子*容量)时触发扩容。

数组的capacity大小是2的x幂也无需多言,但这里多问一句为什么是2的x幂而不是其他数呢?我们知道,当一个key被放进到数组时需要明确自己被放在哪个位置。最简单的当然就是对key进行hash之后h%n确定。而如果数组的长度n是2的x幂,h%n这个操作与h&(n-1)是等价的,会更快。同时在扩容时,每个key需要重新确定自己在数组中的index,这时如果数组每个位置的元素都变了一次,显然开销会比较大。但是如果n是2的x幂,那么在扩容变成2n后需要重新确认index时,对某个table[index]这个元素的新位置只有两种可能:1. 在原地不动(如果h&n的高位为0),2. index+nh&n的高位为1)。这样每个元素移动的概率只有50%,显然会节约很多拷贝操作。

HashMap中链表转红黑树

这个也是高频问点,大家也基本都清楚,JDK1.8之后,如果某位置的链表长度大于某个阈值之后,就会转为红黑树,防止链表深度过大,从而查询时复杂度达到o(n)最坏情况。但是细问起来,如果没有认真看过putVal方法中每一行代码,真的有的地方可能会忽略。比如:

  1. 链表长度达到多少之后开始转链表?你可能脱口而出8。但真的超过这个阈值8之后就会转树吗?我们跟进代码后会发现:还有另一个条件,即数组的长度如果小于MIN_TREEIFY_CAPACITY默认64这个值,会触发一次扩容而并不会执行转树操作,所以链表的长度是可以超过8的。
final void treeifyBin(Node<K,V>[] tab, int hash) {
int n, index; Node<K,V> e;
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
resize();
else if ((e = tab[index = (n - 1) & hash]) != null) {
TreeNode<K,V> hd = null, tl = null;
do {
TreeNode<K,V> p = replacementTreeNode(e, null);
if (tl == null)
hd = p;
else {
p.prev = tl;
tl.next = p;
}
tl = p;
} while ((e = e.next) != null);
if ((tab[index] = hd) != null)
hd.treeify(tab);
}
}
  1. 在转成红黑树时,每个key应该放在左子树还是右子树?这个由什么确定?因为HashMapkey并不要求是Comparable,而TreeMap很显然key是要满足Comparable的,那么此时新来一个TreeNode,左右确定以什么为依据呢?

    面试时在次数被面试官坑了一把,其实我们仔细想想,我们并不需要严格的确定某个TreeNode应该挂在它父节点的左边还是右边,挂在哪边都可以啊,只要我插入时按某个标准,查找时也按同样的标准,两者保持一致就可以了,对吧?跟到源代码,对于没有实现Comparablekey,比较一下hashCode就可以了。源码中的比较一句就是两个keyhashCode,使用的是System.identityHashCode(object)这个native方法。
        static int tieBreakOrder(Object a, Object b) {
int d;
if (a == null || b == null ||
(d = a.getClass().getName().
compareTo(b.getClass().getName())) == 0)
d = (System.identityHashCode(a) <= System.identityHashCode(b) ?
-1 : 1);
return d;
}

后记

还有大家都耳熟能详的东西我就不赘述了,面后也思考了一下,基础还是很重要,还是有很多指的深入思考的地方,一定要打牢基础,可能准备了很多框架原理实践什么的,如果基础的没答好,这些应用层的东西准备的再好,可能也没机会跟面试官聊了,当然在面试中如何去引导面试官这一点也很重要,俗话说的好,把对方拉倒跟我一个低智商区,然后用我丰富的经验打败他,这一点很重要,以后要多注意。

记一次HashMap面试的更多相关文章

  1. 从HashMap面试聊聊互联网内卷

    微信公众号:大黄奔跑 关注我,可了解更多有趣的面试相关问题. 写在之前 毫无疑问,回想2020年有什么词出现在眼前最多的,无疑是"996"和"内卷",从马老师的 ...

  2. 有关 HashMap 面试会问的一切

    前言 HashMap 是无论在工作还是面试中都非常常见常考的数据结构. 比如 Leetcode 第一题 Two Sum 的某种变种的最优解就是需要用到 HashMap 的,高频考题 LRU Cache ...

  3. 一万三千字的HashMap面试必问知识点详解

    目录 概论 Hasmap 的继承关系 hashmap 的原理 解决Hash冲突的方法 开放定址法 再哈希法 链地址法 建立公共溢出区 hashmap 最终的形态 Hashmap 的返回值 HashMa ...

  4. 对于大学4年的反思(续),记我的ThoughtWorks面试

    之前我写了一篇对于大学四年的反思,时隔一个月,为什么我这么快就要来写这篇续章呢?主要有两个原因,第一是感谢静子姐姐,记得知乎上有个回答里面说过人生需要有贵人的帮助,遇到贵人是一件很幸运的事情.我想,静 ...

  5. Java Web架构知识整理——记一次阿里面试经历

    惭愧,从一次电面说起.我个人在某国企做一名软件设计师,国企大家都懂的,待遇一般而且没啥意思,做的方向基本都是操作系统.驱动和工具软件的开发,语言基本都是C/C++.最近也想跳槽,刚好有幸得到了一次阿里 ...

  6. HashMap面试知识点

    HashMap的工作原理是近年来常见的Java面试题. 几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如 ...

  7. 你不得不知道的HashMap面试连环炮

    为什么用HashMap? 简述一下Map类继承关系? 解决哈希冲突的方法? 为什么HashMap线程不安全? resize机制? HashMap的工作原理是什么? 有什么方法可以减少碰撞? HashM ...

  8. 记一次Java面试问题点总结

    引言 昨日接了一个阿里外包的电话面试,问了一些技术问题感觉到自己是真的菜,接触Java开发已经也有一段时间,技术方面说来惭愧,一直以来只是局限于框架工具的用法,也没有进行了解其实现的原理,更重要的是一 ...

  9. HashMap面试知识点总结

    主要参考 JavaGuide 和 敖丙 的文章, 其中也有参考其他的文章, 但忘记保存链接了, 文中图片也是引用别的大佬的, 请见谅. 新手上路, 若有问题, 欢迎指正. 背景 HashMap 的相关 ...

随机推荐

  1. Linux内核分析作业 NO.1

    通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 于佳心 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/cour ...

  2. PowerDesigner16工具学习笔记-建立CDM

    1.基本术语 1.1.实体和属性 实体(entity):指现实世界中客观存在,并可相互区别的事物或者事件. 属性(attribute):一组用来描述实体特征的属性. 实体集(entity set):具 ...

  3. Daily Scrum - 11/25

    今天是Sprint 2的最后一天,我们在下午的课上对之前两个Sprint作了比较详尽的Review,并在课后Daily Scrum上讨论制订了Sprint 3的任务安排.具体Task会在明天更新在TF ...

  4. 正则的replace函数传参使用

    <script> var str = "a1ba2b"; var reg = /a.b/g; str = str.replace(reg,function(a,b){ ...

  5. Linux命令(八)过滤文本 grep

    grep 命令介绍 grep是一个强大的文本搜索工具命令,用于查找文件中符合指定格式的字符串,支持正则表达式.如不指定任何文件名称,或是文件名为 -,则gerp命令从标准输入设备中读取数据. grep ...

  6. BZOJ2428 HAOI2006均分数据(模拟退火)

    显然可以状压dp.显然过不了. 考虑暴力模拟退火.每次随机改变一个数所属集合即可. 并不明白要怎么调参. #include<iostream> #include<cstdio> ...

  7. Cat VS Dog HDU - 3829 (最大独立集 )

    Cat VS Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)Total ...

  8. 【BZOJ1965】[AHOI2005]洗牌(数论)

    [BZOJ1965][AHOI2005]洗牌(数论) 题面 BZOJ 洛谷 题解 考虑反过来做这个洗牌的操作,假定当前牌是第\(l\)张. 因为之前洗的时候考虑了前一半和后一半,所以根据\(l\)的奇 ...

  9. suoi14 子树查找 (dfs)

    把询问记下来,然后开个桶差分 #include<bits/stdc++.h> #define pa pair<int,int> #define lowb(x) ((x)& ...

  10. 前端学习 -- Html&Css -- 相对定位 绝对定位 固定定位

    相对定位 - 定位指的就是将指定的元素摆放到页面的任意位置,通过定位可以任意的摆放元素. - 通过position属性来设置元素的定位. -可选值: static:默认值,元素没有开启定位: rela ...