【Linux基礎I/O】文件調用接口、文件描述符、重定向和緩沖區

【Linux基礎I/O一】文件描述符和重定向

  • 1.C語言的文件調用接口
  • 2.操作系統的文件調用接口
    • 2.1open接口
    • 2.2close接口
    • 2.3write接口
    • 2.4read接口
  • 3.文件描述符fd的本質
  • 4.標準輸入、輸出、錯誤
  • 5.重定向
    • 5.1什么是重定向
    • 5.2輸入重定向和輸出重定向
    • 5.3系統調用的重定向dup2
  • 6.緩沖區

1.C語言的文件調用接口

  1. fopen
FILE *fopen(const char *filename, const char *mode);

filename 參數是一個字符串,指定要打開的文件名或路徑
mode 參數是一個字符串,指定文件的打開模式,常見如下:
“r”:只讀,若文件不存在則報錯
“w”:只寫,若文件不存在則創建,打開時清空文件原有內容
“a”:只寫,若文件不存在則創建,打開時從文件末尾追加
返回值:
如果成功打開文件,則返回指向 FILE 類型結構的指針,該指針用于后續的文件操作。
如果打開失敗,返回 NULL,并且通過檢查 errno 變量可以確定失敗的具體原因

FILE *fp = fopen("temp.txt", "r");
if (fp == NULL) {perror("Error opening file");return 1;
}
  1. fclose
int fclose(FILE *stream);

stream 是一個指向 FILE 結構的指針,指定要關閉的文件
返回值:
如果成功關閉文件,則返回 0。
如果關閉失敗,則返回 EOF

FILE *fp = fopen("temp.txt", "r");
if (fp == NULL) {perror("opening error");return 1;
}if (fclose(fp) == 0) {printf("close succeed.\n");
} else {perror("closing error");return 1;
}
  1. fprintf
int fprintf(FILE *stream, const char *format, ...);

stream是一個指向FILE結構的指針,指定要寫入的目標文件
format是一個格式化字符串,類似于printf函數中的格式化字符串,用于指定輸出的格式
返回值:
成功返回寫入的字符數,如果出錯則返回一個負數
默認打開文件的時候,清空文件內容
a打開方式:append追加方式寫入文件,不會清空原文件內容

2.操作系統的文件調用接口

2.1open接口

在這里插入圖片描述

pathname 是一個字符串,表示要打開的文件路徑
flags 是打開文件的標志位,例如 O_RDONLY(只讀)、O_WRONLY(只寫)、O_RDWR(讀寫)、O_CREAT(若打開的文件不存在,則創建該文件)
mode 是文件的權限,通常與 flags 參數中的某些標志結合使用,用于指定文件的創建模式
返回值:
如果成功,返回一個新的文件描述符,用于后續的文件操作
如果出錯,返回 -1

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main()
{int fd = open("log.txt", O_WRONLY | O_CREAT);return 0;
}

在這里插入圖片描述
運行./mybin后,當前目錄就出現了文件log.txt了,但是它的權限值是亂碼-r-s–x–T,如果你刪掉該文件后再次運行代碼,你會發現下一次的權限值和上次還不一樣
此時就需要三個參數的open接口:
mode用于控制文件的初始權限,一般系統默認掩碼是0002

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main()
{int fd = open("log.txt", O_WRONLY | O_CREAT, 0666);return 0;
}

在這里插入圖片描述
open的第三個參數傳入0666,也就是log.txt的初始權限
由于umask是0002,所以最終權限為664也就是rw-rw-r–

2.2close接口

在這里插入圖片描述

作用:關閉文件
描述符fd對應的文件, 調用成功返回0

2.3write接口

在這里插入圖片描述

fd:被寫入文件的fd
buf:指向被寫入的字符串
count:寫入字符的個數

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main()
{int fd = open("log.txt", O_WRONLY | O_CREAT, 0666);char* str = "Hello\n Hello\n";write(fd, str, 6);close(fd);return 0;
}

向log.txt寫入了一個字符串str,write的第三個參數為6,只寫入了6個字符Hello\n,輸出結果是Hello
在這里插入圖片描述
在保留原先log.txt的情況下,更改test.c:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main()
{int fd = open("log.txt", O_WRONLY | O_CREAT, 0666);char* str = "Hello\n Hello\n";write(fd, str, 6);close(fd);return 0;
}

在這里插入圖片描述
log.txt的內容變成了123lo,為什么?

以O_WRONLY模式對文件進行寫入時,不會先把文件內容清空,而是直接從頭開始覆蓋

有兩種解決方案,對應兩個open的選項

  1. O_TRUNC打開時清空文件內容
  2. O_APPEND以追加的形式寫入

2.4read接口

在這里插入圖片描述

fd:目標文件的文件描述符fd
buf:將文件內容讀取到buf指向的空間中
count:最多讀取count個字節的內容
返回值:
< 0:讀取發送錯誤
= 0:讀取到文件末尾
0:讀取成功,返回讀取到的字符個數

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>int main()
{int fd = open("log.txt", O_RDONLY);char buffer[1024];ssize_t ret1 = read(fd, buffer, 1024);printf("ret1 = %ld\n", ret1);printf("%s", buffer);close(fd);return 0;
}

在系統創建一個log.txt文件,內容為字符串hello Linux
一開始用open以只讀RDONLY形式打開文件,通過read(fd, buffer, 1024)把內容存儲到數組buffer中,并把返回值交給ret1,隨后輸出ret1和buffer
在這里插入圖片描述
第一次read返回值為12,也就是字符串Hello Linux有12個字符

3.文件描述符fd的本質

文件描述符的本質是一個數組的下標

在Linux系統下,一切皆文件
文件 = 內容 + 屬性
文件操作 = 對內容的操作 或 對屬性的操作
因為馮諾依曼體系結構,CPU只和內存做交互,所以要對文件做修改就需要加載到內存
我們會同時打開多個文件,也會有別人同時打開文件,所以,操作系統需要管理這些打開的文件
管理 = 先描述,再組織
操作系統同樣會像管理進程那樣,也給文件創建對應的結構體,然后文件之間會有一些連接關系
這樣,對文件的管理就變成對某種數據結構的管理
文件操作是用戶讓操作系統進行的,操作系統會為此創建進程
所以文件操作實質是進程和被打開文件的關系

操作系統運行時,會有很多進程在運行
在文件沒有被打開之前,文件是存在磁盤中的
打開文件是進程打開的:進程將文件的數據加載到文件內核級的緩存塊中
而一個進程能打開很多文件,同時,系統當中可以存在許多進程
為了更好的管理文件,所有被打開的文件,操作系統都會對其創建一個結構體struct file在這里插入圖片描述
文件 = 屬性 + 內容,而這個struct file結構體對象就是用來描述被打開的文件
被打開的文件結構體對象,被操作系統用雙向鏈表組織起來,成為一個雙向鏈表
于是,操作系統對被打開文件的管理就變成了對一個雙向鏈表的增刪查改,解決了對文件的管理問題

文件和進程之間的關系如何描述和組織
進程的PCB(task_struct)結構體對象中存在一個指針變量:struct files_struct *file
在Linux 2.6.10內核中,struct files_struct如下:
其最后一個成員fd_array是一個數組,指向的成員類型為struct file*,也就是指向struct file的指針

struct files_struct {atomic_t count;spinlock_t file_lock;/* Protects all the below members.  Nests inside tsk->alloc_lock */int max_fds;int max_fdset;int next_fd;struct file ** fd;/* current fd array */fd_set *close_on_exec;fd_set *open_fds;fd_set close_on_exec_init;fd_set open_fds_init;struct file * fd_array[NR_OPEN_DEFAULT];
};

操作系統全局管理的struct files_struct,整個系統中所有被打開的文件都要被這個結構體管理
每個進程自己打開維護的struct files_struct,分別管理自己打開的文件

在這里插入圖片描述

這個指針數組內部的一個個指針就對應著一個個被打開的文件的地址
而文件描述符fd就是這個數組的下標
所以,當用戶想要訪問一個進程下的文件時,因為每一個進程的PCB是唯一的,所以文件管理數組也唯一的,只要是進程打開了一個文件,就會把文件的*file添加進去
只需要返回這個進程PCB結構體中fd_array數組的下標
就可以找到對應的文件了

下述三個系統調用函數都有一個int fd,當打開一個文件時,
要對這個文件進行寫、讀、操作,都需要傳遞open時返回的文件描述符fd
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
用fd去找到對應的文件然后執行相關操作
對文件的讀寫等操作的數據改動都是在緩沖區內進行
然后由操作系統刷新到磁盤對應位置
所以,讀取文件,本質上就是從文件的文件內核緩沖區內加載數據到應用層的用戶級緩沖區

4.標準輸入、輸出、錯誤

0:標注輸入 (鍵盤)
1:標準輸出 (顯示器)
2:標準錯誤 (顯示器)

int fd1 = open("text1.txt",O_WRONLY | O_CREAT);
int fd2 = open("text2.txt",O_WRONLY | O_CREAT);
int fd3 = open("text3.txt",O_WRONLY | O_CREAT);
int fd4 = open("text4.txt",O_WRONLY | O_CREAT);printf("fd1 = %d\nfd2 = %d\nfd3 = %d\nfd4 = %d\n",fd1,fd2,fd3,fd4);

在這里插入圖片描述
確實多出了4個,文件文件描述符從3開始,編號0 1 2的fd去哪里了?
在這里插入圖片描述
C語言中,會為我們默認打開三個流stdin標準輸入,stdout標準輸出,stderr標準錯誤,0、1、2為編號的fd就已經被占用
C語言中,文件流是以FILE的形式被管理的,毫無疑問FILE是對Linux文件系統的封裝,FILE內部一定存儲了fd,否則無法通過fd來訪問特定的文件,其中FILE的_fileno成員就是fd

#include <stdio.h>int main()
{int fd1 = stdin->_fileno;int fd2 = stdout->_fileno;int fd3 = stderr->_fileno;printf("stdin->_fileno = %d\n", fd1);printf("stdout->_fileno = %d\n", fd2);printf("stderr->_fileno = %d\n", fd3);return 0;
}

在這里插入圖片描述
LInux下一切皆文件
在Linux操作系統中的每一個驅動設備都創建了struct file結構體
結構體內部的屬性就是設備的屬性數據和函數指針
所以,盡管每一個設備的操作方法不一樣,但可以把方法的返回值、參數設置成一樣的,然后讓這些函數指針指向底層的硬件設備的操作方法,站在Linxu的角度來看這些硬件,也視為文件
實現這種組織的技術其實就是多態
所以對于硬件這一層,在Linux下叫做vfs,即vitural file system虛擬軟件系統
在這里插入圖片描述

5.重定向

5.1什么是重定向

文件描述符的分配規則:查看自己的文件描述表,分配最小的沒有被使用的fd
printf和scanf作為C語言的函數接口,同樣無法直接和顯示器和鍵盤作交互,其必須依靠相應的文件,也就是標準輸出和標準輸入
但是依靠的指向并不是FILE*,而是文件描述符,printf依靠1號文件,scanf依靠0號文件

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main()
{close(1);//關掉1號文件(stdout)int fd1 = open("log.txt",O_WRONLY | O_CREAT | O_APPEND,0666);//打開log.txtprintf("Hello Linux\n");//向屏幕打印printf("Hello Linux\n");printf("Hello Linux\n");printf("Hello Linux\n");return 0;
}

可以看到Hello Linux并沒有如愿打印在屏幕上,因為printf只往1號文件里寫,就算使用fprintf向stdout輸出也不會輸出到屏幕
說明printf函數和stdout只認文件描述符1,不管1此時還是不是
標準輸出
在這里插入圖片描述
但1號文件被關閉,系統給新文件log.txt分配最小的沒有被使用的fd,也就是1號,所以本來寫入到顯示器里的內容寫入到了log.txt
在這里插入圖片描述
這就是重定向,重定向的本質:是在內核中改變文件描述符表特定下標的內容

5.2輸入重定向和輸出重定向

>代表輸出重定向,將輸出從顯示器更改到指定文件
<代表輸入重定向,將輸入從鍵盤更改到指定文件

測試:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>int main()
{printf("printf->stdout\n");fprintf(stdout,"fprintf->stdout\n");fprintf(stderr,"fprintf->stderr\n");return 0;
}

在這里插入圖片描述
直接運行會向顯示器打印
在這里插入圖片描述
在這里插入圖片描述

重定向后標準輸出被重定向到文件中了,但是標準錯誤仍然還是輸出到顯示器中

因為>是輸出重定向,只會更改標準輸出stdout的文件描述符,也就是將指向顯示器的文件描述符1更改指向log,txt,但是并不會更改標準錯誤stderr的文件描述符2,所以標準錯誤依然寫入到顯示器上,只有標準輸出寫入到了指定的文件中

>:將命令的標準輸出重定向到文件,會覆蓋文件內容。
<:將文件內容作為命令的標準輸入。
>>:將命令的標準輸出重定向到文件,追加到文件末尾,不會覆蓋文件內容。

5.3系統調用的重定向dup2

操作系統提供一個專門用于文件描述符改向的系統調用就叫做dup2
在這里插入圖片描述

oldfd:原始文件描述符,表示要復制的文件描述符。
newfd:目標文件描述符,表示將 oldfd復制給的newfd
返回值:
成功時dup2 返回 newfd(復制操作后新的文件描述符)
失敗時返回 -1,并將 errno 設置為相應的錯誤代碼。

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main() 
{int fd;// 打開文件,如果文件不存在則創建,權限為0644fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);// 將標準輸出重定向到fddup2(fd, STDOUT_FILENO);//STDIN_FILENO和STDOUT_FILENO是C語言標準庫中定義的宏,分別用于表示標準輸入和標準輸出的文件描述符,這兩個宏在<unistd.h>頭文件中定義,通常被賦值為0和1printf("Hello Linux\n");// 關閉原文件描述符close(fd);return 0;
}

在這里插入圖片描述

在這里插入圖片描述

6.緩沖區

緩沖區本質上就是一塊內存區域

fwrite等C語言的文件IO接口,都在底層封裝了系統調用接口write,用戶調用的所有C語言文件IO接口,都會先寫到緩沖區中,然后等到一定條件,在通過一次系統調用,把之前所有緩沖區的數據寫入到操作系統中,這個一次性寫入過程叫做刷新緩沖區
操作系統也有自己的緩沖區,但是這個是操作系統自己管理的內核緩沖區,其決定了wirte等系統調用接口寫入的數據何時寫入到內存中,但不是該博客討論的范圍,后續討論的緩沖區都是用戶級緩沖區(語言級別的文件緩沖區)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>int main()
{close(1);int fd = open("myfile.txt", O_WRONLY|O_CREAT, 0666);printf("fd: %d\n", fd);//fflush(stdout);close(fd);exit(0);//中斷程序}

在這里插入圖片描述
當運行上述代碼時,即使對一個文件寫入了內容,也沒有顯示
使用了fflush函數之后,就顯示了
在這里插入圖片描述
原因就是struct FILE 結構體內還有一個語言級別的文件緩沖區
我們使用的printf、fprintf函數等寫入的數據都是寫到了語言級別的文件緩沖區,而不是到了內存的緩沖區
所以fflush函數所作的工作其實就是把語言級別的緩沖區刷新到內存中
所以如果在文件關閉之前,沒有進行刷新,那么,就無法把語言級的緩沖區刷新到內存

用戶級緩沖區的刷新策略有以下幾種:

1.無緩沖:不進行緩沖,直接輸出
2.行緩沖:向顯示器寫入時,'\n’會強制刷新緩沖區,也就是一行一行刷新緩沖區
3.全緩沖:向普通文件寫入時,一般緩沖區被寫滿才會刷新
4.程序結束,強制刷新緩沖區
5.用戶調用flush函數,強制刷新緩沖區

緩沖區被struct FILE管理,由于每個文件的FILE是獨立的,因此每個文件的緩沖區也是獨立的

特殊情況:

#include <stdio.h>
#include <unistd.h>
#include <string.h>int main()
{fprintf(stdout,"fprintf->stdout\n");char* temp = "write\n";write(1,temp,strlen(temp));fork();return 0;
}

我們成功將內容輸出到了顯示器
但是,當我們將這些內容重定向到文件中,C語言庫的輸出打印了兩次
在這里插入圖片描述
為什么write不打印兩次?
當我們重定向時,write是系統調用,直接寫入struct file的緩沖區(文件內核的緩沖區)

為什么fprintf在fork之前就已經完成了卻打印了兩次?
fprintf因為是語言層面的調用,將內容寫入FILE結構體的緩沖區(語言級別的文件緩沖區),原本向顯示器輸出的策略是行刷新,但在重定向到log.txt前還沒有行刷新將其打印,所以fprint->stdout就被留在了緩沖區
當子進程被創建時會繼承父進程的數據和代碼,stdin的FILE指向的緩沖區也會被繼承
所以當父子進程同時進行至刷新緩沖區時,分別輸出了一句fprint->stdout

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

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

相關文章

鴻蒙HarmonyOS 【ArkTS組件】通用屬性-背景設置

&#x1f4d1;往期推文全新看點&#xff08;附帶最新鴻蒙全棧學習筆記&#xff09; 嵌入式開發適不適合做鴻蒙南向開發&#xff1f;看完這篇你就了解了~ 鴻蒙崗位需求突增&#xff01;移動端、PC端、IoT到底該怎么選&#xff1f; 分享一場鴻蒙開發面試經驗記錄&#xff08;三面…

【76. 最小覆蓋子串】

Leetcode算法練習 筆記記錄 76. 最小覆蓋子串 76. 最小覆蓋子串 滑動窗口的hard題目&#xff0c;思路先找到第一個覆蓋的窗口&#xff0c;不斷縮小左邊界&#xff0c;找到更小的窗口并記錄。 思路很簡單&#xff0c;寫起來就不是一會事了&#xff0c;看題解看了幾個h&#xff0…

Spring事務簡單操作

什么是事務&#xff1f; 事務是一組操作的集合&#xff0c;是一個不可分割的操作 事務會把所有的操作作為?個整體, ?起向數據庫提交或者是撤銷操作請求. 所以這組操作要么同時 成功, 要么同時失敗. 事務的操作 分為三步&#xff1a; 1. 開啟事start transaction/ begin …

Rust 學習筆記:關于錯誤處理的練習題

Rust 學習筆記&#xff1a;關于錯誤處理的練習題 Rust 學習筆記&#xff1a;關于錯誤處理的練習題想看到回溯&#xff0c;需要把哪個環境變量設置為 1&#xff1f;以下哪一項不是使用 panic 的好理由&#xff1f;以下哪一項最能描述為什么 File::open 返回的是 Result 而不是 O…

MCP 協議傳輸機制大變身:拋棄 SSE,投入 Streamable HTTP 的懷抱

在技術的江湖里&#xff0c;變革的浪潮總是一波接著一波。最近&#xff0c;模型上下文協議&#xff08;MCP&#xff09;的傳輸機制就搞出了大動靜&#xff0c;決定和傳統的服務器發送事件&#xff08;SSE&#xff09;說拜拜&#xff0c;轉身擁抱 Streamable HTTP&#xff0c;這…

138. Copy List with Random Pointer

目錄 題目描述 方法一、使用哈希表 方法二、不使用哈希表 題目描述 問題的關鍵是&#xff0c;random指針指向的是原鏈表的結點&#xff0c;這個原鏈表的結點對應哪一個新鏈表的結點呢&#xff1f;有兩種辦法。一是用哈希表。另一種是復制原鏈表的每一個結點&#xff0c;并將…

如何評估開源商城小程序源碼的基礎防護能力?

在電商行業快速發展的背景下&#xff0c;開源商城已經為更多企業或者開發者的首選方案&#xff0c;不過并不是所有的開源商城源碼都能讓人放心使用&#xff0c;今天就帶大家一起了解下如何評估開源商城小程序源碼的基礎防護能力&#xff0c;幫助大家更好地篩選安全性高的商城源…

[Vue]跨組件傳值

父子組件傳值 詳情可以看文章 跨組件傳值 Vue 的核?是單向數據流。所以在父子組件間傳值的時候&#xff0c;數據通常是通過屬性從?組件向?組件&#xff0c;??組件通過事件將數據傳遞回?組件。多層嵌套場景?般使?鏈式傳遞的?式實現provideinject的?式適?于需要跨層級…

悠易科技智能體矩陣撬動AI全域營銷新時代

大數據產業創新服務媒體 ——聚焦數據 改變商業 在數字化浪潮與AI技術的雙重驅動下&#xff0c;數據營銷正經歷前所未有的變革&#xff0c;從傳統的全域智能營銷&#xff0c;邁向更具顛覆性的AI全域營銷時代。 麥肯錫的報告顯示&#xff0c;采用AI驅動營銷的企業&#xff0c;客…

Xilinx XCAU10P-2FFVB676I 賽靈思 Artix UltraScale+ FPGA

XCAU10P-2FFVB676I 是 AMD Xilinx 推出的 Artix UltraScale? FPGA 器件&#xff0c;內部集成了約 96,250 邏輯單元&#xff0c;滿足中等規模高性能應用的需求。該芯片采用 16 nm FinFET 制程工藝&#xff0c;核心電壓典型值約 0.85 V&#xff0c;能夠在較低功耗下提供高達 775…

Java SpringBoot 項目中 Redis 存儲 Session 具體實現步驟

目錄 一、添加依賴二、配置 Redis三、配置 RedisTemplate四、創建控制器演示 Session 使用五、啟動應用并測試六、總結 Java 在 Spring Boot 項目中使用 Redis 來存儲 Session&#xff0c;能夠實現 Session 的共享和高可用&#xff0c;特別適用于分布式系統環境。以下是具體的實…

分布式電源的配電網無功優化

分布式電源(Distributed Generation, DG)的大規模接入配電網,改變了傳統單向潮流模式,導致電壓波動、功率因數降低、網損增加等問題,無功優化成為保障配電網安全、經濟、高效運行的關鍵技術。 1. 核心目標 電壓穩定性:抑制DG并網點(PCC)及敏感節點的電壓越限(如超過5%…

JS手寫代碼篇---手寫Promise

4、手寫promise Promise 是一個內置對象&#xff0c;用于處理異步操作。Promise 對象表示一個尚未完成但預期將來會完成的操作。 Promise 的基本結構 一個 Promise 對象通常有以下狀態&#xff1a; pending&#xff08;進行中&#xff09;&#xff1a;初始狀態&#xff0c;…

我喜歡的vscode幾個插件和主題

主題 Monokaione Monokai Python 語義高光支持 自定義顏色為 self 將 class , def 顏色更改為紅色 為裝飾器修復奇怪的顏色 適用于魔法功能的椂光 Python One Dark 這個主題只在python中效果最好。 我為我個人使用做了這個主題,但任何人都可以使用它。 插件 1.Pylance Pylanc…

【深度學習新浪潮】大模型時代,我們還需要學習傳統機器學習么?

在大模型時代,AI 工程師仍需掌握傳統機器學習知識,這不僅是技術互補的需求,更是應對復雜場景和職業發展的關鍵。以下從必要性和學習路徑兩方面展開分析: 一、傳統機器學習在大模型時代的必要性 技術互補性 大模型(如GPT、BERT)擅長處理復雜語義和生成任務,但在數據量少…

年度工作計劃總結述職報告PPT模版一組分享

工作計劃總結述職報告PPT模版&#xff1a;工作計劃述職報告PPT模版https://pan.quark.cn/s/fba40a5e87da 第一套PPT模版是醫院年度工作計劃的封面頁&#xff0c;有藍橙配色、醫院標題、年度工作計劃的大字、英文副標題、匯報人信息和右上角的醫院logo區域&#xff0c;右側還有醫…

軟件設計師“排序算法”真題考點分析——求三連

一、考點分值占比與趨勢分析 綜合知識題分值統計表 年份考題數量總分值分值占比考察重點2018222.67%時間復雜度/穩定性判斷2019334.00%算法特性對比分析2020222.67%空間復雜度要求2021111.33%算法穩定性判斷2022334.00%綜合特性應用2023222.67%時間復雜度計算2024222.67%分治…

華為云Flexus+DeepSeek征文|基于華為云Flexus云服務的云服務器單機部署Dify-LLM應用開發平臺

目錄 一、前言 二、華為云Flexus云服務優勢 三、華為云Flexus一鍵部署Dify 3.1 選擇模板 3.2 參數配置 3.3 資源棧設置 3.4 配置確認 3.5 創建執行計劃 3.6 部署 四、Dify-LLM應用開發平臺初體驗 4.1 訪問Dify-LLM應用開發平臺 4.2 設置管理員賬戶 4.3 登錄Dify-LLM應用開發平臺…

智能指針RAII

引入&#xff1a;智能指針的意義是什么&#xff1f; RAll是一種利用對象生命周期來控制程序資源&#xff08;如內存、文件句柄、網絡連接、互斥量等等&#xff09;的簡單技術。 在對象構造時獲取資源&#xff0c;接著控制對資源的訪問使之在對象的生命周期內始終保持有效&#…

nt!MiRemovePageByColor函數分析之脫鏈和刷新顏色表

第0部分&#xff1a;背景 PFN_NUMBER FASTCALL MiRemoveZeroPage ( IN ULONG Color ) { ASSERT (Color < MmSecondaryColors); Page FreePagesByColor[Color].Flink; if (Page ! MM_EMPTY_LIST) { // // Remove the first entry on the zeroe…