張小國,祝雪芬
(東南大學(xué) 儀器科學(xué)與工程學(xué)院,江蘇 南京 210096)
卓越工程師教育培養(yǎng)計(jì)劃(簡稱卓越計(jì)劃)旨在培養(yǎng)造就一大批創(chuàng)新能力強(qiáng)、適應(yīng)經(jīng)濟(jì)社會(huì)發(fā)展需要的各類型高質(zhì)量工程技術(shù)人才,為國家走新型工業(yè)化發(fā)展道路、建設(shè)創(chuàng)新型國家和人才強(qiáng)國戰(zhàn)略服務(wù)。按照教育部的設(shè)想[1],卓越計(jì)劃具有3個(gè)特點(diǎn):①行業(yè)企業(yè)深度參與;②學(xué)校按通用標(biāo)準(zhǔn)和行業(yè)標(biāo)準(zhǔn)培養(yǎng)工程人才;③強(qiáng)化學(xué)生的工程和創(chuàng)新能力。顯然,卓越計(jì)劃的實(shí)施離不開具有卓越培養(yǎng)水平的大學(xué)教師。
目前,信息化技術(shù)已經(jīng)滲透到每一個(gè)工科領(lǐng)域,我國高校工科專業(yè)已普及程序設(shè)計(jì)課程,如何在課程教育中有效貫徹卓越計(jì)劃,值得每個(gè)教師深思。我國C++教育工作者對(duì)貫徹卓越工程師教育的理論方法進(jìn)行了大量的探索,典型如:①培養(yǎng)學(xué)生計(jì)算思維[2-4];②針對(duì)教學(xué)內(nèi)容與學(xué)科專業(yè)脫節(jié)的弊端,變革教學(xué)內(nèi)容的組織和設(shè)置[5],串聯(lián)教學(xué)內(nèi)容、方法和實(shí)踐[6-7];③針對(duì)以往教學(xué)實(shí)踐性不足的問題,研究貫徹卓越計(jì)劃的分階段教學(xué)模式[8-10];④研究基于案例、項(xiàng)目及問題導(dǎo)向的教學(xué)模式[11-12];⑤研究以學(xué)生算法邏輯訓(xùn)練和工程應(yīng)用能力培養(yǎng)為導(dǎo)向的考核方法[7,11]。上述探索研究有效培養(yǎng)了學(xué)生的計(jì)算思維能力、應(yīng)用能力和創(chuàng)新能力,推動(dòng)了高校工科計(jì)算機(jī)教育水平的提高。
程序設(shè)計(jì)語言課程旨在使工科學(xué)生深入理解使用計(jì)算機(jī)解決問題的基本原理與方法,學(xué)會(huì)科學(xué)計(jì)算和數(shù)據(jù)處理,樹立以算法為基礎(chǔ)的程序設(shè)計(jì)理念,鍛煉邏輯思維能力,為學(xué)習(xí)專業(yè)相關(guān)的信息處理技術(shù)打下基礎(chǔ)。
對(duì)照卓越計(jì)劃,筆者認(rèn)為程序設(shè)計(jì)與算法語言(C/C++)課程對(duì)應(yīng)的卓越工程師思維和能力應(yīng)體現(xiàn)在以下幾點(diǎn)。
程序設(shè)計(jì)課程實(shí)踐性強(qiáng),能否開發(fā)出滿足功能的程序是最直接的教學(xué)效果評(píng)判標(biāo)準(zhǔn)。通過課程學(xué)習(xí),學(xué)生應(yīng)具備將專業(yè)問題轉(zhuǎn)化為計(jì)算問題的能力,合理設(shè)計(jì)數(shù)據(jù)模型及數(shù)據(jù)結(jié)構(gòu),開發(fā)算法,實(shí)現(xiàn)計(jì)算機(jī)求解,這正是周以真教授提出的計(jì)算思維能力[13]。
軟件缺陷(bug)指軟件中破壞正常運(yùn)行的問題、錯(cuò)誤或隱藏的缺陷等??焖俣ㄎ籦ug并給出針對(duì)性解決方案,是軟件開發(fā)和維護(hù)的常態(tài)需求。軟件全生命周期往往涉及不同的開發(fā)和維護(hù)人員。在不熟悉整體架構(gòu)和代碼前提下,技術(shù)人員需要快速復(fù)現(xiàn)和定位bug并給出解決方案,這是本課程需著力培養(yǎng)的基本能力。
課堂教學(xué)難以面面俱到,卓越的內(nèi)涵還在于快速學(xué)習(xí)新知識(shí)、新技能并快速應(yīng)用。通過學(xué)習(xí)本課程,學(xué)生應(yīng)具備如下技能:①快速自學(xué)本編程語言相關(guān)知識(shí);②快速自學(xué)新計(jì)算機(jī)語言;③快速自行實(shí)現(xiàn)相關(guān)算法;④快速熟悉一個(gè)已有計(jì)算機(jī)系統(tǒng)等技能。
現(xiàn)代軟件大工業(yè)多用跨國、多地、并行開發(fā)模式,從需求、設(shè)計(jì)、代碼、測試、修復(fù)到后期維護(hù)都離不開人際交流,良好的計(jì)算機(jī)相關(guān)交流和交互能力是項(xiàng)目順利實(shí)施的保證。這種能力包含兩個(gè)層面的內(nèi)容:①良好的口頭和書面交流能力;②遵循工程實(shí)踐中成文及約定俗成的規(guī)范,保證編碼和文檔的可讀性和可維護(hù)性。
綜上,筆者參考在工業(yè)界7年實(shí)踐及學(xué)術(shù)界科學(xué)研究和系統(tǒng)開發(fā)的經(jīng)驗(yàn),在C/C++程序設(shè)計(jì)語言教學(xué)中,將前述4點(diǎn)需要著力培養(yǎng)的能力轉(zhuǎn)化為圖1右側(cè)的6種教學(xué)實(shí)踐與建議。
圖1 基于工程實(shí)踐視野的卓越工程師能力分析與能力培養(yǎng)對(duì)應(yīng)關(guān)系圖
教師對(duì)教學(xué)內(nèi)容的深刻理解是一切教學(xué)改革和實(shí)踐的根基。理清概念有助于學(xué)生深入理解知識(shí)點(diǎn),避免誤解,少走彎路。在教學(xué)過程中,既要避免照本宣科,又要反對(duì)故弄玄虛。教師應(yīng)盡量用淺顯直白的語言傳遞概念,用身邊的例子作比喻,充分使用學(xué)生已有的生活經(jīng)驗(yàn)作關(guān)聯(lián),引發(fā)有效聯(lián)想。例如指針章節(jié),可以將內(nèi)存分配比喻成到酒店住宿,把指針比喻成房卡;又如面向?qū)ο?,?qiáng)調(diào)派生的本質(zhì)在多數(shù)場合下就是類型細(xì)分,小類對(duì)象本質(zhì)上就是大類對(duì)象,派生類對(duì)象和基類對(duì)象的相互轉(zhuǎn)化規(guī)則也就了然于心了。
在教學(xué)過程中要有所側(cè)重,關(guān)鍵是傳遞學(xué)習(xí)方法和幫助學(xué)生總結(jié)提煉,澄清典型理解偏差,如不鼓勵(lì)學(xué)生記憶字符的ASCII值、大小寫字符的ASCII差值、I/O流輸出格式規(guī)范等,不鼓勵(lì)學(xué)生死記硬背運(yùn)算符的優(yōu)先級(jí)(建議學(xué)生多用括號(hào))等。
要達(dá)到上述效果,教師應(yīng)多學(xué)習(xí)國外先進(jìn)教材并深入研究C/C++規(guī)范,沒有捷徑。
算法可靈活、編碼須老實(shí)。編程者要牢記“程序是寫給別人看的”這一準(zhǔn)則,保證程序可讀可維護(hù)。大學(xué)新生多屬初次接觸編程,容易寫出不易識(shí)別的代碼。教師應(yīng)身體力行引導(dǎo),要及時(shí)指出學(xué)生編程中的不良習(xí)慣并督促其改進(jìn)。
(1)代碼書寫和展示遵循工業(yè)規(guī)范或約定俗成的規(guī)矩,采用名副其實(shí)而非莫名其妙的變量名、函數(shù)名、類名,讓人一目了然。
(2)介紹谷歌等公司的編碼規(guī)范,推薦一些書寫優(yōu)美的代碼,使學(xué)生感知編碼美學(xué)。
(3)組織學(xué)生討論評(píng)判不同的編碼風(fēng)格和編碼習(xí)慣,使之理解好和壞評(píng)判的內(nèi)在邏輯。
(4)引導(dǎo)學(xué)生把握整體架構(gòu),感知編碼的動(dòng)態(tài)演化過程,貫徹自頂向下的程序設(shè)計(jì)邏輯,展示在整體結(jié)構(gòu)把握上的代碼編寫方法論和整體美學(xué)。
邏輯缺陷和計(jì)算錯(cuò)誤是導(dǎo)致軟件bug的主因之一。幫助學(xué)生建立代碼安全(Security programming)和科學(xué)計(jì)算可信度(Reliability of scientific computing)的基本觀念,有助于學(xué)生平滑進(jìn)入科學(xué)研究和研發(fā)工作。
代碼安全涉及知識(shí)廣,課堂難以全面覆蓋,但可有選擇強(qiáng)調(diào)部分內(nèi)容,并實(shí)踐之。
(1)幫助學(xué)生建立全面的邏輯思維模型。講解基本語法時(shí),要提示學(xué)生考慮所有執(zhí)行分支,如if邏輯要考慮else,switch語句要考慮未被case捕捉而進(jìn)入default的情況,for循環(huán)要考慮循環(huán)何時(shí)開始、改變趨勢、終止條件,遞歸有無考慮終止條件等。
(2)強(qiáng)化學(xué)生對(duì)內(nèi)存分配的理解。C++不支持垃圾收集,程序靈活,客觀性上增加了bug產(chǎn)生的可能性,要讓初學(xué)者明白內(nèi)存分配和內(nèi)存銷毀的對(duì)應(yīng)關(guān)系,將bug扼殺在萌芽中。
(3)強(qiáng)調(diào)變量和指針的初始化。不初始化指針容易導(dǎo)致訪問野指針現(xiàn)象,不初始化變量容易將臟數(shù)據(jù)帶入執(zhí)行過程,因此要求對(duì)所有的指針和變量賦安全初值。
(4)讓學(xué)生評(píng)議自己作業(yè)中的典型錯(cuò)誤,引發(fā)討論和思考,加深他們對(duì)可能出現(xiàn)bug場景的認(rèn)識(shí),形成對(duì)邏輯完備的條件反射。
工科學(xué)生學(xué)習(xí)編程的主要目的是科學(xué)計(jì)算,而計(jì)算機(jī)采用有限二進(jìn)制表達(dá)現(xiàn)實(shí),誤差難免。本科學(xué)生很少接觸到計(jì)算方法或數(shù)值分析這類課程,因此需要對(duì)這類思維進(jìn)行有意識(shí)培養(yǎng)。在教學(xué)過程中,可用例程讓學(xué)生逐步建立可信計(jì)算的概念:
(1)整數(shù)除以整數(shù)等于整數(shù);
(2)比較兩個(gè)實(shí)數(shù)是否相等一般不直接用==比較;
(3)數(shù)字相加可導(dǎo)致向上溢出,比如平均值計(jì)算可能因?yàn)楹偷南蛏弦绯龆鲥e(cuò)等。
軟件缺陷難以杜絕是共識(shí)。軟件調(diào)試是對(duì)程序的排錯(cuò)過程,包括了編譯時(shí)和運(yùn)行時(shí)兩個(gè)階段,前者消除編譯期錯(cuò)誤,后者檢查運(yùn)行時(shí)缺陷。筆者在教學(xué)過程中發(fā)現(xiàn):①在學(xué)習(xí)早期,學(xué)生對(duì)語法不熟悉,容易受困于基本語法錯(cuò)誤而無法深入;②隨著學(xué)習(xí)的深入,學(xué)生可以成功編譯程序,但常?;ㄙM(fèi)成倍的時(shí)間定位和修改缺陷。這容易挫傷學(xué)生學(xué)習(xí)的積極性和自主性,使之產(chǎn)生畏難情緒。
在工業(yè)界,工程技術(shù)人員常常需要在對(duì)軟件整體非常不熟悉的情況下在極短時(shí)間內(nèi)完成bug修改。開發(fā)維護(hù)軟件中,處理一大堆不知道何人何時(shí)完成的歷史遺留代碼是工作常態(tài),這種能力已成為工業(yè)界判斷優(yōu)秀和平庸的標(biāo)準(zhǔn)。
筆者在教學(xué)工作中,主要采取了兩步法提高學(xué)生程序調(diào)試能力。
(1)在學(xué)習(xí)初期,以強(qiáng)化基本語法為主,采用雙語教學(xué)模式讓學(xué)生具備基本技術(shù)英語閱讀能力,引導(dǎo)學(xué)生自己理解編譯器報(bào)錯(cuò)和警告信息,讓學(xué)生對(duì)典型錯(cuò)誤建立起基本的概念,鼓勵(lì)學(xué)生通過幫助系統(tǒng)和互聯(lián)網(wǎng)查詢錯(cuò)誤原因并且搜尋相關(guān)解決方案。
(2)在學(xué)生對(duì)基本語法有一定素養(yǎng)的前提下,強(qiáng)化學(xué)生對(duì)動(dòng)態(tài)工程問題的定位能力,對(duì)軟件常見bug分類,言傳身教設(shè)置斷點(diǎn)、單步調(diào)試、watch變量等基本的調(diào)試方法,講解實(shí)例,分析原因,演示debug過程并講解關(guān)鍵技巧。
C++課程實(shí)踐性強(qiáng),涉及知識(shí)包羅萬象,課堂教學(xué)不是全部,應(yīng)避免灌輸式教學(xué),強(qiáng)化“做中學(xué)、學(xué)中做”,使學(xué)生在犯錯(cuò)中不斷進(jìn)步。
同時(shí),程序設(shè)計(jì)語言日新月異,教師需要在教學(xué)過程中強(qiáng)化學(xué)生對(duì)計(jì)算機(jī)語言特點(diǎn)、計(jì)算思維、算法的理解,讓學(xué)生學(xué)會(huì)一門語言就可以快速短時(shí)間掌握其他計(jì)算機(jī)語言、快速自己查詢資料、快速設(shè)計(jì)新算法,提高運(yùn)用能力。
(1)用問題的形式啟發(fā),讓學(xué)生自己親自驗(yàn)證和體驗(yàn),提高學(xué)習(xí)效果。
(2)避免有問必答的教學(xué),鼓勵(lì)學(xué)生用IDE help或網(wǎng)絡(luò)解決,并跟蹤過程。
(3)讓學(xué)生自學(xué)部分章節(jié),如C++流的部分細(xì)節(jié)內(nèi)容,鼓勵(lì)學(xué)生在編程中“做中學(xué)”。
(4)給有余力的學(xué)生提供一些相對(duì)高級(jí)教程或者推薦一些課外讀物,鼓勵(lì)其自由發(fā)展。
程序設(shè)計(jì)課程教學(xué)離不開上機(jī)實(shí)戰(zhàn),作業(yè)太容易難以鍛煉學(xué)生的能力,太難會(huì)打擊學(xué)生的積極性,總體上應(yīng)該合理安排、循序漸進(jìn),用容易的題目鞏固教學(xué)使學(xué)生積累信心,難一點(diǎn)的題目引發(fā)學(xué)生思考和接受挑戰(zhàn),從而讓學(xué)生真正并理解和掌握教學(xué)內(nèi)容。
在作業(yè)環(huán)節(jié),要重視工業(yè)界對(duì)信息化的需求,致力于提高學(xué)生的實(shí)踐能力和協(xié)作能力,對(duì)學(xué)生在實(shí)踐中暴露的問題,給予仔細(xì)的指導(dǎo)。
(1)強(qiáng)化對(duì)字符串、指針、動(dòng)態(tài)內(nèi)存分配的訓(xùn)練,將這種訓(xùn)練貫穿C++整個(gè)教育過程;
(2)強(qiáng)化對(duì)重要數(shù)據(jù)結(jié)構(gòu)的訓(xùn)練,要求學(xué)生對(duì)動(dòng)態(tài)數(shù)組、鏈表、隊(duì)列等數(shù)據(jù)結(jié)構(gòu)按STL標(biāo)準(zhǔn)接口編程實(shí)現(xiàn),使之掌握STL接口,對(duì)C++面向?qū)ο笏枷胗懈羁痰恼J(rèn)識(shí);
(3)設(shè)置大作業(yè)環(huán)節(jié)讓學(xué)生實(shí)踐本專業(yè)工程計(jì)算問題,從最基本的曲線擬合到方程求解、矩陣運(yùn)算,從報(bào)文處理到信號(hào)濾波,從圖形繪制到圖像處理等。
在教學(xué)實(shí)踐中,教師要高度重視作業(yè)方面的師生互動(dòng):一是對(duì)學(xué)生作業(yè)的典型問題重點(diǎn)講解和引導(dǎo);二是特定學(xué)生屢犯的錯(cuò)誤要針對(duì)性提醒。這種教學(xué)互動(dòng)可以及時(shí)了解學(xué)生對(duì)知識(shí)的掌握和運(yùn)用程度,并依據(jù)這些反饋信息及時(shí)調(diào)整教學(xué)內(nèi)容、方法和進(jìn)度。
教師對(duì)教學(xué)內(nèi)容本身的深刻理解、對(duì)實(shí)際工作技能需求的清晰認(rèn)識(shí),是任何教學(xué)改革和教學(xué)實(shí)踐的根基,離開了這一點(diǎn)討論卓越工程師思維培養(yǎng)或者教學(xué)改革是難以取得良好效果的。幾年的實(shí)踐表明,本文討論的這些執(zhí)行層面的教學(xué)方法取得了不錯(cuò)的教學(xué)效果,激發(fā)了學(xué)生的學(xué)習(xí)熱情并培養(yǎng)了動(dòng)手能力。以近3年為例,學(xué)生后續(xù)參加美國ACM、北斗杯等國際或國家級(jí)競賽獲特等和一等獎(jiǎng)10余項(xiàng)。
需要指出的是,實(shí)施上述教學(xué)方法不需要專門的時(shí)間單獨(dú)執(zhí)行,可以是分散穿插到日常的教學(xué)過程中進(jìn)行,并有意識(shí)針對(duì)性地應(yīng)用。這些舉措顯然無法承載卓越工程師培養(yǎng)的全部使命,但可以潛移默化提高學(xué)生在計(jì)算機(jī)方面的卓越工程師素養(yǎng)。