JAVA
程序员面试
32
问
第一,谈谈 final, finally, finalize 的区别。
final 修饰符(关键字)如果一个类被声明为 final ,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract 的,又被声明为 final 的。将变量或方法声明为 final ,可以保证它们在使用中不被改变。被声明为 final 的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为 final 的方法也同样只能使用,不能重载
finally 再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。
finalize? 方法名。 Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。 finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
第二, Anonymous Inner Class ( 匿名内部类 ) 是否可以 extends( 继承 ) 其它类,是否可以 implements( 实现 )interface( 接口 )?
匿名的内部类是没有名字的内部类。不能 extends( 继承 ) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现。
第三, Static Nested Class 和 Inner Class 的不同,说得越多越好 ( 面试题有的很笼统 ) 。
Nested Class (一般是 C++ 的说法), Inner Class ( 一般是 JAVA 的说法 ) 。 Java 内部类与 C++ 嵌套类最大的不同就在于是否有指向外部的引用上。具体可见 http: //www.frontfree.net/articles/services/view.asp?id=704&page=1
注: 静态内部类( Inner Class )意味着 1 创建一个 static 内部类的对象,不需要一个外部类对象, 2 不能从一个 static 内部类的一个对象访问一个外部类对象
第四, & 和 && 的区别。
& 是位运算符。 && 是布尔逻辑运算符。
第五, HashMap 和 Hashtable 的区别。
都属于 Map 接口的类,实现了将惟一键映射到特定的值上。
HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。
Hashtable 类似于 HashMap ,但是不允许 null 键和 null 值。它也比 HashMap 慢,因为它是同步的。
第六, Collection 和 Collections 的区别。
Collections 是个 java.util 下的类,它包含有各种有关集合操作的静态方法。
Collection 是个 java.util 下的接口,它是各种集合结构的父接口。
第七,什么时候用 assert 。
断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为 true 。如果表达式计算为 false ,那么系统会报告一个 AssertionError 。它用于调试目的:
assert(a > 0); // throws an AssertionError if a <= 0
断言可以有两种形式:
assert Expression1 ;
assert Expression1 : Expression2 ;
Expression1 应该总是产生一个布尔值。
Expression2 可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的 String 消息。
断言在默认情况下是禁用的。要在编译时启用断言,需要使用 source 1.4 标记:
javac -source 1.4 Test.java
要在运行时启用断言,可使用 -enableassertions 或者 -ea 标记。
要在运行时选择禁用断言,可使用 -da 或者 -disableassertions 标记。
要系统类中启用断言,可使用 -esa 或者 -dsa 标记。还可以在包的基础上启用或者禁用断言。
可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过,断言不应该用于验证传递给 公有方法的参数,因为不管是否启用了断言,公有方法都必须检查其参数。不过,既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言 不应该以任何方式改变程序的状态。
第八, GC 是什么 ? 为什么要有 GC? ( 基础 ) 。
GC 是垃圾收集器。 Java 程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()
第九, String s = new String("xyz"); 创建了几个 String Object?
两个对象,一个是 “xyx”, 一个是指向 “xyx” 的引用对象 s 。
第十, Math.round(11.5) 等於多少 ? Math.round(-11.5) 等於多少 ?
Math.round(11.5) 返回( long ) 12 , Math.round(-11.5) 返回( long ) -11;
第二十一, abstract 的 method 是否可同时是 static, 是否可同时是 native ,是否可同时是 synchronized?
都不能
第二十二,接口是否可继承接口 ? 抽象类是否可实现 (implements) 接口 ? 抽象类是否可继承实体类 (concrete class)?
接口可以继承接口。抽象类可以实现 (implements) 接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。
第二十三,启动一个线程是用 run() 还是 start()?
启动一个线程是调用 start() 方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由 JVM 调度并执行。这并不意味着线程就会立即运行。 run() 方法可以产生必须退出的标志来停止一个线程。
第二十四,构造器 Constructor 是否可被 override?
构造器 Constructor 不能被继承,因此不能重写 Overriding ,但可以被重载 Overloading 。
第二十五,是否可以继承 String 类 ?
String 类是 final 类故不可以继承。
第二十六,当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对象的其它方法 ?
不能,一个对象的一个 synchronized 方法只能由一个线程访问。
第二十七, try {} 里有一个 return 语句,那么紧跟在这个 try 后的 finally {} 里的 code 会不会被执行,什么时候被执行,在 return 前还是后 ?
会执行,在 return 前执行。
第二十八,编程题 : 用最有效率的方法算出 2 乘以 8 等於几 ?
有 C 背景的程序员特别喜欢问这种问题。
2 << 3
第二十九,两个对象值相同 (x.equals(y) == true) ,但却可有不同的 hash code ,这句话对不对 ?
不对,有相同的 hash code 。
第三十,当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递 ?
是值传递。 Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。
第三十一, swtich 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上 ?
switch ( expr1 )中, expr1 是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int 、 short 、 char 或者 byte 。 long,string 都不能作用于 swtich 。
第三十二,编程题 : 写一个 Singleton 出来。
Singleton 模式主要作用是保证在 Java 应用程序中,一个类 Class 只有一个实例存在。
一般 Singleton 模式通常有几种种形式 :
第一种形式 : 定义一个类,它的构造函数为 private 的,它有一个 static 的 private 的该类变量,在类初始化时实例话,通过一个 public 的 getInstance 方法获取对它的引用 , 继而调用其中的方法。
public class Singleton {
private Singleton(){}
// 在自己内部定义自己一个实例,是不是很奇怪?
// 注意这是 private 只供内部调用
private static Singleton instance = new Singleton();
// 这里提供了一个供外部访问本 class 的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}
第二种形式 :
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
// 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
// 使用时生成实例,提高了效率!
if (instance==null)
instance = new Singleton();
return instance; }
}