首页 > 其他分享 >OJ在线判题系统项目笔记

OJ在线判题系统项目笔记

时间:2024-09-11 10:53:10浏览次数:9  
标签:题目 OJ 代码 笔记 获取 判题 沙箱 服务

项目介绍

在线评测编程题目代码的系统,出题人预先设置题目的输入样例和输出样例,根据用户提交代码,进行编译代码,运行代码,判断代码执行结果是否正确。

后端服务

网关服务

接收前端请求,转发到对应的服务

用户服务

用户注册、用户登录、用户退出

题目服务

题目浏览,在线做题,题目提交、提交记录

判题服务

判题服务获取调用题目服务获取题目信息,测试用例,调用代码沙箱编译运行代码并对比结果

代码沙箱

编译运行代码,返回执行结果、运行时间、运行内存

公共模块

数据模型、统一异常处理、全局响应封装、工具类

judgeCase:判题用例,包括输入用例和输出用例

judgeInfo:判题信息,包括程序执行信息,运行时间,运行内存

judgeContext:判题上下文,包括题目信息,编程语言,输出用例,输出结果,判题信息

微服务架构优点

微服务架构是一种软件架构风格,把大而全的单体应用拆分为多个职责单一的模块,每个服务单元独立部署,运行和维护。服务单元之间通过网络通信进行交互,从而实现完整系统的功能。微服务架构可以提高系统的灵活性,可维护性,可扩展性,容错性。

本项目中,使用微服务架构将较重的服务(判题服务和代码沙箱)和核心服务(用户服务和题目服务)进行分离解耦,即使判题服务因为代码沙箱压力过大而阻塞,也不会影响核心业务运行。

用户服务

普通用户

注册、登录、获取登录用户、注销、修改个人信息

管理员

增删改 根据id获取用户(包装类) 分页获取用户(包装类)

题目服务

管理员

增删改、根据id获取题目、分页获取题目

普通用户

分页获取题目(包装类)、根据id获取题目(包装类)、分页获取题目提交列表、根据id获取提交题目详情

提交题目(限流器)

题目提交流程

向题目提交表记录题目id,用户id,编程语言和用户代码,设置判题状态为待判题。通过消息队列将questionSubmit对象传递给判题服务

限流器

// 1、 声明一个限流器
RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);

// 2、 设置速率,5秒中产生3个令牌
rateLimiter.trySetRate(RateType.OVERALL, 3, 5, RateIntervalUnit.SECONDS);

// 3、试图获取一个令牌,获取到返回true
rateLimiter.tryAcquire(1)

RateType.OVERALL:所有实例共享令牌

RateType.PER_CLIENT�:单实例令牌数

redission分布式限流采用令牌桶思想和固定时间窗口,trySetRate方法设置桶的大小,利用redis key过期机制达到时间窗口目的,控制固定时间窗口内允许通过的请求量。

判题服务

判题模块作用

查询题目提交和题目信息,调用代码沙箱,把代码和输入用例交给代码沙箱去执行,收集输出结果并执行判题逻辑

判题流程

通过消息队列获得questionSubmit对象,获取题目信息,判断题目是否存在。存在提交数加1。获取用户代码,编程语言,输入用例,输出用例。更新判题状态为判题中,调用代码沙箱,获取程序运行结果,设置判题上下文对象,采用策略模式,调用不同判题方法进行判题(主要是比较不同语言的时间和内存是否超出限制以及输出用例和代码沙箱程序执行结果是否一致)设置判题状态(判题成功/判题失败)和通过数

多种代码沙箱

定义通用代码沙箱调用接口,提供多种代码沙箱的实现类

实例代码沙箱:跑通业务流程

远程代码沙箱:自主实现的代码编译、执行的沙箱接口

三方代码沙箱:开源的代码沙箱服务 judge0的代码沙箱

远程和三方代码沙箱通过http调用

沙箱类型配置化:application.yml中动态配置沙箱类型

沙箱实例工厂化:读取配置,适用工厂模式,创建对应的代码沙箱实现类

沙箱调用代理化:使用代理模式,在调用代码沙箱前后进行统一的日志操作

代码沙箱

实现方式

Java原生代码沙箱和Docker代码沙箱

实现思路

用户代码保存为文件

编译代码,得到class文件

String compileCmd = "javac -encoding utf-8 Main.java";
Process compileProcess = Runtime.getRuntime().exec(comoileCmd);
int exitCode = compileProcess.waitFor()
if(exitCode==0){
    逐行读取输出;
}else{
    逐行读取正常输出;
    逐行读取异常输出;
}

执行java代码

String runCmd = "java Main.java"+inputArgs;
Process runProcess = Runtime.getRuntime().exec(runCmd);

收集整理输出结果

执行结果、执行时间、执行内存

文件清理,释放空间

错误处理,提升程序健壮性

异常情况

执行超时

占用内存

读文件

写文件

运行其他程序

执行高危操作

安全控制

超时控制

创建守护线程,超时自动中断Process

限制资源分配

java -Xmx256M

限制最大占用堆空间256M

限制代码–黑白名单

public static final List<String> balckList = Arrays.asList("Files","exec");

限制权限

Java安全管理器

public class DefaultSecurityManager extends SecurityManager{
    public void checkPermission(Permission perm) {
        throw new RuntimeException("权限异常"+perm.toString());
    }

    public void checkRead(String file) {
        throw new RuntimeException("Read权限异常"+file);
    }

    public void checkWrite(String file) {
        throw new RuntimeException("Write权限异常"+file);
    }

    public void checkExec(String file) {
        throw new RuntimeException("Exec权限异常"+file);
    }

    public void checkConnect(String host,int port) {
        throw new RuntimeException("Connect权限异常"+host+":"+port);
    }
    
}

执行Java代码时

java -Dfile.encoding=UTF-8 -Djava.security.manager=DefaultSecurityManager -cp . Main

运行环境隔离

Java原生代码沙箱

通过Process.exec执行命令行操作来执行代码,并通过Process对象的流来获取输出结果,不够安全

Docker代码沙箱

创建隔离的Java容器并且通过exec命令在容器内执行Java代码和获取输出,更加安全。

用户代码保存为文件

编译为.class文件

拉取镜像、创建容器、运行容器,执行代码,得到输出结果

创建一个交互容器,创建容器时,指定文件路径,把本地文件同步到容器中

创建容器时,进行内存限制,网络限制,读写限制

设计模式

工厂模式

代理模式

策略模式

模版方法模式

标签:题目,OJ,代码,笔记,获取,判题,沙箱,服务
From: https://blog.csdn.net/m0_45362454/article/details/142133998

相关文章

  • PMP模拟考试第48题笔记
    注:quiteresistan 相当抵抗 originally 起初engage参与stakeholderengagementassessmentmatrix 利益相关者参与评估矩阵assessment 评估riskregister  风险登记册stakeholderoutlining  利益相关者概述在管理大型项目时,处理利益相关者的支持和抗拒......
  • kafka入门(千峰)学习笔记
    前言视频链接https://www.bilibili.com/video/BV1Xy4y1G7zA一、kafka介绍1、为什么使用消息队列实现异步通信2、消息队列的流派消息队列解决了通信问题(1)、有broker(类似消息中转站)a.重topic:kafka、activemq、rocketmqb.轻topic:rabbitmq(2)、无broker:zeromq3、kafka安......
  • LAMAR论文阅读笔记
    LargeLanguageModelsAugmentedRatingPredictioninRecommenderSystem论文阅读笔记Abstract现存的问题:​ 由于对推荐中的协作信息缺乏了解,它们在推荐任务(如评分预测任务)中的直接应用往往达不到最佳效果。提出方法:​ 在本文中,我们提出了LargelAnguageModelAugmented......
  • 【爬虫软件】小红书按关键词批量采集笔记,含笔记正文、转评赞藏等!
    一、背景介绍1.1爬取目标熟悉我的小伙伴都了解,我之前开发过2款软件:【GUI软件】小红书搜索结果批量采集,支持多个关键词同时抓取!【GUI软件】小红书详情数据批量采集,含笔记内容、转评赞藏等!现在介绍的这个软件,相当于以上2个软件的结合版,即根据关键词爬取笔记的详情数......
  • shader 案例学习笔记之绘制圆
    环境搭建:参考glslvscode环境搭建先上代码#ifdefGL_ESprecisionmediumpfloat;#endifuniformvec2u_resolution;voidmain(){vec2st=gl_FragCoord.xy/u_resolution.xy;st-=0.5;st.x*=u_resolution.x/u_resolution.y;floatr=length(st);......
  • C#笔记9 对线程Thread的万字解读 小小多线程直接拿下!
    上一条笔记有些潦草,这是因为昨天并没有很好的理解线程可以进行的操作。今天准备细化自己对这方面的理解和记录。来看看细节吧!环境:VS2022系统:windows10环境:.Net8.0以及.NetFrameWork4.7.2(winform)线程是什么?线程是什么?每个操作系统上运行的应用程序都是一个进程,一个......
  • 思源笔记-S3-七牛云-多设备同步
    文档参考:思源笔记配置S3同步、思源笔记使用七牛云编写日期:2024.9.9一、思源笔记安装思源笔记官方下载地址选择对应系统版本进行下载双击【SiYuanInstaller.exe】进行安装二、注册账号注册账号是为了购买订阅,订阅后才提供S3/WEBDAV同步功能打开SiYuan......
  • 代码整洁之道--读书笔记(7)
    代码整洁之道简介:本书是编程大师“Bob大叔”40余年编程生涯的心得体会的总结,讲解要成为真正专业的程序员需要具备什么样的态度,需要遵循什么样的原则,需要采取什么样的行动。作者以自己以及身边的同事走过的弯路、犯过的错误为例,意在为后来者引路,助其职业生涯迈上更高台阶。本......
  • 《计算机算法设计与分析》笔记
    第一章算法概述1.1算法性质:输入、输出、确定性、有限性1.2时间复杂度上界记号O:如果存在正的常数C和自然数N0,使得当N≧N0时有f(N)≦Cg(N),则f(N)有上界函数g(N),记为f(N)=O(g(N))。同阶记号θ:f(N)=θ(g(N))表示f(N)和g(N)同阶。下界记号Ω:如果存在正的常数C和自然数N0......
  • 高级java每日一道面试题-2024年9月06日-基础篇-Java中的PO、VO、BO、DO、DAO、DTO、PO
    如果有遗漏,评论区告诉我进行补充面试官:Java中的PO、VO、BO、DO、DAO、DTO、POJO是什么意思?我回答:PO持久化对象(PersistentObject)PO是持久化对象,用于表示数据库中的实体或表的映射通常与数据库表的结构和字段对应PO的属性对应数据库表的字段,可以进行持久化操作(新......