当前位置: 首页 > news >正文

JVM——Java 虚拟机是如何加载 Java 类的?

引入

在 Java 世界的底层运作中,类加载机制扮演着一个既神秘又关键的角色。它就像是一个精心设计的舞台幕后 machinery,确保了 Java 程序能够顺利运行。今天,我们就深入探索 Java 虚拟机(JVM)是如何加载 Java 类的。

类加载的背景

Java 语言的一个核心优势是它的平台无关性,而这一优势在很大程度上依赖于 Java 虚拟机(JVM)。JVM 作为一个抽象的规范,定义了一个可以执行 Java 字节码的环境。这个环境能够将 Java 字节码转换成特定平台上的机器码,从而实现了 “一次编写,到处运行” 的承诺。

Java 程序在运行时,需要将类文件(.class)加载到 JVM 的内存中。这个过程不仅涉及到类文件的读取,还包括对类的验证、准备、解析和初始化等一系列复杂的操作。这些步骤确保了类的正确性和安全性,并为类的执行做好准备。

类加载的步骤

类加载过程可以分为以下三个主要阶段:加载(Loading)、链接(Linking)和初始化(Initialization)。

每个阶段都有其独特的任务和目标。

(一)加载阶段

加载阶段是类加载过程的起始点。在这个阶段,JVM 需要将类的字节码从各种来源(如本地文件系统、网络等)读取进来,并将其转换为一个 Java 类的表示形式,存放在方法区(Method Area)中。

  1. 字节码来源:字节码可以来源于多个渠道,最常见的是由 Java 编译器生成的 class 文件。除此之外,字节码也可以在程序运行时动态生成,或者从网络中获取(例如在网页中运行的 Java Applet)。

  2. 类加载器:类加载器(ClassLoader)是加载阶段的核心组件。JVM 提供了多个内置的类加载器,包括启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用类加载器(Application ClassLoader)。每个类加载器都有其特定的职责和加载路径。

    • 启动类加载器:负责加载 Java 核心类库(如 java.lang.Object、java.lang.String 等),这些类位于 JRE 的 lib 目录下。

    • 扩展类加载器:负责加载 Java 扩展类库,这些类通常位于 JRE 的 lib/ext 目录下。

    • 应用类加载器:负责加载应用程序类路径(classpath)上的类文件。

  3. 双亲委派模型:类加载器采用了双亲委派模型(Parent Delegation Model)。当一个类加载器收到类加载请求时,它会先将请求委托给父类加载器。只有当父类加载器无法完成加载任务时,子类加载器才会尝试自己加载。这种模型保证了 Java 核心类库的类总是由启动类加载器加载,避免了类的多次加载和版本冲突问题。

(二)链接阶段

链接阶段的目标是将加载进来的类整合到 JVM 中,使其能够被虚拟机执行。

链接过程分为三个步骤:验证、准备和解析。

  1. 验证:验证阶段确保加载的类信息符合 JVM 的规范,并且不会危害虚拟机的安全。这一步骤对类的字节码进行严格检查,包括文件格式验证、元数据验证、字节码验证和符号引用验证。

    • 文件格式验证:检查类文件的格式是否正确,例如魔数是否正确、版本号是否受支持等。

    • 元数据验证:验证类的元数据(如字段、方法、访问修饰符等)是否符合语义规范。

    • 字节码验证:分析字节码指令,确保它们不会执行非法操作,如非法跳转、类型转换错误等。

    • 符号引用验证:确保解析动作能正确执行,即符号引用所指向的类、字段、方法确实存在。

  2. 准备:准备阶段为类的静态变量分配内存,并设置其初始值。这些初始值通常是该类型的默认值(如整数类型的默认值为 0,布尔类型的默认值为 false 等)。在这个阶段,JVM 还会为类的字段、方法等创建数据结构,以便后续的访问和操作。

  3. 解析:解析阶段将类、接口、字段和方法的符号引用转换为直接引用。符号引用是以符号形式表示的类、接口、字段或方法的名称和描述符等信息。直接引用则是指向内存中具体位置的指针或句柄,可以直接访问目标数据。解析过程包括对类或接口、字段、方法和接口方法的解析。

(三)初始化阶段

初始化阶段是类加载过程的最后一步。在这个阶段,JVM 执行类构造器(<clinit>() 方法),对类的静态变量进行初始化操作。类的初始化是按照 Java 代码的语义进行的,包括对静态变量的显式赋值和静态代码块的执行。

  1. 类构造器 <clinit>():类构造器是由编译器生成的特殊方法,它包含了类的静态变量初始化代码和静态代码块中的代码。JVM 会保证类构造器只被调用一次,并且在多线程环境下是线程安全的。

  2. 初始化触发条件:类的初始化并不是在类加载完成后立即执行的,而是需要满足一定的条件才会触发。以下是一些常见的触发类初始化的场景:

    • 遇到 new 指令,创建类的实例。

    • 调用类的静态方法。

    • 访问类的静态字段。

    • 子类的初始化会触发父类的初始化。

    • 使用反射 API 对类进行反射调用。

    • 初始化一个接口时,如果该接口含有 static-initializerdefault 方法,则会触发接口的初始化。

类加载的实践示例

接下来,我们通过一个简单的示例来展示类加载的过程。我们将使用以下代码片段来演示类的加载和初始化。

public class Singleton {private Singleton() {}
​private static class LazyHolder {static final Singleton INSTANCE = new Singleton();static {System.out.println("LazyHolder.<clinit>");}}
​public static Object getInstance(boolean flag) {if (flag) {return new LazyHolder[2];}return LazyHolder.INSTANCE;}
​public static void main(String[] args) {getInstance(true);System.out.println("----");getInstance(false);}
}

在上述代码中,我们定义了一个单例类 Singleton,并使用了懒汉式模式的 LazyHolder 内部类来实现延迟初始化。我们可以通过以下步骤来观察类加载和初始化的过程:

  1. 打印类加载日志:使用 JVM 参数 -verbose:class 来打印类加载的顺序。这个参数会告诉 JVM 在控制台输出每个类加载的信息。

    java -verbose:class Singleton
  2. 观察类初始化的触发时机:在 LazyHolder 内部类的静态代码块中打印特定字样,以便观察类初始化的时机。

  3. 修改字节码并重新加载:使用 jdisjasm 工具对类的字节码进行反汇编和重新汇编,观察修改后的类加载和初始化行为。

拓展

自定义类加载器

除了 JVM 提供的默认类加载器外,我们还可以创建自定义类加载器来实现特殊的类加载需求。自定义类加载器可以实现以下功能:

  • 对类文件进行加密和解密,以保护代码不被轻易篡改或窃取。

  • 动态生成类字节码,实现运行时类的动态加载。

  • 加载来自网络或其他非传统来源的类文件。

自定义类加载器通过继承 java.lang.ClassLoader 类并重写 findClass 方法来实现自定义的类加载逻辑。

public class CustomClassLoader extends ClassLoader {@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {// 自定义类加载逻辑byte[] classData = loadClassData(name);if (classData == null) {throw new ClassNotFoundException();}return defineClass(name, classData, 0, classData.length);}
​private byte[] loadClassData(String name) {// 实现类数据的加载逻辑// 例如从文件系统、网络或加密存储中读取类文件return null;}
}

命名空间和类的唯一性

类加载器在 Java 中还提供了一个重要的功能:命名空间隔离。类的唯一性不仅由类的全名(包括包名和类名)决定,还与加载它的类加载器实例相关。这意味着,即使两个类具有相同的全名,如果它们是由不同的类加载器加载的,JVM 也会将它们视为不同的类。

这一特性在许多应用场景中非常有用,例如:

  • 在 Web 服务器中,不同的 Web 应用程序可以加载相同名称的类,而不会相互干扰。

  • 在 osgi 等模块化系统中,类加载器的命名空间隔离机制可以实现模块之间的版本隔离和依赖管理。

性能优化和工具支持

JVM 提供了丰富的工具来监控和优化类加载过程。

以下是一些常用的工具和参数:

  • -verbose:class:打印类加载的详细日志,帮助开发者了解类加载的顺序和时机。

  • -XX:+TraceClassLoading:输出类加载的追踪信息,提供更详细的类加载调试数据。

  • jstat:监控 JVM 的类加载和卸载统计信息,包括已加载的类数、卸载的类数、内存使用情况等。

  • jvisualvm:一个图形化工具,可以直观地显示 JVM 的运行状态,包括类加载信息、内存使用情况、线程状态等。

常见问题

新建数组是否会加载和初始化元素类?

在 Java 中,新建数组(如 new LazyHolder[2])会导致元素类的加载,但不会触发元素类的初始化。这是因为数组的创建只需要加载元素类的类信息,而不需要立即对数组元素进行初始化。只有当首次主动使用到数组元素类时(如访问数组元素或调用其静态方法),才会触发元素类的初始化。

类加载和链接的触发时机

类的加载和链接过程并不是在类被首次使用时才发生。实际上,类的加载可能在以下几种情况下被触发:

  • 当类作为 Java 应用程序的主类时,会在程序启动时被加载。

  • 当类被用作父类且子类被初始化时,父类会被加载和链接。

  • 当类被用作接口的实现类且接口被初始化时,类会被加载和链接。

链接过程中的验证、准备和解析步骤通常在类加载之后立即进行,但在某些情况下,解析步骤可能会延迟到首次使用相关符号引用时才执行。

如何避免类加载的性能瓶颈?

在大型 Java 应用中,类加载过程可能会成为性能瓶颈,尤其是在应用启动阶段。以下是一些优化类加载性能的建议:

  • 减少不必要的依赖:清理项目的类路径,移除未使用的库和类文件,可以减少类加载的数量和时间。

  • 优化类加载器的层次结构:合理设计类加载器的层次结构,避免过多的类加载器层级和复杂的委派链,可以提高类加载的效率。

  • 使用类预加载技术:对于一些关键类或频繁使用的类,可以在应用启动时提前加载,避免在运行时动态加载导致的延迟。

  • 监控和分析类加载过程:使用 JVM 提供的监控工具(如 jstatjvisualvm 等)来分析类加载的性能瓶颈,根据实际情况进行优化。

总结

Java 虚拟机的类加载机制是 Java 平台无关性和安全性的基石。通过加载、链接和初始化三个阶段,JVM 将类文件转换为内存中的类表示,并确保类的正确性和安全性。深入了解类加载的过程,不仅可以帮助我们更好地理解 Java 语言的底层运作机制,还能在实际开发中优化类加载性能,解决类加载相关的问题。

在实际应用中,掌握类加载机制的细节对于构建高效、可靠的 Java 应用至关重要。通过合理利用 JVM 提供的类加载器和工具,我们可以更好地管理类的加载过程,提升应用的性能和稳定性。希望本文能够为你深入探索 Java 虚拟机的类加载机制提供有价值的参考和指导。

如果你在类加载过程中遇到任何问题,或者对本文有任何疑问或建议,欢迎在评论区留言交流。让我们一起深入学习,共同进步!

相关文章:

JVM——Java 虚拟机是如何加载 Java 类的?

引入 在 Java 世界的底层运作中&#xff0c;类加载机制扮演着一个既神秘又关键的角色。它就像是一个精心设计的舞台幕后 machinery&#xff0c;确保了 Java 程序能够顺利运行。今天&#xff0c;我们就深入探索 Java 虚拟机&#xff08;JVM&#xff09;是如何加载 Java 类的。 …...

Sigmoid函数导数推导详解

Sigmoid函数导数推导详解 在逻辑回归中&#xff0c;Sigmoid函数的导数推导是一个关键步骤&#xff0c;它使得梯度下降算法能够高效地计算。 1. Sigmoid函数定义 首先回顾Sigmoid函数的定义&#xff1a; g ( z ) 1 1 e − z g(z) \frac{1}{1 e^{-z}} g(z)1e−z1​ 2. 导…...

运维工作中,Ansible常用模块有哪些?

Ansible是一个强大的自动化运维工具&#xff0c;他通过模块来执行各种任务。Ansible的模块库非常丰富&#xff0c;涵盖了系统管理、文件操作、软件包管理、网络配置、云服务等多个领域。以下是Ansible中常见的模块分类及具体模块详细介绍&#xff1a; 系统管理模块 主要用于管…...

内存安全的攻防战:工具链与语言特性的协同突围

一、内存安全&#xff1a;C 开发者永恒的达摩克利斯之剑 在操作系统内核、游戏引擎、金融交易系统等对稳定性要求苛刻的领域&#xff0c;内存安全问题始终是 C 开发者的核心挑战。缓冲区溢出、悬空指针、双重释放等经典漏洞&#xff0c;每年在全球范围内造成数千亿美元的损失。…...

Linux-04-搜索查找类命令

一、find查找文件或目录: 1.基本语法: find指令将从指定目录向下递归地遍历其各个子目录1&#xff0c;将满足条件的文件显示在终端 find[搜索范围] [选项] 2.选项说明: 选项功能-name <查询方式>按照指定的文件名查找模式查找文件-user <用户名>查找属于指定用…...

移动光猫 UNG853H 获取超级管理员账号密码

注&#xff1a;电脑连接光猫&#xff0c;网线不要接2口&#xff08;2口一般是IPTV网口&#xff09; 首先浏览器打开 192.168.1.1&#xff0c;使用光猫背面的用户名密码登录。&#xff08;user用户名&#xff09; 然后在浏览器中另开一个窗口打开以下地址&#xff1a; http://…...

健康生活新主张:全方位养生指南

在追求高品质生活的今天&#xff0c;健康养生早已不是老年人的专属话题&#xff0c;而是每个人都该掌握的生活技能。科学养生不需要复杂的程序&#xff0c;而是通过日常习惯的优化&#xff0c;为身体注入源源不断的活力。 饮食管理是健康的根基。选择天然、少加工的食材&#x…...

py使用uniad原生sdk 3, 放弃Buildozer,使用BeeWare

目前&#xff0c;Buildozer 支持打包&#xff1a; Android&#xff1a;通过 Python for Android。您必须有 Linux 或 OSX computer 才能为 Android 进行编译。 iOS&#xff1a;通过 Kivy iOS。您必须拥有 OSX computer 才能为 iOS 进行编译。 支持其他平台在路线图中&#xf…...

【数据分享】2020年中国高精度森林覆盖数据集(免费获取)

森林作为全球陆地生态系统的主体&#xff0c;分布面积广、结构复杂&#xff0c;承担着调节气候、维护生态安全、改善环境等方面的重要作用。我国的森林资源丰富&#xff0c;据《中国森林资源报告&#xff1a;2014—2018》统计&#xff0c;我国森林覆盖率已经达到23.04%。森林覆…...

(007)Excel 公式的使用

文章目录 逻辑运算公式的参数常用函数引用方式引用工作表和工作簿表格的引用修改公式的计算时机区域交叉引用 逻辑运算 公式的参数 单元格引用&#xff1a;SUM(A1:A24)。字面值&#xff1a;SQRT(121)。字面文本字符串&#xff1a;PROPER(“john.f.smith”)。表达式&#xff1a…...

Vue之脚手架与组件化开发

一、基础知识 1、准备工作 node版本在12以上&#xff08;看情况而变&#xff09; 全局安装vue/cli脚手架&#xff08;不理解的可以去看一下node安装环境配置教程&#xff09; npm i vue/cli -g 2、项目初始化 在终端输入 vue create my-vue-project(这里是名字&#xff0…...

第四章 Maven

01 01. maven-课程介绍 02 02. maven-概述-maven介绍 私服&#xff1a;提高下载效率&#xff0c;让中央仓库不必被反复访问。我们一般用阿里云的私服。 03 03. maven-概述-maven安装 04 04. maven-idea集成-配置及创建maven项目 05 05. maven-idea集成-导入maven项目 06 06. …...

哈希表笔记(四)Redis对比Java总结

文章目录 一、基础结构对比数据结构定义Java HashMapRedis字典 主要区别与设计思路 二、关键操作API对比初始化Java HashMapRedis字典 添加元素Java HashMapRedis字典 查找元素Java HashMapRedis字典 删除元素Java HashMapRedis字典 扩容/重哈希操作Java HashMapRedis字典 三、…...

【精选】基于数据挖掘的广州招聘可视化分析系统(大数据组件+Spark+Hive+MySQL+AI智能云+DeepSeek人工智能+深度学习之LSTM算法)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…...

WPF使用依赖注入框架AutoMapper

WPF应用中使用AutoMapper和依赖注入框架实现对象映射与依赖管理 1. 准备工作 首先,通过NuGet安装必要的包: Install-Package AutoMapper Install-Package Autofac Install-Package Autofac.Extensions.DependencyInjection Install-Package Microsoft.Extensions.Dependen…...

WPF封装常用的TCP、串口、Modbus、MQTT、Webapi、PLC通讯工具类

WPF封装常用通讯工具类 下面我将为您封装常用的TCP、串口、Modbus、MQTT、WebAPI和PLC通讯工具类,适用于WPF应用程序开发。 一、TCP通讯工具类 using System; using System.Net.Sockets; using System.Text; using System.Threading.Tasks;public class TcpClientHelper : …...

游戏引擎学习第253天:重新启用更多调试界面

运行游戏&#xff0c;尝试调试系统&#xff0c;并为今天的工作设定方向。 今天我们将继续完成调试编辑代码的收尾工作。虽然昨天已经让它运行起来了&#xff0c;但目前还在使用旧的GUID系统&#xff0c;以及调试系统里早期用于探索阶段的一些旧式实现。因此&#xff0c;我们需…...

C# | 基于C#实现的BDS NMEA-0183数据解析上位机

以下是一个基于C#实现的BDS NMEA-0183数据解析上位机的示例代码,包含基础功能和界面: using System; using System.Collections.Generic; using System.IO.Ports; using System.Windows.Forms; using System.Drawing; using System.Globalization;namespace BDS_NMEA_Viewer…...

【AI提示词】成本效益分析师

提示说明 专注于通过数据驱动的方式提供成本效益分析&#xff0c;帮助客户优化资源投入与预期回报。 提示词 # Role: 成本效益分析师## Profile - language: 中文 - description: 专注于通过数据驱动的方式提供成本效益分析&#xff0c;帮助客户优化资源投入与预期回报 - ba…...

Kotlin革新数据分析

摘要 在数据分析领域&#xff0c;Python长期占据主导地位。然而&#xff0c;随着技术的不断发展&#xff0c;Kotlin凭借其独特优势逐渐崭露头角。本文深入探讨Kotlin在数据分析中的应用&#xff0c;详细阐述其与Python在数据分析生态系统中的差异&#xff0c;通过具体案例展示…...

今日行情明日机会——20250430

指数目前仍然在震荡区间&#xff0c;等后续的方向选择以及放量后的主线~ 2025年4月30日涨停主要行业方向分析 一、核心主线方向 机器人概念&#xff08;政策催化技术突破&#xff09; • 涨停家数&#xff1a;18家。 • 代表标的&#xff1a; ◦ 全筑股份&#xff08;工业机器…...

【Docker】Dockerfile 使用

文章目录 1. 什么是 Dockerfile?2. Dockerfile 核心指令详解2.1 基础指令2.2 构建过程指令2.3 运行时指令2.4 容器启动指令3. Dockerfile 最佳实践3.1 优化镜像构建3.2 安全性增强3.3 多阶段构建4. 完整 Dockerfile 示例5. 构建与验证6. 总结Docker 作为容器化技术的代表,已经…...

【Hive入门】Hive性能调优之资源配置:深入解析执行引擎参数调优

目录 前言 1 Hive执行引擎概述 2 MapReduce引擎调优 2.1 Map阶段资源配置 2.2 Reduce阶段资源配置 2.3 并发控制参数 3 Tez引擎调优 3.1 Tez架构概述 3.2 内存配置 3.3 并发与并行度 4 Spark引擎调优 4.1 Spark执行模型 4.2 内存管理 4.3 并行度配置 5 资源隔离…...

初学python的我开始Leetcode题8-3

提示&#xff1a;100道LeetCode热题-8-3主要是二叉树相关&#xff0c;包括三题&#xff1a;将有序数组转换为二叉搜索树、验证二叉搜索树、二叉搜索树中第K小的元素。由于初学&#xff0c;所以我的代码部分仅供参考。 目录 前言 题目1&#xff1a;将有序数组转换为二叉搜索树…...

【音频】Qt6实现MP3播放器

1、简介 解码MP3有很多种方法,比如:FFmpeg、GStreamer、Qt、libmpg123 库等,下面介绍使用,只使用Qt的接口方法解码、播放MP3。 开发配置: 1)操作系统:Windows11 2)Qt版本:Qt6.5.1 3)编译器:MinGW_64 2、获取音频输出设备 QMediaDevices 用于获取媒体设备,包括音…...

【Linux】VSCode用法

描述 部分图片和经验来源于网络&#xff0c;若有侵权麻烦联系我删除&#xff0c;主要是做笔记的时候忘记写来源了&#xff0c;做完笔记很久才写博客。 专栏目录&#xff1a;记录自己的嵌入式学习之路-CSDN博客 1 安装环境及运行C/C 1.1 安装及配置步骤 请参考这位大佬的…...

普通 html 项目也可以支持 scss_sass

项目结构示例 下载vscode的插件Live Sass Compiler 自动监听编译scss 下载插件Live Server 用于 web 服务器&#xff0c;打开 html 文件到浏览器&#xff0c;也可以不用这个&#xff0c;自己用 nginx 或者宝塔其他 web 工具 新建一个 index.scss打开&#xff0c;点击 vscode 底…...

C#实现主流PLC读写工具类封装

以下是针对三菱、欧姆龙、西门子S7系列、汇川、台达PLC的完整封装工具类实现,基于Modbus TCP/RTU、MC协议、QJ71等主流通信协议: 基础接口定义 /// <summary> /// PLC操作基础接口 /// </summary> public interface IPLC {/// <summary>/// 连接PLC/// &…...

C++之特殊类设计及类型转换

目录 一、设计一个不能被拷贝的类 二、设计一个只能在堆上创建对象的类 三、设计一个只能在栈上创建对象的类 四、设计一个不能被继承的类 五、设计一个只能创建一个对象的类(单例模式) 六、C语言中的类型转换 七、C中的三类类型转换 八、C强制类型转换 8.1、为什么C需…...

【Linux】C语言补充知识

有一些Linux常见的C语言用法需要哈好复习一下。 部分图片和经验来源于网络&#xff0c;若有侵权麻烦联系我删除&#xff0c;主要是做笔记的时候忘记写来源了&#xff0c;做完笔记很久才写博客。 专栏目录&#xff1a;记录自己的嵌入式学习之路-CSDN博客 1 结构体 1.1 结…...

怎么查看数据库容量

要查看数据库容量&#xff0c;你需要登录数据库管理系统&#xff0c;然后执行相应的 SQL 查询语句。不同的数据库管理系统有不同的语法&#xff0c;以下是一些常见的数据库管理系统中查看数据库容量的 SQL 查询语句示例&#xff1a; MySQL/MariaDB: SELECT table_schema &quo…...

深度学习中卷积的计算复杂度与内存访问复杂度

深度学习中卷积的计算复杂度与内存访问复杂度 在深度学习中&#xff0c;普通卷积&#xff08;Standard Convolution&#xff09;、深度可分离卷积&#xff08;Depthwise Separable Convolution, DWConv&#xff09;和部分卷积&#xff08;Partial Convolution, PConv&#xff…...

神经网络—损失函数

文章目录 前言一、损失函数概念二、损失函数原理1、分类问题中常见的损失函数&#xff08;1&#xff09;0-1损失函数原理优缺点 &#xff08;2&#xff09;交叉熵损失&#xff08;Cross-Entropy Loss&#xff09;原理优缺点 &#xff08;3&#xff09; 合页损失&#xff08;Hin…...

Rust中避免过度使用锁导致性能问题的策略

一、引言 在 Rust 多线程编程中&#xff0c;锁是实现线程同步的重要工具&#xff0c;它可以防止多个线程同时访问和修改共享数据&#xff0c;从而避免数据竞争和不一致的问题。然而&#xff0c;过度使用锁会带来严重的性能问题&#xff0c;如锁竞争导致的线程阻塞、上下文切换…...

Qt connect第五个参数

在 Qt 中&#xff0c;QObject::connect 函数的第五个参数用于指定 连接类型&#xff08;Qt::ConnectionType&#xff09;&#xff0c;它决定了信号与槽之间的通信方式。以下是各枚举值的详解及使用场景&#xff1a; 1. Qt::AutoConnection&#xff08;默认值&#xff09; 行为…...

QT —— 信号和槽(带参数的信号和槽函数)

QT —— 信号和槽&#xff08;带参数的信号和槽函数&#xff09; 带参的信号和槽函数信号参数个数和槽函数参数个数1. 参数匹配规则2. 实际代码示例✅ 合法连接&#xff08;槽参数 ≤ 信号参数&#xff09;❌ 非法连接&#xff08;槽参数 > 信号参数&#xff09; 3. 特殊处理…...

极简GIT使用

只为极简使用。 创建本地仓库 初始化git仓库 1.创建一个新文件夹 2.在文件夹内打开git bash 之后进入如下界面&#xff0c;输入git init&#xff0c;这样此文件就可以使用git了。 在此文件夹中&#xff0c;除了.git文件外&#xff0c;其他全部都是工作文件。 接下来将以一个…...

【嵌入式———通用定时器基本操作——实验需求2:案列:测量PWM的频率/周期】

通用定时器输入捕获 需求&#xff1a;把测到的结果通过串口发送到电脑&#xff0c;检查测试结果。 在溢出之前&#xff0c;两次上升/下降沿记录时间。 345部分 滤波器&#xff1a;用来滤掉一些毛刺信息&#xff0c;信号质量好可以不滤波 边沿检测器&#xff1a;确定要捕获的是…...

兰亭妙微:数据驱动的 B 端设计:如何用 UI 提升企业级产品体验?

​ 在数字化转型的浪潮中&#xff0c;企业级产品的用户体验成为了决定产品竞争力的关键因素。对于 B 端产品而言&#xff0c;其使用场景复杂、用户需求多元&#xff0c;如何通过 UI 设计提升产品体验&#xff0c;成为了摆在设计者面前的重要课题。而数据驱动的设计方法&#x…...

Spring AOP---面向切面编程由认识到使用

1. AOP AOP(Aspect-Oriented Programming), 是一种思想, 面向切面编程。 在前文统一异常处理&#xff0c;统一结果返回就是使用了这一思想&#xff08;都是在集中处理某一类事情, 但又不影响原有代码的正常运行&#xff09;&#xff0c;但他们不是AOP&#xff0c;只是应用了这…...

深入解析 Python 应用日志监控:ELK、Graylog 的实战指南

深入解析 Python 应用日志监控:ELK、Graylog 的实战指南 引言 在现代应用开发中,日志不仅仅是用于记录错误和调试信息,它更是系统运行状况的窗口,帮助开发者和运维人员监控、优化应用性能。Python 作为广泛应用的开发语言,其应用日志管理的重要性不言而喻。而 ELK(Elas…...

贝叶斯算法实战:从原理到鸢尾花数据集分类

贝叶斯算法实战&#xff1a;从原理到鸢尾花数据集分类 在机器学习的广阔领域中&#xff0c;贝叶斯算法以其基于概率推理的独特优势&#xff0c;成为数据分类和预测的重要工具。今天&#xff0c;我们将通过一段Python代码&#xff0c;深入探讨贝叶斯算法在鸢尾花数据集分类任务…...

CSS学习笔记14——移动端相关知识(rem,媒体查询,less)

移动端 rem适配布局 rem单位 rem基准是相对于html元素的字体大小 父元素设定font-size&#xff0c;子元素根据rem缩放对应字体大小 媒体查询&#xff08;Media Query&#xff09; media可以针对不同屏幕尺寸设置不同样式当你重置浏览器大小过程中&#xff0c;页面也会根据…...

使用Node编写轻量级后端快速入门

使用Node编写轻量级后端快速入门 node 要作为轻量级后端需要下载一些对应模块可以参考下面命令。你可以借助 npm&#xff08;Node Package Manager&#xff09;来下载它们。 模块下载 express&#xff1a;这是一个广受欢迎的 Node.js Web 应用框架&#xff0c;能用于构建 Web…...

海量数据存储与分析:HBase vs ClickHouse vs Doris 三大数据库优劣对比指南

1.引言 在当今大数据时代&#xff0c;数据正以前所未有的速度持续增长。来自各个领域的数据&#xff0c;如互联网行业用户的每一次点击、浏览记录&#xff0c;金融机构的海量交易数据&#xff0c;以及物联网设备源源不断上传的实时监测数据等&#xff0c;其规模呈指数级攀升。…...

Redis 挂掉后高并发系统的应对策略:使用 Sentinel 实现限流降级与 SkyWalking 监控优化

前言 在现代分布式系统中&#xff0c;Redis 被广泛用作缓存中间件以提升性能和减轻数据库压力。然而&#xff0c;在高并发场景下&#xff0c;一旦 Redis 出现故障&#xff08;如宕机、网络中断等&#xff09;&#xff0c;如果没有有效的容错机制&#xff0c;可能会导致大量请求…...

C++11新特性_自动类型推导_decltype

decltype 是 C11 引入的一个关键字&#xff0c;用于在编译时推导表达式的类型。它提供了一种方式&#xff0c;让编译器根据表达式的类型来确定变量的类型&#xff0c;而不需要显式地指定类型。下面为你详细介绍 decltype 的使用方法和应用场景。 基本语法 decltype 的基本语法…...

Scrapy爬虫实战总结:动态与登录爬取的精炼经验

引言 在AI时代,信息和数据往往成就你的速度和高度。。。 这篇文章基于前两篇的实践基础之上的一次小结,通过“爬取动态网页”和“登录网站”两场实战,我用Scrapy+Splash破译JavaScript,用FormRequest敲开权限大门。这篇总结凝练两场冒险的体验,淬炼Scrapy爬虫的通用经验…...

windows系统搭建自己的ftp服务器,保姆级教程(用户验证+无验证)

前言 最近在搭建环境时&#xff0c;我发现每次都需要在网上下载依赖包和软件&#xff0c;这不仅耗时&#xff0c;而且有时还会遇到网络不稳定的问题&#xff0c;导致下载速度慢或者中断&#xff0c;实在不太方便。于是&#xff0c;我产生了搭建一个FTP服务器的想法。通过搭建FT…...

PDF本地化开源项目推荐

Stirling-PDF 项目详细总结 1. 项目概述 Stirling-PDF 是一个基于 Docker 的本地化 Web 应用&#xff0c;专注于 PDF 文件的多样化处理。其核心特点是&#xff1a; 完全本地化部署&#xff1a;所有文件处理均在用户设备或服务器内存中进行&#xff0c;任务完成后自动清理临…...