java牛客面试刷题记录

说一下JUC

得分点 原子类、锁、线程池、并发容器、同步工具 标准回答 JUC是java.util.concurrent的缩写,这个包是JDK 1.5提供的并发包,包内主要提供了支持并发操作的各种工具。这些工具大致分为如下5类:原子类、锁、线程池、并发容器、同步工具。

  1. 原子类 从JDK 1.5开始,并发包下提供了atomic子包,这个包中的原子操作类提供了一种用法简单、性能高效、线程安全地更新一个变量的方式。在atomic包里一共提供了17个类,属于4种类型的原子更新方式,分别是原子更新基本类型、原子更新引用类型、原子更新属性、原子更新数组。
  2. 锁 从JDK 1.5开始,并发包中新增了Lock接口以及相关实现类用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显式地获取和释放锁。虽然它缺少了隐式获取释放锁的便捷性,但是却拥有了多种synchronized关键字所不具备的同步特性,包括:可中断地获取锁、非阻塞地获取锁、可超时地获取锁。
  3. 线程池 从JDK 1.5开始,并发包下新增了内置的线程池。其中,ThreadPoolExecutor类代表常规的线程池,而它的子类ScheduledThreadPoolExecutor对定时任务提供了支持,在子类中我们可以周期性地重复执行某个任务,也可以延迟若干时间再执行某个任务。此外,Executors是一个用于创建线程池的工具类,由于该类创建出来的是带有无界队列的线程池,所以在使用时要慎重。
  4. 并发容器 从JDK 1.5开始,并发包下新增了大量高效的并发的容器,这些容器按照实现机制可以分为三类。第一类是以降低锁粒度来提高并发性能的容器,它们的类名以Concurrent开头,如ConcurrentHashMap。第二类是采用写时复制技术实现的并发容器,它们的类名以CopyOnWrite开头,如CopyOnWriteArrayList。第三类是采用Lock实现的阻塞队列,内部创建两个Condition分别用于生产者和消费者的等待,这些类都实现了BlockingQueue接口,如ArrayBlockingQueue。
  5. 同步工具 从JDK 1.5开始,并发包下新增了几个有用的并发工具类,一样可以保证线程安全。其中,Semaphore类代表信号量,可以控制同时访问特定资源的线程数量;CountDownLatch类则允许一个或多个线程等待其他线程完成操作;CyclicBarrier可以让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会打开,所有被屏障拦截的线程才会继续运行。

spring Bean生命周期

bean的生命周期分为创建,初始化,调用,销毁

具体步骤如下

  1. spring启动,查找并加载需要被spring管理的bean,进行bean的实例化
  2. 为bean的属性设置值和对其他Bean的引用
  3. 将Bean的实例传递给Bean的前置处理器postProcessBeforeInitialization方法
  4. 调用Bean的初始化方法
  5. 将Bean的实例传递给Bean的后置处理器postProcessAfterInitialization方法
  6. 使用Bean
  7. 容器关闭时,调用Bean的销毁方法(destory-method)

自然排序

Comparable 接口中只提供了一个方法: compareTo(Object obj) ,该方法的返回值是 int 。如果返回值为正数,则表示当前对象(调用该方法的对象)比 obj 对象“大”;反之“小”;如果为零的话,则表示两对象相等。

springboot的起步依赖

stater配置,约定大于配置,springboot将日常企业应用研发中的场景都抽取出来,做成一个个的stater(启动器)stater整合了该场景下各种可能用到的依赖,用户只需要在Maven中引入stater依赖,springboot就能自动扫描到要加载的信息并启动响应默认的配置

以 spring-boot-starter-web 为例,它能够为提供 Web 开发场景所需要的几乎所有依赖,因此在使用 Spring Boot 开发 Web 项目时,只需要引入该 Starter 即可,而不需要额外导入 Web 服务器和其他的 Web 依赖。 加分回答 有时在引入starter时,我们并不需要指明版本(version),这是因为starter版本信息是由 spring-boot-starter-parent(版本仲裁中心) 统一控制的。

@Autowired和@Resource注解的区别

@Autowrited是spring提供的注解,@Resource是JDK提供的注解

@Autowrite只能按类型注入,@Resource默认按名称注入,也支持按类型注入

@Autowired按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值, 可以设置required属性为false,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。@Resource有俩重要属性,name和type。如果没有指定name属性,当注解标注再字段上,即默认的字段名作为bean名称寻找依赖,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象

Spring Boot常用的注解

@SpringbootApplication注解:它是springboot项目的核心注解,用于开启自动配置,是一个复核注解,由三个注解构成

@EnableAutoConfiguration注解:启用 启用 SpringBoot 的自动配置机制

@ComponentScan,用于扫描指定的包和组件。

@SpringBootConfiguration:声明当前类springboot应用的配置类,项目中只能有一个一般无须我们添加。

redis主从同步机制

全量复制

在slave从服务器初始化阶段,需要将master主服务器上所有的数据复制一份

  • 从服务器连接主服务器,并发送psync命令
  • 主服务器收到psync后,master将RDB 文件发送给slave,在此阶段内继续在缓冲区内写操作
  • slave在接收到RDB文件前,会将自身的数据全部丢弃,载入RDB
  • master发送完毕,会向slave的缓冲区发写入执行命令
  • slave完成对RDB的载入,开始接受命令请求,并执行缓冲区的命令

增量复制

在slave完成初始化后开始正常工作,master发生的写操作会同步到slave上

增量复制的话复制挤压缓存中数据,如果主节点offset差距过大,可能导致必须使用全量复制

spring的事务管理

Spring支持两种事务编程模型:

编程式事务 Spring提供了TransactionTemplate模板,利用该模板我们可以通过编程的方式实现事务管理,而无需关注资源获取、复用、释放、事务同步及异常处理等操作。相对于声明式事务来说,这种方式相对麻烦一些,但是好在更为灵活,我们可以将事务管理的范围控制的更为精确。

@Autowired
private PlatformTransactionManager transactionManager;

public void testTransaction() {

  TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
          try {
               // ....  业务代码
              transactionManager.commit(status);
          } catch (Exception e) {
              transactionManager.rollback(status);
          }
}

声明式事务 Spring事务管理的亮点在于声明式事务管理,它允许我们通过声明的方式,在IoC配置中指定事务的边界和事务属性,Spring会自动在指定的事务边界上应用事务属性。相对于编程式事务来说,这种方式十分的方便,只需要在需要做事务管理的方法上,增加@Transactional注解,以声明事务特征即可。

声明式事务管理是Spring事务管理的亮点,它允许我们通过声明的方式,在IoC配置中指定事务的边界和事务属性,Spring会自动在指定的事务边界上应用事务属性。相对于编程式事务来说,这种方式十分的方便,只需要在需要做事务管理的方法上,增加@Transactional注解,以声明事务特征即可。 加分回答 事务的打开、回滚和提交是由事务管理器来完成的,我们使用不同的数据库访问框架,就要使用与之对应的事务管理器。在Spring Boot中,当你添加了数据库访问框架的起步依赖时,它就会进行自动配置,即自动实例化正确的事务管理器。 对于声明式事务,是使用@Transactional进行标注的。这个注解可以标注在类或者方法上。 - 当它标注在类上时,代表这个类所有公共(public)非静态的方法都将启用事务功能。 - 当它标注在方法上时,代表这个方法将启用事务功能。 另外,在@Transactional注解上,我们可以使用isolation属性声明事务的隔离级别,使用propagation属性声明事务的传播机制。

@Transactional(propagation=propagation.PROPAGATION_REQUIRED)
public void aMethod {
  //do something
  B b = new B();
  C c = new C();
  b.bMethod();
  c.cMethod();
}

Spring 框架中,事务管理相关最重要的 3 个接口如下:

PlatformTransactionManager: (平台)事务管理器,Spring 事务策略的核心。
TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。
TransactionStatus:事务运行状态
我们可以把 PlatformTransactionManager 接口可以被看作是事务上层的管理者,而 TransactionDefinition 和 TransactionStatus 这两个接口可以看作是事务的描述。

PlatformTransactionManager 会根据 TransactionDefinition 的定义比如事务超时时间、隔离级别、传播行为等来进行事务管理 ,而 TransactionStatus 接口则提供了一些方法来获取事务相应的状态比如是否新事务、是否可以回滚等等。

Last modification:January 29, 2023
如果觉得我的文章对你有用,请随意赞赏