值得收藏的10道python 面試題
Q1:PEP8是什么?Python之禪(import this)是什么?
這題是考察你對(duì)編碼規(guī)范的認(rèn)識(shí),無論是自己寫代碼還是在團(tuán)隊(duì)中寫代碼,了解并遵循代碼規(guī)范是很基礎(chǔ)的要求。企業(yè)中在提交代碼后都會(huì)有對(duì)應(yīng)的工具來對(duì)代碼進(jìn)行檢查,比如 pep8、flake8、pylint 等,但是 PEP 8 是什么一定要了解。
即 Style Guide for Python Code(Python編碼風(fēng)格指南)。如果面試時(shí)不知道什么是 PEP 8 ,那聊起來想必不會(huì)很愉快。速戰(zhàn)速?zèng)Q的面試,如果不是你把面試官“秒殺”了,那就是面試官把你“秒殺”了,大部分是后者。 Python 之禪,也就是 import this。這屬于對(duì) Python 文化的了解了。什么意思?你去 Python shell 里執(zhí)行一下:import this,然后搜索下答案自然就出來了。
Q2:Python常用的容器類型有哪些以及它們之間的差別?
這是一道基礎(chǔ)題。如果被問到了這個(gè)問題,說明面試官在探測(cè)你對(duì) Python 基礎(chǔ)的掌握。如果不知道,那就會(huì)被“秒殺”。當(dāng)然聊得好了,也可以聊到實(shí)現(xiàn)原理層面。
在 Python 中常用的數(shù)據(jù)類型,有一些是基礎(chǔ)數(shù)據(jù)類型,比如 int、bool、string,還有容器類型,比如 list、set、dict 等。所有的類型又可以氛分為:可變類型和不可變類型(不知道是什么的可以動(dòng)手搜索一下)。單說容器類型,每種容器類型都有使用的場(chǎng)景,比如 list 可以存放不同類型的元素,特點(diǎn)是支持索引和切片操作,支持 insert 和 pop 操作,屬于可變類型。由此也可以展開很多面試題中遇到的坑,比如說這個(gè)代碼:
例子
然后再來說到 tuple,也可以當(dāng)做列表,支持迭代、索引、切片等操作,但因?yàn)樗遣豢勺冾愋?,所以不支?append、insert 等操作,為什么不支持呢?在從應(yīng)用上來說,在實(shí)際編程中經(jīng)常會(huì)用到它,比如:參數(shù)傳遞,解包。這一部分可以繼續(xù)聊下去的就是namedtuple。再然后就是 set 和 dict,它們跟 list 和 tuple有這么幾個(gè)差別:1. 存放的值不是順序的;2. 無法通過索引獲取到數(shù)據(jù); 3. 存放的元素不可重復(fù),并且必須是 hashable(可哈希的),針對(duì) key 來說;4. 更快的查找速度,因?yàn)槭峭ㄟ^哈希表來存儲(chǔ)的。當(dāng)然還可以繼續(xù)深入 set 和 dict 的原理,如何解決哈希碰撞。
Q3:解釋下閉包是什么,以及日常中什么場(chǎng)景會(huì)用到?
閉包是指持有了自由變量的函數(shù),那怎么理解呢,用代碼來看一下:
閉包
日常使用場(chǎng)景是什么呢?最常用會(huì)用到的地方就是裝飾器,上面的示例代碼也能看出來,比如我曾寫過 Cache 的演進(jìn)部分,部分代碼如下:
這就是個(gè)典型的場(chǎng)景。
Q4:GIL 是什么?它的影響和具體原理是什么?
GIL:Global Interpreter Lock(全局解釋器鎖)。具體表現(xiàn)就是:在一個(gè)進(jìn)程中,同一時(shí)刻只能有一個(gè)線程能到解釋器,為什么只能有一個(gè)線程拿到解釋器呢?因?yàn)樵?CPython 中,內(nèi)存管理不是線性安全的,所以,為了避免多個(gè)線程同時(shí)訪問到一個(gè)對(duì)象,就有了這么一個(gè)鎖。順帶著也提到了線程安全的概念,有了 GIL 了,那么 Python 中有哪些類型是線程安全的呢?哪些不是呢?又是一個(gè)新的問題。那么 GIL 的影響是什么呢?就是同一時(shí)刻只有一個(gè)線程在真實(shí)執(zhí)行,對(duì)于 CPU 密集型的應(yīng)用影響比較大,對(duì)于 IO 密集型的應(yīng)用影響沒那么大。當(dāng)然還可以具體展開來說。
Q5:進(jìn)程、協(xié)程、線程分別是什么,以及區(qū)別是什么?
從操作系統(tǒng)角度來講,進(jìn)程是資源分配單元,線程是執(zhí)行單元,多個(gè)線程可以共享所在進(jìn)程的資源。而協(xié)程是從程序運(yùn)行角度來叫,是由用戶(程序)控制和調(diào)度的一個(gè)過程,在 Python 中,協(xié)程是一個(gè)包含了 yield 的函數(shù),比如下圖:
協(xié)程(包含一個(gè)生成器)
在Python 3里面你可以用asyncio.iscoroutine(coro) 來判斷是否為協(xié)程。需要了解的是在協(xié)程執(zhí)行時(shí),是通過 event loop 來調(diào)度的。如果聊到這,可能會(huì)接著聊下 Tornado 的 IOLoop 的事??傮w來說,協(xié)程可以理解為更輕量級(jí)的線程,能夠在單線程中運(yùn)行多個(gè)協(xié)程。需要注意的是,在 Python 中協(xié)程執(zhí)行是串行的,這個(gè)是由于它的調(diào)度機(jī)制決定的,這點(diǎn)不同于 Golang。
Q6:如何理解 Django 被稱為 MTV 模式?
如果是我來問這個(gè)問題,這個(gè)題就是面向?qū)ο笤O(shè)計(jì)和設(shè)計(jì)模式的開始。簡(jiǎn)單來說大家耳熟能詳?shù)哪J浇? MVC。說是 Model View Controller,而在 Django 中因?yàn)?Template 來處理視圖展現(xiàn),所以稱為: MTV。接下里會(huì)問到的就是分層的概念,有句話叫:“沒有什么問題是不能通過增加一層解決的,如果有,那就再加一層?!碑?dāng)然還會(huì)有設(shè)計(jì)模式的一些原則等著你,比如開-閉原則、單一職責(zé)原則等。
Q7:解釋下什么是 ORM 以及它的優(yōu)缺點(diǎn)是什么?
ORM:Object Relational Mapping(對(duì)象關(guān)系映射),它做的事就是幫我們封裝一下對(duì)數(shù)據(jù)庫的操作,避免我們來寫不太好維護(hù)的 SQL 代碼。優(yōu)點(diǎn)就是讓我們寫的代碼更容易維護(hù),因?yàn)槔锩娌挥脢A雜著各種 SQL 代碼。缺點(diǎn)是失去了 SQL 的靈活,并且越是通用的 ORM 框架,性能損耗會(huì)越大。
說到性能損耗,可以接著聊的是 Django 中的 raw sql,也就是說Model.objects.raw這個(gè)方法的使用,它的作用、原理、性能提升等。還可以繼續(xù)聊另外一個(gè)老生常談的問題:N+1 的問題。
Q8:如何排查 Django 系統(tǒng)中的性能問題?
對(duì)于 Django 這樣一個(gè)非常成熟的框架來說,豐富的周邊能夠讓我們快速的找到別人開源出來的優(yōu)秀插件,比如說 Django-debug-toolbar,或者是 Django-silk 。但是一個(gè)基礎(chǔ)問題是:在 Django 的 settings 中,設(shè)置DEBUG = True 和 DEBUG = False 的差別是什么?還可以聊的是對(duì)于 Django 處理請(qǐng)求到返回響應(yīng)的具體流程。因?yàn)橹挥惺煜ち苏w流程,才能在合理的位置進(jìn)行排查。比方說,當(dāng)我們判斷可能是數(shù)據(jù)庫的問題時(shí),那可能需要在 Model 層的某個(gè)方法上加上執(zhí)行時(shí)間監(jiān)測(cè)的邏輯。如果是 View 層的其他邏輯導(dǎo)致的,可能會(huì)在 Middleware 上增加執(zhí)行時(shí)間監(jiān)測(cè)的邏輯。
Q9:Django 系統(tǒng)中如何配置數(shù)據(jù)庫的長(zhǎng)連接?
這涉及到 Django 如何處理數(shù)據(jù)庫連接細(xì)節(jié)的問題。默認(rèn)情況下對(duì)于每一個(gè)請(qǐng)求 Django 都會(huì)建立一個(gè)新的數(shù)據(jù)庫連接。這意味著當(dāng)請(qǐng)求量過大時(shí)就會(huì)出現(xiàn)數(shù)據(jù)庫(MySQL)的 Too many connection 的問題,對(duì)于這個(gè)問題,在其他的語言框架中有連接池這樣的東西來減少數(shù)據(jù)庫的連接數(shù),來提升連接的使用效率。而在 Django 中,為了處理這一問題,增加了一個(gè)配置: CONN_MAX_AGE,在 settings 的 DATABASES 配置中。配置了該選項(xiàng)后,Django 會(huì)跟數(shù)據(jù)庫保持鏈接(時(shí)長(zhǎng)取決于 CONN_MAX_AGE 設(shè)定的值 ),不再會(huì)針對(duì)每個(gè)請(qǐng)求都創(chuàng)建新的連接了。但是需要注意的是,這跟數(shù)據(jù)庫連接池的概念還不太一樣。
Q10:如何部署并監(jiān)控 Django 系統(tǒng)?
這個(gè)就是考察候選人對(duì)于真實(shí)項(xiàng)目的部署和線上問題排查的了解了。如果沒有真實(shí)工作過,可能不太有概念。首先需要理解的是開發(fā)的流程,代碼在程序員的電腦(開發(fā)機(jī))上開發(fā)完成,然后部署到測(cè)試環(huán)境進(jìn)行測(cè)試,這個(gè)過程可能是自動(dòng)的(由 GitLab CI 觸發(fā)或者其他類似邏輯),也可能是需要人工操作的(比如使用 Fabric 或者 ansible)手動(dòng)執(zhí)行部署操作。然后測(cè)試同學(xué)進(jìn)行測(cè)試,沒問題之后,代碼合并到主分支(涉及Git相關(guān)的使用流程),再部署上線。
這時(shí)系統(tǒng)就可以對(duì)外提供服務(wù)了,那么問題來了,用戶的訪問是如何到你部署的系統(tǒng)中來的?再來說監(jiān)控。監(jiān)控的目的是為了保證程序的正常運(yùn)行,如果出現(xiàn)問題我們可以及時(shí)發(fā)現(xiàn)并修復(fù)。所以,簡(jiǎn)單來說有兩個(gè)確定的指標(biāo)可以觀察,第一個(gè)是狀態(tài)碼,對(duì)于 HTTP 服務(wù)來說,監(jiān)控非 200 的狀態(tài)碼的數(shù)量是很有必要的;第二個(gè)就是應(yīng)用內(nèi)的異常監(jiān)控,這個(gè)就是 Sentry 之類的系統(tǒng)來做了,通過它可以收集到具體的異常詳情,完成的 Traceback,可以幫助我們快速地定位問題所在。
雖然說只有十個(gè)問題,但是在正式聊的時(shí)候,每個(gè)問題都是可以層層追問的,其實(shí)面試有個(gè)原則,就是:要追問到候選人答不出來,或者面試官不知道該問什么為止,因?yàn)樾枰_定候選人的技術(shù)掌握的邊界(深度)。
總結(jié)
以上所述是小編給大家介紹的值得收藏的10道python 面試題,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
卡爾曼濾波數(shù)據(jù)處理技巧通俗理解及python實(shí)現(xiàn)
這篇文章主要為大家介紹了卡爾曼濾波數(shù)據(jù)處理技巧的通俗理解及python實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Python道路車道線檢測(cè)的實(shí)現(xiàn)
在本文中,我們將構(gòu)建一個(gè)機(jī)器學(xué)習(xí)項(xiàng)目來實(shí)時(shí)檢測(cè)車道線。我們將使用 OpenCV 庫使用計(jì)算機(jī)視覺的概念來做到這一點(diǎn),感興趣的可以了解一下2021-06-06Python實(shí)時(shí)監(jiān)控網(wǎng)站瀏覽記錄實(shí)現(xiàn)過程詳解
這篇文章主要介紹了Python實(shí)時(shí)監(jiān)控網(wǎng)站瀏覽記錄實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07