单元测试 —— JUnit 5 参数化测试
JUnit 5参数化测试
目录
- 设置
- 我们的第一个参数化测试
- 参数来源
- @ValueSource
- @NullSource & @EmptySource
- @MethodSource
- @CsvSource
- @CsvFileSource
- @EnumSource
- @ArgumentsSource
- 参数转换
- 参数聚合
- 奖励
- 总结
如果您正在阅读这篇文章,说明您已经熟悉了JUnit。让我为您概括一下JUnit——在软件开发中,我们开发人员编写的代码可能是设计一个人的个人资料这样简单,也可能是在银行系统中进行付款这样复杂。在开发这些功能时,我们倾向于编写单元测试。顾名思义,单元测试的主要目的是确保代码的小、单独部分按预期功能工作。
如果单元测试执行失败,这意味着该功能无法按预期工作。编写单元测试的一种工具是JUnit。这些单元测试程序很小,但是非常强大,并且可以快速执行。现在我们已经了解了JUnit,接下来让我们聚焦于JUnit 5中的参数化测试。
参数化测试可以解决在为任何新/旧功能开发测试框架时遇到的最常见问题。
- 编写针对每个可能输入的测试用例变得更加容易。
- 单个测试用例可以接受多个输入来测试源代码,有助于减少代码重复。
- 通过使用多个输入运行单个测试用例,我们可以确信已涵盖所有可能的场景,并维护更好的代码覆盖率。
开发团队通过利用方法和类来创建可重用且松散耦合的源代码。传递给代码的参数会影响其功能。例如,计算器类中的sum方法可以处理整数和浮点数值。JUnit 5引入了执行参数化测试的能力,可以使用单个测试用例测试源代码,该测试用例可以接受不同的输入。这样可以更有效地进行测试,因为在旧版本的JUnit中,必须为每种输入类型创建单独的测试用例,从而导致大量的代码重复。
示例代码
本文附带有在 GitHub上(
code-examples/core-java/junit5-parameterized-tests at master · thombergs/code-examples · GitHub) 的一个可工作的示例代码。
设置
就像疯狂泰坦灭霸喜欢访问力量一样,您可以使用以下Maven依赖项来访问JUnit5中参数化测试的力量:
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-params</artifactId><version>5.9.2</version><scope>test</scope>
</dependency>
让我们来写些代码,好吗?
我们的第一个参数化测试
现在,我想向您介绍一个新的注解 @ParameterizedTest。顾名思义,它告诉JUnit引擎使用不同的输入值运行此测试。
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;public class ValueSourceTest {@ParameterizedTest@ValueSource(ints = { 2, 4 })void checkEvenNumber(int number) {assertEquals(0, number % 2,"Supplied number is not an even number");}
}
在上面的示例中,注解@ValueSource为 checkEvenNumber() 方法提供了多个输入。假设我们使用JUnit4编写相同的代码,即使它们的结果(断言)完全相同,我们也必须编写2个测试用例来覆盖输入2和4。
当我们执行 ValueSourceTest 时,我们会看到什么:
ValueSourceTest
|_ checkEvenNumber
|_ [1] 2
|_ [2] 4
这意味着 checkEvenNumber() 方法将使用2个输入值执行。
在下一节中,让我们学习一下JUnit5框架提供的各种参数来源。
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036
参数来源
JUnit5提供了许多参数来源注释。下面的章节将简要概述其中一些注释并提供示例。
@ValueSource
@ValueSource是一个简单的参数源,可以接受单个字面值数组。@ValueSource支持的字面值类型有short、byte、int、long、float、double、char、boolean、String和Class。
@ParameterizedTest
@ValueSource(strings = { "a1", "b2" })
void checkAlphanumeric(String word) {assertTrue(StringUtils.isAlphanumeric(word),"Supplied word is not alpha-numeric");
}
@NullSource & @EmptySource
假设我们需要验证用户是否已经提供了所有必填字段(例如在登录函数中需要提供用户名和密码)。我们使用注解来检查提供的字段是否为 null,空字符串或空格。
- 在单元测试中使用 @NullSource 和 @EmptySource 可以帮助我们提供带有 null、空字符串和空格的数据源,并验证源代码的行为。
@ParameterizedTest
@NullSource
void checkNull(String value) {assertEquals(null, value);
}@ParameterizedTest
@EmptySource
void checkEmpty(String value) {assertEquals("", value);
}
- 我们还可以使用 @NullAndEmptySource 注解来组合传递 null 和空输入。
@ParameterizedTest
@NullAndEmptySource
void checkNullAndEmpty(String value) {assertTrue(value == null || value.isEmpty());
}
- 另一个传递 null、空字符串和空格输入值的技巧是结合使用 @NullAndEmptySource 注解,以覆盖所有可能的负面情况。该注解允许我们从一个或多个测试类的工厂方法中加载输入,并生成一个参数流。
@ParameterizedTest
@NullAndEmptySource
@ValueSource(strings = { " ", " " })
void checkNullEmptyAndBlank(String value) {assertTrue(value == null || value.isBlank());
}
@MethodSource
该注解允许我们从一个或多个测试类的工厂方法中加载输入,并生成一个参数流。
- 显式方法源 - 测试将尝试加载提供的方法。
// Note: The test will try to load the supplied method
@ParameterizedTest
@MethodSource("checkExplicitMethodSourceArgs")
void checkExplicitMethodSource(String word) {
assertTrue(StringUtils.isAlphanumeric(word),
"Supplied word is not alpha-numeric");
}static Stream<String> checkExplicitMethodSourceArgs() {
return Stream.of("a1",
"b2");
}
- 隐式方法源 - 测试将搜索与测试类匹配的源方法。
// Note: The test will search for the source method
// that matches the test-case method name
@ParameterizedTest
@MethodSource
void checkImplicitMethodSource(String word) {assertTrue(StringUtils.isAlphanumeric(word),
"Supplied word is not alpha-numeric");
}static Stream<String> checkImplicitMethodSource() {
return Stream.of("a1",
"b2");
}
- 多参数方法源 - 我们必须将输入作为参数流传递。测试将按照索引顺序加载参数。
// Note: The test will automatically map arguments based on the index
@ParameterizedTest
@MethodSource
void checkMultiArgumentsMethodSource(int number, String expected) {assertEquals(StringUtils.equals(expected, "even") ? 0 : 1, number % 2);
}static Stream<Arguments> checkMultiArgumentsMethodSource() {return Stream.of(Arguments.of(2, "even"),Arguments.of(3, "odd"));
}
- 外部方法源 - 测试将尝试加载外部方法。
// Note: The test will try to load the external method
@ParameterizedTest
@MethodSource(
"source.method.ExternalMethodSource#checkExternalMethodSourceArgs")
void checkExternalMethodSource(String word) {assertTrue(StringUtils.isAlphanumeric(word),
"Supplied word is not alpha-numeric");
}
// Note: The test will try to load the external method@ParameterizedTest@MethodSource("source.method.ExternalMethodSource#checkExternalMethodSourceArgs")void checkExternalMethodSource(String word) { assertTrue(StringUtils.isAlphanumeric(word),"Supplied word is not alpha-numeric");}package source.method;
import java.util.stream.Stream;public class ExternalMethodSource {static Stream<String> checkExternalMethodSourceArgs() {return Stream.of("a1","b2");}
}
@CsvSource
该注解允许我们将参数列表作为逗号分隔的值(即 CSV 字符串字面量)传递,每个 CSV 记录都会导致执行一次参数化测试。它还支持使用 useHeadersInDisplayName属性跳过 CSV 标头。
@ParameterizedTest
@CsvSource({ "2, even",
"3, odd"})
void checkCsvSource(int number, String expected) {assertEquals(StringUtils.equals(expected, "even")? 0 : 1, number % 2);
}
@CsvFileSource
该注解允许我们使用类路径或本地文件系统中的逗号分隔值(CSV)文件。与 @CsvSource 类似,每个 CSV 记录都会导致执行一次参数化测试。它还支持各种其他属性 -numLinesToSkip、useHeadersInDisplayName、lineSeparator、delimiterString等。
示例 1: 基本实现
@ParameterizedTest
@CsvFileSource(
files = "src/test/resources/csv-file-source.csv",
numLinesToSkip = 1)
void checkCsvFileSource(int number, String expected) {assertEquals(StringUtils.equals(expected, "even")? 0 : 1, number % 2);
}
src/test/resources/csv-file-source.csv
NUMBER, ODD_EVEN
2, even
3, odd
示例2:使用属性
@ParameterizedTest
@CsvFileSource(files = "src/test/resources/csv-file-source_attributes.csv",delimiterString = "|",lineSeparator = "||",numLinesToSkip = 1)
void checkCsvFileSourceAttributes(int number, String expected) {assertEquals(StringUtils.equals(expected, "even")
? 0 : 1, number % 2);
}
src/test/resources/csv-file-source_attributes.csv
|| NUMBER | ODD_EVEN ||
|| 2 | even ||
|| 3 | odd ||
@EnumSource
该注解提供了一种方便的方法来使用枚举常量作为测试用例参数。支持的属性包括:
- value - 枚举类类型,例如 ChronoUnit.class
package java.time.temporal;public enum ChronoUnit implements TemporalUnit {SECONDS("Seconds", Duration.ofSeconds(1)),MINUTES("Minutes", Duration.ofSeconds(60)),
HOURS("Hours", Duration.ofSeconds(3600)),DAYS("Days", Duration.ofSeconds(86400)),//12 other units
}
ChronoUnit 是一个包含标准日期周期单位的枚举类型。
@ParameterizedTest
@EnumSource(ChronoUnit.class)
void checkEnumSourceValue(ChronoUnit unit) {
assertNotNull(unit);
}
在此示例中,@EnumSource 将传递所有16个 ChronoUnit 枚举值作为参数。
- names - 枚举常量的名称或选择名称的正则表达式,例如 DAYS 或 ^.*DAYS$
@ParameterizedTest
@EnumSource(names = { "DAYS", "HOURS" })
void checkEnumSourceNames(ChronoUnit unit) {assertNotNull(unit);
}
@ArgumentsSource
该注解提供了一个自定义的可重用ArgumentsProvider。ArgumentsProvider的实现必须是外部类或静态嵌套类。
- 外部参数提供程序
public class ArgumentsSourceTest {@ParameterizedTest@ArgumentsSource(ExternalArgumentsProvider.class)void checkExternalArgumentsSource(int number, String expected) {assertEquals(StringUtils.equals(expected, "even")? 0 : 1, number % 2,"Supplied number " + number +" is not an " + expected + " number");}
}public class ExternalArgumentsProvider implements ArgumentsProvider {@Overridepublic Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception {return Stream.of(Arguments.of(2, "even"),Arguments.of(3, "odd"));}
}
- 静态嵌套参数提供程序
public class ArgumentsSourceTest {@ParameterizedTest@ArgumentsSource(NestedArgumentsProvider.class)void checkNestedArgumentsSource(int number, String expected) {assertEquals(StringUtils.equals(expected, "even")
? 0 : 1, number % 2,"Supplied number " + number +" is not an " + expected + " number");}static class NestedArgumentsProvider implements ArgumentsProvider {@Overridepublic Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception {return Stream.of(Arguments.of(2, "even"),Arguments.of(3, "odd"));}}
}
参数转换
首先,想象一下如果没有参数转换,我们将不得不自己处理参数数据类型的问题。
源方法: Calculator 类
public int sum(int a, int b) {return a + b;
}
测试用例:
@ParameterizedTest
@CsvSource({ "10, 5, 15" })
void calculateSum(String num1, String num2, String expected) {int actual = calculator.sum(Integer.parseInt(num1),Integer.parseInt(num2));assertEquals(Integer.parseInt(expected), actual);
}
如果我们有String参数,而我们正在测试的源方法接受Integers,则在调用源方法之前,我们需要负责进行此转换。
JUnit5 提供了不同的参数转换方式
- 扩展原始类型转换
@ParameterizedTest
@ValueSource(ints = { 2, 4 })
void checkWideningArgumentConversion(long number) {assertEquals(0, number % 2);
}
使用 @ValueSource(ints = { 1, 2, 3 }) 进行参数化测试时,可以声明接受 int、long、float 或 double 类型的参数。
- 隐式转换
@ParameterizedTest
@ValueSource(strings = "DAYS")
void checkImplicitArgumentConversion(ChronoUnit argument) {assertNotNull(argument.name());
}
JUnit5提供了几个内置的隐式类型转换器。转换取决于声明的方法参数类型。例如,用@ValueSource(strings = "DAYS")注释的参数化测试会隐式转换为类型ChronoUnit的参数。
- 回退字符串到对象的转换
@ParameterizedTest
@ValueSource(strings = { "Name1", "Name2" })
void checkImplicitFallbackArgumentConversion(Person person) {assertNotNull(person.getName());
}public class Person {private String name;public Person(String name) {this.name = name;}//Getters & Setters
}
JUnit5提供了一个回退机制,用于自动将字符串转换为给定目标类型,如果目标类型声明了一个适用的工厂方法或工厂构造函数。例如,用@ValueSource(strings = { "Name1", "Name2" })注释的参数化测试可以声明接受一个类型为Person的参数,其中包含一个名为name且类型为string的单个字段。
- 显式转换
@ParameterizedTest
@ValueSource(ints = { 100 })
void checkExplicitArgumentConversion(@ConvertWith(StringSimpleArgumentConverter.class) String argument) {assertEquals("100", argument);
}public class StringSimpleArgumentConverter extends SimpleArgumentConverter {@Overrideprotected Object convert(Object source, Class<?> targetType)throws ArgumentConversionException {return String.valueOf(source);}
}
如果由于某种原因,您不想使用隐式参数转换,则可以使用@ConvertWith注释来定义自己的参数转换器。例如,用@ValueSource(ints = { 100 })注释的参数化测试可以声明接受一个类型为String的参数,使用
StringSimpleArgumentConverter.class将整数转换为字符串类型。
参数聚合
@ArgumentsAccessor
默认情况下,提供给@ParameterizedTest方法的每个参数对应于一个方法参数。因此,当提供大量参数的参数源可以导致大型方法签名时,我们可以使用ArgumentsAccessor而不是声明多个参数。类型转换支持如上面的隐式转换所述。
@ParameterizedTest
@CsvSource({ "John, 20","Harry, 30" })
void checkArgumentsAccessor(ArgumentsAccessor arguments) {Person person = new Person(arguments.getString(0),arguments.getInteger(1));assertTrue(person.getAge() > 19, person.getName() + " is a teenager");
}
自定义聚合器
我们看到ArgumentsAccessor可以直接访问@ParameterizedTest方法的参数。如果我们想在多个测试中声明相同的ArgumentsAccessor怎么办?JUnit5通过提供自定义可重用的聚合器来解决此问题。
- @AggregateWith
@ParameterizedTest
@CsvSource({ "John, 20","Harry, 30" })
void checkArgumentsAggregator(@AggregateWith(PersonArgumentsAggregator.class) Person person) {assertTrue(person.getAge() > 19, person.getName() + " is a teenager");
}public class PersonArgumentsAggregator implements ArgumentsAggregator {@Overridepublic Object aggregateArguments(ArgumentsAccessor arguments,ParameterContext context) throws ArgumentsAggregationException {return new Person(arguments.getString(0),
arguments.getInteger(1));}
}
实现ArgumentsAggregator接口并通过@AggregateWith注释在@ParameterizedTest方法中注册它。当我们执行测试时,它会将聚合结果作为对应测试的参数提供。ArgumentsAggregator的实现可以是外部类或静态嵌套类。
额外福利
由于您已经阅读完文章,我想给您一个额外的福利 - 如果您正在使用像Fluent assertions for java(AssertJ - fluent assertions java library)这样的断言框架,则可以将
java.util.function.Consumer作为参数传递,其中包含断言本身。
@ParameterizedTest
@MethodSource("checkNumberArgs")
void checkNumber(int number, Consumer<Integer> consumer) {consumer.accept(number);
}static Stream<Arguments> checkNumberArgs() { Consumer<Integer> evenConsumer =i -> Assertions.assertThat(i % 2).isZero();Consumer<Integer> oddConsumer =i -> Assertions.assertThat(i % 2).isEqualTo(1);return Stream.of(Arguments.of(2, evenConsumer),Arguments.of(3, oddConsumer));
}
总结
JUnit5的参数化测试功能通过消除重复测试用例的需要,提供多次使用不同输入运行相同测试的能力,实现了高效的测试。这不仅为开发团队节省了时间和精力,而且还增加了测试过程的覆盖范围和有效性。此外,该功能允许对源代码进行更全面的测试,因为可以使用更广泛的输入进行测试,从而增加了识别任何潜在的错误或问题的机会。总体而言,JUnit5的参数化测试是提高代码质量和可靠性的有价值的工具。
最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
相关文章:

单元测试 —— JUnit 5 参数化测试
JUnit 5参数化测试 目录 设置我们的第一个参数化测试参数来源 ValueSourceNullSource & EmptySourceMethodSourceCsvSourceCsvFileSourceEnumSourceArgumentsSource参数转换参数聚合奖励总结 如果您正在阅读这篇文章,说明您已经熟悉了JUnit。让我为您概括一下…...

uview组件库的安装
更多的请查看官方文档uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 (uviewui.com) // 如果您的根目录没有package.json文件的话,请先执行如下命令: // npm init -y 安装 npm install uview-ui2.0.36 // 更新 // npm update uvie…...

skywalking入门
参考: https://www.jianshu.com/p/ffa7ddcda4ab 参考: https://developer.aliyun.com/article/1201085 skywalking(APM) 调用链路分析以及应用监控分析工具 Skywalking主要由三大部分组成:agent、collector、webapp-…...

【Java 基础篇】Java多线程实现文件上传详解
文件上传是Web应用程序中常见的功能之一,用户可以通过网页将文件从本地计算机上传到服务器。在处理大文件或多用户并发上传的情况下,为了提高性能和用户体验,常常使用多线程来实现文件上传功能。本文将详细介绍如何使用Java多线程实现文件上传…...

【计算机基础】VS断点调试,边学边思考
📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…...
BD就业复习第五天
1. 核心组件的优化:hive、spark、flink 针对Hive、Spark和Flink这三个核心组件,以下是它们的优化和一些常见面试题以及详细的回答: 1. Hive 优化 面试问题1:什么是Hive?为什么需要对Hive进行优化? 回答…...
ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the ‘ssl‘
报错: ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1, currently the ‘ssl’ module is compiled with OpenSSL 1.1.0h 27 Mar 2018.解决办法:将urllib3的版本降低 pip install urllib31.26.15参考 python包报错ImportError: urllib3 v2.…...

Qt5开发及实例V2.0-第十二章-Qt多线程
Qt5开发及实例V2.0-第十二章-Qt多线程 第12章 Qt 5多线程12.1 多线程及简单实例12.2 多线程控制12.2.1 互斥量12.2.2 信号量12.2.3 线程等待与唤醒 12.3 多线程应用12.3.1 【实例】:服务器编程12.3.2 【实例】:客户端编程 本章相关例程源码下载1.Qt5开发…...
Windows 修改系统默认字体
Windows Registry Editor Version 5.00; 重装机后电脑屏幕及字体调整.reg.lnk ;; 显示器分辨率: 3840*2160 ;; 自定义缩放: 266 ;; 辅助功能 - 文本大小 - 110% ;; 最后 ClearType 文本调谐器; https://www.cnblogs.com/bolang100/p/8548040.html#WINDOWS 10 显示中的仅更改文…...

图像处理软件Photoshop 2024 mac新增功能
Photoshop 2024 mac是一款图像处理软件的最新版本。ps2024提供了丰富的功能和工具,使用户能够对照片、插图、图形等进行精确的编辑和设计。 Photoshop 2024 mac软件特点 快速性能:Photoshop 2024 提供了更快的渲染速度和更高效的处理能力,让用…...

JavaScript之观察者模式
本文作者为 360 奇舞团前端开发工程师 概述 在日常开发中,开发人员经常使用设计模式来解决软件设计中的问题。其中,观察者模式是一种常用的模式,它可以帮助开发人员更好地处理对象之间的通信。在 JavaScript 中,观察者模式的应用非…...
深入了解ln命令:创建硬链接和符号链接的实用指南
文章目录 1. 引言1.1 关于ln命令1.2 ln命令的作用和用途 2. 基本用法2.1 创建硬链接2.2 创建符号链接2.3 区别硬链接和符号链接 3. 操作示例3.1 创建硬链接的示例3.2 创建符号链接的示例3.3 查看链接信息 4. 注意事项和常见问题4.1 文件路径4.2 软链接的相对路径4.3 软链接的更…...
虚拟IP技术
1.说明 虚拟IP(Virtual IP Address,简称VIP)是一个未分配给真实弹性云服务器网卡的IP地址。 弹性云服务器除了拥有私有IP地址外,还可以拥有虚拟IP地址,用户可以通过其中任意一个IP(私有IP/虚拟IP…...

蓝桥杯 题库 简单 每日十题 day5
01 字符计数 字符计数 题目描述 给定一个单词,请计算这个单词中有多少个元音字母,多少个辅音字母。 元音字母包括a,e,i,o,u,共五个,其他均为辅音字母。 输入描述 输入格式: 输入一行࿰…...

【计算机网络】图解路由器(一)
图解路由器(一) 1、什么是路由器?2、什么是路由选择?3、什么是转发?4、路由器设备有哪些类型?5、根据性能分类,路由器有哪些类型?5.1 高端路由器5.2 中端路由器5.3 低端路由器 6、什…...

C语言文件的相关操作
C语言中文件的相关操作 文件的打开 使用文件的打开函数需要引入这个头文件:#include <fcntl.h> open函数 int open(char const *pathname, int flags, mode_t mode) 功能:打开已有的文件或者创建新文件参数 pathname:文件路径名&…...
Java入门级简单定时任务TimerTask
如果要执行一些简单的定时器任务,无须做复杂的控制,也无须保存状态,那么可以考虑使用JDK 入门级的定期器Timer来执行重复任务。 一、原理 JDK中,定时器任务的执行需要两个基本的类: java.util.Timer; java…...
Linux命令行教程:使用head和tail命令快速查看文件的开头和结尾
文章目录 简介A. 什么是head和tail命令B. head和tail命令的作用和用途 head命令A. 命令格式和语法B. 常见选项和参数1. -n:指定显示的行数2. -c:指定显示的字节数3. -v:显示文件名 C. 示例和应用实例1. 显示文件的前几行2. 显示多个文件的前几…...

[CISCN 2019 初赛]Love Math 通过进制转换执行命令
目录 hex2bin bin2hex base_convert 动态函数 第一种解法 通过get获取参数 绕过 第二种解法 读取请求头 getallheaders echo a,b 第三种解法 异或获得更多字符 这道题也是很有意思! 通过规定白名单和黑名单 指定了 函数为数学函数 并且参数也只能是规…...

【Linux】系统编程生产者消费者模型(C++)
目录 【1】生产消费模型 【1.1】为何要使用生产者消费者模型 【1.2】生产者消费者模型优点 【2】基于阻塞队列的生产消费者模型 【2.1】生产消费模型打印模型 【2.2】生产消费模型计算公式模型 【2.3】生产消费模型计算公式加保存任务模型 【2.3】生产消费模型多生产多…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

【大模型】RankRAG:基于大模型的上下文排序与检索增强生成的统一框架
文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构C.1 指令微调阶段C.2 排名与生成的总和指令微调阶段C.3 RankRAG推理:检索-重排-生成 D 实验设计E 个人总结 A 论文出处 论文题目:RankRAG:Unifying Context Ranking…...