1. 程式人生 > 其它 >dom元素的事件基礎

dom元素的事件基礎

目錄

基礎知識

GC機制

Python的垃圾回收,其實高階的語言都有自己的垃圾回收機制簡稱GC,python當中主要通過三種方式解決垃圾回收的方 式,引用計數、標記清除、分代回收
》引用計數:如果有新的引用指向物件,物件引用計數就加一,引用被銷燬時,物件引用計數減一,當用戶的引用計數 為0時,該記憶體被釋放
標記清除:首先標記物件(垃圾檢測),然後清除垃圾(垃圾回收)
》首先初始所有物件標記為白色,並確定根節點物件(這些物件是不會被刪除),標記它們為黑色(表示物件有效)。 將有效物件引用的物件標記為灰色(表示物件可達,但它們所引用的物件還沒檢查),檢查完灰色物件引用的物件後, 將灰色標記為黑色。重複直到不存在灰色節點為止。最後白色結點都是需要清除的物件

》分代回收:垃圾回收器會更頻繁的處理新物件。一個新的物件即是你的程式剛剛建立的,而一個老的物件則是經過了 幾個時間週期之後仍然存在的物件。Python會在當一個物件從零代移動到一代,或是從一代移動到二代的過程中提升(promote)這個物件。

裝飾器、生成器、迭代器

裝飾器: 寫程式碼要遵循開放封閉原則,裝飾器本質上是一個巢狀函式(被套著的函式就是閉包),它接受被裝飾的函式(func)作為引數,並返回一個包裝過的函式。在不改變被裝飾函式的程式碼情況下給被裝飾函式或程式新增新的功能,@wrsps可以保證裝飾器修飾的函式的name的值保持不變,使裝飾器更加的完美 載入順序自下而上,執行順序自上而下
應用:當我們記錄日誌的時候,執行某函式、給某個功能新增日誌。 閉:指的該函式是定義在函式內的函式
包:指的就是該函式引用了一個外層函式作用域的名字(e作用域的名字) 封閉:已實現的功能程式碼塊
開放:對擴充套件開發

生成器:yield關鍵字、那麼函式名()結果就是生成器、並且不會執行函式內部程式碼,生成器內建有  iter  和  next 方法,所以生成器本身就是一個迭代器
應用:爬蟲
對比return可以返回多次值、可以掛起儲存函式的執行狀態應用:redis快取

迭代器:不依賴索引取值、 iter 迭代器、 next 生成器,通過迭代取值的方案,可以節省記憶體
其中迭代器又分為可迭代物件和迭代器物件,可迭代物件內建有 iter 的方法的物件都叫可迭代的物件

三元表示式、列表生成式、生成器表示式

三元表示式:是python為我們提供的一種簡化程式碼的解決方案
res = 條件成立時返回的值 if 條件 else 條件不成立時返回的值

列表生成式:就相當於把for迴圈寫到列表中,一行程式碼完成一個功能,簡化程式碼,但是寫的複雜的話會影響閱讀,一 般也不怎麼用
res = [x for x in range(10)]
print(res) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

生成器表示式:將列表生成式的[]換成()即可,對比列表生成式返回的是一個列表,而生成器表示式返回的是一個生成 器物件,對比列表生成式,生成器表示式的優點自然是節省記憶體(一次只產生一個值在記憶體中)

函式遞迴

在呼叫一個函式的內部又呼叫自己,所以遞迴的本質就是一個迴圈的過程,它的大前提就是遞迴呼叫一定要在某一層結 束,如果不結束,會形成一個死迴圈.
遞迴分為兩個階段,回溯,向下一層一層挖井,遞推,向上一層一層返回items=[[1,2],3,[4,[5,[6,7]]]]
def func(items):
   for x in items:
       if type(x) is list: # 滿足未遍歷完items以及if判斷成立的條件時,一直進行呼叫
           func(x)
       else:
           print(x,end=' ') func(items)

匿名函式就是沒有名字的函式,臨時只用一次,也叫 lambds函式
語法: lambds 引數1,引數2,...: expression

單例模式:(單一職責原則):保證一個類僅有一個例項,並提供一個訪問它的全 局訪問點、比如桌面上的垃圾回收站

面向物件

OOP面向物件程式設計

面向物件程式設計的核心是物件二字,物件就是一個用來盛放資料與功能的容器,基於該思想編寫程式就是創造一個個的容 器,其優點是擴充套件性強,但是它也有缺點,就是提高了程式設計的複雜度

在程式中,是先定義類,後產生物件,這裡的物件就是容器,是用來存放資料與功能的,而類也是"容器",用在存放同 類物件共有的資料與功能

面向物件程式設計有三大特徵:封裝,繼承,多型

封裝:將多個屬性和方法封裝到一個抽象的類中、所有類的物件都可以對其呼叫。
針對封裝到物件或者類中的屬性,我們還可以嚴格控制對他們的訪問,分別是隱藏與開放介面,隱藏屬性是採用用下劃 線開頭的方式將屬性隱藏起來,設定成私有的,僅僅是一種變形操作,類裡定義屬性就是為了使用,隱藏並不是目的, 而是限制了類外部對資料的直接操作,類內應該提供相應的介面來允許類外部間接的操作資料,介面之上可以附加額外 的邏輯來對資料的操作進行嚴格的控制

繼承:實現程式碼的重用、繼承父類、重用父類的屬性和方法、減少程式碼的冗餘
繼承描述的是子類與父類之間的關係,是一種什麼是什麼的關係,需要先抽象再繼承。
抽象:最主要的作用是劃分類別(可以隔離關注點,降低複雜度)抽象即總結相似之處,總結物件之間的相似之處得到 類,總結類與類之間的相似之處就可以得到父類
在python2中有經典類和新式類之分,沒有顯式的繼承object類的類,以及該類的子類,都是經典類,顯示的繼承object的類,以及該類的子類,都是新式類
但是在python3中,既是沒有顯示的繼承object,也會預設繼承該類

經典類:深度優先新式類:廣度優先

多型:多型指的是一類事物有多種形態,多型性指的是可以在不用考慮物件具體型別的情況下而直接使用物件、但是需 要依賴封裝和繼承、在python中推崇鴨子型別:完全不依賴繼承、製造出外觀和行為相同物件,同樣可以實現不考慮對 象型別而使用物件

鴨子型別

鴨子型別:是動態型別的一種風格,不管物件屬於哪個,也不管宣告的具體介面是什麼,只要物件實現了相應的方法,函式 就可以在物件上執行操作。即忽略物件的真正型別,轉而關注物件有沒有實現所需的方法、簽名和語義.   是動態型別的一種風格,不管物件屬於哪個,也不管宣告的具體介面是什麼,只要物件實現了相應的方法,函式就可以在物件上執行 操作。即忽略物件的真正型別,轉而關注物件有沒有實現所需的方法、簽名和語義.

繫結方法和非繫結方法

但凡在類中定義一個函式,預設就是繫結給物件的,應該由物件來呼叫,會將物件當作第一個引數自動傳入classmethods:繫結給類的方法,由類來呼叫,自動將類本身當作第一個引數傳入
staticmethod:非繫結方法,不與類和物件繫結,類和物件都可以呼叫,普通函式,沒有自動傳值

property:一種特殊屬性、訪問它時會執行一段功能,用來繫結給物件的方法,將函式物件偽裝成資料屬性,然後返回 值
應用:django模型類中寫子序列化的方法,跨表操作

反射、CBV原始碼簡述

python中的反射就是通過字串的形式操作物件相關的屬性,python中一切事物都是物件,都可以用到反射 反射機制指的是在程式的執行狀態中
對於任意一個類,都可以知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫他的任意方法和屬性。 這種動態獲取程式資訊以及動態呼叫物件的功能稱為反射機制。

hasattr 檢測是否含有某屬性getattr 獲取屬性
setattr 設定屬性delattr 刪除屬性
好處:反射可以提前定義好介面、接基於類的檢視應用場景:
CBV原始碼簡述:根據前端請求方式的不同自動匹配執行對應的方法-在url路由中的views.類 名.as_view()的原始碼下可以看到是被@classonlymethod修飾的類方法,內部定義閉包函式傳參並返回閉包函式名、在dajong啟動的時候會執行urls 的as_view()產生變 形為views.view,在瀏覽器提交請求的時候就會觸發view方法,通過view下的self 使用類的對
象,返回self.dispatch屬性、在父類中的dispathc函式通過反射機制就 通過字串操作物件屬性口只有在被完成後才會真正執行,就是可以事先寫好邏輯介面,事後實現介面功能

元類、魔法方法、猴子補丁

元類:建立類的類就叫元類(metaclass)函式type其實就是一個元類,type 就是Python在背後用來建立所有類的元類。

魔法方法: call , init , new , str ...
類加()觸發類的元類的 call 方法
    str    列印時觸發   str函式或者print函式—>obj.str()
    init   是初始化方法,通過類建立物件時,自動觸發執行 
    new   是建立物件時為物件分配空間、在初始化init之前被呼叫 
當我們建立例項的時候、   new 方法在 init 方法之前被呼叫並將 new 方法的返回值將傳遞給 init 方法作為第一個引數,最後 init 給這個例項設定一些引數。 

猴子補丁:猴子補丁得益於python靈活的語法,一切皆物件的思想。
猴子補丁的主要功能就是動態的屬性的替換。雖然屬性的執行時替換和猴子也沒有什麼關係,所以說猴子補丁的叫法有 些莫名其妙,但是隻要"模組執行時替換的功能"對應就行了。

猴子補丁允許執行期間動態修改一個類或模組

常用模組

os模組式與作業系統互動的一個介面
os.path.join(path1[, path2[,	]]) 將多個路徑組合後返回,第一個絕對路徑之前的引數將被忽略
os.path.splitext() 將檔名和副檔名分開os.path.split() 返回檔案的路徑和檔名
os.mkdir('dirname')   生成單級目錄;相當於shell中mkdir dirname os.remove() 刪除一個檔案

sys
sys.path           返回模組的搜尋路徑,初始化時使用PYTHONPATH環境變數的值sys.exit(n)       退出程式,正常退出時exit(0)
sys.version       獲取Python解釋程式的版本資訊

re 正則
\w 匹配數字字母下劃線
\W 匹配非字母數字下劃線
^ 匹配字串的開頭
$ 匹配字串的末尾

random
生成隨機數
print(random.random())#(0,1)	float   大於0且小於1之間的小數
print(random.randint(1,3)) #[1,3]   大於等於1且小於等於3之間的整

logging 記錄日誌
日誌級別有五種logging.debug('除錯debug') logging.info('訊息info') logging.warning('警告warn') logging.error('錯誤error')
logging.critical('嚴重critical')

json&pickle
json是可以在不同語言之間交換資料的,而pickle只在python之間使用
json只能序列化最基本的資料型別,而pickle可以序列化所有的資料型別,包括類,函式都可以序列化

程序執行緒協程

程序是CPU資源分配的基本單位,執行緒是獨立執行和獨立排程的基本單位(CPU上真正執行的是執行緒)。

程序擁有自己的資源空間,一個程序包含若干個執行緒,執行緒與CPU資源分配無關,多個執行緒共享同一程序內的資源。 執行緒的排程與切換比程序快很多。
協程是單執行緒下的併發,是一種使用者態的輕量級執行緒,即協程是由使用者程式自己控制排程的。 對於多核CPU,利用多程序+協程的方式,能充分利用CPU,獲得極高的效能

"""
Gevent 是一個第三方庫,可以輕鬆通過gevent實現併發同步或非同步程式設計,在gevent中用到的主要模式是Greenlet, 它是以C擴充套件模組形式接入Python的輕量級協程。 Greenlet全部執行在主程式作業系統程序的內部,但它們被協作式地排程。

非同步和同步

我們在說同步、非同步的時候,特指那些需要其他部件協作或者需要一定時間完成的任務
同步:提交一個任務,提交之後在原地等待提交的結果,之後再去提交下一個任務。某功能呼叫時,在沒有得到結果之 前,該呼叫就不會返回
非同步:提交一個任務,提交之後不等提交的任務執行完直接提交下一個任務。非同步的概念和同步相對。

同步與非同步針對的是函式/任務的呼叫方式:同步就是當一個程序發起一個函式(任務)呼叫的時候,一直等到函式
(任務)完成,而程序繼續處於啟用狀態。而非同步情況下是當一個程序發起一個函式(任務)呼叫的時候,不會等函式 返回,而是繼續往下執行當,函式返回的時候通過狀態、通知、事件等方式通知程序任務完成。

GIL鎖/互斥鎖

1、首先明確GIL並不是Python的特性,它是在實現Python解析器(CPython)時所引入   的一個概念 
2、GIL:全域性直譯器鎖。每個執行緒在執行的過程都需要先獲取GIL,保證同一時刻只   有一個執行緒可以執行程式碼。 
3、當前執行緒遇到I/O,或者位元組碼執行100行(python2,python3中使用計時器時間到達閾值釋放GIL),才會釋放GIL 鎖。執行緒的執行仍然是有先後順序的,並不是同時進行 
4、Python使用多程序是可以利用多核的CPU資源的。 
5、多執行緒爬取比單執行緒效能有提升,因為遇到IO阻塞會自動釋放GIL鎖。 多程序可以充分使用cpu的兩個核心而多執行緒卻不能充分使用cpu的兩個核心    cpython直譯器中存在一個GIL(全域性直譯器鎖),它的作用就是保證同一時刻只有一個執行緒可以執行程式碼,因此造成了我們使用多執行緒的時候無法實現並行。 
解決方案: 
     1)更換直譯器比如使用jpython(java實現的python直譯器)(jpython xxx.py) 
   2)使用其他語言(C語言)編寫程式 
   3)使用多程序完成多工的處理
     """
多個程序操作同一份資料的時候,會出現資料錯亂的問題
針對上述問題,解決方法就是加鎖處理,將併發變成序列,犧牲效率但是保證了資料的安全 擴充套件:
行鎖	表鎖注意:
1、鎖不要輕易的使用,容易造成死鎖現象(我們一般寫程式碼不會用到,都是內部封裝好的)
2、鎖只在處理資料的部分加起來保證資料安全(只在爭搶資料的環節加鎖處理即可)

網路

HTTP/HTTPS協議

1、什麼是HTTP?   資料傳輸是明文超文字傳輸協議
是一個基於請求響應,無狀態的,作用於tcp/ip應用層的協議之上的協議,它規定了瀏覽器與服務端之間資料互動的格 式,設計HTTP的初衷是為了提供一種釋出和接收HTML頁面的方法。絕大多數的Web開發,都是構建在HTTP協議之上的Web 應用。

2、什麼是HTTPS? 資料傳輸是密文安全超文字傳輸協議
HTTPS是一種通過計算機網路進行安全通訊的傳輸協議
HTTPS使用的主要目的是提供對網站伺服器的身份認證,同時保護交換資料的隱私與完整性。
    
3、HTTP vs HTTS HTTP特點:
(1)無狀態:協議對客戶端沒有狀態儲存,對事物處理沒有“記憶”能力,比如訪問一個網站需要反覆進行登入操作(2)無連線:HTTP/1.1之前,由於無狀態特點,每次請求需要通過TCP三次握手四次揮手,和伺服器重新建立連線。比如 某個客戶機在短時間多次請求同一個資源,伺服器並不能區別是否已經響應過使用者的請求,所以每次需要重新響應請求,需要耗費不必要的時間和流量。
(3)基於請求和響應:基本的特性,由客戶端發起請求,服務端響應(4)簡單快速、靈活
(5)通訊使用明文、請求和響應不會對通訊方進行確認、無法保護資料的完整性HTTPS特點:
(1)基於HTTP協議,通過SSL或TLS提供加密處理資料、驗證對方身份以及資料完整性保護(2)內容加密:採用混合加密技術,中間者無法直接檢視明文內容
(3)驗證身份:通過證書認證客戶端訪問的是自己的伺服器(4)保護資料完整性:防止傳輸的內容被中間人冒充或者篡改websocket協議 資料傳輸是密文
資料格式"""
請求資料格式
    請求首行(請求方法...)
    請求頭(一大堆K:V鍵值對)
        
    請求體(並不是所有的請求方法都有 主要用來攜帶敏感性資料)
     
     
響應資料格式
    響應首行(響應狀態碼...)
    響應頭(一大堆K:V鍵值對)
        
    響應體(展示給使用者的資料) """

tcp/udp協議

tcp協議:
可靠傳輸,TCP資料包沒有長度限制,理論上可以無限長,但是為了保證網路的效率,通常TCP資料包的長度不會超過IP 資料包的長度,以確保單個TCP資料包不必再分割。
udp協議:
不可靠傳輸,”報頭”部分一共只有8個位元組,總長度不超過65,535位元組,正好放進一個IP資料包。

為什麼連線的時候是三次握手,關閉的時候卻是四次握手?
因為當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文 是用來同步的。但是關閉連線時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK 報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能傳送FIN報文, 因此不能一起傳送。故需要四步握手。

"""
第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,並進入SYN_SENT狀態,等待伺服器確認;SYN:同步 序列編號(Synchronize Sequence Numbers)。

第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK 包,此時伺服器進入SYN_RECV狀態;

第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進 入ESTABLISHED(TCP連線成功)狀態,完成三次握手。

三次握手四次握手

因為當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文 是用來同步的。但是關閉連線時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK 報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能傳送FIN報文, 因此不能一起傳送。故需要四步握手。

"""
第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,並進入SYN_SENT狀態,等待伺服器確認;SYN:同步 序列編號(Synchronize Sequence Numbers)。

第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK 包,此時伺服器進入SYN_RECV狀態;

第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進 入ESTABLISHED(TCP連線成功)狀態,完成三次握手。

django

MTV

Django 是一個由 Python 編寫的一個開放原始碼的 Web 應用框架。是基於MTV模式的框架,需要配合url控制器(路徑分發)使用!
 Django的MTV模式本質上和MVC是一樣的,也是為了各元件間保持鬆耦合關係,只是定義上有些許不同,Django的MTV分 別是指:
· M 代表模型(Model): 負責業務物件和資料庫的關係對映(ORM)。
· T 代表模板 (Template):負責如何把頁面展示給使用者(html)。
· V 代表檢視(View):   負責業務邏輯,並在適當時候呼叫Model和Template。
  除了以上三層之外,還需要一個URL分發器,它的作用是將一個個URL的頁面請求分發給不同的View處理,View再呼叫 相應的Model和Template
  優勢:低耦合,開發快捷,部署方便,可重用性高,維護成本低。Python + Django 是快速開發、設計、部署網站的最佳組合

MVC

M 代表模型(Model): 負責業務物件和資料庫的關係對映(ORM)。

V 代表檢視(View): 負責業務邏輯,

C 代表控制器(url)

ORM

orm:物件關係對映 
     orm目的就是為了能夠讓不懂SQL語句的人通過python面向物件的知識點也能夠輕 鬆自如的操作資料庫 
   類	>>> 表 
   物件	>>> 表裡面的資料 
   物件點屬性	>>> 欄位對應的值 
    
 缺陷:sql封裝死了 有時候查詢速度很慢

forms元件

能夠完成的資訊
    1、渲染html程式碼,2、校驗資料,3、展示提示資訊   為什麼資料校驗非要去後端 不能在前端利用js直接完成呢?
    資料校驗前端可有可無,但是後端必須要有!!!    
    因為前端的校驗是弱不禁風的   你可以直接修改,或者利用爬蟲程式繞過前端頁面直接朝後端提交資料
    
鉤子函式"""
鉤子函式在form元件中能夠讓我們自定義校驗規則在froms元件中有兩類鉤子
    1、區域性鉤子:'單'個欄位增加校驗規則
    2、全域性鉤子:給'多'個欄位增加校驗規則

Auth模組

Auth模組是Django自帶的使用者認證模組:
我們在開發一個網站的時候,無可避免的需要設計實現網站的使用者系統。此時我們需要實現包括使用者註冊、使用者登入、 使用者認證、登出、修改密碼等功能,所以說比較麻煩。Django作為一個完美主義者的終極框架,它內建了強大的使用者認 證系統–auth,它預設使用 auth_user 表來儲存使用者資料。

auth模組的常用方法:
authenticate()提供了使用者認證功能,即驗證使用者名稱以及密碼是否正確,一般需要username 、password兩個關鍵字引數,如果認證成功(使用者名稱和密碼正確有效),便會返回一個 User 物件

login(HttpRequest, user)
該函式接受一個HttpRequest物件,以及一個經過認證的User物件。
該函式實現一個使用者登入的功能。它本質上會在後端為該使用者生成相關session資料。

logout(request) *
該函式接受一個HttpRequest物件,無返回值。
當呼叫該函式時,當前請求的session資訊會全部清除。該使用者即使沒有登入,使用該函式也不會報錯

is_authenticated()
用來判斷當前請求是否通過了認證。

DTL語法

模板語言:主要用於前後端混合開發的專案,後端為前端頁面傳值的語法

模版語法之變數
在 Django 模板中遍歷複雜資料結構的關鍵是句點字元, 語法:{{變數名}}

模板語言之標籤
標籤看起來像是這樣的: {% tag %}
標籤比變數更加複雜:一些在輸出中建立文字,一些通過迴圈或邏輯來控制流程,一些載入其後的變數將使用到的額外 資訊到模版中。
一些標籤需要開始和結束標籤 (例如{% tag %} ...標籤 內容	{% endtag %})

F、Q查詢

F作用:兩個欄位之間作比較,專門取物件中某列值的操作
F物件允許Django在未實際連結資料的情況下具有對資料庫欄位的值的引用。在更新資料時需要先從資料庫裡將原資料 取出後放在記憶體裡,然後編輯某些屬性,最後提交。
查詢男生比女生多的公司models.company.filter(c_boy_num gt=F('c_girl_num'))

Q作用:對物件進行復雜查詢,並支援&(and),|(or),~(not)操作符(與或非)運算來組合生成不同的Q物件,便 於在查詢操作中靈活地運用。如果Q查詢和關鍵字查詢同時存在時,Q查詢要放在關鍵字查詢的前面!
查詢名字不是紅樓夢的書: models.Book.objects.filter(~Q(name='紅樓夢'))

中介軟體

中介軟體是一個用來處理Django的請求和響應的框架級別的鉤子。它是一個輕量、低級別的外掛系統,用於在全域性範圍內 改變Django的輸入和輸出。每個中介軟體元件都負責做一些特定的功能。
中介軟體是幫助我們在檢視函式執行之前和執行之後都可以做一些額外的操作,它本質上就是一個自定義類,類中定義了 幾個方法,Django框架會在請求的特定的時間去執行這些方法。但是由於其影響的是全域性,所以需要謹慎使用,使用不 當會影響效能。
MIDDLEWARE = [
   'django.middleware.security.SecurityMiddleware', # 安全中介軟體
   'django.contrib.sessions.middleware.SessionMiddleware', # 會話中介軟體:處理session
   'django.middleware.common.CommonMiddleware', # 站點中介軟體:處理是否帶斜槓的
   'django.middleware.csrf.CsrfViewMiddleware', # CSRF保護中介軟體:跨站請求偽造的處理
     'django.contrib.auth.middleware.AuthenticationMiddleware', # 認證中介軟體:提供使用者認證服務
      'django.contrib.messages.middleware.MessageMiddleware',# 訊息中介軟體:基於cookie或者會話的訊息功能
     'django.middleware.clickjacking.XFrameOptionsMiddleware', # X-Frame-Options中介軟體:點選劫持保護
]
MIDDLEWARE配置項是一個列表(列表是有序的),列表中是一個個字串,這些字串其實是一個個類,也就是一個個中 間件。
Django預設有七個中介軟體,但是django暴露給使用者可以自定義中介軟體並且裡面可以寫五種方法 1、process_request : 請求進來時,許可權認證 。
2、process_view : 路由匹配之後,能夠得到檢視函式3、process_exception : 異常時執行
4、process_template_responseprocess : 模板渲染時執行5、process_response : 請求有響應時執行

process_request方法
1.	請求來的時候需要經過每一箇中間件裡面的 process_request方法,經過的順序是按照配置檔案中註冊的中介軟體從上往下的順序依次執行
2.	如果中介軟體裡面沒有定義該方法,那麼直接跳過執行下一個中介軟體
3.它的返回值可以是None,按正常流程繼續走,交給下一個中介軟體處理,如果該方法返回了Httpresponse物件,那麼請 求將不再繼續往後執行,而是直接原路返回(校驗失敗不允許訪問.)
process_request方法就是用來做全域性相關的所有限制功能

process_response方法
1.響應走的時候需要經過每一箇中間件裡面的 process_response方法,該方法有兩個額外的引數 request,   response 2,該方法必須返回一個 HttpResponse物件:預設返回的就是形參 response,你也可以自己返回自己的
3.順序是按照配置檔案中註冊了的中介軟體從下往上依次經過,如果你沒有定義的話直接跳過執行下一個
總結:當前端發來請求,Django會執行每個中介軟體中的process_request,執行順序按照配置檔案由上至下執行。響應走 的時候,Django會執行每個中介軟體中的 process_response方法,process_response方法是在檢視函式之後執行的,執行順序是按照配置檔案中註冊了的中介軟體從下往上依次執行

路由分發

當一個url請求過來之後,先到專案主目錄下的urls內。然後由這個url做處理分發給其他app內的urls 一級路由:主目錄urls內引入include   二級路由:只查詢本地urls內的路徑

自動生成路由:SimpleRouter、DefaultRouter
  ViewSetMixin+9個子類檢視才能自動生成路由
Default與Simple的區別是,Default會多附帶一個預設的API根檢視,返回一個包含所有列表檢視的超連結響應資料。

# 1 匯入路由類
from rest_framework.routers import SimpleRouter, DefaultRouter # 2 例項化得到物件
router = SimpleRouter() # 3 註冊路由
router.register('books', views.BookView)

DRF

Restful 規範

RESTful是一種定義Web   API介面的設計風格,尤其適用於前後端分離的應用模式中。

資料的安全保障:url連結一般都採用https協議進行傳輸(資料互動中安全性)
介面特性表現:一看就知道是個api介面,用api關鍵字標識介面url:https://api.baidu.com
多資料版本共存:在url連結中標識資料版本https://api.baidu.com/v1
資料即是資源,均使用名詞(可複數),儘量不要出現動詞
資源操作由請求方式決定(method):提供請求方式來標識增刪改查動作
過濾,通過在url上傳參的形式傳遞搜尋條件:例如url後面?=搜尋,分頁,遊標

jwt認證

JWT(JSON Web Token)
JWT 就是一種在使用者登入後生成token 並把token 放在前端,後端不需要維護使用者的狀態資訊但是可以驗證token 有效性的認證及狀態管理方式。
JWT的構成(base64的使用:加碼和解碼)
1.	頭部(Header)存放如何處理token的方式:加密的演算法、是否有簽名等
2.	載荷(Payload)資料的主體部分:使用者資訊、發行者、過期時間等
3. 簽名(Signature)將header、payload再結合密碼鹽整體處理一下

最後一步簽名的過程,實際上是對頭部以及負載內容進行簽名,防止內容被篡改。如果有人對頭部以及負載的內容解碼 之後進行修改,再進行編碼,最後加上之前的簽名組合形成新的JWT的話,那麼伺服器端會判斷出新的頭部和負載形式 的簽名和JWT附帶上的簽名是不一樣的。如果要對新的頭部和負載進行簽名,在不知道伺服器加密時用的金鑰的話,得 出來的簽名也是不一樣的。

View家族

兩個基類
APIView 是REST framework提供的所有檢視的基類,繼承自Django的View父類
GenericAPIView[通用檢視類]繼承自APIVIew,主要增加了操作序列化器和資料庫查詢的方法,作用是為下面Mixin擴充套件 類的執行提供方法支援。通常在使用時,可搭配一個或多個Mixin擴充套件類。
# 5個檢視擴充套件類(rest_framework.mixins) CreateModelMixin:create方法建立一條DestroyModelMixin:destory方法刪除一條ListModelMixin:list方法獲取所有RetrieveModelMixin:retrieve獲取一條UpdateModelMixin:update修改一條

# 9個子類檢視(rest_framework.generics)
CreateAPIView:繼承CreateModelMixin,GenericAPIView,有post方法,新增資料DestroyAPIView:繼承DestroyModelMixin,GenericAPIView,有delete方法,刪除資料ListAPIView:繼承ListModelMixin,GenericAPIView,有get方法獲取所有UpdateAPIView:繼承UpdateModelMixin,GenericAPIView,有put和patch方法,修改資料RetrieveAPIView:繼承RetrieveModelMixin,GenericAPIView,有get方法,獲取一條

ListCreateAPIView:有get獲取所有,post方法新增RetrieveDestroyAPIView:有get方法獲取一條,delete方法刪除RetrieveUpdateAPIView:有get獲取一條,put,patch修改
RetrieveUpdateDestroyAPIView:有get獲取一條,put,patch修改,delete刪除

# 檢視集
ViewSetMixin:重寫了as_view ViewSet:繼承ViewSetMixin和APIView
GenericViewSet:繼承ViewSetMixin, generics.GenericAPIView ModelViewSet:繼承了GenericViewSet和五個檢視擴充套件類,5個介面都有
ReadOnlyModelViewSet:繼承mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet

action裝飾器
   自動生成路由後,使用action裝飾器來繼續讓寫在檢視類的方法,可以被訪問到

序列化器、區域性,全域性鉤子

前後端不分離專案:有form元件幫我們去做資料校驗,有模板語法,從資料庫取出的queryset物件不需要人為去轉格式 前後端分離專案:我們需要自己去做資料校驗,手動去轉資料格式,因為跨平臺資料傳輸都用json字串,不能直接jsonqueryset物件
1 序列化:把python中的物件轉成json格式字串,序列化器會把模型物件轉換成字典,經過response以後變成json字串
2 反序列化:把json格式字串轉成python中的物件,把客戶端傳送過來的資料,經過request以後變成字典source:指定要序列化的欄位,只有一個欄位(也可以跨表)
SerializerMethodField:跨表查((來定製返回的欄位)要麼是列表,要麼是字典) 序列化器
   -定義一個類,繼承Serializer
   -在類內些欄位(常用欄位,和非常用欄位)(欄位引數)
   -在檢視類中,例項化得到一個序列化類的物件,傳入要序列化的資料
   -物件.data---》就是字典
serializer不是隻能為資料庫模型類定義,也可以為非資料庫模型類的資料定義。serializer是獨立於資料庫之外的存 在。如果我們想要使用序列化器對應的是Django的模型類,DRF為我們提供了ModelSerializer模型類序列化器來幫助我 們快速建立一個Serializer類
 區域性鉤子,全域性鉤子函式
 單個欄位校驗,validate_欄位名
 在序列化器中需要同時對多個欄位進行比較驗證時,可以定義validate方法來驗證

rbac模式

RBAC 是基於角色的訪問控制(Role-Based Access Control )
在 RBAC 中,許可權與角色相關聯,使用者通過成為適當角色的成員而得到這些角色的許可權。這就極大地簡化了許可權的管理。這樣管理都是層級相互依賴的,許可權賦予給角色,而把角色又賦予使用者,這樣的許可權設計很清楚,管理起來很方 便。

應用:Django的 Auth元件 採用的認證規則就是RBAC
1)	像專門做人員許可權管理的系統(CRM系統)都是公司內部使用,所以資料量都在10w以下,一般效率要求也不是很高
2)	使用者量極大的常規專案,會分兩種使用者:前臺使用者(三大認證) 和 後臺使用者(BRAC來管理)
結論:沒有特殊要求的Django專案可以直接採用Auth元件的許可權六表,不需要自定義六個表,也不需要斷開表關係,單 可能需要自定義User表

分頁

 原生django有分頁功能,也可以自定義封裝分頁繼承Paginator類
 drf,三種分頁功能
 -基本分頁:PageNumberPagination
   page_size = 2 # 每頁顯示兩條
   page_query_param = 'page' #查詢第幾頁的引數 ?page=3
   max_page_size = 4     #每頁最大顯示多少條
   page_size_query_param = 'size' #每頁顯示的條數查詢條件(預設是page_size顯示的條數) # ? page=3&size=3
    
 -偏移分頁:LimitOffsetPagination
   default_limit=2 #預設顯示幾條
   limit_query_param='limit'   # ?limit=3   表示取3條
   offset_query_param = 'offset' #偏移 ?offset=5&limit=3   #從第5個位置開始,取3條資料
   max_limit = 5   #最多顯示5條
    
 -遊標分頁:CursorPagination
   cursor_query_param = 'cursor' # 查詢的key值
   page_size = 2 # # 每頁顯示兩條
   ordering = 'id' # 按id欄位排序
    
# 配置使用的分頁類
   pagination_class = CustomNumberPagination 

過濾、排序

過濾:
1 過濾針對於 list 獲取所有(對於列表資料可能需要根據欄位進行過濾)
2 在請求路徑中帶過濾條件,對查詢結果進行過濾
# 在檢視中配置過濾類(區域性使用),然後配置過濾欄位
   filter_backends = [SearchFilter,]
   search_fields = ['name','price']     第三方過濾類使用(django-filter)
內建的SearchFilter過濾類,功能一般,如果想實現更高階的過濾,可以使用第三方通過新增django-fitlter擴充套件來增 強支援,自己定義過濾類,支援模糊查詢

排序:在類檢視中設定filter_backends(排序本身也是過濾)
對於列表資料,REST    framework提供了OrderingFilter過濾器來幫助我們快速指明資料按照指定欄位進行排序。

使用rest_framework.filters.OrderingFilter過濾器,REST framework會在請求的查詢字串引數中檢查是否包含了ordering引數,如果包含了ordering引數,則按照ordering引數指明的排序欄位對資料集進行排序。
前端可以傳遞的ordering引數的可選欄位值需要在ordering_fields中指明。

異常處理、自動生成介面文件

我們在生產環境中,需要把全部異常捕獲,輸入到日誌中。而且我們也不希望給錯誤頁面給使用者看到,這時候應該怎麼 辦呢?這時候可以針對 DRF 框架沒有處理的一些特殊的異常,進行全域性的異常處理。drf 提供了異常處理,我們可以自定義異常處理函式。需要在配置檔案中宣告自定義的異常處理,如果未宣告,會採用預設的方式

DRF 可以自動幫助我們生成介面文件。介面文件以網頁的方式呈現。自動介面文件能生成的是繼承自APIView及其子類的檢視。生成介面文件需要coreapi庫的支援。在總路由中新增介面文件路徑。

文件路由對應的檢視配置為rest_framework.documentation.include_docs_urls, 引數title為介面文件網站的標題。
from rest_framework.documentation import include_docs_urls urlpatterns = [
   ...
   url(r'^docs/', include_docs_urls(title='My REST API'))
]

資料庫

索引、索引下推技術

索引:是一種資料結構(既結構資料),換句話說:索引就是一種組織資料的方式hash索引:
    hash索引是基於hash表實現,記算出hash值對應的k    value適合等值查詢,不適合範圍查詢樹索引:
    二叉樹:非葉子節點只允許最多兩個子節點存在,右邊的子節點大於當前節點的值,每個節點只儲存一個鍵值和數 據
    平衡二叉樹:左右高度子節點不超過1、在資料量大的時候會進行多次磁碟io,降低查詢效率 
    B樹(平衡樹):每個節點儲存更多的鍵值key和資料data,並且每個節點擁有更多的子節點。
 B+樹:
  在非葉子節點上,不儲存資料,只存放鍵值,能儲存更多的鍵值,所有資料均儲存在葉子節點,並且是按照順序排列 的。查詢資料會減少IO,資料查詢的效率更快。這使得B+樹在做範圍查詢、分段查詢、去重查詢、分組查詢異常簡單。
  
  為什麼索引結構預設使用B+樹,而不是Hash,二叉樹,紅黑樹? Hash:雖然可以快速定位,但是沒有順序,IO複雜度高。
二叉樹:樹的高度不均勻,不能自平衡,查詢效率跟樹的高度有關,並且IO代價高。 紅黑樹:樹的高度隨著資料量增加而增加,IO代價高。


普通索引 一張表中可以有多個普通索引,隨便一個欄位都可以建立的索引,我們平常建立的索引大部分都是普通索引聯合索引 好幾個欄位聯合起來建立的索引
唯一索引  業務中唯一的欄位適合建立唯一索引,一個表中可以有多個唯一索引
主鍵索引  和唯一索引一樣,主鍵索引也是唯一的,不同的就是,一個表只能有一個主鍵索引

索引下推技術:
索引下推(index condition pushdown )簡稱ICP 在不使用ICP的情況下,在使用非主鍵索引(又叫普通索引或者二級索 引)進行查詢時,儲存引擎通過索引檢索到資料,然後返回給MySQL伺服器,伺服器 然後判斷資料是否符合條件, 在使用ICP的情況下,如果存在某些被索引的列的判斷條件時,MySQL服 務器將這一部分判斷條件傳遞給儲存引擎,然後由儲存引擎通過判斷索引是否符合   MySQL伺服器傳遞的條件,只有當索引符合條件時才會將資料檢索出來返回給MySQL伺服器 。 索引條件下推優化可以減少儲存引擎查詢基礎表的次數,也可以減少MySQL 伺服器從儲存引擎接收資料的次數。


explain、事務

explain :索引執行計劃檢視 rows的大小 rows是核心指標、優化語句 主要在優化rows 

事務(ACID):
資料庫事務指的則是作為單個邏輯工作單元執行的一系列操作(SQL語句)   功能:
  1、為資料庫操作提供了一個從失敗中恢復到正常狀態的方法,同時提供了資料庫即使在異常狀態下仍能保持一致性 的方法。 
  2、當多個應用程式在併發訪問資料庫時,可以在這些應用程式之間提供一個隔離方法,以防止彼此的操作互相干 擾。
  這些操作要麼全部執行,要麼全部不執行。
  
事務的四大特性? 原子性 Atomicity
     事務作為一個整體,包含在其中對於資料庫的操作,要麼全部執行,要麼全部不執行。
        例如:A給B轉了100,A餘額減100,剛轉完系統崩潰,B收到錢款這一操作沒有執行,
        則整個事務回滾,100元退還到A的餘額一致性 Consistency
    事務應該確保資料庫從一致狀態轉到另一個一致狀態。
       例如:轉賬行為中,一個人減了50元,另外一個人就應該加上這50元,而不能是40元。
          其他一致狀態的含義是資料庫中的資料應滿足完整性約束,例如欄位約束不能為負數,
       事務執行完畢後的該欄位也同樣不是負數。隔離性 Isolation
    多個事務併發執行時,一個事務的執行應該不受其他事務執行的影響。
        舉例:A給B轉100元和C給B轉100元是獨立的。

永續性 Durability
    成功執行的事務產生的結果應該被永久保留在資料庫中

觸發器、儲存過程、檢視

觸發器:觸發器是一個特殊的儲存過程,它是MySQL在insert、update、delete    的時候自動執行的程式碼塊。

檢視:檢視是由查詢結果形成的一張虛擬表,是表通過某種運算得到的一個投影 
      create view view_name as select 語句 

儲存過程:把一段程式碼封裝起來,當要執行這一段程式碼的時候,可以通過呼叫該 儲存過程來實現(經過第一次編譯後再次呼叫不需要再次編譯,比一個個執行sql語 句效率高) 
    create procedure 儲存過程名(引數,引數,…)

常見約束

含義:一種限制,用於限制表中的資料,為了保證表中資料的準確性和可靠性。 分類:六大約束
1.	NOT NULL :非空,用於保證該欄位的值不能為空。例如學生表的學生姓名及學號等等。
2.	DEFAULT:預設值,用於保證該欄位有預設值。例如學生表的學生性別
3.	PRIMARY   KEY:主鍵,用於保證該欄位的值具有唯一性並且非空。例如學生表的學生學號等。
4.	UNIQUE:唯一,用於保證該欄位的值具有唯一性,可以為空。例如註冊使用者的手機號,身份證號等。
5.	CHECK:檢查約束(MySql不支援),檢查欄位的值是否為指定的值。
6.	FOREIGN KEY:外來鍵,用於限制兩個表的關係,用於保證該欄位的值必須來自於主表的關聯列的值,在從表新增外來鍵約束,用於引用主表中某些的值。例如學生表的專業編號
新增約束的實際: 1.建立表時
2.修改表時約束的新增分類:
列級約束:六大約束語法上都支援,但外來鍵約束沒有效果表級約束:除了非空、預設、其它的都支援。

SQL語句、SQL注入

SQL語言主要用於存取資料、查詢資料、更新資料和管理關係資料庫系統,SQL語言由IBM開發。SQL語言分為3種類型: 1、DDL語句   資料庫定義語言: 資料庫、表、檢視、索引、儲存過程,例如CREATE DROP ALTER
2、DML語句     資料庫操縱語言: 插入資料INSERT、刪除資料DELETE、更新資料UPDATE、查詢資料SELECT
3、DCL語句   資料庫控制語言: 例如控制使用者的訪問許可權GRANT、REVOKE

sql注入: 利用現有的程式,將惡意的sql命令注入到後臺的資料庫引擎執行的能力 像符號--會註釋掉之後的sql,根本原理就是字串的拼接name=‘%s' 原生sql中讓execute幫做拼接就可以,django的orm種就不會存在這個問題

MVCC、事務隔離級別、讀現象

多版本控制mvcc:
保證隔離性多版本併發控制,儲存資料在某個節點的快照,讀不加鎖,讀寫不衝突,增加併發建立時間的版本號,過期 時間的版本號,開啟新事務、版本號都會遞增 

事務的隔離級別:   未提交讀、提交讀、可重複讀、可序列化'鎖'
Read uncommitted(未提交讀):在這種事務隔離級別下,一個事務可以讀到另外一個事務未提交的資料。可能會髒讀Read committed(提交讀):在一個事務修改資料過程中,如果事務還沒提交,其他事務不能讀該資料。 可能不可重複讀Repeatable read(可重複讀):由於提交讀隔離級別會產生不可重複讀的讀現象。所以,比提交讀更高一個級別的隔離級別就可以解決不可重複讀的問題。這種隔離級別就叫可重複讀 
Serializable(可序列化):是最高的隔離級別,前面提到的所有的隔離級別都無法解決的幻讀,在可序列化的隔離級別 中可以解決 
innoDB 儲存引擎預設隔離級別為可重複讀(Repeatable Read),該隔離級別下,避免了髒讀、不可重複讀現象的產生,對於索引的查詢採用 next-key locks。 這樣做就避免了幻讀現象(未提交讀),(提交讀) 

讀現象': 髒讀、不可重複讀、幻讀 
髒讀:A事務讀取了已經被B事務更新但是還沒有提交的欄位之後,若此時B回滾,A讀取的內容就是無效的了,稱之為髒 資料;

不可重複讀:事務A按一定條件搜尋,期間事務B刪除了符合條件的某一條資料,導致A 再次讀取時資料少了一條。這種情況歸為不可重複讀;

幻讀:事務A 按照一定條件進行資料讀取,期間事務B插入了相同搜尋條件的新資料,事務A再次按照原先條件進行讀取時,發現了事務B新插入的資料 稱為幻讀;

前提:資料庫的併發場景有三種
讀-讀:不存在任何問題、不需要併發控制 
讀-寫:有隔離性問題,可能遇到髒讀、幻讀、不可重複讀寫-寫:可能存在更新丟失的問題

鎖機制

首先對mysql鎖進行劃分:
按照鎖的粒度劃分:行鎖、表鎖、頁鎖
按照鎖的使用方式劃分:共享鎖、排它鎖(悲觀鎖的一種實現) 還有兩種思想上的鎖:悲觀鎖、樂觀鎖。
InnoDB中有幾種行級鎖型別(三種演算法):Record Lock、Gap Lock、Next-key Lock Record Lock:在索引記錄上加鎖
Gap Lock:間隙鎖
Next-key Lock:Record Lock+Gap Lock--》解決幻讀問題

行鎖:只針對當前操作的行加鎖。行級鎖能減少資料庫操作的衝突。加鎖粒度最小,但加鎖的開銷也最大。有可能會出 現死鎖的情況。行級鎖按照使用方式分為共享鎖和排他鎖。
表鎖:只針對當前的操作對整張表加鎖,資源開銷比行鎖少,不會出現死鎖的情況,但是發生鎖衝突的概率很大。被大 部分的mysql引擎支援,MyISAM和InnoDB都支援表級鎖,但是InnoDB預設的是行級鎖。是mysql鎖中粒度最大的一種鎖, 頁鎖:頁級鎖是MySQL中鎖定粒度介於行級和表級中間的一種鎖。表級鎖速度快衝突多,行級衝突少速度慢。所以取了 折衷的頁級,一次鎖定相鄰的一組記錄。BDB支援頁級鎖

無論是悲觀鎖還是樂觀鎖,他們本質上不是資料庫中具體的鎖概念,而是我們定義出來,用來描述兩種類別的鎖的思想 樂觀鎖和悲觀鎖的概念不僅僅存在於資料庫領域,可以說存線上程安全,存在併發的場景幾乎都有樂觀鎖和悲觀鎖的適 用場景 悲觀鎖和樂觀鎖是一種思想也叫悲觀併發控制和樂觀併發控制還有MVCC 多版本併發控制

悲觀鎖PCC:見名知意,悲觀的認為你會修改資料,所以在我修改前就加鎖,再進行修改 
樂觀鎖OCC:假設資料不會衝突,在資料提交的時候才會進行衝突檢測,如果發現衝突了,則讓返回使用者錯誤的資訊,讓 使用者決定如何去做。

相對於悲觀鎖,在對資料庫進行處理的時候,樂觀鎖並不會使用資料庫提供的鎖機制。一般的實現樂觀鎖的方式就是記 錄資料版本

非同步IO和協程的實現

非同步io和協程我可以通過gevent模組去實現,但是gevent模組和python不相容,所以我得使用補丁.讓我的gevent模組可 以識別到我python的io.我可以對io進行自定義的協程的開啟和釋放..
非同步io的話,他是將io的操作交給了別人(kernel)去完成,然後這個過程我是不需要去等待的.即等著他傳送一個訊號給 我即可.我就不需要去檢查io操作的狀態.也不需要主動的去copy資料了.
我通過這個io非同步和協程的使用,我就可以提供我的併發量,像比較出名的非同步io有epoll,模組有asyncio,gevent,tornado.我在使用scrapy爬蟲的使用,是直接使用sync和await實現的非同步.而且我發現我即使這樣我的 處理速度還是不夠快,然後你說你就引了一個go的動態連結庫.我發現這個過程我的得下載gcc,然後我就研究了一下go的 高併發.結果發現go是因為有一個gmp模型.然後你再介紹gmp模型

redis

Redis資料型別、連結池、管道、事務,快取設計與優化

redis資料庫,非關係型(redis:記憶體資料庫,所有資料放在記憶體中 資料型別:字串,列表,字典(hash),集合,有序集合

連結池:連線池的作用相當於快取了多個客戶端與redis服務端的連線,當有新的客戶端來進行連線時,此時,只需要 去連線池獲取一個連線即可,實際上連線池就是把一個連線共享給多個客戶端,可以說是廣播,要用的話就去接收。 管道:非關係型資料庫,本身不支援事務,redis預設在執行每次請求都會建立(連線池申請連線)和斷開(歸還連線 池)一次連線操作,如果想要在一次請求中指定多個命令,則可以使用pipline實現一次請求指定多個命令,並且預設 情況下一次pipline 是原子性操作。

redis當中如何實現事務?(叢集不支援,單機才支援)
  具體實現:開啟管道,把命令放進去,呼叫execute依次執行管道中的所有命令,它的原理就是要麼一次性都執行, 要麼都不執行,保證了事務 

如果遇到訪問的介面新增修改操作比較頻繁怎麼解決呢?如果是訪問和新增修改同樣頻繁呢? 解答一:每次更新修改資料的時候,redis就刪除一次快取,下次訪問的時候再去mysql中取
解答二:在序列化器中重寫save方法,每次新增修改資料就刪除一次快取,這樣每次訪問該介面的時候再去資料庫中獲 取資料存到快取中,拿到的資料都是最新的,首次訪問快取沒有就去資料庫中拿資料,再次訪問的時候速度就快了。

好處: 加速讀寫
降低後端負載:後端伺服器通過前端快取降低負載,業務端使用redis降低後端mysql負載

應用場景:
1 降低後端負載:對高消耗的sql,join結果集/分組統計的結果做快取
2 加速請求響應:利用redis優化io響應時間
3 大量寫合併為批量寫:如計數器先redis累加再批量寫入db

快取雪崩

存雪崩是指快取同⼀時間⼤⾯積的失效,所以,後⾯的請求都會落到資料庫上,造成資料庫短時間內承受⼤量請
求⽽崩掉。
解決⽅案
1. 快取資料的過期時間設定隨機,防⽌同⼀時間⼤量資料過期現象發⽣。
2. ⼀般併發量不是特別多的時候,使⽤最多的解決⽅案是加鎖排隊。
3. 給每⼀個快取資料增加相應的快取標記,記錄快取的是否失效,如果快取標記失效,則更新資料快取。

快取穿透

快取穿透是指快取和資料庫中都沒有的資料,導致所有的請求都落到資料庫上,造成資料庫短時間內承受⼤量請求
⽽崩掉。
解決⽅案
1. 接⼝層增加校驗,如⽤戶鑑權校驗,id做基礎校驗,id<=0的直接攔截;
2. 從快取取不到的資料,在資料庫中也沒有取到,這時也可以將key-value對寫為key-null,快取有效時間可以設
置短點,如30秒(設定太⻓會導致正常情況也沒法使⽤)。這樣可以防⽌攻擊⽤戶反覆⽤同⼀個id暴⼒攻擊
3. 採⽤布隆過濾器,將所有可能存在的資料雜湊到⼀個⾜夠⼤的 bitmap 中,⼀個⼀定不存在的資料會被這個
bitmap 攔截掉,從⽽避免了對底層儲存系統的查詢壓⼒

附加
對於空間的利⽤到達了⼀種極致,那就是Bitmap和布隆過濾器(Bloom Filter)。
Bitmap: 典型的就是雜湊表
缺點是,Bitmap對於每個元素只能記錄1bit資訊,如果還想完成額外的功能,恐怕只能靠犧牲更多的空間、時間來
完成了。

布隆過濾器(推薦)

就是引⼊了k(k>1)k(k>1)個相互獨⽴的雜湊函式,保證在給定的空間、誤判率下,完成元素判重的過程。
它的優點是空間效率和查詢時間都遠遠超過⼀般的演算法,缺點是有⼀定的誤識別率和刪除困難。
Bloom-Filter演算法的核⼼思想就是利⽤多個不同的Hash函式來解決“衝突”。
Hash存在⼀個衝突(碰撞)的問題,⽤同⼀個Hash得到的兩個URL的值有可能相同。為了減少衝突,我們可以多
引⼊⼏個Hash,如果通過其中的⼀個Hash值我們得出某元素不在集合中,那麼該元素肯定不在集合中。只有在所
有的Hash函式告訴我們該元素在集合中時,才能確定該元素存在於集合中。這便是Bloom-Filter的基本思想。
Bloom-Filter⼀般⽤於在⼤資料量的集合中判定某元素是否存在

快取擊穿

快取擊穿是指快取中沒有但資料庫中有的資料(⼀般是快取時間到期),這時由於併發⽤戶特別多,同時讀快取沒
讀到資料,⼜同時去資料庫去取資料,引起資料庫壓⼒瞬間增⼤,造成過⼤壓⼒。和快取雪崩不同的是,快取擊穿
指併發查同⼀條資料,快取雪崩是不同資料都過期了,很多資料都查不到從⽽查資料庫。
解決⽅案
1. 設定熱點資料永遠不過期。
2. 加互斥鎖,互斥鎖

快取預熱

快取預熱就是系統上線後,將相關的快取資料直接載入到快取系統。這樣就可以避免在⽤戶請求的時候,先查詢數
據庫,然後再將資料快取的問題!⽤戶直接查詢事先被預熱的快取資料!
解決⽅案
1. 直接寫個快取重新整理⻚⾯,上線時⼿⼯操作⼀下;
2. 資料量不⼤,可以在項⽬啟動的時候⾃動進⾏載入;
3. 定時重新整理快取

Celery進行非同步任務、定時任務的處理,包結構封裝與使用

Celery非同步任務框架:是一個簡單、靈活且可靠的,處理大量訊息的分散式系統,專注於實時處理的非同步任務佇列,同 時也支援任務排程
應用場景:
非同步任務:解決耗時任務,將耗時操作任務提交給Celery去非同步執行,比如傳送簡訊/郵件、訊息推送、音視訊處理等等 延遲任務:解決延遲任務(延遲多長時間,執行一個任務)
定時任務:定時執行某件事情,比如每天資料統計

Celery的架構由三部分組成,訊息中介軟體(message broker)、任務執行單元(worker)和 任務執行結果儲存(task result store)組成
訊息中介軟體
Celery本身不提供訊息服務,但是可以方便的和第三方提供的訊息中介軟體整合。包括,RabbitMQ,   Redis等等

任務執行單元
Worker是Celery提供的任務執行的單元,worker併發的執行在分散式的系統節點中。

任務結果儲存
Task result store用來儲存Worker執行的任務的結果,Celery支援以不同方式儲存任務的結果,包括AMQP, redis等

Git專案版本管理工具、docker部署

工作中常用的幾個git命令:
新增檔案的命令:git add file或者git add .
提交檔案的命令:git commit –m 或者 git commit –a 檢視工作區狀況:git status –s
拉取合併遠端分支的操作:git fetch/git merge或者git pull 檢視提交記錄命令:git reflog

我們公司開發用的gitee,有個主分支,我們大家開發都用一個分支,所有人共用一個,它的好處是不存在合併時發生 衝突,我們採用敏捷開發的

Linux操作命令

cd:是切換到你要的目錄裡去
ls:是顯示資料夾裡面有些什麼檔案mkdir:是建立資料夾
touch:是建立檔案
mv:是移動某個檔案到對應的資料夾下vim:是用來做文字編輯的
tree:是顯示目錄層級
echo:相當於python的print,是輸出的列印的意思rm:是刪除

生產者消費者模型

什麼是生產者消費者模型?
生產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過 阻塞佇列來進行通訊,所以生產者生產完資料之後不用等待消費者處理,直接扔給阻塞佇列,消費者不找生產者要資料,而是直接從阻塞佇列裡取,阻塞佇列就相當於一個緩衝區,平衡了生產者和消費者的處理能力。

基於佇列實現生產者消費者模型

"""
生產者:生產/製造東西 消費者:消費/處理東西的
該模型除了上述兩個之外,還需要一個媒介
生活中的例子:做包子的將包子做好之後放在蒸籠(媒介)裡面,買包子的去蒸籠裡面拿 廚師做菜做完之後用盤子裝著給消費者端過去
生產者和消費者之間不是直接做互動的,而是藉助於媒介做互動
生產者(做包子的) +   訊息佇列(蒸籠) + 消費者(吃包子的)

orm可以怎麼優化?

批量建立 bulk_create()
儘量不要在迴圈中操作 QuerySet
用values( )或values_list( )只取需要的列的資料
使用iterator()方法來獲取資料,處理完資料就將其丟棄select_related 查詢外來鍵
prefetch_related 處理一對多、多對多查詢

資料庫可以怎麼優化?

索引、MySQL叢集、負載均衡、讀寫分離
 
程式效率可以怎麼優化?
只加載必要的模組,延遲載入快取優化
伺服器架構優化
後端可以使用uwsgi
前端使用nginx 或者F5做負載均衡

Go:常用變數型別、函式與包的使用、邏輯語句、go檔案編譯打包

mysql,redis 高階

mysql主從同步: 業務、做高可用 兩個nginx和兩個tomcat兩個mysql實現高可用,避免 單點問題、中間使用keepalived監聽 1、實現伺服器負載均衡
2、通過複製實現資料的異地備份、提高資料庫系統的可用性 

原理: 1.Master 資料庫只要發生變化,立馬記錄到Binary log 日誌文 件中 
2.Slave資料庫啟動一個I/O thread連線Master資料庫,請求 Master變化的二進位制日誌 
3.Slave I/O獲取到的二進位制日誌,儲存到自己的Relay log 日誌 檔案中。 
4.Slave 有一個 SQL thread定時檢查Realy log是否變化,變化 那麼就更新資料 

主從延遲:1. 首先就是主庫可以併發寫入,從庫只能通過單sql thread完成任務 (MySQL5.7之前) 
2.  MySQL主從之間的同步,本來就不是時時同步的,是非同步的同步,也 就是說,主庫提交
事務之後,從庫才再來執行一遍。 
3. 在主庫上對沒有索引大表的列進行delete或者update的操作 
4. 從庫的硬體配置沒有主庫的好,經常忽略從庫的重要性 
5. 網路問題 '解決': 1. 避免一些無用的IO消耗,可以上高轉速的磁碟,SSD或者PCIE-SSD 裝置 
2. 陣列級別要選擇RAID10,raid cache策略要使用WB堅決不要WT。 
3. IO排程要選擇deadline模式。 
4. 適當調整buffer pool的大小 

redis非關係型鍵值對NoSQL資料庫' AOF和RDB 'Redis持久化': 
RDB方案: 快照,某時刻完成備份、寫日誌、任何草錯記錄日誌,要恢復資料、只要把 日誌從新走一遍即可 
AOF方案:   客戶端每寫入一條命令,都記錄一條日誌,放到日誌檔案中、如果出現宕機、可以將資料完全恢復.三種策略.日誌不是直接寫到硬碟上,而是放在緩衝區,緩衝區根據一些策略、寫到硬碟 aof重寫: 本質就是把過期的,無用的,可以優化的命令,來優化,減少磁碟佔用量,加快恢復速度 

主從複製: 高可用: 
    1、副本庫通過slaveof 127.0.0.1 6379命令,連線主庫、併發送sync給主庫 
    2、主庫收到sync,觸發BGSAVE,後臺儲存RDB,傳送給副本庫 
    3、副本庫接受或會應用RDB快照、 
    4、主庫會陸續將中間產生的新的操作、儲存併發送給副本庫 
    5、到此、主複製集就正常工作 
    6、再此後、主庫只要發生新的操作、都會以命令傳播形式自動傳送給副本庫 
    7. 所有複製相關資訊,從info資訊中都可以查到.即使重啟任何節點,他的主從關 系依然都在. 
    8. 如果發生主從關係斷開時,從庫資料沒有任何損壞,在下次重連之後,從庫傳送 PSYNC給主庫 
    9. 主庫只會將從庫缺失部分的資料同步給從庫應用,達到快速恢復主從的目的 
    
哨兵高可用: 
    1 多個sentinel發現並確認master有問題 
    2 選舉觸一個sentinel作為領導 
    3 選取一個slave作為新的master 
    4 通知其餘slave成為新的master的slave 
    5 通知客戶端主從變化 

 6 等待老的master復活成為新master的slave 
    
快取雪崩: 大量快取資料在同一時間過期、redis服務宕機、剛好大量使用者請求、都無法在 redis中處理,都會直接訪問資料庫造成高併發、導致資料庫宕機,形成連鎖反應導致伺服器崩潰 
解決方案: 
1 快取資料的過期時間設定隨機,防止同一時間大量資料過期現象發生。
2 如果快取資料庫是分散式部署,將熱點資料均勻分佈在不同搞得快取資料庫中。
3 設定熱點資料永遠不過期。

快取預熱:  業務剛上線的時候就提前把資料快取起來、針對快取雪崩的資料過期的一種方式 

快取擊穿:業務被頻繁訪問,稱為熱資料大量請求訪問的熱資料過期了,無法從快取中讀取,直接訪問資料庫,引起數 據庫壓力瞬間增大,造成過大壓力
解決方案:設定熱點資料永遠不過期。

快取穿透:快取穿透是使用者訪問資料不在快取不在資料庫、所有訪問快取的時候,快取缺失、訪問資料庫、資料庫也沒 有、沒辦法構建快取,這樣大量訪問來的時候就會造成快取穿透,這時的使用者很可能是攻擊者,攻擊會導致資料庫壓力 過大。
解決方案:
1   限制非法請求(介面層增加校驗,如使用者鑑權校驗,id做基礎校驗,id<=0的直接攔截)
2 快取空值(將key-value對寫為key-null,快取有效時間可以設定短點,如30秒(設定太長會導致正常情況也沒法使用)。這樣可以防止攻擊使用者反覆用同一個id暴力攻擊)
3 利用布隆過濾器、 
redis淘汰機制: 用一定的快取丟失來換取記憶體的使用效率。

uWSGI和nginx的理解

 uWSGI是一個web伺服器,它實現了WSGI協議,uwsgi、http等協議,
 Nginx中HttpUwsgiModule的作用是與uWSGI伺服器進行交換,
 WSGI是一種Web伺服器閘道器介面,他是一個Web伺服器與web應用通訊的一種規範
   WSGI是一種通訊協議
      uwsgi是一種線路協議而不是通訊協議,在此常用語在uWSGI伺服器與其他網路伺服器的資料通訊
   uWSGI是實現了uwsgi和WSGI兩種協議的Web伺服器
   nginx是一個開源的高效能的HTTP伺服器和反向代理:
       1.作為web伺服器,它處理靜態檔案和索引檔案效果非常高
       2.它的設計非常注重效率,最大支援5萬個併發連結,但只佔用很少的記憶體空間
       3.穩定性高,配置簡潔。
       4.強大的反向代理和負載均衡功能,平衡叢集中各個副武器的負載壓力應用