2023-07面试题

1,spring中有哪些方式可以把bean注册进ioc容器?

①使用xml的方式声明bean的定义,spring容器在启动时会加载和解析这个xml,把bean装载进ioc容器中。

②使用@ComponentScan注解去扫描声明了@Controller @Service @Repository @Component注解的类,然后把这些类加载进ioc容器。

③使用@Configuration注解声明配置类,并使用@Bean注解实现bean的定义。这种方式是xml文件配置方式的演变。

④使用@Import注解,导入配置类或者普通的bean

⑤实现ImportSelector接口,动态批量注入配置类或者bean对象。这在springboot自动装配中也使用到。

 

2,spring bean的生命周期(实例化-->属性填充-->初始化-->销毁)

①解析类得到BeanDefinition。解析方法:比如@ComponentScan扫描注解,或者解析xml配置文件方式

②创建实例化对象。如果这个bean中有多个构造方法,默认使用无参构造创建bean,如果没有无参构造只有一个有参构造,则使用唯一的有参构造。如果有多个有参构造方法代码会报错。

③属性填充阶段。对象中加了@Autowired或者@Resource注解的属性进行填充。

④回调Aware方法,调用BeanPostProcessor初始化前的方法。

⑤调用初始化方法(需要实例化的对象中有需要初始化的属性)。调用初始化方法的2中方式:实现InitializingBean接口重写它的afterPropertiesSet方法;@PostConstruct注解标注的方法就是初始化的方法

⑥判断是否需要进行aop,如果实例化的对象中使用到了切面,这一步需要进行aop动态代理。

⑦将创建好的单例bean放入单例池

⑧使用bean

⑨spring容器关闭时调用destroy方法销毁

 

3,线程的生命周期有哪些?

创建,就绪,执行,阻塞(等待阻塞,同步阻塞,其他阻塞),死亡

 

4,OpenFeign调用原理

  1. 通过反射机制拿到当前代理类实现的接口XXXFeignApi
  2. 接口通过反射方式拿到接口上的注解@FeignClient(name = "product-service") 取出该注解中的值
  3. 通过反射拿到接口中的方法上面的注解 @GetMapping("product") 进行取出值
  4. 通过反射拿接口中方法参数注解 @RequestParam("pid")取出值
  5. 进行拼接路径 URL地址
  6. 根据服务的名字去注册中心去找到节点信息
  7. 根据你配置的负载均衡策略 选择一个节点
  8. 把路径中的服务名字替换掉ip:prot 信息
  9. 使用RestTemplat 取发送http 请求

 5,redis实现分布式锁

普通单体架构下synchronized同步锁就可以锁住资源了,但是在集群模式下,同步锁是JVM级别的,无法跨多个tomcat锁住资源,这个时候就需要使用到分布式锁了。

redis中setnx(key,value)方法可以实现,当一个setnx插入成功之后会返回true,如果再次插入相同的key则返回false。使用setnx方法当value没有值的时候返回true,当value有值的时候会插入失败并且返回false。

一个线程setnx成功之后就可以访问资源了,但是之后代码报错退出了,而setnx没有清空,导致后续请求进来无法获取锁,这就会导致死锁问题,所以使用setnx方法时必须要设置过期时间。

redisson实现了redis分布式锁

看门狗,默认每隔10s中去查看redis中的key是否在存在,如果存在则会将这个key进行续命,重新设置过期时间30s。

redis集群情况下,使用setnx也是会有问题的,因为setnx方法往redis集群中的master节点中写入数据,master写入完成后会返回,master同步数据到其他slave节点这是异步操作,有可能会出现问题导致数据不一致。redis主从集群只保证高可用,无法保证一致性。

解决方法:redlock,会往所有从节点的redis中同步setnx数据,只有当大部分从节点同步数据成功才会返回加锁成功。

 

posted @ 2023-07-17 22:31  故國神遊  阅读(25)  评论(0编辑  收藏  举报