HashMap最全面试题 连环15问

news2025/1/16 20:19:13

目录

问1:JDK1.7与1.8中的HashMap底层数据结构有什么不同?

问2:何时会转为红黑树,何时会退化为链表?

问3:HashMap根据key查询的时间复杂度?

问4:为何一上来不树化?

问5:树化阈值为何是8?

问6:索引如何计算?hashCode都有了,为何还要提供hash()方法?数组容量为何是2的n次幂?

问7:容量不用2的n次幂行不行?

问8:介绍一下put方法流程,JDK7与JDK8有何不同?

问9:HashMap的扩容机制

问10:负载因子为何默认是0.75?

问11:多线程下1.7与1.8的HashMap会有什么问题?

问12:HashMap的key为null的时候存放在什么位置?

问13:HashMap底层是有序存放的吗?

问14:HashMap的key是否可以为null,作为key的对象有什么要求?

问15:String对象的hashCode()是如何设计的,为什么每次乘的都是31?


问1:JDK1.7与1.8中的HashMap底层数据结构有什么不同?

答:1.7是数组+链表,1.8是数组+(链表 | 红黑树)。

问2:何时会转为红黑树,何时会退化为链表?

答:当链表长度大于8并且数组容量大于等于64时,才会将链表转为红黑树。但如果仅仅是链表长度大于8,则会选择数组扩容的方式来减少链表长度。

退化情况1:在扩容如果拆分树时,树的元素个数<=6则会退化成链表。

退化情况2:remove树节点时,若root、root.left、root.right、root.left.left有一个为null,也会退化成链表。

问3:HashMap根据key查询的时间复杂度?

答:要看key是否发生hash冲突,如果没有发生hash冲突的情况下,时间复杂度为O1,也就是我只查询一次就查到了。如果发生了hash冲突,采用链表的形式存放,时间复杂度为On,也就是从头查询到尾部。如果发生了hash冲突,采用红黑树的形式存放,时间复杂度为Ologn。

问4:为何一上来不树化?

答:假如链表只有3个节点,你一上来就红黑树,难道就比链表的效率高吗?链表只需要从1查到3即可。而且红黑树占用内存也多,链表的数据结构是Node,红黑树底层数据结构是TreeNode,TreeNode的成员变量要比链表的Node多很多,因此对内存的占用也多。

问5:树化阈值为何是8?

答:红黑树用来避免DOS攻击,防止链表超长时性能下降,树化应当是偶然情况,大多数正常情况还是链表的性能高,而且hash值如果足够随机,则在hash表内按泊松分布,在负载因子0.75的情况下,长度超过8的链表出现概率是0.00000006(一亿分之六),选择8就是为了让树化的几率足够小。

问6:索引如何计算?hashCode都有了,为何还要提供hash()方法?数组容量为何是2的n次幂?

答1:调用对象的hashCode方法,得到原始hash值,原始hash值还要调用hashmap中的hash方法进行二次hash,二次hash的结果再去跟我们哈希表中数组的容量(16)做(二次hash结果 & capacity - 1)位移运算,就可以得到索引(桶下标)。

答2:因为2的n次幂时哈希的分布性不是很好,所以二次hash为了让我们的数据分布的更加均匀一些,防止链表过长。

答3:数组容量是2的n次幂有两项好处,第一项好处是当计算索引时,如果是2的n次幂可以使用位移运算代替取模,效率更高;第二项好处是扩容时hash & 旧容量 = 0的元素留在原来位置,不等于0的元素就要移动到新的位置,新位置 = 旧位置 + 旧容量。

问7:容量不用2的n次幂行不行?

答:如果数组的容量不是2的n次幂,那上一问的3个答案都用不上了。例如Hashtable的容量就不是2的n次幂,并不能说哪种设计更优,应该是设计者综合了各种因素,最终选择了使用2的n次幂作为容量。

问8:介绍一下put方法流程,JDK7与JDK8有何不同?

答:流程:

① HashMap是懒惰创建数组的,首次使用才创建数组。

② 计算索引(桶下标)。

③ 如果桶下标没有占用,创建Node占位返回。

④ 如果桶下标已经有人占用

① 已经是TreeNode走红黑树的添加或更新逻辑。

② 是普通Node,走链表的添加或更新逻辑,如果链表长度超过树化阈值,走树化逻辑。

⑤ 返回前检查容量是否超过阈值,一旦超过进行扩容。

不同点:

1、HashMap map = new HashMap(); //默认情况下,先不创建长度为16的数组

2、当首次调用map.put()时,再创建长度为16的数组。

3、1.7是头插法,1.8采用尾插法。

4、1.7是大于等于阈值(12)且没有空位时才扩容,而1.8是大于阈值就扩容。也就是说我已经有12个元素了,put第13个的时候对应的桶下标并没有任何元素在,所以1.7不会触发扩容。

5、当数组指定索引位置的链表长度>8时,且map中的数组的长度> 64时,此索引位置上的所有key-value对使用红黑树进行存储。

问9:HashMap的扩容机制

答:当HashMap中的元素个数超过数组长度 * 负载因子0.75时,就会进行数组扩容,也就是说,默认情况下,数组大小为16,那么当HashMap中的元素个数超过16 X 0.75 = 12的时候,就把数组的大小扩展为2 X 16 = 32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常耗性能的操作,所以如果我们已经预知HashMap元素的个数,就能有效的提高HashMap的性能。

补充:当链表个数达到了8个,数组长度没有达到64,那也会触发扩容机制。

问10:负载因子为何默认是0.75?

答:

① 在空间占用与查询时间之间取得较好的平衡。

② 大于这个值,空间节省了,但链表就会比较长影响性能。

③ 小于这个值,冲突减少了,但扩容就会更加频繁,空间占用多。

问11:多线程下1.7与1.8的HashMap会有什么问题?

答:1.7会发生死链,1.7与1.8都会发生数据错乱。

JDK1.7采用头插法的危害:当扩容的时候,在里面有一个resize方法,它又调用了一个transfer方法(用来将原先table的元素全部移到newTable里面,重新计算hash,然后再重新根据hash分配位置)。把里面的一些Entry进行了一个rehash,在这个过程当中,可能会造成一个链表的循环。就可能在下一次Get的时候出现一个死循环的情况。

JDK1.8采用了尾插法解决了这么一个问题,因为采用了尾插法,没有改变数据插入的这么一个顺序。所以就不会造成一个链表循环的一个过程。

问12:HashMap的key为null的时候存放在什么位置?

答:存放到index为0位置。

问13:HashMap底层是有序存放的吗?

答:是无序的。

因为我们的哈希算法他是散列计算,比如说我们要存放key分别是1-10,但是这些key在计算存放到我们的数组index位置的时候有可能第一个key存放到index为2的位置,第二个key存放在index为1的位置。所以是无序的。如果想要实现有序的HashMap集合,我们可以使用LinkedHashMap集合,它底层才用的是双向链表形式来将我们的HashMap结构中的Entry进行通过双向链表来进行有序连接起来。

问14:HashMap的key是否可以为null,作为key的对象有什么要求?

答:HashMap的key可以为null,但Hashtable、TreeMap、ConcurrentHashMap的key都不能为null。一个对象要想作为HashMap的key需要重写hashCode()和equals()方法,并且key的内容不能修改(不可变),重写hashCode()是为了能有更好的分布性,提高查询性能。重写equals()方法是万一两个key计算出来的索引一样,得需要equals()进一步比较它们是不是相同的对象。

注意:如果hashCode相同,equals不一定相同。如果两个对象equals相同,hashCode肯定也相同。

问15:String对象的hashCode()是如何设计的,为什么每次乘的都是31?

答:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1358208.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android跨进程渲染

文章目录 背景实现步骤服务端客户端参考代码 背景 2024年第一篇博客&#xff0c;希望所有看到这篇博客的同学都能财务自由&#xff0c;早日退休&#xff01; 跨进程渲染就是在服务端进程渲染&#xff0c;在客户端进程显示。在一些 3d 的应用场景&#xff0c;当多个应用需要显…

【揭秘】单例模式DCL导致无法访问对象?

前两天&#xff0c;在审查团队成员的代码时&#xff0c;我发现了一个错误的单例模式写法。 在Java中&#xff0c;单例模式是一种非常常见的设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例&#xff0c;但是&#xff0c;如果不正…

微信怎么做小程序店铺?如何制作微信小程序店铺

在这个数字化的时代&#xff0c;拥有一个属于自己的线上店铺已经成为了一种趋势。而微信小程序&#xff0c;作为微信平台上的一种轻应用&#xff0c;无疑成为了许多人开店的首选。那么&#xff0c;如何利用微信小程序开设自己的店铺呢&#xff1f;下面就让我来为大家详细解析一…

盘点2023年12月Sui生态发展,了解Sui近期成长历程!

12月是一年的“收官”月&#xff0c;我们告别了2023&#xff0c;迎来了崭新的2024&#xff0c;而Web3行业多项指标也持续展现增长趋势。Sui紧随行业脚步&#xff0c;开展了一系列生态活动。其中专为圣诞准备的冬季任务送出了50万SUI&#xff0c;与韩国游戏公司NHN合作的NFT限量…

原来圣诞树可以这么做

先看结果 从上到下依次是&#xff1a; 2^0 2^1 2^2 2^3 2^4 2^5 2^6 2^7 ... 依次排下去&#xff0c;最后加4个单位数的数字 原来代码的世界里还有这个美。^V^

软考报名有哪些要求?

报考任何级别不需要学历、资历条件&#xff0c;只要达到相应的专业技术水平就可以报考相应的级别 (一)2024年软考报名入口 2024年软考采用网络报名方式&#xff0c;考生在报名期间进入中国计算机技术职业资格网 (中国计算机技术职业资格网)&#xff0c;点击页面右下角的报名入…

飞凌嵌入式2023年度盘点——步履不停,向上而行

刚刚过去的一年充满了挑战 但飞凌嵌入式始终带着对未来的期许 坚定地向上而行 凡是过往&#xff0c;皆为序章 让我们站在2024年的开端 一起回顾飞凌嵌入式的2023年度大事 1、企业实力&#xff0c;稳步提升 2023年&#xff0c;飞凌嵌入式成为国家级专精特新“小巨人”企业…

ZkSync第一Dex空投交互全教程,Holdstation ZK热点不容错过

2023 年 12 月 8 日&#xff0c;在以太坊基金会的 176 次会议上&#xff0c;开发人员一致同意&#xff0c;如果事情进展顺利&#xff0c;将在 2024 年初定 Goerli 分叉日期&#xff0c;目标是能在 2024 年 1 月激活 Goerli Dencun 测试网&#xff0c;预计能够在 2024 年 3 月~ …

Scikit-Learn线性回归(五)

Scikit-Learn线性回归五&#xff1a;岭回归与Lasso回归 1、误差与模型复杂度2、正则化3、Scikit-Learn岭&#xff08;Ridge&#xff09;回归4、Scikit-Learn Lasso回归 1、误差与模型复杂度 在第二篇文章 Scikit-Learn线性回归(二) 中&#xff0c;我们已经给出了过拟合与模型泛…

CentOS 7 基于官方源码和openssl制作openssh 9.6 rpm包(含ssh-copy-id) —— 筑梦之路

之前写了一篇&#xff1a; CentOS 7 制作openssh 9.6 rpm包更新修复安全漏洞 —— 筑梦之路_升级openssh9.6-CSDN博客 有好几个网友反馈&#xff0c;ssh-keygen生成密钥存在问题&#xff0c;之前的rsa \ dsa加密算法用不了&#xff0c;因此写了一篇&#xff1a; 关于openssh…

mariadb配置慢sql查询

Mariadb和Mysql配置相同 这里配置的事mariadb 修改配置文件 vi /etc/my.cnf.d/server.cnf[mysqld] slow_query_logon slow_query_log_file/data/mysql_data/slow_query_log.log long_query_time2slow_query_logon 开启慢sql查询slow_query_log_file/data/mysql_data/slow_que…

基于MyCat2.0实现MySQL分库分表方案

目录 一、MyCat概述 二、MyCat作用 2.1 数据分片 2.1.1 垂直拆分 2.1.1.1 垂直分库 2.1.1.2 垂直分表 2.1.1.3 总结 2.1.2 水平拆分 2.1.2.1 水平分库 2.1.2.2 水平分表 2.1.2.3 总结 2.2 读写分离 2.3 多数据源整合 三、MyCat 与ShardingJDBC的区别 3.1 MyCat …

vins 实机测试 rs_d435 + imu

vins 实机测试 文章目录 1. imu标定2. camera内参标定3. imu-cam 外参标定4. vins 实际运行5. realsense 1. imu标定 git clone https://github.com/gaowenliang/code_utils.git git clone https://github.com/gaowenliang/imu_utils.git编译运行&#xff0c; roslaunch imu_…

echarts 切换时出现上一次图形残留。

先说结果&#xff1a;悬浮高亮导致。这可能使echarts的bug。 正常情况出现这种问题&#xff0c;一般是setOption 中没有配置notMerge 导致新的配置与旧配置合并。 但是我这里始终配置notMerge: true&#xff0c;但仍然出现这种问题。 最后发现与鼠标悬浮有关。 环境 echar…

小梅哥Xilinx FPGA学习笔记20——无源蜂鸣器驱动设计与验证(音乐发生器设计)

目录 一&#xff1a;章节导读 二&#xff1a;无源蜂鸣器驱动原理 三&#xff1a;PWM 发生器模块设计 3.1 PWM 发生器模块框图 3.2 PWM 发生器模块接口功能描述 3.3 PWM波生成设计文件代码 3.4 测试仿真文件 3.5 测试仿真结果 3.6 板级调试与验证之顶层文件设计 四&am…

民营体检@2023/24:革新、挑战与本质回归

【潮汐商业评论/原创】 被“健康焦虑”困扰的Joy决定给自己来一次全身的检查&#xff0c;在网上一搜才发现&#xff0c;不仅是体检机构&#xff0c;现在各大医院也都可以体检。“感觉价格也都差不多&#xff0c;是选公立还是体检机构呢&#xff1f;”Joy陷入疑惑。 随着近几年…

洛谷 P1873 砍树 (二分 简单)

【二分答案】是分治的一种&#xff0c;这类问题很经典&#xff0c;接下来几篇文章会关于二分答案相关的文章&#xff0c;希望同学们可以完成10道以上的【二分答案】相关问题&#xff0c;以此来加深对【二分答案】这类问题的个人理解。 原公众号链接&#xff1a;分治第二讲&…

pygame学习(二)——绘制线条、圆、矩形等图案

导语 pygame是一个跨平台Python库(pygame news)&#xff0c;专门用来开发游戏。pygame主要为开发、设计2D电子游戏而生&#xff0c;提供图像模块&#xff08;image&#xff09;、声音模块&#xff08;mixer&#xff09;、输入/输出&#xff08;鼠标、键盘、显示屏&#xff09;模…

stable diffusion 基础教程-提示词之光的用法

基图 prompt: masterpiece,best quality,1girl,solo,looking at viewer,brown hair,hair between eyes,bangs,very long hair,red eyes,blush,bare shoulders,(white sundress),full body,Negative prompt: EasyNegative,badhandv4,nsfw,lowres,bad anatomy,bad hands,text…

Linux第14步_安装FTP服务器

安装“vim编辑器”后&#xff0c;我们紧接着“安装FTP服务器”。 1、在安装前&#xff0c;要检查虚拟机可以上网&#xff0c;否则可能会导致安装失败。 2、在虚拟机界面右击鼠标&#xff0c;弹出下面的对话框 3、点击“打开终端(E)”&#xff0c;得到下面的界面 &#xff1a;…