轻量级编程题评测系统(Compatible Programming Problem Judger)。后端基于 go-judge 沙箱运行,支持传统题与 SPJ(testlib 检查器)。提供简单稳定的 REST API,便于与评测脚本、OJ 或自动化流水线对接。
主要特性:多语言(C++17 / Python3 / PyPy3 / Java)、YAML 题目配置(支持子任务)、沙箱内编译与运行、testlib 检查器自动编译、内存队列 + 本地持久化结果、提交分桶归档、REST API。 (GitHub)
# 1) 安装 Node.js 18+ 与评测依赖(编译器/运行时)
sudo apt update
sudo apt install -y g++ openjdk-17-jdk-headless python3 pypy3
# 2) 启动 go-judge(需按你的 mount 配置启动)
go-judge --mount-conf=mount.yaml
# 3) 启动 LightCPVerifier 服务
npm install
node index.js
# 默认监听 8081(可用 PORT 环境变量修改)
若在容器中使用 testlib,请将 testlib 复制到镜像并通过
mount.yaml只读挂载,如:- source: /lib/testlib destination: /lib/testlib readOnly: true,然后以--mount-conf=mount.yaml启动 go-judge。(GitHub)
仓库已包含 Dockerfile 与 docker-compose.yml,可在一台 Ubuntu 服务器上直接构建与编排(按需将 go-judge 与本服务放入同一网络,映射 题目/提交目录)。
LightCPVerifier/
├── problems/ # 题目数据
│ └── <pid>/
│ ├── config.yaml # 配置
│ ├── statement.txt # 题面
│ ├── checker.cc # 检查器(默认 checker.cpp)
│ └── testdata/ # 测试数据 (.in/.out 或 .in/.ans)
├── data/ # 运行时数据(计数器等)
├── submissions/ # 提交归档(分桶)
├── index.js # 服务主程序
└── package.json
(以上组织与现有 README 描述一致,这里做了更清晰的注释与定位。)(GitHub)
示例 problems/<pid>/config.yaml:
type: default
time: 1s
memory: 256m
subtasks:
- score: 100
n_cases: 10
checker: chk.cc
checker_type: testlib
filename: main.cpp
支持子任务/测试点维度的时空限制、testlib/SPJ、指定编译入口文件等。(GitHub)
- 启动 go-judge:确保
mount.yaml、seccomp.yaml、cgroup等配置按你的环境就绪。 - 启动服务:
# 常用环境变量见下节
PORT=8081 \
GJ_ADDR=http://127.0.0.1:5050 \
JUDGE_WORKERS=4 \
node index.js
默认端口为
8081;如有反向代理(Apache2/Nginx),按需将该端口转发到公网域名。
| 变量名 | 默认值 | 说明 |
|---|---|---|
PORT |
8081 |
服务监听端口 |
GJ_ADDR |
http://127.0.0.1:5050 |
go-judge HTTP 地址 |
TESTLIB_INSIDE |
/lib/testlib |
testlib 在沙箱内的路径(与 mount.yaml 对应) |
SUB_BUCKET |
100 |
提交分桶大小(避免单目录过多文件) |
SUBMISSIONS_DIR |
./submissions |
本地提交归档目录 |
JUDGE_WORKERS |
4 |
评测并发 worker 数量 |
以上键名与默认值来自仓库现有 README 的“环境变量”表。生产环境可将
JUDGE_WORKERS设置为物理核数或nproc结果(如需限制 CPU,可结合容器/CGroups)。(GitHub)
提交一份代码进行评测。
请求体(JSON):
{
"pid": "A001",
"lang": "cpp",
"code": "#include <bits/stdc++.h>\nusing namespace std; int main(){ /* ... */ }"
}
响应:
{ "sid": 1 }
路由接受 JSON 形式的
pid/lang/code,返回自增的sid。(GitHub)
查询某次提交的评测结果。
响应示例:
{
"status": "done",
"passed": true,
"cases": [
{ "ok": true, "status": "Accepted", "time": 1000000, "memory": 65536, "msg": "" }
]
}
当
status为进行中时,你会得到非最终状态。cases为逐点结果(时间单位纳秒、内存单位字节)。(GitHub)
获取题面(纯文本)。
返回该题
statement.txt的内容。(GitHub)
列出题目清单;加 ?statement=true 时,会同时返回题面。
用于小型入口或静态站点生成。(GitHub)
导出提交归档(tar.gz)。
便于批量分析/离线备份。(GitHub)
健康检查端点,返回:
{ "ok": true }
可用于容器/负载均衡存活探测。(GitHub)
- 题目打包:建议仓库外维护一个
problems/根目录,便于与版本库分离;生产环境只同步必要文件(config.yaml、statement.txt、testdata/、checker.cc)。 - 并发与资源:
JUDGE_WORKERS的并发需要与 go-judge 的Parallelism、CPU 核数、I/O 带宽综合衡量;建议逐步加压并观察耗时/队列长度。 - SPJ/testlib:确认镜像/沙箱内
testlib路径与TESTLIB_INSIDE、mount.yaml保持一致,否则会出现编译/运行找不到头文件或可执行文件的问题。
本项目基于 AGPL-3.0 开源。(GitHub)