java面试准备6
创始人
2025-06-01 02:42:10

受检异常与非受检异常

受检异常:编译器必须处理的异常。正确地程序在运行过程中,经常出现的、符合预期的异常情况。一旦发生此类异常,就必须采用某种方式进行处理。除了RuntimeException及其子类之外,其他的Exception都是与受检异常。编译器会检查此类异常,也就是说当编译器检查到应用中的某处可能会发生此类异常时,将会提示你处理本异常,要么使用try-catch捕获,要么使用方法签名中的throws关键字抛出,否则编译不通过。

非受检异常:编译器不会进行检查并且不要求必须处理的异常,也就是说当程序中出现此类异常时,即使我们没有try-catch捕获它,也没有使用throws抛出该异常,编译也会正常通过。该类异常包括运行时异常(RuntimeException及其子类)和错误(Error)。非受检异常不可以通过throws关键字抛出。

Error和Exception区别是什么?

Error类型的错误通常为虚拟机相关错误,如系统崩溃,内存不足,堆栈溢出等,编译器不会对这类错误进行检测,Java应用程序也不应该对这类错误进行捕获,一旦这类错误发生,通常应用程序会被终止,仅仅靠着应用程序本身无法恢复。
Exception类的错误是可以在应用程序中进行捕获并且处理的,遇到这种错误,应该进行处理,使得应用程序可以继续执行下去。

运行时异常和受检异常区别是什么?

运行时异常包括RuntimeException类及其子类,表示JVM在运行期间可能出现的异常。Java编译器不会检查运行时异常。
受检异常是Exception中除了RuntimeException及其子类之外的异常,java编译器会检查受检异常。
RuntimeException异常和受检异常的区别:是否强制要求调用者处理此异常,如果强制要求
则是受检异常。否则就是非受检异常。

JVM是如何处理异常的?

在一个方法中如果发生异常,这个方法会创建一个异常对象,并且转交给jvm,该异常对象包含异常名称、描述以及发生异常时应用程序的状态。创建异常对象并且转交给jvm的过程称为抛出异常。可能有一系列的方法调用,然后才进入抛出异常的方法,这一系列方法调用的有序列表叫作调用栈。
JVM会顺着调用栈去查看是否有可以处理异常的代码,如果有,则调用异常处理代码,当jvm发现时,会把异常代码传递给它。如果没有找到,jvm就会把该异常交给默认的异常处理器。默认异常处理会打印出异常并且终止应用程序。

throw和throws的区别是什么

java的异常处理除了包括捕获异常和处理异常之外,还包括声明异常和抛出异常,可以通过throws关键字在该方法上声明抛出的异常,或者在方法内部通过throw抛出异常对象。
具体区别如下:
(1)throw关键字用于方法内部,只能用于抛出一种异常,用来抛出方法或者代码块中的异常,受检异常和非受检异常都可以抛出。
(2)throws关键字用于方法声明上,可以抛出多个异常,用来标识该方法可能抛出的异常列表。一个方法用throws标识了可能跑出的异常,则调用方必须包含可以处理异常的代码,否则也要在方法签名中用throws关键字声明相对应的异常。

final、fianlly、finalize有什么区别?

(1)fianl可以修饰类、变量、方法,修饰类表示该类不能被继承,修饰方法表示不能被重写、修饰变量表示不能被重新赋值。
(2)finally一般用在try-catch代码块中,在处理异常的时候,通常我们要将一定要执行的代码放在finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放关闭资源的代码。
(3)finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,Java中允许使用finalize()方法在垃圾回收器将对象从内存中清除。

NoClassDefFoundError和ClassNotFoundException的区别?

NoClassDefFoundError是一个Error类型的异常,是由JVM所引起的,不应该尝试捕获这个异常。
引起该异常的原因是JVM或者ClassLoader尝试加载某类的时候找不到该类的定义,该动作发生在运行期间,即编译时该类存在,但在运行时却找不到了,可能是编译后被删除了等原因导致。

ClassNotFoundException是一个受检异常,需要显示地使用try-catch对齐进行捕获或者处理,或者在方法中使用throws关键字进行声明。当使用Class.forName,ClassLoader.loadClass或者ClassLoader.findSystemClass动态加载类到内存时,通过传入的类路径参数没有找到该类,就会抛出该异常异常;另一个原因可能是某个类已经由一个类加载器加载到内存中,另一个类加载器又尝试去加载它。

常见的RuntimeException有哪些?

(1)ClassCastException(类转换异常)
(2)IndexOutOfBoundException(数组越界异常)
(3)NullPointException(空指针异常)
(4)还有IO操作的BufferOverfolwException异常

Tomcat是什么?

Tomcat服务器是Apache软件基金会项目中的一个核心项目,是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选。

Tomcat的缺省端口是多少,怎么修改

找到Tomcat目录下的conf文件夹,进入conf文件夹里面找到server.xml文件,打开server.xml文件,在server.xml文件里面找到下列信息,把Connector标签的8080端口改成你想要的端口:
在这里插入图片描述

tomcat有哪几种Connector运行模式?

(1)BIO:同步并阻塞,一个线程处理一个请求,缺点:并发量高的时候,线程数目较多,浪费资源。
(2)NIO:同步非阻塞IO,利用java的异步IO处理,可以通过少量的线程处理大量的请求,可以复用同一个线程处理多个connection(多路复用)。
(3)APR:即Apache Portable Runtime,从操作系统层面解决io阻塞问题。也叫AIO方式,异步非阻塞IO,与NIO的区别主要是操作系统的底层区别。

tomcat容器是如何创建servlet类实例?用到了什么原理?

(1)当容器启动时,会读取在webapps目录下所有的web应用中的web.xml文件,然后对xml文件进行解析,并读取servlet注册信息。然后将每个应用中注册的servlet类都进行加载,并通过反射的方式实例化。
(2)在servlet注册时加上1,如果为正数,则在一开始实例化,如果不写或者为负数,则第一次请求实例化。

Tomcat作为servlet容器,有三种工作模式:

(1)独立的servlet容器,servlet容器是web服务器的一部分。
(2)进程内的servlet容器,servlet容器是作为web服务器的插件和java容器的实现,web服务器插件在内部地址空间打开一个jvm使得java容器可以在内部得以运行。
(3)进程外的servlet容器,servlet容器运行与web服务器之间的地址空间,并作为web服务器的插件和java容器实现的结合。反映时间不如进程内部,但是伸缩性和稳定性比进程内优;

进入tomcat的请求可以根据tomcat的工作模式分为如下两类:
tomcat作为应用程序服务器:请求来自于前端的web服务器,这可能是Apache,IIS,Nginx等。
tomcat作为独立服务器:请求来自于web服务器。

Tomcat顶层架构小结

(1)Tomcat中只有一个Server,一个Server可以有多个Service,一个Service可以有多个Connector和一个Container。
(2)Server掌管着整个tomcat的生死大权。
(3)Connector用于接受请求并将请求封装成Request和Response来处理。
(4)Service是提供对外服务的。
(5)Container用于封装和管理Servlet,以及具体处理request请求。

JVM的主要组成部分

JVM包含连个子系统和两个组件,两个子系统分别为Class loader(类加载子系统)、Execution engine(执行引擎)。两个组件分别为Runtime Date area(运行时数据区)和Native Interface(本地接口)。
Class loader(类装载子系统):根据给定的去按限定类名来装载class文件到Runtime Data area中的method area。
Execution engine(执行引擎):执行classes中的指令。
Native Interface(本地接口):与native libraries交互,是与其它编程语言交互的接口。
Runtime data area(运行时数据区):就是我们常说的JVM的内存。

JVM的作用

首先通过编译器把Java代码转化成字节码,类加载器(ClassLoader)再把字节码加载到内存中,将其放到运行时数据区的方法区内,而字节码文件指示JVM的一套指令集的规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器执行引擎(Execution Engine),将字节码指令翻译成底层操作系统指令,再交给CPU执行,而在这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。

jvm运行时数据区

java虚拟机规范规定的区域主要分为以下五个部分:
(1)程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都要依赖这个计数器来完成。
(2)java虚拟机栈(Java Virtual Machine Stacks):用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
(3)本地方法栈(Native Method Stack):与虚拟机栈的作用一样,只不过虚拟机栈是用来服务java方法的,而本地方法栈是用为虚拟机调用Native 方法服务的。
(4)Java堆(Java Heap):Java虚拟机中内存最大的一块,是被线程共享的,几乎所有的对象实例都会在这里分配内存。
(5)方法区(Method Area):用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等。

说一下堆栈的区别?

物理地址:
堆的物理地址分配对象是不连续的,因此性能较慢。在GC(垃圾回收)的时候也要考虑到不连续的分配,所以有各种算法。比如,标记-消除,复制,标记-压缩,分代(即新生代使用复制算法,老年代使用标记–压缩)。栈使用的是数据结构中的栈,先进后出的原则,物理地址是连续分配的,所以性能更快。

内存分别:堆因为是不连续的,所以内存分配是在运行期间确认的,因此大小不固定,一般大小远远大于栈。
栈是连续的,所以分配的内存大小要在编译期间就确认,大小是固定的。

存放的内容:
堆中存放的是对象的实例和数组。因此该区更关注的是数据的存储。
栈中存放的是局部变量、返回结果、操作数栈,该区更关注的是方法的执行。

重点关注:
静态的对象放在堆中,静态变量方法方法区中。

可见度区别:
堆对于整个应用程序都是共享的、可见的。
栈只对于线程可见,所以它是线程私有的,生命周期与线程相同。

为对象分配内存

类加载完成后,接着会在Java堆中划分一块内存给对象,内存分配根据Java堆是否规整,有两种分配方式:
(1)指针碰撞:如果Java堆的内存规整,即把所有用过的内存分在一边,空闲的在另一边。分配内存时将位于中间的指针指示器向空闲的内存移动一段与对象大小相同的距离,这样便完成分配内存工作。
(2)空闲列表:如果java堆的内存时不规整的,则需要虚拟机维护一个列表来记录哪些内存时可用的,这样在分配内存时可以直接从堆中查询到足够大的内存分配给对象,并且在分配后更新列表记录。

使用哪种分配方式是由Java堆是否规整来决定的,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

内存溢出异常:Java会存在内存泄露吗?

内存泄露是指不再被使用的对象或者变量一直被占据在内存中。理论上说,Java是有GC垃圾回收机制的,也就是说,不再被使用的对象,会被GC自动回收掉,自动从内存中清除。
但即使是这样,Java还是存在着内存泄露的情况,原因:长生命周期的对象持有短生命周期的引用很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有对它的引用,而导致不能回收,就会发生内存泄露的场景。

简述Java垃圾回收机制

在java中,程序员是不需要显示的区释放一个对象的内存的,而是由java虚拟机自动执行。在jvm中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫描那些没有被任何引用的对象,并且将它们添加到要回收的集合中去,进行回收。

GC是什么?为什么要GC

GC是垃圾回收,内存回收会导致程序或者系统的不稳定甚至崩溃,Java提供的GC功能可以自动监控对象是否超过作用域从而到达自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。

相关内容

热门资讯

实测推荐.新版九哥炸金花.到底... 实测推荐.新版九哥炸金花.到底是不是挂.[其实是有挂]亲,新版九哥炸金花这个游戏其实有挂的,确实是有...
(独家分享)“新九方牛牛.辅助... (独家分享)“新九方牛牛.辅助软件@太坑了果然有挂您好:新九方牛牛这款游戏可以开挂,确实是有挂的,需...
盘点一款“越乡游拼三张究竟是不... 您好:越乡游拼三张这款游戏可以开挂,确实是有挂的,需要软件加微信【3671900】很多玩家在这款游戏...
玩家必看“欢乐标分到底有没有挂... 您好:欢乐标分这款游戏可以开挂,确实是有挂的,需要软件加微信【4830828】很多玩家在这款游戏中打...
玩家必看“宝宝浙江游戏开挂透视... 您好:宝宝浙江游戏这款游戏可以开挂,确实是有挂的,需要软件加微信【6383787】,很多玩家在新青鸟...