【面试篇】牛客网面试总结
文章目錄
- 運(yùn)維
- etcd 如何保持高可用性
- 災(zāi)難恢復(fù)
- 腦裂問題
- mvcc
- 數(shù)組和鏈表的區(qū)別
- 優(yōu)化遍歷鏈表
- hash碰撞
- http rpc
- mongodb優(yōu)點(diǎn)
- gc
- 引用計(jì)數(shù)法的原理和優(yōu)缺點(diǎn)
- 極海channel
- 集群平滑部署
- RT突然高: JIT、 網(wǎng)絡(luò)抖動(dòng)、預(yù)熱
- 代碼28定律:
- 內(nèi)核態(tài)用戶態(tài)區(qū)別
- 大流量時(shí)如何啟動(dòng)集群
- 如何扛住流量洪峰
- 分布式事務(wù)實(shí)現(xiàn)及方案的優(yōu)缺點(diǎn)
- 如何保證redis所有的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)
- cpu順序執(zhí)行
- 死鎖
- 操作系統(tǒng)
- 如何查看進(jìn)程使用的線程數(shù)量?
運(yùn)維
etcd 如何保持高可用性
只有當(dāng)集群中多數(shù)節(jié)點(diǎn)正常的情況下,才可以進(jìn)行運(yùn)行時(shí)的配置管理。如果集群多數(shù)節(jié)點(diǎn)損壞,集群就失去了寫入數(shù)據(jù)的能力。官方推薦3,5,7為etcd cluster數(shù)目,其中7可以滿足大部分情況
通常情況下,如果是Follower節(jié)點(diǎn)宕機(jī),如果剩余可用節(jié)點(diǎn)數(shù)量超過半數(shù),集群可以幾乎沒有影響的正常工作。如果是Leader節(jié)點(diǎn)宕機(jī),那么Follower就收不到心跳而超時(shí),發(fā)起競選獲得投票,成為新一輪term的Leader,繼續(xù)為集群提供服務(wù)。
災(zāi)難恢復(fù)
當(dāng)集群超過半數(shù)的節(jié)點(diǎn)都失效時(shí),就需要通過手動(dòng)的方式,ectd提供了一套備份數(shù)據(jù)并無損重建cluster 的方法
- 備份數(shù)據(jù)到新機(jī)器
- 利用數(shù)據(jù)和 -force-new-cluster重新創(chuàng)建一個(gè)單node集群
- 修改peer url將其他節(jié)點(diǎn)加入
為了最大化集群的安全性,一旦有任何數(shù)據(jù)損壞或丟失的可能性,你就應(yīng)該把這個(gè)節(jié)點(diǎn)從集群中移除,然后加入一個(gè)不帶數(shù)據(jù)目錄的新節(jié)點(diǎn)。
腦裂問題
集群化的軟件總會(huì)提到腦裂問題,如ElasticSearch、Zookeeper集群,腦裂就是同一個(gè)集群中的不同節(jié)點(diǎn),對(duì)于集群的狀態(tài)有了不一樣的理解。
etcd 中有沒有腦裂問題?答案是:沒有
The majority side becomes the available cluster and the minority side is unavailable; there is no “split-brain” in etcd.
以網(wǎng)絡(luò)分區(qū)導(dǎo)致腦裂為例,一開始有5個(gè)節(jié)點(diǎn), Node 5 為 Leader
由于出現(xiàn)網(wǎng)絡(luò)故障,124 成為一個(gè)分區(qū),35 成為一個(gè)分區(qū), Node 5 的 leader 任期還沒結(jié)束的一段時(shí)間內(nèi),仍然認(rèn)為自己是當(dāng)前l(fā)eader,但是此時(shí)另外一邊的分區(qū),因?yàn)?24無法連接 5,于是選出了新的leader 1,網(wǎng)絡(luò)分區(qū)形成。
那么此時(shí)集群可能會(huì)出現(xiàn)一個(gè)短暫的「雙 Leader」?fàn)顟B(tài)
35分區(qū)是否可用?如果寫入了1而讀取了 5,是否會(huì)讀取舊數(shù)據(jù)(stale read)?
答:35分區(qū)屬于少數(shù)派,被認(rèn)為是異常節(jié)點(diǎn),無法執(zhí)行寫操作。寫入 1 的可以成功,并在網(wǎng)絡(luò)分區(qū)恢復(fù)后,35 因?yàn)槿纹谂f,會(huì)自動(dòng)成為 follower,異常期間的新數(shù)據(jù)也會(huì)從 1 同步給 35。
而 5 的讀請(qǐng)求也會(huì)失敗,etcd 通過ReadIndex、Lease read保證線性一致讀,即節(jié)點(diǎn)5在處理讀請(qǐng)求時(shí),首先需要與集群多數(shù)節(jié)點(diǎn)確認(rèn)自己依然是Leader并查詢 commit index,5做不到多數(shù)節(jié)點(diǎn)確認(rèn),因此讀失敗。
- 這不是一個(gè)長期運(yùn)行狀態(tài),維持時(shí)間不會(huì)超過一個(gè)投票周期
- etcd 也有 ReadIndex、 Leaseread 機(jī)制來解決這種狀態(tài)下的一致性語義問題
因此 etcd 不存在腦裂問題。線性一致讀的內(nèi)容下面會(huì)提到。
mvcc
每個(gè) revision 由 {mainID,subID} 唯一標(biāo)識(shí)
這個(gè)描述不算錯(cuò),但要看站在哪個(gè)位置。在數(shù)據(jù)庫領(lǐng)域,面對(duì)高并發(fā)環(huán)境下數(shù)據(jù)沖突的問題,業(yè)界常用的解決方案有兩種:
悲觀鎖,常見的實(shí)現(xiàn)有讀寫鎖(Read/Write Locks)、兩階段鎖(Two-Phase Locking)等
樂觀鎖,常見的實(shí)現(xiàn)有邏輯時(shí)鐘(Logical Clock)、MVCC(Multi-version Cocurrent Control)等
https://cloud.tencent.com/developer/article/1551687
數(shù)組和鏈表的區(qū)別
優(yōu)化遍歷鏈表
跳躍表
hash碰撞
鏈地址法、再hash法、開放地址法、簡歷公共溢出區(qū)等
http rpc
因?yàn)榱己玫膔pc調(diào)用是面向服務(wù)的封裝,針對(duì)服務(wù)的可用性和效率等都做了優(yōu)化。單純使用http調(diào)用則缺少了這些特性。
http(一般指1.1)是rpc調(diào)用的一種實(shí)現(xiàn),但是帶寬開銷比較大,也缺乏一些連接多路復(fù)用的能力,這在高并發(fā)系統(tǒng)中非常致命,還有其他若干缺陷暫且不表。
HTTP 2開銷低,也支持連接多路復(fù)用,很多rpc框架用這個(gè)協(xié)議打底衍生自己協(xié)議。
mongodb優(yōu)點(diǎn)
gc
引用計(jì)數(shù)法的原理和優(yōu)缺點(diǎn)
引用計(jì)數(shù)法(Reference Counting)比較簡單,對(duì)每一個(gè)對(duì)象保存一個(gè)整型的引用計(jì)數(shù)器屬性。用于記錄對(duì)象被引用的情況。
對(duì)于一個(gè)對(duì)象A,只要有任何一個(gè)對(duì)象引用了A,則A的引用計(jì)數(shù)器就加1;當(dāng)引用失效時(shí),引用計(jì)數(shù)器就減1。只要對(duì)象的引用計(jì)數(shù)器的值為0,即表示對(duì)象A不能在被使用,可進(jìn)行回收。
優(yōu)點(diǎn):
- 實(shí)現(xiàn)簡單,垃圾對(duì)象便于辨識(shí);判定效率高,回收沒有延遲性。
缺點(diǎn):
-
他需要單獨(dú)的字段存儲(chǔ)計(jì)數(shù)器,這樣的做法增加了存儲(chǔ)空間的開銷。
-
每次賦值都需要更新計(jì)數(shù)器,伴隨著加法和減法操作,這增加了時(shí)間開銷。
-
引用計(jì)數(shù)器還有一個(gè)嚴(yán)重的問題,即無法處理循環(huán)引用的問題,這是一條致命的缺陷,導(dǎo)致在Java回收的垃圾回收器中沒有使用這類算法。
Python的引用計(jì)數(shù)算法和實(shí)施方案
引用計(jì)數(shù)算法,是很多語言的資源回收選擇,例如因人工智能而大火的Python,它是同時(shí)支持引用計(jì)數(shù)和垃圾回收機(jī)制的。
具體哪種最優(yōu)是要看場景的,業(yè)界有大規(guī)模實(shí)踐中僅保留引用計(jì)數(shù)機(jī)制,以提高吞吐量的嘗試。
Java并沒有選擇引用計(jì)數(shù)是因?yàn)槠浯嬖谝粋€(gè)基本的難題,也就是很難處理循環(huán)引用關(guān)系。
Python是如何解決循環(huán)引用的?
手動(dòng)解除:很好理解,就是在合適的時(shí)機(jī),解除引用關(guān)系。
使用弱引用weakref,weakref是Python提供的標(biāo)準(zhǔn)庫,旨在解決循環(huán)引用問題。
極海channel
集群平滑部署
服務(wù)發(fā)現(xiàn)、心跳檢測(cè)、灰度發(fā)布、JIT預(yù)熱
服務(wù)發(fā)現(xiàn):基于zookeeper 主動(dòng)推拉的機(jī)制
緩存刷新
zk過半機(jī)制就算是成功了
grpc dobble 高效機(jī)制
io模型 同步異步阻塞非阻塞 適用場景,兩個(gè)階段 1.內(nèi)核態(tài)到用戶態(tài)過程 2.磁盤內(nèi)核之間的傳輸
0拷貝 內(nèi)核態(tài)用戶態(tài)
linux參數(shù) backlog netty源碼
RT突然高: JIT、 網(wǎng)絡(luò)抖動(dòng)、預(yù)熱
JIT 是 just in time 的縮寫, 也就是即時(shí)編譯編譯器。在運(yùn)行時(shí) JIT 會(huì)把翻譯過的機(jī)器碼保存起來,以備下次使用,因此從理論上來說,采用該 JIT 技術(shù)可以接近以前純編譯技術(shù)
java代碼執(zhí)行次數(shù)達(dá)到一定的闕值后, 會(huì)編譯成更底層的機(jī)器碼,執(zhí)行起來更加高效。
為什么應(yīng)用不啟動(dòng)的時(shí)候去做:考慮開銷:啟動(dòng)慢、文件大、編譯慢
避免jit對(duì)線上部署的影響,我們?cè)趩?dòng)的時(shí)候直接回放流量,觸發(fā)JIT機(jī)制,RT穩(wěn)定了再去放入線上的流量
代碼28定律:
20%的代碼屬于80%的調(diào)用
內(nèi)核態(tài)用戶態(tài)區(qū)別
很多時(shí)候數(shù)據(jù)要加載到內(nèi)核態(tài),再到用戶態(tài)你才能去操作,0拷貝的過程 優(yōu)化
大流量時(shí)如何啟動(dòng)集群
先把負(fù)載關(guān)了,啟動(dòng)各個(gè)服務(wù)集群,緩存、CDN預(yù)熱
如何扛住流量洪峰
CDN緩存,能扛住80-90%流量
集群,橫向擴(kuò)展機(jī)器
限流、服務(wù)之間熔斷降級(jí)做好
異地多活、多機(jī)房冗災(zāi)策略
分布式事務(wù)實(shí)現(xiàn)及方案的優(yōu)缺點(diǎn)
分布式事務(wù)消息 類似于協(xié)調(diào)者 有半提交的狀態(tài),去做統(tǒng)一的提交或者回滾
二階段提交過程是阻塞的,系統(tǒng)的吞吐量其實(shí)不高
避免分布式事務(wù),進(jìn)事務(wù)的提交
調(diào)遠(yuǎn)端的事物提交,1.調(diào)用超時(shí) 2.提交失敗
1.提交失敗,數(shù)據(jù)都保持一致
2.超時(shí):多節(jié)點(diǎn)、多鏈路超時(shí)情況:超時(shí)我會(huì)發(fā)一個(gè)消息(可以不斷重試,保證消息發(fā)送成功),多個(gè)節(jié)點(diǎn)監(jiān)聽這個(gè)消息,根據(jù)這個(gè)消息去監(jiān)聽事務(wù)是否回滾,每個(gè)節(jié)點(diǎn)提交事務(wù)都都需要記錄流水號(hào),因?yàn)槌瑫r(shí)狀態(tài)遠(yuǎn)端的節(jié)點(diǎn)不知道事務(wù)是否提交,你根據(jù)這個(gè)流水號(hào)判斷節(jié)點(diǎn)是否消費(fèi),遠(yuǎn)程調(diào)用是否成功。
沒有執(zhí)行成功,忽略消息,有執(zhí)行成功,做事務(wù)回滾
如何保證redis所有的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)
redis 內(nèi)存數(shù)據(jù)集大小上升到一定大小的時(shí)候,就會(huì)施行數(shù)據(jù)淘汰策略。redis 提供 6種數(shù)據(jù)淘汰策略:
volatile-lru:從已設(shè)置過期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選最近最少使用的數(shù)據(jù)淘汰
volatile-ttl:從已設(shè)置過期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選將要過期的數(shù)據(jù)淘汰
volatile-random:從已設(shè)置過期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中任意選擇數(shù)據(jù)淘汰
allkeys-lru:從數(shù)據(jù)集(server.db[i].dict)中挑選最近最少使用的數(shù)據(jù)淘汰
allkeys-random:從數(shù)據(jù)集(server.db[i].dict)中任意選擇數(shù)據(jù)淘汰
no-enviction(驅(qū)逐):禁止驅(qū)逐數(shù)據(jù)
LRU算法,淘汰策略默認(rèn)volatile-lru
redis test:0>config get maxmemory-policy 1) maxmemory-policy 2) volatile-lrucpu順序執(zhí)行
亂序優(yōu)化在一定程度上可以提高程序的運(yùn)行速度
為了提升執(zhí)行效率,CPU 會(huì)在不影響最終結(jié)果的情況下對(duì)指令進(jìn)行重排序
屏障技術(shù)
死鎖
發(fā)生情況
cpu利用率:
- 自旋鎖、cas操作,cpu利用率高
- 獲取不到、直接掛起,cpu利用率低
操作系統(tǒng)
如何查看進(jìn)程使用的線程數(shù)量?
方法2)cat /proc/4761(進(jìn)程ID)/status。如下圖所示:
總結(jié)
以上是生活随笔為你收集整理的【面试篇】牛客网面试总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 李文胜oracle,2014年下期解放学
- 下一篇: Java - 传参到底是哪种? pass