Java集合面试题(五)

1、ArrayList默认大小以及如何扩容

1)默认大小:10,如下图:

2)如何扩容:当容量不足时,默认扩容为原来的1.5倍

2、简述ArrayList和LinkedList的区别

共同点:两者都实现了List接口。

区别:

1)数据结构

ArrayList底层数据结构是数组。

LinkedList底层数据结构是双向链表。

2)读写性能

对于查询操作,ArrayList性能更优,因为ArrayList根据下标对元素进行随机访问,时间复杂度为O(1),而LinkedList由于每个元素连接在一起,不能随机访问,因此查询时间复杂度为O(n)。

对于插入和删除操作,LinkedList性能更优,因为LinkedList只需要更新前后元素的引用,而ArrayList需要重新挪动元素的位置。

3)内存消耗

LinkedList更耗内存,这是由于LinkedList中的底层数据结构是双向链表,链表的显著特征是每个节点都要维护前后元素的节点地址,意味着LinkedList中的每个节点既要存储数据,还要存储前后元素的节点地址。

3、简述ArrayList和Vector的区别

共同点

1)两者都是基于索引,内部由一个数组进行操作。

2)两者都维护插入元素的顺序,可以根据插入顺序来获取元素。

3)两者的迭代器实现都是fail-fast。

4)两者都允许null值,也允许使用索引值随机读取元素。

区别

1)Vector是线程安全,因此性能低于ArrayList。

2)ArrayList扩容为原来的1.5倍,而Vector扩容为原来的2倍,而且Vector还可以设置增长空间的大小。

4、简述CopyOnWriteArrayList

CopyOnWriteArrayList是ArrayList的线程安全版。

它的实现原理是在添加元素的时候对方法加锁,先把原List集合复制一份,再添加新的元素,这样就实现了线程安全,如下是添加元素的源码:

// CopyOnWriteArrayList的add方法源码
public boolean add(E e) {
	// 加锁
	final ReentrantLock lock = this.lock;
	lock.lock();
	try {
		// 获取原始集合
		Object[] elements = getArray();
		int len = elements.length;
		
		// 复制一个新集合
		Object[] newElements = Arrays.copyOf(elements, len + 1);
		newElements[len] = e;
		
		// 替换原始集合为新集合
		setArray(newElements);
		return true;
	} finally {
		// 释放锁
		lock.unlock();
	}
}

5、简述CopyOnWriteArraySet

CopyOnWriteArraySet是HashSet的线程安全版。

它的实现原理是使用CopyOnWriteArrayList的addAllAbsent()方法进行去重,添加元素的时候先判断元素是否存在,不存在才进行操作,如下是部分源码:

6、CopyOnWrite* 并发集合

描述:CopyOnWrite简称COW,即复制再写入

1)优点和应用场景:优点是写入数据时加锁,读取数据时不加锁,在多线程并发操作中既保证了线程安全,又可以保证读取性能。应用场景为读多写少

2)缺点:不适用于写多读少的场景,因为每次写入数据都要对集合进行复制,频繁的写入会使性能和内存的开销较大,如果集合很大,还容易造成内存溢出。

7、fail-fast和fail-safe

fail-fast和fail-safe是集合中的一种错误处理机制。

1)fail-fast:即快速失败,当迭代器遍历集合时,如果集合结构发生了变更操作(修改、删除),迭代器则会抛出ConcurrentModificationException异常。

java.util包中的所有集合类都被设计为fail-fast类型,比如常用的ArrayList、HashMap等。

2)fail-safe:即安全失败,当迭代器遍历集合时,会先复制一份再进行遍历,因此原集合的结构发生变更操作不会影响复制集合的遍历,也不会抛出ConcurrentModificationException异常。

java.util.concurrent包中的并发集合类都被设计为fail-safe类型,比如CopyOnWrite*、ConcurrentHashMap等。

8、HashSet是线程安全吗

HashSet不是线程安全,它所有方法都没有syncrhonized修饰,底层是通过HashMap进行去重,如下为部分源码:

9、常见线程安全的Set集合

1)SynchronizedSet:会对关键方法加锁,性能较低。

2)CopyOnWriteArraySet:原理是先复制再写入,适合读多写少的场景,性能较高。

10、HashSet的元素是有序的吗

HashSet的元素不是有序的,其底层是使用HashMap实现,HashMap是按照key的hashCode值计算出数组的索引进行存储,所以元素没有顺序。下图为部分HashSet源码:

本篇面试题到此结束~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值