零拷贝技术解析:从传统I/O到sendfile与splice的完整链路
零拷贝zero-copy在Linux面试和性能调优里几乎是必考题。我自己在给文件上传下载、日志采集、网关转发这类服务做优化时也经常被问到你这里为什么用sendfile为什么数据还是慢每次解释都要从头讲read和write在内核里到底搬了几次数据。今天干脆把这块完整地写一遍从传统I/O路径开始把mmap、sendfile、splice、copy_file_range逐个拆开连同验证手段和坑也一并交代清楚。新手可以当内核I/O入门读有经验的人可以直接跳到第三节和第五节看选型与排错。这篇文章不涉及太偏门的内核细节重点是把“数据到底怎么从磁盘到网卡”这条主链路讲透让你在面试、代码评审、线上问题排查时都能用得上。1. 零拷贝解决的问题先看 read()write() 为什么贵1.1 一条数据从磁盘到网卡的完整旅程想象一个最常见的文件下载服务用户请求一个文件服务进程把磁盘上的文件读进来再写到socket上发给客户端。用最简单的read/write实现这一整条链路在Linux内核里至少经历以下几个阶段。第一进程调用read()CPU从用户态切到内核态内核发现文件内容还没进page cache于是向块设备层发出I/O请求磁盘控制器通过DMA把数据搬进内核的页缓存page cache。这个过程中CPU不参与实际搬运但需要等待DMA完成。第二内核把页缓存中的数据拷贝到用户态缓冲区。这一步是CPU参与的memcpy真正占CPU周期。第三read()返回CPU切回用户态进程处理完这堆字节后调用write()CPU又切到内核态。内核把用户态缓冲区里的内容拷贝到socket发送缓冲区。这一步同样是一次CPU参与的memcpy。第四网卡控制器通过DMA从socket发送缓冲区把数据读走发到网络上write()返回CPU再切回用户态。可以看到一次文件发送理想情况下也有两次DMA往返、两次CPU参与的memcpy外加至少四次用户态/内核态切换。如果把“用户态处理”也算进去数据的路径是先到内核页缓存再到用户态缓冲再回到内核socket缓冲绕了一个大圈子。1.2 两次 CPU 拷贝才是真正的瓶颈很多同学以为慢的是磁盘或网络但在高带宽、低延迟场景下真正吃性能的往往就是那两次CPU拷贝。DMA搬数据不占CPUmemcpy占。而且memcpy不仅消耗CPU周期还会污染L1/L2 cache影响这台机器上其他进程的计算性能。如果以10Gbps网卡满速转发文件来算相当于每秒要搬1.25GB数据。普通服务器内存带宽在几十GB/s看起来还够但如果同样的数据被memcpy搬两遍甚至三遍再加上进程调度、cache失效、上下文切换CPU很快就会成为瓶颈。这也是为什么压测时你看到一个代理进程的CPU先跑到100%而磁盘和网卡都只有30%左右多半就是拷贝路径没优化。我通常在给团队讲这个时会做个比喻readwrite方案里应用层用户缓冲区就是一个“搬运工的中转站”数据本来可以直接从仓库页缓存发车网卡非要先卸到马路边的临时堆场再重新装车。中转站本身不产生价值还占用劳动力CPU。1.3 用户态缓冲区在两端的角色这里要澄清一个容易误会的点并不是所有程序都不该碰数据。如果进程要对文件做压缩、加密、格式转换、协议解析数据必须经过用户态CPU拷贝是躲不掉的。零拷贝优化的前提是“data path”上应用只是一个搬运工对内容不感兴趣。CDN回源、文件服务器、日志转发、内存型网关都符合这个前提。在这些场景里用户态缓冲区存在的唯一意义是让read()和write()有地方放数据它对业务没有任何价值。零拷贝的思路就是把这个中转站拆掉让内核直接完成从页缓存到网卡或者从一个fd到另一个fd的数据转移。2. “零”到底省了什么CPU 拷贝、DMA 拷贝与上下文切换2.1 三种开销要分开算“零拷贝”这个说法容易让人误以为所有复制开销都变成0其实不是。要把三类成本分开看。一类是CPU参与的拷贝比如从page cache到用户态缓冲、从用户态缓冲到socket缓冲区。这类拷贝占用CPU周期最值钱零拷贝主要消灭的是它。另一类是DMA拷贝比如从磁盘到页缓存、socket缓冲区到网卡。DMA由硬件控制器完成不消耗CPU周期但会占用内存带宽和I/O总线资源零拷贝一般不会消灭DMA除非像某些文件系统内部reflink那样连数据物理复制都省了。第三类是系统调用与上下文切换。每次read/write都涉及用户态切内核态再切回syscall本身有开销频繁调用时不可忽略。零拷贝实现往往还能顺带减少syscall次数和上下文切换次数因为少了用户态缓冲这个中间环节。有个经验值可以作为粗略参考一次上下文切换在几十微秒量级一次CPU memcpy搬运大块数据时每GB的数据搬运要消耗几百毫秒CPU时间量级。两个都不算便宜但在高性能转发服务里前者随调用次数增长后者随数据量增长优化时两个维度都要看。2.2 什么时候“零拷贝”收益最大收益最明显的是这三类场景大文件重复发送、高吞吐网络转发、以及数据只在设备间迁移时。比如一个文件服务器反复往外发同一个热门文件这个文件大概率一直在page cache里sendfile一下就把两次CPU拷贝消掉效果立竿见影。收益一般但有价值的是数据量中等、但系统调用频率很高的场景比如日志采集器把内容从磁盘搬到网络。splice在这种场景下能把多次read/write循环收敛为少数几次splice调用减少切换开销。收益不明显甚至负收益的是单次传输小于几百字节的小请求。比如大量短消息、状态查询类接口系统调用和网络往返本身才是瓶颈零拷贝省下的那点拷贝成本可以忽略反而增加了代码复杂度和调试成本。2.3 零拷贝不等于零开销有一说一零拷贝也有隐藏成本。第一page cache是内存换速度文件越多越占内存内存不足时反而引发回收压力。第二sendfile/splice依赖页缓存命中如果文件刚写完还没回写或者被回收了触发磁盘DMA等待仍会有延迟。第三内核里对页的引用计数、skb结构管理、页面碎片整理这些操作虽然比memcpy便宜但并不是零。所以我的判断标准很简单如果你的CPU已经在拷贝上烧得厉害数据路径又不需要应用修改内容那么零拷贝是值得上的如果还没压到瓶颈先把缓冲区大小、连接数、日志频率这些常规参数调一调收益可能更直接。3. 四种常用实现与选型3.1 mmap write省一次用户态中转mmap的字面意思是把文件映射到进程地址空间。映射之后进程可以像访问数组一样读写文件数据实际还是在page cache里通过缺页异常按需加载。用mmapwrite做文件转发时代码大概是这样的char *addr mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0); write(sockfd, addr, file_size); munmap(addr, file_size);相比read/write这里省掉了“page cache到用户态缓冲区”的那次CPU拷贝因为应用拿到的地址直接指向页缓存。注意write把数据发到socket时通常还需要一次从页缓存到socket发送缓冲区的拷贝所以它只是把两次CPU拷贝变一次属于半零拷贝。实际用的时候有两个坑。第一个是映射大文件会占用进程虚拟地址空间32位环境根本没法玩64位下也要注意频繁mmap/munmap的页表开销。第二个是崩溃前未同步修改可能导致丢数据如果映射区域允许写写完后要msync。3.2 sendfile文件到 socket 的标配sendfile是专门为“把文件内容发到socket”设计的系统调用。它把两个动作收敛成一个调用由内核直接完成任务int out_fd sockfd; off_t offset 0; ssize_t sent 0; while (sent file_size) { ssize_t n sendfile(out_fd, in_fd, offset, file_size - sent); if (n 0) { /* 处理 EINVAL/ENOSYS 等错误 */ } sent n; }这里要注意sendfile的参数顺序在很多语言绑定里容易传反。上面的代码是多段发送的标准写法因为sendfile一次调用发送的字节数可能小于请求长度必须循环。在理想情况下如果文件已经缓存在page cache网卡又支持scatter-gather DMAsendfile可以做到全程无CPU拷贝磁盘DMA读入page cache网卡DMA直接从page cache的散列页拿数据。这也是“零拷贝”一词最经典的含义。sendfile的限制是它主要面向socket场景out_fd当然也可以是支持mmap的设备但实际生产环境基本都在网络发送里用。把两个普通文件fd直接交给sendfile内核虽然能走但某些文件系统会回退到内部拷贝不一定有性能提升。3.3 splice任意 fd 间的搬运工splice是一个更底层的搬运接口它把数据从输入fd搬到输出fd中间不出用户态。但它有个特性默认必须在管道上中转所以常见姿势是先把数据从源fd送进管道再立刻从管道送进目标fdint p[2]; pipe(p); /* 从 in_fd 挪到管道 */ ssize_t n splice(in_fd, NULL, p[1], NULL, 4096 * 16, SPLICE_F_MORE); /* 从管道挪到 out_fd */ splice(p[0], NULL, out_fd, NULL, n, SPLICE_F_MORE);注意这只是示意真正的生产代码要循环处理剩余数据、EAGAIN、以及两个fd的阻塞状态。管道在这里不是数据中转站而是传输通道内核通过页引用传递避免了复制。对splice来说源端fd的目标可以是socket、管道、设备灵活性比sendfile高。splice的性能优势建立在页面引用机制上但管道默认缓冲区有限如果数据量很大就要反复循环、唤醒等事件使用复杂度明显高于sendfile。所以能用sendfile的地方优先sendfilesplice更多用于“从socket读数据再写到文件”这类双向搬运比如网络代理捕获流量、socket连接转发。3.4 copy_file_range文件复制的专用通道copy_file_range是内核里完成“文件到文件”拷贝的系统调用同样不需要数据落到用户态。典型用法ssize_t copied copy_file_range(src_fd, off_in, dst_fd, off_out, len, 0); if (copied 0) { /* 支持时使用, 否则回退到普通拷贝 */ }这个调用的强大之处是它把复制操作下推给文件系统。像XFS、Btrfs这类支持reflink的文件系统在同一个文件系统内做copy_file_range时可以实现真正的“物理零拷贝”只是把源文件的extent引用复制给目标文件磁盘上数据根本没搬。此时CPU拷贝是0DMA拷贝也是0速度完全取决于文件系统元数据操作。跨文件系统或底层驱动不支持reflink时copy_file_range会fallback到内核内循环拷贝也就是类似“splice在文件系统内”的路径没有用户态复制但会有page cache层面的内部处理。生产环境里如果拿它做备份工具一定要检查调用返回值不能盲目假定所有文件系统都支持底层的类reflink提速。3.5 实现对比速查实现典型CPU拷贝典型DMA上下文切换适用场景主要坑readwrite224次以上通用、需改数据中转缓冲区浪费mmapwrite124次左右大文件局部处理虚拟内存与页表开销sendfile理想022次左右文件到socket依赖page cache与SGsplice022次左右fd到fd任意搬运必须经管道、易阻塞copy_file_range0或内部处理0或22次左右文件之间复制跨文件系统受限这个表是典型路径下的情况不是绝对数字。就好比“memcpy次数”在不同内核版本、不同硬件队列深度下会有出入但横向对比足够了。选型时先看目标fd类型再想数据是否要修改再考虑文件系统能力。4. 内核原理补课page cache、页引用与 SG-DMA4.1 page cache数据不是被搬走而是被引用前面反复提到page cache这里把机制说透。Linux读写文件时数据基本都要经过page cache。内核把磁盘块映射成一个个内存页文件内容命中时就直接返回内存内容避免每次都访问磁盘。read/write笨就笨在“命中内存”之后还要把内存内容再复制一份给应用。而sendfile/splice的巧妙之处在于内核不复制这些页而是传递页面的引用。比如splice把fd的数据挪到管道时实际上是在pipe_buffer里记录了一个指向页缓存的struct page指针并增加页引用计数而不是把页内容拷进新的内存页。等目标fd真正消费完这部分数据内核再释放引用。这个机制有点像图书馆的跨馆借阅书本不印刷新副本系统里登记一个借出记录就行还书后再注销记录。代价是内核必须精确管理页的引用计数和生命周期稍有不慎就会造成页错误或内存泄漏这也是为什么这些调用比普通I/O更挑内核版本。4.2 SG-DMA 让网卡直接取数再往底层走一步。sendfile要做到“零CPU拷贝”光靠页引用还不够网卡得有能力从多个散落的内存页直接抓数据组包发送这就是scatter-gather DMA简称SG。网卡支持的DMA描述符可以指向多个不连续的内存地址内核构建skb时把页缓存中的页面地址直接挂进skb的frags数组网卡DMA时按frags就地取数整个过程CPU不碰数据内容。可以查一下网卡是否开启了这个能力。用ethtool查看sg开关ethtool -k eth0 | grep scatter-gather如果是“off”或者驱动不支持零拷贝链路会退化内核只好把散落的页拷贝到一个连续的发送缓冲区再交给网卡DMA这时又出现一次CPU拷贝。这也是很多同学在虚拟机、老网卡或某些云环境里测不出sendfile收益的直接原因。另外虚拟化环境下虚拟网卡的DMA路径和物理网卡差别很大测试前先确认平台能力。4.3 与 O_DIRECT、异步 I/O 的关系零拷贝不是唯一的I/O提速手段它和另外两条路线经常被放在一起比较。O_DIRECT是绕过page cache让磁盘DMA直接读写应用提供的缓冲区。它的优势是避免页缓存占用和多份拷贝适合数据库、搜索引擎这类自己管理缓存的程序。但它要求应用缓冲区地址、大小、偏移通常都要对齐块大小使用门槛高而且少了页缓存这层读文件时基本每次都要等磁盘普通文件服务用它反而容易变慢。io_uring是新一代异步I/O接口支持批量提交请求也支持通过固定缓冲区、零拷贝发送等手段减少拷贝。它更像一个综合性的I/O引擎而不是零点拷贝机制本身。如果你在做超大规模存储或网络中间件io_uring值得投入如果只是优化一个文件下载服务先用好sendfile和splice已经能解决九成问题。把这几个概念分清楚再谈优化就不会被“零拷贝 vs O_DIRECT vs 异步IO”这类问题绕晕。简单说零拷贝省的是copyO_DIRECT省的是cache异步省的是线程等待三者目标不同也可以组合使用。5. 实操验证与排错经验5.1 用 strace 和 perf 把开销抓出来说再多理论不如先看系统调用。我干活的第一步就是用strace看程序到底调用了哪些I/O原语strace -c -f -e traceread,write,sendfile,sendfile64,splice -o trace.txt ./your-server跑完看summary里的calls、errors、time字段能直接确认代码走的是普通read/write还是零拷贝路径。如果你的服务支持多线程压测还可以用perf看上下文切换和CPU周期perf stat -e context-switches,cpu-migrations,page-faults,cycles bash -c ...对比两个版本的输出常见结果是改成sendfile后syscall次数明显变少context-switches下降CPU的cycles占用率也在降。页面错误通常不降反升因为mmap阶段会产生缺页异常这是预期内的不要当成问题。5.2 一个可复现的简单转发实验拿一个具体实验说事。你可以准备一个几百MB的本地文件写两个小程序一个用read/write循环转发到socket一个用sendfile直接发送/* 普通 read/write 作为对照 */ while ((n read(fd_in, buf, sizeof(buf))) 0) { if (write(fd_out, buf, n) ! n) break; }/* sendfile 零拷贝版本 */ off_t off 0; while (sent file_size) { ssize_t n sendfile(fd_out, fd_in, off, file_size - sent); if (n 0) break; sent n; }客户端可以简单用curl或wget收文件服务端用上面任意版本listen。在同一台机器上分别压测我见过的大文件场景里sendfile版本能比read/write版本提升30%到一倍以上。如果是小文件或者并发很低差距会缩小因为瓶颈变成了建连和调度。跑这种实验时注意三个变量文件是否在page cache先cat一次再测、网络是走本机回环还是真实网卡回环接口效果最直观、网卡sg能力前面ethtool查过。这三项没控制好测试结果很容易误导人。5.3 常见问题与排查速查现象可能原因处理方向sendfile返回EINVALfd类型不支持、offset非法确认out_fd是socket、in_fd支持mmapsplice返回ENOSYS/EBADF内核太老或fd不属于管道/splice支持类型升级内核或改用sendfile测不出性能提升网卡无SG、虚拟机DMA路径受限检查ethtool换实体机验证内存占用偏高page cache增大、页引用堆积调整脏页回写参数监控回收进程卡住但没崩溃splice管道满后阻塞等待用非阻塞fd或配合poll/epoll小文件反而变慢系统调用与页表开销超过拷贝节约阈值以下继续用普通I/O这些坑里最常被忽略的是fd类型限制。sendfile把out_fd传入一个普通文件虽然会成功但很多内核版本里等于一次普通文件写入效果可能还不如read/write优化过的libc封装。splice更是强依赖管道阻塞模式下管道满了就是一睡不醒的经典现场。5.4 什么场景不建议用零拷贝最后泼一盆冷水。数据要加密、压缩、做协议编解码时应用必须看到内容零拷贝的适用面就没了。比如TLS加密传输明文数据就算在内核里零拷贝到socket开TLS后还是得回到用户态加密等于白折腾。除非网卡支持TLS offload让硬件在DMA路径上顺手完成加解密那是另一个话题。同样频繁打开关闭连接的小传输场景比如健康检查、短消息零拷贝带来的收益会被连接建立成本盖住。拷贝本身再快也快不过“连接都没复用”的浪费。所以我对零拷贝的态度是它是一个非常值得掌握的优化武器但不是万能药。真正厉害的系统设计是在理解数据路径之后做出组合选择该用read/write的地方老老实实用该用sendfile/splice的地方毫不犹豫地换。我个人习惯是第一版先写正常的read/write保证逻辑清晰可调数据路径稳定后再用strace看拷贝开销确认收益确实存在再引入零拷贝。这样既不会一上来过度设计也不会错过关键优化。

相关新闻

BigDecimal去零转字符串:避开科学计数法与JDK陷阱

BigDecimal去零转字符串:避开科学计数法与JDK陷阱

1. 先从需求说起:一个看起来简单的小问题做过几年Java后端的朋友,大概率都遇到过这样一个需求:数据库里存的金额是DECIMAL(20,6)或者种精度比较高的数值,查询出来是BigDecimal类型,前端的表格、对账单、导出Excel又希望…

2026/10/10 21:30:16 阅读更多 →
OpenPencil 画布导航完全指南:平移、缩放与命令面板

OpenPencil 画布导航完全指南:平移、缩放与命令面板

前端桌面应用AI 应用MCP 服务 【免费下载链接】open-pencil AI-native design editor. Open-source Figma alternative. 项目地址: https://gitcode.com/gh_mirrors/op/open-pencil 点击查看 免费下载 OpenPencil 的编辑画布没有边界——文档内容可以无限延伸&…

2026/10/10 21:29:15 阅读更多 →
Tinycast vs Raycast 横评:兼容 114/147 个命令之外,差距还剩什么?

Tinycast vs Raycast 横评:兼容 114/147 个命令之外,差距还剩什么?

Tinycast vs Raycast 横评:兼容 114/147 个命令之外,差距还剩什么? 【免费下载链接】tinycast Tinycast — a tiny, fully native macOS launcher, hotkeys, and clipboard history. 项目地址: https://gitcode.com/GitHub_Trending/ti/tin…

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

最新新闻

Java八种基本类型详解:从int到boolean,内存、范围与转换一次说透

Java八种基本类型详解:从int到boolean,内存、范围与转换一次说透

前两天看到一个挺有意思的说法,有人把 Java 的 int 关键字念成“英特”,还写成了“函数英特12”。乍一看像是网络流行梗,但细想之下还挺有代表性——这是典型的把“类型声明”当成“函数调用”的理解偏差。既然聊到这儿,干脆把 Ja…

2026/10/10 22:18:06 阅读更多 →
8089张野外动物数据集:YOLO与VOC双格式标注实战指南

8089张野外动物数据集:YOLO与VOC双格式标注实战指南

简介:这份资源是面向计算机视觉开发者与深度学习研究者的野生动物目标检测数据集,适用于野外固定视角水域场景下的动物识别与检测模型训练。数据覆盖大角斑羚、大象、长颈鹿、黑斑羚、捻角羚、羚羊、犀牛、角马、斑马共9类动物,图片清晰且未做…

2026/10/10 22:18:06 阅读更多 →
Claude Fable 5.1 与 Mythos 5.1 分权限开放后,TaoToken 统一 Key 的接入配置与验证

Claude Fable 5.1 与 Mythos 5.1 分权限开放后,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/10 22:18:06 阅读更多 →
低剖面高功率PIN二极管CLA4611-085LF:射频开关与电路设计详解

低剖面高功率PIN二极管CLA4611-085LF:射频开关与电路设计详解

1. 低剖面设计:不仅仅是为了“省地方”1.1 这颗小管子到底特殊在哪CLA4611-085LF是一颗表面贴装的硅PIN二极管,封装采用SOD-323,长宽大约2.5mm乘1.2mm,高度不到1mm。第一次拿到样品时,我甚至以为它是个普通的开关二极管…

2026/10/10 22:18:06 阅读更多 →
AnyPS5 引导加载器深度拆解:不拆机打造 PS5 自定义工具环境

AnyPS5 引导加载器深度拆解:不拆机打造 PS5 自定义工具环境

项目概述:AnyPS5 到底在解决什么问题1. 项目概述:AnyPS5 到底在解决什么问题打开任意一个主机折腾群,隔三差五就有人在问“xx版本能不能破”“有没有万能工具”。AnyPS5 这个名字,听起来也像某个一键化方案,但接触过的…

2026/10/10 22:18:06 阅读更多 →
IP5385P单芯片45W快充充电宝方案设计与量产实践

IP5385P单芯片45W快充充电宝方案设计与量产实践

接了一个45W大功率充电宝项目,工期紧,老板压得厉害。最初我们看了一圈方案,有的需要外置协议IC,有的要自己写复杂的MCU快充协商逻辑,有的整体BOM成本根本压不下来。最后翻到英集芯选型表,看到IP5385P这颗芯…

2026/10/10 22:17:05 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/10 11:14: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/10 5:23:50 阅读更多 →
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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/10 10:38:42 阅读更多 →