Skip to content

WangOJ 在线判题平台 已完结

架构设计

请介绍整个系统后端的架构设计,有哪些模块以及各模块之间的关系?

  1. 用户模块:用户注册登录、用户的增删改查等管理功能
  2. 题目模块:题目提交、题目查看及题目的增删改查等管理功能
  3. 判题模块:提供判题服务,调用代码沙箱判题并对比判题结果
  4. 代码沙箱模块:提供代码执行的功能。作为独立服务,通过 API 接口调用,
  5. 公共模块:数据模型、全局请求响应封装、全局异常处理等

有调研过 OJ 系统的实现方案么?

在 GitHub 上调研了许多开源的 OJ 项目。有多种实现方案。

  1. 自主开发的 OJ 系统和代码沙箱。
  2. 使用第三方服务提供的代码执行 API。
  3. 远程判题,逆向其他现有平台的网站,实现一个题目聚合的功能。

除此之外我认为还可以使用 AI 进行辅助判题。通过大模型进行代码的查重和基本判题,比如提交的恶意代码或者明显错误的提交,可以直接用大模型过滤掉,节约代码沙箱的资源。

请介绍一下本项目的完整业务流程?

  1. 管理员创建题目、添加题目的测试用例
  2. 用户自由搜索题目
  3. 用户阅读题目、编写并提交代码
  4. 系统后端调用代码沙箱,对代码进行编译、运行
  5. 判题服务根据测试用例判断用户提交是否正确
  6. 用户可以查看提交记录和判题结果

你在项目中是如何设计库表的?

项目中有三个表:用户表、题目表、提交记录表

  1. 在题目提交表中,给 userId、problemId 字段添加了索引,提高了访问性能。
  2. 部分字段使用 json 格式存储,便于扩展。

在开发过程中,你遇到过比较复杂的技术问题或挑战吗?

在项目中,我遇到的一个挑战是实现代码沙箱功能,这需要通过 Docker Java 库来调用 Docker 命令。我使用了学校项目组的 Ubuntu 服务器安装了 Docker,利用 IDEA 的远程开发工具进行开发。

为了更好地理解使用 Java 与 Docker 的交互,我参考了学长之前完成的一个在线学习项目。在这个项目中,Linux 在线学习模块通过 Docker 实现了网页中的在线交互功能。我学习了该模块与 Docker 交互的实现细节,并将其应用到我的项目中。

代码沙箱和判题服务有什么关系?

  • 代码沙箱:只负责接受代码和输入,返回编译运行的结果,不负责判题
  • 判题模块:调用代码沙箱,把代码和输入用例交给代码沙箱去执行

后端部分

为什么要在项目中用到 Docker?在项目中是如何使用 Docker 的?

使用了 Docker 容器会与宿主机隔离这个特性。在容器中执行代码,避免恶意代码直接运行会影响宿主机。

使用 Docker Java 库来操作 Docker。可以通过代码调用的方式拉取镜像、创建容器、在容器中执行命令、获取输入输出等。

你是怎么保证 Docker 代码沙箱执行程序时的安全性的?

  1. 超时控制:在容器执行时设定超时时间。
  2. 资源限制:创建容器实例时,通过 HostConfig 参数限制 CPU 和内存资源。
  3. 网络限制:创建容器实例时,通过 withNetworkDisabled 禁用网络。

为什么在项目中使用 RabbitMQ 消息队列来处理判题操作?

判题需要调用代码沙箱,服务耗时较长。使用 RabbitMQ 将判题流程异步化。并且可以通过监听器的方式控制同时判题的个数,实现流量消峰。

如何保证代码沙箱服务接口的安全性?

在调用接口时需要传入一个字符串作为秘钥,服务提供方会验证秘钥。并且不暴露代码沙箱的端口,作为内网服务。

Released under the MIT License.