產品經理叫你去改一個 Bug,後來……
簡評:在IT行業存在著許多的矛盾,其中一個就是程序員與產品經理之間的矛盾,有人說這對矛盾就像是針尖對麥芒,矛盾極其嚴重,而且貌似產品經理就是最能夠惹怒程序員的那群人,然而其實作為程序員而言,我們的工作是編寫能夠正常運行的軟件,這也是產品經理所希望的,其實無論是程序猿還是產品經理,我們的目標是一致的。
你曾經碰到過現在這種情況:
- 你的代碼非常優雅。
- 你代碼中的抽象剛剛好,不多不少。
- 你的模塊都各自獨立。
- 所有的測試結果都是綠色的。代碼測試覆蓋率報告花了整整一分鍾才打開,上麵顯示著 97%……
生活很美好。
一個 PM(產品經理)跑進來,跟你說上周你發布的那個更新裏麵有個 bug。不論什麼時候,隻要用戶在購物車裏添加了一件商品,購物車中的計數過個好幾秒才會更新。本來應該立即更新的。
PM 跟你說用戶的抱怨如潮水般用來,他問你:你能看一眼麼?
當然你能看一眼,畢竟這是你做的東西。很可能是其他什麼人犯了錯。不過你會修複這個問題的。你就是這麼正直的員工。你在 Git 上把最新的發布版本同步下來,然後開始研究變更日誌。在上一個發布版本中,你把 HTTP request 庫更新到了最新版。那次審核過了好長的時間。你還能記得這次修改確切的提交所在,那天的天氣不錯。你切換到那次提交,然後模擬了一下更新購物車的請求。不錯 ,你已經充分考慮到了代碼的獨立性,可以很容易地在測試環境和生產環境中進行測試,隻需要切換一個構建標記就夠了。
你找到了那個罪魁禍首。看起來你更新的那個 HTTP 庫有個回歸(regression)。對於特定類型的請求,它花了太長的時間來解析傳入的 JSON 負載。你的應用隻能在請求負載解析完成之後才能更新那個計數器。在架構上還沒有處理最終一致性的問題,要加上這種設計的話,本身就足夠當成一個項目來做了。所以你沒法在本地先更新計數器隨後再同步到服務器上。
你知道這是別人犯的錯。唉,這就是生活。你把事情的原因告訴了 PM。他拍了拍你的背,知道這不怪你。你能把這個問題修複麼?
當然。
你已經考慮好你的解決辦法。你不能把變更都回滾。有一大堆新的代碼和 bug 的修複都依賴於這個新版的庫,要是你把所有東西都回滾的話,這些就都白幹了。隻是把這個庫 fork 下來然後維護一個你自己的版本看上去也不太可行。之前這個項目的維護者有一個超級完備的測試架構,會在上千台設備上測試你修複的代碼。而你隻有三台設備,其中兩個的操作係統版本都老掉牙了。最好還是需要他們的反饋,畢竟這是他們維護的庫,他們對其內部結構很了解,而你不了解。
所以你打算這麼幹:
- Fork 這個庫
- 實現代碼修複
- 向原始的 repo 中發一個 pull request
- 你和維護者可能需要來回幾次溝通
- 最終說服他們相信你的方法才是最好的
- 代碼合並
- 等著這個庫發布一個新的補丁
- 在你的代碼中更新這個庫
- 發布產品的新版本
“好極了,”PM 說,“你覺得需要花多長時間?”
你知道這個答案。人們都說程序員不會估算時間,你可不是那種程序員。(《為什麼軟件開發周期通常是預期的兩三倍?》)“兩周,”你眼都不眨地說,“取決於這個 PR 多久才會被接受,還有維護的人多快能發布一個新版本。”
PM 的臉色立刻就變綠了。“兩周?兩周?!”他重複著同樣的話,好像這樣能改變一樣。不過他還是保持了冷靜。PM 知道怎麼處理負麵的情緒,沒什麼可擔心的。“我們的用戶正在流失!他們什麼都不會買了,因為他們沒法看到自己購物車裏麵的更新!我們是個電商公司!這是不可接受的!”
你看著他經曆著悲傷的五個階段(譯注:否認、憤怒、討價還價、絕望、接受)。你等著最後接受的那個過程什麼時候會發生。不過並沒有。他看起來停在了討價還價的階段。“好吧,”你說著,深陷在你的轉椅裏,“讓我想想。”
你會遷就他一下下,然後他可能就會離開了。你還有很多其他事情要做,你知道的。你開始翻看源代碼。這是你的特長,你的手指敲擊著 IDE 的快捷鍵,就好像海神波塞冬駕馭著大海的波濤。啊哈!你找到它了!有個文檔中沒提到的方法,可以在 JSON 解析的代碼中插入一個鉤子,然後用你自己的實現來替換它!
不過等等。這看起來太醜陋了。這可是個非公開的 API,說不定把它暴露出來是個意外呢。你可不想依賴這種東西,萬一他們在下一個版本裏把它移除掉了怎麼辦?那樣你就得把這套東西整個都重寫一遍了。誰想這麼幹啊?不過這確實比自己維護一個沒測試過的分支要快一些。不過還是太醜陋了。
不要。
你可不想因為商務決策而誤導你,毀了你純淨的神殿。你是神聖的守護者,對抗著那些愚昧的事物。這就是為什麼他們會付你那麼多錢的原因。你的責任就是拒絕這種要求。你衝進 PM 的屋子。“答案是不要。沒有什麼優雅的方法來解決它,我不相信醜陋的旁門左道。抱歉。”
他的反應和你預料中的一樣。
“你告訴我有個方法可以做到,不過你不想這麼做就因為它不夠優雅?我們的用戶正衝我們叫囂著,威脅我們要改用我們競爭對手地產品,而你就不願意修複這個問題,就因為它不夠優雅?“
你失敗了。
這人懂什麼軟件工程?你隻用代碼就憑空創建了這個奇妙的世界。高度可擴展的係統,可以抵抗住來自前蘇聯集團中所有黑客發向你的 DDoS 攻擊。你是個藝術家,而芯片就是你的畫布。你已經無數次地閱讀了《代碼整潔之道》,你對它的了解甚至超過了你對自己 GitHub 密碼的印象。
你衝出了那兒。你需要喝點什麼。這樣的人簡直就是業界的禍根。他們覺得自己那些花哨的 MBA 證書能讓他們知道該如何創造出偉大的軟件,而我們這些開發者卻不知為什麼忽略了這種方法。你昂首闊步地走進休息區,那是你每天享用那些美食家們推薦的午餐的地方。還有咖啡,不限量的、美味的、滋潤著你的靈魂的咖啡。你值得這種享受,因為你是個知識工作者。
你衝了一杯 java 咖啡,想找個地方坐下。然後你看到了他。你的公司中最資深的程序員。
這家夥是個徹頭徹尾的核心人員,是那種“我在上廁所的工夫就能寫出一個編譯器”的程序員。在黑客出現之前他就已經是名黑客了。你想要成為這樣的人。他就像是指環王裏麵的甘道夫。這裏所有人在所有時候都尊敬和畏懼著他。不過他很和藹,總是會幫助那些孩子們。他應該願意聽聽你和 PM 之間發生的事情。畢竟,他是你這一夥的。
於是你坐到他旁邊。他正享受著咖啡,正在看著什麼 Haskell 中抽象的數據類型之類的東西。
沒錯,就得和這樣的人聊聊。
你把自己的壯舉告訴了他。他耐心地聽著,偶爾點點頭,問了些問題。他的肢體語言是向後靠著。從他的眼神中你能看得出來,他以前也經曆過這種事兒。
你終於說完了。好累。
你感覺肩上的分量輕了一些。
他看上去陷入了沉思,好像正在謹慎地選擇著詞匯。
你等著他會大笑著宣布“幹的好,孩子!”,然後你們會一起再衝杯咖啡。他會給你講一個他所經曆過的類似的故事,在那一天,他如何斥責一個愚蠢的 PM。你曾經夢想過這一天。你們會用咖啡碰杯,就像那些在戰場上取勝的戰士那樣。至少,在電影裏他們是那麼幹的。當然,他們通常用的是啤酒,而不是咖啡。
在感情上,你是這麼希望的。
你等待著……
繼續等待著……
他直直地看向你的雙眼,穿透了你的靈魂。那些和電腦一起奮鬥過的歲月讓他的目光變得如此難以忍受,不過他使用了什麼魔法,讓你無法移開你的眼睛。
他隻說了一件事。“我們的工作並不是喝喝咖啡敲敲代碼。我們的工作是編寫能夠正常運行的軟件。”
然後他就走開了。
你呆住了一分鍾。在你肚子裏有種什麼感覺,一種空蕩蕩的、惡心的感覺。你開始意識到這種感覺,叫做羞愧。你讓那些你最虧欠的人失望了,那就是你的用戶。於是你回到自己的座位上,迅速搞定了那個“旁門左道”,然後發布了一個新的版本。
你向 PM 道了歉,自己有點失控了。他說沒事。最後隻要沒事就好。你還是 fork 了這個庫,實現了一個正確的修複方式,然後提交了一個 PR。當這個庫以正確的解決方法發布新版本的時候,你總是可以重構自己的代碼的。
最後更新:2017-04-10 17:29:58
上一篇:
阿裏雲購買、升級主機等產品的雲大使優惠券以及優惠券使用規則
下一篇:
致程序媛們的一封信
Following unknown configure options were used:--enable-fpm
python commands.getoutput 不支持history命令的問題
初窺Linux 之 我最常用的20條命令
Spring中BeanUtils.copyProperties方法測試
sicp 4.2.2小節部分習題
政府安全資訊精選 2017年第六期 車聯網和移動安全可能成為未來監管重點
數據庫--如何連接RDS實例,使用雲數據庫?
macos下eclipse啟動報錯的問題
關於MAVEN找不到JDK的那點事
SQL Server中clustered與nonclustered的區別