JAVA集合和数据结构也是面试常考的点,内容也是比较多。
在看之前希望各位如果方便可以点赞收藏,给我点个关注,创作不易!
JAVA集合
21. ConcurrentHashMap 的并发度是多少?
在JDK1.7中,并发度默认是16,这个值可以在构造函数中设置。如果自己设置了并发度,ConcurrentHashMap
会使用大于等于该值的最小的2的幂指数作为实际并发度,也就是比如你设置的值是17,那么实际并发度是32。
22. ConcurrentHashMap 迭代器是强一致性还是弱一致性?
与HashMap
迭代器是强一致性不同,ConcurrentHashMap
迭代器是弱一致性。
ConcurrentHashMap
的迭代器创建后,就会按照哈希表结构遍历每个元素,但在遍历过程中,内部元素可能会发生变化,如果变化发生在已遍历过的部分,迭代器就不会反映出来,而如果变化发生在未遍历过的部分,迭代器就会发现并反映出来,这就是弱一致性。
这样迭代器线程可以使用原来老的数据,而写线程也可以并发的完成改变,更重要的,这保证了多个线程并发执行的连续性和扩展性,是性能提升的关键。
23. JDK1.7与JDK1.8 中ConcurrentHashMap 的区别?
- 数据结构:取消了
Segment
分段锁的数据结构,取而代之的是数组+链表+红黑树的结构。 - 保证线程安全机制:JDK1.7采用
Segment
的分段锁机制实现线程安全,其中segment
继承自ReentrantLock
。JDK1.8 采用CAS+Synchronized
保证线程安全。 - 锁的粒度:原来是对需要进行数据操作的
Segment
加锁,现调整为对每个数组元素加锁(Node)。 - 链表转化为红黑树:定位结点的hash算法简化会带来弊端,Hash冲突加剧,因此在链表节点数量大于8时,会将链表转化为红黑树进行存储。
- 查询时间复杂度:从原来的遍历链表O(n),变成遍历红黑树O(logN)。
24. ConcurrentHashMap 和Hashtable的效率哪个更高?为什么?
ConcurrentHashMap
的效率要高于Hashtable
,因为Hashtable
给整个哈希表加了一把大锁从而实现线程安全。而ConcurrentHashMap
的锁粒度更低,在JDK1.7中采用分段锁实现线程安全,在JDK1.8 中采用CAS+Synchronized
实现线程安全。
25. 说一下Hashtable的锁机制 ?
Hashtable
是使用Synchronized
来实现线程安全的,给整个哈希表加了一把大锁,多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞等待需要的锁被释放,在竞争激烈的多线程场景中性能就会非常差!
26. 多线程下安全的操作 map还有其他方法吗?
还可以使用Collections.synchronizedMap
方法,对方法进行加同步锁
private static class SynchronizedMap<K,V>
implements Map<K,V>, Serializable {
private static final long serialVersionUID = 1978198479659022715L;
private final Map<K,V> m; // Backing Map
final Object mutex; // Object on which to synchronize
SynchronizedMap(Map<K,V> m) {
this.m = Objects.requireNon null (m);
mutex = this;
}
SynchronizedMap(Map<K,V> m, Object mutex) {
this.m = m;
this.mutex = mutex;
}
// 省略部分代码
}
如果传入的是 HashMap 对象,其实也是对 HashMap 做的方法做了一层包装,里面使用对象锁来保证多线程场景下,线程安全,本质也是对 HashMap 进行全表锁。在竞争激烈的多线程环境下性能依然也非常差,不推荐使用!
27. HashSet 和 HashMap 区别?
补充HashSet的实现:HashSet的底层其实就是HashMap,只不过我们HashSet是实现了Set接口并且把数据作为K值,而V值一直使用一个相同的虚值来保存。如源码所示:
public boolean add(E e) {
return map.put(e, PRESENT)==null;// 调用HashMap的put方法,PRESENT是一个至始至终都相同的虚值
}
由于HashMap的K值本身就不允许重复,并且在HashMap中如果K/V相同时,会用新的V覆盖掉旧的V,然后返回旧的V,那么在HashSet中执行这一句话始终会返回一个false,导致插入失败,这样就保证了数据的不可重复性。
28. Collection框架中实现比较要怎么做?
第一种,实体类实现Comparable
接口,并实现 compareTo(T t)
方法,称为内部比较器。
第二种,创建一个外部比较器,这个外部比较器要实现Comparator
接口的 compare(T t1, T t2)
方法。
29. Iterator 和 ListIterator 有什么区别?
-
遍历。
- 使用Iterator,可以遍历所有集合,如Map,List,Set;但只能在向前方向上遍历集合中的元素。
- 使用ListIterator,只能遍历List实现的对象,但可以向前和向后遍历集合中的元素。
-
添加元素。Iterator无法向集合中添加元素;而,ListIteror可以向集合添加元素。
-
修改元素。Iterator无法修改集合中的元素;而,ListIterator可以使用set()修改集合中的元素。
-
索引。Iterator无法获取集合中元素的索引;而,使用ListIterator,可以获取集合中元素的索引。
总结:数据结构和集合这快的面试考点还是很多的,希望大家仔细看看,这只是一部分。我们分三部分来更新。
多谢大家支持!!!
如果没看过前几篇的文章的,可以点击链接去看看,如果方便可以点赞收藏,给我点个关注,创作不易!
JAVA基础面试题(第九篇)中! 集合与数据结构
JAVA基础面试题(第八篇)上! 集合与数据结构
JAVA基础面试题(第七篇)!异常
JAVA基础面试题(第六篇)!序列化与IO流
JAVA基础面试题(第五篇)!反射与泛型
JAVA基础面试题(第四篇)!equal、hashcode及String解析
JAVA基础面试题(第三篇)!面向对象
JAVA基础面试题(第二篇)!基础语法与关键字
JAVA基础面试题(第一篇)!