程式設計:思考?打字?思考!打字!

馮 欣偉發表於2013-06-30

“如果你思慮不周,你也許會認為程式設計只是一行一行把程式碼語句敲進電腦裡。”——Ward Cunningham 在《程式設計師修煉之道:從小工到專家》中的序言提到。

軟體開發包含很多需要深入思考的內容,諸如設計、解決問題、找出最佳演算法,學習新語言,重構混亂的程式碼,使其變得整潔而優雅等等。

當你嘗試去做一件你從沒做甚至從來沒有人做過的事;或者你以前做過,但毫無疑問不想再犯類似的錯誤,而需要去思考一個更好的方法;或者你嘗試去理解其他人寫的程式碼以便修改;或者你正在查詢一個討厭的BUG。所有這些都會佔用大量的時間,但最終並不會產生很多程式碼。

同時軟體開發中也有許多需要大量打字而不需要過多思考的工作。比如當你很清楚需要做什麼並且如何做時,但是在工作完成之前,你需要編寫大量的程式碼,因為你之前做過類似的東西,所以僅僅需要再做一遍,用另一種指令碼,適應另一種螢幕,另一種報告,另一種除了思考之外的所有東西;或者工作中大部分需要思考的工作已經有人為你做好了,他給你提供了程式線框圖,精確向你描述這個程式看起來的樣子,給人的感覺以及資料的流動,或者提供了詳細的API說明,所以,你要做的事僅僅是把這些思考的結果敲進螢幕同時確保不要犯太多錯誤。

除錯程式是思考型工作(Debugging is thinking)。而修復BUG、使其通過測試、釋出主要是輸入型工作。早期的設計和開發,決定使用的技術並設計框架,是艱難的思考型工作,而基於此開發三個、四個或100個的適應螢幕或報告的程式是輸入型工作。使用者體驗和原型設計是思考型的工作,而將其實現(包括CRUD、適應不同螢幕的配置)卻是輸入型工作。找到一個酷的移動應用點子是思考型工作,而實現它卻是輸入型工作。解決一般的業務問題需要大量的編碼,而通過軟體優化業務流程去需要大量艱難的思考。

所以,思考型工作的人和輸入型工作的人做著不同的工作,並且需要用不同的方式管理。

 

有時候程式設計就是在打字輸入

“我們首先是打字員,然後才是程式設計師。”——Jeff Atwood, Programming Horror

許多業務程式本質上是很膚淺的。大量的資料庫表和檔案充斥著大量的元素和資料,大量的增刪改查頁面、報表相互之間有許多的相似之處;大量的整合工作把不同屬性的不同點對映統一,從而使其滿足約束並在操作上獨立對待。功能需求上冗長的列表,通過一大堆的問題確保每個人都理解需求,許多細節描述用來備忘和追蹤。銀行、保險、政府、會記、財務報表和賬單、庫存管理和ERP系統、CRM系統,企業內部應用、簿記系統、記錄系統等等都是如此。許多線上門戶和商店也一樣。一些維護型工作,如平臺升級、系統整合和移植、稅收變化等也是如此。

你是在建造一幢房子、一座橋、一個百貨商場,或是改造其中之一。大專案經常不斷滋生各種問題,通常要花費大量時間去解決。很多輸入型工作需要做,但是其中有一部分之前已經做過很多次了,那些工作涉及類似的問題,所以你可以應用熟悉的模式、被證明可靠的工具和工作方法。

“我昨天看了你電腦程式的原始碼,它看起來很簡單;只是打了很多字,其中一半還拼寫錯誤。還有,別再讓我抱怨你那過渡使用的冒號了。” —— 《The Pointy Haired Boss sees some actual code

一旦設計確定,絕大部分工作都被充分理解並考慮了所有的細節,剩下的就是管理和協調程式設計師去把這是程式碼敲出來。這是一種經典的專案管理流程:預算、計劃、跟蹤成本和調整、管理計劃。這是關於邏輯、規模、一致性和效率的問題,確保工作在正確的軌道上執行。

 

思考!思考!思考!

其他的問題,比如設計一個遊戲引擎、交易演算法、物流或線上風險管理系統、優化一個實時控制系統,這些工作需要的思考都大於輸入編碼。這些系統有著高標準、非技術性需求(可擴充套件性、實時效能、可靠性、資料完整性和正確性)和複雜的邏輯,但是他們集中在解決一系列緊密結合的問題。只有很少一部分聰明的程式設計師可以思考那些問題並實現。當然,編碼工作仍然需要去做,特別是“外圍”部分,框架、管道、佈線方式等,但是核心的部分通常只有非常少量的程式碼,尤其是在拋棄失敗的試驗和原型之後。

這就是軟體的奧祕所在,有版權或專利的演算法和設計的洞察力是一個成功系統的核心。這種工作需要花費大量的時間去研究、需要無數次的設計原型、需要解決問題的能力,要麼需要過硬的技術,要麼需要深刻的領域知識,又或者要求二者兼備。

 

編碼輸入和思考是不同種類的工作

工作的性質以編碼為主,還是以思考為主,影響著你的團隊需要的人員數量和型別。這會改變人們之間如何合作,以及你如何取管理團隊。編碼可以被外包,但思考不行。你需要認識到哪些問題可以通過編碼解決,而哪些不行,以及什麼時候思考型工作轉變為編碼輸入型工作。

思考型工作可以也應該交給一個小而精的專家團隊,或者乾脆託付給一個天才。在思考設計或思考複雜問題、反覆試驗的階段,你不需要太多的人。做這種工作的人需要完全沉浸其中,在這段時間裡,他們會開展探索性研究,也可能會犯錯誤,他們會學習,在遇到困難時,也許僅僅會盯著螢幕發呆(其實是在思考啦^_^)。

這個階段極其重要,因為在此所犯的錯誤通常都是致命的(終結專案或職業生涯級別的錯誤)。比如選擇了錯誤的技術平臺;假設了錯誤的實時系統的可容忍延遲;花費大量的時間去尋找(或者根本找不到)高可靠性的方案;挑選了錯誤的人員或者嘗試去解決錯誤的問題;使專案失去了節奏。

管理此類工作需要尋找最優秀的人才,確保他們有正確的資訊和工具,讓他們專注,同時要觀察外界的風險,以確保他們不被打擾。

思考型的工作是不可預知的。不存在“複製貼上”的方法,因為你根本不知道從哪“複製和貼上”。你不可能估計此類工作,因為你根本不知道有多少事務是你所不知道的。但是你可以設定一個時間限制,嘗試尋找規定時間內的最佳方案。

編碼輸入型工作是可預知的。你可以同時也不得不去估計這類工作。訣竅在於把所有需要編碼的工作的列出來,併為工作中所有可能遇到的錯誤和變化做出估計。它們通常會隨著專案的進行而快速增加,諸如程式設計師的粗心大意、錯誤理解了需求、遺漏了測試、簡單的“複製貼上”,這些都會導致現在和將來的成本增加。

編碼輸入是一種工人式的工作。雖然一些高階開發者在他們厭煩前可以媲美一個大團隊的工作,但是你不需要專家,那些理解所用語言和工具的基本原則、細心並且願意服從指示、耐心的人都可以勝任此類工作。管理一群“打字員”需要不同的方式和技巧:你需要嘗試變成一個政客、一個外交家、一個後勤人員、一個標準制定者、一個管理員、一個經濟學家的角色。你是在管理專案和人員的風險,而非技術。

一段時間後,一旦大部分“我們不確定我們需要且如何去做”的艱難工作被解決了、一旦未知的事務被逐漸掌握,思考型工作就轉變為了輸入型工作,這時候就需要去填補細節並使流程跑通。

當系統的使用者增加,不得不去處理更多的介面、地點、本地化、電子郵件、摘要、支援和承諾時,你就需要開展更多的輸入型工作。系統保持增長,但是大部分的問題都是熟悉且可解決的。有大量的程式碼可供查詢、學習和複製。你需要的是能夠從中挑選所需和打字快的程式設計師。

 

思考和編碼/輸入

思考和編碼都是軟體開發的重要組成部分。

在《程式設計不僅僅是打字》一文中。Brendan Enrick解釋了結對程式設計有用的原因:這可以讓兩個程式設計師同時各自專注在思考和編碼兩個方面。

“兩個人都在思考,但思考的內容不同。一個開發者擁有鍵盤,並且沉浸其中(這種開發者需要一定的打字速度),他依照當前的程式碼邏輯進行編碼而不是整個應用的結構。一段時間後,他編碼的速度就會提高。

在結對程式設計中不實際編碼的人把所有的時間都專注在思考上。他的腦子中具有編碼者工作的清晰流程,但並不關心實際程式語言的語法,實際的編碼者才需要關心語法。這種在編碼者身後坐著的人,更像是一位嚮導,他必須確保工作進展在正確的道路上,並使用最有效的方式去實現它。”

成為一位優秀的開發者比單純的編碼輸入更出色,而成為一位得力的編碼輸入者也比簡單的敲擊鍵盤更優秀。這意味你必須有很好的基礎:掌握足夠的程式語言特性,知道用什麼工具以及如何使用,要會讀程式碼,當然也要知道如何寫程式碼(同時要寫得快);學會控制你的工具、知道使用哪種編碼更快,這樣你就更加靈活,這些都是接替一個開發者所必須的。最後,不要低估編碼輸入的重要性,也不要讓那些本該是輸入型的工作變成思考型的工作。

相關文章