面灵AI

美团后端开发岗面经(02)

时间
2026-09
来源
牛客网

《面试题目》

  1. String、StringBuffer 和 StringBuilder 有什么区别?
  2. 双亲委派模型的目的是什么,什么情况下会被打破?
  3. Java 反射的原理和应用场景是什么?
  4. 线程池核心线程数应该如何设置?
  5. MySQL 常用存储引擎有什么区别?
  6. 缓存穿透、缓存击穿和缓存雪崩分别是什么?
  7. 令牌桶为什么用 Lua 实现,如何保证原子性?
  8. 高并发优惠券秒杀如何避免超卖?
  9. Agent 的循环流程是什么,如何评估 RAG 知识库的准确率?
  10. 账户互相转账时如何避免死锁?
  11. Kafka 消费失败后会发生什么,应该如何处理?
  12. RPC 服务注册与发现是如何实现的?

《参考解析》

  1. String 不可变,适合常量和共享;StringBuffer 方法同步,适合需要线程安全的拼接;StringBuilder 不同步,单线程下通常性能更好。大量循环拼接应优先使用可变缓冲区。
  2. 双亲委派让类加载器先请求父加载器,避免核心类被重复定义或篡改。模块化容器、线程上下文类加载器和 SPI 等场景会采用有边界的打破方式。
  3. 反射通过 Class 元数据查找构造器、字段和方法,并在运行时访问或调用。它带来灵活性但有性能、可见性和类型安全成本,应把高频路径缓存起来。
  4. CPU 密集任务通常接近 CPU 核数,IO 密集任务可适当放大,但必须结合队列长度、下游吞吐和压测结果。核心线程不是越多越好,还需限制最大线程和拒绝策略。
  5. InnoDB 支持事务、行锁和崩溃恢复,是常用默认引擎;MyISAM 以表锁和读性能见长但不支持事务。选择要基于一致性、并发写和恢复需求。
  6. 穿透是请求不存在的数据,击穿是热点 key 失效瞬间的并发回源,雪崩是大量 key 同时失效或缓存整体不可用。可分别用空值/Bloom Filter、互斥重建和过期时间抖动与多级缓存处理。
  7. Lua 脚本在 Redis 单线程执行,能把令牌检查与扣减放在一个原子操作中。脚本要控制执行时间,并对超时、限流维度和返回值做好约定。
  8. 库存扣减必须带条件并保证原子性,成功后再异步创建订单;订单和领券请求使用幂等键,失败消息可重试或补偿,不能只靠前端按钮禁用。
  9. Agent 通常经历规划、调用工具、观察结果和继续决策,直到满足终止条件。RAG 应用命中率、召回率、答案正确性和引用完整性等离线指标评估,不能凭主观感觉。
  10. 对账户按固定顺序加锁,或用数据库条件更新替代长事务锁持有,可避免循环等待。超时和回滚要记录,不能把死锁异常静默吞掉。
  11. 消费失败时应依据错误类型选择重试、死信或人工补偿;提交 offset 要和业务处理语义匹配,并用业务唯一键保证重复消费不会重复扣款。
  12. 服务启动时向注册中心登记地址与健康状态,客户端订阅变化并按负载策略选择实例。租约过期、网络分区和版本兼容都要有明确处理。