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

关闭超时订单和七天自动确认收货+RabbitMQ规范

关闭超时订单

创建订单之后的一段时间内未完成支付而关闭订单的操作,该功能一般要求每笔订单的超时时间是一致的

TTL(Time To Live)存活时间,只能被设置为某个固定的值,不能更改,否则抛出异常
死信(当消息达到过期时间还没有被消费,那么该消息就“死了”)

消息变为死信的条件:

  • 消息被拒绝,并且requeue=false
  • 消息的过期时间到期了
  • 队列达到最大长度

死信交换机:Dead-Letter-Exchange,简称 DLX

  • 当消息在一个队列中变成死信之后,如果这个消息所在的队列设置了 x-dead-letter-exchange参数,那么它会被发送到 x-dead-letter-exchange对应值的交换机上,这个交换机就称之为死信交换机,与这个死信交换器绑定的队列就是死信队列。
  • x-dead-letter-exchange:出现死信之后将死信重新发送到指定交换机
  • x-dead-letter-routing-key:出现死信之后将死信重新按照指定的 routing-key 发送,如果不设置默认使用消息本身的 routing-key

在这里插入图片描述

  1. 生产者发送带有ttl的消息放入交换机路由到延时队列
  2. 延时队列绑定死信交换机与死信转发的routing-key
  3. 等延时队列中的消息达到延时时间之后变成死信转发到死信交换机并路由到死信队列中
  4. 最后供消费者消费

①、配置类

@Configuration
public class DelayQueueRabbitConfig{public static final String DLX_QUEUE = "queue.dlx";//死信队列public static final String DLX_EXCHANGE = "exchange.dlx";//死信交换机public static final String DLX_ROUTING_KEY = "routingkey.dlx";//死信队列与死信交换机绑定的routing-keypublic static final String ORDER_QUEUE = "queue.order";//订单的延时队列public static final String ORDER_EXCHANGE = "exchange.order";//订单交换机public static final String ORDER_ROUTING_KEY = "routingkey.order";//延时队列与订单交换机绑定的routing-key//定义死信队列@Beanpublic Queue dlxQueue(){return new Queue(DLX_queue,true);}//定义死信交换机@Beanpublic DirectExchange dlxExchange(){return new DirectExchange(DLX_EXCHANGE,true,false);}//死信交换机和死信队列绑定@BeanBinding bindingDLX(){return BindingBuilder.bind(dlxQueue()).to(dlxExchange()).with(DLX_ROUTING_KEY);}//订单延时队列//设置队列里的死信转发到的DLX名称,设置死信在转发时携带的routing-key名称@Beanpublic Queue orderQueue(){Map<String,Object> params = new HashMap<>();params.put("x-dead-letter-exchange", DLX_EXCHANGE);params.put("x-dead-letter-routing-key", DLX_ROUTING_KEY);return new Queue(ORDER_QUEUE, true, false, false, params);}//订单交换机@Beanpublic DirectExchange orderExchange(){return new DirectExchange(ORDER_EXCHANGE,true,false);}//把订单队列和订单交换机绑定一块@Beanpublic Binding orderBinding(){return BindingBuilder.bind(orderQueue()).to(orderExchange()).with(ORDER_ROUTING_KEY);}
}

②、发送消息

@RequestMapping("/order")
public class OrderSendMessageController{@Autowiredprivate RabbitTemplate rabbitTemplate;@GetMapping("/sendMessage")public String sendMessage(){String delayTime = "10000";rabbitTemplate.convertAndSend(DelayQueueRabbitConfig.ORDER_EXCHANGE, DelayQueueRabbitConfig.ORDER_ROUTING_KEY,"发送消息!",message->{message.getMessageProperties().setExpiration(delayTime);return message;});return "ok";}
}

③、消费消息

@Component
@RabbitListener(queues=DelayQueueRabbitConfig.DLX_QUEUE)//监控死信队列
public class OrderMQReciever{@RabbitHandlerpublic void process(String message){System.out.println("OrderMQReciever接收到的消息是:"+ message);}
}

测试:

通过调用接口,发现 10 秒之后才会消费消息
在这里插入图片描述

七天自动确认收货

签收商品后,物流系统会在七天后延时发送一个消息给支付系统,通知支付系统将款打给商家
这个过程持续七天,就是使用了消息中间件的延迟推送功能

传统解决方案:

  • 使用 Redis 给订单设置过期时间,最后通过判断 Redis 中是否还有该订单来决定订单是否已经完成。这种解决方案相较于消息的延迟推送性能较低,因为我们知道 Redis 都是存储于内存中,我们遇到恶意下单或者刷单的将会给内存带来巨大压力;
  • 使用传统的数据库轮询来判断数据库表中订单的状态,这无疑增加了 IO 次数,性能极低;
  • 使用 JVM 原生的 DelayQueue ,也是大量占用内存,而且没有持久化策略,系统宕机或者重启都会丢失订单信息。

还是通过死信队列 + TTL过期时间来实现延迟队列:

①、在 RabbitMQ 3.6.x 开始,RabbitMQ 官方提供了延迟队列的插件

插件下载地址:https://github.com/rabbitmq/rabbitmq-delayed-message-exchange
下载放置到 RabbitMQ 根目录下的 plugins 下

②、创建交换机和消息队列

@Configuration
public class MQConfig{public static final String LAZY_EXCHANGE = "Ex.LazyExchange";public static final String LAZY_QUEUE = "MQ.LazyQueue";public static final String LAZY_KEY = "lazy.#";@Beanpublic TopicExchange lazyExchange(){//Map<String, Object> pros = new HashMap<>();//设置交换机支持延迟消息推送//pros.put("x-delayed-message", "topic");TopicExchange exchange = new TopicExchange(LAZY_EXCHANGE,true,false,pros);exchange.setDelayed(true);//来开启延迟队列return exchange;}@Beanpublic Queue lazyQueue(){return new Queue(LAZY_QUEUE,true);}@Beanpublic Binding lazyBinding(){return BindingBuilder.bind(lazyQueue()).to(lazyExchange()).with(LAZY_KEY);}
}

③、发送方

@Component
public class MQSender{@Autowiredprivate RabbitTemplate rabbitTemplate;/**指定延迟推送时间传入参数 new MessagePostProcessor() 是为了获得 Message对象,因为需要借助 Message对象的API 来设置延迟时间*/public void sendLazy(Object message){//confirmCallback returnCallback 代码省略rabbitTemplate.setMandatory(true);rabbitTemplate.setConfirmCallback(cofirmCallback);rabbitTemplate.setReturnCallback(returnCallback);//id+时间戳 全局唯一CorrelationData correlationData = new CorrelationData("12345678909" + new Date());rabbitTemplate.convertAndSend(MQConfig.LAZY_EXCHANGE, "lazy.boot",new MessagePostProcessor() {@Overridepublic Message postProcessMessage(Message message) throws AmqpException {//设置消息持久化message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);//message.getMessageProperties().setHeader("x-delay", "6000");message.getMessageProperties().setDelay(6000);return message;}},correlationData);}
}

④、消费方

@Component
public class MQReceiver{@RabbitListener(queues = "MQ.lazyQueue")@RabbitHandlerpublic void onLazyMessage(Message msg, Channel channel)throws IOException{long deliveryTag = msg.getMessageProperties().getDeliveryTag();channel.basicAck(deliveryTag, true);System.out.println("lazy receive " + new String(msg.getBody()));}
}

⑤、测试

在 6 秒后收到了消息 “lazy receive hello spring boot:”

@SpringBootTest
@RunWith(SpringRunner.class)
public class MQSenderTest{@Autowiredprivate MQSender mqSender;@Testpublic void sendLazy()throws Exception{String msg = "hello spring boot";mqSender.sendLay(msg + ":");}
}

RabbitMQ规范

1. 一个 RabbitMQ 应用里建立多个 vhost,去对应不同的开发项目

不同的 vhost 对应不同的项目,拥有自己的队列、绑定、交换器和权限控制

当在 RabbitMQ 中创建一个用户时,用户通常会被指派给至少一个 vhost,并且只能访问被指派 vhost 内的队列、交换器和绑定,vhost 之间是绝对隔离的。

现在的状况是大部分使用 RabbitMQ 的技术团队往往就使用默认的 vhost:“/”,如果多出一个项目了,就再去创建一个 RabbitMQ 的进程,这样做,非常浪费开发资源。

推荐一个项目对应一个 vhost

2. 不直接使用 RabbitMQ 自己的客户端

很多公司使用 RabbitMQ 都是直接使用 RabbitMQ 自己的 Java 版本客户端

由于 RabbitMQ 本身内在的复杂性和多样性,有很多技术细节需要独自处理,比如网络连接的处理,比如异常的处理,比如消息失败的处理等等等。这些,如果手头没有一套成熟的框架,那么很可能由于一些细节处理不到位,导致非常多的问题,这都是不必要的成本。

所以,要么使用一套已有的 RabbitMQ 客户端框架(比如 Spring 的 RabbitMQ 框架),要么自己封装出一套底层 RabbitMQ 客户端框架,而不是单独使用 RabbitMQ 的客户端

3. 无论如何消费者必须给回 ACK 响应

ACK 机制就是消费者从 RabbitMQ 收到消息并处理完成后,反馈给 RabbitMQ,然后 RabbitMQ 收到反馈后才将此消息从队列中删除。

由于 ACK 机制本身必须回复给 RabbitMQ,消息才会丢弃这个特点。对于何时给 ACK,我们做开发的时候一定要在开发项目前提前规划好、设计好。
使用 RabbitMQ 通常不想在收到消息就立即给回 ACK 的,也不会设置 autoACK 机制即消费端收到自动返回一个 ACK 响应。一般来讲,我们都会根据业务逻辑的不同,会在不同的位置手动返回 ACK。

这时候,就可能出现问题:当收到消息,有时候处理业务逻辑报错了,往往在处理完业务逻辑就会忽略 ACK,这会导致消息始终卡死在 queue 里……如果数量越来越多,后续处理非常麻烦。

4. 考虑设置 dead letter exchanges

有时候消息投递出错,并不总是在应用接收的时候出了问题,会有很多非应用的问题。比如:

  • 消费端有问题,发出的消息被拒绝了。并且我们也设置了 requeue=false;
  • 消息可能因为没有收到 ACK 超时被删除,或者消费端消费速度跟不上导致消息超时被删除;
  • 消息数量超过了队列最大长度限制被抛弃;
  • 消息总大小超过了队列消息总大小限制被抛弃。

对于这些问题,设置 dead letter exchanges 算是一个解决办法。
当消息一旦出现我上面列举出来的情况,就会被发送到我们设置的 dead letter exchanges。然后我们就可以对这些特殊情况的消息进行单独处理,这样的做法可以让我们的项目更健壮,更容易追踪问题。

5. 尽量使用 Direct Exchange

RabbitMQ 的Exchange 就是消息交换机,它指定消息按什么规则,路由到哪个队列。

  • Direct:处理路由键,需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键为“green”,则只有路由键为“green”的消息才被转发,不会转发路由键为"red",只会转发路由键为“green”;
  • Topic:将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”只能匹配一个词;
  • Fanout:不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到该类型交换机的消息都会被广播到与该交换机绑定的所有队列上;
  • Headers:不处理路由键,而是根据发送的消息内容中的 headers 属性进行匹配。在绑定 Queue 与 Exchange 时指定一组键值对;当消息发送到 RabbitMQ 时会取到该消息的 headers 与 Exchange 绑定时指定的键值对进行匹配;如果完全匹配则消息会路由到该队列,否则不会路由到该队列。

在这四种类型里,Direct 类型的 Exchange 投递消息是最快的。其他的 Exchange,MQ 还得花时间计算投递的位置。
所以,能使用 Direct 类型的建议使用 Direct。

多表操作开启事务

①、MybatisPlusConfig配置类添加注解@EnableTransactionManagement

@Configuration
@MapperSCAN("com.michael.ssxy.*.mapper")
@EnableTransactionManagement
public class MybatisPlusConfig{//新的分页插件,一级和二级遵循mybatis规则//需要设置MybatisConfiguration#useDeprecatedExecutor@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){}
}

②、业务方法添加@Transactional

//向两张表添加数据
@Transactional(rollbckFor={Exception.class})
public Long saveOrder(OrderSubmitVo orderParamVo,List<CartInfo> cartInfoList){}

通过RabbitMQ删除生成订单后的redis购物车数据

在这里插入图片描述

①、Rabbit工具类

public class RabbitService{@Autowiredprivate RabbitTemplate rabbitTemplate;/**exchange交换机routingKey路由message消息*/public boolean sendMessage(String exchange,String routingKey,ObjectMessage){rabbitTemplate.convertAndSend(exchange,routingKey,message);return true;}
}

②、service-order模块中service业务类

将订单id发送到MQ中

private RabbitService rabbitService;//方法内部
rabbitService.sendMessage(MqConst.EXCHANGE_ORDER_DIRECT,MqConst.ROUTING_DELETE_CART,orderParamVo.getUserId());

③、service-cart模块中创建receiver包

@Component
public class CartReceiver{@Autowiredprivate CartInfoService cartInfoService;/**userId从MQ中传过来的*/@RabbitListener(bindings = @QueueBinding(value=@Queue(value=MqConst.QUEUE_DELETE_CART,derable="true"),//持久化exchange=@Exchange(value=MqConst.EXCHANGE_ORDER_DIRECT),key={MqConst.ROUTING_DELETE_CART}))public void deleteCart(Long userId,Message message,Channel channel){if(userId != null){cartInfoService.deleteCartChecked(userId);}//手动确认channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);}
}

业务实现类

@Override
public void deleteCartChecked(Long userId){//根据用户id删除购物车已选中的数据List<CartInfo> cartInfoList = this.getCartCheckedList(userId);//获取skuId集合List<Long> skuIdList = cartInfoList.stream().map(item -> item.getSkuId()).collect(Collectors.toList());//构建redis的keyString cartKey = this.getCartKey(userId);BoundHashOperations<String,String,CartInfo> hashOperation = redisTemplate.boundHashOps(cartKey);skuIdList.forEach(skuId -> {hashOperations.delete(skuId.toString())});
}

相关文章:

关闭超时订单和七天自动确认收货+RabbitMQ规范

关闭超时订单 创建订单之后的一段时间内未完成支付而关闭订单的操作&#xff0c;该功能一般要求每笔订单的超时时间是一致的 TTL&#xff08;Time To Live&#xff09;存活时间&#xff0c;只能被设置为某个固定的值&#xff0c;不能更改&#xff0c;否则抛出异常 死信&#…...

DDD领域驱动开发第2讲:领域驱动开发在货代订单业务的实践

领域驱动开发在货代订单业务的实践 本文是DDD领域驱动开发第2讲,先讲解当前业务存在哪些问题,什么是DDD,为啥需要使用DDD解决现有业务问题,DDD让技术主动理解业务,通过领域模型将可以描述各个业务领域之间的关系,最后讲解领域驱动开发在货代订单的实践。 文章目录 领域驱…...

【Qt学习】| 如何使用QVariant存储自定义类型

QVariant是Qt框架中的一个通用数据类型&#xff0c;可以存储多种类型的数据&#xff0c;主要作用是提供一种类型安全的方式来存储和传递不同类型的数据&#xff0c;而不需要显示地指定数据类型。 QVariant提供了诸多构造函数可以非常方便地对基础数据类型&#xff08;如&#x…...

分割 学习笔记cvpr2024

目录 LiteMedSam 模型37m LightM-Unet 500 str 依赖项: MLWnet 73 star memsam 340M 126 star LiteMedSam 模型37m https://github.com/bowang-lab/MedSAM/blob/LiteMedSAM/README.md LightM-Unet 500 str https://github.com/MrBlankness/LightM-UNet/blob model = Li…...

【多模态处理篇一】【 深度解析DeepSeek图文匹配:CLIP模型迁移实战——从原理到落地的保姆级教程】

引言:当CLIP遇到DeepSeek,会发生什么化学反应? 如果说CLIP是OpenAI为多模态领域投下的"原子弹",那DeepSeek的迁移实战方案就是给这颗原子弹装上了精确制导系统。这个组合能让你用一张猫咪表情包搜到全网同类梗图,还能让电商平台自动生成百万级商品描述,甚至帮…...

水果生鲜农产品推荐系统 协同过滤余弦函数推荐水果生鲜农产品 Springboot Vue Element-UI前后端分离 代码+开发文档+视频教程

水果生鲜农产品推荐系统 协同过滤余弦函数推荐水果生鲜农产品 Springboot Vue Element-UI前后端分离 【亮点功能】 1.SpringbootVueElement-UIMysql前后端分离 2.Echarts图表统计数据, 直观展示数据情况 3.发表评论后&#xff0c;用户可以回复评论, 回复的评论可以被再次回复, …...

1.vue使用vite构建初始化项目

npm create vuelatest❯ npm create vuelatest> npx > create-vueVue.js - The Progressive JavaScript Framework✔ Project name: … vue3_test ✔ Add TypeScript? … No / Yes ✔ Add JSX Support? … No / Yes ✔ Add Vue Router for Single Page Application dev…...

在PyCharm中运行Jupyter Notebook的.ipynb文件及其pycharm软件的基础使用

&#xff08;注意需使用PyCharm专业版&#xff0c;学生、教师可以申请免费使用&#xff1a;https://www.jetbrains.com/shop/eform/students&#xff09; 1. pycharm2024版汉化 https://blog.csdn.net/m0_74103046/article/details/144560999 2. pycharm中的python控制台和J…...

深度体验通义灵码2.0 AI 程序员

通义灵码2.0 作为一名开发者&#xff0c;我去年就使用过1.0&#xff0c;近期有幸体验了 2.0&#xff0c;这是一款集成了 Deepseek 大模型的智能编码助手。在这次体验中&#xff0c;我深入探索了新功能开发、跨语言编程、单元测试自动生成、图生代码等多个场景&#xff0c;深刻…...

Coroutine协程

cooperation 协作 routine 程序&#xff0c;常规 协程核心&#xff1a;函数能够被挂起suspend,当然也能被回复resume 内置函数&#xff1a;also 返回对象本身 扩展&#xff1a; 内置函数let、also、with、run、apply大大提高你的开发效率&#xff01; 协程的作用&#xff1a;…...

使用IDEA提交SpringBoot项目到Gitee上

登录Gitee并新建仓库 创建本地仓库 提交本地代码到本地仓库 提交本地代码到远程仓库...

Windows安装MySQL指南

1.下载 下载地址&#xff1a;https://www.mysql.com/downloads/ 下载版本&#xff1a;MySQL Installer for Window 2.安装MySQL 以下只列出需要注意的一些界面&#xff0c;没出现的界面默认继续即可。 1.选择安装类型 提供了多种安装模式&#xff0c;包括默认开发版、仅…...

汽车免拆诊断案例 | 2013 款奔驰 S300L 车起步时车身明显抖动

故障现象  一辆2013款奔驰S300L车&#xff0c;搭载272 946发动机&#xff0c;累计行驶里程约为15万km。车主反映&#xff0c;将挡位置于D挡&#xff0c;稍微释放一点制动踏板&#xff0c;车辆蠕动时车身明显抖动&#xff0c;类似气缸失火时的抖动&#xff0c;又类似手动变速器…...

从0开始:OpenCV入门教程【图像处理基础】

图像处理基础 一、OpenCV主要功能及模块介绍 1、内置数据结构和输入/输出 OpenCV内置了丰富的与图像处理有关的数据结构&#xff0c;如Image、Point、Rectangle等。core模块实现了各种基本的数据结构。imgcodecs模块提供了图像文件的读写功能&#xff0c;用户使用简单的命令…...

区块链相关方法-SWOT分析

1.SWOT 一、定义:一种基于内外部竞争环境和竞争条件下的态势分析&#xff0c;通过对企业的内外环境所形成的优势&#xff08;Strengths&#xff09;、劣势&#xff08;Weaknesses&#xff09;、机会&#xff08;Opportunities&#xff09;和威胁&#xff08;Threats&#xff0…...

React 前端框架介绍

什么是 React? React 是一个由 Facebook 开发并维护的开源 JavaScript 库,用于构建用户界面。它主要用于创建交互式用户界Face(UI),尤其是当数据变化时需要更新部分视图时非常有效。React 的核心思想是组件化和声明性编程,这使得开发者可以轻松地创建、组合和重用代码。…...

linux串口通讯

在当今的科技世界中,串口通讯虽然不像一些新兴的高速通信技术那般夺目,但它依然在众多领域有着不可替代的地位,尤其是在嵌入式系统开发、工业自动化控制等场景。而 Linux 系统,凭借其开源、稳定且强大的特性,为串口通讯提供了出色的支持。 一、串口通讯基础 串口通讯,简…...

鸿蒙app 开发中 对于数组方法 filter 的理解

这段代码是 TypeScript 中数组 filter 方法的类型定义&#xff0c;下面将详细解释其各个部分的含义、作用及使用场景。 整体功能概述 filter 方法是 JavaScript 和 TypeScript 中数组对象的一个内置方法&#xff0c;它的主要功能是创建一个新数组&#xff0c;新数组中的元素是…...

黄金市场现状与驱动因素分析

一、当前市场现状&#xff1a;挤兑、运力与供应链危机 全球金库告急与运输瓶颈 伦敦商业银行金库的黄金存量告急&#xff0c;纽约和伦敦市场出现“史诗级挤兑”。提取英格兰银行金库的黄金需等待4-8周&#xff0c;远高于常规的几天时间[citation:用户描述]。专业运输车辆超负荷…...

Scrum方法论指导下的Deepseek R1医疗AI部署开发

一、引言 1.1 研究背景与意义 在当今数智化时代&#xff0c;软件开发方法论对于项目的成功实施起着举足轻重的作用。Scrum 作为一种广泛应用的敏捷开发方法论&#xff0c;以其迭代式开发、快速反馈和高效协作的特点&#xff0c;在软件开发领域占据了重要地位。自 20 世纪 90 …...

大学本科教务系统设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点

以下是大学本科教务系统的设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点: 大学本科教务系统设计方案 一、需求分析 1. 核心用户角色 角色功能需求学生选课/退课、成绩查询、课表查看、学分统计、考试报名、学业预警教师成绩录入、课程大纲上传、教学进度管理、…...

个人环境配置--安装记录

根据显卡下载对应的cuda和cudnn 我使用的是docker,首先拉取镜像,我用的是ubuntu20.04 加速&#xff1a;pull hub.1panel.dev/ devel是开发版本 sudo docker pull hub.1panel.dev/nvidia/cuda:11.6.1-devel-ubuntu20.04先测试一下cuda有没有安装好 nvcc -V更新&#xff0c;安装…...

win10把c盘docker虚拟硬盘映射迁移到别的磁盘

c盘空间本身就比较小、如果安装了docker服务后&#xff0c;安装的时候没选择其他硬盘&#xff0c;虚拟磁盘也在c盘会占用很大的空间&#xff0c;像我的就三十多个G&#xff0c;把它迁移到其他磁盘一下子节约几十G 1、先输入下面命令查看 docker 状态 wsl -l -v 2、如果没有停止…...

开源的 LLM 应用开发平台-Dify 部署和使用

加粗样式 Dify 简介 官网 http://difyai.com/ 生成式 AI 应用创新引擎 开源的 LLM 应用开发平台 Dify 为开发者提供了健全的应用模版和编排框架&#xff0c;你可以基于它们快速构建大型语言模型驱动的生成式 AI 应用&#xff0c;将创意变为现实&#xff0c;也可以随时按需无…...

PHP Libxml:深入解析XML解析库及其在PHP中的应用

PHP Libxml:深入解析XML解析库及其在PHP中的应用 引言 XML(可扩展标记语言)是一种用于存储和传输数据的标记语言,广泛应用于Web服务、数据交换等领域。PHP作为一种流行的服务器端脚本语言,提供了强大的XML处理能力。Libxml是PHP中用于处理XML数据的核心库,本文将深入解…...

libxls库的编译以及基于Visual studio的配置

最近有一个需求在windows处理xls&#xff0c;所以就需要libxls这个库&#xff0c;调查了一下&#xff0c;基于C的库的解析情况如下&#xff1a; 所以最理想的就是Libxlsd个开源的方案 基于历史整理的 libxls 在 MinGW 下的编译步骤 前提条件 系统&#xff1a;Windows&#…...

抗辐照加固CAN FD芯片的商业航天与车规级应用解析

在工业自动化、智能汽车、航空航天及国防装备等关键领域&#xff0c;数据传输的安全性、可靠性与极端环境适应能力是技术升级的核心挑战。国科安芯推出全新一代CANFD&#xff08;Controller Area Network Flexible Data Rate&#xff09;芯片&#xff0c;以高安全、高可靠、断电…...

Python教学-最常用的标准库之一——OS库

os 库是 Python 标准库中的一个模块&#xff0c;它提供了一种方便的方式来使用操作系统相关的功能。os 模块提供了很多函数&#xff0c;可以用来处理文件和目录、访问环境变量、执行系统命令等。以下是一些常用的 os 模块的功能和示例&#xff1a; 1. 文件和目录操作 1.1 当前…...

Ollama+Deepseek+AnythingLLM搭建本地知识库

OllamaDeepseek的配置可以参考OllamaDeepseekopen-webui搭建本地知识库-CSDN博客 一&#xff0c;AnythingLLM安装 AnythingLLM官网地址AnythingLLM | The all-in-one AI application for everyone 下载 win64 下载完毕后安装。 二&#xff0c;AnythingLLM 配置 新建工作区 …...

合并区间(56)

56. 合并区间 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:vector<vector<int>> merge(vector<vector<int>>& intervals) {if (intervals.size() 1) {return intervals;}//现根据每一项的第一个值&#…...