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

低价建设网站/推特是谁的公司

低价建设网站,推特是谁的公司,用axure做网站原型的尺寸,苏州网站建设公司电话Kafka 是一款高吞吐量、低延迟的分布式消息系统。本文将详细介绍如何在 Spring Boot 项目中使用 Kafka 进行消息接收与消费,并结合幂等和重试机制,确保消息消费的可靠性和系统的扩展性。我们将以电商交易系统为案例进行深入解析。 1. 系统架构概览 在电…

Kafka 是一款高吞吐量、低延迟的分布式消息系统。本文将详细介绍如何在 Spring Boot 项目中使用 Kafka 进行消息接收与消费,并结合幂等和重试机制,确保消息消费的可靠性和系统的扩展性。我们将以电商交易系统为案例进行深入解析。

1. 系统架构概览

在电商系统中,Kafka 常用于订单状态变更、库存变化等事件的异步处理。

+----------------+     Kafka      +----------------+
| 订单服务       |  ---> Produce ---> | 消费服务       |
| (Order Service)|     Topic      | (Consumer Service)|
+----------------+                +----------------+|                                  |MySQL                               MySQL

主要流程:

  1. 订单服务:接收用户订单请求后,异步将订单信息发送到 Kafka。
  2. 消费服务:从 Kafka 中消费订单信息,更新库存、生成发货信息等操作。
  3. 数据库:使用 MySQL 存储订单和库存数据,并通过 MyBatis 实现持久化操作。

2. Kafka 的基础介绍

Kafka 是一种基于发布-订阅模式的消息系统,支持高吞吐、分区与复制等机制,具备容错和可扩展的特点。它的主要组成部分有:

  • Producer(生产者):向 Kafka 的 Topic 发送消息。
  • Consumer(消费者):从 Kafka 的 Topic 读取消息。
  • Broker(代理):Kafka 的服务器集群。
  • Topic(主题):消息的分类单位。
  • Partition(分区):用于分布式处理消息。

3. 项目环境搭建

3.1 Maven 依赖

在 Spring Boot 项目中,我们通过 spring-kafka 提供对 Kafka 的集成。还需要引入 MyBatis 和 MySQL 相关依赖。

<dependencies><!-- Spring Boot Kafka --><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId></dependency><!-- MySQL Driver --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- MyBatis --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version></dependency><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Lombok (可选,用于简化代码) --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>
3.2 数据库表结构设计

为实现电商系统的消息接收与消费,以下是两个主要数据库表:订单表和消费记录表。

  • 订单表(orders:存储订单的基础信息。
  • 消费记录表(message_consume_record:记录消费过的消息,用于幂等校验。
CREATE TABLE orders (id BIGINT AUTO_INCREMENT PRIMARY KEY,order_no VARCHAR(64) NOT NULL,user_id BIGINT NOT NULL,total_price DECIMAL(10, 2) NOT NULL,status INT NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE message_consume_record (id BIGINT AUTO_INCREMENT PRIMARY KEY,message_key VARCHAR(64) NOT NULL UNIQUE,consumed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

4. Kafka 消息生产与接收实现

4.1 生产者配置

在 Spring Boot 中,我们可以通过 KafkaTemplate 发送消息。首先,在 application.yml 中配置 Kafka 的基础信息:

spring:kafka:bootstrap-servers: localhost:9092producer:retries: 3key-serializer: org.apache.kafka.common.serialization.StringSerializervalue-serializer: org.apache.kafka.common.serialization.StringSerializer

bootstrap-servers: 这是 Kafka 服务的地址,Kafka 集群通常由多个 Broker 组成,每个 Broker 提供消息的存储与转发功能。这里指定了本地的 Kafka 服务器(localhost:9092),如果有多个 Broker,可以用逗号分隔(例如:localhost:9092,localhost:9093)。

retries: 当消息发送失败时,生产者将重试发送的次数。这里配置了 3 次重试。这在网络不稳定或 Kafka 节点暂时不可用时非常有用,可以有效提高消息发送成功率。

key-serializer: 生产者发送的消息可以有一个键值对。key-serializer 用于将消息的键序列化为字节数组。这里使用了 StringSerializer,表示消息的键是字符串形式,序列化为字节后发送。

value-serializer: 类似于键,value-serializer 用于将消息的值序列化为字节数组。配置 StringSerializer 表示消息内容是字符串。

4.2 消息生产示例
@Service
public class OrderProducer {@Autowiredprivate KafkaTemplate<String, String> kafkaTemplate;public void sendOrderMessage(String orderId) {kafkaTemplate.send("order-topic", orderId);}
}

OrderService 中,用户提交订单后,可以将订单 ID 发送至 Kafka:

@Service
public class OrderService {@Autowiredprivate OrderProducer orderProducer;public void createOrder(OrderDTO order) {// 保存订单逻辑...orderProducer.sendOrderMessage(order.getOrderId());}
}

5. 消息消费实现

5.1 消费者配置

在消费者中,我们需要定义 @KafkaListener 注解监听 Kafka 主题,并从中接收消息。

spring:kafka:consumer:group-id: order-groupauto-offset-reset: earliestkey-deserializer: org.apache.kafka.common.serialization.StringDeserializervalue-deserializer: org.apache.kafka.common.serialization.StringDeserializer

group-id: 消费者组 ID。Kafka 允许多个消费者组监听同一个 Topic,每个消费者组可以独立消费消息。此处配置 order-group,意味着该消费者属于订单消费逻辑的消费者组。

auto-offset-reset: 指定消费者在没有初始偏移量(offset)或当前偏移量无效的情况下,从哪里开始读取消息。earliest 表示从最早的可用消息开始消费,这对于新启动的消费者非常有用,能够确保读取历史数据。

key-deserializer: 将接收到的消息键从字节数组反序列化为 Java 对象。这里配置 StringDeserializer,表示键是字符串。

value-deserializer: 类似于键的反序列化,value-deserializer 用于将消息内容反序列化为 Java 对象。配置 StringDeserializer,表示消息内容是字符串。

5.2 消息消费示例
@Service
public class OrderConsumer {@Autowiredprivate OrderService orderService;@KafkaListener(topics = "order-topic", groupId = "order-group")public void consumeOrder(String orderId) {orderService.processOrder(orderId);}
}

OrderService 中,处理接收到的订单消息:

@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Transactionalpublic void processOrder(String orderId) {// 根据订单 ID 更新订单状态、库存等操作Order order = orderMapper.findById(orderId);// 更新订单逻辑...}
}

6. 幂等性保证

Kafka 的消息消费可能会因为网络问题或其他故障导致重复消费,因此在消费消息时需要考虑幂等性。我们可以通过在数据库中存储每个消息的唯一标识来实现幂等。

6.1 幂等校验实现

在消费消息时,首先检查该消息是否已经被消费过:

@Service
public class OrderConsumer {@Autowiredprivate MessageConsumeRecordMapper consumeRecordMapper;@KafkaListener(topics = "order-topic", groupId = "order-group")public void consumeOrder(String orderId) {if (consumeRecordMapper.existsByMessageKey(orderId)) {// 如果已经处理过该消息,直接返回return;}// 处理订单orderService.processOrder(orderId);// 记录已处理消息consumeRecordMapper.insertConsumeRecord(orderId);}
}

MessageConsumeRecordMapper 接口用于操作消费记录表:

@Mapper
public interface MessageConsumeRecordMapper {boolean existsByMessageKey(String messageKey);void insertConsumeRecord(String messageKey);
}

通过这种方式,我们确保了每条消息只被消费一次,避免重复处理订单数据。


7. 重试机制实现

为了保证消息的可靠消费,可能会需要对消费失败的消息进行重试。Kafka 提供了自动重试机制,但在多次重试失败后,仍然可能需要手动处理。因此,我们可以通过将消费失败的消息保存至数据库,并定期进行重试的方式,实现可靠的消息处理。

7.1 消费失败记录表设计
CREATE TABLE failed_message (id BIGINT AUTO_INCREMENT PRIMARY KEY,message_key VARCHAR(64) NOT NULL,payload TEXT NOT NULL,failed_reason TEXT,retry_count INT DEFAULT 0,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
7.2 重试机制实现

在消费消息失败时,将消息记录到失败表中,并定期进行重试。

@Service
public class OrderConsumer {@Autowiredprivate FailedMessageMapper failedMessageMapper;@KafkaListener(topics = "order-topic", groupId = "order-group")public void consumeOrder(String orderId) {try {orderService.processOrder(orderId);} catch (Exception e) {failedMessageMapper.insertFailedMessage(orderId, e.getMessage());}}
}     

通过定时任务或手动触发,定期查询失败的消息并重新消费:

@Service
public class FailedMessageRetryService {@Autowiredprivate FailedMessageMapper failedMessageMapper;@Scheduled(fixedDelay = 60000)  // 每分钟重试一次public void retryFailedMessages() {List<FailedMessage> failedMessages = failedMessageMapper.findAll();for (FailedMessage message : failedMessages) {try {orderService.processOrder(message.getPayload());failedMessageMapper.deleteById(message.getId());} catch (Exception e) {failedMessageMapper.incrementRetryCount(message.getId());}}}
}

8. 扩展性设计

为了使系统具备良好的扩展性,我们需要考虑以下几个方面:

8.1 支持多种消息格式

除了支持 Kafka 消息,我们可以通过设计合理的接口结构,扩展系统支持其他消息队列或 HTTP 请求的接入。例如,通过创建统一的 MessageConsumer 接口,任何类型的消息都可以实现消费逻辑。

public interface MessageConsumer {void consume(String payload);
}@Service
public class KafkaOrderConsumer implements MessageConsumer {@Overridepublic void consume(String payload) {// Kafka 消息消费逻辑}
}

通过这种设计,可以轻松添加新的消息类型或处理逻辑,而不需要修改现有代码。

8.2 动态配置

为了增强系统的灵活性,系统可以支持通过数据库或配置文件动态调整消息消费逻辑。例如,可以在配置文件中定义不同业务的消费逻辑:

message-consumers:order:type: kafkatopic: order-topicuser:type: httpurl: http://example.com/user/message

通过读取这些配置,系统可以动态选择不同的消费逻辑,从而增强扩展性。


9. 性能优化

9.1 异步消费

为了提高消费速度,可以将消息的处理逻辑放入线程池中异步执行,从而避免阻塞 Kafka 消费的主线程。

@Async
public void processOrderAsync(String orderId) {orderService.processOrder(orderId);
}
9.2 批量消费

Kafka 支持批量消费消息,这样可以减少 Kafka 客户端与 Broker 之间的交互次数,提升性能。在 Spring Boot 中,可以通过配置 max.poll.records 参数控制每次批量消费的消息数量。

spring:kafka:consumer:max-poll-records: 500
9.3 分区与并行消费

通过为 Kafka 的 Topic 配置多个分区,并为消费者组中的消费者分配不同的分区,可以实现并行消费,从而提升系统的消费能力。

spring:kafka:consumer:concurrency: 3

10. Kafka 防止 MQ 队列堆积太多导致内存溢出问题

在实际的生产环境中,当消费速度低于消息的生产速度时,Kafka 消费者端的消息队列可能会出现堆积。如果消息堆积时间过长,会导致 Kafka 中的分区文件过大,甚至在消费者端可能造成内存溢出。因此,我们需要在架构设计中考虑如何有效防止消息堆积的问题。

以下是一些常见的应对策略:

10.1 提高消费速度

当 Kafka 的消费速度低于生产速度时,最直接的应对措施就是提升消费的速度:

  1. 并行消费:通过配置 Kafka 消费者的 concurrency 参数来增加消费者实例的数量。Kafka 使用分区来进行负载均衡,分区的数量决定了并发消费的能力。因此,增加分区数可以提升消费者的并发处理能力。
spring:kafka:consumer:concurrency: 3  # 配置多个消费者进行并行处理
  1. 批量消费:通过 max.poll.records 参数配置每次拉取的消息数量。增加批量消费可以减少 Kafka 消费者与 Broker 之间的交互,从而提升性能。
spring:kafka:consumer:max-poll-records: 500  # 每次批量拉取 500 条消息
10.2 优化消息处理逻辑

在消费端,消息的处理速度是决定 Kafka 消费效率的关键。因此,需要对消费逻辑进行优化:

  1. 异步处理:在消息处理完成后再返回响应,可能导致整个消费过程变慢。可以通过使用异步任务处理消息内容,从而避免阻塞 Kafka 消费的主线程。可以结合 Spring 的 @Async 注解实现异步处理。
@Async
public void processOrderAsync(String orderId) {// 异步处理订单消息orderService.processOrder(orderId);
}
  1. 缩短消息处理时间:简化业务逻辑,避免冗长的处理流程。使用缓存等方式减少对数据库的频繁访问,降低 I/O 操作带来的性能开销。
10.3 调整 Kafka 生产者端的速率

生产者端的消息发送速率直接影响消息的堆积情况。当消费端无法跟上生产端的速度时,适当限制生产者的消息发送速率是一个有效的策略:

  1. 限流机制:在生产者端通过限流策略,控制每秒钟向 Kafka 发送的消息数量,确保消费者有足够的时间处理消息。例如,可以使用 RateLimiter 实现限流。
RateLimiter rateLimiter = RateLimiter.create(1000); // 每秒最多发送 1000 条消息public void sendMessage(String topic, String message) {rateLimiter.acquire();  // 获取许可kafkaTemplate.send(topic, message);
}
  1. 分布式限流:如果消息的生产端部署在多个节点上,可以使用 Redis 等工具实现分布式限流。
10.4 设置合适的消费位移提交策略

Kafka 消费者有两种提交消费位移的方式:自动提交和手动提交。默认情况下,Kafka 会每隔一段时间自动提交消费位移。如果消费端发生异常,未能处理的消息在下次重新拉取时会再次被消费。为了避免消息重复消费,我们可以将消费位移的提交改为手动提交,确保消息处理完后再提交位移。

spring:kafka:consumer:enable-auto-commit: false  # 关闭自动提交位移

手动提交消费位移:

try {// 消费处理消息processMessage(record);// 手动提交位移acknowledgment.acknowledge();
} catch (Exception e) {// 处理异常
}
10.5 配置 Kafka 消息保留策略

如果消息堆积严重,可以通过 Kafka 的 retention.ms 参数设置消息的存储时间,确保超过存储时间的消息自动删除,防止 Kafka 分区文件无限制增长。

log.retention.ms=604800000  # 配置 Kafka 日志文件的保留时间,单位为毫秒,这里设置为 7 天

此外,可以通过配置 log.retention.bytes 来限制 Kafka 每个分区的日志文件大小,确保超出大小限制后自动删除最早的消息。

log.retention.bytes=1073741824  # 配置 Kafka 分区日志文件的最大大小,单位为字节,这里设置为 1 GB
10.6 使用 Kafka 消息压缩

对于大数据量的消息,可以启用 Kafka 消息压缩功能,减少消息的占用空间,从而提升生产和消费的效率。Kafka 支持多种压缩算法,包括 GZIP、LZ4 和 SNAPPY。

spring:kafka:producer:compression-type: gzip  # 启用 GZIP 压缩

压缩不仅可以减少网络传输的数据量,还可以降低 Kafka Broker 和消费端的存储压力,从而减少消息堆积的可能性。

相关文章:

Spring Boot 应用Kafka讲解和案例示范

Kafka 是一款高吞吐量、低延迟的分布式消息系统。本文将详细介绍如何在 Spring Boot 项目中使用 Kafka 进行消息接收与消费&#xff0c;并结合幂等和重试机制&#xff0c;确保消息消费的可靠性和系统的扩展性。我们将以电商交易系统为案例进行深入解析。 1. 系统架构概览 在电…...

以到手价为核心的品牌电商价格监测

在当今竞争激烈的电商时代&#xff0c;品牌的价格监测至关重要。传统的页面价监测已无法满足品牌对渠道管控的需求&#xff0c;而到手价监测则成为品牌控价的关键所在。 力维网络&#xff0c;作为深耕数据监测服务多年的专业机构&#xff0c;拥有自主开发的数据监测系统&#…...

Android中使用RecyclerView制作横向轮播列表及索引点

在Android开发中&#xff0c;RecyclerView是一个非常强大的组件&#xff0c;用于展示列表数据。它不仅支持垂直滚动&#xff0c;还能通过配置不同的LayoutManager实现横向滚动&#xff0c;非常适合用于制作轮播图或横向列表。本文将详细介绍如何使用RecyclerView在Android应用中…...

Llama 3.1 技术研究报告-2

3.3 基础设施、扩展性和效率 我们描述了⽀持Llama 3 405B⼤规模预训练的硬件和基础设施&#xff0c;并讨论了⼏项优化措施&#xff0c;这些措施提⾼了训练效率。 3.3.1 训练基础设施 Llama 1和2模型在Meta的AI研究超级集群&#xff08;Lee和Sengupta&#xff0c;2022&#x…...

【深度学习】05-RNN循环神经网络-02- RNN循环神经网络的发展历史与演化趋势/LSTM/GRU/Transformer

RNN网络的发展历史与演化趋势 RNN&#xff08;Recurrent Neural Network&#xff0c;循环神经网络&#xff09;是一类用于处理序列数据的神经网络&#xff0c;特别擅长捕捉数据的时间或上下文依赖性。在其发展的过程中&#xff0c;不断出现各种改进和变体&#xff0c;以解决不…...

C++学习9.27

1、顺序表、栈、队列都更改成模板类 &#xff08;1&#xff09;顺序表 #include <iostream> #include <cstring>using namespace std;template <typename T1,typename T2,typename T3> class My_string { private:T1 *ptr; //指向字符数组的指针T2…...

【STM32开发环境搭建】-1-Keil(MDK) 5.27软件安装和注册教程

目录 1 安装前装备工作 2 安装KEIL(MDK-ARM) 5.27软件 3 注册KEIL(MDK-ARM) 5.27软件&#xff0c;获取License许可证 4 手动安装STM32F0&#xff0c;STM32F1&#xff0c;STM32F4&#xff0c;STM32F7&#xff0c;STM32H7的支持包 4.1 下载STM32的支持包 4.2 安装STM32的支…...

武汉正向科技格雷母线公司,无人天车系统,采用格雷母线定位技术

正向科技-格雷母线高精确定位技术-实操视频 高精度格雷母线内胆采用刚性内胆&#xff0c;基板采用精密度数控加工工艺&#xff0c;穿线卡采用高精度模具制作&#xff0c;不采用泡沫板填充&#xff0c;提高了地址检测精度和线性度。 最新一代的格雷母线定位技术特点是全数字化检…...

【保姆级教程】批量下载Pexels视频Python脚本(以HumanVid数据集为例)

目录 方案一&#xff1a;转换链接为download模式 方案二&#xff1a;获取源链接后下载 附录&#xff1a;HumanVid链接 方案一&#xff1a;转换链接为download模式 将下载链接的后缀加入 /download 然后用下面的脚本下载&#xff1a; import argparse import json import o…...

Python画笔案例-067 绘制配乐七角星

1、绘制橙子 通过 python 的turtle 库绘制 配乐七角星,如下图: 2、实现代码 绘制 配乐七角星 ,以下为实现代码: """配乐七角星.py本程序需要coloradd模块支持,安装方法:pip install coloradd""" import turtle from coloradd import color…...

Spark Job 对象 详解

在 Apache Spark 中&#xff0c;Job 对象是执行逻辑的核心组件之一&#xff0c;它代表了对一系列数据操作&#xff08;如 transformations 和 actions&#xff09;的提交。理解 Job 的本质和它在 Spark 中的运行机制&#xff0c;有助于深入理解 Spark 的任务调度、执行模型和容…...

C#中NModbus4中常用的方法

NModbus4 是一个用于 Modbus 协议通信的 C# 库&#xff0c;它支持串行 ASCII、RTU、TCP 和 UDP 协议。以下是 NModbus4 中常用的一些方法&#xff1a; 创建连接&#xff1a; ModbusSerialMaster.CreateRtu(SerialPort serialPort): 创建一个 RTU 串行连接。ModbusSerialMaster.…...

【Linux】线程同步与互斥

一、线程间互斥 1 .进程线程间的互斥相关概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源 临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区 互斥&#xff1a;任何时刻&#xff0c;互斥保证有且只有一个执行流进入临界…...

003、网关路由问题

1. nginx配置404跳转回默认路由 https://blog.csdn.net/masteryee/article/details/83689954 https://blog.csdn.net/IbcVue/article/details/133230460 https://www.jb51.net/server/317970ynk.htm https://blog.csdn.net/u014438244/article/details/120531287 https://blog…...

Eclipse 快捷键:提高开发效率的利器

Eclipse 快捷键&#xff1a;提高开发效率的利器 Eclipse 是一款广泛使用的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它为Java、C、PHP等编程语言提供了强大的开发支持。对于开发者来说&#xff0c;熟练掌握Eclipse的快捷键不仅能提高编码效率&#xff0c;还能减少…...

Agent智能体

Agent&#xff08;智能体&#xff09;是一个能够感知环境并采取行动的自主实体&#xff0c;通常被设计用于在特定的环境中执行任务。智能体可以通过学习、推理等方式来决策&#xff0c;目标是最大化某种效用或实现某个预定的目标。它们广泛应用于自动化系统、游戏AI、机器人、自…...

用Promise实现前端并发请求

/** * 构造假请求 */ async function request(url) {return new Promise((resolve) > {setTimeout(() > {resolve(url);},// Math.random() * 500 800,1000,);}); }请求一次&#xff0c;查看耗时&#xff0c;预计应该是1s&#xff1a; async function requestOnce() {c…...

通过队列实现栈

请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。int pop() 移除并返回栈顶元素。int to…...

Mac下可以平替paste的软件pastemate,在windows上也能用,还可以实现数据多端同步

Mac平台上非常经典的剪贴板管理工具&#xff1a;「Paste」。作为一款功能完善且易用的工具&#xff0c;「Paste」在实际使用中体现出了许多令人欣赏的特点。但是它是一个收费软件&#xff0c;一年至少要24美元. 现有一平替软件pastemate,功能更加丰富,使用更加方便。 下载地址…...

106. 从中序与后序遍历序列构造二叉树

文章目录 106. 从中序与后序遍历序列构造二叉树思路 105. 从前序与中序遍历序列构造二叉树思路 思考 106. 从中序与后序遍历序列构造二叉树 106. 从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和postorder&#xff0c;其中 inorder 是二叉树的中序遍历&#xff…...

监控和日志管理:深入了解Nagios、Zabbix和Prometheus

在现代IT运维中&#xff0c;监控和日志管理是确保系统稳定性和性能的关键环节。本文将介绍三种流行的监控工具&#xff1a;Nagios、Zabbix和Prometheus&#xff0c;帮助您了解它们的特点、使用场景以及如何进行基本配置。 一、Nagios Nagios 是一个强大的开源监控系统&#x…...

Win10下载Python:一步步指南

Win10下载Python&#xff1a;一步步指南 在Win10操作系统中下载并安装Python可能是一项挑战性的任务&#xff0c;但是在本文中&#xff0c;我们将向您提供三个不同的方法&#xff0c;以便轻松地完成这项任务。 方法一&#xff1a;使用Microsoft Store Microsoft Store是一个…...

Race Karts Pack 全管线 卡丁车赛车模型素材

是8辆高细节、可定制的赛车,内部有纹理。经过优化,可在手机游戏中使用。Unity车辆系统已实施-准备驾驶。 此套装包含8种不同的车辆,每种车辆有8-10种颜色变化,总共有75种车辆变化! 技术细节: -每辆卡丁车模型使用4种材料(车身、玻璃、车轮和BrakeFlare) 纹理大小: -车…...

C#——switch案例讲解

案例&#xff1a;根据输入的内容判断执行哪一条输出语句 string number txtUserName.Text; switch(number) { case"101":MessageBox.Show("您进入了101房间");break; case"102":MessageBox.Show("您进入了102房间");break; case&quo…...

技术美术一百问(02)

问题 前向渲染和延迟渲染的流程 前向渲染和延迟渲染的区别 G-Buffer是什么 前向渲染和延迟渲染各自擅长的方向总结 GPU pipeline是怎么样的 Tessellation的三个阶段 什么是图形渲染API? 常见的图形渲染API有哪些&#xff1f; 答案 1.前向渲染和延迟渲染的流程 【例图…...

12 函数的应用

函数的应用 一、Shell递归函数 ​ 函数优点&#xff1a; ​ 函数在程序设计中是一个非常重要的概念&#xff0c;它可以将程序划分成一个个功能相对独立的代码块&#xff0c;使代码的模块化更好&#xff0c;结构更加清晰&#xff0c;并可以有效地减少程序的代码量。 ​ 递归…...

鸿蒙开发(NEXT/API 12)【硬件(接入手写套件)】手写功能开发

接入手写套件后&#xff0c;可以在应用中创建手写功能界面。界面包括手写画布和笔刷工具栏两部分&#xff0c;手写画布部分支持手写笔和手指的书写效果绘制&#xff0c;笔刷工具栏部分提供多种笔刷和编辑工具&#xff0c;并支持对手写功能进行设置。接入手写套件后将自动开启一…...

基于python+flask+mysql的音频信息隐藏系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…...

18724 二叉树的遍历运算

### 思路 1. **递归构建树**&#xff1a; - 先序遍历的第一个节点是根节点。 - 在中序遍历中找到根节点的位置&#xff0c;左边部分是左子树&#xff0c;右边部分是右子树。 - 递归构建左子树和右子树。 2. **递归生成后序遍历**&#xff1a; - 递归生成左子树的…...

代理模式简介:静态代理VS与动态代理

代理模式&#xff1a;静态代理VS动态代理 1、定义2、分类2.1 静态代理2.2 动态代理 3、使用场景4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、定义 代理模式是一种设计模式&#xff0c;通过代理对象控制对目标对象的访问。简而…...