记一次HashMap面试
记一次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+n(h&n的高位为1)。这样每个元素移动的概率只有50%,显然会节约很多拷贝操作。
HashMap中链表转红黑树
这个也是高频问点,大家也基本都清楚,JDK1.8之后,如果某位置的链表长度大于某个阈值之后,就会转为红黑树,防止链表深度过大,从而查询时复杂度达到o(n)最坏情况。但是细问起来,如果没有认真看过putVal方法中每一行代码,真的有的地方可能会忽略。比如:
- 链表长度达到多少之后开始转链表?你可能脱口而出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);
}
}
- 在转成红黑树时,每个
key应该放在左子树还是右子树?这个由什么确定?因为HashMap的key并不要求是Comparable,而TreeMap很显然key是要满足Comparable的,那么此时新来一个TreeNode,左右确定以什么为依据呢?
面试时在次数被面试官坑了一把,其实我们仔细想想,我们并不需要严格的确定某个TreeNode应该挂在它父节点的左边还是右边,挂在哪边都可以啊,只要我插入时按某个标准,查找时也按同样的标准,两者保持一致就可以了,对吧?跟到源代码,对于没有实现Comparable的key,比较一下hashCode就可以了。源码中的比较一句就是两个key的hashCode,使用的是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面试的更多相关文章
- 从HashMap面试聊聊互联网内卷
微信公众号:大黄奔跑 关注我,可了解更多有趣的面试相关问题. 写在之前 毫无疑问,回想2020年有什么词出现在眼前最多的,无疑是"996"和"内卷",从马老师的 ...
- 有关 HashMap 面试会问的一切
前言 HashMap 是无论在工作还是面试中都非常常见常考的数据结构. 比如 Leetcode 第一题 Two Sum 的某种变种的最优解就是需要用到 HashMap 的,高频考题 LRU Cache ...
- 一万三千字的HashMap面试必问知识点详解
目录 概论 Hasmap 的继承关系 hashmap 的原理 解决Hash冲突的方法 开放定址法 再哈希法 链地址法 建立公共溢出区 hashmap 最终的形态 Hashmap 的返回值 HashMa ...
- 对于大学4年的反思(续),记我的ThoughtWorks面试
之前我写了一篇对于大学四年的反思,时隔一个月,为什么我这么快就要来写这篇续章呢?主要有两个原因,第一是感谢静子姐姐,记得知乎上有个回答里面说过人生需要有贵人的帮助,遇到贵人是一件很幸运的事情.我想,静 ...
- Java Web架构知识整理——记一次阿里面试经历
惭愧,从一次电面说起.我个人在某国企做一名软件设计师,国企大家都懂的,待遇一般而且没啥意思,做的方向基本都是操作系统.驱动和工具软件的开发,语言基本都是C/C++.最近也想跳槽,刚好有幸得到了一次阿里 ...
- HashMap面试知识点
HashMap的工作原理是近年来常见的Java面试题. 几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如 ...
- 你不得不知道的HashMap面试连环炮
为什么用HashMap? 简述一下Map类继承关系? 解决哈希冲突的方法? 为什么HashMap线程不安全? resize机制? HashMap的工作原理是什么? 有什么方法可以减少碰撞? HashM ...
- 记一次Java面试问题点总结
引言 昨日接了一个阿里外包的电话面试,问了一些技术问题感觉到自己是真的菜,接触Java开发已经也有一段时间,技术方面说来惭愧,一直以来只是局限于框架工具的用法,也没有进行了解其实现的原理,更重要的是一 ...
- HashMap面试知识点总结
主要参考 JavaGuide 和 敖丙 的文章, 其中也有参考其他的文章, 但忘记保存链接了, 文中图片也是引用别的大佬的, 请见谅. 新手上路, 若有问题, 欢迎指正. 背景 HashMap 的相关 ...
随机推荐
- 毕业设计---json,Struts,ajax以及JQuery简单案例
<!-- Struts2的xml文件配置 --><struts> <package name="default" namespace="/& ...
- linux终端FQ
工具列表: shadowsocks - QT5 ss账号 proxychains 使用过程: 1.用shadowsocks - QT5登入ss,设置本机端口1080 2.proxychains的使用 ...
- 基于python的机器学习实现日元币对人民币汇率预测
## 导入所需的包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import tensorflow a ...
- java之JDBC学习总结
以前一直以为jdbc是很高大上的东西,没想到今天学了jdbc,惊喜来了,just a tool!当然工具是用来帮助人们学习和提供方便的,所以总结了一下,也就是简单的三板斧: first :加载驱动 t ...
- PHP 爬虫——QueryList
前言: 来了个任务说要做个电影网站,要写个壳,数据直接从别人那扒.行吧!那就要学习下PHP爬虫了.占个博客,以后补充.http://study.querylist.cc/archives/6/ 之前开 ...
- Beta冲刺——day4
Beta冲刺--day4 作业链接 Beta冲刺随笔集 github地址 团队成员 031602636 许舒玲(队长) 031602237 吴杰婷 031602220 雷博浩 031602134 王龙 ...
- 评论beta发布
1. 组名:飞天小女警 项目名:礼物挑选小工具 评价:该系统可以通过选择所要接礼的人的性别.年龄和与送礼者的关系及所要送礼的价值,就可以推荐出所送的礼物.还可以通过男/女所选的Top前10进行简单推荐 ...
- SVN for Mac
SVN for Mac https://www.wikihow.com/Install-Subversion-on-Mac-OS-X https://subversion.apache.org/pac ...
- Linux命令行上传本地文件到服务器 、 下载服务器文件到本地
sh使用命令: scp 将本地文件上传至服务器 第一个是本地文件的路径/文件名, 例如 ./index.tar.gz . index.html . bg.png 等 第二个是要上传到的服务器的位置 ...
- 从web启动winform程序
最近有个客户提出想从网站上启动一个客户端的程序,研究了下,实现方法如下: 1. 注入注册表 try { string appPath ...