鐘耀章,桂 瓊
(桂林理工大學(xué),廣西 桂林 541006)
ACM國(guó)際大學(xué)生程序設(shè)計(jì)競(jìng)賽是由國(guó)際計(jì)算機(jī)協(xié)會(huì)(ACM)主辦的,比賽一般會(huì)有7~13個(gè)題目[1]。三個(gè)人一隊(duì),共同使用一臺(tái)電腦,需要在5個(gè)小時(shí)內(nèi)使用C/C++、Java和Python中的一種來(lái)編寫(xiě)程序從而解決問(wèn)題。在線測(cè)評(píng)系統(tǒng)(Online Judge,OJ)先前的目標(biāo)是為了鍛煉參加ACM國(guó)際大學(xué)生程序設(shè)計(jì)競(jìng)賽的參賽者們。除此之外,在實(shí)際的計(jì)算機(jī)教學(xué)環(huán)境中也起到了很大的作用,學(xué)生在學(xué)習(xí)計(jì)算機(jī)基本算法或者數(shù)據(jù)結(jié)構(gòu)類(lèi)似課程的過(guò)程時(shí),常常不能知道自己設(shè)計(jì)的算法和實(shí)現(xiàn)的代碼是否完全正確而不能做出正確的判斷。特別是一些剛?cè)腴T(mén)的程序設(shè)計(jì)愛(ài)好者常常不能對(duì)自己所寫(xiě)的程序有一個(gè)很好的認(rèn)識(shí),在線測(cè)評(píng)系統(tǒng)憑借著嚴(yán)格的判題體系和大量的測(cè)試數(shù)據(jù)的優(yōu)勢(shì)完美地解決了這個(gè)問(wèn)題。在線測(cè)評(píng)系統(tǒng)對(duì)比人工評(píng)判有著如下的優(yōu)勢(shì):(1)效率高,人工評(píng)判時(shí)間漫長(zhǎng),不能讓學(xué)生及時(shí)地了解到自己那些方面的不足,在線測(cè)評(píng)只需要幾秒鐘就能完成測(cè)評(píng)并實(shí)時(shí)將結(jié)果反饋給用戶。(2)使用方便,你只需要有一臺(tái)能聯(lián)網(wǎng)的電腦就可以進(jìn)行算法訓(xùn)練,并且題目多樣性,大大提高學(xué)生的興趣。(3)公平性,不會(huì)存在人為主觀因素,系統(tǒng)是拿測(cè)試數(shù)據(jù)進(jìn)行對(duì)比。本系統(tǒng)旨為算法愛(ài)好者提供一個(gè)在線學(xué)習(xí)、交流的平臺(tái)。
本次要開(kāi)發(fā)的ACM競(jìng)賽在線測(cè)評(píng)系統(tǒng)分為三個(gè)模塊:前臺(tái)服務(wù)模塊、后臺(tái)管理模塊、后臺(tái)測(cè)評(píng)模塊[2]。前臺(tái)服務(wù)模塊有:用戶注冊(cè)登錄、用戶找回密碼、修改個(gè)人信息、用戶排名、題目預(yù)覽、查看提交代碼和報(bào)名競(jìng)賽等。后臺(tái)管理模塊有:用戶管理、比賽管理、題目管理和管理員注冊(cè)登錄等。后臺(tái)測(cè)評(píng)模塊有:代碼處理、代碼編譯、代碼測(cè)試。系統(tǒng)總體框圖如圖1所示。
圖1 ACM競(jìng)賽在線測(cè)評(píng)系統(tǒng)總體框圖
前臺(tái)服務(wù)模塊指的是本系統(tǒng)普通用戶使用的模塊,就是用戶打開(kāi)瀏覽器輸入本系統(tǒng)的url即可訪問(wèn)到系統(tǒng),前臺(tái)服務(wù)模塊如圖2所示。
圖2 前臺(tái)服務(wù)模塊
(1)用戶注冊(cè):使用本系統(tǒng)需要注冊(cè)一個(gè)用戶,輸入學(xué)號(hào),密碼,名字,學(xué)校,專(zhuān)業(yè)班級(jí),QQ,郵箱等。
(2)用戶登錄:使用本系統(tǒng)必須先登錄,如果想要通過(guò)url的方式直接訪問(wèn)本系統(tǒng),也會(huì)被系統(tǒng)攔截器攔下來(lái)。
(3)用戶找回密碼:當(dāng)用戶忘記自己的密碼時(shí),可以通過(guò)注冊(cè)時(shí)的學(xué)號(hào)和郵箱來(lái)修改新的密碼。
(4)修改個(gè)人信息:用戶可以修改除了學(xué)號(hào)的其他基本信息。
(5)用戶排名:用戶可以查看自己在本系統(tǒng)的排名,根據(jù)你的解題數(shù)和你的提交次數(shù)做一個(gè)排名。
(6)題目預(yù)覽:用戶點(diǎn)擊題目按鈕時(shí),系統(tǒng)會(huì)以每頁(yè)10題的方式來(lái)顯示當(dāng)前系統(tǒng)的所有題目。
(7)查看提交代碼:當(dāng)用戶提交代碼后,系統(tǒng)會(huì)把用戶提交的代碼、運(yùn)行時(shí)間、測(cè)評(píng)狀態(tài)、提交時(shí)間和使用的語(yǔ)言等信息存儲(chǔ)起來(lái),用戶可以查看本題提交狀態(tài)和查看提交的代碼,也可以查看其他用戶提交的信息。
(8)報(bào)名競(jìng)賽:用戶可以報(bào)名正在進(jìn)行的競(jìng)賽。
后臺(tái)管理模塊是屬于管理員的模塊,可以對(duì)用戶、題目和競(jìng)賽進(jìn)行管理,后臺(tái)管理模塊如圖3所示。
圖3 后臺(tái)管理模塊
(1)管理員注冊(cè):如果想登錄系統(tǒng)的后臺(tái)管理頁(yè)面,需要注冊(cè)一個(gè)系統(tǒng)管理員用戶。
(2)管理員登錄:必須要登錄才能訪問(wèn)系統(tǒng)后臺(tái)管理模塊,如果直接通過(guò)url的方式訪問(wèn)后臺(tái)頁(yè)面,也會(huì)被攔截器攔截并且跳轉(zhuǎn)到登錄頁(yè)面。
(3)用戶管理:管理員可以查看用戶,并且對(duì)其進(jìn)行修改刪除操作。
(4)題目管理:管理員可以為系統(tǒng)新增題目、修改題目和刪除題目。
(5)競(jìng)賽管理:管理員可以新增競(jìng)賽、新增競(jìng)賽題目和刪除競(jìng)賽。
后臺(tái)測(cè)評(píng)模塊對(duì)用戶提交的代碼進(jìn)行處理,判定是C還是Java等,編譯代碼,編譯通過(guò)后運(yùn)行代碼,測(cè)評(píng)結(jié)果是否正確,后臺(tái)測(cè)評(píng)模塊如圖4所示。
圖4 后臺(tái)測(cè)評(píng)模塊
(1)用戶端:用戶需要通過(guò)瀏覽器,來(lái)訪問(wèn)本系統(tǒng),首先需要注冊(cè)成為本系統(tǒng)用戶,然后登錄使用本系統(tǒng)。用戶忘記密碼時(shí),可以通過(guò)學(xué)號(hào)和電子郵箱來(lái)修改新密碼。登錄成功首頁(yè)有題目、提交、比賽、個(gè)人信息和排行榜等按鈕。題目頁(yè)面會(huì)以每頁(yè)10條數(shù)據(jù)進(jìn)行分頁(yè)顯示題目,分別顯示題目標(biāo)題、題目難度、通過(guò)率和提交狀態(tài)等信息。點(diǎn)擊題目標(biāo)題將會(huì)跳轉(zhuǎn)到題目詳情頁(yè)面,在該頁(yè)面可以進(jìn)行代碼提交。提交信息頁(yè)面分別顯示運(yùn)行ID、提交用戶、題號(hào)、運(yùn)行時(shí)間、測(cè)評(píng)結(jié)果、提交時(shí)間等信息,點(diǎn)擊運(yùn)行ID會(huì)彈出模態(tài)框里面顯示該次提交的代碼。比賽頁(yè)面分別顯示競(jìng)賽標(biāo)題,競(jìng)賽開(kāi)始結(jié)束時(shí)間和競(jìng)賽當(dāng)前狀態(tài)。競(jìng)賽狀態(tài)會(huì)根據(jù)競(jìng)賽開(kāi)始結(jié)束時(shí)間和系統(tǒng)當(dāng)前時(shí)間做對(duì)比,分3種狀態(tài):未開(kāi)始、正在進(jìn)行和已結(jié)束。用戶可以修改除學(xué)號(hào)之外的個(gè)人信息,查看用戶排行榜。
(2)管理員端:后臺(tái)管理模塊有用戶管理、題目管理和競(jìng)賽管理功能。用戶管理有用戶修改和用戶刪除操作。題目管理有新增、修改和刪除題目操作。競(jìng)賽管理有新增競(jìng)賽、刪除競(jìng)賽和新增競(jìng)賽題目操作。
本OJ系統(tǒng)所支持的編程語(yǔ)言有C,C++,Java,整個(gè)測(cè)評(píng)功能模塊的工作步驟如下:
(1)獲取用戶提交的源代碼,如果是用戶使用的是C、C++語(yǔ)言的話,會(huì)把代碼保存在指定的文件夾下,XXXX.c或者.cpp的文件里,前面4位是系統(tǒng)隨機(jī)產(chǎn)生字符,這也是保證文件名不能相同。如果用戶選擇的是Java語(yǔ)言的話,首先Java的類(lèi)名必須是Main,隨后生成XXXX.java文件。
(2)編譯源代碼生成的.c或者.java文件,系統(tǒng)會(huì)根據(jù)相應(yīng)的文件調(diào)用不同的編譯器,C/C++生成.exe文件,Java生成.class文件,前面的4位隨機(jī)數(shù)和編譯前是一樣的。
(3)運(yùn)行已經(jīng)編譯好的.exe或者.class文件,運(yùn)行文件進(jìn)行數(shù)據(jù)的輸入輸出用來(lái)和錄入數(shù)據(jù)庫(kù)的測(cè)試用例對(duì)比,得到結(jié)果,并將測(cè)評(píng)結(jié)果實(shí)時(shí)反饋給用戶,測(cè)評(píng)功能模塊流程如圖5所示。
圖5 測(cè)評(píng)功能模塊
系統(tǒng)選擇C/C++的編譯器是WinGW,它是一個(gè)精簡(jiǎn)的Windows平臺(tái),支持C/C++、ADA編譯器,使用較為方便[3]。
Java編譯器選擇JDK,它為Java應(yīng)用程序開(kāi)發(fā)提供了編譯和執(zhí)行環(huán)境,所有的Java寫(xiě)程序都依賴于它。
安裝好編譯器和配置好環(huán)境后就可以直接使用cmd窗口執(zhí)行命令調(diào)用相應(yīng)的編譯器編譯運(yùn)行C/C++或Java文件。
(1)先獲取用戶提交的源代碼,判斷提交的是C/C++還是Java。
(2)將用戶提交的代碼存放在系統(tǒng)指定位置,并且C/C++命名為xxxx.c文件,Java命名為xxxx.java(用戶提交的Java代碼,類(lèi)名必須為Main),文件名為隨機(jī)四位字符。
(3)編譯用戶提交的代碼,使用Runtime.getRuntime().exec方法可以調(diào)用cmd命令行窗口執(zhí)行g(shù)++或者javac命令編譯.c和.java文件。
(4)執(zhí)行編譯成功后的.exe文件或者.class文件,還是使用Runtime.getRuntime().exec方法調(diào)用cmd命令行窗口[4]。
Processprocess = Runtime.getRuntime().exec(“運(yùn)行命令”);//執(zhí)行編譯
BufferedWriter bout = new BufferedWriter();
bout = newOutputStreamWriter(process.getOutputStream());// 獲取子進(jìn)程輸出流
bout.write(sampleInput);// 輸入數(shù)據(jù)庫(kù)的測(cè)試樣例
bout.close();
(5)將運(yùn)行輸出的結(jié)果和數(shù)據(jù)庫(kù)測(cè)試數(shù)據(jù)進(jìn)行對(duì)比,并將測(cè)評(píng)結(jié)果存放數(shù)據(jù)庫(kù)
例如用戶提交的是Java代碼,Java源碼測(cè)評(píng)程序流程圖如圖6所示。
圖6 Java源碼測(cè)評(píng)程序流程
ACM國(guó)際大學(xué)生程序設(shè)計(jì)競(jìng)賽是計(jì)算機(jī)界最有權(quán)威的競(jìng)賽之一,也被稱(chēng)為計(jì)算機(jī)界馬拉松。在線測(cè)評(píng)系統(tǒng)是一個(gè)功能性很強(qiáng)且綜合的系統(tǒng),不僅要求會(huì)Java Web和數(shù)據(jù)庫(kù)的知識(shí)還要求實(shí)現(xiàn)頁(yè)面的簡(jiǎn)潔美觀。本文對(duì)在線測(cè)評(píng)系統(tǒng)前臺(tái)服務(wù)模塊到后臺(tái)管理模塊和測(cè)評(píng)模塊做了詳細(xì)需求分析,著重介紹了實(shí)現(xiàn)在線測(cè)評(píng)的整個(gè)流程。系統(tǒng)設(shè)計(jì)已基本完成,能夠在線測(cè)評(píng)并實(shí)時(shí)將結(jié)果反饋給用戶。