【JVM】JVM基础教程(一)
目录
初识JVM
JVM是什么?
JVM的功能
解释、即时编译和运行
内存管理
常见的JVM
JVM虚拟机规范
HotSpot的发展历程
JVM的组成
字节码文件详解
应用场景
以正确姿势打开字节码文件
编辑字节码文件的组成
基本信息
Magic魔数
主副版本号
常量池
接口
字段
方法
案例分析
案例分析
案例分析
属性
常用工具
javap -v命令
IDEA插件-jclasslib
阿里Arthas
入门使用
监控面板
查看字节码信息
案例分析
类的生命周期(重点)
应用场景
生命周期概述
加载阶段
查看内存中的对象
连接阶段
验证阶段
版本号的检测
准备阶段
静态变量分配内存&初始值
解析阶段
初始化阶段
何时初始化?
clinit指令
初始化的要点
案例分析
案例分析
案例分析
案例分析
常量折叠
初识JVM
JVM是什么?
JVM(Java Virtual Machine),中文名Java虚拟机
JVM就是一款软件,用来运行Java字节码文件
将字节码文件【解释】(配合JIT、AOT编译器)成【机器码】,计算机能直接运行机器码
(机器码是计算机能够直接运行的指令集,机器码由二进制数字组成,通常以0和1的形式表示。这些指令被处理器(CPU)解码和执行)
关于JIT和AOT,可以看我另一篇博客:【Java基础面试题003】Java的JIT | AOT是什么?_java jit面试-CSDN博客
JVM的功能
JVM 包含内存管理、解释执行虚拟机指令、即时编译三大功能
解释、即时编译和运行
- 将字节码文件,解释+即时编译成机器码,交给计算机执行
- 即时编译,对热点代码进行优化,提升执行效率
(无论JVM到底是编译字节码还是解释字节码,最终都是生成机器码)
- 由于JVM需要实时解释虚拟机指令,所以Java语言如果不做任何优化,性能不如C、C++等语言
- JVM提供了即时编译(JIT)进行性能的优化,尤其是C2编译器,最终能勉强接近C、C++的运行性能(接近,还是勉强~~),在特性场景下有机会实现超越
- Java需要实时解释,主要是为了支持跨平台特性
内存管理
- 自动给对象、方法等分配内存
- 自动的垃圾回收机制,回收不再使用的对象
常见的JVM
常见的JVM有HotSpot、GraalVM、OpenJ9等,另外DragonWell龙井JDK也 提供了一款功能增强版的JVM。其中使用最广泛的是HotSpot虚拟机。
看得出Java的生态真的很好,不过我用的JDK是这一家的
Adoptium Eclipse Temurin:Home | Adoptium
JVM虚拟机规范
官网地址:Java SE Specifications (oracle.com)
《Java虚拟机规范》由Oracle制定,内容主要包含了Java虚拟机在设计和实现时需要遵守的规范,主 要包含class字节码文件的定义、类和接口的加载和初始化、指令集等内容。
《Java虚拟机规范》是对虚拟机设计的要求,而不是对Java设计的要求,也就是说虚拟机可以运行在 其他的语言比如Groovy、Scala生成的class字节码文件之上。
HotSpot的发展历程
JVM的组成
字节码文件详解
应用场景
- 面试回答
学习字节码文件的组成可以更深入的理解Java代码,说点实际的,最起码面试的时候有用
比如下列面试题:
如果从Java语法层面回答这个题,面试官可能会觉得你的道行不深,如果从字节码文件中的字节码指令来回答这个题,面试官可能会觉得你对JVM的了解还不错
这里给个例子复习一下后自增
(i++先返回值用来赋值操作,后自增,但是自增的值"丢失"了,没有被保存下来,可以理解为自增操作被赋值操作覆盖了)
int i = 0;i = i++;System.out.println(i); // 0int j = 0;j = ++j;System.out.println(j); // 1
- 解决版本冲突
- 系统升级
以正确姿势打开字节码文件
一般的记事本,包括高级记事本,打开字节码文件,会部分乱码,毕竟.java文件编译成.class文件用的编码格式有很多,不单纯是单一的UTF8啥的
为了更直观查看.class文件,可以用下面这一款工具【jclasslib】
官网:GitHub - ingokegel/jclasslib: jclasslib bytecode editor is a tool that visualizes all aspects of compiled Java class files and the contained bytecode.
版本号:v6.0.5

字节码文件的组成
下面围绕这段代码进行分析字节码文件的组成
public interface Test {void printOneLine(int age);
}
public class MyTest implements Test{// 常量private static final String str1 = "黄小桃";private static final String str2 = "黄小桃";private int age;public MyTest(){}public MyTest(int age){this.age = age;}public int getAge(){return this.age;}@Overridepublic void printOneLine(int age){System.out.println(str1 + "那年" + age + "岁");}public static void main(String[] args) {MyTest myTest = new MyTest(19);myTest.printOneLine(myTest.getAge());}
}
基本信息
Magic魔数
- 文件是无法通过文件扩展名来确定文件类型的,文件扩展名可以随意修改,不影响文件的内容
- 软件使用文件的头几个字节(文件头)去校验文件的类型,如果软件不支持该种类型就会出错
- Java字节码文件中,将文件头称为Magic魔数
(魔数:是指文件的前四个字节,用于标识该文件确实是一个有效的Java字节码文件。这个魔数的值是固定的。魔数帮助系统快速识别文件,不需要检查文件内容)
下面给一个魔数的例子:
0000: CAFEBABE (魔数) 0004: 0000 0034 (次版本号、主版本号) ...
主副版本号
就是编译字节码文件的JDK版本号
- 主版本号用来标识大版本号,JDK1.0 - 1.1使用了45.0 - 45.3,JDK1.2是46之后没升级一个大版本就加1;
- 副版本号是当主版本号相同时作为区分不同版本的标识,一般只需要关心主版本号
版本号的作用主要是判断当前字节码的版本和运行时的JDK是否兼容
案例:主版本号不兼容错误
两种解决方案:
- 升级JDK版本(容易引发其他的兼容性问题,需要大量的测试)
- 将第三方依赖的版本号降低或者更换依赖,以满足JDK版本的需求(建议采用)
常量池
避免重复定义相同的内容,节省空间
- 常量池中的数据都有一个编号,编号从1开始。在字段或者字节码指令中通过编号可以快速的找到对应的数据
- 字节码指令中通过编号引用到常量池的过程称之为符号引用
查看源码,有两个常量的内容一致
查看字段,发现有三个字段,常量值索引为#21
根据索引查看常量内容
补充说明:
如果常量名与常量内容相同,那么加载到常量池中,为了节省空间,将直接指向内容,而非先指向类型再指向内容
接口
字段
方法
字节码中的方法区是存放字节码指令的核心位置,字节码指令的内容存放在方法的Code属性中
方法部分,换一个代码案例
public class MyTest {public static void main(String[] args) {int i = 0;int j = i + 1;}
}
这些指令是什么意思呢?可以查看源文档
左键点击指令,查看规范
字面意思就是将这个指令放入操作栈,至于操作栈,下面我会说明
局部变量表是根据源代码从上到下、从右到左执行的顺序,加载到局部变量表的
案例分析
初始环境
先根据顺序加载所有局部变量到局部变量数组中
这个就是局部变量表
iconst_0
对于int i = 0;先将常量池的常量0加载到操作数栈
istore_1
对于int i = 0;再将操作数栈中的0存入局部变量数组下标为1的局部变量i中
iload_1 & iconst_1
对于int j = i + 1;将局部变量数组下标为1的局部变量i的值(0)加载到操作数栈, 并且将常量1加载到操作数栈
iadd
对于int j = i + 1;对操作数栈中的常量们进行加法运算
istore_2
对于int j = i + 1;将操作数栈中的常量值存入局部变量数组[2]的局部变量j中
return
结束方法(main方法)
JVM清空操作数栈,局部变量数组被销毁,内存空间释放
现在再来分析一个案例
案例分析
public class MyTest {public static void main(String[] args) {int i = 0;i = i++;}
}
初始环境
iconst_0
对于int i = 0;先加载常量值0到操作数栈中
istore_1
对于int i = 0;再将常量值0弹入到局部变量i
iload_1
对于i = i++;从语法上看,是先执行i++,将局部变量i的值加载到操作数栈中
iinc 1 by 1
查看源文档
所以是用常数1增加局部变量i
注意看细节,这次的加法是在局部变量中运行的,这也是回答面试的关键点
istore_1
将操作数栈的常量值存入局部变量i,也就是将0替换了1,导致最终结果还是0
return
JVM清空操作数栈,局部变量数组被销毁,内存被释放
最后回答,这种从字节码指令层面的回复,会比Java语法层面的"先增后增"回复好一些
Java语法层面说 n = i++是先返回值给n,再自增,对应到字节码指令层面,就是先iload_ 到操作数栈,n获取的是操作数栈中的数,再 iinc 1 by 1自增
如果是++i
案例分析
public class MyTest {public static void main(String[] args) {int i = 0, j = 0, k = 0;i++;j = j + 1;k += 1;}
}
这么看的话,性能排序是 (i++) = (k+=1) > (j = j + 1)
属性
常用工具
javap -v命令
- javap是JDK自带的反编译工具,可以通过控制台查看字节码文件的内容。适合在服务器上查看字节码文件内 容
- 直接输入javap查看所有参数。
- 输入javap -v 字节码文件名称 查看具体的字节码信息。(如果jar包需要先使用 jar –xvf命令解压)
IDEA插件-jclasslib
这款软件也有idea插件版本,建议开发时使用IDEA插件版本
阿里Arthas
Java应用诊断器,一款宝藏工具,这里我必须吹一波阿里云,真的很棒!下文会频繁的使用这个工具
简介 | arthas (aliyun.com)
链接:https://arthas.aliyun.com/arthas-boot.jar
还有很多中下载安装方式,自己查看官网
入门使用
public class MyTest {public static void main(String[] args) throws Exception{while (true){Thread.sleep(1000);}}
}
这个代码死循环睡眠,模拟程序持续运行
运行jar包
会显示所有Java相关进程,我们要用第4个
输入4,回车
看到当前程序的进程是2388,然后下面的所有命令都只对2388这个进程生效
监控面板
arthas的功能很多,本章节先学习监控面板&&查看字节码信息这两个功能,其余的后面可能会出现
查看官方文档
dashboard -i 2000 -n 3
查看字节码信息
dump命令
dump -d [存放路径] [目标类的全限定名]
jad命令
反编译命令
案例分析
类的生命周期(重点)
类的生命周期描述了一个类加载、使用、卸载的整个过程
类的生命周期是高频面试、笔试点,也是后续大量知识点的基础部分,很重要
比如下列的输出结果是:
public class MyTest {public static void main(String[] args) {System.out.print("A");new MyTest();new MyTest();}public MyTest(){System.out.print("B");}{System.out.print("C");}static{System.out.print("D");}
}
public class MyTest {public static void main(String[] args) {new BO2();System.out.println(BO2.a);}
}class AO2{static int a = 0;static {a = 1;}
}class BO2 extends AO2{static {a = 2;}
}
应用场景
生命周期概述
加载阶段
1.加载(Loading)阶段的第一步是类加载器根据类的全限定名,通过不同渠道以二进制流的方式获取字节码信息。
开发者可以使用Java代码拓展不同的渠道
2.类加载器在加载完类之后,Java虚拟机会将字节码中的信息保存到方法区中
3.字节码信息加载到方法区中之后,JVM在方法区生成一个InstanceKlass对象,保存类的所有信息,里面还包含实现特定功能比如多态的信息
4.同时,JVM还会在堆中生成一份与方法区中数据类似的java.lang.Class对象
作用是:在Java代码中去获取类的信息&&存储静态字段的数据(JDK8及之后)
对于开发者来说,只需要访问堆中的Class对象而不需要访问方法区中所有信息,这样JVM就能很好地控制开发者访问数据的范围
查看内存中的对象
推荐使用JDK自带的hsdb工具查看JVM内存信息。
在JDK/lib目录下
进到lib目录,启动命令
java -cp sa-jdi.jar sun.jvm.hotspot.HSDB
输入java进程PID连接,查看虚拟机内存信息
连接阶段
验证阶段
1.连接(Linking)阶段的第一个环节是验证,验证的主要目的是检测Java字节码文件是否遵守了《Java虚拟机规范》中的约束。这个阶段一般不需要开发者参与
2.主要包含如下四个部分,具体详见《Java虚拟机规范》:
- 文件格式验证,比如文件是否以0xCAFEBABE开头,也就是魔数,主次版本号是否满足当前Java虚拟机版本要求
- 元信息验证,例如类必须有父类(则super不能为空)
- 验证程序执行指令的语义,比如方法内的指令执行中跳转到不正确的位置
- 符号引用验证,例如是否访问了其他类中private的方法等
版本号的检测
Hotspot JDK8中虚拟机源码对版本号检测的代码如下,你能读懂它的含义吗:
准备阶段
静态变量分配内存&初始值
- 准备阶段为静态变量(static)分配内存并设置初始值
- 注意:本章涉及到的内存结构只讨论JDK8及以后的版本
- 准备阶段只会给静态变量赋初始值,而每一种基本数据类型和引用数据类型都有其初始值
- final修饰的基本数据类型的静态变量,准备阶段直接会将代码中的值进行赋值,而没有初始化阶段
解析阶段
解析阶段主要是常量池中的符号引用替换为内存地址直接引用
符号引用就是在字节码文件中使用编号来访问常量池中的内容
直接引用不再使用编号,而是使用内存中地址进行访问具体的数据
初始化阶段
准备阶段:为静态变量(static)分配内存&设置初始值
初始化阶段:为静态变量(static)赋值,执行静态代码块中的代码
注意两者的区别,途中value的最终值应该是1,而不是0
初始化阶段会执行字节码文件中clinit部分的字节码指令。
public class MyTest {public static int value = 1;static{value = 2;}public static void main(String[] args) {}
}
重点来了
何时初始化?
(访问一个类的静态变量或者静态方法,注意变量是final修饰的并且等号右边是常量不会触发初始化。)
1.调用Class.forName(String className)。
2.new一个该类的对象时。
3.执行Main方法的当前类。
4.直接引用静态变量或静态方法
5.使用反射机制访问类的构造器(例如
Constructor<?> constructor = Class.forName("A").getDeclaredConstructor();
)6.静态导入(比如
import static ...
)7.如果有一个枚举类型,并且在其中使用了静态代码块,访问任何枚举值时也会导致整个枚举类被加载,这样其静态代码块会被执行。
clinit指令
clinit指令在特定情况下不会出现,比如:如下几种情况是不会进行初始化指令执行的。
1.无静态代码块且无静态变量赋值语句。
2.有静态变量的声明,但是没有赋值语句。
3.静态变量的定义使用final关键字,这类变量会在准备阶段直接进行初始化。
初始化的要点
数组的创建不会导致数组中元素的类进行初始化
final修饰的变量如果赋值的内容需要执行指令才能得出结果,会执行clinit方法进行初始化
案例分析
面试题一
public class MyTest {public static void main(String[] args) {System.out.print("A");new MyTest();new MyTest();}public MyTest(){System.out.print("B");}{System.out.print("C");}static{System.out.print("D");}
}
先执行clinit部分,也就是static代码块
先搞清楚新指令的作用,查看文档
getstatic
从字节码中获取静态字段值,载入操作栈顶中
ldc
将常量池中的值载入操作数栈中
invokevirtual
处理栈顶操作
OK,现在分析字节码指令
第一行,通过
getstatic
获取System.out
的PrintStream
对象,并将其放入操作数栈顶。也就是定义中的获取静态字段(System.out)的值(PrintStream对象)
这个PrintStream对象就是用来打印的
第二行,从常量池取出字符串D(将常量存入常量池就编译源代码的时候做的,并不需要什么显式的字节码指令,这里可以直接从常量池获取),取出后加载到操作数栈上
第三行,invokevirtual调用printStream类的print方法,打印栈顶的字符串D
第四行,return结束静态代码块
执行main方法前,首先初始化类的static代码块
输出结果:D
现在开始执行main方法
前三行
输出结果:A
第四行,new创建MyTest类的实例,是对象的一个引用(此时对象还没有初始化),也就是所谓的this,还将此引用推送到操作数栈中
第五行,dup复制一份对象的引用,放在操作数栈顶上(每次调用对象都会dup一次,应该是为了每个引用互不影响)
第六行,invokespecial调用构造方法开始初始化刚刚new出来的空对象
看3 - 5行,打印字符串C
看6 - 8行,打印字符串B
书接上回
第七行,pop弹出栈顶的对象引用,对象引用处理完毕
8 - 11行,重复一次上述操作
输出结果:CBCB
案例分析
public class MyTest {public static void main(String[] args) {System.out.println(BO2.a);}
}class AO2{static int a = 0;static {a = 1;}
}class BO2 extends AO2{static {a = 2;}
}
分析:初始化的条件有三个,上面我记的有
所以B02.a这一行就先获取的是父类A02的静态变量a,执行了父类A02的static代码块,将a赋值为1此时字节码执行return结束了静态代码块的初始化操作
这时不再执行子类B02的static代码块,理由是,初始化操作通过return指令已经结束,如果要执行子类B02的static代码块,需要重新初始化,比如可以加一行new B02();
new的操作会再次访问B02的父类A02,发现AO2的静态代码块已经加载过了,不会再触发了,于是开始加载子类的,所以会赋值a为2
案例分析
这个好理解,new的数据,分配了10个空间,每个元素都在准备阶段设置了初始值,A类的默认值是null,所以这个数组的元素全是null
再来复习一下初始化的条件
案例分析
public class MyTest {public static void main(String[] args) {System.out.println(A.a);}
}class A{// public static final int a = 1;public static final int a = Integer.valueOf(1);static {System.out.println("A类的静态代码块初始化");}
}
常量折叠
引入一个概念,编译时常量,A类的public static final int a = 1;
JVM做了优化,在编译时编译器直接将a的值嵌入到代码中,不需要运行时初始化了,直接跳过了初始化阶段
public class MyTest {public static void main(String[] args) {System.out.println(A.a);}
}class A{public static final int a = 1;
// public static final int a = Integer.valueOf(1);static {System.out.println("A类的静态代码块初始化");}
}
仔细对比字节码指令,发现第二种,压根没有getstatic A的clinit初始化操作,而是iconst_1直接从常量池把常量1拿到了操作数栈中,初始化操作直接跳过了
下一章:【JVM】JVM基础教程(二)-CSDN博客
相关文章:
【JVM】JVM基础教程(一)
目录 初识JVM JVM是什么? JVM的功能 解释、即时编译和运行 内存管理 常见的JVM JVM虚拟机规范 HotSpot的发展历程 JVM的组成 字节码文件详解 应用场景 以正确姿势打开字节码文件 编辑字节码文件的组成 基本信息 Magic魔数 主副版本号 常量池 接口…...
企业国内外网络互联方案全解析
面对国内市场日益饱和的现状,企业纷纷将目光投向海外,而实现国内外网络的高效互联,则成为支撑其跨国业务顺利运行的关键。本文将为您详细介绍几种实现国内外网络互联的有效策略,助您轻松应对全球化挑战。 有些企业选择使用虚拟专用…...
【优选算法 位运算】位运算算法入门详解:位运算小专题
判定字符是否唯一 题目解析 算法原理 解法一 :哈希数组 从前往后扫描字符串,把扫描到的字符先进行判断,如果对应的 val 0 ,则放入哈希表中,否则返回 false,知道扫描完整个字符;时间…...
大文件分块上传后端服务器
一、背景: 后台系统需要上传大文件、大视频等数据,耗时过长,接口等待超时,故需优化通过前端多线程分片方式进行文件上传,显著提升上传速度。 二、流程: 前端逻辑: 前端使用分片技术ÿ…...
perl Window安装教程
perl Window安装教程 下载地址 https://platform.activestate.com/tangxing806/ActivePerl-5.28/distributions 运行state-remote-installer.exe 按下图截图步骤 检查perl版本 参考文献: perl安装教程...
Scrcpy投影之后为什么声音在电脑端显示?
关于安卓设备和电脑端扬声器优先级 在使用安卓设备与电脑进行某些连接操作(比如通过 adb 相关工具交互时),确实存在音频输出的优先级选择情况。通常情况下,可能默认音频会输出到电脑端(比如通过投屏等相关操作连接后&…...
2025年山东省职业院校技能大赛“信息安全管理与评估”(山东省) 任务书
2025年山东省职业院校技能大赛“信息安全管理与评估”(山东省 任务书 模块一网络平台搭建与设备安全防护任务1:网络平台搭建 (50分)任务2:网络安全设备配置与防护(250分) 模块二网络安全事件响应、数字取证…...
java+ssm+mysql收纳培训网
项目介绍: 使用javassmmysql开发的收纳视频培训网,系统包含超级管理员,系统管理员、培训师、用户角色,功能如下: 超级管理员:管理员管理;用户管理(培训师、用户)&#…...
多表查询-概述内连接外连接子查询
一.数据准备: 1.部门表: 代码: -- 部门管理 create table tb_dept (id int unsigned primary key auto_increment comment 主键ID,name varchar(10) not null unique comment 部门名称,create_time datetime not null c…...
H5游戏出海如何获得更多增长机会?
海外H5小游戏的崛起给了国内众多中小厂商出海发展的机会,开发者如何在海外市场获得更多的增长机会?#APP出海# H5游戏如何在海外获得核心用户? HTML5游戏的开发与运营者们首先可以利用量多质高的HTML5游戏,维持海外用户粘性&…...
element plus的表单校验,明明输入内容了,但提示红字还是会显示着
下拉框的不隐藏,可能是 trigger为blur的原因,改为change即可 const rules reactive({name: [{ required: true, message: "请输入名称", trigger: "blur" }],price: [{ required: true, message: "请输入价格", trigger…...
MobaXterm Sessions 批量录入导入,会话批量添加,解决导入配置中文乱码
一、创建表格 创建 Excel 表格,将服务器信息写入表格 二、写入文件 新建 list.txt 文件将表格中的服务器信息复制粘贴进去 三、修改脚本 这是你需要修改的变量,其他变量不需要动 # 登录用户 ssh_userroot # 目录名称 folder_name资源池四、执行脚本 …...
Vue项目中的权限控制实践与方案详解
在现代前端开发中,权限控制是一个不可或缺的重要环节。一个完善的权限控制系统不仅能够保护应用的安全性,还能为不同角色的用户提供更好的使用体验。让我们深入探讨Vue项目中权限控制的实现方案和最佳实践。 权限控制本质上是对用户操作的一种限制&…...
C++11新特性之线程std::thread
C std::thread的定义和功能 std::thread是C11引入的标准库类,用于创建和管理线程。通过std::thread,程序可以并发执行多个任务,从而提高效率。 功能与作用: 创建线程:可以启动一个线程执行某个函数或任务。管理线程…...
西门子S7-200 SMART PLC在钢铁行业中的应用
西门子S7-200 SMART PLC在钢铁行业中的应用,主要得益于其强大的功能、简易的编程方式以及卓越的稳定性,这些特点使得它能够在钢铁行业的自动化控制中发挥重要作用。 以下是对西门子S7-200 SMART PLC在钢铁行业中应用的详细分析: 一、钢铁行业…...
Amazon SageMaker 和 Amazon Bedrock 有什么区别
Amazon SageMaker 和 Amazon Bedrock 有什么区别 文章目录 Amazon SageMaker 和 Amazon Bedrock 有什么区别1.服务定位和主要功能区别Amazon SageMakerAmazon Bedrock 2. 适用场景Amazon SageMakerAmazon Bedrock 3. 用户群体Amazon SageMakerAmazon Bedrock 4. 开发和部署流程…...
自动驾驶数据集的应用与思考
数据作为新型生产要素,是数字化、网络化、智能化的基础,是互联网时代的“石油”“煤炭”,掌握数据对于企业而言是能够持续生存和发展的不竭动力,对于需要大量数据训练自动驾驶系统的企业而言更是如此。 而随着激光雷达、毫米波雷…...
Python 中的 threading 模块和 multiprocessing 模块有何区别?
在Python编程中,threading 和 multiprocessing 模块都提供了并行处理的能力,但它们实现的方式以及适用的场景是不同的。 下面将详细解释两者的区别,并给出一些日常开发中的使用建议。 Threading(线程) threading 模…...
网络安全之常见风险端口(Common Risk Ports for Network Security)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…...
思科模拟器路由器的基本配置
一、实验目的 了解路由器的作用掌握路由器的基本配置方法 3、掌握路由器模块的使用和互连方式 二、实验环境 2811路由器一台,计算机两台,Console配置线一根,网线若干;本实验拓扑图如图8-1所示;计算机IP地址规划如表8-…...
使用ssh免密登录实现自动化部署rsync+nfs+lsync(脚本)
单机一键部署sshrsyncnfslsync 执行准备 主机信息 主机角色外网IP内网IP主机名nfs、lsync10.0.0.31176.16.1.31nfs客户端10.0.0.7176.16.1.7web01rsync、nfs10.0.0.41172.16.1.41backup 秘钥信息 #web01可以免密连接nfs和backup [rootweb01 ~]# ssh-keygen [rootweb01 ~]#…...
第425场周赛:最小正和子数组、重排子字符串以形成目标字符串、最小数组和、移除边之后的权重最大和
Q1、[简单] 最小正和子数组 1、题目描述 给你一个整数数组 nums 和 两个 整数 l 和 r。你的任务是找到一个长度在 l 和 r 之间(包含)且和大于 0 的 子数组 的 最小 和。 返回满足条件的子数组的 最小 和。如果不存在这样的子数组,则返回 -…...
常见矩阵分析法(BCG、GE、IE、SPACE、TOWS、优先、战略优先级、安索夫、风险矩阵):如何通过系统化方法助力战略决策与数据驱动决策
在快速变化的商业环境中,企业决策者面临着诸多复杂的选择与挑战。矩阵分析法作为战略分析的重要工具,能够系统化地分析企业的内外部环境,帮助管理层做出更加科学、合理的决策。本文将全面解析常见的矩阵分析法,并探讨它们在数据驱…...
沐风老师3DMAX摄相机阵列插件使用方法
3DMAX摄相机阵列插件,从网格对象或样条线的顶点法线快速创建摄相机阵列。该插件从网格的顶点或样条线的节点获取每个摄影机的位置和方向。 3DMAX摄相机阵列插件支持目前3dMax主流的物理相机、标准相机、VRay物理相机。 【版本要求】 3dMax 2015及更高版本 【安装方…...
踩坑日记-win电脑怎么登录虚拟机上部署的phpmyadmin?
前请提要 电脑win11,安装centOS7虚拟机,部署了linux 安装了docker和一些镜像容器,准备开发项目 访问 phpMyAdmin 时无法打开页面 访问 http://0.0.0.0:8899/ 时,提示无法访问此页面。0.0.0.0 表示 Docker 容器将监听宿主机上的…...
手写观察者模式
本人是JavaScript开发者,以下的示例也是以Javascript举例来说明的。 一、概念 当对象间存在一对多的关系时,使用观察者模式。当被观察的对象发生变化时,其所有的观察者都会收到通知并进行相应的操作。 二、具体例子 比如说,学…...
20.LMAX-DDD的极致性能架构
学习视频来源:DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid1940048&ctype0 文章目录 历史起源架构目标架构要素 时序对比传统时序事件溯源时序LMAX时序 单线程非阻塞异步IO(reactor)多线程单…...
axios的引入和基本使用
一、axios的引入 使用 pnpm add axios 二、使用axios 三、axios的使用方法补充 axios除了直接使用它实例上的方法,还可以通过配置的方式进行使用axios({}),传入一个对象,这个对象可以有如下属性: url(字符串&#…...
14--VulnHub 靶机系列之Gear_Of_War#1
靶机下载地址: https://download.vulnhub.com/gearsofwar/Gear_Of_War%231.ova kali机(VMware)两张网卡: 第一张网卡使用VM0(桥接模式)-桥接到VirtualBox Host-Only Ethernet Adapter 第二张网卡使用NAT模式--用于访问网络 信息收集 kali机eth0的I…...
Python + OpenCV 系列:图像阈值处理
文章目录 引言 1. 阈值处理的基本概念2. OpenCV 中的阈值处理3. 常见的阈值类型3.1 二值化阈值3.2 反向二值化阈值3.3 截断阈值3.4 平滑阈值 4. 自适应阈值5. Otsu’s 阈值法6. 阈值处理的应用场景7. 总结 引言 图像阈值处理是计算机视觉和图像处理中一种非常基础而重要的技术…...
el-thee懒加载删除某条数据 ,el-thee懒加载重置,el-thee刷新某个节点
一、懒加载的tree已经全部展开,外部点击删除的时候不需要重新展开点击获取下一层数据 <template> <el-treeref"tree":data"treeData":props"defaultProps"render-after-expandhighlight-currentlazy:expand-on-click-node&q…...
如何在 JavaScript 中设置定时器?
在 JavaScript 中,设置定时器通常使用两个内置的函数:setTimeout() 和 setInterval()。它们允许你在指定的时间延迟后执行某个函数或者以某个间隔反复执行某个函数。下面,我将结合实际项目代码示例讲解如何使用它们。 1. setTimeout() — 延…...
LDR6500:音频双C支持,数字与模拟的完美结合
在当今数字化快速发展的时代,音频设备的兼容性和性能成为了用户关注的重点。LDR6500,作为乐得瑞科技精心研发的USB Power Delivery(PD)协议芯片,凭借其卓越的性能和广泛的应用兼容性,为音频设备领域带来了新…...
小型项目的数据库适合选用ClickHouse吗?
我们与MySQL比较。 MySQL 1. 传统的业务系统 用户管理订单处理产品信息企业基础数据 2. 特点 行存储,适合频繁的增删改事务支持完善小规模数据查询性能好数据一致性保证生态系统成熟,运维简单 ClickHouse 1. 数据分析场景 日志分析用户行为分析实…...
MySQL--》如何在SQL中巧妙运用函数与约束,优化数据处理与验证?
目录 函数使用 字符串函数 数值函数 日期函数 流程函数 约束 函数使用 函数是指一段可以直接被另一段程序调用的程序或代码,在mysql当中有许多常见的内置函数,接下来开始对这些内置函数及其作用进行简单的讲解和使用: 字符串函数 my…...
鸿蒙HarmonyOS应用开发 探索 HarmonyOS Next-从开发到实战掌握 HarmonyOS Next 的分布式能力
鸿蒙心路旅程:探索 HarmonyOS Next-从开发到实战掌握 HarmonyOS Next 的分布式能力 HarmonyOS Next 是华为推出的全新一代操作系统,旨在进一步推动分布式技术的深度应用和生态融合。本文将从技术特点、应用场景入手,通过实战案例与代码示例&…...
JavaWeb 9 MySQL DDL DML
前言 1、什么是数据库? 数据库:英文为 DataBase,简称DB,它是存储和管理数据的仓库 2、目前主流的关系型数据库有哪些? 目前主流的关系型数据库:(SQL语句是操作关系型数据库的统一标准&#x…...
哑资源对于通信行业的重要性以及哑资源管理的难点
一、哑资源定义与分类 1.1 哑资源概念界定 哑资源(Dumb Resources)在通信行业中指的是那些不具备智能处理能力的物理设备和设施。这些资源虽然不直接参与数据的生成和处理,但它们是通信网络正常运行的基础。哑资源包括但不限于电缆、天线、…...
聊聊大语言模型的上下文处理能力基本概念
一、Llama3的上下文处理能力 Llama 3不同版本的上下文处理能力有所不同: Llama 3基础版本:上下文长度一般为8k tokens左右,约相当于6,000字或10页文档.Llama 3.1版本:将上下文窗口提升到了128k tokens,这使得模型在处…...
总结几种不同风格的学术论文ChatGPT提示词
目录 1.不同写作风格的重要性 2.叙事写作 3.描述性写作 4.说明性写作 5.讨论性写作 小编先跟宝子们来看看一篇学术论文或者研究论文的基本组成部分,有助于后续提示词说明的整体结构和有效性: 引言:引言是写作的开篇部分,作者…...
鸿蒙技术分享:鸿蒙元服务踩坑血泪:文件下载、选择、打开
鸿蒙元服务踩坑:文件下载、选择、打开 因为项目有开发元服务的需求,因此需要将原本给应用开发封装的文件操作相关代码拿到元服务里用。本以为也没很复杂的功能,直接用应该问题不大,结果还是踩了坑…… 原本给应用使用的代码请查…...
12月通信基础知识补充2
看文献过程中不断发现有太多不懂的基础知识,故长期更新这类blog不断补充在这过程中学到的知识。由于这些内容与我的研究方向并不一定强相关,故记录不会很深入请见谅。 【通信基础知识补充6】12月通信基础知识补充2 一、Walsh码1.1 Walsh码的基本特性1.2 …...
佑驾创新冲刺上市:交付进度延后,研发投入缩减,刘国清为实控人
近日,深圳佑驾创新科技股份有限公司(MINIEYE,下称“佑驾创新”)通过港交所聆讯并披露了聆讯后资料集(即招股书)。据贝多财经了解,佑驾创新获得了IPO备案通知书,拟在港交所上市。 对…...
【Linux系列】Linux 防火墙的详细学习
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
使用 Trace 实现 onnx 的导出 - 学习记录
使用 Trace 实现 onnx 的导出 一、使用 Trace 实现 onnx 的导出的流程二、代码分解2.1、定义模型2.2、分析模型操作类型2.3、构建钩子函数2.3.1、定义 hook 函数2.3.2、注册 Conv2d - hook 函数2.3.3、注册 ReLU - hook 函数2.3.4、注册 Add - hook 函数三、完整导出 onnx 代码…...
python字符串处理基础操作总结
1.去掉空格或者特殊符号 input_str.strip() #去掉所有空格 input_str.lstrip() #去掉左边空格 input_str.rstrip() #去掉右边空格 def print_hi():input_str 今天天气不错,风和日丽 out input_str.strip()print(input_str)print(out)if __name__ __main__:print…...
AI如何让PPT制作变得轻松与智能?用一键生成ppt!
谁还愿意把时间浪费在PPT的设计和内容排版上?尤其是对于那些需要频繁制作演示文稿的人来说,一份看起来专业的PPT往往会让人陷入“做与不做”的困境。但随着科技的飞速发展,传统的PPT制作方法正逐渐被更为高效的工具所取代,尤其是智…...
OpenCV相机标定与3D重建(11)机器人世界手眼标定函数calibrateRobotWorldHandEye()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 计算机器人世界/手眼标定: w T b _{}^{w}\textrm{T}_b wTb 和 c T g _{}^{c}\textrm{T}_g cTg。 cv::calibrateRobotWorldHa…...
vscode通过ssh连接虚拟机进行开发
虚拟机自带的vscode很卡而且画质感觉不行,所以用这种方法解决 1.VSCODE安装扩展Tabnine(AI代码补全),Remote Development 2.虚拟机终端ifconfig查看本机ip 192.168.43.197 开启ubuntu的SSH服务 sudo apt-get install openssh-server 配置vscode的ssh …...
TCP/IP协议详解(小白)
TCP/IP协议详解 TCP/IP协议包含了一系列的协议,也叫TCP/IP协议族(TCP/IP Protocol Suite,或TCP/IP Protocols),简称TCP/IP。TCP/IP协议族提供了点对点的连结机制,并且将传输数据帧的封装、寻址、传输、路由…...