【面试篇】牛客网面试总结

运维

etcd 如何保持高可用性

只有当集群中多数节点正常的情况下,才可以进行运行时的配置管理。如果集群多数节点损坏,集群就失去了写入数据的能力。官方推荐3,5,7为etcd cluster数目,其中7可以满足大部分情况

通常情况下,如果是Follower节点宕机,如果剩余可用节点数量超过半数,集群可以几乎没有影响的正常工作。如果是Leader节点宕机,那么Follower就收不到心跳而超时,发起竞选获得投票,成为新一轮term的Leader,继续为集群提供服务。

灾难恢复

当集群超过半数的节点都失效时,就需要通过手动的方式,ectd提供了一套备份数据并无损重建cluster 的方法

  • 备份数据到新机器
  • 利用数据和 -force-new-cluster重新创建一个单node集群
  • 修改peer url将其他节点加入

为了最大化集群的安全性,一旦有任何数据损坏或丢失的可能性,你就应该把这个节点从集群中移除,然后加入一个不带数据目录的新节点。

脑裂问题

集群化的软件总会提到脑裂问题,如ElasticSearch、Zookeeper集群,脑裂就是同一个集群中的不同节点,对于集群的状态有了不一样的理解。

etcd 中有没有脑裂问题?答案是:没有

The majority side becomes the available cluster and the minority side is unavailable; there is no “split-brain” in etcd.
以网络分区导致脑裂为例,一开始有5个节点, Node 5 为 Leader

在这里插入图片描述

由于出现网络故障,124 成为一个分区,35 成为一个分区, Node 5 的 leader 任期还没结束的一段时间内,仍然认为自己是当前leader,但是此时另外一边的分区,因为124无法连接 5,于是选出了新的leader 1,网络分区形成。

那么此时集群可能会出现一个短暂的「双 Leader」状态

在这里插入图片描述

35分区是否可用?如果写入了1而读取了 5,是否会读取旧数据(stale read)?

答:35分区属于少数派,被认为是异常节点,无法执行写操作。写入 1 的可以成功,并在网络分区恢复后,35 因为任期旧,会自动成为 follower,异常期间的新数据也会从 1 同步给 35。

而 5 的读请求也会失败,etcd 通过ReadIndex、Lease read保证线性一致读,即节点5在处理读请求时,首先需要与集群多数节点确认自己依然是Leader并查询 commit index,5做不到多数节点确认,因此读失败。

  • 这不是一个长期运行状态,维持时间不会超过一个投票周期
  • etcd 也有 ReadIndex、 Leaseread 机制来解决这种状态下的一致性语义问题

因此 etcd 不存在脑裂问题。线性一致读的内容下面会提到。

mvcc

每个 revision 由 {mainID,subID} 唯一标识
这个描述不算错,但要看站在哪个位置。在数据库领域,面对高并发环境下数据冲突的问题,业界常用的解决方案有两种:

悲观锁,常见的实现有读写锁(Read/Write Locks)、两阶段锁(Two-Phase Locking)等
乐观锁,常见的实现有逻辑时钟(Logical Clock)、MVCC(Multi-version Cocurrent Control)等

https://cloud.tencent.com/developer/article/1551687

数组和链表的区别

在这里插入图片描述

优化遍历链表

跳跃表

hash碰撞

链地址法、再hash法、开放地址法、简历公共溢出区等

http rpc

因为良好的rpc调用是面向服务的封装,针对服务的可用性和效率等都做了优化。单纯使用http调用则缺少了这些特性。

http(一般指1.1)是rpc调用的一种实现,但是带宽开销比较大,也缺乏一些连接多路复用的能力,这在高并发系统中非常致命,还有其他若干缺陷暂且不表。

HTTP 2开销低,也支持连接多路复用,很多rpc框架用这个协议打底衍生自己协议。

mongodb优点

gc

引用计数法的原理和优缺点

引用计数法(Reference Counting)比较简单,对每一个对象保存一个整型的引用计数器属性。用于记录对象被引用的情况。
对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1;当引用失效时,引用计数器就减1。只要对象的引用计数器的值为0,即表示对象A不能在被使用,可进行回收。

优点:

  • 实现简单,垃圾对象便于辨识;判定效率高,回收没有延迟性。

缺点:

  • 他需要单独的字段存储计数器,这样的做法增加了存储空间的开销。

  • 每次赋值都需要更新计数器,伴随着加法和减法操作,这增加了时间开销。

  • 引用计数器还有一个严重的问题,即无法处理循环引用的问题,这是一条致命的缺陷,导致在Java回收的垃圾回收器中没有使用这类算法。

Python的引用计数算法和实施方案
引用计数算法,是很多语言的资源回收选择,例如因人工智能而大火的Python,它是同时支持引用计数和垃圾回收机制的。

具体哪种最优是要看场景的,业界有大规模实践中仅保留引用计数机制,以提高吞吐量的尝试。

Java并没有选择引用计数是因为其存在一个基本的难题,也就是很难处理循环引用关系。

Python是如何解决循环引用的?

手动解除:很好理解,就是在合适的时机,解除引用关系。

使用弱引用weakref,weakref是Python提供的标准库,旨在解决循环引用问题。

极海channel

集群平滑部署

服务发现、心跳检测、灰度发布、JIT预热

服务发现:基于zookeeper 主动推拉的机制

缓存刷新

zk过半机制就算是成功了

grpc dobble 高效机制

io模型 同步异步阻塞非阻塞 适用场景,两个阶段 1.内核态到用户态过程 2.磁盘内核之间的传输

0拷贝 内核态用户态

linux参数 backlog netty源码

RT突然高: JIT、 网络抖动、预热

JIT 是 just in time 的缩写, 也就是即时编译编译器。在运行时 JIT 会把翻译过的机器码保存起来,以备下次使用,因此从理论上来说,采用该 JIT 技术可以接近以前纯编译技术

java代码执行次数达到一定的阙值后, 会编译成更底层的机器码,执行起来更加高效。
为什么应用不启动的时候去做:考虑开销:启动慢、文件大、编译慢
避免jit对线上部署的影响,我们在启动的时候直接回放流量,触发JIT机制,RT稳定了再去放入线上的流量

代码28定律:

20%的代码属于80%的调用

内核态用户态区别

很多时候数据要加载到内核态,再到用户态你才能去操作,0拷贝的过程 优化

大流量时如何启动集群

先把负载关了,启动各个服务集群,缓存、CDN预热

如何扛住流量洪峰

CDN缓存,能扛住80-90%流量
集群,横向扩展机器
限流、服务之间熔断降级做好
异地多活、多机房冗灾策略

分布式事务实现及方案的优缺点

分布式事务消息 类似于协调者 有半提交的状态,去做统一的提交或者回滚

二阶段提交过程是阻塞的,系统的吞吐量其实不高

避免分布式事务,进事务的提交

调远端的事物提交,1.调用超时 2.提交失败

1.提交失败,数据都保持一致
2.超时:多节点、多链路超时情况:超时我会发一个消息(可以不断重试,保证消息发送成功),多个节点监听这个消息,根据这个消息去监听事务是否回滚,每个节点提交事务都都需要记录流水号,因为超时状态远端的节点不知道事务是否提交,你根据这个流水号判断节点是否消费,远程调用是否成功。

没有执行成功,忽略消息,有执行成功,做事务回滚

如何保证redis所有的数据都是热点数据

redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据

LRU算法,淘汰策略默认volatile-lru

redis test:0>config get maxmemory-policy
1) maxmemory-policy
2) volatile-lru

cpu顺序执行

乱序优化在一定程度上可以提高程序的运行速度
为了提升执行效率,CPU 会在不影响最终结果的情况下对指令进行重排序

屏障技术

死锁

发生情况

cpu利用率:

  • 自旋锁、cas操作,cpu利用率高
  • 获取不到、直接挂起,cpu利用率低

操作系统

如何查看进程使用的线程数量?

方法2)cat /proc/4761(进程ID)/status。如下图所示:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值