最近面試了十幾個人,主要想招Python熟練的,然後問了些Python問題,發現他們大部分答得都不太好。
之後我想了想,好的Python面試題確實難找,找到了問問來面試的人,基本又答不出來,我在Github上逛了3天,找到了這份沒被挖掘的寶藏Python面試題!https://github.com/jackfrued/Python-Interview-Bible例如讓你寫一個刪除列表中重複元素的函數,要求去重後元素相對位置保持不變。你用Python會怎麼寫?
def dedup(items):
no_dup_items = []
seen = set()
for item in items:
if item not in seen:
no_dup_items.append(item)
seen.add(item)
return no_dup_items
甚至幫你想辦法進一步優化,例如改寫成為一個生成器:
def dedup(items):
seen = set()
for item in items:
if item not in seen:
yield item
seen.add(item)
作者提到這個面試時經常出現,並給出了以下拓展學習內容擴展:由於Python中的集合底層使用哈希存儲,所以集合的in和not in成員運算在性能上遠遠優於列表,所以上面的代碼我們使用了集合來保存已經出現過的元素。集合中的元素必須是hashable對象,因此上面的代碼在列表元素不是hashable對象時會失效,要解決這個問題可以給函數增加一個參數,該參數可以設計為返回哈希碼或hashable對象的函數。
def multiply():
return [lambda x: i * x for i in range(4)]
print([m(100) for m in multiply()])
上面代碼的運行結果很容易被誤判為[0, 100, 200, 300]。首先需要注意的是multiply函數用生成式語法返回了一個列表,列表中保存了4個Lambda函數,這4個Lambda函數會返回傳入的參數乘以i的結果。需要注意的是這裡有閉包(closure)現象,multiply函數中的局部變量i的生命周期被延展了,由於i最終的值是3,所以通過m(100)調列表中的Lambda函數時會返回300,而且4個調用都是如此。如果想得到[0, 100, 200, 300]這個結果,可以按照下面幾種方式來修改multiply函數。
def multiply():
return (lambda x: i * x for i in range(4))
print([m(100) for m in multiply()])
def multiply():
for i in range(4):
yield lambda x: x * i
print([m(100) for m in multiply()])
from functools import partial
from operator import __mul__
def multiply():
return [partial(__mul__, i) for i in range(4)]
print([m(100) for m in multiply()])
現有2元、3元、5元共三種面額的貨幣,如果需要找零99元,一共有多少種找零的方式?其實還有一個非常類似的題目:「一個小朋友走樓梯,一次可以走1個臺階、2個臺階或3個臺階,問走完10個臺階一共有多少種走法?」,這兩個題目的思路是一樣,如果用遞歸函數來寫的話非常簡單。
from functools import lru_cache
@lru_cache()
def change_money(total):
if total == 0:
return 1
if total < 0:
return 0
return change_money(total - 2) + change_money(total - 3) + \
change_money(total - 5)
說明:在上面的代碼中,我們用lru_cache裝飾器裝飾了遞歸函數change_money,如果不做這個優化,上面代碼的漸近時間複雜度將會是$O(3^N)$,而如果參數total的值是99,這個運算量是非常巨大的。lru_cache裝飾器會緩存函數的執行結果,這樣就可以減少重複運算所造成的開銷,這是空間換時間的策略,也是動態規劃的編程思想。
其實,還有很多好的面試題都在這個面試寶典中,例如:說說Python中的淺拷貝和深拷貝。Lambda函數是什麼,舉例說明的它的應用場景。不使用中間變量,交換兩個變量a和b的值。在Python中如何實現單例模式。Python是如何實現內存管理的?說一下你對Python中迭代器和生成器的理解。正則表達式的match方法和search方法有什麼區別?用Python代碼實現Python內置函數max。Python中為什麼沒有函數重載?使用Python代碼實現遍歷一個文件夾的操作。__init__和__new__方法有什麼區別?輸入年月日,判斷這個日期是這一年的第幾天。平常工作中用什麼工具進行靜態代碼分析。上面的問題你都會了麼?建議大家趕緊去看看,不會的學起來,不僅筆試面試會用上,平時優化代碼秀操作也是必備啊!
重磅!Python交流群已成立
為了給小夥伴們提供一個互相交流的技術平臺,特地開通了Python交流群。群裡有不少技術大神,不時會分享一些技術要點,更有一些資源收藏愛好者不時分享一些優質的學習資料。(免費,不賣課!)
▲長按掃碼