zoukankan      html  css  js  c++  java
  • 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修饰的,所以当对链表中的元素有修改时,对其他线程是可见的。

      

  • 相关阅读:
    .net core
    asp.net core之abp框架
    C#
    c#
    C#
    C#
    C#
    技术术语
    mysql
    006.内测.情景之迷你财务记账
  • 原文地址:https://www.cnblogs.com/Jomini/p/15407062.html
Copyright © 2011-2022 走看看