面试复盘(赛意)

1.spingcloud 常用的组件

注册中心 eureka,nacos(常用),Consul,zookeeper

远程调用 dubbo(常用,rpc调用),openfeign(RESTful API调用)

网关 gateway

微服务保护 sentinel(常用),Hystrix

分布式事务 seata

2.spingcloud 原生的组件 

根据spring-cloud-alibaba-dependencies可以看到有openfeign,zookeeper,gateway

netflix是集成了网飞的一些组件有eureka。

ps:nacos和seata和sentinel都属于spring-cloud-alibaba,

dubbo也属于阿里但是不在spring-cloud-alibaba-dependencies中,使用需要额外在pom文件中引用。

Dubbo+Nacos+Sping-cloud-alibaba/Sentinel/Seata被阿里成为DNS。

3.自己理解的微服务 

随着业务的发展单体架构暴露出团队协作成本高(频繁的提交,拉取,合并代码),系统发布效率低(任何模块变更都需要发布整个系统,任何一处出现问题都会导致发布失败),系统可用性差(单体架构各个功能模块是作为一个服务部署,相互之间会互相影响,一些热点功能会耗尽系统资源,导致其它服务低可用)等问题。

微服务就是为了解决些问题。

由于服务拆分,每个服务代码量大大减少,参与开发的后台人员在1~3名,协作成本大大降低,解决了团队协作成本高的问题。

每个服务都是独立部署,当有某个服务有代码变更时,只需要打包部署该服务即可,解决了系统发布效率低的问题。

每个服务独立部署,并且做好服务隔离,使用自己的服务器资源,不会影响到其它服务,解决了系统可用性的问题。

4.mq了解吗

解构:系统不用去思考应该将消息发给谁,也不需要考虑是否调用成功和失败,直接将结果发送至队列,各个系统订阅该队列,需要什么数据自己去MQ中消费就行了。

异步:不需要等待下游系统返回结果,响应时间大大降低。

削峰:使用MQ后,可以将所有请求堆积在MQ中,有效的保护下游系统,并可控制好速率,供系统消费。不会出现大量请求同时请求导致系统卡顿,甚至直接不可用的情况。

5.rabbitmq怎么发送消息的

publisher(生产者)会将消息发送给exchange(交换机),exchange负责消息路由,将publisher发送的消息投递到对应的queue(队列queue负责存储消息,publisher投递的消息会暂存在queue中,等待consumer处理。

6.rabbitmq 三种订阅模式

广播:将消息交个所有绑定交换机的队列。

订阅:基于路由key发送给订阅看消息的队列。

通配符订阅:跟订阅类似,支持路由key使用通配符。

头匹配:基于mq的消息头匹配。

7.gatway作用

网关就是络的口。数据在网络间传输,从一个网络传输到另一网络时就需要经过网关来做数据的路由和转发以及数据安全的校验

8.熔断能用那些微服务的组件实现

 sentinel(常用),Hystrix

9.分布式的负载均衡

负载均衡分为服务器端负载均衡和客户端负载均衡。

服务器端负载均衡指的是存放在服务器端的负载均衡器,例如 Nginx、HAProxy、F5 等。

客户端负载均衡指的是嵌套在客户端的负载均衡器,例如 Ribbon。

常见的负载均衡策略有以下几个:

  1. 轮询(Round Robin):轮询策略按照顺序将每个新的请求分发给后端服务器,依次循环。这是一种最简单的负载均衡策略,适用于后端服务器的性能相近,且每个请求的处理时间大致相同的情况。
  2. 随机选择(Random):随机选择策略随机选择一个后端服务器来处理每个新的请求。这种策略适用于后端服务器性能相似,且每个请求的处理时间相近的情况,但不保证请求的分发是均匀的。
  3. 最少连接(Least Connections):最少连接策略将请求分发给当前连接数最少的后端服务器。这可以确保负载均衡在后端服务器的连接负载上均衡,但需要维护连接计数。
  4. IP 哈希(IP Hash):IP 哈希策略使用客户端的 IP 地址来计算哈希值,然后将请求发送到与哈希值对应的后端服务器。这种策略可用于确保来自同一客户端的请求都被发送到同一台后端服务器,适用于需要会话保持的情况。
  5. 加权轮询(Weighted Round Robin):加权轮询策略给每个后端服务器分配一个权重值,然后按照权重值比例来分发请求。这可以用来处理后端服务器性能不均衡的情况,将更多的请求分发给性能更高的服务器。
  6. 加权随机选择(Weighted Random):加权随机选择策略与加权轮询类似,但是按照权重值来随机选择后端服务器。这也可以用来处理后端服务器性能不均衡的情况,但是分发更随机。
  7. 最短响应时间(Least Response Time):最短响应时间策略会测量每个后端服务器的响应时间,并将请求发送到响应时间最短的服务器。这种策略可以确保客户端获得最快的响应,适用于要求低延迟的应用。

10.分布式事务

seata

11.seata怎么实现分布式事务的

Seata支持四种不同的分布式事务解决方案:

  • XA

  • TCC

  • AT

  • SAGA

XA:

一阶段:

  • 事务协调者通知每个事务参与者执行本地事务

  • 本地事务执行完成后报告事务执行状态给事务协调者,此时事务不提交,继续持有数据库锁

二阶段:

  • 事务协调者基于一阶段的报告来判断下一步操作

  • 如果一阶段都成功,则通知所有事务参与者,提交事务

  • 如果一阶段任意一个参与者失败,则通知所有事务参与者回滚事务

TA:

一阶段:

  • 事务协调者通知每个事务参与者执行本地事务

  • 本地事务执行完成后报告事务执行状态给事务协调者,并在执行前后记录undo-log(数据快照),此时事务提交,不再持有数据库锁。

二阶段:

  • 事务协调者基于一阶段的报告来判断下一步操作

  • 如果一阶段都成功,则通知所有事务参与者,删除undo-log

  • 如果一阶段任意一个参与者失败,则通知所有事务参与者根据undo-log恢复数据到更新前

TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。

TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。

RM (Resource Manager) - 资源管理器:管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。)

ps:简述AT模式与XA模式最大的区别是什么?

  • XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。

  • XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。

  • XA模式强一致;AT模式最终一致

12.mysql 数据库三范式

第一范式规定表中的每个列都应该是不可分割的最小单元。

第二范式是表中的非主键列不存在对主键的部分依赖。

第三范式是规定表中的列不存在对非主键列的传递依赖。

13.事务隔离级别

  • 读未提交(Read Uncommitted)
    1. 特点:最低的隔离级别,事务中的修改,即使未提交,也可以被其他事务读取到。
    2. 优点:并发性能最好,读取到的数据最新。
    3. 缺点:存在脏读(Dirty Read)问题,即读取到未提交的数据,可能导致数据不一致性。
  • 读已提交(Read Committed)
    1. 特点:保证事务读取到的数据都是已经提交的,其他事务提交的数据对该事务可见。
    2. 优点:避免了脏读的问题。
    3. 缺点:存在不可重复读(Non-Repeatable Read)问题,即同一个事务中,不同时间读取到的数据可能不一样。
  • 可重复读(Repeatable Read)
    1. 特点:保证同一个事务中,多次读取同一条记录时,读取到的数据都是一致的,MySQL 默认的事务隔离级别。
    2. 优点:避免了不可重复读的问题。
    3. 缺点:存在幻读(Phantom Read)问题,即在一个事务中,两次查询同一个范围的记录,但第二次查询却发现了新的记录。
  • 串行化(Serializable)
    1. 特点:最高的隔离级别,将所有的事务串行执行,保证了数据的完全隔离。
    2. 优点:避免了幻读的问题。
    3. 缺点:并发性能最差,可能导致大量的锁等待和死锁。

14.线程的常见方法 

sleep(x)一个参数时代表休眠x毫秒

sleep(x,y)两个参数时表示休眠x毫秒又y纳秒 

start()一个线程的开始,执行之后java虚拟机调用该线程的run方法

run()如果线程使用Runnable构造的,则它的调用run方法,否则不执行任何操作并返回

interrupt()中断调用方法的进程

interrupted()测试当前线程是否已被中断,此方法清除线程的中断状态 。 换句话说,如果连续两次调用此方法,则第二次调用将返回false(除非当前线程在第一次调用已清除其中断状态之后且在第二次调用检查之前再次中断)。
如果中断返回true,否则返回false

isInterrupted()测试此线程是否已被中断。 线程的中断状态不受此方法的影响。中断则返回true否则返回false

isAlive()测试此线程是否存活。 如果一个线程已经启动并且还没有死亡,它就是活着的。存活返回true否则返回false

join()
join(x)
join(x,y)
三种形式 第二种是等待x毫秒后醒来或者被唤醒后醒来 ,第三种是x毫秒y纳秒之后 如果x为0相当于一直沉睡,第一种方式就等于join(0)
join的底层源码可以发现是通过使用Object类中的wait()方法来实现的

15.线程的创建方式

继承 Thread 类来创建线程

通过实现 Runnable 接口来创建线程

实现 Callable 接口接口来创建线程

使用线程池来创建线程。

16.线程池的工作原理:

1、线程池在初始化的同时,会自动创建一定数量的线程,存放起来;

2、当手动调用execute()和submit()方法的时候,会主动将任务提交到线程池;

3、线程池会判断核心线程数量是否已满,如果已满,则查看线程队列是否已满,否则创建线程执行任务;

4、将任务添加到线程队列,如果线程队列已满,则判断线程池是否已满,否则加入任务队列等待执行;

5、判断线程池最大线程数量是否已满,如果已满则拒绝执行任务,否则创建线程执行任务。

17.object类的方法

1、 getClass():获取类的class对象。
2、 hashCode:获取对象的hashCode值
3、 equals():比较对象是否相等,比较的是值和地址,子类可重写以自定义。
4、 clone():克隆方法。
5、 toString():如果没有重写,应用对象将打印的是地址值。
6、 notify():随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态。该方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。
7、 notifyall():解除所有那些在该对象上调用wait方法的线程的阻塞状态。该方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。
8、 wait():导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒。该方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

18.方法重载和重写

重载是指在同一个类中定义多个方法,它们具有相同的名称但参数列表不同。

重写是子类中把父类本身有的方法重写了一遍,子类方法的参数与父类方法的参数相同。

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求,不能根据返回类型进行区分。

19.用过的反射

  1. Spring 中的依赖注入就是通过反射实现的。
  2. 数据库连接框架也会使用反射来实现调用不同类型的数据库(驱动)

20.什么是反射

在 Java 中,反射是指在运行时检查和操作类、接口、字段、方法等程序结构的能力。通过反射,可以在运行时获取类的信息,创建类的实例,调用类的方法,访问和修改类的字段等。

21.反射可以获得私有方法吗

可以,反射执行私有方法要执行setAccessible(true);

// 1.反射得到对象
Class<?> clazz = Class.forName("User");
// 2.得到方法
Method method = clazz.getDeclaredMethod("publicMethod");
// 得到私有方法
Method privateMethod = clazz.getDeclaredMethod("privateMethod");
// 设置私有方法可访问
privateMethod.setAccessible(true);
// 执行私有方法
privateMethod.invoke(clazz.getDeclaredConstructor().newInstance());

22.继承和实现

一个类只能继承一个抽象类,而一个类却可以实现多个接口。

23.泛型用过吗 

Java泛型是 JDK 5中引⼊的⼀个新特性, 允许在定义类和接口的时候使⽤类型参数。声明的类型参数在使⽤时⽤具体的类型来替换。
泛型最⼤的好处是可以提⾼代码的复⽤性。以List 接口为例,我们可以将 String Integer 等类型放⼊ List 中, 如不⽤泛型, 存放String 类型要写⼀个 List 接口, 存放 Integer 要写另外⼀个 List接口, 泛型可以很好的解决这个问题。

24.泛型不可以代指什么类型

都可以?


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值