如何成為一個卓越的程式設計師

edithfang發表於2014-07-19



作者是Rails/Angular開發者,企業家& YCalum。早先建立了Clickpass.com網站並出售。目前擔任Brojure.com的OTO(唯一O(only)TO),兼職entrepreneur first。

免責宣告這是一篇非常長的文章,比我通常會寫的主題要長得多。我編輯文章併發給朋友評審,直到他們都覺得文章沒有一字需要刪改的。我希望你也這麼認為。

如果有一件事是開發者都關心的,那就是成為更優秀的開發者。那你應該從哪裡開始呢?你是否應該積累一些附加的賣點:比如專研Node知識和no-sequel?或者你應該死記硬背專業的閘道器問題答案,並能按要求立即寫出氣泡排序演算法和短連線演算法嗎?或者有其他更基本和關鍵的東西更值得你投入?

我相信,作為一個程式設計師的資歷和價值並不是以你所知道的東西來衡量的,而是通過你做出多少成就來衡量的。這兩者是相關的,但又有本質的不同。你的價值是你如何推動專案前進,如何鼓勵你的團隊也這樣做。在我十五年的開發生涯中,我從來沒有需要實現一個氣泡排序演算法和短鏈演算法。不過,我花費了成千小時來編寫和重構賬戶管理工具,編輯套件,快取邏輯,郵件介面,測試套件,部署指令碼,JavaScript分層,分析架構和文件。這些都是有價值的事情,完成了這些事情推動了我們的前進。

那些微小的元件是構建專案的磚瓦和沙礫,需要成百上千小時的辛勞工作來組建。儘管它們被用來組裝複雜系統,它們本身卻不應該是複雜的。你應該將簡化這些元件作為目標。多年來,我學會簡單可以通過假以時日的不斷工作和重構來達到,而這比純粹“靈感一閃”的思考更容易得多。

簡單和卓越通過一些事情或者任何可以讓工作完成並從回頭重新審視這樣的過程來不斷完善,這是最可靠的路徑。這也是那些公司和MVP試圖深入我們意識觀念的真諦,軟體也是如此。從一些可工作但醜陋的解決方案開始,你不斷應用這個醜陋和怪異的方案,不斷重構它為最簡單的形式。簡單從工作中比“靈光一閃”來得更為可靠。通過寫程式碼比費力思索更加可預期。簡單來自努力。

衡量一個開發人員的價值,不是通過你能達到的某個點的高度值,而是在於你表現線下的面積值。— Peter Nixey(@peternixey) April 22, 2014

對於聰明的懶人來說,他們可以輕易展現自己的卓越才華,亮瞎同齡人的雙眼,然而公司卻不能建立在這些人之上,產品也無法落實在那些“卓越的才華”上。公司是由那些每天進出辦公室,提交良好的程式碼,並且也讓其他人也幹同樣的事情的團隊和個人。偉大的產品由勤奮的馭馬驅動,而不是由那些盛裝的舞步馬推動的。

多年之前,Joel創造了“明星程式設計師”這個詞多,它依賴公司對需要這樣缺乏合作的極客來完成所有事情的誤解。的確存在擁有這樣特質的人,但是人數不多。你發現他們的聰明缺乏規律——讓他們感興趣的事情表現得驚人的聰明,然而在和其他人協作或與團隊無縫合作時,又顯得無法抱有期望。

他們的成果是無法預期的,但是他們的成就又讓人豔羨,而且更具傳染性。他們的傲慢可能傷及到團隊的其他人員。它大聲而且響亮地釋放這樣的訊號:如果你夠聰明,你可以選擇你何時工作和你幹什麼。你成為了一個“Developerin Residence”。你不但吸取了薪水,也扭曲了你周圍工作人員的價值。

所以現實是,你和你的團隊更可能依靠或者說應該依靠於那些值得依靠並可靠工作的人,而不是那些自認為是“明星程式設計師”或者“程式設計忍者”的人。

卓越的開發者不是那些上手就可以寫出氣泡排序或者短連結演算法的人。他們是你一旦將其安排在專案中工作,就會不停推動和鼓舞周圍每一個人來做到一樣的人。讓明星程式設計師滾蛋,僱傭那些可以駕馭的馭馬(FuckRockstars. Hire workhorses),下面一些方法值得借鑑:

為你的函式和變數取個好名字(編寫見名知意的程式碼)

這是一個難以置信的簡單開始,但是我認為它是程式設計中最重要的技巧之一。函式命名是問題定義直接表現,坦白的說,是程式設計最難的部分。(編注:ITWorld 在2013年發起的一個投票,結果顯示:《程式設計師最頭疼的事:命名》)

名字是你程式碼的的邊界條件,命名是你應該解決的首要問題。

如果你的命名是正確的,也解決了邊界條件,使用這樣的名稱,你幾乎不可避免編寫出了高功能的程式碼。

考慮這樣的函式:
defprocess_text string
…
end
它幾乎沒有透露它準備做什麼或者是怎麼實現的,但是:
defsafe_convert_to_html string
...
end
它告知了接下來會發生什麼,通過這個函式你可以預期它會完成什麼,並且你可以多大程度過載這個函式。

開發者可能會很高興重構一個“process_text”函式,同時將字串轉換為HTML標籤並自動嵌入視訊。不過,這在一些使用這些函式地方時可能是完全不期望的。一旦你改動了它,你就製造了bug。一個清晰的名稱,不但保住函式會做什麼,也表明了它不會做什麼。

函式名稱為函式和呼叫它們的程式碼之間建立了契約關係。好的命名定義了好的架構。http://t.co/6JMyGvGuzl

— Peter Nixey (@peternixey) April 22,2014

一個好的函式,承諾了它會交付什麼並如期望地交付了。好的函式和變數名稱,不但使得程式碼更加清晰易讀,也為你縱橫交錯的程式碼庫建立了成千上萬的約束。草率的命名意味著草率的約束,缺陷,甚至建立在它們之上更加草率的契約。

不僅僅是函式命名可以衡量你的程式碼質量,變數命名也應該加強。有時為了簡化,值得建立一個變數名來自注釋程式碼邏輯。

以下面的內容為例:
if(u2.made <10.minutes.ago)
&& !u2.tkn
&& (u2.made==u2.l_edit)
...
糟糕的變數名稱使得你很難弄清楚到底正在發生,甚至哪怕你這樣做了(成功了),你也難以保證100%清楚原作者意圖是做什麼。它什麼也沒告訴你。

“and not”宣告經常讓人困惑(請永遠不要編寫“andnot”與名稱結尾的程式碼),如果你的工作是重構這樣的程式碼,你不得不做一些複雜的猜測來推斷它原始的含義。

不過:
if(new_user.created_at <10.minutes.ago)
&& !new_user.invitation_token
&& (new_user.created_at==new_user.updated_at)
我們將這些變數修改為一些更有意義的名字,程式碼的含義立馬就變得更清晰了:
user_is_recently_created=user.created_at <10.minutes.ago
invitation_is_unsent=!user.invitation_token
user_has_not_yet_edited_profile=(user.created_at==user.updated_at)

ifuser_is_recently_created
&& invitation_is_unsent
&& user_has_not_yet_edited_profile
...
我們還可以進一步要求對 if 語句宣告中的每一部分進行分離,命名元件並做文件註釋。

需要一些勇氣來寫像“user_is_recently_created”的變數名,因為這樣的命名邏輯模糊。不過我們時不時這樣做了,並且承認這告知了程式碼閱讀者你做了什麼假設。

注意,這些方法比使用註釋要更加有效。一旦你改變了程式碼邏輯就會要求你改變變數的命名,而使用註釋卻無法強制這一點。我很認同DHH,註釋是危險的並且容易腐朽——最好是編寫自注釋的程式碼。

程式碼自注釋越充分,其他人就更可能按照其初始的意圖來實現它,程式碼也會有更好的質量。記住,在電腦科學中只有兩類問題最難:快取失效、命名和off-by-one錯誤。(我懷疑作者是寫錯了,這是三個…)。

“如果你想成為一個偉大的開發者,請確保你寫的程式碼讓人見名知意:也就是說程式碼精確地完成了它名字告訴的東西”— Peter Nixey (@peternixey) April 22,2014

在學習廣泛之前先精深某一方面——從裡到外學習你選擇的技術棧。

只有非常少的程式設計問題是真正新的。很多公司所做的技術工作,是之前的許多團隊已做過的。在StackOverflow上吸引眼球的問題很少沒有在其他地方遇到過。

因為這個確切的原因,你正在努力做的大部分事情,已經被你當前使用的技術棧解決過了。我有一次使用了Rails自帶的簡單而強大的方法,將其他人寫的60多行Rails程式碼重構為一行語句,

大多數程式浪費了大量的時間,用於重新實現那些現有的功能。  — Peter Nixey (@peternixey) April 22,2014

這不僅浪費了他們的時間,而且他們新構建的程式碼冗長且含有很多錯誤。新的程式碼需要新的文件註釋,新的測試來檢查,也讓程式碼充滿噪雜,並且難以閱讀。和其他新程式碼一樣,也容易產生bug。使用技術棧經過嚴謹測試並且實際驗證的程式碼,很少產生bug。

如果你是一個Ruby的開發者,請花時間好好學習Ruby,尤其是陣列的那些驚人多的方法。如果你是Node的開發者,請花時間瞭解它的架構、方法及理念體系。如果你是一名Angular的開發者,你應該敢於挑戰,並理解正由核心團隊錘鍊的那不可思議的架構背後的邏輯。在你重新發明之前先詢問。你行走在巨人的陰影下,花費一些時間找到他們的蹤跡,然後你會對他們已經建立的東西感到驚歎。因為,如果你不這樣做,你只是把問題推給了後面的人,別人會指出為什麼你偏偏選擇了你自己的小路走。

學會辨識糟糕的程式碼

有時候,我注意到一些程式設計師挺不錯的,只不過他們趨於安逸,並沒有意識到他們的程式碼其實可以寫得更好。這對於你個人的發展是一件極為糟糕的事情,在你知道如何改進之前,先要知道什麼是需要改進的。知道好的程式碼應該是怎麼樣的,壞的程式碼長得怎麼樣。據說,象棋大師比普通棋手花費多得多的時間,來學習其他優秀棋手的如何下棋。我非常確信這對於開發者來說也是對的。

能覺察到程式碼異味,是提升你能力的重要的武器之一——哪怕只是有一點點異味或者聞起來可能有點異味。異味程式碼,你可能不知道為什麼,僅僅是覺得哪裡不對的程式碼。

你可能做某件事情用了60行程式碼感覺這很簡單,這也可能讓你覺得應該交由語言本身來處理卻被程式設計師手動處理了的感覺,也可能是你覺得這段程式碼糟糕透頂且難以閱讀。這就是程式碼異味。

這不是件容易的事情,但是經過一些年,你會發現哪些程式碼存在異味,漂亮的程式碼應該是怎麼樣的。你會開發出對程式碼的審美觀,對於醜陋事物所帶有的醜陋理論會讓你感覺很不舒服。簡單即是美,而簡單正是我們所需要的。

真理是,真實有時候是醜陋的,但是你應該不斷地追求美麗,並且當你感覺醜陋無法避免,你知道如何優雅地展示它。如果你不能編寫出優雅的程式碼,最少建立一個史萊克式的程式碼,而在這之前,你需要培養出對程式碼異味的感覺能力。如果你不知道好的程式碼是怎麼樣的,壞的程式碼看起來是怎麼樣的,那你怎麼會想到去改進它呢。

編寫可讀性良好的程式碼

我有一次聽Joel Spolsky說,StackExchange不是針對提出問題的人進行優化,而是對閱讀答案的人進行優化。為什麼呢?因為相較於提出問題的個人,有多得多的人會去檢視答案——應用最大化原則應該對讀者進行優化,而不是提問的人。

我覺得你可以同樣的方式對待程式碼。它可能只是由你一個人寫一次。但是它可能被其他許多人閱讀和編輯。你的程式碼具有兩個功能:其一是滿足你當前的工作,其二是面對在你之後的每一個人,因此程式碼應該始終對可讀性和可理解性進行優化。

“程式碼編寫一年後,從原作者眼光來說,也是全新的程式碼 — Peter Nixey



你程式碼裡面假定什麼?你的方法實際返回什麼?這個四層巢狀的 if/else if and not/unless 宣告究竟是在區分什麼?

有時候你需要的不僅是好的變數名,你也要圍繞著程式碼進行測試,看它究竟需要什麼,並使得程式碼經久耐用。有效的程式碼是可以工作的程式碼,並且始終工作,即使被公司裡每一個人都改過,都還能如常執行。

寫的每一行程式碼,其讀者會是那些對此不感興趣的,或者時間緊迫的團隊成員,他們可能要在接下來一年時間擴充套件這些程式碼。請記住,那個不感興趣,或時間緊迫的人,或許就是你自己。

根據程式碼的生命週期來評估特性價值,而不是它的實現成本。

新的開發者總是喜歡探索和發揮。他們喜歡最新最炫的東西。無論是Nosql資料庫,還是高併發的移動服務,他們想盡快了解和掌握所有這些東西,用完這些玩具,就撇下一堆垃圾給下一個開發人員來擦屁股。

狗不是為聖誕節準備的,特性也不是為下一個釋出版本準備的。— Peter Nixey (@peternixey) April 22, 2014

功能和架構的選擇,會影響所有你在這之上構建的東西。一旦抽象洩露,你在抽象中陷得越深,就有越多的東西會被玷汙,或者這個洩露導致很多東西都“中毒”。

實驗性的架構和某些很炫的特性應該極為謹慎採用。優先新增你需要的功能,而不是你想要的功能。同時請注重架構。把一些實驗玩具留給邊緣專案。你建立的每一個元件,每一個前沿模組合併到你的專案,會快速地改變你的軟體,也會讓你的專案受傷或直接破壞專案。如果你不希望在專案後期除了止血而幹不了其他事情,請不要首先將上述應用到你的專案中。

瞭解和評估技術債務

技術債務是你寫的程式碼但沒有達到最優化或你想要的。它包含一些錯誤,雖然煩人,不過還是可以用的。它可能是一個單應用程式,不過你知道它可能發展為面向服務的程式,也可能是一個20分鐘的計劃任務需要被重構為20秒。

這些成本不僅僅是累加的,而且是複合累加。愛因斯坦曾經說過:宇宙中沒有什麼比複利更強大的力量了。同樣,在大型軟體開發中,也沒有什麼比複合技術債務更具破壞性的了。我們見過或構建的大部分專案,哪怕最小的改變也會花費數月的時間。針對碼基(codebase),人們已經放棄了編寫更好程式碼的想法,只是希望在修改的時候不至於導致站點整個崩潰。

技術債務是專案中一個可怕的負擔。

除非沒有技術債務。

和所有其他債務一樣,應用合理的話,技術債務也會給你帶來巨大的槓桿效應。— Peter Nixey (@peternixey) April 22, 2014

不僅是這樣,技術債務可能是世界上最好的債務,因為你不一定每次都需要償還。當你開發一個功能結果發現它是錯誤的,或者當你開發一個產品結果不能正常工作,你可以丟棄掉它們然後繼續。你可能丟棄功能相關的所有優化,測試和重構。因為這些不是必須的,那就不要去寫這些。這個時候就應該最大化你的槓桿,留個空白,避免錯誤,僅僅為你需要的測試而進行測試。

在一個產品和功能的早期,很可能你現在做的是錯誤的。你還處在探索階段。你要同時以產品和技術實現為核心。這期間可以大量借用技術債務。這不是修改零星錯誤和進行大量重構的時候,這時候你應該集中火力猛攻直到你達到(成果的)另一邊。

不過當你發現,你確信你已經到了正確的位置並走出了另外一邊,這個時候需要進行梳理,並加強你的地位。把事情做得足夠好來推動你前進,償還足夠的技術債務來進入下一個階段。

對於初創公司來說,技術債務和其他許多事情一樣是一場跨越式的遊戲。初始的程式碼是試探性的程式碼,它應該讓你快速前進,發現問題和解決方案,給你恰當的空間來建立營地。你呆的時間越久,營地系統就需要更多內容,而你需要構建更大更強來支撐它。如果你僅僅只需要停留一週時間,不要浪費時間來構建一個可以支援十年的基礎設施。


檢查,再檢查你的程式碼,你的問題由你來修復。

“把程式碼扔過籬笆”的工程師都是可怕的工程師。你應該保證你的程式碼是可以工作的,這不是測試人員或者你同事的工作,這是你的工作。懶洋洋寫就的程式碼會拖延你,延遲週期時間,產生bug,有讓每個人惱火。


如果你一直提交破壞性的程式碼,那麼你就在對團隊其他成員不斷徵稅。— Peter Nixey (@peternixey) April 22, 2014

不要拿自己不當回事,覺得你只是個負擔,問題應該自己解決。

每天至少(只)花4個小時做實際工作

對於討論自我進步,關注和使用在開發者之間流行的生活技巧,簡單的真理是:你不需要做大量的工作,就可以實現高效。真正重要的是,你能持續地做到這一點。每天花費最少完整4個小時來做恰當(proper)的事情,日復一日,你會成為團隊中最有貢獻力的成員。

不過,每天都抽出4個小時來工作比看起來要難得多。

恰當的工作意味著沒有郵件,沒有新聞,沒有會議,沒有雜七雜八的瑣事。意味著一小時最少45分種的時間專注於(你正在做的事情)。一天4小時的工作意味著一天沒有會議,沒有漫長的午餐和休息時間討論足球。我相信,一天紮實工作八小時幾乎是不可能的。每天四小時也意味著你應該瞄準工作五或者六個小時,這樣你才可能得到四小時的認真工作時間。

這也意味著你可以擁有豐滿人生的同時,成為團隊中一個卓有成效的貢獻者。這意味著你不需要在HN上發表一個自我放棄“我忙死了,快來幫幫我”的帖子,這意味著你只要持續工作,你就能被重視和獲得尊重。

軟體團隊並不因為人們每天工作四小時而比工作七小時的團隊進展慢(持續這樣的方式是非常瘋狂的)。他們慢下來是因為人們幾周都沒有找到方向,或者那些響亮而空乏的嗓子,決定花費時間討論google vs facebook 的獲取策略而導致的無止境的咖啡休息時間。

只要能工作就好,不要在乎你的進步看起來是如何緩慢或平庸…

每天工作四個小時,日復一日你會成為團隊中最優秀的人員之一。— Peter Nixey (@peternixey)April 22, 2014

記錄已完成的事情,並和團隊成員分享

不管你是如何記錄文件,是通過類似Copyin的郵件列表,wiki 或者是程式碼中的內嵌註釋,你應該花時間來解釋你的架構方法,和團隊其他成員一起學習。

在安裝Postgres或者ImageMagic時遇到了問題?如果你覺得這解決起來比較困難,團隊的其他成員可能也會遇到這樣的困難,花費一些時間記錄下來並告訴團隊其他人你是如何做到的,節約他們下一次遇到問題時的時間。

程式開發時最糟糕的事情是,整天和bug作戰或者處理安裝問題。如果你花費時間來記錄和分享你找到的方法,你可以從預先為你同事準備中贏得五倍你花費的這些時間。

理解和欣賞處理太多測試和太少測試之間的微妙平衡

測試是一個強大的工具。它允許你設定一個釋出基準,你可以信賴你的釋出,讓你不那麼害怕製造它們。對釋出的恐懼越少,你越這樣做你改進得就越快。

不過,這也可能過頭。測試需要時間編寫,執行和更多的時間來維護。

可以想象測試是盔甲,你穿得越多你受傷的可能性就越小,不過也讓你更難進攻。— Peter Nixey(@peternixey) April 22, 2014

你負重太多而無法前進,阻礙你彎曲四肢,無法移動。太少的話,第一次跨過混凝土地板的滑動就會傷到你,讓你流血。


關於如何進行適量的測試,沒有直觀的答案,某些專案需要比其他專案更多的測試,測試是你專業化需要學習的一個全新的領域。

花時間去理解什麼是真正需要測試,如何編寫一個良好的測試。花時間去檢視當測試新增值,或者最起碼你期望它們是怎麼樣的。不要害怕進行測試,也不要害怕不進行測試。正確的處理方式是平衡,花時間去探索平衡點在哪裡。

讓你的團隊更出色

這不同於其他點,這不是你可以獨自採取行動,也沒有明確的指標告知你其他行動是否有效。

你的存在,是讓你的團隊變得更好還是更糟呢?你的程式碼質量,你的文件和你的技術有米有幫助到你周圍的人。你是否激勵和鼓勵你的隊友成為一個更優秀的開發者?或者你就是那個導致bug的人,或者你堅持自己的觀點浪費數小時討論架構無關的廢話,因為它有助於掩飾你沒有做實際工作的事實?

你應該讓你的團隊變得更好,總是有一兩種方法你可以讓你的團隊變得更好,通過你素養的薰陶而幫助其他人變得更強。然而,成為一個孤獨的“智者”可能是最缺乏價值的,或者說你能選擇的最有破壞價值。事實上,如果你選擇的維度並沒有讓你覺得厭煩,這可能不是一個好的選擇。

It’s not who you are on the inside that defines you

這是一個謙卑的智慧,在蝙蝠俠開篇就有這麼一句,這句也一直伴隨著我。在電影的某個時間,蝙蝠俠在閒逛,表演著一個億萬富翁的花花公子。克里斯蒂安·貝爾懇求凱蒂·赫爾姆斯相信:他內在仍然是一個好人,她只是說了:不是你穿了什麼,而是你做了什麼展現你的價值。

你作為一個開發者的貢獻,不是由你有多聰明或你知道多少來衡量的。這不是由你簡歷上的技術名稱縮寫,你工作的公司和你上過的大學決定的。它們暗示你能做什麼,但是你的價值是由你做過什麼,以及這些如何改變了專案和你周圍的人決定的。
如果你想變得更好,請做好準備。

本文由 伯樂線上 - 周昌鴻   翻譯自 Peter Nixey
來自:伯樂線上
相關閱讀
評論(0)

相關文章