OJ判题项目学习笔记

(来自鱼皮项目编程导航 - 程序员一站式编程学习交流社区,做您编程学习路上的导航员,作者:liyupi (程序员鱼皮) · GitHub

有不正确的地方,欢迎更正

一、项目简介

  YaoOJ(Yao Online Judge)在线判题系统是面向编程学习者与竞赛选手的自动化评测平台,核心功能包括用户在线答题、代码提交及系统自动判题。用户可选择题目,使用 Java等编程语言编写代码并提交(本项目只实现了Java),系统通过预设的输入输出用例、时间与内存限制,结合安全沙箱技术隔离代码运行环境,实现对代码正确性、效率及安全性的自动化验证。判题结果涵盖 “通过”“答案错误”“编译错误” 等十余种状态,支持实时反馈与历史记录查询。

  项目技术栈采用Spring Cloud 微服务架构,前端基于 Vue3 与 Arco Design 组件库开发,实现用户界面与交互逻辑;后端通过消息队列(RabbitMQ)解耦判题任务,利用 Docker 构建代码沙箱确保环境隔离,并集成 MySQL 与 Redis 实现数据存储与缓存。系统设计注重可扩展性,支持多语言评测、分布式任务调度及权限管理(区分普通用户与管理员),同时提供开放接口供第三方调用。

  该项目兼具学习价值与工程实践意义:一方面可深入理解编程思想、计算机基础与架构设计,突破传统 CRUD 开发局限;另一方面,系统复杂度高、技术栈前沿,适合作为简历亮点。项目参考了 Judge0(https://github.com/judge0/judge0)、HustOJ(https://github.com/zhblue/hustoj) 等开源方案,结合自主开发实现核心判题逻辑,旨在为用户提供稳定、高效的编程评测解决方案。

技术栈:SpringBoot、SSM、Docker、RabbitMQ、Redis、Knife4j、Spring Cloud Alibaba(如Nacos、Open Feign、Gateway)

核心业务流程:

项目功能:

  1. 题目模块

    1. 创建题目(管理员)

    2. 删除题目(管理员)

    3. 修改题目(管理员)

    4. 搜索题目(用户)

    5. 在线做题

    6. 提交题目代码

  2. 用户模块

    1. 注册

    2. 登录

  3. 判题模块

    1. 提交判题(结果是否正确与错误)

    2. 错误处理(内存溢出、安全性、超时)

    3. 自主实现 代码沙箱(安全沙箱)

    4. 开放接口(提供一个独立的新服务)

二、核心技术与实现

1. 数据库设计

  • 核心表结构
    • 用户表(user):存储用户信息,包含角色字段(user/admin)用于权限控制。
    • 题目表(question):存储题目内容、输入输出用例(JSON 格式)、判题配置(时间 / 内存限制)。
    • 提交表(question_submit):记录提交记录,包括代码内容、判题状态、执行结果(JSON 格式)。
  • 索引优化:在userIdquestionId字段创建索引,提升查询效率;使用ASSIGN_ID策略生成分布式 ID,避免 ID 泄露。

2. 判题流程与策略

  • 核心流程
    1. 用户提交代码→题目服务校验权限并存储提交记录。
    2. 判题服务从队列获取任务→调用代码沙箱执行代码。
    3. 沙箱返回执行结果(如运行时间、内存占用、输出结果)。
    4. 判题服务对比用户输出与标准答案,更新判题状态(Accepted/Wrong Answer 等)。
  • 策略模式:针对不同编程语言(如 Java、C++)实现差异化判题逻辑,例如 Java 需编译后执行,C++ 直接运行可执行文件。

3. 代码沙箱设计

  • 核心目标:隔离用户代码,防止恶意操作(如内存溢出、文件读写),限制资源占用(CPU / 内存 / 时间)。
  • 实现方案
    • Java 原生实现:通过Process类执行编译命令,结合SecurityManager限制文件读写、网络连接等权限,但存在权限控制粒度粗的问题。
    • Docker 容器化:利用 Docker 的cgroupsnamespaces实现资源隔离,通过镜像管理运行环境(如 OpenJDK 镜像),支持多语言(Java/C++/Go)。核心流程:拉取镜像→创建容器→挂载代码目录→执行判题命令→回收资源。
    • 安全性优化:设置容器内存上限(-m 100m)、只读根文件系统(--read-only)、禁用网络(--network none),结合 Seccomp 过滤危险系统调用。

4. 微服务架构改造

  • 架构拆分
    • 用户服务:处理注册、登录、权限校验。
    • 题目服务:管理题目增删改查、判题任务提交。
    • 判题服务:独立服务,通过消息队列(RabbitMQ)接收判题任务,调用代码沙箱执行判题逻辑。
    • 网关服务:统一路由(Spring Cloud Gateway)、鉴权、限流(Sentinel)。
  • 服务通信
    • OpenFeign:实现服务间远程调用,如题目服务调用用户服务获取用户信息。
    • 消息队列:解耦判题任务,题目服务提交任务到队列,判题服务异步消费,避免同步调用超时问题。

三、关键挑战与解决方案

1. 安全性问题

  • 风险点:用户代码可能包含恶意指令(如删除文件、发起网络请求)。
  • 解决方案
    • 代码沙箱层:Docker 容器隔离 + Seccomp 过滤系统调用 + Java 安全管理器限制文件操作。
    • 网关层:通过GlobalAuthFilter拦截包含敏感路径(如/inner)的请求,防止未授权访问。

2. 性能优化

  • 异步化改造:将判题任务放入消息队列,避免同步处理阻塞接口响应。
  • 资源复用:Docker 容器复用(非一次性容器),减少镜像拉取和容器创建开销。
  • 缓存机制:使用 Redis 缓存用户登录状态,避免频繁查询数据库。

3. 多语言支持

  • 实现方式:为每种语言定制镜像(如openjdk:8-alpinegcc:latest),代码沙箱根据语言参数选择对应镜像执行。
  • 编译命令抽象:通过工厂模式动态生成编译命令(如javacg++),解耦语言差异。

四、学习总结

技术收获

  • 深入理解容器化技术(Docker)在隔离与资源管理中的应用。
  • 掌握微服务架构设计(服务拆分、通信机制、网关路由)。
  • 实践设计模式(工厂模式、策略模式、代理模式)在代码架构中的应用。
  • 提升数据库设计能力(字段类型选择、索引优化、JSON 字段处理)。

前端仓库:

yaooj-frontend: yaooj-frontend 是 YaoOJ 在线判题系统的前端应用,基于 Vue3 + Arco Design 构建,旨在为用户提供简洁高效的编程判题交互界面。项目聚焦于用户在线答题、代码提交、题目管理等核心场景,通过响应式设计适配 PC 与移动端,技术栈涵盖 Vue3、TypeScript、Monaco Editor 等,实现与后端微服务的无缝对接。

后端仓库

yaooj-backend: yaooj-backend 是 YaoOJ 在线判题系统的核心后端服务,负责处理用户请求、管理业务逻辑及实现自动化判题。系统采用微服务架构与容器化技术,旨在为用户提供安全、高效的编程判题平台,适用于编程学习、算法竞赛及教育场景。项目技术栈覆盖 Spring Cloud Alibaba、Docker、MyBatis-Plus 等,重点解决判题系统的资源隔离、性能优化与服务解耦问题。

代码沙箱仓库

yaooj-code-sandbox: yaooj-code-sandbox 是 YaoOJ 在线判题系统的核心模块之一,专注于用户代码的安全执行与资源隔离。其核心职责是为用户提交的代码提供独立、可控的运行环境,确保代码执行过程中不会对宿主机系统造成安全威胁,同时准确返回代码的执行结果(如输出内容、运行时间、内存占用等)。

后端微服务改造仓库:

yaooj-backend-microservice: 微服务框架 Spring Cloud Alibaba 服务注册与发现(Nacos)、网关(Gateway)、限流(Sentinel) 容器化与沙箱 Docker + Cgroups 代码沙箱环境隔离,限制内存 / CPU / 网络访问 持久化 MySQL + MyBatis-Plus 业务数据存储,支持 JSON 字段与分布式 ID 生成 消息队列 RabbitMQ 异步解耦判题任务。

五、项目页面展示

前端登录页面:

前端登录输入信息页面:

前端角色user页面:

前端角色admin页面:

前端“浏览题目”页面:

前端“浏览题目提交”页面:

前端“创建题目”页面:

前端“创建题目”输入页面:

前端“主页”页面

前端“做题”页面

聚合文档user-service页面(部分):

聚合文档question-service页面(部分):

聚合文档judge-service页面(部分):

后端yaooj-backend项目目录:

后端microservice改造目录:

后端yaooj-code-sandbox运行页面

虚拟机运行照片:

虚拟机连接SSH照片:

虚拟机项目所在地照片:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值