September Memo:從熟悉技術,到開始理解一個系統
今年的九月對我來說是一個滿特別的月份,因為加入新的工作環境,我開始接觸一套自己並不熟悉的系統;雖然 C#、ASP.NET、SQL、Web API 這些技術本身並不陌生,但真正需要花時間的,其實不是重新學習這些技術,而是要在有限的時間裡,快速理解一個已經運作中的系統。 回頭看這一個月,做的事情其實滿分散的:分析系統架構與流程、整理文件、研究程式碼效能和雲端成本、進行壓力測試、SQL 移轉 Stored Procedure、補上參數驗證與一致性測試,以及研究 Stored Procedure 的版本控管與 CI/CD;如果單獨看每一件事情,好像彼此之間沒有太大的關係,但把它們串起來之後,這些工作都在做同一件事情:讓自己盡快建立起對這套系統的完整理解,從一個剛加入團隊、還在摸索系統的人,慢慢變成一個可以開始參與改善的人。 剛開始接觸系統時,我花了不少時間去追 API 的執行流程,從 Web API 的入口一路往下看,理解不同 Layer 之間的關係,以及商業邏輯、資料存取和資料庫之間是怎麼串起來的,這個過程也讓我再次感受到,「看懂程式碼」和「理解一個系統」其實是兩件不同的事情;單純知道某個 Method 做什麼,並不代表知道它為什麼會這樣設計,也不代表知道它和其他功能之間有什麼關係,所以這次我比較在意的,不只是把單一功能看懂,而是試著建立整個系統的心智模型:資料從哪裡進來、經過哪些處理、最後流向哪裡,以及不同元件之間是怎麼互相影響的。 在這個過程中,我也開始整理系統架構與流程文件,對我來說文件不只是提供給其他人看的東西,也是一種驗證自己理解是否正確的方法;當我必須把一個複雜的流程整理成可以說明的架構時,往往也會發現自己其實還有一些地方沒有真正理解,也因此這個過程並不是單純把程式碼看過一遍,而是透過整理和描述,把原本零散的資訊慢慢組合成比較完整的系統觀。 從程式碼往外看,開始理解系統的另一面 當對系統有了基本理解之後,我開始關注的不再只是「這段程式碼能不能正常運作」,而是它實際執行時會產生什麼影響,某些程式碼的執行效率會影響 CPU、Memory、Database、I/O 或 Network 的資源使用,而當系統運行在 Cloud 環境時,這些資源消耗最後也可能反映在雲端成本上;這讓我開始用不同的角度看程式碼:如果這段程式碼的執行效率不好,在系統規模變大之後會發生什麼?如果 Request 數量增加,資源消耗會怎麼變化?這些變化最後又會不會轉化成實際的營運成本? 也就是在這個階段,我開始把原本比較單純的「程式碼 → 功能」,慢慢延伸成「程式碼 → 執行效率 → 資源消耗 → 系統運作 → 雲端成本」;這種思考方式和單純看程式碼本身不太一樣,因為開始需要把 Application、Database 和 Infrastructure 放在同一個脈絡裡看。 除了分析程式碼和架構之外,這個月也開始接觸壓力測試,這對我來說也是一個滿有意思的轉變,因為在看程式碼時,我們很容易根據邏輯去推測系統應該會怎麼運作,但真正把系統放到一定的負載下之後,才會知道原本的假設是不是成立;透過壓力測試,我開始關注 Response Time、Throughput、Concurrency、Resource Utilization,以及系統在高負載下的行為:哪些地方會成為 Bottleneck?當同時處理的 Request 增加之後,哪一層會先出現問題?資源使用量和效能之間又是什麼關係? 這也讓我更加確定,寫出一個「可以正常運作」的系統,和真正知道它「在壓力下會怎麼運作」,是兩件不同的事情;前者比較像是確認功能正確,後者則開始涉及系統實際運作時的行為,而這也是我以前比較少從這個角度去思考的事情。 從 SQL Migration 開始,看見更多工程問題 這個月另一個比較有感的工作,是把原本由應用程式組合 SQL Command 的方式,逐步移轉到 Stored Procedure;一開始看起來只是一個 SQL Migration,但實際做下去之後,很快就會牽涉到更多問題:原本的行為能不能完整保留?Parameter 要怎麼處理?缺少 Parameter 時應該怎麼驗證?修改之後又要怎麼確定新舊實作的結果一致? ...