Linux下的第一個程序——進度條(命令行版本)

文章目錄

  • 編寫Linux下的第一個小程序——進度條
    • 進度條的樣式
    • 前置知識
      • 回車和換行
      • 緩沖區
      • 對回車、換行、緩沖區、輸出的測試代碼
        • 簡單的測試樣例
        • 倒計時程序
    • 進度條程序
      • 理論版本
        • 基本框架
        • 代碼實現
      • 真實版本
        • 基礎框架
      • 代碼實現

編寫Linux下的第一個小程序——進度條

在前面的基礎開發工具的學習中,我們學習了幾個比較重要的開發工具。
當然,對于在開發過程中常用的工具是gcc/g++、vim、make,有了這三個工具的基礎后,我們就可以嘗試著寫一個在Linux系統下開發的小項目了。

而本篇文章將講解在Linux系統下開發的小程序——進度條。

進度條的樣式

在這里,我們得明確進度條的樣式。有了進度條的樣式之后,我們才好根據我們要求的樣式進行相對應的程序包編寫。

在這里插入圖片描述
進度條在命令行上的樣式大致就是這個樣子,但是對于進度條而言,需要特別注意的是:
1.旋轉光標應當一直在旋轉,以表明當前進度仍在進行(只不過某段時間內進度為0)
2.百分比應該動態的增大
3.進度條展示的位置應該是有東西不斷地再填充中間的空位,從肉眼上看的效果就是進度條再動態的前進,其實背后是顯示屏在不斷地刷新和字符不斷地填充輸出而已。

基于上述的原理,我們就可與依次來編寫對應的程序。

前置知識

但是,當前我們還得再補充一些基礎的知識,這是針對于IO流的輸入和輸出的問題。

回車和換行

首先,我們來重新了解一下回車和換行。

在我們以往的認知中,我們會很自然地認為”回車“和”換行“是同一件事情。其實不是的。
在這里插入圖片描述
就以我們寫作文的作文格子來舉例,如上圖所示
單純的換行是把筆尖直接置到同一列的下一行的位置。
單純的回車是把筆尖置到這一行的第一個開頭位置。
回車換行先把筆尖置于開頭后再進行換行。

這也很清楚的說明,換行和回車其實不是一樣的操作。但是為什么在c/c++程序里面,打印‘\n’確實出現了回車 + 換行的操作呢?
這是因為編譯器自行解析了,編譯器在碰到換行符的時候,會解析成“回車 + 換行”。

在c/c++程序中,換行符是‘\n’,回車符是‘\r’
c/c++碰到‘\n’會自動解析成‘\r’ + ‘\n’

緩沖區

這個概念其實早在c語言學習的時候就講到過了,但是我們這里還是再進行一次復習,以便后面順利編寫進度條的代碼。

我們來看看下面這一個代碼:

#include<stdio.h>
#include<unistd.h>int main(){printf("Hello World");sleep(3);return 0;
}

我們來看看這個代碼的輸出結果:

在這里插入圖片描述
暫停了三秒鐘…
在這里插入圖片描述
我們會發現,顯示器上會暫停三秒鐘,也就是在這三秒鐘內是沒有任何的輸出的。但是三秒后,Hello World就被輸出在了顯示器上,但是沒有換行效果。

可是我們學過c/c++程序的代碼執行順序,是從上往下執行的。也就是說,printf函數必然是比sleep函數先執行的。那么printf執行后,打印的內容放在哪里呢?答案就是緩沖區。

其實我們之前講過,Linux下一切皆為文件。即使是我們的顯示器(FILE* stdout)。printf是先把內容輸出到緩沖區的。緩沖區再輸出到顯示器上是執行行刷新原則,即碰到換行符才會把內容給輸出到標準輸出流這個顯示器文件上。

上面那一段代碼就是先把Hello World寫入緩沖區,但是又沒碰到換行符。所以就沒有辦法先把字符串輸出到顯示器上。
但是后面能打印出來的原因是——程序結束后會自動刷新緩沖區,所以內容就會被輸出了。


當然,如果我們想要自行刷新緩沖區從而輸出字符串也是可以的,可以使用函數fflush,我們可以對stdout進行刷新(fflush(stdout))
在這里插入圖片描述
此時我們就可以發現,字符串先打印出來到顯示器了,然后再進行休眠。

對回車、換行、緩沖區、輸出的測試代碼

在寫進度條項目之前,我們還是需要進行一些前置準備——測試代碼。

我們上面僅僅是理論上講解了回車、換行、緩沖區的知識,這些其實和系統層面是有關系的。我們以前很多時候寫的程序是停留在語法層面上的。所以對系統層面上的一些內容不是很清楚。在這里我們需要進行相關功能的測試,結合對輸出的理解,這樣子后面寫進度條這個小項目的時候寫起來就快很多了。

簡單的測試樣例

我們下面看第一個測試代碼:

#include<stdio.h>
#include<unistd.h>
int main(){printf("%d\r", 1235456);fflush(stdout);sleep(3);printf("%s\n", "xx123456");return 0;
}

我們來看看這個代碼,最后的輸出效果是怎么樣的:

在這里插入圖片描述
在這里插入圖片描述
我們會發現,這里會先打印出123456這個數字,停留三秒后,由于回車符的作用,光標會重新放在開頭處,然后再次打印字符串”xx123456“的時候就會把原先打印的字符給覆蓋掉。

所以這里的輸出效果是,先在一行中打印數字123456,停留三秒后,打印字符串”xx123456“,覆蓋掉原來的123456,最后輸出結束。

這個代碼結合了回車、換行、緩沖區的知識,能夠更好地幫助我們理解這些內容。


倒計時程序

上面的測試代碼已經初步地了解和掌握了換行、回車、緩沖區的一些相關的用法。但是還有一些問題是我們在寫進度條的代碼的時候會遇見的。

這些問題其實在這個簡單地倒計時程序里就可以體現出來,接下來我們一起來看一下:

初版代碼:

#include<stdio.h>int main(){int i = 9;while(i >= 0){printf("%d\n", i);--i;}return 0;
}

這個代碼費城非常簡單,在這里就不多說了。就是輸出倒計時9 ~ 0,只不過是會換行輸出。這里寫這個代碼的是為了和后面的改進版本進行對比:
在這里插入圖片描述
但是我們想要的倒計時不是這個樣子的,我們希望的是,每次屏幕上閃動動一個數字,一秒后在相同的位置變成下一秒的數字,那這個時候該怎么辦?

版本二:
這個不久正好用到了上個部分測試樣例中用到的原理嗎?我們使用回車符就可以了,然后每次控制打印的數字的顯示時間即可:

#include<stdio.h>
#include<unistd.h>int main(){int i = 9;while(i >= 0){printf("%d\r", i);sleep(1);--i;}return 0;
}

在這里插入圖片描述
但是我們發現一個問題,就是不打印。這個其實就是沒有刷新緩沖區的原因:
在這里插入圖片描述

在這里插入圖片描述
添加了刷新緩沖區的代碼后,我們發現,打印完最后一個數字0后被命令行覆蓋掉了。因為命令行的前面這一串內容也可以看作是字符串,但是我們剛剛輸出的數字倒計時沒有進行換行,所以最后命令行字符串打印的時候直接覆蓋掉了,所以我們可以自行添加一個換行符:

#include<stdio.h>
#include<unistd.h>int main(){int i = 9;while(i >= 0){printf("%d\r", i);fflush(stdout);sleep(1);--i;}printf("\n");return 0;
}

在這里插入圖片描述


上面的代碼看似沒有問題,但其實還有一些小問題沒有解決,比如我們把i改成10看看:
在這里插入圖片描述
我們會發現,打印完10之后,剩下的數字都會打印在開頭的位置,但是末尾會有一個0出現。

這個原因其實很簡單,只是我們得明白一個原理:
所謂的打印,其實就是打印字符!

我們將123456打印在顯示器上,其實并不是把數字打印在上面,而是把123456字符打印在了顯示器上而已。所以 這里也是一樣的道理。10是兩個字符,但是0 ~ 9是一個字符,所以10正常輸出后,剩下的0 ~ 9因為回車符\r的原因,會在行開頭位置打印,但是因為占位是1個字符,所以后面那個0沒辦法被覆蓋掉。

解決辦法很簡單,改一下printf函數的打印格式就好了:
在這里插入圖片描述
打印的時候在占位符前面加一個數字2,表示一次性打印的字符位寬為2(這個數字取決于倒計數里面最大的那個的數位),不足的就填充。但是這樣子我們會發現,個位數打印的時候左邊是空的,這非常不美觀。

所以這就用需要用到我們在printf函數中學到的“左對齊”打印了:

最終版本:

#include<stdio.h>
#include<unistd.h>int main(){int i = 10;while(i >= 0){printf("%-2d\r", i);fflush(stdout);sleep(1);--i;}printf("\n");return 0;
}

printf函數默認是右對齊的,所以字符不夠的時候前面會被填充。所以這里我們可以在數字的前面加一個-,這樣子就會左對齊了:
在這里插入圖片描述
至此,我們就完成了倒計時程序的編寫。

同時,我們還進一步地用實踐來驗證了一我們前面所講的一些前置知識,有了這些前置知識,我們就可以更好地去編寫我們對應的進度條程序了。

進度條程序

這個部分我們將一起來編寫進度條的程序,就按照我們在前面提及的樣式進行編寫。

在這里我們會給出兩個版本:理論版本和真實版本。
理論版本就是我們現在只負責寫進度條的變動邏輯。兩個版本的差異呢?這是因為理論版本只寫了進度條的變動邏輯,但是進度條這個東西一般都是配合一些任務進行的,進度跳的邏輯應該是穿插在某些程序的內部的。

所以由此得知,理論版本的進度條其實是沒辦法運行的,就只能作為進度條的跳動的理論展示而已,所以我們會分開兩個版本進行編寫。

但是寫出來理論版本就好辦多了,因為真實版本也就是把進度條的邏輯嵌套在其他的代碼中。

理論版本

我們先來看理論版本的代碼。

基本框架

我們需要四個文件:

Process.h 包含進度條代碼需要用到的頭文件、變量、聲名進度條展示函數
Process.c 定義進度條展示的函數
main.c 對編寫的進度條代碼進行測試
Makefile 進行自動化編譯

對于Makefile的編寫,其實我們早就學習過了。
而且我們在Makefile的學習中,我們把對應的Makefile的形式改的更加通用,所以我們只需要修改一下文件中的部分文件名即可:

//Makefile
BIN=Process.exe 
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o);
FFLAG=-o
FLAG=-c
RM=rm -rf$(BIN):$(OBJ)gcc $(FFLAG) $@ $^
%.o:%.cgcc $(FLAG) $<.PHONY:clean 
clean:$(RM) $(BIN) $(OBJ)

其實最后我們發現也就是修改了一下生成的可執行文件而已。

接下來是項目的主體框架:

//Process.h
#pragma once 
#include<stdio.h>
#include<unistd.h>
#include<string.h>#define Num 101
#define STYLE '='void Process();//Process.c
#include"Process.h"void Process(){}//main.c
#include"Process.h"int main(){Process();return 0;
}
代碼實現

首先,我們得知道進度條的變動的原理,其實就是打印一個字符數組。那是如何做到進度條的前進的呢?

其實就是不斷地打印這個進度條,把上一次的進度給覆蓋掉,每次打印的進度條里面需要填充更多的符號以表示進度跳動而已。

我們在這里先看代碼,然后再詳細解釋:

void Process(){char buffer[Num];memset(buffer, 0, sizeof(buffer));int i = 0;char lable[] = "/-|\\";int length = strlen(lable);while(i <= 100){printf("[%-100s][%d%%][%c]\r", buffer, i, lable[i % length]);fflush(stdout);buffer[i] = STYLE;usleep(10000);++i;}printf("\n");
}

首先,我們確定了進度條的最大百分比是100%,所以需要100個空間打印字符(表示進度),這些字符是放在一個char數組內的,本質就是字符串。打印的時候需要碰到\0才會停止,所以存儲進度條字符的數組是需要101個空間的,所以Num的值為101。

而且我們把buffer這個數組中的所有值初始化為\0,這樣子后面我們就不需要再處理字符串的\0問題了。

在這個理論版本,我們就假設進度條每次進度+1%,所以打印百分比很簡單,就是打印我們定義的計數器i。

當然,我們還需要設置一個旋轉光標,以表示當前進度還在繼續,只不過是進度很慢而已,所以需要一直旋轉光標。光標的旋轉其實也是字符的快速打印,把中間間隙去掉,在我們的肉眼來看其實就是旋轉的效果,所以定義了一個label數組,里面就是光標旋轉的時候可能會有圖案。但是這里要注意的,由于 \ 這個字符本身在c/c++程序中有轉義字符的意思,所以要想打印出 \ ,需要對其再加一層 \ 的轉義。
對于光標的打印,其實就是不斷地打印label數組中的字符,但是不能越界訪問label數組,所以需要對坐標進行取模運算。

然后每次打印完進度條后,就應該改動進度條,以便下一次的打印。在這個理論版本中,就是不斷地往這個數組內部填充字符。

還有一個點就是,由于在printf函數中%是被賦予了特殊意義,所以只寫一個%是打印不出來的,要想打印出來%就需要寫兩個。

當然上面還有一些細節我沒有講到,但其實都是在前面的前置知識中有說過的。所以在這里就不再過多的贅述了。

最后,我們來看幾張效果圖:

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

這里就隨意的選取幾張圖看看,感興趣的可以自行拷貝實驗一下。

真實版本

前面是理論版本,也就是我們完成了進度條的動態操作。但是這個程序一般都是放在一些下載/上傳等場景下配合使用的。所以這個部分我們就來模擬一下下載場景。

基礎框架

還是一樣,我們需要準備四個文件:

ProcessBar.h 包含進度條代碼需要用到的頭文件、變量、聲名進度條展示函數
ProcessBar.c 定義進度條展示的函數
main.c 定義下載函數和其相關變量
Makefile 進行自動化編譯

有了前面的基礎,這里就不過多的廢話了:

//Makefile
BIN=Load.exe 
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o);
FFLAG=-o
FLAG=-c
RM=rm -rf$(BIN):$(OBJ)gcc $(FFLAG) $@ $^
%.o:%.cgcc $(FLAG) $<.PHONY:clean 
clean:$(RM) $(BIN) $(OBJ)
//main.c
//使用隨機數來模擬每次下載的量 需要用到下面兩個頭文件
#include<stdlib.h>
#include<time.h>
#include"ProcessBar.h"
#define TOTAL 1024.0//總的下載量void Download(){}int main(){Download();return 0;
}//ProcessBar.h
#pragma once #include<unistd.h>
#include<string.h>
#include<stdio.h>
#define Num 101
#define STYLE '='static int lable_move = 0;//用于光標數組的坐標void Process(int cur, double total);//進度條函數//ProcessBar.c
#include"ProcessBar.h"void Process(int cur, double total){}

但是這里需要稍微解釋一下,這里的進度條打印函數相比理論版本是多了兩個參數的。即當前下載的量cur和總共要下載的量total

因為當前這里的進度條函數是嵌套在下載函數Download當中的,但是進度條最終的是什么?是進度。進度是需要計算的。這里的進度條需要展示下載的進度,所以需要獲取到當前下載的量和總共要下載的量,以便能夠在內部進行計算。所以這里需要傳入兩個參數。

代碼實現

接下來我們將對代碼的實現進行講解。

首先我們得明白,在真實版本下的進度條,我們是不需要想理論版本那樣,去進行屏幕沉睡(sleep函數)的控制,也不需要我們自己去計算下一次的進度。因為這些事情都是下載函數Download去操作的。
換而言之:Process函數只負責接收當前的進度和總任務量,進行進度的計算,然后根據計算量去顯示進度條即可!

這里我們也是先直接展示代碼:

//main.c
#include<stdlib.h>
#include<time.h>
#include"ProcessBar.h"
#define TOTAL 1024.0void Download(){srand((unsigned int)time(NULL));int speed = rand()%10;//0 ~ 9int cur_load = 0;while(cur_load <= TOTAL){//打印進度條Process(cur_load, TOTAL);usleep(20000);//sleep(1);// if(cur_load == TOTAL){printf("\n");return;}//重新計算下載量cur_load += speed;if(cur_load > TOTAL) cur_load = TOTAL;speed = rand()%10;}
}int main(){Download();return 0;
}//ProcessBar.h
#pragma once #include<unistd.h>
#include<string.h>
#include<stdio.h>
#define Num 101
#define STYLE '='static int lable_move = 0;void Process(int cur, double total);//ProcessBar.c
#include"ProcessBar.h"void Process(int cur, double total){char buffer[Num];memset(buffer, 0, sizeof(buffer));char lable[] = "/|-\\";int length = strlen(lable);double Precent = (cur * 100 / total);int i = 0;for(i = 0; i < (int)(Precent); ++i){buffer[i] = STYLE;} printf("[%-100s][%.2lf%%][%c]\r", buffer, Precent, lable[lable_move]);fflush(stdout);++lable_move;lable_move %= length;
}

我們下面來解釋一下上述代碼的邏輯:

首先對于main.c來說,其實就是寫一個Download的下載函數,然后main函數中調用一下即可。但是這里我采用了隨機數的方式來獲取每次的下載量(speed),讓下載量有所不同。

但是這里就需要注意一個問題了,很有可能某一次打印完進度條后,再接收下載量可能就超過TOTAL了,這樣子下一次就不會進入循環了。但其實還是有最后一小部分的進度是沒有顯現出來的。所以當下載量speed大于剩余可以下載的量時候,就需要調整speed大小。然后為了能夠進入循環,所以循環條件內,下載量cur_load是需要可以等于TOTAL的。
但是又因為我們對下載量進行特殊處理,如果我們打印完進度條(Process函數)后,不進行判斷,就會導致死循環(因為剩余下載量0 <= speed)。所以這里的循環其實是內部進行退出的。不這么寫會導致死循環的。
然后就是退出循環的時候,需要打印一個換行符,這樣子才能使得進度條單獨成一行。


然后就是Process函數的處理,其實就是修改一下理論版本的進度條函數就可以了。
只不過就是我們需要自行的計算進度,然后把進度對應的字符數填入數組后再打印數組。

但是這里還有一點是不一樣的,就是光標的旋轉。前面寫理論版本的時候我是偷了一個懶,直接拿計數器取余i就獲得了label數組的下標了。

但其實這樣子不對,光標應該是有一個它自己的獨立的坐標數的,即使有時候進度條進度增加為0%,但是它也應該在轉,這表示當前進度仍在進行。如果寫成理論版本那樣就是進度增加為0%的時候光標是不轉的。只不過理論版本的計數器i一直在變,所以光標也會一直轉。

所以這里需要一個計數器,每次打印進度條就獲取對應位置中label數組的元素。但是這里是需要使用一個靜態變量的。因為靜態變量存儲在靜態區,每次++后是會被保存下來這個狀態的。如果是使用棧區上的局部變量,那每次進來都是重新初始化的,這不符合要求。然后再注意這個坐標不要越界即可。

最后,我們還是來看幾張效果圖:

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述這里也是隨機截的幾張圖,我們發現確實是我們想要的結果。

至此,我們所有的關于進度條的內容就講完了。

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

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

相關文章

【項目】仿muduo庫one thread one loop式并發服務器前置知識準備

&#x1f4da; 博主的專欄 &#x1f427; Linux | &#x1f5a5;? C | &#x1f4ca; 數據結構 | &#x1f4a1;C 算法 | &#x1f152; C 語言 | &#x1f310; 計算機網絡 |&#x1f5c3;? mysql 本文介紹了一種基于muduo庫實現的主從Reactor模型高并發服務器框架…

steam報網絡錯誤,但電腦是網絡連接的

steam報網絡錯誤&#xff0c;但電腦是網絡連接的 如&#xff1a; 解決辦法&#xff1a; 關閉電腦防火墻和所有殺毒軟件&#xff0c;然后重新打開steam開代理&#xff0c;可能國內有時候訪問不了 首選1進行嘗試 steam安裝路徑一定要在純英文路徑下 已ok

Vue 組合式 API 與 選項式 API 全面對比教程

一、前言&#xff1a;Vue 的兩種 API 風格 Vue 提供了兩種編寫組件邏輯的方式&#xff1a;組合式 API (Composition API) 和 選項式 API (Options API)。理解這兩種方式的區別和適用場景&#xff0c;對于 Vue 開發者至關重要。 為什么會有兩種 API&#xff1f; 選項式 API&a…

HarmonyOS 應用模塊化設計 - 面試核心知識點

HarmonyOS 應用模塊化設計 - 面試核心知識點 在 HarmonyOS 開發面試中&#xff0c;模塊化設計是必考知識點。本文從面試官角度深度解析 HarmonyOS 應用模塊化設計&#xff0c;涵蓋 HAP、HAR、HSP 等核心概念&#xff0c;助你輕松應對技術面試&#xff01; &#x1f3af; 面試高…

Maven高級學習筆記

分模塊設計 為什么分模塊設計?將項目按照功能拆分成若干個子模塊&#xff0c;方便項目的管理維護、擴展&#xff0c;也方便模塊間的相互調用&#xff0c;資源共享。 注意事項&#xff1a;分模塊開發需要先針對模塊功能進行設計&#xff0c;再進行編碼。不會先將工程開發完畢&…

[創業之路-423]:經濟學 - 大國競爭格局下的多維博弈與科技核心地位

在當今風云變幻的國際舞臺上&#xff0c;大國競爭已成為時代的主旋律&#xff0c;其激烈程度與復雜性遠超以往。這場全方位的較量&#xff0c;涵蓋了制度、思想、文化、經濟、科技、軍事等諸多關鍵領域&#xff0c;每一個維度都深刻影響著大國的興衰成敗&#xff0c;而科技在其…

【企業容災災備系統規劃】

一、企業災備體系 1.1 災備體系 災備切換的困境: 容災領域的標準化方法和流程、算法體系是確保業務連續性和數據可靠性的核心,以下從標準框架、流程規范、算法體系三個維度進行系統分析: 1.1.1、標準化方法體系? ?1. 容災等級標準? ?國際標準SHARE78?: 將容災能力劃…

Kafka Connect基礎入門與核心概念

一、Kafka Connect是什么&#xff1f; Apache Kafka Connect是Kafka生態中用于構建可擴展、可靠的數據集成管道的組件&#xff0c;它允許用戶將數據從外部系統&#xff08;如數據庫、文件系統、API等&#xff09;導入Kafka&#xff08;Source Connector&#xff09;&#xff0…

從零手寫Java版本的LSM Tree (四):SSTable 磁盤存儲

&#x1f525; 推薦一個高質量的Java LSM Tree開源項目&#xff01; https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一個從零實現的Log-Structured Merge Tree&#xff0c;專為高并發寫入場景設計。 核心亮點&#xff1a; ? 極致性能&#xff1a;寫入速度超…

Kotlin的5個主要作用域函數

applay, also,let, run, with 是kotlin標準庫提供的5個主要的作用域函數&#xff08;Scope Functions&#xff09;?&#xff0c;它們的設計目的是為了在特定作用域內更簡潔地操作對象。 如何使用這5個函數&#xff0c;要從它的設計目的來區分&#xff1a; apply : 配置/對象…

原型模式Prototype Pattern

模式定義 用原型實例指定創建對象的種類&#xff0c;并且通過復制這些原型創建新的對象&#xff0c;其允許一個對象再創建 另外一個可定制的對象&#xff0c;無須知道任何創建的細節 對象創建型模式 基本工作原理是通過將一個原型對象傳給那個要發動創建的對象&#xff0c;這…

基于深度學習的智能交通流量預測系統:技術與實踐

前言 隨著城市化進程的加速&#xff0c;交通擁堵問題日益嚴重&#xff0c;給人們的日常生活和經濟發展帶來了巨大的挑戰。智能交通系統&#xff08;ITS&#xff09;作為解決交通問題的重要手段&#xff0c;逐漸成為研究的熱點。其中&#xff0c;交通流量預測是智能交通系統中的…

Cilium動手實驗室: 精通之旅---23.Advanced Gateway API Use Cases

Cilium動手實驗室: 精通之旅---23.Advanced Gateway API Use Cases 1. Lab說明1.1 高級網關 API 使用案例 2. 負載均衡器2.1 部署應用程序2.2 部署 Gateway 和 HTTPRoute 3. HTTP 標頭請求修飾符3.1 部署 HTTPRoute3.2 可觀測性 4. HTTP 響應標頭重寫5. HTTP 流量鏡像5.1 demo應…

Agentic Workflow是什么?Agentic Workflow會成為下一個AI風口嗎?

無論是想要學習人工智能當做主業營收&#xff0c;還是像我一樣作為開發工程師但依然要運用這個顛覆開發的時代寵兒&#xff0c;都有必要了解、學習一下人工智能。 近期發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;入行門檻低&#x…

Some chunks are larger than 500 KiB after minification. Consider

在 vue3vite 項目開發中&#xff0c;build 打包時出現以下警告報錯&#xff1a; (!) Some chunks are larger than 500 KiB after minification. Consider: - Using dynamic import() to code-split the application - Use build.rollupOptions.output.manualChunks to improve…

NodeJS11和10以及之前的版本,關鍵差異?

Node.js 11 相比 10&#xff08;及更早版本&#xff09;&#xff0c;除了事件循環行為的重大改變&#xff0c;還有多個核心模塊和底層機制的升級。以下是它們的關鍵差異和新特性對比&#xff0c;幫助你快速掌握兩個版本的重要變化。 &#x1f527; 一、事件循環行為變化&#x…

調和級數 斂散性

調和級數的斂散性是一個非常經典的問題。我們來全面分析它。 &#x1f9e0; 調和級數定義 調和級數是指&#xff1a; ∑ n 1 ∞ 1 n 1 1 2 1 3 1 4 ? \sum_{n1}^{\infty} \frac{1}{n} 1 \frac{1}{2} \frac{1}{3} \frac{1}{4} \cdots n1∑∞?n1?121?31?41?? …

Python?元組集合字符串

????˙?˙? ? 元組&#x1f6e5;?創建訪問修改解包其他操作比較的依據 集合&#x1f6f8;創建添加和刪除其他操作 字符串&#x1fa82;創建索引和切片基本操作連接加號join() 重復查找in 關鍵字index()find()startswith()endswith() ??替換??分割??大小寫刪除 能…

??信息系統項目管理師-項目整合管理 知識點總結與例題分析??

??一、項目整合管理概述?? ??1. 定義與重要性?? 項目整合管理是項目管理知識領域中的核心過程,它協調所有其他知識領域的過程和活動,確保項目各要素有效整合。其核心目標是: ??統一項目目標??:確保各要素服務于共同目標??協調沖突??:解決項目執行中的各…

『uniapp』onThemeChange監聽主題樣式,動態主題不正確生效,樣式被覆蓋的坑

目錄 問題示例代碼解決思路1&#xff08;缺點影響顯示效果有延遲&#xff09;解決思路2——通過路由刷新頁面&#xff08;缺點只適用于部分網頁&#xff09;解決思路3——vuex&#xff08;沒學會~&#xff09;總結 歡迎關注 『uniapp』 專欄&#xff0c;持續更新中 歡迎關注 『…