首页 > 编程语言 >每日速记10道java面试题05

每日速记10道java面试题05

时间:2024-12-01 10:31:15浏览次数:7  
标签:扩容 10 面试题 java hashmap 黑树 链表 哈希 HashMap

其他面试题:

每日速记10道java面试题01-CSDN博客

每日速记10道java面试题02-CSDN博客

每日速记10道java面试题03-CSDN博客

每日速记10道java面试题04-CSDN博客

目录

1.请你说说java中hashmap的原理

2.HashMap的put(key,value)和get(key)过程

3.在使用hashmap时,有哪些提升性能的技巧?

4.什么是哈希碰撞?怎么解决哈希碰撞?

5.谈一谈hashmap的扩容操作?

6.hashmap的初始容量和负载因子越大越好吗?

7.为什么jdk1.8之后要对hashmap进行了红黑树的改动?

8.jdk1.8对hashmap除了对红黑树的改动还有哪些改动呢?

9.扩容是在原有的hashmap中扩还是新建一个hashmap对象?如果是后者?旧hashmap怎么处理?

10.hashmap有什么缺点呢?


1.请你说说java中hashmap的原理

在jdk1.7前,hashMap底层是由数组和链表实现的,key值会通过hashCode()方法计算出哈希值并映射到数组的槽位,当多个key值映射到同一个槽位时,则会以链表形式放到同一个槽位

Jdk1.8时得到优化,链表长度超过8时将链表转换为红黑树提高查询性能。(延伸→为什么要转换为红黑树?跳转至第七题)

Hashmap的默认初始容量为 16,负载因子为 0.75。也就是说,当存储的元素数量超过 16x0.75=12 个时, Hashap会触发扩容操作,容量x2并重新分配元素位置。这种扩容是比较耗时的操作,频繁扩容会影响性能。

2.HashMap的put(key,value)和get(key)过程

put时,
我们将key/value传给put,它调用hashCode计算hash从而得到插槽位置
并判断这个插槽位置是否已经被占用,没有的话就直接存入,
有的话就遍历这个位置的链表或红黑树看看是否有相同的键,
有的话就更新这个键的值,没有的话就直接存入到链表或数据结构;
然后hashmap开始判断链表的长度是否超过阈值,
是的话就转换为红黑树进行存储;
之后hashmap检查键值对的数量与数组长度比值是否达到负载因子,是的话就进行扩容。

get时,
我们将key传给get,它调用hashCode计算hash从而得到插槽位置,
进一步调用equals方法确定键值对,从而取出value值。 

3.在使用hashmap时,有哪些提升性能的技巧?

1.合理设置hashmap的初始容量和负载因子,尽量减少扩容操作
2.尽量让hash值均匀分布,避免哈希碰撞
3.选择合适的数据类型,使用合适的数据结构:LinkedHashMap(插入顺序存储)、ConcurrentHashMap(高并发线程安全)、TreeMap (可以排序)

4.什么是哈希碰撞?怎么解决哈希碰撞?

Hash 碰撞是指不同的数据通过哈希算法计算后得到相同的哈希值,映射到了哈希表的同一个位置,发生”碰撞”解决方案:
1.拉链法(链地址法): 将哈希表的每一个槽的位置变成一个链表,将哈希值相同的键存储到同一个链表中
2.开放寻址法: 如果出现碰撞,就寻找哈希表下一个可用的位置.
3.再哈希法(双重哈希): 在出现碰撞时,使用第二个哈希函数计算新的索引位置, 减少碰撞的概率

5.谈一谈hashmap的扩容操作?

hashMap默认的负载因子是0.75,即如果hashmap中的元素个数超过了总容量75%,,则会触发扩容,扩容分为两个步骤:

  • 第1步是对哈希表长度的扩展(2倍)
  • 第2步是将旧哈希表中的数据放到新的哈希表中。

因为hashmap的初始容量是16,转换为2进制就是有四位(2的四次方),每次扩容都是乘以2,也就是位数+1,每次扩容的时候元素的hash值也会发生变化,这时候只需要看hash值新增的那个位是0还是1即可,如果是1那该元素在新hashmap的新位置为:旧位置+旧hashmap容量。

 因此,hashmap扩容之后,部分元素的位置会发生变化,但不需要去重新计算哈希值,但即使如此hashmap的扩容操作还是一个比较耗时的操作,我们要尽可能减少hashmap的扩容。

延伸→怎么减少扩容?→(设置大一点的初始容量和负载因子)

延伸→初始容量和负载因子越大越好吗?(问题6)

延伸→扩容是在原有的hashmap中扩还是新建一个hashmap对象?如果是后者?旧hashmap怎么处理?(问题9)

6.hashmap的初始容量和负载因子越大越好吗?

不是的,初始容量设置的大一点确实是可以减少扩容操作,但同时带来的问题就是内存空间的浪费,而负载因子大一点确实也能减少扩容操作,但太大也会影响性能,最极端的例子就是当负载因子为1时,虽然可以减少扩容次数,提高内存利用率,但它增加了哈希冲突的可能性。冲突过多会导致桶内链表或红黑树变长,降低查找插入和删除的效率。因此,负载因子1.0会使得时间复杂度劣化为 0(n),不利于 Hashap的高效运行。

7.为什么jdk1.8之后要对hashmap进行了红黑树的改动?

在 JDK 1.8之前, Hashmap 使用链表来解决哈希冲突。当哈希冲突较多时,链表中的元素增多,查找、插入和删除的时间复杂度从 O(1) 退化为 O(n)。
因此在JDK1.8引入红黑树,将链表长度超过一定阈值(默认 8)时的链表转换为红黑树,避免性能急剧下降。当链表长度降到6以下时红黑树会重新退化为链表,保持简单高效。
红黑树是一种平衡二叉搜索树,插入、删除、查找操作的时间复杂度为 Ò(log n),在元素多的情况下远优于链表的 O(n)。

延伸→既然红黑树效率这么高,那为什么不直接用红黑树就好了,还要用链表呢?

因为红黑树节点的大小是普通节点大小的两倍,所以为了节省内存空间不会直接只用红黑树,只有当节点到达一定数量才会转成红黑树,这里定义的是 8。
为什么是 8 呢?通过计算表明这个长度是时间和空间的平衡点。

8.jdk1.8对hashmap除了对红黑树的改动还有哪些改动呢?

1.优化了哈希值的计算
2.将头插法改成了尾插法
3.优化了扩容机制,在jdk1.8之前,是将所有元素重新计算哈希值,然后根据哈希值重新寻找插入的哈希桶,在idk1.8之后是如果是旧数组中对应的新数组的位置,就直接复制到新数组当中,如果不对应,就计算元素的哈希值,并找到插入的哈希桶 

9.扩容是在原有的hashmap中扩还是新建一个hashmap对象?如果是后者?旧hashmap怎么处理?

 

在Java中的HashMap实现中,当HashMap需要扩容时,它会创建一个新的HashMap实例,并将旧HashMap中的所有元素重新计算哈希值后插入到新的HashMap中。这个过程称为rehashing。

具体来说,当HashMap中的元素数量超过其容量(capacity)和加载因子(load factor)的乘积时,HashMap会进行扩容。扩容操作通常包括以下几个步骤:

  1. 创建一个新的HashMap实例,其容量通常是原HashMap容量的两倍。
  2. 遍历原HashMap中的所有元素。
  3. 对于每个元素,根据新的容量重新计算其哈希值。(jdk1.8前)
  4. 将元素插入到新的HashMap中。
  5. 将原HashMap中的所有引用指向新的HashMap。

这个过程中,旧的HashMap实例不会被修改,而是被新的HashMap实例替代。这样做的好处是可以减少在扩容过程中对HashMap操作的影响,因为元素的插入和查找操作不需要在扩容的同时进行。不过,这也意味着在扩容过程中,HashMap可能会暂时占用更多的内存,因为旧的HashMap实例和新的HashMap实例会同时存在,直到所有的元素都被迁移到新的HashMap中。

总而言之就是:是新建一个容量为旧容量两倍的hashmap,然后把旧hashmap的元素迁移过去,旧hashmap之后会被JVM的垃圾回收机制回收。 

(这里可能会被面试官延伸到JVM和垃圾回收机制那边)

10.hashmap有什么缺点呢?

hashmap比较明显的两个缺点就是扩容操作开销大和线程不安全。

hashmap不是线程安全的,hashmap在多线程会存在下面的问题:
JDK 1.7 HashMap 采用数组 +链表的数据结构,多线程背景下,在数组扩容的时候,存在 Entry 链死循环和数据丢失问题。
JDK 1.8 HashMap 采用数组 + 链表+ 红黑二叉树的数据结构,优化了 1.7 中数组扩容的方案,解决了Entry 链死循环和数据丢失问题。但是多线程背景下,put 方法存在数据覆盖的问题。

如果要保证线程安全,可以使用ConurrentHashMap这个数据结构。

(这里可能可以把面试官引入ConurrentHashMap这个知识点来)

标签:扩容,10,面试题,java,hashmap,黑树,链表,哈希,HashMap
From: https://blog.csdn.net/csdn3043663729/article/details/144164981

相关文章

  • 在Windows 10和Windows 11上,你可以通过设置Windows防火墙来限制外网访问,同时保持局域
    在Windows10和Windows11上,你可以通过设置Windows防火墙来限制外网访问,同时保持局域网的访问不受影响。以下是具体操作步骤:方法1:使用Windows防火墙设置限制打开防火墙设置:按 Win+R 打开运行对话框,输入 wf.msc 并按回车,打开“Windows防火墙高级安全”窗口。创建......
  • # 学期2024-2025-1 学号20241428《计算机基础与程序设计》第10周学习总结
    学期(如2024-2025-1)学号(如:20241300)《计算机基础与程序设计》第X周学习总结作业信息这个作业属于哪个课程<班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里<作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业)这个作业的目标1、信......
  • 2024-2025-1 20241425 《计算机基础与程序设计》第10周学习总结
    2024-2025-120241425《计算机基础与程序设计》第10周学习总结作业信息这个作业属于哪个课程https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP)这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#WEEK10这个作业的目标信息系统、数据库与S......
  • 汽车租赁管理系统|Java|SSM|JSP| 前后端分离
    【重要1⃣️】前后端源码+万字文档+部署文档【重要2⃣️】正版源码有问题包售后            【包含内容】【一】项目提供非常完整的源码注释【二】相关技术栈文档【三】源码讲解视频                     ......
  • 中学校园管理系统|Java|SSM|JSP| 前后端分离
    【重要1⃣️】前后端源码+万字文档+部署文档【重要2⃣️】正版源码有问题包售后            【包含内容】【一】项目提供非常完整的源码注释【二】相关技术栈文档【三】源码讲解视频                     ......
  • Type definition error: [array type, component type: [simple type, class java.lan
     详细报错信息:Typedefinitionerror:[arraytype,componenttype:[simpletype,classjava.lang.String]];nestedexceptioniscom.fasterxml.jackson.databind.exc.InvalidDefinitionException:Cannotconstructinstanceof`java.lang.String[]`:noString-argu......
  • 汽车租赁管理系统|Java|SSM|JSP| 前后端分离
    【重要1⃣️】前后端源码+万字文档+部署文档【重要2⃣️】正版源码有问题包售后            【包含内容】【一】项目提供非常完整的源码注释【二】相关技术栈文档【三】源码讲解视频                     ......
  • # 学期2024-2025-1 学号20241405《计算机基础与程序设计》第10周学习总结
    作业信息|这个作业属于哪个课程|https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP||这个作业要求在哪里|https://www.cnblogs.com/rocedu/p/9577842.html#WEEK10||这个作业的目标|1、信息系统2、数据库与SQL3、人工智能与专家系统4、人工神经网络5、模拟与离散事件......
  • Java学习路径-ChatGPT4o作答
    Java学习路径Java是一门功能强大且用途广泛的编程语言,适用于Web开发、移动开发、大数据、企业应用等领域。以下是系统学习Java的建议路径,从入门到精通。1.基础入门目标:了解Java语言的基本语法、面向对象思想及基本开发工具的使用。学习内容:Java基础语法数据类型(基本......
  • C# mvc +vue+ axios+ api + javascript
    一整天,分享了几条随笔,C#mvc+axios+webapi+javascripthttps://www.cnblogs.com/insus/p/18577591asp.netmvc视图传递数据至另一页的视图https://www.cnblogs.com/insus/p/18578261C#mvc+angular+$http+webapi+javascripthttps://www.cnblogs.com/insus/p/1857......