文章目录
一、项目介绍
本项目是实现一个仿 leetcode 的 OJ (Online-Judge)系统。更准确的说应该称之为leetcode 的裁剪版。因为本项目只实现了leetcode中展示题目列表 + 在线测评的功能。至于leetcode中的其他功能例如:社区、论坛、求职等功能暂未实现,大家可自行进行扩展。
想必大家多多少少都体验过 OJ,这里就不谈如何使用了。项目最终成果如下,可自行体验:
- 主界面
  
- 题目列表 (题库自行扩充 我这里偷懒了)
  
- OJ 界面
  
二、开发环境
本项目我使用的开发环境如下:
- Linux(CentOS 8);
- vscode + vim;
- g++/gdb;
- MakeFile;
- Docker;
- MySQL;
三、第三方库
- Boost:实现字符串切割;
- cpp-httplib:一个简单好用的开源网络库;
- ctemplate:一个简单好用的开源前端网络渲染库;
- jsoncpp:用于序列化与反序列化;
- mysqlclient:C++ 操作 MySQL;
本项目虽然用到了前端相关的库,但是本项目相对的弱化了前端的部分,只实现了必要的功能。
四、相关技术
- C/C++ 基础知识;
- STL 库;
- C++11 语法;
- Linux 基础;
- 网络基础;
- 多进程 + 多线程(httplib 库);
- 负载均衡;
- MySQL 增删改查(非必须本项目提供文件版与MySQL版);
- Docker 基础操作;
五、项目整体框架
本项目是一个OJ系统,意味着以下的流程是必要的:
- 用户访问 OJ 服务网站;
- 用户通过网页选择获取题目列表;
- 服务端 oj_server 模块读取题库信息进行响应;
- 用户选择题目进入OJ界面;
- 服务端 oj_server 读取题目信息进行响应 + 网页渲染(题目标题,题目内容,预设代码等);
- 用户进行编程并提交代码;
- 服务端 oj_server 模块获取用户提交的代码,并整合题目信息;
- 之后 oj_server 的判题功能启动(Judge 函数),Judge 内部请求编译运行服务(compile_and_run模块),并得到运行结果;
- 服务端 oj_server 将结果相应给用户;

通过以上流程,不难看出本项目主要由以下模块构成:
- oj_server:使用 MVC 架构完成前后端的联动;- Model模块:负责数据的存储和业务逻辑。即题库的加载和存储;
- View模块:负责将数据呈现给用户。将题库展现在前端页面上并于用户进行交互;
- Controller模块:主要的逻辑控制模块。Model 与 View 的中介;
 
- compiler:编译运行模块。只负责 oj_server 所提供的代码的编译和运行,并返回结果;- 编译模块(使用程序替换执行 g++ 进行编译工作)
- 运行模块(运行可执行程序,收集程序的标准输出、标准错误内容)
- 编译运行模块(整合编译和运行的功能)
 
除此之外还有一些辅助的模块:
- log:日志模块。负责打印日志信息(这里使用的是我的另一个项目------多功能日志系统,当然你们可以用 cout 来代替);
- comm:公共模块。主要是一个通用工具类和第三方库;
代码目录框架
            
            
              bash
              
              
            
          
          contos 8 $ tree online-judge/
online-judge/
├── comm
│   ├── httplib.h
│   └── util.hpp
├── compiler
│   ├── compile_and_run.cpp
│   ├── compile_and_run.hpp
│   ├── compiler.hpp
│   ├── compiler_server
│   ├── makefile
│   └── runner.hpp
├── Dockerfile
├── LICENSE
├── log
│   ├── example
│   │   ├── makefile
│   │   └── test.cc
│   ├── extend
│   │   └── test.cc
│   ├── LICENSE
│   ├── logs
│   │   ├── buffer.hpp
│   │   ├── format.hpp
│   │   ├── level.hpp
│   │   ├── logger.hpp
│   │   ├── log.h
│   │   ├── looper.hpp
│   │   ├── message.hpp
│   │   ├── sink.hpp
│   │   └── util.hpp
│   ├── practice
│   │   ├── Agency.cc
│   │   ├── arg.c
│   │   ├── arg.cc
│   │   ├── Builder.cc
│   │   ├── Factory.cc
│   │   └── Singleton.cc
│   ├── README.en.md
│   └── README.md
├── oj_server
│   ├── conf
│   │   └── service_machine.conf
│   ├── makefile
│   ├── oj_control.hpp
│   ├── oj_model.hpp
│   ├── oj_model_sql.hpp
│   ├── oj_server
│   ├── oj_server.cpp
│   ├── oj_view.hpp
│   ├── questions
│   │   ├── 1
│   │   │   ├── desc.txt
│   │   │   ├── pre_code.cpp
│   │   │   └── test_code.cpp
│   │   ├── 2
│   │   │   ├── desc.txt
│   │   │   ├── pre_code.cpp
│   │   │   └── test_code.cpp
│   │   ├── 3
│   │   │   ├── desc.txt
│   │   │   ├── pre_code.cpp
│   │   │   └── test_code.cpp
│   │   ├── 4
│   │   │   ├── desc.txt
│   │   │   ├── pre_code.cpp
│   │   │   └── test_code.cpp
│   │   ├── 5
│   │   │   ├── desc.txt
│   │   │   ├── pre_code.cpp
│   │   │   └── test_code.cpp
│   │   ├── 6
│   │   │   ├── desc.txt
│   │   │   ├── pre_code.cpp
│   │   │   └── test_code.cpp
│   │   ├── 7
│   │   │   ├── desc.txt
│   │   │   ├── pre_code.cpp
│   │   │   └── test_code.cpp
│   │   └── questions.list
│   ├── template
│   │   ├── all_questions.html
│   │   └── one_question.html
│   └── wwwroot
│       └── index.html
├── README.en.md
├── README.md
└── temp
20 directories, 68 files