zl程序教程

您现在的位置是:首页 >  其他

当前栏目

HashMap面试题

面试题 HashMap
2023-09-11 14:21:22 时间

一.hashmap基础

1.hashmap的node

  • node是一个节点

  • node存放元素的单元

2.hashmap的容量

  • 初始容量为16,每次扩容为原来的两倍

3.hashmap的负载因子

  • 负载因子为0.75f

  • 默认的阈值为12

  • 太大会造成多线程问题

  • 太小会造成空间浪费

4.hashmap的hash()算法

  • 指的是两次扰动

    • 第一次扰动hash方法的时候

    • 确认数组下标的时候

  • 扰动的目的

    • 是为了让hashmap

5.HashMap里面的hash()返回值

  • 第一次扰动的值

二.hashmap的数组+链表/树问题

1.hashmap为什么引入链表

  • 因为减少查询的速度。

2.为什么jdk1.8会引入红黑树呢

  • 防止一条链表上的速度过多,增加查询时间。

3.hashmap为什么一开始不就使用红黑树?

  • 数据量少的时候链表和红黑树的查询时间复杂度的区别不大。并且红黑树会占用更多的空间。

4.HashMap的底层数组取值的时候,为什么不用取模,而是&

  • &也可以达到取模的效果

  • 在计算机的底层,&方法比取模要快

     

5.数组的长度为什么是2的次幂

  • (n-1)&hash (key)

  • 因为HashMap使用的方法很巧妙,他通过hash&(table.length-1)来获得该对象的保存位,前面说过HashMap的底层数组的长度总是2的n次方,这是HashMap在速度上的优化。当length总是2的n次方时,hash&(length-1)运算等价于对length取模,也就是hash%length,但是&比%具有更高的效率,比如n%32=n&(32-1)

三、hashmap里面的源码

1.HashMap的put()

2.HashMap的扩容原理

  • 1.7的扩容原理(数组+链表)

  • 1.8的扩容原理(数组+链表+红黑树)

    • 第一次扩容

      • 赋值初始容量:16
        初始阈值:12
    • 第二次扩容

      • 当超过阈值的时候进行
        并且容量扩大为原来的一倍,阈值同样扩大为原来的一倍
        阈值 = 容量 * 负载因子
      • 为什么达到阈值的时候扩容?

        • 如果多线程的情况下,如果多个线程同时添加元素,如果达到容量在扩容,可能导致一个线程的元素无法添加进去。
      • 为什么负载因子为0.75

        • 如果太大会出现多线程的情况
          如果太小了,可能会造成空间浪费

3.第一次resize方法做了什么?

  • 赋值初始容量为16

  • 赋值初始阈值为12,0.75f\

  •  

4.扰动的目的(两次扰动)

  • 第一次扰动:

    •  

  • 第二次扰动:

    •  

  • 使得数字变小,让i在一定的范围之内

  • 使得数字分布的更加均匀

5.值的覆盖