Java大厂面试真题:Spring Boot + 微服务 + 缓存架构三轮技术拷问实录
第一轮:基础框架与编码能力(电商场景衔接)
面试官:你好,谢飞机,欢迎参加我们公司的Java开发岗位面试。先简单介绍一下你自己吧。
谢飞机:您好!我叫谢飞机,三年Java经验,熟悉Spring Boot、MySQL和Redis,做过电商平台的订单模块,也用过Kafka做异步通知。
面试官:不错。那我们先从基础开始——请解释一下JVM内存模型的主要组成部分?堆和栈的区别是什么?
谢飞机:嗯……堆是放对象的地方,所有线程共享;栈是每个线程私有的,用来执行方法调用。堆大,栈小,栈满了会StackOverflowError,堆满了就是OutOfMemoryError。
面试官(微笑):回答得很清晰!继续——Spring Boot是如何实现自动配置的?
谢飞机:靠@SpringBootApplication注解,里面有个@EnableAutoConfiguration,它会去读META-INF/spring/org.springframework.boot.autoconfigure.imports文件里的配置类,然后根据条件比如@ConditionalOnClass来决定要不要加载。
面试官:很好!那如果我要自定义一个Starter,该怎么写?
谢飞机:新建个Maven项目,引入spring-boot-autoconfigure,写一个配置类加上条件注解,最后在imports文件里注册就行。
面试官:不错,跟上了版本变化。接下来——你们项目里用Redis缓存商品信息,怎么避免缓存穿透?
谢飞机:可以用布隆过滤器预判key是否存在,或者缓存空值并设置短过期时间。
面试官:如果发生缓存雪崩呢?
谢飞机:给不同的key设置随机过期时间,比如8小时±1小时;还可以用多级缓存+限流降级机制。
面试官:很好,思路正确。最后一个问题——Maven和Gradle有什么区别?
谢飞机:Maven用XML,结构固定但啰嗦;Gradle用Groovy或Kotlin DSL,更灵活,构建速度快,适合复杂项目。
面试官:非常准确,加分项!第一轮表现不错。
第二轮:业务设计与系统架构(内容社区UGC场景延伸)
面试官:现在假设我们要做一个内容社区平台,用户可以发布图文、视频等内容,支持高并发读取。你会如何设计后端架构?
谢飞机:我会用Spring Boot拆成多个微服务,比如用户服务、内容服务、评论服务,用Nacos做注册中心,Feign调用,Redis缓存热点内容,MySQL分库分表存数据。
面试官:合理。那具体说说Redis在高并发下的应用场景?如何防止缓存击穿?
谢飞机:呃……缓存击穿?是不是某个热点key失效了,大量请求打到数据库?
面试官:对,那你怎么办?
谢飞机:可以加互斥锁,让一个线程去查数据库,其他等着;或者提前刷新缓存……
面试官:不错。那如果用户上传视频,你怎么保证上传过程可靠?
谢飞机:前端直传OSS,返回URL;然后发消息到RabbitMQ,异步处理转码、封面提取、审核这些任务。
面试官:很好,这正是我们系统的做法。继续——服务之间怎么鉴权?
谢飞机:我们用JWT,在网关统一校验token。
面试官:JWT有哪些安全风险?
谢飞机:啊?不是挺安全的吗……
面试官:比如无法主动注销、容易被盗用、缺乏刷新机制。有没有考虑结合OAuth2?
谢飞机:这个……我们项目比较简单,就没搞那么复杂……
面试官(点头):理解。第二轮整体不错,但安全方面还有提升空间。
第三轮:复杂问题与性能调优(智慧医疗场景压轴)
面试官:现在系统出现接口响应慢,平均RT 800ms,高峰期超1秒,你如何排查?
谢飞机:先看监控,比如Prometheus查QPS和RT趋势,再看日志有没有异常,然后用Arthas看看哪个方法耗时长……
面试官:如果发现是数据库慢查询导致的呢?
谢飞机:用EXPLAIN分析SQL执行计划,看有没有走索引,字段是否合适,要不要加联合索引……
面试官:如果表数据量很大,已经分库分表了,但某些查询还是慢?
谢飞机:呃……可能得建ES副本来做搜索?或者用缓存?
面试官:对,引入Elasticsearch做读写分离。最后一个问题——分布式事务怎么保证一致性?
谢飞机:嗯……可以用Seata?或者本地消息表?
面试官:具体说说本地消息表?
谢飞机:就是在业务表旁边加个消息表,事务一起提交,然后有个定时任务不断往外发消息……
面试官:基本正确。不过要注意幂等性和重试策略。
面试官:今天的面试就到这里。你基础扎实,对主流技术有了解,但在深度和细节上还需要加强。回去等通知吧,我们会尽快反馈。
📘 面试问题详解与知识点总结
1. JVM内存模型与堆栈区别
- 堆(Heap):存放对象实例,所有线程共享,GC主要区域。
- 栈(Stack):每个线程独立,存储局部变量、方法调用信息,方法执行完自动释放。
- 常见异常:
OutOfMemoryError(堆满)、StackOverflowError(栈溢出)。
2. Spring Boot自动配置原理
@EnableAutoConfiguration→ 扫描META-INF/spring/org.springframework.boot.autoconfigure.imports- 使用
@Conditional系列注解按条件加载Bean。 - 自定义Starter需提供自动配置类并注册到
imports文件中。
3. Redis缓存三大问题及解决方案
| 问题 | 描述 | 解决方案 | |------|------|----------| | 缓存穿透 | 查询不存在的数据,绕过缓存 | 布隆过滤器、缓存空值 | | 缓存击穿 | 热点key失效瞬间大量请求击中DB | 互斥锁、永不过期 | | 缓存雪崩 | 大量key同时失效 | 随机过期时间、多级缓存、集群部署 |
4. 微服务架构设计要点
- 服务拆分:按业务边界划分(用户、内容、订单等)。
- 服务通信:REST + OpenFeign 或 gRPC。
- 注册中心:Nacos / Eureka / Consul。
- 配置管理:Nacos Config 或 Spring Cloud Config。
5. 高并发场景优化策略
- 缓存:Redis + Caffeine 多级缓存。
- 异步化:RabbitMQ/Kafka处理非核心链路(如审核、通知)。
- 数据库优化:索引优化、分库分表、读写分离、ES辅助查询。
- 监控体系:Prometheus + Grafana + ELK + SkyWalking。
6. 分布式事务方案对比
| 方案 | 特点 | 适用场景 | |------|------|----------| | 本地消息表 | 最终一致性,实现简单 | 异步解耦、非强一致 | | Seata AT模式 | 强一致性,依赖全局锁 | 订单创建、支付流程 | | Saga模式 | 长事务补偿机制 | 跨服务复杂流程 | | TCC模式 | Try-Confirm-Cancel,高性能 | 金融交易、库存扣减 |
💡 学习建议:作为Java开发者,不仅要会“用”框架,更要懂“为什么这么设计”。建议深入阅读《Spring源码深度解析》《阿里巴巴Java开发手册》《数据密集型应用系统设计》,并通过开源项目实践提升架构思维。
