导员:你这么牛,那你来讲讲你项目的核心流程-判题模块吧

耗时一个月开发的OJ在线判题系统,文末有项目地址,目前还在更新代码~
今天我们来开发OJ系统后端核心流程之一的判题模块

文章目录

  • 判题机模块与代码沙箱的关系
  • 代码沙箱架构开发
  • 判题服务开发
    • 判题服务业务流程
    • 判断逻辑
    • 策略模式优化
  • 小知识-Lombox Builder 注解
  • 小知识-Mybatis-plus updateById方法
  • 项目地址

判题机模块与代码沙箱的关系

判题模块:调用代码沙箱,把代码和输入交给代码沙箱去执行
代码沙箱:只负责接收代码和输入,返回编译运行的结果,不负责判题(可以作为独立的项目/服务,提供给其他的需要执行代码的项目去使用)
这两个模块完全解耦:在这里插入图片描述

注意:每次代码沙箱要接受和输出一组运行用例

这是一种很常见的性能优化方法(批处理)

因为如果是每个用例单独调用一次代码沙箱,会调用多次接口,需要多次网络传输,程序要多次编译、记录程序的执行状态

代码沙箱架构开发

1)定义代码沙箱的接口,提高通用性

public interface CodeSandbox {/*** 执行代码* @param excodeCodeRequest* @return*/ExecutecodeResponse executeCode(ExecutecodeCodeRequest excodeCodeRequest);
}

之后我们的项目代码只调用接口,不调用具体的实现类,这样在你使用其他的代码沙箱实现类时,就不用去修改名称了,便于扩展

代码沙箱的求接口中,timeLimit可加可不加,可自行扩展,即时中断程序

扩展思路:增加一个查看代码沙箱状态的接口
2)定义多种不同的代码沙箱实现
示例代码沙箱:仅为了跑通业务流程
远程代码沙箱:实际调用接口的沙箱
第三方代码沙箱:调用网上现成的代码沙箱:https://github.com/criyle/go-judge
3)编写单元测试:验证单个代码沙箱的执行

    @Testvoid executeCode(){CodeSandbox codesandbox = new ExampleCodeSandbox();String code = "int main(){}";String language = QuestionSubmitLanguageEnum.JAVA.getValue();List<String> inputList = Arrays.asList("1 2","3 4");ExecutecodeCodeRequest executecodeCodeRequest = ExecutecodeCodeRequest.builder().code(code).language(language).inputList(inputList).build();ExecutecodeResponse executecodeResponse = codesandbox.executeCode(executecodeCodeRequest);Assertions.assertNotNull(executecodeResponse);}

但现在的问题是,我们把new某个沙箱的代码写死了,如果后面项目要改用其他沙箱,可能要改很多地方的代码。

4)使用工厂模式,根据用户传入的字符串参数(沙箱类别),来生成对应的代码沙箱实现类,此处使用静态工厂模式,实现比较简单,符合我们的需求。

/*** 代码沙箱创建工厂:根据指定的字符串参数,创建指定的代码沙箱实例*/
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 "Third":return new ThirdPartyCodeSandbox();default:return new ExampleCodeSandbox();}}}

测试类可改成下面

    @Testvoid executeCode(){String type = "remote";CodeSandbox codesandbox = CodeSandboxFactory.newInstance(type);String code = "int main(){}";String language = QuestionSubmitLanguageEnum.JAVA.getValue();List<String> inputList = Arrays.asList("1 2","3 4");ExecutecodeCodeRequest executecodeCodeRequest = ExecutecodeCodeRequest.builder().code(code).language(language).inputList(inputList).build();ExecutecodeResponse executecodeResponse = codesandbox.executeCode(executecodeCodeRequest);Assertions.assertNotNull(executecodeResponse);}

5)参数配置化,把项目中的一些可以交给用户去自定义的选项或字符串,写到配置文件中,这样开发者只需要改配置文件,而不需要去看你的项目代码,就能够自定义使用你项目的更多功能

application.yml配置文件中指定变量:

# 代码沙箱配置
codesandbox:type: example

在Spring的Bean中通过@Value 注解读取 :

@Value("${codesandbox.type:example}")
private String type;

6)代理模式优化
比如:我们需要在调用沙箱代码前,输出请求参数日志,在调用沙箱代码后,输出响应结果日志,便于管理员去分析
难道每个代码沙箱类都写一遍log.info?难道每次调用代码沙箱前后都执行log?
使用代理模式,提供一个Proxy,来增强代码沙箱的能力(代理模式的作用就是增强能力)
原本:需要用户自己去调用多次
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用代理后:不仅不用改变原本的代码沙箱实现类,而且对调用者来说,调用方式几乎没有改变,也不需要再每个调用沙箱的地方去写统计代码

在这里插入图片描述

代理模式的实现原理:
1、实现被代理的接口
2、通过构造函数接受一个被代理的接口实现类
3、通过被代理的接口实现类,在调用前后增加对应的操作
CodeSandboxProxy 示例代码:

@Slf4j
public class CodeSandboxProxy implements CodeSandbox {private final CodeSandbox codeSandbox;public CodeSandboxProxy(CodeSandbox codeSandbox) {this.codeSandbox = codeSandbox;}@Overridepublic ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {log.info("代码沙箱请求信息:" + executeCodeRequest.toString());ExecuteCodeResponse executeCodeResponse = codeSandbox.executeCode(executeCodeRequest);log.info("代码沙箱响应信息:" + executeCodeResponse.toString());return executeCodeResponse;}
}

使用方式:

CodeSandbox codeSandbox = CodeSandboxFactory.newInstance(type);
codeSandbox = new CodeSandboxProxy(codeSandbox);

7)实现示例的代码沙箱

/*** 示例代码沙箱(仅为了跑通业务流程)*/
@Slf4j
public class ExampleCodeSandbox implements CodeSandbox {@Overridepublic ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {List<String> inputList = executeCodeRequest.getInputList();ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();executeCodeResponse.setOutputList(inputList);executeCodeResponse.setMessage("测试执行成功");executeCodeResponse.setStatus(QuestionSubmitStatusEnum.SUCCEED.getValue());JudgeInfo judgeInfo = new JudgeInfo();judgeInfo.setMessage(JudgeInfoMessageEnum.ACCEPTED.getText());judgeInfo.setMemory(100L);judgeInfo.setTime();executeCodeResponse.setJudgeInfo(judgeInfo);return executeCodeResponse;}
}

判题服务开发

定义单独的judgeService 类,而不是把所有判题相关的代码写到questionSubmitService 里,有利于后续的模块抽离,微服务改造

判题服务业务流程

1)传入题目的提交id,获取到对应的题目,提交信息(包含代码,编程语言等)
2)如果题目提交状态不为等待中,就不用重复执行了,只执行等待中的题目
3)更改题目提交状态为“判题中”,防止重复执行,也能让用户即时看到状态
4)调用沙箱,获取到执行结果
5)根据沙箱的执行结果,设置题目的判题状态和信息

判断逻辑

1、先判断沙箱执行的结果输出数量是否和预期输出数量相等
2、依次判断每一项输出和预期输出结果是否相等
3、判题题目的限制是否符合要求
4、可能还有其他的异常情况

坐标:yoj-backend\src\main\java\com\yupi\yoj\judge\JudgeServiceImpl.java

@Service
public class JudgeServiceImpl implements JudgeService {@Value("${codeSandbox.type:example}")private String type;@Resourceprivate QuestionSubmitService questionSubmitService;@Resourceprivate QuestionService questionService;@Overridepublic QuestionSubmitVO doJudge(long questionSubmitId) {
//        1)传入题目的提交id,获取到对应的题目,提交信息(包含代码,编程语言等)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,"题目不存在");}
//        2)如果题目提交状态不为等待中,就不用重复执行了,只执行等待中的题目Integer status = questionSubmit.getStatus();if(!Objects.equals(status, QuestionSubmitStatusEnum.WAITING.getValue())){throw new BusinessException(ErrorCode.OPERATION_ERROR,"题目正在判題中");}
//        3)更改题目提交状态为“判题中”,防止重复执行,也能让用户即时看到状态QuestionSubmit questionSubmitUpdate = new QuestionSubmit();questionSubmitUpdate.setId(questionSubmit.getId());questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.RUNNING.getValue());boolean save = questionSubmitService.updateById(questionSubmitUpdate);if(!save){throw new BusinessException(ErrorCode.SYSTEM_ERROR,"题目状态更新失败");}
//        4)调用沙箱,获取到执行结果CodeSandbox codesandbox = CodeSandboxFactory.newInstance(type);codesandbox = new CodeSandboxProxy(codesandbox);String code = questionSubmit.getCode();String language = questionSubmit.getLanguage();//输入用例转列表String judgeCaseStr = question.getJudgeCase();List<JudgeCase> judgeCaseList = JSONUtil.toList(judgeCaseStr, JudgeCase.class);//把判题用例中的输入用例过滤出来,喂给需要的inputList,得到了输入列表List<String> inputList = judgeCaseList.stream().map(JudgeCase::getInput).collect(Collectors.toList());ExecutecodeCodeRequest executecodeCodeRequest = ExecutecodeCodeRequest.builder().code(code).language(language).inputList(inputList).build();
//        5)根据沙箱的执行结果,设置题目的判题状态和信息
//        1、先判断沙箱执行的结果输出数量是否和预期输出数量相等
//        2、依次判断每一项输出和预期输出结果是否相等
//        3、判题题目的限制是否符合要求
//        4、可能还有其他的异常情况ExecutecodeResponse executecodeResponse = codesandbox.executeCode(executecodeCodeRequest);List<String> outputList = executecodeResponse.getOutputList();JudgeInfoMessageEnum judgeInfoMessageEnum = JudgeInfoMessageEnum.WAITING;if(inputList.size() != outputList.size()){judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;return null;}for(int i = 0; i < outputList.size();i ++){if(!Objects.equals(outputList.get(i), inputList.get(i))){judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;return null;}}//判断题目限制是否符合要求JudgeInfo judgeInfo = executecodeResponse.getJudgeInfo();Long time = judgeInfo.getTime();Long memory = judgeInfo.getMemory();String judgeConfigStr = question.getJudgeConfig();JudgeConfig judgeConfig = JSONUtil.toBean(judgeConfigStr, JudgeConfig.class);Long needtimeLimit = judgeConfig.getTimeLimit();Long needmemoryLimit = judgeConfig.getMemoryLimit();if(time > needtimeLimit){judgeInfoMessageEnum = JudgeInfoMessageEnum.TIME_LIMIT_EXCEEDED;return null;}if(memory > needmemoryLimit){judgeInfoMessageEnum = JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED;return null;}return null;}
}

策略模式优化

我们的判题策略可能会有很多种,比如:我们的代码沙箱本身执行程序需要消耗时间,这个时间可能不同的编程语言是不同的,比如沙箱执行java要额外话10s

我们可以采用策略模式,针对不同的情况,定义独立的策略,便于修改策略和维护。而不是把所有的判题逻辑,if …else…代码全部混在一起写

实现步骤
1)定义判题策略接口,让代码更加通用化

public interface JudgeStrategy {/*** 执行判题* @param judgeContext* @return*/JudgeInfo doJudge(JudgeContext judgeContext);
}

2)定义判题上下文对象,用于定义在策略中传递的参数(可以理解为一种DTO)

@Data
public class JudgeContext {private JudgeInfo judgeInfo;private List<String> inputList;private List<String> outputList;private List<JudgeCase> judgeCaseList;private Question question;private QuestionSubmit questionSubmit;}

3)实现默认判题策略,先把judgeService中的代码搬运过来

public class DefaultJudgeStrategy implements JudgeStrategy {@Overridepublic JudgeInfo doJudge(JudgeContext judgeContext) {//        1、先判断沙箱执行的结果输出数量是否和预期输出数量相等
//        2、依次判断每一项输出和预期输出结果是否相等
//        3、判题题目的限制是否符合要求
//        4、可能还有其他的异常情况JudgeInfo judgeInfo = judgeContext.getJudgeInfo();Long time = judgeInfo.getTime();Long memory = judgeInfo.getMemory();List<String> inputList = judgeContext.getInputList();List<String> outputList = judgeContext.getOutputList();List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();Question question = judgeContext.getQuestion();QuestionSubmit questionSubmit = judgeContext.getQuestionSubmit();JudgeInfoMessageEnum judgeInfoMessageEnum = JudgeInfoMessageEnum.ACCEPTED;JudgeInfo judgeInfoResponse = new JudgeInfo();judgeInfoResponse.setTime(time);judgeInfoResponse.setMemory(memory);if(inputList.size() != outputList.size()){judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}for(int i = 0; i < outputList.size();i ++){if(!Objects.equals(outputList.get(i), inputList.get(i))){judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}}//判断题目限制是否符合要求String judgeConfigStr = question.getJudgeConfig();JudgeConfig judgeConfig = JSONUtil.toBean(judgeConfigStr, JudgeConfig.class);Long needtimeLimit = judgeConfig.getTimeLimit();Long needmemoryLimit = judgeConfig.getMemoryLimit();if(time > needtimeLimit){judgeInfoMessageEnum = JudgeInfoMessageEnum.TIME_LIMIT_EXCEEDED;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}if(memory > needmemoryLimit){judgeInfoMessageEnum = JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}
}

此时的yoj-backend\src\main\java\com\yupi\yoj\judge\JudgeServiceImpl.java修改的部分

//        5)根据沙箱的执行结果,设置题目的判题状态和信息ExecutecodeResponse executecodeResponse = codesandbox.executeCode(executecodeCodeRequest);List<String> outputList = executecodeResponse.getOutputList();JudgeStrategy judgeStrategy = new DefaultJudgeStrategy();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 = judgeStrategy.doJudge(judgeContext);//6)修改数据库中的判题结果questionSubmitUpdate = new QuestionSubmit();questionSubmitUpdate.setId(questionSubmit.getId());questionSubmitUpdate.setJudgeInfo(JSONUtil.toJsonStr(judgeInfo));questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.SUCCEED.getValue());save = questionSubmitService.updateById(questionSubmitUpdate);if(!save){throw new BusinessException(ErrorCode.SYSTEM_ERROR,"题目状态更新错误");}QuestionSubmit questionSubmitResult = questionSubmitService.getById(questionId);return questionSubmitResult;

4)再新增一种判题策略,通过if…else…的方式选择哪种策略

坐标:yoj-backend\src\main\java\com\yupi\yoj\judge\strategy\JavaLanguageJudgeStrategy.java

public class JavaLanguageJudgeStrategy implements JudgeStrategy {@Overridepublic JudgeInfo doJudge(JudgeContext judgeContext) {//        1、先判断沙箱执行的结果输出数量是否和预期输出数量相等
//        2、依次判断每一项输出和预期输出结果是否相等
//        3、判题题目的限制是否符合要求
//        4、可能还有其他的异常情况JudgeInfo judgeInfo = judgeContext.getJudgeInfo();Long time = judgeInfo.getTime();Long memory = judgeInfo.getMemory();List<String> inputList = judgeContext.getInputList();List<String> outputList = judgeContext.getOutputList();List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();Question question = judgeContext.getQuestion();QuestionSubmit questionSubmit = judgeContext.getQuestionSubmit();JudgeInfoMessageEnum judgeInfoMessageEnum = JudgeInfoMessageEnum.ACCEPTED;JudgeInfo judgeInfoResponse = new JudgeInfo();judgeInfoResponse.setTime(time);judgeInfoResponse.setMemory(memory);if(inputList.size() != outputList.size()){judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}for(int i = 0; i < outputList.size();i ++){if(!Objects.equals(outputList.get(i), inputList.get(i))){judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}}//判断题目限制是否符合要求String judgeConfigStr = question.getJudgeConfig();JudgeConfig judgeConfig = JSONUtil.toBean(judgeConfigStr, JudgeConfig.class);Long needtimeLimit = judgeConfig.getTimeLimit();Long needmemoryLimit = judgeConfig.getMemoryLimit();//假设JAVA程序本身需要额外执行10slong JAVA_TIME_COST = 1000L;if(time - JAVA_TIME_COST> needtimeLimit){judgeInfoMessageEnum = JudgeInfoMessageEnum.TIME_LIMIT_EXCEEDED;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}if(memory - JAVA_TIME_COST > needmemoryLimit){judgeInfoMessageEnum = JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED;judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());return judgeInfoResponse;}
}
JudgeStrategy judgeStrategy = new DefaultJudgeStrategy();
if (language.equals("java")) {judgeStrategy = new JavaLanguageJudgeStrategy();
}
JudgeInfo judgeInfo = judgeStrategy.doJudge(judgeContext);

但是,如果选择某种判题策略过程比较复杂,如果都写在调用判题服务的代码中,代码会越来越复杂,会有大量的if…else…,所以建议单独编写一个判断策略的类

5)定义JudgeManager,目的是尽量简化对判题功能的调用,让调用方写最少的代码,调用最简单。对于判题策略的选取,也是在JudgeManager里处理的
坐标:com.yupi.yoj.judge.JudgeManager

/*** 判题管理(简化调用)*/
@Service
public class JudgeManager {/*** 执行判题** @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);}}

6)在JudgeServiceImpl中,将judgeStrategy.doJudege() 改为 judgeManager.doJudge()

7)坐标:com.yupi.yoj.service.impl.QuestionSubmitServiceImpl
在题目提交实现类中,在返回结果前,执行判题服务

小知识-Lombox Builder 注解

以前我们是使用new 对象后,再逐行执行set方法的方式来给对象进行赋值的。
还有另外一种可能更方便的方式builder。
1)实体类加上@Builder等注解

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ExecuteCodeRequest {private List<String> inputList;private String code;private String language;
}

2)可以使用链式的方式更方便地给对象赋值

ExecuteCodeRequest executeCodeRequest = ExecuteCodeRequest.builder().code(code).language(language).inputList(inputList).build();

小知识-Mybatis-plus updateById方法

根据id进行更新,但是参数却是为实体类,根据传入参数的类的id进行更新,不会全部更新,只会更新设置了值的属性

项目地址

(求求大佬们赏个star~)

前端:https://github.com/IMZHEYA/yoj-frontend
后端:https://github.com/IMZHEYA/yoj-backend
代码沙箱:https://github.com/IMZHEYA/yoj-code-sandbox

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/374463.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新品牌快速成长指南:揭秘品牌成功的黄金法则

打造一个新品牌是一个系统性工程&#xff0c;不是一两句话就能说清楚的。 作为一个13年的营销人&#xff0c;今天试图给大家以最简练和通俗的文字&#xff0c;详细讲讲打造一个全新的品牌都需要做些啥&#xff1f;码字不易&#xff0c;请多给点支持哦。 一、市场调研与定位&a…

Elasticsearch 开放推理 API 增加了对 Amazon Bedrock 的支持

作者&#xff1a;来自 Elastic Mark Hoy, Hemant Malik Elasticsearch 开放推理 API 增加了对托管在 Amazon Bedrock 上的模型生成嵌入的支持。 Elasticsearch 开放 infereence API 使开发人员能够创建推理端点并使用来自领先提供商的机器学习模型。从今天开始&#xff0c;托管…

超简单的通配证书签发工具,免费,无需安装任何插件到本地

常见的acme.sh 或者 lego等工具需要配置&#xff0c;安装不灵活&#xff0c;续签需要配置计划任务&#xff0c;签发单域名证书或者通配证书需要不同的指令和配置&#xff0c;繁琐&#xff0c;如果自己程序想要对接签发证书的api有的不支持&#xff0c;有的用起来繁琐。 最近发…

确保智慧校园安全,充分利用操作日志功能

智慧校园基础平台系统的操作日志功能是确保整个平台运行透明、安全及可追溯的核心组件。它自动且详尽地记录下系统内的每一次关键操作细节&#xff0c;涵盖操作的具体时间、执行操作的用户账号、涉及的数据对象&#xff08;例如学生信息更新、课程调度变动等&#xff09;、操作…

华为HCIP Datacom H12-821 卷34

1.单选题 防火墙默认已经创建了一些安全区域,以下哪一个安全区域不是防火墙上默认存在的? A、Trust B、DMZ C、Internet D、Local 正确答案&#xff1a; C 解析&#xff1a; 防火墙默认情况下为我们提供了三个安全区域&#xff0c;分别是 Trust、DMZ和Untrust 2.判断题 …

(图文详解)小程序AppID申请以及在Hbuilderx中运行

今天小编给大家带来了如何去申请APPID&#xff0c;如果你是小程序的开发者&#xff0c;就必须要这个id。 申请步骤 到小程序注册页面&#xff0c;注册一个小程序账号 微信公众平台 填完信息后提交注册 会在邮箱收到 链接激活账号 确认。邮箱打开链接后&#xff0c;会输入实…

设备管理中的数据结构

一、有哪些数据结构属于设备管理数据结构 1. 设备控制表&#xff08;DCT&#xff09; “Device Control Table”的首字母缩写 2. 控制器控制表&#xff08;COCT&#xff09; “Controller Of Control Table”的首字母缩写。 3. 通道控制表&#xff08;CHCT&#xff09; “…

guided-diffusion 相比于improved-diffusion的sample增加的cond_fn()

目录 1、cond_fn()函数代码2、softmax与log_softmax函数 1、cond_fn()函数代码 def cond_fn(x, t, yNone):assert y is not Nonewith th.enable_grad():x_in x.detach().requires_grad_(True)logits classifier(x_in, t)log_probs F.log_softmax(logits, dim-1)selected l…

Transformer特辑

https://github.com/LongxingTan/Machine-learning-interview 模型结构 基本单元&#xff1a;token_embedding positional encoding, encoder, token_embedding positional encoding, decoderencoder: (self-attention, skip-connect, ln), (ffn, skip-connect, ln)decoder:…

顶顶通呼叫中心中间件实现随时启动和停止质检(mod_cti基于FreeSWITCH)

文章目录 前言联系我们拨号方案启动停止ASR执行FreeSWITCH 命令接口启动ASR接口停止ASR接口 通知配置cti.json配置质检结果写入数据库 前言 顶顶通呼叫中心中间件的实时质检功能是由两个模块组成&#xff1a;mod_asr 和 mod_qc。 mod_asr&#xff1a;负责调用ASR将用户们在通…

二、Qemu+Vscode调试内核

编译内核、busybox、配置Qemu参考&#xff1a;Qemu调试内核 一、修改启动脚本 1、修改Qemu启动脚本 #! /bin/shqemu-system-aarch64 \-machine virt,virtualizationtrue,gic-version3 \-nographic \-m size1024M \-cpu cortex-a72 \-smp 2 \-kernel Image \-drive formatraw…

写作遇到AI痕迹困扰?这里有降低AI痕迹的实用技巧

请问有没有什么免费的论文降重网站&#xff1f; 副本 一句“知网是什么”&#xff0c;我查重查了千百遍。天临六年五月&#xff0c;大家的论文差不多都到了查重的阶段。好不容易论文写&#xff08;shui&#xff09;完了&#xff0c;一看查重报告&#xff0c;满屏的红字让人心心…

Linux--线程ID封装管理原生线程

目录 1.线程的tid&#xff08;本质是线程属性集合的起始虚拟地址&#xff09; 1.1pthread库中线程的tid是什么&#xff1f; 1.2理解库 1.3phtread库中做了什么&#xff1f; 1.4线程的tid&#xff0c;和内核中的lwp 1.5线程的局部存储 2.封装管理原生线程库 1.线程的tid…

java设计模式(十五)命令模式(Command Pattern)

1、模式介绍&#xff1a; 命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c;其主要目的是将请求封装成一个对象&#xff0c;从而允许使用不同的请求、队列或者日志来参数化其他对象。这种模式使得命令的请求者和实现者解耦。 2、应用场景&…

服务启动何时触发 Nacos 的注册流程?

前言&#xff1a; 前面的系列文章让我们对 Nacos 有了一个基本了解&#xff0c;并知道了如何去试用 Nacos 作为注册中心和配置中心&#xff0c;本篇我们将从源码层面去分析 Nacos 的服务注册流程。 Nacos 系列文章传送门&#xff1a; Nacos 初步认识和 Nacos 部署细节 Naco…

C++基础学习笔记

1.命名空间(namespace) 1.什么是命名空间&命名空间的作用 1.在C/C中&#xff0c;变量、函数、类都是大量存在的&#xff0c;这些变量等的名称将都存在于全局作用域中&#xff0c;就会导致很多的命名冲突等。使用命名空间的目的就是对标识符的名称进行本地化&#xff0c;以…

短视频矩阵系统全解析:让获客变得更简单

随着数字媒体的迅猛发展&#xff0c;短视频已成为人们生活中不可或缺的一部分。对于企业而言&#xff0c;如何有效利用短视频平台吸引目标用户&#xff0c;实现高效获客&#xff0c;成为了一个亟待解决的问题。本文将全面解析短视频矩阵系统&#xff0c;带您领略其独特魅力&…

广度优先(BFS)

先看一道简单的题&#xff0c;迷宫问题&#xff1a; 洛谷P1746 离开中山路&#xff1a;P1746 离开中山路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<iostream> #include<cstring> #include<queue> #include <utility> #define N 1002 …

深度学习的数学PDF

链接: https://pan.baidu.com/s/1_jScZ7dcyAWGqbrad6bbCQ?pwd9gj9 提取码: 9gj9 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦

最简单的vue3组件之间传值

localStorage 是 HTML5 引入的一个 Web Storage API 的一部分&#xff0c;它允许网页在用户的浏览器上存储数据。localStorage 提供了一种持久化的本地存储方案&#xff0c;数据不会因为浏览器关闭而丢失&#xff0c;除非用户或脚本显式地删除它们。 localStorage 是一种非常实…