面渣逆袭Spring篇V2.0亮白版
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
前⾔ No. 1 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
前⾔
3.3 万字 180 张⼿绘图,详解 41 道 Spring ⾯试⾼频题(让天下没有难背的⼋股),⾯渣背会这些 Spring ⼋股
⽂,这次吊打⾯试官,我觉得稳了(⼿动 dog)。整理:沉默王⼆,戳转载链接,作者:三分恶,戳原⽂链接。
亮⽩版本更适合拿出来打印,这也是很多学⽣党喜欢的⽅式,打印出来背诵的效率会更⾼。
2025 年 06 ⽉ 15 ⽇开始着⼿第⼆版更新,历经两个⽉,主要是中间有段时间把精⼒放到了派聪明 RAG 这个项⽬
的教程撰写上,第⼆版,我们升级了很多内容。
对于⾼频题,会标注在《Java ⾯试指南(付费)》中出现的位置,哪家公司,原题是什么,并且会加 ,⽬
录⼀⽬了然;如果你想节省时间的话,可以优先背诵这些题⽬,尽快做到知彼知⼰,百战不殆。
区分⼋股精华回答版本和原理底层解释,让⼤家知其然知其所以然,同时⼜能做到⾯试时的⾼效回答。
结合项⽬(技术派、pmhub)来组织语⾔,让⾯试官最⼤程度感受到你的诚意,⽽不是机械化的背诵。
修复第⼀版中出现的问题,包括球友们的私信反馈,⽹站留⾔区的评论,以及 GitHub 仓库中的 issue,让这
份⾯试指南更加完善。
增加⼆哥编程星球的球友们拿到的⼀些 offer,对⾯渣逆袭的感谢,以及对简历修改的⼀些认可,以此来激励
⼤家,给⼤家更多信⼼。
优化排版,增加⼿绘图,重新组织答案,使其更加⼝语化,从⽽更贴近⾯试官的预期。
No. 2 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
码,关注⼆哥的公众号,回复【222】即可拉取最新版本。
当然了,请允许我的⼀点点私⼼,那就是星球的 PDF 版本会⽐公众号早⼀个⽉时间,毕竟星球⽤户都付费过了,
我有必要让他们先享受到⼀点点福利。相信⼤家也都能理解,毕竟在线版是免费的,CDN、服务器、域名、OSS
等等都是需要成本的。
更别说我付出的时间和精⼒了,⼤家觉得有帮助还请给个⼝碑,让你身边的同事、同学都能受益到。
No. 3 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
我把⼆哥的 Java 进阶之路、JVM 进阶之路、并发编程进阶之路,以及所有⾯渣逆袭的版本都放进来了,涵盖 Java
基础、Java集合、Java并发、JVM、Spring、MyBatis、计算机⽹络、操作系统、MySQL、Redis、RocketMQ、分
布式、微服务、设计模式、Linux 等 16 个⼤的主题,共有 40 多万字,2000+张⼿绘图,可以说是诚意满满。
展示⼀下暗⿊版本的 PDF 吧,排版清晰,字体优雅,更加适合夜服,晚上看会更舒服⼀点。
No. 4 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
基础
1.Spring是什么?
Spring 是⼀个 Java 后端开发框架,其最核⼼的作⽤是帮我们管理 Java 对象。
No. 5 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
其最重要的特性就是 IoC,也就是控制反转。以前我们要使⽤⼀个对象时,都要⾃⼰先 new 出来。但有了 Spring
之后,我们只需要告诉 Spring 我们需要什么对象,它就会⾃动帮我们创建好并注⼊到 Spring 容器当中。
⽐如我在⼀个 Service 类⾥需要⽤到 Dao 对象,只需要加个 @Autowired 注解,Spring 就会⾃动把 Dao 对象注
⼊到 Spring 容器当中,这样就不需要我们⼿动去管理这些对象之间的依赖关系了。
另外,Spring 还提供了 AOP,也就是⾯向切⾯编程,在我们需要做⼀些通⽤功能的时候特别有⽤,⽐如说⽇志记
录、权限校验、事务管理这些,我们不⽤在每个⽅法⾥都写重复的代码,直接⽤ AOP 就能统⼀处理。
Spring 的⽣态也特别丰富,像 Spring Boot 能让我们快速搭建项⽬,Spring MVC 能帮我们处理 web 请求,
Spring Data 能帮我们简化数据库操作,Spring Cloud 能帮我们做微服务架构等等。
Spring有哪些特性?
No. 6 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
Spring 的特性还是挺多的,我按照在实际⼯作/学习中⽤得最多的⼏个来说吧。
⾸先最核⼼的就是 IoC 控制反转和 DI 依赖注⼊。这个我前⾯也提到了,就是 Spring 能帮我们管理对象的创建和依
赖关系。
⽐如我写⼀个 UserService,需要⽤到 UserDao,以前得⾃⼰ new ⼀个 UserDao 出来,现在只要在 UserService
上加个 @Service 注解,在 UserDao 字段上加个 @Autowired ,Spring 就会⾃动帮我们处理好这些依赖关系。
这样代码的耦合度就⼤⼤降低了,测试的时候也更容易 mock。
第⼆个就是 AOP ⾯向切⾯编程。这个在我们处理⼀些横切关注点的时候特别有⽤,⽐如说我们要给某些
Controller ⽅法都加上权限控制,如果没有 AOP 的话,每个⽅法都要写⼀遍加权代码,维护起来很麻烦。
No. 7 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
⽤了 AOP 之后,我们只需要写⼀个切⾯类,定义好切点和通知,就能统⼀处理了。事务管理也是同样的道理,加
个 @Transactional 注解就搞定了。
还有就是 Spring 对各种企业级功能的集成⽀持也特别好。⽐如数据库访问,不管我们⽤ JDBC、MyBatis-Plus 还
是 Hibernate,Spring 都能很好地集成。消息队列、缓存、安全认证这些, Spring 都有对应的模块来⽀持。
No. 8 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
另外 Spring 的配置也很灵活,既⽀持 XML 配置,也⽀持注解配置,现在我们基本都⽤注解了,写起来更简洁。
Spring Boot 出来之后就更⽅便了,约定⼤于配置,很多东⻄都是开箱即⽤的。
简单说⼀下什么是AOP和IoC?
AOP ⾯向切⾯编程,简单点说就是把⼀些通⽤的功能从业务代码⾥抽取出来,统⼀处理。⽐如说技术派中的
@MdcDot 注解的作⽤是配合 AOP 在⽇志中加⼊ MDC 信息,⽅便进⾏⽇志追踪。
No. 9 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
IoC 控制反转是⼀种设计思想,它的主要作⽤是将对象的创建和对象之间的调⽤过程交给 Spring 容器来管理。⽐
如说在技术派项⽬当中, @PostConstruct 注解表明这个⽅法由 Spring 容器在 Bean 初始化完成后⾃动调⽤,我
们不需要⼿动调⽤ init ⽅法。
Spring源码看过吗?
No. 10 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
看过⼀些,主要是带着问题去看的,⽐如遇到⼀些技术难点或者想深⼊理解某个功能的时候。
我重点看过的是 IoC 容器的初始化过程,特别是 ApplicationContext 的启动流程。从 refresh() ⽅法开始,包
括 Bean 的定义和加载、Bean ⼯⼚的准备、Bean 的实例化和初始化这些关键步骤。
看源码的时候发现 Spring ⽤了很多设计模式,⽐如⼯⼚模式、单例模式、模板⽅法模式等等,这对我平时写代码
也很有启发。
还有就是 Spring 的 Bean ⽣命周期,从 BeanDefinition 的创建到 Bean 的实例化、属性注⼊、初始化回调,再到
最后的销毁,整个过程还是挺复杂的。看了源码之后对 @PostConstruct 、 @PreDestroy 这些注解的执⾏时机就
更清楚了。
不过说实话,Spring 的源码确实⽐较难啃,涉及的概念和技术点太多了。我⼀般是结合⼀些技术博客和 Claude ⼀
起看,这样理解起来会相对容易⼀些。
PS:关于这份⼩册的 PDF 版本,⽬前只有星球的⽤户可以获取,后续会考虑开放给⼤家。
No. 11 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
1. Java ⾯试指南(付费)收录的京东⾯经同学 5 Java 后端技术⼀⾯⾯试原题:IOC与AOP
memo:2025 年 6 ⽉ 15 ⽇修改⾄此,今天在帮球友们修改简历的时候,碰到⼀个中⼭⼤学本硕的球友,校园荣
誉基本上拉满了,⾮常优秀,那我也希望能够帮助到更多的球友们,帮他们拿到更好的 offer。
2.Spring有哪些模块呢?
我按照平时⼯作/学习中接触的频率来说⼀下。
⾸先是 Spring Core 模块,这是整个 Spring 框架的基础,包含了 IoC 容器和依赖注⼊等核⼼功能。还有 Spring
Beans 模块,负责 Bean 的配置和管理。这两个模块基本上是其他所有模块的基础,不管⽤ Spring 的哪个功能都
会⽤到。
No. 12 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
然后是 Spring Context 上下⽂模块,它在 Core 的基础上提供了更多企业级的功能,⽐如国际化、事件传播、资源
加载这些。ApplicationContext 就是在这个模块⾥⾯的。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// Spring Boot会⾃动创建ApplicationContext
ApplicationContext context = SpringApplication.run(Application.class, args);
}
}
Spring AOP 模块提供了⾯向切⾯编程的⽀持,我们⽤的 @Transactional 、⾃定义切⾯这些都是基于这个模块。
Web 开发⽅⾯,Spring Web 模块提供了基础的 Web 功能,Spring WebMVC 就是我们常⽤的 MVC 框架,⽤来处
理 HTTP 请求和响应。现在还有 Spring WebFlux,⽀持响应式编程。
⽐如说技术派项⽬中, GlobalExceptionHandler 类就使⽤了 @RestControllerAdvice 来实现统⼀的异常处
理。
No. 13 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = ForumAdviceException.class)
public ResVo<String> handleForumAdviceException(ForumAdviceException e) {
return ResVo.fail(e.getStatus());
}
}
数据访问⽅⾯,Spring JDBC 简化了 JDBC 的使⽤,在技术派项⽬中,我们就 JdbcTemplate 来检查表是否存在、
执⾏数据库初始化脚本。
Spring ORM 提供了对 MyBatis-Plus 等 ORM 框架的集成⽀持。在技术派项⽬中,我们就⽤了 @TableName 、
@TableField 等注解进⾏对象关系映射,通过继承 BaseMapper 来获取通⽤的 CRUD 能⼒。
No. 14 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
Spring Test 模块提供了测试⽀持,可以很⽅便地进⾏单元测试和集成测试。我们写测试⽤例的时候经常⽤
@SpringBootTest 这些注解。⽐如说在技术派项⽬中,我们就⽤ @SpringBootTest 注解来加载 Spring 上下
⽂,进⾏集成测试。
@Slf4j
@SpringBootTest(classes = QuickForumApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class BasicTest {
}
还有⼀些其他的模块,⽐如 Spring Security 负责安全认证,Spring Batch 处理批处理任务等等。
现在我们基本都是⽤ Spring Boot 来开发,它把这些模块都整合好了,⽤起来更⽅便。
No. 15 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
memo:2025 年 6 ⽉ 16 ⽇修改⾄此,今天在帮球友们修改简历的时候,碰到⼀个⼤连海事⼤学硕河南理⼯⼤学
本的球友,他荣誉奖项⾥提到的优秀研究⽣、奖学⾦、英语四六级,我希望看到的同学也都能争取⼀下,不要把这
些荣誉拱⼿让⼈,或者压根就不知道,或者不屑于去参加,到时候你简历上这⼀栏就会⽐较苍⽩。
3.Spring有哪些常⽤注解呢?
Spring 的注解挺多的,我按照不同的功能分类来说⼀下平时⽤得最多的那些。
⾸先是 Bean 管理相关的注解。 @Component 是最基础的,⽤来标识⼀个类是 Spring 组件。像 @Service 、
@Repository 、 @Controller 这些都是 @Component 的特化版本,分别⽤在服务层、数据访问层和控制器层。
No. 16 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
依赖注⼊⽅⾯, @Autowired 是⽤得最多的,可以标注在字段、setter ⽅法或者构造⽅法上。 @Qualifier 在有多
个同类型 Bean 的时候⽤来指定具体注⼊哪⼀个。 @Resource 和 @Autowired 功能差不多,不过它是按名称注⼊
的。
No. 17 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
配置相关的注解也很常⽤。 @Configuration 标识配置类, @Bean ⽤来定义 Bean, @Value ⽤来注⼊配置⽂件
中的属性值。我们项⽬⾥的数据库连接信息、Redis 配置这些都是⽤ @Value 来注⼊的。 @PropertySource ⽤来
指定配置⽂件的位置。
No. 18 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
Web 开发的注解就更多了。 @RestController 相当于 @Controller 加 @ResponseBody ,⽤来做 RESTful 接
⼝。
No. 19 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
@RequestMapping 及其变体 @GetMapping 、 @PostMapping 、 @PutMapping 、 @DeleteMapping ⽤来映射
HTTP 请求。 @PathVariable 获取路径参数, @RequestParam 获取请求参数, @RequestBody 接收 JSON 数
据。
AOP 相关的注解, @Aspect 定义切⾯, @Pointcut 定义切点, @Before 、 @After 、 @Around 这些定义通知类
型。
不过我们⽤得最多的还是 @Transactional ,基本上 Service 层需要保证事务原⼦性的⽅法都会加上这个注解。
⽣命周期相关的, @PostConstruct 在 Bean 初始化后执⾏, @PreDestroy 在 Bean 销毁前执⾏。测试的时候
@SpringBootTest 也经常⽤到。
No. 20 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
还有⼀些 Spring Boot 特有的注解,⽐如 @SpringBootApplication 这个启动类注解,
@ConditionalOnProperty 做条件装配, @EnableAutoConfiguration 开启⾃动配置等等。
1. Java ⾯试指南(付费)收录的微众银⾏同学 1 Java 后端⼀⾯的原题:说说 Spring 常⻅的注解?
No. 21 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
memo:2025 年 6 ⽉ 17 ⽇修改⾄此,今天在帮球友们修改简历的时候,碰到⼀个学院本的球友,他的荣誉奖项
还是 OK的,态度也⾮常好,之前有学院本球友拿到滴滴 SP offer 的,希望这位球友也能够成为星球⾥新的榜样。
4. Spring⽤了哪些设计模式?
Spring 框架⾥⾯确实⽤了很多设计模式,我从平时⼯作中能观察到的⼏个来说说。
⾸先是⼯⼚模式,这个在 Spring ⾥⽤得⾮常多。BeanFactory 就是⼀个典型的⼯⼚,它负责创建和管理所有的
Bean 对象。我们平时⽤的 ApplicationContext 其实也是 BeanFactory 的⼀个实现。当我们通过 @Autowired 获
取⼀个 Bean 的时候,底层就是通过⼯⼚模式来创建和获取对象的。
No. 22 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
单例模式也是 Spring 的默认⾏为。默认情况下,Spring 容器中的 Bean 都是单例的,整个应⽤中只会有⼀个实
例。这样可以节省内存,提⾼性能。当然我们也可以通过 @Scope 注解来改变 Bean 的作⽤域,⽐如设置为
prototype 就是每次获取都创建新实例。
No. 23 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
代理模式在 AOP 中⽤得特别多。Spring AOP 的底层实现就是基于动态代理的,对于实现了接⼝的类⽤ JDK 动态代
理,没有实现接⼝的类⽤ CGLIB 代理。⽐如我们⽤ @Transactional 注解的时候,Spring 会为我们的类创建⼀个
代理对象,在⽅法执⾏前后添加事务处理逻辑。
模板⽅法模式在 Spring ⾥也很常⻅,⽐如 JdbcTemplate。它定义了数据库操作的基本流程:获取连接、执⾏
SQL、处理结果、关闭连接,但是具体的 SQL 语句和结果处理逻辑由我们来实现。
No. 24 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
观察者模式在 Spring 的事件机制中有所体现。我们可以通过 ApplicationEvent 和 ApplicationListener 来实现事
件的发布和监听。⽐如⽤户注册成功后,我们可以发布⼀个⽤户注册事件,然后有多个监听器来处理后续的业务逻
辑,⽐如发送邮件、记录⽇志等。
No. 25 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
这些设计模式的应⽤让 Spring 框架既灵活⼜强⼤,也让我在实际的开发中学到很多经典的设计思想。
Spring如何实现单例模式?
传统的单例模式是在类的内部控制只能创建⼀个实例,⽐如⽤ private 构造⽅法加 static getInstance() 这种
⽅式。但是 Spring 的单例是容器级别的,同⼀个 Bean 在整个 Spring 容器中只会有⼀个实例。
具体的实现机制是这样的:Spring 在启动的时候会把所有的 Bean 定义信息加载进来,然后在
DefaultSingletonBeanRegistry 这个类⾥⾯维护了⼀个叫 singletonObjects 的 ConcurrentHashMap,这个 Map
就是⽤来存储单例 Bean 的。key 是 Bean 的名称,value 就是 Bean 的实例对象。
No. 26 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
当我们第⼀次获取某个 Bean 的时候,Spring 会先检查 singletonObjects 这个 Map ⾥⾯有没有这个 Bean,如果
没有就会创建⼀个新的实例,然后放到 Map ⾥⾯。后⾯再获取同⼀个 Bean 的时候,直接从 Map ⾥⾯取就⾏了,
这样就保证了单例。
No. 27 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
还有⼀个细节就是 Spring 为了解决循环依赖的问题,还⽤了三级缓存。除了 singletonObjects 这个⼀级缓存,还
有 earlySingletonObjects ⼆级缓存和 singletonFactories 三级缓存。这样即使有循环依赖,Spring 也能正确处
理。
⽽且 Spring 的单例是线程安全的,因为⽤的是 ConcurrentHashMap,多线程访问不会有问题。
1. Java ⾯试指南(付费)收录的携程⾯经同学 10 Java 暑期实习⼀⾯⾯试原题:Spring IoC 的设计模式,
AOP 的设计模式
2. Java ⾯试指南(付费)收录的⼩公司⾯经合集同学 1 Java 后端⾯试原题:Spring 框架使⽤到的设计模
式?
3. Java ⾯试指南(付费)收录的同学 1 ⻉壳找房后端技术⼀⾯⾯试原题:Spring⽤了什么设计模式?
4. Java ⾯试指南(付费)收录的快⼿同学 4 ⼀⾯原题:Spring中使⽤了哪些设计模式,以其中⼀种模式举
例说明?Spring如何实现单例模式?
memo:2025 年 6 ⽉ 20 ⽇修改⾄此,今天帮球友修改简历的时候,有碰到重庆邮电⼤学本,电⼦科技⼤学硕的
球友,期间还有过清华⼤学科研项⽬的经历,基本上也是把学历这块拉的满中满了,那希望星球能帮助到更多院校
的同学,不管是⼯作党还是学⽣党,都希望⼤家都拿到更好的 offer。
No. 28 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
5.Spring容器和Web容器之间的区别知道吗?(补充)
2024 年 7 ⽉ 11 ⽇增补
⾸先从概念上来说,Spring 容器是⼀个 IoC 容器,主要负责管理 Java 对象的⽣命周期和依赖关系。⽽ Web 容
器,⽐如 Tomcat、Jetty 这些,是⽤来运⾏ Web 应⽤的容器,负责处理 HTTP 请求和响应,管理 Servlet 的⽣命
周期。
/**
* SpringUtil.java
* ⽤于获取 Spring 容器中的 Bean,技术派源码:https://github.com/itwanger/paicoding
*/
@Component
public class SpringUtil implements ApplicationContextAware {
private volatile static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringUtil.context = applicationContext;
}
public static <T> T getBean(Class<T> bean) {
return context.getBean(bean);
}
}
从功能上看,Spring 容器专注于业务逻辑层⾯的对象管理,⽐如我们的 Service、Dao、Controller 这些 Bean 都
是由 Spring 容器来创建和管理的。⽽ Web 容器主要处理⽹络通信,⽐如接收 HTTP 请求、解析请求参数、调⽤相
应的 Servlet,然后把响应返回给客户端。
No. 29 / 180
⾯渣逆袭Spring篇V2-让天下所有的⾯渣都能逆袭
在实际项⽬中,这两个容器是相辅相成的。我们的 Web 项⽬部署在 Tomcat 上的时候,Tomcat 会负责接收 HTTP
请求,然后把请求交给 DispatcherServlet 处理,⽽ DispatcherServlet ⼜会去 Spring 容器中查找相应的
Controller 来处理业务逻辑。
/**
* GlobalViewInterceptor.java
* ⽤于全局拦截器,技术派源码:https://github.com/itwanger/paicoding
*/
@Component
public class GlobalViewInterceptor implements HandlerInterceptor {
@Autowired
private GlobalInitService globalInitService;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// Web 容器的 HTTP 请求 + Spring 容器的业务服务
}
}
还有⼀个重要的区别是⽣命周期。Web 容器的⽣命周期跟 Web 应⽤程序的部署和卸载相关,⽽ Spring 容器的⽣
命周期是在 Web 应⽤启动的时候初始化,应⽤关闭的时候销毁。
现在我们都⽤ Spring Boot 了,Spring Boot 内置了 Tomcat,把 Web 容器和 Spring 容器都整合在⼀起了,我们
只需要运⾏⼀个 jar 包就可以了。
@SpringBootApplication
public class QuickForumApplication {
public static void main(String[] args) {
SpringApplication.run(QuickForumApplication.class, args);
}
}
No. 30 / 180