面灵AI→

滴滴后端一面(网约车技术部):拼团库存、Redis 阻塞与限流

轮次
一面
时间
2026-10
来源
牛客网

《面试题目》

  1. 营销拼团交易项目介绍,以及项目中遇到的问题。
  2. 项目中高并发场景下库存异常的解决方案?
  3. 项目中 Redis 发生阻塞的场景?
  4. 营销拼团系统在高并发、流量脉冲下的可用性保障方案?
  5. 拼团项目里限流和线程保护相关措施?
  6. 代码题:无重复字符的最长子串。

《参考解析》

库存异常:先分类再给方案

「库存异常」在秒杀/拼团场景里通常是三种问题:超卖(卖出多于库存)、少卖(库存有货但没卖出去,常见于回滚或锁过期)、以及数据不一致(缓存与数据库对不上)。方案按层讲:入口层做限流与防重(同一用户同一活动只能参与一次,用 Redis 去重或数据库唯一索引);扣减层把库存判断与扣减做成原子操作——最稳的是数据库条件更新 update stock set num = num - 1 where id = ? and num > 0,用影响行数判断是否成功,因为只有数据库的行锁在并发下不可绕过;如果要用 Redis 扛流量,则必须用 Lua 脚本把「判断 + 扣减」打包成原子操作,并且把 Redis 当作「预扣层」、数据库作为最终账本,配一条异步落库与对账链路(Redis 扣成功而数据库失败时要有补偿,否则少卖或错账)。少卖的常见根因是「预扣了但订单超时未支付没有回补」,所以要设计超时释放(延时消息或定时扫描),并且回补要幂等(同一订单号只能回补一次)。

Redis 阻塞的典型场景

要能从「慢命令、大 key、集中失效、持久化与主从、以及网络与客户端」几个方向列举。慢命令:keys *、hgetall/smembers 操作大集合、zrange 取大范围、复杂度是 O(n) 的 Lua 脚本,单线程模型下都会把后续请求堵住。大 key 与热 key:单个 key 存了几 MB、或者某个热点 key 的 QPS 集中到一个分片,写入与网络传输都会成为瓶颈。集中失效与缓存雪崩:大批 key 同一时刻过期,请求全部回源到数据库,同时 Redis 自身也会因回源重建而压力骤增。持久化与主从:BGSAVE/AOF rewrite 的 fork 会带来内存与磁盘 IO 抖动,主从全量同步期间主节点压力上升;集群扩缩容时的 slot 迁移也会造成短暂不可用。连接层面:客户端连接池耗尽导致等待、管道与事务被大请求占满、以及阻塞式命令(BLPOP)用了过长超时。应对手段:用 scan 替代 keys、把大 key 拆分成多个小 key 或改用 Hash 分桶、对热点 key 做本地缓存与分片、过期时间加随机抖动、把持久化放到从节点或选低峰执行、监控慢查询(slowlog)与内存碎片率、并给客户端设置合理的超时与重试。

可用性保障与限流、线程保护

流量脉冲下的可用性按「入口 → 服务 → 依赖 → 数据」四层给方案。入口层:限流(按用户、接口、集群维度,令牌桶/漏桶/滑动窗口)、排队(把瞬时并发转成队列)、以及静态化与 CDN 承接读流量。服务层:无状态化以便快速扩容、把同步调用改异步(消息队列削峰)、接口降级(非核心能力直接返回兜底)、以及隔离(把秒杀/拼团这类突发业务与主链路部署隔离,避免互相拖垮)。依赖层:超时与重试(重试要加抖动与上限,避免重试风暴)、熔断(失败率超阈值直接拒绝,给下游恢复时间)、舱壁隔离(不同依赖用独立线程池,避免一个慢依赖占满所有线程)。数据层:读写分离、热点数据缓存、以及数据库层的连接数上限与慢查询保护。

「限流和线程保护」要说清实现与判据。限流算法上,固定窗口简单但有临界问题,滑动窗口更平滑,令牌桶允许突发、漏桶限制速率恒定,Guava RateLimiter、Sentinel 是常见实现;分布式限流要靠 Redis(Lua 保证原子)或专门的网关。线程保护的核心是「不让慢依赖吃光线程」:不同下游用独立线程池与独立队列(隔舱),给每个池明确的队列长度与拒绝策略,池满时按业务优先级拒绝低优先任务而不是全部阻塞;同时监控活跃线程数、队列长度、拒绝次数,这三个指标比日志更早暴露问题。还要提一句线程池与限流的关系:限流保护下游、线程池保护自己,两者要一起配才有意义。

算法:无重复字符的最长子串

滑动窗口标准解法:用左右指针维护一个不含重复字符的窗口,右指针扩张时把字符写进哈希表(记录最近出现的下标),遇到重复就把左指针跳到「该字符上次出现位置 + 1」(注意要用 max(left, lastIndex + 1),避免左指针回退),每一步更新最大长度。时间复杂度 O(n)、空间 O(字符集大小)。边界与常见错误:空串、单字符、全部字符相同、包含空格与符号(用数组代替哈希表要注意字符范围);左指针回退是最常见的 bug。可以补一句变体:如果允许最多 k 个重复字符,就把「重复」的判据换成「窗口内某字符计数大于 k」,窗口收缩条件随之改变——这是同一套滑动窗口模板的延伸。