Java虚拟机揭秘-底层驱动力,性能保障!


Java虚拟机作为Java技术体系的核心组成部分,其重要性不言而喻。它不仅为Java提供了跨平台的能力,更是Java程序运行的基石。本文将为您深入解析Java虚拟机的工作原理、作用和应用场景,并通过生动的实例让您彻底理解这一关键技术。


一、Java虚拟机详细介绍


1、什么是Java虚拟机?

Java虚拟机(Java Virtual Machine,JVM)是一个虚拟的计算机,它有自己完善的硬件架构,能够运行Java字节码。JVM有着与硬件无关的指令集,屏蔽了与具体操作系统相关的信息,使得Java语言编译后的字节码可以在多种平台上运行。这正是Java"一次编写,处处运行"的根本所在。

JVM 并非只能运行Java语言,而是面向多语言的运行平台,只要遵守JVM的约定(只要编译成.class文件),就可以运行在JVM虚拟机上。

现在除了Java之外,比如scala、kotlin、groovy等语言都运行在JVM上。


在这里插入图片描述


2、Java虚拟机的作用

(1)、内存管理

自动内存管理是JVM最基本的作用之一。JVM通过自动分配和管理内存,防止了手动编码过程中可能出现的内存泄漏等问题。

(2)、跨平台能力

Java字节码可以在任何安装了JVM的设备上运行,这使得Java拥有了出色的跨平台能力,避免了操作系统、硬件的制约。

(3)、自动优化

现代JVM能够对热点代码进行运行时的动态优化,包括生成本地机器代码、内联编译等,大幅提升程序性能。

(4)、安全性

JVM对字节码进行了语法检查、类型检查和安全检查,并提供了沙箱防护机制,确保了Java程序的健壮与安全。


3、JVM、JDK、JRE 的区别与联系

JVM、JDK、JRE是Java开发和运行环境中的三个核心组件,它们之间有着紧密的关系:


(1)、JVM(Java Virtual Machine,Java虚拟机)

JVM是Java平台的核心组成部分,它是一个可以执行Java字节码的虚拟计算机。JVM提供了一个运行时环境,用于加载Java程序的类文件,执行其中的字节码,并管理程序的执行,如内存管理、垃圾回收等。JVM确保了Java的跨平台性,即所谓的“一次编写,到处运行”。


(2)、JRE(Java Runtime Environment,Java运行时环境)

JRE是运行Java应用程序所必需的环境。它包含了JVM以及Java核心类库和其它运行Java程序所需的资源。简单来说,JRE是JVM的宿主环境,它提供了JVM运行所需的所有资源。JRE不包含开发工具,因此它只适用于运行Java程序。


(3)、 JDK(Java Development Kit,Java开发工具包)

JDK是为Java开发者提供的一套工具包,它包含了JRE的所有内容,并且还包括了用于开发Java应用程序的工具和库。JDK中包含了javac编译器、调试器、jar工具、Java文档生成器(javadoc)等开发工具。此外,JDK还包含了一些用于Java性能测量和监控的工具,以及Java平台的源代码。


(4)、JDK、JRE和JVM的关系

  • JVM是JRE的一部分:JRE提供了JVM,使得Java程序可以在不同的平台上运行。

  • JDK包含了JRE:JDK中包含了一个完整的JRE,因此安装了JDK就不需要单独安装JRE。

  • JDK为开发者提供工具:JDK提供了编译器和调试器等开发工具,而JRE和JVM则提供了运行Java程序所需的环境。


(5)、应用场景

  • JRE适用于只运行Java程序的用户:如果只需要运行Java程序,不需要开发Java程序,那么安装JRE就足够了。
  • JDK适用于Java开发者:如果你是一名Java开发者,需要编写、编译和调试Java程序,那么需要安装JDK。

总之:

JVM作为核心,提供了字节码的执行环境;JRE作为JVM的宿主,提供了运行时所需的资源;JDK则为开发者提供了完整的开发和运行环境。


二、Java虚拟机的工作原理

Java虚拟机的工作过程可以概括为以下几个阶段:

在这里插入图片描述


1、编译阶段

首先 java经过javac编译成.class文件。

类的编译阶段主要是把源码文件编译成JVM可以解析的class文件,这个阶段会经过词法分析、语法语义分析、生成字节码,这个几个阶段后生成最后的class,用16进制的方式打开class文件后如图:

在这里插入图片描述


class 文件是Java编译器将Java源代码(.java 文件)编译后生成的字节码文件。这个文件是JVM执行引擎执行的基础。.class 文件包含了多种类型的数据,用于确保JVM能够正确地加载、链接和执行代码。以下是.class 文件中包含的主要内容:

  • 魔数(Magic Number)
    每个.class 文件的开始都是魔数,用于标识这个文件是否是一个有效的类文件。魔数是四个字节,值为 0xCAFEBABE

  • 版本信息
    包括主版本号和次版本号,用于确定这个.class 文件是为哪个版本的Java虚拟机编译的。

  • 常量池(Constant Pool)
    常量池用于存储编译期间生成的各种字面量和符号引用。这部分可能包括类和接口的名称、字段名、方法名、字符串常量等。

  • 访问标志(Access Flags)
    定义了这个类或接口的访问权限,如是否是公共的(public)、抽象的(abstract)等。

  • 类索引、父类索引
    类索引用于确定这个类的全名,父类索引指向常量池中的一个引用,表示这个类的直接父类。

  • 接口索引表(Interfaces)
    如果这个类实现了一个或多个接口,接口索引表将列出这些接口。

  • 字段表集合(Fields)
    字段表包含了类的字段信息,每个字段都有其名称、描述符、访问修饰符等。

  • 方法表集合(Methods)
    方法表包含了类的方法信息,包括方法的名称、返回类型、参数列表、局部变量表、字节码指令等。

  • 属性表集合(Attributes)
    属性表可以包含多种不同的属性,如代码(Code)属性包含了实际的字节码指令、行号表、异常处理表等;SourceFile属性表示源代码文件的名称;还有其他如Deprecated、Synthetic等属性。

  • 字节码(Bytecode)
    方法的字节码是JVM执行的指令集,定义了方法的行为。

  • 栈映射表(Stack Map Table)
    在较新的JVM版本中,栈映射表用于支持字节码的验证和JIT编译器的优化。

  • 异常表(Exception Table)
    如果方法中有try-catch块,异常表将列出可能抛出的异常类型和异常处理器。

这些组成部分共同定义了Java类的结构和行为,使得JVM能够加载和执行Java程序。开发者通常不会直接编辑.class 文件,而是通过Java源代码进行编程,并利用编译器生成这些字节码文件。


2、类加载阶段

Java 类加载过程是 Java 运行时环境中的一个关键特性,它涉及到将 Java 类(通常是 .class 文件)加载到 JVM(Java 虚拟机)中,并为类的实例化和执行做准备。类加载过程大致可以分为以下几个阶段:


(1)、加载(Loading)

加载是类加载过程的第一个阶段,在这个阶段,JVM 完成以下任务:

  • 通过类的全名查找 .class 文件。

  • 加载 .class 文件到内存中,通常使用二进制形式。

  • 通过解析常量池中的符号引用(如类名、方法名、字段名等),将它们转换为直接引用。


(2)、验证(Verification)

验证阶段确保加载的类信息是合法的、符合JVM规范的,不会危害虚拟机安全。验证包括以下几个方面:

  • 文件格式验证:确保 .class 文件符合Java类文件的规范。

  • 元数据验证:检查类的结构信息,如访问修饰符、类和接口的继承关系等。

  • 字节码验证:确保字节码的指令不会做出危害虚拟机安全的行为。

  • 符号引用验证:确保符号引用能正确解析。


(3)、准备(Preparation)

准备阶段是为类的静态变量分配内存,并设置初始值。这里的初始值指的是数据类型的零值,如:

  • 整数类型 int 的初始值为 0
  • 浮点类型 float 的初始值为 0.0
  • 引用类型(如类、接口、数组)的初始值为 null
  • boolean 类型的初始值为 false
  • char 类型的初始值为 \u0000(Unicode编码中的空字符)。

(4)、解析(Resolution)

解析阶段是将常量池中的符号引用转换为直接引用的过程。直接引用是指向内存中的直接地址。解析包括:

  • 类或接口的解析。

  • 字段的解析。

  • 方法的解析。

  • 接口方法的解析。

  • 字段和方法的访问权限的解析。


(5)、初始化(Initialization)

初始化是类加载的最后一个阶段,它包括:

  • 执行静态初始化块(使用 static 关键字声明的代码块)。
  • 为静态变量赋予正确的初始值。
  • 如果类具有超类(除了 Object 类之外),则先初始化其超类。

执行顺序和触发条件:

  • 类的加载过程是按照上面列出的顺序进行的,但并不是所有的类都会经过所有阶段。例如,如果一个类没有进行任何静态变量的赋值操作,那么它可能不会进入初始化阶段。
  • 类的加载是由某个特定的动作触发的,如 new 关键字实例化对象、访问静态字段、调用静态方法等。

注意事项:

  • 类加载器不仅仅加载 .class 文件,它还负责加载包和其他资源文件。
  • 类加载过程是线程安全的。
  • 类加载器的父子委派模型确保了Java核心库的安全性,防止核心库被随意替换。

通过以上各个阶段,JVM 确保了类的安全性、一致性和可用性,为类的执行提供了必要的准备和初始化工作。


3、解释和执行阶段

加载完成后,执行引擎负责解释和执行字节码指令。执行引擎主要由解释器和即时编译器(JIT)两部分组成。解释器逐条解释字节码,JIT则能够动态编译热点代码为优化后的本地机器码以提高执行效率。

执行引擎通常包括以下部分:

  • 字节码解释器:负责逐条解释执行字节码。

  • 即时编译器:负责将热点字节码编译为机器码。

  • 代码优化器:负责对编译后的机器码进行进一步的优化。

  • 代码缓存:存储编译后的机器码,供后续执行使用。


(1)、解释执行(Interpretation)

执行引擎的一种基本工作模式是解释执行。在这种模式下,执行引擎逐条读取字节码,并根据字节码执行相应的操作。这种方式类似于我们在学习编程时使用的解释器。

过程:

  • 第一步,字节码扫描:执行引擎从PC寄存器(程序计数器)指向的字节码指令开始执行。

  • 第二步,解释执行:对每条字节码进行解释,并执行其对应的操作。

  • 第三步,状态更新:更新操作数栈、局部变量表和程序计数器等状态。

  • 第四步,循环执行:继续扫描下一条字节码,直到方法执行完毕或遇到返回指令。


(2)、即时编译(Just-In-Time Compilation, JIT)

为了提高程序的执行效率,现代JVM通常采用即时编译技术。即时编译器将热点代码(频繁执行的代码)编译为本地机器码,以提高执行速度。

过程:

  • 第一步,代码选择:JIT编译器选择需要编译的热点代码,这些代码可能是被多次调用的方法或循环体。

  • 第二步,编译优化:JIT编译器将字节码编译为机器码,并进行优化,如分支预测、循环展开等。

  • 第三步,本地代码缓存:编译后的机器码被存储在执行引擎的代码缓存中,以便重复使用。

  • 第四步,执行本地代码:执行引擎直接执行编译后的机器码,而不是逐条解释字节码。


(3)、热点代码探测(HotSpot Code Detection)

为了确定哪些代码需要即时编译,JVM需要能够探测热点代码。这通常通过以下方式实现:

  • 计数器:为每个方法入口和循环回边设置计数器,统计执行次数。
  • 阈值设定:当计数器达到一定阈值时,认为该代码是热点代码,适合进行即时编译。

(4)、多版本优化(Multi-Versioning)

为了进一步优化性能,JVM可以为同一段代码生成多个版本,以适应不同的执行环境或条件。例如,基于处理器的CPU架构特点,生成优化的机器码。

JVM的执行引擎是实现Java程序高效运行的关键。通过解释执行和即时编译,执行引擎能够在保持跨平台特性的同时,提供接近本地编译语言的性能。随着JVM技术的发展,执行引擎的优化策略也在不断进步,以满足日益增长的性能需求。


4、内存管理阶段

Java虚拟机负责自动分配和管理堆、栈、方法区等运行时数据区域。其中垃圾收集器(GC)通过跟踪可达性分析,自动回收无用对象的内存空间。

JVM内存管理是确保Java程序高效运行的关键环节。JVM内存管理主要包括以下几个阶段:

(1)、类加载过程中的内存分配

当JVM开始加载一个类时,它会为这个类分配内存以存储类的元数据。这包括类的信息、字段、方法等。这个阶段的内存分配是在方法区(Method Area)进行的。


(2)、对象创建时的内存分配

当使用new关键字创建一个对象时,JVM会在堆(Heap)中为这个新对象分配内存。堆是JVM中用于存储对象实例和数组的部分。

过程:

  • 确定对象大小:JVM首先确定对象所需的内存大小。

  • 内存分配:在堆中找到足够大的连续空间分配给对象。

  • 对象头信息设置:设置对象头(Mark Word),包含对象的哈希码、GC信息、锁状态等。

  • 初始化:执行<init>方法,对对象进行初始化。


(3)、 运行时的内存管理

在程序运行期间,JVM需要不断管理内存的使用,包括局部变量的创建和销毁,以及对对象的访问。

过程:

  • 局部变量表:方法执行时,其局部变量会在栈(Stack)的局部变量表中分配空间。

  • 操作数栈:方法执行过程中,临时数据会在操作数栈中存取。

  • 引用访问:通过引用访问堆中的对象,进行读写操作。


(4)、垃圾收集(Garbage Collection, GC)

JVM周期性地执行垃圾收集,回收不再被引用的对象所占用的内存。

过程:

  • 可达性分析:从一系列的GC Roots开始,标记所有可达的对象。
  • 清理:清除未被标记的对象,回收内存。
  • 内存整理:可选地整理内存,减少碎片。

(5)、 内存分配和回收策略

JVM使用不同的算法和策略来优化内存的分配和回收。例如:

  • 复制算法:用于新生代,将内存分为一个eden区和两个survivor区,对象在这些区域之间复制。
  • 标记-清除算法:用于老年代,首先标记所有存活的对象,然后清除未被标记的对象。
  • 标记-清除-整理:在标记-清除的基础上,对内存进行整理,消除碎片。

(6)、内存分配的并发处理

为了避免在内存分配和回收过程中的Stop-The-World现象,JVM采用了并发处理机制:

  • 并发标记:在应用程序运行的同时进行对象的标记。
  • 并发清理:在应用程序运行的同时进行内存的清理。
  • 增量收集:将垃圾收集过程分步骤执行,减少GC暂停时间。

(7)、 内存溢出处理

当JVM的内存不足时,会抛出内存溢出异常。例如,堆内存不足时会抛出OutOfMemoryError

JVM内存管理是一个复杂的过程,涉及到内存的分配、垃圾收集、内存整理和并发处理等多个方面。通过有效的内存管理策略,JVM确保了Java程序的高效运行,同时提供了自动内存管理和垃圾回收功能,简化了内存管理的复杂性。了解JVM内存管理的工作原理对于Java开发者来说是非常重要的,它有助于我们编写更高效的程序,并在遇到性能问题时能够快速定位和解决。


// GC示例
public static void main(String[] args) {byte[] array = new byte[1024 * 1024 * 50]; //50MB数组array = null; // 数组不可访问System.gc(); // 触发GC
}

5、执行子系统阶段

JVM执行子系统不仅仅是执行字节码的组件,它还提供了与操作系统之间通信的能力,支持线程同步、文件I/O等操作。以下是执行子系统在这些方面的作用和实现方式:


(1)、线程管理

JVM执行子系统负责管理Java程序中的线程。每个线程在操作系统中都对应一个内核线程,JVM需要管理这些线程的创建、同步、调度和终止。

  • 线程创建

    • Java程序通过Thread类或Runnable接口启动新线程。JVM负责将这些线程映射到操作系统的线程。
  • 线程同步

    • JVM提供了同步机制,包括synchronized关键字和java.util.concurrent包中的并发工具,以确保线程安全。
  • 线程调度

    • JVM执行子系统与操作系统的调度器协作,管理线程的执行顺序和时间分配。


(2)、系统调用

JVM提供了对本地系统调用的接口,使得Java程序能够执行操作系统级别的操作。

JVM通过本地库接口(如Java Native Interface, JNI)允许Java代码调用本地方法,实现与操作系统的交互。


(3)、文件I/O 及操作

JVM执行子系统支持文件输入输出操作,使得Java程序能够读写文件。

I/O操作:

Java程序使用java.iojava.nio包中的类进行文件I/O操作。JVM负责将这些操作映射到对应的操作系统I/O调用。


(4)、网络通信

JVM支持网络通信,使得Java程序能够进行网络连接和数据传输。

网络I/O:

Java程序使用java.net包中的类进行网络编程。JVM负责网络连接的建立、数据的发送和接收。


(5)、 安全性

JVM执行子系统还负责执行安全策略,确保Java程序不会执行有害的系统操作。


(6)、安全管理器

JVM提供了安全管理器(java.lang.SecurityManager),可以监控和限制程序对系统资源的访问。


(7)、 性能监控与优化

JVM执行子系统还包括性能监控和优化工具,帮助开发者了解程序的运行情况,并进行性能调优。


JVM执行子系统是Java程序与操作系统之间的桥梁。它不仅负责执行字节码,还提供了线程管理、内存管理、系统调用、文件I/O、网络通信等能力,确保Java程序能够高效、安全地运行。通过JVM执行子系统,Java程序能够充分利用操作系统提供的资源和功能。


以上就是Java虚拟机的基本工作流程,体现了JVM为Java提供了一个安全、高效的运行环境。


三、Java虚拟机的应用场景


Java虚拟机为我们提供了无数的便利,可以在以下场景大显身手:
  • 跨平台应用开发

    JVM的存在使得Java可以运行于任何安装了虚拟机的平台,从而实现了跨平台的能力,如Android应用、嵌入式设备、云服务器等。

  • 大数据分析

    Hadoop、Spark等大数据处理框架都是建立在JVM之上,利用其高效的内存管理和多线程支持,极大提高了分布式计算能力。

  • 中间件服务

    Java的各种应用服务器中间件如WebLogic、WebSphere、Tomcat等,都是基于JVM构建的,发挥了JVM提供的跨平台、高效、安全等特性。


总之,Java虚拟机作为Java技术体系的根基,贯穿于Java应用的方方面面。了解JVM的工作原理和特性,将使我们能够编写出更加高效、可靠的程序。期待在下期与您分享更多关于JVM调优和故障排查的干货知识,敬请期待!


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

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

相关文章

element-plusDate Picker 日期选择器获取年月日

代码逻辑 对选择日期选择后进行搜索 &#xff1a; function dataValue(value) {console.log(value);scenic_list.value arrlist.value.filter(function (item) {// 判断是否满足搜索条件if (String(item.create_time).indexOf(String(value)) > -1) {return scenic_list}}…

SpringMVC流程

1、SpringMVC常用组件&#xff1a; DispatcherServlet&#xff08;请求分发器&#xff09;&#xff1a;Spring MVC的核心组件之一&#xff0c;负责处理全局配置和将用户请求分发给其他组件进行处理。Controller&#xff08;处理器&#xff09;&#xff1a; 实际处理业务逻辑的…

B站滑块登录之极验点选

滑块登录这些东西都不是很难&#xff0c;我个人的去处理的话一般会考虑三种方案&#xff0c;一个是自动化selenium 二是各类打码平台 三是ocr识别&#xff0c;本文是selenium接打码平台&#xff0c;也是个比较常规的操作。 先常规步骤跟着来吧&#xff0c;做登录的话把基本的模…

Tower在深度学习中的概念,tower没有确切定义

在论文UniTS中&#xff0c;来自Havard的工作。 tower更像是针对一个task的组件 tower这个概念貌似在REC&#xff08;recommendation&#xff09;推荐系统中使用较多 deep learning - What is a tower? - Data Science Stack Exchange https://developers.google.com/machin…

技术前沿 |【VL-BEIT:引领未来的极简单阶段多模态预训练方案】

VL-BEIT&#xff1a;引领未来的极简单阶段多模态预训练方案 引言一、VL-BEIT的基本介绍二、VL-BEIT的原理和工作方式三、VL-BEIT的特点四、VL-BEIT的应用场景五、总结与展望 引言 在人工智能蓬勃发展的今天&#xff0c;多模态预训练模型正逐渐成为研究和应用的热点。这些模型能…

二叉树OJ题目

一.二叉树第k层结点个数 有这样的一个思路&#xff1a;我既然要求第k层的结点个数&#xff0c;我肯定是要用到递归&#xff0c;那么当我在递归到第k层的时候我就开始判断&#xff0c;这一层是不是我所需要的那一层&#xff0c;如果是&#xff0c;就计数有几个节点&#xff0c;…

边框渐变样式

实现样式&#xff1a; 对应代码&#xff1a; div {min-height: 40vh;border: 10px solid transparent;background-image: linear-gradient(#222, #222), var(--gradient);background-origin: border-box;background-clip: padding-box, border-box;border-radius: 10px;positi…

粉丝问,有没有UI的统计页面,安排!

移动应用的数据统计页面具有以下几个重要作用&#xff1a; 监控业务指标&#xff1a;数据统计页面可以帮助用户监控关键业务指标和数据&#xff0c;例如用户活跃度、销售额、转化率等。通过实时更新和可视化呈现数据&#xff0c;用户可以及时了解业务的整体状况和趋势。分析用…

每日练习之字符串——得分

得分 题目描述 运行代码 #include <iostream> using namespace std; int main(){int n;cin>>n;while(n--){string s;cin>>s;int ls.length();int a0;int t1;for(int i0;i<l;i){if(s[i]O){at;t;}else if(s[i]X){t1;}}cout<<a<<endl;} } 代码…

QT7_视频知识点笔记_5_线程,数据库

多线程 两种办法&#xff1a;第一种&#xff1a;Qt4.7之前的线程使用的方法&#xff08;简单&#xff09;&#xff1b;第二种&#xff1a;Qt4.7之后的&#xff08;灵活–推荐&#xff09;----connect最后一个参数的作用&#xff1a;默认连接&#xff0c;队列连接&#xff0c;直…

操作系统总结4----死锁的处理策略总结

目录 2.4.2 死锁的处理策略-----预防死锁 &#xff08;1&#xff09;知识总览 &#xff08;2&#xff09;破环互斥条件 &#xff08;3&#xff09;破环不剥夺条件 &#xff08;4&#xff09;破环求情和保持条件 &#xff08;5&#xff09;破环循环等待条件 总结 2.4.3 死…

AI革命:生活无处不智能

AI革命&#xff1a;生活无处不智能 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享学习心得&#xff0…

使用FFmpeg推流实现在B站24小时点歌直播

使用FFmpeg推流实现在B站24小时点歌直播 本文首发于个人博客 安装FFmpeg centos7 https://www.myfreax.com/how-to-install-ffmpeg-on-centos-7/ https://linuxize.com/post/how-to-install-ffmpeg-on-centos-7/ 使用FFmpeg在B站直播 https://zhuanlan.zhihu.com/p/2395…

竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

FreeRTOS任务间通信“IPC”

---------------信号量--------------- 信号量的定义&#xff1a; 操作系统中一种解决问题的机制&#xff0c;可以实现 “共享资源的访问” 信号&#xff1a;起通知作用量&#xff1a;还可以用来表示资源的数量当"量"没有限制时&#xff0c;它就是"计数型信…

C++原创人工智能QPBS01G大功告成!!!

俗话说得好&#xff0c;你周五周六不写作业&#xff0c;要上学了才着急了 我之前的版本bug太多&#xff0c;结果这两天晚上改的我两眼发白&#xff0c;太烦人了 这次这娃学聪明了&#xff0c;遇到不会的问题上网搜&#xff0c;我还更新了反骂人骂人功能&#xff0c;第一次测试…

抖音小店新规又来了!平台下调了两项门槛,惊掉商家下巴!

大家好&#xff0c;我是电商糖果 平台这几年为了快速发展电商项目&#xff0c;一直在向商家释放友好政策&#xff0c;目的就是为了吸引更多的商家入驻。 这不官方5月30日起下调了两个门槛&#xff0c;让不少商家大呼不可思议。 第一个就是保证金下调。 平台按照商家经营类目…

ProxySQL路由策略实现读写分离

目的&#xff1a;配置proxysql路由策略后将不同用户的不同请求路由到不同的节点&#xff0c;实现读写分离 前提条件&#xff1a; 配置表mysql_replication_hostgroups&#xff0c;10为写组&#xff0c;20为读组 mysql_users表中已添加用户writer用户加入10写组&#xff0c;rea…

【QT八股文】系列之篇章3 | QT的多线程以及QThread与QObject

【QT八股文】系列之篇章3 | QT的多线程 前言4. 多线程为什么需要使用线程池线程池的基础知识python中创建线程池的方法使用threading库队列Queue来实现线程池使用threadpool模块&#xff0c;这是个python的第三方模块&#xff0c;支持python2和python3 QThread的定义QT多线程知…

下一代Docker会让部署更丝滑吗

下一代Docker会让部署更丝滑吗 如何通俗易懂的理解DockerDocker有什么缺点Docker与AI结合&#xff0c;会让部署更加丝滑吗 随着互联网技术的不断发展&#xff0c;单机系统已经无法满足日益正常的用户量以及正常处理用户请求&#xff0c;这个时候就需要进行多机部署&#xff0c;…