單例模式:javascript
單例模式是一種經常使用的軟件設計模式。在它的核心結構中只包含一個被稱爲單例類的特殊類。經過單例模式能夠保證系統中一個類只有一個實例並且該實例易於外界訪問,從而方便對實例個數的控制並節約系統資源。若是但願在系統中某個類的對象只能存在一個,單例模式是最好的解決方案。css
__new__()
在__init__()
以前被調用,用於生成實例對象。利用這個方法和類的屬性的特色能夠實現設計模式的單例模式。單例模式是指建立惟一對象,單例模式設計的類只能實例 這個絕對常考啊.絕對要記住1~2個方法,當時面試官是讓手寫的.html
class Borg(object):java
_static ={}python
def __new__(cls,*args,**kwargs):git
ob =super(Borg,cls).__new__(cls,*args,kwargs)github
ob.__dict__ =cls._staticweb
return =ob 面試
幾種常見的單例模式
設計模式
1 使用__new__方法 class Singleton(object): def __new__(cls, *args, **kw): if not hasattr(cls, '_instance'): orig = super(Singleton, cls) cls._instance = orig.__new__(cls, *args, **kw) return cls._instance class MyClass(Singleton): a = 1 2 共享屬性 建立實例時把全部實例的__dict__指向同一個字典,這樣它們具備相同的屬性和方法. class Borg(object): _state = {} def __new__(cls, *args, **kw): ob = super(Borg, cls).__new__(cls, *args, **kw) ob.__dict__ = cls._state return ob class MyClass2(Borg): a = 1 3 裝飾器版本 def singleton(cls): instances = {} def getinstance(*args, **kw): if cls not in instances: instances[cls] = cls(*args, **kw) return instances[cls] return getinstance @singleton class MyClass: ... 4 import方法 做爲python的模塊是自然的單例模式 # mysingleton.py class My_Singleton(object): def foo(self): pass my_singleton = My_Singleton() # to use from mysingleton import my_singleton my_singleton.foo()
閉包:
def func1(m):
def inner(m):
print(m)
return inner
語法糖裝飾器
def warpper(func)
def inner(*args,**kwargs):
re = func(*args,**kwargs)
return re
return inner
調用
@warpper
def 函數(參數)
二分法:
def func(list,num): min =0 # 起始索引 max =len(list)-1 #最大索引 if num in list: while True: center =int((min+max)/2 )# 獲取中間的值 # print(center) if list[center]>num: max=center-1 # elif list[center]<num: min =center+1 elif list[center]==num: print("位置在",center) return list[center] list =[1, 6, 9, 15, 26, 38, 49, 57, 63, 77, 81, 93] func(list,15)
簡述代碼跑出如下異常的緣由是什麼
IndexError 序列中沒有此索引(index)
AttributeError 對象沒有這個屬性
AssertionError 斷言語句失敗
NotImplementedError 還沒有實現的方法
StopIteration 迭代器沒有更多的值
TypeError 對類型無效的操做
IndentationError 縮進錯誤
簡述你對GIL的理解
GIL的全稱是Global Interpreter Lock(全局解釋器鎖),來源是python設計之初的考慮,爲了數據安全所作的決定。 每一個CPU在同一時間只能執行一個線程 在單核CPU下的多線程其實都只是併發,不是並行,併發和並行從宏觀上來說都是同時處理多路請求的概念。 但併發和並行又有區別,並行是指兩個或者多個事件在同一時刻發生;而併發是指兩個或多個事件在同一時間間隔內發生。 在Python多線程下,每一個線程的執行方式: 1、獲取GIL 2、執行代碼直到sleep或者是python虛擬機將其掛起。 3、釋放GIL 可見,某個線程想要執行,必須先拿到GIL,咱們能夠把GIL看做是「通行證」,而且在一個python進程中,GIL只有一個。 拿不到通行證的線程,就不容許進入CPU執行。 在Python2.x裏,GIL的釋放邏輯是當前線程碰見IO操做或者ticks計數達到100(ticks能夠看做是Python自身的一個計數器, 專門作用於GIL,每次釋放後歸零,這個計數能夠經過 sys.setcheckinterval 來調整),進行釋放。 而每次釋放GIL鎖,線程進行鎖競爭、切換線程,會消耗資源。而且因爲GIL鎖存在, python裏一個進程永遠只能同時執行一個線程(拿到GIL的線程才能執行)。 IO密集型代碼(文件處理、網絡爬蟲等),多線程可以有效提高效率(單線程下有IO操做會進行IO等待, 形成沒必要要的時間浪費,而開啓多線程能在線程A等待時,自動切換到線程B, 能夠不浪費CPU的資源,從而能提高程序執行效率),因此多線程對IO密集型代碼比較友好。 更多參考資料: http://cenalulu.github.io/python/gil-in-python
copy和deepcopy的區別是什麼
—–咱們尋常意義的複製就是深複製,即將被複制對象徹底再複製一遍做爲獨立的新個體單獨存在。因此改變原有被複制對象不會對已經複製出來的新對象產生影響。 —–而淺複製並不會產生一個獨立的對象單獨存在,他只是將原有的數據塊打上一個新標籤,因此當其中一個標籤被改變的時候,數據塊就會發生變化,另外一個標籤也會隨之改變。這就和咱們尋常意義上的複製有所不一樣了。 對於簡單的 object,用 shallow copy 和 deep copy 沒區別 複雜的 object, 如 list 中套着 list 的狀況,shallow copy 中的 子list,並未從原 object 真的「獨立」出來。也就是說,若是你改變原 object 的子 list 中的一個元素,你的 copy 就會跟着一塊兒變。這跟咱們直覺上對「複製」的理解不一樣。 代碼解釋
簡述多線程、多進程、協程之間的區別與聯繫
概念:
進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,
進程是系統進行資源分配和調度的一個獨立單位。每一個進程都有本身的獨立內存空間,
不一樣進程經過進程間通訊來通訊。因爲進程比較重量,佔據獨立的內存,
因此上下文進程間的切換開銷(棧、寄存器、虛擬內存、文件句柄等)比較大,但相對比較穩定安全。
線程是進程的一個實體,是CPU調度和分派的基本單位,
它是比進程更小的能獨立運行的基本單位.
線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),
可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源。
線程間通訊主要經過共享內存,上下文切換很快,資源開銷較少,但相比進程不夠穩定容易丟失數據。
協程是一種用戶態的輕量級線程,協程的調度徹底由用戶控制。
協程擁有本身的寄存器上下文和棧。
協程調度切換時,將寄存器上下文和棧保存到其餘地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,
直接操做棧則基本沒有內核切換的開銷,能夠不加鎖的訪問全局變量,因此上下文的切換很是快。
線程是指進程內的一個執行單元,也是進程內的可調度實體。線程與進程的區別:
1) 地址空間:線程是進程內的一個執行單元,進程內至少有一個線程,它們共享進程的地址空間,
而進程有本身獨立的地址空間
2) 資源擁有:進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源
3) 線程是處理器調度的基本單位,但進程不是
4) 兩者都可併發執行
5) 每一個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口,
可是線程不可以獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制
1) 一個線程能夠多個協程,一個進程也能夠單獨擁有多個協程,這樣python中則能使用多核CPU。
2) 線程進程都是同步機制,而協程則是異步
3) 協程能保留上一次調用時的狀態,每次過程重入時,就至關於進入上一次調用的狀態
在函數定義中使用args和*kwargs傳遞可變長參數
*args用來將參數打包成tuple給函數體調用
**kwargs 打包關鍵字參數成dict給函數體調用
做用: 瀏覽器端能夠接受的媒體類型,
例如: Accept: text/html 表明瀏覽器能夠接受服務器回發的類型爲 text/html 也就是咱們常說的html文檔,
若是服務器沒法返回text/html類型的數據,服務器應該返回一個406錯誤(non acceptable)
通配符 * 表明任意類型
例如 Accept: / 表明瀏覽器能夠處理全部類型,(通常瀏覽器發給服務器都是發這個)
做用: 瀏覽器申明本身接收的編碼方法,一般指定壓縮方法,是否支持壓縮,支持什麼壓縮方法(gzip,deflate),(注意:這不是隻字符編碼);
例如: Accept-Encoding: zh-CN,zh;q=0.8
做用: 瀏覽器申明本身接收的語言。
語言跟字符集的區別:中文是語言,中文有多種字符集,好比big5,gb2312,gbk等等;
例如: Accept-Language: en-us
例如: Connection: keep-alive 當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP鏈接不會關閉,若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接
例如: Connection: close 表明一個Request完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP鏈接會關閉, 當客戶端再次發送Request,須要從新創建TCP鏈接。
做用: 請求報頭域主要用於指定被請求資源的Internet主機和端口號,它一般從HTTP URL中提取出來的
例如: 咱們在瀏覽器中輸入:http://www.hzau.edu.cn
瀏覽器發送的請求消息中,就會包含Host請求報頭域,以下:
Host:www.hzau.edu.cn
此處使用缺省端口號80,若指定了端口號,則變成:Host:指定端口號
當瀏覽器向web服務器發送請求的時候,通常會帶上Referer,告訴服務器我是從哪一個頁面連接過來的,服務器籍此能夠得到一些信息用於處理。好比從我主頁上連接到一個朋友那裏,他的服務器就可以從HTTP Referer中統計出天天有多少用戶點擊我主頁上的連接訪問他的網站。可用於防盜鏈
做用:告訴HTTP服務器, 客戶端使用的操做系統和瀏覽器的名稱和版本.
咱們上網登錄論壇的時候,每每會看到一些歡迎信息,其中列出了你的操做系統的名稱和版本,你所使用的瀏覽器的名稱和版本,這每每讓不少人感到很神奇,實際上,服務器應用程序就是從User-Agent這個請求報頭域中獲取到這些信息User-Agent請求報頭域容許客戶端將它的操做系統、瀏覽器和其它屬性告訴服務器。
例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)
更多參考資料:https://blog.csdn.net/u014175572/article/details/54861813
cookie數據存放在客戶的瀏覽器上,session數據放在服務器上
cookie不是很安全,別人能夠分析存放在本地的COOKIE並進行COOKIE欺騙考慮到安全應當使用session。
session會在必定時間內保存在服務器上。當訪問增多,會比較佔用服務器的性能考慮到減輕服務器性能方面,應當使用COOKIE。
單個cookie保存的數據不能超過4K,不少瀏覽器都限制一個站點最多保存20個cookie。
建議:
將登錄信息等重要信息存放爲SESSION
其餘信息若是須要保留,能夠放在COOKIE中
同源策略是瀏覽器上爲安全性考慮實施的很是重要的安全策略。何謂同源:URL由協議、域名、端口和路徑組成,若是兩個URL的協議、域名和端口相同,則表示他們同源。同源策略:瀏覽器的同源策略,限制了來自不一樣源的"document"或腳本,對當前"document"讀取或設置某些屬性。從一個域上加載的腳本不容許訪問另一個域的文檔屬性。舉個例子:好比一個惡意網站的頁面經過iframe嵌入了銀行的登陸頁面(兩者不一樣源),若是沒有同源限制,惡意網頁上的javascript腳本就能夠在用戶登陸銀行的時候獲取用戶名和密碼。在瀏覽器中<script>、<img>、<iframe>、<link>等標籤均可以加載跨域資源,而不受同源限制,但瀏覽器限制了JavaScript的權限使其不能讀、寫加載的內容。另外同源策略只對網頁的HTML文檔作了限制,對加載的其餘靜態資源如javascript、css、圖片等仍然認爲屬於同源。