大厂 面经

1、分布式事务是怎么做的?用起来会存在什么问题?

         Seata的TCC模式

        优点:相比AT模式无需生成全局锁和数据快照,性能好

                   不依赖数据库事务,而是依赖于补偿操作,适用于非事务型数据库

        缺点:业务代码侵入,需要人工实现try,confirm,cancel这三个方法,实现复杂。

                   同时也要解决空回滚和业务悬挂问题。

2、分布式锁是用什么做的?

      分布式锁需要满足四个条件:互斥性,防止死锁,容错性,可重入性。

      用了redisson框架实现分布式锁,加锁和解锁用了LUA脚本实现了锁互斥,看门狗机制实现了锁续期,利用了redis发布和订阅机制实现了锁阻塞,同时也支持可重入锁。

加锁过程,第一个if判断锁是否存在,若锁不存在则新增锁,锁重入计数设置为1,设置锁过期时间,返回空值;若锁存在则再判断锁的唯一标识是否匹配,若匹配则表明当前加锁请求为锁重入请求,故锁重入计数+1,并重新设置锁过期时间,返回空值;若唯一标识不匹配则表明锁被其他线程占有,当前线程无权解他人的锁,返回锁剩余的过期时间。

3、RocketMQ怎么保证消息不丢失?

        分三个阶段来保证消息不丢失,一是producer发送消息阶段,采用同步发送,等待broker接收到消息后返回确认消息;消息发送失败或者超时则进行重试,默认重试三次;broker提供多个master,保持高可用。二是broker处理消息阶段,采用同步刷盘策略,等待刷盘成功才返回produceru一个成功消息;主从模式,支持同步双写。三是consumer消费消息阶段,消费者中实现逻辑确保消息在消费成功后,再发送确认消息给broker,当消息消费失败了,进行消费消息重试机制。

4、RocketMQ如何做到消息有序消费?

        RocketMQ保证消息的有序性分为了两种:一是全局有序,二是局部有序。全局有序是指创建一个topic,并且该topic下只有一个队列。适用于并发度不大,并且对消息要求严格一致性的场景下。而局部有序,适用于对性能比较高的场景,在设计层面上需要保证有序消息放在topic下的同一个队列即可。在代码实现上,RocketMQ在发送消息时,指定MessageSelector对象来保证有序消息发送到同一个队列即可。而消费消息也要保持有序性,RocketMQ的MessageListener回调函数提供了有序消费 MessageListenerOrderly消费模式和 并发消费MessageListenerConcurrently消费模式。为了保证有序消费,需要保证消费者注册 MessageListenerOrderly 的回调函数,来实现 顺序消费。

这两种消费方式都是使用线程池去消费消息,只不过在 MessageListenerOrderly 通过分布式锁和本地锁来保证同时只有一条线程去队列中消费数据,以此来保证顺序消费

但是使用了 MessageListenerOrderly 顺序消费会导致 两个问题:

  • 使用了锁,导致吞吐量下降
  • 前一个消息阻塞时,会导致后边消息都被阻塞。因此如果消息消费失败,要设置好最大重试。

而使用局部有序也存在一些问题,当出现broker发生宕机或者扩容时,队列数量就会发生变化,消息就会分到到不同的队列,这样就无法保证有序了。若可以容忍短暂的丢失消息有序,使用局部有序比较合适。

5、SpringCloud限流用的是哪个组件?Sentinel对于限流的策略有几种?

        Sentinel组件,快速失败使用到了滑动时间窗口计数算法,warm up使用到了令牌桶算法,排队等待使用到了漏桶算法。热点参数限流也用到了令牌桶算法。

6、SpringCloud的授权验证是在哪个组件上做的?

        SpringCloudGateway+SpringSecurity+OAuth2.0

7、对于SpringBoot,要做全局的异常拦截要怎么做?

        @RestControllerAdvice+@ExceptionHandler。全局异常处理类只需要在类上标注@RestControllerAdvice,并在处理相应异常的方法上使用@ExceptionHandler注解,写明处理哪个异常即可。如BindException,MethodArgumentNotValidException,MissingServletRequestParameterException。

8、Bean的生命周期?

9、类的生命周期?

  1. 加载,类被加载到虚拟机内存中,这个过程包括通过类的全限定名获取二进制字节流,将字节流转换为方法区的运行时数据结构,并在内存中生成代表该类的java.lang.Class对象。
  2. 验证、确保类的字节流符合虚拟机的要求,不会危害虚拟机自身的安全。这个过程包括文件格式验证、元数据验证、字节码验证和符号引用验证。
  3. 准备、为类的静态变量(即类变量)分配内存并设置默认初始值。
  4. 解析、将符号引用解析为直接引用。
  5. 初始化、对类变量进行初始化,这个过程会执行静态代码块和静态变量的赋值操作。如果存在父类,则父类会先进行初始化。
  6. 使用、类的使用包括直接引用和间接引用,直接引用会导致类的初始化,而间接引用如引用静态变量、定义类数组或引用常量不会引起类的初始化。
  7. 卸载、当类没有正在使用的实例且对应的ClassLoader被回收时,类会被卸载。这个过程包括在方法区中清空类信息。

10、Bean的作用域有哪些?

  • singleton:单例作用域,所有对该Bean的请求都返回同一个Bean实例。
  • prototype:原型作用域,每次请求时都创建一个新的Bean实例。
  • request:请求作用域,每个HTTP请求都会创建一个新的Bean实例,该Bean实例仅在当前请求内有效。
  • session:会话作用域,每个HTTP会话都会创建一个新的Bean实例,该Bean实例仅在当前会话内有效。
  • application:全局作用域,一个bean 定义对应于单个ServletContext 的生命周期。
  • websocket: HTTP WebSocket 作用域,一个bean 定义对应于单个websocket 的生命周期。

·11、@RestController的作用域是哪个?在里面定义一个成员变量是线程安全的吗?

        singleton单例,可修改的成员变量不是线程安全的,存在资源竞争问题,要想线程安全,可以增加@Scope("prototype"),或者使用ThreadLocal进行数据处理。

12、对于Bean的加载,它是串行还是并行的?

13、Bean初始化的时候调用内部的一个函数,这个函数使用哪个注解?

        @PostContract注解。

​Spring中初始化bean和销毁bean的时候执行某个方法:

  1. 第一种是:通过注解@PostConstruct  和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作。
  2. 第二种是:通过 在xml中定义init-method 和  destory-method方法。
  3. 第三种是: 通过bean实现InitializingBean和 DisposableBean接口,重写afterPropertiesSet()和destroy()方法。

14、@Autowired和@Resourece这两个注解有什么区别?

  • @Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
  • Autowired 默认的注入方式为byType(根据类型进行匹配),@Resource默认注入方式为 byName(根据名称进行匹配)。
  • 当一个接口存在多个实现类的情况下,@Autowired@Resource都需要通过名称才能正确匹配到对应的 Bean。Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称。
  • @Autowired 支持在构造函数、方法、字段和参数上使用。@Resource 主要用于字段和方法上的注入,不支持在构造函数或参数上使用。

15、Java里的抽象类是用来做什么的?

  • 提供抽象方法:抽象类可以包含一些没有具体实现的抽象方法,这些方法需要在子类中被实现。这使得抽象类能够定义类的基本行为,而具体的实现则由子类来完成。
  • 强制子类实现特定方法:通过在抽象类中定义抽象方法,强制子类必须实现这些方法,确保了子类具有相同的基本功能。
  • 提高代码的可维护性:使用抽象类可以更好地组织和管理类的层次结构,使代码更易于理解和维护。
  • 实现多态性:抽象类可以作为接口的一种替代方案,实现多态性。子类可以通过重写抽象类中的方法来提供不同的行为。

16、Mybatis-Plus定义一个字段自增。

        @TableField(update = "%s+1", updateStrategy = FieldStrategy.IGNORED),@Version

17、Mybatis-Plus定义一个索引

        @Index

18、Mybatis-Plus定义一个主键

        @TableId(type = IdType.AUTO)

19、MySQL的索引有哪些?

·        普通索引(NORMAL)唯一索引(UNIQUE)主键索引 (PRIMARY)组合索引  全文索引(FULLTEXT)

20、MySQL的事务隔离级别?

        读未提交、读已提交、可重复读、串行化。

21、可重复读还存在什么问题?怎么解决这个幻读?

        幻读问题。幻读是指在同一个事务中,前后两次查询相同的范围时,得到的结果不一致。

        MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」,但是它很大程度上避免幻读现象(并不是完全解决了),解决的方案有两种:

  • 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题。
  • 针对当前读(select ... for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,因为当执行 select ... for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。

22、MySQL锁的写法有几种?

        全局锁:flush tables with read lock

        表锁:lock table t_stu read / write

        行级锁:select ... lock in share mode / select ... for update

23、MySQL的内连接,左连接、右连接、外连接有什么区别?

  • left join(左连接):返回包括左表中的所有记录和右表中连接字段相等的记录。
  • right join(右连接):返回包括右表中的所有记录和左表中连接字段相等的记录。
  • inner join(内连接):只返回两个表中连接字段相等的行。
  • full join (全外连接):返回左右表中所有的记录和左右表中连接字段相等的记录。

24、MySQL的字符串类型有哪些?

  CHARVARCHARTEXTBLOB

  • 数据的最大可能长度:预估数据的最大长度,选择合理的数据类型以避免浪费空间或数据截断。
  • 查询性能需求:固定长度的CHAR更适合频繁搜索的场景,因为它的读取速度通常更快。
  • 数据的变动频率:如果数据内容变化频繁,选择VARCHAR可以减少对存储空间的浪费。
  • 存储大文本或二进制数据:对于需要存储大量文本或二进制数据的应用,应选择TEXT或BLOB类型。

25、Maven的pom.xml文件,包的依赖有冲突的时候,怎么解决?

  • 使用<dependencyManagement>统一管理依赖版本在父项目的pom.xml中使用。<dependencyManagement>元素可以统一管理项目中所有模块的依赖版本。这样,即使不同的模块引入了相同的依赖,也能保证使用的是统一的版本。
  •  排除特定依赖。如果你确定某个依赖(或其传递依赖)不需要或可能引起冲突,可以在引入依赖时使用<exclusions>标签显式排除这些依赖。
  • 直接声明依赖版本。直接在项目中声明需要使用的依赖版本可以覆盖传递依赖中的版本。Maven会根据“最近优先”原则使用最近声明的版本。
  • 使用mvn dependency:tree分析依赖树。使用mvn dependency:tree命令可以帮助你理解项目的依赖结构,识别哪些依赖可能会引起冲突。了解依赖树有助于决定采取哪种策略来解决冲突。

26、SpringBoot的starter是做什么用的?

在Spring Boot中,starter是一种用于简化依赖管理和配置的特殊类型的依赖项。它们是预先配置的一组依赖项,可以在项目中添加它们作为单个依赖项,而不需要显式地指定每个依赖项的版本。

starter的主要作用有以下几个方面:

  1. 自动配置:starter包含了一些自动配置的类和配置文件,可以根据项目的需要自动配置Spring Boot应用程序的各种组件,例如数据库、消息队列、Web服务等。这样,开发人员可以避免手动配置大量的组件,减少了开发和维护的工作量。

  2. 依赖管理:starter可以一次性引入多个相关的依赖项,这些依赖项都是为了支持某个特定的功能或功能集合而设计的。通过引入starter,开发人员可以省去手动添加每个依赖项的步骤,简化了依赖管理的过程。

  3. 约定优于配置:starter遵循了Spring Boot的约定优于配置的原则,提供了一种标准的配置方式,使得开发人员可以快速构建和部署应用程序。开发人员只需要按照starter的要求进行配置,即可获得默认的配置和功能。当项目需要定制化配置时,也可以通过覆盖默认配置来实现。

总之,Spring Boot的starter提供了一种简化依赖管理和配置的方式,使得开发人员可以更加方便地构建和部署应用程序。它提供了自动配置、依赖管理和约定优于配置等功能,减少了开发和维护的工作量,提高了开发效率和项目的可维护性。

27、@SpringBootApplication是哪几个注解的和?

        @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan这三个注解的和。

在Spring Boot中,启动类注解的作用是标识该类作为Spring Boot应用的入口点。通过使用启动类注解,Spring Boot能够自动配置和启动应用程序。启动类注解通常是@SpringBootApplication,该注解包含了@EnableAutoConfiguration和@ComponentScan注解。

@SpringBootApplication注解的作用如下:

  • @SpringAutoConfiguration:表明当前类是配置类。
  • @EnableAutoConfiguration:启用Spring Boot的自动配置机制,根据应用程序的类路径和依赖自动配置Spring的各种组件、第三方库和框架。

  • @ComponentScan:自动扫描当前包及其子包下的所有Spring组件,包括Controller、Service、Repository等。

通过这些注解,Spring Boot能够自动扫描和加载应用程序中的各个组件,并根据自动配置机制自动配置应用程序的运行环境,从而简化了开发和部署的过程。

28、如何自定义一个注解?

一.元注解

  • @Retention 指定注解的生命周期
  • @Retention(RetentionPolicy.SOURCE)
  • 其中Retention是一个枚举类
  • RetentionPolicy.SOURCE : 注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃(.java文件)
  • RetentionPolicy.CLASS :注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期(.class文件)
  • RetentionPolicy.RUNTIME: 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在(内存中的字节码)
  • @Target指定注解可以修饰的元素类型
  • @Target(ElementType.Field)
  • ElementType.ANNOTATION_TYPE - 标记的注解可以应用于注解类型。
  • ElementType.CONSTRUCTOR - 标记的注解可以应用于构造函数。
  • ElementType.FIELD - 标记的注解可以应用于字段或属性。
  • ElementType.LOCAL_VARIABLE - 标记的注解可以应用于局部变量。
  • ElementType.METHOD - 标记的注解可以应用于方法。
  • ElementType.PACKAGE - 标记的注解可以应用于包声明。
  • ElementType.PARAMETER - 标记的注解可以应用于方法的参数。
  • ElementType.TYPE - 标记的注解可以应用于类的任何元素。
  • @Documented
  • 指定注解会被JavaDoc工具提取成文档。默认情况下,JavaDoc是不包括文档的
  • @Inherited
  • 表示该注解会被子类继承,注意,仅针对类,成员属性、方法并不受此注释的影响。

二、格式: public @interface 注解名称 { [访问级别修饰符] [数据类型] 属性名() default 默认值; }

三、使用:用拦截器或者面向切面来使用注解

29、Java的锁有哪些?

        悲观锁、乐观锁、共享锁、独占锁、轻量级锁、重量级锁、偏向锁、自旋锁、可重入锁、公平锁、非公平锁、读写锁、互斥锁、同步锁、死锁、分段锁、锁粗化、锁消除。

CAS:乐观锁、自旋锁、轻量级锁

synchronized:悲观锁、独占锁、重量级锁、可重入锁、非公平锁、互斥锁、同步锁

Reentrantlock:悲观锁、独占锁、重量级锁、可重入锁、非公平锁、公平锁、互斥锁、同步锁

ReentrantReadWriteLock:读写锁、共享锁、独占锁

30、各自哪些场景用了哪些锁?

悲观锁适合写多读少的场景、乐观锁适合读多写少的场景。共享锁适合读读共享、读写互斥。独占锁读写互斥、写写互斥。公平锁是多个线程按照申请锁的顺序来获取锁。非公平锁是线程尝试获取锁,如果获取不到,则再采用公平锁的方式。可重入锁是任意线程在获取到锁之后能够再次获取该锁而不会被锁所阻塞,一定程度上避免死锁。

31、synchronized修饰方法时锁的是类还是实例对象?

synchronized修饰普通方法时锁的是实例对象,修饰静态方法时锁的类。

32、实例化出两个对象,它们之间会互斥吗?

若是同一个线程访问两个对象的静态方法,因为锁的是类,这两个对象互斥。

若是同一个线程访问两个对象的普通方法,因为锁的是各自的对象,这两个对象不互斥。

33、Java创建线程有几种方式?

继承于Thread类、实现Runnable接口、实现Callable接口、使用线程池

34、启动jar包可以配置一些系统级别的参数,哪些参数可以设置呢?

35、-X有哪些参数?

  • -Xms设置初始堆大小
  • -Xmx设置最大堆大小
  • -Xss设置线程堆栈大小
  • -Xmn设置新生代大小

36、-Xms和-Xmx设置多少合适?

37、JVM如何调优?有什么方法?

38、对http协议熟悉吗?400代表什么?403?404?

  •  400表示客户端请求的报文有错误,但只是个笼统的错误。
  •  403表示服务器禁止访问资源,并不是客户端的请求出错。
  •  404表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。

39、Linux操作命令,如何看一个主机的负载?如何看内存的大小?如何看当前的磁盘空间?

        top、free -h 、df -h

40、docker常用的命令有哪些?

41、docker-compose如何启动

        docker-compose up -d

42、docker-compose如何定义一个网络?

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值