Forward


  • Vocabulary
    • leverage v. 起槓桿作用
    • idiosyncrasy n. 特質
    • unheard adj. 前所未聞的
    • ubiquitous adj. 無處不在的

Introduction


  • Vocabulary
    • roller coasster
    • toil away
    • ensuing adj. 隨之而來的;隨後的
    • abound v. 盛產;富有
    • yardstick n. 尺度;準繩
    • rigorous adj. 嚴格的

Part 1 - Adopt the Right Mindsets

Chapter 1 - Focus on High-Leverage Activities 專注在高效的活動


A rookie engineer pairs one or two mentors with following stuffs:

  • Code review
  • Pair programming (what’s this?)
  • Discussing engineering tradeoffs

Onboarding Program: 10 recurring tech talks and 10 Codelabs.

效益(leverage)評估:

$$ Leverage = \frac{Impact Produced}{Time Invested} $$

leverage 同樣也代表「投資報酬率(ROI,Return On Investment)」,高效的工程師倂非追求花更多時間完成更多的任務,而是在優先度最高事項(high priority task)以高效率的方式完成。

利用 80/20 法則,專注在 20% 最重要的事情上,以達成 80% 的成效。

比起該掉壞習慣更好更快的方式是,打從一開始就不要養成這樣的習慣。

增進效益(leverage)的三種方式:

  1. 縮短完成某件事項的時間
  2. 增進某些事項的產出
  3. 專注在高效益、高報酬的事項

因此, 我們可以在做某些事的時候,問自己以下三個問題:

  1. 我如何在更短的時間內完成這件事?
  2. 我如何在做這件事時,產出更多價值?
  3. 還有其他能夠產出更多價值的事情,是我值得花時間的嗎?

Key Takeaways(重點回顧)

  1. 評估每件事的投資報酬率
  2. 有系統性地增進使用時間的效益:在有限的時間裡,事項之間的取捨
  3. 專注在著力點(leverage point):時間有限(而且寶貴),著眼於高回報的事項
  • Vocabulary
    • influx n. 湧入
    • outline v. 概述
    • assess v. 評估
    • inescapable adj. 不可避免地
    • comprise v. 包括
    • boulder n. 巨石
    • dividend n. 股利
    • upfront adj. adv. 前期的;前期地
    • numerator n. 分子
    • denominator n. 分母
    • outset n. 開端
    • underscore adj. 強調
    • philanthropy n. 慈善事業
    • measles n. 麻疹
    • malaria n. 瘧疾

Chapter 2 - Optimize for Learning


優化的學習方式能提供更高的效益

如果我們要增進自我能力,「成長型思維」是不可或缺的因素

Invest in Iteration Speed(實踐成長性思維)

固定型思維的人認爲「一個人的成敗來自於先天上的條件(例如:天賦、才智),失敗就代表我們不夠聰明,或是能力不足」。但是對成長性思維的人而言,「透過一些努力,我們能夠改變自己的智力、能力」。就算一開始在某個領域只是一個初學者,但是透過不斷地挑戰、從失敗中學習,終究會帶來豐碩的成果。

想著如何訴説我們的故事,而不是讓別人來定義我們,也不是我們的學歷、工作經歷。

勇於嘗試新事物、無論是溝通技巧、新的網路技術,或是其他技能,不要在責備自己的失敗、無法控制的外部因素上蹉跎。在學習過程中,找到對自己更有效率地學習方式,並從中獲取寶貴的經驗。

Optimize for Learning(學習速度上的投資)

複利的特性:

  1. 指數型的成長
  2. 越早投入,成長的速度越快(這也是爲何投資專家都建議越早投入 401k 退休儲蓄計劃越好,因爲你有更多的時間滾利)
  3. 利息的差異對後續影響甚鉅,而且也是非綫性的

學習就像是複利:

  1. 學習過程也是指數型成長的,學得越多,我們的知識背景越雄厚,因此學習起來更加快速
  2. 越早學習,就能加速學習速度(根據第一點)。例如:第一份好的工作,能夠讓我們找到更好的工作,並影響往後的職涯發展
  3. 如同滾利,學習量對對長期發展來説很大

growth-curve

我們時常在做一些毫無挑戰、無趣、沒意義又花時間的事情上,這其實對學習的效率並不好,我們失去了增進學習效率及未來成長的機會。

Seek work environments conductive to learning(尋找可以能夠學習成長的工作環境)

  1. Fast growth(快速成長):   一個快速成長的公司,人事擴張、業務擴張
  2. Training(訓練): 良好、完整的新進人員訓練。另外,好的導師制度看得出團隊重視技能成長
  3. Openness(開放性): 開放的思維與討論,勇於發問的文化
  4. Pace(步調):快速的步調能夠增進學習的速度
  5. People(團隊組成): 如果周圍有聰明、極具創造力的人,那他們很有可能稱為我們的導師,它可以影響我們的進步速度以及工作幸福感。
  6. Autonomy(自律性):擁有自由調配時間的彈性,自己掌控工作以及學習的步調。

Dedicate Time on the Job to Develop New Skills(花時間在發展新技能)

專案不斷地增加的待辦事項,就算我們加快脚步想要更快速地完成那些任務,但是那個清單並不會因此而減少,我們花了很多時間在上面,但是卻沒有時間去發展、學習新的技能,那些才是能夠增進我們效率的技能。

以 Google 為首發展一個名爲 20% 時間的概念,當工程師將每週的一天時間在個人專案(side project)上,就可以為公司帶來進步。

Steven Sinofsky(微軟 Windows 部門的前主管)曾提倡臨近訓練(暫譯)(Adjacent Discipline)的想法,主要就是在描述我們學習的内容,如果是同一個領域的知識,那學習的效果將會相輔相成。

10 個學習上的建議:

  1. 向公司内優秀工程師學習他們在程式裏的抽象化概念
  2. 寫更多的程式碼,熟能生巧,透過做中學習
  3. 多參加讀書會、技術研討會,或是一些教學資源
  4. 精通我們主要使用的程式語言,深入探討深層的概念,熟悉核心語法。另外,確保其中一個我們會的語言是脚本語言,因爲它能夠讓我們快速開始,無需編譯
  5. 將我們的程式碼給最嚴格的人 review,降低標準對程式碼品質的進步無益,也要避免寫了很炫炮的程式碼,但無法派上用場
  6. 加入一些想要精進的課程:例如:公司的工作坊、附近大學、或線上課程
  7. 參與一些有興趣的專案的討論
  8. 參與不同類型的專案。如果我們發現自己不斷用同樣的方式做重複的事情,那就是時候嘗試一些新技術。
  9. 確保我們所屬的團隊裏有自身工程師可以作爲學習對象
  10. 用於嘗試理解陌生的程式碼

Always Be Learning(終生學習)

在工作之外的時間裏,提供 10 個切入點來養成學習的習慣:

  1. **學習新的程式語言或是框架:**軟體領域變化、演進快速,所以要養成持續學習的習慣,這也是它有趣的地方,因爲學習新技術可以激發新的思維,進而優化我們的做事方式
  2. **投資高需求技能:**觀察最近的趨勢,看哪些是目前非常短缺的技能
  3. **養成閲讀的習慣:**雖然聽起來很八股,但是閲讀一直是很多名人、偉人建議培養的好習慣,閲讀能夠增進我們的視野。
  4. **參與討論群組、讀書會:**跟相同興趣或是研究相同主題的人們相互討論,可以激發彼此
  5. **參加講座、研討會、線下聚會:**這些場所可以很容易得知目前該領域的趨勢,也可以藉機會認識相同興趣的人們
  6. **建立、鞏固人脈:**認識的人越多,我們的機會就越多
  7. **追蹤一些講師的部落格:**善用網路資源去學習他人的經驗
  8. **寫一些教學文章:**教學相長,當我們在寫教學文章的時候,我們需要把我們已經學會的觀念轉化成文字,而且避免寫出錯誤的資訊,也迫使我們必須確定自己的觀念是否正確。除了撰寫教學文章之外,在研討會上演講也是一樣的。(編按:能夠 live coding 才是真正厲害的强者)
  9. **做一些個人專案(side project):**做個人專案,就算跟程式無關也沒關係,有時候做迥異領域的事,例如:繪畫、寫作,反而可以幫助我們成爲更好的工程師
  10. **追求所愛:**比起一些被動娛樂(例如:看電視),將時間投資在有意義的興趣,不但能培養新技能,也可以增進心理健康。
  • Vocabulary
    • rationale n. 基本原理
    • orchestrate v. 精心策劃
    • plateau v. 停滯;遲滯
    • botch v. 誤事
    • ample adj. 充足的
    • aptitude n. 才華;才智
    • remedial adj. 補救的
    • assessment n. 評估
    • preconception n. 偏見
    • compound interest n. 複利
    • cushy n. 輕鬆的
    • overhead v. 消耗
    • rigorous adj. 嚴厲的
    • autonomy n. 自治;獨立性;自律性
    • inextricably adv. 逃不掉地
    • serendipitous adj. 意想不到的
    • hone v. 切磋
    • orthogonal adj. 直角的

Chapter 3 - Prioritize Regularly


優先度排程(Prioritization)是一門學問,就跟其他的技能一樣需要不斷地練習,高效工程師不斷地再持續精進這件事。

Try To-Dos in a Single, Easily Accessible List

建立一個好的待辦事項清單可以確保不會遺漏掉任何事情。首先依優先度排定一個必須做的事項清單。

搞定!:工作效率大師教你:事情再多照樣做好的搞定 5 步驟」一書的作者大衛.艾倫提到,人類的大腦擅長的是資訊處理,而非資訊儲存。所以比較好的方式就是將需要記憶的事情,用其他方式記錄下來,而不是依靠大腦的記憶。

待辦清單必須有以下兩個重要的元素:

  1. 有固定格式的陳述
  2. 放在一個容易取得的地方

我們可以很快地從清單中看出哪些是目前可以完成的,或是在某些空擋,一瞥清單就可以很快地找到能夠做些什麽,而不是費勁心思努力回想。

待辦清單可以有很多種的形式,例如一本可隨身攜帶的筆記本、任務管理軟體(桌面程式或是手機 APP)、同步到雲端的文字檔(可以同時在電腦及手機上檢視、編輯)。

Focus on What Directly Produces Value

專注在能夠生產價值的事情上,當我們拿出實際成果,就沒有人會抱怨拒絕的會議、很慢回信、或是不處理一些小 bug。在生活中也是如此,相較於不喝一杯 3 美元的星巴克拿鐵,花時間研究怎麽買廉價航空的機票才能真正為我們在下一趟旅程省錢。

不要試著做完所有的事情(因爲那是不可能的,我們的時間有限),專注在重要的事,專注在能夠產出價值的事。

Focus on the Important and Non-Urgent(任務類型的四個象限)

與成功有約:高效能人士的七個習慣」一書的作者: 史蒂芬‧柯維認爲,我們不該將「重要」跟「緊急」畫上等號。柯維將所有事項分成四大類,分別以「重要」、「不重要」、「緊急」、「不緊急」區分,如下圖:

task-type

以長遠的視野來看,第二區的事項才是最重要的投資,也是影響力最大的。但通常這區的事項沒有明顯的截止日期,花時間投入也不會有立竿見影的成效,而且在短期的時程看來,有可能看起來是在浪費時間(因爲看不出任何顯著的成效,但卻花了很多時間在上面),所以我們通常很容易忽略這一區。

在待辦事項中分辨哪些是屬於第二區(不緊急但是重要)的任務,這是最重要的,並且將歸類於第三區(緊急但不重要)及第四區(不緊急亦不重要)的優先度排到最後。此外,要特別注意第一區(緊急且重要)的事項,因爲它們看起來是必須優先處理的任務,但是建議不要花太多時間在上面。切記,第二區的才是最重要的。

Protect Your Maker’s Schedule(保護你的開發時程)

比起其他專業人員,工程師需要藉長期且連續的時間來提高生產力。

只要我們能夠維持在心理學家米哈里.契克森(Mihály Csíkszentmihályi)所提倡的「心流」(flow),就能夠提高生產力,有人描述這種狀態為「一個不需要刻意維持專注、忘卻時間流逝感、無我的狀態」。心流需要高度的專注力,打岔會中斷心流。

美國著名程式設計師兼風險投資家保羅.格雷厄姆(Paul Graham)在一篇名爲「創造者的日程、管理者的日程」(Maker’s Schedule, Manager’s Schedule)論文中提到,管理者(管理階層)的時程規劃通常以「小時」為單位,但是對創造者(執行團隊)(例如:軟體工程師、作家……等)而言,比較適合以至少「半天」爲單位去執行他們的任務。

所以,盡可能規劃為自己保留完整且連續的開發時間,排不必要的會議及關閉不必要的聊天訊息通知。

延伸閲讀:

Limit the Amount of Work in Progress(避免同時進行太多的事項)

避免過多的多工,因爲我們的大腦無法同時處理太多的事情,同時進行太多的事情,反而會降低專注力、甚至影響生產力。

「Personal Kanban」一書中提到,我們必須要限制進行中任務的數量,就像是雜耍員可以很簡單地操控 3 顆球,但是若是 6 顆、7 顆,他勢必無法專注在所有球上。作者 Barry 及 Benson 提到:「我們越接近大腦所能處理資訊的承載極限,就越容易累積心理壓力,也會影響效率。」,「給大腦的工作量綫性增加,但出錯的機率卻是指數增加。」

人類的大腦雖然可以同時處理很多事情,但是如果我們講求做事的品質、效率及生產力,那就要盡量避免多工處理。想像它是一個擅長單執行緒的處理器,將不必要的事情先排除吧!

延伸閲讀:

Fight Procrastination with If-Then Plans(用 If-Then 計劃去解決拖延症)

實現:達成目標的心智科學」一書的作者海蒂.格蘭特.海佛森提出一個幫助我們改善拖延症問題的方法,稱爲「- 計劃」(if-then plan)。我們在進行一項任務之前,進行這個計劃,例如:「三點會議結束了,我來查這個預計會很花時間的 bug」、「在晚餐後,我來看一則關於安卓開發的演講」。

以程式的術語來説,就是以一個「條件」來作爲「觸發」一個事件(我們規劃要執行的任務),只要有了明確的觸發條件,也就能減少拖延的發生。← 尋找「最有生產力的一年」句子,提示訊訊號

- 計劃」讓我們在創造者日程中,很快地決定在片段的時間區塊我們能夠做些什麽事,試問自己:「我在開會前有 20 分鐘的空擋,我要做 OOO」。試著列出一個待辦事項清單,裏面的事項是不需要花太多時間來做的,利用空擋時間完成這些事吧!

Make a Routine of Prioritization

優化工作流程,就如前面所描述的,很多人提出不同的見解及方式,世上沒有所謂的最佳解。適合的方法也因人而異,唯有找到最適合自己的方式、參考各種做法甚至混合(hybrid)、打造自己的系統(build up your system),才能真正提升生產力。

作者目前使用一個管理平臺「Asana」來管理自己的待辦事項、追蹤任務進度、學習新技能等。

Key Takeaways(重點回顧)

  • 列出一個待辦事項清單:切記大腦是做決策的中樞,不是儲存資料的硬碟

  • 做能夠有直接產出的任務:不要想著完成所有事

  • **花時間投資在「重要但非緊急」的事情上:**一切都是爲了長遠的計劃

  • **減少任務切換的次數:**這都是爲了減少切換工作模式時耗費的精神力、也減少專注力的損耗

  • 用「- 計劃」對抗拖延症

  • 養成定期檢查優先序的習慣

  • Vocabulary

    • proliferate v. 增值;擴散
    • cadence n. 節奏;韻律
    • garner v. 儲存;儲藏
    • heuristic adj. 啓發式的
    • smugly adv. 自滿地;自以爲是地
    • assortment n. 分類
    • canonical adj. 規範的
    • huddle v. 雜亂一團;混亂
    • roadblock n. 障礙物
    • budgetary adj. 預算的
    • corollary n. 推論;必然的結果
    • detract v. 減損;貶低;轉移
    • inundate v. 浸水;泛濫
    • whittle v. 消弱;消減
    • contiguous adj. 連續的;臨近的
    • empirical adj. 經驗主義的
    • consolidate v. 鞏固;使聯合;統一
    • substantive adj. 實質的

Part 2 - Execute, Execute, Execute

Chapter 4 - Invest in Iteration Speed


使用 CI/CD 增加開發迭代速度,加速工作流程

Move Fast to Learn Fast

Invest in Time-Saving Tools(投資在節省時間的工具上)

工具可以幫助我們增進效率,就像在寫 code 的時候,秉持著 DRY(Don’t Repeat Yourself)原則一樣,重複性的事情,就應該交由工具來處理。

動手打造能夠節省時間的工具。短期看來,可能因爲花了額外的時間來開發這些工具而減少了原本開發的時間;而長期的成效很難在短期内看出優勢。因此,我們要從小的地方開始著手,等到有一點成效之後,在將範圍擴大。

Shorten Your Debugging and Validation Loops

Master Your Programming Environment

善用快捷鍵來節省時間

也許一開始因爲要適應新的習慣或是方法,必須更耗時間,看起來不但沒有省,反而更費時間。但是這只有一開始。例如一開始學習盲打,一定很慢,看來沒有效率,但是一旦熟悉之後,絕對能夠增進工作效率。沒有人一夕之間就可以精通一項技能,都是要靠時間的累積、不斷地練習才有辦法上手。

這裏提供打好程式基礎的一些方式:

  • 找一個適合自己的 IDE
  • 學習一個高階脚本語言。脚本語言的優勢就是可以節省編譯的時間,此外,高階語言的語法更加精簡好閲讀。
  • 熟悉 UNIX 或 Windows 的 shell 指令
  • 多用鍵盤,少用滑鼠
  • 將自定流程自動化
  • 將想法與思考流程用脚本語言實現

Don’t Ignore Your Non-Engineering Bottlenecks

除了增進開發的迭代速度之外,非技術面遇到的問題也同樣會影響我們的開發進度,例如產品經理遲遲沒有確定客戶需求、設計師沒有尚未提供一個重要的 UX flow、或其他團隊沒有準時交付我們需要的功能,因此無法繼續開發下去……等等。

  • Vocabulary
    • intervention n. 介入;調停
    • laborious adj. 艱苦的;費勁的
    • regression n. 退步;逆行
    • leeway n. 餘地;靈活性;機動性
    • indoctrinate v. 教導;灌輸
    • uproar n. 喧囂;騷動
    • confine v. 限制
    • compelling adj. 强制的
    • advent n. 來臨;降臨;問世
    • inroad n. 侵入;侵略
    • churn v. 攪拌;鑄造
    • complacent adj. 滿足的;自滿的;得意的
    • dent n. 塌陷;凹痕

Chapter 5 - Measure What You Want to Improve


Use metrics to Drive Progress(用指標去驅動進度)

彼得.杜拉克在「杜拉克談高效能的 5 個習慣」一書中説到:「如果沒辦法衡量,就無法談進步」。

好的「指標」(Metrics)可以幫助我們完成一些目標:

  • 第一,幫助我們專注在正確的事上。當設定一個跟目標有關的指標後,就能確保進步的方向沒有偏離目標。
  • 第二,好的指標防止我們未來後悔曾經做過的事
  • 第三,。。。
  • 第四, 好的指標可以分析目前的進度。假設我們每週的進度指標是 1%,那麽我們就可以用這個數據去分析並建立未來近期的目標。

將目標與指標量化本來就不是一件容易的事,但是難量化不代表就不值得去做。

問自己兩件事:

  • 有什麽方法能夠將目前的進度量化?
  • 倘若正在進行的任務不屬於核心指標(core metric),仍值得去做嗎?還是有忽略的關鍵指標(key metric)?

Pick the Right Metric to Incentivize the Behavior You Want

舉幾個例子説明追蹤不同的指標對一個團隊會有什麽影響:

  • 每週的工作時數 vs. 每週的生產力: 我們都知道拉長工作時數來增加產出不能解決根本的問題,在沒有效率不變的情況下,產出隨時間綫性成長是理所當然的,但是人非機器,連續長時間的工作會帶來職業倦怠,效率低落是必然的,所以反而沒有得到比較好的成效。所以,若要增進產出,我們要分析每週的生產力,例如產品品質、網站速度、客戶成長率之類的
  • 點擊率 vs. 長點擊率(Click-through rates vs. long click-through rates): 以 Google 的搜尋來説,點擊率並無法完全代表使用者偏好,使用者在某些網站停留的時間越久,才是使用者偏好的指標
  • 平均回應速度 vs. 95, 99 百分位數的回應速度(Average response times vs. 95th or 99th percentile response times): Google、Yahoo、Amazon 及 Facebook 很多研究都顯示使用者很在乎網站的回應速度,但我們要怎麽定義這個速度是否快速?平均回應速度跟 95、99 百分位數的回應速度上意義很不一樣。若是平均值,我們著重的點就是在提升整體的速度,像是升級基礎設施(infrastructure)來減少資料計算所需要的時間。但是若我們要降低 95、99 百分位數的回應時間,我們就要揪出系統最壞(或最差)的狀況,像是回應速度滿可能是因爲使用者請求大量的資料,通常他們會是大戶(power user)。
  • Bug fixed vs. bugs outstanding
  • 總註冊數 vs. 每週註冊成長率(Registered users vs. weekly rate of registered users): 穩定的使用者成長率比較重要,細水長流,以長遠的計劃看來,我們要追求的是長期的穩定,而非一夕之間的爆紅。
  • 每週活躍的用戶 vs. 每週各年齡層活躍的用戶(Weekly active users vs. weekly active rate by age of cohort): 分析活躍的用戶數還不夠,如果跟進一步去看年齡層的分佈,有助於未來產品的走向上的決策。

Instrument Everything to Understand What’s Going On

將分析的數據視覺化,有助於我們分析趨勢,找到問題點(例如:伺服器回應慢速),並找到解決問題的方向

分析問題的時候,診斷的工具很重要

成功的科技公司會建造一個類似飛機駕駛員的操控儀表板,上面監控著各式各樣的數據。在越短的時間内發現某些問題的根本原因,我們就能越快做出相對應的對策。

Internalize Useful Numbers

Be Skeptical about Data Integrity

資料可以被濫用,端看使用資料的人如何去詮釋他手上的資料。

  • 記錄所有的 data,當我們需要的時候,自然會派上用場

  • 打造工具,增加收集資料的準確性

  • 寫 E2E 整合測試去驗證整個分析 pipeline

  • Vocabulary

    • laudable adj. 值得讚賞的
    • trove n. 收藏品;貴重發掘物
    • corpora n. corpus 的複數型
    • corpus n. 語言資料庫
    • conceive v. 構思
    • incentivize v. 激勵
    • precipitous adj. 陡峭的;急躁的
    • cohort n. 軍隊;一群
    • rep n. 名聲
    • acquire v. 收購
    • disparate adj. 不同的;迥異的
    • reiterate v. 反復地說;反復地做
    • abysmal adj. 深不可測的
    • snafu n. 天翻地覆;大混亂
    • egregious adj. 惡名昭彰的;過分的;驚人的
    • awry adj. 歪曲的;歪斜的
    • halve v. 減半
    • anomaly n. 不規則;異常的事物
    • causality n. 因果關係
    • myriad adj. 無數的
    • ream n. 大量的紙

Chapter 6 - Validate Your Ideas Early and Often


不斷地針對客戶反饋持續做調整,才能找到產品最重要的地方,而不會迷失方向

不只是「Get things done」,更要是「Get right things done」

Find Low-Effort Ways to validate your Work

利用「最小可行性產品」(MVP, Minimum Viable Product)盡量收集客戶的需求。

有時候,打造 MVP 需要一點創造力。Drew Houston 在打造 Dropbox 初期的當下,市面上已經有很多無數的檔案共享平臺。但 Houston 相信無縫的使用者體驗才是使用者最需要的,因此,他製作了一個四分鐘的介紹影片介紹他的 MVP,介紹他的跨平臺檔案共享 MVP(限制版本),一夜之間,Dropbox 的 beta 版使用申請信從 5000 成長到 75000。利用 MVP 去驗證產品是否是使用者想要的,增加對產品開發的信心。

我們雖然不會總是在研發新產品,但是這並不影響 MVP 這個概念想要傳達的動機,我們要用省事的方式去驗證整個專案的走向是否符合客戶的期待。

Continuously Validate Product Changes with A/B Testing

在 A/B 測試當中,只有一小部分的使用者可以看到新功能,而大部分的使用者沒有。通常 A/B 測試框架會在瀏覽器 cookie 中儲存使用者 ID 或一些亂數,用來決定使用者能夠看到的功能。

A/B 測試可以讓我們決定新增哪一個新功能、也可以量化其帶來的改變。

Etsy 的開發團隊會提出一個假設,然後用 A/B 測試驗證這個假設的成果,然後從獲得的數據中學習並改進。

A/B 測試就是以小規模(限制新增的功能、限制可以看的使用者)的方式做實驗,並在回收數據、分析數據之後,導出產品的未來走向。

A/B 測試的宗旨在於,不是要做出一個完整的方案之後,再部署到平臺讓使用者去使用。因爲除了要先耗費大量人力與時間之外,得到使用者回饋的時間也會拖慢。利用 A/B 進行小規模的試驗部分的小功能,不僅投入時間人力相對較少,也可以很快地得到使用者的反應。就如第四章所闡述的重點,增進迭代的速度,才能及時做出改善,減少時間人力上的損失。

Beware the One-Person Team

就算是一人專案,也不是只能埋頭苦幹,就像是沃兹尼克當年在家裏一首打造蘋果電腦一樣,他也是有從賈伯斯那邊獲得一些想法與啓發。我們要建立一些回饋的管道幫助專案順利進行,有以下策略可以參考:

  • **對他人的回饋保持開放心態:**如果心態上太保守,就很難聽取別人的回饋,這樣別人以後也不想再發表自己的看法。良藥是苦口的,有些意見反而是一個進步的好機會。
  • **頻繁的 commit code:**一次 commit 大量的 code 會難以追蹤,如果是要給別人做 code review 的話,對方也很難抓到這個 commit 的重點,進而可能失焦,忽略了一些很重要的細節。code 的改動區域越大,code review 就越花時間。相對地,少量 code review 不但省時間、code review 品質較好之外,得到對方回饋的時間也較快,可以增進開發迭代速度。
  • **給嚴格的人做 code review:**爲確保品質,給嚴格的人 code review 比較好,也許會收到很多批評,但是總比上綫後收到客戶的批評來得好。
  • **詢問團隊成員的想法:**最直接得到回饋的方式就是去詢問意見。找團隊成員花瑣碎的時間聊聊你的想法。研究顯示,最好的學習方式就是將你所習得的概念解釋給一個人聼。(編按:當你可以解釋給別人聼,代表你已經内化了)而且在解釋的時候,一些盲點或是不足的部分就是顯示我們學習上的漏洞、需要加强的部分。大部分的人應該都很樂意幫忙,在閑暇之餘解決一些有趣的問題。因此,爲了讓別人以後也願意分享己見,我們要尊重對方的時間(因爲他們的時間也很寶貴),準備好我們要提出的問題,並且有條理地説明曾經嘗試的方法。在討論之後,回饋他們這個想法的實行結果。
  • 先為新系統設計界面或是 API
  • **祭出設計文件先於花時間開始寫 code:**這就像是花 10% 的時間先去驗證其他 90% 要做的工作是否值得去做。文件不一定要是非常正式的,可以是一封詳細描述的 Email,但是内容要足夠讓對方充分理解我們要做的事,而且能夠引導對方問出準確的問題。
  • If possible, structure ongoing projects so that there is some shared context with your teammates: 盡量避免跟團隊成員同時間分別做不同的專案。同時做同一個專案的好處是,可以減少討論、code review 時的溝通成本。比起同時並行多個專案,一次只執行一個專案更可以縮短專案開發的時程。
  • Solicit buy-in for controversial features before investing too mush time: 與客戶的訪談及建立 prototype 來説服股東,這些事很容易被工程師誤解這類行銷活動成辦公室政治,但其實不然。如果能從一段簡短的訪談中就能得知客戶的回饋,也比花大把時間開發出來後才得到客戶反饋來得省事許多,就如同前面所説,越早得到回饋就越好。

Build Feedback Loops for your Decisions

臉書的技術總監 Nimrod Hoofien 曾説:「所有決策都必須要有 feedback loop,否則,你只是在猜測。」

Key Takeaways(重點回顧)

  • Approach a problem iteratively to reduce wasted effort

  • Reduce the risk of large implementations by using small validations

  • Use A/B testing to continuously validate your product hypotheses

  • When working on a solo project, find ways of soliciting regular feedback

  • Adopt a willingness to validate your decisions

  • Vocabulary

    • onslaught n. 猛攻;突擊
    • lackluster adj. 無光澤的;無神的
    • rudimentary adj. 根本的;未發達的
    • naught n. 無;零 adj. 無價值的;無用的
    • pedigree n. 血統;家譜
    • tread n. 鞋底
    • veer v. 轉向
    • impede v. 阻礙;妨礙;阻止
    • outspent adj. 用完了
    • sole adj. 唯一的;僅有的;單獨的
    • retention n. 保留;保持
    • daunting adj. 使人畏縮的
    • ostensibly adv. 假裝地;表面地
    • prohibitive adj. 禁止的;抑制的
    • ginormous adj. 巨大的
    • smug adj. 自以爲是的
    • monotonous adj. 單調的
    • surmountable adj. 可戰勝的;可剋服的;可凌駕的
    • receptive adj. 能接納的
    • grapple v. 抓住;掌握
    • misconstrue v. 誤解;曲解
    • nebulous adj. 星雲狀的;朦朧的
    • silo n. 地窖

Chapter 7 - Improve Your Project Estimation Skills


Use Accurate Estimates to Drive Project Planning

爲了讓我們更精確地評估專案的時程並保有彈性,有以下方法:

  • **將專案拆解成小的 task:**拆解成小的 task 有助於時間的評估,如果一個 task 評估需要花超過兩天,則再拆成更多的 task
  • 評估 task 需要多少時間可以完成,而不是某些人「希望」你多少時間完成
  • **將評估當成是可行性分佈,而不是理想情境:**Tom DeMarco 在他的著作中曾説道:「我們很常做過度樂觀的預估,那些通常太過理想化,以至於完全不可能實現。」我們可以説:「我們大概有 50% 的機率在 4 週内交付這個 feature,90% 的機率可以在 8 週内完成」,而不是「我們可以在 6 週内完成」。
  • 讓負責做的人來評估時間:同樣的 task 每個人完成的時間不一樣
  • **留意「錨定效應」(Anchoring bias):**我們容易受先前的資訊影響我們的決策。通常會受 PM 的時程評估影響我們自己時程評估的精確度。

    人類在進行決策時,會過度偏重先前取得的資訊(這稱為錨點),即使這個資訊與這項決定無關。- Wikipedia

錨定效應 - 维基百科,自由的百科全书

  • Use multiple approaches to estimate the same task
  • **留意「人月神話」:**一個女人可以在九個月生一個小孩,不代表九個女人可以在一個月生出一個小孩。團隊成員的增加會帶來更多的溝通成本,也不一定會因此增加生產力、縮短開發時程。
  • 利用過往的經驗來評估時程
  • Use timeboxing to constrain tasks that can grow in scope
  • Allow others to challenge estimates

Budget for the Unknown

時程的延宕不是一瞬間的,而是漸進式、不斷累積而來的。

Define Specific Project Goals and Measurable Milestones

在整個專案時程之中建立多個里程碑(milestone),里程碑可以幫助我們不斷檢查專案進度是否有如期進行、是否有可能影響預定交付日期、並且可以隨時做調整與應變措施,看是要延期或是刪減任務……等。

Reduce Risk Early

我們通常會選擇簡單的,或是明顯的任務去做,這看起來好像進展快速,但是實則不然。先處理最棘手、最有可能出問題的部分,才有助於我們提早找到問題,越早解決重大的問題,也相對減少專案無法如期交付的機會。

Approach Rewrite Projects with Extreme Caution

但發現程式碼已經變成亂七八糟充滿技術債的狀態,我們就會有想要「砍掉重練」的衝動:「或許能夠重新設計整個架構,讓程式碼看起來更簡潔?」但重構是一個高風險的事。

將專案的重構拆解成多個階段,然後依照時程的步調局部地進行。

Don’t Sprint in the Middle of a Marathon

What I met at my former company…

Teams consisted of talented and dedicated people trying to hit an aggressive deadline, convinced that a project slip would break the business.

每當我們發現專案進度落後原先的計劃,第一個想到的就是:接下來的兩個月,我們要延長工時,改成每週工作 50 小時,這樣就可以如期交付。但是增加工作時間不代表一定能夠如期交付:

  • **生產力會隨著工作時數的增加而下降:**很多的研究指出,過長的工時會造成生產力下降、出錯機率增加,短期内或許會因爲工作時數拉長而增加產出,但長期來看卻不是。1980 年的研究指出,能夠達到最大產出且保持員工的生產力,以每天 8 小時的工作時數為上限。這也是爲何現在大部分公司都是以一天 8 小時、一週 40 小時的工作時數。(編按:這就跟熬夜需要花更多時間補眠一樣)
  • **落後時程或許比你所想像的更多:**若感到時程上個月的進度落後,代表我們低估了這個專案所需要花的時間,也就是説,未來幾個月的預估也是低估的。
  • **額外的工作時間會造成倦怠:**加班等於犧牲了人們的私人時間,舉凡跟朋友相處、運動、休息、睡眠的時間。這些都是從繁重的工作中回復精神的活動。
  • **超時工作影響士氣:**每個人都有無法配合加班的理由,願意配合加班的人必須承擔其他無法加班的同事的工作量,進而影響整個團隊士氣
  • Communication overhead increases as the deadline looms
  • 在交付日期前夕趕進度容易造成技術債

加班不是萬靈丹,但也有時候會遇到不得不加班的情況。

  • Vocabulary
    • inkling n. 暗示
    • loathe v. 厭惡;憎惡
    • overbudget n. 爆預算
    • demise v. 死亡;讓渡
    • salvage v. 搶救;打撈;營救
    • calamity n. 災難;不幸事件
    • termite n. 白蟻
    • conflate v. 合併
    • shard n. 陶瓷的碎片;碎片;外殼
    • endorphin n. 腦内啡
    • amortize v. 分期償還
    • litter v. 弄亂
    • jeopardy n. 危險;危害
    • cardinal adj. 主要的
    • pave away v. 為……鋪路
    • incentivize v. 激勵
    • panacea n. 萬能藥
    • crutch n. 支撐
    • contingency n. 偶然;可能性

Part 3 - Build Long-Term Value

Chapter 8 - Balance Quality with Pragmatism


Balance Quality with Pragmatism

臉書的前技術總監 Bobby Johnson 提出:「用對或錯來評估(維護程式碼品質)並不是一個很好的方式,我比較偏好『是否有用』,這幫助我更有效率地做決策」。利用實用主義來判斷我們維護程式碼品質要到什麽程度。

Establish Sustainable Code Review Process

在 Google,沒有經過 code review 是無法將 code 推到 remote 端的,必須至少經過一個以上的人做 code review。

code review 的好處包含以下幾點:

  • **可以儘早發現 bug:**2008 年的研究顯示,來自 650 家公司的 12500 個專案中,執行 code review 可以降低平均 85% 左右的 bug
  • **對 code change 有責任感:**在修改 code 的時候,會更加小心,我們不會隨隨便便修改,然後等別人發現之後再試圖修復它
  • **好的程式碼架構模型:**code review 也是相互學習的一種方式,也可以增進彼此的心智模型,寫出更好維護的程式碼
  • **同步程式邏輯:**code review 的人也可以藉機瞭解這部分的功能功能以及運作邏輯,當你放假或不在公司的時候,更可以很有效率地處理這部分的 bug
  • 增進長遠的機動性:高品質的程式碼易讀性佳、容易修改,也不容易產生 bug。

我們都知道 code review 能夠帶來的好處,但是很多人卻不太這麽做,通常我們會認爲 code review 太花時間,會拖慢迭代速度,所以寧可將這些事件拿去做開發。

我們不該是在要不要 code review 之間做決定,其實不是二元論的問題,而是我們要針對哪些部分在做 review。例如針對核心邏輯做 review。在 Quora,他們只針對商業邏輯的部分(model 及 controller)做 code review。

Manage Complexity through Abstraction

正確的抽象化可以增進生產力:

  • 將原本複雜的問題簡化成一個一個容易理解的單元
  • 減少未來增加功能的困難度、增進擴充的自由度
  • 解決一個困難題,然後解法可以複用(秉持 DRY 原則)

Lunascript ? 沒聽過,查不到

好的抽象化包含以下特徵:

  • 易於學習
  • 沒有文件也容易上手
  • 很難誤用
  • 可以輕易達成需求
  • 方便擴充
  • appropriate to the audience

Clojure 程式語言的作者 Rich Hickey 曾説:「Simple things take on one role, fulfill one task, accomplish one objective, or deal with one concept.」

抽象化的幾個建議:

  • Avoiding mutable state
  • Using functional rather than imperative programming(宣告式優於指令式)
  • Preferring composition over inheritance(組合優於繼承)
  • Expressing data manipulations declaratively rather than imperatively

學習抽象化的幾個方向:

  • 從 GitHub 上別人的專案中學習
  • 研究科技巨擘,例如:Google、Facebook、LinkedIn、Twitter 等公司的開源專案,看他們是怎麽做抽象化的
  • 研究 Parse、Stripe、Dropbox、Facebook、AWS 等公司開發的熱門 API 的界面是如何設計的

Automate Testing 自動化測試

  • 測試可以讓我們更有自信地重構、修改程式碼
  • 寫測試跟寫文件一樣,越早做越好,因爲當下原作者最清楚程式片段在做些什麽,如果是過了一個月或者一年之後,就不是那回事了
  • 自動化測試很好,但不代表所有地方都要做自動化測試。很難達成 100% 的測試覆蓋率,有些地方也不適合做自動化測試。
  • 覆蓋率不是越高越好。
  • 第一次寫測試總是困難的。從可以發揮測試最大功效的地方開始著手,一旦我們有了不錯的開始、測試的流程、測試庫之後,寫測試的阻力就會開始減低。

Repay Technical Debt(償還技術債)

  • 技術債通常是因爲想要求快速開發、忽略寫測試、懶得重構之類的原因而產生。
  • 有時候因爲時程關係,可以容許用一些 workaround 的方式去做,但是要做定期地重構及整理,把那些技術債給排除
  • 技術債放著不管,就會越積越多,未來會衍生很多難解的問題
  • Google 會舉辦 Fixit 活動,例如:Docs Fixit、Customer Happiness Fixit、Internationalization Fixit 等,針對不同主題去整理程式碼,去消除累積的技術債。
  • LinkedIn 會暫停整整兩個月的開發時間,並用這段時間修復一些問題
  • 我們的時間有限,所以不要想著去除掉所有的技術債,而是選擇重要的,能夠減少最多問題的地方進行修復或重構

Key Takeaways(重點回顧)

  • 建立 code review 的文化 code review 是教學相長的一種方式,在開發與 code review 之間取得一個平衡的時間分配

  • 投資在好的抽象化工具,簡化複雜的問題 好的抽象化可以將複雜的問題簡化,切分成小的區塊、將問題分成很多部分,各個擊破

  • 寫自動化測試 自動化測試節省我們的時間,也幫助我們建立修改程式碼的信心

  • 做好技術債的控管 精挑出最重要的地方做重構或修改,將原本部分的開發時間用來移除技術債,就要將發揮這些時間的最大效益

  • Vocabulary

    • pragmatism n. 實用主義
    • nimbly adv. 敏捷地;機敏地
    • stringent adj. 迫切的;嚴厲的
    • stifle v. 窒息;抑制
    • hamper v. 阻礙
    • dogmatic adj. 教條的;獨斷的
    • unduly adv. 不適當地;過度地
    • ingrain v. 使根深柢固
    • susceptible adj. 易受影響的
    • consolidate v. 鞏固;統一
    • detract v. 減損;貶低
    • haphazard adj. 偶然的;偶發的
    • disentwine v. 鬆開;解開
    • incidental adj. 附帶的;偶然的
    • discrepancy n. 差異;差別
    • permutation n. 交換;排列
    • repay v. 償還
    • incur v. 招致;蒙受;遭遇

Chapter 9 - Minimize Operational Burden


Minimize Operational Burden

Instagram 爲了減少的維護成本,避免追求最新的技術(例如:NoSQL),選擇穩定且發展成熟的技術(例如:PostgreSQL)、Memcache、Redis 等。他們避免自造輪子,也就省去了還要去維護它們的時間成本。

Embrace Operation Simplicity

  • 簡單的解決方案代表著易於執行
  • 賈伯斯在設計 iPod 時候曾說:「當我們面對一個問題的時候,一開始的解決方案通常會非常複雜,但是當我們更深入瞭解面臨的問題、抽絲剝繭地分析之後,會得出一個簡單且優雅的答案。但多數人沒有花時間及精力去挖掘它。」
  • 精簡打從一開始就是 Instagram 的特色,Instagram 的前身 Burbn 擁有很多且複雜的功能,但是創辦人 Krieger 及 Kevin Systrom 決定移除大部分的功能,只留下最重要的、Instagram 的核心、也是用戶最愛用的功能:分享照片,而這就是 Instagram 現在的樣子

太複雜的架構會大大增加維護的成本:

  • Engineering expertise gets splintered across multiple systems
  • Increased complexity introduces more potential single points of failure 複雜的系統代表熟悉的人更少,如果只有一個人瞭解,當那個人去放假或生病的時候該怎麽辦?
  • New engineers face a steeper learning curve when learning and understanding the new systems 複雜的系統,對新進工程師而言,學習曲線也會變陡,也就意味著需要更是多時間才能上手
  • Effort towards improving abstractions, libraries, and tools gets diluted across the different systems
  • 尋找最簡單的解決方案

Build Systems to Fail Fast

讓系統很容易地故障(fail fast)聽起來是一個很違反直覺的一個作法,「產生急性的、明顯的故障(failing immediately and visibly)」聽起來像是讓系統更脆弱,但實際上是使之更穩定。因為找尋問題會更快速、除錯會更容易,也就會有更少的問題進入 production。

Examples of failing fast include:

  • Crashing at startup time when encountering configuration errors 如果有環境設置上的錯誤,直接在啟動 server 的時候就 crash
  • Validating software inputs, particularly if they won’t be consumed until much later
  • Bubbling up an error from an external service that you don’t know how to handle, rather than swallowing it 若是來自外部服務的錯誤無法自己處理,不要做 catch,而是直接揭露出來
  • Throwing an exception as soon as possible when certain modifications to a data structure, like a collection, would render dependent data structures, like an iterator, unusable 若遇到資料結構上的變動,則拋出例外錯誤
  • Throwing an exception if key data structures have been corrupted rather than propagating that corruption further within the system 若核心資料結構損壞了,就直接拋出例外錯誤
  • Asserting that key invariants hold before or after complex logic flows and attaching sufficiently descriptive failure messages
  • Alerting engineers about any invalid or inconsistent program state as early as possible

Relentlessly Automate Mechanical Tasks

將一些重複性作業做自動化,以節省時間

一些能夠用來自動化的事項:

  • Validating that a piece of code, an interaction, or a system behaves as expected
  • Extracting, transforming, and summarizing data 資料收集、資料轉換、資料統計
  • Detecting spikes in the error rate 偵測錯誤發生頻率
  • Building and deploying software to new machines 部署軟體到新機器
  • Capturing and restoring database snapshots
  • Periodically running batch computations
  • Restarting a web service 重啟服務
  • Checking code to ensure it conforms to style guidelines 檢查 coding style
  • Training a machine learning model 機器學習的訓練模型
  • Managing user accounts or user data 使用者帳戶及資料管理
  • Adding or removing a server to or from a group of services 伺服器及服務的管理

Facebook 的前技術總監 Bobby Johnson 提到:「自動化分為兩種類型:機械自動化(automating mechanics)及決策自動化(automating decision-making)。」第一個比較直觀,也就是前面所提到將重複性作業做自動化。第二個則比較有挑戰性,像是在系統建置的時若出了問題,決定是否要自行修復的自動化。

Make Batch Processes Idempotent

Hone Your Ability to Respond and Recover Quickly

  • Netflix 公司提倡:「防範重大系統故障的最佳解就是讓它經常故障」
  • 他們減少營運負擔的方式就是:快速地修復
  • 因為產生 bug 在所難免,因此最重要的是我們如何處理這些錯誤
  • 在某些時候,「快速地修復」比「一開始竭力預防故障」還來得有效率
  • 盡可能將所有可能發生的情景先羅列出來,並思考每個情境的應對措施,這樣在真正緊急的情況發生的時候,我們也能夠從容地應對高壓的環境、順利地解決問題
  • 不只有 Netflix,其他公司也有一些故障應變演習的策略:
    • Google 每年舉辦為期多天的災難修復測試(Disaster Recovery Testing,簡稱 DiRT)。他們模擬天災來襲,例如:地震、龍捲風來襲,切斷所有資料中心及辦公室的電源,然後確保團隊、溝通、重要系統都能夠正常運作
    • 在 Dropbox,工程團隊刻意在 production 環境加上額外的負載,藉此模擬極端狀況,然後在觸發警報之後恢復原狀,並著手進行錯誤分析。因為這只是模擬測試,所以沒有真正要搶修時的龐大壓力
  • Netflix、Google、Dropbox 都會將非常極端的狀況考慮進去並實行模擬演習,以確保團隊的災難應變能力能夠在不可預期的狀況發生時,快速修復系統。這告訴我們防範未然的重要性
  • 時常問自己「萬一」的問題:
    • What if a critical bug gets deployed as part of a release? How quickly can we roll it back or respond with a fix, and can we shorten that window? 若重大 bug 部署上去,我們預計回溯要花時間多久?修復要花多久?
    • What if a database server fails? How do we fail over to another machine and recover any lost data? 若資料庫伺服掛了,如何轉移到另一台伺服器,並回復遺失的資料?
    • What if our servers get overloaded? How can we scale up to handle the increased traffic or shed load so that we respond correctly to at least some of the requests? 若伺服器滿載,如何解決滿載問題?
    • What if our testing or staging environments get corrupted? How would we bring up a new one? 若測試或部署環境掛了,是否有替代方案?
    • What if a customer reports an urgent issue? How long would it take customer support to notify engineering? How long for engineering to follow up with a fix? 若客戶回報重大錯誤,需要多久回報給工程團隊?又需要等多久才可以開始進行修復?
    • What if users revolt over a new and controversial feature? What is our stance and how quickly can we respond? 若使用者對新功能且有爭議的功能有抱怨,我們應該用什麼樣的姿態、花多久時間去回覆?
    • What if a project slips past a promised deadline? How might we predict the slippage early, recover, and respond? 若專案時程延期,超過預期交付時間,我們如何更早預測到延期、並提出應對措施?

Key Takeaways(重點回顧)

  • 先做簡單的任務

  • 快速失敗、快速除錯

  • Automate mechanics over decision-making

  • Aim for idempotence and reentrancy

  • 規劃及多練習防災演練

  • Vocabulary

    • budding adj. 萌芽的;發育期的
    • enamor v. 使迷戀;使傾心
    • proponent n. 提倡者
    • beefy adj. 健壯的
    • decipherable adj. 可破解的
    • muddy v. 使混濁 adj. 混濁的
    • trifling adj. 不重要的;微不足道的
    • relentlessly adv. 無情地;殘酷地
    • conform v. 遵照
    • amok adv. 殺人狂地;狂亂地
    • resilient adj. 有彈力的;迅速恢復精力的
    • spurious adj. 假的;偽造的
    • heckler n. 擾亂份子
    • revolt v. 反叛;起義

Chapter 10 - Invest in Your Team’s Growth


  • 不僅只是在個人方面講求效率,在團隊方面也同等重要
  • Your career success depends largely on your company and team’s success, and the success of your company or team depends on more than just your individual contributions.

Make Hiring Everyone’s Responsibility

  • 面試通常曠日費時,但是如果找到一位工程師,就可以為公司每單位時間增加更多的產能
  • Dropbox 將面試變成一種公司文化,所有人都有當面試官的義務
  • 一個有效率的面試流程能夠達成兩個目標:
    • 能夠篩選出能夠為團隊帶來進步的成員
    • 讓求職者為加入該團隊感到興奮
  • 身為面試官,我們要斟酌如何提出準確、高 signal-to-noise 比的問題——能夠在單位時間內得到最多面試者資訊的問題(也就是指 signal),同時也要減少多餘的資訊(也就是指 noise)
  • 精確的提問能夠讓我們更快選出最佳人選
  • 傳統上,像是 Google、Microsoft、Facebook 及 Amazon 這類大型科技公司都會在面試的時候考白板題(演算法之類的),這類教科書式的題目可以顯示出面試者的基礎知識的能力,但是卻無法了解他們真正在工作時的狀況
  • 有些公司將捨去原本的白板題,改採用上機考。上機考可以用來觀察面試者如何除錯(debug)、使用開源碼、使用 Google、stack overflow 查詢資料、使用終端機及 UNIX 指令、嘗試一些新套件、程式碼重構等等,這些在白板題看不到有用資訊(signal)
  • 一些高效的面試策略
    • Take time with your team to identify which qualities in a potential teammate you care about the most: coding aptitude, mastery of programming languages, algorithms, data structures, product skills, debugging, communication skills, culture fit, or something else. Coordinate to ensure that all the key areas get covered during an interview loop. 花時間確認團隊最在乎的核心價值是什麼,例如:coding style、程式語言種類、演算法、資料結構、溝通技巧、文化等等,可以幫助選擇面試者的方向
    • Periodically meet to discuss how effective the current recruiting and interview processes are at finding new hires who succeed on the team. Keep on iterating until you find ways to accurately assess the skills and qualities that your team values. 定期討論當前的應徵策略及流程是否符合目前團隊的需求
    • Design interview problems with multiple layers of difficulty that you can tailor to the candidate’s ability by adding or removing variables and constraints. Building a fast search interface can, for instance, be made harder by requiring the search query to be distributed across multiple machines. Or, it can be made simpler by assuming size constraints on the items to be indexed. Layered problems tend to provide more fine-grained signals about a candidate’s ability than binary ones, where the candidate either gets the answer or he doesn’t. 設計一個分等級的面試題,以對應不同能力的面試者
    • Control the interview pace to maintain a high signal-to-noise ratio. Don’t let interviewees ramble, get stumped, or get sidetracked for too long. Either guide the interviewee along with hints, or wrap up and move on to a different question. 控制面試的步調,維持高 signal-to-noise 比例,不要讓面試者閒置太久
    • Scan for red flags by rapidly firing short-answer questions to probe a wide surface area. Questions like how parameter passing works in a programming language or how a core library works might take a qualified candidate no more than a few seconds or a minute to answer, but can surface any warning areas that you might want to further address.
    • Periodically shadow or pair with another team member during interviews. These sessions help calibrate ratings across interviewers and provide opportunities to give each other feedback on improving the interview process. 定期參與其他團隊的面試,可以互相學習彼此的面試流程、得到彼此的回饋
    • Don’t be afraid to use unconventional interview approaches if they help you identify the signals that your team cares about. Airbnb, for example, devotes at least two of its interviews to evaluating a candidate’s culture fit because they attribute much of their success to everyone’s alignment on the company’s core values. 勇於嘗試新的面試型態

Design a Good Onboarding Process

  • 花時間在面試,也就是推團隊有幫助,也是對自己有幫助
  • Quora 的新進人員訓練流程中,每個新人配有一個 mentor
  • Onboarding is a win-win situation; the new hires receive valuable training, and the mentors get more things done
  • Quora 的新進人員訓練,包含四個目標:
    • 讓新人儘快進入狀況:越快進入狀況,也就能越快能提高生產力
    • 傳授團隊的文化及核心價值
    • Expose new engineers to the breadth of fundamentals needed to succeed
    • 增進與團隊成員的互動:幫助認識團隊的所有成員,更能增進團隊合作的效率
  • Quora 的新進人員訓練,分成以下四個主要的活動:
    • **Codelabs:**這是學習 Google 的 codelabs 概念。Codelab 是一個文件,用來解釋公司的程式碼抽象概念、如何使用等等。他們針對自己的 web 框架 WebNode、即時更新系統(Real-time updating system) LiveNode、快取層(Caching layer)DataBox、除錯工具製作 Codelab,就是為了讓新進工程師能夠了解公司整個基本架構是如何建立及運作的
    • **Onboarding talks(報到講座):**Quora 有一系列 10 堂的報到講座,該講座的講者通常是資深工程師,介紹公司的 codebase、網站架構、展示開發工具、單元測試等等。也藉此認識團隊成員
    • **Mentorship(導師制度):**藉由導師制度做一對一的引導及教學,討論進度、review code、做訓練規劃等等
    • **Starter tasks(新手任務):**解一些 bug、新增一些小功能,藉此讓新人可以更快進入開發流程
  • 好的新進人員訓練是一個迭代的過程

Share Ownership of Code

  • 讓團隊的所有人了解彼此的工作內容,這樣才可以互相 cover。當有人生病或請假的時候,就有人可以支援,也減少 on-call 的機會
  • 可以將維護負擔的責任平分擔到團隊成員中
  • Strategies of increasing shared ownership:
    • Avoid one-person teams. 避免一人團隊
    • Review each other’s code and software designs. 互相做 code review
    • Rotate different types of tasks and responsibilities across the team. 團隊成員輪流做不同類型的任務
    • Keep code readable and code quality high. 維持良好的程式碼品質
    • Present tech talks on software decisions and architecture.
    • Document your software, either through high-level design documents or in code-level comments. 維護程式碼、製作相關文件,不論是一般的開發用文件,或是寫註解在程式碼裡面
    • Document the complex workflows or non-obvious workarounds necessary for you to get things done. 將複雜的工作流程文件化
    • Invest time in teaching and mentoring other team members. 將時間投資在教學、栽培團隊成員

Build Collective Wisdom through Post-Mortems

  • post-mortem(事後剖析)不是為了要追究責任,而是分析發生的原因及來龍去脈,並且討論防範的措施及改進的地方
  • 美國太空總署 NASA 從 1960 年代開始,就不斷地在做這件事,蒐集並記錄所有的故障紀錄、人為疏失等等,並且同時也記載解決方案,並集結成冊,而成 Flight Rules
  • Fight Rules 裡面描寫碰到的問題及情況,然後包含一步驟一步驟詳細的解決方案
  • Flight Rules 的內容不斷更新,當出現手冊裡面沒記載的狀況時,就會加入手冊裡
  • 正因為每次發射火箭的成本需要花費 4 億 5 千萬美金,所以 NASA 才要做足準備,確保各方面都萬無一失,無論是發射的前置作業,還是任務結束的檢討等等
  • Amazon 及 Asana 利用 Toyota 的「五個為什麼」方法去探討發生問題的根本原因

Build a Great Engineering Culture

  • Great engineering cultures 建立好的工程文化
    • Optimize for iteration speed. 增進迭代速度
    • Push relentlessly towards automation. 推動自動化
    • Build the right software abstractions. 建立好的抽象化
    • Focus on high code quality by using code reviews. 利用 code review 以維持程式碼品質
    • Maintain a respectful work environment. 維持一個相互尊重的工作環境
    • Build shared ownership of code. 共享程式碼邏輯
    • Invest in automated testing. 投資自動化測試
    • Allot experimentation time, either through 20% time or hackathons. 撥出大約 20% 的工作時間在嘗試新技術、或是參加黑客松
    • Foster a culture of learning and continuous improvement. 培養持續學習精進的文化
    • Hire the best.
  • 羅馬不是一天造成的,工程師文化亦然。需要有人起頭,還有眾多工程師持續地維持及改進。當我們每個人都專注在 hight-leverage 的活動,不只是成為高效工程師,而更重要的是高效已融為文化的一部分

Key Takeaways(重點回顧)

  • Help the people around you be successful

  • Make hiring a priority 將徵才視為優先事項

  • Invest in onboarding and mentoring 重視新進人員的報到及培訓流程

  • Build shared ownership of code

  • Debrief and document collective wisdom 收集、建立問題與除錯文件

  • Create a great engineering culture 建立好的工程師文化

  • Vocabulary

    • foray v. 侵略;劫掠
    • life preserver n. 救生圈
    • envision v. 想像
    • offshoot n. 分流
    • wade v. 跋涉
    • obscure adj. 含糊的;晦澀的;難解的
    • acclimate v. 使適應新環境;使服水土
    • supplant v. 排擠掉;代替
    • succinct adj. 簡潔的
    • instill v. 慢慢地灌輸
    • wand n. 魔杖
    • hands-on adj. 親自手動的;躬親的
    • seniority n. 年資
    • impart v. 給予;傳授
    • ingest v. 攝取;吸收
    • demographic adj. 人口統計學的
    • quirky adj. 詭詐的;多變的
    • incapacitate v. 使無能力
    • fungible adj. 不可取代的
    • post-mortem n. 事後剖析;事後驗屍
    • dissect v. 解剖;切開;仔細研究
    • levy v. 強制徵收
    • compendium n. 概略;概要;手冊
    • collective adj. 集體的;共同的
    • evocative adj. 喚起 ⋯⋯ 的;引起 ⋯⋯ 的
    • allot v. 分配;指派;撥出
    • rung n. 梯級

Epilogue


Time is our most finite asset, and leverage—the value we produce per unit time—allows us to direct our time toward what matters most.

時間是我們最有限的資產,而 leverage(單位時間的產出)能夠引導我們去找做最優先、最重要的任務

  • leverage 不限於工程界,而適用在所有的地方,例如我們的生活
  • 生活上的任何決定,我們都可以使用 leverage 的技巧分析下一步該怎麼做
  • 但也不代表我們必須在各方面都追求 high-leverage(高效益),休閒活動例如:旅遊、爬山、跳舞、跟家人朋友的相處時光等等,生產力就不再重要

Vocabulary