Java集合面试题汇总(不定期更新)

1.判断一个集合类是否为线程安全的机制是什么?

怎么判断一个Java类是否是线程安全?有那些角度?_不积跬步,无以致千里的博客-CSDN博客_java怎么判断线程是否安全

2.说一下 Fail-Fast 机制,结合源码 说一下(如果可以的话) 

3.Java中有哪些容器(集合类)? 

Java中的集合类主要由Collection和Map这两个接口派生而出,其中Collection接口又派生出三个子接口,分别是Set、List、Queue。所有的Java集合类,都是Set、List、Queue、Map这四个接口的实现类,这四个接口将集合分成了四大类,其中

  • Set代表无序的,元素不可重复的集合;

  • List代表有序的,元素可以重复的集合;

  • Queue代表先进先出(FIFO)的队列;

  • Map代表具有映射关系(key-value)的集合。

这些接口拥有众多的实现类,其中最常用的实现类有HashSet、TreeSet、ArrayList、LinkedList、ArrayDeque、HashMap、TreeMap等。

4.Java中的容器,线程安全和线程不安全的分别有哪些?

java.util包下的集合类大部分都是线程不安全的,例如我们常用的HashSet、TreeSet、ArrayList、LinkedList、ArrayDeque、HashMap、TreeMap,这些都是线程不安全的集合类,但是它们的优点是性能好。如果需要使用线程安全的集合类,则可以使用Collections工具类提供的synchronizedXxx()方法,将这些集合类包装成线程安全的集合类。

java.util包下也有线程安全的集合类,例如Vector、Hashtable。这些集合类都是比较古老的API,虽然实现了线程安全,但是性能很差。所以即便是需要使用线程安全的集合类,也建议将线程不安全的集合类包装成线程安全集合类的方式,而不是直接使用这些古老的API。

从Java5开始,Java在java.util.concurrent包下提供了大量支持高效并发访问的集合类,它们既能包装良好的访问性能,有能包装线程安全。这些集合类可以分为两部分,它们的特征如下:

  • 以Concurrent开头的集合类:

    以Concurrent开头的集合类代表了支持并发访问的集合,它们可以支持多个线程并发写入访问,这些写入线程的所有操作都是线程安全的,但读取操作不必锁定。以Concurrent开头的集合类采用了更复杂的算法来保证永远不会锁住整个集合,因此在并发写入时有较好的性能。

  • 以CopyOnWrite开头的集合类:

    以CopyOnWrite开头的集合类采用复制底层数组的方式来实现写操作。当线程对此类集合执行读取操作时,线程将会直接读取集合本身,无须加锁与阻塞。当线程对此类集合执行写入操作时,集合会在底层复制一份新的数组,接下来对新的数组执行写入操作。由于对集合的写入操作都是对数组的副本执行操作,因此它是线程安全的。

Java:CAS(乐观锁) - 简书 (jianshu.com)

什么是CAS机制?如何解决ABA问题?_小问号阿的博客-CSDN博客

ReentrantLock详解_SunStaday的博客-CSDN博客_reentrantlock

AQS详解(面试)_木霖森77的博客-CSDN博客_aqs

JAVA Semaphore详解 - 简单爱_wxg - 博客园 (cnblogs.com)

ArrayList

相关阅读:

ArrayList源码分析(扩容机制jdk8) - 掘金 (juejin.cn)

1.ArrayList 初始化时数组的默认长度是多少?

        默认长度为10。但是ArrayList的默认长度是有jdk版本差异的,在jdk8版本之前默认长度是10。而在jdk8版本的时候对ArrayList数组的默认长度进行了优化,将原来的默认长度10,改为了初始长度为0。当我们在首次添加元素,需要分配数组空间时,jdk自动帮我们进行了扩容操作,将初始数组长度扩容成了10。这样做有效地降低了无用内存的占用!它利用了数组扩容的特性来完成集合的这些功能,这也就是ArrayList集合查询快、增删慢的原因了!

2.ArrayList 扩容是扩容多少倍?扩容后是用原来的数组还是新的数组?

        新的容量是旧容量加上旧容量值右移一位得到的,一个数右移n(n>0)位的结果等于这个数除以2^n的整数部分;新数组。

3.ArrayList 是一个线程安全的集合类吗?

不是。

解决ArrayList线程不安全方案

4.ArrayList 和 LinkedList 的使用场景

(1)如果应用程序对数据有较多的随机访问,ArrayList对象要优于LinkedList对象;

  ( 2 ) 如果应用程序有更多的插入或者删除操作,较少的随机访问,LinkedList对象要优于ArrayList对象;

(3)不过ArrayList的插入,删除操作也不一定比LinkedList慢,如果在List靠近末尾的地方插入,那么ArrayList只需要移动较少的数据,而LinkedList则需要一直查找到列表尾部,反而耗费较多时间,这时ArrayList就比LinkedList要快。

5.谈谈CopyOnWriteArrayList的原理?

Java CopyOnWriteArrayList详解 - 简书 (jianshu.com)

LinkedList

相关阅读:

Java如何实现LinkedList按索引下标进行插入 - 枫叶像思念 - 博客园 (cnblogs.com)

HashMap

1.HashMap实现原理?

HashMap的实现原理_〆、风神的博客-CSDN博客_hashmap底层实现原理

2.如何得到一个线程安全的Map?

  1. 使用Collections工具类,将线程不安全的Map包装成线程安全的Map;

  2. 使用java.util.concurrent包下的Map,如ConcurrentHashMap;

  3. 不建议使用Hashtable,虽然Hashtable是线程安全的,但是性能较差。

3.介绍一下HashMap的扩容机制?

Hashmap实现原理及扩容机制详解_lkforce的博客-CSDN博客_hashmap扩容机制

4.说一说HashMap和HashTable的区别

HashMap和Hashtable的区别_xuhuaabc的博客-CSDN博客_hashmap和hashtable

 

5.hashmap为什么线程不安全?

首先HashMap是线程不安全的,其主要体现:

#1.在jdk1.7中,在多线程环境下,扩容时会造成环形链或数据丢失。

#2.在jdk1.8中,在多线程环境下,会发生数据覆盖的情况。

面试官:HashMap 为什么线程不安全? - 腾讯云开发者社区-腾讯云 (tencent.com)

 

6.介绍一下ConcurrentHashMap是怎么实现的?

1.7

漫画:什么是ConcurrentHashMap? - 知乎 (zhihu.com)

ConcurrentHashMap(JDK8) - 腾讯云开发者社区-腾讯云 (tencent.com)

7.说一说HashSet的底层结构?

HashSet是基于HashMap实现的,默认构造函数是构建一个初始容量为16,负载因子为0.75 的HashMap。它封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT,它是一个静态的 Object 对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值