java基础面试题(三)附答案
-
请说明List、Map、Set三个接口分别存取元素时各有什么特点?
List以特定索引来存取元素,可以有重复元素
Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)
Map保存键值对(k-v)映射,映射关系可以是一对一或一对多
Set和Map容器都有基于哈希存储和排序树的两个实现版本,基于哈希存储的版本存取时间复杂度为O(1),基于排序树版本的实现在插入和删除元时会按照元素会元素的(k)构成排序树从而达到排序和去重的效果。
-
说明ArrayList和Vector的区别
- 线程安全
- 在多并发情况下ArrayList存储数据是线程不安全的,(使用CopyOnWriteArrayList)
- Vector存储数据是安全的;Vector的实现方法基本都用了synchronize修饰,在存储时会有加锁安全;
- 初始大小和扩容
- ArrayList初始大小为0,若放入一个元素,数据扩容大小为10,若数组容量不够时,扩容到原来的0.5倍;
- Vector初始大小为10,若数组容量不够时,扩容到原来的1倍;
- 底层实现
- ArrayList和Vector底层实现都是动态数组
- 存储效率
- 因为Vector调用方法存储数据会获取锁资源和释放锁,相比ArrayList效率较慢;
- 线程安全
-
LinkedList和ArrayList有什么区别?
- LinkedList底层实现是使用双向链表(JDK6使用的循环链表,JDK7去除了循环),ArrayList底层实现是动态数组;
- LinkedList在插入,删除,修改数据时,因为使用的是链表存储,所以效率比较高,时间复杂度为O(1),ArrayList使用的数组在存取修改时候需要移动元素,所以效率较慢,时间复杂度为O(n);
- ArrayList实现了RandomAccess接口(支持随机访问),而LinkedList没有实现(不支持随机访问);
- ArrayList所存储元素占用空间内存较小,而LinkedList较大,需要存放(pre+data+next);
-
说明Collection和Collections的区别
- Collection是一个接口,是除k-v接口的父类接口,下面有set和List子接口,用于数据存储;
- Collections是一个类,里面有大量的静态方法,类似Arrays类一样,用于集合的遍历等操作,比如(迭代器、synchronize块)
-
请你说明HashMap和HashTable的区别
- 底层实现
- HashMap底层是红黑树+数组+链表实现的(JDK8以后)
- HashTable底层是数组+链表
- 线程安全
- HashMap是线程不安全的,在并发操作时可能会产生死循环transfer函数尾插法(JDK7),数据覆盖并发put(JDK8);
- HashTable是线程安全的,所实现类都是用synchronize关键字修饰的;
- 扩容方式(默认的和自定义的)
- HashMap默认情况下容量的大小是16;扩容时变为原来的1倍;HashMap自定义容量是时2的N次幂大小;
- HashTable默认情况下的初识容量为11;扩容时变为原来大小的1倍+1;HashTable自定义容量是时默认值;
- 底层实现
-
fail-fast和fail-safe的区别
-
fail-fast机制
这是HashMap集合的机制,如果在循环Map集合时去改变集合的数据,就会报出ConcurrentModifitionException错误。
-
fail-safe机制
-
-
请你说明一下ConcurrentHashMap的原理
ConcurrentHashMap是一个线程安全的Map集合,支持并发读取数据,一个线程读取某一个数据,而别的线程也可以去读取其他的数据;
底层实现是使用Segement数组实现的(JDK7),一个Segement被一个Segement锁而包括
维护了一个Segement数组,每一个Segement里面包含了一个Entry<k,v>链表,获取每一个Segement就需要获取Segement的锁
JDK8使用synchronize锁和CAS,volatile等实现的
-
ConcurrentHashMap有说明优势?在jdk1.7和jdk1.8有什么区别?
线程安全,支持并发访问。
-
解释一下为什么HashMap的容量是2的幂次方?
HashMap的初始容量是16,也是2的幂次方。这是在小数据的情况下为了避免hash冲突而设置的数字,因为在大小是2的幂次方的情况下,n-1&HashCode计算出来的值分部均匀而且产生的避免hash最少。
-
HashMap的底层是怎么实现的?在jdk1.7和jdk1.8有什么区别?
HashMap底层是数组+链表+红黑树实现的
- 当每加入一个数据时,该数据是一个Entry对象,此对象里面有插入数据的HashCode值,K-V值,Next引用(用于指向下一个对象),存入数据时根据HashCode判断有无冲突,没有就直接存放,产生Hash冲突判断K是否相同,相同则覆盖数据,不同的话直接链入链表,使用Next引用指向(链地址法);
- 当数组大小大于64或者链表长度大于阈值(默认是8)时,数组将变成红黑树存储数据,提高效率。
JDK7没有添加红黑树的概念,底层是数组+链表实现的。