2023最新面试题-Java-7

1. 说说自定义注解的场景及实现;

利用自定义注解 , 结合 SpringAOP 可以完成权限控制、日志记录、统一异常处理、数字签名、数 据加解密
等功能。
实现场景( API 接口数据加解密)
1 )自定义一个注解,在需要加解密的方法上添加该注解
2 )配置 SringAOP 环绕通知
3 )截获方法入参并进行解密
4 )截获方法返回值并进行加密

 

2. 说一下JVM堆栈的区别?

 物理地址

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

内存分别

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

存放的内容

堆存放的是对象的实例和数组。因此该区更关注的是数据的存储
栈存放:局部变量,操作数栈,返回结果。该区更关注的是程序方法的执行。
PS
1. 静态变量放在方法区
2. 静态的对象还是放在堆。
程序的可见度
堆对于整个应用程序都是共享、可见的。
栈只对于线程是可见的。所以也是线程私有。他的生命周期和线程相同。

3. 描述一下JVM加载Class文件的原理机制

Java 中的所有类,都需要由类加载器装载到 JVM 中才能运行。类加载器本身也 是一个类,而它的工作就 是把class 文件从硬盘读取到内存中。在写程序的时 候,我们几乎不需要关心类的加载,因为这些都是隐 式装载的,除非我们有特殊 的用法,像是反射,就需要显式的加载所需要的类。

 类装载方式,有两种 :

1. 隐式装载, 程序在运行过程中当碰到通过 new 等方式生成对象时,隐式调用 类装载器加载对应的类到 jvm中,
2. 显式装载, 通过 class.forname() 等方法,显式加载需要的类
Java 类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是保证 程序运行的基础类 ( 像是 基类) 完全加载到 jvm 中,至于其他类,则在需要的时候 才加载。这当然就是为了节省内存开销。

4. 说一下 JVM 调优的工具?

JDK 自带了很多监控工具,都位于 JDK bin 目录下,其中最常用的是 jconsole jvisualvm 这两款视 图监控工具。
jconsole :用于对 JVM 中的内存、线程和类等进行监控;
jvisualvm JDK 自带的全能分析工具,可以分析:内存快照、线程快照、程序 死锁、监控内存的
变化、 gc 变化等。
线上arthes

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

-Xms2g :初始化推大小为 2g
-Xmx2g :堆最大内存为 2g
-XX:NewRatio=4 :设置年轻的和老年代的内存比例为 1:4 -XX:SurvivorRatio=8 :设置新生代
Eden Survivor 比例为 8:2 –XX:+UseParNewGC :指定使用 ParNew + Serial Old 垃圾回收器
组合; -XX:+UseParallelOldGC :指定使用 ParNew + ParNew Old 垃圾回收器组 合;
-XX:+UseConcMarkSweepGC :指定使用 CMS + Serial Old 垃圾回收器组 合;
-XX:+PrintGC :开启打印 gc 信息;
-XX:+PrintGCDetails :打印 gc 详细信息。

6.程序算法调优

一切都是为了这一步,调优,在调优之前,我们需要记住下面的原则:
1 、多数的 Java 应用不需要在服务器上进行 GC 优化;
2 、多数导致 GC 问题的 Java 应用,都不是因为我们参数设置错误,而是代码问题;
3 、在应用上线之前,先考虑将机器的 JVM 参数设置到最优(最适合);
4 、减少创建对象的数量;
5 、减少使用全局变量和大对象;
6 GC 优化是到最后不得已才采用的手段;
7 、在实际使用中,分析 GC 情况优化代码比优化 GC 参数要多得多;

GC优化的目的有两个

1 、将转移到老年代的对象数量降低到最小;
2 、减少 full GC 的执行时间;
为了达到上面的目的,一般地,你需要做的事情有:
1 、减少使用全局变量和大对象;
2 、调整新生代的大小到最合适;
3 、设置老年代的大小为最合适;
4 、选择合适的 GC 收集器;

分析结果,判断是否需要优化

如果各项参数设置合理,系统没有超时日志出现, GC 频率不高, GC 耗时不高,那么没有必要进行 GC 优 化;如果GC 时间超过 1-3 秒,或者频繁 GC ,则必须优化;

7. 如果满足下面的指标,则一般不需要进行GC

Minor GC 执行时间不到 50ms
Minor GC 执行不频繁,约 10 秒一次;
Full GC 执行时间不到 1s
Full GC 执行频率不算频繁,不低于 10 分钟 1 次;

8.JVM调优常用参数配置

-Xms: 初始堆大小
-Xms :最大堆大小
-XX:NewSize=n: 设置年轻代大小
-XX:NewRatio=n: 设置年轻代和年老代的比值。如:为 3 表示年轻代和年老代比值为 1 3 ,年轻代占整个年
轻代年老代和的 1/4
-XX:SurvivorRatio=n: 年轻代中 Eden 区与两个 Survivor 区的比值。注意 Survivor 区有两个。如 3 表示
Eden 3 Survivor 2 ,一个 Survivor 区占整个年轻代的 1/5
-XX:MaxPermSize=n: 设置持久代大小

 

说明:
1 、一般初始堆和最大堆设置一样,因为:现在内存不是什么稀缺的资源,但是如果不一样,从初
始堆到最大堆的过程会有一定的性能开销,所以一般设置为初始堆和最大堆一样。 64 位系统理论
上可以设置为无限大,但是一般设置为 4G , 因为如果再大, JVM 进行垃圾回收出现的暂停时间会比
较长,这样全 GC 过长,影响 JVM 对外提供服务,所以不能太大。一般设置为 4G
2 -XX:NewRaio -XX:SurvivorRatio 这两个参数,都是设置年轻代和年老代的大小的,设置一个
即可,第一是设置年轻代的大小,第二个是设置比值,理论上设置一个既可以满足需求

 

9. 回收器的选择

JVM 给了三种选择:串行收集器,并行收集器,并发收集器,但是串行收集器只适用于小数据量的情 况,一般不考虑使用了,所以这里只针对并行收集器和并发收集器。默认情况下,JDK5.0 以前是使用的 串行收集器,如果想使用其他收集器需要在启动时加入相应的参数,JDK5.0 以后, JVM 会根据系统当前 的配置进行判断
吞吐量优先的并行收集器
并行收集器主要以到达一定的吞吐量为目标,适用于后台处理
java -Xmx3550m-Xms3550m-Xss128k-XX:+UseParallelGC
-XX:ParallelGCThreads=20
-XX:+UseParallelGC:选择垃圾收集器为并行收集器。次配置仅对年轻代有效。即上述配置下,年轻代使用
并行收集,而年老代仍旧使用串行收集。
-XX:PARALLELgcThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最
好配置与处理器数目相同。
-XX:+UseParallelOldGC:配置年老代来及收集方式为并行收集,JDK6.0支持对年老代并行收集
-XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调
整年轻代大小,以满足此值
-XX:+UseAdaptiveSizePolicy:设置此选项以后,并行收集器会自动选择年轻代区大小和相应的
Survivor区比例,以达到目标系统规定的最低响应时间或者收集频率等,此值建议使用并行收集器时,一直
打开
响应时间优先的并发收集器
并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域 等.
-XX:CMSFullGCsBeforeCompaction=5
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction:由于并发收集器不对内存空间进行压缩、整理、所以运行一段时间以
后会产生“碎片”,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理
-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,但是可以消除碎片

你可能感兴趣的:(2023最新面试题整理,java)