Java狡猾面试题 Top10
——翻译自博文 Top 10 Tricky Java interview questions and Answers
-
- Java狡猾面试题 Top10
- 下面 Java 程序的输出是
- 如果在 try 或者 catch 块内有 return 或者 Systemexit会发生什么finally是否会执行
- 可否重写override private 或 static 方法
- 表达式10 00会有什么结果异常编译错误
- Java是否支持多继承
- 下面 Java 程序的输出是什么
- 如果父类里的某个方法抛出 NullPointerException那么在子类里可否用抛出 RuntimeException 的方法覆盖它
- 下面 campateTo 的实现有没有问题这里的id是Integer类型
- 如何保证N个线程访问N个资源时不发生死锁
- 考虑下面的代码两个变量都不是 volatile两个线程都没有用 synchronized有没有可能 Thread 2 输出 x 0
1. 下面 Java 程序的输出是?
public class Test {
public static void main(String[] args) {
System.out.println(Math.min(Double.MIN_VALUE, 0.0d));
}
}
这道题之所以狡猾,是因为Double类不像Integer,MIN_VALUE是负数。Double的MIN_VALUE是最小的正数。所以这道题的答案是:输出0.0。
2. 如果在 try 或者 catch 块内有 return 或者 System.exit(),会发生什么?finally是否会执行?
这道题是一个很出名的Java狡猾面试题。答案是:无论return在try里面还是catch里面,finally都会执行;而System.exit()无论在try里面还是catch里面,finally都不会执行。
3. 可否重写(override) private 或 static 方法?
private方法是不能重写的,因为根本就不可见。static方法表面上看它是可以重写的,但实际上是父类的相同方法被隐藏了,而不是被重写了。
4. 表达式:1.0 / 0.0,会有什么结果?异常?编译错误?
结果是 Double.INFINITY 。
5. Java是否支持多继承?
接口可以,类不可以。
6. 下面 Java 程序的输出是什么?
public class Test {
public static void main(String[] args) throws Exception {
char[] chars = new char[] {'\u0097'};
String str = new String(chars);
byte[] bytes = str.getBytes();
System.out.println(Arrays.toString(bytes));
}
}
这道题考察对String是否有较深的了解。这道题的答案是;不确定。因为具体是什么样的数组,取决与当前系统的字符集和Locale。在没有指定的情况下,getBytes()方法会根据当前系统和Locale选一个字符集做encode,而不同的字符集encode结果是不一样的,可能是一个元素的byte数组,也可能是两个元素的byte数组。
7. 如果父类里的某个方法抛出 NullPointerException,那么在子类里可否用抛出 RuntimeException 的方法覆盖它?
如果父类方法和子类方法抛出的异常都是未受检查异常(即 RuntimeException),那么允许父类抛出子类所抛异常的子类,即题目里说的情况是允许的。如果是受检查异常,那么不允许。
8. 下面 campateTo() 的实现有没有问题?(这里的id是Integer类型)
public int compareTo(Object o){
Employee emp = (Employee) o;
return this.id - emp.id;
}
当this.id非常小时,this.id - emp.id 的结果可能会溢出,一旦溢出,结果就会难以预料。正确的写法是:当 this.id > emp.id 时,返回 1,当 this.id < emp.id 时,返回-1,当相同时,返回0 。
9. 如何保证N个线程访问N个资源时不发生死锁。
这个问题甚至对于有经验的或者是高级程序员都会不好回答。关键在于获取锁和释放锁的顺序。如果获取锁用一个特定的顺序,然后释放的时候用其相反的顺序,就可以保证不会发生死锁。可以参考 how to avoid deadlock in java (需要翻墙,或者请自行搜索类似内容)
10. 考虑下面的代码,两个变量都不是 volatile,两个线程都没有用 synchronized。有没有可能 Thread 2 输出 “x = 0”。
int x = 0;
boolean bExit = false;
Thread 1 (not synchronized)
x = 1;
bExit = true;
Thread 2 (not synchronized)
if (bExit == true)
System.out.println("x=" + x);
答案是:有可能。因为这段代码既没有 volatile,也没有 synchronized,所以编译器编译了以后有可能 bExit = true; 会比 x = 1; 先执行。如果要保证,那么可以将 bExit 声明为 volatile,bExit成为 volatile 以后,编译器就不会将语句重新排序。