Java核心面试题
原文地址:
http://javahungry.blogspot.com/2013/06/top-25-most-frequently-asked-core-java.html
https://www.toptal.com/java/interview-questions
https://blog.udemy.com/java-interview-questions/
Java的面试题非常多,有的是200多题,少的10道,20道。真没什么耐心完全翻译,结合几篇博文整理一下,也算是对接到Java面试的一种临时抱佛脚的方式吧。
1.当对象作为HashMap的Key时,这个对象类应实现哪两个方法?
必须实现equals和hashcode两个方法。
2.什么是不可变对象?举例
不可变对象是在java中一旦被创建就无法改变的对象,对不可变对象都将创建一个新的对象。例如:String和很多定义为final的对象。
3.创建一个String对象采用new()和直接赋值有什么不同?
当你采用new()创建一个string时,将会在heap中创建一个对象,而不会在string pool中创建。而直接赋值,则会在string pool中创建。
String s = new String(“test”); 将不会将s对象放入string pool,我们可以采用String.intern()来显示的将s对象放入string pool。而String s=”test”则会自动的将s对象放入string pool。
4.StringBuffer和StringBuilder有什么不同?
StringBuffer是线程安全的(线程同步),速度比StringBuilder慢。StringBuilder不是线程安全的,速度要快一些。
5.ArrayList和Vector有什么不同?
a.Vector是线程安全,而ArrayList不是。
b.vector比ArrayList慢。
c.Vector默认一次增长一倍,ArrayList默认一次增长50%。
d.Vector定义了增长大小的方法setSize(int i).ArrayList没有。
e.Vector和Hashtable是Java中同时实现Enumeration和Iterator的类,ArrayList只使用了iterator.
f.Vector从最早的java版本就有了,ArrayList从1.2之后才有
6.Iterator和Enumeration有什么不同?
A.iterator有三个方法hasNext(),next(),remove(),Enumeration有hasMoreElements()和nextElement()两个方法。
B.iterator允许调用者删除元素。
C.iterator的方法名更合理。
7.在写或者访问存储过程时,如何截获error异常?
在执行存储过程时,存储过程内部错误,则会返回错误代码。当调用存储过程本身出现错误,则或产生SQLException。
8.Executor.submit()和Executor.execute()有什么不同?
Submit()和execute()产生的异常是不一样的,如果采用execute()执行的任务抛出异常,将会产生一个未被捕获的异常。如果没有显示捕获,默认的会打印System.err的stack trace 。如果采用submit执行任务产生的异常,则任务会终止,产生一个异常,Future.get会抛出这个异常,封装成一个ExecutionException。
9.如果你没有override hashcode()方法,会产生什么问题?
没有重写hashcode()方法的对象如果作为hashMap的key,则当出现key相同时,不会覆盖原来key的值。
10.在try,catch块中调用return 或者System.exit,finally代码块还执行吗?
在try,catch块中调用return 时,finally块依然执行。
但是在try,catch块中调用System.exit 时,finally块不执行。
11.在java中能ovverride private和static的方法吗?
不能。
12.当往HashMap中赋值一个已经存在的key值时,会怎样?
当往HashMap中赋值一个已经存在的key值时,会替换原来相同的key的值,因为HashMap中值是唯一的。
13.如何保证有N个线程访问N个资源的情况下没有死锁?
如果你访问资源的顺序与释放资源的顺序相反,则可以避免死锁。
14.描述并比较fail-fast和fail-safe,并给出例子
Fail-fast在迭代循环时,不能对集合就行修改,包括增删改。如果进行这些操作,将抛出ConcurrentModificationException,例如:ArrayList,HashSet,HashMap等。
Fail-safe是操作的集合的克隆拷贝,所以在迭代时,操作集合不会产生异常,例如:ConcurrentHashMap,CopyOnWriteArrayList。
15.ArrayList,LinkedList和Vector都实现自List接口,哪一个在添加删除时最快,并解释。
LinkedList一般在添加删除时最快。ArrayList和Vector使用的是一个列表存储元素。当添加添加,删除时,会移动之后的元素。Vector是同步的,所以ArrayList比Vector快一些。LinkedList采用双链表实现,因此添加删除元素只需要处理之后的一个元素就行。
16.为什么将敏感数据(密码,保密数字)存在字符列表里比放在String串种安全?
在Java中,String是不可变的,会存在String pool中,一旦创建了,会一直保存到垃圾回收为止,即使你不用了,也存在一段不确定的回收期,任何人都可以通过访问String pool,获取值。而字符列表是可变的mutable,如果你不用了,可以直接赋空值,就不会保留在内存里了。
17.什么事ThreadLocal类?你为什么会用
一个ThreadLocal对象可以存储不同的线程。每个线程可以通过get()和set()访问各自的初始变量。ThreadLocal对象主要提供私有的静态类访问线程(如user ID, transaction ID).每个线程的ID在第一次调用ThreadID.get()时产生,并保持不变。
public class ThreadId {
// Next thread ID to be assigned
private static final AtomicInteger nextId = new AtomicInteger(0);
// Thread local variable containing each thread's ID
private static final ThreadLocal
new ThreadLocal
@Override protected Integer initialValue() {
return nextId.getAndIncrement();
}
};
// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
return threadId.get();
}
}
18.volatile是什么,为什么要用它?
在java中,每一个线程都有自己的栈,包括它能访问的变量拷贝等,当一个线程创建时,它会复制所有的可以访问的变量到自己的栈内,volatile就像对JVM说:注意,这个变量可能被别的线程访问。
由volatile定义的变量允许每一个线程读取变量的当前值。采用volatile比采用lock要快的多。例如,采用volatile定义一个结束线程的标识。
public class Foo extends Thread {
private volatile boolean close = false;
public void run() {
while(!close) {
// do work
}
}
public void close() {
close = true;
// interrupt here if needed
}
}
19.比较sleep()和wait(),包括什么时候用,为什么用。
Sleep()是阻止一定时间进行下面的操作。Wait()是暂停线程一段时间。
Sleep()一般用于类似于投票或检查某种结果,wait()一般用于多线程与notify()或者notifyAll()一起用,实现同步,避免资源竞争。
20.你怎样才能捕获另一个线程抛出的异常?
可以采用Thread.UncaughtExceptionHandler.例如:
// create our uncaught exception handler
Thread.UncaughtExceptionHandler handler = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread th, Throwable ex) {
System.out.println("Uncaught exception: " + ex);
}
};
// create another thread
Thread otherThread = new Thread() {
public void run() {
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException();
}
};
// set our uncaught exception handler as the one to be used when the new thread
// throws an uncaught exception
otherThread.setUncaughtExceptionHandler(handler);
// start the other thread - our uncaught exception handler will be invoked when
// the other thread throws an uncaught exception
otherThread.start()
21.什么是Java的Classloader?列出主要的三类classloader.
Classloader是JRE加载Java类的命令方式(延迟加载)到JVM中,主要加载local file system, remote file system,the web.