要數學好,寫Code先會好?

Gordon Lau

Gordon Lau

2020-07-17

有一個非常常見的問題,筆者不論在日常教學工作,或是宣傳活動之中,都經常被問到。這個問題就是:「我的數學不好,可以學習寫程式嗎?」一開始筆者都不以為然,以為只是大眾對程式設計師眾多誤解中的其中一個,後來被多問幾次後,發覺為數不少的行外人,都認為寫程式的人,數學必然非常優異:反之,數學不濟的人,則絕無可能成為軟件工程師。

這個印象乍看之下,好像有點道理,平常遇見的軟件工程師之中,很多都是中學時理科班出身,大學學位即使不是電腦科學(Computer Science),也會是其他工程系(Engineering),或是其他純科學系(Pure Science),甚少會遇見出身文學(Art)相關學系的工程師。這不是正正就是證明了這個數學好,寫程式才會好的現象嗎? 筆者我本身也是一個類似例子,我本身在大學是主修物理、副修電腦科學,物理系本身是數學系以外最多數學計算的學系,這看來也與這個現象完全符合啊!

但這個看法,其實犯了一個基本的統計學謬誤,就是相關不蘊含因果關係(Correlation does not imply causation),也就是即使觀察到很多軟件工程師數學不錯,我們也不能由此推論出「一個人先要數學好,寫程式才會好」這個因果關係,更不能推論出「一個人數學不好,寫程式就不會好」。為甚麼呢?因為數學好與寫程式好,兩者可以有個共同原因(Common Cause),可以是純粹巧合(Coincidence),兩者相關不代表有因果關係,更何況做數學與寫程式每天所做的事更是截然不同。

如果你統計每年美國在泳池溺水的人,與影星尼古拉斯.基治(Nicolas Cage)的作品並排的話,你會發覺有驚人的相關,難道尼古拉斯.基治拍愈多作品,就會導致更多人溺水嗎?

correlations.png

Spurious Correlations有更多有趣例子

以筆者個人教育經驗所得,通常本身有理工科底子同學在學習程式設計時在學習算法上較有優勢,但在CSS、程式語言語法、解難能力上則與其他同學差別不大。在工作之中,也認識 很多程式設計高手,本身也不是甚麼「數魔」,數學程度也大概是高中水平。所以看來這個現象可信程度是一半半吧? 當然筆者一人經驗沒有太大參考價值,那有認知科學(Cognitive Science)界嚴謹研究得出的結果嗎?

paper.png

今年三月時美國華盛頓大學發表了一篇題為Relating Natural Language Aptitude to Individual Differences in Learning Programming Languages的學術論文,找來了36個本身無任何編程底子的志願者,參與10個45分鐘長Codecademy的網上Python課堂,每堂後都有即時小測,志願者需要合格才可以繼續向下一個練習進發,在完成十個課堂後,再以三個基準量度每個參與者的編程能力:學習速度(Learning Rate)、編程準確度(Programming Accuracy)、陳述式知識(Declarative Knowledge)。其中學習速度以參與者在課堂上表現計算,編程準確度則以參與者嘗試編寫一個包剪揼(Rock-Paper-Scissor)的遊戲作為完成標準,陳述式知識則以50條多項選擇題計分。

研究者希望在這個實驗之中,找出甚麼因素最影響學習編程效果好壞(Factors affecting programming learning),因此他們也量度了數個與參與者本身認知能力(Cognitive Abilities)有關的量度: 語言能力(Language Aptitude)、計算能力(Numeracy)、流動推論能力(Fluid Reasoning)、工作記憶能力(Working Memory)。 這是研究人員得到的結果。

results.png

研究者發現,流動推論能力及工作記憶能力之高下最能夠預測學習編程的表現,34%的方差(Variance, 統計學概念,用作描述變數的離散程度)可以由學習者的以上兩種能力預測得到。以日常語言描術,就是有三分之一的學習編程表現差異,可以由這兩項能力決定。

那甚麼是流動推論能力及工作記憶能力呢?所謂流動推論能力(Fluid Reasoning),其實源自於1963年心理學家Raymond Cattell所提出的固定智力(Crystallized Intelligence)及流動智力(Fluid Reasoning)而來,固定智力指的是經過學習知識而得來的解難能力; 流動智力指的是不經過往知識,純由現況發現新知識的能力。 舉一簡單例子解說,一個天天操練IQ題,變得非常擅於解決IQ題的人,固定智力很高; 一個不常玩IQ題,卻總能以新穎方法解決IQ題的人,則流動智力很高了。 簡而言之,流動智力高的人,比較接近大眾心目中的聰明人;固定智力高的,則是高教育人群。所以說了這麼多,有34%學習編程的表現,可以用「聰明」兩個字來概括了。

聰明的人學編程較快,這大概是「阿媽是女人」式的知識,那有何意義呢?因為好戲在後頭:第二重要的因素竟然是語言能力(Language Aptitude),而不是大眾以為的數學能力(Numeracy)。語言能力高下解釋了17%的方差,計算能力卻只解釋了2%的方差,在細項之中,也只有學習速度(Learning Rate)受數學能力所影響。這也有一定合理性,程式語言的性質與自然語言非常相似,現代程式語言更是愈來愈往易於閱讀(High readability)方向發展,而實驗中的Python,就更有Runnable Pseudo-code(可運行偽程式碼)的美譽。語言能力好,自然在學習理解Python時,事半功倍。

著名電腦科學家Edsger W. Dijkstra曾有一句名言:

Besides a mathematical inclination, an exceptionally good mastery of one's native tongue is the most vital asset of a competent programmer.

Dijkstra認為一個程式設計師的語言能力非常重要,更是一個程式設計師好壞的重要分野。當然Dijkstra也認為數學能力(Mathematical inclination)也很重要,但根據這個研究,似乎數學能力只能算是第三因素。

那麼文首一開頭提及的現象又如何解釋?為何大多數軟件工程師都是理科班出身?又或是學位常是理工科系呢?在研究之中當然沒有任何這樣的分析,因為參與者皆是本身無任何編程底子,光是這一點就篩走了大多數理工科的同學。筆者在此大膽假設這個現象的成因:本身就讀理工科之同學因學系需要,在流動推理能力(Fluid Reasoning)方面較強,學習編程自然就事半功倍。因此不是數學好所以編程好;而是推論能力較好,所以數學及編程皆好。

Mathematics_Programming.png

這個假設,就要留待認知科學未來的研究了。姑勿論最終原因何在,筆者相信的是,即使你的數學不是非常優秀,要學習編程依然是綽綽有餘的!

Comments

Read More

學寫Code失敗之四大原因

學好手勢 == 學好Coding

學寫程式為何甚艱難?

軟件工程師成長手冊

專家級新手

平常人都能掌握的Programming 原則