邵新慧 李響 劉成偉 張晟東
【摘 要】在考試系統(tǒng)中,實(shí)現(xiàn)自動(dòng)判卷是程序題考核設(shè)計(jì)的核心。圍繞該核心,開發(fā)設(shè)計(jì)“教師端程序題模板生成工具”、“學(xué)生端答題界面”、“服務(wù)端自動(dòng)判卷邏輯業(yè)務(wù)”三個(gè)子模塊,以確保每一個(gè)程序題都有一個(gè)全面而準(zhǔn)確的判卷模板與之對(duì)應(yīng),學(xué)生可以方便快捷地在可編輯區(qū)域編寫代碼并進(jìn)行測(cè)試和提交,判卷模板和學(xué)生代碼自動(dòng)組合并編譯成一個(gè)可執(zhí)行程序,從而得到判卷得分臨時(shí)數(shù)據(jù)文件,考試系統(tǒng)通過讀取該臨時(shí)數(shù)據(jù)得到判卷結(jié)果。
【關(guān)鍵詞】考試系統(tǒng) 程序題 自動(dòng)判卷 C語(yǔ)言 Java語(yǔ)言
隨著計(jì)算機(jī)技術(shù)的發(fā)展,越來越多的考試采用上機(jī)考試的形式。對(duì)選擇題、判斷題這類有固定答案的考試題型的判卷是很簡(jiǎn)單的;然而,對(duì)程序題這種表述形式多樣化的題型,很難通過自動(dòng)判卷給出合理的分?jǐn)?shù),多數(shù)是針對(duì)某一個(gè)運(yùn)行結(jié)果進(jìn)行判斷,未能滿足根據(jù)得分點(diǎn)進(jìn)行判卷的需求。本文通過詳細(xì)介紹“教師端程序題模板生成工具”、“學(xué)生端答題界面”、“服務(wù)端自動(dòng)判卷邏輯業(yè)務(wù)”三個(gè)模塊的設(shè)計(jì),闡述了程序題自動(dòng)判卷、以及合理評(píng)分的解決方案,在一定程度上提升了程序題考試的可行性、以及程序題判卷的合理性。
1 自動(dòng)判卷功能的設(shè)計(jì)方案
1.1 設(shè)計(jì)思路
由于考試系統(tǒng)的開發(fā)語(yǔ)言是面向?qū)ο笳Z(yǔ)言Java;程序題考核所用的語(yǔ)言為是C語(yǔ)言。所以很難通過代理模式實(shí)現(xiàn)對(duì)C語(yǔ)言程序的處理。因此,可將程序題判卷從系統(tǒng)整體設(shè)計(jì)中獨(dú)立出來,兩者之間通過某個(gè)簡(jiǎn)單的數(shù)據(jù)存儲(chǔ)建立聯(lián)系。
記事本文件(設(shè)為grade.txt)可作為上述的中介數(shù)據(jù)存儲(chǔ),其主要用于存儲(chǔ)學(xué)生得分記錄。一方面:系統(tǒng)可以讀取文件信息將得分記錄存入數(shù)據(jù)庫(kù);另一方面:grade.txt可以通過調(diào)用java.lang.Runtime實(shí)例的exec(String command)方法運(yùn)行某個(gè)可執(zhí)行文件(設(shè)為judgeMain.exe)來得到。而judgeMain.exe文件、也可以通過調(diào)用exec(String command)方法對(duì)某個(gè)源文件(設(shè)為judgeMain.cpp)進(jìn)行編譯和鏈接而生成。
其中,judgeMain.cpp文件是可以實(shí)現(xiàn)自動(dòng)判卷、并將得分紀(jì)錄寫入記事本的源代碼文件。因此,只要獲得judgeMain.cpp文件,自動(dòng)判卷問題就可以得到解決。
1.2 設(shè)計(jì)方案
1.2.1 核心方案
獲取judgeMain.cpp文件,使考試系統(tǒng)整體設(shè)計(jì)和程序題自動(dòng)判卷業(yè)務(wù)邏輯相對(duì)獨(dú)立,通過exec(String command)方法編譯、鏈接、運(yùn)行判卷程序。
1.2.2 judgeMain.cpp文件的獲取
假設(shè)A:每個(gè)用于學(xué)生考試的考試模板都有一個(gè)與之對(duì)應(yīng)的判卷模板,該判卷模板通過輸出流生成一個(gè)記事本文件,并且學(xué)生在考試模板里填寫的內(nèi)容可以自動(dòng)而正確地填寫到判卷模板里。
假設(shè)B、有一個(gè)簡(jiǎn)單可用的程序題模板生成工具,通過該工具,結(jié)合某個(gè)欲要考核算法或知識(shí)點(diǎn)的源代碼文件,能夠簡(jiǎn)單快速的生成一一對(duì)應(yīng)的考試模板和判卷模板。
假設(shè)C、有一個(gè)嚴(yán)格規(guī)范而且靈活簡(jiǎn)潔的程序題答題編譯界面,既方便學(xué)生填寫、編譯、運(yùn)行程序,而且可以準(zhǔn)確地將學(xué)生填寫區(qū)域的代碼上傳到服務(wù)器。
可見,假設(shè)B和C成立時(shí),A成立,從而可獲得judgeMain.cpp文件。
1.2.3 結(jié)論:開發(fā)以下兩個(gè)模塊支撐自動(dòng)判卷實(shí)現(xiàn)
(1)教師端程序題模板生成工具;(2)嚴(yán)格而便捷的學(xué)生斷答題界面。
1.2.4 根據(jù)以上分析,自動(dòng)判卷模板的原理可用圖1來描述
2 教師端程序題模板生成工具
2.1 功能實(shí)現(xiàn)
為實(shí)現(xiàn)程序題自動(dòng)判卷功能,設(shè)計(jì)程序題模板生成工具,并讓其實(shí)現(xiàn)以下功能:導(dǎo)入一個(gè)源文件, 生成一一對(duì)應(yīng)的考試模板、判卷模板,并為生成的考試、判卷模板提供瀏覽、測(cè)試功能,以便及時(shí)修改和調(diào)整。
2.2 設(shè)計(jì)方法
2.2.1 對(duì)導(dǎo)入源文件預(yù)處理
對(duì)源文件以注釋的形式添加一些特殊標(biāo)記,通過識(shí)別這些特殊標(biāo)記對(duì)源代碼自動(dòng)修改或增添。例如:
//code_fosOpen 開文件流標(biāo)記,在判卷模板中自動(dòng)增加定義記事本文件的輸出流代碼;
//code_fosClose 關(guān)文件流標(biāo)記,在判卷模板中自動(dòng)增加關(guān)閉文件流和釋放內(nèi)存代碼;
//code_judge 判卷變量標(biāo)記,設(shè)置得分點(diǎn);
//code_delete 挖空行標(biāo)記,所設(shè)置行變?yōu)橄聞澗€;
//edit_function 編輯函數(shù)標(biāo)記,設(shè)置函數(shù),由學(xué)生編寫函數(shù)體;
//code_resetInstance 修改用例標(biāo)記,為判卷模板和考試模板設(shè)置不同的測(cè)試用例。
2.2.2 判卷函數(shù)頭文件、靜態(tài)庫(kù)文件
功能:在判卷模板中將考生答案和正確答案進(jìn)行對(duì)比。
文件描述:
(1)頭文件(compare.h),文件內(nèi)容如右圖。(2)靜態(tài)庫(kù)文件(compare.lib),為compare.h中聲明的方法提供具體實(shí)現(xiàn)。
文件引用:
#include"compare.h"
#pragma comment(lib,"compare.lib")
2.2.3 模板生成工具設(shè)計(jì)
針對(duì)1中的不同標(biāo)記,該工具會(huì)自動(dòng)生成相應(yīng)的按鈕,通過點(diǎn)擊按鈕和簡(jiǎn)單的設(shè)置生成判卷、考試模板:
(1)判卷模板。點(diǎn)擊按鈕實(shí)現(xiàn)函數(shù)體編寫、代碼段填空、判卷變量的選擇,通過對(duì)判卷變量正確值的設(shè)置、以及判卷代碼插入位置的設(shè)置,可預(yù)覽、測(cè)試、生成判卷模板。
(2)考試模板。在判卷模板設(shè)置的基礎(chǔ)上,通過對(duì)測(cè)試用例進(jìn)行修改,可預(yù)覽、測(cè)試、生成考試模板,并具有相應(yīng)題目說明文件的編寫功能。
2.3 原理解釋與圖解
現(xiàn)結(jié)合一個(gè)簡(jiǎn)單的例子對(duì)模板生成工具的原理進(jìn)行解釋,并用圖解展示:
第一步:選擇載入用于生成考試、判卷模板的.cpp源文件,然后根據(jù)按鈕提示,選擇挖空行、編輯函數(shù)、判卷變量等,并根據(jù)提示進(jìn)行必要的設(shè)置(見圖3)。
附:為便于說明問題,此處以一個(gè)求取平方數(shù)的簡(jiǎn)單程序?yàn)槔?,本例中只有一個(gè)判卷變量(對(duì)應(yīng)一個(gè)得分點(diǎn))的設(shè)置,對(duì)于較復(fù)雜的程序,可以設(shè)置多個(gè)得分點(diǎn)。
第二步:點(diǎn)擊“預(yù)覽”菜單對(duì)將要生成的判卷模板進(jìn)行預(yù)覽,初步查看是否正確,然后點(diǎn)擊“測(cè)試”菜單選擇對(duì)判模板進(jìn)行自動(dòng)編譯運(yùn)行,若正常運(yùn)行,轉(zhuǎn)步驟三;若失敗,根據(jù)編譯運(yùn)行的錯(cuò)誤提示,返回步驟一進(jìn)行修改設(shè)置。
第三步:點(diǎn)擊“生成”菜單,選擇保存位置,即可生成判卷模板(見圖4)。
第四步:進(jìn)行用例修改,修改后的用例用于生成學(xué)生考試模板(見圖5)。
第五步:預(yù)覽、測(cè)試運(yùn)行,最終生成考試模板,并根據(jù)運(yùn)行結(jié)果編寫題意說明文件(見圖6,圖7)。
3 學(xué)生端答題界面
3.1 功能要求
為嚴(yán)格保證自動(dòng)判卷的實(shí)現(xiàn),同時(shí)滿足學(xué)生方便答題需求,學(xué)生端答題界面須滿足如下功能要求:
(1)無需啟動(dòng)客戶端編譯器,學(xué)生直接在答題界面的可編輯區(qū)域編寫代碼,其他區(qū)域的代碼無法修改;(2)具有便捷的編譯運(yùn)行程序的功能,并提示編譯或運(yùn)行錯(cuò)誤;(3)學(xué)生編寫的函數(shù)體和填寫的代碼段可準(zhǔn)確無誤上傳至服務(wù)端。
3.2 實(shí)現(xiàn)方法要點(diǎn)
3.2.1 答題界面
(1)將題意說明和不可修改的源代碼部分顯示為只讀;(2)識(shí)別考試源代碼中的“//添加函數(shù)實(shí)現(xiàn)代碼”字段,以及填空標(biāo)記下劃線“_________________”,將對(duì)應(yīng)區(qū)域設(shè)置為可編輯;(3)在可編輯區(qū)域?qū)?yīng)的控制程序中添加鍵盤監(jiān)聽:實(shí)現(xiàn)對(duì)括號(hào)、引號(hào)的自動(dòng)配對(duì),以及換行時(shí)提供自動(dòng)縮進(jìn),為學(xué)生快速編寫格式規(guī)范的代碼提供方便。
3.2.2 編譯運(yùn)行
通過java.lang.Runtime實(shí)例的exec(String command)方法,啟動(dòng)獨(dú)立進(jìn)程調(diào)用編譯和鏈接命令,并獲取該進(jìn)程的輸入流,提取編譯鏈接過程中的錯(cuò)誤信息,實(shí)現(xiàn)編譯錯(cuò)誤提示;若編譯正確,則運(yùn)行程序。
3.2.3 上傳代碼
由于僅提取學(xué)生編寫的函數(shù)題代碼和學(xué)生填空代碼段,只需提取可編譯區(qū)域的文本記錄即可,而且信息量小,因此可采用一般socket通信的形式(不用文件上傳等形式)將代碼段上傳至服務(wù)端。
3.3 例子與圖解
(1)將2中得到的考試模板和題意說明文件用于學(xué)生考試端程序題考試(如圖8);
(2)在函數(shù)編寫區(qū)域編寫代碼,將填空橫線刪除并填寫代碼,然后直接點(diǎn)擊編譯運(yùn)行(圖9)。
(3)根據(jù)錯(cuò)誤提示修改代碼,重新編譯運(yùn)行(圖10)。
(4)點(diǎn)擊交卷后,學(xué)生編寫的函數(shù)體和填空代碼行上傳至服務(wù)器(圖11)。
4 服務(wù)端自動(dòng)判卷邏輯業(yè)務(wù)
4.1 自動(dòng)判卷業(yè)務(wù)設(shè)計(jì)
基于模板生成工具、學(xué)生答題客戶端的設(shè)計(jì)和實(shí)現(xiàn),自動(dòng)判卷邏輯業(yè)務(wù)設(shè)計(jì)如下:
(1)一般情況下:只需把學(xué)生上傳的答題信息寫入相應(yīng)的判卷模板中,然后生成臨時(shí)判卷源文件,針對(duì)這個(gè)臨時(shí)文件編譯運(yùn)行即可得到判卷結(jié)果。
(2)異常情況:如果學(xué)生提交的程序沒來得及調(diào)試正常而存在死循環(huán),需要在A的基礎(chǔ)上進(jìn)行如下改進(jìn):
通過倒計(jì)時(shí)線程啟動(dòng)判卷程序,倒計(jì)時(shí)線程結(jié)束后,若判卷程序還在運(yùn)行,則殺死,并將異常記錄寫入數(shù)據(jù)庫(kù)。
邏輯圖如下(圖12)。
4.2 評(píng)分過程
在考試、判卷模板制作過程中,可以根據(jù)每個(gè)題目的實(shí)際情況設(shè)計(jì)判卷(得分)變量,并針對(duì)每一個(gè)判卷變量考核知識(shí)點(diǎn)難度設(shè)置得分權(quán)重(學(xué)生不知道具體的得分變量和權(quán)重)。然后,將學(xué)生上傳的代碼插入到判卷模板中,生成judgeMain.cpp,針對(duì)每個(gè)得分點(diǎn)都會(huì)調(diào)用compare函數(shù)比較學(xué)生答案和標(biāo)準(zhǔn)答案,得到一個(gè)布爾型返回值,然后根據(jù)這個(gè)返回值在記事本文件(grade.txt)里寫入1(得分)或0(不得分)。
該自動(dòng)判卷程序可滿足對(duì)一個(gè)程序題進(jìn)行細(xì)節(jié)得分點(diǎn)的判斷,而不是籠統(tǒng)的僅僅判斷最終答案,在一定程度上保證了給分的合理性。
5 結(jié)語(yǔ)
通過上述方案設(shè)計(jì)的程序題考核與判卷模塊,是東北大學(xué)數(shù)值分析考試系統(tǒng)(可通過程序題考核學(xué)生對(duì)數(shù)值算法的理解與應(yīng)用能力)的重要組成部分,該考試系統(tǒng)的測(cè)試結(jié)果和初期使用情況證明:對(duì)于程序題考核和自動(dòng)判卷,這樣的設(shè)計(jì)方案是可行的、對(duì)判卷過程中的常處理是可行的,最終判卷結(jié)果是合理的。
參考文獻(xiàn):
[1]申田靜.國(guó)內(nèi)在線考試系統(tǒng)研究綜述[J].中國(guó)教育技術(shù)裝備,2015(14):19-21.
[2]馮山,許毅,朱大勇.Visual C++集成開發(fā)環(huán)境中編譯鏈接中間文件的管理及其空間回收.四川師范大學(xué)學(xué)報(bào):自然科學(xué)版,2003,26(2):205-208.
[3]高洪巖. Java多線程編程核心技術(shù).北京:機(jī)械工業(yè)出版社,2015.
作者簡(jiǎn)介:邵新慧(1970—),女,山東青島人,副教授,博士,教師,數(shù)值代數(shù)理論與應(yīng)用研究。