java面试题
1.是否可以从一个static方法内部发出对非static方法的调用?
答:不行
class Son extends Father{
public Son() {
System.out.println("Son's constructor");
}
static {
System.out.println("Son's static");
}
{
System.out.println("Son's non static");
}
public static void funStatic(){
this.fun();//报错cannot be referenced from a static context
}
public void fun(){
System.out.println("static");
}
2.Math.round(11.5)等於多少?Math.round(-11.5)等於多少?
12
-11
3.接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concreteclass)?抽象类中是否可以有静态的main方法?
接口可继承接口
interface Father{
void Ifun();
}
interface Son extends Father{
void ISfun();
}
抽象类可实现接口
abstract class Abc implements Father{
@Override
public void Ifun() {
System.out.println("abc");
}
}
抽象类可继承具体类
(前提是被继承的具体类有构造方法不能私有)
abstract class Abc extends Father{
@Override
public void Ifun() {
System.out.println("abc");
}
}
抽象类中可以有静态的main方法
abstract class Abc extends Father{
public static void main(String[] args){
System.out.println("abc");
}
}
4.String s = new String(“xyz”);创建了几个StringObject?是否可以继承String类?
创建了两个对象,第一个是常量池中的xyz,如果常量池中已经存在xyz则不再创建,第二个对象是堆中创建一个String对象指向常量池中的xyz。所以是两个String Object;String不可被继承它是final修饰的。
5.下面这条语句一共创建了多少个对象:String s=“a”+“b”+“c”+“d”;
对于如下代码:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期再去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。
题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个”abcd”的字符串,所以,上面的代码应该只创建了一个String对象。写如下两行代码,
6.try {}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?
public class main {
public int test(){
int x = 0;
try {
System.out.println("开始执行try");
return x;
}finally {
System.out.println("开始执行finally");
x++;
System.out.println("finally执行结束");
}
}
public static void main(String[] args){
System.out.println(new main().test());
}
}
执行结果:
开始执行try
开始执行finally
finally执行结束
0
x返回0;
在try中的x已准备好返回,但是此时又转到finally中进行x++的操作,这时会把x的值保存在不同于x的局部变量中去,当执行完finally后再将值放回来,进行返回。
7.final, finally, finalize的区别。
final 用于声明属性,方法和类, 分别表示属性不可变, 方法不可覆盖, 类不可继承. finally 是异常处理语句结构的一部分,表示总是执行. finalize 是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等.
8.运行时异常与一般异常有何异同?
运行时异常:由java虚拟机抛出的异常。用户不必处理。
一般异常是用户可以抛出的异常,如果抛出调用必须进行处理。
运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
9.error和exception有什么区别?
Error类和Exception类的父类都是throwable类,他们的区别是:
Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。
Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。
Exception类又分为运行时异常(Runtime Exception)和受检查的异常(Checked Exception ),运行时异常;ArithmaticException,IllegalArgumentException,编译能通过,但是一运行就终止了,程序不会处理运行时异常,出现这类异常,程序会终止。而受检查的异常,要么用try。。。catch捕获,要么用throws字句声明抛出,交给它的父类处理,否则编译不会通过。
10、能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?
我们可以做强制转换,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,如果强制转化,int 类型的高 24 位将会被丢弃,因为byte 类型的范围是从 -128 到 127。
11.a.hashCode() 有什么用?与 a.equals(b) 有什么关系?
hashCode()返回对象的哈希值;
如果a.equals(b),则ab的hashCode一定相等
如果ab的hashCode相等,a不一定equals(b)
12.字节流与字符流的区别
字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。
字节流默认不使用缓冲区;字符流使用缓冲区。
字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。
13.什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。
无论何种类型的数据,都是以二进制的形式在网络上传送,为了由一个进程把Java对象发送给另一个进程,需要把其转换为字节序列才能在网络上传送,把JAVA对象转换为字节序列的过程就称为对象的序列化,将字节序列恢复成Java对象的过程称为对象的反序列化,(然后java.io.ObjectOutPutStream的writeObject(Object obj)的方法就可以 将参数指定的对象进行序列化 并且把得到的字节流写到一个目标输出流上去)
序列化的实现:将需要被序列化的类实现Serializable接口,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
14.java中会存在内存泄漏吗,请简单描述。
1.长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景,通俗地说,就是程序员可能创建了一个对象,以后一直不再使用这个对象,这个对象却一直被引用,即这个对象无用但是却无法被垃圾回收器回收的,这就是java中可能出现内存泄露的情况,例如,缓存系统,我们加载了一个对象放在缓存中(例如放在一个全局map对象中),然后一直不再使用它,这个对象一直被缓存引用,但却不再被使用。
检查java中的内存泄露,一定要让程序将各种分支情况都完整执行到程序结束,然后看某个对象是否被使用过,如果没有,则才能判定这个对象属于内存泄露。
2.如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持久外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会造成内存泄露。
3.当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露。
15.描述一下JVM加载class文件的原理机制?
16.垃圾回收的优点和原理。并考虑2种回收机制。
17、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
18.在java语言中,判断一块内存空间是否符合垃圾收集器收集标准的标准只有两个:
1.给对象赋值为null,以下没有调用过。
2.给对象赋了新的值,重新分配了内存空间。