C++進階——C++11_{ }初始化_lambda_包裝器

目錄

1、{ }初始化

1.1 C++98的{ }

1.2 C++11的{ }

1.3?C++11中的std::initializer_list

總結一下:

2、lambda

2.1 lambda的語法

2.2 捕捉列表

2.3 lambda的應用

2.4 lambda的原理

3、包裝器

3.1 function

3.2 bind


1、{ }初始化

1.1 C++98的{ }

C++98中一般數組結構體可以用{ }進行初始化

struct Point
{int _x;int _y;
};int main()
{int array1[] = {1, 2, 3, 4, 5};int array2[5] = {0};Point p = {1, 2};return 0;
}

1.2 C++11的{ }

C++11 以后想統一初始化方式,試圖實現一切對象皆可用 { } 初始化{ } 初始化也叫做列表初始化

內置類型支持自定義類型支持自定義類型本質是類型轉換,中間會產生臨時對象,最后優化
了以后變成直接構造

{ } 初始化的過程中,可以省略?=?

#include <iostream>
#include <vector>
using namespace std;struct Point
{int _x;int _y;
};class Date
{
public:Date(int year = 1, int month = 1, int day = 1): _year(year), _month(month), _day(day){cout << "Date(int year, int month, int day)" << endl;}Date(const Date& d): _year(d._year), _month(d._month), _day(d._day){cout << "Date(const Date& d)" << endl;}private:int _year;int _month;int _day;
};int main()
{// C++98 支持的初始化方式int a1[] = {1, 2, 3, 4, 5};int a2[5] = {0};Point p = {1, 2};// C++11 支持的初始化方式// 內置類型支持int x1 = {2};// 自定義類型支持// 這里本質是用 {2025, 1, 1} 構造一個 Date 臨時對象// 臨時對象再去拷貝構造 d1,編譯器優化后合二為一變成 {2025, 1, 1} 直接構造初始化 d1// 運行一下,我們可以驗證上面的理論,發現是沒調用拷貝構造的Date d1 = {2025, 1, 1};// 這里 d2 引用的是 {2024, 7, 25} 構造的臨時對象const Date& d2 = {2024, 7, 25};// 需要注意的是 C++98 支持單參數時類型轉換,也可以不用 {}Date d3 = {2025};Date d4 = 2025;// 可以省略掉 =Point p1{1, 2};int x2{2};Date d6{2024, 7, 25};const Date& d7{2024, 7, 25};// 不支持,只有 {} 初始化,才能省略 =// Date d8 2025;vector<Date> v;v.push_back(d1);v.push_back(Date(2025, 1, 1));// 比起有名對象和匿名對象傳參,這里 {} 更有性價比v.push_back({2025, 1, 1});return 0;
}

1.3?C++11中的std::initializer_list

但是對象容器初始化還是不太方便,比如一個vector對象,我想用N個值構造初始化,那么我們得實現很多個構造函數才能支持

vector<int> v1 = {1, 2, 3};
vector<int> v2 = {1, 2, 3, 4, 5};

C++11 庫中提出了一個 std::initializer_list 的類,

auto il = { 10, 20, 30 };  // the type of il is an initializer_list

這個類的本質是底層開一個數組,將數據拷貝過來std::initializer_list 內部有兩個指針分別指向數組的開始結束支持迭代器遍歷

這是它的文檔:initializer_list - C++ Reference?。

容器支持一個 std::initializer_list構造函數,也就支持任意多個值構成的初始化。STL 中的容器支持用 {x1, x2, x3...} 進行初始化,就是通過 std::initializer_list 的構造函數支持的。

// 標準庫中的聲明示例// vector 的 initializer_list 構造函數
vector(initializer_list<value_type> il, const allocator_type& alloc = allocator_type());// list 的 initializer_list 構造函數
list(initializer_list<value_type> il, const allocator_type& alloc = allocator_type());// map 的 initializer_list 構造函數
map(initializer_list<value_type> il,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// 自定義 vector 的簡化實現
template<class T>
class vector {
public:typedef T* iterator;  // 迭代器類型// initializer_list 構造函數vector(initializer_list<T> il) {for (auto& e : il) {  // 遍歷列表元素push_back(e);     // 逐個插入容器}}private:iterator _start = nullptr;        // 指向首元素iterator _finish = nullptr;       // 指向最后一個元素的下一個位置iterator _endofstorage = nullptr; // 指向存儲空間的末尾
};

#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;int main() {// 1. 測試 initializer_list 的基本特性std::initializer_list<int> mylist;mylist = {10, 20, 30};  // 初始化列表賦值// 輸出 initializer_list 的大小(通常是固定大小,包含兩個指針)cout << "sizeof(mylist): " << sizeof(mylist) << endl;// 2. 驗證 initializer_list 的存儲位置int i = 0;cout << "mylist.begin(): " << mylist.begin() << endl;  // 指向第一個元素cout << "mylist.end(): " << mylist.end() << endl;      // 指向末尾后一位cout << "&i: " << &i << endl;                          // 對比棧地址// 3. 容器的兩種初始化方式對比vector<int> v1({1, 2, 3, 4, 5});       // 直接構造(顯式 initializer_list)vector<int> v2 = {1, 2, 3, 4, 5};      // 隱式轉換(可能觸發拷貝優化)const vector<int>& v3 = {1, 2, 3, 4, 5}; // 引用臨時對象(生命周期延長)// 4. map 的嵌套初始化(pair + initializer_list)map<string, string> dict = {{"sort", "排序"}, {"string", "字符串"}};// 5. initializer_list 賦值操作v1 = {10, 20, 30, 40, 50};  // 調用 operator=(initializer_list)return 0;
}

總結一下:

C++11,基本實現了一切對象皆可初始化。?

2、lambda

2.1 lambda的語法

lambda 表達式本質是一個匿名函數對象,跟普通函數不同的是它可以定義在函數內部
lambda 表達式語法層面而言沒有類型,所以我們一般是用auto或者模板參數定義的對象去接收。

lambda 表達式格式

[capture-list] (parameters) -> return type { function body }

[capture-list]捕捉列表編譯器根據 [ ] 判斷是否為 lambda 函數捕捉列表能夠捕捉上下文中的變量供 lambda 函數使用,捕捉列表可以傳值傳引用捕捉,具體細節在 2.2 中我們再細講。捕捉列表為空?[ ] 也不能省略

(parameters)參數列表,與普通函數的參數列表功能類似,如果不需要參數傳遞,則可以連同( )一起省略

-> return type返回值類型,用追蹤返回類型形式(允許將函數的返回類型放在參數列表之后(用->引導))聲明函數的返回值類型沒有返回值時此部分可省略。一般返回值類型明確情況下,也可省略,由編譯器對返回類型進行推導

{ function body }函數體,函數體內的實現跟普通函數完全類似,在該函數體內,除了可以使用其參數外,還可以使用所有捕獲到的變量函數體為空{ }也不能省略

#include <iostream>
using namespace std;int main() {// 1. 一個簡單的lambda表達式auto add1 = [](int x, int y)->int { return x + y; };cout << add1(1, 2) << endl;  // 輸出: 3/* Lambda表達式特性說明:1. 捕捉列表為空也不能省略(必須寫[])2. 參數列表為空可以省略(如func1示例)3. 返回值可以省略,可以通過返回對象自動推導4. 函數體不能省略*/// 2. 無參數、無顯式返回類型的lambdaauto func1 = [] {cout << "hello bit" << endl;return 0;};func1();  // 輸出: hello bit// 3. 通過引用修改外部變量int a = 0, b = 1;        auto swap1 = [](int& x, int& y) {int tmp = x;x = y;y = tmp;};swap1(a, b);cout << a << ":" << b << endl;  // 輸出: 1:0return 0;
}

2.2 捕捉列表

Lambda 表達式的變量捕捉規則

在?lambda?表達式中,默認只能使用?lambda 函數體和參數中的變量。如果想使用外層作用域中的變量,就需要進行捕捉。

第一種捕捉方式:顯式捕捉

在捕捉列表中顯式指定?傳值捕捉?和?傳引用捕捉,多個變量用逗號分隔。

[x, y, &z] 表示 x y?值捕捉z?引用捕捉

第二種捕捉方式:隱式捕捉

[=]?表示?隱式值捕捉[&] 表示?隱式引用捕捉

lambda 表達式中使用了哪些變量,編譯器就會自動捕捉哪些變量。即按需捕捉

第三種捕捉方式:混合捕捉

在捕捉列表中?混合使用隱式捕捉和顯式捕捉

[=, &x]?表示其他變量?隱式值捕捉x?引用捕捉

[&, x, y] 表示其他變量?隱式引用捕捉x?y?值捕捉

混合捕捉規則:

  • 第一個元素必須是 &?=

  • &?混合捕捉時,后面的捕捉變量必須是?值捕捉

  • =?混合捕捉時,后面的捕捉變量必須是?引用捕捉


Lambda 表達式的變量作用域規則

  • 如果?lambda 表達式定義在函數局部作用域,它可以捕捉?lambda 位置之前定義的局部變量,但不能捕捉?靜態局部變量?和?全局變量(它們可以直接使用,無需捕捉)。

  • 如果?lambda 表達式定義在全局位置,捕捉列表必須為空(不能捕捉任何變量)一般也不會定義在全局。


Lambda 的 const 性和 mutable 修飾

  • 默認情況下,傳值捕捉是被?const ?修飾的,即?傳值捕捉的變量不能修改引用捕捉沒有const修飾

  • 使用?mutable 修飾符(加在參數列表后面)可以取消?const 限制,使?傳值捕捉的變量可以修改(但修改的是形參不影響實參)。

  • 使用?mutable 后,參數列表()不可省略(即使參數為空)

#include <iostream>
using namespace std;int x = 0; // 全局變量// 全局lambda的捕捉列表必須為空(全局變量可直接使用,無需捕捉)
auto func_global = []() {x++; // 直接修改全局變量
};int main() {// 局部變量int a = 0, b = 1, c = 2, d = 3;// 1. 顯式捕捉:值捕捉a,引用捕捉bauto func1 = [a, &b] {// a++;  // 錯誤:值捕捉的變量默認const,不可修改b++;    // 正確:引用捕捉可修改return a + b;};cout << func1() << endl;// 2. 隱式值捕捉(=):自動捕捉所有使用的局部變量(a,b,c)auto func2 = [=] {return a + b + c; // d未使用,不會被捕捉};cout << func2() << endl;// 3. 隱式引用捕捉(&):自動引用捕捉所有修改的變量auto func3 = [&] {a++; c++; d++; // 全部通過引用修改};func3();cout << a << " " << b << " " << c << " " << d << endl;// 4. 混合捕捉1:默認引用捕捉,顯式值捕捉a,bauto func4 = [&, a, b] {// a++; b++;  // 錯誤:a,b是值捕捉c++; d++;     // 正確:其他變量隱式引用捕捉return a + b + c + d;};func4();cout << a << " " << b << " " << c << " " << d << endl;// 5. 混合捕捉2:默認值捕捉,顯式引用捕捉a,bauto func5 = [=, &a, &b] {a++; b++;     // 正確:a,b是引用捕捉// c++; d++;  // 錯誤:其他變量隱式值捕捉return a + b + c + d;};func5();cout << a << " " << b << " " << c << " " << d << endl;// 6. 靜態/全局變量無需捕捉static int m = 0;auto func6 = [] {return x + m; // 直接使用全局和靜態變量};// 7. mutable修飾:允許修改值捕捉的副本(不影響外部變量)auto func7 = [=]() mutable {a++; b++; c++; d++; // 修改的是內部副本return a + b + c + d;};cout << func7() << endl;   // 輸出副本修改后的值cout << a << " " << b << " " << c << " " << d << endl; // 原變量不變return 0;
}

2.3 lambda的應用

在學習 lambda 表達式之前,我們使用的可調用對象只有函數指針仿函數對象函數指針
類型定義起來比較麻煩仿函數定義一個類,相對會比較麻煩。使用 lambda 去定義可調用對象,既簡單方便

lambda 在很多其他地方用起來也很好用。比如線程中定義線程的執行函數邏輯,智能指針中定
制刪除器等,lambda 的應用還是很廣泛的,以后我們會不斷接觸到。

struct Goods
{string _name;  // 名字double _price; // 價格int _evaluate; // 評價// ...Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){}
};struct ComparePriceLess
{bool operator()(const Goods& gl, const Goods& gr){return gl._price < gr._price;}
};struct ComparePriceGreater
{bool operator()(const Goods& gl, const Goods& gr){return gl._price > gr._price;}
};int main()
{vector<Goods> v = { { "蘋果", 2.1, 5 }, { "?蕉", 3, 4 }, { "橙?", 2.2, 3 }, { "菠蘿", 1.5, 4 } };// 類似這樣的場景,我們實現仿函數對象或者函數指針支持商品中// 不同項的?較,相對還是?較?煩的,那么這? lambda 就很好?了sort(v.begin(), v.end(), ComparePriceLess());sort(v.begin(), v.end(), ComparePriceGreater());sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._price < g2._price;});sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._price > g2._price; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._evaluate < g2._evaluate;});sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {return g1._evaluate > g2._evaluate;});return 0;
}

2.4 lambda的原理

lambda原理范圍 for 相似,編譯后從匯編指令層的角度看,壓根就沒有 Lambda 和范圍 for 這樣的東西。范圍 for 底層是迭代器,而 lambda 底層是仿函數對象,也就是說我們寫了一個 lambda 以后,編譯器會生成一個對應的仿函數的類

仿函數的類名編譯器按一定規則生成的保證不同的 lambda 生成的類名不同

lambda 參數 / 返回類型 / 函數體就是仿函數 operator () 的參數 / 返回類型 / 函數體

lambda捕捉列表本質是初始化?仿函數類的成員變量,也就是說捕捉列表的變量都是 lambda 類構造函數的實參,當然隱式捕捉時,編譯器要看使用哪些就傳哪些對象

上面的原理,我們可以透過匯編層了解一下,下面第二段匯編層代碼印證了上面的原理。

class Rate
{
public:Rate(double rate) : _rate(rate){}double operator()(double money, int year){return money * _rate * year;}private:double _rate;
};int main()
{double rate = 0.49;// lambda 表達式auto r2 = [rate](double money, int year) {return money * rate * year;};// 函數對象(仿函數)Rate r1(rate);r1(10000, 2);  // 調用仿函數r2(10000, 2);  // 調用 lambda// 無參 lambdaauto func1 = [] {cout << "hello world" << endl;};func1();  // 調用無參 lambdareturn 0;
}
// lambda 表達式
auto r2 = [rate](double money, int year) {return money * rate * year;
};// 捕捉列表的 `rate`,可以看到作為 `lambda_1` 類構造函數的參數傳遞了,
// 這樣在初始化成員變量后,才能在下面的 operator() 中使用
// 
// 匯編代碼片段:
// 00D8295C  lea         eax,[rate]  
// 00D8295F  push        eax  
// 00D82960  lea         ecx,[r2]  
// 00D82963  call        `main'::`2'::<lambda_1>::<lambda_1> (0D81F80h)  // 函數對象(仿函數)
Rate r1(rate);
// 匯編代碼片段:
// 00D82968  sub         esp,8  
// 00D8296B  movsd       xmm0,mmword ptr [rate]  
// 00D82970  movsd       mmword ptr [esp],xmm0  
// 00D82975  lea         ecx,[r1]  
// 00D82978  call        Rate::Rate (0D81438h)  r1(10000, 2);
// 匯編代碼片段:
// 00D8297D  push        2  
// 00D8297F  sub         esp,8  
// 00D82982  movsd       xmm0,mmword ptr [__real@40c3880000000000 (0D89B50h)]  
// 00D8298A  movsd       mmword ptr [esp],xmm0  
// 00D8298F  lea         ecx,[r1]  
// 00D82992  call        Rate::operator() (0D81212h)  // 從匯編層可以看到,r2(lambda 對象)的調用本質還是調用 operator(),
// 其類型是 `lambda_1`,這個類型名的規則由編譯器自定義,確保不同的 lambda 不沖突
r2(10000, 2);
// 匯編代碼片段:
// 00D82999  push        2  
// 00D8299B  sub         esp,8  
// 00D8299E  movsd       xmm0,mmword ptr [__real@40c3880000000000 (0D89B50h)]  
// 00D829A6  movsd       mmword ptr [esp],xmm0  
// 00D829AB  lea         ecx,[r2]  
// 00D829AE  call        `main'::`2'::<lambda_1>::operator() (0D824C0h)  

3、包裝器

3.1 function

1. std::function 是一個類模板,也是一個包裝器
2. std::function 實例對象可以包裝存儲其他的可調用對象,包括函數指針仿函數lambda 等,統一類型,存儲的可調用對象被稱為 std::function 的目標。若 std::function 不含目標,則稱它為空。調用空 std::function 的目標會導致拋出 std::bad_function_call 異常。

// 前置聲明(未定義的通用模板)
template <class T>
class function;  // undefined base template// 特化版本:支持函數類型簽名(返回類型 + 參數列表)
template <class Ret, class... Args>
class function<Ret(Args...)> {// 實現內容(此處未展開)// 通常包含 operator() 以支持函數調用
};

以上是 std::function 的原型,它被定義在 <functional> 頭文件中。

官方文檔:std::function - cppreference.com

#include <functional>
#include <iostream>
using namespace std;// 普通函數
int f(int a, int b) {return a + b;
}// 仿函數(函數對象)
struct Functor {int operator()(int a, int b) {return a + b;}
};// 類(包含靜態和非靜態成員函數)
class Plus {
public:Plus(int n = 10) : _n(n) {}// 靜態成員函數static int plusi(int a, int b) {return a + b;}// 非靜態成員函數(依賴 this 指針)double plusd(double a, double b) {return (a + b) * _n;}private:int _n;
};int main() {// 1. 包裝普通函數function<int(int, int)> f1 = f;cout << f1(1, 1) << endl;  // 輸出: 2// 2. 包裝仿函數對象function<int(int, int)> f2 = Functor();cout << f2(1, 1) << endl;  // 輸出: 2// 3. 包裝 lambda 表達式function<int(int, int)> f3 = [](int a, int b) { return a + b; };cout << f3(1, 1) << endl;  // 輸出: 2// 4. 包裝靜態成員函數(無需對象實例)function<int(int, int)> f4 = &Plus::plusi;cout << f4(1, 1) << endl;  // 輸出: 2// 5. 包裝非靜態成員函數(需綁定對象)Plus pd(10);  // _n = 10// 方式1:傳遞對象指針function<double(Plus*, double, double)> f5 = &Plus::plusd;cout << f5(&pd, 1.1, 1.1) << endl;  // 輸出: (1.1 + 1.1) * 10 = 22// 方式2:傳遞對象值(拷貝)function<double(Plus, double, double)> f6 = &Plus::plusd;cout << f6(pd, 1.1, 1.1) << endl;    // 輸出: 22// 方式3:傳遞右值引用function<double(Plus&&, double, double)> f7 = &Plus::plusd;cout << f7(move(pd), 1.1, 1.1) << endl;  // 輸出: 22cout << f7(Plus(10), 1.1, 1.1) << endl;  // 輸出: 22(臨時對象)return 0;
}

靜態成員函數不屬于對象,不需要傳this指針,非靜態成員函數需傳遞this指針,傳遞對象(會自行取對象地址)或對象地址。?

3.2 bind

1. 基本形式(自動推導返回類型)

template <class Fn, class... Args>
/* unspecified */ bind(Fn&& fn, Args&&... args);

2. 指定返回類型(C++14 起支持)

template <class Ret, class Fn, class... Args>
/* unspecified */ bind(Fn&& fn, Args&&... args);

bind 是一個函數模板,它也是一個可調用對象的包裝器,可以把它看做一個函數適配器(?封裝函數/可調用對象),對接收 的 fn 可調用對象進行處理返回一個可調用對象

bind 可以用來調整參數個數和參數順序。bind 也在<functional>這個頭文件中。

調用 bind 的一般形式: auto newCallable = bind(callable,arg_list); 其中 newCallable 本身是一個可調用對象arg_list 是一個逗號分隔參數列表對應給定的 callable參數。當我們調用 newCallable 時,newCallable 會調用 callable,并傳給它 arg_list 中的參數。

arg_list 中的參數可能包含形如 _n 的名字,其中 n 是一個整數,表示 newCallable參數。數值 n 表示生成的可調用對象中參數的位置:_1 newCallable第一個參數(無所謂_1的位置在哪)_2第二個參數,以此類推。_1/_2/_3.... 這些占位符 placeholders 的一個命名空間中。

#include <iostream>
#include <functional>// 定義一個減法函數,返回 (a - b) * 10
int Sub(int a, int b) {return (a - b) * 10;
}// 定義一個減法函數,返回 (a - b - c) * 10
int SubX(int a, int b, int c) {return (a - b - c) * 10;
}// 定義一個 Plus 類,包含靜態和非靜態的加法函數
class Plus {
public:// 靜態加法函數static int plusi(int a, int b) {return a + b;}// 非靜態加法函數double plusd(double a, double b) {return a + b;}
};int main() {// 使用 std::placeholders 命名空間中的占位符using namespace std::placeholders;// 綁定 Sub 函數,正常順序傳遞參數auto sub1 = std::bind(Sub, _1, _2);std::cout << sub1(10, 5) << std::endl;// 調整參數順序,交換 _1 和 _2 的位置auto sub2 = std::bind(Sub, _2, _1);std::cout << sub2(10, 5) << std::endl;// 調整參數個數,固定第一個參數為 100auto sub3 = std::bind(Sub, 100, _1);std::cout << sub3(5) << std::endl;// 調整參數個數,固定第二個參數為 100auto sub4 = std::bind(Sub, _1, 100);std::cout << sub4(5) << std::endl;// 分別綁死 SubX 函數的第 1、2、3 個參數auto sub5 = std::bind(SubX, 100, _1, _2);std::cout << sub5(5, 1) << std::endl;auto sub6 = std::bind(SubX, _1, 100, _2);std::cout << sub6(5, 1) << std::endl;auto sub7 = std::bind(SubX, _1, _2, 100);std::cout << sub7(5, 1) << std::endl;// 綁定 Plus 類的非靜態成員函數std::function<double(Plus&&, double, double)> f6 = &Plus::plusd;Plus pd;std::cout << f6(std::move(pd), 1.1, 1.1) << std::endl;std::cout << f6(Plus(), 1.1, 1.1) << std::endl;// 使用 std::bind 綁定 Plus 類的非靜態成員函數,固定對象std::function<double(double, double)> f7 = std::bind(&Plus::plusd, Plus(), _1, _2);std::cout << f7(1.1, 1.1) << std::endl;// 定義一個計算復利的 lambda 函數auto func1 = [](double rate, double money, int year) -> double {double ret = money;for (int i = 0; i < year; i++) {ret += ret * rate;}return ret - money;};// 綁死一些參數,實現支持不同年利率、不同金額和不同年份計算復利的結算利息std::function<double(double)> func3_1_5 = std::bind(func1, 0.015, _1, 3);std::function<double(double)> func5_1_5 = std::bind(func1, 0.015, _1, 5);std::function<double(double)> func10_2_5 = std::bind(func1, 0.025, _1, 10);std::function<double(double)> func20_3_5 = std::bind(func1, 0.035, _1, 30);std::cout << func3_1_5(1000000) << std::endl;std::cout << func5_1_5(1000000) << std::endl;std::cout << func10_2_5(1000000) << std::endl;std::cout << func20_3_5(1000000) << std::endl;return 0;
}    

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

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

相關文章

【微知】Mellanox網卡網線插入后驅動的幾個日志?(Cable plugged;IPv6 ... link becomes ready)

概要 本文是一個簡單的信息記錄。記錄的是當服務器網卡的光模塊插入后內核的日志打印。通過這種日志打印&#xff0c;可以在定位分析問題的時候&#xff0c;知道進行過一次模塊插拔。 日志 截圖版&#xff1a; 文字版&#xff1a; [32704.121294] mlx5_core 0000:01:00.0…

單片機Day05---靜態數碼管

目錄 一、原理圖&#xff1a;?編輯 二、思路梳理&#xff1a; 三&#xff1a;一些說明&#xff1a; 1.點亮方式&#xff1a; 2.數組&#xff1a; 3.數字與段碼對應&#xff1a; 四&#xff1a;程序實現&#xff1a; 一、原理圖&#xff1a; 二、思路梳理&#xff1a; …

Cesium.js(6):Cesium相機系統

Camera表示觀察場景的視角。通過操作攝像機&#xff0c;可以控制視圖的位置、方向和角度。 幫助文檔&#xff1a;Camera - Cesium Documentation 1 setView setView 方法允許你指定相機的目標位置和姿態。你可以通過 Cartesian3 對象來指定目標位置&#xff0c;并通過 orien…

【Python技術生態全景:十大核心應用領域深度解析】

目錄 前言&#xff1a;Python的統治力一、基礎應用領域1. Web開發數據科學 二、前沿技術領域機器學習深度學習 三、行業解決方案量化金融生物信息 四、創新應用方向物聯網開發區塊鏈開發 五、效率工具生態自動化運維游戲開發 結語&#xff1a;Python的邊界與突破技術局限未來演…

leetcode 2787. Ways to Express an Integer as Sum of Powers

題目描述 這道題是0-1背包問題。可以理解為&#xff0c;有一個最大容量是n的背包&#xff0c;有n個物品&#xff0c;第i個物品的重量是i^x&#xff0c;問裝滿背包有多少種裝法。題目要求必須是互不相同的數的x次冪的和等于n&#xff0c;那就表示每個數只能用一次&#xff0c;也…

面試經驗分享 | 成都滲透測試工程師二面面經分享

可以看看我的置頂文章和專欄找我哦 概況 面試過程 面試官的問題 問題1、你覺得當前OAuth2.0下的攻擊手段有哪些&#xff1f;結合具體案例詳細講講 問題2、php/java反序列化漏洞的原理?程序員/運維如何避免此類漏洞或如何防御? 問題3、如果一臺服務器被入侵后,你會如何做應急…

模仿axios的封裝效果來封裝fetch,實現baseurl超時等

因為要在cocos游戲項目里面發送網絡請求獲取數據&#xff0c;并且還有可能用到websocket發送請求&#xff0c;所以這里封裝一個fetch放便使用&#xff1a; // fetch封裝// 基礎配置 const BASE_URL 你的url const TIMEOUT 5000// 請求封裝 const http async (url: string, …

小米運維面試題及參考答案(80道面試題)

請講解一下 linux top 后進程的狀態 在 Linux 系統中,使用top命令可以查看系統中正在運行的進程的相關信息,進程通常有以下幾種狀態: 運行(R):表示進程正在 CPU 上運行或者正在運行隊列中等待運行。處于運行狀態的進程正在積極地使用 CPU 資源來執行其任務。睡眠(S):進…

a sort.py demo

這份代碼展示了如何使用 sort.py。注意&#xff0c;此處&#xff0c;我將文件名改為 my_sort.py。 你并不能直接 copy 使用&#xff0c;因為環境&#xff0c;包&#xff0c;還有模型。 此處使用 SSD-MobileNetv2 進行物體檢測&#xff0c;將結果傳入以 np 數組的形式傳入sort…

使用Redis解決:集群的Session共享問題

使用Redis解決&#xff1a;集群的Session共享問題 session共享問題&#xff1a;多臺Tomcat并不共享session存儲空間&#xff0c;當請求切換到不同的tomcat服務時導致數據丟失的問題。 問題背景 ?無狀態HTTP協議&#xff1a;HTTP協議本身是無狀態的&#xff0c;服務器無法直接識…

Linux 內核知識體系[1]

1 Linux內核知識體系 2.Linux內核學習路線 2.1基礎知識準備 操作系統基礎&#xff1a;了解操作系統的概念和基本原理&#xff0c;包括進程管理、內存管理、文件系統、輸入輸出等。 書籍&#xff1a;《操作系統&#xff1a;設計與實現》&#xff08;Andrew S. Tanenbaum&…

KiActivateWaiterQueue函數和Queue->Header.WaitListHead隊列等待列表的關系

第一部分&#xff1a; if (Thread->ApcState.KernelApcPending && (Thread->SpecialApcDisable 0) && (Thread->WaitIrql < APC_LEVEL)) { } else { // // Insert wait block in ob…

讓DeepSeek API支持聯網搜索

引子 DeepSeek官網注冊的API token是不支持聯網搜索的&#xff0c;這導致它無法輔助分析一些最新的情況或是幫忙查一下互聯網上的資料。本文從實戰角度提供一種穩定可靠的方法使得DeepSeek R1支持聯網搜索分析。 正文 首先登錄火山方舟控制臺&#xff0c;https://www.volcen…

生物信息Rust-01

前言-為什么想學Rust&#xff1f; 一直想多學一門編譯語言&#xff0c;主要有幾個原因吧&#xff08;1. 看到一位老師實驗室要求需要掌握一門編譯語言&#xff1b;2. 自己享想試著開發一些實用的生信工具&#xff0c;感覺自己現在相比于數據分析&#xff0c;探索生物學層面的意…

字符串與相應函數(上)

字符串處理函數分類 求字符串長度&#xff1a;strlen長度不受限制的字符串函數&#xff1a;strcpy,strcat,strcmp長度受限制的字符串函數:strncpy,strncat,strncmp字符串查找&#xff1a;strstr,strtok錯誤信息報告&#xff1a;strerror字符操作&#xff0c;內存操作函數&…

asm匯編源代碼之文件操作相關

提供7個子程序:   1. 關閉文件 FCLOSE   2. 打開文件 FOPEN   3. 文件大小 FSIZE   4. 讀文件 FREAD   5. 寫文件 FWRITE   6. 建立文件 FCREATE   7. 讀取或設置文件指針 FPOS 具體功能及參數描述如下 ; ---------------------------- FCLOSE PROC  FAR ; IN…

[Dify] 使用 Docker 本地部署 Dify 并集成 Ollama 模型的詳細指南

在 AI 應用快速發展的今天&#xff0c;開源項目如 Dify 正成為構建本地化 AI 應用的利器。通過 Dify&#xff0c;你可以輕松地集成不同的大語言模型&#xff08;LLM&#xff09;&#xff0c;如 Ollama&#xff0c;并快速創建可交互的 AI 應用。本篇文章將帶你一步步通過 Docker…

Spring Boot 測試詳解,包含maven引入依賴、測試業務層類、REST風格測試和Mock測試

Spring Boot 測試詳解 1. 測試依賴引入 Spring Boot 默認通過以下 Maven 依賴引入測試工具&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</s…

DevOps與功能安全:Perforce ALM通過ISO 26262合規認證,簡化安全關鍵系統開發流程

本文來源perforce.com&#xff0c;由Perforce中國授權合作伙伴、DevSecOps解決方案提供商-龍智翻譯整理。 近日&#xff0c;Perforce ALM&#xff08;原Helix ALM&#xff09;通過了國際權威認證機構 TV SD的ISO 26262功能安全流程認證&#xff01;該認證涵蓋Perforce ALM解決方…

Android11車載WiFi熱點默認名稱及密碼配置

一、背景 基于車廠信息安全要求,車載熱點默認名稱不能使用統一的名稱,以及默認密碼不能為簡單的1~9。 基于舊項目經驗,組裝工廠自動化測試及客戶整車組裝的時候均存在多臺設備同時打開,亦不太推薦使用統一的熱點名稱,連接無法區分。 二、需求 根據客戶的要求,默認名稱…