a. Python(解釋型語言、弱類型語言)和其餘語言的區別?
1、編譯型語言:一次性,將所有的程序編譯成二進制文件,而後在運行。(c,c++ ,go)
運行速度快。開發效率低
2、解釋型語言:當你的程序運行時,一行一行的解釋,並運行。(python , PHP)
運行速度相對較慢,可是調試代碼很方便,開發效率高
html
3、混合型:(C#,Java)前端
python特色:java
CPython 當咱們從Python官方網站下載並安裝好Python 3.6後,咱們就直接得到了一個官方版本的解釋器:CPython。這個解釋器是用C語言開發的,因此叫CPython。在命令行下運行python就是啓動CPython解釋器。 CPython是使用最廣的Python解釋器。教程的全部代碼也都在CPython下執行。 IPython IPython是基於CPython之上的一個交互式解釋器,也就是說,IPython只是在交互方式上有所加強,可是執行Python代碼的功能和CPython是徹底同樣的。比如不少國產瀏覽器雖然外觀不一樣,但內核其實都是調用了IE。 CPython用>>>做爲提示符,而IPython用In [序號]:做爲提示符。 PyPy PyPy是另外一個Python解釋器,它的目標是執行速度。PyPy採用JIT技術,對Python代碼進行動態編譯(注意不是解釋),因此能夠顯著提升Python代碼的執行速度。 絕大部分Python代碼均可以在PyPy下運行,可是PyPy和CPython有一些是不一樣的,這就致使相同的Python代碼在兩種解釋器下執行可能會有不一樣的結果。若是你的代碼要放到PyPy下執行,就須要瞭解PyPy和CPython的不一樣點。 Jython Jython是運行在Java平臺上的Python解釋器,能夠直接把Python代碼編譯成Java字節碼執行。 IronPython IronPython和Jython相似,只不過IronPython是運行在微軟.Net平臺上的Python解釋器,能夠直接把Python代碼編譯成.Net的字節碼。 小結: Python的解釋器不少,但使用最普遍的仍是CPython。若是要和Java或.Net平臺交互,最好的辦法不是用Jython或IronPython,而是經過網絡調用來交互,確保各程序之間的獨立性。
一、縮進使用4個空格鍵。不建議使用tab
二、運算符左右隔空一格
三、類名首字母大寫
四、函數命名所有使用小寫,能夠用下劃線分割
五、常量或全局變量使用大寫,能夠用下劃線分割
六、不建議import os,time
七、建議使用塊註釋
參考python
print("轉換爲二進制爲:", bin(dec)) int("01010101",2) print("轉換爲八進制爲:", oct(dec)) print("轉換爲十六進制爲:", hex(dec))
def addr2dec(addr): "將點分十進制IP地址轉換成十進制整數" items = [int(x) for x in addr.split(".")] print(items) return sum(items[i] << [24, 16, 8, 0][i] for i in range(4)) print(addr2dec("10.3.9.12"))
python2內容進行編碼(默認ascii),而python3對內容進行編碼的默認爲utf-8。
ascii 最多隻能用8位來表示(一個字節),即:2**8 = 256,因此,ASCII碼最多隻能表示 256 個符號。 1-->48 A-->65 a-->97
unicode 規定雖有的字符和符號最少由 16 位來表示(2個字節),即:2 **16 = 65536,
UTF-8 是對Unicode編碼的壓縮和優化,他再也不使用最少使用2個字節,而是將全部的字符和符號進行分類:
A 1個字節 歐洲 一個字 2個字節 亞洲 一個子 3個字節
gbk A : 1個字節 中 :兩個字節
v1 = 1 or 3
#1
v2 = 1 and 3
#3
v3 = 0 and 2 and 1 #0
v4 = 0 and 2 or 1 #1
v5 = 0 and 2 or 1 or 4 #1
v6 = 0 or False and 1 #Falsemysql
機器碼(machine code),學名機器語言指令,有時也被稱爲原生碼(Native Code),是電腦的CPU可直接解讀的數據。react
字節碼是一種中間狀態(中間碼)的二進制代碼(文件)。須要直譯器轉譯後才能成爲機器碼。linux
一、默認解釋器編碼:
py2: ascii
py3: utf-8
二、字符串:
py2: str:字符串 -->字節
unicode:u"shh"
py3: bytes 和 str
三、range和xrange
py2 range返回list xrange返回生成器
py3 range返回生成器
四、py2 int、long
py3 int
五、py2 yield
py3 yiled、 yield from
六、py2 新式類和經典類
py3 新式類
七、py2 raw_input py3 input
八、py2 print py3 print()
python3去除了long類型,如今只有一種整型——int,但它的行爲就像python2版本的longnginx
0 空列表字符串 負數 不成立的表達式 None 等c++
readlines 返回一個列表程序員
xreadlines 返回一個生成器
不可哈希:list dict set 可哈希:int str bool None tuple
- 字符串 strip()去除
find()找不到返回-1 、index()找不到報錯
split()分割
join()拼接
replace()替換
- 字典 pop() 刪除 建立字典的三種方法:一、直接表達 二、dict(name="cao") 三、dict.formkeys(["key","key"],value)
update()
clear()清空
get()
dict.items() - 元組tuple 只讀 按str索引方法去查 - 列表 append()
inset()按索引增長
extend()迭代增長
conut()
sort()排序
index()
rserver()反轉 - 集合 add() update() remove() del() pop() clear() 交集$ 並集| 差集-
collections Python內建的一個集合模塊,提供了許多有用的集合類。
Counter是一個簡單的計數器,例如,統計字符出現的個數:
OrderedDict能夠實現一個FIFO(先進先出)的dict,當容量超出限制時,先刪除最先添加的Key:
deque是爲了高效實現插入和刪除操做的雙向列表,適合用於隊列和棧:
defaultdict使用dict時,若是引用的Key不存在,就會拋出KeyError。若是但願key不存在時,返回一個默認值,就能夠用defaultdict:
*args :接收全部按照位置傳的參數,接收到的是參數組成的元祖
**kwargs :接收全部按照關鍵字傳的參數,接收到的是參數組成的字典
引用計數 (對象被引用時+1,引用的對象被刪除時-1)
標記清除
分代回收(系統中的全部內存塊根據其存活時間劃分爲不一樣的集合,每個集合就成爲一個「代」,垃圾收集的頻率隨着「代」的存活時間的增大而減少)
在Python中對象的賦值其實就是對象的引用。當建立一個對象,把它賦值給另外一個變量的時候,python並無拷貝這個對象,只是拷貝了這個對象的引用而已。
淺拷貝:拷貝了最外圍的對象自己,內部的元素都只是拷貝了一個引用而已。也就是,把對象複製一遍,可是該對象中引用的其餘對象我不復制
深拷貝:外圍和內部元素都進行了拷貝對象自己,而不是引用。也就是,把對象複製一遍,而且該對象中引用的其餘對象我也複製。
###############################
淺拷貝copy ,第一層建立的是新的內存地址,而從第二層開始,指向的都是同一個內存地址,因此,對於第二層以及更深的層數來講,與原內存地址不變。
l1 = [1,[22,33,44],3,4,] l2 = l1.copy() l1[1].append('55') print(l1,id(l1),id(l1[1])) #[1, [22, 33, 44, '55'], 3, 4] 1787518244744 1787518244808 print(l2,id(l2),id(l2[1])) #[1, [22, 33, 44, '55'], 3, 4] 1787518244616 1787518244808 ############ l1[1].append("cao") print(l1) #[1, [22, 33, 44, '55', 'cao'], 3, 4] print(l2) #[1, [22, 33, 44, '55', 'cao'], 3, 4] ######################### l1[0] = "chao" print(l1) #['chao', [22, 33, 44, '55'], 3, 4] print(l2) #[1, [22, 33, 44, '55'], 3, 4]
深拷貝deepcopy,兩個是徹底獨立的,改變任意一個的任何元素(不管多少層),另外一個絕對不改變。
import copy l1 = [1,[22,33,44],3,4,] l2 = copy.deepcopy(l1) print(id(l1[1])) print(id(l2[1])) print("="*20) l1[0] = 111 print(l1) print(l2) print("="*20) l1[1].append('barry') print(l1) print(l2) ############ 1742824920904 1742824920520 ==================== [111, [22, 33, 44], 3, 4] [1, [22, 33, 44], 3, 4] ==================== [111, [22, 33, 44, 'barry'], 3, 4] [1, [22, 33, 44], 3, 4]
print('\n'.join([' '.join(['%s*%s=%-2s' % (j, i, i * j) for j in range(1, i + 1)]) for i in range(1, 10)]))
v = dict.fromkeys(['k1','k2'],[]) print(v) v["k1"].append(666) print(v) v["k1"] = 777 print(v)
{'k1': [], 'k2': []}
{'k1': [666], 'k2': [666]}
{'k1': 777, 'k2': [666]}
##############
def num():
return [lambda x:x+1 for i in range(4)]
print([m(2) for m in num()]) #[3,3,3,3]
print([m(1) for m in num()]) #[2,2,2,2]
################
print([ i % 2 for i in range(10) ]) #[0,1,0,1,0,1,0,1,0,1]
print(( i % 2 for i in range(10) )) #生成器
###################
a. 1 or 2 1
b. 1 and 2 2
c. 1 < (2==2) False
d. 1 < 2 == 2 Ture
not > and > or
- 函數參數傳遞的是什麼? 引用、內存地址
#魔性的用法:默認參數儘可能避免使用可變數據類型 類型一: lst = [] def func(l = lst): #默認參數 l.append(1) print(l) func() #[1] func() #[1,1] 默認參數只會被執行一次:第一次調用函數時,默認參數被初始化爲【】,之後每次調用時都會使用已經初始化的【】。 類型二: lst = [] def func(l = lst): l.append(1) print(l) func([]) #[1] func([]) #[1] 類型三: def func(a1,a2=[]): a2.append(a1) print(a2) func(1) #[1,] func(3,[]) #[3,] func(4) #[1,4] 類型四: def func(a1,a2=[]): a2.append(a1) return a2 l1 = func(1) print(l1) # [1,] l2 = func(3,[]) print(l2) # [3, ] l3 = func(4) print(l3) # [1,4] 類型五: def func(a1,a2=[]): a2.append(a1) return a2 l1 = func(1) # l1=[1,4] l2 = func(3,[]) # l2=[3,] l3 = func(4) # l3=[1,4] print(l2) print(l1) print(l3)
簡單的函數: my_lambda = lambda arg : arg + 1
簡單的條件語句: val= "cao" if 1==1 else "chao"
列表生成式 s1=[i*2 for i in range(5)] print(s1) 生成器表達式 s=(i*2 for i in range(5) ) print(s.__next__()) print(next(s))
val = [lambda :i + 1 for i in range(10)] [function,funtion...] print(val,type(val)) #<class 'list'> print(val[0],type(val[0])) #<class 'function'> data = val[0]() print(data) #10
應用到閉包函數:
當調用函數的時候,都會優先在外部做用域中查找i變量,這時列表生產式中循環立馬執行,最後i賦值爲9
def foo(): m=3 n=5 def bar(): a=4 return m+n+a return bar >>>bar = foo() >>>bar() 12
簡單的說,這種內部函數可使用外部函數變量的行爲,就叫閉包。
閉包的意義與應用:延遲計算:
閉包的意義:返回的函數對象,不只僅是一個函數對象,在該函數外還包裹了一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域
#應用領域:延遲計算(原來咱們是傳參,如今咱們是包起來)
裝飾器就是閉包函數的一種應用場景
- map - filter
map()函數接收兩個參數,一個是函數,一個是可迭代對象,map將傳入的函數依次做用到序列的每一個元素,並把結果做爲新的list返回。 def mul(x): return x*x n=[1,2,3,4,5] res=list(map(mul,n)) print(res) #[1, 4, 9, 16, 25] filter()函數接收一個函數 f 和一個list,這個函數 f 的做用是對每一個元素進行判斷,返回 True或 False, filter()根據判斷結果自動過濾掉不符合條件的元素,返回由符合條件元素組成的新list。 def is_odd(x): return x % 2 == 1 v=list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17])) print(v) #[1, 7, 9, 17]
- isinstance - type
isinstance() 函數來判斷一個對象是不是一個已知的類型,相似 type()。
isinstance() 與 type() 區別:
type() 不會認爲子類是一種父類類型,不考慮繼承關係。
isinstance() 會認爲子類是一種父類類型,考慮繼承關係。
若是要判斷兩個類型是否相同推薦使用 isinstance()。
- zip
zip() 函數用於將可迭代的對象做爲參數,將對象中對應的元素打包成一個個元組,而後返回由這些元組組成的列表。 >>>a = [1,2,3] >>> b = [4,5,6] >>> c = [4,5,6,7,8] >>> zipped = zip(a,b) # 打包爲元組的列表 [(1, 4), (2, 5), (3, 6)] >>> zip(a,c) # 元素個數與最短的列表一致 [(1, 4), (2, 5), (3, 6)] >>> zip(*zipped) # 與 zip 相反,可理解爲解壓,返回二維矩陣式 [(1, 2, 3), (4, 5, 6)]
- reduce
from functools import reduce
reduce() 函數會對參數序列中元素進行累積。 用傳給reduce中的函數 function(有兩個參數)先對集合中的第一、2個元素進行操做,獲得的結果再與第三個數據用function函數運算,最後獲得一個結果。 >>>def add(x, y) : # 兩數相加 ... return x + y ... >>> reduce(add, [1,2,3,4,5]) # 計算列表和:1+2+3+4+5 15 >>> reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函數 15
生成器:一個函數調用時返回一個迭代器,或 函數中包含yield語法,那這個函數就會變成生成器;
應用場景:
- range/xrange - py2: range(1000),當即建立;xrange(1000)生成器; - py3: range(1000)生成器; 沒有xrange
-redis獲取值
hscan_iter 利用yield封裝hscan建立生成器,實現分批去redis中獲取數據
迭代器:含有__iter__和__next__方法 (包含__next__方法的可迭代對象就是迭代器)
特色:
訪問者不須要關心迭代器內部的結構,僅需經過next()方法不斷去取下一個內容(惰性計算)
不能隨機訪問集合中的某個值 ,只能從頭至尾依次訪問
訪問到一半時不能往回退
便於循環比較大的數據集合,節省內存
可迭代對象:一個類內部實現__iter__方法且返回一個迭代器。
應用場景:
- wtforms中對form對象進行循環時候,顯示form中包含的全部字段。
- 列表、字典、元組
總結:若是想要讓一個對象能夠被for循環,那麼就須要在當前類中定義__iter__
問題:什麼是裝飾器?
在對原函數不進行修改時,在函數執行前和執行後添加功能
問題:手寫裝飾器
import functools
def warpper(func):
@functools.wraps(func) #保留原函數信息
def inner(*args,**kwargs):
#執行函數前
return func(*args,**kwargs)
#執行函數後
return inner
# 1. 執行wapper函數,並將被裝飾的函數當作參數。 wapper(index)
# 2. 將第一步的返回值,從新賦值給 新index = wapper(老index)
@warpper #index=warpper(index)
def index(x):
return x+100
問題:應用場景
django: csrf 內置認證、緩存
flask: 路由、before_request
帶參數裝飾器:flask:路由
CBV as_view()
偏函數: import functools def func(a1, a2, a3): return a1 + a2 + a3 new_func = functools.partial(func, 11, 2) #將11,2依次傳入到func函數的前兩個參數 print(new_func(3))
應用場景
falsk中取值時 經過localproxy 、偏函數、localstack、local
-繼承、封裝、多態(簡單描述)
python中一切皆對象
封裝:
其實就是將不少數據封裝到一個對象中,相似於把不少東西放到一個箱子中,
如:一個函數若是好多參數,起始就能夠把參數封裝到一個對象再傳遞。
應用場景:
- django rest framework中的request對象。
- flask中:request_context/app_context對象
繼承:
若是多個類中都有共同的方法,那麼爲了不反覆編寫,就能夠將方法提取到基類中實現,讓全部派生類去繼承便可。
應用場景:
- rest frmawork 視圖
- 版本、認證、分頁
多態:
python自己就是多態的,崇尚鴨子模型,只要會呱呱叫我麼就認爲它是鴨子。
class A: def send(self): print("A") class B: def f(self): print("B") def func(arg): arg.send() obj = A() func(obj)
-雙下劃線:
__getattr__
-CBV -django配置文件 -wtforms中的Form()示例化中 將"_fields中的數據封裝到From類中"
__mro__ wtform中 FormMeta中繼承類的優先級 __dict__ __new__ ,實例化可是沒有給當前對象 wtforms,字段實例化時返回:不是StringField,而是UnboundField rest frawork many=Turn 中的序列化
單例模式 __call__ flask 請求的入口app.run() 字段生成標籤時:字段.__str__ => 字段.__call__ => 插件.__call__ __iter__ 循環對象是,自定義__iter__ wtforms中BaseForm中循環顯示全部字段時定義了__iter__ -metaclass - 做用:用於指定當前類使用哪一個類來建立 - 場景:在類建立以前定製操做 示例:wtforms中,對字段進行排序。
子類繼承父類的方法,其繼承順序按照__mro__
staticmethod
classmethod 須要傳入參數cls當前類
兩種方法都不須要實例化就可使用l類.方法或對象.方法
Python的類能夠繼承多個類,Python的類若是繼承了多個類,那麼其尋找方法的方式有兩種
當類是經典類時,多繼承狀況下,會按照深度優先方式查找
當類是新式類時,多繼承狀況下,會按照廣度優先方式查找
簡單點說就是:經典類是縱向查找,新式類是橫向查找
經典類和新式類的區別就是,在聲明類的時候,新式類須要加上object關鍵字。在python3中默認全是新式類
from types import MethodType,FunctionType class Foo(object): def fetch(self): pass Foo.fetch 此時fetch爲函數 print(isinstance(Foo.fetch,MethodType)) print(isinstance(Foo.fetch,FunctionType)) # True obj = Foo() obj.fetch 此時fetch爲方法 print(isinstance(obj.fetch,MethodType)) # True print(isinstance(obj.fetch,FunctionType))
單例模式:一個類只能有一個實例化對象
應用場景:Django中的admin組件中admin.site()就是由單例模式建立的,其中封裝了全部的表對象
#基於new
class Singleton(object):
每一次實例化的時候,返回同一個instance對象 def __new__(cls,*args,**kwargs): if not hasattr(cls,"instance"): cls.instace=super(Singleton,cls).__new__(cls,*args,**kwargs) return cls.instace a=Singleton() b=Singleton() print(a,b) print(a is b)
#基於裝飾器
def Singleton(cls):
_instance={}
def _singleton(*args,**kwargs):
if cls not in _instance:
_instance[cls]=cls(*args,**kwargs)
return _instance[cls]
return _singleton
@Singleton
class A(object):
a=1
def __init__(self,x=None):
self.x=x
c=A(2)
b=A(3)
print(c is b)
os、sys、json、re、logging、random、time、requests、beautifulsoup,
os模塊是與操做系統交互的一個接口 ,提供了不少方法來處理文件和目錄
os.remove(‘path/filename’) 刪除文件 os.rename(oldname, newname) 重命名文件 os.walk() 生成目錄樹下的全部文件名 os.chdir('dirname') 改變目錄 os.getcwd() 取得當前工做目錄 os.path.getsize() 返回文件大小
sys模塊負責程序與python解釋器的交互,提供了一系列的函數和變量,用於操控python的運行時環境。
sys.argv 命令行參數List,第一個元素是程序自己路徑 sys.exit(n) 退出程序,正常退出時exit(0),錯誤退出sys.exit(1) sys.version 獲取Python解釋程序的版本信息 sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 sys.platform 返回操做系統平臺名稱
logging :記錄日誌,分爲五種級別,debug,info ,warning,error,critical
random
random.random() 0-1隨機數
random.randint(1,9) 1-9 隨機整數
requests 獲取頁面html和xml
json 序列化
. 匹配除換行符之外的任意字符 \w 匹配字母或數字或下劃線 \s 匹配任意的空白符 \d 匹配數字 \n 匹配一個換行符 \t 匹配一個製表符 \b 匹配一個單詞的結尾 ^ 匹配字符串的開始 $ 匹配字符串的結尾 \W 匹配非字母或數字或下劃線 \D 匹配非數字 \S 匹配非空白符 a|b 匹配字符a或字符b () 匹配括號內的表達式,也表示一個組 [...] 匹配字符組中的字符 [^...] 匹配除了字符組中字符的全部字符 用法說明 * 重複零次或更屢次 + 重複一次或更屢次 ? 重複零次或一次 {n} 重複n次 {n,} 重複n次或更屢次 {n,m} 重複n到m次
一、寫一個郵箱、手機號、IP
#匹配手機號 import re def phone(arg): s=re.match("^(13|14|15|18)[0-9]{9}$",arg) if s: return "正確" return "錯誤" print(phone("23722751552"))
#匹配郵箱
re.match("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$",arg)
#匹配IP
re.match("\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b",arg)
?: 優先匹配
\b 匹配一個單詞的結尾
re.match只匹配字符串的開始,若是字符串開始不符合正則表達式,則匹配失敗,函數返回None;
re.search匹配整個字符串,直到找到一個匹配。
1 import re 2 s="fnfffidvvgf" 3 4 m=re.match("fi",s) 5 print(m) #None 6 s=re.search("fi",s).group() 7 print(s) #fi
貪婪匹配: 匹配1次或屢次<.+> 匹配0次或屢次<.*>
非貪婪匹配:匹配0次或1次<.?>
[i**2 for i in range(1,11)]
list(set([1,2,45,5,2]))
li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] def search(someone, li): l = -1 h = len(li) while l + 1 != h: m = int((l + h) / 2) if li[m] < someone: l = m else: h = m p = h if p >= len(li) or li[p] != someone: print("元素不存在") else: str = "元素索引爲%d" % p print(str) search(1, li) # 元素索引爲2
方法一: 使用os.walk file-- 是你所要便利的目錄的地址, 返回的是一個三元組(root,dirs,files)。 root 所指的是當前正在遍歷的這個文件夾的自己的地址 dirs 是一個 list ,內容是該文件夾中全部的目錄的名字(不包括子目錄) files 一樣是 list , 內容是該文件夾中全部的文件(不包括子目錄) def open_2(file): for root, dirs , files in os.walk(file): print("ss",files) for filename in files: print(os.path.abspath(os.path.join(root, filename))) #返回絕對路徑 open_2("F:\搜索") 方法二: import os def open(files): for dir_file in os.listdir(files): # print("ss",dir_file) #遞歸獲取全部文件夾和文件 files_dir_file = os.path.join(files, dir_file) if os.path.isdir(files_dir_file): #是否是文件夾 open(files_dir_file) else: print(files_dir_file) open("F:\搜索") 並將下面的全部文件內容寫入到一個文件中 def open_2(file): for root, dirs , files in os.walk(file): for filename in files: with open(os.path.abspath(os.path.join(root, filename)), "r") as f: for i in f.readlines(): print(i) with open("./cao.txt","a",encoding="utf-8") as f2: f2.write(i) f2.write("\n") open_2("F:\搜索")
1 # 建立一個文件 2 open("chao.txt","w",encoding="utf-8") 3 import os
#刪除文件 4 os.remove("chao.txt")
一、pip3 包管理器
二、源碼安裝
-下載、解壓
-python setup.py bulid
-python setup.py install
使用python內置的排列組合函數(不放回抽樣排列) product 笛卡爾積 (有放回抽樣排列) permutations 排列 (不放回抽樣排列) combinations 組合,沒有重複 (不放回抽樣組合) combinations_with_replacement 組合,有重複 (有放回抽樣組合) import itertools print(len(list(itertools.permutations('12345', 3)))) # 60
反射的核心本質就是以字符串的形式去導入個模塊,經過字符串的形式操做對象相關的屬性
Django中的 CBV就是基於反射實現的。
導入模塊:
x=__import__("time")
print(x.time())
指定當前類是由那個類建立的
默認爲type
- 場景:在類建立以前定製操做 - 示例:wtforms中,對字段進行排序。
try: fh = open("testfile", "w") try: fh.write("這是一個測試文件,用於測試異常!!") finally: print "關閉文件" fh.close() except IOError: print "Error: 沒有找到文件或讀取文件失敗" raise拋異常 inputValue=input("please input a int data :") if type(inputValue)!=type(1): raise ValueError else: print inputValue
整數、字符創、字典、列表、bool、None
重寫default() import json import datetime dic = { 'k1':123, 'ctime':datetime.datetime.now() } class MyJSONEncoder(json.JSONEncoder): def default(self,o): if isinstance(o,datetime.datetime): return o.strftime("%Y-%m-%d") else: return super(MyJSONEncoder,self).default(o) v=json.dumps(dic,cls=MyJSONEncoder) print(v)
json.dumps(xxxx,ensure_ascii=False)
上下文管理器:
在使用Python編程中,能夠會常常碰到這種狀況:有一個特殊的語句塊,在執行這個語句塊以前須要先執行一些準備動做;當語句塊執行完成後,須要繼續執行一些收尾動做。 例如:當須要操做文件或數據庫的時候,首先須要獲取文件句柄或者數據庫鏈接對象,當執行完相應的操做後,須要執行釋放文件句柄或者關閉數據庫鏈接的動做。 又如,當多線程程序須要訪問臨界資源的時候,線程首先須要獲取互斥鎖,當執行完成並準備退出臨界區的時候,須要釋放互斥鎖。 對於這些狀況,Python中提供了上下文管理器(Context Manager)的概念,能夠經過上下文管理器來定義/控制代碼塊執行前的準備動做,以及執行後的收尾動做。
在Python中,能夠經過with語句來方便的使用上下文管理器,
with語句能夠在代碼塊運行前進入一個運行時上下文(執行__enter__方法),並在代碼塊結束後退出該上下文(執行__exit__方法)。
操做文件:with open
Flask中的離線腳本:
with app.app_context():
pass
yiled:一、一個函數中含有yield關鍵字,此函數爲生成器,
二、生成器調用是不會當即執行,必須使用next()(結束是會報錯)或send()或for調用執行
三、yield能夠返回值也能夠取值(生產者消費者模式)
四、調用生成器send方法傳遞數據時,必須先調用next(生成器)或者生成器.send(None)方法
yield from 可讓生成器,直接在其餘函數中調用,
互聯網協議按照功能不一樣分爲osi七層或tcp/ip五層或tcp/ip四層
物理層:主要是基於電器特性發送高低電壓(電信號),高電壓1,低電壓0,設備有網卡、網線、集線器,中繼器,雙絞線等! 單位:bit比特
數據鏈路層:定義了電信號的分組方式(電信號0和1沒有實際意義)規定了報頭(18字節)和數據 設備有:網橋、以太網交換機、網卡 單位:幀
網絡層:主要功能是將ip地址翻譯成對應的mac物理地址 路由 arp協議
傳輸層:創建端口到端口之間的通訊 tcp協議udp協議
會話層:創建客戶端與服務端鏈接
表示層:對來自應用層的命令和數據進行解釋,並按照必定的格式傳送給會話層
應用層:規定應用程序的數據格式
C/S架構:
client端與server端的服務架構(客戶端能夠包含一個或多個在用戶的電腦上運行的程序)
B/S架構:隸屬於C/S架構的
Broswer端(網頁端)與server端
優勢:統一了全部應用程序的入口、使用方便、輕量級
三次握手:
SYC=1(創建鏈接) ACK(確認請求)
一、客戶端(Client)向服務端(Server)發送一次請求(請求鏈接)
二、服務端確認並回復客戶端(ACK=1, SYC=1,並在seq基礎上產生一個隨機數發給客戶端)
三、客戶端檢驗確認請求(ACK=1) 此時客戶端與服務端就創建了鏈接
四次揮手:
FAN=1(斷鏈接) ACK=1(確認請求)
一、客戶端向服務端發一次請求(FAN=1)
二、服務端回覆客戶端 (ACK=1) (斷開客戶端—>服務端)
三、服務端再向客戶端發請求(FAN=1) (由於有數據傳輸,因此二、3不能合併)
四、客戶端確認請求(ACK=1) (斷開服務端--->客戶端)
tcp是基於鏈接的,必須先啓動服務端,而後再啓動客戶端去鏈接服務端(三次握手,四次揮手)
udp是無鏈接的,先啓動那一端均可以 (應用:QQ聊天) (可能會產生丟包,由於服務端不監聽客戶端只負責發送數據,無論客戶端是否收到數據)
兩個程序經過一個雙向的通訊鏈接實現數據的交換,這個鏈接的一端稱爲一個socket
TCP協議操做:
服務器端: 客戶端
建立套接字 建立套接字
綁定ip和端口 綁定ip和端口
監聽 鏈接服務器
accept等待鏈接 通訊(收recv,發send)
通訊(收recv,發send)
UDP:傳輸速度快
不面向鏈接,不能保證數據的完整性
服務器端: 客戶端:
建立套接字 綁定套接字
綁定ip和端口 通訊(收recvfrom,發sendto)
通訊(收recvfrom,發sendto)
粘包只會在tcp中產生,由於tcp是面向鏈接的、面向流(能夠將多個小數據合併成一個大的數據包發送)這樣以來,接收方不知道 數據包中的數據是以什麼未分割數據的,就會產生粘包
而udp是無鏈接的、面向消息的(他不會將多個消息合併成一個大消息發送的,即便是空消息也會發送(自動加上消息頭的))
兩種狀況:
一、發送端須要等緩衝區滿才發送出去,形成粘包(發送數據時間間隔很短,數據了很小,會合到一塊兒,產生粘包)
二、接收方不及時接收緩衝區的包,形成多個包接收(客戶端發送了一段數據,服務端只收了一小部分,服務端下次再收的時候仍是從緩衝區拿上次遺留的數據,產生粘包)
監聽多個socket是否發生變化
- select,內部循環檢測socket是否發生變化;最多檢測1024個socket
- poll, 內部循環檢測socket是否發生變化;
- epoll, 使用回調函數的機制(自定義了三個函數)任務完成時自動調用的函數
交換機 路由器(小型交換機)
數據連接層 網絡層
利用mac地址肯定傳輸數據的目的地 利用網關ip地址肯定傳輸數據的目的地
有防火牆
防火牆是內部網與外部網之間的一種訪問控制設備。
它可經過監測、限制、更改跨越防火牆的數據流,儘量地對外部屏蔽網絡內部的信息、結構和運行情況, 以此來實現網絡的安全保護。
局域網:是指在小範圍內由多臺計算機互聯成的計算機組 廣域網:
ip和子網掩碼作按位與運算,能夠獲得網關ip
子網掩碼是用來判斷任意兩臺計算機的IP地址是否屬於同一個子網絡的根據。
進程:正在執行的一個程序或者一個任務,而執行任務的是cpu
每一個進程都有本身的獨立內存空間,不一樣進程經過進程間通訊IPC(隊列,管道)來通訊。
開進程消耗比較大,且上下文進程間的切換開銷比較大,
相比線程數據相對比較穩定安全。
線程:線程是進程的一個實體,是CPU調度和分派的基本單位
線程間通訊主要經過共享內存,開線程資源開銷小,上下文切換很快,但相比進程不夠穩定容易丟失數據。
協程:是一種「微線程」,實際並不存在,是程序員人爲創造出來的控制程序調度的(程序執行一段代碼,切換執行另外一段代碼)它能夠實現單線程下的併發、
一、程序執行遇到IO切換,性能提升,實現了併發
二、無IO時切換,性能下降
優勢:
1. 協程的切換開銷更小,屬於程序級別的切換,操做系統徹底感知不到,於是更加輕量級
2. 單線程內就能夠實現併發的效果,最大限度地利用cpu
一、進程多與線程比較
1.線程是程序執行的最小單位,而進程是操做系統分配資源的最小單位;
2.一個進程由一個或多個線程組成,線程是一個進程中代碼的不一樣執行路線;
3.進程之間相互獨立,但同一進程下的各個線程之間共享程序的內存空間(包括代碼段、數據集、堆等)及一些進程級的資源(如打開文件和信號),某進程內的線程在其它進程不可見;
4.開啓進程比開線程資源開銷大,線程上下文切換比進程上下文切換要快得多。由於線程共享進程內的資源
二、協程與線程進行比較
1) 一個線程能夠多個協程,一個進程也能夠單獨擁有多個協程,這樣python中則能使用多核CPU。
2) 線程進程都是同步機制,而協程則是異步
3) 協程能保留上一次調用時的狀態,每次過程重入時,就至關於進入上一次調用的狀態
進程是系統分配系統資源的最小單位,進程之中能夠有多個線程,一個進程中的全部資源共享,進程之間資源不會共享;
線程是系統進行任務調度的最小單位,一個進程中的線程共享該進程的系統資源,線程是輕量級的進程;
協程又稱微線程,輕量級線程,執行具備原子性,執行須要程序員來調用度,能夠執行效率高
三、多線程用於IO密集型,如socket,爬蟲,web
多進程用於計算密集型,如金融分析
四、使用concurrent.futures開線程池和進程池
五、進程鎖與線程鎖
進程鎖:
#加鎖能夠保證多個進程修改同一塊數據時,同一時間只能有一個任務能夠進行修改,即串行的修改,沒錯,速度是慢了,但犧牲了速度卻保證了數據安全。 雖然能夠用文件共享數據實現進程間通訊,但問題是: 1.效率低(共享數據基於文件,而文件是硬盤上的數據) 2.須要本身加鎖處理 #所以咱們最好找尋一種解決方案可以兼顧:1、效率高(多個進程共享一塊內存的數據)2、幫咱們處理好鎖問題。這就是mutiprocessing模塊爲咱們提供的基於消息的IPC通訊機制:隊列和管道。 1 隊列和管道都是將數據存放於內存中 2 隊列又是基於(管道+鎖)實現的,可讓咱們從複雜的鎖問題中解脫出來, 咱們應該儘可能避免使用共享數據,儘量使用消息傳遞和隊列,避免處理複雜的同步和鎖問題,並且在進程數目增多時,每每能夠得到更好的可獲展性。
線程鎖:
GIL和Lock
解決死鎖問題使用遞歸鎖(Rlock)
進程鎖:爲了不多個進程同時同享一個資源,加鎖限制同一時間只能有一個進程修改數據,從而保證數據安全 (可使用隊列和管道)
線程鎖:同一時間只能一個線程訪問加鎖的資源,可是其餘線程能夠訪問未加鎖的資源
GIL是全局解釋器鎖,它的本質是一把互斥鎖,將併發運行變成串行,以此來控制同一時間內共享數據只能被一個任務所修改,進而保證數據安全。(同一時刻同一進程中只有一個線程被執行)
鎖的目的是爲了保護共享的數據,同一時間只能有一個線程來修改共享的數據
結論:保護不一樣的數據就應該加不一樣的鎖。
GIL 與Lock是兩把鎖,保護的數據不同,GIL是解釋器級別的(固然保護的就是解釋器級別的數據,好比垃圾回收的數據),
Lock是保護用戶本身開發的應用程序的數據,很明顯GIL不負責這件事,只能用戶自定義加鎖處理
進程池;
from concurrent.futures import ProcessPoolExecutor import time,os def piao(name,n): print('%s '%(name)) time.sleep(2) return n**3 if __name__=='__main__': p = ProcessPoolExecutor(4) objs= [] for i in range(10): obj = p.submit(piao,'sb %s'%i,i) objs.append(obj) p.shutdown(wait=True) print("主",os.getpid()) for obj in objs: print(obj.result())
from concurrent.futures import ProcessPoolExecutor import time,os def piao(name,n): print('%s is pioing %s'%(name,os.getpid())) return n**2 if __name__=='__main__': p = ProcessPoolExecutor(4) for i in range(10): res = p.submit(piao,'alex %s'%i,i).result() print(res) p.shutdown(wait=True) print('主',os.getpid())
線程池:
from concurrent.futures import ThreadPoolExecutor from threading import current_thread import time,random def task(n): print('%s is running' %current_thread().getName()) time.sleep(random.randint(1,3)) return n**2 if __name__ == '__main__': # t=ProcessPoolExecutor() #默認是cpu的核數 # import os # print(os.cpu_count()) t=ThreadPoolExecutor(3) #默認是cpu的核數*5 objs=[] for i in range(10): obj=t.submit(task,i) objs.append(obj) t.shutdown(wait=True) for obj in objs: print(obj.result()) print('主',current_thread().getName())
爲每個線程開闢一塊內存空間存數據
一、管道(無名管道、有名管道)
二、消息隊列
三、信號量
四、信號
五、共享內存地址
六、socket
經過ip地址獲取mac地址的一種協議
併發:是一種僞並行,單個cpu能夠利用多道技術實現「併發」
並行:多個任務能夠同時運行,多cpu才能實現
- 非阻塞:程序執行過程當中遇到IO不等待 - 代碼: sk = socket.socket() sk.setblocking(False) #會報錯,捕獲異常 - 異步: - 經過執行回調函數:當達到某個指定的狀態以後,自動調用特定函數。
把域名解析成ip :先去本地hosts文件中解析,若是沒有再去DNS域名解析服務器解析
hosts:網址與ip的關係映射
建立一個緩衝區,減小了生產者與消費者這件的依賴關係、支持併發、解決了生產者快慢的問題
用戶能夠就近取得所需的內容,提升用戶訪問網站的響應速度。(解決了Internet網絡擁擠的狀態)
相關技術:負載均衡、緩存、動態內容分發與複製(將靜態網頁、圖像、流媒體複製放入各個cdn中)
LVS(liunx虛擬服務器):是一個虛擬的服務器集羣系統:
LVS主要用於多服務器的負載均衡。它工做在網絡層,能夠實現高性能,高可用的服務器集羣技術
Keepalived的做用是檢測服務器的狀態,若是有一臺web服務器宕機,或工做出現故障,Keepalived將檢測到,並將有故障的服務器從系統中剔除,同時使用其餘服務器代替該服務器的工做,當服務器工做正常後Keepalived自動將服務器加入到服務器羣中,這些工做所有自動完成,不須要人工干涉,須要人工作的只是修復故障的服務器
做用:
管理LVS負載均衡軟件、實現LVS集羣節點的狀態檢查
作web架構的高可用
將請求分發到不一樣的服務器上去響應,而且讓每一個服務器的負載達到均衡的狀態
種類:
haproxy:是一種提供高可用、負載均衡以及基於tcp或http的應用程序代理
做用:
一、nginx是一個輕量級的Web服務器(反向代理服務器、負載均衡服務器)
二、做用:
(1)保證內網的安全,可使用方向代理WAF(Web防火牆)功能,阻止web攻擊(大型網站,一般將反向代理做爲公網訪問地址,Web服務器是內網)
(2)負載均衡,經過反向代理服務器來優化網站的負載,其特色是佔有內存少,併發能力強
三、正向代理與反向代理
比喻:a(客戶端)、b(代理)、c(服務端)三我的,正向代理是:a經過b向c借錢(a是知道c存在的)
反向代理是:a向b借錢,b向c借錢(a不知道c的存在)
rpc(遠程過程調用):可讓程序在不一樣的內存空間(不一樣的系統)實現遠程數據通訊和互相調用
流程:客戶端調用rpc接口------>rpc-------->服務端
應用場景:好比兩臺服務器A,B,一個應用部署在A服務器上,想要調用B服務器上應用提供的函數或者方法,因爲不在一個內存空間,不能直接調用,這時候須要經過就能夠應用RPC框架的實現來解決
asynio模塊能夠實現異步網絡操做、併發、協程
python經過gevent中的greenlet實現協程,
當一個greenlet遇到IO操做時,好比訪問網絡,就自動切換到其餘的greenlet,等到IO操做完成,再在適當的時候切換回來繼續執行。因爲IO操做很是耗時,常常使程序處於等待狀態,有了gevent自動切換協程,就保證總有greenlet在運行,而不是等待IO。
使用gevent實現單線程併發 爬蟲(gevent中的pool或joinall) web聊天室
twisted是一個用python語言編寫的事件驅動網絡框架,
特色是:內部基於一個事件循環(reactor),當外部事件執行時遇到IO等待則掛起,執行下一個,IO等待完成後返回一個Deferred對象,Deferred對象會自動觸發回調機制調用相應的函數處理
優缺點:關係型:容易理解(二維表結構)、支持sql複雜查詢、支持事務(保持數據一致性)
非關係:數據基於鍵值對存儲、查詢速度快,數據沒有耦合性、擴展性強、
innodb 支持事務(回滾)、表鎖、行鎖(select id,name from user where id=2 for update)
myisam 支持全文索引、表鎖(- select * from user for update)
無重複列
表中屬性必須依賴於主鍵
非主屬性相關信息(關聯表信息)不能依賴於主鍵 (消除數據冗餘)
權限表、BBS、權限
注意:FK M2M
多表聯查:
select * from tb1,tb2 沒有where條件時,笛卡爾乘積效果
left join 以左表爲基準,顯示因此的內容,右表沒有對應項時,顯示null
select * from tb1 left join tb2 on tb1.id=tb2.id;
inner join 只顯示兩張表共同內容
select * from tb1 inner join tb2 on tb1.id=tb2.id;
union 顯示兩張表因此內容
select * from tb1 left join tb2 on tb1.id=tb2.id union select * from tb2 left join tb1 on tb1.id=tb2.id;
分組函數
select 部門ID,max(id) from 用戶表 group by 部門ID having count(id)>3
group by 字段 having 判斷條件 (固定語法)分組和聚合函數搭配
建立索引:
建立表+索引
create table tb( id int not null primary key
name varchar(32),
pwd varchar(32)
unique tb_pwd (pwd))
普通索引:create index tb_name on tb(name)
聯合索引:create index tb_name_age on tb(name,age)
原理:B+/哈希索引 查找速度快;更新速度慢
一、索引必定是爲搜索條件的字段建立的
二、innodb表的索引會存放於s1.ibd文件中,而myisam表的索引則會有單獨的索引文件table1.MYI
單列:
一、普通索引 index 加速查找
二、惟一索引 unique 加速查找+不能重複
三、主鍵索引 primary key 加速查找+不能重複+不能爲空
多列:
一、聯合索引
二、聯合惟一索引
三、聯合主鍵索引
聯合索引聽從最左前綴原則
若是組合索引爲:(name,email)
name and email -- 使用索引
name -- 使用索引
email -- 不使用索引
其它操做:
索引合併:利用多個單例索引查找
覆蓋索引:在索引表中就能查到想要的數據
建立了索引,但沒法命中
- like '%xx' select * from tb1 where name like '%cn'; - 使用函數 select * from tb1 where reverse(name) = 'wupeiqi'; - or select * from tb1 where nid = 1 or email = 'seven@live.com'; 特別的:當or條件中有未創建索引的列才失效,如下會走索引 select * from tb1 where nid = 1 or name = 'seven'; select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex' - 類型不一致 若是列是字符串類型,傳入條件是必須用引號引發來,否則... select * from tb1 where name = 999; - != select * from tb1 where name != 'alex' 特別的:若是是主鍵,則仍是會走索引 select * from tb1 where nid != 123 - > select * from tb1 where name > 'alex' 特別的:若是是主鍵或索引是整數類型,則仍是會走索引 select * from tb1 where nid > 123 select * from tb1 where num > 123 - order by select email from tb1 order by name desc; 當根據索引排序時候,選擇的映射若是不是索引,則不走索引 特別的:若是對主鍵排序,則仍是走索引: select * from tb1 order by nid desc;
一組sql批量執行,要麼所有執行成功、要麼所有失敗 遵循原子性、一致性、持久性、隔離性
start transaction; 開始事務 增、刪、改 update user set balance=900 where name='wsb'; #買支付100元 update user set balance=1010 where name='egon'; #中介拿走10元 update user set balance=1090 where name='ysb'; #賣家拿到90元 commit; 提交事務
rollback; 回滾
問題:如何基於數據庫實現商城商品計數器?
select * from user for update
樂觀鎖(讀)
悲觀鎖(寫)
存儲過程、視圖、函數、觸發器、都是保存在數據庫中
觸發器:在數據庫中對某張表進行「增刪改」時,添加一些操做
視圖:一張虛擬表,根據SQL語句動態的獲取數據集,並命名,下次使用時直接調用名稱(只能查)
v = select * from tb where id <1000 select * from v 等同於: select * from (select * from tb where id <1000) as v
存儲過程:將經常使用的sql語句命名保存到數據庫中,使用時能夠直接調用名稱
參數有:in(入參類型) out(出參類型) inout(出入參類型)
函數:在sql語句中使用
- 聚合:max/sum/min/avg
- 時間格式化 date_format
- 字符串拼接 concat
存儲過程與函數的區別:
區別:
函數 存儲過程
必須有返回值 return 能夠經過out、inout返回零各或多個值
不能單獨使用,必須做爲表達式的一部分 能夠做爲一個獨立的sql語句執行
sql語句中能夠直接調用函數 sql中不能調用過程
主鍵:肯定表中一條記錄的惟一標識
外鍵:用於關聯另外一張表的字段,(經過該字段肯定表中記錄)
char 固定長度(255)
varchar 變長 (理論65535)
1、數學函數 ROUND(x,y) 返回參數x的四捨五入的有y位小數的值 RAND() 返回0到1內的隨機值,能夠經過提供一個參數(種子)使RAND()隨機數生成器生成一個指定的值。 2、聚合函數(經常使用於GROUP BY從句的SELECT查詢中) AVG(col)返回指定列的平均值 COUNT(col)返回指定列中非NULL值的個數 MIN(col)返回指定列的最小值 MAX(col)返回指定列的最大值 SUM(col)返回指定列的全部值之和 GROUP_CONCAT(col) 返回由屬於一組的列值鏈接組合而成的結果 3、字符串函數 CHAR_LENGTH(str) 返回值爲字符串str 的長度,長度的單位爲字符。一個多字節字符算做一個單字符。 CONCAT(str1,str2,...) 字符串拼接 若有任何一個參數爲NULL ,則返回值爲 NULL。 CONCAT_WS(separator,str1,str2,...) 字符串拼接(自定義鏈接符) CONCAT_WS()不會忽略任何空字符串。 (然而會忽略全部的 NULL)。 CONV(N,from_base,to_base) 進制轉換 例如: SELECT CONV('a',16,2); 表示將 a 由16進制轉換爲2進制字符串表示 FORMAT(X,D) 將數字X 的格式寫爲'#,###,###.##',以四捨五入的方式保留小數點後 D 位, 並將結果以字符串的形式返回。若 D 爲 0, 則返回結果不帶有小數點,或不含小數部分。 例如: SELECT FORMAT(12332.1,4); 結果爲: '12,332.1000' INSERT(str,pos,len,newstr) 在str的指定位置插入字符串 pos:要替換位置其實位置 len:替換的長度 newstr:新字符串 特別的: 若是pos超過原字符串長度,則返回原字符串 若是len超過原字符串長度,則由新字符串徹底替換 INSTR(str,substr) 返回字符串 str 中子字符串的第一個出現位置。 LEFT(str,len) 返回字符串str 從開始的len位置的子序列字符。 LOWER(str) 變小寫 UPPER(str) 變大寫 REVERSE(str) 返回字符串 str ,順序和字符順序相反。 SUBSTRING(str,pos) , SUBSTRING(str FROM pos) SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len) 不帶有len 參數的格式從字符串str返回一個子字符串,起始於位置 pos。帶有len參數的格式從字符串str返回一個長度同len字符相同的子字符串,起始於位置 pos。 使用 FROM的格式爲標準 SQL 語法。也可能對pos使用一個負值。倘若這樣,則子字符串的位置起始於字符串結尾的pos 字符,而不是字符串的開頭位置。在如下格式的函數中能夠對pos 使用一個負值。 mysql> SELECT SUBSTRING('Quadratically',5); -> 'ratically' mysql> SELECT SUBSTRING('foobarbar' FROM 4); -> 'barbar' mysql> SELECT SUBSTRING('Quadratically',5,6); -> 'ratica' mysql> SELECT SUBSTRING('Sakila', -3); -> 'ila' mysql> SELECT SUBSTRING('Sakila', -5, 3); -> 'aki' mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2); -> 'ki' 4、日期和時間函數 CURDATE()或CURRENT_DATE() 返回當前的日期 CURTIME()或CURRENT_TIME() 返回當前的時間 DAYOFWEEK(date) 返回date所表明的一星期中的第幾天(1~7) DAYOFMONTH(date) 返回date是一個月的第幾天(1~31) DAYOFYEAR(date) 返回date是一年的第幾天(1~366) DAYNAME(date) 返回date的星期名,如:SELECT DAYNAME(CURRENT_DATE); FROM_UNIXTIME(ts,fmt) 根據指定的fmt格式,格式化UNIX時間戳ts HOUR(time) 返回time的小時值(0~23) MINUTE(time) 返回time的分鐘值(0~59) MONTH(date) 返回date的月份值(1~12) MONTHNAME(date) 返回date的月份名,如:SELECT MONTHNAME(CURRENT_DATE); NOW() 返回當前的日期和時間 QUARTER(date) 返回date在一年中的季度(1~4),如SELECT QUARTER(CURRENT_DATE); WEEK(date) 返回日期date爲一年中第幾周(0~53) YEAR(date) 返回日期date的年份(1000~9999) 重點: DATE_FORMAT(date,format) 根據format字符串格式化date值 mysql> SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y'); -> 'Sunday October 2009' mysql> SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s'); -> '22:23:00' mysql> SELECT DATE_FORMAT('1900-10-04 22:23:00', -> '%D %y %a %d %m %b %j'); -> '4th 00 Thu 04 10 Oct 277' mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', -> '%H %k %I %r %T %S %w'); -> '22 22 10 10:23:00 PM 22:23:00 00 6' mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V'); -> '1998 52' mysql> SELECT DATE_FORMAT('2006-06-00', '%d'); -> '00' 5、加密函數 MD5() 計算字符串str的MD5校驗和 PASSWORD(str) 返回字符串str的加密版本,這個加密過程是不可逆轉的,和UNIX密碼加密過程使用不一樣的算法。 6、控制流函數 CASE WHEN[test1] THEN [result1]...ELSE [default] END 若是testN是真,則返回resultN,不然返回default CASE [test] WHEN[val1] THEN [result]...ELSE [default]END 若是test和valN相等,則返回resultN,不然返回default IF(test,t,f) 若是test是真,返回t;不然返回f IFNULL(arg1,arg2) 若是arg1不是空,返回arg1,不然返回arg2 NULLIF(arg1,arg2) 若是arg1=arg2返回NULL;不然返回arg1 7、控制流函數小練習 #7.1、準備表 /* Navicat MySQL Data Transfer Source Server : localhost_3306 Source Server Version : 50720 Source Host : localhost:3306 Source Database : student Target Server Type : MYSQL Target Server Version : 50720 File Encoding : 65001 Date: 2018-01-02 12:05:30 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for course -- ---------------------------- DROP TABLE IF EXISTS `course`; CREATE TABLE `course` ( `c_id` int(11) NOT NULL, `c_name` varchar(255) DEFAULT NULL, `t_id` int(11) DEFAULT NULL, PRIMARY KEY (`c_id`), KEY `t_id` (`t_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of course -- ---------------------------- INSERT INTO `course` VALUES ('1', 'python', '1'); INSERT INTO `course` VALUES ('2', 'java', '2'); INSERT INTO `course` VALUES ('3', 'linux', '3'); INSERT INTO `course` VALUES ('4', 'web', '2'); -- ---------------------------- -- Table structure for score -- ---------------------------- DROP TABLE IF EXISTS `score`; CREATE TABLE `score` ( `id` int(11) NOT NULL AUTO_INCREMENT, `s_id` int(10) DEFAULT NULL, `c_id` int(11) DEFAULT NULL, `num` double DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of score -- ---------------------------- INSERT INTO `score` VALUES ('1', '1', '1', '79'); INSERT INTO `score` VALUES ('2', '1', '2', '78'); INSERT INTO `score` VALUES ('3', '1', '3', '35'); INSERT INTO `score` VALUES ('4', '2', '2', '32'); INSERT INTO `score` VALUES ('5', '3', '1', '66'); INSERT INTO `score` VALUES ('6', '4', '2', '77'); INSERT INTO `score` VALUES ('7', '4', '1', '68'); INSERT INTO `score` VALUES ('8', '5', '1', '66'); INSERT INTO `score` VALUES ('9', '2', '1', '69'); INSERT INTO `score` VALUES ('10', '4', '4', '75'); INSERT INTO `score` VALUES ('11', '5', '4', '66.7'); -- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `s_id` varchar(20) NOT NULL, `s_name` varchar(255) DEFAULT NULL, `s_age` int(10) DEFAULT NULL, `s_sex` char(1) DEFAULT NULL, PRIMARY KEY (`s_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES ('1', '魯班', '12', '男'); INSERT INTO `student` VALUES ('2', '貂蟬', '20', '女'); INSERT INTO `student` VALUES ('3', '劉備', '35', '男'); INSERT INTO `student` VALUES ('4', '關羽', '34', '男'); INSERT INTO `student` VALUES ('5', '張飛', '33', '女'); -- ---------------------------- -- Table structure for teacher -- ---------------------------- DROP TABLE IF EXISTS `teacher`; CREATE TABLE `teacher` ( `t_id` int(10) NOT NULL, `t_name` varchar(50) DEFAULT NULL, PRIMARY KEY (`t_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of teacher -- ---------------------------- INSERT INTO `teacher` VALUES ('1', '大王'); INSERT INTO `teacher` VALUES ('2', 'alex'); INSERT INTO `teacher` VALUES ('3', 'egon'); INSERT INTO `teacher` VALUES ('4', 'peiqi'); #7.2、統計各科各分數段人數.顯示格式:課程ID,課程名稱,[100-85],[85-70],[70-60],[ <60] select score.c_id, course.c_name, sum(CASE WHEN num BETWEEN 85 and 100 THEN 1 ELSE 0 END) as '[100-85]', sum(CASE WHEN num BETWEEN 70 and 85 THEN 1 ELSE 0 END) as '[85-70]', sum(CASE WHEN num BETWEEN 60 and 70 THEN 1 ELSE 0 END) as '[70-60]', sum(CASE WHEN num < 60 THEN 1 ELSE 0 END) as '[ <60]' from score,course where score.c_id=course.c_id GROUP BY score.c_id;
select * form tb limit 0,5
limit 起始,數量
數據量過大,頁數越大,查詢速度越慢,由於頁數越大,數據id就越大,查詢時就會從頭開始掃描數據,
解決辦法:
方案一:
一、記錄當期頁,數據ID的最大值、最小值, 二、翻頁查詢時,先根據數據ID篩選數據,在limit查詢
select * from (select * from tb where id > 22222222) as B limit 0,10
若是用戶本身修改url上的頁碼,咱們能夠參考rest-frameword中的分頁,對url中的頁碼進行加密處理
方案二:
能夠根據實際業務需求,只展現部分數據(只顯示200-300頁的數據)
slow_query_log = ON 是否開啓慢日誌記錄 long_query_time = 2 時間限制,超過此時間,則記錄 slow_query_log_file = /usr/slow.log 日誌文件 log_queries_not_using_indexes = ON 爲使用索引的搜索是否記錄
導入:mysqldump -u root -p db > F:\db.txt
導出:mysqldump -u root -p db(存在的) < F:\db.txt;
explain select * from tb; #查看sql語句執行速度
- 不用 select *
- 固定長度字段列,往前放
- char(固定長度)和varchar
- 固定數據放入內存:choice
- 讀寫分離,利用數據庫的主從進行分離:主,用於刪除、修改更新;從,查。
- 分庫,當數據庫中表太多,將表分到不一樣的數據庫;例如:1w張表
- 分表
- 水平分表,將某些列拆分到另一張表;例如:博客+博客詳細
- 垂直分表,將歷史信息分到另一張表中;例如:帳單
- 緩存:利用redis、memcache,將經常使用的數據放入緩存中
-查詢一條數據
select * from tb where name='alex' limit 1
-text類型
爲前面幾個字符串建立索引
在對name作了惟一索引前提下,簡述如下區別:
一、 select * from tb where name = ‘Oldboy-Wupeiqi’
二、select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1 速度快
一、添加事務,
加鎖
修改數據並判斷是否爲0
釋放鎖
提交事務
二、將秒殺商品放入redis中利用watch實現,
三、使用隊列
處理併發:
一、前端:擴容(加機器)、 限流(限制ip訪問次數)、靜態化(頁面最大程度使用靜態,cdn)
二、後端:【內存】+【排隊】