怎麼看待數學和編程的關係?


我不是大牛,甚至在大學因為是讀認知科學,缺乏較多正規的大學數學訓練。

在我的職業生涯中,基本上逃不過數學。計算機圖形學需要很多不同種類的數學,主要是線性代數和數值方法(方程求解、微積分)。就算是數學不好,很多問題可以蠻力用數值方法解決。例如要求一個函數在某點的導數,可以用差分(finite difference)。

但這種蠻力可能會有缺點,例如性能不佳、不精確、不穩定。如果數學好一點,可能我們可以直接找到導數的分析解。例如有一次我需要用到Perlin noise的導數,為了改善差分的問題,就嘗試找出分析解,後來其他人也問到相同的問題,就記錄下來了:3D Perlin noise analytical derivative。

許多時候,我們需要計算一些函數的值,例如最簡單的f:mathbb{R} 
ightarrow mathbb{R}形式。如果這些函數是由超越函數(如sin、exp)所組成的連續函數,可能用Taylor series展開及一些數值方法能找出更快的近似式。

我的體會是,有時數學不好也能完成一些編程工作,但有可能限制了工作的品質。如果數學更好一些,可以把一些問題分析得更透徹,寫出更快、更精確、更穩定的計算代碼。所以近年我也在自修一些數學科目,希望能對工作有幫助。不要懼怕數學,它有時候可以成為你的朋友,迎接更多挑戰。


今天在回答清華的差生以後有何出路?時, @楊碩 留言:其實我能寫出這篇回答,跟吳軍老師的數學之美和浪潮之巔都很有關係,這兩本書對我影響非常大。

楊碩的這篇回答,看起來題目不同,但其實回答的都是一個問題:數學思維會給編程帶來怎樣的幫助?推薦:高中數學(理科思維)不是特別特別好,未來能做成優秀程序員嗎? - 楊碩的回答

楊碩在回答中按照自己的理解,對代碼工作進行了概念性分類,分為:

1結構性的工作/2效率性的工作/3邏輯性的工作/4模擬性的工作/5物理性的工作,並分別介紹了各類代碼工作所涉及到的數學知識,以及相關學科知識。由此,他有了如下體悟:

(摘錄)

我們高中學的數學,以及大學一年級學的微積分,其實都不是數學的本質,而是數學工具。數學的本質是建立一套嚴密的體系來描述世界,揭示世界本身的嚴格表示形式

==當我在學習了機器人運動學之後,再回頭去看代數與幾何,就明白了人們為什麼要建立種種複雜的代數結構並且去分析他們的性質。

==在學習了概率機器人理論以後,再回頭去看概率和統計,就明白了期望和方差這些不知道是確定還是不確定的玩意到底有什麼用。

我感覺其實學習大部分的數學知識都不存在有沒有天賦這樣一個說法,目前好的數學教材非常多,而且都把知識解釋得非常清楚,這本書看不懂了完全可以換一本再看。任何智力正常的人,在系統的訓練和合理的時間投入之後,都可以學會數學系本科涵蓋的一切數學知識。

學習數學的關鍵在於有沒有興趣去欣賞它抽象的美,以及是不是願意投入時間。 一開始我是不太會欣賞數學的,我高中數學很差,高考數學只有100多幾分。大學一開始學微積分也學得很差。但是我在大二大三期間寫機器人程序的時候發現了代數的重要性,學會了欣賞數學,於是就能學好數學了

我家有個知名程序員:一個小程序輕鬆換回一輛寶馬 他讀高中和大學時,數學特別好,打雙升心算速度奇快,圍棋下得好。現在他在做什麼呢(以下截圖來自他的微博):

對,他從2004年開始研究數字電視,慢慢從做軟體轉到做晶元。這個過程無疑是艱辛的,但得益於他的數學基礎(為了做晶元,他需要讀大量的數學paper),他硬是把這個興趣堅持到了現在,晃眼十年過去了。會怎樣?我不大在乎,只知道他選擇走的是比較困難的路,沒什麼好擔心的,他向來如此。

編程、做軟體,是工程的一種。所以題主的這個問題,也屬於討論數學和工程的關係範疇。我爸爸是搞數學的,這個話題在我們家經常拿出來說。他是擅長運用數學協助解決工程應用問題的。

下面這個系列,作者是 @田淵棟 博士(卡耐基梅隆大學機器人系博士,Facebook人工智慧組研究員)數學的用處(一)///數學的用處(二)///數學的用處(三)///數學的用處(四)

另推薦他的:在谷歌無人車組的工作感想

有人就會問了,大部分高級抽象和我們平時的工作沒啥關聯,有必要學習它們么?答案是:確實沒有必要(笑)。數學家們把這種抽象過程當作遊戲,自得其樂地在那裡不停地發文章;而我們工科生要解決實際問題,要以最小的代價命中問題的要害,只取所需要的部分就行。雖然如此,但是——

學會這樣一種自下而上的,多級抽象的思考方式,個人認為是數學帶給我們的最重要財富

有效率的思維,是像一束激光,在合適的時候聚焦於問題關鍵點,而忽略細節;等解決完了,再重新分析,迅速切換到下一個關鍵點,幾個關鍵點一解決,綱舉而目張,問題自然解決。而關鍵點如何選擇,大節如何把握,細節如何忽略,就是需要不停磨練的藝術。每次細節複雜,邏輯關係混亂的時候,不是拼耐心把它們全都解決,而是移開目光,朝天仰望,想一想其中有什麼最重要的成分,把他們抽出來反覆理解,按照重要和次要排序,最終理順關係,再開始動手。

上面摘錄 @田淵棟 博士的這段話,與上面 @Milo Yip講的——

我的體會是,有時數學不好也能完成一些編程工作,但有可能限制了工作的品質。如果數學更好一些,可以把一些問題分析得更透徹,寫出更快、更精確、更穩定的計算代碼

講的是類似的道理。

或可參考:

計算機系的高數,離散,線代都是用在哪些方面的?

在了解工業化的過程中,得到「產學研」三個字,奉為經典。  

  就像「貪嗔痴戒定慧」六個字,奉為了解人性和自身的好東西。   

  吳軍的浪潮之巔(第2版)將「產學研「討論的非常好。   

  IT新。日新月異。   

IT跟數學近。數學是IT的母系,又是核心的方法。

數學之美

美在有用,這是對學生講的

美在抽象,這是對工程界講的。抽象是以不變應萬變。抽象是把握本質

  美在簡潔,這是對學術界講的。   

  這本書以數學為引,對青年人教導了IT中的產學研。   

  對年輕人構建世界觀,規劃學習成長路線很有幫助。   

  吳軍的位置和視野都很好。這兩本書都很經典且重要。這本書應該在大學生大一結束後儘快看明白。

  這本書也能讓學生更形象的認識《人月神話》里的外科手術式團隊。


小時候數學很好,大學畢業去做工程師,現在自己開公司。說兩個小故事。

上月底,推動公司產品改進,將一些原本等額本息的項目梳理為先息後本模式。提出想法後,發現大伙兒始終算不清楚。於是自己花一個晚上把這個資產證券化模型做了出來,就是現在的「L計劃」。過程中差點要去學Matlab,後來沒用Matlab也搞定了。

小時候簡單的數字計算基本上都心算,這個習慣保持到現在。往往在朋友們打開計算器輸入數字過程中,我直接就把結果報出來。這也帶給我一個好處:在交流中聽到一些行業內的數字,可以迅速把這些數字做各種計算得出一個初步結論。

如果我認準要做一件事,我會去找各種資料、工具、方法來學到需要技能——即便我是一個數學白痴。

所以,如果你在將來工作生涯中發現遇到一些障礙,需要一些數學的積累才能邁過去,那就去學習、補課。而不要雙手一攤說哎呀我的數學還給老師了因為我是學渣我還要自學C/C++/JAVA不能兼得……這是借口。


當年的我跟題主很像,現在在做工程師,不是碼農。

客觀的說,本科出來的程序員做的工作,還是很少用到高等數學的。在我幾年的工作中,好像就只在計算機圖形學裡用一點線性代數的東西,還有我自己做過兩次曲線擬合。相比之下初等數學和數據結構、操作系統、計算機網路這些專業基礎課更「實用」。

開始意識到數學不夠用是發現做物理模擬時,離散的運算是有累計誤差的,然後就學了學數值積分。當用到數學的時候,才會感覺到知識儲備不足。今年買了本高等數學的書開始重新學習。

既然工作中用不到,什麼時候用到呢?

一是我喜歡物理,讀了一些科普書後越發的覺得不學數學就沒法真正體會到那些物理髮現的精妙。比如我們都知道海森堡測不準原理,不看數學就很難理解為什麼測不準,實驗儀器不夠精確還是測量方法有弊端?其實是數學上的測不準,無論怎麼換儀器改進方法都沒用。

二是和同事聊天的時候。和優秀的工程師一起工作,話題多是計算理論,數學,物理,哲學等。別人討論一個概率問題你插不上嘴,別人說計算的極限你不理解背後的數學原理,這時候就捉急了。

三是數學會改變一個人的思維方式,好吧,我是學渣,這一條講不出什麼,但我相信大神們會同意。

總之,數學帶給人的快樂不像編程那麼強烈,但更綿長。我覺得題主跟我一樣,是個實用主義者,雖然敬畏數學,但在不知道它有什麼用的時候就是沒有興趣。那把我買的那本書推薦給你把,叫《數學橋》,再推薦你看看matrix67大神的博客(書和博客的鏈接自己google下,我手機打字就不代勞了),多些對數學的了解,不一定多懂,但要在需要的時候能夠找到方向。


數學的作用在兩點:(1) 訓練抽象能力;(2) 實用性。先說抽象能力。寫代碼是非常需要抽象能力的,這個抽象能力可以在數學中進行訓練,尤其是代數學習。那些概念是一個比一個抽象啊,通過數學學習,可以輕鬆的看到一個個問題的實質。實用性:在編程的很多領域中,數學是必不可缺的,圖形圖像語音視頻機器學習等等等等。說的現實一點吧,以過去一年做的項目為例,用不到數學的代碼,平均下來大約一行代碼兩三塊錢,用到數學的代碼,平均下來一行代碼在100元左右。


你跟我讀大學時基本一模一樣。

作為對比,說個我寢室個數學隨手滿分的牛人。

我20w的時候他30w,我40w的時候他開始創業,現在他第一個遊戲已經發行了,我覺得發達指日可待。


打基礎的時候你跑去學編程了,以後你還要花時間撿回來,何必呢?我大學就是太急於求成了,分分鐘就想學會謀生的手段,真的是因小失大。工作後又抽時間補基礎,事倍功半。


如果數學不好很多時候你會不知道一個看起來很難的問題其實在數學裡已經有人研究過/解決了。。。

嗯哼。。。


————王垠


看了這個問題,我特別想以我自己的經歷作為反例,我大一的時候和你一樣,奔波於一些技術團隊研究編程,沒有認真去學過數學,到目前為止,各科數學都不高,而自己已經步入大三,基本已經沒有數學方面的課,我卻需要經常去惡補自己曾經犯下的錯,繼續學數學,我大一的時候也很幼稚,也在知乎上提問過類似的問題,當時非常的迷茫,但是現在對於大一時候應該做的事,想的比較明白了,題主如果是學計算機方向的,那麼數學真的是非常重要的,未來的路很長,先不說什麼工程和科研,把基礎打好後面去做什麼都會容易很多。數學就是基礎。

我不能說的很絕對,成為大牛數學一定要好,可能有的大牛數學並不是很出色,但是數學好會很大程度幫助你以後的路。

我因為大一大二沒有好好學數學,在實驗室里接觸到了機器學習數據挖掘這種東西,大二暑假去一家公司做了視覺圖像處理演算法實習生,發現當時在抱怨的數學課怎麼那麼多的自己真是太傻了,工作的過程中感覺自己的數學完全不夠用啊有木有!現在我只能慢慢去學自己當年輕視的數學,只能在看人家paper的時候不懂了,去慢慢翻書重補,目前自己對於那種數學的敏感度很低。但是你如果認真學了數學,可能將來看paper的時候會很容易想到一些創新性的東西。

我覺得你大一既然喜歡編程就做好兩件事已經很不錯了,一,打好編程基本功,可以去嘗試做一些小項目,或者多去oj上刷刷演算法題,參加下ACM競賽;二,就是學好數學,學好數學,我覺得可以這樣看待,未必一定要拿到高分,當然,你學好了應該不會低,但是你要做到的是不要為了應付考試,刷分去學,而是真正理解了一些東西,甚至是深層次方面,為了刷分應付考試的東西往往忘得很快,但如果用心去學了,你會記得很清楚,在你以後無論從事科研還是工程,都會有很大幫助,理解一些東西會很快。這是我對於大學學習數學重要性的理解,希望能與題主共勉。


我覺得你是不是太著急了。。。


十年前在國外遊戲公司出差,因遇到三維遊戲底層代碼,每行代碼都認識但就是不明白內在邏輯,特意讓同事寄線形代數過去,並惡補高數中空間解析幾何章節。現在辦公桌上還擺著這些書。當聽到同事因大學離家遠而把書處理掉了很覺不可思議。


別的領域我不太清楚,但是對於quant或者廣大偏數學方向的碼農而言,數學和編程就是「念能力」和「具現化系物體」關係(自動腦補獵人里的酷拉皮卡),或者內功和招式的關係。

不舉例子是說不清的:

比如,一個年華的收益率,跟貼現率有如下關係:

R[0,t] =-ln(P[0,t])/t

但是問題來了,在t接近零點的時候,我們知道債券價格趨近1,這個變成了一個0/0性極限,我們相求他必須使用洛必達法則:

R[0,t]= -frac{frac{partial P[0,t]}{partial t} }{P[0,t]}

現在有一個需求,如果這個價格要求表現為一個多項式,這個多項式的自變數要求根據不同債券因子進行改變。上面這個會變成什麼東西?他寫出來會變成什麼樣子?

對於這個理解上和實現上有雙重困難的東西,必須要一些數學的原理輔助以編程的實現才能完成了。在泛函分析里,上面那個「導數」,其實是個線性微分運算元。 我們需要求出一個「函數到導函數的映射」然後把多項式(具體函數)帶進去來實現。泛函分析在這裡給了我可以這麼做的理論依據,然後我會用一些「類矩陣化」的寫法來實現它:

For i = 1 To Nperiod_Plot
Cells(2 + i, "c").Value = discount_curve_Plot(i, 1)
"evaluing the rest of opreater
With Application
If clean_MJplot(i) &< 0.5 Then dt_operator(3) = 2 * clean_MJplot(i) For j = 1 To 4 dt_operator(j + 3) = .Max(2 * (clean_MJplot(i) - knot(j)) ^ 2, 0) "MAX Next j "now calculate the vector"s derivative with derivative opreater d_P = .MMult(dt_operator, .Transpose(beta_new)) Cells(2 + i, "b").Value = d_P(1) / discount_curve_Plot(i, 1) Else Cells(2 + i, "b").Value = -Log(discount_curve_Plot(i, 1)) / clean_MJplot(i) End If End With Next i

另一個例子,在蒙特卡洛法里,程序員完全可以使用並行運算,強制提高計算量來獲得更精確的結果。這當然是可行的(就是樓上朋友所謂的「蠻力」),但是其實實際上使用了平方倍的運算換取了常數倍的精度(因為誤差收斂的速度是樣本的根號倍frac{X-mu}{sqrt{s/n} }  sim N(0,1)),效率上是低下的。於是人們發明了特殊的方差縮減技術,來從數學上消除誤差側面提高計算效率。

再舉一個編程反幫數學的例子,求期權隱含波動率的時候我需要用現有市場價格對模型參數進行校準,但是模型不止一個,同時函數也不止一個。用計算機的數學說,這些功能之間的層級比較複雜。為了實現這些,我分別寫了一個抽象期權類,若干個具體期權模型類,還有一套函數的牛頓法模板。抽象類和具體類的繼承關係良好的描述多個模型之間的特性;而函數模板到類的引用構造造了一個可以直接調用不不同期權模型的泛型函數:

template&double SolverNRT(Function* function,
double Target, double guess, double acc)
{
double x1 = guess;
double x2 = x1 - (function-&>F(x1) - Target) / function-&>dF(x1);
while (abs(x1 - x2) &> acc)
{
x1 = x2;
x2 = x1 - (function-&>F(x1) - Target) / function-&>dF(x1);
}
return x2;
}

這些大大減少了我的開發時間和函數的利用效率。

上面這些例子可以看出在某些領域裡,數學和編程是相輔相成的。 假如有一個數學魔王,空有一身魔力但苦於不能再現實世界中施展,被束之理論的高閣。計算機就成為了那個在一定尺度上(離散的空間)幫助魔王施展法術的器;又假如有一個計算機劍士,空有一身計算能力但缺乏催化劑只能像個戰士一樣蠻力橫砍,數學就成了能劍士劍上的附魔,給予劍士四兩千斤,彈指核彈的能力。


關鍵是學習數學思想,而不是具體公式。具體公式再牛的人也不會完全記住,但是牛人分分鐘就可以把從基本公式出發推出來!


可以說,個人感覺數學是非常的重要,不管怎麼樣,你專業課可以差,gpa可以低,但是,你的數學能力不能差,一定要在本科階段好好把自己的數學能力夯實好,這樣,今後不管是繼續讀書還是工作,你都不會感覺自己的「腿」比別人短。


思維方式和核心思路一定要理解清楚,細節肯定會忘記的


數學對於大多數程序員來說不是核心競爭力,但不是說你可以忘記的乾乾淨淨!

13年曾經做過開發測試的面試,為了降低對測試人員的編碼能力的要求我只是問最簡單的代碼題目。比如給3個邊長判斷能否成為三角形,給3個二維坐標判斷第三個點是否在前兩個點所在的線段上?

結果有人說不知道怎麼判斷能否組成三角形,有人問前兩個點不在一條線上怎麼辦?

這種就是完全沒有共同語言了!


微積分,複變函數什麼的思想記得概念記得思路記得,感覺自己不知道怎麼湊的時候就用Wolfram alpha求解就是了。線性代數概率統計泛函圖論必須記得,因為常用啊!目前做鐵路工業上的輔助軟體,數學需求還是有一些的。

哦對了,有一個東西叫做數理邏輯,如果想做出嚴密的計算系統的話,這個必須明白啊。涉及到健壯性的開發經常採用形式化方法基本是依賴這個。


學渣路過

工作中我是指哪打哪,需要什麼知識,惡補什麼知識。我是普通人 @趙劼(參照老趙另外那個關於年薪百萬的回答)


我不是大牛。

我初三學的微積分,現在高三還沒忘。要知道,高中常規的課程里根本不會涉及這些東西……你在大學裡接觸這些的機會當然更多,說實話,如果理解到它了很難忘掉的。即使是做CS,以後用到的數學肯定也特別多,更別說工程師了。數學不好,幹什麼都不行,何況還是大學低年級的課程……這些都學不好怎麼行……

自學和學校學的東西並不矛盾,如果你已提前自學了以後的內容,站在一個更高的觀點,看現在學的東西,你就會覺得太簡單了。


推薦閱讀:

在互聯網公司,是產品更重要還是運營重要?
如何看待李昕澤說三四十歲的人不懂互聯網?
c++,不熟悉網路編程,不會腳本,可以投BAT什麼崗位?
如何看待今日頭條最新估值達到 110 億美元?
什麼是能源互聯網?

TAG:互聯網 | 程序員 | 編程 | 職業規劃 | 個人發展 |