html
new是一個靜態方法,init是一個實例方法new返回一個建立的實例,init什麼都不返回new返回一個cls的實例時後面的init才能被調用當建立一個新實例時調用new,初始化一個實例時調用initpython
二、深淺拷貝linux
淺拷貝只是增長了一個指針指向一個存在的地址,而深拷貝是增長一個指針而且開闢了新的內存,這個增長的指針指向這個新的內存,採用淺拷貝的狀況,釋放內存,會釋放同一內存,深拷貝就不會出現釋放同一內存的錯誤git
三、HTTP/IP相關協議,分別位於哪層程序員
http協議是超文本傳輸協議,http協議是基於TCP/IP通訊協議來傳遞數據http協議工做與c/s架構上,瀏覽器做爲http的客戶端經過URL向http服務端即web服務器發送所用請求。web服務器收到全部請求後,向客戶端發送響應信息,http特色是短鏈接,無狀態地址欄鍵輸入URL,按下回車以後經歷了什麼?1.瀏覽器向DNS服務器請求解析該URL中的域名所對應的IP地址2.解析出IP地址後,根據IP地址和默認端口80,和服務器創建TCP鏈接3.瀏覽器發出讀取文件的http請求,該請求報文做爲TCP三次握手的第三個報文的數據發送給服務器4.服務器對瀏覽器請求作出響應,並把對應的html文件發送給瀏覽器5.釋放TCP鏈接6.瀏覽器將該HMTL渲染並顯示內容web
四、TCP/UDP區別ajax
TCP協議是面向鏈接,保證高可靠性(數據無丟失,數據無失序,數據無錯誤,數據無重複達到)傳輸層協議UDP:數據丟失,無秩序的傳輸層協議(qq基於udp協議)正則表達式
五、webscoketredis
websocket是基於http協議的,可持續化鏈接輪詢:瀏覽器每隔幾秒就發送一次請求,詢問服務器是否有新消息長輪詢:客戶端發起鏈接後,若是沒有消息,就一直不返回response給客戶端,直到有消息返回,返回完以後,客戶端再次發起鏈接算法
六、RabbitMQ:
服務器端有Erlang語言來編寫,支持多種客戶端,只會ajax,用於分佈式系統中存儲轉發消息,在易用性、擴展性、高可用性的方面不俗。connection是RabbitMQ的socket鏈接,它封裝了socket部分相關協議邏輯connectionFactroy爲connection的製造工廠channel是咱們與RabbitMQ打交道的最重要的一個接口,大部分的業務操做是在chaanel這個接口中完成,包括定義Queue、定義Exchange、綁定Queue與Exchange,發佈消息等
七、裝飾器
調用裝飾器實際上是一個閉包函數,爲其餘函數添加附加功能,不修改被修改的源代碼和不修改被修飾的方式,裝飾器的返回值也是一個函數對象。好比:插入日誌、性能測試、事物處理、緩存、權限驗證等,有了裝飾器,就能夠抽離出大量與函數功能自己無關的雷同代碼並繼續重用。八、閉包
1.必須有一個內嵌函數2.內嵌函數必須引用外部函數的變量(該函數包含對外做用域而不是全局做用域名字的引用)3.外部函數的返回值必須是內嵌函數
九、迭代器與生成器
迭代器:迭代可迭代對象對應iter(方法)和迭代器對應next(方法)的一個過程
在後臺 for 語句 對容器象調用 iter()函數。iter()是 python 的內置函數,iter() 會返回一個定義 next()方法的迭代器對象,它在容器中逐個訪問容器內元素,next()也是 python 的內置函數。在沒有後續元素時, next()會 拋出一個 StopIter 異常。
生成器:包括含有yield這個關鍵字,生成器也是迭代器,調動next把函數變成迭代器。
須要返回數據時候使用 yield 語 句。每次 next()被調用,生成器會返回它脫離的位置,記憶語句最 後一次執行和全部數據。
區別:生成器能作到迭代的全部事 ,並且由於自動建立了 iter()和 next()方法 ,生成器顯得特別簡潔 ,並且生成器也是 高效的 ,使用生成器表達式取代列解析能夠同時節省內存。除了建立和保程序狀態的自動方法,當發生器終結時 ,還會自動拋出 StopIteration 異常。
十、classmethod,staticmethod,property
類方法:將類的函數轉換成類方法,函數上裝飾@classmethod會將函數的自動傳值參數改爲cls靜態方法:此方法至關於給類擴展一個功能,將類內的函數實例化,給類或對象使用,此時類內的函數就是普通函數,無論是類仍是實例化的對象均可以使用實例化:類的實例化就會產生一個實例(對象),能夠理解爲類()把虛擬的東西實例化,獲得具體存在的值十一、經常使用的狀態碼
200--服務器成功返回網頁204--請求收到,但返回信息爲空304--客戶端已經執行了GET,但文件未變化400--錯誤請求,如語法錯誤403--無權限訪問404--請求的頁面不存在500--服務器產生內部錯誤十二、多進程,多線程,協程,GIL
GIL:全局解釋器鎖,是鎖在cpython解釋器上,致使同一時刻,同一進程只能有一個線程被執行多進程:多進程模塊multiprocessing來實現,cpu密集型,IO計算型能夠用多進程多線程:多線程模塊threading來實現,IO密集型(IO:輸入輸出),多線程能夠提升效率
GIL 對多線程的影響?
每一個CPU在同一時間只能執行一個線程,在 Python 多線程下,每一個線程的執行方式:
獲取 GIL
執行代碼直到 sleep 或者是 python 虛擬機將其掛起。
釋放 GIL 可見,某個線程想要執行,必須先拿到 GIL,咱們能夠把 GIL 看 做是「通行證」,而且在一個 python 進程中,GIL 只有一個。拿不 到通行證的線程,就不容許進入 CPU 執行。 在 Python2.x 裏,GIL 的釋放邏輯是當前線程碰見 IO 操做或者 ticks 計數達到 100(ticks 能夠看做是 Python 自身的一個計數器, 專門作用於 GIL,每次釋放後歸零,這個計數能夠經過 sys.setcheckinterval 來調整),進行釋放。而每次釋放 GIL 鎖, 線程進行鎖競爭、切換線程,會消耗資源。而且因爲 GIL 鎖存在, python 裏一個進程永遠只能同時執行一個線程(拿到 GIL 的線程才能 執行)。 IO 密集型代碼(文件處理、網絡爬蟲等),多線程可以有效提高 效率(單線程下有 IO 操做會進行 IO 等待,形成沒必要要的時間浪費, 而開啓多線程能在線程 A 等待時,自動切換到線程 B,能夠不浪費 CPU 的資源,從而能提高程序執行效率),因此多線程對 IO 密集型代碼比 較友好。
併發:併發是指兩個或多個事件在同一時間間隔內發生,同時能夠容納任務的極限
並行:並行是指兩個或者多個事件在同一時刻發生,同時事件所能同時進行極限,好比6核能夠真正同時進行6個進程
在單核 CPU 下的多線程其實都只是併發, 不是並行,併發和並行從宏觀上來說都是同時處理多路請求的概念。
協程:又稱纖程,python在一個線程當中完成輪詢。依賴於geenlet,對於多線程應用。協程是一種用戶態的輕量級線程,調度徹底由用戶控制。 協程擁有本身的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其餘地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操做棧則基本沒有內核切換的開銷,能夠不加鎖的訪問全局變量,因此上下文的切換很是快。進程:是資源管理單位,進程是相互獨立的佔用獨立內存,是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,上下文進程間的切換開銷(棧、 寄存器、虛擬內存、文件句柄等)比較大,但相對比較穩定安全。python能夠同時開啓多個進程。線程:線程是進程的一個實體,是CPU調度的最小執行單位,線程的出現爲了下降上下文切換的消耗,提供系統的併發性,不一樣進程經過進程間通訊來通訊。線程本身基本上不擁有系統 資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存 器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源。線程間通訊主要經過共享內存,上下文切換很快,資源開 銷較少,但相比進程不夠穩定容易丟失數據。python一個進程只能同時開啓一個線程,多個線程輪詢。
python 的多進程與多線程的運行機制是什麼?有什麼區別? 分別在什麼狀況下用?
運行機制:進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是 系統進行資源分配和調度的一個獨立單位 線程是進程的一個實體,是 CPU 調度和分派的基本單位,它是比進程更小的能獨立 運行的基本單位.線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源 (若是製造數據的速度時快時慢,緩衝區的好處就體現出來了。當數據製造快的時候,消費者來不及處理,未處理的數據能夠暫時存在緩衝區中。 程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有 的所有資源.
區別: 多進程穩定性好,一個子進程崩潰了,不會影響主進程以及其他進程。可是缺點是創 建進程的代價很是大,由於操做系統要給每一個進程分配固定的資源,而且,操做系統對進 程的總數會有必定的限制,若進程過多,操做系統調度都會存在問題,會形成假死狀態。 多線程效率較高一些,可是致命的缺點是任何一個線程崩潰均可能形成整個進程的崩 潰,由於它們共享了進程的內存資源池。
使用狀況:若是代碼是 IO 密集型——多線程。
若是代碼是 CPU 密集型的——多進程是更好的選擇,特別是計算密集型所使用的機器是多核或多CPU的。
1三、IO多路複用/異步非阻塞
IO多路複用:經過一種機制,能夠監聽多個描述符 select/poll/epollselect:鏈接數受限,查找配對速度慢,數據由內核拷貝到用戶態poll:改善了鏈接數,可是仍是查找配對速度慢,數據由內核拷貝到用戶態epoll:epoll是linux下多路複用IO接口,是select/poll的加強版,它能顯著提升程序在大量併發鏈接中只有少許活躍的狀況下的系統CPU利用率異步非阻塞:異步體如今回調上,回調就是有消息返回時告知一聲兒進程進行處理。非阻塞就是不等待,不須要進程等待下去,繼續執行其餘操做,無論其餘進程的狀態。
談談你對同步異步阻塞非阻塞理解?
同步:在發出一個功能調用時,在沒有獲得結果以前,該調用就不返回。絕大多數函數都是同步調用(例 如 sin, isdigit 等)。
異步:異步的概念和同步相對。當一個異步過程調用發出後,調用者不能馬上獲得結果。實際處理這個調用的部件在完成後,經過狀態、通知 和回調來通知調用者。
以 CAsycSocket 類爲例(注意,CSocket 從 CAsyncSocket 派生,可是起功能已經由異步轉化爲同步),當一個 客戶端經過調用 Connect 函數發出一個鏈接請求後,調用者線程立 刻能夠朝下運行。當鏈接真正創建起來之後,socket 底層會發送一 個消息通知該對象。這裏提到執行部件和調用者經過三種途徑返回結 果:狀態、通知和回調。可使用哪種依賴於執行部件的實現,除 非執行部件提供多種選擇,不然不受調用者控制。若是執行部件用狀 態來通知,那麼調用者就須要每隔必定時間檢查一次,效率就很低。若是是使用通知的方式,效率則很高, 由於執行部件幾乎不須要作額外的操做。至於回調函數,其實和通知沒太多區別。
阻塞調用:是指調用結果返回以前,當前線程會被掛起。函數只有在 獲得結果以後纔會返回。
實際上阻塞調用和同步調用是不一樣的。對於同步調用來講,不少時候當前線程仍是激活的,只是從邏輯上當前函數沒有返回而已。
例如,咱們在 CSocket 中 調用 Receive 函數,若是緩衝區中沒有數據,這個函數就會一直等待, 直到有數據才返回。而此時,當前線程還會繼續處理各類各樣的消息。 若是主窗口和調用函數在同一個線程中,除非你在特殊的界面操做函 數中調用,其實主界面仍是應該能夠刷新。socket 接收數據的另外 一個函數 recv 則是一個阻塞調用的例子。當 socket 工做在阻塞模式 的時候,若是沒有數據的狀況下調用該函數,則當前線程就會被掛起, 直到有數據爲止。
非阻塞調用:非阻塞和阻塞的概念相對應,指在不能馬上獲得結果以前,該函數不會阻塞當前線程,而會馬上返回。
對象的阻塞模式和阻塞函數調用:對象是否處於阻塞模式和函數是否是阻塞調用有很強的相關性,可是並非一一對應的。阻塞對象上 能夠有非阻塞的調用方式,咱們能夠經過必定的 API 去輪詢狀態,在適當的時候調用阻塞函數,就能夠避免阻塞。而對於非阻塞對象,調 用特殊的函數也能夠進入阻塞調用。函數 select 就是這樣的一個例子。
1四、PEP8規範是什麼?
變量:
常量:大寫加下劃線 USER_CONSTANT 私有變量 : 小寫和一個前導下劃線 _private_value Python 中不存在私有變量一說,如果遇到須要保護的變量,使用小寫和一個前導下劃線。內置變量 : 小寫,兩個前導下劃線和兩個後置下劃線 class 兩個前導下劃線會致使變量在解釋期間被改名。這是爲了不內置變量和 其餘變量產生衝突。
函數和方法:
整體而言應該使用小寫和下劃線。但有些比較老的庫使用的是混合大小寫, 即首單詞小寫,以後每一個單詞第一個字母大寫,其他小寫。但如今,小寫和下劃 線已成爲規範。 私有方法 :小寫和一個前導下劃線 def _secrete(self): print "don't test me." 這裏和私有變量同樣,並非真正的私有訪問權限。同時也應該注意通常函 數不要使用兩個前導下劃線(當遇到兩個前導下劃線時,Python 的名稱改編特性 將發揮做用)。 特殊方法 :小寫和兩個前導下劃線,兩個後置下劃線 def add(self, other): return int.add(other) 這種風格只應用於特殊函數,好比操做符重載等。 函數參數 : 小寫和下劃線,缺省值等號兩邊無空格
類:
類老是使用駝峯格式命名,即全部單詞首字母大寫其他字母小寫。類名應該簡明,精確,並足以從中理解類所完成的工做。常見的一個方法是使用表示其類 型或者特性的後綴,例如: SQLEngine,MimeTypes 對於基類而言,可使用一個 Base 或者 Abstract 前 綴 BaseCookie,AbstractGroup
模塊和包:
除特殊模塊 init 以外,模塊名稱都使用不帶下劃線的小寫字母。 如果它們實現一個協議,那麼一般使用 lib 爲後綴,例如: import smtplib import os import sys
關於參數:
不要用斷言來實現靜態類型檢測。斷言能夠用於檢查參數,但不該僅僅是進 行靜態類型檢測。 Python 是動態類型語言,靜態類型檢測違背了其設計思想。斷言應該用於避免函數不被毫無心義的調用。
不要濫用 args 和 **kwargs。args 和 **kwargs 參數可能會破壞函數的健壯性。它們使簽名變得模糊,並且代碼經常開始在不該該的地方構建小的參數解析器。
其餘:
使用 has 或 is 前綴命名布爾元素 is_connect = True has_member = False
用複數形式命名序列 members = ['user_1', 'user_2']
用顯式名稱命名字典 person_address = {'user_1':'10 road WD', 'user_2' : '20 street huafu'}
避免通用名稱 諸如 list, dict, sequence 或者 element 這樣的名稱應該避免。
避免現有名稱 諸如 os, sys 這種系統已經存在的名稱應該避免。
一些數字 一行列數 : PEP 8 規定爲 79 列。根據本身的狀況,好比不要超過滿屏時編輯 器的顯示列數。 一個函數 : 不要超過 30 行代碼, 便可顯示在一個屏幕類,能夠不使用垂直遊 標便可看到整個函數。 一個類 : 不要超過 200 行代碼,不要有超過 10 個方法。一個模塊不要超 過 500 行。
驗證腳本 能夠安裝一個 pep8 腳本用於驗證你的代碼風格是否符合 PEP8。
1五、range-and-xrange
都在循環時使用,xrange內存性能更好,xrange用法與range徹底相同,range一個生成list對象,xrange是生成器
1六、with上下文機制原理
enter和exit,上下文管理協議,即with語句,爲了讓一個對象兼容with語句,必須在這個對象類中聲明enter和exit方法,使用with語句的目的就是把代碼塊放入with中執行,with結束後,自動完成清理工做,無須受到干預
1七、經典類、新式類
經典類遵循:深度優先,python2中新式類遵循:廣度優先,Python3中
1八、有沒有一個工具能夠幫助查找Python的bug和進行靜態的代碼分析?
PyChecker是一個Python代碼的靜態分析工具,它能夠幫助查找Python代碼的bug,會對代碼的複雜度和格式提出警告,Pylint是另一個工具能夠進行codingstandard檢查 1九、 Python是如何進行內存管理的
1.對象引用計數:引用計數增長的狀況:來保持追蹤內存中的對象,全部對象都用引用計數,一個對象分配一個新名稱將其放入一個容器中(列表,字典,元祖)引用計數減小的狀況:使用del語句對對象別名顯示的銷燬引用超出做用域或被從新賦值sys.getrefcount()函數能夠得到對象的當前引用計數2.標記-清除機制
3.分代技術
20、什麼是python?使用python有什麼好處?
python是一種編程語言,它有對象、模塊、線程、異常處理和自動內存管理。它簡潔,簡單、方便、容易擴展、有許多自帶的數據結果,並且它開源
2一、什麼是pickling和unpickling?
Pickle模塊讀入任何python對象,將它們轉換成字符串,而後使用dump函數將其轉儲到一個文件中——這個過程叫作pickling反之從存儲的字符串文件中提取原始python對象的過程,叫作unpickling
2二、python是如何被解釋的?
Python是一種解釋性語言,它的源代碼能夠直接運行,Python解釋器會將源代碼轉換成中間語言,以後再翻譯成機器碼再執行
2三、數組和元組之間的區別是什麼?
數組和元祖之間的區別:數組內容能夠被修改,而元組內容是隻讀的,不可被修改的,另外元組能夠被哈希,好比做爲字典的key
2四、參數按值傳遞和引用傳遞是怎麼實現的?
python中的一切都是類,全部的變量都是一個對象的引用。引用的值是由函數肯定的,所以沒法被改變,可是若是一個對象是能夠被修改的,你能夠改動對象
2五、Python都有哪些自帶的數據結構?
Python自帶的數據結構分爲可變和不可變的:可變的有:數組、集合、字典,不可變的是:字符串、元組、整數
2六、什麼是python的命名空間?
在python中,全部的名字都存在於一個空間中,它們在改空間中存在和被操做——這就是命名空間,它就好像一個盒子,在每一個變量名字都對應裝着一個對象,當查詢變量的時候,會從該盒子裏面尋找相應的對象
2七、python中的unittest是什麼?
在python中,unittest是python中的單元測試框架,它擁有支持共享搭建、自動測試、在測試中暫停代碼、將不一樣測試迭代成一組
2八、*args與**kwargs
*args表明位置參數,它會接收任意多個參數並把這些參數做爲元祖傳遞給函數。**kwargs表明的關鍵字參數,返回的是字典,位置參數必定要放在關鍵字前面
2九、在Python中什麼是slicing?
slicing是一種在有序的對象類型中(數組、元祖、字符串)節選某一段的語法
30、Python中的docstring是什麼?
Python中文檔字符串被稱爲docstring,它在Python中的做用是爲函數、模塊和類註釋生成文檔
3一、os與sys區別:
os是模塊負責程序與操做系統的交互,提供了訪問操做系統底層的接口sys模塊是負責程序與python解釋器的交互,提供了一系列的函數和變量,用於操控Python時運行的環境
3二、實現一個單例模式
new()在 init()以前被調用,用於生成實例對象。利用這個方法和類的屬性的特色能夠實現設計模式的單例模式。單例模式是指建立惟一對象,單例模式設計的類只能實例,實例化1個對象
class Singleton(object):
__instance=None
def __init__(self):
pass
def __new__(cls, *args, **kwargs):
if Singleton.__instance is None:
Singleton.__instance=object.__new__(cls,*args,**kwargs)
return Singleton.__instance
\33. 大數據的文件的讀取:
讀取大幾 G 的大文件,能夠利用生成器 generator
對可迭代對象 file,進行迭代遍歷:for line in file,會 自動地使用緩衝 IO(buffered IO)以及內存管理,而沒必要擔憂任何 大文件的問題。
with open('filename') as file:
for line in file: do_things(line)
\34. python 中的反射是什麼?
python中反射的核心本質其實就是利用字符串的形式去對象(模 塊)中操做(查找/獲取/刪除/添加)成員,一種基於字符串的事件 驅動。
35.什麼是線程安全?
線程安全是在多線程的環境下,可以保證多個線程同時執行時程序依舊運行正確, 並且要保證對於共享的數據能夠由多個線程存取,可是同一時刻只能有一個線 程進行存取。多線程環境下解決資源競爭問題的辦法是加鎖來保證存取操做的惟一性。
\36. 十個經常使用的 linux 命令?
Ls,help,cd ,more,clear,mkdir,pwd,rm,grep,find,mv,su,date…
\37. find 和 grep?
grep 命令是一種強大的文本搜索工具,grep 搜索內容串能夠是正則表達式, 容許對文本文件進行模式查找。若是找到匹配模式, grep 打印包含模式的全部行。
find 一般用來在特定的目錄下搜索符合條件的文件,也能夠用來搜索特定用戶 屬主的文件。
38.什麼是面向對象編程?
面向對象編程是一種解決軟件複用的設計和編程方法。這種方法把軟件系統中 相近類似的操做邏輯和操做應用數據、狀態,以類的型式描述出來,以對象實例的形式 在軟件系統中複用,以達到提升軟件開發效率的做用。
\39. 面向對象有那些技術?
類(Class): 用來描述具備相同的屬性和方法的對象的集合。它定義了該集合中每一個 對象所共有的屬性和方法。對象是類的實例。
類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數體 以外。類變量一般不做爲實例變量使用。
數據成員:類變量或者實例變量用於處理類及其實例對象的相關的數據。 方法重寫:若是從父類繼承的方法不能知足子類的需求,能夠對其進行改寫,這 個過程叫方法的覆蓋(override),也稱爲方法的重寫。
實例變量:定義在方法中的變量,只做用於當前實例的類。
繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法。 繼承也容許把一個派生類的對象做爲一個基類對象對待。
實例化:建立一個類的實例,類的具體對象。
方法:類中定義的函數。
對象:經過類定義的數據結構實例。對象包括兩個數據成員(類變量和實例變量) 和方法。
40..靜態方法和類方法是什麼?
靜態方法:須要經過修飾器@staticmethod 來進行修飾,靜態方法不須要多 定義參數。
類方法:類方法是類對象所擁有的方法,須要用修飾器@classmethod 來標識 其爲類方法,對於類方法,第一個參數必須是類對象,通常以 cls 做爲第一個參 數(也能夠用其餘名稱的變量做爲其第一個參數),可以經過實例對象和類對象 去訪問。
\41. 類屬性、實例屬性是什麼?
類屬性:定義在類裏面但在函數外面的變量,是靜態的。類對象所擁有的屬性,它被全部類對象的實例對象所共有,在內存中只存在一個副本。對於公有的類屬性,在類外能夠經過類對象和實例對象訪問。
實例屬性:定義在init()方法裏的變量就是實例屬性,這些屬性只有被建立時纔會 被建立。 當類屬性與實例屬性同名時,一個實例訪問這個屬性時實例屬性會覆蓋類屬性。
\42. 若是你須要執行一個定時任務,你會怎麼作?
Linux 的 Crontab 執行命令: sudo crontab -e 例:0 */1 * * * /usr/local/etc/rc.d/lighttpd restart 每一小時重啓 apache
\43. 線上服務可能由於種種緣由致使掛掉怎麼辦? L
inux 下的後臺進程管理利器 supervisor 每次文件修改後在 linux 執行:service supervisord restart
如何提升 Python 的運行效率,請說出很多於 2 種提升運行效 率的方法?
使用生成器
關鍵代碼使用外部功能包:Cython、Pylnlne、PyPy、Pyrex 針對循環的優化——儘可能避免在循環中訪問變量的屬性
\45. 介紹下「消費者」和「生產者」模型。
生產者-消費者模型是多線程同步的經典案例。此模型中生產者向緩衝區 push 數據,消費者從緩衝區中 pull 數據。 這個 Demo 中緩衝區用 python 實現的 Queue 來作,這個模塊是線程安全的使開發者不 用再爲隊列增長額外的互斥鎖. 信號處理的實現是這樣的:
主線程接到一個 SIGTERM 的信號後先通知 Consumer 中止向緩衝區 push 數據並退 出
Produer 將緩衝區中的數據消費徹底後在退出
主線程退出
生產者消費者模型的優勢:
解耦 假設生產者和消費者分別是兩個類。若是讓生產者直接調用消費者的某個方法,那麼生產 者對於消費者就會產生依賴(也就是耦合)。未來若是消費者的代碼發生變化,可能會 影響到生產者。而若是二者都依賴於某個緩衝區,二者之間不直接依賴,耦合也就相應降 低了。
支持併發 因爲生產者與消費者是兩個獨立的併發體,他們之間是用緩衝區做爲橋樑鏈接,生產者只 須要往緩衝區裏丟數據,就能夠繼續生產下一個數據,而消費者只須要從緩衝區了拿數據 便可,這樣就不會由於彼此的處理速度而發生阻塞。
支持忙閒不均 若是製造數據的速度時快時慢,緩衝區的好處就體現出來了。當數據製造快的時候,消費 者來不及處理,未處理的數據能夠暫時存在緩衝區中。 等生產者的製造速度慢下來,消 費者再慢慢處理掉。
\46. 爬蟲在向數據庫存數據開始和結束都會發一條消息,是 scrapy 哪 個模塊實現的?
Item Pipeline scrapy 的信號處理使用的是 dispatch模塊
\47. 爬取下來的數據如何去重,說一下具體的算法依據?
經過 MD5 生成電子指紋來判斷頁面是否改變
.nutch 去重。nutch 中 digest 是對採集的每個網頁內容的32 位哈希值,若是兩個網頁內容徹底同樣,它們的 digest 值確定會 同樣。
\48. 寫爬蟲是用多進程好?仍是多線程好? 爲何?
IO 密集型代碼(文件處理、網絡爬蟲等),多線程可以有效 提高效率(單線程下有 IO 操做會進行 IO 等待,形成沒必要要的時間浪 費,而開啓多線程能在線程 A 等待時,自動切換到線程 B,能夠不浪 費 CPU 的資源,從而能提高程序執行效率)。在實際的數據採集過程當中,既考慮網速和響應的問題,也須要考慮自身機器的硬件狀況,來設置多進程或多線程。
\49. 說一下 numpy 和 pandas 的區別?分別的應用場景?
Numpy 是的擴展包,純數學。 Pandas 作 以矩陣爲基礎的數學計算模塊。提供了 一套名爲 DataFrame 的數據結構,比較契合統計分析中的表結構,並 且提供了計算接口,可用 Numpy 或其它方式進行計算。
\50. 驗證碼如何處理?
Scrapy 自帶處理驗證碼
獲取到驗證碼圖片的 url,調用第三方付費藉口破解驗證碼
51.分佈式有哪些方案,哪種最好?
celery、beanstalk,gearman
我的認爲gearman比較好。緣由主要有如下幾點:
技術類型簡單,維護成本低。
簡單至上。能知足當前的技術需求便可="" (分佈式任務處理、="" 異步同步任務同時支持、任務隊列的持久化、維護部署簡單)。
有成熟的使用案例。instagram="" 就是使用的="" 來完成="" 圖片的處理的相關任務,有成功的經驗,咱們固然應該借鑑。
\52. post和 get 區別?
get請求:請求的數據會附加在url以後,以?分割和傳輸數據,多個參數用&鏈接。url的編碼格式採用的是ascii 編碼,而不是uniclde,便是說全部的非字符都要編碼以後再傳輸。
post請求:post請求會把請求的數據放置在http請求包的包體中。上面的item="bandsaw" 就是實際的傳輸數據。
所以,get請求的數據會暴露在地址欄中,而post請求則不會。
傳輸數據的大小在http規範中,沒有對長度和傳輸的數據大小進行限制。可是在實際開發過程當中,對於get,特定的瀏覽器和服務器對url長度有限制。所以,在使用請求時,傳輸數據會受到限制。對於post,因爲不是地址欄傳值,理論上是不會受限制的,可是實際上各個服務器會規定對form提交數據大小進行限制,apache、iis 都有各自的配置。
安全性post的安全性比get的高。
53.爲何要三次握手和四次揮手?
創建鏈接的過程是利用客戶服務器模式,假設主機a="" 爲客戶端,主機 b爲服務器端。
tcp的三次握手過程:主機a向b發送鏈接請求;主機b對收到的主機a的報文段進行確認;主機a再次對主機b的確認進行確認。
採用三次握手是爲了防止失效的鏈接請求報文段忽然又傳送到主機於是產生錯誤。
失效的鏈接請求報文段是指:主機a發出的鏈接請求沒有收到主機b 的確認,因而通過一段時間後,主機a又從新向主機b發送鏈接請求,且創建成功,順序完成數據傳輸。考慮這樣一種特殊狀況,主機a第一次發送的鏈接請求並無丟失,而是由於網絡節點致使延遲達到主機 b,主機b覺得是主機a又發起的新鏈接,因而主機b贊成鏈接,並向主機a發回確認,可是此時主機a根本不會理會,主機b就一直在等待主機a發送數據,致使主機b資源浪費。
爲何採用兩次握手不行?
緣由就是上面說的失效的鏈接請求的特殊狀況,所以採用三次握手剛恰好,兩次可能出現失效,四次甚至更屢次則不必,反而複雜了
54.多線程有哪些模塊?
在python中可以使用的多線程模塊主要有兩個,thread和threading模塊。
55.分佈式爬蟲主要解決什麼問題?
ip 帶寬 cpu io
56.什麼是url?
url,即統一資源定位符,也就是咱們說的網址,統一資源定位符是對能夠從互聯網上獲得的資源的位置和訪問方法的一種簡潔的表示,是互聯網上標準資源的地址。互聯網上的每一個文件都有一個惟一的url,它包含的信息指出文件的位置以及瀏覽器應該怎麼處理它。
\57. 建立一個簡單 tcp 服務器須要的流程?
socket 建立一個套接字
bind 綁定 ip 和 port
listen 使套接字變爲能夠被動連接
accept 等待客戶端的連接 5.recv/send 接收發送數據
\58. TTL,MSL,RTT是什麼?
MSL:報文最大生存時間,他是任何報文在網絡上存在的最長時間,超過這個 時間報文將被丟棄。
TTL:TTL 是 time to live 的縮寫,中文能夠譯爲「生存時間」,這個生存時間是由源主機設置初始值但不是存的具體時間,而是存儲了一個 ip 數據報能夠通過的最 大路由數,每通過一個處理他的路由器此值就減 1,當此值爲 0 則數據報將被丟棄,同 時發送 ICMP 報文通知源主機。RFC 793 中規定 MSL 爲 2 分鐘,實際應用中經常使用的是30 秒,1 分鐘和 2 分鐘等。TTL 與 MSL 是有關係的但不是簡單的相等的關係,MSL 要大於等於 TTL。
RTT: RTT 是客戶到服務器往返所花時間(round-trip time,簡稱 RTT), TCP 含有動態估算 RTT 的算法。TCP 還持續估算一個給定鏈接的 RTT,這是由於 RTT 受網絡傳輸擁塞程序的變化而變化。
\59. 經常使用的反爬蟲措施?
添加代理
下降訪問頻率
User-Agent
動態 HTML 數據加載
驗證碼處理
Cookie
\60. 關於 HTTP/HTTPS 的區別,分別應該在什麼場合下使用?
Hhttps 協議須要到 ca 申請證書,通常免費證書不多,須要交費。
http 是超文本傳輸協議,信息是明文傳輸,https 則是具備安全性的 ssl 加密傳輸協議
http 和 https 使用的是徹底不一樣的鏈接方式用的端口也不同,前者是 80,後者是 443。
http 的鏈接很簡單,是無狀態的 HTTPS 協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網絡協議 要比 http 協議安全
應用場合:http適合於對傳輸速度,安全性要求不是很高,且須要快速開發的應用。如 web 應用, 小的手機遊戲等等. https:https 應該用於任何場景!
HTTPS優勢和缺點:
優勢:
使用 HTTPS 協議可認證用戶和服務器,確保數據發送到正確的客戶機和服務器;
HTTPS 協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網絡協議, 要比 http 協議安全,可防止數據在傳輸過程當中不被竊取、改變,確保數據的完整性。
HTTPS 是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增長了中 間人攻擊的成本
缺點:
HTTPS 協議的加密範圍也比較有限,在黑客攻擊、拒絕服務攻擊、服務器劫持等方 面幾乎起不到什麼做用
HTTPS 協議還會影響緩存,增長數據開銷和功耗,甚至已有安全措施也會受到影響 也會所以而受到影響。
SSL 證書須要錢。功能越強大的證書費用越高。我的網站、小網站沒有必要通常不會用。
HTTPS 鏈接服務器端資源佔用高不少,握手階段比較費時對網站的相應速度有負面影響。
HTTPS 鏈接緩存不如 HTTP 高效。
\61. HTTPS 是如何實現安全傳輸數據的?
HTTPS 其實就是在 HTTP 跟 TCP 中間加多了一層加密層 TLS/SSL。SSL 是個加密套件, 負責對 HTTP 的數據進行加密。TLS 是 SSL 的升級版。如今提到 HTTPS,加密套件基本指的是TLS。原先是應用層將數據直接給到 TCP 進行傳輸,如今改爲應用層將數據給到 TLS/SSL,將數據加密後,再給到 TCP 進行傳輸。
HTTPS 安全證書是怎麼來的,如何申請,國內和國外有哪些第 三方機構提供安全證書認證?
國內:沃通(WoSign) 中國人民銀行聯合 12 家銀行創建的金融 CFCA 中國電信認證中心(CTCA) 海關認證中心(SCCA) 國家外貿部 EDI 中心創建的國富安 CA 安全認證中心 SHECA(上海 CA)爲首的 UCA 協卡認證體系
國外:StartSSL GlobalSign GoDaddy Symantec
62.桶排序(最快最簡單的排序)
桶排序的基本思想是將一個數據表分割成許多 buckets,而後每 個 bucket 各自排序,或用不一樣的排序算法,或者遞歸的使用 bucket sort 算法。也是典型的 divide-and-conquer 分而治之的策略。它是 一個分佈式的排序,介於 MSD 基數排序和 LSD 基數排序之間
def bucketSort(nums):
# 選擇一個最大的數
max_num = max(nums)
# 建立一個元素全是 0 的列表, 當作桶
bucket = [0]*(max_num+1)
# 把全部元素放入桶中, 即把對應元素個數加一
for i in nums: bucket[i] += 1
# 存儲排序好的元素
sort_nums = []
# 取出桶中的元素
for j in range(len(bucket)):
if bucket[j] != 0:
for y in range(bucket[j]):
sort_nums.append(j)
return sort_nums nums = [5,6,3,2,1,65,2,0,8,0]
print bucketSort(nums)
桶排序是穩定的,桶排序是常見排序裏最快的一種, 大多數狀況下比快排還要快,桶排序很是快,可是同時也很是耗空間,基本上是最耗空間的 一種排序算法
\63. 排序算法的分析
排序算法的穩定性:若是在對象序列中有兩個對象r[i]和r[j] , 它們的排序碼 k[i]==k[j] 。若是排序先後,對象 r[i]和 r[j] 的相 對位置不變,則稱排序算法是穩定的;不然排序算法是不穩定的。
時間開銷:排序的時間開銷可用算法執行中的數據比較次數與數據移動次數來衡量。 算法運行時間代價的大略估算通常都按平均狀況進行估算。對於那些受對象排序碼序列初始排列及對象個數影響較大的,須要按最好狀況和最壞狀況進行估算。
空間開銷:算法執行時所需的附加存儲。
64.Python垃圾回收機制
Python中的垃圾回收是以引用計數爲主,標記-清除、分代收集爲輔。引用計數的缺陷是循環引用的問題。
引用計數
原理:當一個對象的引用被建立或者複製時,對象的引用計數加1;當一個對象的引用被銷燬時,對象的引用計數減1,當對象的引用計數減小爲0時,就意味着對象已經再沒有被使用了,能夠將其內存釋放掉。
使用gc模塊垃圾回收:import gc模塊,而且is_enable()=True纔會啓動自動垃圾回收。
標記-清除
原理:將集合中對象的引用計數複製一份副本,這個計數副本的做用是尋找root object集合(該集合中的對象是不能被回收的)。當成功尋找到root object集合以後,首先將如今的內存鏈表一分爲二,一條鏈表中維護root object集合,成爲root鏈表,而另一條鏈表中維護剩下的對象,成爲unreachable鏈表。一旦在標記的過程當中,發現如今的unreachable可能存在被root鏈表中直接或間接引用的對象,就將其從unreachable鏈表中移到root鏈表中;當完成標記後,unreachable鏈表中剩下的全部對象就是名副其實的垃圾對象了,接下來的垃圾回收只需限制在unreachable鏈表中便可。
分代
原理:將系統中的全部內存塊根據其存活時間劃分爲不一樣的集合,每個集合就成爲一個「代」,垃圾收集的頻率隨着「代」的存活時間的增大而減少。也就是說,活得越長的對象,就越不多是垃圾,就應該減小對它的垃圾收集頻率。那麼如何來衡量這個存活時間:一般是利用幾回垃圾收集動做來衡量,若是一個對象通過的垃圾收集次數越多,能夠得出:該對象存活時間就越長。
有三種狀況會觸發垃圾回收:
調用gc.collect()
,
當gc模塊的計數器達到閥值的時候。
程序退出的時候
經常使用gc模塊函數
gc.set_debug(flags)設置gc的debug日誌,通常設置爲gc.DEBUG_LEAK
gc.collect([generation])顯式進行垃圾回收,能夠輸入參數,0表明只檢查第一代的對象,1表明檢查一,二代的對象,2表明檢查一,二,三代的對象,若是不傳參數,執行一個full collection,也就是等於傳2。返回不可達(unreachable objects)對象的數目
gc.set_threshold(threshold0[, threshold1[, threshold2])設置自動執行垃圾回收的頻率。
gc.get_count()獲取當前自動執行垃圾回收的計數器,返回一個長度爲3的列表
65.Python解決高併發思路
HTML頁面靜態化
圖片服務器分離(能夠用fastdfs輕量級的分佈式文件存儲系統)
使用緩存(用redis)
數據庫集羣
庫表散列使用負載均衡的方法(配置nigix服務器)
鏡像
CDN加速技術(內容分發網絡)
66.with關鍵字:
with語句時用於對try except finally 的優化,讓代碼更加美觀,例如經常使用的開發文件的操做,用try except finally 實現,打開文件的時候,爲了能正常釋放文件的句柄,都要加個try,而後再finally裏把f close掉,可是這樣的代碼不美觀,finally就像個尾巴,一直託在後面,尤爲是當try裏面的語句時幾十行。用with的實現,這條語句就好簡潔不少,當with裏面的語句產生異常的話,也會正常關閉文件。
除了打開文件,with只適用於上下文管理器的調用,除了文件外,with還支持 threading、decimal等模塊,固然咱們也能夠本身定義能夠給with調用的上下文管理器,使用類定義上下文管理器須要在類上定義enter和exit方法,執行with A() as a: 語句時會先執行enter方法,這個方法的返回值會賦值給後面的a變量,當with裏面的語句產生異常或正常執行完時,都好調用類中的exit方法。
在開發的過程當中,會有不少對象在使用以後,是須要執行一條或多條語句來進行關閉,釋放等操做的,例如上面說的的文件,還有數據庫鏈接,鎖的獲取等,這些收尾的操做會讓代碼顯得累贅,也會形成因爲程序異常跳出後,沒有執行到這些收尾操做,而致使一些系統的異常,還有就是不少程序員會忘記寫上這些操做--!--!,爲了不這些錯誤的產生,with語句就被生產出來了。with語句的做用就是讓程序員不用寫這些收尾的代碼,而且即便程序異常也會執行到這些代碼(finally的做用)
67.子類重寫了__init__
方法, 初始化子類時, 父類的__init__
方法還會執行嗎?
不會了。
如何在子類重寫了__init__
方法的狀況下, 還能執行父類的__init__
方法?
使用super方法。