今天繼續分享 Python 相關的面試題,你準備好了嘛!html
網絡編程篇前端
是網絡傳輸協議,人爲的把網絡傳輸的不一樣階段劃分紅不一樣的層次。mysql
七層劃分爲:應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層、物理層。linux
五層劃分爲:應用層、傳輸層、網絡層、數據鏈路層、物理層。程序員
物理層:網線,電纜等物理設備 數據鏈路層:Mac 地址 網絡層:IP 地址 傳輸層:TCP,UDP 協議 應用層:FTP 協議,Email,WWW 等web
都發生在傳輸層面試
TCP 協議是主機對主機層的傳輸控制協議,提供可靠的鏈接服務,採用三次握手確認創建一個鏈接。ajax
TCP 標誌位(位碼),有6種標示:SYN(synchronous創建聯機) ACK(acknowledgement 確認) PSH(push傳送) FIN(finish結束) RST(reset重置) URG(urgent緊急)redis
Sequence number(順序號碼) Acknowledge number(確認號碼)算法
第一次握手:主機 A 發送位碼爲 syn=1,隨機產生 seq number=1234567 的數據包到服務器,並進入 SYN_SEND 狀態,主機 B 由 SYN=1 知道,A 要求創建聯機;
第二次握手:主機 B 收到請求後要確認聯機信息,向 A 發送 ack number=(主機 A 的 seq+1),syn=1,ack=1,隨機產生 seq=7654321 的包,並進入 SYN_RECV 狀態;
第三次握手:主機 A 收到後檢查 ack number 是否正確,即第一次發送的 seq number+1,以及位碼 ack 是否爲 1,若正確,主機 A 會再發送 ack number=(主機 B 的 seq+1),ack=1,主機 B 收到後確認 seq 值與 ack=1 則鏈接創建成功,兩個主機均進入 ESTABLISHED 狀態。
以上完成三次握手,主機 A 與主機 B 開始傳送數據。
由於 TCP 鏈接是全雙工的,所以每一個方向都必須單獨進行關閉。這個原則是當一方完成它的數據發送任務後就能發送一個 FIN 來終止這個方向的鏈接。收到一個 FIN 只意味着這一方向上沒有數據流動,一個 TCP 鏈接在收到一個 FIN 後仍能發送數據。首先進行關閉的一方將執行主動關閉,而另外一方執行被動關閉。
B/S 又稱爲瀏覽器/服務器模式。好比各類網站,jupyter notebook 等。
優勢:零安裝,維護簡單,共享性好。
缺點:安全性較差,個性化不足。
C/S 又稱爲客戶端/服務器模式。好比微信客戶端,Oracle 客戶端等。
優勢:安全性好,數據傳輸較快,穩定。
缺點:對 PC 機操做系統等有要求,當客戶端較多時,服務器端負載較大。
TCP 和 UDP 都是 OSI 模型中運輸層的協議。TCP 提供可靠的通訊傳輸,而 UDP 則常被用於廣播和細節控制交給應用的通訊傳輸。
UDP 不提供複雜的控制機制,利用 IP 提供面向無鏈接的通訊服務。
TCP 充分實現了數據傳輸時各類控制功能,能夠進行丟包的重發控制,還能夠對次序亂掉的分包進行順序控制。
TCP 應用:FTP 傳輸,點對點短信等。
UDP 應用:媒體流等。
廣域網(WAN,Wide Area Network)也稱遠程網(long haul network )。一般跨接很大的物理範圍,所覆蓋的範圍從幾十千米到幾千千米,它能鏈接多個城市或國家,或橫跨幾個洲並能提供遠距離通訊,造成國際性的遠程網絡。
局域網(Local Area Network,LAN)是指在某一區域內由多臺計算機互聯成的計算機組。通常是方圓幾公里之內。局域網能夠實現文件管理、應用軟件共享、打印機共享、工做組內的日程安排、電子郵件和傳真通訊服務等功能。局域網是封閉型的,能夠由辦公室內的兩臺計算機組成,也能夠由一個公司內的上千臺計算機組成。
ARP(Address Resolution Protocol)即地址解析協議, 用於實現從 IP 地址到 MAC 地址的映射,即詢問目標 IP 對應的 MAC 地址。
socket 是對 TCP/IP 協議的封裝,它的出現只是使得程序員更方便地使用 TCP/IP 協議棧而已。socket 自己並非協議,它是應用層與 TCP/IP 協議族通訊的中間軟件抽象層,是一組調用接口(TCP/IP網絡的API函數)。
「TCP/IP 只是一個協議棧,就像操做系統的運行機制同樣,必需要具體實現,同時還要提供對外的操做接口。 這個就像操做系統會提供標準的編程接口,好比win32編程接口同樣。TCP/IP 也要提供可供程序員作網絡開發所用的接口,這就是 Socket 編程接口。」
Server:
import socket
import threading
def tcplink(sock, addr):
print('Accept new connection from %s:%s...' % addr)
sock.send(b'Welcome!')
while True:
data = sock.recv(1024)
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
sock.close()
print('Connection from %s:%s closed.' % addr)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 監聽端口:
s.bind(('127.0.0.1', 9999))
s.listen(5)
print('Waiting for connection...')
while True:
# 接受一個新鏈接:
sock, addr = s.accept()
# 建立新線程來處理TCP鏈接:
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
複製代碼
Client:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 創建鏈接:
s.connect(('127.0.0.1', 9999))
# 接收歡迎消息:
print(s.recv(1024).decode('utf-8'))
for data in [b'Michael', b'Tracy', b'Sarah']:
# 發送數據:
s.send(data)
print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
複製代碼
例子來源於廖雪峯的官網
進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。每一個進程都有本身的獨立內存空間,不一樣進程經過進程間通訊來通訊。
線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源。
協程是一種用戶態的輕量級線程,協程的調度徹底由用戶控制。協程擁有本身的寄存器上下文和棧。
多進程:密集 CPU 任務,須要充分使用多核 CPU 資源(服務器,大量的並行計算)的時候,用多進程。
缺陷:多個進程之間通訊成本高,切換開銷大。
多線程:密集 I/O 任務(網絡 I/O,磁盤 I/O,數據庫 I/O)使用多線程合適。
缺陷:同一個時間切片只能運行一個線程,不能作到高並行,可是能夠作到高併發。
協程:又稱微線程,在單線程上執行多個任務,用函數切換,開銷極小。不經過操做系統調度,沒有進程、線程的切換開銷。
缺陷:單線程執行,處理密集 CPU 和本地磁盤 IO 的時候,性能較低。處理網絡 I/O 性能仍是比較高。
多線程請求返回是無序的,哪一個線程有數據返回就處理哪一個線程,而協程返回的數據是有序的。
池的功能是限制啓動的進程數或線程數。當併發的任務數遠遠超過了計算機的承受能力時,即沒法一次性開啓過多的進程數或線程數時,就應該用池的概念將開啓的進程數或線程數限制在計算機可承受的範圍內。
from multiprocessing import Pool
import os
import time
import random
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
def test_pool():
print('Parent process %s.' % os.getpid())
p = Pool(4)
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')
if __name__ == '__main__':
test_pool()
複製代碼
output
Parent process 32432.
Waiting for all subprocesses done...
Run task 0 (15588)...
Run task 1 (32372)...
Run task 2 (12440)...
Run task 3 (18956)...
Task 2 runs 0.72 seconds.
Run task 4 (12440)...
Task 3 runs 0.82 seconds.
Task 1 runs 1.21 seconds.
Task 0 runs 3.00 seconds.
Task 4 runs 2.95 seconds.
All subprocesses done.
複製代碼
apply_async(func[, args[, kwds]]) :使用非阻塞方式調用 func(並行執行,堵塞方式必須等待上一個進程退出才能執行下一個進程),args 爲傳遞給 func 的參數列表,kwds 爲傳遞給 func 的關鍵字參數列表; close():關閉 Pool,使其再也不接受新的任務; terminate():無論任務是否完成,當即終止; join():主進程阻塞,等待子進程的退出, 必須在 close 或 terminate 以後使用;
也可使用 concurrent.futures 模塊提供的功能來實現
def test_future_process():
print('Parent process %s.' % os.getpid())
p = ProcessPoolExecutor(4)
for i in range(5):
p.submit(long_time_task, i)
p.shutdown(wait=True)
print('Finish')
if __name__ == '__main__':
# test_pool()
test_future_process()
複製代碼
output
Parent process 29368.
Run task 0 (32148)...
Run task 1 (31552)...
Run task 2 (24012)...
Run task 3 (29408)...
Task 2 runs 0.52 seconds.
Run task 4 (24012)...
Task 3 runs 0.86 seconds.
Task 1 runs 1.81 seconds.
Task 0 runs 1.83 seconds.
Task 4 runs 1.69 seconds.
Finish
複製代碼
def sayhello(a):
print("hello: " + a)
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (a, (end - start)))
def test_future_thread():
seed = ["a", "b", "c", "d"]
start = time.time()
with ThreadPoolExecutor(3) as executor:
for i in seed:
executor.submit(sayhello, i)
end = time.time()
print("Thread Run Time: " + str(end - start))
複製代碼
output
hello: a
hello: b
hello: c
Task a runs 0.40 seconds.
hello: d
Task b runs 0.56 seconds.
Task d runs 1.70 seconds.
Task c runs 2.92 seconds.
Thread Run Time: 2.9195945262908936
複製代碼
能夠看出,因爲是建立了限制爲3的線程池,因此只有三個任務在同時執行。
def write(q):
print("write(%s), 父進程爲(%s)" % (os.getpid(), os.getppid()))
for i in "Python":
print("Put %s to Queue" % i)
q.put(i)
def read(q):
print("read(%s), 父進程爲(%s)" % (os.getpid(), os.getppid()))
for i in range(q.qsize()):
print("read 從 Queue 獲取到消息: %s" % q.get(True))
def test_commun():
print("(%s) start" % os.getpid())
q = Manager().Queue()
pw = Process(target=write, args=(q, ))
pr = Process(target=read, args=(q, ))
pw.start()
pr.start()
pw.join()
pr.terminate()
複製代碼
output
(23544) start
write(29856), 父進程爲(23544)
Put P to Queue
Put y to Queue
Put t to Queue
Put h to Queue
Put o to Queue
Put n to Queue
read(25016), 父進程爲(23544)
read 從 Queue 獲取到消息: P
read 從 Queue 獲取到消息: y
read 從 Queue 獲取到消息: t
read 從 Queue 獲取到消息: h
read 從 Queue 獲取到消息: o
read 從 Queue 獲取到消息: n
複製代碼
Python 的 multiprocessing 模塊包裝了底層的機制,提供了 Queue、Pipes 等多種方式來交換數據。
進程鎖:是爲了控制同一操做系統中多個進程訪問一個共享資源,只是由於程序的獨立性,各個進程是沒法控制其餘進程對資源的訪問的,可是可使用本地系統的信號量控制。
信號量(Semaphore),有時被稱爲信號燈,是在多線程環境下使用的一種設施,是能夠用來保證兩個或多個關鍵代碼段不被併發調用。
線程鎖:當多個線程幾乎同時修改一個共享數據的時候,須要進行同步控制,線程同步可以保證多個線程安全的訪問競爭資源(全局內容),最簡單的同步機制就是使用互斥鎖。
某個線程要更改共享數據時,先將其鎖定,此時資源的狀態爲鎖定狀態,其餘線程就能更改,直到該線程將資源狀態改成非鎖定狀態,也就是釋放資源,其餘的線程才能再次鎖定資源。互斥鎖保證了每一次只有一個線程進入寫入操做。從而保證了多線程下數據的安全性。
並行:多個 CPU 核心,不一樣的程序就分配給不一樣的 CPU 來運行。可讓多個程序同時執行。
併發:單個 CPU 核心,在一個時間切片裏一次只能運行一個程序,若是須要運行多個程序,則串行執行。
ThreadLocal 叫作線程本地變量,ThreadLocal 在每個變量中都會建立一個副本,每一個線程均可以訪問本身內部的副本變量,對其餘線程時不可見的,修改以後也不會影響到其餘線程。
域名解析是指將域名解析爲 IP 地址。也有反向的「逆解析」,將 IP 經過 DNS 服務器查找到對應的域名地址。
DNS 是域名系統 (Domain Name System),域名系統爲因特網上的主機分配域名地址和 IP 地址。用戶使用域名地址,該系統就會自動把域名地址轉爲 IP 地址。
LVS 是 Linux Virtual Server 的簡寫,意即 Linux 虛擬服務器,是一個虛擬的服務器集羣系統,即負載均衡服務器。
LVS 工做模式分爲 NAT 模式、TUN 模式、以及 DR 模式。
Nginx 主要功能:一、反向代理 二、負載均衡 三、HTTP 服務器(包含動靜分離) 四、正向代理
正向代理:某些狀況下,代理用戶去訪問服務器,須要手動設置代理服務器的 IP 和端口號。
反向代理:是用來代理服務器的,代理要訪問的目標服務器。代理服務器接受請求,而後將請求轉發給內部網絡的服務器(集羣化),並將從服務器上獲得的結果返回給客戶端,此時代理服務器對外就表現爲一個服務器。
負載均衡服務器相似於 LVS HTTP 服務器相似於 Tomcat 等。
HAProxy 提供高可用性、負載均衡,以及基於 TCP 和 HTTP 的應用程序代理。
keepalived 是集羣管理中保證集羣高可用的一個服務軟件,其功能相似於 heartbeat,用來防止單點故障。
RPC 是指遠程過程調用,也就是說兩臺服務器 A,B,一個應用部署在 A 服務器上,想要調用 B 服務器上應用提供的函數/方法,因爲不在一個內存空間,不能直接調用,須要經過網絡來表達調用的語義和傳達調用的數據。
CDN 的全稱是 Content Delivery Network,即內容分發網絡。CDN 是構建在網絡之上的內容分發網絡,依靠部署在各地的邊緣服務器,經過中心平臺的負載均衡、內容分發、調度等功能模塊,使用戶就近獲取所需內容,下降網絡擁塞,提升用戶訪問響應速度和命中率。CDN 的關鍵技術主要有內容存儲和分發技術。
數據庫和框架篇
關係型數據庫:MySQL,Oracle,SQLServer,SQLite,DB2
非關係型數據庫:MongoDB,Redis,HBase,Neo4j
創建科學的,規範的的數據庫是須要知足一些規範的,以此來優化數據數據存儲方式,在關係型數據庫中這些規範就能夠稱爲範式。
第一範式:當關系模式 R 的全部屬性都不能在分解爲更基本的數據單位時,稱 R 是知足第一範式的,簡記爲 1NF。
關係模式R的全部屬性不能再分解
第二範式:若是關係模式 R 知足第一範式,而且 R 的全部非主屬性都徹底依賴於 R 的每個候選關鍵屬性,稱 R 知足第二範式,簡記爲 2NF。
非主屬性都要依賴於每個關鍵屬性
三範式:設 R 是一個知足第一範式條件的關係模式,X 是 R 的任意屬性集,若是 X 非傳遞依賴於 R 的任意一個候選關鍵字,稱 R 知足第三範式,簡記爲 3NF。
數據不能存在傳遞關係,即每一個屬性都跟主鍵有直接關係而不是間接關係
事務(Transaction)是併發控制的基本單位。所謂的事務,它是一個操做序列,這些操做要麼都執行,要麼都不執行,它是一個不可分割的工做單位。
在關係數據庫中,一個事務能夠是一條 SQL 語句、一組 SQL 語句或整個程序。
四個屬性:原子性,一致性,隔離性和持久性。
MySQL 目前主要有如下幾種索引類型:
一對一關係示例: 一個學生對應一個學生檔案材料,或者每一個人都有惟一的身份證編號。
一對多關係示例: 一個學生只屬於一個班,可是一個班級有多名學生。
多對多關係示例: 一個學生能夠選擇多門課,一門課也有多名學生。
觸發器:觸發器是一個特殊的存儲過程,它是數據庫在 insert、update、delete 的時候自動執行的代碼塊。
函數:數據庫中提供了許多內置函數,還能夠自定義函數,實現 sql 邏輯。
視圖:視圖是由查詢結果造成的一張虛擬表,是表經過某種運算獲得的一個投影。
存儲過程:把一段代碼封裝起來,當要執行這一段代碼的時候,能夠經過調用該存儲過程來實現(通過第一次編譯後再次調用不須要再次編譯,比一個個執行 sql 語句效率高)
DML(數據操做語言)
DDL(數據定義語言)
定義主鍵和外鍵主要是爲了維護關係數據庫的完整性
主鍵是能肯定一條記錄的惟一標識。不能重複,不容許爲空。
外鍵用於與另外一張表關聯。是能肯定另外一張表記錄的字段,用於保持數據的一致性。
主鍵 | 外鍵 | 索引 | |
---|---|---|---|
定義 | 惟一標識一條記錄,不能重複,不容許爲空 | 表的外鍵是另外一表的主鍵,外鍵能夠重複,能夠是空值 | 該字段沒有重複值,但能夠有空值 |
做用 | 用來保證數據完整性 | 用來和其餘表創建聯繫 | 提升查詢排序的速度 |
個數 | 只能有一個 | 可有多個 | 可有多個 |
mysqldump -u 用戶名 -p 數據庫名 > 導出的文件名
char:存儲定長數據很方便,CHAR 字段上的索引效率級高,必須在括號裏定義長度,能夠有默認值,好比定義 char(10)。
varchar:存儲變長數據,但存儲效率沒有 CHAR 高,必須在括號裏定義長度,能夠有默認值。
mysql 創建多列索引(聯合索引)有最左前綴的原則,即最左優先,如:
若是有一個2列的索引(col1,col2),則已經對(col1)、(col1,col2)上創建了索引;
若是有一個3列索引(col1,col2,col3),則已經對(col1)、(col1,col2)、(col1,col2,col3)上創建了索引;
a
,b
,c
,d
),那麼能命中索引的查詢爲 a,ab,abc,abcd,除此以外都沒法命中索引讀寫分離,就是將數據庫分爲了主從庫,一個主庫用於寫數據,多個從庫完成讀數據的操做,主從庫之間經過某種機制進行數據的同步,是一種常見的數據庫架構。
數據庫水平切分,是一種常見的數據庫架構,是一種經過算法,將數據庫進行分割的架構。一個水平切分集羣中的每一個數據庫,一般稱爲一個「分片」。每個分片中的數據沒有重合,全部分片中的數據並集組成所有數據。
水平切分分爲庫內分表和分庫分表,是根據表內數據內在的邏輯關係,將同一個表按不一樣的條件分散到多個數據庫或多個表中,每一個表中只包含一部分數據,從而使得單個表的數據量變小,達到分佈式的效果。
redis 默認有16個數據庫,每一個數據庫中的數據都是隔離的,這樣,在存儲數據的時候,就能夠指定把不一樣的數據存儲到不一樣的數據庫中。 且只有單機纔有,若是是集羣就沒有數據庫的概念。
RDB 持久化:是將 Reids 在內存中的數據庫記錄定時 dump 到磁盤上的持久化
AOF(append only file)持久化:將 Reids 的操做日誌以追加的方式寫入文件
通用的三種過時策略
redis 採用惰性刪除+按期刪除策略
限定 Redis 佔用的內存,Redis 會根據自身數據淘汰策略,加載熱數據到內存。 因此,計算一下全部熱點數據大約佔用的內存,而後設置一下 Redis 內存限制便可。
使用 redis 第三方庫來操做
import redis
# 建立一個 redis 鏈接池
def redis_conn_pool():
pool = redis.ConnectionPool(host='redis-host', port=redis-port,
decode_responses=True, password='redis-pwd')
r = redis.Redis(connection_pool=pool)
return r
複製代碼
訂閱者
if __name__ == "__main__":
conn = redis.Redis(host='',
port=12143, password='')
ps = conn.pubsub()
ps.subscribe('chat') # 從 chat 訂閱消息
for item in ps.listen(): # 監聽狀態:有消息發佈了就拿過來
if item['type'] == 'message':
print(item)
print(item['channel'])
print(item['data'])
複製代碼
發佈者
if __name__ == "__main__":
number_list = ['300033', '300032', '300031', '300030']
signal = ['1', '-1', '1', '-1']
pool = redis.ConnectionPool(host='redis-12143.c8.us-east-1-3.ec2.cloud.redislabs.com', port=12143,
decode_responses=True, password='pkAWNdYWfbLLfNOfxTJinm9SO16eSJFx')
r = redis.Redis(connection_pool=pool)
for i in range(len(number_list)):
value_new = str(number_list[i]) + ' ' + str(signal[i])
print(value_new)
r.publish("chat", value_new)
複製代碼
import redis
con = redis.Redis()
con.keys(pattern='key*') # *表明通配符
複製代碼
class Zhan:
def __init__(self,conn):
self.conn = conn
def push(self,val):
self.conn.rpush('aaa',val)
def pop(self):
return self.conn.rpop('aaa')
class Dui:
def __init__(self,conn):
self.conn = conn
def push(self,val):
self.conn.rpush('bbb',val)
def get(self):
return self.conn.lpop('bbb')
class Xu:
def __init__(self,conn):
self.conn = conn
def push(self,val,count):
self.conn.zadd('ccc',val,count)
def get(self):
a = self.conn.zrange('ccc', 0, 0)[0]
self.conn.zrem('ccc', a)
return a
複製代碼
在從服務器中配置 SLAVEOF 127.0.0.1 6380 # 主服務器 IP,端口
def list_iter(name):
""" 自定義redis列表增量迭代 :param name: redis中的name,即:迭代name對應的列表 :return: yield 返回 列表元素 """
list_count = r.llen(name)
for index in xrange(list_count):
yield r.lindex(name, index)
複製代碼
watch 用於在進行事務操做的最後一步也就是在執行 exec 以前對某個 key 進行監視,若是這個被監視的 key 被改動,那麼事務就被取消,不然事務正常執行。
爲 redis 集羣設計的鎖,防止多個任務同時修改數據庫,其本質就是爲集羣中的每一個主機設置一個會超時的字符串,當集羣中有一半多的機器設置成功後就認爲加鎖成功,直至鎖過時或解鎖不會有第二個任務加鎖成功。
超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最爲普遍的一種網絡協議。HTTP 是一個客戶端和服務器端請求和應答的標準。客戶端是終端用戶,服務器端是網站。通常由 HTTP 客戶端發起一個請求,創建一個到服務器指定端口(默認是80端口)的 TCP 鏈接,HTTP 服務器則在那個端口監聽客戶端發送過來的請求,並給與響應。
WSGI:全稱是 Web Server Gateway Interface,是一種描述 web server 如何與 web application 通訊的規範。django,flask 等都遵循該協議。
uwsgi:是服務器和服務端應用程序的一種協議,規定了怎麼把請求轉發給應用程序和返回; uwsgi 是一種線路協議而不是通訊協議,在此經常使用於在 uWSGI 服務器與其餘網絡服務器的數據通訊。
uWSGI:是一個 Web 服務器,它實現了 WSGI 協議、uwsgi、http 等協議。Nginx 中 HttpUwsgiModule 的做用是與 uWSGI 服務器進行交換。
1xx: 信息
2xx:成功
3xx:重定向
4xx:客戶端錯誤
5xx:服務器錯誤
GET,POST,PUT,DELETE,PATCH 等
響應式佈局是 Ethan Marcotte 在2010年5月份提出的一個概念,簡而言之,就是一個網站可以兼容多個終端——而不是爲每一個終端作一個特定的版本。
AJAX 是一種在無需從新加載整個網頁的狀況下,可以更新部分網頁的技術。
AJAX = 異步 JavaScript 和 XML
$(function(){
$('#send').click(function(){
$.ajax({
type: "GET",
url: "test.json",
data: {username:$("#username").val(), content:$("#content").val()},
dataType: "json",
success: function(data){
$('#resText').empty(); //清空resText裏面的全部內容
var html = '';
$.each(data, function(commentIndex, comment){
html += '<div class="comment"><h6>' + comment['username']
+ ':</h6><p class="para"' + comment['content']
+ '</p></div>';
});
$('#resText').html(html);
}
});
});
});
複製代碼
同源策略限制了從同一個源加載的文檔或腳本如何與來自另外一個源的資源進行交互。這是一個用於隔離潛在惡意文件的重要安全機制。
若是兩個頁面的協議,端口(若是有指定)和主機都相同,則兩個頁面具備相同的源。咱們也能夠把它稱爲「協議/主機/端口 tuple」,或簡單地叫作「tuple". ("tuple" ,「元」,是指一些事物組合在一塊兒造成一個總體,好比(1,2)叫二元,(1,2,3)叫三元)
CORS 全稱是跨域資源共享(Cross-Origin Resource Sharing),是一種 AJAX 跨域請求資源的方式,支持現代瀏覽器。
CSRF(Cross-site request forgery),中文名稱:跨站請求僞造,也被稱爲:one click attack/session riding,縮寫爲:CSRF/XSRF。
輪詢
var xhr = new XMLHttpRequest();
setInterval(function(){
xhr.open('GET','/user');
xhr.onreadystatechange = function(){
};
xhr.send();
},1000)
複製代碼
長輪詢
function ajax(){
var xhr = new XMLHttpRequest();
xhr.open('GET','/user');
xhr.onreadystatechange = function(){
ajax();
};
xhr.send();
}
複製代碼
所謂 MVC 就是把 web 應用分爲模型(M),控制器(C),視圖(V)三層,他們之間以一種插件似的,鬆耦合的方式鏈接在一塊兒。 模型負責業務對象與數據庫的對象(ORM),視圖負責與用戶的交互(頁面),控制器(C)接受用戶的輸入調用模型和視圖完成用戶的請求。
Django 中的 MTV 模式:Model(模型):負責業務對象與數據庫的對象(ORM),Template(模版):負責如何把頁面展現給用戶,View(視圖):負責業務邏輯,並在適當的時候調用 Model 和 Template,本質上與 MVC 相同。
接口冪等性就是用戶對於同一操做發起的一次請求或者屢次請求的結果是一致的,不會由於屢次點擊而產生了反作用。
簡潔,輕巧,擴展性強,自由度高。
ORM 的全稱是 Object Relational Mapping,即對象關係映射。它的實現思想就是將關係數據庫中表的數據映射成爲對象,以對象的形式展示,這樣開發人員就能夠把對數據庫的操做轉化爲對這些對象的操做。
PV:是(page view)訪問量,頁面瀏覽量或點擊量,衡量網站用戶訪問的網頁數量。在必定統計週期內用戶每打開或刷新一個頁面就記錄1次,屢次打開或刷新同一頁面則瀏覽量累計。 UV:是(Unique Visitor)獨立訪客,統計一段時間內訪問某站點的用戶數(以cookie爲依據)。
supervisor 管理進程,是經過 fork/exec 的方式將這些被管理的進程看成 supervisor 的子進程來啓動,因此咱們只須要將要管理進程的可執行文件的路徑添加到 supervisor 的配置文件中便可。
優勢:
缺點:
from django.db import connection
cursor = connection.cursor()
cursor.execute("SELECT DATE_FORMAT(create_time, '%Y-%m') FROM blog_article;")
ret = cursor.fetchall()
print(ret)
複製代碼
cookie 是保存在瀏覽器端的鍵值對,能夠用來作用戶認證。
sesseion 是將用戶的會話信息保存在服務端,key 值是隨機產生的字符串,value 值是 session 的內容,依賴於 cookie 將每一個用戶的隨機字符串保存到用戶瀏覽器中。
BeautifulSoup 庫是解析、遍歷、維護「標籤樹」的功能庫。
url = "http://www.baidu.com/"
request = requests.get(url)
html = request.content
soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8")
複製代碼
Selenium 是模擬操做瀏覽器的庫,能夠根據咱們的指令,讓瀏覽器自動加載頁面,獲取須要的數據,甚至頁面截屏,或者判斷網站上某些動做是否發生等。
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
print(browser.page_source) # browser.page_source 是獲取網頁的所有 html
browser.close()
複製代碼
歡迎關注個人微信公衆號--蘿蔔大雜燴,或者掃描下方的二維碼,你們一塊兒交流,學習和進步!