來源:http://suo.im/5GezbF
前言
花費了整整3天時間整理出來的全網最實用Python面試題大全,一共30道題目+答案的純幹貨,如此的辛勤整理,希望大家多多支援,建議點贊+收藏!
上次那篇《Python基礎文法全解!2.6萬字,38張圖!》已經110個贊了,感謝大家的支援。看看今天這篇能不能達到100贊,哈哈~
長文警告,全文共12000+字,涵蓋Python面試可能遇到的所有問題,希望對大家有幫助,不過大家最好不要硬背,實戰大于理論。祝大家面試順利!
1、談談對 Python 和其他語言的差別?
答:Python 是一門文法簡潔優美,功能強大無比,應用領域非常廣泛,具有強大完備的第三方庫,他是一門強類型的可移植、可擴充,可嵌入的解釋型程式設計語言,屬于動态語言。
- 和Java相比:Python比Java要簡單.Python是函數為一等公民的語言,而Java是類為一等公民的語言.Python是弱類型語言,而Java是強類型語言。
- 和C相比:對于使用:Python的類庫齊全并且使用簡潔,很少代碼實作的功能用C可能要很複雜。對于速度:Python的運作速度相較于C,絕對是很慢了.Python和CPython解釋器都是C語言編寫。
2、談談Python 的特點和優點是什麼?
答:Python 是一門動态解釋性的強類型定義語言:編寫時無需定義變量類型;運作時變量類型強制固定;無需編譯,在解釋器環境直接運作。
- 解釋性:一個用編譯型語言(如 C 或 C++)寫的程式,可以從源檔案轉換到一個計算機使用的語言。這個過程主要通過編譯器完成。當運作程式的時候,我們可以把程式從硬碟複制到記憶體中并且運作。而 Python 語言寫的程式,則不需要編譯成二進制代碼,可以直接從源代碼運作程式。在計算機内部,由 Python 解釋器把源代碼轉換成位元組碼的中間形式,然後再把它翻譯成計算機使用的機器語言并運作。
- 動态性:在運作時可以改變其結構的語言 :例如新的函數、對象、甚至代碼可以被引進,已有的函數可以被删除或是其他結構上的變化。動态語言目前非常具有活力。Python便是一個動态語言,除此之外如 PHP 、 Ruby 、 JavaScript 等也都屬于動态語言 。
- 面向對象:面向對象程式設計簡單來說就是基于對 類 和 對象 的使用,所有的代碼都是通過類和對象來實作的程式設計就是面向對象程式設計!面向對象的三大特性:封裝、繼承、多态
- 文法簡潔:Python 是一種代表簡單注意思想的語言,閱讀一個良好的 Python 程式,即使是在 Python 文法要求非常嚴格的大環境下,給人的感覺也像是在讀英語段落一樣。換句話說,Python 程式設計語言最大的優點之一,是其具有僞代碼的特質,它可以讓我們在開發 Python 程式時,專注于解決問題,而不是搞明白語言本身。
- 開源:Python 是開源的,簡單地了解就是,使用者使用 Python 進行開發和釋出自己編寫的程式,不需要支付任何費用,也不用擔心版權問題,即使作為商業用途,Python 也是免費的。開源正在成為軟體行業的一種發展趨勢,現在有很多商業軟體公司都開始将自己的産品變成開源的(例如 Java)。也許,Python 的開源正是它如此優秀的原因之一,因為會有這麼一群人,他們希望看到一個更加優秀的 Python,進而為了這個目标,不斷地對 Python 進行創造,不斷地改進。
- 可擴充性:Python 的可擴充性展現為它的子產品,Python 具有腳本語言中最豐富和強大的類庫,這些類庫覆寫了檔案 I/O、GUI、網絡程式設計、資料庫通路、文本操作等絕大部分應用場景。
3、說說Python解釋器種類以及特點?
答:Python是一門解釋器語言,代碼想運作,必須通過解釋器執行,Python存在多種解釋器,分别基于不同語言開發,每個解釋器有不同的特點,但都能正常運作Python代碼。
Python解釋器主要有以下幾個:
- CPython:官方版本的解釋器:CPython。這個解釋器是用C語言開發的,是以叫CPython。在指令行下運作python就是啟動CPython解釋器。CPython是使用最廣且被的Python解釋器。
- IPython:IPython是基于CPython之上的一個互動式解釋器,也就是說,IPython隻是在互動方式上有所增強,但是執行Python代碼的功能和CPython是完全一樣的。CPython用>>>作為提示符,而IPython用In [序号]:作為提示符。
- PyPy:PyPy是另一個Python解釋器,它的目标是執行速度。PyPy采用JIT技術,對Python代碼進行動态編譯(注意不是解釋),是以可以顯著提高Python代碼的執行速度。
- 絕大部分Python代碼都可以在PyPy下運作,但是PyPy和CPython有一些是不同的,這就導緻相同的Python代碼在兩種解釋器下執行可能會有不同的結果。如果你的代碼要放到PyPy下執行,就需要了解PyPy和CPython的不同點。
- Jython:Jython是運作在Java平台上的Python解釋器,可以直接把Python代碼編譯成Java位元組碼執行。
- IronPython:IronPython和Jython類似,隻不過IronPython是運作在微軟.Net平台上的Python解釋器,可以直接把Python代碼編譯成.Net的位元組碼。
在這些Python解釋器中,使用廣泛的是CPython 。
4、說說Python面向對象三大特性?
答:Python是一門面向對象的語言。面向對象都有三大特性:封裝、繼承、多态。
下面分别來說說這三大特性:
- 封裝:隐藏對象的屬性和實作細節,僅對外提供公共通路方式。在python中用雙下劃線開頭的方式将屬性設定成私有的 。好處:1. 将變化隔離;2. 便于使用;3. 提高複用性;4. 提高安全性。
- 繼承:繼承是一種建立新類的方式,在python中,建立的類可以繼承一個或多個父類,父類又可稱為基類或超類,建立的類稱為派生類或子類。即一個派生類繼承基類的字段和方法。繼承也允許把一個派生類的對象作為一個基類對象對待。例如,有這樣一個設計:一個Dog類型的對象派生自Animal類,這是模拟"是一個(is-a)"關系 。
python中類的繼承分為:單繼承和多繼承
class ParentClass1: #定義父類class ParentClass2: #定義父類class SubClass1(ParentClass1): #單繼承,基類是ParentClass1,派生類是SubClassclass SubClass2(ParentClass1,ParentClass2): #python支援多繼承,用逗号分隔開多個繼承的類
- 多态:一種事物的多種展現形式,函數的重寫其實就是多态的一種展現 。Python中,多态指的是父類的引用指向子類的對象 。
- 實作多态的步驟:1、定義新的子類,2、重寫對應的父類方法,3、使用子類的方法直接處理,不調用父類的方法。多态的好處:(1)增加了程式的靈活性(2)增加了程式可擴充性
5、說說 Python 中有幾種資料類型?
答:Python 中主要有8種資料類型:number(數字)、string(字元串)、list(清單)、tuple(元組)、dict(字典)、set(集合)、Boolean(布爾值)、None(空值)。
6、說說Python中xrange和range的差別?
答:range()和xrange()都是在循環中使用,輸出結果一樣。
- range()傳回的是一個list對象,而xrange傳回的是一個生成器對象(xrange object)。
- xrange()則不會直接生成一個list,而是每次調用傳回其中的一個值,記憶體空間使用極少。因而性能非常好,是以盡量用xrange吧。
在python3 中沒有xrange,隻有range。range和python2 中的xrange()一樣。
7、Python變量、函數、類的命名規則?
答:
- (1)不能以數字開頭,不能出現中文。
- (2)命名以字母開頭,包含數字,字母(區分大小寫),下劃線。
- (3)不能包含關鍵字,見名知意。
8、說說Python可變與不可變資料類型的差別?
答:Python中看可變與不可變資料類型,主要是看變量所指向的記憶體位址處的值是否會改變 。Python 的六種标準資料類型:數字、字元串、清單、元組、字典、集合。
- 不可變資料(3個):Number(數字)、String(字元串)、Tuple(元組)。
- 可變資料(3個):List(清單)、Dictionary(字典)、Set(集合)。
9、列舉幾個Python中的标準異常類?
10、說說Python中疊代器和生成器的差別?
答:Python中生成器能做到疊代器能做的所有事,而且因為自動建立了__iter__()和next()方法,生成器顯得特别簡潔,而且生成器也是高效的,使用生成器表達式取代清單解析,同時節省記憶體。除了建立和保持程式狀态的自動生成,當發生器終結時,還會自動跑出StopIterration異常。
- 清單、元組、字典、字元串都是可疊代對象。
- 數字、布爾值都是不可疊代的。
11、說說Python字典以及基本操作?
答:字典是 Python 提供的一種常用的資料結構,主要用于存放具有映射關系的資料 。比如儲存某班同學的成績單資料,張三:95分,李四:70分,王五:100分 ... ,因為姓名和成績是有關聯的,是以不能單獨用兩個清單來分别儲存,這時候用字典來存儲,再合适不過了 。
字典是一種可變的容器模型,它是通過一組鍵(key)值(value)對組成,這種結構類型通常也被稱為映射,或者叫關聯數組,也有叫哈希表的。每個key-value之間用“:”隔開,每組用“,”分割,整個字典用“{}”括起來 ,格式如下所示:
dictionary = {key1 : value1, key2 : value2 }
定義字典時,鍵前值後,鍵必須唯一性,值可以不唯一,如果鍵有相同,值則取最後一個;
值可以是任何的資料類型,但是鍵必須是不可變的資料類型(數字、字元串、元組)。想要通路字典中的值,隻需要将鍵放入方括号裡,如果用字典裡沒有的鍵通路資料,會輸出錯誤 。
12、說說Python種有幾種字元串格式化?
答:Python字元串格式化主要有兩種方式:分别為占位符(%)和format方式 。文末還有2種要介紹,是以總共有4種 。
其中,占位符(%)方式比較老,而format方式是比較先進的,目前兩者共存。占位符方式在Python2.x中用的比較廣泛,随着Python3.x的使用越來越廣,format方式使用的更加廣泛。
13、說說Python多線程與多程序的差別?
- 1、多線程可以共享全局變量,多程序不能
- 2、多線程中,所有子線程的程序号相同;多程序中,不同的子程序程序号不同
- 3、線程共享記憶體空間;程序的記憶體是獨立的
- 4、同一個程序的線程之間可以直接交流;兩個程序想通信,必須通過一個中間代理來實作
- 5、建立新線程很簡單;建立新程序需要對其父程序進行一次克隆
- 6、一個線程可以控制和操作同一程序裡的其他線程;但是程序隻能操作子程序
兩者最大的不同在于:在多程序中,同一個變量,各自有一份拷貝存在于每個程序中,互不影響;而多線程中,所有變量都由所有線程共享 。
14、說說Python中HTTP常見響應狀态碼?
答:http協定是超文本傳輸協定,是用于從網際網路伺服器傳輸文本到本地浏覽器的傳送協定,是基于tcp/ip通信協定來傳輸資料的。
HTTP狀态碼(HTTP Status Code)是用以表示網頁伺服器超文本傳輸協定響應狀态的3位數字代碼。它由 RFC 2616 規範定義的,并得到 RFC 2518、RFC 2817、RFC 2295、RFC 2774 與 RFC 4918 等規範擴充。所有狀态碼的第一個數字代表了響應的五種狀态之一。
15、說說Python中猴子更新檔是什麼?
答:在Ruby、Python等動态程式設計語言中,猴子更新檔僅指在運作時動态改變類或子產品,為的是将第三方代碼打更新檔在不按預期運作的bug或者feature上 。在運作時動态修改子產品、類或函數,通常是添加功能或修正缺陷。猴子更新檔在代碼運作時記憶體中發揮作用,不會修改源碼,是以隻對目前運作的程式執行個體有效。因為猴子更新檔破壞了封裝,而且容易導緻程式與更新檔代碼的實作細節緊密耦合,是以被視為臨時的變通方案,不是內建代碼的推薦方式。
16、說說Python中的垃圾回收機制?
答:垃圾回收機制(Garbage Collection:GC)基本是所有進階語言的标準配置之一了,在一定程度上,能優化程式設計語言的資料處理效率和提高程式設計軟體開發軟體的安全性能 。在python中的垃圾回收機制主要是以引用計數為主要手段以标記清除和隔代回收機制為輔的手段 。可以對記憶體中無效資料的自動管理!
17、說說Python中有幾種辦法交換兩個變量的值?
答:交換兩個變量的值方法,這個面試題如果隻寫一種當然很簡單,沒什麼可以說的。今天這個面試是問大家有幾種辦法來實作交換兩個變量的值 。
方法一:通過新添加中間變量temp的方式,這個方法是最簡單的,每個語言都适用。
def swap(a,b): temp = a a = b b = temp print(a,b)
方法二:Python獨有的方法,一行代碼就能搞定,直接将兩個變量放到元組中 。
def swap2(a,b): a,b = b,a print(a,b)
方法三:這個方法,是不是很少人想到了,采用加減法來交換 。我們不考慮效率,能達到交換的效果就行 。
def swap3(a, b): a = a + b b = a - b a = a - b print(a, b)
方法四:采用異或運算,這個是不是看起來比較高大上。通過按位異或運算來交換兩變量的值,可以減少變量的定義,同時減少計算機對代碼的解析時間。按位異或運算即計算機會先把十進制數轉化為二進制數,并對二進制數進行從右到左用從1開始編數,然後比較兩個二進制數值相同位置的數,如果相同結果為0,不同時結果為1 。"1^1=0 1^0=1 0^0=0"
如:1010
1111
則結果為 0101
def swap4(a,b): a = a ^ b b = a ^ b a = a ^ b print(a,b)
18、說說Python中的6種位運算符?
答:在Python中,按位運算符有左移運算符(<>)、按位與運算(&)、按位或運算(|)、按位取反運算(~)、異或運算符,其中按位取反運算符為單目運算符 。
19、說說Python中的類型轉換有哪些?
答:在Python處理資料時,不可避免的要使用資料類型之間的轉換。簡單的諸如int、float、string之間的轉換;更有數組array、清單list之間的轉換。
以下是幾個内置的函數可以執行資料類型之間的轉換。這些函數傳回一個新的對象,表示轉換的值。
20、Python中實作二分查找的2種方法?
答:在Python實作二分查找法有兩種方法,分别用循環和遞歸方式。
二分查找法:搜尋過程從數組的中間元素開始,如果中間元素正好是要查找的元素,則搜尋過程結束;如果某一特定元素大于或者小于中間元素,則在數組大于或小于中間元素的那一半中查找,而且跟開始一樣從中間元素開始比較。如果在某一步驟數組為空,則代表找不到。這種搜尋算法每一次比較都使搜尋範圍縮小一半。注意如果要想使用二分查找,前提必須是元素有序排列 。
循環方式
def binary_search_2(alist,item): """二分查找---循環版本""" n = len(alist) first = 0 last = n-1 while first <= last: mid = (first + last)//2 if alist[mid] ==item: return True elif item < alist[mid]: last = mid - 1 else: first = mid + 1 return Falseif __name__ == "__main__": a = [1,5,6,10,11,13,18,37,99] sorted_list_21 = binary_search_2(a, 18) print(sorted_list_21) //True sorted_list_22 = binary_search_2(a, 77) print(sorted_list_22) //False
遞歸方式
def binary_search(alist,item): """二分查找---遞歸實作""" n = len(alist) if n > 0: mid = n//2 #數組長度的一半中間下标 if item == alist[mid] : return True #查找成功 elif item < alist[mid]: return binary_search(alist[:mid],item) else: return binary_search(alist[mid+1:], item) else : return False #失敗if __name__ == "__main__": a = [1,5,6,10,11,13,18,37,99] # print(a) sorted_list_11 = binary_search(a,37) print(sorted_list_11)//True sorted_list_12= binary_search(a, 88) print(sorted_list_12)//False
21、說說Python中的lambda表達式?
答:在Python中lambda表達式也叫匿名函數,即函數沒有具體的名稱。lambda表達式是Python中一類特殊的定義函數的形式,使用它可以定義一個匿名函數。與其它語言不同,Python的lambda表達式的函數體隻能有單獨的一條語句,也就是傳回值表達式語句。
lambda表達式,通常是在需要一個函數,但是又不想費神去命名一個函數的場合下使用 。lambda所表示的匿名函數的内容應該是很簡單的,如果複雜的話,就重新定義一個函數了。lambda 表達式允許在一行代碼中建立一個函數并傳遞。
lambda表達式在Python中的優點和缺點: 一方面,Lambda函數的減少了代碼的行數,友善又簡潔。另一方面,Lambda表達式有諸多限制,不能使用複雜邏輯。
add = lambda x, y : x+ynum =add(1,2)print("x+y=",num)# 結果為:x+y=3
22、說說Python中的反射?
答:在反射機制就是在運作時,動态的确定對象的類型,并可以通過字元串調用對象屬性、方法、導入子產品,是一種基于字元串的事件驅動。通過字元串的形式,去子產品尋找指定函數,并執行。利用字元串的形式去對象(子產品)中操作(查找/擷取/删除/添加)成員。
Python是一門解釋型語言,是以對于反射機制支援很好。在Python中支援反射機制的函數有getattr()、setattr()、delattr()、exec()、eval()、__import__,這些函數都可以執行字元串。
23、說說Python删除list裡的重複元素有幾種方法?
答:在Python中主要有5種方式,還沒看答案,你能想起幾種呢,面試筆試題經常碰到的一道題 。
使用set函數:set是定義集合的,無序,非重複
numList = [1,1,2,3,4,5,4]print(list(set(numList)))#[1, 2, 3, 4, 5]
先把list重新排序,然後從list的最後開始掃描
a = [1, 2, 4, 2, 4, 5,]a.sort()last = a[-1]for i in range(len(a) - 2, -1, -1): if last == a[i]: del a[i] else: last = a[i]print(a) #[1, 2, 4, 5]
使用字典函數
a=[1,2,4,2,4,]b={}b=b.fromkeys(a)c=list(b.keys())print(c) #[1, 2, 4]
append方式
def delList(L): L1 = [] for i in L: if i not in L1: L1.append(i) return L1print(delList([1, 2, 2, 3, 3, 4, 5])) #[1, 2, 3, 4, 5]
count + remove方式
def delList(L): for i in L: if L.count(i) != 1: for x in range((L.count(i) - 1)): L.remove(i) return Lprint(delList([1, 2, 2, 3, 3, 4]))#[1, 2, 3, 4]
24、說說Python中的__new__和__init__的差別?
答:在Python中__new__和__init__具有不同的功能。并且對于Python的新類和舊類而言功能也不同。
- __new__是在執行個體建立之前被調用的,因為它的任務就是建立執行個體然後傳回該執行個體對象,是個靜态方法。
- __init__是當執行個體對象建立完成後被調用的,然後設定對象屬性的一些初始值,通常用在初始化一個類執行個體的時候。是一個執行個體方法。
- 主要差別在于:__new__是用來創造一個類的執行個體的,而__init__是用來初始化一個執行個體的。
25、說說Python中的help()和dir()函數?
答:在Python中help()和dir()這兩個函數都可以從Python解釋器直接通路,并用于檢視内置函數的合并轉儲。
- help()函數:help()函數用于顯示文檔字元串,還可以檢視與子產品,關鍵字,屬性等相關的使用資訊。
- dir()函數:dir()函數可以列出指定類或子產品包含的全部内容(包括函數、方法、類、變量等)
26、說說提高Python運作效率的技巧?
答:不喜歡Python的人經常會吐嘈Python運作太慢。下面給大家介紹幾種種提高python執行效率的方法 。
- 使用局部變量:盡量使用局部變量代替全局變量:便于維護,提高性能并節省記憶體。一方面可以提高程式性能,局部變量查找速度更快;另一方面可用簡短辨別符替代冗長的子產品變量,提高可讀性。
- 使用較新的Python版本:Python已經更新了很多個版本,每個版本的Python都會包含優化内容,使其運作速度優于之前的版本,是以大家記得經常更新版本哦!
- 先編譯後調用:使用eval()、exec()函數執行代碼時,最好調用代碼對象(提前通過compile()函數編譯成位元組碼),而不是直接調用str,可以避免多次執行重複編譯過程,提高程式性能。正規表達式模式比對也類似,也最好先将正規表達式模式編譯成regex對象(通過re.complie()函數),然後再執行比較和比對。
- 采用生成器表達式替代清單解析:清單解析會産生整個清單,對大量資料的疊代會産生負面效應。而生成器表達式則不會,其不會真正建立清單,而是傳回一個生成器,在需要時産生一個值(延遲計算),對記憶體更加友好。
- 關鍵代碼使用外部功能包:使用 C/C++ 或機器語言的外部功能包處理時間敏感任務,可以有效提高應用的運作效率。這些功能包往往依附于特定的平台,是以你要根據自己所用的平台選擇合适的功能包 。比如下面四個功能包:Cython、Pylnlne、PyPy、Pyrex 。
- 在排序時使用鍵:Python 含有許多古老的排序規則,這些規則在你建立定制的排序方法時會占用很多時間,而這些排序方法運作時也會拖延程式實際的運作速度。最佳的排序方法其實是盡可能多地使用鍵和内置的 sort() 方法。
- 優化算法時間:算法的時間複雜度對程式的執行效率影響最大,在Python中可以通過選擇合适的資料結構來優化時間複雜度,如list和set查找某一個元素的時間複雜度分别是O(n)和O(1)。不同的場景有不同的優化方式,總得來說,一般有分治,分支界限,貪心,動态規劃等思想。
- 循環優化“每種程式設計語言都會強調需要優化循環。當使用Python的時候,你可以依靠大量的技巧使得循環運作得更快。
- 技巧 1:減少循環内部不必要的計算
- 技巧 2:嵌套循環中,盡量減少内層循環的計算
- 技巧 3:盡量使用局部變量
- 技巧 4:使用 join() 連接配接字元串
- 交叉編譯你的應用:計算機其實并不了解用來建立現代應用程式的程式設計語言,計算機了解的是機器語言。是以我們可以用Python語言編寫應用,再以C++這樣的語言運作你的應用,這在運作的角度來說,是可行的。Nuitka是一款有趣的交叉編譯器,能将你的Python代碼轉化成C++代碼。這樣,你就可以在native模式下執行自己的應用,而無需依賴于解釋器程式。你會發現自己的應用運作效率有了較大的提高,但是這會因平台和任務的差異而有所不同。
27、Python中的單例模式有幾種實作方式?
答:單例模式(Singleton Pattern)是一種常用的軟體設計模式,該模式的主要目的是確定某一個類隻有一個執行個體存在。在 Python 中,你可以想出幾種種方法來實作單例模式呢?筆試題中,手寫單例模式,也是經常碰到的,是以都要掌握下!
1)使用子產品實作:Python 的子產品就是天然的單例模式,因為子產品在第一次導入時,會生成 .pyc 檔案,當第二次導入時,就會直接加載 .pyc 檔案,而不會再次執行子產品代碼。是以,我們隻需把相關的函數和資料定義在一個子產品中,就可以獲得一個單例對象了。如果我們真的想要一個單例類,可以考慮這樣做:
#test1.pyclass Singleton(object): def foo(self): passsingleton = Singleton()#test2.pyfrom test1 import singleton
2)用__new__特殊方法實作
class Singleton: def __new__(cls, *args, **kwargs): if not hasattr(cls, '_instance'): cls._instance = super(Singleton, cls).__new__(cls) return cls._instance def __init__(self, name): self.name = names1 = Singleton('IT圈')s2= Singleton('程式IT圈')print(s1 == s2) # True
3)使用裝飾器實作
def singleton(cls): _instance = {} def inner(*args, **kwargs): if cls not in _instance: _instance[cls] = cls(*args, **kwargs) return _instance[cls] return [email protected] Singleton: def __init__(self, name): self.name = names1 = Singleton('IT圈')s2= Singleton('程式IT圈')print(s1 == s2) # True
4)類裝飾器實作
class Singleton: def __init__(self, cls): self._cls = cls self._instance = {} def __call__(self, *args): if self._cls not in self._instance: self._instance[self._cls] = self._cls(*args) return self._instance[self._cls]@Singletonclass Singleton: def __init__(self, name): self.name = names1 = Singleton('IT圈')s2= Singleton('程式IT圈')print(s1 == s2) # True
5)使用元類實作方式
class Singleton1(type): def __init__(self, *args, **kwargs): self.__instance = None super(Singleton1, self).__init__(*args, **kwargs) def __call__(self, *args, **kwargs): if self.__instance is None: self.__instance = super(Singleton1, self).__call__(*args, **kwargs) return self.__instanceclass Singleton(metaclass=Singleton1): def __init__(self, name): self.name = names1 = Singleton('IT圈')s2= Singleton('程式IT圈')print(s1 == s2) # True
28、Python實作自省的方法有哪些?
答:自省是一種自我檢查行為。在計算機程式設計中,自省是指這種能力:檢查某些事物以确定它是什麼、它知道什麼以及它能做什麼。自省向程式員提供了極大的靈活性和控制力。
說的更簡單直白一點:自省就是面向對象的語言所寫的程式在運作時,能夠知道對象的類型。一句可以概況為:運作時能夠獲知對象的類型。
Python實作自省有很多方法,常用的有
- type(),判斷對象類型
- dir(), 帶參數時獲得該對象的所有屬性和方法;不帶參數時,傳回目前範圍内的變量、方法和定義的類型清單
- help() , 用于檢視函數或子產品用途的詳細說明
- isinstance(),判斷對象是否是已知類型
- issubclass(),判斷一個類是不是另一個類的子類
- hasattr(),判斷對象是否包含對應屬性
- getattr(),擷取對象屬性
- setattr(), 設定對象屬性
- id(): 用于擷取對象的記憶體位址
- callable():判斷對象是否可以被調用。
29、簡述一下爬蟲的步驟?
- 确定需求;
- 确定資源;
- 通過url擷取網站的傳回資料;
- 定位資料;
- 存儲資料。
30、遇到的反爬蟲政策以及解決方法?
- 通過headers反爬蟲:自定義headers,添加網頁中的headers資料。
- 基于使用者行為的反爬蟲(封IP):可以使用多個代理IP爬取或者将爬取的頻率降低。
- 動态網頁反爬蟲(JS或者Ajax請求資料):動态網頁可以使用 selenium + phantomjs 抓取。
- 對部分資料加密處理(資料亂碼):找到加密方法進行逆向推理。
常見的反爬蟲和應對方法有:
- 基于使用者行為,同一個ip段時間多次通路同一頁面 利用代理ip,建構ip池
- 請求頭裡的user-agent 建構user-agent池(作業系統、浏覽器不同,模拟不同使用者)
- 動态加載(抓到的資料和浏覽器顯示的不一樣),js渲染 模拟ajax請求,傳回json形式的資料
- selenium / webdriver 模拟浏覽器加載
- 對抓到的資料進行分析
- 加密參數字段 會話跟蹤【cookie】 防盜鍊設定【Referer】
以後遇到更多的問題會加更,祝大家面試順利!共勉~
如果本文對你有幫助的話記得點個贊或者在看哈~
END