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)用記錄到特定方法等。