1.python中線程和協程的區別,各自優缺點
1.區別:
- 線程可以併發運行,線程之間是不能共寫全局變量(寫衝突)。
- 協程不能併發運行,協程之間可以共享全局變量(不會存在寫衝突)。
- 一個線程可以有多個協程,進程線程都是同步機制,而協程則是異步。
- 協程能夠保留上一次調用時的狀態,每次過程重入時,就相當於進入上一次調用狀態
一個具有多線程的程序可以同時運行幾個線程,而協同程序卻需要彼此協作地運行。就是說,一個具有多個協同程序的程序在任何時刻只能運行一個協同程序,並且正在運行的協同程序只會在其顯示地掛起時,它的執行纔會暫停。
2.優缺點
-
最大的優勢就是協程極高的執行效率。因爲子程序切換不是線程切換,而是由程序自身控制,因此,沒有線程切換的開銷,和多線程比,線程數量越多,協程的性能優勢就越明顯。
-
第二大優勢就是不需要多線程的鎖機制,因爲只有一個線程,也不存在同時寫變量衝突,在協程中控制共享資源不加鎖,只需要判斷狀態就好了,所以執行效率比多線程高很多。
2.線程間共享變量如何保證不被其他線程改變
類似問法,flask/Django是如何實現不同線程中的request變量的
這裏面用到了ThreadLocal變量,參見:https://selfboot.cn/2016/08/22/threadlocal_overview/
3.redis高併發如何實現
1.redis是基於內存的,內存的讀寫速度非常快;
2.redis是單線程的,省去了很多上下文切換線程的時間;
3.redis使用多路複用技術,可以處理併發的連接。非阻塞IO 內部實現採用epoll,採用了epoll+自己實現的簡單的事件框架。epoll中的讀、寫、關閉、連接都轉化成了事件,然後利用epoll的多路複用特性,絕不在io上浪費一點時間。
參見:https://zhuanlan.zhihu.com/p/58038188
io多路複用:https://www.jianshu.com/p/dfd940e7fca2
4.1000個.log文件查找帶某字符串的linux命令
用grep -rn ‘字符串’ 文件夾路徑
參考:https://blog.csdn.net/BabyFish13/article/details/79709028
5.自己編寫的框架路由map如何實現
6.__new__和__init__區別 聯繫
__new__
和__init__
的區別主要表現在:
它自身的區別;
及在Python中新式類和老式類的定義。
__new__
負責對象的創建而__init__
負責對象的初始化。
__new__
:創建對象時調用,會返回當前對象的一個實例
__init__
:創建完對象後調用,對當前對象的一些實例初始化,無返回值
1. 在類中,如果__new__
和__init__
同時存在,會優先調用__new__
class ClsTest(object):
def __init__(self):
print("init")
def __new__(cls,*args, **kwargs):
print("new")
ClsTest()
輸出:
new
2. 如果__new__返回一個對象的實例,會隱式調用__init__
class ClsTest(object):
def __init__(self):
print ("init")
def __new__(cls,*args, **kwargs):
print ("new %s"%cls)
return object.__new__(cls, *args, **kwargs)
ClsTest()
輸出:
new <class '__main__.ClsTest'>
init
3. __new__方法會返回所構造的對象,__init__則不會。__init__無返回值。
class ClsTest(object):
def __init__(cls):
cls.x = 2
print ("init")
return cls
ClsTest()
輸出
init
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() should return None, not 'ClsTest'
4. 若__new__沒有正確返回當前類cls的實例,那__init__是不會被調用的,即使是父類的實例也不行
class ClsTest1(object):
pass
class ClsTest2(ClsTest1):
def __init__(self):
print ("init")
def __new__(cls,*args, **kwargs):
print ("new %s"%cls)
return object.__new__(ClsTest1, *args, **kwargs)
b=ClsTest2()
print (type(b))
輸出:
new <class '__main__.ClsTest2'>
<class '__main__.ClsTest1'>
5.知識點:
- 繼承自object的新式類纔有__new__
- __new__至少要有一個參數cls,代表要實例化的類,此參數在實例化時由Python解釋器自動提供,__new__必須要有返回值,返回實例化出來的實例,可以return父類__new__出來的實例,或者直接是object的__new__出來的實例
- __init__有一個參數self,就是這個__new__返回的實例,__init__在__new__的基礎上可以完成一些其它初始化的動作,__init__不需要返回值
- 如果__new__返回一個對象的實例,會隱式調用__init__