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

【教程】PyTorch多机多卡分布式训练的参数说明 | 附通用启动脚本

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn]

如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~

目录

torchrun

一、什么是 torchrun

二、torchrun 的核心参数讲解

三、torchrun 会自动设置的环境变量

四、torchrun 启动过程举例

机器 A(node_rank=0)上运行

机器 B(node_rank=1)上运行

五、小结表格

PyTorch

一、背景回顾

二、init_process_group

三、脚本中通常的典型写法

通用启动脚本


torchrun 与 torch.multiprocessing.spawn 的对比可以看这篇:

【知识】torchrun 与 torch.multiprocessing.spawn 的对比

torchrun

一、什么是 torchrun

torchrun 是 PyTorch 官方推荐的分布式训练启动器,它的作用是:

  • 启动 多进程分布式训练(支持多 GPU,多节点)

  • 自动设置每个进程的环境变量

  • 协调节点之间建立通信

二、torchrun 的核心参数讲解

torchrun \--nnodes=2 \--nproc_per_node=2 \--node_rank=0 \--master_addr=192.168.5.228 \--master_port=29400 \xxx.py

🔹 1. --nnodes(Number of Nodes)

  • 表示参与训练的总机器数

  • 你有几台服务器,就写几。

  • 在分布式训练中,一个 node 就是一台物理或虚拟的主机。

  • node的编号从0开始。

✅ 例子:你用 2 台机器 → --nnodes=2


🔹 2. --nproc_per_node(Processes Per Node)

  • 表示每台机器上要启动几个训练进程。

  • 一个进程对应一个 GPU,因通常设置为你机器上要用到的GPU数。

  • 因此,整个分布式环境下,总训练进程数 = nnodes * nproc_per_node

✅ 例子:每台机器用了 2 张 GPU → --nproc_per_node=2


🔹 3. --node_rank

  • 表示当前机器是第几台机器

  • 从 0 开始编号,必须每台机器都不同!

✅ 例子:

机器 IPnode_rank
192.168.5.2280
192.168.5.2291

🔹 4. --master_addr--master_port

  • 指定主节点的 IP 和端口,用于 rendezvous(进程对齐)和通信初始化。

  • 所有机器必须填写相同的值!

✅ 建议:

  • master_addr 就是你指定为主节点的那台机器的 IP

  • master_port 选一个未被占用的端口,比如 29400

三、torchrun 会自动设置的环境变量

当用 torchrun 启动后,它会自动给每个进程设置这些环境变量

环境变量含义
RANK当前进程在全局中的编号(0 ~ world_size - 1)
LOCAL_RANK当前进程在本机中的编号(0 ~ nproc_per_node - 1)
WORLD_SIZE总进程数 = nnodes * nproc_per_node

你可以在训练脚本里用 os.environ["RANK"] 来读取这些信息:

import os
rank = int(os.environ["RANK"])
local_rank = int(os.environ["LOCAL_RANK"])
world_size = int(os.environ["WORLD_SIZE"])

示例分配图:

四、torchrun 启动过程举例

假设:

  • 有 2 台机器

  • 每台机器有 2 个 GPU

  • 总共会启动 4 个进程

机器 A(node_rank=0)上运行

torchrun \--nnodes=2 \--nproc_per_node=2 \--node_rank=0 \--master_addr=192.168.5.228 \--master_port=29400 \xxx.py

机器 B(node_rank=1)上运行

torchrun \--nnodes=2 \--nproc_per_node=2 \--node_rank=1 \--master_addr=192.168.5.228 \--master_port=29400 \xxx.py

torchrun 给每个进程编号的顺序(分配 RANK / LOCAL_RANK)

torchrun 按照每台机器上 node_rank 的顺序,并在每台机器上依次启动 LOCAL_RANK=0, 1, ..., n-1,最后合成 RANK。

RANK = node_rank × nproc_per_node + local_rank

Step 1:按 node_rank 升序处理(node 0 → node 1)

Step 2:每个 node 内部从 local_rank=0 开始递增


本质上:torchrun 是主从结构调度的

  • 所有 node 启动后,都会和 master_addr 通信。

  • master 会统一收集所有 node 的状态。

  • 每个 node 根据你给的 node_rank 自行派生 local_rank=0~n-1

  • 所有节点通过 RANK = node_rank * nproc_per_node + local_rank 得到自己的全局编号。

这个机制是 可预测、可控、可复现 的。


📦 node_rank=0 (机器 1)
    ├── local_rank=0 → RANK=0
    └── local_rank=1 → RANK=1

📦 node_rank=1 (机器 2)
    ├── local_rank=0 → RANK=2
    └── local_rank=1 → RANK=3

最终分配:

Node RankLocal RankGlobal Rank (RANK)使用 GPU
0000
0111
1020
1131

五、小结表格

参数作用设置方式
--nnodes总节点数你写在命令里
--nproc_per_node每台节点的进程数(= GPU 数)你写在命令里
--node_rank当前机器编号(0开始)每台机器唯一
--master_addr主节点 IP(所有节点需一致)你设置
--master_port主节点端口(所有节点需一致)你设置
RANK当前进程在所有进程中的编号torchrun 自动设置
LOCAL_RANK当前进程在本节点上的编号torchrun 自动设置
WORLD_SIZE总进程数 = nnodes * nproc_per_node自动设置

PyTorch

PyTorch 的分布式通信是如何通过 init_process_grouptorchrun 生成的环境变量配合起来工作的。

一、背景回顾

你已经用 torchrun 启动了多个训练进程,并且 torchrun 为每个进程自动设置了这些环境变量:

变量名含义
RANK当前进程的全局编号(从 0 开始)
LOCAL_RANK本机上的编号(一般等于 GPU ID)
WORLD_SIZE总进程数
MASTER_ADDR主节点的 IP
MASTER_PORT主节点用于通信的端口

那么 这些变量是如何参与进程通信初始化的? 这就涉及到 PyTorch 的核心函数:


二、init_process_group

torch.distributed.init_process_group 是 PyTorch 初始化分布式通信的入口:

torch.distributed.init_process_group(backend="nccl",  # 或者 "gloo"、"mpi"init_method="env://",  # 通过环境变量读取设置
)

关键点:

  • backend="nccl":推荐用于 GPU 分布式通信(高性能)

  • init_method="env://":表示通过环境变量来初始化


你不需要自己设置 RANK / WORLD_SIZE / MASTER_ADDR,只要写:

import torch.distributed as distdist.init_process_group(backend="nccl", init_method="env://")

PyTorch 会自动去环境中读这些变量:

  • RANK → 当前进程编号

  • WORLD_SIZE → 总进程数

  • MASTER_ADDRMASTER_PORT → 主节点 IP 和端口

然后就能正确初始化所有通信进程。

三、脚本中通常的典型写法

import os
import torch# 初始化 PyTorch 分布式通信环境
torch.distributed.init_process_group(backend="nccl", init_method="env://")# 获取全局/本地 rank、world size
rank = int(os.environ.get("RANK", -1))
local_rank = int(os.environ.get("LOCAL_RANK", -1))
world_size = int(os.environ.get("WORLD_SIZE", -1))# 设置 GPU 显卡绑定
torch.cuda.set_device(local_rank)
device = torch.device("cuda")# 打印绑定信息
print(f"[RANK {rank} | LOCAL_RANK {local_rank}] Using CUDA device {torch.cuda.current_device()}: {torch.cuda.get_device_name(torch.cuda.current_device())} | World size: {world_size}")

这段代码在所有进程中都一样写,但每个进程启动时带的环境变量不同,所以最终 ranklocal_rankworld_size 就自然不同了。

通用启动脚本

#!/bin/bash# 设置基本参数
MASTER_ADDR=192.168.5.228           # 主机IP
MASTER_PORT=29400                   # 主机端口
NNODES=2                            # 参与训练的总机器数
NPROC_PER_NODE=2                    # 每台机器上的进程数# 所有网卡的IP地址,用于筛选
ALL_LOCAL_IPS=$(hostname -I)
# 根据本机 IP 配置通信接口
if [[ "$ALL_LOCAL_IPS" == *"192.168.5.228"* ]]; thenNODE_RANK=0                       # 表示当前机器是第0台机器IFNAME=ens1f1np1  mytorchrun=~/anaconda3/envs/dglv2/bin/torchrun
elif [[ "$ALL_LOCAL_IPS" == *"192.168.5.229"* ]]; thenNODE_RANK=1                       # 表示当前机器是第1台机器IFNAME=ens2f1np1mytorchrun=/opt/software/anaconda3/envs/dglv2/bin/torchrun
elseexit 1
fi# 设置 RDMA 接口
export NCCL_IB_DISABLE=0            # 是否禁用InfiniBand
export NCCL_IB_HCA=mlx5_1           # 使用哪个RDMA接口进行通信
export NCCL_SOCKET_IFNAME=$IFNAME   # 使用哪个网卡进行通信
export NCCL_DEBUG=INFO              # 可选:调试用
export GLOO_IB_DISABLE=0            # 是否禁用InfiniBand
export GLOO_SOCKET_IFNAME=$IFNAME   # 使用哪个网卡进行通信
export PYTHONUNBUFFERED=1           # 实时输出日志# 启动分布式任务
$mytorchrun \--nnodes=$NNODES \--nproc_per_node=$NPROC_PER_NODE \--node_rank=$NODE_RANK \--master_addr=$MASTER_ADDR \--master_port=$MASTER_PORT \cluster.py## 如果想获取准确报错位置,可以加以下内容,这样可以同步所有 CUDA 操作,错误不会“延迟触发”,你会看到确切是哪一行代码出了问题:
## CUDA_LAUNCH_BLOCKING=1 torchrun ...

相关文章:

【教程】PyTorch多机多卡分布式训练的参数说明 | 附通用启动脚本

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 目录 torchrun 一、什么是 torchrun 二、torchrun 的核心参数讲解 三、torchrun 会自动设置的环境变量 四、torchrun 启动过程举例 机器 A&#…...

九、自动化函数02

// 进阶版本的屏幕截图 void getScreenShot(String str) throws IOException {// ./src/test/image/ 存放图片路径// 屏幕截图SimpleDateFormat sim1 new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sim2 new SimpleDateFormat("HHmmss");Str…...

构建批量论文格式修改系统:从内容识别到自动化处理

在学术研究和论文管理中,自动化处理论文格式是一个极具挑战性但非常有价值的任务。无论是提取论文的关键信息,还是批量修改格式,都需要一个强大的内容识别系统作为基础。本文将结合两份代码(paper_parser.py 和 paper_analyzer.py),深入分析它们如何实现论文内容的识别,…...

站台候车,好奇铁道旁的碎石(道砟)为何总是黄色的?

一、发现问题 同学们在站台等车时有没有发现,铁道旁的小石子很多都是黄色的,有部分为白色,像上图这样,这是为什么呢?是石头原生为黄色,还是因为其他原因变成了红黄色?是从灰白色变为了红黄色吗&…...

Oracle PL/SQL 中,异常(Exception)

在 Oracle PL/SQL 中,异常(Exception) 是处理运行时错误的机制,能够将错误逻辑与业务逻辑解耦,保证程序的健壮性和可维护性。以下从 原理 和 案例 两个方面详细解析 一、异常处理的核心原理 1. 异常触发机制 自动触发…...

OpenCV学习之获取图像所有点的坐标位置(二)

1.功能介绍 (1)使用openCV解析了.jpeg、.jpg、.png格式的图像文件,输出了图像的宽、高、通道数; (2)创建txt格式文件,保存图像中各像素点的rgba值。 2.环境介绍 操作系统:window10 开发语言:visual studio 2015 c++ 3.功能实现过程 3.1环境设置 (1)打开Vs2015…...

代码随想录算法训练营Day30 | 01背包问题(卡码网46. 携带研究材料)、Leetcode416.分割等和子集

代码随想录算法训练营Day30 | 01背包问题(卡码网46. 携带研究材料)、Leetcode416.分割等和子集 一、01背包问题 相关题目:卡码网46. 携带研究材料 文档讲解:01背包问题(二维)、01背包问题(一维…...

opencv 形态学变换

形态学变换 1. 核2.腐蚀(cv2.erode)3. 膨胀(cv2.dilate)4. 开运算(cv.MORPH_OPEN)5. 闭运算(cv2.MORPH_CLOSE)6. 礼帽运算(找出增多的白色区域)7. 黑帽运算8.…...

视频设备轨迹回放平台EasyCVR打造水库大坝智慧安防视频监控智能分析方案

一、项目背景 水库安全度汛是全国防汛抗洪工作的重点,水库监控系统对保障水库安全、及时排险意义重大。多数水库站点分散、位置偏,地形复杂,与监控中心相隔较远。​ 传统有线监控系统成本高、工期长,遇山河等阻碍时布线困难&…...

使用 LLaMA-Factory 对 DeepSeek R1进行微调教程

如本教程有问题,感谢大家在评论区指出。 如操作过程中遇到解决不了的问题,可以在评论区提问,作者看到了会回复。 微调简介 模型微调通过在特定任务数据集上继续训练预训练模型来进行,使得模型能够学习到与任务相关的特定领域知识…...

【Kubernetes基础--Pod深入理解】--查阅笔记2

深入理解Pod 为什么要有个Pod1. 容器协作与资源共享2. 简化调度和资源管理3. 设计模式支持 Pod 基本用法Pod 容器共享 VolumePod 的配置管理ConfigMap 概述创建 ConfigMap 资源对象在 Pod 中使用 ConfigMap使用 ConfigMap 的限制条件 为什么要有个Pod Pod 的引入并非技术冗余&…...

C语言进阶之自定义类型:结构体,枚举,联合

结构体 结构体类型的声明 结构的基础知识 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 结构的声明 struct tag{member-list;}variable-list;例如描述一个学生: struct Stu{char name[20];//名字int age;//年龄ch…...

深入解析C++引用:安全高效的别名机制及其与指针的对比

一、引用的核心概念 1.1 引用定义 引用(Reference)是C为变量创建的别名,通过&符号声明。其核心特性: 指针适用场景: 现代C黄金法则: "引用是指针的安全马甲,而智能指针是带着安全帽的…...

【rdma通信名词概念】

rdma通信名词概念 1.在rdma网卡中,QP(SQ和RQ)、CQ、EQ和SQR的含义是什么以及功能是什么?2 PCIe中的MSI-X中断机制? 1.在rdma网卡中,QP(SQ和RQ)、CQ、EQ和SQR的含义是什么以及功能是什么? QP:queue pair&am…...

Mysql主从复制有哪些方式

MySQL 主从复制主要有以下几种方式,根据不同的分类标准(如同步机制、数据复制格式、拓扑结构等)可以分为: 一、按同步机制分类 1. 异步复制 (Asynchronous Replication) 原理:主库提交事务后,立即返回给客…...

Vue工程化开发脚手架Vue CLI

开发Vue有两种方式 核心包传统开发模式:基于html / css / js 文件,直接引入核心包,开发 Vue。工程化开发模式:基于构建工具(例如:webpack)的环境中开发Vue。 脚手架Vue CLI Vue CLl 是 Vue 官方…...

MySQL函数运算

1.日期时间函数 查询当前日期时间的函数(使用函数需要加select): curdate() 查看当前数据库的日期部分(年月日) SELECT CURDATE(); curtime() 查看当前数据库的时间部分(时分秒) SELECT CURTIME(); now() 查看当前…...

Spring如何解决项目中的循环依赖问题?

目录 什么是循环依赖? 如何解决? 采用两级缓存解决 需要AOP的Bean的循环依赖问题? 三级缓存解决 什么是循环依赖? 循环依赖就是Spring在初始化Bean时两个不同的Bean你依赖我,我依赖你的情况 例如A依赖B&#xf…...

【Pandas】pandas DataFrame itertuples

Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前几行DataFrame.at快速访问和修改 DataFrame 中单个值的方法DataFrame.iat快速访问和修改 DataFrame 中单个值的方法DataFrame.loc用于基于标签(行标签和列标签&#…...

正则表达式反向引用的综合应用魔法:从重复文本到简洁表达的蜕变

“我....我要....学学学学....编程 java!” —— 这类“重复唠叨”的文本是否让你在清洗数据时头疼不已? 本文将带你一步步掌握正则表达式中的反向引用技术,并结合 Java 实现一个中文文本去重与清洗的实用工具。 结合经典的结巴实例。如何高效地将这样的…...

ESP32驱动读取ADXL345三轴加速度传感器实时数据

ESP32读取ADXL345三轴加速度传感器实时数据 ADXL345三轴加速度传感器简介ADXL345模块原理图与引脚说明ESP32读取ADXL345程序实验结果 ADXL345三轴加速度传感器简介 ADXL345是一款由Analog Devices公司推出的三轴数字加速度计,分辨率高(13位),测量范围达…...

C++高级3 绑定器

绑定器 C11从Boost库中引入了bind绑定器和function函数对象机制 绑定器二元函数对象 一元函数对象 bind1st 绑定第一个 bind2nd 绑定第二个 #include <iostream> #include <memory> #include <vector> #include <functional> #include <ctime…...

Android 接口定义语言 (AIDL)

目录 1. 本地进程调用(同一进程内)2. 远程进程调用(跨进程)3 `oneway` 关键字用于修改远程调用的行为Android 接口定义语言 (AIDL) 与其他 IDL 类似: 你可以利用它定义客户端与服务均认可的编程接口,以便二者使用进程间通信 (IPC) 进行相互通信。 在 Android 上,一个进…...

【android bluetooth 案例分析 02】【CarLink 详解2】【Carlink无配对连接机制深度解析】

Carlink无配对连接机制深度解析&#xff08;首次/二次免鉴权原理&#xff09; 一、核心结论&#xff1a;Carlink通过SDK层协议设计完全绕过传统蓝牙配对 传统蓝牙配对&#xff08;Pairing&#xff09;依赖协议栈生成长期绑定密钥&#xff08;LTK&#xff09;&#xff0c;而Car…...

ubuntu 2204 安装 vcs 2023

系统 : Ubuntu 22.04.1 LTS vcs 软件 : 有已经安装好的软件(位于redhat8.10),没找到安装包 . 安装好的目录文件 占用 94 G注意 : 该虚拟机(包括安装好的软件)有114G,其中安装好的目录文件占用94GB // 即 我要把 这里 已经安装好的软件(包括scl/vcs/verdi 和其他软件) 在 …...

Spring Boot循环依赖全解析:原理、解决方案与最佳实践

&#x1f6a8; Spring Boot循环依赖全解析&#xff1a;原理、解决方案与最佳实践 #SpringBoot核心 #依赖注入 #设计模式 #性能优化 一、循环依赖的本质与危害 1.1 什么是循环依赖&#xff1f; 循环依赖指两个或多个Bean相互直接或间接引用&#xff0c;形成闭环依赖关系。 典…...

按键精灵安卓/ios脚本辅助工具开发教程:如何把界面配置保存到服务器

在使用按键精灵工具辅助的时候&#xff0c;多配置的情况下&#xff0c;如果保存现有的配置&#xff0c;并且读取&#xff0c;尤其是游戏中多种任务并行情况下&#xff0c;更是需要界面进行保存&#xff0c;简单分享来自紫猫插件的配置保存服务器写法。 界面例子&#xff1a; …...

【厦门大学】大模型概念、技术与应用实践

大模型概念、技术与应用实践 引言一、人工智能发展简史1.1 图灵测试的提出1.2 人工智能的诞生1.3 人工智能的发展阶段 二、大模型的核心概念2.1 大模型的定义2.2 大模型的特点 三、大模型的发展历程3.1 萌芽期&#xff08;1950-2005&#xff09;3.2 沉淀期&#xff08;2006-201…...

The Strict Teacher (Hard Version) 去除无效的干扰!巧妙转化

文章目录 The Strict Teacher (Hard Version) 思考问题&#xff01;那么多个人抓一个人&#xff0c;是否是每一个人都是对于最优策略的答案是有贡献的&#xff1f;答案是否定的&#xff0c;其实问题可以简化为三种情况&#xff1a; 所有的老师都在大卫的右边&#xff0c;…...

Linux中信号的保存

一、认识信号的其他相关概念 实际执行信号的处理动作称为信号递达 信号从产生到递达之间的状态&#xff0c;称为信号未决 进程可以选择阻塞某个信号 被阻塞的信号产生时将保持在未决状态&#xff0c;直到进程解除对该信号的阻塞&#xff0c;才进行递达的动作 阻塞和忽略是不同的…...

2024ICPC 南京 B 生日礼物

题目&#xff1a; 格莱美的生日快到了&#xff0c;她从朋友那里得到了一个序列 A 作为礼物。这个序列只有 0 、 1 和 2 。格莱美认为这个数列太长了&#xff0c;因此她决定修改 A 使其更短。 从形式上看&#xff0c;格莱美可以执行任意数量的运算。每次她都可以从以下三种运算…...

扫地机器人进化史:从人工智障到家政王者

1996年&#xff0c;瑞典伊莱克斯推出的"三叶虫"开启了扫地机器人的纪元。这款售价2000美元的"初代机"工作时像喝醉的水手&#xff0c;随机碰撞的清扫方式让用户直呼"买了个寂寞"。谁能想到&#xff0c;这个当初被戏称为"人工智障"的发…...

C 语 言 --- 数 据 类 型 的 存 储

C 语 言 --- 数 据 类 型 的 存 储 空 类 型大 小 端 存 储大 端 存 储 --- 正 着 放&#xff08;从 小 到 大&#xff09;小 端 存 储 --- 倒 着 放&#xff08;从 大 到 小&#xff09; 浮 点 型 在 内 存 中 的 存 储总结 &#x1f4bb;作 者 简 介&#xff1a;曾 与 你 一 …...

3.8 字符串的常用函数

重点&#xff1a;字符串的常用函数 #1.测试转换大小写 lower:大写->小写 upper&#xff1a;小写->大写 swapcase&#xff1a;自动将大写转小写小写转大写 print("ABC".lower()) #abcprint("abc".upper()) #ABCprint…...

事件触发控制与响应驱动控制的定义、种类及区别

一、定义 事件触发控制&#xff08;Event-Triggered Control, ETC&#xff09; 事件触发控制是一种基于动态条件触发的控制策略&#xff0c;其核心在于通过预设的事件触发条件&#xff08;如系统状态误差超过阈值、特定信号到达等&#xff09;来决定何时更新控制信号或进行通信…...

Android离屏渲染

写在前面 与iOS同事聊天时聊到圆角会使用离屏渲染的方式绘制&#xff0c;影响性能&#xff1b;Android上有没有不知道&#xff0c;学习了一下整理了这篇文章。 Android 圆角与离屏渲染&#xff08;Offscreen Rendering&#xff09; 一、什么是离屏渲染&#xff1f; 离屏渲染…...

35. 搜索插入位置

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2示例 2: 输入:…...

网络的起点:深入解析计算机网络中的网络接口层

一、什么是网络接口层&#xff1f; 计算机网络的 网络接口层&#xff08;Network Interface Layer&#xff09;&#xff0c;在 TCP/IP模型 中处于最底层&#xff0c;负责将数据从计算机传输到物理网络媒介&#xff0c;并在此基础上确保数据的正确传输。它位于数据链路层和物理…...

智能指针(内存泄漏)

一、RALL RALL的核心概念&#xff1a; 资源获取即初始化&#xff1a;资源的分配与对象的初始化绑定在一起&#xff0c;资源的释放与对象的销毁绑定在一起。 不是所有智能指针都用这个思想 可以有效避免死锁问题 二、智能指针 通过将new出的对象教给有生命周期的对象处理。 在…...

秒杀秒抢系统开发:飞算 JavaAI 工具如何应对高并发难题?

秒杀、秒抢活动已成为电商促销与吸引流量的常用手段。然而&#xff0c;此类活动所带来的高并发访问&#xff0c;对系统性能构成了巨大挑战。如何确保系统在高并发场景下依然能够稳定、高效运行&#xff0c;成为开发者亟待解决的关键问题。飞算 JavaAI 工具作为一款功能强大的开…...

AI在代码Review中的应用试验与推广策略

一、引言 在软件开发领域&#xff0c;代码审查&#xff08;Code Review&#xff09;是保障代码质量的关键环节。传统的代码审查依赖人工&#xff0c;不仅效率低下&#xff0c;而且容易出现疏漏。随着人工智能技术的发展&#xff0c;AI在代码审查中的应用逐渐成为可能。近期&am…...

自定义Jackson序列化和反序列化

为什么需要自定义Jackson序列化和反序列化?下面举个例子看看就知道了 问题描述 由于 Spring Boot 内置使用的就是 Jackson JSON 框架&#xff0c;所以&#xff0c;无需引入新的依赖&#xff0c;仅需添加自定义配置类即可&#xff0c;让其支持新的日期 API Controller层的代码…...

人工智能浪潮与生成式人工智能认证(GAI认证)的登场

当ChatGPT在2023年引爆全球对话时,人类已悄然站在人工智能发展史上的关键转折点。生成式人工智能(Generative AI)不再仅仅是实验室中的技术概念,而是正在重塑内容创作、商业决策、教育医疗等领域的底层逻辑。这场技术浪潮的冲击力,不仅体现在算法模型的指数级进化上,更在…...

Redis - 讲清楚集群模式(Redis Cluster)(上)

节点与集群构建 节点组成&#xff1a;Redis集群由多个独立节点组成&#xff0c;通过CLUSTER MEET命令实现节点握手&#xff0c;形成集群。 握手过程&#xff1a; 节点A为节点B创建clusterNode结构&#xff0c;发送MEET消息。 节点B接收后创建节点A的clusterNode结构&#xff…...

什么是 矩阵号 ?为什么要做海外矩阵?

简单说&#xff0c;就是——在海外平台批量搞账号/店铺&#xff0c;组团赚钱&#xff01; 比如这样玩&#x1f447; ● TikTok 矩阵号&#xff1a;5 个账号&#xff0c;分别做美妆、3C、家居&#xff0c;覆盖不同老外兴趣圈。 ● 亚马逊矩阵店铺&#xff1a;A 店卖手机壳&#…...

10 穴 汽车连接器的15个设计特点

汽车行业严重依赖卓越的电气系统来确保功能和可靠性。这些系统的关键组件是 10 腔连接器&#xff0c;它为布线和信号传输提供解决方案。制造商和工程师必须仔细评估这些连接器的设计特性&#xff0c;以优化性能和安全性。 本博客研究了汽车 10 腔连接器的 15 个设计特征&#…...

WHAT - 动态导入模块遇到版本更新解决方案

文章目录 一、动态导入模块二、常见原因与解决方案1. 模块 URL 错误2. 开发人员发版用户停留在旧页面问题背景解决方案思路1. 监听错误&#xff0c;提示用户刷新2. 使用缓存控制策略&#xff1a;强制刷新3. 动态模块加载失败时兜底4. 使用 import.meta.glob() 或 webpack 的 __…...

4.15学习总结

学习了IO流和相关的字符集 完成一道算法题...

THCON 2025

Crypto OTPas_ouf 用10个字符异或加密的jpg图片&#xff0c;通过头得到key再恢复原图 Mammoths Personnal Slot Machine 梅森旋转恢复 from pwn import * from randcrack import RandCrack from tqdm import trange context.log_level errorp remote(74.234.198.209, 33…...

Linux 深入浅出信号量:从线程到进程的同步与互斥实战指南

知识点1【信号量概述】 信号量是广泛用于进程和线程间的同步和互斥。信号量的本质 是一个非负的整数计数器&#xff0c;它被用来控制对公共资源的访问 当信号量值大于0的时候&#xff0c;可以访问&#xff0c;否则将阻塞。 PV原语对信号量的操作&#xff0c;一次P操作使信号…...