ASM 字节码增强实战:CodeGuide 手把手教你给所有方法加 TryCatch,非入侵采集异常与出参
文档教程后端【免费下载链接】CodeGuide:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总旨在为大家提供一个清晰详细的学习教程侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助请给予支持(关注、点赞、分享)项目地址https://gitcode.com/gh_mirrors/code/CodeGuide点击查看免费下载本文基于 CodeGuide 开源仓库《用字节码增强技术给所有方法加上TryCatch捕获异常并输出》整理成文。当业务系统出现问题时你是否希望在不改动一行业务代码的前提下自动抓取每个方法的入参、出参与异常信息本指南以strToNumber方法为靶点逐步演示如何用 ASM 指令码将一个普通方法改造成被TryCatch包裹、可输出监控信息的增强方法。读完你将掌握 ASM 字节码增强的核心骨架ClassReader/ClassWriter/AdviceAdapter理解onMethodEnter、visitMaxs、onMethodExit三个注入点的配合方式以及ASTORE、ALOAD、LDC、INVOKESTATIC、ATHROW等关键指令的实战含义从而能自己搭建一套非入侵的监控组件。一、为什么需要给方法织上监控一套系统是否稳定运行取决于它的运行健康度这包括调用量、可用率、影响时长以及服务器性能等各项指标的综合值。并且在系统出现异常问题时最好能抓取整个业务方法执行链路并输出当时的入参、出参、异常信息以及一些 JVM、Redis、MySQL 的各项性能指标用于快速定位并解决问题。要做到这件事常见的监控方案有三种方案做法缺点硬编码直接在方法中写代码收取执行耗时、出入参与异常信息成本太大且有不可预估的风险切面 AOP做一套统一监控组件仍需要硬编码维护成本不低探针非入侵基于探针技术采用字节码增强方式监控如 Google Dapper、Zipkin 的思路需要掌握字节码编程能力在字节码增强方面有三个常用框架ASM、Javassist、ByteCode各有优缺点按需选择。本文聚焦 ASM 方式通过指令码来改写方法给方法添加TryCatch块用于采集异常信息以及正常的出参结果。从仓库目录可以看到CodeGuide 的字节码编程专题覆盖了 ASM、Javassist、Byte-Buddy 三大框架README.md 的7. 字节码编程章节对整套学习路线做了归档其中 ASM 部分还包括完整的 ASM 官方文档译文是本文深入原理的权威依据。二、系统环境与依赖jdk1.8.0asm-commons 6.2.1本文用到的AdviceAdapter就位于org.objectweb.asm.commons包三、技术目标把方法改造成什么样通过 ASM 字节码增强技术使用指令码将方法修改为我们想要的效果。生产落地时通常需要配合JavaAgent技术在工程启动加载类时修改字节码本文为了把字节码核心内容完整展示出来采用加载类名称获取字节码进行修改的方式更完整的JavaAgent ASM落地方案可参考仓库姊妹篇 《JavaAgentASM字节码插桩采集方法名称以及入参和出参结果并记录方法耗时》。修改之前的方法public Integer strToNumber(String str) { return Integer.parseInt(str); }修改之后的方法public Integer strToNumber(String str) { try { Integer var2 Integer.parseInt(str); MethodTest.point(org.itstack.test.MethodTest$Test.strToNumber, var2); return var2; } catch (Exception var3) { MethodTest.point(org.itstack.test.MethodTest$Test.strToNumber, var3); throw var3; } }对比修改前后主要有两点变化返回值赋值给新的局部变量并做了输出原本return的表达式结果被保存到var2先调用监控方法point输出再return var2整个方法被包裹在TryCatch中捕获到异常后把异常信息也交给point输出随后throw var3原样抛出保证原有异常语义不变。想通这一点你就能意识到把它用到自己的业务中就可以做一套非入侵的监控系统了。四、实现过程字节码增强的过程乍一看比较麻烦如果没有阅读过 JVM 虚拟机规范等相关书籍确实不好理解。但正是这部分不那么容易理解的知识才是后续价值的体现。仓库中恰好有完整的 JVM 指令表 和 字节代码指令附录 可供随时查阅。1. 搭建字节码处理框架/** * 字节码增强获取新的字节码 */ private byte[] getBytes(String className) throws IOException { ClassReader cr new ClassReader(className); ClassWriter cw new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); cr.accept(new ClassVisitor(ASM5, cw) { public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { // 方法过滤 if (!strToNumber.equals(name)) return super.visitMethod(access, name, descriptor, signature, exceptions); MethodVisitor mv super.visitMethod(access, name, descriptor, signature, exceptions); return new AdviceAdapter(ASM5, mv, access, name, descriptor) { // 方法进入时修改字节码 protected void onMethodEnter() {} // 访问局部变量和操作数栈 public void visitMaxs(int maxStack, int maxLocals) {} // 方法退出时修改字节码 protected void onMethodExit(int opcode) {} }; } }, ClassReader.EXPAND_FRAMES); return cw.toByteArray(); }这段代码就是 ASM 用于处理字节码增强的模板代码块ClassReader/ClassWriter分别负责类的读取和写入。加载方式在构造方法中提供得比较丰富可以通过类名、字节码或流的方式处理。姊妹篇 2020-04-05 插桩篇 中就是通过new ClassReader(classfileBuffer)以字节数组方式加载两种入口对应不同的落地场景。ClassWriter.COMPUTE_MAXS让 ASM 自动计算方法的最大栈深maxStack与局部变量数maxLocals省去手工维护的负担。ASM 文档 3.3 工具 中也指出实践中通过COMPUTE_MAXS计算最优maxStack的效率远高于使用AnalyzerAdapter手工推导。ClassReader.EXPAND_FRAMES展开栈映射帧配合visitFrame时更新帧信息保证改写后的方法能被 JVM 验证器接受。方法过滤visitMethod中通过name只处理目标方法strToNumber其余方法原样透传。这也是所有 ASM 监控系统的通用做法——在MethodVisitor层做字节码注入。方法访问层用到了AdviceAdapter的三个钩子基本所有 ASM 字节码增强操作都离不开它们方法时机用途onMethodEnter方法进入时设置基本内容如记录起始纳秒、标记Try块开始visitMaxs方法结束前添加Catch块将整个方法包裹起来onMethodExit方法退出时、RETURN之前注入结尾字节码如调用外部方法输出监控信息关于AdviceAdapter的定位ASM 文档 3.3.4 AdviceAdapter 有权威说明它是一个抽象类可用于在方法的开头以及恰在任意RETURN或ATHROW指令之前插入代码。它的最大优势是对构造器同样有效——在构造器中不能把代码恰好插入到开头而必须插在对超构造器super(...)的调用之后AdviceAdapter内部专门检测了这个调用同时它继承自LocalVariablesSorter可以方便地使用newLocal申请新的局部变量槽位本文第 4、5 节正是这么用的。2. 获取方法返回值被测试的方法public Integer strToNumber(String str) { return Integer.parseInt(str); }编写指令onMethodExit方法Override protected void onMethodExit(int opcode) { if ((IRETURN opcode opcode RETURN) || opcode ATHROW) { int nextLocal this.nextLocal; mv.visitVarInsn(ASTORE, nextLocal); // 将栈顶引用类型值保存到局部变量indexbyte中。 mv.visitVarInsn(ALOAD, nextLocal); // 从局部变量indexbyte中装载引用类型值入栈。 } }逐条说明this.nextLocal获取局部变量的索引值即当前局部变量表的末尾位置用于存放ARETURN的值ARETURN返回对象类型如果是返回int则需要使用IRETURN。ASTORE将栈顶引用类型值保存到局部变量。可以在脑中想象方法里有局部变量区和操作数栈两块区域指令在执行中不断压栈、弹栈。ALOAD从局部变量装载引用类型值入栈将刚才保存的值放回操作数栈供后续输出使用。被初次增强后的方法public Integer strToNumber(String str) { Integer var2 Integer.parseInt(str); return var2; }原本的返回值被赋值到一个参数上之后再由return将参数返回。这样我们就拿到了方法出参var2可以对它进行输出操作了。3. 输出方法返回值定义输出结果方法public static void point(String methodName, Object response) { System.out.println(系统监控 :: [方法名称 methodName 输出信息 JSON.toJSONString(response) ]\r\n); }在onMethodExit中使用字节码增强调用这个静态方法Override protected void onMethodExit(int opcode) { if ((IRETURN opcode opcode RETURN) || opcode ATHROW) { ... mv.visitLdcInsn(className . name); // 类名.方法名 mv.visitVarInsn(ALOAD, nextLocal); mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(MethodTest.class), point, (Ljava/lang/String;Ljava/lang/Object;)V, false); } }mv.visitLdcInsn(className . name)把常量池中的常量值int、float、string reference、object reference入栈即把类名.方法名字符串写入常量池。mv.visitVarInsn(ALOAD, nextLocal)把上面保存的返回值加载到操作数栈。mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(MethodTest.class), point, (Ljava/lang/String;Ljava/lang/Object;)V, false)调用静态方法。INVOKESTATIC是调用指令后面是方法所属类的内部名、方法名、方法描述。(Ljava/lang/String;Ljava/lang/Object;)V表示String和Object两个入参V表示返回空即方法void point(String methodName, Object response)。这里用到的Type是 ASM 提供的运行时工具类ASM 文档 2.3.1 Type 说明getInternalName()返回类的内部名如java/lang/StringgetDescriptor()返回类型描述符getArgumentTypes/getReturnType可以解析方法描述符是编写字节码时的常用辅助。再次被增强后的方法public Integer strToNumber(String str) { Integer var2 Integer.parseInt(str); point(org.itstack.test.MethodTest.strToNumber, var2); return var2; }增强后每次调用这个方法都会输出方法名称和出参结果。但还遗留一个问题如果抛异常了就监控不到了4. 给方法加上 TryCatch添加TryCatch开始onMethodEnterprivate Label from new Label(), to new Label(), target new Label(); Override protected void onMethodEnter() { //标志try块开始位置 visitLabel(from); visitTryCatchBlock(from, to, target, java/lang/Exception); }在onMethodEnter()中加入TryCatch开始块这是 ASM 中的固定模式按需添加即可。添加TryCatch结尾visitMaxsOverride public void visitMaxs(int maxStack, int maxLocals) { //标志try块结束 mv.visitLabel(to); //标志catch块开始位置 mv.visitLabel(target); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{java/lang/Exception}); // 异常信息保存到局部变量 int local newLocal(Type.LONG_TYPE); mv.visitVarInsn(ASTORE, local); // 抛出异常 mv.visitVarInsn(ALOAD, local); mv.visitInsn(ATHROW); super.visitMaxs(maxStack, maxLocals); }在visitMaxs方法中完成TryCatch的结尾捕获异常后请原样抛出。mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{java/lang/Exception})在指定方法操作数栈中将TryCatch处理完成。这几个参数也可以动态拼装局部变量、参数、栈、异常。之所以要显式visitFrame是因为字节码增强改变了控制流后原本的栈映射帧已经失效——这正是 ASM 文档第 8 章方法分析 所讲的数据流分析问题新增的异常处理器入口target处操作数栈上会多出一个Exception引用必须用F_SAME1帧声明否则类加载时会被 JVM 验证器拒绝。ASTORE将异常信息保存到局部变量再用ALOAD放到操作数栈用于抛出。ATHROW抛出异常的指令即throw var。这次增强后的方法public Integer strToNumber(String str) { try { Integer var2 Integer.parseInt(str); point(org.itstack.test.MethodTest.strToNumber, var2); return var2; } catch (Exception var3) { throw var3; } }此时整个方法已经被包装到TryCatch中下一步就是把异常信息也打印出来。5. 输出异常信息定义输出异常方法public static void point(String methodName, Throwable throwable) { System.out.println(系统监控 :: [方法名称 methodName 异常信息 throwable.getMessage() ]\r\n); }在visitMaxs中把调用外部方法的内容集成进抛出异常的逻辑Override public void visitMaxs(int maxStack, int maxLocals) { ... // 输出信息 mv.visitLdcInsn(className . name); // 类名.方法名 mv.visitVarInsn(ALOAD, local); mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(MethodTest.class), point, (Ljava/lang/String;Ljava/lang/Throwable;)V, false); ... }mv.visitLdcInsn加载常量即类名和方法名。ALOAD将异常信息加载到操作数栈用于输出。INVOKESTATIC调用静态方法。Java 中的方法调用指令除了INVOKESTATIC外还有invokespecial调用私有/构造/超类方法、invokevirtual普通实例方法分派、invokeinterface接口方法分派可以参考 JVM 指令表 加深印象。现在再看字节码增强后的方法public Integer strToNumber(String str) { try { Integer var2 Integer.parseInt(str); point(org.itstack.test.MethodTest.strToNumber, (Object)var2); return var2; } catch (Exception var3) { point(org.itstack.test.MethodTest.strToNumber, (Throwable)var3); throw var3; } }至此这个方法已通过字节码彻底改造完成正常路径输出出参异常路径输出异常信息后原样抛出。对外输出的方法后续可以通过 MQ 等机制推送出去用于图表展示监控信息。6. 核心指令速查把上面用到的指令汇总如下方便对照 JVM 指令表 学习指令作用本文用途ASTORE将栈顶引用类型值保存到局部变量保存返回值 / 异常对象ALOAD从局部变量装载引用类型值入栈把返回值 / 异常重新压栈供输出LDC常量池常量值入栈把类名.方法名压栈作为入参INVOKESTATIC调用静态方法调用point(...)输出监控信息ATHROW抛出异常增强后原样抛出捕获到的异常visitTryCatchBlock声明异常处理器范围圈定 try 块起止与 catch 入口visitFrame写栈映射帧修正异常处理入口的帧状态五、测试验证测试方法是一个字符串转数字的方法通过传入不同参数验证数字字符串正常返回非数字字符串触发异常分支。另外要注意通过字节码增强改造后方法反馈给我们的仍然是字节码需要使用ClassLoader重新加载后执行。测试方法public static void main(String[] args) throws Exception { // 方法字节码增强 byte[] bytes new MethodTest().getBytes(MethodTest.class.getName()); // 输出方法新字节码 outputClazz(bytes, MethodTest.class.getSimpleName()); // 测试方法 Class? clazz new MethodTest().defineClass(org.itstack.test.MethodTest, bytes, 0, bytes.length); Method queryUserInfo clazz.getMethod(strToNumber, String.class); // 正确入参测试验证结果输出 Object obj01 queryUserInfo.invoke(clazz.newInstance(), 123); System.out.println(01 测试结果 obj01); // 异常入参测试验证打印异常信息 Object obj02 queryUserInfo.invoke(clazz.newInstance(), abc); System.out.println(02 测试结果 obj02); }输出结果ASM字节码增强后类输出路径/User/itstack/git/github.com/WormholePistachio/SQM/target/test-classes/MethodTestSQM.class 系统监控 :: [方法名称org.itstack.test.MethodTest.strToNumber 输出信息123] 01 测试结果123 系统监控 :: [方法名称org.itstack.test.MethodTest.strToNumber 异常信息For input string: abc] Process finished with exit code 1从输出可以看到正常入参123时监控输出出参123方法正常返回异常入参abc时Integer.parseInt抛出NumberFormatException被我们织入的 catch 块捕获并输出For input string: abc后原样抛出程序以 exit code 1 结束——异常语义没有被破坏但异常信息已经完整落到了监控输出里。六、从单方法到全方法如何扩展成真正的监控组件本文为了突出字节码核心内容只对strToNumber一个方法做增强。生产级的非入侵监控需要回答两个问题给哪些方法增强增强后输出什么1. 方法过滤与描述解析在visitMethod中把!strToNumber.equals(name)换成自己的过滤规则如排除init、clinit只处理业务包路径即可批量织入。更进一步的实现可以参考姊妹篇 2020-04-05 插桩篇方法的入参和出参在字节码中被描述成一段指定码如(II)Ljava/lang/String;表示两个int入参、一个String出参复杂描述如(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;IJ[I[[Ljava/lang/Object;Lorg/itstack/test/Req;)Ljava/lang/String;需要使用正则(L.*?;|\\[{0,2}L.*?;|[ZCBSIFJD]|\\[{0,2}[ZCBSIFJD]{1})逐块拆解8 个基本类型Z C B S I F J D需要先装箱Integer.valueOf等才能放进Object[]数组。2. 入参采集与全局方法 ID在onMethodEnter中先用INVOKESTATIC System.nanoTime()LSTORE记录开始时间再通过BIPUSH/ICONST_xANEWARRAY创建参数数组、AASTORE逐项赋值在onMethodExit中把耗时、方法 ID、入参数组、出参一起交给ProfilingAspect.point(...)输出。为了不在每次调用时重复传递方法信息可以为每个方法预生成一个全局唯一methodIdAtomicInteger自增 AtomicReferenceArrayMethodTag存放增强时只压入一个int即可。这套onMethodEnter采集入参、onMethodExit输出出参的模式与 ASM 文档 3.3.4 节的 AddTimerMethodAdapter 示例 中进入记时、退出结算的写法一脉相承——包括(opcode IRETURN opcode RETURN) || opcode ATHROW这个返回值类型判断正是源自该示例的经典写法。字节码增强的骨架一旦掌握换成记耗时采集入参织入 TryCatch都只是在这三个钩子里填不同的指令而已。3. 从案例工程到全链路监控CodeGuide 仓库还提供了完整的进阶路径基于JavaAgent的 全链路监控系列ThreadLocal 链路追踪、JVM 内存与 GC 信息、开发应用级监控以及 字节码插桩技术调研用于系统监控设计和实现。把这些与本文的 TryCatch 织入技术组合就能拼出一套完整的非入侵服务质量监控方案。七、总结通过字节码指令控制代码的编写注入完成功能的同时也加深了对 JVM 虚拟机的理解——不再只是硬背理论而是彻底实践。可以配合仓库的 用 Java 实现 JVM 系列 从解释器视角再看一遍ASTORE、ATHROW等指令是如何被执行的。掌握字节码编程后可以在很多场景中建设高级玩法非入侵监控系统、全链路监控、反射框架等底层其实都用到了 ASM。翻看 Spring、MyBatis 等框架源码也会更容易读懂。深入研究可阅读JVM 虚拟机规范与仓库内的 ASM 文档译文涵盖类、方法、工具、方法分析、后向兼容等章节以及 字节码编程入门篇《如果你只写CRUD那这种技术你永远碰不到》系统补齐 ASM 的完整知识版图。赞分享文档教程后端【免费下载链接】CodeGuide:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总旨在为大家提供一个清晰详细的学习教程侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助请给予支持(关注、点赞、分享)项目地址https://gitcode.com/gh_mirrors/code/CodeGuide点击查看免费下载相关推荐CodeGuide 中间件实战非入侵监控设计之 ASM 字节码插桩CodeGuide 中间件实战非入侵监控设计之 ASM 字节码插桩 本文源自小傅哥《SpringBoot 中间件设计和开发》专栏第 16 章。在大型互联网架构文档教程后端基于 Javassist 字节码插桩的方法级监控采集运行时入参、出参与异常信息CodeGuide 实战基于 Javassist 字节码插桩的方法级监控采集运行时入参、出参与异常信息CodeGuide 实战 字节码插桩技术常与 JavaAgent 探针结合文档教程后端JavaAgent ASM 字节码探针实战以 IDEA 破解 Jar 包为例拆解非入侵式类增强原理JavaAgent ASM 字节码探针实战以 IDEA 破解 Jar 包为例拆解非入侵式类增强原理 本文以开源仓库 CodeGuide https://文档教程后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

ONS15454配置实战指南:从PPT幻灯片到可执行CLI命令

ONS15454配置实战指南:从PPT幻灯片到可执行CLI命令

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

2026/9/24 4:52:31 阅读更多 →
烽火HG680KA刷机变砖救砖全攻略:短接强刷与固件校验实战

烽火HG680KA刷机变砖救砖全攻略:短接强刷与固件校验实战

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

2026/9/24 4:52:31 阅读更多 →
老式锅包肉:从用料配比到三次复炸的完整工艺指南(all-in-rag 食谱知识库实战)

老式锅包肉:从用料配比到三次复炸的完整工艺指南(all-in-rag 食谱知识库实战)

教程人工智能大模型RAG 【免费下载链接】all-in-rag 🔍大模型应用开发实战一:RAG 技术全栈指南,在线阅读地址:https://datawhalechina.github.io/all-in-rag/ 项目地址: https://gitcode.com/datawhalechina/all-in-ra…

2026/9/24 4:52:31 阅读更多 →

最新新闻

Mac录屏全攻略:自带工具与OBS等专业方案选型指南

Mac录屏全攻略:自带工具与OBS等专业方案选型指南

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

2026/9/24 6:21:22 阅读更多 →
VC6.0程序在Win11上闪退?三步修复兼容性实战指南

VC6.0程序在Win11上闪退?三步修复兼容性实战指南

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

2026/9/24 6:21:22 阅读更多 →
STM32G4 ADC硬件过采样与软件滤波实战:从配置到代码落地

STM32G4 ADC硬件过采样与软件滤波实战:从配置到代码落地

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

2026/9/24 6:21:22 阅读更多 →
VCS后仿真SDF警告处理:编译选项实战指南

VCS后仿真SDF警告处理:编译选项实战指南

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

2026/9/24 6:21:22 阅读更多 →
球杆平衡系统:从PID到LQR的控制算法实战指南

球杆平衡系统:从PID到LQR的控制算法实战指南

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

2026/9/24 6:21:22 阅读更多 →
Presto Release 0.161 技术详解:ORDER BY 语义变更、EXCEPT 正确性修复与连接器增强

Presto Release 0.161 技术详解:ORDER BY 语义变更、EXCEPT 正确性修复与连接器增强

大数据数据库后端 【免费下载链接】presto The official home of the Presto distributed SQL query engine for big data 项目地址: https://gitcode.com/gh_mirrors/pre/presto 点击查看 免费下载 导读 本文基于 Presto 官方发布说明 release-0.161.rst&#xf…

2026/9/24 6:20:22 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →