当前位置: 首页 > news >正文

wap网站微信一键登录网站开发业务怎么开展

wap网站微信一键登录,网站开发业务怎么开展,云匠网app,seo快速排名软件首页判题机架构优化(策略模式) 思考 我们的判题策略可能会有很多种 比如 我们的代码沙箱本身执行程序需要消耗时间 这个时间可能不同的编程语言是不同的 比如沙箱执行Java要额外花费2秒 我们可以采用策略模式 针对不同的情况 定义不同独立的策略 而不是把所有情况全部放在一个i…

判题机架构优化(策略模式)

思考

我们的判题策略可能会有很多种 比如 我们的代码沙箱本身执行程序需要消耗时间

这个时间可能不同的编程语言是不同的 比如沙箱执行Java要额外花费2秒

我们可以采用策略模式 针对不同的情况 定义不同独立的策略

而不是把所有情况全部放在一个if else里面

定义一个策略接口

我們先写一个方法

这个方法传入的是一个上下文对象context

package com.dduo.dduoj.judge.strategy;import com.dduo.dduoj.model.dto.questionsubmit.JudgeInfo;/*
* 判题策略
* */
public interface JudgeStrategy {/** 执行判题* @param judgeContext* @return* */JudgeInfo doJudge(JudgeContext judgeContext);}

创建这个上下文对象

我们传入的数据 有判题状态 输入用例 输出用例

用于定义在策略中传递的参数

package com.dduo.dduoj.judge.strategy;import com.dduo.dduoj.model.dto.questionsubmit.JudgeInfo;
import com.dduo.dduoj.model.entity.Question;
import lombok.Data;import java.util.List;/*
* 上下文 用于定义在策略中传递的参数
* */@Data
public class JudgeContext {private JudgeInfo judgeInfo;private List<String> inputList;private List<String> outputList;private Question question;}

接下来我们要把刚刚写的判题逻辑部分的代码搬到接口的实现类里面去

这边创建一个策略模式接口的实现类

默认实现类

类名为DefaultJudgeStrategy

我们先从上下文对象中获得信息

再进行判断

返回值

package com.dduo.dduoj.judge.strategy;import cn.hutool.json.JSONUtil;
import com.dduo.dduoj.model.dto.question.JudgeCase;
import com.dduo.dduoj.model.dto.question.JudgeConfig;
import com.dduo.dduoj.model.dto.questionsubmit.JudgeInfo;
import com.dduo.dduoj.model.entity.Question;
import com.dduo.dduoj.model.enums.JudgeInfoMessageEnum;import javax.swing.*;
import java.util.List;public class DefaultJudgeStrategyImpl implements JudgeStrategy {/*** 执行判题* @param judgeContext* @return*/@Overridepublic JudgeInfo doJudge(JudgeContext judgeContext) {// 从上下文对象获取信息JudgeInfo judgeInfo = judgeContext.getJudgeInfo();List<String> inputList = judgeContext.getInputList();List<String> outputList = judgeContext.getOutputList();Question question = judgeContext.getQuestion();List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaselist();// 从判题信息中获取信息Long memory = judgeInfo.getMemoryLimit();Long time = judgeInfo.getTime();JudgeInfo judgeInfoResponse = new JudgeInfo();JudgeInfoMessageEnum judgeInfoMessageEnum = JudgeInfoMessageEnum.Accepted;judgeInfoResponse.setMemoryLimit(memory);judgeInfoResponse.setTime(time);// 先判断沙箱执行的结果输出数量是否和预期输出数量相等if (outputList.size() != inputList.size()) {judgeInfoMessageEnum = JudgeInfoMessageEnum.Wrong_Answer;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}// 依次判断每一项输出和预期输出是否相等for (int i = 0; i < judgeCaseList.size(); i++) {JudgeCase judgeCase = judgeCaseList.get(i);if (!judgeCase.getOutput().equals(outputList.get(i))) {judgeInfoMessageEnum = JudgeInfoMessageEnum.Wrong_Answer;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}}// 判断题目限制String judgeConfigStr = question.getJudgeConfig();JudgeConfig judgeConfig = JSONUtil.toBean(judgeConfigStr, JudgeConfig.class);Long needMemoryLimit = judgeConfig.getMemoryLimit();Long needTimeLimit = judgeConfig.getTimeLimit();if (memory > needMemoryLimit) {judgeInfoMessageEnum = JudgeInfoMessageEnum.Memory_Limit_Exceeded;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}if (time > needTimeLimit) {judgeInfoMessageEnum = JudgeInfoMessageEnum.Memory_Limit_Exceeded;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}
}

我们把所有判题的内容 放到一个单独的类里面 这个类叫做默认策略

接下来我们就可以在实现类里面用默认策略去解决

先根据沙箱的执行结果设置题目的判题状态和信息

再把上下文对象放到策略模式里面去

package com.dduo.dduoj.judge;import cn.hutool.json.JSONUtil;
import com.dduo.dduoj.common.ErrorCode;
import com.dduo.dduoj.exception.BusinessException;
import com.dduo.dduoj.judge.codesandbox.CodeSandbox;
import com.dduo.dduoj.judge.codesandbox.CodeSandboxFactory;
import com.dduo.dduoj.judge.codesandbox.CodeSandboxProxy;
import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeRequest;
import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeResponse;
import com.dduo.dduoj.judge.strategy.DefaultJudgeStrategy;
import com.dduo.dduoj.judge.strategy.JudgeContext;
import com.dduo.dduoj.judge.strategy.JudgeStrategy;
import com.dduo.dduoj.model.dto.question.JudgeCase;
import com.dduo.dduoj.model.dto.questionsubmit.JudgeInfo;
import com.dduo.dduoj.model.entity.Question;
import com.dduo.dduoj.model.entity.QuestionSubmit;
import com.dduo.dduoj.model.enums.QuestionSubmitStatusEnum;
import com.dduo.dduoj.service.QuestionService;
import com.dduo.dduoj.service.QuestionSubmitService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;@Service
public class JudgeServiceImpl implements JudgeService {// 题目服务@Resourceprivate QuestionService questionService;// 题目提交服务@Resourceprivate QuestionSubmitService questionSubmitService;@Value("${codesandbox.type:example}")private String value;@Overridepublic QuestionSubmit doJudge(Long questionSubmitId) {QuestionSubmit questionSubmit = questionSubmitService.getById(questionSubmitId);if (questionSubmit == null) {throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "提交信息不存在");}//拿到题目提交信息Long questionId = questionSubmit.getQuestionId();//拿到题目Question question = questionService.getById(questionId);if (question == null) {throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "题目不存在");}// 题目存在// 开始判题// 更改题目的状态 status// 如果不为等待状态if (questionSubmit.getStatus().equals(QuestionSubmitStatusEnum.WAITING.getValue())) {throw new BusinessException(ErrorCode.OPERATION_ERROR, "题目正在判题中");}// 重新设置QuestionSubmit questionSubmitUpdate = new QuestionSubmit();questionSubmitUpdate.setId(questionSubmitId);questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.RUNNING.getValue());boolean judge = questionSubmitService.updateById(questionSubmitUpdate);if (!judge) {throw new BusinessException(ErrorCode.SYSTEM_ERROR, "题目状态更新错误");}// 接下来放代码沙箱CodeSandbox codeSandbox = CodeSandboxFactory.NewInstance(value);codeSandbox = new CodeSandboxProxy(codeSandbox);// 拿出数据String code = questionSubmit.getCode();String language = questionSubmit.getLanguage();// 获取输入用例String judgeCaseStr = question.getJudgeCase();List<JudgeCase> judgeCaselist = JSONUtil.toList(judgeCaseStr, JudgeCase.class);List<String> inputList = judgeCaselist.stream().map(JudgeCase::getInput).collect(Collectors.toList());ExecuteCodeRequest executeRequest = ExecuteCodeRequest.builder().code(code).language(language).inputList(inputList).build();ExecuteCodeResponse executeCodeResponse=codeSandbox.executeCode(executeRequest);List<String> outputList = executeCodeResponse.getOutputList();// 根据沙箱的执行结果 设置题目的判题状态和信息JudgeContext judgeContext = new JudgeContext();judgeContext.setJudgeInfo(executeCodeResponse.getJudgeInfo());judgeContext.setInputList(inputList);judgeContext.setOutputList(outputList);judgeContext.setQuestion(question);judgeContext.setJudgeCaselist(judgeCaselist);// 用默认策略去解决JudgeStrategy judgeStrategy=new DefaultJudgeStrategy();JudgeInfo judgeInfo = judgeStrategy.doJudge(judgeContext);// 修改数据库中的判题结果questionSubmitUpdate = new QuestionSubmit();questionSubmitUpdate.setId(questionSubmitId);questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.SUCCESS.getValue());questionSubmitUpdate.setJudgeInfo(JSONUtil.toJsonStr(judgeInfo));// 看数据库boolean update = questionSubmitService.updateById(questionSubmitUpdate);if (!update) {throw new BusinessException(ErrorCode.SYSTEM_ERROR, "题目状态更新错误");}// 返回结果QuestionSubmit questionSubmitResult = questionSubmitService.getById(questionId);return questionSubmitResult;}
}

刚才只是定义了默认策略

我们还要定义其他策略

如Java程序的执行的策略

接下来我们就要去想一想如何去切换策略

但是如果用简单的判断 如果有复杂的情况会很麻烦 而且 写的if else语句会变的很多

建议单独编写一个判断策略的方法 或者是类

工厂 map缓存

定义JudgeManager 目的是尽量简化对判题功能的调用

让调用方最简便

去操作

补全代码

实际上就是对我们选择合适的策略这个过程

或者是进行其他的判断的时候

进行了一个判断

package com.dduo.dduoj.judge;import com.dduo.dduoj.judge.strategy.DefaultJudgeStrategy;
import com.dduo.dduoj.judge.strategy.JavaLanguageJudgeStrategy;
import com.dduo.dduoj.judge.strategy.JudgeContext;
import com.dduo.dduoj.judge.strategy.JudgeStrategy;
import com.dduo.dduoj.model.dto.questionsubmit.JudgeInfo;
import com.dduo.dduoj.model.entity.QuestionSubmit;/*
*  判题管理(简化调用)
* */
public class JudgeManger {/** 执行判题* @param judgeContext* @return* */JudgeInfo doJudge(JudgeContext judgeContext) {QuestionSubmit questionSubmit = judgeContext.getQuestionSubmit();String language = questionSubmit.getLanguage();JudgeStrategy judgeStrategy = new DefaultJudgeStrategy();if ("java".equals(language)) {judgeStrategy = new JavaLanguageJudgeStrategy();}return judgeStrategy.doJudge(judgeContext);}}

这样就行

在之前的题目提交实现类 核心逻辑里面

那么我们的核心逻辑就是这样的

@Override
public long doQuestionSubmit(QuestionSubmitAddRequest questionSubmitAddRequest, User loginUser) {// 校验编程语言是否合法String language = questionSubmitAddRequest.getLanguage();QuestionSubmitLanguageEnum languageEnum = QuestionSubmitLanguageEnum.getEnumByValue(language);if (languageEnum == null) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "编程语言错误");}long questionId = questionSubmitAddRequest.getQuestionId();// 判断实体是否存在,根据类别获取实体Question question = questionService.getById(questionId);if (question == null) {throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);}// 是否已提交题目long userId = loginUser.getId();// 每个用户串行提交题目QuestionSubmit questionSubmit = new QuestionSubmit();questionSubmit.setUserId(userId);questionSubmit.setQuestionId(questionId);questionSubmit.setCode(questionSubmitAddRequest.getCode());questionSubmit.setLanguage(language);// 设置初始状态questionSubmit.setStatus(QuestionSubmitStatusEnum.WAITING.getValue());questionSubmit.setJudgeInfo("{}");boolean save = this.save(questionSubmit);if (!save){throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据插入失败");}// todo 执行判题服务Long questionSubmitId = questionSubmit.getId();// 执行判题服务CompletableFuture.runAsync(() -> {judgeService.doJudge(questionSubmitId);});return questionSubmitId;
}

这边懒加载

可以解决循环依赖

http://www.yayakq.cn/news/703385/

相关文章:

  • 网站如何设置长尾词编程课网课哪家好
  • 网站建设需要的技术手段用二级页面做网站的源代码
  • 深圳网站的建设保山网站建设服务
  • 简单的旅游网站怎么做wordpress出境游
  • wordpress网站设密码错误网站推广软件排名
  • 网站建设阐述中介公司注册条件
  • 通信的毕设网站建设网站建设价格差异
  • 移动网站制作小语种网站建设
  • 网站中的ppt链接怎么做的七牛云
  • 网站维护年费o2o移动电子商务平台有哪些
  • 网站与微信区别网站建设kaodezhu
  • 河北网站建设搭建网站制作佛山
  • 用html5做的美食网站wordpress电影系统
  • wordpress media.php网站SEO优化托管
  • app和网站哪个有优势宁波软件开发制作
  • 淮安网站排名优化公司在服务器网站上做跳转页面跳转页面
  • 唐山网站建设zzvg百度网站收录提交入口
  • 湖南网站备案需要多久网站设计合同
  • 网站建设公司哪家好?该如何选择什么是网络设计原则
  • 食品网站app建设方案中国建设银行下载
  • 房地产市场信息系统网站做网站要钱的吗
  • 百度网站托管常见的网上购物平台有哪些
  • 网站建设国际深圳南昌淘宝网站制作公司
  • 做网站常德加强门户网站建设 信息公开
  • 湛江网站建设开发网站建设软件培训学校
  • 更换网站程序3322做网站
  • 百度seo怎么做网站内容优化不属于网络推广方法
  • ps做网站图南宁seo优化公司
  • 学校网站建设开发项目计划报告关键词爱站网
  • 自己做盗版小说网站手机视频网站怎么做