Java异常处理从原理到实战:try-catch/finally、异常日志与避坑指南
聊Java异常这个话题之前我一直觉得它特别像程序员界的“体检报告”入职一两年的人能看懂try-catch-finally就已经觉得自己会了工作三五年的人开始思考受检异常和非受检异常到底该选哪个真正在线上扛过故障的才会明白异常处理不只是语法问题而是整个系统的可观测性、稳定性和研发规范问题。我见过太多项目代码跑得好好的一上生产就出事日志里全是吞掉的异常、打了一半的堆栈、被错误包装的根因。排查问题时油锅已经烧起来了你却发现连口锅在哪都不知道。所以这篇文章我想认真聊一次Java异常从体系设计、JVM层实现原理再到实战中的异常策略、日志处理和避坑清单。目标只有一个——让你写的异常代码经得起线上环境的考验。1. 从体系设计说起受检异常与非受检异常怎么选1.1 异常体系的全局认知Java的异常体系其实就一张图能讲清楚一切的根是Throwable它下面分成两个大类Error和Exception。Error代表JVM层面或者系统层面的严重问题比如OutOfMemoryError、StackOverflowError这是程序本身很难恢复的正常情况下不要试图去catch它。而Exception才是我们日常打交道最多的部分下面又分为受检异常和非受检异常。用个生活化的类比Error就像家里突然停电了你改不了也不该硬改而Exception更像是某个房间的插头松了、灯泡坏了属于设备层面的问题你可以修、可以换、可以预防。很多同学看到Exception下面那一串类就头疼其实不需要都记住。核心要掌握的是三类一类是IOException、SQLException这类受检异常编译器强制你处理一类是NullPointerException、IllegalArgumentException这类非受检异常属于代码逻辑没写好还有一类是RuntimeException下面自己派生出来的业务异常类属于团队内部自己定义的规范。在开始谈选型之前我先给新手一个最基础的认知异常不是“程序出错”的代名词而是程序在非正常路径上的另一种返回方式。它和方法的return一样都是在向调用方传达信息只不过return传达的是正常结果异常传达的是“这里出了问题你要不要处理”。思想上转过这个弯后面很多东西都会自然很多。1.2 受检与非受检为什么Java要这么分受检异常是Java一个非常独特的设计很多从其他语言转过来的开发者一开始会很不习惯。它的本意是编译器在编译阶段强制你处理那些“可预期但无法避免”的失败场景比如读写文件时磁盘可能满了、网络请求时对面服务可能挂了。这类异常不是你的逻辑错误而是外部环境的不确定性所以Java觉得你有义务处理。但实际开发中受检异常是个非常有争议的设计。我记得有个有名的吐槽你明明知道自己处理不了这个异常但编译器逼着你写catch块于是你只能打个log然后重新抛出或者干脆就写个空的catch把它吞掉——这反而是最糟糕的用法。所以现在的共识是受检异常适合用在“调用方真的有办法处理”的场景比如用户输入的文件不存在了你可以提示用户重新选择文件。如果调用方其实什么都做不了那就不要用受检异常直接抛一个非受检异常上来让上层统一处理。非受检异常也就是RuntimeException及其子类代表的是编程错误、状态错误、参数错误这类问题比如空指针、数组越界、非法参数。这类异常不应该逐个去catch而应该靠代码审查、单元测试和防御性编程来减少。当它们真的发生时通常意味着代码有bug处理方式不是catch后继续跑而是让程序停下来把堆栈信息打出来倒逼你修复根因。我自己在带项目时候定过一条简单规则凡是调用方能够基于异常做出不同决策的用受检异常凡是调用方只能选择“整个任务失败”的用非受检异常凡是自己代码里产生的错误一律非受检异常别让上层平白多一堆catch。这条规则不一定适用于所有项目但对大多数业务系统来说是务实的。2. 深入JVMtry-catch-finally到底是怎么跑的2.1 字节码里面的异常表很多Java开发者写了一两年try-catch却从没想过这段代码在JVM里长什么样。这其实挺遗憾的因为理解了字节码层的实现你就明白为什么有些异常处理代码性能差为什么finally在某些极端情况下那么“顽固”。我先给个例子你写的是这样一段Java代码public void readFile(String path) { try { FileInputStream in new FileInputStream(path); in.read(); in.close(); } catch (FileNotFoundException e) { log.error(file not found, e); } catch (IOException e) { log.error(read failed, e); } }编译成class文件之后方法体里会附带一张异常表。这张表是JVM用来做异常分发的核心结构每一行都记录着四样东西try块的起始字节码偏移量、try块的结束偏移量、catch块的起始偏移量、以及要捕获的异常类型。当方法执行过程中抛出异常时JVM会从上到下扫描异常表先看当前正在执行的字节码指令是否落在某个try范围区间内再看抛出的异常类型是否能被对应的catch处理器捕获。注意这个顺序很重要多个catch块在字节码层面就是异常表里的多行记录JVM是按行顺序匹配的所以先捕获子类、再捕获父类是必须遵守的规则否则子类那个catch永远没机会执行。这里有个冷知识现代JVM的热点方法在解释执行时异常分发的开销其实并不大因为异常表现在已经优化成了一种高效的数据结构。但真正的问题在于一旦异常真的被抛出JVM需要遍历当前调用栈、构建异常对象、填充堆栈轨迹这个过程才是真正昂贵的地方。这就引出了下面要聊的话题。2.2 finally为什么一定会执行你思考过finally块为什么“无论是否发生异常都会执行”吗不是因为编译器给了它什么魔法而是因为在编译阶段finally块里的字节码被复制进了多个分支。具体来说编译器会把try块正常结束后的路径、每个catch块处理完后的路径、以及每一个可能抛出异常但未被捕获的路径统统插入一份finally块的代码副本。换句话说你写的finally块在最终生成的字节码里出现了好几次。这也是为什么在finally里写复杂逻辑要非常小心因为你的一段代码被复制多份一旦逻辑出问题隐患也会被放大好几倍。关于finally有两个长期存在的坑是必须说的。第一个是不要在finally里面return。Java官方规范明确说明过如果finally块里有return它会覆盖掉try或catch里的任何return值包括覆盖掉异常本身。这意味着你catch到的那个异常表面上被捕获了但因为finally先return了这个异常就这样被无声无息地吞掉了。这种代码我在Code Review里碰到过不止一次每次都要苦口婆心解释为什么不行。第二个坑是不要在finally块里做可能抛异常的操作但不好好处理。比如你在finally里面写stream.close()这个方法本身就会抛受检异常如果一个异常正在向上传播这里又抛一个新异常新异常会直接顶掉原来的异常原始堆栈就丢了。正确做法是close操作单独处理保证不会干扰主路径的异常传递。2.3 异常的性能成本与优化建议很多老前辈说“try-catch会影响性能所以要少用”这话在十年前也许有道理但在现代JVM上已经不太准确了。JIT编译后的try-catch在没有异常抛出的情况下几乎是没有额外开销的因为在字节码层面进入try块并不需要特殊的check。真正消耗性能的地方在于异常对象的创建当JVM抛出异常时它会去填充当前线程的堆栈快照生成异常对象。这个操作即使异常被很快catch住成本也不低。有一句非常经典的话“异常创建的成本不在于new而在于fillInStackTrace”。所以不要用异常来做正常流程控制更不要在高频循环里用异常来处理“可以预判的”问题。举个例子有些同事喜欢这样写try { int value Integer.parseInt(input); // 使用value } catch (NumberFormatException e) { // 当作非数字处理 }如果input大部分情况下都是数字这个写法的消费还能接受但如果输入里大量是非数字你等于在为每次合法判断都创建一个异常对象性能会很差。更好的做法是先用正则或Character.isDigit()做预判断只有真正无法判断时才用异常处理。记住这个原则异常是为“异常情况”设计的不是用来替代条件分支的。另一个优化思路是不一定要保留堆栈信息。如果你明确知道某个异常只需要作为发生信号被捕获并且你会在catch块里自行补充上下文那么可以重写fillInStackTrace来去掉堆栈快照。但这个优化非常强行使用前必须做权衡因为丢失堆栈对于问题排查是重大损失。一般项目里我不会推荐这么做除非是在极端性能敏感的场景里。3. 面向实战的异常处理策略3.1 统一异常体系怎么搭聊完底层原理属于“内功”的部分就告一段落了。接下来聊更接地气的内容一个项目里异常体系到底怎么搭才不乱。我先描述一个混乱现场项目里每个模块各写各的异常有返回false的、有返回null的、有抛RuntimeException的、有抛自定义的BusinessException的。到了上层接口又要把这些全部兜住转成统一响应你就得在Controller里写一堆catch块每个都不一样最后代码成了一团乱麻。比较好的做法是搭建一个分层的异常体系让每个异常类都有明确的定位。我在自己负责的项目里习惯这样设计定义一个基础的BaseException继承自RuntimeException包含错误码、错误消息、原始异常三个核心属性。业务模块继承BaseException比如OrderException、UserException用于承载业务语义。系统级错误单独用一个SystemException比如数据库连接失败、第三方服务超时等它的语义是“系统暂时不可用需要重试”。所有对外暴露的接口在入口处都通过一个统一异常处理器做兜底转换业务异常直接进入响应体系统异常被记录日志后返回通用错误信息。代码上大致长这样public class BaseException extends RuntimeException { private final String errorCode; private final String errorMessage; public BaseException(String errorCode, String errorMessage) { super(errorMessage); this.errorCode errorCode; this.errorMessage errorMessage; } public BaseException(String errorCode, String errorMessage, Throwable cause) { super(errorMessage, cause); this.errorCode errorCode; this.errorMessage errorMessage; } // getter省略 }这样一个体系的好处是上层代码不需要关心底层每个模块的异常细节只要统一按BaseException处理即可而具体模块内可以通过异常类快速定位是哪个环节出的问题。我每次看到一套清晰异常体系的项目就会觉得这个团队的工程质量是有底子的。3.2 什么时候捕获什么时候抛出新手最容易犯的一个错误是“到处都catch到处都try”。写代码的人生怕某个地方异常了程序会崩于是能包的地方全包上结果就是异常被层层吞掉、包装、再抛出到最后线上一个问题查了三天都不知道根因在哪。我自己定过一个边界原则在边界进行捕获和处理在内部直接抛出。所谓边界指的是你的系统与外部世界交互的地方比如HTTP接口入口、消息队列消费者入口、定时任务入口。这些地方必须捕获异常因为你要决定返回什么给调用方、要不要记录告警。而内部的方法调用不应该频繁catch让异常沿着调用链向上传播直到到达一个“有能力处理”的边界。具体落实下来有几种情况会直接拦截下来就地处理一是你有明确的降级策略比如调用B服务失败后可以走本地缓存的兜底数据二是你能给调用方提供一个明确且友好的提示比如参数校验失败三是你需要把受检异常转换成一个更贴合当前业务语义的异常。除此之外一律往上抛。这里还需要特别提醒一个反向问题不要在核心业务逻辑里包一个非常大的try-catch然后catch块里写“反正也是系统异常就这么算了”。这种写法的本质是逃避问题。异常被吞掉了业务数据可能是错的而系统依然在运行。等真正出大事的时候你连错误日志都找不到这种情况其实比程序直接崩溃可怕得多。3.3 业务异常与系统异常分治我在项目里复盘线上故障的时候发现团队里很多人对“业务异常”和“系统异常”的理解是模糊的而这恰恰决定了异常处理方式应该完全不同。业务异常指的是因为业务规则不满足而产生的异常比如“账户余额不足”、“订单已取消”、“库存不够”。这种异常本质上不是故障它只是一种正常的业务分支表达。它的处理方式通常是捕获后转换成一个明确的错误码返回给前端展示提示文案或者在公司内部系统中转入人工处理流程。业务异常通常不需要告警也不需要触发重试因为它们不会因为重试而解决。系统异常指的是因为系统资源、外部依赖、环境问题导致的异常比如网络超时、数据库连接池耗尽、第三方服务5xx。这种异常才是真正需要警惕的。它意味着你的系统或依赖方处于不健康状态。处理方式不只是catch后返回错误而是要触发告警、记录完整堆栈、考虑自动重试、甚至走熔断降级。举个例子一个下单接口里库存服务调用超时了这是系统异常。如果你只是catch住了返回一个“服务器繁忙”给前端然后什么也不做那么等库存服务恢复时这个订单实际并没有创建成功用户不仅体验差系统数据也处于不一致状态。正确做法是要么把整个下单流程设计成可重试的并自动重试要么记录下这个失败请求通过异步补偿机制去核对和修复同时立刻触发告警。这个区分直接决定了你的异常处理是真在解决问题还是只做表面功夫。4. 日志处理与问题复现4.1 异常日志的正确姿势异常处理到位的最后一道防线是日志。因为再好的异常策略如果日志里什么都没留下来就等于白处理了。我在排查问题的时候最痛苦的情况就是看到下面这类日志2024-06-01 12:00:00 ERROR xxx: null没有堆栈没有上下文只有一个null这基本上等于告诉排查者请重新复现问题吧。而有些问题比如并发下的偶发问题可能几个月都复现不出来。这里必须强调一个铁律打印异常日志时一定要把异常对象整体传进去而不要只调e.getMessage()或者e.toString()。log.error(something failed, e)这个写法在日志框架里会把完整的堆栈轨迹输出包含了异常发生的类、方法、行号、调用链。而e.getMessage()往往只返回异常的消息字符串e.toString()虽然带了异常类名但都没有堆栈。线上排查时堆栈就是破案的指纹少了这个指纹案子基本就难破了。同时异常日志里一定要带上上下文参数。比如在一个订单处理的方法里catch了异常至少要打出orderId、userId、请求参数等关键标识。你试想一下一条日志只写着“处理订单失败”没有订单号运维在日志平台里连对应的请求都串不起来。我们在代码规范里有个硬性要求所有异常日志至少包含一个可以唯一定位当前请求的ID要么是业务单号要么是链路追踪的traceId。4.2 异常链不要吃异常日志里还有一个隐蔽的问题就是异常链的断裂。很多时候一个底层异常在传播过程中被上层catch后包装成了一个新的业务异常但忘了把原始异常作为原因传进去。结果就是日志里只有“订单创建失败”这个表象底层的SQLException连影子都看不到。正确的做法是在包装异常时始终带上原始异常作为cause。比如throw new OrderException(2001, 订单创建失败, e);Java的异常机制里有一个cause字段专门用来保存被包装前的原因。当日志框架打印堆栈时会顺着cause一直打印出完整的原因链。这样你就能从业务异常的堆栈一路看到最底层的技术异常定位问题的效率会高很多。Java 7还引入了一个addSuppressed机制用来记录那些在异常处理过程中被抑制的异常。比如try-with-resources关闭资源时如果主逻辑抛了异常资源关闭时又抛了一个异常新异常会被加入到suppressed列表里而不会覆盖主异常。这一点对于finally里处理close操作特别有用。如果你还在用老式的try-finally手动关闭资源我真的建议换成try-with-resources它设计得比你想的更周全。我有一个特别深的体会在团队里推行“异常链完整”这条规则时一开始阻力不小因为很多人觉得“包一层就够了带不带cause没区别”。后来有一次线上排查一个问题日志打了三页前两页全是业务异常包装最后一行才看到真正的数据库死锁原因。从那以后所有人在写包装异常时都会手一抖下意识把e带上。5. 常见问题与避坑速查5.1 高频坑位清单做异常处理这么多年我把见过的高频问题整理成了一张清单。你可以把它当作自己写代码时的自查表。坑位表现正确解法吞异常catch块为空或只写注释要么处理要么打印日志并重新抛出只打message不打堆栈日志里只有一行“NullPointerException”必须传异常对象打印完整堆栈catch后返回null调用方拿到null后继续使用引发二次问题明确语义必要时抛自定义异常finally里returntry/catch中的异常被覆盖吞掉严禁在finally里returncatch顺序颠倒先捕获父类再捕获子类子类永远不执行先捕获具体子类异常再处理父类异常无数值意义的异常复用到处抛Exception建立分层异常体系明确语义高频循环中用异常做判断性能差堆栈创建开销大用条件判断代替异常流转不区分业务/系统异常该重试的不重试该告警的不告警分治两类异常各自制定策略包装异常忘写cause根因丢失排查困难new XxxException(msg, e)这张表里的每一条几乎都对应着我在真实项目里踩过的坑。尤其“吞异常”和“不打印堆栈”两个问题是技术债的首席贡献者。代码review时如果看到空的catch块我现在的态度就是直接打回不打任何商量。5.2 遇到线上异常时的排查思路最后分享一套我自己在线上遇到异常时的排查顺序这套方法救过我很多次也带过好几个刚入门的朋友上手。第一步先看异常栈的顶部。堆栈顶部通常就是异常真正发生的位置。很多人一上来就滑到堆栈底部找自己的业务代码方向反了。先确认“在哪一行爆的”再顺着call chain往回推很快能锁定大概范围。第二步搜索当前请求的完整链路日志。通过traceId或者业务单号把这一条请求从入口到出口的所有日志拉出来按时间顺序排列。你会发现异常往往不是孤立出现的前面一定有一些预兆比如慢调用、超时、参数异常。第三步确定异常类型属于哪一类。如果是业务异常优先查数据状态和业务规则如果是系统异常优先查网络、连接池、资源使用率、GC情况。这一步千万不要弄反否则你会花半天时间在一个业务异常上查数据库连接池。第四步修复验证时要模拟真实场景。不要只在单元测试里跑了绿色就觉得完事把旧数据、边界输入、并发访问都考虑到。尤其一些并发相关的异常单线程测试根本测不出来需要做一轮简单的压测或者多线程并发验证。这四步流程并不复杂但绝大多数团队并没有把排查过程标准化。线上故障发生时情绪紧张、时间紧迫没有固定流程的情况下很容易东一榔头西一棒子最后越查越乱。我个人在实际操作中的体会是异常处理的代码往往要等三个月甚至更久之后在某个深夜的告警电话里才真正体现出价值。你写的每一行catch、每一个日志参数、每一次带上cause的包装都在为那个时刻储备弹药。所以不妨从今天起把你项目里那些空的catch块、只打message不打堆栈的日志、乱抛一气的Exception都翻出来修一遍。这个过程不会太轻松但回报一定值得。

相关新闻

小区物业管理系统数据库设计:从ER模型到索引优化实战

小区物业管理系统数据库设计:从ER模型到索引优化实战

简介:这是一份面向高校数据库课程设计的小区物业管理系统数据库设计文档,以完整报告形式呈现,系统覆盖需求分析、概念结构设计、逻辑结构设计、物理结构设计、详细设计及总结等核心环节,能够为正在完成课设或毕业设计的学生提供直…

2026/10/12 4:22:35 阅读更多 →
Rocq Prover 变更详解:About 命令现在展示 Abbreviation 参数的符号作用域

Rocq Prover 变更详解:About 命令现在展示 Abbreviation 参数的符号作用域

形式化验证编程语言 【免费下载链接】coq The Rocq Prover is an interactive theorem prover, or proof assistant. It provides a formal language to write mathematical definitions, executable algorithms and theorems together with an environment for semi-interacti…

2026/10/12 4:21:35 阅读更多 →
Linux inotify阻塞模式实战:文件系统事件监听与目录监控

Linux inotify阻塞模式实战:文件系统事件监听与目录监控

1. 为什么要用inotify,而不是轮询在日常的系统运维或者服务端开发中,监控目录变化是个常年挥之不去的需求。早期大家喜欢写一个死循环,每隔几百毫秒去扫描一次目录,比对文件列表,靠时间戳和大小来判断有没有变化。这种…

2026/10/12 4:21:35 阅读更多 →

最新新闻

测试工程师转型AI数据治理:从缺陷猎人到数据架构师

测试工程师转型AI数据治理:从缺陷猎人到数据架构师

我刚做测试那几年,最上头的不是点按钮找 bug,而是盯着一套接口设计图想“这里到底谁能把它弄坏”。那种感觉就像追一部有瑕疵的侦探剧,提前锁定凶手。后来团队里一位做平台架构的同事半开玩笑说:你有这种“总想证明系统有罪”的毛…

2026/10/12 5:17:06 阅读更多 →
基于4A理念的运维安全管理平台架构设计与实践

基于4A理念的运维安全管理平台架构设计与实践

直接说结论:基于4A理念的运维安全管理平台,不是简单买一套堡垒机,而是要把账号、认证、授权、审计四个体系从架构层面统一建模,形成一个完整的技术闭环。我自己在金融、政务类项目里做过几套这样的平台,最深的感受是—…

2026/10/12 5:17:05 阅读更多 →
Zed官宣支持ACP:一次模型配置,全场景AI能力复用

Zed官宣支持ACP:一次模型配置,全场景AI能力复用

做原生 IDE 的人突然聊起 Agent 协议,这消息一出来,圈子里的讨论热度确实不低。很多朋友第一反应是:Zed 不是一直在打磨编辑器性能吗,怎么突然官宣 ACP 了?第二反应其实是更实际的问题——这东西跟我手上的工具链到底有…

2026/10/12 5:17:05 阅读更多 →
java.lang.OutOfMemoryError:Java大数据量查询内存溢出排查与TaoToken配置实践

java.lang.OutOfMemoryError:Java大数据量查询内存溢出排查与TaoToken配置实践

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

2026/10/12 5:17:05 阅读更多 →
技术日报|WiFi穿墙追踪人体项目登顶日增2152星,龙虾AI openclaw悄然突破24万星:用TaoToken统一Key复现双项目本地部署

技术日报|WiFi穿墙追踪人体项目登顶日增2152星,龙虾AI openclaw悄然突破24万星:用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/12 5:17:05 阅读更多 →
PLC联锁控制系统在污水泵站无人值守中的设计与实践

PLC联锁控制系统在污水泵站无人值守中的设计与实践

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

2026/10/12 5:16:05 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 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/11 10:45:37 阅读更多 →
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/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练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/11 14:36:54 阅读更多 →