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

JVM之class文件结构剖析

文章目录

  • 0.前言
  • 1. 引言
    • 1.1 Java编译原理基础
    • 1.2 Class文件在Java编译过程中的角色
  • 2. Class文件的整体结构
    • 2.1 Class 文件组成
  • 3. Class文件的详细解析
    • 3.1 魔数与版本号的作用和意义
    • 3.2 常量池的结构和作用
    • 3.3 访问标志的含义和可能的值
    • 3.4 类索引、父类索引和接口索引集合的作用和构成
    • 3.5 字段表和方法表
    • 3.6 属性表的详细解析
  • 4. Class文件在JVM中的角色
    • 4.1 Class文件在JVM中的生命周期
    • 4.2 JVM是如何加载和使用Class文件的
    • 4.3 Class文件在动态链接、加载和运行机制中的作用
  • 5. javap 命令详解
  • 6. 十六进制编辑器 010 Editor 查看Class 文件
  • 7. 使用jclasslib 工具查看字节码
  • 8.参考文档

0.前言

在Java编译过程中,源代码首先会被编译器编译成为字节码文件,这些文件的后缀名为.class。然而,尽管.class文件在Java编程中占有重要地位,但是大多数Java开发者对其内部的结构和工作原理并不是非常了解。所以抽时间我整理一下,和大家一起学习进步。

本文旨在对Java的.class文件结构进行详细的剖析,让我们一起了解其内部的工作机制。希望大家在阅读本文后, 对Java虚拟机有更多的了解,并在日后的编程工作中更加得心应手。

1. 引言

在了解JVM Class文件结构剖析之前,我们需要对两个基础知识进行了解一下。java 编译原理Class文件在Java编译过程中的角色

1.1 Java编译原理基础

在这里插入图片描述
在Java编译过程中,对于每个阶段的示例如下:

  1. 词法分析
    词法分析:这个阶段会将源代码分割成一系列的词元(Token)。每个词元都是源代码中的一个最小有意义的独立部分,例如关键字(如public, class等)、标识符、运算符等。
    源代码:
public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, World!");}
}

词法分析后,会得到一系列的词元(Token),如:public, class, HelloWorld, {, public, static, void, main, (, String, [, ], args, ), {, System, ., out, ., println, (, "Hello, World!", ), ;, }, }

  1. 语法分析
    语法分析:语法分析阶段会根据词元,构建出抽象语法树(Abstract Syntax Tree, AST)。AST是一种用于表示程序结构的树形结构,树的每个节点都代表程序代码中的一个构造(例如声明,表达式等)。

语法分析阶段生成的抽象语法树(AST)涵盖源代码的结构信息。以下是HelloWorld类的简化版AST:

  ClassDeclaration├── Modifier: public├── Name: HelloWorld└── MethodDeclaration├── Modifier: public├── Modifier: static├── ReturnType: void├── Name: main├── Parameter: String[] args└── Block└── MethodInvocation├── Name: System.out.println└── Argument: "Hello, World!"
  1. 语义分析
    语义分析:这个阶段会检查源代码的语义是否正确。例如类型检查,确保赋值和操作符等的类型正确性。此外,语义分析还包括符号解析,将代码中的变量和类型名称解析为内部的符号引用。

举一例错误的赋值语句:

public class Test {public static void main(String[] args) {int a = "hello";}
}

在语义分析阶段,编译器会检查变量类型是否正确。在这个例子中,尝试将字符串"hello"赋值给整型变量a,这是错误的,编译器会提示类型不匹配的错误。

  1. 代码生成
    代码生成:在所有分析完成后,编译器会生成字节码,字节码是一种中间代码,可以在Java虚拟机(JVM)上执行。

在代码生成阶段,编译器会将以上的源代码转化为以下的Java字节码:

public class HelloWorld {public HelloWorld();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnpublic static void main(java.lang.String[]);Code:0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #3                  // String Hello, World!5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: return
}

这是.class文件的内容,可以通过javap -c HelloWorld命令查看。

1.2 Class文件在Java编译过程中的角色

  1. 字节码的载体

    Class文件包含了Java程序的字节码,也就是Java源代码编译之后的结果。Java编译器(如javac)会将Java源代码转化为字节码,字节码是一种中间语言,它比源代码更接近于机器语言。字节码的存在使得Java程序可以在任何安装了Java虚拟机的平台上运行,因为Java虚拟机能够解释和执行字节码。

  2. 实现跨平台特性

    字节码是一种平台无关的中间表示形式,它不依赖于特定的硬件和操作系统。这意味着只要一个设备安装了Java虚拟机,那么这个设备就能够执行Java程序,无论这个设备使用的是什么操作系统。这就是Java的"一次编写,到处运行"的理念。

  3. 动态加载和链接

    Java虚拟机在运行时会动态地加载Class文件。也就是说,Java虚拟机并不会一次性加载所有的Class文件,而是在程序运行过程中,当需要使用到某个类时,才会将这个类的Class文件加载进内存。这种动态加载的机制提高了内存的使用效率。

    除了加载,Java虚拟机还会进行链接。链接是指将Class文件中的符号引用替换为直接引用的过程。符号引用是一种抽象的引用,它可以是任何形式的字符集,用来描述被引用的信息。直接引用则是指向目标的指针、相对偏移量或者是一个能够直接定位到目标的句柄。

  4. 存储元数据

    Class文件中包含了Java类或接口的元数据信息。这些信息包括类名,方法名,字段名以及它们的访问修饰符等。这些元数据在运行时可以被Java虚拟机用于反射、泛型等操作。

    反射的操作包括获取Class实例,获取类的构造方法,字段和方法,创建类的实例,调用方法,访问字段等。

    泛型则是Java语言提供的一种代码抽象和复用机制。Java的泛型是在编译器这个层次来实现的,也就是说,Java的泛型仅仅是给编译器Java源码用的,确保数据的类型安全。而字节码文件中,是不包含泛型中的类型信息的。在编译器编译Java源码到字节码时,会将源码中的泛型擦除,而在需要的地方插入类型强制转换的代码来确保类型正确。

2. Class文件的整体结构

参考Oracle 官方文档 Chapter 4. The class File Format https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
在这里插入图片描述

2.1 Class 文件组成

部分名称描述
魔数魔数是Class文件的头四个字节,它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。Java的魔数固定为0xCAFEBABE
版本号版本号是Class文件的次要版本号和主要版本号,它们都占用两个字节。主要版本号确定了Class文件的版本,比如JDK 1.1的主要版本号为45,而JDK 1.2~1.8的主要版本号则分别为46~52。
常量池常量池是Class结构的一部分,它用于存放编译期生成的各种字面量和符号引用。这部分内容将在类加载后进入方法区中。
访问标志访问标志用于识别一些类或接口层次的访问信息,包括:是否为public,是否为abstract,是否为interface等。
类索引、父类索引类索引和父类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。
接口索引集合接口索引集合用于描述这个类实现了哪些接口,这些接口将被初始化到一个列表中。
字段表字段表用于描述接口或类中声明的变量,变量包括类级别的类变量,还有就是实例变量,没有方法体中的局部变量。
方法表方法表用于描述类或接口中声明的方法。
属性表属性表用于描述某个类,方法和字段的附加信息。比如,可以设置一个字段是否被废弃(Deprecated);还可以设置方法的字节码等。

每个部分都承担着其自身的职责,真正让Java有"一次编写,到处运行"特性的就是字节码,字节码是存储在方法表的code属性里的。

以下是一个简单的Java程序示例,我们将逐步解析其生成的Class文件各部分:

public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, World!");}
}

编译上述Java程序会得到一个HelloWorld.class文件,这个文件包含了字节码和其它相关信息。我们使用JDK自带的javap工具来解析这个Class文件:

javap -verbose HelloWorld

以下是解析结果的一部分:

Classfile /C:/HelloWorld.classLast modified Mar 11, 2021; size 434 bytesMD5 checksum 63bf0338975b5720bf154f48d8a5db14
public class HelloWorldminor version: 0major version: 59flags: (0x0021) ACC_PUBLIC, ACC_SUPERthis_class: #7                          // HelloWorldsuper_class: #2                         // java/lang/Objectinterfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:#1 = Methodref          #2.#3          // java/lang/Object."<init>":()V#2 = Class              #4             // java/lang/Object#3 = NameAndType        #5:#6          // "<init>":()V#4 = Utf8               java/lang/Object#5 = Utf8               <init>#6 = Utf8               ()V#7 = Class              #8             // HelloWorld#8 = Utf8               HelloWorld#9 = Utf8               Code#10 = Methodref          #11.#12        // java/lang/System.out:Ljava/io/PrintStream;#11 = Class              #13            // java/lang/System#12 = NameAndType        #14:#15        // out:Ljava/io/PrintStream;#13 = Utf8               java/lang/System#14 = Utf8               out#15 = Utf8               Ljava/io/PrintStream;#16 = String             #17            // Hello, World!#17 = Utf8               Hello, World!#18 = Methodref          #19.#20        // java/io/PrintStream.println:(Ljava/lang/String;)V#19 = Class              #21            // java/io/PrintStream#20 = NameAndType        #22:#23        // println:(Ljava/lang/String;)V#21 = Utf8               java/io/PrintStream#22 = Utf8               println#23 = Utf8               (Ljava/lang/String;)V#24 = Utf8               main#25 = Utf8               ([Ljava/lang/String;)V#26 = Utf8               SourceFile#27 = Utf8               HelloWorld.java#28 = Utf8               LineNumberTable#29 = Utf8               LocalVariableTable#30 = Utf8               this#31 = Utf8               LHelloWorld;#32 = Utf8               args#33 = Utf8               [Ljava/lang/String;
{public HelloWorld();descriptor: ()Vflags: (0x0001) ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 1: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   LHelloWorld;public static void main(java.lang.String[]);descriptor: ([Ljava/lang.String;)Vflags: (0x0009) ACC_PUBLIC, ACC_STATICCode:stack=2, locals=1, args_size=10: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #16                 // String Hello, World!5: invokevirtual #18                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: returnLineNumberTable:line 3: 0line 4: 8LocalVariableTable:Start  Length  Slot  Name   Signature0       9     0  args   [Ljava/lang/String;
}
SourceFile: "HelloWorld.java"

从中我们可以看到:

  • 魔数、版本号:javap工具并未直接显示,但我们知道每个Class文件的开头四个字节就是魔数,而紧接着的4个字节代表版本号。

  • 常量池:在"Constant pool"部分,包含了本程序中所使用到的各种常量和符号引用。

  • 访问标志:在"flags"部分显示,ACC_PUBLIC表示这是一个public类,ACC_SUPER是Java编译器为了支持某些编译优化而设定的。

  • 在这里插入图片描述

  • 类索引、父类索引:在"this_class"和"super_class"部分显示,分别表示这个类自身和其父类在常量池中的索引。

  • 接口索引集合:本例没有实现任何接口,所以此部分为空。

  • 字段表:本例没有定义任何字段,所以此部分为空。

  • 方法表:在"Code"部分可以看到两个方法的字节码,一个是默认的构造函数<init>,一个是我们定义的main方法。

  • 属性表:在"SourceFile"部分显示,表示这个Class文件对应的源文件名。

3. Class文件的详细解析

在这里插入图片描述

3.1 魔数与版本号的作用和意义

魔数(Magic Number)是用来标识文件格式的一种约定,Java Class文件的魔数是0xCAFEBABE。当Java虚拟机加载Class文件时,首先会检查这个魔数,如果不是0xCAFEBABE,那么JVM会拒绝加载这个文件。

版本号(Version Number)包括主版本号和次版本号,主版本号变化通常代表JVM做了不兼容的修改,次版本号变化则表示JVM做了向后兼容的修改。JVM在加载Class文件时,也会检查版本号,如果文件的版本高于JVM的版本,那么JVM会拒绝加载这个文件。

3.2 常量池的结构和作用

常量池(Constant Pool)是Java Class文件结构的一个重要部分,它主要存储两类常量:字面量(Literal)和符号引用(Symbolic Reference)。字面量包括文本字符串、声明为final的常量值等;符号引用则包括类和接口的全限定名、字段的名称和描述符、方法的名称和描述符等。

常量池的主要作用是为Java Class文件中的字面量和符号引用提供统一的存储空间,当Java虚拟机执行Class文件中的字节码时,会使用到常量池中的数据。

3.3 访问标志的含义和可能的值

访问标志(Access Flags)用于标识类或接口的访问权限和特性。如public(0x0001)、final(0x0010)、super(0x0020)、interface(0x0200)、abstract(0x0400)等。

3.4 类索引、父类索引和接口索引集合的作用和构成

类索引、父类索引和接口索引集合用于确定类的继承关系。类索引代表当前类,父类索引代表当前类的直接父类,接口索引集合代表当前类实现的所有接口。

3.5 字段表和方法表

字段表(Field Table)用于描述类或接口中声明的变量,包括字段的名称、描述符、访问标志等信息。方法表(Method Table)用于描述类或接口中声明的方法,包括方法的名称、描述符、访问标志、字节码等信息。

3.6 属性表的详细解析

属性表(Attribute Table)用于描述类、字段和方法的附加信息,例如源文件名(SourceFile)、字段的常量值(ConstantValue)、方法的字节码(Code)、已废弃信息(Deprecated)等。不同的属性有不同的内部结构,但都遵循“属性名索引-属性长度-属性信息”这样的基本格式。

4. Class文件在JVM中的角色

4.1 Class文件在JVM中的生命周期

Java虚拟机(JVM)对Class文件的处理可以分为以下几个阶段:

  1. 加载(Loading): 在这个阶段,JVM从本地磁盘、网络或者其他来源加载.class文件。加载完成之后,JVM将会创建一个表示这个类的java.lang.Class对象。

  2. 验证(Verification): 为了确保Class文件的正确性,JVM会对加载进来的字节码文件进行严格的验证,包括文件格式验证、元数据验证、字节码验证、符号引用验证等。如果验证失败,JVM将抛出java.lang.VerifyError异常。

  3. 准备(Preparation): 在这个阶段,JVM会为类变量(static变量)分配内存,并设置类变量的初始值。同时,JVM还会为类的方法表、接口表等分配内存。

  4. 解析(Resolution): 这个阶段主要执行符号引用到直接引用的转换。JVM将会解析类中的方法、字段、类、接口等的符号引用,将其替换为直接引用。

  5. 初始化(Initialization): 初始化阶段主要执行类构造器<clinit>方法,以及静态变量的赋值操作。这个阶段会确保类的初始化过程是线程安全的。

  6. 使用(Using): 类成功加载、验证、解析和初始化之后,就可以被程序使用了。这时,程序可以创建类的实例、调用方法、访问字段等。

  7. 卸载(Unloading): 当类不再被引用,并且在垃圾收集器运行后被标记为可回收时,JVM会卸载这个类。此时,JVM会释放与类相关的所有内存资源。

4.2 JVM是如何加载和使用Class文件的

JVM使用类加载器(ClassLoader)来加载和管理Class文件。类加载器负责将Class文件的字节码加载到内存中,并且执行验证、准备、解析等操作。在这个过程中,类加载器还会处理类之间的依赖关系,保证类的正确加载。

当程序需要使用一个类时,类加载器会首先查找是否已经加载过这个类。如果没有加载过,类加载器会根据类的全限定名(包名+类名)加载类的字节码,然后执行整个生命周期的操作。

一旦类被加载到JVM中,它就可以被程序使用。程序可以通过创建类的实例、调用方法、访问字段等方式使用这个类。

4.3 Class文件在动态链接、加载和运行机制中的作用

Class文件是Java程序在JVM中的载体。它包含了类的所有信息,包括类的属性、方法、常量池等。在Java程序执行的过程中,JVM通过动态链接、加载和运行机制来管理和使用Class文件。

  • 动态链接:JVM在运行时将符号引用替换为直接引用的过程称为动态链接。Class文件中的符号引用包括方法引用、字段引用、类引用等。动态链接保证了Java代码可以在不同的环境下运行。

  • 加载:JVM通过类加载器将Class文件加载到内存中。在这个过程中,JVM会执行验证、准备、解析等操作,确保类的正确性和可用性。

  • 运行:加载完成的Class文件可以被程序使用。在运行期间,JVM会执行类的方法、访问字段、创建实例等操作。同时,JVM还会处理异常、垃圾回收等任务,保证程序的正常运行。

5. javap 命令详解

在上面的示例介绍中我们使用了一个命令

javap -verbose HelloWorld

那么我单独拉出来,给大家聊一下这个命令的作用。

javap 是Java虚拟机自带的反编译工具,用于从命令行解析class文件,打印出字节码、常量、构造方法、函数等等的信息。以下是javap命令的一些常用选项:

  • -help:查看帮助文档
  • -version:输出javap的版本信息
  • -v-verbose:详细输出,输出额外的更为详细的信息,比如常量池信息、版本信息、字节码指令等
  • -l:输出行号和本地变量表
  • -public:只显示public的类和成员
  • -protected:只显示protected的类和成员
  • -package:只显示package的类和成员
  • -private:显示所有的类和成员
  • -c:对代码进行反汇编
  • -s:输出内部类型签名
  • -sysinfo:用于输出系统信息,包括主版本号、次版本号等
  • -constants:显示最终常量

也可以混合使用多个选项,如javap -private -c HelloWorld可以显示HelloWorld中所有的类和成员,以及反汇编出的字节码。

假设我们有以下的一个简单的Java类HelloWorld.java

public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, world!");}
}

首先,我们需要使用javac命令编译这个Java文件,生成对应的Class文件:

javac HelloWorld.java

然后,我们就可以使用javap命令查看生成的Class文件的内容了。我们先只查看Class文件的概述:

javap HelloWorld

输出如下:

Compiled from "HelloWorld.java"
public class HelloWorld {public HelloWorld();public static void main(java.lang.String[]);
}

这里我们可以看到,javap默认输出了Class文件的类名,以及其中的方法。

接下来,我们使用 -v 参数打印Class文件的详细内容:

javap -v HelloWorld

输出如下:

Classfile /path/to/HelloWorld.classLast modified Apr 15, 2021; size 455 bytesMD5 checksum 9d422a48a6a88f5c6ed5d6eb7cce5015Compiled from "HelloWorld.java"
public class HelloWorldminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Methodref          #4.#10         // java/lang/Object."<init>":()V#2 = Fieldref           #11.#12        // java/lang/System.out:Ljava/io/PrintStream;#3 = String             #13            // Hello, world!#4 = Class              #14            // java/lang/Object#5 = Class              #15            // HelloWorld#6 = Methodref          #16.#17        // java/io/PrintStream.println:(Ljava/lang/String;)V......

这个输出包含了HelloWorld Class文件的很多详细信息,如版本号、访问标志、常量池等等。例如,我们可以在常量池中看到Hello, world!这个字符串常量。

6. 十六进制编辑器 010 Editor 查看Class 文件

参考 https://bbs.kanxue.com/thread-257797.htm
参考 https://blog.csdn.net/freeking101/article/details/102908538

在这里插入图片描述
以下是您可以手动应用模板的方法,以防文件扩展名不是原始扩展名

在这里插入图片描述
这是模板结果的样子:

在这里插入图片描述
在十六进制/ASCII转储下方,显示了模板结果:一组嵌套字段,与.class文件的内部结构相匹配。例如,我在这里选择的第一个字段是u4 magic,它是一个.class文件的魔数标头:CAFEBABE。
在这里插入图片描述

7. 使用jclasslib 工具查看字节码

jclasslib 是一个功能丰富的字节码查看器,用于查看和分析 Java class 文件的结构。

  1. 下载和安装 jclasslib

官网 https://jclasslib.org/ 免费开源

  1. 打开 jclasslib

    安装完成后,打开 jclasslib。会看到一个简洁的界面。
    在这里插入图片描述
    在这里插入图片描述

  2. 打开 class 文件

    点击菜单栏的 File > Open... 选项,浏览的文件系统找到要查看的 .class 文件,选择它然后点击 Open

    或者,也可以直接把 .class 文件拖拽到 jclasslib 的窗口中。
    在这里插入图片描述

  3. 查看字节码

    成功打开 .class 文件后,会在左侧看到一个树形结构,表示了 .class 文件的结构。可以点击树形结构的各个节点查看详细的信息。

    右侧的窗口会根据选中的节点显示对应的详细信息。例如,如果选中了 constant_pool 节点,右侧就会显示常量池的所有内容。

    jclasslib 还提供了一个 Hex viewer 选项卡,可以在这里查看每个节点的原始字节码。

8.参考文档

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html

相关文章:

JVM之class文件结构剖析

文章目录 0.前言1. 引言1.1 Java编译原理基础1.2 Class文件在Java编译过程中的角色 2. Class文件的整体结构2.1 Class 文件组成 3. Class文件的详细解析3.1 魔数与版本号的作用和意义3.2 常量池的结构和作用3.3 访问标志的含义和可能的值3.4 类索引、父类索引和接口索引集合的作…...

TDengine 签约中石化,支撑八大油田 PCS 系统

近日&#xff0c;TDengine 成功签约中国石化 PCS 一级部署时序数据库项目。未来&#xff0c;TDengine 将作为中国石化 PCS 系统的时序数据库&#xff0c;为石化总部、胜利油田、西北油田、中原油田、河南油田、华北油田、江苏油田、华东油田、江汉油田等油田 PCS 系统提供高效、…...

win11 定时计划任务

控制面板 任务计划 添加任务计划 &#xff0c;选按步骤添加。...

C++入门之引用与内联函数

一、引用 1、初步理解 引用在语法上的理解就是起别名&#xff0c;用法就是在类型后面加&&#xff0c;例子&#xff1a;int a 1; int& b a; 上例所示&#xff0c;执行后&#xff0c;b就是a的别名&#xff0c;它们代表同一块空间&#xff0c;a的改变会影响b&#xff0…...

浅谈智能照明控制系统应用在城市轨道交通

叶根胜 江苏安科瑞电器制造有限公司 江苏江阴 214405 摘要&#xff1a;在传统的城市轨道交通设计方面&#xff0c;照明设计方案具有一定的弊端。随着计算机技术的发展&#xff0c;智能化技术渐渐步入人们的生活并成为主流&#xff0c;故在城市轨道交通中应用新型的照明控制设…...

macos 中ios系统升级,但是macos还是老系统,在手机上无法安装ios软件

https://github.com/filsv/iOSDeviceSupport 构建项目出现 解决的方法&#xff1a; 就可以了&#xff0c;...

Pytest+Allure生成可添加附件的测试报告

#测试套件层级 allure.feature("测试PecExplorer") #重试次数&#xff0c;粒度为用例&#xff0c;建议用例设计可重复性高 pytest.mark.flaky(reruns3) class TestPecExplorer:#功能模块层级allure.story("登录界面")#测试用例层级allure.title("Test…...

Spacedrive:开源跨平台文件管理 | 开源日报 No.57

denoland/deno Stars: 91.2k License: MIT Deno 是一个简单、现代和安全的 JavaScript 和 TypeScript 运行时&#xff0c;使用 V8 引擎并用 Rust 构建。其主要功能包括&#xff1a; 默认情况下具有高度安全性&#xff0c;除非显式启用&#xff0c;否则无法访问文件、网络或环…...

c# 同步异步锁

在 C# 中&#xff0c;synchronization&#xff08;同步&#xff09;和asynchronization&#xff08;异步&#xff09;锁都是用来保护共享资源的。在单线程环境中&#xff0c;这些锁不是必要的&#xff0c;但在多线程环境中&#xff0c;由于多个线程可以访问和修改同一资源&…...

【Spring AOP】统⼀数据返回格式

为什么需要统一数据返回格式&#xff1f; ⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据。降低前端程序员和后端程序员的沟通成本&#xff0c;按照某个格式实现就⾏了&#xff0c;因为所有接⼝都是这样返回的。有利于项⽬统⼀数据的维护和修改。有利于后端技术部⻔的…...

python+django高校体育乒乓球场地预约管理系统_s2409

本系统提供给管理员对首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;乒乓球场管理,场地类型管理,场地预约管理,暂离申请管理,离开申请管理,管理员管理,留言反馈,系统管理等诸多功能进行管理。本系统对于用户输入的任何信息都进行了一定的验证&#xff0c;为管理员操…...

Python Selenium设计模式-POM

前言本文就python selenium自动化测试实践中所需要的POM设计模式进行分享&#xff0c;以便大家在实践中对POM的特点、应用场景和核心思想有一定的理解和掌握。 为什么要用POM 基于python selenium2开始UI级自动化测试并不是多么艰巨的任务。**只需要定位到元素&#xff0c;执…...

【计算机毕设选题推荐】网络在线考试系统SpringBoot+SSM+Vue

前言&#xff1a;我是IT源码社&#xff0c;从事计算机开发行业数年&#xff0c;专注Java领域&#xff0c;专业提供程序设计开发、源码分享、技术指导讲解、定制和毕业设计服务 项目名 网络在线考试系统 技术栈 SpringBootSSMVueMySQLMaven 文章目录 一、网络在线考试系统-环境…...

AUTOSAR汽车电子嵌入式编程精讲300篇-基于FPGA的LIN总线控制器设计与验证(续)

目录 3.2.3波特率发生模块 3.2.4数据采样模块 3.2.5校验和产生模块 3.2.6奇偶校验模块 3.2.7接收模块<...

Qt ModelView显示数据库数据

利用qt的model view来显示数据表userudps里的数据 用了一个label 两个combox和一个tableview&#xff0c;实现如下效果&#xff1a; 我这里用到是mysql数据库&#xff0c;一般配置mysql数据库就两种有驱动或者没驱动&#xff0c;有的话把mysql的bin目录的libmysql.dll复制到q…...

Vue-3.1缓存组件keep-alive

问题&#xff1a;从首页卡片点到详情页&#xff0c;又点返回&#xff0c;数据重新加载了->希望回到原来的位置 原因&#xff1a;路由跳转后&#xff0c;组件被销毁了&#xff0c;返回回来组件又被重建了&#xff0c;所以数据重新被加载了 解决&#xff1a;利用keep-alive将…...

14.8 Socket 一收一发通信

通常情况下我们在编写套接字通信程序时都会实现一收一发的通信模式&#xff0c;当客户端发送数据到服务端后&#xff0c;我们希望服务端处理请求后同样返回给我们一个状态值&#xff0c;并以此判断我们的请求是否被执行成功了&#xff0c;另外增加收发同步有助于避免数据包粘包…...

7天狂揽 1.3w star 的 MetaGPT,他们的目标让软件公司为之一惊

在 AI 产品爆炸的今天&#xff0c;拥有各种本领的 AI 产品层出不穷&#xff0c;但 MetaGPT 的出现仍然显的格外耀眼&#xff0c;其可以实现只输入单一 prompt&#xff0c;就可以输出需求分析、需求文档、技术架构、最终代码等等产物&#xff0c;这相当于一个开发团队的输出成果…...

工控网络协议模糊测试:用peach对modbus协议进行模糊测试

0x00 背景 本人第一次在FB发帖&#xff0c;进入工控安全行业时间不算很长&#xff0c;可能对模糊测试见解出现偏差&#xff0c;请见谅。 在接触工控安全这一段时间内&#xff0c;对于挖掘工控设备的漏洞&#xff0c;必须对工控各种协议有一定的了解&#xff0c;然后对工控协议…...

python+opencv+机器学习车牌识别 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于机器学习的车牌识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;3分 该项目较为新颖&#xff0c;适…...

魔域服务端数据库说明

Magic.DB MagID: 魔法ID Mag:Magic MagName: 魔法名称 EffectType: 效果类型 Effect: 效果 Spell: 魔力&#xff08;魔法值&#xff09; Power: 能力&#xff0c;力量 MaxPower: 最大能力 DefSpell: 变化后的魔力Def&#xff1a;deformation DefPower: 变化后能力 DefMaxPower:…...

笔记本无线网卡MAC一直改动

今天在网管处把我无线网卡的MAC地址添加后&#xff0c;回来链接无线网却一直显示网络链接失败&#xff0c;以为是自己的驱动问题&#xff0c;去官网下载了最新的驱动结果依然无法链接。之前在家或者公共场合链接WiFi从来没有出现过类似情况。 百思不得其解之际发现自己的无线网…...

【Tomcat】Apache发布两个新版本Tomcat修复多个Bug

Apache 官网发布了两个最新的 Tomcat 版本包&#xff0c;分别是&#xff1a;8.5.94、9.0.81 这两个最新版本修复了多个漏洞&#xff0c;统计信息如下表所示。有关漏洞的详细信息&#xff0c;请查阅官方相关文档&#xff08;见&#xff1a;参考&#xff09;。 严重等级漏洞说明…...

Empowering Low-Light Image Enhancer through Customized Learnable Priors 论文阅读笔记

中科大、西安交大、南开大学发表在ICCV2023的论文&#xff0c;作者里有李重仪老师和中科大的Jie Huang&#xff08;ECCV2022的FEC CVPR2022的ENC和CVPR2023的ERL的一作&#xff09;喔&#xff0c;看来可能是和Jie Huang同一个课题组的&#xff0c;而且同样代码是开源的&#xf…...

LeetCode 2652. 倍数求和【数学,容斥原理】简单

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

ansible-playbook剧本

一&#xff0c;playbook组成&#xff1a; &#xff08;1&#xff09;Tasks&#xff1a;任务&#xff0c;即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 &#xff08;2&#xff09;Variables&#xff1a;变量 &#xff08;3&#xff09;Templates&…...

竞赛选题 深度学习LSTM新冠数据预测

文章目录 0 前言1 课题简介2 预测算法2.1 Logistic回归模型2.2 基于动力学SEIR模型改进的SEITR模型2.3 LSTM神经网络模型 3 预测效果3.1 Logistic回归模型3.2 SEITR模型3.3 LSTM神经网络模型 4 结论5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 …...

机械设计师应该在工作中培养哪些良好习惯?

图纸规范 1、一定要按照制图标准设计图纸&#xff01;图纸上任何一条直线&#xff08;无论是点划线、粗实线、细实线等等&#xff09;、数值、公差、图标等&#xff0c;都必须有理有据&#xff0c;不能想当然。图纸是产品生产的基础&#xff0c;无论是生产、加工、装配&#x…...

小程序新增功能页面

需求背景: 小程序主页面有个报名板块,我打算替换主页面报名板块菜单,迁移到我的页面里面, 替换成资讯栏目,我喜欢分享最新技术,开源课题,IT资讯,本想做成论坛的效果,由于时间问题,先替换添加板块 替换后效果: 模块功能: 添加、修改、删除、查看 文件目录:// 添…...

LeetCode每日一题——2652. Sum Multiples

文章目录 一、题目二、题解 一、题目 Given a positive integer n, find the sum of all integers in the range [1, n] inclusive that are divisible by 3, 5, or 7. Return an integer denoting the sum of all numbers in the given range satisfying the constraint. E…...

Python问答题(更新中)

1. 列表&#xff08;list&#xff09;和元组&#xff08;tuple&#xff09;有什么区别&#xff1f; 列表是可变的&#xff0c;创建后可以对其进行修改&#xff1b;元组是不可变的&#xff0c;元组一旦创建&#xff0c;就不能对其进行更改。列表表示的是顺序。它们是有序序列&a…...

服务器中了locked勒索病毒怎么办,勒索病毒解密,数据恢复

最近一段时间内&#xff0c;相信很多使用金蝶或用友的办公软件的企业&#xff0c;有很多都经历了locked勒索病毒的攻击&#xff0c;导致企业服务器被加密无法正常使用&#xff0c;严重影响了企业的正常工作。通过云天数据恢复中心的解密恢复发现&#xff0c;在今年locked勒索病…...

游游的字母串 (环形数组两点之间的位置)

题目链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例&#xff1a; 输入 yab 输出 3 思路&#xff1a; 暴力枚举&#xff0c;全部变成对应的26个字母字符需要的操作步数&#xff0c;取最少的一个操作步数&#xff0c; 这里的操作步数&#xff0…...

Flink的ResourceManager详解(一)

ResourceManager 总结 一、概述 1、ResourceManager 管理 Flink 集群中的计算资源&#xff0c;计算资源主要来自 TaskManager 组件。 2、如果集群采用 Native【本地模式】部署&#xff0c;则 ResourceManager 会动态地向集群资源管理器申请 Container 并启动TaskManager&…...

Tornado 可以使用 nginx 提供负载均衡

Tornado和nginx都是网络服务器的重要组成部分&#xff0c;但它们在职能和使用场景上存在显著的差异。 Tornado可以独立运行&#xff0c;而不需要依赖nginx等其他Web服务器。这是因为Tornado本身就是一个完整的Web服务器&#xff0c;可以独立处理HTTP请求并返回响应数据。 ngi…...

Golang 面向对象编程 多态

基本介绍 变量(实例)具有多种形态。面向对象的第三大特征&#xff0c;在Go语言&#xff0c;多态特征是通过接口实现的&#xff08;接口能够体现多态的特征&#xff09;。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态。 在前面的Usb接口案例&#xff0c;u…...

WLAN 无线案例(华为AC控制器配置模板)

实验说明&#xff1a; 无线用户VLAN 30 192.168.30.0/24 AP和AC用VLAN 20 192.168.20.0/24 有线网段 VLAN 10 192.168.10.0/24 步骤一&#xff1a;全网互通 sw1&#xff1a; sysname sw1 # vlan batch 10 20 30 # dhcp enable # ip pool 20 gateway-list 192.168.20.1…...

精美的早安问候语,暖心祝福,开心每一天

1、 美好的祝福&#xff0c;成了清晨的主题。相互问候&#xff0c;是一天的开始。让我们伴着不老的岁月&#xff0c;永远开心快乐。早晨好&#xff01; 2、 心宽似海&#xff0c;百福皆来&#xff0c;世事看淡&#xff0c;内心安然。随缘即福&#xff0c;随遇而安&#xff0…...

嵌入式养成计划-41----C++ auto--lambda表达式--C++中的数据类型转换--C++标准模板库(STL)--list--C++文件操作

九十九、auto 99.1 概念 C11引入了自动类型推导&#xff0c;和Python不一样&#xff0c;C中的自动类型推导&#xff0c;需要auto关键字来引导比如 &#xff1a;auto a 1.2; 会被编译器自动识别为 a 为 double 类型 99.2 作用 auto修饰变量&#xff0c;可以自动推导变量的数…...

全局事件总线

全局事件总线 功能&#xff1a;可以解决所有组件之间通信传数据的问题原理&#xff1a;通过一个共享对象&#xff0c;将所有组件全部绑定到对象上&#xff0c;即可通过这个对象实现组件与组件之间的传递数据&#xff0c;而这个共享对象叫做全局事件总线。 如何分清楚谁是发送方…...

通讯网关软件026——利用CommGate X2ORACLE-U实现OPC UA数据转入ORACLE

本文介绍利用CommGate X2ORACLE-U实将OPC UA数据源中的数据转入到ORACLE数据库。CommGate X2ORACLE-U是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;将OPC UA数据源的数据写入到ORACLE数据…...

RAII与智能指针

RAII与智能指针 1.RAII1.1RAII理解1.2RAII的原理1.2.1简单的例子说明局部对象的自动销毁的特性 1.2.2 RAII 过程 2.智能指针2.1 auto_ptr2.1.1auto_ptr的使用构造函数与析构函数拷贝构造函数与赋值提领操作auto ptr其它函数 2.1.2autoptr使用的注意事项 2.2 unique_ptr2.2.1uni…...

易云维智慧工业云平台助力广西国企培育数字产业化平台,打造数字化产业生态

2022年6月6日&#xff0c;广西壮族自治区人民政府国有资产监督管理委员会出台了《国有企业数字化转型工作实施意见》&#xff0c;明确了总体要求、主要目标、重点推进国有企业数字化转型的任务和保障措施。 《意见》预计&#xff0c;到2025年底&#xff0c;广西基本实现自治区级…...

【密码学】第三章、分组密码

DES、IDEA、AES、SM4 1、分组密码定义&#xff08;按照五个组成部分答&#xff09; 密钥空间&#xff1a;属于对称加密算法kekd明密文空间&#xff1a;将明文划分为m比特的组&#xff0c;每一块依次进行加密加解密算法&#xff1a;由key决定一个明文到密文的可逆映射 2、发展…...

宁夏企业过等保选哪家测评机构好?选哪家堡垒机好?

最近不少宁夏小伙伴在问&#xff0c;宁夏企业过等保选哪家测评机构好&#xff1f;选哪家堡垒机好&#xff1f;今天我们小编就给大家来简单说说哈&#xff01; 宁夏企业过等保选哪家测评机构好&#xff1f; 目前宁夏正规具有资质的等保测评机构只有3家&#xff0c;分别为中电信…...

Vue绑定style和class 对象写法

适用于&#xff1a;要绑定多个样式&#xff0c;个数确定&#xff0c;名字也确定&#xff0c;但不确定用不用。 绑定 class 样式【对象写法】&#xff1a; .box{width: 100px;height: 100px; } .aqua{background-color: aqua; } .border{border: 20px solid red; } .radius{bor…...

使用vue-sign插件

Vue-sign是一个基于Vue.js和Canvas的签名组件&#xff0c;可以轻松地在Vue应用程序中实现签名板或手写签名功能。使用它可以使用户在前端网页上直接进行手写签名&#xff0c;实现更好的用户交互和业务需求。 使用Vue-sign可以提供以下好处&#xff1a; 通过Vue.js框架进行开发…...

python究竟可以用来做些什么

这里就不撰述python的一些像什么“高级语言”之类的比较常规的介绍了&#xff0c;还是老样子&#xff0c;说说一些比较常用的东西吧。 python是什么 python&#xff0c;一款可编程的开源软件&#xff0c;很多第三方库、框架也是开源的&#xff0c;比如强大的anaconda、sklear…...

Segment Anything(论文解析)

Segment Anything 摘要1.介绍2 SAM任务SAM模型 摘要 我们介绍了“Segment Anything” (SA) 项目&#xff1a;这是一个新的任务、模型和数据集对于图像分割。使用我们高效的模型进行数据收集&#xff0c;我们构建了迄今为止最大的分割数据集&#xff08;远远超过其他数据集&…...

@ConditionalOnProperty 用法

文章目录 前言一、使用场景二、使用步骤1.错误示例2.ConditionalOnProperty的解决方案 总结 前言 ConditionalOnProperty 是Spring Boot中的条件注解&#xff0c;它的核心功能是通过属性名以及属性值来实现的&#xff0c;常被用于判断某个属性是否存在&#xff0c;然后决定某个…...