主頁 > 後端開發 > 簡述泛型的基本使用和作用

簡述泛型的基本使用和作用

2023-06-03 07:44:27 後端開發

前言

在上一篇文章中,給大家講解了泛型的概念、作用、使用場景,以及泛型集合、泛型介面和泛型類的用法,但受限于篇幅,并沒有把泛型的內容講解完畢,所以今天我們會繼續學習泛型方法、泛型擦除,以及通配符等的內容,希望大家繼續做好學習的準備哦,


全文大約【4600】 字,不說廢話,只講可以讓你學到技術、明白原理的純干貨!本文帶有豐富的案例及配圖視頻,讓你更好地理解和運用文中的技術概念,并可以給你帶來具有足夠啟迪的思考...

一. 泛型方法

1. 簡介

我們可以在定義介面和類時使用泛型,這樣該介面和類中的所有方法及成員變數等處,也都可以使用該泛型,但其實泛型可以應用在整個類上,也可以只應用在類中的某個方法上,也就是說,方法所在的類可以是泛型類,也可以不是泛型類,方法中是否帶有泛型,與其所在的類有沒有泛型沒有關系,

泛型方法是在呼叫方法時才確定型別的方法,泛型可以使得該方法獨立于類而產生變化,另外,static靜態方法無法訪問泛型類的型別引數,因此,如果想讓一個static方法具有泛型能力,就必須使該靜態方法成為泛型方法,

2. 語法

我們在定義泛型方法時,需要在方法名的前面添加型別引數,定義泛型方法的語法格式如下:

[訪問權限修飾符] [static] [final] <型別引數串列> 回傳值型別 方法名([形式引數串列])

例如:

public static <T> List showInfo(Class<T> clazz,int userId){}

一般情況下,我們撰寫泛型方法時,必須在該方法的名稱前宣告要使用的泛型,并且可以同時宣告多個泛型,中間也是用逗號分割,接下來就定義一個泛型方法,給大家具體介紹一下泛型方法的創建和使用,

3. 代碼案例

這里我們定義一個泛型方法,用于對陣列排序后再遍歷元素輸出,代碼如下:

import java.util.Arrays;

public class Demo04 {
	
	//定義了一個靜態的泛型方法,遍歷陣列中的每個元素
	public static <T> void printArray(T[] arr) {
		//先對陣列進行排序
		Arrays.sort(arr);
		//再遍歷陣列元素
	    for (T t : arr) {
	        System.out.print(t + " ");
	    }
	    System.out.println();
	}
	
	public static void main(String[] args) {
		Integer[] nums= {100,39,8,200,65};
		//呼叫泛型方法
		printArray(nums);
	}
}

在上面的代碼中,printArray()就是一個泛型方法,該方法中使用了型別引數T,并且我們在方法的引數中,使用型別引數T定義了一個泛型陣列T[],接著對該陣列進行排序和遍歷,這樣以后無論我們傳入任何型別的陣列,都可以在不進行型別轉換的前提下,輕松實作排序等功能了,這樣我們之前提的需求也就很容易實作了,

二. 通配符

除了以上這些用法之外,泛型中還有一個很重要的通配符功能,接下來我們就來看看它是怎么回事,

1. 簡介

泛型中的通配符其實也是一種特殊的泛型型別,也稱為通配符型別引數,利用通配符型別引數,可以讓我們撰寫出更通用的代碼,甚至可以在不知道實際型別的情況下使用它們,我們一般是使用 ? 來代替具體的型別引數,例如 List<?> 在邏輯上可以等同于 List、List 等所有 List<具體型別實參> 的類,

對此,有的小伙伴可能會很好奇,我們為什么需要通配符呢?其實之所以會出現通配符,主要是在開發時,有時候我們需要一個泛型型別,但我們卻不知道該使用哪個具體的型別,在這種情況下,我們就可以使用通配符型別引數,讓代碼更加地通用,比如,我們想撰寫一個可以接受任何型別的集合,并回傳其中最大的元素時,此時我們可能并不確定到底該傳入哪個具體的集合,那使用通配符就會更好一些,

2. 通配符的形式

泛型通配符在具體使用時,有如下三種實作形式:

  • 未限定通配符(?)?表示未知型別的通配符
  • 上限通配符(? extends T)?表示型別上限的通配符,T是一個類或介面
  • 下限通配符(? super T)?表示型別下限的通配符,T是一個類或介面

接下來我們針對以上這三種形式,分別通過幾個案例來給大家講解其用法,

3. 未限定通配符(?)

未限定通配符(?)是一種表示未知型別的通配符,它可以在需要一個型別引數的情況下使用,但由于沒有限制,因此它只能用于簡單的情況,例如集合中的迭代器或者回傳型別是泛型的方法等,下面是一個簡單的例子:

import java.util.ArrayList;
import java.util.List;

public class Demo05 {

	public static void main(String[] args) {
		List<String> names = new ArrayList<String>();
		List<Integer> ages = new ArrayList<Integer>();
		List<Number> numbers = new ArrayList<Number>();

		names.add("一一哥");
		names.add("秦始皇");
		ages.add(28);
		ages.add(50);
		ages.add(28);
		numbers.add(100);
		numbers.add(800);

		printElement(names);
		printElement(ages);
		printElement(numbers);
	}

	//未限定通配符的使用
	public static void printElement(List<?> data) {
		for(int i=0;i<data.size();i++) {
			//data.getClass().getSimpleName():用于獲取某個類的類名
			System.out.println(data.getClass().getSimpleName()+"--data: " + data.get(i));
		}
	}

}

在這個例子中,printElement()方法就接受了一個未知型別的List集合,所以names,ages,numbers都可以作為這個方法的實參,這就是未限定通配符的作用,

4. PECS原則

PECS是Producer Extends Consumer Super的縮寫,這是關于Java泛型的一種設計原則,該原則表示,如果我們需要回傳T,它是生產者(Producer),要使用extends通配符;如果需要寫入T,它就是消費者(Consumer),要使用super通配符,該原則可以指導我們在使用泛型時,該如何定義型別引數的上限和下限,

當我們使用泛型時,可能需要定義型別引數的上限和下限,

例如,我們想要撰寫一個方法來處理一些集合型別,但我們不知道這些集合中到底有什么型別的元素,此時我們就可以定義一個型別引數來處理所有的集合型別,一般我們可以利用extends來設定泛型上限,利用super來設定泛型下限,接下來會在下面的第5和第6小結中,給大家講解泛型的上限和下限具體該如何實作,請大家繼續往下學習,

5. 上限通配符(? extends T)

上限通配符(?extends T)是一種表示型別上限的通配符,其中T是一個類或介面,泛型類的型別必須實作或繼承 T這個介面或類,它指定了可以使用的型別上限,主要是用于限制輸入的引數型別,

import java.util.ArrayList;
import java.util.List;

/**
 * @author 一一哥Sun 
 */
public class Demo06 {

	public static void main(String[] args) {
		List<String> names = new ArrayList<String>();
		List<Integer> ages = new ArrayList<Integer>();
		List<Number> numbers = new ArrayList<Number>();

		names.add("一一哥");
		names.add("秦始皇");
		ages.add(28);
		ages.add(50);
		ages.add(28);
		numbers.add(100);
		numbers.add(800);
		
		//String等非Number型別就不行
		//printElementUpbound(names);
		
		//泛型值只能是Number及其子型別別,所以Integer/Double/Float等型別都可以,但String就不行
		printElementUpbound(ages);
		printElementUpbound(numbers);
	}

	//上限通配符的使用,這里的泛型值只能是Number及其子型別別
	public static void printElementUpbound(List<? extends Number> data) {
		for(int i=0;i<data.size();i++) {
			//data.getClass().getSimpleName():用于獲取某個類的類名
			System.out.println(data.getClass().getSimpleName()+"--data: " + data.get(i));
		}
	}
}

在這個例子中,printElementUpbound方法中的集合泛型,可以是Number類或其子類,除此之外的其他型別都不行,也就是說,我們只能使用Number或其子類作為型別引數,泛型型別的上限是Number,這就是上限通配符的含義,

6. 下限通配符(? super T)

下限通配符(?super T)是一種表示型別下限的通配符,其中T是一個類或介面,它指定了可以使用的型別下限,主要用于限制輸出的引數型別,下面是一個簡單的例子:

import java.util.ArrayList;
import java.util.List;

public class Demo07 {

	public static void main(String[] args) {
		List<String> names = new ArrayList<String>();
		List<Integer> ages = new ArrayList<Integer>();
		List<Double> numbers = new ArrayList<Double>();

		names.add("一一哥");
		names.add("秦始皇");
		ages.add(28);
		ages.add(50);
		ages.add(28);
		numbers.add(100.0);
		numbers.add(800.9);
		
		//String等非Number型別就不行
		//printElementUpbound(names);
		
		//此時Double型別也不行
		//printElementDownbound(numbers);
		
		//泛型值只能是Integer及其父型別別,所以Double/Float/String等型別都不可以
		printElementDownbound(ages);
		
	}

	//下限通配符的使用,這里的泛型值只能是Integer及其父型別別
	public static void printElementDownbound(List<? super Integer> data) {
		for(int i=0;i<data.size();i++) {
			System.out.println(data.getClass().getSimpleName()+"--data: " + data.get(i));
		}
	}
}

在這個例子中,printElementDownbound方法中的集合泛型,可以是Integer或其父型別,即型別下限是Integer,除此之外的其他型別都不行,也就是說,我們只能使用Integer或其父類作為型別引數,泛型型別的下限是Integer,這就是下限通配符的含義,

7. <? extends T>和<? super T>的區別

在這里,要給大家再總結一下<? extends T>和<? super T>的區別:

  • <? extends T> 允許呼叫 T get()這樣的 讀方法來獲取 T物件 的參考,但不允許呼叫 set(T)這樣的 寫方法來傳入 T 的參考(傳入 null 除外);
  • <? super T> 允許呼叫 set(T)這樣的 寫方法傳入 T物件 的參考,但不允許呼叫 T get()這樣的 讀方法來獲取 T物件 的參考(獲取 Object 除外),
  • <? extends T> 允許讀不允許寫, <? super T> 允許寫不允許讀,

大家注意,無論是未限定通配符、上限通配符還是下限通配符,我們既可以在方法中使用,也可以在類或介面中使用,

三. 泛型擦除

我們在學習泛型時,除了要掌握上面這些泛型類、泛型介面、泛型方法以及通配符等內容之外,還要學習泛型擦除的相關內容,那么什么是泛型擦除呢?我們繼續往下學習吧,

1. 簡介

所謂的泛型擦除(Type Erasure),就是指在編譯時,JVM編譯器會將所有的泛型資訊都擦除掉,變成原始型別,一般是將泛型的型別引數替換成具體型別的上限或下限(如果沒有指定上界,則默認為Object),

換句話說,雖然我們在代碼中使用了泛型,但在編譯后,所有的泛型型別都會被擦除掉,轉而使用其對應的原始型別,這就是Java泛型的底層實作原理,這樣設計的目的是為了兼容舊的JDK版本,使得Java具有了較好的向后兼容性,舊的非泛型代碼可以直接使用泛型類別庫,而不需要進行任何修改,同時,Java也提供了反射機制來操作泛型型別,使得泛型型別在某些情況下還是可以被獲取到的,所以即使有泛型擦除,仍然也不會太影響Java虛擬機的運行時效率,

比如,在我們定義一個泛型類時,我們會使用泛型型別引數來代替具體的型別,好比下面這個例子:
在這里插入圖片描述

2. 泛型擦除帶來的限制

在編譯之后,這個泛型類的型別引數T就會被擦除,成為其對應的原始型別Object,

這也意味著,我們無法在運行時獲取到泛型的實際型別引數,所以泛型擦除的使用會有一些限制,首先由于泛型型別引數被擦除了,因此我們在運行時就無法獲得泛型型別引數的資訊,例如,如果我們有一個List型別的變數,在運行時我們就無法獲得這個List集合中的元素型別是Integer,另一個限制是在使用泛型型別時,還需要注意型別安全性,在編譯階段,編譯器會檢查泛型型別的型別安全性;但在運行階段,由于泛型型別引數被擦除了,因此就無法保證型別安全性了,泛型擦除的限制,主要表現在以下幾個方面:

無法使用基本型別實體化型別引數;

無法在運行時獲取泛型型別資訊;

泛型型別引數不能用于靜態變數或靜態方法;

不能實體化T型別,

接下來再給大家具體分析一下這些限制

2.1 無法使用基本型別實體化型別引數

Java泛型中的型別引數不能是基本型別,只能是類或介面型別,例如,以下代碼在編譯階段會出錯,無法通過編譯:

List<int> list = new ArrayList<int>();

正確的寫法是使用基本型別對應的包裝型別,如下所示:

List<Integer> list = new ArrayList<Integer>();

2.2 無法在運行時獲取泛型型別資訊

由于泛型擦除的存在,導致我們在程式運行時無法獲取泛型型別的資訊,例如,以下代碼在運行時就無法獲取List的元素型別:

List<String> list = new ArrayList<String>(); 
Class<?> clazz = list.getClass(); 
Type type = clazz.getGenericSuperclass(); 
// 輸出:class java.util.ArrayList<E>
System.out.println(type); 

在輸出的結果中,我們只能得到ArrayList的型別資訊,而無法獲取到集合中具體的泛型型別資訊,也就是獲取不到String的資訊,但如果我們就是想在運行時獲取到泛型的實際型別引數,其實可以參考以下方式進行實作:

public class Box<T> {
    private T content;

    public Box(T content) {
        this.content = content;
    }

    public T getContent() {
        return content;
    }

    public void setContent(T content) {
        this.content = content;
    }

    public Class<?> getContentType() {
        return content.getClass();
    }
}

在上面的代碼中,我們新增了一個方法 getContentType(),該方法用于回傳泛型型別引數的實際位元組碼型別,以后我們通過呼叫這個方法,就可以間接地獲取到泛型型別的資訊了,

2.3 泛型型別引數不能用于靜態變數或靜態方法

由于泛型型別引數是在實體化物件時才被確定的,因此不能在靜態變數或靜態方法中使用泛型型別引數,例如,以下代碼是無法編譯通過的:

public class MyClass<T> {   
    //這樣的代碼編譯不通過
    private static T value;   
    
    public static void setValue(T value) {        
        MyClass.value = https://www.cnblogs.com/qian-fen/p/value;     
    } 
}

正確的寫法是使用一個實際型別來代替泛型型別引數:

public class MyClass {     
    private static String value;          
    public static void setValue(String value) {         
        MyClass.value = https://www.cnblogs.com/qian-fen/p/value;     
    } 
}

2.4 不能實體化T型別

比如在下面的案例中:

public class MyClass<T> {
    private T first;
    private T last;
    
    public MyClass() {
        first = new T();
        last = new T();
    }
}

上述代碼無法通過編譯,因為構造方法的兩行陳述句:

first = new T(); 
last = new T(); 

擦拭后實際上變成了:

first = new Object(); 
last = new Object(); 

這樣一來,創建new MyClass<String>()和創建new MyClass<Integer>()就變成了Object,編譯器會阻止這種型別不對的代碼,如果我們想對泛型T進行實體化,需要借助Class< T >引數并集合反射技術來實作,且在使用時也必須傳入Class< T >,


四. 結語

不過,盡管泛型擦除有一些限制,但泛型仍然不失為一種強大的編程工具,它可以提高代碼的可讀性和可維護性,通過合理地使用泛型,我們可以在編譯時進行型別檢查,避免型別轉換的錯誤和運行時例外,從而提高了代碼的安全性和可靠性,同時,我們也需要了解Java泛型擦除的限制,以便在實際應用中做出正確的決策,

視頻教程:視頻教程,戳我直達

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/554120.html

標籤:Java

上一篇:為什么說 Go 語言字串是不可變的?

下一篇:返回列表

標籤雲
其他(160206) Python(38196) JavaScript(25473) Java(18175) C(15236) 區塊鏈(8269) C#(7972) AI(7469) 爪哇(7425) MySQL(7223) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5346) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4581) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1980) 功能(1967) Web開發(1951) HtmlCss(1951) C++(1928) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1879) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • 簡述泛型的基本使用和作用

    # 前言 在上一篇文章中,給大家講解了泛型的概念、作用、使用場景,以及泛型集合、泛型介面和泛型類的用法,但受限于篇幅,并沒有把泛型的內容講解完畢。所以今天我們會繼續學習泛型方法、泛型擦除,以及通配符等的內容,希望大家繼續做好學習的準備哦。 *** 全文大約【**4600】** 字,不說廢話,只講可以 ......

    uj5u.com 2023-06-03 07:44:27 more
  • 為什么說 Go 語言字串是不可變的?

    **原文鏈接:** [為什么說 Go 語言字串是不可變的?](https://mp.weixin.qq.com/s/AOb6AjKwyTwLeAUou0AU-Q) 最近有讀者留言說,平時在寫代碼的程序中,是會對字串進行修改的,但網上都說 Go 語言字串是不可變的,這是為什么呢? 這個問題本身并 ......

    uj5u.com 2023-06-03 07:38:25 more
  • JVM致命錯誤日志詳解

    [toc] 這篇文章是我之前總結的一篇文章,因為整理博客的原因,原有博客已經注銷,但這篇文章對一些讀者很有用,所以現在新瓶裝舊酒重新整理回來分享給大家。 最近一段時間生產環境頻繁出問題,每次都會生成一個hs_err_pid*.log檔案,因為作業內容的原因,在此之前并沒有了解過相關內容,趁此機會學習 ......

    uj5u.com 2023-06-02 10:10:23 more
  • JVM致命錯誤日志詳解

    [toc] 這篇文章是我之前總結的一篇文章,因為整理博客的原因,原有博客已經注銷,但這篇文章對一些讀者很有用,所以現在新瓶裝舊酒重新整理回來分享給大家。 最近一段時間生產環境頻繁出問題,每次都會生成一個hs_err_pid*.log檔案,因為作業內容的原因,在此之前并沒有了解過相關內容,趁此機會學習 ......

    uj5u.com 2023-06-02 10:06:25 more
  • EasyExcel

    EasyExcel是一個基于Java的、快速、簡潔、解決大檔案記憶體溢位的Excel處理工具。 他能讓你在不用考慮性能、記憶體的等因素的情況下,快速完成Excel的讀、寫等功能。 # 快速入門 匯入依賴 ~~~xml com.alibaba easyexcel 3.1.1 ~~~ # 寫 Excel # ......

    uj5u.com 2023-06-02 08:25:19 more
  • Jackson前后端開發模式必備json利器

    ### 前言 json是我們現代互聯網程式最常用的互動格式,是否你在作業中會遇到前端說欄位不一致需要改的需求,是否遇到過資料庫欄位名與javaBean的規范不同,是否遇到過json與javaBean相互轉換時因為需求寫的土匪代碼,這些都可以用Jackson完成,我們經常和json打交道,而Jacks ......

    uj5u.com 2023-06-02 08:25:14 more
  • Java中的同步和異步

    在Java中,同步(Synchronous)和異步(Asynchronous)是用來描述程式執行模式的概念。 1. 同步:同步指的是按照程式的順序依次執行代碼,每個操作都會等待前一個操作完成后再執行。同步執行的特點是阻塞,即某個操作的完成會導致后續操作的等待。在多執行緒編程中,同步可以通過使用鎖(如` ......

    uj5u.com 2023-06-02 08:25:10 more
  • celery筆記一之celery介紹、啟動和運行結果跟蹤

    > 本文首發于公眾號:Hunter后端 > 原文鏈接:[celery筆記一之celery介紹、啟動和運行結果跟蹤](https://mp.weixin.qq.com/s/o6enPH4f1qo8WXrl9vO-1w) 本篇筆記內容如下: 1. celery 介紹 2. celery 準備 3. ce ......

    uj5u.com 2023-06-02 08:25:03 more
  • 驅動開發:內核決議PE結構節表

    在筆者上一篇文章`《驅動開發:內核決議PE結構匯出表》`介紹了如何決議記憶體匯出表結構,本章將繼續延申實作決議PE結構的PE頭,PE節表等資料,總體而言內核中決議PE結構與應用層沒什么不同,在上一篇文章中`LyShark`封裝實作了`KernelMapFile()`記憶體映射函式,在之后的章節中這個函式... ......

    uj5u.com 2023-06-02 08:24:53 more
  • Spring Cloud開發實踐(七): 集成Consul配置中心

    Consul 通過 Key/Value 功能集中管理存盤配置資訊, 通過 Spring Cloud Consul Config 可以實作 Config Server 和 Client 的關聯. 在 Spring 啟動的 bootstrap 階段, 配置會被載入環境背景關系. ......

    uj5u.com 2023-06-02 08:24:47 more