[面试原题]java
[题目一] Java的HashMap是如何工做的?面试
[正确答案]算法
博为峰小博老师:数组
HashMap是一个针对数据结构的键值,每一个键都会有相应的值,关键是识别这样的值。缓存
HashMap 基于 hashing 原理,咱们经过 put ()和 get ()方法储存和获取对象。当咱们将键值对传递给 put ()方法时,它调用键对象的 hashCode ()方法来计算 hashcode,让后找到 bucket 位置来储存值对象。当获取对象时,经过键对象的 equals ()方法找到正确的键值对,而后返回值对象。HashMap 使用 LinkedList 来解决碰撞问题,当发生碰撞了,对象将会储存在 LinkedList 的下一个节点中。 HashMap 在每一个 LinkedList 节点中储存键值对对象。安全
[正确答案]数据结构
博为峰小博老师:多线程
快速失败的Java迭代器可能会引起ConcurrentModifcationException在底层集合迭代过程当中被修改。故障安全做为发生在实例中的一个副本迭代是不会抛出任何异常的。快速失败的故障安全范例定义了当遭遇故障时系统是如何反应的。例如,用于失败的快速迭代器ArrayList和用于故障安全的迭代器ConcurrentHashMap。并发
[正确答案]性能
在问题二中咱们看到ConcurrentHashMap被做为故障安全迭代器的一个实例,它容许完整的并发检索和更新。当有大量的并发更新时,ConcurrentHashMap此时能够被使用。这很是相似于Hashtable,但ConcurrentHashMap不锁定整个表来提供并发,因此从这点上ConcurrentHashMap的性能彷佛更好一些。因此当有大量更新时ConcurrentHashMap应该被使用。
[题目四] List怎么实现了最快插入?
[正确答案]
LinkedList和ArrayList是另个不一样变量列表的实现。ArrayList的优点在于动态的增加数组,很是适合初始时总长度未知的状况下使用。LinkedList的优点在于在中间位置插入和删除操做,速度是最快的。
LinkedList实现了List接口,容许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操做使LinkedList可被用做堆栈(stack),队列(queue)或双向队列(deque)。
ArrayList实现了可变大小的数组。它容许全部元素,包括null。 每一个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增长,可是增加算法并无定义。当须要插入大量元素时,在插入前能够调用ensureCapacity方法来增长ArrayList的容量以提升插入效率。
[题目五] 如何保证一个集合线程安全?
[正确答案]
Vector, Hashtable, Properties 和 Stack 都是同步的类,因此它们都线程安全的,能够被使用在多线程环境中
. 使用Collections.synchronizedList(list)) 方法,能够保证 list 类是线程安全的
· 使用java.util.Collections.synchronizedSet() 方法能够保证 set 类是线程安全的
[题目六] hashCode()和equals()方法有何重要性?
[正确答案]
HashMap使用Key对象的hashCode()和equals()方法去决定key-value对的索引。当咱们试着从HashMap中获取值的时候,这些方法也会被用到。若是这些方法没有被正确地实现,在这种状况下,两个不一样Key也许会产生相同的hashCode()和equals()输出,HashMap将会认为它们是相同的,而后覆盖它们,而非把它们存储到不一样的地方。一样的,全部不容许存储重复数据的集合类都使用hashCode()和equals()去查找重复,因此正确实现它们很是重要。equals()和hashCode()的实现应该遵循如下规则:
1.若是o1.equals(o2),那么o1.hashCode() == o2.hashCode()老是为true的。
2.若是o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。
[题目七] 可否使用任何类做为Map的key?
[正确答案]
咱们可使用任何类做为Map的key,然而在使用它们以前,须要考虑如下几点:
(1)若是类重写了equals()方法,它也应该重写hashCode()方法。
(2)类的全部实例须要遵循与equals()和hashCode()相关的规则。请参考以前提到的这些规则。
(3)若是一个类没有使用equals(),你不该该在hashCode()中使用它。
(4)用户自定义key类的最佳实践是使之为不可变的,这样,hashCode()值能够被缓存起来,拥有更好的性能。不可变的类也能够确保hashCode()和equals()在将来不会改变,这样就会解决与可变相关的问题了。
这就是为什么String和Integer被做为HashMap的key大量使用。
[题目八] 咱们如何对一组对象进行排序?
[正确答案]
若是咱们须要对一个对象数组进行排序,咱们可使用Arrays.sort()方法。若是咱们须要排序一个对象列表,咱们可使用Collection.sort()方法。两个类都有用于天然排序(使用Comparable)或基于标准的排序(使用Comparator)的重载方法sort()。Collections内部使用数组排序方法,全部它们二者都有相同的性能,只是Collections须要花时间将列表转换为数组。
[题目九] 并发集合类是什么?
[正确答案]
Java1.5并发包(java.util.concurrent)包含线程安全集合类,容许在迭代时修改集合。迭代器被设计为fail-fast的,会抛出ConcurrentModificationException。一部分类为:CopyOnWriteArrayList、 ConcurrentHashMap、CopyOnWriteArraySet。
[题目十] 队列和栈是什么,列出它们的区别?
[正确答案]
栈和队列二者都被用来预存储数据。java.util.Queue是一个接口,它的实现类在Java并发包中。队列容许先进先出(FIFO)检索元素,但并不是老是这样。Deque接口容许从两端检索元素。
栈与队列很类似,但它容许对元素进行后进先出(LIFO)进行检索。
Stack是一个扩展自Vector的类,而Queue是一个接口。