Skip to content

Latest commit

 

History

History
721 lines (557 loc) · 47.5 KB

2022-08-29:Addy: Software Engineering - The Soft Parts.md

File metadata and controls

721 lines (557 loc) · 47.5 KB

2022-08-29:Addy: Software Engineering - The Soft Parts.md

JUNE 14, 2022 Addy Osmani

學習新事物

以下幾點應該可以幫助大多 junior, mid 向前邁進,應對不斷變化的技術,並在遵循軟體工程範式的標準流程和發現新的最佳實踐的同時構建複雜的系統

  • 盡可能地應用第一原則。學會將問題分解成小塊,是生活中最重要的技能之一

掌握技術

掌握技術意味著所提供的價值與工作時間的比率很高

  • 意味能分辨出能增加價值的任務,並幫助團隊把精力集中在這個方向上
  • 也意味著知道如何避免那些不能為團隊/公司提供價值的工作
  • 最好的工程師可以引導整個團隊遠離那些並不有用的工作

我經常被問到,「我怎麼知道我的時間是否得到了最好的利用?」

  • 幾乎總是會有一些任務可以填補你的時間,讓你「感覺」到忙碌
  • 真正的訣竅是確保在正確的事情上工作。如果想移山,就專注於那些能移動的任務,即使這種移動很小

你可以問自己一些問題:

  • 我的目標是什麼?我所關注的任務是否與這些目標一致?
  • 是否有一些我可以做得不同或更好的事情?

即使是問自己這樣的問題,也會有超乎尋常的力量。

批判性思考並提出有理有據的論點

批判性思維是使用認知技能獨立思考的能力,以做出深思熟慮的決定。對這項技能進行投資,以提高思維清晰度

  • 作為工程師,有時會急於馬上解決一個問題,以便讓人覺得我們正在取得進展,或者看起來我們正在對利益相關者作出回應
  • 如果沒有充分考慮原因和後果,這可能會帶來風險

換句話說,批判性思維是有目的的思考並形成自己的結論

  • 這種以目標為導向的思考可以幫助你專注於根本原因的問題,避免未來因沒有牢記原因和後果而產生的問題

大致上,一些批判性思維的基礎上提出的一些問題是:

  • 如何知道我們正在解決正確的問題?
  • 如何知道我們在以正確的方式解決問題? (即在我們對問題和約束條件的理解下,平衡嚴謹性和效率)
  • 如果我們不知道問題的來源,我們怎麼能確定根本原因?
  • 我們如何將關鍵問題分解成更小的問題,以便我們能夠進一步分析?
  • 一旦有了一個或多個假設,我們該如何安排工作來評估這些假設?
  • 如果我們受到限制(時間壓力),我們可以採取什麼捷徑,而不過度影響我們圍繞問題的分析的嚴謹性?
  • 證據是否充分支持結論?
  • 我們如何知道我們何時完成?什麼時候解決方案才算 "足夠好"?
  • 如何將解決方案清晰合理地傳達給所有利益相關者?

我發現這些問題往往有幫助

  • 有時,我們會解決一個問題的症狀,但卻發現還有其他的症狀冒出來
  • 在其他時候,我們可能會迅速地推出一個解決方案,但在以後的道路上會產生更多的問題
  • 有了批判性思維的鏡頭,我們可能會挑戰假設,仔細觀察風險/效益,尋找矛盾的證據,評估可信度
    • 並尋找更多的 data 來建立我們正在做正確的事情的信心

例如,我見過的工程師常犯的一個錯誤是假設相關關係意味著因果關係(即兩件事情相關並不一定意味著一件事情導致另一件事情)

  • 批判性思維者可能會反駁這樣的假設,問我們為什麼相信它們是真的。

Critical thinkers:

  • 提出有意識的問題,清晰準確地表述這些問題
  • 收集和評估相關訊息,驗證他們如何回答這個問題
  • 得出有理有據的結論和解決方案,用相關的標準和規範來檢驗它們
  • 在其他思想體系中進行開放性思考,必要時認識和評估其假設、影響和實際後果
  • 在找出複雜問題的解決方案時與他人進行有效溝通
  • 批判性思維具有 "軟技能 "和 "硬技能 "兩方面的特點,因此也包括在這篇報導中

建立一個強大的基礎

掌握基礎知識並反复應用,以獲得新的技能

  • 學習基礎知識的長期價值在於它們是可以轉移的。
  • 期而言,它們可以幫助你做出更好的決定,並能使 code 更有效率

可轉移的技能

可轉移的技能是那些你可以從一個 project 帶到另一個 project 的技能

基本原理是任何軟體工程職業的基礎

  • 有兩個層次--宏觀和微觀
  • 宏觀層是軟體工程的核心,微觀層是實現(如 tech stack, libraries, frameworks 等)。

在宏觀層面上:

  • 學習的程式概念在很大程度上是可以轉移的,不管是什麼語言。語法可能有所不同,但核心思想仍然是相同的
    • 包括: data 結構(數組、對象、模塊、hashes)、算法(搜索、排序)、架構(設計模式、狀態管理),甚至性能優化(如急於求成與懶惰評估、記憶化、緩caching, lazy-loading 等)。這些都是會經常使用的概念,對它們進行逆向了解會有很大的價值

在微觀層面上

  • 要學習這些概念的實現
  • 這可能包括:使用的語言(JavaScript、Python、Ruby等),使用的框架(如React、Angular、Vue等),使用的後端(如Django、Rails等),以及使用的 tech stack(如 Google App Engine, GCP 等)
    • 其中涉及到一些細節,這些細節對獲得專業知識是有價值的,以達到有效的目的,但並不總是可以轉移

通過學習基礎知識,你可以獲得技能和工具,然後忽略基礎知識,獲得成長。

  • 也就是說,從實際出發,沒有人有時間在職業生涯的開始階段學習所有的東西
  • 總有一天,你不應該過度關注基礎知識,而應該學習為現實世界建立應用所需要的東西。這就是 "邊做邊學 "方法的用處

效率

充分了解基本原理可以幫助你寫出更有效的 code

  • 這包括一些概念,如時間複雜度,記憶體使用量,以及性能和可維護性之間的權衡
  • 這些概念可以讓你在構建任何合理的大型應用時做出權衡

這很有幫助。速度對於現代應用程序來說往往是至關重要的,而且往往會以明顯的方式影響終端使用者的體驗

更好的決策

對宏觀和微觀基本面有很好的了解可以幫助你做出更好的決策。

  • 你可以利用你所獲得的知識,根據任何 project 的目標和約束條件,對使用哪些技術和避免哪些技術做出更好的決定
  • 這可以幫助你避免選擇錯誤的技術或錯誤的工具來完成工作的陷阱

"你還沒有掌握一個工具,直到你明白什麼時候不應該使用它。" - @kelseyhightower

軟體工程涉及到許多不同層面的思考

  • 核心語言、實施、基礎設施、工具和人員
  • 只有對這些層面有一個表面上的了解,絕對可以讓你更快地構建
  • 但真正了解基本原理(包括O(n)時間複雜度)可以幫助你走得更遠,特別是當語言和框架的格局隨著時間的推移而改變時

專注在使用者,其他的都會跟上

從使用者體驗開始,倒推到你需要的技術
Steve Jobs 曾說過一句著名的話: 「你必須從客戶體驗開始,然後向後推到技術。你不能從技術開始,然後再想辦法把它賣到哪裡去」

這句話讓我記憶猶新,因為作為工程師

  • 我們太容易從想要使用特定解決方案的地方開始
  • 無論是由於流行、開發人員的經驗或只是個人偏好,並試圖找到一種方法來合理地使用它們
  • 相反,我們應該專注於我們是為誰建立的,他們有什麼問題,以及目前可用的選項是如何落空的

一個使用者在慶祝他們喜歡的功能的推出

  • 偉大的使用者體驗來自於兩個觀點的結合,客戶和技術
  • 向人們展示你認為他們想要的東西,並注意他們所說的話
  • 當然,這個問題的空間有巨大的細微差別,什麼樣的工程選擇能讓你在 mobile hardware 上提供一個偉大的體驗?
    • 哪些選擇會影響工程速度、規模或招聘?
    • 最終,我們受益於對客戶的不懈關注,然後在我們必須工作的限制條件下,引導我們解決他們的需求

最好的軟體是由那些對使用者有同理心的工程師建造的

企業的成功取決於客戶的滿意度

  • 而客戶的滿意度在軟體方面往往轉化為使用者體驗
  • 了解 end user 如何體驗產品或服務
  • 確保你的解決方案不會妨礙他們有效地完成工作
  • 如果允許你與 end user 直接互動,嘗試更好地了解他們的需求和痛點

提升你的技能

選擇適合你的使用情況的東西,而不是選擇流行趨勢

  • 使用「無聊」的技術(經過測試的技術)與炒作的技術相比,是可以的
  • 語言、框架和 library 經常演變。選擇有助於提供一個偉大的最終產品的東西
  • 當開始一個新 project 時,從「無聊」的技術開始(但很好理解),然後有意識地決定從它中選擇最好的工具來解決一個問題

當挑選要學習或使用的新技能時,不要害怕選擇一些無聊的、沒有新聞的東西

  • 當涉及到技術時,無論是語言、框架,還是 library 和工具,FOMO 可能都不會有成效
  • 雖然知道使用什麼很重要,但你的主要目標是提供一個優秀的最終產品
  • 不要追逐新的和閃亮的技術,除非認為它們為解決方案增加了價值
  • 同時,也不要因為某些東西沒有被充分討論而迴避它

利用新 project 來學習新技術。

個人和黑客馬拉松 project 也是學習新技術的好機會

  • 許多人有較少的機會開始做一些全新的事情
  • 這樣的 project 可以成為研究新技術的低風險方式,評估其優點和缺點(小規模),並積累些第一手的知識,這些知識對將來可能是有價值的

保持好奇心,永不停止學習

寫下你學到的東西。它促使你更好地理解主題

  • 只有當你嘗試向別人解釋事情時,你的知識差距才會變得清晰
  • 如果沒有人讀你寫的東西也沒關係。你只需為自己做這件事,就能得到很多好處
  • 學習應該是一個持續的過程
  • 真正的專家精通技術,但意識到總是有學習和改進的餘地

好奇心是學習的動力,因此

  • 如果對一個新的框架感到好奇,就用 google 它,閱讀文件,試試 tutorials,讀 source code
  • 學習不需要發生在教室裡。它可以在任何地方、任何時間發生
  • 每天花半小時閱讀教科書中的一個章節,聽技術 podcast,閱讀開發 blog 或學習新的程式語言

對領導者來說,承認自己不知道的事情是很有力量的。

  • 有了這種自信,就會降低人們對 Senior 工程師必須了解一切的期望
  • 你絕對不需要擁有所有的答案,但能夠承認你是人,並致力於與你的團隊一起找出解決問題的方法,這才是重要的部分

領導者在犯錯時也要承認

  • 教會你的團隊如何謙虛地處理錯誤,並渴望學習和改進,這很重要
  • 現實世界並不完美,向你的團隊展示它的不完美是完全可以的,讓他們做好心理準備

做一個看守者,而不是一個所有者 (Be a caretaker, rather than an owner)

在 open-source project 的早期階段

  • 像所有者一樣思考是很常見的。你經常直接擁有證明價值,開發 featre、回答問題和宣傳
  • 但當人員變化或你自己的時間有限時,這可能不是擴展 project 的最佳方式
  • 在最初的緊縮之後,另一種思考方式是將你的角色演變為一個看守者,而不是所有者
  • 一個看守人可能會專注於擴大自己的規模。這可以通過與其他維護者、貢獻者和社區分享盡可能多的知識
    • (通過設計文件、code 註釋和其他記錄的最佳實踐)
    • 這也有助於增加 reviewer 的數量,使其在你不再參與的情況下做出正確的決定

這往往是 project 在多年後可持續發展所需要的

技能的深度和廣度

考慮一下做一個萬能的人和一個大師是否適合你。

  • 你能掌握的最偉大的技能之一是學習如何學習
  • 這應該是一個優先事項,而不是說僅僅深入研究特定的程式語言或框架
  • 這有助於保持好奇心。一旦有了這方面的經驗,你可能會問,你的目標是成為一個專家還是一個萬能的人

在中等規模的團隊中

  • 擁有某個領域的專業技能和技能、多才多藝、善於合作的人,在必要時可以替代其他人,這是很有效的

體驗就是學習

當學習一門新的語言時,要專注於用它建立一些有形的東西,給你帶來第一手的經驗

  • 如果正在學習一種新的語言,你不需要為了成為好的開發者而記住它的所有語法或文件
  • 更重要的是要知道如何解決問題。通過寫大量的相關 code 或從現有的 code 中學習來贏得經驗
  • 其結果應該有助於你用該語言寫出高效的 code
  • 軟體的主要價值不是產生的 code,而是產生 code 的人所積累的知識

技術的複雜性

通用 code 與特定 code

為手頭的問題編寫專門的 code

  • 但要努力發現那些可以使其成為一個小的通用的 code
  • 通常情況下,我們試圖把 code 寫得盡可能的通用,最終卻使那些有效的 code 不能幫助完成問題
  • 相反,專門為這個問題而構建,但試圖發現可以讓它變得更通用的地方

有幾條通常討論的原則是關於設計複雜性的。在極限程式的世界裡,你有。

  • YAGNI (You aren't gonna need it, 或者你不需要它),它指出工程師不應該增加功能,直到它是必要的
  • 做最簡單的可能工作的事情,以取得快速進展,而不是為未來做計劃

這兩個原則的目的是防止過度工程化。然而

  • 這些原則可能會被濫用,從而創造出多個簡單的解決方案,但卻不能很好地整合

在光譜的另一端

  • 你有一個抽象原則,旨在通過抽象和泛化,盡可能地減少 code 中的重複結構
  • 在極端的抽象和極端的簡單之間選擇一個中間地帶,使 code 有一點通用性。AHA(避免草率的抽象)原則也提倡類似的想法

Deep modules

編寫 code ,為其他開發者解決複雜的問題,但通過一個清晰的 interface exposes 功能
如果你是一個 API 設計者或開發者,你的責任是提供一個 interface,為其他開發者簡化複雜的功能

  • 如果 interface 太難理解,並且給使用它的工程師帶來了成本,那麼這個目的就落空了

這個想法反映在深度模塊(Deep Modules)的概念中

  • 最好的 modules 是那些具有最大利益和最小成本的模塊
  • 一個 modules 提供的好處是它的功能,而一個 modules 的成本是它的 interface

雖然 interface 的簡單性是可取的,但複雜的問題有時需要復雜的 code 來解決

  • 這種複雜性最好嵌入到 code 中去。當複雜的功能被抽象化時,提供給終端使用者或 interface 使用者的價值就會更高
  • 一個包含多個可見 functions/class 的 API 與另一個使用較少的 public functions/classes 實現相同功能的 API 相比,更加複雜,搜索起來也更具挑戰性
    • 新的 functions/class 增加了維護工程師和 library 使用者的 interface 成本

在維護 project 中的學習

在處理舊系統中的 legacy code 時

  • 要理解該留的 code 和該走的 code 之間的區別
  • 任何高級工程師都應該努力理解該留的 code 和該走的 code 之間的區別

理解該留的 code 和該走的 code 之間的區別很重要

  • 大型的、長期的生產系統會有一些不好的 code,或者沒有很好的理由再保留的 code
  • 欣賞一些東西存在的原因是健康的(好的原因?壞的原因?)刪除壞的 code,保留好的 code

軟體行業已經到了一個階段,許多 project 都在處理舊的或遺留系統的維護和遷移問題

  • 如果發現自己在這樣的團隊中,不要感到沮喪。通過查看舊 code ,你可以獲得很多特定領域的知識
  • 雖然老的 code/validations 可能有很好的理由存在於 production 中,但不要認為每一行都仍然相關,這是健康的

一些軟體工程師對觸碰生產中的 code 持謹慎態度

  • 因為擔心會引入一個錯誤
  • 因此,他們為新的用例加入條件並重複一些 code
  • 這樣的變通方法在那一瞬間可能會節省時間,但隨著時間的推移,它們會成為維護的惡夢
  • 不要假設現有的 code 是無懈可擊的。可能有一些之前被忽視的可擴展性或效率方面的問題,你可以解決

在一個綠地 project 上的學習

實驗,創新,快速失敗,更好地解決問題

  • 當你的任務是從頭開始建立一個系統時,你的學習之旅是完全不同的
  • 當開始迭代原型或開發功能時,你會學習什麼是有效的,什麼是無效的
  • 敏捷方法論和快速失敗原則幫助你用更少的資源提前驗證你的想法。它們能夠劃分和克服複雜的問題

完成的定義

定義什麼是「完成」是很節省時間的

  • 可以幫助你估計所需的努力,計劃開發,並避免以後不必要的修改
  • 在處理複雜問題時,另一個敏捷原則也很有用,那就是就「完成」的定義達成一致
    • 除了滿足使用者需求和驗收標準外,還可以包括其他條件,如 code reviews、測試、documentation 等

分階段推出

一個大型的 release 可以分為一系列風險較低的、被充分理解的推出

  • 在計劃大規模 production 系統的 release 時,推廣計劃與架構和 code 一樣重要
  • 迭代開發的分階段 release 可以幫助你更好地管理由於明顯的大變化而帶來的風險
  • 你也可以與開發和測試策略一起創建 release 策略,為一個複雜的 release 製定一個 end-to-end 的計劃

系統性 debugging

debugging 時,你應該嘗試系統地、嚴格地解決問題,解決所有的測試條件

  • 始終讀錯誤訊息(和 stack trace)。那裡面很可能有寶貴的訊息,可以隔離問題,以便解決問題
  • 許多工程師在尋求 debugging 幫助之前,忽略了錯誤訊息所能提供的洞察力
  • 假設機器在告訴你什麼是錯的,而且可能是正確的,而不是假設做一些小的編輯和不斷地重新運行 code 會更快地解決問題
  • 如果寫了一個拋出異常的解決方案,卻沒有仔細閱讀異常訊息,你可能是在浪費時間
  • 通常情況下,錯誤或異常訊息是一個很大的提示,說明實際上出了什麼問題

設計文件

設計文件的重要性

設計文件不應該是事後的想法,而應該是軟體工程過程中的一個組成部分

  • 設計文件是一個無處不在的工具,它可以幫助你從你的同行或其他需要與你的系統部分對接的團隊那裡獲得共識
  • 來自他人的反饋使你能夠找出差距並完善設計
  • 文件可以作為未來加入團隊的工程師的寶貴助手,可以幫助他們理解問題的空間以及在設計解決方案時考慮的權衡和替代方案
  • 文件提供了一個空間來記錄所有參與設計的人和他們的貢獻,作為文件歷史的一部分
  • 這有助於其他人了解是誰推動了具體的決定,以及要聯繫誰來做進一步的闡述

文件過程

協調對設計文件的審查,並將設計的發展與原始文件進行比較,以驗證所有相關的約束條件都得到了解決

  • 雖然一個人可以記錄設計,但實際的設計過程是在一系列的白板會議、隨機的當面討論、slack、或 email /電話討論中發生的
  • 只有在把它寫在紙上之後,你才能識別出矛盾的承諾,並看看討論過的不同部分是否適合在一起
  • 在創建初稿後,協調審查可以確保所有相關方都同意
    • 然而,可能會發生這樣的情況:由於沿途發生了一些變化,已實施的設計與記錄的內容不一致。

溝通

謙虛,明確溝通,尊重他人。善待他人不需要花錢,但其影響是無價的

  • 良好的溝通需要花費精力和心思。應該有更多的精力用於同情心
  • 溝通是成為一個有效的、高產的、高效的軟體工程師所需的軟技能或人際關係技能的一個關鍵部分
  • 溝通不暢會導致功能不正確,code 不兼容,或團隊動態不協調
  • 溝通可以幫助人們更好地理解需求,防止問題升級

工程師為了確保產品對他人有幫助

  • 我們必須使我們的努力與團隊中的其他人以及業務和使用者的期望同步。這使得協作和溝通成為我們工作的關鍵支柱

Junior developers 大多與其他團隊成員、測試工程師和團隊領導溝通,分享想法並討論解決問題的替代方案

  • 隨著發展,為有效完成工作所需的溝通數量也在增加。 email 、會議和公開談話的數量增加
  • 我們必須與企業領導、經理、利益相關者和團隊成員溝通。你的工作越專業,別人不容易理解你的風險就越大

Customized 溝通

使用與你的聽眾相關的語言、概念和細節水平

  • 無論我們對一個問題或情況的理解程度如何,當與他人討論時,必須定制我們的言語,使他們能夠迅速掌握與他們相關的內容
    • 當與商業人士交談時,談論你所做的事情的商業影響。避免使用過度的技術術語
    • 當與工程管理部門交談時,傳達技術影響或挑戰
    • 當與決策者交談時,你要描述可用的選項以及它們的影響和風險,而不是選項如何運作的細節
    • 當提供狀態更新時,要注意還有什麼事情發生,以及你的更新與 project 目標有什麼關係
  • 同樣的原則也適用於寫 email 和向更多的聽眾介紹情況時。寫下與接收訊息的人相關的內容
  • 在演講時,你可能需要為你的想法辯護。以深思熟慮的方式來表達問題和回應。膝跳式的反應通常不利於溝通

善良是一種超能力,要發揮它

  • 平靜、善良和樂於助人可以讓你走得更遠,而不是打斷別人
  • 對團隊中的人好一點,這將有助於使團隊更加強大和成功
  • 對團隊以外的人也要友好。對待組織中的所有職能部門(人力資源部門、財務部門或營銷部門),要給予同等尊重
  • 你可能不會直接幫助他們,但你總是可以理解他們的工作,並與他們產生共鳴
  • 當別人做得好或獲得讚譽時,祝賀或讚賞他們。善意是會傳染的。你曾對其好的人更有可能在未來對任何援助請求作出回應

自由地告訴人們他們做得很好。

  • 雖然在需要改進的時候給予反饋很重要,但如果事情進展順利,給予人們積極的反饋也很關鍵
  • 這有助於你的團隊知道,他們正在做出改變,並受到重視

NO 的力量

說「不」比過度承諾要好

  • 在涉及更多工作的情況下,大多數人都不擅長說「不」
  • 因為他們沒有意識到「不」是一種選擇
  • 然而,過度承諾是一種責任,因為它可能導致延誤
  • 讓對方知道你已經在做什麼,並提供一個合理的估計需要多長時間,是一種尊重的表現
  • 這讓對方有機會考慮他們的選擇,要求別人或延長他們的時間表
  • 如果管理層知道這將大大影響產品的品質,他們就不會要求你在時間內交付東西

任何有生產力的人善於說不

  • 人們會要求你花費更多的時間,而不是你能抽出的時間
  • 你可以溫和但堅定地說「不」,把人們引向其他地方(委託),或者要求人們與你的經理討論是否可以分配更多的時間來幫助他們

你不可能取悅所有人,在說 yes 與 no 時要非常注意

  • 與領導者對所有事情都說 yes 相對應的是對所有事情都說 yes,卻沒有設定明確的界限
  • 承擔超過現有的資源可以合理地執行的範圍,會導致你、你的團隊和最終你的客戶感到心痛
  • 這對領導者來說尤其重要,因為其他人會指望你來製定規範,告訴他們什麼時候應該說 yes 或輕輕地推回去

接受和尊重

  • 承認你不知道的事情,並對尋求幫助持開放態度,甚至是向後輩求助
  • 承認你不知道的事情是可以的。軟體領域最重要的技能之一就是能夠找到答案並從中學習

作為 senior leader

  • 要學會接受周圍的後輩可能更了解 project 的技術細微差別
  • 當你不知道的時候,承認你不知道的事情,讓 juniors 來解釋是 OK 的
  • 他們會因為你的誠實和對學習的興趣而更加尊重你,而你也會更好地了解事情的真相,並為其增加價值
  • 作為 juniors,你應該根據 seniors 們的舒適程度,公開或閉門向他們解釋技術概念

共享資訊

利用會議和問答環節,提出正確的問題,交流知識,為團隊提供訊息

  • 在主持會議時,不要只一個人說話
  • 會議是一個讓其他人分享想法和提供誠實反饋的機會
  • 以要傾聽並為其他人的貢獻留出空間
  • Junior 可能會迴避問太多的問題。如果是 senior,你可以通過提出背景(context)來促使他們提出正確的問題
  • 在回答問題時,讓提問的人知道你很高興他們提出了這個問題

Flexibility

  • 堅定地捍衛你的觀點,但也要在每次有新的證據與你的觀點相抵觸時進行審查
  • 傾聽其他意見是溝通的關鍵部分,這是至關重要的
  • 對一個可能有不止一個解決方案的問題,與其執著於自己的觀點,不如傾聽和評估其他選擇
  • 也許他們會提出一個先前忽略的方面
  • Paul Saffo 的 principle Strong opinions weakly held 告訴我們要堅定地捍衛自己的觀點
    • 但也要在每次有新的證據與之矛盾時對其進行審查
    • 這是一種基於科學證據的方法,不考慮提出想法或意見的人

保持記錄

在非正式會議後

  • 一封友好的 email 有助於重申討論中的關鍵點或承諾。
  • 純粹的口頭交流的缺點是,它可能被遺忘或記錯
  • 將所有發生的事情記錄下來,並在相關的討論中得到簽收,可以消除這種風險
  • 如果你或其他人已經同意幫助完成一項任務,那麼通過 email 確認最後期限,以確保每個人,包括你的上司,都在同一起跑線上
  • 保留這種計劃外工作的記錄,在考核討論中也會有幫助

良好的信念 (Good faith)

  • 知道什麼時候應該保持沉默並觀察其中的動態
  • 可能會有這樣的情況:你不理解一些決定,或者這些決定由於技術和商業原因沒有意義
  • 這可能發生在多團隊的討論中。真誠地參與,並假設人們不會冒著被公開惡意攻擊的風險
  • 可能你並沒有掌握完整的情況,或者他們有不同的優先事項
  • 提出問題並陳述你的意見,不要對最後的決定感到憤怒或沮喪

資歷

我們渴望在職業生涯中成長,無論是角色還是能力

  • 有人對 senior 職位感興趣,有人則希望擔任 leadership or management roles
  • 無論是哪種情況,資歷較高的人都會表現出一些關鍵特徵
  • 在整個旅程中,你可能有導師來指導成長。下面是我對培養能使你為高級職位做好準備的素質的方法

資歷和戰略思維 (Seniority and strategic thinking)

  • 不要在不確定的情況下不做決定或不採取行動。
  • 很多時候你會發現,做任何決定都比不做決定要好。這至少可以讓別人知道你傾向於什麼方向
  • 有時候,作為領導者,沒有花足夠的時間反思我們的團隊期望我們做出什麼決定
  • 因為沒有 100% 確定掌握了所有的事實。我們可以也應該盡量建立一個完整的細節,以做出有信心的決定,但這並不總是可能的
    • (時間緊迫的情況下)這會導致團隊長時間的等待/不確定
    • 在這情況下,即使在訊息有限的情況下,積極地讓自己更好地做出決定,也會有幫助

Leaders 是那些拓寬視野,從戰略角度思考,為他人制定路線圖的人。

  • 你的戰略思考和計劃能力,以及將你的思維運用到更大範圍的能力,最好是隨著經驗的增長而增長
  • 作為一名個人貢獻者,可以專注於指定的任務或所從事的功能
  • 隨著晉升,你工作的影響已經超出了具體的任務和 project

在權衡各種選擇時

  • 你要學會從利益和製約因素的角度來看待大局
  • 軟技能的應用範圍也在增加。例如,如果早先你是為一個團隊做決定,或對團隊中的其他工程師講話
  • 隨著你的成長,你的選擇和溝通會影響到多個團隊

以身作則

教你的團隊捕魚

  • 不要總是為他們解決問題,而是溫和地引導他們發展技能,自己解決
  • Engineering leaders 要授權。當你變得更資深時,放棄你的玩具,指導、授權並使你的團隊成功
  • 這是你如何擴大效益的方法。這可以通過提出好的問題而不是(僅僅)給出答案來實現

在評估具有挑戰性的問題時

  • 你要以身作則
  • 當有人提供解決方案時,你要提出相關問題
  • 技術軌道上的前輩們負責團隊內外的協調、談判和建立共識
  • 他們為提高團隊的整體產出做出貢獻,而不僅僅是他們自己
  • 作 senior,你可能偶爾會通過編碼來獲得新的技能或了解地面實際情況,但這並不是你工作內容的一部分
  • 相反,你是一個確保架構圖中沒有任何遺漏或 code 中沒有漏洞的人
  • 你應該能夠用證據或理由來解釋你的決定,說明它們將如何提供技術或商業價值

senior engineer 應該善於架構軟體系統和人類系統或團隊

  • 你可以領導一個不同的工程師小組,把任務委託給他們,指導他們關心 code 品質/性能/簡單性
  • 你可以在需要時給予反饋,並在必要時為他們辯護
  • 同時,應該能夠推銷你自己,你的工作,以及你解決挑戰性問題的能力,以獲得組織中的知名度
  • 總的來說,你應該處理好與團隊內部人員和管理層的關係。

提高你的效率 (Scale your effectiveness)

世界上最好的工程壯舉是由工程師團隊完成的,而不是個人

  • 如果你想取得更多的成就,或者表明你已經準備好在公司中成為更「高層」,那麼就通過合作和指導來增加你的效率
  • 證明這不僅為你自己,而且為你團隊的其他成員增加價值

當擴大自己的規模

  • 必須將心態從「我」轉變為「我們」
  • 通過與他人合作,分享所學到的東西,並專注於提升周圍人的技能和專業知識,會開始完成了很多工作

當你開始作為個人貢獻者時

  • 你可能沒有一個專門的「團隊」由你領導
  • 但可以找到志同道合的人進行合作(也許與你的目標一致),一起工作,比你獨自完成更多的工作
  • 隨著你的資歷越來越深,你的這種想法會朝著建立團隊和不斷提高效率的方向發展

冒名頂替綜合症

我們所有人都曾在某個時候覺得自己不足以勝任某個角色或工作

  • 冒名頂替綜合症是真實的,而且非常普遍
  • 你可能會覺得自己是個冒牌貨,甚至在別人向你尋求建議時也是如此
  • 可能永遠無法治愈這種綜合症,但它會促使你保持好奇心,學習新事物
  • 接受犯錯、不知道答案或尋求指導是可以的,這有助於克服冒名頂替綜合症

輔導

指導他人

成為護欄(guardrail),及時提供訊息,使你的被指導者不至於最終陷入完全不正確的境地,而是通過自己的努力獲得掌握

  • 在職業生涯的不同時期,你可能會發現自己處於指導者或被指導者的角色
  • 指導不一定是正式的過程。你可以尋找機會指導他人,或者讓自己甚至非正式地接受指導
  • 指導他人使你有機會自己學習人際交往技巧

以下是指導時的一些關鍵點

  • 指導是為了引導人們自己發現答案,而不是給現成的解決方案
  • 在解決他們的問題時,允許被指導者進行試驗
  • 他們在評估風險和收益方面處於最佳位置
  • 然而,請給他們找到答案所需的工具。如果是技術問題,建議他們嘗試一些想法和方案,但讓他們做實際的工作
  • 讓他們分享他們的想法,並仔細聆聽,提出問題,並參與對話
  • 如果有人不能自己想出解決方案,向他們展示你將如何處理這個問題,以及為什麼你選擇特定的模式來解決這個問題
  • 教他們如何分析結果或調試問題
  • 實施解決方案和調試解決方案時,分享你的思考過程。分享你解決問題的技巧,而不僅僅是答案

全組織的指導 (Organization-wide mentoring)

確保指導是 senior engineer 角色的一部分,也有助於在某人轉到其他團隊、職位或組織時保留關鍵的領域知識

  • 假設你真誠地指導某人,而且這也是你工作描述的一部分
  • 在這情況下,你必須在你的時間表中為指導活動留出時間。這將使你能夠適當地進行指導
  • 並為你的被指導者的生活帶來改變。有些組織可能還根據職業發展階梯和每一階梯的要求,為指導者/被指導者的討論制定了明確的程序

被指導者的角色

導師可以為你提供建議

  • 但只有你自己才能主動採取行動,根據任何建議管理自己的職業和成長
  • 假設你是 junior,希望在一個組織中成長。在這種情況下,給你的建議只有一個。找到能夠幫助你在成長的階梯上航行的強大導師

在你的職業生涯中

  • 你會遇到教練、導師或你仰視的同事。他們可以為你提供如何發展你的技能的建議
  • 但你是可以採取行動的人。在吸收建議時,要提防關於技術的一概而論聲明
  • 不同的情況需要不同的原則,對一個 project 起作用的方法可能對另一個 project 不起作用

有效的團隊 (Effective teams)

建立信任

信任可以將團隊成員團結起來,為共同的目標而努力,而官僚主義會使他們分裂

  • 當工程師們走到一起,進行思想開放和不偏不倚的頭腦風暴時,它為推動創新的新想法和不同觀點鋪平了道路
  • 這導致了高效率和高生產力的團隊
  • 然而,只有在團隊成員之間的溝通和關係健康的情況下,團隊成員之間的有效協作才有可能

以下是建立、維持和成為有效團隊的一些要點

  • 建立信任是團隊建設中最關鍵的組成部分
  • 團隊成員之間的信任是快速完成工作和團隊有效的必要條件
  • 團隊成員可能會使用不同的軟體工程流程,如審查和測試來審查 project 的健康狀況
  • 然而,如果沒有信任,這些過程就會變得乏味和官僚化
  • 例如,如果你信任某位工程師的 code,你可能會在 code 審查中少吹毛求疵

了解商業模式

理解變化的業務影響。

  • 當收到新需求時,要理解它們背後的動機
  • 不要略過需求中的「目的」或「商業目標」部分。提出問題來理解商業模式和它與這些需求的關係
  • 現有的 code library 或與主題專家(SMEs)交談可以提供關於領域和架構的洞察力
  • 參考文件或將功能和用例映射到系統流程和 data 流

很多工程師都喜歡用技術挑戰來解決問題

  • 了解業務方面的問題,並能夠提出具有成本效益的解決方案,可能會更有意義
  • 記住,你的使用者/客戶也是在努力做他們的工作,像你一樣度過一天或一周的時間。盡量不要讓他們的生活變得更加艱難

增加你的影響

  • 對商業、軟體方程式的感知和敏銳度會增加你工作的影響力
  • 獲得對業務和產品的 360 度視角有助於你對團隊和 project 做出積極的貢獻
  • 如果你了解銷售或市場的思維方式,你就能更好地做出正確的決定,做有影響力的工作
  • 隨著你對團隊成功的影響增加,你的工作滿意度和薪酬也會提高
  • 可以在沒有監督的情況下獨立工作,通過做適合團隊、project 和業務的事情來推動整體效率

Work/life balance

如果你是一個掌握了技術能力、人為因素和領域知識的人

  • 那麼你作為一個軟體工程師的技能將無一例外地受到追捧
  • 你的團隊和組織中的人們會向你諮詢。除了你的工程承諾外,你還會成為合作過載的受害者
  • 臨時的請求會吞噬你的時間,並阻止你去做你所熱衷的事情

時間管理

為深度工作而 optimize 你的 calendar

  • 在日程表上留出時間,用於專注的深度工作
  • 我已經這樣做了很多年,發現這對編寫設計或戰略文件,或者只是處理一個困難的技術問題非常有效
  • 深度工作是指不分心的、高度集中的工作,能在很短的時間內創造大量的價值

每當你從一個任務切換到另一個任務時

  • 注意力的殘餘就會停留在對前一個任務的思考上。這使得你很難以必要的注意力來工作真正重要的事情

深度工作可以最大限度地提高在有限的時間內通過專注於單一任務而擠出來的生產力

  • 沒有分心,沒有Twitter,沒有聊天或 email 。把深度工作保留給那些認知能力強的任務。強烈建議嘗試一下。
  • 改變位置有時可以幫助進行深度工作。有時會落入一個陷阱,把一個特定的地方(如辦公桌、房間或大樓)與一種特定的任務聯繫起來,增加一點變化可以幫助我們重新振作起來

避免分裂工作時間

  • 當一個小時的工作由於分心而被分割成幾塊時,你就會感到壓力
  • 找出分心的原因(無論是你還是其他人),並解決它。否則你的一天就不會有那麼高的效率

過度工作並不是良好工作道德的一部分

  • 你永遠不可能比世界上所有人都更努力工作
  • 許多公司把工作過度的員工作為「標準」
  • 錯誤地認為這與擁有良好的工作道德是一樣的
  • 成功來自於許多因素,而不僅僅是過度工作

不斷試圖超越自己的標準是不現實的。

  • 我在這方面經常犯錯
  • 如果你想培養冷靜,避免瘋狂的工作環境,你必須對足夠的東西感到舒服
  • 作為經理或領導,你的團隊可能會以你為榜樣來處理這個問題。對足夠的事情感到滿意可以樹立一個好的榜樣

時間是有限的。與其試圖尋求更多的時間,不如消除不必要的任務:

  • 很多指導意見都談到了重新安排工作的問題
  • 真正的問題是一開始就試圖完成太多的工作
  • 消除不必要的、浪費時間的工作,而不是試圖管理有限的時間

你不需要知道每一件事情的進展。

  • 許多人害怕錯過每一個新故事或更新
  • 這是人們痴迷於每小時檢查 Twitter、Reddit 等的原因之一
  • 現實中,這些訊息中的大多數只是沒有那麼重要。可以嘗試切換到這些新聞的摘要視圖,或者對你檢查的頻率設置限制。

最好的辦法是通過學會說「不」,知道何時停止

  • 計劃好時間,包括工作之間的休息時間,積極主動地使自己免於疲憊。
  • 時間管理和保持良好的工作與生活平衡對所有級別的工程師都至關重要
  • 經常性的加班會導致倦怠和壓力。壓力會引起其他身體和精神健康的並發症
  • 在你收工前解決一個問題可能很誘人,但隨著時間的推移,這可能成為一種習慣

鼓勵自己和團隊的休息、假期和休假

  • 你的健康和家庭是至關重要的
  • 如果你作為高級工程師意識到這一點,並為團隊中的其他人樹立一個優秀的榜樣,這將促進整體健康和幸福
  • 另一方面,疲憊和倦怠會導致工作場所的毒害

隨著你對問題認識的提高,update estimates

  • 總是會有客戶或你工作的利益相關者想知道一個 project 或任務什麼時候可以交付,以及這個成本是否值得
  • 這完全合理的。有時他們想配合一個最後期限,或者在其他地方有依賴性,需要支持你的工程工作,需要計劃

軟體的最後期限是出了名的難以準確預測

  • 基於估算的最後期限應該只在 project 處於特定階段時給出
  • 時間過去後,隨著我們對團隊解決問題的能力有了更多的了解,估算應該得到更新
  • 第一個估計往往是最不可靠的,然而它是一個起點,可以隨著時間的推移而得到完善
  • 這個最初的估計往往是非常保守的
  • 如果產品需求、使用者體驗或依賴性不明確,一個更大的保守估計往往對有幫助
  • 當這種估算是與 project 管理人員合作進行的時候,我經常會取得最大的成功,這樣我們就能在改進估算方面達成一致

軟體估算的麻煩在於

  • 當第一個粗略的估算被固化為記錄的計劃,而不是初稿
  • 當關鍵路徑上的團隊採用它,但把對估算的調整看作是工程上的一個小插曲
  • 這可能是一個問題。一旦 project 獲得綠燈,要更好地弄清細節
    • 這可能意味著,基於對解決需求的更深入的理解,三個月的估計會變成兩個月(或四個月)

在可能的情況下

  • 幾乎總是希望估算能驅動你的進度,而不是讓進度驅動估算
  • 在我的團隊中,雖然我們有時會有不可動搖的最後期限(如會議),但如果估算超出了這些日期,(通常)也是可以的
  • 推遲到未來,總是我們可以與領導討論的選項。當然,這並不總是微不足道的
    • 當日程表確實試圖被拉進來時,你可以把工作分成「必須做的」和「可以做的」(並把這些移到未來的衝刺階段)
    • 然後審查「必須做的」是否符合你的最後期限

如果時間表仍然太緊,還可以問一些其他問題

  • 比如「可以為這個 project 增加更多的工程師嗎?」和
  • 「是否有一個大幅減少的範圍,仍然可以使按時交付成為可能?」

取消 project 有時是正確的(即使是不舒服的)決定。

我討厭這樣的決定,但

  • 取消一個 project 有時是對你的團隊和組織最健康的長期決定
  • 如果 project 在啟動之前就被取消了,獲得牽引力,然後最終不得不被廢棄,因為它的人員配置已經無法維持,這一點尤其正確

什麼時候會發生這種情況?

  • 你可以就投資一個新 project 做出決定,這些決定在某個時間點上是正確的
  • 在那個時間點上,星星很可能已經排列好了(市場適應性、組織買入、人員承諾),使它完全有意義
  • 一年後,事情會發生變化--市場、領導層、 project 的重要性
  • 定期檢查你在 project 開始時所作的假設是否在其生命週期內繼續保持真實性,這一點至關重要。

你越能保持對假設的信心

  • 你就越有機會使 project 能夠成功啟動並繼續得到支持
  • 取消 project 是很困難的,原因很多,其中最重要的是,有很多人帶著真實的情感投入到他們希望啟動的 project 中
  • 作為領導者,將人們從被取消的 project 中引導到其他成功啟動的 project 上是很複雜的
  • 但對於讓人們回到一個心理安全、信任和快樂的地方是很重要的
  • 在客戶方面,要注意使用者的信任,以及你的長期決定會如何影響這一點。

關於技術債務。一盎司的預防勝過一磅的治療

Titus Winters 將技術債務定義為

  • 「我們今天擁有的 code 和系統與我們希望擁有的 code 和系統之間的差異」
  • 某些類型的債務比其他類型的影響更大
  • 有些債務可能是由於沒有及早發現的錯誤(疏忽),有些是由於事後了解到的情況(事後諸葛亮),有些是由於技術系統環境的變化(背景)

堅持優先處理技術債務有時是很難的

  • 因為不可能總是量化那些沒有表現出來的錯誤或沒有發生的故障
  • 因為「把債務還得夠多」
  • 保持團隊對這種工作的興趣,並在績效評估中給予獎勵,也是非常重要的
  • 然而,一旦問題隨著時間的推移開始堆積,「治療」的成本就會高得多
    • 與污染類似,在多年的時間裡,預防技術債務是一個比後期緩解更便宜的策略

你能做些什麼來防止債務的積累?

  • 技術負責人應該在衝刺階段定期投入時間進行清理
  • 除了建立新的功能外,還要償還債務
  • 評審員應該意識到對短期速度的推動,實際上可能會導致更多的問題
  • 經理和主管應該注意批准與現有 project 重疊的新 project
    • 除非你確定這種權衡是值得的(例如,解決現有系統的債務與建立新的東西相比不值得)
  • 監測 project 的健康狀況對所有這些都非常重要。

沒有休息和良好的工作/生活平衡,你或你的團隊可能會 burnout

職業倦怠是一種由於工作場所的壓力沒有得到成功管理而產生的疲憊

  • 許多工程師在大流行期間由於工作壓力而遭遇倦怠,但它一直存在於技術領域
  • 我在每次 1:1 時都會問:「你的壓力水平如何? 我能做些什麼來幫助你?」
    • ("how are your stress levels doing? what can I do to help?")

我對職業倦怠的經驗是

  • 它發生得很慢,以冷漠結束
  • 慢慢地開始感到精力不足,沒有動力,精疲力竭,同時盡力應對工作壓力
  • 質疑自己是否有問題
  • 但沒有意識到你的身體正在加班加點地工作以彌補你的能量不足
  • 你不斷地把自己逼得越來越緊,但最終感覺已經沒有什麼可以付出了

解決的辦法是做這些事情的反面:

  • 休息,睡更多的覺
  • 從我工作的時間裡擠出更多的價值,更好地授權,並有一個明確的工作「停止時間」

作為管理者,為了避免我們 burning out

  • 嘗試鼓勵我們的團隊使用他們的假期,休息並定期檢查人們在壓力方面是否真的做得不錯

專注於 problems vs. projects

想像一下

  • 你的使用者有一個未解決的需求(例如,一個問題)
  • 當你是一個隸屬於某個特定 project 的工程師時,問你的特定 project 如何解決這個問題是很正常的

在一個擁有類似形狀 project 的大型組織中

  • 很有可能看到多個工程師試圖獨立地這樣思考("我的 project 如何解決這個問題?")
  • 然而,當你擁有一個 project 組合的時候,這可能就不太清楚了

如果使用者可能一起使用你的許多 project 呢?

  • 如果他們各自以稍微不同的方式解決這個問題而不知道對方的方法,那不是很奇怪嗎?
  • 相反,你要問「什麼才是解決這個問題的正確的 end-to-end solution?」
  • 然後回過頭來看,什麼 project 或對一系列 project 的修改能最全面地解決這個需求
    • 這可能需要讓從事多個相關 project 的人員進行更深入的合作
    • 然而,這可以在最後為你的使用者帶來一個更好的、不那麼混亂的故事。

結論

「讓優秀的人圍繞著你,與那些做得最好的人一起工作」 - Brian Staufenbiel

投資於與你可以學習的人的友誼和關係

  • 對他們的指導、輔導、他們的成功和他們的失敗持開放態度
  • 永遠不要害怕尋求幫助或洞察力。在很多情況下,它只是一個問題而已。

一個興奮的團隊

  • 記住,在一個特定的組織中,對技術、業務領域和人力資源的掌握必須隨著時間的推移而培養
  • 一個組織不可能從另一個組織聘請大師,並期望他們從第一天起就有成效
  • 如果你是一名優秀的工程師,你將為組織的發展做出貢獻。作為回報,將提供給你新的途徑,使你能夠獲得新的技能和自我成長