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

JMH 基准测试实战:Java 性能对比的正确打开方式!

📖 摘要

在Java开发中,我们经常需要比较不同实现方式的性能差异。但如何科学、准确地进行性能测试呢?本文将带你深入理解JMH(Java Microbenchmark Harness)工具,通过实战演示如何正确编写和运行基准测试,避免常见的性能测试陷阱,让你的性能对比结果真实可靠!

📚 目录

  1. 为什么需要JMH?
  2. JMH基础概念
  3. 环境准备
  4. 第一个JMH基准测试
  5. 常用注解详解
  6. 避免性能测试陷阱
  7. 实战案例:字符串拼接性能对比
  8. 高级特性
  9. 总结

🤔 为什么需要JMH?

在日常开发中,我们经常会遇到这样的场景:

long start = System.currentTimeMillis();
// 测试代码
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");

这种简单粗暴的性能测试方式存在很多问题:

  1. JVM预热问题:JVM需要时间"热身",初始执行的代码通常比后续执行慢
  2. 编译器优化:JIT编译器可能会优化掉"无用"代码
  3. 统计误差:单次测试结果不具有代表性
  4. 环境干扰:GC、CPU调度等都会影响结果

JMH是OpenJDK团队开发的专门用于Java微基准测试的工具,它能解决上述所有问题,提供科学、准确的性能测试结果。

📖 JMH基础概念

JMH中有几个核心概念需要理解:

  1. @Benchmark:标记要测试的方法
  2. Mode:测试模式,如吞吐量(Throughput)、平均时间(AverageTime)等
  3. Warmup:预热阶段,让JVM达到稳定状态
  4. Measurement:实际测量阶段
  5. Fork:在独立的JVM进程中运行测试,避免相互干扰
  6. State:测试状态,可用于共享数据

🛠️ 环境准备

1. 添加JMH依赖

使用Maven项目,添加以下依赖:

org.openjdk.jmhjmh-core1.36org.openjdk.jmhjmh-generator-annprocess1.36provided

2. IDE插件(可选)

IntelliJ IDEA有JMH插件,可以方便地运行单个基准测试方法。

🚀 第一个JMH基准测试

让我们从一个最简单的例子开始:

import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;@BenchmarkMode(Mode.AverageTime) // 测试平均执行时间
@OutputTimeUnit(TimeUnit.NANOSECONDS) // 输出结果的时间单位
@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS) // 预热3轮,每轮1秒
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) // 测试5轮,每轮1秒
@Fork(1) // 使用1个进程
@State(Scope.Thread) // 每个测试线程一个实例
public class FirstBenchmark {@Benchmarkpublic void testMethod() {// 这里是被测试的方法int a = 1;int b = 2;int sum = a + b;// 防止被JIT优化掉if (sum != 3) {throw new AssertionError();}}public static void main(String[] args) throws Exception {org.openjdk.jmh.Main.main(args);}
}

运行这个基准测试,你会看到类似如下的输出:

Benchmark                Mode  Cnt  Score   Error  Units
FirstBenchmark.testMethod  avgt    5  0.321 ± 0.012  ns/op

这表示我们的测试方法平均每次执行耗时0.321纳秒。

🏷️ 常用注解详解

JMH提供了丰富的注解来配置基准测试,下面介绍最常用的几个:

1. @BenchmarkMode

定义测试模式,可选值:

  • Throughput:吞吐量,单位时间内的操作数
  • AverageTime:平均时间,每次操作耗时
  • SampleTime:采样时间
  • SingleShotTime:单次执行时间
  • All:所有模式
@BenchmarkMode({Mode.Throughput, Mode.AverageTime})

2. @Warmup

配置预热参数:

  • iterations:预热轮数
  • time:每轮时间
  • timeUnit:时间单位
@Warmup(iterations = 3, time = 100, timeUnit = TimeUnit.MILLISECONDS)

3. @Measurement

配置实际测量参数:

  • iterations:测量轮数
  • time:每轮时间
  • timeUnit:时间单位
@Measurement(iterations = 5, time = 100, timeUnit = TimeUnit.MILLISECONDS)

4. @Fork

指定fork的进程数,避免测试间相互干扰:

@Fork(2) // 使用2个独立进程

5. @State

定义状态对象,用于在不同测试方法间共享数据:

@State(Scope.Thread) // 每个线程一个实例
public class MyState {public int a = 1;public int b = 2;
}@Benchmark
public void testMethod(MyState state) {int sum = state.a + state.b;
}

⚠️ 避免性能测试陷阱

1. 死代码消除(Dead Code Elimination)

JIT编译器会优化掉没有实际效果的代码。例如:

@Benchmark
public void wrongTest() {Math.log(1.0); // 结果没有被使用,会被优化掉
}

正确做法是返回计算结果或使用Blackhole

@Benchmark
public double correctTest() {return Math.log(1.0);
}// 或者
@Benchmark
public void correctTest2(Blackhole blackhole) {blackhole.consume(Math.log(1.0));
}

2. 常量折叠(Constant Folding)

JIT会预先计算常量表达式:

@Benchmark
public int wrongTest() {return 1 + 2; // 会被优化为return 3
}

使用@State注入变量:

@State(Scope.Thread)
public class MyState {public int a = 1;public int b = 2;
}@Benchmark
public int correctTest(MyState state) {return state.a + state.b;
}

3. 循环展开(Loop Unrolling)

JMH会自动处理循环问题,不要手动写循环:

// 错误做法
@Benchmark
public void wrongTest() {for (int i = 0; i < 10000; i++) {// 测试代码}
}// 正确做法
@Benchmark
public void correctTest() {// 单次操作的代码
}

JMH会自动控制迭代次数来获得准确的测量结果。

🎯 实战案例:字符串拼接性能对比

让我们通过一个实际案例来比较不同字符串拼接方式的性能差异:

import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(1)
@State(Scope.Thread)
public class StringConcatBenchmark {private String str1 = "Hello";private String str2 = "World";private String str3 = "JMH";private String str4 = "Benchmark";@Benchmarkpublic String concatWithPlus() {return str1 + str2 + str3 + str4;}@Benchmarkpublic String concatWithStringBuilder() {StringBuilder sb = new StringBuilder();sb.append(str1);sb.append(str2);sb.append(str3);sb.append(str4);return sb.toString();}@Benchmarkpublic String concatWithStringBuffer() {StringBuffer sb = new StringBuffer();sb.append(str1);sb.append(str2);sb.append(str3);sb.append(str4);return sb.toString();}@Benchmarkpublic String concatWithStringFormat() {return String.format("%s%s%s%s", str1, str2, str3, str4);}
}

运行结果可能如下:

Benchmark                              Mode  Cnt      Score      Error  Units
StringConcatBenchmark.concatWithPlus           thrpt    5  12345.678 ±  234.567  ops/ms
StringConcatBenchmark.concatWithStringBuilder  thrpt    5  23456.789 ±  345.678  ops/ms
StringConcatBenchmark.concatWithStringBuffer   thrpt    5  12345.678 ±  123.456  ops/ms
StringConcatBenchmark.concatWithStringFormat   thrpt    5   1234.567 ±   45.678  ops/ms

从结果可以看出:

  1. StringBuilder性能最好
  2. +操作符在现代Java版本中会被优化为StringBuilder,性能也不错
  3. StringBuffer由于同步开销,性能稍差
  4. String.format性能最差

🚀 高级特性

1. 参数化基准测试

使用@Param注解可以测试不同参数下的性能:

@State(Scope.Thread)
public class ParamBenchmark {@Param({"10", "100", "1000"})public int length;private String str;@Setuppublic void setup() {str = new String(new char[length]).replace('\0', 'x');}@Benchmarkpublic String testToUpperCase() {return str.toUpperCase();}
}

2. 分组测试

可以分组比较不同实现:

@Benchmark
@Group("stringCompare")
public boolean compareWithEquals() {return str1.equals(str2);
}@Benchmark
@Group("stringCompare")
public boolean compareWithEqualsIgnoreCase() {return str1.equalsIgnoreCase(str2);
}

3. 时间控制

精确控制测试时间:

@Benchmark
@BenchmarkMode(Mode.SingleShotTime)
@Measurement(batchSize = 10000) // 每轮执行10000次
public void testMethod() {// ...
}

📌 总结

  1. JMH是Java微基准测试的事实标准工具,能提供科学准确的性能数据
  2. 基准测试需要考虑JVM预热、编译器优化等多种因素
  3. 使用@State管理测试状态,避免常量折叠等问题
  4. 使用Blackhole防止死代码消除
  5. 不要手动写循环,JMH会自动处理迭代
  6. 实际项目中,应该针对关键路径进行基准测试
  7. 测试结果要结合具体场景分析,没有绝对的"最优"

通过本文的学习,你应该已经掌握了JMH的基本用法和核心概念。在实际项目中,合理使用JMH可以帮助你做出更科学的性能优化决策,避免过早优化和错误优化。

记住:基准测试只是工具,真正的性能优化应该基于实际业务场景和性能分析!


🔔 最后提醒:性能优化应该遵循"三原则":

  1. 先测量,再优化
  2. 优化关键路径
  3. 保持代码可读性

Happy benchmarking! 🎉

推荐阅读文章

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 什么是 Cookie?简单介绍与使用方法

  • 什么是 Session?如何应用?

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • 如何理解应用 Java 多线程与并发编程?

  • 把握Java泛型的艺术:协变、逆变与不可变性一网打尽

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 如何理解线程安全这个概念?

  • 理解 Java 桥接方法

  • Spring 整合嵌入式 Tomcat 容器

  • Tomcat 如何加载 SpringMVC 组件

  • “在什么情况下类需要实现 Serializable,什么情况下又不需要(一)?”

  • “避免序列化灾难:掌握实现 Serializable 的真相!(二)”

  • 如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)

  • 解密 Redis:如何通过 IO 多路复用征服高并发挑战!

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • “打破重复代码的魔咒:使用 Function 接口在 Java 8 中实现优雅重构!”

  • Java 中消除 If-else 技巧总结

  • 线程池的核心参数配置(仅供参考)

  • 【人工智能】聊聊Transformer,深度学习的一股清流(13)

  • Java 枚举的几个常用技巧,你可以试着用用

  • 由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)

  • 如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系

  • HTTP、HTTPS、Cookie 和 Session 之间的关系

  • 使用 Spring 框架构建 MVC 应用程序:初学者教程

  • 有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误

  • Java Spring 中常用的 @PostConstruct 注解使用总结

  • 线程 vs 虚拟线程:深入理解及区别

  • 深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别

  • 10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!

  • 探索 Lombok 的 @Builder 和 @SuperBuilder:避坑指南(一)

  • 为什么用了 @Builder 反而报错?深入理解 Lombok 的“暗坑”与解决方案(二)

相关文章:

JMH 基准测试实战:Java 性能对比的正确打开方式!

&#x1f4d6; 摘要 在Java开发中&#xff0c;我们经常需要比较不同实现方式的性能差异。但如何科学、准确地进行性能测试呢&#xff1f;本文将带你深入理解JMH&#xff08;Java Microbenchmark Harness&#xff09;工具&#xff0c;通过实战演示如何正确编写和运行基准测试&a…...

etf可以T+0交易吗?

在我国的A股市场中&#xff0c;部分ETF基金支持T0交易&#xff0c;这为投资者提供了更灵活的交易策略。 支持T0交易的ETF基金类型包括&#xff1a; 货币型ETF&#xff1a;主要投资于货币市场工具&#xff0c;如短期债券和银行存款&#xff0c;具有较高的流动性。 债券型ETF&…...

解决问题:Vscode 自动更新不匹配远程服务器版本

避免自动更新&#xff1a; 1. 打开&#xff1a;文件 - 首选项 - 设置 - 应用程序 - 更新&#xff1b; 2. 设置下列选项&#xff1a; 如果已自动更新&#xff0c;如何回退至原有的历史版本 &#xff1a; 去官网下载所需的历史版本&#xff0c;然后直接按流程安装&#xff0c;…...

【Leetcode-Hot100】盛最多水的容器

题目 解答 目的是求面积最大&#xff0c;面积是由两个下标和对应的最小值得到&#xff0c;因此唯一的问题就是如何遍历这两个下标。我采用begin和end两个变量&#xff0c;确保begin是小于end的&#xff0c;使用它们二者求面积&#xff0c;代码如下&#xff1a; 很不幸 出错了…...

FFMEPG常见命令查询

基本参数 表格1&#xff1a;主要参数 参数说明-i设定输入流-f设定输出格式(format) 高于后缀名-ss开始时间-t时间长度codec编解码 表格2&#xff1a;音频参数 参数说明-aframes设置要输出的音频帧数-f音频帧深度-b:a音频码率-ar设定采样率-ac设定声音的Channel数-acodec设定…...

欢迎来到 Codigger Store:Boby周边专区

亲爱的 Codigger 用户们&#xff0c;感谢你们一直以来的支持与热爱&#xff01;你们的每一次代码跳跃、每一次项目成功&#xff0c;都离不开你们对编程的热情和对 Codigger 的信任。为了回馈大家的厚爱&#xff0c;我们在 Codigger Store 中特别开设了 Boby 周边专区&#xff0…...

决策树模型

决策树(TDS) 注意1&#xff1a;决策树有很多种算法&#xff0c;比如&#xff1a;ID3算法&#xff0c;C4.5算法&#xff0c;CART算法&#xff0c;这三个算法的区别是选择最优划分属性的方法不同&#xff0c;第一个是根据信息增益来选&#xff1b;第二个是找出信息增益高于平均水…...

解锁深度学习激活函数

在深度学习的广袤天地里&#xff0c;激活函数宛如隐匿于神经网络架构中的神奇密码&#xff0c;掌控着模型学习与表达的关键力量。今天&#xff0c;就让我们一同深入探究这些激活函数的奇妙世界&#xff0c;揭开它们神秘的面纱。 一、激活函数为何不可或缺&#xff1f; 想象一…...

Kubernetes 深入浅出系列 | 容器剖析之容器安全

目录 1、容器真的需要privileged权限吗?一、什么是 --privileged 权限&#xff1f;二、privileged 的风险到底有多大&#xff1f;三、常见需求场景及更安全的替代方式四、如何判断容器是否真正需要特权&#xff1f; 2、不以 Root 用户运行容器&#xff0c;真的更安全吗&#x…...

Spring Boot应用中可能出现的Full GC问题

Full GC的原理与触发条件 原理 标记-清除&#xff1a;首先遍历所有对象&#xff0c;标记可达的对象&#xff0c;然后清除不可达的对象。复制算法&#xff1a;将内存分为两部分&#xff0c;每次只使用其中一部分。当这部分内存用完时&#xff0c;将存活的对象复制到另一部分&a…...

Maven 的安装与配置(IDEA)

2025/4/9 向 一、什么是Maven Maven 是一个基于项目对象模型&#xff08;Project Object Model&#xff0c;POM&#xff09;概念的项目构建工具&#xff08;所以就是一个工具&#xff09;&#xff0c;它主要用于自动化项目的构建过程&#xff0c;包括编译、测试、打包、部署等…...

软考中级-软件设计师 2022年下半年上午题真题解析:通关秘籍+避坑指南

&#x1f4da; 目录&#xff08;快速跳转&#xff09; 选择题&#xff08;上午题&#xff09;&#xff08;每题1分&#xff0c;共75分&#xff09;一、 计算机系统基础知识 &#x1f5a5;️&#x1f4bb; 题目1&#xff1a;计算机硬件基础知识 - RISC&#xff08;精简指令集计算…...

全栈开发套件Telerik DevCraft——赋能现代化应用构建

Telerik DevCraft包含一个完整的产品栈来构建您下一个Web、移动和桌面应用程序。它使用HTML和每个.NET平台的UI库&#xff0c;加快开发速度。Telerik DevCraft提供完整的工具箱&#xff0c;用于构建现代和面向未来的业务应用程序&#xff0c;目前提供UI for ASP.NET MVC、Kendo…...

Windows + vmware + ubuntu+docker + docker-android实现Android模拟器构建和启动

文章目录 引言编译启动过程玩下adb最后 引言 Windows vmware ubuntudockerdocker-android实现Android模拟器启动 编译启动过程 #下载docker-android git clone https://github.com/budtmo/docker-android.gitmaqiubuntu:~/docker-android$ git remote -v origin https://…...

远程团队协作效率低,如何优化

在远程工作的环境中&#xff0c;团队协作效率低下成为许多企业面临的一大挑战。随着全球化和技术进步&#xff0c;远程团队的出现成为企业的常态&#xff0c;但由于沟通不畅、任务管理不明确、缺乏团队凝聚力等问题&#xff0c;往往会影响团队的整体效率。为了优化远程团队的协…...

Oracle 19C 通过 ODBC 连接 SQL Server 数据库指南 (Red Hat 7)

前言 本指南详细说明如何在 Red Hat Enterprise Linux 7 系统上配置 Oracle 19C 通过 ODBC 连接 SQL Server 数据库。这种异构数据库连接方式称为 Oracle Heterogeneous Services,允许 Oracle 数据库直接访问非 Oracle 数据源。 系统要求 操作系统:Red Hat Enterprise Linu…...

【MYSQL从入门到精通】数据类型及建表

一些基础操作语句 1.使用客户端工具连接数据库服务器&#xff1a;mysql -uroot -p 2.查看所有数据库&#xff1a;show databases; 3.创建属于自己的数据库&#xff1a; create database 数据库名;create database if not exists 数据库名; 强烈建议大家在建立数据库时指定编…...

鸿蒙开发中的并发与多线程

文章目录 前言异步并发 (Promise和async/await)多线程并发并发能力选择耗时任务并发执行场景常见业务场景 常驻任务并发执行场景常见业务场景 传统共享内存并发业务长时任务并发执行场景常见业务场景 并发任务管理线程间通信同语言线程间通信&#xff08;ArkTS内&#xff09;线…...

ruby self

在 Ruby 中&#xff0c;self 是一个指向当前对象的特殊变量&#xff0c;它的值根据代码的上下文动态变化。理解 self 的指向是掌握 Ruby 面向对象编程的关键。以下是详细解析&#xff1a; 一、self 的核心规则 self 始终指向当前方法的执行者&#xff08;即调用方法的对象&…...

Kotlin 学习-集合

/*** kotlin 集合* List:是一个有序列表&#xff0c;可通过索引&#xff08;下标&#xff09;访问元素。元素可以在list中出现多次、元素可重复* Set:是元素唯一的集合。一般来说 set中的元素顺序并不重要、无序集合* Map:&#xff08;字典&#xff09;是一组键值对。键是唯一的…...

封装方法的辨析

equals //字符串 str1.equals(str2); //list的两个实现类 list1.equals(list2); //map的两个实现类 //比较所有的键值对是否相同 map1.equals(map2); //数组&#xff08;包括string类型&#xff09; //比较内容是否相同 Arrays.equals(array1, array2); contains 基本都有…...

解决 IntelliJ IDEA 中 Maven 项目左侧项目视图未显示顶层目录问题的详细步骤说明

以下是解决 IntelliJ IDEA 中 Maven 项目左侧项目视图未显示顶层目录问题的详细步骤说明&#xff1a; 1. 切换项目视图模式 默认情况下&#xff0c;IDEA 的项目视图可能处于 Packages 模式&#xff0c;仅显示代码包结构&#xff0c;而非物理目录。 操作步骤&#xff1a; 点击…...

CMIP6数据分析与可视化、降尺度技术与气候变化的区域影响、极端气候分析

当前的CMIP6计划相较于前代模型&#xff0c;在空间分辨率、物理过程表达和地球系统组件耦合等方面均有显著提升。 一&#xff1a;气候变化研究的AI新视角 1、气候模型基础与全球气候模型&#xff08;GCM&#xff09; 全球气候&#xff08;环流&#xff09;模型的基本原理、发…...

如何精准控制大模型的推理深度

论文标题 ThinkEdit: Interpretable Weight Editing to Mitigate Overly Short Thinking in Reasoning Models 论文地址 https://arxiv.org/pdf/2503.22048 代码地址 https://github.com/Trustworthy-ML-Lab/ThinkEdit 作者背景 加州大学圣迭戈分校 动机 链式推理能显…...

1. Git 下载和安装

文章目录 Git 下载Git 安装&#xff08;以windows为例&#xff09;Git 使用&#xff08;以windows为例&#xff09; Git 下载 1.进 Git 官网 https://git-scm.com/downloads 2.选择对应的操作系统 3.选择对应的操作系统位数 Git 安装&#xff08;以windows为例&#xff09;…...

git回滚指定版本并操作

你可以通过以下步骤切换到第三个版本。根据你的需求&#xff0c;有两种主要方法&#xff1a; 方法 1&#xff1a;临时查看第三个版本&#xff08;不修改当前分支&#xff09; 适用于仅查看或测试旧版本&#xff0c;不保留后续修改&#xff1a; 找到第三个版本的提交哈希&#…...

FastAdmin和thinkPHP学习文档

介绍 - FastAdmin框架文档 - FastAdmin开发文档https://doc.fastadmin.net/doc目录结构 ThinkPHP5.0完全开发手册 看云ThinkPHP V5.0是一个为API开发而设计的高性能框架——是一个颠覆和重构版本&#xff0c;采用全新的架构思想&#xff0c;引入了很多的PHP新特性&#xff0c…...

通过HTTP协议实现Git免密操作的解决方案

工作中会遇到这样的问题的。 通过HTTP协议实现Git免密操作的解决方案 方法一&#xff1a;启用全局凭据存储&#xff08;推荐&#xff09; 配置凭证存储‌ 执行以下命令&#xff0c;让Git永久保存账号密码&#xff08;首次操作后生效&#xff09;&#xff1a; git config --g…...

git 查看某一文件夹下所有文件 修改记录

git: 如何查询某个文件或者某个目录的更新历史_git 查看指定文件夹的记录-CSDN博客 git log --follow path/to/your/file git log -p --follow path/to/your/file git log --stat --follow path/to/your/file这是最常用的方法&#xff0c;可以显示指定文件的所有提交历史…...

测试(一)

软件的生命周期&#xff1a; 需求分析——计划——设计——编码——测试——运行维护 常见的开发模型&#xff1a; 瀑布模型&#xff1a; 最基本的开发模型&#xff0c;绝大多数开发模型的基本框架。 特点&#xff1a;线性的开发流程 使用场景&#xff1a;需求固定&#xff…...

解决华硕主板Z890m下载ubuntu20.04后没有以太网问题

问题描述&#xff1a; 华硕主板Z890m下载双系统ubuntu20.04后&#xff0c;发现ubuntu不能打开以太网。 问题原因&#xff1a; 华硕主板的网卡驱动是r8125,而ubuntu20.04的驱动版本是r8169&#xff0c;所以是网卡驱动不匹配造成 解决方案 开机界面按下F2进入BOIS模式&#…...

从零推导飞机小扰动运动线性方程——0. 学习目录

第0期文章——学习目录 如图&#xff0c;本专栏将连载以下学习内容&#xff0c;带你从零开始学习飞机小扰动方程&#xff01;...

Agentic AI 干货!DeepSeek + OpenAI SDK 构建 Agent 实战

引言&#xff1a; DeepSeek-R1、OpenAI-o1 等具备内化的假设、反思、验证等优秀推理能力的 LLM 大型推理模型将 AI 发展推进到智能体 AI 时代&#xff0c;将使 AI Agent 迸发出远超上一代由外化的手搓式简单推理 Agent 不可比拟的发展势能。 在 GTC2025 大会上&#xff0c;英伟…...

【语法】C++的list

目录 为什么会有list&#xff1f; 迭代器失效&#xff1a; list和vector的迭代器不同的地方&#xff1a; list的大部分用法和vector都很像&#xff0c;例如push_back&#xff0c;构造&#xff0c;析构&#xff0c;赋值重载这些就不再废话了&#xff0c;本篇主要讲的是和vecto…...

Java接口性能优化面试问题集锦:高频考点与深度解析

1. 如何定位接口性能瓶颈&#xff1f;常用哪些工具&#xff1f; 考察点&#xff1a;性能分析工具的使用与问题定位能力。 核心答案&#xff1a; 工具&#xff1a;Arthas&#xff08;在线诊断&#xff09;、JProfiler&#xff08;内存与CPU分析&#xff09;、VisualVM、Prometh…...

基于STM32与应变片的协作机械臂力反馈控制系统设计与实现---5.2 工业机械臂系统性能测试全方案(专业工程级)

5.2 工业机械臂系统性能测试全方案(专业工程级) 一、测试体系架构设计 1.1 三级测试体系 #mermaid-svg-A55VxjZ7ENKNWAli {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-A55VxjZ7ENKNWAli .error-icon{fill:#55…...

VM——相机拍照失败

1、问题&#xff1a;相机频闪触发&#xff0c;在MVS中正常出图&#xff0c;在VM中出现拍照失败 2、解决&#xff1a; 1、首先排查网络设置&#xff08;巨帧是否设置&#xff09; 2、电脑的所有防火墙是否关闭 3、在MVS中恢复相机的设置参数为默认参数&#xff0c;删除VM中的全…...

图解力扣回溯及剪枝问题的模板应用

文章目录 选哪个的问题17. 电话号码的字母组合题目描述解题代码图解复杂度 选不选的问题78. 子集题目描述解题代码图解复杂度 两相转化77. 组合题目描述解题代码法一&#xff1a;按选哪个的思路法二&#xff1a;按选不选的思路 图解选哪个&#xff1a;选不选 复杂度 选哪个的问…...

Trae + LangGPT 生成结构化 Prompt

Trae LangGPT 生成结构化 Prompt 0. 引言1. 安装 Trae2. 克隆 LangGPT3. Trae 和 LangGPT 联动4. 集成到 Dify 中 0. 引言 Github 上 LangGPT 这个项目&#xff0c;主要向我们介绍了写结构化Prompt的一些方法和示例&#xff0c;我们怎么直接使用这个项目&#xff0c;辅助我们…...

模糊测试究竟在干什么

目录 1.软件漏洞和缺陷 2.模糊测试与传统测试 3.汽车领域中的模糊测试 4.常见工具总结 1.软件漏洞和缺陷 提单、上票、拒收&#xff0c;这是开发和测试的日常博弈。大多数时候&#xff0c;我们是根据自己对需求的理解来进行开发和测试&#xff0c;这基本是属于功能层级。 …...

【RTD200P04 MCAL 篇3】 S32M244 PWM PDB ADC控制

【RTD200P04 MCAL 篇3】 S32M244 PWM PDB ADC控制 一&#xff0c;文档简介二&#xff0c;PWMTRGMUXPDBADC 2ch 软件配置与实现2.1 软硬件版本平台2.2 MCAL工程以及模块配置2.2.1 Dio 模块配置2.2.2 Adc模块配置2.2.3 Mcu模块配置2.2.4 Platform模块配置2.2.5 Port模块配置2.2.6…...

03--Deepseek服务器部署与cjson解析

一、ollama部署deepseek模型 1、Ollama 是一个开源的本地大语言模型运行框架&#xff0c;专为在本地机器上便捷部署和运行大型语言模型&#xff08;LLM&#xff09;而设计。 Ollama 教程&#xff1a;从 0 到 1 全面指南 教程【全文两万字保姆级详细讲解】 -CSDN博客 1.下载o…...

实现抗隐私泄漏的AI人工智能推理

目录 什么是私人AI? 什么是可信执行环境? TEE 如何在 AI 推理期间保护数据? 使用 TEE 是否存在风险? 有哪些风险? Atoma 如何应对这些风险 为什么去中心化网络是解决方案 人工智能推理过程中还有其他保护隐私的方法吗? 私人人工智能可以实现什么? 隐私驱动的应…...

Kotlin 学习--数组

一、关于数组的基础知识和常用方式 /*** kotlin 数组* 使用arrayOf创建数组&#xff0c;必须指定数组的元素&#xff0c;可以是任意类型* */val arrayNumber arrayOf(1, 2, 3, 4)/*** 集合中的元素可以是任意类型* kotlin 中的Any 等价于 java 中的Object 对象的意思* */val a…...

Spring Boot 启动后自动执行 Service 方法终极指南

**导语​​&#xff1a;**在 Spring Boot 开发中&#xff0c;我们经常需要在应用启动后立即执行初始化任务&#xff08;如加载配置、预热缓存、启动定时任务&#xff09;。本文将深度解析 ​​5 种主流实现方案​​&#xff0c;包含完整代码示例、执行顺序控制技巧和避坑指南&a…...

STM32 HAL库之GPIO示例代码

LED灯不断闪烁 GPIO初始化&#xff0c;main文件中的 MX_GPIO_Init(); 也就是在 gpio.c文件中 void MX_GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStruct {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOE_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_C…...

中间件-消息队列

SpringAMQP 任何语言只要遵循AMAP协议&#xff0c;都可以与RabbitMQ交互 生产者、队列、交换机、消费者 生产者Publisher&#xff1a;生产消息&#xff0c;发给交换机 交换机Exchange&#xff1a;接收生产者发送的消息。知道如何处理消息&#xff0c;例如递交给某个特别队列、…...

go游戏后端开发32:自摸杠处理逻辑

当我们在自摸杠时&#xff0c;实际上在杠完之后&#xff0c;我们还需要进行一个删除操作。因此&#xff0c;我们需要在上面拷贝一个删除操作。由于这是自摸杠&#xff0c;所以这个地方需要删除四次。在这里&#xff0c;我们需要注意的是&#xff0c;自摸杠时&#xff0c;传过来…...

AI创业风向标:构建下一代「AI叙事创作平台」

随着技术的进步和市场需求的爆发,AI故事叙述平台正成为投资者和创业者关注的焦点。本文将探讨为何这一赛道值得关注,并提供一些关于如何构建成功的AI叙事创作平台的战略建议。 一、为什么这是2025年值得关注的赛道? 1. 底层需求的爆发 人类永恒的故事需求:全球每月有超过…...

拜特科技签约惠生工程,携手打造高效资金管理系统

近日&#xff0c;拜特科技成功签约惠生工程(中国)有限公司&#xff08;以下简称“惠生工程”&#xff09;资金管理系统项目。此次双方携手打造一套先进的资金管理系统&#xff0c;为惠生工程的战略发展注入强劲新动力&#xff0c;推动其资金管理迈向更高水平。 惠生工程作为行…...