前言
??文章分兩部分敢会,第一部分做了一定的匯總和思路整理,第二部分記錄不同公司的面試記錄
(一)
1.問(wèn)題回答思路小結(jié)
1.場(chǎng)景題
?1)開(kāi)發(fā)方案設(shè)計(jì):
??講一下實(shí)現(xiàn)邏輯撮弧,選幾個(gè)點(diǎn)講一下實(shí)現(xiàn)細(xì)節(jié)
?2)線上生產(chǎn)問(wèn)題排查和優(yōu)化:
??第一步饲做,先講清楚臨時(shí)的解決方案,先把臨時(shí)出現(xiàn)的問(wèn)題搞定了
??第二步狼电,現(xiàn)場(chǎng)問(wèn)題解決完畢后蜒灰,講一下如何排查問(wèn)題發(fā)生原因,程序怎么優(yōu)化
2.講項(xiàng)目經(jīng)驗(yàn)
?1)簡(jiǎn)單介紹該項(xiàng)目的背景(別太啰嗦肩碟,面試官不愛(ài)聽(tīng)太復(fù)雜的背景)强窖,然后講清楚如何去完成它的,完成過(guò)程中的每一個(gè)要點(diǎn)削祈,要知道用了什么方法解決翅溺,講清楚為什么這樣做,邏輯要自洽
?2)講系統(tǒng)架構(gòu)髓抑,和代碼結(jié)構(gòu)咙崎,可以考慮結(jié)合領(lǐng)域模型來(lái)講
2.高頻問(wèn)題總結(jié)
高頻問(wèn)題領(lǐng)域:
分庫(kù)分表,讀寫(xiě)分離吨拍,數(shù)據(jù)一致性褪猛,高并發(fā),更新問(wèn)題等
1. 緩存的使用密末,原理握爷,常見(jiàn)異常跛璧,緩存和DB一致性問(wèn)題
- 應(yīng)用場(chǎng)景:高性能讀寫(xiě),代替DB承擔(dān)讀流量新啼,分布式鎖追城,或其他高性能的臨時(shí)性存儲(chǔ)場(chǎng)景
- 運(yùn)行機(jī)制:IO多路復(fù)用+單線程+純內(nèi)存操作+持久化
- 常見(jiàn)問(wèn)題:
- redis抖動(dòng)/網(wǎng)絡(luò)異常(運(yùn)維,監(jiān)控燥撞,哨兵座柱,主從)
- 大體積key
i. 問(wèn)題表現(xiàn):占用空間多,占用大量讀寫(xiě)流量
ii. 問(wèn)題解決:對(duì)象/集合拆分 - 熱點(diǎn)數(shù)據(jù)
i. 問(wèn)題表現(xiàn):不同應(yīng)用競(jìng)爭(zhēng)流量物舒,影響性能
ii. 問(wèn)題解決:1.使用本地內(nèi)存緩存色洞;2.待補(bǔ)充 - 與DB數(shù)據(jù)一致性問(wèn)題
i. 雙寫(xiě),先寫(xiě)db再刪key
ii. redis根據(jù)風(fēng)險(xiǎn)設(shè)置過(guò)期時(shí)間冠胯,注意過(guò)期時(shí)間需要加隨機(jī)值火诸,避免大面積同時(shí)過(guò)期
iii. 定時(shí)任務(wù),定時(shí)從DB掃描最近一段時(shí)間的update情況荠察,主動(dòng)更新到redis
iv. 應(yīng)用寫(xiě)的時(shí)候只關(guān)心寫(xiě)DB置蜀,然后在DB端主動(dòng)寫(xiě)入到redis,然后應(yīng)用端從redis讀(DB寫(xiě)入redis的方法待補(bǔ)充) - 緩存穿透
請(qǐng)求合法性檢查 + 空值緩存 - 緩存并發(fā)
分布式鎖 - 緩存雪崩
key加隨機(jī)過(guò)期時(shí)間
2. 消息中間件(主要是KAFKA)
- 應(yīng)用場(chǎng)景:削峰填谷悉盆,跨模塊數(shù)據(jù)同步與解耦盯荤,分布式數(shù)據(jù)一致性補(bǔ)償工具
- 運(yùn)行機(jī)制:使用zk作為集群管理,topic的多分區(qū)主從冗余焕盟,磁盤(pán)持久化等
- 常見(jiàn)問(wèn)題:
- 消息丟失
- 消費(fèi)者不會(huì)丟消息秋秤,因?yàn)橛術(shù)roup和ack作為消費(fèi)保證
- 生產(chǎn)者可能會(huì)丟消息,宕機(jī)或crush等脚翘,發(fā)送消息前將數(shù)據(jù)保存到DB
a) 可以設(shè)置一個(gè)發(fā)送狀態(tài)灼卢,定時(shí)任務(wù)掃描發(fā)送失敗的數(shù)據(jù)重發(fā)
b) 提供一個(gè)檢索接口,下游服務(wù)主動(dòng)檢查到消息丟失堰怨,通過(guò)檢索接口重新獲取
- 消息堆積
- 基本思路:消息堆積算生產(chǎn)問(wèn)題芥玉,先從臨時(shí)解決堆積問(wèn)題開(kāi)始,然后再考慮代碼優(yōu)化問(wèn)題
- 消費(fèi)者擴(kuò)容备图,臨時(shí)加強(qiáng)消費(fèi)能力
- 查看代碼邏輯灿巧,查看系統(tǒng)運(yùn)維信息,看看堆積消息的時(shí)間段發(fā)生了什么
a) 可能的原因:消費(fèi)者消費(fèi)慢揽涮,DB請(qǐng)求打滿了抠藕,長(zhǎng)事務(wù)多導(dǎo)致DB響應(yīng)慢,消費(fèi)者在消費(fèi)事務(wù)中是否涉及RPC蒋困,等等
- 消息冪等
- 生產(chǎn)者端的通用性冪等(就是防重發(fā))盾似,每個(gè)生產(chǎn)者被分配了一個(gè)productId,加上消息默認(rèn)內(nèi)置一個(gè)序列號(hào),在生產(chǎn)者和kafka之間雙端同步零院,以此防重
- 消費(fèi)者端溉跃,可能是業(yè)務(wù)上或者程序上重復(fù)發(fā),通過(guò)唯一索引防重
- 消息的消費(fèi)順序保證
- 基本思路:同一個(gè)分區(qū)只能被一個(gè)消費(fèi)者消費(fèi)
- 基于1)告抄,設(shè)置分區(qū)參數(shù)與消費(fèi)者集群size相等撰茎,保證一分區(qū)對(duì)應(yīng)一消費(fèi)者成員
- 基于2)可以一個(gè)消費(fèi)者成員對(duì)應(yīng)多個(gè)分區(qū),只需要保證一個(gè)分區(qū)對(duì)應(yīng)一個(gè)消費(fèi)者成員即可
- 消息丟失
3. 數(shù)據(jù)庫(kù)問(wèn)題
- 索引
- 索引設(shè)置
- 索引命中(生效問(wèn)題打洼,枚舉列問(wèn)題龄糊,最左原則,注意最左原則沒(méi)有條件的順序問(wèn)題募疮,優(yōu)化引擎會(huì)進(jìn)行檢索計(jì)劃的優(yōu)化炫惩,只需要命中了最左邊的索引即可)
- 索引對(duì)于性能的影響(加強(qiáng)讀性能,但造成了寫(xiě)放大)
- 索引結(jié)構(gòu)(B+樹(shù)阿浓,聚簇索引與非聚簇索引他嚷,回表問(wèn)題)
- 分庫(kù)分表
- 分庫(kù)分表要基于業(yè)務(wù)場(chǎng)景和需求來(lái)談,比如說(shuō)分訂單表搔扁,最簡(jiǎn)單的按用戶分爸舒,按商家分蟋字,等等思路稿蹲,然后為了適應(yīng)需求將訂單冗余3份,比如說(shuō)買(mǎi)家表存一份鹊奖,商家表存一份苛聘,最后運(yùn)營(yíng)存一份
- 比如說(shuō)分用戶表,可以按地區(qū)分忠聚,或者單純按用戶ID哈希分设哗,等等
- 哈希分表保證均勻,然后為了適配讀的需求做冗余两蟀,參考1)
- 悲觀鎖和樂(lè)觀鎖
4. 讀寫(xiě)分離网梢,多用于分散負(fù)載,通過(guò)主從或者別的什么方式赂毯,將寫(xiě)的節(jié)點(diǎn)和讀的節(jié)點(diǎn)分離開(kāi)
5. 跨系統(tǒng)數(shù)據(jù)一致性問(wèn)題
- 異常有限重試
- 定時(shí)任務(wù)重試
- MQ補(bǔ)償重試
6. DDD領(lǐng)域模型
7. 限流熔斷場(chǎng)景战虏,相關(guān)的實(shí)現(xiàn)方式
8. 分布式系統(tǒng)中,系統(tǒng)的分層怎么分党涕,分層的依據(jù)和考慮是什么烦感?
9. 業(yè)務(wù)服務(wù)中的分塊,基于什么標(biāo)準(zhǔn)膛堤,或者說(shuō)思想去分塊手趣?講講項(xiàng)目中分塊的現(xiàn)狀,想法和理由肥荔,聊聊你對(duì)業(yè)務(wù)分層的認(rèn)識(shí)
- 用自己系統(tǒng)的業(yè)務(wù)現(xiàn)狀作為基準(zhǔn)绿渣,聊聊怎么通過(guò)需求朝群,去區(qū)分業(yè)務(wù)領(lǐng)域的邊界,模塊的職能
- 基于A中符,再聊聊這樣分模塊之后潜圃,模塊之間的互動(dòng),最好可以說(shuō)出分塊的好處舟茶,和存在的問(wèn)題谭期,存在問(wèn)題能不能有更好的方法解決
- 結(jié)合對(duì)業(yè)務(wù)/系統(tǒng)一定的發(fā)展的預(yù)見(jiàn)性,來(lái)聊聊這樣分塊是為了適應(yīng)怎樣的發(fā)展
3.病發(fā)編程筆記
- 線程的先后執(zhí)行等待:最簡(jiǎn)單的方法用join就行吧凉;
- 線程一等多隧出,CountDownLatch,等計(jì)數(shù)到 0 的時(shí)候阀捅,調(diào)用await方法等待的線程會(huì)被喚醒胀瞪;
- 多個(gè)線程在某個(gè)節(jié)點(diǎn)等待同步執(zhí)行,CyclicBarrier饲鄙,多個(gè)線程執(zhí)行await的點(diǎn)會(huì)等待凄诞,等計(jì)數(shù)器到 0 時(shí)會(huì)全部往下執(zhí)行
- 多個(gè)線程占用有限資源,Semaphore信號(hào)量忍级,當(dāng)信號(hào)量計(jì)數(shù)器為 0 帆谍,則后續(xù)申請(qǐng)的線程會(huì)被阻塞,直到有別的線程釋放資源
- 異步獲得返回結(jié)果轴咱,F(xiàn)utureTask+Callable
- sleep 是thread類靜態(tài)方法汛蝙,不會(huì)釋放鎖而是阻塞等待
wait是對(duì)象的方法,會(huì)釋放鎖朴肺,只能在sync代碼塊內(nèi)使用(同理notify也是)
4.階段性面試小結(jié)
- 工作中常用的設(shè)計(jì)模式窖剑,不能是下意識(shí)地覺(jué)得這個(gè)場(chǎng)景可以用,應(yīng)該是可以清晰地說(shuō)明為什么這個(gè)場(chǎng)景會(huì)用設(shè)計(jì)模式戈稿,用了有什么好處西土,最好可以說(shuō)出別的設(shè)計(jì)模式其實(shí)也可以代替,只是因?yàn)槭裁丛颍▊€(gè)人習(xí)慣鞍盗,個(gè)人喜好需了,領(lǐng)導(dǎo)喜好)而采用了現(xiàn)在的設(shè)計(jì)模式
- JUC包詳細(xì)再?gòu)?fù)習(xí)一遍,最好可以手?jǐn)]AQS
- 常用中間件(REDIS,KAFKA)橡疼,應(yīng)該對(duì)應(yīng)用中可能出現(xiàn)的異常情況有清楚的認(rèn)識(shí)援所,并對(duì)大部分的異常場(chǎng)景有對(duì)應(yīng)的解決/補(bǔ)償方案
5.限流熔斷設(shè)計(jì)方案
限流:
- 在入口配置一個(gè)filter作為統(tǒng)計(jì)
- 定義一個(gè)時(shí)間輪,時(shí)間輪可以用數(shù)組,根據(jù)用戶配置的限流時(shí)間單位(10秒,5分鐘,10分鐘等)配置,一般可以考慮以一個(gè)小時(shí)作為時(shí)間輪跨度,
比如說(shuō)配置為5分鐘為一個(gè)限流時(shí)間單位,那就創(chuàng)建一個(gè)60分鐘/5分鐘=12的長(zhǎng)度的數(shù)組 - 設(shè)置一個(gè)atomicInteger作為時(shí)間輪下標(biāo),通過(guò)一個(gè)timer作為計(jì)時(shí)觸發(fā)器,根據(jù)配置時(shí)間(5分鐘),每次下標(biāo)+1
- 數(shù)組里每個(gè)元素也是一個(gè)atomicInteger計(jì)數(shù)器,根據(jù)用戶配置的邊界值,當(dāng)前時(shí)間單位的計(jì)數(shù)器達(dá)到峰值后,后面進(jìn)入的請(qǐng)求都直接拋異常打回
熔斷:
??解釋原因:之所以有限流保護(hù)的同時(shí)還需要熔斷,是因?yàn)橄蘖饕矡o(wú)法完全保證安全,因?yàn)橛锌赡蹹B承擔(dān)的壓力過(guò)大,應(yīng)用與DB的交互遇到大量長(zhǎng)等待或者超時(shí),
同時(shí)另一個(gè)原因是可能熱點(diǎn)流量大量命中長(zhǎng)事務(wù),造成大量響應(yīng)慢甚至超時(shí),此時(shí)需要觸發(fā)熔斷保護(hù)系統(tǒng)
- 在限流的基礎(chǔ)上,給每一個(gè)進(jìn)入的請(qǐng)求添加一個(gè)監(jiān)視器,用一個(gè)集合保存這些監(jiān)視器,同時(shí)設(shè)置一個(gè)異常請(qǐng)求統(tǒng)計(jì)器
- 異常請(qǐng)求統(tǒng)計(jì)器會(huì)統(tǒng)計(jì)每一個(gè)返回異常的請(qǐng)求,統(tǒng)計(jì)數(shù)字考慮有超時(shí)淘汰策略(比如說(shuō)這一分鐘發(fā)生了10次異常請(qǐng)求,10分鐘后就減10淘汰這些過(guò)時(shí)統(tǒng)計(jì))
- 根據(jù)需求/配置,每當(dāng)集合中的監(jiān)視器size,或者異常統(tǒng)計(jì)器的異常數(shù)字超出了安全線,就馬上通知服務(wù)注冊(cè)中心將本應(yīng)用下線
- 待大量滯留的流量處理完畢后,重新通知服務(wù)注冊(cè)中心上線本應(yīng)用
6.算法相關(guān)
完全沒(méi)基礎(chǔ)或者全忘了的,去復(fù)習(xí)/學(xué)習(xí)大學(xué)教材的《數(shù)據(jù)結(jié)構(gòu)與算法》欣除,有基礎(chǔ)有印象的住拭,LeetCode上做easy和medium級(jí)別的題目,做個(gè)三五十題有感覺(jué)了,基本上大部分公司的一面二面沒(méi)什么問(wèn)題滔岳。