今日头条一面:十道经典面试题解析,我的腾讯 Java 面试经历分享
TCP 连接的客户端机:每一个 ip 可建立的 TCP 连接理论受限于 ip_local_port_range 参数,也受限于 65535。但可以通过配置多 ip 的方式来加大自己的建立连接的能力。
TCP 连接的服务器机:每一个监听的端口虽然理论值很大,但这个数字没有实际意义。最大并发数取决你的内存大小,每一条静止状态的 TCP 连接大约需要吃 3
.3K 的内存。
6.Eureka 原理,是否是强一致性,eureka 集群。宕机了服务还能调用么?Eureka 和 ZooKeeper 对比
6.1 eureka 架构
注册中心是分布式开发的核心组件之一,而 eureka 是 spring cloud 推荐的注册中心实现。
架构图如下:
Eureka Server:提供服务注册和发现,多个 Eureka Server 之间会同步数据,做到状态一致
Service Provider:服务提供方,将自身服务注册到 Eureka,从而使服务消费方能够找到
Service Consumer:服务消费方,从 Eureka 获取注册服务列表,从而能够消费服务
6.2 基于集群的 Eureka 架构图
Eureka server 可以集群部署,多个节点之间会通过 Replicate(异步方式)进行数据同步,保证数据最终一致性。Eureka Server 作为一个开箱即用的服务注册中心,提供的功能包括:服务注册、接收服务心跳、服务剔除、服务下线等。
服务启动后向 Eureka 注册,Eureka Server 会将注册信息向其他 Eureka Server 进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。
6.3 宕机了服务还能调用么?
Eureka 挂了,微服务是可以调通的,不过有个前提:provider 的地址没变!如果 provider 换了一个 IP 地址或者端口,这个时候,consumer 就无法及时感知到这种变化,就会调不通。
6.4 Eureka 和 ZooKeeper 对比
Zookeeper 保证 CP(一致性和分区容错性),但是不保证可用性,ZK 的 leader 选举期间,是不可用的。
Eureka 保证 AP(可用性和分区容错性),它优先保证可用性,几个节点挂掉不会影响正常节点的工作。
7.Hystrix 了解嘛?说说 Hystrix 的工作原理
Hystrix 工作流程图如下:
构建命令
Hystrix 提供了两个 Command, HystrixCommand 和 HystrixObservableCommand,可以使用这两个对象来包裹待执行的任务。
执行命令
有四种方式执行 command。分别是:
R execute():同步执行,从依赖服务得到单一结果对象
Future queue():异步执行,返回一个 Future 以便获取执行结果,也是单一结果对象
Observable observe():hot observable,创建 Observable 后会订阅 Observable,可以返回多个结果
Observable toObservable():cold observable,返回一个 Observable,只有订阅时才会执行,可以返回多个结果
检查缓存
如果启用了 Hystrix Cache,任务执行前将先判断是否有相同命令执行的缓存。如果有则直接返回缓存的结果;如果没有缓存的结果,但启动了缓存,将缓存本次执行结果以供后续使用。
4.检查断路器是否打开 断路器(circuit-breaker)和保险丝类似,保险丝在发生危险时将会烧断以保护电路,而断路器可以在达到我们设定的阀值时触发短路(比如请求失败率达到 50%),拒绝执行任何请求。
如果断路器被打开,Hystrix 将不会执行命令,直接进入 Fallback 处理逻辑。
5.检查线程池/信号量情况 Hystrix 隔离方式有线程池隔离和信号量隔离。当使用 Hystrix 线程池时,Hystrix 默认为每个依赖服务分配 10 个线程,当 10 个线程都繁忙时,将拒绝执行命令。信号量同理。
6.执行具体的任务 通过 HystrixObservableCommand.construct() 或者 HystrixCommand.run() 来运行用户真正的任务。
7.计算链路健康情况 每次开始执行 command、结束执行 command 以及发生异常等情况时,都会记录执行情况,例如:成功、失败、拒绝以及超时等情况,会定期处理这些数据,再根据设定的条件来判断是否开启断路器。
8.命令失败时执行 Fallback 逻辑 在命令失败时执行用户指定的 Fallback 逻辑。上图中的断路、线程池拒绝、信号量拒绝、执行执行、执行超时都会进入 Fallback 处理。
9.返回执行结果 原始结果将以 Observable 形式返回,在返回给用户之前,会根据调用方式的不同做一些处理。
8.zookeeper 一致性保证,zab 协议原理,zookeeper 属于哪种一致性,强一致性么,还是最终一致性
Zab 协议,英文全称是 Zookeeper Atomic Broadcast(Zookeeper 原子广播)。Zookeeper 是通过 Zab 协议来保证分布式事务的最终一致性。
Zab 协议是为分布式协调服务 Zookeeper 专门设计的一种支持崩溃恢复的原子广播协议 ,是 Zookeeper 保证数据一致性的核心算法。Zab 借鉴了 Paxos 算法,是一种通用的分布式一致性算法。
基于 Zab 协议,Zookeeper 实现了一种主备模型(即 Leader 和 Follower 模型)的系统架构来保证集群中各个副本之间数据的一致性。就是指只有一台 Leader 节点负责处理外部的写事务请求,然后它(Leader)将数据同步到其他 Follower 节点。
Zookeeper 客户端会随机的链接到 zookeeper 集群中的一个节点,如果是读请求,就直接从当前节点中读取数据;如果是写请求,那么节点就会向 Leader 提交事务,Leader 接收到事务提交,会广播该事务,只要超过半数节点写入成功,该事务就会被提交。
Zab 协议要求每个 Leader 都要经历三个阶段:发现,同步,广播。
发现:要求 zookeeper 集群必须选举出一个 Leader 进程,同时 Leader 会维护一个 Follower 可用客户端列表。将来客户端可以和这些 Follower 节点进行通信。
同步:Leader 要负责将本身的数据与 Follower 完成同步,做到多副本存储。这样也是提现了 CAP 中的高可用和分区容错。Follower 将队列中未处理完的请求消费完成后,写入本地事务日志中。
广播:Leader 可以接受客户端新的事务 Proposal 请求,将新的 Proposal 请求广播给所有的 Follower。
9. 聊聊 zookeeper 选举机制
服务器启动或者服务器运行期间(Leader 挂了),都会进入 Leader 选举,我们来看一下~假设现在 ZooKeeper 集群有五台服务器,它们 myid 分别是服务器 1、2、3、4、5,如图:
9.1 服务器启动的 Leader 选举
zookeeper 集群初始化阶段,服务器(myid=1-5)依次启动,开始 zookeeper 选举 Leader~
服务器 1(myid=1)启动,当前只有一台服务器,无法完成 Leader 选举
服务器 2(myid=2)启动,此时两台服务器能够相互通讯,开始进入 Leader 选举阶段
2.1. 每个服务器发出一个投票
服务器 1 和服务器 2 都将自己作为 Leader 服务器进行投票,投票的基本元素包括:服务器的 myid 和 ZXID,我们以(myid,ZXID)形式表示。初始阶段,服务器 1 和服务器 2 都会投给自己,即服务器 1 的投票为(1,0),服务器 2 的投票为(2,0),然后各自将这个投票发给集群中的其他所有机器。
2.2 接受来自各个服务器的投票
每个服务器都会接受来自其他服务器的投票。同时,服务器会校验投票的有效性,是否本轮投票、是否来自 LOOKING 状态的服务器。
2.3. 处理投票
收到其他服务器的投票,会将被人的投票跟自己的投票 PK,PK 规则如下:
优先检查 ZXID。ZXID 比较大的服务器优先作为 leader。
如果 ZXID 相同的话,就比较 myid,myid 比较大的服务器作为 leader。
服务器 1 的投票是(1,0),它收到投票是(2,0),两者 zxid 都是 0,因为收到的 myid=2,大于自己的 myid=1,所以它更新自己的投票为(2,0),然后重新将投票发出去。对于服务器 2 呢,即不再需要更新自己的投票,把上一次的投票信息发出即可。
2.4. 统计投票
每次投票后,服务器会统计所有投票,判断是否有过半的机器接受到相同的投票信息。服务器 2 收到两票,少于 3(n/2+1,n 为总服务器),所以继续保持 LOOKING 状态
服务器 3(myid=3)启动,继续进入 Leader 选举阶段
3.1 跟前面流程一致,服务器 1 和 2 先投自己一票,因为服务器 3 的 myid 最大,所以大家把票改投给它。此时,服务器为 3 票(大于等于 n/2+1),所以服务器 3 当选为 Leader。 服务器 1,2 更改状态为 FOLLOWING,服务器 3 更改状态为 LEADING;
服务器 4 启动,发起一次选举。
4.1 此时服务器 1,2,3 已经不是 LOOKING 状态,不会更改选票信息。选票信息结果:服务器 3 为 3 票,服务器 4 为 1 票。服务器 4 并更改状态为 FOLLOWING;
服务器 5 启动,发起一次选举。
同理,服务器也是把票投给服务器 3,服务器 5 并更改状态为 FOLLOWING;
投票结束,服务器 3 当选为 Leader
9.2 服务器运行期间的 Leader 选举
zookeeper 集群的五台服务器(myid=1-5)正在运行中,突然某个瞬间,Leader 服务器 3 挂了,这时候便开始 Leader 选举~
![](https://img-blog.csdnimg.cn/img_convert/c8fc63ee55ea64cc034ca706a20e21d6.webp?x-oss-process=image/fo
rmat,png)
变更状态
Leader 服务器挂了之后,余下的非 Observer 服务器都会把自己的服务器状态更改为 LOOKING,然后开始进入 Leader 选举流程。
每个服务器发起投票
每个服务器都把票投给自己,因为是运行期间,所以每台服务器的 ZXID 可能不相同。假设服务 1,2,4,5 的 zxid 分别为 333,666,999,888,则分别产生投票(1,333),(2,666),(4,999)和(5,888),然后各自将这个投票发给集群中的其他所有机器。
接受来自各个服务器的投票
处理投票
投票规则是跟 Zookeeper 集群启动期间一致的,优先检查 ZXID,大的优先作为 Leader,所以显然服务器 zxid=999 具有优先权。
统计投票
改变服务器状态
10. 算法:给定一个字符串 s ,请你找出其中不含有重复字符的最长连续子字符串的长度。
可以使用滑动窗口实现,代码如下:
public int lengthOfLongestSubstring2(String s) {
评论