面試-python

io多路複用機制

# io多路複用 是同步阻塞的,單線程,這裏阻塞是指select函數執行時線程被阻塞,而不是指socket
創建一些socket,例如,當socket1在執行一些讀寫的操作時,socket2可以去執行一些別的操作了,不用等着socket1把讀寫操作完,才操作;

			   用戶執行的程序
			       |   # 阻塞的是調用select函數
				select 函數
			  / | | | | \ 
             s1 s2 s3 s4 s5 s6   # 處理IO操作的是異步,而且不影響用戶執行的程序  
# 在查資料看一看
epoll select poll

# 阻塞I/O模型
監聽到一個請求時,只有等這個請求處理完,才能處理下一個請求

# 非阻塞I/O模型
監聽到一個請求,進行處理,在處理的過程中,又來了一個請求,直接返回錯誤或者空

與多進程和多線程技術相比,I/O多路複用技術的最大優勢是系統開銷小,系統不必創建進程/線程,也不必維護這些進程/線程,從而大大減小了系統的開銷

協程爲什麼比線程和進程快

進程和線程都面臨着內核態和用戶態的切換問題而耗費許多切換時間,而協程就是用戶自己控制切換的時機,不再需要陷入系統的內核態
# 關鍵字yield

淺拷貝和深拷貝

import copy
a = [1, 2, 3, 4, ['a', 'b']]  #原始對象

b = a  # 賦值,傳對象的引用
c = copy.copy(a)  # 對象拷貝,淺拷貝
d = copy.deepcopy(a)  # 對象拷貝,深拷貝

a.append(5)  # 修改對象a
a[4].append('c')  # 修改對象a中的['a', 'b']數組對象

print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d

輸出結果:
a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]  # 引用a
c =  [1, 2, 3, 4, ['a', 'b', 'c']]  # 淺拷貝
d =  [1, 2, 3, 4, ['a', 'b']] # 深拷貝

# 總結
引用,和原數據一模一樣
深拷貝,是完全獨立的一份
淺拷貝,如果原數據裏面的元素是可變類型的,那麼該可變類型變化時,淺拷貝的數據也發生變化,僅此而已,其他的都不影響淺拷貝的數據

python的垃圾回收機制

Python GC主要使用引用計數(reference counting)來跟蹤和回收垃圾
在引用計數的基礎上,通過“標記-清除”(mark and sweep)解決容器對象可能產生的循環引用問題
通過“分代回收”(generation collection)以空間換時間的方法提高垃圾回收效率

1.引用計數
2.標記-清除,解決循環引用
3.分代回收

迭代器和生成器

迭代器:滿足兩個模方法,iter和next,必須爲可迭代對象,能被for遍歷的都是迭代器
生成器:是一個特殊的迭代器,把return改爲yield
[i for i range(10)] --> (i for i range(10)) # 這就是生成器了

數據庫

數據庫引擎
# MyISAM
查詢快,但增刪性能不行

# 所有表必須使用Innodb存儲引擎(5.6以後的默認引擎)
支持事務,行級鎖,更好的恢復性,高併發下性能更好
數據庫事務
原子性:一個事務不可再分割,要麼都執行要麼都不執行
一致性:一個事務執行會是數據從一個一致狀態切換到另外一個一致狀態
隔離線:一個事務的執行不受其他事務的干擾
持久性:一個事務一旦提交,則會永久的改變數據庫的數據
數據庫鎖
# 表鎖(偏讀)
1、對MyISAM表的讀操作(加讀鎖),不會阻塞其他進程對同一表的讀請求,但會阻塞對同一表的寫請求。只有當讀鎖釋放後,纔會執行其他進程的寫操作
2、對MyISAM表的寫操作(加寫鎖),會阻塞其他進程對同一表的讀和寫操作,只有當寫鎖釋放後,纔會執行其它進程的讀寫操作。
簡而言之,就是讀鎖會阻塞寫,但是不會堵塞讀。而寫鎖則會吧讀和寫都堵塞。

# 行鎖(偏寫)
# 行鎖注意點:
無索引行鎖升級爲表鎖
間隙鎖危害
間隙鎖:鎖住了不存在的資源,消耗了性能;

# 對行鎖的優化建議:
儘可能讓所有數據檢索都通過索引來完成,避免無索引行鎖升級爲表鎖。
合理設計索引,儘量縮小鎖的方位
儘可能較少檢索條件,避免間隙鎖
儘量控制事務大小,減少鎖定資源量和時間長度
儘可能低級別事務隔離
悲觀鎖和樂觀鎖
# 悲觀鎖
顧名思義,悲觀,認爲來操作數據庫,都會修改裏面的數據,所以給它加鎖,只能等到它釋放了,下一個人才能操作
機制:使用數據庫鎖的機制,排它鎖的機制

# 樂觀鎖
顧名思義和樂觀,認爲來操作數據庫的,都不會修改裏面的數據,當修改數據時,它就會把當前記錄表的版本號與數據庫表中的版本號進行比較,如果一致,就允許修改,不一致就不允許,重新更新一下即可
機制:不是真正的鎖,使用數據的版本號或者時間戳

Redis

redis五大數據類型
string hash list set zset
redis爲什麼快
1.純c編寫
2.內存操作
3.單線程
4.I/O多路複用
持久化
# RDB
檢測key的變化,在一定時間內,key變化的次數達到了,就把數據存儲到文件中

# AOF
根據定義的時間,來記錄操作的執行語句,存到文件中
例如:記錄每一分鐘內的所有執行語句,存到文件中
Redis Sentienl[哨兵]故障轉移
1.多個sentinel發現並確認master有問題
2.選舉出一個sentinel作爲領導
3.選出一個slave作爲master
4.通知其餘slave成爲新的master的slave
5.通知客戶端主從變化
6.等待老的master複製成爲新master的slave
缺點
1.是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要侷限在較小數據量的高性能操作和運算上。
2.Redis較難支持在線擴容,在集羣容量達到上限時在線擴容會變得很複雜。爲避免這一問題,運維人員在系統上線時必須確保有足夠的空間,這對資源造成了很大的浪費。

網絡

七層協議
應用層:與其它計算機進行通訊的一個應用,它是對應應用程序的通信服務的 http
表示層:這一層的主要功能是定義數據格式及加密

會話層:它定義瞭如何開始、控制和結束會話
傳輸層:TCP/UDP
網絡層:IP
數據鏈路層:它定義了在單個鏈路上如何傳輸數據
物理層
三次握手
1.客戶端通過向服務器端發送一個SYN來創建一個主動打開,作爲三次握手的一部分。客戶端把這段連接的序號設定爲隨機數 A。
2.服務器端應當爲一個合法的SYN回送一個SYN/ACK。ACK 的確認碼應爲 A+1,SYN/ACK 包本身又有一個隨機序號 B。
3.最後,客戶端再發送一個ACK。當服務端受到這個ACK的時候,就完成了三路握手,並進入了連接創建狀態。此時包序號被設定爲收到的確認號 A+1,而響應則爲 B+1
四次揮手
1.客戶端發送一個數據分段, 其中的 FIN 標記設置爲1. 客戶端進入 FIN-WAIT 狀態. 該狀態下客戶端只接收數據, 不再發送數據.
2.服務器接收到帶有 FIN = 1 的數據分段, 發送帶有 ACK = 1 的剩餘數據分段, 確認收到客戶端發來的 FIN 信息.
3.服務器等到所有數據傳輸結束, 向客戶端發送一個帶有 FIN = 1 的數據分段, 並進入 CLOSE-WAIT 狀態, 等待客戶端發來帶有 ACK = 1 的確認報文.
4.客戶端收到服務器發來帶有 FIN = 1 的報文, 返回 ACK = 1 的報文確認, 爲了防止服務器端未收到需要重發, 進入 TIME-WAIT 狀態. 服務器接收到報文後關閉連接. 客戶端等待 2MSL 後未收到回覆, 則認爲服務器成功關閉, 客戶端關閉連接.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章