1.操做系統的發展歷史中產生了多道技術: 多道技術:(多道指的是多道/個程序) 空間上的複用:內存中進入多個程序 PS:內存必須實現物理級別的隔離 時間上的複用:cpu要切換: 1. 一個程序佔用cpu的時間過長 2. 一個程序遇到I/O阻塞 產生背景:針對單核,實現併發 2.網絡傳輸五層協議:物理層 - 數據鏈路層(以太網協議--> head + data) - 網絡層(IP -- 路由) - 傳輸層(TCP, UDP) - 應用層(HTTP) 3.變量的三個特徵: id, type, value 4.可變類型是不可hash類型 hash 是什麼? 不可變類型是可hash類型 5.集合的元素遵循三個原則:1:每一個元素必須是不可變類型 2:沒有重複的元素 3:無序 6.爲何py3中字符串是str py2中是bytes類型? 7.文件處理? 8.內置函數? 11. md5 一個文件 import hashlib md5_obj = hashlib.md5() import os filesize = os.path.getsize('filename') f = open('filename','rb') while filesize>0: if filesize > 1024: content = f.read(1024) filesize -= 1024 else: content = f.read(filesize) filesize -= filesize md5_obj.update(content) md5_obj.hexdigest() 12.socket 是什麼? 它是網路傳輸過程當中 應用層與傳輸層中間的一個接口, 它把複雜的TCP,UDP等協議封裝在身後, 只留出咱們看到的接口, 至於內部是怎麼實現的網路鏈接等等不須要咱們知道。 13. TCP 的三次握手 和四次揮手: 握手(我來了你準備好了嗎--> 收到,我也準備好了,你來吧 --> 好的) 揮手(我要走了,你準備好了嗎 --> 你先等一下我還有東西給你 --> 好了嗎 --> 好了 ) 14.爲什麼tcp是可靠傳輸,udp是不可靠傳輸? tcp在數據傳輸時,發送端先把數據發送到本身的緩存中,而後協議控制將緩存中的數據發往對端,對端返回一個ack=1,發送端則清理緩存中的數據,對端返回ack=0,則從新發送數據,因此tcp是可靠的 15.粘包: 1.發送數據時間間隔很短,數據了很小,會合到一塊兒,產生粘包 2.接收方不及時接收緩衝區的包,形成多個包接收(客戶端發送了一段數據,服務端只收了一小部分,服務端下次再收的時候仍是從緩衝區拿上次遺留的數據,產生粘包) 解決辦法: 發送端先發送報頭的長度 --> 發報頭數據 --> 最後發送數據 16.操做系統的兩大做用:一是爲軟件提供簡單的接口來操做硬件。二是使多個軟件對硬件的需求變得有序化 17.multiprocessing類實現開啓子進程 (from multiprocessing import Process) p=Process() p.daemon = True # 守護進程,守護進程不能夠再有子進程,而且主進程死守護進程就死,要寫在p.start()以前 p.join() # 主進程等子進程執行完 以後再結束---> 等的時間就是執行時間最長的子進程執行的時間 p.terminate() # 強制終止進程p,不會進行任何清理操做,若是p建立了子進程,該子進程就成了殭屍進程,用該方法須要特別當心這種狀況。若是p保存了一個鎖那麼也將不會被釋放,進而致使死鎖 p.is_alive() # 若是p仍然運行,返回True p.name # 查看進程的名稱 p.pid -->查看進程的pid p.ppid -->查看進程的父進程pid 主進程不會等待子進程的結束,除非加了join方法 18.共享就存在競爭,----加鎖-----隊列 19.建立線程模塊:from threading import Thread 多線程共享它們進程的資源,線程的建立比建立進程開銷小 守護線程: 主線程的非守護線程執行完(主線程執行完畢)——>守護死 20.GIL 鎖 與 Lock鎖 21.進程池、線程池:from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor 進程池 默認個數是CPU個數,而線程池的默認個數是CPU個數的5倍 22.協程 優勢:建立時消耗資源更小,屬於程序級別的切換,操做系統徹底感知不到,於是更加輕量級 缺點:1.協程的本質是單線程下,沒法利用多核,能夠是一個程序開啓多個進程,每一個進程內開啓多個線程,每一個線程內開啓協程 2. 協程指的是單個線程,於是一旦協程出現阻塞,將會阻塞整個線程 gevent 模塊實現協程: from gevent import monkey;monkey.patch_all() #monkey;monkey.patch_all() 能夠識別其餘的I/O操做 import gevent import time,threading def eat(name): print('%s eat 1' %name) time.sleep(2) print('%s eat 2' %name) return 'eat' def play(name): print('%s play 1' %name) time.sleep(3) print('%s play 2' %name) return 'play' start=time.time() g1=gevent.spawn(eat,'egon') g2=gevent.spawn(play,'egon') # g1.join() # g2.join() gevent.joinall([g1,g2]) print('主',(time.time()-start)) print(g1.value) print(g2.value) # 結果: egon eat 1 egon play 1 egon eat 2 egon play 2 主 3.0018091201782227 eat play 23.select,poll,epoll實現IO多路複用機制 三個模塊的區別: select模塊自動監聽多個套接字 (誰好了就返回誰) 可是監聽的套接字(socket)個數不是無限多的 poll的實現機制和select時很是類似的 epoll模型能夠解決套接字個數很是多的狀況(由於它的內部檢測哪一個套接字好了的機制和select不一樣 (select是遍歷每一個套接字,看有沒有好了的, 而epoll是 若是哪一個套接字好了,就自動跑出來)), 可是windows不支持epoll模型 24.數據庫的curd基本語句 25.InnoDB 支持事務,支持行級別鎖定、 Memory 不支持事務,支持表級別鎖定, MyISAM 不支持事務,支持表級別鎖定 26.from multiprocessing import Process,JoinableQueue,Queue import time,random,os def consumer(q): while True: res=q.get() if res is None:break #收到結束信號則結束 time.sleep(random.randint(1,3)) print('\033[45m%s 吃 %s\033[0m' %(os.getpid(),res)) q.task_done() # 向q.join()發送一次信號,證實一個數據已經被取走了 def producer(name,q): for i in range(2): time.sleep(random.randint(1,3)) res='%s%s' %(name,i) q.put(res) print('\033[44m%s 生產了 %s\033[0m' %(os.getpid(),res)) # q.join() #q.join除了能夠放在主進程裏面,也能夠放在這裏 if __name__ == '__main__': q=JoinableQueue() #生產者們:即廚師們 p1=Process(target=producer,args=('包子',q)) p2=Process(target=producer,args=('骨頭',q)) p3=Process(target=producer,args=('泔水',q)) #消費者們:即吃貨們 c1=Process(target=consumer,args=(q,)) c2=Process(target=consumer,args=(q,)) c1.daemon=True #設置成守護進程 c2.daemon=True #開始 p1.start() p2.start() p3.start() c1.start() c2.start() p1.join() #必須保證生產者所有生產完畢,才應該發送結束信號 p2.join() p3.join() q.join() #生產者和消費者的進程都完成了 print('主') #爲何設置消費者爲守護進程,由於執行到最後,生產者進程執行完了,主進程也完成了,可是因爲消費者 #進程是死循環,並無結束,設置成守護進程後,主進程結束了,c1和c2也就能夠結束了 27. 現有兩個元組(('a'),('b')),(('c'),('d')), 請使用python中匿名函數生成列表[{'a':'c'},{'b':'d'}] 28. assert 斷言是什麼?它的使用場景? 29. logging模塊的使用 import logging def my_logger(filename,file=True,stream = True): logger = logging.getLogger() formatter = logging.Formatter(fmt='%(name)s %(asctime)s [%(lineno)d] -- %(message)s', datefmt='%d/%m/%y %H:%M:%S') logger.setLevel(logging.DEBUG) if file: file_handler = logging.FileHandler(filename,encoding='utf-8') file_handler.setFormatter(formatter) # 文件流 文件操做符 logger.addHandler(file_handler) if stream: stream_handler = logging.StreamHandler() stream_handler.setFormatter(formatter) #屏幕流 屏幕操做符 logger.addHandler(stream_handler) return logger logger = my_logger('logging',file=False) logger.warning("出錯了")