軟體設計雜談 - ianchen0119/Introduce-to-5GC GitHub Wiki
大家好,我是 Ian!在前面的篇章中我們探討了 5G 核心網路的運作原理,以及時下最夯的雲原生軟體開發實務,本篇章我想跟各位分享自己學習程式設計一段時間後對於軟體開發的看法。
進入正題
對於本科生來說,在學校修課時會練習到的東西大概包含:
- 如何使用外部套件提供的 API、如何使用系統呼叫?(使用已經實作好的高階函式)
- 了解程式語言本身(程式語言的特性、底層運作)
- 計算機相關理論,了解硬體行為(了解處理器行為,才有可能知道系統軟體開發遇到的非預期行為)
- 學習作業系統、計算機網路等進階的專業學科(把先前學到的東西彙整,這時候可能會對接觸到多執行緒程式的開發)
跳脫學校的專業訓練進到職場後,又會看到不同的方向學校做的專案要求功能性上的正確,但是業界需要的軟體必須要達到:
- 功能性
- 可靠性
- 安全性
一個軟體要從一個階段跳到下一個階段,過程中可能需要付出數倍的努力才有可能做到,為了有效的達到這些目的,又可以分為兩大方向:
1. 將系統結合現有的解決方案
撇開軟體設計上的問題,要改善系統的效率其實也有多種方式,比如說:
- 既有網路服務無法處理高併發問題或是吞吐量過低,最快的方式就是加強硬體規格
- 編譯時期的最佳化
- 將原始碼經過編譯器轉換為 binary file 的過程中,其實編譯器會為我們做許多安全性與效能上的改良。
- 導入既有的可靠專案
- Database 的效率太低、存取太慢或是有可靠性(備援的需求),我們可以導入像是 redis 這樣的 in-memory storage,可靠性問題也可以使用 DB 本身的 HA 來解決。
2. 改善軟體自身的體質
坊間上有需多相關的軟體設計書籍,我們也常常可以聽到設計模式、程式撰寫規範、某程式語言的 Best pratice,以小弟個人的淺見來說,這些東西想要解決的是:
- 當一個專案的複雜度到達了上萬行,其實會衍生出很多問題:
- 可讀性
- 可維護性
- 可靠性
- 安全性
前面三點我們可以在許多的設計模式書籍上看到對應的解決方案,比如說:
- Factory 相關的 patterns 探討不同設計下,物件與物間之間的耦合度(程式會不會改了一個物件或是一個函式,進而產生出許多新問題)、擴展性(如果我要新增既有的子模組,容不容易擴充?)、抽象性(其他開發者能不能快速理解這些程式碼,對於物件的抽象做的好不好)
- Concurrency 相關的 patterns 告訴我們在並行程式開發下,除了使用 Lock 避免 race condition,其實還有很多設計值得深究,像是:
- 為了避免不斷地建立與銷毀 thread,出現了 thread pool 或是 worker pool 的設計(程式在初始化時會預先建立好 worker,如果有新任務可以直接 assign 給 worker pool 中閒置的 worker)。
- Producer 與 consumer 模型可以幫助我們開發更有效的服務,以 network functions 中的 SMF 來看,它有 PFCP、HTTP 等訊息需要處理。對於接收請求,我們可以交給一個 worker 處理(也就是 producer),收到訊息後再交給 Dispatcher 或是 Handler 進行後續的處理(consumer)。
- Fan-out-fan-in pattern 讓我們可以結合
生產者與消費者模型
以及worker pool
讓整個系統從輸入、處理到輸出的過程最佳化。
而安全性問題就像是個無底洞,只有還沒被挖掘或是未公開的漏洞,要開發保證完全安全、無懈可擊的軟體幾乎是不可能的,所以我們可以看到坊間有很多公司會設有 bug bounty 專案,或是專門提供弱點掃描的公司。除了這些作法,要加強程式的安全性也需要了解程式語言或是服務本身常見的漏洞:
- 記憶體溢位,像是:Stack overflow、heap overflow,即使現代的編譯器可能會在編譯時期幫我們做初步的檢查或是防範,但實作上仍須小心!
- 權限檢查:系統的權限管理,如何將使用者分級、限制不同使用者權限下能做的操作(Token、IAM)。
- 安全通訊:訊息的完整性保護與加密、訊息傳送之前的 authentication。
- 永久保存資料的機密性:使用者密碼是否能明文的存放在資料庫?如果不行,該怎麼做?
- Zero-day:你寫的程式本身可能沒問題,但你用的軟體(作業系統、網頁伺服器、外部套件)可能有漏洞!
- 惡意流量檢測:如何偵測惡意流量並且導入黑白名單機制,避免 DDOS 攻擊拖垮系統的吞吐量。
總結
從 2022 年中到現在開始以軟體工程師的角色看待專案的開發,在這過程中其實學到了非常多東西(具體化以前學到的抽象概念、學習如何溝通與表達想法),再來是深刻的體會到其實當上軟體工程師以後並不會整天對著鍵盤敲敲打打,多數時間都會花在溝通、測試、設計與文件的撰寫,扣除掉這些剩餘的時間才是程式碼的開發或是除錯。 本來想說唸了研究所 loading 這麼重,今年可能沒有辦法參加鐵人賽,結果變成我一邊修課、研究、工作、寫書、寫新系列文的稿,雖然對自己目前的能力跟成就都不是很滿意,但每一年透過鐵人賽觀察到自己的成長其實是一件十分熱血沸騰的事情,在這邊也要再度感謝女朋友與指導教授(我老闆)的支持,沒有他們任何一個人的點頭同意,我都沒有機會出現在這裡(汗)。