主题
WangOJ 在线判题平台 已完结
架构设计
请介绍整个系统后端的架构设计,有哪些模块以及各模块之间的关系?
- 用户模块:用户注册登录、用户的增删改查等管理功能
- 题目模块:题目提交、题目查看及题目的增删改查等管理功能
- 判题模块:提供判题服务,调用代码沙箱判题并对比判题结果
- 代码沙箱模块:提供代码执行的功能。作为独立服务,通过 API 接口调用,
- 公共模块:数据模型、全局请求响应封装、全局异常处理等
有调研过 OJ 系统的实现方案么?
在 GitHub 上调研了许多开源的 OJ 项目。有多种实现方案。
- 自主开发的 OJ 系统和代码沙箱。
- 使用第三方服务提供的代码执行 API。
- 远程判题,逆向其他现有平台的网站,实现一个题目聚合的功能。
除此之外我认为还可以使用 AI 进行辅助判题。通过大模型进行代码的查重和基本判题,比如提交的恶意代码或者明显错误的提交,可以直接用大模型过滤掉,节约代码沙箱的资源。
请介绍一下本项目的完整业务流程?
- 管理员创建题目、添加题目的测试用例
- 用户自由搜索题目
- 用户阅读题目、编写并提交代码
- 系统后端调用代码沙箱,对代码进行编译、运行
- 判题服务根据测试用例判断用户提交是否正确
- 用户可以查看提交记录和判题结果
你在项目中是如何设计库表的?
项目中有三个表:用户表、题目表、提交记录表
- 在题目提交表中,给 userId、problemId 字段添加了索引,提高了访问性能。
- 部分字段使用 json 格式存储,便于扩展。
在开发过程中,你遇到过比较复杂的技术问题或挑战吗?
在项目中,我遇到的一个挑战是实现代码沙箱功能,这需要通过 Docker Java 库来调用 Docker 命令。我使用了学校项目组的 Ubuntu 服务器安装了 Docker,利用 IDEA 的远程开发工具进行开发。
为了更好地理解使用 Java 与 Docker 的交互,我参考了学长之前完成的一个在线学习项目。在这个项目中,Linux 在线学习模块通过 Docker 实现了网页中的在线交互功能。我学习了该模块与 Docker 交互的实现细节,并将其应用到我的项目中。
代码沙箱和判题服务有什么关系?
- 代码沙箱:只负责接受代码和输入,返回编译运行的结果,不负责判题
- 判题模块:调用代码沙箱,把代码和输入用例交给代码沙箱去执行
后端部分
为什么要在项目中用到 Docker?在项目中是如何使用 Docker 的?
使用了 Docker 容器会与宿主机隔离这个特性。在容器中执行代码,避免恶意代码直接运行会影响宿主机。
使用 Docker Java 库来操作 Docker。可以通过代码调用的方式拉取镜像、创建容器、在容器中执行命令、获取输入输出等。
你是怎么保证 Docker 代码沙箱执行程序时的安全性的?
- 超时控制:在容器执行时设定超时时间。
- 资源限制:创建容器实例时,通过 HostConfig 参数限制 CPU 和内存资源。
- 网络限制:创建容器实例时,通过 withNetworkDisabled 禁用网络。
为什么在项目中使用 RabbitMQ 消息队列来处理判题操作?
判题需要调用代码沙箱,服务耗时较长。使用 RabbitMQ 将判题流程异步化。并且可以通过监听器的方式控制同时判题的个数,实现流量消峰。
如何保证代码沙箱服务接口的安全性?
在调用接口时需要传入一个字符串作为秘钥,服务提供方会验证秘钥。并且不暴露代码沙箱的端口,作为内网服务。