Java面试题之Java基础部分(5)

40final, finally, finalize的区别。

1final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……

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

3finalizeObject类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用

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

Java 提供了两类主要的异常 : runtime exception checked exception checked 异常也就是我们经常遇到的 IO 异常,以及 SQL 异常都是这种异常。 对于这种异常, JAVA 编译器强制要求我们必需对出现的这些异常进行 catch 所以,面对这种异常不管我们是否愿意,只能自己去写一大堆 catch 块去处理可能的异常。

但是另外一种异常: runtime exception ,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机 接管。比如:我们从来没有人去处理过 NullPointerException 异常,它就是运行时异常,并且这种异常还是最常见的异常之一。

出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由 Thread.run() 抛出 ,如果是单线程就被 main() 抛出 。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是 Exception 的子类,也有一般异常的特点,是可以被 Catch 块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。

如果不想终止,则必须扑捉所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。 在这个场景这样处理可能是一个比较好的应用,但并不代表在所有的场景你都应该如此。如果在其它场景,遇到了一些错误,如果退出程序比较好,这时你就可以不太理会运行时异常 ,或者是通过对异常的处理显式的控制程序退出。

异常处理的目标之一就是为了把程序从异常中恢复出来。

42errorexception有什么区别?

Throwable 是所有 Java 程序中错误处理的父类 ,有两种资类: Error Exception

Error :表示由 JVM 所侦测到的无法预期的错误,由于这是属于 JVM 层次的严重错误 ,导致 JVM 无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息。比如说内存溢出

Exception :表示一种设计或实现问题,是可恢复的例外,是可捕捉到的。

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

异常是指java程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间、地点、人物、情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。

Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.ThrowableThrowable下面又派生了两个子类:ErrorExceptionError表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的

问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。

java为系统异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常,而系统异常可以处理也可以不处理,所以,编译器不强制用try..catch处理或用throws声明,所以系统异常也称为unchecked异常。

44、请写出你最常见到的5runtime exception

数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);除数为0的异常(ArithmeticException)IllegalArgumentException(不合法的参数异常)

这道题主要考你的代码量到底多大,如果你长期写代码的,应该经常都看到过一些系统方面的异常,你不一定真要回答出5个具体的系统异常,但你要能够说出什么是系统异常,以及几个系统异常就可以了,当然,这些异常完全用其英文名称来写是最好的,如果实在写不出,那就用中文吧,有总比没有强!

所谓系统异常,就是…..,它们都是RuntimeException的子类,在jdk doc中查RuntimeException类,就可以看到其所有的子类列表,也就是看到了所有的系统异常。我比较有印象的系统异常有:NullPointerExceptionArrayIndexOutOfBoundsExceptionClassCastException

1Object x = new Integer(0);

System.out.println((String)x);

当试图将对象强制转换为不是实例的子类时,抛出该异常(ClassCastException)

2int a=5/0;

一个整数“除以零”时,抛出ArithmeticException异常。

3, String s=null;

int size=s.size();

当应用程序试图在需要对象的地方使用 null 时,抛出NullPointerException异常

4, "hello".indexOf(-1);

指示索引或者为负,或者超出字符串的大小,抛出StringIndexOutOfBoundsException异常

5String[] ss=new String[-1];

如果应用程序试图创建大小为负的数组,则抛出NegativeArraySizeException异常。

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

throws捕获并向外抛出异常

throw抛出异常

try catch是内部捕获异常并做自定义处理

finally是无论是否有异常都会被处理的语句,除非在finally前存在被执行的System.exit(int i)时除外

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

有两种实现方法,分别是继承Thread类与实现Runnable接口

synchronized关键字修饰同步方法

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

两种方式比较(面试)

1A extends Thread

  简单

  不能再继承其他类了(Java单继承),同份资源不共享

2A implements Runnable:(推荐)

  该类还可以继承其他类,也可以实现其他接口。

  多个线程共享一个目标资源,适合多线程处理同一份资源。

47sleep()wait()有什么区别?

1)这两个方法来自不同的类分别是ThreadObject

2)最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

3)使用范围:waitnotifynotifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。Wait方法要等待唤醒后,线程才会继续执行;sleep则是休眠一段时间后,线程自动恢复。

4sleep必须捕获异常,而waitnotifynotifyAll不需要捕获异常

(网上的答案:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 waitObject类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

48、同步和异步有何异同,在什么情况下分别使用他们?举例说明。

同步:上一段代码没的完成,下一段必须等到上一段代码完成后才可以执行。如买票排队。异步:上一段代码没的完成,下一段不必等到上一段代码完成就可以执行。如手机发送短信

同步可以避免出现死锁,一般共享某一资源的时候用,如果每个人都有修改权限,同时修改一个文件,有可能使一个人读取另一个人已经删除的内容,就会出错,同步就会按顺序来修改。

异步则是可以提高效率了,现在cpu都是双核,四核,异步处理的话可以同时做多项工作,当然必须保证是可以并发处理的。

同步和异步最大的区别就在于。一个需要等待,一个不需要等待。比如广播,就是一个异步例子。发起者不关心接收者的状态。不需要等待接收者的返回信息电话,就是一个同步例子。发起者需要等待接收者,接通电话后,通信才开始。需要等待接收者的返回信息。

49. 下面两个方法同步吗?

class Test{

synchronized static void sayHello3(){}

synchronized void getX(){}

}

sayHello3是一个静态函数,所以可以直接由类名调用,所以这里用到的锁是Test的字节码文件,即Test.class;而get函数不是静态函数,需要由这个类的实例进行调用,所以用到的锁是this,所以这两个方法不是同步的(当然对于单独的函数,那是同步的。)

50、多线程有几种实现方法?同步有几种实现方法?

多线程有两种实现方法,分别是继承Thread类与实现Runnable接口

线程同步

1. 用 synchronized 修饰需要同步的方法

2. 用 synchronized 块包围需要同步的语句

3. 使用 java.util.concurrent 包中的各种同步锁

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/417b4bdbdf5aba80bc7782bea7f3f981.html