JAVA面试题集及解答
4、Array 和 ArrayList 有何区别
-
Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
-
补充:Array运用多态的特性,如果定义数组类型的时候定义为父类,而存进数组为该父类的子类的话可以存储不同类型的对象,但是一般不推荐,放进去,再取出来的时候,就不知道这个该当作哪个子类来用了,所以必须当作父类来用。你可以用强转的方法,不过不建议。ArrayList可以存储不同类型的数据,一般为了类型安全这样子创建List<类型> list = new ArrayList<>()
-
Array是指定大小后不可变的,而ArrayList大小是可变的(动态扩容)。
-
Array没有提供ArrayList那么多功能,比如addAll、removeAll和iterator等
5、Iterator 和 ListIterator 有什么区别
-
Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
-
Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
-
ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
7、守护线程
线程通常都有五种状态,创建、就绪、运行、阻塞和死亡。
-
创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。
-
就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
-
运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
-
阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。
-
死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪
10、notify()和 notifyAll()有什么区别?
-
如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。
-
当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争。
-
优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。
12、转发(forword)和重定向(redirect)的区别
转发:
- 转发地址栏路径不变
- 只能访问当前服务器上的资源
- 转发只是一次请求,可以使用request对象来共享数据
重定向:
- 地址栏发生变化
- 可以访问其他站点(服务器)的资源
- 重定向是两次请求,不能使用request对象共享资源
菜鸟试水,待续——

浙公网安备 33010602011771号