本文轉(zhuǎn)載自 InfoQ
身為程序員,我們往往都了解大神級程序員的故事。比如很小就開始編程,在 11 歲時(shí)就創(chuàng)建了第一家能盈利的網(wǎng)站,16 歲上大學(xué)、17 歲成立公司、23 歲成為億萬富翁。我們喜歡這些故事,喜歡這些英雄。他們以高產(chǎn)的編程項(xiàng)目和引領(lǐng)潮流的方式激勵(lì)著我們。從解決復(fù)雜的 NP 問題到籌集數(shù)百萬的 A 輪融資,他們似乎從來不會(huì)失誤。
不過,事實(shí)是這樣的:每一個(gè)開發(fā)者,甚至是這些超牛逼的大神級開發(fā)者,都會(huì)把事情搞砸,然后克服挫折。不同之處只在于規(guī)模:如果我們搞砸了,數(shù)據(jù)庫記錄就會(huì)被破壞;如果他們搞砸了,可能就是一個(gè)價(jià)值數(shù)十億美元的錯(cuò)誤。為什么我們總是如此害怕錯(cuò)誤?犯錯(cuò)是件好事,沒有什么比失敗更好的老師了。但是,它也帶來了某種恥辱,沒有人愿意討論錯(cuò)誤,因?yàn)闆]有人愿意被看作是天才堆中的蠢貨。
但這樣的壓制是有后果的。當(dāng)開發(fā)者犯錯(cuò)時(shí),經(jīng)常會(huì)被認(rèn)為是個(gè)人的失敗然后被指責(zé)?!癕ike 忘記更新發(fā)布文檔”或者“Bill 選錯(cuò)了分支”,這樣做其實(shí)適得其反。失敗通常是系統(tǒng)性的,是發(fā)現(xiàn)和糾正業(yè)務(wù)缺陷的好機(jī)會(huì)。沒有比失敗更好的老師了,我們不應(yīng)該害怕談?wù)撌 1局@種精神,我坦白地指出作為一名初出茅廬的軟件開發(fā)者,我所犯下的三個(gè)最嚴(yán)重的失誤。接著,我將繼續(xù)解釋,我是如何從每一次的失敗中成長起來的,并且我感謝這每一次的失敗。
1刪除了上千個(gè)網(wǎng)址
當(dāng)我在一家大型金融機(jī)構(gòu)工作時(shí),我開發(fā)了一套清理 F5 網(wǎng)絡(luò)層中未使用路由的系統(tǒng)。在阻塞之前,F(xiàn)5 路由池只能支持大約 5000 個(gè) URL。系統(tǒng)會(huì)自動(dòng)監(jiān)控這些 URL 流量,通知未使用的資源的擁有者,并清理掉它們,這樣 F5 系統(tǒng)就不會(huì)崩潰,不間斷的人工手動(dòng)操作也能被解放出來。
該系統(tǒng)一直運(yùn)行良好,但是,在某個(gè)星期天,我醒來后看到一封電子郵件,它說前一晚有 1000 條路由被刪除了,用戶抱怨說這些都是活動(dòng) / 實(shí)時(shí) URL!
大家的周末就這樣被毀掉了,我們的團(tuán)隊(duì)立刻行動(dòng)起來。原來,一個(gè)舊的 .yaml 配置文件與應(yīng)用容器部署在一起,它刪除了 1 周內(nèi)而不是 1 個(gè)月內(nèi)的非活動(dòng)路由。慶幸的是,我設(shè)置了故障保護(hù)以防止刪除生產(chǎn)資源,但是問題仍然很嚴(yán)重,如果我的程序確實(shí)刪除了活動(dòng)的資源,全公司范圍內(nèi)高使用率的應(yīng)用程序可能會(huì)因此中斷。
而結(jié)果發(fā)現(xiàn),大多數(shù)資源若在一個(gè)星期內(nèi)不活躍,那么一個(gè)月內(nèi)仍然如此。換句話說,重要的應(yīng)用不會(huì)在一個(gè)星期內(nèi)都不活躍。因此,最終的損失是可控的:在被刪除的 1000 個(gè) URL 中,只有幾個(gè)遭遇了投訴。但對我和我的經(jīng)理來說,這也是巨大的指責(zé)和壓力,特別是在損失還不清楚的早期階段。所以我們建立了一個(gè)“作戰(zhàn)室”,把整個(gè)團(tuán)隊(duì)的資源轉(zhuǎn)移到手工重建這些丟失的資源上。
為什么會(huì)這樣?
一開始,我認(rèn)為這都是我的錯(cuò)。但是,事后看來,這也是一種系統(tǒng)性失敗。第一,現(xiàn)有的 F5 路由管理系統(tǒng)不能滿足業(yè)務(wù)需求,而且沒有明確的備份 / 回滾策略,這是個(gè)大問題。另外,由于不必要的復(fù)雜部署過程,舊配置文件還掛在那里。這太官僚化了,很容易出問題。最終,這項(xiàng)關(guān)鍵任務(wù)交給了我一個(gè)人(也就是說,沒有代碼審查 / 團(tuán)隊(duì)參與),并且 deadline 很寬松,這簡直是災(zāi)難的“配方”。我們從未將這事看得有多重要?,F(xiàn)在,隨著經(jīng)驗(yàn)的積累再回顧過去,可以看出這一結(jié)果似乎是不可避免的。
我是如何成長的?
我很感激那些站出來把我們從這場混亂中解救出來的同事們。而我的經(jīng)理和最資深的開發(fā)者告訴我,他們對我這個(gè)工程師失去了信心,不讓我繼續(xù)參與重要項(xiàng)目時(shí),我感到前所未有的職業(yè)壓力。換句話說,他們不相信我做了如此愚蠢的事,也不相信我可以繼續(xù)從事這個(gè)項(xiàng)目或者其他重要項(xiàng)目(他們最終撤回了)。
雖然很尷尬,但我承認(rèn)我還是為此哭了。后來一位隊(duì)友帶我去喝啤酒,當(dāng)我把談話內(nèi)容轉(zhuǎn)述給他后,他說這很不公平,并且告訴我他和其他隊(duì)友都非常欣賞我。這一周我一直被壓得喘不過氣來,聽到有人這么說的時(shí)候,我終于忍不住了。另外主管還帶我去吃午餐,幫我度過難關(guān)。所有這些都讓我記憶猶新。
它使我了解到,盡管代碼有良好的控制,但基礎(chǔ)設(shè)施和數(shù)據(jù)卻常常沒有得到良好的把控。通過 DBMate 和 Terraform 等數(shù)據(jù)庫遷移工具管理系統(tǒng)中的這些組件,并將其與應(yīng)用程序代碼的重要性同等對待,這一點(diǎn)非常關(guān)鍵。
對于生產(chǎn)環(huán)境,限制訪問也是至關(guān)重要的。例如,我甚至不會(huì)在 IDE 上保留一個(gè)本地主分支,而是傾向于鎖定團(tuán)隊(duì)范圍內(nèi)對非特性分支的所有直接推送。默認(rèn)情況下,數(shù)據(jù)庫和云賬戶應(yīng)該是只讀的,應(yīng)該有明確的備份和恢復(fù)策略。例如,在我接下來的工作中,一個(gè)開發(fā)者意外地刪除了 prod S3 存儲(chǔ)桶中的文件。要不是我在一周前就設(shè)置好 S3 的版本控制策略(默認(rèn)是關(guān)閉的 —— 亞馬遜太坑爹了!),我們可能會(huì)永久丟失。
最后,我上了最后一課,也是最重要的一課,那就是同理心。最近我的一位隊(duì)友也遇到了類似的情況:他將錯(cuò)誤的代碼投入生產(chǎn),而我們不得不手工修改一些數(shù)據(jù)。他對自己的所作所為感到內(nèi)疚。借此機(jī)會(huì),我明確地解釋,這是因?yàn)槲覀兊牟渴饠?shù)據(jù)遷移流程還不夠完善,這是我們團(tuán)隊(duì)的失敗,而不是他的失敗,都是注定要發(fā)生的。與此同時(shí),我還要提醒他,他所創(chuàng)造的偉大的功能,對我們和公司來說是多么重要。其錯(cuò)誤只是提醒我們重新檢查我們的工具 / 流程,這也是促使他對解決方案做出貢獻(xiàn)。錯(cuò)誤就是機(jī)會(huì)。
2將代碼通過電子郵件發(fā)到公司外部
在離職之前,我把代碼通過電子郵件發(fā)給了自己。在對 Spring 庫進(jìn)行了近一年的研究后,我創(chuàng)造了一些非常好的測試模式。我不想忘記這些好的想法,并打算在 Medium 博客上撰寫關(guān)于這些想法的系列文章。
約一個(gè)月后,在我新入職的第一天,我收到了令我臉色煞白的短信?!案鐐儯覀儓F(tuán)隊(duì)出事了。有人把代碼通過電子郵件發(fā)到了公司外部,這涉及到法律問題。你知道是誰干了這事嗎?”
我立刻打電話給以前的經(jīng)理,沒有人接。打電話給我的同事,無人接聽。法律部門已經(jīng)介入,讓他們與我斷絕聯(lián)系。這真是太可怕了。新經(jīng)理覺得不對勁,就問起我這件事。他過去是個(gè)律師,所以他讓我請律師以防萬一。我急切地給妻子的家庭律師打電話,討論了各種情況。由于牽涉到的是實(shí)用程序代碼,因此他們不太可能會(huì)“找我麻煩”,但可能性還是存在的。
那天妻子來接我時(shí),心情很好。她問我第一天過得怎么樣,我回答說:“我想我搞砸了”,她臉色也變了。當(dāng)我說完這件事的經(jīng)過后,她像吃了定心丸一樣,告訴我,雖然真的很蠢,但是我們能挺過去。接下來的一個(gè)星期,我一直生活在迷霧中,直到我前公司的法務(wù)團(tuán)隊(duì)找到我,告訴我,如果我簽署立即刪除那段代碼的協(xié)議,他們就不會(huì)起訴我。
為什么會(huì)這樣?
舊有觀念把我束縛住了,就這么簡單。盡管它看起來像一個(gè)邪惡的陰謀,但一個(gè)簡單的事實(shí)是,我對我創(chuàng)建的模式和實(shí)用程序感到非常自豪,我認(rèn)為如果我失去了它們,我就會(huì)失去一些作為開發(fā)者的東西。我有一些宏偉的想法,那就是這樣可以產(chǎn)生一些有趣的博文,不知何故,我滿腦子只想這件事,利益超過了風(fēng)險(xiǎn)。
時(shí)至今日,我依然為這次事件給我的前隊(duì)友帶來的影響感到難過。這個(gè)錯(cuò)誤百分之百是我造成的,但是他們肯定要處理掉這些后果。團(tuán)隊(duì)的聲譽(yù)可能會(huì)受損,而處理審核問題則會(huì)給大家?guī)砗艽蟮穆闊_@有損于我的職業(yè)聲譽(yù),并令人遺憾地中斷了許多關(guān)系。
我是如何成長的?
最重要的是,此后我對公司郵件和內(nèi)部交流變得非常謹(jǐn)慎。由于在 Slack 私信中的談話不當(dāng),在我新工作不到一周的時(shí)間里,就有幾個(gè)員工被解雇了。這是一件相當(dāng)混亂的事情:他們都被解雇了,而我們其他人最終也不得不參加關(guān)于工作場所騷擾的強(qiáng)制性人力資源培訓(xùn)。雖然你們公司的技術(shù)人員很不稱職,但是你要永遠(yuǎn)相信他們對你的私信是完全可視的。
還有一點(diǎn)很重要,就是妻子和父母是如何在我身邊支持我的。面對這樣的局面,我感到很沮喪,頭腦一片空白,是他們的冷靜和理解使我回到現(xiàn)實(shí)。那時(shí)候,我處在生存危機(jī)的邊緣:我怎么能有博士學(xué)位,同時(shí)又那么粗心大意,還那么愚蠢呢?這樣會(huì)不會(huì)毀掉自己的未來?如果沒有家人的支持,我可能會(huì)走火入魔,使整個(gè)局面更加糟糕。他們的建議和指導(dǎo)讓我請來了律師,使我的處境不再那么糟糕。
YAGNI(you ain't gonna need it,你不需要它),它不僅僅是軟件的一個(gè)原則。這段代碼真的要再看一遍嗎?即便這會(huì)帶來多篇博文,也值得去冒險(xiǎn)嗎?肯定不行。如果你已經(jīng)離開了一份工作,或者為了重新開始生活,那就離開吧。不要帶走任何東西,別往后看,只往前看。
3在新冠肺炎疫情期間失業(yè)
2019 年,我在一家比較成功的初創(chuàng)公司工作,致力于使路面的維護(hù)流程現(xiàn)代化。地方政府是我們的主要收入來源,我們還有風(fēng)投的支持。這兩個(gè)來源都在 2020 年 3 月突然消失殆盡。我們的公司成功地在新冠肺炎疫情爆發(fā)中度過了幾個(gè)月,迅速轉(zhuǎn)向應(yīng)對客戶需求的變化,并通過小企業(yè)救濟(jì)基金獲得了部分資金。
然而到了 7 月,我們顯然需要收縮。CEO 親自在 11 點(diǎn)半時(shí)在 Slack 上給我發(fā)了私信,讓我在 12 點(diǎn)打個(gè)電話,這讓我有種不祥之感。到 12 點(diǎn) 15 分的時(shí)候,我就被炒魷魚了。套用一句話:“Adam,我們讓你走,立刻生效。我們認(rèn)為你做得很好;但是,由于目前的環(huán)境,我們打算裁員”。當(dāng)天,我是 15 個(gè)被無情解雇的人之一,沒有任何警告,沒有離職費(fèi),甚至沒有 5 分鐘的時(shí)間向我的團(tuán)隊(duì)道別(通話時(shí) Slack 賬戶被禁用)。
半年前,我和妻子剛剛搬進(jìn)我們的第一所房子,如果沒有穩(wěn)定的收入,我們的財(cái)務(wù)狀況無法維持很長時(shí)間。
接下來的幾個(gè)月很殘酷,我哪兒也找不到工作。同病相憐的質(zhì)量工程師充斥著市場。見鬼,我沒有辦法得到失業(yè)補(bǔ)償,這讓我很沮喪,于是我寫了一整篇博客文章。
怎么會(huì)這樣?
新冠肺炎疫情的爆發(fā),直接導(dǎo)致了裁員和就業(yè)市場的低迷。但是這是一個(gè)慘痛的教訓(xùn):我被解雇了,因?yàn)槲也皇潜夭豢缮俚?。企業(yè)沒有我,生意也能順利進(jìn)行。他們保留的工程師技術(shù)實(shí)力很強(qiáng),但更重要的是,他們在核心業(yè)務(wù)系統(tǒng)上工作。讓他們走,可能會(huì)導(dǎo)致業(yè)務(wù)徹底崩潰。這就是我最大的錯(cuò)誤。
作為一個(gè)新員工,他們將我安排在很酷的綠地項(xiàng)目(指的是一項(xiàng)不被先前工作限制的項(xiàng)目)上。我在 Jupyter 中從事機(jī)器學(xué)習(xí)管道和數(shù)據(jù)分析工作。但是我們的核心系統(tǒng)是普通的 Flask 應(yīng)用。沒有人真的把我推到這個(gè)系統(tǒng)里,所以我保持距離。當(dāng)它們出現(xiàn)錯(cuò)誤時(shí),我沒有解決它們。我沒有在他們慢下來時(shí)支持他們,也沒有人叫我這么做,所以我就沒有這樣做。我做的是很酷的新東西,事關(guān)公司的未來!但事實(shí)證明,這些系統(tǒng),以及構(gòu)建并支持它們的工程師,對公司來說,比我的價(jià)值更大?;叵肫饋?,現(xiàn)在已經(jīng)很清晰了。反思 CEO 不得不做出的艱難決定,他還是做出了正確的讓我走人的決定。
我是如何成長的?
7 月至 9 月是艱難的,我在一個(gè)又一個(gè)的工作機(jī)會(huì)中被淘汰。尤其是我?guī)缀蹩梢栽谝患矣耙艄菊业轿覊裘乱郧蟮墓ぷ?,但是在最后一步被拒絕了(連續(xù)兩年),這讓我很沮喪。最后,我接受了一份無聊的 Java 工作。我意識(shí)到,無聊的軟件有直接的需求和專門的使用者,類似“這個(gè)按鍵不可用”之類的事情很容易解決,不需要博士學(xué)位也不需要多年的規(guī)劃。
干一些無聊的事情也能讓你變得更重要。從建立基礎(chǔ)設(shè)施到處理硬功能,我自愿做了很多核心工作。盡管我的目標(biāo)不是成為系統(tǒng)本身的一部分(也就是說,我仍然希望實(shí)現(xiàn)自我控制),但這將使我更難離開。
同時(shí),我也不再擔(dān)心面試和失業(yè)問題。我們只能盡力而為,努力做到最好,其他的我們都無法控制。你沒得到這份工作,或許是因?yàn)榱硪粋€(gè)人在某項(xiàng)技術(shù)上更有經(jīng)驗(yàn),或許他們已經(jīng)給出去了 Offer。又或者,你不像下一個(gè)候選人那樣好。丟掉你的自負(fù),坦然接受所有的理由,恐懼就會(huì)消失。意識(shí)到自己可能不是、也永遠(yuǎn)不會(huì)成為一名大神級的開發(fā)者,也沒什么關(guān)系。
最終我學(xué)到的最后一點(diǎn)就是不斷地尋求反饋。我做得怎么樣?為什么我要做 X 工作?X 對公司成功至關(guān)重要嗎?如果不重要,那是什么呢?別太執(zhí)著于自己的工作。有時(shí)候,我們害怕反饋,因?yàn)樗鼤?huì)挫傷我們的自尊心,但是接受反饋就是快速前進(jìn)的道路。此外,如果你是拒絕給求職者反饋信息的眾多公司之一,那你應(yīng)該為此感到羞恥。
這一切表明,失敗和障礙不僅是不可避免的,而且是必然的。個(gè)人的失敗很少是個(gè)人的過錯(cuò)。失敗是一個(gè)機(jī)會(huì)——了解自己和身邊人的機(jī)會(huì)。你老板是想拆你的臺(tái),還是拉你上來?朋友和家人是否支持你?這是一個(gè)多么好的時(shí)機(jī),讓我們暫停、反思并修正方向。