程序員不需要知道太多數學,你認同嗎?

我聽到的關於學習編程的最常見的顧慮,就是人們認為這需要很多數學知識。其實,大多數編程需要的數學知識不超過基本算數。實際上,善於編程與善於解決數獨問題沒有太大差別。你認同這個觀點嗎?


答主個人資歷:數學系本科,CS類碩士

先亮總體觀點:任何面向工作的功利的學習行為都可以視為一種投資,必須考慮成本和收益的tradeoff;總體來看,個人認為計算機系本科不教的數學對於絕大多數程序員來說都是沒有必要熟練掌握的數學。

數學不包括演算法。演算法一直是屬於計算機科學領域的。數據結構演算法能力是程序員的核心能力之一,而且永不過時。

當程序員做開發工作,有些方向不太需要數學,有些方向需要特定類型的數學(比如遊戲開發、圖形學會用到大量數值工具等);解決特定問題需要學習特定類型的數學;專門做特定領域的計算機科學研究需要用到大量特定領域的數學;既然如此,那就在碰到相應問題的需求去學習對應的知識就好了,沒有必要非要計較到底哪個重要(前提是你應當知道你這個方向需要什麼樣的知識),也沒有必要僅僅是為了提高「數學基礎」而盲目不加選擇的去學習所有種類的數學。

關於這個問題,最大的迷思就是數學系學生眼中的數學程序員眼中的數學是完全不同的;

  1. 在數學系學生眼中的數學其實大部分的分支對做程序員特別是做開發都沒有什麼用或者不太用得到,意義不大(比如復變、泛函、數論、抽代、常/偏微分方程,更不要說什麼代數幾何、調和分析等,儘管有些領域會有對應的應用,比如抽代、數論可以用在密碼學,泛函、最優化可以用在機器學習,復變可以用在信號處理,但是總體來說還是非常少見,對普通程序員來說意義不大,對非特定領域的日常開發也幾乎沒有影響),而且學習數學的難度極大(遠大於日常程序員所需知識的學習難度),成本太高(我就不說學習數學非常容易忘掉了,等「打好了基礎」 之後結果沒有馬上繼續在相應方向上深挖不斷應用的話,一兩年沒有用,雖然也許腦中所謂的「數學思維」還在,但是具體的內容早已忘光了,到時候會發現自己即使「學了數學」也會感到數學根本不夠用;簡而言之數學根本是個無底洞);
  2. 另一方面,在絕大多數程序員眼裡數學似乎只有離散數學(包括數理邏輯、集合論、圖論、狀態機理論等)、具體數學、計算理論還有高數線代概率論隨機過程所包括的範圍,有時候甚至還包括演算法,這些分支的數學當然對程序員很重要,多掌握一些總是沒錯的(說實話,絕大多數答案都還在糾結至多線性代數、大學解析幾何的層次,甚至更多人只是停留在高中數學,我估計他們本人也從未聽說過更高層次的數學,他們自己都不知道自己在談論什麼東西)。

總體來說,數學是屬於那種少部分情況才會用到,卻需要大量精力去學習的內容;何況學了數學也不是一勞永逸,太少用到的話就難免退化了,總而言之做普通開發很難保持一個比較高的數學水平。所以要注意不必本末倒置,作為程序員,開發能力才是絕大部分時間會用到的主線能力(如果做研究,則需要多一些特定領域的數學知識,學術界比較看重數學);如果你的工作不具備讓你在工作中「被動學習」掌握很多數學的話(比如做機器學習、數據挖掘類工作,也包括自然語言處理、計算機視覺等,以及專門的演算法工程師),還是就維持大學甚至高中水準的數學就可以了,不然也很容易就會忘掉。


數學對於程序員而言是這樣一種東西,你不懂的時候就不可能知道你需要它,反正別人的代碼你都看得懂,但是你不可能知道別人是怎麼想出來的。


「程序員不需要道太多數學」中的「太多」令它變成偽命題。

「太多」就是指多於合適量,說不需要知道太多當然是對的,但知道太多也不會造成壞影響。

而問題描述中說大部分程序員只需算數,要求也太低了吧。


首先,數學不是編程或工程項目上的需求,而是計算機科學的需求。而優秀的程序員大多有紮實的計算機科學基礎和某個子領域的專精。

計算機科學經常需要的數學有:

微積分學

線性代數

初等概率論,隨機過程

圖論,組合數學

資訊理論

初等數論,抽象代數(密碼學,編碼理論)

複分析,調和分析(多媒體,信號處理)

凸優化,時序分析(數據挖掘,機器學習)

微分方程,動力系統(數值分析)

解析幾何,射影幾何(計算幾何學)

範疇論(編程語言理論,感謝 @褚舒墨 )

泛函分析(機器視覺, 感謝 @十餘 )

計算機科學不常需要的數學有:

實分析,測度論

高等概率論

代數數論

解析數論

交換代數

運算元代數

點集拓撲

代數拓撲,同調代數

幾何拓撲,紐結理論

微分幾何

分形幾何

代數幾何

這裡,我只列舉must-to-have的數學領域,而非nice-to-have的數學領域。另外,很多領域我也不是很了解,歡迎大家糾正和補充。


然而廢柴們都是把「太多」等同於自己不會的那部分。

抬杠的說數學家也不需要懂太多數學。歐幾里得不懂微積分,牛頓不懂群論,帕斯卡來考代數幾何,成績恐怕也不樂觀。


我需要聲明一點,評論里一些知友問我怎麼學編程,怎麼學這個那個,我真不知道,我又不是大牛,而且有一些沒有工作的人問我學不學數學什麼的,我想說,我雖然認為數學必不可少,但是你還沒工作就先好好把技術學好,先拿到offer上班了再做其他打算不是更好么?可別說我誤導人啊。

#以下為原答案

我今年初去北京面試一家美資外企,招懂開發的網路工程師,簡單說就是python + CCIE。

我英語好,本以為手到擒來。但是沒想到栽在技術上。他們技術面試官給我上了一課,我雖然沒能拿到offer,但我非常感謝他,這件事影響我很大。

面試前,我寫了幾個練手小項目,遠程郵件控制電腦關機啊,埠掃描啊,BeautifulSoup爬蟲什麼的。面試官說,這些東西都沒用,他考我一些邏輯題和現實當中的問題,讓我手寫python代碼解出來,我有點蒙,畢竟我數學確實不厲害(不是學不會,真是以前沒學,都打dota了)。

最後他跟我聊很多,主要是告訴我不要放太多精力在模仿現成的項目上面,那些網課啊培訓啊都是扯淡的,言外之意就是,他們只招數學厲害,邏輯思維厲害的人,不要項目經驗豐富,但邏輯一般的人。

讓我回去把數學好好學一學,邏輯思維也鍛煉鍛煉再來面試,切記不要浪費時間在一些簡單調用各種庫的練手項目上,這些東西體現不了任何數學思想,所以都是浪費時間。

後來我發現,自學或者培訓苦學幾個月,做大量練習,做各種小項目練手,但沒數學基礎的人,去北京能找一個8k的工作很正常,但是他們一輩子也就那個水平了。google,微軟還有一些歐美外企他們這麼學下輩子都沒機會進去。

所以,切身體會,數學,對程序員來說,是最最最重要的!


微積分並不是數學中唯一的分支。像集合論、圖論、複雜度、組合數學、關係代數、布爾代數、謂詞邏輯這些屬於「離散」的東西也叫數學。數學家的根在微積分,研究連續的東西,比如極限。程序員的根在離散,研究離散的東西,比如編碼(encoding)。離散加上計算理論加上演算法(可能還有一點點數論),就是程序員的數學。

編程本身是用不了多少東西的,編程所解決的問題才會用到數學,這要看你打算編個啥。我還是秉持「用什麼學什麼」的觀點。知識可以在短期內獲得,但是代碼的技巧需要千錘百鍊。當初咱們都是從「五天搞定線代、三天搞定概統」的階段過來的,領域特定的知識一個月還啃不完??


小學二年級的時候,你問老師9除以2是多少,老師告訴你除不盡,那時候你覺得,這就是「太多」數學了。

初中二年級的時候,你問老師計算器上的這個e是什麼意思,老師說這是自然對數,你現在不用掌握,你覺得,這就是「太多」數學了。

高中二年級的時候,你問老師sin(x)和x軸圍成的面積是多少,老師說大學的時候會教,你覺得,這就是「太多」數學了。

大學二年級的時候,你問老師是否存在無限多對距離足夠近的素數,老師說過幾年你問問一個叫張益唐的人,你覺得,這就是「太多」數學了。

「太多」本身並不是一個有絕對意義的概念。你現在不需要的,就可以認為是「太多」的。

因此題目的觀點從某種角度說是毫無問題的,程序員絕對不需要數學家那麼深厚的數學功底,數學也並不是程序員最核心的技能。

實際上,以大部分程序員水平之差,數學根本不會對他們的提升造成任何影響,自然任何數學都是「太多」。

所謂木桶效應。


數學對程序員的意義和錢對人的意義類似。

錢少的,活起來就難免畏手畏腳,十分憋屈,搞不好還會因為太窮而掛掉。有錢的,就能做一些窮人做不了的事情,就能在許多事情上有更多選擇。錢多了,往往不是壞事。

數學也這樣。數學不好的,有些事做起來就很麻煩,有些事可能根本做不了。數學好的,能做的就更多,選擇也更多。


這個其實是站在兩個角度上說的。。。

說不需要太多數學,是站在數學的角度上,其實說複雜度證明,基本的概率論,數學學生大多覺得,這很正常。。。充其量是想複雜度要多倒幾次,沒有什麼難的。。。

然而,數學的入門課,比如抽代,實分析,複分析,這些東西你們是真的不需要。。。就算是圖論數論,也是搞數學得學證明,碼農記結論。。。所以這完全就不是在 「搞數學」 嘛。。。

然而說需要數學的,都是從碼農的角度來說的,本以為調用 api,基本邏輯好了,養成好習慣就行了。。。

後來發現,媽的,演算法題還要邏輯思維?!圖形學還要算矩陣演算法證明還要會基本的證明?!後來發現各種東西還要推概率,還要推收斂?!近似我還要知道泰勒展開?!

天吶,這誰說的不需要太多數學,出來我打死你。。。

至於為什麼說不需要 「太多」 數學。。。因為對一部分人來說。。。你用的數學根本不夠多。。。


認同,因為數學學多了就不想寫程序了,數學(學得懂的話)比寫程序好玩兒多了……


我在成為程序猿之前,一直聽到兩種聲音:

1、程序員不需要懂太多數學英語;

2、想成為程序員就要好好學數學和英語。

在我接觸編程的初期,我信了前者。我發現編程沒有所謂要數學好英語好,只要一個稍微邏輯正常的人都能寫出程序。於是我天天玩命敲代碼,想到什麼寫什麼,看著自己寫出的一堆亂麻在機器上跑起來,那種成就感從心底油然而生。

後來在這一行業接觸越來越廣,慢慢發現自己能力越來越有限,力不從心。

學圖形學和directx遊戲編程時候,天天回去惡補線性代數和空間幾何。

看演算法導論第一個演算法的時間複雜度證明都看不懂,被嚇得不輕。於是又惡補離散數學。

後來為了一個比賽,研究手勢識別,接觸圖像識別領域,又跟小組一起惡補了概率論。還通宵了幾個晚上。那時候真是要哭了。

從我工作開始,我幾乎有一半時間都是在閱讀英文文檔。很多時候還要讀一些英文原著,有些國外的好書,不是沒中文版,就是翻譯太差勁。好在從初中開始英語一直很好,所以看英文文檔還算無壓力。但是看英文書有時候還是有些吃力,可能什麼時候找時間得補一補了。

接觸越廣,需要的基礎知識越多。接觸越深,需要基礎知識越紮實。

所以,對於還不懂自己以後得路怎麼走的童鞋。我建議你,先把知識學廣了。至少有個了解,到時候發現自己想深入一個領域時候,不至於以後死得很慘。

所以現在,哪個傢伙再跟我說數學英語不重要,我直接抄起一本演算法導論直接拍死他。


邏輯學告訴我討論問題要先統一定義,我們來逐個分析一下。

首先「太多」是多多少?很多答案在哭訴概率論線代沒學好,但是我覺得這根本不能算太多,畢竟任何一個本科院校的計算機專業都會教這些,你和我說這是太多?這明明是基本功……所以我認為應該以大學課程為準(從大學開始才有計算機專業),超出微積分、線代、概率論、離散數學(這個範圍太廣,可以認為是數理邏輯、圖論、抽象代數、數論四個學科的弱化版)的,才叫「太多」。

我們再討論一下「程序員」指的是什麼。我認為,程序員是工程師,不是研究員。工程師的任務是把學術界的理論成果做出實際可用的產品,而不是自己在理論前沿開疆闢土。目前的工業生產中,也基本不需要超出上一段提到的數學。

所以,我們可以說「目前為止,程序員不需要太多數學」。

另外我想說一點,快速學習能力遠比提前積累大量知識重要得多。不管是科研還是工程,很多時候不會給你太多準備時間,這時候如果過分追求「紮實」、「系統」,反而會拖累整體進度。能儘快的學會所需的知識,這才是最重要的。


看你是做什麼的咯,如果是數據挖掘的,不會數學簡直是自掘墳墓。

我實習的時候去做數據分析,終面是一個人大統計學的博士,關於數據分析的啥也沒問,問了我什麼是特徵值,奇異值和特徵值有什麼區別,怎麼求特徵值,還有些複變函數的東西。。我還以為是考研複試呢 = =,然後他問我,有沒有啥項目經驗,我說沒有啊,但是我參加過數學建模,雖然全國的沒有獲獎,但是有個校級一等獎,是我一個人做的,我把論文帶過來了,您要看嗎?他很詫異,然後看了下問了下我論文里寫的徑向基函數插值擬合的東西,然後問完了之後問我本科畢業論文寫的啥,我說蟻群演算法在交通路徑中的應用,並且也把論文帶過來了,要看嗎?哈哈哈,boss估計愣了一下,估計沒想到有人會帶著論文來面試。然後他看了一下,問了下蟻群演算法的數學實現,matlab代碼啥的。總之,雖然不了解數據分析,但是懂數學還是很好找相關的實習的。

後來跳槽的時候面的別的幾家公司,經常直接拿白紙推導數學公式的,寫代碼,拿到offer還都是很順利的。

總之,不會數學也可以做程序員,但是上升有限,尤其是數據挖掘,你不想一輩子就做個啥也不懂的調參俠吧。雖然很多時候我們的工作也是調參,但是懂的人調和瞎調的人上升空間肯定不一樣。


今年,大三暑假出去找實習,面試了三家公司,過了兩家,有一家沒過,下面我就公司需求和數學來分析一下。

職位都是java實習生

第一家公司

給他們談了項目經驗,學習經歷,過了一面,二面,並且兩個面試官對我評價非常高。三面是技術總監面試我,主要是考演算法,很簡單的兩個演算法題,但是由於本人寫演算法,搞acm都是用c++,而面試官要求我用java,導致基礎的輸入輸出,字元串處理吃了虧,勉強花了20分鐘才解決了兩道水題。直接導致我沒能拿到offer(5天過後我問過這家公司的面試官,他回復我說,覺得我代碼寫得不夠)

第二家公司

一共二面,主要是談項目經驗,沒有演算法,最後也過了。公司說給研究生待遇,但魔都的環境放在這兒,這家公司即使是研究生的實習工資依舊不能讓我很好的生活下去,遂放棄。

第三家公司

一共二面,筆試過了,技術負責人一面,主要是講項目經驗,覺得我講的還不錯。之後是架構師電話面試,有兩個生僻的問題沒答上來,其他都還行。也過了。待遇也算不錯,工資也按照我要的給了。沒涉及太多演算法。

總體而言,我覺得非常難過的點,在於第一家,可以說一二輪面試決定你的基礎分的話,三輪的演算法面卻決定了你最後的去與留。有能力有發展前途的公司就註定你不僅僅是有項目經驗就可以的。有很多時候吧,工作了兩三年的人,卻是沒有應屆生水平高的。

我也不是想鼓吹演算法,數學。就拿java這一行來說,用框架,調api是大多數碼農必須會的,但牛逼的人也不是說就一定是數學好,例如精通設計模式,理解框架內核,知識面廣...都是脫離了低級碼農層次的人,不像是一些人講的唯演算法與數學是用。

很反感兩類人,一類是不懂數學,不懂演算法,說這兩個東西沒有用的人;一類是略懂數學,略懂演算法,就容不得別人說這兩個東西一點點不好的人。


其實在一本叫《A Programmer"s Ranting》的書里(我們和豆瓣合作翻譯的版本(https://read.douban.com/ebook/11174020/) 以及 徐旭銘 與人民郵電出版社出版的版本:(《程序員的吶喊》([美]Steve,Yegge)【摘要 書評 試讀】)),作者Steve Yegge也討論了程序員是不是要學數學,他說了一些實際的學數學的好處:

?學習數學能提高你的問題辨識的能力,或說套路的能力;比如知道一個問題是組合數學問題,你就知道怎麼用組合數學的問題去解;知道一個問題是離散優化的問題就知道怎麼用離散優化去解

?學習數學能讓你做出比較酷的程序在朋友面前炫耀 XDDD 比如做物理引擎充當搖獎機之類的

更不用說那些raytracing之類的了。

不過我這裡說的用數學是很偏應用的,不偏證明。數學是形式化人們對世界的認識的科學,我只用到了其中的萬分之一不到吧。

所以就看你想不想學啦。

p.s. 如果你看到這個答案並且對《A Programmer"s Rantings》這本書的我們與豆瓣合作翻譯的電子版(https://read.douban.com/ebook/11174020/)有興趣的話,可以給我發私信,我在豆瓣閱讀中贈送給你,因為現在那本書雖然已經上架,但我翻譯的那部分稿子有些問題還在商討解決中… 我覺得很不好意思讓大家付錢(真抱歉!)(送到我豆瓣閱讀里的錢花完為止吧大概能送一二十份,嗯)

編輯2016-07-20 21:31,還有五份

這個答案的價值沒有其它幾個高,所以也請不要贊了吧


根bie本qiang不wo需gong要zuo


你問我支不支持,我當然是反對的。

程序員如果沒有數學支持,很容易淪為碼農。

雖然,我承認,日常的商業編程里,確實不需要太高深的數學功底,但是:數學是成為大師的基石。

天可憐見,我的數學太差。一直在惡補,一直效率低。


我小時候也被騙了,現在後悔都晚了

連類型論都不會還寫個毛的程序(逃


買菜需要數學嗎?

吃飯需要數學嗎?

睡覺需要數學嗎?

做菜需要數學嗎?

旅遊需要數學嗎?

其實很簡單,看看工地就能明白了。

建築設計需要數學吧?

實地施工計算需要吧?

生產磚的需要吧?

唯一不怎麼需要的,就是搬磚了。


推薦閱讀:

寫一個自己的開源框架需要有哪些能力和基礎?
CS PhD@UIUC(DB/IR/DM) Waterloo(IR) vs. MLT@CMU?
為什麼會議論文在計算機專業非常重要,而在其他專業卻不值一提?
opencv在CV, ML, DIP等領域處於什麼地位?

TAG:程序員 | 演算法 | 計算機科學 |