当前位置:首页 > java > 面试题 > 正文内容

Spring 非常规面试题

关中浪子2年前 (2022-04-25)面试题1087
【腾讯云】2核2G4M云服务器新老同享99元/年,续费同价
找梯子最重要的就是稳定,这个已经上线三年了,一直稳定没有被封过,赶紧下载备用吧!

1. Spring循环依赖相关问题

spring三层缓存的第二层缓存有什么用?

循环依赖为什么要使用三级缓存?二级不能解决么?beanB从三级缓存中获取beanA以后提升到二级缓存 ?

循环依赖涉及二级缓存具体作用是什么,一般不用二级缓存也能实现?

为什么spring无法处理基于构造器的循环依赖问题?

二级缓存为什么要放入代理对象?直接放入三级缓存中未成形对象不可以嘛?


Spring中循环依赖场景有:

构造器的循环依赖(构造器注⼊)

Field 属性的循环依赖(set注⼊)


其中,构造器的循环依赖问题⽆法解决,只能拋出 BeanCurrentlyInCreationException 异常,在解决属性循环依赖时,spring采⽤的是 提前暴露对象 的⽅法。


Spring 的循环依赖的理论依据基于 Java 的引⽤传递,当获得对象的引⽤时,对象的属性是可以延后设置的,但是构造器必须是在获取引⽤之前。


Spring利用singletonObjects, earlySingletonObjects, singletonFactories三级缓存去解决循环依赖问题

三个缓存其实就是三个Map:

在这里插入图片描述


解答:三个缓存 各司其职(鸡蛋不要放到一个篮子里),面向对象设计的原则,就是这么设计的!

将成型的bean和不成形的bean分开,分别存储


一级存储:存储成型的bean

二级缓存:存储不成形的bean,未来可以存储增强后得bean

三级缓存是不成形得bean,在三级缓存向二级缓存存储bean得时候,可以执行增强操作,获取bean得代理对象

三级缓存:存储数据形式<key , 工厂> 的形式


例如:

A对象,对A对象进行了AOP增强

B对象


ioc实例化bean过程:

具体源码剖析流程参考:Spring循环依赖源码剖析


2. SpringBean的生命周期

Bean ⽣命周期的整个执⾏过程描述:


根据配置情况调⽤ Bean 构造⽅法或⼯⼚⽅法实例化 Bean。

利⽤依赖注⼊完成 Bean 中所有属性值的配置注⼊。

如果 Bean 实现了 BeanNameAware 接⼝,则 Spring 调⽤ Bean 的 setBeanName() ⽅法传⼊当前 Bean 的 id 值。

如果 Bean 实现了 BeanFactoryAware 接⼝,则 Spring 调⽤ setBeanFactory() ⽅法传⼊当前⼯⼚实例的引⽤。

如果 Bean 实现了 ApplicationContextAware 接⼝,则 Spring 调⽤ setApplicationContext() ⽅法传⼊

当前 ApplicationContext 实例的引⽤。

如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调⽤该接⼝的预初始化⽅法

postProcessBeforeInitialzation() 对 Bean 进⾏加⼯操作,此处⾮常重要,Spring 的 AOP 就是利⽤它实现的。

如果 Bean 实现了 InitializingBean 接⼝,则 Spring 将调⽤ afterPropertiesSet() ⽅法。

如果在配置⽂件中通过 init-method 属性指定了初始化⽅法,则调⽤该初始化⽅法。

如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调⽤该接⼝的初始化⽅法 postProcessAfterInitialization()。

此时,Bean 已经可以被应⽤系统使⽤了。

如果在 中指定了该 Bean 的作⽤范围为 scope=“singleton”,则将该 Bean 放⼊ Spring IoC 的缓存池中,

将触发 Spring 对该 Bean 的⽣命周期管理;如果在 中指定了该 Bean 的作⽤范围为 scope=“prototype”,则将该 Bean 交给调⽤者,调⽤者管理该 Bean 的⽣命周期,Spring 不再管理该 Bean。

如果 Bean 实现了 DisposableBean 接⼝,则 Spring 会调⽤ destory() ⽅法将 Spring 中的 Bean 销毁;

如果在配置⽂件中通过 destory-method 属性指定了 Bean 的销毁⽅法,则 Spring 将调⽤该⽅法对 Bean 进⾏销毁。

注意:Spring 为 Bean 提供了细致全⾯的⽣命周期过程,通过实现特定的接⼝或 的属性设置,都可以对 Bean 的⽣命周期过程产⽣影响。

虽然可以随意配置 的属性,但是建议不要过多地使⽤ Bean 实现接⼝,因为这样会导致代码和 Spring 的聚合过于紧密

在这里插入图片描述


3. Spring是如何对XXXService进行依赖注入的(Service没有set方法和构造方法)

反射的方式


4. spring源码分析中核心流程有哪些?面试的或工作中写代码能借鉴的

容器初始化流程

循环依赖流程


5. bean中如果又多个构造方法,容器初始化的时候要怎么去选择?

选择无参构造器,必须有无参构造器


6. Spring源码类名都很长,如何记住层层调用关系?面试提问源码问题一般细到什么层级?

了解机制原理/流程即可、不问类名


7. set方式注入时,property标签里面的name属性是需要注入的类名还是属性名,跟同事争论了很久,官方文档是写的属性名,但是老师讲的例子里面是写的类名,很困惑

setXXX中的XXX,其实不是属性名称和类名称


8. static方法和单例实例方法在内存中有什么区别,分别在什么情况下使用?单例的实例方法在多线程访问时是否有性能瓶颈?

静态方法在类加载的时候就创建了,实例方法当对象实例化的时候才去占用内存

static方法区占用内存区域有限(连续占用内存区域,执行性能稍高),太多会影响性能

实例方法是离散分布的


一般工具方法都设置成static


单例的实例方法在多线程访问时 如果存在成员变量、操作了成员变量,考虑到锁的时候,就影响性能


9. Spring容器里的单例bean如果有非静态成员变量int a=0,业务方法中会改变a的值,那么第二次调用该bean的时候a的初始值还是0吗?

不是


10. Spring容器在初始化一个bean的时候会做那些事情,顺序是怎样的,在容器关闭的时候,又会做哪些事情

在spring的BeanFactory工厂列举了很多接口,代表着bean的生命周期,我们主要记住的是我圈红线圈出来的接口, 再结合spring的源码来看这些接口主要是在哪里调用的

在这里插入图片描述

14. Spring事务失效场景及原理

1)吃异常

2)数据库引擎不支持事务

3)非public方法

4)调用同类的方法 等


15. 自定义依赖注入注解不是很清楚

注解就是一个标记,不同的标记表明我们要针对类、字段、或者方法做一些什么事情


16. spring源码中总共用到了哪些设计模式,具体体现在哪?

在这里插入图片描述


17. 单例 多个线程取去会怎么样?

如果单例中操作成员变量,会造成并发问题


18. 如果autowired注入时使用的是接口,如何在ioc容器中定位实现类

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean


按照名称和类型


19. 如何自定义一款spring的插件,比如做一个通用的权限拦截,然后根据用户的登录信息去用户中心查看是否有权限,在sprinng加载的时候,就把该插件加载进去?然后业务代码中这块完全不写可以做到吗?

说的这个就是SpringMVC拦截器


定义拦截器,注册到容器中


20. 事务的超时这个地方是怎么控制的?

timeout


21. Spring 循环注入有什么好处

是个问题,而非好处,我们尽量避免这种情况发生


22. 为什么不能将对象注入到servlet

bean对象在spring容器中,servlet在servlet容器中;


可以通过Spring暴露的接口方法,WebApplicationContextUtils.getWebApplicationContext获取到容器,然后getBean

也可以使用@Autowired,但是需要做一些配置

public void init() throws ServletException {
        WebApplicationContextUtils
                .getWebApplicationContext(getServletContext())
                .getAutowireCapableBeanFactory().autowireBean(this);
    }


23. 自定义注解实现动态代理,怎么作用于方法上边

对象是类的对象,方法级别控制直接在Invoke方法中判断Method是否有相应注解即可


24. PROPAGATION_NESTED 嵌套事务什么意思

PROPAGATION_NESTED 开始一个 “嵌套的” 事务, 它是已经存在事务的一个真正的子事务。潜套事务开始执行时, 它将取得一个 savepoint

如果这个嵌套事务失败, 我们将回滚到此 savepoint。潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交

如果外部事务 commit, 潜套事务也会被 commit, 这个规则同样适用于回滚.


25. spring多例模式管理的bean是用户获取的时候才去初始化,那么这种方式和new出来的实例有什么区别,相比而言有哪些优势

无对比性,spring ioc是管理单例对象,多例模式只是为了支持可能的其他需求


26. 容器为什么要设计@Compoment, @Repository, @Service, 只用一个注解实现不是更好管理吗?

为了让我们更方便的按层次管理代码


27. spring的单例Bean是线程安全的吗?

不是,在bean中如果维护了成员变量,请自行控制其并发访问

可以通过参数传递去避免比较好


28. servlet是单例模式,为什么doGet和doPost不需要synchronized修饰?单例如何保证高并发时的性能?(假如存在实例变量)

servlet本身没有替我们考虑线程安全问题,需要我们自己考虑


避免使用实例变量(推荐)

synchronized同步 / ThreadLocal

实现SingleThreadModel 接口

最好避免使用成员变量(设计的角度)


29. 事务从手写改为动态代理,转账时执行了两次Update,第一次执行的时候代理对象会提交了事务,第二次执行Update时,出现了问题第一次的Update已经提交了就不能回滚了吧?

第一次的并没有提交,同一个事务


30. 能不能给我们讲讲大型互联网企业在使用spring国际化的一些经验

国内使用国际化较少

前端页面 /spring国际化 / 后台实现 /单独写一套/ 等方案


31. "spring在进行初始化beanDefinition的时候,是否对每一个加上@Component或者@Service等注解的类,都保留了既可以根据该类的类型得到bean对象,又可以根据该类的名称得到bean对象,也可以根据该类的自定义注解名得到该对象?

实际不需要存储两台,存储两套是一种实现的方式


32. TransactionStatus这个类具体有啥用?

查看事务的状态


33. 分布式事物该怎么去实现,大致思路是什么怎么控制

思路:外围启动一个大事务,包含很多小的事务;最终大事务的提交与否,需要依靠各个小事务来决定


比如阿里的seata: (分布式事务的一种解决方案)

Seata 的设计思路是将一个分布式事务可以理解成一个全局事务,下面挂了若干个分支事务,而一个分支事务是一个满足 ACID 的本地事务,因此我们可以操作分布式事务像操作本地事务一样。

Seata 内部定义了 3个模块来处理全局事务和分支事务的关系和处理过程,这三个组件分别是:

Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。

Transaction Manager ™: 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。

Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。


34. spring应用如此广泛,那么他有哪些不足,或者说我们在哪些业务场景可以不考虑spring

小型项目引入Spring增加了复杂度

核心功能基于容器

一旦引入spring,和它的耦合就会很大


35. 由于现在接触的都是传统的垂直架构系统,知道spring这样用,在大型分布式系统中spring是怎么玩的?有不一样的地方或注意点吗?

互联网公司很多都摆脱了垂直架构了

IOC和aop是核心,这是不变的玩法一样,后面有SpringBoot,微服务SpringCloud


36. ThreadLocal在Spring中是怎么使用的?

无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。


就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全的“状态性对象”采用ThreadLocal进行封装,让它们也成为线程安全的“状态性对象”,因此有状态的Bean就能够以singleton的方式在多线程中正常工作


37. 面试中被问到的,如何用aop实现一个参数校验器

在前置通知中配置切入点拦截方法

取出参数,校验参数(可以自定义一些注解,添加到参数上(非空,长度限制... ...))

在aop的横切逻辑中解析注解,判断是否符合要求


38. spring初始化过程中都有加锁,spring初始化过程是并发的吗?

防止并发刷新,例如refresh可以手动触发,防止并发操作


在这里插入图片描述


39. spring有几种事件类型?怎么使用?他们的作用是什么?如果自定义一个事件?

ContextRefreshedEvent

ContextStartedEvent

ContextStoppedEvent

ContextClosedEvent

RequestHandledEvent


定义bean,实现ApplicationListener接口即可



40. 当一个接口有多个实现类,且这些实现类都有@Service注解,那么在beanDefinition中是怎么存放的呢?为什么这样@Autowired就会报错呢?

多个beanDefinition

一个接口,多个实现类,不知道具体应该使用哪个实现类,需要格外指定,否则报错


41. spring是怎么集成tomcat,然后进行启动的?

ContextLoaderListener  初始化spring容器操作


42. spring学完了,其中的组件,还不能串起来,譬如web,orm,oxm,jms,servlet

spring全家桶还没有学完


43. 从ThreadLocal中获取Connection,完成后而不手动移除,会不会造成内存泄露?

可以手动销毁资源,如果当前请求处理线程销毁了,也会销毁内部资源


44. 事务A调用事务B Brollback 事务A 也rollback吗

方法之间调用,方法中的事务和事务的传播行为的设置有关


45. 有些时候循环依赖是否可以通过懒加载的方式解决,如果可以,这种方式和spring解决循环依赖相比有什么区别?

懒加载解决不了循环依赖问题,只是掩耳盗铃把问题后置罢了


46. 有参构造注入为什么无法解决循环依赖?(set注入可以)

对象还没实例化完

set注入是把对象实例化后,进行注入对象的半成品


47. ThreadLocal 如果配合线程池使用,线程会重复使用,这样会有安全嘛?

需要清理控制,进行初始化的设置


扫描二维码推送至手机访问。

版权声明:本文由码农翻生发布,如需转载请注明出处。

本文链接:https://lubojian.cn/post/172.html

分享给朋友:
返回列表

上一篇:2022最新 SpringCloud面试题【36题】

没有最新的文章了...

相关文章

2022最新 Java基础面试题【120题】

2022最新 Java基础面试题【120题】

1. Java 基本概念1.1 Java源程序的扩展名是什么?.java1.2 什么是标识符?在java语言中能够我们自己起名的都叫标识符1.3 标识符有哪些特点?标识符是大小写字母、数字字符、$和_组成,不能以数字开头,也不能是java关...

2022最新 Java高并发面试题【110题】

2022最新 Java高并发面试题【110题】

1. 并发基础1.1 并行和并发有什么区别?并行多个处理器或多核处理器同时处理多个任务。并发多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。串行有n个任务,由一个线程按顺序执行。由于任务、方法...

2022最新 Java虚拟机(JVM)面试题【35题】

2022最新 Java虚拟机(JVM)面试题【35题】

1. JVM 基础1.1 JVM 内存分哪几个区,每个区的作用是什么?方法区有时候也成为永久代,在该区内很少发生垃圾回收,但是并不代表不发生 GC,在这里进行的 GC 主要是对方法区里的常量池和对类型的卸载方法区主要用来存储已被虚拟机加载的...

2022最新 Redis面试题【50题】

1. Redis基础1.1 什么是 Redis?Redis 本质上是一个 Key-Value 类型的内存数据库,很像 memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据 flush 到硬盘上进行保存。因为...

2022最新 MySQL面试题【111题】

2022最新 MySQL面试题【111题】

1. MySQL 基础1.1 超键、候选键、主键、外键分别是什么?超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键。超键包含候选键和主键。候选键:是最小超键,即没有冗余...

2022最新 SpringMVC面试题【32题】

2022最新 SpringMVC面试题【32题】

1. Spring MVC基础1.1 什么是Spring MVC?Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把模型-视图-控制器分离,将web层进行职责解耦,把复杂的web应用分成逻辑...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。