python面試問(wèn)題

1. Python 的特點(diǎn)和優(yōu)點(diǎn)是什么?

1. 解釋性
2. 動(dòng)態(tài)特性
3. 面向?qū)ο?4. 語(yǔ)法簡(jiǎn)潔
5. 開(kāi)源
6. 豐富的社區(qū)資源

深拷貝和淺拷貝有什么區(qū)別?

答: 淺拷貝在創(chuàng)建新實(shí)例類(lèi)型時(shí)會(huì)用到,并保留在新實(shí)例中復(fù)制的值。淺拷貝用于復(fù)制引用指針,就像復(fù)制值一樣。這些引用指向原始對(duì)象,并且在類(lèi)的任何成員中所做的更改也將影響它的原始副本。淺拷貝允許更快地執(zhí)行程序,它取決于所使用的數(shù)據(jù)的大小。

深拷貝用于存儲(chǔ)已復(fù)制的值。深層復(fù)制不會(huì)將引用指針復(fù)制到對(duì)象。它引用一個(gè)對(duì)象,并存儲(chǔ)一些其他對(duì)象指向的新對(duì)象。原始副本中所做的更改不會(huì)影響使用該對(duì)象的任何其他副本。由于為每個(gè)被調(diào)用的對(duì)象創(chuàng)建了某些副本,因此深層復(fù)制會(huì)使程序的執(zhí)行速度變慢。

3. 列表和元祖有什么不同?

主要區(qū)別在于列表是可變的,元祖是不可變的。

5. Python 中如何實(shí)現(xiàn)多線程?

線程是輕量級(jí)的進(jìn)程,多線程允許一次執(zhí)行多個(gè)線程。眾所周知,Python 是一種多線程語(yǔ)言,它有一個(gè)多線程包。

GIL(全局解釋器鎖)確保一次執(zhí)行單個(gè)線程。一個(gè)線程保存 GIL 并在將其傳遞給下一個(gè)線程之前執(zhí)行一些操作,這就產(chǎn)生了并行執(zhí)行的錯(cuò)覺(jué)。但實(shí)際上,只是線程輪流在 CPU 上。當(dāng)然,所有傳遞都會(huì)增加執(zhí)行的開(kāi)銷(xiāo)。

.8. 如何在 Python 中管理內(nèi)存?

Python 用一個(gè)私有堆內(nèi)存空間來(lái)放置所有對(duì)象和數(shù)據(jù)結(jié)構(gòu),我們無(wú)法訪問(wèn)它。由解釋器來(lái)管理它。不過(guò)使用一些核心 API,我們可以訪問(wèn)一些 Python 內(nèi)存管理工具控制內(nèi)存分配。

Python中 help()和 dir()函數(shù)的用途是什么?

答: Help()和 dir()這兩個(gè)函數(shù)都可以從Python解釋器訪問(wèn),并用于查看內(nèi)置函數(shù)的合并轉(zhuǎn)儲(chǔ)。

Help()函數(shù): help()函數(shù)用于顯示文檔字符串,還可以幫助您查看與模塊,關(guān)鍵字,屬性等相關(guān)的幫助。
Dir()函數(shù): dir()函數(shù)用于顯示定義的符號(hào)。

12. 什么是 Python 字典?

字典是我在 C++和 Java 中沒(méi)有見(jiàn)過(guò)的數(shù)據(jù)結(jié)構(gòu),它擁有鍵-值對(duì)

字典是可變的,我們也可以用推導(dǎo)式的方式創(chuàng)建它.

{25: 5, 16: 4, 9: 3, 4: 2, 1: 1}

13. 能否解釋一下 *args 和 **kwargs?

如果我們不知道將多少個(gè)參數(shù)傳遞給函數(shù),比如當(dāng)我們想傳遞一個(gè)列表或一個(gè)元組值時(shí),就可以使用*args。
當(dāng)我們不知道將會(huì)傳入多少關(guān)鍵字參數(shù)時(shí),使用**kwargs 會(huì)收集關(guān)鍵字參數(shù)。

17. 解釋 Python 中的 join() 和 split() 函數(shù)

join() 函數(shù)可以將指定的字符添加到字符串中。
split() 函數(shù)可以用指定的字符分割字符串

19. Python 中標(biāo)識(shí)符的命名規(guī)則?

Python 中的標(biāo)識(shí)符可以是任意長(zhǎng)度,但必須遵循以下命名規(guī)則:

1. 只能以下劃線或者 A-Z/a-z 中的字母開(kāi)頭。

2. 其余部分只能使用 A-Z/a-z/0-9。

3. Python 標(biāo)識(shí)符區(qū)分大小寫(xiě)。

4. 關(guān)鍵字不能作為標(biāo)識(shí)符。

21. 如何將字符串轉(zhuǎn)換為小寫(xiě)?

使用 lower() 函數(shù)
轉(zhuǎn)換為大寫(xiě)用 upper() 函數(shù)
要檢查字符串是否為全大寫(xiě)或全小寫(xiě),使用 isupper() 和 islower() 函數(shù)

23. 請(qǐng)解釋 Python 中的閉包?

如果在一個(gè)內(nèi)部函數(shù)里。對(duì)在外部作用域(但不是在全局作用域)的變量進(jìn)行引用,那么內(nèi)部函數(shù)就是一個(gè)閉包。

24. 解釋 Python 中的//,%和**運(yùn)算符

//運(yùn)算符執(zhí)行地板除法,返回結(jié)果的整數(shù)部分 (向下取整)。

用/符號(hào)除法結(jié)果為 3.5。

**符號(hào)表示取冪. a**b 返回 a 的 b 次方

% 是取模符號(hào)。返回除法后的余數(shù)。

2、迭代器和生成器的區(qū)別

迭代器
是一個(gè)更抽象的概念,任何對(duì)象,如果它的類(lèi)有next方法和iter方法返回自己本身。對(duì)于string、list、dict、tuple等這類(lèi)容器對(duì)象,使用for循環(huán)遍歷是很方便的。在后臺(tái)for語(yǔ)句對(duì)容器對(duì)象調(diào)用iter()函數(shù),iter()是python的內(nèi)置函數(shù)。iter()會(huì)返回一個(gè)定義了next()方法的迭代器對(duì)象,它在容器中逐個(gè)訪問(wèn)容器內(nèi)元素,next()也是python的內(nèi)置函數(shù)。在沒(méi)有后續(xù)元素時(shí),next()會(huì)拋出一個(gè)StopIteration異常

生成器(Generator)
是創(chuàng)建迭代器的簡(jiǎn)單而強(qiáng)大的工具。它們寫(xiě)起來(lái)就像是正規(guī)的函數(shù),只是在需要返回?cái)?shù)據(jù)的時(shí)候使用yield語(yǔ)句。每次next()被調(diào)用時(shí),生成器會(huì)返回它脫離的位置(它記憶語(yǔ)句最后一次執(zhí)行的位置和所有的數(shù)據(jù)值)

區(qū)別:
生成器能做到迭代器能做的所有事,而且因?yàn)樽詣?dòng)創(chuàng)建了__iter__()和next()方法,生成器顯得特別簡(jiǎn)潔,而且生成器也是高效的,使用生成器表達(dá)式取代列表解析可以同時(shí)節(jié)省內(nèi)存。除了創(chuàng)建和保存程序狀態(tài)的自動(dòng)方法,當(dāng)發(fā)生器終結(jié)時(shí),還會(huì)自動(dòng)拋出StopIteration異常

裝飾器的作用和功能:

引入日志

函數(shù)執(zhí)行時(shí)間統(tǒng)計(jì)

執(zhí)行函數(shù)前預(yù)備處理

執(zhí)行函數(shù)后的清理功能

權(quán)限校驗(yàn)等場(chǎng)景

緩存

簡(jiǎn)單談下GIL:

Global Interpreter Lock(全局解釋器鎖)

    Python代碼的執(zhí)行由Python 虛擬機(jī)(也叫解釋器主循環(huán),CPython版本)來(lái)控制,Python 在設(shè)計(jì)之初就考慮到要在解釋器的主循環(huán)中,同時(shí)只有一個(gè)線程在執(zhí)行,即在任意時(shí)刻,只有一個(gè)線程在解釋器中運(yùn)行。對(duì)Python 虛擬機(jī)的訪問(wèn)由全局解釋器鎖(GIL)來(lái)控制,正是這個(gè)鎖能保證同一時(shí)刻只有一個(gè)線程在運(yùn)行。

在多線程環(huán)境中,Python 虛擬機(jī)按以下方式執(zhí)行:

1. 設(shè)置GIL
2. 切換到一個(gè)線程去運(yùn)行
3. 運(yùn)行:
    a. 指定數(shù)量的字節(jié)碼指令,或者

    b. 線程主動(dòng)讓出控制(可以調(diào)用time.sleep(0))
4. 把線程設(shè)置為睡眠狀態(tài)
5. 解鎖GIL
6. 再次重復(fù)以上所有步驟

在調(diào)用外部代碼(如C/C++擴(kuò)展函數(shù))的時(shí)候,GIL 將會(huì)被鎖定,直到這個(gè)函數(shù)結(jié)束為止(由于在這期間沒(méi)有Python 的字節(jié)碼被運(yùn)行,所以不會(huì)做線程切換)。

find和grep

grep命令是一種強(qiáng)大的文本搜索工具,grep搜索內(nèi)容串可以是正則表達(dá)式,允許對(duì)文本文件進(jìn)行模式查找。如果找到匹配模式,grep打印包含模式的所有行。

find通常用來(lái)再特定的目錄下搜索符合條件的文件,也可以用來(lái)搜索特定用戶(hù)屬主的文件。

如何提高python的運(yùn)行效率

使用生成器;關(guān)鍵代碼使用外部功能包(Cython,pylnlne,pypy,pyrex);針對(duì)循環(huán)的優(yōu)化--盡量避免在循環(huán)中訪問(wèn)變量的屬性

Python中的yield用法

yield簡(jiǎn)單說(shuō)來(lái)就是一個(gè)生成器,這樣函數(shù)它記住上次返 回時(shí)在函數(shù)體中的位置。對(duì)生成器第 二次(或n 次)調(diào)用跳轉(zhuǎn)至該函 次)調(diào)用跳轉(zhuǎn)至該函 數(shù)。

描述數(shù)組、鏈表、隊(duì)列、堆棧的區(qū)別?

數(shù)組與鏈表是數(shù)據(jù)存儲(chǔ)方式的概念,數(shù)組在連續(xù)的空間中存儲(chǔ)數(shù)據(jù),而鏈表可以在非連續(xù)的空間中存儲(chǔ)數(shù)據(jù);

隊(duì)列和堆棧是描述數(shù)據(jù)存取方式的概念,隊(duì)列是先進(jìn)先出,而堆棧是后進(jìn)先出;隊(duì)列和堆??梢杂脭?shù)組來(lái)實(shí)現(xiàn),也可以用鏈表實(shí)現(xiàn)。

跨域請(qǐng)求問(wèn)題django怎么解決的(原理)

啟用中間件

post請(qǐng)求

驗(yàn)證碼

表單中添加{%csrf_token%}標(biāo)簽

請(qǐng)解釋或描述一下Django的架構(gòu)

對(duì)于Django框架遵循MVC設(shè)計(jì),并且有一個(gè)專(zhuān)有名詞:MVT

M全拼為Model,與MVC中的M功能相同,負(fù)責(zé)數(shù)據(jù)處理,內(nèi)嵌了ORM框架

V全拼為View,與MVC中的C功能相同,接收HttpRequest,業(yè)務(wù)處理,返回HttpResponse

T全拼為T(mén)emplate,與MVC中的V功能相同,負(fù)責(zé)封裝構(gòu)造要返回的html,內(nèi)嵌了模板引擎

django對(duì)數(shù)據(jù)查詢(xún)結(jié)果排序怎么做,降序怎么做,查詢(xún)大于某個(gè)字段怎么做

排序使用order_by()

降序需要在排序字段名前加-

查詢(xún)字段大于某個(gè)值:使用filter(字段名_gt=值)

說(shuō)一下Django,MIDDLEWARES中間件的作用?

中間件是介于request與response處理之間的一道處理過(guò)程,相對(duì)比較輕量級(jí),并且在全局上改變django的輸入與輸出。

你對(duì)Django的認(rèn)識(shí)?

Django是走大而全的方向,它最出名的是其全自動(dòng)化的管理后臺(tái):只需要使用起ORM,做簡(jiǎn)單的對(duì)象定義,它就能自動(dòng)生成數(shù)據(jù)庫(kù)結(jié)構(gòu)、以及全功能的管理后臺(tái)。

Django內(nèi)置的ORM跟框架內(nèi)的其他模塊耦合程度高。

應(yīng)用程序必須使用Django內(nèi)置的ORM,否則就不能享受到框架內(nèi)提供的種種基于其ORM的便利;理論上可以切換掉其ORM模塊,但這就相當(dāng)于要把裝修完畢的房子拆除重新裝修,倒不如一開(kāi)始就去毛胚房做全新的裝修。

Django的賣(mài)點(diǎn)是超高的開(kāi)發(fā)效率,其性能擴(kuò)展有限;采用Django的項(xiàng)目,在流量達(dá)到一定規(guī)模后,都需要對(duì)其進(jìn)行重構(gòu),才能滿足性能的要求。

Django適用的是中小型的網(wǎng)站,或者是作為大型網(wǎng)站快速實(shí)現(xiàn)產(chǎn)品雛形的工具。

Django模板的設(shè)計(jì)哲學(xué)是徹底的將代碼、樣式分離; Django從根本上杜絕在模板中進(jìn)行編碼、處理數(shù)據(jù)的可能。

Django重定向你是如何實(shí)現(xiàn)的?用的什么狀態(tài)碼?

使用HttpResponseRedirect

redirect和reverse

狀態(tài)碼:302,301

ngnix的正向代理與反向代理?

正向代理 是一個(gè)位于客戶(hù)端和原始服務(wù)器(origin server)之間的服務(wù)器,為了從原始服務(wù)器取得內(nèi)容,客戶(hù)端向代理發(fā)送一個(gè)請(qǐng)求并指定目標(biāo)(原始服務(wù)器),然后代理向原始服務(wù)器轉(zhuǎn)交請(qǐng)求并將獲得的內(nèi)容返回給客戶(hù)端??蛻?hù)端必須要進(jìn)行一些特別的設(shè)置才能使用正向代理。

反向代理正好相反,對(duì)于客戶(hù)端而言它就像是原始服務(wù)器,并且客戶(hù)端不需要進(jìn)行任何特別的設(shè)置??蛻?hù)端向反向代理的命名空間中的內(nèi)容發(fā)送普通請(qǐng)求,接著反向代理將判斷向何處(原始服務(wù)器)轉(zhuǎn)交請(qǐng)求,并將獲得的內(nèi)容返回給客戶(hù)端,就像這些內(nèi)容原本就是它自己的一樣。

Django 本身提供了 runserver,為什么不能用來(lái)部署?

runserver 方法是調(diào)試 Django 時(shí)經(jīng)常用到的運(yùn)行方式,它使用 Django 自帶的

WSGI Server 運(yùn)行,主要在測(cè)試和開(kāi)發(fā)中使用,并且 runserver 開(kāi)啟的方式也是單進(jìn)程 。

 uWSGI 是一個(gè) Web 服務(wù)器,它實(shí)現(xiàn)了 WSGI 協(xié)議、uwsgi、http 等協(xié)議。注意 uwsgi 是一種通信協(xié)議,而 uWSGI 是實(shí)現(xiàn) uwsgi 協(xié)議和 WSGI 協(xié)議的 Web 服務(wù)器。uWSGI 具有超快的性能、低內(nèi)存占用和多 app 管理等優(yōu)點(diǎn),并且搭配著 Nginx

就是一個(gè)生產(chǎn)環(huán)境了,能夠?qū)⒂脩?hù)訪問(wèn)請(qǐng)求與應(yīng)用 app 隔離開(kāi),實(shí)現(xiàn)真正的部署 。相比來(lái)講,支持的并發(fā)量更高,方便管理多進(jìn)程,發(fā)揮多核的優(yōu)勢(shì),提升性能。

AJAX是什么,如何使用AJAX?

ajax(異步的javascript 和xml) 能夠刷新局部網(wǎng)頁(yè)數(shù)據(jù)而不是重新加載整個(gè)網(wǎng)頁(yè)。

第一步,創(chuàng)建xmlhttprequest對(duì)象,var xmlhttp =new XMLHttpRequest();XMLHttpRequest對(duì)象用來(lái)和服務(wù)器交換數(shù)據(jù)。

第二步,使用xmlhttprequest對(duì)象的open()和send()方法發(fā)送資源請(qǐng)求給服務(wù)器。

第三步,使用xmlhttprequest對(duì)象的responseText或responseXML屬性獲得服務(wù)器的響應(yīng)。

第四步,onreadystatechange函數(shù),當(dāng)發(fā)送請(qǐng)求到服務(wù)器,我們想要服務(wù)器響應(yīng)執(zhí)行一些功能就需要使用onreadystatechange函數(shù),每次xmlhttprequest對(duì)象的readyState發(fā)生改變都會(huì)觸發(fā)onreadystatechange函數(shù)。

POST和GET的區(qū)別

GET請(qǐng)求,請(qǐng)求的數(shù)據(jù)會(huì)附加在URL之后,以?分割URL和傳輸數(shù)據(jù),多個(gè)參數(shù)用&連接。URL的編碼格式采用的是ASCII編碼,而不是uniclde,即是說(shuō)所有的非ASCII字符都要編碼之后再傳輸。

POST請(qǐng)求:POST請(qǐng)求會(huì)把請(qǐng)求的數(shù)據(jù)放置在HTTP請(qǐng)求包的包體中。上面的item=bandsaw就是實(shí)際的傳輸數(shù)據(jù)。

因此,GET請(qǐng)求的數(shù)據(jù)會(huì)暴露在地址欄中,而POST請(qǐng)求則不會(huì)。

傳輸數(shù)據(jù)的大小

在HTTP規(guī)范中,沒(méi)有對(duì)URL的長(zhǎng)度和傳輸?shù)臄?shù)據(jù)大小進(jìn)行限制。但是在實(shí)際開(kāi)發(fā)過(guò)程中,對(duì)于GET,特定的瀏覽器和服務(wù)器對(duì)URL的長(zhǎng)度有限制。因此,在使用GET請(qǐng)求時(shí),傳輸數(shù)據(jù)會(huì)受到URL長(zhǎng)度的限制。

對(duì)于POST,由于不是URL傳值,理論上是不會(huì)受限制的,但是實(shí)際上各個(gè)服務(wù)器會(huì)規(guī)定對(duì)POST提交數(shù)據(jù)大小進(jìn)行限制,Apache、IIS都有各自的配置。

安全性

POST的安全性比GET的高。這里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全僅僅是不修改服務(wù)器的數(shù)據(jù)。比如,在進(jìn)行登錄操作,通過(guò)GET請(qǐng)求,用戶(hù)名和密碼都會(huì)暴露再URL上,因?yàn)榈卿涰?yè)面有可能被瀏覽器緩存以及其他人查看瀏覽器的歷史記錄的原因,此時(shí)的用戶(hù)名和密碼就很容易被他人拿到了。除此之外,GET請(qǐng)求提交的數(shù)據(jù)還可能會(huì)造成Cross-site request frogery攻擊。

cookie 和session 的區(qū)別?

1、cookie數(shù)據(jù)存放在客戶(hù)的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。

2、cookie不是很安全,別人可以分析存放在本地的COOKIE并進(jìn)行COOKIE欺騙考慮到安全應(yīng)當(dāng)使用session。

3、session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問(wèn)增多,會(huì)比較占用服務(wù)器的性能考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用COOKIE。

4、單個(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。

創(chuàng)建一個(gè)簡(jiǎn)單tcp服務(wù)器需要的流程

1.socket創(chuàng)建一個(gè)套接字

2.bind綁定ip和port

3.listen使套接字變?yōu)榭梢员粍?dòng)鏈接

4.accept等待客戶(hù)端的鏈接

5.recv/send接收發(fā)送數(shù)據(jù)

scrapy和scrapy-redis有什么區(qū)別?為什么選擇redis數(shù)據(jù)庫(kù)?

1) scrapy是一個(gè)Python爬蟲(chóng)框架,爬取效率極高,具有高度定制性,但是不支持分布式。而scrapy-redis一套基于redis數(shù)據(jù)庫(kù)、運(yùn)行在scrapy框架之上的組件,可以讓scrapy支持分布式策略,Slaver端共享Master端redis數(shù)據(jù)庫(kù)里的item隊(duì)列、請(qǐng)求隊(duì)列和請(qǐng)求指紋集合。

2) 為什么選擇redis數(shù)據(jù)庫(kù),因?yàn)閞edis支持主從同步,而且數(shù)據(jù)都是緩存在內(nèi)存中的,所以基于redis的分布式爬蟲(chóng),對(duì)請(qǐng)求和數(shù)據(jù)的高頻讀取效率非常高。

你用過(guò)的爬蟲(chóng)框架或者模塊有哪些?談?wù)勊麄兊膮^(qū)別或者優(yōu)缺點(diǎn)?

Python自帶:urllib,urllib2

第 三 方:requests

框 架:Scrapy

urllib和urllib2模塊都做與請(qǐng)求URL相關(guān)的操作,但他們提供不同的功能。

urllib2.:urllib2.urlopen可以接受一個(gè)Request對(duì)象或者url,(在接受Request對(duì)象時(shí)候,并以此可以來(lái)設(shè)置一個(gè)URL 的headers),urllib.urlopen只接收一個(gè)url

urllib 有urlencode,urllib2沒(méi)有,因此總是urllib,urllib2常會(huì)一起使用的原因
scrapy是封裝起來(lái)的框架,他包含了下載器,解析器,日志及異常處理,基于多線程, twisted的方式處理,對(duì)于固定單個(gè)網(wǎng)站的爬取開(kāi)發(fā),有優(yōu)勢(shì),但是對(duì)于多網(wǎng)站爬取 100個(gè)網(wǎng)站,并發(fā)及分布式處理方面,不夠靈活,不便調(diào)整與括展。
request 是一個(gè)HTTP庫(kù), 它只是用來(lái),進(jìn)行請(qǐng)求,對(duì)于HTTP請(qǐng)求,他是一個(gè)強(qiáng)大的庫(kù),下載,解析全部自己處理,靈活性更高,高并發(fā)與分布式部署也非常靈活,對(duì)于功能可以更好實(shí)現(xiàn).

Scrapy優(yōu)缺點(diǎn):

優(yōu)點(diǎn):scrapy 是異步的

采取可讀性更強(qiáng)的xpath代替正則

強(qiáng)大的統(tǒng)計(jì)和log系統(tǒng)

同時(shí)在不同的url上爬行

支持shell方式,方便獨(dú)立調(diào)試

寫(xiě)middleware,方便寫(xiě)一些統(tǒng)一的過(guò)濾器

通過(guò)管道的方式存入數(shù)據(jù)庫(kù)

缺點(diǎn):

基于python的爬蟲(chóng)框架,擴(kuò)展性比較差

基于twisted框架,運(yùn)行中的exception是不會(huì)干掉reactor,并且異步框架出錯(cuò)后是不會(huì)停掉其他任務(wù)的,數(shù)據(jù)出錯(cuò)后難以察覺(jué)。

你常用的mysql引擎有哪些?各引擎間有什么區(qū)別?

主要 MyISAM 與 InnoDB 兩個(gè)引擎,其主要區(qū)別如下:

一、InnoDB 支持事務(wù),MyISAM 不支持,這一點(diǎn)是非常之重要。事務(wù)是一種高

級(jí)的處理方式,如在一些列增刪改中只要哪個(gè)出錯(cuò)還可以回滾還原,而 MyISAM

就不可以了;

二、MyISAM 適合查詢(xún)以及插入為主的應(yīng)用,InnoDB 適合頻繁修改以及涉及到

安全性較高的應(yīng)用;

三、InnoDB 支持外鍵,MyISAM 不支持;

四、MyISAM 是默認(rèn)引擎,InnoDB 需要指定;

五、InnoDB 不支持 FULLTEXT 類(lèi)型的索引;

六、InnoDB 中不保存表的行數(shù),如 select count(*) from table 時(shí),InnoDB;需要

掃描一遍整個(gè)表來(lái)計(jì)算有多少行,但是 MyISAM 只要簡(jiǎn)單的讀出保存好的行數(shù)即

可。注意的是,當(dāng) count(*)語(yǔ)句包含 where 條件時(shí) MyISAM 也需要掃描整個(gè)表;

七、對(duì)于自增長(zhǎng)的字段,InnoDB 中必須包含只有該字段的索引,但是在 MyISAM

表中可以和其他字段一起建立聯(lián)合索引;

八、清空整個(gè)表時(shí),InnoDB 是一行一行的刪除,效率非常慢。MyISAM 則會(huì)重

建表;

九、InnoDB 支持行鎖(某些情況下還是鎖整表,如 update table set a=1 where

user like '%lee%'

描述下scrapy框架運(yùn)行的機(jī)制?

從start_urls里獲取第一批url并發(fā)送請(qǐng)求,請(qǐng)求由引擎交給調(diào)度器入請(qǐng)求隊(duì)列,獲取完畢后,調(diào)度器將請(qǐng)求隊(duì)列里的請(qǐng)求交給下載器去獲取請(qǐng)求對(duì)應(yīng)的響應(yīng)資源,并將響應(yīng)交給自己編寫(xiě)的解析方法做提取處理:1. 如果提取出需要的數(shù)據(jù),則交給管道文件處理;2. 如果提取出url,則繼續(xù)執(zhí)行之前的步驟(發(fā)送url請(qǐng)求,并由引擎將請(qǐng)求交給調(diào)度器入隊(duì)列...),直到請(qǐng)求隊(duì)列里沒(méi)有請(qǐng)求,程序結(jié)束。

什么是關(guān)聯(lián)查詢(xún),有哪些?

將多個(gè)表聯(lián)合起來(lái)進(jìn)行查詢(xún),主要有內(nèi)連接、左連接、右連接、全連接(外連接)

寫(xiě)爬蟲(chóng)是用多進(jìn)程好?還是多線程好? 為什么?

IO密集型代碼(文件處理、網(wǎng)絡(luò)爬蟲(chóng)等),多線程能夠有效提升效率(單線程下有IO操作會(huì)進(jìn)行IO等待,造成不必要的時(shí)間浪費(fèi),而開(kāi)啟多線程能在線程A等待時(shí),自動(dòng)切換到線程B,可以不浪費(fèi)CPU的資源,從而能提升程序執(zhí)行效率)。在實(shí)際的數(shù)據(jù)采集過(guò)程中,既考慮網(wǎng)速和響應(yīng)的問(wèn)題,也需要考慮自身機(jī)器的硬件情況,來(lái)設(shè)置多進(jìn)程或多線程

常見(jiàn)的反爬蟲(chóng)和應(yīng)對(duì)方法?

1).通過(guò)Headers反爬蟲(chóng)

從用戶(hù)請(qǐng)求的Headers反爬蟲(chóng)是最常見(jiàn)的反爬蟲(chóng)策略。很多網(wǎng)站都會(huì)對(duì)Headers的User-Agent進(jìn)行檢測(cè),還有一部分網(wǎng)站會(huì)對(duì)Referer進(jìn)行檢測(cè)(一些資源網(wǎng)站的防盜鏈就是檢測(cè)Referer)。如果遇到了這類(lèi)反爬蟲(chóng)機(jī)制,可以直接在爬蟲(chóng)中添加Headers,將瀏覽器的User-Agent復(fù)制到爬蟲(chóng)的Headers中;或者將Referer值修改為目標(biāo)網(wǎng)站域名。對(duì)于檢測(cè)Headers的反爬蟲(chóng),在爬蟲(chóng)中修改或者添加Headers就能很好的繞過(guò)。

2).基于用戶(hù)行為反爬蟲(chóng)

還有一部分網(wǎng)站是通過(guò)檢測(cè)用戶(hù)行為,例如同一IP短時(shí)間內(nèi)多次訪問(wèn)同一頁(yè)面,或者同一賬戶(hù)短時(shí)間內(nèi)多次進(jìn)行相同操作。

大多數(shù)網(wǎng)站都是前一種情況,對(duì)于這種情況,使用IP代理就可以解決??梢詫?zhuān)門(mén)寫(xiě)一個(gè)爬蟲(chóng),爬取網(wǎng)上公開(kāi)的代理ip,檢測(cè)后全部保存起來(lái)。這樣的代理ip爬蟲(chóng)經(jīng)常會(huì)用到,最好自己準(zhǔn)備一個(gè)。有了大量代理ip后可以每請(qǐng)求幾次更換一個(gè)ip,這在requests或者urllib2中很容易做到,這樣就能很容易的繞過(guò)第一種反爬蟲(chóng)。

對(duì)于第二種情況,可以在每次請(qǐng)求后隨機(jī)間隔幾秒再進(jìn)行下一次請(qǐng)求。有些有邏輯漏洞的網(wǎng)站,可以通過(guò)請(qǐng)求幾次,退出登錄,重新登錄,繼續(xù)請(qǐng)求來(lái)繞過(guò)同一賬號(hào)短時(shí)間內(nèi)不能多次進(jìn)行相同請(qǐng)求的限制。

3).動(dòng)態(tài)頁(yè)面的反爬蟲(chóng)

上述的幾種情況大多都是出現(xiàn)在靜態(tài)頁(yè)面,還有一部分網(wǎng)站,我們需要爬取的數(shù)據(jù)是通過(guò)ajax請(qǐng)求得到,或者通過(guò)JavaScript生成的。首先用Fiddler對(duì)網(wǎng)絡(luò)請(qǐng)求進(jìn)行分析。如果能夠找到ajax請(qǐng)求,也能分析出具體的參數(shù)和響應(yīng)的具體含義,我們就能采用上面的方法,直接利用requests或者urllib2模擬ajax請(qǐng)求,對(duì)響應(yīng)的json進(jìn)行分析得到需要的數(shù)據(jù)。

能夠直接模擬ajax請(qǐng)求獲取數(shù)據(jù)固然是極好的,但是有些網(wǎng)站把a(bǔ)jax請(qǐng)求的所有參數(shù)全部加密了。我們根本沒(méi)辦法構(gòu)造自己所需要的數(shù)據(jù)的請(qǐng)求。這種情況下就用selenium+phantomJS,調(diào)用瀏覽器內(nèi)核,并利用phantomJS執(zhí)行js來(lái)模擬人為操作以及觸發(fā)頁(yè)面中的js腳本。從填寫(xiě)表單到點(diǎn)擊按鈕再到滾動(dòng)頁(yè)面,全部都可以模擬,不考慮具體的請(qǐng)求和響應(yīng)過(guò)程,只是完完整整的把人瀏覽頁(yè)面獲取數(shù)據(jù)的過(guò)程模擬一遍。

用這套框架幾乎能繞過(guò)大多數(shù)的反爬蟲(chóng),因?yàn)樗皇窃趥窝b成瀏覽器來(lái)獲取數(shù)據(jù)(上述的通過(guò)添加 Headers一定程度上就是為了偽裝成瀏覽器),它本身就是瀏覽器,phantomJS就是一個(gè)沒(méi)有界面的瀏覽器,只是操控這個(gè)瀏覽器的不是人。利selenium+phantomJS能干很多事情,例如識(shí)別點(diǎn)觸式(12306)或者滑動(dòng)式的驗(yàn)證碼,對(duì)頁(yè)面表單進(jìn)行暴力破解等。

分布式爬蟲(chóng)主要解決什么問(wèn)題?

1)ip

2)帶寬

3)cpu

4)io

列出5個(gè)python標(biāo)準(zhǔn)庫(kù)

os:提供了不少與操作系統(tǒng)相關(guān)聯(lián)的函數(shù)

sys:   通常用于命令行參數(shù)

re:   正則匹配

math: 數(shù)學(xué)運(yùn)算

datetime:處理日期時(shí)間

python2和python3的range(100)的區(qū)別

python2返回列表,python3返回迭代器,節(jié)約內(nèi)存

python內(nèi)建數(shù)據(jù)類(lèi)型有哪些

整型--int

布爾型--bool

字符串--str

列表--list

元組--tuple

字典--dict

簡(jiǎn)述面向?qū)ο笾?strong>new和init區(qū)別

__init__是初始化方法,創(chuàng)建對(duì)象后,就立刻被默認(rèn)調(diào)用了,可接收參數(shù).
1、__new__至少要有一個(gè)參數(shù)cls,代表當(dāng)前類(lèi),此參數(shù)在實(shí)例化時(shí)由Python解釋器自動(dòng)識(shí)別

2、__new__必須要有返回值,返回實(shí)例化出來(lái)的實(shí)例,這點(diǎn)在自己實(shí)現(xiàn)__new__時(shí)要特別注意,可以return父類(lèi)(通過(guò)super(當(dāng)前類(lèi)名, cls))__new__出來(lái)的實(shí)例,或者直接是object的__new__出來(lái)的實(shí)例

3、__init__有一個(gè)參數(shù)self,就是這個(gè)__new__返回的實(shí)例,__init__在__new__的基礎(chǔ)上可以完成一些其它初始化的動(dòng)作,__init__不需要返回值

4、如果__new__創(chuàng)建的是當(dāng)前類(lèi)的實(shí)例,會(huì)自動(dòng)調(diào)用__init__函數(shù),通過(guò)return語(yǔ)句里面調(diào)用的__new__函數(shù)的第一個(gè)參數(shù)是cls來(lái)保證是當(dāng)前類(lèi)實(shí)例,如果是其他類(lèi)的類(lèi)名,;那么實(shí)際創(chuàng)建返回的就是其他類(lèi)的實(shí)例,其實(shí)就不會(huì)調(diào)用當(dāng)前類(lèi)的__init__函數(shù),也不會(huì)調(diào)用其他類(lèi)的__init__函數(shù)。

python2和python3區(qū)別?列舉5個(gè)

1、Python3 使用 print 必須要以小括號(hào)包裹打印內(nèi)容,比如 print('hi')

Python2 既可以使用帶小括號(hào)的方式,也可以使用一個(gè)空格來(lái)分隔打印內(nèi)容,比如 print 'hi'

2、python2 range(1,10)返回列表,python3中返回迭代器,節(jié)約內(nèi)存

3、python2中使用ascii編碼,python中使用utf-8編碼

4、python2中unicode表示字符串序列,str表示字節(jié)序列

      python3中str表示字符串序列,byte表示字節(jié)序列

5、python2中為正常顯示中文,引入coding聲明,python3中不需要

6、python2中是raw_input()函數(shù),python3中是input()函數(shù)

Python解釋“re”模塊的 split(), sub(), subn()方法。

答: 要修改字符串,Python的“re”模塊提供了3種方法。他們是:

split() - 使用正則表達(dá)式將“split”給定字符串放入列表中。
sub() - 查找正則表達(dá)式模式匹配的所有子字符串,然后用不同的字符串替換它們
subn() - 它類(lèi)似于 sub(),并且還返回新字符串和替換的序號(hào)。

range和xrange之間有什么區(qū)別?

答: 在大多數(shù)情況下,xrange和range在功能方面完全相同,它們都提供了一種生成整數(shù)列表供您使用的方法。唯一的區(qū)別是range返回一個(gè)Python列表對(duì)象,x range返回一個(gè)xrange對(duì)象。

這意味著xrange實(shí)際上并不像run-time那樣生成靜態(tài)列表。它使用稱(chēng)為yielding的特殊技術(shù)根據(jù)需要?jiǎng)?chuàng)建值。該技術(shù)與一種稱(chēng)為生成器的對(duì)象一起使用。這意味著,如果你有一個(gè)非常巨大的范圍,你想生成一個(gè)列表,比如10億,xrange就是要使用的功能。

如果你有一個(gè)真正的內(nèi)存敏感系統(tǒng),例如你正在使用的手機(jī),尤其如此,因?yàn)閞ange將使用盡可能多的內(nèi)存來(lái)創(chuàng)建整數(shù)數(shù)組,這可能導(dǎo)致內(nèi)存錯(cuò)誤并導(dǎo)致崩潰程序。

解釋在Django框架中使用session?

答: Django提供的會(huì)話允許您在per-site-visitor的基礎(chǔ)上存儲(chǔ)和檢索數(shù)據(jù)。 Django通過(guò)在客戶(hù)端放置會(huì)話ID cookie并在服務(wù)器端存儲(chǔ)所有相關(guān)數(shù)據(jù)來(lái)抽象發(fā)送和接收cookie的過(guò)程。

什么是Python中的map函數(shù)?

答: Map函數(shù)執(zhí)行作為第一個(gè)參數(shù)給出的函數(shù),該函數(shù)遍歷第二個(gè)參數(shù)給出的迭代的所有元素的。如果給定的函數(shù)包含多于1個(gè)參數(shù),則給出了許多迭代。

解釋裝飾器的用法。

答: Python中的裝飾器用于修改或注入函數(shù)或類(lèi)中的代碼。使用裝飾器,您可以包裝類(lèi)或函數(shù)方法調(diào)用,以便在執(zhí)行原始代碼之前或之后執(zhí)行一段代碼。裝飾器可用于檢查權(quán)限,修改或跟蹤傳遞給方法的參數(shù),將調(diào)用記錄到特定方法等。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容