您的位置:首页 > 职场人生

Java面试题大全(Java基础十三)

2016-09-29 16:56 316 查看
71、heap和stack有什么区别。

stack内存指的是程序进入一个方法时,系统会专门为这个方法分配一块内存空间,这块内存空间也被称为该方法栈区,该方法的栈区专门用于存储该方法中定义的局部变量,包括基本类型的变量和引用变量。当这个方法结束时,该方法栈区将会自动被销毁,栈区中的所有局部变量都会随之销毁。

heap内存是Java虚拟机拥有的内存区,所有Java对象都将被放在heap内存内,位于heap内存中的Java对象由系统的垃圾回收器负责跟踪管理——也就是进行垃圾回收,当堆内存中的Java对象没有引用变量引用它时,这个Java对象就变成了垃圾,垃圾回收期就会在合适的时候回收它。

72、try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?

肯定会执行。finally{}块的代码只有在try{}块中包含遇到System.exit(0);之类的导致Java虚拟机直接退出的语句才会不执行。

当程序执行try{}遇到return时,程序会先执行return语句,但并不会立即返回——也就是把return语句要做的一切事情都准备好,也就是在将要返回、但并未返回的时候,程序把执行流程转去执行finally块,当finally块执行完成后就直接返回刚才return语句已经准备好的结果。

例如我们有如下程序:

public class Test
{
public static void main(String[] args)
{
System.out.println(new Test().test());;
}
static int test()
{
int x = 1;
try
{
return x;
}
finally
{
System.out.println("finally块执行:" + ++x);
}
}
}


此时的输出结果为:

finally块执行:2

1

看到上面程序中finally块已经执行了,而且程序执行finally块时已经把x变量增加到2了。但test()方法返回的依然是1,这就是由return语句执行流程决定的,Java会把return语句先执行完、把所有需要处理的东西都先处理完成,需要返回的值也都准备好之后,但是还未返回之前,程序流程会转去执行finally块,但此时finally块中的对x变量的修改已经不会影响return要返回的值了。

但如果finally块里也包含return语句,那就另当别论了, 因为finally块里的return语句也会导致方法返回,例如把程序该为如下形式:

public class Test
{
public static void main(String[] args)
{
System.out.println(new Test().test());;
}
static int test()
{
int x = 1;
try
{
return x++;
}
finally
{
System.out.println("finally块执行:" + ++x);
return x;
}
}
}


此时的输出结果为:

finally块执行:3

3

正如介绍的,程序在执行return x++;时,程序会把return语句执行完成,只是等待返回,此时x的值已经是2了,但程序此处准备的返回值依然是1。接下来程序流程转去执行finally块,此时程序会再次对x自加,于是x变成了3,而且由于finally块中也有return x;语句,因此程序将会直接由这条语句返回了,因此上面test()方法将会返回3。

73、下面的程序代码输出的结果是多少?

public class smallT
{
public static void main(String args[])
{
smallT t = new smallT();
int b = t.get();
System.out.println(b);
}
public int get()
{
try
{
return 1 ;
}
finally
{
return 2 ;
}
}
}


输出结果是:2。

这个程序还是刚才介绍的return语句和finally块的顺序问题。

Java会把return语句先执行完、把所有需要处理的东西都先处理完成,需要返回的值也都准备好之后,但是还未返回之前,程序流程会转去执行finally块。但如果在执行finally块时遇到了return语句,程序将会直接使用finally块中的return语句来返回——因此上面程序将会输出2。

74、final, finally, finalize的区别。

final是一个修饰符,它可以修改类、方法、变量。

final修饰类时表明这个类不可以被继承。

final修饰方法时表明这个方法不可以被其子类重写。

final修饰变量时可分为局部变量、实例变量和静态变量,当final修饰局部变量时,该局部变量可以被一次赋值,以后该变量的值不能发生该变量;当final修饰实例变量时,实例变量必须由程序在构造器、初始化块、定义时这3个位置的其中之一指定初始值;当final修饰静态变量时,静态变量必须由程序在静态初始化块、定义时这2个位置的其中之一指定初始值。

finally是异常处理语句结构的一部分,表示总会执行的代码块。

finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收。但实际上重写该方法进行资源回收并不安全,因为JVM并不保证该方法总被调用。

75、运行时异常与一般异常有何异同?

Checked异常体现了Java的设计哲学:没有完善错误处理的代码根本就不会被执行!

对于Checked异常的处理方式有两种:

A.当前方法明确知道如何处理该异常,程序应该使用try…catch块来捕获该异常,然后在对应的catch块中修补该异常。

B.当前方法不知道如何处理这种异常,应该在定义该方法时声明抛出该异常。

但Runtime异常则更加灵活,Runtime异常无须显式声明抛出,如果程序需要捕捉Runtime异常,也可以使用try…catch块来捕捉Runtime异常。

76、error和exception有什么区别?

Error错误,一般是指虚拟机相关的问题,如系统崩溃、虚拟机出错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不应该试图使用catch块来捕获Error对象。

Exception表示一种设计或实现问题。也就是说,程序员应该对这些情况进行考虑、并提供相应的处理。

77、Java中的异常处理机制的简单原理和应用。

程序运行过程中可能出现各种“非预期”情况,这些非预期情况可能导致程序非正常结束。

为了提高程序的健壮性,Java提供了异常处理机制:

try
{
s1...
s2...
s3...
}
catch(Exception ex)
{
//对异常情况的修复处理
}


对于上面处理流程,当程序执行try块里的s1、s2、s3遇到异常时,Java虚拟机将会把这个异常情况封装成异常对象,这个异常对象可以被后面对应的catch块捕捉到,这样保证这些异常会得到合适的处理。

Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Error错误,一般是指虚拟机相关的问题,如系统崩溃、虚拟机出错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不应该试图使用catch块来捕获Error对象。

Exception表示一种设计或实现问题。也就是说,程序员应该对这些情况进行考虑、并提供相应的处理。

异常有可分为Runtime异常和Checked异常,Checked异常体现了Java的设计哲学:没有完善错误处理的代码根本就不会被执行!对于Checked异常的处理方式有两种:

A.当前方法明确知道如何处理该异常,程序应该使用try…catch块来捕获该异常,然后在对应的catch块中修补该异常。

B.当前方法不知道如何处理这种异常,应该在定义该方法时声明抛出该异常。

实际上Java的Checked异常后来“争议不断”,因为Checked异常要求程序员要么显式声明抛出,要么进行捕捉,不能对Checked异常不闻不问,这样就给编程带来了一定的复杂度,比如Spring、Hibernate框架的一大特点就是把Checked异常包装成了Runtime异常。

Runtime异常则比较灵活,开发者既可以选择捕获Runtime异常,也可以不捕获。

78、请写出你最常见到的5个runtime exception。

对于一个有1~2年左右编程经验的人来说,总会经常遇到一些常见的异常,其中有些就是Runtime Exception。比如:

NullPointerException - 当调用一个未初始化的引用变量(实际值为null)的实例Field、实例方法时都会引发该异常。

ArithmeticException - 算术异常。比如5/0将引发该异常。

ArrayIndexOutOfBoundsException:数组索引越界异常。

ClassCastException:类型转换异常。

IllegalArgumentException:参数非法的异常。

79、JAVA语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别代表什么意义?在try块中可以抛出异常吗?

try块表示程序正常的业务执行代码。如果程序在执行try块的代码时出现了“非预期”情况,JVM将会生成一个异常对象,这个异常对象将会被后面相应的catch块捕获。

catch块表示一个异常捕获块。当程序执行try块引发异常时,这个异常对象将会被后面相应的catch块捕获。

throw用于手动地抛出异常对象。throw后面需要一个异常对象。

throws用于在方法签名中声明抛出一个或多个异常类,throws关键字后可以紧跟一个或多个异常类。

finally块代表异常处理流程中总会执行的代码块。

对于一个完整的异常处理流程而言,try块是必须的,try块后可以紧跟一个或多个catch块,最后还可以带一个finally块。

try块中可以抛出异常。

80、Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?

在Java5以前,有如下两种:

第一种:继承Thread类,重写它的run()方法。

代码如下:

new Thread()
{
public void run()
{
//线程执行体
}
}.start();


第二种:实现Runnable接口,并重写它的run()方法。

代码如下:

new Thread(new Runnable()
{
public void run()
{
//线程执行体
}
}).start();


从上面代码不难看出,线程的执行体是一个run()方法,然后程序通过start()方法启动一条线程。

从Java 5开始,Java提供了第三种方式来创建多线程:实现Callable接口,并实现call()方法。Callable接口相当于Runnable接口的增强版,因为Callable接口中定义的call()方法既拥有返回值,也可以声明抛出异常。

代码如下:

new Thread(new FutureTask<Object >(new Callable<Object>()
{
public Object call() throws Exception
{
//线程执行体
}
})).start();


不仅如此,Java 5还提供了线程支持,ExecutorService对象就代表了线程池,如果开发者利用ExecutorService来启动线程,ExecutorService底层会负责管理线程池。此时,开发者只要把Runnable对象传给ExecutorService即可。如下代码:

ExecutorService pool = Executors.newFixedThreadPool(3)
pool.execute(new Runnable()
{
public void run()
{
//线程执行体
}
});


如果执行通过Callable方式实现的线程,则可按如下代码:

ExecutorService pool = Executors.newFixedThreadPool(3)
pool.execute(new FutureTask<Object >(new Callable<Object>()
{
public Object call() throws Exception
{
//线程执行体
}
}));


用synchronized关键字修饰同步方法。需要指出的是,非静态的同步方法的同步监视器是this,也就是调用该方法对象,而静态的同步方法的同步监视器则是该类本身。因此使用synchronized修饰的静态方法、非静态方法的同步监视器并不相同,只有基于同一个同步监视器的同步方法、同步代码块才能实现同步。

反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被”挂起”的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 面试题