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

单元测试之JUnit5知识点总结及代码示例

     单元测试是软件开发过程中的一种验证手段,它针对最小的可测试部分(通常是函数或方法)进行检查和验证。其实单元测试还是挺重要的,不过国内很多公司的项目其实并没有做好单元测试,或者根本就没做单元测试,原因可能是项目周期比较紧张,开发时间不充足,所以就省略了单元测试,也有可能是领导不重视单元测试。之前工作中做单元测试主要用到JUnit和TestNG,做覆盖统计主要用的JaCoCo。不过本篇主要总结JUnit5的知识点及用法。JUnit5官网:JUnit 5

目录

1.Junit5简介和环境搭建

2.JUnit 5 的主要注解

 3.JUnit 5 断言(Assertions)

 4.JUnit 5 测试方法

5. JUnit 5 测试执行控制

6.JUnit 5 测试输出

 7.JUnit 5 测试辅助功能

8.JUnit 5 错误处理和异常测试

9.JUnit 5 测试依赖注入

10.JUnit 5 测试监听器

11.JUnit 5 测试配置

12. JUnit 5 测试动态生成

13.JUnit 5 测试参数化

14.JUnit 5 测试并行执行

15.JUnit 5 测试可读性

16.JUnit 5 测试条件

17.Spring Boot项目集成Junit5


     1.Junit5简介和环境搭建
特性描述
JUnit 5 架构JUnit 5 由三个主要模块组成:JUnit Platform、JUnit Jupiter 和 JUnit Vintage。
JUnit Platform提供了一个测试框架的运行时平台,允许IDE和构建工具在JVM上启动和请求测试。
JUnit Jupiter提供了新的编程模型和扩展模型,用于编写测试。
JUnit Vintage允许JUnit 5运行JUnit 3和JUnit 4的测试。
环境搭建使用Maven或Gradle将JUnit 5添加到项目中。

环境搭建:

 使用Maven或Gradle将JUnit 5添加到项目中。

<dependency> 
<groupId>org.junit.jupiter</groupId> 
<artifactId>junit-jupiter-api</artifactId><version>5.7.0</version><scope>test</scope></dependency> 
2.JUnit 5 的主要注解
注解描述代码示例
@BeforeEach在每个测试方法执行之前运行的方法。
@BeforeEach 
public void init() { 
... }

@AfterEach在每个测试方法执行之后运行的方法。@AfterEach public void tearDown() { ... }
@BeforeAll在所有测试方法执行之前,整个类中只运行一次。 @BeforeAll public static void setUpBeforeClass() { ... }
@AfterAll在所有测试方法执行之后,整个类中只运行一次。 @AfterAll public static void tearDownAfterClass() { ... }
@Test标记一个方法为测试方法。 @Test public void myTestMethod() { ... }
@RepeatedTest允许测试方法重复执行指定次数。 @RepeatedTest(10) public void repeatedTestMethod() { ... }
@ParameterizedTest用于参数化测试。 @ParameterizedTest public void parameterizedTestMethod(int param) { ... }
@MethodSource@ParameterizedTest一起使用,提供测试参数。
 @MethodSource("parameters") 
public void parameterizedTestMethod(int param) { 
... 
} static Stream<Object[]> parameters() { 
return Stream.of(new Object[]{1}); }

 3.JUnit 5 断言(Assertions)
断言方法描述代码示例
assertAll()允许组合多个断言,如果任何一个断言失败,测试会立即失败。 assertAll("Test Group", () -> assertEquals(2, 1 + 1), () -> assertEquals("foo", "bar"));
assertNotNull()验证对象不是null assertNotNull("Object should not be null", myObject);
assertNull()验证对象是null assertNull("Object should be null", myObject);
assertTrue()验证条件为true assertTrue("Should be true", condition);
assertFalse()验证条件为false assertFalse("Should be false", condition);
assertEquals()验证两个值是否相等。 assertEquals(2, 1 + 1);
assertNotEquals()验证两个值是否不相等。 assertNotEquals("Should not be equal", 2, 3);
assertSame()验证两个引用是否指向同一个对象。 Object obj1 = new Object(); Object obj2 = obj1; assertSame(obj1, obj2);
assertNotSame()验证两个引用是否指向不同的对象。 assertNotSame("Should not be same", obj1, obj2);

以上是JUnit 5中常用的断言方法,它们帮助开发者验证测试用例中的预期结果是否符合实际结果。

 4.JUnit 5 测试方法
特性描述代码示例
测试方法使用@Test注解标记的方法,JUnit 5将自动运行这些方法作为测试。 @Test public void testMethod() { ... }
测试方法参数测试方法可以接收参数,如测试数据。 @ParameterizedTest public void testMethod(String data) { ... }
超时测试使用@Timeout注解设置测试方法的最大执行时间。 @Test @Timeout(value = 500, unit = TimeUnit.MILLISECONDS) public void testMethod() { ... }
动态测试使用@DynamicTest注解创建动态生成的测试。 
@TestFactoryStream<DynamicTest> dynamicTestsStream() { 
return Stream.of("Test1", "Test2") .map(data -> DynamicTest.dynamicTest(data, () -> {... 
}
)); 
}

条件测试使用@EnabledIf@DisabledIf注解根据条件启用或禁用测试。 @EnabledIf("expression") @Test public void testMethod() { ... }
5. JUnit 5 测试执行控制
控制方式描述代码示例
标签(Tags)使用@Tag注解给测试分类,可以通过标签过滤运行特定测试。 @Tag("fast") @Test public void fastTestMethod() { ... }
测试配置(Test Configuration)使用@TestInstance注解控制测试方法的生命周期。 @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MyTestClass { ... }
测试筛选器(Test Filters)使用JUnit 5的内置筛选器来选择要运行的测试。在命令行中使用 -@include 或 --exclude 选项。
测试依赖(Test Dependencies)使用@ExtendWith注解定义测试类或方法的依赖关系。 @ExtendWith(CustomExtension.class) public class MyTestClass { ... }
重复测试(Repeated Tests)使用@RepeatedTest注解让测试方法重复执行。 @RepeatedTest(5) public void repeatedTestMethod() { ... }
参数化测试(Parameterized Tests)使用@ParameterizedTest@MethodSource注解执行参数化测试。 @ParameterizedTest @MethodSource("dataProvider") public void parameterizedTest(int param) { ... } static Stream<?> dataProvider() { return Stream.of(1, 2, 3); }
临时文件夹(Temporary Folders)使用@TempDir注解为测试方法提供临时文件夹路径。 @Test public void testWithTempFolder(@TempDir Path tempDir) { ... }

以上是JUnit 5中测试执行控制的一些关键特性,它们允许开发者更灵活地控制测试的执行流程和条件。

6.JUnit 5 测试输出
特性描述代码示例
断言消息使用断言方法的重载版本,提供自定义的失败消息。 assertEquals("List should contain 'B'", "A", list.get(1));
日志记录使用@LogMessageRule注解捕获日志消息。 @Rule public LogMessageRule rule = new LogMessageRule(); @Test public void testLogCapture() { rule.expect(WARNING); logger.warn("This is a warning message"); }
测试输出(Test Output)使用@TestInfo获取测试信息,如测试方法名称、显示名称等。 @Test public void testWithTestInfo(TestInfo testInfo) { System.out.println("Running test: " + testInfo.getDisplayName()); }
测试模板方法(Test Template Methods)使用@TestTemplate注解定义模板方法,结合@ExtendWith注解使用。 @TestTemplate public void testTemplateMethod(MyCustomExtension ext) { ... } @ExtendWith(MyCustomExtension.class) public void extendWithMethod() { ... }
动态测试(Dynamic Tests)生成动态测试用例,返回StreamDynamicTest @TestFactory Stream<DynamicTest> dynamicTests() { return Stream.of("A", "B", "C") .map(input -> DynamicTest.dynamicTest(input, () -> assertEquals(1, input.length()))); }
 7.JUnit 5 测试辅助功能
功能描述代码示例
假设(Assumptions)使用假设来避免在不满足特定条件时执行测试。assumeTrue("This test assumes JDK 11 or higher", javaVersion >= 11);
测试时钟(Test Clock)使用@MockClock注解模拟时间,用于时间相关的测试。 @Test @MockClock("12:00:00") public void testWithMockClock() { ... }
测试资源(Test Resources)使用@RegisterExtension注解注册测试资源,如临时文件、数据库连接等。 @RegisterExtension public TemporaryFolder folder = new TemporaryFolder(); @Test public void testWithTemporaryFolder() { Path path = folder.getRoot().toPath(); ... }
测试规则(Test Rules)使用测试规则来为测试方法提供额外的行为,如日志捕获、重复测试等。 @Rule public TestRule logWatcher = new LogWatcher(); @Test public void testWithLogWatcher() { ... }
条件测试(Conditional Tests)根据系统属性或环境变量的条件执行测试。 @EnabledIfEnvironment("os.name == 'Windows 10'") @Test public void windows10OnlyTest() { ... }
测试配置参数(Test Configuration Parameters)从命令行或配置文件中读取参数,并在测试中使用。 @Test public void testWithConfigurationParameter(@ConfiguredParameter("timeout") int timeout) { ... }
测试模板方法(Test Template Methods)允许为测试提供自定义的执行逻辑。 @TestTemplate public void testTemplateMethod(MyCustomExtension ext) { ... } @ExtendWith(MyCustomExtension.class) public void extendWithMethod() { ... }

这些辅助功能增强了JUnit 5的测试能力,使得测试更加灵活和强大

8.JUnit 5 错误处理和异常测试
特性描述代码示例
期望异常(Expected Exceptions)使用assertThrows来验证方法是否抛出了特定的异常。 Assertions.assertThrows(IllegalArgumentException.class, () -> { throw new IllegalArgumentException("bad argument"); });
异常测试(Exception Testing)使用@Test注解的expectedExceptions属性来测试预期的异常。 @Test(expectedExceptions = ArithmeticException.class) public void testDivideByZero() { int i = 1 / 0; }
断言异常内容(Asserting Exception Content)捕获异常并验证其内容,如消息或原因。 Exception exception = assertThrows(IllegalArgumentException.class, () -> { throw new IllegalArgumentException("error"); }); assertEquals("error", exception.getMessage());
错误收集(Error Collecting)使用assertAll来执行多个断言,即使其中一个失败,其他断言也会继续执行。 assertAll("test", () -> assertEquals(2, 1 + 1), () -> assertThrows(RuntimeException.class, () -> { throw new RuntimeException(); }));
软断言(Soft Assertions)使用软断言来收集多个失败的断言,而不是在第一个失败时立即停止测试。 SoftAssertions softly = new SoftAssertions(); softly.assertThat(codePointBefore('a')).isEqualTo(-1); softly.assertThat(codePointBefore('A')).isEqualTo(-1); softly.assertAll();

 这些特性帮助开发者更好地处理测试中的异常情况,确保测试的准确性和健壮性。

9.JUnit 5 测试依赖注入
特性描述代码示例
构造器注入使用@Autowired注解在测试类构造器中注入依赖。 @SpringBootTest public class MySpringBootTest { @Autowired private MyService service; }
字段注入使用@Inject注解在字段上注入依赖。 public class MyTestClass { @Inject private MyService service; }
方法参数注入使用@InjectMocks注解在测试方法的参数上注入依赖。@Test public void testMethod(@Mocked MyDependency dependency) { ... }
模块化测试使用@ExtendWith注解和自定义扩展来模块化测试逻辑。 @ExtendWith(MyExtension.class) public class MyTestClass { ... }
测试实例化使用@TestInstance注解控制测试类的实例化方式。 @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MyTestClass { ... }
测试上下文管理使用@TestInfo获取测试上下文信息,如测试方法名称、测试类等。public class MyTestClass { @Test public void testMethod(TestInfo testInfo) { System.out.println(testInfo.getDisplayName()); } }

依赖注入是现代测试框架中的重要特性,它允许测试代码更加模块化和可重用。JUnit 5通过集成Spring等框架,提供了强大的依赖注入支持。

10.JUnit 5 测试监听器
特性描述代码示例
监听器(Listeners)使用@ExtendWith注解添加监听器,监听测试的生命周期事件。 @ExtendWith(MyTestWatcher.class) public class MyTestClass { ... }
测试执行监听器(Test Execution Listeners)实现TestExecutionListener接口,监听测试的执行过程。 public class MyTestExecutionListener implements TestExecutionListener { ... }
测试实例监听器(Test Instance Listeners)实现TestInstanceListener接口,监听测试实例的创建和生命周期。public class MyTestInstanceListener implements TestInstanceListener { ... }
测试生命周期监听器(Test Lifecycle Listeners)实现TestLifecycleListener接口,监听测试的整个生命周期。 public class MyTestLifecycleListener implements TestLifecycleListener { ... }
测试失败监听器(Test Failure Listeners)实现TestFailureListener接口,监听测试失败事件。 public class MyTestFailureListener implements TestFailureListener { ... }
测试告警监听器(Test Alerting Listeners)实现TestAlerting接口,对测试失败进行告警。 public class MyTestAlerting implements TestAlerting { ... }

测试监听器是JUnit 5中用于监听和响应测试事件的强大机制,它们可以用来扩展JUnit 5的功能,如测试报告生成、性能监控等。

11.JUnit 5 测试配置
配置项描述使用示例
全局配置通过junit-platform.properties文件进行全局配置。junit.jupiter.conditions.include-classes-with-at-least-one-method = true
测试方法配置使用注解在测试方法上指定配置。 @Test @DisplayName("A test with custom display name") void testMethod() { ... }
测试类配置使用注解在测试类上指定配置。 @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MyTestClass { ... }
测试模板配置使用注解在测试模板方法上指定配置。 @TestTemplate public void testTemplate() { ... }
参数化测试配置使用注解在参数化测试方法上指定配置。 @ParameterizedTest(name = "{index} => {0} + {1} = {2}") @MethodSource("dataProvider") void parameterizedTest(int a, int b, int expected) { ... }
测试过滤器配置使用注解或命令行参数来过滤测试。在命令行中使用 --filter 选项。
测试重复配置使用注解在测试方法上指定重复次数。 @RepeatedTest(3) void repeatedTestMethod() { ... }
测试超时配置使用注解在测试方法上指定执行超时时间。@Test @Timeout(duration = 500, unit = TimeUnit.MILLISECONDS) void testMethod() { ... }

测试配置是JUnit 5中用于定制测试行为的重要特性,它允许开发者根据需要调整测试的执行方式。

12. JUnit 5 测试动态生成
特性描述代码示例
动态测试(Dynamic Tests)允许在测试执行期间动态生成测试用例。@TestFactory Stream<DynamicTest> dynamicTests() { return Stream.of("foo", "bar") .map(s -> DynamicTest.dynamicTest(s, () -> assertNotEquals(0, s.length()))); }
测试工厂(Test Factories)创建动态测试的方法,可以返回StreamIterableDynamicTest @TestFactory Stream<DynamicTest> dynamicTestsWithStream() { return Stream.of(1, 2, 3) .map(i -> DynamicTest.dynamicTest("Test with " + i, () -> {})); }
测试模板方法(Test Template Methods)使用模板方法来定义测试逻辑,并通过扩展执行不同的测试用例。 @TestTemplate void testWithCustomProvider(Object o) { ... } @ExtendWith(CustomProviderExtension.class) void extendWithCustomProvider() { ... }
测试扩展(Test Extensions)自定义扩展可以介入测试执行的各个阶段,实现自定义逻辑。 public class CustomExtension implements TestExecutionListener { ... }

动态生成测试用例是JUnit 5中一个强大的特性,它允许开发者根据需要灵活地生成测试用例,从而提高测试的复用性和灵活性。

13.JUnit 5 测试参数化
特性描述代码示例
参数化测试(Parameterized Tests)允许为单个测试方法提供多个输入参数。 @ParameterizedTest @MethodSource("numbersProvider") void parameterizedTest(int number) { ... } static Stream<Integer> numbersProvider() { return Stream.of(1, 2, 3); }
方法源(Method Source)提供测试参数的来源,可以是静态方法或字段。 static Stream<Arguments> numbersProvider() { return Stream.of(Arguments.of(1), Arguments.of(2), Arguments.of(3)); }
CSV源(CSV Source)使用CSV格式的字符串直接提供测试参数。 @ParameterizedTest @CsvSource({ "1, 2, 3", "4, 5, 6" }) void parameterizedTest(int a, int b, int c) { ... }
对象数组源(Object Array Source)使用对象数组直接提供测试参数。 @ParameterizedTest @ArgumentsSource(ObjectArraySource.class) void parameterizedTest(String data) { ... }
自定义提供器(Custom Providers)创建自定义的参数提供器来生成测试参数。 public class CustomProvider implements ArgumentsProvider { public Stream<? extends Arguments> provideArguments(ExtensionContext context) { return Stream.of(Arguments.of("A", "B")); } }

参数化测试是JUnit 5中用于测试多种输入组合的强大特性,它允许开发者编写更简洁、更高效的测试代码。

14.JUnit 5 测试并行执行
特性描述代码示例
并行执行(Parallel Execution)允许同时运行多个测试,以加快测试套件的执行速度。使用JUnit 5的junit.jupiter.execution.parallel.enabled配置属性来启用并行执行。
测试类级别的并行对整个测试类中的测试方法进行并行执行。 @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class MyTestClass { ... }
方法级别的并行对单个测试方法进行并行执行。使用JUnit 5的junit.jupiter.execution.parallel.mode.default配置属性来设置默认的并行模式。
自定义并行策略通过实现TestExecutionListener接口来自定义测试的并行执行策略。 public class CustomParallelismListener implements TestExecutionListener { ... }
资源隔离确保在并行执行过程中,测试之间的资源是隔离的,避免相互干扰。使用@RegisterExtension注解的ResourceLock规则来锁定特定资源。
动态测试并行对动态生成的测试用例进行并行执行。@TestFactory方法中返回的DynamicTest流可以被并行执行。

测试并行执行是提高测试效率的重要特性,它可以有效减少持续集成(CI)环境中的测试等待时间。

15.JUnit 5 测试可读性
特性描述代码示例
显示名称(Display Name)为测试方法提供可读性强的显示名称。 @DisplayName("Test with custom display name") @Test public void testMethod() { ... }
嵌套测试(Nested Tests)使用嵌套的测试方法来组织测试逻辑,提高测试的可读性。 @Test public void outerTest() { @Test public void innerTest() { ... } }
测试描述(Test Description)提供测试的描述信息,增强测试的可读性。使用TestInfo获取测试的描述信息,并在测试日志中展示。
断言消息(Assertion Messages)在断言失败时提供自定义的消息,帮助理解失败的原因。 assertEquals("Expected reference equality", obj1, obj2);
测试模板(Test Templates)使用测试模板方法来提供可读性强的测试逻辑。 @TestTemplate void testWithCustomProvider(Object o) { ... }

测试可读性是JUnit 5中用于提高测试代码和测试报告可读性的重要特性,它有助于开发者更好地理解和维护测试代码。

16.JUnit 5 测试条件
特性描述代码示例
条件注解(Conditional Annotations)根据条件启用或禁用测试,如系统属性、环境变量等。 @EnabledIf("javaVersion > 11") @Test public void testMethod() { ... }
系统属性条件(System Property Condition)根据系统属性的值来启用或禁用测试。 @EnabledIfSystemProperty(named = "os.arch", matches = ".*64.*") @Test public void testMethod() { ... }
环境变量条件(Environment Variable Condition)根据环境变量的值来启用或禁用测试。 @EnabledIfEnvironmentVariable(named = "CI", matches = "true") @Test public void testMethod() { ... }
自定义条件(Custom Conditions)实现Condition接口来提供自定义的条件逻辑。 public class CustomCondition implements Condition { ... }
测试配置参数(Test Configuration Parameters)从命令行或配置文件中读取参数,并在测试中使用。 @Test public void testWithConfigurationParameter(@ConfiguredParameter("timeout") int timeout) { ... }

测试条件是JUnit 5中用于根据环境或配置来控制测试执行的重要特性,它允许开发者灵活地决定哪些测试应该运行。

17.Spring Boot项目集成Junit5

  17.1首先,确保你的pom.xml(Maven)或build.gradle(Gradle)文件中包含了JUnit 5和Spring Boot Test的依赖。

对于Maven,pom.xml可能包含以下依赖:

<dependencies><!-- Spring Boot Test Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.5.0</version> <!-- 使用你项目匹配的版本 --><scope>test</scope></dependency>
</dependencies>

 对于Gradle,build.gradle可能包含以下依赖:

dependencies {// Spring Boot Test StartertestImplementation('org.springframework.boot:spring-boot-starter-test:2.5.0') // 使用你项目匹配的版本
}

17.2 创建测试类

创建一个测试类,使用@SpringBootTest注解来指示Spring Boot为测试提供支持。使用@Test注解标记测试方法。

这里是一个简单的服务层测试示例:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;@SpringBootTest
public class SomeServiceTest {@Autowiredprivate SomeService someService;@MockBeanprivate SomeDependency someDependency;@Testpublic void testSomeMethod() {// 设置mock行为when(someDependency.someMethod()).thenReturn("expected value");// 调用待测试的方法String result = someService.someMethod();// 验证结果assertEquals("expected value", result);// 验证依赖是否被调用verify(someDependency).someMethod();}
}

 这个例子中,SomeService是我们想要测试的服务层组件,而SomeDependency是它的一个依赖项,我们使用@MockBean注解来创建一个模拟对象。

17.3 运行测试

你可以在IDE中运行测试,或者使用Maven或Gradle的命令行工具来执行测试。

对于Maven,使用以下命令:

mvn test

 对于Gradle,使用以下命令:

./gradlew test

 这只是一个极简单的示例,在项目的具体需求下,测试会更复杂,包括更多的模拟对象,服务和测试用例等。

相关文章:

单元测试之JUnit5知识点总结及代码示例

单元测试是软件开发过程中的一种验证手段&#xff0c;它针对最小的可测试部分&#xff08;通常是函数或方法&#xff09;进行检查和验证。其实单元测试还是挺重要的&#xff0c;不过国内很多公司的项目其实并没有做好单元测试&#xff0c;或者根本就没做单元测试&#xff0c;原…...

什么是数据平台——企业构建Data+AI的基础数据底座需要的决策参考

什么是数据平台 标准的解释是这样的 Wikipedia A data platform usually refers to a software platform used for collecting and managing data, and acting as a data delivery point for application and reporting software. 数据平台是指将各类数据进行整合、存储、处…...

Oracle 流stream数据的复制

Oracle 流stream数据的复制 --实验的目的是捕获scott.emp1表的变化&#xff0c;将变化应用到远程数据库scott.emp1表中。 --设置初始化参数 AQ_TM_PROCESSES1 COMPATIBLE9.2.0 LOG_PARALLELISM1 GLOBAL_NAMEStrue JOB_QUEUE_PROCESSES2 --查看数据库的名称&#xff0c;我的为o…...

「 安全设计 」68家国内外科技巨头和安全巨头参与了CISA发起的安全设计承诺,包含MFA、默认密码、CVE、VDP等七大承诺目标

美国网络安全和基础设施安全局&#xff08;CISA&#xff0c;CyberSecurity & Infrastructure Security Agency&#xff09;于2024年5月开始呼吁企业是时候将网络安全融入到技术产品的设计和制造中了&#xff0c;并发起了安全设计承诺行动&#xff0c;该承诺旨在补充和建立现…...

【K8S】pod无限重启,报错Back-off restarting failed container

1. 问题 pod启动后一直重启&#xff0c;并报Back-off restarting failed container。 原理&#xff1a; Back-off restarting failed container的Warning事件&#xff0c;一般是由于通过指定的镜像启动容器后&#xff0c;容器内部没有常驻进程&#xff0c;导致容器启动成功后…...

摸鱼文章1

1111111...

【设计模式】之适配器模式

系列文章目录 &#xff08;其他设计模式可以到 &#x1f449;&#x1f449;&#x1f449;&#xff09;设计模式_小杰不秃头的博客 &#x1f60a;&#x1f604;&#x1f61b; 前言 今天继续给大家介绍23种设计模式中的适配器模式&#xff0c;这个模式相比于其他模式比较好理解…...

Python轻量级Web框架Flask(13)—— Flask个人博客项目

0、前言: ★这部分内容是基于之前Flask学习内容的一个实战项目梳理内容,没有可以直接抄下来跑的代码,是学习了之前Flask基础知识之后,再来看这部分内容,就会对Flask项目开发流程有更清楚的认知,对一些开发细节可以进一步的学习。项目功能,通过Flask制作个人博客。项目架…...

电商技术揭秘营销相关系列文章合集(4)

相关系列文章 电商技术揭秘相关系列文章合集&#xff08;1&#xff09; 电商技术揭秘相关系列文章合集&#xff08;2&#xff09; 电商技术揭秘相关系列文章合集&#xff08;3&#xff09; 文章目录 引言集合说明集合文章列表 引言 在数字化浪潮的推动下&#xff0c;电商行…...

LeetCode-2391. 收集垃圾的最少总时间【数组 字符串 前缀和】

LeetCode-2391. 收集垃圾的最少总时间【数组 字符串 前缀和】 题目描述&#xff1a;解题思路一&#xff1a;处理垃圾和路程单独计算。解题思路二&#xff1a;逆向思维&#xff0c;计算多走的路解题思路三&#xff1a;只记录&#xff0c;当前t需要计算几次 题目描述&#xff1a;…...

再有人说数字孪生大屏没有用,用这8条怼回去。

数字孪生大屏之所以受到欢迎&#xff0c;主要有以下几个原因&#xff1a; 实时数据可视化 数字孪生大屏可以将实时数据以直观的可视化形式展示出来&#xff0c;让用户能够一目了然地了解数据的状态和趋势。这样可以帮助用户更好地理解和分析数据&#xff0c;及时做出决策和调…...

蓝桥杯练习系统(算法训练)ALGO-946 Q神的足球赛

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 足球赛上&#xff0c;只见Q神如闪电般的速度带球时而左&#xff0c;时而右&#xff0c;时而前&#xff0c;时而后&#xff…...

【Android】Kotlin学习之Kotlin方法的声明和传参

方法声明 普通类的方法 静态类的方法 不需要构建实例对象, 可以通过类名直接访问静态方法 : NumUtil.double(1) companion object 伴生类的方法 使用companion object 在普通类里定义静态方法 参数 括号内传入方法 : 当参数是方法时, 并且是最后一个参数 , 可以使用括号外…...

微信小程序 17:小程序使用 npm 包和组件应用

目前&#xff0c;小程序中已经支持实用 npm 安装第三方包&#xff0c;从而提高小程序的开发效率&#xff0c;但是在小程序中使用 npm 包有三个限制&#xff1a; 不支持 Node.js内置库的包不支持依赖于浏览器内置对象的包不支持依赖于 C插件的包 Vant Weapp Vant Weapp是有赞…...

【mysql篇】执行delete删除大量数据后,磁盘未清空,为什么?

目录 迁移脚本删除数据以及备份数据 解决方法OPTIMIZE TABLE二进制日志按月生成数据 最近某个项目虽说用户量不大&#xff0c;但是&#xff0c;单表的数据量越来越大&#xff0c;mysql一般单表超过千万级别后&#xff0c;性能直线下降&#xff0c;所以利用shardingphere按月做了…...

【Qt 学习笔记】Qt常用控件 | 多元素控件 | Tree Widget的说明及介绍

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 多元素控件 | Tree Widget的说明及介绍 文章编号&#x…...

在Mars3d实现cesium的ImageryLayer自定义瓦片的层级与原点

需要自定义瓦片层级和原点&#xff0c;所以需要自己写第三方图层&#xff0c;但是之前写的很多方法&#xff0c;图层控制和显隐以及透明度&#xff0c;需要跟之前的交互一直&#xff0c;改动量太大的话不划算&#xff0c;所以直接看Mars3d的layer基类&#xff0c;把重写的image…...

logback日志持久化

1、问题描述 使用logback持久化记录日志。 2、我的代码 logback是Springboot框架里自带的&#xff0c;所以只要引入“spring-boot-starter”就行了。无需额外引入logback依赖。 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns&…...

函数原型(Function Prototype)、函数定义(Function Definition)和函数声明(Function Declaration)

函数原型&#xff08;Function Prototype&#xff09;、函数定义&#xff08;Function Definition&#xff09;和函数声明&#xff08;Function Declaration&#xff09;在C和C等编程语言中扮演着不同的角色&#xff0c;但它们有时在概念上可能会有些重叠。下面是它们之间的主要…...

Go有无缓冲channel的区别

无缓冲的channel channel的默认类型就是无缓冲的。当一个数据被发送到无缓冲的channel中&#xff0c;发送操作会被阻塞&#xff0c;知道有另一个goroutine从这个channel中接收这个数据。同样&#xff0c;当试图从一个无缓冲的channel中接收数据时&#xff0c;如果没有数据可以…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中&#xff0c;向量运算构成了理解几何结构的基石。叉乘&#xff08;外积&#xff09;与点积&#xff08;内积&#xff09;作为向量代数的两大支柱&#xff0c;表面上呈现出截然不同的几何意义与代数形式&#xff0c;却在深层次上揭示了向量间相互作用的…...

字符串哈希+KMP

P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...

未授权访问事件频发,我们应当如何应对?

在当下&#xff0c;数据已成为企业和组织的核心资产&#xff0c;是推动业务发展、决策制定以及创新的关键驱动力。然而&#xff0c;未授权访问这一隐匿的安全威胁&#xff0c;正如同高悬的达摩克利斯之剑&#xff0c;时刻威胁着数据的安全&#xff0c;一旦触发&#xff0c;便可…...

运动控制--BLDC电机

一、电机的分类 按照供电电源 1.直流电机 1.1 有刷直流电机(BDC) 通过电刷与换向器实现电流方向切换&#xff0c;典型应用于电动工具、玩具等 1.2 无刷直流电机&#xff08;BLDC&#xff09; 电子换向替代机械电刷&#xff0c;具有高可靠性&#xff0c;常用于无人机、高端家电…...

NLP学习路线图(三十四): 命名实体识别(NER)

一、命名实体识别(NER)是什么? 命名实体识别(Named Entity Recognition, NER)是自然语言处理中的一项关键序列标注任务。其核心目标是从非结构化的文本中自动识别出特定类别的名词性短语,并将其归类到预定义的类别中。 核心目标:找到文本中提到的命名实体,并分类。 典…...