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

news2024/11/14 18:44:22

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.coloradmin.cn/o/1693521.html

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

相关文章

可视化 | Seaborn中的矩阵图及示例

Seaborn是python提供的一个很棒的可视化库。它有几种类型的绘图&#xff0c;通过这些绘图&#xff0c;它提供了惊人的可视化能力。其中一些包括计数图&#xff0c;散点图&#xff0c;配对图&#xff0c;回归图&#xff0c;矩阵图等等。本文讨论了Seaborn中的矩阵图。 示例1&am…

《计算机网络微课堂》2-2 物理层下面的传输媒体

请大家注意&#xff0c;传输媒体不属于计算机网络体系结构的任何一层&#xff0c;如果非要将它添加到体系结构中&#xff0c;‍‍那只能将其放在物理层之下。 传输媒体可分为两类&#xff1a;一类是导引型传输媒体&#xff0c;‍‍另一类是非导引型传输媒体。 在导引型传输媒体…

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

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

使用Python Tkinter创建GUI应用程序

大家好&#xff0c;当我们谈及使用Python Tkinter创建GUI应用程序时&#xff0c;我们涉及的不仅是技术和代码&#xff0c;更是关于创造力和用户体验的故事。Tkinter作为Python标准库中最常用的GUI工具包&#xff0c;提供了丰富的功能和灵活的接口&#xff0c;让开发者能够轻松地…

《计算机网络微课堂》2-3 传输方式

本节课我们介绍几种传输方式&#xff1a; 串行传输和并行传输同步传输和异步传输单工&#xff0c;半双工‍‍以及全双工通信 ​​ ‍ 串行 我们首先来看串行传输和并行传输&#xff0c;串行传输是指‍‍数据是一个比特依次发送的&#xff0c;因此在发送端和接收端之间‍‍只…

YOLOv10 论文学习

论文链接&#xff1a;https://arxiv.org/pdf/2405.14458 代码链接&#xff1a;https://github.com/THU-MIG/yolov10 解决了什么问题&#xff1f; 实时目标检测是计算机视觉领域的研究焦点&#xff0c;目的是以较低的延迟准确地预测图像中各物体的类别和坐标。它广泛应用于自动…

速看!!!24上软考-信息系统项目管理师真题回忆,考点已更新

整理了24上半年软考高级信息系统项目管理师的考试真题&#xff0c;软考一个批次一套题&#xff0c;现在都是机考&#xff0c;收集题目比较困难&#xff0c;希望能给个小小的赞支持一下。 注意&#xff1a;当天考试的宝子们可以对答案预估分数&#xff01;后面场次的宝子可以提…

基于jeecgboot-vue3的Flowable新建流程定义(一)

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、vue3版本因为流程分类是动态的&#xff0c;不再固定了&#xff0c;所以新建的时候需要选择建立哪种流程类型的流程 代码如下&#xff1a; <!-- 选择模型的流程类型对话框 -->&…

Spring Cloud学习笔记(Nacos):配置中心基础和代码样例

这是本人学习的总结&#xff0c;主要学习资料如下 - 马士兵教育 1、Overview2、样例2.1、Dependency2.2、配置文件的定位2.3、bootstrap.yml2.4、配置中心新增配置2.5、验证 1、Overview 配置中心用于管理配置项和配置文件&#xff0c;比如平时写的application.yml就是配置文件…

【MySQL】聊聊脏页flush的原理和控制策略

flush的时机 当更新一条SQL的时候&#xff0c;其实是先写undo日志&#xff0c;然后更新数据&#xff0c;二阶段写入redo 和 bin log。对于更新数据&#xff0c;其实是只修改了changer buffer中的数据&#xff0c;比如将name qxlxi, 但是磁盘数据页没有和内存页数据保持一致。…

删除指定目录

题目描述 我们定义一种目录结构字符串(类似Windows的 tree /f 的输出内容),用它来表达目录树的结构,如图所示: 目录结构字符串的输入仅含数字、字母和|-,其中:|- 表示子目录的层次符号;字母或数字组成目录名(字母大小写敏感)。 某一子目录挂接在其前面、最近的上一层…

【Linux系统编程】进程概念、进程排队、进程标识符、进程状态

目录 什么是进程&#xff1f; 浅谈进程排队 简述进程属性 进程属性之进程标识符 进程操作之进程创建 初识fork fork返回值 原理角度理解fork fork的应用 进程属性之进程状态 再谈进程排队 进程状态 运行状态 阻塞状态 挂起状态 Linux下的进程状态 “R”(运行状…

【Go专家编程——内存管理——垃圾回收】

垃圾回收 所谓的垃圾就上不在需要的内存块&#xff0c;垃圾如果不清理&#xff0c;这些内存块就没有办法再次被分配使用。在不支持垃圾回收的编程语言中&#xff0c;这些垃圾内存就上泄露的内存。 1. 垃圾回收算法 常见的垃圾回收算法有3种 引用计数&#xff1a;对每个对象…

SpringCloud的Config配置中心,为什么要分Server服务端和Client客户端?

SpringCloud的Config配置中心&#xff0c;为什么要分Server服务端和Client客户端&#xff1f; 在SpringCloud的Config配置中心中分了Server服务端和Client客户端&#xff0c;为什么需要这样分呢&#xff1f;它的思想是所有微服务的配置文件都放到git远程服务器上&#xff0c;让…

使用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…

机器学习(五) -- 监督学习(5) -- 线性回归1

系列文章目录及链接 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;4&#xff09; -- 集成学习方法 - 随机森林 下篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;5&#xff09; -- 线性回归2 前言 tips&#xff1…

Redis教程(十五):Redis的哨兵模式搭建

一、搭建Redis一主二从 分别复制三份Redis工作文件夹&#xff0c;里面内容一致 接着修改7002的配置文件&#xff0c;【redis.windows-service.conf】 port 7002 改成 port 7002 slaveof 127.0.0.1 7001 7003也同样修改 port 7003 slaveof 127.0.0.1 7001 这样就指定了700…

B站滑块登录之极验点选

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

【启程Golang之旅】运算符与流程控制讲解

欢迎来到Golang的世界&#xff01;在当今快节奏的软件开发领域&#xff0c;选择一种高效、简洁的编程语言至关重要。而在这方面&#xff0c;Golang&#xff08;又称Go&#xff09;无疑是一个备受瞩目的选择。在本文中&#xff0c;带领您探索Golang的世界&#xff0c;一步步地了…

【qt】标准型模型 下

标准型模型 一.前言二.预览数据1.获取表头2.获取数据项 三.保存文件1.文件对话框获取保存文件名2.用文件名初始化文件对象3.打开文件对象4.用文件对象初始化文本流5.写入数据 四.格式1.居右2.居中3.居左4.粗体 五.模型的信号1.解决粗体action问题2.状态栏显示信息 六.总结 一.前…