王飞飞 徐帅武
摘要:针对现有程序在线评测系统存在的运行效率低、功能较为单一的问题,该文设计实现了一基于Koa2的PDSUOJ系统,该系统前端与服务端框架分别采用Rect与Midway,进行数据存储与缓存时使用PostgreSQL与Redis,同时为了满足服务之间隔离与快速部署的需求采用Docker作为各个服务的运行容器。该系统主要实现了用户信息管理、用户分组信息管理、题目信息管理、题目提交评测、提交数据管理等功能,系统界面简单友好,运行效率高,可以满足用户在线评测程序的需求。
关键词:评测系统;服务端;数据管理
中图分类号:TP311 文献标识码:A
文章编号:1009-3044(2020)03-0094-02
1 概述
随着计算机编程技术的发展,各类程序在线评测系统开始出现[1-3],但是現有的系统大多主要以学生竞赛训练为主,与教学工作相结合用于程序课程考核的较少,因此功能较为单一,在实现学生分组、课程分类、评测结果数据分组汇总方面存在欠缺,且存在代码耦合严重难以二次开发、系统扩展性与数据安全性较差等问题。为了更好地满足教学需要,本文在对现有系统进行分析研究的基础上,根据学生与教师在系统性能、功能和扩展性的需求,确定系统功能与实现该系统所采用的技术,设计实现了一在线评测系统。
2 系统功能需求分析与相关技术
2.1 系统功能需求分析
通过对现有在线评测平台的分析[4-6],在对教师与学生的需求进行调研的基础上,将系统用户分为两类:普通用户与特权用户。
普通用户功能包括个人信息管理、查看排行、题目查询与浏览、题目提交与程序考核管理。其中个人信息管理包括用户注册登录、信息查看与信息修改;查看排行可以分组查看,也可以查看他人的成绩信息;题目查询与浏览可以实现分类查询、模糊搜索、题目自定义排序与查看详情;题目提交为答题完毕后提交题目。
特权用户功能包括用户管理、题目管理、用户组信息管理、考核管理。其中用户管理包括对注册用户个人信息进行查看、删除、修改等,对用户近期答题情况、错误率、排名等情况进行查看;题目管理包括对题目的添加、修改、删除、隐藏、分类等操作;用户组信息管理包括新增用户组,实现对用户组信息的修改与删除,对用户组内成员信息的管理;考核管理包括出题、选择参加学生、对提交题目进行评判等。
2.2 相关技术分析
本系统前端开发采用Rect,它可以在数据发生变化时检测到相应信息以完成对视图的自动更新,从而实现数据到视图的映射;可以通过Rect构建组件实现代码复用,也可以实现与其他框架的组合使用;Rect内部实现了Virtual DOM系统,当数据量大且变化快时只更新变化的数据,有效地改善了性能瓶颈问题。
Midway是基于Koa2的后端框架,与Koa2相比增加了许多便于开发的中间件,其开发语言采用TypeScript,有利于程序的后期扩展,同时兼容Egg.js的写法,可以利用各种中间件加快开发速度,同时内置了单元测试。软件开发过程中,程序在不同机器上会出现不兼容的状况,不同的技术也会存在不同的环境依赖,此类问题一般采用虚拟机或者Docker技术解决,由于Docker在启动、硬盘使用、性能、系统支持量方面存在的优势,本系统采用Docker技术来解决环境配置问题。
3 系统设计与实现
3.1 系统设计
本系统主体架构包括前端显示、后端逻辑层与判题服务三部分。其中Rect实现前端展示与操作逻辑,SPA模式的采用使页面切换等由前端处理,服务端仅提供页面数据,从而减少了网络请求数据量,页面展示时为无刷新的切换方式,增加了呈现速度。Service层采用TypeScript作为开发语言进行程序编写,以Node.js为程序运行环境,如果后端服务压力过大则可以开启多个,与前端服务器一起实现负载均衡,减轻后端服务压力,具体如图l所示。
用户提交答案到服务端后,服务端先通过一次Hash对重复提交进行过滤,然后将信息发送至Judge服务器,如果当前判题服务空闲则直接进行处理,否则将信息存入Redis缓存队列,当有判题核心处于空闲状态时则从缓存中进行读取判题,处理后将结果返回至服务端。具体工作流程如下:
1)评测服务接受评测请求;
2)判断是否空闲,如果空闲则执行下一步,否则处于等待状态;
3)对程序进行编译,如果编译失败则跳转到Error,否则执行下一步;
(Error)响应异常,跳转到8);
4)读取评测数据,运行编译后的程序对产生的结果进行比较;
5)如果结果正确则跳转到下一步,否则跳转到Error;
6)判断是否还有下一组数据,如果有则跳转到4),否则执行下一步;
7)响应请求结果为成功,执行下一步;
8)判断缓存队列中是否存在等待中的请求,如果存在则跳转到3),否则结束程序。
3.2 系统实现
本系统实现的功能有权限管理、用户注册登录、题目提交、用户管理、用户组管理、题目管理、系统判题等,下面以题目提交与判题为例进行描述。
题目提交实现过程中,将前端页面分为题目描述与弹窗两部分,这样可以实现无须将页面下拉到底端即可实现提交功能。该模块中,选择提交代码语言时使用Select选择器,用户可在基于CodeMirror的代码输入框中输入程序源代码,通过相应配置实现代码高亮等功能,CodeMirror通过注册该组件上的on-Change事件获取用户输入的源代码,代码提交时通过Base64进行编码,这样可以减少在数据传输过程中可能出现的错误;在服务端,获取/upProblem路径上的post提交时采用SubmitCon-troller类中的方法,提交获取后通过pid调用prisma.problem方法进行详细信息的查询,然后通过prisma. createSubmit创建一个用于提交的等待状态,并将信息发送给Judge服务器;Judge服务对接收到的信息进行解码与编译,然后将运行结果与正确答案进行比较,并将结果发送至SubmitController的updateProb-lem方法,该方法将所有测试产生的运行结果进行遍历,得出最终运行结果,并将其写入数据库。
对题目进行评测时,源代码编写采用C++语言实现,具体如下:首先调用parse_arguments函数对传人的实际参数进行解析,然后在Compiler函数中创建子线程,从而实现对源代码文件的编译,最后执行freopen0函数,并重定向到stderr/stdout文件,将结果返回给Main函数。在Main函数中获取Compiler函数的返回值,若该值为0则给出错误信息。当编译过程结束后,对mate.Json中的文件列表进行遍历,进行外部数据的读取,在该过程中,输入文件使用*.in,保存输出结果使用temp/*.out文件,如果运行超时,则向相应子进程发出信号,返回超时信息,如果运行正常,则对文件进行比较,判断比较结果是否一致,一致则为通过,如果不一致则返回错误,然后将运行时间和内存写入result.j son文件,继续执行下一组数据。
4 结束语
本文在对现有系统与用户需求进行分析的基础上,设计实现了以基于Koa2的在线评测系统,系统采用三层架构模式进行开发,主要采用Rect、PostgreSQL等技术,实现了用户分组管理、分角色权限管理、前端服务端开发分离、题目在线评测等功能,并在学生中进行测试,测试过程与结果表明:该系统界面友好、扩展性强,可以较好地满足用户的需求。
参考文献:
[1]黄洪波.大规模编程题在线评判技术研究[D].广州:华南农业大学,2016:18-20.
[2]杨志伟,曾艳姗,基于Linux的ACM在线评测系统研究[J].计算机与现代化,2010(6):166-169.
[3]李博,孟成博.对HUSTOJ在线评测系统的若干优化与创新[J].现代计算机:专业版,2013,(35):47-50,56.
[4]杜艳美.基于web前端的性能优化框架模型研究[D].绵阳:西南科技大学,2018:9-11.
[5]蔡崇超.基于Web的在线判题系统设计与实现[J].软件导刊,2016,15(3):107-109.
[6]王致远,周威,陈义明.基于SSM的ACM虚拟判题系统的设计与实现[J].电脑知识与技术,2018,14(9):95-97.