zoukankan      html  css  js  c++  java
  • 异常处理面试题详解

    1. 下列哪种异常是检查型异常,需要在编写程序时声明()
      A. NullPointerException
      B. ClassCastException
      C. FileNotFoundException
      D. IndexOutOfBoundsException
      答案:C
      分析:NullPointerException 空指针异常
      ClassCastException 类型转换异常
      IndexOutOfBoundsException 索引超出边界的异常
      以上这些异常都是程序在运行时发生的异常,所以不需要在编写程序时声
    2. Java 出现 OutOf MemoryError(OOM 错误)的原因有哪
      些?出现 OOM 错误后,怎么解决?
      答:
      OutOf MemoryError 这种错误可以细分为多种不同的错误,每种错误都有
      自身的原因和解决办法,如下所示:
      java.lang.OutOfMemoryError: Java heap space
      错误原因:此 OOM 是由于 JVM 中 heap 的最大值不满足需要。
      解决方法:1) 调高 heap 的最大值,即-Xmx 的值调大。2) 如果你的程序
      存在内存泄漏,一味的增加 heap 空间也只是推迟该错误出现的时间而已,
      所以要检查程序是否存在内存泄漏。
      java.lang.OutOfMemoryError: GC overhead limit exceeded
      错误原因:此 OOM 是由于 JVM 在 GC 时,对象过多,导致内存溢出,建
      议调整 GC 的策略,在一定比例下开始 GC 而不要使用默认的策略,或者将
      新代和老代设置合适的大小,需要进行微调存活率。
      解决方法:改变 GC 策略,在老代 80%时就是开始 GC,并且将
      -XX:SurvivorRatio(-XX:SurvivorRatio=8)和-XX:NewRatio
      (-XX:NewRatio=4)设置的更合理。
      java.lang.OutOfMemoryError: Java perm space
      错误原因:此 OOM 是由于 JVM 中 perm 的最大值不满足需要。
      解决方法:调高 heap 的最大值,即-XX:MaxPermSize 的值调大。
      另外,注意一点,Perm 一般是在 JVM 启动时加载类进来,如果是 JVM 运
      行较长一段时间而不是刚启动后溢出的话,很有可能是由于运行时有类被动
      态加载进来,此时建议用 CMS 策略中的类卸载配置。如:
      -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled。 java.lang.OutOfMemoryError: unable to create new native thread
      错误原因:当 JVM 向 OS 请求创建一个新线程时,而 OS 却由于内存不足无
      法创建新的 native 线程。
      解决方法:如果 JVM 内存调的过大或者可利用率小于 20%,可以建议将
      heap及perm的最大值下调,并将线程栈调小,即-Xss调小,如:-Xss128k。
      java.lang.OutOfMemoryError: Requested array size exceeds VM limit
      错误原因:此类信息表明应用程序(或者被应用程序调用的 APIs)试图分配
      一个大于堆大小的数组。例如,如果应用程序 new 一个数组对象,大小为
      512M,但是最大堆大小为 256M,因此 OutOfMemoryError 会抛出,因
      为数组的大小超过虚拟机的限制。
      解决方法:1) 首先检查 heap 的-Xmx 是不是设置的过小。2) 如果 heap
      的-Xmx 已经足够大,那么请检查应用程序是不是存在 bug,例如:应用程
      序可能在计算数组的大小时,存在算法错误,导致数组的 size 很大,从而导
      致巨大的数组被分配。
      java.lang.OutOfMemoryError: request bytes for .
      Out of swap space
      错误原因:抛出这类错误,是由于从 native 堆中分配内存失败,并且堆内
      存可能接近耗尽。这类错误可能跟应用程序没有关系,例如下面两种原因也
      会导致错误的发生:1) 操作系统配置了较小的交换区。2)系统的另外一个
      进程正在消耗所有的内存。
      解决办法:1) 检查 os 的 swap 是不是没有设置或者设置的过小。2) 检查
      是否有其他进程在消耗大量的内存,从而导致当前的 JVM 内存不够分配。
      注意:虽然有时部分显示导致 OOM 的原因,但大多数情况下,
      显示的是提示分配失败的源模块的名称,所以有必要查看日志文
      件,如 crash 时的 hs 文件。
    3. 列举常见的运行时异常
      答:
      ClassCastException(类转换异常)
      比如 Object obj=new Object(); String s=(String)obj;
      IndexOutOfBoundsException(下标越界异常)
      NullPointerException(空指针异常)
      ArrayStoreException(数据存储异常,操作数组时类型不一致)
      BufferOverflowException(IO 操作时出现的缓冲区上溢异常)
      InputMismatchException(输入类型不匹配异常)
      ArithmeticException(算术异常)
      注意:运行时异常都是 RuntimeException 子类异常。
    4. 下面关于 Java.lang.Exception 类的说法正确的是()
      A. 继承自 Throwable
      B. 不支持 Serializable
      C. 继承自 AbstractSet
      D. 继承自 FitelnputStream
      答案:A
      分析:
      Throwable 是 Exception 和 Error 的父类,Exception 虽然没有实现
      Serializable 接口,但是其父类 Throwable 已经实现了该接口,因此
      Exception 也支持 Serializable。
    5. Unsupported major.minor version 52 是什么异常,怎么
      造成的,如何解决?
      答:问题的根本原因是工程中某个 jar 包的版本(jar 包编译时的所用的 jdk
      版本)高于工程 build path 中 jdk 的版本,这个是不兼容的! 编程中遇到此
      异常 Unsupported major.minor version 52.0(根据版本号,这里可以为
      其他数值,52 是 1.8jdk jar 包与 1.8 以下低版本 jdk 不匹配),在将 build
      path 中 jdk 的版本调整与 jar 包匹配后,解决异常。
    6. try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally{}
      里的 code 会不会被执行,什么时候被执行,在 return 前还是后?
      答:会执行,在方法返回调用者前执行。Java 允许在 finally 中改变返回值
      的做法是不好的,因为如果存在 finally 代码块,try 中的 return 语句不会立
      马返回调用者,而是记录下返回值待 finally 代码块执行完毕之后再向调用
      者返回其值,然后如果在 finally 中修改了返回值,这会对程序造成很大的
      困扰,C#中就从语法上规定不能做这样的事。
      (也许你的答案是在 return 之前,但往更细地说,我的答案是在 return 中间
      执行,请看下面程序代码的运行结果:
      public classTest {
      /**
    • @paramargs add by zxx ,Dec 9, 2008
      */
      public static voidmain(String[] args) {
      // TODO Auto-generated method stub
      System.out.println(newTest().test());;
      }
      static int test()
      {
      int x = 1;
      try
      {
      returnx;
      }
      finally
      {
      ++x;
      }
      }

    }
    ---------执行结果 ---------
    1
    运行结果是 1,为什么呢?主函数调用子函数并得到结果的过程,好比主函
    数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再
    将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函
    数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。
    285. Java 语言如何进行异常处理,关键字:throws、throw、try、
    catch、finally 分别如何使用?
    答:Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,
    并提供了良好的接口。在 Java 中,每个异常都是一个对象,它是 Throwable
    类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中
    包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。
    Java 的异常处理是通过 5 个关键词来实现的:try、catch、throw、throws
    和 finally。一般情况下是用 try 来执行一段程序,如果出现异常,系统会抛
    出(throw)一个异常,这时候你可以通过它的类型来捕捉(catch)它,
    或最后(finally)由缺省处理器来处理;try 用来指定一块预防所有“异常”
    的程序;catch 子句紧跟在 try 块后面,用来指定你想要捕捉的“异常”的
    类型;throw 语句用来明确地抛出一个“异常”;throws 用来标明一个成
    员函数可能抛出的各种“异常”;finally 为确保一段代码不管发生什么
    “异常”都被执行一段代码;可以在一个成员函数调用的外面写一个 try 语
    句,在这个成员函数内部写另一个 try 语句保护其他代码。每当遇到一个 try
    语句,“异常”的框架就放到栈上面,直到所有的 try 语句都完成。如果下
    一级的 try 语句没有对某种“异常”进行处理,栈就会展开,直到遇到有处
    理这种“异常”的 try 语句。
    286. 运行时异常与受检异常有何异同?
    答:异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟
    机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没
    有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序
    设计无误,仍然可能因使用的问题而引发。Java 编译器要求方法必须声明抛
    出可能发生的受检异常,但是并不要求必须声明抛出未被捕获的运行时异常。
    异常和继承一样,是面向对象程序设计中经常被滥用的东西,神作《Effective
    Java》中对异常的使用给出了以下指导原则:
    • 不要将异常处理用于正常的控制流(设计良好的 API 不应该强迫它的调
    用者为了正常的控制流而使用异常)
    • 对可以恢复的情况使用受检异常,对编程错误使用运行时异常
    • 避免不必要的使用受检异常(可以通过一些状态检测手段来避免异常发生)
    • 优先使用标准的异常
    • 每个方法抛出的异常都要有文档
    • 保持异常的原子性
    • 不要在 catch 中忽略掉捕获到的异常
    (异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的
    通常操作中可能遇到的异常,是一种常见运行错误。java 编译器要求方法必
    须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获
    的运行时异常。)
    287. 类 ExampleA 继承 Exception,类 ExampleB 继承
    ExampleA
    有如下代码片断:
    try{
    throw new ExampleB("b")
    }catch(ExampleA e){
    System.out.println("ExampleA");
    }catch(Exception e){
    System.out.println("Exception");
    }
    }
    请问执行此段代码的输出是什么?
    答:输出:ExampleA。(根据里氏代换原则[能使用父类型的地方一定能使
    用子类型],抓取 ExampleA 类型异常的 catch 块能够抓住 try 块中抛出的
    ExampleB 类型的异常)
    补充: 比此题略复杂的一道面试题如下所示(此题的出处是《Java 编程思
    想》),说出你的答案吧!
    package com.bjsxt;
    class Annoyance extends Exception {}
    class Sneeze extends Annoyance {}
    class Human {
    public static void main(String[] args)
    throws Exception {
    try {
    try {
    throw new Sneeze();
    }
    catch ( Annoyance a ) {
    System.out.println("Caught Annoyance");
    throw a;
    }
    }
    catch ( Sneeze s ) {
    System.out.println("Caught Sneeze");
    return ;
    }
    finally {
    System.out.println("Hello World!");
    }
    }
    }
    输出为:
    Caught Annoyance
    Caught Sneeze
    Hello World!
    288. Error 和 Exception 的区别
    Error 类,表示仅靠程序本身无法恢复的严重错误,比如说内存溢出、动
    态链接异常、虚拟机错误。应用程序不应该抛出这种类型的对象。假如出现
    这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以在
    进行程序设计时,应该更关注 Exception 类。
    Exception 类,由 Java 应用程序抛出和处理的非严重错误,比如所需文
    件没有找到、零作除数,数组下标越界等。它的各种不同子类分别对应不同
    类型异常。可分为两类:Checked 异常和 Runtime 异常
    289. Java 异常处理 try-catch-finally 的执行过程
    try-catch-finally 程序块的执行流程以及执行结果比较复杂。
    基本执行过程如下:
    1)程序首先执行可能发生异常的 try 语句块。
    2)如果 try 语句没有出现异常则执行完后跳至 finally 语句块执行;
    3)如果 try 语句出现异常,则中断执行并根据发生的异常类型跳至相应的
    catch 语句块执行处理。
    4)catch 语句块可以有多个,分别捕获不同类型的异常。
    5)catch 语句块执行完后程序会继续执行 finally 语句块。
    finally 语句是可选的,如果有的话,则不管是否发生异常,finally 语句都会
    被执行。需要注意的是即使 try 和 catch 块中存在 return 语句,finally 语
    句也会执行,是在执行完 finally 语句后再通过 return 退出。
    290. 异常处理中 throws 和 throw 的区别
    1)作用不同:
    throw 用于程序员自行产生并抛出异常;
    throws 用于声明在该方法内抛出了异常
    2) 使用的位置不同:
    throw 位于方法体内部,可以作为单独语句使用;
    throws 必须跟在方法参数列表的后面,不能单独使用。
    3)内容不同:
    throw 抛出一个异常对象,且只能是一个;
    throws 后面跟异常类,而且可以有多个

  • 相关阅读:
    java中几个常见的Arrays下的类
    java二分查找法的实现过程
    java冒泡排序的实现过程
    java数组中选择排序的实现
    正则表达式
    StringBuilder的使用与总结
    String的几个常用API
    关于API,注释文档以及String
    关于sqlserve2000和sqlserver2005以后版本配置连接池的一些思路
    专题-X教育
  • 原文地址:https://www.cnblogs.com/linanana/p/12545990.html
Copyright © 2011-2022 走看看