当前位置: 首页 > news >正文

【学习笔记】深入理解JVM之类加载机制

【学习笔记】深入理解JVM之类加载机制

以后基本上都在语雀上面更新,大家有兴趣可以看看嗷!
首发地址: 知识库

文章流程图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6mcrGx0K-1671638019183)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20221221234802063.png)]

1、概述

首先我们先来看看一个 Class 文件所需要经过的一个流程图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SQMDXw9o-1671638019183)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20221218145747775.png)]

而我们今天要重点需讲的就是 类加载器 这部分。

在讲类加载器之前先问一个问题——什么是 Class 文件?

Class 文件是一组 8 字节为基础单位的二进制文件,各个数据项项目严格按照顺序紧凑地排列在文件之中,中间没有添加任何分隔符,这使得 Class 文件中存储的内存内容部分都是程序运行的必要数据,没有空隙存在。

通过上面的回答我们知道 Class 文件,是一个以 8 自己为基础单位的二进制文件,那如果遇到一个需要 占用8字节以上的的空间数据项时会怎么办?

当出现占用超过 8 以上空间的数据项时,则会采用 高位在前 的方式分割成若干个 8 个字节进行存储。

补充:

一般 Class 文件的头四个字节被称为 魔数(Magic Number) ,它的作用就是确定这个文件是否为一个能被虚拟机接受的 Class 文件。

2、类加载机制

那什么又是类加载机制呢?

Java虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行 校验、转换解析和初始化 ,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。

类加载的过程图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kgFGj2lU-1671638019184)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20221218151529117.png)]

2.1 加载

注意此处的 “加载” 是 ‘’类加载“ 过程中的一个阶段, 大家不要弄混了嗷。

在加载阶段,Java 虚拟机需要完成以下三件事:

  • 通过一个类的 全限定名 来获取定义此类的二进制字节流。
  • 将这个 字节流 所代表的 静态存储结构 转化为方法区的 运行时数据结构
  • 在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。

补充:

可以获取二进制字节流的方式:

  • 从ZIP压缩包中读取,这很常见,最中成为日后JAR、EAR、WAR的格式基础。
  • 从网络中获取,这种场景最低昂行的应用就是 Web Applet
  • 运行时计算生成,这种场景使用得最多的就是 动态代理 技术,在 java.lang.reflect.Proxy 中,就是用了 ProxyGenerator.generateProxyClass() 来为特定接口生成形式为 "*$Proxy" 的代理类的二进制字节流。
  • 从数据库中读取。
  • 其他文件生成。

2.2 验证

验证是链接阶段的第一步,这一阶段的目的是确保 Class 文件的字节流中包含的信息符合 《Java虚拟机规范》的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机自身的安全。

举个例子:

我们知道 Class 文件并不一定都是 Java 源码编译而来,它可以使用包括靠键盘 0和1 直接在二进制编辑器中敲出 Class 文件。如果不进行此方面的验证,对其完全信任的话,可能会有恶意的企图的字节码流程,而导致整个系统搜到破坏。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Jr9QB1u-1671638019184)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20221218200905808.png)]

所以说验证字节码是 Java 虚拟机自我保护的一项必要措施。

验证阶段是是十分严谨的,直接决定了 Java虚拟机 是否能承受恶意代码的攻击。验证阶段大致分为以下四个阶段:

  • 文件格式验证
  • 元数据验证
  • 字节码验证
  • 符号引用验证

♣️ 2.2.1 文件格式验证

第一阶段就是需要验证字节流是否符合 Class 文件格式的规范,并且能被当前版本的虚拟机处理。这一阶段可能包括下面这些验证点:

  • 是否以魔数 0xCAFEBABE 开头。
  • 主、次版本号是否在当前的 Java 虚拟机接受范围之内。
  • 常量池的常量中是否有不被支持的常量类型。
  • 指向常量的各种索引值中是否有指向不存在的常量或不符合类型的常量。
  • CONSTANT_Utf8_info型的常量中是否有不符合UTF-8编码的数据。
  • Class 文件中各个部分及文件本身是否有被删除的或附加的其他信息。

目的:

上述的验证阶段主要是为了保证输入的字节流能正确地解析并存储于方法区内。这个阶段是基于二进制字节流进行的,只有通过了这个阶段的验证之后,这段字节流才被允许进入Java虚拟机内存的方法区中进行存储。所以后面的三个验证阶段都是基于 方法区的存储结构来进行的

♣️ 2.2.2 元数据验证

第二阶段是对字节码描述的信息进行语义分析,以保证其描述的信息符合《Java语言规范》要求,这个阶段可能包括的验证点如下:

  • 这个类是否有父类(除了 java.lang.Object 之外,所有的类都应当有父类)。
  • 这个类的父类是否继承了不允许被继承的类(被final修饰的类)。
  • 如果这个类不是抽象类,是否实现了其父类或接口之中要求实现的所有方法。
  • 类中的字段、方法是否与父类产生矛盾(例如覆盖了父类的final字段,或者出现不符合规则的方法重载,例如方法参数都一致,但是返回值类型却不同等)。

目的:

是对类的元数据信息进行语义校验,保证不存在《Java语言规范》定义相悖的元数据信息。

♣️ 2.2.3 字节码验证

本阶段是真个验证阶段最为复杂的一个阶段,主要目的是通过数据流分析和控制流分析,确定程序语义是合法的、符合逻辑的。本阶段是对 方法体(Class文件中的Code属性) 进行校验分析,保证被校验类的方法在运行时不会做出未来虚拟机安全的行为。

例如:

  • 保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作,例如不会出现类似于“在操作栈放置了一个int类型的数据,使用时却按照long类型来加载本地变量表中” 这样的情况。
  • 保证跳转指令都不会跳转到方法体以外的字节码指令上。
  • 保证方法体中的类型转换总是有效的,例如可以把一个子类的对象赋值给父类数据类型,这样是安全的,但是把父类对象赋值给自类数据类型,甚至把对象赋值给与它毫无继承关系、完全不想干的一个数据类型,则是危险和不合法的。

如果有一个方法体中的字节码没有通过字节码的验证,那它肯定是有问题的。但是如果通过了验证也不能百分之百的保证他是安全的。

♣️ 2.2.4 符号引用验证

最后一个阶段的校验行为发生在虚拟机将符号转化为直接引用的时候,这个转化动作将在连接的第三阶段( 解析阶段中发生 )。其可以看作是对类自身以为(常量池中各个符号引用)的各类信息进行匹配性校验,通俗来说就是,该类是否缺少或者被禁止访问它依赖的某些外部类、方法、字段等资源。本阶段通常需要校验下列内容:

  • 符号引用中通过 字符串描述全限定名 是否能找到 对应的类
  • 指定类中 是否存在符合方法的字段 描述符简单名称 所描述的 方法和字段
  • 符号引用中的类、字段、方法的可访问性( private、protected、public、<package> ) 是否可被当前类访问。

本阶段的主要目的就是确保解析行为能正常执行,如果无法通过 符号引用验证 阶段 Java虚拟机 将会抛出一个 java.lang.IncompatibleClassChangeError 的子类异常,典型的如:java.lang.IllegalAccessError、java.lang.NoSuchFieldError、java.lang.NoSuchMethodError 等。

♣️ 2.2.5 总结

验证阶段对于虚拟机的类加载机制来说,是一个非常重要的、但却不是必须要执行的阶段,因为验证阶段只有通过或者不通过的差别,只要通过了验证,其后就对程序运行期没有任何影响,如果程序运行的全部代码(包括自己编写的、第三方包中的、从外部加载的、动态生成的等所有代码)都已经被反复使用和验证过了,再生产环境的实施阶段即可以考虑使用 -X verify:none 参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间。

2.3 准备

准备阶段是正式为类中定义的变量( 静态变量,被 static 修饰的变量 ) 分配内存并设置变量的初始值的阶段。从概念上讲,这些变量所使用的内存都应当在方法区中进行配置,但应该注意方法区本生就是一个逻辑上的区域。在 JDK1.8 之后,类变量会随着 Class 对象一起存放在 Java 堆中。

注意: 准备阶段进行内存分配的仅包括类变量,而不是实例变量,实例变量将会在对象实例化的时候随着对象一起分配在Java堆中

我们通常情况下数据类型 零值

例如:

public static int value = 123;

如上述代码,value 在准备阶段过后的初始值为0而不是123,因为 这时尚未开始执行任何Java方法,而把 value 赋值为123的 putstatic 指令是程序被编译后,存放于类构造器 <clinit>() 方法之中,所以把 value 赋值为123的动作要到类的初始化阶段才会被执行。

零值表补充:

**[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FLQhhdZm-1671638019184)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20221218222700941.png)]**

但是会出现特殊情况:

如果类字段的字段属性表中存在 ConstantValue 属性,那在准备阶段变量值就会被初始化为 ConstantValue 属性所指定的初始值,如果上面代码改为以下情况:

public static final int value = 123;

编译时 Javac 会将为 value 值生成 ConstantValue 属性,在准备阶段虚拟机就会根据 ConstantValue 的设置将 value 赋值为 123。

总结:

  • 为类变量分配内存并切设置该类变量的默认初始值,即零值。
  • 这里不包含使用 final 修饰的 static ,因为 final 在编译的时候机会分配,准备阶段会显示初始化。
  • 这里不会为 实例变量 分配初始化,类变量会分配在方法区中,而实例变量实惠随着对象一起分配到 Java堆中。

2.3 解析

解析过程是 Java虚拟机 将常量池内的 符号引用 替换为 直接引用 的过程。

  • 符号引用: 符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。

  • 直接引用: 直接引用是可以直接指向目标的指针、相对偏移量或者是一个能间接定位到目标的句柄。

解析的流程有以下四个:

  • 类或接口的解析
  • 字段解析
  • 方法解析
  • 接口方法解析

事实上解析操作都是往往伴随着 JVM 在执行过程中完成初始化之后再执行。

2.4 初始化

类的初始化阶段是类加载过程的最后一个步骤,之前介绍的的几个类的加载动作里,除了在 加载阶段 用户应用程序可以通过自定义类加载器的方式局部参与,其余动作完全由 Java 虚拟机来主导控制权。直到 初始化阶段Java 虚拟机才开始真正开始执行类中编写的 Java 程序代码,将主导权移交给应用程序。

而在初始化阶段,则会根据程序员通过程序编码指定的主观计划去初始化类变量和其他资源。

总结:

  • 初始化阶段就是执行类构造器 <clinit>() 方法的过程。
  • 此方法不需要被定义,而javac编译器自动收集类中所有变量值的赋值动作和静态代码块中语句合并而来。
  • 构造器方法中指令按语句在源文件中出现的顺序执行。
  • <clinet>() 不同于类的构造器(<init>()
  • 若该类具有父类,JVM 保证子类的 <client>() 执行前,父类的 <clinit>() 已经执行完毕。
  • 虚拟机必须保证一个类的 <clinit>() 方法再多线程下被同步加锁。

3、类加载器

首先我们要知道什么是 类加载器

通过一个类的全限定名来获取描述该类的二进制字节流 这个动作放到 Java 虚拟机外部去实现,以便让应用程序自己去决定如何获取所需的类。实现这个动作的代码被称为 类加载器(Class Loader)

对于任意一个类,都必须由加载它的类加载器和这个类本身一起共同确立其在 java 虚拟机中的 唯一性 ,每一个类加载器都拥有一个独立的类名称空间。通俗一点讲就是:比较两个类是否相等,只有在这两个类是同一个类加载器加载的前提下才有意义。

类加载器一共有以下几种:

名称加载哪的类说明
Bootstrap ClassLoader(启动类加载器)JAVA_HOME/jre/lib无法直接访问
Extension ClassLoader(扩展类加载器)JAVA_HOME/jre/lib/ext上级为 Bootstrap,显示为 null
Application ClassLoader(应用程序类加载器)classpath上级为 Extension
自定义类加载器自定义上级为 Application

类加载器的优先级(由高到低):启动类加载器 -> 扩展类加载器 -> 应用程序类加载器 -> 自定义类加载器

3.1 启动类加载器(Bootstrap ClassLoader)

  • 这个类加载器是使用 C++/C 语言来实现的,嵌套在 JVM 内部。
  • 它用来加载 Java 的核心库(JAVA_HOME/jre/lib),用于提供 JVM 自身需要的类。
  • 并不是继承自 java.lang.Class.ClassLoader ,没有父加载器。
  • 加载扩展类和应用程序类加载器,并指定为他们的父类加载器。

获取启动类能够加载的路径:

    public static void main(String[] args) {URL[] urLs = Launcher.getBootstrapClassPath().getURLs();for(URL element: urLs){System.out.println(element.toExternalForm());}}

file:/Users/tiejiaxiaobao/Library/Java/JavaVirtualMachines/liberica-1.8.0_345/jre/lib/resources.jar
file:/Users/tiejiaxiaobao/Library/Java/JavaVirtualMachines/liberica-1.8.0_345/jre/lib/rt.jar
file:/Users/tiejiaxiaobao/Library/Java/JavaVirtualMachines/liberica-1.8.0_345/jre/lib/sunrsasign.jar
file:/Users/tiejiaxiaobao/Library/Java/JavaVirtualMachines/liberica-1.8.0_345/jre/lib/jsse.jar
file:/Users/tiejiaxiaobao/Library/Java/JavaVirtualMachines/liberica-1.8.0_345/jre/lib/jce.jar
file:/Users/tiejiaxiaobao/Library/Java/JavaVirtualMachines/liberica-1.8.0_345/jre/lib/charsets.jar
file:/Users/tiejiaxiaobao/Library/Java/JavaVirtualMachines/liberica-1.8.0_345/jre/lib/jfr.jar
file:/Users/tiejiaxiaobao/Library/Java/JavaVirtualMachines/liberica-1.8.0_345/jre/classes

3.2 扩展类加载器(Extension ClassLoader)

  • Java语言编写,由 sun.misc.Launcher$ExtClassLoader 实现。
  • 派生于ClassLoader类。
  • 父类加载器为启动类加载器。
  • java.ext.dirs 系统属性所指定的目录中加载类库,或从 JDK 的安装目录的 jre/lib/ext 子目录(扩展目录)下加载类库。如果用户创建JAR在此目录下,则会自由由扩展类加载器加载。
//获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
// sun.misc.Launcher$AppClassLoader@18b4aac2

例如:

    public static void main(String[] args) {String property = System.getProperty("java.ext.dirs");for(String p: property.split(":")){System.out.println(p);}}

输出:

/Users/tiejiaxiaobao/Library/Java/Extensions
/Users/tiejiaxiaobao/Library/Java/JavaVirtualMachines/liberica-1.8.0_345/jre/lib/ext
/Library/Java/Extensions
/Network/Library/Java/Extensions
/System/Library/Java/Extensions
/usr/lib/java

3.3 应用程序加载器(AppClassLoader)

  • 由Java语言编写,由 sun.misc.Launcher$AppClassLoader 实现。
  • 派生于 ClassLoader 类。
  • 父类加载器为扩展加载器。
  • 它负责加载环境变量 classpath 或系统属性 java.class.path 指定路径下的类库。

3.4 用户自定义类加载器

为什么要自定义类加载器呢?

  • 隔离加载类
  • 修改类加载的方式
  • 扩展加载源
  • 防止源码泄露

那又什么时候去定义呢?

  • 1)想加载非 classpath 随意路径中的类文件
  • 2)都是通过接口来使用实现,希望解耦时,常用在框架设计
  • 3)这些类希望予以隔离,不同应用的同名类都可以加载,不冲突,常见于 tomcat 容器

步骤:

  • 继承 ClassLoader 父类。
  • 要遵从双亲委派机制,重写 findClass 方法 注意不是重写 loadClass 方法,否则不会走双亲委派机制。
  • 读取类文件的字节码。
  • 调用父类的 defineClass 方法来加载类。
  • 使用者调用该类加载器的 loadClass 方法。

4、双亲委派模型

♣️ 什么是双亲委派模型呢?

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UtWnM5dJ-1671638019184)(/Users/tiejiaxiaobao/Library/Application Support/typora-user-images/image-20221219212226647.png)]

实现:

		protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {// 首先,检查请求的类是否已经被加载过了 Class c = findLoadedClass(name); if (c == null) {try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name); }} catch (ClassNotFoundException e) {// 如果父类加载器抛出ClassNotFoundException // 说明父类加载器无法完成加载请求}if (c == null) {// 在父类加载器无法加载时// 再调用本身的findClass方法来进行类加载 c = findClass(name);} }if (resolve) { resolveClass(c);}return c; 
}

♣️为什么使用双亲委派模型呢?(好处)

  • 采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父加载器已经加载了该类时,就没有必要子加载器再加载一次。
  • 其次是考虑到安全因素,java 核心 api 中定义类型不会被随意替换,假设通过网络传递一个名为 java.lang.Integer 的类,通过双亲委托模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载网络传递的过来的 java.lang.Integer,而直接返回已加载过的 Integer.class,这样便可以防止核心API库被随意篡改。

参考

本篇笔记参考:尚硅谷JVM 26 - 36 集

《深入理解Java虚拟机》第三版

第六章—类文件结构

第七章—虚拟机类加载机制

文章地址:https://blog.csdn.net/weixin_43591980/article/details/119916684

相关文章:

【学习笔记】深入理解JVM之类加载机制

【学习笔记】深入理解JVM之类加载机制 以后基本上都在语雀上面更新&#xff0c;大家有兴趣可以看看嗷&#xff01; 首发地址&#xff1a; 知识库 文章流程图&#xff1a; 1、概述 首先我们先来看看一个 Class 文件所需要经过的一个流程图&#xff1a; 而我们今天要重点需讲的…...

驾驭云端之风1——Spring Cloud微服务架构实践指南

本博客纯属个人总结&#xff0c;非原创。喜欢技术交流的&#xff0c;可关注博主&#xff0c;武汉有后端开发群&#xff0c;可支持内推&#xff0c;了解武汉行情等。 前沿 优惠卷平台项目的整体功能和模块&#xff0c;以及每个功能点的技术选型和背后的依据。 搭建一个简化版的…...

【计算机网络基础】

计算机网络基础网络的基本概念网络互联网IP地址MAC地址网络协议网络分层模型网络应用程序的通信流程网络的基本概念 网络 网络是由若干结点和链接这些结点的链路组成&#xff0c;网络中的结点可以是计算机&#xff0c;交换机&#xff0c;路由器等设备 网络设备&#xff1a;交…...

grep与nm命令的应用

相关知识拓展 Linux中grep的命令使用 在Linux中&#xff0c;grep可用于shell脚本&#xff0c;因为grep通过返回一个状态值来说明搜索状态&#xff0c;如果模板搜索成功&#xff0c;则返回0&#xff0c;如果搜索不成功&#xff0c;则返回1&#xff0c;如果搜索的文件不存在&…...

【linux】软硬链接

在linux中在磁盘中定位文件并不是根据文件名而是根据文件的inode&#xff0c;一个文件对应一个inode但是一个inode可以对应多个文件。硬链接硬链接是通过索引节点进行的链接。在Linux中&#xff0c;多个文件指向同一个索引节点是允许的&#xff0c;像这样的链接就是硬链接。硬链…...

骨传导蓝牙耳机排行,盘点几款性能不错的骨传导耳机

随着蓝牙耳机的普及&#xff0c;骨传导耳机也越来越受到欢迎&#xff0c;很多人也都开始在了解并尝试骨传导耳机。相比于其他类型耳机&#xff0c;在舒适度、安全方面有一定优势。尤其是在户外运动时&#xff0c;或者长时间佩戴运动时&#xff0c;使用骨传导耳机可以避免耳朵因…...

ARM中的寄存器

ARM工作模式 ARM有8个基本的工作模式 User 非特权模式&#xff0c;一般在执行上层的应用程序时ARM处于该模式FIQ 当一个高优先级中断产生后ARM将进入这种模式IRQ 当一个低优先级中断产生后ARM将进入这种模式SVC 当复位或执行软中断指令后ARM将进入这种模式Abort 当产生存取异常…...

git操作修改历史版本指定tag标签的代码,并发布新标签

场景&#xff1a; 当项目已经迭代多个版本之后&#xff0c;突然发现旧版本0.0.1出现了紧急bug&#xff0c;需要及时处理&#xff1b; 如果直接用新版本替换上去是存在极大隐患的&#xff0c;且时间来不及&#xff1b; 所以需要直接在0.0.1版本的基础上去修复bug&#xff0c;然…...

SpringMVC——响应处理(1)【包含源码分析】

Controller public class JsonReturnController {ResponseBodyGetMapping("/getPet")public Pet getPet(){Pet petnew Pet();pet.setAge(5);pet.setName("lily");return pet;} }项目启动后 浏览器输入 http://localhost:8080/getPet 。 debug DispatcherS…...

Normalization

1、BN&#xff08;Batch Normalization&#xff09; 深度网络参数训练时内部存在协方差偏移&#xff08;Internal Covariate Shift&#xff09;现 象&#xff1a;深度网络内部数据分布在训练过程中发生变化的现象。训练深度网络时&#xff0c;神经网络隐层参数更新会导致网络输…...

27K测试老鸟分享自己6年面试心得,四种公司、四种问题…

这里总结了下自己今年的面试情况 先说一下自己的个人情况&#xff0c;普通二本计算机专业毕业&#xff0c;懂python&#xff0c;会写脚本&#xff0c;会selenium&#xff0c;会性能。趁着金三银四跳槽季&#xff0c;面试字节跳动测试岗技术面都已经过了&#xff0c;本来以为是…...

中小企业数字化自动化转型的方法

自动化是我们国内未来的趋势。智能制造的实现主要依托两个基础能力&#xff0c;一个是工业制造技术&#xff0c;另一个就是工业互联网。而自动化是工业制造技术的重要组成部分&#xff0c;是高度智能制造装备的核心部分&#xff0c;与承接着制造单元与工业互联网这两大核心。懂…...

利用GPT-3 Fine-tunes训练专属语言模型

利用GPT-3 Fine-tunes训练专属语言模型 文章目录什么是模型微调&#xff08;fine-tuning&#xff09;&#xff1f;为什么需要模型微调&#xff1f;微调 vs 重新训练微调 vs 提示设计训练专属模型数据准备清洗数据构建模型微调模型评估模型部署模型总结什么是模型微调&#xff0…...

kubeadm方式安装k8s高可用集群(版本1.26x)

K8S官网&#xff1a;https://kubernetes.io/docs/setup/ 高可用Kubernetes集群规划 配置备注系统版本CentOS 7.9Docker版本20.10.xPod网段172.16.0.0/12Service网段10.103.10.0/16 主机IP说明k8s-master01 ~ 03192.168.77.101 ~ 103master节点 * 3k8s-master-lb192.168.77.2…...

分享5款堪称神器的免费软件,建议先收藏再下载

转眼间新年已经过去一个月了&#xff0c;最近陆陆续续收到好多小伙伴的咨询&#xff0c;这边也是抓紧整理出几个好用的软件&#xff0c;希望可以帮到大家。 1.电脑安全管家——火绒 火绒是一款电脑安全软件&#xff0c;病毒库更新及时&#xff0c;界面清晰干净&#xff0c;没…...

【项目实战】从0开始入门JDK源码 - LinkedList源码

一、源码位置 一般来说IDEA配置好JDK以后 ,JDK的源码其实也配置好了,本文是基于JDK1.8的源码说明 rt - java - util - LinkedList 二、 继承关系图 LinkedList public class LinkedList<E>extends AbstractSequentialList<E>implements...

Polygon zkEVM的gas定价

1. 引言 所有的zkEVM都存在一个有趣的问题&#xff1a; 如何给gas定价&#xff1f; 在Ethereum Virtual Machine (EVM)中&#xff0c;gas通过为每个计算设置economic fee&#xff0c;来保持网络安全。恶意行为&#xff0c;如拒绝服务&#xff08;DoS&#xff09;攻击&#x…...

stl中的智能指针类详解

C98/03的尝试——std&#xff1a;&#xff1a;auto_ptr C11标准废弃了std&#xff1a;&#xff1a;auto_ptr&#xff08;在C17标准中被移除&#xff09;&#xff0c;取而代之的是std&#xff1a;&#xff1a;unique_ptr, std&#xff1a;&#xff1a;auto_ptr容易让人误用的地…...

Linux 阻塞和非阻塞 IO 实验

目录 一、阻塞和非阻塞简介 1、IO 概念 2、阻塞与非阻塞 二、等待队列 1、等待队列头 2、等待队列项 3、将队列项添加/移除等待队列头 4、等待唤醒 5、等待事件 三、轮询 1、应用程序的非阻塞函数 2、Linux 驱动下的 poll 操作函数 四、阻塞IO之等待事件唤醒 添加…...

你要的react+ts最佳实践指南

本文根据日常开发实践&#xff0c;参考优秀文章、文档&#xff0c;来说说 TypeScript 是如何较优雅的融入 React 项目的。 温馨提示&#xff1a;日常开发中已全面拥抱函数式组件和 React Hooks&#xff0c;class 类组件的写法这里不提及。 前沿 以前有 JSX 语法&#xff0c;…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

算术操作符与类型转换:从基础到精通

目录 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符&#xff1a;、-、*、/、% 赋值操作符&#xff1a;和复合赋值 单⽬操作符&#xff1a;、--、、- 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...

负载均衡器》》LVS、Nginx、HAproxy 区别

虚拟主机 先4&#xff0c;后7...