大家好,我是鸭鸭!
最近小猿口算迎来泼天的富贵,大学生、研究生、程序员轮番上线暴打小学生。在大家热火朝天地炸鱼的时候,小猿口算悄无声息地上线了好友对战、战绩胜率查询、反外挂系统……
小猿口算程序员:
小猿口算的官方号还趁此期间宣传了一波猿辅导今年的校招。让鸭鸭忍不住想起前些日子看到小猿口算招高级反爬算法工程师的截图……
这张图鸭鸭没有在 Boss 上找到,不过小猿口算确实有在招人。目前明确是小猿口算的岗位只有两个,一个是 IOS 研发工程师,20~40k,14 薪;一个是 C 端产品经理,25~40k,14薪。
猿辅导旗下还有猿辅导、斑马App、南瓜科学、猿编程等多款在线教育产品,早 10 晚7 ,六险一金。据说猿辅导整体工作氛围不卷,下午茶、健身房等等福利待遇都不缺,工作氛围很是不错。
至于校招方面,鸭鸭找到一份过去猿辅导的校招薪资,可以供大家参考,按岗位来划分:
- 算法岗分为三档:27k、30k、35k;
- 开发岗分为三档:25k、27k、30k;
- 产品岗分为两档:19k、21k。
不知道这个薪资有没有让你满意呢?
要想拿下这种神仙工作,面试时总不能连八股文都答不出来吧?欢迎大家来面试鸭刷题,一举拿下心仪 offer !
来看今天的一道猿辅导真题:
说下 Spring Bean 的生命周期?
回答重点
- 实例化:Spring 容器根据配置文件或注解实例化 Bean 对象。
- 属性注入:Spring 将依赖(通过构造器、setter 方法或字段注入)注入到 Bean 实例中。
- 初始化前的扩展机制:如果 Bean 实现了 BeanNameAware 等 aware 接口,则执行 aware 注入。
- 初始化前(BeanPostProcessor):在 Bean 初始化之前,可以通过 BeanPostProcessor 接口对 Bean 进行一些额外的处理。
- 初始化:调用 InitializingBean 接口的 afterPropertiesSet() 方法或通过 init-method 属性指定的初始化方法。
- 初始化后(BeanPostProcessor):在 Bean 初始化后,可以通过 BeanPostProcessor 进行进一步的处理。
- 使用 Bean:Bean 已经初始化完成,可以被容器中的其他 Bean 使用。
- 销毁:当容器关闭时,Spring 调用 DisposableBean 接口的 destroy() 方法或通过 destroy-method 属性指定的销毁方法。
扩展知识
理解生命周期
我们需要先知晓之所以 Bean 容易被添加一些属性,或者能在运行时被改造就是因为在生成 Bean 的时候,Spring对外暴露出很多扩展点。
基于这些点我们可以设置一些逻辑,Spring 会在 Bean 创建的某些阶段根据这些扩展点,基于此进行 Bean 的改造。
有了上面的认识,我们再来看 Spring Bean 的生命周期,我用一幅图总结一下:
大致了解生命周期之后,我们再来看详细的操作,可以看到有好多扩展点:
注意细节,这幅图的颜色和上面那副有对应关系的。
Spring Bean 生命周期详细步骤
实例化阶段:
- Bean 的实例化是通过反射机制创建的。Spring 根据
@Component
、@Bean
或者 XML 中的<bean>
元素配置,来确定要创建的 Bean。
属性赋值阶段:
- 在实例化完成后,Spring 会进行依赖注入。这包括将属性值注入到 Bean 的字段中,可能是通过构造函数注入、setter 方法注入,或者直接字段注入。
初始化前的扩展机制:
- Bean 可以实现
BeanNameAware
、BeanFactoryAware
等Aware
接口,从而在初始化之前获取 Bean 的名称、BeanFactory、ApplicationContext 等容器资源。例如,ApplicationContextAware
接口允许 Bean 获取ApplicationContext
,以便进一步与 Spring 容器交互。
BeanPostProcessor 的作用:
BeanPostProcessor
接口允许开发者在 Bean 初始化前后添加自定义逻辑。例如,可以在postProcessBeforeInitialization
方法中执行某些前置操作,如代理包装、AOP 切面等。在postProcessAfterInitialization
中,可以进一步修改或替换 Bean 实例。
初始化的细节:
InitializingBean
接口提供了一个afterPropertiesSet
方法,用于在 Bean 的所有属性设置完成后执行一些自定义初始化逻辑。开发者也可以通过@PostConstruct
注解或者 XML/Java 配置中的init-method
属性,来指定初始化方法。
Bean 的就绪状态:
- Bean 完成初始化后,即进入就绪状态,可以供应用程序使用。在此状态下,Bean 已经完成了所有的属性设置和初始化步骤,处于可用状态。
销毁阶段的清理:
- Bean 的销毁通常在容器关闭时进行。
DisposableBean
接口提供了destroy
方法,用于清理资源。开发者也可以通过@PreDestroy
注解或配置中的destroy-method
属性,指定清理逻辑。
Bean 的生命周期扩展点汇总
Spring 提供了多个扩展点,让开发者可以自定义和控制 Bean 的生命周期:
BeanPostProcessor:
- 通过实现
BeanPostProcessor
接口,开发者可以在 Bean 初始化前后添加自定义逻辑,如动态代理、AOP 增强等。
BeanFactoryPostProcessor:
BeanFactoryPostProcessor
允许开发者在 Bean 实例化之前,修改 Bean 的定义信息(如属性值),它在所有 Bean 实例化之前执行。
Aware 接口:
- Spring 提供了多个
Aware
接口,如BeanNameAware
、BeanFactoryAware
、ApplicationContextAware
等,允许 Bean 获取 Spring 容器的相关信息,进一步定制生命周期。
@PostConstruct 和 @PreDestroy:
- 这些注解提供了一种声明式的方法来定义初始化和销毁逻辑,通常用于替代 XML 或 Java 配置中的
init-method
和destroy-method
。
Bean 的作用域(Scope)与生命周期的关系
Spring Bean 的生命周期还与其作用域密切相关:
Singleton(单例):
- 默认作用域,Bean 的生命周期与 Spring 容器的生命周期一致。在容器启动时创建,在容器关闭时销毁。
Prototype(原型):
- 每次请求时创建一个新的 Bean 实例,容器只负责创建,不管理其生命周期(不调用销毁方法)。
Request、Session、Application、WebSocket:
- 这些作用域用于 Web 应用中,Bean 的生命周期分别与 HTTP 请求、会话、应用或 WebSocket 的生命周期一致。
常见的生命周期应用场景
连接池管理:
- 在初始化阶段创建数据库连接池,在销毁阶段关闭连接池,以确保资源的有效管理。
缓存初始化:
- 在
afterPropertiesSet
或@PostConstruct
中加载缓存数据,在销毁阶段清理缓存。
动态代理创建:
- 在
postProcessBeforeInitialization
中为 Bean 创建动态代理,以实现 AOP 功能。
最后
再来推荐下我们的面试刷题网站和小程序:面试鸭!