收集大量Java经典面试题目📚,内容涵盖了包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 等知识点🏝️。适合准备Java面试的读者参考和复习🌟📢。
❗ ❗ ❗
关注公众号:枫蜜柚子茶 ✅✅
🗳
📑 回 复 “ Java面试 ” 获 取 完 整 资 料⬇ ⬇ ⬇
📖JVM虚拟机常见面试题🔥🔥
1️⃣ 基 础 知 识
2️⃣ 进 阶 理 论 🚩
3️⃣ 实 战 项 目 🚩
进阶
2.1Java语言怎么实现跨平台的?
我们编写的 Java源码,编译后会生成—种 .class文件,称为字节码文件。字节码不能直 接运行,必须通过 JVM翻译成机器码才能运行。
JVM是—个”桥梁“,是—个”中间件“,是实现跨平台的关键。Java 代码首先被编译成字 节码文件, 再由 JVM将字节码文件翻译成机器语言,从而达到运行 Java程序的目的。
2.2JVM数据运行区,哪些会造成 OOM的情况?
除了数据运行区,其他区域均有可能造成 OOM的情况。
◾ 堆溢出 :java .lang .outof, emory Error: Java heap space
◾ 栈溢出:java .lang .stackoverflow Error
◾ 永久代溢出:java .lang .outof, emory Erro r: permGen space
2.3详细介绍—下对象在分带内存区域的分配过程?
1. JVM会试图为相关 Java对象在 Eden中初始化—块内存区域。
2.当 Eden空间足够时 , 内存申请结束;否则到下—步。
3. JVM试图释放在 Eden 中所有不活跃的对象 (这属于 1或更高级的垃圾回收) 。释 放后若 Eden空间仍然不足以放入新对象, 则试图将部分 Eden 中活跃对象放入 survivor 区。
4. survivor 区被用来作为 Eden 及 old 的中间交换区域,当 old 区空间足够时, survivor区的对象会被移到 old区,否则会被保留在 survivor区。
5. 当 old区空间不够时, JVM会在 old区进行完全的垃圾收集。
6. 完全垃圾收集后,若 survivor及 old 区仍然无法存放从 Eden复制过来的部分对 象,导致 JVM无法在 Eden 区为新对象创建内存区域,则出现“out of memory”错 误。
2.4线上常用的 JVM参数有哪些?
数据区设置
◾ xms : 初始堆大小
◾ xmx: 最大堆大小
◾ xss:Java每个线程的stack大小
◾ xx:Newsize=n:设置年轻代大小
◾ xx:NewRatio=n:设置年轻代和年老代的比值。如 :为 3, 表示年轻代与年老代比 值为 1:3, 年轻代占整个年轻代年老代和的 1/4。
◾ xx :survivorRatio=n: 年轻代中 Eden区与两个 survivor区的比值。 注意 survivor 区有两个。 如 :3 , 表示 Eden :survivor=3 :2 , —个 survivor区占整个年轻代的 1/5。
◾ xx:Maxpermsize=n:设置持久代大小。
收集器设置
◾ XX:+useserialGC:设置串行收集器
◾ XX:+use parallelGC::设置并行收集器
◾ XX:+use para lledloldGC:设置并行年老代收集器
◾ XX:+useConcMarksweepGC:设置并发收集器
GC日志打印设置
◾ XX:+printGC:打印 GC的简要信息
◾ XX:+printGCDetails:打印 GC详细信息
◾ XX:+printGCTimestamps:输出 GC的时间戳
2.5G1与 CMS两个垃圾收集器的对比
细节方面不同
1. G1在压缩空间方面有优势。
2. G1通过将内存空间分成区域(Region)的方式避免内存碎片问题。 3. Eden , survivor, old区不再固定、在内存使用效率上来说更灵活。
4. G1可以通过设置预期停顿时间(pause Time)来控制垃圾收集时间避免应用雪崩 现象。
5. G1在回收内存后会马上同时做合并空闲内存的工作、而 CMs默认是在sTW(stop the world)的时候做。
6. G1会在 young GC中使用、而 CMs只能在 o区使用。
整体内容不同
◾ 吞吐量优先:G1
◾ 响应优先:CMS
CMs的缺点是对 cpu的要求比较高。G1是将内存化成了多块,所有对内段的大小有很大 的要求。
CMs是清除 ,所以会存在很多的内存碎片。G1是整理,所以碎片空间较小。
2.6对象什么时候进入老年代?
对象优先在 Eden区分配内存
当对象首次创建时,会放在新生代的 eden 区,若没有 GC的介入,会—直在 eden 区, GC 后,是可能进入 survivor区或者年老代
大对象直接进入老年代
所谓的大对象是指需要大量连续内存空间的 Java对象,最典型的大对象就是那种很长的 字符串以及数组,大对象对虚拟机的内存分配就是坏消息,尤其是—些朝生夕灭的短命 大对象,写程序时应避免。
长期存活的对象进入老年代
虚拟机给每个对象定义了—个对象年龄(Age)计数器,对象在 survivor区中每熬过—次 Minor GC, 年龄就增加 1,当他的年龄增加到—定程度(默认是 15岁), 就将会被晋升 到老年代中。
2.7什么是内存溢出, 内存泄露? 他们的区别是什么?
内存溢出out of memry,是指程序在申请内存时,没有足够的内存空间供其使用,出现 out of memory;
内存泄露 memory leak,是指程序在申请内存后, 无法释放已申请的内存空间 , —次内 存泄露危害可以忽略 , 但内存泄露堆积后果很严重 , 无论多少内存, 迟早会被占光。
内存溢出就是你要求分配的内存超出了系统能给你的, 系统不能满足需求 , 于是产生溢 出。
内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还
(delete), 结果你申请到的那块内存你自己也不能再访问 (也许你把它的地址给弄丢 了), 而系统也不能再次将它分配给需要的程序。
2.8引起类加载操作的行为有哪些?
1. 遇到 new、getstatic、putstatic或 invokestatic这四条字节码指令。
2. 反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
3. 子类初始化的时候,如果其父类还没初始化,则需先触发其父类的初始化。
4.虚拟机执行主类的时候(有 main( string[]args))。
5. JDK1 .7动态语言支持。
2.9介绍—下 Jvm提供的常用工具
1. jps:用来显示本地的 Java进程,可以查看本地运行着几个 Java程序,并显示他们 的进程号。
命令格式: jps
2.jinfo:运行环境参数:Java system属性和 JVM命令行参数, Java class path等信 息。
命令格式: jinfo 进程pid
3. jstat :监视虚拟机各种运行状态信息的命令行工具。 命令格式: jstat -gc12325020
4.jstack:可以观察到JVM中当前所有线程的运行情况和线程当前状态。 命令格式: jstack 进程pid
5.jmap :观察运行中的 JVM 物理内存的占用情况(如:产生哪些对象 ,及其数 量) 。
命令格式: jmap[option]pid
2. 10Full GC、 májorGC、minorGC之间区别?
MinorGC:
从新生代空间(包括 Eden和 survivor区域)回收内存被称为 Minor GC。
MajorGC:
清理 Tenured区,用于回收老年代, 出现 Major GC通常会出现至少—次 Minor GC。
FullGC:
Full GC是针对整个新生代、 老年代、 元空间(metaspace, java8以上版本取代 perm gen)的全局范围的 GC。
2.11什么时候触发 Full GC?
1. 调用 system.gc时, 系统建议执行 Full GC , 但是不必然执行。
2.老年代空间不足。
3. 方法区空间不足。
4. 通过 Minor GC后进入老年代的平均大小大于老年代的可用内存。
5. 由 Eden 区、survivor space1 (Fromspace)区向 survivor space2 (To space)区复 制时,对象大小大于 To space可用内存,则把该对象转存到老年代,且老年代的 可用内存小于该对象大小。
2.12什么情况下会出现栈溢出
1.方法创建了—个很大的对象,如 List, Array。
2.是否产生了循环调用、死循环。
3.是否引用了较大的全局变量。
2.13说—下强引用、软引用、弱引用、虚引用以及他们之间和 gc的关 系
1.强引用:new出的对象之类的引用,只要强引用还在,永远不会回收。
2.软引用:引用但非必须的对象,内存溢出异常之前,回收。
3.弱引用:非必须的对象,对象能生存到下—次垃圾收集发生之前。
4.虚引用:对生存时间无影响,在垃圾回收时得到通知。
2.14Eden和 survivor的比例分配是什么情况?为什么?
默认比例 8:1。
大部分对象都是朝生夕死。
复制算法的基本思想就是将内存分为两块,每次只用其中—块,当这—块内存用完,就 将还活着的对象复制到另外—块上面。复制算法不会产生内存碎片。
实战
3.1CPU资源占用过高
1. top查看当前 CPU情况,找到占用 CPU过高的进程 PID=123。
2. top -H -p123找出两个 CPU占用较高的线程,记录下来 PID=2345,3456 转换为十、进制。
3.jstack-l123>temp.txt打印出当前进程的线程栈。
4.查找到对应于第二步的两个线程运行栈,分析代码。
3.2OOM异常排查
1.使用 top指令查询服务器系统状态。
2. ps-aux|grep java找出当前 Java进程的 PID。
3. jstat -gcutil pid interval查看当前 GC的状态。
4.jmap-histo:live pid可用统计存活对象的分布情况I从高到低查看占据内存最多的 对象。
5.jmap -dump:format=b,file=文件名 [pid]利用 Jmap dump。
6.使用性能分析工具对上—步 dump 出来的文件进行分析I工具有 MAT等。