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