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

微服务项目->在线oj系统(Java版 - 5)

相信自己,终会成功

微服务代码:  lyyy-oj: 微服务

目录

C端代码

用户题目接口

 修改后用户提交代码(应用版)

 用户提交题目判题结果

代码沙箱

1. 代码沙箱的核心功能

2. 常见的代码沙箱实现方式

3. 代码沙箱的关键问题与解决方案

4. 你的代码如何与沙箱交互?

6. 总结

Elasticsearch

RabbitMQ

RabbitMQ 主要功能

RabbitMQ 工作流程示例

典型应用场景


C端代码

用户题目接口

从前端接收到数据,判断是什么语言,如果是Java语言(目前只能进行Java语言的判定)

利用代码沙箱(下方有介绍),对语言进行判断

assembleJudgeSubmitDTO:拿到questionId , 从es中查询题目信息

如果questionES不等于空,

BeanUtil.copyProperties(questionES,judgeSubmitDTO),将questionES复制给 judgeSubmitDTO

否则,从数据库中查找数据,将查出的数据复制给judgeSubmitDTO

然后将数据存入es中

将从线程池中拿到的数据赋值给judgeSubmitDTO

拼接代码后进行解析测试用例

步骤说明
questionCaseList.stream()List<QuestionCase>转为Stream<QuestionCase>,支持链式操作
.map(QuestionCase::getInput)提取每个QuestionCase对象的input字段(方法引用,等价于x -> x.getInput()
.toList()Stream<String>收集为不可变List<String>(Java 16+特性)
setInputList/setOutputList最终将输入/输出列表设置到判题DTO对象

数据流转示例

假设原始数据:

List<QuestionCase> questionCaseList = [{"input": "1 2", "output": "3"},{"input": "3 4", "output": "7"}
]

 转换后结果:

inputList = ["1 2", "3 4"]  // 所有input的集合
outputList = ["3", "7"]      // 所有output的集合
 @Override//后端接收到请求,获取参数,根据getProgramType判断用户提交代码语言类型//    UserSubmitDTO(用户提交的数据,包括题目ID、代码、考试ID等)
//    JudgeSubmitDTO(判题服务需要的数据,包括题目信息、测试用例、用户代码等)public R<UserQuestionResultVO> submit(UserSubmitDTO submitDTO) {Integer programType = submitDTO.getProgramType();if(ProgramType.JAVA.getValue().equals(programType)){//按照Java逻辑处理JudgeSubmitDTO judgeSubmitDTO=assembleJudgeSubmitDTO(submitDTO);
//            remoteJudgeService.doJudgeJavaCode(judgeSubmitDTO)return remoteJudgeService.doJudgeJavaCode(judgeSubmitDTO);}throw new ServiceException(ResultCode.FAILED_NOT_SUPPORT_PROGRAM);}private JudgeSubmitDTO assembleJudgeSubmitDTO(UserSubmitDTO submitDTO) {Long questionId = submitDTO.getQuestionId();//orElse,findbyId返回的是Optional对象,并不是数据本身,如果能查出数据,返回数据本身//查不出来数据,返回null// 1. 查询题目信息(优先ES,不存在则查MySQL并缓存)QuestionES questionES = questionRepository.findById(questionId).orElse(null);JudgeSubmitDTO judgeSubmitDTO=new JudgeSubmitDTO();if(questionES!=null){BeanUtil.copyProperties(questionES,judgeSubmitDTO);}else{Question question = questionMapper.selectById(questionId);BeanUtil.copyProperties(question,judgeSubmitDTO);questionES=new QuestionES();// 2. 组装 JudgeSubmitDTOBeanUtil.copyProperties(question, questionES);questionRepository.save(questionES);}// 3. 设置用户信息(从 ThreadLocal 获取用户ID)judgeSubmitDTO.setUserId(ThreadLocalUtil.get(Constants.USER_ID,Long.class));judgeSubmitDTO.setExamId(submitDTO.getExamId());judgeSubmitDTO.setProgramType(submitDTO.getProgramType());// 4.拼接用户代码和题目主函数judgeSubmitDTO.setUserCode(codeConnect(submitDTO.getUserCode(),questionES.getMainFuc()));// 5. 解析测试用例(从 ES 的 JSON 字符串转换成 List)List<QuestionCase> questionCaseList = JSONUtil.toList(questionES.getQuestionCase(), QuestionCase.class);List<String> inputList = questionCaseList.stream().map(QuestionCase::getInput).toList();judgeSubmitDTO.setInputList(inputList);List<String> outputList = questionCaseList.stream().map(QuestionCase::getOutput).toList();judgeSubmitDTO.setOutputList(outputList);return judgeSubmitDTO;}

 修改后用户提交代码(应用版)

JudgeProducer(使用了RabbitMQ(下方有介绍))

 /*** 将用户提交的代码通过RabbitMQ异步发送给判题服务(目前仅支持Java)* @param submitDTO 用户提交的代码信息,包含代码内容、题目ID、编程语言类型等* @return true 提交成功 | 抛出异常 提交失败(不支持的编程语言)* @throws ServiceException 如果编程语言不支持,抛出业务异常(ResultCode.FAILED_NOT_SUPPORT_PROGRAM)*/@Overridepublic boolean rabbitSubmit(UserSubmitDTO submitDTO) {// 1. 获取用户提交的编程语言类型Integer programType = submitDTO.getProgramType();if(ProgramType.JAVA.getValue().equals(programType)){//按照Java逻辑处理, 组装判题服务需要的DTO(包括代码、测试用例等信息)JudgeSubmitDTO judgeSubmitDTO=assembleJudgeSubmitDTO(submitDTO);// 通过RabbitMQ生产者将判题任务发送到消息队列(异步处理)
//             把参数给rabbitmq,但是没执行判题结果,目前实现是同步调用远程服务judgeProducer.produceMsg(judgeSubmitDTO);// 返回true表示消息已成功提交到队列(注意:不表示判题已完成)return true;}throw new ServiceException(ResultCode.FAILED_NOT_SUPPORT_PROGRAM);}
@Component
//@Component:将该类标记为 Spring 组件,由 Spring 容器管理
@Slf4j
public class JudgeProducer {@Autowiredprivate RabbitTemplate rabbitTemplate;public void produceMsg(JudgeSubmitDTO judgeSubmitDTO) {try {
//            使用 RabbitTemplate 向 RabbitMQ
//            发送消息消息内容是 JudgeSubmitDTO(判题提交数据传输对象)
//            发送到名为 OJ_WORK_QUEUE 的队列rabbitTemplate.convertAndSend(RabbitMQConstants.OJ_WORK_QUEUE, judgeSubmitDTO);} catch (Exception e) {log.error("生产者发送消息异常", e);throw new ServiceException(ResultCode.FAILED_RABBIT_PRODUCE);}}
}

 用户提交题目判题结果

  /*** 根据考试ID、题目ID和时间戳查询用户的判题结果* @param examId 考试ID* @param questionId 题目ID* @param currentTime 提交时间标识(用于区分同一题目的多次提交)* @return UserQuestionResultVO 包含判题状态、执行结果、用例详情等*/@Overridepublic UserQuestionResultVO exeResult(Long examId, Long questionId, String currentTime) {//把结果获取出来// 1. 从ThreadLocal中获取当前用户ID(基于登录上下文)Long userId = ThreadLocalUtil.get(Constants.USER_ID, Long.class);// 2. 查询数据库获取用户提交记录UserSubmit userSubmit = userSubmitMapper.selectCurrentUserSubmit(userId, questionId, examId, currentTime);// 3. 构建返回VO对象UserQuestionResultVO resultVO = new UserQuestionResultVO();// 4. 判题结果不存在的情况(可能还在判题中)if (userSubmit == null) {resultVO.setPass(QuestionResType.IN_JUDGE.getValue()); // 设置状态为"判题中"}// 5. 存在判题结果else {resultVO.setPass(userSubmit.getPass());resultVO.setExeMessage(userSubmit.getExeMessage());if (StrUtil.isNotEmpty(userSubmit.getCaseJudgeRes())) {resultVO.setUserExeResultList(JSON.parseArray(userSubmit.getCaseJudgeRes(), UserExeResult.class));}}return resultVO;}

代码沙箱

代码沙箱(Code Sandbox)是一种安全隔离的执行环境,用于运行不受信任的代码(如用户提交的编程题答案),防止恶意代码影响主系统。在在线判题系统(Online Judge)中,代码沙箱是核心组件之一。

1. 代码沙箱的核心功能

功能

说明

安全隔离

防止用户代码破坏主机(如删除文件、无限循环、占用资源)。

资源限制

限制 CPU、内存、执行时间,避免恶意代码耗尽系统资源。

输入/输出控制

提供标准输入(测试用例),捕获标准输出/错误,与判题系统交互。

多语言支持

支持 Java、Python、C++ 等语言的编译和运行。

错误处理

捕获运行时异常、编译错误,并返回友好提示。

2. 常见的代码沙箱实现方式

1.基于 Docker 的沙箱

原理:每个用户提交的代码在一个临时 Docker 容器中运行,运行后销毁。

优点

强隔离性(进程、文件系统、网络均隔离)。

可限制 CPU、内存等资源(通过 cgroups)。

示例流程

用户提交代码 → 判题系统接收。

生成临时 Docker 容器,挂载代码文件。

在容器内编译/运行代码,传入测试用例。

捕获输出,对比预期结果。

销毁容器。

2. 基于 JVM 沙箱(Java 专用)

原理:利用 Java 的 SecurityManager 或字节码修改(如 ASM)限制敏感操作。

优点

轻量级,启动快。

适合纯 Java 判题场景。

缺点

无法完全隔离系统调用(如 System.exit())。

需要自定义安全策略。

3. 第三方沙箱服务

示例

Judge0:开源的在线判题沙箱(支持 60+ 语言)。

Piston:轻量级多语言执行引擎。

优点:无需自行维护沙箱环境。

3. 代码沙箱的关键问题与解决方案

问题

解决方案

恶意代码

使用 Docker 隔离,限制系统调用(如 forkexec)。

无限循环

设置超时机制(如 Linux 的 timeout 命令)。

内存溢出

通过 -Xmx 限制 JVM 内存,或 Docker --memory 限制容器内存。

文件系统安全

Docker 使用只读文件系统,或临时挂载空目录。

网络隔离

禁用容器网络(--network none)。

4. 你的代码如何与沙箱交互?

执行流程

用户提交代码 → 你的服务组装 JudgeSubmitDTO(题目ID、代码、测试用例等)。

通过 Feign 调用判题服务(remoteJudgeService.doJudgeJavaCode)。

判题服务将代码发送到 代码沙箱 执行。

沙箱返回结果(通过/失败、错误信息、用时等)。

你的服务接收结果并返回给用户。

6. 总结

代码沙箱 是判题系统的核心,确保安全性和稳定性。

推荐方案

小型系统:用 Docker 快速实现。

大型系统:结合 Kubernetes 管理沙箱集群。

扩展方向

支持更多语言(Python、C++)。

分布式判题(提高并发能力)。

为什么需要沙箱?

安全隔离:防止用户代码破坏宿主系统。

资源控制:限制CPU/内存使用,避免恶意代码耗尽资源。

环境一致性:确保每次执行都在干净的环境中运行。


Elasticsearch

官方网站:

Elastic Docs | Elastic

Elasticsearch(简称 ES)是一个开源的分布式 搜索和分析引擎,基于 Apache Lucene 构建,专为处理海量数据设计,支持近实时(NRT, Near Real-Time)搜索。

优点

高性能搜索,支持复杂查询(全文检索、模糊匹配、聚合分析)。

水平扩展能力强,适合大数据场景。

生态完善(ELK Stack、APM、SIEM 等)。

缺点

不支持事务(不适合金融级一致性要求场景)。

资源消耗较高(尤其是内存)。

学习曲线较陡(需理解分词、映射、集群管理等)


RabbitMQ

RabbitMQ 是一个开源的 消息代理(Message Broker),实现了 AMQP(Advanced Message Queuing Protocol) 协议,用于在分布式系统中存储、转发消息。

核心角色:生产者(Producer)→ RabbitMQ → 消费者(Consumer)

典型场景:异步任务处理、应用解耦、流量削峰、分布式系统通信。

概念说明
Producer消息生产者,发送消息到 Exchange
Consumer消息消费者,从 Queue 接收消息
Exchange消息路由组件,决定消息投递到哪些 Queue(类型:Direct、Fanout、Topic、Headers)
Queue存储消息的缓冲区,消费者从中订阅消息
BindingExchange 和 Queue 的绑定规则(如路由键 Routing Key)
Channel轻量级连接(复用 TCP 连接,减少开销)
Virtual Host虚拟隔离环境(类似命名空间,不同 vhost 资源互不干扰)

RabbitMQ 主要功能

消息路由(Exchange Types)

Direct Exchange
→ 精确匹配 Routing Key,消息投递到完全匹配的 Queue。

// 示例:日志级别路由(error、warning、info)
channel.queueBind("error_queue", "logs_exchange", "error");

Fanout Exchange
→ 广播模式,消息发送到所有绑定的 Queue(忽略 Routing Key)。

// 示例:新闻通知广播
channel.exchangeDeclare("news", BuiltinExchangeType.FANOUT);

 Topic Exchange
→ 通配符匹配 Routing Key* 匹配一个词,# 匹配多个词)。

// 示例:订单路由(order.create、order.payment.success)
channel.queueBind("queue_payment", "orders", "order.payment.*");

 Headers Exchange
→ 基于消息头(Headers)匹配,不依赖 Routing Key(性能较低,较少使用)。

 消息可靠性

消息确认(ACK/NACK)
→ 消费者处理成功后发送 ACK,失败时 NACK(可配置重试或进入死信队列)。

channel.basicConsume(queue, false, consumer); // 手动ACK
channel.basicAck(deliveryTag, false); // 确认处理成功

 持久化(Persistence)
→ Exchange、Queue、消息均可持久化到磁盘,防止服务重启丢失。

// 声明持久化队列
channel.queueDeclare("task_queue", true, false, false, null);

 死信队列(DLX)
→ 处理失败或超时的消息可转发到死信队列,用于异常监控和重试。

Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", "dlx_exchange");
channel.queueDeclare("normal_queue", false, false, false, args);

高级特性

TTL(Time-To-Live)
→ 设置消息或队列的过期时间(超时未消费则自动删除)。

// 消息级别TTL
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().expiration("60000") // 60秒过期.build();
channel.basicPublish(exchange, routingKey, props, message.getBytes());

优先级队列(Priority Queue)
→ 消息按优先级消费(需队列声明时支持)。

Map<String, Object> args = new HashMap<>();
args.put("x-max-priority", 10); // 最大优先级为10
channel.queueDeclare("priority_queue", false, false, false, args);

 集群与镜像队列
→ 支持多节点集群,镜像队列(Mirrored Queue)实现高可用。

RabbitMQ 工作流程示例

典型应用场景

  1. 异步任务处理
    → 用户注册后异步发送邮件/短信。

  2. 应用解耦
    → 订单系统与库存系统通过消息队列通信。

  3. 流量削峰
    → 秒杀请求先写入队列,后端按能力消费。

  4. 日志收集
    → 多个服务发送日志到统一队列,由消费者存储到ES/数据库。

 对比其他消息队列

RabbitMQKafkaRocketMQ
协议AMQP自定义协议自定义协议
吞吐量中等(万级TPS)高(百万级TPS)高(十万级TPS)
延迟低(毫秒级)中(依赖批量)
适用场景业务消息、实时处理日志流、大数据金融级事务消息

RabbitMQ 是轻量级、高可用的消息中间件,适合需要可靠消息传递的分布式系统。通过灵活的路由规则和丰富的特性,平衡了性能与功能需求 

相关文章:

微服务项目->在线oj系统(Java版 - 5)

相信自己,终会成功 微服务代码: lyyy-oj: 微服务 目录 C端代码 用户题目接口 修改后用户提交代码(应用版) 用户提交题目判题结果 代码沙箱 1. 代码沙箱的核心功能 2. 常见的代码沙箱实现方式 3. 代码沙箱的关键问题与解决方案 4. 你的代码如何与沙箱交互&#xff1f; …...

disryptor和rabbitmq

disryptor和rabbitmq Disruptor 是什么&#xff1f; Disruptor 是一个由 LMAX Exchange 开发的高性能、低延迟的进程内&#xff08;in-process&#xff09;并发编程框架/库。它最初是为了解决金融交易系统中高吞吐量、低延迟消息传递的需求而设计的。 核心特点和设计理念&am…...

HTTP与HTTPS协议的核心区别

HTTP与HTTPS协议的核心区别 数据传输安全性 HTTP采用明文传输&#xff0c;数据易被窃听或篡改&#xff08;如登录密码、支付信息&#xff09;&#xff0c;而HTTPS通过SSL/TLS协议对传输内容加密&#xff0c;确保数据完整性并防止中间人攻击。例如&#xff0c;HTTPS会生成对称加…...

Flink 并行度的设置

在 Apache Flink 中&#xff0c;并行度&#xff08;Parallelism&#xff09; 是控制任务并发执行的核心参数之一。Flink 提供了 多个层级设置并行度的方式&#xff0c;优先级从高到低如下&#xff1a; &#x1f9e9; 一、Flink 并行度的四个设置层级 层级描述设置方式Operator…...

【微服务】SpringBoot + Docker 实现微服务容器多节点负载均衡详解

目录 一、前言 二、前置准备 2.1 基本环境 2.2 准备一个springboot工程 2.2.1 准备几个测试接口 2.3 准备Dockerfile文件 2.4 打包上传到服务器 三、制作微服务镜像与运行服务镜像 3.1 拷贝Dockerfile文件到服务器 3.2 制作服务镜像 3.3 启动镜像服务 3.4 访问一下服…...

get请求使用数组进行传参

get请求使用数组进行传参,无需添加中括号 mvc接口要添加参数名&#xff0c;使用array承接。不能用list, 否则会报错 这里是用apifox模拟前端调用。 前端调用代码 // 根据项目ID和角色ID查询相关审批人 export function findRelativeApproverByProjectIdAndRoleId(roleIds, p…...

20. 自动化测试框架开发之Excel配置文件的IO开发

20.自动化测试框架开发之Excel配置文件的IO开发 一、核心架构解析 1.1 类继承体系 class File: # 文件基类# 基础文件验证和路径管理class ExcelReader(File): # Excel读取器# 实现Excel数据解析逻辑1.2 版本依赖说明 # 必须安装1.2.0版本&#xff08;支持xlsx格式&#…...

【MySQL成神之路】MySQL常用语法总结

目录 MySQL 语法总结 数据库操作 表操作 数据操作 查询语句 索引操作 约束 事务控制 视图操作 存储过程和函数 触发器 用户和权限管理 数据库操作 创建数据库&#xff1a; CREATE DATABASE database_name; 选择数据库&#xff1a; USE database_name; 删除数…...

Linux动静态库制作与原理

什么是库 库是写好的现有的&#xff0c;成熟的&#xff0c;可以复用的代码。现实中每个程序都要依赖很多基础的底层库&#xff0c;不可能每个人的代码都从零开始&#xff0c;因此库的存在意义非同寻常。 本质上来说库是一种可执行代码的二进制形式&#xff0c;可以被操作系统…...

确保高质量的音视频通话,如何最大化利用视频带宽

在当今数字时代&#xff0c;音视频内容随处可见&#xff0c;对于开发者来说&#xff0c;理解互联网带宽变得至关重要。我们的在线体验质量&#xff0c;无论是观看高清电影还是演唱会直播&#xff0c;都严重依赖于互联网带宽的概念。在本文中&#xff0c;我们将揭示视频带宽的复…...

ffmpeg 把一个视频复制3次

1. 起因&#xff0c; 目的: 前面我写过&#xff0c;使用 python 把一个视频复制3次但是速度太慢了&#xff0c;我想试试看能否改进。而且我想换一种新的视频处理思路&#xff0c;并试试看速度如何。 2. 先看效果 效果就是能行&#xff0c;而且速度也快。 3. 过程: 代码 1…...

GPT/Claude3国内免费镜像站更新 亲测可用

无限次使用&#xff1a;无限制的提问次数&#xff0c;不设上限&#xff0c;随心所欲。 无需魔法、稳定流畅&#xff1a;操作简便&#xff0c;无需复杂设置&#xff0c;即可享受稳定流畅的服务。 手机和电脑均能用&#xff1a;轻松适配手机和电脑&#xff0c;使用体验更佳。 …...

AI自动化工作流:开启当下智能生产力的价值

举手之言&#xff1a;AI自动化工作流创造了什么呢&#xff1f; AI自动化工作流 &#xff0c;顾名思义&#xff0c;是将人工智能&#xff08;AI&#xff09;技术与自动化流程相结合&#xff0c;通过智能化的方式来完成复杂的任务和操作。简单来说&#xff0c;它就是利用AI的强大…...

stm32——EXTI外部中断

NVIC优先级分组 抢占优先级 可以进行中断嵌套的优先级&#xff0c;即可以不等上一个中断执行完成就进入下一个中断 响应优先级 决定中断发生的顺序&#xff0c;但不可嵌套 程序实现 对射式红外传感计次 #include "stm32f10x.h" // Device head…...

Python:操作Excel按行写入

Python按行写入Excel数据,5种实用方法大揭秘! 在日常的数据处理和分析工作中,我们经常需要将数据写入到Excel文件中。Python作为一门强大的编程语言,提供了多种库和方法来实现将数据按行写入Excel文件的功能。本文将详细介绍5种常见的Python按行写入Excel数据的方法,并附上…...

Redis进阶知识

Redis 1.事务2. 主从复制2.1 如何启动多个Redis服务器2.2 监控主从节点的状态2.3 断开主从复制关系2.4 额外注意2.5拓扑结构2.6 复制过程2.6.1 数据同步 3.哨兵选举原理注意事项 4.集群4.1 数据分片算法4.2 故障检测 5. 缓存5.1 缓存问题 6. 分布式锁 1.事务 Redis的事务只能保…...

Python机器学习笔记(二十三 模型评估与改进-网格搜索)

上一次学习了评估一个模型的泛化能力,现在继续学习通过调参来提升模型的泛化性能。scikit-learn中许多算法的参数设置,在尝试调参之前,重要的是要理解参数的含义。找到一个模型的重要参数(提供最佳泛化性能的参数)的取值是一项棘手的任务,但对于几乎所有模型和数据集来说…...

12.vue整合springboot首页显示数据库表-实现按钮:【添加修改删除查询】

vue整合springboot首页显示数据库表&#xff1a;【添加修改删除查询】 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是node.js和vue的使用。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性。【帮帮志系…...

bisheng系列(一)- 本地部署(Docker)

目录 一、导读 二、说明 1、镜像说明 2、本节内容 三、docker部署 1、克隆代码 2、运行镜像 3、可能的错误信息 四、页面测试 1、注册用户 2、登陆成功 3、添加模型 一、导读 环境&#xff1a;Ubuntu 24.04、Windows 11、WSL 2、Python 3.10 、bisheng 1.1.1 背景…...

如何用Python批量解压ZIP文件?快速解决方案

如何用Python批量解压ZIP文件&#xff1f;快速解决方案 文章目录 **如何用Python批量解压ZIP文件&#xff1f;快速解决方案**代码结果详细解释 话不多说&#xff0c;先上干货&#xff01;&#xff01;&#xff01; 代码 import os import zipfiledef unzip_file(dir_path: str…...

DriveGenVLM:基于视觉-语言模型的自动驾驶真实世界视频生成

《DriveGenVLM: Real-world Video Generation for Vision Language Model based Autonomous Driving》2024年8月发表&#xff0c;来自哥伦比亚大学的论文。 自动驾驶技术的进步需要越来越复杂的方法来理解和预测现实世界的场景。视觉语言模型&#xff08;VLM&#xff09;正在成…...

JavaScript 中的五种继承方式进行深入对比

文章目录 前言JavaScript 五种继承方式对比原型链继承构造函数继承组合继承寄生组合继承ES6 class extends 继承五种继承方式对比表前言 对 JavaScript 中的五种继承方式进行深入对比:原型链继承、构造函数继承、组合继承、寄生组合继承、以及 ES6 的 class extends。 内容将…...

企业标准信息公共服务平台已开放标准通编辑器访问入口

标准通 数字化标准编辑器 专业、高效、便捷 企业标准信息公共服务平台 近日&#xff0c;企业标准信息公共服务平台已开放标准通编辑器访问入口&#xff0c;可进入官网指定版块使用&#xff01; 核心功能亮点 解决企业痛点 传统标准编制&#xff0c;需反复核对格式、逐条…...

[Linux]安装吧!我的软件包管理器!

一、常见安装方式 在 Linux 中&#xff0c;有 3 种常见的软件安装方式&#xff1a; &#xff08;1&#xff09;yam、apt &#xff08;2&#xff09;.rpm 安装包安装 &#xff08;3&#xff09;源码安装 二、什么是软件包 在 Linux 下安装软件&#xff0c;通常的办法是下载…...

Spring Boot 与 RabbitMQ 的深度集成实践(三)

高级特性实现 消息持久化 在实际的生产环境中&#xff0c;消息的可靠性是至关重要的。消息持久化是确保 RabbitMQ 在发生故障或重启后&#xff0c;消息不会丢失的关键机制。它涉及到消息、队列和交换机的持久化配置。 首先&#xff0c;配置队列持久化。在创建队列时&#xf…...

进阶-数据结构部分:1、数据结构入门

飞书文档https://x509p6c8to.feishu.cn/wiki/HRLkwznHiiOgZqkqhLrcZNqVnLd 一、存储结构 顺序存储 链式存储 二、常用数据结构 2.1、栈 先进后出 场景&#xff1a; 后退/前进功能&#xff1a;网页浏览器中的后退和前进按钮可以使用栈来实现。在浏览网页时&#xff0c;每次…...

React 19中useContext不需要Provider了。

文章目录 前言一、React 19中useContext移除了Provider&#xff1f;二、使用步骤总结 前言 在 React 19 中&#xff0c;useContext 的使用方式有所更新。开发者现在可以直接使用 作为提供者&#xff0c;而不再需要使用 <Context.Provider>。这一变化简化了代码结构&…...

Json schema校验json字符串(networknt/json-schema-validator库)

学习链接 json-schema官网 - 英文 jsonschemavalidator 可在线校验网站 networknt的json-schema-validator github地址 networknt的json-schema-validator 个人gitee地址 - 里面有md文档说明和代码示例 JSON Schema 入门指南&#xff1a;如何定义和验证 JSON 数据结构 JS…...

交易所开发:构建功能完备的金融基础设施全流程指南

交易所开发&#xff1a;构建功能完备的金融基础设施全流程指南 ——从技术架构到合规安全的系统性解决方案 一、开发流程&#xff1a;从需求分析到运维优化 开发一款功能完备的交易所需要遵循全生命周期管理理念&#xff0c;涵盖市场定位、技术实现、安全防护和持续迭代四大阶…...

Windows_Vs2022 C#语言开发环境构建

Windows_VisualStudio2022 C#语言开发环境构建 一、C#语言简介历史背景语言特点应用领域开发工具未来发展方向 二、Visual Studio 2022&#xff08;一&#xff09;开发语言支持&#xff08;二&#xff09;主要功能&#xff08;三&#xff09;适用场景&#xff08;四&#xff09…...