如何成為一名優秀的程式設計師?需要具備哪些基本的素質和能力?

程序員書屋 發佈 2020-05-10T15:16:36+00:00

我強烈建議:軟體開發者除具備應對本職工作的技術技能之外,還必須大力拓展自己的「軟技能」。事實上,關於這一點我寫了整整一本書。儘管如此,我仍然無可否認:技術技能還是至關重要的。我的意思是,如果你不會寫代碼,不能開發軟體,那麼你學到的所有的軟技能對你而言都是「屠龍之技」。

我強烈建議:軟體開發者除具備應對本職工作的技術技能之外,還必須大力拓展自己的「軟技能」。事實上,關於這一點我寫了整整一本書。儘管如此,我仍然無可否認:技術技能還是至關重要的。

我的意思是,如果你不會寫代碼,不能開發軟體,那麼你學到的所有的軟技能對你而言都是「屠龍之技」。也許你會成為一個好經理、好教練,但不會成為一名軟體開發者。

因為你正在閱讀本書的這部分內容,所以我就假設你有興趣成為一名優秀的軟體開發者,我們就來談談要在軟體開發這一行登堂入室,你需要了解的傍身之技。

安身立命的本領

現在要談論的是一個很容易令許多初級軟體開發者不知所措的話題,因為他們會覺得有太多的東西要去了解,千頭萬緒不知道從哪裡下手。

我要試著解構一下這個問題,這裡只論述能使你迅速成長成為軟體開發者的最為重要的和最有價值的技能。

本章絕不能作為軟體開發者可能需要的所有技術技能的事無巨細的詳盡清單,我只打算列出必要的內容,並在這裡逐一進行概述。

別擔心,在本書的第三篇「關於軟體開發你需要知道些什麼」中,我還將另外奉獻一章,對每一項技能我都會抽絲剝繭地深入探討。我還把這個清單壓縮成一個有用的工具——「軟體開發者技能評估」,供你免費下載。

因此,毫無疑問,下面將簡要介紹我認為最重要的技術技能。

一門程式語言

我想我們最好是從這個話題開始,不是嗎?

想成為一名程式設計師,卻連一門程式語言都不懂,那可是緣木求魚。你懂我的意思,對吧?(不明白的可參考Ernest P. Worrell[2]的系列電影,很搞笑的。)

我們將在第5章中詳細討論如何選擇一門程式語言,所以這裡不再贅述。不過,我要說的是,選擇到底該學習哪一門程式語言其實並不像你想像中那麼重要。相反,讓我們來談談,為什麼我建議從學習「一門」程式語言開始,而不是試圖學習太陽底下的每一門程式語言。

許多初學編程的人在找到軟體開發的第一份工作之前,都試圖竭盡全力學好幾門程式語言,藉此來增加自己找工作的砝碼。但我認為,雖然你最終應該學習掌握的程式語言不止一種,但是我並不建議你在前期就學習很多程式語言,因為這只會導致混亂,讓你將本應用於學習其他技術技能的精力耗散殆盡。恰恰相反,我建議你潛心鑽研一門程式語言的來龍去脈,這樣你才可以胸有成竹地宣稱:我具備用這門語言編寫代碼的能力。

還記得我們在第2章討論「你想成為哪種軟體開發者」時不厭其煩地強調你需要儘量具體、具體再具體嗎?

在這裡,道理是一模一樣的。

如何結構化代碼

在學習一門程式語言之後,甚至是正在學習這門程式語言的過程當中,你就需要了解如何正確地結構化你的代碼。這是我的堅定信仰。

我已經給你準備好了極佳的資源,以此來幫你結構化代碼這一極有價值的技能——由Steven McConnell編寫的《代碼大全》。

那麼,「結構化代碼」到底是什麼含義呢?

我的意思是:編寫優質的、整潔的、不需要太多注釋就能理解的通俗易懂的代碼,因為代碼本身是用於溝通的。

許多軟體開發者終其整個職業生涯也沒有學會這項技能,那只能用「命途多蹇」來形容他了。因為包括我在內的許多人都依此來評價一名軟體開發者的技能高低和競爭力強弱。

良好的代碼結構體現了一個人對技術的奉獻精神,而不是敷衍了事。結構化代碼實際上正是軟體開發過程中的藝術部分,同時也是關鍵部分,因為你和你的同事正是通過代碼來交流和共事的,而且你們還要曠日持久地花費大把時間維護現有代碼,而不是編寫新代碼。

我不會在本書中與你詳細討論如何正確地結構化你的代碼。因為正像我說過的,我已經給你提供了極佳的資源,但是你必須從一開始就努力學習如何寫出優質的、整潔的代碼,而不是「以後」在學這一技能。

我向你保證,即使你是一個初學者,只要你能寫出優質、整潔、簡潔、易懂的代碼來表達它的結構、它的含義,那麼任何一個看到你的代碼的面試官都會認為你是一位有經驗的專業人士。

不僅如此,從某種程度上講,你一定會成為專業人士,至少已經走在通往這個方向的路上。因為你已經把這份職業當作一門專業,而不只是一份工作,這正是真正的工匠精神的標誌。

面向對象設計

有人可能會對這一點提出質疑,特別是當你正在學的不是面向對象(OO)的程式語言時,但在軟體開發界已經有了種類繁多的面向對象的設計思想,所以你需要確保自己了解它。

面向對象設計是一種設計複雜程序的方法,它將複雜程序分解為單個的、代表特定角色與職責的類或者對象(類的實例化),其中封裝功能。

在軟體開發的世界裡,我們一直在矢志不渝地管理複雜度,以「對象」的方法來思考將有助於我們定義和設計複雜的系統,我們會把一個系統看作是一群相互作用的組件,而不是試圖從整體上處理這個複雜的組合體。

今天,函數式程式語言多種多樣,但你會發現,最流行的軟體開發語言和模式仍然在部分地或者全量地深受面向對象的設計與分析的影響。因此,你應該深刻理解什麼是類,牢固掌握不同類型的繼承關係有哪些,並且明確領會面向對象的術語,如多態、封裝。

算法和數據結構

如果你想在大學或者各類學院通過傳統的學位教育獲得計算機科學學位,你會發現這一內容是最難啃的硬骨頭。

算法是解決各種計算機科學/編程問題的常用方法。例如,有幾種常用的算法可以將事物按照規定的要求排序。根據算法的速度、內存大小和里昂的數據類型的不同,這些排序算法的性能不盡相同。

在計算機科學領域有很多這種算法,了解如何根據這些算法來編寫自己的程序以解決實際問題是非常重要的,特別是當問題非常棘手的時候。通常,精通各類算法的開發者用區區一個小時就可以解決盤亘在其他開發者手上好幾天都束手無策的問題。

如果你對各類算法做不到融會貫通,你就無法知曉其實優雅的解決方案早已比比皆是。因此,僅憑這個原因,我認為算法就是一項價值千金的技能。

數據結構也屬於類似的範疇,通常與算法一起協同工作。

所有的軟體開發者都應該熟悉下面幾種常用的數據結構,包括:

  • 數組或向量;
  • 鍊表;
  • 棧;
  • 隊列;
  • 樹;
  • 散列表;
  • 集合。

通過掌握數據結構和算法,可以輕而易舉、氣定神閒地解決許多編程難題。

剛開始學習編程時,我對數據結構和算法的知識是一頭霧水的,因為大部分內容我是自學的。我不知道它們的真正價值,直到我在一個叫作「頂級程式設計師」(TopCoder)的網站上參加競賽的時候我才發現,通曉數據結構和算法的知識會給你帶來巨大的優勢。

很快,這些技能在編程領域的現實世界中舉足輕重的作用便凸顯在我眼前,因為我遇到了一些既簡單又有趣的問題,而這些問題在我認真學習算法和數據結構之前是不知道該如何解決的。

事實上,我認為算法和數據結構是軟體開發中最有趣的領域之一。通過算法和數據結構可以事半功倍地解決難題,利用數據結構和算法可以開發出簡單、優雅的解決方案,而且效果還非常好。

截至我寫本書時,關於這方面最棒的資源還是Gayle Laakmann McDowell的名著《程式設計師面試金典》。在書中,她詳細介紹了你需要知道的算法和數據結構的所有知識。

學習這項技能是一項挑戰,但是物有所值。這是一項能令你在同行中脫穎而出的技能。因為大多數軟體開發者在這方面的技能都少得可憐。

如果想通過微軟或谷歌這樣的公司的面試,你必須掌握這項技能,勢在必行。

開發平台及其相關技術

你應該至少具備一個開發平台的相關經驗,並精通與之相關的技術或者框架。

我說的平台是什麼意思呢?一般來說,它指的是作業系統(OS),但它也可以指代其他類似於作業系統的抽象。例如,你可以是Mac開發者,也可以是Windows開發者,前者專注於Mac作業系統,後者則專注於Windows作業系統,你也可以成為專注於某個特定Web平台上的Web開發者。

在這裡我可不想陷入對某一個具體平台的論戰之中,不同的人會有不同的見解,但是為了方便當前討論,我會把一個平台看作是一個特定的環境,而你個人的職業發展將會隨著不同的環境有著不同的生態與特性。

再強調一次,與選哪一門程式語言類似,我認為你到底該選哪種平台其實無關緊要,重要的是你必須得選一種。

每家公司雇用的開發者通常都是固定於某一個特定平台或技術的。如果你擁有在iOS平台上的開發經驗,那麼你找到一份iOS開發的工作就會簡單得多。這意味著你需要熟悉平台本身,以及程式設計師在該平台上做開發時通常會使用的開發工具、慣用模式和常見框架。

你可能認為選擇哪種程式語言決定了選擇哪種平台,事實上這種情況很少發生。以C#語言為例,今天的C #開發者可以為Windows、iOS或者Android平台編寫代碼,也可以為Mac、Linux甚至是嵌入式系統開發程序。因此,不必在乎選擇哪種語言,你需要選擇的是一個平台。

框架或者棧

除學習特定的程式語言和特定的平台之外,我還強烈建議你學習一種框架,以及與該框架相關聯的完整的開發棧。

什麼是框架?什麼是棧?

框架就是一系列用於在特定平台上或跨多個平台上編寫的庫。通常,框架可以使在該平台上的一般性編程任務變得更容易。

回到剛才的C #例子。大多數C #開發者使用.NET框架編寫C #應用程式。在.NET框架中包含有大量的庫與類,這可以讓一位C#開發者工作在更高層級的抽象上,每次當他想寫做點兒什麼的時候他並不需要完全從底層開始。例如,.NET框架中含有用於圖像操控的代碼。從頭開始編寫這些代碼,無疑是非常困難的。所以框架為C#開發者帶來巨大的好處,可以讓他們不需要編寫代碼,只需要以某種方式熟練操控庫函數即可。

棧稍有所不同。棧是用於創建一個完整的應用程式所必備的一系列相關技術,通常包括一個框架。

例如,常見的MEAN棧。它是MongoDB、Express.js、AngularJS和Node.js四種技術的合稱。MongoDB是資料庫技術,Express.js是基於Node.js的用於創建Web應用程式的框架,AngularJS是用於創建Web應用程式用戶介面的前端JavaScript框架,Node.js是開發Web應用程式中的JavaScript運行環境。

是否理解上述技術無關緊要,除非你是一名MEAN棧的開發者。重要的是,你要明白,如果你對上述所有技術和框架都了解,你就可以開發出完整的Web應用程式。

棧可以讓創建應用程式變得更加簡單,因為棧提供了一種通用的范型,需多開發者都在使用它來開發應用程式,因此可以輕而易舉地做到知識共享,並且你可以確信:一組特定的技術在協同工作方面是行之有效的。

學會了某個棧時非常有價值的,因為這意味著你擁有開發完整應用程式所需的全部技能。許多公司都是使用某一個特定的棧來開發應用程式的,所以他們都在竭力網羅搜尋熟悉該棧的開發者,希望自己能夠在競爭中藉此旗開得勝。

資料庫基礎知識

儘管在過去幾年中資料庫技術發生了非常大的變化,但我並不認為資料庫很快就會消失,所以我想你應該了解一些關於資料庫的技術,你覺得呢?

在編寫本書時,現行的資料庫技術主要有兩種:關係型資料庫和文檔型資料庫。我認為,今天的開發者至少應該熟悉關係型資料庫的知識,可能也需要對文檔型資料庫有一定的了解。

在軟體開發中,資料庫通常用來存儲應用程式的數據。當然,有些軟體開發團隊有專職的資料庫開發者或者資料庫管理員(DBA),但這並不能夠成為你不去了解資料庫基礎知識的藉口。

最低限度,你需要了解以下機制:

  • 資料庫如何運行;
  • 如何執行基本的查詢語句以獲取數據;
  • 如何插入、更新與刪除數據;
  • 如何連接數據集。

此外,你可能還需要了解如何使用你所選擇的平台和/或框架來編寫程序以檢索和存儲數據。

大多數開發者都能編寫與資料庫交互的代碼。

原始碼控制

原始碼控制是任何一個軟體開發項目的必要組成部分。

遙想當年,在我們那個年代,還沒有什麼原始碼控制,我們要麼把項目的全部文件都放到網絡上共享,要麼就靠純手工來回傳遞軟體的不同版本。我很慚愧,當年的我不止一次地參與過這些令人啼笑皆非的「遊戲」。但是,當時的我還很年輕,也很蠢萌,你沒必要這麼做。

現在,幾乎所有的專業開發者都應該知道如何使用原始碼控制來簽入和簽出代碼,並且能夠合併來自多個原始碼版本的變更。

原始碼控制的最基本要求就是,在一個軟體項目中各個文檔與代碼上所有變更的歷史記錄都被完整無誤地保存下來;同時還允許多個開發者在同一時間處理同一段代碼,並將這些更改合併在一起。

這裡我們不討論原始碼控制的細節,但是你應該熟悉至少一種原始碼控制系統,並且熟悉原始碼控制的基本概念。

在當今的軟體開發界,幾乎所有的專業軟體開發團隊都會使用某種原始碼控制系統。

構建與部署

今天,大多數軟體開發項目都會應用某種自動化構建和部署系統。

這些任務過去都是手工完成的。現在,有好幾種不同的軟體應用程式可以幫助團隊自動化這兩項任務。而對有些團隊來說,這兩項工作仍然是手動的。

那麼,什麼是構建和部署呢?好問題。

你知道如何編寫代碼並將代碼簽入原始碼控制系統嗎?在完成簽入工作之後確保代碼確實有效,這可是個好主意。這就是構建系統的作用。構建系統的最基本作用就是編譯所有的原始碼,並確保不出現任何編譯錯誤。

一個複雜的構建系統還可以運行單元測試用例或用戶測試用例,執行針對代碼的質量檢查,並提供代碼庫的當前狀態報告。

部署系統將負責將代碼部署到生產環境或者測試環境中。

你不必成為這方面的技術專家,但是了解這些系統如何工作、了解構建和部署代碼的過程是非常重要的。

如今,在通常情況下,創建和維護構建與部署系統這個領域裡最熱門的話題非DevOps(Developer Operation的簡寫)莫屬。但是,這並不能構成你不了解如何運作這個過程的理由。

測試

過去,開發者不需要對測試有太多了解。我們會寫一大堆代碼,然後就像甩包袱一般把它們扔給一堆測試人員,他們會在我們的代碼中找出各種各樣的bug,我們再去修復這些bug,就是這樣。

這樣的日子一去不復返了。如今,越來越多的軟體項目都採用了所謂的敏捷過程,(下面我們會在「方法論」一節討論更多有關敏捷的話題),在敏捷過程中軟體開發者和測試人員必須更加緊密地合作。

質量已然成為整個團隊的責任——我更願意強調,其實一直都是這樣的。因此,你需要知道一些關於測試的知識。你至少應該熟悉一些基本術語,例如:

  • 白盒測試;
  • 黑盒測試;
  • 單元測試(並非真正意義上的測試);
  • 邊界條件;
  • 測試自動化;
  • 驗收測試。

一個優秀的開發者(我假設你至少想成為一個優秀的開發者)會在自己測試了自己編寫的代碼之後才將代碼交付給別人。

如果你真的想被別人視為專業人士而不僅僅是一名黑客,這一點是無可辯駁的。

調試

很多新手的軟體開發者的夢都是在調試器面前破碎的。

每個人都想寫代碼,對吧?但是沒有人想調試他們的代碼,對吧?明白我的意思了吧?以下就是見證真相的時刻。

身為軟體開發者,你90%的時間都會消耗在苦苦探究「我的代碼為什麼不能正常工作」這個問題上。我知道這一點也不刺激。我知道你幻想著每天只寫新代碼,然而真實的世界不是這樣運作的。

如果你使用的是類似「測試驅動開發」的方法,你可能會在調試器上花費比較少的時間。但是,無論如何你都必須學習如何調試自己的以及其他人的代碼,無可逃避。因此,與其對你必須做的事情採取心不在焉的態度,還不如咬緊牙關,真正學會如何卓有成效地做好調試工作。

在第32章中,我會更多地討論這個問題,現在你只需要知道調試工作的必要性和必然性。

方法論

被上面這一長串你需要知道的技能清單嚇倒了嗎?如果還沒有的話,我這裡還得再加一個,不過我保證這是最後一個。

當一個軟體開發團隊剛開始編寫代碼並努力完成工作時,大多數情況下都會使用某種至少他們會假裝遵循的方法。(在這裡順便說一下,請注意:不要期望任何一支團隊真正遵循他們聲稱的自己正在使用的軟體開發方法。在這裡,我可不想憤世嫉俗地指手畫腳,我只是一個現實主義者,而且我碰巧知道有很多人說他們正在實施某種軟體開發方法,如Scrum,因為他們每天都有一個會議,在會上每個人都要站著。)

因此,你至少要對一些最常見的軟體開發方法背後的基本思想了如指掌,這一點非常關鍵。在這裡我要著重強調瀑布式開發和敏捷開發這兩種開發方法。

大多數團隊都聲稱他們在使用敏捷方法工作。敏捷本身是一個相當鬆散的概念,但是,如果你想要談論這個話題並且融入敏捷團隊,那麼你應該知道敏捷包含一些實踐,還有一些儀式(可以這麼說)。

本文摘自剛剛上架新書《軟技能2 軟體開發者職業生涯指南》



  • 作為一名軟體開發者,我該如何起步?
  • 我該如何培養自己的技術能力?
  • 我該如何談判薪水?在合同制員工和正式職員之間我該如何選擇?
  • 我該如何跟我的老闆、同事打交道?我該如何對待職場偏見?我該如何跟技術女性打交道?我該如何成為一名技術女性?
  • 我真正需要知道什麼?又該如何學習它們?
  • 大學學歷教育、編程訓練營還有自學成才,該選哪一種?
  • 我如何找到一份工作?如果沒有經驗,我該怎麼辦?
  • 我怎樣才能通過面試?
  • 身在職場我該怎樣穿著?
  • 我怎樣才能推動自己的職業發展提升到一個新的水平?

這是一本為軟體開發者量身定做的職業發展指南,處於任何發展階段的軟體開發者,都將從本書中獲益。如果你是軟體開發/編程的初學者或者只是對軟體開發感興趣的人士,可以通過本書了解如何開啟軟體開發的職業之旅,如何獲得第一份工作;如果你是中級軟體開發者,可以通過本書發現自己的知識短板,學會如何進一步拓展和掌握新的技術技能,如何學習新的程式語言,如何提升技術水平,如何在自己夢想的編程工作中深耕細作;如果你是身經百戰的專業軟體開發者,可以通過本書了解如何拓展和推進自己的職業生涯,如何更好地與同事和老闆相處,如何推銷自己的想法,如何做好向上管理,如何升職加薪。

資深軟體開發者兼軟體開發者的人生導師約翰·森梅茲在本書中針對職場上的各項重要的「軟技能」,為軟體開發者提供專業的職業發展指導,讓軟體開發者的職業生涯更加精彩和輝煌。

本書與《軟技能:代碼之外的生存指南》既相得益彰,又各有側重——《軟技能:代碼之外的生存指南》全方位論述軟體開發者生活和工作中需要關注的各種「軟技能」,而本書則從軟體開發者職業生涯的時空關係出發,描述軟體開發者職業發展整個歷程中應具備的各種「軟技能」。

關鍵字: