LOADING

加载过慢请开启缓存 浏览器默认开启

2024小米后端一面(二)

讲一下对于Nacos的理解

nacos是一个致力于发现、配置和管理微服务的开源平台,支持几乎所有主流类型的服务发现、配置和管理功能。Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。相当于Eureka+Config的组合

Nacos是支持AP还是CP

Nacos支持两种模式,也就是cp(一致性/分区容错性)和AP(可用性/分区容错性),默认情况下是AP模式,但是可以通过配置文件修改为CP模式

在CP模式下,Nacos会强调数据的一致性和分区容忍性,值得注意的是
在AP模式下,Nacos会强调服务的可用性和分区容忍性

Nacos使用AP是什么协议

Nacos使用的是Raft协议,Raft协议是一种强一致性的协议,它的特点是选举过程简单,只需要收到大多数节点的投票就可以当选,而且选举过程是有限的,不会出现无限期的选举,同时Raft协议还有一个特点就是日志复制,只有当日志复制成功后才会提交,这样就保证了数据的一致性

Nacos自研了一种AP分布式协议Distro,这是一种面向临时实例设计的分布式协议,其中保证了在某些Nacos节点宕机后,整个临时实例处理系统依旧可以正常工作,作为一种有状态的中间件应用的内嵌协议,Distro保证了各个Nacos节点对于海量注册请求的统一协调和存储

Nacos使用CP是什么协议

Nacos使用的是Paxos协议,Paxos协议是一种强一致性的协议,它的特点是选举过程复杂,需要经过两轮投票才能当选,同时选举过程是无限期的,直到选举出一个合适的节点为止,同时Paxos协议还有一个特点就是日志复制,只有当日志复制成功后才会提交,这样就保证了数据的一致性

Raft协议如何实现选举的

Raft协议的选举过程分为两个阶段,首先是选举阶段,然后是日志复制阶段
每个副本都有三种状态,分别是Follower、Candidate、Leader
其中Leader负责处理所有的客户端请求,并生成新的日志条目,Foller则接收并复制Leader的日志条目,Candidate则是用于选举Leader的状态
如果Leader挂掉了,某个节点会转化为Candidate状态,然后向其他所有节点发送投票请求消息,在这个过程中,每个节点都会有两个时间状态,election timeout和heartbeat time interval,真正的超时时间是在最小超时时间和最大超时时间之间随机产生的,当收到投票请求后,其他节点会根据请求中的候选人信息和自己的状态进行判断是否接收该请求,如果投票超过半数,则该节点成为Leader,然后向其他节点发送心跳消息,如果在election timeout时间内没有收到心跳消息,则会重新进入选举阶段
成为Leader后,开始日志复制阶段,Leader会向其他节点发送日志复制请求,其他节点接收到请求后,会将日志复制到自己的日志中,然后返回响应,当Leader收到超过半数的响应后,就会提交日志,然后向其他节点发送心跳消息,如果在heartbeat time interval时间内没有收到心跳消息,则会重新进入选举阶段

Distro协议底层原理

Distro 协议是 Nacos 对于临时实例数据开发的⼀致性协议。其数据存储在缓存中,并且会在启动时进行全量数据同步,并定期进行数据校验。
在 Distro 协议的设计思想下,每个 Distro 节点都可以接收到读写请求。所有的Distro协议的请求场景主要分为三种情况:

  1. 当该节点接收到属于该节点负责的实例的写请求时,直接写入。
  2. 当该节点接收到不属于该节点负责的实例的写请求时,将在集群内部路由,转发给对应的节点,从而完成读写。
  3. 当该节点接收到任何读请求时,都直接在本机查询并返回(因为所有实例都被同步到了每台机器上)。
    Distro 协议作为 Nacos 的内嵌临时实例⼀致性协议,保证了在分布式环境下每个节点上面的服务信息的状态都能够及时地通知其他节点,可以维持数十万量级服务实例的存储和⼀致性。

线程池的工作原理

通过一种叫做池化的技术的核心思想,主要是实现资源的复用,避免资源的重复创建和销毁带来的性能开销

算法:栈A元素乱序,利用一个栈B对A进行排序

public static void sort(Stack<Integer> stack){
    Stack<Integer> help = new Stack<>();
    while(!stack.isEmpty()){
        int cur = stack.pop();
        while(!help.isEmpty() && help.peek() < cur){
            stack.push(help.pop());
        }
        help.push(cur);
    }
    while(!help.isEmpty()){
        stack.push(help.pop());
    }
}

算法:给定一系列的时间戳,找出某一个月内出现两次以上的时间

// 时间戳转化为日期
public static String stampToDate(long time){
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = new Date(time);
    return simpleDateFormat.format(date);
}
// 将时间戳转化为日期,然后将日期转化为月份,然后将月份作为key,出现的次数作为value存入map中
public static void main(String[] args) {
    long[] time = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    Map<String, Integer> map = new HashMap<>();
    for (long l : time) {
        String date = stampToDate(l);
        String month = date.substring(0, 7);
        if (map.containsKey(month)) {
            map.put(month, map.get(month) + 1);
        } else {
            map.put(month, 1);
        }
    }
    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        if (entry.getValue() > 1) {
            System.out.println(entry.getKey());
        }
    }
}
本文作者:GWB
当前时间:2023-11-09 11:11:08
版权声明:本文由gwb原创,本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 国际许可协议。
转载请注明出处!