最近在帮几个朋友做大厂模拟面试,发现一个特别普遍的现象:大家单拎出来都能聊,Spring Boot 自动装配背得滚瓜烂熟,Redis 分布式锁也能说两句,Kafka 生产端参数张口就来,Spring Security 过滤器链也看过。但只要面试官把场景串成一条完整链路——比如从"用户登录"到"下单"再到"异步通知"——就开始卡壳,互相之间的衔接、容错、数据一致性完全讲不清楚。
这其实就是大厂 Java 面试和普通面试最大的区别:不考孤立知识点,考的是你在一套 Spring Boot + Redis + Kafka + Spring Security 的真实系统里,能不能把每个环节讲透。这篇文章我就用一场面试实录的形式,把这个全链路拆开揉碎了讲一遍。整个面试的载体是一个非常接地气的项目——上门烹饪预约服务系统,你把它换成任何带订单、带用户、带消息通知的业务系统都成立。内容会尽量贴近真实面试的追问节奏,适合准备 Java 中高级岗位、或者想系统梳理中间件知识体系的朋友。
1. 面试开场:一个"全链路项目"是如何被层层深挖的
面试官上来第一句话通常是:"先介绍一个你最有代表性的项目吧。"
很多人这个时候就开始背项目流水账:我们用了 Spring Boot、Redis、Kafka、Spring Security,做了用户管理、订单管理、通知管理……听起来什么都做了,但面试官根本抓不住重点。
谢飞机的回答方式值得参考,他抛出来的是核心链路:
我做的是一个上门烹饪预约服务系统。用户通过小程序选厨师、选时段、下单支付,厨师端接单并上门服务。我主要负责的是预约下单这条核心链路:用户登录鉴权走 Spring Security + JWT,下单时先把热门时段的库存预热到 Redis 做并发控制,下单成功发出订单创建事件到 Kafka,消费端异步处理支付回调、给厨师发单、给用户发通知,再把结果回写数据库。
这几句话一出来,面试官立刻就能把整个系统的技术链路画出来,并且从每个环节往里挖。
这个项目的核心价值在于:它不是一个 CRUD 堆砌的管理系统,而是一个有并发、有异步、有安全控制的真实业务场景。预约下单天然存在热点问题——热门厨师的热门时段会被多人同时抢;也天然存在解耦需求——下单成功了不能同步等着发短信、推小程序通知;更天然需要权限控制——顾客、厨师、运营管理员三类角色看到的数据完全不一样。
所以面试官接下来的每一个问题,都可以从这条链路上延伸出去。这也是我建议大家准备项目时的一个核心思路:与其准备几十个八竿子打不着的知识点,不如把一条主链路上的技术全部吃透,让面试官顺着你的项目问,问到哪里你都能接住。
下面这场"面试实录",就是沿着这条链路逐层展开的。我按技术栈拆成四段来复盘,每一段都是面试官真实会追问的深度。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Spring Boot 层:启动、自动装配、兼容性和部署方式
2.1 自动装配的底层原理,别只说"约定大于配置"
面试官问的第一个问题往往是:"项目为什么选 Spring Boot?它的启动原理是什么?"
很多人的回答是:"因为 Spring Boot 内嵌了 Tomcat,打一个 jar 包就能跑,而且自动装配很方便。"这种回答太表面了,面试官接下来一定会追问:"自动装配到底是怎么实现的?"
完整的链路是这样的:@SpringBootApplication 是一个组合注解,它包含了 @SpringBootConfiguration、@EnableAutoConfiguration 和 @ComponentScan。其中最关键的是 @EnableAutoConfiguration,它通过 @Import(AutoConfigurationImportSelector.class) 导入一个选择器,这个选择器会去读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件(Spring Boot 2.7 之后是 spring.factories,更早版本用的是 spring.factories),把里面声明的所有自动配置类都加载进来。
注意,是"加载进来",不是"全部生效"。每个自动配置类上都有大量的条件注解,比如 @ConditionalOnClass、@ConditionalOnMissingBean、@ConditionalOnProperty。像 RedisAutoConfiguration 上就有 @ConditionalOnClass(RedisOperations.class),只有你的 classpath 里有 Redis 相关的 jar 包,这个配置类才会生效。@ConditionalOnMissingBean 的意思是,如果你自己定义了一个 RedisTemplate 的 Bean,那么自动配置的就会退位让贤,以你的为准。
这个机制最重要的意义在于:它把"配置"和"生效"解耦了。你引入一个 spring-boot-starter-data-redis,自动配置类被加载,但因为条件注解的存在,不会覆盖你已有的自定义配置。
面试中如果能答到这一层,已经超过了 80% 的候选人。如果再能补充一句"条件注解是 Spring Boot 扩展机制的核心,自定义 Starter 也是基于这个原理",那这一题就很稳了。
2.2 Springfox 3.0.0 与 Spring Boot 2.6+ 的兼容坑
这套项目里有一个很真实的坑:如果你用的是 Spring Boot 2.6 以上的版本,还继续用 Springfox 3.0.0 做 Swagger 文档,启动的时候大概率会直接抛异常,报错信息类似:
code复制java.lang.NullPointerException: Cannot invoke
"springfox.documentation.spring.web.WebMvcPatternsRequestConditionWrapper.getPatterns()"
because "this.condition" is null
这个坑的本质原因是:Spring Boot 2.6 开始,Spring MVC 的路径匹配策略从 AntPathMatcher 换成了 PathPatternParser,Springfox 3.0.0 内置的 WebMvcPatternsRequestConditionWrapper 只适配了旧的 AntPathMatcher,两者不兼容,启动时就会 NPE。
我当时实际的排查过程是这样的:项目从 Spring Boot 2.5 升到 2.6 之后,一启动就报这个 NPE,第一反应以为是 Bean 冲突,排查了半天没结果,后来去查 Spring Boot 2.6 的 release notes,才发现是路径匹配策略变更导致的破坏性更新。解决办法很简单,在 application.yml 里加一行配置:
yaml复制spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
或者更彻底一点,换掉 Springfox,迁移到 springdoc-openapi,它的底层走的不是这套匹配逻辑,性能和长期维护性都更好。面试的时候如果能把"问题现象 → 问题根因 → 解决方案 → 更优替代"讲完整,面试官会很有好感,因为这就是真实项目里踩坑和解决问题的完整闭环。
2.3 命令行运行和 Tomcat 部署的差别
这题看着基础,但真问起来能筛掉一半人。Spring Boot 项目可以用 java -jar 直接跑,是因为内置了 Tomcat,本质上就是在一个 main 方法里启动了 Spring 容
