【Java面试题】第八期:Java进阶篇,每周10道,根本停不下来~

这篇具有很好参考价值的文章主要介绍了【Java面试题】第八期:Java进阶篇,每周10道,根本停不下来~。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Java面试题】第八期:Java进阶篇,每周10道,根本停不下来~,# Java EE (Java高级特性),面试,java-ee,jvm,java,开发语言

1️⃣ 什么是字节码?好处是什么?

【Java面试题】第八期:Java进阶篇,每周10道,根本停不下来~,# Java EE (Java高级特性),面试,java-ee,jvm,java,开发语言

字节码是一种中间形式的代码,它是Java源代码编译后生成的一种二进制格式的代码,可以在Java虚拟机上运行。Java源代码编译后生成的字节码可以在不同的平台上运行,因为不同版本的Java虚拟机可以在不同的操作系统和硬件上运行,这使得Java具有了跨平台的特性。

字节码的好处是它可以提高Java程序的执行效率,因为字节码是一种经过编译的代码,而不是源代码。这使得Java程序在运行时可以更快地执行,因为它们不需要像解释执行源代码那样耗费时间。此外,字节码还可以被优化和调整,以进一步提高Java程序的性能。


2️⃣ 什么是Java序列化?何时需要序列化?如何实现序列化?

Java序列化是将Java对象转换为字节序列的过程,反序列化是将字节序列转换成Java对象的过程。
Java序列化以便可以将其存储在文件中、在网络上传输或者在进程之间传递,可以将对象的状态保存到硬盘或者内存中,同时又能够方便地将对象恢复到其原始状态。

需要序列化的情况通常包括:

  • 将对象存储到文件中,以便在以后的某个时间点检索它;
  • 将对象通过网络传输,例如在客户端和服务器之间传输数据;
  • 在进程之间传递对象

在Java中,可以通过实现Serializable接口来实现对象的序列化和反序列化,这个接口没有需要实现的方法,实现Serializable接口是为了告诉 JVM这个类的对象可以被序列化。

需要注意的是,不是所有的对象都需要或能够序列化。例如下面这些情况:

  • 包含非序列化字段的类对象,比如 Thread 类、InputStream 类等;
  • 包含对不可序列化实例化对象的引用的类对象,因为这个引用指向的对象不可序列化,那么这个类对象也不可序列化;
  • 包含循环引用的类对象,即一个对象引用了另一个对象,而后者又引用了前者,这种情况会导致无限递归,无法序列化;
  • 包含被 static修饰的静态变量的类对象,因为静态变量不属于任何一个实例化对象,无法通过实例化对象进行序列化;
  • 包含匿名内部类、局部内部类和 lambda 表达式的类对象,因为这些类没有名字,无法被序列化;
  • 包含被 transient 修饰的变量的类对象,因为 transient 可以用来修饰不需要序列化的变量,这些变量的值在序列化和反序列化时会被忽略。

3️⃣ 怎么判断对象是否可以被回收?

【Java面试题】第八期:Java进阶篇,每周10道,根本停不下来~,# Java EE (Java高级特性),面试,java-ee,jvm,java,开发语言

在Java中,判断一个对象是否可以被回收,需要通过垃圾回收机制来进行判断。垃圾回收机制主要有两种判断方式:引用计数法和可达性分析法

  • 引用计数法在对象中维护一个计数器,记录对象被引用的次数。当对象被引用时,计数器加一;当对象不再被引用时,计数器减一。当计数器为0时,说明该对象已经没有被引用,可以被回收;
    需要注意的是,引用计数法其实是很难解决对象之间相互循环引用的问题,所以Java虚拟机没有选用此方法来管理内存。

  • 可达性分析法从一组被称为“GC Roots”的对象开始,向下搜索,如果一个对象没有任何引用链相连(即无法从GC Roots到达该对象),则说明该对象是不可达的,可以被回收
    GC Roots包括:虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象等。
    需要知道实际上可达性分析法在JVM的应用中,宣告一个对象真正死亡,会存在两次标记过程:

    • 第一次标记: 如果对象在进行可达性分析后发现没有 GCRoots 相连接的引用链,那么它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。
      当对象未覆写finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机会将这两种情况都视为没有必要执行。如果对象被判定为有必要执行,则会被放到一个F-Queue队列;
    • 第二次标记:finalize()方法是对象跳脱死亡命运的最后一次机会,稍后GC将对F-Queue中对象进行第二次小规模标记,如果对象要在finalize()中重新拯救自己:只要重新与引用链上的任何一个对象建立关联即可,例如将自己(this关键字)赋值给某个类变量或者对象的成员变量,那在第二次标记时它将被移出即将回收的对象集合。

所以说,Java中的垃圾回收机制会采用可达性分析法,自动判断对象是否可以被回收,开发者无需手动判断。


4️⃣ 说一下 JVM 的垃圾回收器都有哪些?有什么区别?

【Java面试题】第八期:Java进阶篇,每周10道,根本停不下来~,# Java EE (Java高级特性),面试,java-ee,jvm,java,开发语言

可以按照垃圾分代将GC分为以下几类垃圾收集器:

  • 新生代收集器: Serial、 ParNew、Parallel Scavenge;
  • 老年代收集器: Serial Old、 Parallel Old、 CMS;
  • 整堆收集器: G1。

各种收集器都有其适用的场景和特点:

  • Serial GC: 最基本也是最古老的收集器,它是单线程的,在收集垃圾时会暂停应用程序;

  • Serial Old GC:Serial GC的升级版,主要用于管理老年代内存,采用的是标记-整理算法,实现简单,能有效解决内存碎片问题。但由于采用的“stop the world”方式进行垃圾回收,因此会导致应用程序的停顿时间较长;

  • Parallel Scavenge GC: 也是一种单线程的收集器,与Serial收集器相比,它可以利用多CPU来并行处理垃圾回收;

  • Parallel Old GC:是Parallel Scavenge GC的补充,它主要是为了解决老年代的垃圾回收问题。Parallel Old GC采用了标记-整理算法;

  • ParNew GC:是一种基于并行垃圾回收算法的,主要用于新生代的垃圾回收器。使用多个线程并行地进行垃圾回收,以达到快速回收内存、提高应用程序的吞吐量的目的;

  • CMS GC: 一种以低延迟为目标的,主要用于老年代的收集器,它采用了一种称为“标记-清除”的算法,能够在尽可能短的时间内完成垃圾回收;

  • G1 GC: 一种基于分代收集算法的,以低延迟和高吞吐量为目标的收集器,它能够在不牺牲太多吞吐量的情况下,取得与CMS收集器相当的低延迟;

  • Shenandoah GC: 是一种以极低延迟和高吞吐量为目标的收集器,它采用了一种称为“读写屏障”的技术,可以在不暂停应用程序的情况下完成垃圾回收。

在JDK8中,Parallel收集器是默认的垃圾收集器。它采用多线程进行垃圾收集,可以在多核CPU上更好地发挥优势,具有高效、稳定的特点。此外,CMS收集器和G1收集器也比较常用,它们具有更好的响应时间和更小的停顿时间,适用于对响应时间和吞吐量都有较高要求的场景。
不同的垃圾收集器适用于不同的场景,需要根据具体情况进行选择。

在JDK中,可以通过命令行参数或JVM参数来配置垃圾收集器。以下是一些常用的相关参数:

  • -XX:+UseSerialGC:使用Serial收集器,适用于单核CPU或小内存的场景;
  • -XX:+UseParallelGC:使用Parallel收集器,适用于多核CPU或需要高吞吐量的场景;
  • -XX:+UseConcMarkSweepGC:使用CMS收集器,适用于需要短停顿时间和高响应时间的场景;
  • -XX:+UseG1GC:使用G1收集器,适用于大内存和需要高吞吐量的场景;
  • -XX:ParallelGCThreads:设置Parallel收集器的线程数。

需要注意的是,过于频繁的Full GC可能会影响应用程序的性能和稳定性,需要根据具体情况进行设置和调整。同时,不同的垃圾收集器可能支持的参数不同,需要查阅相关文档进行了解。


5️⃣ 说一下 JVM 有哪些垃圾回收算法?

JVM中有多种垃圾回收算法,主要分为以下几种:

  • 标记-清除算法(Mark and Sweep):
    最基本的垃圾回收算法,它分为两个阶段:标记和清除。标记阶段会遍历所有的对象,标记出所有需要回收的对象,然后在清除阶段将这些对象回收。但是,这种算法存在着内存碎片的问题;

  • 复制算法(Copy):
    复制算法将内存分为两个区域,每次只使用其中一个区域,当这个区域被使用完后,将其中存活的对象复制到另一块区域中,并进行清理。这种算法的缺点是需要至少两倍的内存空间;

  • 标记-整理算法(Mark and Compact):
    标记-整理算法综合了标记-清除算法和复制算法的优点,它也分为两个阶段:标记和整理。标记阶段和标记-清除算法相同,但在整理阶段,该算法会将所有存活的对象整理到内存的一端,然后清理掉边界以外的所有对象。这种算法可以避免内存碎片的问题;

  • 分代算法(Generational):
    分代算法是目前主流的垃圾回收算法,它根据对象的存活时间将内存分为多个代(Young Gen和 Old Gen)。Young Gen是存放新生对象的区域,使用复制算法;Old Gen是存放存活时间较长的对象的区域,使用标记-整理算法。这种算法通过不同的垃圾回收算法,针对不同代的对象进行回收,提高了垃圾回收的效率。


6️⃣ 详细介绍一下 CMS 垃圾回收器?

【Java面试题】第八期:Java进阶篇,每周10道,根本停不下来~,# Java EE (Java高级特性),面试,java-ee,jvm,java,开发语言

CMS(Concurrent Mark Sweep)是一种 并发的垃圾回收器,它是在 JDK 1.5 中引入的,主要关注点是减少 Full GC 时 用户线程的停顿时间

CMS 的工作分为以下四个阶段:

  • 初始标记(Initial Mark):首先,停止应用程序的所有线程,然后标记所有与 GC Root 直接关联的对象,并记录下这些对象的信息;
  • 并发标记(Concurrent Mark):在初始标记阶段之后,CMS 开始对堆内存进行并发标记,即标记所有与 GC Root 间接关联的对象。在此期间,应用程序的线程可以继续运行,不需要停顿;
  • 重新标记(Remark):并发标记过程中,由于应用程序的线程仍在运行,可能会产生新的对象被引用,因此需要重新标记一次,以标记所有遗漏的对象;
  • 并发清除(Concurrent Sweep):在重新标记完成后,开始并发地清除所有未被标记的对象,释放内存空间。

需要注意的是,CMS 垃圾回收器有一定的缺点:

  • CMS 只能处理老年代的垃圾回收,不能处理年轻代的垃圾回收,因此需要和其他垃圾回收器(如 ParNew)配合使用;
  • 并发执行垃圾回收时,会消耗一定的 CPU 资源,可能会对应用程序的性能产生影响;
  • 使用了“标记-清除”算法,可能会产生内存碎片,进而导致 Full GC 的频繁发生,影响应用程序的性能。

因此,在使用 CMS 垃圾回收器时,需要根据应用程序的实际情况进行调优,以达到最佳的性能表现。


7️⃣ 什么是STW?

STW是指Stop-The-World,是Java虚拟机进行垃圾回收时,需要暂停所有应用线程的一种策略

在进行垃圾回收时,虚拟机需要遍历所有的对象来判断哪些对象可以回收,而应用线程如果同时在运行,就会不断地创建新的对象,导致垃圾回收的效果不佳。因此,采用STW策略可以暂停应用线程,使得虚拟机可以更高效地进行垃圾回收。

同时,因其需要暂停所有应用线程的特点,如何减少STW也成为了GC算法优化的重点,也是JVM调优的重点。


8️⃣ 简述分代垃圾回收器是如何工作的?

分代垃圾回收器是一种基于对象生命周期进行管理的垃圾回收器,它将堆内存划分为不同的代(Generation),每个代按照对象的年龄分为不同区域,一般分为新生代(Young Gen)和老年代(Old Gen)。

  • 新生代新生代是存放新创建的对象的区域,使用复制算法。 一般占用堆内存的较小比例,其中又分为 Eden 区、To Survivor区(S0)、From Survivor 区(S1)三个部分,它们的默认大小占比是 8:1:1。

    • 新创建的对象会被放入 Eden 区,当 Eden 区满时,会触发 Minor GC,执行了第一次GC,将存活的对象复制到 其中一个Survivor 区;
    • 在后续的每一次 Minor GC中,若对象仍然存活,就会在两个Survivor 区之间来回拷贝,每拷贝一次年龄加1;
    • 在对象年龄达到15时,再发生下一次GC时若对象仍然存活,则将其拷贝到老年代,最后清空 Eden 和 Survivor 区。
  • 老年代老年代是存放存活时间较长的对象的区域,使用标记-整理或标记-清除算法,一般占用堆内存的较大比例。

    • 当 Eden 区和 Survivor 区中的对象经过多次垃圾回收后仍然存活,则会被晋升到老年代。当老年代空间不足时,会触发 Full GC,被标记为垃圾对象会被清理掉。

分代垃圾回收器的优点在于:不同代的对象具有不同的生命周期,可以针对性地采用不同的垃圾回收算法,从而提高垃圾回收的效率。同时,由于新生代的对象生命周期较短,因此回收的频率也较高,可以尽快地回收不再使用的对象,避免内存泄漏和内存碎片的问题。


9️⃣ 说一下 JVM 调优的工具?

JVM调优的工具主要分为以下几类:

  • 监控工具:监控JVM的运行情况,如JMX、VisualVM等;

    • JMX:JVM自带的监控工具,可以查看JVM的内存使用情况、线程状态、类加载情况等信息;
    • VisualVM:一款免费的Java应用程序性能分析工具,可以通过插件方式支持多种JVM,包括JRockit、IBM JDK、OpenJDK等。VisualVM可以监控应用程序的CPU、内存、线程、GC等情况,同时还提供了堆内存分析、线程分析和CPU分析等功能;
  • 垃圾回收器:垃圾回收工具主要是提供不同的垃圾回收算法对垃圾回收过程进行优化,如G1、CMS等;

    • 各种垃圾收集器详细情况请查看上文第四题、第六题…
  • 堆内存工具:分析应用程序的内存使用情况,如JConsole、Java Mission Control等;

    • JConsole:监控堆内存使用情况、线程状态、类加载情况等信息;
    • Java Mission Control:进行更加深入的堆内存分析,包括对象分配、对象生命周期、对象引用关系等;
    • jstack:JDK 自带的一个命令行工具,可以用来生成线程堆栈转储信息。生成 dump.txt 文件可用来分析线程状态和调用栈;
    • jmap:JDK 自带的另一个命令行工具,可以用来生成堆转储信息。生成 dump.bin 文件可辅助分析内存使用情况和查找内存泄漏;
  • 代码分析工具:分析应用程序的代码性能,如JProfiler、YourKit等;

    • JProfiler:方法级别的性能分析、内存分析等;
    • YourKit:CPU分析、内存分析、线程分析等。

这些工具可以帮助开发人员快速定位应用程序的性能问题,并进行优化。


🔟 常用的 JVM 调优的参数都有哪些?

JVM 的参数可以分为以下几类:

  • 标准参数(-开头的参数):这些参数是所有 JVM 实现都必须支持的参数,如 -version、-help 等。可以用 java -help 打印出来;

  • 非标准参数(-X开头的参数):这些参数是各个 JVM 实现自己定义的参数,可能不同的 JVM 实现支持不同的参数,如 -Xmx、-Xms 等。可以用 java -X 打印出来;

  • 高级运行时参数(-XX开头的参数):这些参数是一些高级运行时参数,用于对 JVM 内部的各个模块进行调优,如 GC 收集器、JIT 编译器等。这些参数不是所有 JVM 实现都支持的,也可能因 JVM 实现版本的不同而有所差异;

  • 隐式参数:这些参数是 JVM 内部自动设置的参数,不需要用户手动设置,如 -Xms 和 -Xmx 之间的关系、自适应调节参数等。

常用的 JVM 调优参数如下:

  • -Xss:设置 线程栈的大小。默认值取决于平台,一般为512KB或1024KB;

  • -Xmx:设置 最大堆内存大小,如“-Xmx 1024m”表示将最大堆内存设置为1024MB。当应用程序需要更多的内存时,可以通过增加-Xmx参数来扩大堆内存的容量;

  • -Xms:设置 初始堆内存大小,如“-Xms 512m”表示将初始堆内存设置为512MB。初始堆内存大小的设置可以影响应用程序的启动速度和性能;

  • -XX:NewSize:设置新生代的初始大小

  • -XX:MaxNewSize:设置新生代的最大大小

  • -XX:NewRatio:设置新生代与老年代的比例,默认为 2,表示新生代占整个堆内存的 1/3;

  • -XX:SurvivorRatio:设置Eden区与Survivor区的比例,默认为 8,表示 Eden 区占新生代内存的 8/10;

  • -XX:+UseAdaptiveSizePolicy:开启自适应的堆大小调整策略

  • -XX:MaxPermSize:用于JDK8之前的版本设置永久代(Permanent Generation)的最大大小;

  • -XX:MaxMetaspaceSize:用于Java 8及以后的版本控制元空间(Metaspace)的大小;

  • -XX:MaxDirectMemorySize:设置直接内存的大小;

  • -XX:+UseSerialGC:使用Serial收集器,适用于单核CPU或小内存的场景;

  • -XX:+UseParallelGC:使用Parallel收集器,适用于多核CPU或需要高吞吐量的场景;

  • -XX:+UseConcMarkSweepGC:使用CMS收集器,适用于需要短停顿时间和高响应时间的场景;

  • -XX:+UseG1GC:使用G1收集器,适用于大内存和需要高吞吐量的场景;

  • -XX:ParallelGCThreads:设置Parallel收集器的线程数;

  • -XX:MaxHeapFreeRatio:设置空余堆内存占堆内存的最大比例,当空余堆内存超过该比例时,会触发Full GC;

  • -XX:MinHeapFreeRatio:设置空余堆内存占堆内存的最小比例,当空余堆内存低于该比例时,也会触发Full GC;

  • -XX:+HeapDumpOnOutOfMemoryError:当内存溢出时,生成堆内存转储文件;

  • -XX:+PrintGCDetails:打印 GC 详细信息;

  • -XX:+PrintGC:打印 GC 信息。


图片来源:
引用计数法和可达性算法
垃圾回收③—垃圾回收器

【Java面试题】第八期:Java进阶篇,每周10道,根本停不下来~,# Java EE (Java高级特性),面试,java-ee,jvm,java,开发语言文章来源地址https://www.toymoban.com/news/detail-540968.html

到了这里,关于【Java面试题】第八期:Java进阶篇,每周10道,根本停不下来~的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CTF 入门指南:从零开始学习网络安全竞赛(第八期)

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 CTF比赛是快速提升网络安全实战技能的重要途径,已成为各个行业选拔网络安全人才的通用方法。但是,本书作者在从事CTF培训的过程中,发现存在几个突出的问题:

    2024年02月07日
    浏览(31)
  • 分布式websocket即时通信(IM)系统保证消息可靠性【第八期】

    b站上面本期视频版本,观看视频食用更佳!点击即可跳转,找不到视频可以直接搜索我 目前叫 呆呆呆呆梦 目前已经写的文章有。并且有对应视频版本。 git项目地址 【IM即时通信系统(企聊聊)】点击可跳转 sprinboot单体项目升级成springcloud项目 【第一期】 前端项目技术选型

    2024年01月22日
    浏览(47)
  • 【AI视野·今日Sound 声学论文速览 第八期】Wed, 20 Sep 2023

    AI视野 ·今日CS.Sound 声学论文速览 Wed, 20 Sep 2023 Totally 1 papers 👉 上期速览 ✈更多精彩请移步主页 Accelerating Diffusion-Based Text-to-Audio Generation with Consistency Distillation Authors Yatong Bai, Trung Dang, Dung Tran, Kazuhito Koishida, Somayeh Sojoudi 扩散模型为绝大多数文本到音频 TTA 生成方法提供支持。

    2024年02月08日
    浏览(23)
  • 【送书福利-第八期】《硅基物语.AI大爆炸: ChatGPT→AIGC→GPT-X→AGI进化→魔法时代→人类未来》

    大家好,我是洲洲,欢迎关注,一个爱听周杰伦的程序员。关注公众号【程序员洲洲】即可获得10G学习资料、面试笔记、大厂独家学习体系路线等…还可以加入技术交流群欢迎大家在CSDN后台私信我! 一个AI者的自白:我是一个AI,我的思维如同光速般迅猛,我的逻辑如同天文

    2024年02月08日
    浏览(29)
  • 【山河送书第八期】:《用ChatGPT轻松玩转机器学习与深度学习》突破传统学习束缚,借助ChatGPT的神奇力量,解锁AI无限可能!

    随着科技的飞速发展,人工智能已经成为了当今社会最热门的话题之一。从自动驾驶汽车到智能家居,再到医疗诊断和金融投资等领域,人工智能的应用已经渗透到我们生活的方方面面。在这个过程中,机器学习和深度学习作为人工智能的核心技术,扮演着至关重要的角色。

    2024年02月11日
    浏览(28)
  • 2023年Java核心技术面试第八篇(篇篇万字精讲)

    目录 十五 . 面向对象的基本要素:封装,继承,多态  15.1 封装: 15.1.1 例子: 15.2 继承 15.2.1 例子 15.3 多态 15.3.1 例子 15.3.2 小结:谈谈多态的继承的联系 十六 . synchronized 和 ReentrantLock 的区别? 16.1 典型回答 16.2 深入理解底层锁的概念 16.2.1 synchronized 16.2.2 ReentrantLock 16.2.2.1

    2024年02月11日
    浏览(27)
  • 面试京东失败,再看看2年前的面试题,根本不是一个难度···

    刚从京东走出来,被二面难到了,我记得学长两年前去面试的时候,问的问题都特别简单,咋现在难度高了这么多。面试前我也刷过很多的题和看过很多资料,后来想想,这年头网上资料泛滥,测试面试文档更是层出不穷,但很难分辨那种资料有用。   答案显然是不够的!那

    2024年02月04日
    浏览(43)
  • 面试京东失败,再看看两年前的面试题,根本不是一个难度

    刚从京东走出来,被二面难到了,我记得学长两年前去面试的时候,问的问题都特别简单,咋现在难度高了这么多。面试前我也刷过很多的题和看过很多资料,后来想想,这年头网上软件测试资料泛滥,软件测试 面试文档更是层出不穷,但很难分辨那种资料有用。  答案显然

    2023年04月23日
    浏览(30)
  • 面试宝典进阶之Java线程面试题

    (1)线程是CPU调度的最小单位,进程是计算分配资源的最小单位。 (2)一个进程至少要有一个线程。 (3)进程之间的内存是隔离的,而同一个进程中的线程之间是共享内存的。 T2、【初级】线程的创建有哪几种方式? (1)继承Thread类,重写run方法。 (2)实现Runnable接口

    2024年02月02日
    浏览(37)
  • 我嘞个神——原来创建应用根本不需要会编码(看我10分钟应用上线)

    目录 一、前言 二、官网功能查询与环境初始化 YonBuilder应用开发 三、测试过程 3.1、创建应用 3.2、数据建模 3.3、页面建模 3.4、页面发布 四、时间累计 五、效率评价 六、总结 这里我用到了用友的平台,很多学生们刚毕业都在从事运维和实施的岗位,而且这个平台在我这面也

    2024年02月03日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包