面試妥了!2020 爬蟲面試題目合集

2021-02-15 CSDN


作者 | 不願透露姓名の網友

出品 | CSDN博客

介紹爬蟲

1.爬蟲:自動的抓取網際網路上信息的腳本文件。

2.爬蟲可以解決的問題:

(1)解決冷啟動問題

(2)搜尋引擎的根基:做搜尋引擎少不了爬蟲

(3)建立知識圖譜,幫助建立機器學習知識圖譜

(4)可以製作各種商品的比價軟體,趨勢分析。

3.爬蟲分類

(1)通用爬蟲:搜尋引擎的主要組成,作用就是將網際網路的上頁面整體的爬取下來之後,保存到本地。

(2)聚焦爬蟲:聚焦爬蟲在實施網頁抓取時會對內容進行處理篩選,儘量保證只抓取與需求相關的網頁信息。

通用爬蟲和聚焦爬蟲的區別:聚焦爬蟲在實施網頁抓取時會對內容進行處理篩選,儘量保證只抓取與需求相關的網頁信息。

4.爬蟲遵循的協議:robot協議

定義:網絡爬蟲排除標準。

作用:告訴搜尋引擎哪裡可以爬,哪裡不可以爬。

5.通用爬蟲工作流程

(1)抓取網頁:通過搜尋引擎將待爬取的url加入到通用爬蟲的url隊列中,進行網頁內容的爬取

(2)數據存儲:將爬取下來的網頁保存到本地,這個過程會有一定的去重操作,如果某個網頁的內 容大部分內容都會重複,搜尋引擎可能不會保存。

(3)預處理:提取文字,中文分詞,消除噪音(比如版權聲明文字,導航條,廣告等)。

(4)設置網站排名,為用戶提供服務。

6.一些反爬及其應對措施

( 1)通過user-agent來判斷是否是爬蟲。

解決方案:可以通過偽裝請求頭中的user-agent來解決。若user-agent被檢測到,可以找大量的user-agent,放入列表,然後進行更換

(2)將IP進行封殺。

解決方案:可以通過代理來偽裝IP。

(3)通過訪問頻率來判斷是否是一個爬蟲。

解決方案:可以通過設置請求間隔,和爬取間隔。

(4)當一定時間內的總請求數超過上限,彈出驗證碼。

解決方案:對於簡單的驗證碼圖片可以使用tesseract來處理,對於複雜的可以去打碼平臺。

(5)通過JS來獲取頁面數據。

解決方案:可以使用selenium+phantomjs來加載JS獲取數據。

介紹搜尋引擎

1.搜尋引擎的主要組成

通用爬蟲:就是將網際網路的上頁面整體的爬取下來之後,保存到本地。

通用爬蟲要想爬取網頁,需要網站的url.但是搜尋引擎是可以搜索所有網頁的。那麼通用爬蟲url就要涉及到所有網頁,這個『所有』是如何做到的:

2.搜尋引擎的工作流程(通用爬蟲的工作流程)

(1)抓取網頁:通過搜尋引擎將待爬取的URL加入到通用爬蟲的URL隊列中,進行網頁內容的爬取。

(2)數據存儲:將爬取下來的網頁保存到本地,這個過程會有一定的去重操作,如果某個網頁的內 容大部分內容都會重複,搜尋引擎可能不會保存。

(3)預處理:提取文字,中文分詞,消除噪音(比如版權聲明文字,導航條,廣告等)。

(4)設置網站排名,為用戶提供服務。

3.搜尋引擎的局限性

(1)搜尋引擎只能爬取原網頁,但是頁面90%內容都是無用的。

(2)搜尋引擎不能滿足不同行業,不同人的特定需求。

(3)通用搜尋引擎只能爬取文字信息,不能對音頻、圖片等進行爬取。

(4)只能基於關鍵字查詢,無法基於語義查詢。

介紹HTTP

網絡七層協議:

1.HTTP協議特點

2.HTTP工作過程

3.HTTP協議和HTTPS協議的區別

HTTP協議是使用明文數據傳輸的網絡協議,明文傳輸會讓用戶存在一個非常大的安全隱患。埠80

HTTPS協議可以理解為HTTP協議的安全升級版,就是在HTTP的基礎上增加了數據加密。埠443

HTTPS協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網絡協議要比HTTP協議安全。

4.HTTP通信

HTTP通信由兩部分組成:客戶端請求消息與伺服器響應消息。

5.關於響應常見的響應碼

6.客戶端請求(Get和Post區別)

(1)組成:請求行、請求頭部、空行、請求數據四個部分組成

(2)請求方法Get/Post

(3)Get和Post的區別

GET和POST本質上就是TCP連結,並無差別。但是由於HTTP的規定和瀏覽器/伺服器的限制,導致他們在應用過程中體現出一些不同。

(4)常見的請求頭

User-Agent:客戶端請求標識。

Accept:傳輸文件類型。

Referer :請求來源。

cookie (cookie):在做登錄的時候需要封裝這個頭。

Content-Type (POST數據類型)

7.伺服器響應

(1)組成:狀態行,響應頭,空行,響應正文。

(2)常見的響應頭

Content-Type:text/html;資源文件的類型,還有字符編碼

Content-Length:響應長度

Content-Size響應大小

Content-Encoding告訴客戶端,服務端發送的資源是採用什麼編碼的。

Connection:keep-alive這個欄位作為回應客戶端的Connection:keep-alive,告訴客戶端伺服器的tcp連接也是一個長連接,客戶端可以繼續使用這個TCP連接發送HTTP請求

url

統一資源定位符:

基本格式:scheme://host[:port#]/path/…/?query-string

協議://伺服器ip地址:埠號/資源路徑/?key1=參數1&key2=參數2

scheme:協議(例如:HTTP、HTTPS、FTP)

host/IP:伺服器的IP位址或者域名

port:伺服器的埠(如果是走協議默認埠,預設埠80),用來從網際網路進入電腦

path:訪問資源的路徑,就是為了在電腦中找到對應的資源路徑

query-string:參數,發送給http伺服器的數據

anchor:錨(跳轉到網頁的指定錨點位置)

Q:當我們在瀏覽器輸入一個URL,為什麼可以加載出一個頁面?為什麼抓包的過程中請求一個URL,出現很多的資源請求?

當我們在瀏覽器輸入一個URL,客戶端會發送這個URL對應的一個請求到伺服器獲取內容。伺服器收到這個請求,解析出對應內容,之後將內容封裝到響應裡發送到客戶端

當客戶端拿到這個HTML頁面,會查看這個頁面中是否有CSS、JS、image等URL,如果有,在分別進行請求,獲取到這些資源。

客戶端會通過HTML的語法,將獲取到的所有內容完美的顯示出來。

Cookie和Session

產生原因:由於HTTP是一個無狀態的協議,每次請求如果需要之前的一些信息,無法記錄,因此為了解決這個問題,產生了一種記錄狀態技術,Cookie和Session。

Cookie指某些網站為了辨別用戶身份,進行會話跟蹤而存儲在用戶本地終端上的數據,種類有會話Cookie和持久Cookie。

(1)會話Cookie指存在瀏覽器內存的Cookie,當瀏覽器關閉,會話Cookie會失效;

(2)持久Cookie是保存在硬碟上的Cookie。

Session用來存儲特定的用戶會話所需的屬性及其配置信息。

Cookie是在客戶端記錄狀態,Session是在服務端記錄狀態。

聯繫:當客戶端發送一個Cookie,伺服器會從這個Cookie中找到sessionID,再查找出相應的Session信息返回給客戶端,來進行用戶頁面的流轉。如果通過sessionID來查找Session的時候,發現沒有Session(一般第一次登陸或者清空了瀏覽器),那麼就會創建一個Session。

hashlib密碼加密

def get_hex(value): 

md5_ = hashlib.md5()

    md5_.update(value.encode('utf-8')) 

    return md5_.hexdigest() 

關於response.text亂碼問題

response的常用屬性:

1.獲取字符串類型的響應正文:response.text

2.獲取bytes類型的響應正文:response.content

3.響應正文字符串編碼:response.encoding

4.狀態碼:response.status_code

5.響應頭:response.headers

response.text亂碼問題:

#方法一:轉換成utf-8格式  

response.encoding='utf-8'  

print(response.text) 

#方法二:解碼為utf-8 :

with open('index.html','w',encoding='utf-8') as fp:    fp.write(response.content.decode('utf-8')) 

代理

代理的作用:

1、突破自身IP 訪問限制, 訪問一些平時不能訪問的站點。

2、訪問一些單位或團體內部資源:比如使用教育網內地址段免費代理伺服器, 就可以用於對教育網開放的各類FTP 下載上傳, 以及各類資料查詢共享等服務。

3、提高訪問速度:通常代理伺服器都設置一個較大的硬碟緩衝區,當有外界的信息通過時, 同時也將其保存到緩衝區中,當其他用戶再訪問相同的信息時,則直接由緩衝區中取屮信息傳給用戶,以提高訪問速度。

4、隱藏真實IP :上網者也可以通過這種方法隱藏自己的IP , 免受攻擊。對於爬蟲來說, 我們用代理就是為了隱藏自身IP , 防止自身的被封鎖。

代理根據匿名程度的分類:

JSON數據

數據的分類:

JSON的本質:是一個字符串,JSON是對JS對象的字符串表達式,它使用文本形式表示一個JS對象的信息。

JSON使用:

(1)json.dumps(Python的list或者dict),將Python的list或者dict返回為一個JSON字符串;

(2)json.loads(json字符串),將JSON字符串返回為Python的list或者dict;

(3)json.dump(list/dict,fp),將Python的list或者dict轉為一個JSON字符串,保存到文件中;

(4)json.load(fp) ,從JSON文件中讀出JSON數據,並轉換為Python的list或者dict。

正則表達式

1、貪婪和非貪婪

(1)正則默認是貪婪模式,所以數量控制符默認是取最大值,也是貪婪。例如*

(2)非貪婪是用?來控制,儘量匹配最少的次數,0次或一次。

2、Python使用格式:

pattern=re.compile('正則表達式') 

print(pattern.match(字符串,start,end))#默認從頭開始匹配,只匹配一次,返回一個match對象

print(pattern.search(字符串,start,end))#從任意位置開始匹配,只匹配一次,返回一個match對象

print(pattern.findall(字符串,start,end))#全文多次匹配,將匹配到的結果放到一個list返回給我們

print(pattern.finditer(字符串,start,end))#全文多次匹配,將匹配到的結果放到一個match對象的迭代器返回

XML

XML的基本知識:

1.定義:XML稱為可拓展性標記語言,類似 HTML;

2.特點:XML具有自描述特性,是一種半結構化數據;

3.作用:XML的設計宗旨是傳輸數據,而非顯示數據。可以作為配置文件使用來記錄一些重要信息;

4.XML的標籤需要我們自行定義。

HTML和XML 區別:

語法方面:

在HTML中不區分大小寫,在XML中嚴格區分大小寫

在HTML中,在某些情況可以省略閉合標籤。在XML中,絕對不能省略任何標記。

在XML中,單標籤結尾處需要加』/』。

XML文檔中,空白部分不會被解析器自動刪除,但是HTML是過濾掉空格的

在XML中,屬性值必須封裝在引號中。在HTML中,引號可用可不用。

在HTML中屬性名可以不帶屬性值,XML必須帶屬性值而且不能為空。

標記不同:

HTML使用固有的標記,XML沒有固有標記。

作用不同:

XML主要用來傳輸數據,HTML主要用來顯示數據。

Selenium+PhantomJS

Selenium:Web自動測試工具。

PantomJS:是一個無界面的瀏覽器,所以他可以運行JS代碼,幫我們拿到頁面數據。

特點:功能強大,幾乎可以對付任何網頁,但會導致代碼效率低。

Selenium 是一個 Web 的自動化測試工具,可以根據我們的指令,讓瀏覽器自動加載頁面,獲取需要的數據,甚至頁面截屏,或者判斷網站上某些動作是否發生。Selenium 自己不帶瀏覽器,不支持瀏覽器的功能,它需要與第三方瀏覽器結合在一起才能使用。但是我們有時候需要讓它內嵌在代碼中運行, 所以我們可以用一個PhantomJS 的工具代替真實的瀏覽器。Selenium 庫裡有個叫 WebDriver 的 API。WebDriver 有點兒像可以加載網站的瀏覽器,但是它也可以查找頁面元素,與頁面上的元 素進行交互 (發送文本、點擊等),以及執行其他動作來運行網絡爬蟲。

PhantomJS 是一個基於 Webkit 的「無界面」瀏覽器,它會把網站加載到內存並執行頁面上的 JavaScript,因為不會展示圖形界面,所以運行起來比完整的瀏覽器要高效。相比傳統的 Chrome或 Firefox 瀏覽器等,資源消耗會更少。如果我們把 Selenium 和 PhantomJS 結合在一起,就可以運行一個非常強大的網絡爬蟲了,這個爬蟲可以處理 JavaScript、Cookie、headers,以及任 何我們真實用戶需要做的事情。主程序退出後,selenium 不保證 phantomJS 也成功退出,最好手動關閉 phantomJS 進程。(有可能會導致多個 phantomJS 進程運行,佔用內存)。WebDriverWait 雖然可能會減少延時,但是目前存在 bug(各種報錯),這種 情況可以採用 sleep。phantomJS 爬數據比較慢,可以選擇多線程。如果運行的時候發現有的可 以運行,有的不能,可以嘗試將 phantomJS 改成 Chrome。

實現模擬登錄的方式有哪些

1.直接使用已知的Cookie訪問

先用瀏覽器登錄,獲取瀏覽器裡的cookie字符串,然後封裝至請求頭。

2.模擬登錄後用session保持登錄狀態

使用session模擬登陸後,就會自動存儲一個cookie次從而保持住登錄狀態。

3.使用Selenium+PhantomJS訪問

Selenium庫提供了find_element(s)_by_xxx的方法來找到網頁中的輸入框、按鈕等元素。其中xxx可以是id、name、tag_name(標籤名)、class_name(class),也可以是xpath(xpath表達式)等等。當然還是要具體分析網頁原始碼。

線程+進程+多線程

關係:一個程序至少有一個進程,一個進程至少有一個線程。

線程的順序:

新建:線程創建(t=threading.Thread(target=方法名)或者線程類)

就緒:當啟動線程後,線程就進入就緒狀態,就緒狀態的線程會被放到一個CPU調度隊列裡面,cpu會負責讓其中的線程運行,變為運行狀態。

運行狀態:CPU調度一個就緒狀態的線程,該線程就變為運行狀態。

阻塞狀態:當運行狀態的線程被阻塞變為阻塞狀態,阻塞狀態的線程就會重新變為就緒狀態才能繼續運行。

死亡狀態:線程執行完畢。

多線程和多進程優缺點

多線程的優點:

程序邏輯和控制方式複雜;

所有線程可以直接共享內存和變量;

線程方式消耗的總資源比進程方式好。

多線程缺點:

多進程優點:

多進程缺點:

在實際開發中,選擇多線程和多進程應該從具體實際開發來進行選擇。最好是多進程和多線程結合。

互斥鎖和死鎖和GLF鎖

1.互斥鎖

定義:當多個線程幾乎同時修改某一個共享數據的時候,需要進行同步控制。線程同步能夠保證多個線程安全訪問「競爭資源」,最簡單的同步機制就是引用互斥鎖。

由於線程共享進程的內存空間和數據,因此在某個線程要共享數據時,先將其鎖定,此時資源的狀態為「鎖定」,其他線程不能更改;直到該線程釋放資源,將資源的狀態變成「非鎖定」,其他的線程才能再次鎖定該資源。互斥鎖保證了每次只有一個線程進入寫入操作,從而保證了多線程情況下數據的正確性。互斥鎖體現的就是一個同步的機制,即該線程釋放資源就是一個條件,條件完成,才能執行下一步操作。是微觀的操作。

鎖的好處:

(1)確定了某段代碼只能由一個線程從頭到尾完整地執行。

(2)全局變量的安全

鎖的壞處:

(1)阻止了多線程的並發執行,包含鎖的某段代碼實際上只能以單線程模塊執行,效率降低

(2)由於可以存在多個鎖,不同的線程持有不同的鎖,並試圖獲取對方持有的鎖的時,可能會造成「死鎖」。

2.死鎖

(1)同一個線程先後兩次調用lock,在第二次調用時,由於鎖已經被自己佔用,該線程會掛起等待自己釋放鎖,由於該線程已被掛起而沒有機會釋放鎖,因此 它將一直處於掛起等待狀態,變為死鎖;

(2)線程A獲得了鎖1,線程B獲得了鎖2,這時線程A調用lock試圖獲得鎖2,結果是需要掛起等待線程B釋放鎖2,而這時線程B也調用lock試圖獲得鎖1,結果是需要掛起等待線程A釋放鎖1,於是線程A和B都在等待對方釋放自己才釋放,從而造成兩個都永遠處於掛起狀態,造成死鎖。

3.有GLF鎖為什麼還要有互斥鎖

(1)為什麼設計GLF鎖?

Python 在設計之初就考慮到要在解釋器的主循環中,同時只有一個線程在執行,即在任意時刻,只有一個線程在解釋器中運行。對Python 虛擬機的訪問由全局解釋器鎖(GIL)來控制,正是GIL鎖能保證同一時刻只有一個線程在運行。

(2)宏觀微觀考慮GLF鎖?

GIL是宏觀的操作。比如在一個4核的環境下,只有一個核是運行著線程,而其他三個核是空的。GIL是線程鎖,針對線程,而不是進程。

MongoDB

MongoDB和傳統的關係型資料庫區別:

1.傳統資料庫特點是存儲結構化數據,數據以行為單位,每行的數據結構和類型相同。

2.MongoDB存儲的是文檔,每個文檔得結構可以不相同,能夠更便捷的獲取數據。

3.MongoDB的集合不需要提前創建,可隱式創建,而關係型資料庫的表需要提前定義。

4.MongoDB第三方支持豐富。(這是與其他的NoSQL相比,MongoDB也具有的優勢)。

5.MongoDB不支持事務操作。

6.MongoDB支持大容量的存儲,佔用空間過大。

MongoDB和SQL的對比:

遊標:

定義:由於MongoDB底層是JS編寫,因此可以使用一些JS代碼,通俗的說遊標不是查詢結果,而是查詢的返回資源或者接口,就像Python中的生成器,通過這個生成器,可以一次一次的獲取每一個資源。

持久化:日誌和快照對比

快照和日誌兩者如何選擇?

推薦兩種共同使用:

1.如果Redis僅僅是用來做為緩存伺服器的話,我們可以不使用任何的持久化。

2.一般情況下我們會將兩種持久化的方式都開啟。redis優先加載AOF文件來回複數據。RDB的好處是快速。

3.在主從節點中,RDB作為我們的備份數據,只在salve(從節點)上啟動,同步時間可以設置的長一點,只留(save 900 1)這條規則就可以了。

4.開啟AOF的情況下,主從同步是時候必然會帶來IO的性能影響,此時我們可以調大auto-aof-rewrite-min-size的值,比如5GB。來減少IO的頻率

5.不開啟AOF的情況下,可以節省IO的性能影響,這是主從間通過RDB持久化同步,但如果主從都掛掉,影響較大。

在dump rdb過程中,aof如果停止同步,會不會丟失?

答: 不會,所有的操作緩存在內存的隊列裡,dump完成後,統一操作。

aof重寫是指什麼?

答:由於日誌保存的是所有操作命令,導致存的日誌會過大,而且資料庫中有可能數據進行過刪除,因此日誌中的一些命令就相當於無效,因此日誌先會刪除,然後內存中的數據會逆化成命令,再重新寫入到日誌文件中,以解決 aof日誌過大的問。

如果rdb文件和aof文件都存在,優先用誰來恢復數據?

答: 在這種情況下,當Redis重啟的時候會優先載入AOF文件來恢復原始的數據,因為在通常情況下AOF文件保存的數據集要比RDB文件完整。

恢復時rdb和aof哪個恢復的快?

答: rdb快,因為其是數據的內存映射,直接載入到內存,而aof是命令,需要逐條執行。

Scrapy和Scrapy-Redis

什麼是Scrapy?

Scrapy 是一個快速、高層次的基於 Python 的 Web 爬蟲構架,它用於抓取Web 站點並從頁面中提取結構化的數據。Scrapy 使用了 Twisted異步網絡庫來處理網絡通訊。

Scrapy 常應用在包括數據挖掘,信息處理或存儲歷史數據等一系列的程序中。

Scrapy優缺點

優點:

缺點:

Scrapy的組件:

Scrapy和scrapy-redis的區別:

Scrapy是一個Python爬蟲框架,爬取效率極高,具有高度定製性,但是不支持分布式。而scrapy-redis一套基於redis資料庫、運行在Scrapy框架之上的組件,可以讓scrapy支持分布式策略,Slaver端共享Master端Redis資料庫裡的item隊列、請求隊列和請求指紋集合

為什麼選擇Redis資料庫,因為Redis支持主從同步,而且數據都是緩存在內存中的,所以基於Redis的分布式爬蟲,對請求和數據的高頻讀取效率非常高。

Redis的優點:

1.數據讀取快,因為數據都放在內存上

2.支持事務watch

3.數據持久化,支持快照和日誌,方便恢復數據

4.擁有豐富的數據類型:list,string,set,qset,hash

5.支持主從複製,可以進行數據備份

6.豐富的特性:可以作為緩存,消息隊列,設置過期時間,到期自動刪除

分布式爬蟲主要解決什麼問題?

IP、帶寬、CPU、io

Scrapy如何實現分布式抓取?

可以藉助scrapy_redis類庫來實現。

在分布式爬取時,會有master機器和slave機器,其中,master為核心伺服器,slave為具體的爬蟲伺服器。

我們在master伺服器上搭建一個Redis資料庫,並將要抓取的url存放到redis資料庫中,所有的slave爬蟲伺服器在抓取的時候從redis資料庫中去連結,由於scrapy_redis自身的隊列機制,slave獲取的url不會相互衝突,然後抓取的結果最後都存儲到資料庫中。master的redis資料庫中還會將抓取過的url的指紋存儲起來,用來去重。相關代碼在dupefilter.py文件中的request_seen()方法中可以找到。

定時任務:

1.可以設計一個定時的類,使用時間模塊(time,datetime),比如爬取時候獲取當前時間,再當前時間多久後再爬取

2.使用linux的crontab的計劃任務

crontab -l 列出所有的定時任務    看不到配置文件中寫的定時任務  

crontab -e 新增計劃任務  跟上面的區別在於  沒有用戶名 

crontab  -r 清空計劃任務  

分  時 日  月  周   命令    

舉例使用:

*  *   *   *  *    命令   每分每時每天每月每周 執行這個命令  

0-59 0-23 1-31 1-12 0-6  0是 周天 1-6 周一到周六      

0  2   *   *   *   mysqldump  每天的2點備份資料庫  

0  2   *   *   2   sync    每個周二的2點做數據同步     

0  8   15  *   *   /home/jsgz.py 每個月15號的八點給大家算工資  

0  */2 *   *   *   /home/camera.py 每隔2個小時執行一次查看攝像頭  

0  8,12,18 * * 1-5 kq.py    每周1-5 的 8點 12點 18點  執行打卡  

0  8  *  * * *  spider.sh   每天 8點爬蟲

爬蟲框架、模塊

Python自帶:urllib,urllib2。

urllib和urllib2模塊都做與請求URL相關的操作,但他們提供不同的功能。

urllib2.:urllib2.urlopen可以接受一個Request對象或者url,(在接受Request對象時候,並以此可以來設置一個URL 的headers),urllib.urlopen只接收一個url。

urllib 有urlencode,urllib2沒有,因此總是urllib,urllib2常會一起使用的原因

第 三 方:Requests

Requests是一個HTTP庫, 它只是用來,進行請求,對於HTTP請求,他是一個強大的庫,下載,解析全部自己處理,靈活性更高,高並發與分布式部署也非常靈活,對於功能可以更好實現.

框 架:Scrapy

Scrapy是封裝起來的框架,他包含了下載器,解析器,日誌及異常處理,基於多線程, twisted的方式處理,對於固定單個網站的爬取開發,有優勢,但是對於多網站爬取 100個網站,並發及分布式處理方面,不夠靈活,不便調整與括展。

MyISAM 與 InnoDB 

MyISAM 與 InnoDB 兩個引擎有什麼區別?

InnoDB 支持事務,MyISAM 不支持,這一點是非常之重要。事務是一種高級的處理方式,如果在一些列增刪改中只要哪個出錯還可以回滾還原,而 MyISAM就不可以了。

MyISAM 適合查詢以及插入為主的應用,InnoDB 適合頻繁修改以及涉及到安全性較高的應用。

InnoDB 支持外鍵,MyISAM 不支持。

MyISAM 是默認引擎,InnoDB 需要指定。

InnoDB 不支持 FULLTEXT 類型的索引。

InnoDB 中不保存表的行數,如 select count( * ) from table 時,InnoDB;需要掃描一遍整個表來計算有多少行,但是 MyISAM 只要簡單的讀出保存好的行數即 可。注意的是,當 count( * )語句包含 where 條件時 MyISAM 也需要掃描整個表。

對於自增長的欄位,InnoDB 中必須包含只有該欄位的索引,但是在 MyISAM表中可以和其他欄位一起建立聯合索引。

清空整個表時,InnoDB 是一行一行的刪除,效率非常慢。MyISAM 則會重建表。

寫爬蟲是用多進程好?還是多線程好? 為什麼?

IO密集型情況使用多線程;

計算密集型情況下使用多進程;

IO 密集型代碼(文件處理、網絡爬蟲等),多線程能夠有效提升效率(單線程下有 IO 操作會進行 IO 等待,造成不必要的時間浪費,而開啟多線程能在線程 A 等待時,自動切換到線程 B,可以不浪費 CPU 的資源,從而能提升程序執行效率)。在實際的數據採集過程中,既考慮網速和響應的問題,也需要考慮自身 機器的硬體情況,來設置多進程或多線程。

資料庫的優化

為什麼要優化?

一個應用吞吐量瓶頸往往出現在資料庫的處理速度上,隨著應用程式的使用和業務的拓展,資料庫數據量逐漸增多,資料庫處理壓力逐漸增大,關係型資料庫數據存放在磁碟上的,讀寫速度較慢(與內存中的數據相比)。

優化方式:

設計表的時候嚴格根據資料庫的設計範式來設計資料庫;

select 後儘量不使用*;

儘量不使用嵌套查詢,使用連接查詢或者where查詢;

sql關鍵詞儘量使用大寫;

儘量使用邏輯外交不使用物理外鍵;

給查詢頻繁的欄位添加索引,並且遵循最左原則(儘量將首選關鍵欄位放在最前邊);

垂直分庫分表:把一些不經常讀的數據或者結果複雜的表拆分成多張表,較少磁碟I/O操作;

水平分庫分表:於數據量龐大的表,使用水平分庫分表;

使用緩存,把經常訪問到的數據而且不需要經常變化的數據放在緩存中,能節約磁碟IO;

優化硬體;

主從分離讀寫;採用主從複製把資料庫的讀操作和寫入操作分離開來。

使用過的解析數據包:Xpath、正則

怎麼監控爬蟲的狀態

(1)使用 Python 的 STMP 包將爬蟲的狀態信心發送到指定的郵箱。

(2)Scrapyd、pyspider

(3)引入日誌

panads讀取數據

import pandas as pd

# 加載detail

detail = pd.read_excel("./meal_order_detail.xlsx")

# 1、直接查看方式--先後索引

#  先列 後行的方式

# 獲取dishes_id counts amounts dishes_name 多列數據

res = detail[["dishes_id","counts","amounts","dishes_name"]]

# 獲取多列的前n行

res1 = detail[["dishes_id", "counts", "amounts", "dishes_name"]][:20]

res2 = detail[["dishes_id", "counts", "amounts", "dishes_name"]].head(20)

# res = detail[["dishes_id", "counts", "amounts", "dishes_name"]][[0,1,2,3,4]] #  # 不可以的

# res = detail["dishes_id"][[0,1,2,3,4]] # 可以的

# print("獲取多列的結果:\n", res)

# 2、同時索引

# loc  只能使用名稱 ---注意:可以使用名稱切片---包含收尾

# iloc 只能使用下標

res3 = detail.loc[:,"dishes_id":"counts"]

# 3、ix ---同時索引混合索引

# 既可以使用名稱,也可以使用下標

# res = detail.ix[0:4, "dishes_id":"counts"]

# res = detail.ix[0:4, 0:2]  # 前面行使用名稱,列使用下標

#

# res = detail.ix[0:4, 0:"amounts"] # 錯誤的,不能混搭

# print("res:\n", res)



# 直接索引方式  # 速度最快

# loc iloc  #速度適中 # 某些大的平臺上只封裝loc iloc方式 --推薦

# ix # 速度最慢 --在最新的版本中提示,將要被刪除掉

Nginx的正向代理和反向代理

Web 開發中,部署方式大致類似。簡單來說,使用 Nginx 主要是為了實現分流、轉發、負載均衡, 以及分擔伺服器的壓力。Nginx 部署簡單,內存消耗少,成本低。Nginx 既可以做正向代理,也可以做反向代理。

正向代理:請求經過代理伺服器從區域網發出,然後到達網際網路上的伺服器。特點:服務端並不知道真正的客戶端是誰。

反向代理:請求從網際網路發出,先進入代理伺服器,再轉發給區域網內的伺服器。特點:客戶端並不知道真正的服務端是誰。

區別:正向代理的對象是客戶端。反向代理的對象是服務端。

緩存穿透、緩存擊穿、緩存雪崩

Redis技術就是NoSQL技術中的一種,但是引入Redis又有可能出現緩存穿透,緩存擊穿,緩存雪崩等問題。

1.緩存穿透:

(1)產生原因:key對應的數據在數據源並不存在,每次針對此key的請求從緩存獲取不到,請求都會到數據源,從而可能壓垮數據源。比如用一個不存在的用戶id獲取用戶信息,不論緩存還是資料庫都沒有,若黑客利用此漏洞進行攻擊可能壓垮資料庫。

(2)解決方案:

①最常見的則是採用布隆過濾器,將所有可能存在的數據哈希到一個足夠大的bitmap中,一個一定不存在的數據會被這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。

②另外也有一個更為簡單粗暴的方法(我們採用的就是這種),如果一個查詢返回的數據為空(不管是數據不存在,還是系統故障),我們仍然把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分鐘。

2.緩存擊穿:

(1)產生原因:key對應的數據存在,但在redis中過期,此時若有大量並發請求過來,這些請求發現緩存過期一般都會從後端DB加載數據並回設到緩存,這個時候大並發的請求可能會瞬間把後端DB壓垮。

(2)解決方案:業界比較常用的做法,是使用mutex。簡單地來說,就是在緩存失效的時候(判斷拿出來的值為空),不是立即去load db,而是先使用緩存工具的某些帶成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一個mutex key,當操作返回成功時,再進行load db的操作並回設緩存;否則,就重試整個get緩存的方法。

3.緩存雪崩:

(1)產生原因:當緩存伺服器重啟或者大量緩存集中在某一個時間段失效,這樣在失效的時候,也會給後端系統(比如DB)帶來很大壓力。

(2)解決方案:

①緩存失效時的雪崩效應對底層系統的衝擊非常可怕!大多數系統設計者考慮用加鎖或者隊列的方式保證來保證不會有大量的線程對資料庫一次性進行讀寫,從而避免失效時大量的並發請求落到底層存儲系統上。

②簡單方案就時講緩存失效時間分散開,比如我們可以在原有的失效時間基礎上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重複率就會降低,就很難引發集體失效的事件。

Python垃圾回收機制

引用計數是一種垃圾收集機制,而且也是一種最直觀,最簡單的垃圾收集技術。當 Python 的某個對象的引用計數降為 0 時,說明沒有任何引用指向該對象,該對象就成為要被回收的垃圾了。比如某個新建對象,它被分配給某個引用,對象的引用計數變為 1。如果引用被刪除,對象的引用計數為 0,那麼該對象就可以被垃圾回收。不過如果出現循環引用的話,引用計數機制就不再起有效的作用了。

一般是類中的 __del方法進行的。

版權聲明:本文為CSDN博主「不願透露姓名の網友」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/qq_40558166/article/details/103044923

金三銀四招聘季,你還有哪些面試乾貨文章呢?分享或者查看乾貨文章可戳:

☞Namebase 給 GitHub 開發者白送錢,是拉新還是投資騙局?

☞在線音視頻時代來臨!

☞2020,國產AI開源框架「亮劍」TensorFlow、PyTorch

相關焦點

  • 【必收藏】2020 爬蟲面試題目合集
    (2)聚焦爬蟲:聚焦爬蟲在實施網頁抓取時會對內容進行處理篩選,儘量保證只抓取與需求相關的網頁信息。通用爬蟲和聚焦爬蟲的區別:聚焦爬蟲在實施網頁抓取時會對內容進行處理篩選,儘量保證只抓取與需求相關的網頁信息。
  • Python 爬蟲面試題 170 道
    最近在刷面試題,所以需要看大量的 Python 相關的面試題,從大量的題目中總結了很多的知識,同時也對一些題目進行拓展了,但是在看了網上的大部分面試題都有這幾個問題:有些部分還是 Python2 的代碼回答的很簡單,關鍵的題目沒有點出為什麼
  • Python 爬蟲面試題 170 道:2019 版
    引言最近在刷面試題,所以需要看大量的 Python 相關的面試題,從大量的題目中總結了很多的知識,同時也對一些題目進行拓展了,但是在看了網上的大部分面試題不是很滿意。難受啊,所以我決定針對市面上大多的 Python 題目做一個分析,同時也希望大家儘可能的做到舉一反三,而不是局限於題目本身。大概就這樣吧,有你看過的題目也有你沒看到過的。
  • 寧德2020年事業單位面試名單_寧德事業單位面試題目
    寧德2020年事業單位面試名單_寧德事業單位面試題目由福建公務員考試錄用網提供同步福建事業單位考試網,更多關於事業單位考試的內容,請關注福建公務員考試網!   日前,寧德人社局回復上半年寧德市事業單位招聘公共題面試時間,初定於8月22-23日舉行!
  • 2020年湖南教師資格面試題目及解析_湖南教師資格面試教師考試
    2020年湖南教師資格面試題目及解析_湖南教師資格面試教師考試由湖南中小學教師資格網考試快訊提供,以及提供2020湖南中小學教師資格證試題真題考試信息。更多關於2020年湖南教師資格面試題目及解析_湖南教師資格面試教師考試,教師資格考試面試,教師資格面試試題,教師資格面試解析快訊的內容,請關注湖南中小學教師資格證考試網!!
  • 2020年北京教師資格面試題目及答案_北京教師資格面試考試估分...
    【導讀】中國教育考試網:2020下半年安徽教師資格考試面試時間為1月9日-10日,華圖教育根據網絡搜集及考生回憶整理提供2020下半年安徽教師資格考試面試試題及解析,供廣大考生參考,請廣大考生保持關注!
  • 2020年重慶教師資格面試題目及解析_重慶教師資格面試教師考試
    【導讀】中國教育考試網:2020下半年安徽教師資格考試面試時間為1月9日-10日,華圖教育根據網絡搜集及考生回憶整理提供2020下半年安徽教師資格考試面試試題及解析,供廣大考生參考,請廣大考生保持關注!
  • 2020年江蘇教師資格面試題目及答案_江蘇教師資格面試考試估分
    【導讀】中國教師資格證網:2020下半年安徽教師資格考試面試時間為1月9日-10日,華圖教育根據網絡搜集及考生回憶整理提供2020下半年安徽教師資格考試面試試題及解析,供廣大考生參考,請廣大考生保持關注!
  • 2020部隊文職面試題目及答案:10月28日面試題
    【導讀】華圖廣西軍隊文職考試網同步華圖教育發布:2020部隊文職面試題目及答案:10月28日面試題,詳細信息請閱讀下文!如有疑問請加【2020廣西軍隊文職交流群:947948407】 ,更多資訊請關注廣西華圖微信公眾號(gxhuatu),廣西軍隊文職課程諮詢電話:0771-2808922 2020年軍隊文職10月23日出成績,從出成績後,考生陸續收到用人單位的面試通知信息,發現只有少部分用人單位面試不足一周時間!
  • 2020年山東教師資格面試考試題目答案
    【導讀】教師資格證官網:2020下半年安徽教師資格考試面試時間為1月9日-10日,華圖教育根據網絡搜集及考生回憶整理提供2020下半年安徽教師資格考試面試試題及解析,供廣大考生參考,請廣大考生保持關注!
  • 2020年重慶教師資格面試考試題目答案
    【導讀】中國教師資格證網:2020下半年安徽教師資格考試面試時間為1月9日-10日,華圖教育根據網絡搜集及考生回憶整理提供2020下半年安徽教師資格考試面試試題及解析,供廣大考生參考,請廣大考生保持關注!
  • 2020年安徽教師資格考試面試題目
    【導讀】NTCE:2020安徽教師資格面試將於1月9日~10日進行,華圖教育根據考生回憶及網絡整理提供2020安徽教師資格考試試題並組織老師教研提供試題解析,請廣大考生保持關注!
  • 2020年天津教師資格面試題目及解析_天津教師資格面試教師考試
    【導讀】天津中小學教師資格網:2020下半年安徽教師資格考試面試時間為1月9日-10日,華圖教育根據網絡搜集及考生回憶整理提供2020下半年安徽教師資格考試面試試題及解析,供廣大考生參考,請廣大考生保持關注!
  • 無領導面試題目100及最佳答案_2020廣東省考面試
    無領導面試題目100及最佳答案_2020廣東省考面試由廣東公務員考試網考試快訊欄目由提供,更多關於廣東公務員無領導小組面試,廣東公務員考試快訊的內容,請關注廣東公務員考試頻道/廣東公務員考試網!
  • 2020年山西教師資格面試題目及解析_山西教師資格面試教師考試
    山西教師資格證考試網同步中小學教師資格證網考試動態信息:2020年山西教師資格面試題目及解析_山西教師資格面試教師考試,2020陽泉市教師資格證試題真題。更多關於教師資格面試試題,教師資格面試解析,教師資格考試面試,中小學教師資格證網的信息的內容,請關注山西教師資格證考試網以及山西華圖教育!
  • 2020年國家教師資格面試題目及解析_國家教師資格面試教師考試
    2020年國家教師資格面試題目及解析_國家教師資格面試教師考試由國家教師資格證網考試快訊提供,以及提供2020國家教師資格證試題真題考試信息。更多關於2020年國家教師資格面試題目及解析_國家教師資格面試教師考試,教師資格考試面試,教師資格面試解析,教師資格面試試題快訊的內容,請關注國家教師資格證考試網!!
  • 2020年海南教師資格面試考試題目答案
    【導讀】海南教師資格證網:2020下半年安徽教師資格考試面試時間為1月9日-10日,華圖教育根據網絡搜集及考生回憶整理提供2020下半年安徽教師資格考試面試試題及解析,供廣大考生參考,請廣大考生保持關注!
  • 2020年北京教師資格面試題目及解析_北京教師資格面試教師考試...
    【導讀】北京中小學教師資格網:2020下半年安徽教師資格考試面試時間為1月9日-10日,華圖教育根據網絡搜集及考生回憶整理提供2020下半年安徽教師資格考試面試試題及解析,供廣大考生參考,請廣大考生保持關注!
  • 2020年安徽教師資格面試題目解析
    【導讀】安徽教師資格證網:2020安徽教師資格面試將於1月9日~10日進行,華圖教育根據考生回憶及網絡整理提供2020安徽教師資格考試試題並組織老師教研提供試題解析,請廣大考生保持關注!
  • 2020年內蒙古教師資格面試題目及答案_內蒙古教師資格面試教師考試估
    【導讀】中國教育考試網:2020下半年安徽教師資格考試面試時間為1月9日-10日,華圖教育根據網絡搜集及考生回憶整理提供2020下半年安徽教師資格考試面試試題及解析,供廣大考生參考,請廣大考生保持關注!