Java的类是怎样在虚拟机中加载的?详细阐述JVM的加载、验证和解析过程

导航:

【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/黑马旅游/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码

目录

一、类加载过程概述

二、加载

2.1 基础概念

2.1.1 类加载

2.1.2 类的Class对象 

2.1.3 类加载子系统

2.1.4 双亲委派模型  

2.1.4.1 JVM三个默认类加载器

2.1.4.2 双亲委派模型的工作过程

2.2 类加载的具体过程

2.2.1 获取类的字节码文件

2.2.2 静态结构转运行时结构

2.2.3 生成类的Class对象

三、链接:验证、准备、解析

四、初始化


 

一、类加载过程概述

类加载过程:加载、链接(验证、准备、解析)、初始化。

  • 加载:生成类的Class对象,作为这个类各种数据的访问入口。
  • 链接:将类的二进制数据合并到JRE(即Java运行环境,等于JVM+Java程序运行所需的类库)中。
  • 初始化:给类中的类变量赋初值、执行静态语句块。

二、加载

2.1 基础概念

2.1.1 类加载

类加载:类加载就是Java 虚拟机(JVM)将类的字节码加载到内存中,并对其进行初始化的过程。此阶段最终会生成类的Class对象,作为这个类各种数据的访问入口

我们都知道,每个执行过的Java文件都会经历编译、运行两个阶段,这两个阶段分别对应JDK的bin目录下javac.exe、java.exe两个文件:

  • javac.exe:将我们写的类编译成.class文件(即字节码文件);
  • java.exe:运行这个.class文件。

通过javac.exe、java.exe编译、运行Java文件:

1.准备

准备测试类 :

/*** @Author: vince* @CreateTime: 2024/04/20* @Description: 测试类:Hello world* @Version: 1.0*/
public class Test {public Test() {}public static void main(String[] args) {System.out.println("hello~~~~~~~");}
}

2.编译

打开cmd窗口,使用javac命令编译成字节码文件:

javac Test.java

3.运行

运行class文件:

java Test

2.1.2 类的Class对象 

类的Class对象:在运行期间,JVM虚拟机会把.class文件中的类信息(变量、方法等信息)加载进内存中,并解析生成类的Class对象。通过这个类的Class对象,我们可以获取到类的各种信息。

类的字节码文件和Class对象的区别:

  • 类的class字节码文件是编译时生成的,类的class对象是运行时生成的。
  • 类的字节码文件是一个存储在电脑硬盘中的文件,例如Test.class;类的Class对象是存放在内存中的数据,可以快速获取其中的信息;
  • 两者都存储类的各种信息;

 类的字节码文件详解:

JDK编译生成的.class字节码文件是什么?从底层结构到代码验证,深度解析Java字节码文件-CSDN博客

2.1.3 类加载子系统

整个加载过程是在JVM中的类加载子系统完成的。 

类加载子系统:通过类加载机制加载类的class文件,如果该类是第一次加载,会执行加载、验证、解析。只负责class文件的加载,至于是否可运行,则由执行引擎决定。

JVM中,类加载过程是在类加载子系统完成的。

类加载过程:加载 --> 链接(验证 --> 准备 --> 解析) --> 初始化

类加载子系统详细参考:什么是JVM的内存模型?详细阐述Java中局部变量、常量、类名等信息在JVM中的存储位置-CSDN博客

类加载子系统采用了双亲委派模型,通过一系列的类加载器来实现类加载任务。 

2.1.4 双亲委派模型  

双亲委派模型:当一个类加载器接收到加载类的请求时,它首先会将这个请求委派给其父类加载器处理,只有在父类加载器无法完成加载任务时,才会由该类加载器自己去加载类。 

2.1.4.1 JVM三个默认类加载器
  • 启动类加载器BootStrapClassLoader(最顶端):
    • 加载内容:负责加载java的核心类库,包括java.lang包中的类等。底层使用C++实现(不会继承ClassLoader),是虚拟机自身的一部分。
    • 不能被直接引用:因为是C++实现的,所以无法被Java程序直接引用,只能加载委派过来的请求。这些类库存放在 JAVA_HOME\lib(具体解释看下文) 目录下,或者被 -Xbootclasspath 参数指定的路径中。(启动类加载器主要加载java的核心类库,即加载lib目录下的所有class)
  • 扩展类加载器ExtClassLoader:
    • 加载内容:负责加载JAVA_HOME\lib\ext目录中,或者被java.ext.dirs系统变量所指定的路径中所有类库。
    • 可以被直接引用:它可以直接用来加载类,也可以通过委派加载类。Ext是Extract缩写,译为扩展、提取。
  • 应用程序类加载器AppClassLoader(最低端):
    • 加载内容:负责加载类路径的所有类库,在大多数情况下,我们编写的 Java 程序都是由这个类加载器加载的。
    • 可以被直接引用:可以直接在代码中使用这个类加载器。

JAVA_HOME\lib:

是 JDK(Java Development Kit)安装目录下的一个子目录,其中包含了 Java 核心类库,包括一些 Java 的基础类和工具类等。这些类库是 Java 编程语言的基础,为 Java 程序的运行提供了必要的支持。

一些常见的在 JAVA_HOME\lib 目录下的重要文件包括:

  • rt.jar:Java 运行时的核心库,包含了 Java 核心类库的大部分内容,如 java.lang、java.util 等。
  • charsets.jar:包含了字符集支持的类库。
  • jfxrt.jar:JavaFX 运行时的核心库。
  • tools.jar:包含了一些 Java 开发工具的类库,如编译器、调试器等。
  • dt.jar:包含了 Java 开发工具包的类库,如图形界面工具等。

在编译和运行 Java 程序时,这些类库会被 JVM 的 Bootstrap ClassLoader 加载,以便程序能够使用 Java 核心类库提供的功能。

 

JAVA_HOME\lib\ext:

是 JDK(Java Development Kit)安装目录下的一个子目录,用于存放 Java 的扩展类库。这些类库提供了一些 Java 平台的扩展功能,如 XML 解析、网络协议、加密解密等。

在 JAVA_HOME\lib\ext 目录下,通常会包含一些 JAR 文件,这些文件是扩展类库的实现。一些常见的扩展类库包括:

  • dnsns.jar:DNS 名称服务提供者实现。
  • jaccess.jar:Java 访问桥实现。
  • ldapsec.jar:LDAP 安全实现。
  • sunjce_provider.jar:Sun 的 JCE(Java Cryptography Extension)提供者实现。
  • sunpkcs11.jar:Sun 的 PKCS#11 提供者实现。

这些扩展类库提供了一些 Java 平台的高级功能,但并不是所有的 Java 运行时环境都会使用到。通常情况下,如果你需要使用这些扩展功能,你可以将相应的 JAR 文件添加到类路径中,以便 Java 程序能够访问到这些功能。

2.1.4.2 双亲委派模型的工作过程

工作过程:

  1. 检查父类加载器是否已经加载过这个类:JVM 会首先询问父类加载器是否已经加载了该类。如果已经加载过了,直接返回该类的 Class 对象。如果没加载过,则:

  2. 委派给父类加载器加载:如果父类加载器没有加载过该类,那么 JVM 将委托给父类加载器进行加载。每一层都是这样继续委派,直到达到最顶层的启动类加载器。

  3. 尝试加载类:如果父类加载器无法加载该类(即所有的父类加载器都无法加载),那么 JVM 将尝试使用自己的类加载器来加载类。

实际流程:

JVM在加载一个类时,会调用应用程序类加载器的loadClass()方法来加载这个类,不过在这方法中,会先使用扩展类加载器的loadClass()方法来加载类,同样扩展类加载器的loadClass()方法中会先使用启动类加载器来加载类;

如果启动类加载器加载到了就直接成功,如果启动类加载器没有加载到,那扩展类加载器就会自己尝试加载该类,如果没有加载到,那么则会由应用程序类加载器来加载这个类。 

双亲委派模型的作用:

  • 避免类的重复加载:无论哪一个类加载器要加载某类,最终都是委派最顶端的启动类加载器。
  • 防止核心API被篡改:如果没有使用双亲委派模型,都由各个类加载器自行去加载的话,如果用户自己也编写了一个名为java.lang.Object的类,并放在程序的ClassPath中,那系统中就会出现多个不同的Object类,Java类型体系中最基础的行为也就无从保证,应用程序将会变得一片混乱。

类路径:

classpath:类路径classpath是编译之后的target文件夹下的WEB-INF/class文件夹。内容等同于打包前的src.main.java和src.main.resource下的目录和文件

classpath* :不仅包含class路径,还包括jar文件中(class路径)进行查找. 

2.2 类加载的具体过程

2.2.1 获取类的字节码文件

类加载过程中的第一步:通过类的全限定名获取定义此类的二进制字节流(即类的.class文件)。

  • 类的全限定名:即"包名.类名",例如Object类的全限定名是java.lang.Object 。包名的各个部分之间,包名和类名之间, 使用点号分割。 
  • 类的二进制字节流:即类的字节码文件,是一组以8个字节(64位)为基础单位的二进制流,各个单位内部及之间都排列紧凑,中间没有添加任何分隔符和空隙,这使得整个Class文件中存储的内容几乎都是程序运行的必要数据。当遇到需要占用8个字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8个字节进行存储,保证每个基础单位只有8个字节。

类的字节码文件详解:

JDK编译生成的.class字节码文件是什么?从底层结构到代码验证,深度解析Java字节码文件-CSDN博客

2.2.2 静态结构转运行时结构

类加载过程中的第二步:将这个.class字节码文件的静态存储结构,转化为方法区的运行时数据结构

  • 静态存储结构:二进制文件,存储内容,存储内容包括魔数、版本号、常量池、访问标识、类索引、字段表、方发表、属性表
  • 运行时数据结构:存储在内存中的JVM内存模型中的运行时数据区-方法区,存储内容是类常量池、运行时常量池、字符串常量池,存储形式是永久代(JDK7及之前)和元空间(JDK8及之后)。

此步骤中,JVM会将类常量池的部分符号引用放入运行时常量池。

字节码文件的静态存储结构:
JDK编译生成的.class字节码文件是什么?从底层结构到代码验证,深度解析Java字节码文件-CSDN博客

运行时数据区:在程序运行时,存储程序的内容(例如字节码、对象、参数、返回值等)。

运行时数据区包括本地方法栈、虚拟机栈、方法区、堆、程序计数器。

在运行时数据区中,只有方法区和堆是各线程共享的进程内存区域,其他运行区都是每个线程可以独立拥有的。

图示:

详细参考:什么是JVM的内存模型?详细阐述Java中局部变量、常量、类名等信息在JVM中的存储位置-CSDN博客

2.2.3 生成类的Class对象

在内存中生成类的java.lang.Class对象,作为方法区这个类各种数据的访问入口。

类的 Class 对象:类的 Class 对象是 Java 中用于表示类的元数据信息的对象,它包含了关于类的结构、字段、方法等各种信息,同时也提供了一些方法操作这些信息。Class 对象在 Java 反射和动态代理等场景中被广泛使用,可以在代码运行期间,动态获取和操作类的信息。

常用方法:

  • 获取类名、包名:通过 getName() 方法获取类的全限定名,通过 getPackage() 方法获取类所在的包信息。
  • 获取类的字段、方法:通过 getFields() 和 getDeclaredFields() 方法获取类的字段信息,通过 getMethods() 和 getDeclaredMethods() 方法获取类的方法信息。
  • 获取类的父类和接口信息:通过 getSuperclass() 方法获取类的父类信息,通过 getInterfaces() 方法获取该类所实现的接口信息。
  • 获取类的对象:通过 newInstance() 方法实例化类,获取类的对象。
  • 获取类的类型:通过 isInterface() 方法判断类是否是接口,通过 isArray() 方法判断类是否是数组类型,通过 isPrimitive() 方法判断类是否是基本数据类型等。

获取Class对象的三种方法:

  • 类名 .class 字面量:在程序中直接使用类的 .class 字面量可以获取该类的 Class 对象。例如:Class<?> clazz = MyClass.class;
  • 已有对象的 getClass() 方法:如果已经有该类的对象实例,可以通过调用对象的 getClass() 方法来获取该类的 Class 对象。例如:Class<?> clazz = obj.getClass();
  • Class.forName(类全限定名) :可以通过类的全限定名使用 Class.forName() 方法来获取该类的 Class 对象。例如:Class<?> clazz = Class.forName("com.example.MyClass");

注意类的class对象是运行时生成的,类的class字节码文件是编译时生成的。

类的字节码文件和Class对象的区别:

  • 生成时机:类的class字节码文件是编译时生成的,类的class对象是运行时生成的。
  • 本质:类的字节码文件是个文件,类的Class对象是个对象。文件存储在电脑硬盘中,例如Test.class;对象存放在内存中,可以快速获取其中的信息;
  • 存储内容:两者都存储类的各种信息;

三、链接:验证、准备、解析

链接:将类的二进制数据合并到JRE中。该过程分为以下3个阶段:

验证:确保代码符合JAVA虚拟机规范和安全约束。包括文件格式验证、元数据验证、字节码验证、符号引用验证。

  • 文件格式验证:验证字节码文件是否符合规范。
    • 魔数:是否魔数0xCAFEBABE开头。魔数是每个Class文件的头4个字节。唯一作用是确定这个文件是不是一个能被虚拟机接受的Class文件。cafeBabe可以翻译为咖啡宝贝。
    • 版本号:版本号是否在JVM兼容范围。JVM可以通过版本号判断这个字节码文件所对应的JDK版本。版本号从45开始,JDK1.1之后每个大版本的主版本号向上加1,例如JDK2.0的主版本号46,JDK8的版本号52(转为16进制是0x34 hex)。高版本的JDK能够向下兼容更低版本的Class文件,但不能运行更高版本的Class文件。所以虚拟机会拒绝执行超过其版本号的Class文件。
      • 次版本号(Minor Version):第5和第6个字节。
      • 主版本号(Major Version):第7和第8个字节。数据类型为u2,即占两个字节
    • 常量类型:类常量池里常量类型是否合法
    • 索引值:索引值是否指向不存在或不符合类型的常量。
  • 元数据验证:元数据是字节码里类的全名、方法信息、字段信息、继承关系等。
    • 标识符:验证类名接口名标识符有没有符合规范
    • 接口实现方法:有没有实现接口的所有方法
    • 抽象类实现方法:有没有实现抽象类的所有抽象方法
    • final类:是不是继承了final类。
  • 指令验证:主要校验类的方法体,通过数据流和控制流分析,保证方法在运行时不会危害虚拟机安全。
    • 类型转换:保证方法体中的类型转换是否有效。例如把某个类强转成没继承关系的类
    • 跳转指令:保证跳转指令不会跳转到方法体以外的字节码指令上;
    • 保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作。
  • 符号引用验证:确保后面解析阶段能正常执行。
    • 类全限定名地址:验证类全限定名是否能找到对应的类字节码文件
    • 引用地址:引用指向地址是否存在实例
    • 引用权限:是否有权引用

准备:为类变量(即static变量)分配内存并赋零值。

解析:将方法区-运行时常量池内的符号引用(类的名字、成员名、标识符)转为直接引用(实际内存地址,不包含任何抽象信息,因此可以直接使用)。

  • 符号引用:符号引用,顾名思义,就是一个符号,符号引用被使用的时候,才会解析这个符号。如果熟悉linux或unix系统的,可以把这个符号引用看作一个文件的软链接,当使用这个软连接的时候,才会真正解析它,展开它找到实际的文件。
  • 直接引用:实际内存地址。当一个类被加载时,该类所用到的别的类的符号引用都会保存在常量池,实际代码执行时,首次遇到某个别的类时,JVM会对常量池的该类的符号引用展开,转为直接引用,这样下次再遇到同样的类型时,JVM 就不再解析,而直接使用这个已经被解析过的直接引用。

示例:

        String s1="test1";String s2="test2";// s1,s2相当于符号引用:在编译时,JVM并没有解析s1;// 在运行时第一次加载这个类时,JVM会将s1和s2这两个符号引用解析为直接引用System.out.println(s1+s2);// "test1","test2"相当于直接引用:直接能访问到两个字符串的内存地址System.out.println("test1"+"test2");

四、初始化

初始化步骤:

  • 类变量赋初值:声明类变量时,直接初始值,例如public static int age=23;
  • 执行静态语句块:
    • 检查执行父类静态代码块:​​​​​假如该类的直接父类还没有被初始化,则先初始化其直接父类
    • 执行静态代码块:假如类中有初始化语句,则系统依次执行这些初始化语句

类变量赋值的两种方式:

/*** @Author: vince* @CreateTime: 2024/04/23* @Description: 类变量赋初值* @Version: 1.0*/
public class User {// 声明类变量并直接赋初值public static int age=23;// 在静态代码块中指定初始值public static int weight;static {weight=23;}}

类什么情况下会被初始化?

只有当对类的主动使用的时候才会导致类的初始化。

类会被初始化的场景:

  • new实例化:当通过 new 关键字创建类的实例时,该类会被初始化。这包括了显式地使用构造器创建对象,以及通过反射机制调用类的构造器来创建对象。
  • 访问类的静态成员:当访问类的静态字段(类变量)或静态方法时,如果该类还没有被初始化,则会触发类的初始化。
  • 反射:通过 Class.forName() 方法加载类时,如果指定了 initialize 参数为 true,则会触发类的初始化。
  • 子类初始化:当初始化一个类的子类时,如果该子类的父类还没有被初始化,则会先触发父类的初始化。
  • 启动类:Java虚拟机启动时被标明为启动类的类(Java Test),直接使用java.exe命令来运行某个主类

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

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

相关文章

解决 uniapp uni.getLocation 定位经纬度不准问题

【问题描述】 直接使用uni.getLocation获取经纬度不准确&#xff0c;有几百米的偏移。 【解决办法】 加偏移量 //加偏移 let x longitude let y latitude let x_pi (3.14159265358979324 * 3000.0) / 180.0 let z Math.sqrt(x * x y * y) 0.00002 * Math.sin(y * x_pi)…

信息系统项目管理师0067:数据建模(5信息系统工程—5.2数据工程—5.2.1数据建模)

点击查看专栏目录 文章目录 5.2数据工程5.2.1数据建模1.数据模型2.数据建模过程记忆要点总结5.2数据工程 数据工程是信息系统的基础工程。围绕数据的生命周期,规范数据从产生到应用的全过程,目标是为信息系统的运行提供可靠的数据保障和服务,为信息系统之间的数据共享提供安…

图像处理的基本操作

一、PyCharm中安装OpenCV模块 二、读取图像 1、基本语法 OpenCV提供了用于读取图像的imread()方法&#xff0c;其语法如下&#xff1a; image cv2.imread&#xff08;filename&#xff0c;flags&#xff09; &#xff08;1&#xff09;image&#xff1a;是imread方法的返回…

【服务器部署篇】Linux下Tomcat安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

【C++题解】1302. 是否适合晨练?

问题&#xff1a;1302. 是否适合晨练&#xff1f; 类型&#xff1a;分支 题目描述&#xff1a; 夏天到了&#xff0c;气温太高&#xff0c;小明的爷爷每天有晨练的习惯&#xff0c;但有时候温度不适合晨练&#xff1b;小明想编写一个程序&#xff0c;帮助爷爷判断温度是否适合…

MyBatis入门学习一(引入配置、体验CURD)

目录 1、MyBatis概述 1.1 MyBatis简介 1.2 MyBatis架构 1.3 MyBatis执行流程 1.4 与Hibernate的比较 2、MyBatis初体验 2.1 创建并配置项目 2.2 创建数据库表 2.3 引入MyBatis及其配置 2.3.1 MyBatis引入及配置 2.3.2 Log4j引入及配置 2.4 测试 2.4.1 编写测试类 …

C语言之回调函数+可变参数__VA_ARGS__:用法实例(四十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【linux】进程地址被占用

在强制关闭一个udp程序后&#xff0c;重启该程序报错&#xff1a; bind error: Address already in use 查找并关闭占用端口的进程&#xff1a; 首先&#xff0c;确定哪个进程占用了目标端口。在Linux系统中&#xff0c;可以使用以下命令&#xff1a; netstat -tulnp | grep …

【Linux网络】FTP服务

目录 一、FTP简介 1.FTP-文件传输协议 2.FTP的两种模式 二、安装配置FTP 1.安装环境 2.对文件的操作 3.切换目录 4.设置匿名用户 5.图形化界面登录 6.白名单与黑名单 重点与难点 一、FTP简介 1.FTP-文件传输协议 FTP是FileTransferProtocol&#xff08;文件传输协…

css中设置元素大小的属性block-size

block-size 是 CSS 中的一个属性&#xff0c;它用于设置元素的块级尺寸&#xff08;即元素的高度&#xff09;。这个属性是 height 和 max-height 的逻辑组合&#xff0c;允许你同时设置元素的最小和最大高度。 这些属性旨在让布局不再依赖于传统的物理方向&#xff08;如上下左…

如何调节电脑屏幕亮度?让你的眼睛更舒适!

电脑屏幕亮度的调节对于我们的视力保护和使用舒适度至关重要。不同的环境和使用习惯可能需要不同的亮度设置。可是如何调节电脑屏幕亮度呢&#xff1f;本文将介绍三种不同的电脑屏幕亮度调节方法&#xff0c;帮助您轻松调节电脑屏幕亮度&#xff0c;以满足您的需求。 方法1&…

hbase 集成 phoenix 实现 sql 化

1. 依赖 hbase > hbase 集群搭建 2. 下载安装包 点击下载 ps&#xff1a;该网页在内网可能打不开&#xff0c;遇到该情况有条件的可以打开 VPN 在下载 3. 上传解压 使用工具将安装包上传的服务器上 笔者这里选择 上传到 /opt/software 目录&#xff0c;解压到 /opt/mo…

spring security登录认证授权

spring security登录认证授权 是什么 Spring Security 主要实现了Authentication&#xff08;认证&#xff0c;解决who are you? &#xff09; 和 Access Control&#xff08;访问控制&#xff0c;也就是what are you allowed to do&#xff1f;&#xff0c;也称为Authorizat…

C语言扫雷游戏完整实现(下)

文章目录 前言一、排雷函数菜单二、排雷函数菜单的实现三、拓展棋盘功能四、源码1. test.c源文件2. game.h头文件3. game.c源文件 总结 前言 C语言实现扫雷游戏的排雷菜单&#xff0c;以及功能的实现&#xff0c;拓展棋盘功能&#xff0c;以及源码等。 上半部分的链接地址: C语…

python 笔记ast.literal_eval

1 介绍 ast.literal_eval 是 Python 标准库 ast 模块中的一个函数&#xff0c;用于安全地评估表示 Python 字面量或容器&#xff08;如列表、字典、元组、集合&#xff09;的字符串 import ast # 解析并执行一个数字表达式 num ast.literal_eval("3.14") prin…

新媒体运营-----短视频运营-----PR视频剪辑----软件基础

新媒体运营-----短视频运营-----PR视频剪辑-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/138079659 文章目录 1.1 PR软件重置与初始化设置1.2 新建项目及序列设置1.3 PR工作区的管理方法1.4 导入4K超高清视频并与ME配合工作1…

远程监控与控制的融合:吊车远程视频监控与远程开机的实现

随着信息技术的飞速发展&#xff0c;远程控制技术已经广泛应用于各个领域&#xff0c;包括工业、医疗、教育等。吊车远程视频监控作为远程控制的一种具体应用&#xff0c;不仅实现了对吊车操作的实时监控&#xff0c;还通过与远程开机功能的结合&#xff0c;进一步提升了远程控…

ctfshow web41-web50

web41 代码审计 <?php if(isset($_POST[c])){$c $_POST[c]; if(!preg_match(/[0-9]|[a-z]|\^|\|\~|\$|\[|\]|\{|\}|\&|\-/i, $c)){eval("echo($c);");} }else{highlight_file(__FILE__); } ?> 过滤了&#xff1a;[0-9] [a-z] ^ ~ $ [ ] { } & -…

Python自动化系统6

元素的特征:根据页面设计规则&#xff0c;有些特征是唯一 开发遵循了这个规则 id :类比身份证号―仅限于当前页面 username username 注意:如果id 不是固定的话&#xff0c;就不能使用来定位! xpath: 1、绝对路径&#xff1a;/html/body/div/div/div[1]/a/b --根节点&#xff…

初始Maven

1.背景 问题引入&#xff1a;为什么要使用 Maven&#xff1f; 1.1 添加第三方 jar 包 在 JavaEE 开发领域&#xff0c;有大量的第三方框架和工具可以供我们使用。使用这些 jar 包最简单的方法就是复制粘贴到 WEB-INF 目录中的 lib 目录下。但是会导致每次创建一个新工程就需要将…