寫這篇主要是想復(fù)盤一下我的兩次面試經(jīng)歷,一個(gè)是B站的后端開發(fā)崗,另一個(gè)是百度的搜索研發(fā)。文章涵蓋了MySQL、Golang、 計(jì)算機(jī)網(wǎng)絡(luò)、Elasticsearch、 分布式、搜索的一些知識(shí)。
作者:郁南
1.你之前是負(fù)責(zé)搜索的,那我想聽一下你們搜索系統(tǒng)的大致流程
說(shuō)實(shí)在還挺驚訝面試官會(huì)問這個(gè)的,因?yàn)閷?duì)方是一個(gè)后端工程師,所以就沒講多細(xì)致,答得很general,大體來(lái)說(shuō)就是,query分析->粗排召回->精排算特征-> learning to rank計(jì)算score ->返回結(jié)果,每個(gè)再展開來(lái)說(shuō)一些即可。面試官問這個(gè)相當(dāng)于在問項(xiàng)目,確定簡(jiǎn)歷的真實(shí)性,所以這個(gè)沒啥參考價(jià)值。
2.MySQL的事務(wù)隔離級(jí)別有哪些?
總共是四大隔離級(jí)別,理解以后用自己的話答就好了
面試官還是比較滿意這個(gè)答案的,但接下來(lái)面試官問道:
3.以上事務(wù)隔離是如何實(shí)現(xiàn)的?
老實(shí)回答,這題我不會(huì),面試官提示MVCC,我還是不會(huì)hhh。回去翻了一些資料,在這里補(bǔ)充一下答案。所謂的MVCC就是MultipleVersion Concurrency Control,多版本并發(fā)控制,從名字上也可以看出來(lái),它是使用版本號(hào)來(lái)對(duì)數(shù)據(jù)進(jìn)行并發(fā)控制的。實(shí)際上,在數(shù)據(jù)表的每一列,都存儲(chǔ)兩個(gè)隱藏列,一個(gè)是trx_id,代表事務(wù)的ID,另一個(gè)是roll_pointer,指向其上一個(gè)版本的記錄,如此組成一個(gè)記錄的版本鏈,接下來(lái)就可以講ReadView了,它存儲(chǔ)著一種用來(lái)記錄當(dāng)前活躍狀態(tài)的讀寫事務(wù),用于判定該transaction可見到的數(shù)據(jù)版本。
4.MySQL索引的原理是什么?
B+樹,本質(zhì)上它是將瘦長(zhǎng)的平衡二叉樹,改造成一個(gè)矮扁的平衡多叉樹從而減少IO查詢次數(shù),平均查詢復(fù)雜度仍能保證O(logN),另外與B樹不同的是,除了葉子結(jié)點(diǎn)外,其他結(jié)點(diǎn)均不存儲(chǔ)數(shù)據(jù),另外葉子結(jié)點(diǎn)之間,用鏈表方式相連以加速查詢。當(dāng)然視面試官的反應(yīng),可以再補(bǔ)充B+樹的插入和刪除操作。
5.MySQL建立索引時(shí),應(yīng)該注意什么?
這個(gè)按照自己的經(jīng)驗(yàn)來(lái)回答了,三點(diǎn):1.對(duì)區(qū)分度高的列做索引, 對(duì)于那種只有兩三個(gè)值得索引并沒有多大意義。2.建立聯(lián)合索引時(shí)要滿足最左匹配原則,例如SELECT * FROM TABLE WHERE A=1 AND B=2 AND C=3,此時(shí)需要對(duì)ABC建聯(lián)合索引, 對(duì)ABC單獨(dú)建三個(gè)索引是沒用的。面試官又問,那我對(duì)BAC建聯(lián)合索引就命中不了索引了嗎?我說(shuō)是的,被面試官懟了一下,其實(shí)MySQL在很久以前就在查詢優(yōu)化器里加入了這個(gè)feature,是可以命中的。3.只對(duì)需要作為查詢條件的列建索引,否則會(huì)拖慢插入速度。
6.MySQL存儲(chǔ)引擎由哪些?他們有什么區(qū)別?應(yīng)用場(chǎng)景是怎樣的
也是一道經(jīng)典MySQL題了,主要分為Innodb和MyISAM,最主要的區(qū)別在于InnoDB采用的簇集索引,MyISAM采用的是非簇集索引。
對(duì)于非簇集索引來(lái)說(shuō),葉子結(jié)點(diǎn)存放的值實(shí)際上是data域的地址,data和 索引是完全分離的。
7.用戶從輸入U(xiǎn)RL到看到瀏覽器展示結(jié)果,經(jīng)過(guò)了哪些過(guò)程?越詳細(xì)越好。
8.redis的數(shù)據(jù)類型有哪些?在哪些場(chǎng)景使用?
string, set, list, hash dict, zset
string就是經(jīng)常用的key value鍵值對(duì);
hash dict可以表示一個(gè)對(duì)象,是一個(gè)field和value的映射表;
set就是集合,用hash來(lái)實(shí)現(xiàn)的;
list本質(zhì)上是個(gè)雙端隊(duì)列, 可以實(shí)現(xiàn)從左邊add也可以從右邊add
zset是有序集合, 用跳表來(lái)實(shí)現(xiàn),可以用來(lái)實(shí)現(xiàn)實(shí)時(shí)排行榜。
9.redis設(shè)置過(guò)期時(shí)間的原理是怎樣的?
這個(gè)我沒有看過(guò),但是我猜了兩種策略,給猜對(duì)了:1.惰性刪除,像限流器那樣,只有在get的時(shí)候去檢查它是否expire,如果過(guò)期,就刪除。2.定時(shí)刪除。 具體的我沒想對(duì),回去看了一下,官方給出的答案是這樣的:
Specifically this is what Redis does 10 times per second:
Test 20 random keys from the set of keys with an associated expire.
Delete all the keys found expired.
If more than 25% of keys were expired, start again from step 1.
也就是說(shuō),每秒做10次這樣的行為: 從所有設(shè)置過(guò)期時(shí)間的key中, 隨機(jī)選擇20個(gè)key,刪除所有過(guò)期的key, 如果25%的key都過(guò)期了,就回到步驟1再做一次。
10.你剛才提到了限流器,如何實(shí)現(xiàn)一個(gè)限流器?
限流器的原理就是令牌桶,按照一定的時(shí)間往桶里加入Token,如果桶已經(jīng)滿了丟棄令牌。每個(gè)新請(qǐng)求就消耗一個(gè)token, 如果token沒了就拒絕服務(wù)請(qǐng)求。新請(qǐng)求來(lái)臨時(shí),會(huì)請(qǐng)求從桶中拿走一個(gè)Token,如果沒有Token可拿了就阻塞或者拒絕服務(wù)請(qǐng)求,它的所有計(jì)算本質(zhì)上都是惰性計(jì)算。
11.Goroutine為什么這么輕?
簡(jiǎn)單來(lái)說(shuō),因?yàn)樗前l(fā)生在操作系統(tǒng)的用戶態(tài)的,不需要進(jìn)入內(nèi)核態(tài)進(jìn)行系統(tǒng)調(diào)用,操作系統(tǒng)的上下文切換會(huì)帶來(lái)很大的開銷,切g(shù)oroutine和線程一樣,共享堆,不共享?xiàng)!?/p>
Golang的垃圾回收是怎么做的?
很早之前看過(guò),剛好被問到了就回答得比較順利。三色并發(fā)標(biāo)記,基本思想是把內(nèi)存中的所有對(duì)象分為黑白灰三類,一開始所有對(duì)象都是白色對(duì)象,然后把所有可達(dá)對(duì)象標(biāo)記為灰色,再?gòu)乃谢疑珜?duì)象出發(fā),將所有觸及到的對(duì)象標(biāo)記為灰色,自身灰色標(biāo)記為黑色對(duì)象,如此循環(huán)往復(fù),直到?jīng)]有灰色對(duì)象為止,由于每次標(biāo)記剩下的都是不可達(dá)的白色對(duì)象,所以直接將白色對(duì)象刪除即可。
本文分享給需要面試刷題的朋友,也祝愿大家順利拿到自己想要的offer,這份資料主要包含了Java基礎(chǔ),數(shù)據(jù)結(jié)構(gòu),jvm,多線程等等,由于篇幅有限,以下只展示小部分面試題
有需要的伙伴可以關(guān)注、點(diǎn)贊、評(píng)論 私信回復(fù)我:“大廠”關(guān)鍵字,就可以拿到上述資料了!
]]>彥祖,都看到這了,點(diǎn)贊,收藏,叨叨一下扒~