非常全面的Python常見(jiàn)基礎(chǔ)面試題及答案
Python
1 Python垃圾回收機(jī)制是什么
作為Python的使用者來(lái)說(shuō),Python中的垃圾回收主要以引用計(jì)數(shù)為主,再引入標(biāo)記、清除,分代為輔來(lái)解決循環(huán)引用的問(wèn)題。
一個(gè)對(duì)象被引用時(shí),引用計(jì)數(shù)加1,當(dāng)對(duì)象被del時(shí),引用計(jì)數(shù)減去1,為0時(shí),對(duì)象就被清除,一般情況下用戶不會(huì)去操作Python 的垃圾回收機(jī)制,但它留有API接口。
2 元組和列表的區(qū)別
主要區(qū)別是列表是可變的,而元組是不可變的。
>>> mylist=[1,3,3] >>> mylist[1]=2 >>> mytuple=(1,3,3) >>> mytuple[1]=2 Traceback (most recent call last): File "<pyshell#97>", line 1, in <module>
3 元組可以作為字典的key?
首先一個(gè)對(duì)象能不能作為字典的key, 就取決于其有沒(méi)有__hash__方法。 所以除了容器對(duì)象(list/dict/set)和內(nèi)部包含容器對(duì)象的tuple 是不可作為字典的key, 其他的對(duì)象都可以。
4 進(jìn)程 線程 協(xié)程
4.1 進(jìn)程
1、操作系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,多個(gè)進(jìn)程之間相互獨(dú)立
2、穩(wěn)定性好,如果一個(gè)進(jìn)程崩潰,不影響其他進(jìn)程,但是進(jìn)程消耗資源大,開(kāi)啟的進(jìn)程數(shù)量有限制
4.2 線程
1、CPU進(jìn)行資源分配和調(diào)度的基本單位,線程是進(jìn)程的一部分,是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位,一個(gè)進(jìn)程下的多個(gè)線程可以共享該進(jìn)程的所有資源
2、如果IO操作密集,則可以多線程運(yùn)行效率高,缺點(diǎn)是如果一個(gè)線程崩潰,都會(huì)造成進(jìn)程的崩潰
4.3 協(xié)程
1、子程序調(diào)用總是一個(gè)入口,一次返回,調(diào)用順序是明確的。而協(xié)程的調(diào)用和子程序不同。
2、協(xié)程看上去也是子程序,但執(zhí)行過(guò)程中,在子程序內(nèi)部可中斷,然后轉(zhuǎn)而執(zhí)行別的子程序,在適當(dāng)?shù)臅r(shí)候再返回來(lái)接著執(zhí)行。
5 賦值、淺拷貝和深拷貝
深拷貝就是將一個(gè)對(duì)象拷貝到另一個(gè)對(duì)象中,這意味著如果你對(duì)一個(gè)對(duì)象的拷貝做出改變時(shí),不會(huì)影響原對(duì)象。在Python中,我們使用函數(shù)deepcopy()執(zhí)行深拷貝
淺拷貝則是將一個(gè)對(duì)象的引用拷貝到另一個(gè)對(duì)象上,所以如果我們?cè)诳截愔懈膭?dòng),會(huì)影響到原對(duì)象
6 GIL
GIL是python的全局解釋器鎖,同一進(jìn)程中假如有多個(gè)線程運(yùn)行,一個(gè)線程在運(yùn)行python程序的時(shí)候會(huì)霸占python解釋器(加了一把鎖即GIL),使該進(jìn)程內(nèi)的其他線程無(wú)法運(yùn)行,等該線程運(yùn)行完后其他線程才能運(yùn)行。如果線程運(yùn)行過(guò)程中遇到耗時(shí)操作,則解釋器鎖解開(kāi),使其他線程運(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)資源開(kāi)銷(xiāo)大
7 列表去重
先通過(guò)轉(zhuǎn)換為集合去重,在轉(zhuǎn)列表
8 最常用的排序算法及其復(fù)雜度
8.1 冒泡排序
外層循環(huán)從1到n-1,內(nèi)循環(huán)從當(dāng)前外層的元素的下一個(gè)位置開(kāi)始,依次和外層的元素比較,出現(xiàn)逆序就交換,通過(guò)與相鄰元素的比較和交換來(lái)把小的數(shù)交換到最前面。
def bubbleSort(array): if len(array) < 2: return array else: isSorted = False counter = 0 while not isSorted: isSorted = True for idx in range(len(array) - 1 - counter): if array[idx] > array[idx + 1]: isSorted = False (array[idx + 1], array[idx]) = (array[idx], array[idx + 1]) counter += 1 return array
8.3 快速排序
通過(guò)一趟排序?qū)⒋庞涗浄指舫瑟?dú)立的兩部分,其中一部分記錄的關(guān)鍵字均比另一部分的關(guān)鍵字小,則可分別對(duì)這兩部分記錄繼續(xù)進(jìn)行排序,以達(dá)到整個(gè)序列有序。
1、選定Pivot中心軸
2、從R指針開(kāi)始,將大于Pivot的數(shù)字放在Pivot的右邊
3、將小于Pivot的數(shù)字放在Pivot的左邊
4、分別對(duì)左右子序列重復(fù)前三步操作
def quickSort(array): print(array) if len(array) < 2: return array else: pivot_index = 0 pivot = array[pivot_index] less_part = [i for i in array[pivot_index+1:] if i <= pivot] large_part = [i for i in array[pivot_index+1:] if i > pivot] return quickSort(less_part) + [pivot] + quickSort(large_part)
9 閉包
函數(shù)的返回值是函數(shù)對(duì)象,只有外部函數(shù)才可以對(duì)他進(jìn)行訪問(wèn),提高了安全性
10 with
with語(yǔ)句的使用,可以簡(jiǎn)化了代碼,有效避免資源泄露的發(fā)生
打開(kāi)文件在進(jìn)行讀寫(xiě)的時(shí)候可能會(huì)出現(xiàn)一些異常狀況,如果按照常規(guī)的f.open
寫(xiě)法,我們需要try,except,finally,做異常判斷,并且文件最終不管遇到什么情況,都要執(zhí)行finally f.close()關(guān)閉文件,with方法幫我們實(shí)現(xiàn)了finally中f.close
11 實(shí)例方法 靜態(tài)方法
實(shí)例方法只能被實(shí)例調(diào)用,靜態(tài)方法(@由staticmethod裝飾器的方法)、類(lèi)方法(由@classmethod裝飾器的方法),可以被類(lèi)或類(lèi)的實(shí)例對(duì)象調(diào)用。
1、實(shí)例方法,第一個(gè)參數(shù)必須要默認(rèn)傳遞實(shí)例對(duì)象,一般使用self。
2、靜態(tài)方法,參數(shù)沒(méi)有必要。
3、類(lèi)方法,第一個(gè)參數(shù)必須要默認(rèn)傳遞,一般使用cls。
12 迭代器和生成器
12.1 迭代器
迭代器是一個(gè)可以記住遍歷的位置的對(duì)象。
迭代器對(duì)象從集合的第一個(gè)元素開(kāi)始訪問(wèn),直到所有的元素被訪問(wèn)完結(jié)束。迭代器只能往前不會(huì)后退。
迭代器有兩個(gè)基本的方法:iter() 和 next()。
字符串,列表或元組對(duì)象都可用于創(chuàng)建迭代器:
>>> list=[1,2,3,4] >>> it = iter(list) # 創(chuàng)建迭代器對(duì)象 >>> print (next(it)) # 輸出迭代器的下一個(gè)元素 1 >>> print (next(it)) 2 >>>
12.2 生成器
使用了yield的函數(shù)被稱(chēng)為生成器
生成器是一個(gè)返回迭代器的函數(shù),只能用于迭代操作,更簡(jiǎn)單點(diǎn)理解生成器就是一個(gè)迭代器
在調(diào)用生成器運(yùn)行的過(guò)程中,每次遇到 yield 時(shí)函數(shù)會(huì)暫停并保存當(dāng)前所有的運(yùn)行信息,返回 yield 的值, 并在下一次執(zhí)行 next() 方法時(shí)從當(dāng)前位置繼續(xù)運(yùn)行
13 匿名函數(shù)
print [(lambda x:x*x)(x)for x in range(5)] [0, 1, 4, 9, 16, 25]
14 map reduce filter
14.1 map
對(duì)可迭代對(duì)象中的每個(gè)元素進(jìn)行相同的操作
def fn(x): return x+1 resp = map(fn,li) print(list(resp)) [2, 3, 4]
14.2 reduce
從左到右對(duì)一個(gè)序列的項(xiàng)累計(jì)地應(yīng)用有兩個(gè)參數(shù)的函數(shù),以此合并序列到一個(gè)單一值。(例如累加或累乘列表元素等等)
from functools import reduce nums=[1, 2, 3, 4] def fn(x, y): return x * y resp = reduce(fn, nums) print(resp) 24
14.3 filter
filter函數(shù)用于過(guò)濾序列,過(guò)濾掉不符合條件的元素,返回由符合條件元素組成的新列表。該接收兩個(gè)參數(shù): 第一個(gè)為函數(shù),第二個(gè)為序列,序列的每個(gè)元素作為參數(shù)傳遞給函數(shù)進(jìn)行判,然后返回 True 或 False,最后將返回 True 的元素放到新列表
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] def fn(a): return a%2 == 1 newlist = filter(fn, a) newlist = [i for i in newlist] print(newlist) ## 輸出: [1, 3, 5, 7, 9]
Django
1 什么是wsgi
Python Web Server Gateway Interface,翻譯過(guò)來(lái)是Python web服務(wù)器網(wǎng)關(guān)接口,實(shí)際上就是一種協(xié)議,我們的應(yīng)用(Django,Flask)實(shí)現(xiàn)了WSGI,就可以配合實(shí)現(xiàn)了WSGI(uWSGI,gunicorn)的服務(wù)器工作了
2 django請(qǐng)求的生命周期
- 前端發(fā)送請(qǐng)求
- wsgi, 他就是socket服務(wù)端,用于接收用戶請(qǐng)求并將請(qǐng)求進(jìn)行初次封裝,然后將請(qǐng)求交給web框架(Flask、Django)
- 中間件處理請(qǐng)求,幫助我們對(duì)請(qǐng)求進(jìn)行校驗(yàn)或在請(qǐng)求對(duì)象中添加其他相關(guān)數(shù)據(jù),例如:csrf、request.session
- 路由匹配,根據(jù)當(dāng)前請(qǐng)求的URL找到視圖函數(shù),如果是FBV寫(xiě)法,通過(guò)判斷method兩類(lèi)型,找到對(duì)應(yīng)的視圖函數(shù);如果是CBV寫(xiě)法,匹配成功后會(huì)自動(dòng)去找dispatch方法,然后Django會(huì)通過(guò)dispatch反射的方式找到類(lèi)中對(duì)應(yīng)的方法并執(zhí)行
- 視圖函數(shù),在視圖函數(shù)中進(jìn)行業(yè)務(wù)邏輯的處理,可能涉及到:orm、view視圖將數(shù)據(jù)渲染到template模板
- 視圖函數(shù)執(zhí)行完畢之后,會(huì)把客戶端想要的數(shù)據(jù)返回給dispatch方法,由dispatch方法把數(shù)據(jù)返回經(jīng)客戶端
- 中間件處理響應(yīng)
- wsgi,將響應(yīng)的內(nèi)容發(fā)送給瀏覽器
- 瀏覽器渲染
3 列舉django的內(nèi)置組件
- Admin: 對(duì)model中對(duì)應(yīng)的數(shù)據(jù)表進(jìn)行增刪改查提供的組件
- model:負(fù)責(zé)操作數(shù)據(jù)庫(kù)
- form:1.生成HTML代碼 2.數(shù)據(jù)有效性校驗(yàn) 3校驗(yàn)信息返回并展示
- ModelForm: 即用于數(shù)據(jù)庫(kù)操作,也可用于用戶請(qǐng)求的驗(yàn)證
4 列舉django中間件的5個(gè)方法?以及django中間件的應(yīng)用場(chǎng)景
- process_request : 請(qǐng)求進(jìn)來(lái)時(shí),權(quán)限認(rèn)證
- process_view : 路由匹配之后,能夠得到視圖函數(shù)
- process_exception : 異常時(shí)執(zhí)行
- process_template_responseprocess : 模板渲染時(shí)執(zhí)行
- process_response : 請(qǐng)求有響應(yīng)時(shí)執(zhí)行
5 簡(jiǎn)述什么是FBV和CBV
FBV和CBV本質(zhì)是一樣的,基于函數(shù)的視圖叫做FBV,基于類(lèi)的視圖叫做CBV
在python中使用CBV的優(yōu)點(diǎn):
- 提高了代碼的復(fù)用性,可以使用面向?qū)ο蟮募夹g(shù),比如Mixin(多繼承)
- 可以用不同的函數(shù)針對(duì)不同的HTTP方法處理,而不是通過(guò)很多if判斷,提高代碼可讀性
6 django的request對(duì)象是在什么時(shí)候創(chuàng)建的
class WSGIHandler(base.BaseHandler): request = self.request_class(environ)
請(qǐng)求走到WSGIHandler類(lèi)的時(shí)候,執(zhí)行cell方法,將environ封裝成了request
7 如何在CBV添加裝飾器
7.1 方法
from django.utils.decorators import method_decorator @method_decorator(check_login) def post(self, request): ...
7.2 dispatch
@method_decorator(check_login) def dispatch(self, request, *args, **kwargs):
7.3 類(lèi)
@method_decorator(check_login, name="get") @method_decorator(check_login, name="post") class HomeView(View): ...
8 列舉django orm 中所有的方法
<1> all(): 查詢(xún)所有結(jié)果
<2> filter(**kwargs): 它包含了與所給篩選條件相匹配的對(duì)象。獲取不到返回None
<3> get(**kwargs): 返回與所給篩選條件相匹配的對(duì)象,返回結(jié)果有且只有一個(gè)。
如果符合篩選條件的對(duì)象超過(guò)一個(gè)或者沒(méi)有都會(huì)拋出錯(cuò)誤。
<4> exclude(**kwargs): 它包含了與所給篩選條件不匹配的對(duì)象
<5> order_by(*field): 對(duì)查詢(xún)結(jié)果排序
<6> reverse(): 對(duì)查詢(xún)結(jié)果反向排序
<8> count(): 返回?cái)?shù)據(jù)庫(kù)中匹配查詢(xún)(QuerySet)的對(duì)象數(shù)量。
<9> first(): 返回第一條記錄
<10> last(): 返回最后一條記錄
<11> exists(): 如果QuerySet包含數(shù)據(jù),就返回True,否則返回False
<12> values(*field): 返回一個(gè)ValueQuerySet——一個(gè)特殊的QuerySet,運(yùn)行后得到的
并不是一系 model的實(shí)例化對(duì)象,而是一個(gè)可迭代的字典序列
<13> values_list(*field): 它與values()非常相似,它返回的是一個(gè)元組序列,values返回的是一個(gè)字典序列
<14> distinct(): 從返回結(jié)果中剔除重復(fù)紀(jì)錄
9 select_related 和 prefetch_related的區(qū)別
有外鍵存在時(shí),可以很好的減少數(shù)據(jù)庫(kù)請(qǐng)求的次數(shù),提高性能
select_related 通過(guò)多表 join 關(guān)聯(lián)查詢(xún), 一次性獲得所有數(shù)據(jù), 只執(zhí)行一次SQL查詢(xún)
prefetch_related 分別查詢(xún)每個(gè)表, 然后根據(jù)它們之間的關(guān)系進(jìn)行處理, 執(zhí)行兩次查詢(xún)
10 django 中 csrf 的實(shí)現(xiàn)機(jī)制
第一步:django第一次響應(yīng)來(lái)自某個(gè)客戶端的請(qǐng)求時(shí),后端隨機(jī)產(chǎn)生一個(gè)token值,把這個(gè)token保存在SESSION狀態(tài)中;同時(shí),后端把這個(gè)token放到cookie中交給前端頁(yè)面;
第二步:下次前端需要發(fā)起請(qǐng)求(比如發(fā)帖)的時(shí)候把這個(gè)token值加入到請(qǐng)求數(shù)據(jù)或者頭信息中,一起傳給后端;Cookies:{csrftoken:xxxxx}
第三步:后端校驗(yàn)前端請(qǐng)求帶過(guò)來(lái)的token和SESSION里的token是否一致。
11 django中如何實(shí)現(xiàn)orm表中添加數(shù)據(jù)時(shí)創(chuàng)建一條日志記錄
# 使用Django的信號(hào)機(jī)制,可以在添加、刪除數(shù)據(jù)前后設(shè)置日志記錄: pre_init # Django中的model對(duì)象執(zhí)行其構(gòu)造方法前,自動(dòng)觸發(fā) post_init # Django中的model對(duì)象執(zhí)行其構(gòu)造方法后,自動(dòng)觸發(fā) pre_save # Django中的model對(duì)象保存前,自動(dòng)觸發(fā) post_save # Django中的model對(duì)象保存后,自動(dòng)觸發(fā) pre_delete # Django中的model對(duì)象刪除前,自動(dòng)觸發(fā) post_delete # Django中的model對(duì)象刪除后,自動(dòng)觸發(fā) # 使用 @receiver(post_save, sender=Myclass) # 信號(hào)接收裝飾器。由于內(nèi)置信號(hào),所以直接接收 def signal_handler(sender, **kwargs): # 接收到信號(hào)后,在此處理 logger = logging.getLogger() logger.success('保存成功')
12 django緩存如何設(shè)置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 緩存后臺(tái)使用的引擎 'TIMEOUT': 300, # 緩存超時(shí)時(shí)間(默認(rèn)300秒,None表示永不過(guò)期,0表示立即過(guò)期) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大緩存記錄的數(shù)量(默認(rèn)300) 'CULL_FREQUENCY': 3, # 緩存到達(dá)最大個(gè)數(shù)之后,剔除緩存?zhèn)€數(shù)的比例,即:1/CULL_FREQUENCY(默認(rèn)3) }, } }
13 django的緩存能使用redis嗎?如果可以的話,如何配置
CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # "PASSWORD": "密碼", } } }
14 django路由系統(tǒng)中name的作用
主要是通過(guò)name的值,來(lái)查找url地址,可以理解為反射作用。在html模板中使用name來(lái)反射url優(yōu)勢(shì)就是后期url規(guī)則發(fā)生改變之后,只需調(diào)整urls.py即可,所有的模板文件都不需要修改。
15 django rest framework框架中都有那些組件
- 認(rèn)證
- 權(quán)限(授權(quán))
- 用戶訪問(wèn)次數(shù)/頻率限制
- 版本
- 解析器(parser)
- 序列化
- 分頁(yè)
- 路由系統(tǒng)
- 視圖
- 渲染器
16 簡(jiǎn)述 django rest framework框架的認(rèn)證流程
- 當(dāng)用戶進(jìn)行登錄的時(shí)候,運(yùn)行了登錄類(lèi)的as_view()方法,進(jìn)入了APIView類(lèi)的dispatch方法
- 執(zhí)行self.initialize_request這個(gè)方法,里面封裝了request和認(rèn)證對(duì)象列表等其他參數(shù)
- 執(zhí)行self.initial方法中的self.perform_authentication,里面運(yùn)行了user方法
- 再執(zhí)行了user方法里面的self._authenticate()方法
總結(jié)
到此這篇關(guān)于Python常見(jiàn)基礎(chǔ)面試題及答案的文章就介紹到這了,更多相關(guān)Python基礎(chǔ)面試題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python進(jìn)階學(xué)習(xí)實(shí)時(shí)目標(biāo)跟蹤示例詳解
這篇文章主要為大家介紹了python進(jìn)階學(xué)習(xí)實(shí)時(shí)目標(biāo)跟蹤示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03python處理“”開(kāi)頭加數(shù)字的html字符方法
在本篇文章里小編給大家整理了關(guān)于python如何處理“&#”開(kāi)頭加數(shù)字的html字符的相關(guān)知識(shí)點(diǎn)總結(jié),有興趣的朋友們學(xué)習(xí)下。2019-06-06Python爬蟲(chóng)爬取全球疫情數(shù)據(jù)并存儲(chǔ)到mysql數(shù)據(jù)庫(kù)的步驟
這篇文章主要介紹了Python爬蟲(chóng)爬取全球疫情數(shù)據(jù)并存儲(chǔ)到mysql數(shù)據(jù)庫(kù)的步驟,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-03-03Python實(shí)現(xiàn)平行坐標(biāo)圖的繪制(plotly)方式
今天小編就為大家分享一篇Python實(shí)現(xiàn)平行坐標(biāo)圖的繪制(plotly)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11Python爬蟲(chóng)實(shí)戰(zhàn)項(xiàng)目掌握酷狗音樂(lè)的加密過(guò)程
在常見(jiàn)的幾個(gè)音樂(lè)網(wǎng)站里,酷狗可以說(shuō)是最好爬取的啦,什么彎都沒(méi)有,所以最適合小白入門(mén)爬蟲(chóng),本篇針對(duì)爬蟲(chóng)零基礎(chǔ)的小白,所以每一步驟我都截圖并詳細(xì)解釋了,其實(shí)我自己看著都啰嗦,歸根到底就是兩個(gè)步驟的請(qǐng)求,還請(qǐng)大佬繞路勿噴2021-09-09