CPU密集型与I/O密集型任务区分指南:线程池配置与性能优化实战

1. 先从一次线上问题的排查说起

大概半年前,一位朋友找我帮忙看一起线上事故,现象很有意思:一个服务平时响应挺快,但每到整点数据汇总的时段,接口延迟就从几十毫秒飙升到好几秒,CPU 使用率却只涨了一点点。他以为是自己分配的线程数不够,把核心线程从 8 调到 32,结果延迟更严重了,CPU 反而时不时跑满。

这个场景你应该不陌生。很多人在做性能调优时都遇到过类似的疑惑:为什么加线程反而更慢?为什么 CPU 没满但任务就是跑不动?为什么同一个优化方案换个服务就完全失效?

答案往往就藏在标题里这四个字里:CPU密集型任务与I/O密集型任务。

这不是两个抽象的概念标签,而是你在设计并发模型、配置线程池、选型技术方案时绕不开的两个基本参照系。换句话说,只要你写后端服务、做嵌入式开发、搞数据处理,或者哪怕只是负责运维排查问题,这组概念就直接决定了你的系统能撑住多大流量、延迟能做到多低。

这篇文章我会从这两类任务的本质区别讲起,再结合线程池配置、编程模型选型、性能排查这些真实场景,把我踩过的坑和验证过的方案一次性说清楚。

2. CPU密集型任务与I/O密集型任务的核心差异

2.1 CPU密集型任务的本质特征

CPU密集型任务,字面意思就是“吃 CPU”的任务。这类程序运行时,绝大部分时间都消耗在 CPU 的计算、逻辑判断、数值运算上,等待的占比极小。

典型的例子包括:视频编解码、图像处理、压缩解压、加密解密、科学计算、复杂的业务规则校验等。它们的共同特点是在有限的数据上做大量的计算,计算密度很高。

我举个具体的场景你就能感受到:假设你现在要对一批 100 万条记录做 MD5 签名,每条记录签名耗时约 10 微秒,整个过程就是纯粹的计算。CPU 的核数决定了同一时刻能跑多少条,加内存、换更快的磁盘、升级网络带宽,都没用,瓶颈死死卡在 CPU 的频率和核数上。

关于这类任务,有两点很多人存在误解。第一,CPU 使用率高不代表这个任务就一定属于 CPU 密集型。比如某个服务发生了死循环,CPU 也能跑到 100%,但这可能是代码缺陷而不一定是业务本身的特征。第二,单次执行时间短的任务也可能是 CPU 密集型的,比如高频的核心算法函数,单次只有几十微秒,但每毫秒被调用千百次,积少成多。

2.2 I/O密集型任务的真实瓶颈

I/O密集型任务正好相反,它的“慢”在于等待外部资源返回结果。这个 I/O 是广义的,包括磁盘读写、网络请求、数据库查询、消息队列收发,还包括部分进程间通信场景。

有一个 90% 的人初始阶段会搞混的问题:一个任务在执行过程中有时算得多、有时等得多,怎么归类?标准是看时间占比。如果任务生命周期里,花在等待上的时间占了大头计算只有小部分,那就是 I/O 密集型。举个例子,一个服务的接口要查数据库,平均耗时 800 毫秒,其中 760 毫秒花在等待数据库返回,只有 40 毫秒在做业务计算,它就是一个典型的 I/O 密集型任务。

这时加 CPU 核数几乎解决不了问题,瓶颈在于让数据回来。你需要的是在等待期间去干别的活,也就是并发。我见过有团队在 MySQL 单次查询要 1 秒的场景下,为了追求“效率同步”?把并发的数据库请求改成了串行执行,接口耗时直接从 1 秒爆到几十秒,场景的适配度远比听起来更有说服力。理解了这个底层逻辑存在错误的很多。理解了这一层,很多设计决策就很好解释了。

2.3 核心瓶颈在哪里

维度CPU密集型任务I/O密集型任务
主要瓶颈CPU计算能力(频率、核数、缓存命中率)外部设备的响应速度(磁盘/网络/远端服务)
CPU使用率高,通常稳定在70%以上低,常徘徊在10%-30%,甚至更低
加CPU核数的效果核数够则接近线性提升,复现效果取决于并发设计几乎无变化,除非同时增加并发度
加并发线程/W的效果超过核数后显著下降,上下文切换反而拖慢大幅提升吞吐,直到接近外部设备上限
典型代表视频转码、加解密、压缩解压、大数运算接口调用、数据库访问、文件读写、爬虫
类比工人在工位上一直敲零件工人站在零件传送带边等货

这张表是我在实际调优中反复对照的清单。每次拿到一个性能问题,先往表里套,往往五分钟就能定位方向,省掉大把瞎折腾的时间。

注意:还有一种“混合型任务”不能忽略,比如一个接口先做数据校验(CPU密集),再去数据库查询(I/O密集),最后写日志落盘(I/O密集)。实际生产中的绝大多数服务都是这种混合形态,只是占比不同。既然大多数系统里主要是 I/O 密集型,本文后面针对方案选型会侧重讲这个。

3. 为什么这个区分决定了你的技术方案

3.1 线程池大小的配置逻辑

Java 中 ThreadPoolExecutor 的 corePoolSize 怎么定,如果你搜过相关文章,大概率见过这条“经验公式”:

  • CPU密集型任务:线程数 = CPU核数 + 1
  • I/O密集型任务:线程数 = CPU核数 × 2(或更多,比如核数 / (1 - 阻塞系数))

公式本身没有错,但如果你不理解背后的原因,换了硬件就可能被坑。我先解释原理。

对于 CPU 密集型任务,如果你的线程数等于核数,理论上每个 CPU 都在满负荷工作。为什么要加 1?这是为了应对偶发性的缺页中断、锁竞争等导致个别核短暂的空闲,多一个线程能把这个空当补上。但如果你把 CPU 密集场景的线程配成 CPU 核数的两倍,会发生什么?每个线程都在排队抢 CPU,操作系统频繁做上下文切换,光是保存和恢复线程上下文的状态就要耗掉可观的时间,吞吐量不升反降。我实测过一个纯计算的压测:8 核机器、16 个线程跑加密签名,比 9 个线程的吞吐量低了近 20%,CPU 时间大量浪费在线程切换上。

对于 I/O 密集型任务,线程数大于核数就是合理的。因为线程大部分时间都在等待,CPU 是闲下来的,同一个核完全可以同时伺候好几个线程。阻塞系数越高,需要的线程就越多。但这个公式的局限在于“阻塞系数”本身就很难精确测量。我一般用这样的策略:先按核数 × 2 起步,然后压测,观察 CPU 使用率和延迟曲线的拐点,逐步调大或调小。

3.2 从同步阻塞到异步非阻塞的进化路线

如果说线程池配置是在“给定模型下做参数优化”,那么从同步阻塞到异步非阻塞就是在“换求解模型”。编程模型演进的主线,本质上就是不断解放线程、减少等待浪费的过程。

最传统的同步阻塞模型下,一个线程发起 I/O 后只能干等着,纯粹是资源和耐心的双重消耗。性能上不去的根源在于线程本身有创建成本、有上下文切换成本、有栈内存占用。以 Java 标准线程栈默认 1MB 为例,开 1000 个线程,光栈内存就占了 1GB,还没算上其他开销。

异步非阻塞模型把思路完全倒过来了:发起 I/O 后线程不等待,立刻回到线程池去处理别的请求,等数据就绪了再通过事件机制来通知。这就是为什么 Netty 能够用很少的线程撑住海量连接,本质上是把原来漫长的等待从线程上卸掉了,交给操作系统和事件循环。

但我要提醒你:异步编程的收益虽然诱人,代价是代码可读性和调试难度陡增。回调嵌套一度被戏称为“回调地狱”,后来才有了协程这种更优雅的解法。协程的做法是让代码写起来像同步的,但实际上在等待点自动让出控制权,做到了两全其美,Go 的 goroutine 就是这种思路的代表。

3.3 什么样的任务应该选择什么样的技术栈

现在很多人在选型上有一种惯性思维:一遇到高并发就上异步框架,一看到“性能”两个字就觉得协程是救星。但我的建议是反过来,先回答一个问题:这个服务的主要时间到底花在哪?

如果服务主要是 CPU 密集型,异步框架提供不了任何帮助。你更应该关注的是算法本身有没有优化空间,能不能用并行流、SIMD 指令、GPU 异构计算来提速。有人曾经把一个纯计算的模块从多线程改成异步模型,性能反而更差,因为事件循环里塞了重计算,直接把循环里的其他轻任务全部卡住了。这是典型的技术选型错配。

如果服务主要是 I/O 密集型,那做异步改造、用协程、调大线程池,收益就会非常明显。判断依据很简单:你在压测时观察 CPU 使用率,如果 CPU 长期徘徊在 20% 以下、而请求队列还有很多任务滞留,说明大量线程在等 I/O,这场景就是异步化的主场。

提示:实际业务中 90% 以上的后台接口服务都属于 I/O 密集型,因为绕不开数据库和网络调用。但算法服务、图像处理服务多是 CPU 密集型的。用错误模型指导设计,性能天花板会非常低。

4. 实操:如何识别与度量你手头的任务类型

4.1 快速识别法:观察 CPU 使用率

拿到一个不熟悉的服务,最快判断它属于哪种类型的方法就是看运行时的 CPU 使用率。

如果服务正常运行时的 CPU 使用率长期保持在 70% 以上,很可能是 CPU 密集型的。注意要选有业务流量的时候观察,避开刚启动或者空闲期。反过来,如果是中间件或接口类服务,CPU 使用率通常在 10% 到 30% 之间,而请求延迟却有几十毫秒以上,基本可以认定是 I/O 密集型的。

有一种需要警惕的伪现象:某服务 CPU 使用率波动很大,有时 90% 有时 5%。这往往不是单纯的 CPU 密集,而是某些时段突然触发了大量的 CPU 计算,比如临时报表导出、数据汇总任务。这类突发型需求建议单独做线程隔离,不要和核心业务线程池混用,否则高峰期会殃及池鱼。

4.2 使用工具做更精确的量化

粗略观察之外,我推荐用工具把数据量化出来,这样调优才有依据。Linux 系统上比较顺手的一套组合是 top、pidstat 和 iostat。

先用 top 看全局,重点看 %Cpu(s) 这一行的 us(用户态)和 sy(内核态)占比。us 很高说明计算密集,sy 偏高则可能涉及系统调用或上下文切换过多。然后用 pidstat -t -p [PID] 1 这个命令能按线程维度查看 CPU 使用情况,方便定位是不是某个线程在吃 CPU。看 I/O 等待就用 iostat -x 1,重点观察 %util 和 svctm 两个指标,判断磁盘是不是瓶颈。

如果是 Java 服务,还可以用 jstack 抓线程快照,看线程的堆栈状态分布。大量线程卡在 socketRead 或者 park 相关方法上,基本可以断定是在等网络或数据库返回,属于 I/O 密集的佐证。这个技巧在我排查问题的时候特别管用,比盲猜准确得多。

4.3 我踩过的一次分析失误

这里分享一个我自己早期做调优时复盘很久的反例,希望你能绕开。当时有一个统计服务,业务方反馈“很慢”。我抓了 top 一看,CPU 使用率只有 15%,第一反应这是一个 I/O 密集型任务,于是大手笔调大了线程池。

结果呢?吞吐量不仅没提升,延迟反而更高了。后来仔细做 profiling 才发现,这个服务的 CPU 使用率低是因为它大多数时间在获取全局锁,线程全被阻塞在了锁等待上。锁竞争让 CPU 空转,但它不属于正常的 I/O 等待。我又查了线程 dump,发现大量线程卡在 synchronized 块入口,线程状态是 BLOCKED。

这个经历给我的教训是:指标要看,但要结合多种证据交叉验证。CPU 使用率低不一定等于 I/O 密集,还可能是锁竞争、资源池耗尽甚至线程被外部系统限流。判断任务类型不能只看单一指标,必须结合线程状态、调用链分析和业务逻辑来综合判断。

5. 常见问题与排查技巧实录

5.1 线程池配置误区

线程池不是越大越好,也不是越小越省,而是要和任务类型匹配。我见过一个团队把核心线程数配置成 200,处理器核数是 16,任务是 CPU 密集型的签名计算,结果是线程频繁在阻塞和唤醒之间切换,整体吞吐量只有合理配置下的三分之一。压测显示,16 核机器配 17 个线程的性能最好,线程数越多反而越差。

另一个极端是把 I/O 密集型任务的线程池配得过于“精致”,比如 8 核机器配了 12 个线程。数据库查询耗时 200 毫秒,如果同时有 40 个请求进来,12 个线程只能先跑 12 个,剩下的 28 个排队。平均响应时间被拉得很长。这种情况把线程数加到 30 之后,延迟马上降了下来。

我的建议是:线程池参数不要拍脑袋,用目标 TPS 和单个请求的耗时反推。比如你期望单机支撑 500 TPS,每个请求平均耗时 300 毫秒,那么同时在途处理中的任务数是 500 × 0.3 = 150,线程池至少要能容纳这个量级的并发请求,否则就会排队。这个方法比“核数 × 2”更贴合实际业务场景。

5.2 任务类型混用导致的线程饥饿

生产环境里一个比较隐蔽的问题是 CPU 密集型的任务占用了 I/O 密集型的线程池,导致后者的核心业务被饿死。

举个例子,某服务只有一个公共线程池,里面既处理接口请求,也处理报表导出。导出功能因为要加密、要压缩、要处理大量文本结构,计算量极大。高峰期导出任务把自己的核跑满了,接口请求的延迟从 20 毫秒飙升到 5 秒,最后就是整站的体验血崩。

解决思路也简单:把不同类型的任务拆到不同的线程池里,设置不同的参数,必要时用信号量限制重计算任务的并发数。比如,接口请求属于 I/O 密集型,线程数可以多一些,配合异步化;导出任务属于 CPU 密集型,线程数就控制在一个很小的范围,比如 2 到 N+1,避免它干扰主流程。

5.3 上下文切换开销的量化感受

很多人对上下文切换开销没有直观感受,觉得“操作系统切换一下能有多慢?”我做过一次实验,8 核机器上,一个纯计算任务分别用 8 个线程和 64 个线程去跑,时间相差将近 40%。额外的时间绝大部分都花在了线程切换上。切换到哪个线程、保存寄存器状态、加载新线程的寄存器和栈、刷新 TLB,这些动作每一次都要消耗微秒级时间。线程数越多、切换越频繁,损耗就到了肉眼可见的级别。

所以对 CPU 密集型任务来说,“不让线程闲着”反而是正确的目标,而不是“让线程数越多越好”。你要做的是让每一核都有活干,而不是让每一核都在换活干。

5.4 核心排查流程速查表

现象可能原因验证手段解决方向
CPU 高、延迟高计算密集或代码死循环top 查看 us,jstack 看线程栈优化算法,控制并发数,必要时水平扩容
CPU 低、延迟高I/O 等待或锁竞争pidstat、iostat、jstack 看 BLOCKED异步化改造或调线程池、查锁粒度
线程数调大反而更慢上下文切换开销变大vmstat 看 cs(context switch)列减小线程数,或者替换为异步模型
线程池排队严重线程数不足以承载在途请求监控队列长度、活跃线程数按 TPS × 单请求耗时反推线程数
单线程卡满、整体响应慢CPU 任务和 I/O 任务共用线程池线程 dump 找出热点线程拆分线程池,隔离重计算任务

这张表是我在排查问题时反复对照的路线图。多数性能问题,走完这几行基本能定位到根因。

6. 经验总结:一眼定位问题的方法论

最后分享一点我自己沉淀下来的方法论。每次遇到性能问题,我第一件事不是看代码,而是先问三个问题:这个任务的理想瓶颈是什么?当前时间都花在哪里了?采用的并发模型和任务类型匹配吗?

实操上的判断路径是这样的:

第一步,先确定任务类型。看 CPU 使用率,结合线程状态做交叉验证。

第二步,确定当前方案。如果你是同步模型,大量线程在阻塞等待,考虑异步化改造的收益;如果你是异步模型,却把重计算也塞了进来,就考虑分流。

第三步,再确定参数。线程数、队列长度、超时时间这些,都要基于前两步的结论来定,而不是凭感觉。

很多人来问我调优问题,我反推回去,发现有相当比例的根因都是把任务类型搞错了。有的是把 I/O 密集型当成 CPU 密集型去调优,狂加核数、精简线程数,结果性能没有任何变化;也有的是把 CPU 密集型当成 I/O 密集型去搞异步化,给重计算套了一个又一个事件循环,反而把轻量级任务拖下水。

如果你读到这里,应该已经能感受到:区分这两类任务并不只是面试时的八股考点,它是你架构选型、资源规划、性能排查的基础视角。理解任务类型识别这件事,是做性能优化的第一性原理。以后再遇到一个慢接口,先别急着加机器,先想想它是在算还是在等。把这个想明白了,很多问题的答案都会自己浮现出来。

相关新闻

嵌入式开发AI协同实战:STM32代码生成与调试全流程

嵌入式开发AI协同实战:STM32代码生成与调试全流程

1. 为什么嵌入式开发需要引入AI协同 1.1 从"单打独斗"到"人机配合"的转变 搞嵌入式软件这行的朋友都清楚,STM32程序的开发流程跟纯软件有着本质区别。纯软件写完代码直接跑就行,但嵌入式你得面对寄存器配置、时钟树、中断优先级、外…

2026/10/20 16:21:54 阅读更多 →
从单次LLM调用到完整Agent:Harness Runtime架构选型与工程实践

从单次LLM调用到完整Agent:Harness Runtime架构选型与工程实践

1. 从一次裸调用说起:为什么单次 LLM 调用撑不起一个 Agent 很多人第一次接触 Agent 开发,都是从一段几十行的脚本开始的:拼一个 prompt,调一次模型接口,拿到返回文本,解析一下,结束。这个模式在…

2026/10/20 16:20:52 阅读更多 →
7代CPU装Win7核显驱动实战:改INF与镜像注入全流程指南

7代CPU装Win7核显驱动实战:改INF与镜像注入全流程指南

简介:针对Intel 7代CPU(如i5-7500、i7-7700)在Windows 7下安装集成显卡驱动的实际需求,这份资源面向需要解决系统兼容性问题的IT运维人员与装机用户。压缩包共收录660个文件,大小约354.69MB,包含Inf与Sys驱…

2026/10/20 16:20:52 阅读更多 →

最新新闻

SLAM技术工程化实践:激光与视觉惯性里程计复现与调参指南

SLAM技术工程化实践:激光与视觉惯性里程计复现与调参指南

简介:本资源为高博《自动驾驶与机器人中的SLAM技术》源码修改版,面向自动驾驶、机器人及SLAM方向的开发者与深蓝学院学员,提供经定制调整的可运行代码,帮助读者从传感器数据、建图算法到优化模块直观理解完整实现流程。压缩包约23…

2026/10/20 17:09:34 阅读更多 →
机器学习与深度学习:区别、原理与实战指南

机器学习与深度学习:区别、原理与实战指南

机器学习、深度学习这两个词,这几年几乎已经被说烂了。但真被问到“区别到底是什么、我该先学哪个、实际项目里怎么用”,能一句话讲清楚的人并不多。作为常年跟数据打交道的人,我习惯把机器学习理解成“按菜谱学做菜”:你告诉系统…

2026/10/20 17:09:34 阅读更多 →
accountaccessor.dll报错怎么办?免费安全的系统修复方法

accountaccessor.dll报错怎么办?免费安全的系统修复方法

先说实话:accountaccessor.dll 这种系统组件报错,80% 以上的“免费下载”方案,反而是把电脑推向更坑的深渊。我在日常帮人修电脑的过程里,隔三差五就能遇到这类问题。很多人第一反应就是打开搜索,找到一堆“dll下载站”…

2026/10/20 17:09:34 阅读更多 →
ROS2数据手套遥操作:用滑动窗口滤波消除机械手舵机抖动

ROS2数据手套遥操作:用滑动窗口滤波消除机械手舵机抖动

第一次在 ROS2 里把数据手套的读数直接转发给机械手,我发现了一个有点尴尬的现象:我戴着手套慢慢张开手,机械手指却在那里高频哆嗦。屏幕上显示的弯曲角度曲线粗看还行,放大一看每一帧都在 5 上下跳动,这个噪声落到舵机…

2026/10/20 17:09:34 阅读更多 →
客服机器人主动发券唤醒沉睡客户:购买意图识别与实战拆解

客服机器人主动发券唤醒沉睡客户:购买意图识别与实战拆解

我接手这个需求的时候,第一反应是:客服机器人不是用来回答问题的吗?怎么还要主动发券?但实际业务场景里,这种“看似越权”的需求往往是增长团队最后捞人的一根稻草。电商平台积压了大量沉睡客户——买过几次、加过购物…

2026/10/20 17:09:34 阅读更多 →
从码农到扫地机器人掌门:跨界创业的底层系统思维

从码农到扫地机器人掌门:跨界创业的底层系统思维

很多人看到“从码农到扫地茅掌门,再到越野追梦人”这个标题,第一反应都是问同一句:你到底是写代码的、造机器人的,还是玩越野车的? 我的回答是:三个都做过,但没有任何一个是靠“换工作”换来的…

2026/10/20 17:08:33 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →