Java面经(2)

1、JVM加载流程:

1. 解析命令行参数:解析用户启动JVM时传入的参数,配置运行时环境。-classpath:指定类搜索路径。-Xmx/-Xms:设置堆内存最大/初始大小。-XX:+UseG1GC:指定垃圾回收器类型。

2. 创建Bootstrap ClassLoader:引导类加载器是 JVM 的内置加载器,负责加载 Java 核心类库。

3. 加载核心类:引导类加载器首先加载 JVM 运行所需的基础类,如java.lang.Objectjava.lang.ClassLoader等,这些类构成了 JVM 的运行基础。

4. 初始化运行时组件和内存区域:

内存区域划分:堆:对象实例存储区域(分新生代、老年代);方法区:类元数据、常量池等(JDK8后取代永久代);虚拟机栈:线程私有的方法调用栈帧;本地方法栈:Native方法调用栈;程序计数器:记录当前线程执行位置。

运行时组件初始化:垃圾回收器:根据参数初始化对应的GC实现(如G1、CMS)。即时编译器(JIT):初始化解释器和编译器(如C1、C2)。字节码执行引擎:负责解释或编译执行字节码。

5. 创建主线程与守护线程:主线程:由JVM自动创建,负责执行用户程序的main()方法。线程栈中压入main()方法的栈帧。

守护线程:后台服务线程(如GC线程、信号处理线程)。当所有非守护线程结束时,JVM自动退出。

6. 类加载验证(执行类加载过程):在执行main方法前,JVM 需要加载并初始化包含main方法的类

7. 压入main方法栈帧:类加载完成后,JVM 通过主线程调用main方法(public static void main(String[] args)),程序开始运行。然后在虚拟机栈中为main方法创建栈帧,执行字节码指令。

8. 运行时:JIT优化------将热点代码编译为本地机器码,提升执行效率。

9. 关闭阶段:JVM 退出的常见场景包括:正常退出main方法执行完毕,或调用System.exit(0)异常退出:程序抛出未捕获的异常,或调用System.exit(非0)。强制终止:通过操作系统命令(如 kill 进程)终止 JVM 进程。

退出时,JVM 会执行以下操作:

执行所有已注册的shutdown hook(通过Runtime.addShutdownHook()注册的线程)。释放资源(如文件句柄、网络连接)。关闭 JVM 进程。

2、classloader有两个参数是啥:

应该指的是classloader的核心方法protected Class<?> loadClass(String name, boolean resolve)。分别是要加载的类的全限定名和一个标志参数用来指定是否需要解析

3、如何打破双亲委派:

1. 自定义类加载器并重写 loadClass() 方法:默认的 loadClass() 方法实现了双亲委派逻辑,若要打破该逻辑,需重写该方法,直接调用 findClass() 进行类加载,而不先委派给父类加载器。

2. 使用线程上下文类加载器(Thread Context ClassLoader):允许子模块(如 SPI 接口的实现类)通过当前线程的类加载器加载,而非父类加载器。

4、什么场景需要打破双亲委派?

1. 实现模块化或类隔离:在一个应用中需要加载同名但不同版本的类,或者不同模块需要隔离依赖库(避免类冲突)。典型的例子是Web容器(如Tomcat),每个Web应用可能需要独立的类加载环境。Tomcat为每个Web应用使用独立的WebAppClassLoader,优先加载自身路径下的类,若找不到再委派给父类加载器(打破了默认的“先父后子”顺序)

2. 热部署或热加载:在应用不重启的情况下,动态替换或重新加载类(如开发调试、线上热修复)。双亲委派模型中,类一旦被加载,除非重新创建类加载器,否则无法重新加载。为每个模块或需要热加载的组件创建独立的类加载器,直接加载类而不委派父类加载器。

5、cs 两个操作怎么保证原子性?

在 Java 中,CAS 通过 Unsafe 类中的 native 方法实现,这些方法调用底层的硬件指令来完成原子操作。由于其实现依赖于 C++ 内联汇编和 JNI 调用,因此 CAS 的具体实现与操作系统以及 CPU 密切相关。

6、execute和submit的区别

接口归属

Executor接口

ExecutorService接口(继承自Executor

任务类型

仅支持Runnable

支持RunnableCallable

返回值

void(无法获取结果)

Future对象(可获取异步结果)

异常处理

任务内部异常需自行捕获,否则静默失败

异常会被封装在Future中,调用get()时抛出

全部评论

相关推荐

05-22 15:55
门头沟学院 C++
ResourceUtilization:应该配文,扫描二维码加速offer发放速度
点赞 评论 收藏
分享
暑期实习面试差不多结束了,整理一下面经准备秋招,好多都是之前整理好的,当时八股没背完,回答错的比较多📍面试公司:美团💻面试岗位:后端开发❓面试问题:上来一道选择题,选择擅长的语言(C++、JAVA、Go),果断选择C++后面6道专业技术题,每题有3次换题机会,然后3道通用面试题?1.TCP断点重传机制(一开始看到的时候傻了,愣了一下换题按钮没点到,不太确定断点有没有区别?硬着头皮答了超时重传、快速重传、RTO、RTT和SACK、DSACK)2.Linux&nbsp;移动大量文件,如何保证权限不变(cp&nbsp;-p,有子文件夹的话使用&nbsp;rsync-&nbsp;a)3.如何确认mysql索引被使用(使用explain&nbsp;key列显示的索引名,none是没使用索引,all是全文索引。发现show&nbsp;index忘记说了。。。)4.C++中static变量在哪个阶段被创建(静态初始化是编译放在bss,动态初始化在函数调用时。不知道记没记错)5.C++中new和malloc的区别(经典C++八股)6.设计一个系统,如何快速获取用户的关注列表和粉丝列表(应该换题的,但是感觉其他的也不一定会,就硬着头皮答了。使用哈希表建立用户id和粉丝/关注列表的映射,可以实现O(1)查询,使用redis缓存,关注/粉丝大的,可以写入mysql)(当时思路有点乱,应该是答错了)ai追问:使用redis缓存的时候,如何保证数据库一致性(单机:使用事务;分布式:先写数据库,再写缓存,采用双写机制,采取补偿机制,根据日志查找问题修改)通用面试题:1.你接触一个新的领域,如何去学习的?具体示例。(讲了一下学习计算机)ai追问:在学习计算机这个领域时,当你遇到特别棘手问题或者瓶颈时,你是如何调整学习策略或心态?具体例子(讲了一下在实验室打比赛的问题,算法、数据结构比较难)ai追问:在这个过程中你遇到一个特别难以理解的算法或者概念时,你是如何判断自己是否真正掌握了?能具体描述一下验证的具体步骤或方法吗?(写博客,练习,尝试变种题型)2.描述一个你在压力下快速解决问题的情况,你采取了哪些步骤?结果如何?(描述了软件验收测试,存在bug)ai追问:在这个过程中,你是如何评估和决定优先处理哪些步骤的?你觉得哪些因素对你当时的决策产生了重要的影响?ai追问:在高压与情况紧急的情况下,你是如何确保团队的高效沟通与协作的?3.你未来三年的职业规划🙌面试感想:面了半小时,第一次面试有点太紧张了
查看14道真题和解析 面试问题记录
点赞 评论 收藏
分享
评论
点赞
2
分享

创作者周榜

更多
牛客网
牛客企业服务