RabbitMQ消息队列 面试专题

csdn

RabbitMQ消息队列 面试专题

  • RabbitMQ的实现原理
  • 为什么需要消息队列
  • 常见消息队列比较
  • 如何保证消息不丢失
  • 如何防止消息重复消费
  • 如何保证消息的有序性
  • 如何处理消息堆积

RabbitMQ的实现原理

RabbitMQ 是一个基于 AMQP(Advanced Message Queuing Protocol) 协议实现的开源消息中间件,其核心设计围绕 消息路由、持久化、可靠性传输和高可用性 展开。以下是其核心实现原理的深度解析:

  • 核心架构模型
    RabbitMQ 基于 AMQP 的 生产者-消费者模型,关键组件包括:
组件作用
Producer(生产者)发送消息到 Exchange
Exchange(交换机)接收消息并根据规则(Binding Key)路由到指定队列
Queue(队列)存储消息的缓冲区,消息在此等待被消费
Consumer(消费者)从队列订阅并处理消息
Binding(绑定)定义 Exchange 和 Queue 之间的映射关系(基于 Routing Key)
Channel(信道)复用 TCP 连接的轻量级虚拟通道,减少资源消耗
Virtual Host(虚拟主机)逻辑隔离的多租户机制,类似命名空间

RabbitMQ

  • 消息路由机制
    RabbitMQ 的核心是 Exchange 如何将消息路由到队列,支持四种类型:

    • Direct Exchange(直连交换机)
      • 规则:精确匹配 Routing Key。
      • 场景:点对点精确投递。
      channel.queue_bind(queue="order_queue", exchange="orders", routing_key="order.create")
      
    • Topic Exchange(主题交换机)
      • 规则:通配符匹配(* 匹配一个词,# 匹配多个词)。
      • 场景:灵活的多播路由。
      channel.queue_bind(queue="logs", exchange="log_topic", routing_key="logs.*.error")
      
    • Fanout Exchange(扇出交换机)
      • 规则:广播到所有绑定队列,忽略 Routing Key。
      • 场景:发布/订阅模式。
      channel.queue_bind(queue="news_feed", exchange="news", routing_key="")
      
    • Headers Exchange(头交换机)
      • 规则:基于消息头的键值对匹配(而非 Routing Key)。
      • 场景:复杂属性匹配。
  • 消息存储与持久化
    RabbitMQ 通过 持久化机制 防止消息丢失:

    持久化对象配置方法
    Exchangechannel.exchange_declare(exchange=“orders”, exchange_type=“direct”, durable=True)
    Queuechannel.queue_declare(queue=“order_queue”, durable=True)
    Message设置 delivery_mode=2(消息属性中指定)
    • 存储引擎:使用 Erlang 的 Mnesia 数据库 存储元数据(Exchange、Queue、Binding),消息内容默认存储在内存,启用持久化后会写入磁盘。
    • 性能优化:通过 消息批处理(Batching)惰性队列(Lazy Queues) 减少磁盘 I/O 压力。
  • 可靠性传输

    • 生产者确认(Publisher Confirms)
      • 生产者开启 confirm 模式,Broker 在消息持久化后发送 basic.ack,失败时发送 basic.nack
      • 实现原理:通过 Erlang 的 gen_server 进程管理确认状态。
    • 消费者确认(Consumer Acknowledgements)
      • 消费者设置 auto_ack=false,处理完成后手动发送 basic.ack
      • 预取机制(Prefetch):通过 basic.qos 控制未确认消息的最大数量,防止消费者过载。
  • 高可用性设计

    • 集群模式
      • 普通集群:节点间同步元数据(Exchange、Queue 定义),但消息不跨节点复制。
      • 镜像队列(Mirrored Queues):消息在多个节点间镜像复制,配置策略示例:
    rabbitmqctl set_policy ha-all "^ha." '{"ha-mode":"all", "ha-sync-mode":"automatic"}'
    
  • 脑裂处理

    • 使用 仲裁机制(Quorum Queues)(RabbitMQ 3.8+)替代镜像队列,基于 Raft 协议保证数据一致性。
  • 流量控制

    • 背压机制(Back Pressure):当消费者处理速度过慢时,RabbitMQ 通过阻塞生产者的 TCP 连接施加背压。
    • 流控(Flow Control):基于内存和磁盘阈值自动限制消息接收速率。
  • 底层实现技术

    • Erlang/OTP:RabbitMQ 使用 Erlang 语言开发,利用其轻量级进程(每个 Connection 对应一个 Erlang 进程)和高并发特性。
    • Mnesia:分布式数据库存储元数据,支持事务和快速查询。
    • 协议解析:AMQP 协议帧解析通过二进制模式匹配高效实现。
  • 总结

    • 灵活的路由机制:通过 Exchange 类型和 Binding 规则实现消息的动态分发。
    • 持久化与可靠性:消息、队列、交换机的持久化 + 生产者/消费者双向确认。
    • 高可用架构:集群 + 镜像队列/仲裁队列保证服务连续性。
    • 高效资源管理:Channel 复用连接、Erlang 轻量级进程、背压控制。

为什么需要消息队列

消息队列(Message Queue)是一种在分布式系统中用于组件间通信的中间件技术,它通过异步、解耦、可靠传输等特性,解决了传统系统设计中的许多痛点。以下是消息队列的核心价值和应用场景:

  • 系统解耦
    • 问题:直接调用(如HTTP/RPC)会导致系统紧耦合,任一方的故障或升级都可能影响整体。
    • 解决方案:消息队列作为中间层,生产者与消费者无需知道彼此存在。
      • 示例:订单系统将订单消息发送到队列,库存系统、物流系统各自独立消费消息,即使某一系统宕机,其他系统仍可正常工作。
  • 异步处理
    • 问题:同步调用链路过长时,响应时间累积,用户体验差。
    • 解决方案:非关键操作异步化,提升主流程响应速度。
      • 示例:用户注册后,主流程仅写入数据库,发送验证邮件、短信通知等通过消息队列异步处理,用户无需等待。
  • 流量削峰
    • 问题:突发流量(如秒杀活动)可能压垮后端服务。
    • 解决方案:消息队列作为缓冲区,平滑流量冲击。
      • 示例:电商秒杀时,请求先写入队列,后端服务按最大处理能力逐步消费,避免服务器过载。
  • 数据可靠性
    • 问题:网络抖动或服务宕机可能导致数据丢失。
    • 解决方案:消息队列提供持久化、确认机制(ACK)、重试等保障。
      • 示例:支付结果通知失败时,消息队列自动重推,确保最终一致性(如RabbitMQ的ACK机制、Kafka的副本同步)。
  • 扩展性
    • 问题:系统规模扩大时,直接通信的架构难以水平扩展。
    • 解决方案:消息队列天然支持分布式架构,方便增减生产者或消费者。
      • 示例:日志收集场景中,多个服务向队列发送日志,消费者集群可动态扩容处理海量数据。
  • 数据流处理
    • 问题:实时数据分析、监控等场景需要低延迟处理流水数据。
    • 解决方案:消息队列与流处理框架(如Flink、Spark)结合,实现实时管道。
      • 示例:用户行为日志通过Kafka传输,实时计算集群分析后生成推荐结果。
  • 典型应用场景
    • 电商系统:订单处理、库存扣减、物流通知。
    • 金融支付:交易流水异步对账、通知推送。
    • 物联网:海量设备数据采集与分发。
    • 微服务架构:服务间通信、事件驱动设计(Event-Driven Architecture)。
  • 何时不需要消息队列?
    • 低复杂度系统:若系统简单,引入消息队列可能增加运维负担。
    • 强实时性需求:异步可能带来延迟,不适合毫秒级响应场景。
    • 数据一致性要求极高:需结合分布式事务(如Saga、TCC)解决一致性问题。
  • 总结
    消息队列通过解耦、异步、削峰、可靠传输等能力,成为分布式系统的“中枢神经”,尤其适用于高并发、多组件协作的场景。但其引入也需权衡复杂度,根据实际需求选择适合的队列类型(如RabbitMQ、Kafka、RocketMQ)。

常见消息队列比较

特性RabbitMQKafkaRocketMQActiveMQ
吞吐量中等(万级TPS)极高(百万级)高(十万级)低(万级)
延迟低(微秒级)高(毫秒级)中低(毫秒级)中(毫秒级)
可靠性高(ACK机制)高(副本同步)高(事务消息)中(依赖配置)
消息持久化支持长期存储支持支持
扩展性中等(垂直扩展)极强(水平)强(水平)
事务支持基础事务无(需外部实现)分布式事务JMS事务
典型场景企业级异步日志/流处理金融/电商传统企业应用

选型建议

  • 高吞吐 & 流处理:选Kafka(如日志采集、实时分析)。
  • 复杂路由 & 低延迟:选RabbitMQ(如订单系统、即时通知)。
  • 金融级事务 & 高可靠:选RocketMQ(如支付、交易系统)。
  • 传统企业集成:选ActiveMQ(简单场景,非高并发)。
    扩展知识:新兴队列
  • Pulsar:云原生设计,支持多租户、分层存储,适合混合云场景。
  • NATS:轻量级、极低延迟,适合物联网(IoT)和微服务通信。

如何保证消息不丢失

RabbitMQ 通过多层次的机制确保消息不丢失,涵盖生产者、Broker 和消费者三个环节。以下是详细的解决方案:

  • 生产者端:确保消息成功投递
    • 启用发布确认(Publisher Confirms)
      生产者将信道设置为 confirm 模式,消息成功写入 Broker 后,会收到异步确认(basic.ack)。若未收到确认(如网络故障),生产者需重发消息。
      channel.confirmSelect(); // 开启确认模式
      // 发送消息...
      channel.waitForConfirms(); // 等待Broker确认
      
    • 事务机制(慎用)
      通过 AMQP 事务(txSelect/txCommit)确保原子性,但性能较差,推荐使用确认模式。
    • 消息持久化标记
      发送消息时设置 deliveryMode=2,即使 Broker 重启,消息也不会丢失。
      AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().deliveryMode(2) // 持久化消息.build();
      channel.basicPublish(exchange, routingKey, props, message.getBytes());
      
  • Broker 端:持久化与高可用
    • 持久化交换机、队列和消息

      • 声明交换机时设置 durable=truechannel.exchangeDeclare(exchangeName, “direct”, true);
      • 声明队列时设置 durable=truechannel.queueDeclare(queueName, true, false, false, null);
      • 发送消息时设置 deliveryMode=2(见上文)。
    • 镜像队列(Mirrored Queues)
      在集群中配置镜像队列,确保消息在多个节点冗余存储。即使某节点故障,其他节点仍可提供服务。

      rabbitmqctl set_policy ha-all "^ha." '{"ha-mode":"all"}' # 将所有队列镜像到所有节点
      
  • 消费者端:可靠消费与手动确认
    • 关闭自动应答(AutoAck=false)
      消费者手动发送确认(ACK),确保消息处理完成后才通知 Broker 删除消息。
      channel.basicConsume(queueName, false, consumer); // 关闭自动ACK
      // 处理消息后手动确认
      channel.basicAck(deliveryTag, false);
      
    • 消费失败重试
      若处理失败,可发送 basicNack 或 basicReject 使消息重新入队,或延迟后重试。
      channel.basicNack(deliveryTag, false, true); // 重新放回队列
      
  • 其他增强措施
    • 监控与告警
      使用 RabbitMQ Management 插件或 Prometheus 监控消息堆积、节点状态,及时发现问题。
    • 网络与故障恢复
      配置合理的超时和重试机制,避免因短暂网络抖动导致消息丢失。
    • 幂等性设计
      消费者处理消息时需支持幂等,避免因重复投递(如生产者重试)导致数据不一致。

如何防止消息重复消费

在 RabbitMQ 中,消息重复消费通常是由于网络问题、消费者故障或消息确认机制未正确处理导致的。RabbitMQ 本身不提供直接解决重复消费的机制,但可以通过以下方法实现防重:

  • 幂等性设计(核心方案)

    • 实现方式:
      • 唯一业务标识符:每条消息携带唯一 ID(如 UUID),消费者处理前检查该 ID 是否已执行。

      • 数据库去重:在业务表中记录已处理的消息 ID,通过唯一索引或 INSERT … ON CONFLICT DO NOTHING 避免重复。

      • Redis 防重:用 Redis 的 SETNX(key 为消息 ID)记录处理状态,设置合理过期时间。

      • 乐观锁:更新数据时通过版本号或条件判断(如 UPDATE table SET status = ‘done’ WHERE status = ‘pending’)。

        -- 示例:数据库去重表
        CREATE TABLE processed_messages (id VARCHAR(255) PRIMARY KEY,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        );
        
  • 手动确认机制(ACK)
    合理配置 RabbitMQ 的消息确认机制,避免因未正确 ACK 导致消息重新入队。

    • 步骤
      • 消费者处理完业务逻辑后,手动发送 basic_ack 确认消息。
      • 若处理失败,发送 basic_nackbasic_reject 拒绝消息,并选择是否重新入队(requeue=false 时消息进入死信队列)。
    • 注意:确保 ACK 前业务逻辑已完成,避免程序崩溃导致消息丢失。
      // 示例:Java 客户端手动 ACK
      channel.basicConsume(queueName, false, (consumerTag, delivery) -> {try {// 处理业务逻辑processMessage(delivery.getBody());// 成功则手动 ACKchannel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);} catch (Exception e) {// 失败则 NACK(不重新入队)channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, false);}
      });
      
  • 消息全局唯一 ID
    在生产者端为每条消息生成唯一标识符,消费者通过该 ID 判断是否重复。

  • 生产者示例:

    import uuid
    message = {"msg_id": str(uuid.uuid4()),"data": "your_payload"
    }
    channel.basic_publish(exchange='exchange',routing_key='routing_key',body=json.dumps(message),properties=pika.BasicProperties(delivery_mode=2)  # 持久化消息
    )
    
  • 死信队列(DLX)与重试次数限制
    通过死信队列捕获多次处理失败的消息,避免无限重试。

    • 配置步骤
      • 定义正常队列并绑定死信交换机。
      • 设置消息的最大重试次数(通过 x-death 头信息计数)。
      • 达到重试上限后,消息转入死信队列进行人工干预或日志记录。
        // 创建队列时声明死信交换机
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", "dlx_exchange");
        args.put("x-max-retries", 3);  // 自定义重试次数
        channel.queueDeclare("normal_queue", true, false, false, args);
        
  • 分布式锁
    在并发场景下,使用分布式锁确保同一消息在同一时刻仅被一个消费者处理。

    • 工具:Redis RedLock、ZooKeeper 或数据库锁。
    • 示例(Redis)
      lock_key = f"message_lock:{message_id}"
      if redis.set(lock_key, 1, ex=60, nx=True):try:process_message(message)redis.delete(lock_key)except:redis.delete(lock_key)
      else:# 锁已被占用,放弃处理或重试
      

总结方案

  • 生产者端:为消息注入唯一 ID,确保消息可追踪。
  • 消费者端
    • 使用唯一 ID + 数据库/Redis 实现幂等性。
    • 正确配置手动 ACK,避免消息意外重新入队。
    • 结合死信队列限制重试次数。
  • 业务层:设计天然幂等的操作(如 SET 操作代替 INCREMENT)。

如何保证消息的有序性

RabbitMQ 默认不保证消息的全局有序性,但在特定场景和配置下可以实现有序性。以下是常见方法和注意事项:

  • 单生产者和单消费者
    • 原理:若只有一个生产者发送消息到队列,且队列仅有一个消费者(单线程处理),RabbitMQ 的 FIFO(先进先出)特性会保证消息顺序。
    • 限制:无法横向扩展消费者,性能受限。
  • 消息分组(Message Grouping)
    • 使用场景:需要多消费者但保证同一组消息有序。
    • 实现方式
      • 路由键分组:将需有序的消息通过相同路由键发送到同一队列(如按用户ID分组)。
      • 一致性哈希交换器:通过插件(如 rabbitmq-consistent-hash-exchange)将相同特征的消息路由到固定队列。
    • 示例:订单操作消息按订单ID哈希到特定队列,每个队列由独立消费者处理。
  • 消费者单线程处理
    • 预取限制(Prefetch):设置 prefetch_count=1,确保消费者一次只处理一条消息,避免并发导致的乱序。
      channel.basic_qos(prefetch_count=1)
      
    • 串行化处理:消费者内部使用单线程或队列机制按顺序处理消息。
  • 消息确认(ACK)机制
    • 顺序确认:消费者在处理完当前消息后发送ACK,再接收下一条消息。结合 prefetch_count=1 可防止消息堆积导致的乱序。
  • 业务层有序性控制
    • 版本号/序列号:消息中携带序列号,消费者按序号重新排序或拒绝乱序消息。
    • 数据库状态:通过数据库事务或状态机确保业务操作顺序,即使消息乱序也能正确处理。
  • 插件或外部系统
    • RabbitMQ 插件:如 rabbitmq-message-ordering 插件(需评估稳定性)。
    • 分布式锁:在处理关键消息时使用锁(如 Redis 锁),确保同一资源的消息串行处理。

注意事项

  • 性能与扩展性:有序性常以牺牲并发为代价,需权衡吞吐量和顺序需求。
  • 网络分区与故障:RabbitMQ 集群在分区时可能影响消息顺序,需设计容错机制。
  • 重试机制:消息重试可能导致乱序,需结合业务逻辑处理(如丢弃旧消息或重新入队)。

总结
RabbitMQ 的有序性需通过约束生产者、消费者、队列设计及业务逻辑共同实现。在分布式场景下,严格全局有序较难实现,通常采用分组有序或最终一致性方案。设计时应优先评估是否必需强顺序,避免过度设计。

如何处理消息堆积

针对 RabbitMQ 的消息堆积问题,可以从 预防堆积处理堆积 两个方向入手,以下分步骤说明解决方案:

  • 预防消息堆积
    • 提升消费者处理能力
      • 横向扩展(增加消费者)
        • 使用 Work Queue 模式,启动多个消费者实例并行处理消息。
        • 示例代码(Spring Boot 中配置消费者并发):
        @RabbitListener(queues = "myQueue", concurrency = "5-10") // 最小5,最大10个消费者
        public void handleMessage(String message) { ... }
        
      • 优化消费者逻辑
        • 减少单条消息处理耗时(如异步操作、避免阻塞调用)。
        • 使用批量消费(如 prefetchCount 调高 + 批量处理逻辑)。
    • 控制生产者速率
      • 限流机制
        • 在生产者端添加速率限制(如令牌桶算法)。
        • 使用 RabbitMQ 的 Publisher Confirms 确保消息可靠发送,避免盲目重试。
      • 流量削峰
        • 引入缓冲层(如 Redis、Kafka)暂存突发流量,平滑写入 RabbitMQ。
    • 队列配置优化
      • 设置队列长度限制
        • 定义队列最大长度,超出时丢弃旧消息或拒绝新消息。
        • 示例(声明队列时设置参数):
          args.put("x-max-length", 10000);  // 队列最多存10000条消息
          args.put("x-overflow", "reject-publish"); // 超出后拒绝新消息
          
      • 设置消息 TTL(过期时间)
        • 自动删除过期消息,避免堆积。
        • 示例:
          args.put("x-message-ttl", 60000); // 消息存活60秒
          
    • 使用惰性队列(Lazy Queues)
      • 将消息直接存储到磁盘,减少内存占用,避免内存爆满。
      • 声明队列时添加参数:
        args.put("x-queue-mode", "lazy");
        
    • 死信队列(DLX)处理异常消息
      • 将处理失败或超时的消息路由到死信队列,避免阻塞主队列。
      • 配置示例:
        args.put("x-dead-letter-exchange", "dlx.exchange");
        args.put("x-dead-letter-routing-key", "dlx.routingKey");
        
  • 处理已有消息堆积
    • 临时扩容消费者
      • 快速增加消费者实例或线程数,优先消化堆积消息。
      • 动态调整 prefetchCount(适当增大):
        spring:rabbitmq:listener:simple:prefetch: 100  # 每次从队列拉取100条消息
        
    • 消息转移与重分发
      • 使用 rabbitmqadmin 工具将堆积队列的消息转移到其他队列临时处理:
        rabbitmqadmin move messages source_queue="myQueue" target_queue="backupQueue" vhost="/"
        
      • 编写脚本重新发布消息(注意避免循环)。
    • 批量清理消息
      • 通过管理界面或 API 删除非关键消息:
        rabbitmqadmin purge queue name=myQueue
        
    • 降级处理
      • 抽样分析消息内容,丢弃非关键数据(如日志消息)。
  • 监控与预警
    • 监控指标:
      • 队列长度(rabbitmqctl list_queues)、消费者数量、消息吞吐速率。
    • 配置告警:
      • 使用 Prometheus + Grafana 或 RabbitMQ 插件(如 rabbitmq_prometheus)设置阈值告警。

总结方案对比

方案适用场景注意事项
增加消费者消费者处理能力不足确保系统资源(CPU/线程)充足
惰性队列内存敏感型场景,允许稍高延迟磁盘 I/O 可能成为瓶颈
消息 TTL允许消息过期可能丢失数据,需业务容忍
死信队列处理异常消息需额外监控死信队列
队列限流控制生产者速率可能增加生产者延迟

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

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

相关文章

【Hudi-SQL DDL创建表语法】

CREATE TABLE 命令功能 CREATE TABLE命令通过指定带有表属性的字段列表来创建Hudi Table。 命令格式 CREATE TABLE [ IF NOT EXISTS] [database_name.]table_name[ (columnTypeList)]USING hudi[ COMMENT table_comment ][ LOCATION location_path ][ OPTIONS (options_lis…

蓝桥杯备考:动态规划路径类DP之矩阵的最小路径和

如题&#xff0c;要求左上角到右下角的最短路径&#xff0c;我们还是老样子按顺序做 step1:确定状态表示 f[i][j]表示(1,1)到(i,j)的最短距离 step2 :推导状态表达方程 step3:确定填表顺序&#xff0c;应该是从上到下&#xff0c;从左到右 step4:初始化 step5 找结果&#…

【Maven】基于IDEA学习 Maven依赖 与 工程继承、聚合关系

文章目录 一、基于IDEA 进行Maven依赖管理1. 依赖管理概念2. Maven工程核心信息配置和解读&#xff08;GAVP&#xff09;3. Maven工程依赖管理配置依赖管理和依赖添加依赖版本统一提取和维护 4. 依赖范围5. Maven工程依赖下载失败错误解决6. Maven工程Build构建配置指定打包命名…

微信小程序注册组件

在微信小程序中注册组件分为自定义组件的创建和全局/局部注册&#xff0c;下面为你详细介绍具体步骤和示例。 自定义组件的创建 自定义组件由四个文件组成&#xff0c;分别是 .js&#xff08;脚本文件&#xff09;、.json&#xff08;配置文件&#xff09;、.wxml&#xff08…

贪心算法二

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是贪心算法&#xff0c;并且掌握贪心算法。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! >…

react中的fiber和初次渲染

源码中定义了不同类型节点的枚举值 组件类型 文本节点HTML标签节点函数组件类组件等等 src/react/packages/react-reconciler/src/ReactWorkTags.js export const FunctionComponent 0; export const ClassComponent 1; export const IndeterminateComponent 2; // Befo…

Wireshark的OSPF报文抓包和分析(单区域ospf实验)

一、OSPF的5种数据包和7种状态机制 数据包 Hello&#xff1a;发现、建立邻居&#xff08;邻接&#xff09;关系、维持、周期保活&#xff1b;存在全网唯一的RID&#xff0c;使用IP地址表示 DBD&#xff1a;本地的数据库的目录&#xff08;摘要&#xff09;&#xff0c;LSDB的…

前后分离文件上传案例,前端HTML,后端Net6开发的webapi(完整源代码)下载

文件上传功能在项目开发中非常实用&#xff0c;本案例前端用HTML页面的form表单实现&#xff0c;后端用Net6实现。 前后分离文件上传案例&#xff0c;前端HTML&#xff0c;后端Net6&#xff08;完整源代码&#xff09; 下载链接https://download.csdn.net/download/luckyext/9…

Linux之命令记录【一】

文章目录 前言几个重要的热键1.[Tab]按键2.[Ctrl]-c 按键3.[Ctrl]-d 按键4.[shift]{[PageUP]|[Page Down]}按键 线上求助&#xff08;查看帮助信息&#xff09;1. --help2.man page3.info page 用户身份1.su 基础指令1.date2.cal3.bc 系统字符集相关1.locale 文本编辑器1.nano …

Unity HDR颜色、基础颜色、强度强度、HDR面板Intensity之间的相互转换

目录 前言&#xff1a; 一、UnityHDR面板的规律 二、HDR与基础颜色转换&#xff0c;HDR强度获取&#xff0c;输入设置强度获取 1.基础色->HDR颜色 2.HDR颜色->基础色 3.获取HDR颜色在面板中的强度 4.获取HDR颜色在面板设置输入时的强度 前言&#xff1a; HDR&#…

T41LQ专为人工智能物联网(AIoT)应用设计,适用于智能安防、智能家居、机器视觉等领域 软硬件资料+样品测试

君正&#xff08;Ingenic&#xff09;T系列芯片涵盖多个型号&#xff0c;每个型号根据不同应用需求提供了多个版本。以下是各型号及其主要版本&#xff1a; 1. T23系列&#xff1a; T23N&#xff1a;标准版&#xff0c;适用于移动摄像机、安全监控、视频通话和视频分析等应用…

高频 SQL 50 题(基础版)| 高级字符串函数 / 正则表达式 / 子句:1667. 修复表中的名字、1527. 患某种疾病的患者、196. 删除重复的电子邮箱、176. 第二高的薪水、...

高级字符串函数 / 正则表达式 / 子句 1667. 修复表中的名字 题目链接&#xff1a;1667. 修复表中的名字 状态&#xff1a;学会了 思路&#xff1a; 要求修复名字&#xff08;首字母大写&#xff0c;其他字母小写&#xff09;&#xff0c;按顺序返回。 想法就是取出名字这一列&…

《异步江湖:XHR、Promise 与 Event Loop 的恩怨情仇》

XMLHttpRequest XMLHttpRequest&#xff08;简称 XHR&#xff09;是浏览器提供的一个 JavaScript 对象&#xff0c;用于在客户端和服务器之间发送 HTTP 请求。它是实现 AJAX&#xff08;Asynchronous JavaScript and XML&#xff09; 技术的核心工具&#xff0c;允许网页在不…

C++课程设计【宿舍管理查询软件】

宿舍管理查询软件 一、题目描述二、源码以及说明宿舍管理查询软件设计与实现1. 系统设计思路1.1 功能需求1.2 数据结构2. 系统实现3. 代码说明3.1 数据结构3.2 功能实现3.3 文件存储4. 示例运行输入输出5. 总结其他QT文章推荐一、题目描述 (一)问题描述 为宿舍管理人员编写一…

MWC 2025 | 移远通信推出AI智能无人零售解决方案,以“动态视觉+边缘计算”引领智能零售新潮流

在无人零售市场蓬勃发展的浪潮中&#xff0c;自动售货机正经历着从传统机械式操作向AI视觉技术的重大跨越。 移远通信作为全球领先的物联网整体解决方案供应商&#xff0c;精准把握行业趋势&#xff0c;在2025世界移动通信大会&#xff08;MWC&#xff09;上宣布推出全新AI智能…

C语言常用的头文件,include文件

常用头文件功能速览 1 &#xff0c;通用常用头文件 01. stdio.h——标准输入输出 02. stdlib.h——内存管理与分配、随机数、字符串转换 03. string.h——字符串处理 04. math.h——数学 05. time.h——时间和日期 06. ctype…

[MySQL初阶]MySQL(4)基本查询

标题&#xff1a;[MySQL初阶]MySQL&#xff08;4&#xff09;基本查询 水墨不写bug 文章目录 一. 数据表设计二、对数据表的操作1. Create 操作&#xff08;插入数据&#xff09;查看最近受影响的行数&#xff1a; 2. Retrieve 操作&#xff08;读取数据&#xff09;&#xff0…

小米智能音箱Pro搭载“超级小爱”,支持远程控车

大家好,今天我要给大家好好唠唠小米智能音箱Pro,尤其是它搭载的“超级小爱”,那功能可太强大了,还支持远程控车,真的是给我们的生活带来了超多便利和惊喜。 先来说说这小米智能音箱Pro的外观。它的设计非常简约时尚,整体造型方方正正,线条流畅,放在家里任何一个角落都…

react中的useContext--为什么使用(一)

React 的数据传递流程 在 React 中&#xff0c;数据传递通常是自上而下的&#xff0c;也就是父组件把数据通过 props 传递给子组件&#xff0c;子组件无法直接修改父组件的数据。 例子&#xff1a;父组件向子组件传递数据 const Parent () > {const user { name: &quo…

如何使用 LLM 生成的术语自动在搜索应用程序上构建 autocomplete 功能

作者&#xff1a;来自 Elastic Michael Supangkat 了解如何在 Elastic Cloud 中&#xff0c;通过使用 LLM 生成的词汇&#xff0c;为搜索应用增强自动补全功能&#xff0c;实现更智能、更动态的搜索建议。 自动补全是搜索应用中的一项关键功能&#xff0c;它通过在用户输入时实…