hashmap经典面试问题以及答案
上一篇文章分析了hashmap的主要方法,了解了主要方法接下来好解答平时面试的问题了。
加载因子为什么是 0.75?
那加载因子为什么是 0.75 而不是 0.5 或者 1.0 呢?
首先如果加载因子比较大,那么扩容发生的频率就比较低,但是他浪费的空间比较小,不过发生hash冲突的几率就比较大,比如加载因子是1的时候,如果hashmap长度为128,那么可能hashmap的实际存储元素数量在64至128之间的时间段比较多,而这个时间段发生hash冲突就比较大,造成数组中其中一条链表较长,就会影响性能。
而当加载因子值比较小的时候,扩容的频率就会变高,因此会占用更多的空间,但是元素的存储就比较稀疏,发生哈希冲突的可能性就比较小,因此操作性能会比较高,比如设置成0.5,同样128长度的hashmap,当数量达到65的时候就会触发hashmap的扩容,扩容后长度为256,256里面只存储了65个似乎有点浪费了。
所以综合了以上情况就取了一个 0.5 到 1.0 的平均数 0.75 作为加载因子。
当有哈希冲突时,HashMap 是如何查找并确认元素的?
通过昨天分析get方法应该已经比较清楚了,如果哈希冲突,还是找到table[index]的第一个Node,然后一个一个去比对链表中的key,key一致则找到,引用put流程图其中一部分如下图:
JDK 1.8 HashMap 扩容时做了哪些优化?
在 JDK 1.7 中 HashMap 是以数组加链表的形式组成的,JDK 1.8 之后新增了红黑树的组成结构,当链表大于 8 并且容量大于 64 时,链表结构会转换成红黑树结构,即使在hashcode 完全相同极端情况下,由于红黑树的特点,查找某个特定元素,也只需要O(log n)的开销,而如果查找链表,时间复杂度会退化到 O(n)。
HashMap 是线程安全的吗,为什么不是线程安全的?
通过例子来讲解这个不安全的过程,引用上一篇文章的例子,首先一个长度为8的map<Integer,V>,map已经存了key为1、9的两个值,他们都会在map的table[1]上。
1、首先线程1put一个key=17的值,当程序运行到判断key=9的下一个节点为null准备把key=17的值设置为它的下一个节点时,线程让出资源。
2、此时执行线程2,对mapput一个key=25的数据,这个数据正常作为key=9的next正常插入。
3、线程1再次拿到资源继续执行,设置key=9的next为key=17,这样线程2设置的key=25就被覆盖。
以上的流程示意图如下图:
关键代码在于HashMap的put代码,详解如下图:
HashMap 是如何导致死循环的?
说到死循环都是说jdk7的hashmap的死循环,主要在多线程情况下,多个线程对map的同时扩容造成的,jdk7扩容的关键代码如下图:
可以看到jdk7比上一篇文章分析的jdk8的扩容的关键代码就简单多了,实际上就是遍历所以元素,找到在新的table下的位置,并把新table对应位置的元素设置成当前元素的next,就是所谓的头插法!
那么为什么会造成死循环呢?这里简单做一个造成死循环的流程分析,如下图:
造成死循环的原因主要在于线程1执行单key=9,并取出他的next(key=25)作为下次遍历后,线程1交出了执行权休息去了,而接着线程2吭哧吭哧的执行完扩容,扩容由于采用头插法,此时key=25那个Entry对象的next是key=9。
所以当线程1继续执行,到遍历next(key=25)时他的next变成了key=9,最终造成了两个Entry互相引用,如果后面调用map.get(41)就会刚好查询table[9],然后遍历这个链表,造成死循环!
总结
hashmap面试时主要的问题就是上面的那些了,有些可能没有覆盖到,但是只要弄懂了源码,所有问题都差不多,注意jdk8只是解决了死循环的问题,多线程下数据丢失的问题还是没有解决,所以多线程还是用ConcurrentHashMap。
有时候面试的时候可能面试官只会问“你了解hashmap吗?”,这种问题就不要想简单了直接回答一个了解就完了,而是把你理解的比如hashmap结构、主要方法实现、jdk7与jdk8的区别、jdk7可能的问题等都可以主动说出来,这样会更好!
Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!
hashmap经典面试问题以及答案相关推荐
- django render_2020年最新Django经典面试问题与答案汇总(下)大江狗整理
终于我们来到Django经典面试问题与答案系列的终章了,在本章我们将分享最后10个常用有用的知识点,也是面试时常问的经典问题.如果你还没有读过本系列前两篇文章的,可以点击如下链接阅读. 2020年最新 ...
- 1000以内完数c语言程序_C语言经典面试题目及答案详解(二)
接着上次来说,C语言经典面试题目及答案详解(一)当中大部分是一些概念和理解的东西 ,今天说一说实践操作,有关c的经典程序. 1.输出9*9口诀.共9行9列,i控制行,j控制列. #include &q ...
- c语言sort函数_C语言经典面试题目及答案详解(二)
接着上次来说,C语言经典面试题目及答案详解(一)当中大部分是一些概念和理解的东西 ,今天说一说实践操作,有关c的经典程序. 1.输出9*9口诀.共9行9列,i控制行,j控制列. #include 2. ...
- 2018最新Web前端经典面试试题及答案
本篇收录了一些面试中经常会遇到的经典面试题以及自己面试过程中遇到的一些问题,并且都给出了我在网上收集的答案.马上就要过春节了,开年就是崭新的一年,相信很多的前端开发者会有一些跳槽的悸动,通过对本篇知识 ...
- 2020年最新Django经典面试问题与答案汇总(下)-大江狗整理
终于我们来到Django经典面试问题与答案系列的终章了,在本章我们将分享最后10个常用有用的知识点,也是面试时常问的经典问题.如果你还没有读过本系列前两篇文章的,可以点击如下链接阅读. 2020年最新 ...
- 33条C#、.Net经典面试题目及答案[zt]
本文集中了多条常见的C#..Net经典面试题目例如".NET中类和结构的区别"."ASP.NET页面之间传递值的几种方式?",并简明扼要的给出了答案,希望能对学 ...
- 嵌入式工程师的经典面试题目及答案
上个星期,去深圳一家搞ARM开发的公司面试,HR叫我做了一份卷子,里面都是C编程,心中暗喜,因为这些题基本上都在程序员面试宝典里见过.后来回到学校,在网上搜索,原来这些题都是嵌入式工程师的经典面试题目 ...
- 2018最新Web前端经典面试试题及答案-史上最全前端面试题(含答案)--转载
版权声明:本文为转载文章,感谢博主小胖梅的博客,如有侵权,请联系我删除,谢谢 转载链接: https://blog.csdn.net/xm1037782843/article/details/8070 ...
- 2019最新Web前端经典面试试题及答案,持续更新
Ps: 文章所述内容,来源渠道平时积累以及网上摘录.按日期持续更新...目录: 转载请注明来源. -2018/6/8 1.position的定位方式 2.描述下从输入URL到整个网页加载完毕及显示 ...
- C#、.Net经典面试题目及答案
1, 请你说说.NET中类和结构的区别? 答:结构和类具有大体的语法,但是结构受到的限制比类要多.结构不能申明有默认的构造函数,为结构的副本是又编译器创建和销毁的,所以不需要默认的构造函数和析构函数. ...
最新文章
- html弹窗确认取消公告代码,js 弹出确认与取消对话框的四种方法
- python爬取快代理IP并测试IP的可用性
- android开源许可证
- jquery 简单分页插件jQuerypage
- 开篇 — 【面向对象设计模式学习】
- 如何获取filecoin_获得Filecoin币有哪些条件?
- oracle用户密码复杂度查询,11gR2 Database用户密码复杂度验证
- python爬虫从入门到放弃(八)之 Selenium库的使用
- lisp抛物线插值_抛物线插值法
- 百度之星资格赛 J题 百度的新大厦
- python切片表达式3个参数_Python:Base3(函数,切片,迭代,列表生成式)
- 通过分区(Partitioning)提高Spark的运行性能
- 计算机专业男生宿舍,实拍大学男生宿舍,男生们不是玩电脑游戏,就是瘫在床上看手机!...
- 排序算法--希尔排序
- android手机视频,安卓手机视频加密软件
- 中国地产商寻找下一个春天
- 大数据处理中心什么意思_什么是数据处理中心或数据中心
- web测试与APP测试方法总结
- html删除图片效果,html+css实现图片右上角加删除叉、图片删除按钮
- element ui的双层el-dialog样式控制