面试总结篇--spring相关

本文概述了面试中常见的问题,包括数据类型int和integer的区别、ArrayList与LinkedList的性能比较,以及Spring AOP的实现原理和事务管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总结面试中常见的一些问题。

1、int和integer的区别

首先int的基本数据类型,但是integer是一个封装数据类型;

int的默认是0,但是integer模式是null;

在jvm层面,是出于性能和开销的考虑,引入了int,不是一个完全面向对象处理的;integer是完完全全的对象,在实例里面有对象头,会加载class对象

int的比较是通过==,但是integer是通过equal,

integer还有一个内部的缓存存在,即-128~127;

在实际使用的时候,如果是一些临时的对象用int,会分配在栈上,但是对一些pojo类,还是需要通过integer,这样可以更好的实现序列化和反序列化,

2、arraylist和linkedlist

一个是数组,一个是双向链表;

ArrayList适合读取,因为只要直接索引获得,但是linked需要通过遍历获取,

插入的时候linkedlist更好,因为它只需要将指针指向另一个位置,而ArrayList插入的时候涉及到扩容等,元素需要移动位置,会引起比较大的开销

3、线程的实现方法

继承thread、实现runable接口、继承callable接口,线程池

4、死锁

引起死锁的四个条件

资源互斥,不可抢占、不会主动释放,进程-资源之间形成回路

5、代码级别的锁不能在多节点的时候会失效

  用db的乐观锁机制,通过一个version实现,

redis分布式锁

6、redis分布式缓存

7、redis的集群会通过hash的key落到不同的槽里面

8、rpc调用

        springcloud的rpc调用是通过feign调用,其实际上是通过发出一个http请求来实现的,会把调用的一些对象序列化成json,在不同的节点之间进行调用;它有一套吧治理的机制,比如注册中心、服务发现、熔断、限流这样一些机制,然后实现各个微服务之间的调用。

对spring中ioc的理解

spring是一个ioc容器,容器就是放数据的,java里面的容器就是集合类。ioc容器实际上就是个map(key,value),里面存的是各种对象(在xml里配置的bean节点||repository、service、controller、component),在项目启动的时候会读取配置文件里面的bean节点,根据全限定类名使用反射new对象放到map里;扫描到打上上述注解的类还是通过反射new对象放到map里。

     这个时候map里就有各种对象了,接下来我们在代码里需要用到里面的对象时,再通过DI注入(autowired、resource等注解,xml里bean节点内的ref属性,项目启动的时候会读取xml节点ref属性根据id注入,也会扫描这些注解,根据类型或id注入;id就是对象名)。

对属性注入完毕后,然后检查aware相关接口并设置相关依赖,主要是beanameaware和beanfactoryaware,

这之后执行初始化前的方法beanpostprocessor,然后执行初始化方法,然后执行初始化后的方法,执行完这些方法后,如果bean是单例会放入单例池里面,然后使用这个bean,使用完之后调用destory销毁。

ioc的底层实现

工作原理:实现原理

1、反射

2、工厂模式的实现

3、xml解析

spring中的bean的生命周期

1、实例化bean,通过反射的方式生成对象

2、填充bean的属性,即从ioc容器中选择autowared注释的属性注入,(会引起三级循环、循环依赖的问题)

3、回调,调用aware接口相关的方法,即完成beanname、beanfactory、beanclassload对象的属性设置。

4、执行初始化前的方法beanpostprocessor ,使用比较多的是applicationcontextpostprocessor,设置applicationcontext、environment、resourceloader、embeddvalueresolver等对象

5、执行initmethod初始化的方法,同时会判断是否实现了initializingbean接口,如果实现了,调用afterpropertiesset方法,如果没有实现接口,就不会调用

6、调用beanpostprocessor的后置处理方法,spring的aop就是此处实现的;通过接口abstractAutoProxyCreator;

7、获取到完整的对象,可以通过getbean的方式来进行对象的获取

8、执行销毁方法destory。

 spring缓解循环依赖

 

 通过三级缓存来解决循环依赖的问题,这个过程中提前暴露对象,同时会用到aop原理;

1、先解释什么是循环依赖问题,比如A依赖B,B依赖A,就构成了循环依赖,即相互引用,形成闭环

2、解决方法:

核心是为了打断这个闭环。

         先创建对象A,实例化对象A,此时A对象中的b属性为空,就会从ioc容器中查找b,如果找到了就直接赋值,不存在循环依赖问题,找不到就直接创建B对象,

         然后实例化b对象,此时b对象中a属性为空,需要填充属性a;

        在然后从容器中查找a,找不到,如此会形成闭环。

由于spring的三级缓存,会发现a对象是存在的,此时的a不是一个完整的状态,只是完成了实例化,但是没有完成初始化,在程序调用过程中,会先将这个不完整的对象赋值给属性,然后等待后续操作来完成赋值,

5、bean factory 和factory bean的区别

都是用来创建bean对象的。

不同点是当使用beanfactory创建对象的时候,必须要遵循严格的声明周期流程,如果想要简单的自定义某个对象的创建,同时创建完成的对象想交给spring来管理,那么就需要实现factorybean接口了,

里面有三个方法   issingleton 是否是单例模式

                           getobjecttype  获取返回对象的类型

                           getobject  自定义创建对象的过程  new、反射、动态代理

使用这种方式创建完对象后,会将对象交给spring管理。

 spring里面用到的设计模式

1、单例模式   bean默认都是单例的

2、原型模式:指定作用域为prototype

3、工程模式:beanfactory

4、模板方法:postprocessbeanfactory、onrefresh

5、策略模式:xmlbeandefinitionreader、propertiesbeandefinitionreader

6、观察者模式:listener、event

7、适配器模式:adapter、

8、装饰器模式:beanwraper

9、代理模式:动态代理

10、委托者模式:delegate

spring的aop的底层实现原理

动态代理,即面向切面编程

aop是ioc的一个扩展功能。,先有的ioc,在有的aop,只是在ioc的整个流程中新增的一个扩展点而已,在beanpostprocessor这个位置扩展的。

总:aop概念---面向切面编程,使用场景--日志、事务等实现方式:动态代理;

bean的创建过程中有一个步骤可以对bean进行扩展实现,aop本身就是一个扩展功能,所以在beanpostprocessor的后置处理方法中来进行实现。

1、代理对象的创建过程是通过切面、切入点这些来实现,即aspect切面,以及通知beafore、after等定义切点;

2、通过jdk或者cglib的方式来生成代理对象。

3、在执行方法调用的时候,会调用到生成的字节码文件

4、根据之前定义好的通知来生成拦截器链;

spring的事务是如何回滚的

即spring的事务管理是如何实现的。

里面涉及声明式事务和编程式事务。

事务的整体过程是:建立连接开启事务---> 进行sql操作--->成功就提交commit,失败就回滚rollback;

spring的事务是由aop来实现的,首先要生成代理对象,然后按照aop的整套流程来执行具体的操作逻辑,正常情况下要通过通知来完成核心功能,但是事务不是通过通知来具体实现的,而是通过一个transacinterceptor来实现的,然后调用invoke来实现具体的逻辑。

具体步骤是::

1、先做准备工作,解析各个方法上事务相关的属性,比如隔离性、传播特性,然后根据具体的属性判断是否开启新事务

2、当需要开启事务的时候,获取数据库连接,关闭自动提交功能,开启事务

3、执行具体的sql逻辑

4、在操作过程中,如果执行失败了,就会通过completetransactionafterthrowing来完成事务的回滚操作,回滚的具体逻辑是通过 dorollback方法来实现的,实现的时候也是要先获取连接对象,通过连接对象来回滚

5、如果执行过程中没有失败,就直接提交事务,提交的具体逻辑是通过dicommit方法来实现的,实现的时候也是需要获取连接,通过具体的连接来实现的,

6、当事务执行完毕之后,需要清除相关的事务信息cleanuptransactioninfo;

谈一下spring事务的传播特性

一共七种;

required: 有就加入,没有就创建

requires_new: 不管有没有都新建一个事务,

nested:支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。

support: 有就加入,没有就不用事务

not_support: 以非事务的方式运行,如果当前有事务就挂起

never: 以非事务的方式运行,如果当前有事务就抛出异常

mandatory: 有就加入,没有就抛出异常

具体场景:

A方法调用B方法,ab方法都有事务,并且事务传播特性不一样,那么A如果有异常,b怎么办,b如果异常,a怎么办。

jdk1.8的新特性:

1、lambda表达式

2、函数式接口

3、方法引用和函数构造器

4、stream的api

5、接口中支持默认方法和静态方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zero _s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值