1、Python基礎python
一、什麼是python?使用python有什麼好處?mysql
python是一種編程語言,它有對象、模塊、線程、異常處理和自動內存管理。它簡潔,簡單、方便、容易擴展、有許多自帶的數據結果,並且它開源linux
Python是一種解釋性語言,它的源代碼能夠直接運行,Python解釋器會將源代碼轉換成中間語言,以後再翻譯成機器碼再執行redis
二、可變類型與不可變類型算法
可變類型:list、dict、可變集合setsql
不可變類型:數字,str,tuple元組,frozenset數據庫
內存中的那塊內容(value)是否可變編程
可直接在原來的地址,修改設計模式
不可變的類型均可以被hash哈希數組
三、深淺copy
對不可變類型進行copy的話,都是深copy
對於可變類型進行copy的話,通常都是淺copy
淺拷貝只是增長了一個指針指向所複製的對象,共用一塊內存
深拷貝是增長一個指針而且開闢了新的內存,這個增長的指針指向這個新的內存,
In [42]: li = [1,2,3,[4,5]] In [43]: li2 = copy.copy(li) In [44]: li3 = copy.deepcopy(li) In [45]: li[-1][-1] = "222" In [46]: li Out[46]: [1, 2, 3, [4, '222']] In [47]: li2 Out[47]: [1, 2, 3, [4, '222']] In [48]: li3 Out[48]: [1, 2, 3, [4, 5]]
簡單來講,若是有嵌套的話,淺copy只複製第一層,深copy會複製全部的
四、range-and-xrange
py2: range() 生成的是列表 xrange() 生成的是一個生成器 py3: range() 就是一個生成器 xrange() 沒了
五、閉包
def func(): def inner(): print('aaaa') return inner func()() # aaaa
內部函數對外部函數做用域裏變量的引用(非全局變量),則稱內部函數爲閉包。
閉包的意義:返回函數對象+一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域
六、裝飾器
調用裝飾器實際上是一個閉包函數,
不修改函數的代碼與修飾方式,爲其餘函數添加附加功能
好比:插入日誌、性能測試、事物處理、緩存、權限驗證等
# 裝飾器 import time def login(func): def inner(): start_time = time.time() func() end_time = time.time() print("fun 執行時間",end_time-start_time) return inner @login def test(): for i in range(10000): for j in range(10000): pass print('test函數執行') test() # test函數執行 # fun 執行時間 2.0163347721099854
七、生成器
延遲操做,須要的時候才產生結果,而不是當即產生結果
在每次調用next()的時候執行,遇到yield語句返回
建立生成器的兩種方式:
li = [i for i in range(100)]、yield方法
八、迭代器
for循環的數據類型:集合數據類型+生成器
list,tuple,dict,set,str + generator
不是一次性把數據加載到內存,而是被next()函數調用,不斷返回下一個數據
九、*args與**kwargs
*args:位置參數 ('alex',18)
**kwargs:關鍵字參數 {'name'='alex','age'=18} 關鍵字參數必定要放在最後面
2、面向對象
一、經典類、新式類
經典類:深度優先,python2中
新式類:廣度優先,Python3中
二、繼承、多態、封裝
(1)繼承:類與類之間關係,Cat類是動物類,解決代碼重用問題
重用 父類的屬性與方法
def __init__(self, name, life_value, aggresivity, weapon): super().__init__(name, life_value, aggresivity,) # python3格式 self.weapon = weapon def attack(self, enemy): super().attack(enemy)
(2)多態:同一類事物多種形態
一個接口,多種形態
不該關注對象的類型自己,而是它如何使用的
鴨子類型:若是看起來像、叫聲像並且走起路來像鴨子,那麼它就是鴨子’
(3)封裝
私有化的屬性,私有化的方法,封裝起來,外部沒法調用 雙下劃線__foo
三、classmethod,staticmethod,property
(1)property:特性 (統一訪問 原則)
@property def bmi(self): return self.weight / (self.height ** 2)
把類的方法轉換爲屬性,直接 alex.bmi 調用
(2)staticmethod 靜態方法 (普通函數 ) 綁定到對象上
類內的函數實例化---> 普通函數 。 (類和對象均可以使用)
@classmethod def from_conf(cls): obj = settings.name, return obj
(3)classmethod 類方法 (def foo(cls)) 綁定到類上
將cls 類自己當作參數傳入,直接用類來調用函數,而不用藉助類實例
優雅地實現某個類的實例的構造
四、 new.init區別,如何實現單例模式
建立一個新實例時調用new new()在 init()以前被調用
初始化一個實例時調用init
單例模式設計的類只能實例化1個對象
# 方式1 python模板自帶單例模式 # admin.py class Admin(object): def register(self): pass site = Admin() # test.py from admin import site site.register() # 方式2 __new__ _instance class Single(object): _instance = None def __new__(cls,*args,**kwargs): if not cls._instance: cls._instance = super(Single,cls).__new__(cls,*args,**kwargs) return cls._instance
五、反射
「字符串」形式,操做對象的相關屬性或方法。
hasattr, getattr, setattr, delattr
ret = getattr(obj,'get_file')() # 反射 obj是實例對象,name是方法
3、併發
一、線程、進程的區別
(1)進程:程序的運行過程, os 資源調度、分配的基本單位 os的併發
(2)線程:進程的實體, cpu 調度、分派的基本單位 進程內部的併發
區別
一、進程有獨立的內存空間, 線程 共享 本進程 的內存空間
二、進程有獨立的系統資源 ,線程只有(程序計數器,一組寄存器,棧) 共享本進程的資源(內存,I/O,cpu)
三、獨立性:進程崩潰,不會影響其餘的(健壯) 線程崩潰,本進程的所有線程死掉
四、開銷:進程切換與建立 開銷大於 線程的
五、線程不能獨立執行 進程能夠
聯繫
均可併發、一個進程由1or多個線程 組成、一個進程中的全部線程共享該進程所有資源
二、協程、GIL
GIL:全局解釋器鎖(cpython解釋器), 同一時刻,在cpu只能有一個線程執行
協程:輕量級的線程,用戶控制調度的
單線程下(的併發), 遇到I/O阻塞,多個任務,自動切換
三、進程同步方式
一、Event事件 。 通知操做
二、互斥量。 加鎖
三、信號量。 生產者消費者模型 阻塞隊列Queue
四、臨界區 。保護區域
同步問題:生產者消費者模型,做者讀者問題,哲學家進餐問題
四、通訊方式
管道,系統IPC(消息隊列,信號量,信號,共享內存),套接字,遠程過程調用rpc
五、死鎖
多個進程運行,爭奪資源,一種僵局;沒有外力,進程,沒法繼續執行
致使死鎖的緣由:循環等待、不可搶佔、佔有且等待、互斥
死鎖處理:
一、預防 :破壞4個條件
二、避免:銀行家算法
三、檢測:算法檢測,清除死鎖
四、解除: 檢測到,撤銷進程or剝奪資源
六、select、poll和epoll (I/O多路複用)
能夠監視多個描述符
一個描述符就緒,通知應用程序,執行讀or寫操做
(1)select :
把文件描述符 fd 集合maxSize=1024,用戶態copy到內核態 開銷大,在內核,遍歷全部fd
(2)poll:
改善了鏈接數,不斷輪詢,fd集合 每次都copy到內核態
(3)epoll:
linux下的多路複用I/O接口, 只copy一次,只告知 ,剛變爲就緒狀態的fd
4、mysql數據庫
一、索引
B+數:二叉樹-->平衡二叉樹-->B數
一個排序好,數據結構 (協助快速查詢data) 範圍查詢
create index ix_age on t1(age); create index 索引名1,索引名2 on 表名('字段1','字段2')
(1)何時用?
常常 select查詢、表記錄超多
常常須要搜索的列、主鍵列、鏈接的列(外鍵)、範圍查找 age in [20,40]、排序的列 salary、where上的列
(2)何時不用?
常常update,delete,insert 表記錄少
不常用的列 addr,數據值不多的列 blog,文本,image,bit 修改>查詢的
二、存儲過程
至關於 函數,封裝了,一系列,可執行的sql語句,存放在mysql中
直接調用它的名稱
create procedure p1() BEGIN select * from blog; INSERT into blog(name,sub_time) values("xxx",now()); END
優勢:網絡傳輸量小,程序與slq解耦
缺點:程序猿拓展功能不方便
三、數據庫引擎
INNODB 支持事務,外鍵,行鎖, 查表總行數,全表掃描
MYISAM不支持事務,不支持外鍵,表鎖(插入data,鎖定這個表),查表總行數,不須要全表掃描
四、redis
key-value數據庫 ,常常用的data放在redis
性能極高,支持多種數據類型 ,放在內存中 (必要時能夠寫入硬盤)
5、網絡
一、http經常使用的狀態碼
200:請求成功 OK
202:服務器接受請求,還沒有處理
302:重定向
304 :上次的文檔,已被緩存, 還可繼續使用
400:客戶端請求語法or參數錯誤
403:服務器收到請求,拒絕提供服務,找不到cookie
404:客戶端請求的資源url不存在
500: 服務器的程序出現錯誤
503:服務器當前時間不能處理客戶端的請求,一段時間後恢復
二、HTTP請求方式
HTTP1.0 GET/HEAD/POST
HTTP1.1 PUT/DELETE/CONNECT/OPTIONS/TRACE
3.GET/POST區別
(1)get提交的數據放在url後 /?name=alex&age=18 http請求頭
post的數據放在http報請求體
(2)GET的數據大小有限制,POST沒有限制
(3)GET方式會帶來安全問題,在url出現信息,可能得到username password
(4)在服務端 獲取請求數據方式不一樣
四、http請求頭,請求體
協議版本,狀態碼,狀態碼緣由 HTTP /1.1 200 OK
Cookie:
Content-Language
Content-Type 文本類型
Content-Length 請求體長度
User-Agent: 瀏覽器的身份標識,類型,手機端or電腦端
Date:時間
請求體
五、TCP/UDP區別 (運輸層)
一、TCP 傳輸控制協議,面向鏈接的,可靠的,數據流傳輸 ,注重data安全性,傳輸慢,面向字節流
二、UDP用戶數據報文協議,非面向鏈接的,不可靠,數據流傳輸, data傳輸快,安全性通常,面向報文
淺拷貝只是增長了一個指針指向一個存在的地址,
深拷貝是增長一個指針而且開闢了新的內存,這個增長的指針指向這個新的內存,
簡單地說,淺拷貝只拷貝一層(若是有嵌套),深拷貝拷貝全部層。
In [42]: li = [1,2,3,[4,5]] In [43]: li2 = copy.copy(li) In [44]: li3 = copy.deepcopy(li) In [45]: li[-1][-1] = "222" In [46]: li Out[46]: [1, 2, 3, [4, '222']] In [47]: li2 Out[47]: [1, 2, 3, [4, '222']] In [48]: li3 Out[48]: [1, 2, 3, [4, 5]]
閉包的意義:返回的函數對象,不只僅是一個函數對象,在該函數外還包裹了一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域
def func(): def inner(): print('aaaa') return inner func()() # aaaa
調用裝飾器實際上是一個閉包函數,爲其餘函數添加附加功能,不修改被修改的源代碼和不修改被修飾的方式,裝飾器的返回值也是一個函數對象。
好比:插入日誌、性能測試、事物處理、緩存、權限驗證等,有了裝飾器,就能夠抽離出大量與函數功能自己無關的雷同代碼並繼續重用。
# 裝飾器 import time def login(func): def inner(): start_time = time.time() func() end_time = time.time() print("fun 執行時間",end_time-start_time) return inner @login def test(): for i in range(10000): for j in range(10000): pass print('test函數執行') test() # test函數執行 # fun 執行時間 2.0163347721099854
python是一種編程語言,它有對象、模塊、線程、異常處理和自動內存管理。它簡潔,簡單、方便、容易擴展、有許多自帶的數據結果,並且它開源
Python是一種解釋性語言,它的源代碼能夠直接運行,Python解釋器會將源代碼轉換成中間語言,以後再翻譯成機器碼再執行
數組和元祖之間的區別:數組內容能夠被修改,而元祖內容是隻讀的,不可被修改的,另外元祖能夠被哈希,好比做爲字典的key
os是模塊負責程序與操做系統的交互,提供了訪問操做系統底層的接口
sys模塊是負責程序與python解釋器的交互,提供了一系列的函數和變量,用於操控Python時運行的環境
py2: range() 生成的是列表 xrange() 生成的是一個生成器 py3: range() 就是一個生成器 xrange() 沒了
Pickle模塊讀入任何python對象,將它們轉換成字符串,而後使用dump函數將其轉儲到一個文件中——這個過程叫作pickling
反之從存儲的字符串文件中提取原始python對象的過程,叫作unpickling
生成器:Python使用生成器對延遲操做提供了支持。所謂延遲操做,是指在須要的時候才產生結果,而不是當即產生結果。這也是生成器的主要好處。
這裏,最難理解的就是generator和函數的執行流程不同。
函數是順序執行,遇到return語句或者最後一行函數語句就返回。generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次被next()調用時從上次返回的yield語句處繼續執行。
能夠直接做用於for
循環的數據類型:
list
、tuple
、dict
、set
、str
等;一類是generator
,包括生成器和帶yield
的 generator function。
不是一次性把數據加載到內存,而是被next()函數調用,不斷返回下一個數據
類方法:將類的函數轉換成類方法,函數上裝飾@classmethod會將函數的自動傳值參數改爲cls
靜態方法:此方法至關於給類擴展一個功能,將類內的函數實例化,給類或對象使用,此時類內的函數就是普通函數,無論是類仍是實例化的對象均可以使用
實例化:類的實例化就會產生一個實例(對象),能夠理解爲類()把虛擬的東西實例化,獲得具體存在的值
_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
GIL:全局解釋器鎖,是鎖在cpython解釋器上,致使同一時刻,同一進程只能有一個線程被執行
多進程:多進程模塊multiprocessing來實現,cpu密集型,IO計算型能夠用多進程
多線程:多線程模塊threading來實現,IO密集型,多線程能夠提升效率
協程:依賴於geenlet,對於多線程應用。cpu經過切片的方式來切換線程間的執行,遇到IO操做自動切換,線程切換時須要耗時,
而協成好處沒有切換的消耗,沒有鎖定概念。
進程:是資源管理單位,進行是相互獨立的,實現併發和併發
線程:是最小的執行單位,線程的出現爲了下降上下文切換的消耗,提供系統的併發性
IO多路複用:經過一種機制,能夠監聽多個描述符 select/poll/epoll
select:鏈接數受限,查找配對速度慢,數據由內核拷貝到用戶態
poll:改善了鏈接數,可是仍是查找配對速度慢,數據由內核拷貝到用戶態
epoll:epoll是linux下多路複用IO接口,是select/poll的加強版,它能顯著提升程序在大量併發鏈接中只有少許活躍的狀況下的系統CPU利用率
異步非阻塞:異步體如今回調上,回調就是有消息返回時告知一聲兒進程進行處理。非阻塞就是不等待,不須要進程等待下去,
繼續執行其餘操做,無論其餘進程的狀態。
1.縮進:4個空實現縮進,儘可能不使用Tab
2.行:沒行最大長度不超過79,換行可使用反斜槓
3.命名規範:
4.註釋規範:
enter_和_exit,上下文管理協議,即with語句,爲了讓一個對象兼容with語句,必須在這個對象類中聲明_enter_和_exit_方法,
使用with語句的目的就是把代碼塊放入with中執行,with結束後,自動完成清理工做,無須收到干預
經典類遵循:深度優先,python2中
新式類遵循:廣度優先,Python3中
可變:列表 字典 不可變: 數字 字符串 元祖
在python中,全部的名字都存在於一個空間中,它們在改空間中存在和被操做——這就是命名空間,它就好像一個盒子,在每一個變量名字都對應裝着一個對象,
當查詢變量的時候,會從該盒子裏面尋找相應的對象
B+樹(數據結構,平衡樹,根節點,子節點,數據) 索引可以讓數據庫查詢數據的速度上升,而使寫入數據的速度降低, 由於平衡樹這個結構必須一直維持在一個正確的狀態, 增刪改數據都會改變平衡樹各節點中的索引數據內容,破壞樹結構, 所以,在每次數據改變時, DBMS必須去從新梳理樹(索引)的結構以確保它的正確,這會帶來不小的性能開銷, 也就是爲何索引會給查詢之外的操做帶來反作用的緣由。
(Hash Table,又稱爲散列表),是一種線性表的存儲結構。經過把每一個對象的關鍵字k做爲自變量,經過一個哈希函數h(k),將k映射到下標h(k)處,並將該對象存儲在這個位置。
例如:數據集合{1,6,7,9},假設存在哈希函數h(x)使得h(1) = 0, h(6) = 2, h(7) = 4, h(9) = 5,那麼這個哈希表被存儲爲[1,None, 6, None, 7, 9]。 當咱們查找元素6所在的位置時,經過哈希函數h(x)得到該元素所在的下標(h(6) = 2),所以在2位置便可找到該元素。