十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
(1).引用計(jì)數(shù)
成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供鐘山企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、H5建站、小程序制作等業(yè)務(wù)。10年已為鐘山眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。
(2). 垃圾回收
(3). 內(nèi)存池機(jī)制
在python中每創(chuàng)建一個(gè)對(duì)象,對(duì)應(yīng)的會(huì)有一個(gè)引用計(jì)數(shù),當(dāng)發(fā)生賦值操作如a=b,對(duì)應(yīng)的b的引用計(jì)數(shù)會(huì)自動(dòng)加1,當(dāng)引用的對(duì)象被清除或者函數(shù)結(jié)束時(shí),引用計(jì)數(shù)會(huì)自動(dòng)減1。
在python中使用引用計(jì)數(shù),標(biāo)記清楚,分代回收三種方式進(jìn)行垃圾回收。
其中,引用計(jì)數(shù)當(dāng)對(duì)象的引用計(jì)數(shù)歸0時(shí),對(duì)象會(huì)自動(dòng)被清除。標(biāo)記清除機(jī)制是首先遍歷所有對(duì)象,如果對(duì)象可達(dá),就說(shuō)明有變量引用它,則標(biāo)記其為可達(dá)的。如果不可達(dá),則對(duì)其進(jìn)行清除。分代回收是當(dāng)對(duì)象創(chuàng)建時(shí)被標(biāo)記為第0代,經(jīng)過(guò)一次垃圾回收之后,余下的對(duì)象被標(biāo)記為第1代,最高為第2代。其原理是,對(duì)象的生存期越長(zhǎng),月可能不是垃越。
ython語(yǔ)言雖然提供了對(duì)內(nèi)存的垃圾收集機(jī)制,但實(shí)際上它將不用的內(nèi)存放到內(nèi)存池而不是返回給操作系統(tǒng),所以就有了以下:
1 Pymalloc機(jī)制;這個(gè)主要是為了加速Python的執(zhí)行效率,Python引入了一個(gè)內(nèi)存池機(jī)制,用于管理,為了對(duì)小塊內(nèi)存的申請(qǐng)和釋放。
2 Python中所有小于256個(gè)字節(jié)的對(duì)象都是依靠pymalloc分配器來(lái)實(shí)現(xiàn)的,而稍大的對(duì)象用的則是系統(tǒng)的malloc。
3 對(duì)于Python對(duì)象,比如整數(shù)、浮點(diǎn)數(shù)和List這些,都有自己獨(dú)立的內(nèi)存池,對(duì)象間并不共享他們的內(nèi)存池。換句話說(shuō)就是,假設(shè)你分配并且釋放了大量的整數(shù),那么用于緩存這些整數(shù)的內(nèi)存就不能再分配給浮點(diǎn)數(shù)。
給你一份千鋒python的面試題吧
1、多線程使用Python是個(gè)好主意嗎?列出一些方法可以讓一些Python代碼以并行方式運(yùn)行。
答:Python不允許真正意義上的多線程。它有一個(gè)多線程包,但如果你想使用多線程來(lái)加速你的代碼,那么使用它通常不是一個(gè)好主意。Python有一個(gè)名為全局解釋器鎖(Global
Interpreter
Lock(GIL))的結(jié)構(gòu)。GIL確保每次只能執(zhí)行一個(gè)“線程”。一個(gè)線程獲取GIL,做一點(diǎn)工作,然后將GIL傳遞到下一個(gè)線程。這種情況發(fā)生的很快,因此對(duì)于人眼看來(lái),你的線程似乎是并行運(yùn)行的,但它們實(shí)際上只是輪流使用相同的CPU核心。所有這些GIL傳遞都增加了運(yùn)行的內(nèi)存。這意味著如果你想讓代碼運(yùn)行得更快,那么使用線程包通常不是一個(gè)好主意。
使用Python的線程包也是有原因的。如果你想同時(shí)運(yùn)行一些東西,并且效率不是一個(gè)問(wèn)題,那么它就完全沒(méi)問(wèn)題了?;蛘?,如果你正在運(yùn)行需要等待某些事情的代碼(例如某些IO),那么它可能會(huì)很有意義。但是線程庫(kù)不會(huì)讓你使用額外的CPU核心。
多線程可以外包到操作系統(tǒng)(通過(guò)多處理),一些調(diào)用Python代碼的外部應(yīng)用程序(例如,Spark或Hadoop),或者Python代碼調(diào)用的一些代碼例如:你可以使用你的Python代碼調(diào)用一個(gè)C函數(shù)來(lái)完成昂貴的多線程事務(wù)。
2、這段代碼輸出了什么:
def f(x,l=[]):for i in range(x):l.append(i*i)print(l) f(2)f(3,[3,2,1])f(3)
答:[0, 1][3, 2, 1, 0, 1, 4][0, 1, 0, 1, 4]
3、如何在Python中管理內(nèi)存?
Python中的內(nèi)存管理由Python私有堆空間管理。所有Python對(duì)象和數(shù)據(jù)結(jié)構(gòu)都位于私有堆中。程序員無(wú)權(quán)訪問(wèn)此私有堆。Python解釋器負(fù)責(zé)處理這個(gè)問(wèn)題。Python對(duì)象的堆空間分配由Python的內(nèi)存管理器完成。核心API提供了一些程序員編寫代碼的工具Python還有一個(gè)內(nèi)置的垃圾收集器,它可以回收所有未使用的內(nèi)存,并使其可用于堆空間。
4、range&xrange有什么區(qū)別?
在大多數(shù)情況下,xrange和range在功能方面完全相同。它們都提供了一種生成整數(shù)列表的方法,唯一的區(qū)別是range返回一個(gè)Python列表對(duì)象,x range返回一個(gè)xrange對(duì)象。
這就表示xrange實(shí)際上在運(yùn)行時(shí)并不是生成靜態(tài)列表。它使用稱為yielding的特殊技術(shù)根據(jù)需要?jiǎng)?chuàng)建值。該技術(shù)與一種稱為生成器的對(duì)象一起使用。因此如果你有一個(gè)非常巨大的列表,那么就要考慮xrange。
5、Python中help()和dir()函數(shù)的用法是什么?
Help()和dir()這兩個(gè)函數(shù)都可以從Python解釋器直接訪問(wèn),并用于查看內(nèi)置函數(shù)的合并轉(zhuǎn)儲(chǔ)。
help()函數(shù):help()函數(shù)用于顯示文檔字符串,還可以查看與模塊,關(guān)鍵字,屬性等相關(guān)的使用信息。
dir()函數(shù):dir()函數(shù)用于顯示定義的符號(hào)。
6、NumPy中有哪些操作Python列表的函數(shù)?
Python的列表是高效的通用容器。它們支持(相當(dāng))有效的插入,刪除,追加和連接,Python的列表推導(dǎo)使它們易于構(gòu)造和操作。
它們有一定的局限性:它們不支持像素化加法和乘法等“向量化”操作,并且它們可以包含不同類型的對(duì)象這一事實(shí)意味著Python必須存儲(chǔ)每個(gè)元素的類型信息,并且必須執(zhí)行類型調(diào)度代碼在對(duì)每個(gè)元素進(jìn)行操作時(shí)。
NumPy不僅效率更高; 它也更方便。你可以免費(fèi)獲得大量的向量和矩陣運(yùn)算,這有時(shí)可以避免不必要的工作。它們也得到有效實(shí)施。
NumPy數(shù)組更快,你可以使用NumPy,F(xiàn)FT,卷積,快速搜索,基本統(tǒng)計(jì),線性代數(shù),直方圖等內(nèi)置。
這些內(nèi)容還是比較重要的,如果有幫到你,麻煩采納謝謝
這是一位有著五年 Python 經(jīng)驗(yàn)的好友最近對(duì) Python 崗位面試后的一篇經(jīng)驗(yàn)總結(jié),從 Python 就業(yè)方向到 Python 面試題。
Python 就業(yè)方向 :
下面是 Python 面試知識(shí)點(diǎn),總結(jié)了華為、阿里巴巴等互聯(lián)網(wǎng)公司 Python 常問(wèn)面試題。每道題都提供參考答案,希望能夠幫助你在求職面試中脫穎而出,找到一份高薪工作。
這些面試題分為 Python 基礎(chǔ)和 Python高級(jí),內(nèi)容包含: 基礎(chǔ)語(yǔ)法、文件操作、模塊與包、數(shù)據(jù)類型、元類、內(nèi)存管理與垃圾回收機(jī)制以及 Python 函數(shù) 等知識(shí)點(diǎn)。
(一) Python 基礎(chǔ)語(yǔ)法
(二) 文件操作
(三) 模塊與包
(四) 數(shù)據(jù)類型
(五)企業(yè)面試題
(一) 元類
(二)內(nèi)存管理與垃圾回收機(jī)制
(三)函數(shù)
(四) 面向?qū)ο?/p>
由于篇幅有限,這份 Python 面試寶典已經(jīng)被整理成了PDF文檔,有需要 Python 面試寶典全套完整文檔(面試題+答案解析)的可以 免費(fèi)領(lǐng)取!
面試題
1、Python是如何進(jìn)行內(nèi)存管理的?
Python的內(nèi)存管理主要有三種機(jī)制:引用計(jì)數(shù)機(jī)制、垃圾回收機(jī)制和內(nèi)存池機(jī)制。
a. 引用計(jì)數(shù)
當(dāng)給一個(gè)對(duì)象分配一個(gè)新名稱或者將一個(gè)對(duì)象放入一個(gè)容器(列表、元組或字典)時(shí),該對(duì)象的引用計(jì)數(shù)都會(huì)增加。
當(dāng)使用del對(duì)對(duì)象顯示銷毀或者引用超出作用于或者被重新賦值時(shí),該對(duì)象的引用計(jì)數(shù)就會(huì)減少。
可以使用sys.getrefcount()函數(shù)來(lái)獲取對(duì)象的當(dāng)前引用計(jì)數(shù)。多數(shù)情況下,引用計(jì)數(shù)要比我們猜測(cè)的大的 多。對(duì)于不可變數(shù)據(jù)(數(shù)字和字符串),解釋器會(huì)在程序的不同部分共享內(nèi)存,以便節(jié)約內(nèi)存。
b. 垃圾回收
當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)歸零時(shí),它將被垃圾收集機(jī)制處理掉。
當(dāng)
兩個(gè)對(duì)象a和b相互引用時(shí),del語(yǔ)句可以減少a和b的引用計(jì)數(shù),并銷毀用于引用底層對(duì)象的名稱。然而由于每個(gè)對(duì)象都包含一個(gè)對(duì)其他對(duì)象的應(yīng)用,因此引用
計(jì)數(shù)不會(huì)歸零,對(duì)象也不會(huì)銷毀。(從而導(dǎo)致內(nèi)存泄露)。為解決這一問(wèn)題,解釋器會(huì)定期執(zhí)行一個(gè)循環(huán)檢測(cè)器,搜索不可訪問(wèn)對(duì)象的循環(huán)并刪除它們。
c. 內(nèi)存池機(jī)制
Python提供了對(duì)內(nèi)存的垃圾收集機(jī)制,但是它將不用的內(nèi)存放到內(nèi)存池而不是返回給操作系統(tǒng)。
1)Pymalloc機(jī)制。為了加速Python的執(zhí)行效率,Python引入了一個(gè)內(nèi)存池機(jī)制,用于管理對(duì)小塊內(nèi)存的申請(qǐng)和釋放。
2)Python中所有小于256個(gè)字節(jié)的對(duì)象都使用pymalloc實(shí)現(xiàn)的分配器,而大的對(duì)象則使用系統(tǒng)的 malloc。
3)對(duì)于Python對(duì)象,如整數(shù),浮點(diǎn)數(shù)和List,都有其獨(dú)立的私有內(nèi)存池,對(duì)象間不共享他們的內(nèi)存池。也就是說(shuō)如果你分配又釋放了大量的整數(shù),用于緩存這些整數(shù)的內(nèi)存就不能再分配給浮點(diǎn)數(shù)。
【Python環(huán)境】12道 Python面試題總結(jié)
2、什么是lambda函數(shù)?它有什么好處?
lambda 表達(dá)式,通常是在需要一個(gè)函數(shù),但是又不想費(fèi)神去命名一個(gè)函數(shù)的場(chǎng)合下使用,也就是指匿名函數(shù)
lambda函數(shù):首要用途是指點(diǎn)短小的回調(diào)函數(shù)
lambda [arguments]: expression
a=lambda x,y:x+y
a(3,11)
3、Python里面如何實(shí)現(xiàn)tuple和list的轉(zhuǎn)換?
直接使用tuple和list函數(shù)就行了,type()可以判斷對(duì)象的類型。
4、請(qǐng)寫出一段Python代碼實(shí)現(xiàn)刪除一個(gè)list里面的重復(fù)元素。
這個(gè)地方用set可以實(shí)現(xiàn)。
5、Python里面如何拷貝一個(gè)對(duì)象?(賦值,淺拷貝,深拷貝的區(qū)別)
賦值(=),就是創(chuàng)建了對(duì)象的一個(gè)新的引用,修改其中任意一個(gè)變量都會(huì)影響到另一個(gè)。
淺拷貝:創(chuàng)建一個(gè)新的對(duì)象,但它包含的是對(duì)原始對(duì)象中包含項(xiàng)的引用(如果用引用的方式修改其中一個(gè)對(duì)象,另外一個(gè)也會(huì)修改改變){1,完全切片方法;2,工廠函數(shù),如list();3,copy模塊的copy()函數(shù)}
深拷貝:創(chuàng)建一個(gè)新的對(duì)象,并且遞歸的復(fù)制它所包含的對(duì)象(修改其中一個(gè),另外一個(gè)不會(huì)改變){copy模塊的deep.deepcopy()函數(shù)}
6、介紹一下except的用法和作用?
try…except…except…[else…][finally…]
執(zhí)行try下的語(yǔ)句,如果引發(fā)異常,則執(zhí)行過(guò)程會(huì)跳到except語(yǔ)句。對(duì)每個(gè)except分支順序嘗試執(zhí)行,如果引發(fā)的異常與except中的異常組匹配,執(zhí)行相應(yīng)的語(yǔ)句。如果所有的except都不匹配,則異常會(huì)傳遞到下一個(gè)調(diào)用本代碼的最高層try代碼中。
try下的語(yǔ)句正常執(zhí)行,則執(zhí)行else塊代碼。如果發(fā)生異常,就不會(huì)執(zhí)行
如果存在finally語(yǔ)句,最后總是會(huì)執(zhí)行。
【Python環(huán)境】12道 Python面試題總結(jié)
7、Python里面match()和search()的區(qū)別?
re模塊中match(pattern,string [,flags]),檢查string的開(kāi)頭是否與pattern匹配。
re模塊中research(pattern,string [,flags]),在string搜索pattern的第一個(gè)匹配值。
print(re.match(‘super’, ‘superstition’).span())
(0, 5)
print(re.match(‘super’, ‘insuperable’))
None
print(re.search(‘super’, ‘superstition’).span())
(0, 5)
print(re.search(‘super’, ‘insuperable’).span())
(2, 7)
8、用Python匹配HTML tag的時(shí)候,.*和.*?有什么區(qū)別?
術(shù)語(yǔ)叫貪婪匹配( .* )和非貪婪匹配( .*? )
例如:
test
.* :
test
.*? :
9、以下的代碼的輸出將是什么? 說(shuō)出你的答案并解釋
輸出:
使你困惑或是驚奇的是關(guān)于最后一行的輸出是 3 2 3 而不是 3 2 1。為什么改變了 Parent.x 的值還會(huì)改變 Child2.x 的值,但是同時(shí) Child1.x 值卻沒(méi)有改變?
這
個(gè)答案的關(guān)鍵是,在 Python
中,類變量在內(nèi)部是作為字典處理的。如果一個(gè)變量的名字沒(méi)有在當(dāng)前類的字典中發(fā)現(xiàn),將搜索祖先類(比如父類)直到被引用的變量名被找到(如果這個(gè)被引用的
變量名既沒(méi)有在自己所在的類又沒(méi)有在祖先類中找到,會(huì)引發(fā)一個(gè) AttributeError 異常 )。
因此,在父類中設(shè)置 x = 1 會(huì)使得類變量 X 在引用該類和其任何子類中的值為 1。這就是因?yàn)榈谝粋€(gè) print 語(yǔ)句的輸出是 1 1 1。
隨后,如果任何它的子類重寫了該值(例如,我們執(zhí)行語(yǔ)句 Child1.x = 2),然后,該值僅僅在子類中被改變。這就是為什么第二個(gè) print 語(yǔ)句的輸出是 1 2 1。
最后,如果該值在父類中被改變(例如,我們執(zhí)行語(yǔ)句 Parent.x = 3),這個(gè)改變會(huì)影響到任何未重寫該值的子類當(dāng)中的值(在這個(gè)示例中被影響的子類是 Child2)。這就是為什么第三個(gè) print 輸出是 3 2 3。
10、以下代碼將輸出什么?
答案
以上代碼將輸出 [],并且不會(huì)導(dǎo)致一個(gè) IndexError。
正如人們所期望的,試圖訪問(wèn)一個(gè)超過(guò)列表索引值的成員將導(dǎo)致 IndexError(比如訪問(wèn)以上列表的 list[10])。盡管如此,試圖訪問(wèn)一個(gè)列表的以超出列表成員數(shù)作為開(kāi)始索引的切片將不會(huì)導(dǎo)致 IndexError,并且將僅僅返回一個(gè)空列表。
【Python環(huán)境】12道 Python面試題總結(jié)
一個(gè)討厭的小問(wèn)題是它會(huì)導(dǎo)致出現(xiàn) bug ,并且這個(gè)問(wèn)題是難以追蹤的,因?yàn)樗谶\(yùn)行時(shí)不會(huì)引發(fā)錯(cuò)誤。
11、以下的代碼的輸出將是什么? 說(shuō)出你的答案并解釋?
你將如何修改 extendList 的定義來(lái)產(chǎn)生期望的結(jié)果
以上代碼的輸出為:
許多人會(huì)錯(cuò)誤的認(rèn)為 list1 應(yīng)該等于 [10] 以及 list3 應(yīng)該等于 ['a']。認(rèn)為 list 的參數(shù)會(huì)在 extendList 每次被調(diào)用的時(shí)候會(huì)被設(shè)置成它的默認(rèn)值 []。
盡管如此,實(shí)際發(fā)生的事情是,新的默認(rèn)列表僅僅只在函數(shù)被定義時(shí)創(chuàng)建一次。隨后當(dāng) extendList 沒(méi)有被指定的列表參數(shù)調(diào)用的時(shí)候,其使用的是同一個(gè)列表。這就是為什么當(dāng)函數(shù)被定義的時(shí)候,表達(dá)式是用默認(rèn)參數(shù)被計(jì)算,而不是它被調(diào)用的時(shí)候。
因此,list1 和 list3 是操作的相同的列表。而 ````list2是操作的它創(chuàng)建的獨(dú)立的列表(通過(guò)傳遞它自己的空列表作為list``` 參數(shù)的值)。
extendList 函數(shù)的定義可以做如下修改,但,當(dāng)沒(méi)有新的 list 參數(shù)被指定的時(shí)候,會(huì)總是開(kāi)始一個(gè)新列表,這更加可能是一直期望的行為。
12、以下程序輸出什么?
好
吧,第一行代碼覺(jué)對(duì)是我第一次見(jiàn),第一行輸出的是[[], [], [], [], []],一個(gè)含有5個(gè)空列表的列表,而第二行輸出的是[[10],
[10], [10], [10],
[10]],我只能解釋為這5個(gè)列表指向了同一個(gè)列表,所以修改任意一個(gè)其它4個(gè)都會(huì)改變,可以用list[0]=10 斷開(kāi)一個(gè)連接試試。
無(wú)意間,看到這么一道Python面試題:以下代碼將輸出什么?
def testFun:
temp = [lambda x : i*x for i in range(4)]
return temp
for everyLambda in testFun:
print (everyLambda(2))
腦中默默一想,這還用說(shuō)么,肯定是:
2
4
6
最后一看答案,竟然是:
6
6
6
6
于是帶著懷疑的心態(tài)(其實(shí)是不服輸,不認(rèn)錯(cuò)),打開(kāi)編輯器,快速一敲,果然是:
懷疑了人生半天,本來(lái)還想黑,WTF Python…然后才想通是自己太生疏......
最后發(fā)現(xiàn)原因竟是:Python 的閉包的后期綁定導(dǎo)致的 late binding。
這意味著在閉包中的變量是在內(nèi)部函數(shù)被調(diào)用的時(shí)候被查找,所以當(dāng)任何testFun 返回的函數(shù)被調(diào)用,i 的值是在它被調(diào)用時(shí)的周圍作用域中查找。
也就是說(shuō)無(wú)論哪個(gè)返回的函數(shù)被調(diào)用,for 循環(huán)都已經(jīng)完成了,i 最后的值是 3,因此,每個(gè)返回的函數(shù) testFun 的值都是 3。
因此一個(gè)等于 2 的值被傳遞進(jìn)以上代碼,它們將返回一個(gè)值 6 (比如:3 x 2)。
究竟如何才能實(shí)現(xiàn)出這樣的結(jié)果呢?
2
4
6
想了想,若能立即綁定參數(shù),或者直接不用閉包總該行吧,用另一種方式避免 i 的改寫。
回憶了之前所學(xué)知識(shí),最后醞釀出了四種解決方案。
第一種:創(chuàng)建一個(gè)閉包,通過(guò)使用默認(rèn)參數(shù)立即綁定它的參數(shù)
def testFun:
temp = [lambda x, i=i: i * x for i in range(4)]
return temp
for everyLambda in testFun:
print(everyLambda(2))
第二種:使用functools.partial 函數(shù),把函數(shù)的某些參數(shù)(不管有沒(méi)有默認(rèn)值)給固定住(也就是相當(dāng)于設(shè)置默認(rèn)值)
from functools import partial
from operator import mul
def testFun:
return [partial(mul, i) for i in range(4)]
for everyLambda in testFun:
print(everyLambda(2))
第三種:優(yōu)雅的寫法,直接用生成器
def testFun:
return (lambda x, i=i: i * x for i in range(4))
for everyLambda in testFun:
print(everyLambda(2))
第四種:利用yield的惰性求值的思想
def testFun:
for i in range(4):
yield lambda x: i * x
for everyLambda in testFun:
print(everyLambda(2))
最終運(yùn)行結(jié)果:
有了解決方案后,又陷入了懷疑自己,這個(gè)題目究竟是考察的是什么?是在考面試者閉包相關(guān)知識(shí)以及Python 的閉包的后期綁定問(wèn)題么?
若將題目改成:以下代碼輸出的結(jié)果是(0,2,4,6)么?如果不是,你將會(huì)怎么做,讓它變成(0,2,4,6)?這樣會(huì)不會(huì)更有意思點(diǎn)呢?歡迎大家出妙招,看究竟有多少招?(哈哈哈?。。。?/p>
本文題目:關(guān)于python面試題函數(shù)的信息
網(wǎng)頁(yè)鏈接:http://m.jiaotiyi.com/article/doojjpg.html