当前位置: 首页 > article >正文

项目总结:java agent的使用

测试团队会做java agent的事,实现测试模拟,各种数据采集等等工作,而这些不需要开发改代码来做到,只需要挂载下agent。

目录

    • javaagent认识和例子代码
      • 例子:
      • java.lang.instrument
      • 自定义实现一个javaagent
      • agent jar测试
    • 回顾javaagent的作用
    • 项目中用到agent的例子

javaagent认识和例子代码

例子:

java -javaagent:/Users/mubi/git_workspace/common1/common-test/target/common-test-1.0-SNAPSHOT-jar-with-dependencies.jar com.test.AgentTest

在这里插入图片描述

不改变代码,而是在java命令后加入-javaagent:xx.jar实现对class的干预

java.lang.instrument

https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html

Provides services that allow Java programming language agents to instrument programs running on the JVM.

即在Java编程语言中,允许Java代理(Agents)进行代码插装(Instrumentation)的服务主要由Java Agent API提供。这个API允许开发者在运行时动态修改或增强Java应用程序的字节码,而无需修改源代码或重新编译。这对于性能监控、调试、安全增强等场景非常有用。

自定义实现一个javaagent

  • MyAgent
package com.test;import java.lang.instrument.Instrumentation;/*** @Author mubi* @Date 2025/2/11 21:45*/
public class MyAgent {/*** jvm 参数形式启动,运行此方法** @param agentArgs agentArgs 是我们启动 Java Agent 时带进来的参数,比如-javaagent:xxx.jar agentArgs* @param inst*/public static void premain(String agentArgs, Instrumentation inst) {System.out.println("premain");customLogic(inst);}/*** 动态 attach 方式启动,运行此方法** @param agentArgs* @param inst*/public static void agentmain(String agentArgs, Instrumentation inst) {System.out.println("agentmain");customLogic(inst);}/*** 打印所有已加载的类名称 修改字节码** @param inst*/private static void customLogic(Instrumentation inst) {inst.addTransformer(new MyTransformer(), true);}
}
  • 使用javaassist改变class文件
package com.test;import java.io.ByteArrayInputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;/*** javassist 官方文档:http://www.javassist.org/tutorial/tutorial.html*/
public class MyTransformer implements ClassFileTransformer {@Overridepublic byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
//        System.out.println("正在加载类:" + className);if (!"com/test/Hello".equals(className)) {return classfileBuffer;}CtClass cl = null;try {ClassPool classPool = ClassPool.getDefault();cl = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));CtMethod ctMethod = cl.getDeclaredMethod("test");System.out.println("获取方法名称:" + ctMethod.getName());// 声明本地变量ctMethod.addLocalVariable("start", CtClass.longType);ctMethod.addLocalVariable("end", CtClass.longType);ctMethod.insertBefore("System.out.println(\" 动态插入的打印语句 \");");ctMethod.insertBefore("start = System.currentTimeMillis();");// $_在Javassist中是一个特殊的变量,代表当前正在处理的类或方法中的表达式ctMethod.insertAfter("System.out.println($_);");ctMethod.insertAfter("end = System.currentTimeMillis();");// 输出耗时ctMethod.insertAfter("System.out.println((end-start) + \" ms\");");byte[] transformed = cl.toBytecode();return transformed;} catch (Exception e) {e.printStackTrace();}return classfileBuffer;}
}
  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>common1</artifactId><groupId>com.container</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>common-test</artifactId><repositories></repositories><build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>2.5.5</version><executions><execution><goals><goal>attached</goal></goals><id>make-assembly</id><phase>package</phase><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifestEntries><Premain-Class>com.test.MyAgent</Premain-Class><Agent-Class>com.test.MyAgent</Agent-Class><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes></manifestEntries></archive></configuration></execution></executions></plugin></plugins></build><properties><spring.verson>5.1.3.RELEASE</spring.verson></properties><dependencies><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.27.0-GA</version></dependency><dependency><groupId>org.ow2.asm</groupId><artifactId>asm</artifactId><version>9.2</version></dependency><dependency><groupId>org.ow2.asm</groupId><artifactId>asm-commons</artifactId><version>9.2</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies></project>

即加入:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>2.5.5</version><executions><execution><goals><goal>attached</goal></goals><id>make-assembly</id><phase>package</phase><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifestEntries><Premain-Class>com.test.MyAgent</Premain-Class><Agent-Class>com.test.MyAgent</Agent-Class><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes></manifestEntries></archive></configuration></execution></executions></plugin>

按照要求:

An agent JAR file may have both the Premain-Class and Agent-Class attributes present in the manifest. When the agent is started on the command-line using the -javaagent option then the Premain-Class attribute specifies the name of the agent class and the Agent-Class attribute is ignored. Similarly, if the agent is started sometime after the VM has started, then the Agent-Class attribute specifies the name of the agent class (the value of Premain-Class attribute is ignored).

一个代理 JAR 文件可能在清单中同时具有 Premain-Class 和 Agent-Class 属性。 当使用 -javaagent 选项在命令行上启动代理时,Premain-Class 属性指定代理类的名称,而 Agent-Class 属性将被忽略。 同样,如果代理在 VM 启动后的某个时间启动,则 Agent-Class 属性指定代理类的名称(忽略 Premain-Class 属性的值)

打包生成agent jar

在这里插入图片描述

agent jar测试

定义Hello类

package com.test;import java.util.concurrent.TimeUnit;/*** @Author mubi* @Date 2025/2/11 23:20*/
public class Hello {public String test() {try {TimeUnit.SECONDS.sleep(1);System.out.println("hello logic");} catch (Exception e) {}return "hello test";}
}

测试类并加上agent参数-javaagent:/Users/mubi/git_workspace/common1/common-test/target/common-test-1.0-SNAPSHOT-jar-with-dependencies.jar

在这里插入图片描述

测试输出如下:

在这里插入图片描述
即完成了代理行为。

回顾javaagent的作用

JVM启动后,JVM会执行指定Agent类的premain()方法,在premain()中可以调用Instrumentation对象的addTransformer方法注册ClassFileTransformer。当JVM加载类时会将类文件的字节数组传递给ClassFileTransformer的transform方法,在transform方法中对Class文件进行解析和修改,之后JVM就会加载转换后的Class文件。

这样实例化后执行代理了的方法就能完成,因为class文件被改过且加载好了。

在这里插入图片描述

项目中用到agent的例子

当一个入口流程开始后,可能因为不同的输入,执行了不同的链路。业务如果有扩展,那么就需要是否有执行,以及执行情况。

如下 AppProcess的entry方法 的入参不同,调用的扩展点实现也是不同,通过java agent 可以采集到信息
在这里插入图片描述

  • 主程序
package com.pro.biz;import java.util.ArrayList;
import java.util.List;public class AppProcess {/*** 扩展点*/List<StrService> strServiceList;public AppProcess() {strServiceList = new ArrayList<>();}public void setStrServiceList(){strServiceList.add(new X());strServiceList.add(new Y());}public void entry(String name) {String s = null;if (name.equals("one")) {s = strServiceList.get(0).dealStr(name);System.out.println("entry:" + s);return;}if (name.equals("all")) {for (StrService strService : strServiceList) {s = strService.dealStr(name);System.out.println("entry:" + s);}return;}}
}
  • 扩展点和实现类
    在这里插入图片描述

  • Agent类

package com.pro.agent;import java.lang.instrument.Instrumentation;/*** @Author mubi* @Date 2025/2/12 22:54*/
public class StatAgent {/*** jvm 参数形式启动,运行此方法** @param agentArgs agentArgs 是我们启动 Java Agent 时带进来的参数,比如-javaagent:xxx.jar agentArgs* @param inst*/public static void premain(String agentArgs, Instrumentation inst) {
//        System.out.println("premain");customLogic(inst);}/*** 动态 attach 方式启动,运行此方法** @param agentArgs* @param inst*/public static void agentmain(String agentArgs, Instrumentation inst) {
//        System.out.println("agentmain");customLogic(inst);}/*** 打印所有已加载的类名称 修改字节码** @param inst*/private static void customLogic(Instrumentation inst) {inst.addTransformer(new StatTransformer(), true);}
}
package com.pro.agent;import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;import java.io.ByteArrayInputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;/*** @Author mubi* @Date 2025/2/12 22:55*/
public class StatTransformer implements ClassFileTransformer {@Overridepublic byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
//        if (!"com/pro/biz/AppProcess".equals(className)) {
//            return classfileBuffer;
//        }CtClass cl = null;try {ClassPool classPool = ClassPool.getDefault();cl = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));CtMethod ctMethod = null;try{ctMethod = cl.getDeclaredMethod("dealStr");}catch (Exception e){}if(ctMethod != null && !className.equals("com/pro/biz/StrService")) {
//                System.out.println("获取到方法名称:" + ctMethod.getName());
//                System.out.println(className);//                ctMethod.insertBefore("System.out.println(\"入参: \" + $1);");
//                ctMethod.insertAfter("System.out.println(\"出参: \" + $_);");ctMethod.insertAfter("com.pro.stat.StrServiceCallStats.addCallInfo($0.getClass().getName(), $1, $_);");//                StringBuilder methodBody = new StringBuilder();
//                methodBody.append("{")
//                        .append("System.out.println(\"Input: \" + $1);") // input parameter
//                        .append("$r = $proceed($$);") // proceed with the original method
                        .append("System.out.println(\"Output: \" + result);") // output
//                        .append("return $r;")
//                        .append("}");
//
//                // Modify the method
//                ctMethod.setBody(methodBody.toString());}// 插入统计代码
//            String insertBeforeCode = "{ $_ = $proceed($$); " +
//                    "StrServiceCallStats.addCallInfo($0.strServiceList.get($index).getClass().getName(), $1, $_); }";
//            entryMethod.insertBefore(insertBeforeCode);byte[] transformed = cl.toBytecode();return transformed;} catch (Exception e) {e.printStackTrace();}return classfileBuffer;}
}
  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>common1</artifactId><groupId>com.container</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>common-project</artifactId><build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>2.5.5</version><executions><execution><goals><goal>attached</goal></goals><id>make-assembly</id><phase>package</phase><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifestEntries><Premain-Class>com.pro.agent.StatAgent</Premain-Class><Agent-Class>com.pro.agent.StatAgent</Agent-Class><Can-Redefine-Classes>true</Can-Redefine-Classes><Can-Retransform-Classes>true</Can-Retransform-Classes></manifestEntries></archive></configuration></execution></executions></plugin></plugins></build><properties><spring.verson>5.1.3.RELEASE</spring.verson></properties><dependencies><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.29.0-GA</version></dependency><dependency><groupId>org.ow2.asm</groupId><artifactId>asm</artifactId><version>9.2</version></dependency><dependency><groupId>org.ow2.asm</groupId><artifactId>asm-commons</artifactId><version>9.2</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies></project>

打包后生成agent jar, 运行时加上-javaagent:/Users/mubi/git_workspace/common1/common-project/target/common-project-1.0-SNAPSHOT-jar-with-dependencies.jar

相关文章:

项目总结:java agent的使用

测试团队会做java agent的事&#xff0c;实现测试模拟&#xff0c;各种数据采集等等工作&#xff0c;而这些不需要开发改代码来做到&#xff0c;只需要挂载下agent。 目录 javaagent认识和例子代码例子&#xff1a;java.lang.instrument自定义实现一个javaagentagent jar测试 回…...

使用 LangChain 对接硅基流动(SiliconFlow)API:构建一个智能对话系统

文章目录 什么是硅基流动&#xff08;SiliconFlow&#xff09;&#xff1f;LangChain 简介在 LangChain 中对接硅基流动步骤 1&#xff1a;安装必要的库步骤 2&#xff1a;设置 API 密钥步骤 3&#xff1a;编写代码代码解析步骤 4&#xff1a;运行代码如何扩展和改进总结 在现代…...

如何借助NoETL指标平台实现数据分析、决策的提效?

通常&#xff0c;企业通过明确分析目标、定位所需分析的数据&#xff0c;再通过多渠道汇集销售数据、客户反馈、市场调研等信息&#xff0c;经过数据清洗、缺失值处理及格式标准化等手段&#xff0c;运用描述性统计、回归分析、聚类分析及关联规则挖掘等多样分析方法&#xff0…...

Java--IO流详解 (上)--字符流

目录 IO流的概念 字符流 输入流 Reader核心方法 1.close() 2.mark(int readAheadLimit) 3.markSupported() 4.read() 5.read(char[] cbuf) 6.read(char[] cbuf, int off, int len) 7.read(CharBuffer target) 8.ready() 9.reset() 10.skip(long n) Reader 的常用…...

大模型语言简介

大模型语言能做什么 信息提取 将长段文字中的信息抽取出来并且以结构化的方式输出。相比起传统NLP的方式&#xff0c;大模型在泛化能力上有非常大的提升&#xff0c;并且开发成本要低2个数量级。应用场景包括&#xff1a;论文论点论据提取、用户画像提取、舆情分析、病例结构…...

手动配置IP

手动配置IP&#xff0c;需要考虑四个配置项&#xff1a; 四个配置项 IP地址、子网掩码、默认网关、DNS服务器 IP地址&#xff1a;格式表现为点分十进制&#xff0c;如192.168.254.1 子网掩码&#xff1a;用于区分网络位和主机位 【子网掩码的二进制表达式一定是连续的&#…...

Golang 进阶训练营

一、Golang 的 slice、map、channel 1.1 slice vs array a : make([]int, 100) //切片 b : [100]int{} //数组array需指明长度&#xff0c;长度为常量且不可改变 array长度为其类型中的组成部分&#xff08;给参数为长度100的数组的方法传长度为101的会报错&#xff09; array在…...

2-使用wifidog实现portal

wifidog是openwrt上面实现portal认证的一个开源工具&#xff0c;从网关端到服务器都帮你搭建好&#xff0c;通过学习wifidog的原理&#xff0c;后面就可以改造成自己需要的逻辑。 1. openwrt安装wifidog 添加源 vim 14.07/feeds.conf.defaultsrc-git wifidog https://github.c…...

Spring Boot + ShardingSphere 踩坑记

最近在准备秋招&#xff0c;偷了个轮子项目之后想改个分表&#xff0c;于是有了这篇文章。 省流&#xff1a;请使用shardingsphere-jdbc 5.5.2&#xff0c;并根据官方5.5.2版本文档进行配置&#xff0c;不要使用starter。此外&#xff0c;如果希望使用INTERVAL分片算法&#x…...

AI时代前端开发的创造力:解放还是束缚?

在人工智能&#xff08;AI&#xff09;快速发展的时代&#xff0c;AI技术的影响已经渗透到各个领域&#xff0c;从医疗保健到金融服务&#xff0c;再到创意产业。AI工具的出现&#xff0c;为前端开发带来了前所未有的效率提升&#xff0c;但也引发了人们对创造力的担忧&#xf…...

有哪些免费的SEO软件优化工具

随着2025年互联网的不断发展&#xff0c;越来越多的企业意识到在数字营销中&#xff0c;网站的曝光度和排名至关重要。无论是想要提高品牌知名度&#xff0c;还是想要通过在线销售增加收益&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;都是一项不可忽视的关键策略。而要…...

FastExcel + Java:打造高效灵活的Excel数据导入导出解决方案

作者&#xff1a;后端小肥肠 &#x1f347; 我写过的文章中的相关代码放到了gitee&#xff0c;地址&#xff1a;xfc-fdw-cloud: 公共解决方案 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; 基于AOP的数据字典实现…...

在Vue中,JavaScript数组常用方法,添加,插入,查找,删除等整理

在Vue中&#xff0c;JavaScript数组常用&#xff0c;添加&#xff0c;插入&#xff0c;查找&#xff0c;删除等整理 1.splice()方法可以直接修改原数组&#xff0c;通过指定要删除元素的索引来删除它。 例&#xff1a; let index // 要删除的元素的索引; this.array.splice(i…...

vue知识点2

1.methods和mounted的区别 methods是定义方法&#xff0c;不涉及到调用 mounted涉及到操作 所以methods后面是&#xff1a;&#xff0c;mounted后面是&#xff08;&#xff09; 2.介绍一下emit的用法 如果子控件要调用父页面的方法&#xff0c;在父页面的子控件引用处&…...

node.js + html调用ChatGPTApi实现Ai网站demo(带源码)

文章目录 前言一、demo演示二、node.js 使用步骤1.引入库2.引入包 前端HTML调用接口和UI所有文件总结 前言 关注博主&#xff0c;学习每天一个小demo 今天是Ai对话网站 又到了每天一个小demo的时候咯&#xff0c;前面我写了多人实时对话demo、和视频转换demo&#xff0c;今天…...

14.Python生成器、迭代器、闭包、装饰器、元类、垃圾回收、内建函数

在 Python 中&#xff0c;生成器、迭代器、闭包、装饰器、元类、垃圾回收和内建函数是一些重要的概念和功能&#xff0c;它们对于编写高效、灵活的代码非常重要。下面我们逐一详细介绍这些概念及其用法。 1. 生成器&#xff08;Generator&#xff09; 生成器是一个函数&#…...

STM32+Proteus+DS18B20数码管仿真实验

1. 实验准备 硬件方面&#xff1a; 了解 STM32 单片机的基本原理和使用方法&#xff0c;本实验可选用常见的 STM32F103 系列。熟悉 DS18B20 温度传感器的工作原理和通信协议&#xff08;单总线协议&#xff09;。数码管可选用共阴极或共阳极数码管&#xff0c;用于显示温度值。…...

Vulhub靶机 ActiveMQ 反序列化漏洞(CVE-2015-5254)(渗透测试详解)

一、开启vulhub环境 docker-compose up -d 启动 docker ps 查看开放的端口 漏洞版本&#xff1a;Apache ActiveMQ 5.x ~ Apache ActiveMQ 5.13.0 二、访问靶机IP 8161端口 默认账户密码 admin/admin&#xff0c;登录 此时qucues事件为空 1、使用jmet-0.1.0-all.jar工具将…...

ConcurrentHashMap扩容

目录 一、tryPreSize方法-初始化数组 二、tryPreSize方法-扩容标识戳 三、transfer方法-构建新数组 四、transfer方法-迁移数据 五、transfer方法-lastRun机制 六、helpTransfer方法-协助扩容 三种触发方式 达到了扩容的阈值 一、tryPreSize方法-初始化数组 // 扩容前…...

2025年二级建造师报名流程图解

2025年二级建造师报名时间&#xff01;附报名流程&#xff01; ⏰️已公布25年二建考试时间的省份如下&#xff1a; ️4月19日、20日考试的城市有&#xff1a;贵州 ️5月10日、11日考试的城市有&#xff1a;湖北、陕西、宁夏、甘肃、福建、浙江、江西、黑龙江、河南、湖南、…...

【自学笔记】人工智能基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 人工智能重点知识点总览一、基础概念与原理1.1 人工智能定义与发展1.2 算法与数据结构1.3 数学基础 二、机器学习2.1 监督学习2.2 无监督学习2.3 强化学习 三、深度…...

hexo 魔改 | 修改卡片透明度

hexo 魔改 | 修改卡片透明度 ** 博客食物用更佳 博客地址 ** 这是笔者自己瞎倒腾的。作为前端菜鸡一枚&#xff0c;大佬们随便看看就好~ 我用的主题是 butterfly 4.12.0 分析 通过开发者工具可以看出来卡片的背景和 --card-bg 变量有关 再在 sources 下的 css 文件夹下的…...

Golang的并发编程案例详解

Golang的并发编程案例详解 一、并发编程概述 并发编程是指程序中有多个独立的执行线索&#xff0c;并且这些线索在时间上是重叠的。在 Golang 中&#xff0c;并发是其核心特性之一&#xff0c;通过 goroutine 和 channel 来支持并发编程&#xff0c;使得程序可以更高效地利用计…...

【升级】阿里云对象存储 HTTPS 根证书升级公告

--时间打败一切...

贪心算法与动态规划的区别

贪心算法&#xff1a;每一步都选择当前最优解&#xff0c;期望通过局部最优达到全局最优。 动态规划&#xff1a;通过分解问题为子问题&#xff0c;存储并重用子问题的解&#xff0c;避免重复计算。 最简单的JS ACM代码举例 贪心算法&#xff1a;找零问题 function greed…...

策略模式-小结

总结一下看到的策略模式&#xff1a; A:一个含有一个方法的接口 B:具体的实行方式行为1,2,3&#xff0c;实现上面的接口。 C:一个环境类&#xff08;或者上下文类&#xff09;&#xff0c;形式可以是&#xff1a;工厂模式&#xff0c;构造器注入模式&#xff0c;枚举模式。 …...

TDengine 性能测试工具 taosBenchmark

简介工具获取运行 无参数模式命令行模式配置文件模式 命令行参数配置文件参数 通用配置参数写入配置参数 数据库相关超级表相关标签列与数据列写入行为相关 查询配置参数 执行指定查询语句查询超级表 订阅配置参数数据类型对照表 配置文件示例 写入 JSON 示例查询 JSON 示例订阅…...

硬件学习笔记--41 电磁兼容试验-5 射频场感应的传导干扰试验介绍

目录 电磁兼容试验-射频场感应的传导干扰试验介绍 1.试验目的 2.试验方法 3.判定依据及意义 电磁兼容试验-射频场感应的传导干扰试验介绍 驻留时间是在规定频率下影响量施加的持续时间。被试设备&#xff08;EUT&#xff09;在经受扫频频带的电磁影响量或电磁干扰的情况下&a…...

泛型 类 接口 方法 通配符

泛型 泛型类 what: 类型参数化 why use&#xff1a; 1. 输出时候是object类型 而不是真正类型转化麻烦 import java.util.ArrayList; import java.util.List;public class ObjectExample {public static void main(String[] args) {List<Object> list new ArrayLi…...

文字转语音(三)FreeTTS实现

项目中有相关的功能&#xff0c;就简单研究了一下。 说明 FreeTTS 是一个基于 Java 的开源文本转语音&#xff08;TTS&#xff09;引擎&#xff0c;旨在将文字内容转换为自然语音输出。 FreeTTS 适合对 英文语音质量要求低、预算有限且需要离线运行 的场景&#xff0c;但若需…...