哈希娱乐 行业新闻 党建先锋

HashMap常见面试题解析哈希娱乐

发布时间:2025-11-25 19:49:27  浏览: 次

  哈希游戏作为一种新兴的区块链应用,它巧妙地结合了加密技术与娱乐,为玩家提供了全新的体验。万达哈希平台凭借其独特的彩票玩法和创新的哈希算法,公平公正-方便快捷!万达哈希,哈希游戏平台,哈希娱乐,哈希游戏

HashMap常见面试题解析哈希娱乐

  通过获取key对象的hashcode计算出该对象的哈希值,通过改哈希值与数组长度减去1进行位与运算(n-1 hash),得到buckets 的位置,当发生hash冲突时,如果value值一样,则会替换旧的key的value,value不一样则新建链表结点,当链表的长度超过8,则转换为红黑树存储。

  在jdk1.8之前创建该对象,会创建一个长度为16的Entry[] table用来存储键值对数据。jdk1.8之后不是在构造方法创建了,而是在第一次调用put方法时才进行创建,创建Node[] table,然后java7中链表的加入时

  Java7在多线程操作HashMap时可能引起死循环,原因是扩容转移后前后链表顺序倒置,在转移过程中修改了原来链表中节点的引用关系。

  Java7在多线程操作HashMap时可能引起死循环,原因是扩容转移后前后链表顺序倒置,在转移过程中修改了原来链表中节点的引用关系。

  Java8在同样的前提下并不会引起死循环,原因是扩容转移后前后链表顺序不变,保持之前节点的引用关系。

  但是即使不会出现死循环,但是通过源码看到put/get方法都没有加同步锁,多线程情况最容易出现的就是:无法保证上一秒put的值,下一秒get的时候还是原值,所以线程安全还是无法保证。

  HashMap会进行resize(扩容)操作,重新计算hash值,在resize操作的时候会造成线程不安全。下面将举两个可能出现线、put的时候导致的多线程数据不一致。 这个问题比较好想象,比如有两个线程A和B,首先A希望插入一个key-value对到HashMap中,首先计算记录所要落到的桶的索引坐标,然后获取到该桶里面的链表头结点,此时线程A的时间片用完了,而此时线程B被调度得以执行,和线程A一样执行,只不过线程B成功将记录插到了桶里面,假设线程A插入的记录计算出来的桶索引和线程B要插入的记录计算出来的桶索引是一样的,那么当线程B成功插入之后,线程A再次被调度运行时,它依然持有过期的链表头但是它对此一无所知,以至于它认为它应该这样做,如此一来就覆盖了线程B插入的记录,这样线程B插入的记录就凭空消失了,造成了数据不一致的行为。

  2、另外一个比较明显的线程不安全的问题是HashMap的get操作可能因为resize而引起死循环(cpu100%),即产生链表循环引用的现象(jdk7)

  大小为2的幂是,在计算buckets桶位置的时候,公式为((n-1) hash),2的幂减去1的数的二进制数的结尾都是1,与hash值进行与运算,会得到其余数。进行按位与操作,使得结果剩下的值为对象的hash值的末尾几位,这样就我们只要保证对象的hash值生成足够散列即可

  使存储高效,尽量减少碰撞,在((n-1)hash) 求索引的时候更均匀

  //当链表长度为8时,使用以红黑树代替链表,红黑树的结点是链表长度的两倍,当比较短的时候,使用红黑树的效率其实并不高,根据泊松分布公式的统计结果,在结点数达到8时,适合使用红黑树

  //链表转红黑树时数组的大小的阈值,即数组大小大于这个数字时且链表长度大于8才会转为红黑树,

  如果key相同,则会替换key对应的内容最最小值,key不相同,则接到后面的链表,如果链表长度到达8且数组的长度大于64时,则将链表转为红黑树,如果数组长度小于64,则是进行扩容

  在get和put的过程中,计算下标时,先对hashCode进行hash操作,然后再通过hash值进一步计算下标,如下图所示: