python中类型错误、计数不采用关键字的错误怎么改_Learning/Python-面试问题.md at master · yxxyyx1314/Learning · GitHub...
Python-面試問(wèn)題
參考鏈接
面:Python 中什么元素為假?
答:(0,空字符串,空列表、空字典、空元組、None, False)
面:Python 中查看某個(gè)關(guān)鍵字的屬性?
答:dir ( key ),help() 函數(shù)返回幫助文檔和參數(shù)說(shuō)明,dir() 函數(shù)返回對(duì)象中的所有成員 (任何類型)
面:Python 全局變量 global 的使用?
面:Python 中的 pass 語(yǔ)句有什么作用?
答:我們?cè)趯懘a時(shí),有時(shí)可能只寫了函數(shù)聲明而沒(méi)想好函數(shù)怎么寫,但為了保證語(yǔ)法檢查的正確必須輸入一些東西。在這種情況下,我們使用 pass 語(yǔ)句。
面:舉例說(shuō)明異常模塊中 try except else finally 的相關(guān)意義?
答:try..except..else 沒(méi)有捕獲到異常,執(zhí)行 else 語(yǔ)句;try..except..finally 不管是否捕獲到異常,都執(zhí)行 finally 語(yǔ)句。
面:with 方法打開(kāi)處理文件幫我們做了什么?yield 的使用-生成器?
答:功能類似 try,except,finally 中 finally 的用法,with:除了有更優(yōu)雅的語(yǔ)法,真正強(qiáng)大的地方:with 還可以很好的處理上下文環(huán)境產(chǎn)生的異常。with 后面的函數(shù)需要有 __ exit __ 方法,當(dāng)程序出現(xiàn)異常的時(shí)候會(huì)幫助我們打印異常,清理資源,關(guān)閉文件。with 參考博客,yield 參考博客
面:Python 中斷言方法舉例?
答:使用 assert 斷言是學(xué)習(xí) Python 一個(gè)非常好的習(xí)慣,Python assert 斷言句語(yǔ)格式及用法很簡(jiǎn)單。在沒(méi)完善一個(gè)程序之前,我們不知道程序在哪里會(huì)出錯(cuò),與其讓它在運(yùn)行最崩潰,不如在出現(xiàn)錯(cuò)誤條件時(shí)就崩潰。
面:列出 Python 中可變數(shù)據(jù)類型 和 不可變數(shù)據(jù)類型,并簡(jiǎn)述原理?
答:不可變數(shù)據(jù)類型:數(shù)值型、字符串型、和 元組;不允許變量的值發(fā)生變化,如果改變了變量的值,相當(dāng)于是新建了一個(gè)對(duì)象,而對(duì)于相同的值的對(duì)象,在內(nèi)存中則只有一個(gè)對(duì)象(一個(gè)地址)可變數(shù)據(jù)類型:列表 和 字典,允許變量的值發(fā)生變化,即如果對(duì)變量進(jìn)行 append、+= 等這種操作后,只是改變了變量的值,而不會(huì)新建一個(gè)對(duì)象,變量引用的對(duì)象的地址也不會(huì)變化,不過(guò)對(duì)于相同的值的不同對(duì)象,在內(nèi)存中則會(huì)存在不同的對(duì)象,即每個(gè)對(duì)象都有自己的地址,相當(dāng)于內(nèi)存中對(duì)于同值的對(duì)象保存了多份,這里不存在引用計(jì)數(shù),是實(shí)實(shí)在在的對(duì)象。
面:賦值,淺拷貝,深拷貝的區(qū)別?
**賦值:**簡(jiǎn)單地拷貝對(duì)象的引用,兩個(gè)對(duì)象的 id (內(nèi)存中的地址)相同,并且共用一個(gè)對(duì)象,刪除 a 也不會(huì)刪除數(shù)組,原因見(jiàn)下一題 引用計(jì)數(shù)機(jī)制。
**淺拷貝-copy():**創(chuàng)建一個(gè)新的組合對(duì)象,這個(gè)新對(duì)象與原對(duì)象共享內(nèi)存中的子對(duì)象。當(dāng)改變?cè)瓕?duì)象時(shí),才會(huì)創(chuàng)建一個(gè)實(shí)例。僅僅是最頂層開(kāi)辟了新的空間,里層的元素地址還是一樣的。
**深拷貝-deepcopy():**創(chuàng)建一個(gè)新的組合對(duì)象,同時(shí)遞歸地拷貝所有子對(duì)象,新的組合對(duì)象與原對(duì)象沒(méi)有任何關(guān)聯(lián)。雖然實(shí)際上會(huì)共享不可變的子對(duì)象,但不影響它們的相互獨(dú)立性。
#賦值
a = [1,2,3]
b = a #賦值 id(a) == id(b),直接引用計(jì)數(shù)
#淺拷貝
import copy
a = 1 #對(duì)于不可變數(shù)據(jù)類型 數(shù)字a=1; 字符串a(chǎn)='hello'; 元組a=(1,2,3),不存在啥淺拷貝的,和賦值一樣
b = copy.copy(a) #id(a) == id(b)
a = [1,2,3] #對(duì)于可變數(shù)據(jù)類型 列表,字典,僅僅是最頂層開(kāi)辟了新的空間,里層的元素地址還是一樣的。
b = copy.copy(a) # id(a) != id(b)
id(a[0]) == id(b[0]) #True 里面的不可變類型地址是一樣的
#深拷貝,邏輯同上,但是淺拷貝不會(huì)遞歸拷貝元素是地址的值,淺拷貝對(duì) c 也是簡(jiǎn)單的拷貝。
import copy
c = [4,5]
a = [1,2,3,c]
b = copy.deepcopy(a) #會(huì)遞歸 a 中的引用,改變 c 的值,b 不會(huì)改變。
面:簡(jiǎn)述 Python 引用計(jì)數(shù)機(jī)制?
答:GC(Garbage Collector(垃圾收集器))機(jī)制:以下三種都是;
Python 垃圾回收主要以引用計(jì)數(shù)為主,標(biāo)記-清除 和 分代清除 為輔的機(jī)制,其中 標(biāo)記-清除 和 分代回收 主要是為了處理循環(huán)引用的難題。
引用計(jì)數(shù)算法:當(dāng)有 1 個(gè)變量保存了對(duì)象的引用時(shí),此對(duì)象的引用計(jì)數(shù)就會(huì)加 1,變?yōu)?0 后才會(huì)真正清除對(duì)象。
優(yōu)點(diǎn):高效、實(shí)時(shí)性[為 0 直接清除,其他可能需要等到合適的時(shí)機(jī)]、易于實(shí)現(xiàn)
缺點(diǎn):消耗資源、無(wú)法解決循環(huán)引用;解決:標(biāo)記-清除 和 分代清除
循環(huán)引用參考博客,下面簡(jiǎn)要介紹。
#循環(huán)引用問(wèn)題
list1 = [];list2 = []
list1.append(list2)
list2.append(list1)
'''
針對(duì)循環(huán)引用的情況:我們有一個(gè)“孤島”或是一組未使用的、互相指向的對(duì)象,但是誰(shuí)都沒(méi)有外部引用。換句話說(shuō),我們的程序不再使用這些節(jié)點(diǎn)對(duì)象了,所以我們希望Python的垃圾回收機(jī)制能夠足夠智能去釋放這些對(duì)象并回收它們占用的內(nèi)存空間。但是這不可能,因?yàn)樗械囊糜?jì)數(shù)都是1而不是0。
『標(biāo)記清除(Mark—Sweep)』算法是一種基于追蹤回收(tracing GC)技術(shù)實(shí)現(xiàn)的垃圾回收算法。它分為兩個(gè)階段:第一階段是標(biāo)記階段,GC 會(huì)把所有的『活動(dòng)對(duì)象』打上標(biāo)記,第二階段是把那些沒(méi)有標(biāo)記的對(duì)象『非活動(dòng)對(duì)象』進(jìn)行回收。那么 GC 又是如何判斷哪些是活動(dòng)對(duì)象哪些是非活動(dòng)對(duì)象的呢?
對(duì)象之間通過(guò)引用(指針)連在一起,構(gòu)成一個(gè)有向圖,對(duì)象構(gòu)成這個(gè)有向圖的節(jié)點(diǎn),而引用關(guān)系構(gòu)成這個(gè)有向圖的邊。從根對(duì)象(root object)出發(fā),沿著有向邊遍歷對(duì)象,可達(dá)的(reachable)對(duì)象標(biāo)記為活動(dòng)對(duì)象,不可達(dá)的對(duì)象就是要被清除的非活動(dòng)對(duì)象。根對(duì)象就是全局變量、調(diào)用棧、寄存器。
'''
面:Python 中的 值傳遞 與 引用傳遞?
答:Python 不允許程序員選擇采用 傳值 還是 傳引用。Python 參數(shù)傳遞采用的肯定是 傳對(duì)象引用 的方式。實(shí)際上,這種方式相當(dāng)于傳值和傳引用的一種綜合。如果函數(shù)收到的是一個(gè)可變對(duì)象(比如字典、列表)的引用,就能修改對(duì)象的原始值——相當(dāng)于通過(guò) 傳引用 來(lái)傳遞對(duì)象。如果函數(shù)收到的是一個(gè)不可變對(duì)象(比如數(shù)字、字符或者元組)的引用,就不能 直接修改原始對(duì)象——相當(dāng)于通過(guò) 傳值 來(lái)傳遞對(duì)象。 當(dāng)人們復(fù)制 列表 或 字典 時(shí),就復(fù)制了對(duì)象列表的引用值,如果改變引用的值,則修改了原始的參數(shù)。
基本概念
面:避免轉(zhuǎn)義給字符串加哪個(gè)字母表示原始字符串?
print(r'\abc') #輸出原始字符串 \abc,只有在不對(duì) \ 進(jìn)行轉(zhuǎn)義的時(shí)候用到
面:單引號(hào),雙引號(hào),三引號(hào)的區(qū)別?
name = 'tom'; sex = "male" #單引號(hào)和雙引號(hào)單獨(dú)使用沒(méi)什么區(qū)別
#下面才是單雙引號(hào)設(shè)計(jì)的本質(zhì)目的,這樣里面 'A' 就可以不用添加 \,變?yōu)?\'A\'
sentense = "We all know that 'A' and 'B' are two capital letters."
#三個(gè)引號(hào)不經(jīng)常用,用于原格式輸出
article = '''從哪來(lái)?
到哪去?
怎么去?
'''
面:Python2 和 Python3 的區(qū)別?
Python3 使用 print 必須要以小括號(hào)包裹打印內(nèi)容。
2.x 中 range 函數(shù)返回一個(gè)列表,3.x 返回一個(gè)可迭代對(duì)象。
2.x 中 sort 有 cmp 參數(shù)可接受兩個(gè)參數(shù)的函數(shù),3.x 中只有 key 接受一個(gè)參數(shù)的函數(shù)。
2.x 默認(rèn)編碼:ascii 解決辦法:在首行 # -- encoding:utf-8--;3.x 中編碼:utf-8。
2.x 整數(shù)除法為 /,3.x 為 //。
面:提高 Python 運(yùn)行效率的方法?
答:1.使用生成器,因?yàn)榭梢怨?jié)約大量?jī)?nèi)存。2.循環(huán)代碼優(yōu)化,避免在循環(huán)中調(diào)用太多函數(shù),可以用變量代替。
面:列舉 3 條以上 PEP8 編碼規(guī)范?
不要在行尾加分號(hào), 也不要用分號(hào)將兩條命令放在同一行。
不要使用反斜杠連接行,與左括號(hào)對(duì)齊,Python 會(huì)將圓括號(hào)的行隱式的連接起來(lái)。
頂層函數(shù)和類的定義,前后用兩個(gè)空行隔開(kāi)。
一般使用 4 個(gè)空格來(lái)縮進(jìn)代碼
面:Python 中標(biāo)識(shí)符的命名規(guī)則?
答:Python 中的標(biāo)識(shí)符可以是任意長(zhǎng)度,但必須遵循以下命名規(guī)則:
只能以下劃線或者 A-Z/a-z 中的字母開(kāi)頭。
其余部分只能使用 A-Z/a-z/0-9。
Python 標(biāo)識(shí)符區(qū)分大小寫。
關(guān)鍵字不能作為標(biāo)識(shí)符。
面:IOError、AttributeError、ImportError、IndentationError IndexError、KeyError、SyntaxError、NameError分別代表什么異常?
答:IOError:輸入輸出異常
AttributeError:試圖訪問(wèn)一個(gè)對(duì)象沒(méi)有的屬性
ImportError:無(wú)法引入模塊或包,基本是路徑問(wèn)題
IndentationError:語(yǔ)法錯(cuò)誤,代碼沒(méi)有正確的對(duì)齊
IndexError:下標(biāo)索引超出序列邊界
KeyError:試圖訪問(wèn)你字典里不存在的鍵
SyntaxError:Python 代碼邏輯語(yǔ)法出錯(cuò),不能執(zhí)行
NameError:使用一個(gè)還未賦予對(duì)象的變量
面:Python中的身份運(yùn)算符 is 和 == 的區(qū)別?
答:is 判斷兩個(gè)對(duì)象 id 是否相同,== 判斷兩個(gè)對(duì)象值是否相同,具體參考我的博客
面:Python 中運(yùn)算符?
[+,-,*,/,%,//,**] #算術(shù)運(yùn)算符
[>,>=,
[&,|,~,^,<>] #位運(yùn)算符
[in] #成員運(yùn)算符
[and,or,not] #邏輯運(yùn)算符
面:在 Python 中使用多進(jìn)制數(shù)字?
bin(10) #轉(zhuǎn)為二進(jìn)制,python 中二進(jìn)制表示0b1010
oct(10) #轉(zhuǎn)為八進(jìn)制, 0o12
hex(10) #轉(zhuǎn)為十六進(jìn)制,0xa
面:什么是元組的解封裝?
x,y,z = (1,2,3) #用變量取出 tuple 里面的值
內(nèi)部函數(shù)
面:列出幾種魔法方法并簡(jiǎn)要介紹用途?
答:兩邊的下劃線省略了, init :對(duì)象初始化方法
new :創(chuàng)建對(duì)象時(shí)候執(zhí)行的方法,單列模式會(huì)用到
str :當(dāng)使用 print 輸出對(duì)象的時(shí)候,只要自己定義了 __ str __(self) 方法,那么就會(huì)打印從在這個(gè)方法中 return 的數(shù)據(jù)
del :刪除對(duì)象執(zhí)行的方法
面:Python 中的 sort 是用什么排序?qū)崿F(xiàn)的,時(shí)間復(fù)雜度是多少?
答:TimSort 算法是一種起源于 歸并排序 和 插入排序 的混合排序算法,設(shè)計(jì)初衷是為了在真實(shí)世界中的各種數(shù)據(jù)中可以有較好的性能。基本工作過(guò)程是:1.掃描數(shù)組,確定其中的單調(diào)上升段和嚴(yán)格單調(diào)下降段,將嚴(yán)格下降段反轉(zhuǎn);2.定義最小基本片段長(zhǎng)度,短于此的單調(diào)片段通過(guò) 插入排序集中為長(zhǎng)于此的段;3.反復(fù)歸并一些相鄰片段,過(guò)程中避免歸并長(zhǎng)度相差很大的片段,直至整個(gè)排序完成,所用分段選擇策略可以保證O(n log n)時(shí)間復(fù)雜性。 可以看到,原則上TimSort是歸并排序,但小片段的合并中用了插入排序。
注意:2.x 中 cmp 可以接受兩個(gè)參數(shù)的函數(shù),3.x 中 key 接受一個(gè)參數(shù)的函數(shù),需要用key = cmp_to_key(func) 進(jìn)行模擬。
面:Python 的高階函數(shù)有哪些?
#更多可參考 Python 常用函數(shù)
map(lambda x: x*x ,[1,2,3])
zip([1,2,3],[4,5,6])
filter(lambda x: True if x%2==0 else False, [1,2,3,4])
import functools
functools.reduce(lambda x,y: x+y, [1,2,3,4])
#問(wèn):中的 *args,**kwargs 什么意思?
fun(*args,**kwargs)
#主要用于函數(shù)定義,將不定數(shù)量的參數(shù)傳遞給fun函數(shù),參數(shù)存在args中,args是一個(gè)元組(tuple)。允許你將不定長(zhǎng)度的鍵值對(duì)作為參數(shù)傳遞給一個(gè)函數(shù),參數(shù)則存儲(chǔ)為一個(gè)字典(dict)。
面:Python 中生成隨機(jī)整數(shù)、隨機(jī)小數(shù)、0 - 1 之間小數(shù)方法?
import random
random.randint(a,b) #生成區(qū)間內(nèi)的整數(shù)包括區(qū)間 [a,b]
random.random() #生成 [0.0,1.0) 中的隨機(jī)小數(shù)
import numpy
numpy.random.randn(5) #返回一個(gè)列表,生成 5 個(gè)隨機(jī)數(shù)
進(jìn)階問(wèn)題
面:簡(jiǎn)述 Python GIL 的概念, 以及它對(duì) Python 多線程的影響?編寫一個(gè)多線程抓取網(wǎng)頁(yè)的程序,并闡明多線程抓取程序是否可比單線程性能有提升,并解釋原因。?
答:目的:為了利用多核,Python 開(kāi)始支持多線程。而解決多線程之間數(shù)據(jù)完整性和狀態(tài)同步,最簡(jiǎn)單方法自然就是加鎖,于是有了 GIL 這把超級(jí)大鎖。
影響:開(kāi)始當(dāng)然是為了支持多線程,但后來(lái)發(fā)現(xiàn)對(duì)效率有很多影響。看到過(guò)一個(gè)測(cè)試,
一個(gè)循環(huán) 1 億次的計(jì)數(shù)器函數(shù)。一個(gè)通過(guò)單線程執(zhí)行兩次,一個(gè)多線程執(zhí)行。多線程竟然慢了大約45%。
原因:按照 Python 社區(qū)的想法,為了讓各個(gè)線程能夠平均利用 CPU 時(shí)間,Python 會(huì)計(jì)算當(dāng)前已執(zhí)行。這種模式在只有一個(gè) CPU 核心的情況下毫無(wú)問(wèn)題。任何一個(gè)線程被喚起時(shí)都能成功獲得到 GIL,但當(dāng) CPU 有多個(gè)核心的時(shí)候,問(wèn)題就來(lái)了。從 release GIL 到 acquire GIL 之間幾乎是沒(méi)有間隙的。所以當(dāng)其他在其他核心上的線程被喚醒時(shí),大部分情況下主線程已經(jīng)又再一次獲取到 GIL了。這個(gè)時(shí)候被喚醒執(zhí)行的線程只能白白的浪費(fèi) CPU 時(shí)間。參考博客
面:什么是猴子補(bǔ)丁?
答:在運(yùn)行時(shí)動(dòng)態(tài)修改類和模塊,這種場(chǎng)景也比較多,比如我們引用團(tuán)隊(duì)通用庫(kù)里的一個(gè)模塊,又想豐富模塊的功能,除了繼承之外也可以考慮用 Monkey Patch。個(gè)人感覺(jué) Monkey Patch 帶來(lái)了便利的同時(shí)也有搞亂源代碼優(yōu)雅的風(fēng)險(xiǎn)。
面:如何在 Python 中管理內(nèi)存?
答:Python 用一個(gè)私有堆內(nèi)存空間來(lái)放置所有對(duì)象和數(shù)據(jù)結(jié)構(gòu),我們無(wú)法訪問(wèn)它,由解釋器來(lái)管理它,不過(guò)使用一些核心 API,我們可以訪問(wèn)一些 Python 內(nèi)存管理工具控制內(nèi)存分配。
面:當(dāng)退出 Python 時(shí)是否釋放所有內(nèi)存分配?
答:答案是否定的。那些具有對(duì)象循環(huán)引用或者全局命名空間引用的變量,在 Python 退出是往往不會(huì)被釋放另外不會(huì)釋放 C 庫(kù)保留的部分內(nèi)容。
面:一句話解釋什么樣的語(yǔ)言能夠用(decorator)裝飾器?
答:函數(shù)可以作為參數(shù)傳遞的語(yǔ)言,可以使用裝飾器
def prin_fun_name(func):
def new_method(*args, **kw):#適用于任意參數(shù)的裝飾器
print('used function' + func.__name__)
return func(*args, **kw)
return new_method
面:請(qǐng)解釋 Python 中的閉包?
答:1. 假如你需要寫一個(gè)帶參數(shù)的裝飾器,那么一般都會(huì)生成閉包。
我個(gè)人認(rèn)為,閉包存在的意義就是它夾帶了外部變量(私貨),如果它不夾帶私貨,它和普通的函數(shù)就沒(méi)有任何區(qū)別。參考博客
面:解釋 Python 中 metaclass 關(guān)鍵字?
面:?
答:
面:?
答:
面:?
答:
面:?
答:
面:?
答:
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的python中类型错误、计数不采用关键字的错误怎么改_Learning/Python-面试问题.md at master · yxxyyx1314/Learning · GitHub...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 多层陶瓷电容器用处_陶瓷电容的作用及特点
- 下一篇: python 拆分excel openp