漫談孩子學習編程和寫軟件
應該是美國中小學即將開學的緣故,家長需要給孩子們選擇周末興趣班,這幾天好多朋友問我,孩子們要不要學編程,更具體的說,要不要學習Python程序設計。孩子要不要學編程,的確是個好問題。就算沒有朋友問,我自己也考過很多,也曾試過。在女兒讀二三年級的時候,我教過她簡單的Python和Java程序設計。很可惜,成效並不大,盡管我挑選了幾個很有趣的簡單數學問題,用計算機去求解,仍然不能引起孩子的興趣。這就更讓我進一步思考,到底該不該現在就教孩子寫程序,如果教,該教哪一種程序設計語言,怎麽教。
我自己不是計算機科班出身,但是靠著科學計算混飯吃,能夠熟練地使用C,C++,FORTRAN,Java, Visual Basic,MATLAB,PYTHON,Bash, GrADS, NCL甚至是AML寫程序。大學期間,我正經八本上的計算機課,也隻有C語言程序設計。用了不到一個月時間,我就把譚浩強先生寫的《C語言程序設計》自學完了。通過這本書,我學會麵向過程的軟件開發方法。學期末,我就用C語言給我們班寫了一個獎學金評選的程序。當時是九十年代末,C++已經開始成為潮流。寫程序的人如果不會C++,是不敢出去吹牛的。我很喜歡吹牛,所以買了本C++程序設計的教材。C++比C語言豐富多了,我用了兩三個月才學明白什麽叫做麵向對象的軟件開發方法。我大學畢業的時候,用C++開發了一套人工神經網路的程序。在2000年,在好多國內的書店裏,如果你問有沒有人工神經網絡方麵的書,店員大多會讓你去醫學門類去尋找。所以,我那時候,作為一個地質係的學生,用基於人工神經網絡的人工智能,去研究礦山穩定性,也值得大吹特吹了。自吹自擂這麽多,拉回到程序設計的話題上,其實哪種語言不重要,關鍵是學會軟件開發的方法,比如前麵提到的麵向過程和麵向對象軟件開發。
當然,一個寫程序的人必須要了解計算機的體係結構。我很幸運,從C語言開始學習編程。學過C語言的,很多人都很憎恨它,就算學過,一輩子也不會用C語言寫一個超過100行的程序。C語言之所以招人厭惡,是因為它太接近計算機硬件了。作為一種強類型語言,也就是說,需要直接聲明和定義變量的計算機語言,寫程序的人必須了解,什麽是整數,什麽是實數,什麽數有符號,什麽數無符號。解決問題,我們必須搞清楚,實數需要小數點後幾位的經度,整數需要幾個字節。問題複雜了,需要分配內存,需要傳遞複雜變量,就要涉及地址和指針。把這些細節搞清楚,的確是需要花點時間學習計算機的硬件和原理。因為這個,和多人都望而卻步打了退堂鼓。然而,對那些肯花時間鑽研的人,一旦弄明白了底層細節,以後操作計算機就像是庖丁解牛一樣,可以輕鬆玩耍。
通過C語音學習編程,起點高,的確有點難。對很多人來說,就像是撞牆一樣痛苦。可是一旦把牆撞破了,就可以把頭伸進計算機的內部世界,能夠享受把自己的想法轉變成計算機程序的自由,最終可以驅使計算機替你思考。在我上大學的時候,除了計算機係的學生,肯去研究C和C++程序設計的人非常少。多數人都去學習如BASIC這樣的語言。BASIC很方便,方便到變量既可以聲明,也可以不聲明,總之是無所謂,關係不大。靈活帶來方便,也帶來混亂。BASIC的程序,大都是亂七八糟,就像一盆煮熟的方便麵,順著哪根麵條,也捋不出一個頭緒。很多人把這個問題歸咎於BASIC程序中的GO TO語句。在我看來,這多少是冤枉了GO TO。問題的主要原因是,那些從BASIC學習計算機程序設計的人,沒有學會正確的軟件開發方法。他們大多是圖簡單,圖方便,圖快,最後把程序搞成了塗鴉。回想一下當年我的同學,熱衷短平快學習BASIC和Visual Basic之類編程工具的人,大多沒有在軟件一行走下去深入發展。相反,好多學習C,C++和Visual C++的同學,成了軟件業的精英,現在坐擁豪宅若幹。
前麵談的都是曆史,現在轉到現實。現如今再沒有人學習什麽Basic和Visual Basic。短平快的軟件開發,大家都選擇Python。Python可以算最成功的解釋型語言,沒有之一,而是唯一。Python引人指出,大概有這麽幾點。第一就是,嚴格的程序書寫規範。Python的作者深受Perl語言自由靈活書寫風格之苦,要求Python的開發者,必須按照既定的規則,書寫每一行程序,否則Python解釋器跟你沒完沒了地抱怨,這樣確保了Python代碼有良好的可讀性。因此,你上周寫的程序,今天還能很容易地看懂。第二,Python程序既能麵向過程,也能麵向對象。什麽是過程,什麽是對象,如果你寫不了200行的程序,沒必要去敲破腦袋搞清楚。 第三,Python提供了豐富的基本數據結構,例如元組(tuple),列表(list),字典(dictionary)和集合(set)之類的的數據結構。對於C++的開發者,如果使用這些數據街頭,需要學習複雜的標準模板庫,要麽自己去開發,總之是費時費力。而Python的用戶,可以輕鬆使用這些數據結構帶來豐富功能。 最後也是最重要的一點,Python有極其豐富的共享資源。對於一個應用Python的軟件開發人員而言,一定要記住,你是在用Python而不是開發Python。對於任何一個常用的計算機操作,不管複雜與否,開發人員基本上都可以在網上找到免費的Python代碼庫。開發人員需要做的,就是開發盡可能簡單的Python代碼,調用這些代碼庫,完成自己的任務。
Python容易不容易學?Python強大不強大?我的答案是Python很強大,但是我不知道對於小孩子來說,到底容易不容易學。如果沒有任何數據結構的基礎,我不知道怎麽給孩子講明白列表的工作原理。那些現成的Python代碼庫,真的既豐富又強大。有大人幫忙,孩子們可以輕鬆用Python寫一個收發電子郵件的程序。可是電子郵件裏的文字和圖片,到底是怎樣從這台計算機到那台計算機的,孩子們要是問起來,Python程序員應該不是很容易回答。隨手抓來的Python代碼庫,讓我們不必關注細節,直奔主題地開發程序,完成我們的工作。可是,我總覺得,孩子們學習計算機程序設計,是需要了解細節的。教孩子學習寫程序,不應該是簡單的然他們學會怎樣用別人的代碼搭積木,而更應該讓他們了解每塊積木是怎麽工作的。我們大人用Python寫程序,是因為我們隻看重結果。孩子們學習寫程序,更應該側重過程。如果沒有計算機基礎,上來就學習Python,孩子再聰明,怕也隻能是渾淪吞棗式地學習。在大人的指引下,他們能夠寫出小程序,離開了大人指導,他們還能走多遠?我不是很樂觀。
我喜歡用Python,可是我心裏總是隱隱約約覺得,Python不是一個給小孩子入門的計算機語言。當然,我也不想讓一個孩子硬著頭皮去學習C和C++。想來想去,程序設計可能是無法快速入門的。想靠著十節八節Python程序設計課程,就讓孩子去研究人工智能,為申請大學加分的想法,是不切實際的。 在我看來,學習程序設計,還得從長計議。要是我列一個課程表。第一個必修課就是數學。理解程序設計的一個基本需求就是,孩子得理解數學中函數的定義。不管是麵向對象還是麵向過程,我們都會把相關的一組計算機操作組織到子程序(或者叫做函數)裏。理解了數學中的函數,孩子們就可以學習麵相過程的程序設計了。能寫出幾十個子程序(函數)構成的程序,才有學習麵向對象程序設計的基礎。有了一定的數學基礎,第二個必修課就是計算機操作。好多孩子會在計算機上打遊戲,卻從來沒有在計算機上發過一封電子郵件。編程的一個基礎就是,計算機打字。孩子正確使用鍵盤和鼠標,也得點功夫。學會操作計算機,就可以真正接觸程序設計了。好多老師,從集成開發環境(IDE)(比如說Eclipse)開始教授程序設計。不管學習Java還是Python,都是按照老師的指導,在IDE裏輸入程序,然後用鼠標按一下按鈕,結果一下就跑出來了。一旦離開了IDE,孩子們一臉茫然不知道那裏可以寫程序,更不知道程序怎樣變成可執行代碼,並運行處結果。要是我來上課,一定從最簡單的文本編輯工具開始。我會教孩子怎樣打開命令行窗口(Terminal),怎樣啟動文字編輯器,怎樣輸入程序,怎樣保存代碼,然後怎樣編譯程序,最後怎樣執行程序。
到底哪一種計算機語言最適合初學的孩子呢?我想我會選擇Java。Java在語言要素和語法上,繼承了C和C++,基本上就是一個C++的簡化版。談到課程設置,我想我會從數據類型,條件判斷(IF語句),和循環結構開始,讓孩子了解一個程序的基本構造:數據,判斷,和循環。我不會著急讓孩子學習類和麵向對象的概念。相反,我會用半個學期,甚至一個學期的時間,讓孩子學習麵向過程的程序設計的理念。也就是說,怎樣把一個複雜的問題分解成若幹步驟,每一個步驟又通過一個Java的函數來實現。讓孩子們學會,怎樣把這些函數組織在一起,解決他們的問題。
想想看,我們為什麽要寫程序?寫程序的目的就是為了解決問題。在寫程序之前,我們腦子裏要形成一個解決方案。這個方案,往往包括多個前後銜接的步驟,甚至有條件判斷,還有重複性的步驟。 這些步驟,都可以通過程序中的函數來實現。用計算機求解問題,真正的難點不是寫程序的過程,而是開發問題的解決方案。計算機代碼,隻不過是解決方案的計算機實現。用上半個學期,甚至一個學期,教授孩子怎樣去利用計算機,探討問題的解決方案,所用時間其實並不長。家長呢,應該認識到這一點。教授孩子寫程序,其實是教授孩子用計算機來解決問題。麵對相抵複雜的問題,如果孩子們可以設計解決方案,可以寫出包括十幾個甚至更多的函數的代碼,那說明孩子們可以進一步提高了。我們可以隨後教授孩子,怎樣以數據為中心,進行麵型對象的程序設計,開發更大規模的軟件了。 當然這是後話,對於初學者的父母,完全不需要上來就考慮麵向對象。
Python要不要學?要!不過是在孩子們完全理解了麵向過程程序設計理念之後。有了這樣的基礎,即便不用Python裏麵的“類”,孩子們也可以寫出像模像樣的Python程序。如果孩子有了麵向對象的基礎,那麽就可以更加容易地理解Python中的元組,列表,字典,還有集合等數據結構以及相關的操作(或者說函數)了。如果孩子有興趣,也完全有可能應用Python的類(class)的組織代碼,開發出複雜的軟件。有了程序設計基礎,孩子們可以更加深入地理解並有效地利用共享的Python代碼庫。那時候,他們用共享代碼開發出的電子郵件收發工具,不再是簡單地模仿。孩子們可以設置甚至改造共享代碼,把他們的有趣的想法實現到軟件工具裏。我相信,經曆這樣的過程,孩子們可以真正地了解計算機以及程序設計。深入掌握,必然幫助他們觸類旁通,以後學習人工智能,自然會有堅實的基礎。
最後一句話:Python便捷強大,適合急功近利式的軟件開發,未必適合孩子們入門學習。