网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
本栏目Java开发岗高频面试题主要出自以下各技术栈:Java基础知识
、集合容器
、并发编程
、JVM
、Spring全家桶
、MyBatis等ORMapping框架
、MySQL数据库
、Redis缓存
、RabbitMQ消息队列
、Linux操作技巧
等。
面试题1:能简单说一下你对Spring框架的理解么?
我们一般说的Spring框架就是Spring Framework,一种轻量级框架,用于提高开发人员的开发效率和可维护性。它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。这些模块包括:核心容器
、数据访问/集成
、响应式 web 编程
、AOP(面向切面编程)
、工具
、消息和测试模块
。
下图对应的是Spring 4.x的版本,目前最新的5.x版本中Web模块的Portlet组件已经被废弃掉,同时增加了用于异步响应式处理的WebFlux组件。
主要模块包括:
Spring Core
:Core封装包是框架的最基础部分,提供IOC和依赖注入特性
。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
Spring AOP
:AOP模块是Spring的AOP库,提供了AOP(拦截器)机制
,并提供常用的拦截器,供用户自定义和配置。
Spring JDBC
:负责Java数据库连接。
Spring JMS
:负责Java消息服务。
Spring ORM
:用于支持常用的Hibernate,Mybatis等框架,Spring本身并不对ORM进行实现,仅对常见的ORM框架进行封装
,并对其进行管理;
Spring Web
:WEB模块提供对常见框架如Struts X,SpringMVC,JSF的支持,Spring能够管理这些框架,将Spring的资源注入给框架,也能在这些框架的前后插入拦截器。
Spring Test
:提供了对JUnit和TestNG测试的支持。
Core Container中的
Core
组件是Spring所有组件的核心,Beans
组件和Context
组件是实现IOC和DI的基础,AOP
组件用来实现面向切面编程。
追问1:常见的Core组件有哪些?
- IoC Container,控制反转容器
- Events,事件编程
- Resources,资源加载
- i18n,国际化
- Validation,校验
- Data Binding,数据绑定
- Type Conversion,类型转换
- SpEL,Spring 表达式
- AOP,面向切面编程
课间休息,又来秀一下来自咱们群里同学的搬砖工地,坐标:上海 朱家角。
作者:🇨 🇭 🇪 🇳 🇬
面试题2:谈谈对Spring IOC的理解
IOC(Inversion Of Controll
,控制反转)是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由给Spring框架来管理。
IOC在其他语言中也有应用,并非Spring特有。IOC容器是Spring用来实现IOC的载体,IOC容器实际上就是一个Map(key, value)
,Map中存放的是各种对象。
将对象之间的相互依赖关系交给IOC容器来管理,并由IOC容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。IOC容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。
在实际项目中一个Service类可能由几百甚至上千个类作为它的底层,假如我们需要实例化这个Service,可能要每次都搞清楚这个Service所有底层类的构造函数,这是不现实的。如果利用IOC的话,你只需要配置好,然后在需要的地方引用就行了
,大大增加了项目的可维护性且降低了开发难度。
Spring时代我们一般通过XML文件来配置Bean,后来开发人员觉得用XML文件来配置不太友好,于是Sprng Boot注解配置就慢慢开始流行起来。
追问1:Spring中的bean的作用域有哪些?
spring 支持 5 种作用域,如下:
singleton
:唯一bean实例,Spring中的bean默认都是单例的。prototype
:每次请求都会创建一个新的bean实例。request
:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。session
:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。global-session
:全局session作用域,仅仅在基于Portlet的Web应用中才有意义,Spring5中已经没有了。Portlet是能够生成语义代码(例如HTML)片段的小型Java Web插件。它们基于Portlet容器,可以像Servlet一样处理HTTP请求。但是与Servlet不同,每个Portlet都有不同的会话。
追问2:Spring中的bean生命周期?
- Bean容器找到配置文件中Spring Bean的定义。
- Bean容器利用Java Reflection API创建一个Bean的实例。
- 如果涉及到一些属性值,利用set()方法设置一些属性值。
- 如果Bean实现了BeanNameAware接口,调用
setBeanName()
方法,传入Bean的名字。
- 如果Bean实现了BeanClassLoaderAware接口,调用
setBeanClassLoader()
方法,传入ClassLoader对象的实例。 - 如果Bean实现了BeanFactoryAware接口,调用
setBeanClassFacotory()
方法,传入ClassLoader对象的实例。 - 与上面的类似,如果实现了其他*Aware接口,就调用相应的方法。
- 如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行
postProcessBeforeInitialization()
方法。 - 如果Bean实现了InitializingBean接口,执行
afeterPropertiesSet()
方法。 - 如果Bean在配置文件中的定义包含init-method属性,执行指定的方法。
- 如果有和加载这个Bean的Spring容器相关的BeanPostProcess对象,执行postProcessAfterInitialization()方法。
- 当要销毁Bean的时候,如果Bean实现了DisposableBean接口,
执行destroy()方法
。 - 当要销毁Bean的时候,如果Bean在配置文件中的定义包含destroy-method属性,执行指定的方法。
追问3: Spring 中的 bean 是线程安全的吗?
Spring容器中的Bean是否线程安全,容器本身并没有提供Bean的线程安全策略
,因此可以说Spring容器中的Bean本身不具备线程安全的特性
,但是具体还是要结合具体scope的Bean去研究。
结合上面提到的Spring bean 的作用域(scope)
- 对于
prototype作用域的Bean
,每次都创建一个新对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题。 - 对于
singleton作用域的Bean
,所有的线程都共享一个单例实例的Bean,因此是存在线程安全问题的。但是如果单例Bean是一个无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的。比如Controller类、Service类和Dao等,这些Bean大多是无状态的,只关注于方法本身。
有状态Bean
(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的
。无状态Bean
(Stateless Bean):就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的
。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
那么很难做到真正的技术提升。**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!