《面试1v1》类加载过程

news2025/1/11 16:43:39

我是 javapub,一名 Markdown 程序员从👨‍💻,八股文种子选手。

面试官: 你了解Java的类加载过程吗?跟我聊聊classes是如何加载到JVM中的。

候选人: Java的类加载过程由加载、验证、准备、解析和初始化5个阶段组成。当我们使用java命令执行一个类时,JVM会首先搜索类的加载路径,这包括Bootstrap Classpath、Extension Classpath和Application Classpath。

面试官: 哈哈,这也太官方了吧,来,我们以更口语的方式探讨下类加载过程。想象你是一名新手Java程序员,刚入职一个公司,被分配一个任务需要执行一个Java类,你会有什么疑惑或者过程?

候选人: 好的,那我来思考下当初我第一次运行Java程序的时候的内心活动:
天啊,我首先得搞清楚要运行的这个类到底在哪儿?难道要我一个个文件翻找吗?那还不如让我直接读JVM的源码来找呢!
Wait,原来JVM已经把这事儿都帮我干了,它会去找 classpath 下的文件,包括环境变量里设置的那堆classpath。这肯定是个苦力活,幸好有JVM这个工具哥帮忙!
找到类文件了,接下来JVM该干嘛?嗯,它得确定这个类里写的是否都是正确的Java语法,不会误导小菜鸟我。它会进行类文件的验证,确保我的Java程序没有安全隐患!
验证通过了,JVM该准备干啥?它需要为类中的静态变量分配内存并设置默认初始值,这个过程就是准备阶段。
静态变量有内存了,JVM还需要干什么?嗯,它得解析类文件里的符号引用,像是类名、方法名、变量名等,把这些符号转成直接引用,方便后续调用。这就是解析阶段。
最后,JVM要真正帮我干活了,它要执行类构造器()方法的字节码,给静态变量复杂的初始值。这就是初始化阶段。
Initialization of 类名 complete! 我的任务终于可以开始执行了!真不容易,还得感谢JVM这位大恩人。

面试官: 哈哈,这个解释我喜欢!inclusion of源代码和动态的思考过程增加了解释的轻松和趣味性。你这种围绕一个场景作解释的方式很形象,让人容易理解,这在技术面试中是很重要的一点。

候选人: 谢谢面试官的夸奖!我也觉得把一个复杂的技术问题变成一个故事或场景会让人更容易理解其中的逻辑和流程。这也是我在博客和公众号里常用的一种讲解方式,很高兴面试官能够欣赏!

面试官: 那我们继续聊聊类加载过程中最重要的几个类吧,什么类负责 finding 和loading 操作?

候选人: 在类加载过程中,ClassLoader 类及其子类负责finding和loading操作。

面试官: 是的,ClassLoader是一个很重要的类。那么默认的ClassLoader又有哪几个?

候选人: 默认有3个ClassLoader:

  1. Bootstrap ClassLoader 启动类加载器:负责加载JDK内置的类,如rt.jar等。
  2. Extension ClassLoader 扩展类加载器:负责加载JDK扩展目录中的jar包、以及VM指定的其他jar包。
  3. App ClassLoader 应用程序类加载器:负责加载用户自定义的类。
//JDK源码中ClassLoader的继承关系
public class ClassLoader {
    public ClassLoader() {} 
    public Class<?> loadClass(String name) {...}
}
public class SecureClassLoader extends ClassLoader {...} 
public class URLClassLoader extends SecureClassLoader {...} 
//和类加载息息相关的其他类 
public final class Class<T> {...}  
public class ClassNotFoundException extends Exception {...}

面试官: ClassLoader的加载顺序遵循什么规则?

候选人: ClassLoader遵循父类委派模式,当一个类加载器收到类加载请求时,它会把这个请求委派给它的父类加载器去完成,依此形成一个链条。只有父类加载器在它的搜索范围内无法找到所需的类时,子加载器才会尝试自己去加载这个类。
因此,类加载的顺序为:

  1. Bootstrap ClassLoader
  2. Extension ClassLoader
  3. App ClassLoader
    如果父类可以完成类加载工作则子类不会再去加载,否则子类才会负责加载。这种委派机制可以避免重复加载,也有利于安全性。

面试官: 很好,你对Java类加载机制有很深入的理解。最后,我们聊一聊类加载过程的双亲委派模型在哪些方面带来的好处?

候选人: 类加载双亲委派模型带来的好处主要有两点:

  1. 避免重复加载:当父类已经加载了某个类时,子类不会再重复加载该类,从而避免资源消耗。
  2. 安全性:父类加载的类被所有的子类所信任。 strs如果子类可以随意加载,那么就可能加载一个非授权版本的类,破坏安全性。
    综上,双亲委派模型体现了“安全第一,不重复加载”的设计思想,这两点好处使得Java类加载机制更加完备和安全。

面试官: 很好,你的回答很全面和到位。

候选人: 非常感谢面试官的指导。

面试官: 你的谢意我心领了,我们的对话也达到了我的目的。真诚地希望这些知识能在你的工作中派上用场。加油!

候选人: 非常感谢面试官的鼓励!我会努力运用所学的知识,在工作实践中不断进步。也祝面试官心想事成

面试官: 好,让我们继续讨论类加载过程中另一个重要概念:类的生命周期。什么是类的生命周期?它包括哪几个阶段?

候选人: 类的生命周期描述了一个类从被加载到被卸载的整个过程。它主要包括:

  1. 加载:找寻并加载类的二进制数据,将其读入内存,并为之创建一个Class对象。
  2. 链接:验证、准备和解析。验证是否有正确的内部结构,并和其他类保持一致性。准备分配内存并设置初始值。把相关的符号引用转换为直接引用。
  3. 初始化:执行类构造器()方法的字节码,给类的静态变量赋予正确的初始值。
  4. 使用:程序使用这个类创建实例对象、访问类的静态变量和方法等。
  5. 卸载:GC回收这个类的所有实例和空间。卸载该类的字节码,并从运行时常量池中移除这个类的符号引用。

面试官: 说明的很详细。类的生命周期中,有哪几个阶段会触发类初始化?

候选人: 有三种情况会触发类的初始化:

  1. 新创建一个该类的实例。
  2. 访问该类的静态变量,或为静态变量赋值。
  3. 调用该类的静态方法。
    除此之外,下面这些操作不会触发类的初始化:
  4. 使用一个类的名称,如在变量声明中使用该类的名称。
  5. 使用类加载器加载一个类。
  6. 访问某个类的静态常量。
//举例
public class Test {
    public static int a = 1;  //静态变量,会触发初始化
    public static final int b = 2;   //静态常量,不会触发初始化
    public static void method(){}   //静态方法,会触发初始化
}
Test t = new Test();   //创建实例,会触发初始化
Test.a = 2;           //访问静态变量,会触发初始化
Test.b = 3;           //访问静态常量,不会触发初始化
Test.method();        //调用静态方法,会触发初始化  

面试官: 说的很清楚,举例也很形象。那静态代码块是在哪个阶段执行的?

候选人: 静态代码块是在类初始化阶段执行的,位于()方法中。它优先于构造方法执行,并且只执行一次。例如:

public class Test {
    static {
        System.out.println("静态代码块执行");
    } 
    public Test() {
        System.out.println("构造方法执行");
    }
}

Test t1 = new Test();  
//打印:
静态代码块执行  
构造方法执行  

Test t2 = new Test();
//打印:
构造方法执行

因此,静态代码块主要用于一次性地对类进行初始化设置,这些设置只在类第一次被加载时执行。它和构造方法的不同之处在于,构造方法在每次创建实例时都会执行。

面试官: 很好,你对类的生命周期及其与类初始化的关系理解很透彻。我想你应该可以轻松应付与类加载相关的面试题了!

候选人: 非常感谢面试官的提问,这些关于类的生命周期和初始化阶段的知识点对我来说均很重要。我会不断复习和运用这些知识,以便进一步熟练掌握类加载机制的相关原理,从而应对可能遇到的面试题和实际开发中的相关问题。

最近我在更新《面试1v1》系列文章,主要以场景化的方式,讲解我们在面试中遇到的问题,致力于让每一位工程师拿到自己心仪的offer,感兴趣可以关注JavaPub追更!


《面试1v1》 连载中…


🎁目录合集:

Gitee:https://gitee.com/rodert/JavaPub

GitHub:https://github.com/Rodert/JavaPub

http://javapub.net.cn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/590503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5月底了,现在不想着跳槽可就晚了

前两天跟朋友感慨&#xff0c;今年的铜三铁四、裁员、疫情导致好多人都没拿到offer!现在已经5月底了&#xff0c;具体金九银十只剩下三个月。 对于想跳槽的职场人来说&#xff0c;绝对要从现在开始做准备了。这时候&#xff0c;很多高薪技术岗、管理岗的缺口和市场需求也出来了…

五、常用提升物体的方式

机器人在运动中伸展和提升功能&#xff0c;历来是比赛中机器人的一个重要的性能指标&#xff0c;因为按 比赛要求&#xff0c;机器人在上场前必须经过体积大小的检测&#xff0c;而在场地中如果能够有更好的伸展性 能将对比赛成绩十分有利&#xff0c;因此机器人提升自身高度以…

SAP-MM发票校验容差详解

MIRO发票校验容差详解 MIRO发票校验容差是指收货业务与发票校验业务之间的差异&#xff0c;这种差异可 能是物料价格差异、收货数量差异、收货金额差异等等&#xff0c;总之&#xff0c;发票校验的容差 内容最为丰富&#xff0c;容差类型有很多种&#xff0c;如下表所示&…

【ChatGPT插件第一期】28个ChatGPT插件,让你的学习、工作、生活效率翻倍!

文章目录 人工智能福利文章什么是ChatGPT插件如何使用ChatGPT插件28个插件全解读写在最后 人工智能福利文章 【分享几个国内免费可用的ChatGPT镜像】【10几个类ChatGPT国内AI大模型】【用《文心一言》1分钟写一篇博客简直yyds】【用讯飞星火大模型1分钟写一个精美的PPT】 Cha…

Linux I2C驱动分析4 - GPIO模拟I2C

一. 前言 在嵌入式开发中&#xff0c;由于芯片的I2C接口有限&#xff0c;或者出于硬件画板的方便&#xff0c;我们都需要将普通的GPIO模拟I2C接口使用。出于对这样的需求&#xff0c;Linux-2.6.x已经有相关代码了&#xff0c;Linux-3.x有标准的内核选项支持该功能&#xff0c;内…

模特信息管理系统的开发与实现(ASP.NET,SQLServer)

需求分析 模特信息管理系统主要给商家和模特用户提供服务&#xff0c;系统分为前台和后台两部分。 本研究课题重点主要包括&#xff1a;活动管理&#xff0c;商家管理&#xff0c;模特管理&#xff0c;系统公告管理和活动报名管理。 活动管理模块主要实现活动更新、活动添加、活…

生鲜农产品冷链物流配送路径优化模型构建及算法实现

摘要&#xff1a;本案例讲述的案例为生鲜农产品冷链物流配送路径优化&#xff0c;涉及的目标函数成本包括碳排放成本、固定成本、运输成本、货损变质成本、时间惩罚成本。 目标种类&#xff1a;单目标模型。 求解方法&#xff1a;基础版蚁群算法改进版蚁群算法。 整体对标层…

快速掌握EasyExcel在web场景中的应用(读和写)

目录 一、引入依赖 二、设置表头 三、web下载模板 四、测试下载功能 五、复杂表头 六、写入数据 七、格式优化 7.1 日期自定义转换 7.2 列宽行高注解 八、动态表头 九、动态表格写入数据 一、引入依赖 <dependency><groupId>com.alibaba</groupId>…

Linux——生产者消费者模型和信号量

目录​​​​​​​ 基于BlockingQueue的生产者消费者模型 概念 条件变量的第二个参数的作用 锁的作用 生产者消费者模型的高效性 生产者而言&#xff0c;向blockqueue里面放置任务 消费者而言&#xff0c;从blockqueue里面拿取任务&#xff1a; 总结 完整代码(不含存储…

从零开始搭建一个moveit2简单机械臂模型

文章目录 前言一、设计一个简单机械臂二、构造创建文件关系CMakeLists.txt 修改增加如下&#xff1a;package.xml 修改增加如下&#xff1a;urdf.rviz 全文如下&#xff1a;demo.launch.py 全文如下&#xff1a; launch rviz构造link构造joint 总结 前言 在网上搜了许多文章&a…

游戏互动,用Python点燃【儿童节】的欢乐!

当孩子们踏入人生的旅途时&#xff0c;他们需要的并不仅仅是学习知识&#xff0c;更需要的是在快乐的氛围中成长。六一儿童节即将来临&#xff0c;让我们用Python代码为孩子们送去一份特别的礼物吧&#xff01; 在本篇文章中&#xff0c;我会带领大家一起探索如何利用Python代…

php中文字符串提取方法,preg_replace 和preg_match_all区别

在php中&#xff0c;可以利用以下两种函数来只提取字符串的中文字符 preg_replace()函数 preg_match_all()函数 方法1&#xff1a;使用preg_match_all()函数 preg_match_all()函数配合正则表达式“/[\x{4e00}-\x{9fff}]/u”可以过滤字符串&#xff0c;只获取中文字符。 会…

chatgpt赋能python:Python中[:3]的用法介绍

Python中[:3]的用法介绍 Python是一种高级编程语言&#xff0c;经常被用于数据科学、机器学习、人工智能和Web应用程序开发。在Python中&#xff0c;有许多有用的编程技巧和语法&#xff0c;其中之一就是[:3]。 什么是[:3]&#xff1f; 在Python中&#xff0c;[:3]是一种称为…

研发工程师玩转Kubernetes——使用Ingress进行路由

依据微服务理念&#xff0c;我们希望每个独立的功能由一个服务支持。比如有两个接口&#xff1a;http://www.xxx.com/plus和http://www.xxx.com/minus&#xff0c;前者由一个叫plus-service的服务支持&#xff0c;后者由一个叫minus-service的服务支持。这样就需要一个路由层&a…

华为OD机试真题B卷 Java 实现【查找两个字符串a,b中的最长公共子串】,附详细解题思路

一、题目描述 查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。 注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开! 数据范围:字符串长度1≤length≤300 。 二、输入描述 输入两个字符串…

牛客网刷题学习SQL(五)

SQL25 查找山东大学或者性别为男生的信息 分析&#xff1a; 查看学校为山东大学或者性别为男性的用户的device_id、gender、age和gpa数据&#xff0c;结果不去重。 山东大学 --》 where university“山东大学” 男性—》where gender “male” 结果不去重 所以上面不能使用or&…

改进的yolo目标检测(yolo创新与改进)

目标检测是计算机视觉领域中的一个重要问题,它需要从图像或视频中检测出物体的位置和类别。近年来,深度学习技术在目标检测领域取得了显著的进展,其中一个重要的方法是基于YOLO(You Only Look Once)算法的目标检测。 YOLO算法的优点是速度快,但是在检测小物体和密集物体…

SAP-MM-发票-采购附加成本处理简介

一&#xff0e;采购附加成本处理&#xff1a; 原材料的采购成本包括采购成本&#xff08;采购单价*采购数量&#xff09;和相关采购附加成本&#xff08;运输费、保险费、报关费、仓储费、滞期费、租船费、码头费及代理费等费用&#xff09;&#xff0c;对于采购附加成本主要有…

覆盖标准(白盒、黑盒和灰盒)

覆盖标准(白盒、黑盒和灰盒) 覆盖标准Coverage Criteria 覆盖标准采用软件的抽象表示并将其划分为可测试的功能。 每个功能构成了测试需求的基础——需要由软件的测试套件进行测试的东西。 当测试套件的一个测试用例满足测试要求时&#xff0c;我们说测试要求被覆盖。测试套件…

四、机器人整体结构的稳定性

结构的稳定性是指结构在外界载荷作用下&#xff0c;能否维持自己的形状和位置。如果结构在外界载荷作用下能够维持自己的形状和位置&#xff0c;则称为稳定&#xff1b;如果结构在外界载荷作用下无法维持自己的形状和位置&#xff0c;则称为不稳定。 结构的稳定性是一个相对概念…