您的位置:首页 > 职场人生

博为峰Java面试题-Java集合类2

2016-10-26 00:00 183 查看
[面试原题]

[题目一] Java的HashMap是如何工作的?

[正确答案]

博为峰小博老师

HashMap是一个针对数据结构的键值,每个键都会有相应的值,关键是识别这样的值。

HashMap 基于 hashing 原理,我们通过 put ()和 get ()方法储存和获取对象。当我们将键值对传递给 put ()方法时,它调用键对象的 hashCode ()方法来计算 hashcode,让后找到 bucket 位置来储存值对象。当获取对象时,通过键对象的 equals ()方法找到正确的键值对,然后返回值对象。HashMap 使用 LinkedList 来解决碰撞问题,当发生碰撞了,对象将会储存在 LinkedList 的下一个节点中。 HashMap 在每个 LinkedList 节点中储存键值对对象。



[题目二] 什么是快速失败的故障安全迭代器??

[正确答案]

博为峰小博老师

快速失败的Java迭代器可能会引发ConcurrentModifcationException在底层集合迭代过程中被修改。故障安全作为发生在实例中的一个副本迭代是不会抛出任何异常的。快速失败的故障安全范例定义了当遭遇故障时系统是如何反应的。例如,用于失败的快速迭代器ArrayList和用于故障安全的迭代器ConcurrentHashMap。

[题目三] 什么时候使用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是一个接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  博为峰 java 面试题