程式設計師:學校教的數學知識,程式設計根本用不到!

前端啟航發表於2019-02-15

學校中所學的很多數學知識,在程式設計中用不到。

這兒是我能記得的在學校學到的數學:

初中:數,數數,算術知識,初級代數(“帶問題的小故事”)

高中:代數,幾何,高等代數,三角學,微積分先修課 (二次曲線論和極限)

大學:微積分,微分公式,線性代數,概率和統計,離散數學

程式設計師:學校教的數學知識,程式設計根本用不到!

上面那個關於高中數學課程單子上所列的,怎麼來著?

代數?是的。沒問題。你需要代數,和一些理解解析幾何的知識。那些很有用,並且在以後幾個月裡,你能學到一切你想要的,十拿九穩的。剩下的呢?我認為一個基本的介紹可能會有用,但是在這上面花整個學期或一年就顯得很荒謬了。

我現在意識到那個書單列表原是設計來準備給那些以後要當科學家和工程師的學生的。他們在高中裡所教的數學課程並不是為你的程式設計生涯做準備的,簡單的事實是,多數的程式設計工作所需要的數學知識相比其他作為工程師角色的人所需要的數學增長的更快。

即使你打算當一名科學家或者一名工程師,在你理解了什麼是數學之後-- 數學它如何而來,如何而去,為何而生,我發現這更加容易去學習和欣賞幾何學和三角學。不必去專研記住幾何上的證明和三角恆等式,雖然那確實是高中學校要求你必須去做的。

所以這樣的書單列表不再有什麼用了。學校教給我們的不是最合適的數學,並且方式也不對。

不奇怪程式設計師認為他們不再需要數學:我們學的大部分數學知識對我們的工作沒什麼大的幫助。

程式設計師:學校教的數學知識,程式設計根本用不到!

學校沒有教你的數學

程式設計師們最需要的是離散數學、概率論和線性代數,而不是微積分。

在現實中,電腦科學家經常使用的數學,跟上面所列的數學僅有很小的重疊。舉個例子,你在中學裡學的大部分數學是連續性的:也就是說,那是作為實數的數學。而對於電腦科學家來說,他們所感興趣的95%也許更多的是離散性的:比如,關於整數的數學。

我打算在以後的部落格中再談一些有關電腦科學,軟體工程,程式設計,搞些有趣的東東,和其他常常令人犯暈的訓練。我已經從Richard Gabriel的《軟體的模式》這本書中洞察到一個無關鉅細的基本框架。如果你明顯的等不下去的話,去讀吧。是本不錯的書。

到現在為止,不要讓“電腦科學家”這個詞困擾到你。它聽上去很可怕,其實數學不是電腦科學家所獨有的領域,你也能作為一個黑客自學它,並且能做的和他們一樣棒。你作為一個程式設計師的背景將會幫助你保持只關注那些有實踐性的部分。

我們用來建立計算模型的,大體上是離散數學。這是普遍的做法。如果正好今天你在看這篇部落格,從現在起你正瞭解到更多的數學,並且你會認識到那樣的普遍做法是不對的。從現在開始,你將有信心認為可以忽略這些,並以你想要的方式自學。

對程式設計師來說,最有效的離散數學的分支是概率理論。這是你在學校學完基本算術後的緊接著的課。你會問,什麼是概率理論呢?你就數啊,看有多少次出現滿堂彩?或者有多次是同花順。不管你思考什麼問題如果是以“多少種途徑...”或“有多大機率的...”,那就是離散問題。當他發生時,都轉化成“簡單”的計數。拋個硬幣看看...?毫無疑問在他們教你基本的計算用法後他們會教你概率理論。

我還儲存著大學裡的離散數學課本。可能他只佔了三分之一的課程,但是它卻涵蓋了我們幾乎每天計算機程式設計工作大部分所用到的數學。

也真是夠奇怪的,我的教授從沒告訴我數學是用來幹嗎的,或者我也從來沒有聽說過。種種原因吧。所以我也從沒有給以足夠的注意:只是考試及格然後把他們都忘光,因為我不認為她還和程式設計有啥關係,事情變化是我在大學學完一些電腦科學的課程之後,也許是25%的課程,可憐啊!我必須弄明白什麼對於自己來說是最重要的,然後再是向深度發展。

我想,如果每門數學課都花上整整一週的時間,而只是介紹讓你如何入門的話,那將非常不錯,這是最有意思的一種假設,那麼你知道了你正學習的物件是哪種怪物了。怪物,大概對每一門課都合適。

除了概率和離散數學外,還有不少其他的數學分支,可能對程式設計師相當的有用,學校通常不會教你的,除非你的輔修科目是數學,這些數目列表包括:

統計學,其中一些包括在我的離散數學課裡,她的某些訓練只限於她自身。自然也是相當重要的,但想學的話不需要什麼特別的入門。

代數和線性代數(比如:矩陣)。他們會在教完代數後立即教線性代數。這也簡單,這但相當多的領域非常有用,包括機器學習。

數理邏輯。我有相當完整的關於這門學科的書沒有讀,是 Stephen Kleene寫的,克林閉包的發明者,我所知道的還有就是Kleenex。這個就不要讀了。我發誓我已經嘗試了不下20次,卻從沒有讀完第二章。如果哪位牛掰有什麼更好的入門建議的話可以給我推薦。雖然,這明顯是非常重要的一部分。

資訊理論和柯爾莫戈洛夫複雜性理論。真不可思議,不是麼?我敢打賭沒哪個高中會教你其中任何一門課程。她們都是新興的學科。資訊理論是(相當相當相當相當難懂)關於資料壓縮,柯爾莫戈洛夫複雜性理論是(同樣非常難懂)關於演算法複雜度的。也就是說,你要把它壓縮的儘量小,你所要花費的時間也就變的越長,同樣的,程式或資料結構要變得多優雅也有同樣的代價。

他們都很有趣,也很有用。

當然,也有其他的一些因素,某些領域是重複的。也拿來說說吧:你所發現有用的那部分數學,不同於那些你在學校裡認為有用的數學。

那微積分呢?每個人都學它,所以它也一定是重要的,不對嗎?

好吧,微積分實際上是相當容易的。在我學習它之前,它聽上去好像是世界上最難的一件事,好像和量子力學差不多。量子力學對我來說真的不是那麼容易理解,但是微積分卻不是。在我意識到程式設計師能夠快速的學習數學時,我拿起一些微積分課本用一個月通讀了整本書,一個晚上讀一小時。

微積分都是關於連續統的 -- 變化的比率,曲線的面積,立體的體積。是些有用的東西,但是實際細節卻包含大量的記憶量並且枯燥,作為一個程式設計師來說根本不需要這些。更好的方法是從整體上了解那些概念和技術,在必要的時候再去查詢那些細節。

幾何,三角,微分,積分,圓錐曲線,微分方程,和他們的多維和多元 -- 這些都有重要的應用。不過這時候不需要你去了解它們。這大概不是個好注意讓你年復一年的去做證明和它們的練習題,不是嗎?如果你打算花大量的時間去學習數學,那也是和你生活相關的部分。

程式設計師:學校教的數學知識,程式設計根本用不到!

學習數學的正確方法

正確學習數學的方法是廣度優先,而非深度優先。你要考察的是整個數學世界,學習每個概念的名字,區分出什麼是什麼。

具體的來看,考慮用長除法?如果你能在紙上做長整除,現在就舉起你的手,會有人舉手嗎?至少我不這麼認為。

回頭看看在學校裡學過的長除法,要是不讓你覺得煩惱和憤怒才怪。當然,這是顯然的,但你不一定要自己親自去做,因為很容易用計算器來做,即使你不幸在一座沒有電力的荒無人煙的小島上。你起碼還有個計算器,在的手錶上,補牙的什麼東東,或其他什麼上面。

為什麼他們還教你這些呢?為什麼我們感到含混心虛訥,如果我們不能記住怎樣去做?這不是好像我們需要再次知道她。除此以外,如果你命懸一線,你可以運用任意大的數來做長除法。相象你被囚禁在第三世界的地牢裡,那兒的獨裁者是不會放你出來的,除非你計算出 219308862/103503391。你會怎麼做呢?好吧,很容易。你開始從分子減去分母,直到不能再減只剩餘數為止。若實在有壓力,你可以想個辦法,繼續使用反覆減,估算作為十進位制的餘數(這種情況下,0.1185678219,Emacs M-x calc 告訴我的。夠精確了!)

你或許明白,除法就是反覆的減。這樣從直覺上對除法概念的理解就根深蒂固啦!

學習數學的正確方法是忽略實際的演算法和證明,對於大部分情況來說,他們的名字,他們的作用,他們計算的大致步驟, (有時是)誰發明了他們,發明了多久了,他們的缺陷是什麼,和他們相關的有什麼。把數學當文科來學。

為什麼呢?因為第一步反應在數學上的是問題的確定。如果你有一個問題去解決,並且假設你沒有頭緒如何開始,這將花費你很長的時間來弄明白。但如果你知道這是個變異的問題,或者是一個凸優化問題,或者一個布林的邏輯問題,然後你起碼能知道從哪著手開始尋找解決方案。

現在有許許多多的數學技術和整個的學科分支。如果你不知道組合邏輯是什麼,甚至連聽都沒聽說過,那麼你是不可能意識到在組合邏輯中可以找到的解決答案的問題的,難道不是麼?

但那實在是個大新聞,因為閱讀這些領域,學習實際演算法,建模和計算結果的方法,記住這些名字都是容易的。在學校裡他們教你鏈式法則,你也能回憶起他們並能運用在考試題上,但有多少學生能真正的瞭解他們到底意味著什麼呢?所以當他們遇到變種的鏈式問題時,他們就不懂得如何運用公式了。讓人感到諷刺的是,瞭解這是什麼比記住如何運用公式更為容易,鏈式法則僅僅是如何對鏈式函式求導的意思,函式 f() 引用函式 g() ,你要求導 f(g()),好了,程式設計師知道所有這些函式相關的;我們每天都使用他們,所以現在比過去在學校更加容易能夠想象到問題所在。

這就是為什麼我認為他們以錯誤的方式在教數學。對大多數高中畢業生來說,他們專門教授的內容,不是可以靠經驗來證明數學是如何如何有用的,他們教的那些恰恰是非經驗式的內容。在你學習如何求導和做積分之前,你將要學習如何計數,怎樣程式設計。

我認為學習數學最好的方法是每天花15到30分鐘逛維基百科。那上面有數千數學分支的相關文章。可以從一些你感興趣的文章著手(比如,弦理論,或者,傅立葉變換,或者張量理論,就是能衝擊你相象力的東西) 閱讀。如果有什麼你不理解的,就去了解那些連結。如此這般直到你累到不行為止。

幾個月後,這麼做會縱向擴充套件你的數學知識面,你會發現一些模式,好比,數學的每個分支看上去都包括了一個有著複雜的多元的變數,然後線性代數將會慢慢爬滿你的書單列表,直到你強迫自己學會他實際上是怎樣工作的,你要下載個電子書或買本書,直到你能從中找到樂趣。

憑藉著維基百科,你也能快速的找到一條瞭解數學基本原理的途徑,條條大道通羅馬。在某些領域,數學幾乎總是形式化我們的“常識”,所以我們能減少或證明那些領域裡的新事物。對數學本身的研究就是無止境而且令人著迷的:構造形式模型本質的能力,證明,自明的系統,規則表示,資訊,和計算。

符號是個很重大的但很快會令人放棄的東西。數學符號是關閉你通往另一個世界的符咒。即使你熟悉累加,積分,多項式,指數,等等,如果你看到一堆符號堆徹的異常複雜時,你就把他實現的功能簡單的當成一個原子操作好了,不要深究太多。

然而,從觀察數學來說,嘗試著明白人們正在試圖解決的問題(那些已被證明了的問題某天也許會對你有實際用途),你會開始在符號中看到相同的型別,你也不再排斥他們。比如,累加符號(大寫符號-西格馬)或者π(大寫符號-pi,連乘符號)起初看上去讓人心裡沒底,即時你瞭解了他們的基本原理。但如果你是個程式設計師,你會認識到他僅僅是個迴圈:一個累加值,一個累乘。積分是一段連續曲線的相加,所以那不會讓你鬱悶太久。

一旦你習慣了數學的許多分支,和許多不同的符號的格式,你就走在瞭解許多數學知識的路上了。因為你不再害怕,你將會發現問題,其實他們會自動跳到你面前。“嗨,”你會思索,“我瞭解這個。這是乘法符號!”

這樣你就能扔掉計算器了。有一個充滿相象的計算器比如 R,Matlab,Mathematica,甚或是支援向量機的C語言庫。但幾乎所有有用的數學都是重型自動機,所以你能夠讓一切都變的自動化。

程式設計師:學校教的數學知識,程式設計根本用不到!

數學如何幫助我們

也許不是--不能立刻奏效。但確實能幫助提升你的邏輯推理能力:好比是在體育館做練習,如果你每天都做一點的話,你整體的能力會得到提升。

對我來說,我已經注意到一些我已經感興趣的領域(包括人工智慧,機器學習,自然語言處理,和模式識別)大量的使用到數學。如我已經挖的有點深度的領域,我已經發現他們使用的數學不再比我在中學的學到的數學還要更難;大部分來說僅僅是不同領域。而不是更難了,並且學習使我能寫(或者是在我自己的程式碼裡使用)神經網路,基因演算法,貝頁斯分類器,叢集演算法,影象識別,和其他時髦的東西,能產生很酷的應用。我常向我的朋友顯寶。

我已經漸漸意識到這點,當別人給我看一篇包含了數學符號的文章我不再像突然冒了一身冷汗:組合,微分,真值表,定列式,無限系列,等等;那些數學符號現在變得容易相處了,但(像程式語言的語法)一開始的話多少還是有點讓人感到有些怪異。現在我能更好的理解了,當我一點不知道正在說什麼時,也不再感到自己是個不懂數學的人了。因為我知道自己是能夠弄明白的。那很好。

我會繼續加油做的更好滴。我還有不少活頭,有好多書和文章要讀。有時我會花整個週末來讀數學書,有時會數週都不再思索她。也和其他興趣一樣,如果你單純的信任她你就會有興趣,也能更容易的消磨時光,你可以經常一點點的嘗試應用你覺得有趣的,並從中獲益。

自己是從事了五年的前端工程師,不少人私下問我,2019年前端該怎麼學,方法有沒有?

沒錯,年初我花了一個多月的時間整理出來的學習資料,希望能幫助那些想學習前端,卻又不知道怎麼開始學習的朋友。

如果你依然在程式設計的世界裡迷茫,不知道自己的未來規劃,可以加入web前端學習交流群:731771211 裡面可以與大神一起交流並走出迷茫。新手可進群免費領取學習資料,看看前輩們是如何在程式設計的世界裡傲然前行!群裡不停更新最新的教程和學習方法(進群送web前端系統學習路線,詳細的前端專案實戰教學視訊),有想學習web前端的,或是轉行,或是大學生,還有工作中想提升自己能力的,正在學習的小夥伴歡迎加入

點選:加入

相關文章