日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python后端知识点的自我复习

發布時間:2024/3/26 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python后端知识点的自我复习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

python知識點

數據結構

Linux操作系統

計算機網絡

mysql數據庫

緩存redis:內存數據庫

web知識點


python知識點

python特點

(1)python是動態強類型語言,強語言不會發生隱式的類型轉換

(2)膠水語言,輪子多,應用廣泛

(3)性能問題,代碼維護問題,python2、3兼容問題

(4)python中一切皆對象

python2/3之間的差異

(1)print改為函數,python2中是一個關鍵字

(2)編碼,python3不再有unicode對象,默認str就是unicode

(3)除法,python3返回浮點數

(4)3中可以用super()直接調用父類函數

(5)高級解包,*args、**kwargs,分別返回tuple、dict

(6)新增,yield產生生成器,內置庫asyncio、enum、mock、ipaddress、concurrent.futures等

python函數傳遞

(1)傳遞可變類型參數

def do_ls(l):l.append(0)print(l)l = [] # 執行結果 do_ls(l) # [0] do_ls(l) # [0,0] do_ls(l) # [0,0,0]

(2)傳遞不可變類型參數

def do_str(s):s += "a"print(s)s = "hh" # 執行結果 do_str(s) # hha do_str(s) # hha

?因為在python中,對一個變量賦值,只是將對象的引用賦給變量,比如:a=1,本質上是1這個對象的引用賦予了a。回到上面的解析,傳遞可變參數給函數的時候,本質上將可變參數的引用傳入函數,所以在函數內使用的變量引用和外部的是一樣的,又因為是參數是可變類型,所以在函數內部發生修改時,外部的變量也一樣發生改變。不可變類型的參數,之所以沒有變化,是因為引用指向了其他對象。

def do_str(s):print("這是剛剛傳入的s,id為:", id(s)) # 這是剛剛傳入的s,id為: 140338339314032s += "a"print("這是發生改變后的s, id為:", id(s)) # 這是發生改變后的s, id為: 140338338859376print(s)s = "hh" print("這是外部s, id為:", id(s)) # 這是外部s, id為: 140338339314032 # 執行結果 do_str(s) # hha def do_ls(s):print("這是剛剛傳入的s,id為:", id(s)) # 這是剛剛傳入的s,id為: 139688067340160s += "a"print("這是發生改變后的s, id為:", id(s)) # 這是發生改變后的s, id為: 139688067340160print(s)s = [] print("這是外部s, id為:", id(s)) # 這是外部s, id為: 139688067340160 # 執行結果 do_ls(s) # ["a"]

?(3)注意點:函數中,默認參數只計算一次

def do_ls(l = [1]):l.append(1)print(l)do_ls() # [1,1] do_ls() # [1,1,1]

python中異常處理

try:# 無異常執行 except:# 發生異常執行 else:# 異常沒有發生,即執行 finally:# 無論是否發生異常都執行

注意:可以研究raise庫,出現異常的時候,可以自帶自定義的錯誤信息

python中的GIL鎖:

(1)影響:

? ? ? ? a、同一時間只能有一個線程執行字節碼

? ? ? ? b、CPU密集計算,難用到多核優勢

? ? ? ? c、IO期間會釋放GIL,對IO密集程序影響不大

(2)避免GIL影響的方式:

? ? ? ? a、CPU密集可以使用多線程+進程池

? ? ? ? b、IO密集使用多線程/協程

? ? ? ? c、cython擴展

(3)有GIL鎖也要關注線程安全,因為非原子操作存在,在IO的時候,GIL鎖會釋放,其他線程開始執行,有可能會出現線程不安全

服務端性能優化措施:

(1)web應用一般語言不會成為瓶頸,數據結構與算法優化

(2)數據庫:索引優化、慢查詢消除、批量操作減少IO,NoSQL

(3)網絡IO:批量操作、pipeline操作減少IO

(4)緩存:內存數據庫redis、memcached

(5)異步:asyncio、celery

(6)并發:gevent、多線程

生成器與迭代器:

(1)生成器:
????????生成器本質上就是一個函數,它記住了上一次返回時在函數體中的位置。對生成器函數的第二次(或第n次)調用,跳轉到函數上一次掛起的位置。而且記錄了程序執行的上下文。生成器不僅“記住”了它的數據狀態,生成還記住了程序執行的位置。

(2)迭代器:

????????迭代器是一種支持next()操作的對象。它包含了一組元素,當執行next()操作時,返回其中一個元素。當所有元素都被返回后,再執行next()報異常—StopIteration生成器一定是可迭代的,也一定是迭代器對象

(3)區別:
????????a、生成器是生成元素的,迭代器是訪問集合元素的一中方式
????????b、迭代輸出生成器的內容
????????c、迭代器是一種支持next()操作的對象
????????d、迭代器(iterator):其中iterator對象表示的是一個數據流,可以把它看做一個有序序列,但我們不能提前知道序列的長度,只有通過nex()函數實現需要計算的下一個數據。可以看做生成器的一個子集。

python面向對象:

(1)創建一個對象的時候,會先調用__new__方法,再調用__init__進行初始化

(2)類變量:可以通過類或實例直接訪問的變量,可以修改

class Person:Country = 'China'def __init__(self, name):self.name = namedef print_name(self):print(self.name)wjf = Person("wjf") wjf.print_name() # wjf print(wjf.Country) # China print(Person.Country) # ChinaPerson.Country = "CHINA"print(wjf.Country) # CHINA print(Person.Country) # CHINA

(3)classmethod和staticmethod的區別

? ? ? ? a、都可以class.method()的方式使用

? ? ? ? b、classmethod第一個參數是cls,可以引用類變量

? ? ? ? c、staticmethod用法和普通函數一樣,只是放到類里面組織

class Person:Country = 'China'def __init__(self, name):self.name = name@classmethoddef print_country(cls):print(cls.Country)@staticmethoddef join_name(first_name, last_name):print(first_name + last_name)Person.print_country() # China Person.join_name("vick", "·vi") # vick·vi

(4)__call__函數:將對象變成函數的使用方式,例如:可用于用戶改變狀態的場景

class Person:def __call__(self,name):print("my name is ", name)wjf = Person() wjf("wjf") # my name is wjf

python裝飾器decorator:

(1)python中一切皆對象,函數也可以作為參數傳遞

(2)裝飾器是接受函數作為參數,添加功能后返回一個新函數的函數(類)

(3)@語法糖的方式使用裝飾器

(4)注意裝飾器的調用順序:裝飾順序,就近原則;執行順序,就遠原則;執行結束:就近原則。也可以理解為,就近入棧,執行時按出棧順序入棧,結束時按順序出棧,最終才結束函數調用。

def test1(func):print("test1被調用")def test1_1(*args, **kwargs):print("test1_1被調用")res = func(*args, **kwargs)print("test1_1被調用-end")return resreturn test1_1def test2(func):print("test2被調用")def test2_2(*args, **kwargs):print("test2_2被調用")res = func(*args, **kwargs)print("test2_2被調用-end")return resreturn test2_2@test1 @test2 def test():print("test被調用")return "結束"print(test())""" test2被調用 test1被調用 test1_1被調用 test2_2被調用 test被調用 test2_2被調用-end test1_1被調用-end 結束 """

(5)帶參數的裝飾器

def test2(x):print("test2被調用")def test1(func):print("test1被調用")def test1_1(*args, **kwargs):print(x+1)res = func(*args, **kwargs)print("test1_1被調用-end")return resreturn test1_1return test1@test2(1) def test():print("test被調用")return "結束"print(test())""" test2被調用 test1被調用 2 test被調用 test1_1被調用-end 結束 """

(6)類裝飾器

class test:def __init__(self, use_int=False) -> None:self.use_int = use_intdef __call__(self, func):def _log(*args, **kwargs):if self.use_int:print("打開")else:print("不打開")res = func(*args, **kwargs)return resreturn _log@test(True) def mydo():print("mydo執行了")return "結束"print(mydo())""" 打開 mydo執行了 結束 """

python的設計模式:

(1)工廠模式:解決對象創建問題

(2)構造模式:控制復雜對象的創建(比如組裝電腦,這個模式允許自定義電腦的配置),創建和表示分離

(3)原型模式:通過原型的克隆創建新的實例

(4)單例模式:一個類只能創建同一個對象(容易被問到,甚至實現,比如說python的模塊)

class Singleton:def __new__(cls, *args, **kwargs):if not hasattr(cls, '_instance'):_instance = super().__new__(cls, *args, **kwargs)cls._instance = _instancereturn cls._instanceclass MyClass(Singleton):passc1 = MyClass() c2 = MyClass()print(c1 is c2) # true# is 和 == 的區別:is判斷引用是否一樣;==判斷值是否一樣

(5)對象池模式:預先分配同一個類型的一組實例

(6)惰性計算模式:延遲計算(python的property)

多線程threading模塊:?

(1)threading.Thread類用來創建線程;

(2)start()方法啟動線程;

(3)可以用join()等待線程結束。

python多進程:

(1)multiprocessing多進程模塊;

(2)Multiprocessing.Process類實現多進程;

(3)一般在cpu密集程序里,可以使用,提高程序效率。

python的垃圾回收機制:

(1)引用計數為主(缺點:循環引用無法解決);

(2)引入標記清除和分代回收解決引用技術的問題。


數據結構

常用內置庫數據結構和算法:
(1) 線性結構:語言內置,list、tuple;內置庫:array、collections.namedtuple

(2)鏈式結構:內置庫,collections.deque(雙端隊列)

(3)字典結構:語言內置,dict;內置,collections.Counter(計數器)、collections.OrderedDict(有序字典)

(4)集合:語言內置,set、frozenset(不可變)

(5)排序算法:語言內置,sorted

(6)二分算法:內置庫,bisect

(7)堆算法:heapq模塊

collections模塊用法:

(1)Counter:字典的子類,提供了可哈希對象的計數功能

(2)defaultdict:字典的子類,提供了一個工廠函數,為字典查詢提供了默認值

(3)OrderedDict:字典的子類,保留了他們被添加的順序

(4)namedtuple:創建命名元組子類的工廠函數

(5)deque:類似列表容器,實現了在兩端快速添加(append)和彈出(pop)

dict底層使用的哈希表:

(1)為了支持快速查找,使用了哈希表作為底層

(2)哈希表平均查找時間復雜度O(1)

(3)使用二次探查法解決哈希沖突問題

其他部分有關算法會重新更新。


Linux操作系統

日常開發用到命令:

根據進程名查看進程號:ps -ef | grep 進程名

根據進程號查看占用的端口:netstat -apn | grep 進程號 -m 顯示多少條

根據端口號查看使用的進程:lsof -i:端口號

實時抓取某個文件的內容:tail -f 文件名

Ubuntu的定時任務:crontab -l:顯示定時任務有哪些;crontab -e進入編輯

window下需要用到命令:

查看所有進程占用的端口:?netstat -ano

查看占用指定端口的進程信息:netstat -aon|findstr "8000"

根據進程號查看進程信息:?tasklist|findstr "10076"

結束進程:taskkill /T /F /PID 10076

進程與線程的區別:

(1) 進程是對運行時程序的封裝,是系統資源調度和分配的基本單位;

(2)線程是進程的子任務,cpu調度和分配的基本單位,實現進程內的并發;

(3)一個進程可以包含多個線程,線程依賴進程存在,并共享進程內存。

線程同步的方式:

(1)互斥量(鎖):通過互斥機制防止多個線程同時訪問公共資源;

(2)信號量:控制同一時刻多個線程訪問同一個資源的線程數;

(3)事件(信號):通過通知的方式保持多個線程同步。

進程間通信的方式:

(1)管道/匿名管道/有名管道(pipe)

(2)信號:比如用戶使用ctrl+c產生SIGINT程序終止信號;

(3)消息隊列(Message);

(4)共享內存;

(5)信號量;

(6)套接字(socket):最常用的方式,我們的web應用都是這種方式。

分頁機制:邏輯地址和物理地址分離的內存分配管理方案

(1)程序的邏輯地址劃分為固定大小的頁;

(2)物理地址劃分為同樣大小的幀;

(3)通過頁表對應邏輯地址和物理地址;

分段機制:為了滿足代碼的一些邏輯需求

(1)數據共享,數據保護,動態鏈接等;

(2)通過段表實現邏輯地址和物理地址的映射;

(3)每個段內部是連續內存分配,段和段之間是離散分配的

分段和分頁的區別:

(1) 頁是出于內存利用率的角度提出的離散分配機制;

(2)段是出于用戶角度,用于數據保護、數據隔離等用途的管理機制;

(3)頁的大小是固定的,操作系統決定的;段大小不確定,用戶程序決定。

虛擬內存:把一些暫時不用的內存信息放到硬盤上

(1)局部性原理,程序運行時只有部分必要的信息裝入內存;

(2)內存中暫時不需要的內容放到硬盤上;

(3)系統好像提供了比實際內存大得多的容量,為虛擬內存。

內存抖動:

(1)頻繁的頁調度,進程不斷產生缺頁中段;

(2)置換一個頁,又不斷再次需要這個頁;

(3)運行程序太多;頁面替換策略不好;

(4)解決方案,終止進程或者增加物理內存。

死鎖:一組進程中,每個進程都無限等待被該組進程中另一進程所占有的資源,因而永遠無法得到的資源,這種現象稱為進程死鎖,這一組進程就稱為死鎖進程

(1)互斥使用(資源獨占):一個資源每次只能給一個進程使用;

(2)占有且等待(請求和保持,部分分配):進程在申請新的資源的同時保持對原有資源的占有;

(3)不可搶占(不可剝奪):資源申請者不能強行的從資源占有者手中奪取資源,資源只能由占有者自愿釋放;

(4)循環等待:存在一個進程等待隊列 {P1 , P2 , … , Pn},其中P1等待P2占有的資源,P2等待P3占有的資源,…,Pn等待P1占有的資源,形成一個進程等待環路。

當死鎖產生的時候一定會有這四個條件,有一個條件不成立都不會造成死鎖。


計算機網絡

瀏覽器輸入一個url中間經歷的過程:

(1)DNS查詢(域名解析)

(2)TCP握手(3次握手)

(3)HTTP請求

(4)反向代理Nginx(負載均衡)

(5)uwsgi/gunicom

(6)web app響應

(7)TCP揮手(4次揮手)

TCP 和 UDP的區別:

(1)tcp,面向連接、可靠的、基于字節流

(2)無連接、不可靠、面向報文

5中IO模型:

(1)Blocking IO(阻塞io)

(2)Nonblocking IO(非阻塞io)

(3)IO multiplexing(io多路復用)

(4)Signal Driven IO(信號驅動io)

(5)Asynchronous IO(異步io)

io多路復用:

(1)為了實現高并發需要一種機制并發處理多個socket

(2)Linux常見的是select/poll/epoll

(3)可以使用單線程單進程處理多個socket

三握四揮:

(1)TCP/IP 協議是傳輸層的一個面向連接的安全可靠的一個傳輸協議,三次握手的機制是為了保證能建立一個安全可靠的連接,那么第一次握手是由客戶端發起,客戶端會向服務端發送一個報文,在報文里面:SYN標志位置為1,表示發起新的連接。當服務端收到這個報文之后就知道客戶端要和我建立一個新的連接,于是服務端就向客戶端發送一個確認消息包,在這個消息包里面:ack標志位置為1,表示確認客戶端發起的第一次連接請求。以上兩次握手之后,對于客戶端而言:已經明確了我既能給服務端成功發消息,也能成功收到服務端的響應。但是對于服務端而言:兩次握手是不夠的,因為到目前為止,服務端只知道一件事,客戶端發給我的消息我能收到,但是我響應給客戶端的消息,客戶端能不能收到我是不知道的。所以,還需要進行第三次握手,第三次握手就是當客戶端收到服務端發送的確認響應報文之后,還要繼續去給服務端進行回應,也是一個ack標志位置1的確認消息。通過以上三次連接,不管是客戶端還是服務端,都知道我既能給對方發送消息,也能收到對方的響應。那么,這個連接就被安全的建了。

?

(2)四次握手機制也是由客戶端去發起,客戶端會發送一個報文,在報文里面FIN位標志位置一,當服務端收到這個報文之后,我就知道了客戶端想要和我斷開連接,但是此時服務端不一定能做好準備,因為當客戶端發起斷開連接的這個消息的時候,對于服務端而言,他和還有可能有未發送完的消息,他還要繼續發送,所以呢,此時對于服務端而言,我只能進行一個消息確認,就是我先告訴服務端,我知道你要給我斷開連接了,但是我這里邊還可能沒有做好準備,你需要等我一下,等會兒我會告訴你,于是呢,發完這個消息確認包之后,可能稍過片刻它就會繼續發送一個斷開連接的一個報文啊,也是一個FIN位置1的報文也是由服務端發給客戶端的啊,這個報文表示服務端已經做好了斷開連接的準備,那么當這個報文發給客戶端的時候,客戶端同樣要給服務端繼續發送一個消息確認的報文一共有四次,那么,通過這四次的相互溝通和連接,我就知道了,不管是服務端還是客戶端都已經做好了斷開連接的

https加密過程

①https加密過程,為了防止中間人攻擊,所以先使用非對稱加密,產生了會話密鑰后,再使用會話密鑰進行對稱加密進行消息的傳輸。

②非對稱加密,就是服務端發送公鑰s給客戶端后,客戶端使用公鑰s加密了數據后,再發送給服務端,服務端可以使用私鑰進行解密。


mysql數據庫

事務是什么:

(1)事務是數據庫并發控制的基本單位;

(2)事務1可以看作是一系列sql語句的集合;

(3)事務必須要么全部執行成功,要么全部執行失敗(回滾);

事務的4個特性ACID:

(1)原子性:一個事務中所有操作全部完成或失敗;

(2)一致性:事務開始和結束之后數據完整新沒被破壞;

(3)隔離性:允許多個事務同時對數據庫修改和讀寫;

(4)持久性:事務結束之后,修改是永遠的不會丟失。

事務并發會出現4種問題:

(1)幻讀:一個事務第二次查出現第一次沒有的結果;

(2)非重復讀:一個事務重復讀兩次得到不同結果(獲得結果不是最新的);

(3)臟讀:一個事務讀取到另一個事務沒有提交的修改;

(4)丟失修改:并發寫入造成其中一些修改丟失。

事務的4種隔離級別:

(1)讀未提交:別的事務讀到未提交的數據;

(2)讀已提交:只能讀取已經提交的數據;

(3)可重復讀:同一個事務先后查詢結果一頁(默認);

(4)串行讀:事務完成串行化的執行,隔離級別最高,執行效率最低。

防止高并發下插入重復值:

(1)使用數據庫的唯一索引;

(2)使用隊列異步寫入;

(3)使用redis實現分布式鎖;

樂觀鎖和悲觀鎖:

(1)悲觀鎖,先獲取鎖再進行操作。一鎖二查三更新;

(2)樂觀鎖,先修改,更新的時候發現數據變了就回滾。

InnoDB和MyISAM引擎的區別:

(1)MyISAM不支持事務,InnoDB支持事務;

(2)MyISAM不支持外鍵,InnoDB支持外鍵;

(3)MyISAM只支持表鎖,InnoDB支持行鎖和表鎖;

B-Tree:

(1)多路平衡查找樹(每個節點最多m(m>=2)個孩子,稱為m階或者度);

(2)葉節點具有相同的深度;

(3)節點中的數據key從左到右是遞增的。

B+Tree:

(1)mysql實際使用的B+Tree作為索引的數據結構;

(2)只在葉子節點帶有指向記錄的指針(可以增加樹的度);

(3)葉子節點通過指針相連(實現范圍查詢)。

mysql索引的類型:

(1)普通索引(create index);

(2)唯一索引,索引列的值必須是唯一的(create unique index);

(3)多列索引;

(4)主鍵索引(primary key),一個表只能有一個;

(5)全文索引(fulltext index),InnDB不支持。

什么時候創建索引:

(1)經常用作查詢條件的字段(where條件);

(2)經常用作表連接的字段;

(3)經常出現在order by,group by 之后的字段。

哪些字段適合當索引:

(1)非空字段;

(2)區分度高,離散度大,作為索引的字段值盡量不要有大量相同值;

(3)索引的長度不要太長(比較耗費時間);

索引失效:口訣:模糊匹配、類型隱轉、最左匹配

(1)以%開頭的like語句,模糊搜索;

(2)出現隱式類型轉換(在python這種動態語言查詢中需要注意);

(3)沒有滿足最左匹配原則;

比如:a, b, c為聯合索引如果: where a b c; where a b; where a; where b c; 這個會導致索引失效

?聚集索引和非聚集索引:

(1)聚集和非聚集:是B+Tree葉節點存的是指針還是數據記錄;

(2)MyISAM索引和數據分離,使用的非聚集;

(3)InnoDB數據文件就是索引文件,主鍵索引就是聚集索引。

用該兩表來探究mysql連接的區別

內連接:

?(1)將左表和右表關聯起來的數據連接后返回;

(2)類似求兩個表的交集

(3)select * from A inner join B on A.id=B.id;

?外連接:

(1)左連接返回左表中所有記錄,即使右表中沒有匹配的記錄(left join);

(2)右連接返回右表中所有記錄,即使左表中沒有匹配的記錄(right join)

mysql分區:

(1)概念:分區就是把一張表分成N多個區塊。分區表是一個獨立的邏輯表,但是底層由多個物理子表組成。當查詢條件的數據分布在某一個分區的時候,查詢引擎只會去某一個分區查詢,而不是遍歷整個表。如果需要刪除某一個分區的數據,只需要刪除對應的分區即可。

(2)分區表的類型:

????????①range分區:按照范圍分區。比如按照時間范圍分區。

????????②list分區:和range分區相似,主要區別在于list是枚舉值列表的集合,range是連續的區間值的集合。對于list分區,分區字段必須是已知的,如果插入的字段不在分區時的枚舉值中,將無法插入。

? ? ? ? ③hash分區:可以將數據均勻地分布到預先定義的分區中。

(3)分區可能出現的問題:

????????①打開和鎖住所有底層表的成本可能很高。當查詢訪問分區表時,mysql需要打開并鎖住所有的底層表,這個操作在分區過濾前發生,所以無法通過分區過濾來降低此開銷,會影響到查詢速度,可以通過批量操作來降低此類開銷,比如批量插入、LOAD DATA INFILE和一次刪除多條數據。

????????②維護分區的成本可能很高,例如重組分區,會先創建一個臨時分區,然后將數據復制到其中,最后再刪除原分區。

????????③所有分區必須使用相同的存儲引擎。


緩存redis:內存數據庫

redis的作用:

(1)緩解關系數據庫(常見的是mysql)并發訪問的壓力:熱點數據;

(2)減少響應時間:內存IO速度比磁盤快;

(3)提升吞吐量:redis等內存數據庫單機就可以支撐很大的并發;

(4)redis和memcached主要區別,就是redis可以持久化。

redis的數據類型:

(1)String(字符串):用來實現簡單的kv鍵值對存儲,比如計數器;

(2)List(鏈表):實現雙向鏈表,比如用戶關注,粉絲列表;

(3)hash(哈希表):用來存儲彼此相關的鍵值對;

(4)set(集合):存儲不重復元素,比如用戶的關注者;

(5)sorted set(有序集合):實時信息排行榜


web知識點

什么是WSGI:

(1)解決python web server亂象;

(2)描述了web server(Gunicorn/uWSGI)如何與web框架(Flask/Django)交互,web框架如何處理請求;

web框架對比:

(1)Djingo:大而全,內置ORM、Admin等組件,第三方插件比較多;

(2)Flask:微框架,插件機制,比較靈活;

(3)Tornado:異步支持的微框架和異步網絡庫。

MVC是什么:

(1)Model:負責業務對象和數據庫的交互(ORM)

(2)View:負責與用戶的交互展示;

(3)Controller:接收請求參數調用模型和視圖完成請求。

常見的web安全問題:

(1)sql注入;

(2)xss(跨站腳本攻擊);

(3)csrf(跨站請求偽造)。

sql注入:

(1)通過構造特殊的輸入參數傳入web應用,導致后端執行了惡意sql;

(2)通常由于程序員未對輸入進行過濾,直接動態拼接sql產生;

(3)可以使用開源工具sqlmap、sqlninja檢測。

如何防范sql注入:永遠不要相信用戶的任何輸入

(1)對輸入參數做好檢查(類型和范圍);過濾和轉義特殊字符;

(2)不要直接拼接使用sql,使用ORM可以大大降低sql注入風險;

(3)數據庫層:做好權限管理配置;不要明文存敏感信息。

xss攻擊:

(1)惡意用戶將代碼植入到提供給其他用戶使用的頁面中,未經轉義的惡意代碼輸出到其他用戶的瀏覽器被執行;

(2)用戶瀏覽頁面的時候嵌入頁面的腳本(js)會被執行,攻擊用戶;

(3)主要分未為:反射型(非持久型)、存儲型(持久型)。

前后端分離是什么:

后端只負責提供數據接口,不再渲染模板,前端獲取數據并呈現

前后端分離的優點:

(1)前后端解耦,接口復用(前端和客戶端共用接口),減少并發量;

(2)各司其職,前后端同步開發,提升工作效率,定義號接口規范;

(3)更有利于調試(mock),測試和運維部署。

通俗易懂的RESTful:

本質上設計出來是為了解決url膨脹的問題,因為曾經的url,一個url對應一個操作、狀態等,后續會出現過多的url難以管理,所以出現了restful風格。通過在representation增加更多的描述,然后后端再根據描述返回對應的結果。所以restful風格沒有解決前后端的工作量,只是解決了url膨脹的問題。

什么是RESTful:

(1)表現層狀態轉移,由于http協議的主要設計者提出;

(2)資源(resources),表現層(representation),狀態轉化(state transfer)

(3)是一種以資源為中心的web軟件架構風格,可以用Ajax和RESTful web服務構建應用;

(4)Resources(資源):使用URI指向的一個實體;

(5)Representation(表現層):資源的表現形式,比如圖片、html文本;

(6)State Transfer(狀態轉化):get、post、put、delete http動詞來操作資源,實現資源狀態的改變。

RESTful的準則:?

(1)所有事物抽象為資源(resource),資源對應唯一的標識(identifier);

(2)資源通過接口進行操作實現狀態轉移,操作本身是無狀態的;

(3)對資源的操作不會改變資源的標識。

RESTful API:

(1)通過http get、post、put、delete 獲取、新建、更新、刪除 資源;

(2)一般使用json格式返回數據;

(3)一般web框架都有相應的插件支持RESTfu API。

python 運行后無法停止,查端口的方式linux (1)ps -ef | grep python (2)ps aux | grep python window (1)wmic process where name="python.exe" list full

session、cookie、token:

共同點:都是用于鑒權、記錄用戶信息、保持用戶操作

區別:

(1)session:存于服務端,記錄用戶信息,客戶端只存sessionId,缺點大量用戶需要session的時候,增加服務器的存儲成本

(2)cookie:存于客戶端,記錄用戶信息,缺點較為不安全?

(3)token:基于jwt,記錄用戶信息,客戶端存token,服務端只存token的密鑰

nginx分包方式(負載均衡):?

  • 源地址哈希法:根據獲取客戶端的IP地址,通過哈希函數計算得到一個數值,用該數值對服務器列表的大小進行取模運算,得到的結果便是客服端要訪問服務器的序號。采用源地址哈希法進行負載均衡,同一IP地址的客戶端,當后端服務器列表不變時,它每次都會映射到同一臺后端服務器進行訪問。
  • 輪詢法:將請求按順序輪流地分配到后端服務器上,它均衡地對待后端的每一臺服務器,而不關心服務器實際的連接數和當前的系統負載。
  • 隨機法:通過系統的隨機算法,根據后端服務器的列表大小值來隨機選取其中的一臺服務器進行訪問。
  • 加權輪詢法:不同的后端服務器可能機器的配置和當前系統的負載并不相同,因此它們的抗壓能力也不相同。給配置高、負載低的機器配置更高的權重,讓其處理更多的請;而配置低、負載高的機器,給其分配較低的權重,降低其系統負載,加權輪詢能很好地處理這一問題,并將請求順序且按照權重分配到后端。
  • 加權隨機法:與加權輪詢法一樣,加權隨機法也根據后端機器的配置,系統的負載分配不同的權重。不同的是,它是按照權重隨機請求后端服務器,而非順序。
  • 最小連接數法:由于后端服務器的配置不盡相同,對于請求的處理有快有慢,最小連接數法根據后端服務器當前的連接情況,動態地選取其中當前積壓連接數最少的一臺服務器來處理當前的請求,盡可能地提高后端服務的利用效率,將負責合理地分流到每一臺服務器。
  • php?

    操作數據庫分頁

    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <?phpclass MysqlConn {public $host, $port, $user, $passwd, $db;public $conn;function __construct($host, $port, $user, $passwd, $db){$this->host = $host;$this->port = $port;$this->user = $user;$this->passwd = $passwd;$this->db = $db;$this->conn = $this->getConn();}private function getConn() {$conn = new mysqli($this->host,$this->user, $this->passwd, $this->db, $this->port);if ($conn->connect_error) {throw new Exception($conn->connect_error);}return $conn;}function readRow($offset, $limit, $table, $where) {$sql = "select * from $table ";if (count($where) != 0) {$sql .= "where ";$lenNum = count($where);foreach ($where as $k=>$value) {$lenNum -= 1;if ($lenNum < 1) {$sql .= "$k = $value ";} else {$sql .= "$k = $value and ";}}}if ($limit != 0) {$sql .= "limit $limit ";}if ($offset != 0) {$sql .= "offset $offset";}echo $sql;$res = $this->conn->query($sql);if ($res) {while ($arr = $res->fetch_assoc()) {echo "<br>";echo var_dump($arr);}} else {echo "no row";}}function __destruct() {$this->conn->close();} } try {$conn = new MysqlConn("127.0.0.1", 3306, "root", "123456", "reward");echo "連接成功";$where = [// "id"=>19];$table = "users";$offset = 5;$limit = 5;$conn->readRow($offset, $limit, $table, $where); } catch (Exception $e) {echo $e->getMessage(); }

    ?通用分頁類:

    <?phpClass FY {public $maxNum;function __construct($num) {$this->maxNum = $num;}function getPageNum() {$pageNum = $_GET["pagenum"];return $pageNum;}function getData($pageNum) {$preNum = $pageNum-1;$preStr = "<a href='http://localhost:8080/php_stu/fy/fengye.php?pagenum=$preNum&&maxpage=$this->maxNum'><<< pre</a>";$preStrGrep = "<a style='color:gray;'><<< pre</a>";$nextNum = $pageNum+1;$nextStr = "<a href='http://localhost:8080/php_stu/fy/fengye.php?pagenum=$nextNum&&maxpage=$this->maxNum'>next >>></a>";$nextStrGrep = "<a style='color:gray;'>next >>></a>";// 小于等于0if ($this->maxNum <= 0) {echo $preStrGrep . "&nbsp" . $nextStrGrep;return;}$temA = "<a href='http://localhost:8080/php_stu/fy/fengye.php?pagenum=%s&&maxpage=$this->maxNum'>&nbsp %s &nbsp</a>";$temB = "<b>&nbsp %s &nbsp</b>";// [1,10]if ($this->maxNum <= 10) {$endStr = "";if ($pageNum == 1) {$endStr .= $preStrGrep;} else {$endStr .= $preStr;}for ($i=1; $i<=$this->maxNum;$i++) {if ($i == $pageNum) {$tempStr = sprintf($temB, $i);$endStr .= $tempStr;} else {$tempStr = sprintf($temA, $i, $i);$endStr .= $tempStr;}}if ($pageNum == $this->maxNum) {$endStr .= $nextStrGrep;} else {$endStr .= $nextStr;}echo $endStr;return;}// (10, +無窮)if ($this->maxNum > 10) {$endStr = "";if ($pageNum == 1) {$endStr .= $preStrGrep;} else {$endStr .= $preStr;}$startNum = 0; $endNum = 0;// 找起始, 加前綴if ($pageNum < 10) {$startNum = 1; $endNum = 10;} elseif ($pageNum >= 10 and $pageNum <= $this->maxNum-10) {$startNum = $pageNum -5;$endNum = $pageNum + 5;$endStr .= sprintf($temA, 1, 1);$endStr .= sprintf($temA, 2, 2);$endStr .= "&nbsp...&nbsp";} elseif ($pageNum > $this->maxNum-10) {$startNum = $this->maxNum-10;$endNum = $this->maxNum;$endStr .= sprintf($temA, 1, 1);$endStr .= sprintf($temA, 2, 2);$endStr .= "&nbsp...&nbsp";}for ($i=$startNum; $i<=$endNum;$i++) {if ($i == $pageNum) {$tempStr = sprintf($temB, $i);$endStr .= $tempStr;} else {$tempStr = sprintf($temA, $i, $i);$endStr .= $tempStr;}}// 加后綴if ($pageNum < 10) {$endStr .= "&nbsp...&nbsp";$endStr .= sprintf($temA, $this->maxNum-1, $this->maxNum-1);$endStr .= sprintf($temA, $this->maxNum, $this->maxNum);} elseif ($pageNum >= 10 and $pageNum <= $this->maxNum-10) {$endStr .= "&nbsp...&nbsp";$endStr .= sprintf($temA, $this->maxNum-1, $this->maxNum-1);$endStr .= sprintf($temA, $this->maxNum, $this->maxNum);} elseif ($pageNum > $this->maxNum-10) {// $endStr .= "&nbsp...&nbsp";}if ($pageNum == $this->maxNum) {$endStr .= $nextStrGrep;} else {$endStr .= $nextStr;}echo $endStr;return;}} }function getMaxPage() {$maxPage = $_GET["maxpage"];return $maxPage; }$maxPage = getMaxPage();$obj = new FY($maxPage); $pageNum = $obj->getPageNum(); $obj->getData($pageNum);

    ?效果如上

    總結

    以上是生活随笔為你收集整理的python后端知识点的自我复习的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。