王勇剛
(云南大學 旅游文化學院,云南 麗江 674199)
程序設計類課程是計算機類專業(yè)學生必修的核心課程。在計算機類專業(yè)中一般作為學生入門級的課程,地位非常重要。該課程對于計算機類學生后續(xù)專業(yè)課程知識的學習起著舉足輕重的作用,但往往也是這門課程將計算機類專業(yè)的學生擋在了門外。這很大程度上都源于只重視某門程序設計語言本身的語法講解和應用。盡管有些教師研究了一些比較好的教學方法,能使大部分學生學好一門程序設計語言,但遇到其它類型的程序設計語言時絕大部分學生很難達到無師自通的水平。因此,有些學校的人才培養(yǎng)方案中開出多門程序類的課程,以求學生能掌握更多的程序設計工具,可結(jié)果卻事與愿違。
目前許多高校普遍開設了各種高級程序設計語言課程,如 Pascal、C、C++,甚至部分高校開設了 Java、C#、Lisp、Prolog等程序設計語言課程[1]。這些語言中哪一門課程作為入門級的程序設計課本身就存在很大的分歧。Java作為入門級教學語言就存在不少爭議[2],有人認為C作為入門級語言已經(jīng)滯后[3],等等。筆者認為無論哪種語言,它們都有相通之處——計算思維。其目的都是要培養(yǎng)學生分析問題、解決問題的編程能力。而這種能力的培養(yǎng),不同程序設計語言只是方式方法上略有不同。例如命令式的書寫方式、面向?qū)ο蟮脑O計方法、函數(shù)式程序設計、邏輯式程序設計等。筆者所在的學校就以《Java程序設計》作為大一新生的入門級程序設計課程。
筆者所在的學校以培養(yǎng)應用型人才為目標,但又不同于職業(yè)教育。主要區(qū)別在于高職教育崗位遷移能力和發(fā)展后勁不足,而應用型本科教育過度強調(diào)系統(tǒng)理論學習,實踐能力不足[4]。其主要原因就是應用型本科類的專業(yè)教學實踐時間遠不及職業(yè)教育。因此計算思維的能力培養(yǎng)顯得尤為重要。
一個專業(yè)的人才培養(yǎng)方案以及由此而確定的專業(yè)課程是一個完善的體系,各門課程前后往往有著密切的聯(lián)系。但是各門課程的授課教師往往只是對本門課程研究比較深入,而忽略了課程之間的聯(lián)系。這就使得學生在學習程序設計語言課程時視野狹窄,看不到它在今后的學習甚至是工作中會有哪些更深入的應用。當然有限的課時以及入門級的學生還不具備學習這些知識的能力,但要通過這門課程的學習使學生具有初步的了解,從而提高學生的學習興趣。
《沉浸式項目教學法在JAVA課程中的應用》中強調(diào)學生的專注度,通過激發(fā)學生的興趣引導學生進行全身心的投入[5]?!抖嘣己朔绞皆贘ava程序設計課程中的應用研究》中介紹通過多種有效考核的方式,以能力考核為重點,來激勵學生學習[6]。《“案例驅(qū)動+項目導向”的Java程序設計課程教學模式研究》中以項目驅(qū)動的方式來組織教學[7]?!禞ava程序設計課程開放式教學》中通過課程第一堂課組織、核心課程網(wǎng)站建設、優(yōu)秀學生上臺展示演講、軟件大賽引導、校企聯(lián)合實訓、系統(tǒng)大作業(yè)訓練等形式,采用開放式的形式組織教學[8]。《CDIO工程教育模式下的主動式項目驅(qū)動學習——以“Java程序設計”課程為例》中強化實踐教學,增強職業(yè)能力,培養(yǎng)合格的軟件工程師為目標[9]。以上這些方法對于剛?cè)雽W的大一新生來說都很難實施,因為學生連打字都還不嫻熟,又如何要求他們有能力去達到這些教學方法中的要求呢?《基于計算思維的Java程序設計課程教學實踐》中雖然強調(diào)了計算思維的重要性,但也只是通過強化實踐訓練來達到教學目標,可結(jié)果并不樂觀[10]。《基于計算思維的Java程序設計教學改革》中同樣也只是強調(diào)實例強化突破教學瓶頸[11]?!兑浴坝嬎闼季S”為導向的程序設計入門類課程改革探索》中提出了“流程圖+算法設計”的方法,結(jié)合圖形形象思維以提高學生的編程能力,但也并未對計算思維的過程進行梳理[12]。
首先,大一剛?cè)雽W的新生大部分未深入接觸過計算機,對計算機的認知比較粗淺,一開始就學習程序設計這類核心難度較大的專業(yè)課程,本身就是一道難以逾越的學習屏障。其次,各種創(chuàng)新教學方法的提出,針對學生進行創(chuàng)新能力的培養(yǎng),筆者認為這都高出了新生能夠認知和接納的范圍。創(chuàng)新能力是基于專業(yè)基礎知識能力的,沒有扎實的基礎空談創(chuàng)新能力,都是無本之源。此外,一個企業(yè)級的專業(yè)人才是在本行業(yè)進行長期實踐的過程中逐步成長起來的,僅僅依靠項目驅(qū)動式教學的方式來提高學生的實踐應用能力,只能是杯水車薪、效果甚微。最后的結(jié)果就是學生只是了解了一些零散的知識,沒有形成有效的計算思維能力,實踐能力更是蒼白乏力。
君子務本,本立而道生。首先,要針對新生的特點和課程在教學體系中的地位,確定教學目標及教學內(nèi)容的取舍。其次,學生計算機知識能力還停留在“零”的水平,高大上的東西還只能遠觀而不可褻玩。此外,學生以前形成的學習思維方式與計算思維方式有很大的區(qū)別,思維方式的轉(zhuǎn)變與形成,成為本門課程教學需要突破的關鍵問題。
對程序設計類課程而言,編程能力是計算思維和技能化知識的綜合體現(xiàn)。計算思維正確與否也必須經(jīng)過實踐的檢驗[13]。而計算思維是運用計算機科學的基礎概念進行問題求解、系統(tǒng)設計以及人類行為理解等涵蓋計算機科學之廣度的一系列思維活動[14]。
筆者以《Java程序設計》課程教學為例,通過多年的實踐摸索提出一種基于計算思維的分模塊教學方法。該方法的特點是重計算思維梳理,按計算機解決問題的步驟,分模塊依次進行教學,再輔以簡單的程序設計案例題,以數(shù)學思維和計算思維兩種方式相融合進行解題,以此來提高學生對數(shù)學思維和計算思維的認知,并迅速完成數(shù)學思維到計算思維的轉(zhuǎn)變與形成。
該專業(yè)人才培養(yǎng)方案將《Java程序設計》作為新生入門級程序設計語言課程,沒有任何的先修課程作為輔助,后續(xù)課程主要有Java Web、Android應用開發(fā)、J2EE等。鑒于此,本門課程的培養(yǎng)目標為培養(yǎng)學生的計算思維和編程能力。教學內(nèi)容從過程控制開始,到面向?qū)ο蟮某绦蛟O計方法為止,主要以命令行的形式組織教學。而Java機制下的其它應用任務交由后續(xù)相關課程去完成,但必須讓學生清楚地了解到后續(xù)課程的相關要求。
很多教師在進行程序課程教學的時候,往往一開始就從簡單的語法規(guī)則入手,附加一些程序案例,想讓學生通過潛移默化的過程慢慢地從中領悟計算思維的方式,并形成一定的程序設計能力。基本上所有的教程書籍也都是以這樣的方式來組織的。筆者以程序設計解決實際問題的流程入手,一開始就給學生梳理計算思維的全過程,然后分模塊各個擊破,最終達到教學目標的要求,能培養(yǎng)學生較強的程序設計語言的遷移能力,使他們了解無論使用何種編程語言,其過程都是類似的。
(1)程序設計的流程分析
程序設計的目的就是編寫程序控制計算機,讓它來為人類解決實際問題,其流程如圖1所示。
圖1 程序設計的一般流程
(2)模塊劃分
在程序設計的流程分析中,分析問題、抽象事物、描述數(shù)據(jù)三個方面融入到了編程實踐的過程中,與程序設計的具體實施緊密相連,因此它們是貫穿于編程實踐的過程中。模塊的劃分如表1所示。
表1 授課內(nèi)容模塊劃分
模塊的劃分根據(jù)程序設計的基本流程進行,其特點與筆者通過文獻檢索或者訪問交流中了解的內(nèi)容相比,有以下特點:
①任何一門語言其涉及面都很廣泛,如果作為新生入門級的程序設計課程不應該也不可能全方位的講解。
因此從培養(yǎng)學生計算思維能力的角度入手,在內(nèi)容的取舍上,筆者立足于面向過程的流程控制編程能力的培養(yǎng)和面向?qū)ο蟮目刂婆_應用技術(shù)能力的培養(yǎng)兩方面。其它應用領域的內(nèi)容放在擴展認知中,即只是蜻蜓點水般地給學生提一提,留下懸念,并指導其在今后的專業(yè)學習中什么時候或哪些地方可以學到、用到。
例如,在講解數(shù)據(jù)如何存儲、存儲在哪里的時候,首先,從最簡單的單變量數(shù)據(jù)存儲開始,讓學生編寫一個小程序,將Java提供的所有基本類型都申請一個變量,從鍵盤輸入一個原始數(shù)據(jù),然后將其輸出,并告之內(nèi)存空間是存放數(shù)據(jù)的地方。此處不對數(shù)據(jù)進行任何的處理,只是讓學生知道如何輸入一個簡單數(shù)據(jù),如何存儲在內(nèi)存變量中,又如何將其進行控制臺輸出。此后,一般教師的做法就會講解基本運算、基本控制語句等內(nèi)容,但筆者卻不是如此,而是馬上向?qū)W生提出幾個問題:除了內(nèi)存中可以存放數(shù)據(jù),哪些地方還可以存放數(shù)據(jù)呢?一個變量只能存儲一個簡單的數(shù)據(jù),那么如何存儲一系列數(shù)據(jù)呢?Java程序設計語言提供了這樣的方式來操作,其它語言肯定也要提供這樣的操作,其做法會有什么不同呢?這些問題馬上就把學生引入到了計算思維的領域中來,而問題的回答不會深入地去講解如何解決這些問題,而是引導學生將來在哪些課程中會接觸到。于是就在擴展認知中提出。之后,順理成章地進入到批量數(shù)據(jù)的存儲模塊。馬上講解數(shù)組是如何定義存儲數(shù)據(jù)的,如何把里面的數(shù)據(jù)讀取顯示出來。同樣以一個簡單的程序來實踐數(shù)組的定義、數(shù)據(jù)輸入、數(shù)據(jù)顯示操作。實踐完成后又立即拋出一些問題:數(shù)組空間可以有多大?內(nèi)存有多大?存不下了該怎么辦?一臺電腦可以存多少數(shù)據(jù)?一臺電腦可以直接接入多少外存?多個電腦是否可以存放同一應用中的數(shù)據(jù)等等,這些問題就會引導學生去了解現(xiàn)在有哪些技術(shù)是用來解決這些問題的,讓學生對將來的專業(yè)學習有一個清醒的體系認識,了解這些技術(shù)都與程序設計有關。
②模塊的劃分并不是以Java程序設計語言本身的結(jié)構(gòu)進行,而是根據(jù)程序設計的基本流程進行。
程序設計處理的對象是數(shù)據(jù),自然要解決的問題就是數(shù)據(jù)如何描述,之后如何存儲、如何處理、如何輸出。因此不論哪種程序設計語言都要想辦法解決這些問題,只是方式方法略有不同。所以,首先從程序設計語言提供的基本處理操作入手,了解表達式、語句等一系列最底層的操作,并告之無論哪種程序設計語言一開始都是如此。之后引入流程控制的三種結(jié)構(gòu)。然后講解將復雜的操作分成不同模塊進行處理。之后又引入封裝技術(shù),將復雜的數(shù)據(jù)和模塊分類表示,從而引入面向?qū)ο蟮奶幚矸绞健0凑者@樣的流程一步一步地將知識傳授給學生,而不是單單介紹Java程序設計語言是如何做的。
③計算思維直接就從劃分的模塊過程中完美地體現(xiàn)出來。
模塊的劃分直接以程序設計的流程來進行,而這個流程也直接反應了計算思維的過程。計算機處理的任何對象都可以看成是數(shù)據(jù)的某一種形式。而任何數(shù)據(jù)在計算機中都有一個最原始的表示形態(tài),其存儲只是存在不同方式、不同位置等差別。對數(shù)據(jù)的處理也都是由最基本的語句指令通過不同的流程控制結(jié)構(gòu)進行模塊劃分和封裝之后來進行,一切的處理過程最終都將回歸到計算機提供的指令系統(tǒng)來完成。按照這樣的方式,學生對計算思維的過程很容易就有了一個簡單明了的印象,并對程序設計的底層編程能力有了一個全面的認知和掌握,也使得各種程序語言工具之間的遷移能力有了顯著的提高。自從按照這樣的方法進行程序設計語言課程的教學后,后續(xù)課程教學的教師反饋給筆者的信息是學生學習能力相比以前有了很大的改觀。
④所有教學實踐案例都以最簡單的形式進行,并未像其它教師一樣采用項目驅(qū)動式或者大型案例系統(tǒng)的方式組織。
筆者在網(wǎng)絡上檢索的“趣味編程100例”和“奧數(shù)網(wǎng)”上大量的題目作為學生實踐應用的案例。這些題目都比較簡短,但都能充分體現(xiàn)學生最底層的程序設計處理能力,并且大量題目都能體現(xiàn)數(shù)學推理與計算思維之間的區(qū)別與聯(lián)系,從而使學生能夠更好地理解數(shù)學思維與計算思維的方式方法,并最終能讓學生充分掌握計算思維的應用。
學生一直以來接觸的都是數(shù)學思維的培養(yǎng),而計算思維雖然與之有很大的聯(lián)系,但又有巨大的差別,因此筆者在組織教學的過程中經(jīng)常用這兩種思維方式來指導學生進行編程實踐。以下例舉一個具體的實例來與大家進行分享。
例題:有甲、乙、丙三人同時同地出發(fā),繞一個花圃行走,乙、丙二人同方向行走,甲與乙、丙相背而行。甲每分鐘走40米,乙每分鐘走38米,丙每分鐘走36米。在途中,甲和乙相遇后3分鐘和丙相遇。問:這個花圃的周長是多少米?
學生遇到這樣的題目,不自主地肯定是以數(shù)學思維的方式來解答,筆者就順應學生已有的思維方式來進行。
首先,假設周長為L,甲與乙相遇的時間為t。從而得到甲與乙相遇時周長可表示為:L=(V甲+V乙)×t。甲與乙相遇時周長可表示為:L=(V甲+V丙)×(t+3)。 其中:V甲、V乙、V丙分別表示甲乙丙的速度。之后換算得到求t的表達式:t=(3V甲+3V丙)÷(V乙-V丙),最后得到 L的值。 編程實現(xiàn)后,就讓學生思考,這樣的方式還需要自己去進行推導,換算相應的表達式,那么有沒有更好的方式讓計算機自己去求解呢?
然后,提出用計算思維方式去求解這道題目。同樣假設周長為L,甲與乙相遇的時間為t,并將t賦值為1,即假定兩人相遇至少要花1分鐘的時間。然后利用這個時間t去計算甲與乙相遇時走過的路程,再計算t+3分鐘后甲與丙走過的路程,最后利用循環(huán)結(jié)構(gòu)判斷這兩個路程是否相等,若不等則將t的值增1,繼續(xù)循環(huán),若相等則循環(huán)結(jié)束,從而得到的t就表示甲乙兩者相遇所用的時間,之后計算出花圃的周長。程序如下:
以上通過編寫程序求解簡單問題的兩種思維方法清晰明了地給學生展現(xiàn)了數(shù)學思維方式和計算思維方式的不同。學生通過這樣的簡單應用案例,從中更容易接受和掌握計算思維在程序設計過程中的體現(xiàn)。相比文中開始部分提及的各種教學方法,更適合入門級學生對程序設計語言課程的了解和掌握。
本文提出的基于計算思維程序設計的教學方法更注重幫助學生對該思維方式的疏通和引導,通過簡單程序設計應用解題,直接將傳統(tǒng)的思維方式和計算思維方式的解題過程對比,使學生輕而易舉地掌握計算思維的過程,并明確地了解與傳統(tǒng)思維方式的差別。通過兩年的教學實踐和高年級教師的教學反饋,驗證了該方法更適合新生入門級程序設計課程的教學。