【秋招冲刺-每日打卡】应届生JAVA岗-每日5道高频面试题【Day5】- 异常类篇(1)

简介: 【秋招冲刺-每日打卡】应届生JAVA岗-每日5道高频面试题【Day5】- 异常类篇(1)

文章大纲

一: Error和Exception有什么区别?

(一): 为什么JAVA存在这种异常机制

(二): 程序错误的分类

(三): 异常家族的结构

(四): 常见的异常有哪些

二: Java语言如何处理异常,关键字:try、catch、finally、throws、throw分别有什么作用?

三: 在程序中遇到异常在所难免,你有什么好的处理异常经验?

四: final、finally、finalize的区别?

追问1、try-catch-finally需要同时都存在?那个可以省略?

五: NoClassDefFoundError和 ClassNotFoundException区别是什么?

追问1、try-finally结构中,如果在try和finally中分别有return,则具体的返回情况会是什么?

追问2、try-catch-finally结构中,如果在catch中return了,finally中的代码是否还会被执行?

每日小结

image.png

大家好,这里是IT学习日记,一个非双一流大学毕业的深漂族,年少曾憧憬大厂,面试过许多家公司,也曾踩过无数坑,深知面试技巧和知识广度与深度对一个应届生乃至工作多年的开发者的重要性。

故特意收集了各个公司、大厂的面试高频题,通过每天打卡的方式,和大家一起记录和学习,希望能够帮助到应届生和开发者们少走弯路,一起冲向大厂!!!

image.png

一: Error和Exception有什么区别?


(一): 为什么JAVA存在这种异常机制


 异常机制是指当程序出现错误时,该如何处理,它给程序提供了一个安全的退出通道,就跟我们大楼的安全通道类似,当出现火灾或者不可控的情况时,人们可以通过安全通道逃生。



(二): 程序错误的分类


 主要分为三种既编译时错误、运行时错误、逻辑错误。


 1、编译时错误: 它指的是程序的编写不符合对应程序的语言语法,编译器会提示异常信息,且这些异常必须处理,否则程序无法被运行。


 2、运行时错误: 它指的是程序运行时,运行环境发现程序不合理而抛出的错误,它主要是开发考虑不够细致导致,这种错误只能依靠异常机制来进行处理,而且能否预防程序在运行时出现错误也是一个开发者是否考虑周全,经验是否丰富的考察标准。


 3、逻辑错误: 它指的是程序的运行流程和结果跟开发者预测的不一样,出现这种问题可能是开发没有考虑周全导致。



(三): 异常家族的结构

image.png

1、Throwable: 可抛出的,它是JAVA中所有异常的一个父类,用来定义所有可以作为异常被抛出来的类,Exception(异常)和Error(错误)是它的子类,Exception(异常)和Error(错误)的最大区别是异常可以通过异常处理机制在程序中处理,而错误则是没法通过程序处理。


 Throwable常用方法:

image.png

2、Exception(异常): Throwable的子类之一,表示程序可以处理的异常,它又分为两类即编译时异常(CheckedException)和运行时异常(RuntimeException),这类异常应该尽可能在程序去处理它们。


编译时异常: Exception中除了RuntimeException以外的异常,这种异常是必须处理的,否则编译程序不过,程序无法被执行,常见的如:IOException、SQLException等等。

运行时异常: 这类异常编译器是无法检测的,一般是有程序的逻辑错误引起的,在程序中可以通过异常捕获机制来进行处理,处理这类异常主要看开发者是否考虑全面,开发经验是否丰富可以提前预测代码可能出现异常,常见的有:空指针异常,数组下标越界等。

image.png

3、Error(错误): Throwable的子类之一,表示无法通过程序处理的的错误,通常出现的原因和开发者无关,一般是由虚拟机JVM引起的,常见的如:VirtulMachineError、AWTError等等。

image.png

(四): 常见的异常有哪些


 一: 常见的编译时异常


 1、IOException: IO操作输入流或者输出流可能出现的异常


 2、FileNotFoundException: 文件未找到异常


 3、EOFException: 文件已结束异常


 二: 常见的运行时时异常


 1、NullPointerException: 空指针异常,当对象为null对,调用对象的某个方法时会抛出


 2、ArrayIndexOutOfBoundsException: 数组下标越界异常,当访问的数组下标是负数或者大于数组的大小时会抛出该异常


 3、ArithmeticException: 算术条件异常,如分母为0时的除法运算


 4、SecurityException: 安全性异常


 5、IllegalArgumentException: 非法参数异常



二: Java语言如何处理异常,关键字:try、catch、finally、throws、throw分别有什么作用?


 JAVA中是通过面向对象的方式来处理异常,将不同的异常分为不同的类,在JAVA中,每一个异常都是一个对象,它们都属性Throwable的子类或者其子类的实例,如果某个地方出现了异常,则在该处抛出一个异常对象,这个异常对象中包含了异常信息,开发者可以通过异常处理机制对异常进行处理。


 ,在JAVA中异常处理机制主要是通过try、catch、finally、throws、throw这五个关键字来进行处理的。


 如果某个方法过程中可能会throw出一个异常,那么这个代码范围可以使用try…catch包围起来,当出现异常的时候,则会进入到catch的逻辑中,用户可以根据自己的需要去进行相应的错误日志记录等,如果这个代码有资源在执行完成后需要释放,可以使用finally关键字来存放释放资源的逻辑。

image.png

1、try关键字:


 主要用于包围可能存在异常情况的代码段,并不是范围越大越好,如果可能,尽量将包围的范围缩小,因为不出异常情况下效率是没有多大影响,但是如果出现异常,那么范围越大则效率越低,因为被try包围的代码快,会阻止对JAVA的优化如指令重排序。


 2、catch关键字:


 catch子句紧跟在try块后面,用来指定你想要捕获的异常的类型,进行异常日志的记录等逻辑处理。

 3、finally关键字:


 finally为确保一段代码不管发生什么异常状况都要被执行,除非虚拟机退出如:exit(0),常用于资源的释放。


 4、throw关键字:


 throw语句用来明确地抛出一个异常,如某个代码段已经会出现某个问题,但是你并不像在这里进行处理,此时可以通过throw关键字进行异常抛出,让调用者去处理。


 5、throws关键字:


 throws用来声明一个方法可能抛出的各种异常,用于方法声明处,表示这个方法中可能抛出的异常,需要调用者进行处理或者晚上抛出这些异常。

image.png

三: 在程序中遇到异常在所难免,你有什么好的处理异常经验?


  1、异常不要用来做流程控制、条件控制,因为异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式要低很多(阿里巴巴开发规范手册)

image.png

  2、代码划分为可能出现异常代码块和不可能出现异常代码块,可能出现异常的代码块使用try…catch异常捕获机制进行处理,而不应该对一大段代码进行try…catch,这不仅是不负责任的表现,同时出现异常时也很难定位到问题。

image.png

  3、捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的

内容。

image.png

4、每个方法的异常最好有相应的文档描述,便于日后代码维护。


 5、在事务的场景下,抛出异常被 catch 后,如果需要回滚,一定要注意手动回滚事务。


 6、finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。如果 JDK7 及以上,可以使用 try-with-resources 方式.

image.png

PS:上面的经验参考自《阿里巴巴开发规范手册-泰山版》,有需要的可以私信我。

image.png

四: final、finally、finalize的区别?


final:修饰符(关键字)可以用于修饰类、方法、变量。分别表达的含义是类不可以被继承、方法不能被重写、被修饰的变量是常量,需要在声明的时候给定初始值。


finally:通常放在try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,可以将释放外部资源的代码写在finally块中。


finalize:Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作。


追问1、try-catch-finally需要同时都存在?那个可以省略?

 不需要同时存在,try-catch-finally可以划分为try-catch、try-finally、try-catch-finally三种结构。


 try-catch结构主要是为了捕获可能出现的异常并进行相应的异常处理。


 try-finally结构主要是为了捕获异常时正确释放资源或者关闭流


 try-catch-finally结构主要是为了处理既要捕获异常处理异常,也要在出现异常时关闭流和释放对应资源的场景

image.png

五: NoClassDefFoundError和 ClassNotFoundException区别是什么?


 NoClassDefFoundError是这一种Error类型错误,它是由JVM异常而引起的,无法通过程序去处理的,所以这个错误我们不应该通过异常处理机制去处理。


 ClassNotFoundException是Exception的一种子类,它是一种运行时异常,可以通过异常处理机制进行处理,常见的引起原因如下:


 1、使用 Class.forName, ClassLoader.loadClass 或 ClassLoader.findSystemClass 动态加载类到内存的时候,根据类路径没有找到对应的类,则抛出该异常。


 2、某个类已经由一个类加载器加载至内存中,另一个加载器又尝试去加载它,因为类只能被一个累加载器加载一次,对类加载流程感兴趣的可以看之前的一篇文字: 《诚意满满,准备跳槽和应届生必备JAVA面试知识点!》。



追问1、try-finally结构中,如果在try和finally中分别有return,则具体的返回情况会是什么?


 情况1: 如果返回的类型是值类型(常见的JAVA八大类型),那么当try和finally同时修改参数,并且在try中返回时,返回的值是try中修改后的值,而不是finally修改的值。


 具体原因: 通过反编译执行的字节码文件可知,try语句块中的return返回的值并不是外部定义的变量i,而是在内部自定义了一个局部变量,存储了try语句块中赋值后的变量,然后return时是返回这个局部变量,而不是变量i。

image.png

image.png

情况2: 如果返回的类型是值类型(常见的JAVA八大类型),那么当try和finally同时有return语句时,返回的值是finally中修改后的值。

image.png

情况3: 如果返回的类型是引用类型,那么返回的值则是最后finally中设置的值,因为它们指向的是同一个引用地址,所以最后修改的值就是引用地址中最新的值。

image.png

追问2、try-catch-finally结构中,如果在catch中return了,finally中的代码是否还会被执行?


  会的,finally中的代码会在catch结构return之前被执行,但是不推荐在catch中做return操作。

image.png

每日小结


  不积跬步,无以至千里;不积小流,无以成江海。今天播种努力的种子,总会有一天发芽!


  欢迎大家关注,如果觉得文章对你有帮助,不要忘记一键三连哦,你的支持是我创作更加优质文章的动力,希望大家都能够早日拿到心仪的Offer,有任何面试问题可以私信我,欢迎大家投稿面试题目哦!


相关文章
|
16天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
39 17
|
7天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
11天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
51 4
|
12天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
29 2
|
9天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
|
18天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
6天前
|
安全 Java 开发者
深入解读JAVA多线程:wait()、notify()、notifyAll()的奥秘
在Java多线程编程中,`wait()`、`notify()`和`notifyAll()`方法是实现线程间通信和同步的关键机制。这些方法定义在`java.lang.Object`类中,每个Java对象都可以作为线程间通信的媒介。本文将详细解析这三个方法的使用方法和最佳实践,帮助开发者更高效地进行多线程编程。 示例代码展示了如何在同步方法中使用这些方法,确保线程安全和高效的通信。
25 9
|
9天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
|
5天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
9天前
|
Java
JAVA多线程通信:为何wait()与notify()如此重要?
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是实现线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件满足时被唤醒,从而确保数据一致性和同步。相比其他通信方式,如忙等待,这些方法更高效灵活。 示例代码展示了如何在生产者-消费者模型中使用这些方法实现线程间的协调和同步。
23 3

热门文章

最新文章