在线评测系统中判题机的设计与实现
2022-06-22吕英华
吕英华
(北海职业学院,广西 北海 536000)
0 引言
Online Judge系统是一个在线判题系统,能够对用户提交的多种程序源代码进行编译执行,并根据预先存储的结果进行校验后得到源程序的正确性。Online Judge系统最初使用于ACM比赛中[1],随着国内计算机行业的不断发展,许多高校开发了属于自己的Online Judge系统,同时计算机行业也开发了Online Judge系统服务于个人或他人。现在Online Judge系统不仅在比赛中使用,还在教学、考试、程序上机实践中使用,极大提高了教学工作效率和方便了各类编程人员。
1 设计思路
Online Judge系统主要有两种典型的模式,分别是C/S模式和B/S模式。C/S模式主要用在各种大型比赛中,比如省赛、区赛、国际赛等;B/S模式主要用在教学、上机练习等。该Online Judge系统采用B/S模式,主要由前端、后端及判题机三大部分组成。整个系统以数据库为中心,用户在前端页面登录进入系统,前端页面则显示从数据库中获取的题目、比赛列表、排名等信息,用户选择对应的题目进行答题,提交代码保存至数据库。判题机是Online Judge系统的核心部分,评判之前先从数据库中提取代码,将代码保存至文件中,再对代码文件进行编译、执行和评判操作,最后将评判结果存入数据库中,以上则完成了评判流程,前端页面则将评判结果从数据库中读取出来并显示。系统逻辑图如图1所示。
图1 系统逻辑
2 判题机实现
判题机是整个Online Judge系统的核心内容,主要功能是对用户提交的代码进行编译、执行、评判等,写好的判题机可以放入Windows环境或Linux环境中。该Online Judge系统采用Python实现,支持多种程序(如C、C++、java)源代码编译执行。
2.1 编译代码
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() #获取编译错误信息
2.2 评判流程
判题机的评判流程是根据代码编译执行后返回的信息做出对应的执行流程。首先,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。
2.3 时间和内存测量
检测程序的执行时间和内存,可以通过github上的一个开源项目lorun去实现。该开源项目是利用C语言编写的一个Python扩展模块,使程序能够在一个类似沙盒的环境下执行,并能够精准地获取程序的执行时间和内存,还能对程序进行限制,防止外部调用。
2.4 安全处理
Online Judge系统还要做好安全处理,防止用户恶意攻击破坏系统。解决该问题,可以从以下方面进行处理。
(1)通过防火墙限制网络访问,或者禁止系统连接外网;
(2)对代码进行预先检查;
(3)将判题机和服务器进行分离;
(4)控制文件的执行权限;
(5)设置沙盒环境,将程序执行环境和外部进行隔离。可以从操作系统中设置,如设置Linux环境chroot命令,也可以使用Python的方法实现。
3 结语
设计一款完善的判题机需要用到的技术除了整套的web技术栈外,还需要操作系统、沙箱等知识,属实不容易。该判题机的设计借助了网上多位大神的逻辑、经验、代码,目前已能够正常使用,但还需进行优化改进。