常見面試題整理--Python概念篇
雙十一你們的手還健在嗎? 還在的話來刷一波題?
希望此文可以長期更新並作為一篇Python的面試寶典。每一道題目都附有詳細解答,以及更加詳細的回答鏈接。此篇是概念篇,下一篇會更新面試題代碼篇。
(一)、這兩個參數是什麼意思:*args,**kwargs?我們為什麼要使用它們?答:如果我們不確定往一個函數中傳入多少參數,或者我們希望以元組(tuple)或者列表(list)的形式傳參數的時候,我們可以使用*args(單星號)。如果我們不知道往函數中傳遞多少個關鍵詞參數或者想傳入字典的值作為關鍵詞參數的時候我們可以使用**kwargs(雙星號),args、kwargs兩個標識符是約定俗成的用法。
另一種答法:當函數的參數前面有一個星號*號的時候表示這是一個可變的位置參數,兩個星號**表示這個是一個可變的關鍵詞參數。星號*把序列或者集合解包(unpack)成位置參數,兩個星號**把字典解包成關鍵詞參數。
代碼輔助理解:
(二)、談一談Python的裝飾器(decorator)
裝飾器本質上是一個Python函數,它可以讓其它函數在不作任何變動的情況下增加額外功能,裝飾器的返回值也是一個函數對象。它經常用於有切面需求的場景。比如:插入日誌、性能測試、事務處理、緩存、許可權校驗等。有了裝飾器我們就可以抽離出大量的與函數功能無關的雷同代碼進行重用。
有關於具體的裝飾器的用法看這裡:裝飾器 - 廖雪峰的官方網站
(三)、簡要描述Python的垃圾回收機制(garbage collection)Python中的垃圾回收是以引用計數為主,標記-清除和分代收集為輔。
- 引用計數:Python在內存中存儲每個對象的引用計數,如果計數變成0,該對象就會消失,分配給該對象的內存就會釋放出來。
- 標記-清除:一些容器對象,比如list、dict、tuple,instance等可能會出現引用循環,對於這些循環,垃圾回收器會定時回收這些循環(對象之間通過引用(指針)連在一起,構成一個有向圖,對象構成這個有向圖的節點,而引用關係構成這個有向圖的邊)。
- 分代收集:Python把內存根據對象存活時間劃分為三代,對象創建之後,垃圾回收器會分配它們所屬的代。每個對象都會被分配一個代,而被分配更年輕的代是被優先處理的,因此越晚創建的對象越容易被回收。
如果你想要深入了解Python的GC機制,點擊這裡:[轉載]Python垃圾回收機制--完美講解!
(四)、Python多線程(multi-threading)。這是個好主意嗎?
Python並不支持真正意義上的多線程,Python提供了多線程包。Python中有一個叫Global Interpreter Lock(GIL)的東西,它能確保你的代碼中永遠只有一個線程在執行。經過GIL的處理,會增加執行的開銷。這就意味著如果你先要提高代碼執行效率,使用threading不是一個明智的選擇,當然如果你的代碼是IO密集型,多線程可以明顯提高效率,相反如果你的代碼是CPU密集型的這種情況下多線程大部分是雞肋。
想要深入詳細了解多線程,點擊這裡:詳解Python中的多線程編程_python
想了解一下IO密集和CPU密集可以點擊這裡:CPU-bound(計算密集型) 和I/O bound(I/O密集型)
(五)、 說明os,sys模塊不同,並列舉常用的模塊方法?
官方文檔:
- os模板提供了一種方便的使用操作系統函數的方法
- sys模板可供訪問由解釋器使用或維護的變數和與解釋器交互的函數
另一種回答:
os模塊負責程序與操作系統的交互,提供了訪問操作系統底層的介面。sys模塊負責程序與Python解釋器的交互,提供了一系列的函數和變數用戶操作Python運行時的環境。
一些常用的方法:
一些常用的用法示例:
想要了解更詳細的使用請訪問:os和sys模塊 - 君醉(六)、什麼是lambda表達式?它有什麼好處?
簡單來說,lambda表達式通常是當你需要使用一個函數,但是又不想費腦袋去命名一個函數的時候使用,也就是通常所說的匿名函數。
lambda表達式一般的形式是:關鍵詞lambda後面緊接一個或多個參數,緊接一個冒號「:」,緊接一個表達式。lambda表達式是一個表達式不是一個語句。
想更加詳細的了解Python中的Lamdba表達式可以點擊這裡:Lambda 表達式有何用處?如何使用? - Python(七)、Python中pass語句的作用是什麼?
pass語句不會執行任何操作,一般作為佔位符或者創建佔位程序
(八)、Python是如何進行類型轉換的?
Python提供了將變數或值從一種類型轉換為另一種類型的內置方法。
(九)、Python裡面如何拷貝一個對象?
Python中對象之間的賦值是按引用傳遞的,如果要拷貝對象需要使用標準模板中的copy
- copy.copy:淺拷貝,只拷貝父對象,不拷貝父對象的子對象。
- copy.deepcopy:深拷貝,拷貝父對象和子對象。
- __init__為初始化方法,__new__方法是真正的構造函數。
- __new__是實例創建之前被調用,它的任務是創建並返回該實例,是靜態方法
- __init__是實例創建之後被調用的,然後設置對象屬性的一些初始值。
總結:__new__方法在__init__方法之前被調用,並且__new__方法的返回值將傳遞給__init__方法作為第一個參數,最後__init__給這個實例設置一些參數。
想要更加詳細的了解這兩個方法,請點擊:Python中的__new__及其用法(十一)、Python中單下劃線和雙下劃線分別是什麼?
- __name__:一種約定,Python內部的名字,用來與用戶自定義的名字區分開,防止衝突
- _name:一種約定,用來指定變數私有
- __name:解釋器用_classname__name來代替這個名字用以區別和其他類相同的命名
想要更加詳細的了解這兩者的區別,請點擊:Python中的下劃線(譯文)
(十二)、說一說Python自省。
自省就是面向對象的語言所寫的程序在運行時,所能知道對象的類型。簡單一句話就是運行時能夠獲得對象的類型。比如:type()、dir()、getattr()、hasattr()、isinstance()
想要完整的理解Python自省,請點擊:Python自省(反射)指南
有關於元類以及單例模式會在後面文章中做詳細的解釋說明。
本文參考文獻資料:
「1」七、PYTHON 一些基礎面試題目總結
「2」很全的 Python 面試題
「3」Python自省(反射)指南
「4」Python學習筆記(十二):lambda表達式與函數式編程
「5」Python面試必須要看的15個問題
學習編程,歡迎關注專欄:學習編程 - 知乎專欄推薦閱讀:
※論Python asyncio的一個坑
※用C++畫光(三):四叉樹
※【philippica】正則表達式從入門到放棄
※koa2:Node.js開發一個同步伺服器