20 Things I've Learned in my 20 Years as a Software Engineer
標題我差點要說是「開發者的20道陰影😅」…
翻譯的比例約是85%,其他的部分則是我的消化內容,若堅持要看原文的,我覺得沒太大問題。他用字不難,文法不刁,很推薦。👍
網路上關於軟體開發的忠告很多,雖然從前人的智慧結晶中吸取重要的成功經驗很好,但我們一定要謹記在心的是,任何的忠告都有它適用的環境,沒有任何一個忠告是可以在什麼狀況都通用的。就像一樣是軟體產品,有人會建議你要定價要高一點,才回收得了整個開發成本,但20年後公司在軟體產品的定價要低一點,才能獲取更多的用戶,獲得更大的成功;在開發出指標性殺手級App的公司,後來可能會軸轉(Pivot)開發方向,將所有元件功能開發成微服務(Microservices),然後也這樣子建議其他的開發者。
若你沒有搞清楚所在的環境是什麼樣子,這些忠告或建議並沒有什麼意義。硬是照著這些早期的忠告,可能只會讓事情變得更糟。僅管這些忠告真的是實務的智慧結晶,但我們仍需記得以現在的環境及視角,來看待這些忠告是否還合宜。在經過小公司和大公司的軟體產品研發經歷後,以下就是經過20年的軟體開發經歷後,我學到最重要的20堂課。
由於資訊散播成本已幾近為0,而任何一個科技領域深究下去幾乎都是幾十年的經驗積累。僅管軟體開發者幾乎都是終身學習者,但你距離任何一個領域的「專業」,很理所當然地都會是一個很大很長的鴻溝。你越早認清這個事實,越早能擺脫「冒牌者症候群」的困擾,就帶著愉快的心態,去學習及教導別人吧,輸出就是最好的輸入。
就算你乍聽起來就是一個老生常談,但對永遠都對新東西充滿好奇心的工程師來說,要專注開發對用戶來說是「對」的東西,簡直就是貶低了他們的價值。這是一定要被校正的觀念,不論面對的環境或問題是多麼的困難或複雜,多麼有挑戰性,只要開發出來的東西,無法讓用戶用來解決問題,那就是沒有價值。
設計軟體本質上就是一種「傾聽」,我們軟體開發者,得讓自己的一部分是軟體開發者,一部分是心理學家,甚至有一部分是人類學家。投資這個傾聽的過程,就是「設計」的一部分,不管有沒有專屬的UX團隊。認真的自學這個能力,就能為股東帶來可觀的股利,因為誰又能真正精算得出來,浪費了工程師大把的時間,開發出錯的東西,用戶不使用的成本有多大呢?
好的軟體工程師,會深入去想自己的源碼會給用戶什麼樣的體驗。僅管「用戶體驗」似乎跟源碼沒有直接關係,但軟體開發領域中那些呼叫介面(External API),用戶介面(User Interface)或是通訊協定(Protocol),都是好的軟體工程師會打磨的地方,他們會思考誰會用它?為什麼用它?會怎麼樣用它?對用戶來說什麼是必須被滿足,最重要的需求?時刻把這些問句謹記在心,就是創造良好用戶體驗的根本。
軟體工程師就像手裡拿著鐵槌,看到問題的第一個想法就是寫code去解決它。人們傾向用自己擅長的技能解決問題本就是天性,而資歷較淺的軟體工程師,又常有「文人相輕」的毛病,很容易掉進「非我所創(Not Invented Here)」症候群,覺得別人寫的東西就是不夠好,無法解決問題,所以就去重新發明輪子,這是我們必須要多注意的有毒文化。
軟體工程師的主要工作是「交付價值」,而不是「交付軟體」。很少軟體工程師真正瞭解這個觀念,更少人是已經將這個觀念內化於心。能將這個觀念內化的軟體工程師,會以不同的角度看待問題,自然也會用不同的角度找出解法。唯有當你能正確的意識到,軟體並不總是所有解法中最重要的那一個,你就具備了「以正確的工具解決正確的問題」的思維,而且有可能會找出根本不需要是軟體的解法。
有些人會傾向在接到問題之後,馬上跳下去開始寫code。另一種人則是習慣在寫code之前要做好十足的調查,研究,不斷的確認及評估,最終在過多的資訊或可能性中癱瘓掉,動彈不得。不管是哪種人,都難以專心在「解決問題」上。在這種狀況下,唯有設下死線(Deadline),才能迫使他們回頭專心面對問題,在不斷的迭代"不夠好"的解決方案的過程中,讓解法一次次變得更好。
越是資深的技術經理人,越是遠離軟體開發的實作面越遠。僅管如此,瞭解並掌握在軟體開發的生態系統中,「什麼是可能(以)發生的」這個問題,仍然是一個技術經理人不能荒廢的技能。或許跟上這個生態圈的變化,是很累人並需要投入心力的一件事,但如果你無法掌握什麼是合理的可能性,你不但不能自己設計出好系統,你也無法找到值得信任的人來做。總而言之,越久沒寫過code的人,越是要質疑他設計系統的能力及品質。
Bjarne Stroustrup 有句名言:「世界上只有2種程式語言,一種是大家一邊嫌難用還繼續用的,一種是根本沒人用的。」套用到系統這個規模的軟體開發也是一樣,永遠不會有正確的系統架構,永遠都有還不完的技術債,永遠設計不出完美的介面,而且驗證程式永遠來不及測試及保證系統的品質,習慣這個事實吧。不過,這並不是把源碼寫爛,把事情搞砸的理由,而是一個新的學習視角。別再焦慮著不斷追求「簡潔」和「完美」,而是要積極的在「優化」品質上保持活力。最重要的是,要讓你的團隊為創造一個「活著」的,能持續交付價值的系統為榮,並樂在其中。
對每一個「以往都是這麼做(完成)」的作法,每一個對環境的假設,都要有質疑的空間。如果有新人入職,留意他們卡住的地方,為什麼那邊會是問題?他們在想什麼?如果有一個不明就理的功能需求,確保你有打破砂鍋問到底的好奇心,瞭解為什麼他們有這種需求。如果不夠清楚,就繼續問,每一個QBQ(Questions Behinds Quesions)都有值得我們瞭解的洞見。
「10倍工程師」就是個神話,而且是很蠢的那種。那個神話是說這個世界上,會有一個技術超群,思慮深廣的工程師,他1天的產能,能抵其他一般職能水平,但努力工作的工程師2週的份。也許你現在正會心一笑想著,你確實遇過"10倍工程師",他們產出了10倍的源碼產量,然後你和團隊成員,得花上10倍的時間去把他寫的code優化或除錯。「10倍工程師」不是這麼定義的,但也沒那麼難找,只要你能閃過那些0.1倍的工程師,像是不尋求反饋,不測試結果,不考慮極值(Edge Cases)狀況等等的那些,那麼那些一般水平的工程師,個個就都是10倍工程師了。你看,沒那麼難找吧?
沒有什麼問題,是比資深工程師對於他們使用的工具或是開發軟體的方法,都沒有任何評論或意見,還來得嚴重。意見是否被認同,這是個人主觀及經驗問題,但 「沒有意見」完全就是等於「認知不足」的表現 。如果你對自己的開發工具,沒有一大堆覺得很讚的設計,也沒有一大堆覺得很糟的體驗可說,那只能說你對這個工具的認識還很不足,你需要用得更深更久一點。身為開發人員,本就要習慣去探索新的程式語言,新的函式庫,甚至是新的思維模型(Paradigm,我覺得"範式"很難懂…😜),然後去表達自己的意見。要提升解決問題的能力,最好的方法就是積極的去觀察及探索,身邊解決問題的人們,所使用的技術或是工具是什麼。
人們常說,也很喜歡討論一大堆關於創新的主題,但他們通常追尋的,都是CP值漂亮的,或是新奇原創的解決方案。如果你真的「創新」了什麼東西,改變了人們做事的方式,你能得到的通常都是負面的反饋。所以,如果你真的相信你的創新是有價值的,值得堅持下去的,那就做好長期抗戰的準備吧。
許多功能強大或完整的系統,它們保證資料完整性及正確性的主要機制,竟然只是「希望」或「預期」它們運作一切順利。也就是說,任何非預期的運作或操作方式,就會產生不完整或不正確的資料。去處理這些壞掉的資料,絕對是系統運作一段夠長的時間後,任何人都不想去碰的惡夢。你一定要記得,資料很容易,也很合理的,一定會活得比你的源碼還要久,所以投入資源去保證資料的品質,讓它們都是有秩序的,"乾淨"的,絕對是一項划算的長期投資。
許多人聽過一些舊技術,像COBOL或SQL這類仍在運行的系統中,運行的好好的技術。在日新月異的技術變化環境下,它們不但還活得好好的,而且持續在交付價值。就像在地球環境遭逢巨變的時候,活下來的不是地上霸主恐龍,而是"只能"在海裡生活的鯊魚。除非你有十足,充份且正確的理由,才去考慮是否要用新技術取代他們。
工程師不善表達,並不代表他們的意見沒有價值。而表達最多,最吵的那些人也不一定代表他們更瞭解用戶。儘量去詢問所有的用戶,任何你身邊的用戶都去問,獲取反饋和建議,你會知道這是多麼重要的一件事。
軟體工程師不應該只是寫軟體,他們更應該規律性的寫部落格,寫日誌,寫文件,或寫任何能讓他們的溝通能力更精準的東西。寫作有助於釐清問題的本質,也有助於和其他協作對象的溝通,更重要的是,這也能助未來的自己一臂之力。好的寫作能力,是軟體工程師最重要,也必須要精通的技能之一。
每個人都已對「敏捷開發」有些概念了,但所謂的「敏捷」,就是要小單位的創建及學習,然後持續迭代及優化。也許你聽過大公司用了什麼技術很讚,或是什麼開源專案的Scrum流程跑得很好,但你唯一要記得的,就是要先儘可能的讓你的流程短小精幹,直到你很清楚為什麼需要更多,才做出改變。
如果你將軟體工程師的輸出和工作內容分離,你會發現他們就不那麼關心他們的工作了。為什麼DevOps類的工作會這麼受歡迎,不是因為它解決了控制權傳遞或是效率低下的問題,而是因為這是從頭到尾,對全程負責,能直接交付價值的一種工作。為什麼跨職能的專案團隊工作會受歡迎,因為這種工作的範圍,已擴展到每個人都「擁有」這個專案價值的程度。只要讓有熱情及能力的工作者,對整個軟體的設計,開發,到交付等各個階段負責,讓他們真正「擁有」這個產品的一部分,就會有令人驚喜的回報。
面試只能用來瞭解求職者的基本背景,以及他擅長的領域在哪裡。想要透過面試去得知,這個求職者是否適合團隊合作,是一個緣木求魚的想法。不論這個求職者技能多好,知識多淵博,都不代表他會是一個好的團隊成員。更何況,也不會有人會在面試的時候告訴你,他會是一個不可靠,防衛性強,很自負,或是絕不會準時出席會議的混蛋。有人會說,透過一些「訊號」可以辨識或推論得知這些缺點,像是若求職者在面試過程中,頻看手錶或直接詢問時間,就代表他們不會考慮來這家公司入職?這完全是胡扯。如果你繼續在面試的時候,用這些無科學根據的瞎猜找人,你只是在把好的求職者給拒於門外而已。
許多外力或是建議都會促使我們在系統建置的前期,就把規模建置的更大。不論是預算資源的分配,或是決定哪些功能不予製作,都是為了要建立「最好」或「完美」的系統。但這些外力都只會讓我們「做得太多」,這都是我們要挺身抵抗的。學得越多,經驗越多,你就會知道每個系統都是在不斷的迭代及優化,而不是在一開始就設計到最好。這將會是個讓人驚訝,且難以說服眾人的觀念。