作者 | Mickey Muldoon
譯者 | 孫薇
我並非一個10倍的開發者(10倍開發者指的是在其領域,所產生的成果是其他同事的十倍),從撥號時代以來,我從未建過網站,大學畢業沒幾年我就選擇了編程,因為對於政府和政治這些東西我並不擅長,導致事業一度陷入僵局。
因此,大約5年中我一直在朝九晚五地寫代碼,那段時間我還養著3個孩子,剛開始編程時2個才出生,1個2歲。所以,我不是那種通宵達旦、周末無休的程式設計師,我還得照顧家人。
大約一年前,我開始為自己的首個開源項目投入貢獻,那是我的第一個副業項目,一個會議網站。
我從未完整地讀過一本軟體工程相關的書籍。
總而言之,我只是一個1倍開發者,所做的事情也只夠讓我體面地混過去而已。
作為一個1倍開發者,我大量使用了常規知識,對於軟體工程我沒太多有趣的新東西可說。
總的來說,我還沒抽出時間大量從事工作以外的內容,或者在副業上再多花些時間,或者真正廣泛地讀些東西,或者大幅超越自己。我在主業和副業上都難以抽出更多時間。
但我感覺到了自己的雄心,想要成為一個1.1倍的開發者,也在嘗試找到辦法來實現。
這陣子我的空閒時間多了一些,由於新冠疫情和隔離,導致我雖在休假卻無處可去,孩子們也因為疫情而只能休著「春假」在家學習,於是就有了本文。
因此我打算以如下方式將我的軟體工程學知識作以闡述:
1. 寫下我關於某些軟體工程學話題的愚見;
2. 將我的想法分享給更聰明的人,請求大家猛烈地批評指正;
3. 基於第二點更新;
4. 嘗試找出方法,以查找軟體工程相關的信息,或者基於新項目的反饋,並根據優先級將有用的信息排序,並與第一點相結合。
事不宜遲,以下就是我關於1倍開發者的經驗法則。
規則本元
規則1:規則是個好東西
根據我的觀察,人類天生就在尋求非理性、不一致性和權威主義的模式,也就是說,一般而言大多數人會不自覺傾向於將目標設定為令領導者滿意的方式,複製周邊人的做法,並遵循某些已有的模式。在一個複雜的世界裡,保持理性和一致性非常困難。因此,直接完成「領導指派的任務」或者「同事都在做的事情」就成了簡便的選擇。
在許多情況下,這條策略能很好地服務於人,而且確實有助於建立「團隊一致性」。但是,如果你的目標真的很外延——比「團隊一致性」要求更高,涉及到完成團隊外部的目標時,嘗試保持理性和一致性就非常有價值了。
我認為,經驗法則(或者你想換個說法,改叫原則)有助於提供一些保護、一些框架、一些支架,讓人們得以擺脫默認思維模式。它們有助於增強某種程度的邏輯一致性;在存在許多相互競爭的優先事項和價值觀時,有助於將重點集中在會話上;當你在無休止的選項中嘗試找到決策方案時,有助於提供一種更加明確和周全的便捷方案。
我在亞馬遜工作,這家公司以存在一套普適原則而聞名,這些原則在招聘時,在艱難決策時,在評估權衡時都會體現。而且我認為,這些原則的存在對亞馬遜是好事,並非由於它們包含任何天才性的特殊之處,而僅僅是因為擁有這些原則總比退回到盲從領導者更好。
思考很困難,決策也很難,有周全的規則來指導決策有助於我們做得更好。
以上這些的意思是:下面列出的經驗法則與亞馬遜的並不完全相同,大多只是在我思考這些主題時,跳到腦海裡的經驗法則而已。
生產力及學習
規則2:我學到的大多東西在其情境之外都沒什麼用處
有時候我會聽人說起,IQ測試唯一衡量的只是「你在參加IQ測試時的表現」。我認同這個說法,並同意大多數知識都是高度情境相關的。從大學開始,我從事了大約7份不同的「真正工作」,每份都有不同的職務頭銜。在亞馬遜,我做過兩個完全不同的產品和行業。
我發現,我在一份工作中學到的大多知識(差不多90%)對下一份來說都是沒用的,即便是在同一個職業領域中。倒並非完全無用——另外的10%可能是非常重要的10%,比如如何更好地處理電子郵件,或者如何應對辦公室政治。但當我開始下一份工作時,我所學到的大多知識仍然全都是「一次性的」,與特定公司的運作方式相關的特定知識。
亞馬遜可能是個極端案例,因為這裡的開發者花了大量時間來掌握公司的內部工具和商業概念,這些在別的公司完全見不到。或許我在某種程度上也被這些感染了,我知道其他開發者有著不同的經驗,他們所掌握的特定技術和技能實際上可以從一份工作遷移到下一份。
在學校時(我的確花了幾年時間工作),事實上大多知識都是不可轉移的。在某個領域學到的東西,對其他領域並無幫助。
因此,我任性地傾向於這樣的想法:如果我今天90%的工作對於下一份工作沒什麼用,就應該減掉那90%(例如:專注於可以通用的想法、系統、抽象概念和技術),只是別太在意那90%(就像我之前那樣),或者找到一份我願意犧牲掉那90%時間的工作,因為我覺得選擇這份工作的原因很重要,或者給的工資很豐厚。
這條規則可能更局限於我個人,因為我已經換了一堆職業。對其他人來說,他們可以將技能從一份工作帶到下一份。
規則3:將「學習時間」集中在複合上
複合是個很重要的概念,在複利中、摩爾定律中隨處可見。它是關於良性循環的概念。因此在我有限的空閒時間裡,我認為需專注於可能引發良性循環的東西。
良好的起點之一就是掌握快速打字的技能。在過去兩個月中,我在keybr.com網站上花了些時間有條理地學習如何打字更快,這讓我能夠在相同時間裡寫更多內容,交流更多東西,完成更多工作,因為我在計算機上做什麼都更快了。
建立持久的關係也是一項複合活動,因為你可以接觸更多有助於你快速完成工作的人員。
消化媒體(書籍、博客等)並非天然的複合過程。唯有當你有某些方法想要反饋、消化,或將現有的知識與想法相融合時(比如本文中一些有價值的內容),作為讀者,除非立即積極「處理」這些內容,否則很可能無法從中受益。
程式語言
這部分很有可能會充分暴露我的無知。
規則4:何時選用Java或C
Java是大型企業應用的理想之選,很難想像諸如亞馬遜這樣的企業使用其他語言。這是因為Java有庫及社區的深層支持,且靜態類型使得處理大公司內部天文數字級別的數據模型變得更加容易。
我將C#視為微軟公司所推出的Java替代版,因此,如果我需要利用Java的某些優勢,但又使用到了微軟的生態系統,就會使用C#。
規則5:何時選用Python或Ruby
Python和Ruby對我來說非常相似。兩者都是腳本語言,且都是動態類型,似乎是00年代最偉大的東西了。在速度比易讀性或debug更重要時,可以選用它們。其次,針對機器學習或者人工智慧應用程式,選用Python。
當使用Python時,應當啟用類型提示會讓情況更加清晰。
規則6:何時使用硬核語言
在我看來:Go、Rust、Haskell、Erlang、Clojure、Kotlin和Scala都是更為硬核的語言,其中我只用Kotlin發布過生產代碼。
但假設一下的話,如果要構建全新的Web服務,我也許會用Go/Rust語言,因為延遲和性能在這種情況下比社區和庫的支持更加重要。當我需要非常優雅或數學化的功能方法,卻又無需大量的業務邏輯時,也許會選用Haskell或Erlang。至於Clojure,該何時使用我就不知道了,在我看來,如果我開始了解和喜歡Lisp之後,可能會用到它。我知道Clojure是一種可編譯為JVM字節碼的功能範例,但在這種情況下,我更傾向於使用Kotlin。因為Kotlin支持Java,對Intellij也有很好的支持。Scala也是一樣,我可能首先會用Kotlin。
規則7:怎樣使用Javascript
我寫過的代碼中,最糟的便是Javascript的。當時,我正為亞馬遜開發移動購物體驗,我的團隊對JS框架知之甚少。因此我們換成了vanilla JQuery。起初非常簡單,但之後我們有很多前端需求,很快管理前端狀態完全成為了噩夢,想想看,組件消失又重現,而我們不知道原因,因此只能在控制臺上註銷掉所有的變量。
因此我是諸多體驗極差的人之一,但我認為,這主要得歸咎於我們自己。現在數年過去了,我的JS準則是:
1. 改用Typescript,讓情況更清晰;
2. 嘗試將更多邏輯塞入伺服器端,如果前端不是太複雜,我會考慮類似Phoenix之類的框架,將所有內容全部丟到伺服器端;
3. 如果需要前端交互性,使用類似Vue或React之類的框架;
4. 不要跳過單元測試。
規則8:何時使用C或C\++
我感覺:不是我們選擇了C語言,而是它選擇了你。有大量的應用程式——作業系統、語言設計、低級編程和硬體都必須使用C語言。
C\++則很有趣,對於諸如機器人技術、視頻遊戲和高頻交易這樣的應用來說,它極為有用。無垃圾回收功能對性能帶來的收益,讓它更優於Java。
規則9:如果想要測試伺服器變更卻不重建,請使用PHP或Hack
由於安全因素,亞馬遜禁止使用PHP,但至少到2020年為止,其改進版Hack還在Facebook和Slack公司的後端上使用。
在此之前我從未考慮過何時應該使用PHP或Hack,也許是因為它們在亞馬遜是一種禁忌。我知道Slack和Wikipedia都在使用這兩種語言,Slack聲稱,它的編程環境極為開發者友好,例如,無需重啟本地伺服器就可查看變更,並web原生支持並發。
技術
規則10:何時使用無伺服器函數
當有一個相對較小且較為簡單的模塊代碼需要偶爾運行時,我會選用無伺服器函數。
規則11:選用哪種資料庫技術
當需要臨時查詢以及/或者需要ACID及事務支持時,請選擇SQL,否則請選擇no-SQL。儘管noSQL在處理事務方面,PostgreSQL(我對AWS Aurora的風格很熟悉)在可用性、可伸縮性和持久性方面表現都在改善,但傳統上來說,noSQL更有優勢。
測試
規則12:何時編寫單元測試
只要缺陷的預期值並非微不足道,我都會嘗試編寫單元測試。預期值算法:「缺陷的可能性\*缺陷的成本」。由於無法真正精確計算出這些值,這算是一種逃避策略。但至少就我編寫的代碼和通常拿到的需求而言,缺陷造成高昂損失的可能性總會發生。
但是,每段代碼都應當有個細緻的單元測試,以證明代碼是以可測試的方式所編寫的,這一點非常重要。
不過,我並不認為需要囊括每行每段代碼,除非你無法信任自己(或別人)在預期值方面的評估結果,那也可以採用這種策略。
規則13:何時編寫集成測試
我對集成測試的定義是:當你調用不屬於自己的代碼時所使用的測試(而不是模擬)。
當我對不屬於自己的代碼不夠信任時,都會嘗試編寫一個集成測試,尤其當這些代碼有可能在我未知的情況下執行更改時。
規則14:何時編寫端到端測試
我將端到端測試定義為產品模擬完整「用戶會話」的測試——這裡的用戶可能是嘗試對我的代碼進行多次迭代,以完成某項工作的人類或者另一臺計算機。這通常是規則12中所定義集成測試的超級集合。
1. 當我對產品的運作原理並不完全了解,也無法對變更進行完整的單元測試,希望能確定該產品的可運行性時,更像是「煙霧測試」;
2. 當我需要回歸測試用例,以便在將來的重構中驗證功能時;
3. 當結果難以提前預知,比如進行複雜的計算時,我想測試一些代碼對其影響。
情況1應當避免,但情況2和3很難真正避免掉。
DevOps
規則15:何時安排專門的支持工程師
在亞馬遜,默認情況下,你對自己的代碼提供支持,因此如果你的某個系統出現了嚴重故障,你某個同事將會被派遣,並預期以通宵達旦的方式工作至問題解決。
可能很殘酷。但在亞馬遜公司(比如我現在的團隊),當然還包括其他公司,會聘請專門的網站可靠性工程師(SRE)在正常的工作時間之外,在線解決生產環境中的嚴重問題。
在多年對付此類問題(並在我的團隊內推動大家解決此類問題)之後,我逐漸相信:作為程式設計師,如果在非工作時間,有可能出現你無法控制的風險,那麼你應當始終提倡有專職的SRE來解決問題。一個很好的案例:如果你繼承了某人的代碼,就可以解決現有的缺陷。
找到身處其他時區、通過訓練足以支持你系統的人員往往並不困難,只需有資金支付即可。團隊中的工程師需要共同努力,將這一觀點傳達給管理層,
安全性
規則16:如果你將所有的IT安全性問題推給信息安全部門(InfoSec),他們將對你提出嚴苛的規則
信息安全是一項艱苦的工作,博弈論想要生效,就會步入難以避免地過度謹慎小心。因此我認為,如果你至少能完成某些自己的安全保障工作,就能避免嚴厲限制的衝擊。
一個很好的例子就是亞馬遜內部wiki的遷移失敗經驗。早在2015年,亞馬遜的信息安全團隊就禁用了PHP。我們內部wiki使用的MediaWiki就是以PHP編寫的,而內部wiki團隊並沒有質疑這個決定(儘管Facebook、WordPress、Slack公司都在使用PHP,Facebook還構建了清理過的Hacklang用以替代),而是執行了信息安全團隊的建議。他們使用基於Java的替代品(Xwiki)來替換MediaWiki,最終使得相關團隊用超過4個自然年的時間替代了24個開發年的產品,還不包括這次遷移對其他團隊工作的中斷——鑑於頁面需要不斷增加已遷移和未遷移項目。如果他們拒絕了PHP禁令,或者自己針對Hack進行一些研究,可能就會避免這場災難。
設計與白板
規則17:讓設計會話關乎輸入,而非批准
很多會議的目的在於獲得批准或者獲得同意,除非萬不得已,這種情況應當避免。你不需要獲批,而是需要做出自己的決策,或者確定該從他人那裡獲得何種程度的許可。
與之不同,設計會議或對話應當是關於信息獲取以及回答問題的。
項目管理
規則18:評估更多用於施壓而非項目策劃
我曾擔任過開發者及嘗試發布產品的產品經理兩種角色,一直以來,我需要參與很多的評估會議。
人們常說,評估是用於計劃的,是為了搞清楚某項工作所需要花費的時間,以便大家能夠據之安排自己的工作。
.在我為期五年的產品發布經驗中,回憶起來僅有一個項目是達到這個目標的——那是一個非常簡單的安卓應用,沒有外部依賴關係,技術上並不複雜,只有一個本地mySQL資料庫,以及一些視圖。在這個特定案例中,由於未知因素極少,評估非常準確,我們可以正確預期工作的完成時間,誤差在1-2天之內。由於我們的期限定得非常嚴格,這次評估起到了很大作用。
這也是唯一一個我參與的項目裡,可以正確量化速度,並正確推進裡程碑的項目。
在其他所有項目中,評估的主要目的是施加壓力:適時拋出類似「你說過只用5天」這樣的對話,從而逼迫開發者更快更努力,同時也花費更多時間迅速完成工作,以免以後再遇到這樣的對話。
我不反對有壓力,但我認為,我們需要正確認識到:這才是評估的主要目的。
規則19:明確嚴格期限、軟性期限、內部期限和預期完成日期之間的區別
嚴格期限:如果錯過將對企業造成嚴重的不利影響。
軟性期限:如果錯過會令某些人看起來會很差勁。
內部期限:這是團隊的內部目標,不會影響到團隊外部的任何人。
預期完成日期:這是團隊針對當下情況所評估的工作完成時間。
我見過很多將這些期限搞混的痛苦經歷。任何時候,如果你拿到一個期限,請確認是其中的哪一個。當然,通常情況下,我們需要保證按時達成內部期限的工作,以確保在嚴格期限之前完工。但需要指出:讓內部期限以嚴格期限的形式體現時,會對開發者造成壓力,讓他們延長工作時間。
需要牢記的另外一點:如果某個工程師給出一個預期時間,而其他人將其定義成嚴格期限(這種情況時有發生),這種做法是錯誤的。
規則20:當某人談及敏捷時,請推進看板方法而不是Scrum
當某人討論我們在做敏捷開發時,對我意味著每兩周一次團隊內部會議,僅此而已。
然後某些人可能會迷失在敏捷開發的兩種風格:看板方法和Scrum裡。在我看來,Scrum意味著「在那兩周之內你需要完成特定的任務」;而看板則意味著「在兩周之內完成你能完成的所有任務」。如果你不清楚所在團隊遵循的風格是哪種,應當明確討論,然後推進看板方法。考慮到評估的難度(見規則18),Scrum很容易導致在那兩周時間裡,你需要被迫加班以完成相應的工作。
原文連結:
https://muldoon.cloud/programming/2020/04/17/programming-rules-thumb.html
本文為CSDN翻譯文章,轉載請註明出處。