ExplainThis 全端開發雙週報 #75 系統設計中的非功能需求
系統設計中的非功能需求
嗨~歡迎閱讀第 75 期 ExplainThis 全端開發雙週報!
最近在社群中看到一個叫 Can’t Maintain 的有趣網站 (連結),該網站提供小遊戲,來測試大家對於元件 API 可維護性的理解。進到網站後,會有一系列二擇一的問題,要在兩種不同的元件 API 設計中,選你覺得比較好維護的。選完後會立即看到結果,以及為什麼正確,或者為什麼不對的相關說明。
在 AI 能幫忙快速實作的時代下,能否有能力一眼辨別 AI 生成的程式碼好壞,會是很重要的能力。推薦大家可以到這網站玩玩,培養介面設計的判斷力。
如果對如何培養相關能力感興趣,我們在 E+ 的《寫出好維護的程式碼》線上課程 (連結) 詳談了經典的程式設計觀點,歡迎加入 E+ 後觀看 (連結)
以上,讓我們一起進到這期的主題文章~
系統設計中的非功能需求
在開發軟體產品時,產品本身要達到的功能會被歸類為功能需求 (functional requirement)。舉例來說,在社群媒體網站中,讓使用者可以瀏覽動態牆、能留言、能按讚,這些都屬於功能需求。但要讓一個產品受使用者青睞,除了功能本身以外,還有其他需要看重的。
舉例來說,效能就是多數使用者在乎的。先前有不少研究指出,如果一個電商網站的加載變快,將能顯著提升使用者的留存率。以多數人的使用經驗來說,相信不會想要逛一個每次進去都得等五秒、十秒的電商平台或社群媒體。效能就是屬於非功能需求,而除了效能以外,軟體產品的可用性、資訊安全等,也都是重要的非功能需求。
從我們的觀點看,身為軟體工程師,能把功能實作出來是最基本的;如果想要成為資深工程師,就不能只是讓東西能動就好,「做好非功能需求的設計」是不能不面對的門檻。
在眾多非功能需求中,《Designing Data Intensive Applications》的作者在這個章節著重其中四種,包含效能、可靠性、可擴展性,以及可維護性,以下讓我們分別來討論。
效能 (Performance)
當提到軟體效能時,相信多數人會想到延遲度 (latency) 與吞吐量 (throughput) 這兩個衡量指標。
所謂的延遲度是指請求進到系統到系統回應的這段時間,理想上如果延遲越低會越好。例如某支 API 的回應速度能在一百毫秒內,延遲度就會比五百毫秒回應來得低。而吞吐量則是指某個系統每秒鐘能處理多少請求或資料,例如每秒可以處理萬筆寫入請求,理想上越高會越好。
雖然以理想的狀況來說,低延遲與高吞吐 (low latency and high throughput) 是軟體系統設計者的目標。但就現實來說,在資源有限的狀況下,兩者經常會有取捨。假如今天一台機器處理的請求量多起來,可能 CPU 正在處理某個請求,導致新進來的請求無法馬上處理,這樣延遲度就會增加。
作者在下方可擴展性的篇幅中,會多談吞吐量,以下讓我們先針對延遲度來討論。
拆解回應時間
在看延遲度時,書中有特別進一步拆分。當一個請求進來後,會先有網路延遲,接著可能會需要排在佇列上等待被處理,接著才會真正被處理;處理完之後回傳又會再有網路傳輸的時間。雖然書中沒細談,在實務上這個流程可以拆到更細。舉例來說,在請求送到客戶端後,又可以拉出另一個流程細節,在 什麼是關鍵渲染路徑 (critical rendering path)? 一文中,我們有談到從前端的角度如何拆解關鍵渲染路徑。
在實務上拆解這樣的流程會很有幫助,具體會推薦在流程中的每一個節點,都要衡量相關的時間。這樣當今天請求回應變慢,可以立即看出是哪一段不尋常,讓團隊能加速找出問題所在。
為什麼推薦用中位數與百分位數衡量
在衡量延遲度時,書中推薦不要用平均數來衡量。這是因為當用平均數來衡量,沒辦法清楚得知有多少使用者遇到延遲度高的請求。舉例來說,如果平均回應時間是 200 毫秒,這看起來可能很不錯;但有可能有一大群很快、另一大群很慢的請求,只看平均沒辦法看出那群很慢的請求有多慢。
反之,如果用中位數與百分位來衡量,就能夠清楚許多。假如中位數 (俗稱 p50) 是 200 毫秒,就代表有一半的請求超過 200 毫秒才完成回應。如果第 95 百分位 (俗稱 p95) 是 1.5 秒,就能夠看出有 5% 的請求超過 1.5 秒才獲得回應。對於使用者數量龐大的軟體系統來說 (例如千萬量級以上),即使 5% 也超過 50 萬,數量上相當可觀,用百分位數就能讓軟體團隊去照顧到這一塊。
除了不要用平均數這點,作者在這個區塊中也有談到 SLO,書中有關 SLO 的內容基本上我們在 SLO 是什麼? 為什麼 SLO 對軟體團隊很重要? 主題文中都有討論到 (甚至談得比書中提的深),因此推薦還不熟的讀者可以回顧。
閱讀更多
除了效能外,《Designing Data Intensive Applications》一書中也討論了可靠性、可擴展性,以及可維護性等不同的非功能需求。如果對完整的導讀感興趣,歡迎加入 E+ 成長計畫閱讀 (連結)~
本期推薦
《Willingness to Get Bored》一文談了要把事情做好 (例如把程式碼寫好),需要願意熬過無聊,能否在遇到卡關仍堅持下去會是關鍵 (連結)。當然,更理想的狀況是別人覺得無聊,但你卻樂此不疲,我們在《選一個讓你不感覺苦也不倦怠的職涯》一文談過這點 (連結)
隨著 AI 代理發展越來越成熟,業界開始有觀點認為應該要把介面設計,變得更加代理友善 (agent-friendly)。《You Need to Rewrite Your CLI for AI Agents》 這篇文章從 CLI 角度談可以如何重新設計介面,讓 AI 代理更容易使用你開發的 CLI (連結)
上週在 PM 界頗有名的 Aakash Gupta 分享了一個在面試時的反常要訣,他提到從神經科學研究的角度看,在面試時表現得淡然一點、混蛋一點,反而可能會有更好的表現 (連結)
最近因為中東地區的戰況,讓 AWS 阿聯酋資料中心疑似被轟炸波及到。透過這個事件,我們寫了一篇貼文來談,當軟體維運遇到不可抗的事故時,可以如何有效縮減爆炸半徑 (連結)
因為 AI 更容易處理基於領域分類的程式碼庫,領域驅動 (DDD) 的開發方式最近重新受到關注,《Upskilling your Team in DDD》 講座用很簡要易懂的方式講解 DDD (連結)
《Nobody Gets Promoted for Simplicity 》這篇文在社群中引起廣大討論 (連結),該文描述了軟體業界的一個怪異現象,把軟體寫得簡潔一點對升遷沒幫助的觀察,然而社群中有不少人反駁自己在的地方不是這樣。不過確實有很多公司是這樣,因此推薦找新工作時要慎選,不要選擇文中描述的公司類型。
《Code is cheap. Show me the talk》一文在談論近期軟體業界的轉變。作者的觀點是,以前會說 Talk is cheap. Show me the code. 但現在反過來變成 Code is cheap。這個轉變下,開發者能否去想像、闡述、定義問題,並且去架構,會帶來很大的優勢 (連結)
文末彩蛋
這期的彩蛋是來自紐約時報暢銷作家 Sahil Bloom 的分享,他提到他在二十多歲時收過最好的建議是「當你成功時,大家其實沒那麼在意;當你失敗時,也不會有人真的在乎」。
Nobody cares. When you’re winning, nobody cares. When you’re losing, nobody cares. It doesn’t mean nobody loves you, it just means nobody cares about your life as much as you do. You are in control. It’s on you. Nobody cares. Go do the thing.
在我們邁入三十歲後讀到這段話,覺得特別有感。二十代經歷大學與職涯初期,在那時總是特別在乎其他人的眼光,也因此總是從眾地選擇那些被其他人、被社會認為好的職涯選擇。在選實習與第一份工作時,想的不是自己感不感興趣,而是公司的名字響不響亮、說出去好不好聽。雖然選擇是自己做的,但背後驅動的卻不真的從自己而來。
在多累積一點人生歷練後,更加意識到各行各業都有其價值;也正是因為有不同的職業存在,當有需求時,能夠找到相對應的幫助。身為軟體工程師,因為工作的通用性高,各行各業都有軟體的需求,我們能投身於某個自己想看見改變的產業,透過軟體的力量將其升級。因此,推薦在選擇職涯時,可以試著不管別人的眼光 (因為也沒人真的這麼在乎),去那個自己最想看見改變的地方吧。


