1. 程式人生 > >Python面試寶典 ——Linux及Python語法面試題

Python面試寶典 ——Linux及Python語法面試題

一、大資料的檔案的讀取
1.讀取大幾G的大檔案,可以利用生成器 generator
2.對可迭代物件 file,進行迭代遍歷:for line in file,會自動地使用緩衝IO(buffered IO)以及記憶體管理,而不必擔心任何大檔案的問題。

with open('filename') as file:
    for line in file:
        do_things(line)

二、迭代器和生成器區別 ?
答:
( 1)迭代器是一個更抽象的概念,任何對如果它類有 )迭代器是一個更抽象的概念,任何對如果它類有 )迭代器是一個更抽象的概念,任何對如果它類有 )迭代器是一個更抽象的概念,任何對如果它類有 nextnextnextnext方法和 方法和 iteriteriteriter方法返回自己本身 。對於 strings、list、dict、tuple等這類容器物件,使用 forforfor循 環遍歷是很方便的。在後臺 for語句對容器象呼叫 iter()函式, iter()是 python的內建函式。 iter()會返回一個定義了 會返回一個定義了 next()方法的迭代器物件,它在容中逐個 方法的迭代器物件,它在容中逐個 方法的迭代器物件,它在容中逐個 訪問容器內元素, next()也是 python的內建函式。在沒有後續元素時, next()會 丟擲一個 StopIter異常
( 2)生成器( Generator)是建立迭代器的簡單而強大工具。它們寫起來就像 )是建立迭代器的簡單而強大工具。它們寫起來就像 )是建立迭代器的簡單而強大工具。它們寫起來就像 )是建立迭代器的簡單而強大工具。它們寫起來就像 是正規的函式,只在需要返回據時候使用 yield語句。每次 next()被呼叫 被呼叫 時,生成器會返回它脫離的位置(記憶語句最後一次執行和所有資料 時,生成器會返回它脫離的位置(記憶語句最後一次執行和所有資料 時,生成器會返回它脫離的位置(記憶語句最後一次執行和所有資料 值)
區別:生成器能做到迭代的所有事 區別:生成器能做到迭代的所有事 ,而且因為自動建立了 iter

()和 next()方法 ,生成器顯得特別簡潔 ,而且生成器也是高效的 而且生成器也是高效的 而且生成器也是高效的 ,使用生成器表 達式取代列,使用生成器表 達式取代列,使用生成器表 達式取代列解析可以同時節省 記憶體。除了建立和保程式狀態的自動方法 記憶體。除了建立和保程式狀態的自動方法 記憶體。除了建立和保程式狀態的自動方法 記憶體。除了建立和保程式狀態的自動方法 ,當發生器終結時 當發生器終結時 當發生器終結時 ,還會自動丟擲 StopIteration異常。Yield的用法有點像return,但是它返回的是一個生成器。

三、執行緒、程序、協程
程序是具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的一個獨立單位。每個程序都有自己的獨立記憶體空間,不同程序通過程序間通訊來通訊。由於程序比較重量,佔據獨立的記憶體,所以上下文程序間的切換開銷(棧、暫存器、虛擬記憶體、檔案控制代碼等)比較大,但相對比較穩定安全。
  執行緒是程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位.執行緒自己基本上不擁有系統資源,只擁有一點在執行中必不可少的資源(如程式計數器,一組暫存器和棧),但是它可與同屬一個程序的其他的執行緒共享程序所擁有的全部資源。執行緒間通訊主要通過共享記憶體,上下文切換很快,資源開銷較少,但相比程序不夠穩定容易丟失資料。
協程是一種使用者態的輕量級執行緒,協程的排程完全由使用者控制。協程擁有自己的暫存器上下文和棧。協程排程切換時,將暫存器上下文和棧儲存到其他地方,在切回來的時候,恢復先前儲存的暫存器上下文和棧,直接操作棧則基本沒有核心切換的開銷,可以不加鎖的訪問全域性變數,所以上下文的切換非常快。

四、 裝飾器
裝飾器是一個很著名的設計模式,經常被用於有切面需求的場景,較為經典的有插入日誌、效能測試、事務處理等。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量函式中與函式功能本身無關的雷同程式碼並繼續重用。概括的講,裝飾器的作用就是為已經存在的物件新增額外的功能。
裝飾器(decorator)裡引入通用功能處理:
引入日誌
函式執行時間統計
執行函式前預備處理
執行函式後清理功能
許可權校驗等場景
快取

from time import ctime, sleep
def timefun(func):
    def wrappedfunc
():
print("%s called at %s"%(func.__name__, ctime())) return func() return wrappedfunc @timefun def foo(): print("I am foo") foo() sleep(2) foo()

五、談談你對同步非同步阻塞非阻塞理解
所謂同步,就是在發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回。按照這個定義,其實絕大多數函式都是同步呼叫(例如sin, isdigit等)。但是一般而言,我們在說同步、非同步的時候,特指那些需要其他部件協作或者需要一定時間完成的任務。最常見的例子就是 SendMessage。該函式傳送一個訊息給某個視窗,在對方處理完訊息之前,這個函式不返回。當對方處理完畢以後,該函式才把訊息處理函式所返回的 LRESULT值返回給呼叫者。
非同步的概念和同步相對。當一個非同步過程呼叫發出後,呼叫者不能立刻得到結果。實際處理這個呼叫的部件在完成後,通過狀態、通知和回撥來通知呼叫者。以CAsycSocket類為例(注意,CSocket從CAsyncSocket派生,但是起功能已經由非同步轉化為同步),當一個客戶端通過呼叫 Connect函式發出一個連線請求後,呼叫者執行緒立刻可以朝下執行。當連線真正建立起來以後,socket底層會發送一個訊息通知該物件。這裡提到執行部件和呼叫者通過三種途徑返回結果:狀態、通知和回撥。可以使用哪一種依賴於執行部件的實現,除非執行部件提供多種選擇,否則不受呼叫者控制。如果執行部件用狀態來通知,那麼呼叫者就需要每隔一定時間檢查一次,效率就很低(有些初學多執行緒程式設計的人,總喜歡用一個迴圈去檢查某個變數的值,這其實是一種很嚴重的錯誤)。如果是使用通知的方式,效率則很高,因為執行部件幾乎不需要做額外的操作。至於回撥函式,其實和通知沒太多區別。
阻塞呼叫是指呼叫結果返回之前,當前執行緒會被掛起。函式只有在得到結果之後才會返回。有人也許會把阻塞呼叫和同步呼叫等同起來,實際上他是不同的。對於同步呼叫來說,很多時候當前執行緒還是啟用的,只是從邏輯上當前函式沒有返回而已。例如,我們在CSocket中呼叫Receive函式,如果緩衝區中沒有資料,這個函式就會一直等待,直到有資料才返回。而此時,當前執行緒還會繼續處理各種各樣的訊息。如果主視窗和呼叫函式在同一個執行緒中,除非你在特殊的介面操作函式中呼叫,其實主介面還是應該可以重新整理。socket接收資料的另外一個函式recv則是一個阻塞呼叫的例子。當socket工作在阻塞模式的時候,如果沒有資料的情況下呼叫該函式,則當前執行緒就會被掛起,直到有資料為止。
非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函式不會阻塞當前執行緒,而會立刻返回。
物件的阻塞模式和阻塞函式呼叫。物件是否處於阻塞模式和函式是不是阻塞呼叫有很強的相關性,但是並不是一一對應的。阻塞物件上可以有非阻塞的呼叫方式,我們可以通過一定的API去輪詢狀態,在適當的時候呼叫阻塞函式,就可以避免阻塞。而對於非阻塞物件,呼叫特殊的函式也可以進入阻塞呼叫。函式select就是這樣的一個例子。

六、 GIL對多執行緒的影響?
GIL的全稱是Global Interpreter Lock(全域性直譯器鎖),來源是python設計之初的考慮,為了資料安全所做的決定。每個CPU在同一時間只能執行一個執行緒(在單核CPU下的多執行緒其實都只是併發,不是並行,併發和並行從巨集觀上來講都是同時處理多路請求的概念。但併發和並行又有區別,並行是指兩個或者多個事件在同一時刻發生;而併發是指兩個或多個事件在同一時間間隔內發生。)
在Python多執行緒下,每個執行緒的執行方式:
1、獲取GIL
2、執行程式碼直到sleep或者是python虛擬機器將其掛起。
3、釋放GIL
可見,某個執行緒想要執行,必須先拿到GIL,我們可以把GIL看作是“通行證”,並且在一個python程序中,GIL只有一個。拿不到通行證的執行緒,就不允許進入CPU執行。
在Python2.x裡,GIL的釋放邏輯是當前執行緒遇見IO操作或者ticks計數達到100(ticks可以看作是Python自身的一個計數器,專門做用於GIL,每次釋放後歸零,這個計數可以通過 sys.setcheckinterval 來調整),進行釋放。而每次釋放GIL鎖,執行緒進行鎖競爭、切換執行緒,會消耗資源。並且由於GIL鎖存在,python裡一個程序永遠只能同時執行一個執行緒(拿到GIL的執行緒才能執行)。
IO密集型程式碼(檔案處理、網路爬蟲等),多執行緒能夠有效提升效率(單執行緒下有IO操作會進行IO等待,造成不必要的時間浪費,而開啟多執行緒能線上程A等待時,自動切換到執行緒B,可以不浪費CPU的資源,從而能提升程式執行效率),所以多執行緒對IO密集型程式碼比較友好。

七、 python中的反射?
python中反射的核心本質其實就是利用字串的形式去物件(模組)中操作(查詢/獲取/刪除/新增)成員,一種基於字串的事件驅動。

八、python2和python3的區別?
1.效能
Py3.0執行 pystone benchmark的速度比Py2.5慢30%。Guido認為Py3.0有極大的優化空間,在字串和整形操作上可
以取得很好的優化結果。
Py3.1效能比Py2.5慢15%,還有很大的提升空間。
2.編碼
Py3.X原始碼檔案預設使用utf-8編碼,這就使得以下程式碼是合法的:

 >>> 中國 = 'china' 
    >>>print(中國) 
    china 

3.語法
1)去除了<>,全部改用!=
2)去除“,全部改用repr()
3)關鍵詞加入as 和with,還有True,False,None
4)整型除法返回浮點數,要得到整型結果,請使用//
5)加入nonlocal語句。使用noclocal x可以直接指派外圍(非全域性)變數
6)去除print語句,加入print()函式實現相同的功能。同樣的還有 exec語句,已經改為exec()函式
7)改變了順序操作符的行為
8)輸入函式改變了,刪除了raw_input,用input代替:
2.X:guess = int(raw_input(‘Enter an integer : ‘)) # 讀取鍵盤輸入的方法
3.X:guess = int(input(‘Enter an integer : ‘))
9)去除元組引數解包。不能def(a, (b, c)):pass這樣定義函數了
10)新式的8進位制字變數,相應地修改了oct()函式。
11)增加了 2進位制字面量和bin()函式
12)擴充套件的可迭代解包。在Py3.X 裡,a, b, *rest = seq和 *rest, a = seq都是合法的,只要求兩點:rest是list
物件和seq是可迭代的。
13)新的super(),可以不再給super()傳引數,
14)新的metaclass語法:
class Foo(*bases, **kwds):
pass
15)支援class decorator。用法與函式decorator一樣:
4.字串和位元組串
1)現在字串只有str一種型別,但它跟2.x版本的unicode幾乎一樣。
2)關於位元組串,請參閱“資料型別”的第2條目
5.資料型別
1)Py3.X去除了long型別,現在只有一種整型——int,但它的行為就像2.X版本的long
2)新增了bytes型別,對應於2.X版本的八位串,定義一個bytes字面量的方法如下:
str物件和bytes物件可以使用.encode() (str -> bytes) or .decode() (bytes -> str)方法相互轉化。
3)dict的.keys()、.items 和.values()方法返回迭代器,而之前的iterkeys()等函式都被廢棄。同時去掉的還有
dict.has_key(),用 in替代它吧
6.面向物件
1)引入抽象基類(Abstraact Base Classes,ABCs)。
2)容器類和迭代器類被ABCs化,所以cellections模組裡的型別比Py2.5多了很多。

 >>> import collections 
    >>> print('\n'.join(dir(collections))) 

Callable Container Hashable ItemsView Iterable Iterator KeysView Mapping MappingView MutableMapping MutableSequence MutableSet NamedTuple Sequence Set Sized ValuesView all builtins doc file name _abcoll _itemgetter _sys defaultdict deque 另外,數值型別也被ABCs化。關於這兩點,請參閱 PEP 3119和PEP 3141。
3)迭代器的next()方法改名為next(),並增加內建函式next(),用以呼叫迭代器的next()方法
4)增加了@abstractmethod和 @abstractproperty兩個 decorator,編寫抽象方法(屬性)更加方便。
7.異常
1)所以異常都從 BaseException繼承,並刪除了StardardError
2)去除了異常類的序列行為和.message屬性
3)用 raise Exception(args)代替 raise Exception, args語法
4)捕獲異常的語法改變,引入了as關鍵字來標識異常例項
5)異常鏈,因為context在3.0a1版本中沒有實現
8.模組變動
1)移除了cPickle模組,可以使用pickle模組代替。最終我們將會有一個透明高效的模組。
2)移除了imageop模組
3)移除了 audiodev, Bastion, bsddb185, exceptions, linuxaudiodev, md5, MimeWriter, mimify, popen2,
rexec, sets, sha, stringold, strop, sunaudiodev, timing和xmllib模組
4)移除了bsddb模組
5)移除了new模組
6)os.tmpnam()和os.tmpfile()函式被移動到tmpfile模組下
7)tokenize模組現在使用bytes工作。主要的入口點不再是generate_tokens,而是 tokenize.tokenize()
9.其它
1)xrange() 改名為range(),要想使用range()獲得一個list,必須顯式呼叫:

    >>> list(range(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

2)bytes物件不能hash,也不支援 b.lower()、b.strip()和b.split()方法,但對於後兩者可以使用 b.strip(b’ \n\t\r \f’)和b.split(b’ ‘)來達到相同目的
3)zip()、map()和filter()都返回迭代器。而apply()、 callable()、coerce()、 execfile()、reduce()和reload ()函式都被去除了現在可以使用hasattr()來替換 callable(). hasattr()的語法如:hasattr(string, ‘name‘)
4)string.letters和相關的.lowercase和.uppercase被去除,請改用string.ascii_letters 等
5)如果x < y的不能比較,丟擲TypeError異常。2.x版本是返回偽隨機布林值的
6)getslice系列成員被廢棄。a[i:j]根據上下文轉換為a.getitem(slice(I, j))或 setitemdelitem呼叫
7)file類被廢棄

九、 什麼是pep8?
1變數
常量:大寫加下劃線 USER_CONSTANT
私有變數 : 小寫和一個前導下劃線 _private_value
Python 中不存在私有變數一說,若是遇到需要保護的變數,使用小寫和一個前導下劃線。但這只是程式設計師之間的一個約定,用於警告說明這是一個私有變數,外部類不要去訪問它。但實際上,外部類還是可以訪問到這個變數。
內建變數 : 小寫,兩個前導下劃線和兩個後置下劃線 class
兩個前導下劃線會導致變數在解釋期間被更名。這是為了避免內建變數和其他變數產生衝突。使用者定義的變數要嚴格避免這種風格。以免導致混亂。
2 函式和方法
總體而言應該使用,小寫和下劃線。但有些比較老的庫使用的是混合大小寫,即首單詞小寫,之後每個單詞第一個字母大寫,其餘小寫。但現在,小寫和下劃線已成為規範。
私有方法 :小寫和一個前導下劃線
def _secrete(self):
print “don’t test me.”
這裡和私有變數一樣,並不是真正的私有訪問許可權。同時也應該注意一般函式不要使用兩個前導下劃線(當遇到兩個前導下劃線時,Python 的名稱改編特性將發揮作用)。
特殊方法 :小寫和兩個前導下劃線,兩個後置下劃線
def add(self, other):
return int.add(other)
這種風格只應用於特殊函式,比如操作符過載等。
函式引數 : 小寫和下劃線,預設值等號兩邊無空格
3 類
類總是使用駝峰格式命名,即所有單詞首字母大寫其餘字母小寫。類名應該簡明,精確,並足以從中理解類所完成的工作。常見的一個方法是使用表示其型別或者特性的字尾,例如:
SQLEngine,MimeTypes對於基類而言,可以使用一個 Base 或者 Abstract 字首BaseCookie,AbstractGroup
4 模組和包
除特殊模組 init 之外,模組名稱都使用不帶下劃線的小寫字母。
若是它們實現一個協議,那麼通常使用lib為字尾,例如:
import smtplib
import os
import sys
5 關於引數
5.1 不要用斷言來實現靜態型別檢測。斷言可以用於檢查引數,但不應僅僅是進行靜態型別檢測。 Python 是動態型別語言,靜態型別檢測違背了其設計思想。斷言應該用於避免函式不被毫無意義的呼叫。
5.2 不要濫用 *args 和 **kwargs。*args 和 **kwargs 引數可能會破壞函式的健壯性。它們使簽名變得模糊,而且程式碼常常開始在不應該的地方構建小的引數解析器。
6 其他
6.1 使用 has 或 is 字首命名布林元素
is_connect = True
has_member = False
6.2 用複數形式命名序列
members = [‘user_1’, ‘user_2’]
6.3 用顯式名稱命名字典
person_address = {‘user_1’:’10 road WD’, ‘user_2’ : ‘20 street huafu’}
6.4 避免通用名稱
諸如 list, dict, sequence 或者 element 這樣的名稱應該避免。
6.5 避免現有名稱
諸如 os, sys 這種系統已經存在的名稱應該避免。
7 一些數字
一行列數 : PEP 8 規定為 79 列。根據自己的情況,比如不要超過滿屏時編輯器的顯示列數。
一個函式 : 不要超過 30 行程式碼, 即可顯示在一個螢幕類,可以不使用垂直遊標即可看到整個函式。
一個類 : 不要超過 200 行程式碼,不要有超過 10 個方法。一個模組 不要超過 500 行。
8 驗證指令碼
可以安裝一個 pep8 指令碼用於驗證你的程式碼風格是否符合 PEP8。

十、什麼是執行緒安全?
執行緒安全是在多執行緒的環境下,能夠保證多個執行緒同時執行時程式依舊執行正確, 而且要保證對於共享的資料可以由多個執行緒存取,但是同一時刻只能有一個執行緒進行存取。多執行緒環境下解決資源競爭問題的辦法是加鎖來保證存取操作的唯一性。

十一、 十個常用的linux命令?
Ls,help,cd ,more,clear,mkdir,pwd,rm,grep,find,mv,su,date…

十二、find和grep?
grep命令是一種強大的文字搜尋工具,grep搜尋內容串可以是正則表示式,允許對文字檔案進行模式查詢。如果找到匹配模式, grep列印包含模式的所有行。
find通常用來在特定的目錄下搜尋符合條件的檔案,也可以用來搜尋特定使用者屬主的檔案。

十三、什麼是面向物件程式設計?
面向物件程式設計是一種解決軟體複用的設計和程式設計方法。 這種方法把軟體系統中相近相似的操作邏輯和操作 應用資料、狀態,以類的型式描述出來,以物件例項的形式在軟體系統中複用,以達到提高軟體開發效率的作用。

十四、面向物件有那些技術?
類(Class): 用來描述具有相同的屬性和方法的物件的集合。它定義了該集合中每個物件所共有的屬性和方法。物件是類的例項。
類變數:類變數在整個例項化的物件中是公用的。類變數定義在類中且在函式體之外。類變數通常不作為例項變數使用。
資料成員:類變數或者例項變數用於處理類及其例項物件的相關的資料。
方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。
例項變數:定義在方法中的變數,只作用於當前例項的類。
繼承:即一個派生類(derived class)繼承基類(base class)的欄位和方法。繼承也允許把一個派生類的物件作為一個基類物件對待。例如,有這樣一個設計:一個Dog型別的物件派生自Animal類,這是模擬”是一個(is-a)”關係(例圖,Dog是一個Animal)。
例項化:建立一個類的例項,類的具體物件。
方法:類中定義的函式。
物件:通過類定義的資料結構例項。物件包括兩個資料成員(類變數和例項變數)和方法。

十五、 靜態方法和類方法?
靜態方法:需要通過修飾器@staticmethod來進行修飾,靜態方法不需要多定義引數。
類方法:類方法是類物件所擁有的方法,需要用修飾器@classmethod來標識其為類方法,對於類方法,第一個引數必須是類物件,一般以cls作為第一個引數(也可以用其他名稱的變數作為其第一個引數),能夠通過例項物件和類物件去訪問。

十六、 類屬性、例項屬性?
類屬性:定義在類裡面但在函式外面的變數,是靜態的。類物件所擁有的屬性,它被所有類物件的例項物件所共有,在記憶體中只存在一個副本。對於公有的類屬性,在類外可以通過類物件和例項物件訪問。
例項屬性:定義在init()方法裡的變數就是例項屬性,這些屬性只有被建立時才會被建立。
當類屬性與例項屬性同名時,一個例項訪問這個屬性時例項屬性會覆蓋類屬性

十七、 如果你需要執行一個定時任務,你會怎麼做?
Linux的Crontab 執行命令: sudo crontab -e
例:0 /1 * * /usr/local/etc/rc.d/lighttpd restart 每一小時重啟apache

十八、 線上服務可能因為種種原因導致掛掉怎麼辦?
Linux下的後臺程序管理利器 supervisor
每次檔案修改後在linux執行:service supervisord restart

十九、 python的多程序與多執行緒的執行機制是什麼?有什麼區別?分別在什麼情況下用?
執行機制:程序是具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的一個獨立單位
執行緒是程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位.執行緒自己基本上不擁有系統資源,只擁有一點在執行中必不可少的資源(如果製造資料的速度時快時慢,緩衝區的好處就體現出來了。當資料製造快的時候,消費者來不及處理,未處理的資料可以暫時存在緩衝區中。
程式計數器,一組暫存器和棧),但是它可與同屬一個程序的其他的執行緒共享程序所擁有的全部資源.
區別:
多程序穩定性好,一個子程序崩潰了,不會影響主程序以及其餘程序。但是缺點是建立程序的代價非常大,因為作業系統要給每個程序分配固定的資源,並且,作業系統對程序的總數會有一定的限制,若程序過多,作業系統排程都會存在問題,會造成假死狀態。
多執行緒效率較高一些,但是致命的缺點是任何一個執行緒崩潰都可能造成整個程序的崩潰,因為它們共享了程序的記憶體資源池。
使用情況:如果程式碼是IO密集型的,多執行緒。
如果程式碼是CPU密集型的,多程序是更好的選擇——特別是所使用的機器是多核或多CPU的。

二十、 如何提高Python的執行效率,請說出不少於2種提高執行效率的方法。
使用生成器
關鍵程式碼使用外部功能包:Cython、Pylnlne、PyPy、Pyrex
針對迴圈的優化——儘量避免在迴圈中訪問變數的屬性;

二十一、 介紹下“消費者”和“生產者”模型。
生產者-消費者模型是多執行緒同步的經典案例。此模型中生產者向緩衝區push資料,消費者從緩衝區中pull資料。
這個Demo中緩衝區用python實現的Queue來做,這個模組是執行緒安全的使開發者不用再為佇列增加額外的互斥鎖.
訊號處理的實現是這樣的:
1)主執行緒接到一個SIGTERM的訊號後先通知Consumer停止向緩衝區push資料並退出
2)Produer將緩衝區中的資料消費完全後在退出
3)主執行緒退出
生產者消費者模型的優點:
1、解耦
假設生產者和消費者分別是兩個類。如果讓生產者直接呼叫消費者的某個方法,那麼生產者對於消費者就會產生依賴(也就是耦合)。將來如果消費者的程式碼發生變化, 可能會影響到生產者。而如果兩者都依賴於某個緩衝區,兩者之間不直接依賴,耦合也就相應降低了。
2、支援併發
由於生產者與消費者是兩個獨立的併發體,他們之間是用緩衝區作為橋樑連線,生產者只需要往緩衝區裡丟資料,就可以繼續生產下一個資料,而消費者只需要從緩衝區了拿資料即可,這樣就不會因為彼此的處理速度而發生阻塞。
3、支援忙閒不均
如果製造資料的速度時快時慢,緩衝區的好處就體現出來了。當資料製造快的時候,消費者來不及處理,未處理的資料可以暫時存在緩衝區中。 等生產者的製造速度慢下來,消費者再慢慢處理掉。

有興趣學習、提升的同學可以加群705673780,大家一起交流學習哦,群內更有免費資料可供學習~