諸多工程師以「寫出能運行之代碼」為工作完成之時。

然真正成熟之軟體工程,遠不止於此。

汝所寫每一段註釋、每一次 commit message、每一份 bug report、每一個提問,皆將於未來繼續「發聲」。彼等將為用戶所見、為維護者所見、為日後之汝所見,亦將為數年後接手此段代碼之工程師所見。

由此觀之,軟體開發實不惟「寫代碼」,更在持續進行一種跨時間、跨角色之溝通。

而優秀工程師之價值,往往即體現於此溝通品質之上。

代碼為機器執行,工程文檔為人理解

程式固然須能運行,然一項目能否長期維護,多時取決於人能否快速理解之。

未來閱讀汝代碼之人,或為:

  • 汝之同事
  • 代碼評審者
  • 倉庫維護者
  • 新入團隊之工程師
  • 數月後之汝自身

彼等所面對者,並非汝寫代碼時腦中上下文,僅能見汝所留之「痕跡」。

此等痕跡包括:

  • 代碼註釋
  • commit message
  • PR 描述
  • issue 與 bug report
  • 討論串中之問題與回答

此等內容之品質,直接決定他人理解汝工作之成本,亦決定協作是否順暢。

換言之,工程協作之本質,乃降低他人重建上下文之成本。

佳註釋,非重複代碼,乃解釋「為何」

諸多初學者寫註釋時,喜將代碼再翻譯一遍。例如:

i += 1  # i 加 1

此類註釋幾無價值,因代碼本身已說明「做了何事」。

真正有價值之註釋,應回答此等問題:

  • 此處為何要如此做?
  • 有無易誤解之邊界條件?
  • 此實現乃規避何歷史問題?
  • 為何未採用另一種看似更直觀之寫法?

亦即,代碼負責表達 what,註釋更應補充 whywhy 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. 復現步驟為何

維護者最需者乃一條可重複執行之路徑。

例如:

  1. 使用普通用戶帳號登入
  2. 進入個人資料頁面
  3. 上傳超過 50MB 之 PNG 圖片
  4. 點擊保存
  5. 頁面提示上傳成功,然刷新後頭像未更新

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 描述讓評審者迅速進入上下文

此等看似不像「核心開發工作」,卻決定團隊能否高效運轉。

真正優秀之工程師,所寫下不惟代碼,尚有能被後來者理解之意圖。

結語

代碼會運行一陣子,然溝通痕跡會影響很久。

今日汝寫下之一條註釋、一次提交說明、一份問題報告,或於數月後,助某同事節省數小時;或於數年後,助未來之汝少走諸多彎路。

故,勿僅問己:

此段代碼能否跑?

亦多問一句:

當他人見此次改動時,能否快速理解吾為何如此做?

此,往往方是工程成熟度真正開始出現之處。