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

RabbitMQ 消息模式实战:从简单队列到复杂路由(二)

进阶探索:工作队列模式

工作队列模式剖析

工作队列模式,也被称为任务队列模式,是对简单队列模式的一种扩展和优化,旨在解决当任务量较大时,单个消费者无法快速处理所有任务的问题 。在工作队列模式中,依然有生产者负责生成并发送任务消息,但消费者不再是单一的个体,而是多个消费者共同协作。

其核心工作原理是负载均衡,生产者将大量的任务消息发送到同一个队列中,多个消费者同时监听这个队列。RabbitMQ 会按照一定的规则,将队列中的消息依次分发给各个消费者,确保每个消费者都能分配到任务,从而实现任务的并行处理 。这种模式下,消息的分发机制主要有轮询分发和公平分发两种。轮询分发是 RabbitMQ 的默认分发方式,它会将消息逐个发送到在序列中的下一个消费者,不考虑每个消费者处理任务的时长等因素,平均每个消费者获取相同数量的消息 。而公平分发则会根据消费者的处理能力进行任务分配,通过设置basicQos方法,限制每个消费者在同一时刻只能处理一条未确认的消息,在这个消费者确认消息之前,不会再发送下一条消息给它,从而将消息分配给下一个不忙的消费者,实现更合理的任务分配 。

实际应用场景

工作队列模式在实际业务中有着广泛的应用。以订单处理场景为例,在电商大促期间,订单量会瞬间暴增,如果仅依靠单个订单处理服务(即单个消费者)来处理这些订单,必然会导致处理速度缓慢,订单积压,严重影响用户体验。而采用工作队列模式,将订单消息发送到队列中,多个订单处理服务(多个消费者)从队列中获取订单消息并并行处理,能够大大提高订单处理的效率,快速响应用户的订单请求 。

在数据处理领域,比如日志分析场景。系统会产生大量的日志数据,需要对这些日志进行分析处理,提取有用的信息。可以将日志数据封装成消息发送到工作队列,多个日志分析服务(消费者)从队列中获取日志消息进行分析,从而实现高效的数据处理,快速得出分析结果,为系统的优化和决策提供支持 。

代码示例展示

下面通过 Java 代码来展示如何实现工作队列模式。假设我们有一个任务队列,生产者将任务消息发送到该队列,多个消费者从队列中获取任务并处理。

生产者代码如下:

 

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

public class Producer {

private final static String QUEUE_NAME = "work_queue";

public static void main(String[] argv) throws Exception {

ConnectionFactory factory = new ConnectionFactory();

factory.setHost("localhost");

try (Connection connection = factory.newConnection();

Channel channel = connection.createChannel()) {

channel.queueDeclare(QUEUE_NAME, false, false, false, null);

for (int i = 0; i < 10; i++) {

String message = "Task " + i;

channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));

System.out.println(" [x] Sent '" + message + "'");

}

}

}

}

在生产者代码中,我们创建了一个连接工厂ConnectionFactory,设置了 RabbitMQ 服务器地址为本地localhost。通过工厂创建连接Connection和通道Channel,声明了一个名为work_queue的队列。然后通过循环发送 10 条任务消息到队列中,每条消息的内容为 “Task + 序号” 。

消费者代码如下:

 

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

import com.rabbitmq.client.DeliverCallback;

public class Consumer {

private final static String QUEUE_NAME = "work_queue";

public static void main(String[] argv) throws Exception {

ConnectionFactory factory = new ConnectionFactory();

factory.setHost("localhost");

try (Connection connection = factory.newConnection();

Channel channel = connection.createChannel()) {

channel.queueDeclare(QUEUE_NAME, false, false, false, null);

// 设置同一时刻服务器只发送一条消息给消费者,实现公平分发

channel.basicQos(1);

DeliverCallback deliverCallback = (consumerTag, delivery) -> {

String message = new String(delivery.getBody(), "UTF-8");

System.out.println(" [x] Received '" + message + "'");

// 模拟任务处理时间

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

System.out.println(" [x] Done");

// 手动确认消息已被处理

channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);

};

// 关闭自动确认,改为手动确认

boolean autoAck = false;

channel.basicConsume(QUEUE_NAME, autoAck, deliverCallback, consumerTag -> { });

}

}

}

在消费者代码中,同样创建了连接工厂、连接和通道,并声明了与生产者相同的队列work_queue。通过channel.basicQos(1)方法设置了公平分发,确保同一时刻每个消费者只处理一条消息。定义了DeliverCallback回调函数来处理接收到的消息,在回调函数中,打印接收到的消息,通过Thread.sleep(1000)模拟任务处理时间,处理完成后,使用channel.basicAck方法手动确认消息已被处理,参数delivery.getEnvelope().getDeliveryTag()是消息的唯一标识,false表示不批量确认 。最后,通过channel.basicConsume方法开始消费消息,设置autoAck为false,即关闭自动确认,开启手动确认模式 。通过运行多个消费者实例,可以看到任务消息会被均衡地分配到各个消费者进行处理,实现了工作队列模式的负载均衡和并行处理功能。

消息广播:发布订阅模式

发布订阅模式原理

发布订阅模式是 RabbitMQ 中一种非常灵活且强大的消息通信模式,它打破了一对一或一对多的常规消息传递限制,实现了消息的广播式分发 。在这个模式中,交换机(Exchange)扮演着核心角色,它是消息的中转站,负责接收生产者发送的消息,并根据特定的规则将消息路由到一个或多个队列中 。

与简单队列模式和工作队列模式不同,发布订阅模式中生产者不再直接将消息发送到队列,而是发送到交换机。交换机不存储消息,它仅仅根据自身的类型和绑定规则来决定如何处理接收到的消息 。在发布订阅模式中,通常使用扇形交换机(Fanout Exchange)。扇形交换机的工作方式非常简单直接,它会将接收到的每一条消息无条件地广播到所有与它绑定的队列中,不关心消息的路由键(routing key),就像一个广播电台,只要有消息到达,就会向所有听众广播 。

当生产者将消息发送到扇形交换机后,交换机会迅速将消息复制多份,分别发送到与之绑定的各个队列。每个队列都可以有一个或多个消费者,这些消费者可以独立地从队列中获取消息并进行处理 。这样,一条消息就可以被多个不同的消费者同时接收和处理,实现了消息的广播效果,满足了多系统、多模块同时对同一消息感兴趣的业务需求 。

应用场景举例

发布订阅模式在实际业务中有广泛的应用。以电商系统中的实时通知场景为例,当用户完成一笔订单支付后,系统需要向多个模块发送通知。通过发布订阅模式,订单支付成功的消息被发送到交换机,与交换机绑定的库存管理队列、物流调度队列、用户积分队列等多个队列都会接收到该消息 。库存管理模块的消费者接收到消息后,会对商品库存进行扣减操作;物流调度模块的消费者会根据订单信息安排发货;用户积分模块的消费者则会为用户增加相应的积分 。这样,通过一次消息发布,多个相关业务模块都能及时获取到关键信息并进行相应处理,实现了系统间的高效协作和信息共享 。

在消息推送场景中,发布订阅模式同样发挥着重要作用。比如在一个新闻资讯平台,当有新的新闻发布时,生产者将新闻消息发送到交换机,与交换机绑定的各个用户设备队列都会收到该消息 。不同用户设备(手机端、PC 端等)上的消费者接收到消息后,会将最新的新闻推送给用户,使用户能够及时获取到感兴趣的内容 。这种方式大大提高了消息推送的效率和覆盖面,确保了信息的及时传递 。

代码实现步骤

下面通过 Java 代码来展示如何实现发布订阅模式。假设我们有一个生产者将消息发送到交换机,多个消费者从与交换机绑定的队列中获取消息。

首先,在 Maven 项目中引入 RabbitMQ 客户端依赖,确保pom.xml文件中有如下配置:

 

<dependency>

<groupId>com.rabbitmq</groupId>

<artifactId>amqp-client</artifactId>

<version>5.16.0</version>

</dependency>

生产者代码如下:

 

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

public class Publisher {

private final static String EXCHANGE_NAME = "fanout_exchange";

public static void main(String[] argv) throws Exception {

ConnectionFactory factory = new ConnectionFactory();

factory.setHost("localhost");

try (Connection connection = factory.newConnection();

Channel channel = connection.createChannel()) {

// 声明交换机,类型为fanout

channel.exchangeDeclare(EXCHANGE_NAME, "fanout");

String message = "Publish/Subscribe Message";

// 发送消息到交换机,routingKey为空

channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));

System.out.println(" [x] Sent '" + message + "'");

}

}

}

在生产者代码中,创建了连接工厂、连接和通道后,使用channel.exchangeDeclare方法声明了一个名为fanout_exchange的扇形交换机。然后通过channel.basicPublish方法将消息发送到交换机,由于是扇形交换机,不关心路由键,所以第二个参数为空字符串 。

消费者代码如下:

 

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

import com.rabbitmq.client.DeliverCallback;

public class Subscriber {

private final static String EXCHANGE_NAME = "fanout_exchange";

public static void main(String[] argv) throws Exception {

ConnectionFactory factory = new ConnectionFactory();

factory.setHost("localhost");

try (Connection connection = factory.newConnection();

Channel channel = connection.createChannel()) {

// 声明交换机,确保与生产者一致

channel.exchangeDeclare(EXCHANGE_NAME, "fanout");

// 声明一个临时队列,队列名称随机生成

String queueName = channel.queueDeclare().getQueue();

// 将队列绑定到交换机,routingKey为空

channel.queueBind(queueName, EXCHANGE_NAME, "");

System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

DeliverCallback deliverCallback = (consumerTag, delivery) -> {

String message = new String(delivery.getBody(), "UTF-8");

System.out.println(" [x] Received '" + message + "'");

};

channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });

}

}

}

消费者代码中,同样先声明了扇形交换机fanout_exchange。然后使用channel.queueDeclare()方法创建了一个临时队列,队列名称是随机生成的,并且该队列具有独占、自动删除的特性,即当消费者断开连接时,队列会自动被删除 。接着通过channel.queueBind方法将临时队列绑定到交换机上,routingKey 为空 。最后定义了消息处理回调函数DeliverCallback,当接收到消息时,会打印出接收到的消息内容 。使用channel.basicConsume方法开始消费消息,设置为自动确认模式 。运行多个消费者实例,当生产者发送消息后,可以看到每个消费者都能接收到相同的消息,成功实现了发布订阅模式 。

相关文章:

RabbitMQ 消息模式实战:从简单队列到复杂路由(二)

进阶探索&#xff1a;工作队列模式 工作队列模式剖析 工作队列模式&#xff0c;也被称为任务队列模式&#xff0c;是对简单队列模式的一种扩展和优化&#xff0c;旨在解决当任务量较大时&#xff0c;单个消费者无法快速处理所有任务的问题 。在工作队列模式中&#xff0c;依然…...

崩坏星穹铁道风堇前瞻养成攻略 崩坏星穹铁道风堇配队推荐

风堇是崩坏星穹铁道3.3上半版本即将登场的一名全新五星角色&#xff0c;她的机制和强度都还不错&#xff0c;今天就给大家一些养成攻略。 一、突破材料准备 1.基础材料&#xff1a;旅情见闻 3 个冒险记录 3 个漫游指南 289 个命运的足迹 8 个 2.特供材料&#xff1a;思量的种…...

如何利用 Python 爬虫按关键字搜索京东商品:实战指南

在电商领域&#xff0c;京东作为国内知名的电商平台&#xff0c;拥有海量的商品数据。通过 Python 爬虫技术&#xff0c;我们可以高效地按关键字搜索京东商品&#xff0c;并获取其详细信息。这些信息对于市场分析、选品上架、库存管理和价格策略制定等方面具有重要价值。本文将…...

阿里云的网络有哪些

阿里云的网络类型丰富&#xff0c;主要包括以下几种&#xff1a; 专有网络 VPC&#xff08;Virtual Private Cloud&#xff09;1&#xff1a;是用户基于阿里云创建的自定义私有网络。不同的专有网络之间二层逻辑隔离&#xff0c;用户可在自己创建的专有网络内创建和管理云产品…...

【微信小程序】webp资源上传失败

正文 快速开发了一个小程序&#xff0c;图片资源占比较多&#xff0c;于是从 png 到 jpg 压缩&#xff0c;勉强满足了 2MB 的限制&#xff0c;不用另外准备 cdn。 但这样肯定不适合&#xff0c;进一步更新时&#xff0c;空间便会爆表。 于是花了点时间&#xff0c;将所有的…...

鸿蒙 ArkUI - ArkTS 组件 官方 UI组件 合集

ArkUI 组件速查表 鸿蒙应用开发页面上需要实现的 UI 功能组件如果在这 100 多个组件里都找不到&#xff0c;那就需要组合造轮子了 使用技巧&#xff1a;先判断需要实现的组件大方向&#xff0c;比如“选择”、“文本”、“信息”等&#xff0c;或者是某种形状比如“块”、“图…...

科学养生指南:解锁健康生活的密码

健康是人生最宝贵的财富&#xff0c;科学养生则是守护这笔财富的关键。即使抛开传统中医理论&#xff0c;现代科学也为我们提供了诸多实用的养生方法。​ 合理饮食是健康养生的基石。人体需要碳水化合物、蛋白质、脂肪、维生素和矿物质等多种营养物质维持运转。日常饮食应遵循…...

Linux的进程管理和用户管理

gcc与g的区别 比如有两个文件&#xff1a;main.c mainc.cpp&#xff08;分别是用C语言和C语言写的&#xff09;如果要用gcc编译&#xff1a; gcc -o mainc main.c gcc -o mainc mainc.cpp -lstdc表明使用C标准库&#xff1b; 区别一&#xff1a; gcc默认只链接C库&#x…...

数据科学和机器学习的“看家兵器”——pandas模块 之五

目录 4.5 pandas 高级数据处理与分析 一、课程目标 二、对数据表格进行处理 (一)行列转置 (二)将数据表转换为树形结构 三、数据表的拼接 (一)merge () 函数的运用 (二)concat () 函数的运用 (三)append () 函数的运用 四、对数据表格的同级运算 五、计算数据表格中数…...

轻量级Web画板Paint Board如何本地部署与随时随地在线绘画分享

文章目录 前言1.关于Paint Board2.本地部署paint-board3.使用Paint Board4.cpolar内网穿透工具安装5.创建远程连接公网地址6.固定Paint Board公网地址 前言 今天我要给大家介绍一款超级轻便、好玩到飞起的Web画板Paint Board&#xff01;这可是创意人手中的秘密武器。无论是刚…...

攻击溯源技术体系:从理论架构到工程化实践的深度剖析

一、攻击溯源的理论基石与模型构建 1.1 形式化理论框架 攻击溯源本质上是基于离散数学与图论的演绎推理过程。通过构建攻击事件有向图&#xff08;AEDG, Attack Event Directed Graph&#xff09;&#xff0c;将网络空间中的每个事件抽象为节点&#xff0c;事件间的因果关系…...

fpga系列 HDL : Microchip FPGA开发软件 Libero Soc 安装 license申请

启动 注册账号&#xff1a;https://login.microchip.com/申请免费许可&#xff1a;https://www.microchipdirect.com/fpga-software-products C:\Windows\System32>vol驱动器 C 中的卷是 Windows卷的序列号是 ****-****为“D:\Microsemi\License.dat”创建环境变量“LM_LICE…...

海康立体相机3DMVS软件使用不同工作模式介绍

文章目录 1. Sensor Calibration&#xff08;传感器标定模式&#xff09;2. Depth&#xff08;深度模式&#xff09;3. RGB-D&#xff08;彩色深度融合模式&#xff09;4. Depalletizing&#xff08;拆垛模式&#xff09;5. Debug&#xff08;调试模式&#xff09;6. Point Clo…...

深度学习、机器学习及强化学习的联系与区别

联系 深度学习与机器学习 &#xff1a;深度学习是机器学习的一个分支。机器学习涵盖众多方法&#xff0c;如决策树、支持向量机等&#xff0c;而深度学习基于神经网络构建多层结构来学习数据特征。深度学习利用反向传播算法和梯度下降等优化方法来训练神经网络模型&#xff0c;…...

75.xilinx复数乘法器IP核调试

&#xff08;83*j&#xff09;*(57j) 935j 正确的是 1971j 分析出现的原因&#xff1a;&#xff08;abj&#xff09;* (cdj) (ac-bd)j(adbc) 其中a,b,c,d都是16bit的有符号数&#xff0c;乘积的结果为保证不溢出需要32bit存储&#xff0c;最终的复数乘法结果是两个32b…...

【笔记】CosyVoice 模型下载小记:简单易懂的两种方法对比

#工作记录 笔记标签&#xff1a;#CosyVoice 模型 #模型下载 #ModelScope #Git LFS #语音合成开发 一、强烈推荐&#xff1a;用 ModelScope SDK 下载&#xff08;简单又靠谱&#xff09; 1.1 好处多多 不容易出错&#xff1a;能自动把模型需要的所有东西都下载好&#xff0c…...

本地部署 私有云网盘 Nextcloud 并实现外部访问

Nextcloud 是一款开源免费的私有云盘系统&#xff0c;可以快速地搭建一套属于自己的云同步网盘&#xff0c;从而实现跨设备的文件同步、文件共享、以及团队协作等功能。Nextcloud 功能强大且完全开源&#xff0c;拥有庞大的开源社区支持。 本文将详细的介绍如何利用 Docker 在…...

黑马程序员C++2024版笔记 第0章 C++入门

1.C代码的基础结构 以hello_world代码为例&#xff1a; 预处理指令 #include<iostream> using namespace std; 代码前2行是预处理指令&#xff0c;即代码编译前的准备工作。&#xff08;编译是将源代码转化为可执行程序.exe文件的过程&#xff09; 主函数 主函数是…...

D3485:一款高性能RS-485收发器解析

D3485是一款5V供电、半双工RS-485收发器&#xff0c;广泛应用于智能电表、工业控制和安防监控等领域。它内部包含一路驱动器和一路接收器&#xff0c;采用限摆率驱动器设计&#xff0c;能有效减少电磁干扰&#xff08;EMI&#xff09;和反射&#xff0c;支持高达10Mbps的无差错…...

std::deque和std::vector对比

std::deque和std::vector都是 C标准库中非常重要的容器&#xff0c;但它们的设计目标和优化方向不同&#xff0c;因此各有适用场景。std::deque并没有取代std::vector&#xff0c;原因主要在于以下几个方面&#xff1a; 1.性能特点不同 1.1std::vector的优势 • 连续存储&am…...

【蓝桥杯省赛真题49】python偶数 第十五届蓝桥杯青少组Python编程省赛真题解析

python偶数 第十五届蓝桥杯青少组python比赛省赛真题详细解析 博主推荐 所有考级比赛学习相关资料合集【推荐收藏】1、Python比赛 信息素养大赛Python编程挑战赛 蓝桥杯python选拔赛真题详解...

15分钟决胜项目管理:碎片时间的高效拆解术

作为项目经理&#xff0c;你是否经常觉得一天像打仗&#xff1f;会议连轴转、消息轰炸、计划赶不上变化……时间总是不够用。但真相是&#xff1a;高效的人并不是时间更多&#xff0c;而是更会“切分时间”。试试“15分钟法则”——每天用几段碎片时间&#xff0c;就能让工作从…...

计算机网络:什么是电磁波以及有什么危害?

电磁波详解 电磁波(Electromagnetic Wave)是由电场和磁场相互激发、在空间中传播的能量形式。它既是现代通信的基石(如手机、Wi-Fi、卫星信号),也是自然界中光、热辐射等现象的本质。以下从定义、产生、特性、分类及应用全面解析: 一、电磁波的本质 1. 核心定义 电场与…...

Docker部署单节点Elasticsearch

1.Docker部署单节点ES 1.前置条件 配置内核参数 echo "vm.max_map_count262144" >> /etc/sysctl.conf sysctl -w vm.max_map_count262144准备密码 本文所有涉及密码的配置&#xff0c;均使用通用密码 Zzwl2024。 生产环境&#xff0c;请用密码生成器生成20…...

Docker构建Nginx、PHP、MySQL及WordPress部署及解释

目录 一、构建Nginx 二、构建PHP 三、构建MySQL 四、启动容器 五、测试 六、部署网站 一、构建Nginx 创建目录并进入目录 bash 复制 mkdir /opt/nginx cd /opt/nginx mkdir /opt/nginx&#xff1a;在 /opt 目录下创建一个名为 nginx 的目录。 cd /opt/nginx&#x…...

计算机网络:蜂窝网络和WiFi网络使用的射频信号有什么区别?

— 频段设计,蜂窝网络,比如4G LTE或5G,使用的频段通常由各国政府机构分配,例如在Sub-6GHz范围内,还有一些高频的毫米波。而WiFi主要使用的是2.4GHz和5GHz的ISM(工业、科学、医疗)免许可频段。这说明两者的频段不同,可能带来不同的传播特性和干扰情况。 —调制方式,蜂窝…...

今日行情明日机会——20250515

上证指数缩量收阴线&#xff0c;个股跌多涨少&#xff0c;上涨波段4月9日以来已有24个交易日&#xff0c;时间周期上处于上涨末端&#xff0c;注意风险。 深证指数缩量收阴线&#xff0c;日线上涨结束的概率在增大&#xff0c;注意风险。 2025年5月15日涨停股主要行业方向分…...

康复训练:VR 老年虚拟仿真,趣味助力恢复​

对于那些因身体机能衰退、疾病或者意外而急需康复训练的老人而言&#xff0c;传统的康复方式通常显得极为枯燥乏味。例如&#xff0c;只是在康复师的指导下机械地重复抬腿、伸手等简单动作&#xff0c;日复一日&#xff0c;毫无新意&#xff0c;这样的模式使得老人很难长期坚持…...

【美团】后端一面复盘|项目驱动 + 手撕 + JVM + 数据库全面覆盖

【美团】后端一面复盘&#xff5c;项目驱动 手撕 JVM 数据库全面覆盖 &#x1f4cd; 面试公司&#xff1a;美团 &#x1f3af; 面试岗位&#xff1a;后端开发工程师 &#x1f4de; 面试形式&#xff1a;电话面&#xff08;OC&#xff09; &#x1f552; 面试时长&#xff1…...

3DVR制作的工具或平台

3DVR&#xff08;三维虚拟现实&#xff09;是利用三维图像技术和虚拟现实技术&#xff0c;将真实场景进行三维扫描并转换成计算机可识别的三维模型&#xff0c;使用户能够在虚拟空间中自由漫游&#xff0c;体验身临其境的感觉。3DVR技术结合了全景拍摄和虚拟现实&#xff0c;提…...

websocket入门详解

入门websocket的基础应该掌握一下问题&#xff1a; 1、什么是握手&#xff1f; 2、什么是websocket&#xff1f; 3、websocket和http的区别&#xff0c;应用场景 4、html前端简单代码演示 5、springboot整合websocket使用 6、使用vueelementui打造简单聊天室 7、使用web…...

go-zero(十八)结合Elasticsearch实现高效数据检索

go-zero结合Elasticsearch实现高效数据检索 1. Elasticsearch简单介绍 Elasticsearch&#xff08;简称 ES&#xff09; 是一个基于 Lucene 库 构建的 分布式、开源、实时搜索与分析引擎&#xff0c;采用 Apache 2.0 协议。它支持水平扩展&#xff0c;能高效处理大规模数据的存…...

window 显示驱动开发-报告图形内存(四)

检索图形内存数字 创建图形应用程序的软件开发人员可以使用从 Windows Vista 开始的 Microsoft DirectX 版本 10 API 在运行 Windows 显示驱动程序模型 (WDDM) 显示驱动程序的计算机上检索准确的图形内存数集。 以下步骤演示如何检索图形内存编号&#xff1a; 由于新的图形内…...

精益数据分析(60/126):移情阶段的终极追问——如何用结构化访谈挖掘真实需求

精益数据分析&#xff08;60/126&#xff09;&#xff1a;移情阶段的终极追问——如何用结构化访谈挖掘真实需求 在创业的移情阶段&#xff0c;客户访谈的深度决定了需求洞察的准确度。今天&#xff0c;我们结合《精益数据分析》的方法论&#xff0c;探讨如何通过“追问技巧”…...

主流快递查询API横向对比:快递100快递鸟菜鸟物流接口差异解析

主流快递查询API横向对比&#xff1a;快递100/快递鸟/菜鸟物流接口差异解析 一、核心功能与适用范围 菜鸟API 核心功能&#xff1a;物流信息查询、电子面单打印、智能仓储管理、跨境物流服务&#xff0c;整合阿里生态资源&#xff08;如淘宝、天猫订单直接对接&#xff09;。…...

c++从入门到精通(四)--动态内存,模板与泛型编程

文章目录 动态内存直接管理内存Shared_ptr类Unique_ptrWeak_ptr动态数组allocator类文本查询程序 模板与泛型编程定义模板函数模板类模板模板参数成员模板控制实例化 模板实参推断重载与模板可变参数模板模板特例化 动态内存 c中动态内存的管理是通过new和delete运算符来实现的…...

反病毒反垃圾U-Mail邮件系统从容应对

在数字化时代&#xff0c;电子邮件依然是企业沟通的核心工具。然而&#xff0c;垃圾邮件、病毒邮件和钓鱼邮件等安全威胁&#xff0c;如同潜伏在暗处的幽灵&#xff0c;随时可能侵蚀企业的信息安全。因此&#xff0c;企业需要构建一套严密的邮件安全防御体系&#xff0c;才能有…...

第一天的尝试

目录 一、每日一言 二、练习题 三、效果展示 四、下次题目 五、总结 一、每日一言 可能我们会失败&#xff0c;但是人生容错率挺高的&#xff0c;你没必要活成万众瞩目的样子&#xff0c;我们也想要这样的生活&#xff0c;但是我们要付出努力和时间&#xff0c;所以当情绪来…...

GUI图形化演示

概述 Swing组件通常被称为“轻量级组件”,他完全由Java编写&#xff0c;不依赖操作系统语言&#xff0c;他的类继承关系如下&#xff1a; Java.lang.Object->Java.awt.Component->Java.awt.Container->Javax.swing.JCompoment JCompoent是swing组件存放的位置&…...

Day118 | 灵神 | 二叉树 | 删点成林

Day118 | 灵神 | 二叉树 | 删点成林 1110.删点成林 1110. 删点成林 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 最直接的思路就是看当前结点的值是不是在要删除的列表中&#xff0c;在的话删除当前结点并把左右孩子加入res中 很可惜这样是错的&#xff0c;…...

每周靶点:IL31、B7H3及文献分享

本期精选了《炎症中的“瘙痒”细胞因子IL31》《免疫检查点分子B7H3》《重组抗体&#xff1a;抗体测序和人工智能助力抗体设计》《文献分享&#xff1a;用于HER2特异性递送的单链Fab衍生药物偶联物》《文献分享&#xff1a;全长抗体、片段和双特异性格式的可开发性的比较研究》五…...

机器学习笔记——特征工程

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本笔记介绍机器学习中常见的特征工程方法、正则化方法和简要介绍强化学习。 文章目录 特征工程&#xff08;Fzeature Engineering&#xff09;1. 特征提取&#xff…...

麒麟v10 部署 MySQL 5.6.10 完整步骤

需要包的私信我 一、安装依赖&#xff08;Perl环境&#xff09; # 在线安装依赖 yum -y install perl perl-devel# 离线安装&#xff08;需提前下载好rpm包&#xff09; mkdir /data/ybn/soft/pre yum install --downloadonly --downloaddir/data/ybn/soft/pre perl perl-dev…...

digitalworld.local: DEVELOPMENT靶场

digitalworld.local: DEVELOPMENT 来自 <https://www.vulnhub.com/entry/digitalworldlocal-development,280/> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.18…...

高等数学基础(梯度下降法求函数的最小值)

梯度下降法, 一般是寻找函数极小值最常用的优化方法. 当目标函数时凸函数时, 梯度下降时全局解, 但是一般情况没办法保证是全局最优的. 通常在求最优解时, 首先会设定好步长大小进行调整, 按照上述方法对参数进行调整后就会逼近一个极小值 设函数 f ( x ) f(x) f(x)为一元连续函…...

【AI News | 20250515】每日AI进展

AI Repos 1、helix-db 专用于RAG以及AI应用的一款高性能图向量数据库&#xff1a;HelixDB&#xff0c;比Neo4j快1000倍&#xff0c;比TigerGraph快100倍&#xff0c;向量搜索性能和Qdrant相当。原生支持图形和矢量数据类型&#xff0c;比较适合RAG和AI应用&#xff0c;像知识图…...

大数据架构选型分析

选择依据 1.业务需求与技术要求 用户需要根据自己的业务需求来选择架构&#xff0c;如果业务对于Hadoop、Spark、Strom等关键技术有强制性依赖&#xff0c;选择Lambda架构可能较为合适&#xff1b;如果处理数据偏好于流式计算&#xff0c;又依赖Flink计算引擎&#xff0c;那么…...

C++中多重继承下的虚表结构

在 C 的多重继承 中&#xff0c;虚表&#xff08;vtable&#xff09;结构会变得更加复杂。 一、基础回顾&#xff1a;单继承下的虚表结构 类中含有虚函数 → 编译器生成虚表&#xff08;每类一张&#xff09;&#xff1b;每个对象有一个隐藏的虚表指针&#xff08;vptr&#x…...

安全巡检清单

安全巡检报告清单 引言 安全巡检是保障信息系统稳定运行和数据安全的关键环节。通过周期性的状态检查、安全扫描、日志分析和补丁管理&#xff0c;可以及时发现并修复潜在的安全隐患和漏洞&#xff0c;确保网络设备、服务器、操作系统及应用系统的高可用性和安全性。本清单旨…...

【redis】redis常见数据结构及其底层,redis单线程读写效率高于多线程的理解,

redis常用数据结构及底层 string字符串、list链表、set无序集合、zset有序集合、hash哈希 1.string 底层结构是SDS简单动态字符串 struct sdshdr {int len; // 已用长度&#xff08;字符串实际长度&#xff09;int free; // 剩余可用空间char buf[]; // 数组&#…...