网站设计怎么做,网站建设实战,健康养生网站源码,seo百度发包工具无论是在实际工作中还是在面试中#xff0c;HashMap 无疑是使用频率最高的知识点之一#xff0c;所以我们需要搞懂每一个关于 HashMap 的知识点才行。哈喽#xff0c;大家好#xff0c;我是老王#xff0c;欢迎来到 Java 面试突击#xff0c;我们今天来开始第 6 期的内容… 无论是在实际工作中还是在面试中HashMap 无疑是使用频率最高的知识点之一所以我们需要搞懂每一个关于 HashMap 的知识点才行。哈喽大家好我是老王欢迎来到 Java 面试突击我们今天来开始第 6 期的内容。本期的问题是HashMap 为什会导致 CPU 运行 100%这是一个比较常见的经典问题了但是有很多人读者朋友给我反馈尼玛看文章根本看不懂啊Sun 公司都不知道这个问题的原因吧不是 Oracle 公司都不知道这个问题的原因吧面试官怕也不知道这个的答案吧咳咳作为一个很正经的面试官我觉得这个问题一点都不重要重要的是你不知道答案啊。好的下一位面试者请进您先回去等通知吧。为了避免这种尴尬的事情发生今天我们来好好聊一下这个问题毕竟技能再手才能吊打面试官不是正文 这个问题相关的知识点有以下几个HashMap 的底层数据结构是什么什么是哈希碰撞如何该解决这个问题什么是扩展因子它有什么用还有对 HashMap 源码的理解为什么 HashMap 会导致死循环视频版答案 视频内容如下图文答案 1.HashMap 的底层数据结构先来说 HashMap 的底层数据结构看过 HashMap 的源码我们就会发现JDK 1.7 和 JDK 1.8 HashMap 的组成是不同的JDK 1.7 HashMap 的组成是数组 链表的形式而 JDK 1.8 新增了红黑树的数据结构当 HashMap 中的链表长度大于 8 时链表结构就会转换为红黑树如下图所示2.哈希碰撞及解决方案所谓的哈希碰撞指的是不同的值经过哈希之后得到的值确是相同的这种情况就叫做哈希碰撞或哈希冲突。解决哈希碰撞的常用方法是开放定址法和链表地址法而 HashMap 采用的就是链表地址法。它的实现原理就是将 HashMap 中相同的哈希值以链表的形式存储起来。3.扩展因子扩展因子也叫加载因子或负载因子是 HashMap 中的一个属性如下图所示假如数组的默认长度为 10扩展因子为 0.5那么当数组超过 10*0.55 个时HashMap 就会扩容为之前容量的两倍所以说扩展因子就是用来判定 HashMap 是否满足扩容条件的。4.HashMap死循环分析HashMap 导致 CPU 100% 的原因就是因为 HashMap 死循环导致的那 HashMap 是如何造成死循环的接下来我们一起来看。以 JDK 1.7 为例假设 HashMap 的默认大小为 2HashMap 本身中有一个键值 key(5)我们再使用两个线程t1 添加 key(3)t2 添加 key(7)首先两个线程先把 key(3) 和 key(7) 都添加到 HashMap 中此时因为 HashMap 的长度不够用了就会进行扩容操作然后这时线程 t1 在执行到 EntryK,V next e.next; 时交出了 CPU 的使用权源代码如下void transfer(Entry[] newTable, boolean rehash) {int newCapacity newTable.length;for (EntryK,V e : table) {while(null ! e) {EntryK,V next e.next; // 线程一执行此处if (rehash) {e.hash null e.key ? 0 : hash(e.key);}int i indexFor(e.hash, newCapacity);e.next newTable[i];newTable[i] e;e next;}}
}
那么此时线程 t1 中的 e 指向了 key(3)而 next 指向了 key(7) 之后线程 t2 重新 rehash 之后链表的顺序被反转链表的位置变成了 key(5) - key(7) - key(3)其中 “-” 用来表示下一个元素当 t1 重新获得执行权之后先执行 newTalbe[i] e 把 key(3) 的 next 设置为 key(7)而下次循环时查询到 key(7) 的 e.next 为 key(3)于是就形 成了 key(3) 和 key(7) 的环形引用就导致了死循环的产生如下图所示HashMap 发生死循环的一个重要原因是 JDK 1.7 时链表的插入是首部倒序插入的而 JDK 1.8 时已经变成了尾部插入有人把这个死循环的问题反馈给了 Sun 公司但它们认为这不是一个问题因为 HashMap 本身就是非线程安全的如果要在多线程使用建议使用 ConcurrentHashMap 替代 HashMap但面试中这个问题被问的频率比较高所以在这里就特殊说明一下。小结 HashMap 是非线程安全的以 JDK 1.7 为例当多线程并发扩容时就会出现环形引用的问题从而导致死循环的出现一直死循环就会导致 CPU 运行 100%所以在多线程使用时我们需要使用 ConcurrentHashMap 来替代 HashMap但只有懂得其中的因果关系才能吊打面试官好了本节内容到这里就结束了我们下期再见。上期中奖名单皮卡皮卡、一步、好好学习、谈笑、包子有话要讲。以上中奖的朋友请加我的微信GG_Stone 领取奖励。【END】近期热文 面试突击 005 | Redis 是如何实现高可用的它的实现方式有哪些面试突击 004 | 如何排查 Redis 中的慢查询视频实战篇面试突击 003 | Redis 如何实现查询附近的人面试突击 002 | Redis 是如何处理已过期元素的面试突击 001 | Redis 如何从海量数据中查询出某一个 KeyJava面试详解(2020版)500 面试题和核心知识点详解关注下方二维码订阅更多精彩内容朕已阅