【Java實戰?】深入Java單元測試:JUnit 5實戰指南

目錄

  • 一、單元測試概述
    • 1.1 單元測試概念
    • 1.2 單元測試優勢
    • 1.3 JUnit 5 框架組成
    • 1.4 JUnit 5 環境搭建
  • 二、JUnit 5 核心功能實戰
    • 2.1 測試類與測試方法
    • 2.2 測試生命周期
    • 2.3 斷言方法
    • 2.4 異常測試
  • 三、單元測試進階實戰
    • 3.1 參數化測試
    • 3.2 測試套件
    • 3.3 Mockito 框架
    • 3.4 單元測試實戰案例


一、單元測試概述

1.1 單元測試概念

單元測試是軟件開發過程中至關重要的一環,它專注于對軟件中最小的可測試單元進行驗證。在 Java 中,這些最小單元通常指的是方法或函數。通過精心設計針對這些單元的測試用例,我們能夠深入檢查每個單元的功能是否符合預期。

比如,在一個簡單的數學計算類中,有一個用于兩數相加的方法add(int a, int b)。單元測試就會針對這個方法編寫多個測試用例,包括正常的相加情況,如add(2, 3)是否返回5;也會考慮邊界情況,如add(0, 0)的結果,以及特殊情況,如傳入最大整數相加是否會溢出等。通過這樣細致的測試,確保add方法在各種情況下都能正確工作,為整個軟件系統的穩定性奠定基礎。

1.2 單元測試優勢

  • 提前發現 bug:在開發過程中,越早發現問題,修復成本就越低。單元測試由開發人員在代碼編寫階段執行,能夠及時捕捉到代碼中的邏輯錯誤、邊界條件處理不當等問題,避免這些問題在后續集成測試、系統測試甚至生產環境中才被發現,從而節省大量的時間和精力。
  • 便于重構:隨著項目的演進,代碼需要不斷重構以提高可維護性和擴展性。有了完善的單元測試,開發人員在重構代碼時可以更加放心,因為只要單元測試全部通過,就可以基本保證重構后的代碼功能沒有改變。例如,當對一個復雜算法進行優化時,運行單元測試可以快速驗證優化后的代碼是否依然正確。
  • 提升代碼質量:編寫單元測試的過程促使開發人員更加深入地思考代碼的功能和邏輯,從而編寫出更健壯、更清晰的代碼。同時,單元測試也可以作為一種文檔,記錄代碼的預期行為和使用方式,方便后續維護和理解。

1.3 JUnit 5 框架組成

  • JUnit Jupiter:它是 JUnit 5 的核心模塊,提供了全新的編程模型和擴展模型。在編程模型方面,它引入了一系列新的注解,如@Test、@BeforeEach、@AfterEach等,讓編寫測試代碼更加簡潔和靈活。在擴展模型上,允許開發者創建自定義的測試擴展,以滿足特定的測試需求。
  • JUnit Vintage:主要用于兼容舊版本的 JUnit 測試,即 JUnit 3 和 JUnit 4 的測試用例。在項目從舊版本的 JUnit 遷移到 JUnit 5 時,這個模塊可以確保舊的測試用例依然能夠正常運行,為項目的平穩過渡提供保障。
  • JUnit Platform:作為整個 JUnit 5 測試框架的基礎,它為在 JVM 上啟動測試框架提供了必要的支持,定義了 TestEngine API,用于開發在平臺上運行的測試引擎,使得 JUnit 5 能夠與各種 IDE 和構建工具集成,方便開發者使用。

1.4 JUnit 5 環境搭建

以 Maven 項目為例,在pom.xml文件中添加 JUnit 5 依賴:

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

如果需要兼容 JUnit 4 的測試,還需添加:

<dependency><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId><version>5.10.0</version><scope>test</scope>
</dependency>

在 IDE 中的配置步驟如下:

  • IntelliJ IDEA:新建項目時,若選擇 Maven 項目,在創建過程中可直接在pom.xml添加上述依賴,IDEA 會自動下載相關庫。若項目已創建,打開pom.xml添加依賴后,點擊右上角的Maven圖標,選擇Reload All Maven Projects即可。創建測試類時,在src/test/java目錄下新建類,無需額外配置即可使用 JUnit 5 進行測試。
  • Eclipse:新建 Java 項目后,右鍵點擊項目,選擇Properties,在彈出的窗口中選擇Java Build Path,切換到Libraries標簽,點擊Add Library,選擇JUnit,然后選擇JUnit 5,點擊Finish。之后在src/test/java目錄下創建測試類即可使用 JUnit 5。

二、JUnit 5 核心功能實戰

2.1 測試類與測試方法

在 JUnit 5 中,使用@Test注解來標記一個方法為測試方法。例如:

import org.junit.jupiter.api.Test;public class CalculatorTest {@Testpublic void testAdd() {// 測試邏輯}
}

@DisplayName注解則可以為測試類或測試方法自定義顯示名稱,使測試報告更加易讀。例如:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;@DisplayName("計算器測試類")
public class CalculatorTest {@Test@DisplayName("加法測試方法")public void testAdd() {// 測試邏輯}
}

2.2 測試生命周期

  • @BeforeEach:標注在方法上,在每一個測試方法(使用@Test、@RepeatedTest、@ParameterizedTest或@TestFactory注解的方法)執行之前都會執行該方法。常用于初始化測試所需的資源,如創建對象實例、建立數據庫連接等。例如:
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;public class UserServiceTest {private UserService userService;@BeforeEachpublic void setUp() {userService = new UserService();}@Testpublic void testAddUser() {// 測試添加用戶的邏輯}
}
  • @AfterEach:標注在方法上,在每一個測試方法執行之后都會執行該方法。主要用于清理測試過程中產生的資源,如關閉數據庫連接、刪除臨時文件等。例如:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;public class UserServiceTest {private UserService userService;@BeforeEachpublic void setUp() {userService = new UserService();}@Testpublic void testAddUser() {// 測試添加用戶的邏輯}@AfterEachpublic void tearDown() {// 清理資源的邏輯}
}
  • @BeforeAll:標注在靜態方法上,在當前測試類中所有的測試方法執行之前執行一次。適用于初始化一些在整個測試類中都需要共享的資源,如加載配置文件、初始化數據庫連接池等。例如:
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;public class DatabaseTest {private static DatabaseConnection connection;@BeforeAllpublic static void setUp() {connection = DatabaseConnection.getConnection();}@Testpublic void testQuery() {// 測試數據庫查詢的邏輯}
}
  • @AfterAll:標注在靜態方法上,在當前測試類中所有的測試方法執行完畢之后執行一次。用于釋放那些在@BeforeAll中初始化的共享資源,如關閉數據庫連接池、釋放文件鎖等。例如:
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;public class DatabaseTest {private static DatabaseConnection connection;@BeforeAllpublic static void setUp() {connection = DatabaseConnection.getConnection();}@Testpublic void testQuery() {// 測試數據庫查詢的邏輯}@AfterAllpublic static void tearDown() {connection.close();}
}

2.3 斷言方法

斷言方法是 JUnit 5 中用于驗證測試結果是否符合預期的關鍵工具。常用的斷言方法有:

  • assertEquals:用于驗證兩個值是否相等。例如:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;public class MathUtilsTest {@Testpublic void testAdd() {int result = MathUtils.add(2, 3);assertEquals(5, result);}
}
  • assertTrue:用于驗證某個條件是否為真。例如:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;public class StringUtilsTest {@Testpublic void testIsEmpty() {assertTrue(StringUtils.isEmpty(""));}
}
  • assertNotNull:用于驗證某個對象是否不為空。例如:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;public class UserServiceTest {@Testpublic void testGetUserById() {User user = userService.getUserById(1);assertNotNull(user);}
}

2.4 異常測試

在測試過程中,常常需要驗證某些代碼在特定情況下是否會拋出預期的異常。JUnit 5 提供了兩種主要的方式來進行異常測試:

  • @Test (expected = 異常類.class):在 JUnit 4 中就已存在,在 JUnit 5 中仍然可用。通過在@Test注解中使用expected屬性指定預期拋出的異常類型。例如:
import org.junit.jupiter.api.Test;public class MathUtilsTest {@Test(expected = ArithmeticException.class)public void testDivideByZero() {MathUtils.divide(10, 0);}
}
  • assertThrows:JUnit 5 中新增的方式,通過assertThrows方法來驗證代碼塊是否拋出預期的異常,并可以進一步對異常的屬性進行驗證。例如:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;public class MathUtilsTest {@Testpublic void testDivideByZero() {ArithmeticException exception = assertThrows(ArithmeticException.class,() -> MathUtils.divide(10, 0));assertEquals("/ by zero", exception.getMessage());}
}

這種方式不僅能驗證異常是否拋出,還能獲取異常對象,從而對異常的詳細信息(如錯誤消息、堆棧跟蹤等)進行斷言驗證。

三、單元測試進階實戰

3.1 參數化測試

在 JUnit 5 中,參數化測試是一項非常實用的功能,它允許我們使用不同的參數多次運行同一個測試方法,從而覆蓋更多的測試場景。通過@ParameterizedTest注解結合@ValueSource、@MethodSource等注解來實現。

比如,我們有一個用于判斷數字是否為偶數的方法isEven(int num),可以編寫如下參數化測試:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;public class MathUtilsTest {@ParameterizedTest@ValueSource(ints = {2, 4, 6, 8})public void testIsEven(int num) {assertTrue(MathUtils.isEven(num));}@ParameterizedTest@ValueSource(ints = {1, 3, 5, 7})public void testIsNotEven(int num) {assertFalse(MathUtils.isEven(num));}
}

在上述代碼中,@ParameterizedTest注解表明這是一個參數化測試方法。@ValueSource(ints = {2, 4, 6, 8})提供了一組測試數據,testIsEven方法會針對這組數據中的每一個值執行一次,驗證isEven方法在這些偶數輸入下的正確性。同理,testIsNotEven方法針對奇數數據進行測試。

如果需要更復雜的參數設置,可以使用@MethodSource注解。例如:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;public class MathUtilsTest {static Stream<Integer> evenNumbersProvider() {return Stream.of(2, 4, 6, 8);}@ParameterizedTest@MethodSource("evenNumbersProvider")public void testIsEven(int num) {assertTrue(MathUtils.isEven(num));}
}

這里通過evenNumbersProvider方法返回一個包含偶數的Stream,@MethodSource(“evenNumbersProvider”)指定該方法作為參數數據源,testIsEven方法會根據這個數據源中的數據依次執行測試。

3.2 測試套件

在實際項目中,通常會有多個測試類。使用測試套件可以將多個相關的測試類組織在一起,方便批量執行。在 JUnit 5 中,使用@Suite注解來創建測試套件。

假設我們有兩個測試類CalculatorTest和MathUtilsTest,可以創建一個測試套件類AllTestsSuite:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.runner.RunWith;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;@RunWith(JUnitPlatform.class)
@Suite
@SelectClasses({CalculatorTest.class, MathUtilsTest.class})
public class AllTestsSuite {// 測試套件類不需要任何方法,僅用于組織測試類
}

在上述代碼中,@RunWith(JUnitPlatform.class)指定使用 JUnit Platform 運行測試,@Suite注解表明這是一個測試套件,@SelectClasses注解指定要包含在測試套件中的測試類。運行AllTestsSuite時,JUnit 會依次執行CalculatorTest和MathUtilsTest中的所有測試方法,大大提高了測試效率,尤其適用于集成測試或回歸測試場景。

3.3 Mockito 框架

在單元測試中,被測對象往往依賴其他對象。這些依賴對象可能是數據庫連接、網絡服務調用等,直接使用真實的依賴對象進行測試會帶來很多問題,比如測試環境依賴、測試速度慢等。Mockito 框架就是為了解決這些問題而誕生的,它可以模擬依賴對象的行為,實現隔離測試。

以一個用戶服務類UserService依賴用戶倉庫類UserRepository為例:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;@ExtendWith(MockitoExtension.class)
public class UserServiceTest {@Mockprivate UserRepository userRepository;@Testpublic void testGetUserById() {// 模擬userRepository.findById(1L)的返回值User mockUser = new User(1L, "張三", "zhangsan@example.com");when(userRepository.findById(1L)).thenReturn(mockUser);UserService userService = new UserService(userRepository);User user = userService.getUserById(1L);assertEquals(mockUser, user);}
}

在上述代碼中,首先通過@Mock注解創建了UserRepository的模擬對象userRepository。在testGetUserById方法中,使用when(userRepository.findById(1L)).thenReturn(mockUser)模擬了userRepository.findById(1L)方法的行為,使其返回一個預設的模擬用戶對象mockUser。然后創建UserService對象并調用getUserById方法,最后斷言返回的用戶對象與模擬用戶對象一致。這樣就實現了對UserService的隔離測試,不受UserRepository實際實現的影響,提高了測試的獨立性和可重復性。

3.4 單元測試實戰案例

下面以一個UserService層的方法測試為例,綜合展示 JUnit 5 的各種功能和技術的使用。假設UserService有一個注冊用戶的方法registerUser(User user),該方法依賴UserRepository來保存用戶信息,并且需要對用戶輸入進行一些驗證。

首先,創建UserService和UserRepository接口及實現類:

// UserRepository接口
public interface UserRepository {User save(User user);
}// UserRepository實現類
public class UserRepositoryImpl implements UserRepository {@Overridepublic User save(User user) {// 實際保存用戶到數據庫的邏輯,這里簡化為直接返回用戶對象return user;}
}// UserService接口
public interface UserService {boolean registerUser(User user);
}// UserService實現類
public class UserServiceImpl implements UserService {private final UserRepository userRepository;public UserServiceImpl(UserRepository userRepository) {this.userRepository = userRepository;}@Overridepublic boolean registerUser(User user) {if (user == null || user.getUsername() == null || user.getPassword() == null) {return false;}// 簡單的用戶名長度驗證if (user.getUsername().length() < 3) {return false;}User savedUser = userRepository.save(user);return savedUser != null;}
}

然后,編寫UserService的單元測試類:

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;@DisplayName("用戶服務測試")
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {@Mockprivate UserRepository userRepository;private UserService userService;@BeforeEachpublic void setUp() {userService = new UserServiceImpl(userRepository);}@Test@DisplayName("正常注冊用戶測試")public void testRegisterUserSuccess() {User user = new User("testUser", "testPassword", "test@example.com");when(userRepository.save(user)).thenReturn(user);boolean result = userService.registerUser(user);assertTrue(result);}@Test@DisplayName("注冊用戶為空測試")public void testRegisterUserWithNullUser() {boolean result = userService.registerUser(null);assertFalse(result);}@Test@DisplayName("注冊用戶用戶名過短測試")public void testRegisterUserWithShortUsername() {User user = new User("ab", "testPassword", "test@example.com");boolean result = userService.registerUser(user);assertFalse(result);}@Test@DisplayName("注冊用戶保存失敗測試")public void testRegisterUserSaveFailure() {User user = new User("testUser", "testPassword", "test@example.com");when(userRepository.save(user)).thenReturn(null);boolean result = userService.registerUser(user);assertFalse(result);}
}

在這個測試類中:

  • 使用@DisplayName為測試類添加了有意義的顯示名稱。
  • 通過@Mock創建了UserRepository的模擬對象,并在@BeforeEach方法中創建UserService對象,將模擬的UserRepository注入其中。
  • 編寫了四個測試方法,分別測試正常注冊用戶、注冊用戶為空、注冊用戶用戶名過短以及注冊用戶保存失敗的情況。每個測試方法都使用了斷言來驗證方法的返回結果是否符合預期,同時利用 Mockito 框架模擬了UserRepository的save方法的不同行為,以覆蓋各種可能的測試場景,確保UserService的registerUser方法在各種情況下都能正確工作。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/96199.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96199.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96199.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

分布式微服務--ZooKeeper作為分布式鎖

看這篇博客之前可以先去了解博主的另一篇講解ZooKeeper的博客&#xff1a;分布式微服務--ZooKeeper的客戶端常用命令 & Java API 操作-CSDN博客 1. 為什么需要分布式鎖&#xff1f; 在分布式系統中&#xff0c;多個服務節點可能同時訪問或修改同一份共享資源&#xff08;例…

基于容器化云原生的 MySQL 及中間件高可用自動化集群項目

1 項目概述 本項目旨在構建一個高可用、高性能的 MySQL 集群,能夠處理大規模并發業務。通過容器化部署、多級緩存、完善的監控和備份策略,確保數據庫服務的連續性和數據安全性。 架構總覽 預期目標 數據庫服務可用性達到 99.99% 支持每秒 thousands 級別的并發訪問 實現秒…

如何將 iPhone 備份到電腦/PC 的前 5 種方法

定期備份你的 iPhone&#xff08;最好每兩周一次&#xff09;對于保護你的數據至關重要。它確保了如果設備損壞、丟失或被盜&#xff0c;或者你換了新手機&#xff0c;你不會丟失重要信息&#xff0c;并且可以輕松地從備份中恢復應用程序、照片、設置等。如果你不確定如何備份 …

國產AI芯片編程模型深度對比:寒武紀MLU vs 壁仞BR100異構計算設計

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 引言&#xff1a;國產AI芯片的崛起與挑戰 隨著人工智能技術的飛速…

【項目】基于One Thread One Loop模型的高性能網絡庫實現 - 項目介紹與前置知識

目錄 項目介紹 HTTP服務器基本認識 Reactor模式基本認識 單Reactor單線程模式認識 單Reactor多線程模式認識 多Reactor多線程模式認識 模塊劃分 Server模塊 Buffer模塊 Socket模塊 Channel模塊 Connection模塊 Acceptor模塊 TimerQueue模塊 Poller模塊 EventLo…

lua中table鍵類型及lua中table的初始化有幾種方式

在 Lua 中&#xff0c;table 的鍵幾乎可以是任何類型&#xff0c;但有幾個重要的規則和最佳實踐需要了解。1. 主要鍵類型(1) 字符串 (string)這是最常見、最推薦的鍵類型。local person {name "Alice", -- 等同于 ["name"] "Alice"["age…

matlab實現利用雙MZI產生RZ33-QPSK信號

利用MATLAB實現雙MZI產生RZ33-QPSK信號的代碼&#xff1a; 參數設置 % 信號參數 fs 1e6; % 采樣頻率 fc 10e6; % 載波頻率 T 1e-6; % 符號周期 N 1000; % 采樣點數 t 0:1/fs:(N-1)/fs; % 時間向量生成QPSK信號 % 生成隨機二進制序列 data randi([0,1],1,N);% 將二進制序列…

Vue響應式更新 vs React狀態更新:兩種范式的底層邏輯與實踐差異

在現代前端框架中&#xff0c;Vue和React作為兩大主流選擇&#xff0c;分別采用了截然不同的狀態管理與更新機制。Vue的“響應式更新”通過自動追蹤依賴實現數據與視圖的聯動&#xff0c;而React的“狀態更新”則依賴顯式setState觸發重新渲染。本文將從底層原理、更新流程、優…

Spring MVC 的常用注解

一、控制器相關注解ControllerController注解用于標記一個類為 Spring MVC 的控制器。在 Spring MVC 框架里&#xff0c;控制器扮演著關鍵角色&#xff0c;負責接收 HTTP 請求并返回響應。當一個類被Controller注解標記后&#xff0c;Spring 容器會自動識別并將其納入管理。例如…

Oracle APEX 利用卡片實現翻轉(方法一)

目錄 0. 以 Oracle 的標準示例表 EMP 為例&#xff0c;實現卡片翻轉 1. 創建PL/SQL動態內容區域 2. 添加 CSS 實現翻轉效果 3. 添加動態操作 (Dynamic Action) 4. 看效果 0. 以 Oracle 的標準示例表 EMP 為例&#xff0c;實現卡片翻轉 正面&#xff1a; 顯示員工姓名 (EN…

Gradio全解11——Streaming:流式傳輸的視頻應用(1)——FastRTC:Python實時通信庫

Gradio全解11——Streaming&#xff1a;流式傳輸的視頻應用&#xff08;1&#xff09;——FastRTC&#xff1a;Python實時通信庫前言第11章 Streaming&#xff1a;流式傳輸的視頻應用11.1 FastRTC&#xff1a;Python實時通信庫11.1.1 WebRTC協議與FastRTC介紹1. WebRTC協議的概…

一文學會二叉搜索樹,AVL樹,紅黑樹

文章目錄二叉搜索樹查找插入刪除AVL樹概念插入旋轉AVL驗證紅黑樹概念插入檢測二叉搜索樹 也稱二叉排序樹或二叉查找樹 二叉搜索樹&#xff1a;可以為空&#xff0c;若不為空滿足以下性質 ?1&#xff0c;非空左子樹小于根節點的值 ?2&#xff0c;非空右子大于根節點的值 ?3…

Android實戰進階 - 啟動頁

場景&#xff1a;當啟動頁處于倒計時階段&#xff0c;用戶將其切換為后臺的多任務卡片狀態&#xff0c;倒計時會繼續執行&#xff0c;直到最后執行相關邏輯&#xff08;一般會跳轉引導頁、進入主頁等&#xff09; 期望&#xff1a;而綜合市場來看&#xff0c;一般我們期望的是當…

無標記點動捕技術:重塑展廳展館的沉浸式數字交互新時代

在元宇宙浪潮的持續推進下&#xff0c;虛擬數字人正逐漸成為連接虛實世界的重要媒介。在展廳展館中&#xff0c;數字人不僅能夠扮演導覽員、講解員角色&#xff0c;更可通過情感化交互提升參觀體驗&#xff0c;使文化傳播更具感染力和沉浸感。虛擬人的引入&#xff0c;為傳統展…

輕松Linux-7.Ext系列文件系統

天朗氣清&#xff0c;惠風和煦&#xff0c;今日無事&#xff0c;遂來更新。 1.概述 總所周知&#xff0c;我們存的數據都是在一個叫硬盤的東西里面&#xff0c;這個硬盤又像個黑盒&#xff0c;這章就來簡單解析一下Linux中文件系統。 現在我們用的大都是固態硬盤&#xff0c;…

Matlab機器人工具箱使用4 蒙特卡洛法繪制工作區間

原理&#xff1a;利用rand隨機數&#xff0c;給各個關節設置隨機關節變量&#xff0c;通過正運動學得到末端位姿變換矩陣&#xff0c;然后利用變換矩陣2三維坐標標記出末端坐標&#xff0c;迭代多次就可以構成點云。教程視頻&#xff1a;【MATLAB機器人工具箱10.4 機械臂仿真教…

【項目】在AUTODL上使用langchain實現《紅樓夢》知識圖譜和RAG混合檢索(三)知識圖譜和路由部分

首先在數據集 - 開放知識圖譜下載紅樓夢的知識圖譜&#xff0c;這個網站上有各種各樣的知識圖譜&#xff0c;可以挑你感興趣的做( ? ?ω?? ) 這個知識圖譜的作者們已經將三元組抽取出來了&#xff0c;我們可以直接用&#xff0c;如果你對三元組是如何生成的感興趣&#xf…

pycharm 最新版上一次編輯位置

2025nipycharm方法一&#xff1a;用快捷鍵&#xff08;最方便&#xff09;跳回上一次編輯位置&#xff1a;Windows/Linux: Ctrl Alt ←macOS: ? Option ←跳到前一次位置&#xff1a;Windows/Linux: Ctrl Alt →macOS: ? Option →方法二&#xff1a;顯示工具欄按鈕在…

前端性能監控與優化:從 Lighthouse 到 APM

在當今競爭激烈的數字環境中&#xff0c;用戶對Web應用性能的要求日益提高。一個緩慢或響應遲鈍的應用不僅會流失用戶&#xff0c;更可能損害品牌形象和商業價值。因此&#xff0c;前端性能的監控與優化已成為前端開發不可或缺的關鍵環節。本文將深入探討從基礎的性能評估工具L…

TC_Motion多軸運動-電子齒輪

目錄 電子齒輪 【基本概念】 【應用示例】 【開發總結】 END 電子齒輪 【基本概念】 定義:通過軟件方法實現機械齒輪的速比調節功能(兩個軸成線性比例旋轉) 優點 免維護,告別機械損耗 易調節,任意修改齒輪比 精度高,無機械背隙 應用場景 多臺電機拖動同一負載,要求多臺…