新闻详情

新闻详情

首页 / 资讯中心 / 详情

代码性能剖析工具实战:用py-spy定位热点与优化落地

发布时间:2026/10/2 9:41:27来源:尧图网络
代码性能剖析工具实战:用py-spy定位热点与优化落地
1. 写在前面为什么你的代码又慢又卡却找不到元凶先说一个我自己的经历。早两年在公司做一个内部数据处理平台线上服务跑起来功能一切正常可一到月底批量出报表的时段机器负载就往顶上冲页面转圈转到用户直接关浏览器。当时我第一反应是“加机器”但加了两台也没什么改善。后来有空静下心花了半天把核心接口用性能剖析工具从头到尾测了一遍才发现问题根本不在服务器数量而是一段看似不起眼的多层嵌套循环里某个字典字段被反复用字符串拼接当key去查询数据量一上来就是几百万次的无谓计算CPU全耗在hash和字符串生成上了。从那次以后我形成了一个习惯凡是上线前的新模块或者线上出了“慢查询”“高CPU”这类模糊告警第一件事不是拍脑袋改代码而是先用像样的性能剖析工具把热点位置定位出来。这也是我想写这篇东西的原因——代码性能剖析工具在国内开发圈里聊的人不少但多数教程要么停留在“装个cProfile跑一下”的层面要么直接甩一堆火焰图的截图看完还是不知道怎么真正定位问题、怎么优化。这篇文章适合谁看如果你是刚开始关注自己代码为什么慢的后端开发或者你维护着一个越跑越慢的Python量化策略、数据处理脚本又或者你被leader指派去排查一个资源占用异常的服务那么这篇文章能帮你把“性能剖析工具”这件事彻底落地。我会从工具背后的工作原理讲起讲到现实里怎么选、怎么用、怎么读结果最后把我踩过的坑一并交代清楚。核心关键词就三个代码性能剖析工具、热点定位、性能优化落地。2. 搞懂底层逻辑剖析工具到底在你的代码里做了什么很多人在用性能剖析工具的时候只知道它能给出“函数耗时占比”这种统计结果但不知道它内部是怎么拿到这些数字的。不同统计原理直接决定了工具的使用场景——是适合线上无侵入排查还是适合离线精确采样这其实特别关键。2.1 插桩式剖析精确但是有成本插桩式instrumentation剖析简单理解就是“在你每个函数的入口和出口都埋一个计时器”。Python里最典型的代表是标准库的cProfile它通过C扩展的钩子机制在函数调用、返回的时候记录CPU时间线和内存访问情况。这种方式的优点是统计极其精确——每个函数被调用了多少次、一共消耗了多少秒、自身代码消耗多少秒exclusive time、包括子调用消耗多少秒cumulative time都能拿到精确数值。但它的缺点也很明显第一是有性能开销。你正常跑一个10秒的任务插桩式剖析跑下来可能要20秒甚至更久额外时间大概有2到10倍的放大。第二是会改变执行时机尤其涉及多线程、网络IO的程序插桩本身可能掩盖真实的等待时间。所以cProfile这类工具适合“离线、单次、对性能开销不敏感”的场景比如你发现自己写了个批处理脚本很慢跑一遍cProfile看结果这是完全合理的用法。2.2 采样式剖析低开销线上排查利器另一种主流方式是采样式sampling剖析。它的原理特别像统计一个城市里哪些路口最堵——你不需要在每一辆车上装记录仪只需要每隔一小段时间随机抓拍一次看看当前时刻大量车都聚在哪个路口就能精确推断出整体交通瓶颈。在代码世界里代表工具是py-spy。如果你运行Python的时候碰到过“进程好像卡住了但不知道卡在哪个函数”py-spy就是专门解决这类问题的。它通过读取进程的运行时栈信息每隔一个固定间隔比如默认的0.01秒抓一次当前正在执行的Python调用栈然后把几秒钟内抓到的几千个样本汇总成统计图。采样式剖析几乎不打乱原程序的运行节奏开销通常低于5%而且不需要对目标程序做任何代码改动、不需要重启进程。这对于排查线上正在运行的服务实在是太重要了。2.3 理解CPU时间、墙钟时间与IO等待的差别很多新手读性能报告会忽略一个关键维度剖析工具统计的到底是什么时间。墙钟时间wall-clock time从函数开始到结束真实的物理时间包含了一切等待。CPU时间程序在CPU上真正消耗的计算时间不含IO等待、锁等待。IO等待时间程序在等待磁盘、网络数据就绪的空闲时间。举个例子你的接口读一个数据库外部表可能要等800毫秒但CPU实际只用了50毫秒。如果只盯着CPU时间调优会以为函数根本不慢如果分不清墙钟时间里的IO耗时又会把大量精力浪费在优化执行逻辑上实际上瓶颈在超长的数据库查询或网络往返。采样式剖析在采样瞬间抓的是“正在执行的函数调用栈”所以理论上它体现的是CPU运行状态但如果你在抓样本的同时py-spy也会把Python底层的IO等待状态标记出来。配合读火焰图的时候火焰图顶层的宽大色块并不一定代表“这个函数要优化”还要看色块颜色代表的是用户态CPU还是内核态等待。2.4 为什么我优先推荐采样式剖析工具排除项目特殊要求我自己在实际工作里绝大多数场景优先选采样式工具py-spy然后才用cProfile做离线二次验证。原因很现实第一线上服务是“不能停的”插桩式剖析要求你改动代码、重启进程这在生产环境往往很难接受采样式直接挂载attach到正在运行的进程上几分钟就能出结果。第二采样工具对原程序的影响小测出来的数据更接近真实运行状态。第三py-spy作为Rust写的原生工具本身资源占用低而且支持跨平台。如果你做的是离线脚本一次性优化cProfile给的精确数值确实很有参考价值。两者不是替代关系而是互补关系。等后面讲实用场景时我会专门给一个选型建议。3. 第一现场实操用py-spy定位性能瓶颈就是这么简单py-spy是我目前用的最顺手的剖析工具。你不用改代码不用重启进程直接对一个正在运行的程序做现场抓取。下面我把完整操作过程写下来包括准备、现场挂载、读结果这三个阶段每一步你都照着做就能跑通。3.1 安装与前置检查安装方式无非是pip或condapip install py-spy如果是Linux环境还可以通过二进制发布包直接下载。检查是否安装成功直接在命令行输入版号py-spy --version有两点前置注意py-spy在Linux上需要目标进程有读取权限通常建议用sudo运行py-spy否则可能报PermissionDenied。目标程序必须是Python 3.5以上的版本并且没有做过太底层的运行时劫持比如某些Cython直接执行二进制的情况采样可能抓不到有效栈。3.2 现场挂载对一个正在运行的慢任务做快照假设你有个脚本slow_task.py里面存在一个缓慢的批量处理循环。先在终端把这个脚本跑起来python slow_task.py然后另开一个终端先查一下进程号ps aux | grep slow_task有了PID之后执行sudo py-spy dump --pid 12345这条命令会显示当前时刻这个Python进程的调用栈相当于“你按了暂停键看一眼现在正在干什么”。如果你觉得看一眼不够想知道一段时间内的热点分布就可以在拿火焰图的时候用到record命令这个放到后面火焰图章节细说。dump用的最多的时候是线上服务卡住、CPU飙高、请求不响应这类故障。你不需要猜测不用看监控挂上去看一眼当前栈就是最直接的事实。实际测过一次某服务周期性CPU 100%我用py-spy dump --pid只需要1秒就看到了栈顶全是某个第三方SDK的网络重试循环根本不在我们业务代码里。排查方向瞬间就明确了。3.3 核心命令速查dump、record、toppy-spy面向日常用得最多的是三个命令我习惯把它们列成一张速查表命令适用场景用法示例dump进程当前瞬间在做什么排查卡死、假死sudo py-spy dump --pid 12345record采样一段时间并生成火焰图定位热点分布sudo py-spy record -o profile.svg --pid 12345top实时刷新查看当前最耗时的函数排行sudo py-spy top --pid 12345top命令有点像Linux下的top你直接看到当前进程里排名靠前的Python函数调用实时更新适合先在脑海里建立“当前到底谁最忙”的粗略概念。record则是采样几秒到几十秒输出一个火焰图文件适合做正式分析。3.4 生成火焰图把抽象采样数据变成可视化结论这是很多人最容易忽略的步骤——采样生成的原始数据已经包含了完整的调用栈和耗时占比但肉眼从文本里读效率太低。把record的结果转成火焰图才真正方便分析。命令很直接sudo py-spy record -o profile.svg --pid 12345 --duration 30--duration 30表示采样30秒。跑完之后你会得到一个profile.svg文件用浏览器打开就是一个横向的火焰图。火焰图怎么读记住三个关键点横轴代表的是时间占比不是执行顺序。每个色块越宽说明这个函数在采样周期内占据的CPU时间越多。纵轴代表调用栈的深度。底部是入口函数比如main顶部是此刻正在执行的叶子函数。你从顶部往下看能看到一整条从全局入口到当前函数的完整调用路径。真正要优化的是那些“顶端宽大的色块”。顶端函数就是实际干活的叶子函数如果它非常宽说明程序大量时间停在这个函数里顺着宽色块往下看找到它属于哪个业务模块优化对象就清楚了。举个例子。我剖析一个Python版本的量化交易策略回测脚本时火焰图顶端正中出现了一个很宽的色块追溯调用链发现来自pandas的DataFrame.iterrows()。宽达30%以上的执行时间都花在逐行迭代上。发现问题之后换成向量化计算回测耗时直接缩短到原来的三分之一。没有火焰图的话这种隐藏在一堆数据处理代码里的热点很难被直觉发现。4. 深挖代码热点从火焰图到具体优化策略你辛辛苦苦拿到火焰图不代表优化工作就结束了。恰恰相反分析火焰图、理解热点背后的代码结构、确定怎么改才是性能剖析的真正价值所在。这里有大量经验谈我一条条拆开讲。4.1 定位热点自顶向下追溯“宽块”的业务归属定位热点有一套固定心智模型。你得明确火焰图上宽的色块才是瓶颈窄色块不管它在栈顶还是栈底都不用管。第一步找到最宽的那个块看它的函数名和图例往往能直接看清是哪种操作——比如str.join、re.search、DataFrame.groupby之类的都是高频热点函数名。第二步顺着这个宽块往Y轴下方看找到它的父调用路径。如果一路回溯到你的业务函数def cal_sma()那说明你的策略计算是主瓶颈如果回溯到第三方库的某个内部方法那你就要考虑替换实现或者优化调用方式了。第三步注意区分“自己代码慢”和“第三方库慢”。自己在代码里开的循环优化空间很大但如果热点在第三方SDK内部有时直接换库或者升级版本反而更见效。4.2 从热点反推代码问题循环、内存复制、算法复杂度根据我的经验火焰图上呈现的热点往往能反推出几类典型代码问题第一类无意识的重复计算。在循环体内反复读取同一个不变量比如for item in items: result heavy_lookup(config[key1][key2]) # 每次循环都重复计算 process(item, result)优化就是把这个查表操作移到循环外算一次就好。第二类大规模数据的逐行操作。比如用纯Python循环处理百万行数据或是在pandas.DataFrame上反复用.iterrows()逐行访问。这类问题往往直接替换成向量化运算或reduce操作就能大幅提速。第三类不必要的复制。切片、深拷贝、字符串拼接在循环里大面积出现时内存分配会吃掉大量CPU时间。你可以把list[:]换成索引访问把字符串拼接换成join()把深拷贝改成按需检查。第四类过度的调用层级。线程池套线程池、装饰器套装饰器、函数式编程里层层闭包转发这些情况在火焰图上会显示为栈非常深、每层色块都很窄但其实消耗的是调用框架本身的时间。减少中间分发层执行路径更直整体能得到稳定收益。4.3 实战案例一个量化策略代码的剖析与提速前面提到我处理过量化交易策略回测脚本这里把完整过程展开。那个脚本的原始流程很简单加载历史行情数据对每根K线计算多个技术指标执行买卖逻辑最后统计收益。一开始回测一年数据要将近四分钟策略迭代一次改参数也要等很久效率很低。我用py-spyrecord采样了15秒生成的火焰图一眼就看到了一个超宽的块pandas的.iterrows()出现在整个回测主循环的顶端。这意味着每次用for index, row in df.iterrows()取一行数据pandas都要为这一行临时构造一个Series对象几万根K线跑下来就是几万次对象构造成本极高。优化方式就是向量化重写。把循环里对单一行的技术指标计算改成对整个Series的操作把条件分支改成用numpy.where或pandas布尔索引把信号生成从循环内判断改成信号列表整体操作只在最终交易撮合阶段才用循环去遍历信号位。改完之后同样的回测从240秒降到了约40秒提速六倍。后续再加指标时我仍然先跑一次py-spy采样确认热点分布后再动手基本不会做无用功。这个过程其实想说明一句话性能剖析工具不是用来展示数据有多漂亮的它是用来告诉你“注意力应该集中在哪”的。拿到报告之后绝大部分时间应该花在理解和打磨热点函数上而不是反复跑剖析看数字。4.4 什么时候该用cProfile做二次验证有一种情况我会补一步cProfile验证。如果py-spy火焰图已经定位到一个函数比较可疑但我想知道更精确的调用次数、自身耗时的量化对比比如“这个函数一共被调用了57万次自身耗时16秒”这时我会单独针对这段逻辑写一个小的压力测试脚本用cProfile跑一遍。python -m cProfile -s cumtime slow_function_test.py-s cumtime可以按累计时间排序你会得到一份精确到函数的调用耗时表。这个表对后续优化前后对比特别有价值优化前跑一次优化后跑一次两张表一对比性能收益一目了然。cProfile精确py-spy轻量两者各司其职。我的习惯是先用py-spy花几十秒确认热点方向再用cProfile花几分钟确认优化前后的精确变化。这种组合在实战中效率最高。5. 进阶玩法剖析web服务与并发程序的独门技巧很多人觉得剖析工具只能用于命令行脚本其实web服务、多线程程序同样能剖析只是有一些需要避开的坑。我把这些坑和技巧一次讲到位。5.1 线上Web服务不动线上代码的排查法Web服务的问题更隐蔽接口偶尔变慢、内存悄悄上涨、CPU周期性飙高。这时候你几乎不可能给线上程序插桩因为改代码意味着重新发版、重启服务代价太大了。正确做法是保持服务运行在另外的终端用py-spy dump --pid或record去fork式采样。注意如果你用的是Gunicorn多进程模式ps命令会看到多个Python worker进程你得确认采样的是哪一个。一般先看哪个worker CPU高就针对它采样比如top -H -p pid找到CPU占用率最高的线程对应的进程号再对它做采样才不至于采样到一个正在空闲排队的worker。线上排查看的是“正在发生的真相”不是“我们以为的问题”。挂载式采样给了我们一个机会——不改一行业务代码直接窥视运行时内部这在过去是不可想象的。5.2 多线程与async程序的采样注意事项Python多线程或asyncio的协程程序用py-spy采样要注意一个问题py-spy默认抓的是整个进程的调用栈但多线程情况下每次采样抓的是当前时刻某个线程的运行位置所以单次dump可能只看到某一个线程的栈。如果想准确看到多个线程都在干嘛可以多执行几次dump或者用record采样一段时间让统计结果自然覆盖不同线程的时间分布。另外一个细节py-spy record默认会把多个线程的栈混合汇总到一张火焰图。如果只想看某个线程目前py-spy的record还不支持直接指定线程ID但你可以先用py-spy dump --pid PID多次采样结合py-spy top实时看各个函数实时占比再判断是哪块区域卡住了。asyncio协程有自己的特殊性py-spy抓到的栈有时候显示的是事件循环的_run_once而不是具体的业务协程。出现这种情况时别慌你看栈里是否有你的业务函数名字如果协程调用链被事件循环包裹火焰图同样会把时间归属到最顶层的叶子操作上通常还能定位到await后面的IO等待或者CPU计算位置。5.3 CPU高和IO慢的标志性火焰图形状火焰图颜色有讲究。py-spy生成的火焰图里色块颜色有时代表函数所在模块Python函数和C函数会用不同颜色区分但某些版本里还会区分CPU和IO状态。更主流的判断方法是看火焰图的整体形状火焰图整体呈现“平顶宽块”——说明CPU时间被大量集中在少数几个函数上这是典型的CPU密集瓶颈。火焰图顶部“锯齿状”、整体又宽又矮——说明程序大量时间在等待IO函数调用本身很浅但是总线时间被拉长了。火焰图突然出现很窄很高的针状块——通常是一次异常处理、外部SDK调用或者C扩展调用务必关注。这种“图形结构直觉”多练几次就能掌握比读数字更快。我平时收到一份新的火焰图扫描一遍整体形状心里基本就有数该往哪个模块走下一步还是该联系基础设施组查网络。5.4 服务端性能剖析的性能开销为什么可以忽略总有人担心给线上程序做采样会不会干扰用户请求实测下来给你一个明确结论py-spy默认采样间隔是0.01秒每秒钟抓100个线程样本多数服务本身每秒能处理几千个请求这个开销连千分之一都不到完全可以忽略。真正需要谨慎的是长时间高频率record。我曾经试过对一个请求量很大的服务持续采样10分钟最终机器负载也没有因为剖析本身出现明显波动。不过安全起见生产环境建议把--duration控制在30到60秒拿到足够样本就停。想要更细的数据可以多次执行而不是一次跑很久。6. 别踩这些坑我的剖析经验与问题排查实录性能剖析工具很简单但用不好会得出完全错误的结论。这些坑我基本都踩过列出来希望大家绕道走。6.1 常见错误一剖析到的是“优化后的代码”这个坑特别隐蔽——你改进了代码但是忘了重新编译扩展模块、忘了重启服务、或者部署环境和本地环境代码版本不一致结果剖析结果还是老版本的行为。我自己的教训是每次剖析前先确认代码版本、git commit号、运行环境三者的对应关系否则你花半天分析的热点可能根本不在线上跑。6.2 常见错误二采样时间太短结论不稳定py-spy默认采样3秒就能出图但如果程序行为是有阶段性的比如每10秒才进入一次密集计算只采样3秒可能完全错过热点。遇到周期性任务像定时批量同步、定时清理线程建议把--duration拉到任务周期的两到三倍。以量化回测为例我会跑完整个回测周期确保每个交易日逻辑都被覆盖到。6.3 常见错误三用单次结果指导优化性能数据天然有波动。一次采样显示函数A很慢不代表它永远是瓶颈内存缓存状态变化、网络抖动、不同批次数据规模都会改变热点分布。我的做法是至少采样三到五次取重复出现的宽块作为重点优化对象只出现一次的宽色块先放一边。6.4 常见错误四忽略了线程锁和GIL的影响Python的GIL对多线程性能有决定性影响。如果你剖析一个多线程程序发现百花齐放的锁等待火焰图上的宽块可能并不是业务逻辑耗时长而是线程在等待GIL释放。遇到这种情况直接用多进程multiprocessing替代多线程或者考虑用异步IO往往能根本性解决。另外锁等待往往表现为栈顶是threading.lock.acquire或semlock.acquire这类函数。看到这些你的优化方向不是精简业务代码而是降低锁竞争、减少共享状态的频繁访问。6.5 原始问题排查速查表我把过去几年遇到最多的性能相关现象和对应的剖析对策整理成了一张表现象首选操作火焰图/报告表现常见根因服务CPU 100%且请求无响应py-spy dump --pid栈集中在单个业务循环或SDK轮询死循环 / 重试风暴 / 批量计算过于庞大接口偶尔卡顿几十秒py-spy record --duration 60火焰图某块宽度异常且与线程锁相关锁竞争 / 外部系统超时重试批量脚本越跑越慢cProfile离线统计cumtime集中在某数据处理操作数据量增长后算法复杂度飙升内存持续增长py-spy dump结合内存工具栈中反复出现容器扩展、字符串操作无界缓存 / 日志堆积 / 内存拷贝过多多线程并发无明显加速py-spy top实时观察大量时间在GIL相关调用上GIL限制CPU密集型任务并行表里的每一行都是真实出现过的线上体验不是教科书式假设。7. 更开阔的视野不同语言生态下的剖析工具怎么选性能剖析不只是Python的专属话题你做的项目可能涉及Node.js、Java、Go等。选好剖析工具不仅要懂原理还取决于你所在技术栈的“调查文化”。这里列一个我工作多年的横向参考表语言/运行时常用剖析工具特点Pythonpy-spy、cProfile、yappipy-spy适合线上cProfile适合离线yappi是线程感知更强的插桩工具Node.jsflamebearer、0x、clinic.js对异步网络IO的可视化尤其强大能直观展示event loop阻塞Java/JVMasync-profiler、JFR、YourKitasync-profiler是现代化性能剖析标杆JFR是JDK自带低开销录音机Gopprof自带工具链CPU剖析和火焰图生成都是标准操作配合net/http/pprof能做线上采样Rustperf flamegraph系统级性能分析的老牌路径配合perf_event_open做低层采样不同语言生态性能剖析的根本思路是相通的采样或插桩 → 生成调用栈统计 → 可视化 → 聚焦热点 → 优化 → 再验证。方法论不随语言改变。如果你的团队刚好要把性能剖析体系建立起来我的建议是先统一到“火焰图采样工具”这个标准流程上不管哪个语言都能套用再允许各语言生态用自己最顺手的原生工具做细化。有了统一的分析语言和标准跨语言的服务排查效率会直线上升。8. 在团队里推广性能剖析文化的几个建议工具本身学会了更大的挑战在于让团队形成“遇事不决先剖析”的共识。从个人经验看有几个比较见效的切入点。第一个切入点是在故障复盘里引入剖析报告。不用上来就搞全组培训先选一次真实的线上事故你用py-spy把当时的现场抓下来复盘时放火焰图给大家看胜过讲十遍方法论。第二个切入点是把剖析步骤文档化沉淀。我们组里现在有一份“性能排查规范”里面记录了标准命令、采样时长建议、常见火焰图样式对应的经典案例还有一份“进程挂载权限自查清单”。后来新来的同学照着文档也能独立排查基础性能问题。第三个切入点是建立性能基准测试机制。对核心接口和批量任务每次上线前先记录一份剖析基线包括热点函数Top5、整体耗时代分布上线后再跑一遍对拍两次结果。只要某个新热点的占比显著超过基线就说明这次改动引入了性能风险源码评审阶段就能拦住问题。第四个切入点是发扬“写代码时就想性能”的思维。剖析工具始终是事后确认真正高效的是开发者在写代码的时候就想清楚数据规模、复杂度、复用性。一次写对比事后剖析再优化节省的时间多得多。推广这套文化的时候我反复跟同事说的一句话是性能剖析不是用来“证明自己没写错”的而是用来“发现哪些地方能写得更好”的。它应该成为日常开发工具链的一部分而不是濒临事故、焦头烂额时才想起来的手段。9. 最后分享一点我个人的使用体会性能剖析工具用了这么多年我最大的感受是它把“代码很慢”这种模糊感受变成了一张张清晰的地图。你可以对着地图做决策而不是靠着灵感和经验去猜。过去你以为慢的地方剖析下来往往不是瓶颈你以为没问题的角落可能恰恰是CPU燃烧的重灾区。我个人现在处理性能问题的标准流程已经固定下来了线上问题先用py-spy挂载采样看现场接着生成火焰图找热点然后针对热点函数做cProfile二次精确测量优化后重测对比数据。整个过程控制在半天内就能完成一轮“剖析-优化-验证”的闭环。如果你今天看完这篇文章想从零开始落地我的建议是从一个真实存在的慢脚本开始跑一遍py-spy record生成第一张火焰图对照本文讲的方法试着找出最大那个宽色块再决定要不要优化它。只要做过一次完整的闭环你就能体会到剖析工具带来的“掌控感”——不是代码追着你跑而是你追着性能问题跑。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Redis缓存比MySQL查询快116倍?Spring Boot缓存实战全程复盘 2026/10/2 10:37:32

Redis缓存比MySQL查询快116倍?Spring Boot缓存实战全程复盘

可能很多人看到“Redis缓存比数据库查询快”这种结论,第一反应都是“哦,教科书里都这么说”。但真正让我对这个差距有切身体会的,是最近在苍穹外卖项目里做的一次压测:同一个“根据分类查询菜品列表”的接口,改造成Red…

阅读更多 →
DeepSeek V4 发布窗口临近:1T MoE + 昇腾 950PR + 1M 上下文,用 TaoToken 统一 Key 跑通开源大模型推理链路 2026/10/2 10:37:25

DeepSeek V4 发布窗口临近:1T MoE + 昇腾 950PR + 1M 上下文,用 TaoToken 统一 Key 跑通开源大模型推理链路

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

阅读更多 →
Python爬虫实战:抓取安居客新房数据简易版教程 2026/10/2 10:37:25

Python爬虫实战:抓取安居客新房数据简易版教程

朋友上周问我,说想整理一下上海各个板块的新盘报价,问我有没有现成工具。我说你自己打开安居客一页一页翻不就行了?他说三百多个楼盘,一个个点开再把单价、户型、电话复制进表格,一个晚上就没了。这个场景太熟悉了。很…

阅读更多 →
从Jev到NeoHorse-Jev-4B:开源决策模型如何重塑Agent工作流 2026/10/2 10:37:25

从Jev到NeoHorse-Jev-4B:开源决策模型如何重塑Agent工作流

Jev 这个名字最近在圈子里频繁出现,你可能也刷到过:有人在 Codex 里给它配了把“决策钥匙”,让它替 Agent 判断下一步是查数据库、改代码还是继续挖掘上下文;也有人用它在本地部署了任务调度链路;甚至有人扒出它在 Git…

阅读更多 →
JavaScript API入门:从DOM操作到事件监听的实战笔记 2026/10/2 10:37:25

JavaScript API入门:从DOM操作到事件监听的实战笔记

很多人一听到"JavaScript APIs"就觉得是另一门语言,或者是什么高不可攀的东西,尤其看到"APIs 第一天"这种标题,第一反应通常是:完了,又要背一长串函数名了。其实完全不是这么回事。API全称是Appli…

阅读更多 →
PostgreSQL DBA最常用SQL:连接、慢查询、锁与vacuum巡检实战 2026/10/2 10:37:25

PostgreSQL DBA最常用SQL:连接、慢查询、锁与vacuum巡检实战

做了这么多年 PostgreSQL DBA,我手里攒下的 SQL 片段非常多,但真正能让我每次巡检、救火、接手新环境时打开就用的,永远就那么几十条。后来我把它们整理成一个文件,起了个名字叫dba_daily.sql,新同事接手时照着跑一圈&…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉