JDK集合面试题大全

JDK集合面试题大全


目录

文档索引

面试题汇总

Q:JDK提供的集合中,哪些是线程安全,哪些是线程不安全?

Q: List实现类的区别和使用场景

Q: HashMap的实现原理

Q: Map实现类之间的区别和使用场景

Q:Set实现类之间的区别和使用场景

Q: JDK7和JDK8对HashMap实现的不同


文档索引


面试题汇总

Q:JDK提供的集合中,哪些是线程安全,哪些是线程不安全

线程不安全:

List(ArrayList、LinkedList)

Map(HashMap、LinkedHashMap、TreeMap)

Set(HashSet、LinkedHashSet、TreeSet)

Queue

线程安全:

List(Vector、Collections.synchronizedList、CopyOnWriteArrayList)

Map(Hashtable、Collections.synchronizedMap、ConcurrentHashMap)

Set(Collections.synchronizedSet、CopyOnWriteArraySet)

Queue

Q: List实现类的区别和使用场景

A:

ArrayList:

底层为数组,初始化为空数组,当开始add时,初始化为长度10的数组。

扩容机制:通过arrayCopy将数组扩容,扩容长度为原长度的1.5倍

优势:通过下标访问,效率相对高。但add或remove时,因为需要对下标后所有元素都需移动,效率较低。

风险:当申请的数组大小超出剩余内存大小时,抛出OOM:异常

LinkedList:

底层为双向链表

扩容机制:因为是通过链表组织,无需扩容

优势:需通过头节点或尾节点访问指定节点,效率较低。但add或remove时,因为只需要对前后节点的指向做变更,效率较高。

风险:当链表长度过长,超出剩余内存大小时,抛出OOM:异常

Vector:

底层与ArrayList类似,但是方法加了synchronized保证线程安全

扩容机制、优势、风险:与ArrayList类似

Collections.synchronizedList:

通过synchronized对传入的list保证线程安全,锁对象可通过参数传入,或默认this

扩容机制、优势、风险:与传入list一致

CopyOnWriteArrayList:

底层为数组,初始化为空数组,每次add或remove在会创建一个新数组,在新数组执行完操作后,再设置为当前数组,通过ReentrantLock实现线程安全。

扩容机制:因为每次add都会创建一个新数组,故无扩容机制

优势:前两种在get时都加了锁,导致get效率差。而CopyOnWriteArrayList的get无需加锁,效率较高。

风险:每次add都需创建一个新数组,针对写多读少的场景效率差。

Q: HashMap的实现原理

A:

底层为数组+单链表,初始化为长度为16的数组,通过对key的hashCode进行hash,分配至不同的下标元素中,如下标元素已有节点,则作为链表节点插入。

jdk7使用头插法,但该方法在多线程时会导致环形链表,jdk8改用尾插法。

因为链表长度过长时,查询效率差,jdk8在链表长度超过8时,转化为红黑树结构。

扩容机制:将数组长度扩充为原来的两倍。jdk7通过对每个节点重hash进行分配,jdk8优化为通过多出的高位,判断节点是位于原位置还是原位置+扩充长度的位置。

风险:当申请的数组大小超出剩余内存大小时,抛出OOM:异常

Q: Map实现类之间的区别和使用场景

A:

HashMap:

底层为数组+单链表,初始化为长度为16的数组,通过对key的hashCode进行hash,分配至不同的下标元素中,如下标元素已有节点,则作为链表节点插入。

jdk7使用头插法,但该方法在多线程时会导致环形链表,jdk8改用尾插法。

因为链表长度过长时,查询效率差,jdk8在链表长度超过8时,转化为红黑树结构。

扩容机制:将数组长度扩充为原来的两倍。jdk7通过对每个节点重hash进行分配,jdk8优化为通过多出的高位,判断节点是位于原位置还是原位置+扩充长度的位置。

风险:当申请的数组大小超出剩余内存大小时,抛出OOM:异常

LinkedHashMap:

在hashmap的基础上,对每个节点增加了前后指针,用双向链表将每个节点组织起来,可通过插入顺序或访问顺序来进行遍历。

扩容机制:与HashMap类似

优势:可通过节点的前后指针顺序遍历,可作为LRU缓存。

风险:与HashMap类似

TreeMap:

底层为红黑树,通过传入的Comparator实现排序

扩容机制:无需扩容

优势:实现自定义排序算法的map

风险:与HashMap类似

Hashtable:

底层与HashMap类似,但是方法加了synchronized保证线程安全

扩容机制、优势、风险:与HashMap类似

Collections.synchronizedMap:

通过synchronized对传入的map保证线程安全,锁对象可通过参数传入,或默认this

扩容机制、优势、风险:与传入map一致

ConcurrentHashMap:

jdk7底层为分段锁,分段锁继承ReentrantLock,通过lock实现线程安全,初始化为16个分段锁,每个分段锁持有一个长度为2的数组。

该结构存在每个分段锁都需对数组长度扩容的耗费,jdk8底层为数组+单链表+红黑树,与HashMap相似,利用CAS+volatile+synchronized保证线程安全

扩容机制:jdk7每个分段锁的数组会自行扩容,扩容规则与HashMap相似。

优势:前两种在get时都加了锁,导致get效率差。而ConcurrentHashMap的get无需加锁,效率较高。

风险:

Q:Set实现类之间的区别和使用场景

A:

Set的底层通过持有Map实现,key存传入的集合值,value则存Object。

HashSet、LinkedHashSet和TreeSet底层对应的HashMap、LinkedHashMap和TreeMap,扩容机制、优势与风险一致。

Collections.synchronizedSet:

通过synchronized对传入的set保证线程安全,锁对象可通过参数传入,或默认this

扩容机制、优势、风险:与传入set一致

CopyOnWriteArraySet:

底层为CopyOnWriteArrayList,利用addIfAbsent实现去重,扩容机制、优势与风险和CopyOnWriteArrayList一致。

Q: JDK7和JDK8对HashMap实现的不同

A:JDK8中,对HashMap的实现进行优化,如链表长度超过指定长度(默认15),则会转化为红黑树进行存储。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值