沈阳网站建设制作公司网站目标建设

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

沈阳网站建设制作公司,网站目标建设,wordpress站点结构,泉州建设人才网站判题机模块预开发(架构师)(工厂模式) 判题机模块 是为了把代码交个代码沙箱去处理 得到结果返回 代码沙箱 梳理判题模块和代码沙箱的关系 判题模块#xff1a;调用代码沙箱 把代码和输入交给代码沙箱去执行 代码沙箱#xff1a;只负责接受代码和输入 返回编译的结果 不负…判题机模块预开发(架构师)(工厂模式) 判题机模块 是为了把代码交个代码沙箱去处理 得到结果返回 代码沙箱 梳理判题模块和代码沙箱的关系 判题模块调用代码沙箱 把代码和输入交给代码沙箱去执行 代码沙箱只负责接受代码和输入 返回编译的结果 不负责判题 这两个模块完全解耦 我们采用API交互 为什么代码沙箱要接受和输出一组运行用例 前提我们的每道题目有多组测试用例 如果每个用例单独调用一个代码用例 会调用多次接口 需要多次网络运输 程序要多次编译 记录程序的执行状态 重复的代码不重复编译 这是一种常见的性能优化的方法 创建一个新的包 用来放代码沙箱模块 先写一个接口 package com.dduo.dduoj.judge.codesandbox;public interface CodeSandbox {ExecuteCodeRequest executeCode(ExecuteCodeRequest executeCodeRequest); } 提高通用性 之后我们的项目代码只调用接口 不调用具体的实现类 就不用去修改名称了 便于拓展 写一下实体类 ExecuteCodeRequest请求 package com.dduo.dduoj.judge.codesandbox.model;import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor;import java.util.List;Data Builder NoArgsConstructor AllArgsConstructor public class ExecuteCodeRequest {private ListString inputList;private String code;private String language; } ExecuteCodeResponse响应 package com.dduo.dduoj.judge.codesandbox.model;import com.dduo.dduoj.model.dto.question.JudgeConfig; import com.dduo.dduoj.model.dto.questionsubmit.JudgeInfo;import java.util.List;public class ExecuteCodeResponse {private ListString outputList;//执行信息private String message;//执行状态private Integer status;private JudgeInfo judgeInfo; } 完善 定义不同的代码沙箱实现类 示例代码沙箱 远程代码沙箱 第三方代码沙箱 架构工作 lombok Builder注解 测试一下 package com.dduo.dduoj.judge.codesandbox;import com.dduo.dduoj.judge.codesandbox.impl.ExampleCodeSandbox; import com.dduo.dduoj.judge.codesandbox.impl.RemoteCodeSandbox; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeRequest; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeResponse;import com.dduo.dduoj.model.enums.QuestionSubmitLanguageEnum; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;import java.util.Arrays; import java.util.List;SpringBootTest class CodeSandboxTest {Testvoid executeCode() {CodeSandbox codeSandbox new RemoteCodeSandbox();String code int main() { };String language QuestionSubmitLanguageEnum.JAVA.getValue();ListString inputList Arrays.asList(1 2, 3 4);ExecuteCodeRequest executeCodeRequest ExecuteCodeRequest.builder().code(code).language(language).inputList(inputList).build();ExecuteCodeResponse executeCodeResponse codeSandbox.executeCode(executeCodeRequest);Assertions.assertNotNull(executeCodeResponse);} } 工厂模式 但是现在问题是我们把new代码沙箱写死了 如果后面项目要改用其他沙箱 可能要改很多地方的代码 我们要使用工厂模式 根据用具传入的字符串参数 生成对应的代码沙箱实现类 package com.dduo.dduoj.judge.codesandbox;import com.dduo.dduoj.judge.codesandbox.impl.ExampleCodeSandbox; import com.dduo.dduoj.judge.codesandbox.impl.RemoteCodeSandbox; import com.dduo.dduoj.judge.codesandbox.impl.ThirdPartyCodeSandbox;//代码沙箱工厂 根据字符串参数 创建指定的代码沙箱示例 public class CodeSandboxFactory {/** 创建代码沙箱示例* param type 沙箱类型* return* */public static CodeSandbox NewInstance(String type) {switch (type) {case example:return new ExampleCodeSandbox();case remote:return new RemoteCodeSandbox();case thirdParty:return new ThirdPartyCodeSandbox();default:return new ExampleCodeSandbox();}} } 如果确定代码沙箱示例不会出现线程安全问题 可复用 那么可以使用单例工厂模式 但是这种方式是不可取的 我们应该把这些东西放到配置里面 配置化 去改配置文件 而不是修改字符串 这就叫参数配置化 开发者只需要去修改配置文件 而不是去看项目代码 就能自定义使用项目的更多功能 先在application.yml里面去设置 再在程序里面去读取 示例 package com.dduo.dduoj.judge.codesandbox;import com.dduo.dduoj.judge.codesandbox.impl.ExampleCodeSandbox; import com.dduo.dduoj.judge.codesandbox.impl.RemoteCodeSandbox; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeRequest; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeResponse;import com.dduo.dduoj.model.enums.QuestionSubmitLanguageEnum; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest;import java.util.Arrays; import java.util.List;SpringBootTest class CodeSandboxTest {Value(${codesandbox.type:example})private String value;Testvoid executeCode() {CodeSandbox codeSandbox CodeSandboxFactory.NewInstance(value);String code int main() { };String language QuestionSubmitLanguageEnum.JAVA.getValue();ListString inputList Arrays.asList(1 2, 3 4);ExecuteCodeRequest executeCodeRequest ExecuteCodeRequest.builder().code(code).language(language).inputList(inputList).build();ExecuteCodeResponse executeCodeResponse codeSandbox.executeCode(executeCodeRequest);Assertions.assertNotNull(executeCodeResponse);} } 我们要增强代码沙箱的能力 在调用代码沙箱前 输出请求参数 在代码沙箱调用后 输出响应结果日志 package com.dduo.dduoj.judge.codesandbox.impl;import com.dduo.dduoj.judge.codesandbox.CodeSandbox; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeRequest; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeResponse; import lombok.extern.slf4j.Slf4j;//示例代码沙箱 (仅供测试 跑通业务流程) Slf4j public class ExampleCodeSandbox implements CodeSandbox {Overridepublic ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {log.info(请求信息executeCodeRequest.toString());System.out.println(示例代码沙箱);return null;} } 思考 我们每一个代码沙箱类都写一个 log.info ? 难道每次调用代码沙箱前后都要执行log ? 我们使用代理模式 提供一个Proxy 来增强代码沙箱的能力 静态代理模式 中介 调用者调用代理类 代理类去调用代码沙箱 代理类还可以做一些额外的功能 不仅不用改变原本的代码沙箱实现类 而且对调用者来说 基本也没有改变 也不需要在每一个调用代码沙箱的地方去统计代码 package com.dduo.dduoj.judge.codesandbox;import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeRequest; import com.dduo.dduoj.judge.codesandbox.model.ExecuteCodeResponse; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j;Slf4j AllArgsConstructor public class CodeSandboxProxy implements CodeSandbox{private CodeSandbox codeSandbox;Overridepublic ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {log.info(代码沙箱的请求信息executeCodeRequest.toString());ExecuteCodeResponse executeCodeResponse codeSandbox.executeCode(executeCodeRequest);log.info(代码沙箱的响应信息executeCodeResponse.toString());return executeCodeResponse;} }接下来我们就可以去修改调用方式 Test void executeCodeByProxy() {CodeSandbox codeSandbox CodeSandboxFactory.NewInstance(value);codeSandbox new CodeSandboxProxy(codeSandbox);String code int main() { };String language QuestionSubmitLanguageEnum.JAVA.getValue();ListString inputList Arrays.asList(1 2, 3 4);ExecuteCodeRequest executeCodeRequest ExecuteCodeRequest.builder().code(code).language(language).inputList(inputList).build();ExecuteCodeResponse executeCodeResponse codeSandbox.executeCode(executeCodeRequest);Assertions.assertNotNull(executeCodeResponse); }