大廠 Python常見面試20題(整理版)

1.python的數(shù)據(jù)結(jié)構(gòu)?
整數(shù)(int)
浮點(diǎn)(float)
字符串(str)
布爾(bool)
列表(list)
元組(tuple)
字典(dict)
集合(set)
2.python中列表和元組的區(qū)別?
列表:list是可變類型,數(shù)據(jù)可以動(dòng)態(tài)變化
元組:tuple是不可變類型,數(shù)據(jù)大小固定
3.什么是生產(chǎn)器、迭代器?二者有何區(qū)別?
迭代器:
作用:簡化循環(huán)的代碼并可以節(jié)約內(nèi)存
是一個(gè)可以記住遍歷的位置的對象。迭代器對象從集合的第一個(gè)元素開始訪問,直到所有的元素被訪問完結(jié)束。迭代器只能往前不會(huì)后退
迭代器有兩個(gè)基本的方法:iter() 和 next()。
生成器:
作用:節(jié)約大量內(nèi)存 使用了 yield 的函數(shù)被稱為生成器、生成器是一個(gè)返回迭代器的函數(shù),只能用于迭代操作,更簡單點(diǎn)理解生成器就是一個(gè)迭代器 原理:在調(diào)用生成器運(yùn)行的過程中,每次遇到 yield 時(shí)函數(shù)會(huì)暫停并保存當(dāng)前所有的運(yùn)行信息,返回 yield 的值, 并在下一次執(zhí)行 next() 方法時(shí)從當(dāng)前位置繼續(xù)運(yùn)行。
4.什么是閉包?什么是裝飾器?裝飾器作用是?
閉包是指Python中將組成函數(shù)的語言和這些語言的執(zhí)行環(huán)境打包到一起所得到的對象
裝飾器是一種增加函數(shù)或類功能的簡單方法,它可以快速給不同的函數(shù)或類插入相同的功能。語法:“@裝飾器名”加在函數(shù)之前.
5.什么是匿名函數(shù)?好處?
匿名函數(shù):使用lambda創(chuàng)建的函數(shù),所謂匿名,意即不再使用 def 語句這樣標(biāo)準(zhǔn)的形式定義一個(gè)函數(shù)。
好處:
1、使用Python寫一些執(zhí)行腳本時(shí),使用lambda可以省去定義函數(shù)的過程,讓代碼更加精簡。 2、對于一些抽象的,不會(huì)別的地方再復(fù)用的函數(shù),有時(shí)候給函數(shù)起個(gè)名字也是個(gè)難題,使用lambda不需要考慮命名的問題。 3、使用lambda在某些時(shí)候讓代碼更容易理解。 應(yīng)用場景:經(jīng)常與一些內(nèi)置函數(shù)相結(jié)合使用,比如說map()、filter()、sorted()、reduce()等
表達(dá)式格式:lambda 參數(shù)列表: lambda體。
6.用過類嗎?知道繼承嗎?請寫一個(gè)例子,用到繼承
7. 深拷貝與淺拷貝
淺拷貝,改變原始對象中為可變類型的元素的值,會(huì)同時(shí)影響拷貝對象;改變原始對象中為不可變類型的元素的值,不會(huì)響拷貝對象。
深拷貝,除了頂層拷貝,還對子元素也進(jìn)行了拷貝。經(jīng)過深拷貝后,原始對象和拷貝對象所有的可變元素地址都沒有相同的了
8、列舉8個(gè)常用模塊都有那些?
os模塊:提供了不少與操作系統(tǒng)相關(guān)聯(lián)的函數(shù).
sys模塊:通用工具腳本經(jīng)常調(diào)用命令行參數(shù).
re模塊:為高級字符串處理提供了正則表達(dá)式工具。對于復(fù)雜的匹配和處理,正則表達(dá)式提供了簡潔、優(yōu)化的解決方案:
random模塊:提供了生成隨機(jī)數(shù)的工具。
json模塊:提供Python解析json數(shù)據(jù)的方法,和python格式相互轉(zhuǎn)化的方法
time模塊:python中用于處理時(shí)間的模塊
logging模塊:python中關(guān)于日志處理的模塊
xml模塊:python爬蟲中用于定位html標(biāo)簽的模塊
9.python的垃圾回收機(jī)制(了解)
python采用的是引用計(jì)數(shù)機(jī)制為主,標(biāo)記-清除和分代收集(隔代回收、分代回收)兩種機(jī)制為輔的策略
計(jì)數(shù)機(jī)制:
Python的GC模塊主要運(yùn)用了引用計(jì)數(shù)來跟蹤和回收垃圾。在引用計(jì)數(shù)的基礎(chǔ)上,還可以通過“標(biāo)記-清除”解決容器對象可能產(chǎn)生的循環(huán)引用的問題。通過分代回收以空間換取時(shí)間進(jìn)一步提高垃圾回收的效率。
標(biāo)記-清除:
標(biāo)記-清除的出現(xiàn)打破了循環(huán)引用,也就是它只關(guān)注那些可能會(huì)產(chǎn)生循環(huán)引用的對象 缺點(diǎn):該機(jī)制所帶來的額外操作和需要回收的內(nèi)存塊成正比。
隔代回收原理:將系統(tǒng)中的所有內(nèi)存塊根據(jù)其存活時(shí)間劃分為不同的集合,每一個(gè)集合就成為一個(gè)“代”,垃圾收集的頻率隨著“代”的存活時(shí)間的增大而減小。也就是說,活得越長的對象,就越不可能是垃圾,就應(yīng)該減少對它的垃圾收集頻率。那么如何來衡量這個(gè)存活時(shí)間:通常是利用幾次垃圾收集動(dòng)作來衡量,如果一個(gè)對象經(jīng)過的垃圾收集次數(shù)越多,可以得出:該對象存活時(shí)間就越長。
10.列表和數(shù)組的區(qū)別?
列表(List):存儲(chǔ)不同類型的元素,并且可以隨意增加、刪除或修改其中的元素?大小不是固定的
數(shù)組(Array):是一種固定大小的數(shù)據(jù)結(jié)構(gòu),它只能存儲(chǔ)相同類型的元素,其內(nèi)存空間是連續(xù)的、預(yù)先分配好的所以數(shù)組的訪問速度比列表快得多。
11.append()和extend()的區(qū)別?
append
方法可以將一個(gè)元素添加到列表的末尾。 方法可以將另一個(gè)列表中的所有元素添加到當(dāng)前列表末尾。extend
舉個(gè)例子:
<<<a = [1, 2, 3]
<<<b = [4, 5, 6]
<<<a.append(b)
<<<print(a)
[1, 2, 3, [4, 5, 6]]
<<<a = [1, 2, 3]
<<<a.extend(b)
<<<print(a)
[1, 2, 3, 4, 5, 6]
12.== 和 is 區(qū)別?
在Python中,“==”和“is”是兩個(gè)不同的操作符,用于比較對象之間的相等性。
"=="操作符用于比較兩個(gè)對象的值是否相等。它會(huì)通過比較對象的內(nèi)容來判斷它們是否相等。例如:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # 輸出: True
上述代碼中,盡管a和b是兩個(gè)不同的對象,但它們的值是相等的,所以使用“==”操作符進(jìn)行比較會(huì)返回True。
而"is"操作符則用于比較兩個(gè)對象是否是同一個(gè)對象(在內(nèi)存中的同一位置)。它會(huì)檢查兩個(gè)對象的身份標(biāo)識(shí)是否相同。例如:
a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) ?# 輸出: False
上述代碼中,盡管a和b的值相等,但它們是兩個(gè)不同的對象,所以使用“is”操作符進(jìn)行比較會(huì)返回False。
需要注意的是,在Python中,小整數(shù)對象[-5, 256]在解釋器啟動(dòng)時(shí)會(huì)被提前創(chuàng)建,并且會(huì)被重復(fù)使用。因此,對于這個(gè)范圍內(nèi)的整數(shù)對象,使用“is”操作符進(jìn)行比較可能會(huì)返回True。例如:
a = 10
b = 10
print(a is b) ?# 輸出: True`
但對于大整數(shù)對象或其他類型的對象,使用“is”操作符進(jìn)行比較通常會(huì)返回False。因此,在一般情況下,我們應(yīng)該使用"=="操作符來比較對象的值是否相等。
13.break,continue,pass區(qū)別?
break、continue和pass是Python中的三種控制語句,它們的作用不同。
break語句用于跳出循環(huán),即在循環(huán)體中遇到break語句時(shí),立即退出循環(huán),不再執(zhí)行循環(huán)體中剩余的語句,繼續(xù)執(zhí)行循環(huán)后面的語句。
continue語句用于跳過本次循環(huán),即在循環(huán)體中遇到continue語句時(shí),立即跳過本次循環(huán),繼續(xù)執(zhí)行下一次循環(huán)。
pass語句用于占位,即在程序中需要一個(gè)語句,但暫時(shí)不需要執(zhí)行任何操作時(shí),可以使用pass語句占位,使程序不會(huì)出錯(cuò)。
14.局部變量和全局變量區(qū)別?
局部變量和全局變量是Python中的兩種不同的變量作用域。
局部變量是在函數(shù)內(nèi)部定義的變量,其作用范圍僅限于函數(shù)內(nèi)部。當(dāng)函數(shù)執(zhí)行結(jié)束后,局部變量會(huì)被銷毀,無法在函數(shù)外部訪問。
全局變量是在函數(shù)外部定義的變量,其作用范圍可以是整個(gè)程序。全局變量可以在程序的任何地方訪問和修改。
在函數(shù)內(nèi)部,如果要修改全局變量的值,需要使用關(guān)鍵字global進(jìn)行聲明。否則,如果在函數(shù)內(nèi)部直接對全局變量進(jìn)行賦值操作,將會(huì)創(chuàng)建一個(gè)新的局部變量,并不會(huì)修改全局變量的值。`
總結(jié)來說,局部變量只在定義它們的函數(shù)內(nèi)部可見,而全局變量在整個(gè)程序中都可見。
16.xrange和range區(qū)別?
xrange用法和range完全一樣,不同的是range生成的是一個(gè)list對象,而xrange生成的是一個(gè)生成器。
在處理很大的數(shù)字序列的時(shí)候,xrange會(huì)比range性能高很多,因?yàn)椴挥靡簧蟻砭烷_辟很大的內(nèi)存空間。
17.什么是裝飾器?
給已有函數(shù)增加額外功能的函數(shù),它本質(zhì)上就是一個(gè)閉包函數(shù)。
裝飾器的功能特點(diǎn):不修改已有函數(shù)的源代碼;不修改已有函數(shù)的調(diào)用方式;給已有函數(shù)增加額外的功能。
18.什么是GIL?
GIL是python的全局解釋器鎖,同一進(jìn)程中假如有多個(gè)線程運(yùn)行,一個(gè)線程在運(yùn)行python程序的時(shí)候會(huì)霸占python解釋器(加了一把鎖即GIL),使該進(jìn)程內(nèi)的其他線程無法運(yùn)行,等該線程運(yùn)行完后其他線程才能運(yùn)行。如果線程運(yùn)行過程中遇到耗時(shí)操作,則解釋器鎖解開,使其他線程運(yùn)行。所以在多線程中,線程的運(yùn)行仍是有先后順序的,并不是同時(shí)進(jìn)行。
多進(jìn)程中因?yàn)槊總€(gè)進(jìn)程都能被系統(tǒng)分配資源,相當(dāng)于每個(gè)進(jìn)程有了一個(gè)python解釋器,所以多進(jìn)程可以實(shí)現(xiàn)多個(gè)進(jìn)程的同時(shí)運(yùn)行,缺點(diǎn)是進(jìn)程系統(tǒng)資源開銷大。
19.元組可以作為字典的key嘛?
首先一個(gè)對象能不能作為字典的key, 就取決于其有沒有__hash__方法。 所以除了容器對象(list/dict/set)和內(nèi)部包含容器對象的tuple 是不可作為字典的key, 其他的對象都可以。
20.Python 中的多線程和多進(jìn)程有什么區(qū)別?如何實(shí)現(xiàn)多線程或多進(jìn)程?
多線程是在同一個(gè)進(jìn)程中運(yùn)行多個(gè)線程,每個(gè)線程都可以執(zhí)行不同的任務(wù)。多進(jìn)程是在不同的進(jìn)程中運(yùn)行多個(gè)進(jìn)程,每個(gè)進(jìn)程都有自己的內(nèi)存空間和系統(tǒng)資源。在 Python 中,可以使用 threading 模塊實(shí)現(xiàn)多線程,使用 multiprocessing 模塊實(shí)現(xiàn)多進(jìn)程。