ContestSonic 开发笔记(五)

论文编完了,对着一个完全没开发的系统写 5588 字论文我崩溃了。

下面备份一些关于架构设计的部分,原版论文就删掉了……

编出来的东西也多大意思,留着没啥用……

关于调查结果

年初的时候进行了一个小范围的调查,针对使用者使用习惯与期望的。在前期调查中,共收到 65 份答卷,有 8 份无效答卷,有效答卷 57 份。调查项有:调查者的身份,是否曾用过线下测评系统,对于测评系统倾向采用的模型等。

对教练的需求调查

有幸有两位教练接受调查,被调查的教练中,都用过线下测评系统,都支持选手端全平台,测评端在 Linux 的方案。办比赛的时候所用测评机数有只用一台的情况,也有用两台以上的情况。题目自测需求一位有一位没有。均倾向于用网页交互,倾向于反作弊系统不多余,应加入反作弊系统。在运行时间上,支持相对运行时间与保留时间限制一半一半,用 diff 和用 testlib 手写一半一半,有线上线下联动需求。都开设了程序设计课,笔试上机一半一半,都认为现在的测评系统可以满足需要。

对现役竞赛选手的需求调查

共调查到 37 位现役竞赛选手。其中 32 人的学校用过线下测评系统,占 86.49%;7 人支持选手端全平台,测评端为本机,21 人支持选手端全平台,测评端在 Linux,4 人支持选手端全平台,测评端全平台,5 人支持选手端,测评端均在 Linux。19 人支持用一台测评机,18 人支持用两台及以上测评机。19 人不常用线下测评系统自测。21 人倾向网页交互,16 人倾向 GUI 交互。26 人认为反作弊系统不多余,占大多数。29 人认为保持时间限制更合理,5 人支持用相对时间,3 人支持用绝对运算量。29 人用 testlib 重写 fc 或 diff。16 人需要线上线下比赛联动,1 人认为不可行,有需求。26 人的学校开设了程序设计课程并需要考试。5 人的考试需要笔试,剩下均为上机。

对退役竞赛选手的需求调查

共调查到 18 位退役竞赛选手。16 人的学校用过线下测评系统,占 88.89%;2 人支持选手端全平台,测评端为本机,7 人支持选手端全平台,测评端在 Linux,6 人支持选手端全平台,测评端全平台,3 人支持选手端,测评端均在 Linux。4 人支持用一台测评机,14 人支持两台及以上测评机。12 人经常用线下测评系统自测。13 人倾向于用网页交互。10 人认为反作弊系统不多余。11 人认为保留时间限制的设定,3 人认为用相对时间作为时间限制,4 人认为用绝对运算量作为时间限制。16 人支持用 testlib,9 人支持线上线下比赛联动,15 人的学校开设了程序设计课程。其中 4 人笔试,11 人上机。

总结

根据调查,将采用选手端全平台测评端 Linux 端模型设计,采用网页端交互,考虑分布式测评,实现一个反作弊系统。并且力求前端设计简洁,后端响应迅速。

↑一段软件魔幻文学

说实话感觉这个系统只是服务大型比赛的,对于普通学校日常考试的话,可能有些学校拿不出那么多机器运行这个……

关于整体结构

系统分为两个部分:选手端和裁判端。

这里取消将测评端单独分出的设计,直接将测评端与裁判端绑定。首先从逻辑来说测评机只是裁判判断题目是否通过的工具,应该归入测评端。其次是自己比较懒,能省一端是一端,或许还能有附加效果。

选手端

使用选手端的计算机应互相独立,但同时连接到裁判端形成星型结构,并受裁判端的控制。选手端需要向裁判提交数据内容的有且仅有三个功能:

  • 提交代码:选手将自己的代码发送到裁判端申请测评;
  • 向裁判提问:对题目或代码编写环境的问题通过提问功能发送到裁判端;
  • 打印:选手要求裁判打印代码或其他文件。

选手端仅会从裁判端获得以下两种包含数据内容的信息: - 代码运行状态:包括代码是否通过,若未通过是何种错误以及错误信息,若通过代码运行消耗时空量; - 裁判向选手提供的信息:包括对选手提问的回应,对选手的通知,题目的附加文件和比赛相关信息。

裁判端

裁判端应为一个服务器集群,分别处理代码测评和管理比赛。

对于处理代码测评部分的服务器,仅需要接收从比赛管理端发来的测评某个测试数据集的请求,测评请求的测试数据集,并返回结果,为一个 0 到 100 之间的实数。

对于比赛管理端,需要连接选手端与测评端,具体说来,需要实现以下功能:

  • 根据需要向选手提供信息:包括回应选手的提问,通知选手比赛相关信息或题目更正或说明,提供题目附加文件和选手的排名;
  • 根据需要向外围提供信息:IOI 与 ICPC 比赛排名赛时对外公开,因此需要单独维护;
  • 管理所有参赛者:需要赛前添加所有参赛者,并可以取消参赛者比赛权力;
  • 管理所有题目:需要赛前添加题目,并可以对题目数据进行修改和对该题所有提交进行重新测评;
  • 与测评端交互:向测评端发送测评请求,并接受返回的分数,给选手评分。

关于实现细节

测评技术与细节

说这个没啥用,因为解决方案挺多,JudgeDuckOS, cgroup, docker 什么的(但是 docker 判题据学长说有漏洞)。

测评任务应以子任务为单位发送,以解决子任务依赖和子任务时空限制不同的问题。

测试数据也均以子任务为结构进行组织。

前端实现细节

对于前端,设计时应注意扁平化设计,避免复杂菜单和选项以方便选手与裁判快速获得所需信息。选手提交题目可以通过拖拽文件到对应题目编号上的方式,方便选手快速提交题目。

后端实现细节

想把数据库砍了,直接重要数据全放内存……

其实有些东西要共享访问的话这样就很不好……

逻辑细节

有些提交是对同一份代码的重复提交,这样的情况直接判一下 MD5 就行了。

如果要更新榜单的话,可以设置一个时间间隔更新。

原则上选手可以无限制打印,但是由于主办方的打印机数目有限,并不能提供无限制的打印服务,因此将打印限制字节数定为与提交代码最大长度相同。由于本身打印服务是为了方便选手在不利用计算机的条件下调试代码,因此打印的最大长度应与提交代码最大长度匹配。设计的时候也在想是不是应该禁止掉除了代码以外的打印(也就是只打印提交过的代码),但是有时候找规律就要打数字表,还可以空打一页纸当做草稿纸等等进行骚操作,这样就不能禁止。

在前一年的四川省大学生程序设计竞赛中,因为一队选手打印了过量的信息,导致打印队列阻塞,影响到了其他队伍的打印,并与主办方发生了十分遗憾的冲突。为了避免这种情况,设计打印功能时应注意。

安全细节

最近 CF 被 DDoS 了,如果局域网内 DDoS 服务器也会挂掉,在现场配备一定数量的大铁棍子可以随时捶人的情况下,也应保证服务器稳定可靠(工作比赛那么长时间)。

写完感觉更厌恶自己了……

以上。

希望有能力的时候能写写吧……