类的加载机制
-
类加载的概念
- 类加载是 Java 虚拟机(JVM)把字节码文件(.class 文件)转变为 Java 类型的复杂且关键的过程。这就如同把一份详细的设计图纸(字节码文件)加工成一个可以实际运行和使用的软件模块(Java 类型)。字节码文件包含了类的完整定义,包括类的结构、成员变量、方法、构造函数等信息,类加载机制就是要把这些信息合理地加载到内存中,使得程序能够有效地利用这些类来执行各种操作。
-
类加载的时机
- 主动引用(一定会触发类加载)
- 创建类的实例:
- 当使用
new
关键字创建对象时,JVM 会检查这个类是否已经加载。如果没有加载,就会触发类加载过程。这是因为在创建对象之前,JVM 需要知道这个类的结构信息,比如对象的大小、成员变量的布局等,这些信息都存储在类的字节码文件中,只有通过类加载才能获取。例如,对于一个自定义的Person
类,当执行Person p = new Person();
时,JVM 会首先加载Person
类。
- 当使用
- 访问类的静态变量(除了被
final
修饰的常量且在编译期就能确定值的情况):- 静态变量属于类本身,当访问一个类的静态变量时,JVM 需要确保这个类已经加载到内存中。对于非编译期确定值的
final
静态变量,其初始化可能涉及到复杂的代码逻辑,所以访问这类变量会触发类加载。例如,有一个类Counter
,其中有一个静态变量static int count;
,当执行Counter.count
时,就会触发Counter
类的加载。但如果是final static int MAX_COUNT = 100;
这种在编译阶段就能确定值的常量,JVM 在编译时就已经将其值放入常量池,访问它不会触发类加载,因为不需要再去加载类获取这个常量的值。
- 静态变量属于类本身,当访问一个类的静态变量时,JVM 需要确保这个类已经加载到内存中。对于非编译期确定值的
- 调用类的静态方法:
- 静态方法与类相关联,而不是与对象相关联。所以,当调用一个类的静态方法时,JVM 必须先加载这个类。例如,在一个
MathUtils
类中有一个静态方法public static int add(int a, int b) { return a + b; }
,当执行MathUtils.add(1, 2);
时,JVM 会加载MathUtils
类,因为只有加载了这个类才能找到并执行add
方法。
- 静态方法与类相关联,而不是与对象相关联。所以,当调用一个类的静态方法时,JVM 必须先加载这个类。例如,在一个
- 使用反射方式对类进行操作:
- 反射是 Java 中强大的机制,允许程序在运行时动态地获取类的信息并操作类。当使用
java.lang.reflect
包中的方法,如Class.forName("com.example.MyClass")
或者通过类的Class
对象的newInstance()
方法来创建类的实例时,会触发类加载。这是因为反射操作需要访问类的内部结构信息,而这些信息只有在类加载后才能获取。例如,在一个数据库连接框架中,通过Class.forName("com.mysql.jdbc.Driver")
加载数据库驱动类,使得框架能够使用这个驱动类来建立数据库连接。
- 反射是 Java 中强大的机制,允许程序在运行时动态地获取类的信息并操作类。当使用
- 初始化一个类的子类:
- 当创建一个子类的对象时,JVM 会先检查父类是否已经加载。如果父类没有加载,就会先加载父类。这是因为子类继承了父类的成员变量和方法,子类的对象在内存中的布局和初始化过程依赖于父类的结构信息。例如,有一个父类
Animal
和一个子类Dog
,当执行Dog d = new Dog();
时,JVM 会先加载Animal
类,然后再加载Dog
类。
- 当创建一个子类的对象时,JVM 会先检查父类是否已经加载。如果父类没有加载,就会先加载父类。这是因为子类继承了父类的成员变量和方法,子类的对象在内存中的布局和初始化过程依赖于父类的结构信息。例如,有一个父类
- 作为启动类(包含
main
方法的类)被执行:- 包含
main
方法的类是 Java 程序的入口点。当运行一个 Java 程序时,JVM 首先要加载这个启动类,因为main
方法是程序执行的起点。例如,对于一个简单的HelloWorld
程序,其包含main
方法的HelloWorld
类就是启动类,JVM 会先加载这个类,然后从main
方法开始执行程序。
- 包含
- 创建类的实例:
- 被动引用(不会触发类加载)
- 通过子类引用父类的静态变量,不会导致子类的加载,只会加载父类:
- 当通过子类来访问父类的静态变量时,JVM 能够根据子类的信息找到父类的符号引用,并且只需要加载父类就可以获取这个静态变量的值。例如,父类
Parent
有一个静态变量static int parentVar = 10;
,子类Child
,当执行System.out.println(Child.parentVar);
时,只会加载Parent
类,因为 JVM 可以通过Child
类的继承关系找到Parent
类中parentVar
的定义,不需要加载Child
类。
- 当通过子类来访问父类的静态变量时,JVM 能够根据子类的信息找到父类的符号引用,并且只需要加载父类就可以获取这个静态变量的值。例如,父类
- 定义类数组,不会触发类的加载:
- 定义一个类数组只是声明了一个可以存储该类对象的容器,并没有实际使用这个类的任何成员。例如,
A[] aArray = new A[10];
只是在内存中分配了一个可以存储 10 个A
类对象的空间,但没有创建A
类的对象,也没有访问A
类的静态成员,所以不会触发A
类的加载。
- 定义一个类数组只是声明了一个可以存储该类对象的容器,并没有实际使用这个类的任何成员。例如,
- 通过子类引用父类的静态变量,不会导致子类的加载,只会加载父类:
- 主动引用(一定会触发类加载)
-
类加载的过程
- 加载(Loading)
- 字节码文件获取:
- 类加载器(ClassLoader)是类加载过程的核心角色。它负责根据类的全限定名(如
com.example.MyClass
)来查找并获取类的字节码文件。字节码文件的来源多种多样。在最常见的本地文件系统场景下,类加载器会按照classpath
环境变量指定的路径去查找.class 文件。例如,如果classpath
包含了/project/src
目录,当要加载com.example.MyClass
类时,类加载器会在/project/src/com/example/MyClass.class
路径下查找字节码文件。除了本地文件系统,字节码文件还可以来自网络,这在一些动态加载的应用场景中很有用,比如 Java Applet 或者一些基于网络的插件系统,类加载器可以通过网络协议(如 HTTP)从远程服务器下载字节码文件。另外,在一些特殊的应用场景下,字节码文件甚至可以从数据库或者其他自定义的存储介质中获取。
- 类加载器(ClassLoader)是类加载过程的核心角色。它负责根据类的全限定名(如
- 字节码文件转换为二进制流:
- 一旦找到字节码文件,类加载器会将其读取并转换为二进制字节流。这个过程类似于将文件从硬盘的存储格式转换为计算机能够处理的内存中的数据格式。对于本地文件系统中的.class 文件,类加载器会通过文件输入流(
FileInputStream
)等机制读取文件内容,并将其转换为二进制字节流。这个字节流是后续操作的基础,它包含了类的所有信息,包括类的结构、方法代码、变量定义等。
- 一旦找到字节码文件,类加载器会将其读取并转换为二进制字节流。这个过程类似于将文件从硬盘的存储格式转换为计算机能够处理的内存中的数据格式。对于本地文件系统中的.class 文件,类加载器会通过文件输入流(
- 在内存中生成代表这个类的
java.lang.Class
对象:- 在将字节码文件转换为二进制字节流之后,类加载器会在内存中创建一个
java.lang.Class
对象来代表这个类。这个Class
对象是 Java 反射机制的基石,它就像是类在内存中的一个 “代理” 或者 “身份证”。通过这个Class
对象,可以访问和操作类的各种属性,如获取类的名称、访问类的方法、获取类的成员变量等。例如,可以通过Class
对象的getName()
方法获取类的名称,通过getMethods()
方法获取类的所有方法信息。这个Class
对象在内存中的存储位置和管理方式由 JVM 内部机制决定,它是类在内存中的一种抽象表示,使得 JVM 能够在运行时对类进行各种操作。
- 在将字节码文件转换为二进制字节流之后,类加载器会在内存中创建一个
- 字节码文件获取:
- 验证(Verification)
- 文件格式验证:
- 这是验证过程的第一步,主要检查字节码文件是否符合 Java 虚拟机规范的格式要求。字节码文件有一个特定的格式,开头部分是魔数(
CAFEBABE
),这是一个用于标识字节码文件的特殊标记。验证过程会检查文件是否以正确的魔数开头,就像检查一个文件是否是合法的字节码文件的 “身份证” 一样。同时,还会检查文件的版本号是否在当前 JVM 支持的范围内。Java 字节码文件的版本号随着 Java 语言的发展而更新,JVM 只能处理与其兼容的版本号范围内的字节码文件。如果文件格式不符合要求,JVM 会抛出java.lang.VerifyError
异常,拒绝加载这个类。
- 这是验证过程的第一步,主要检查字节码文件是否符合 Java 虚拟机规范的格式要求。字节码文件有一个特定的格式,开头部分是魔数(
- 元数据验证:
- 元数据验证主要关注类的元数据信息,即类的结构相关的信息。这包括检查类的父类是否正确,例如,一个类不能继承一个
final
类,验证过程会检查这种非法的继承关系。同时,对于实现接口的类,会检查是否实现了接口中要求的所有方法。例如,如果一个类声称实现了java.util.List
接口,那么就需要验证它是否实现了List
接口中定义的所有方法,如add
、remove
、get
等方法。此外,还会检查类的成员变量和方法的访问修饰符是否合法,例如,一个private
方法不能在类外部被访问,验证过程会确保这种访问限制得到遵守。
- 元数据验证主要关注类的元数据信息,即类的结构相关的信息。这包括检查类的父类是否正确,例如,一个类不能继承一个
- 字节码验证:
- 字节码验证是对类的字节码指令进行详细检查,确保字节码流可以被虚拟机安全地执行。这是验证过程中最复杂的部分,因为它需要对字节码的逻辑和操作进行深入分析。例如,检查字节码是否存在非法的操作码,每个操作码在字节码文件中都有其特定的含义和规则,不合法的操作码可能会导致 JVM 执行错误的操作。同时,还会检查跳转指令是否指向合法的位置,字节码中的跳转指令用于实现循环、条件判断等逻辑结构,验证过程需要确保这些跳转指令不会导致程序执行到非法的内存区域或者跳过一些必要的初始化代码。如果字节码验证失败,JVM 会抛出
java.lang.VerifyError
异常。
- 字节码验证是对类的字节码指令进行详细检查,确保字节码流可以被虚拟机安全地执行。这是验证过程中最复杂的部分,因为它需要对字节码的逻辑和操作进行深入分析。例如,检查字节码是否存在非法的操作码,每个操作码在字节码文件中都有其特定的含义和规则,不合法的操作码可能会导致 JVM 执行错误的操作。同时,还会检查跳转指令是否指向合法的位置,字节码中的跳转指令用于实现循环、条件判断等逻辑结构,验证过程需要确保这些跳转指令不会导致程序执行到非法的内存区域或者跳过一些必要的初始化代码。如果字节码验证失败,JVM 会抛出
- 符号引用验证:
- 在 Java 程序中,代码中的类、方法和变量等可能是通过符号引用来表示的。符号引用是一种在编译阶段使用的引用方式,它通过字符串来描述目标的名称和位置。在解析阶段,这些符号引用会被转换为直接引用,而在这之前需要进行符号引用验证。主要验证符号引用中通过字符串描述的全限定名是否能找到对应的类、字段和方法等。例如,当一个类
A
引用了另一个类B
时,在字节码文件中可能只是通过符号(如B
的全限定名)来表示这个引用。符号引用验证会检查这个全限定名是否能够正确地定位到一个实际存在的B
类。如果符号引用验证失败,JVM 会抛出java.lang.NoClassDefFoundError
异常。
- 在 Java 程序中,代码中的类、方法和变量等可能是通过符号引用来表示的。符号引用是一种在编译阶段使用的引用方式,它通过字符串来描述目标的名称和位置。在解析阶段,这些符号引用会被转换为直接引用,而在这之前需要进行符号引用验证。主要验证符号引用中通过字符串描述的全限定名是否能找到对应的类、字段和方法等。例如,当一个类
- 文件格式验证:
- 准备(Preparation)
- 在准备阶段,JVM 会为类的静态变量分配内存空间,并设置默认初始值。这个过程是类加载过程中的一个重要环节,它主要是为后续的初始化阶段做准备。对于基本数据类型的静态变量,会根据其类型设置默认值。例如,对于
static int num;
,JVM 会为num
分配 4 个字节的内存空间(假设int
类型占 4 个字节),并将其初始值设置为 0。对于static boolean flag;
,会将其初始值设置为false
。对于引用类型的静态变量,会将其初始值设置为null
。需要注意的是,如果是static final
常量,并且其值在编译期就能确定(如static final int CONST_NUM = 10;
),那么在这个阶段会直接将其值设置为 10,而不是先设置为默认值再进行初始化。这是因为编译期确定值的常量在字节码文件中已经被当作一个常量值处理,不需要再经过初始化阶段。
- 在准备阶段,JVM 会为类的静态变量分配内存空间,并设置默认初始值。这个过程是类加载过程中的一个重要环节,它主要是为后续的初始化阶段做准备。对于基本数据类型的静态变量,会根据其类型设置默认值。例如,对于
- 解析(Resolution)
- 符号引用转换为直接引用:
- 在 Java 程序中,很多引用是通过符号引用来表示的。符号引用是一种在编译阶段使用的、比较抽象的引用方式,它通过字符串来描述目标的名称和位置。例如,当一个类
A
引用了另一个类B
时,在字节码文件中可能只是通过符号(如B
的全限定名)来表示这个引用。解析阶段的一个重要任务就是将这些符号引用转换为直接引用。直接引用可以是指向目标的指针、相对偏移量或者能直接定位到目标的句柄。例如,将对类B
的符号引用转换为指向B
类在内存中Class
对象的指针,这样在程序执行过程中,当需要访问B
类时,就可以通过这个直接引用来快速定位到B
类。
- 在 Java 程序中,很多引用是通过符号引用来表示的。符号引用是一种在编译阶段使用的、比较抽象的引用方式,它通过字符串来描述目标的名称和位置。例如,当一个类
- 解析类或接口、字段、方法的引用:
- 这包括对类和接口的加载和链接(如果还没有完成),以及对字段和方法的查找和绑定。例如,当一个类
A
调用了另一个类B
的方法method
时,在解析阶段需要找到B
类的method
方法在内存中的位置,并建立起A
类和B
类method
方法之间的调用关系。对于类和接口的解析,会检查引用的类或接口是否已经加载,如果没有加载,会触发加载过程。对于字段和方法的解析,会在类的字节码中查找对应的字段和方法的定义,并确定其在内存中的访问方式。这可能涉及到权限检查,例如,一个private
方法只能在其所属的类内部被访问,如果在其他类中试图访问这个private
方法,解析过程会检查这种访问是否合法。
- 这包括对类和接口的加载和链接(如果还没有完成),以及对字段和方法的查找和绑定。例如,当一个类
- 符号引用转换为直接引用:
- 初始化(Initialization)
- 执行类的初始化代码:
- 这是类加载过程的最后一步,会执行类的初始化代码。初始化代码包括静态变量的初始化语句和静态初始化块(
static {...}
)中的代码。这些代码会按照在类中出现的顺序依次执行。例如,对于一个类C
,有static int num = 10;
和static { System.out.println("Initializing C"); }
,在初始化阶段,会先将num
的值初始化为 10,然后执行静态初始化块中的打印语句。初始化代码是类在加载后第一次被使用时执行的代码,它用于初始化类的静态资源,例如,初始化一个静态的数据库连接池、加载配置文件等操作。
- 这是类加载过程的最后一步,会执行类的初始化代码。初始化代码包括静态变量的初始化语句和静态初始化块(
- 初始化顺序:
- 如果一个类有父类,那么先初始化父类,再初始化子类。这是因为子类可能会继承父类的静态变量和静态方法,需要先确保父类的初始化完成,才能正确地初始化子类。而且,在初始化过程中,同一个类只会被初始化一次,这是通过一个标记位来控制的。当一个类开始初始化时,JVM 会设置一个标记,表示这个类正在初始化。如果在初始化过程中遇到对同一个类的再次初始化请求,JVM 会忽略这个请求,避免重复初始化导致的错误。
- 执行类的初始化代码:
- 加载(Loading)
-
类加载器(ClassLoader)
- 启动类加载器(Bootstrap ClassLoader)
- 它是 Java 虚拟机内置的类加载器,处于类加载器层次结构的最顶层。启动类加载器负责加载 Java 核心类库,这些核心类库对于 Java 程序的运行是至关重要的,如
java.lang.Object
、java.util.ArrayList
等。它使用原生代码(C/C++)来实现,这使得它能够高效地加载最基础的类库。由于其特殊的实现方式,启动类加载器没有对应的java.lang.ClassLoader
对象,所以在 Java 代码中无法直接引用它。启动类加载器的加载路径是固定的,通常是<JAVA_HOME>/jre/lib
目录下的核心类库,这些类库是经过严格测试和优化的,构成了 Java 运行环境的基础。
- 它是 Java 虚拟机内置的类加载器,处于类加载器层次结构的最顶层。启动类加载器负责加载 Java 核心类库,这些核心类库对于 Java 程序的运行是至关重要的,如
- 扩展类加载器(Extension ClassLoader)
- 扩展类加载器位于类加载器层次结构的第二层,它负责加载 Java 的扩展类库,即
<JAVA_HOME>/jre/lib/ext
目录下的类库。扩展类加载器是由sun.misc.Launcher$ExtClassLoader
实现的,它是java.lang.ClassLoader
的子类。它可以加载一些第三方的扩展库,这些库提供了一些额外的功能,比如加密算法库、XML 解析库等。扩展类加载器的存在使得 Java 程序可以方便地扩展其功能,而不需要将所有的功能都集成在核心类库中。它的加载路径除了<JAVA_HOME>/jre/lib/ext
目录外,还可以通过系统属性java.ext.dirs
来指定其他扩展目录。
- 扩展类加载器位于类加载器层次结构的第二层,它负责加载 Java 的扩展类库,即
- 应用程序类加载器(Application ClassLoader)
- 也称为系统类加载器,它是类加载器层次结构中的第三层,负责加载用户类路径(
classpath
)上的类库。它是sun.misc.Launcher$AppClassLoader
实现的,也是java.lang.ClassLoader
的子类。在大多数情况下,我们编写的 Java 程序中的类都是由应用程序类加载器加载的。它可以加载我们自己编写的类、第三方的库(如果这些库在classpath
中)等。应用程序类加载器的加载路径可以通过系统属性classpath
来指定,它会按照classpath
中指定的目录和文件来查找和加载类。同时,它还会委托给其父类加载器(扩展类加载器和启动类加载器)来加载类,这是类加载器的委托机制的一部分。
- 也称为系统类加载器,它是类加载器层次结构中的第三层,负责加载用户类路径(
- 自定义类加载器(Custom ClassLoader)
- 除了上述三种标准的类加载器外,我们还可以根据自己的需求创建自定义类
- 启动类加载器(Bootstrap ClassLoader)
相关文章:
类的加载机制
类加载的概念 类加载是 Java 虚拟机(JVM)把字节码文件(.class 文件)转变为 Java 类型的复杂且关键的过程。这就如同把一份详细的设计图纸(字节码文件)加工成一个可以实际运行和使用的软件模块(J…...
基于vite创建的react18项目的单元测试
题外话 最近一个小伙伴进了字节外包,第一个活就是让他写一个单元测试。 嗯,说实话,在今天之前我只知道一些理论,但是并没有实操过,于是我就试验了一下。 通过查询资料,大拿们基本都说基于vite的项目&…...
fiddler抓包工具与requests库构建自动化报告
一. Fiddler 抓包工具 1.1 Fiddler 工具介绍和安装 Fiddler 是一款功能强大的 HTTP 调试代理工具,能够全面记录并深入检查您的计算机与互联网之间的 HTTP 和 HTTPS 通信数据。其主界面布局清晰,主要包含菜单栏、工具栏、树形标签栏和内容栏。 1.2 Fid…...
Docker login 报证书存储错误的解决办法
文章目录 docker login 出现错误,提示:Error saving credentials: error storing credentials - err: exit status 1, out: Cannot autolaunch D-Bus without X11 $DISPLAY 环境 使用的是 Mint Linux ,容器为 docker-ce 最新版 1 2 3 4 $…...
【自动化Selenium】Python 网页自动化测试脚本(上)
目录 1、Selenium介绍 2、Selenium环境安装 3、创建浏览器、设置、打开 4、打开网页、关闭网页、浏览器 5、浏览器最大化、最小化 6、浏览器的打开位置、尺寸 7、浏览器截图、网页刷新 8、元素定位 9、元素交互操作 10、元素定位 (1)ID定位 &…...
什么是MyBatis?
MyBatis简介 MyBatis是一款优秀的持久层框架,用于简化Java应用程序对数据库的操作。它曾是Apache的一个开源项目,名为iBatis,2010年迁移到Google Code并改名为MyBatis,2013年11月又迁移到了GitHub。 一、MyBatis的作用 在JavaE…...
TortoiseGit 将本地已有仓库推送到远程
TortoiseGit 将本地已有仓库推送到远程 一、创建线上仓库二、创建本地仓库三、提交内容到本地仓库四、添加远程仓库地址补充 一、创建线上仓库 在gitlab管理面页面按这前讲过的步骤创建一个空仓库。(通常我们把服务器上这个仓库叫远程仓库,把我们自己电…...
腾讯云OCR车牌识别实践:从图片上传到车牌识别
在当今智能化和自动化的浪潮中,车牌识别(LPR)技术已经广泛应用于交通管理、智能停车、自动收费等多个场景。腾讯云OCR车牌识别服务凭借其高效、精准的识别能力,为开发者提供了强大的技术支持。本文将介绍如何利用腾讯云OCR车牌识别…...
TailwindCss 总结
目录 一、简介 二、盒子模型相关 三、将样式类写到一个类里面apply 四、一款TailWind CSS的UI库 一、简介 官方文档:Width - TailwindCSS中文文档 | TailwindCSS中文网 Tailwind CSS 的工作原理是扫描所有 HTML 文件、JavaScript 组件以及任何 模板中的 CSS 类…...
Java与C#
Java和C#(C Sharp)是两种流行的面向对象编程语言,它们在很多方面非常相似,因为它们都受到了类似的编程范式和语言设计理念的影响。然而,它们之间也存在一些重要的区别。 平台依赖性: Java:Java是…...
leetcode:222完全二叉树的节点个数
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。 完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最…...
[STM32]从零开始的STM32 FreeRTOS移植教程
一、前言 如果能看到这个教程的话,说明大家已经学习嵌入式有一段时间了。还记得嵌入式在大多数时候指的是什么吗?是的,我们所说的学习嵌入式大部分时候都是在学习嵌入式操作系统。从简单的一些任务状态机再到复杂一些的RTOS,再到最…...
java——Tomcat连接池配置NIO、BIO、APR
Tomcat连接池的配置涉及不同的IO模型,包括NIO(Non-blocking IO,非阻塞IO)、APR(Apache Portable Runtime,Apache可移植运行库)和BIO(Blocking IO,阻塞IO)。以…...
跨域相关的一些问题 ✅
当网页从一个源(https://baidu.com)请求另一个源(如 https://taobao/api)的资源时,就发生了跨域。由于安全原因(防止恶意网站通过脚本访问用户在其他网站上的数据),浏览器对跨域请求…...
RPC学习
一、什么是 RPC RPC(Remote Procedure Call),即远程过程调用,是一种计算机通信协议,它允许运行在一台计算机上的程序调用另一台计算机上的子程序或函数,就好像调用本地程序中的函数一样,无需程序…...
coe文件转mif(c语言)
1 mif文件格式 DEPTH=1024; --The size of data in bits WIDTH=16; --The size of memory in words ADDRESS_RADIX = DEC; --The radix for address values DATA_RADIX = UNS...
【leetcode】动态规划
31. 873. 最长的斐波那契子序列的长度 题目: 如果序列 X_1, X_2, ..., X_n 满足下列条件,就说它是 斐波那契式 的: n > 3对于所有 i 2 < n,都有 X_i X_{i1} X_{i2} 给定一个严格递增的正整数数组形成序列 arr ࿰…...
介绍一下atoi(arr);(c基础)
hi , I am 36 适合对象c语言初学者 atoi(arr);是返回整数(int型),整数是arr数组中字符中数字 格式 #include<stdio.h> atoi(arr); 返回值arr数组中的数字 未改变arr数组 #include<stdlib.h>//atoi(arr); 返 <stdlib> int main(…...
docker入门学习笔记
docker的定义 docker是一个用于构建、运行、传送 应用程序的平台。 为什么要使用docker ? 在开发测试库环境中测试成功后,打包成集装箱,到生产环境也是能够成功的。而传统的安装方式不仅繁琐,并且在测试环境安装后,到…...
使用Python和Pybind11调用C++程序(CMake编译)
目录 一、前言二、安装 pybind11三、编写C示例代码四、结合Pybind11和CMake编译C工程五、Python调用动态库六、参考 一、前言 跨语言调用能对不同计算机语言进行互补,本博客主要介绍如何实现Python调用C语言编写的函数。 实验环境: Linux gnuPython3.10…...
tableau-制作30个图表
制作条形图 步骤: 1、横轴是数值,对应了某一个度量值,纵轴是一个标签 战区的成交额,条形图横轴是战区,纵轴是成交额 下钻条形图 1、增加业务架构-战区右键点击,分层结构,增加分层结构 调整业务架构,将战区,城市,小组移动到业务架构下方 此时的条形图上方有➕号展开后…...
2024APMCM亚太杯数学建模C题【宠物行业】原创论文分享
大家好呀,从发布赛题一直到现在,总算完成了2024 年APMCM亚太地区大学生数学建模竞赛C题的成品论文。 给大家看一下目录吧: 目录 摘 要: 10 一、问题重述 14 二.问题分析 15 2.1问题一 15 2.2问题二 15 2.3问题三…...
C语言解析命令行参数
原文地址:C语言解析命令行参数 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 C语言有一个 getopt 函数,可以对命令行进行解析,下面给出一个示例,用的时候可以直接copy过去修改,很方便…...
推荐一款龙迅HDMI2.0转LVDS芯片 LT6211UX LT6211UXC
龙迅的HDMI2.0转LVDS芯片LT6211UX和LT6211UXC是两款高性能的转换器芯片,它们在功能和应用上有所差异,同时也存在一些共同点。以下是对这两款芯片的详细比较和分析: 一、LT6211UX 主要特性: HDMI2.0至LVDS和MIPI转换器。HDMI2.0输…...
libmodbus 源码学习笔记
1.核心函数_框架_数据结构 整个通信的过程 就是上面这个框架 下面就是具体过程 <1> 主设备 我们首先要初始化 我们要使用的串口 然后 设置我们要访问的哪一个设备 最后打开串口 <2>从机设备 也是我们要初始化我们的串口 然后随后立即设置我们的串口设备地址 最后…...
通用网络安全设备之【防火墙】
概念: 防火墙(Firewall),也称防护墙,它是一种位于内部网络与外部网络之间的网络安全防护系统,是一种隔离技术,允许或是限制传输的数据通过。 基于 TCP/IP 协议,主要分为主机型防火…...
Vue.js基础——贼简单易懂!!(响应式 ref 和 reactive、v-on、v-show 和 v-if、v-for、v-bind)
Vue.js是一个渐进式JavaScript框架,用于构建用户界面。它专门设计用于Web应用程序,并专注于视图层。Vue允许开发人员创建可重用的组件,并轻松管理状态和数据绑定。它还提供了一个虚拟DOM系统,用于高效地渲染和重新渲染组件。Vue以…...
Mybatis 执行存储过程,获取输出参数的值
数据库环境:SQL Server 2008 R2 存储过程 alter procedure proc_generateOuterApplyId acceptType varchar(4),acceptGroupId int,outerApplyId varchar(20) output as begin set nocount onset outerApplyId 24GD6688--select outerApplyId as …...
RAG架构类型
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
Oracle 数据库 IDENTITY 列的性能选项
在上一篇文章Oracle 数据库 IDENTITY 列中,我们介绍了Oracle IDENTITY列的基础知识。本文将介绍IDENTITY列的几个性能选项。由于IDENTITY列内部使用sequence机制,因此也等同于是sequence的性能选项。 由于sequence是递增的,在高并发时&#…...
企业网站建设报价方案/seo网站推广经理
在odoo里如果想单击某个菜单打开的页面是自带过滤的,可以在打开菜单的动作中添加默认过滤来实现,今天有同学在群里问,如何在Many2many的添加更多的弹出窗口中添加类似的过滤,其实是非常非常简单的,只需要在field的cont…...
没网站怎么做二维码扫描连接/盛大游戏优化大师
在数据分析领域,最热门的莫过于Python和R语言,此前有一篇文章《别老扯什么Hadoop了,你的数据根本不够大》指出:只有在超过5TB数据量的规模下,Hadoop才是一个合理的技术选择。这次拿到近亿条日志数据,千万级…...
wordpress 忘记用户名密码破解/推广app
当我读取ACCESS里的系统表MSysObjects时,出现:不能读取记录;在 MSysObjects 上没有读取数据权限。的提示,语句是:select name from MSysObjects where type1 and flags0,而这个语句是可以直接在ACCESS查询器…...
网站首页一般做多大尺寸/郑州网站推广多少钱
2017年3月计算机二级MSOffice考前摸底测试题五一、选择题1.CPU主要技术性能指标有( )。A.字长、主频和运算速度B.可靠性和精度C.耗电量和效率D.冷却效率2.计算机系统软件中,最基本、最核心的软件是( )。A.操作系统B.数据库管理系统C.程序语言处理系统D.系统维…...
校园网站建设案例/百度关键词优化查询
题目链接:hdu 5105 Math Problem 题目大意:给定a。b,c,d。l,r。表示有一个函数f(x)|a∗x3b∗x2c∗xd|(L≤x≤R),求函数最大值。 解题思路:考虑极点就可以,将函数求导后得到f′(x)0的…...
小程序推广运营公司/安卓优化大师老版本下载
使用openssl加密文件Openssl是一个开源的用以实现SSL协议的产品,它主要包括了三个部分:密码算法库、应用程序、SSL协议库。Openssl实现了SSL协议所需要的大多数算法。下面我将单介绍使用Openssl进行文件的对称加密操作。一、Openssl支持的加密算法有&…...