《Software Engineering at Google》ch 2 — How to Work Well on Teams

一個沒那麼肥的肥宅
今天的天空,有點藍
11 min readDec 11, 2021

前言:對於軟體工程的興趣隨著職涯的年齡與日俱增,恰好前陣子發現 Google 出了關於軟體工程的經驗談。《Software Engineering at Google》這一系列的文章是想分享我閱讀《Software Engineering at Google》這本書的筆記。透過汲取更多前人的經驗,來讓自己對於軟體工程方面的 scalability 能夠更有感觸。希望可以給自己的學習歷程留下一些什麼,也希望對想了解這方面知識的人有一些幫助。

本章節談是關於 Google 軟體工程中的文化與社會層面。我們常說人類天生是不完美的,但在了解同事會寫下的 bugs 前,你最能夠掌握的是自己的 bugs。我們希望你能思考自身的行為與態度,並從中了解到如何成為一個更有效率且成功的軟體工程師,能夠花更多的時間在寫出好的程式碼,減少在人際問題所需要的精力。

在這章節中,最重要的一點是必須瞭解軟體開發是一項團隊共同努力的工作。為了要能夠在工程專案中取得成功,必須圍繞著謙遜、尊重、信任的核心原則。

幫助我將程式碼藏起來

Ben 與我在 2008 年中時發現一些需求的趨勢,如「你是否在版本控制系統中隱藏某些分支」、「你能否創造出一個一開始能夠藏起來而當準備好才發布的開源專案?」、「我想要重寫我的程式碼,你能否幫我擦掉所有過去的歷史紀錄呢?」。這些議題的共同點是什麼呢?

答案是不安全感。人們往往害怕被評判,尤其是在面對某些還未完成的事情的時候。但實際上,這樣的不安全感隱藏的是更大的問題。

天才的迷思

人們天性上會想要找出一個模範並且崇拜他。對於軟體工程師來說,這些模範可能是 Linus Torvalds、Guido Van Rossum 或是 Bill Gates。畢竟像是 Linus 自己寫出 Linux 的,不是嗎?

實際上,Linus 做的是寫出一個類似 Unix 的 kernel 的 proof-of-concept,並且展示到 email list。這絕對是一個令人驚艷的成就,但這畢竟只是冰山一角。現在 Linux 是當初的數百倍大並且由數千名工程師共同開發。Linus 真正的成就是帶領這些人一起共同協作。Linux 並不能說是一個人的成就,而是整個社群共同協作的智慧結晶。同樣地,Unix 本身也並不是 Ken Thompson 與 Dennis Ritchie 單獨完成,而是 Bell Labs 中的一些很聰明的人所共同合作。Guido Van Rossum 並不是一個人寫出 Python 的一切,他寫了第一版,但是有數百位其他的工程師貢獻了隨後的新版本、增加的新功能與改善的 bugs。Steve Jobs 帶領團隊做出了 Macintosh,Bill Gates 的成就在於建立一個圍繞在 MS-DOS 的成功企業。因此,天才的迷思只是做為人們想要將整個團隊的成功歸因於某個領導者的傾向罷了。

在許多工程師的內心身處,多都曾有下面這種期待被視為天才的歷程:

  • 你突然想到某個超棒的點子
  • 你躲在某個山洞好幾個月,努力將你的點子做出產品
  • 你接著將你的軟體發布給全世界,每個人都被你的天分震驚了
  • 你的同儕被你的聰明所震驚
  • 人們爭先恐後的使用你的軟體
  • 名氣與金錢隨之而來

暫停一下,該回到現實了,你可能不是一個天才。

沒有冒犯之意,不過即使你是個相當聰明的人,你仍然會犯錯。再說,即使有聰明的點子與超強的程式技巧也無法保證你的軟體會大賣,更糟的是你可能最終會發現自己在解決的僅僅是個分析的問題而不是人類的問題。此外,成為一個天才絕對不是作為怪人的藉口,因為缺法社交技巧通常不會是很好的團隊協作者。大部分 Google ( 以及絕大多數公司 ) 的工作都不會需要天才等級的智慧,但是絕對 100% 需要一定的社交技巧。在像是 Google 這種公司,與同事協作的好壞與否,往往關係著職業生涯是否能夠再向前一步。

結果顯示,天才迷思是不安全感的另一種顯現。相當多的工程師相當害怕去分享才剛開始的工作專案,因為這代表同儕會看到他們所犯下的錯,進而知道程式碼的作者並不是天才。這也造成前述所說的,某些工程師希望躲在洞穴裡面不斷地修正、修正、再修正,直到確保產品沒有一絲缺陷才將傑作公諸於眾。將程式碼藏起來可以說是非常完美的選擇。

事實上,工程師們可能都曾經有過這種感覺 : 「在事情完成以前總會有強烈的不安全感,彷彿人們看到之後將會強烈地批判我或是認為是個傻子。」因此,躲在洞穴埋頭苦幹地做,直到完成你的曠世巨作才公諸於眾,就成了再自然不過的選項了。

另一個這麼做的動機,可能是出於擔心其他人會在你完成事情之前,就將你的點子偷走並且去實作;畢竟,藉由將秘密藏起來,你就控制了這個點子。如果你真的這麼想,我們將告訴你為什麼事情不是如此。

隱藏通常意味著傷害

如果你花了非常多時間獨自工作,你其實在增加不必要的失敗風險。即便軟體開發是需要高度專注且獨處的智慧結晶,你仍然會需要人與人互相合作,透過教學相長所帶來的益處。

早期檢查

如果你將等自己的絕妙點子都完成實作之後才跟任何其他人分享,這樣的行為是一場豪賭,因為有相當高的機率你可能有重複造輪子的風險,而且也喪失了共同協作的好處。早期失誤的機率相當高,只要越早得到回饋,就能降低更多風險。記得原則:「及早失敗、快速失敗、經常失敗」。

巴士因子

Bus factor (noun): the number of people that need to get hit by a bus before your project is completely doomed.

如果你是唯一個在從事你的專案的人,你或許能感受到秘密不會外洩的安全感,不過當你被公車撞到時,你的專案馬上就無法再向前進了。當你與另一個同事一同共事,巴士因子就放大一倍。如果你有一個小團隊,那麼專案就有越高的機率在有人消失的時候 ( ex: 結婚、離職、為了照顧親戚而請假… ) 能夠繼續走下去。此外,良好的文件同樣也能增加巴士因子。

進展速度

除了巴士因子之外,還有一個與進展速度有關的議題值得討論。一個人單獨工作時,往往進展緩慢,只有一個人時,你能夠學到多少東西?你能夠做多快?網路上的資源或許豐富,但都比不上真實的人與人的接觸。這也是為什麼在許多軟體公司裡面,團隊通常會做在一起 ( 或是進行結隊程式設計 )。程式設計很難,軟體工程更難,你會需要另外的那雙眼一同協助。

換另一種比喻。回想一下你是如何與 compiler 一起工作,你是否會花了好幾天寫了 10000 行程式碼才按下 compile 的按鍵呢?當然不會。通常在越短的迭代,程式設計師的工作效率才會越高:寫新的函式、編譯、增加一個測試、編譯、重構、編譯。這也是現今 DevOps 的哲學:越早得到回饋,越早進行測試,越早去思考安全性與產品的環境等等的因素,全部都與左移有關;因為越早發現問題,那麼要修正就越容易。

總之,別藏起來

自己一個人單獨工作的風險一定較與他人一同工作的風險來的更高。即便你擔心某些人會偷了你的點子或是認為你不夠聰明,你更該關心的是浪費寶貴的時間在錯誤的方向上。

歸根究柢還是團隊

在程式設計的領域中,踽踽獨行的工匠實在非常罕見,即使他們存在,也是無法靠著自己達成超越常人的成就;那些改變世界的成就往往都是火花般的靈感與英雄般的團隊相輔想成。

軟體工程是一個團隊努力的成果。你無法只透過躲在山洞裡閉門造車來改變世界,而是需要與他人合作、分享知識、團隊分工、互相學習才有機會獲得成功。高效率的團隊是成功的關鍵,你我都應該要以這個做為目標往前行。

三個重要因素

如果說團隊合作是能夠創造出好的軟體的最佳路徑,那麼我們該如何建立這樣的團隊呢?謙遜、尊重、信任是我們認為最重要的三個因素。幾乎大部分社會層面上的衝突,都是來自於缺乏謙遜、尊重與信任。回想一下某些自己所遭遇的困境,是否每個人都足夠謙遜?是否人們真的互相尊重?人與人之間有互相信任嗎?

放下自我

沒有人想要與總覺得自己最聰明的人工作。即使你真的是非常聰明,也沒有必要在別人面前彰顯這件事。這與自信不衝突,但是請不要認為自己是無所不知的人。放下自我,不要過度擔心自己是否有優秀到超越別人,相反地,追求整個群體的自我,嘗試去建立整個團隊的凝聚力與認同,才是重要的事。

學習如何給予與接受評論

在足夠專業的軟體工程環境中,任何的評論幾乎都不會是針對個人的,這只是為了要完成更好的專案的過程而已。這其中的訣竅是,你要能夠區分出對於某些人的產出給出有建設性的評論與對於某人人格特質的批評是不一樣的。此外,相當重要的是,學習如何尊重夥伴並且禮貌地給予有建設性的評論。只要真心尊重他人,就有動力去選擇更委婉且有幫助的措辭,這將在第 9 章繼續討論。

站在另一面,你同樣要去學習接受評論。程式設計就像是其他任何的技巧,是可以透過練習得到進步的。如果你的同儕提供了你一條更好的寫法,難道你會將其視為人格上的攻擊嗎?我們希望不是如此。你的自我價值並不該與你的程式碼或是任何你的專案有所連結,因此請不斷告訴自己:

You are not your code。

舉例來說,你最好不要這麼對你的同事說:「你的這個函式完全搞錯控制流程了,你應該使用的是類似別人使用 ooxx 的程式碼模式」這樣的評論充滿了反模式:告訴別人他們是「錯的」、要求他們改變、以及指責他們與其他人不同。較好的陳述方式是:「我對於這部分的控制流程有些困惑,我想知道如果套用 ooxx 的程式碼模式能否讓這段變得更乾淨且容易維護?」注意到,你正在謙遜地讓問題是有關於你自己,而不是他們。他們並沒有錯;你只是對於理解這段程式碼有些疑問。這樣的討論專注於程式碼本身,而不是任何人的價值或是程式技巧。

快速失敗,再迭代

有個很有名的都市傳說:一名經理人犯下了失誤導致公司損失一千萬美元,他隔天垂頭喪氣地來到辦公室並且收拾自己桌上的物品。當他終於接到「CEO 想找你」時,他來到了 CEO 的辦公室並且在辦公桌上放上了一張紙。

「這是什麼? 」CEO 問。

「我的辭職信。我猜測你請我來是為了要當面告知要開除我了。」經理人回答。

「將你開除?我為什麼要開除你?我才剛花了一千萬訓練你!」CEO 這樣回答。

這當然是個非常誇張的故事,但 CEO 知道將其開除也無法挽救回那損失的千萬美元,而且還會損失一個他非常確定永遠不會在犯同樣的錯的主管。

在 Google,失敗被認為是良好的學習機會,能夠再下一次做的更好。正如同愛迪生所說的:「如果我發現有 10000 種方式都無法成功,我並不是失敗,我也不會氣餒,因為我每一次錯誤的嘗試都是下一次往前一步的基石。」

絕不指責的檢討文化

從錯誤中最好的學習方式莫過於對於錯誤做 root cause analysis 並且記錄在所謂的事後分析中。要注意的是這個事後分析並不是寫了一堆無用的藉口,而是應該明確描述學到了什麼、以及記取教訓之後該做什麼樣的改變,接著,確保團隊都能夠存取得到文件並且遵循這樣的修正。好的紀錄能夠協助他人避免重複犯下一樣的錯,所以千萬不要將這些紀錄擦掉,因為這些紀錄很可能是遭遇同樣迷霧中的其他人的一盞明燈。

好的事後分析應該要包含以下:

  • 事件簡短的摘要
  • 從事件發生、調查到解決的時間軸
  • 事件成因
  • 影響與損失評估
  • 一系列修正的動作
  • 一系列避免重蹈覆轍的動作
  • 所學到的教訓

此外,保持耐心且心胸開闊,而不是互相指責,才有機會建立好的團隊,創造出好的軟體。請記住,你的同事是你的夥伴,不是你的競爭者,你們有著共同的目標。

Googley

在過去,Google 會用 Googley 來形容某些內部的文化,這個詞彙沒有被明確的定義過,每個人只將其當作「做對的事情」或是「對他人友好」等等較為模糊的意義,甚至,在面試的時候,人們會用「這個人程式寫得不錯,但是似乎沒有 Googley 的態度」。但逐漸地,Googley 這個詞彙已經承擔了過多的意義:如果不夠 Googley 代表的是「面試者不夠像面試官」因而不被錄用,那對於 Google 是個相當不好的事情。Google 一點都不希望雇用某個「很像我」的人,而是希望找到來自四面八方且背景都不同的人。

因此,Google 也將 Googley 認真的定義出一個明確的意義 — 一個代表具有領導精神,並且強調謙遜、尊重、信任的特質。

結論

運作良好的團隊是好的軟體背後的基石。儘管天才的迷思仍然存在,但真相是沒有人能夠只靠自己完成一切。有了謙遜、尊重、信任這樣的特質,以及鼓勵人們勇於承擔風險與失敗的文化,健康的團隊才會存在。

--

--