大家好,我是程序媛雪儿。
最近学了鱼皮哥的oj判题项目,写篇文章来记录一下这波学习的收获。
一、业务方面
oj判题系统主要包括题目模块、用户模块、判题模块、沙箱模块四个模块。其核心模块是判题模块和沙箱模块,判题模块发送题目的代码,题目的输入用例给代码沙箱,代码沙箱编译执行代码得到结果,沙箱模块把得到的结果,执行信息,执行环境再返回给判题模块,由判题模块来对比输入输出用例是否一致,从而来判断题目是否正确,判题模块和代码沙箱模块是通过API交互的,代码沙箱是一个单独的项目,实现了解耦。
二、技术方向
前端比较有亮点的技术包含以下几个方面
1、自动生成typescript前端请求代码工具
使用起来很简单,安装代码生成器,生成代码就好,关键命令如下
npm install openapi-typescript-codegen --save-dev
openapi --input http://localhost:8101/api/v2/api-docs --output ./generated --client xhr
仓库地址:
https://github.com/ferdikoomen/openapi-typescript-codegen
2、整合了MarkDown编辑器,可以写.md后缀文件支持的语法,在项目里主要是用来编辑题目信息,答案,示例代码等。
仓库地址:
https://github.com/bytedance/bytemd
3、整合了monaco-editor代码编辑器,这个代码支持html、java、JavaScript,python等多种语言的提示编写高亮,在系统里主要是用来给用户回答问题的代码的。
仓库地址:
https://github.com/microsoft/monaco-editor
后端的技术亮点在代码沙箱,代码沙箱除了完成最基本的编译运行代码,返回执行结果这个业务功能,主要还提供了返回代码执行时间、占用内存等信息。考虑到用户可能写危险程序,比如故意占用时间资源,导致程序卡死,占用内存资源,导致内存溢出,读取程序隐私文件,导致信息泄露,写入密码程序,运行木马程序等等,针对时间空间资源的浪费比较好解决,时间资源浪费,那就在执行程序的时候再开个线程,监视执行代码的进程,固定时间如果程序执行不完,直接杀掉进程。空间资源的浪费就更简单了,运行代码的时候直接使用java运行的命令java -Xmx256m 来限制空间,比较麻烦的读写等操作的限制。有以下几种解决方案
1、关键词匹配
在编译运行代码前,对要执行的code进行关键词匹配,如果包含exec、write等危险信息,直接return。
2、写限制程序、比如写个安全管理器来限制读、写、执行等操作
3、用Docker实现代码沙箱
这个真的比较巧妙,容器技术可以限制使用的cpu,网络、内存、时间等等资源,我也是第一次见识到了怎么用java代码操作Docker,这个是终极解决方案。
三、其他收获
1、第一次知道可以用idea的gateway操作linux系统上的java代码运行
2、学会了根据需求画时序图、业务流程图
四、自己做的不足之处
在把项目做完之后,我也曾想着扩展扩展业务功能啥的,但是我做的技术性的内容太少了,我只是把整个页面的登录登出、前端展示使用了插槽个性化展示表格信息,从用户角度出发,给每道题提供了基础代码,保持monaco-editor可以热更新代码这种优化。
类似于功能性的优化,比如,增加其他代码的编译运行,使用多种方式计算程序使用的空间信息等等,做的比较少。
五、总结
以上是在oj系统学习过程中我的小小收获。多说一嘴,我很推荐宝子们像我一样学习个技术或者项目,写篇文章来整理一下,我觉得随着时间的流逝,我们做过的项目都可以慢慢沉淀下来成为我们自己独一无二的知识库和宝贵的财富。
希望大家可以学的开心,学有所获。
前端仓库:
https://gitee.com/gu-feiyin/snowyeeoj-frontend
后端仓库:
https://gitee.com/gu-feiyin/oj_snowyee_backend
代码沙箱仓库
https://gitee.com/gu-feiyin/snowyee-code-sandbox
项目体验上线地址:
http://www.snowyee.cn/snowyee-oj/
雪儿个人博客(上面有我完整的oj判题系统的学习笔记)
http://www.snowyee.cn/