當前位置: 華文星空 > 知識

那些編程水平很高的程式設計師是怎麽訓練出來的?

2019-10-19知識

如果你問「很高」的話……

那麽答案很簡單:那是對你從小到大整個教育歷程中每個知識點真正掌握與否的一次總檢驗。

要看破這一點,我們首先需要弄明白「程式」究竟是什麽。

原理很簡單:電腦是一種能夠在一秒鐘內做出數十億道算術題的器材;程式設計師可以透過與或非三種邏輯判斷影響電腦的做題順序,這種順序可歸結為順序、分支、迴圈三種。

程式設計師的工作,就是抽取萬事萬物的數學骨架,把一切一切都歸結到一大堆數學題上;然後讓電腦透過計算這些題目,在「數學空間」把我們想要的任何東西模擬出來。

有很多東西需要根據情況隨機應變,這個「隨機應變」就對應於「分支」——情況A這樣處理,情況B那樣處理,這就是分支。

有很多東西是對海量實體套同一個模子,這個「套模子」就對應於「迴圈」——反復用同一段程式碼對排著隊的不同實體做同一套操作,這就是迴圈。

圖靈證明,只要有這麽個支持,一切可抽象為計算的過程都可以用功能極其有限的一台機器執行。這種機器被稱為「圖靈機」。

當我們在「數學空間」把任務處理完之後,我們還需要操縱「外設」,比如顯視器印表機音箱等等,把結果展示出來——這同樣需要先做一套數學變換,然後透過IO口輸出訊號,就好像扳動了無形的「操縱桿」一樣,控制各種外設和人類完成互動。

所謂「程式」,就是程式設計師們預先安排好的一堆指令;當電腦執行這些指令時,你需要的音樂軟件、記事本、ppt等等,就先在數碼安排好一切、然後再透過鍵盤滑鼠顯視器等等外設和你互動。

被儲存在某處的那組指令就是程式;程式每次被CPU執行,就叫一個「行程」。

明白了這個,那麽我們就知道了:

1、程式設計師需要抽取任何現實需求的數學骨架(或者說,理解一切需求內部的數學規律)

2、程式設計師需要把數學骨架轉譯成電腦可以理解的指令

3、程式設計師需要用指令控制外設,把虛無縹緲的「使用者介面」實實在在展示在使用者面前、或者控制機器完成各種動作

其中的2、3屬於基本技能,做不到就吃不了程式設計師這碗飯;但這個技能的上限也非常非常高,高到優秀程式設計師的工作效率可以輕易超過庸手十倍以上的程度。

為什麽會有這麽大差別呢?

差距主要就在1上。

優秀程式設計師深刻理解了電腦原理,因此從思路到實作毫無窒礙。

優秀程式設計師規劃能力極強,可以把很復雜的工作安排的井井有條、有能力把它分成很多簡單單元逐一解決。

優秀程式設計師理解力極佳,可以透徹理解使用者需求,透徹理解萬事萬物內部隱藏著的數學規律——因此,他們不僅知道自己要做什麽、怎樣做、為什麽,還可以觸類旁通,化一切規律為我所用。

當庸手出苦力一行行碼程式碼時,高手早已洞悉了其中的秘密,於是用自行設計的一套演算法讓電腦自己尋找出路——甚至還可以證明這個演算法一定能以最高效率完成工作。這差距,是不是一下子就拉開了?

舉例來說,很多低階程式設計師喜歡吐槽「總是寫重復的業務程式碼」;但是另一位程式設計師是這麽做的……

他找了份報社的工作,每天的任務就是把新聞報道整理一下釋出到網站上。這顯然是個毫無前途的工作,因為你只要每天腳打後腦勺的把稿件拷貝到html頁面上就完了。毫無技術含量,只能拼體力出苦力,每天996、007,但總有海量的稿件等著你……而你,甚至都沒有權力去改變稿件中的某個錯別字!

這工作,到街上找個二傻子都幹的了吧?

這人,這輩子,完了。

但是這條鹹魚還是想掙紮下。

他發現,所有的稿件都由幾個部份構成,標題、作者、正文、參照,偶爾還有題圖/插圖。

嗯,標題得居中,用大號黑體字,不能傾斜,不能加底線;作者用5號字,同樣居中……

好嘛,盡是繁文縟節。做多了成了熟練工,一天也用不著幹別的了……

但是,等等,重復勞動不應該讓電腦做嗎?你幹嘛要自己做?你的編程學狗肚子裏了?

於是,這條鹹魚搞了個「樣版」,用{{title}}標記html中應該填標題的地方,用{{author}}標記html中應該填作者的地方……

那麽,現在他只要找個地方保存這個「標準html」,然後用程式自動從數據庫讀取文章標題、作者等內容,把{{title}}代換掉……

你看,現在這條鹹魚徹底閑了:報社的同事們只要把文章上傳數據庫,他跑一下他的批次處理——別說一天的工作,一年的工作他也能用幾秒鐘時間搞定。

畢竟他只需要敲敲鍵盤啟動程式,剩下的苦活累活全是電腦的事,不是嗎。

閑了的鹹魚開始琢磨。他把他這套樣版系統進一步擴寫、完善,然後作為開源軟件釋出。

最終,這個系統一炮打響。它就是著名的Django: https:// baike.baidu.com/item/dj ango/61531

讓我們繼續對你的驚嚇之旅 ^_^

最近有朋友考駕照,特別怕科目三的直線行駛,一走就歪。

怎麽辦呢?

我告訴他,你往遠處看,越遠越好。比如直路上你可以看遠方的地平線。

好了,問題解決。

你是不是要懵了:這都哪跟哪啊?江湖騙子吧?

放心。我還可以讓你更懵:這,可都是三角函數的基本套用啊。你初中咋學的?

抓狂不?

聽我解釋。

當你操縱的汽車和道路之間存在一個夾角時,車子自然會在行駛一段距離後和道路越分越遠;然後你著急一打方向,掛科。

那麽,正確的做法是什麽呢?

沒錯,那就是:從一開始就不要讓車子行駛方向和道路形成夾角。

問題是,人的感覺是極不精確的。你怎麽知道車子行駛方向和道路有無夾角?

所以,你只有緊盯邊線,哎呀似乎靠左邊了我打點方向……一打就多,一多就要從右邊出線。趕緊再打,哎呀,左邊又多了……車子喝醉酒一樣來回一搖,掛科。

可是,你的「傳感器」就這麽不精確啊。怎麽辦呢?

並不是開車會走直線的都是天賦異稟的神仙。

還記得初中學過的三角函數嗎?從一個頂點出發、相互存在一個很小夾角的兩條射線,會隨著距離……怎麽樣?

越分越遠。直到這個距離遠大於道路的寬度。

好,道路是一條直線,你的視線是另一條直線;而你端端正正坐在駕駛室裏,正常情況下,你的視線和車行方向平行——告訴我,往遠處看,當你發現車行方向不正時,你會發現什麽?

沒錯,人的感覺極不精確;尤其道路那麽寬,坐在車裏時哪裏看得見兩條線的交叉點?哪裏感覺得到這個角度?所以我們無法發現車行方向和道路方向存在夾角。

但往遠處看,借助距離,近處的誤差就被抹平,而視線和道路不在同一條線上時就會有明顯的偏差,於是你是不是一下子就發覺了?

很好,打點方向糾正。

你看,借助距離,我們就加強了我們的感官精確度。

類似的,做自動控制,機器人用的傳感器也沒那麽精確。怎麽辦?

很簡單,「錨定」一個遠期目標,不要硬測硬算。

如果列出誤差傳遞公式,很容易發現裏面會有個類似的項——這些項決定了若幹個周期後,誤差會放大到誇張的地步。

你要「錨」的近了,誤差就會累積,就會引起震蕩,就會造成專案失敗;「錨」的遠一點,那麽誤差的累積就很容易發現,就可以更快的回到正軌。

歸根結底,這還是能歸結到「∠A的兩條邊在距頂點R處的兩個點之間的距離」上,歸結到「兩條直線的影像」上。

只不過,當年你是死記硬背、混過考試,還是把概念徹底吃透、然後又學出來學到生活中,那麽在遇到問題時,你和別人就有了質的差距。

別以為這東西很無聊。知道當年海軍測距用的合象式測距儀嗎?當年有這玩意兒的英軍打的清政府覺得洋人會妖法!

圖片來自網絡

你,能把知識用的如此天馬行空、信手拈來嗎?

請註意,這個「信手拈來」可不是「隨口就能解釋清楚合像式測距儀」的工作原理,而是:隨便需要一個什麽樣的需求,你都應該馬上就能想到對應的數學原理、然後馬上發明一種東西來實作這個需求。

必須註意:發明可比解釋難多了。

仍以合像式測距儀為例——它恰恰正是從「專業知識」到「傻瓜式界面」的一個典型案例。

最初,你得到的需求可能是:設計一款測距儀器,要求皮實耐操、使用簡便,要求戰場上那些文化程度不高、驚慌失措的大頭兵也能本能的用對。

面對這樣一個需求,你怎樣才能讓甲方滿意呢?

僅從知識儲備上說,你需要:

深刻理解三角形測距原理,能夠反向思考——什麽測角度?什麽千分尺?大兵們有那麽鎮定、有那麽清晰的頭腦嗎?能夠在戰火紛飛的戰場上完成一道三角函數題?還必須精確到小數點後XX位?

顯然,在此之前,你必須深刻理解千分尺(螺旋測微器)工作原理,這才能把它和望遠鏡有機結合,從而直接把「擰旋鈕對準某個目標」對應到「測量」——然後旋鈕對應的讀數就是最終距離。

但要做到這點,談何容易。

你能讓大兵跑這頭擰擰鏡頭、把刻度對準船上某個定點;然後再跑那頭擰另一個鏡頭,把刻度對準另一個定點嗎?這段過程中,你自己的船轉彎了呢?風吹著走了弧線了呢?對方轉彎、看不到之前的標誌物了呢?

因此,你必須設計一個機構,使得大兵可以在一個位置同時控制兩個鏡頭、讓它們對準同一個標誌物。

然後,你還得根據兩端測到的不同角度,計算距離……

你看,這難度高出天際了吧?

而「合像」這個思路就是個天才的設計。

它的思路是,兩端兩個鏡頭聯動,使得當目標在視場中間時,測距基線的垂線恰好對準目標——於是兩個鏡頭到目標的連線再加上基線恰巧構成個等腰三角形。這就使得最終只需考慮單獨一個角就能算出距離,從而大幅降低了計算復雜度。

同時,借助「潛望鏡」原理(看到沒?又一個原理!),把基線兩端的兩個鏡頭的視野同時呈現在觀察者面前——然後又是一個天才設計:不需要你一個個鏡頭對準目標上的同一個標誌物,而是把兩個鏡頭的視場各截一半;那麽當你透過中間的目鏡,把左右兩邊鏡頭視場對應的、同一目標的上下半拉嚴絲合縫的對到一起時,你已經完成了這個「對正目標」的操作。

復雜操作就這樣被傻瓜化了。

現在,只剩最後一步:怎麽把「角度」和「距離」聯系起來。

註意這裏是利用等腰三角形的底邊長和底角角度算三角形中垂線的長度;因此調節旋鈕轉過的角度並不和垂線長度成正比。所以你不可能用擰一圈100米擰10圈1000米這種簡單機構。你需要設計一套指示機構,並做一些稍微復雜的標定——最好還能把它「塞」進視場裏去。

不過,相對於其他,這已經是簡單的體力活了。

這裏面用到了哪些知識呢?

三角形性質,三角函數;輪軸/螺旋;齒輪的嚙合;杠桿轉動角度如何與螺旋測微器聯動;平面鏡成像;凸透鏡成像(光路分析:「上下視場對齊」是怎麽和「角度測量」聯系起來的)……

還有無法直觀看到、但卻必不可少的:機械加工精度、裝配精度、溫度補償、戰艦本身各種震動的消除(補償)、潤滑、抗(海水/汗液)腐蝕……

看到了嗎?

你的幾何代數物理化學……只要有任何短板,你做的了這個嗎?

想做這個,你必須全能。

別說什麽課本沒寫老師沒講。學以致用,這就是用。這就是要你在掌握了書本知識之後、自己在實踐中推廣的。

這東西太多太雜,而且會因地制宜、以各種匪夷所思的方式利用任何原理的任何細枝末節——或者說,各種概念的內涵外延你全都必須完全掌握,不允許有任何死角。

而要做到這一點,死記硬背毫無意義;你必須自己學會悟、學會推廣——自己會走,才能想去哪就去哪。

——當然,我在這裏選了一個物理器材舉例。因為它看得見摸得著,沒有接觸過相關領域的讀者多少也能有個感性認識。

如你所見,所謂「工程師」,就是理解很多很多學科的基本原理、能夠在實踐中恰到好處利用的人。軟件工程師也不例外——如果你想要自己「優秀」的話。

拿我們熟悉、同時又總是看不起的美圖秀秀來說吧。

我們知道,美圖秀秀是個Photoshop的「抄襲品」,它做不了專業軟件,只好把專業軟件的功能拷貝下來實作個劣化版、然後主打小白市場……嗯,你看,不加掩飾的濃濃鄙夷。

不過……跟著鄙夷之前,你有沒有問過自己——美圖秀秀的原理是什麽?哪本書講過?你寫得出來嗎?

我想,如果問過自己,恐怕大多數人都不敢鄙夷了。

為什麽呢?

因為哪怕你就是學電腦圖形影像的,課本裏也沒教過你什麽叫「肌膚遮瑕」「睫毛濃黑」……

而且……這倆不恰好是相反的嗎?一個要去掉皮膚上細微的瑕疵,另一個反而要把皮膚上的黑色絲狀物凸出……

所以你還必須繼續「活用知識」。比如說,書上教過你「邊緣捕捉」,教過你「大面積著色」,教過你「模式辨識」……

你必須活用這些知識、用到你那些只會死記硬背的同學目瞪口呆的程度,再結合皮膚/美妝方面的常識,你才能在「濃黑睫毛」的同時,幫小姑娘們把臉上的黑痣自動點掉。

你看,雖說是「五毛錢特效」,可你照樣得是個「萬事通」——不然哪怕想「抄演算法」,你都不知道該抄什麽。

——Photoshop當然沒開源;但gimp可是開源的,隨便你抄。你抄的出美圖秀秀嗎?

可見,在軟件設計中,類似的東西同樣會貫穿始終,這才能把復雜繁難的專業技術對應到傻瓜都能掌握的「傻瓜界面」上去。

這就是為什麽同樣看了C程式設計教程,有的人馬上就能上手做一些奇奇怪怪的東西、而另一些人一片茫然的原因。

而這種茫然,在你工作之後,會更加的普遍、更加的具有壓迫力——當你的同事可以因地制宜信手拈來一堆解決方案之時,你不僅不知道他們「從哪學來的這些古怪知識」,甚至就連理解他們的思路都極為困難。以致於……就好像我見過的很多同事一樣:你別和我說原理!要我做什麽,你直接說!

——所以我不僅經常給電腦寫程式,我還經常給人寫程式:

要部署我這個軟件,你要:

1、安裝debian 9.10

2、登入debian,執行apt-get install sshd 安裝配置ssh服務

3、……

沒錯。沒有我寫的一二三四,很多人連安裝部署都不會;而且連debian的哪個版本都必須精確到小版本號。不然……他們可沒能力隨機應變(哪怕這個專案是跨平台設計,但你仍然必須逐個平台指定版本號寫一二三四的部署流程:給人寫程式比給電腦寫程式更麻煩,因為你不能讓他們做太多復雜判斷、不能給他們太多太復雜的步驟。因為人可能看序列,而電腦不會)。

那麽,你猜,如果你學成了這樣……還有可能進步嗎?

何況,從「提醒一下還是能回憶起學過的知識」到「勉強能明白別人的思路」再到「勉強能跟上別人的思路」再到「可以不費力的跟上別人思路」再到「能和思維跳脫的同事一起縱橫捭闔、相互補充相互促進、把一個設計真正做到完美」——這裏面,要走的路,可長的很呢。

仍以合象式測距儀舉例:我壓根沒看過它的設計圖、原理圖;以上大段文字,都是我看到「合像」二字後腦子裏一下子湧出來的。但我敢說,我畫出來的原理圖一定和實物圖相差無幾。

如果你將來能進入一個不錯的公司,你就會發現,那些優秀的同事都可以輕易做到這些。

甚至,你想了很久、絞盡腦汁想出來一個方案(很可能比這個測距儀要復雜曲折的多);結果到了會議上,你才吐露一個詞,人家馬上就能把你的整個方案徹底領會貫通、甚至還能當即提出一些直擊要害的問題來。

如果你也有這種能力的話,和這種同事的交流一定是非常輕松愉快的;和他合作,做任何事都可以很輕松:你稍微一提,他能把任何細節都考慮到,直接給你個成品出來。

而另一些同事,你苦口婆心一遍遍的給他們解釋,他們也領會不了這種明明很簡單的問題。好不容易把每個要點都提到了,他還能給你做的差三落四,甚至連最最基本的核心功能都沒做對。

而實際工作中,「編程水平」恰恰就體現在這裏:能夠長期、穩定、高效的實作某個具體功能只是個基本要求;更重要的,是能給團隊指明方向,讓他們知道怎麽走才能搶到競爭對手前面、把別人不曾做到也不知道該怎麽做的東西帶到現實。

你看,當年的每一口夾生飯,你都要在實踐中付出代價。

這些東西,會在編程實踐中成為常識——理解電腦體系結構、打通數碼世界和現實世界的藩籬,這是個很不簡單的任務,它把很多很多人攔在了編程門外;但打通了之後,你能往數碼世界搬進去什麽呢?

很顯然,你真正理解、掌握的知識越多,那麽你就越是有更多東西可以搬進數碼世界。相反,你的夾生飯越多——學了杠桿輪軸你懂不了變速箱玩不轉發動機、學了電路你不知道收音機電視機如何工作——那麽你就越是摸不著頭腦。

如前面我舉那個三角函數的例子。這東西太基礎了,以致於對很多很多人——那些真正理解了知識而不是死記硬背的人——來說,這都是本能。

但是,如果你只會做題,如果你從未圍繞著你學過的概念有過任何思考,那麽別人的每一句話,對你都是天書。

——如果我不解釋,恐怕大部份人都會覺得「看遠點就能解決開車走不了直線問題」和跳大神一樣呢。

那麽,有沒有想過,其實你我都學過的每一個知識點,別人都可能掌握到了這種程度呢?

那麽,有沒有想過,當會議上,別人在每一個話題上都如此天馬行空、讓你目不暇接時,你會是什麽體驗?

你壓根就跟不上他們的思路。

在他們看來,壓根就沒有難題,隨隨便便一個方案接一個方案就提出來了,隨隨便便就能想出特殊場景來對不同方案做出挑戰、完成取舍。

但哪怕他們掰開了揉碎了給你講,你都怎麽也轉不過彎來。

你壓根想不到自己學過的知識還能這樣用;他們則理解不了人人都學過的那麽點簡單知識,居然……只是死記硬背?!

綜上,優秀的程式設計師已經不僅僅是比拼對電腦系統本身的了解了——那只是基礎。

他們真正比拼的,是對這個世界認識的深刻程度;是因地制宜的把腦中雜七雜八的知識拿來、解決實際問題的能力。

這種東西是怎麽訓練出來的呢?

很簡單,從小就要多動腦,要真正把任何知識理解了、活用了;千萬不要透過死記硬背這類手段逃課。

人生是個馬拉松。

你在小學手工課上耗費的時間並沒有白費;你好奇的拆開玩具、擺弄鐘表收音機所付出的努力成為了你的積澱;你「不務正業」的胡思亂想、對科普對科幻的癡迷使得你更早的接觸了本質……

現在,它們終於體現出價值來了。