面试 Java 基础八股文十问十答第十八期

面试 Java 基础八股文十问十答第十八期

作者:程序员小白条个人博客

相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新!

⭐点赞⭐收藏⭐不迷路!⭐

1)多线程场景下如何使用 ArrayList?

  • ArrayList 不是线程安全的,多个线程同时对其进行读写操作可能会导致数据不一致或其他异常。
  • 如果需要在多线程环境中使用 ArrayList,可以考虑使用线程安全的集合类,如 CopyOnWriteArrayList 或通过使用同步机制来保证线程安全。
  • 如果多个线程需要同时读取 ArrayList,可以使用不可变的方式来保证线程安全,例如将 ArrayList 声明为 final 或使用 Collections.unmodifiableList() 方法返回一个只读的 List。

2)为什么 ArrayList 的 elementData 加上 transient 修饰?

ArrayList 的 elementData 字段加上 transient 修饰是为了在序列化过程中排除该字段。transient 关键字表示该字段不会被序列化,这是因为 ArrayList 的序列化过程是通过对数组元素进行逐个序列化来实现的,而不是对整个数组进行序列化。因此,为了避免重复序列化数组元素,elementData 字段被标记为 transient

3)List 和 Set 的区别

  • List 是有序的集合,可以存储重复的元素,可以通过索引访问元素。常见的 List 实现类有 ArrayList 和 LinkedList。
  • Set 是无序的集合,不能存储重复的元素,不支持通过索引访问元素。常见的 Set 实现类有 HashSet 和 TreeSet。
  • List 允许元素的插入和删除操作,可以通过索引来操作元素。Set 不允许重复元素的存在,插入重复元素会被忽略。
  • List 的遍历顺序是按照元素的插入顺序,而 Set 的遍历顺序是不确定的。
  • List 和 Set 都是接口,可以根据具体的需求选择使用哪个接口及其实现类。

总结来说,List 适合需要按照顺序存储元素并且需要频繁访问元素的场景,而 Set 适合需要去重并且不关心元素的顺序的场景。

4)说一下 HashSet 的实现原理?

  • HashSet 是基于 HashMap 实现的,底层使用 HashMap 存储元素。
  • HashSet 中的元素被存储在 HashMap 的 key 中,而 value 则被设置为一个固定的常量 Object。
  • 当向 HashSet 中添加元素时,实际上是将元素作为 key 存储到 HashMap 中,而 value 则是一个固定的常量 Object。
  • HashSet 利用 HashMap 的 key 的唯一性来保证元素的唯一性。

5)HashSet如何检查重复?HashSet是如何保证数据不可重复的?

HashSet 检查重复的方式是通过 HashMap 的 key 的唯一性来实现的。当向 HashSet 中添加元素时,HashSet 会将元素作为 HashMap 的 key 存储,而 value 则是一个固定的常量 Object。由于 HashMap 的 key 是唯一的,所以当尝试向 HashSet 中添加重复的元素时,新元素的 key 会与已存在的 key 相同,导致添加操作失败,从而保证了 HashSet 中不会存在重复的元素。

6)HashSet与HashMap的区别

  • 存储方式:HashSet 是基于 HashMap 实现的,底层使用 HashMap 存储元素。
  • 元素类型:HashSet 存储的是不重复的元素,而 HashMap 存储的是键值对(key-value)。
  • 元素顺序:HashSet 是无序的,元素的顺序是不确定的;而 HashMap 是无序的,元素的顺序是由键的哈希值决定的。
  • 元素访问:HashSet 不支持通过索引访问元素;而 HashMap 可以通过键来访问对应的值。
  • 重复元素:HashSet 不允许重复元素的存在,添加重复元素会被忽略;而 HashMap 允许键的重复,但不允许值的重复。
  • 性能:HashSet 的性能略低于 HashMap,因为 HashSet 需要通过哈希计算来确定元素的存储位置,而 HashMap 需要同时存储键和值。

综上所述,HashSet 和 HashMap 在存储方式、元素类型、元素顺序、元素访问、重复元素和性能等方面存在一些区别。选择使用哪个取决于具体的需求和使用场景。

7)BlockingQueue是什么?

BlockingQueue是Java中的一个接口,它表示一个支持线程安全的、有限容量的队列。它定义了一组用于添加、移除、查询元素的方法,以及阻塞等待队列操作的方法。BlockingQueue通常用于多线程环境下的生产者-消费者模型,其中生产者线程将元素放入队列,消费者线程从队列中取出元素进行处理。BlockingQueue提供了一种线程安全的方式来实现线程间的数据传输和同步。

8)说一下 HashMap 的实现原理?

HashMap 是 Java 中常用的数据结构之一,它是基于哈希表实现的。HashMap 通过将键值对存储在一个数组中,并使用键的哈希值来确定存储位置,从而实现快速的插入、删除和查找操作。HashMap 的实现原理如下:

  • HashMap 使用数组和链表(或红黑树)的组合来存储键值对。
  • 当向 HashMap 中插入键值对时,首先根据键的哈希值计算出在数组中的存储位置,如果该位置为空,则直接插入;如果该位置已经存在元素,则通过比较键的哈希值和键的相等性来判断是否为相同的键,如果是相同的键,则更新对应的值;如果是不同的键,则将该键值对添加到链表(或红黑树)的末尾。
  • 当从 HashMap 中获取值时,根据键的哈希值计算出在数组中的存储位置,然后遍历链表(或红黑树)进行比较,找到对应的键值对并返回值。
  • 当从 HashMap 中删除键值对时,根据键的哈希值计算出在数组中的存储位置,然后遍历链表(或红黑树)进行比较,找到对应的键值对并删除。

9)HashMap在JDK1.7和JDK1.8中有哪些不同? HashMap的底层实现

在 JDK 1.7 和 JDK 1.8 中,HashMap 的实现有以下不同之处:

  • JDK 1.7 中的 HashMap 使用数组和链表的组合来存储键值对,当链表长度超过一定阈值时,会将链表转换为红黑树,以提高查找效率。而 JDK 1.8 中引入了红黑树的新实现,即链表长度超过一定阈值时,会进行树化操作,使得整个查找过程更加高效。
  • JDK 1.8 中的 HashMap 在处理哈希冲突时使用了一种新的方式,即通过计算键的哈希值和数组长度的按位与操作来确定存储位置,而不是传统的取模操作,这样可以更快地计算出存储位置。
  • JDK 1.8 中的 HashMap 在扩容时使用了一种新的方式,即将原来的数组分成两个部分,分别处理原数组中的元素和新增元素,减少了元素的复制次数,提高了扩容的效率。

10)HashMap的put方法的具体流程?

HashMap 的 put 方法的具体流程如下:

  • 首先,根据键的哈希值计算出在数组中的存储位置。
  • 如果该位置为空,则直接将键值对插入到该位置。
  • 如果该位置已经存在元素,则遍历链表(或红黑树)进行比较,找到对应的键值对。
  • 如果找到了相同的键,则更新对应的值。
  • 如果找到了不同的键,则将该键值对添加到链表(或红黑树)的末尾。
  • 如果链表(或红黑树)的长度超过一定阈值,进行相应的转换操作(链表转换为红黑树,或红黑树转换为链表)。
  • 如果数组的使用空间超过了负载因子(默认为 0.75)乘以数组长度的阈值,进行扩容操作,将原来的数组扩大一倍,并重新计算存储位置。

通过以上流程,HashMap 的 put 方法可以实现将键值对添加到 HashMap 中,并根据键的哈希值进行查找和更新操作。

开源项目地址:https://gitee.com/falle22222n-leaves/vue_-book-manage-system

前后端总计已经 800+ Star,1.5W+ 访问!

⭐点赞⭐收藏⭐不迷路!⭐

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小白条

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值