什麼是編程的基本功?

在知乎搜索了半天,發現沒有相關這個主題的問答,於是乎就提問了。表述如下:一名籃球運動員,在他能力提升的過程中,有那麼一些基本功或者說基本動作需要反覆練習的,比如運球、投籃、折返跑等等,而體力、體格、耐力等等可以說是他的「內功」,那麼類比這個例子,我想知道,編程或者軟體開發中,哪些是可以被拆分出來,進行反覆訓練,從而紮實基礎的東西。注意:我知道有人可能會說是演算法、數據結構、組成原理等等這些計科系理論課程,但是我更認為這些是「內功」而非我說的基本功,所以,請問各位程序員前輩,編程提升的過程中的基本功是什麼?


就是跟所有平台、語言、領域、信仰都無關的那部分通用的知識。


我補一個現時31個答案中都沒有提到的──設計(design)。

設計並不是單指平面設計、服裝設計、工業設計、建築設計那些似乎和美學相關的事物,在編程或軟體開發上,也有軟體設計、設計模式、演算法設計、語法設計等等。

但什麼是設計?這是一個比較困難的問題。在維基百科Design條目中,引述了[1]對設計的正式定義建議:

(noun) a specification of an object, manifested by an agent, intended to accomplish goals, in a particular environment, using a set of primitive components, satisfying a set of requirements, subject to constraints;

難於理解這種長句的話,可以看看[1]中的圖:

我未讀過一些關於廣義的設計理論,但我認為這是對於編程或軟體開發中的一個重要能力。怎樣在各種局限中,找到最優而符合要求的方案,是一個漫長的思考過程。但在我接受的教育中,這可能並不受重視,似乎更多是靠自學得來。例如在中學時設計一些海報、刊物、立體裝置、遊戲設計(國內較多稱為策劃),中學時還開發過設計用的軟體(三維建模、地形設計、邏輯電路設計),近幾年做過兩個居所的室內設計(迷你新居裝修筆記、Milo的相冊-又一香港新居),最近也在嘗試機械/電子設計。

我體會到這些各式各樣的設計,和編程/軟體設計是有許多共性的:

  • 需求分析;
  • 研究各種現有的方案/技術/材料/工具;
  • 構思、編寫/繪製/製作出模型;
  • 評估設計及迭代;
  • 計算預算、分工;
  • 實現、管理進度;
  • 檢討結果,總結經驗;
  • 等等……

我覺得如果能系統地訓練設計這種能力,對於編程/軟體開發應該有很大幫助。所以除了學習GoF軟體設計模式,也可以去看一看它原來的出處 [2](中譯本《建築模式語言(上下) (豆瓣)》)。希望作為程序員,也同時可以有自信地自稱為設計師。

參考文獻

[1] Ralph, Paul, and Yair Wand. "A proposal for a formal definition of the design concept." Design requirements engineering: A ten-year perspective. Springer Berlin Heidelberg, 2009. 103-136. http://paulralph.name/wp-content/uploads/2011/01/Ralph-and-Wand-A-Proposal-for-a-Formal-Definition-of-the-Design-Concept.pdf

[2] Ishikawa, Sara, and Murray Silverstein. A pattern language: towns, buildings, construction. Vol. 2. Oxford University Press, 1977.


英語。

然後你就可以去StackOverflow上學習了。

知乎是個娛樂站點,不要問這些專業問題,你搜不出也是因為知乎搜索太爛。


自學能力


打字……

別笑,高中 oi 不少打字都不利索的


以前看到一句話,數學是程序員藍量上限,英語是程序員回藍速度。


檢索資料能力!但是別用百度!

我是認真的。

以前經常有些學生,問我這個怎麼,那個怎麼做?

然後我拿來一搜,好多講解的很詳細的教程。

【感謝那些無私的有時間學教程的同學】。

「XX同學,這個問題網路上資料很多,自己搜吧」

【註:做為未來的程序員預備,搜索資料能力是一項必須的練習,所以本人基本上不會直接提供鏈接,除非對方是美女】

「啊啊,老師,找不到啊!」

「嗯嗯,找不到正常,可能你的關鍵字沒有用對,你試試XX和YY的組合」

「好的,謝謝。」

幾分鐘後。。。。。。。。。。。

「啊啊啊啊啊啊啊啊啊啊啊啊,還是找不到啊!」

突然間,我明白了。

「你用百度的吧」

「是的!」

「恭喜恭喜,掉入了程序員的陷阱!」

「這樣吧,現在google打不開,用http://www.aol.com

看到右邊的那個標誌了嗎? google幫的,效果還是不錯的。日常用還可以。就提醒到這裡了,請叫我雷鋒」

「。。。。。。。。。。。。。。。。謝謝」


英語

因為:

1 多數開源項目的注釋都是英文;

2 多數API文檔都是用英文寫的;

3 多數優秀的技術書籍都是英文版的;

4 stackoverflow、google論壇、github等都是英文站點;

5 命令行都是英文;

6 編程的時候用英文可以避免編碼問題的煩惱;

7 未經漢化的英文版軟體用起來更爽;

8 變數命名的時候可以避免用拼音。

暫時就想到這麼多,英文真的很重要,我一直在背單詞,上quora、github和stackoverflow呢。

知識是無國界的,但前提是你要有那個能力消化它。


代數。


這個問題我願意來考慮回答一下

第一部分:什麼是基本功

先說說我所理解的基本功是什麼: 在討論,計劃,工作,策略以及其他一切相關於這個事物的活動時候,可以不用拿出來討論的「技能」,但是卻又是必須一定擁有的「技能」而這個「技能」的好壞也直接影響到你所進行活動的質量高低這個「技能」就是基本功。

而且基本功也是隨著水平的提高而變化,原來在水平低下時候所謂的技巧會在水平高的時候編程基本功。

就比如說寫小說,一般來說,用詞造句,如何開頭如何結尾可能都是小說技巧。但是這個前提是你必須會寫字,或者會打字,這個寫字和打字的技術就是基本功。當你小說水平升級了,已經寫小說的過程中,不在討論遣詞造句了,而是要選擇討論哪種哲學意義的話,那麼遣詞造句,如何開頭結尾就不再是技巧,而是基本功了。或者說在水平低的時候,如果寫個完整的故事,那個是技巧,而打字寫字是基本功;當水平高的時候,故事情節的發展是技巧,而寫個完整的故事就變成了基本功。

第二部分:什麼是編程的基本功

重複第一部分的內容:在你討論編程活動過程中,什麼東西非常必要,卻不用討論的技術,就是基本功。

1. 查詢和閱讀文檔能力

原因:你使用編程來解決問題的時候,基本上最終的東西是代碼,但是編程的知識太廣,總有你不會的,總有你不了解的,總有你記不住的。這個時候,有文檔作為資料參考,就是你快速把別人的經驗知識轉化為自己的生產力和自己的代碼。

查詢閱讀文檔是可以分成很多部分。主要是一下幾個部分

  • 教程文檔
  • 技術參考文檔
  • 第一手的英語文檔
  • 代碼例子

教程文檔,是手把手教會你如何使用這個編程技術的重要文檔之一,入門一個技術的重要教學資料,如果這個都會不看,那麼就已經喪失了自學編程技術的能力了。

技術參考文檔,一般來說API的技術文檔我們說的比較多,很多API都沒有教程給出,要自己靠查詢文檔,再根據需求特點來使用API。這個相對教程文檔枯燥。而且這個水平我認為還分幾種情況(當然有能力自己編寫一個,不靠文檔的情況不在這裡的考慮範圍之內):

(1) 知道哪個API符合需求

(2) 知道哪個API接近自己需求,但需要進行數據轉換

(3) 不知道有沒有API符合自己需求的,但能找到一個API接近自己需求的

(4) 不知道有沒有API符合自己需求的,也不知道怎麼找的。

第三第四種情況,就考驗自己閱讀文檔的能力了。

讀第一手英語資料也是很重要的。我最願意讀的文檔資料是PHP的官網和jQuery的官網。php的官網的文檔非常有意思,不但自己寫詳細的API說明,有例子,底下還有很多用戶在提供很多相關的信息和使用API的技巧。英語資料的好處是細緻,理解簡單,而且更新快,甚至你可以和寫文檔的人進行交流。

(題外話,經常給發給別人英語的文檔資料,對方卻是一句不懂英語,有沒有中文版的,把我搞的很無語)

這裡有另外一個基本功,就是英語能力。如果英語能力好,再結合英語版的教程文檔和英語版技術參考文檔,那麼這個基本功會給你的編程水平提高,是有很大的幫助的。

2. 數學

原因:編程到處都是數學的表現形式。就算你不懂數學,但當你編碼了,就是在做數學做的事情。

電腦其實就是數學的現實產物,方方面面都有著數學的元素在裡面,上面有人說了,數學是藍瓶的最大值,這點我很認同。

正是前人的努力,我們現在的編程才會如此的容易。但不代表數學現在不重要,編程就不要數學了。在編程中,處處可以看到數學的東西再裡面.如果有了數學基礎,這些東西理解起來就會更加容易。

先說說,編程基礎中的數學:

  • 函數/方法,數學就有函數概念 y=f(x),f就是函數,x就是輸入,y就是輸出。
  • 邏輯布爾值,if和while都需要有一定的邏輯判定,而數學的邏輯學在這裡很有用
  • 數學運算,這個和數學就一樣了
  • 遞歸,也有一套自己的數學法則

數學的應用的地方也就更多了:

  • 2d/3d矢量製圖繪畫
  • 加密解密演算法
  • 視頻圖片壓縮演算法
  • 文件壓縮演算法
  • 物理引擎

等等等等。

那麼學好數學有什麼好處呢:

(1)理解

比如現在流行的函數式編程,裡面的概念就是數學中的函數積分的概念,如果數學學好的話,函數式裡面的調用,運算,組合等概念會非常容易理解了

(2)轉化

把一些演算法轉化成代碼,想RSA的數學加密解密演算法,都是先有理論,讓後有人用代碼實現的。把數學演算法看懂,轉化成可以應用的電腦代碼或是API

(3)優化

一些演算法其實用數學公式就可以完成,而不需要邏輯流程。最近的有一個例子就很明顯了,我編寫了兩個比特單位轉化程序,第一次是用while和if寫成的,第二次是用數學公式寫成的,數學的優化特性裡面顯示出來了。

https://github.com/caoglish/code-problems/commit/1aaa8656b1b45fe69e7bf4cdfebc6360f21c978e#diff-182022bbc8857067401094a7f24f9076

(4)邏輯

編程中充滿了邏輯,邏輯不好就無法編程。正是由於編程中邏輯很多很重要,所以好好學習數學的邏輯運算,會對編程特別有幫助。因為可以通過運算,簡化你的邏輯條件,使得程序更高效,也可能更加容易讀懂,邏輯更加清晰。

(5) 分析

有了數學工具,可以進行數據分析,進行數據挖掘。當然也可以對代碼本身進行分析,分析其時間複雜度和空間複雜度,作為參考,進行更好的代碼優化。

3. 讀代碼

原因:讀代碼不產生任何代碼,如果不能很好的理解現有代碼,又如何改進代碼,修正錯誤呢

讀代碼是一件非常困難的事情,甚至可能比寫代碼還困難。很多人更喜歡自己重寫,也不願意去讀別人的代碼。但是實際工作中,可能更多的是維護舊代碼,也公司沒有時間和資源去支持你編寫新的代碼。而學習編程,更多的是在讀別人代碼過程中學習的。

所以在編程過程中讀懂代碼卻真的是一項非常重要,卻容易忽視的能力。

(1)讀懂自己過去的代碼

是不是有這樣的經歷,代碼放6個月後自己去讀,可能都不知道當時為啥這樣寫。最好自己慢慢調試,最終明白自己當年寫這段代碼的思路是啥了. 先讀懂自己過去的代碼,試著優化重構,提高過去代碼質量,就是提高了自己代碼能力了

(2)讀他人代碼思路

自己寫的都可能不記得思路了,那麼從頭開始看別人寫的代碼就更加困難了。

讀別人代碼,更多的是了解思考,為什麼別人那麼寫,為什麼這樣寫的好處。理清思路,畫出流程圖,可能會更好的理解他人的代碼。

(3)學習他人的優秀代碼結構

學習別人的代碼結構,看看別人如何使用數據結構,數據模式的。這樣可以轉化成自己的知識

(4)讀懂他人代碼演算法

如果別人是大牛,數學學得很好,很多數學公式,很多遞歸,如果自己沒有一定的數學基礎,可能就暈了,這個時候,數學的基本功可能就會在這裡發揮作用了。

(5)破解糾錯

如果讀懂別人代碼,發現代碼有問題,有漏洞,可以破解,可以糾錯,讓然後把漏洞通知作者,也是提高自己能力的方法之一。當然在對付自己過去的代碼時候,也會發現破綻,只有讀懂了代碼,才能進行修復或者改進。如果你是黑客,讀懂代碼,可以幫助你破解軟體和網站。

總結一下讀代碼作為基本功的作用:在實際工作中,最先做的其實就是讀代碼了,可能對別人遺留下來的代碼,可能是自己過去寫的代碼。在沒有充足資源和時間的時候,重寫代碼是最最不好的選擇,所以只有讀懂這些遺留代碼,才能更好的重構,優化和改進現有代碼,可以使得代碼更加安全,容易維護。

~~先想到這些,以後再想到什麼再進行補充~~


不說高大上,說點實際的

對於碼農來說,以下基本功很重要:

1.強大短時機械記憶能力,這對於你的編程速度非常有幫助

2.暴力實現需求能力,這是你的產品經理和老闆喜歡的

3.IDE,項目管理,配置工具,各種輪子妥妥的,有助於幫助公司提高整體開發速度,而且其他職位的人對協作平台不擅長,這有助於你提升人際關係


心靜,心境


推薦一位IT精英的博客,博客地址:

  • zhuweisky - 博客園

不為繁華易匠心

做技術是需要匠心的。什麼是匠心?我們原本是有匠心的,我們如今還有匠心嗎?我們為什麼沒有匠心了?為什麼我們要重拾匠心?如何重拾匠心?

一. 做技術是需要匠心的

中國古時的玉匠,切磋琢磨,用繩與砂漿,費數十載心力,終將渾然璞玉製成傳世珍品,千年遺音在,猶見當年寂寞心。

日本傳統的刀匠,將千錘百鍊之鋼反覆鍛鑿、淬火、打造、磨製,每一處技至精微,每一處心入幽明——刀中有魂!

歐洲中世紀的石匠,在哥特式教堂的飛檐上雕刻出了靈獸狀噴水嘴,雖不為世人所見,仍一絲不苟——每一鑿中都有天堂!

米蓋朗基羅花四年雕刻出了震驚世人的《大衛》,曹雪芹批閱十載創作出了藝術巔峰的《紅樓》——任何偉大的作品背後都有一顆匠心。

二. 什麼是匠心?

匠心是對於作品而言的。

匠心是傾注於作品之中的精神、情感、乃至魂魄。

匠心發自於愛,是對作品視如己出的拳拳之心,是恆久忍耐又有恩慈。

匠心是出於這份愛的對於完美的追求,是追求中不避艱苦,是追求中自得其樂。

匠心是涵泳在作品之中的自我實現,是我與作品的相互完成,彼此造就。

在匠心看來,作品是我的至親之物,棲居著我的精神,安放著我的靈魂。

匠心即是愛心 + 恆心 + 一片苦心 + 七竅玲瓏心 + 出離心 + 寂寞心 + 金剛心 + 歡喜心 + 其人雖已歿,千載有餘情。

三.我們原本是有匠心的

我們原本是有匠心的。

當年Ken Thompson 和 Dennis M.Ritchie 一起在貝爾實驗室里苦心孤詣。

如今,沒有人不知道Unix意味著什麼,C意味著什麼。

他們的匠心也彰顯在Unix和C中令無數人為之驚嘆、感懷。

四.我們如今還有匠心嗎?

如今,我們再也難得見到「作品」問世。

甚至於「產品」也是少見。見得最多的則是「商品」。

對於我們而言,做什麼東西並不重要,重要的是做這個掙不掙錢。於是我們沖著掙錢做了各種項目,C/S、B/S、前端、後端、資料庫、Java、.Net、安卓——彷彿無所不知,無所不曉,十年之後回首,覺得自己已然是全才。

我們從事了大量的勞動,寫了幾十萬行代碼。我們的工資越來越高,並為此沾沾自喜。

可是,這樣的成就,無非是一個熟練工人的成就。

我們何曾擁有匠心?

五.我們為什麼沒有匠心了?

隨著大生產時代的到來,那種田園詩般的男耕女織、帶月荷鋤歸的工作方式,早已一去不復返。社會分工越來越細碎化,我們面對的是一個又一個的局部。在這之中需要的是規格化、標準化、量化和同質化。換言之,你所做的工作必須是合乎統一規範的,具有統一規格的單元,如此才能拼接到整體的工作中。因此,任何的創造性,任何私人性質的感情和精神的注入,歸根到底,只是錯誤的根源。 ——我們於何處安放匠心?

如今,商品成為了一切物所具有的普遍的形式。沒有什麼不是商品。商品是以交換為目的的。我們生產任何勞務、產品、或服務,都是為了交換,為了換取一般等價物,即貨幣,即金錢。因此,錢成為了衡量一切的準繩。如今不乏偉大的商品誕生,可是偉大的作品卻乏善可陳。商品需要的是批量生產,需要對消費者投其所好,當然商品也需要創意,可是那不是匠心!在一個由商品拜物教統治的時代,我們於何處安放匠心?

世界如此繁華,匠心未免太奢侈了!我們在喧嘩與騷動中度日,有太多的追求,太多的比較,太多的你追我趕,太多的惶惶終日。每天有看不完的新聞,刷不完的微博,做不完的手頭工作。我們為無盡的事情發愁,疲於奔命。匠心未免太奢侈了!早在我們出生的那一刻,我們就開始照著大家來活,大家都在讀書,大家都在考學,大家都在找工作,大家都在結婚,大家都在買房,大家都在炒股,當我們跟著大家忙忙碌碌的時候,匠心自始就已沉淪!

六.為什麼我們要重拾匠心?

假使我們沒有匠心,我們將不會在工作中獲得真正的快樂。因為我們不能自覺自由地工作,我們的工作是boss定義的,而不是自己定義的。如此一來,我們就與我們的勞動之間切斷了血肉聯繫。我們的勞動成為了壓迫我們、奴役我們的異己力量。我們淪為被迫勞動。我們真正的生活在下班之後開始。我們不停地抱怨:要不是為了幾個臭錢,我才不要干這些。如何才能回歸到那種田園詩般的勞作之中——我們必須重拾匠心!

唯有在擁有匠心之後,我們才能走向真正的自我實現。馬斯洛將人的最高層次的需求定義為自我實現。一個自我實現的人,一個將自己的才能發揮到最大限度的人,才是那個獲得最大心理滿足的人。現實生活中唯有少數精英才能夠成為自我實現人。但是這並不妨礙我們追求自我實現。一個有著庸碌之心的人,是不可能走向自我實現的。唯有重拾匠心,我們才能佔有工作的全部意義,才能不避艱苦、精益求精,與自己的作品相互完成,彼此造就。

七.如何重拾匠心?

對於如何重拾匠心的問題,恐怕要留給每一個人來思考。而且是一個需要始終思考的問題。

在這裡我並不想給出答案。

只希望能在這篇文章中能夠看見你,看見我,看見大家。

能見眾生便是如來,不易匠心方得始終。

參考閱讀:

程序員的出路之一

——————————————————————————————————


理解力,想像力,精力,英文。


代碼能力。就是給你一個需求,你能快速的分析,然後快速用代碼實現的能力。這是要經過一定時間的積澱才能夠獲得的能力。

學習能力。你現在會得再多,都會有過時的一天,只有不斷的學習才能與時俱進。作為一名程序員沒有強大的學習能力的話,真是一件悲哀的事。


1) 英語

2) 搜索引擎使用能力

3) 推理和邏輯

4) 抽象和建模


抽象能力,也就是理科思維,決定是否牛。

交流能力,包括語言的理解和表達能力,決定扭曲世界的力量大小。

學習能力,資料收集和管理與整合,決定適應變化的生存能力大小。


本來想說組成原理/數據結構和演算法/os/編譯原理等之類,但樓主都說了,這是內功,不是基本功。好吧,我覺得應該就是英語+數學+邏輯思辨能力+興趣。對編程沒興趣的編程狗飄過。(逃。。。


成就感挺重要的


盲打


推薦閱讀:

新手想玩硬體,買單片機還是樹莓派好呢?會一點點c?
如何理解「程序=演算法+數據結構」這句話?
上海交通大學 ACM 的 Dreadnought 隊伍怎麼這麼強?
編程是什麼?如何從零開始學習?
如何快速地在每個函數入口處加入相同的語句?

TAG:編程 | 計算機 | 軟體工程 | 練習 | 基本功 |