网上关于java的面试题随处可见,可比较宅的我仍然愿意总结到自己的博客中,希望对看到的小伙伴们有所帮助,答案仅供参考,也欢迎小伙伴们留言。。。
一、java基础
1.JDK 和 JRE 有什么区别?
jdk是java开发工具包,提供了java开发环境和运行环境,它包含jre,还包含了很多java程序调试和分析工具。
jre为java运行提供了所需环境。
简而言之:如果需要运行java程序,只需安装jre就行,如果要编写java程序,需要安装jdk。
2.== 和 equals 的区别是什么?
==基本类型比较的的是值,引用类型比较的是地址值。
equals方法比较引用数据类型,所有的对象都会继承 Object 类中的方法,没有重写 Object 类中的 equals 方法,equals方法和==号比较引用数据类型无区别,重写后的equals方法比较的是对象中的属性。
特例:
当用equals()方法进行比较时,对类File、String、Date及包装类(WrapperClass)来说,是比较类型及内容而不考虑引用的是否同一对象;因为这些类重写了Object类的equals()方法。
参考本人博客:https://blog.csdn.net/duan196_118/article/details/104092688
3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
不对。两个对象的hashCode相同,其equals不一定为true。看过上面参考博客的小伙伴会知道:
"如果两个对象相同,那么它们的hashCode应该相等。如果两个对象不相同,它们的hashCode可能相同"。
1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。
2、如果两个对象不equals,他们的hashcode有可能相等。
3、如果两个对象hashcode相等,他们不一定equals。
4、如果两个对象hashcode不相等,他们一定不equals
4.final 在 java 中有什么作用?
final是修饰符,意为最终的,不可变的。
被final修饰的类叫最终类,不能被继承。
被final修饰的方法不能被重写。
被final修饰的变量为常量,常量必须初始化,初始化之后值就不能被修改。
5.java 中的 Math.round(-1.5) 等于多少?
等于-1,Math.round(); 向上取整;
关于Math类的更多用法参考博客:https://blog.csdn.net/duan196_118/article/details/104134461
6.String 属于基础的数据类型吗?
String类不属于基础数据类型,能阐述基础数据类型有哪些,并介绍String类型的特点如它被final修饰,不能被继承等等更好。
7.java 中操作字符串都有哪些类?它们之间有什么区别?
操作字符串的类有:String 、StringBuffer、StringBuilder。
具体区别参考博客:https://blog.csdn.net/duan196_118/article/details/104135390
8.String str="i"与 String str=new String("i")一样吗?
不一样,String str="i",jvm会将其分配到常量池中。而String str=new String("i")则会被分配到堆内存中。
9.如何将字符串反转?
使用StringBuilder或StringBuffer的reverse方法。
10.String 类的常用方法都有那些?
length(); 返回字符串的长度
split(); 切割字符串,返回一个切割后的数组
trim(); 去除字符串首尾空格
substring(); 截取字符串
replace(); 字符串的替换
contains(); 判断是否包含指定子串
indexOf():返回指定字符的索引
isEmpty(); 判断字符串是否为空
charAt(); 返回指定索引处的字符
getBytes(); 返回字符串的byte类型数组
equals(); 字符串的比较
toUpperCase(); 转为大写
toLowerCase(); 转为小写
startsWith(); 以指定前缀开头
endsWith(); 判断字符串是否以指定后缀结尾
java.lang.String是常见的一个类,它提供了很多方法,根据个人情况合理答出常用的方法即可。
11.抽象类必须要有抽象方法吗?
不需要,抽象类可以有抽象方法和非抽象方法。
12.普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法。
普通类可以直接被实例化,抽象类不能直接被实例化。
13.抽象类能使用 final 修饰吗?
不能,被final修饰的类无法被继承,而抽象类就是让其它类继承的,若被final修饰就无法被继承了。
14.接口和抽象类有什么区别?
1) 接口使用interface声明,用implements关键字来实现接口,抽象类用abstract声明,使用extends来继承。
2)抽象类可以有构造函数,而接口不能有。
3)抽象类可以有普通方法和抽象方法,而接口不能有普通方法(jdk1.8新特性:在一个接口里面有了一个实现的方法。只需要使 用 default关键字即可)
4)接口不能定义静态方法,抽象类可以(jdk1.8之后可以)
5)接口中的成员变量是静态常量,使用public static final修饰,抽象类可以定义静态常量也可以定义非静态常量
6)一个类可以实现多个接口,但只能继承一个类。java是单继承多实现。
15.java 中 IO 流分为几种?
按功能来分:输入流(input)、输出流(output)
按类型来分:字节流和字符流
可根据个人的情况对IO流做出介绍
16.BIO、NIO、AIO 有什么区别?
BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
17. Files的常用方法都有哪些?
Files.createDirectory():创建文件夹
Files.exists():检测文件路径是否存在
Files.createFile():创建文件
Files.delete():删除一个文件或目录
Files.copy():复制文件
Files.move():移动文件
Files.size():查看文件个数
Files.read():读取文件
Files.write():写入文件
18.你知道的开源协议有哪些?
GPL (GNU General Public License) :GNU通用公共许可协议
LGPL (GNU Lesser General Public License) :GNU宽通用公共许可协议
BSD(Berkeley Software Distribution) :伯克利软件分发许可协议
MIT(Massachusetts Institute of Technology):MIT之名源自麻省理工学院
Apache (Apache License) :Apache许可协议
MPL (Mozilla Public License) :Mozilla公共许可协议
19. 数据库中的范式有哪些?
第一范式----数据库中的表(所有字段值)都是不可分割的原子数据项。
第二范式----数据库表中的每一列都和主键相关,而不能只和主键的某一部分相关。
第三范式----数据库表中每一列数据都和主键直接相关,不能间接相关。范式是为了减小数据冗余。
20.什么是反射?
java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性方法;对于任意一个对象都能调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能成为java的反射机制。
反射机制的讲解:https://blog.csdn.net/duan196_118/article/details/104105628
21.什么是 java 序列化?什么情况下需要序列化?
序列化一般是指把结构化的对象变成无结构的字节流,便于存储和传输。首先序列化并不是java所独有的,基本所有编程语言都提供了序列化的方式,序列化是编程的一种解决问题的方式。java序列化就是将对象按照某种协议格式(某种约定的方式)放入一个buffer中,其目的是便于网络传输或持久存储。反序列化,就是将序列化后的buffer按照序列化时还原成原来的对象,这样程序就 能直接使用还原的对象了。
简单的说:序列化就是将对象输出到外界,反序列化就是将外界或磁盘中的对象加载到内存中。
( 序列化:将 Java 对象转换成字节流的过程。就是为了保存在内存中的各种对象的状态,并且通过反序列化可以把保存的对象再读出来。)
a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;
22.动态代理是什么?有哪些应用?
当想要给实现了某个接口的类中的方法,加一些额外的处理。比如说加日志,加事务等。可以给这个类创建一个代理,故名思议就是创建一个新的类,这个类不仅包含原来类方法的功能,而且还在原来的基础上添加了额外处理的新类。这个代理类并不是定义好的,是动态生成的。具有解耦意义,灵活,扩展性强。
动态代理的应用:
Spring的AOP
事务
权限
日志
23.怎么实现动态代理?
动态代理实现:
首先必须定义一个接口,还要有一个InvocationHandler(将实现接口的类的对象传递给它)处理类。再有一个工具类Proxy(习惯性将其称为代理类,因为调用他的newInstance()可以产生代理对象,其实他只是一个产生代理对象的工具类)。利用到InvocationHandler,拼接代理类源码,将其编译生成代理类的二进制码,利用加载器加载,并将其实例化产生代理对象,最后返回。
24.为什么要使用克隆?
想要对一个对象进行处理,又想保留原有的数据进行接下来的操作,clone是最简单最高效的方法。
25.深拷贝和浅拷贝区别是什么?
浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝(例:assign())
深拷贝是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝(例:JSON.parse()和JSON.stringify(),但是此方法无法复制函数类型)
26.常见的异常类有哪些?
ArithmeticException:数学异常。例如,一个整数“除以零”时,抛出此类的一个实例。
ClassCastException:强转异常,当试图将对象强制转换为不是实例的子类时,抛出该异常。
NullPointerException:当应用程序试图访问空对象时,则抛出该异常。
SQLException:提供关于数据库访问错误或其他错误信息的异常。
IndexOutOfBoundsException:指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
NumberFormatException:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
NoSuchMethodException:无法找到某一特定方法时,抛出该异常。
FileNotFoundException:当试图打开指定路径名表示的文件失败时,抛出此异常。
IOException:当发生某种I/O异常时,抛出此异常。
IllegalArgumentException:抛出的异常表明向方法传递了一个不合法或不正确的参数。
SecurityException:由安全管理器抛出的异常,指示存在安全侵犯。
UnsupportedOperationException:当不支持请求的操作时,抛出该异常。
RuntimeException:是那些可能在Java虚拟机正常运行期间抛出的异常的超类。
27.throw 和 throws 的区别?
throw是手动抛出一个具体的异常。
throws是在方法声明处抛出一个异常,声明异常但不处理异常,谁调用我就让其处理异常。
throw,如果执行了,那么一定是抛出了某种异常了,而throws表示可能出现,但不一定。
28.final、finally、finalize 有什么区别?
final是修饰符,意为最终的,不可变的。 被final修饰的类叫最终类,不能被继承。被final修饰的方法不能被重写。被final修饰的变量为常量,常量必须初始化,初始化之后值就不能被修改。
finally一般作用在try-catch中,在处理异常时将一定要执行的代码放到finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
finalize是Object类的一个方法,改方法一般由垃圾回收器来调用,当我们调用System的gc()方法的时候,由垃圾回收器调用finalize(),回收垃圾。
29.try-catch-finally 中哪个部分可以省略?
好多人认为try-catch语句是放在一起不能省略的。其实try语句后面是可以省略catch语句的,但是必须有finally语句。也可以省略finally语句,但是必须要有catch语句。也就是说try语句后面必须要有一个别的语句跟在后面。
切记:catch和finally语句不能同时省略!!!
30.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
会执行
1、不管有没有异常,finally中的代码都会执行
2、当try、catch中有return时,finally中的代码依然会继续执行
3、finally是在return后面的表达式运算之后执行的,此时并没有返回运算之后的值,而是把值保存起来,不管finally对该值做任何的改变,返回的值都不会改变,依然返回保存起来的值。也就是说方法的返回值是在finally运算之前就确定了的
4、如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。
5、finally代码中最好不要包含return,程序会提前退出,也就是说返回的值不是try或catch中的值
31.get 和 post 请求有哪些区别?
参考博客:https://blog.csdn.net/duan196_118/article/details/104155755
32.http 响应码 301 和 302 代表的是什么?有什么区别?
它们都是Http状态码,代表着某个URL发生了改变。
301代表永久重定向
302代表暂时重定向
33.forward 和 redirect 的区别?
forward:转发,是服务器内部行为,地址栏不会发生改变。request域可以共享。
redirect:重定向,相当于两次http请求,服务器在响应第一次请求的时候,让浏览器再向另外一个URL发出请求。request域失效。
34.简述 tcp 和 udp的区别?
1. TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。
2. TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。
3. Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。
4. UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
5. 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。
6. TCP对系统资源要求较多,UDP对系统资源要求较少。
35. OSI 的七层模型都有哪些?
1. 应用层:网络服务与最终用户的一个接口。
2. 表示层:数据的表示、安全、压缩。
3. 会话层:建立、管理、终止会话。
4. 传输层:定义传输数据的协议端口号,以及流控和差错校验。
5. 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择。
6. 数据链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能。
7. 物理层:建立、维护、断开物理连接。
36. tcp 为什么要三次握手,两次不行吗?为什么?
为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。
37. 如何实现跨域?
document.domain+iframe的设置(设置document.domain解决无法读取非同源网页的 Cookie问题)
jsonp(不能成为真正的Ajax,本质上仍是动态创建script)
跨域资源共享(CORS)
nginx解决跨域...
可参考博客:https://blog.csdn.net/duan196_118/article/details/103840356
38.说一下 JSONP 实现原理?
jsonp 即 json+padding,动态创建script标签,利用script标签的src属性可以获取任何域下的js脚本,通过这个特性(也可以说漏洞),服务器端不在返货json格式,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
39.说一下你熟悉的设计模式?
单例模式,工厂模式,当然是挑选自己熟悉的设计模式进行阐述了,并不是越多越好哟,根据自己的情况作答。
40.简单工厂和抽象工厂有什么区别?
简单工厂:是由一个工厂对象创建产品实例,简单工厂模式的工厂类一般是使用静态方法,通过不同的参数的创建不同的对象实例可以生产结构中的任意产品,不能增加新的产品
抽象工厂:用来生产不同产品族的全部产品,对于增加新的产品,无能为力;支持增加产品族。
41. 说一下 jvm 的主要组成部分?及其作用?
1.类加载器(Class Loader):加载类文件到内存。Class loader只管加载,只要符合文件结构就加载,至于能否运行,它不负责,那是有Exectution Engine 负责的。
2.执行引擎(Execution Engine):也叫解释器,负责解释命令,交由操作系统执行。
3.本地库接口(Native Interface):本地接口的作用是融合不同的语言为java所用
4.运行时数据区(Runtime Data Area):运行数据区是jvm的重点,我们所有所写的程序都被加载到这里,之后才开始运行。
42.说一下 jvm 运行时数据区?
详细参考博客:https://blog.csdn.net/duan196_118/article/details/104214447
1. 方法区 - 方法区是被所用线程共享,所有字段和方法字节码以及一些特殊方法,如构造函数,接口代码也在此定义,简单的说,所有定义的方法的信息都保存在该区域,此区域属于共享区域。
静态变量,常量,类信息(构造方法,接口定义),运行时的常量池存在方法区中,但是实例变量存在堆内存中,和方法区无关。
2. 堆区 - 用于存储java程序在运行过程中创建的所有对象。每个JVM还有一个堆区。由于方法 和堆区共享多个线程的内存,所存储的数据不是线程安全的。
3. 栈区 - 对于每个线程,都会创建一个单独的运行时栈。对于每个方法调用,将在栈内存中创建一个称为堆栈帧的条目。所有局部变量都将在栈内存中创建。因为它不是共享资源,所以栈区域是线程安全的。
4. PC寄存器 - 每个线程都有独立的PC寄存器,是线程私有的,一旦执行指令就保存当前执行指令的地址,PC寄存器将用下一条指令更新。即它代表指令在主存中的地址,每执行一条指令后PC+1,即指向下一条指令。本地方法栈即通过Java调用本地方法时的相关信息,但与调用Java方法不一样,调用Java方法时JVM会向当前Java栈中压入一个新的栈桢,而调用本地方法则不会修改Java栈。
5. 本地方法栈 - 本地方法栈包含本机方法信息。对于每个线程,都会创建一个单独的本地方法栈。可以理解成JVM运行时数据区的一个扩展。
43.说一下堆栈的区别?
堆:一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的。类的加载器读取了类文件之后,需要把类、方法、常变量放到堆内存中,以方便执行器执行,堆内存分三部分:永久存储(用于存放jdk自身携带的class,interface的元数据,也就是说它存储的是运行环境必须的类信息,被装载至此区域的数据是不会被垃圾回收掉的,只有关闭jvm释放此区域所占用的内存)区、新生区、老年代。
栈:栈也叫栈内存,是java程序的运行区,是在线程创建时创建,它的生命周期跟随线程的生命周期,线程结束栈内存释放;对于栈来说不存在垃圾回收的问题,只要线程一结束,该栈就结束。栈中的数据以栈帧的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法和运行期数据的集合,当一个方法A被调用时就产生了一个栈帧F1,并被压入到栈中,A方法又调用了B方法,于是产生栈帧F2也被压入栈,执行完毕后,先弹出F2栈帧,再弹出F1栈帧,遵循“先进后出”原则。
堆与栈的区别:
1.栈内存存储的是变量而堆内存存储的是对象;
2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;
3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。
44.什么是类加载器,类加载器有哪些?
实现通过类的权限定名获取该类的二进制字节流的代码块叫做类加载器。
主要有一下四种类加载器:
1. 启动类加载器(Bootstrap ClassLoader)用来加载java核心类库,无法被java程序直接引用。
2. 扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
3. 系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。
4. 用户自定义类加载器,通过继承 java.lang.ClassLoader类的方式实现。
45.什么是双亲委派模型?
类加载的双亲委派模型
双亲委派模型要求除了顶层的启动类加载器外,其他的类加载器都应当有自己的父类加载器。这里类加载器之间的父子关系一般不会以继承关系来实现,而是都使用组合关系来复用父加载器的代码。
工作过程:
如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传递到顶层的启动类加载器中,
只有当父类加载器反馈自己无法完成这个请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
46.说一下类加载的执行过程?
类加载的五个过程:加载、验证、准备、解析、初始化。
加载:
在加载阶段,虚拟机主要完成三件事:
1.通过一个类的全限定名来获取定义此类的二进制字节流。
2.将这个字节流所代表的静态存储结构转化为方法区域的运行时数据结构。
3.在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区域数据的访问入口。
验证:
验证阶段作用是保证Class文件的字节流包含的信息符合JVM规范,不会给JVM造成危害。如果验证失败,就会抛出一个java.lang.VerifyError异常或其子类异常。验证过程分为四个阶段:
1.文件格式验证:验证字节流文件是否符合Class文件格式的规范,并且能被当前虚拟机正确的处理。
2.元数据验证:是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言的规范。
3.字节码验证:主要是进行数据流和控制流的分析,保证被校验类的方法在运行时不会危害虚拟机。
4.符号引用验证:符号引用验证发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在解析阶段中发生。
准备:
准备阶段为变量分配内存并设置类变量的初始化。在这个阶段分配的仅为类的变量(static修饰的变量),而不包括类的实例变量。对已非final的变量,JVM会将其设置成“零值”,而不是其赋值语句的值:
pirvate static int size = 12;
那么在这个阶段,size的值为0,而不是12。 final修饰的类变量将会赋值成真实的值。
解析:
解析过程是将常量池内的符号引用替换成直接引用。主要包括四种类型引用的解析。类或接口的解析、字段解析、方法解析、接口方法解析。
初始化:
在准备阶段,类变量已经经过一次初始化了,在这个阶段,则是根据程序员通过程序制定的计划去初始化类的变量和其他资源。这些资源有static{}块,构造函数,父类的初始化等。
至于使用和卸载阶段阶段,这里不再过多说明,使用过程就是根据程序定义的行为执行,卸载由GC完成。
47.判断对象是否存活一般有两种方式:
1. 引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。
2. 可达性分析(Reachability Analysis):从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对象。
48.怎么判断对象是否可以被回收?
1.该对象没有与GC Roots相连
2.该对象没有重写finalize()方法或finalize()已经被执行过则直接回收(第一次标记)、否则将对象加入到F-Queue队列中(优先级很低的队列)在这里finalize()方法被执行,之后进行第二次标记,如果对象仍然应该被GC则GC,否则移除队列。 (在finalize方法中,对象很可能和其他 GC Roots中的某一个对象建立了关联,finalize方法只会被调用一次,且不推荐使用finalize方法)
49.简述java内存分配与回收策率以及Minor GC和Major GC
1. 对象优先在堆的Eden区分配。
2. 大对象直接进入老年代.
3.长期存活的对象将直接进入老年代.
当Eden区没有足够的空间进行分配时,虚拟机会执行一次Minor GC.Minor Gc通常发生在新生代的Eden区,在这个区的对象生存期短,往往发生Gc的频率较高,回收速度比较快;Full Gc/Major GC 发生在老年代,一般情况下,触发老年代GC的时候不会触发Minor GC,但是通过配置,可以在Full GC之前进行一次Minor GC这样可以加快老年代的回收速度。
50.java 中都有哪些引用类型?
强引用:GC时不会被回收
软引用:描述有用但不是必须的对象,在发生内存溢出异常之前被回收
弱引用:描述有用但不是必须的对象,在下一次GC时被回收
虚引用(幽灵引用/幻影引用):无法通过虚引用获得对象,用PhantomReference实现虚引用,虚引用用来在GC时返回一个通知。
51.说一下 jvm 有哪些垃圾回收算法?
常用的垃圾回收算法
标记-清除算法:
标记-清除算法采用从根集合(GCRoots)进行扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收,此算法一般没有虚拟机采用。
复制算法:
将内存分成两块容量大小相等的区域,每次只使用其中的一块,当这一块用完了,就将所有存活的对象复制到另一块内存空间,然后清除前一块内存空间。这样一来就不容易出现内存碎片的问题。
标记-整理算法:
思想:在完成标记之后,它不是直接清理可回收对象,而是将存活对象向一端移动,然后清理掉端边界以外的内存。不会产生内存碎片,但是依旧移动对象的成本。
分代收集算法:
分代收集算法是目前大部分jvm的垃圾收集器采用的算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代和新生代,在堆区之外还有一个代就是永久代。老年代的特点是每次垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾回收时都有大量对象需要被回收,那么就可以根据不同的特点采取合适的收集算法。
52.说一下 jvm 调优的工具?
常用调优工具分为两类,jdk自带监控工具:jconsole和jvisualvm,第三方有:MAT(Memory Analyzer Tool)、GChisto。
- jconsole,Java Monitoring and Management Console是从java5开始,在JDK中自带的java监控和管理控制台,用于对JVM中内存,线程和类等的监控
- jvisualvm,jdk自带全能工具,可以分析内存快照、线程快照;监控内存变化、GC变化等。
- MAT,Memory Analyzer Tool,一个基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗
- GChisto,一款专业分析gc日志的工具
53.常用的 jvm 调优的参数都有哪些?
1. 设定堆内存大小
-Xmx:堆内存最大限制。
2. 设定新生代大小。 新生代不宜太小,否则会有大量对象涌入老年代
-XX:NewSize:新生代大小
-XX:NewRatio 新生代和老生代占比
-XX:SurvivorRatio:伊甸园空间和幸存者空间的占比
3. 设定垃圾回收器 年轻代用 -XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC
希望对看到的小伙伴们有帮助哟,后续对java Web 及框架部分作出总结,如有不同意见,欢迎留言指正。望不吝赐教。。。
面试题持续更新:https://blog.csdn.net/duan196_118/article/details/104728292