每日一面系列之HashMap夺命连环问

发表于 4年以前  | 总阅读数:489 次

1.HashMap的底层数据结构是什么?

底层数据结构是哈希表结构(链表散列:数组+单向链表),结合了数组和链表的优点,当链表长度超过8时,链表会转为红黑树。数组中的每一个元素都是链表。总结来说就是HashMap在JDK1.8之前底层是由数组+链表实现的,在JDK1.8开始底层是由数组+链表或者数组+红黑树实现的。

追问:为什么在1.8中增加红黑树?

当需要查找某个元素的时候,线性探索是最直白的方式,它会把所有数据遍历一遍直到找到你所查找的数据,对于数组和链表这种线性结构来说,当链表长度过长(数据有成百上千)的时候,会造成链表过深的问题,这种查找方式效率极低,时间复杂度是O(n)。简单来说红黑树的出现就是为了提高数据检索的速度。

追问:链表过深问题为什么不用二叉查找树代替,而选择红黑树?为什么不一直使用红黑树?

二叉树在特殊情况下会变成一条线性结构,这就跟原来的链表结构一样了,选择红黑树就是为了解决二叉树的缺陷。

红黑树在插入数据的时候需要通过左旋、右旋、变色这些操作来保持平衡,为了保持这种平衡是需要付出代价的。当链表很短的时候,没必要使用红黑树,否则会导致效率更低,当链表很长的时候,使用红黑树,保持平衡的操作所消耗的资源要远小于遍历链表锁消耗的效率,所以才会设定一个阈值,去判断什么时候使用链表,什么时候使用红黑树。

追问:讲一下你对红黑树的认识

  • 每个节点非红即黑
  • 根节点总是黑色的
  • 如果节点是红色,则它的子节点必须是黑色(反之不一定)
  • 每个叶子节点都是黑色的空节点
  • 从根节点到叶子节点或者空节点的每条路径必须包含相同数量的黑色节点(黑色节点的深度相同)

2.讲一下HashMap的工作原理,put()和get()的过程分别是怎么样的?

存储对象时,将key和vaule传给put()方法:

  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并且数组长度大于64,大于的话链表转换为红黑树;
  7. 插入完成之后判断当前节点数是否大于阈值(capacity*loadFactor),如果大于开始扩容为原数组的二倍。

下面以流程图方式更加直观的看一下插入流程:

获取对象时,将key传给get()方法:

  1. 调用hash(key)方法获取key对应的hash值从而获取该键值对在数组中的下标。
  2. 对链表进行顺序遍历,使用equals()方法查找链表中相等的key对应的value值。

追问:说一下数组是怎么扩容的?

创建一个新数组,新数组初始化容量大小是旧数组的两倍,对原数组中元素重新进行一次hash从而定位在新数组中的存储位置,元素在新数组中的位置只有两种,原下标位置或原下标+旧数组的大小。

追问:为什么要对原数组中元素再重新进行一次hash?直接复制到新数组不行吗?

因为数组长度扩大以后Hash规则也会随之变化。 Hash的公式—> index = HashCode(Key) & (Length - 1)

追问:在插入元素的时候,JDK1.7与JDK1.8有什么不同?

1.7是先判断是否需要扩容,再进行插入操作。1.8是先插入,插入完成之后再判断是否需要扩容。

注:hashcode是用来定位的,定键值对在数组中的存储位置。equals()方法是用来定性的,比较两个对象是否相等。

3.你说JDK1.8之前使用头插法将Entry节点插入链表,那么头插法具体是怎么做的?设计头插法的目的是什么?

新值会作为链表的头部替换原来的值,原来的值会被顺推到链表当中。下面以图解方式说明一下:

设计者认为后来插入的值被查找的概率比较高,使用头插法可以提高查找的效率。

4.之前是头插法,为什么JDK1.8之后要改成尾插法?

JDK1.8之前扩容的时候,头插法会导致链表反转,在多线程情况下会出现环形链表,导致取值的时候出现死循环,JDK1.8开始在同样的前提下就不会导致死循环,因为在扩容转移前后链表的顺序不变,保持之前节点的引用关系。

例: A线程和B线程同时向同一个下标位置插入节点,遇到容量不够开始扩容,重新hash,放置元素,采用头插法,后遍历到的B节点放入了头部,这样形成了环,如下图所示:

5.HashMap是怎么设定初始化容量大小的?

使用new HashMap()不传值,默认大小是16,负载因子是0.75。如果传入参数K,那么初始化容量大小为大于K的2的最小整数幂。比如传入的是10,那么初始化容量大小就是16(2的4次方)。

追问:为什么HashMap的数组长度要取2的整数幂?

因为这样数组长度-1正好相当于一个“低位掩码”。“与”操作的结果就是散列值的高位全部归零,只保留低位值,用来做数组下标访问。以初始长度16为例,16-1=15。2进制表示是00000000 00000000 00001111。和某散列值做“与”操作如下,结果就是截取了最低的四位值。

6.讲一下HashMap中的哈希函数时怎么实现的?

key的hashcode是一个32位的int类型值,hash函数就是将hashcode的高16位和低16位进行异或运算。

追问:哈希函数为什么这么设计?

这是一个扰动函数,这样设计的原因主要有两点:

  1. 可以最大程度的降低hash碰撞的概率(hash值越分散越好);
  2. 因为是高频操作,所以采用位运算,让算法更加高效;

7.HashMap是线程安全的吗?

不是,在多线程的情况下,1.7的HashMap会导致死循环、数据丢失、数据覆盖。在1.8中如果有多个线程同时put()元素还是会存在数据覆盖的问题。以1.8位例,A线程判断index位置为空后正好挂起,B线程开始向index位置写入节点数据,这时A线程恢复现场,执行赋值操作,就把A线程的数据给覆盖了。

追问:如何解决这个线程不安全的问题?

可以使用HashTable、Collections.synchronizedMap、以及ConcurrentHashMap这些线程安全的Map。

追问:分别讲一下这几种Map都是如何实现线程安全的?

HashTable是直接在操作方法上加synchronized关键字,锁住整个数组,粒度比较大;

Collections.synchronizedMap是使用Collections集合工具的内部类,通过传入Map封装出一个SynchronizedMap对象,内部定义了一个对象锁,方法内通过对象锁实现;

ConcurrentHashMap在JDK1.7中使用分段锁,降低了锁粒度,让并发度大大提高,在JDK 1.8 中直接采用了CAS(无锁算法)+ synchronized的方式来实现线程安全。

8.说一下HashMap在JDK1.8中都有哪些改变?

  1. 底层数据结构:1.7中是数组+链表。1.8中是数组+链表或数组+红黑树;
  2. 元素插入方式:1.7是头插法插入链表。1.7是尾插法插入链表;
  3. 节点类型:1.7中数组中节点类型是Entry节点,1.8中数组中节点类型是Node节点;
  4. 元素插入流程:1.7中是先判断是否需要扩容,再插入。1.8中是先插入,插入成功之后再判断是否需要扩容;
  5. 扩容方式:1.7中需要对原数组中元素重新进行hash定位在新数组中的位置。1.8中采用更简单的逻辑判断,原下标位置或原下标+旧数组的大小。

9.HashMap的内部节点是有序的吗?

是无序的,根据hash值随机插入。

追问:你知道哪些有序的Map?

LinkedHashMap和TreeMap。

追问:说一下这两种Map分别是怎么实现有序的

LinkedHashMap:LinkedHashMap内部维护了一个单链表,有头尾节点,同时LinkedHashMap节点Entry内部除了继承HashMap的Node属性,还有before 和 after用于标识前置节点和后置节点。可以实现按插入的顺序或访问顺序排序。

TreeHashMap: TreeMap是按照Key的自然顺序或者Comprator的顺序进行排序,内部是通过红黑树来实现。所以要么key所属的类实现Comparable接口,或者自定义一个实现了Comparator接口的比较器,传给TreeMap用于key的比较。

10.HashMap,LinkedHashMap,TreeMap 有什么区别?

LinkedHashMap 保存了记录的插入顺序,在用 Iterator 遍历时,先取到的记录肯定是先插入的;遍历比 HashMap 慢。TreeMap 实现 SortMap 接口,能够把它保存的记录根据键排序(默认按键值升序排序,也可以指定排序的比较器)

追问:讲一下这三种Map的使用场景

一般情况下,使用最多的是 HashMap。

HashMap:在 Map 中插入、删除和定位元素时;

TreeMap:在需要按自然顺序或自定义顺序遍历键的情况下;

LinkedHashMap:在需要输出的顺序和输入的顺序相同的情况下。

本文由哈喽比特于4年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/6N7xa4hqyt4v0c0e4dFHjA

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237231次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8065次阅读
 目录