【面试篇】牛客网面试总结
文章目录
- 运维
- etcd 如何保持高可用性
- 灾难恢复
- 脑裂问题
- mvcc
- 数组和链表的区别
- 优化遍历链表
- hash碰撞
- http rpc
- mongodb优点
- gc
- 引用计数法的原理和优缺点
- 极海channel
- 集群平滑部署
- RT突然高: JIT、 网络抖动、预热
- 代码28定律:
- 内核态用户态区别
- 大流量时如何启动集群
- 如何扛住流量洪峰
- 分布式事务实现及方案的优缺点
- 如何保证redis所有的数据都是热点数据
- cpu顺序执行
- 死锁
- 操作系统
- 如何查看进程使用的线程数量?
运维
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。如下图所示:
【面试篇】牛客网面试总结相关推荐
- 【牛客网面试必刷TOP101】链表篇(一)
链表 一.前言 二.学习刷题网站 1.推荐的原因 三.刷题 <1>反转链表 递归法 <2>链表内指定区间反转 ①头插法 ②递归法 <3>链表中的节点每k个一组翻转 ...
- 牛客网面试高频题top100(11~20)
** 牛客网面试高频题top100(11~20 java实现) ** 11.跳台阶 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结 ...
- 牛客网面试高频题top100(1~10)
*牛客网面试高频题top100(1~10 java实现) 1.反转链表 描述: 给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表 ...
- 【百日冲大厂】第十篇,牛客网选择题+编程题井字棋+密码强度等级
前言: 大家好,我是良辰丫,刷题的第十篇,牛客网选择题+编程题井字棋+密码强度等级.
- 【百日冲大厂】第二篇,牛客网选择题+排序子序列+倒置字符串
前言: 大家好,我是良辰丫,今天是刷题的第二篇,牛客网选择题+排序子序列+倒置字符串,每天都去努力,每天都庆幸今天的自己比昨天的自己更优秀,加油,为理想而努力吧!!!
- python简单实践作业答案_python入门实践四:爬取牛客网面试专项练习题及答案
说明:个人练手python用. 操作系统:window10 x64 IDE:Pycharm 2017.2.2 Python版本:3.6.2 目标 牛客网是一个IT笔试面试的平台,提供了很多题库,今天我 ...
- 牛客网|面试必刷TOP101
BM42 用两个栈实现队列_牛客题霸_牛客网 (nowcoder.com) 由于栈是先进后出,队列是先进先出的,所以需要两个栈来倒来倒去 将数据都push进入 stack1,pop的时候将stack1 ...
- SQL日常练习2-进阶篇-牛客网
本文章目的: 在于对SQL系统化学习后,进行: 1,日常练习,巩固基础: 2,加深对SQL知识: 3,总结SQL相关知识体系: 4,或者某有朝一日能快速捡起相关SQL知识. 5,同时结尾附带有KES数 ...
- 【2020】超100篇牛客网Java面经高频知识点汇总
总觉得自己好像什么都会点,但是面试就被问得很懵逼,自己很菜就不再吐槽了 最近疯狂的在牛客刷面经,但是过目就忘了!!!所以分门别类的记录了一下高频的考点. 何为高频的考点?快速扫描了七八十篇面经后,再看 ...
最新文章
- 【面向对象编程】(3) 类之间的交互,依赖关系,关联关系
- mysql字符集相关问题_MySQL 字符集相关问题
- 不可不知的C#基础 1. -- Extension 扩展方法
- 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字
- CentOS 8安装JFrog Artifactory社区版解决方案
- React进阶—性能优化
- Chrome 渲染流水线演化的未来
- 用好href的target, base href
- Java并发编程之线程池ThreadPoolExecutor解析
- php遍历目录与文件夹的多种方法详解
- 关于码云的一些基本知识_关于葡萄酒,你必须知道的一些基础知识
- linux ps流程,Linux下PS命令详解 (转)
- 数码视讯Q1、Q5机顶盒线刷固件
- 根据前序序列和中序序列重建二叉树
- Operator学习笔记
- mybatis中大于小于号转义字符
- 游戏中数据库的设计、类的管理
- 使用Python播放MIDI音符
- Ubuntu22降版本
- Android 自定义控件之——画个老虎机来玩玩
热门文章
- 利用“顺丰速运”下发GuLoader恶意软件的风险分析
- letter-shell | 一个功能强大的嵌入式shell
- 工业自动控制过程中最好用SCADA软件推荐
- Amazon CloudFront CDN + s3 源站跨域配置
- 华为私有云的搭建方案_Kali linux 搭建私有云
- MySQL字符集(表情包)
- 盘点个人信息保护方面的那些认证
- [GXYCTF2019]BabySQli
- css小游戏,js小游戏,Flex Box青蛙、冒险游戏、设计模式游戏等
- Trimble Yuma超级掌上计算机实机感受