2016/05/17

程式設計真正要學的是什麼?


最近有人問我孩子可以上什麼程式設計課程。在回答這個問題之前,先來說一個數學家高斯的故事。

西元1777年高斯出生在德國鄉下,他的數學老師因自己在窮鄉僻壤教書而對學生態度不是很好,有天出了一題數學想考考這些三年級的小學生:

81297+81495+81693+…+100899 = ?

沒想到當老師才寫完題目,像我都還搞不清楚這是什麼題目時,高斯小朋友已輕鬆地在他的石板上寫下正確答案。

這是一個等差數列的求和問題(公差為198,項數為100),我猜小高斯在老師出這道題目時早已自己研究過,就像:1 + 2 + 3 + 4 + ....+ 98 + 99 + 100 = ?

高斯發現:
       1 +100= 101
       2 + 99 = 101
       3 + 98 = 101
               .
               .
               .
          50+51 = 101

頭尾兩數兩兩相加,是50對和都是101的組合。

高斯找到一個所有等差級數求和的計算方法,只要套這個公式(也就是所謂的演算法)就能很快算出結果,無論數字多大、多少組,計算時間都差不多。

高斯在晚年對自己的孫兒講述小時候的故事,說他在還不會講話的時候,就靠平日的「觀察」自己學會了計算。

書上的傳記故事就講到這裡,但我很好奇小高斯如何發現頭尾兩數相加的和剛好都一樣?他是把否把這些數字當成玩具,用各種方法排列組合,反覆搬來移去...最後才發現這個規律,還是像牛頓一樣被一顆蘋果啟發的?

這道題目也常出現在程式設計的課程中,最常見的就是用一個迴圈來求解。如果教學的重點在練習程式語言中的迴圈語法,那OK,但如果寫在分秒必爭的程式中就很不OK,因為算100個數要跑一百次迴圈、1000個數要一千次迴圈...,計算時間會隨著數字愈多而遞增。

若用高斯的演算法,則無論幾個數都只要一個計算就結束。

現在,你應該了解我認為程式設計該學什麼了吧!不是程式語言的皮毛,而是解決問題的方法,這有個專有名詞:演算法。

怎麼學演算法?以高斯本身的說法就是透過「觀察」,發掘事物中的「規律」。最後的計算反而不是重點。

程式設計說到底,最重要,最有價值的也正是拆解、洞察的能力。如何拆解、洞察出其中的規律,有時需要一點創意,來點不一樣角度,或許難題就有解了。

就拿Google的圖像搜尋為例。當我們輸入「海灘」,電腦是怎麼找出和海灘有關的照片?看看這個影片:Findable Photos Using Data and Algorithms,Google工程師想出幾個方法。

一是先讓電腦解析照片中有那些物體,如果照片出現了沙子、水、椰子樹、海鷗等海灘上會出現的東西,就認定這是張與海灘有關的照片。另外一個方法是分析照片中的GPS地理資訊,找出在海邊拍的照片。

可是如果是在海邊和朋友的合照,裡頭沒有海灘相關物體,也沒有GPS地理資訊怎麼辦?Google工程師再想...,發現這可從同一時間拍的其他照片,推論出這張合照應該也是在海邊拍的。

回到程式設計,或是「Computational Thinking」,我認為真正的重點應該是在「Think」這個部分。我不知道高斯怎麼「思考」出許多數學理論,但我們可以做一些思考練習。

誰說學程式設計一定要有電腦?Computer Science Unplugged 網站集合了數百位教師的心血,設計了許多在教室及家裡,只要雙手和紙筆就能玩的活動,探索二進位數字、排序、圖像、密碼學等問題,更棒的是有中文版的教學活動手冊:《不插電的資訊科學》可供下載!

透過這些不插電的思考觀察活動,或許更能讓我們專注並發現程式設計的本質。

參考:數學天才—高斯的故事Findable Photos Using Data and AlgorithmsExploring Computational ThinkingComputer Science Unplugged