OJ在线评测系统 代码沙箱优化模版方法模式 使用与有规范的流程 并且执行流程可以复用

代码沙箱优化模版方法模式

上次我们代码沙箱的docker实现和原生实现

我们可以使用模版方法设计模式去优化我们的代码

我们原生的java实现代码沙箱和docker实现代码沙箱是有更多重复点的

比如说把文件 收集文件 进行校验

我们要用模版方法设计模式

定义一套通用的执行流程 让子类去负责每个具体步骤的执行流程

模版方法的应用场景 使用与有规范的流程 并且执行流程可以复用

作用是 答复节约重复代码量 便于项目扩展 更好的去维护

抽象出具体的流程

先复制具体的实现类

再把代码从完整的方法抽离成一个一个的子写法

想把代码保存为文件

/*** 1. 把用户的代码保存为文件* @param code 用户代码* @return*/public File saveCodeToFile(String code) {String userDir = System.getProperty("user.dir");String globalCodePathName = userDir + File.separator + GLOBAL_CODE_DIR_NAME;// 判断全局代码目录是否存在,没有则新建if (!FileUtil.exist(globalCodePathName)) {FileUtil.mkdir(globalCodePathName);}// 把用户的代码隔离存放String userCodeParentPath = globalCodePathName + File.separator + UUID.randomUUID();String userCodePath = userCodeParentPath + File.separator + GLOBAL_JAVA_CLASS_NAME;File userCodeFile = FileUtil.writeString(code, userCodePath, StandardCharsets.UTF_8);return userCodeFile;}

想编译代码 获得class文件

   /*** 2、编译代码* @param userCodeFile* @return*/public ExecuteMessage compileFile(File userCodeFile) {String compileCmd = String.format("javac -encoding utf-8 %s", userCodeFile.getAbsolutePath());try {Process compileProcess = Runtime.getRuntime().exec(compileCmd);ExecuteMessage executeMessage = ProcessUtils.runProcessAndGetMessage(compileProcess, "编译");if (executeMessage.getExitValue() != 0) {throw new RuntimeException("编译错误");}return executeMessage;} catch (Exception e) {
//            return getErrorResponse(e);throw new RuntimeException(e);}}

执行文件,获得执行结果列表

    /*** 3、执行文件,获得执行结果列表* @param userCodeFile* @param inputList* @return*/public List<ExecuteMessage> runFile(File userCodeFile, List<String> inputList) {String userCodeParentPath = userCodeFile.getParentFile().getAbsolutePath();List<ExecuteMessage> executeMessageList = new ArrayList<>();for (String inputArgs : inputList) {
//            String runCmd = String.format("java -Xmx256m -Dfile.encoding=UTF-8 -cp %s Main %s", userCodeParentPath, inputArgs);String runCmd = String.format("java -Xmx256m -Dfile.encoding=UTF-8 -cp %s Main %s", userCodeParentPath, inputArgs);try {Process runProcess = Runtime.getRuntime().exec(runCmd);// 超时控制new Thread(() -> {try {Thread.sleep(TIME_OUT);System.out.println("超时了,中断");runProcess.destroy();} catch (InterruptedException e) {throw new RuntimeException(e);}}).start();ExecuteMessage executeMessage = ProcessUtils.runProcessAndGetMessage(runProcess, "运行");System.out.println(executeMessage);executeMessageList.add(executeMessage);} catch (Exception e) {throw new RuntimeException("执行错误", e);}}return executeMessageList;}

获取输出结果

   /*** 4、获取输出结果* @param executeMessageList* @return*/public ExecuteCodeResponse getOutputResponse(List<ExecuteMessage> executeMessageList) {ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();List<String> outputList = new ArrayList<>();// 取用时最大值,便于判断是否超时long maxTime = 0;for (ExecuteMessage executeMessage : executeMessageList) {String errorMessage = executeMessage.getErrorMessage();if (StrUtil.isNotBlank(errorMessage)) {executeCodeResponse.setMessage(errorMessage);// 用户提交的代码执行中存在错误executeCodeResponse.setStatus(3);break;}outputList.add(executeMessage.getMessage());Long time = executeMessage.getTime();if (time != null) {maxTime = Math.max(maxTime, time);}}// 正常运行完成if (outputList.size() == executeMessageList.size()) {executeCodeResponse.setStatus(1);}executeCodeResponse.setOutputList(outputList);JudgeInfo judgeInfo = new JudgeInfo();judgeInfo.setTime(maxTime);// 要借助第三方库来获取内存占用,非常麻烦,此处不做实现
//        judgeInfo.setMemory();executeCodeResponse.setJudgeInfo(judgeInfo);return executeCodeResponse;}

删除文件

 /*** 5、删除文件* @param userCodeFile* @return*/public boolean deleteFile(File userCodeFile) {if (userCodeFile.getParentFile() != null) {String userCodeParentPath = userCodeFile.getParentFile().getAbsolutePath();boolean del = FileUtil.del(userCodeParentPath);System.out.println("删除" + (del ? "成功" : "失败"));return del;}return true;}

获取错误响应

    /*** 6、获取错误响应** @param e* @return*/private ExecuteCodeResponse getErrorResponse(Throwable e) {ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();executeCodeResponse.setOutputList(new ArrayList<>());executeCodeResponse.setMessage(e.getMessage());// 表示代码沙箱错误executeCodeResponse.setStatus(2);executeCodeResponse.setJudgeInfo(new JudgeInfo());return executeCodeResponse;}

我们之前流程化程序

这样提成一一个方法就会很简单

自上而下一层一层去抽取

我们此时重写父类中的方法

  @Overridepublic ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {List<String> inputList = executeCodeRequest.getInputList();String code = executeCodeRequest.getCode();String language = executeCodeRequest.getLanguage();//        1. 把用户的代码保存为文件File userCodeFile = saveCodeToFile(code);//        2. 编译代码,得到 class 文件ExecuteMessage compileFileExecuteMessage = compileFile(userCodeFile);System.out.println(compileFileExecuteMessage);// 3. 执行代码,得到输出结果List<ExecuteMessage> executeMessageList = runFile(userCodeFile, inputList);//        4. 收集整理输出结果ExecuteCodeResponse outputResponse = getOutputResponse(executeMessageList);//        5. 文件清理boolean b = deleteFile(userCodeFile);if (!b) {log.error("deleteFile error, userCodeFilePath = {}", userCodeFile.getAbsolutePath());}return outputResponse;}

现在我们就能定义子类

直接复用父类的模版方法就行

这就是模版方法设计模式 Template

package com.yupi.yuojcodesandbox;import com.yupi.yuojcodesandbox.model.ExecuteCodeRequest;
import com.yupi.yuojcodesandbox.model.ExecuteCodeResponse;
import org.springframework.stereotype.Component;/*** Java 原生代码沙箱实现(直接复用模板方法)*/
@Component
public class JavaNativeCodeSandbox extends JavaCodeSandboxTemplate {@Overridepublic ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {return super.executeCode(executeCodeRequest);}
}

我们这边如果在子类里面重写了父类的某个方法

那么子类执行的时候

优先的是去执行子类里面重写方法 就是已经覆盖过的实现

如果没有重写 是去执行模版中的默认实现

接下来我们要去改造一下docker代码沙箱的实现

继承我们的模版方法

自定义某些方法的实现

我们发现我们写JavaDockerCodeSandbox类就是重写了创建容器类

package com.yupi.yuojcodesandbox;import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.yupi.yuojcodesandbox.model.ExecuteCodeRequest;
import com.yupi.yuojcodesandbox.model.ExecuteCodeResponse;
import com.yupi.yuojcodesandbox.model.ExecuteMessage;
import com.yupi.yuojcodesandbox.model.JudgeInfo;
import com.yupi.yuojcodesandbox.utils.ProcessUtils;
import lombok.extern.slf4j.Slf4j;import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;/*** Java 代码沙箱模板方法的实现*/
@Slf4j
public abstract class JavaCodeSandboxTemplate implements CodeSandbox {private static final String GLOBAL_CODE_DIR_NAME = "tmpCode";private static final String GLOBAL_JAVA_CLASS_NAME = "Main.java";private static final long TIME_OUT = 5000L;/**** @param executeCodeRequest 代码请求* @return*/@Overridepublic ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {List<String> inputList = executeCodeRequest.getInputList();String code = executeCodeRequest.getCode();String language = executeCodeRequest.getLanguage();//        1. 把用户的代码保存为文件File userCodeFile = saveCodeToFile(code);//        2. 编译代码,得到 class 文件ExecuteMessage compileFileExecuteMessage = compileFile(userCodeFile);System.out.println(compileFileExecuteMessage);// 3. 执行代码,得到输出结果List<ExecuteMessage> executeMessageList = runFile(userCodeFile, inputList);//        4. 收集整理输出结果ExecuteCodeResponse outputResponse = getOutputResponse(executeMessageList);//        5. 文件清理boolean b = deleteFile(userCodeFile);if (!b) {log.error("deleteFile error, userCodeFilePath = {}", userCodeFile.getAbsolutePath());}return outputResponse;}/*** 1. 把用户的代码保存为文件* @param code 用户代码* @return*/public File saveCodeToFile(String code) {String userDir = System.getProperty("user.dir");String globalCodePathName = userDir + File.separator + GLOBAL_CODE_DIR_NAME;// 判断全局代码目录是否存在,没有则新建if (!FileUtil.exist(globalCodePathName)) {FileUtil.mkdir(globalCodePathName);}// 把用户的代码隔离存放String userCodeParentPath = globalCodePathName + File.separator + UUID.randomUUID();String userCodePath = userCodeParentPath + File.separator + GLOBAL_JAVA_CLASS_NAME;File userCodeFile = FileUtil.writeString(code, userCodePath, StandardCharsets.UTF_8);return userCodeFile;}/*** 2、编译代码* @param userCodeFile 保存的文件* @return*/public ExecuteMessage compileFile(File userCodeFile) {String compileCmd = String.format("javac -encoding utf-8 %s", userCodeFile.getAbsolutePath());try {Process compileProcess = Runtime.getRuntime().exec(compileCmd);ExecuteMessage executeMessage = ProcessUtils.runProcessAndGetMessage(compileProcess, "编译");if (executeMessage.getExitValue() != 0) {throw new RuntimeException("编译错误");}return executeMessage;} catch (Exception e) {
//            return getErrorResponse(e);throw new RuntimeException(e);}}/*** 3、执行文件,获得执行结果列表* @param userCodeFile* @param inputList* @return*/public List<ExecuteMessage> runFile(File userCodeFile, List<String> inputList) {String userCodeParentPath = userCodeFile.getParentFile().getAbsolutePath();List<ExecuteMessage> executeMessageList = new ArrayList<>();for (String inputArgs : inputList) {
//            String runCmd = String.format("java -Xmx256m -Dfile.encoding=UTF-8 -cp %s Main %s", userCodeParentPath, inputArgs);String runCmd = String.format("java -Xmx256m -Dfile.encoding=UTF-8 -cp %s Main %s", userCodeParentPath, inputArgs);try {Process runProcess = Runtime.getRuntime().exec(runCmd);// 超时控制new Thread(() -> {try {Thread.sleep(TIME_OUT);System.out.println("超时了,中断");runProcess.destroy();} catch (InterruptedException e) {throw new RuntimeException(e);}}).start();ExecuteMessage executeMessage = ProcessUtils.runProcessAndGetMessage(runProcess, "运行");System.out.println(executeMessage);executeMessageList.add(executeMessage);} catch (Exception e) {throw new RuntimeException("执行错误", e);}}return executeMessageList;}/*** 4、获取输出结果* @param executeMessageList* @return*/public ExecuteCodeResponse getOutputResponse(List<ExecuteMessage> executeMessageList) {ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();List<String> outputList = new ArrayList<>();// 取用时最大值,便于判断是否超时long maxTime = 0;for (ExecuteMessage executeMessage : executeMessageList) {String errorMessage = executeMessage.getErrorMessage();if (StrUtil.isNotBlank(errorMessage)) {executeCodeResponse.setMessage(errorMessage);// 用户提交的代码执行中存在错误executeCodeResponse.setStatus(3);break;}outputList.add(executeMessage.getMessage());Long time = executeMessage.getTime();if (time != null) {maxTime = Math.max(maxTime, time);}}// 正常运行完成if (outputList.size() == executeMessageList.size()) {executeCodeResponse.setStatus(1);}executeCodeResponse.setOutputList(outputList);JudgeInfo judgeInfo = new JudgeInfo();judgeInfo.setTime(maxTime);// 要借助第三方库来获取内存占用,非常麻烦,此处不做实现
//        judgeInfo.setMemory();executeCodeResponse.setJudgeInfo(judgeInfo);return executeCodeResponse;}/*** 5、删除文件* @param userCodeFile* @return*/public boolean deleteFile(File userCodeFile) {if (userCodeFile.getParentFile() != null) {String userCodeParentPath = userCodeFile.getParentFile().getAbsolutePath();boolean del = FileUtil.del(userCodeParentPath);System.out.println("删除" + (del ? "成功" : "失败"));return del;}return true;}/*** 6、获取错误响应** @param e* @return*/private ExecuteCodeResponse getErrorResponse(Throwable e) {ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();executeCodeResponse.setOutputList(new ArrayList<>());executeCodeResponse.setMessage(e.getMessage());// 表示代码沙箱错误executeCodeResponse.setStatus(2);executeCodeResponse.setJudgeInfo(new JudgeInfo());return executeCodeResponse;}
}

熟悉模版方法模式的人一看就懂这个方法

package com.yupi.yuojcodesandbox;import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.yupi.yuojcodesandbox.model.ExecuteCodeRequest;
import com.yupi.yuojcodesandbox.model.ExecuteCodeResponse;
import com.yupi.yuojcodesandbox.model.ExecuteMessage;
import com.yupi.yuojcodesandbox.model.JudgeInfo;
import com.yupi.yuojcodesandbox.utils.ProcessUtils;
import lombok.extern.slf4j.Slf4j;import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;/*** Java 代码沙箱模板方法的实现*/
@Slf4j
public abstract class JavaCodeSandboxTemplate implements CodeSandbox {private static final String GLOBAL_CODE_DIR_NAME = "tmpCode";private static final String GLOBAL_JAVA_CLASS_NAME = "Main.java";private static final long TIME_OUT = 5000L;/**** @param executeCodeRequest 代码请求* @return*/@Overridepublic ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {List<String> inputList = executeCodeRequest.getInputList();String code = executeCodeRequest.getCode();String language = executeCodeRequest.getLanguage();//        1. 把用户的代码保存为文件File userCodeFile = saveCodeToFile(code);//        2. 编译代码,得到 class 文件ExecuteMessage compileFileExecuteMessage = compileFile(userCodeFile);System.out.println(compileFileExecuteMessage);// 3. 执行代码,得到输出结果List<ExecuteMessage> executeMessageList = runFile(userCodeFile, inputList);//        4. 收集整理输出结果ExecuteCodeResponse outputResponse = getOutputResponse(executeMessageList);//        5. 文件清理boolean b = deleteFile(userCodeFile);if (!b) {log.error("deleteFile error, userCodeFilePath = {}", userCodeFile.getAbsolutePath());}return outputResponse;}/*** 1. 把用户的代码保存为文件* @param code 用户代码* @return*/public File saveCodeToFile(String code) {String userDir = System.getProperty("user.dir");String globalCodePathName = userDir + File.separator + GLOBAL_CODE_DIR_NAME;// 判断全局代码目录是否存在,没有则新建if (!FileUtil.exist(globalCodePathName)) {FileUtil.mkdir(globalCodePathName);}// 把用户的代码隔离存放String userCodeParentPath = globalCodePathName + File.separator + UUID.randomUUID();String userCodePath = userCodeParentPath + File.separator + GLOBAL_JAVA_CLASS_NAME;File userCodeFile = FileUtil.writeString(code, userCodePath, StandardCharsets.UTF_8);return userCodeFile;}/*** 2、编译代码* @param userCodeFile 保存的文件* @return*/public ExecuteMessage compileFile(File userCodeFile) {String compileCmd = String.format("javac -encoding utf-8 %s", userCodeFile.getAbsolutePath());try {Process compileProcess = Runtime.getRuntime().exec(compileCmd);ExecuteMessage executeMessage = ProcessUtils.runProcessAndGetMessage(compileProcess, "编译");if (executeMessage.getExitValue() != 0) {throw new RuntimeException("编译错误");}return executeMessage;} catch (Exception e) {
//            return getErrorResponse(e);throw new RuntimeException(e);}}/*** 3、执行文件,获得执行结果列表* @param userCodeFile* @param inputList* @return*/public List<ExecuteMessage> runFile(File userCodeFile, List<String> inputList) {String userCodeParentPath = userCodeFile.getParentFile().getAbsolutePath();List<ExecuteMessage> executeMessageList = new ArrayList<>();for (String inputArgs : inputList) {
//            String runCmd = String.format("java -Xmx256m -Dfile.encoding=UTF-8 -cp %s Main %s", userCodeParentPath, inputArgs);String runCmd = String.format("java -Xmx256m -Dfile.encoding=UTF-8 -cp %s Main %s", userCodeParentPath, inputArgs);try {Process runProcess = Runtime.getRuntime().exec(runCmd);// 超时控制new Thread(() -> {try {Thread.sleep(TIME_OUT);System.out.println("超时了,中断");runProcess.destroy();} catch (InterruptedException e) {throw new RuntimeException(e);}}).start();ExecuteMessage executeMessage = ProcessUtils.runProcessAndGetMessage(runProcess, "运行");System.out.println(executeMessage);executeMessageList.add(executeMessage);} catch (Exception e) {throw new RuntimeException("执行错误", e);}}return executeMessageList;}/*** 4、获取输出结果* @param executeMessageList* @return*/public ExecuteCodeResponse getOutputResponse(List<ExecuteMessage> executeMessageList) {ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();List<String> outputList = new ArrayList<>();// 取用时最大值,便于判断是否超时long maxTime = 0;for (ExecuteMessage executeMessage : executeMessageList) {String errorMessage = executeMessage.getErrorMessage();if (StrUtil.isNotBlank(errorMessage)) {executeCodeResponse.setMessage(errorMessage);// 用户提交的代码执行中存在错误executeCodeResponse.setStatus(3);break;}outputList.add(executeMessage.getMessage());Long time = executeMessage.getTime();if (time != null) {maxTime = Math.max(maxTime, time);}}// 正常运行完成if (outputList.size() == executeMessageList.size()) {executeCodeResponse.setStatus(1);}executeCodeResponse.setOutputList(outputList);JudgeInfo judgeInfo = new JudgeInfo();judgeInfo.setTime(maxTime);// 要借助第三方库来获取内存占用,非常麻烦,此处不做实现
//        judgeInfo.setMemory();executeCodeResponse.setJudgeInfo(judgeInfo);return executeCodeResponse;}/*** 5、删除文件* @param userCodeFile* @return*/public boolean deleteFile(File userCodeFile) {if (userCodeFile.getParentFile() != null) {String userCodeParentPath = userCodeFile.getParentFile().getAbsolutePath();boolean del = FileUtil.del(userCodeParentPath);System.out.println("删除" + (del ? "成功" : "失败"));return del;}return true;}/*** 6、获取错误响应** @param e* @return*/private ExecuteCodeResponse getErrorResponse(Throwable e) {ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();executeCodeResponse.setOutputList(new ArrayList<>());executeCodeResponse.setMessage(e.getMessage());// 表示代码沙箱错误executeCodeResponse.setStatus(2);executeCodeResponse.setJudgeInfo(new JudgeInfo());return executeCodeResponse;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2024年合肥市职业院校技能大赛(中职组)赛 网络安全理论题

竞赛内容 模块A: 理论技能与职业素养 培训、环境、资料、考证 公众号&#xff1a;Geek极安云科 网络安全群&#xff1a;624032112 网络系统管理群&#xff1a;223627079 网络建设与运维群&#xff1a;870959784 极安云科专注于技能提升&#xff0c;赋能 2024年广东省高校的技…

cubemx配置ADC

参考博客&#xff1a;https://blog.csdn.net/qq_29031103/article/details/119894077 生成代码&#xff1b; 接着编写代码&#xff1a; 1&#xff09;在main函数bsp初始化部分&#xff1b; 添加&#xff1a;HAL_ADCEx_Calibration_Start(&hadc1); 2&#xff09;在…

C++之STL—常用拷贝和替换算法

copy(iterator beg, iterator end, iterator dest); // 按值查找元素&#xff0c;找到返回指定位置迭代器&#xff0c;找不到返回结束迭代器位置 // beg 开始迭代器 // end 结束迭代器 // dest 目标起始迭代器 replace(iterator beg, iterator end, oldvalue, newvalue); …

Techub专访顾荣辉教授:解密CertiK的安全战略路线

当 Web3 安全审计公司还在争抢审计份额时&#xff0c;CertiK 已经开始将目光瞄准即将进军 Web3 的传统商业巨头。CertiK 不仅在传统行业进行白帽行动获得如苹果公司的官方感谢&#xff0c;还是 Web3 行业唯一一家拥有 SOC 2 和 ISO 认证的 Web3 的安全公司。基于此&#xff0c;…

Redis篇(数据类型)

目录 讲解一&#xff1a;简介 讲解二&#xff1a;常用 一、String类型 1. 简介 2. 常见命令 3. Key结构 4. 操作String 5. 实例 二、Hash类型 1. 简介 2. 常见命令 3. 3操作hash 4. 实例 三、List类型 1. 简介 2. 特征 3. 应用场景 4. 常见命令 5. 操作list …

AT89C51 利用SBIT寻址,并且在内存中实现伪动态密码的混淆

前置发现 && 分析 char bdata DB[2]; //char sbit x bdata DB[0]^7; //取内存地址数组[0]地址的的七位 这样我们可以对数组DB中索引0的位置进行修改… 例如,将密码A映射到真实密码C,这样做的好处是你的程序被逆向分析的时候,攻击者无法真正知道密码到底是什么…因为…

程序员必备秘籍:掌握代码规范,让开发效率飞速提升!

在软件开发的世界里&#xff0c;代码规范如同指南针&#xff0c;为开发团队和测试团队指明方向。一个统一的代码规范不仅能够提升代码的可读性和可维护性&#xff0c;还能显著提高开发效率和团队协作能力。 本文将带你深入了解代码规范的重要性&#xff0c;并揭示如何通过它来实…

Angular与Vue的全方位对比分析

一、框架概述 Angular Angular是由Google开发和维护的一款开源JavaScript框架。它采用TypeScript编写&#xff0c;具有一套完整的开发工具和规范。Angular遵循MVC&#xff08;Model - View - Controller&#xff09;或更确切地说是MVVM&#xff08;Model - View - ViewModel&a…

探索私有化聊天软件:即时通讯与音视频技术的结合

在数字化转型的浪潮中&#xff0c;企业对于高效、安全、定制化的通讯解决方案的需求日益迫切。鲸信&#xff0c;作为音视频通信技术的佼佼者&#xff0c;凭借其强大的即时通讯与音视频SDK&#xff08;软件开发工具包&#xff09;结合能力&#xff0c;为企业量身打造了私有化聊天…

原生代理IP是什么?

代理IP的各个类型称呼有很多&#xff0c;且它们在网络使用和隐私保护方面扮演着不同的角色。今天将探讨什么是原生IP以及原生IP和住宅IP之间的区别&#xff0c;帮助大家更好地理解这两者的概念和实际应用&#xff0c;并选择适合自己的IP类型。 一、什么是原生IP&#xff1f; 原…

【Transformers实战篇2】练习之命名实体识别

文章目录 一、命名实体识别简介1.1 数据标注体系1.2 IOB2标注体系1.3 IOBES标注体系 二、代码实战2.1 导入相关包2.2 加载数据集2.3 数据集预处理2.3.1 借助word_idx实现标签映射 2.4 创建模型2.5 创建评估函数2.6 配置训练参数2.7 创建训练器2.8 模型训练2.9 模型预测 本文为 …

基于SSM的图书管理管理系统的设计与实现 (含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的图书管理管理系统4拥有两种角色&#xff0c;用户可以浏览评论图书、登录注册&#xff0c;管理员可以进行图书馆管理、用户管理、分类管理等功能 1.1 背景描述 图书书店销售管理…

Apache OFBiz SSRF漏洞CVE-2024-45507分析

Apache OFBiz介绍 Apache OFBiz 是一个功能丰富的开源电子商务平台&#xff0c;包含完整的商业解决方案&#xff0c;适用于多种行业。它提供了一套全面的服务&#xff0c;包括客户关系管理&#xff08;CRM&#xff09;、企业资源规划&#xff08;ERP&#xff09;、订单管理、产…

Colorful/七彩虹将星X17 AT 22 Win11原厂OEM系统 带COLORFUL一键还原

安装完毕自带原厂驱动和预装软件以及一键恢复功能&#xff0c;自动重建COLORFUL RECOVERY功能&#xff0c;恢复到新机开箱状态。 【格式】&#xff1a;iso 【系统类型】&#xff1a;Windows11 原厂系统下载网址&#xff1a;http://www.bioxt.cn 注意&#xff1a;安装系统会…

这五本大模型书籍,让你从大模型零基础到精通,非常详细收藏我这一篇就够了

大模型&#xff08;Large Language Models, LLMs&#xff09;是近年来人工智能领域的一大热点&#xff0c;它们在自然语言处理、对话系统、内容生成等多个方面展现出了强大的能力。随着技术的发展&#xff0c;市面上出现了许多介绍大模型理论与实践的书籍&#xff0c;为研究人员…

【ADC】SAR 型 ADC 和 ΔΣ ADC 的选型决策方法

本文学习于TI 高精度实验室课程&#xff0c;介绍如何选择 SAR 或 delta-sigma 型 ADC。 文章目录 一、选型决策树二、特定传感器的应用三、需要 DC 精度但分辨率较低的应用四、需要 DC 精度且分辨率较高的应用五、极低噪声的 DC 精密测量六、需要捕获瞬态信号值的应用七、需要高…

敏感字段加密 - 华为OD统一考试(E卷)

2024华为OD机试(E卷+D卷+C卷)最新题库【超值优惠】Java/Python/C++合集 题目描述 【敏感字段加密】给定一个由多个命令字组成的命令字符串: 1、字符串长度小于等于127字节,只包含大小写字母,数字,下划线和偶数个双引号; 2、命令字之间以一个或多个下划线 进行分割; 3、可…

朋友圈信息流广告投放,曝光成本是多少?

微信作为国内最流行的社交平台之一&#xff0c;其朋友圈广告凭借精准的用户画像和强大的社交属性&#xff0c;成为了众多品牌商家进行市场推广的重要渠道。云衔科技推出了专业的微信朋友圈广告开户及代运营服务&#xff0c;旨在帮助企业轻松跨越技术门槛&#xff0c;精准触达目…

猜拳数据集-石头-剪刀-布数据集

“石头-剪刀-布”计算机视觉项目是一个利用摄像头捕捉手势并识别出手势是石头、剪刀还是布的项目。这类项目通常用于学习和展示计算机视觉技术&#xff0c;如图像处理、特征提取以及机器学习或深度学习模型的应用。 数据介绍 rock-paper-scissors Computer Vision Project数…

信息学奥赛复赛复习05-CSP-J2020-01优秀的拆分-对数函数、自然对数、以2为底的对数、幂函数、打表

PDF文档回复:20240927 1 2020 CSP-J 题目1 优秀的拆分 [题目描述] 一般来说&#xff0c;一个正整数可以拆分成若干个正整数的和 例如&#xff0c;11&#xff0c;101234 等。对于正整数 n的一种特定拆分&#xff0c;我们称它为“优秀的”&#xff0c;当且仅当在这种拆分下&am…