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

04-Seata 深度解析:从分布式事务原理到 Seata 实战落地

Seata 深度解析:从分布式事务原理到 Seata 实战落地

一、分布式事务核心理论与挑战

1.1 分布式事务的本质难题

在微服务架构中,一次业务操作可能涉及多个服务的数据库操作,传统单体事务(ACID)无法跨越服务边界,导致以下核心问题:

  • 原子性破坏:跨服务操作部分成功、部分失败时如何回滚?
  • 一致性缺失:分布式环境下如何保证数据最终一致?
  • 网络分区影响:节点间通信失败时如何处理事务状态?

1.2 分布式事务模型对比

模型核心思想典型方案一致性级别性能特点适用场景
强一致全局锁 / 两阶段提交(2PC)XA 协议、Seata TC 模式强一致低并发(锁粒度大)金融转账、订单支付
最终一致补偿机制(TCC/SAGA)、可靠消息Seata AT/TCC/SAGA 模式最终一致高并发(无全局锁)电商库存扣减、物流同步
最大努力重试 + 人工干预事务消息 + 本地消息表最终一致高可用(允许重试)非核心业务流程

二、Seata 架构与核心组件解析

2.1 Seata 整体架构

数据源层
业务应用端
事务管理端
注册/汇报事务状态
发起全局回滚/提交
查询事务状态
开启全局事务
调用微服务
操作本地资源
调用服务B
操作本地资源
代理数据源
记录UNDO日志
DataSource
Undo Log Table
服务A
服务B
Resource Manager
Transaction Coordinator
Transaction Manager

2.2 核心组件功能

  1. TC(事务协调者)
    • 维护全局事务状态(初始化、提交、回滚)
    • 协调各服务 RM 完成分支事务的提交 / 回滚
    • 支持 Nacos/Redis/MySQL 作为事务日志存储
  2. TM(事务管理器)
    • 发起全局事务(@GlobalTransactional 注解驱动)
    • 控制全局事务的提交 / 回滚时机
  3. RM(资源管理器)
    • 管理本地数据库连接(通过数据源代理实现)
    • 记录 UNDO 日志(用于 AT 模式自动补偿)
    • 响应 TC 指令完成分支事务的提交 / 回滚

2.3 三大事务模式对比

(1)AT 模式(自动补偿)
  • 核心原理:
    1. 执行前记录数据快照(UNDO 日志)
    2. 执行业务 SQL 并提交本地事务
    3. 全局事务提交时直接确认,回滚时根据 UNDO 日志反向补偿
  • 优点:无侵入性(只需添加 Seata 依赖),适配现有业务代码
  • 缺点:需创建undo_log表,高并发下存在锁竞争
(2)TCC 模式(两阶段提交)
  • 核心原理:
    • Try:预留资源(如冻结库存)
    • Confirm:正式提交资源(扣减库存)
    • Cancel:释放预留资源(解冻库存)
  • 优点:细粒度资源控制,适合跨服务复杂逻辑
  • 缺点:需手动实现三个阶段,开发成本高
(3)SAGA 模式(长事务补偿)
  • 核心原理:
    • 将长事务拆分为多个本地事务,每个事务附带反向补偿逻辑
    • 当某一步失败时,按相反顺序执行补偿事务
  • 优点:无全局锁,适合异步、最终一致场景
  • 缺点:补偿逻辑需自行实现,事务链路长时状态管理复杂

三、Seata AT 模式实战:订单 - 库存分布式事务

3.1 环境准备

  • 技术栈:Spring Boot 3.1.2 + Seata 1.6.1 + Nacos 2.3.1
  • 场景:用户下单时扣减库存,确保订单与库存操作要么全成功、要么全回滚

3.2 核心配置步骤

(1)TC 服务部署(Seata Server)
# 下载Seata Server  
wget https://github.com/seata/seata/releases/download/v1.6.1/seata-server-1.6.1.tar.gz  
# 修改registry.conf使用Nacos  
registry {  type = "nacos"  serverAddr = "nacos:8848"  namespace = ""  
}  
# 启动TC服务  
sh seata-server.sh -m file  
(2)业务服务集成 Seata
  1. 添加依赖:

    <dependency>  <groupId>com.alibaba.cloud</groupId>  <artifactId>spring-cloud-starter-alibaba-seata</artifactId>  
    </dependency>  
    
  2. 配置application.yml

    seata:  tx-service-group: my_test_tx_group  # 事务分组名称  service:  vgroup-mapping:  my_test_tx_group: default  # 映射到Seata Server的default分组  
    
(3)创建 UNDO 日志表
CREATE TABLE `undo_log` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `branch_id` bigint(20) NOT NULL,  `xid` varchar(100) NOT NULL,  `context` varchar(128) NOT NULL,  `rollback_info` longblob NOT NULL,  `log_status` int(11) NOT NULL,  `log_created` datetime NOT NULL,  `log_modified` datetime NOT NULL,  PRIMARY KEY (`id`),  UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)  
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;  

3.3 代码实现

(1)订单服务(发起全局事务)
@Service  
public class OrderService {  @GlobalTransactional(name = "createOrder", rollbackFor = Exception.class)  public void createOrder(Order order) {  // 1. 保存订单  orderRepository.save(order);  // 2. 调用库存服务扣减库存  stockFeignClient.deductStock(order.getProductId(), order.getQuantity());  }  
}  
(2)库存服务(分支事务)
@Service  
public class StockService {  public void deductStock(Long productId, Integer quantity) {  Stock stock = stockRepository.findByProductId(productId);  if (stock.getStock() < quantity) {  throw new RuntimeException("库存不足");  }  stock.setStock(stock.getStock() - quantity);  stockRepository.save(stock);  }  
}  

3.4 异常处理与回滚验证

  • 正常提交:订单与库存操作均成功,全局事务提交
  • 库存不足回滚:库存服务抛异常,Seata 自动回滚订单插入操作
  • 查看 UNDO 日志:回滚时根据undo_log表恢复订单表数据

四、生产环境最佳实践

4.1 性能优化策略

(1)UNDO 日志优化
  • 批量删除过期日志:定期清理undo_log表中状态为已回滚已提交的记录
  • 分库分表:按xidbranch_id哈希分表,避免单表数据量过大
(2)事务分组设计
  • 按业务场景划分事务分组(如order_tx_grouppayment_tx_group
  • 不同分组对应不同的 Seata Server 集群,避免跨业务事务干扰
(3)锁优化
  • 启用globalTable全局锁表(Seata 1.5 + 新增),解决多服务操作同一资源时的脏写问题
  • 调整seata.tm.lock.wait-timeout(默认 30 秒)避免长时锁等待

4.2 高可用架构设计

(1)TC 集群部署
# Nacos配置中心存储Seata集群信息  
seata:  registry:  type: nacos  server-addr: nacos-cluster:8848  config:  type: nacos  server-addr: nacos-cluster:8848  namespace: seata-config  
(2)RM 数据源代理
  • 使用SeataDataSourceProxy代理数据源,支持 XA 模式与 AT 模式切换
  • 配置连接池参数(如 HikariCP 的connectionTimeout=30000)避免超时

4.3 监控与故障排查

(1)核心监控指标
  • seata_tm_commit_success:全局事务提交成功数
  • seata_tm_rollback_count:全局事务回滚数
  • seata_rm_undo_log_size:UNDO 日志表数据量
(2)排查工具
  • Seata Dashboard:可视化查看全局事务状态、分支事务详情
  • 日志分析:
    • TC 日志定位事务协调失败原因(io.seata.server.log
    • RM 日志查看 UNDO 日志生成与补偿过程(io.seata.rm.datasource

五、分布式事务方案选型指南

5.1 技术选型决策树

是否需要强一致?
选择2PC/XA模式 Seata TC/AT模式
是否需要灵活补偿逻辑?
选择TCC/SAGA模式 Seata TCC/SAGA
选择可靠消息/最终一致 Seata AT+MQ

5.2 各方案对比总结

方案开发成本性能一致性适用场景
Seata AT中高最终一致简单 CRUD 场景(如订单、库存)
Seata TCC最终一致复杂业务逻辑(如跨服务资源预留)
Seata SAGA中高最高最终一致长事务流程(如物流状态机)
XA 协议强一致金融级强一致场景(如账户转账)

六、Seata 源码深度解析:AT 模式核心流程

6.1 全局事务开启

// TransactionalTemplate.java  
public Object execute(TransactionTemplate.TransactionCallback action) {  // 1. 生成XID(全局事务ID)  String xid = transactionManager.begin();  try {  // 2. 执行业务逻辑  Object result = action.doInTransaction();  // 3. 提交全局事务  transactionManager.commit(xid);  return result;  } catch (Exception e) {  // 4. 回滚全局事务  transactionManager.rollback(xid);  throw e;  }  
}  

6.2 分支事务注册

// AbstractDataSourceProxy.java  
public Connection getConnection() throws SQLException {  Connection conn = physicalConnection;  // 注册分支事务(绑定XID)  RootContext.bind(xid);  return new ConnectionProxy(conn, this);  
}  

6.3 UNDO 日志生成

// UndoLogManager.java  
public void generateUndoLog(Connection conn, String xid, long branchId, SQLRecognizer sqlRecognizer) {  // 1. 解析SQL获取表名、主键  String tableName = sqlRecognizer.getTableName();  Object pk = sqlRecognizer.getPrimaryKey();  // 2. 查询旧数据快照  String oldRow = queryOldData(conn, tableName, pk);  // 3. 记录UNDO日志  insertUndoLog(conn, xid, branchId, tableName, oldRow, newRow);  
}  

七、总结与未来方向

7.1 Seata 核心价值

  • 无侵入性:AT 模式只需添加依赖,无需修改现有业务代码
  • 多模式支持:一套框架覆盖强一致与最终一致场景
  • 生态整合:与 Nacos、Sentinel、Spring Cloud 深度集成

7.2 挑战与应对

  • 性能损耗:AT 模式的 UNDO 日志与全局锁会带来 10%-20% 的性能开销,需通过连接池优化、批量操作减少影响
  • 异常处理:补偿逻辑需考虑幂等性(如通过xid+branch_id唯一键避免重复补偿)

7.3 未来趋势

  1. Serverless 支持:轻量化 Seata TC 部署,适配 Knative 等 Serverless 架构
  2. 多云协同:跨云厂商的分布式事务解决方案(如 Kubernetes-native 事务管理)
  3. AI 辅助:基于机器学习预测事务失败概率,动态调整补偿策略

相关文章:

04-Seata 深度解析:从分布式事务原理到 Seata 实战落地

Seata 深度解析&#xff1a;从分布式事务原理到 Seata 实战落地 一、分布式事务核心理论与挑战 1.1 分布式事务的本质难题 在微服务架构中&#xff0c;一次业务操作可能涉及多个服务的数据库操作&#xff0c;传统单体事务&#xff08;ACID&#xff09;无法跨越服务边界&…...

2025企业增长新引擎:AI Agent驱动人效跃迁|白皮书2.0发布

2025年伊始&#xff0c;一款名为DeepSeek-R1的国产AI大模型以其高性能、低成本等核心优势成功霸榜热搜&#xff0c;在全国乃至全球掀起一场以AI为核心的技术革新与管理变革。 面对这样极具颠覆性的革新命题&#xff0c;易路人力资源科技王天扬先生自2022年起就率团队持续专注于…...

IJCV-2025 | 深圳大学记忆增强的具身导航!ESceme:基于情景记忆的视觉语言导航

作者&#xff1a;Qi Zheng 1 , 2 ^{1,2} 1,2, Daqing Liu 3 ^{3} 3, Chaoyue Wang 3 ^{3} 3, Jing Zhang 2 ^{2} 2, Dadong Wang 4 ^{4} 4, Dacheng Tao 2 ^{2} 2单位&#xff1a; 1 ^{1} 1深圳大学电子与信息工程学院&#xff0c; 2 ^{2} 2悉尼大学计算机科学学院&#xff0c;…...

[第十六届蓝桥杯 JavaB 组] 真题 + 经验分享

A&#xff1a;逃离高塔(AC) 这题就是简单的签到题&#xff0c;按照题意枚举即可。需要注意的是不要忘记用long&#xff0c;用int的话会爆。 &#x1f4d6; 代码示例&#xff1a; import java.io.*; import java.util.*; public class Main {public static PrintWriter pr ne…...

《分布式软总线:网络抖动下的数据传输“定海神针”》

在当下&#xff0c;智能设备之间的互联互通已成为生活与工作的刚需。分布式软总线作为实现这一愿景的关键技术&#xff0c;正日益凸显其重要性。然而&#xff0c;网络环境的复杂性&#xff0c;尤其是网络抖动频繁的情况&#xff0c;给分布式软总线的数据传输带来了严峻挑战。如…...

C++函数

函数 为什么要使用函数 已经有main函数&#xff0c;为什么还要自定义函数&#xff1f;&#xff1a;“避免重复制造轮子”&#xff0c;提高开发效率 函数的定义 函数的设计方法&#xff1a;先确定函数的功能、确定函数的参数、是否需要参数&#xff0c;参数的个数&#xff0c…...

FreeRTOS菜鸟入门(五)·空闲任务与阻塞延时的实现

目录 1. 实现空闲任务 1.1 定义空闲任务的栈 1.2 定义空闲任务的任务控制块 1.3 创建空闲任务 2. 实现阻塞延时 2.1 vTaskDelay()函数 2.2 修改 vTaskSwitchContext()函数 3. SysTick 中断服务函数 4. SysTick 初始化函数 通过之前我们了解知道&#xff0c;任…...

PCIe 学习笔记(一)

系列文章目录 【PCIe】链路测试&#xff0c;数字工程师也要会看高速信号眼图&#xff01; 【PCIe】链路训练状态机(LTSSM) - PCIe链路建立过程概述 【PCIe】PCIe设备的BDF与系统枚举过程 文章目录 系列文章目录PCIe LTSSM**1. 链路训练状态&#xff08;Training States&#…...

【正点原子STM32MP257连载】第四章 ATK-DLMP257B功能测试——LED、按键测试

1&#xff09;实验平台&#xff1a;正点原子ATK-DLMP257B开发板 2&#xff09;浏览产品&#xff1a;https://www.alientek.com/Product_Details/135.html 3&#xff09;全套实验源码手册视频下载&#xff1a;正点原子资料下载中心 文章目录 第四章 ATK-DLMP257B功能测试4.1 LED…...

深度为16,位宽8bit的单端口SRAM——学习记录

链接&#xff1a; 【Verilog HDL 训练】第 13 天&#xff08;存储器、SRAM&#xff09;-云社区-华为云 module sram #(parameter ADDR_BITS4)(input clk,input [ 7:0] addr,input [ 7:0] din,input ce,input we,output reg [ 7:0] dout);localparam MEM_DEPTH 1<<ADDR_…...

面向对象编程

在面向对象编程中&#xff0c;除了通过创建类的实例来访问其属性和方法外&#xff0c;还可以通过在一个类里创建另一个类的属性&#xff08;本质上也是持有另一个类的实例引用&#xff09;的方式来访问该类的属性和方法。下面为你详细解释这两种方式&#xff1a; 1. 通过创建实…...

远程登录一个Linux系统,如何用命令快速知道该系统属于Linux的哪个发行版,以及该服务器的各种配置参数,运行状态?

远程登录一个Linux系统&#xff0c;如何用命令快速知道该系统属于Linux的哪个发行版&#xff0c;以及该服务器的各种配置参数&#xff0c;运行状态&#xff1f; 查看Linux发行版信息 查看发行版名称和版本&#xff1a; cat /etc/*-release或 lsb_release -a查看内核版本&#…...

简单socket通信,回显 服务器程序与客户端程序之间的通信。

Socket 通信编程是一种基于网络的通信方式&#xff0c;允许不同主机上的程序通过网络进行数据交换。 实现结构try catch&#xff1a; 前情了解&#xff1a; 1.如何创建服务器端 定义ServerSocket套接字&#xff0c;需要等待客户端连接&#xff0c;阻塞&#xff0c;直到接入连接…...

C# 基类型和派生类型之间的转型

1.什么是基类型和派生类 基类型&#xff1a;父类&#xff0c;所有子类都继承自它。 派生类型&#xff1a;子类&#xff0c;继承了父类的属性和方法&#xff0c;还可以添加自己的新功能。 例子&#xff1a; class Animal { }//基类型 class Dog : Animal { }//派生类型 这…...

深度学习--激活函数

激活函数通过计算加权和并加上偏置来确定神经元是否应该倍激活&#xff0c;它们将输入信号转换为输出的可微运算。大多数激活函数都是非线性的&#xff0c;由于激活函数是深度学习的基础&#xff0c;下面简要介绍一些常见的激活函数。 1 RelU函数 最受欢迎的激活函数是修正线性…...

MySQL 缓存机制全解析:从磁盘 I/O 到性能优化

MySQL 缓存机制全解析&#xff1a;从磁盘 I/O 到性能优化 MySQL 的缓存机制是提升数据库性能的关键部分&#xff0c;它通过多级缓存减少磁盘 I/O 和计算开销&#xff0c;从而提高查询和写入的效率。 1. 为什么需要缓存&#xff1f; 数据库的性能瓶颈通常集中在磁盘 I/O 上。…...

【项目管理】第17章 项目干系人管理-- 知识点整理

项目管理-相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 (一)知识总览 项目管理知识域 知识点: (项目管理概论、立项管理、十大知识域、配置与变更管理、绩效域) 对应:第6章-第19章 第6章 项目管理概论 4分第13章 项目资源管理 3-4分第7章 项目…...

编程语言到mysql ‘\‘到数量关系

在 MySQL 的模糊查询中&#xff0c;反斜杠 \ 的转义规则需要根据 转义层级 和 SQL 模式 来确定。以下是详细说明及示例&#xff1a; 一、默认模式下&#xff08;未启用 NO_BACKSLASH_ESCAPES&#xff09; 1. 规则说明 反斜杠转义&#xff1a;\ 是 MySQL 的默认转义字符。 转义…...

本地生活服务平台搭建方案详解:同城跑腿外卖系统源码一体化开发

在数字化浪潮不断推进的今天&#xff0c;本地生活服务平台正逐渐成为人们日常生活中不可或缺的一部分。从点餐外卖到同城帮买、帮送、帮取&#xff0c;用户对即时服务的需求愈发强烈。与此同时&#xff0c;创业者和本地商家也纷纷看好“同城服务 外卖配送”的一体化平台模式&a…...

索引语法SQL性能分析索引的使用

目录 准备: 一.索引语法 1). 创建索引 2). 查看索引 3). 删除索引 4).使用索引查询和普通查询的区别 二.SQL性能分析 1.SQL执行频率 2.慢查询日志 3.profile详情 4.explain 三.索引的使用 1.最左前缀法则 2.范围查询 3.索引失效情况 索引列运算 字符串不加引号…...

Docker技术基础新手入门教程

Docker技术深度解析:从架构到实战的运维指南 一、Docker核心架构与组件详解1. 什么是Docker?1. Docker引擎(Docker Engine)2. Docker对象模型二、关键技术深度剖析1. 容器隔离机制2. 容器网络模型网络驱动类型自定义网络实战3. 存储卷与数据持久化三种挂载方式对比示例:My…...

NO.93十六届蓝桥杯备战|图论基础-拓扑排序|有向无环图|AOV网|摄像头|最大食物链计数|杂物(C++)

有向⽆环图 若⼀个有向图中不存在回路&#xff0c;则称为有向⽆环图(directed acycline graph)&#xff0c;简称 DAG 图 AOV⽹ 举⼀个现实中的例⼦&#xff1a;课程的学习是有优先次序的&#xff0c;如果规划不当会严重影响学习效果。课程间的先后次序可以⽤有向图表⽰ 在…...

Rust泛型与特性

文章目录 泛型函数中的泛型结构体与枚举中的泛型特性&#xff08;trait&#xff09;默认特性Trait作为参数特性做返回值 给结构体实现方法 泛型 泛型编程是现代编程语言中重要的机制 C是通过模板来实现泛型的&#xff0c;而C语言中是没有泛型的 泛型是用来表达抽象类型的机制…...

Day08【基于预训练模型分词器实现交互型文本匹配】

基于预训练模型分词器实现交互型文本匹配 目标数据准备参数配置数据处理模型构建主程序测试与评估总结 目标 本文基于预训练模型bert分词器BertTokenizer&#xff0c;将输入的文本以文本对的形式&#xff0c;送入到分词器中得到文本对的词嵌入向量&#xff0c;之后经过若干网络…...

基于uniapp 实现画板签字

直接上效果图 代码 <template><view class"container"><!-- 签名画布 --><view class"canvas-container"><canvas canvas-id"signCanvas" class"sign-canvas"touchstart"handleTouchStart"touc…...

5.跳表(skiplist)

1. 什么是跳表 -skiplist skiplist 本质上也是一种查找结构&#xff0c;用于解决算法中的查找问题&#xff0c;跟平衡搜索树和哈希表的价值是一样的&#xff0c;可以作为key 或者 key/value 的查找模型。 skiplist &#xff0c;顾名思义&#xff0c;首先它是一个 list 。实际上…...

GitHub 封禁中国 IP:影响、原因及应对

在技术全球化的当下&#xff0c;代码托管平台如同开发者的 “数字仓库”&#xff0c;而 GitHub 无疑是其中最广为人知的一座。但在 2025 年 4 月 13 日&#xff0c;一则令人震惊的消息在国内开发者社群中炸开了锅 ——GitHub 疑似封禁中国 IP。一时间&#xff0c;这一事件迅速成…...

基于工业操作系统构建企业数字化生态的实践指南

一、工业操作系统选型策略 工业操作系统&#xff08;IIoT OS&#xff09;的选型需从功能适配性、技术成熟度、生态兼容性三个维度综合评估。以玉麟科技DIOS平台为例&#xff0c;其 "云端 终端" 架构支持全球设备管理&#xff0c;通过工业知识模型实现设备健康度预测…...

金能电力领跑京东工业安全工器具赛道 2025年首季度数据诠释“头部效应”

金能电力领跑京东工业安全工器具赛道 2025年首季度数据诠释“头部效应” 在2025年第一季度京东工业平台“电料辅件-安全工器具”热销品牌的激烈竞争中&#xff0c;金能电力以一组极具说服力的数据&#xff0c;向行业展示了何为“绝对头部”。从成交金额、销量到流量、客群覆…...

基于大模型的反流食管炎手术全流程风险预测与治疗方案研究报告

目录 一、引言 1.1 研究背景 1.2 研究目的 1.3 研究方法与创新点 二、反流食管炎概述 2.1 定义与发病机制 2.2 临床症状与诊断标准 2.3 流行病学现状 三、大模型技术原理与应用现状 3.1 大模型基本原理 3.2 在医疗领域的应用案例 3.3 用于反流食管炎预测的优势 四…...

探索 C 与 Java/Kotlin 的语言差异:从指针到高阶函数

作为一名熟悉 Java 和 Kotlin 的开发者&#xff0c;初次接触 C/C 时常会遇到一系列概念上的“文化冲击”。本文将从几个关键点出发&#xff0c;帮助你更好地理解 C/C 与 Java/Kotlin 在语言设计上的核心区别。 1. 指向未知类型的指针 void*、结构体指针访问 ->、空指针常量 …...

Redis之缓存过期淘汰策略

面试切入点 Redis内存满了怎么办&#xff1f; redis的默认内存多少&#xff1f;在哪里查看&#xff1f;如何设置修改&#xff1f; 查看redis最大占用内存 打开redis配置文件&#xff0c;设置maxmemory参数&#xff0c;maxmemory是bytes字节类型&#xff0c;注意转换。 redi…...

Rust-引用借用规则

目录 一、概述 二、借用规则 三、详细解释 3.1 第一条规则 3.2 第二条规则 3.3 第三条规则 四、总结 Welcome to Code Blocks blog 本篇文章主要介绍了 [Rust-引用借用规则] ❤博主广交技术好友&#xff0c;喜欢文章的可以关注一下❤ 一、概述 Rust为确保程序在运行时不…...

【报错】解决pytorch出现RuntimeError: An attempt has been made to start a new process...

此错误是由于在 Windows 系统中使用多进程时&#xff0c;没有正确使用 if __name__ __main__: 语句块造成的。在 Windows 里&#xff0c;多进程的启动方式是 spawn&#xff0c;并非 fork&#xff0c;所以必须在主模块中使用 if __name__ __main__: 语句块来避免子进程重复执行…...

游戏引擎学习第228天

对上次的内容进行回顾&#xff0c;并为今天的开发环节做铺垫。 目前大部分功能我们已经完成了&#xff0c;唯一剩下的是一个我们知道存在但目前不会实际触发的 bug。这个 bug 的本质是在某些线程仍然访问一个已经被销毁的游戏模式&#xff08;mode&#xff09;之后的状态&…...

Pytorch Hook 技巧

通过 functools.partial 扩展 Pytorch Hook 机制 阅读 atom 文章源码时学习到的技巧&#xff0c;mark一下 通过 functools.partial&#xff0c;开发者无需修改原始函数或 PyTorch 的 Hook 机制&#xff0c;即可实现​​参数扩展与接口适配​​&#xff0c;这是 Python 函数式编…...

Python multiprocessing模块介绍

multiprocessing 是 Python 标准库中的一个模块&#xff0c;用于实现多进程并行计算&#xff0c;可以在多核 CPU 上显著提升程序性能&#xff0c;尤其适用于 CPU 密集型任务。Python 的多线程由于 GIL&#xff08;全局解释器锁&#xff09;限制&#xff0c;在进行 CPU 密集型任…...

[特殊字符] LoRA微调大模型实践:从MAC到Web的全流程指南

&#x1f680; 实践步骤概览 今天我们要在MAC上完成一个完整的AI项目闭环&#xff1a; 微调一个大模型 → 2. 导出模型并部署 → 3. 暴露API给web后端 → 4. 前端展示 &#x1f6e0;️ 微调模型准备 核心配置 框架&#xff1a;LLama-Factory &#x1f3ed; 算法&#xff1a…...

第二天 通过脚本控制物体移动和旋转

一、Unity脚本编程基础认知 1.1 为什么说脚本是Unity的灵魂&#xff1f; Unity引擎的核心架构采用ECS&#xff08;Entity-Component-System&#xff09;模式&#xff0c;脚本作为组件的具体实现&#xff0c;控制着游戏对象的所有行为。统计显示&#xff0c;一个中等规模的Uni…...

在SpringBoot中访问 static 与 templates 目录下的内容

目录 步骤一&#xff1a;添加 Thymeleaf 依赖 (处理 Templates 目录)步骤二&#xff1a;配置静态资源路径 (可选但建议了解)步骤三&#xff1a;访问不同目录下的 HTML 文件访问 static 目录下的 HTML 文件访问 templates 目录下的 HTML 文件 总结 在使用 Spring Boot 开发 Web …...

常见的 API 设计风格

在软件开发中&#xff0c;常见的 API 设计风格主要有以下几种&#xff0c;每种风格适用于不同的场景和需求&#xff1a; 1. RESTful API (主流) 特点&#xff1a; 基于 HTTP 协议&#xff0c;使用标准方法&#xff08;GET/POST/PUT/DELETE&#xff09;资源导向&#xff08;UR…...

Grass.io项目现状:DePIN亮眼明星,扩张中的AI数据银行

Grass.io项目现状:DePIN亮眼明星,扩张中的AI数据银行 Grass如何在DePIN项目丛林中脱颖而出? 答案在于其"零门槛"策略——用户是基石,其他一切皆为杠杆。 Grass通过"技术+模式"双轮驱动打破行业内卷:零知识证明技术与Solana Layer2架构确保数据真实…...

ERR_PNPM_DLX_NO_BIN No binaries found in tailwindcss

场景复现&#xff1a; 最近在vue3项目中安装了tailwindcss&#xff0c;但是它默认帮我安装的版本是4XX的&#xff0c;导致我执行 npx tailwindcss init -p报错了。 解决方案&#xff1a; 更改tailwindcss的版本为3 pnpm add -D tailwindcss3再次执行生成tailwindcss的初始…...

2025“钉耙编程”中国大学生算法设计春季联赛(6)(1001,1003,1008):1007

不知道为啥&#xff0c;感觉后面的联赛题目有挺多出的是模拟题目&#xff08;这三道题目难度依次递增&#xff09; 1001 #include<bits/stdc.h> using namespace std; #define int long long const int op1e97; const int o1e34;inline void solve(){int n,a,b,c;cin>…...

Leetcode 2814. 避免淹死并到达目的地的最短时间

1.题目基本信息 1.1.题目描述 现给定一个 n * m 的索引从 0 开始的二维字符串网格 land&#xff0c;目前你站在为 “S” 的单元格上&#xff0c;你需要到达为 “D” 的单元格。在这片区域上还有另外三种类型的单元格&#xff1a; “.”&#xff1a;这些单元格是空的。 “X”…...

4.15【A】pc homework3~

5 假设read_document函数可以实现读取第m个文件&#xff0c;并返回该文本文档的每行数据 那么考虑双层并行结构&#xff0c;外层为文档级并行&#xff0c;内层为每个文档内的行级并行 动态分配文档任务&#xff0c;避免线程闲置 #include <omp.h> int total_words …...

aslist和list的区别

‌Arrays.asList和List的主要区别在于它们的固定长度和不可变性、与原始数组的关系、性能以及使用场景。 一、固定长度和不可变性 ‌Arrays.asList‌&#xff1a;通过Arrays.asList方法创建的List是一个固定长度的List&#xff0c;其长度与原始数组相同。这意味着你不能通过添…...

Notepad++中将文档格式从Windows(CR LF)转换为Unix(LF)

在Windows中用记事本写了一个.sh的Linux运行脚本&#xff0c;是无法直接在Linux中执行&#xff0c;需要首先把文本编码格式转换为Unix的&#xff0c;特别是换行符这些&#xff0c;转换步骤如下&#xff1a; 1、打开文档 在Notepad中打开需要转换的文件。 2、进入文档格式转换…...

控制理论与应用Latex模版/中文Latex

报错1 ! Package CJK Error: Invalid character code. 解决方法&#xff1a; 用记事本打开tex文件 另存为&#xff0c;选择utf-8格式 ! paragraph ended before \mulearg was complete. 备注&#xff0c;控制理论与应用有个自己的模版内容&#xff0c;是通过导入方式调用…...

Linux指令和权限(10-3)

部分指令和权限 一丶指令 1.echo echo的基础作用向显示器输出。作用类似于C语言的printf&#xff0c;C的cout。 1.1 echo 输入内容 – 会显示输出到屏幕的下一行 echo "hello Linux"1.2 echo 输入内容>目标文件 – 向目标文件输出内容&#xff08;输出重定向&…...