1.redis分布式锁实

2.zset底层数据结构

3.dubbo nacos 结构 作用 服务怎么注册发现的

4.rabbitmq 发消息策略

5.rabbitmq 怎么保证数据的一致性

6.spring 和springboot使用感受

7.微服务有哪些组件

8.多线程 配置

9.线程阻塞怎么办

10.事物中 可以配置哪些参数

11.redis 有几种数据类型

12.mybatis 参数是怎么传的

13.mysql 优化

14.SpringBoot之常用注解

15.重载与重写的区别

16.各mq的区别

17.rabbitmq的几种消息模型

18.多线程中怎么将线程按指定顺序执行

19.nacos用法

20.什么是微服务?

21.什么情况下spring事物会失效

  1. 方法内的自调用:Spring事务是基于AOP的,只要使用代理对象调用某个方法时,Spring事务才能生效,而在一个方法中调用使用this.xxx()调用方法时,this并不是代理对象,所以会导致事务失效。
    a. 解放办法1:把调用方法拆分到另外一个Bean中
    b. 解决办法2:自己注入自己
    c. 解决办法3:AopContext.currentProxy()+@EnableAspectJAutoProxy(exposeProxy = true)
  2. 方法是private的:Spring事务会基于CGLIB来进行AOP,而CGLIB会基于父子类来失效,子类是代理类,父类是被代理类,如果父类中的某个方法是private的,那么子类就没有办法重写它,也就没有办法额外增加Spring事务的逻辑。
  3. 方法是final的:原因和private是一样的,也是由于子类不能重写父类中的final的方法
  4. 单独的线程调用方法:当Mybatis或JdbcTemplate执行SQL时,会从ThreadLocal中去获取数据库连接对象,如果开启事务的线程和执行SQL的线程是同一个,那么就能拿到数据库连接对象,如果不是同一个线程,那就拿到不到数据库连接对象,这样,Mybatis或JdbcTemplate就会自己去新建一个数据库连接用来执行SQL,此数据库连接的autocommit为true,那么执行完SQL就会提交,后续再抛异常也就不能再回滚之前已经提交了的SQL了。
  5. 没加@Configuration注解:如果用SpringBoot基本没有这个问题,但是如果用的Spring,那么可能会有这个问题,这个问题的原因其实也是由于Mybatis或JdbcTemplate会从ThreadLocal中去获取数据库连接,但是ThreadLocal中存储的是一个MAP,MAP的key为DataSource对象,value为连接对象,而如果我们没有在AppConfig上添加@Configuration注解的话,会导致MAP中存的DataSource对象和Mybatis和JdbcTemplate中的DataSource对象不相等,从而也拿不到数据库连接,导致自己去创建数据库连接了。
  6. 异常被吃掉:如果Spring事务没有捕获到异常,那么也就不会回滚了,默认情况下Spring会捕获RuntimeException和Error。
  7. 类没有被Spring管理
  8. 数据库不支持事务

22.你是如何理解Spring事务的传播机制的?底层是如何实现的?

在这里插入图片描述
一个线程在运行过程中,可能会连续调用好几个方法,在调用某一个方法时,可能就开启了一个Spring事务,那么在调用接下来的方法时,到底是共用同一个事务呢?还是新开一个事务呢?这就是传播机制,程序员可以根据不同的业务场景进行配置,比如:
9. REQUIRED(Spring默认的事务传播类型):如果当前没有事务,则自己新建一个事务,如果当前存在事务,则加入这个事务
10. SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行
11. MANDATORY:当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。
12. REQUIRES_NEW:创建一个新事务,如果存在当前事务,则挂起该事务。
13. NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务
14. NEVER:不使用事务,如果当前事务存在,则抛出异常
15. NESTED:如果当前事务存在,则在嵌套事务中执行,否则和REQUIRED的操作一样(开启一个事务)

在Spring中,一个Spring事务就是对应一个数据库连接,新开一个Spring事务其实就是新开一个数据库连接,比如执行某个方法时需要开启一个Spring事务,那么就会创建一个数据库连接,然后开始执行方法,如果方法中调用了其他方法,此时就会看这个其他方法怎么配置的:
16. 比如是REQUIRES_NEW,那么就会新开一个数据库连接,这个其中方法中的sql就会在这个新开的数据库连接中执行
17. 比如是REQUIRED,那么就不会新开,而是基于之前的数据库连接来执行方法中的sql

23.Spring AOP是如何实现的?它和AspectJ有什么区别?

在这里插入图片描述
Spring AOP是利用的动态代理机制,如果一个Bean实现了接口,那么就会采用JDK动态代理来生成该接口的代理对象,如果一个Bean没有实现接口,那么就会采用CGLIB来生成当前类的一个代理对象。代理对象的作用就是代理原本的Bean对象,代理对象在执行某个方法时,会在该方法的基础上增加一些切面逻辑,使得我们可以利用AOP来实现一些诸如登录校验、权限控制、日志记录等统一功能。

Spring AOP和AspectJ之间并没有特别强的关系,AOP表示面向切面编程,这是一种思想,各个组织和个人都可以通过技术来实现这种思想,AspectJ就是其中之一,它会在编译期来对类进行增强,所以要用AspectJ,得用AspectJ开发的编译器来编译你的项目。而Spring AOP则是采用动态代理的方式来实现AOP,只不过觉得AspectJ中设计的那几个注解比较好,比如@Before、@After、@Around等,同时也不给程序员造成困扰,所以Spring AOP中会对这几个注解进行支持,虽然注解是相同的,但是底层的支持实现是完全不一样的。

24.@SpringBootApplication注解有什么用?为什么一定要写它?

@SpringBootApplication是一个复合注解:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {


}

是以上三个注解的整合,在一个类上只要加了@SpringBootApplication,就相当于同时加了以上的三个注解,当Spring容器在启动时,当解析到一个类上有@SpringBootApplication,那么就相当于这个类上有:

  1. @ComponentScan,从而Spring容器会进行扫描,扫描路径为当前在解析的这个类所在的包路径。
  2. @EnableAutoConfiguration,这个注解会负责进行自动配置类的导入,也就是将项目中的自动配置类导入到Spring容器中,从而得到解析
  3. @SpringBootConfiguration,它其实就相当于是@Configuration,表示当前类是一个配置类

所以,在使用SpringBoot时,我们一般会加上@SpringBootApplication这个注解,因为只要加上了它,SpringBoot就会进行扫描,就会导入自动配置类并解析解析。

25.你是如何理解SpringBoot中的自动配置的?

在Spring中,我们通常需要去配置很多的Bean:
● 比如用Mybatis,我们要配置SqlSessionFactory的Bean对象
● 用AOP,我们需要配置@EnableAspectJAutoProxy注解
● 用Spring事务,我们需要配置DataSourceTransactionManager的Bean对象
● 用RabbitMQ,我们要配置RabbitTemplate的Bean对象
● 等等

而我们用SpringBoot时,我们基本不用再去配这些了,因为SpringBoot帮我们配置好了,怎么做到的呢?其实就是SpringBoot内置了很多的配置类,比如

  1. RabbitAutoConfiguration
  2. AopAutoConfiguration
  3. ElasticsearchDataAutoConfiguration
  4. DataSourceTransactionManagerAutoConfiguration
  5. 等等
    内置的这些配置类,也可以叫做自动配置类,我们在依赖了spring-boot-starter-web后,会间接的依赖到spring-boot-autoconfigure这个jar,这个jar中都包含了很多的自动配置类:
    在这里插入图片描述
    这其实就是SpringBoot的自动配置,帮程序员提前配置了很多东西,Bean或者注解。

26.

27.

28.

29.

3

Logo

为武汉地区的开发者提供学习、交流和合作的平台。社区聚集了众多技术爱好者和专业人士,涵盖了多个领域,包括人工智能、大数据、云计算、区块链等。社区定期举办技术分享、培训和活动,为开发者提供更多的学习和交流机会。

更多推荐