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

Java 单元测试框架之 Mockito 详细介绍


本文是博主在学习如何高效创建单元测试时的知识记录,文中项目代码是基于 SpringBoot 项目,测试组件使用的 JUnit 5,单元测试组件使用的 Mockito 。虽然现在都是在使用 AI 助手帮助生成单元测试和代码辅助修改,但我们不能被工具挡住了要了解知识的目的,学会知识才是根本所在。
网图


文章目录

  • 一、Mockito 是什么?
  • 二、Mockito 的使用方法
    • 1、使用 Maven 引入依赖
    • 2、使用 Gradle 引入依赖
    • 3、如何使用 mock 和 when 方法
  • 三、Mockito 常见注解
    • 1、@ExtendWith(MockitoExtension.class)
    • 2、@Mock
    • 3、@Spy
    • 4、@InjectMocks
    • 5、@Captor
    • 6、@BeforeEach / @BeforeAll
    • 7、示例一
    • 8、示例二
    • 9、@Captor 示例
  • 四、注意事项

一、Mockito 是什么?

Mockito 是一个基于行为驱动开发(BDD)的模拟框架,用于Java的流行的单元测试框架,主要用于创建和管理模拟对象,使得编写单元测试变得更加简单和高效。

它允许开发者创建模拟对象,这些模拟对象可以模仿真实对象的行为,帮助开发者在隔离的环境中测试代码。通过使用 Mockito ,开发者可以专注于测试单个类的功能,而无需依赖外部系统或其他复杂的对象。

简单的说,就是某些方法调用的服务没有启动的话,Mockito 可以帮你模拟这个服务的返回值,让你可以只专注于自己的业务代码的开发。

用官方的换描述 Mockito 就是以下的几点:

  • 隔离测试:在单元测试中,需要隔离被测试的类与其他外部依赖,这样可以确保测试只关注被测试类的逻辑,而不受其他组件的影响。
  • 简化测试编写:Mockito 提供了简洁的 API ,使得创建和配置模拟对象变得容易,从而减少了测试代码的编写量,提供了大量的注解辅助完成测试用例的编写。
  • 提高测试的可靠性:通过模拟外部依赖,可以避免因外部系统的不稳定或不可用导致测试失败。

二、Mockito 的使用方法

1、使用 Maven 引入依赖

1、Spring Boot 2.2 及以上版本默认使用 JUnit 5 ,如果使用的是 JUnit 5 进行测试,需要引入 spring-boot-starter-test 依赖,它已经包含了 MockitoJUnit 5 的相关依赖。

pom.xml 中添加以下依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>

spring-boot-starter-test 是 Spring Boot 提供的一个测试启动器,它集成了多种测试框架和工具,其中就包括Mockito。由于 scope 设置为 test ,这些依赖只会在测试环境中生效。

2、如果你不想使用 spring-boot-starter-test ,也可以单独引入 Mockito 核心依赖。

pom.xml 中添加以下依赖:

<dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>4.11.0</version> <!-- 可根据需要选择合适的版本 --><scope>test</scope>
</dependency>

同时,如果你使用 JUnit 5 进行测试,还需要单独引入 JUnit 5 的依赖:

<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><scope>test</scope>
</dependency>
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><scope>test</scope>
</dependency>

3、扩展:Mockito 还提供了一些扩展,如Mockito Inline,可以用于模拟静态方法和私有方法等。如果你想要深入研究Mockito ,那一定要试试这些扩展。

pom.xml 中添加以下依赖:

<dependency><groupId>org.mockito</groupId><artifactId>mockito-inline</artifactId><version>4.11.0</version> <!-- 可根据需要选择合适的版本 --><scope>test</scope>
</dependency>

2、使用 Gradle 引入依赖

1、如果你使用 Gradle 构建项目,并且结合 JUnit 5 进行测试。

build.gradle 中添加以下依赖。

testImplementation 'org.springframework.boot:spring-boot-starter-test'

这行代码会引入 spring-boot-starter-test 依赖,其中包含了 Mockito 和 JUnit 5 的相关依赖。

2、如果你不想使用spring-boot-starter-test,可以单独引入Mockito核心依赖和JUnit 5的依赖。

build.gradle 中添加以下代码:

testImplementation 'org.mockito:mockito-core:4.11.0' // 可根据需要选择合适的版本
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-engine'

3、扩展:如果需要使用 Mockito Inline 扩展,可以在 build.gradle 中添加以下依赖:

testImplementation 'org.mockito:mockito-inline:4.11.0' // 可根据需要选择合适的版本

在 Spring Boo t项目中引入 Mockito 可以通过引入 spring-boot-starter-test 依赖的方式,也可以单独引入 Mockito 核心依赖和相关测试框架依赖。同时,还可以根据需要引入 Mockito 的扩展依赖。

3、如何使用 mock 和 when 方法

如果在测试用例中仅​使用 Mockito 进行测试时候,使用的是 Mockito 环境, 这个时候不会加载 SpringBoot 上下文,@Autowired 等注解不会起作用,这个时候手动使用 @Mock 和 @InjectMock 来处理类之间的依赖关系。

  • 在下面的示例不会加载 SpringBoot 上下文,会定位到 SpringBoot 的方法中。
  • 使用 Mockito.mock() 方法可以创建模拟对象。例如数据库的 Mapper 对象,用于调用数据库获取数据。
  • 使用 Mockito.when() 方法可以定义模拟对象的行为,这步很重要,模拟对象没办法拥有服务对象的功能。
  • 例如,在业务逻辑中存在调用数据库数据返回对象这样一个方法: 模拟对象.select(日期)
  • 我们使用 when(模拟对象.select(日期)).thenReturn(new User("John", 18, "男")); 这个语句定义模拟行为。
  • 即业务逻辑中 Mapper..select(日期) 会得到 new User("John", 18, "男") ,模拟对象也要拥有这个能力。
  • when 的意思就是如果遇到这个方法就返回 new User("John", 18, "男") 的结果,thenReturn 就是返回的意思。
import static org.mockito.Mockito.when;@ExtendWith(MockitoExtension.class)
public class UserServiceTest {@Testpublic void testSomeMethod() {// 首先使用 mock 方法创建一个模拟对象UserDao userDao = mock(UserDao.class);// 给这个模拟对象做一个设定,当 userDao.findById(1) 方法时,when(userDao.findById(1)).thenReturn(new User("John"));UserService userService = new UserService(userDao);// 注意:userService.findUserById(1) 即为 在这个方法中会传递到 userDao.findById(1)User user = userService.findUserById(1);assertEquals("John", user.getUsername());// 验证是否调用了 userDao.findById(1)verify(userDao).findById(1);// 模拟方法调用:除了返回固定值,还可以模拟抛出异常、返回不同值等复杂行为。when(userDao.findById(1)).thenThrow(new RuntimeException());// 参数匹配:可以使用参数匹配器来匹配方法调用的参数。when(userDao.findById(anyInt())).thenReturn(new User("John"));when(userDao.findByName(anyString())).thenReturn(new User("AnyName"));}
}

详细说一下 when 的用法,这个通常用在参数输入上,例如在上面使用了 userDao.findById(1) 方法,这里传了参数 1 ,但是很多时候我们项目中类似的业务代码都会传一些复杂对象,我们去构建这个复杂对象无疑是麻烦的。

这时,我们可以这样用 userDao.findById(anyInt()) ,对于基本类型 any() 方法都有支持,如果是日期则使用 any(LocalDate.class) ,如果是其他的 Object 类型则使用 any(Object.class)

三、Mockito 常见注解

Mockito 提供了多个注解,这些注解有助于简化测试代码,使测试结构更加清晰和易于维护。

1、@ExtendWith(MockitoExtension.class)

@ExtendWith(MockitoExtension.class) 用于将 Mockito 集成到 JUnit 5 测试框架。使用该注解后,JUnit 5 会自动初始化标记为 @Mock、@InjectMocks 等注解的对象,而无需手动调用 MockitoAnnotations.initMocks(this)。它使得在单元测试中使用 Mockito 更为便捷,可以快速创建模拟对象(mocks)、间谍对象(spies),并注入到被测试类中。

当测试不依赖于 Spring 容器时,MockitoExtension 可以模拟外部依赖,专注于测试目标类的逻辑。在测试中,如果目标类依赖于外部服务或组件,可以通过 @Mock 注解模拟这些依赖,从而集中测试目标类的行为。

2、@Mock

用于创建模拟对象。被该注解标记的字段,在测试类初始化时,Mockito 会自动为其创建一个模拟实例,在测试中模拟对象可以替代真实对象,用于获取对象中的方法进行测试。

当你需要测试 A 类中的 a 方法,a 方法引用了 B 类的 b 方法。其中我们称 a 方法为要测的业务方法,b 方法称为 a 业务中所要使用的服务方法,例如调用数据库。@Mock 注解就添加在要引入的 B 类的上面。

即,测试方法中调用的服务就是需要模拟的对象。

3、@Spy

用于创建一个真实对象的部分模拟(Spy)对象。与 @Mock 不同,@Spy 创建的对象会保留真实对象的部分行为,只有被 stubbed(设定特定行为)的方法才会按照模拟的方式执行。相当于这个注解注入的类还能引用部分自身逻辑。

4、@InjectMocks

用于自动将标记为 @Mock@Spy 的依赖注入到被测试的类中。这样可以方便地为被测试类提供模拟的依赖对象,减少手动实例化和注入的代码。这个注解就是放在我们要测试的那个方法所在类的上面,即 A 方法的上面。

5、@Captor

该注解用于捕获传递给模拟对象方法的参数。这在需要验证方法调用时传递的参数是否符合预期,或者需要对传递的参数进行进一步操作时非常有用。

6、@BeforeEach / @BeforeAll

这两个注解就是用来在测试用例运行之前对定义的对象做一些操作的,例如赋值或初始化。

7、示例一

该示例中 MyRepository 就是类 B ,引用的服务类,getData 就是服务方法 b,MyService 就是类 A ,测试方法所在类,getNewData 就是方法 a,要测试的方法。

import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;import static org.mockito.Mockito.when;@ExtendWith(MockitoExtension.class) // 启用 Mockito 扩展
public class MyServiceTest {@Mockprivate MyRepository myRepository; // 模拟 MyRepository@InjectMocksprivate MyService myService; // 将模拟的 myRepository 注入到 MyService 中private User user;@BeforeEachvoid setUp(){// 用于初始化 Mockito 注解MockitoAnnotations.openMocks(this);user = new User("jack", 20, "男");}@Testvoid testServiceMethod() {// 模拟行为when(myRepository.getData(any(LocalDate.class))).thenReturn("Mocked Data");// 测试服务方法String result = myService.getNewData();// 验证结果assertEquals("Mocked Data", result);}// 这里@Spy注解创建了MathCalculator的Spy对象,add方法被模拟,返回固定值10,而不是真实的计算结果。@Spyprivate MathCalculator calculator = new MathCalculator();@Testpublic void testAdd() {// 模拟add方法的行为Mockito.when(calculator.add(2, 3)).thenReturn(10);int result = calculator.add(2, 3);assertEquals(10, result);}class MathCalculator {public int add(int a, int b) {return a + b;}}}

在这个例子中,@Mock 注解用于创建模拟对象,@InjectMocks 注解用于将模拟对象注入到被测试类中。如果测试需要 Spring 的上下文支持(例如依赖注入),则需要使用 @ExtendWith(SpringExtension.class)@SpringBootTest ,而不是 @ExtendWith(MockitoExtension.class)

8、示例二

该示例中@InjectMocks@Mock 创建的 productDao 注入到 OrderService 中,使 OrderService 在测试时能使用模拟的 ProductDao 行为。

import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;public class OrderServiceTest {@Mockprivate ProductDao productDao;@InjectMocksprivate OrderService orderService;@Testpublic void testCalculateOrderTotal() {// 模拟productDao的getPrice方法Mockito.when(productDao.getPrice(1)).thenReturn(10.0);double total = orderService.calculateOrderTotal(1, 2);assertEquals(20.0, total);}
}class OrderService {private ProductDao productDao;public OrderService(ProductDao productDao) {this.productDao = productDao;}public double calculateOrderTotal(int productId, int quantity) {double price = productDao.getPrice(productId);return price * quantity;}
}class ProductDao {public double getPrice(int productId) {// 实际实现会从数据库等获取价格return 0;}
}

9、@Captor 示例

这里 @Captor 注解结合 ArgumentCaptor 捕获了传递给 emailSender.send 方法的第一个参数(邮箱地址),并验证其是否为预期值。

import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;public class EmailServiceTest {@Mockprivate EmailSender emailSender;@Captorprivate ArgumentCaptor<String> emailAddressCaptor;@Testpublic void testSendEmail() {EmailService emailService = new EmailService(emailSender);emailService.sendEmail("test@example.com", "Hello");Mockito.verify(emailSender).send(emailAddressCaptor.capture(), Mockito.anyString());assertEquals("test@example.com", emailAddressCaptor.getValue());}}class EmailService {private EmailSender emailSender;public EmailService(EmailSender emailSender) {this.emailSender = emailSender;}public void sendEmail(String to, String content) {emailSender.send(to, content);}}class EmailSender {public void send(String to, String content) {// 实际发送邮件的逻辑}}

四、注意事项

  • 避免过度模拟:虽然模拟可以隔离测试,但过度模拟可能导致测试失去意义,因为它与实际运行环境相差太大。
  • 维护测试的可读性:确保测试代码清晰易懂,避免过于复杂的模拟设置和验证逻辑。
  • 及时更新测试:当被测试类的接口或依赖发生变化时,及时更新相应的测试代码。

好了,通过以上介绍,你应该对 Mockito 单元测试有了较为清晰的了解,赶紧上手试试吧。

相关文章:

Java 单元测试框架之 Mockito 详细介绍

本文是博主在学习如何高效创建单元测试时的知识记录&#xff0c;文中项目代码是基于 SpringBoot 项目&#xff0c;测试组件使用的 JUnit 5&#xff0c;单元测试组件使用的 Mockito 。虽然现在都是在使用 AI 助手帮助生成单元测试和代码辅助修改&#xff0c;但我们不能被工具挡住…...

对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势 , 基于 openEuler 构建 LVS-DR 群集。

对比 LVS 负载均衡群集的 NAT 模式和 DR 模式&#xff0c;比较其各自的优势 NAT模式的优势&#xff1a; 可以隐藏后端服务器的IP地址&#xff0c;提高了系统的安全性。 支持多个后端服务器共享同一个IP地址&#xff0c;提高了系统的可扩展性。 可以在负载均衡器和后端服务…...

mapbox V3 新特性,添加下雪效果

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;mapbox 从入门到精通 文章目录 一、&#x1f340;前言1.1 ☘️mapboxgl.Map 地图对象…...

谈谈云计算、DeepSeek和哪吒

我不会硬蹭热点&#xff0c;去分析自己不擅长的跨专业内容&#xff0c;本文谈DeepSeek和哪吒&#xff0c;都是以这两个热点为引子&#xff0c;最终仍然在分析的云计算。 这只是个散文随笔&#xff0c;没有严谨的上下游关联关系&#xff0c;想到哪里就写到哪里。 “人心中的成见…...

深入HBase——引入

引入 前面我们通过深入HDFS到深入MapReduce &#xff0c;从设计和落地&#xff0c;去深入了解了大数据最底层的基石——存储与计算是如何实现的。 这个专栏则开始来看大数据的三驾马车中最后一个。 通过前面我们对于GFS和MapReduce论文实现的了解&#xff0c;我们知道GFS在数…...

【前端】【vue】vue2/3,nuxt的插槽使用详解

插槽在Vue2、Vue3和不同版本Nuxt中的使用 Vue2中的插槽 基础插槽 在Vue2中&#xff0c;基础插槽允许在组件的模板中定义一个占位符&#xff0c;然后在使用组件时插入自定义内容。例如&#xff0c;创建一个简单的MyBox组件&#xff1a; <template><div class"…...

逆境、情绪低落时可用的锦囊、咒语

《浮生一梦》&#xff08;一&#xff09; 大多数人都经历过逆境低谷、失败、挫折、看似无端情绪低落、抑郁… 人逢情绪低落时&#xff0c;几乎任何话都听不进去&#xff0c;再正的能量也塞不进脑子&#xff0c;笑话笑不出来&#xff0c;食不知味… 复原力不强者很难走出来&am…...

【目标检测json2txt】label从COCO格式json文件转YOLO格式txt文件

目录 🍀🍀1.COCO格式json文件 🌷🌷2.YOLO格式txt文件 💖💖3.xml2json代码(python) 🐸🐸4.输入输出展示 🙋🙋4.1输入json 🍂🍂4.2输出txt 整理不易,欢迎一键三连!!! 送你们一条美丽的--分割线-- 🍀🍀1.COCO格式json文件 COCO数…...

ASP.NET Core SixLabors.ImageSharp 位图图像创建和下载

从 MVC 控制器内部创建位图图像并将其发送到浏览器&#xff1b;用 C# 编写并与 Linux 和 Windows 服务器兼容。 使用从 ASP.NET MVC 中的控制器下载任何文件类型File。 此示例创建一个位图 (jpeg) 并将其发送到浏览器。它需要 NuGet 包SixLabors.ImageSharp v1.0.4。 另请参…...

Java开发实战:使用IntelliJ IDEA 开发Spring Boot + MyBatis + MySQL的详细实现步骤

使用IntelliJ IDEA 开发Spring Boot MyBatis MySQL的详细实现步骤 在本文中&#xff0c;我们将一步步讲解如何在IntelliJ IDEA 2024.2.3中使用Spring Boot、MyBatis和MySQL来开发一个简单的Web应用。通过本文&#xff0c;你将学会如何设置项目、配置数据库、创建实体类、编写…...

python-leetcode-在排序数组中查找元素的第一个和最后一个位置

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:def find_first(nums, target):left, right 0, len(nums) - 1result -1while left < rig…...

Oracle RHEL 7.8 安装

前言 Red Hat Enterprise Linux Server release 7.8 为企业级 SO 镜像。绝大部分企业如果使用Oracle数据库均会使用其企业版 OS &#xff0c;能够很好的支持数据库的运行 文档目的 当前文档仅针对 VMware Workstation Pro 进行 OS 介质安装。 镜像下载地址 注意&#xff1…...

Java多线程交替打印

1. 双线程交替打印奇偶数 class Printer{private int num1; //要打印的数字private Object myLock new Object();public static void main(String[] args){Printer pnew Printer();Thread t1new Thread( ()->p.printNum(true), "threadA");t1.start();Thread t…...

华为2288H V5服务器无法启动问题处理

问题&#xff1a;通电后服务器前面显示888&#xff0c;点击电源键没有反应 一.通过管理口管理服务器硬件设备 华为2288H V5它默认的IP是192.168.2.100 网关是255.255.255.0 2.将网线一头连接服务器的Mgmt口&#xff0c;另一头来连接笔记本的网口&#xff0c;将笔记本的的本地…...

阿里巴巴对deepseek回应

行业背景与发布契机 当杭州的DeepSeek在相关领域展现实力时&#xff0c;阿里巴巴为了在技术竞争中占据一席之地&#xff0c;推出新的视觉 - 语言模型&#xff0c;试图吸引行业关注。 Qwen2.5 - VL系列模型发布详情 模型介绍&#xff1a;阿里巴巴发布Qwen2.5 - VL系列视觉 - 语…...

如何使用UniApp实现页面跳转和数据传递?

在 UniApp 中&#xff0c;页面跳转和数据传递是基本的功能&#xff0c;允许用户在应用中浏览不同的页面并传递必要的信息。以下是如何实现页面跳转和数据传递的详细步骤和示例。 一、页面跳转 UniApp 提供了几种方式来进行页面跳转&#xff0c;主要包括&#xff1a; uni.nav…...

STM32:迎接汽车与AI时代MCU新挑战

作为通用32位MCU市场最受关注的产品系列&#xff0c;意法半导体&#xff08;ST&#xff09;的STM32 MCU从2007年问世之后就迎来爆发式增长&#xff0c;成功占据通用32位MCU市占率领头羊的位置&#xff0c;并且不断引领着通用MCU技术与应用的新思维开拓。 本文引用地址&#xf…...

【操作系统】深入理解Linux物理内存

物理内存的组织结构 我们平时所称的内存也叫随机访问存储器也叫 RAM 。RAM 分为两类&#xff1a; 一类是静态 RAM&#xff08; SRAM &#xff09;&#xff0c;这类 SRAM 用于 CPU 高速缓存 L1Cache&#xff0c;L2Cache&#xff0c;L3Cache。其特点是访问速度快&#xff0c;访…...

K8s组件

一、Kubernetes 集群架构组件 K8S 是属于主从设备模型&#xff08;Master-Slave 架构&#xff09;&#xff0c;即有 Master 节点负责集群的调度、管理和运维&#xff0c;Slave 节点是集群中的运算工作负载节点。 主节点一般被称为 Master 节点&#xff0c;master节点上有 apis…...

【ESP32接入国产大模型之Deepseek】

【ESP32接入国产大模型之Deepseek】 1. Deepseek大模型1.1 了解Deepseek api1.2 Http接口鉴权1.3. 接口参数说明1.3.1 请求体(request)参数1.3.2 模型推理 2. 先决条件2.1 环境配置2.2 所需零件 3. 核心代码3.1 源码分享3.2 源码解析3.3 连续对话修改后的代码代码说明示例输出注…...

Vue 2 路由指南:从基础到高级

注意&#xff1a;对于代码看不清的部分&#xff0c;用鼠标选中就能看到了&#xff0c;背景颜色和字体颜色过于接近&#xff0c;我也不知道怎么调&#xff0c;只能这样子先看着了 一、Vue Router 是什么&#xff1f; Vue Router 是 Vue.js 官方的路由管理器&#xff0c;它允许…...

2025最新深度学习pytorch完整配置:conda/jupyter/vscode

从今天开始&#xff0c;开始一个新的专栏&#xff0c;更新深度学习相关的内容&#xff0c;从入门到精通&#xff0c;首先的首先是关于环境的配置指南&#xff1a;工欲善其事必先利其器&#xff01; PyTorch 是由 Facebook&#xff08;现 Meta&#xff09;开发的 开源深度学习框…...

Python教学-最常用的标准库之一——OS库

os 库是 Python 标准库中的一个模块&#xff0c;它提供了一种方便的方式来使用操作系统相关的功能。os 模块提供了很多函数&#xff0c;可以用来处理文件和目录、访问环境变量、执行系统命令等。以下是一些常用的 os 模块的功能和示例&#xff1a; 1. 文件和目录操作 1.1 当前…...

尚硅谷爬虫note006

一、ajax的get请求 1. ajax的get请求—豆瓣电影第一页 # _*_ coding : utf-8 _*_ # Time : 2025/2/13 15:14 # Author : 20250206-里奥 # File : demo23_ajax的get请求 # Project : PythonProject10-14import urllib.requestfrom demo17_qingqiuduixaingdedingzhi import hea…...

LeetCode刷题---字符串---859

亲密字符串 859. 亲密字符串 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给你两个字符串 s 和 goal &#xff0c;只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果&#xff0c;就返回 true &#xff1b;否则返回 false 。 交换字母的定义是&…...

探索大数据处理:利用 Apache Spark 解锁数据价值

探索大数据处理&#xff1a;利用 Apache Spark 解锁数据价值 大家好&#xff0c;我是你们熟悉的大数据领域自媒体创作者Echo_Wish。今天&#xff0c;我们来聊聊如何利用Apache Spark进行大规模数据处理。Apache Spark作为一个快速、通用的集群计算框架&#xff0c;以其出色的性…...

伯克利 CS61A 课堂笔记 08 —— Strings and Dictionaries

本系列为加州伯克利大学著名 Python 基础课程 CS61A 的课堂笔记整理&#xff0c;全英文内容&#xff0c;文末附词汇解释。 目录 01 Strings 字符串 Ⅰ Strings are An Abstraction. Ⅱ Strings Literals have Three Forms Ⅲ String are Sequences 02 Dictionaries 字典 …...

V93K测试机

爱德万V9300&#xff08;又称V93K&#xff09;是Advantest公司推出的高端可扩展SoC测试平台&#xff0c;在半导体测试领域具有标杆地位。以下为该设备的详细介绍&#xff1a; ### 一、核心性能与技术优势 1. **高速高精度测试能力** V9300支持高达112 Gbps PAM4信号&…...

在 CentOS 上更改 SSH 默认端口以提升服务器安全性

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 欢迎点赞 &#x1f44d; 收藏 ⭐评论 …...

基于逻辑概率的语义信道容量(Semantic Channel Capacity)和语义压缩理论(Semantic Compression Theory)

基于逻辑概率的语义信道容量&#xff08;Semantic Channel Capacity&#xff09;和语义压缩理论&#xff08;Semantic Compression Theory&#xff09;是语义通信&#xff08;Semantic Communication, SemCom&#xff09;的核心研究方向&#xff0c;它们旨在优化通信效率&#…...

Golang GORM系列:GORM事务及错误处理

在数据库管理领域&#xff0c;确保数据完整性至关重要。GORM是健壮的Go对象关系映射库&#xff0c;它为开发人员提供了维护数据一致性和优雅地处理错误的基本工具。本文是掌握GORM事务和错误处理的全面指南。我们将深入研究如何使用事务来保证原子性&#xff0c;并探索有效处理…...

51单片机-C语言扩展及最小系统

1、C-51的数据类型扩充定义 sfr&#xff1a;特殊功能寄存器声明 sfr&#xff1a;变量名地址值&#xff1b; 特殊功能寄存器在reg51.H这个头文件里面都帮我们定义好了&#xff0c;所以平时我们就不要自己去定义寄存器的名字。 sbit&#xff1a;特殊功能位声明sbit 变量名地址…...

日常问题-pnpm install执行没有node_modules生成

日常问题-pnpm install执行没有node_modules生成 1.问题2.解决方法 1.问题 执行pnpm i后&#xff0c;提示Scope: all 3 workspace projects Done in 503ms&#xff0c;而且没有node_modules生成。很奇怪 2.解决方法 确保根目录有 pnpm-workspace.yaml 文件&#xff1a; 把这…...

FreeRTOS低功耗总结

前言 Cortex-M核的MCU一般支持以下三种低功耗方式&#xff1a; ● 睡眠(Sleep)模式 ● 停止(Stop)模式 ● 待机(Standby)模式 睡眠模式 进入睡眠模式有两种指令&#xff1a;WFI(等待中断)和WFE(等待事件)&#xff0c; WFI进入睡眠模式后&#xff0c;任意中断都可唤醒。 WFE进…...

UniApp 实现炫酷导航栏:选中图标上移并隐藏文字

在移动应用开发中&#xff0c;导航栏是用户与应用交互的重要组成部分&#xff0c;一个美观且交互性强的导航栏能大大提升用户体验。本文将详细介绍如何使用 UniApp 实现一个独特的导航栏&#xff0c;当用户选中某个导航项时&#xff0c;对应的图标会上移并隐藏文字&#xff0c;…...

Django 操作表中的数据(增删改查)

1.新建数据 我之前已经在数据库中创建了两张表&#xff0c;如下 在urls.py文件中添加一行代码&#xff0c;然后再在views.py文件中编写函数 &#xff08;将 URL 路径 orm/ 映射到 Django 视图函数 views.orm&#xff0c;当用户访问 orm/ 时&#xff0c;Django 会调用 orm 视图…...

优选驾考小程序

第2章 系统分析 2.1系统使用相关技术分析 2.1.1Java语言介绍 Java语言是一种分布式的简单的 开发语言&#xff0c;有很好的特征&#xff0c;在安全方面、性能方面等。非常适合在Internet环境中使用&#xff0c;也是目前企业级运用中最常用的一个编程语言&#xff0c;具有很大…...

vue开发06:前端通过webpack配置代理处理跨域问题

1.定义 在浏览器尝试请求不同源&#xff08;域名、协议、端口号不同&#xff09;的资源时&#xff0c;浏览器的同源策略会阻止这种跨域请求。&#xff08;比如前端端口15500&#xff0c;后端端口5050&#xff0c;前端界面不可以直接调用5050端口&#xff09; 2.解决方案 使用前…...

C++基础 | 线程`std::thread`

什么是std::thread&#xff1f; std::thread是C11中引入的一个类&#xff0c;用于表示和管理线程。通过std::thread&#xff0c;我们可以创建一个新的线程来执行指定的任务。线程是操作系统调度的基本单位&#xff0c;多个线程可以并发执行&#xff0c;从而提高程序的效率。 创…...

体验 DeepSeek-R1:解密 1.5B、7B、8B 版本的强大性能与应用

文章目录 &#x1f34b;引言&#x1f34b;DeepSeek 模型简介&#x1f34b;版本更新&#xff1a;1.5B、7B、8B 的区别与特点&#x1f34b;模型评估&#x1f34b;体验 DeepSeek 的过程&#x1f34b;总结 &#x1f34b;引言 随着大规模语言模型的持续发展&#xff0c;许多模型在性…...

2024年认证杯SPSSPRO杯数学建模A题(第二阶段)保暖纤维的保暖能力全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 A题 保暖纤维的保暖能力 原题再现&#xff1a; 冬装最重要的作用是保暖&#xff0c;也就是阻挡温暖的人体与寒冷环境之间的热量传递。人们在不同款式的棉衣中会填充保暖材料&#xff0c;从古已有之的棉花、羽绒到近年来各种各样的人造纤维。不…...

P1878 舞蹈课(详解)c++

题目链接&#xff1a;P1878 舞蹈课 - 洛谷 | 计算机科学教育新生态 1.题目解析 1&#xff1a;我们可以发现任意两个相邻的都是异性&#xff0c;所以他们的舞蹈技术差值我们都要考虑&#xff0c;4和2的差值是2&#xff0c;2和4的差值是2&#xff0c;4和3的差值是1&#xff0c;根…...

或非门组成的SR锁存器真值表相关问题

PS&#xff1a;主要是给大家抛砖引玉&#xff0c;不喜勿喷。 问题描述&#xff1a;或非门组成的SR锁存器&#xff0c;为什么当SD和RD等于0时候的真值表一个是Q0&#xff0c;Q0.一个结果是Q1&#xff0c;Q1&#xff1f;...

机器学习算法 - 随机森林之决策树初探(1)

随机森林是基于集体智慧的一个机器学习算法&#xff0c;也是目前最好的机器学习算法之一。 随机森林实际是一堆决策树的组合&#xff08;正如其名&#xff0c;树多了就是森林了&#xff09;。在用于分类一个新变量时&#xff0c;相关的检测数据提交给构建好的每个分类树。每个…...

webpack构建流程

文章目录 [TOC](文章目录) 运行流程初始化流程编译构建流程compile编译make 编译模块build module 完成模块编译 输出流程seal输出资源emit输出完成 小结 运行流程 是一个串行的过程&#xff0c;它的工作流程就是将各个插件串联起来 在运行过程中会广播事件&#xff0c;插件只…...

服务器之连接简介(Detailed Explanation of Server Connection)

一台服务器最大能支持多少连接&#xff1f;一台客户端机器最多能发起多少条连接&#xff1f;&#xff1f; 我们知道TCP连接&#xff0c;从根本上看其实就是client和server端在内存中维护的一组【socket内核对象】&#xff08;这里也对应着TCP四元组&#xff1a;源IP、源端口、…...

第1章大型互联网公司的基础架构——1.5 服务发现

讲到这里&#xff0c;我们已经对一个客户端请求进入业务HTTP服务的过程有了较为详细的了解。业务HTTP服务在处理请求的过程中免不了与其他下游服务通信——可能会调用其他业务服务&#xff0c;可能需要访问数据库&#xff0c;可能会向消息中间件投递消息等&#xff0c;所以业务…...

uniapp PDF 预览和下载

创建 index.vue <template><view><view class"box"><view class"item" ><view class"title"><span></span><text>文件</text></view><view class"list" v-for"(…...

ubuntu服务器部署

关闭欢迎消息 服务器安装好 ubuntu 系统后&#xff0c;进行终端登录&#xff0c;会显示出很多的欢迎消息 通过在用户的根目录下执行 touch .hushlogin 命令&#xff0c;再次登录终端就不会出现欢迎消息 修改hostname显示 修改 /etc/hostname 文件内容为主机名&#xff0c;保…...

Deepseek 本地部署

准备环境 设备&#xff1a;家用笔记本电脑&#xff0c;8核/16G/1Tb SSD/无独显 系统&#xff1a;windows10 软件环境&#xff08;非源码部署不需要&#xff09;&#xff1a;conda 4.8.5、python3.7、git2.13 步骤 下载安装Ollama 下载地址&#xff1a;OllamaGet up and r…...