网站维护开发合同/360广告投放平台

网站维护开发合同,360广告投放平台,邢台企业做网站价格,中国焊接外包加工网一、引言 在分布式系统中,传统的 REST 调用模式往往导致耦合,难以满足高并发和异步解耦的需求。消息驱动架构(EDA, Event-Driven Architecture)通过异步通信、事件溯源等模式,提高了系统的扩展性与可观测性。 作为 S…

一、引言

在分布式系统中,传统的 REST 调用模式往往导致耦合,难以满足高并发和异步解耦的需求。消息驱动架构(EDA, Event-Driven Architecture)通过异步通信、事件溯源等模式,提高了系统的扩展性与可观测性。

作为 Spring Cloud 生态的一部分,Spring Cloud Stream 抽象了不同消息中间件(如 Kafka、RabbitMQ)的底层差异,提供统一的编程模型,从而简化了微服务间的事件交互。本文将结合理论与实例,探讨 Spring Cloud Stream 的核心价值,具体包括:

• 高效解耦:通过声明式通道和 Binder 抽象,屏蔽底层中间件的复杂性。

• 状态可溯:通过事件日志驱动业务状态,确保数据一致性。

• 生产就绪:通过容错机制与治理策略,支持高可靠系统的落地。

二、消息驱动微服务模型

2.1 Spring Cloud Stream 架构与核心组件

Spring Cloud Stream 是 Spring Cloud 生态中消息中间件的抽象层,通过统一的编程模型屏蔽 Kafka、RabbitMQ 等中间件的实现差异,实现跨平台消息交互。

核心组件:

• Binder

作用:对接具体消息中间件(如 Kafka、RabbitMQ),提供统一的 API。

价值:开发者无需关注底层协议(如 AMQP、Kafka Protocol),通过配置切换中间件。

• Binding

作用:定义消息通道与中间件物理目标(如 Topic、Queue)的绑定规则。

配置示例:

spring.cloud.stream.bindings.outputChannel.destination=orders

• Message Channel

编程接口:通过@Input、@Output注解声明输入/输出通道。

示例:

public interface OrderChannels {  @Output("order-events") MessageChannel orderOutput();  
}

设计原则:

• 开箱即用:自动配置连接工厂、序列化器等基础设施。

• 扩展性:支持自定义 Binder 实现(如阿里云 RocketMQ)。

2.2 完整的消息驱动示例

生产者发送流程
在这里插入图片描述

消费者监听流程
在这里插入图片描述

完整代码结构参考

生产者项目
├── src/main/java
│   ├── com/example/producer
│   │   ├── MessageProducer.java
│   │   └── MyMessageChannels.java
│   └── resources/application.yml消费者项目
├── src/main/java
│   ├── com/example/consumer
│   │   ├── MessageConsumer.java
│   │   └── MyMessageChannels.java
│   └── resources/application.yml

完整示例步骤如下:

第1步:创建 Spring Boot 项目

使用 Spring Initializr 创建项目,选择依赖:

• 生产者项目:Spring Web,Spring Cloud Stream,Lombok

• 消费者项目:Spring Cloud Stream,Lombok

• 中间件支持:根据实际选择配置RabbitMQ或Kafka,本示例以RabbitMQ为例。

生成项目,下载并解压项目,相关依赖都在pom.xml中。

消费者项目中核心依赖示例:

<dependencies><!-- Web支持(用于创建REST接口) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 消息驱动核心 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream</artifactId></dependency><!-- 选择其中一个中间件依赖 --><!-- RabbitMQ --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream-binder-rabbit</artifactId></dependency><!-- 或 Kafka --><!--<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream-binder-kafka</artifactId></dependency>--><!-- 代码简化工具 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>

第2步:定义消息通道接口(生产者 & 消费者共用)

在两个项目的src/main/java下创建消息通道接口文件:

定义输出通道方法和输入通道方法。

public interface MyMessageChannels {//定义消息发送通道@Output("outputChannel")  // 指定通道名称为 "outputChannel"MessageChannel outputChannel(); // 方法名也是 outputChannel(推荐但不强制)//定义消息接收通道@Input("inputChannel")     // 指定通道名称为 "inputChannel"SubscribableChannel inputChannel(); // 方法名也是 inputChannel
}

注解解析:

• @Output(“outputChannel”):定义输出通道,用于消息生产者向outputChannel 通道发送消息。

• @Input(“inputChannel”):定于输入通道,用于消息消费者从inputChannel通道读取消息。

注解名称解析:

注解名称”outputChannel “ 与方法名(outputChannel)一致,是最佳实践,代码清晰易读。

如果修改方法名(但保持注解名称不变),代码依然有效。

情况1:通道名称以注解中的值为主,方法名可随意。

@Output("myCustomOutput") // 通道名称是 "myCustomOutput"
MessageChannel anyMethodName(); // 方法名随意

情况2:注解未指定名称,则通道名称默认取方法名(此时方法名必须有意义)。

@Output // 未指定名称,通道名称自动取方法名 "outputChannel"
MessageChannel outputChannel(); 

配置绑定的关键点

在配置文件(如 application.yml)中,绑定的是 注解中定义的通道名称,而不是方法名。具体可见下文 第5步示例。

第3步:实现消息生产者

在生产者项目中,创建控制器:

// MessageProducer.java
@RestController
@RequiredArgsConstructor
public class MessageProducer {// 自动注入通道private final MyMessageChannels channels;// 处理POST请求:/send?message=内容@PostMapping("/send")public String sendMessage(@RequestParam String message) {// 发送消息到outputChannel:// 1. channels.outputChannel() 获取输出通道对象// 2. MessageBuilder构建消息对象,withPayload设置消息内容// 3. 调用send()将消息发送到消息中间件channels.outputChannel().send(MessageBuilder.withPayload(message).build());//返回响应结果return "Message sent: " + message;}
}

注解解析:

@RestController:相当于@Controller + @ResponseBody。

• 表明该类是一个处理 Web 请求的控制器,其方法的返回数据会直接作为响应内容(非视图页面)。

@RequiredArgsConstructor:Lombok 注解。

• 自动生成构造器,用于注入final修饰的字段(例如:channels)。

代码解析:

• channels.outputChannel().send():将消息发送到outputChannel,RabbitMQ会将其存入主题(Topic)。

• MessageBuilder.withPayload(message).build():创建消息对象,将字符串message作为负载。

第4步:实现消息消费者

在消费者项目中,创建消息监听器:

@Service
@EnableBinding(MyMessageChannels.class) // 绑定消息通道
public class MessageConsumer {@StreamListener("inputChannel")public void handle(String message) {System.out.println("Received: " + message); // 消费并打印消息}
}

解析:
• @EnableBinding(MyMessageChannels.class):声明并绑定应用的消息通道,使 Spring Cloud Stream 自动配置与消息代理(如 Kafka/RabbitMQ)的连接。该注解仅负责通道的注册。
• 消息的接收与处理由@StreamListener或@RabbitListener等注解实现。
• @StreamListener(“inputChannel”):监听inputChannel,当有消息到达时触发handle方法。

第5步:配置绑定(关键步骤)
生产者配置文件

在生产者项目的src/main/resources/application.yml中添加如下配置:

spring:cloud:stream:bindings:outputChannel-out-0:  # 对应注解中的名称,@Output("outputChannel")destination: demo-queue  # 消息队列名称(RabbitMQ 自动创建)# 如果使用 RabbitMQ,需配置连接信息(默认连本地)rabbit:bindings:outputChannel-out-0:producer:exchangeType: direct  # 交换机类型

消费者配置文件

spring:cloud:stream:bindings:inputChannel-in-0:    # 对应注解中的名称@Input("inputChannel")destination: demo-queue  # 必须与生产者的destination一致group: my-group     # 消费者组(RabbitMQ中可选,Kafka必填)# RabbitMQ 连接配置(与生产者一致)rabbit:bindings:inputChannel-in-0:consumer:exchangeType: directdurableSubscription: true  # 持久化订阅

第6步:运行与测试

1、 启动 RabbitMQ

本地安装 RabbitMQ或使用 Docker:

docker run -d -p 5672:5672 -p 15672:15672 rabbitmq:management

2、启动生产者应用

• 访问http://localhost:8080/send?message=Hello

• 预期响应:Message sent: Hello

3、启动消费者应用

• 控制台输出:[消费者] 收到消息:Hello

4、验证队列

• 访问RabbitMQ 管理界面:http://localhost:15672

• 查看Queues标签页,确认demo-queue.my-group队列已创建。

• 检查消息是否被消费(队列中的消息数应为 0)。

2.3 常见问题自查表
在这里插入图片描述

三、事件溯源与消息驱动的架构融合

3.1 事件溯源(Event Sourcing)模型

事件溯源是一种以不可变事件流为核心的数据持久化模式。所有系统状态变更均以事件(Event)形式按顺序记录在事件日志(Event Log)中,而非直接修改当前状态。每个事件代表一次原子性操作(如订单创建、账户扣款),通过事件回放可重建任意时间点的系统状态。

核心特性:

• 不可变性:事件一旦存储,不可修改或删除。

• 顺序性:事件按时间顺序持久化,形成完整的操作历史。

• 唯一事实源:系统的当前状态完全由事件日志推导得出。

类比:

• 传统数据库:直接覆盖银行账户余额(如余额从 1000 → 800,无法追溯原因)。

• 事件溯源:记录每笔交易事件(如“存款 +200”“转账 -400”),通过事件回放计算当前余额(1000 + 200 - 400 = 800)。

3.2 核心优势与应用场景
在这里插入图片描述

3.3 事件溯源与CQRS的协同设计

CQRS(命令查询职责分离)

核心思想:将系统的写操作(Command)与读操作(Query)分离,独立优化。

与事件溯源的协同

• 写模型(Command Side)

职责:生成事件并持久化到事件日志(如 Kafka)。

示例:创建订单时发布OrderCreatedEvent,而非直接更新数据库。

• 读模型(Query Side)

职责:从优化的读存储(如 Redis、Elasticsearch)获取数据。

示例:查询订单状态时直接从缓存读取,避免复杂的 JOIN 查询。

技术价值

• 性能优化:读写分离避免数据库锁竞争,提升吞吐量。

• 架构灵活性:读模型可针对业务需求独立扩展(如全文检索、聚合统计)。

3.4 Spring Cloud Stream 在事件驱动架构中的实践

核心作用:

作为事件驱动架构的传输层,Spring Cloud Stream 实现以下关键能力:

能力1:事件传输管道(事件分发与路由)

生产者:通过@Output通道发布事件,推送事件至消息代理(如 Kafka)。

消费者:通过@Input通道订阅事件,支持条件路由(如基于消息头过滤)。

示例场景:订单服务发布OrderCreatedEvent,库存服务、支付服务分别订阅并处理。

能力2:读写分离(CQRS)实现

写模型:生成事件并持久化至事件日志(如 Kafka)。

@RestController  
public class OrderController {  @PostMapping("/orders")  public void createOrder() {  channels.orderOutput().send(MessageBuilder.withPayload(event).build());  }  
}

读模型:监听事件更新物化视图(如 Redis 缓存)。

@StreamListener("order-events")  
public void updateOrderView(OrderCreatedEvent event) {  redisTemplate.opsForValue().set(event.getOrderId(), event);  
}

能力3:可靠性保障

• 顺序性:通过分区键(如orderId)保证同一实体事件顺序处理。

• 幂等性:结合 Redis 防重机制(见 4.2 节)。

• 容错:集成死信队列(DLQ)隔离异常消息(见 4.1 节)。

3.5 事件存储选型与全链路协作

事件存储模式选择
在这里插入图片描述

从事件生成到存储到消费的完整协作过程

sequenceDiagramparticipant CommandService as 命令服务(写模型)participant Kafka as 消息代理(Kafka)participant EventStore as 事件存储(数据库)participant QueryService as 查询服务(读模型)participant ReadDB as 读数据库(Redis)CommandService->>Kafka: 发送OrderCreatedEventKafka->>EventStore: 持久化事件日志Kafka->>QueryService: 推送事件QueryService->>ReadDB: 更新读模型(物化视图)QueryService-->>Client: 响应查询请求

核心角色:

• 命令服务(生产者):生成事件并发送到消息代理。

• 消息代理(如 Kafka):作为事件传输通道,负责分发事件。

• 事件存储(如 MongoDB):持久化事件日志,支持回放与查询。

• 查询服务(消费者):监听事件并更新读模型(如 Redis 缓存)。

3.6 事件溯源完整示例 (订单系统为例)

1)定义事件对象(核心数据结构)

@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderCreatedEvent {private String orderId;    // 订单唯一标识private String product;    // 商品名称private int quantity;      // 购买数量
}

解析:

• OrderCreatedEvent:订单创建事件,包含orderId、product、quantity。

• @Data:Lombok 注解,自动生成类的所有 getter、setter等 方法。

• @AllArgsConstructor:Lombok 注解,自动生成一个包含所有字段的构造器。

• @NoArgsConstructor:Lombok 注解,自动生成一个无参构造器。

2)事件生产者(写模型:生成事件)

相关 MyMessageChannels 定义参见第二章2.2示例代码。

@RestController
@RequiredArgsConstructor
public class OrderController {private final MyMessageChannels channels; // 消息通道接口// 创建订单并发送事件@PostMapping("/createOrder")public String createOrder(@RequestParam String product, @RequestParam int quantity) {OrderCreatedEvent event = new OrderCreatedEvent(UUID.randomUUID().toString(), // 生成唯一订单IDproduct, quantity);// 发送事件到消息通道channels.outputChannel().send(MessageBuilder.withPayload(event).build());return "Order Created: " + event;}
}

解析:

• 生产者通过 HTTP 接口接收请求,构造OrderCreatedEvent事件,并发送到 Kafka 事件流(outputChannel)进行异步处理。

3)事件存储(持久化事件日志)
事件消费者(Event Store Service)

@EnableBinding(MyMessageChannels.class) // 绑定消息通道
public class EventStore {@StreamListener("inputChannel")public void storeEvent(OrderCreatedEvent event) {System.out.println("Storing Event: " + event);saveEventToDatabase(event); // 模拟事件存储}private void saveEventToDatabase(OrderCreatedEvent event) {// 实际场景:事件应存入数据库(如MySQL、MongoDB)}
}

解析:

• 消费者监听消息通道inputChannel的OrderCreatedEvent并存储,实现事件溯源。

• 事件存入数据库(如 MySQL、MongoDB),以支持历史回放和查询。

4)事件查询(读模型)

CQRS 模式下,读模型典型实现:

@RestController
@RequiredArgsConstructor
public class OrderQueryController {private final OrderRepository orderRepository; // 读数据库(如Redis)// 查询订单信息@GetMapping("/orders/{orderId}")public OrderView getOrder(@PathVariable String orderId) {return orderRepository.findById(orderId).orElseThrow(() -> new OrderNotFoundException("Order Not Found"));}
}

解析:

• OrderView存储在读数据库(如 Redis/Elasticsearch),保证高效查询。

• 采用事件驱动更新,每次OrderCreatedEvent发生时,通过监听事件更新OrderView读模型(如订单创建后更新 Redis 缓存)。

3.7 常见问题解答

Q1:事件存储和传统数据库有什么区别?

• 事件存储:仅追加(append-only)不可修改的事件日志,记录“发生了什么”。

• 传统数据库:直接修改当前状态,记录“现在是什么”。

Q2:CQRS 会增加系统复杂度吗?

• 初期:需要维护读写两套逻辑,有一定学习成本。

• 长期:提升扩展性和性能,适合高并发场景。

Q3:如何保证事件顺序?

• Kafka:通过分区键(如订单 ID)确保同一实体的事件顺序处理。

• 数据库:使用递增版本号或时间戳排序。

总结
事件溯源与消息驱动架构,通过不可变事件流与读写分离重塑了系统设计。

1.事件溯源:以事件日志为唯一事实源,支持历史回溯与状态重建,保障数据可靠性与审计能力。

2.CQRS协同:解耦命令与查询,写模型生成事件流,读模型通过缓存或搜索引擎优化响应效率。

3.消息驱动:基于Spring Cloud Stream实现异步事件传输,服务间解耦,适配高并发与分布式场景。

核心价值

• 技术侧:提升吞吐量、扩展性与容错能力。

• 业务侧:满足高频交易(如电商、金融)的合规需求,支持复杂业务链路追踪。

适用场景:适用于需高可靠性、实时响应及跨服务协作的系统,如:订单管理、实时计费等。

四、生产级消息治理

4.1 死信队列(DLQ)容错机制

死信队列(Dead Letter Queue, DLQ)

死信队列是消息系统中用于存储无法正常消费的消息的特殊队列。当消息因异常(如处理失败、超时、格式错误)无法被消费者正确处理时,系统自动将其转移到 DLQ,避免消息丢失或无限重试阻塞系统。

1.核心作用

• 容错处理:隔离异常消息,防止主业务队列被“毒丸消息”(Poison Pill)阻塞。

• 问题排查:集中存储失败消息,便于后续人工或自动分析原因。

• 重试机制:支持手动或自动从 DLQ 重新投递消息到主队列进行重试。

2.配置示例

在消费者应用程序的application.yml 中配置,定义消费失败的信息处理方法。

spring:  cloud:  stream:  bindings:  inputChannel:  consumer:  enable-dlq: true    # 启用死信队列  dlq-name: my-dlq    # 指定 DLQ 名称  

解析:

• enable-dlq: true:开启 DLQ 功能,默认将失败消息发送到名为.dlq的队列。

• dlq-name: my-dlq:指定 DLQ 名称,覆盖默认命名规则。

3.应用场景

在这里插入图片描述

4.注意事项

• 监控 DLQ 堆积:需集成监控工具(如 Prometheus)告警 DLQ 消息量,避免积压。

• 死信处理策略:

• 人工介入:分析日志,修复代码后重投递。

• 自动重试:配置规则(如延迟重试、错误类型过滤)。

• 结合重试机制:设置合理的重试次数(如 3 次)后再进入 DLQ,减少无效处理。

总结

死信队列是消息系统的“安全网”,通过隔离异常消息保障系统健壮性,是生产环境中不可或缺的容错机制。

4.2 幂等性设计(基于 Redis)

通过 Redis 原子操作实现消息消费的幂等性,确保消息仅被处理一次,避免重复消费导致的数据不一致问题。

1.代码示例

@Component  
@RequiredArgsConstructor  
public class IdempotentConsumer {  private final StringRedisTemplate redisTemplate;  @StreamListener("inputChannel")  public void processEvent(OrderCreatedEvent event) {  // 生成唯一事件标识(基于业务唯一键,如订单ID)  String eventId = "event:" + event.getOrderId();  // 原子性操作:尝试将事件ID存入Redis(仅当Key不存在时成功)  Boolean isNew = redisTemplate.opsForValue()  .setIfAbsent(eventId, "processed", Duration.ofMinutes(10));  if (Boolean.TRUE.equals(isNew)) {  // 首次处理事件(执行业务逻辑)  System.out.println("Processing event: " + event);  } else {  // 重复事件,跳过处理(记录日志或告警)  System.out.println("Duplicate event ignored: " + event);  }  }  
}  

核心设计解析:

在这里插入图片描述

2.生产级优化建议

异常处理:

• Redis 操作失败:捕获RedisConnectionFailureException,结合重试机制或死信队列(DLQ)处理。

• 业务逻辑异常:删除 Redis Key 并重试,或标记为需人工干预。

性能优化:

• 集群模式:使用 Redis Cluster 提升可用性与扩展性。

• 本地缓存:结合本地缓存(如 Caffeine)减少 Redis 访问频率。

监控与告警:

• Redis Key 堆积:监控 Key 数量与内存占用,设置阈值告警。

• 重复事件频率:统计重复事件日志,分析系统瓶颈或攻击行为。

3.适用场景

• 支付回调:防止重复扣款或到账。

• 订单状态更新:避免多次触发发货、库存扣减。

• 事件溯源:确保事件回放时数据一致性。

总结

通过 Redis 的原子操作与唯一键设计,实现轻量级分布式幂等性控制。此方案兼顾简洁性与可靠性,适用于多数高并发场景,是消息驱动架构中保障数据一致性的核心手段之一。

4.3 监控与告警

指标采集:集成Prometheus监控消息吞吐量、延迟与错误率。

可视化看板:通过Grafana展示实时数据,设置阈值触发告警(如 DLQ 堆积超限)。

五、总结

5.1 核心重点

• 消息驱动架构:@Input/@Output 定义通道,Binder 抽象层简化消息传递与异步解耦。

• 事件溯源与 CQRS:事件日志驱动状态回溯,读写分离优化性能,确保一致性。

• 生产级治理:死信队列容错、幂等性防重、监控告警保障稳定性。

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

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

相关文章

王者荣耀道具页面爬虫(json格式数据)

首先这个和英雄页面是不一样的&#xff0c;英雄页面的图片链接是直接放在源代码里面的&#xff0c;直接就可以请求到&#xff0c;但是这个源代码里面是没有的 虽然在检查页面能够搜索到&#xff0c;但是应该是动态加载的&#xff0c;源码中搜不到该链接 然后就去看看是不是某…

【一起来学kubernetes】12、k8s中的Endpoint详解

一、Endpoint的定义与作用二、Endpoint的创建与管理三、Endpoint的查看与组成四、EndpointSlice五、Endpoint的使用场景六、Endpoint与Service的关系1、定义与功能2、创建与管理3、关系与交互4、使用场景与特点 七、Endpoint的kubectl命令1. 查看Endpoint2. 创建Endpoint3. 编辑…

C# Enumerable类 之 集合操作

总目录 前言 在 C# 中&#xff0c;System.Linq.Enumerable 类是 LINQ&#xff08;Language Integrated Query&#xff09;的核心组成部分&#xff0c;它提供了一系列静态方法&#xff0c;用于操作实现了 IEnumerable 接口的集合。通过这些方法&#xff0c;我们可以轻松地对集合…

51c自动驾驶~合集54

我自己的原文哦~ https://blog.51cto.com/whaosoft/13517811 #Chameleon 快慢双系统&#xff01;清华&博世最新&#xff1a;无需训练即可解决复杂道路拓扑 在自动驾驶技术中&#xff0c;车道拓扑提取是实现无地图导航的核心任务之一。它要求系统不仅能检测出车道和交…

Spring Cloud Eureka - 高可用服务注册与发现解决方案

在微服务架构中&#xff0c;服务注册与发现是确保系统动态扩展和高效通信的关键。Eureka 作为 Spring Cloud 生态的核心组件&#xff0c;不仅提供去中心化的服务治理能力&#xff0c;还通过自我保护、健康检查等机制提升系统的稳定性&#xff0c;使其成为微服务架构中的重要支撑…

Unity屏幕适配——立项时设置

项目类型&#xff1a;2D游戏、竖屏、URP 其他类型&#xff0c;部分原理类似。 1、确定设计分辨率&#xff1a;750*1334 为什么是它&#xff1f; 因为它是 iphone8 的尺寸&#xff0c;宽高比适中。 方便后续适配到真机的 “更长屏” 或 “更宽屏” 2、在场景…

深度学习中LayerNorm与RMSNorm对比

LayerNorm不同于BatchNorm&#xff0c;其与batch大小无关&#xff0c;均值和方差 在 每个样本的特征维度 C 内计算&#xff0c; 适用于 变长输入&#xff08;如 NLP 任务中的 Transformer&#xff09; 详细的BatchNorm在之前的一篇文章进行了详细的介绍&#xff1a;深度学习中B…

使用WireShark解密https流量

概述 https协议是在http协议的基础上&#xff0c;使用TLS协议对http数据进行了加密&#xff0c;使得网络通信更加安全。一般情况下&#xff0c;使用WireShark抓取的https流量&#xff0c;数据都是加密的&#xff0c;无法直接查看。但是可以通过以下两种方法&#xff0c;解密抓…

Linux命令基础,创建,输入,输出,查看,查询

什么是命令、命令行 命令行&#xff1a;即&#xff1a;Linux终端&#xff08;Terminal&#xff09;&#xff0c;是一种命令提示符页面。以纯“字符”的形式操作操作系统&#xff0c;可以使用各种字符化命令对操作系统发出操作指令。 命令&#xff1a;即Linux程序。一个命令就…

【笔记】深度学习模型训练的 GPU 内存优化之旅:综述篇

开设此专题&#xff0c;目的一是梳理文献&#xff0c;目的二是分享知识。因为笔者读研期间的研究方向是单卡上的显存优化&#xff0c;所以最初思考的专题名称是“显存突围&#xff1a;深度学习模型训练的 GPU 内存优化之旅”&#xff0c;英文缩写是 “MLSys_GPU_Memory_Opt”。…

Vue 3 Diff 算法深度解析:与 Vue 2 双端比对对比

文章目录 1. 核心算法概述1.1 Vue 2 双端比对算法1.2 Vue 3 快速 Diff 算法 2. 算法复杂度分析2.1 时间复杂度对比2.2 空间复杂度对比 3. 核心实现解析3.1 Vue 2 双端比对代码3.2 Vue 3 快速 Diff 代码 4. 性能优化分析4.1 性能测试数据4.2 内存使用对比 5. 使用场景分析5.1 Vu…

神经网络的基本知识

感知机 输入&#xff1a;来自其他 n 个神经元传递过来的输入信号 处理&#xff1a;输入信号通过带权重的连接进行传递, 神经元接受到总输入值将与神经元的阈值进行比较 输出&#xff1a;通过激活函数的处理以得到输出 感知机由两层神经元组成, 输入层接受外界输入信号传递给…

C++相关基础概念之入门讲解(上)

1. 命名空间 C中的命名空间&#xff08;namespace&#xff09;是用来避免命名冲突问题的一种机制。通过将类、函数、变量等封装在命名空间中&#xff0c;可以避免不同部分的代码中出现相同名称的冲突。在C中&#xff0c;可以使用namespace关键字来定义命名空间。 然后我们在调…

网络协议栈

网络协议栈的位置 用户在应用层的各种请求最终会下达给操作系统&#xff0c;操作系统内除了进程管理、文件管理、内存管理、驱动管理之外&#xff0c;还有一个内嵌的软件协议栈&#xff0c;协议栈将用户的数据进行各种封包后&#xff0c;通过网卡将数据传递到网络当中&#xf…

C++之list类(超详细)

在上一节中我们学习了STL中的vector这个容器&#xff0c;这节我们来学习一下另外一个常用的容器——list。 文章目录 前言 一、list的介绍 二、list的使用及相关接口 1.list的使用 2.list的迭代器使用 3.list的相关接口 3.1 list capacity 3.2 list element access 3.3…

mysql、oracle、SQLserver之间的区别和优势

MySQL、Oracle和SQL Server都是常见的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它们在某些方面有一些区别和优势。 MySQL&#xff1a; MySQL是一种开源的RDBMS&#xff0c;由Oracle公司开发和维护。它具有快速、稳定和易于使用的特点。MySQL适用于中小型…

75.HarmonyOS NEXT ImageItemView组件深度剖析:手势交互与动画实现(二)

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT ImageItemView组件深度剖析&#xff1a;手势交互与动画实现(二) 一、手势系统架构 .gesture(GestureGroup(GestureMode.Exclusiv…

Qt 控件概述 QWdiget

Qt为我们提供了很多控件&#xff0c;这些控件拿过来就可以使用 目录 QWidget 属性 WindowFrame的影响 QWidget Qt中所有的组件都是继承自QWidget Qt Creator中的右侧可以看到QWidget的各种属性 其中各种属性都可以在Qt文档中找到说明 ​ 属性 enabled&#xff1a;描述该组…

适合企业内训的AI工具实操培训教程(37页PPT)(文末有下载方式)

详细资料请看本解读文章的最后内容。 资料解读&#xff1a;适合企业内训的 AI 工具实操培训教程 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;技术迅速发展&#xff0c;深度融入到各个领域&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;更是成…

Spring Boot对接twilio发送邮件信息

要在Spring Boot应用程序中对接Twilio发送邮件信息&#xff0c;您可以使用Twilio的SendGrid API。以下是一个简单的步骤指南&#xff0c;帮助您完成这一过程&#xff1a; 1. 创建Twilio账户并获取API密钥 注册一个Twilio账户&#xff08;如果您还没有的话&#xff09;。在Twi…