Haskell 实现 RabbitMQ 六套官方教程:从 Hello World 到 RPC 的完整实战指南
示例工程【免费下载链接】rabbitmq-tutorialsTutorials for using RabbitMQ in various ways项目地址https://gitcode.com/gh_mirrors/ra/rabbitmq-tutorials点击查看免费下载本指南以 haskell/README.md 为核心脉络系统讲解如何用 Haskell 与Network.AMQP客户端库逐一套跑通 RabbitMQ 官方六套教程Hello World、工作队列、发布/订阅、路由、主题、RPC。文中给出的每个命令与代码示例均来自仓库中真实可运行的.hs文件读完你既能用stack或runhaskell直接复现全部示例也能理解Network.AMQP在队列声明、消息发布、消费确认、交换机绑定与 RPC 回调等环节的核心 API 用法。环境准备Network.AMQP 与本地 RabbitMQ运行本仓库的 Haskell 示例只需要一个关键依赖Network.AMQP它是 Haskell 生态中面向 AMQP 0-9-1 协议的客户端库提供了openConnection、openChannel、declareQueue、declareExchange、publishMsg、consumeMsgs等教程中反复使用的高层函数。在运行任何示例之前请确保满足以下前置条件本地 RabbitMQ 节点已启动且使用默认配置监听127.0.0.1、默认 vhost/、默认账号guest/guest。所有源码中的连接参数均与此默认值一一对应例如 send.hs 中的openConnection 127.0.0.1 / guest guest。安装 GHC 与stack。如果不想手动管理 GHC 版本和依赖包README 推荐直接使用stack它会在首次运行时自动为你安装ghc、amqp以及其他必需包。两种运行方式runhaskell与stack仓库中每个.hs文件都可以独立运行。README 给出了两种执行方式直接执行runhaskell FILE ARGS使用stack执行stack FILE ARGS等价于stack runghc FILE ARGS。实际上每个源文件头部都内嵌了 stack 所需的依赖声明注释例如 send.hs#!/usr/bin/env stack {- stack --install-ghc runghc --package amqp --package bytestring -}这意味着即使你用runhaskell send.hs运行该文件本身也保留了stack模式下可复现的完整依赖清单而用stack send.hs hello world这类命令运行时stack会读取该头部注释自动安装 GHC 与依赖无需额外手工stack install。所有示例都启用了OverloadedStrings扩展{-# LANGUAGE OverloadedStrings #-}因此字符串字面量可以直接当作Text/ByteString使用简化了与 AMQP 消息体BL.ByteString的交互。教程一Hello World —— 队列声明、发送与消费对应文件send.hs生产者与 receive.hs消费者运行命令runhaskell send.hs runhaskell receive.hs生产者的核心逻辑非常精简send.hsmain do conn - openConnection 127.0.0.1 / guest guest ch - openChannel conn declareQueue ch newQueue {queueName hello, queueAutoDelete False, queueDurable False} publishMsg ch hello (newMsg {msgBody Hello World!, msgDeliveryMode Just NonPersistent}) BL.putStrLn [x] Sent Hello World! closeConnection conn这里体现了Network.AMQP的三个关键 APIopenConnection host vhost user password建立到 RabbitMQ 的连接openChannel在连接上打开一个信道Channel后续所有操作都在信道上进行declareQueue ch newQueue {...}声明队列queueName设为helloqueueAutoDelete为False队列在消费方断开后不自动删除queueDurable为False非持久化队列Broker 重启后消失。publishMsg ch hello (newMsg {...})中的第二个参数是交换机名称传入空字符串即使用默认交换机此时 routing key第三个参数hello就是目标队列名。消息通过newMsg构造msgBody指定消息体msgDeliveryMode Just NonPersistent明确该消息为非持久化投递。消费者receive.hs声明同一个队列后通过consumeMsgs注册回调consumeMsgs ch hello NoAck deliveryHandler -- waits for keypresses getLineconsumeMsgs ch queueName ackMode handler的第三个参数NoAck表示使用自动确认模式回调函数deliveryHandler :: (Message, Envelope) - IO ()收到(消息体, 投递元数据)二元组后用msgBody msg取出内容并打印。程序通过getLine阻塞等待按键防止 main 提前退出导致连接被关闭。教程二工作队列 —— 持久化、预取限制与手动确认对应文件newTask.hs任务生产者与 worker.hs任务消费者运行命令runhaskell newTask.hs hello world runhaskell worker.hs生产者newTask.hs与前例最大的区别是消息持久化publishMsg ch task_queue (newMsg {msgBody body, msgDeliveryMode Just Persistent})msgDeliveryMode Just Persistent会把消息标记为持久化投递配合 Worker 端对task_queue的持久化声明任务在 RabbitMQ 重启后仍能恢复。命令行参数通过getArgs读取并拼接为消息体bodyFor [] Hello, world!无参数时用默认值有参数时BL.pack . unwords $ xs将参数用空格连接。消费者worker.hs引入了三项针对任务处理的关键配置declareQueue ch newQueue {queueName task_queue, queueAutoDelete False, queueDurable True} qos ch 0 1 False consumeMsgs ch task_queue Ack deliveryHandlerqueueDurable True队列本身持久化配合消息持久化形成任务不丢失的完整链路qos ch 0 1 False设置 QoS 预取限制RabbitMQ 每次只向该消费者推送1条消息prefetch count 1避免某个慢消费者积压大量消息从而实现任务在多个 Worker 间的公平分发consumeMsgs ... Ack ...改用手动确认模式回调在处理完成后必须显式调用ackEnv metadata告诉 Broker本条消息已处理完成worker.hs。若 Worker 在处理过程中崩溃消息不会被确认会重新投递给其他消费者。回调中通过threadDelay (1000000 * n)模拟耗时任务其中n countDots body即消息体中.的个数BL.count .。例如发送runhaskell newTask.hs Hello........Worker 就会休眠约 8 秒——这正是教程用来演示负载均衡的方式。教程三发布/订阅 —— fanout 交换机与临时队列对应文件emitLog.hs日志生产者与 receiveLogs.hs日志消费者运行命令runhaskell receiveLogs.hs runhaskell emitLog.hs hello world这一套教程引入**交换机exchange**概念。生产者emitLog.hs声明了一个名为logs、类型为fanout的交换机logsExchange logs declareExchange ch newExchange {exchangeName logsExchange, exchangeType fanout, exchangeDurable False} publishMsg ch logsExchange (newMsg {msgBody body, msgDeliveryMode Just NonPersistent})fanout交换机会把收到的每条消息广播给所有绑定它的队列因此发布时 routing key 传空字符串即可被忽略。exchangeDurable False表示该交换机为非持久化。消费者receiveLogs.hs展示了临时队列 绑定的标准组合declareExchange ch newExchange {exchangeName logsExchange, exchangeType fanout, exchangeDurable False} (q, _, _) - declareQueue ch newQueue {queueName , queueAutoDelete True, queueDurable False} bindQueue ch q logsExchange queueName 由 Broker 生成随机唯一队列名如amq.gen-xxx每个消费者一个专属队列queueAutoDelete True消费者断开连接后队列自动删除bindQueue ch q logsExchange 将临时队列绑定到logs交换机。由于是 fanoutbinding key 同样为空字符串。declareQueue返回三元组(队列名, 消息数, 消费者数)这里用(q, _, _)只取队列名q供后续消费使用。这样每个消费者拿到的都是独立队列从而保证一条日志被广播给所有在线的日志接收者。教程四路由 —— direct 交换机与多 routing key 绑定对应文件emitLogDirect.hs 与 receiveLogsDirect.hs运行命令runhaskell receiveLogsDirect.hs info warn runhaskell emitLogDirect.hs warn a warning教程四把日志系统升级为按严重级别路由。生产者emitLogDirect.hs改用direct类型交换机发布时以第一个命令行参数作为 routing key即严重级别logsExchange direct_logs declareExchange ch newExchange {exchangeName logsExchange, exchangeType direct, exchangeDurable False} publishMsg ch logsExchange severity (newMsg {msgBody body, msgDeliveryMode Just NonPersistent})参数解析使用了Safe库的atMayseverityFor xs maybe info DT.pack (atMay xs 0)即默认严重级别为info消息体bodyFor xs maybe Hello world BL.pack (atMay xs 1)取第二个参数缺省为Hello world。消费者receiveLogsDirect.hs允许传入多个严重级别并为每个级别都建立绑定(q, _, _) - declareQueue ch newQueue {queueName , queueAutoDelete True, queueDurable False} forM_ severities (bindQueue ch q logsExchange . DT.pack)关键在forM_ severities (bindQueue ch q logsExchange . DT.pack)对命令行传入的每个严重级别如info、warn都调用一次bindQueue使同一个队列绑定多个 routing key。direct交换机的路由规则是routing key 精确匹配的队列才会收到消息。例如运行runhaskell receiveLogsDirect.hs info warn后该队列只会收到级别为info或warn的日志而error级别则被过滤。回调中通过envRoutingKey metadata取回该消息实际的路由 key打印为[x] warn:a warning的格式receiveLogsDirect.hs并调用ackEnv metadata完成手动确认。教程五主题 —— topic 交换机与通配符匹配对应文件emitLogTopic.hs 与 receiveLogsTopic.hs运行命令runhaskell receiveLogsTopic.hs info warn runhaskell emitLogTopic.hs warn a warning教程五将路由升级为主题匹配。生产者emitLogTopic.hs把交换机类型改为topic并将 routing key 设计为设施.严重级别的层级结构logsExchange topic_logs declareExchange ch newExchange {exchangeName logsExchange, exchangeType topic, exchangeDurable False} publishMsg ch logsExchange severity (newMsg {msgBody body, msgDeliveryMode Just NonPersistent})与教程四的区别在于默认 keyseverityFor xs maybe anonymous.info DT.pack (atMay xs 0)缺省值为anonymous.info默认设施anonymous 默认级别info。消费者端receiveLogsTopic.hs的队列声明与绑定逻辑和 direct 版完全一致(q, _, _) - declareQueue ch newQueue {queueName , queueAutoDelete True, queueDurable False} forM_ severities (bindQueue ch q logsExchange . DT.pack)区别全部体现在绑定 key 的语义上。topic交换机按点分单词的 routing key 做部分匹配binding key 中允许两种通配符*恰好匹配一个单词#匹配零个或多个单词。例如绑定*.warn可收到a.warn、b.warn等所有设施产生的 warn 日志绑定kern.*只收内核日志绑定#则接收全部日志。这也是为什么教程建议把 receive 端的info warn换成*.info #之类模式来体验更灵活的路由。与 direct 一样topic模式也支持对同一队列绑定多个 key 实现并集接收。教程六RPC —— 回调队列、correlation id 与同步调用对应文件rpcServer.hsRPC 服务端与 rpcClient.hsRPC 客户端运行命令runhaskell rpcServer.hs runhaskell rpcClient.hs教程六实现一个经典的 Fibonacci RPC客户端把fib(30)请求发到rpc_queue服务端计算后把结果发回客户端专属的回调队列。这是六套教程中代码量最大、最能体现Network.AMQP异步模型的一组。服务端[rpcServer.hs](https://link.gitcode.com/i/846ceb55720d83d9553df239409b79b1#L11-L46的核心qos ch 0 1 False declareQueue ch newQueue {queueName rpcQueue} m - newEmptyMVar consumeMsgs ch rpcQueue Ack $ handleRequest ch m putStrLn [x] Awaiting RPC requests takeMVar mrpcQueue rpc_queue是请求队列qos ch 0 1 False保证同一时刻只处理一个请求consumeMsgs ... Ack ...以手动确认模式消费请求用MVar让主线程阻塞在takeMVar m上程序常驻等待请求。请求处理函数handleRequestrpcServer.hs完整展示了 RPC 应答链路handleRequest ch m (msg, envelope) do n - readIO . BL.unpack . msgBody $ msg putStrLn $ [.] fib( show n ) let result fib n let response newMsg { msgCorrelationID msgCorrelationID msg , msgBody BL.pack . show $ result } publishMsg ch replyTo response ackEnv envelope where replyTo fromJust $ msgReplyTo msg关键点有三个replyTo从请求消息头msgReplyTo msg取出回调队列名即客户端的专属队列应答消息就发到这个队列msgCorrelationID把请求中的 correlation id 原样回填到应答消息供客户端关联请求与响应fib采用迭代实现fib n go n 0 1尾递归避免指数爆炸计算完成后publishMsg ch replyTo response经默认交换机投递到回调队列最后ackEnv envelope确认请求已处理。客户端[rpcClient.hs](https://link.gitcode.com/i/5646957a7cb39ff68e31001a006d7830#L30-L57封装了callFib ch queue n这一同步风格调用callFib ch queue n do cid - genCorrelationId rqn - declareReplyQueue let body BL.pack . show $ n let message newMsg {msgCorrelationID Just cid, msgReplyTo Just rqn, msgBody body} publishMsg ch queue message m - newEmptyMVar consumeMsgs ch rqn Ack $ handleResponse cid m res - takeMVar m return resgenCorrelationId用Data.UUID.V4的nextRandom生成 UUID 作为 correlation idtoText $ nextRandom保证全局唯一declareReplyQueue声明一个临时回调队列queueAutoDelete True, queueExclusive True服务端应答就发到这里请求发出后在回调队列上注册handleResponse cid m当收到的消息msgCorrelationId cid时解析结果并putMVar m res外层takeMVar m拿到结果——用MVar把异步消费包装成同步等待消息头msgCorrelationID、msgReplyTo都通过Just包装的Maybe传递读取时用fromJust取出这与服务端fromJust $ msgReplyTo msg形成对称。小结一份可运行、可复现的 Haskell AMQP 学习地图从 haskell/README.md 到仓库内的 12 个源文件整套教程覆盖了 RabbitMQ 最核心的六种消息模式同时也勾勒出Network.AMQP的完整使用轮廓教程交换机类型关键 API / 概念源文件Hello World默认交换机declareQueue、publishMsg、consumeMsgs NoAcksend.hs、receive.hs工作队列默认交换机queueDurable、msgDeliveryMode Persistent、qos、手动AcknewTask.hs、worker.hs发布/订阅fanoutdeclareExchange、临时队列、bindQueueemitLog.hs、receiveLogs.hs路由directrouting key 精确匹配、多 key 绑定forM_bindQueueemitLogDirect.hs、receiveLogsDirect.hs主题topic*/#通配符、层级 keyemitLogTopic.hs、receiveLogsTopic.hsRPC默认交换机replyTo、correlationId、MVar同步封装rpcServer.hs、rpcClient.hs需要留意的是Network.AMQP在 vhost、队列/交换机的持久化、确认模式等参数上的语义均与 AMQP 0-9-1 协议一致示例默认连接127.0.0.1上使用默认配置的 RabbitMQ。若你的 Broker 不在本机或启用了 TLS、修改过默认账号需要相应调整每个文件中的openConnection参数。上手时建议按教程一到六的顺序逐个运行先起消费者再起生产者观察终端输出即可直观验证每种消息模式的路由行为。若需进一步学习协议层面的设计与概念可参考仓库根目录的 README.md 了解各语言版本的全貌并结合 RabbitMQ 官方文档阅读本仓库仅提供可运行代码概念讲解请查阅官方教程站点。赞分享示例工程【免费下载链接】rabbitmq-tutorialsTutorials for using RabbitMQ in various ways项目地址https://gitcode.com/gh_mirrors/ra/rabbitmq-tutorials点击查看免费下载相关推荐PDF.js 官方 Examples 指南从 Hello World 到完整页面渲染的实战教程PDF.js 官方 Examples 指南从 Hello World 到完整页面渲染的实战教程 本篇技术指南以 PDF.js 官方文档 Examples 篇前端ReScript 官方项目模板入门从 npm install 到 Hello World 的完整实战指南ReScript 官方项目模板入门从 npm install 到 Hello World 的完整实战指南 本指南以 ReScript 官方 starter 模编译器编程语言开发工具GCDWebServer终极实战指南从Hello World到企业级应用完整教程GCDWebServer终极实战指南从Hello World到企业级应用完整教程 GCDWebServer 是iOS、macOS和tvOS平台上排名第一的轻量后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

银行排队系统实战:链式队列与最小堆事件驱动调度设计

银行排队系统实战:链式队列与最小堆事件驱动调度设计

简介:一份面向数据结构期末作业的银行排队系统完整实现,适合正在学习队列、需要完成课程设计或备战考试的学生。项目以VIP与普通用户的不同优先级为切入点,用实际案例串联起队列基础、STL queue用法和多队列调度等知识点。压缩包共9个文件&am…

2026/10/15 18:19:31 阅读更多 →
Android Dialog蒙板原理与深度定制指南

Android Dialog蒙板原理与深度定制指南

1. 项目概述:为什么一个弹框背景色会让人反复调试到凌晨两点Android开发里,Dialog弹框之外的区域默认是半透明黑色(#80000000),这个设计本意是突出焦点、弱化背景干扰。但实际项目中,它几乎成了每个中高级开…

2026/10/15 18:18:30 阅读更多 →
OpenCV人脸识别实战:Haar级联检测与LBPH身份识别完整教程

OpenCV人脸识别实战:Haar级联检测与LBPH身份识别完整教程

1. 整体设计与方案选型先说结论:用 OpenCV 和 Python 做一套能识别具体身份的人脸识别系统,不一定要上深度学习框架。我这次实战项目选的是 OpenCV 自带的 Haar 级联做人脸检测,再用 LBPH 识别器做身份判断,全程在 CPU 上跑&#…

2026/10/15 18:18:30 阅读更多 →

最新新闻

目标检测后处理:IOU与NMS从原理到工程化实战

目标检测后处理:IOU与NMS从原理到工程化实战

做目标检测的朋友都知道,模型跑通只是第一步,真正决定最终效果上限的,往往是两段看起来很不起眼的计算:IOU与NMS。IOU负责衡量两个检测框到底重合成什么样,NMS负责把同一目标周围那些重复的、多出来的框“压”下去。无…

2026/10/15 21:19:30 阅读更多 →
Docker Compose部署WeKnora:从环境规划到上线运维的完整指南

Docker Compose部署WeKnora:从环境规划到上线运维的完整指南

我第一次帮人部署WeKnora时,对方给的服务器上已经跑了七八个业务,系统里Python和Node版本乱成一锅粥。当时我们几乎没有犹豫,直接用Docker部署WeKnora,把服务、数据库、缓存全部容器化隔离,不到半天就正常跑起来&#…

2026/10/15 21:19:30 阅读更多 →
500k长上下文实战:Codex与ChatGPT Work工作流重构指南

500k长上下文实战:Codex与ChatGPT Work工作流重构指南

直接说结论:从16k到128k,再到200k,然后跳到500k,这个数字看着只是“变大了”,但真正用起来你会发现,这根本不是同一个物种。我花了几个晚上把 Codex 和 ChatGPT Work 里的长上下文工作流重新跑了一遍&#…

2026/10/15 21:19:30 阅读更多 →
TxBENCH硬盘检测全攻略:性能测试、SMART健康与翻新盘识别

TxBENCH硬盘检测全攻略:性能测试、SMART健康与翻新盘识别

简介:TxBENCH 电脑及硬盘检测工具是一套面向电脑 DIY 爱好者、硬件评测人员及普通用户的 SSD 检测资源,覆盖基础读写测试、大文件拷入高级测试、安全擦除与驱动信息查看等核心功能,可帮助判断硬盘性能是否达到预期,并兼顾旧盘数据…

2026/10/15 21:19:30 阅读更多 →
Halcon+MFC工业模板匹配实战:从环境搭建到产线鲁棒部署

Halcon+MFC工业模板匹配实战:从环境搭建到产线鲁棒部署

简介:本资源是一个基于Halcon与MFC联合开发的模板匹配实战Demo,面向具备C基础和图像处理入门经验的Windows桌面应用开发者,解决工业视觉中目标定位、多尺度形状识别与灰度匹配等典型需求。项目完整实现形状匹配、形状缩放匹配及灰度匹配三类核…

2026/10/15 21:19:30 阅读更多 →
MySQL零基础入门:从安装到增删改查实战教程

MySQL零基础入门:从安装到增删改查实战教程

写这篇教程的初衷很简单——我见过太多人一上来就啃官方文档,结果被术语劝退;也见过不少人背了一堆命令,却连数据库都没装好。MySQL作为最流行的开源关系型数据库,它其实没有传说中那么难,难的是没人告诉你第一步该干嘛…

2026/10/15 21:18:29 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →