諸多工程師以「寫出能運行之代碼」為工作完成之時。
然真正成熟之軟體工程,遠不止於此。
汝所寫每一段註釋、每一次 commit message、每一份 bug report、每一個提問,皆將於未來繼續「發聲」。彼等將為用戶所見、為維護者所見、為日後之汝所見,亦將為數年後接手此段代碼之工程師所見。
由此觀之,軟體開發實不惟「寫代碼」,更在持續進行一種跨時間、跨角色之溝通。
而優秀工程師之價值,往往即體現於此溝通品質之上。
代碼為機器執行,工程文檔為人理解
程式固然須能運行,然一項目能否長期維護,多時取決於人能否快速理解之。
未來閱讀汝代碼之人,或為:
- 汝之同事
- 代碼評審者
- 倉庫維護者
- 新入團隊之工程師
- 數月後之汝自身
彼等所面對者,並非汝寫代碼時腦中上下文,僅能見汝所留之「痕跡」。
此等痕跡包括:
- 代碼註釋
- commit message
- PR 描述
- issue 與 bug report
- 討論串中之問題與回答
此等內容之品質,直接決定他人理解汝工作之成本,亦決定協作是否順暢。
換言之,工程協作之本質,乃降低他人重建上下文之成本。
佳註釋,非重複代碼,乃解釋「為何」
諸多初學者寫註釋時,喜將代碼再翻譯一遍。例如:
i += 1 # i 加 1此類註釋幾無價值,因代碼本身已說明「做了何事」。
真正有價值之註釋,應回答此等問題:
- 此處為何要如此做?
- 有無易誤解之邊界條件?
- 此實現乃規避何歷史問題?
- 為何未採用另一種看似更直觀之寫法?
亦即,代碼負責表達 what,註釋更應補充 why 與 why not。
一經驗判斷標準為:
若刪除註釋,讀代碼之人仍知「其做何事」,然不知「為何必須如此做」,則此條註釋即為有價值。
Commit message 之核心,非描述改何,乃解釋為何改
諸多團隊之提交記錄如此:
- fix bug
- update code
- small changes
- refactor
- wip
此等資訊對於版本控制系統或「夠用」,然對於協作者幾無幫助。
佳 commit message,應盡量回答一關鍵問題:
是何問題迫使汝做出此次修改?
因代碼 diff 已能展示「改何處」,然其不能自動告知他人:
- 改動背後之觸發原因為何
- 此次修改乃修復何現象
- 此改動為相容、效能、穩定性,抑或可維護性
- 為何此方案較其他方案更合適
例如,相較:
fix login bug
更具資訊量之寫法為:
prevent login failure when session cookie expires during OAuth callback
前者僅告知他人「修了登入問題」,後者則給出具體場景與問題邊界。
優秀之提交記錄,不惟為當前評審方便,更為未來之排查、回溯與知識傳遞做準備。
當團隊需定位一問題「自何次修改引入」時,清晰之 commit history 往往能節省大量時間。
Bug report 寫得好,乃助問題更快被解決
眾人提 bug 時,預設思路為:「吾已發現問題,開發應去查。」
然自維護者視角觀之,一 bug 能否快速被處理,往往取決於報告是否足夠具體、可驗證、可復現。
一份高品質之 bug report,至少應回答以下問題:
1. 問題為何
勿僅寫「不能用」「有問題」「出錯了」。
應盡量描述具體現象,例如:
- 點擊保存按鈕後頁面無回應
- 上傳 50MB 以上文件時接口返回 500
- 移動端切換深色模式後導航欄文字消失
2. 復現步驟為何
維護者最需者乃一條可重複執行之路徑。
例如:
- 使用普通用戶帳號登入
- 進入個人資料頁面
- 上傳超過 50MB 之 PNG 圖片
- 點擊保存
- 頁面提示上傳成功,然刷新後頭像未更新
3. 預期結果與實際結果分別為何
此乃諸多 bug report 缺失之部分。
明確寫出,他人方能快速判斷此究竟為 bug、需求理解偏差,抑或環境問題。
4. 問題出現之環境為何
例如:
- 瀏覽器版本
- 作業系統
- App 版本
- 分支 / 提交號
- 測試環境抑或生產環境
5. 有無額外線索
譬如:
- 報錯截圖
- 日誌片段
- 相關請求參數
- 是否穩定復現
- 是否自某次變更後開始出現
一份佳 bug report,本質上乃減少維護者之猜謎時間。
汝提供之資訊越清晰,問題進入修復流程之速度通常即越快。
面向維護者溝通,方更易獲得回應
無論提 issue、發 PR,抑或請求他人幫忙,本質上汝皆在與「有諸多事務待辦之人」溝通。
彼等通常不會先立於汝之角度想:「此問題對汝多重要」,而會先本能地判斷:
- 吾需花多少時間方能看懂?
- 此是否為一真實且明確之問題?
- 此請求是否已做基本功?
- 吾此刻介入,能否有效推進?
故,佳溝通不惟「將問題拋出」,乃讓對方低成本地進入問題。
此意味汝需提前做好此事:
- 給出背景,而非僅扔結論
- 給出證據,而非僅給判斷
- 給出復現路徑,而非僅說「有 bug」
- 給出汝已嘗試過何,而非將排查完全外包予他人
當他人覺「此事值得處理,且吾能快速上手」,回應率自然高許多。
提問能力,往往較答案本身更重要
工程團隊中一常見問題為:
非無人願助汝,乃汝之問題使他人難助。
例如:
- 「此為何不行?」
- 「吾此處報錯了怎麼辦?」
- 「有人知如何改否?」
- 「此庫是否有問題?」
此類問題之問題在於:資訊密度太低,他人需先反過來審問汝,方能開始思考。
一更佳之提問方式,通常包含此數元素:
1. 目標
汝欲實現何?
2. 現象
此刻具體發生何事?
3. 已嘗試內容
汝已排查過何?
4. 卡點
汝目前最不確定之處何在?
譬如,與其問:
為何接口不工作?
不如問:
吾在本地調用/api/upload時持續收到 403。已確認 token 有效,且同帳號訪問其他接口正常。
吾檢查了請求頭,發現僅有此接口需要額外的
X-Workspace-Id。吾目前不確定是權限配置問題,抑或網關攔截。
有無人知此接口在本地調試時尚需補何上下文?
此種問題更易獲得高品質回答,因他人無需從零開始推測汝遭遇何事。
佳問題之本質,乃讓他人可直接進入分析,而非先進入資訊採集。
工程協作中最被低估之能力:替他人節省上下文切換成本
為何有之工程師總能推動事務向前,而有人明明亦很努力,卻總讓協作卡住?
差別往往不在技術深度,而在是否能替他人節省理解成本。
汝寫之內容越清楚,他人即越易:
- 快速 review
- 快速定位問題
- 快速判斷優先級
- 快速決定是否採納汝之方案
- 快速接手後續工作
反之,模糊之提交說明、含混之 bug 描述、低品質之提問,會將大量工作變成「二次溝通」與「重複確認」。
而此正是團隊效率被悄悄吞噬之處。
優秀工程師,不惟寫代碼之人,亦是留下清晰軌跡之人
回首觀之,軟體工程中諸多高品質協作,並非因某人「特別會說」,而是因其所留每一工程痕跡皆足夠清晰:
- 註釋解釋關鍵決策
- commit message 說明變更動機
- bug report 助他人快速復現
- 提問方式讓討論直達核心
- PR 描述讓評審者迅速進入上下文
此等看似不像「核心開發工作」,卻決定團隊能否高效運轉。
真正優秀之工程師,所寫下不惟代碼,尚有能被後來者理解之意圖。
結語
代碼會運行一陣子,然溝通痕跡會影響很久。
今日汝寫下之一條註釋、一次提交說明、一份問題報告,或於數月後,助某同事節省數小時;或於數年後,助未來之汝少走諸多彎路。
故,勿僅問己:
此段代碼能否跑?
亦多問一句:
當他人見此次改動時,能否快速理解吾為何如此做?
此,往往方是工程成熟度真正開始出現之處。