京东面试:什么是 JIT,JIT什么优势?什么是 类的生命周期七个阶段 ?什么是 字节码增强?

本文 的 原文 地址

原始的内容,请参考 本文 的 原文 地址

本文 的 原文 地址

尼恩说在前面

在45岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题:

  • 什么是 JIT,JIT什么优势?什么是 类的生命周期七个阶段 ?

  • 什么是 字节码增强?

最近有小伙伴在面试京东、 阿里、希音等大厂,又遇到了相关的面试题。 小伙伴 没系统梳理, 支支吾吾的说了几句,面试官不满意, 挂了

针对上面的面试题, 接下来 尼恩结合互联网上的一些实际案例, 大家做一下系统化、体系化的梳理。 使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

一、字节码文件

1、什么是字节码?

在Java之前, 跨平台 是一个难题。 而 Java 跨平台 的优势: “一次编译,到处运行” 。

构成 Java 生态 跨平台 的基石—— Java 字节码。

无论在何种环境下编译,Java 源代码都能生成标准格式的字节码(.class 文件),由 JVM 解释执行。

为啥要从 字节码入手。

对开发者而言,了解字节码有助于更深入、直观地理解 Java 语言的底层机制。

例如,通过查看字节码,可以清楚地看到 volatile关键字是如何生效的。

例如,字节码增强技术在 Spring AOP、ORM 框架及热部署等领域应用广泛,掌握其原理对我们大有裨益。

还有,由于 JVM 规范的标准性,任何能生成符合规范的字节码的程序都可以在 JVM 上运行,因此像 Scala、Groovy、Kotlin 等 JVM 语言也有机会扩展 Java 不具备的特性或实现更友好的语法糖。

从字节码的视角学习这些语言,往往能够更深刻地理解其设计思路。

我们通常使用 javac命令将 .java源文件编译为字节码文件

字节码文件由十六进制数值构成,JVM 按一组两个十六进制值(即一个字节)为单位进行读取。

image-20251010224922386

2、字节码文件的结构

.java文件经 javac编译后生成 .class文件。

编译后得到的 ByteCodeDemo.class文件以十六进制形式打开后,表现形式如下:

image-20251011083859226

JVM 规范要求字节码文件必须按以下十部分顺序构成:

image-20251010224947554

(1)魔数(Magic Number)

每个 .class文件的前 4 个字节是固定的魔数值:0xCAFEBABE

JVM 通过该标志,快速判断文件是否为可能有效的字节码文件。

有趣的是,魔数“CAFEBABE”由 Java 之父 James Gosling 指定,意为“Cafe Babe”(咖啡宝贝),而 Java 的图标正是一杯咖啡。

(2)版本号

魔数之后的 4 个字节是版本号信息:前 2 个字节表示次版本号(Minor Version),后 2 个字节表示主版本号(Major Version)。

例如 00 00 00 34表示次版本号为 0,主版本号为 52(十六进制 0x34),对应 Java 8。

(3)常量池(Constant Pool)

版本号之后是常量池,它是字节码文件中的资源仓库,主要存放两大类常量:

  • 字面量:如 final修饰的常量值、文本字符串等;
  • 符号引用:包括类/接口的全限定名、字段名称与描述符、方法名称与描述符等。

常量池的结构分为两部分:

  • 常量池计数器(constant_pool_count):2 个字节,表示常量池中的常量数量(实际数量为 计数值 - 1);
  • 常量池数据区:由多个 cp_info表项组成,每个 cp_info对应一个常量。

image-20251010225100837

JVM 共定义了 14 种 cp_info类型,其通用结构如下:


cp_info {u1 tag;          // 常量类型标识u2 info_length;  // 后续信息长度(视类型而定)u1 bytes[info_length]; // 具体数据内容
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过 javap -verbose ByteCodeDemo可查看反编译后的常量池内容,更直观易懂:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(4)访问标志(Access Flags)

常量池后的 2 个字节是访问标志,用于标识类或接口的访问权限及属性,例如是否为 publicfinalabstract等。

JVM 使用位掩码表示多个标志组合,例如 public final类对应的标志值为 0x0001 | 0x0010 = 0x0011

常见访问标志如下:

标志名 十六进制值 含义
ACC_PUBLIC 0x0001 public类型
ACC_FINAL 0x0010 final类型
ACC_SUPER 0x0020 使用invokespecial指令
ACC_INTERFACE 0x0200 接口
ACC_ABSTRACT 0x0400 抽象类或接口
ACC_SYNTHETIC 0x1000 合成类型
ACC_ANNOTATION 0x2000 注解类型
ACC_ENUM 0x4000 枚举类型

(5)当前类名

访问标志后的 2 个字节是一个索引值,指向常量池中该类全限定名的字符串常量。

(6)父类名称

当前类名后的 2 个字节也是一个索引值,指向常量池中父类的全限定名字符串。

(7)接口信息

父类名称后是接口计数器(2 字节)及接口索引列表,列出所有实现的接口在常量池中的索引。

(8)字段表(Fields Table)

字段表用于描述类中声明的字段(类变量和实例变量),不包括方法内的局部变量。结构分为两部分:

  • 字段计数器(2 字节):表示字段个数;
  • 字段信息表(field_info):每个字段的详细信息。

字段信息结构如下:


field_info {u2 access_flags;    // 访问标志,如private、static等u2 name_index;      // 字段名在常量池中的索引u2 descriptor_index;// 字段描述符(如I表示int)索引u2 attributes_count;// 属性个数attribute_info attributes[attributes_count]; // 属性表
}

image-20251010225139221

案例中private int a,0002对应为Private。

通过索引下标在常量池查询#7号常量,得到字段名为“a”,描述符为“I”(代表int)。

综上,就可以唯一确定出一个类中声明的变量private int a

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(9)方法表(Methods Table)

方法表存储所有方法的信息,也分为两部分:

  • 方法计数器(2 字节):表示方法个数;
  • 方法信息表(method_info):每个方法的详细信息。

方法信息结构如下:


method_info {u2 access_flags;     // 访问标志,如public、synchronized等u2 name_index;       // 方法名在常量池中的索引u2 descriptor_index; // 方法描述符(如()V)索引u2 attributes_count; // 属性个数attribute_info attributes[attributes_count]; // 属性表
}

image-20251010225206289

通过 javap -verbose可查看方法表的详细信息,可以看到主要包括以下三个部分:

  • “Code区”:源代码对应的JVM指令操作码,在进行字节码增强时重点操作的就是“Code区”这一部分。
  • “LineNumberTable”:行号表,将Code区的操作码和源代码中的行号对应,Debug时会起到作用(源代码走一行,需要走多少个JVM指令操作码)。
  • “LocalVariableTable”:本地变量表,包含This和局部变量,之所以可以在每一个方法内部都可以调用This,是因为JVM将This作为每一个方法的第一个参数隐式进行传入。当然,这是针对非Static方法而言。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(10)附加属性表(Additional Attributes)

字节码文件的最后部分可包含自定义属性信息,如源文件名称、注解信息等。

3、字节码指令集

JVM 字节码指令是堆栈导向的,操作码长度为一个字节(0x00~0xFF),最多支持 256 条指令。

Java 虚拟机规范定义了丰富的指令集,包括算术运算、类型转换、对象创建、方法调用等类别。

以下是一些常见指令示例:

指令助记符 操作码(十六进制) 功能说明
iconst_2 0x05 将int型常量2压入操作数栈
istore_1 0x3C 将栈顶int值存入局部变量槽1
iadd 0x60 弹出栈顶两个int值,相加后压回
ireturn 0xAC 返回int类型结果

完整指令集可参考 Oracle 官方文档。

在上图中,Code区的红色编号0~17,就是.java中的方法源代码编译后让JVM真正执行的操作码,也就是完整的add()方法的实现

4、操作数栈与字节码执行

JVM的指令集是基于栈而不是寄存器,基于栈可以具备很好的跨平台性(因为寄存器指令集往往和硬件挂钩),

但缺点在于,要完成同样的操作,基于栈的实现需要更多指令才能完成(因为栈只是一个FILO结构,需要频繁压栈出栈)。

另外,由于栈是在内存实现的,而寄存器是在CPU的高速缓存区,相较而言,基于栈的速度要慢很多,这也是为了跨平台性而做出的牺牲。

这也是为啥 java 比 go 慢的原因之一。

JVM:基于栈的虚拟机,这个是java慢的一个核心原因之一

  • JVM 字节码 是一种中间语言,运行在虚拟机上。
  • 它的指令操作主要依赖于操作数栈(operand stack),而不是寄存器。
  • 例如,iadd 指令会从栈顶弹出两个整数,相加后再压回栈中。
  • 优点:指令集简洁,跨平台,容易实现。
  • 缺点:性能相对较低,因为频繁的栈操作。

Go 基于寄存器的机器码,这个是Go 快的一个核心原因之一

  • Go 是静态编译型语言,编译器(如 gc)会将 Go 代码直接编译成目标平台的机器码(如 x86-64、ARM)。
  • 这些机器码是基于寄存器的,因为现代 CPU 架构(如 x86、ARM)本身就是寄存器架构。
  • Go 编译器在生成代码时,会使用寄存器来存储变量、参数、返回值等,而不是像 JVM 那样用栈。
  • 所以,Go 的“指令集”其实就是目标平台的机器指令集,是寄存器驱动的。

我们在上文所说的操作码或者操作集合,其实控制的就是这个JVM的操作数栈。

为了更直观地感受操作码是如何控制操作数栈的,以及理解常量池、变量表的作用,这里 将add()方法的对操作数栈的操作制作为GIF动图,如下图所示。

GIF动图中,仅截取了常量池中被引用的部分,以指令iconst_2开始到ireturn结束,与方法表Code区0~17的指令一一对应:

图片

基于栈的设计使 JVM 具有良好的跨平台性,但执行性能可能不如基于寄存器的架构。

为了缓解性能问题,JVM 引入了 JIT(即时编译)技术,将热点代码编译为本地机器码执行。

理论 上, JIT 最终吐出来的东西一定是“基于寄存器的真正机器码”,因为只有这样才能在物理 CPU 上直接跑。

但JIT 不是一次性把整个 Java 字节码“平移”成机器码,而是先把基于栈的 byte-code 当输入,经过一次“栈→寄存器”的转换,再生成宿主 CPU 的寄存器指令。

下面把流程拆开说清:

1、输入:基于栈的字节码
例:


iload_1
iload_2
iadd
istore_3

语义:把局部变量 1、2 压栈 → 弹出两个 int 相加 → 结果存回局部变量 3。

全程没有寄存器名字,只有深度为 2 的 operand stack。

2、JIT 编译器(C1/C2/Graal 等)做的核心事情

a. 字节码解析 + 类型推导 → 得到一个有类型的“栈机器”中间表示(IR)。

b. “栈调度”(stack-to-register allocation):把每条 push/pop 映射到虚拟寄存器(SSA 值)。

c. 全局寄存器分配(图着色、线性扫描等):把虚拟寄存器再映射到物理寄存器(x86 的 rax/rbx/rsi…)。
d. 指令选择:生成真正的 ADD、MOV、LEA… 指令。

e. 优化 + 重排 + 发射:最终得到可在 CPU 上直接运行的机器码片段。

3、 输出:基于寄存器的机器码

上面 4 条字节码可能被 JIT 编译成(x86-64):


mov    eax, [rbp+local_1]   ; eax = local_1
add    eax, [rbp+local_2]   ; eax += local_2
mov    [rbp+local_3], eax   ; local_3 = eax

已经没有 operand stack 的影子,完全使用寄存器与内存操作数。

JIT 的输入是“基于栈的字节码”,输出是“基于寄存器的本地机器码”;中间经过把栈语义等价变换成寄存器语义的编译过程。

5、查看字节码的工具

除了使用 javap命令反编译字节码外,推荐使用 IntelliJ IDEA 插件 jclasslib可视化查看字节码细节。

安装后,通过菜单栏的 “View” → “Show Bytecode With jclasslib” 即可查看当前类的字节码信息,包括常量池、方法表、属性表等,界面直观友好。

image-20251011075556806

掌握字节码结构与指令集,不仅有助于我们深入理解 Java 程序的运行机制,也是学习高级主题如字节码增强、性能优化的重要基础。

二、类装载机制

类的装载就是将字节码文件加载到JVM中的过程

1、类的入口点

在深入探讨JVM如何加载.class文件之前,先回顾一下C语言的执行过程。

一个简单的C程序:


#include <stdio.h>
int main() {printf("Hello, World! \n");return 0;
}

编辑完保存为hello.c文本文件,然后安装gcc编译器(GNU C/C++)


$ gcc hello.c
$ ./a.out
Hello, World!

这个过程就是gcc编译器将hello.c文本文件编译成机器指令集,然后读取到内存直接在计算机的CPU运行。

从操作系统层面看的话,就是一个进程的启动到结束的生命周期。

而Java的执行方式,和c 有所不同。

我们编写一个HelloWorld类:


public class HelloWorld {public static void main(String[] args) {System.out.println("my classLoader is " + HelloWorld.class.getClassLoader());}
}

需要通过两个步骤执行:


$ javac HelloWorld.java        # 编译
$ java HelloWorld              # 执行

这里的关键区别在于:执行Java程序时,操作系统启动的是java命令对应的进程(即JVM),而HelloWorld类只是传递给这个进程的参数。

JVM会寻找并执行指定类中的main方法作为程序入口。

Java的main方法有严格的格式要求,必须是public static void main(String[] args)

我们可以通过实验验证这些要求的必要性:

  • 去掉public修饰符:JVM会报错,因为需要访问权限
  • 去掉static修饰符:JVM会报错,因为需要能够不创建实例就调用
  • 修改返回类型:JVM会报错,因为需要统一的void返回类型
  • 更改方法名:JVM会报错,因为找不到约定的入口方法

这些规则确保了JVM能够以统一的方式启动任何Java程序。

从底层实现来看,java命令(由C++编写)通过JNI(Java Native Interface)调用Java的main方法。

源码简化后的调用逻辑如下:


// 获取主类名
mainClassName = GetMainClassName(env, jarfile);// 加载主类
mainClass = LoadClass(env, classname);// 获取main方法ID
mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V");// 调用main方法
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);

2、类的生命周期七个阶段

当我们编写一个Java类并运行它时,这个类在JVM中会经历完整的生命周期。

理解这个过程对于掌握JVM工作原理至关重要。

一个类在JVM中的完整生命周期包括7个阶段:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)。

image-20251011080223350

前五个阶段(加载到初始化)统称为类加载过程。

下面我们详细分析每个阶段的具体工作。

2.1 加载阶段(Loading)

加载是类生命周期的起点,主要任务是找到类的二进制表示并将其加载到内存中。

核心操作:

  • 根据类的全限定名(如java.lang.String)定位class文件
  • 读取class文件的二进制字节流
  • 将字节流转换为方法区的运行时数据结构
  • 在堆内存中生成一个代表该类的java.lang.Class对象,作为访问方法区数据的入口

技术细节:

加载阶段由类加载器(ClassLoader)具体执行。JVM内置了三级类加载器:

  • 启动类加载器(Bootstrap ClassLoader):加载JRE核心库
  • 扩展类加载器(Extension ClassLoader):加载扩展库
  • 应用类加载器(Application ClassLoader):加载用户类路径上的类

如果找不到指定的类文件,JVM会抛出NoClassDefFoundError。值得注意的是,加载阶段并不检查class文件的语法和格式是否正确,这些检查会在后续阶段进行。

2.2 验证阶段(Verification)

验证是连接过程的第一步,确保被加载的类符合JVM规范且不会危害虚拟机安全。

这个阶段就像是对进口商品进行海关检查,防止有害内容进入国内。

验证内容包括:

(1) 文件格式验证:检查魔数(CAFEBABE)、版本号等基本信息

(2) 元数据验证:对类的元数据进行语义检查,如是否有父类、是否实现所有抽象方法等

(3) 字节码验证:通过数据流和控制流分析,验证程序逻辑的合理性

(4) 符号引用验证:检查常量池中的符号引用能否正确解析

可能抛出的异常:

  • VerifyError:验证失败
  • ClassFormatError:类格式错误
  • UnsupportedClassVersionError:版本不支持

验证过程中可能需要加载其他相关类,如果发现类层次结构问题(如循环继承),JVM会抛出ClassCircularityError

2.3 准备阶段(Preparation)

准备阶段为类变量分配内存并设置初始值。这些变量指的是被static修饰的静态变量,不包括实例变量。

关键特点:

  • 分配内存:在方法区中为静态变量分配内存空间
  • 设置默认值:为静态变量赋予类型默认值(0、false、null等)
  • 不执行代码:此阶段不会执行任何Java代码或赋值语句

示例分析:


public static int value = 123;     // 准备阶段后value的值为0,而非123
public static final int CONST = 456; // 准备阶段后CONST的值就是456

对于final静态常量,某些JVM实现会直接在此阶段赋值,这是因为常量的值在编译期就能确定。

这种差异有时会让开发者感到困惑,特别是从其他语言(如C#)转来的开发者。

2.4 解析阶段(Resolution)

解析阶段将常量池中的符号引用转换为直接引用。这个过程就像是将地址簿中的名称转换为实际的家庭住址。

解析内容:

  • 类或接口解析:将类名解析为实际类引用
  • 字段解析:将字段符号引用解析为具体字段
  • 方法解析:将方法符号引用解析为具体方法
  • 接口方法解析:将接口方法符号引用解析为具体实现

技术细节:

符号引用是一组描述被引用目标的符号,包含在class文件的常量池中。直接引用则可以是直接指向目标的指针、相对偏移量或能间接定位到目标的句柄。

解析阶段可以在初始化之后进行,这是Java语言"运行时绑定"特性的基础。JVM实现可以根据需要灵活选择解析时机,采用惰性解析策略以提高性能。

2.5 初始化阶段(Initialization)

初始化是类加载过程的最后一步,真正开始执行类中定义的Java代码。

触发条件:

JVM规范严格规定,只有在类首次被"主动使用"时才进行初始化。主动使用包括:

  • 创建类的实例
  • 访问类的静态变量或静态方法
  • 使用反射调用类方法
  • 初始化子类会触发父类初始化
  • 包含main方法的启动类

初始化内容:

  • 执行静态变量赋值语句
  • 执行静态代码块(static{})
  • 执行类构造器<clinit>()方法

2.6 使用和卸载阶段

初始化完成后,类就进入了使用阶段,可以被正常实例化和调用了。当类不再被需要时,可能进入卸载阶段。

使用阶段:

类完全加载后,应用程序可以创建实例、调用方法、访问字段等。这是类生命周期中最长的阶段。

卸载条件:

当满足以下条件时,类可以被卸载:

  • 该类的所有实例都已被回收
  • 加载该类的ClassLoader已被回收
  • 该类对应的Class对象没有被任何地方引用

卸载类的过程由JVM的垃圾收集器完成,开发者通常不需要关心这个过程。

2.7 惰性加载(Lazy Loading)机制

HotSpot JVM为了提高性能,采用了许多优化策略。

其中最重要的是惰性加载(Lazy Loading)机制:除非必要,否则不会提前加载和链接类。

示例说明:


class A {static {System.out.println("A初始化");}
}class B {static {System.out.println("B初始化");}public static void method() {System.out.println("B的方法被调用");}
}public class LazyLoadingDemo {public static void main(String[] args) {A a = null; // 不会触发A的初始化System.out.println("A的引用已创建");B.method(); // 第一次主动使用B,触发B的初始化}
}

输出结果:


A的引用已创建
B初始化
B的方法被调用

这种惰性加载策略显著提高了JVM的启动性能和内存使用效率。

只有当一个类被真正"主动使用"时,JVM才会执行完整的加载、链接和初始化过程。

3、类加载器

在JVM执行main方法之前,首先需要找到对应的.class文件并将其加载到内存中。

这个任务由类加载器(ClassLoader)完成。

从操作系统层面看,类加载本质上就是JVM进程通过I/O操作从磁盘或网络读取.class文件的二进制数据,然后将其存入内存的特定区域。

如果单纯从技术实现角度考虑,类加载可以用很简单的代码实现:

C语言版本:


char *fgets(char *buf, int n, FILE *fp);

Java版本:


InputStream f = new FileInputStream("HelloWorld.class");

但如果只是简单地将类文件读入内存,没有良好的组织和管理机制,JVM将无法高效地使用这些类。

因此,JVM设计了一套完整的类加载体系结构。

3.1 系统内置的类加载器

...................由于平台篇幅限制, 剩下的内容(5000字+),请参参见原文地址

原始的内容,请参考 本文 的 原文 地址

本文 的 原文 地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/937397.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年阀门保温罩厂家最新推荐排行榜,工业阀门保温罩,管道阀门保温罩,定制阀门保温罩,高效节能阀门保温罩公司推荐

2025年阀门保温罩厂家最新推荐排行榜在工业节能与管道系统优化领域,阀门保温罩作为关键的热管理组件,正受到越来越多企业的重视。随着国家"双碳"目标的持续推进,工业领域对节能减排的需求日益增强,阀门保…

10亿用户微博Feed流,如何 抵抗 100WQPS 热点 ?如何 抵抗雪崩 ?

本文 的 原文 地址 原始的内容,请参考 本文 的 原文 地址 本文 的 原文 地址 10亿用户微博Feed流,100WQPS 热点 如何 抵抗雪崩 ? 一、Feed流系统概述 第一、Feed流基本概念 Feed流是现代社交平台的核心功能,指持续…

三大智能体开发平台详细对比:FastGPT、Dify和Coze

三大智能体开发平台详细对比:FastGPT、Dify和Coze三大智能体开发平台详细对比:FastGPT、Dify和Coze目前,市面上涌现了众多基于 RAG(检索增强生成)的优秀产品,其中以FastGPT、Dify 和Coze 最具代表性,备受用户关…

AI大模型学习路线:(非常详细)AI大模型学习路线,收藏这一篇就够了!

AI大模型学习路线:(非常详细)AI大模型学习路线,收藏这一篇就够了!AI大模型学习路线:(非常详细)AI大模型学习路线,收藏这一篇就够了! 1. 打好基础:数学与编程 数学基础线性代数:理解矩阵、向量、特征值、特…

2025 年二氧化氯发生器厂家最新推荐榜:聚焦国内优质品牌,助力水处理企业精准选购高性价比设备

引言随着我国水处理行业向精细化、高效化方向发展,消毒设备作为水质安全的关键环节,其性能与成本已成为水厂、污水处理厂及养殖企业等用户的核心关注点。当前市场中,二氧化氯发生器品牌数量激增,但产品质量差异显著…

Gitee Insight领跑DevSecOps赛道:2025研发效能工具深度评测

Gitee Insight领跑DevSecOps赛道:2025研发效能工具深度评测 在数字化转型加速推进的当下,研发效能工具已成为企业技术架构中不可或缺的核心组件。随着DevSecOps理念的普及和落地,企业对研发全流程的智能化、安全性和…

基于扩展卡尔曼滤波与无迹卡尔曼滤波的电力系统动态状态估计MATLAB实现

基于扩展卡尔曼滤波(EKF)与无迹卡尔曼滤波(UKF)的电力系统动态状态估计MATLAB实现一、代码 1.1 系统参数初始化 %% 电力系统参数设置 sys = powerflow(ieee39); % 加载IEEE 39节点系统 gen_bus = ; % 发电机节点…

MySQL读写分离—— ProxySQL MyCAT ShardingSphere

MySQL读写分离—— ProxySQL & MyCAT & ShardingSphere实现MySQL读写分离确实有多种成熟的中间件方案可供选择。 最常用的三种中间件及其核心特性,如下:特性​ProxySQL​​MyCAT​​ShardingSphere​​类型​…

定时任务清除Windows服务器30天以上java系统日志

定时任务清除Windows服务器30天以上java系统日志最近服务器上的java系统运行着的时候,突然挂掉了,后来查询问题发现是系统日志太多,把硬盘空间占满了。 于是就上网查询了关于定时任务清除30天以上的系统日志,特意整…

中国研发效能工具市场迎来爆发期:头部厂商如何赋能企业数字化转型?

中国研发效能工具市场迎来爆发期:头部厂商如何赋能企业数字化转型? 随着数字经济的深入发展,研发效能度量工具正在成为中国企业数字化转型的关键基础设施。市场调研数据显示,2023年中国DevOps工具市场规模突破50亿…

MATLAB GUI的通用视频处理

一、系统架构设计 1. 模块化功能设计 graph TDA[主界面] --> B[视频输入模块]A --> C[核心处理引擎]A --> D[输出管理模块]A --> E[参数控制面板]subgraph 核心处理引擎C1(帧提取) --> C2(预处理)C2 --…

AI大模型全栈开发Coze+Dify+MCP+llama+LangChain+LangGraph智能体部署

AI大模型全栈开发Coze+Dify+MCP+llama+LangChain+LangGraph智能体部署如果想让你的智能助手实时获取最新信息,联网检索能力必不可少!然而,Dify插件市场的搜索工具要么需要付费,要么性能有限。而Coze提供的免费网页…

一键生成毛茸萌宠形象,基于函数计算极速部署ComfyUI生图系统

场景简介重要阿里云不对第三方模型的合法性、安全性、准确性进行任何保证,阿里云不对由此引发的任何损害承担责任。您应自觉遵守第三方模型的用户协议、使用规范和相关法律法规,并就使用第三方模型的合法性、合规性自…

Navicat Premium 17.0.3 安装与使用教程|MySQL、Oracle、PostgreSQL全支持

软件介绍 Navicat Premium 17.0.3是一款功能强大的数据库开发工具,它允许用户从单一应用程序中同时连接并管理多种数据库,如MySQL、MariaDB、MongoDB、SQL Server、Oracle、PostgreSQL和SQLite等。这款软件以其新颖的…

国产研发效能工具崛起:Gitee Insight领跑DevSecOps新赛道

国产研发效能工具崛起:Gitee Insight领跑DevSecOps新赛道 在数字化转型浪潮下,研发效能工具市场正经历着前所未有的变革。根据最新行业调研数据显示,2025年中国DevOps工具市场规模预计突破百亿元,其中具备国产化、…

2025-10-15 2个元素a和b,a的层级(z-index)比b的高,a为固定定位(fixed),b为粘性定位(sticky),当二者有部分重叠时,b会遮挡a的原因以及解决方法

原因:可能是由于层叠上下文导致 解决方案:把元素a拎出来,和元素b分开,注意,元素b的父级不能包含元素a,试一下。

MATLAB含风电场RX模型的系统潮流计算

MATLAB实现,用于计算含风电场RX模型的电力系统潮流 1. 主程序文件 main.m - 主程序 %% 含风电场RX模型的系统潮流计算 % 作者: MATLAB助手 % 功能: 实现含风电场的电力系统潮流计算clear; clc; close all;%% 系统参数…

(Adobe Photoshop 2025 )PS2025最新激活版下载安装教程!最新PS 2025安装包免费版下载与保姆级安装教程

软件介绍 Adobe Photoshop 2025 是 Adobe Creative Cloud 生态的旗舰图像处理与设计软件,其版本不断更新,带来了诸多新功能和优化。本次是正式版,直接安装,安装完成就可以直接用了! 软件下载 (PS)Adobe Photoshop…

RocketMQ容器dashboard报错WARNING:IPv4 forwarding is disabled. Networking will not work

RocketMQ容器dashboard报错WARNING:IPv4 forwarding is disabled. Networking will not work这个报错 不是 RocketMQ 自己的问题,而是 宿主机 Linux 内核没有打开 IPv4 转发,导致容器拿不到外部网络(NameServer、Br…

centos 7.9安装zabbix proxy 代理

centos 7.9安装zabbix proxy 代理安装mysql教程8.0.30https://www.cnblogs.com/huzhimin/p/18630995root MyNew@123 ALTER USER root@localhost IDENTIFIED BY Zabbix@2025; 改更root的密码 show databases; 查看所有…