網絡編程
架構:程序員開發的一種模式python
c/s架構 客戶端/服務器模式程序員
b/s架構 Browser瀏覽器/服務器模式面試
B/S 架構的優點:統一了應用的接口算法
mac地址:物理地址編程
mac地址是12位十六進制組成瀏覽器
ip地址:四位點分十進制組成(ipv4)安全
端口:操做系統 爲每個應用程序分配一個端口號服務器
ip+端口號 惟一肯定某一個電腦上的某一程序網絡
arp協議:經過目標ip地址,獲取目標mac地址數據結構
肯定在局域網內:ip地址&子網掩碼
路由器:
有一個路由表,記錄了歸他管的全部網段
協議:由多人制定的一種規則
TCP:安全可靠的通訊方式,面向鏈接,數據流形式傳輸
UDP:不安全,不可靠,可是速度快,數據包形式傳輸
tcp和udp的區別:
TCP---傳輸控制協議,提供的是面向鏈接、可靠的字節流服務。當客戶和服務器彼此交換數據前,必須先在雙方之間創建一個TCP鏈接,以後才能傳輸數據。TCP提供超時重發,丟棄重複數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另外一端。
UDP---用戶數據報協議,是一個簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,可是並不能保證它們能到達目的地。因爲UDP在傳輸數據報前不用在客戶和服務器之間創建一個鏈接,且沒有超時重發等機制,故而傳輸速度很快
tcp三次握手和四次揮手:
三次握手:創建了一個全雙工的通訊連接
(面試回答)
首先,必須先由客戶端發起鏈接的請求
接下來,服務器接收到請求以後,回覆給客戶端兩個標識,一個syn表示
服務器接收到請求,一個ack表示服務器在作準備工做,兩個標識一塊兒
回覆給客戶端
最後,客戶端接收到服務器的回覆,客戶端準備鏈接的全部資源,開始進行鏈接
發送給服務器一個ack表示客戶端的鏈接準備工做已經完成
(此時表示客戶端和服務器能夠相互鏈接了)
若是面試官問你,哪句代碼體現了三次握手?
回答: 服務器端的accept,客戶端connect
四次揮手:
(面試回答)
(1)首先由鏈接雙方任意一方發起斷開鏈接的請求,發起方發送的請求表示
是我沒有數據要繼續發送了,能夠斷開鏈接了,可是你若是還有數據能夠繼續向我發送數據.
(2)接收方回覆給發起方,表示接到了發起放的斷開請求,開始着手準備斷開事宜
(3)接收方準備完成後,給發起方發送一個標識,表示接受方沒有數據繼續發送了
能夠斷開鏈接了
(4)發起方接收到消息後,準備斷開鏈接,回收資源
若是面試官問你,哪句代碼體現了四次揮手?
回答: close()
ois七層模型:
應用層:py代碼,應用
表示層
會話層
傳輸層:tcp和udp協議 四層路由器
網絡層:ip協議 路由器 三層交換機
數據鏈路層:arp協議 網卡 交換機
物理層:網線,集線器
send 和 sendall 的區別:
對於程序員來講,用起來是沒有什麼區別的
實際上,在socket底層對於兩個方法的封裝有卻別:
send(num) 此方法會嘗試先發送n個數據(n<num),接下來再嘗試發送num-n
sendall(num) 此方法會嘗試一次性將num個數據發送出去
基於文件類型的套接字: AF_UNIX
基於網絡類型的套接字: AF_INET
黏包:就是由於接收端不知道如何接收數據,形成接收數據的混亂的問題
只發生在tcp協議上. 由於tcp協議的特色是面向數據流形式的傳輸
粘包的發生主要是由於tcp協議有兩個機制: 合包機制(nagle算法),拆包機制
解決黏包的方案:使用struct模塊來肯定傳輸了多少字節
tcp的聊天
import socket udp_sk = socket.socket(type=socket.SOCK_DGRAM) #建立一個服務器的套接字 udp_sk.bind(('127.0.0.1',9000)) #綁定服務器套接字 msg,addr = udp_sk.recvfrom(1024) print(msg) udp_sk.sendto(b'hi',addr) # 對話(接收與發送) udp_sk.close() # 關閉服務器套接字 srever
client端 import socket ip_port=('127.0.0.1',9000) udp_sk=socket.socket(type=socket.SOCK_DGRAM) udp_sk.sendto(b'hello',ip_port) back_msg,addr=udp_sk.recvfrom(1024) print(back_msg.decode('utf-8'),addr)
socketserver
# 正常狀況下,tcp協議的socket server,同一時刻只能處理一個請求
# 使用socketserver.ThreadingTCPServer就可讓你的tcp協議的server端同時接受多個客戶端的請求
# 基於socket實現的
# serverforever方法
# 啓動了一個socket的server端
# socketserver啓動以後就會一直對外提供服務
# 一個client服務結束了以後,socketserver會幫助你conn.close
# 可是sk對象永遠不會中止服務
併發編程:
操做系統的三種基本類型:多道批處理系統(時空複用,空間隔離)、分時系統、實時系統。
操做系統是一個協調管理和控制計算機硬件資源和軟件資源的控制程序.
進程:是系統進行資源分配和調度的基本單位,是操做系統結構的基礎,進程是正在運行的程序的實例(an instance of a computer program that is being executed)。廣義定義:進程是一個具備必定獨立功能的程序關於某個數據集合的一次運行活動。它是操做系統動態執行的基本單元,在傳統的操做系統中,進程既是基本的分配單元,也是基本的執行單元。
併發:
併發是指資源有限的狀況下,二者交替輪流使用資源,好比一段路(單核CPU資源)同時只能過一我的,A走一段後,讓給B,B用完繼續給A ,交替使用,目的是提升效率。
進程的狀態:就緒,運行,阻塞
同步:所謂同步就是一個任務的完成須要依賴另一個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成,這是一種可靠的任務序列。要麼成功都成功,失敗都失敗,兩個任務的狀態能夠保持一致。
異步:所謂異步是不須要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工做,依賴的任務也當即執行,只要本身完成了整個任務就算完成了。至於被依賴的任務最終是否真正完成,依賴它的任務沒法肯定,因此它是不可靠的任務序列
。
異步非阻塞:
效率更高,
由於打電話是你(等待者)的事情,而通知你則是櫃檯(消息觸發機制)的事情,程序沒有在兩種不一樣的操做中來回切換
。
好比說,這我的忽然發覺本身煙癮犯了,須要出去抽根菸,因而他告訴大堂經理說,排到我這個號碼的時候麻煩到外面通知我一下,那麼他就沒有被阻塞在這個等待的操做上面,天然這個就是異步+非阻塞的方式了。
進程的建立:系統初始化,一個進程運行過程當中開啓了子進程,用戶交互式請求,一個批處理做業初識化
進程的結束:正常退出,出錯退出,嚴重退出,被其餘進程殺死
進程中:建立進程,鎖,隊列,進程池
數據隔離:進程與進程之間內存中的數據是互相隔離的
主進程建立守護進程(報活)
其一:守護進程會在主進程代碼執行結束後就終止
其二:守護進程內沒法再開啓子進程,不然拋出異常:AssertionError: daemonic processes are not allowed to have children
信號量的原理:鎖+計數器
鎖的分類:
在多個進程\線程同時訪問一個數據的時候就會產生數據不安全的現象
# 多進程 訪問文件
# 多線程
# 同時去訪問一個數據
# 儘可能不要設置全局變量
# 只要在多線程/進程之間用到全局變量 就加上鎖
互斥鎖:
遞歸鎖:
全局解釋器鎖:
死鎖出現的緣由:多把鎖同時應用在多個線程中
互斥鎖和遞歸鎖哪一個好
# 遞歸鎖 快速恢復服務
# 死鎖問題的出現 是程序的設計或者邏輯的問題
# 還應該進一步的排除和重構邏輯來保證使用互斥鎖也不會發生死鎖
# 互斥鎖和遞歸鎖的區別
# 互斥鎖 就是在一個線程中不能連續屢次ACQUIRE
# 遞歸鎖 能夠在同一個線程中acquire任意次,注意acquire多少次就須要release多少次
事件 : 經過一個標記來控制對多個進程進行同步控制
IPC通訊
# 隊列 管道+鎖
# 管道 是隊列的底層
管道 pipe
# IPC通訊的一種機制,隊列就是基於管道來完成通訊的,可是管道是原生的通訊方式,
# 在進程之間會產生數據不安全的狀況,須要本身手動加鎖來處理.
# 管道在數據傳輸過程當中,還涉及到一個端口管理,這個須要咱們在代碼中作處理才能使代碼更完善.
(瞭解)# 數據共享 _ 進程就是數據隔離的
# Manager模塊
# 數據類型 都可以進行數據共享
# 一部分都是不加鎖 不支持數據進程安全
# 不安全的解決辦法 加鎖
# 進程池
# 進程不能無限開 會給操做系統調度增長負擔
# 且真正能被同時執行的進程最多也就和CPU個數相同等
# 進程的開啓和銷燬都要消耗資源和時間
進程池
# 何時用進程池
# 面向高計算型的場景 採用多進程
# 若是開啓的進程數超過5個
# 有幾個CPU就可以同時運行幾個進程
線程:線程
# 線程是CPU調度的最小單位
# 每一個進程中至少有一個線程
# 實際上執行代碼的是線程
線程屬於進程
# 進程負責獲取操做系統分配給個人資源
# 線程負責執行代碼
從代碼的角度上來看
# 多進程
# 開啓和結束 時間開銷大
# 切換的效率低
# 內存隔離
# 多線程
# 開啓和結束 時間開銷很是小
# 切換效率高
# 內存不隔離
# 線程進程之間的對比
# 線程不能獨立存在,必須在一個進程裏
# 線程的開啓 關閉以及切換的開銷要遠遠小於進程
# 同一個進程之間的多個線程之間數據共享
# 何時纔會有到CPU
# 程序計算的時候
# IO阻塞
# 是不會用到CPU的
池 和 信號量
# 池 效率高
# 池子裏有幾個一共就起幾個
# 無論多少任務 池子的個數是固定的
# 開啓進程和關閉進程這些事都是須要固定的開銷
# 就不產生額外的時間開銷
# 且進程程池中的進程數控制的好,那麼操做系統的壓力也小
# 信號量
# 有多少個任務就起多少進程/線程
# 能夠幫助你減小操做系統切換的負擔
# 可是並不能幫助你減小進/線程開啓和關閉的時間
協程:
能在一條線程的基礎上,在多個任務之間互相切換
# 節省了線程開啓的消耗
# 是從python代碼的級別調度的
# 正常的線程是CPU調度的最小單位
# 協程的調度並非由操做系統來完成的
須要安裝第三方模塊:greenlet,gevent