回顧之前易忘記的知識

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("出錯了")

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章