Java集合面试题

HashMap

  1、new HashMap(25) 是什么

     实例化了一个长度为32容量的HashMap, 因为是2的次方, 容量不是25。

  2、为什么 hashMap 使用 红黑书

      AVL树比红黑树保持更加严格的平衡。AVL树中从根到最深叶的路径最多为~1.44 lg(n + 2),而在红黑树中最多为~2 lg(n + 1)。

      是许多二叉查找树中的一种,它能保证在最坏的情况下,基本动态集合操作时间为O(lgn).

       插入和删除节点导致失衡后的rebalance操作,红黑树能够提供一个比较"便宜"的解决方案,降低开销,是对search,insert ,以及delete效率的折衷,总体来说,RB-Tree的统计性能高于AVL.

      https://www.cnblogs.com/wq-9/articles/14202773.html

  3、什么是哈希碰撞 和 解决方式

    概念:

      计算得到的Hash值相同,需要放到同一个bucket中

    解决方式:

      Hashmap里面的bucket出现了单链表的形式,散列表要解决的一个问题就是散列值的冲突问题,通常是两种方法:链表法和开放地址法。

      链表法 就是将相同hash值的对象组织成一个链表放在hash值对应的槽位;

        插入一个 Entry 对象(即Key - Value), 通过Key的hashCode 与 数组长度减一,获取到其 数组坐标

        分情况

          1、获取到的位置,没有 Entry 对;

            即该桶为null, 则直接新放入的对象, 指向 null(1.8 尾插法)

          2、获取到的位置,有 Entry 对象 或者 Entry 链;

            新插入的 Entry, 先通过 key 的hash 与 链表中的 key equal,

            如果都不同则,插入尾部;

            如果有相同的,则替换了 key 相同的 Entry 对象      

      开放地址法 是通过一个探测算法,当某个槽位已经被占据的情况下继续查找下一个可以使用的槽位。

           为什么要用开放地址法呢,因为如果数据全都在同一个桶里面, 查询从数组变为查询链表,查询速率就会从O(1) 变为 O(n) 。

            开放定址法区分为线性探查法、二次探查法、双重散列法等

            参考: https://www.jianshu.com/p/379680144004

      Java 8 的 哈希碰撞优化

            当桶里面的长度大于 8 时, 链表变为红黑树,查询速度从 O(n)变为 O(logn) 

            小于 6 重新变为 链表;

  4、为什么在JDK1.8中进行对HashMap优化的时候,把链表转化为红黑树的阈值是8,而不是7或者不是20呢(面试蘑菇街问过)

    1)如果选择6和8(如果链表小于等于6树还原转为链表,大于等于8转为树),中间有个差值7可以有效防止链表和树频繁转换。

    假设一下,如果设计成链表个数超过8则链表转换成树结构,链表个数小于8则树结构转换成链表,如果一个HashMap不停的插入、删除元素,链表个数在8左右徘徊,就会频繁的发生树转链表、链表转树,效率会很低。

    2)由于treenodes的大小大约是常规节点的两倍,因此我们仅在容器包含足够的节点以保证使用时才使用它们,

      当它们变得太小(由于移除或调整大小)时,它们会被转换回普通的node节点,容器中节点分布在hash桶中的频率遵循泊松分布,桶的长度超过8的概率非常非常小。

  5、为什么 HashMap 中 String、Integer 这样的包装类适合作为 key 键、

    

 

  6、HashMap 中的 key若 Object类型, 则需实现哪些方法?

    

  7、jdk7 先扩容再put jdk8 先put再扩容

    8、为什么链表在get时不需要加锁,而红黑树需要加锁:

     在更新期间链表遍历总是可以进行的,但是树遍历不行,因为树旋转时可能会改变根结点或者其链接。

     而且,链表中成员都是valuenext都是volatile修饰的,所以当对链表中的元素有修改时,对其他线程是可见的。

 

  

 

posted @ 2021-10-14 15:52  李荣先辈Java  阅读(78)  评论(0编辑  收藏  举报