关于一些java面试题的思考--java集合篇
第一题:对java集合的了解?
答:常见集合如下图所示
集合中一些常考题:
(1)HashMap 和Hashtable的区别有哪些?
答:hashMap 没有考虑线程同步,是线程不安全的,hashtable使用了Synchronize关键字,是线程安全的。同事前者允许null作为key;后者不允许null作为key
(2)HashMap的底层实现?
答:在java8之前,其底层实现是数组+链表实现,java8使用了数组+链表+红黑树实现。
(3)ConcurrentHashMap和Hashtable的区别?
答:ConcurrentHashMap 结合了HashMap和HashTab二者的优势。HashMap没有考虑同步,HashTable考虑到了同步的问题。但是HashTable在每次同步执行时都要锁住整个结构。ConcurrentHashMap锁的方式是稍微细粒度的。它将hash表分为16个桶(默认值),诸如get,put,remove等常用操作都只锁住当前所需要的桶。
(4)ConcurrentHashMap 的具体实现?
答:该类包含两个静态内部类 HashEntry 和 Segment;前者用来封装映射表的键值对,后者用来充当锁的角色;Segment 是一种可重入的锁 ReentrantLock,每个 Segment 守护一个 HashEntry 数组里得元素,当对 HashEntry 数组的数据进行修改时,必须首先获得对应的 Segment 锁。
(5)list和set有什么区别?
答:list是元素是有序的,可以重复的,set是元素无序的,不可以重复的
(6)ArrayList和LinkedList的用法区别?
答:ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。LinkedList经常用在增删操作较多而查询操作很少的情况下,ArrayList则相反用在查询较多而增删操作较少的情况下。ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
(7)Vector和ArrayList的区别
答:vector是线程同步的,所以它也是线程安全的,而ArrayList是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用ArrayList效率比较高。
(8)对Stack了解多少?
答:Java 集合框架中的 Stack 继承自 Vector:跟 Vector 一样,它是 数组实现的栈。栈是一种线性数据结构,遵从 LIFO(后进先出)的操作顺序,所有操作都是在顶部进行。
(9)java集合的快速失败机制 “fail-fast”
答:它是 java 集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生 fail-fast 机制。
例如:假设存在两个线程(线程 1、线程 2),线程 1 通过 Iterator 在遍历集合 A 中的元素,在某个时候线程 2 修改了集合 A 的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生 fail-fast 机制。
原因:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变 modCount 的值。每当迭代器使用 hashNext()/next() 遍历下一个元素之前,都会检测 modCount 变量是否为 expectedmodCount 值,是的话就返回遍历;否则抛出异常,终止遍历。
解决方法:(1)在遍历过程中,所有涉及到改变 modCount 值得地方全部加上 synchronized;(2)使用 CopyOnWriteArrayList 来替换 ArrayList。