悦省 ← 返回提示词库

AI / 编程与调试

并发与竞态审阅

假设两个请求同时到达,逐条走共享状态

审查下面这段代码的并发安全。方法:假设有两个请求在同一毫秒到达,逐个走一遍共享状态。请:1)列出所有共享可变状态(内存变量、缓存、数据库行、文件);2)指出哪几处存在检查与使用之间的间隙(先查后写);3)说明在什么并发量下才会暴露,以及暴露时的现象;4)给出最小改法(锁、唯一约束、原子操作、改为幂等),并说明各自的代价。

```
[粘贴代码]
```
使用建议

低并发项目也值得跑一遍,先查后写的坑往往要等流量涨上来才炸。

适合什么场景

  • 存在「先查再写」的逻辑:库存扣减、优惠券领取、幂等下单。
  • 单机测试永远通过,多实例部署或压测后开始出现重复数据。

不适合的场景

  • 单进程、无共享状态、纯函数:没有并发问题可审。
  • 已经确认问题在数据库隔离级别或锁等待:直接看锁和事务,不必通读代码。

示例

输入
def claim_coupon(user_id, coupon_id):
    if db.exists("select 1 from claims where user_id=? and coupon_id=?", user_id, coupon_id):
        return "already"
    if db.count("select count(*) from claims where coupon_id=?", coupon_id) >= 100:
        return "sold_out"
    db.insert("claims", user_id=user_id, coupon_id=coupon_id)
    return "ok"
你会得到
共享可变状态是 claims 表和库存计数;两处 check-then-act 间隙:同一用户并发两次都能通过 exists,库存剩 99 时两个请求都能通过 count<100。暴露条件是双实例加约 10 QPS 的抢券,现象是重复领取和超发。最小改法:`(user_id, coupon_id)` 唯一约束兜底,再用一条 `INSERT ... SELECT ... WHERE count < 100` 原子写入,代价是冲突时需要重试。

常见误用

  • 只说「看看有没有并发问题」,不交代部署形态(单实例还是多实例、有没有 Redis 锁):它会把单机安全的代码判成危险。
  • 收到「加锁」建议就加进程内锁,多实例部署下等于没加。

可以这样改

  • 加「假设 3 个实例、无共享缓存」,它才会把进程内变量也算作共享状态。
  • 要求「给出能稳定复现的压测脚本思路(并发数、请求顺序)」,抽象风险就变成可验证实验。

同方向的其他提示词