面灵AI

Java小厂后端面经(转Go方向)

轮次
一面
base
福建
时间
2026-06
来源
牛客网

《面试题目》

  1. 明确说明需要转 Go,能不能接受?
  2. 自我介绍。
  3. 项目介绍。
  4. 对项目进行拷打。
  5. 说明三级缓存架构设计,回答的是缓存穿透、击穿、雪崩。
  6. Redis 中缓存了哪些数据,用的什么数据结构,为什么用这个?
  7. 秒杀系统的流程是什么?
  8. 下单信息怎么返回给用户?
  9. 使用了消息队列,独立的线程获取消息后实现了什么?
  10. 刚下完单,订单信息还在消息队列中未写入数据库时,怎么通过订单 ID 查询订单信息?
  11. 生成订单到写 MySQL 的过程中一致性和性能怎么取舍?
  12. 对 MySQL 的理解,追问为什么主键使用 int,说一下最左前缀法则,解释为什么 like %xxx 会产生索引失效。
  13. 使用过多线程吗?
  14. 简单说一下 CAS 机制。

《参考解析》

1. 三级缓存与穿透/击穿/雪崩

三级缓存通常指本地缓存(Caffeine)+ 分布式缓存(Redis)+ 数据库,逐层兜底。缓存穿透(查询不存在的数据)用布隆过滤器或缓存空值防御;缓存击穿(单个热点 key 过期瞬间高并发)用互斥锁重建或逻辑过期;缓存雪崩(大量 key 同时过期)用过期时间加随机抖动 + 多级缓存分散压力。

2. 秒杀系统流程与一致性取舍

典型流程:请求先到网关限流 → Redis 预扣库存(Lua 脚本保证原子性)→ 库存够则异步发 MQ 下单消息 → 消费者落库生成订单 → 返回用户排队中/已下单。下单瞬间数据库未必已写入,前端轮询订单状态接口,后端可先用 Redis 记录「订单已受理」状态供查询,DB 写入完成后再更新为最终状态,本质是用最终一致性换取秒杀峰值下的高吞吐。

3. MySQL 主键用 int 与最左前缀法则

主键建议用自增 int/bigint 而非 UUID,因为 InnoDB 聚簇索引按主键物理排序存储,自增主键保证顺序插入、减少页分裂,UUID 随机写入会导致频繁页分裂、索引膨胀。最左前缀法则:联合索引 (a,b,c) 只有从最左列 a 开始连续匹配的查询条件才能用上索引,跳过 a 直接查 b 则索引失效。like '%xxx'(前置通配符)无法利用 B+ 树索引的有序性做范围扫描,因此索引失效;like 'xxx%'(后置通配符)仍可命中索引。

4. CAS 机制

CAS(Compare And Swap)是一种无锁并发原语,包含内存值、预期值、新值三个参数,仅当内存值等于预期值时才更新为新值,否则失败重试(自旋)。Java 中 AtomicInteger 等原子类基于 CAS + Unsafe 类的硬件级 CMPXCHG 指令实现,避免了 synchronized 的线程阻塞开销,但存在 ABA 问题(可用版本号/AtomicStampedReference 解决)和高并发下自旋空转的 CPU 开销问题。