職涯發展的第一步是認識自己。理解你的動機、優勢和劣勢,才能做出正確的職涯選擇。
職涯方向的自我檢視#
關於職涯方向#
- 我當初為什麼成為程式設計師?(我的初心是什麼?)
- 我在目前的角色中成長嗎?有什麼證據?
- 我能看到未來五年在現有公司/行業的發展路徑嗎?
- 什麼讓我興奮?什麼讓我疲憊?
- 第 7 年、第 10 年、第 15 年的成功對我來說是什麼樣子?
關於技能發展#
- 我的技能地圖是什麼?哪裡密集(深度)、哪裡稀疏(缺失)?
- 哪三個領域的提升能帶來最大價值?
- 我的學習有多少是刻意的,有多少是被動反應式的?
- 我正在建立深度還是廣度?是否需要重新平衡?
關於晉升準備#
- 我能展示處理複雜問題的能力嗎?
- 我能展現當責意識嗎?(當我負責某事時會怎樣?)
- 我的工作是否跨越多個領域?
- 我的深度故事是什麼?(為什麼我是領域 X 的專家?)
用好時光日誌找線索#
光靠「擔心、分析、推測」無法認識自己——那不是設計人生,而是糾結人生。要走出迷霧,得靠兩個可觀察的線索:投入程度(Engagement) 與 精力(Energy)。
連續三週,每天花幾分鐘記錄主要活動,標示兩個指標:
| 線索 | 觀察 | 警訊 |
|---|---|---|
| 投入 | 什麼時刻興奮、專注、忘記時間(心流)? | 無聊、煩躁是小損耗 |
| 精力 | 哪些活動補充精力、哪些消耗精力? | 「被抽乾」是真正要警覺的訊號 |
投入 ≠ 精力充沛。有人辯論時極度專注(高投入),卻每次辯完筋疲力盡(低精力)。要分辨兩者。
記錄要越具體越好:「員工會議很開心」應細化成「當我把同事的話重新表達、大家說『對!就是這個!』那一刻」——這才看得出你享受的是「精準重述想法」還是「促成共識」,兩者職涯方向截然不同。
職涯一生加起來約 90,000 ~ 125,000 小時。若絕大多數時間不能讓你「活過來」,它就在一點一滴消耗你。
程式設計師的技能地圖#
必須精通(深度)#
| 技能 | 說明 |
|---|---|
| 開發平台 | 精通一個特定的語言生態系統 |
| 核心演算法 | 不是死記硬背,而是理解時間/空間複雜度的思維方式 |
| 資料結構 | 陣列、鏈結串列、堆疊、佇列、樹、圖及其變體 |
必須理解(廣度)#
| 技能 | 說明 |
|---|---|
| 資料儲存 | SQL、NoSQL、快取系統及其適用場景 |
| 測試方法 | TDD 思維、單元測試紀律 |
| 工程標準 | 程式碼組織、風格一致性 |
| 開發流程 | 敏捷方法論和團隊工作流程 |
| 版本控制 | Git 基礎(分支、合併、歷史) |
最初的 10,000 小時將用於獲取這個基礎。有一張地圖,才能刻意建構,而不是隨機學習。
回饋分析法:辨識你真正的優勢#
多數人自以為知道自己擅長什麼,但通常都搞錯了——連自以為「不擅長什麼」也常判斷失準。重點在於:人只能靠優勢創造績效,不可能在弱點上建立卓越。
辨識優勢唯一可靠的方法是「回饋分析(feedback analysis)」:
- 每當做出重要技術決策或關鍵行動時,寫下你預期會發生什麼
- 九到十二個月後,把實際結果與當初的預期對照
- 持續比對,二到三年內就能看清自己的優勢輪廓
回饋分析會揭示四件事:優勢在哪裡、哪些壞習慣阻礙了優勢、哪些領域只是普通水準、哪些領域再努力也無法勝任。
從回饋導出的五個行動原則#
| 原則 | 做法 |
|---|---|
| 專注優勢 | 把自己放到優勢能產出成果的位置,而非花力氣修補弱點 |
| 強化優勢 | 補強優勢周圍的知識缺口(「數學家是天生的,但人人都能學會三角函數」) |
| 克服智識傲慢 | 別以「不懂人」「不懂業務」為傲——以無知為榮等於自我設限 |
| 修正壞習慣 | 例如「只會規劃、不會執行」「缺乏基本禮貌」,都會在合作時讓聰明工作失敗 |
| 知道不該做什麼 | 在毫無天賦的領域,不要把力氣投入「從無能變平庸」 |
把無能者改造成平庸者,所需精力遠大於把優秀者推向卓越。能量、時間應投入後者。
比優勢更關鍵:我如何發揮績效#
對知識工作者而言,「我如何把事情做好」可能比「我的優勢是什麼」更關鍵。幾個必問:
- 我是讀者還是聽者? 用錯方式接收資訊,連別人的話都吸收不進去。
- 我如何學習? 靠寫作、記筆記、實作、聽自己說話——學習方式至少有六種以上。
- 我擅長獨立還是合作? 決策者還是顧問?在大組織還是小組織表現好?
結論值得重複:不要試圖改變自己(你大概不會成功),而是努力改善發揮績效的方式,並盡量不接下你注定做不好的工作。
三種程式碼類型#
這個分類呼應 高效工作方法論 — 核心原則 提到的「本質複雜度 vs 偶然複雜度」:功能程式碼處理本質複雜度,控制與運維程式碼則是為了應對部署環境帶來的偶然複雜度。
每個生產系統都包含:
flowchart LR
subgraph 三種程式碼
F[🔧 功能程式碼<br/>業務邏輯]
C[⚙️ 控制程式碼<br/>性能・可靠性]
O[📊 運維程式碼<br/>可觀測性]
end
F --- C --- O
style F fill:#e3f2fd,stroke:#1565c0
style C fill:#fff3e0,stroke:#ef6c00
style O fill:#f3e5f5,stroke:#7b1fa21. 功能程式碼(Functional Code)#
業務邏輯的實現。
- 複雜性來自理解真實需求,而非編碼本身
- 最難的部分是橋接:使用者意圖 → 功能需求 → 實現
範例:「刪除訊息」的多種使用者意圖
- 撤回未發送的訊息
- 隱藏歷史記錄
- 限制訊息傳播
- 徹底刪除資料
每種意圖對應不同的技術實現。
2. 控制程式碼(Control Code)#
執行策略、性能、可靠性。
- 非功能性考量:負載均衡、限流、故障轉移、重試
- 現代框架已封裝大部分,但你必須理解原理
- 應與功能程式碼分離,避免糾纏
3. 運維程式碼(Operations Code)#
可觀測性和運行時管理。
- 日誌、指標、動態配置、監控
- 經常在問題發生後才補上——最好提前設計
- 啟用生產環境除錯和快速恢復
這三種程式碼應該有清晰的邊界。優雅的系統展現乾淨的分離——它們與功能本身同樣重要。
從粗放到精益的成長#
階段一:粗放而豐富#
- 大量輸出,透過實踐學習
- 快速完成功能,快速迭代
- 感覺浪費但卻是必要的,用於建立直覺
- 這個階段是必經之路
階段二:精益而精練#
- 品質改進,深思熟慮的設計
- 在努力和收益之間做權衡
- 重構成為循環的一部分
- 從完成的工作中提取可重用的模式
你必須經過階段一才能到達階段二。沒有捷徑。
炫技 vs 克制#
炫技(Show-off Code)#
- 不必要地使用複雜技術
- 添加超出問題需要的抽象層
- 更容易引入 bug
- 例如:為偽狀態使用狀態機,而不是真正的領域狀態
克制(Restrained Code)#
- 直接、可讀、高效
- 即使看不懂細節也能看到結構
- 在真正需要時才使用技術,而非提前使用
- 等待合適的時機應用新技術
年輕工程師容易混淆技術深度和技術難度。真正的深度是知道何時不使用高階技術。
架構 vs 實現#
| 面向 | 架構 | 實現 |
|---|---|---|
| 關注點 | 邊界、分解、交互、組裝 | 選擇、設計、效率、穩定性 |
| 核心焦點 | 管理系統「熵」 | 追求「簡潔」 |
| 溝通方式 | 文件、決策、原則 | 程式碼、測試、部署 |
| 工作層級 | 高(系統)、中(模組)、低(程式碼結構) | 在架構邊界內工作 |
架構與實現之間的斷裂帶#
- 靜態文件 vs 動態執行
- 團隊規模造成溝通障礙
- 解決方案:關注邊界和戰略位置,而非每個細節
- 接受系統會演化——引導演化,而非完全控制
系統設計的五個視圖#
mindmap
root((系統設計<br/>五視圖))
組成視圖
存在哪些服務/組件?
交互視圖
組件如何通信?
依賴關係、流程
部署視圖
在哪裡部署?
如何部署?
流程視圖
業務邏輯
控制邏輯
狀態視圖
存在哪些狀態?
如何轉換?| 視圖 | 問題 |
|---|---|
| 組成視圖 | 存在哪些服務/組件? |
| 交互視圖 | 組件如何通信?(依賴、流程) |
| 部署視圖 | 在哪裡、如何部署? |
| 流程視圖 | 業務和控制邏輯是什麼? |
| 狀態視圖 | 存在哪些狀態、如何轉換? |
就像工程的「三視圖」,但用於軟體系統。透過多個視角全面理解系統。