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

Junit到Springboot单元测试

第一部分 junit与springboot的前世今生一、junit4与junit5及springboot中的使用在现代软件开发中单元测试是确保代码质量的重要环节。Spring Boot框架通过整合JUnit为开发者提供了便捷的单元测试支持。1.1 Spring Boot中JUnit版本的变化在Spring Boot 2.0之前框架默认使用JUnit 4作为测试平台。然而从Spring Boot 2.0开始JUnit 5成为默认的测试框架。以下是Spring Boot不同版本中JUnit版本的对比Spring Boot版本默认JUnit版本1.xJUnit 42.xJUnit 5例如Spring Boot 2.2.0使用JUnit 5.5.2版本。开发者可以通过POM文件确认具体版本。1.2 POM文件配置在Spring Boot项目中单元测试的依赖通过spring-boot-starter-test启动器引入。以下是POM文件的配置示例dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope exclusions exclusion groupIdorg.junit.vintage/groupId artifactIdjunit-vintage-engine/artifactId /exclusion /exclusions /dependency1.3 排除JUnit Vintage Enginejunit-vintage-engine是JUnit 3和JUnit 4的运行支持平台。默认情况下Spring Boot测试启动器会排除该依赖以鼓励开发者使用JUnit 5。如果需要使用JUnit 4可以移除exclusions标签。二、JUnit 4与JUnit 5的对比以下是JUnit 4和JUnit 5的主要差异特性JUnit 4JUnit 5注解RunWith、TestSpringBootTest、Test默认启动类支持需要手动指定启动类自动检测启动类测试方法支持需要Test注解需要Test注解扩展支持有限更强大的扩展机制三、JUnit 4测试代码示例以下是一个基于JUnit 4的测试代码示例import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.junit.Test; RunWith(SpringJUnit4ClassRunner.class) SpringBootTest(classes SpringBootExceptionAndJourneyApplication.class) public class UserServiceTest { Test public void testAddUser() { System.out.println(JUnit 4 测试方法运行成功); } }四、JUnit 5测试代码示例以下是一个基于JUnit 5的测试代码示例import org.springframework.boot.test.context.SpringBootTest; import org.junit.jupiter.api.Test; SpringBootTest public class UserServiceTest { Test public void testAddUser() { System.out.println(JUnit 5 测试方法运行成功); } }五、实际案例持久层与业务层测试假设我们有一个UserDAO和UserService以下是它们的实现代码5.1 持久层代码public class UserDAOImpl { public void insert() { System.out.println(INSERT INTO USER VALUES(...)); } }5.2 业务层代码import org.springframework.stereotype.Service; Service public class UserServiceImpl { private final UserDAOImpl userDAO; public UserServiceImpl(UserDAOImpl userDAO) { this.userDAO userDAO; } public void addUser() { userDAO.insert(); } }5.3 测试代码import org.springframework.boot.test.context.SpringBootTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; SpringBootTest public class UserServiceTest { Autowired private UserServiceImpl userService; Test public void testAddUser() { userService.addUser(); } }六、常见问题与解答以下是关于Spring Boot整合JUnit单元测试的常见问题问题答案1. Spring Boot默认使用哪个JUnit版本Spring Boot 2.x默认使用JUnit 5。2. 如何在Spring Boot中使用JUnit 4需要移除POM文件中junit-vintage-engine的排除配置。3. JUnit 5是否需要指定启动类默认情况下JUnit 5会自动检测启动类。如果项目中有多个启动类需要通过SpringBootTest(classes ...)指定。4. JUnit 5的测试方法是否需要RunWith注解不需要JUnit 5使用SpringBootTest注解即可。5. 如何确认JUnit版本通过POM文件中的依赖版本确认例如junit-jupiter-api的版本号。七、流程图Spring Boot整合JUnit单元测试的步骤创建Spring Boot项目添加spring-boot-starter-test依赖确认JUnit版本编写测试代码运行测试第一部分总结我们现在直接使用junit5在springboot项目中使用即可。使用方式为添加注解SpringBootTest(会自己找启动类有多个则通过classes ...指定)就可以让容器启动来测试。疑问1不是说5的话boot项目需要ext注解吗AI解答ExtendWith确实是 JUnit 5 的核心注解。不过在 Spring Boot 项目里你通常不需要手动添加它。 为什么会有这个误解你的理解是对的JUnit 5 确实使用ExtendWith来集成 Spring 的功能它取代了 JUnit 4 的RunWith。在早期版本的 Spring Boot (2.1.x 之前)确实需要手动在测试类上写上ExtendWith(SpringExtension.class)。✅ 现在的实际情况是怎样的从Spring Boot 2.1.x版本开始官方为了让开发更便捷做了一个“贴心”的优化。SpringBootTest这个我们最常用的注解其内部源码已经自动包含了ExtendWith(SpringExtension.class)。你可以把它理解为SpringBootTest是一个“大礼包”里面已经帮你把ExtendWith这个“工具”放进去了。所以当你使用SpringBootTest时就无需再重复添加了。代码对比早期写法 (已过时)// 在 Spring Boot 2.1 之前需要这样写 ExtendWith(SpringExtension.class) // 手动启用 Spring 扩展 SpringBootTest public class OrderServiceTest { // ... }现在写法 (推荐)// 现在这样写就足够了 SpringBootTest public class OrderServiceTest { // ... } 什么时候才需要手动写ExtendWith只有在一些不使用SpringBootTest的底层测试场景中你才可能需要手动添加。例如如果你只用ContextConfiguration来加载一个特定的 Spring 配置文件进行测试这时就需要手动通过ExtendWith(SpringExtension.class)来启用 Spring 的扩展支持。但对于绝大多数 Spring Boot 的集成测试来说放心地只使用SpringBootTest吧疑问2有必要每次启动整个容器吗请看第二部分第二部分 springboot项目怎么进行mock很多开发者在刚开始写测试时都会纠结是“启动整个 Spring 容器”还是“只测一个类”。简单来说“优雅”的测试 选对测试类型 用好 Mock 隔离 一、Mock 是啥解决啥问题1. 通俗解释什么是 Mock想象一下你是一名汽车引擎设计师你在测试UserService你需要测试引擎UserService的运转是否良好。如果不使用 Mock你必须把引擎装到整辆车里连上油箱、排气管、轮胎甚至要把车开到路上启动 Spring 容器、连接真实数据库、连接真实 Redis。这非常慢而且如果车打不着火你不知道是引擎坏了还是油箱漏了还是轮胎没气。使用 Mock你在实验室里给引擎接上一个模拟油箱Mock Repository和一个模拟排气管Mock EmailService。你可以控制“模拟油箱”里有多少油Stubbing预设返回值。你可以观察引擎是否真的向“模拟排气管”排气了Verification验证调用。重点你只测试引擎本身不关心外面的世界。2. Mock 解决了什么问题速度极快不需要启动 Spring 容器不需要连接数据库IO 操作最耗时。单元测试通常是毫秒级的。隔离性强如果测试失败了肯定是你的Service逻辑写错了而不是因为数据库连不上或者网络波动。覆盖极端情况你可以轻松模拟“数据库挂了”或者“查不到数据”的场景而在真实环境中很难故意制造这些故障。✨ 二、如何“优雅”地执行 Boot 项目单元测试在 Spring Boot 中优雅的核心在于“各司其职”。不要把所有测试都写成SpringBootTest启动全容器那样太慢了。我们需要区分两种测试策略1. 纯单元测试 (Unit Test) —— 推荐用于 Service 层特点完全不启动 Spring 容器纯 Java 代码运行。工具JUnit 5 Mockito (Mock,InjectMocks)。场景测试UserService里的业务逻辑比如计算价格、校验参数。代码示例// 1. 不需要 SpringBootTest不需要启动容器 // 使用 Mockito 的扩展来初始化 Mock 对象 ExtendWith(MockitoExtension.class) class UserServiceTest { // 2. Mock: 创建一个假的 UserRepository它是空的需要你喂数据 Mock private UserRepository userRepository; // 3. InjectMocks: 创建 UserService 实例并把上面的 userRepository 塞进去 InjectMocks private UserService userService; Test void shouldFindUserById() { // --- Arrange (准备) --- User mockUser new User(1L, Alice); // 告诉 Mock 对象当有人调用 findById(1L) 时返回 mockUser when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser)); // --- Act (执行) --- User result userService.findById(1L); // --- Assert (断言) --- assertThat(result.getName()).isEqualTo(Alice); // --- Verify (验证) --- // 验证 userRepository.findById 是否真的被调用了一次 verify(userRepository, times(1)).findById(1L); } }优雅点速度飞快完全隔离。2. 切片测试 / 集成测试 (Slice Test) —— 推荐用于 Controller 或 Repository特点只启动 Spring 容器的一部分比如只启动 Web 层或者只启动 JPA 层。工具WebMvcTest(控制器),DataJpaTest(数据库),MockBean。场景测试UserController的接口映射是否正确或者测试 SQL 语句是否正确。代码示例 (测试 Controller)// 1. WebMvcTest: 只启动 Web 层相关的 Bean (Controller, Converter 等)不启动 Service WebMvcTest(UserController.class) class UserControllerTest { Autowired private MockMvc mockMvc; // Spring 提供的模拟 HTTP 客户端 // 2. MockBean: 这是 Spring 的注解 // 它会去 Spring 容器里把 UserService 替换成一个 Mock 对象 MockBean private UserService userService; Test void shouldReturnUserJson() throws Exception { // --- Arrange --- // 模拟 Service 层返回数据 when(userService.findById(1L)).thenReturn(new User(1L, Alice)); // --- Act Assert --- // 发送一个模拟的 GET 请求 mockMvc.perform(get(/users/1)) .andExpect(status().isOk()) // 期望状态码 200 .andExpect(jsonPath($.name).value(Alice)); // 期望返回 JSON 中有 name: Alice } }优雅点比SpringBootTest快但又能测试 Spring 的注解如RestController,RequestMapping是否生效。 三、总结Mock 注解对比表这是最容易混淆的地方请注意区分表格特性Mock(Mockito)MockBean(Spring Boot)所属库MockitoSpring Boot Test是否启动 Spring否(纯单元测试)是(集成测试/切片测试)作用范围仅在测试类内部有效会替换 Spring 容器中的 Bean使用场景测试 Service 业务逻辑测试 Controller, 或者需要 Spring 注入的场景性能极快 (毫秒级)较快 (秒级取决于加载多少组件) 四、最佳实践建议Service 层优先使用ExtendWith(MockitoExtension.class)Mock。不要动不动就SpringBootTest那样太慢了。Controller 层使用WebMvcTestMockBean。Repository 层使用DataJpaTest(它会自动配置内存数据库 H2)。全链路测试只有当你需要测试“整个应用能不能跑起来”或者“配置类是否正确”时才使用SpringBootTest。这样分层测试你的项目构建速度会非常快而且逻辑清晰维护起来也很优雅。第二部分总结使用mock可以最小化范围测试而不是启动整个容器。一般测试的都是service层直接使用ExtendWith(MockitoExtension.class)Mock。不要动不动就SpringBootTest那样太慢了第三部分 Mock中的常见问题一、mock原理就是 “伪造” 依赖接口 / 对象 / 函数的返回结果让程序在没有真实后端、真实服务时也能正常跑、正常测。原理为通过动态代理、字节码增强或请求拦截等方式劫持目标方法 / 接口调用跳过真实逻辑执行并直接返回预设伪造数据从而实现依赖隔离与行为模拟。✨ 疑问final类怎么模拟呢在 Java 中final 关键字的设计初衷就是为了防止继承类或重写方法。而 Mockito 的核心原理恰恰是生成子类动态代理来拦截方法调用。 所以默认情况下Mockito 无法 Mock final 类或 final 方法。如果你强行去 mock通常会报 Cannot mock/spy class ... final class 的错误。 方案使用mockito-inline推荐现代做法这是目前最主流的做法。从 Mockito 2.x 后期版本开始官方提供了一个扩展模块mockito-inline它利用 Java Instrumentation API 在运行时修改字节码从而支持 Mockfinal类。适用场景Spring Boot 2.x (较新版本) 或 Spring Boot 3.x且你不想引入沉重的 PowerMock。1. 添加依赖虽然 Spring Boot 的spring-boot-starter-test已经包含了mockito-core但你需要额外引入mockito-inline。dependency groupIdorg.mockito/groupId artifactIdmockito-inline/artifactId version5.x.x/version !-- 版本号通常与 mockito-core 保持一致 -- scopetest/scope /dependency2. 开启配置关键步骤仅仅加依赖是不够的你必须告诉 Mockito 使用这个“内联”模式。在src/test/resources目录下创建一个文件夹mockito-extensions并在其中创建一个文件org.mockito.plugins.MockMaker。文件路径src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker文件内容mock-makerinline3. 编写测试配置好后你就可以像 Mock 普通类一样 Mockfinal类了代码完全不用变// 假设 FinalService 是一个 final 类 final class FinalService { public String sayHello() { return Hello; } } ExtendWith(MockitoExtension.class) class FinalServiceTest { Mock private FinalService finalService; // 直接 Mock不会报错 Test void testFinalClass() { when(finalService.sayHello()).thenReturn(Mocked Hello); assertEquals(Mocked Hello, finalService.sayHello()); } }二、 Spy 是啥解决什么问题1. 核心概念部分模拟Mock完全模拟创建一个空壳对象。所有方法默认都不执行真实代码直接返回 null 或 0。你必须手动定义每一个方法的行为。Spy部分模拟包装一个真实的对象。默认情况下它会执行真实的代码。只有当你明确告诉它“这个方法要拦截”时它才会返回假数据。2. 解决什么问题场景一遗留代码或复杂对象。当你有一个类方法很多你只想 Mock 其中一个很难测的方法比如调用了外部 API而其他方法逻辑很复杂你不想重写这时用 Spy 最省事。场景二验证真实调用。你想确保某个方法被调用了同时还想验证它执行后的真实副作用。️ 怎么用核心语法在 Spring Boot 项目中我们通常分两种情况使用 Spy纯单元测试和Spring 容器集成测试。1. 纯单元测试使用Spy这是 Mockito 的原生用法用于测试普通的 Java 类。关键点使用 Spy 时存根语法Stubbing必须换Mock 用when(mock.method()).thenReturn(...)Spy 用doReturn(...).when(spy).method()为什么因为 Spy 默认执行真实方法如果用when(spy.method())真实方法会立即执行可能导致空指针异常。ExtendWith(MockitoExtension.class) class UserServiceTest { // 1. 必须初始化真实对象不能写 Spy private UserService userService; (这样会报空指针) Spy private UserService userService new UserService(); Mock private UserRepository userRepository; Test void testSpyUsage() { // --- Arrange --- // 假设 UserService 有个方法 calculateTax() 很复杂我们想 Mock 它 // 注意语法doReturn(...).when(spy).method() doReturn(100.0).when(userService).calculateTax(); // --- Act --- // 调用其他未 Mock 的方法会执行真实逻辑 // 调用 calculateTax会返回 100.0 double tax userService.calculateTax(); // --- Assert --- assertEquals(100.0, tax); // --- Verify --- // 验证真实方法是否被调用 verify(userService, times(1)).calculateTax(); } }2. Spring 集成测试使用SpyBean当你使用SpringBootTest时普通的Spy无法替换 Spring 容器里的 Bean。这时要用 Spring Boot 提供的SpyBean。作用把 Spring 容器里原本的 Bean 替换成一个 Spy 对象。SpringBootTest class OrderServiceIntegrationTest { Autowired private OrderService orderService; // 真实的 Service // 1. SpyBean替换容器里的 UserService但保留真实逻辑 SpyBean private UserService userService; Test void testOrderWithSpyBean() { // --- Arrange --- // 拦截 getUserLevel 方法返回 VIP doReturn(VIP).when(userService).getUserLevel(anyLong()); // --- Act --- // 调用 orderService它会调用 userService.getUserLevel // 此时 getUserLevel 返回 VIP但 userService 的其他方法如 saveUser仍走真实数据库逻辑如果配置了的话 orderService.createOrder(1L); // --- Verify --- // 验证 getUserLevel 确实被调用了 verify(userService).getUserLevel(1L); } }⚖️ Mock vs Spy怎么选为了让你更清晰地做决定我整理了这个对比表表格维度Mock (完全模拟)Spy / SpyBean (部分模拟)真实代码执行绝不执行默认执行(除非被拦截)初始化要求不需要实例化必须有真实实例 (new Object())存根语法when(mock.method())...doReturn(...).when(spy)...风险低完全隔离中真实代码可能抛异常或依赖数据库适用场景依赖对象Repository, Client被测对象本身想测部分逻辑、遗留代码⚖️ Spy vs InjectMocks维度SpyInjectMocks核心职责部分模拟。包装一个真实对象保留真实逻辑但允许拦截特定方法。依赖注入。创建被测对象并自动把Mock或Spy塞进去。代码行为默认执行真实代码。负责初始化对象通过构造函数或字段注入。语法陷阱必须手动初始化实例 new UserService()否则报错。不需要手动初始化Mockito 会自动帮你new出来。常用搭配用于被测对象本身当你不想 Mock 所有方法时。用于被测对象当你想完全隔离只测逻辑流转时。存根语法必须用doReturn(...).when(spy)...(它本身不存根它注入的对象如果是 Mock则用when...thenReturn) 避坑指南初始化陷阱使用Spy时字段必须手动初始化如 new UserService()否则 Mockito 无法创建 Spy 对象会报NullPointerException。Final 方法和 Mock 一样Spy 也无法 Spyfinal方法。调用final方法时永远执行真实代码无法拦截。自调用问题在 Spring 中如果一个 Bean 的方法 A 调用了同一个类的方法 Bthis.methodB()即使你 Spy 了方法 BA 调用 B 时走的也是真实逻辑Spy 的拦截可能失效因为 Spring AOP 代理机制。总结建议在单元测试中优先使用Mock因为它更干净、更安全。只有当你真的需要保留真实逻辑或者为了省事不想 Mock 所有依赖时才使用Spy。

相关文章:

Junit到Springboot单元测试

第一部分 junit与springboot的前世今生一、junit4与junit5及springboot中的使用在现代软件开发中,单元测试是确保代码质量的重要环节。Spring Boot框架通过整合JUnit,为开发者提供了便捷的单元测试支持。1.1 Spring Boot中JUnit版本的变化在Spring Boot …...

GOM引擎插件加载全解析:从X-FKGOM到X-GOMPJ,如何正确配置登录器与M2插件

GOM引擎插件深度配置指南:从授权管理到功能优化全流程 在传奇私服开发领域,GOM引擎凭借其出色的画面表现和丰富的功能扩展性,已成为众多开发者的首选方案。但真正让GOM引擎从同类产品中脱颖而出的,是其强大的插件系统——通过X-FK…...

新手必看:Qwen-Image-Edit-2511-Unblur-Upscale修复模糊人像全流程详解

新手必看:Qwen-Image-Edit-2511-Unblur-Upscale修复模糊人像全流程详解 1. 为什么你需要这个工具? 你是否遇到过这样的情况:翻看老照片时发现珍贵的人像照片变得模糊不清?或者手机拍摄的照片因为手抖而变得模糊?传统…...

Dify Rerank性能翻倍实录:从0.42到0.89 NDCG提升,我们只改了这4行配置

第一章:Dify Rerank性能翻倍实录:从0.42到0.89 NDCG提升,我们只改了这4行配置在真实生产环境中对 Dify v0.12.3 的 Rerank 模块进行基准测试时,原始配置下对 1,247 条 QA 对的排序结果 NDCG5 仅为 0.42。通过深入分析 reranker 调…...

我把 VS Code 里看依赖版本的插件,做了一个更快的版本

我把 VS Code 里看依赖版本的插件,做了一个更快的版本 平时写 Node.js 项目时,我经常会在 package.json 里看看依赖有没有更新。 之前我一直在用 Version Lens 这类插件,它的体验本身是不错的:打开 package.json,就能直…...

NE2A-SCPU01安全网络控制器

NE2A-SCPU01 安全网络控制器一、产品概述NE2A-SCPU01 是一款工业级安全网络控制器,用于监控和管理工业安全系统。该控制器可集成多个安全设备(如安全传感器、急停开关、安全继电器等),实现安全逻辑运算、故障检测和系统保护&#…...

RV1126准备-----编译和测试SDK自带的RKNN例程

一、SDK自带的RKNN例程介绍位置: SDK自带的RKNN例程位于SDK的external/rknpu/rknn/rknn_api/examples目录下内容: 包含多输入示例、目标检测、批量推理、透传模式、零拷贝等不同功能的示例代码3rdparty目录:CImg: 轻量级C图像处理库,只有一个CImg.h头文件&#xff0…...

Make构建系统原理与嵌入式工程实践

1. Make 构建系统原理与工程实践在嵌入式开发流程中,从源代码到可执行镜像的转化过程包含两个关键阶段:编译(compile)与构建(build)。编译关注单个源文件如何转换为目标文件(如.o)&a…...

(二)传统企业vs数字原生企业:差距到底在数据,还是思维?

传统企业vs数字原生企业:差距到底在数据,还是思维?在上一篇博客《别再误解数字化!企业转型的核心本质,从来不是买软件》里,我们戳破了企业数字化转型的最大误区:把工具采购当成转型核心&#xf…...

如何在Java中使用字符串拼接优化性能

在Java中进行字符串拼接时,选择合适的方式对性能影响很大。由于String对象是不可变的,每次使用拼接都会创建新的String对象,频繁操作会导致大量临时对象,增加GC压力。以下是几种优化字符串拼接性能的方法。1. 使用StringBuilder进…...

Python后台任务不中断:nohup与输出缓冲的实战技巧

1. 为什么需要后台运行Python脚本 我在第一次部署机器学习模型训练任务时,就遇到了一个典型问题:本地SSH连接到远程服务器启动训练后,只要网络波动导致连接断开,训练进程就会立刻终止。这种经历相信不少开发者都遇到过——辛辛苦苦…...

基于T型三电平逆变器的下垂控制:电压电流双闭环与LCL滤波、SPWM调制仿真研究

下垂控制-基于T型三电平逆变器的下垂控制,电压电流双闭环,采用LCL滤波,SPWM调制方式 1.提供simulink仿真源文件 2.提供下垂控制原理与下垂系数计算方法 3.中点平衡控制,电压电流双闭环控制 4.提供参考文献 在现代电力系统中&#…...

从零到部署:我用SeaTable私有云为团队搭建了一个轻量级项目管理系统(附docker-compose.yml配置)

从零构建企业级项目协同平台:基于SeaTable私有云的轻量化实践指南 当团队规模扩张到10人以上时,Excel共享表格开始频繁出现版本冲突,而Jira这类专业工具又显得过于笨重。我们技术团队在尝试了市面上17种协作工具后,最终选择用SeaT…...

三月第三周周报

标题Physics-informed machine learning with embedded sediment rating curve constraints for high-fidelity multi-lead-time forecast of suspended sediment concentration背景作者Yousef Hemmatzadeh , Sadra Shadkani期刊来源Journal of hydrologyDOI10.1016/j.jhydrol.…...

FPGA千兆网硬件设计避坑指南:RTL8211EG布局布线实战经验分享

FPGA千兆网硬件设计避坑指南:RTL8211EG布局布线实战经验分享 在高速数字电路设计中,千兆以太网接口的硬件实现一直是工程师面临的挑战之一。作为FPGA与物理层之间的关键桥梁,RTL8211EG PHY芯片的布局布线质量直接影响着网络通信的稳定性和性能…...

为什么嵌入式开发离不开C语言:底层执行模型与工程实践

1. 项目概述本项目并非硬件设计实体,而是一则面向嵌入式系统工程师与底层开发者的技术科普漫画文档。其核心价值在于以可视化、具象化的方式厘清编程语言演进脉络中C语言的不可替代性,并锚定其在嵌入式领域的真实技术坐标。不同于常规开源硬件项目提供原…...

MCP 2.0生产部署安全熵值评估模型(独家):用3个量化指标预判协议层侧信道泄露风险——仅限首批200位架构师获取

第一章:MCP 2.0生产部署安全熵值评估模型的演进逻辑与核心定位MCP 2.0(Mission-Critical Platform 2.0)在金融与能源等高保障场景中承担着实时决策、多源异构数据融合与自主策略执行的关键职能。其生产部署的安全熵值评估模型并非对传统风险评…...

Kubernetes 入门:从容器到集群管理的全面指南

一、前言在云原生时代,Kubernetes(简称 K8S)已经成为容器编排的事实标准。无论是初创公司还是大型企业,都在积极采用 K8S 来管理和部署他们的应用程序。本文将带你从零开始,系统了解 Kubernetes 的核心概念、架构原理和…...

华为HCIA(华为认证ICT工程师)大纲:从零基础到网络实战的完整指南

1. 华为HCIA认证概述:网络工程师的起点 华为HCIA(华为认证ICT工程师)是华为认证体系中面向初学者的入门级认证,相当于网络工程师行业的"驾照考试"。作为华为认证金字塔的基石,HCIA认证覆盖网络技术、云计算、…...

绩效流于形式?3款HR咨询方案实测对比

一、先上硬参数:三家咨询机构核心信息对比先声明啊,这表是我跟三家机构对接企业客户反馈整理的,没水分,都是实打实的信息:机构名称核心服务模式付费方式咨询师背景售后保障适配企业类型润行咨询结果式咨询陪伴落地按月…...

仓储空间智能基础设施构建路径研究: 融合动态建模与 Pixel-to-Space 的三维空间认知与决策体系(面向“十五五”的关键技术突破与工程应用)

仓储空间智能基础设施构建路径研究 —— 融合动态建模与 Pixel-to-Space 的三维空间认知与决策体系(面向“十五五”的关键技术突破与工程应用) 一、研究背景:迈向空间智能基础设施时代 随着数字经济、智能制造与新型基础设施建设的持续推进…...

SPM新手避坑指南:手把手教你完成fMRI数据预处理(从DICOM到平滑)

SPM新手避坑指南:手把手教你完成fMRI数据预处理(从DICOM到平滑) 当你第一次打开SPM软件准备处理fMRI数据时,是否感到无从下手?作为神经影像分析的基础工具,SPM在学术研究中广泛应用,但其复杂的参…...

FPGA实战:从PWM原理到《欢乐颂》音乐播放器的设计与实现

1. 蜂鸣器与PWM基础原理 第一次接触FPGA驱动蜂鸣器时,我被这个看似简单却充满技术细节的项目深深吸引了。无源蜂鸣器就像个"挑剔的歌手",不给它合适的节奏就绝不开口。这里的关键就在于PWM(脉冲宽度调制)技术&#xff0…...

R语言实战:如何用ggplot2绘制Structure分析的DeltaK折线图

R语言实战:用ggplot2绘制Structure分析的DeltaK折线图 群体遗传学研究中,Structure软件是分析群体结构的经典工具。但如何从多次运行结果中确定最佳K值,一直是研究者面临的挑战。DeltaK方法由Evanno提出,通过计算相邻K值似然值的变…...

STM32F103RCT6+MPU6050实战:手把手教你打造自平衡麦克纳姆轮小车(附PID调参秘籍)

STM32F103RCT6MPU6050实战:从零构建自平衡麦克纳姆轮机器人 当四个麦克纳姆轮在地面划出精确的八字轨迹,车身在倾斜瞬间自动调整转速恢复平衡——这种充满未来感的运动控制,其实用一块30元的STM32开发板就能实现。本文将彻底拆解自平衡麦克纳…...

Jetson Orin NX实战:从零部署YOLOv5的完整环境配置指南

1. Jetson Orin NX与YOLOv5的黄金组合 如果你正在寻找一款能在边缘设备上高效运行目标检测的解决方案,Jetson Orin NX搭配YOLOv5绝对是当前最热门的选择之一。作为NVIDIA最新推出的边缘计算平台,Jetson Orin NX凭借其强大的AI算力和能效比,已…...

基于springboot大数据爬虫二手车管理系统平台设计与开发(源码+精品论文+答辩PPT等资料)

博主介绍:CSDN毕设辅导第一人、靠谱第一人、全网粉丝50W,csdn特邀作者、博客专家、腾讯云社区合作讲师、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交…...

普中51单片机打地鼠游戏开发全流程:从仿真到代码实现(附完整流程图)

普中51单片机打地鼠游戏开发全流程:从仿真到代码实现 记得第一次用51单片机做游戏时,那种看到LED灯随按键亮起的兴奋感至今难忘。打地鼠游戏看似简单,却是学习嵌入式开发的绝佳练手项目——它涵盖了硬件连接、中断处理、随机数生成、状态机设…...

基于springboot上海百货展展会系统设计与开发(源码+精品论文+答辩PPT等资料)

博主介绍:CSDN毕设辅导第一人、靠谱第一人、全网粉丝50W,csdn特邀作者、博客专家、腾讯云社区合作讲师、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交…...

手把手教你绕过Dify Marketplace限制:本地编译自定义异步节点插件(含TypeScript类型声明补全与调试断点配置)

第一章:Dify自定义节点异步处理概述Dify 的自定义节点(Custom Node)机制支持在工作流中嵌入开发者自主实现的逻辑单元,其中异步处理能力是构建高响应性、长周期任务(如大文件解析、外部 API 轮询、模型微调回调&#x…...