【茫茫架构路】1. Class File字节码文件解析
本文所有内容的JDK版本为 OpenJDK 11
JDK11 Class File官方说明。
Java解析字节码文件源码参考,以下为部分字节码解析源码展示。
public ClassFile(DataInputStream in) {try {//magic: 0xCAFEBABEthis.magic = ClassReader.readInt(in);System.out.println("magic: >>> " + this.magic);this.minorVersion = ClassReader.readUnsignedShort(in);System.out.println("minorVersion: >>> " + this.minorVersion);this.majorVersion = ClassReader.readUnsignedShort(in);System.out.println("majorVersion: >>> " + this.majorVersion);this.constantPoolCount = ClassReader.readUnsignedShort(in);System.out.println("constantPoolCount: >>> " + this.constantPoolCount);this.constantPool = new ConstantPoolInfo[this.constantPoolCount];for (int i = 1; i < this.constantPoolCount; i++) {ConstantPoolInfo cp = ConstantPoolFactory.getCp(in);this.constantPool[i] = cp;System.out.println("constantPool[" + i + "]: " + cp.getClass().getSimpleName() + " >>> " + JSONObject.toJSONString(cp));}this.accessFlags = ClassReader.readUnsignedShort(in);System.out.println("\naccessFlags: >>> " + this.accessFlags);//this class name index in constant poolthis.thisClass = ClassReader.readUnsignedShort(in);System.out.println("thisClass: >>> " + this.thisClass);//super class name index in constant poolthis.superClass = ClassReader.readUnsignedShort(in);System.out.println("superClass: >>> " + this.superClass);//interface countthis.interfaceCount = ClassReader.readUnsignedShort(in);System.out.println("interfaceCount: >>> " + this.interfaceCount);this.interfaces = new int[this.interfaceCount];for (int i = 0; i < this.interfaceCount; i++) {int f = ClassReader.readUnsignedShort(in);this.interfaces[i] = f;System.out.println("interfaces[" + i + "] >>> " + f);}//field countthis.fieldCount = ClassReader.readUnsignedShort(in);System.out.println("fieldCount: >>> " + this.interfaceCount);this.fields = new Field[this.fieldCount];for (int i = 0; i < this.fieldCount; i++) {Field field = new Field(in);this.fields[i] = field;System.out.println("fields[" + i + "] >>> " + JSONObject.toJSONString(field));}} catch (IOException e) {e.printStackTrace();}}
Java 虚拟机不与包括 Java 语言在内的任何程序语言绑定,它只与" Class 文件"这种特定的二进制文件格式所关联, Class 文件中包含了 Java 虚拟机指令集
、符号表
以及若干其他辅助信息
。基于安全方面的考虑,《 Java 虚拟机规范》中要求在 Class 文件必须应用许多强制性的语法和结构化约束。作为一个通用的、与机器无关的执行平台,任何其他语言的实现者都可以将 Java 虚拟机作为他们语言的运行基础,以 Class 文件作为他们产品的交付媒介。
根据《Java虚拟机规范》的规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构只有两种数据类型:**无符号数**
和**表**
。
- 无符号数:以u1、u2、u4、u8来分别代表一个、两个、四个、八个字节的无符号数。无符号数可以用来描述数字、索引引用、数量值或者按照UTF8编码构成的字符串值。
- 表:由多个或者其他表作为数据项构成的复合数据类型。有点类似于Java中所说的对象。
ClassFile {u4 magic;u2 minor_version;u2 major_version;u2 constant_pool_count;cp_info constant_pool[constant_pool_count-1];u2 access_flags;u2 this_class;u2 super_class;u2 interfaces_count;u2 interfaces[interfaces_count];u2 fields_count;field_info fields[fields_count];u2 methods_count;method_info methods[methods_count];u2 attributes_count;attribute_info attributes[attributes_count];
}
Test.java
是我们一个测试文件,生成的字节码文件见紧邻的代码块内容。
public class Test {private Integer variable;public static void main(String[] args) throws Exception {System.out.println("Hello World.");}
}
ca fe ba be 00 00 00 37 00 27 0a 00 06 00 18 09 |.......7.'......|
00 19 00 1a 08 00 1b 0a 00 1c 00 1d 07 00 1e 07 |................|
00 1f 01 00 08 76 61 72 69 61 62 6c 65 01 00 13 |.....variable...|
4c 6a 61 76 61 2f 6c 61 6e 67 2f 49 6e 74 65 67 |Ljava/lang/Integ|
65 72 3b 01 00 06 3c 69 6e 69 74 3e 01 00 03 28 |er;...<init>...(|
29 56 01 00 04 43 6f 64 65 01 00 0f 4c 69 6e 65 |)V...Code...Line|
4e 75 6d 62 65 72 54 61 62 6c 65 01 00 12 4c 6f |NumberTable...Lo|
63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 |calVariableTable|
01 00 04 74 68 69 73 01 00 0e 4c 74 6f 64 6f 50 |...this...LtodoP|
6b 67 2f 54 65 73 74 3b 01 00 04 6d 61 69 6e 01 |kg/Test;...main.|
00 16 28 5b 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 |..([Ljava/lang/S|
74 72 69 6e 67 3b 29 56 01 00 04 61 72 67 73 01 |tring;)V...args.|
00 13 5b 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 |..[Ljava/lang/St|
72 69 6e 67 3b 01 00 0a 45 78 63 65 70 74 69 6f |ring;...Exceptio|
6e 73 07 00 20 01 00 0a 53 6f 75 72 63 65 46 69 |ns.. ...SourceFi|
6c 65 01 00 09 54 65 73 74 2e 6a 61 76 61 0c 00 |le...Test.java..|
09 00 0a 07 00 21 0c 00 22 00 23 01 00 0c 48 65 |.....!..".#...He|
6c 6c 6f 20 57 6f 72 6c 64 2e 07 00 24 0c 00 25 |llo World...$..%|
00 26 01 00 0c 74 6f 64 6f 50 6b 67 2f 54 65 73 |.&...todoPkg/Tes|
74 01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 |t...java/lang/Ob|
6a 65 63 74 01 00 13 6a 61 76 61 2f 6c 61 6e 67 |ject...java/lang|
2f 45 78 63 65 70 74 69 6f 6e 01 00 10 6a 61 76 |/Exception...jav|
61 2f 6c 61 6e 67 2f 53 79 73 74 65 6d 01 00 03 |a/lang/System...|
6f 75 74 01 00 15 4c 6a 61 76 61 2f 69 6f 2f 50 |out...Ljava/io/P|
72 69 6e 74 53 74 72 65 61 6d 3b 01 00 13 6a 61 |rintStream;...ja|
76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 |va/io/PrintStrea|
6d 01 00 07 70 72 69 6e 74 6c 6e 01 00 15 28 4c |m...println...(L|
6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 |java/lang/String|
3b 29 56 00 21 00 05 00 06 00 00 00 01 00 02 00 |;)V.!...........|
07 00 08 00 00 00 02 00 01 00 09 00 0a 00 01 00 |................|
0b 00 00 00 2f 00 01 00 01 00 00 00 05 2a b7 00 |..../........*..|
01 b1 00 00 00 02 00 0c 00 00 00 06 00 01 00 00 |................|
00 08 00 0d 00 00 00 0c 00 01 00 00 00 05 00 0e |................|
00 0f 00 00 00 09 00 10 00 11 00 02 00 0b 00 00 |................|
00 37 00 02 00 01 00 00 00 09 b2 00 02 12 03 b6 |.7..............|
00 04 b1 00 00 00 02 00 0c 00 00 00 0a 00 02 00 |................|
00 00 0c 00 08 00 0d 00 0d 00 00 00 0c 00 01 00 |................|
00 00 09 00 12 00 13 00 00 00 14 00 00 00 04 00 |................|
01 00 15 00 01 00 16 00 00 00 02 00 17 |.............|
magic
每个Class文件的头4个字节被称为魔数,即0xCAFEBABE,唯一作用就是确定这个文件是否为一个能被虚拟机接收的Class文件。类加载过程中的验证
阶段就会包含此部分的验证。由于大小端差异,可能展示略有不同。
minor_version
魔数后面两个字节0000
是次版本号。
major_version
次版本号后面两个字节0x0037
是主版本号,十进制为55,即Java11对应的版本号。版本号的意义是:高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件。因为《Java虚拟机规范》在Class文件校验部分明确要求了即使文件格式并未发生任何变化,虚拟机也必须拒绝执行超过其版本号的Class文件。
constant_pool_count
接下来的两个字节代表常量池数量0x0027
,十进制为39。与我们的习惯不同,计数是从1开始的而不是0,所以代表我们这个Class文件中有38个常量值,索引范围是1~38。之所以不从0开始,是因为0有特殊考虑,即不引用任何常量池时。
constant_pool
常量池。主要包含两大类常量:符号引用和字面量(又称直接引用)。
- 符号引用:存放常量池索引
- 字面量:常量。
常量池第一个字节为标志位
,0a
即十进制10
,查表速得为CONSTANT_Methodref
。
CONSTANT_Methodref
的结构为:
CONSTANT_Methodref_info {u1 tag;u2 class_index;u2 name_and_type_index;
}
往后读两个字节00 06
即为class_index,该值为常量池的一个索引,表示指向常量池中#6元素。通过jclasslib工具可以知道这是一个CONSTANT_Class
类型的常量池索引,最终指向的class name是一个java/lang/Object
的字符串。
再往后读两个字节00 18
即为name_and_type_index,十进制24,同样是常量池中的一个CONSTANT_NameAndType
类型的索引,指向常量池中#24元素。通过jclasslib工具快速查看一下表示一个名为返回值为void的方法,即Java.lang.Object的初始化方法。
至此第一个常量池变量就解析完了,后面37个依次类推可依次解析完成。
access_flags
在常量池结束之后,紧接着的2个字节代表访问标志(access_flags),这个标志用于识别一些类或者接口层次的访问信息,包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract 类型;如果是类的话,是否被声明为final等等。
0x0021
即为access_flag,即ACC_PUBLIC
和 ACC_SUPER
this_class
this_class用于确定这个类的全限定名。0x0005
表示指向常量池#5号索引。
super_class
super_class用于确定这个类的父类的全限定名,由于Java语言不允许多 重继承,所以父类索引只有一个,除了java.lang.Object之外,所有的Java类都有父类,因此除了 java.lang.Object外,所有Java类的父类索引都不为0。
0x0006
表示指向常量池#6号索引。
interfaces_count
接口计数器(int erfaces _count ),表示索引表 的容量。0x0000
表示指向接口数量为0。如果该类没有实现任何接口,则该计数器值为0,后面接口的索引表不再占用任何字节。
interfaces
接口索引表,每一个item指向常量池索引。由于此测试类没有接口,故而字节码文件缺失该部分内容。
fields_count
字段计数器,值为0x0001
,说明这个类只有一个字段表数据 。
fields
用于描述接口或者类中声明的变量。包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。字段可以包括的修饰符有字段的作用域(public、private、protected修饰符)、是实例变量还是类变量(static修饰符)、可变性(final)、并发可见性(volatile修饰符,是否强制从主内存读写)、可否被序列化(transient修饰符)、字段数据类型(基本类型、对象、数组)、 字段名称。
field_info {u2 access_flags;u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count];
}
access_flags
字段修饰符,0x0002
表示ACC_PRIVATE
name_index
字段名称在常量池的索引,即0x0007
。
descriptor_index
字段和方法描述符在常量池的索引,即0x0008
。
描述符的作用是用来描述字段 的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。根据描述符规则,基本数据类 型(byte、char、double、float、int、long、short、boolean)以及代表无返回值的void类型都用一个大写字符来表示,而对象类型则用字符L加对象的全限定名来表示。
对于数组类型,每一维度将使用一个前置的“ [”字符来描述,如一个定义为“ java.lang.String[][]”类型 的二维数组将被记录成“ [[Ljava/lang/St ring;”,一个整型数组“int []”将被记录成“ [I”。
用描述符来描述方法时,按照先参数列表、后返回值的顺序描述,参数列表按照参数的严格顺序 放在一组小括号“()”之内。如方法void inc()的描述符为“()V”,方法java.lang.String toString()的描述符 为“()Ljava/lang/String;”,方法int indexOf(char[]source,int sourceOffset,int sourceCount,char[]target, int targetOffset,int targetCount,int fromIndex)的描述符为“([CII[CIII)I”。
attributes_count
同下attributes_count
attribute_info
同下attribute_info
methods_count
方法计数器,即0x0002
,表示有两个方法。其实这个测试类中只有一个显示方法,但是大家别忘了还有一个无参构造函数方法<init>
。
methods
Class文件存储 格式中对方法的描述与对字段的描述采用了几乎完全一致的方式,方法表的结构如同字段表一样,依次包括访问标志(access_flags)、名称索引(name_index)、描述符索引(descriptor_index)、属性表集合(attributes)几项。
method_info {u2 access_flags;u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count];
}
access_flags
因为volatile关键字和transient 关键字不能修饰方法,所以方法表的访问标志中没有了 ACC_VOLATILE标志和ACC_TRANSIENT标志。与之相对,synchronized、native、strictfp和abstract 关键字可以修饰方法,方法表的访问标志中也相应地增加了ACC_SYNCHRONIZED、 ACC_NATIVE、ACC_STRICTFP和ACC_ABSTRACT标志。
我们这个测试类中第一个方法字节码access_flags对应0x0001
,即ACC_PUBLIC
。
name_index
方法名称在常量池的索引,即0x0009
。
descriptor_index
方法描述符在常量池的索引,相关说明同字段中的descriptor_index,即0x000a
。
attribute_info
同下attribute_info
attributes_count
同下attribute_info
attributes_count
属性计数器。
attribute_info
属性表(attribute_info)在前面的讲解之中已经出现过数次,Class文件、字段表、方法表都可以
携带自己的属性表集合,以描述某些场景专有的信息。其结构如下。
attribute_info {u2 attribute_name_index;u4 attribute_length;u1 info[attribute_length];
}
attribute_name_index
属性名称在常量池索引。attribute_name_index 处的constant_pool 条目必须是表示属性名称的CONSTANT_Utf8_info 结构。
attribute_length
属性长度。
info
为了能正确解析Class文件,《Java虚拟机规范》最初只预定义了9项所有Java虚拟机实现都应 当能识别的属性,而在最新的《Java虚拟机规范》的Java SE 11版本中,预定义属性已经增加到28项。具体如下。根据attribute_name_index
可以加载到类名称,然后根据反射去找到对应的预定义属性类型进行解析。
字节码文件解析过程对后续**类加载**
以及**字节码增强技术**
都有很大裨益。
相关文章:

【茫茫架构路】1. Class File字节码文件解析
本文所有内容的JDK版本为 OpenJDK 11 JDK11 Class File官方说明。 Java解析字节码文件源码参考,以下为部分字节码解析源码展示。 public ClassFile(DataInputStream in) {try {//magic: 0xCAFEBABEthis.magic ClassReader.readInt(in);System.out.println("m…...

Golang笔记
01 = 和 := 的区别? 前者是赋值变量,后者是定义变量 02 指针的作用 指针指向变量的地址,在64位机器上占8个字节 【1 字节(Byte)= 8 位(bit) 1 千字节(KB,Kilobyte)= 1,024 字节(2^10 字节)】 作用 取址然后取值swap函数 交换变量的值指针接收器来改变结构体里面…...

在Linux上安装RStudio工具并实现本地远程访问【内网穿透】
文章目录 前言1. 安装RStudio Server2. 本地访问3. Linux 安装cpolar4. 配置RStudio server公网访问地址5. 公网远程访问RStudio6. 固定RStudio公网地址 前言 RStudio Server 使你能够在 Linux 服务器上运行你所熟悉和喜爱的 RStudio IDE,并通过 Web 浏览器进行访问…...

leetcode 128. 最长连续序列
2023.10.23 本题思路:遍历所有元素,对当前元素num进行查找:有无元素(num1)、有无元素(num2)......若有则继续查找下去,同时记录最大序列长度,无则遍历下一个元素。 考虑到数组中可能有重复元素需要去重,并且…...

k8s-----4、yaml文件,做资源编排和资源对象部署
yaml文件 1、YAML 文件概述2、YAML 文件书写格式3、资源清单描述方法4、yaml文件编写4.1 没有真正部署资源的过程4.2 资源已经存在的时候 5、yaml文件中必须存在的属性 1、YAML 文件概述 k8s 集群中对资源管理和资源对象编排部署都可以通过声明样式(YAML࿰…...

proteus中仿真arduino的水位测试传感器
一、原理介绍 我们这里使用的水位传感器,只能说是一个小实验用途的水位传感器。我们首先上图 如上图所示,线没有连接,传感器由许5对裸露在外的铜线片作为传感部分,当浸入水中时这些铜线片会被水桥接。 这些被水连接起来的铜线&a…...

设计模式-单例模式 (Singleton)
单例模式 (Singleton) 单例模式是一种创建型设计模式,它确保类只有一个实例,并提供了一种访问该实例的全局方法。这种模式有助于确保系统中的某些组件只有一个实例,并提供了一种方便的方法来访问该实例。 1、单例类只…...

程序包org.apache.ibatis.mapping不存在 符号找不到
找不到符号 符号: 类 Cursor和程序包org.apache.ibatis.mapping不存在 在idea中没有错误,但是在linux编辑时报了这两个错误,之前有遇见过符号找不到的问题, 当时的问题是编译的import xxx.xxx.xxx.* 识别不成功过,将*改为…...

Microsoft Edge浏览器中使用免费的ChatGPT
一、双击打开浏览器 找到:扩展,打开 二、打开Microsoft Edge加载项 三、Move tab新标签 获取免费ChatGPT 四、启用Move tab。启用ChatGPT。 扩展 管理扩展 启用 五、新建标签页,使用GPT 六、使用举例 提问 GPT回复...

Python 框架学习 Django篇 (五) Session与Token认证
我们前面经过数据库的学习已经基本了解了怎么接受前端发过来的请求,并处理后返回数据实现了一个基本的登录登出效果,但是存在一个问题,我们是将所有的请求都直接处理了,并没有去检查是否为已经登录的管理员发送的,如果…...

cocos creator 小游戏允许他人访问本地项目
需求背景: 发版成微信小游戏前,需要策划介入体验。不上传微信体验版本 实现: 1.发布平台选择web桌面端 2.构建完成后点击运行从浏览器上获取本地的运行地址 3.winR ——》 cmd 控制台 输入 ipconfig 找到IPv4地址,替换本地部分 …...

分布式存储 vs. 全闪集中式存储:金融数据仓库场景下的性能对比
作者:深耕行业的 SmartX 金融团队 张德敏 近年来随着金融行业的高速发展,经营决策者及监管机构对信息时效性的要求越来越高,科技部门面临诸多挑战。例如,不少金融机构使用数仓业务系统,为公司高层提供日常经营报表&am…...

RHCE---搭建博客网站
一.实验要求: Server-NFS-DNS主机配置NFS服务器,将博客网站资源文件共享给Server-web主机,Server-NFS-DNS主机配置DNS Server-web主机配置web服务,通过域名www.openlab.com可以访问到自建的博客网站 二.准备工作 创建两台虚拟机…...

Spring中方法拦截器
一、MethodInterceptor 在动态代理中要想添加一个额外功能,只要去实现MethodBeforeAdvice这个接口就行了,但是实现了这个接口的额外功能只能运行在目标类执行之前,如果是想在目标类执行之后呢?那这个需求就完成不了,所…...

【网络】HTTPS讲解(侧重于加密、秘钥、证书的讲解)
HTTPS讲解 前言正式开始安全HTTP和HTTPS的关系什么是加密和解密为什么要加密运营商劫持中间人 常⻅的加密⽅式对称加密⾮对称加密 数据摘要数字签名HTTPS 的⼯作过程⽅案 1 - 只使⽤对称加密(不可靠)⽅案 2 - 只使⽤⾮对称加密(不可靠&#x…...
absolute 定位
关于CSS的一些学习记录 absolute定位类型 语法staticrelative 相对定位absolute 绝对定位fixed 固定定位stick 粘性定位 absolute CSS postion属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则决定了该元素的最终位置。 定位类型 定位元素是其计算后…...

比亚迪、吉利、蔚来等将出席2023第四届中国新能源汽车热管理峰会
会议背景 2023第四届中国新能源汽车热管理创新国际峰会将于11月16日-17日在上海举办。会议线上线下同步举行,会场提供中英同声传译。 本次峰会将密切关注“双碳”目标下中国新能源汽车一体化热管理的最新行业动态与关键技术的研发和应用方案。会议将对中国新能源汽…...

OJ第五篇
文章目录 用队列实现栈用栈实现队列设计循环队列 用队列实现栈 链接:用队列实现栈 这道题是让我们用两个队列实现一个栈,简单来说,就是利用队列来实现一个先入后出的功能,我们知道队列是先入先出,如何用两个队列来实…...

【论文解读】Parameter-Efficient Transfer Learning for NLP
一. 介绍 1.1 为什么要引入Adapter 在存在许多下游任务的情况下,微调的参数效率很低:每个任务都需要一个全新的模型。作为替代方案,我们建议使用适配器模块进行传输。 1.2 论文目标 目标是建立一个在所有这些方面都表现良好的系统,但不需…...

星途星纪元 ES,用艺术思维表达工程技术
10月8日,星途星纪元ES携手世界级成都爱乐首席乐团、旅德青年钢琴家王超,在成都打造了一场“万物星声”超舒适音乐会视听盛宴。这是星途星纪元首次跨界音乐圈、牵手音乐挚友,共同演绎音乐和汽车的美学协奏曲,开启高端超舒适美学新纪…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...