成為高效程式設計師的7個重要習慣

發表於2013-07-10

作為軟體工程師,你希望從工作中獲得的是:穩定的薪水、參與好專案的機會、好工作的跳板或只是和其他程式設計師成為好基友。這裡的“高效”,我指的是按時完符合要求的專案的能力。經歷過不少軟體編寫工作後,我相信以下實踐會幫助你學會“高效”,同時提高專業聲望、拉長職業壽命,和獲得個人滿足

1. 理解你的需求

成為高效程式設計師的第一步是,保證時間的合理分配。沒有什麼比將時間花在完全沒有前途的工作上更浪費的了。

儘快開工

儘快完成一個直觀的系統。這意味著先建立介面,無論是程式介面還是使用者介面,然後生成內部功能的存根程式碼(如果有必要的話)。這麼做便於“客戶”檢視,通過執行使用者介面或編寫程式介面的程式碼,可以發現最初程式碼存在的矛盾或遺漏。甚至在第一次交付以前,你有可能會注意到問題或可改進的地方。

有一個經典觀念認為,如果你提前設計好所有東西,那麼之後你要做的就只剩寫程式碼了。如果你之前做過完全相同的專案,那麼這個說法當然正確。但如果不是,你很可能會陷入死角,也就是你只是在猜想或執行一個可疑的假設。

很早以前在一家無線網路的新公司工作時,我們開了兩個月的會來設計一個將在6個月內釋出的無線門戶和閘道器。最終,我們厭煩了開會,開始編寫程式碼。頭兩週內,我負責的部分與原始設計不符,兩個月後的第一個無線連線測試表明,我完全誤解了無線協議。

這不是說設計是沒必要的。但在一定程度上,設計只是一種猜想。設計應該通實執行來確認,並且早執行總是比晚執行好。

即使原始設計是充分的,只要你發現可以調整的地方,你就要改進它。硬體產品、建築和大型軟體專案等會受到僵死的“預製”的損害,但對於軟體,你可以在專案早期提煉專案要求,然後製作適合的介面。但是,這必須儘早完成。

儘早開工有利於樹立你的職業形象。如果能向你的老闆展示一些成果,他會很高興的。另一方面,提早開工有助於緩解焦慮。

經常交付

一旦你完成一些可用的東西了,不要只是把它留作“概念實證”。要讓其他人試執行它、看看他們的反應,然後讓它指導開發過程的優先次序。觀察人們如何使用你的軟體,這是無可代替的方法。客戶問卷調查和焦點研究可能會提供一些有用的意見,但有可能會讓開發者的設計決定和特點被客戶牽著鼻子走,這是一種冒險。

特別是要儘快將軟體交付QA人員,經常提交成果,最好是按預定的時間間隔。讓他們測試每天的成果,或至少是每週的成果也是好的。這會讓QA人員覺得自己全程參與專案開發,從而培養職業責任感,更樂意發現和報告問題。最需要優先解決的是導致產品失效的問題,如崩潰或死迴圈——讓問題儘可能涵蓋多方面,熟悉整個產品,這樣才有可能提早發現設計問題。

在一個小型3D軟體公司,我負責移植從SGI出品的龍頭產品到Windows NT。6個月後,移植沒完成,倒有了崩潰的傾向,我很不情願地將第一輪成果交付測試團隊。幸運的是,因為漏洞太多,QA經理堅持要我立刻解決導致測試人員無法有意義地使用程式的問題。如果是我自己測試,我應該會忙於看起來更困難更重要的核心3D問題,可能會怠慢看來起比較普通的問題,如使用者介面、載入-儲存功能和與計劃支援的硬體之間的相容性。

程式設計師常常不想過早將程式碼交付測試人員——他們不想聽到自己已經知道的漏洞;而測試人員極有可能不想測試基本上行不通的東西。但測試人員的工作就是找到這些問題。如果程式設計師想盡快看到成果的話,應該把漏洞報告當成好東西。

2. 把工作當真

將軟體放在儘可能接近完工的狀態下執行。你永遠不知道你什麼時候得演示系統、傳送評估備份或甚至交付。

使用真實資料

如果你只用作為著冰山一角的樣本資料作測試,那麼,你的程式可能一撞上真實資料的大冰山就沉了。

我曾參與開發一種用於評估先進的半導體絕對值的供應鏈管理產品。跨過交付這道大坎後,我們接到訊息說他們輸入的第一批真實資料仍然在處理中——已經兩天了。我同情主程式設計師,他不得不在管理人員和客戶的催促之下忙活了兩週。很高興遇上這事的人不是我。

使用正式版本

記住,用你自己的機器建立的東西不是正式的。

在最近的一個遊戲開發專案中,我負責使用者介面,我陸續從QA那接到報告說有些顏色不對。最後,我發現問題只出現在交付版本中,另一位程式設計師使用專門的主機除錯工具找到了漏洞。結果竟是一個我在兩個月前犯下的愚蠢錯誤,沒有指定初始顏色值。除錯版本總是選擇特定的預設值,但是交付版本會更改,最終結果是不太確定的。如果我注意經常地執行交付版本,我會立刻發現問題的,而不是損失大量的時間。

經常合併

及時將你的程式碼併入主程式碼庫中——你拖得越久,這項工作就越累。

我曾與一名程式設計師共事,他覺得每天資料庫中出現的所有新程式碼和資料變化都“很麻煩”。確實,這讓所有其他程式設計師每天都要花一定時間合併,他才能夠只掃視一下程式碼和資料就開始執行一些不錯的獨立樣本。但每一次階段性交付時,我們都要花好幾天再次把單獨的程式碼接到當前的程式碼庫中,有時候甚至得拖延交付或冒著損失整個專案的風險。

將你的程式碼與正式版本分開意味著程式設計師不能評估你的程式碼,以及測試員不能儘早發現漏洞。可能你並不想其他人挑剔你的程式碼,但早發現問題總是比晚發現好的——所以,忍了罷。

3. 理解你的程式碼

生活中充滿了奇妙的神祕,但你的程式碼可不適合出現這些神祕。你不必知道你的車怎麼工作的——如果引擎發出奇怪的聲音,把它交給汽車技師就好了。但換成是你的程式碼,如果連你都不知道它是怎麼執行的或出了什麼錯,那就沒人知道了。

有自己的編寫風格

我童年時的鋼琴教師是這麼評價我和我姐姐哥哥的:“你姐姐的時間感強,你哥哥的鍵盤打得不錯。”然後他停頓了一下說:“你嘛,嗯,你很努力。”

程式設計是一種有些人能做有些人不能做的事,但還有一些人則是天才。雖然我有過多年的練習,鋼琴還是彈不好;雖然我那麼喜歡打球,水平仍然一般般。但我確實認為我有程式設計和寫作的天賦。不要吃驚,我認為好程式就像好散文。散文和程式碼都是文字,有語法、句法、拼寫和語義。對於大多數寫程式碼的人和寫作的人,有這些就夠了,但好作家和好程式設計師還要有一種美感,他們的作品在結構和風格上是有特點的,往往能借此識別出作者。

許多Windows程式設計師都感到好奇:為什麼壞脾氣的老Unix/Mac/Amiga/Lisp程式設計師對Win32/MFC/.NET很不滿,但如果所有應用介面都來自Microsoft,你可能就不知道還有什麼東西是更好的。

複製貼上

風格化程式設計的反面是複製貼上。從什麼地方複製一些可能有用的程式碼,稍作調整,合併,重複,然後就大功告成了。你的軟體簡直就是大雜燴。

離開一家公司的幾個月後,一位前同事電郵問我,他複製貼上了十頁的程式碼組成一個演算法,為什麼執行不了。我實在不知道怎麼回答了。如果你不能解釋你自己的程式碼應該是怎麼執行的,你還指望誰來拯救你?

我甚至在診斷自己從樣本程式碼複製貼上過來的程式碼時也犯過難。從複製貼上開始新程式碼是合情理的,但你不能因為看起來能執行就放手不管了——你得返回去看看你是否讀懂了每一條,根據自己的目的理清程式碼。

清理程式碼

保持你的房子/公寓/房間整潔的最好辦法就是每天花一點時間清理它,或至少每週清理一次吧。如果等到住所亂到一定程度才打掃,那麼這麻煩就非常大了。除非你僱個清潔工。

假設你沒辦法奢侈到僱一個人每天幫你清理程式碼的程度,那麼你就應該定時地檢查你的程式碼、清理累積的死程式碼、淘汰過時的註釋和錯誤的名稱,否則你必定會得到一份不敢拿出來見人的程式碼。如果你不覺得丟不起人,好吧,你行。

我指導過的一名程式設計師總是向我報告,她的程式碼“完成”了。這是管理者樂意聽到的話,卻讓我非常抓狂。她的程式碼從來沒有做完——你得除錯它、維護它、改進它,直到它徹底沒問題。

問題?註釋?

有些人認為程式設計是一門手藝活,也有些人認為程式設計是一項工程。更經常的是,它是一門考古學。你挖掘程式碼的沉積物,想知道這些奇怪的人工產品是用來幹什麼的。為後來人著想一下,留點線索吧。

我問之前提到的那位程式設計師“完成”註釋了沒有。結果是,一個函式名稱為“GetData”的註釋居然是“Gets data”。這不只是廢話——簡直是侮辱。什麼資料?什麼格式?來自哪裡?更不要提像伺服器不可用或傳送中斷時會怎麼樣這種小細節了。

將你的程式碼做成文件,以防有人隨時要拿來用。可能要用的人就是你本人——想想如果不這麼做,你得重新訪問程式碼多少次啊?

與之前的一個老闆合作時,他叫我瀏覽一段沒人有時間看的程式碼。一開始,我認為它很糟,不知道寫的都是什麼東西。之後我慢慢摸索出來這段程式碼是幹什麼的,所以我勉強同意它不算太糟。最後我終於認出這貨竟是我兩年以前寫的。教訓:多留點註釋。

當你寫程式碼時,記得註釋,而不是等著出現什麼方便的清理短語——註釋你的程式碼,讓它甚至可以清楚地反映你在編寫時的想法。你可以成為自己的編寫夥伴。

現在你可以用javadoc和doxygen等生成漂亮的HTML或來自原始碼註釋的其他格式化的檔案。理想的情況是,你每天晚上做的就是doc生成的部分,可以通過你的內聯網獲得。

注意警告

無視編輯器和執行時間警告會害到你自己。有“警告”就有原因。

我曾做過一個基於Unix的應用,它不能成功地連線某些函式。我們通過在執行時再次連線這些函式解決問題。六個月後,當我們執行一個乾淨的新版本時,我們才發現原來我們關掉了能提醒我們未知連線漏洞的警告。在供應商的斥責下,我們將連線問題解決了。但結果是,原來我們只要通過重新排列庫就能連線上了。

提高編輯器的警告水平,註釋程式碼以及記錄建立和執行時間的警告資訊,最好包括解決警告的標準,這樣你就會知道是否解決問題或忽略問題。

4. 優化程式設計

帶著目的寫程式碼

複製貼上程式碼的人的另一個極端是,只是為了讓程式碼看起來更漂亮(至少對他們而言)而改變程式碼。雖然有程式設計審美感是值得讚揚的,但改變程式碼以便讓你覺得漂亮只是浪費時間(無用的冒險)。瀏覽並改變別人寫的程式碼,讓它看起來更漂亮,真是讓人生氣。

我有一個挑剔的同事,瀏覽我們的程式碼庫時將所有的附加語都刪除了。如果他只是清理了入門級員工寫的程式碼,那可能沒人會說什麼,但那些附加語是我們團隊的技術領導寫的,他可是我們公司最出色的人物之一。

不要搞破壞

“程式碼重構”現在十分流行,但程式設計師往往以為它是指程式碼清理或重新設計。這個技巧是指重新組織程式碼,同時不破壞其他東西。如果你以改進的名義破壞已經存在的功能,那麼你的意思就是:要麼你的時間比其他人的時間金貴,要麼你不破壞就不會整程式碼。

我有一個特別討人嫌的同事,他決定重新執行我們系統中的解析器,但結果讓程式碼變成其他所有人都不知道怎麼寫了。我讓他恢復原狀,之後發現程式碼能編寫了,卻不能執行了—–問他怎麼回事,他說“應你的要求”,他移除了整個解析器。真沒團隊精神。

保持程式碼執行需要一些耐心和額外的工作——你勤奮地迴歸測試你的工作,在將函式新增到新程式碼中時,你可能需要暫時留住老程式碼和介面。但對於所有與這個程式碼庫有關的人來說,這是必須做的。

找到瓶頸

人們總是談論“最佳”,但這不是一個正確的詞。我們極少將最佳作為目標——相反的,我們的目標是改進和權衡以達到足夠好的表現。

在谷歌的電話面試時,我被問到如何在一組有序的數字中搜尋某個數字。顯然,提問的人是在問二進位制搜尋法。但在現實生活中,我可能會做出“錯誤”的選擇——從頭找到尾。如果程式表現足夠好了,還花兩倍的時間寫兩倍的、必須維護和除錯的程式碼,那是毫無意義的,特別是如果那段程式碼並非程式的瓶頸(我嚴重懷疑如果那個資料是瓶頸部分,你居然還會將它線性排列)。

如果你確實需要在程式的速度或空間方面達到最佳,折騰除了瓶頸以外的其他任何部分都只是浪費時間。

5. 自我管理

你可能對你那位討厭的老闆有各種抱怨,你的抱怨可能沒錯。所以你得成為你自己的管理者。即使你的老闆人不錯,他也不會站在你背後告訴你該寫什麼、怎麼寫才會快(儘管我肯定許多老闆恨不得這麼做)。

估計時間

程式設計師不能提供有用的時間估計,這是出了名的。但我認為這是無理指責,因為管理層往往作出更差的預測,並且程式設計師的警告往往被無視(這可能是所有工程的共同災難)。但是,合理的時間估計對於按時完成專案仍然是關鍵的。

在一個商業軟體專案中,我的有些同事居然樂得忘了產品交付日期——有人問是否已經交付了,另一個人才很驚訝地發現,日子已經過去好幾天了。

更糟的也更普遍的是,程式設計師能給出的時間估計是“只需要幾天。”每次我聽到這話,或者我自己說出這話,我都感到害臊。

一家影象軟體公司的總裁想讓產品支援VRML(那時它是下一件大任務),包括我們將在兩個月內發行的產品也支援VRML。他可能想到(他是正確的)我會拒絕開始新專案,所以他問了另一個工程師,得到了他想到的回答:“只需要幾天。”兩天後,我告訴總裁,我們剛剛浪費了他和我的兩天時間,因為有兩百多個更重要的漏洞要修復,他認為我的理由算是充分。(後話:VRML沒有太成功。)

另一位程式設計師完全沒有時間估計的概念。但沒有必要完全拒絕時間的模糊屬性——畢竟只是估計,事實上你應該避免太確切。如果你是一名有經驗的工程師,你就知道你以前做類似的工作需要多長時間,如果你不是,那你就問問有經驗的人。

我有一個聰明的朋友,經常被指派去開發實驗原型,他問我:“你怎麼估計時間?”我認為這是一個反問句,但甚至純研究人員也要估計時間。有人支付他們,希望得到結果,即使它是許多演示樣本或某段時間發表的文章。

如果你確實估計不準需要多少時間,那麼你就不是做這項任務的合適人選。

有時候程式設計師不情願承諾時間是因為他們害怕保證。確實,這個世界沒那麼美好,經理會在時間上跟你討價還價,競爭對手可能用嚴苛或不切實際的安排來擠兌你,希望你失敗。在你承諾時間後,你就悲劇了,你別想得到任何你希望的結果。

我曾有個老闆問完成時間後會追問一句:“你保證?”但問他硬體條件和其他相關事宜時,他會說:“我儘量。”

我能說的只有,抓緊時間以及給出現實估計。任何讓步都應該根據實際的介於產品和資源之間的交易。要根據假設、相關事宜和資源做時間安排,找個地方寫下來,這樣以後你就不用麻煩你不太給力的記性了。

計劃進度

在決定上哪去以前,你不會跳上車的,對吧?你在開車時心裡可能就有路線了。相同地,在你開始用電腦寫以前,你應該知道你今天想完成什麼,有一些想法了。

每天都會遇到分心的事,所以你不可能總是完成你想完成的事。與那些將軟體工程團隊當作自動販賣機的人的想法相反的是,有些任務不是一天就能完成的。所以想想你到週五要完成什麼,如果你完成了,那麼週末你就可以好好過了。

6. 不斷學習

一名社團足球隊成員曾經問我,我們每天束緊防滑釘練習,你們“C語言程式設計的祕密是什麼?”如果存在這樣的祕密的話,我肯定會在晚間電視節目上宣傳如何靠房地產發財。對不起,沒有捷徑——你必須學習、練習和犯錯。你不一定得依靠團體訓練或學校教育——有許多國立的和當地的專業團體、書籍,當然還有網路。

程式設計是科學

程式設計被稱作“電腦科學”是有原因的。無需正規的電腦科學教育,任何人都可以輕易地開始程式設計(可能太容易了)。特別是,那些學過其他工程和理科的人,可以非常快地上手程式設計,然後以此謀生。但對於高效地處理重大任務,你必須知道軟體的固有功能和限制、識別前提,這樣你才不會白費力氣地做重複的工作。你不必知道所有事,但你應該至少粗略地瞭解許多領域,必要時能做一些額外的研究。

例如,建立了新檔案格式的人應該知道一些關於編輯器的事。我不是指所有程式碼生成的優化如迴圈展開,而是基本的問題和各種編輯的短語和大部分指定標記和語法的重要性。今天,大多數人會預設地使用XML,那是件好事,

但在那之前,一般是粗略地寫一些文字格式,指向一些生成的樣本文件作為檔案,之後其他寫了另一個解析器的人會補上一些在文件中閱讀的東西,但不是全部。在出了差錯的情況下,你有兩種方式推卸責任——要麼讀者不行,要麼作者太差。無論怎麼樣,更受歡迎的產品會贏。

我對3D圖象行業最不能容忍的事情之一是,過多的檔案格式不明。當我執行一個3D作品的OBJ檔案解析器時,我測試的每份匯出作品都生成明顯不同的檔案,比如空白和換行不同。與之形成對比的是,我的一個初出茅廬的同事用語法和詞法分析器設計了一個新遊戲交換格式(現在,這不再是什麼大不了的事了—-大多數新圖象檔案格式好像都是基於XML的)。

只會將簡單的指令碼和使用者介面放在一起的程式設計師和可以處理實際問題的程式設計師,如果說這二者有什麼區別的話,那就是對複雜計算的理解能力,如演算法怎麼影響問題的大小。每一位程式設計師都應該知道基本的複雜性術語和對常見問題的複雜程度有常識性認識。

我的第一份工作是計算機輔助半導體設計,涉及許多可擴充套件性的問題,包括一些NP-complete問題(非常難處理)。但是,每次看到線上性時間中不能解決的問題,和我們自誇可能意味著大部分是線性時間的“線性”演算法,有些工程師會興奮地說:“這是旅行商問題!”(旅行商問題,即TSP是一個有著重要工程背景、在圖論中的典型組合優化問題,已被證實是一個NP完全問題。也就是,如果一個旅行商不得不到幾個城市做生意,怎樣走最短的路線使他一次到達這幾個城市。)

免費啤酒、自由討論、免費軟體

好吧,其實沒有免費啤酒;但現在程式設計師過得還不錯(儘管經濟衰退和外包業惹爭議)——畢竟你需要的東西網上教程、討論組上都有,還有免費軟體可以用。你要解決的只有硬體和寬頻問題。

7. 尊重

高效軟體工程師的要求之一是,被認真對待。你必須得到你的同事和老闆的尊重,至少出於你的技術能力、對自己的工作有主導權、對他人有一定影響力。

愚蠢問題

真的,這個世界上存在許多愚蠢的問題。提出一個聰明的問題會增加別人對你的尊重,但這是一項技術活。一個揭露未解決的事的好問題會讓別人看到你深刻的內涵,你敏銳的思維。要求說明關於技術引數的問題,顯示了你閱讀和發現問題的能力。

如果你的問題沒有得到答案,可能是問題本身有誤,所以不要再重複發問了。換一種方式提問,帶上更多細節或背景。如果被提問的是你,或花時間回覆新手問題的是你,你會感謝上述考慮的。

能與技術支援人員保持良好關係,這是讓我對自己都感到驕傲的事。但我確實記得一件往事,那時我丟擲一個問題:“幾周前提出來的那個問題是怎麼回事?”你可以想象別人是多麼惱火地回答——“你說的怎麼回事是指什麼,並且,你說的是什麼問題?”

粗魯無禮是沒有回報的,特別是如果你是要求免費指導或諮詢討論組。即使你是在支援協議的保護之下發問,激怒了你的技術顧問對長期合作也會很不利。

我曾經向臭脾氣的新人們解釋為什麼他們的問題有問題或者什麼是他們從一開始就做錯了的,真是太累人了。現在,我給你快速生效的傻瓜過濾器——“我想知道的只是……”或果斷無視。

讓所有人知道你讀了檔案和谷歌搜尋了該問題。除了避免回覆必然的“RTFM”(RTFM意為:去讀該死的指導手冊。當你需要資訊或者解決問題時,在請求對方幫助之前,應該花一些時間嘗試自己去尋找需要的東西。)和“Google is your friend”,都顯示了你做足了功課,那些幫助的人不必搜尋相同的資源。如果你確實指望他們為你搜尋那些資源,那你的意思就是,你的時間比他們的金貴,你在謀殺他們的時間。

白痴答案

如果你要表現得你知道自己在說什麼,那麼你確實應該知道你到底在說什麼。工程師的交流有時候更多地是炫耀自己的知識而不是提供資訊(如果你也能這麼做,那我向你致敬)。這往往無益於求職面試,面試官其實是假借“發現你是怎麼想的”的幌子,向求職者丟擲空洞的問題。當然,如果求職者有一點自知之明的話,也可能產生出乎意料的結果。

有一位技術總監打電話面試我,要我概述C++編輯的結果堆疊框架,並且口頭答覆他。我一步一步地打草稿,每次我給他正確的答案,他都反過來要我說一個錯誤的答案,以便我們可以仔細檢查為什麼那個選擇不管用。我不知道我這麼寫是不是在彰顯我有多聰明或他有多聰明。

作為一名工程師,你不能太倚重錢財和長相——信譽才是你的資本。所以如果你犯錯了,就坦率承認吧。

我有幸與一名資深工程師共事,他從來不犯錯。當他的Java程式碼在多重處理器系統中崩潰時,原來是出現了大漏洞。當我拿程式碼指出UI程式碼不支援多執行緒執行時,他堅持說只有一個執行緒。當我列出程式碼中的7條執行緒(我能找出的)時,他同意不應該保留這麼多執行緒,並且最好修改一下。但他還是按老樣子編寫程式碼——他沒有修復任何漏洞,他只是用更多程式碼掩蓋了漏洞。

最後,一個節省時間的建議:不要糾結於愚蠢的爭論。愚蠢是會傳染的。

相關文章