程序喵小七

不是在写bug,就是在写bug的路上

从零开始的代码评测系统设计与实践(五) —— 新的开始

0x00 前提

自从2015年WeJudge(亦简称为OJ)第一个版本面世以来,经历过两次比较大规模的重写。为什么是重写不是重构?因为代码写的很烂。目前的3.x版本是最好的一个版本了,但无论是从技术层面来看,还是从产品层面来看,它都还存在很多很多的问题。基于这些问题,加上我对个人成长的期望,我希望能从现有的基础出发,开发一套代码判题服务实现的解决方案。这个项目会以BSD协议开源,同时,判题机程序deer-executor会以GPL协议开源。开源是希望能够和大家分享交流,希望知识和成果要属于大家。


从零开始的代码评测系统设计与实践(四) —— 特殊评测

0x00 背景

传统的评测模式下,判题机按照固定的顺序执行:运行被测程序,获取运行结果,比对结果数据。由于是严格比较,结果数据和答案属于有任意一个字节(除常用格式字符外)不匹配,都将被判定为WA。

有些时候,这种方式太过于苛刻。在涉及到浮点数运算的题目,如计算圆的面积时,我们不得不面对计算结果的精度误差,这将导致原本正确的程序,被判定为WA,显然这不符合我们的逾期。

在特殊评测功能还没能设计开发出来之前,我们通常的解决办法是固定使用一种数据类型出题,比如要求选手使用double来存储浮点数,这样可以确保最终打印的小数精度和我们设定的答案一致。

我们知道,数据检查工具是判题机的一部分,那么是否能让判题机支持调用出题者编写的数据检查工具呢?


从零开始的代码评测系统设计与实践(三) —— 运行结果处理

0x00 获取运行结果

上两篇文章,我介绍了判题机是如何管理进程,并如何限制进程的资源使用。目标程序运行完毕退出后,我们的判题机进程将从等待中唤醒,进行运行数据的收集工作。此时,判题机能够作出判断的状态分别有AC(暂时)、TLE、MLE、RE和OLE。

从进程篇我们可以了解到,WIFSIGNALED(status)可以判定进程是因为收到系统信号而终止的。此时,再使用WTERMSIG(status)获取到进程的信号,根据信号的不同来判定运行状态。


从零开始的代码评测系统设计与实践(二) —— 资源占用与限制

0x00 资源占用

一个完整的判题机核心,不可避免要支持程序的资源占用判定。我们常以两个维度来判定一个程序的优劣,时间维度和空间维度。在ACM-ICPC比赛里,通常每道题目都有一个期望的最差运行时间,和最大内存占用。如果你的程序算法效率足够高,便可以很快的运行完某个测试数据;如果你的算法效率不够优,也许还可以通过使用内存来优化,但难免会造成内存占用。

一旦程序超出了预期,如运行过慢、陷入了死循环或内存占用太多,判题机核心的工作就是结束掉它,并收集它的信息,再给出相关的出错提示。

从上一节我们可以了解到,wait4()函数可以返回一个rusage结构体,我们可以完成对它信息的收集工作。那么问题来了,如果程序陷入了死循环,判题机又是如何知道的呢?


从零开始的代码评测系统设计与实践(一) —— 进程和输入输出

不过是去便利店买了个泡面,居然穿越到了异世界。一次意外的去世,发现自己拥有了死亡后读档的技能…原来,世界线分支交错复杂,不同的世界线里发生着不同的故事…

0x00 进程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

来自百度百科词条

进程就像是一个个世界线的分支,各自发生着不同的故事,但又是相互关联的。

我们运行的每一个程序,系统都会为它创建一个进程,然后分配内存和堆栈,装入程序的指令,并执行它们。如果我们要在自己的程序里调用其他的程序,就需要向系统申请创建子进程,重复执行上述的初始化操作。那么进程应该如何创建呢?


从零开始的代码评测系统设计与实践(序)

0x00 我为什么要开发OJ?

在线判题系统(Online Judge)是一种在编程竞赛中用来测试参赛程序的在线系统,也可以用于平时练习。

相信参加过ACM-ICPC、IO的童鞋们都对它不陌生吧,那个偶尔让你产生许许多多的小问号,想AC却又不停的WA,做题做到停不下来的系统。

五年前,作为前ACM校队队员,在深感自己太菜的技术后,一次突发奇想和老师讨论起了怎么把OJ用到教学中去,让学弟学妹们也被折腾一下(这句划掉),从此给自己挖了一个巨大的坑。


在线代码评测服务架构的设想与设计

重新开了个系列,此文废弃。

https://www.lanrongqi.com/2020/07/online-judge-development-0/

0x00 背景

WeJudge 3.0 第一期工作已经基本上完成了,平台初步完成了题库模块、判题模块和教学系统(课程模块、作业模块)的开发并进入内测阶段。本文根据内测阶段系统工作情况的反馈,就判题模块反映出的问题,整理相关技术方案,讨论一套更加合适、高效的判题模块设计方案