揭秘字符串的奧秘:探索String類的深層含義與源碼解讀

文章目錄

    • 一、導論
      • 1.1 引言:字符串在編程中的重要性
      • 1.2 目的:深入了解String類的內部機制
    • 二、String類的設計哲學
      • 2.1 設計原則:為什么String類如此重要?
      • 2.2 字符串池的概念與作用
    • 三、String類源碼解析
      • 3.1 成員變量
      • 3.2 構造函數
      • 3.3 equals(): 判斷兩個對象是否相等
      • 3.4 charAt(): 獲取指定位置的字符
      • 3.5 length(): 獲取字符串長度
      • 3.6 concat(): 字符串連接
      • 3.7 substring(): 子串提取
      • 3.8 compareTo (): 字符串長度相等的比較
      • 3.9 hashCode():重寫hashCode
      • 3.10 replace ():新值替換舊值
      • 3.11 trim():去除空格
      • 3.12 startsWith():前綴+后綴
    • 四、String類的內部實現機制
      • 4.1 字符串的存儲方式:常量池、堆、棧
      • 4.2 字符串不可變性的實現細節
    • 五、性能優化與字符串操作技巧
      • 5.1 使用StringBuilder和StringBuffer提高字符串拼接效率
      • 5.2 字符串比較的最佳實踐
    • 六、案例分析與實例演示
      • 6.1 實際代碼示例:如何更好地使用String類
      • 6.2 常見陷阱與解決方案

一、導論

1.1 引言:字符串在編程中的重要性

字符串在編程中非常重要,因為它們是處理文本數據的基本單位。在幾乎所有編程語言中,都有專門的字符串類型和相關的操作方法,這些方法使得處理文本變得更加方便和靈活。

字符串在編程中的重要性

  1. 文本處理: 字符串用于存儲和處理文本數據。無論是讀取文件、用戶輸入還是與外部系統通信,都需要使用字符串。
  2. 數據表示: 許多數據格式,如JSON、XML和HTML,都使用字符串來表示結構化的數據。在這些情況下,字符串是將數據進行序列化和反序列化的基礎。
  3. 用戶界面: 用戶界面中的文本標簽、按鈕標簽等通常都是字符串。程序需要能夠操作和顯示這些字符串以與用戶進行交互。
  4. 搜索和匹配: 字符串操作是執行搜索、替換和匹配操作的基礎。正則表達式是一種強大的工具,用于在字符串中進行復雜的模式匹配。
  5. 密碼學和安全性: 字符串在密碼學中的使用非常廣泛。加密和哈希算法通常對字符串進行操作,以確保數據的安全性。
  6. 網絡通信: 在網絡通信中,數據通常以字符串的形式傳輸。這包括HTTP請求和響應、數據庫查詢和響應等。
  7. 程序邏輯: 在編程中,字符串也常常用于表示程序中的命令、條件和邏輯結構。例如,條件語句中的比較操作就涉及到字符串的比較。

總體而言,字符串在編程中是一個不可或缺的組成部分,廣泛用于處理和表示各種類型的文本數據。

1.2 目的:深入了解String類的內部機制

在Java中,String類是不可變的,這意味著一旦字符串對象被創建,它的內容就不能被修改。

String類內部機制的重要信息:

  1. 不可變性(Immutability): String類的不可變性是通過將字符數組(char數組)聲明為final并使用private final char value[]來實現的。這意味著一旦字符串被創建,它的內容不能被更改。
  2. 字符串池(String Pool): Java中的字符串池是一種特殊的存儲區域,用于存儲字符串常量。當你創建一個字符串時,JVM首先檢查字符串池是否已經存在相同內容的字符串,如果存在則返回池中的引用,否則創建一個新的字符串對象并放入池中。
  3. 常量池(Constant Pool): 字符串池實際上是常量池的一部分,其中存儲了類、方法和接口中的常量數據。字符串常量池屬于這個常量池。
  4. StringBuilder和StringBuffer: 在Java中,如果需要對字符串進行頻繁的修改,建議使用StringBuilder(非線程安全)或StringBuffer(線程安全)而不是String。這是因為StringBuilderStringBuffer類提供了可變的字符串,避免了每次修改都創建新的字符串對象的開銷。
  5. 字符串連接: 字符串連接使用+運算符時,實際上是創建了一個新的字符串對象。對于頻繁的字符串連接操作,最好使用StringBuilderStringBuffer以提高性能。
  6. 字符串比較: 使用equals()方法來比較字符串的內容,而不是使用==運算符。equals()方法比較字符串的實際內容,而==運算符比較的是對象引用。
  7. 字符串不可變性的好處: 不可變字符串有助于線程安全,可以安全地在多個線程中共享,而無需擔心數據被修改。此外,不可變性還有助于緩存字符串,提高性能。

總的來說,了解String類的內部機制有助于更有效地使用字符串,理解字符串的創建、比較和連接等操作的性能影響。

二、String類的設計哲學

2.1 設計原則:為什么String類如此重要?

String類之所以如此重要,主要是因為字符串在計算機編程中是一種非常常用的數據類型,而Java的String類提供了豐富的方法和功能,使得字符串的處理變得更加方便和靈活。

String類的重要特點和用途:

  1. 不可變性(Immutable): String類的實例是不可變的,一旦創建了字符串對象,就不能再修改它的值。這使得字符串在多線程環境下更安全,也更容易進行優化。

  2. 字符串連接和拼接: String類提供了豐富的方法來進行字符串的連接和拼接,例如使用+運算符或者concat()方法。這使得構建復雜的字符串變得簡單,而且性能較好。

    String firstName = "John";
    String lastName = "Doe";
    String fullName = firstName + " " + lastName;
    
  3. 字符串比較: String類提供了用于比較字符串的方法,如equals()compareTo()。這些方法使得比較字符串內容變得方便,可以輕松地判斷兩個字符串是否相等。

    String str1 = "hello";
    String str2 = "world";
    if (str1.equals(str2)) {// 字符串內容相等
    }
    
  4. 字符串操作: String類包含許多有用的方法,如length()charAt()substring()等,可以對字符串進行各種操作,例如獲取字符串長度、訪問特定位置的字符、提取子串等。

    String text = "Hello, World!";
    int length = text.length(); // 獲取字符串長度
    char firstChar = text.charAt(0); // 獲取第一個字符
    String subString = text.substring(0, 5); // 提取子串
    
  5. 正則表達式: String類提供了支持正則表達式的方法,可以用于字符串的模式匹配和替換操作。

    String text = "The quick brown fox jumps over the lazy dog";
    String replacedText = text.replaceAll("fox", "cat");
    
  6. 國際化(Internationalization): String類提供了支持國際化的方法,可以處理不同語言和字符集的字符串。

String類的重要性在于它為字符串的處理提供了豐富的工具和方法,使得在Java中進行字符串操作變得更加方便、高效和安全。

2.2 字符串池的概念與作用

當談到Java中的字符串池時,我們通常指的是字符串常量池,它是Java中用于存儲字符串常量的一個特殊區域。

  1. 概念
    • 字符串池是一個位于堆區的特殊存儲區域,用于存儲字符串常量。
    • 字符串池是Java運行時數據區的一部分,它有助于提高字符串的重用性和節省內存。
  2. 作用
    • 字符串重用:字符串池確保相同內容的字符串在內存中只有一份。當你創建一個字符串常量時,Java首先檢查字符串池中是否已經存在相同內容的字符串,如果存在,則返回池中的引用,而不是創建一個新的對象。
    • 節省內存:通過重用相同的字符串,避免了在內存中創建多個相同內容的字符串對象,從而節省了內存空間。
    • 提高性能:由于字符串常量池減少了相同字符串的創建和銷毀,因此可以提高程序的性能。

下面是一個簡單的例子,說明字符串池的工作方式:

String s1 = "Hello";  // 創建字符串常量 "Hello",存儲在字符串池中
String s2 = "Hello";  // 直接引用字符串池中的 "Hello",不會創建新的對象System.out.println(s1 == s2);  // 輸出 true,因為它們引用的是相同的字符串對象

**解釋:**由于字符串"Hello"在字符串池中已經存在,因此s2直接引用了已有的對象,而不是創建新的對象。這種字符串池的機制有助于提高內存利用率和程序性能。

三、String類源碼解析

3.1 成員變量

在這里插入圖片描述

3.2 構造函數

// 默認構造函數
public String() {// 通過空字符串的值("")來初始化新創建的字符串對象的值this.value = "".value;
}// 帶有 String 類型參數的構造函數
public String(String original) {// 將新創建的字符串對象的值設置為原始字符串對象的值// value 和 hash 是 String 對象的內部屬性this.value = original.value; // 通過訪問原始字符串對象的 value 屬性來獲取其值this.hash = original.hash; // 獲取原始字符串對象的哈希碼(hash code)
}// 帶有 char 數組參數的構造函數,使用 java.utils 包中的 Arrays 類進行復制
public String(char value[]) {// 使用 Arrays 類的 copyOf 方法復制傳入的 char 數組// 將復制后的數組作為新字符串對象的值this.value = Arrays.copyOf(value, value.length);
}// 用于根據給定的字符數組、偏移量和長度創建一個新的字符串對象
public String(char value[], int offset, int count) {// 檢查偏移量是否小于零if (offset < 0) {// 表示字符串索引越界throw new StringIndexOutOfBoundsException(offset);}// 檢查長度是否小于等于零if (count <= 0) {if (count < 0) {// 表示字符串索引越界throw new StringIndexOutOfBoundsException(count);}// 如果長度為零,并且偏移量在字符數組的范圍內,則將新字符串的值設置為空字符串,然后返回// 為了處理特殊情況,以防止數組越界if (offset <= value.length) {this.value = "".value;return;}}// 檢查偏移量和長度的組合是否超出了字符數組的范圍// Note: offset or count might be near -1>>>1.if (offset > value.length - count) {// 字符串索引越界throw new StringIndexOutOfBoundsException(offset + count);}// 如果通過了所有檢查,使用Arrays.copyOfRange方法從輸入字符數組中復制指定偏移量和長度的部分,然后將這個部分作為新字符串的值。this.value = Arrays.copyOfRange(value, offset, offset+count);
}// 接受一個字節數組 bytes,一個偏移量 offset,一個長度 length,以及一個字符集名稱 charsetName
// 目的是將字節數組以指定的字符集解碼成字符串
public String(byte bytes[], int offset, int length, String charsetName)throws UnsupportedEncodingException {// 參數表示要使用的字符集的名稱,如果為 null,則拋出 NullPointerException 異常if (charsetName == null)throw new NullPointerException("charsetName");// 檢查偏移量和長度是否在字節數組的有效范圍內checkBounds(bytes, offset, length);// 用于實際的解碼過程,將字節數組轉換為字符串,并將結果存儲在 this.value 字段中this.value = StringCoding.decode(charsetName, bytes, offset, length);
}// 使用字節數組的全部內容,并將偏移量設置為0,長度設置為字節數組的長度。通過調用上一個構造方法來完成實際的字符串解碼
public String(byte bytes[], String charsetName)throws UnsupportedEncodingException {this(bytes, 0, bytes.length, charsetName);
}// 接受一個 StringBuffer 對象 buffer,并將其內容復制到新創建的 String 對象中
public String(StringBuffer buffer) {// 通過對 buffer 對象進行同步,確保在復制過程中沒有其他線程對其進行修改synchronized(buffer) {// 使用 Arrays.copyOf 方法來復制字符數組,然后將結果存儲在 this.value 字段中this.value = Arrays.copyOf(buffer.getValue(), buffer.length());}
}

3.3 equals(): 判斷兩個對象是否相等

在這里插入圖片描述

3.4 charAt(): 獲取指定位置的字符

在這里插入圖片描述

3.5 length(): 獲取字符串長度

在這里插入圖片描述

3.6 concat(): 字符串連接

在這里插入圖片描述

3.7 substring(): 子串提取

在這里插入圖片描述

3.8 compareTo (): 字符串長度相等的比較

在這里插入圖片描述

3.9 hashCode():重寫hashCode

在這里插入圖片描述

3.10 replace ():新值替換舊值

在這里插入圖片描述

3.11 trim():去除空格

在這里插入圖片描述

3.12 startsWith():前綴+后綴

在這里插入圖片描述

四、String類的內部實現機制

4.1 字符串的存儲方式:常量池、堆、棧

在Java中,字符串可以存儲在常量池(String Pool)、堆內存(Heap)和棧內存(Stack)中,具體取決于字符串的創建方式和使用情況。

  1. 常量池(String Pool):
    • 字符串池是常量池的一部分,用于存儲字符串常量。
    • 當你使用字符串字面量創建一個字符串時,例如String str = "Hello";,字符串常量"Hello"會存儲在常量池中。
    • 如果已經存在相同內容的字符串常量,那么新的字符串引用會指向已存在的字符串常量,而不會創建新的對象。
  2. 堆內存(Heap):
    • 當使用new關鍵字創建字符串對象時,例如String str = new String("Hello");,字符串對象會存儲在堆內存中。
    • 不管字符串內容是否相同,每次使用new都會在堆內存中創建一個新的字符串對象,即使內容相同也會占用不同的內存空間。
  3. 棧內存(Stack):
    • 字符串引用變量(例如String str = ...;)本身存儲在棧內存中,而不是字符串內容。
    • 如果一個方法內部創建了一個字符串對象,該引用變量也會存儲在棧內存中。

下面是一個簡單的示例,說明了字符串在常量池和堆中的存儲方式:

String str1 = "Hello"; // 存儲在常量池
String str2 = "Hello"; // 直接引用常量池中的"Hello"String str3 = new String("Hello"); // 存儲在堆內存
String str4 = new String("Hello"); // 存儲在堆內存,不同于str3System.out.println(str1 == str2); // true,因為引用的是同一個常量池中的對象
System.out.println(str3 == str4); // false,因為使用了new關鍵字,創建了兩個不同的對象

請注意,對于字符串的比較,應該使用equals()方法而不是==運算符,因為==比較的是引用是否相同,而equals()比較的是字符串的內容是否相同。

4.2 字符串不可變性的實現細節

在Java中,字符串的不可變性是通過以下方式實現的:

  1. final修飾符: Java中的String類被聲明為final,這意味著它不能被繼承。因此,無法創建String類的子類來修改其行為。
  2. 字符數組: 字符串在Java內部是通過字符數組(char array)實現的。這個字符數組被聲明為final,并且它的引用是私有的,因此外部無法直接訪問。
  3. 不可變性方法: String類中的大多數方法都被設計為不會修改字符串本身,而是返回一個新的字符串。例如,concatsubstringreplace等方法都是返回新的字符串對象而不是修改原始字符串。
  4. StringBuilder和StringBuffer的區別: 如果需要對字符串進行頻繁的修改,可以使用StringBuilder或者在多線程環境下使用StringBuffer。這兩者與String不同,它們是可變的。StringBuilderStringBuffer允許修改其內部的字符序列,因此它們的性能可能更好。

雖然字符串是不可變的,但Java中的字符串池(String Pool)提供了一種機制,可以在一定程度上重用字符串對象,以提高性能和節省內存。字符串池可以通過String.intern()方法來使用。這個方法會在字符串池中查找相等的字符串,如果找到則返回池中的實例,否則將字符串添加到池中并返回。這種機制有助于減少內存占用,因為相同的字符串在池中只存在一份。

總的來說,Java中字符串的不可變性是通過final關鍵字、私有字符數組和返回新字符串的方法等多個機制來實現的。

五、性能優化與字符串操作技巧

5.1 使用StringBuilder和StringBuffer提高字符串拼接效率

在Java中,StringBuilderStringBuffer都是用于處理字符串拼接的類,它們的設計目的是為了提高字符串操作的效率,特別是在涉及大量字符串拼接的情況下。

主要區別在于它們的線程安全性:

  1. StringBuilder: 是非線程安全的,適用于單線程環境下的字符串拼接。由于不需要考慮線程同步的開銷,通常比StringBuffer性能稍好。

    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append("Hello");
    stringBuilder.append(" ");
    stringBuilder.append("World");
    String result = stringBuilder.toString();
    
  2. StringBuffer: 是線程安全的,適用于多線程環境下的字符串拼接。它使用了同步方法,因此在多線程情況下可以確保操作的原子性,但這也導致了一些性能開銷。

    StringBuffer stringBuffer = new StringBuffer();
    stringBuffer.append("Hello");
    stringBuffer.append(" ");
    stringBuffer.append("World");
    String result = stringBuffer.toString();

在實際使用中,如果你的應用是單線程的,建議使用StringBuilder,因為它相對更輕量。如果涉及到多線程操作,并且需要保證線程安全性,可以選擇使用StringBuffer。總的來說,在大多數情況下,StringBuilder更常見,因為很多場景下不需要關心線程安全性。

5.2 字符串比較的最佳實踐

在Java中進行字符串比較時,有幾種不同的方法,而選擇哪種方法通常取決于你的具體需求。

下面是一些在Java中進行字符串比較的最佳實踐

  1. 使用equals方法:

    String str1 = "Hello";
    String str2 = "World";if (str1.equals(str2)) {// 字符串相等
    }

    這是最基本的字符串比較方法。使用equals方法比較字符串的內容是否相同。

  2. 忽略大小寫比較:

    String str1 = "Hello";
    String str2 = "hello";if (str1.equalsIgnoreCase(str2)) {// 忽略大小寫,字符串相等
    }

    使用equalsIgnoreCase方法來執行大小寫不敏感的比較。

  3. 使用compareTo方法:

    String str1 = "Hello";
    String str2 = "World";int result = str1.compareTo(str2);if (result == 0) {// 字符串相等
    } else if (result < 0) {// str1 小于 str2
    } else {// str1 大于 str2
    }

    compareTo方法返回一個整數,表示兩個字符串的大小關系。

  4. 使用Objects.equals方法(防止空指針異常):

    String str1 = "Hello";
    String str2 = "World";if (Objects.equals(str1, str2)) {// 字符串相等,包括處理空指針異常
    }

    Objects.equals方法可以防止在比較時出現空指針異常。

  5. 使用StringUtils.equals方法(Apache Commons Lang庫):

    import org.apache.commons.lang3.StringUtils;String str1 = "Hello";
    String str2 = "World";if (StringUtils.equals(str1, str2)) {// 字符串相等,包括處理空指針異常
    }

    如果你使用Apache Commons Lang庫,可以使用其中的StringUtils.equals方法來進行字符串比較,它也能處理空指針異常。

六、案例分析與實例演示

6.1 實際代碼示例:如何更好地使用String類

在Java中,String類是一個常用的類,用于表示字符串并提供了許多方法來處理字符串。

以下是一些使用String類的實際代碼示例,展示了如何更好地利用該類的一些常見方法:

  1. 字符串的基本操作:
public class StringExample {public static void main(String[] args) {// 創建字符串String str1 = "Hello";String str2 = "World";// 字符串連接String result = str1 + ", " + str2;System.out.println(result);// 獲取字符串長度int length = result.length();System.out.println("Length: " + length);// 字符串比較boolean isEqual = str1.equals(str2);System.out.println("Are strings equal? " + isEqual);// 忽略大小寫比較boolean isEqualIgnoreCase = str1.equalsIgnoreCase("hello");System.out.println("Are strings equal (ignore case)? " + isEqualIgnoreCase);// 提取子字符串String substring = result.substring(0, 5);System.out.println("Substring: " + substring);// 查找字符或子字符串的位置int index = result.indexOf("World");System.out.println("Index of 'World': " + index);}
}
  1. 使用StringBuilder進行字符串拼接:
public class StringBuilderExample {public static void main(String[] args) {// 使用StringBuilder進行字符串拼接StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("Hello");stringBuilder.append(", ");stringBuilder.append("World");// 轉換為StringString result = stringBuilder.toString();System.out.println(result);}
}
  1. 字符串的拆分與連接:
public class SplitJoinExample {public static void main(String[] args) {// 字符串拆分String names = "John,Jane,Jim";String[] nameArray = names.split(",");for (String name : nameArray) {System.out.println("Name: " + name);}// 字符串連接String joinedNames = String.join("-", nameArray);System.out.println("Joined Names: " + joinedNames);}
}

6.2 常見陷阱與解決方案

在Java中,String類是一個常用的類,但在使用過程中可能會遇到一些陷阱。以下是一些常見的String類使用陷阱及其解決方案:

  1. 字符串拼接的陷阱

    • 陷阱:使用+運算符進行字符串拼接時,每次拼接都會創建一個新的String對象,效率較低。
    • 解決方案:使用StringBuilder類進行字符串拼接,它是可變的,可以減少對象的創建。
    StringBuilder sb = new StringBuilder();
    sb.append("Hello");
    sb.append(" ");
    sb.append("World");
    String result = sb.toString();
  2. 字符串比較的陷阱

    • 陷阱:使用==比較字符串內容,這比較的是對象的引用而不是內容。
    • 解決方案:使用equals()方法進行字符串內容的比較。
    String str1 = "Hello";
    String str2 = new String("Hello");
    if (str1.equals(str2)) {// 內容相等
    }
  3. 不可變性的陷阱

    • 陷阱:String對象是不可變的,每次對字符串進行修改都會創建新的對象,可能導致性能問題。
    • 解決方案:如果需要頻繁修改字符串,可以使用StringBuilderStringBuffer,它們是可變的。
    StringBuilder sb = new StringBuilder("Hello");
    sb.append(" World");
    String result = sb.toString();
  4. 空字符串處理的陷阱

    • 陷阱:未對空字符串進行判空處理可能導致空指針異常。
    • 解決方案:始終在使用字符串之前檢查是否為null或空字符串。
    String str = ...; // 從其他地方獲取的字符串
    if (str != null && !str.isEmpty()) {// 執行操作
    }
  5. 字符串常量池的陷阱

    • 陷阱:使用new String()方式創建字符串對象時,不會在常量池中進行緩存,可能導致不必要的內存消耗。
    • 解決方案:直接使用字符串字面量,或者使用intern()方法將字符串對象放入常量池。
    String str1 = "Hello"; // 位于常量池
    String str2 = new String("Hello").intern(); // 放入常量池

這些是一些常見的String類使用陷阱及其解決方案。在開發中,始終注意字符串的不可變性和性能問題,選擇適當的方式來處理字符串操作。

盈若安好,便是晴天

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

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

相關文章

[今來] 神話故事:金馬和碧雞

文章目錄 金馬山和碧雞山神話傳說金馬坊和碧雞坊金馬碧雞 金馬山和碧雞山 昆明山明水秀&#xff0c;北枕蛇山&#xff0c;南臨滇池&#xff0c;金馬山和碧雞山則東西夾峙&#xff0c;隔水相對&#xff0c;極盡湖光山色之美。金馬山逶迤而玲瓏&#xff0c;碧雞山峭拔而陡峻&…

[Java][Map]linkedhashmap的引入

我們可以看到&#xff1a; linkedhashmap中元素的讀取是有順序的&#xff0c;基于這種雙向鏈表 我們可以優先讀取8索引bucket上的元素 然后讀取3索引bucket上的元素&#xff0c;以及其掛載的元素 最后讀取0索引bucket上的元素 bucket是hashbucket! 這種寫法是很有序的 也是…

Pytorch初步使用

文章目錄 創建張量指定設備沿軸計算 創建張量 如果說數組是numpy的操作對象&#xff0c;那么張量Tensor就是pytorch的操作單元&#xff0c;從數據內容來說&#xff0c;與高維數組是如出一轍的&#xff0c;但作為一個類&#xff0c;其構造函數支持通過聲明張量的維度來進行初始…

clickhouse數據庫磁盤空間使用率過高問題排查

一、前言 clickhouse天天觸發磁盤使用率過高告警&#xff0c;所以需要進行排查&#xff0c;故將排查記錄一下。 二、排查過程 1、連接上進入clickhouse 2、執行語句查看各庫表使用磁盤情況 SELECT database, table, formatReadableSize(sum(bytes_on_disk)) as disk_space F…

藍橋杯物聯網競賽_STM32L071_8_ADC擴展模塊

原理圖&#xff1a; 擴展模塊原理圖&#xff1a; RP1和RP2分別對應著AIN1和AIN2&#xff0c;扭動它們&#xff0c;其對應滑動變阻器阻值也會變化 實驗板接口原理圖&#xff1a; 對應實驗板接口PB1和PB0 即AN1對應PB1, AN2對應PB0 CubMx配置&#xff1a; ADC通道IN8和IN9才對…

C#.net使用npgsql批量寫入數據入庫到postgresql數據庫

C#.net使用npgsql批量寫入數據入庫到postgresql數據庫 npgsql批量存儲數據1. 單條存儲2. 批量存儲 npgsql批量存儲數據 轉載自&#xff1a;https://blog.csdn.net/liuwanying0226/article/details/130825503 1. 單條存儲 當有類型限定時&#xff0c;例如jsonb&#xff0c;在…

uniApp項目的創建,運行到小程序

一、項目創建 1. 打開 HBuilder X 2. 右擊側邊欄點擊新建&#xff0c;選擇項目 3. 填寫項目名&#xff0c;點擊創建即可 注&#xff1a;uniapp中如果使用生命周期鉤子函數&#xff0c;建議使用哪種 ?(建議使用Vue的) 二、運行 1. 運行前先登錄 2. 登錄后點擊 manifest.js…

基于lambda簡化設計模式

前言 雖說使用設計模式可以讓復雜的業務代碼變得清晰且易于維護&#xff0c;但是某些情況下&#xff0c;開發可能會遇到我為了簡單的業務邏輯去適配設計模式的情況&#xff0c;本文筆者就以四種常見的設計模式為例&#xff0c;演示如何基于lambda來簡化設計模式的實現。 策略…

WorkPlus高效助力企業溝通的專業級即時通訊軟件

在當今高度信息化和全球化競爭的世界&#xff0c;企業需要一個高效便捷的溝通工具來促進團隊協作、提高工作效率。在這樣的背景下&#xff0c;WorkPlus作為一款專業級的即時通訊軟件應運而生。讓我們一起深入了解WorkPlus&#xff0c;探討其在企業溝通中的領先優勢和卓越能力。…

平衡二叉樹

AVL簡稱平衡二叉樹&#xff0c;縮寫為BBST&#xff0c;由蘇聯數學家 Adelse-Velskil 和 Landis 在 1962 年提出。 二叉樹是動態查找的典范&#xff0c;但在極限情況下&#xff0c;二叉樹的查找效果等同于鏈表&#xff0c;而平衡二叉樹可以完美的達到 log ? 2 n \log_2 n log2…

ElementPlus table 中嵌套 input 輸入框

文章目錄 需求分析 需求 vue3 項目中 使用UI組件庫 ElementPlus 時&#xff0c;table 中嵌入 input輸入框 分析 <template><div class"p-10"><el-table :data"tableData" border><el-table-column prop"date" label&qu…

課堂練習4.1:段式內存管理

4-1 課堂練習4.1&#xff1a;段式內存管理 段式內存管理以段為單位分配內存空間&#xff0c;段內連續&#xff0c;段間可以不連續。段可以很大&#xff0c;比如數據段、代碼段、棧段等。本實訓分析 Linux 0.11 的段式內存管理技術。 第1關1 號進程 mynext 變量的邏輯地址與線性…

cache教程 3.HTTP服務器

上一節我們實現了單機版的緩存服務&#xff0c;但是我們的目標是分布式緩存。那么&#xff0c;我們就需要把緩存服務部署到多態機器節點上&#xff0c;對外提供訪問接口。客戶端就可以通過這些接口去實現緩存的增刪改查。 分布式緩存需要實現節點間通信&#xff0c;而通信方法…

【面試經典150 | 二叉樹】翻轉二叉樹

文章目錄 寫在前面Tag題目來源題目解讀解題思路方法一&#xff1a;遞歸方法二&#xff1a;迭代 寫在最后 寫在前面 本專欄專注于分析與講解【面試經典150】算法&#xff0c;兩到三天更新一篇文章&#xff0c;歡迎催更…… 專欄內容以分析題目為主&#xff0c;并附帶一些對于本題…

4-SpringMVC

文章目錄 項目源碼地址回顧-MVC什么是MVC&#xff1f;MVC各部分組成 回顧-ServletMaven創建Web項目1、創建Maven父工程pom&#xff0c;并導入依賴2、用Maven新建一個Web Module3、代碼&#xff1a;HelloServlet.java3、代碼-hello.jsp3、代碼-web.xml4、配置Tomcat5、瀏覽器測試…

github使用方法【附安裝包】

如果你是一枚Coder&#xff0c;但是你不知道Github&#xff0c;那么我覺的你就不是一個菜鳥級別的Coder&#xff0c;因為你壓根不是真正Coder&#xff0c;你只是一個Code搬運工。說明你根本不善于突破自己&#xff01;為什么這么說原因很簡單&#xff0c;很多優秀的代碼以及各種…

高級系統架構設計師之路

前言&#xff1a;系 統 架 構 設 計 師 (System Architecture Designer)是項目開發活動中的眾多角色之 一 &#xff0c;它可 以是 一個人或 一個小組&#xff0c;也可以是一個團隊。架構師 (Architect) 包含建筑師、設計師、創造 者、締造者等含義&#xff0c;可以說&#xff0…

邊緣計算系統設計與實踐:引領科技創新的新浪潮

文章目錄 一、邊緣計算的概念二、邊緣計算的設計原則三、邊緣計算的關鍵技術四、邊緣計算的實踐應用《邊緣計算系統設計與實踐》特色內容簡介作者簡介目錄前言/序言本書讀者對象獲取方式 隨著物聯網、大數據和人工智能等技術的快速發展&#xff0c;傳統的中心化計算模式已經無法…

基于ssm人力資源管理系統論文

摘 要 隨著企業員工人數的不斷增多&#xff0c;企業在人力資源管理方面負擔越來越重&#xff0c;因此&#xff0c;為提高企業人力資源管理效率&#xff0c;特開發了本人力資源管理系統。 本文重點闡述了人力資源管理系統的開發過程&#xff0c;以實際運用為開發背景&#xff0…

【大數據】Hudi 核心知識點詳解(一)

Hudi 核心知識點詳解&#xff08;一&#xff09; 1.數據湖與數據倉庫的區別 &#xff1f;1.1 數據倉庫1.2 數據湖1.3 兩者的區別 2.Hudi 基礎功能2.1 Hudi 簡介2.2 Hudi 功能2.3 Hudi 的特性2.4 Hudi 的架構2.5 湖倉一體架構 3.Hudi 數據管理3.1 Hudi 表數據結構3.1.1 .hoodie …