阿里P6面试题及答案( 三 )


16.什么是死锁(deadlock)?

所谓死锁是指多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进 。死锁产生的4个必要条件:
互斥条件:进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某 资源仅为一个进程所占有 。此时若有其他进程请求该资源,则请求进程只能等待 。
不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放) 。
请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放 。
循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求 。
17.如何确保N个线程可以访问N个资源同时又不导致死锁?
使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁 。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了 。
18.Java集合类框架的基本接口有哪些?
集合类接口指定了一组叫做元素的对象 。集合类接口的每一种具体的实现类都可以选择以它自己的方式对元素进行保存和排序 。有的集合类允许重复的键,有些不允许 。
Java集合类提供了一套设计良好的支持对一组对象进行操作的接口和类 。Java集合类里面最基本的接口有:
Collection:代表一组对象,每一个对象都是它的子元素 。
Set:不包含重复元素的Collection 。
List:有顺序的collection,并且可以包含重复元素 。
Map:可以把键(key)映射到值(value)的对象,键不能重复 。
19.为什么集合类没有实现Cloneable和Serializable接口?
克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的 。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化 。
20.什么是迭代器(Iterator)?
Iterator接口提供了很多对集合元素进行迭代的方法 。每一个集合类都包含了可以返回迭代器实例的
迭代方法 。迭代器可以在迭代的过程中删除底层集合的元素,但是不可以直接调用集合的
remove(Object Obj)删除,可以通过迭代器的remove()方法删除 。
21.Iterator和ListIterator的区别是什么?
下面列出了他们的区别:
Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List 。
Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向 。
ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等 。
22.快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
一:快速失败(fail—fast)
在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的结构进行了修改(增加、删除),则会抛出Concurrent
Modification Exception 。
原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量 。集合在被遍历期间如果结构发生变化,就会改变modCount的值 。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历 。
注意:这里异常的抛出条件是检测到 modCount!=expectedmodCount
这个条件 。如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出 。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug 。
场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改) 。
二:安全失败(fail—safe)
采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历 。
原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发Concurrent
Modification Exception 。
缺点:基于拷贝内容的优点是避免了Concurrent Modification Exception,但同样地,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的 。


推荐阅读