我的下单接口偶尔会给同一个用户生成两笔一模一样的订单、甚至重复扣款,我对着这些诡异的重复数据排查了大半天才真正理解幂等性的复盘

我的下单接口偶尔生成两笔几乎一模一样的订单、甚至同一笔消费扣两次款,两条订单除订单号外字段全同、时间差几百毫秒像被复制。我一开始以为是用户手抖点两次,排查日志才懂:重复大多不是点两次,而是"重试"——服务端处理成功了但返回响应超时,前端没收到成功就自动重试;调下游支付成功了但响应超时,本服务以为失败就重试;走 MQ 的 at-least-once 同一消息被消费多次。本质是网络不可靠、超时不等于失败,重试是各层默认的自我保护,"重复"是分布式常态,而我的下单是非幂等操作,执行一次和两次结果不同。这篇从幂等性与分布式重复常态讲起,到幂等键+唯一约束去重(而非先查再插)、状态机CAS/token/去重表等按场景的实现、几种方案对比与端到端链路的常见坑、用并发+重试测试验证,以及那句最戳心的——别祈祷不出错,要假设一定会重复、会超时,并提前设计好出错时系统依然正确。

我的下单接口偶尔会给同一个用户生成两笔一模一样的订单、甚至重复扣款,我对着这些诡异的重复数据排查了大半天才真正理解幂等性的复盘

这是一个让我对"分布式系统"敬畏起来的故事。我有一个下单接口,逻辑很直白:接收用户请求 → 扣减库存 → 创建订单 → 扣款。它绝大多数时候都工作得很好。可线上偶尔会冒出一些诡异的脏数据:同一个用户,在几乎同一时刻,生成了两笔内容一模一样的订单;更严重的几次,是同一笔消费,被扣了两次款客服收到投诉,我一查数据库,两条订单除了订单号,其余字段(用户、商品、金额、时间)几乎完全相同,像是被复制了一份

我一开始怀疑是前端有 bug、用户手抖点了两次。可深入排查日志后,我发现真相远比这复杂,也补上了我对分布式系统一个最核心的认知漏洞:这些重复,大多不是用户点两次造成的,而是"重试"造成的。场景五花八门:其一,用户点了下单,请求已经到了服务端、也处理成功了,但返回响应时,网络抖动、超时了;前端没收到成功响应,以为失败了,于是自动重试,又发了一次——服务端就处理了两次其二,我的服务调用支付/库存等下游时,下游其实成功了,但响应超时,我的服务以为失败,发起了重试其三,如果中间过了消息队列,MQ 为了保证"消息不丢",采用的是"至少投递一次(at-least-once)"语义,同一条消息,可能被投递、消费多次而所有这些场景,都指向同一个我从未真正重视过的本质:在分布式系统里,"一次请求/消息,被处理多次",不是异常,而是必然会发生的常态——因为网络是不可靠的,而为了对抗这种不可靠,重试,是几乎所有环节的默认自我保护机制;它带来的代价,就是"重复"。而我的下单接口,是一个非幂等(non-idempotent)的操作:它被执行一次和执行两次,产生的结果,是不同的(执行两次就生成两笔订单、扣两次款);把一个非幂等的操作,暴露在一个"必然会重复请求"的环境里,出乱子,只是迟早的事我这才痛彻地明白:"幂等性(idempotency)"——即"一个操作,无论执行一次还是多次,产生的结果都相同"——不是一个锦上添花的高级特性,而是分布式系统里,任何"会改变数据的关键写操作",都必须具备的基本生存能力。不设计幂等,就等于默认网络永远可靠、请求永不重复,而这,在分布式世界里,是一个致命的天真假设

故障现场:非幂等的写操作,遇上重试就重复执行

我把这个"重复下单"的现场,用代码摊开给你看:

// ✗ 灾难: 非幂等的下单, 重试一次就多生成一笔订单/多扣一次款
public Order createOrder(OrderRequest req) {
    // ✗ 没有任何"防重复"机制, 来一次请求就实打实执行一次
    deductStock(req.getItemId(), req.getQty());     // 扣库存
    Order order = new Order(req);
    orderDao.insert(order);                          // ✗ 每次都 insert 一条新订单
    pay(req.getUserId(), req.getAmount());           // ✗ 每次都扣一次款
    return order;
}

// 重复怎么发生(都不是"用户故意点两次"):
//   场景1: 服务端处理成功了, 但返回响应时网络超时
//          → 前端没收到成功 → 自动重试 → 服务端处理第二次 → 两笔订单。
//   场景2: 调下游(支付)成功了, 但下游响应超时
//          → 本服务以为失败 → 重试 → 扣两次款。
//   场景3: 走了 MQ, at-least-once 语义 → 同一消息被消费多次 → 重复执行。

// 本质:
//   - 网络不可靠 → 重试是默认的自我保护 → "重复请求"是分布式常态。
//   - createOrder 是"非幂等"操作: 执行1次 vs 2次 结果不同(多一笔订单)。
//   - 非幂等操作 + 必然会重复的环境 = 迟早出重复数据。

// 现象: 数据库里两条订单, 除订单号外字段几乎全同, 时间相差几百毫秒。

// 根因: 关键写操作没做幂等, 遇到网络重试/重复投递时被重复执行。

看着这段代码,我才算彻底想明白了这些重复数据的根源。问题的核心,是我的 createOrder 是一个非幂等的写操作——它没有任何"防重复"机制,来一次请求,就实打实地执行一次:扣一次库存、插一条订单、扣一次款。而重复,几乎都不是"用户故意点两次",而是重试:场景一,服务端处理成功了,但返回响应时网络超时,前端没收到成功、自动重试,服务端就处理了第二次;场景二,调下游支付成功了但响应超时,本服务以为失败、重试,扣了两次款;场景三,走了 MQ,at-least-once 语义下同一消息被消费多次这一切的本质是:网络不可靠 → 重试是默认的自我保护 → "重复请求"是分布式系统的常态;而把一个非幂等的操作(执行 1 次和 2 次结果不同),放进一个必然会重复的环境,就迟早会出重复数据归根结底:关键写操作没做幂等,遇到网络重试/重复投递时被重复执行,这,就是重复下单、重复扣款的根源。

第一件事:搞懂幂等性与分布式的"重复"常态

定位到根源,我必须把"幂等性"和"为什么会重复"这件事,从根上彻底搞清楚:

幂等性: 一个操作执行一次和执行多次, 产生的结果相同

# 为什么分布式系统里"重复"是常态?
#   - 网络不可靠: 请求/响应都可能丢、可能超时。
#   - 超时的歧义: "超时" ≠ "失败"! 可能"对方已成功, 只是响应没回来"。
#   - 为对抗不可靠 → 各层默认重试(前端重试、RPC重试、MQ重投)。
#   - 结果: 同一个操作, 必然有概率被请求/执行多次。

# 哪些操作天然幂等? 哪些不是?
#   - 天然幂等: 查询(GET)、把状态设为固定值(set status=PAID)、删除(delete by id)。
#   - 非幂等: 插入新记录(每次多一条)、累加(balance += 100, 每次多扣)、
#             "创建订单""扣款""发短信"等"产生新副作用"的操作。

# HTTP 方法的幂等约定(设计参考):
#   - GET/PUT/DELETE 应设计成幂等; POST 通常非幂等(创建)。

# 幂等的核心思路: 让系统能"识别出这是重复请求, 并直接返回上次的结果"
#   - 需要一个"唯一标识"来判断"这是不是同一个操作"。
#   - 第一次执行并记录; 后续重复请求识别到 → 不再执行, 返回已有结果。

# 关键认知: 别假设"请求只来一次"。
#   - 任何会改数据的关键写操作, 都要设计成"重复执行也安全"。
#   - "超时不代表失败" 是分布式第一课。

# 核心: 网络不可靠+重试使"重复"成为分布式常态; 非幂等写操作必然出事;
#   关键写操作必须做幂等(靠唯一标识识别重复并返回上次结果)。

原理终于清晰了。什么是幂等性?——一个操作,执行一次和执行多次,产生的结果相同为什么分布式系统里"重复"是常态?因为网络不可靠(请求/响应都可能丢、超时);而最致命的,是"超时"的歧义——超时 ≠ 失败!它很可能是"对方其实已经成功了,只是响应没回来";为了对抗这种不可靠,各层都默认重试(前端、RPC、MQ),结果就是同一个操作,必然有概率被执行多次哪些操作天然幂等?查询、把状态设为固定值(set status=PAID)、按 id 删除,是天然幂等的;而插入新记录、累加(balance += 100)、创建订单、扣款、发短信等"产生新副作用"的操作,是非幂等的。(HTTP 也有约定:GET/PUT/DELETE 应幂等,POST 通常非幂等。)那幂等的核心思路是什么?让系统能"识别出这是重复请求,并直接返回上次的结果"——这需要一个"唯一标识"来判断"是不是同一个操作":第一次执行并记录,后续重复请求识别到,就不再执行、直接返回已有结果由此,我刻下一个关键认知:别假设"请求只来一次";任何会改数据的关键写操作,都要设计成"重复执行也安全";"超时不代表失败",是分布式第一课。归根结底:网络不可靠 + 重试,使"重复"成为分布式常态;非幂等写操作必然出事;关键写操作必须做幂等(靠唯一标识识别重复并返回上次结果)。

第二件事:正解——用幂等键 + 唯一约束去重

搞懂了原理,正解就清晰了:给每个请求一个全局唯一的"幂等键",用数据库的唯一约束做"同一个键只能成功一次"的硬保证。

// ✓ 正解: 客户端带幂等键 + 服务端用唯一约束去重
// 1. 客户端生成一个全局唯一的幂等键(如 UUID), 同一笔操作重试时复用同一个键
//    POST /order  Header: Idempotency-Key: 7f3a... (重试时这个键不变!)

// 2. 服务端: 幂等键落库, 用唯一索引保证"同一个键只能插入成功一次"
//    建表: CREATE TABLE idempotent (key VARCHAR PRIMARY KEY, result TEXT, status INT);

public Order createOrder(OrderRequest req, String idempotencyKey) {
    // ✓ 先尝试占位: 唯一约束保证并发/重试下只有一个能成功
    try {
        idempotentDao.insert(idempotencyKey, "PROCESSING");  // 主键=幂等键
    } catch (DuplicateKeyException e) {
        // ✓ 插入失败 = 这个键已存在 = 重复请求!
        Record r = idempotentDao.get(idempotencyKey);
        if (r.status == DONE) return r.result;     // ✓ 已完成 → 直接返回上次结果
        else throw new RetryLaterException();       // 上次还在处理中 → 让客户端稍后重试
    }

    // ✓ 走到这里说明是"第一次", 正常执行业务
    Order order = doCreateOrder(req);
    idempotentDao.update(idempotencyKey, DONE, order);  // ✓ 记录结果
    return order;
}

// 为什么用唯一约束?
//   - 它是数据库层面的"原子去重", 天然扛并发(两个并发请求只有一个 insert 成功)。
//   - 比"先查再插"可靠: 先查再插之间有缝隙, 并发下两个都查不到、都插入 → 仍重复!

// 核心: 客户端带不变的幂等键(重试复用), 服务端用唯一约束原子去重,
//   重复请求识别到就返回上次结果, 而不是再执行一遍。

修复的方案,既简洁又可靠。第一步,客户端为每一笔操作,生成一个全局唯一的"幂等键"(如 UUID),并放在请求头里;关键是——重试时,复用同一个键!(这样服务端才能识别出"这是同一笔操作的重试")。第二步,服务端把幂等键落库,并用数据库的唯一约束(主键/唯一索引)做去重:处理前,先尝试用幂等键"占位"insert——如果 insert 成功,说明是"第一次",正常执行业务、再记录结果;如果 insert 抛唯一键冲突,说明这个键已存在、是重复请求,这时直接返回上次的结果(若上次还在处理中,就让客户端稍后重试)。这里有个关键设计:为什么用唯一约束、而不是"先查有没有、再决定插不插"?因为"先查再插"之间有时间缝隙,并发下两个请求可能都查不到、于是都去插入,照样重复!而唯一约束是数据库层面的原子去重,天然扛并发——两个并发请求,只有一个能 insert 成功归根结底:客户端带不变的幂等键(重试复用),服务端用唯一约束原子去重,重复请求识别到就返回上次结果,而不是再执行一遍。

第三件事:不同场景的幂等实现方式

幂等键+唯一约束是通法,但不同场景还有更轻量或更合适的实现,我也一并梳理了:

幂等的几种实现: 按场景选最合适的

# 1. 唯一约束去重(最通用, 推荐):
#    - 幂等键 / 业务唯一键(如"用户+商品+秒级时间"或订单号)做唯一索引。
#    - insert 冲突即视为重复 → 返回已有结果。
#    - 适合: 创建类操作(下单、注册、支付单)。

# 2. 状态机流转(适合有状态的对象):
#    - 订单: 待支付 → 已支付 → 已发货, 用 CAS 更新:
#      UPDATE order SET status='PAID' WHERE id=? AND status='UNPAID'
#    - 重复执行: 第二次 WHERE 条件不满足(已是PAID), 影响行数=0, 不重复扣。
#    - 适合: 支付、发货等"状态推进"类操作。

# 3. token / 防重令牌(适合防表单重复提交):
#    - 进页面先领一个一次性 token, 提交时带上。
#    - 服务端校验并删除 token; 重复提交时 token 已不存在 → 拒绝。
#    - 适合: 前端表单防重复点击。

# 4. 去重表 + 唯一键(适合 MQ 消费幂等):
#    - 消费消息前, 用 messageId 查/插去重表。
#    - 已存在 → 说明消费过 → 直接 ack 跳过。
#    - 适合: MQ at-least-once 下的消费端去重。

# 选型要点:
#   - 创建类 → 唯一约束; 状态推进 → 状态机CAS;
#   - 表单防重 → token; MQ消费 → 去重表。
#   - 幂等键怎么来: 客户端生成(UUID) 或 用业务天然唯一键。

# 核心: 按场景选幂等实现 —— 创建用唯一约束、状态推进用状态机CAS、
#   表单用token、MQ消费用去重表; 本质都是"识别重复 + 不重复执行"。

幂等的"工具箱"就此打开。方式一,唯一约束去重(最通用):用幂等键或业务唯一键(如"用户+商品+秒级时间"、或订单号)建唯一索引,insert 冲突即视为重复,适合下单、注册、支付单等创建类操作。方式二,状态机流转(适合有状态对象):用 CAS 更新——UPDATE order SET status='PAID' WHERE id=? AND status='UNPAID',重复执行时第二次 WHERE 条件已不满足、影响行数为 0,不会重复扣,适合支付、发货等"状态推进"操作。方式三,token 防重令牌:进页面先领一个一次性 token,提交时带上,服务端校验并删除,重复提交时 token 已不存在、被拒绝,适合前端表单防重复点击方式四,去重表(适合 MQ 消费):消费前用 messageId 查/插去重表,已存在就说明消费过、直接 ack 跳过,适合 MQ at-least-once 下的消费端去重归根结底:按场景选幂等实现——创建用唯一约束、状态推进用状态机 CAS、表单用 token、MQ 消费用去重表;但它们的本质,都是同一个:"识别出重复 + 不重复执行"

下面这张图,是这次"重复下单"的成因与幂等解法:

第四件事:几种幂等方案的横向对比

修复时我把几种幂等实现,按"适用场景、并发安全、复杂度"几个维度横向比了一遍,方便对号入座。

方案 核心机制 最适合的场景 注意点
幂等键 + 唯一约束 insert 冲突即去重 下单/注册/支付单等创建 键要全局唯一, 重试需复用同一键
状态机 CAS WHERE 限定旧状态 支付/发货等状态推进 看影响行数判断是否真的改了
防重 token 一次性令牌, 用后即焚 前端表单防重复提交 token 要有有效期
去重表(messageId) 消费前查/插去重表 MQ at-least-once 消费 去重记录要定期清理
分布式锁 同一键串行执行 需严格串行的临界操作 有性能损耗, 锁要设超时防死锁

把它们排在一起,选择就清楚了。最通用、最该优先考虑的,是幂等键 + 唯一约束——它简单、可靠、靠数据库天然扛并发,适合绝大多数创建类操作;状态推进(支付、发货)用状态机 CAS 最自然(靠 WHERE 限定旧状态 + 看影响行数);前端表单防重token;MQ 消费去重去重表至于分布式锁:它能让同一键串行执行,适合需要严格串行的临界操作,但它有性能损耗、锁还要设超时防死锁,能用唯一约束/CAS 解决的,就别动用分布式锁(杀鸡用牛刀)。这些方案的共性,值得反复咀嚼:它们没有一个是"阻止重复请求到来"(那做不到),而全都是"让重复请求到来后,不产生重复的副作用"——这,正是幂等设计的精髓:不与"重复"对抗,而是坦然接纳重复、并让它变得无害

第五件事:幂等设计里那些容易踩的坑

做幂等,看着简单,但魔鬼在细节。我把实现幂等时容易自以为做对、其实有漏洞的坑,系统排查了一遍。

容易踩的坑 问题 正确做法
用"先查再插"判重 查和插之间有缝隙, 并发下仍重复 用唯一约束让数据库原子去重
重试时幂等键变了 每次新键, 服务端认不出是重复 同一操作的重试必须复用同一键
幂等记录和业务不在一个事务 业务成功但记录失败(或反之), 状态不一致 放同一本地事务, 或用状态标记+补偿
只防了入口, 没防下游调用 对下游的重试仍重复扣款 调下游也要传幂等键, 下游也做幂等
去重表/键无限增长 越积越多拖垮存储 设 TTL 或定期归档清理
"处理中"状态没处理好 第一次还没完, 第二次直接返回空 区分 处理中/已完成, 处理中让其重试

这张表,让我对"幂等"的认识,从"加个唯一键就行"深化到了"一个需要严谨设计的完整链路"。最隐蔽、也最致命的坑,是"先查再插"判重:它看起来能防重复,可查询和插入之间的那道缝隙,在并发下会被两个请求同时钻过去,照样产生重复——必须用数据库唯一约束这种原子手段。其余的坑也都很真实:重试时幂等键变了(每次新键,服务端根本认不出重复);幂等记录和业务不在一个事务(导致状态不一致);只防了入口、没防对下游的调用(对下游重试照样重复扣款,所以调下游也要传幂等键、下游也要做幂等);去重表无限增长(要设 TTL/定期清理);以及"处理中"状态没处理好(第一次还没完成,第二次重复请求直接返回了空结果)。它们共同的启示是:幂等不是一个"点",而是一条"链"——从客户端生成键、到入口去重、到事务一致、再到下游传递,任何一环的疏漏,都会让整个幂等防线形同虚设。做幂等,要有"端到端"的全链路视角。

第六件事:写一个关键接口时,我现在会怎么决策

现在,每当我准备写一个"会改数据"的关键接口,脑子里都会过一遍这张决策图——核心就一句:假设它一定会被重复调用

这张图的灵魂,是一个前置假设:我现在写任何会改数据的接口,都默认假设"它一定会被重复调用",而不是"它应该只来一次"。第一问:这个操作天然幂等吗?——像"设为固定值""按 id 删除"这种,本身就安全,无需额外处理;而创建、累加、扣款这种,必须做幂等设计然后按操作类型选方案:创建类用幂等键+唯一约束、状态推进用状态机 CAS、MQ 消费用去重表、表单提交用 token。再贯穿两条链路要求:幂等记录要和业务在同一事务调下游也要传递幂等键最后,也是我以前最缺的一步:并发 + 重试的测试验证——同一请求并发/重复执行多次,结果必须一致,才算真的做对了,而不是"我以为做了幂等"。

我立下的几条规矩

这场"重复下单、重复扣款"的事故,换来了我做分布式系统时,刻进骨子里的几条铁律:

  1. 默认假设请求会重复。网络不可靠+重试,让"重复"成为常态;任何会改数据的关键写操作,都要设计成"重复执行也安全"。
  2. 超时不代表失败。这是分布式第一课;对方可能已经成功了,只是响应没回来——所以重试前必须考虑幂等。
  3. 幂等优先用唯一约束,别用"先查再插"。查插之间有缝隙,并发下仍重复;唯一约束是数据库级的原子去重。
  4. 重试必须复用同一个幂等键。键一变,服务端就认不出是重复,幂等彻底失效。
  5. 按场景选方案。创建→唯一约束,状态推进→CAS,MQ→去重表,表单→token,严格串行才上分布式锁。
  6. 幂等是端到端的链路。记录与业务同事务、调下游也传键、去重表设TTL——任何一环漏了都白搭。
  7. 幂等要用并发+重试测试验证。同请求多次执行结果一致才算数,别停留在"我以为做了"。

附:用并发测试验证幂等是否真的生效

幂等做没做对,不能靠"看代码觉得没问题",要靠并发+重试的测试逼它现形。下面这段,把"怎么测幂等"具体写了出来:

// ✓ 用并发测试验证幂等: 同一个幂等键, 多线程同时打, 只能成功创建一笔
@Test
public void test_idempotent_under_concurrency() throws Exception {
    String sameKey = "idem-key-fixed-123";          // ✓ 关键: 所有线程用同一个幂等键
    OrderRequest req = sampleRequest();
    int threads = 20;
    ExecutorService pool = Executors.newFixedThreadPool(threads);
    CountDownLatch start = new CountDownLatch(1);
    List> futures = new ArrayList<>();

    for (int i = 0; i < threads; i++) {
        futures.add(pool.submit(() -> {
            start.await();                            // ✓ 所有线程卡在同一起跑线, 制造真并发
            return createOrder(req, sameKey);         // 同一个键, 并发调用
        }));
    }
    start.countDown();                                // 同时放行

    // ✓ 收集所有返回的订单
    Set orderIds = new HashSet<>();
    for (Future f : futures) orderIds.add(f.get().getId());

    // ✓ 断言1: 所有请求返回的是同一笔订单(幂等返回上次结果)
    assertEquals(1, orderIds.size());
    // ✓ 断言2: 数据库里只有一笔订单(没有重复创建)
    assertEquals(1, orderDao.countByRequest(req));
    // ✓ 断言3: 只扣了一次款
    assertEquals(req.getAmount(), getTotalCharged(req.getUserId()));
}

// 还要测"串行重试"场景:
//   连续用同一个键调 5 次, 同样断言: 1 笔订单、1 次扣款、5 次都返回同一结果。

// 核心: 幂等必须用"同键并发 + 同键重试"测试验证 ——
//   断言"只创建一笔、只扣一次款、多次返回同一结果", 而不是只看代码觉得对。

这段测试,是我现在所有"关键写接口"上线前的必过关卡它的精髓,是用 20 个线程、卡在同一条起跑线上、用同一个幂等键、同时发起调用,去人为制造出最严苛的并发;然后,用三条断言把幂等钉死:所有请求返回的是同一笔订单、数据库里只有一笔订单、款只扣了一次除了并发,还要测串行重试:用同一个键连续调 5 次,同样断言"1 笔订单、1 次扣款、5 次都返回同一结果"。这套测试的价值,在于它把"幂等"这个抽象的承诺,变成了可被机器反复验证的、铁一般的事实:幂等做没做对,不是靠"读代码觉得应该没问题"来判断的——并发的世界里,"觉得对"和"真的对"之间,隔着无数个你想不到的时序;唯有用并发和重试,亲手把它逼到极限、再用断言确认它依然正确,你才能真正放心地,把它交给那个会无情地、反复地重试你的分布式世界。

写在最后

回头看,这场由"接口不幂等"引发的、重复下单重复扣款的事故,真正教给我的,是一个比"幂等性"本身更根本的世界观转变:单机时代"我调用,它执行,要么成功要么失败,干净利落"的确定性世界,迈入分布式时代"消息会丢、会重、会乱序,超时是常态,'不知道成没成功'是日常"的不确定性世界我过去写代码的所有直觉,都建立在那个美好而脆弱的单机假设之上:网络永远通、调用必有明确结果、一次请求只处理一次。可一旦跨越了网络、走进了分布式,这些假设,统统不再成立——而幂等性,正是我们为了在这个充满了"重复"与"不确定"的新世界里活下去,所必须建立的第一道、也是最基本的一道防线。所以,做分布式系统,最重要的心态转变是:从"祈祷不出错"转向"假设一定会出错(会重复、会超时、会失败),并提前设计好:当它出错时,系统依然能保持正确"。真正健壮的分布式系统,从来不是建立在"网络可靠"的幻想之上,而是建立在"网络一定不可靠"的清醒预判,和对每一种异常的周全应对之上把"它一定会被重复调用"当成写每个关键接口时的默认前提——这,是我用一次"重复扣款"的崩溃,换来的、关于分布式架构最朴素、也最深刻的领悟。如果这篇复盘,能让你在下一次写下一个写接口之前,多问一句"它被调用两次,会怎样",那我对着那些重复数据熬的这大半天,就值了。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

我把大模型当成一个稳定的函数写进了自动化流程,结果同样的输入每次跑出的结果都不一样、测试时灵时不灵,我对着这种飘忽不定排查了大半天的复盘

2026-6-2 1:55:30

技术教程

我在 C# 里随手把异步方法写成了 async void,结果里面抛的异常我的 try-catch 怎么都抓不到、还直接把整个进程干崩了,我排查了大半天的复盘

2026-6-2 2:06:22

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索