常见面试题之类加载器

news2024/11/16 16:55:35

1. 什么是类加载器,类加载器有哪些?

要想理解类加载器的话,务必要先清楚对于一个Java文件,它从编译到执行的整个过程。

在这里插入图片描述

  • 类加载器:用于装载字节码文件(.class文件)
  • 运行时数据区:用于分配存储空间
  • 执行引擎:执行字节码文件或本地方法
  • 垃圾回收器:用于对JVM中的垃圾内容进行回收

类加载器

JVM只会运行二进制文件,而类加载器(ClassLoader)的主要作用就是将字节码文件加载到JVM,从而让Java程序能够启动起来。现有的类加载器基本上都是java.lang.ClassLoader的子类,该类的只要职责就是用于将指定的类找到或生成对应的字节码文件,同时类加载器还会负责加载程序所需要的资源。

类加载器种类

类加载器根据各自加载范围的不同,划分为四种类加载器:

  • 启动类加载器(BootStrap ClassLoader):

    该类并不继承ClassLoader类,其是由C++编写实现。用于加载**JAVA_HOME/jre/lib**目录下的类库。

  • 扩展类加载器(ExtClassLoader):

    该类是ClassLoader的子类,主要加载**JAVA_HOME/jre/lib/ext**目录中的类库。

  • 应用类加载器(AppClassLoader):

    该类是ClassLoader的子类,主要用于加载**classPath**下的类,也就是加载开发者自己编写的Java类。

  • 自定义类加载器:

    开发者自定义类继承ClassLoader,实现自定义类加载规则。

上述三种类加载器的层次结构如下如下:

在这里插入图片描述

类加载器的体系并不是“继承”体系,而是委派体系,类加载器首先会到自己的parent中查找类或者资源,如果找不到才会到自己本地查找。类加载器的委托行为动机是为了避免相同的类被加载多次。

2. 什么是双亲委派模型?

如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就返回成功;只有父类加载器无法完成此加载任务时,才由下一级去加载。

在这里插入图片描述

3. JVM为什么采用双亲委派机制?

(1)通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性。

(2)为了安全,保证类库API不会被修改

在工程中新建java.lang包,接着在该包下新建String类,并定义main函数。

public class String {

    public static void main(String[] args) {

        System.out.println("demo info");
    }
}

此时执行main函数,会出现异常,在类java.lang.String中找不到main方法。

在这里插入图片描述

出现该信息是因为由双亲委派的机制,java.lang.String的在启动类加载器(Bootstrap classLoader)得到加载,因为在核心jre库中有其相同名字的类文件,但该类中并没有main方法。这样就能防止恶意篡改核心API库。

4. 说一下类装载的执行过程?

类从加载到虚拟机中开始,直到卸载为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这三个部分统称为连接(linking)。

在这里插入图片描述

类加载过程详解

1.加载

在这里插入图片描述

  • 通过类的全名,获取类的二进制数据流。

  • 解析类的二进制数据流为方法区内的数据结构(Java类模型)

  • 创建java.lang.Class类的实例,表示该类型。作为方法区这个类的各种数据的访问入口

在这里插入图片描述

2.验证

在这里插入图片描述

验证类是否符合JVM规范,安全性检查

  • 文件格式验证:是否符合Class文件的规范(2)元数据验证
    • 这个类是否有父类(除了Object这个类之外,其余的类都应该有父类)
    • 这个类是否继承(extends)了被final修饰过的类(被final修饰过的类表示类不能被继承)
    • 类中的字段、方法是否与父类产生矛盾。(被final修饰过的方法或字段是不能覆盖的)
  • 字节码验证
    • 主要的目的是通过对数据流和控制流的分析,确定程序语义是合法的、符合逻辑的。
  • 符号引用验证:符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量

比如:int i = 3;
字面量:3
符号引用:i

3.准备

在这里插入图片描述

为类变量分配内存并设置类变量初始值

  • static变量,分配空间在准备阶段完成(设置默认值),赋值在初始化阶段完成

  • static变量是final的基本类型,以及字符串常量,值已确定,赋值在准备阶段完成

  • static变量是final的引用类型,那么赋值也会在初始化阶段完成

在这里插入图片描述

4.解析

在这里插入图片描述

把类中的符号引用转换为直接引用

比如:方法中调用了其他方法,方法名可以理解为符号引用,而直接引用就是使用指针直接指向方法。

在这里插入图片描述

5.初始化

在这里插入图片描述

对类的静态变量,静态代码块执行初始化操作

  • 如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。

  • 如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。

6.使用

在这里插入图片描述

JVM开始从入口方法开始执行用户的程序代码

  • 调用静态类成员信息(比如:静态字段、静态方法)

  • 使用new关键字为其创建对象实例

7.卸载

当用户程序代码执行完毕后,JVM便开始销毁创建的Class对象,最后负责运行的JVM也退出内存。

5. 面试现场

5.1 什么是类加载器,类加载器有哪些?

JVM只会运行二进制文件,而类加载器(ClassLoader)的主要作用就是将字节码文件加载到JVM,从而让Java程序能够启动起来。

常见的类加载器有4个:

第一个是启动类加载器(BootStrap ClassLoader):其是由C++编写实现。用于加载JAVA_HOME/jre/lib目录下的类库。

第二个是扩展类加载器(ExtClassLoader):该类是ClassLoader的子类,主要加载JAVA_HOME/jre/lib/ext目录中的类库。

第三个是应用类加载器(AppClassLoader):该类是ClassLoader的子类,主要用于加载classPath下的类,也就是加载开发者自己编写的Java类。

第四个是自定义类加载器:开发者自定义类继承ClassLoader,实现自定义类加载规则。

5.2 说一下类装载的执行过程?

类从加载到虚拟机中开始,直到卸载为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这三个部分统称为连接(linking)。

1.加载:查找和导入class文件;

2.验证:保证加载类的准确性;

3.准备:为类变量分配内存并设置类变量初始值;

4.解析:把类中的符号引用转换为直接引用;

5.初始化:对类的静态变量,静态代码块执行初始化操作;

6.使用:JVM开始从入口方法开始执行用户的程序代码;

7.卸载:当用户程序代码执行完毕后,JVM便开始销毁创建的Class对象,最后负责运行的JVM也退出内存。

5.3 什么是双亲委派模型?

如果一个类加载器收到了类加载的请求,它首先不会自己尝试加载这个类,而是把这请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传说到顶层的启动类加载器中,只有当父类加载器返回自己无法完成这个加载请求(它的搜索返回中没有找到所需的类)时,子类加载器才会尝试自己去加载。

5.4 JVM为什么采用双亲委派机制?

主要有两个原因。

第一、通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性。

第二、为了安全,保证类库API不会被修改。

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

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

相关文章

八 、HTML表单

1、表单 三层架构 数据访问层 响应业务逻辑层的请求 与物理数据库交互 业务逻辑层 响应表示层的请求 与数据访问层交互 完成特定的业务逻辑约束 表示层 显示信息 收集信息(与业务逻辑层交互) HTML显示信息 基本标签:行内元素、块级元素 HT…

Java 设计模式——策略模式

目录 1.概述2.结构3.案例实现4.优缺点5.使用场景6.JDK 源码解析——Comparator 1.概述 (1)先看下面的图片,我们去旅游选择出行模式有很多种,可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。 (2)策略…

【计算机网络】网络编程套接字(二)

文章目录 网络编程套接字(二)简单TCP服务器实现创建套接字服务器绑定服务器监听服务器接收连接服务器处理请求 简单TCP客户端实现创建套接字客户端发起连接客户端发起请求 服务器简单测试服务器简单测评多进程版TCP服务器捕捉SIGCHLD信号孙子进程提供服务…

如何使用ai绘画生成器创造出惊人的作品

你们了解如何文字生图片吗,简单的来说就是用文字描述出图片的样子,然后通过ai技术生成出来。 这种技术现在应用的很广泛,在各行各业都有在使用,平常我无聊的时候,就靠它为我打磨时间了。 不过现在的ai绘画工具有很多…

51 # 二叉搜索树的实现

实现二叉搜索树 比如我们有数组: [10, 8, 19, 6, 15, 22, 20]需要把数组转为二叉搜索树,效果如下: // 节点 class Node {constructor(element, parent) {this.element element; // 存的数据this.parent parent; // 父节点this.left null…

订座排队小程序/H5/app【附源码】

订座排队小程序/H5/app 可看 应用效果 首页 答题活动规则 选择门店暂无门店 订座订座 订座成功 用户反馈订座 关于后端

抖音seo源码/源码开发部署环境配置及流程分享

抖音seo源码开发部署环境配置: 要配置抖音seo源码开发环境,您需要完成以下步骤: 安装 Python:请在官网下载 Python 并进行安装。 安装 Django:请在命令行中输入以下命令来安装 Django: pip install django…

双周连载 | 暗网分析报告Part 1:他们无法保护你

双周连载 | 暗网分析报告Part 1:他们无法保护你 暗网,一个人们讳莫如深的世界,一个充斥着悄无声息的威胁,似乎永久地悬在我们每个人的头顶。这是一个罪恶的不法之地,时刻散播着未知的可怕力量,这便是那些隐…

使用 Elastic 修剪传入日志体量

作者:Carly Richmond 记录日志还是不记录日志? 一直是软件工程师仍在努力解决的一个难题,这对站点可靠性工程(SRE)同事来说是不利的。 开发人员并不总能正确了解他们在应用程序中捕获的警告和错误的级别或上下文&#…

01-webpack的理解,解决了什么问题

一、背景 Webpack 最初的目标是实现前端项目的模块化,旨在更高效地管理和维护项目中的每一个资源 模块化 最早的时候,我们会通过文件划分的形式实现模块化,也就是将每个功能及其相关状态数据各自单独放到不同的JS 文件中 约定每个文件是一…

dubbo监控中心dubbo-admin老版本(dubbo-ops)使用

1、dubbo分组 在dubbo中&#xff0c;可以指定group&#xff0c;如下&#xff1a; <dubbo:registry protocol"zookeeper" address"${dubbo.registry.address}" client"curator" group"${dubbo.registry.group}" /> 使用proper…

差值结构的排斥能

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点&#xff0c;AB训练集各由5张二值化的图片组成&#xff0c;让差值结构中有7个1, 行分布是0&#xff0c;1&#xff0c;2&#xff0c;2&#xff0c;2列分布是1&#xff0c;2&#xff0c;4.统计迭代次数并排序。 得…

今年面试真的很难...

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;今年面试实在是太卷了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约…

应用层:文件传输协议FTP

1.应用层&#xff1a;文件传输协议FTP 笔记来源&#xff1a; 湖科大教书匠&#xff1a;应用层概述 湖科大教书匠&#xff1a;文件传输协议FTP 声明&#xff1a;该学习笔记来自湖科大教书匠&#xff0c;笔记仅做学习参考 将某台计算机中的文件通过网络传送到可能相距很远的另一…

猿人学web刷题1

1.第一题 js混淆源码乱码 - 猿人学 : url 时间戳加密 右键遇到反调试&#xff0c;参考前面的文章 过反调试 2.ast解混淆 首页1.js 拿到 function oo0O0, 在<script>标签里面, 无法调试&#xff0c;分析自己提取出来&#xff0c;或则hook替换 加密逻辑存在于window.a中&a…

Linux分布式应用 Zabbix监控软件实例:监控NGINX的性能

实例&#xff1a;监控NGINX的性能 1.安装&#xff08;确认是否有状态统计模块&#xff09; yum -y install nginx 2.更改NGINX配置文件添加状态统计站点 vim /etc/nginx/nginx.conf #主配置文件 vim /etc/nginx/conf.d/default.conf #子配置文件location /nginx_status {stub_…

Docker 常用指令集合,更换镜像(Ubantu)

1.更换镜像 先进入root用户 cat /etc/docker/daemon.json 查看有没有镜像创建目录,创建并编辑damon,json文件 mkdir -p /etc/docker vim /etc/docker/daemon.json# 填写内容 {"registry-mirrors": ["https://h5rurp1p.mirror.aliyuncs.com"] } 重新启…

在工作中保持情绪稳定:策略与实践

一、引言 近期发生的新闻热点再度引发公众对稳定情绪和心理健康的关注。在快节奏的现代生活中&#xff0c;我们常常面临各种压力和挑战&#xff0c;这可能会导致情绪波动&#xff0c;甚至影响我们的工作和生活质量。有时候我们遇到的最大的敌人&#xff0c;不是运气也不是能力…

Kubernetes的介绍(组件、Pod)和 安装使用

目录 Kubernetes是什么&#xff1f; 跟Kubernetes相似的软件&#xff1a; k8s里有哪些组件&#xff1f; 官方网站&#xff1a;Kubernetes 组件 | Kubernetes master上的Control Plane组件 什么是组件&#xff1f; Pod是什么呢&#xff1f; 1、kube-apiserver …

Oracle的CentOS安装

1.CentOS环境 阿里云轻量型服务器 2核-4g内存-80G系统盘 2.Oracle下载 Oracle下载 Oracle 数据库免费 CPU 限制 Oracle 数据库免费版自动将自身限制为两个内核进行处理。例如&#xff0c;在具有 2 个双核 CPU&#xff08;四个核&#xff09;的计算机上&#xff0c;如果大量…