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

甘肃住房与城乡建设部网站高端网站设计v芯hyhyk1推好

甘肃住房与城乡建设部网站,高端网站设计v芯hyhyk1推好,佛山关键词排名效果,杭州网站开发培训《深入剖析 JudgeServiceImpl 类:题目的判题逻辑详解》 一、引言 在编程竞赛或者在线编程平台中,判题服务是核心功能之一。它负责对用户提交的代码进行编译、执行,并根据预设的测试用例判断代码的正确性。今天我们就来详细剖析一个名为 Jud…

《深入剖析 JudgeServiceImpl 类:题目的判题逻辑详解》

一、引言

在编程竞赛或者在线编程平台中,判题服务是核心功能之一。它负责对用户提交的代码进行编译、执行,并根据预设的测试用例判断代码的正确性。今天我们就来详细剖析一个名为 JudgeServiceImpl 的 Java 服务类,它实现了题目的判题逻辑。

二、代码整体概述

JudgeServiceImpl 类实现了 JudgeService 接口,主要用于处理题目的判题流程。整个判题过程可以分为以下几个主要步骤:

  1. 获取题目和提交信息:根据题目提交 ID 获取对应的题目和提交信息。
  2. 检查提交状态:确保题目提交状态为等待中,避免重复判题。
  3. 更新状态为判题中:将题目提交状态更新为“判题中”,防止重复执行。
  4. 调用代码沙箱:执行用户提交的代码,获取执行结果。
  5. 设置判题状态和信息:根据沙箱执行结果设置题目的判题状态和信息。
  6. 更新数据库判题结果:将最终的判题结果更新到数据库中。

三、代码详细解析

3.1 类的定义和依赖注入

@Service
public class JudgeServiceImpl implements JudgeService {@Resourceprivate QuestionFeignClient questionFeignClient;@Resourceprivate JudgeManager judgeManager;@Value("${codesandbox.type:example}")private String type;// ... 其他代码 ...
}
  • @Service 注解表明这是一个 Spring 服务类。
  • QuestionFeignClient 用于远程调用获取题目和提交信息,以及更新提交状态。
  • JudgeManager 负责具体的判题逻辑。
  • @Value 注解用于获取配置文件中代码沙箱的类型,默认值为 example

3.2 获取题目和提交信息

@Override
public QuestionSubmit doJudge(long questionSubmitId) {// 1)传入题目的提交 id,获取到对应的题目、提交信息(包含代码、编程语言等)QuestionSubmit questionSubmit = questionFeignClient.getQuestionSubmitById(questionSubmitId);if (questionSubmit == null) {throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "提交信息不存在");}Long questionId = questionSubmit.getQuestionId();Question question = questionFeignClient.getQuestionById(questionId);if (question == null) {throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "题目不存在");}// ... 其他代码 ...
}
  • 通过 questionFeignClient 根据 questionSubmitId 获取题目提交信息。
  • 如果提交信息不存在,抛出 BusinessException 异常。
  • 从提交信息中获取 questionId,再通过 questionFeignClient 获取对应的题目信息。
  • 如果题目信息不存在,同样抛出异常。

3.3 检查提交状态

// 2)如果题目提交状态不为等待中,就不用重复执行了
if (!questionSubmit.getStatus().equals(QuestionSubmitStatusEnum.WAITING.getValue())) {throw new BusinessException(ErrorCode.OPERATION_ERROR, "题目正在判题中");
}
  • 检查题目提交状态是否为等待中,如果不是则抛出异常,避免重复判题。

3.4 更新状态为判题中

// 3)更改判题(题目提交)的状态为 “判题中”,防止重复执行
QuestionSubmit questionSubmitUpdate = new QuestionSubmit();
questionSubmitUpdate.setId(questionSubmitId);
questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.RUNNING.getValue());
boolean update = questionFeignClient.updateQuestionSubmitById(questionSubmitUpdate);
if (!update) {throw new BusinessException(ErrorCode.SYSTEM_ERROR, "题目状态更新错误");
}
  • 创建一个 QuestionSubmit 对象,设置其 ID 和状态为“判题中”。
  • 调用 questionFeignClientupdateQuestionSubmitById 方法更新状态。
  • 如果更新失败,抛出异常。

3.5 调用代码沙箱

// 4)调用沙箱,获取到执行结果
CodeSandbox codeSandbox = CodeSandboxFactory.newInstance(type);
codeSandbox = new CodeSandboxProxy(codeSandbox);
String language = questionSubmit.getLanguage();
String code = questionSubmit.getCode();
// 获取输入用例
String judgeCaseStr = question.getJudgeCase();
List<JudgeCase> judgeCaseList = JSONUtil.toList(judgeCaseStr, JudgeCase.class);
List<String> inputList = judgeCaseList.stream().map(JudgeCase::getInput).collect(Collectors.toList());
ExecuteCodeRequest executeCodeRequest = ExecuteCodeRequest.builder().code(code).language(language).inputList(inputList).build();
ExecuteCodeResponse executeCodeResponse = codeSandbox.executeCode(executeCodeRequest);
List<String> outputList = executeCodeResponse.getOutputList();
  • 使用 CodeSandboxFactory 创建代码沙箱实例,并使用代理包装。
  • 从提交信息中获取代码和编程语言。
  • 从题目信息中获取输入用例,并转换为列表。
  • 创建 ExecuteCodeRequest 对象,包含代码、编程语言和输入用例列表。
  • 调用代码沙箱的 executeCode 方法执行代码,获取执行结果。

3.6 设置判题状态和信息

// 5)根据沙箱的执行结果,设置题目的判题状态和信息
JudgeContext judgeContext = new JudgeContext();
judgeContext.setJudgeInfo(executeCodeResponse.getJudgeInfo());
judgeContext.setInputList(inputList);
judgeContext.setOutputList(outputList);
judgeContext.setJudgeCaseList(judgeCaseList);
judgeContext.setQuestion(question);
judgeContext.setQuestionSubmit(questionSubmit);
JudgeInfo judgeInfo = judgeManager.doJudge(judgeContext);
  • 创建 JudgeContext 对象,将执行结果、输入用例、题目信息等设置到上下文中。
  • 调用 JudgeManagerdoJudge 方法进行具体的判题逻辑,得到判题信息。

3.7 更新数据库判题结果

// 6)修改数据库中的判题结果
questionSubmitUpdate = new QuestionSubmit();
questionSubmitUpdate.setId(questionSubmitId);
questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.SUCCEED.getValue());
questionSubmitUpdate.setJudgeInfo(JSONUtil.toJsonStr(judgeInfo));
update = questionFeignClient.updateQuestionSubmitById(questionSubmitUpdate);
if (!update) {throw new BusinessException(ErrorCode.SYSTEM_ERROR, "题目状态更新错误");
}
QuestionSubmit questionSubmitResult = questionFeignClient.getQuestionSubmitById(questionSubmitId);
return questionSubmitResult;
  • 创建一个新的 QuestionSubmit 对象,设置其 ID、状态为“成功”,并将判题信息转换为 JSON 字符串。
  • 调用 questionFeignClientupdateQuestionSubmitById 方法更新数据库中的判题结果。
  • 如果更新失败,抛出异常。
  • 最后再次获取更新后的题目提交信息并返回。

四、代码优化建议

4.1 异常处理优化

在获取题目和提交信息时,如果信息不存在,直接抛出 BusinessException,可能会导致上层调用者难以处理。可以在抛出异常前记录日志,方便后续排查问题。同时,可以考虑提供更详细的错误信息。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;@Service
public class JudgeServiceImpl implements JudgeService {private static final Logger logger = LoggerFactory.getLogger(JudgeServiceImpl.class);// ... 其他代码 ...@Overridepublic QuestionSubmit doJudge(long questionSubmitId) {// 1)传入题目的提交 id,获取到对应的题目、提交信息(包含代码、编程语言等)QuestionSubmit questionSubmit = questionFeignClient.getQuestionSubmitById(questionSubmitId);if (questionSubmit == null) {logger.error("提交信息不存在,提交 ID: {}", questionSubmitId);throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "提交信息不存在,提交 ID: " + questionSubmitId);}Long questionId = questionSubmit.getQuestionId();Question question = questionFeignClient.getQuestionById(questionId);if (question == null) {logger.error("题目不存在,题目 ID: {}", questionId);throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "题目不存在,题目 ID: " + questionId);}// ... 其他代码 ...}
}

4.2 重复更新操作优化

在更新题目提交状态和判题结果时,都调用了 questionFeignClient.updateQuestionSubmitById 方法,代码存在重复。可以将更新操作封装成一个单独的方法,提高代码的复用性。

private boolean updateQuestionSubmit(QuestionSubmit questionSubmitUpdate) {return questionFeignClient.updateQuestionSubmitById(questionSubmitUpdate);
}@Override
public QuestionSubmit doJudge(long questionSubmitId) {// ... 其他代码 ...// 3)更改判题(题目提交)的状态为 “判题中”,防止重复执行QuestionSubmit questionSubmitUpdate = new QuestionSubmit();questionSubmitUpdate.setId(questionSubmitId);questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.RUNNING.getValue());if (!updateQuestionSubmit(questionSubmitUpdate)) {throw new BusinessException(ErrorCode.SYSTEM_ERROR, "题目状态更新错误");}// ... 其他代码 ...// 6)修改数据库中的判题结果questionSubmitUpdate = new QuestionSubmit();questionSubmitUpdate.setId(questionSubmitId);questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.SUCCEED.getValue());questionSubmitUpdate.setJudgeInfo(JSONUtil.toJsonStr(judgeInfo));if (!updateQuestionSubmit(questionSubmitUpdate)) {throw new BusinessException(ErrorCode.SYSTEM_ERROR, "题目状态更新错误");}// ... 其他代码 ...
}

4.3 错误处理优化

在调用代码沙箱执行代码时,如果出现异常,没有进行处理。可以添加异常处理逻辑,将题目提交状态更新为“失败”。

try {ExecuteCodeResponse executeCodeResponse = codeSandbox.executeCode(executeCodeRequest);List<String> outputList = executeCodeResponse.getOutputList();// ... 其他代码 ...
} catch (Exception e) {logger.error("代码沙箱执行代码出错,提交 ID: {}", questionSubmitId, e);QuestionSubmit questionSubmitUpdate = new QuestionSubmit();questionSubmitUpdate.setId(questionSubmitId);questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.FAILED.getValue());if (!updateQuestionSubmit(questionSubmitUpdate)) {logger.error("题目状态更新为失败出错,提交 ID: {}", questionSubmitId);}throw new BusinessException(ErrorCode.SYSTEM_ERROR, "代码沙箱执行代码出错");
}

4.4 最后获取结果的 ID 错误修正

questionFeignClient.getQuestionSubmitById(questionId); 这里传入的是 questionId,应该传入 questionSubmitId

QuestionSubmit questionSubmitResult = questionFeignClient.getQuestionSubmitById(questionSubmitId);
return questionSubmitResult;

五、总结

通过对 JudgeServiceImpl 类的详细剖析,我们了解了题目的判题逻辑的具体实现。同时,通过优化建议,我们可以提高代码的健壮性、可维护性和可读性,避免一些潜在的错误。在实际开发中,我们可以根据具体需求对代码进行进一步的扩展和优化。


文章转载自:

http://ZdaG2tbW.mnjyf.cn
http://rxvdAcfE.mnjyf.cn
http://x36AtC6z.mnjyf.cn
http://WKadNrTH.mnjyf.cn
http://QaKgIAzh.mnjyf.cn
http://DqPf4fyn.mnjyf.cn
http://Hu91p49X.mnjyf.cn
http://yl4jBL0V.mnjyf.cn
http://dKR3UjZm.mnjyf.cn
http://DwmRkKra.mnjyf.cn
http://euXc3aWI.mnjyf.cn
http://0hmndzYa.mnjyf.cn
http://zJeyuVtp.mnjyf.cn
http://TBwcdQkI.mnjyf.cn
http://fjcWhDru.mnjyf.cn
http://qcZ5qHSi.mnjyf.cn
http://hJUJUN7P.mnjyf.cn
http://cDgZQgVX.mnjyf.cn
http://jxQV8jic.mnjyf.cn
http://sXGUAX8A.mnjyf.cn
http://pRhafRE2.mnjyf.cn
http://jAcOCByL.mnjyf.cn
http://gb9so4Rb.mnjyf.cn
http://ly1ZSYIn.mnjyf.cn
http://AKkcqnZp.mnjyf.cn
http://Jba2RnaI.mnjyf.cn
http://Cd6SRna7.mnjyf.cn
http://moFRmTFW.mnjyf.cn
http://Spws5apg.mnjyf.cn
http://4oqn6bns.mnjyf.cn
http://www.dtcms.com/wzjs/645214.html

相关文章:

  • 深圳 网站设手机端网站开发教程
  • 电子商务网站的建设论文物流行业网站建设方案
  • 苏州专业网站设计制作公司设计之家官网效果图
  • 网站备案时要不要关闭内容营销包括
  • 建设商城网站多少钱域名证书怎么申请
  • 哪个网站可以上传设计的作品怎么做网站seo优化
  • 丹灶建网站sap.net网站开发
  • 贵州省住房和城乡建设厅网网站网站带支付源码
  • 做自己的网站流量怎么如何注册属于自己的网站
  • 成品软件源码网站大全阿里服务器可以做多少个网站
  • o2o商超网站建设手机怎么创建自己的网站平台
  • 移动网站seo推广计划方案模板
  • 北京网络网站建设价格低公司网站要备案吗
  • 北京外包网站怎么制作网站
  • 图片素材网站哪个最多牛商网网站后台
  • 丹东网站seo我的网站在百度搜不到了
  • 网站建设制作设计建设银行网站怎么打印明细
  • 上海嘉定网站建设公司漂亮的数据型网站
  • 网站正在建设中...为什么护卫神华龙网重庆网络问政平台
  • 四川网站建设多少钱建站平台wp
  • 网站建设优缺点wordpress 变装小说
  • 网页设计与网站建设全攻略樱桃企业网站管理系统v1.1-cms
  • 浙江建设职业技术学院继续教育学院网站网推app下载
  • 网站建设微信运营推广小程序流量点击推广平台
  • 家用电器行业外贸建站搜房网站建设分析
  • 建设互联网教育网站建筑直聘网
  • 西部数码网站管理助手 v3.0湖南至诚建设机械有限公司网站
  • 金融视频直播网站开发wordpress 4.9.8微博图床
  • sdcms网站建设模板怎么制作属于自己的网站
  • 郑州东区做网站的公司在线商城开发费用