小红书引擎架构Java开发一面面经

小红书 · 引擎架构Java开发工程师 · 一面 · 2026-06

《面试题目》

  1. 自我介绍
  2. 项目中短期记忆和长期记忆分别是怎么做的?知识库上传是如何实现的?
  3. Redis 的作用是什么?选型时为什么选择 Redis?它的稳定性如何?任务有持久化吗?
  4. Redis 持久化期间宕机等原因导致数据丢失怎么办?
  5. 使用 Redis 作消息队列会不会导致额外维护一个中间件?除了消息队列,还有哪些异步处理方式?
  6. 讲一下线程池的参数、工作原理和拒绝策略,用过哪些线程池?
  7. Redis 某个 Key 很大会有什么问题?为什么大 Key 会影响 Redis 性能?如何解决?
  8. 场景题:文件解析时用户突然上传大量文件导致服务器打满,该如何决策?
  9. 如何明确线程数量?如何定位哪个线程被阻塞?
  10. 对外提供的接口如何保障执行过程中的可观测性?
  11. 多个方法连续调用时,如何在无侵入的情况下通过日志查看完整调用链?AOP 的原理是什么?

《参考解析》

  1. Redis 大 Key 的危害与解决:大 Key(如超大 Hash、List、单个 Value 过大的 String)会导致单次操作耗时长阻塞主线程(Redis 单线程模型下影响尤其明显)、内存分布不均引发数据倾斜、以及主从同步/迁移时网络阻塞。解决思路是拆分大 Key(如按业务维度拆成多个小 Key)、用 SCAN 替代 KEYS 做批量处理避免阻塞、对已存在的大 Key 定期做异步拆分迁移。
  2. AOP 的实现原理:Spring AOP 基于动态代理实现——目标类实现了接口时使用 JDK 动态代理,没有实现接口时使用 CGLIB 生成子类代理;在代理对象方法执行前后织入切面逻辑(如打印调用链日志、记录耗时),从而做到业务代码无侵入。要打通完整调用链,通常会在切面里生成/透传一个 TraceId,并借助 ThreadLocal 或 MDC 把 TraceId 写入日志上下文,实现跨方法甚至跨服务的链路追踪。
  3. 线程阻塞排查思路:可以用 jstack 导出线程栈,查找处于 BLOCKED 或长时间 WAITING 状态的线程,结合线程名和堆栈定位具体阻塞点;也可以借助 Arthas 的 thread 命令实时查看 CPU 占用最高的线程和其调用栈,快速定位是锁竞争、IO 等待还是死循环导致的阻塞。