Python面试宝典
轉自黑馬程序員《Python面試寶典》http://bbs.itheima.com/thread-402667-1-1.html?可以下載PDF文件。
目錄
Q1 代碼中要修改不可變數據會出現什么問題?拋出什么異常?
Q2 不適用中間變量交換變量a,b的值。
Q3 print調用的什么底層方法?
Q4 下面這段代碼的輸出結果是什么?請解釋。
Q5 input()函數
Q6 range()和xrange()的區別。(Python2)
Q7 4G內存如何讀取一個5G的數據?
Q8?現在考慮有一個 jsonline 格式的文件 file.txt 大小約為 10K,之前處理文件的代碼如下所示.
Q9 read、readline和readlines的區別?
Q10 補充缺失的代碼。
Q11 在except中return后還會執行finally中的代碼嗎?如何拋出自定義異常?
Q12 except的作用和用法。
Q13 有哪些常用的python標注庫。
Q14 賦值、淺拷貝和深拷貝的區別。
Q15 __init__ 和__new__區別
Q16 隨機數
Q17 輸入某年某月某日,判斷這一天是這一年的第幾天?
Q18 打亂一個排好序的list對象
Q19 說明os.path 和sys.path分別表示什么?
Q20 os模塊常見方法
Q21? python中sys模塊常用方法?
Q22?unittest
Q23 模塊和包
Q24 Python是強語言類型還是弱語言類型?
Q25 解釋型語言和編譯型語言。
Q26 Python日志
Q27Python是如何進行類型轉換的?
Q28 Python2和Python3的區別。
Q29 關于Python程序的運行,有什么手段能提升性能。
Q30 Python中的作用域。
Q31 Python自省
Q32 Python代碼規范
Q1 代碼中要修改不可變數據會出現什么問題?拋出什么異常?
代碼會報錯,拋出TypeErrory異常
- 可變數據類型:列表list和字典dict,集合set
- 不可變數據類型:基本數據類型(int,float,string)元組tuple
Q2 不適用中間變量交換變量a,b的值。
方法1:
a=a+b b=a-b a=a-b方法2:
a=a^b b=b^a a=a^b方法3:
a,b=b,aQ3 print調用的什么底層方法?
print方法默認調用sys.stdout.write方法,即往控制臺打印字符串。
Q4 下面這段代碼的輸出結果是什么?請解釋。
class Parent(object):x=1 class Child1(Parent):pass class Child2(Parent):pass print(Parent.x,Child1.x,Child2.x) Child1.x=2 print(Parent.x,Child1.x,Child2.x) parent.x=3 print(Parent.x,Child1.x,Child2.x)結果為:
111? ?#繼承自父類的類屬性x,所有都一樣,指向同一塊內存地址。
121? ?#Child1.x進行賦值,指向了新的內存地址。
323? ?#更改Parent.x, 指向了新的內存地址,Child3繼承父類,也指向改地址。
Q5 input()函數
在Python3中,input()獲取用戶輸入,不論用戶輸入什么,獲取到的都是字符串類型。
在Python2中有raw_input() input(),raw_input()在Python3中的input()作用一樣,input()輸入什么數據類型,獲取到的就是什么數據類型。
Q6 range()和xrange()的區別。(Python2)
兩者用法相同,不同的是range返回的結果是一個列表,而xrange的結果是一個生成器,前者是直接開辟一塊內存空間來保存列表,后者是邊循環邊使用,只有使用時才會開辟內存空間,所以當列表很長時,使用xrange性能要比range好,而range則是用空間來換取時間。
在Python3中range()相當于2中的xrange(),所以3中已經沒有xrange()函數了。
Q7 4G內存如何讀取一個5G的數據?
方法一:
可以通過生成器,分多次讀取,每次讀取比較少量的數據進行處理,處理結束后在一次讀取后面的數據。
方法二:
可以通過Linux命令split切割成小文件,然后對數據進行處理,此方法效率比較高。可以按照行數切割,也可以按照文件大小切割。
Q8?現在考慮有一個 jsonline 格式的文件 file.txt 大小約為 10K,之前處理文件的代碼如下所示.
def get_lines():l = []with open(‘file.txt’,‘rb’) as f:for eachline in f:l.append(eachline)return l if __name__ == ‘__main__’:for e in get_lines():process(e) #處理每一行數據現在要處理一個大小為 10G 的文件,但是內存只有 4G,如果在只修改 get_lines 函數而其他代碼保持不變的情況下,應該如何實現?需要考慮的問題都有哪些?
要考慮的問題:
內存只有4G無法一次性讀入10G的文件,需要分批讀入。分批讀入數據要記錄每次讀入數據的位置。
要考慮每次讀入數據的大小,太小就會在讀取操作上花費過多的時間。
修改后的代碼:
def get_lines():l=[]with open('file.txt','rb') as f:data=f.readlines(6000)l.append(data)yield l?書中給的代碼并不能循環迭代,修改如下。
def get_lines():# l=[]flag=Truewith open('file.txt','rb') as f:while flag:data=f.readlines(1000)# l.append(data)if data:yield dataelse:flag=FalseQ9 read、readline和readlines的區別?
read:讀取整個文件
readline:讀取一行,使用生成器方法。
readlines:讀取整個文件到一個迭代器以便遍歷。
Q10 補充缺失的代碼。
def print_directory_contents(sPath):'''這個函數接收文件夾的名稱作為輸入參數。返回該文件夾中文件的路徑以及其包含文件夾中文件的路徑'''#請補充代碼完整代碼如下,?
#首先導入os庫 import os def print_directory_contents(sPath):#os.listdir() 方法用于返回指定的文件夾包含的文件或文件夾的名字的列表。#只支持在 Unix, Windows 下使用。for sChild in os.listdir(sPath):#os.path.join(path1,path2,...)用于路徑拼接文件路徑sChildPath=os.path.join(sPath,sChild)#os.path.isdir()函數判斷是否為文件夾,是文件夾返回True.if os.path.isdir(sChildPath):print_directory_contents(sChildPath)else:print(sChildPath)Q11 在except中return后還會執行finally中的代碼嗎?如何拋出自定義異常?
return之后依然執行finally中的代碼。
用raise方法可以拋出自定義異常。
Q12 except的作用和用法。
try:
? #except 要和try一起使用。
except:#捕獲所有異常
except <異常名>:#捕獲指定異常
except <異常1,異常2>:捕獲異常1或者異常2
except<異常名>,<數據>:捕獲指定異常及其附加的數據
except<異常1,異常2>,<數據>:捕獲異常1或者異常2,及其附加的數據。
Q13 有哪些常用的python標注庫。
標準庫:os操作系統;time時間;random隨機;pymysql連接數據庫;threading線程;multiprocessing進程;queue隊列;math數學
第三方庫:django,flask,requests,hashlib,md5,selenium,scrapy,xadmin。
常用的科學計算庫:Numpy,Scipy,Pandas
可視化庫:matplotlib
Q14 賦值、淺拷貝和深拷貝的區別。
賦值
在python中,對象的賦值就是簡單的對象引用。如:
a=[1,2,3,"abc",['hello',567]] b=a此時a和b指向同一塊內存地址,相當于把a的引用賦值給了b。
a is b,為True,id(a)=id(b)
賦值操作(包括對象作為參數、返回值)不會開辟新的內存空間,它只是賦值了對象的引用。修改了a,也就影響了b;修改了b也就意向了a。
淺拷貝 shallow copy
淺拷貝會創建新對象,其內容非元對象本身的引用,而是原對象內第一層對象的引用。
淺拷貝有三種形式:切片操作,工廠函數、copy模塊中的copy函數。
切片操作:b=a[:] 或者b=[x for i in a];
工廠函數:b=list(a);
copy函數:b=copy.copy(a)
淺拷貝產生的列表b不再是列表a了,用is判斷已經不是同一個對象了,id也不同,也不指向同一片內存空間。但是當我們使用id(x) for x in a 和 id(x) for x in b來查看a和b中元素地址時,會發現兩者包含的元素的地址是相同。
需要注意的是淺拷貝值拷貝了一層,在列表a中有一個嵌套的list,修改嵌套列表中的袁術,列表的地址并未發生變化,指向的都是同一個位置。
深拷貝 deepcopy
深拷貝和淺拷貝相對應,深拷貝拷貝了對象的所有元素,包括多層嵌套的元素。因此它的時間和空間開銷要高。
同時對列表a,如果使用b=copy.deepcopy(a),再修改列表b不會影響列表a,嵌套中列表也不會產生任何影響,因為深拷貝拷貝出來的對象是一個全新的對象,不再與原來的對象有任何關聯。
注意:對于非容器對象,如數字、字符、以及其他的“原子”類型,沒有拷貝一說,產生的都是原對象的引用。
如果元組變量值包含原子類型對象,即使采用了深拷貝,也只能得到淺拷貝。
Q15 __init__ 和__new__區別
__init__ 用來初始化實例,為其實例設置屬性。
__init__的第一個占位參數是class的實例對象。
init 在對象創建后,對對象進行初始化。
__new__用來創建實例,在返回的實例上執行__init__,如果不返回實例那么__init__將不會執行。
__new__的第一個占位參數是class對象。
當一個類實例化時,最先執行的是__new__,而不是__init__。
new 是在對象創建之前創建一個對象,并將該對象返回給 init。
Q16 隨機數
在python中用生成隨機數的模塊是random,在使用前需要import。
random.random():生成一個0-1之間的隨機浮點數、
random.uniform(a,b):生成[a, b]之間的浮點數。
ramdom.randint(a,b):生成【a,b】之間的整數。
random.randrange(a,b,step):在指定的集合[a, b)中,以step為基數隨機取一個數。
random.choice(sequence):從特定序列中隨機取一個元素,這里的序列可以是字符串,列表,元組等。
Q17 輸入某年某月某日,判斷這一天是這一年的第幾天?
源碼如下,書中代碼有一定錯誤。
import datetime def dayofyear():try:years=int(input("請輸入年份:"))months=int(input("請輸入月份:"))days=int(input("請輸入天:"))except:print("輸入有誤,請輸入整數")date1=datetime.date(year=years,month=months,day=days)date2=datetime.date(year=years,month=1,day=1)return (date1-date2).days+1 if __name__ == '__main__':days=dayofyear()print(days)Q18 打亂一個排好序的list對象
import random #random.shuffle()會在原地進行操作,沒有返回值。 random.shuffle(alist)Q19 說明os.path 和sys.path分別表示什么?
os.path:主要用于對系統路徑文件的操作
sys.path:主要是對python解釋器的系統環境參數的操作。(動態的改變Python解釋器搜索路徑。)
Q20 os模塊常見方法
os.remove(‘path/filename’) 刪除文件
os.rename(oldname, newname) 重命名文件
os.walk() 生成目錄樹下的所有文件名
os.chdir('dirname') 改變目錄
os.mkdir/makedirs('dirname')創建目錄/多層目錄
os.rmdir/removedirs('dirname') 刪除目錄/多層目錄
os.listdir('dirname') 列出指定目錄的文件
os.getcwd() 取得當前工作目錄
os.chmod() 改變目錄權限
os.path.basename(‘path/filename’) 去掉目錄路徑,返回文件名
os.path.dirname(‘path/filename’) 去掉文件名,返回目錄路徑
os.path.join(path1[,path2[,...]]) 將分離的各部分組合成一個路徑名
os.path.split('path') 返回( dirname(), basename())元組
os.path.splitext() 返回 (filename, extension) 元組
os.path.getatime\ctime\mtime 分別返回最近訪問、創建、修改時間
os.path.getsize() 返回文件大小
os.path.exists() 是否存在
os.path.isabs() 是否為絕對路徑
os.path.isdir() 是否為目錄
os.path.isfile() 是否為文件
更多os模塊的方法請參考:http://www.runoob.com/python3/python3-os-file-methods.html
Q21? python中sys模塊常用方法?
sys.argv 命令行參數List,第一個元素是程序本身路徑
sys.modules.keys() 返回所有已經導入的模塊列表
sys.exc_info() 獲取當前正在處理的異常類,exc_type、exc_value、exc_traceback當前處理的異常詳細信息
sys.exit(n) 退出程序,正常退出時exit(0)
sys.hexversion 獲取Python解釋程序的版本值,16進制格式如:0x020403F0
sys.version 獲取Python解釋程序的版本信息
sys.maxint 最大的Int值
sys.maxunicode 最大的Unicode值
sys.modules 返回系統導入的模塊字段,key是模塊名,value是模塊
sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform 返回操作系統平臺名稱
sys.stdout 標準輸出
sys.stdin 標準輸入
sys.stderr 錯誤輸出
sys.exc_clear() 用來清除當前線程所出現的當前的或最近的錯誤信息
sys.exec_prefix 返回平臺獨立的python文件安裝的位置
sys.byteorder 本地字節規則的指示器,big-endian平臺的值是'big',little-endian平臺的值是'little'
sys.copyright 記錄python版權相關的東西
sys.api_version 解釋器的C的API版本
Q22?unittest
unittest是Python中的單元測試框架。它擁有支持共享搭建、自動測試、在測試中暫停代碼、將不同測試迭代成一組等工程
Q23 模塊和包
在python中模塊是搭建程序的一種方式。每一個Python代碼文件都是一個模塊,并可以引用其他模塊,比如對象和屬性。
一個包含許多python代碼的文件夾就是一包。一個包可以包含模塊和子文件夾。
Q24 Python是強語言類型還是弱語言類型?
Python是強類型的動態腳本語言。
強類型:不允許不同類型相加。
動態:不使用顯示數據類型聲明,切確定一個變量的類型是在第一次給它賦值的時候。
腳本語言:一般也是解釋型語言,運行代碼只需要一個解釋器,不需要編譯。
Q25 解釋型語言和編譯型語言。
計算機不能直接理解高級語言,只能直接理解機器語言,所以必須要把高級語言翻譯成機器語言,計算機才能執行高級語言編寫的程序。
解釋型語言在運行程序的時候才會進行翻譯,邊翻譯邊運行。
編譯型語言在程序運行之前,需要一個專門的編譯過程,把程序編譯成機器語言,會生成一個編譯文件,直接運行該編譯文件即可。若源代碼沒有修改,再次運行程序時,無需再次編譯。
Q26 Python日志
Python中自帶logging模塊,用于日志管理。調用logging.basicConfig()方法,配置需要的日志等級和相關參數,Python解釋器會按照配置的參數生成相應的日志。
Q27Python是如何進行類型轉換的?
Python內部封裝了各種轉換函數,可以使用目標類型關鍵字進行強制類型轉換,進制之間的轉換可以用int('str',base='n')將特定進制的字符串轉換為十進制,再用相應的進制轉換函數將十進制轉換為目標進制。
還有列表和元組之間的相互轉換:
list-->tuple? ? ?tuple(list)
tuple-->list? ? ?list(tuple)
Q28 Python2和Python3的區別。
核心類區別:
1.Python3對Unicode字符的原生支持。
Python2中使用ASCII碼作為默認編碼方式導致string有兩種類型str和Unicode,Python3中只支持Unicode類型的string。
2.Python3中采用的是絕對路徑的方式進行import。
Python2中相對路徑的import會導致標準庫導入變得困難(同一目錄下有file.py,如何同時導入這個文件和標準庫文件file)。Python3中這一點被修改了,如果還需要導入同一目錄的文件必須使用絕對路徑,否則只能使用相關導入的方式來進行導入。
3.Python2中存在老式類和新式類,Python3中統一采用新式類。新式類申明要求繼承object,必須使用新式類應用多重繼承。
4.Python3使用更加嚴格的縮進。Python2的縮進機制中,一個tab和8個space是等價的,所以在縮進中同時允許tab和space在代碼中共存。這種等價機制會導致部分IDE使用存在問題。Python3中1個tab只能找另一個tab代替,因此tab和space共存會導致報錯:TabError:inconsistent use of tabs and spaces in indentaion.
廢棄類差別:
1. print 語句被 Python3 廢棄,統一使用 print 函數
2. exec 語句被 python3 廢棄,統一使用 exec 函數
3. execfile 語句被 Python3 廢棄,推薦使用 exec(open("./filename").read())
4. 不相等操作符"<>"被 Python3 廢棄,統一使用"!="
5. long 整數類型被 Python3 廢棄,統一使用 int
6. xrange 函數被 Python3 廢棄,統一使用 range,Python3 中 range 的機制也進行修改并提高
了大數據集生成效率
7. Python3 中這些方法再不再返回 list 對象:dictionary 關聯的 keys()、values()、items(),zip(),
map(),filter(),但是可以通過 list 強行轉換:
8. 迭代器 iterator 的 next()函數被 Python3 廢棄,統一使用 next(iterator)
9. raw_input 函數被 Python3 廢棄,統一使用 input 函數
10. 字典變量的 has_key 函數被 Python 廢棄,統一使用 in 關鍵詞
11. file 函數被 Python3 廢棄,統一使用 open 來處理文件,可以通過 io.IOBase 檢查文件類型
12. apply 函數被 Python3 廢棄
13. 異常 StandardError 被 Python3 廢棄,統一使用 Exception
修改類差異:
1.浮點數除法操作符“/”和“//”的區別:
"/":
Python2 中若兩個整形進行運算,結果為整形,但若其中有一個浮點數類型,則結果為浮點數。
python3為真除法,運算結果為float類型。
“//”:
Python2 中返回小于除法運算結果的最大整數,從類型上講,與"/"運算符返回類型邏輯一致。
Python3中與python2作用相同。
2.異常拋出和捕捉機制的區別。
Python2
1. raise IOError, "file error" #拋出異常 2. except NameError, err: #捕捉異常Python3
1. raise IOError("file error") #拋出異常 2. except NameError as err: #捕捉異常3.for循環中變量值區別。
Python2 中,for循環會修改外部相同名稱變量的值。
i=1 print('comprehension: ', [i for i in range(5)]) print('after: i=.',i) #i=4Python3中,for循環不會修改外部相同名稱變量的值。
i=1 print('comprehension: ', [i for i in range(5)]) print('after: i=.',i) #i=14.round函數返回值區別
Python2中,round函數返回float類型值。
isinstance(round(15.5),float) #TruePython3中,round函數返回int類型值。
isinstance(round(15.5),int) #True5.比較操作符的區別。
Python2中任意兩個對象都可以比較。
Python3中只有同一類型數據的對象才可以進行比較。
Q29 關于Python程序的運行,有什么手段能提升性能。
Q30 Python中的作用域。
Python,一個變量的作用域總是由在代碼中被賦值的地方所決定。變量作用域的搜索順序LEGB
本地作用域(Local)--》當前作用域被嵌入的本地作用域(Enclosing locals)----》 全局、模塊作用域(Global)---》內置作用域(Built-in)
Q31 Python自省
Python自省是Python具有的一種能力,是程序員面向對象的語言所寫的程序在運行時,能夠獲得對象的類型。更多關于Python自省請參考http://python.jobbole.com/82110/
Q32 Python代碼規范
PEP8規范。
1.變量
常亮:大寫加下劃線
私有變量:小寫和一個前導下劃線。_private_value.
Python中不存在私有變量一說,若是遇到需要保護的變量,使用小寫和一個前導下劃線。但這只是程序員之間的一個約定,用于警告說明這是一個私有變量,外部類不要去訪問它。但實際上,外部類還是可以訪問到這個變量。
內置變量:小寫,兩個前導下劃線和兩個后置下劃線
Q33 軟鏈接和硬鏈接的區別。
軟鏈接:類似Windows的快捷方式,當刪除源文件時,那么軟鏈接也就失效了.
硬鏈接:可以理解為源文件的一個別名,多個別名所代表的是同一個文件。當rm一個文件的時候,那么此文件的硬鏈接數減1,當硬鏈接數為0時,文件被刪除。
Q34 10個常用的Linux命令行?
pwd 顯示工作路徑
ls 查看目錄中的文件cd /home 進入 '/ home' 目錄'
cd .. 返回上一級目錄
cd ../.. 返回上兩級目錄
mkdir dir1 創建一個叫做 'dir1' 的目錄'
rm -f file1 刪除一個叫做 'file1' 的文件',-f 參數,忽略不存在的文件,從不給出提示。
rmdir dir1 刪除一個叫做 'dir1' 的目錄'
groupadd group_name 創建一個新用戶組
groupdel group_name 刪除一個用戶組
tar -cvf archive.tar file1 創建一個非壓縮的 tarball
tar -cvf archive.tar file1 file2 dir1 創建一個包含了 'file1', 'file2' 以及 'dir1'的檔案文件
tar -tf archive.tar 顯示一個包中的內容
tar -xvf archive.tar 釋放一個包
tar -xvf archive.tar -C /tmp 將壓縮包釋放到 /tmp 目錄下
tar -cvfj archive.tar.bz2 dir1 創建一個 bzip2 格式的壓縮包
tar -xvfj archive.tar.bz2 解壓一個 bzip2 格式的壓縮包
tar -cvfz archive.tar.gz dir1 創建一個 gzip 格式的壓縮包
tar -xvfz archive.tar.gz 解壓一個 gzip 格式的壓縮包
Q35 Linux關機命令
reboot? 重新啟動操作系統
shutdown -r now 重新啟動操作系統,shutdown會給別的用戶提示
shutdown -h now? 立刻關機,其中now相當于時間為0的狀態
shutdown -h 20:25? ?系統在今天的20:25會關機
shutdown -h +10? ? ?系統會在十分鐘后關機
init 0? ? ? ? 關機
init 6重啟
Q36 Python中類方法、類實例方法、靜態方法有何區別。
類方法:是類對象的方法,在定義時需要在上方使用“@classmethod”進行修飾,形參為 cls ,表示類對象,類對象和實例對象都可調用;
類實例方法:是類實例化對象的方法,只有實例對象可以調用,形參為self,指代對象本身。
靜態方法:是一個任意函數,在其上方使用“@staticmethod”進行裝飾,可以直接用對象調用,靜態方法實際上跟該類沒有太大關系。
Q37 Python的內存管理機制及調優手段。
內存管理機制:引用計數、垃圾回收、內存池
引用計數:引用計數是一種非常高效的內存管理手段,當一個Python對象被引用時其引用計數增加1,當其不再被一個變量引用時計數減1。當引用計數等于0時,對象被刪除。
垃圾回收:
1. 引用計數。引用計數也是一種垃圾收集機制,而且也是一種最直觀、最簡單的垃圾收集計數。當出現循環引用,引用計數機制就不再起有效的作用。
2.標記清除。如果兩個對象的引用計數為1,但是僅僅存在他們之間的循環引用,那么這兩個對象都是需要被回收的,也就是說,它們的引用計數雖然表現 為非0,但實際上有效的計數為0。所以先將循環引用摘掉,就會得出這兩個對象的有效計數。
3.分代回收。從前面“標記-清除”這樣的垃圾收集機制來看,這種垃圾收集機制所帶來的額外操作實際上與系統中總的內存塊的數量是相關的,當需要回收的內存塊越多時,垃圾檢測帶來的額外操作就越多,而垃圾回收帶來的額外操作就越少;反之,當需要回收的內存塊越少時,垃圾檢測就將比垃圾回收帶來更少的額外操作。
例如:
當某些內存塊M經過了3次垃圾收集的清洗之后還存活時,我們就將內存塊M劃到一個集合A中去,而新分配的內存都劃分到集合B中去。當垃圾收集開始工作時,大多數情況都只對集合B進行垃圾收集,而對集合A進行垃圾回收要隔相當一段長時間才進行,這就使得垃圾收集機制需要處理的內存少了,效率自然就提高了。在這個過程中,集合B中的某些內存塊由于存活時間長而會被轉移到集合A中,當然,集合A中實際上也存在一些垃圾,這些垃圾的回收會因為這種分代的機制而被延遲。
內存池:
1. Python的內存機制呈現金字塔形狀,-1,-2 層主要有操作系統進行操作。
2. 第0層是C中的malloc,free 等內存分配和釋放函數 進行操作。
3. 第1層和第2層是內存池,有python的接口函數PyMem_Malloc 函數實現,當對象小于256k 時由該層直接分配內存。
4. 第3層是最上層, 也就是我們隊python對象的直接操作。
Python在運行期間會大量執行malloc 和 free 的操作,頻繁地在用戶態和核心態之間進行切換,這將嚴重影響Python的執行效率。為了加速Python的執行效率,Python引入了一個內存池機制,用于管理對小塊內存的申請和釋放。
Python內部默認的小塊內存與大塊內存的分界點定在256個字節,當申請的內存小于256字節時,PyObject_Malloc 會在內存池中申請內存;當申請的內存大于256字節時,PyObject_Malloc 的行為將蛻化為malloc的行為。當然,通過修改Python源代碼,我們可以改變這個默認值,從而改變Python的默認內存管理行為。
調優手段:
1.手動垃圾回收
2.調高垃圾回收閾值。
3.避免循環引用(手動解循環引用和使用弱引用)
Q38 內存泄露是什么?如何避免?
指由于疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。內存泄露并非指內存在物理上的消失,而是應用程序分配某段內存后,由于設計錯誤,是去了對該段內存的控制,因而造成了內存的浪費。導致程序運行速度減慢甚至造成系統奔潰等嚴重后果。
有__del__() 函數的對象間的循環引用時導致內存泄露的主兇。
如何避免。不使用一個對象時, 使用 del object 來刪除一個對象的引用計數就可以有效防止內存泄露問題。
通過Python 擴展模塊 gc 來查看不能回收的對象的詳細信息。
可以通過 sys.getrefcount(obj) 來獲取對象的引用計數,并根據返回值是否為0來判斷是否內存泄露。?
Q39 Python函數調用的時候參數的傳遞方式是值傳遞還是引用傳遞?
Python的參數傳遞有:位置參數、默認參數、可變參數、關鍵字參數。
參數的傳遞方式根據情況而定。
不可變參數用值傳遞:
像整數和字符串這樣的不可變對象,是通過拷貝進行傳遞的, 因為你無論如何都可不能在遠處改變不可變對象。
可變參數是引用傳遞:
比如像列表,字典這樣的對象是通過引用傳遞、和c語言里面的用指針傳遞數組很相似,可變對象能在函數內部改變。
Q40 對缺省參數的理解。
缺省參數指在調用函數的時候沒有傳入參數的情況下,調用默認的參數,在調用函數的同時賦值時,所傳入的參數會代替默認參數。
*args 是不定長參數,可以表示輸入的參數是不確定的,可以是任意多個。
**kwargs? 是關鍵字參數,賦值的時候是以鍵 = 值的方式,參數是可以任意多對在定義函數的時候不確定會有多少參數會傳入時,就可以使用兩個參數。
Q41 hasattr() getattr() setattr() 函數使用詳解?
hasattr(object,'name'):判斷一個對象里面是否有name屬性或者name方法,返回bool值,有name屬性,返回True,否則返回False。
getattr(object,name[,default]):?獲取對象 object 的屬性或者方法,如果存在則打印出來,如果不存在,打印默認值,默認值可選。注意:如果返回的是對象的方法,則打印結果是:方法的內存地址,如果需要運行這個方法,可以在后
面添加括號()。
setattr(object,name,values):?給對象的屬性賦值,若屬性不存在,先創建再賦值。
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的Python面试宝典的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件开发中JAVA编程语言的应用
- 下一篇: Java检验yyyymm合法,JAVA日