6.8 note

paxos算法_初步感知

Paxos算法保證一致性主要通過以下幾個關鍵步驟和機制:

?

準備階段

?

- 提議者向所有接受者發送準備請求,請求中包含一個唯一的編號。

?

- 接受者收到請求后,會檢查編號,如果編號比它之前見過的都大,就會承諾不再接受編號更小的提議,并回復提議者,告知自己已接受過的最大編號的提議。

?

提議階段

?

- 提議者收到多數接受者的回復后,根據回復內容來確定提議的值。如果有接受者在回復中包含了已接受的提議值,提議者就從中選擇編號最大的提議值作為自己要提議的值;如果沒有,提議者就自己選擇一個值。然后,提議者將選定的值和編號一起作為提議發送給接受者。

?

- 接受者收到提議后,只有在之前沒有承諾過不接受該提議,并且提議的編號不小于它之前見過的最大編號時,才會接受該提議。

?

學習階段

?

- 一旦有多數接受者接受了某個提議,這個提議就被認為是達成了一致。此時,系統中的其他節點可以通過學習這個已達成一致的提議來更新自己的狀態,從而保證整個系統的一致性。

?

通過這一系列的步驟,Paxos算法能夠在分布式系統中,即使存在節點故障、消息丟失等情況,也能保證最終達成一致的狀態,確保數據的一致性和正確性


舉個栗子🌰

假設你和一群朋友打算一起去看電影,但是對于看哪部電影大家有不同的想法,這時就可以用類似Paxos算法的方式來達成一致:
?
準備階段
?
- 你主動站出來成為“提議者”,你先給每個朋友發消息說:“我準備提議看一部電影,我現在的提議編號是1(這個編號是唯一且不斷遞增的),你們之前有沒有收到過其他人的提議呀?如果有,是關于看什么電影的,編號是多少呢?”
?
- 朋友們收到消息后,會查看自己收到過的提議編號。如果你的編號比他們之前收到的都大,他們就會回復你,比如有的朋友會說:“我之前沒收到過提議。”有的朋友可能會說:“我之前收到過提議看電影A,編號是0。”同時,他們會承諾不再接受編號小于1的提議。
?
提議階段
?
- 你收到朋友們的回復后,發現有朋友提到了之前看過的提議看電影A,編號是0,而你的編號是1更大,所以你可以選擇自己重新提議看電影B,也可以選擇就提議看電影A。然后你把你的提議(比如看電影B,編號是1)發給朋友們。
?
- 朋友們收到你的提議后,會檢查這個提議的編號是不是不小于他們之前見過的最大編號,并且他們之前沒有承諾過不接受這個提議。如果滿足條件,他們就會接受這個提議,比如同意一起去看電影B。
?
學習階段
?
- 當有超過一半的朋友都接受了看電影B這個提議,那么就相當于大家達成了一致,決定一起去看電影B。然后大家就可以一起去看電影,保證了所有人的行動一致。
?
在這個過程中,即使有朋友一開始沒收到消息,或者中間有消息延遲等情況,只要最終大家都按照這個流程來,就能保證最終能就看哪部電影達成一致,就像Paxos算法在分布式系統中保證數據一致性一樣。


Paxos算法這樣的一致性算法的設計思路是基于對分布式系統中一致性問題的深刻理解和長期的研究探索逐漸形成的,主要考慮以下幾個方面:

?

問題分析

- 分布式系統中存在節點故障、網絡延遲、消息丟失等問題,要保證數據在多個節點間的一致性,需要設計一種能在復雜環境下達成共識的機制。

- 借鑒現實生活中類似議會投票等協商場景的經驗,思考如何通過類似的投票、協商過程讓分布式系統中的節點就某個值達成一致。

?

關鍵原則確定

- 安全性原則是確保只有被多數節點認可的值才能被選定,防止出現不一致的情況。就像在選舉中,只有獲得多數選票的候選人才能當選,保證結果的唯一性和確定性。

- 活性原則是保證系統能夠不斷推進,不會因為某些故障或異常而陷入死循環或無法做出決策的狀態。例如,通過給提議編號等方式,讓系統能夠區分不同的提議,避免重復或無效的提議導致系統停滯。

?

逐步構建算法

- 先設計準備階段,讓提議者了解系統中已有的提議情況,同時讓接受者承諾不接受低編號提議,為后續提議的順利進行奠定基礎。這一步就像在會議前先收集各方意見,確定大家的基本立場。

- 再設計提議階段,提議者根據準備階段的反饋確定提議值并發送給接受者,接受者根據一定規則決定是否接受提議。這個過程類似會議中的討論和表決環節。

- 最后通過學習階段,讓系統中的其他節點能夠得知達成一致的結果,從而實現整個系統的一致性更新。

?

通過這樣從問題分析到關鍵原則確定,再到逐步構建算法的過程,經過不斷地理論推導、實踐驗證和優化,最終形成了Paxos算法這種能夠有效保證分布式系統一致性的經典算法。

?

?

rabbitmq 6種模式

?

sql連接

?select p.FirstName,p.LastName,a.City,a.State
from
person p left join address a
on
p.personid=a.personid

?

2的冪再和,二進制取模相加==n

?1.?分解n為2的冪次:
?
- 利用二進制特性,n的每一位1對應一個唯一的2的冪次(如n=10=8+2=23+21,對應powers=[2,8])。
?
- 通過不斷對n取余和整除2,提取每一位二進制位,將對應的冪次存入?powers?數組。
?
2.?處理查詢:
?
- 每個查詢給出一個區間?[l, r]?,表示求?powers[l] * powers[l+1] * ... * powers[r]?的結果。
?
- 由于結果可能很大,每次乘法后都對?1e9+7?取模(利用模運算性質防止溢出)。
?
3.?注意點:
?
- 使用?long long?存儲中間結果,避免整數溢出。
?
- ?powers?數組的下標直接對應查詢中的區間端點(如查詢?[0,2]?表示取前3個冪次相乘)。
?
示例理解:

  • - 若?n=15?(二進制?1111?),則?powers = [1,2,4,8]?。
  • - 查詢?[0,2]?對應計算?1*2*4=8?,查詢?[1,3]?對應?2*4*8=64?。

class Solution {
public:
? ? vector<int> productQueries(int n, vector<vector<int>>& queries) {
? ? ? ? // 造powers數組
? ? ? ? vector<int> powers;
? ? ? ? // 由n變到1powers數組
? ? ? ? for(int i=0,i1=1,j=0;n>0;)
? ? ? ? {
? ? ? ? ? ? i=n%2;
? ? ? ? ? ? if(i==1) {powers.push_back(i1);j++;}
? ? ? ? ? ? n/=2;i1*=2;

? ? ? ? }
? ? ? ? // return powers;
? ? ? ? // 造answers數組
? ? ? ? vector<int> answers;
? ? ? ? for(int i=0; i<queries.size(); i++)
? ? ? ? {
? ? ? ? ? ? long long ans=1;
? ? ? ? ? ? int c=1e7;
? ? ? ? ? ? for(int k=queries[i][0]; k<=queries[i][1]; k++)
? ? ? ? ? ? {ans=((ans%c)*(powers[k]%c))%c;}

? ? ? ? ? ? ?//求區間乘積
? ? ? ? ? ? //利用了(a*b)%c=((a%c)*(b%c))%c 拆分取模,防止溢出
? ? ? ? ? ? answers.push_back(ans);
? ? ? ? }
? ? ? ? return answers;
? ? }
};

?

爬樓梯

class Solution {
public:
? ? int climbStairs(int n)?
? ? {
? ? ? ? if(n<3) return n;
? ? ? ? vector<int> dp(n+1);
? ? ? ? dp[1]=1,dp[2]=2;
? ? ? ??
? ? ? ? for(int i=3;i<=n;i++)
? ? ? ? {
? ? ? ? ? ? dp[i]=dp[i-1]+dp[i-2];
? ? ? ? }
? ? ? ? return dp[n];
? ? }
};

接雨水

這段代碼用「棧」來計算接雨水的量,核心邏輯是:

從左到右遍歷每個柱子,用棧記錄「可能成為左邊邊界」的柱子下標。

當遇到更高的柱子(右邊界)時計算兩者之間的「凹槽儲水量」:

?

1.?彈出棧頂(中間柱子),若棧空則無法形成凹槽,跳過。

2.?確定左右邊界:新棧頂是左邊界,當前下標是右邊界。

3.?計算高度差:左右邊界的最小值 - 中間柱子高度,得到儲水高度。

4.?計算寬度:右邊界下標 - 左邊界下標 - 1,乘高度得到水量,累加到結果。

?

舉例:柱子高度為 ?[0,1,0,2,1,0,1,3,2,1,2,1]?,

遍歷到 ?i=3?(高度2)時,棧中是 ?[0,1]?(高度0,1),

彈出1(高度1),左邊界是0(高度0),右邊界是3(高度2),

儲水高度 = min(0,2) - 1 = -1?不,這里實際是 min(左邊界高度, 右邊界高度) - 中間高度,

左邊界高度是 ?height[0]=0?,右邊界是 ?height[3]=2?,中間是 ?height[1]=1?,

所以儲水高度是 0-1?不對! 哦這里發現描述有誤,正確邏輯是:只有左右邊界都高于中間柱子時才有儲水,

所以當右邊界高度 > 中間柱子時,左邊界必須存在且高度 > 中間柱子,

此時儲水高度 = min(左邊界高度, 右邊界高度) - 中間高度,

寬度是右邊界下標 - 左邊界下標 - 1。

?

代碼通過棧動態維護左右邊界,逐個計算每個凹槽的水量,最終總和就是答案。

?

int trap(vector<int>& height)
{
? ? int ans = 0;
? ? stack<int> st;
? ? for (int i = 0; i < height.size(); i++)
? ? {
? ? ? ? while (!st.empty() && height[st.top()] < height[i])
? ? ? ? {
? ? ? ? ? ? int cur = st.top();
? ? ? ? ? ? st.pop();
? ? ? ? ? ? if (st.empty()) break;
? ? ? ? ? ? int l = st.top();
? ? ? ? ? ? int r = i;
? ? ? ? ? ? int h = min(height[r], height[l]) - height[cur];
? ? ? ? ? ? ans += (r - l - 1) * h;
? ? ? ? }
? ? ? ? st.push(i);
? ? }
? ? return ans;
}

雙指針


?

?class Solution {

public:

? ? int trap(vector<int>& height) {

? ? ? ? int ans = 0, left = 0, right = height.size() - 1, pre_max = 0, suf_max = 0;

? ? ? ? while (left < right) {

? ? ? ? ? ? pre_max = max(pre_max, height[left]);

? ? ? ? ? ? suf_max = max(suf_max, height[right]);

? ? ? ? ? ? ans += pre_max < suf_max ? pre_max - height[left++] : suf_max - height[right--];

? ? ? ? }

? ? ? ? return ans;

? ? }

};

?

dfs超時優化

注意到 十的九次方?

原代碼,超時

class Solution {
public:
? ? int n=0;
? ? vector<int> ans;

? ? int findKthNumber(int n, int k)?
? ? {
? ? ? ? this->n=n;
? ? ? ? for(int i=1;i<10;i++)
? ? ? ? {
? ? ? ? ? ? dfs(i);
? ? ? ? }
? ? ? ?
? ? ? ? return ans[k-1];
? ? }
? ??
? ? void dfs(int num)
? ? ? ? {
? ? ? ? ? ? if(num>n)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ??
? ? ? ? ? ? ans.push_back(num);
? ? ? ? ? ? for(int i=0;i<10;i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? dfs(num*10+i);
? ? ? ? ? ? }
? ? ? ? }
};

數學優化

class Solution {
public:
? ? long getCount(long prefix, long n) {
? ? ? ? long cur = prefix;
? ? ? ? long next = cur + 1;
? ? ? ? long count = 0;
? ? ? ? while(cur <= n) {
? ? ? ? ? ? count += min(n+1, next) - cur;
? ? ? ? ? ? cur *= 10;
? ? ? ? ? ? next *= 10;
? ? ? ? }
? ? ? ? return count;
? ? }

? ? int findKthNumber(int n, int k) {
? ? ? ? long p = 1;
? ? ? ? long prefix = 1;
? ? ? ? while(p < k) {
? ? ? ? ? ? long count = getCount(prefix, n);
? ? ? ? ? ? if (p + count > k) {
? ? ? ? ? ? ? ? /// 說明第k個數,在這個前綴范圍里面
? ? ? ? ? ? ? ? prefix *= 10;
? ? ? ? ? ? ? ? p++;

? ? ? ? ? ? } else if (p+count <= k) {
? ? ? ? ? ? ? ? /// 說明第k個數,不在這個前綴范圍里面,前綴需要擴大+1
? ? ? ? ? ? ? ? prefix++;
? ? ? ? ? ? ? ? p += count;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return static_cast<int>(prefix);
? ? }
};
?
優化思路:
?
1.?字典序規則:
像查字典一樣,先比首位,再比第二位。例如:
?

  • - 1開頭的數(1,10,11,12…)比2開頭的數(2,20,21…)更小。

?
2.?關鍵函數?getCount?:
計算以?prefix?(如1、10)開頭的數字有多少個≤n。
?

  • - 比如?prefix=1?,n=20時,包含1、10-19、20(共1+10+1=12個)。
  • - 計算方式:逐層擴展(1→10→100),每次算當前層有多少個數在n以內。

3.理解

- ?p++?是深入子節點找下一個數,
?
- ?p += count?是跳過當前前綴,去下一個前綴找。


十叉樹

把數字看作樹,用子樹大小判斷第k個數在左子樹還是右兄弟:
?

  • - 子樹夠大:鉆進左子樹(?node*=10?)。
  • - 子樹不夠大:跳過左子樹,去右兄弟(?node++?)。

通過這種方式,每次跳躍式減少k的范圍,效率極高(對數級時間復雜度)。

class Solution {
public:
? ? int findKthNumber(int n, int k) {
? ? ? ? // 逐層統計 node 子樹大小
? ? ? ? auto count_subtree_size = [&](int node) -> int {
? ? ? ? ? ? // 子樹大小不會超過 n,所以 size 用 int 類型
? ? ? ? ? ? // 但計算過程中的 left 和 right 會超過 int,所以用 long long 類型
? ? ? ? ? ? int size = 0;
? ? ? ? ? ? long long left = node, right = node + 1;
? ? ? ? ? ? while (left <= n) {
? ? ? ? ? ? ? ? // 這一層的最小值是 left,最大值是 min(right, n + 1) - 1
? ? ? ? ? ? ? ? size += min(right, n + 1LL) - left;
? ? ? ? ? ? ? ? left *= 10; // 繼續,計算下一層
? ? ? ? ? ? ? ? right *= 10;
? ? ? ? ? ? }
? ? ? ? ? ? return size;
? ? ? ? };

? ? ? ? int node = 1;
? ? ? ? k--; // 訪問節點 node
? ? ? ? while (k > 0) {
? ? ? ? ? ? int size = count_subtree_size(node);
? ? ? ? ? ? if (size <= k) { // 向右,跳過 node 子樹
? ? ? ? ? ? ? ? node++; // 訪問 node 右側兄弟節點
? ? ? ? ? ? ? ? k -= size; // 訪問子樹中的每個節點,以及新的 node 節點
? ? ? ? ? ? } else { // 向下,深入 node 子樹
? ? ? ? ? ? ? ? node *= 10; // 訪問 node 的第一個兒子
? ? ? ? ? ? ? ? k--; // 訪問新的 node 節點
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return node;
? ? }
};

?

線程

?

?模擬?貪心

要么都變成 1,要么都變成 -1,因此先枚舉要變成哪個。

剩下的問題就是一個經典的貪心。

由于乘以 -1 兩次之后會變回原數,因此每個下標最多選擇一次,且下標選擇的順序沒有關系。

不妨假設操作是從左到右進行的。

從左到右考慮每個下標,如果當前值不是目標值,由于后續操作只會影響右邊的數,再不操作就沒機會了,所以此時必須要選擇該下標。

按該貪心思路算出最少操作次數即可,復雜度 O(n) 。

思維題:想到傳遞的目標判斷即可

其實也還可以找奇偶的規律,但是還是這種更好

class Solution {
public:
? ? bool canMakeEqual(vector<int>& nums, int K) {
? ? ? ? int n = nums.size();

? ? ? ? // 所有值都變成 x 的最少操作次數
? ? ? ? auto check = [&](int x) {
? ? ? ? ? ? int cnt = 0;
? ? ? ? ? ? vector<int> vec = nums;
? ? ? ? ? ? // 從左到右考慮每個下標,如果不是目標值,必須操作
? ? ? ? ? ? for (int i = 0; i + 1 < n; i++) if (vec[i] != x) {
? ? ? ? ? ? ? ? vec[i] *= -1;
? ? ? ? ? ? ? ? vec[i + 1] *= -1;
? ? ? ? ? ? ? ? cnt++;
? ? ? ? ? ? }
? ? ? ? ? ? return vec[n - 1] == x && cnt <= K;
? ? ? ? };

? ? ? ? // 枚舉最后變成 1 還是 -1
? ? ? ? return check(1) || check(-1);

? ? }
};

總結:

1.?枚舉目標:結果只有兩種可能——全 ?1??或者全 ?-1??。所以我們分別試試這兩種情況,看哪種能實現(這就是 “枚舉” ,把可能的目標全列出來試)。
?
2.?貪心操作:確定目標(比如要全 ?1??)后,怎么操作最省次數?
?
- 規則是 “選一個下標 ?i??,?nums[i]??和 ?nums[i+1]??都變號” 。而且變號兩次等于沒變(比如 ?1??變 ?-1??再變 ?1??),所以每個位置最多操作一次,從左到右處理最合理 。
?
- 舉個例子:數字是 ?[-1, -1, 1]??,目標要全 ?1??。從左開始看,第一個數是 ?-1??(不是目標 ?1??),必須操作下標 ?0??,讓 ?nums[0]??和 ?nums[1]??變號,變成 ?[1, 1, 1]??,這樣一次就解決。如果不操作當前下標,后面操作不影響前面,就永遠變不成目標了,所以 “遇到不一樣的,必須當下操作” ,這就是貪心的 “貪”—— 抓住當下機會,保證結果最優。

?

移動模擬_優化

原代碼

class Solution {
public:
? ? int N;
? ? void move(char c, vector<int>& pos, vector<int>& t) {
? ? ? ? if (c == 'L') pos[1] -= 1;
? ? ? ? if (c == 'R') pos[1] += 1;
? ? ? ? if (c == 'U') pos[0] -= 1;
? ? ? ? if (c == 'D') pos[0] += 1; ? ? ? ?
? ? ? ? t = pos;
? ? }
? ? bool check(vector<int>& pos) {
? ? ? ? if (pos[0] >= 0 && pos[0] < N && pos[1] >= 0 && pos[1] < N) return true;
? ? ? ? else return false;
? ? }
? ? vector<int> executeInstructions(int n, vector<int>& startPos, string s) {
? ? ? ? vector<int> res(s.size());
? ? ? ? N = n;
? ? ? ? for (int i = 0; i < s.size(); i ++ ) {
? ? ? ? ? ? vector<int> tempos(startPos);
? ? ? ? ? ? int temres = 0;
? ? ? ? ? ? for (int j = i; j < s.size(); j ++ ) {
? ? ? ? ? ? ? ? vector<int> t(2);
? ? ? ? ? ? ? ? move(s[j], tempos, t); ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? if (check(t)) temres ++ ,tempos = t;

? ? ? ? ? ? ? ? else break;
? ? ? ? ? ? }
? ? ? ? ? ? res[i] = temres;
? ? ? ? }
? ? ? ? return res;
? ? }
};

優化:

改用迭代器并內聯函數的 C++ 代碼(主要修改循環和容器操作部分):

class Solution {

public:

? ? int N;

? ? // 內聯移動函數(用引用避免拷貝)

? ? inline void move(char c, vector<int>& pos, vector<int>& t) {

? ? ? ? switch(c) {

? ? ? ? ? ? case 'L': pos[1]--; break;

? ? ? ? ? ? case 'R': pos[1]++; break;

? ? ? ? ? ? case 'U': pos[0]--; break;

? ? ? ? ? ? case 'D': pos[0]++;?

? ? ? ? }

? ? ? ? t = pos; // 更新目標位置

? ? }

? ? // 內聯邊界檢查

? ? inline bool check(const vector<int>& pos) {

? ? ? ? return pos[0] >= 0 && pos[0] < N && pos[1] >= 0 && pos[1] < N;

? ? }

?

? ? vector<int> executeInstructions(int n, vector<int>& startPos, string s) {

? ? ? ? vector<int> res(s.size());

? ? ? ? N = n;

? ? ? ??

? ? ? ? // 使用迭代器遍歷字符串

? ? ? ? for(auto it_i = s.begin(); it_i != s.end(); ++it_i) {

? ? ? ? ? ? vector<int> currentPos = startPos;

? ? ? ? ? ? int count = 0;

? ? ? ? ? ??

? ? ? ? ? ? // 從當前迭代器位置開始遍歷

? ? ? ? ? ? for(auto it_j = it_i; it_j != s.end(); ++it_j) {

? ? ? ? ? ? ? ? vector<int> tempPos(2);

? ? ? ? ? ? ? ? move(*it_j, currentPos, tempPos); // 傳入字符值

? ? ? ? ? ? ? ??

? ? ? ? ? ? ? ? if(check(tempPos)) {

? ? ? ? ? ? ? ? ? ? count++;

? ? ? ? ? ? ? ? ? ? currentPos = tempPos; // 更新當前位置

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? break; // 越界則終止

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? res[it_i - s.begin()] = count; // 計算索引

? ? ? ? }

? ? ? ? return res;

? ? }

};

?

主要改動點:?

1.?函數內聯:使用 ?inline? 關鍵字聲明 ?move? 和 ?check? 函數(現代編譯器可能自動優化,但顯式聲明更清晰)

?

2.?迭代器替代索引:

- 外層循環用 ?s.begin()?/?end()? 迭代器遍歷

- 內層循環從當前迭代器位置 ?it_i? 開始

- 通過 ?it_i - s.begin()? 計算結果數組索引

?

3.?代碼優化:

- ?switch? 替代多個 ?if? 提高分支效率

- ?currentPos? 直接修改減少拷貝(原代碼中 ?tempos = t? 可直接操作 ?currentPos?)

- ?const? 修飾 ?check? 函數參數避免意外修改

?

注意:C++ 中容器迭代器在動態擴容時可能失效,但此處 ?string? 是固定長度,迭代器始終有效,無需擔心此問題。


內聯函數

內聯函數是一種用 ?inline? 關鍵字聲明的特殊函數,目的是讓編譯器在編譯時直接把函數代碼「嵌入」到調用它的地方,避免普通函數調用的「跳轉開銷」,提高程序運行速度。

?

舉個簡單例子:

假設有個函數計算兩數之和:

int add(int a, int b) {?

? ? return a + b;?

}

?

普通調用時,程序會「跳轉到函數地址執行代碼,再跳轉回來」。

如果聲明為內聯函數:

inline int add(int a, int b) {?

? ? return a + b;?

}

編譯時,編譯器會把 ?add(3,5)? 直接替換成 ?3+5?,就像你直接寫在代碼里一樣,省去了跳轉步驟。

?

關鍵特點:

1.?編譯時替換:不是運行時調用,而是編譯階段直接「展開代碼」。

2.?適合簡單函數:通常用于代碼量少(如幾行)、調用頻繁的函數(比如循環里的小操作)。

3.?可能被編譯器忽略:最終是否內聯由編譯器決定(太復雜的函數會被拒絕)。

?

優點 vs 缺點:

  • - 優點:減少函數調用開銷,提升執行效率。
  • - 缺點:如果函數被多次調用,會導致目標代碼體積增大(用空間換時間)。

總結:內聯函數就像「把常用的小工具直接粘在使用的地方」,省去了拿工具的步驟,但粘太多會占地方。

?

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

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

相關文章

c++ openssl 使用 DES(數據加密標準)進行加密和解密的基本操作

使用 DES&#xff08;數據加密標準&#xff09;進行加密和解密的基本操作&#xff0c;重點展示了 ECB 和 CBC 模式&#xff0c;并且通過篡改密文的方式來進行攻擊。下面是對每個部分的詳細解析。 1. 結構體 Slip struct Slip {char from[16] { 0 }; // 交易的發起者&#x…

OpenWrt:使用ALSA實現邊錄邊播

ALSA是Linux系統中的高級音頻架構&#xff08;Advanced Linux Sound Architecture&#xff09;。目前已經成為了linux的主流音頻體系結構&#xff0c;想了解更多的關于ALSA的知識&#xff0c;詳見&#xff1a;http://www.alsa-project.org 在內核設備驅動層&#xff0c;ALSA提供…

【.net core】天地圖坐標轉換為高德地圖坐標(WGS84 坐標轉 GCJ02 坐標)

類文件 public static class WGS84ToGCJ02Helper {// 定義一些常量private const double PI 3.14159265358979324;private const double A 6378245.0;private const double EE 0.00669342162296594323;// 判斷坐標是否在中國范圍內&#xff08;不在國內則不進行轉換&#x…

Matlab自學筆記五十七:符號運算、可變精度運算、雙精度浮點型運算,三種運算精度的概念、比較、選擇和應用

1.可變精度算術的概念 默認的&#xff0c;Matlab雙精度浮點數使用16位數字精度&#xff0c;而符號數學工具箱的vpa函數&#xff0c;提供了無限大的可變精度&#xff0c;它默認使用32位數字精度&#xff0c;32位指的是有效數字的位數&#xff1b; 2.具體用法 程序示例&#x…

由匯編代碼確定switch語句

int switch2(int x) {int result0;switch(x){/* switch語句主體缺失 */}return result; }在編譯函數時&#xff0c;GCC為程序的初始部分以及跳轉表生成了如下匯編代碼。 1 MOVL 8(%ebp), %eax ;x位于相對于寄存器%ebp偏移量為8的地方。 2 ADDL $2, %eax …

java 使用HanLP 入門教程

1. 安裝 HanLP Maven 依賴 <dependency><groupId>com.hankcs</groupId><artifactId>hanlp</artifactId><version>portable-1.8.4</version> <!-- 最新版本請查看官網 --> </dependency>注意&#xff1a;portable 版本…

vm虛擬機添加虛擬機無反應,獲取所有權

問題描述 虛擬機忘記關機&#xff0c;就把電腦關了&#xff0c;早上打開用不了了&#xff0c;重新添加&#xff0c;也沒反應&#xff0c;獲取所有權后就沒了 問題解決 將虛擬機文件目錄下的.lck文件夾&#xff0c;刪除&#xff0c;或者改個名&#xff0c;我是改為了.backup方…

為何選擇Spring框架學習設計模式與編碼技巧?

&#x1f4cc; 結論先行 推薦項目&#xff1a;Spring Framework 推薦理由&#xff1a;設計模式覆蓋全面 編碼技巧教科書級實現 Java 生態基石地位 &#x1f3c6; 三維度對比分析 維度SpringMyBatisXXL-JOB設計模式??????????代碼抽象??????????生態價…

MySQL 索引:聚集索引與二級索引

在數據庫性能優化的征途中&#xff0c;索引無疑扮演著至關重要的角色。正確理解和使用索引&#xff0c;能夠顯著提升查詢效率&#xff0c;為應用帶來絲滑般的操作體驗。今天&#xff0c;我們將深入 MySQL 的心臟&#xff0c;重點探討 InnoDB 存儲引擎中兩種核心的索引類型&…

【Elasticsearch】映射:詳解 _source store 字段

映射&#xff1a;詳解 _source & store 字段 1._source 字段1.1 特點1.2 示例 2.store 字段2.1 特點2.2 示例 3.兩者對比3.1 使用建議3.2 實際應用示例 1._source 字段 _source 是 Elasticsearch 中一個特殊的元字段&#xff0c;它存儲了文檔在索引時的原始 JSON 內容。 …

新建網站部署流程

1. 新建 Node 服務&#xff0c;指定端口并代理前端靜態資源 操作步驟&#xff1a; 初始化 Node 項目mkdir my-website && cd my-website npm init -y npm install express創建 app.js&#xff08;示例代碼&#xff09;const express require(express); const app e…

時序數據庫IoTDB結合SeaTunnel實現高效數據同步

益、基本概念介紹 1.1 Apache IoTDB Apache IoTDB是一款專為工業物聯網設計的時序數據庫管理系統&#xff0c;集數據收集、存儲、管理與分析于一體&#xff0c;滿足海量數據存儲、高速讀取及復雜數據分析需求。其架構包括時序文件&#xff08;TsFile&#xff09;、數據庫引擎…

k8s業務程序聯調工具-KtConnect

概述 原理 工具作用是建立了一個從本地到集群的單向VPN&#xff0c;根據VPN原理&#xff0c;打通兩個內網必然需要借助一個公共中繼節點&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;簡化了建立連接的過程&#xff0c;apiserver間接起到了中繼節…

RFID推動新能源汽車零部件生產系統管理應用案例

RFID推動新能源汽車零部件生產系統管理應用案例 一、項目背景 新能源汽車零部件場景 在新能源汽車零部件生產領域&#xff0c;電子冷卻水泵等關鍵部件的裝配溯源需求日益增長。傳統 RFID 溯源方案采用 “網關 RFID 讀寫頭” 模式&#xff0c;存在單點位單獨頭溯源、網關布線…

C#封裝HttpClient:HTTP請求處理最佳實踐

C#封裝HttpClient&#xff1a;HTTP請求處理最佳實踐 在現代的.NET應用程序開發中&#xff0c;與外部服務進行HTTP通信是一項常見需求。HttpClient作為.NET框架中處理HTTP請求的核心組件&#xff0c;為我們提供了強大而靈活的API。然而&#xff0c;直接使用原生的HttpClient可能…

【Redis/2】核心特性、應用場景與安裝配置

文章目錄 一、初識 Redis1.1 Redis 概述1. Redis 簡介2. Redis 的發展歷程 1.2 Redis 核心特性1. 高性能2. 豐富的數據類型3. 持久化4. 原子操作5. 主從復制6. 高可用性與分布式7. 內存存儲與低延遲8. 靈活的過期策略9. 事務支持10. 簡單的 API總結 1.3 Redis 應用場景Redis 適…

AI大模型在測試領域應用案例拆解:AI賦能的軟件測試效能躍遷的四大核心引擎(順豐科技)

導語 5月份QECon深圳大會已經結束&#xff0c;繼續更新一下案例拆解&#xff0c;本期是來自順豐科技。 文末附完整版材料獲取方式。 首先來看一下這個案例的核心內容&#xff0c;涵蓋了測四用例設計、CI/CD輔助、測試執行、監控預警四大方面&#xff0c;也是算大家比較熟悉的…

【HTML】HTML 與 CSS 基礎教程

作為 Java 工程師&#xff0c;掌握 HTML 和 CSS 也是需要的&#xff0c;它能讓你高效與前端團隊協作、調試頁面元素&#xff0c;甚至獨立完成簡單頁面開發。本文將用最簡潔的方式帶你掌握核心概念。 一、HTML&#xff0c;網頁骨架搭建 核心概念&#xff1a;HTML通過標簽定義內…

Redis 集群批量刪除key報錯 CROSSSLOT Keys in request don‘t hash to the same slot

Redis 集群報錯 CROSSSLOT Keys in request dont hash to the same slot 的原因及解決方案 1. 錯誤原因 在 Redis 集群模式下&#xff0c;數據根據 哈希槽&#xff08;Slot&#xff09; 分散存儲在不同的節點上&#xff08;默認 16384 個槽&#xff09;。當執行涉及多個 key …

.Net Framework 4/C# LINQ*

一、什么是 LINQ LINQ 是一種在 C# 等編程語言中集成的查詢功能&#xff0c;它允許開發者使用編程語言本身的語法進行數據查詢&#xff0c;而不是嵌入式的字符串 SQL 語句。LINQ 查詢可以應用于對象、XML 和數據庫等多種數據源。 二、LINQ 查詢的基本構成 LINQ 查詢通常包含以…