搞定這套Python爬蟲面試題,面試會so easy
先來一份完整的爬蟲工程師面試考點:

image
一、 Python 基本功
1、簡述Python 的特點和優點
Python 是一門開源的解釋性語言,相比 Java C++ 等語言,Python 具有動態特性,非常靈活。
2、Python 有哪些資料型別?
Python 有 6 種內建的資料型別,其中不可變資料型別是Number(數字), String(字串), Tuple(元組),可變資料型別是 List(列表),Dict(字典),Set(集合)。
3、列表和元組的區別
列表和元組都是可迭代物件,能夠對其進行迴圈、切片等,但元組 tuple 是不可變的。元組不可變的特性,使得它可以成為字典 Dict 中的鍵。
Python學習群:556370268,有大牛答疑,有資源共享!是一個非常不錯的交流基地!歡迎喜歡Python的小夥伴!
4、Python 是如何執行的
CPython:
Python 程式執行時,會先進行編譯,將 .py 檔案中的程式碼編譯成位元組碼(byte code),編譯結果儲存在記憶體的 PyCodeObject 中,然後由 Python 虛擬機器解釋執行。當程式執行結束後,Python 直譯器會將 PyCodeObject 儲存到 pyc 檔案中。每一次執行時 Python 都會先尋找與檔案同名的 pyc 檔案,如果 pyc 存在則比對修改記錄,根據修改記錄決定直接執行或再次編譯後執行,最後生成 pyc 檔案 。
5、Python 執行速度慢的原因
a). Python 不是強型別的語言,所以直譯器執行時遇到變數以及資料型別轉換、比較操作、引用變數時都需要檢查其資料型別。
b). Python 的編譯器啟動速度比 JAVA 快,但幾乎每次都要啟動編譯。
c). Python 的物件模型會導致訪問記憶體效率變低。Numpy 的指標指向快取區資料的值,而 Python 的指標指向快取物件,再通過快取物件指向資料:

image
6、面對 Python 慢的問題,有什麼解決辦法
a). 可以使用其他的直譯器,比如 PyPy 和 Jython 等。
b). 如果對效能要求較高且靜態型別變數較多的應用程式,可以使用 CPython。
c). 對於 IO 操作多的應用程式,Python 提供 asyncio 模組提高非同步能力。
7、描述一下全域性直譯器鎖 GIL
每個執行緒在執行時候都需要先獲取 GIL,保證同一時刻只有一個執行緒可以執行程式碼,即同一時刻只有一個執行緒使用 CPU,也就是說多執行緒並不是真正意義上的同時執行。但是在 IO 操作時,是可以釋放鎖的(這也是 Python 能夠非同步的原因)。而且如果想要利用多核 CPU,那麼可以使用多程序。
8、深拷貝 淺拷貝
深拷貝是將物件本身複製給另一個物件,淺拷貝則是將物件的引用複製給另一個物件。所以當複製後的物件改變時,深拷貝的原物件值不會改變,而淺拷貝原物件的值會被改變。
9、is 和 == 的區別
is 表示的是物件標示符(object identity),而 == 表示的是相等(equality)。
is 的作用是用來檢查物件的標示符是否一致,也就是比較兩個物件在記憶體中的地址是否一樣,而 == 是用來檢查兩個物件是否相等。但是為了提高系統性能,對於較小的字串 Python 會保留其值的一個副本,當建立新的字串的時候直接指向該副本即可。如:
a = 8 b = 8 a is b
10、檔案讀寫
簡述檔案讀取時 read 、readline、readlines 的區別和作用
他們的區別除了讀取內容範圍不同外,返回的內容型別也不同。
read()會讀取整個檔案,將讀取到底的檔案內容放到一個字串變數,返回 str 型別。
readline()讀取一行內容,放到一個字串變數,返回 str 型別。
readlines() 讀取檔案所有內容,按行為單位放到一個列表中,返回 list 型別。
11、請用一行程式碼實現
請分別使用匿名函式和推導式這兩種方式將 [0, 1, 2, 3, 4, 5] 中的元素求乘積,並列印輸出元組。
print(tuple(map(lambda x: x * x, [0, 1, 2, 3, 4, 5]))) print(tuple(i*i for i in [0, 1, 2, 3, 4, 5]))
12、請用一行程式碼實現
用 reduce 計算 n 的階乘(n!=1×2×3×...×n)
print(reduce(lambda x, y: x*y, range(1, n)))
13、請用一行程式碼實現
篩選並列印輸出 100 以內能被 3 整除的數的集合
print(set(filter(lambda n: n % 3 == 0, range(1, 100))))
14、請用一行程式碼實現
text = 'Obj{"Name": "pic", "data": [{"name": "async", "number": 9, "price": "$3500"}, {"name": "Wade", "number": 3, "price": "$5500"}], "Team": "Hot"'
列印文字中的球員身價元組,如 (
5500)
print(tuple(i.get("price") for i in json.loads(re.search(r'[(.*)]', text).group(0))))
15、請寫出遞迴的基本骨架
def recursions(n): if n == 1: # 退出條件 return 1 # 繼續遞迴 return n * recursions(n - 1)
16、切片
請寫出下方輸出結果
tpl = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95] print(tpl[3:]) print(tpl[:3]) print(tpl[::5]) print(tpl[-3]) print(tpl[3]) print(tpl[::-5]) print(tpl[:]) del tpl[3:] print(tpl) print(tpl.pop()) tpl.insert(3, 3) print(tpl) [15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95] [0, 5, 10] [0, 25, 50, 75] 85 15 [95, 70, 45, 20] [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95] [0, 5, 10] 10 [0, 5, 3]
17、檔案路徑
列印輸出當前檔案所在目錄路徑
import os print(os.path.dirname(os.path.abspath(__file__)))
列印輸出當前檔案路徑
import os print(os.path.abspath(__file__))
列印輸出當前檔案上兩層檔案目錄路徑
import os print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
18、請寫出執行結果,並回答問題
tpl = (1, 2, 3, 4, 5) apl = (6, 7, 8, 9) print(tpl.__add__(apl))
問題:tpl 的值發生變化了嗎?
執行結果如下:
(1, 2, 3, 4, 5, 6, 7, 8, 9)
答:元組是不可變的,它是生成新的物件
19、請寫出執行結果,並回答問題
name = ('James', 'Wade', 'Kobe') team = ['A', 'B', 'C'] tpl = {name: team} print(tpl) apl = {team: name} print(apl)
問題:這段程式碼能執行完畢嗎?為什麼?它的執行結果是?
答:這段程式碼不能完整執行,它會在 apl 處丟擲異常,因為字典的鍵只能是不可變物件,而 list 是可變的,所以不能作為字典的鍵。執行結果是:
{('James', 'Wade', 'Kobe'): ['A', 'B', 'C']} TypeError
20、裝飾器
請寫出裝飾器程式碼骨架
def log(func): def wrapper(*args, **kw): print('call %s():' % func.__name__) return func(*args, **kw) return wrapper
簡述裝飾器在 Python 中的作用:
在不改動原函式程式碼的情況下,為其增加新的功能。
Python學習群:556370268,有大牛答疑,有資源共享!是一個非常不錯的交流基地!歡迎喜歡Python的小夥伴!
21、多程序 多執行緒
多程序更穩定還是多執行緒更穩定?為什麼?
多程序更穩定,它們是獨立執行的,不會因為一個崩潰而影響其他程序。
多執行緒的致命缺點是什麼?
因為所有執行緒共享程序的記憶體,所以任何一個執行緒掛掉都可能直接造成整個程序崩潰。
程序間通訊有哪些方式?
共享變數、佇列、管道。