場景題:排行榜怎么設計?
刷到此貼的友友春招/暑期必上岸?。?!
鼠鼠在秋招的過程中多次被問到場景題,中大廠的考察頻率相當之高,一般會放在最后一個問題用來拖時間,也遇到過上來就問你怎么設計一個系統(tǒng)(面試官以此來決定后面對你的態(tài)度)。所以鼠鼠準備開這個場景題欄目,分享在秋招過程中遇到的場景題以及如何進行回答,感興趣和感覺有幫助的友友點個關(guān)注和贊吧,你們的點贊和關(guān)注是鼠鼠持續(xù)更新下去的最大動力?。?!
話不多說開啟今天的主題,排行榜設計吧?。。?/p>
排行榜是很常見的一個功能,在社交軟件、游戲等各種場景中都有應用,積分、點贊、禮物、戰(zhàn)績排名等各類排行榜功能,這些排行本質(zhì)都是基于計數(shù)進行排序的。不同的場景會有細微的設計差異,這里只講通用的排行榜系統(tǒng)該如何設計,遇到具體的場景再做細微的調(diào)整即可,就算在面試過程中只能答出本文所設計的通用排行榜,也足夠了,畢竟對于應屆生也只會考察到這個程度,面試是盡可能多的回答問題,很難追求所有問題都能回答出來……
大家可能看過一些八股文,會回答直接使用zset進行試試排行即可。
鼠鼠也曾在面試中這樣回答過:將每個用戶的得分作為zset中元素的score,將用戶ID作為元素的value。使用zset提供的排序功能,可以按照分數(shù)從高到低排序。
當時面試官說如果分數(shù)相同,按照默認的排序規(guī)則會按照value值排序,他希望按照時間順序排序,也就是分數(shù)相同的情況下先上榜的排在前面。
當時把鼠鼠給難住了,面完后才找到一個可行的方案:
為了實現(xiàn)分數(shù)相同按照時間順序排序,可以將分數(shù)score設置為一個浮點數(shù),其中整數(shù)部分為得分,小數(shù)部分為時間戳
即:score = 分數(shù) + 1 - 時間戳/1e13
此時在分數(shù)相同的情況下,時間早的時間戳小,除以一個很大的數(shù)后得到的數(shù)字就小,被1減去以后得到的差就會大,也就實現(xiàn)了
分數(shù)相同的情況下先上榜的排在前面。
但面試官后面希望我聊一些系統(tǒng)設計的思路,當時鼠鼠完全沒有系統(tǒng)設計的思路,不管后面復盤后也總結(jié)出了一套方法論,在這里分享給大家。
(1)明晰項目訴求:在這里就是設計出一個根據(jù)積分或點贊等數(shù)據(jù)進行排序。同時關(guān)注請求量,是否需要做高并發(fā)/高可用的擴展設計;此外對實時性是否也要要求,追求強一致性還是最終一致性
(2)確定業(yè)務邏輯:新用戶上榜后排行榜要產(chǎn)生變化;用戶積分發(fā)生變化后調(diào)整排名
(3)架構(gòu)設計:存儲(MySQL/Redis)+服務(是否需要拆分為多個服務)
大體上排行榜由兩部分組成,排序結(jié)構(gòu)和信息匯總結(jié)構(gòu)。也就是我們在排行榜上看到的根據(jù)點贊數(shù)排出前一百,而信息匯總則是我們點擊某一個用戶頭像可以看到其具體的用戶信息。 系統(tǒng)設計初期,前端同步調(diào)用排行榜系統(tǒng),對于并發(fā)量不大的情況,可以直接使用MySQL作為存儲,直接操作數(shù)據(jù)庫io即可,這里數(shù)據(jù)庫的極限在5000/s。也可以先把全量數(shù)據(jù)從數(shù)據(jù)庫里取出來后在內(nèi)存中進行排序(前提是數(shù)據(jù)量不大的情況下)
但隨著并發(fā)量和用戶量上升,這種強依賴的同步調(diào)用會增加接口延遲。 這時可以增加中間層,也就是應對接口性能提不上去的三板斧之一(緩存,消息隊列,分庫分表)。如使用Rocket MQ或Kafka等消息隊列(MQ)。流量大時可對排行榜系統(tǒng)起到削峰作用,還可批量插入數(shù)據(jù)庫減少IO次數(shù),提高插入效率。不過,使用MQ后要做好冪等處理(八股提問,MQ的消息冪等有哪些方式可以實現(xiàn))。 當流量和并發(fā)量持續(xù)上升,數(shù)據(jù)庫讀寫鎖競爭加劇,可采用主從分離等方式均攤讀壓力,當然也可以直接考慮使用Redis作為排行榜。利用Redis的sortset類型排序(這里需要掌握zset,相關(guān)的八股文也要熟悉,可能會被問到),如排行評論數(shù)可使用ZINCRBY命令更新,查詢用ZREVRANGE命令獲取前N名排名和分數(shù)。 架構(gòu)上可以由Redis作為消費者,它訂閱MQ消息,消費時做冪等判斷,用Lua腳本保證操作原子性。(這段話可以作為經(jīng)典話術(shù)使用)
總結(jié):
針對排行榜,簡單的就直接可以使用Redis排序,但如果需要保證時間戳小的在前面就需要做一點小處理。
面對設計一個通用的排行榜系統(tǒng),考察系統(tǒng)設計能力,這里就可以從我前面列舉的方法論進行展開,多多關(guān)注我的文章,積累經(jīng)驗,相信友友們一定會越來越游刃有余。
PS:
其實在整個分析過程中大家可以發(fā)現(xiàn),場景題其實就會把我們背的那些八股和技術(shù)運用起來,所以在學習場景題的時候就可以把八股文進行問題,有點像單詞背不住就去讀閱讀文章,在讀文章的時候記住八股文,在上面的分析過程中我也有幾處進行了隨機的八股提問。排行榜這個過程系統(tǒng)設計過程中有用到MQ,那友友們是不是可以順帶復習一下MQ的相關(guān)八股呢?
(1)如何保證MQ的消息冪等性?
(2)MQ的推模式和拉模式是什么?
(3)如何保證MQ消息不丟?
……
以上都是鼠鼠在面試中只要遇到Redis就一定會被問到的,不一定是全部問到,但至少都是三選一了…
好了如果大家有什么問題的話歡迎來評論區(qū)交流。包括但不限于文章創(chuàng)作改正意見,后續(xù)分享內(nèi)容(面經(jīng),知識輸出,經(jīng)驗分享等等),都看到這了,點個免費的關(guān)注和贊不過分吧