面灵AI→

字节腾讯快手等后端与 AI 全栈高频 12 题汇总:Redis 锁与 RAG

时间
2026-10
来源
牛客网

《面试题目》

八股

  1. Redis 分布式锁:用 SET NX EX 加锁,释放为什么常用 Lua 脚本?
  2. MySQL 索引:B+ 树的结构、联合索引的最左前缀,索引是不是越多越好?
  3. 事务隔离级别有哪些?脏读与幻读分别指什么?redo log 与 binlog 的两阶段提交解决什么问题?
  4. TCP 与 UDP 有什么区别?三次握手与四次挥手的过程是怎样的?
  5. HTTP 与 HTTPS 有什么区别?TLS 的大致链路是怎样的?
  6. 进程、线程、协程有什么区别?(Go 岗常接着问 GMP)
  7. Go:GMP 调度模型、slice 扩容、WaitGroup 分别是什么机制?
  8. 缓存穿透、击穿、雪崩分别指什么,各自怎么解决?

系统与项目

  1. 接口幂等怎么保证?用 requestId 去重,重试会不会重复扣款?
  2. 缓存和数据库如何保持一致?
  3. RAG 的全流程是怎样的?幻觉怎么压制?
  4. Agent:Function Calling 怎么用,短期与长期记忆怎么存,token 成本怎么控?

手撕

  1. 反转链表。
  2. Top-K。
  3. 不超过 N 的最大数。

《参考解析》

Redis 分布式锁:正确性全在释放和续期两处 SET NX EX 一次原子地完成「不存在才写」与「带过期」,value 必须放只有自己知道的随机值。释放不能先 GET 再 DEL——两步之间锁可能刚好过期被别人拿走,你删的就成了别人的锁;用 Lua 让「比较 value 再删除」在 Redis 单线程里原子执行,这才是脚本存在的理由。剩下的漏洞是业务执行超过 ttl:锁已自动释放,需要看门狗续期,同时业务侧要有幂等兜底。多实例场景里,写存储时带上单调递增的 fencing token 做校验,比堆 Redlock 更实在。

MySQL 索引:B+ 树为磁盘而设计,最左前缀由排序决定 B+ 树把数据全放在叶子、叶子之间用链表串联,非叶节点只存键,扇出大、树高小,一次点查只需少量磁盘页,范围扫描顺着叶子链表走即可,这是它胜过哈希与二叉搜索树的地方。联合索引 (a,b,c) 的排序是先 a 再 b 再 c,所以条件必须从最左列开始且连续才能用上;a=1 and c=3 用不到 c 的定位,但仍可能走覆盖索引。索引不是越多越好:每个索引都要在写入时维护、占空间、放大写开销,还会让优化器选错计划,原则是按查询建、优先做覆盖。

缓存一致性:先讲读写比,再谈方案 主流是 Cache Aside:读先查缓存、miss 再读库回填;写先更库再删缓存(不要更新缓存,并发写会让旧值覆盖新值)。删缓存失败或主从延迟时,用延迟双删或订阅 binlog 异步失效,并诚实说明强一致做不到、只能收敛不一致窗口。三个异常要分清:穿透查的是不存在的键,用空值缓存或布隆过滤器;击穿是热点键过期瞬间打穿,用逻辑过期或互斥重建;雪崩是大量键同时失效,给过期时间加随机抖动并做多级缓存。

幂等:先定义「什么算同一请求」 幂等的前提是一个业务唯一键,requestId 只是它的载体:客户端生成、服务端落去重表并建唯一索引,插入成功才继续,冲突就直接返回上次结果。第二道闸是状态机:支付单只允许从「待支付」跳到「已支付」,更新时带 where status 条件、判断影响行数。重试会不会重复扣款,取决于扣款动作有没有被同一个键罩住——去重在上游、扣款在下游时,中间失败照样重复,所以要么下游也带同一个键,要么用业务单据号做对账补偿。

RAG 与 Agent:幻觉和成本都要落到可测的指标 RAG 的链路是切分 → 向量化入库 → 查询改写 → 召回 top-k → 重排 → 拼上下文 → 带引用生成。压幻觉按性价比排:先提召回质量(切分粒度、混合检索、重排),再在提示里要求只依据给定片段作答、无依据就说不知道,输出带出处便于核验,最后用带标注的评测集算命中率与忠实度,别靠体感。Agent 侧三件事:工具描述写清入参与何时调用;短期记忆是对话窗口,长期记忆按用户维度存事实并按需召回;token 成本靠上下文裁剪、工具结果截断、前缀缓存与限制最大轮次控制。