系統(tǒng)設(shè)計面試題指北
本文轉(zhuǎn)載自微信公眾號「JavaGuide」,作者Guide哥 。轉(zhuǎn)載本文請聯(lián)系JavaGuide公眾號。
系統(tǒng)設(shè)計在面試中一定是最讓面試者頭疼的事情之一。 因為系統(tǒng)設(shè)計相關(guān)的問題通常是開放式的,所以沒有標(biāo)準(zhǔn)答案。你在和面試官思想的交流碰撞中會慢慢優(yōu)化自己的系統(tǒng)設(shè)計方案。理論上來說,系統(tǒng)設(shè)計面試也是和面試官一起一步一步改進原有系統(tǒng)設(shè)計方案的過程。
系統(tǒng)設(shè)計題往往也非常能考察出面試者的綜合能力,回答好的話,很容易就能在面試中脫穎而出。不論是對于參加社招還是校招的小伙伴,都很有必要重視起來。
接下來,我會帶著小伙伴們從我的角度出發(fā)來談?wù)劊喝绾螠?zhǔn)備面試中的系統(tǒng)設(shè)計部分。
由于文章篇幅有限,就不列舉實際例子了,可能會在后面的文章中單獨提一些具體的例子。
個人能力有限。如果文章有任何需要改善和完善的地方,歡迎在評論區(qū)指出,共同進步!
系統(tǒng)設(shè)計面試一般怎么問?
我簡單總結(jié)了一下系統(tǒng)設(shè)計面試相關(guān)問題的問法:
- 設(shè)計一個某某系統(tǒng)比如秒殺系統(tǒng)、微博系統(tǒng)、搶紅包系統(tǒng)、短網(wǎng)址系統(tǒng)。
- 設(shè)計某某系統(tǒng)中的一個功能比如嗶哩嗶哩的點贊功能。
- 設(shè)計一個框架比如 RPC 框架、消息隊列、緩存框架、分布式文件系統(tǒng)等等。
- 某某系統(tǒng)的技術(shù)選型比如緩存用Redis 還是 Memcached、網(wǎng)關(guān)用 Spring Cloud Gateway 還是Netflix Zuul2 。
系統(tǒng)設(shè)計怎么做?
我們將步驟總結(jié)成了以下 4 步。
Step1:問清楚系統(tǒng)具體要求
當(dāng)面試官給出了系統(tǒng)設(shè)計題目之后,一定不要立即開始設(shè)計解決方案。 你需要先理解系統(tǒng)設(shè)計的需求:功能性需求和非功能性需求。
為了避免自己曲解題目所想要解決的問題,你可以先簡要地給面試官說說自己的理解,
為啥要詢問清楚系統(tǒng)的功能性需求也就是說系統(tǒng)包含哪些功能呢?
畢竟,如果面試官冷不丁地直接讓你設(shè)計一個微博系統(tǒng),你不可能把微博系統(tǒng)涵蓋的功能比如推薦信息流、會員機制等一個一個都列舉出來,然后再去設(shè)計吧!你需要篩選出系統(tǒng)所提供的核心功能(縮小邊界范圍)!
為啥要詢問清楚系統(tǒng)的非功能性需求或者說約束條件比如系統(tǒng)需要達到多少 QPS 呢?
讓你設(shè)計一個 1w 人用的微博系統(tǒng)和 100w 人用的微博系統(tǒng)能一樣么?不同的約束系統(tǒng)對應(yīng)的系統(tǒng)設(shè)計方案肯定是不一樣的。
Step2:對系統(tǒng)進行抽象設(shè)計
我們需要在一個 High Level 的層面對系統(tǒng)進行設(shè)計。
你可以畫出系統(tǒng)的抽象架構(gòu)圖,這個抽象架構(gòu)圖中包含了系統(tǒng)的一些組件以及這些組件之間的連接。
Step3:考慮系統(tǒng)目前需要優(yōu)化的點
對系統(tǒng)進行抽象設(shè)計之后,你需要思考當(dāng)前抽象的系統(tǒng)設(shè)計有哪些需要優(yōu)化的點,比如說:
當(dāng)前系統(tǒng)部署在一臺機器夠嗎?是否需要部署在多臺機器然后進行負(fù)載均衡呢?
數(shù)據(jù)庫處理速度能否支撐業(yè)務(wù)需求?是否需要給指定字段加索引?是否需要讀寫分離?是否需要緩存?
數(shù)據(jù)量是否大到需要分庫分表?
是否存在安全隱患?
系統(tǒng)是否需要分布式文件系統(tǒng)?
......
Step4:優(yōu)化你的系統(tǒng)抽象設(shè)計
根據(jù) Step 3 中的“系統(tǒng)需要優(yōu)化的點” 對系統(tǒng)的抽象設(shè)計做進一步完善。
系統(tǒng)設(shè)計該如何準(zhǔn)備?
知識儲備
系統(tǒng)設(shè)計面試非常考察你的知識儲備,系統(tǒng)設(shè)計能力的提高需要大量的理論知識儲備。比如說你要知道大型網(wǎng)站架構(gòu)設(shè)計必備的三板斧:
- 高性能架構(gòu)設(shè)計:熟悉系統(tǒng)常見性能優(yōu)化手段比如引入 讀寫分離、緩存、負(fù)載均衡、異步等等。
- 高可用架構(gòu)設(shè)計 :CAP 理論和 BASE 理論、通過集群來提高系統(tǒng)整體穩(wěn)定性、超時和重試機制、應(yīng)對接口級故障:降級、熔斷、限流、排隊。
- 高擴展架構(gòu)設(shè)計 :說白了就是懂得如何拆分系統(tǒng)。你按照不同的思路來拆分軟件系統(tǒng),就會得到不同的架構(gòu)。
實戰(zhàn)
雖然懂得了理論,但是自己沒有進行實踐的話,很多東西是無法體會到的!
因此,你還要 不斷通過實戰(zhàn)項目鍛煉自己的系統(tǒng)設(shè)計能力。
保持好奇心
多思考自己經(jīng)常瀏覽的網(wǎng)站是怎么做的。比如:
- 你刷微博的時候可以思考一下微博是如何記錄點贊數(shù)量的?
- 你看嗶哩嗶哩的時候可以思考一下消息提醒系統(tǒng)是如何做的?
- 你使用短鏈系統(tǒng)的時候可以考慮一下短鏈系統(tǒng)是如何做的?
- ......
技術(shù)選型
實現(xiàn)同樣的功能,一般會有多種技術(shù)選擇方案,比如緩存用Redis 還是 Memcached、網(wǎng)關(guān)用 Spring Cloud Gateway 還是Netflix Zuul2 。很多時候,面試官在系統(tǒng)設(shè)計面過程中會具體到技術(shù)的選型,因而,你需要區(qū)分不同技術(shù)的優(yōu)缺點。
系統(tǒng)設(shè)計面試必知系統(tǒng)設(shè)計的時候必然離不開描述性能相關(guān)的指標(biāo)比如 QPS。
性能相關(guān)的指標(biāo)
響應(yīng)時間
響應(yīng)時間 RT(Response-time)就是用戶發(fā)出請求到用戶收到系統(tǒng)處理結(jié)果所需要的時間。
RT 是一個非常重要且直觀的指標(biāo),RT 數(shù)值大小直接反應(yīng)了系統(tǒng)處理用戶請求速度的快慢。
并發(fā)數(shù)
并發(fā)數(shù)可以簡單理解為系統(tǒng)能夠同時供多少人訪問使用也就是說系統(tǒng)同時能處理的請求數(shù)量。
并發(fā)數(shù)反應(yīng)了系統(tǒng)的負(fù)載能力。
QPS 和 TPS
- QPS(Query Per Second) :服務(wù)器每秒可以執(zhí)行的查詢次數(shù);
- TPS(Transaction Per Second) :服務(wù)器每秒處理的事務(wù)數(shù)(這里的一個事務(wù)可以理解為客戶發(fā)出請求到收到服務(wù)器的過程);
書中是這樣描述 QPS 和 TPS 的區(qū)別的。
QPS vs TPS:QPS 基本類似于 TPS,但是不同的是,對于一個頁面的一次訪問,形成一個 TPS;但一次頁面請求,可能產(chǎn)生多次對服務(wù)器的請求,服務(wù)器對這些請求,就可計入“QPS”之中。如,訪問一個頁面會請求服務(wù)器 2 次,一次訪問,產(chǎn)生一個“T”,產(chǎn)生 2 個“Q”。
吞吐量
吞吐量指的是系統(tǒng)單位時間內(nèi)系統(tǒng)處理的請求數(shù)量。
一個系統(tǒng)的吞吐量與請求對系統(tǒng)的資源消耗等緊密關(guān)聯(lián)。請求對系統(tǒng)資源消耗越多,系統(tǒng)吞吐能力越低,反之則越高。
TPS、QPS 都是吞吐量的常用量化指標(biāo)。
- QPS(TPS) = 并發(fā)數(shù)/平均響應(yīng)時間(RT)
- 并發(fā)數(shù) = QPS * 平均響應(yīng)時間(RT)
系統(tǒng)活躍度
介紹幾個描述系統(tǒng)活躍度的常見名詞,建議牢牢記住。你不光會在回答系統(tǒng)設(shè)計面試題的時候碰到,日常工作中你也會經(jīng)常碰到這些名詞。
PV(Page View)
訪問量, 即頁面瀏覽量或點擊量,衡量網(wǎng)站用戶訪問的網(wǎng)頁數(shù)量;在一定統(tǒng)計周期內(nèi)用戶每打開或刷新一個頁面就記錄 1 次,多次打開或刷新同一頁面則瀏覽量累計。UV 從網(wǎng)頁打開的數(shù)量/刷新的次數(shù)的角度來統(tǒng)計的。
UV(Unique Visitor)
獨立訪客,統(tǒng)計 1 天內(nèi)訪問某站點的用戶數(shù)。1 天內(nèi)相同訪客多次訪問網(wǎng)站,只計算為 1 個獨立訪客。UV 是從用戶個體的角度來統(tǒng)計的。
DAU(Daily Active User)
日活躍用戶數(shù)量。
MAU(monthly active users)
月活躍用戶人數(shù)。
舉例:某網(wǎng)站 DAU 為 1200w, 用戶日均使用時長 1 小時,RT 為 0.5s,求并發(fā)量和 QPS。
平均并發(fā)量 = DAU(1200w)* 日均使用時長(1 小時,3600 秒) /一天的秒數(shù)(86400)=1200w/24 = 50w
真實并發(fā)量(考慮到某些時間段使用人數(shù)比較少) = DAU(1200w)* 日均使用時長(1 小時,3600 秒) /一天的秒數(shù)-訪問量比較小的時間段假設(shè)為 8 小時(57600)=1200w/16 = 75w
峰值并發(fā)量 = 平均并發(fā)量 * 6 = 300w
QPS = 真實并發(fā)量/RT = 75W/0.5=100w/s
常用性能測試工具
后端常用
既然系統(tǒng)設(shè)計涉及到系統(tǒng)性能方面的問題,那在面試的時候,面試官就很可能會問:你是如何進行性能測試的?
推薦 4 個比較常用的性能測試工具:
- Jmeter :Apache JMeter 是 JAVA 開發(fā)的性能測試工具。
- LoadRunner:一款商業(yè)的性能測試工具。
- Galtling :一款基于 Scala 開發(fā)的高性能服務(wù)器性能測試工具。
- ab :全稱為 Apache Bench 。Apache 旗下的一款測試工具,非常實用。
沒記錯的話,除了 LoadRunner 其他幾款性能測試工具都是開源免費的。
前端常用
- Fiddler:抓包工具,它可以修改請求的數(shù)據(jù),甚至可以修改服務(wù)器返回的數(shù)據(jù),功能非常強大,是 Web 調(diào)試的利器。
- HttpWatch: 可用于錄制 HTTP 請求信息的工具。
常見軟件的 QPS
這里給出的 QPS 僅供參考,實際項目需要進行壓測來計算。
- Nginx :一般情況下,系統(tǒng)的性能瓶頸基本不會是 Nginx。單機 Nginx 可以達到 30w +。
- Redis: Redis 官方的性能測試報告:https://redis.io/topics/benchmarks 。從報告中,我們可以得出 Redis 的單機 QPS 可以達到 8w+(CPU 性能有關(guān)系,也和執(zhí)行的命令也有關(guān)系比如執(zhí)行 SET 命令甚至可以達到 10w+QPS)。
- MySQL: MySQL 單機的 QPS 為 大概在 4k 左右。
- Tomcat :單機 Tomcat 的 QPS 在 2w 左右。這個和你的 Tomcat 配置有很大關(guān)系,舉個例子 Tomcat 支持的連接器有 NIO、NIO.2 和 APR。AprEndpoint 是通過 JNI 調(diào)用 APR 本地庫而實現(xiàn)非阻塞 I/O 的,性能更好,Tomcat 配置 APR 為 連接器的話,QPS 可以達到 3w 左右。更多相關(guān)內(nèi)容可以自行搜索 Tomcat 性能優(yōu)化。
系統(tǒng)設(shè)計原則
合適優(yōu)于先進 > 演化優(yōu)于一步到位 > 簡單優(yōu)于復(fù)雜
常見的性能優(yōu)化策略
性能優(yōu)化之前我們需要對請求經(jīng)歷的各個環(huán)節(jié)進行分析,排查出可能出現(xiàn)性能瓶頸的地方,定位問題。
下面是一些性能優(yōu)化時,我經(jīng)常拿來自問的一些問題:
- 當(dāng)前系統(tǒng)的 SQL 語句是否存在問題?
- 當(dāng)前系統(tǒng)是否需要升級硬件?
- 系統(tǒng)是否需要緩存?
- 系統(tǒng)架構(gòu)本身是不是就有問題?
- 系統(tǒng)是否存在死鎖的地方?
- 數(shù)據(jù)庫索引使用是否合理?
- 系統(tǒng)是否存在內(nèi)存泄漏?(Java 的自動回收內(nèi)存雖然很方便,但是,有時候代碼寫的不好真的會造成內(nèi)存泄漏)
- 系統(tǒng)的耗時操作進行了異步處理?
- ……
性能優(yōu)化必知法則
SQL 優(yōu)化,JVM、DB,Tomcat 參數(shù)調(diào)優(yōu) > 硬件性能優(yōu)化(內(nèi)存升級、CPU 核心數(shù)增加、機械硬盤—>固態(tài)硬盤等等)> 業(yè)務(wù)邏輯優(yōu)化/緩存 > 讀寫分離、集群等 > 分庫分表
系統(tǒng)設(shè)計面試的注意事項
想好再說
沒必要面試官剛問了問題之后,你沒準(zhǔn)備好就開始回答。這樣不會給面試官帶來好印象的!系統(tǒng)設(shè)計本就需要面試者結(jié)合自己的以往的經(jīng)驗進行思考,這個過程是需要花費一些時間的。
沒有絕對的答案
系統(tǒng)設(shè)計沒有標(biāo)準(zhǔn)答案。重要的是你和面試官一起交流的過程。
一般情況下,你會在和面試官的交流過程中,一步一步完成系統(tǒng)設(shè)計。這個過程中,你會在面試官的引導(dǎo)下不斷完善自己的系統(tǒng)設(shè)計方案。
因此,你不必要在系統(tǒng)設(shè)計面試之前找很多題目,然后只是單純記住他們的答案。
勿要絕對
系統(tǒng)設(shè)計沒有最好的設(shè)計方案,只有最合適的設(shè)計方案。這就類比架構(gòu)設(shè)計了:軟件開發(fā)沒有銀彈,架構(gòu)設(shè)計的目的就是選擇合適的解決方案。 何為銀彈? 狼人傳說中,只有銀彈(銀質(zhì)子彈)才能制服這些猛獸。對應(yīng)到軟件開發(fā)活動中,銀彈特指開發(fā)者們尋求的一種克服軟件開發(fā)這個難纏的猛獸的“萬能鑰匙 🔑”。
權(quán)衡利弊
知道使用某個技術(shù)可能會為系統(tǒng)帶來的利弊。比如使用消息隊列的好處是解耦和削峰,但是,同樣也讓系統(tǒng)可用性降低、復(fù)雜性提高,同時還會存在一致性問題(消息丟失或者消息未被消費咋辦)。
慢慢優(yōu)化
剛開始設(shè)計的系統(tǒng)不需要太完美,可以慢慢優(yōu)化。
不追新技術(shù)
使用穩(wěn)定的、適合業(yè)務(wù)的技術(shù),不必要過于追求新技術(shù)。
追簡避雜
系統(tǒng)設(shè)計應(yīng)當(dāng)追求簡單避免復(fù)雜。KISS( Keep It Simple, Stupid)原則——保持簡單,易于理解。
總結(jié)
這篇文章簡單帶著小伙伴們分析了一下系統(tǒng)設(shè)計面試。如果你還想要深入學(xué)習(xí)的話,可以參考:https://github.com/donnemartin/system-design-primer 。
參考https://github.com/donnemartin/system-design-primer
https://www.acecodeinterview.com/intro/
https://gist.github.com/vasanthk/485d1c25737e8e72759f
原文鏈接:https://mp.weixin.qq.com/s/1Jl8ee0jJoFdGMfIhl_qaQ