RabbitMQ死信队列与延迟队列
目录
死信队列
死信队列的定义
死信队列的应用场景
死信队列的作用
死信队列架构图
死信队列代码实现
延迟队列
延迟队列的定义
延迟队列的应用场景
延迟队列的作用
延迟队列架构图
延迟队列的代码实现
死信队列
死信队列的定义
死信队列(Dead Letter Queue): 死信队列是一种特殊的队列,用于存放不能被消费的消息。当消息满足某些条件时,比如消息过期、消息被拒绝消费或消息达到最大重试次数等,RabbitMQ 会将这些消息自动发送到死信队列中,以便后续处理。 死信队列通常用于处理异常情况下的消息,例如重试机制、错误处理和日志记录等。我们可以设置交换机和队列的属性,将满足条件的消息转发到指定的死信队列中,然后在死信队列中进行后续处理。
死信队列的应用场景
RabbitMQ的死信队列提供了一种灵活和可靠的机制来处理无法被消费或需要特殊处理的消息,在以下几个常见应用场景中非常有用。
-
错误处理:当消息在消费过程中发生错误时,可以将错误消息发送到死信队列中,供后续进行错误处理、重试或记录日志等操作。这样可以避免消费者一直尝试处理无法成功的消息,提高系统的容错性和可靠性。
-
延迟消息:通过设置消息的过期时间,可以将消息发送到一个带有死信队列的普通队列中,从而实现延迟消息的功能。消息会在过期时间到达后自动转发到死信队列,然后消费者可以接收和处理这些延迟消息。这种方式可以用于实现定时任务、延时处理等需求。
-
优先级队列:通过设置队列和消息的优先级属性,可以在消费者处理消息时,优先处理具有较高优先级的消息。如果某个消息无法被及时处理,可以将其发送到死信队列中,以防止其他高优先级的消息被堵塞。
-
消息溢出保护:当队列的长度超过一定限制时,可以设置死信队列,将超出限制的消息转发到死信队列中,避免队列的无限增长。这有助于保护系统不会因为消息积压而崩溃或降低性能。
-
消息路由失败处理:当消息无法被正确路由到目标队列时,可以将其发送到死信队列中。这种情况通常发生在消息的路由键与已绑定的交换机和队列不匹配时,通过死信队列可以记录这些无法被路由的消息。
死信队列的作用
死信队列是一种用于处理消费者无法成功处理的消息的特殊队列。当消息不能被正常消费或处理时,它们会被发送到死信队列中,以便进行后续的处理或排查。以下是死信队列的几个作用:
-
保留失败消息: 死信队列充当了一个缓冲区,用于存储那些无法被消费者成功处理的消息。这些消息可以被保留在队列中,以便稍后进行进一步的分析、排查和处理。
-
错误处理与重试: 死信队列提供了一种机制来处理消费者无法处理的消息。当消息被发送到死信队列时,您可以检查并找出导致失败的原因。根据失败原因,您可以采取适当的措施,例如重新发送消息、修复消费者、调整处理逻辑等。
-
异常情况的监控和报警: 死信队列可以帮助您监控系统中出现的异常情况。通过检查死信队列中的消息数量或频率,您可以识别出消费问题、性能问题或其他运行时异常,并及时采取措施来解决这些问题。您还可以设置报警规则,以便在死信队列中积累了过多的消息时获得通知。
-
分析和故障排除: 死信队列存储了消费者无法成功处理的消息,这些消息可能包含了系统中的问题或异常情况。通过仔细分析死信消息,您可以识别出问题的根本原因,并采取相应的措施来修复系统或调整处理逻辑。
总之,死信队列是一种用于处理消费者无法处理的消息的机制。它提供了保留失败消息、错误处理与重试、异常监控与报警以及故障排除等功能,帮助保证消息处理的可靠性和系统的稳定性。
死信队列架构图
在这个架构图中,有以下组件:
- Producer Application:消息生产者应用程序,发送消息到 RabbitMQ 中的 Exchange(交换机)A。
- Exchange A:将收到的消息路由到 Queue Q。如果消息无法被路由,则将其发送到 Dead Letter Exchange B。
- Queue Q:主要的消费者队列,负责接收和处理消息。如果消息无法被消费,则将其发送到 Dead Letter Exchange B。
- Dead Letter Exchange B:其中一个交换机,负责将无法被消费的消息路由到 Dead Letter Queue D。
- Consumer Application:消费者应用程序,从 Queue Q 接收消息进行消费。
- Dead Letter Queue D:死信队列,用于存储无法被消费的消息。
总之,RabbitMQ 死信队列的架构允许开发人员使用 Exchange(交换机)来路由消息。当无法将消息路由到主要的消费者队列时,将其发送到死信交换机并路由到死信队列。这提供了一种强大的机制来处理异常情况,并避免消息丢失。
死信队列代码实现
以下是使用 Java 实现 RabbitMQ 死信队列的示例代码:
首先,我们需要添加 RabbitMQ 的 Java 客户端依赖。在 Maven 项目中,可以在 pom.xml
文件中添加以下依赖项:
<dependencies><dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.12.0</version></dependency>
</dependencies>
然后,我们可以编写代码来创建死信交换机和队列:
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;public class DeadLetterQueueExample {private static final String HOST = "localhost";private static final String DLX_EXCHANGE = "dlx_exchange";private static final String DLX_QUEUE = "dlx_queue";private static final String NORMAL_EXCHANGE = "normal_exchange";private static final String NORMAL_QUEUE = "normal_queue";public static void main(String[] args) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost(HOST);Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 创建死信交换机channel.exchangeDeclare(DLX_EXCHANGE, BuiltinExchangeType.DIRECT);// 创建死信队列channel.queueDeclare(DLX_QUEUE, true, false, false, null);// 将死信队列绑定到死信交换机channel.queueBind(DLX_QUEUE, DLX_EXCHANGE, "");// 创建普通交换机channel.exchangeDeclare(NORMAL_EXCHANGE, BuiltinExchangeType.DIRECT);// 创建普通队列,并指定死信交换机和队列Map<String, Object> arguments = new HashMap<>();arguments.put("x-dead-letter-exchange", DLX_EXCHANGE); // 将未消费的消息发送到死信交换机channel.queueDeclare(NORMAL_QUEUE, true, false, false, arguments);// 将普通队列绑定到普通交换机channel.queueBind(NORMAL_QUEUE, NORMAL_EXCHANGE, "");System.out.println("Waiting for messages...");// 定义消息处理函数DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");try {System.out.println("Received message: " + message);// 此处省略消息处理逻辑// 手动确认消息channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);} catch (Exception e) {// 消息处理失败,将消息发送到死信交换机channel.basicPublish("", DLX_QUEUE, null, delivery.getBody());}};// 启动消费者,监听普通队列上的消息boolean autoAck = false; // 关闭自动确认模式channel.basicConsume(NORMAL_QUEUE, autoAck, deliverCallback, consumerTag -> {});// 等待消息处理完成Thread.sleep(10000);channel.close();connection.close();}
}
通过以上 Java 代码,我们可以实现一个基本的 RabbitMQ 死信队列。当普通队列上的消息无法被消费时,会被发送到死信交换机,并最终路由到死信队列。在这个示例中,我们使用 x-dead-letter-exchange
参数将未能成功消费的消息发送到死信交换机。
请注意,以上代码只是示例,需要根据实际需求进行适当修改和扩展。另外,确保已经添加了 RabbitMQ 的 Java 客户端依赖。
延迟队列
延迟队列的定义
延迟队列(Delayed Queues): 延迟队列允许消息在一定时间后才能被消费者接收和处理。与普通队列不同,延迟队列会在消息发送后暂时存储消息,直到设定的延迟时间过去后才将消息发送给消费者。 RabbitMQ 并没有内置的延迟队列机制,但我们可以通过插件或自定义实现来实现延迟队列。一种常见的实现方式是使用 RabbitMQ 的过期时间(TTL)和死信队列结合,将消息发送到带有延迟时间的队列中,然后在消息过期后自动转发到死信队列中,从而达到延迟队列的效果。
延迟队列的应用场景
RabbitMQ延迟队列可以提供灵活可靠的消息延迟处理功能,满足各种业务需求,具有以下几个常见的应用场景。
-
定时任务:延迟队列可以用于实现定时任务的调度。将需要延迟执行的任务消息发送到延迟队列中,并设置延迟时间。当延迟时间到达后,消息会被转发到指定的目标队列,然后被消费者获取和执行。这样可以很方便地实现各种定时任务,如定时发送提醒、定时数据备份等。
-
消息重试:延迟队列可以用于处理发送失败的消息的重试机制。当消息发送失败时,可以将消息发送到延迟队列,并设置一段延迟时间。如果在延迟时间内没有收到回应,那么消息会被转发到目标队列,并重新尝试处理。这样可以增加消息的可靠性,确保消息能够成功发送和处理。
-
订单超时处理:对于涉及订单的业务系统,延迟队列可以用于处理订单超时的情况。当订单创建后,可以将订单信息发送到延迟队列,并设置一个较长的延迟时间。如果在延迟时间内没有支付或完成相应操作,那么订单会被转发到指定的目标队列进行超时处理,比如取消订单、释放库存等。
-
流量控制:延迟队列可以用于实现流量控制机制。当系统负载过高或并发请求过多时,可以将部分请求消息发送到延迟队列,并设置一段延迟时间。这样可以通过延时来平滑系统负载,避免瞬时的高峰压力对系统造成影响。
-
消息分发调度:延迟队列可以用于实现消息的按时序分发和调度。例如,在社交媒体应用中,可以将用户发布的消息发送到延迟队列,并根据消息的发布时间设置不同的延迟时间。这样可以按照时间顺序逐个转发消息,确保消息按照正确的时间顺序进行处理和展示。
延迟队列的作用
延迟队列用于延迟处理消息,其作用是将消息延迟发送给接收方,以满足需要在一定时间之后执行某些操作的需求。以下是延迟队列的几个作用:
-
延迟任务调度: 延迟队列可以用于任务调度,通过将任务消息放入延迟队列,并设置延迟时间,从而实现在指定时间后执行任务。这对于需要在未来某个时间点触发的操作非常有用,例如定时任务、定时提醒等。
-
消息重试与补偿: 在一些情况下,当消息处理失败时,我们可能希望将消息重新发送给消费者或进行补偿操作。延迟队列可以用于设定一段延迟时间,在此时间内等待消费者重新可用,并将消息重新发送给消费者,以进行重试或补偿处理。
-
事件顺序控制: 在某些场景中,消息的顺序非常重要。延迟队列可以根据消息的延迟时间,保证消息按照预期的顺序发送给消费者。这对于需要确保事件按照正确顺序处理的业务非常关键,如订单处理、任务流程控制等。
-
流量控制与防止系统过载: 当系统的请求或消息量过大时,延迟队列可以帮助平衡流量,避免系统过载。通过设置适当的延迟时间,可以限制消息的处理速率,确保系统能够按照可承受的负载进行处理。
总之,延迟队列提供了一种机制,可以将消息在指定的延迟时间后发送给接收方。它适用于延迟任务调度、消息重试与补偿、事件顺序控制以及流量控制等场景,帮助满足业务需求并保证系统的可靠性。
延迟队列架构图
在这个架构图中,有以下组件:
- Exchange:负责将消息路由到 Delay Queue。
- Delay Queue:延迟队列,用于存储具有延迟时间的消息。它在一定的延迟时间后将消息转发到 Message Queue。
- Message Queue (MQ):正常的消息队列,负责接收和存储延迟队列转发过来的消息。
- Consumer Application:消费者应用程序,从 Message Queue 接收消息进行消费。
实现 RabbitMQ 的延迟队列通常需要借助 RabbitMQ 的插件,例如 rabbitmq_delayed_message_exchange 插件。该插件提供了一个特殊的 Exchange 类型,能够将消息按照一定的延迟时间转发到指定的队列。
总之,RabbitMQ 延迟队列架构允许开发人员在消息被发送到消费者之前引入延迟。通过将消息先发送到延迟队列,然后根据延迟时间自动转发到消息队列中,可以实现灵活的延迟消息处理。这对于需要延迟处理的业务场景非常有用,例如订单超时取消、任务调度等。
延迟队列的代码实现
要实现 RabbitMQ 的延迟队列,我们可以结合使用 RabbitMQ 的插件 rabbitmq_delayed_message_exchange
和 Java 客户端来实现。以下是示例代码:
首先,确保已经安装并启用了 rabbitmq_delayed_message_exchange
插件。可以通过以下命令启用它:
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
然后,在 Java 代码中使用延迟队列:
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;public class DelayedQueueExample {private static final String HOST = "localhost";private static final String EXCHANGE_NAME = "delayed_exchange";private static final String QUEUE_NAME = "delayed_queue";private static final String ROUTING_KEY = "";public static void main(String[] args) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost(HOST);Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 创建延迟交换机,类型为 x-delayed-messageMap<String, Object> arguments = new HashMap<>();arguments.put("x-delayed-type", "direct");channel.exchangeDeclare(EXCHANGE_NAME, "x-delayed-message", true, false, arguments);// 创建延迟队列channel.queueDeclare(QUEUE_NAME, true, false, false, null);// 将队列绑定到交换机channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);System.out.println("Waiting for messages...");// 定义消息处理函数DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println("Received message: " + message);// 手动确认消息channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);};// 启动消费者,监听延迟队列上的消息boolean autoAck = false; // 关闭自动确认模式channel.basicConsume(QUEUE_NAME, autoAck, deliverCallback, consumerTag -> {});// 发布延迟消息publishDelayedMessage(channel, 5000, "Delayed Message 1"); // 延迟5秒publishDelayedMessage(channel, 10000, "Delayed Message 2"); // 延迟10秒Thread.sleep(15000); // 等待消息处理完成channel.close();connection.close();}private static void publishDelayedMessage(Channel channel, long delayMillis, String message) throws IOException {AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder().contentType("text/plain").deliveryMode(2) // 持久化消息.headers(Map.of("x-delay", delayMillis)) // 设置延迟时间.build();channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, properties, message.getBytes("UTF-8"));System.out.println("Published delayed message: " + message);}
}
在上述示例中,我们创建了一个延迟交换机并绑定到一个延迟队列。然后,我们通过设置消息的 x-delay
头部属性来指定消息的延迟时间。在消息发布时,我们使用延迟时间发送消息到交换机,这样消息将会在指定的延迟时间后被路由到队列。消费者通过监听延迟队列来接收延迟消息。
更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)
相关文章:

RabbitMQ死信队列与延迟队列
目录 死信队列 死信队列的定义 死信队列的应用场景 死信队列的作用 死信队列架构图 死信队列代码实现 延迟队列 延迟队列的定义 延迟队列的应用场景 延迟队列的作用 延迟队列架构图 延迟队列的代码实现 死信队列 死信队列的定义 死信队列(Dead Letter …...
存储管理呀
世界太吵,别听,别看,别管,别怕,向前走 一. 存储管理 初识硬盘 机械 HDD 固态 SSDSSD的优势 SSD采用电子存储介质进行数据存储和读取的一种技术,拥有极高的存储性能,被认为是存储技术发展的未来…...
学习 BeautifulSoup 库从入门到精通
可以按照以下步骤进行: 1. 安装 BeautifulSoup: 首先,确保你已经安装了 Python。然后可以使用 pip 命令来安装 BeautifulSoup 库。在命令行中输入以下命令: pip install beautifulsoup42. 导入 BeautifulSoup: 在 …...
JavaScript基础知识总结
目录 一、js代码位置 二、变量与数据类型 1、声明变量 2、基本类型(7种基本类型) 1、undefined和null 2、String ⭐ 模板字符串(Template strings) 3、number和bigint ⭐ 4、boolean ⭐ 5、symbol 3、对象类型 1、Fun…...

技术面试与HR面:两者之间的关联与区别
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...

【Redis】为什么要学 Redis
文章目录 前言一、Redis 为什么快二、Redis 的特性2.1 将数据储存到内存中2.2 可编程性2.3 可扩展性2.4 持久性2.5 支持集群2.6 高可用性 三、Redis 的应用场景四、不能使用 Redis 的场景 前言 关于为什么要学 Redis 这个问题,一个字就可以回答,那就是&…...

动静态库生成使用
🔥🔥 欢迎来到小林的博客!! 🛰️博客主页:✈️林 子 🛰️博客专栏:✈️ Linux 🛰️社区 :✈️ 进步学堂 🛰…...
LLVM编译安装
LLVM编译安装 #全量下载 git clone https://github.com/llvm/llvm-project.git #只下载最新commit版本 git clone --depth 1 https://github.com/llvm/llvm-project.git#配置 #!/bin/bash set -ex cmake -S llvm -B build -DCMAKE_INSTALL_PREFIX/data0/huozai/software/insta…...
表的内连接和外连接
表的连接是SQL中的一种操作,用于将两个或多个表中的数据按照某个条件进行关联。 内连接 使用内连接将两个表(Table1 和 Table2)进行连接: select * from Table1 inner join Table2 on Table1.id Table2.id;举例: -- 用普通的写法 select…...

三、C#—变量,表达式,运算符(3)
🌻🌻 目录 一、变量1.1 变量1.2 使用变量的步骤1.3 变量的声明1.4 变量的命名规则1.5 变量的初始化1.6 变量初始化的三种方法1.7 变量的作用域1.8 变量使用实例1.9 变量常见错误 二、C#数据类型2.1 数据类型2.2 值类型2.2.1 值类型直接存储值2.2.2 简单类…...

纷享销客受邀出席CDIE2023数字化创新博览会 助力大中型企业增长
2023年,穿越周期,用数字化的力量重塑企业经营与增长的逻辑,再次成为企业数字化技术应用思考的主旋律,以数字经济为主线,数字技术融入产业发展与企业增长为依据,推动中国企业数字化升级。 9月5日,…...
linux下qt交叉编译 tslib 库
在 Linux 下进行 Qt 的交叉编译,并包含 tslib 库,可以按照以下步骤进行操作:1. 准备交叉编译工具链:首先,你需要准备适用于目标平台的交叉编译工具链。这个工具链包括交叉编译器、 2. 链接器和其他相关的工具ÿ…...

2.13 PE结构:实现PE代码段加密
代码加密功能的实现原理,首先通过创建一个新的.hack区段,并对该区段进行初始化,接着我们向此区段内写入一段具有动态解密功能的ShellCode汇编指令集,并将程序入口地址修正为ShellCode地址位置处,当解密功能被运行后则可…...
Rust更换Cargo国内源,镜像了寂寞
换皮不换身 换了国内源,构建时该卡还会卡。因为它所谓的换源,只是更换crates.io“索引”的源,而不是package“内容”的源。换了国内源后,在国内编译时访问 crates.io-index 自然会快很多,可是crates.io-index里面的信…...

【网络安全带你练爬虫-100练】第23练:文件内容的删除+写入
目录 0x00 前言: 0x02 解决: 0x00 前言: 本篇博文可能会有一点点的超级呆 0x02 解决: 你是不是也会想: 使用pyrhon将指定文件夹位置里面的1.txt中数据全部删除以后---->然后再将参数req_text的值写入到1.txt …...
ESP32蓝牙实例-BLE服务器与客户端通信
BLE服务器与客户端通信 文章目录 BLE服务器与客户端通信1、软件准备2、硬件准备3、代码实现3.1 BLE服务器实现3.2 Android手机测试BLE服务器3.3 ESP32 BLE客户端在本文中,我们将介绍如何使用低功耗蓝牙在两个 ESP32 开发板之间执行 BLE 服务器客户端通信。 换句话说,将介绍如…...

第11章_瑞萨MCU零基础入门系列教程之SysTick
本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id728461040949 配套资料获取:https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总: ht…...
【面试题精讲】如何使用Stream的聚合功能
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 系列文章地址 求和(Sum): List<Integer> numbers Arrays.asList(1, 2, 3, 4, 5);int sum n…...
Linux 中的 chmod 命令及示例
在 Unix 操作系统中,chmod命令用于更改文件的访问模式。该名称是change mode的缩写。其中规定每个文件和目录都有一组权限来控制权限,例如谁可以读取、写入或执行该文件。其中权限分为三类:同时读、写和执行,用“r”、“w”和“x”表示。这些字母组合在一起形成一组用户的特…...
sannaing i14 pro max使用体验
体验了一把山寨机,不明真相的人会以为这是三星的英文标志,又是pro又是max的,价格600,进系统去看了配置,cpu写的是snapdragon 888,运存12g,内存500g。下了个安兔兔也是被忽悠了,它也以…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...