Giter Club home page Giter Club logo

onlinejudge's Introduction

Online Judge


0. 简介

  • 首先是一定要感谢HUST OJ的大大们的,阅读源代码的过程中经验值飞增。
  • 这是一个使用JSP实现的简单的OJ,对数据库的操作均通过调用存储过程和激发触发器来实现。(所以最后写出来的存储过程好多啊。。。。)
  • 数据库的信息,例如地址啊用户名啊密码啊没有写在Java类里,而是写了一个叫做databaseInfo.xml的文件(在web/WEB-INF路径下),然后用一个监听类来获取这个文件的绝对路径地址,在ConnectionDao这个类里读取出相应的信息,这样移植起来就方便啦,不给源码只给编译后的class文件的话也可以修改数据库。
  • 判题的隔离问题使用Docker来实现,下载了一个ubuntu镜像,然后自己在镜像中安装gcc, g++, java, 并新建一个弱权限的用户。把修改后的镜像保存起来,在判题时进入docker使用弱权限用户运行程序。
  • JSP只负责前端和处理用户提交的信息。用户提交代码后,JSP将信息写入数据库,提交状态设置成queueing,之后就不需要管了,全权交给Linux端去弄。
  • Linux端有两个程序,一个是轮询程序(polling.cpp),另一个是判题程序(judge.cpp),两个程序的参数都是通过命令行传参的,因此我又另外写了两个shell脚本(startup.sh和judge.sh)去执行程序。
  • Linux端C++与数据库的连接是使用mysql-connector-c++实现的。

1. 目前实现的功能

  • 登录、注册、修改个人信息; (这不是废话吗)
  • 通过竞赛的标题搜索相关的竞赛;
  • 可以根据用户名、代码提交的结果、编程语言来查看提交状态;
  • 管理员增删改题目、样例,添加竞赛;
  • 使用JQuery富文本编辑器编辑题目信息;
  • 用户可以提交C、C++、JAVA程序;
  • 限制每个账号30秒内只能提交一次;
  • 后台判题使用Docker,能判断AC、WA,能处理编译超时,运行超时,内存超限,输出超限,运行错误这几种情况。
  • 竞赛/作业加密功能,且用户登录正确之后就不需要再输入密码;
  • 竞赛模式和练习模式,竞赛模式有时间限制,时间截止就无法提交,而练习模式无限制;
  • 用户提交代码可以选择是否公开自己的代码,其他用户可以在竞赛结束后查看别人公开的代码;
  • 增加总排行榜,显示AC数、AC率;
  • 分页显示信息;
  • 测试数据文本文件上传;
  • 判题按队列顺序进行,全权由linux处理。
  • 通过使用setrlimit和alarm限制时间、内存、输出文件大小、可产生的进程数等,ptrace监听控制,实现防止#include "/dev/random"头文件造成的编译无法停止,死循环程序攻击,疯狂输出,fork炸弹,系统调用等攻击手段,同时,使用Docker进行隔离,容器炸了也不关我主机的事,判题结束后容器会被删除,下次判题又是新的容器。
  • 通过ptrace获取子进程的syscallId,并与允许的系统调用id进行比对,若不在许可列表中,则返回RE。自己手动跑了几个程序打表打出好多常规程序会产生的系统调用Id,但是怕漏了几个导致误判,就借鉴了HUST OJ源码中的过滤列表。(再次感谢大佬们开源)

2. 主要判题流程

  • 使用 nohup ./startup.sh $ 命令可以让进程在后台运行,退出终端后程序也不会终止。这个脚本会执行polling程序,并将相关的参数以命令行的形式传进程序中。polling程序是一个死循环的轮询程序。程序获取参数后,会连接数据库,然后调用存储过程将数据库中所有状态为queueing的提交按提交时间排序,先提交的排前面,全部放进队列里,然后断开数据库连接。如果队列不为空,就将数据逐个拿出来,把代码写入到文件中后,fork()一个子进程去启动judge.sh脚本,父进程就用waitpid()等待子进程结束。一直到队列为空。之后就sleep一秒中,然后继续刚才的操作,查询数据库的信息并判题。
  • judge.sh文件做两件事,一件是把编译后的judge程序拷贝到所要隔离的目录下(当初写这个是怕用户程序把目录下所有文件都删了,导致后续无法判题,现在想想,似乎删不了正在执行的程序,不过这样做了之后,我在修改judge文件之后,就不需要再手动拷过去了2333),另一件事是运行Docker,并在Docker中运行judge程序。
  • judge程序是判题程序。首先是通过传递的参数编译用户的源代码,如果编译出错,则向数据库写入系统错误或编译错误及错误信息;否则,开始判题。判题时,通过链接数据库获取题目限制的时间和内存,并读取所有的输入数据、输出数据。对于每组数据,先将输入数据写入到当前工作目录下的文件中,然后fork()一个子进程去运行代码,并用freopen重定向输入数据为刚才保存的文件、输出为文本文件,stderr也重定向为文本文件。父进程用ptrace监控该子进程,若达到超时、超内存、状态异常等情况,则改变判题结果为对应的状态,并结束子进程。若子进程正常结束,则比对一下用户输出与该组输出数据。判题直到数据全跑完,或者判题结果不再是AC,就可以结束了。最后就是更新数据库结果了。(PS:Docker默认不能使用ptrace,这个bug调了好久,最后才发现是Docker的问题。。。在启动Docker之前,加入启动选项 --cap-add=SYS_PTRACE就行了。)
  • 运行时间的获取可以直接有usage得到,而内存大小就搞不定了。通过研究HUST OJ的源代码,发现进程在运行的时候,会产生 /proc/pid/status这个文件(pid就是该进程的pid),里面记录了挺多内存信息的,且单位是KB,需要自己转一下,那么问题就变成文件读取了。(这是C和C++的,JAVA的需要到另一个地方看,应该是因为JVM的关系。)

3. 计划拓展功能

  • 批量生成竞赛用户账号,并加入到竞赛中;
  • 通过邮箱找回密码;
  • 数据下载,包括竞赛排行榜、总排行榜、题目信息、竞赛信息等;
  • 除管理员外,其他用户查看别人的代码,均将代码生成为图片;

onlinejudge's People

Contributors

mufeng964497595 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

onlinejudge's Issues

求助po主

毕业设计是这个 但在部署上有点问题555555 希望能解答一下~~有偿

同样开发oj

你好,你的代码给了我不少思路,谢啦。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.