在线测评系统的设计与实现
2023-11-14龙丹,徐轲,甘泉
龙 丹,徐 轲,甘 泉
(桂林信息科技学院信息工程学院,桂林 541004)
0 引言
在线测评系统如今为人类社会提供了关于数据结构、算法和数学的重要服务,在学术界和工业界发挥着重要的作用,特别是在竞赛教育方面,使用在线测评系统的用户的编程和思维能力得到了锻炼和提升[1]。
为了解决在线提交解决方案代码的问题,XKOJ 设计了用户表、题目表、提交表、比赛表和博客表,构建了完整的在线测评系统生态。该系统包含用户注册登录、题目创建和阅读、代码提交验证、比赛创建和运行、以及博客发表和浏览功能。该项目运行在云服务器上,使用Django 框架和Redis两个Docker容器来保证安全性和可移植性。在Django 项目中,提交题目使用异步任务队列Celery 来避免在线提交解决方案可能发生的冲突。每一个需要测评的程序都通过延时进入函数,作为一个任务加入到队列中,由队列中的调度方案来执行任务。通过任务文件中不同的装饰器找到任务所需执行的函数代码,对提交代码进行编译评测,反馈结果到视图文件中,并通过数据渲染给前端页面,让用户直观看到提交结果。
1 测评系统需求与技术介绍
1.1 服务器原理介绍
租赁云服务器,本系统所运行的环境为Ubuntu 20.04。在本地创建镜像后,可以利用镜像创建Docker容器,并在容器内安装项目所需的使用工具,例如Python 3、Vim 和Django-admin等。为该容器创建用户并分配Sudo 权限,然后可以使用服务器端口和账号密码直接进行SSH登录。
1.2 数据库原理介绍
Django 默认使用关系型数据库管理系统。其中SQLite 是默认的数据库引擎,它是一个轻量级的数据库,无需独立的服务器进程,直接存储在文件中。Django 的对象关系映射提供了一种将对象映射到关系数据库中的方法,可以将对象转换为SQL 查询,从而在数据库中创建、读取、更新和删除数据。
Django 的ORM 基于模型和字段的概念。模型表示数据库中的一个表,而字段则表示该表中的一列。模型类定义了模型的属性和行为,其中属性是模型的字段。模型类还可以通过定义方法来实现模型的逻辑和行为。
1.3 开发工具与技术介绍
XKOJ 为云服务器挂载Docker 中创建的项目,在Docker 中操作项目能简化项目的部署和隔离管理,提高系统的可扩展性和安全性。系统运用了Python 语言支持的Django 框架来搭建,重点逻辑部分有三块内容:模型、视图、数据库。通过模型定义数据的结构,视图负责处理用户的请求并返回响应,数据库用于存储应用程序的数据[2]。通过链接调用对应的视图中的函数,来实现后端响应的功能,同时可以通过标识、POST 或GET 方法获取相应的页面内容,并在加载的数据库中找出对应的内容,将处理好的数据集打包传递给将要加载的网页中。
数据库处理采用Django 自带的默认关系型数据库,通过映射的方式创建数据库表,对在线测评系统所需的用户、题目、比赛、博客、提交信息进行特征封装,并在逻辑上需要时将它们相互关联,保证信息的连通性。在项目完成上,使用了部分Shell 脚本来帮助管理员解决启用系统文件、代码文件与编译文件定量删除等;在前端页面上自定义了绝大部分样式代码,引入了Ace 代码编辑器、Markdown、Mathjax 等开源文件增加页面可读性;在后端引入Celery异步任务队列,通过创建任务文件编写任务逻辑,在视图中将打包好数据集的任务放入队列中进行等待,在消息队列空闲时将会通过自身的调度方式执行一个任务。
通过Docker 将开放端口挂载Redis 缓存数据库,Celery 使用Redis 作为消息代理,将任务放入Redis 中间件队列,并从队列中获取任务以进行处理。Redis 作为消息代理,具有快速读取和写入的能力,可以使得Celery 的任务执行更加高效和快速。此外,Celery 还使用Redis 作为结果存储,保存任务执行的结果和状态,以供查询和分析。
2 系统主要功能需求
2.1 测评机需求
测评机首先要根据提交信息的表单传入信息,在异常处理模块下根据声明的数据库变量读取到信息数据集。程序根据使用语言执行对应的编译指令,在创建的子进程中对提交程序代码进行编译,通过返回的编译文件,在子进程中产生输出文件并与测试样例输出文件进行对比,结合编译时的信息返回相应结果,包含通过、错误、编译错误、超时、超限、程序异常[3]。
对于多组测试用例,则需要产生多组子进程来执行编译文件产生结果集,将各种情况存放在列表中,按照结果优先级进行反馈。
对于没有确定结果的题目,需要采取特殊判断的方式,即按照用户提交代码产生的结果信息,根据题目要求逻辑,进行验证程序的编写,并将用户提交代码的输出文件输入到验证程序中运行,若满足所有条件,或输出期望结果,则返回此提交结果正确,否则依旧根据结合编译时的信息,按照各种情况的优先级进行反馈[4]。
图1 测评机处理任务流程
2.2 训练模式与比赛模式需求
在XKOJ中,训练模式对应标题单,比赛模式对应比赛。在查看题目之后的所有操作都相同,但是会调用不同的测评机,传递不同的比赛信息。在XKOJ中,视图会根据不同的比赛ID将提交结果保存在不同比赛外键的表中,在后续查看比赛排名与提交信息时,能够清晰地显示当前比赛中的各种信息。但如果是在题单中提交代码,则不会将其添加到任何比赛中,而是会保存在无比赛外键的表中,为用户提供状态查看与代码查看。
图2 练习、比赛共用题库模块需求
3 XKOJ系统分析与实现
3.1 系统与数据库表构思
系统功能总体分为四个类别:设置、题目、博客、比赛。
在每个类别下,需要编写对应的视图函数实现需求。
设置:登录、登出、注册、查看用户信息。
题目:查看题目列表、查看题目内容、提交解决方案、查看提交结果。
博客:查看文章列表、编写博客、查看文章内容、点赞、评论。
比赛:创建比赛、报名、查看比赛列表、查看比赛排名、查看提交状态。
实现不同的视图函数,需要建立对应的数据表,用来支持系统完成相应的操作。
图3 XKOJ主要数据表结构系统重点视图函数与数据库表
3.2 用户功能分析
用户是在线测评系统一个重要的组成部分,系统需要具体实现:注册、登录、填写、显示和修改个人信息功能,并保证用户提交题目或者比赛会产生相应的练习数据与比赛数据,并能进行查询。
3.3 测评机功能分析
一个在线测评系统需要验证用户根据题目要求编写的代码是否正确,即需要设计一个满足评测需求的测评机。测评机需要识别语言和代码信息,并编译运行程序,判断程序是否符合要求,将结果数据打包返回。
对于处理多用户多提交解决方案代码的实际情况,首先应保证测评机能稳定有序地返回评测结果,其次应尽可能优化测评机的评测水平以提高其性能。考虑到安全性,防止提交代码内包含恶意攻击代码,应尽可能使用子进程去验证并执行子任务。
图4 测评机功能分析
3.4 题库功能分析
题库是在线测评系统的核心,有了阶梯难度分布的广泛题库,才能更好地锻炼用户的代码水平[5]。
解决问题的代码编写需要在限定的时间和空间复杂度内考察用户的算法能力,并对数据范围有敏感的认知。通过各表间的相互联系,共同实现在线测评系统的一整套流程。
3.5 博客功能分析
博客是在线测评系统的重要组成部分,用户可以通过编写博客的方式进行输出,分享解决问题或积累的知识,还可以通过博客内的各类知识与题解提高自己的学识。博客查阅需要舒适的阅读体验,可以通过封装Markdown 提高内容的可读性。
3.6 比赛功能分析
比赛是一个封装的功能,需要保证每场比赛之间的独立性。同时,在逻辑上,XKOJ 将题单作为没有开始与结束时间的比赛放在比赛页面中。用户点击比赛时,将跳转到报名信息界面进行报名。如果用户未报名,则返回报名成功;如果已报名,则进入具体比赛界面。通过不同表单之间的联系,匹配用户、题目、比赛三元组的信息,在比赛期间实时更新排名。在提交表中加入用户提交本题的错误次数、正确标识和正确时间;在排名表中加入用户的总通过数和总花费时间,作为特征依据“通过数量多者优先,通过数量相同者花费时间小者优先”的规则,对每位参加比赛的用户进行排序。
对于提交状态,只需要在比赛内的测评机内不断更新任务队列中已处理的任务信息即可。同时,根据自定义需求,在网页上显示部分特征。
关于比赛题目查阅问题,本系统采用通过超链接传递比赛ID 的方式,让题目在提交时首先判断是通过练习题单提交还是通过比赛提交,并调用不同的测评机进行评测。这样能够很好地将提交信息封装到每场不同的比赛中,保证数据清晰。
4 测评系统测试及总结
Celery是一种基于Python 的异步任务队列消息代理,它提供了分布式任务调度和处理的功能。它可以与多种后端存储集成,支持任务的异步执行,可靠性高、可扩展性强。
测评环境为阿里云服务器2 核2 GB,测试内容为使用Celery 作为任务队列来实现一个测评机任务队列,Redis 作为支持AMQP 的消息代理传递消息。通常情况下,Celery支持处理数以万计的任务,但是任务队列的吞吐量会受到消息代理的限制、任务处理时间的约束。
本次测试通过程序编写,模拟用户提交解决方案,并发提交5000 个任务到任务队列中,并记录完成这些任务所需要的时间。为了测试测评机的吞吐量,测试了使用1 个测评机和4 个测评机的情况完成所有任务所需的时间,并计算出每秒可以测评的任务数量。
进行两组测试,一组测试需要计算两个数的和;另一组测试题目为图论经典题目最大流,需要在有向图中找到一条从原点到汇点的路径,使得路径上的最小边权最大。
表1 测评机吞吐量测试
经过表格内的测试结果,在任务量很大时测评机依旧可以保持不错的状态,使用4个测评机时效率大概为单测评机的四倍。这说明,在处理较大的任务量时,使用Celery 可以显著提高任务处理的效率,减少任务完成的时间,提高系统的性能。因此,在本系统的使用需求下,采用Celery实现任务队列是不错的选择。
5 结语
近年来,在线评测系统已经被广泛应用于各个领域。随着计算机科学技术的不断发展,在线评测系统也在不断进步和完善。未来,这些系统将引入更多的智能技术,如机器学习和深度学习,以提高评测的准确性和效率[6]。同时,为了保证比赛评判的公正性,将会为比赛参赛者提供更高效的代码查重机制,并引入更加公正和客观的评判机制。这些系统将根据不同用户的需求和特点,提供更加个性化的学习内容和评测体验。未来,在线评测系统将会不断更新题库,覆盖更多的算法和数据结构等知识,同时添加更多实际应用场景下的编程题目,以帮助程序员更好地解决现实生活中遇到的问题。
此外,未来的在线评测系统将建立更加开放的社区生态,注重社区的建设和发展,为用户提供更丰富的交流和互动机会,促进用户之间的交流和学习。同时,这些系统将提供更加高效的测试和调试工具,帮助程序员更快地发现和解决程序中的问题。它们还将为新出现的编程语言提供机会和平台,以便它们传播、交流和发展。不仅如此,这些系统还将为不同需求的群体提供一个计算机科学技术交流的平台,促进计算机科学技术的发展。