系統設計在面試中一定是最讓面試者頭疼的事情之一, 因為系統設計相關的問題通常是開放式的,所以沒有標準答案,你在和面試官思想的交流碰撞中會慢慢優化自己的系統設計方案,理論上來說,系統設計面試也是和面試官一起一步一步改進原有系統設計方案的程序,
系統設計題往往也非常能考察出面試者的綜合能力,回答好的話,很容易就能在面試中脫穎而出,不論是對于參加社招還是校招的小伙伴,都很有必要重視起來,
接下來,我會帶著小伙伴們從我的角度出發來談談:如何準備面試中的系統設計部分,
由于文章篇幅有限,就不列舉實際例子了,可能會在后面的文章中單獨提一些具體的例子,
個人能力有限,如果文章有任何需要改善和完善的地方,歡迎在評論區指出,共同進步!
系統設計面試一般怎么問?
我簡單總結了一下系統設計面試相關問題的問法:
- 設計一個某某系統比如秒殺系統、微博系統、搶紅包系統、短網址系統,
- 設計某某系統中的一個功能比如嗶哩嗶哩的點贊功能,
- 設計一個框架比如 RPC 框架、訊息佇列、快取框架、分布式檔案系統等等,
- 某某系統的技術選型比如快取用
Redis還是Memcached、網關用Spring Cloud Gateway還是Netflix Zuul2,
系統設計怎么做?
我們將步驟總結成了以下 4 步,
Step1:問清楚系統具體要求
當面試官給出了系統設計題目之后,一定不要立即開始設計解決方案, 你需要先理解系統設計的需求:功能性需求和非功能性需求,
為了避免自己曲解題目所想要解決的問題,你可以先簡要地給面試官說說自己的理解,
為啥要詢問清楚系統的功能性需求也就是說系統包含哪些功能呢?
畢竟,如果面試官冷不丁地直接讓你設計一個微博系統,你不可能把微博系統涵蓋的功能比如推薦資訊流、會員機制等一個一個都列舉出來,然后再去設計吧!你需要篩選出系統所提供的核心功能(縮小邊界范圍)!
為啥要詢問清楚系統的非功能性需求或者說約束條件比如系統需要達到多少QPS呢?
讓你設計一個1w人用的微博系統和100w人用的微博系統能一樣么?不同的約束系統對應的系統設計方案肯定是不一樣的,
Step2:對系統進行抽象設計
我們需要在一個 High Level 的層面對系統進行設計,
你可以畫出系統的抽象架構圖,這個抽象架構圖中包含了系統的一些組件以及這些組件之間的連接,

Step3:考慮系統目前需要優化的點
對系統進行抽象設計之后,你需要思考當前抽象的系統設計有哪些需要優化的點,比如說:
- 當前系統部署在一臺機器夠嗎?是否需要部署在多臺機器然后進行負載均衡呢?
- 資料庫處理速度能否支撐業務需求?是否需要給指定欄位加索引?是否需要讀寫分離?是否需要快取?
- 資料量是否大到需要分庫分表?
- 是否存在安全隱患?
- 系統是否需要分布式檔案系統?
- ......
Step4:優化你的系統抽象設計
根據 Step 3 中的“系統需要優化的點” 對系統的抽象設計做進一步完善,
系統設計該如何準備?
知識儲備
系統設計面試非常考察你的知識儲備,系統設計能力的提高需要大量的理論知識儲備,比如說你要知道大型網站架構設計必備的三板斧:
- 高性能架構設計: 熟悉系統常見性能優化手段比如引入 讀寫分離、快取、負載均衡、異步 等等,
- 高可用架構設計 :CAP理論和BASE理論、通過集群來提高系統整體穩定性、超時和重試機制、應對介面級故障:降級、熔斷、限流、排隊,
- 高擴展架構設計 :說白了就是懂得如何拆分系統,你按照不同的思路來拆分軟體系統,就會得到不同的架構,
實戰
雖然懂得了理論,但是自己沒有進行實踐的話,很多東西是無法體會到的!
因此,你還要 不斷通過實戰專案鍛煉自己的系統設計能力,
保持好奇心
多思考自己經常瀏覽的網站是怎么做的,比如:
- 你刷微博的時候可以思考一下微博是如何記錄點贊數量的?
- 你看嗶哩嗶哩的時候可以思考一下訊息提醒系統是如何做的?
- 你使用短鏈系統的時候可以考慮一下短鏈系統是如何做的?
- ......
技術選型
實作同樣的功能,一般會有多種技術選擇方案,比如快取用Redis 還是 Memcached、網關用 Spring Cloud Gateway 還是 Netflix Zuul2 , 很多時候,面試官在系統設計面程序中會具體到技術的選型,因而,你需要區分不同技術的優缺點,
系統設計面試必知
系統設計的時候必然離不開描述性能相關的指標比如 QPS,
性能相關的指標
回應時間
回應時間RT(Response-time)就是用戶發出請求到用戶收到系統處理結果所需要的時間,
RT是一個非常重要且直觀的指標,RT數值大小直接反應了系統處理用戶請求速度的快慢,
并發數
并發數可以簡單理解為系統能夠同時供多少人訪問使用也就是說系統同時能處理的請求數量,
并發數反應了系統的負載能力,
QPS 和 TPS
- QPS(Query Per Second) :服務器每秒可以執行的查詢次數;
- TPS(Transaction Per Second) :服務器每秒處理的事務數(這里的一個事務可以理解為客戶發出請求到收到服務器的程序);
書中是這樣描述 QPS 和 TPS 的區別的,
QPS vs TPS:QPS 基本類似于 TPS,但是不同的是,對于一個頁面的一次訪問,形成一個TPS;但一次頁面請求,可能產生多次對服務器的請求,服務器對這些請求,就可計入“QPS”之中,如,訪問一個頁面會請求服務器2次,一次訪問,產生一個“T”,產生2個“Q”,
吞吐量
吞吐量指的是系統單位時間內系統處理的請求數量,
一個系統的吞吐量與請求對系統的資源消耗等緊密關聯,請求對系統資源消耗越多,系統吞吐能力越低,反之則越高,
TPS、QPS都是吞吐量的常用量化指標,
- QPS(TPS) = 并發數/平均回應時間(RT)
- 并發數 = QPS * 平均回應時間(RT)
系統活躍度
介紹幾個描述系統活躍度的常見名詞,建議牢牢記住,你不光會在回答系統設計面試題的時候碰到,日常作業中你也會經常碰到這些名詞,
PV(Page View)
訪問量, 即頁面瀏覽量或點擊量,衡量網站用戶訪問的網頁數量;在一定統計周期內用戶每打開或重繪一個頁面就記錄1次,多次打開或重繪同一頁面則瀏覽量累計,UV 從網頁打開的數量/重繪的次數的角度來統計的,
UV(Unique Visitor)
獨立訪客,統計1天內訪問某站點的用戶數,1天內相同訪客多次訪問網站,只計算為1個獨立訪客,UV 是從用戶個體的角度來統計的,
DAU(Daily Active User)
榷訓躍用戶數量,
MAU(monthly active users)
月活躍用戶人數,
舉例:某網站 DAU為 1200w, 用戶日均使用時長 1 小時,RT為0.5s,求并發量和QPS,
平均并發量 = DAU(1200w)* 日均使用時長(1 小時,3600秒) /一天的秒數(86400)=1200w/24 = 50w
真實并發量(考慮到某些時間段使用人數比較少) = DAU(1200w)* 日均使用時長(1 小時,3600秒) /一天的秒數-訪問量比較小的時間段假設為8小時(57600)=1200w/16 = 75w
峰值并發量 = 平均并發量 * 6 = 300w
QPS = 真實并發量/RT = 75W/0.5=100w/s
常用性能測驗工具
后端常用
既然系統設計涉及到系統性能方面的問題,那在面試的時候,面試官就很可能會問:你是如何進行性能測驗的?
推薦 4 個比較常用的性能測驗工具:
- Jmeter :Apache JMeter 是 JAVA 開發的性能測驗工具,
- LoadRunner:一款商業的性能測驗工具,
- Galtling :一款基于Scala 開發的高性能服務器性能測驗工具,
- ab :全稱為 Apache Bench ,Apache 旗下的一款測驗工具,非常實用,
沒記錯的話,除了 LoadRunner 其他幾款性能測驗工具都是開源免費的,
前端常用
- Fiddler:抓包工具,它可以修改請求的資料,甚至可以修改服務器回傳的資料,功能非常強大,是Web 除錯的利器,
- HttpWatch: 可用于錄制HTTP請求資訊的工具,
常見軟體的QPS
這里給出的 QPS 僅供參考,實際專案需要進行壓測來計算,
- Nginx :一般情況下,系統的性能瓶頸基本不會是 Nginx,單機 Nginx 可以達到 30w +,
- Redis: Redis 官方的性能測驗報告:https://redis.io/topics/benchmarks ,從報告中,我們可以得出 Redis 的單機 QPS 可以達到 8w+(CPU性能有關系,也和執行的命令也有關系比如執行 SET 命令甚至可以達到10w+QPS),
- MySQL: MySQL 單機的 QPS 為 大概在 4k 左右,
- Tomcat :單機 Tomcat 的QPS 在 2w左右,這個和你的 Tomcat 配置有很大關系,舉個例子Tomcat 支持的連接器有 NIO、NIO.2 和 APR,
AprEndpoint是通過 JNI 呼叫 APR 本地庫而實作非阻塞 I/O 的,性能更好,Tomcat 配置 APR 為 連接器的話,QPS 可以達到 3w左右,更多相關內容可以自行搜索 Tomcat 性能優化,
系統設計原則
合適優于先進 > 演化優于一步到位 > 簡單優于復雜
常見的性能優化策略
性能優化之前我們需要對請求經歷的各個環節進行分析,排查出可能出現性能瓶頸的地方,定位問題,
下面是一些性能優化時,我經常拿來自問的一些問題:
- 當前系統的SQL陳述句是否存在問題?
- 當前系統是否需要升級硬體?
- 系統是否需要快取?
- 系統架構本身是不是就有問題?
- 系統是否存在死鎖的地方?
- 資料庫索引使用是否合理?
- 系統是否存在記憶體泄漏?(Java 的自動回收記憶體雖然很方便,但是,有時候代碼寫的不好真的會造成記憶體泄漏)
- 系統的耗時操作進行了異步處理?
- ……
性能優化必知法則
SQL優化,JVM、DB,Tomcat引數調優 > 硬體性能優化(記憶體升級、CPU核心數增加、機械硬碟—>固態硬碟等等)> 業務邏輯優化/快取 > 讀寫分離、集群等 > 分庫分表
系統設計面試的注意事項
想好再說
沒必要面試官剛問了問題之后,你沒準備好就開始回答,這樣不會給面試官帶來好印象的!系統設計本就需要面試者結合自己的以往的經驗進行思考,這個程序是需要花費一些時間的,
沒有絕對的答案
系統設計沒有標準答案,重要的是你和面試官一起交流的程序,
一般情況下,你會在和面試官的交流程序中,一步一步完成系統設計,這個程序中,你會在面試官的引導下不斷完善自己的系統設計方案,
因此,你不必要在系統設計面試之前找很多題目,然后只是單純記住他們的答案,
勿要絕對
系統設計沒有最好的設計方案,只有最合適的設計方案,這就類比架構設計了:軟體開發沒有銀彈,架構設計的目的就是選擇合適的解決方案, 何為銀彈? 狼人傳說中,只有銀彈(銀質子彈)才能制服這些猛獸,對應到軟體開發活動中,銀彈特指開發者們尋求的一種克服軟體開發這個難纏的猛獸的“萬能鑰匙??”,
權衡利弊
知道使用某個技術可能會為系統帶來的利弊,比如使用訊息佇列的好處是解耦和削峰,但是,同樣也讓系統可用性降低、復雜性提高,同時還會存在一致性問題(訊息丟失或者訊息未被消費咋辦),
慢慢優化
剛開始設計的系統不需要太完美,可以慢慢優化,
不追新技術
使用穩定的、適合業務的技術,不必要過于追求新技術,
追簡避雜
系統設計應當追求簡單避免復雜,KISS( Keep It Simple, Stupid)原則——保持簡單,易于理解,
總結
這篇文章簡單帶著小伙伴們分析了一下系統設計面試,如果你還想要深入學習的話,可以參考: 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
微信搜“JavaGuide”回復“計算機基礎”即可獲取圖解計算機基礎+個人原創的 Java 面試手冊,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/203291.html
標籤:Java
上一篇:SpringBoot第四集:整合JDBC和JPA(2020最新最易懂)
下一篇:Cglib 如何實作多重代理?
