呂英華
(北海職業學院,廣西 北海 536000)
Online Judge系統是一個在線判題系統,能夠對用戶提交的多種程序源代碼進行編譯執行,并根據預先存儲的結果進行校驗后得到源程序的正確性。Online Judge系統最初使用于ACM比賽中[1],隨著國內計算機行業的不斷發展,許多高校開發了屬于自己的Online Judge系統,同時計算機行業也開發了Online Judge系統服務于個人或他人。現在Online Judge系統不僅在比賽中使用,還在教學、考試、程序上機實踐中使用,極大提高了教學工作效率和方便了各類編程人員。
Online Judge系統主要有兩種典型的模式,分別是C/S模式和B/S模式。C/S模式主要用在各種大型比賽中,比如省賽、區賽、國際賽等;B/S模式主要用在教學、上機練習等。該Online Judge系統采用B/S模式,主要由前端、后端及判題機三大部分組成。整個系統以數據庫為中心,用戶在前端頁面登錄進入系統,前端頁面則顯示從數據庫中獲取的題目、比賽列表、排名等信息,用戶選擇對應的題目進行答題,提交代碼保存至數據庫。判題機是Online Judge系統的核心部分,評判之前先從數據庫中提取代碼,將代碼保存至文件中,再對代碼文件進行編譯、執行和評判操作,最后將評判結果存入數據庫中,以上則完成了評判流程,前端頁面則將評判結果從數據庫中讀取出來并顯示。系統邏輯圖如圖1所示。

圖1 系統邏輯
判題機是整個Online Judge系統的核心內容,主要功能是對用戶提交的代碼進行編譯、執行、評判等,寫好的判題機可以放入Windows環境或Linux環境中。該Online Judge系統采用Python實現,支持多種程序(如C、C++、java)源代碼編譯執行。
Online Judge系統最重要的功能是支持多種編程語言提交代碼,由于不同的編程語言需要到不同的編譯器,則可以選擇Python提供的subprocess模塊去調用外部編譯器,該模塊能夠對不同編程語言進行擴展,只需配置好編譯參數即可。

具體實現是調用subprocess.Popen方法,設置方法中的shell=True,并使用cwd指定工作目錄,stdout和stderr設置為subprocess.PIPE管道。調用communicate方法獲取外部程序的輸出信息,一般返回0和1。
p=subprocess.Popen(build_cmd[language],shell=True,cwd=dir_work,stdout=subprocess.PIPE,stderr=subprocess.PIPE) #調用subprocess.Popen
out,err=p.communicate() #獲取編譯錯誤信息
判題機的評判流程是根據代碼編譯執行后返回的信息做出對應的執行流程。首先,communicate方法如果出現編譯錯誤Compile Error,則停止,否則繼續往下執行;其次,判題機會依次檢查程序是否出現超時、超內存和非法指針、數組越界等情況,如果程序返回Time Limit Exceeded錯誤信息,則說明執行超時了;如果程序返回Memory Limit Exceeded錯誤信息,則說明執行超出內存限制了;如果程序返回Runtime Error錯誤信息,則說明程序運行錯誤,需要進行修改[2]。評判流程圖如圖2所示。

圖2 評判流程
當以上所有流程跑完,都未出現錯誤信息,程序繼續執行,下一步驟,則需要將結果和標準答案進行比較,得出答題是否正確,有以下幾種比較情況。
(1)當程序運行結果和預設的標準答案一致,則程序會返回Accepted,說明答題成功;
(2)將程序運行結果中無用的空格符、換行符等去掉后與預設的標準答案是一致的,則程序會返回Presentation Error,說明運行結果格式有誤;
(3)當程序運行結果和預設的標準答案不一致,則返回Wrong Answer,說明答題失敗[3];
(4)如果程序運行結果僅有一部分和預設的標準答案一致,會返回Output Limit Exceeded。
檢測程序的執行時間和內存,可以通過github上的一個開源項目lorun去實現。該開源項目是利用C語言編寫的一個Python擴展模塊,使程序能夠在一個類似沙盒的環境下執行,并能夠精準地獲取程序的執行時間和內存,還能對程序進行限制,防止外部調用。
Online Judge系統還要做好安全處理,防止用戶惡意攻擊破壞系統。解決該問題,可以從以下方面進行處理。
(1)通過防火墻限制網絡訪問,或者禁止系統連接外網;
(2)對代碼進行預先檢查;
(3)將判題機和服務器進行分離;
(4)控制文件的執行權限;
(5)設置沙盒環境,將程序執行環境和外部進行隔離。可以從操作系統中設置,如設置Linux環境chroot命令,也可以使用Python的方法實現。
設計一款完善的判題機需要用到的技術除了整套的web技術棧外,還需要操作系統、沙箱等知識,屬實不容易。該判題機的設計借助了網上多位大神的邏輯、經驗、代碼,目前已能夠正常使用,但還需進行優化改進。