NVMe读延迟trace分析:从事件时间线到瓶颈定位
1. NVMe读命令的延迟地图先搞清楚延迟花在哪trace才有意义1.1 一条读命令从应用到NAND的完整链路很多刚接触NVMe性能分析的朋友一上来就抓trace结果面对几十万条事件记录完全不知道先看哪里。我先说句实话NVMe读命令的trace分析真正的难点不在工具而在你是否清楚一条读请求在Linux系统里到底走了多少站。以最常见的场景为例一个进程调用read()去读/dev/nvme0n1p5上的4KB数据。请求先进入VFS层接着被文件系统xfs/ext4/btrfs等处理映射成块地址后生成bio提交给块层的blk-mq多队列框架。块层会根据CPU编号选择软件队列再经过可选的IO调度器最终把请求送到NVMe驱动的硬件队列SQ/CQ队列对。驱动将命令写入提交队列写一次doorbell寄存器通知SSD开始干活。SSD内部经过FTL映射寻址、读NAND闪存页、纠错、拉数据把结果放到完成队列并触发MSI-X中断CPU的中断处理函数、软中断、块层回调、VFS回调依次执行最后read()带着数据返回用户态。这里每一个环节都会消耗时间。NVMe最迷惑人的地方在于它太快了快到单个环节几微秒的异常都会被放大成明显的性能抖动。我在实测中遇到过很多次应用侧看到的p99读延迟从80us恶化到200us但SSD自身标称延迟几乎没变问题完全出在中断、队列或调度上。不画清楚这条路径图你抓到trace也无从下手。1.2 正常读延迟的构成比例我自己压过不少NVMe盘也拆过上千条读命令的trace。用一句话概括正常情况下的延迟分布设备内部占大头软件栈占小头但软件栈的绝对值不容忽略。以一块普通的PCIe 4.0 M.2消费级SSD、4KB随机读、队列深度1为例实测典型延迟构成大致如下环节典型耗时说明VFS 文件系统 page cache处理5 ~ 15us受锁竞争、元数据操作影响较大块层排队 调度2 ~ 8us调度器非none时会更高NVMe驱动构建命令 doorbell写入2 ~ 5usMMIO写后需要等待PCIe posted完成PCIe传输下发 返回1 ~ 3us与PCIe速率和payload大小有关SSD内部读FTL NAND 固件50 ~ 80us主导项消费级TLC/QLC普遍在此区间中断触发 中断处理 完成回调3 ~ 10us中断合并策略影响很大加起来大概70 ~ 120us正好是很多人用fio测出来的4KB随机读延迟区间。这里我想强调一个反直觉的点很多优化文章一上来就让你调内核参数但如果你抓trace发现SSD内部耗时已经占了85%以上那调软件栈等于白费力气。反过来如果软件栈占比超过30%那就得警惕了——此时大概率存在调度器排队、中断合并等待或队列资源争抢。trace分析的第一价值就是把设备慢和路径慢这两件事分开。1.3 设备慢与路径慢的判别方法判别方法其实很简单读命令的时间戳分成四段——块层下发前后、驱动提交前后、设备完成中断后、块层完成回调后。看哪一段异常放大。段1下发前从block_rq_insert到block_rq_issue如果这里长时间滞留给调度器或队列。段2驱动提交从block_rq_issue到写doorbell如果卡住通常是队列满或IOMMU/映射问题。段3设备内部从doorbell到CQ中断到达这是SSD固件和NAND的真实耗时。段4完成路径从中断到达block_rq_complete看中断合并和软中断是否拖慢。我见过最典型的误判案例一台服务器上跑数据库NVMe读延迟p99从90us涨到250usDBA怀疑SSD坏了一查smart-log完全正常。我抓trace一看段3只从60us涨到70us真正的放大在段1——块层的某个软件队列出现了严重的不均衡大量请求堆在同一颗CPU上排队。把它归到设备故障就是完全找错了方向。2. 看懂nvme0n1p5设备拓扑与命令追踪的对应关系2.1 命名规则再梳理控制器、命名空间、分区先解决一个最基础但最容易搞混的问题。/dev/nvme0n1p5到底是什么我看到不少人在社区里问nvme0n1p5是不是第5个NVMe硬盘这里必须纠正不是。Linux下NVMe设备命名分三级/dev/nvme0这是控制器Controller你的SSD通常对应一个PCIe物理设备。/dev/nvme0n1这是命名空间Namespace可以理解为SSD内部的一个逻辑块设备。绝大多数消费级SSD只有一个namespace所以nvme0n1就是第一块NVMe盘的默认块设备。/dev/nvme0n1p5这是nvme0n1上的第5个分区不是第5块盘。用lsblk看最直观# lsblk nvme0n1 259:0 1.8T 0 disk ├─nvme0n1p1 259:1 512M 0 part ├─nvme0n1p2 259:2 2G 0 part └─nvme0n1p5 259:5 500G 0 part分区编号跟着分区表走p5就是第5个分区条目。顺带一提在blktrace里你会看到设备号比如259:5其中主设备号259是Linux动态分配给NVMe设备组的次设备号才是区分控制器的关键。用cat /sys/block/nvme0n1p5/dev可以查到对应设备号。2.2 从trace事件字段反查设备路径抓trace时你会遇到一个尴尬情况blkparse输出里只有主次设备号如259,5没有设备名。怎么和/dev/nvme0n1p5对上号方法很简单打开/sys/block/*/dev逐一对# cat /sys/block/nvme0n1/dev 259:0 # cat /sys/block/nvme0n1p5/dev 259:5所以blktrace里出现259,5就是分区nvme0n1p5259,0是整块盘。我建议你在抓trace之前把目标设备和分区的设备号都记下来后面分析会顺手得多。这里还要提醒一句blktrace可以直接针对分区抓比如blktrace -d /dev/nvme0n1p5。但如果你后续要用trace的block_rq_insert事件和文件系统的行为关联建议直接整盘抓过滤时再按设备号区分。分区一级的trace会丢掉文件系统层的信息不利于完整链路分析。2.3 多命名空间和远端盘场景的额外复杂度如果你的环境不是单盘单命名空间而是企业级SSD开了多个namespace或者通过NVMe over Fabrics连了远端存储trace事件里就会多出一些字段比如nsid命名空间ID、qid队列ID、cid命令ID。多namespace场景下同一个控制器上不同namespace的性能特性可能完全不同——有的namespace是SLC模式、有的跑QLC。抓trace时除了看设备号还要在nvme驱动事件里看nsid是否和目标盘一致避免把两个命名空间的延迟混在一起。NVMe over Fabrics场景更复杂。主机侧抓到的nvme驱动事件只是本地发起实际读命令要封装成RDMA报文传到target再在target侧进入另一个完整的存储栈。两端的trace是分开的延迟差异对照才能定位是网络还是target盘的问题。这个展开讲又是一篇文章本文先聚焦单机本地盘的场景。3. 四类trace工具的选择逻辑不是所有场景都要上eBPF3.1 ftrace和trace-cmd看软件路径最直接工具不在多在于你清楚每个视角能看到什么。我日常用得最多的组合是ftrace事件 blktrace偶尔用perf做统计特殊场景才写bpf脚本。下面逐个讲清楚。ftrace最直接的价值是看事件序列和函数的调用路径。新版内核把块层和NVMe驱动层的tracepoint都暴露出来了直接可用trace-cmd record -e block:* -e nvme:* -e irq:irq_handler_entry -e irq:irq_handler_exit -e sched:sched_switch sleep 10这里最有用的是nvme驱动自己的事件位于/sys/kernel/debug/tracing/events/nvme下nvme_setup_cmd记录命令初始信息包括qid、cid、opcode、nsid、LWBA逻辑块地址。nvme_complete_rq记录命令完成信息包括qid、cid、status、结果长度。这两个事件配合block层的block_rq_insert / block_rq_issue / block_rq_complete基本就能拼出一条读命令从块层到驱动的完整时间线。而且ftrace每个事件自带时间戳精确度足够。有人会问为什么不用eBPF我承认bpf能干更多事比如自定义聚合、上下文关联。但对大多数人来说内核自带tracepoint已经覆盖了90%的NVMe读分析场景。bpf脚本写起来容易调试和内核版本适配却麻烦。不是所有场景都要上eBPF——先用最稳的工具建立基线再考虑更强的工具。3.2 perf长时长延迟分布统计perf的优势在于开销低、适合大样本统计。比如你想看整块盘一小时的读延迟分布用perf记录块层完成事件和下发事件然后后处理两者时间差perf record -e block:block_rq_issue -e block:block_rq_complete -a sleep 3600 perf script trace.txt脚本里按设备号过滤把每个IO的完成时间减下发时间就能画出延迟直方图。perf record的开销比blktrace低不少生产环境短时间抓取时更安全。不过perf的事件上下文不如blktrace丰富它看不到队列深度、合并情况这些细节定位根因时可以作为辅助手段。3.3 blktrace和blkparse块层IO的黄金标准如果想看块层完整行为blktrace依然是绕不过去的工具。它跟踪的每个IO事件都有动作码新手看到0,123这种输出很容易晕。我整理一个常用动作码表供查阅动作码含义分析价值QIO进入队列request queued文件系统/bio提交入口G从请求池获取request可以看request分配是否有压力M / F后向/前向合并合并多顺序性好随机读通常少Irequest插入调度队列调度器处理起点Drequest下发到驱动dispatch块层提交给NVMe驱动的时刻P / U插件plug / 拔掉unplug看批量延迟的成因CIO完成complete块层看到完成的时刻X请求拆分split大IO被硬件限制拆分的信号一条完整的读逻辑如下Q -M/F- I - D - ……设备处理…… - C。D和C的时间差大致反映驱动设备的耗时Q和D的差反映块层排队。实际命令也简单blktrace -d /dev/nvme0n1 -a read -o bt blkparse -i bt.blktrace.0 -o bt.txt加上-a read只跟踪读请求能少掉不少写请求的噪声。blktrace确实会带来不小的CPU开销高队列深度生产盘上动辄丢事件这一点心里有数就行。3.4 工具选型对照表直接给一张表帮你根据场景快速决定用哪个分析目标首选工具理由看一条读命令的软件路径trace-cmdftrace事件事件齐、时间戳准、能看函数栈统计长时间延迟分布perf record 后处理开销可控样本量大看块层排队/合并/下发细节blktrace blkparse动作码语义最丰富查命令状态码和命令级异常trace-cmd抓nvme:*事件能看到qid/cid/status字段深度自定义聚合bpftrace / bcc脚本灵活但维护成本高工具形状清楚了下一步就是实战。4. 一次读命令的trace实战拆解从下发到完成的事件时间线4.1 一组可复现的抓取命令纸上谈兵没意思我直接给一组我常用来抓读trace的命令组合。环境是Linux 6.x内核、memblaze/三星这类企业盘或消费级盘都能用。准备工作确认内核有tracefs挂载mount -t tracefs tracefs /sys/kernel/tracing。然后抓取块层、NVMe驱动、中断三个维度的事件trace-cmd record -e block:block_rq_insert \ -e block:block_rq_issue \ -e block:block_rq_complete \ -e nvme:nvme_setup_cmd \ -e nvme:nvme_complete_rq \ -e irq:irq_handler_entry \ -e irq:irq_handler_exit \ -e sched:sched_switch -o nvme_trace.dat \ -- sleep 30另开一个终端用fio制造4KB随机读压力fio --namerandread --filename/dev/nvme0n1p5 \ --rwrandread --bs4k --iodepth1 --ioenginelibaio \ --direct1 --time_based --runtime20 --numjobs1这里刻意用iodepth1、direct1队列深度1能清晰看到每条命令的时间线不至于乱序direct绕过page cache保证请求真正下发到设备。分析完如果想让trace里的事件更密集再把iodepth提到16或32。4.2 事件时间线的标准读法抓完后用trace-cmd report nvme_trace.dat提取一条典型读命令。我简化一个真实例子关键字段看时间戳和函数名fio-12345 [002] d... 123.456789: block_rq_insert: 259,5 R 4096 () fio-12345 [002] d... 123.456792: block_rq_issue: 259,5 R 4096 () fio-12345 [002] d... 123.456795: nvme_setup_cmd: vn... qid2 cid128 nsid1 opcode0x02 SSD内部访问NAND等待约60us irq-0 [005] d.h. 123.456858: irq_handler_entry: irq47 namenvme0q2 irq-0 [005] d.h. 123.456860: nvme_complete_rq: qid2 cid128 status0 irq-0 [005] d.h. 123.456863: block_rq_complete: 259,5 R 4096 () fio-12345 [005] d..1 123.456865: (read return)把这几个时间点连起来看insert到issue3us块层几乎没排队符合queue深度1预期。issue到setup_cmd3us驱动构建命令很快。setup_cmd到irq_handler_entry63us这是设备真正干活的时间包含FTL映射、NAND读、固件调度、PCIe DMA回传。这个值就是你盘在这条命令上的真实介质延迟。irq_handler_entry到block_rq_complete3us中断处理加块层回调很快说明没有中断合并或合并数值很小。完整延迟76us左右。正常。读trace的时候我会在脑子里反复对照这条命令在哪个环节停留最久。上面的例子很健康但实际抓trace时你经常看到的是下面这些异常模式。4.3 从trace看三个异常模式模式一insert到issue明显拉长从3us变成300us甚至更长。这说明请求在块层排队通常伴随队列深度过高或某个软件队列的CPU被其他任务抢占。我在第5章会详细说。模式二irq_handler_entry到block_rq_complete长达20~50us。这往往不是中断处理本身慢而是NVMe中断合并策略在作祟。固件可能攒了一批完成条目才发一次中断单个IO的可见延迟就被拖高了。低队列深度、追求极低延迟的场景下这是最让人头疼的问题之一。模式三nvme_complete_rq事件里status字段不是0。status0表示成功非0就要查协议状态码了。常见的有0x401内部错误、0x2命令超时/中止、0x80固件拒绝。看到非0的status先去看SSD的smart-log和error-log这通常是设备侧问题的强信号。4.4 一次真实定位过程莫名高到200us的读延迟上个月我给一台数据库服务器做读延迟排查现象是fio的4K随机读p50只有80usp99却飙到200usCPU也不高盘也没报错。我按老套路抓了trace重点挑出p99那批慢命令看时间线分布。结果惊讶地发现这批慢命令的block_rq_insert到block_rq_complete总时长都超过180us但其中nvme_setup_cmd到nvme_complete_rq只有65us左右——设备很正常。问题出在哪慢命令的block_rq_insert发生在CPU3上而block_rq_issue却跑到了CPU7上中间又出现了一大段sched_switch事件证明请求的软中断或块层处理被打断了多次。进一步看是因为当时另一组IO压力把CPU7的kworker占满NVMe的完成处理被延迟调度。最终结论这不是NVMe的问题是宿主机上CPU噪声导致的调度延迟。这个案例值得记住trace里如果出现大量sched_switch事件夹在IO事件中间说明IO处理线程被反复抢占延迟大头根本不在存储设备。5. 读延迟瓶颈定位从trace结果反推优化方向5.1 案例一队列深度上不去读延迟随iodepth恶化有一次压测我把fio的iodepth从1提到64总IOPS没怎么涨平均延迟翻了三倍。一开始怀疑SSD固件调度不行抓trace发现每条读命令的设备内耗时一直稳定在70us上下根本不是盘的问题。再细看traceblock_rq_insert的CPU分布严重偏斜——几乎全部落在CPU2和CPU6上。原因是我们这台机器开了很多cgroup、大量IRQ绑定在同一组CPU上blk-mq的软件队列派发策略没能把负载摊开。NVMe本来就是多队列设计每队列对应一条CPU路径当所有软件队列都映射到少数CPU时并发上不去是必然。解决办法也不复杂确认NVMe驱动的irqbalance/affinity_hints已生效/proc/irq/*/smp_affinity_list对照检查华为/Intel等不少驱动都有irqpoll或者poll_queues参数轮询模式在高IOPS场景下效果明显如果盘支持多队列让fio或应用多用几个线程别把所有IO压到单线程单队列。从trace里看到的第一信号永远是请求的CPU分布是否均匀。压NVMe读性能先看这个比调什么内核参数都直接。5.2 案例二中断合并策略把低延迟场景带沟里NVMe控制器普遍支持中断合并interrupt coalescing作用是攒多个完成条目再统一发中断减少CPU打断次数。高吞吐场景这是好功能但在追求极低单IO延迟的场景它就是毒药。有次我在一个低延迟存储项目里读延迟指标要求p99 100us。抓trace发现ns设备内耗时近70us中断合并再吃掉15~20us直接爆指标。查当前固件配置nvme get-feature /dev/nvme0 -f 0x8 -c 0返回值里带coalescing time和coalescing threshold。按需关闭或调低nvme set-feature /dev/nvme0 -f 0x8 -v 0 -c 0这里-v 0是把合并时间调成0也就是来一条完成条目就立刻发中断。改完再抓traceirq_handler到block_rq_complete的间隔肉眼可见地缩小。代价是中断次数上升、CPU占用增加但低延迟场景下这点代价换p99大幅下降完全值得。当然不同厂商的参数语义略有差异改之前建议用nvme id-ctrl看一下固件支持的feature说明并在低峰期操作。5.3 案例三调度器和直接IO对读路径的影响之前遇到一个更隐蔽的情况业务用的是ext4文件系统读文件而非裸设备trace里block_rq_insert到block_rq_issue的耗时占到总延迟的30%以上。一开始怀疑文件系统锁竞争抓trace看线程上下文发现request在调度队列里排队。查/sys/block/nvme0n1/queue/scheduler发现是mq-deadline而不是none。NVMe这类高性能设备默认调度器在多数场合是none也就是noop。如果系统被配置成mq-deadline或bfq即使顺序读也可能引入不必要的排队、合并和电梯算法开销。改回来echo none /sys/block/nvme0n1/queue/scheduler改完看下一轮traceinsert到issue从60us降到3us读延迟整体降了20%以上。不过要注意一点如果你的盘是分区上面挂LVM、软RAID或md设备块层的路径又多了一层切换调度器的影响就要重新评估。这恰恰说明trace分析不能只看最终数值得回到你的存储拓扑中去理解每一层到底做了什么。5.4 从trace沉淀一套自己的分析方法工具说再多不沉淀成流程都白搭。我现在的日常流程基本固定先抓10分钟基线trace覆盖空闲和正常负载针对每个慢IO按第4章的时间线拆成块层驻留、驱动提交、设备处理、中断处理四段把四段耗时按百分位统计找出哪一段在p99放量定位到具体段后对照CPU分布、调度切换、中断合并、队列深度逐一排查修改配置后重复抓trace对比而不是只看fio的最终数字。这个过程看起来简单但帮我定位过的问题包括CPU噪声导致的调度延迟、固件奇怪GC策略、BIOS里PCIe ASPM没关造成的传输跳变、甚至NUMA远端访问导致的门铃写入变慢。每次都是trace里的一个细节指针把我引到根因上。写在最后先建立基线再谈优化顺着这个话题再多说一句。我见过不少人抓trace五分钟就下结论盘有问题回去把设备一换问题依旧。真正靠trace吃饭的人都明白单条慢命令说明不了任何问题你需要先建立这台设备、这套配置下的正常形态——包括稳定延迟、队列分布、中断耗时区间。有了基线任何偏离都能被快速放大和定位。如果看完这篇你觉得抓trace太麻烦那我建议你用一个折中方案日常关注/sys/block/nvme0n1/stat里的平均耗时和nvme smart-log的媒体温度、寿命、温度上限这些指标不用trace也能反映设备健康度。但一旦出现平均延迟正常、尾延迟却飙高的案例别犹豫把trace-cmd那组命令跑起来你会看到延迟藏在存储栈的哪个角落里。

相关新闻

UE4反射系统深度解析:从UHT编译期代码生成到运行时类型注册全链路

UE4反射系统深度解析:从UHT编译期代码生成到运行时类型注册全链路

1. 从一个让人抓狂的编译错误说起如果你在UE4里写过C,大概率遇到过这种场景:头文件里加了一个UPROPERTY()宏,编译通过,编辑器里也能跑,但当你试图在反射层面拿到这个属性的元数据时,发现它压根不存在。或者…

2026/10/14 7:48:43 阅读更多 →
洛谷P1114非常男女:前缀和与哈希映射求解最长平衡区间

洛谷P1114非常男女:前缀和与哈希映射求解最长平衡区间

洛谷P1114这道“非常男女”计划,我第一次读题时还以为是道关于配对的模拟题,点进去才发现它是一道很经典的前缀和练手题,在各大OJ和算法入门清单里都常驻。题目本身不复杂,但能从一个“统计男女数量相等的最长连续区间”的问题里&…

2026/10/14 7:48:43 阅读更多 →
单片机毕设选题推荐:基于WIFI的智能大称量体脂秤远程数据管理系统设计 基于单片机的身高体重体脂率测量与远程监控装置设计(032503)

单片机毕设选题推荐:基于WIFI的智能大称量体脂秤远程数据管理系统设计 基于单片机的身高体重体脂率测量与远程监控装置设计(032503)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/10/14 7:48:43 阅读更多 →

最新新闻

CMS技术演进:从静态生成到云原生架构

CMS技术演进:从静态生成到云原生架构

1. 内容管理系统的前世今生1993年,伊利诺伊大学的学生们为了管理NCSA官网的新闻更新,编写了一个简单的网页发布脚本。这个看似不起眼的工具,后来被公认为世界上第一个内容管理系统(CMS)的雏形。当时没人能预料到&#…

2026/10/14 10:45:54 阅读更多 →
agent-skills 实战:从零构建可靠的 AI Agent 能力体系

agent-skills 实战:从零构建可靠的 AI Agent 能力体系

1. 从零理解 agent-skills:它到底是什么,为什么值得关注 第一次看到 “agent-skills” 这个词,很多人会下意识把它当成某个具体框架或者某个开源库的名字。但如果你最近在关注 AI 应用开发这个圈子,会发现它其实更像是一个正在快速…

2026/10/14 10:45:54 阅读更多 →
收藏 | 超详细解析LLM与Agent,小白也能轻松入门AI开发

收藏 | 超详细解析LLM与Agent,小白也能轻松入门AI开发

本文系统介绍了LLM(大型语言模型)和AI Agent的核心概念、特点及区别。LLM是经过海量文本训练的神经网络,擅长预测文本序列,但知识静态、被动响应。AI Agent则以LLM为核心,能自主规划、调用工具、自我优化,完…

2026/10/14 10:45:54 阅读更多 →
从AI设计到CAD绘制与Bug检测:开源工具实操指南

从AI设计到CAD绘制与Bug检测:开源工具实操指南

过去两年我一直在留意一个趋势:AI 已经不是只会在聊天框里写东西了,而是真的开始进入那些需要“职业手活”的岗位。最有代表性的三个方向,就是标题里说的这三个——AI 当设计师、AI 画 CAD、AI 测 Bug。对应到开源社区里,我也确实…

2026/10/14 10:45:54 阅读更多 →
神经网络前向传播详解:从手算到Python代码实现

神经网络前向传播详解:从手算到Python代码实现

开头这200来字我得说明白一件事:很多人学神经网络,一上来就被反向传播劝退,看了一堆偏导数、链式法则就开始怀疑人生。其实大可不必。我见过太多初学者最后能啃下深度学习,靠的不是一开始就把梯度背下来,而是老老实实把…

2026/10/14 10:45:54 阅读更多 →
Shell脚本多行注释技巧与工程实践

Shell脚本多行注释技巧与工程实践

1. Shell脚本多行注释的必要性与挑战 在Bash和KornShell(KSH)脚本开发中,我们经常遇到需要临时禁用大段代码或添加详细说明文档的情况。与大多数编程语言不同,Shell脚本原生并不支持类似C语言的/* */或Python的 这样的多行注释语法…

2026/10/14 10:44:53 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →