諶衛(wèi)軍
摘要:提出一種基于能力培養(yǎng)的程序設計課程教學方法,將程序設計過程分為3個步驟:問題分析、算法設計和編碼。針對問題分析提出案例教學方法,以案例的形式闡釋問題分析的過程和技能;針對算法設計提出編程模式的概念,這是自頂向下設計技術的一種具體實現(xiàn);針對編碼設計并實現(xiàn)一個功能強大的在線訓練系統(tǒng),為全面提高學生的動手實踐能力提供技術上的保證。
關鍵詞:程序設計;案例教學;編程模式;在線訓練系統(tǒng)
0 引言
隨著信息技術的不斷發(fā)展,計算機被廣泛應用于各行各業(yè)。熟練掌握一門計算機程序設計技術已經(jīng)不僅僅是計算機專業(yè)學生的基本要求,而是所有大學生尤其是理工科學生需要掌握的一種技能。在多年的教學實踐中,筆者深刻地體會到程序設計類課程與傳統(tǒng)課程有很大區(qū)別,而現(xiàn)有的一些教學方法和教學理念也存在某種誤區(qū)。
首先,大部分選修程序設計課程的學生都是大一新生,以前從未接觸過編程,因此不太了解程序設計的特點,不知道如何學,可能還是沿用中學時代的學習方法,容易走彎路。筆者在每個學期的第一堂課都會進行一項調查,將班上所有學生按照編程基礎分類,從調查結果看,大部分學生在選修該課程之前沒有任何編程基礎,不知道應該怎么學。事實上,從歷屆學生平時的提問也可以看出,他們經(jīng)常問的問題是標識符的意義、運算符的功能、for語句中的表達式能否使用嵌套的表達式等。學生主要將注意力放在了編程語言的語法細節(jié)上,以為每一個知識點都非常重要,而在實際的編程過程中,這種語法細節(jié)沒有太大意義。
其次,在講授程序設計類課程時,一些教師的教學理念和教學方法也存在誤區(qū)。一般來說,程序設計類課程主要講授兩個方面的內容:編程語言的語法知識和實際的編程技能。其中,編程技能最重要,學生學習程序設計課程的最終目的就是在碰到一個實際的編程問題時,能夠設計出相應算法并編寫出正確代碼,最終解決這個問題。然而,在實際教學過程中,一個常見的現(xiàn)象就是教師把教學重點放在了編程語言的語法知識上。在課堂上,教師會詳細講授每一個語法細節(jié),然后用一些小例子演示語法的使用方法;在平時練習和期末考試中也采用傳統(tǒng)的考核方式,用選擇題、填空題和問答題等題型考查學生對語法知識點的掌握情況。
總之,對于程序設計類課程,由于各個環(huán)節(jié)都可能存在一些不足,容易導致學生陷入眼高手低、紙上談兵的誤區(qū)。事實上,在教學過程中,筆者最常碰到的問題就是學生對C語言的語法非常熟悉,然而一旦要編程解決一個實際問題就無能為力。
1 相關工作
國外一些研究表明,在學習程序設計時最重要的技能是問題分析和求解,這是一種思維層面的、抽象的技能,也恰恰是學生所欠缺的,而且這種技能不像具體的語法知識只要簡單地傳授即可,它需要培養(yǎng)和訓練。文獻[1]指出很多學生尤其是大一新生最缺乏的就是問題分析與求解能力,而對于教師而言,講授語法知識比較簡單,因為這些知識都是固定的,是一條條的規(guī)則,但要想讓學生提高分析問題、解決問題的能力,難度就會大很多。文獻[2]指出在一門計算機課程中,學生的薄弱之處就在于問題分析和求解技能,因此課程的重點必須放在這種能力的提高上。文獻[3]通過采訪計算機科學系的5位教師,發(fā)現(xiàn)大部分學生都想當然地認為自己具有問題分析和求解能力,而不能發(fā)現(xiàn)自己在程序設計中的弱點。
那么如何提高學生的問題分析和求解技能呢?文獻[1]提出一種自頂向下的設計技術,基本思路是把待求解的問題用一組類似于英語的偽語言指令描述,然后一步步地優(yōu)化、細化該程序。文獻[4]中也指出在編程過程中,自頂向下的方法非常重要,應該把一個大問題分解為若干個可以管理的小問題,分別求解每個小問題,然后將結果綜合在一起,從而得到原始問題的求解方案。
筆者認為自頂向下的設計技術毫無疑問是一個非常實用、有效的方法,但問題在于如何具體實現(xiàn)。對于程序設計來說,最主要的是如何才能把一個復雜問題分解為若干子問題,然后將它們組合在一起。問題的分解本身就是一種技能,學生可能知道要分解,但并不知道該怎么分解。此外,對于分解后的子問題,有些學生可能還是不知道該如何解決。
在程序設計過程中,除了問題分析和求解技能外,還有一項重要技能就是代碼編寫。文獻[5]指出學生在編程時會把自然語言中的一些用法不恰當?shù)伢w現(xiàn)在編程語言中,從而導致程序出現(xiàn)各種問題。文獻[6]指出編程的難點并不在于編程語言的語法,事實上,學生即使精通語法,也仍有可能無法寫出正確的代碼。為了提高學生的編程能力,主要的方法就是加強訓練。
2 教學目標和理念
基于多年的一線教學經(jīng)驗,筆者對程序設計課程進行了教學改革,基本目標是通過教學內容、教學方法、訓練方法和教材等多方面的改革,幫助學生在學完該課程后能夠切實提高編程技能,解決實際編程問題。換言之,不能把目標局限在掌握低層次的簡單語法知識上,而是要瞄準高層次的抽象思維方式以及如何提高學生的能力和素質,這才是最重要的。
在教學理念上,要堅持以學生為主體,采用啟發(fā)式教學,充分調動學生的主觀能動性和創(chuàng)造性,鼓勵他們自己寫出算法。事實上,程序設計類課程為學生提供了一個靈活、可自由發(fā)揮的平臺,這個平臺上沒有權威,也沒有標準答案,對于任何一個程序設計問題都存在著不同的解法,“條條道路通羅馬”。因此,學生可以充分發(fā)揮自己的想象力,運用所掌握的基礎知識設計出各種與眾不同的解決方案,而這也正是創(chuàng)新能力的體現(xiàn)。
總之,筆者認為上述教學目標和教學理念符合現(xiàn)代教育教學的客觀規(guī)律,符合高校的人才培養(yǎng)目標。
3 教學方法
基于多年的教學經(jīng)驗以及對程序設計課程的思考和理解,筆者提出一種基于能力培養(yǎng)的程序設計課程教學方法。程序設計類課程教學框架如圖1所示,該框架源自筆者對程序設計過程的理解,即編程模型。
圖1中,計算機程序設計可以看成是把一個文字形式問題的描述轉換為相應的源代碼。整個過程可以分為3個步驟,即問題分析、算法設計和編碼編寫。由于每一個步驟涉及不同的技能,因此需要采用不同的教學方法。具體來說,在問題分析環(huán)節(jié)使用案例教學的方法;在算法設計環(huán)節(jié)使用編程模式的概念;在編碼環(huán)節(jié)設計并實現(xiàn)一個在線訓練系統(tǒng)。endprint
3.1 問題分析
問題分析是程序設計的第l步。一般來說,一個編程問題的描述就是一段自然語言句子,如果學生沒有受過良好的訓練,就不知道如何分析問題,如何在這些句子中找到有用的信息。因此,問題分析能力是程序設計中的一項重要技能,但是學生卻很難獲得這方面的幫助。一方面,大量的編程書籍主要是介紹編程語言的語法,很少有材料討論如何分析問題;另一方面,通常的程序設計課程也不講這些內容,認為這種分析問題的能力與生俱來。實際上,學生的最大問題并不是看不懂題目,而是不知道該做什么和如何做。
如何解決這個問題?基本思路是把問題分析方法也作為課程內容的一部分,要有意識、有針對性地向學生講授這部分內容。在具體實現(xiàn)上,筆者采用案例教學法,在課程講義中集成20多個編程案例,通過案例的形式向學生展示問題分析的技能。所謂案例并不是傳統(tǒng)意義上的一個個簡單的編程小例子,也并不是附屬于某個語法、為了闡釋某個語法的使用方法而引入的,案例必須經(jīng)過精心設計,具有獨立、完整的內容。引入案例的目的并不是為了解釋語法,而是為了向學生闡釋某一類編程問題的分析方法和解決方法。一般來說,一個案例需要具備以下4個特點:
(1)具有一定規(guī)模,同時考查多個知識點;
(2)具有完整的內容,包括問題分析、算法設計、編碼測試、題后討論等多個環(huán)節(jié);
(3)具有一定難度,富有挑戰(zhàn)性;
(4)生動有趣,能吸引人。
例如,筆者的課程講義中有一個案例是“猜數(shù)字游戲”,問題描述是“編寫一個程序,由電腦隨機產(chǎn)生一個數(shù)字不重復的四位數(shù),由玩家猜,每猜一次,電腦將顯示形如*A*B的結果,其中A代表位置正確數(shù)字也正確,B代表數(shù)字正確但位置不正確,如2A2B,表示有兩個數(shù)字和位置都正確,兩個數(shù)字正確但位置不正確,總共有10次機會”。這個案例來源于真實的游戲,一些手機、PDA等終端設備上都有該游戲。該案例既具有趣味性,又有一定難度,富有挑戰(zhàn)性。
對于每一個案例,筆者不是簡單地列出源代碼,然后為學生解釋,而是著重于問題分析和解題的思路。以“猜數(shù)字游戲”為例,如何從編程的角度對其進行問題分析呢?所謂問題分析,就是對問題描述進行仔細研究,明白它的真正含義,然后抽取出需要解決的問題,將大問題分解為小問題,引導學生建立這樣的觀點:先不要想怎么做,而是先想清楚需要做什么?需要解決哪幾個問題?對于上述例子,經(jīng)過問題分析,實際上需要解決3個技術問題:
(1)如何隨機產(chǎn)生一個數(shù)字不重復的四位數(shù)?
(2)對于一個四位數(shù),如何將它的每一位數(shù)字拆分出來?
(3)對于玩家猜測的一個四位數(shù),如何計算相應A和B的數(shù)量?
總之,對于每一個編程案例,筆者都會進行問題分析,講清思路演變的過程,久而久之學生就慢慢地掌握了這項技能。
3.2 算法設計
經(jīng)過問題分析之后,學生就知道了需要做什么并會將大問題分解為幾個小問題,接下來就要進行算法設計,即如何解決這些問題。算法設計也是程序設計中的一項重要技能,是解決問題的關鍵步驟,但是一方面,大部分學生以前沒有任何編程基礎,不懂算法設計;另一方面,在通常的程序設計課程中,學生又得不到這方面的訓練。這樣導致的結果就是當學生拿到一個題目以后,雖然能夠看懂,但是完全沒有思路,不知道如何下手。
為了解決這個問題,筆者提出編程模式的概念。這個概念來自于中國武術中的“套路”,即對于一名武術選手,他平時的工作就是學習和練習各種各樣的套路,然后在與其他選手進行比賽時快速作出決定,在何種情形下應該使用何種套路。這正是一個新程序員在面對新的編程問題時應有的思路。因此,可以對一些常用的算法思路進行歸納和抽象,得到編程模式。
編程模式具有如下3個特征:
(1)獨立性:編程模式獨立于具體的編程問題,它是一組相似問題的歸納和概括;
(2)可重用性:一個編程模式可以應用在不同的編程問題中,可重用性是編程模式最重要的特征;
(3)抽象性:一個編程模式是一個算法的抽象,它的實現(xiàn)獨立于具體的編程語言,換言之,無論是C、Java還是其他編程語言都能使用。
典型編程模式的例子包括計算一組數(shù)據(jù)之和、尋找一組數(shù)據(jù)中的最大值或最小值、計算一組數(shù)據(jù)中每一項的出現(xiàn)頻率等。以“頻率計算”編程模式為例,它可能出現(xiàn)在不同的編程問題中。以下是一些例子。
(1)在一個電視選秀節(jié)目中,觀眾將通過手機投票的方式評選出十大歌手,請編寫一個程序,幫助組委會統(tǒng)計每一位歌手的得票數(shù);
(2)編寫一個程序,統(tǒng)計在莎士比亞的所有作品中每一個英文單詞的出現(xiàn)次數(shù);
(3)有一種文本加密方式是字母映射,即將一個英文字母映射為另一個英文字母,這樣原本有語意的句子就變成了一個雜亂無章的字符串,但這種加密方式可以通過統(tǒng)計字符出現(xiàn)的頻率破解,請編寫一個程序,統(tǒng)計在英文文本中26個字母的出現(xiàn)頻率。
以上這些編程問題表面上似乎各不相同,但實際上它們能夠使用相同的編程模式求解。有了編程模式以后,當學生再碰到一個新的編程問題時,雖然從表面上看該問題是新的,以前沒有見過,也不會做,但是可以采用上述自頂向下的分析技術將它分解為若干子問題,而每個子問題可以用以前曾經(jīng)學過的某個編程模式解決,最后再將它們綜合在一起即可,這樣學生分析問題、解決問題的能力就得到了提高。
筆者提出的編程模式概念實際上是國內外研究者提出的自頂向下設計技術的一種具體實現(xiàn)。通常的自頂向下技術只強調了要分解,但對于如何分解、分解到何種程度、分解以后的子問題如何解決等問題則沒有明確說明。筆者的改進主要體現(xiàn)在兩個方面:一是使問題的分解更具有可操作性,分解的原則或目標就是該子問題的大小合適,學生能夠解決;二是對于分解以后的子問題,學生能夠用以前學過的某個編程模式解決,這就提高了學生解決問題的能力。endprint
3.3 代碼編寫
在算法設計完成后,最后一個步驟就是編碼,即使用某種編程語言將該算法轉換為相應的源代碼。然而,對于毫無編程經(jīng)驗的學生來說,這并不是一件很容易的事情。事實上,即使學生已經(jīng)想到一個很好的算法,他也仍然有可能無法寫出正確的代碼,根本原因就是缺乏實踐以及足夠量的編碼訓練。
為了解決這個問題,筆者所在的團隊設計并實現(xiàn)了一個功能強大的在線訓練系統(tǒng),為全面提高學生的自學能力和動手實踐能力提供技術_上的保證。筆者始終認為,對于程序設計類課程,學生必須在練中學、用中學。如果單靠學生自己摸索、嘗試,那么效率會很低。因此,有必要為學生提供一個良好的訓練平臺,協(xié)助和促進他們進行實踐。該平臺以任務驅動的方式發(fā)布編程問題,學生只需登錄任何一臺聯(lián)網(wǎng)的電腦,就可以實現(xiàn)在線閱讀題目、編寫程序、編譯鏈接、運行、調試、提交程序,然后系統(tǒng)會自動對學生提交的源代碼進行驗證并立即返回結果。由于這種反饋是實時的,因此學生可以在系統(tǒng)的幫助下一步步完善自己的程序,這樣就大大提高了學習效率,并且由于是在線訓練系統(tǒng),無需人工干預,因此學生可以在任何時候學習任意長的時間,這樣,只要學生愿意,就能夠得到足夠量的編碼訓練。
在線訓練系統(tǒng)除了編碼訓練之外,還能讓教師將課程講義發(fā)布在網(wǎng)站上,學生可以下載或在線閱讀講義。此外,學生還能在網(wǎng)站上發(fā)表文章,討論問題;利用即時通信軟件相互交流。
4 實施效果
筆者的教學方法主要落實在兩門程序設計類課程上,一門是為軟件專業(yè)本科生開設的專業(yè)基礎課計算機語言與程序設計,另一門是給全校本科生開設的選修課計算機程序設計基礎。經(jīng)過近十年的教學實踐,筆者根據(jù)各方面的反饋情況,不斷進行更新和完善,目前教學已進入較為成熟和穩(wěn)定的階段,也取得了一些成果。
在專家評價方面,主講教師的教學理念得到專家認可,曾經(jīng)多次獲得教學方面的獎項。在學生評價方面,學生一直對相關課程給予較高評價。我們在歷年的教學評估中均進入了全校的前20%并多次進入到全校的前5%。
5 結語
計算機程序設計是大學生尤其是理工科學生必須掌握的一項基本技能,如何講好該課程,如何切實提高學生的分析問題、解決問題的能力,是每一位任課教師需要認真思考的問題。筆者提出的基于能力培養(yǎng)的程序設計課程教學方法,就是在這個方面的一種嘗試。未來的工作包括進一步完善案例教學和編程模式的概念,構建案例庫,提出更多、更實用的編程模式,完善在線訓練系統(tǒng),引入更多的功能,如代碼相似度檢查、學生在線活動數(shù)據(jù)分析等。
參考文獻:
[1]Riley D D.Teaching problem solving in an introductory computer science class[C]∥Proceedings of the 12th SIGCSE technical symposium on computer science education.New York:ACM.1981:244-251.
[2]Henderson P B.Anatomy of an introductory computer science course[C]∥Proceedings of the 17th SIGCSE technical symposium on computer science education.New York:ACM,1986:257-263.
[3]Ismail M N,Ngah N A,Umar I N.Instructional strategy in the teaching of computer programming:a need assessment analyses[J]. The Turkish Online Journal of Educational Technology,2010,9f21:125-131.
[4]Maheshwari P.Teaching programming paradigms and languages for qualitative learning[C]∥Proceedings of the 2nd Australasian Conference on Computer Science Education.New York:ACM.1997:32-39.
[5]Bonar J,Soloway E.Preprogramming knowledge:a major source of misconceptions in novice programmers[J].Human-Computer Interaction,1985,1(2):133-161.
[6]Ris R.Teaching eiffel as a first language[J].Journal of Object-Oriented Programming,1996(9):30-41.
[7]Chen W J,Li X,Lju W D.Teaching computer programming to non-computer science students[C]∥Proceedings of the 3rd Asian Conference on Education.Katahira:IAFOR Publications,2011:784-795.
[8]Chen W J,Li X,Liu w D.Teaching computer programming courses using programming patterns[C]∥Proceedings of the 20 1 2 3rd Intemational Conference On E-Business and E-Government.WashingtonD C:IEEE Computer Society,2012:606-609.
[9]shi K L,Chen W J,Zhang L,et al.Kaleidia:a practical e-learning platform for computer programming courses[C]∥Proceedings of the Canada International Conference on Education.Toronto:Infonomics Society,2012:103-108.
(編輯:宋文婷)endprint