说说类加载器双亲委派模型JVM中存在三个默认的类加载器
- BootstrapClassLoader
- ExtClassLoader
- AppClassLoader
AppClassLoader的父加载器是ExtClassLoader,ExtClassLoader的父加载器是BootstrapClassLoader。
JVM在加载一个类时,会调用AppClassLoader的loadClass方法来加载这个类,不过在这个方法中,会先使用ExtClassLoader的loadClass方法来加载类,同样ExtClassLoader的loadClass方法中会先使用BootstrapClassLoader来加载类,如果BootstrapClassLoader加载到了就直接成功,如果BootstrapClassLoader没有加载到,那么ExtClassLoader就会自己尝试加载该类,如果没有加载到,那么则会由AppClassLoader来加载这个类。
所以,双亲委派指得是,JVM在加载类时,会委派给Ext和Bootstrap进行加载,如果没加载到才由自己进行加载。
泛型中extends和super的区别
- <?extendsT>表示包括T在内的任何T的子类
- <?superT>表示包括T在内的任何T的父类
并发编程三要素?
- 原子性:不可分割的操作,多个步骤要保证同时成功或同时失败
- 有序性:程序执行的顺序和代码的顺序保持一致
- 可用性:一个线程对共享变量的修改,另一个线程能立马看到
简述CAP理论
CAP理论是分布式领域非常重要的一个理论,很多分布式中间件在实现时都需要遵守这个理论,其中:
- C表示一致性:指的的是分布式系统中的数据的一致性
- A表示可用性:表示分布式系统是否正常可用
- P表示分区容器性:表示分布式系统出现网络问题时的容错性
CAP理论是指,在分布式系统中不能同时保证C和A,也就是说在分布式系统中要么保证CP,要么保证AP,也就是一致性和可用性只能取其一,如果想要数据的一致性,那么就需要损失系统的可用性,如果需要系统高可用,那么就要损失系统的数据一致性,特指强一致性。CAP理论太过严格,在实际生产环境中更多的是使用BASE理论,BASE理论是指分布式系统不需要保证数据的强一致,只要做到最终一致,也不需要保证一直可用,保证基本可用即可。
图的深度遍历和广度遍历
- 图的深度优先遍历是指,从一个节点出发,一直沿着边向下深入去找节点,如果找不到了则返回上一层 找其他节点
- 图的广度优先遍历只是,从一个节点出发,向下先把第一层的节点遍历完,再去遍历第二层的节点,直 到遍历到最后一层
聊一聊快排算法
快速排序算法底层采用了分治法。
基本思想是:
- 先取出数列中的第一个数作为基准数
- 将数列中比基准数大的数全部放在它的右边,比基准数小的数全部放在它的左边
- 然后在对左右两部分重复第二步,直到各区间只有一个数
- Java版代码实现
public class QuickSort {
public static void quickSort(int[] arr, int low, int high) {
int i, j, temp, t;
if (low > high) {
return;
}
i = low;
j = high;
//temp就是基准位
temp = arr[low];
while (i < j) {
//先看右边,依次往左递减
while (temp <= arr[j] && i < j) {
j--;
}
//再看左边,依次往右递增
while (temp >= arr[i] && i < j) {
i ;
}
//如果满足条件则交换
if (i < j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[i];
arr[i] = temp;
//递归调用左半数组
quickSort(arr, low, j - 1);
//递归调用右半数组
quickSort(arr, j 1, high);
}
public static void main(String[] args) {
int[] arr = {10, 7, 2, 4, 7, 62, 3, 4, 2, 1, 8, 9, 19};
quickSort(arr, 0, arr.length - 1);
for (int i = 0; i < arr.length; i ) {
System.out.println(arr[i]);
}
}
TCP的三次握手和四次挥手
TCP协议是7层网络协议中的传输层协议,负责数据的可靠传输。
在建立TCP连接时,需要通过三次握手来建立,过程是:
- 客户端向服务端发送一个SYN
- 服务端接收到SYN后,给客户端发送一个SYN_ACK
- 客户端接收到SYN_ACK后,再给服务端发送一个ACK
在断开TCP连接时,需要通过四次挥手来断开,过程是:
- 客户端向服务端发送FIN
- 服务端接收FIN后,向客户端发送ACK,表示我接收到了断开连接的请求,客户端你可以不发数据了,不过服务端这边可能还有数据正在处理
- 服务端处理完所有数据后,向客户端发送FIN,表示服务端现在可以断开连接
- 客户端收到服务端的FIN,向服务端发送ACK,表示客户端也会断开连接了
消息队列如何保证消息可靠传输
消息可靠传输代表了两层意思,既不能多也不能少。
- 为了保证消息不多,也就是消息不能重复,也就是生产者不能重复生产消息,或者消费者不能重复消费消息
- 首先要确保消息不多发,这个不常出现,也比较难控制,因为如果出现了多发,很大的原因是生产者自己的原因,如果要避免出现问题,就需要在消费端做控制
- 要避免不重复消费,最保险的机制就是消费者实现幂等性,保证就算重复消费,也不会有问题,通过幂等性,也能解决生产者重复发送消息的问题
- 消息不能少,意思就是消息不能丢失,生产者发送的消息,消费者一定要能消费到,对于这个问题,就要考虑两个方面
- 生产者发送消息时,要确认broker确实收到并持久化了这条消息,比如RabbitMQ的confirm机制,Kafka的ack机制都可以保证生产者能正确的将消息发送给broker
- broker要等待消费者真正确认消费到了消息时才删除掉消息,这里通常就是消费端ack机制,消费者接收到一条消息后,如果确认没问题了,就可以给broker发送一个ack,broker接收到ack后才会删除消息
发散性思考题
画出项目架构图,介绍自己所处的模块
这里就需要大家在平时的工作中积极的去了解项目架构了。
好了本章到此结束,希望对你有所帮助,注学习顺利