知乎后端开发实习生一轮面经

知乎 · 后端开发实习生-研发运营 · 一面 · 2026-06

《面试题目》

  1. 自我介绍:突出项目经验和对 AI/大模型方向的兴趣
  2. Code Review(秒杀业务):给一段秒杀下单代码,找出问题
    • 库存扣减和订单创建没有做并发控制,容易超卖
    • 一人一单校验和库存校验存在竞态条件
    • @Async 异步通知如果抛异常没有兜底处理
    • 事务方法内部调用异步方法,可能导致事务还未提交就发送了通知
  3. SQL 性能分析:给出建表语句、索引和三条查询 SQL,分析每一条的性能问题(如 DATE(create_time) = '2026-06-01' 对字段做函数运算导致索引失效)

《参考解析》

  1. 秒杀超卖的并发控制方案:库存扣减需要保证原子性,常见方案是数据库层面用 UPDATE stock SET count = count - 1 WHERE id = ? AND count > 0 的条件更新(利用行锁+条件判断防止超卖),或使用 Redis 的 DECR/Lua 脚本做原子扣减,再异步落库;一人一单校验则需要配合分布式锁或数据库唯一约束(用户ID+活动ID)避免竞态条件下重复下单。
  2. 事务与异步方法调用顺序问题@Transactional 方法内部直接调用 @Async 方法时,由于 Spring 事务基于 AOP 代理,事务提交发生在方法返回之后,而异步方法可能在事务真正提交前就已经在另一个线程执行并读到未提交的数据(或发出了通知但事务后续回滚),正确做法是用 TransactionSynchronizationManager.registerSynchronization 在事务提交后的回调里触发异步逻辑,或者用事务事件监听(@TransactionalEventListener(phase = AFTER_COMMIT))。
  3. 对字段做函数运算导致索引失效WHERE DATE(create_time) = '2026-06-01' 这类写法会对索引列做函数计算,MySQL 无法直接使用 create_time 上的索引(因为索引存储的是原始值而非函数计算后的值),优化方式是改写为范围查询 WHERE create_time >= '2026-06-01 00:00:00' AND create_time < '2026-06-02 00:00:00',从而让索引正常生效。