1. 程式人生 > 其它 >【Python實現】微信防撤回

【Python實現】微信防撤回

2) 檔案系統的理解(EXT4XFSBTRFS

檔案系統主要用於控制所有程式在不使用資料時如何儲存資料、如何訪問資料以及有什麼其它資訊(元資料)和資料本身相關。

Linux 作業系統即便使用標準安裝過程,在同一塊磁碟上仍使用多個分割槽。擁有不同分割槽的一個主要目的就是為了在災難發生時能獲得更好的資料安全性。

EXT4:使用廣泛,Linux現在預設的是廣泛採用的 ext4易用性以及廣泛性

XFSXFS 檔案系統是擴充套件檔案系統的一個擴充套件,XFS 檔案系統有一些缺陷,例如它不能壓縮,刪除大量檔案時效能低下。

btrfs:有很多好用的功能,例如寫複製、擴充套件校驗、快照、清洗、自修複數據、冗餘刪除以及其它保證資料完整性的功能。

 

3) 檔案處理grep,awk,sed這三個命令必知必會

grep文字過濾器,命令用於列印輸出文字中匹配的模式串,它使用正則表示式作為模式匹配的條件。

Sed  是一種線上編輯器,它一次處理一行內容。。

awk    是一種用於處理文字的程式語言工具。

 

9) 硬連線和軟連線的區別

APUE 4.154.16

硬連結:

AB的硬連結(AB都是檔名),則A的目錄項中的inode節點號與B的目錄項中的inode節點號相同,即一個inode節點對應兩個不同的檔名,兩個檔名指向同一個檔案,AB對檔案系統來說是完全平等的。如果刪除了其中一個,對另外一個沒有影響。每增加一個檔名,inode

節點上的連結數增加一,每刪除一個對應的檔名,inode節點上的連結數減一,直到為0inode節點和對應的資料塊被回收。注:檔案和檔名是不同的東西,rm A刪除的只是A這個檔名,而A對應的資料塊(檔案)只有在inode節點連結數減少為0的時候才會被系統回收。

軟連結:

AB的軟連結(AB都是檔名),A的目錄項中的inode節點號與B的目錄項中的inode節點號不相同,AB指向的是兩個不同的inode,繼而指向兩塊不同的資料塊。但是A的資料塊中存放的只是B的路徑名(可以根據這個找到B的目錄項)。AB之間是“主從”關係,如果B被刪除了,A仍然存在(因為兩個是不同的檔案),但指向的是一個無效的連結。

 

區別:

硬連結實際上是為檔案建一個別名,連結檔案和原檔案實際上是同一個檔案。可以通過ls -i來檢視一下,這兩個檔案的inode號是同一個,說明它們是同一個檔案;而軟連結建立的是一個指向,即連結檔案內的內容是指向原檔案的指標,它們是兩個檔案。

軟連結可以跨檔案系統,硬連結不可以;

軟連結可以對一個不存在的檔名(filename)進行連結(當然此時如果你vi這個軟連結檔案,linux會自動新建一個檔名為filename的檔案),硬連結不可以(其檔案必須存在,inode必須存在);

軟連結可以對目錄進行連線,硬連結不可以。

 


10) 檔案許可權怎麼看(rwx

檔案許可權檢視ls -l,檢視檔案所有者,所屬組,其他的檔案許可權,rwx777

修改使用chmod命令


11) 檔案的三種時間(mtime, atimectime),分別在什麼時候會改變

 

更改狀態時間是該檔案的i節點最後一次被修改的時間。在本章中我們已說明了很多操作,它們影響到i節點,但並沒有更改檔案的實際內容:檔案的存取許可權、使用者I D、連線數等等。因為i節點中的所有資訊都是與檔案的實際內容分開存放的,所以,除了檔案資料修改時間以外,還需要更改狀態時間。

 

14) 檔案讀寫使用的系統呼叫

讀檔案:

int fd = -1;

char filename[] = "/root/test.txt";

fd = open(filename,O_RDONLY);

size = read(fd,buf,10);

close(fd);

 

寫檔案:

int fd = -1;

char buf[] = "boys and girls\n hi,children!";

fd = open(filename,O_RDWR|O_APPEND);

size = write(fd,buf,strlen(buf));

close(fd);

 

二、IO


1LinuxI/O模型介紹、過程、區別以及同步非同步阻塞非阻塞的區別(超級重要)

阻塞IO是在兩個過程應用都處於阻塞狀態。程序或執行緒呼叫某個函式,該函式需要滿足特定條件才能向下執行。如果條件不滿足,則會使呼叫程序或執行緒阻塞,讓出CPU控制權,並一直持續到條件滿足為止。

非阻塞IO是應用發出IO操作後可以立刻返回,通過輪詢盤判斷資料是否準備好,在copy資料階段阻塞應用。

IO多路複用:是阻塞呼叫select,查詢可用的套接字,如果有套接字可用,那麼就阻塞呼叫(recvfrom)完成資料的copy過程。Linux select就是這種模型,缺點是一次select會掃描所有的socket

訊號驅動IO是應用發出SIGIO後立刻返回,核心中資料準備好後,通知應用,由應用進行阻塞recvfrom呼叫從核心copy資料。linux epoll就是基於事件的就緒通知方式,省去了所有socket的掃描開銷。

非同步IO是應用發出aio-read後馬上返回,資料準備好後,由作業系統把資料copy到應用,並通知應用資料copy完成。

 

阻塞:使用者程序訪問資料時,如果未完成IO,呼叫的程序一直處於等待狀態,直到IO操作完成。

非阻塞:使用者程序訪問資料時,會馬上返回一個狀態值,無論是否完成,此時程序可以操作其他事情。
    同步:使用者程序發起IO後,進行就緒判斷,輪詢核心狀態。

非同步:使用者程序發起IO後,可以做其他事情,等待核心通知。


4IO複用的三種方法(select,poll,epoll)深入理解,包括三者區別,內部原理實現?

selectpollepoll都是IO多路複用的機制I/O多路複用就通過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程式進行相應的讀寫操作。但selectpollepoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒後自己負責進行讀寫,也就是說這個讀寫過程是阻塞的,而非同步I/O則無需自己負責進行讀寫,非同步I/O的實現會負責把資料從核心拷貝到使用者空間

select:是最初解決IO阻塞問題的方法。用結構體fd_set來告訴核心監聽多個檔案描述符,該結構體被稱為描述符集。由陣列來維持哪些描述符被置位了。對結構體的操作封裝在三個巨集定義中。通過輪尋來查詢是否有描述符要被處理,如果沒有返回。

存在的問題:內建陣列的形式使得select的最大檔案數受限與FD_SIZE;每次呼叫select前都要重新初始化描述符集,將fd從使用者態拷貝到核心態,每次呼叫select後,都需要將fd從核心態拷貝到使用者態;輪尋排查當檔案描述符個數很多時,效率很低;

poll:通過一個可變長度的陣列解決了select檔案描述符受限的問題。陣列中元素是結構體,該結構體儲存描述符的資訊,每增加一個檔案描述符就向陣列中加入一個結構體,結構體只需要拷貝一次到核心態。poll解決了select重複初始化的問題。輪尋排查的問題未解決。

epoll:輪尋排查所有檔案描述符的效率不高,使伺服器併發能力受限。因此,epoll採用只返回狀態發生變化的檔案描述符,便解決了輪尋的瓶頸。


5EpollET模式和LT模式(ET的非阻塞)

LT:level trigger, 水平觸發模式

ET:edge trigger, 邊緣觸發模式

相同點:都是通過epoll_waitEPOLL等待佇列讀取啟用事件
區別:1. LT模式讀取啟用事件後,如果還有未處理的資料。事件會重新放入EPOLL等待佇列。2. ET模式讀取啟用事件,直接從EPOLL等待佇列移除,不管是否有未處理的資料

 

LT模式問題:如果可讀或可寫事件未處理,會頻繁啟用未處理事件

解決方法:不想處理讀寫事件時, EPOLL中移除控制代碼。需要處理時再加入EPOLL

 

ET模式問題:如果可讀或可寫沒有全部處理,會有老資料殘留。要等待新資料到來。

解決方法:1. 迴圈讀取或寫入資料,一直到EAGAINEWOULDBLOCK

2. 讀取或者寫入資料後,通過epoll_ctl設定EPOLL_CTL_MOD,啟用未處理事件

 

ET模式餓死問題處理方法:

應用層維護一個list, 儲存epoll_wait返回的就緒檔案描述符, 然後迴圈處理

list不為空時, 進行迴圈處理其中事件

每個檔案描述符只進行一定限度的 IO 操作, 比如每次限定只讀 1KB 資料, 然後繼續處理其他的檔案描述符

如果該檔案描述符讀了 1KB 沒讀完 (沒有返回EAGIN / EWOULDBLOCK), 就繼續停留在list, 反之如果其上的 IO 操作執行完了, 就將其移除list

 

上一題中程式設計的時候有什麼區別,是在邊緣觸發的時候要把套接字中的資料讀乾淨,那麼當有多個套接字時,在讀的套接字一直不停的有資料到達,如何保證其他套接字不被餓死(面試網易遊戲的時候問的一個問題,答不上來,印象賊深刻)

 

 

 

三、程序

13Linux程序管理

在很多情況下,程序都是動態建立並由一個動態分配的 task_struct 表示。一個例外是 init 程序本身,它總是存在並由一個靜態分配的 task_struct 表示。在 ./linux/arch/i386/kernel/init_task.c 內可以找到這樣的一個例子。

Linux 內所有程序的分配有兩種方式。第一種方式是通過一個雜湊表,由 PID 值進行雜湊計算得到;第二種方式是通過雙鏈迴圈表。迴圈表非常適合於對任務列表進行迭代。由於列表是迴圈的,沒有頭或尾;但是由於 init_task 總是存在,所以可以將其用作繼續向前迭代的一個錨點

 

15fork返回值是什麼?

fork函式通過系統呼叫建立一個與原來程序幾乎完全相同的程序,也就是兩個程序可以做完全相同的事,但如果初始引數或者傳入的變數不同,兩個程序也可以做不同的事。

它可能有三種不同的返回值:

    1在父程序中,fork返回新建立子程序的程序ID

    2在子程序中,fork返回0

    3如果出現錯誤,fork返回一個負值

17守護程序、孤兒程序、殭屍程序問題

    守護程序:

通常在系統後臺執行,沒有控制終端,不與前臺互動,Daemon程式一般作為系統服務使用。Daemon是長時間執行的程序,通常在系統啟動後就執行,在系統關閉是才結束。一般說Daemon程式在後臺執行,是因為它沒有控制終端,無法和前臺的使用者互動。Daemon程式一般都作為服務程式使用,等待客戶端程式與它通訊。我們把執行的Daemon程式稱作守護程序。

 

孤兒程序:

一個父程序退出,而它的一個或多個子程序還在執行,那麼這些子程序將成為孤兒程序。孤兒程序將被 init 程序(程序號為 1)所收養,並由 init 程序對它們完成狀態收集工作。由於孤兒程序會被 init 程序收養,所以孤兒程序不會對系統造成危害。

 

殭屍程序:

一個子程序的程序描述符在子程序退出時不會釋放,只有當父程序通過 wait() waitpid() 獲取了子程序資訊後才會釋放。如果子程序退出,而父程序並沒有呼叫 wait() waitpid(),那麼子程序的程序描述符仍然儲存在系統中,這種程序稱之為殭屍程序。

殭屍程序通過 ps 命令顯示出來的狀態為 Zzombie)。

系統所能使用的程序號是有限的,如果產生大量殭屍程序,將因為沒有可用的程序號而導致系統不能產生新的程序。

要消滅系統中大量的殭屍程序,只需要將其父程序殺死,此時殭屍程序就會變成孤兒程序,從而被 init 程序所收養,這樣 init 程序就會釋放所有的殭屍程序所佔有的資源,從而結束殭屍程序。

 

 

17)處理殭屍程序的兩種經典方法

父程序回收法:

wait函式將使其呼叫者阻塞,直到其某個子程序終止。故父程序可呼叫wait函式回收其殭屍子程序。

init程序回收法:

上面的這種解決方案需要父程序去等待子程序,但在很多情況下,這並不合適,因為父程序也許還有其他任務要做,不能阻塞在這裡。在講述下面這種不用父程序等待就能完成回收子程序的方法之前,先請明白以下兩個概念:

1. 如果父程序先於子程序結束,那麼子程序的父程序自動改為 init 程序。

2. 如果 init 的子程序結束,則 init 程序會自動回收其子程序的資源而不是讓它變成殭屍程序。

 

18)程序終止的幾種方式

1main函式的自然返回,return

2、呼叫exit函式

3、呼叫_exit函式

4、呼叫abort函式

5、接受能導致程序終止的訊號:

 

exit_exit函式都是用來終止程序的。當程式執行到exit_exit時,程序會無條件的停止剩下的所有操作,清除包括PCB在內的各種資料結構,並終止本程式的執行。

exit函式和_exit函式的最大區別在於exit函式在退出之前會檢查檔案的開啟情況,把檔案緩衝區中的內容寫回檔案,也就是清理I/O緩衝

abort()是使異常程式終止,同時傳送SIGABRT訊號給呼叫程序。

 

四、執行緒

 

 

五、記憶體管理

 

16)什麼是虛擬記憶體?

1. 每個程序都有自己獨立的4G記憶體空間,各個程序的記憶體空間具有類似的結構

2. 一個新程序建立的時候,將會建立起自己的記憶體空間,此程序的資料,程式碼等從磁碟拷貝到自己的程序空間,哪些資料在哪裡,都由程序控制表中的task_struct記錄,task_struct中記錄中一條連結串列,記錄中記憶體空間的分配情況,哪些地址有資料,哪些地址無資料,哪些可讀,哪些可寫,都可以通過這個連結串列記錄

3. 每個程序已經分配的記憶體空間,都與對應的磁碟空間對映

 

 

1. 每個程序的4G記憶體空間只是虛擬記憶體空間,每次訪問記憶體空間的某個地址,都需要把地址翻譯為實際實體記憶體地址

2. 所有程序共享同一實體記憶體,每個程序只把自己目前需要的虛擬記憶體空間對映並存儲到實體記憶體上。

3. 程序要知道哪些記憶體地址上的資料在實體記憶體上,哪些不在,還有在實體記憶體上的哪裡,需要用頁表來記錄

4.頁表的每一個表項分兩部分,第一部分記錄此頁是否在實體記憶體上,第二部分記錄實體記憶體頁的地址(如果在的話)

5. 當程序訪問某個虛擬地址,去看頁表,如果發現對應的資料不在實體記憶體中,則缺頁異常

6.缺頁異常的處理過程,就是把程序需要的資料從磁碟上拷貝到實體記憶體中,如果記憶體已經滿了,沒有空地方了,那就找一個頁覆蓋,當然如果被覆蓋的頁曾經被修改過,需要將此頁寫回磁碟

 

17Linux是如何避免記憶體碎片的

夥伴演算法,用於管理實體記憶體,避免記憶體碎片;

快取記憶體Slab層用於管理核心分配記憶體,避免碎片。

 

 

六、常用命令
6) 查詢程序佔用CPU的命令(注意要了解到usedbuf***代表意義)


7linux的其他常見命令(killfindcp等等)


8shell指令碼用法

 


12Linux監控網路頻寬的命令,檢視特定程序的佔用網路資源情況命令

 

18Linux基本命令?

命令 作用

pwd     顯示當前目錄

rm     刪除

touch 生成檔案

cat     讀取指定檔案的內容並列印到終端輸出

mkdir 新建目錄make directory

file     檢視檔案型別

whereiswhichfind locate 查詢

chown 改變檔案所有者

df     檢視磁碟容量

wc     計數工具

tr     刪除一段文字資訊中的某些文字。或者將其進行轉換

join     連線兩個檔案

paste 它是在不對比資料的情況下,簡單地將多個檔案合併一起,以Tab隔開

 

 

Linux核心

 

1Linux核心的程序排程