目錄
歡迎前往GitHub貢獻自己的問題和答案
前往有道雲瀏覽(推薦)
前往CSDN瀏覽
文章目錄
- 目錄
- Python模塊
- 01.python中有哪些可變類型與不可變類型
- 02.棧和堆的區別是什麼
- 03.簡述數組,鏈表,隊列,堆棧的區別
- 04.深拷貝和淺拷貝的區別是什麼
- 05.面向對象的3個特性是什麼
- 06.什麼是閉包
- 07.匿名函數/函數/閉包/對象在做實參時有什麼區別
- 08.簡述什麼是進程、線程、協程
- 09.簡述進程、線程、協程三者的區別
- 10.簡述進程、線程、協程適用於那種應用場景類型
- 11.協程爲何比線程還快
- 12.什麼是迭代器,爲什麼要使用它
- 13.什麼是生成器,爲什麼要使用它
- 14.簡述迭代器、生成器的區別
- 15.什麼是裝飾器,爲什麼要使用它
- 16.什麼是線程安全
- 17.標準庫有哪些線程安全的隊列
- 18.什麼是GIL
- 19.什麼時候釋放GIL鎖
- 20.互斥鎖與GIL的區別
- 21.python高併發解決方案有哪些
- 22.談談對不定⻓參數的理解
- 23.談談對缺省參數的理解
- 24.break和continue的區別
- 25.`is` 和 `==`的區別
- 26.`__new__()` 和 `__init__()`的區別
- 27.`range`和`xrange`的區別
- 28. `yield`和`return`的相同點和區別
- 29.列舉5個python常用標準庫並說明其作用
- 30.談談你知道的幾種設計模式
- 31.Python2和Python3的區別
- Linux模塊
- HTTP模塊
- 01.HTTP是什麼
- 02.HTTP請求報文與響應報文格式
- 03.HTTP常見首部字段有哪些
- 04.HTTP與HTTPS的區別
- 05.列舉HTTP請求中常見的請求方式
- 06.GET方法與POST方法的區別
- 07.常見的HTTP相應狀態碼
- 08.如何對HTTP進行優化
- 09.TCP與UDP的區別
- 10.請介紹TCP的3次握手和4次揮手流程
- 11.爲什麼TCP連接的時候是3次握手,關閉的時候卻是4次握手?
- 12.TCP爲什麼會分包和粘包
- 13.HTTP和websocket的區別
- 14.HTTP的長連接與websocket的持久連接的區別
- 15.什麼是cookie?其特點和應用場景有哪些?其如何獲取、設置?
- 16.什麼是session?其特點和應用場景有哪些?其如何設置、獲取、清空?
- 17.session和cookie的相同點和區別
- 18.什麼是JWT,有什麼特點
- 19.簡述JWT的工作原理
- 20.傳統Session方式存儲ID和JWT的區別
- Django模塊
- 框架層
- 01.什麼是Django框架?
- 02.Django對web開發有哪些優勢
- 03.簡述Django項目的組成模塊
- 04.簡述MVC模式和MVT模式
- 05.簡述Django請求生命週期
- 07.什麼是WSGI
- 08.uwsgi、uWSGI和WSGI的區別
- 09.Django的HttpRequest對象是在什麼時候創建的?
- 10.什麼是中間件並簡述其作用
- 11.列舉django中間件的5個方法,以及django中間件的應用場景
- 12.簡述Django對http請求的執行流程
- 13.Django中session的運行機制是什麼
- 14. 什麼是CSRF,請描述其攻擊原理,在Django中如何解決
- 15. Django中CSRF的實現機制
- 16.什麼是跨域請求,其有哪些方式
- 17.跨域請求Django是如何處理的
- 16.什麼是信號量
- 17.web框架的本質是什麼
- 18.談談你對restful規範的認識
- 19.Django中如何加載初始化數據
- 20.Django緩存系統類型有哪些
- 21.請簡述Django下的(內建)緩存機制
- 22.什麼是ASGI,簡述WSGI和ASGI的關係與區別
- 23.Django如何實現websocket
- 25.列舉django的核心組件
- 26.Django本身提供了runserver,爲什麼不能用來部署
- 27.ajax請求的csrf解決方法
- 路由層
- 01.路由優先匹配原則是什麼
- 02.urlpatterns中的name與namespace的區別
- 03.Django路由系統中include是幹嘛用的?
- 04.Django2.x中的path與django1.x裏面的URL有什麼區別
- 05.Django重定向的幾種方法,用的什麼狀態碼
- 模型層
- 01.命令migrate 和makemigrations的差別
- 02.Django的Model的繼承有幾種形式
- 03.class Meta中的元信息字段有哪些
- 04.Django模型類關係有哪幾種
- 05.外鍵有什麼用,什麼時候合適使用外接,外鍵一定需要索引嗎?
- 06.`Primary Key`和`Unique Key`的區別
- 07.DateTimeField類型中的`auto_now`與`auto_now_add`有什麼區別
- 08.當刪除一個外鍵的時候,其關聯的表有幾種處理方式
- 09.如何通過外鍵,子表查詢父表和父表查詢子表
- 10.談談 GenericForeignkey 和 GenericRelation
- 11.django中怎麼寫原生SQL
- 12.談一談你對ORM的理解
- 13.如何使用Django ORM批量創建數據
- 14.列舉django ORM中操作QuerySet對象的方法(至少5個)
- 15.ORM如何取消級聯
- 16.查詢集的2大特性?什麼是惰性執行
- 17.查詢集返回的列表過濾器有哪些
- 18.selected_related與prefetch_related有什麼區別
- 19.values()與values_list()有什麼區別
- 20.QueryDict和dict區別
- 21.Django中查詢Q和F的區別
- 視圖層
- 高階
- 數據庫模塊
- MySQL
- 01.NoSQL和SQL數據庫之間有什麼不同?
- 02.MySQL支持哪些存儲引擎?
- 03.InnoDB和MyISAM有什麼區別?
- 04.數據表類型有哪些
- 05.簡單描述mysql中,索引,主鍵,唯一索引,聯合索引的區別,對數據庫的性能有什麼影響(從讀寫兩方面)
- 06.主鍵、外鍵和索引的區別
- 07.索引的底層實現原理
- 08.建立索引有什麼原則
- 09.索引的優點和缺點是什麼
- 10.什麼情況下不宜建立索引
- 11.什麼是事務,其有哪些特性
- 12.事務有哪些隔離級別
- 13.Mysql中的事務回滾機制概述
- 14.SQL注入的主要特點
- 15.SQL語言包括哪幾部分?每部分都有哪些操作關鍵字?
- 16.完整性約束包括哪些?
- 17.什麼是鎖?
- 18.什麼叫視圖?遊標是什麼?
- 19.NULL是什麼意思
- 20.SQL語句中‘相關子查詢’與‘非相關子查詢’有什麼區別
- 21.char和varchar的區別
- 22.談談三個範式
- 23.如何進行SQL優化
- 24.說說對SQL語句優化有哪些方法
- 25.實踐中如何優化MySQL
- 26.如何設計一個高併發的系統
- 27.鎖的優化策略
- 28.MySQL數據庫作發佈系統的存儲,一天五萬條以上的增量,預計運維三年,怎麼優化
- 29.對於大流量的網站,您採用什麼樣的方法來解決各頁面訪問量統計問題
- 30.主鍵使用自增ID還是UUID?
- 31.超大分頁怎麼處理?
- 32.關心過業務系統裏面的sql耗時嗎?統計過慢查詢嗎?對慢查詢都怎麼優化過?
- 33.Modelfirst和DBfirst區別
- Redis模塊
- 01. 什麼是Redis?
- 02. Redis相比memcached有哪些優勢?
- 03. Redis支持哪幾種數據類型?
- 04. Redis主要消耗什麼物理資源?
- 05. Redis的全稱是什麼?
- 06. Redis有哪幾種數據淘汰策略?
- 07. Redis官方爲什麼不提供Windows版本?
- 08. 一個字符串類型的值能存儲最大容量是多少?
- 09. 爲什麼Redis需要把所有數據放到內存中?
- 10. Redis集羣方案應該怎麼做?都有哪些方案?
- 11. Redis集羣方案什麼情況下會導致整個集羣不可用?
- 12. MySQL裏有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據?
- 13. Redis有哪些適合的場景?
- 14.Redis爲什麼快?除了他是內存型數據庫外,還有什麼原因
- 15. Redis和Redisson有什麼關係?
- 16. Redis與Redisson對比有什麼優缺點?
- 17. Redis如何設置密碼及驗證密碼?
- 18. 說說Redis哈希槽的概念?
- 19. Redis集羣的主從複製模型是怎樣的?
- 20. Redis集羣會有寫操作丟失嗎?爲什麼?
- 21. Redis集羣之間是如何複製的?
- 22. Redis集羣最大節點個數是多少?
- 23. Redis集羣如何選擇數據庫?
- 24. 怎麼測試Redis的連通性?
- 25. Redis中的管道有什麼用?
- 26. 怎麼理解Redis事務?
- 27. Redis事務相關的命令有哪幾個?
- 28. Redis key的過期時間和永久有效分別怎麼設置?
- 29. Redis如何做內存優化?
- 30. Redis回收進程如何工作的?
- 31. Redis回收使用的是什麼算法?
- 32. Redis如何做大量數據插入?
- 33. 爲什麼要做Redis分區?
- 34. 你知道有哪些Redis分區實現方案?
- 35. Redis分區有什麼缺點?
- 36. Redis持久化數據和緩存怎麼做擴容?
- 37. 分佈式Redis是前期做還是後期規模上來了再做好?爲什麼?
- 38. Twemproxy是什麼?
- 39. 支持一致性哈希的客戶端有哪些?
- 40. Redis與其他key-value存儲有什麼不同?
- 41. Redis的內存佔用情況怎麼樣?
- 42. 都有哪些辦法可以降低Redis的內存使用情況呢?
- 43. 查看Redis使用情況及狀態信息用什麼命令?
- 44. Redis的內存用完了會發生什麼?
- 45. Redis是單線程的,如何提高多核CPU的利用率?
- 46. 一個Redis實例最多能存放多少的keys?List、Set、Sorted Set他們最多能存放多少元素?
- 47. Redis常見性能問題和解決方案?
- 48. Redis提供了哪幾種持久化方式?
- 49. 如何選擇合適的持久化方式?
- 50. 修改配置不重啓Redis會實時生效嗎?
- 部署模塊
- 常用算法模塊
- 其他模塊
- 雲服務模塊
Python模塊
01.python中有哪些可變類型與不可變類型
初級
Python
- 可變類型:會在原來的內存地址上修改元素 比如: 列表,字典
- 不可變類型:不會在原來的內存地址上修改元素,而是指向了新的內存引用 比如:整型,字符串,元組
02.棧和堆的區別是什麼
初級
Python
- 申請方式的不同。棧由系統自動分配,而堆是人爲申請開闢;
- 申請大小的不同。棧獲得的空間較小,而堆獲得的空間較大;
- 申請效率的不同。棧速度較快,堆速度比較慢;
- 底層不同。棧是連續的空間,堆是不連續的空間,是一棵完全二叉樹。
- 存儲內容的不同。棧在函數調用時,第一個進棧的是主函數中的下一條指令的地址,然後是函數的各個參數, 在大多數C編譯器中,參數是由右向左入棧的,然後是函數中的局部變量,注意靜態變量是不入棧的, 靜態變量存儲在靜態存儲區。當本次函數調用結束後,局部變量先出棧,然後是參數,最後棧頂指針指向最開始存的地址,也就是主函數中的下一條指令,程序由該點繼續運行;堆一般是在堆的頭部用一個字節存放堆的大小。堆中的具體內容由程序員安排。
03.簡述數組,鏈表,隊列,堆棧的區別
初級
Python
數組和鏈表是存儲方式的概念,數組在連續的空間中存儲數據,鏈表在非連續的空間中存儲數據;
隊列和堆棧是描述數據存取方法的概念,隊列是先進先出,而堆棧是後進後出,隊列和堆棧可以用鏈表來實現,也可以用數組來實現
04.深拷貝和淺拷貝的區別是什麼
高級
Python
首先深拷貝和淺拷貝都是對象的拷貝,都會生成一個看起來相同的對象,他們本質的區別是拷貝出來的對象的地址是否和原對象一樣,也就是地址的複製還是值的複製的區別。
- 淺拷貝是對一個對象父級(外層)的拷貝,並不會拷貝子級(內部)
使用淺拷貝的時候,分爲兩種情況:
- 如果最外層的數據類型是可變的,比如說列表,字典等,淺拷貝會開啓新的地址空間去存放。
- 如果最外層的數據類型是不可變的,比如元組,字符串等,淺拷貝對象的時候,還是引用對象的地址空間。
- 深拷貝對一個對象是所有層次的拷貝(遞歸),內部和外部都會被拷貝過來。
深拷貝也分兩種情況:
- 最外層數據類型可變。這個時候,內部和外部的都會拷貝過來。
- 外層數據類型不可變,如果裏面是可變數據類型,會新開闢地址空間存放。如果內部數據類型不可變,纔會如同淺拷貝一樣,是對地址的引用。
05.面向對象的3個特性是什麼
初級
Python
- 封裝:根據職責將屬性和方法封裝到一個抽象的類中定義類的準則
- 繼承:實現代碼的重用,相同的代碼不需要重複的編寫
- 多態:不同的子類調用相同的父類,產生不同的結果
06.什麼是閉包
高級
Python
閉包是由兩個函數嵌套定義,內部函數裏面用到了外部函數裏面的變量值,那麼這個變量(變量值)加上內部還是裏面的代碼組成的代碼塊,組成了一個新的內存空間,我們把這個空間叫做閉包。
閉包 = 函數+環境變量(在函數定義的時候定義,它不是全局變量,這個環境變量一定要被內部函數調用纔算是閉包)
07.匿名函數/函數/閉包/對象在做實參時有什麼區別
高級
Python
- 匿名函數:能夠完成基本的簡單功能,傳遞是這個函數的引用,只有功能
- 普通函數:能夠完成比較普通的功能,傳遞是這個函數的引用,只有功能
- 閉包:能夠完成比較複雜的功能,傳遞是這個閉包中的函數和數據,因此傳遞是功能+數據
- 對象:能夠完成最爲複雜的功能,傳遞是很多數據和很對功能,因此傳遞是功能+數據
08.簡述什麼是進程、線程、協程
高級
Python
- 進程是系統進行資源分配和調度的一個獨立單位,一個程序至少有一個進程,一個進程至少有一個線程。
- 線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。線程不能夠獨立執行,必須依存在進程中
- 協程是一種比線程更加輕量級的存在,一個線程也可以擁有多個協程。
09.簡述進程、線程、協程三者的區別
高級
Python
- 進程切換需要的資源很大,效率相對低
- 線程切換需要的資源一般,效率比進程高
- 協程切換任務資源很小,三者中效率最高
- 多進程、多線程根據CPU核數不一樣可能是並行,但是協程是在一個線程中所以是併發。
10.簡述進程、線程、協程適用於那種應用場景類型
高級
Python
- 計算密集型:用進程
- IO密集型:用線程或協程
11.協程爲何比線程還快
高級
Python
高併發+高擴展性+低成本:一個CPU支持上萬的協程都不是問題。所以很適合用於高併發處理協程能保留上一次調用時的狀態,不管是進程還是線程,每次阻塞、切換都需要陷入系統調用,使用線程時需要非常小心地處理同步問題,而協程完全不存在這個問題。
12.什麼是迭代器,爲什麼要使用它
高級
Python
可以被next()函數調用並不斷返回下一個值的對象稱爲迭代器:Iterator
from collections import Iterator
def Iteror2():
'''迭代器原理'''
list = [1, 2, 3, 4]
it = iter(list) # 創建迭代器
while True:
try:
print(next(it))
except StopIteration:
sys.exit()
# 判斷是否爲迭代器
isinstance((x for x in range(10)), Iterator)
#>>> True
迭代是訪問集合元素的一種方式。
迭代器保存的是獲取數據的方式而不是結果,所以想用的時候就可以生成,節省大量內存空間,它是一個可以記住遍歷的位置的對象。
迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。
迭代器有兩個基本的方法:iter() 和 next()。
字符串,列表或元組對象都可用於創建迭代器。
13.什麼是生成器,爲什麼要使用它
高級
Python
生成器定義在Python中,一邊循環一邊計算的機制,使用了 yield 的函數被稱爲生成器(generator)。
跟普通函數不同的是,生成器是一個返回迭代器的函數,只能用於迭代操作,更簡單點理解生成器就是一個特殊的迭代器。
在調用生成器運行的過程中,每次遇到 yield 時函數會暫停並保存當前所有的運行信息,
返回 yield 的值, 並在下一次執行 next() 方法時從當前位置繼續運行。
調用一個生成器函數,返回的是一個迭代器對象。
list5 = [x for x in range(5)]
print(list5) #output:[0, 1, 2, 3, 4]
列表所有數據都在內存中,如果有海量數據的話將會非常耗內存。如僅需要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。如果列表元素按照某種算法推算出來,那我們就可以在循環的過程中不斷推算出後續的元素,這樣就不必創建完整的list,從而節省大量的內存空間。
簡單一句話:我又想要得到龐大的數據,又想讓它佔用內存空間少,那就用生成器! 生成器僅僅保存了一套生成數值的算法,並且沒有讓這個算法現在就開始執行,而是我什麼時候調它,它什麼時候開始計算一個新的值,並給你返回。
14.簡述迭代器、生成器的區別
高級
Python
能使用for遍歷的就叫可迭代對象,能使用next方法的就是迭代器,生成器是特殊的迭代器。生成器能做到迭代器能做的所有事,而且因爲自動創建了 iter()和 next()方法,生成器顯得特別簡潔和高效,使用生成器表達式取代列表解析可以同時節省內存空間。
15.什麼是裝飾器,爲什麼要使用它
高級
Python
- 裝飾器本質上是一個函數,這個函數的主要作用是包裝另一個函數或類
包裝的- 目的是在不改變原函數名的情況下改變被包裝對象的行爲。 - 接收一個函數,內部對其包裝,然後返回一個新函數,這樣子動態的增強函數功能
- 通過高階函數傳遞函數參數,新函數添加舊函數的需求,然後執行舊函數。
在django中middkeware中間件 其實就是高級的裝飾器用法。
16.什麼是線程安全
高級
Python
線程安全:就是對於多線程同時操作是是安全的而不會發生寫衝突,比如python的Queue
非線程安全:就是多線成同時操作時會發生寫衝突,比如python的list,set,dict
返回目錄
17.標準庫有哪些線程安全的隊列
高級
Python
Python Queue模塊有三種隊列:
- FIFO隊列先進先出.(線程安全)
- LifoQueue類似於堆,即先進後出(線程安全)
- PriorityQueue優先級隊列,級別越低,越先出來(線程安全)
對應的構造函數:
- class Queue.Queue(maxsize) FIFO
- class Queue.LifoQueue(maxsize) LIFO
- class Queue.PriorityQueue(maxsize) 優先級隊列
18.什麼是GIL
高級
Python
GIL是python中的全局解釋器鎖,是不可控的,同一個進程中,假如有多個線程在運行,那麼其中一個線程在運行的時候就會霸佔GIL鎖,就使得其他線程無法運行,等該線程運行結束以後,其他線程才能運行。如果線程中遇到耗時操作(I/O密集型任務),則解釋器鎖會解開,使得其他線程運行,所以說在多線程中,線程的運行仍是有先後順序的,並不是同時進行。
返回目錄
19.什麼時候釋放GIL鎖
高級
Python
- 時間片耗盡(cpu時間)
- 任務遇到I/O等待時
- 執行任務結束
- 執行到字節碼閾值時
20.互斥鎖與GIL的區別
高級
Python
互斥鎖是在多線程的情況下,確保當前線程執行完成後,再執行下一個任務,當前任務沒有結束,下個任務會阻塞。
GIL是保證同一時間只有1個線程在執行,但是該線程讓出GIL的時,有可能並沒完成該線程的任務,該線程的任務分多少次執行完成這個會安裝GIL的默認策略。
21.python高併發解決方案有哪些
高級
Python
- gevent
代碼看起來好看一些,但是維護比較差,patch沒有規律,而且裏面封裝了C,對python3的支持最差. - twisted
穩定性是最好的,但是需要較長時間的學習.對python3的支持較差. - tornado
兼容性最好.但是過於簡單了,功能不強,另外沒有python數據庫適配器能和tornado無縫對接,因此調用數據庫很麻煩,而且只支持web.
22.談談對不定⻓參數的理解
初級
Python
一般分爲兩種:
- 一種是args 位置參數 在定義函數時,在形參前面加一個,代表可以接收任意多個實參,用元組類型保存所有數據。一般寫成def function(*args)
- 一種是**kwargs 命名參數 代表可以接收任意多個的命名參數,用字典類型保存。
23.談談對缺省參數的理解
初級
Python
如果調用函數的時候,傳遞了對應位置的實參,那就使用這個傳遞的值,如果沒有傳遞對應的值,那就使用缺省參數的值。
24.break和continue的區別
初級
Python
- break和continue都是用於while嵌套循環中
- continue是結束內層的while循環,但並沒有終止整個循環
- break是結束整個while循環
25.is
和 ==
的區別
高級
Python
- “==”僅判斷A和B的值是否相等
- is 不僅是會判斷A和B的值是否相等,還會判斷A和B的id是否一致
26.__new__()
和 __init__()
的區別
高級
Python
_new_作用於_init_之前。前者可以決定是否調用後者,可以決定調用哪個類的_init_方法。
27.range
和xrange
的區別
初級
Python
xrange和range 的用法完全相同,但是xrange返回的是一個生成器。
返回目錄
28. yield
和return
的相同點和區別
高級
Python
- 相同點:功能都是返回程序執行結果
- 區別:yield返回執行結果並不中斷程序執行,return在返回執行結果的同時中斷程序執行。
29.列舉5個python常用標準庫並說明其作用
初級
Python
- os:提供不少於操作系統相關聯的函數
- sys:通常用於命令行參數
- datetime:日期時間
- re:正則匹配
- math:數學運算
30.談談你知道的幾種設計模式
高級
Python
- 單例模式:保證一個類僅有一個實例,並提供一個訪問他的全局訪問點,例如框架中的數據庫連接
- 裝飾器模式:不修改元類代碼和繼承的情況下動態擴展類的功能,例如框架中的每個controller文件會提供before和after方法。
- 迭代器模式: 提供一個方法順序訪問一個聚合對象中各個元素,在PHP中將繼承 Iterator 類
- 命令模式: 將”請求”封閉成對象, 以便使用不同的請求,隊列或者日誌來參數化其他對象. 命令模式也支持可撤銷的操作.
31.Python2和Python3的區別
- python解釋器默認編碼
python2 解釋器默認編碼:ascii
python3 解釋器默認編碼:utf-8
- 輸入
python2:name=raw_input(‘請輸入姓名’)
python3:name=input(‘請輸入你的姓名’)
- 輸出
python2:print “你好”
python3:print(“你好”)
- 數字表示
python2 64位機器,範圍-263~263-1 超出上述範圍,python自動轉化爲long(長整型) 注:long(長整型)數字末尾有一個L
python3 所有整型都是int,沒有long(長整型)
5.整型除法
python2:只能保留整數位
python3:可以保留所有內容
- range / xrange
python2:
xrange:不會在內存中立即創建,而是在循環時,邊循環邊創建
range:在內存立即把所有的值創建
python3:
只有range,相當於python2中的xrange
range:不會在內存中立即創建,而是在循環時,邊循環邊創建
- 包的定義
python2:文件夾中必須有_ _ init _ .py文件
python3:不需要有 _ init _ _.py文件
- 字典的keys / values / items方法
python2:返回列表,通過索引可以取值
python3:返回迭代器,只能通過循環取值,不能通過索引取值
- map / filter
python2:返回列表,直接創建值,可以通過索引取值
python3:返回迭代器,不直接創建值,通過循環,邊循環邊創建
- str(字符串類型)的區別(最大區別,優先寫這個)
python2:
str類型,相當於python3中的字節類型,utf-8/gbk等其他編碼
unicode類型,相當於python3中的字符串類型,unicode編碼
python2中沒有字節類型
python3:
str類型,字符串類型,unicode編碼
python3中沒有unicode類型
- 繼承object
class Foo:
pass
class Foo(object):
pass
# 在python3中這倆的寫法是一樣,因爲所有的類默認都會繼承object類,全部都是新式類。
# 如果在python2中這樣定義,則稱其爲:經典類
class Foo:
pass
# 如果在python2中這樣定義,則稱其爲:新式類
class Foo(object):
pass
# 新式類
# 繼承object
# 支持super
# 多繼承 廣度優先C3算法
# mro方法
# 經典類
# py2中不繼承object
# 沒有super語法
# 多繼承 深度優先
# 沒有mro方法
Linux模塊
01.列舉10個常見的Linux命令
初級
Linux
cd pwd touch ls mkdir rm help sudo ssh date clear vim ps cat more scp cp find mv grep echo
HTTP模塊
01.HTTP是什麼
初級
HTTP
- HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。
- HTTP協議是一個基於TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。
- HTTP協議是一個屬於應用層的面向對象的協議。
- HTTP協議工作於客戶端和服務端架構上。瀏覽器作爲HTTP客戶端通過URL向HTTP服務器發送請求,服務器根據接收到的請求後,向客戶端發送響應信息,
-
基於TCP/IP
雙方建立通信的順序,以及Web頁面顯示需要 處理的步驟,等等。像這樣把與互聯網相關聯的協議集合起來總稱爲 TCP/IP。而HTTP協議是基於TCP/IP協議之上的應用層協議。
-
基於請求-響應模式
HTTP協議規定,請求從客戶端發出,最後服務器響應該請求並返回
-
無狀態保存
HTTP是一種無狀態協議。HTTP協議不對請求和響應之間的通信狀態進行保存,不做持久化處理。這是爲了更快地處理大量事務,確保協議的可伸縮性,而特意把HTTP協議設計成 如此簡單的。
可是,隨着Web的不斷髮展,因無狀態而導致業務處理變得棘手的情況增多了。比如,用戶登錄到一家購物網站,即使他跳轉到該站的 其他頁面後,也需要能繼續保持登錄狀態。
針對這個實例,網站爲了能夠掌握是誰送出的請求,需要保存用戶的狀態。HTTP/1.1雖然是無狀態協議,但爲了實現期望的保持狀態功能, 於是引入了Cookie技術。有了Cookie再用HTTP協議通信,就可以管 理狀態了。
02.HTTP請求報文與響應報文格式
初級
HTTP
- 請求報文包含三部分:
- 請求行(包含請求方法、URL、HTTP版本)
- 請求首部字段
- 請求內容實體
- 響應報文包含三部分:
- 狀態行(包含狀態碼、狀態碼的原因短語、HTTP版本)
- 響應首部字段
- 響應內容實體
03.HTTP常見首部字段有哪些
初級
HTTP
- 通用首部字段(請求報文與響應報文都會使用的首部字段)
字段 | 字段描述 |
---|---|
Date | 創建報文時間 |
Connection | 連接的管理 |
Cache-Control | 緩存的控制 |
Transfer-Encoding | 報文主體的傳輸編碼方式 |
- 請求首部字段(請求報文會使用的首部字段)
字段 | 字段描述 |
---|---|
Host | 請求資源所在服務器 |
Accept | 可處理的媒體類型 |
Accept-Charset | 可接收的字符集 |
Accept-Encoding | 可接受的內容編碼 |
Accept-Language | 可接受的自然語言 |
- 響應首部字段(響應報文會使用的首部字段)
字段 | 字段描述 |
---|---|
Accept-Ranges | 可接受的字節範圍 |
Location | 令客戶端重新定向到的URI |
Server | HTTP服務器的安裝信息 |
- 實體首部字段(請求報文與響應報文的實體部分使用的首部字段)
字段 | 字段描述 |
---|---|
Allow | 資源可支持的HTTP方法 |
Content-Type | 實體主類的類型 |
Content-Encoding | 實體主體適用的編碼方式 |
Content-Language | 實體主體的自然語言 |
Content-Length | 實體主體的的字節數 |
Content-Range | 實體主體的位置範圍,一般用於發出部分請求時使用 |
04.HTTP與HTTPS的區別
初級
HTTP
HTTPS
- HTTP協議傳輸的數據都是明文、未加密的。因此使用HTTP協議傳輸隱私信息非常不安全。
- HTTPS協議是由HTTP+SSL構建的網絡協議,可進行加密傳輸、身份認證,要比HTTP協議安全。
不同點 | HTTP | HTTPS |
---|---|---|
安全證書 | 不需要 | 需要到ca申請證書(免費/付費可選) |
是否加密 | 不加密,信息是明文傳輸 | 具有安全性的ssl加密傳輸協議 |
驗證數據 | 不驗證數據,可能遭到僞裝 無法驗證報文完整性,可能被篡改 |
驗證數據且對數據完整性保護 |
連接方式 | 無狀態連接 | HTTPS協議是由HTTP+SSL協議構建的 可進行加密傳輸、身份認證的網絡協議,比HTTP協議安全。 |
默認端口 | 80 | 443 |
安全性 | 不安全 | 安全 |
05.列舉HTTP請求中常見的請求方式
初級
HTTP
方法名稱 | 定義 |
---|---|
GET | 向特定的路徑資源發出請求 |
POST | 向指定路徑資源提交數據進行處理請求(一般用於提交表單或者上傳文件) |
PUT | 從客戶端向服務器傳送數據更新指定的資源 |
PATCH | 從客戶端向服務器傳送數據更新部分指定的資源 |
DELETE | 請求服務器刪除指定的資源 |
HEAD | 向服務器索要與GET一樣的請求,但是不返回返回體。 這個方法可以在不必傳輸整個響應內容的情況下,獲取包含在響應消息頭中的元信息 |
OPTIONS | 查詢相應URL支持的HTTP方法 |
TRACE | 返回服務器收到的請求,主要用於測試或診斷 |
CONNECT | HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務 |
06.GET方法與POST方法的區別
初級
HTTP
不同點 | GET | POST |
---|---|---|
本質 | 產生1個TCP數據包,只跑1次 瀏覽器會把HTTP header和data一併發送出去,服務器響應200(返回數據) |
產生2個TCP數據包,來回各1次(共2次) 瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據) |
請求形式 | 參數通過URL傳遞 | 把數據放在Request的body中 |
安全性 | 因爲URL是可見的,可能會泄露私密信息, 如賬號密碼等,所以不安全 |
數據在request中,用戶不可見,較get安全性較高 |
傳輸數據量 | 傳輸的數據量小,因爲受URL長度最多是1024字節,但效率較高; | 可以傳輸大量數據,所以上傳文件時只能用Post方式; |
支持編碼 | 只能進行url編碼 | 支持多種編碼 |
字符格式 | 只能支持ASCII字符,向服務器傳的中文字符可能會亂碼。 | 支持標準字符集,可以正確傳遞中文字符。 |
瀏覽器處理 | 請求會被瀏覽器主動cache,請求參數會被完整保留在瀏覽器歷史記錄裏 | 瀏覽器不會主動cache,參數不會被保留,除非手動設置 |
業務應用 | 常用在從服務器上獲取數據 | 常用在向服務器發送數據 |
GET只需要跑一趟就把信息送到了,而POST得跑兩趟。第一趟,先去和服務器打個招呼“嗨,我等下要送一消息來,你們打開門迎接我”,然後再回頭把數據送過去。
因爲POST需要兩步,時間上消耗的要多一點。所以看起來GET比POST更有效,但事實上不是,在網絡環境好的情況下,發一次包的時間和發兩次包的時間差別基本可以無視。而在網絡環境差的情況下,兩次包的TCP在驗證數據包完整性上,有非常大的優點。而且並非所有瀏覽器都會在POST中發送兩次包,Firefox瀏覽器就只發送一次。
07.常見的HTTP相應狀態碼
初級
HTTP
狀態碼 | 描述 |
---|---|
1xx | 指示信息–表示請求已接收,繼續處理 |
2xx | 成功–表示請求已被成功接收、理解、接受 |
3xx | 重定向–要完成請求必須進行更進一步的操作 |
4xx | 客戶端錯誤–請求有語法錯誤或請求無法實現 |
5xx | 服務器端錯誤–服務器未能實現合法的請求 |
狀態碼 | 描述 |
---|---|
200 | 請求被正常處理 |
204 | 請求被受理但沒有資源可以返回 |
206 | 客戶端只是請求資源的一部分,服務器只對請求的部分資源執行GET方法, 相應報文中通過Content-Range指定範圍的資源。 |
301 | 永久性重定向 |
302 | 臨時重定向 |
303 | 與302狀態碼有相似功能,只是它希望客戶端在請求一個URI的時候, 能通過GET方法重定向到另一個URI上 |
304 | 發送附帶條件的請求時,條件不滿足時返回,與重定向無關 |
307 | 臨時重定向,與302類似,只是強制要求使用POST方法 |
400 | 請求報文語法有誤,服務器無法識別 |
401 | 請求需要認證 |
403 | 請求的對應資源禁止被訪問 |
404 | 服務器無法找到對應資源 |
500 | 服務器內部錯誤 |
503 | 服務器正忙 |
08.如何對HTTP進行優化
中級
HTTP
1. TCP複用
TCP連接複用是將多個客戶端的HTTP請求複用到一個服務器端的TCP連接上,HTTP複用是指一個客戶端的多個HTTP請求通過一個TCP連接進行處理
2. 內容緩存
將經常用到的內容進行緩存到瀏覽器中,那麼客戶端就可以直接在內存中獲取響應的數據
3. 壓縮
將文本數據進行壓縮,減少帶寬
4. SSL加速
使用SSL協議對HTTP協議進行加密,在通道內加密並加速
09.TCP與UDP的區別
初級
TCP
UDP
UDP協議和TCP協議都是傳輸層協議。
TCP(Transmission ControlProtocol,傳輸控制協議)提供的是面向連接,可靠的字節流服務。客戶和服務器交換數據前,必須現在雙方之間建立一個TCP連接,之後才能傳輸數據。並提供超時重發、丟棄重複數據,檢驗數據,流量控制等功能,保證數據能完整地從一端傳到另一端。
簡單說就是必須要建立連接後才能傳輸數據,確保傳輸完整性,類比現實當中的打電話。
UDP(User Data Protocol,用戶數據報協議)是一個簡單的面向數據報的運輸層協議。它不提供可靠性,只是把應用程序傳給IP層的數據報發送出去,但是不能保證它們能到達目的地。由於UDP在傳輸數據報前不用再客戶和服務器之間建立一個連接,且沒有超時重發等機制,所以傳輸速度很快。
簡單說就是單向把程序中的信息發送了,但也不知道對方收到沒有,類比現實當中的寄信。
類型 | 不同點描述 |
---|---|
TCP | 面向連接,可靠的,速度慢,效率低。 |
UDP | 無連接、不可靠、速度快、效率高。 |
10.請介紹TCP的3次握手和4次揮手流程
初級
TCP
SYN:請求字段
ACK:應答字段
建立雙工通信,確保雙方都能收到對方的信息,所以需要3次握手
第1次握手:建立連接時,客戶端發送syn包(syn=x)到服務器,並進入同步已發送狀態,等待服務器確認;SYN:同步序列編號。
例如:客戶端SYN=1; 客戶端向服務器發送建立通信請求把客戶端SYN=1的包發到服務器
客戶端:我發了!
第2次握手:服務器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(syn=y),即SYN+ACK包,此時服務器進入同步已接受狀態;
例如:服務端ACK=客戶端SYN+1=2,服務端SYN=10;意思是服務端已經收到客戶端請求,並在客戶端SYN請求值上加1作爲ACK值返回給客戶端,告知客戶端自己已收到,同時發送服務端自己的SYN值給客戶端。(注意此處會同時返回SYN和ACK包給客戶端)
服務器:你發來吧,我收到你的SYN了!
第3次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態,完成三次握手。
例如:客戶端AC包=服務端SYN+1=11;客戶端在收到服務器的SYN包,並在服務器SYN請求值上加1作爲ACK返回給服務端,告知客服端已收到服務端的SYN包,完成第三次握手。
客戶端:我收到你的SYN了!
數據傳輸…
全雙工關閉需要客戶端和服務器發送和接受都關閉,但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,只能先回復一個ACK報文,所以需要4次揮手
第1次揮手:客戶端進程發出連接釋放報文,並且停止發送數據。此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。
客戶端:我不發了!停止發送,等待你的確認
第2次揮手:
服務器收到連接釋放報文,發出確認報文。服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
服務器:我知道了!進入等待程序關閉狀態
客戶端收到服務器的確認請求後,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最後的數據)。
客戶端:好,我知道你已經收到了!繼續等待你的關閉確認
第3次揮手:服務器將最後的數據發送完畢後,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由於在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號爲seq=w,此時,服務器就進入了LAST-ACK(最後確認)狀態,等待客戶端的確認。
服務器:我不發了!關閉發送,等待你的確認
第4次揮手:
客戶端收到服務器的連接釋放報文後,必須發出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,必須經過2MSL(最長報文段壽命)的時間後,當客戶端撤銷相應的TCB後,才進入CLOSED狀態。
客戶端:我已經收到你的確認了,關閉接收
服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB後,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。
服務器:我已經收到你的確認了,關閉發送
11.爲什麼TCP連接的時候是3次握手,關閉的時候卻是4次握手?
初級
TCP
因爲當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,“你發的FIN報文我收到了”。 只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。
12.TCP爲什麼會分包和粘包
高級
TCP
- TCP是以段(Segment)爲單位發送數據的,建立TCP鏈接後,有一個最大消息長度(MSS).如果應用層數據包超過MSS,就會把應用層數據包拆分,分成兩個段來發送.這個時候接收端的應用層就要拼接這兩個TCP包,才能正確處理數據.
- 有時候,TCP爲了提高網絡的利用率,會使用一個叫做Nagle的算法.該算法是指,發送端即使有要發送的數據,如果很少的話,會延遲發送.如果應用層給TCP傳送數據很快的話,就會把兩個應用層數據包“粘”在一起,TCP最後只發一個TCP數據包給接收端.
13.HTTP和websocket的區別
中級
HTTP
WEBSOCKET
- 最大的區別就是HTTP只能由客戶端推送信息給被動的服務端,而websocket既可以讓客戶端發送消息給服務端,也可以讓服務端主動推送消息到客戶端,實現雙工通信
- http協議是用在應用層的協議,他是基於tcp協議的,http協議建立鏈接也必須要有三次握手才能發送信息。
http鏈接分爲短鏈接,長鏈接,短鏈接是每次請求都要三次握手才能發送自己的信息。即每一個request對應一個response。長鏈接是在一定的期限內保持鏈接。保持TCP連接不斷開。客戶端與服務器通信,必須要由客戶端發起然後服務器返回結果。客戶端是主動的,服務器是被動的。
- WebSocket是爲解決客戶端與服務端實時通信。瀏覽器和服務器只需要做1個握手的動作,在建立連接之後,雙方可以在任意時刻,相互推送信息。同時,服務器與客戶端之間交換的頭信息很小。
建立了WebSocket之後服務器不必在瀏覽器發送request請求之後才能發送信息到瀏覽器。這時的服務器已有主動權想什麼時候發就可以發送信息到服務器。而且信息當中不必在帶有head的部分信息了與http的長鏈接通信來說,這種方式,不僅能降低服務器的壓力。而且信息當中也減少了部分多餘的信息。
14.HTTP的長連接與websocket的持久連接的區別
高級
HTTP
WEBSOCKET
-
HTTP1.1的連接默認使用長連接(persistent connection)
HTTP 1.1默認進行持久連接。在1次 TCP 連接中可以完成多個 HTTP 請求,但是對每個請求仍然要單獨發 header,Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Nginx)中設定這個時間。這種長連接是一種“僞鏈接”
-
WebSocket的持久連接
WebSocket 是一個持久化的協議,只需建立1次Request/Response消息對,之後都是TCP連接,避免了需要多次建立Request/Response消息對而產生的冗餘頭部信息。
15.什麼是cookie?其特點和應用場景有哪些?其如何獲取、設置?
中級
COOKIE
PYTHON
- cookie是一種會話跟蹤技術,由服務器生成,然後通過響應發送給客戶端的一個鍵值對。
- 特點:
- cookie是一個標準的python字典,以鍵值對方式進行存儲,鍵值都是字符串
- 通過瀏覽器訪問一個網站時,瀏覽器會將存儲該網站相關的所有cookie信息發送給該網站的服務器,request.COOKIES
- cookie是基於域名安全的
- cookie是有過期時間的,如果不指定,默認關閉瀏覽器後cookie就會過期
- 單個Cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個Cookie。
- 應用場景:記住用戶名和密碼,安全性要求不高
response.set_cookie("is_login",True) # 獲取
request.COOKIES.get("is_login") # 設置
16.什麼是session?其特點和應用場景有哪些?其如何設置、獲取、清空?
中級
SESSION
PYTHON
- Session是服務器端技術,它保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上。這就是 Session。客戶端瀏覽器再次訪問時只需要從該 Session 中查找該客戶的狀態就可以了。
- 特點:
- 它是以已鍵值對進行存儲
- 它依賴cookie,唯一的標識碼session ID保存在cookie中
- 它也是有過期時間,如果不指定,默認兩週就會過期
- 它是用base64加密
- 應用場景:涉及到安全性要求比較高的數據,銀行卡賬戶、密碼
request.session["is_login"] = True # 設置
is_login = request.session.get("is_login") # 獲取
request.session.flush() # 清空
17.session和cookie的相同點和區別
中級
SESSION
COOKIE
- 相同點
cookie/session | |
---|---|
跟蹤技術 | 都是蹤瀏覽器用戶身份的繪畫方式 |
生成地點 | 都在服務器 |
存儲形式 | 都是鍵值對 |
過期時間 | 都可自定義 |
- 不同點
cookie | session | |
---|---|---|
存放地點 | 瀏覽器 | 服務器 |
安全性 | 不安全,他人可通過分析存放在本地的cookie並進行Cookie欺騙 | 比較安全,因數據在服務器中,且用base64加密 |
依賴性 | 無 | 依賴cookie,唯一的標識碼session ID保存在cookie中 |
過期時間 | 默認關閉瀏覽器後就會過期 | 默認兩週就會過期 |
18.什麼是JWT,有什麼特點
初級
JWT
cookie
session
JWT 全稱 JSON Web Tokens,它定義了一種以JSON 對象形式的安全通信方法。它由頭部、負載和簽名3部分組成。它具有2個特點:
- 簡潔:可以通過URL, POST 參數或者在 HTTP header 發送,因爲數據量小,傳輸速度快
- 自包含:負載中包含了所有用戶所需要的信息,避免了多次查詢數據庫
19.簡述JWT的工作原理
初級
JWT
cookie
session
- 客戶端通過Web表單將正確的用戶名和密碼發送到服務端的接口。這一過程一般是POST請求。建議的方式是通過SSL加密的傳輸(https協議),從而避免敏感信息被嗅探。
- 服務端覈對用戶名和密碼成功後,將用戶的id等其他信息作爲JWT Payload(負載),將其與頭部分別進行Base64編碼拼接後簽名,形成一個JWT。形成的JWT就是一個形同lll.zzz.xxx的字符串,並設置有效時間。
- 服務端將JWT字符串作爲登錄成功的返回結果返回給客戶端。
- 客戶端將返回的JWT以cookie的形式保存在瀏覽器上,並設置cookie的有效時間(建議客戶端cookie和服務端JWT的有效時間設置爲一致),用戶登出時客戶端需刪除cookie。
- 客戶端在每次請求時將JWT放入HTTP Header中的Authorization位。(解決XSS和XSRF問題)
- 服務端對收到的JWT進行解密和校驗,如檢查簽名是否正確、Token是否過期、Token的接收方是否是自己等。
- 驗證通過後服務端使用JWT中包含的用戶信息進行其他邏輯操作,返回相應結果,否則返回401。
20.傳統Session方式存儲ID和JWT的區別
初級
JWT
cookie
session
Session是保存在服務端的,而JWT是保存在客戶端的。
Session方式存儲用戶id的最大弊病在於Session是存儲在服務器端的,所以需要佔用大量服務器內存,對於較大型應用而言可能還要保存許多的狀態。 一般而言,大型應用還需要藉助一些KV數據庫和緩存機制來實現Session的存儲。
JWT方式將用戶狀態分散到了客戶端中,可以減少服務器查詢數據庫的次數和減輕服務端的內存壓力。 除了用戶id之外,還可以存儲其他的和用戶相關的信息,例如該用戶是否是管理員、用戶所在的分組等。雖說JWT方式讓服務器有一些計算壓力(例如加密、編碼和解碼),但是這些壓力相比磁盤存儲而言可能就不算什麼了。具體是否採用,需要在不同場景下用數據說話。
Django模塊
框架層
01.什麼是Django框架?
初級
Django
Django是一個開放源代碼的Web應用框架,由Python寫成。採用了MTV的框架模式。使用這種架構,程序員可以方便、快捷地創建高品質、易維護、數據庫驅動的應用程序。它還包含許多功能強大的第三方插件,使得Django具有較強的可擴展性。
02.Django對web開發有哪些優勢
初級
Django
- 功能完善、要素齊全:該有的、可以沒有的都有,自帶大量常用工具和框架,無須你自定義、組合、增刪及修改。
- 完善的文檔:經過十多年的發展和完善,Django有廣泛的實踐案例和完善的在線文檔。開發者遇到問題時可以搜索在線文檔尋求解決方案。
- 強大的數據庫訪問組件:Django的Model層自帶數據庫ORM組件,使得開發者無須學習其他數據庫訪問技術(SQL、pymysql、SQLALchemy等)。
- 靈活的URL映射:Django使用正則表達式管理URL映射,靈活性高。新版的2.0,進一步提高了URL編寫的優雅性。
- 豐富的Template模板語言:類似jinjia模板語言,不但原生功能豐富,還可以自定義模板標籤,並且與其ORM的用法非常相似。
- 自帶後臺管理系統admin:只需要通過簡單的幾行配置和代碼就可以實現一個完整的後臺數據管理控制平臺。
- 完整的錯誤信息提示:在開發調試過程中如果出現運行錯誤或者異常,Django可以提供非常完整的錯誤信息幫助定位問題。
03.簡述Django項目的組成模塊
初級
Django
- Project
- Apps
- Model
- URL Route
- View
- DTL
- Admin
- Cache System
以下詳細參考:
- 工程
工程是承載了Django實例的所有設置的Python程序包。大部分情況下,一個Web站點就是一個工程。工程內可以新建及存放該工程固有的應用,或者保存Web站點的設置(數據庫設置、Django的選項設置、各應用的設置等)
- 應用
對於Django而言,應用之的是表示單一工程的Web應用的Python程序包。由於其本質就是Python程序包,因此方法PYTHONPATH有效地任何位置都沒有問題。這裏最好儘量減少應用與工程、應用於應用之間的依賴關係,做到功能獨立,以便在其他工程中重複利用。
- 模型
Django提供了O/R映射工具,因此可以用Python代碼來描述數據庫佈局。
每個模型都是繼承了django.db.models.Model類的Python的類,分別對應數據庫中的一個表格。通過建數據庫的字段、關係、行爲定義爲模型類的屬性或方法,我們可以使用豐富且靈活的數據庫方位API。
- URL分配器
URL分配器機制使得URL信息不再受框架及擴展名的制約,從而讓Web應用的URL設計保持簡介。
URl在URlconf模塊中進行描述,URLconf模塊中包含使用正則表達式書寫的URL和Python函數的映像。URlconf能夠以應用爲單位進行分割,因此提高了應用的可重複利用性。另外,我們可以利用給URL設置名稱並定義的方式讓代碼和目標直接通過該名稱調用URL,從而將URL設計與代碼分離。
- 視圖
Django的視圖時一類函數,它能夠生成指定頁面的HttpResponse對象或像Http 404這樣的異常情況,返回HTTP請求。典型的視圖函數的處理流程通常是從請求參數中獲取數據,讀取模型,熱按後根據獲取的數據渲染模板。
- 模板系統
在Django的概念中,模板系統只負責顯示,並不是編寫邏輯代碼的環境。因此Django的模板系統將設計與內容、代碼分離開來,是一共功能強、擴展性高、對設計者很友好的模板語言。
模板基於文本而不是XML,因此它不但能生成XML和HTML,還能生成E-mail、JavaScript、CSV等任意文本格式。
另外,如果使用模板繼承功能,子模板只需要將父模板中預留的空位填滿即可。我們在編寫模板時只需要描述各個模板獨有的部分,因此可以省去重複冗餘的編碼過程。
- 管理界面
大多Web應用在運行過程中,都需要一個專供擁有管理員權限的用戶添加、編輯、刪除數據的界面,但是實際製作這個界面並不容易。
Django只需將已經完工的模型添加到管理站點,就能根據模型定義,動態地生成頁面。爲我們提供一個功能齊全的管理界面。
- 緩存系統
Django可以使用memcached等緩存後端輕鬆地緩存數據。比如可以將動態頁面的渲染結果緩存下來,等到下次需要時直接讀取緩存,從而不必每次都對動態頁面進行處理。
緩存的後端可以從memcached、數據庫、文件系統、本地內存等位置進行選擇。緩存對象也支持整個網站、特定的整個視圖、部分模板、特定數據等。
04.簡述MVC模式和MVT模式
初級
MVC
MVT
MVC就是把Web應用分爲模型(M),控制器©和視圖(V)三層,他們之間以一種插件式的、鬆耦合的方式連接在一起,模型負責業務對象與數據庫的映射(ORM),視圖負責與用戶的交互(頁面),控制器接受用戶的輸入調用模型和視圖完成用戶的請求。
MTV
Django的MTV模式本質上和MVC是一樣的,也是爲了各組件間保持鬆耦合關係,只是定義上有些許不同,Django的MTV分別是:
M 代表模型(Model): 負責業務對象和數據庫的關係映射(ORM)。
T 代表模板 (Template):負責如何把頁面展示給用戶(html)。
V 代表視圖(View): 負責業務邏輯,並在適當時候調用Model和Template。
除了以上三層之外,還需要一個URL分發器,它的作用是將一個個URL的頁面請求分發給不同的View處理,View再調用相應的Model和Template,MTV的響應模式。
05.簡述Django請求生命週期
初級
Django
生命週期
- uWSGI服務器通過wsgi協議,將HttpRequest交給web框架 (Flask、Django)
- 首先到達request中間件,對請求對象進行校驗或添加數據,例如:csrf、request.session,如果驗證不通過直接跳轉到response中間件
- 通過URL配置文件找到urls.py文件
- 根據瀏覽器發送的URL,通過視圖中間件去匹配不同的視圖函數或視圖類,如果沒有找到相對應的視圖函數,就直接跳轉到response中間件
- 在視圖函數或視圖類中進行業務邏輯處理,處理完返回到response中間件
- 模型類通過ORM獲取數據庫數據,並返回序列化json或渲染好的Template到response中間件
- 所有最後離開的響應都會到達response中間件,對響應的數據進行處理,返回HttpResponse給wsgi
- wsgi經過uWSGI服務器,將響應的內容發送給瀏覽器。
07.什麼是WSGI
初級
wsgi
Django
WSGI(Python Web Server Gateway Interface,即Web服務器網關接口)是Python定義的Web服服務器和Web應用程序或框架之間的一種簡單而通用的接口。它是Python爲了解決Web服務器端與客戶端之間的通信問題而產生的,它基於現存的CGI標準而設計。其定義了Web服務器如何與Python應用程序進行交互,讓Python寫的Web應用程序可以和Web服務器對接起來。
返回目錄
08.uwsgi、uWSGI和WSGI的區別
中級
uwsgi
uWSGI
WSGI
graph LR
Nginx-- uwsgi ---uWSGI
uWSGI-- WSGI ---Django
- uwsgi:是uWSGI服務器實現的獨有協議,用於Nginx服務與uWSGI服務的通信規範
- uWSGI:是一個Web服務器,它實現了WSGI/uwsgi/HTTP等協議,用於接收Nginx轉發的動態請求,處理後發個python應用程序
- WSGI:用在python web框架(Django/Flask)編寫的應用程序與web服務器之間的規範
09.Django的HttpRequest對象是在什麼時候創建的?
中級
WSGI
class WSGIHandler(base.BaseHandler):
request = self.request_class(environ)
請求走到WSGIHandler類的時候,執行cell方法,將environ封裝成了request
10.什麼是中間件並簡述其作用
初級
中間件
Django
中間件是一個用來處理Django請求和響應的框架級鉤子。它是一個輕量、低級別的插件系統,用於在全局範圍內改變Django的輸入和輸出。每個中間件組件都負責做一些特定的功能。
返回目錄
11.列舉django中間件的5個方法,以及django中間件的應用場景
初級
中間件
Django
- process_request : 請求進來時,權限認證
- process_view : 路由匹配之後,能夠得到視圖函數
- process_exception : 異常時執行
- process_template_responseprocess : 模板渲染時執行
- process_response : 請求有響應時執行
12.簡述Django對http請求的執行流程
初級
Django
在接受一個Http請求之前的準備,需啓動一個支持WSGI網關協議的服務器監聽端口等待外界的Http請求,比如Django自帶的開發者服務器或者uWSGI服務器。
Django服務器根據WSGI協議指定相應的Handler來處理Http請求。此時服務器已處於監聽狀態,可以接受外界的Http請求,當一個http請求到達服務器的時候,Django服務器根據WSGI協議從Http請求中提取出必要的參數組成一個字典(environ)並傳入Handler中進行處理。在Handler中對已經符合WSGI協議標準規定的http請求進行分析,比如加載Django提供的中間件,路由分配,調用路由匹配的視圖等。最後返回一個可以被瀏覽器解析的符合Http協議的HttpResponse。
13.Django中session的運行機制是什麼
初級
Django
django的session存儲可以利用中間件來實現。需要在 settings.py
文件中註冊APP、設置中間件用於啓動。設置存儲模式(數據庫/緩存/混合存儲)和配置數據庫緩存用於存儲,生成django_session表單用於讀寫。
14. 什麼是CSRF,請描述其攻擊原理,在Django中如何解決
初級
Django
CSRF(cross-site request forgery)簡稱跨站請求僞造。例如,你訪問了信任網站A,然後網站A會用保存你的個人信息並返回給你的瀏覽器一個cookie,然後呢,在cookie的過期時間之內,你去訪問了惡意網站B,它給你返回一些惡意請求代碼,要求你去訪問網站A,而你的瀏覽器在收到這個惡意請求之後,在你不知情的情況下,會帶上保存在本地瀏覽器的cookie信息去訪問網站A,然後網站A誤以爲是用戶本身的操作,導致來自惡意網站C的攻擊代碼會被執行:發郵件,發消息,修改你的密碼,購物,轉賬,偷窺你的個人信息,導致私人信息泄漏和賬戶財產安全受到威脅。
在post請求時,form表單或ajax裏添加csrf_token,服務端開啓CSRF中間件進行驗證。
解決原理是頁面添加csrf_token值後,用戶通過URL訪問(GET請求)該頁面時,Django會在響應中自動幫我們生成cookie信息,返回給瀏覽器,同時在前端代碼會生成一個csrf_token值,然後當你POST提交信息時,Django會自動比對cookie裏和前端form表單或ajax提交上來的csrf_token值,兩者一致,說明是當前瀏覽器發起的正常請求並處理業務邏輯返回響應,那麼第三方網站拿到你的cookie值爲什麼不能通過驗證呢,因爲他沒你前端的那個隨機生成的token值,他總不能跑到你電腦面前查看你的瀏覽器前端頁面自動隨機生成的token值吧。
注意:你打開瀏覽器訪問某個url(頁面),默認是get請求,也就是說,你只要訪問了url,對應的視圖函數裏只要不是if xx == post的邏輯就會執行,所以你打開頁面,他會先生成cookie(token)值,返回給瀏覽器,然後你提交表單,或者發ajax請求時,會將瀏覽器的cookie信息(token值)發送給服務器進行token比對,這個過程相對於你發起了兩次請求,第一次是get,第二次纔是post,搞清楚這個,你才能明白csrf_token是怎麼比對的。
15. Django中CSRF的實現機制
初級
Django
- django第1次響應來自某個客戶端的請求時,服務器隨機產生1個token值,把這個token保存在session中;同時服務器把這個token放到cookie中交給前端頁面;
- 該客戶端再次發起請求時,把這個token值加入到請求數據或者頭信息中,一起傳給服務器;
- 服務器校驗前端請求帶過來的token和session裏的token是否一致。
16.什麼是跨域請求,其有哪些方式
初級
Django
- 跨域是指一個域下的文檔或腳本試圖去請求另一個域下的資源。
方式如下:
- 資源跳轉: a鏈接、重定向、表單提交
- 資源嵌入: link/script/img/frame/dom等標籤,還有樣式中background:url()、@font-face()等文件外鏈
- 腳本請求: js發起的ajax請求、dom和js對象的跨域操作等
17.跨域請求Django是如何處理的
初級
Django
使用第三方工具 django-cors-headers 即可徹底解決
- 註冊app
- 添加中間件
- 配置運行跨域請求方法
16.什麼是信號量
初級
Django
Django包含一個"信號調度程序",它有助於在框架中的其他位置發生操作時通知分離的應用程序。簡而言之,信號允許某些發送者通知一組接收器已經發生了某些動作。當許多代碼可能對同一事件感興趣時,它們特別有用.
17.web框架的本質是什麼
初級
Django
- web框架本質是一個socket服務端,用戶的瀏覽器是一個socket客戶端。
18.談談你對restful規範的認識
初級
Django
restful是一種軟件架構設計風格,並不是標準,它只是提供了一組設計原則和約束條件,主要用於客戶端和服務器交互類的軟件。 就像設計模式一樣,並不是一定要遵循這些原則,而是基於這個風格設計的軟件可以更簡潔,更有層次,我們可以根據開發的實際情況,做相應的改變。
它裏面提到了一些規範,例如
- restful 提倡面向資源編程,在url接口中儘量要使用名詞,不要使用動詞
- 在url接口中推薦使用Https協議,讓網絡接口更加安全
- 可以根據Http不同的method,進行不同的資源操作
- 在url中可以體現版本號
- url中可以體現是否是API接口
- url中可以添加條件去篩選匹配
- 響應式應該設置狀態碼
- 有返回值,而且格式爲統一的json格式
- 返回錯誤信息
- 返回結果中要提供幫助鏈接,即API最好做到Hypermedia
19.Django中如何加載初始化數據
初級
Django
Django在創建對象時在調用save()方法後,ORM框架會把對象的屬性寫入到數據庫中,實現對數據庫的初始化;通過操作對象,查詢數據庫,將查詢集返回給視圖函數,通過模板語言展現在前端頁面。
20.Django緩存系統類型有哪些
初級
Django
1. 全站緩存,較少使用
MIDDLEWARE_CLASSES = (
‘django.middleware.cache.UpdateCacheMiddleware’, # 第一
'django.middleware.common.CommonMiddleware',
‘django.middleware.cache.FetchFromCacheMiddleware’, # 最後
)
2. 視圖緩存,用戶視圖函數或視圖類中
from django.views.decorators.cache import cache_page
import time
@cache_page(15) #超時時間爲15秒
def index(request):
t=time.time() #獲取當前時間
return render(request,"index.html",locals())
3. 模板緩存,指緩存不經常變換的模板片段
{% load cache %}
<h3 style="color: green">不緩存:-----{{ t }}</h3>
{% cache 2 'name' %} # 存的key
<h3>緩存:-----:{{ t }}</h3>
{% endcache %}
21.請簡述Django下的(內建)緩存機制
初級
Django
Django根據設置的緩存方式,瀏覽器第一次請求時,cache會緩存單個變量或整個網頁等內容到硬盤或者內存中,同時設置response頭部,當瀏覽器再次發起請求時,附帶f-Modified-Since請求時間到Django,Django發現f-Modified-Since會先去參數之後,會與緩存中的過期時間相比較,如果緩存時間比較新,則會重新請求數據,並緩存起來然後返回response給客戶端,如果緩存沒有過期,則直接從緩存中提取數據,返回給response給客戶端。
22.什麼是ASGI,簡述WSGI和ASGI的關係與區別
初級
Django
ASGI是異步網關協議接口,一個介於網絡協議服務和Python應用之間的標準接口,能夠處理多種通用的協議類型,包括HTTP,HTTP2和WebSocket。
WSGI是基於HTTP協議模式的,不支持WebSocket,而ASGI的誕生則是爲了解決Python常用的WSGI不支持當前Web開發中的一些新的協議標準。同時,ASGI對於WSGI原有的模式的支持和WebSocket的擴展,即ASGI是WSGI的擴展。
23.Django如何實現websocket
初級
Django
django實現websocket使用channels。channels通過http協議升級到websocket協議,保證實時通訊。 也就是說,我們完全可以用channels實現我們的即時通訊。而不是使用長輪詢和計時器方式來保證僞實時通訊。他使用asgi協議而不是wsgi協議,他通過改造django框架,使django既支持http協議又支持websocket協議。
25.列舉django的核心組件
初級
Django
- 用於創建模型的對象關係映射;
- 爲最終用戶設計較好的管理界面;
- URL設計;
- 設計者友好的模板語言;
- 緩存系統。
26.Django本身提供了runserver,爲什麼不能用來部署
初級
Django
- runserver方法是調試 Django 時經常用到的運行方式,它使用Django自帶的
WSGI Server 運行,主要在測試和開發中使用,並且 runserver 開啓的方式也是單進程。 - uWSGI是一個Web服務器,它實現了WSGI協議、uwsgi、http 等協議。注意uwsgi是一種通信協議,而uWSGI是實現uwsgi協議和WSGI協議的 Web 服務器。uWSGI具有超快的性能、低內存佔用和多app管理等優點,並且搭配着Nginx就是一個生產環境了,能夠將用戶訪問請求與應用 app 隔離開,實現真正的部署 。 相比來講,支持的併發量更高,方便管理多進程,發揮多核的優勢,提升性能。
27.ajax請求的csrf解決方法
高級
Django
- 首先在你需要發起ajax post請求的頁面的裏面隨便一個地方加上 {% crsr_token %}
- 在發起ajax post 請求時,組織json參數時,將瀏覽器cookie中的值賦予加入json中,鍵名爲‘csrfmiddlewaretoken’
路由層
01.路由優先匹配原則是什麼
初級
路由
Django
在url匹配列表中位置優先匹配
- 如第1條和第2條同時滿足匹配規則,則優先匹配第1條。
- 如第1條爲正則模糊匹配,第2條爲精確匹配,也是優先匹配第1條
02.urlpatterns中的name與namespace的區別
初級
Django
name:給路由起一個別名
namespace:防止多個應用之間的路由重複
03.Django路由系統中include是幹嘛用的?
初級
Django
include用作路由轉發,通常,我們會在每個app裏,各自創建一個urls.py路由模塊,然後從根路由出發,將app所屬的url請求,全部轉發到相應的urls.py模塊中。
04.Django2.x中的path與django1.x裏面的URL有什麼區別
初級
Django
path與url是兩個不同的模塊,效果都是響應返回頁面, path調用的是python第三方模塊或框架,而url則是自定義的模塊。url默認支持正則表達式,而path不支持,正則表達式需要使用另外一個函數re_path。
# django 2.x
django.urls path
# django 1.x
django.conf.urls url
05.Django重定向的幾種方法,用的什麼狀態碼
初級
Django
- HttpResponse
- Redirect
- Reverse
- 狀態碼:302,301
模型層
01.命令migrate 和makemigrations的差別
初級
Django
- makemigrations:生成遷移文件
- migrate:執行遷移
02.Django的Model的繼承有幾種形式
初級
Django
- 用父類model來保存在子類model中重複的信息。父類model是不使用的也就是不生成單獨的數據表,這種情況下使用抽象基類繼承 Abstract base classes。
- 如從現有的model繼承並讓每個model都有自己的數據表,那麼使用多重表繼承 Multi-table inheritance。
- 如只在 model 中修改 Python 級的行爲,而不涉及字段改變。 代理 model (Proxy models) 適用於這種場合
03.class Meta中的元信息字段有哪些
初級
Django
- Model類可以通過元信息類設置索引和排序信息
- 元信息是在Model類中定義一個Meta子類
class Meta:
# ---常用
db_table = 'table_name' # 自定義表名
index_together = ('tag1', 'tag2') # 聯合索引
unique_together = ('tag3', 'tag4') # 聯合唯一索引
verbose_name = 'table_name' # /admin/中顯示的表名稱
verbose_name_plural = verbose_name
ordering = 'ordering_tag' # 排序字段#這個選項是指定,模型的複數形式是什麼
abstract =True # 抽象基類
# ---非常用
# app_label這個選項只在一種情況下使用,就是你的模型類不在默認的應用程序包下的models.py文件中,
# 這時候你需要指定你這個模型類是那個應用程序的。
# 比如你在其他地方寫了一個模型類,而這個模型類是屬於myapp的
app_label='myapp'
# db_table 是用於指定自定義數據庫表名的。
db_table='my_owner_table'
# 有些數據庫有數據庫表空間,比如Oracle。你可以通過db_tablespace來
# 指定這個模型對應的數據庫表放在哪個數據庫表空間。
db_tablespace
# 由於Django的管理方法中有個lastest()方法,就是得到最近一行記錄。
# 如果你的數據模型中有 DateField 或 DateTimeField 類型的字段,
# 你可以通過這個選項來指定lastest()是按照哪個字段進行選取的
get_latest_by = "order_date"
# 由於Django會自動根據模型類生成映射的數據庫表,如果你不希望Django這麼做,可以把managed的值設置
# 爲False。默認值爲True,這個選項爲True時Django可以對數據庫表進行 migrate或migrations、
# 刪除等操作。在這個時間Django將管理數據庫中表的生命週期如果爲False的時候,不會對數據庫表進行
# 創建、刪除等操作。可以用於現有表、數據庫視圖等,其他操作是一樣的。
managed
# permissions主要是爲了在Django Admin管理模塊下使用的,如果你設置了這個屬性可以讓
# 指定的方法權限描述更清晰可讀。要創建一個對象所需要的額外的權限. 如果一個對象有 admin 設置,
# 則每個對象的添加,刪除和改變權限會人(依據該選項)自動創建.
# 下面這個例子指定了一個附加權限: can_deliver_pizzas:
permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)
# 這個選項一般用於多對多的關係中,它指向一個關聯對象。就是說關聯對象找到這個對象後它是經過排序的。
# 指定這個屬性後你會得到一個get_XXX_order()和set_XXX_order()的方法,
# 通過它們你可以設置或者回去排序的對象。
order_with_respect_to = 'pizza'
04.Django模型類關係有哪幾種
初級
Django
- 一對一關係:OneToOneField
- 一對多關係:ForeignKey
- 多對多關係:ManyToManyField
05.外鍵有什麼用,什麼時候合適使用外接,外鍵一定需要索引嗎?
中級
Django
- 程序很難100%保證數據的完整性,而用外鍵即使在數據庫服務器宕機或異常的時候,也能夠最大限度的保證數據的一致性和完整性。
- 如果項目性能要求不高,安全要求高,建議使用外鍵,如果項目性能要求高,安全自己控制,不用外鍵,因爲外鍵查詢比較慢。
- 加入外鍵的主要問題就是影響性能,因此加入索引能加快關聯查詢的速度。
06.Primary Key
和Unique Key
的區別
中級
Django
- Primary key與Unique Key都是唯一性約束。
- Primary key是主鍵,一個表只能由一個,Unique key是唯一鍵,一個表可以有多個唯一鍵字段。
- Primary key 必須不能爲空,Unique Key 可爲空。
07.DateTimeField類型中的auto_now
與auto_now_add
有什麼區別
初級
Django
- DateTimeField.auto_now 用於記錄更新時間
這個參數的默認值爲false,設置爲true時,能夠在保存該字段時,將其值設置爲當前時間,並且每次修改model,都會自動更新。因此這個參數在需要存儲“最後修改時間”的場景下,十分方便。需要注意的是,設置該參數爲true時,並不簡單地意味着字段的默認值爲當前時間,而是指字段會被“強制”更新到當前時間,你無法程序中手動爲字段賦值;如果使用django再帶的admin管理器,那麼該字段在admin中是隻讀的。
- DateTimeField.auto_now_add 用於記錄創建時間
這個參數的默認值也爲False,設置爲True時,會在model對象第一次被創建時,將字段的值設置爲創建時的時間,以後修改對象時,字段的值不會再更新。該屬性通常被用在存儲“創建時間”的場景下。與auto_now類似,auto_now_add也具有強制性,一旦被設置爲True,就無法在程序中手動爲字段賦值,在admin中字段也會成爲只讀的。
08.當刪除一個外鍵的時候,其關聯的表有幾種處理方式
初級
Django
有6種處理方式:
- 同時刪除父表和子表
- 阻止刪除父表
- 子表設置爲空
- 子表設置爲默認值
- 子表什麼都不做
- 設置爲一個傳遞給SET()的值或者一個回調函數的返回值
CASCADE:代表刪除聯級,父表(少類表)被刪除的記錄在子表(多類表)中所有字段也會被對應刪除,模擬SQL語言中的ON DELETE CASCADE約束,將定義有外鍵的模型對象同時刪除!(該操作爲當前Django版本的默認操作!)
PROTECT:阻止上面的刪除操作,但是彈出ProtectedError異常
SET_NULL:代表父表(少類表)被刪除後子表(多類表)對應的外鍵字段會設置爲null,只有當字段設置了null=True,blank=True時,方可使用該值。
SET_DEFAULT:代表父表(少類表)被刪除後子表(多類表)對應的外鍵字段會設置爲默認值。只有當字段設置了default參數時,方可使用。
DO_NOTHING:什麼也不做,一切看數據庫級別的約束
SET():設置爲一個傳遞給SET()的值或者一個回調函數的返回值。注意大小寫,用得很少。
09.如何通過外鍵,子表查詢父表和父表查詢子表
中級
Django
父表和子表關係如下:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=64)
age = models.IntegerField()
tel = models.CharField(max_length=64)
@property
def all_cars(self):
'''返回全部信息'''
return self.cars.all()
@property
def info(self):
'''返回部分信息'''
return '%s %s' % (self.name, self.tel)
class Car(models.Model):
owner = models.Foreignkey(Person, related_name='cars')
name = models.CharField(max_length=64)
price = models.FloatField()
子表查詢父表
car = Car.objects.get(id=1)
# 查詢該車的車主
owner = car.owner
父表查詢子表
Tom = Person.objects.get(id=1)
# 查詢此人有多少車
# 方式一:
# Django默認每個主表對象都有一個外鍵的屬性,可以通過它來查詢所有屬於主表的子表信息
# 查詢方式:主表.子表_set(),返回值爲一個queryset對象
Tom.Car_set().all()
# 方式二:
# 通過在外鍵中設置related_name屬性值既可
Tom.cars.all()
# 方式三:
# 通過@property裝飾器在model中預定義方法實現
Tom.all_cars
10.談談 GenericForeignkey 和 GenericRelation
高級
Django
GenericForeignkey 和 GenericRelation 的方法能夠解決多外鍵的表單產生的大量沉餘數據。通過ContentType的查詢,起到一個自動一對多的作用,能和任何模型都能連接起來,保證了代碼的乾淨。避免了創建大量無用的空數據,有效減少存儲空間和服務器壓力。
11.django中怎麼寫原生SQL
中級
Django
SQL
- 使用extra
# 查詢人民郵電出版社出版並且價格大於50元的書籍
Book.objects.filter(publisher__name='人民郵電出版社').extra(where=['price>50'])
- 使用raw
books=Book.objects.raw('select * from hello_book')
for book in books:
print book
- 使用遊標
from django.db import connection
cursor = connection.cursor()
cursor.execute("insert into hello_author(name) values ('特朗普')")
cursor.execute("update hello_author set name='普京' WHERE name='特朗普'")
cursor.execute("delete from hello_author where name='普京'")
cursor.execute("select * from hello_author")
cursor.fetchone()
cursor.fetchall()
12.談一談你對ORM的理解
中級
ORM
ORM是“對象-關係-映射”的簡稱。
ORM是MVC或者MVC框架中包括一個重要的部分,它實現了數據模型與數據庫的解耦,即數據模型的設計不需要依賴於特定的數據庫,通過簡單的配置就可以輕鬆更換數據庫,這極大的減輕了開發人員的工作量,不需要面對因數據庫變更而導致的無效勞動。
13.如何使用Django ORM批量創建數據
中級
Django
ORM
可以使用django.db.models.query.QuerySet.bulk_create()
批量創建對象,減少SQL查詢次數。
例子如下:
# 創建一個空列表
querysetlist=[]
# 把創建的對象添加入列表中
for i in resultlist:
querysetlist.append(Account(name=i))
# 批量創建
Account.objects.bulk_create(querysetlist)
14.列舉django ORM中操作QuerySet對象的方法(至少5個)
初級
Django
ORM
方法 | 作用 |
---|---|
all() | 查詢所有結果 |
filter() | 過濾查詢對象。獲取不到返回None。 |
get() | 返回與所給篩選條件相匹配的對象,返回結果有且只有1個。如果符合篩選條件的對象超過1個或者沒有都會拋出錯誤。 |
exclude() | 排除滿足條件的對象 |
order_by() | 對查詢結果排序 |
reverse() | 對查詢結果反向排序 |
count() | 返回數據庫中匹配查詢(QuerySet)的對象數量。 |
first() | 返回第一條記錄 |
last() | 返回最後一條記錄 |
exists() | 如果QuerySet包含數據,就返回True,否則返回False |
values() | 返回包含對象具體值的字典的QuerySet |
values_list() | 與values()類似,只是返回的是元組而不是字典。 |
distinct() | 對查詢集去重 |
15.ORM如何取消級聯
初級
Django
user = models.ForeignKey(User,blank=True,null=True,on_delete=models.SET_NULL)
在父表被刪除,null爲True的時候就會取消級聯
16.查詢集的2大特性?什麼是惰性執行
中級
Django
特性:
- 惰性執行
- 緩存
惰性執行是指創建查詢集不會訪問數據庫,直到調用數據時,纔會訪問數據庫。
17.查詢集返回的列表過濾器有哪些
中級
Django
all():返回所有數據
filter():返回滿足條件的數據
exclude():返回滿足條件之外的數據,相當於sql語句中where部分的not關鍵字
order_by():排序
18.selected_related與prefetch_related有什麼區別
高級
Django
在Django中當創建一個查詢集的時候,並沒有跟數據庫發生任何交互。因此我們可以對查詢集進行級聯的filter等操作,只有在訪問Queryset的內容的時候,Django纔會真正進行數據庫的訪問。而多頻率、複雜的數據庫查詢往往是性能問題最大的根源。
不過我們實際開發中,往往需要訪問到外鍵對象的其他屬性。如果按照默認的查詢方式去遍歷取值,那麼會造成多次的數據庫查詢,效率可想而知。
在查詢對象集合的時候,把指定的外鍵對象也一併完整查詢加載,避免後續的重複查詢。使用 select_related() 和 prefetch_related() 可以很好的減少數據庫請求的次數,從而提高性能。
- select_related適用於一對一字段(OneToOneField)和外鍵字段(ForeignKey)查詢;
- prefetch_related適用多對多字段(ManyToManyField)和一對多字段的查詢。(或許你會有疑問,沒有一個叫OneToManyField的東西啊。實際上 ,ForeignKey就是一個多對一的字段,而被ForeignKey關聯的字段就是一對多字段了)
19.values()與values_list()有什麼區別
初級
Django
- values : 讀取字典的Queryset
- values_list : 讀取元組的Queryset
20.QueryDict和dict區別
高級
Django
在HttpRequest對象中, GET和POST屬性是django.http.QueryDict類的實例。QueryDict類似字典的自定義類,用來處理單鍵對應多值的情況。在 HttpRequest 對象中,屬性 GET 和 POST 得到的都是 django.http.QueryDict 所創建的實例。這是一個django 自定義的類似字典的類,用來處理同一個鍵帶多個值的情況。在 python 原始的字典中,當一個鍵出現多個值的時候會發生衝突,只保留最後一個值。而在 HTML 表單中,通常會發生一個鍵有多個值的情況,例如,多選框就是一個很常見情況。request.POST 和request.GET 的QueryDict 在一個正常的請求/響應循環中是不可變的。若要獲得可變的版本,需要使用.copy()方法。
- python dict當一個鍵出現多個值的時候會發生衝突,只保留最後一個值。
- QueryDict是類似字典的自定義類,用來處理單鍵對應多值的情況。
21.Django中查詢Q和F的區別
中級
Django
ORM
- Q查詢:對數據的多個字段聯合查詢(常和且或非"&|~"進行聯合使用)
- F查詢:對數據的不同字段進行比較(常用於比較和更新,對數據進行加減操作)
視圖層
01.簡述什麼是FBV和CBV
初級
Django
FBV(function base views)使用視圖函數處理請求
CBV(class base views)使用視圖類處理請求
返回目錄
02.如何給CBV的程序添加裝飾器
初級
Django
from django.utils.decorators import method_decorator
@method_decorator(check_login)
def post(self, request):
'''給方法加'''
...
@method_decorator(check_login)
def dispatch(self, request, *args, **kwargs):
'''給dispatch加'''
...
@method_decorator(check_login, name="get")
@method_decorator(check_login, name="post")
class HomeView(View):
'''給類加'''
...
導入 method_decorator 裝飾器
- 給方法加
- 給dispatch加
- 給類加
03.常用視圖響應的方式有哪些
初級
Django
- 常用視圖響應的方式有4種方式redirect、Response、HttpResponse和JsonResponse
return Response({content=響應體, content_type=響應體數據類型, status=狀態碼)
return HttpResponse(content=響應體, content_type=響應體數據類型, status=狀態碼)
return JsonResponse({‘city’: ‘beijing’, ‘subject’: ‘python’},status=response.status_code)
return redirect(‘/index.html’)
04.在視圖函數中,常用的驗證裝飾器有哪些?
中級
Django
裝飾器 | 用途 |
---|---|
@login_required() | 檢查用戶是否通過身份驗證 |
@group_required() | 檢查用戶是否屬於有權限的用戶組訪問 |
@anonymous_required() | 檢驗用戶是否已經登錄 |
@superuser_only() | 它只允許超級用戶才能訪問視圖 |
@ajax_required | 用於檢查請求是否是AJAX請求 |
@timeit | 用於改進某個視圖的響應時間,或者只想知道運行需要多長時間 |
05.視圖函數和視圖類的區別?
高級
Django
優點 | 缺點 | |
---|---|---|
視圖函數 | 容易實現跟理解;流程簡單;直接使用裝飾器 | 代碼難以重用;處理HTTP請求時要有分支表達式 |
視圖類 | 易拓展跟代碼重用;可以用混合類繼承;單獨用類方法處理HTTP請求;有許多內置的通用視圖函數 | 不容易去理解;代碼流程負載;父類混合類中隱藏較多代碼;使用裝飾器時需要額外的導入或覆蓋方法 |
高階
01.Django如何實現高併發?
高級
Django
- Nginx + uWSGI + Django
- Nginx + gunicorn + gevent + Django
02.如何提高Django應用程序的性能?
高級
Django
前端優化:
- 減少 http 請求,減少數據庫的訪問量,比如使用雪碧圖。
- 使用瀏覽器緩存,將一些常用的 css,js,logo 圖標,這些靜態資源緩存到本地瀏覽器,通過設置 http 頭中的 cache-control 和 expires 的屬性,可設定瀏覽器緩存,緩存時間可以自定義。
- 對 html,css,javascript 文件進行壓縮,減少網絡的通信量。
後端優化:
- 合理的使用緩存技術,對一些常用到的動態數據,比如首頁做一個緩存,或者某些常用的數據做個緩存,設置一定得過期時間,這樣減少了對數據庫的壓力,提升網站性能。
- 使用 celery 消息隊列,將耗時的操作扔到隊列裏,讓 worker 去監聽隊列裏的任務,實現異步操作,比如發郵件,發短信。
- 就是代碼上的一些優化,補充:nginx 部署項目也是項目優化,可以配置合適的配置參數,提升效率,增加併發量。
- 如果太多考慮安全因素,服務器磁盤用固態硬盤讀寫,遠遠大於機械硬盤,這個技術現在沒有普及,主要是固態硬盤技術上還不是完全成熟, 相信以後會大量普及。
- 服務器橫向擴展。
03.Django中當用戶登錄到A服務器進入登陸狀態,下次被nginx代理到B服務器會出現什麼影響
高級
Django
如果用戶在A應用服務器登陸的session數據沒有共享到B應用服務器,那麼之前的登錄狀態就沒有了。
返回目錄
04.談談對Celery的理解
高級
Django
Celery是由Python開發、簡單、靈活、可靠的分佈式任務隊列,其本質是生產者消費者模型,生產者發送任務到消息隊列,消費者負責處理任務。 Celery側重於實時操作,但對調度支持也很好,其每天可以處理數以百萬計的任務。
特點:
簡單:熟悉celery的工作流程後,配置使用簡單
高可用:當任務執行失敗或執行過程中發生連接中斷,celery會自動嘗試重新執行任務
快速:一個單進程的celery每分鐘可處理上百萬個任務
靈活:幾乎celery的各個組件都可以被擴展及自定製
05.Celery有哪些應用場景
高級
Django
- 異步任務:當用戶在網站進行某個操作需要很長時間完成時,我們可以將這種操作交給Celery執行,直接返回給用戶,等到Celery執行完成以後通知用戶,大大提好網站的併發以及用戶的體驗感。例如:發送驗證郵件
- 定時任務:向定時清除沉餘數據或批量在幾百臺機器執行某些命令或者任務,此時Celery可以輕鬆搞定。
06.Celery的工作原理是什麼
高級
Django
Celery由以下三部分構成:消息中間件(Broker)、任務執行單元Worker、結果存儲(Backend),如下圖:
工作原理:
任務模塊Task包含異步任務和定時任務。其中,異步任務通常在業務邏輯中被觸發併發往消息隊列,而定時任務由Celery Beat進程週期性地將任務發往消息隊列;
任務執行單元Worker實時監視消息隊列獲取隊列中的任務執行;
Woker執行完任務後將結果保存在Backend中;
消息中間件Broker
消息中間件Broker官方提供了很多備選方案,支持RabbitMQ、Redis、Amazon SQS、MongoDB、Memcached 等,官方推薦RabbitMQ。
任務執行單元Worker
Worker是任務執行單元,負責從消息隊列中取出任務執行,它可以啓動一個或者多個,也可以啓動在不同的機器節點,這就是其實現分佈式的核心。
結果存儲Backend
Backend結果存儲官方也提供了諸多的存儲方式支持:RabbitMQ、 Redis、Memcached,SQLAlchemy, Django ORM、Apache Cassandra、Elasticsearch。
數據庫模塊
MySQL
01.NoSQL和SQL數據庫之間有什麼不同?
初級
MySQL
- SQL數據庫主要稱爲關係數據庫;
- NoSQL數據庫主要稱爲非關係數據庫或分佈式數據庫;
- 結構
SQL數據庫是最廣泛使用的選項之一,使其成爲安全的選擇,尤其適用於複雜的查詢。但它具有一定的限制性。SQL數據庫是基於表的,它要求您在使用之前使用預定義模式來確定數據的結構。此外,您的所有數據都必須遵循相同的結構。這可能需要大量的前期準備,這意味着結構的變化既困難又對整個系統造成破壞。
NoSQL數據庫具有非結構化數據的動態模式。他是鍵值對,基於文檔的,圖形數據庫或寬列存儲。數據以多種方式存儲,這意味着它可以是面向文檔,面向列,基於圖形或組織爲KeyValue存儲。這種靈活性意味着可以在沒有首先定義結構的情況下創建文檔。每個文檔也可以有自己獨特的結構。語法因數據庫而異,您可以隨時添加字段。
- 可伸縮性
SQL數據庫是可垂直擴展的。這意味着您可以通過增加RAM,CPU或SSD等功能來增加單個服務器的負載。
NoSQL數據庫可以橫向擴展。這意味着您可以通過分片或在NoSQL數據庫中添加更多服務器來處理更多流量。
- 遵循的屬性
SQL數據庫遵循ACID屬性(原子性,一致性,隔離性和持久性)
NoSQL數據庫遵循Brewers CAP定理(一致性,可用性和分區容差)。
SQL | NoSQL |
---|---|
關係數據庫管理系統 | 非關係或分佈式數據庫系統 |
靜態或預定義的架構 | 動態架構 |
不適用於分層數據存儲 | 適合分層數據存儲 |
適合複雜查詢 | 不太適合複雜的查詢 |
可垂直擴展 | 可橫向擴展 |
Mysql/Oracle/PostgreSQL | MongoDB/Redis/RavenDB |
02.MySQL支持哪些存儲引擎?
初級
MySQL
MySQL支持多種存儲引擎,比如InnoDB,MyISAM,Memory,Archive等等.在大多數的情況下,直接選擇使用InnoDB引擎都是最合適的,InnoDB也是MySQL的默認存儲引擎.
03.InnoDB和MyISAM有什麼區別?
初級
MySQL
- InnoDB支持事務,而MyISAM不支持事務
- InnoDB支持行級鎖,而MyISAM支持表級鎖
- InnoDB支持MVCC, 而MyISAM不支持
- InnoDB支持外鍵,而MyISAM不支持
- InnoDB不支持全文索引,而MyISAM支持
04.數據表類型有哪些
初級
MySQL
- MyISAM
- InnoDB
- HEAP
- BOB
- ARCHIVE
- CSV
05.簡單描述mysql中,索引,主鍵,唯一索引,聯合索引的區別,對數據庫的性能有什麼影響(從讀寫兩方面)
中級
MySQL
- 索引是一種特殊的文件,它們包含着對數據表裏所有記錄的引用指針。
- 普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對數據的訪問速度。普通索引允許被索引的數據列包含重複的值。
- 唯一索引可以保證數據記錄的唯一性。在數據列創建索引的時候添加關鍵字UNIQUE把它定義爲唯一索引,能確保定某個數據列只包含彼此各不相同的值。
- 主鍵,是一種特殊的唯一索引,在一張表中只能定義一個主鍵索引,主鍵用於唯一標識一條記錄,使用關鍵字 PRIMARY KEY 來創建。
- 聯合索引可以涵蓋多個數據列聯合查詢。
- 索引可以極大的提高數據的查詢速度,但是會降低插入、刪除、更新表的速度,因爲在執行這些寫操作時,還要操作索引文件。
06.主鍵、外鍵和索引的區別
初級
MySQL
定義:
- 主鍵:唯一標識一條記錄,不能有重複的,不允許爲空
- 外鍵:表的外鍵是另一表的主鍵, 外鍵可以有重複的, 可以是空值
- 索引:該字段沒有重複值,但可以有一個空值
作用:
- 主鍵:用來保證數據完整性
- 外鍵:用來和其他表建立聯繫用的
- 索引:是提高查詢排序的速度
個數:
- 主鍵:主鍵只能有一個
- 外鍵:一個表可以有多個外鍵
- 索引:一個表可以有多個唯一索引
07.索引的底層實現原理
初級
MySQL
實現原理:B+樹,經過優化的B+樹
主要是在所有的葉子結點中增加了指向下一個葉子節點的指針,因此InnoDB建議爲大部分表使用默認自增的主鍵作爲主索引。
08.建立索引有什麼原則
初級
MySQL
- 選擇唯一性建立索引
- 爲經常需要排序、分組和聯合操作的字段建立索引
- 爲常作爲查詢條件的字段建立索引
- 限制索引的數目
- 儘量使用數據量少的索引
- 儘量使用前綴來索引
- 刪除不再使用或者很少使用的索引
09.索引的優點和缺點是什麼
初級
MySQL
優點
- 快速訪問數據表中的特定信息,提高檢索速度
- 創建唯一性索引,保證數據庫表中每一行數據的唯一性。
- 加速表和表之間的連接
- 減少查詢中分組和排序的時間
缺點:
- 創建索引和維護索引需要耗費時間,隨着數據量增加而增加;
- 每個索引都需要佔用物理空間,隨着數據量增加而增加
- 當對錶進行增、刪、改、的時候索引也要動態維護,這樣就降低了數據的維護速度。
10.什麼情況下不宜建立索引
中級
MySQL
- 對於查詢中很少涉及的列或者重複值比較多的列,不宜建立索引。
- 對於一些特殊的數據類型,不宜建立索引,比如文本字段(text)等
11.什麼是事務,其有哪些特性
初級
MySQL
- 事務是一系列的數據庫操作,是數據庫應用的基本邏輯單位。事務是被綁定在一起作爲一個邏輯工作單元的SQL語句分組,如果任何一個語句操作失敗那麼整個操作就被失敗,以後操作就會回滾到操作前狀態,或者是上有個節點。爲了確保要麼執行,要麼不執行,就可以使用事務。要將有組語句作爲事務考慮,就需要通過ACID測試,即原子性,一致性,隔離性和持久性。簡單一句話:事務就是一個操作序列,這些操作要麼都執行,要麼都不執行,它是一個不可分割的工作單位。
事務特性:
- 原子性:即不可分割性,事務要麼執行,要麼不執行。
- 一致性:事務的執行使得數據庫從一種一致性的正確狀態轉換成另一種一致性的正確狀態
- 隔離性:事務操作之間彼此獨立和透明互不影響。在事務正確提交之前,不允許把該事務對數據的任何修改提供給其他事務,
- 持久性:事務正確提交後,其結果將永久保存在數據庫中。即使系統崩潰、修改的數據也不會丟失。
12.事務有哪些隔離級別
初級
MySQL
- 未提交讀(Read Uncommitted):允許髒讀,其他事務只要修改了數據,即使未提交,本事務也能看到修改後的數據值。也就是可能讀取到其他會話中未提交事務修改的數據。
- 已提交讀(Read Committed):如果一個事務只能讀到另一個已經提交的事務修改過的數據,並且其他事務每對該數據進行一次修改並提交後,該事務都能查詢得到最新值,那麼這種隔離級別就稱之爲已提交讀。Oracle等多數數據庫默認都是該級別 (不重複讀)。
- 可重複讀(Repeated Read):可重複讀。一個事務只能讀到另一個已經提交的事務修改過的數據,但是第一次讀過某條記錄後,即使其他事務修改了該記錄的值並且提交,該事務之後再讀該條記錄時,讀到的仍是第一次讀到的值,而不是每次都讀到不同的數據。那麼這種隔離級別就稱之爲可重複讀。它是mysql默認的隔離級別。
- 串行讀(Serializable):如果一個事務先根據某些條件查詢出一些記錄,之後另一個事務又向表中插入了符合這些條件的記錄,原先的事務再次按照該條件查詢時,能把另一個事務插入的記錄也讀出來,那就意味着發生了幻讀。
13.Mysql中的事務回滾機制概述
初級
MySQL
事務是用戶定義的一個數據庫操作序列,這些操作要麼全做要麼全不做,是一個不可分割的工作單位,事務回滾是指將該事務已經完成的對數據庫的更新操作撤銷。
如要同時修改數據庫中兩個不同表時,如果它們不是一個事務的話,當第一個表修改完,可能第二個表修改過程中出現了異常而沒能修改,此時就只有第二個表依舊是未修改之前的狀態,而第一個表已經被修改完畢。而當你把它們設定爲同一個事務的時候,當第一個表修改完,第二表修改出現異常而沒能修改,第一個表和第二個表都要回到未修改的狀態,這就是所謂的事務回滾
14.SQL注入的主要特點
中級
MySQL
變種極多,攻擊簡單,危害極大
主要危害:
- 未經授權操作數據庫的數據
- 惡意纂改網頁
- 私自添加系統賬號或者使數據庫使用者賬號
- 網頁掛木馬
15.SQL語言包括哪幾部分?每部分都有哪些操作關鍵字?
初級
MySQL
SQL語言包括數據定義(DDL)、數據操縱(DML),數據控制(DCL)和數據查詢(DQL)四個部分。
- 數據定義:Create Table,Alter Table,Drop Table, Craete/Drop Index等
- 數據操縱:Select ,insert,update,delete,
- 數據控制:grant,revoke
- 數據查詢:select
16.完整性約束包括哪些?
中級
MySQL
數據完整性是指數據的精確和可靠性。
分爲以下四類:
- 實體完整性:規定表的每一行在表中是惟一的實體。
- 域完整性:是指表中的列必須滿足某種特定的數據類型約束,其中約束又包括取值範圍、精度等規定。
- 參照完整性:是指兩個表的主關鍵字和外關鍵字的數據應一致,保證了表之間的數據的一致性,防止了數據丟失或無意義的數據在數據庫中擴散。
- 用戶定義的完整性:不同的關係數據庫系統根據其應用環境的不同,往往還需要一些特殊的約束條件。用戶定義的完整性即是針對某個特定關係數據庫的約束條件,它反映某一具體應用必須滿足的語義要求。
與表有關的約束:包括列約束(NOT NULL(非空約束))和表約束(PRIMARY KEY、foreign key、check、UNIQUE) 。
17.什麼是鎖?
中級
MySQL
數據庫是一個多用戶使用的共享資源。當多個用戶併發地存取數據時,在數據庫中就會產生多個事務同時存取同一數據的情況。若對併發操作不加控制就可能會讀取和存儲不正確的數據,破壞數據庫的一致性。
加鎖是實現數據庫併發控制的一個非常重要的技術。當事務在對某個數據對象進行操作前,先向系統發出請求,對其加鎖。加鎖後事務就對該數據對象有了一定的控制,在該事務釋放鎖之前,其他的事務不能對此數據對象進行更新操作。
基本鎖類型:鎖包括行級鎖和表級鎖
18.什麼叫視圖?遊標是什麼?
中級
MySQL
- 視圖是一種虛擬的表,具有和物理表相同的功能。可以對視圖進行增,改,查,操作,視圖通常是有一個表或者多個表的行或列的子集。對視圖的修改不影響基本表。它使得我們獲取數據更容易,相比多表查詢。
- 遊標是對查詢出來的結果集作爲一個單元來有效的處理。遊標可以定在該單元中的特定行,從結果集的當前行檢索一行或多行。可以對結果集當前行做修改。一般不使用遊標,但是需要逐條處理數據的時候,遊標顯得十分重要。
19.NULL是什麼意思
初級
MySQL
NULL這個值表示UNKNOWN(未知):它不表示“”(空字符串)。對NULL這個值的任何比較都會生產一個NULL值。您不能把任何值與一個 NULL值進行比較,並在邏輯上希望獲得一個答案。
20.SQL語句中‘相關子查詢’與‘非相關子查詢’有什麼區別
中級
MySQL
子查詢:嵌套在其他查詢中的查詢稱之。子查詢又稱內部,而包含子查詢的語句稱之外部查詢(又稱主查詢)。所有的子查詢可以分爲兩類,即相關子查詢和非相關子查詢
- 非相關子查詢是獨立於外部查詢的子查詢,子查詢總共執行一次,執行完畢後將值傳遞給外部查詢。
- 相關子查詢的執行依賴於外部查詢的數據,外部查詢執行一行,子查詢就執行一次。
故非相關子查詢比相關子查詢效率高
21.char和varchar的區別
中級
MySQL
char是一種固定長度的類型,每個值都佔用N個字節,如果某個長度小於N,MySQL就會在它的右邊用空格字符補足。合適存儲具有近似得長度(md5值,身份證,手機號),長度比較短小的字符串。
varchar則是一種可變長度的類型,每個值只佔用剛好夠用的字節再加上一個用來記錄其長度的字節。適合經常更新得字符串,更新時不會出現頁分裂得情況,避免出現存儲碎片,獲得更好的io性能。
22.談談三個範式
中級
MySQL
- 第一範式: 每個列都不可以再拆分
- 第二範式: 非主鍵列完全依賴於主鍵,而不能是依賴於主鍵的一部分.
- 第三範式: 非主鍵列只依賴於主鍵,不依賴於其他非主鍵.
在設計數據庫結構的時候,要儘量遵守三範式,如果不遵守,必須有足夠的理由.比如性能. 事實上我們經常會爲了性能而妥協數據庫的設計.
23.如何進行SQL優化
高級
MySQL
- 選擇正確的存儲引擎
以 MySQL爲例,包括有兩個存儲引擎 MyISAM 和 InnoDB,每個引擎都有利有弊。
MyISAM 適合於一些需要大量查詢的應用,但其對於有大量寫操作並不是很好。甚至你只是需要update一個字段,整個表都會被鎖起來,而別的進程,就算是讀進程都無法操作直到讀操作完成。另外,MyISAM 對於 SELECT COUNT(*) 這類的計算是超快無比的。
InnoDB 的趨勢會是一個非常複雜的存儲引擎,對於一些小的應用,它會比 MyISAM 還慢。但是它支持“行鎖” ,於是在寫操作比較多的時候,會更優秀。並且,他還支持更多的高級應用,比如:事務。
- 優化字段的數據類型
記住一個原則,越小的列會越快。如果一個表只會有幾列罷了(比如說字典表,配置表),那麼,我們就沒有理由使用 INT 來做主鍵,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 會更經濟一些。如果你不需要記錄時間,使用 DATE 要比 DATETIME 好得多。當然,你也需要留夠足夠的擴展空間。
- 爲搜索字段添加索引
索引並不一定就是給主鍵或是唯一的字段。如果在你的表中,有某個字段你總要會經常用來做搜索,那麼最好是爲其建立索引,除非你要搜索的字段是大的文本字段,那應該建立全文索引。
- 避免使用Select *從數據庫裏讀出越多的數據,那麼查詢就會變得越慢。
如果你的數據庫服務器和WEB服務器是兩臺獨立的服務器的話,這還會增加網絡傳輸的負載。即使你要查詢數據表的所有字段,也儘量不要用*通配符,善用內置提供的字段排除定義也許能給帶來更多的便利。
- 使用 ENUM 而不是 VARCHAR
ENUM 類型是非常快和緊湊的。在實際上,其保存的是 TINYINT,但其外表上顯示爲字符串。這樣一來,用這個字段來做一些選項列表變得相當的完美。例如,性別、民族、部門和狀態之類的這些字段的取值是有限而且固定的,那麼,你應該使用 ENUM 而不是 VARCHAR。
- 儘可能的使用 NOT NULL
除非你有一個很特別的原因去使用 NULL 值,你應該總是讓你的字段保持 NOT NULL。 NULL其實需要額外的空間,並且,在你進行比較的時候,你的程序會更復雜。 當然,這裏並不是說你就不能使用NULL了,現實情況是很複雜的,依然會有些情況下,你需要使用NULL值。
- 固定長度的表會更快
如果表中的所有字段都是“固定長度”的,整個表會被認爲是 “static” 或 “fixed-length”。 例如,表中沒有如下類型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一個這些字段,那麼這個表就不是“固定長度靜態表”了,這樣,MySQL 引擎會用另一種方法來處理。固定長度的表會提高性能,因爲MySQL搜尋得會更快一些,因爲這些固定的長度是很容易計算下一個數據的偏移量的,所以讀取的自然也會很快。而如果字段不是定長的,那麼,每一次要找下一條的話,需要程序找到主鍵。
24.說說對SQL語句優化有哪些方法
中級
MySQL
- Where子句中:where表之間的連接必須寫在其他Where條件之前,那些可以過濾掉最大數量記錄的條件必須寫在Where子句的末尾.HAVING最後。
- 用EXISTS替代IN、用NOT EXISTS替代NOT IN。
- 避免在索引列上使用計算
- 對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where 及 order by
- 應儘量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描
- 應儘量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描
25.實踐中如何優化MySQL
高級
MySQL
- SQL語句及索引的優化
- 數據庫表結構的優化
- 系統配置的優化
- 硬件的優化
26.如何設計一個高併發的系統
高級
MySQL
- 數據庫的優化,包括合理的事務隔離級別、SQL語句優化、索引的優化
- 使用緩存,儘量減少數據庫IO
- 分佈式數據庫、分佈式緩存
- 服務器的負載均衡
27.鎖的優化策略
高級
MySQL
- 讀寫分離
- 分段加鎖
- 減少鎖持有的時間
- 多個線程儘量以相同的順序去獲取資源
28.MySQL數據庫作發佈系統的存儲,一天五萬條以上的增量,預計運維三年,怎麼優化
- 設計良好的數據庫結構,允許部分數據冗餘,儘量避免join查詢,提高效率。
- 選擇合適的表字段數據類型和存儲引擎,適當的添加索引。
- mysql庫主從讀寫分離。
- 找規律分表,減少單表中的數據量提高查詢速度。
- 添加緩存機制,比如memcached,apc等。
- 不經常改動的頁面,生成靜態頁面。
- 書寫高效率的SQL。比如不使用 SELECT *
29.對於大流量的網站,您採用什麼樣的方法來解決各頁面訪問量統計問題
高級
MySQL
- 確認服務器是否能支撐當前訪問量。
- 優化數據庫訪問。
- 禁止外部訪問鏈接(盜鏈), 比如圖片盜鏈。
- 控制文件下載。
- 使用不同主機分流。
- 使用瀏覽統計軟件,瞭解訪問量,有針對性的進行優化。
30.主鍵使用自增ID還是UUID?
高級
MySQL
推薦使用自增ID,不要使用UUID。
因爲在InnoDB存儲引擎中,主鍵索引是作爲聚簇索引存在的,也就是說,主鍵索引的B+樹葉子節點上存儲了主鍵索引以及全部的數據(按照順序),如果主鍵索引是自增ID,那麼只需要不斷向後排列即可。如果是UUID,由於到來的ID與原來的大小不確定,會造成非常多的數據插入或移動,然後導致產生很多的內存碎片,進而造成插入性能的下降。
總之,在數據量大一些的情況下,用自增主鍵性能會好一些。
31.超大分頁怎麼處理?
高級
MySQL
超大的分頁一般從三個方向上來解決.
- 優化SQL查詢語句
數據庫層面,這也是我們主要集中關注的(雖然收效沒那麼大),類似於select * from table where age > 20 limit 1000000,10這種查詢其實也是有可以優化的餘地的. 這條語句需要load1000000數據然後基本上全部丟棄,只取10條當然比較慢. 當時我們可以修改爲select * from table where id in (select id from table where age > 20 limit 1000000,10).這樣雖然也load了一百萬的數據,但是由於索引覆蓋,要查詢的所有字段都在索引中,所以速度會很快. 同時如果ID連續的好,我們還可以select * from table where id > 1000000 limit 10,效率也是不錯的,優化的可能性有許多種,但是核心思想都一樣,就是減少load的數據。 - 優化產品設計
從需求的角度減少這種請求….主要是不做類似的需求(直接跳轉到幾百萬頁之後的具體某一頁.只允許逐頁查看或者按照給定的路線走,這樣可預測,可緩存)以及防止ID泄漏且連續被人惡意攻擊。 - 使用緩存
解決超大分頁,其實主要是靠緩存,可預測性的提前查到內容,緩存至redis等k-V數據庫中,直接返回即可。
32.關心過業務系統裏面的sql耗時嗎?統計過慢查詢嗎?對慢查詢都怎麼優化過?
高級
MySQL
在業務系統中,除了使用主鍵進行的查詢,其他的我都會在測試庫上測試其耗時,慢查詢的統計主要由運維在做,會定期將業務中的慢查詢反饋給我們。
慢查詢的優化首先要搞明白慢的原因是什麼?
是查詢條件沒有命中索引?
是load了不需要的數據列?
還是數據量太大?
所以優化也是針對這三個方向來的,
- 首先分析語句,看看是否load了額外的數據,可能是查詢了多餘的行並且拋棄掉了,可能是加載了許多結果中並不需要的列,對語句進行分析以及重寫。
- 分析語句的執行計劃,然後獲得其使用索引的情況,之後修改語句或者修改索引,使得語句可以儘可能的命中索引。
- 如果對語句的優化已經無法進行,可以考慮表中的數據量是否太大,如果是的話可以進行橫向或者縱向的分表。
- 推薦使用自增ID,不要使用UUID.
33.Modelfirst和DBfirst區別
中級
Django
Model First 就是代表model優先,那麼前提也就是先創建model,然後根據model自動建立數據庫。
Datebase First 就是代表數據庫優先,那麼前提就是先創建數據庫。
區別
當數據結構發生變化的時候,
Datebase First選擇的是從數據庫生成。
Model First選擇的是從模型生成數據庫。
原因
在數據結構發生變化的時候,Datebase First編程方式中是選擇從數據庫更新模型,因此就導致了Datebase First是以數據庫爲主;而Model First選擇的是空模型生成。
Redis模塊
01. 什麼是Redis?
初級
Redis
Redis本質上是一個Key-Value類型的內存數據庫,很像memcached,整個數據庫統統加載在內存當中進行操作,定期通過異步操作把數據庫數據flush到硬盤上進行保存。因爲是純內存操作,Redis的性能非常出色,每秒可以處理超過 10萬次讀寫操作,是已知性能最快的Key-Value DB。 Redis的出色之處不僅僅是性能,Redis最大的魅力是支持保存多種數據結構,此外單個value的最大限制是1GB,不像 memcached只能保存1MB的數據,因此Redis可以用來實現很多有用的功能,比方說用他的List來做FIFO雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的Set可以做高性能的tag系統等等。另外Redis也可以對存入的Key-Value設置expire時間,因此也可以被當作一 個功能加強版的memcached來用。 Redis的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要侷限在較小數據量的高性能操作和運算上。
返回目錄
02. Redis相比memcached有哪些優勢?
初級
Redis
- memcached所有的值均是簡單的字符串,redis作爲其替代者,支持更爲豐富的數據類型
- redis的速度比memcached快很多
- redis可以持久化其數據
03. Redis支持哪幾種數據類型?
初級
Redis
String、List、Set、Sorted Set、hashes
04. Redis主要消耗什麼物理資源?
初級
Redis
redis是一種基於內存的高性能數據庫— 主要消耗於內存
05. Redis的全稱是什麼?
初級
Redis
Remote Dictionary Server。
06. Redis有哪幾種數據淘汰策略?
初級
Redis
- noeviction:返回錯誤當內存限制達到並且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)
- allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
- volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新添加的數據有空間存放。
- allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。
- volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過期集合的鍵。
- volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。
07. Redis官方爲什麼不提供Windows版本?
初級
Redis
因爲目前Linux版本已經相當穩定,而且用戶量很大,無需開發windows版本,反而會帶來兼容性等問題。
08. 一個字符串類型的值能存儲最大容量是多少?
初級
Redis
512M
09. 爲什麼Redis需要把所有數據放到內存中?
初級
Redis
Redis爲了達到最快的讀寫速度將數據都讀到內存中,並通過異步的方式將數據寫入磁盤。所以redis具有快速和數據持久化的特徵。如果不將數據放在內存中,磁盤I/O速度爲嚴重影響redis的性能。在內存越來越便宜的今天,redis將會越來越受歡迎。 如果設置了最大使用的內存,則數據已有記錄數達到內存限值後不能繼續插入新值。
10. Redis集羣方案應該怎麼做?都有哪些方案?
中級
Redis
- twemproxy,大概概念是,它類似於一個代理方式,使用方法和普通redis無任何區別,設置好它下屬的多個redis實例後,使用時在本需要連接redis的地方改爲連接twemproxy,它會以一個代理的身份接收請求並使用一致性hash算法,將請求轉接到具體redis,將結果再返回twemproxy。使用方式簡便(相對redis只需修改連接端口),對舊項目擴展的首選。 問題:twemproxy自身單端口實例的壓力,使用一致性hash後,對redis節點數量改變時候的計算值的改變,數據無法自動移動到新的節點。
- codis,目前用的最多的集羣方案,基本和twemproxy一致的效果,但它支持在 節點數量改變情況下,舊節點數據可恢復到新hash節點。
- redis cluster3.0自帶的集羣,特點在於他的分佈式算法不是一致性hash,而是hash槽的概念,以及自身支持節點設置從節點。具體看官方文檔介紹。
- 在業務代碼層實現,起幾個毫無關聯的redis實例,在代碼層,對key 進行hash計算,然後去對應的redis實例操作數據。 這種方式對hash層代碼要求比較高,考慮部分包括,節點失效後的替代算法方案,數據震盪後的自動腳本恢復,實例的監控,等等。
11. Redis集羣方案什麼情況下會導致整個集羣不可用?
中級
Redis
有A,B,C三個節點的集羣,在沒有複製模型的情況下,如果節點B失敗了,那麼整個集羣就會以爲缺少5501-11000這個範圍的槽而不可用。
12. MySQL裏有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據?
中級
Redis
redis內存數據集大小上升到一定大小的時候,就會施行數據淘汰策略。
13. Redis有哪些適合的場景?
中級
Redis
- 會話緩存(Session Cache)
最常用的一種使用Redis的情景是會話緩存(session cache)。用Redis緩存會話比其他存儲(如Memcached)的優勢在於:Redis提供持久化。當維護一個不是嚴格要求一致性的緩存時,如果用戶的購物車信息全部丟失,大部分人都會不高興的,現在,他們還會這樣嗎?
幸運的是,隨着 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來緩存會話的文檔。甚至廣爲人知的商業平臺Magento也提供Redis的插件。
- 全頁緩存(FPC)
除基本的會話token之外,Redis還提供很簡便的FPC平臺。回到一致性問題,即使重啓了Redis實例,因爲有磁盤的持久化,用戶也不會看到頁面加載速度的下降,這是一個極大改進,類似PHP本地FPC。
再次以Magento爲例,Magento提供一個插件來使用Redis作爲全頁緩存後端。
此外,對WordPress的用戶來說,Pantheon有一個非常好的插件 wp-redis,這個插件能幫助你以最快速度加載你曾瀏覽過的頁面。
3.隊列
Reids在內存存儲引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作爲一個很好的消息隊列平臺來使用。Redis作爲隊列使用的操作,就類似於本地程序語言(如Python)對 list 的 push/pop 操作。
如果你快速的在Google中搜索“Redis queues”,你馬上就能找到大量的開源項目,這些項目的目的就是利用Redis創建非常好的後端工具,以滿足各種隊列需求。例如,Celery有一個後臺就是使用Redis作爲broker,你可以從這裏去查看。
- 排行榜/計數器
Redis在內存中對數字進行遞增或遞減的操作實現的非常好。集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單,Redis只是正好提供了這兩種數據結構。所以,我們要從排序集合中獲取到排名最靠前的10個用戶–我們稱之爲“user_scores”,我們只需要像下面一樣執行即可:
當然,這是假定你是根據你用戶的分數做遞增的排序。如果你想返回用戶及用戶的分數,你需要這樣執行:
ZRANGE user_scores 0 10 WITHSCORES
Agora Games就是一個很好的例子,用Ruby實現的,它的排行榜就是使用Redis來存儲數據的,你可以在這裏看到。
- 發佈/訂閱
最後(但肯定不是最不重要的)是Redis的發佈/訂閱功能。發佈/訂閱的使用場景確實非常多。我已看見人們在社交網絡連接中使用,還可作爲基於發佈/訂閱的腳本觸發器,甚至用Redis的發佈/訂閱功能來建立聊天系統!(不,這是真的,你可以去核實)。
14.Redis爲什麼快?除了他是內存型數據庫外,還有什麼原因
15. Redis和Redisson有什麼關係?
中級
Redis
Redisson是一個高級的分佈式協調Redis客服端,能幫助用戶在分佈式環境中輕鬆實現一些Java的對象 (Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, ReadWriteLock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog)。
16. Redis與Redisson對比有什麼優缺點?
中級
Redis
Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支持;Redisson實現了分佈式和可擴展的Java數據結構,和Jedis相比,功能較爲簡單,不支持字符串操作,不支持排序、事務、管道、分區等Redis特性。Redisson的宗旨是促進使用者對Redis的關注分離,從而讓使用者能夠將精力更集中地放在處理業務邏輯上。
17. Redis如何設置密碼及驗證密碼?
初級
Redis
設置密碼:config set requirepass 123456
授權密碼:auth 123456
18. 說說Redis哈希槽的概念?
初級
Redis
Redis集羣沒有使用一致性hash,而是引入了哈希槽的概念,Redis集羣有16384個哈希槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽,集羣的每個節點負責一部分hash槽。
19. Redis集羣的主從複製模型是怎樣的?
中級
Redis
爲了使在部分節點失敗或者大部分節點無法通信的情況下集羣仍然可用,所以集羣使用了主從複製模型,每個節點都會有N-1個複製品.
20. Redis集羣會有寫操作丟失嗎?爲什麼?
中級
Redis
Redis並不能保證數據的強一致性,這意味這在實際中集羣在特定的條件下可能會丟失寫操作。
21. Redis集羣之間是如何複製的?
初級
Redis
異步複製
22. Redis集羣最大節點個數是多少?
初級
Redis
16384個。
23. Redis集羣如何選擇數據庫?
初級
Redis
Redis集羣目前無法做數據庫選擇,默認在0數據庫。
24. 怎麼測試Redis的連通性?
初級
Redis
ping
25. Redis中的管道有什麼用?
初級
Redis
一次請求/響應服務器能實現處理新的請求即使舊的請求還未被響應。這樣就可以將多個命令發送到服務器,而不用等待回覆,最後在一個步驟中讀取該答覆。
這就是管道(pipelining),是一種幾十年來廣泛使用的技術。例如許多POP3協議已經實現支持這個功能,大大加快了從服務器下載新郵件的過程。
26. 怎麼理解Redis事務?
初級
Redis
事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。
事務是一個原子操作:事務中的命令要麼全部被執行,要麼全部都不執行。
27. Redis事務相關的命令有哪幾個?
初級
Redis
MULTI、EXEC、DISCARD、WATCH
28. Redis key的過期時間和永久有效分別怎麼設置?
初級
Redis
EXPIRE和PERSIST命令。
29. Redis如何做內存優化?
中級
Redis
儘可能使用散列表(hashes),散列表(是說散列表裏面存儲的數少)使用的內存非常小,所以你應該儘可能的將你的數據模型抽象到一個散列表裏面。比如你的web系統中有一個用戶對象,不要爲這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,而是應該把這個用戶的所有信息存儲到一張散列表裏面.
30. Redis回收進程如何工作的?
中級
Redis
一個客戶端運行了新的命令,添加了新的數據。
Redi檢查內存使用情況,如果大於maxmemory的限制, 則根據設定好的策略進行回收。
一個新的命令被執行,等等。
所以我們不斷地穿越內存限制的邊界,通過不斷達到邊界然後不斷地回收回到邊界以下。
如果一個命令的結果導致大量內存被使用(例如很大的集合的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。
31. Redis回收使用的是什麼算法?
中級
Redis
LRU算法
32. Redis如何做大量數據插入?
中級
Redis
Redis2.6開始redis-cli支持一種新的被稱之爲pipe mode的新模式用於執行大量數據插入工作。
33. 爲什麼要做Redis分區?
中級
Redis
分區可以讓Redis管理更大的內存,Redis將可以使用所有機器的內存。如果沒有分區,你最多隻能使用一臺機器的內存。分區使Redis的計算能力通過簡單地增加計算機得到成倍提升,Redis的網絡帶寬也會隨着計算機和網卡的增加而成倍增長。
34. 你知道有哪些Redis分區實現方案?
中級
Redis
客戶端分區就是在客戶端就已經決定數據會被存儲到哪個redis節點或者從哪個redis節點讀取。大多數客戶端已經實現了客戶端分區。
代理分區 意味着客戶端將請求發送給代理,然後代理決定去哪個節點寫數據或者讀數據。代理根據分區規則決定請求哪些Redis實例,然後根據Redis的響應結果返回給客戶端。redis和memcached的一種代理實現就是Twemproxy
查詢路由(Query routing) 的意思是客戶端隨機地請求任意一個redis實例,然後由Redis將請求轉發給正確的Redis節點。Redis Cluster實現了一種混合形式的查詢路由,但並不是直接將請求從一個redis節點轉發到另一個redis節點,而是在客戶端的幫助下直接redirected到正確的redis節點。
35. Redis分區有什麼缺點?
中級
Redis
涉及多個key的操作通常不會被支持。例如你不能對兩個集合求交集,因爲他們可能被存儲到不同的Redis實例(實際上這種情況也有辦法,但是不能直接使用交集指令)。
同時操作多個key,則不能使用Redis事務.
分區使用的粒度是key,不能使用一個非常長的排序key存儲一個數據集(The partitioning granularity is the key, so it is not possible to shard a dataset with a single huge key like a very big sorted set).
當使用分區的時候,數據處理會非常複雜,例如爲了備份你必須從不同的Redis實例和主機同時收集RDB / AOF文件。
分區時動態擴容或縮容可能非常複雜。Redis集羣在運行時增加或者刪除Redis節點,能做到最大程度對用戶透明地數據再平衡,但其他一些客戶端分區或者代理分區方法則不支持這種特性。然而,有一種預分片的技術也可以較好的解決這個問題。
36. Redis持久化數據和緩存怎麼做擴容?
高級
Redis
如果Redis被當做緩存使用,使用一致性哈希實現動態擴容縮容。
如果Redis被當做一個持久化存儲使用,必須使用固定的keys-to-nodes映射關係,節點的數量一旦確定不能變化。否則的話(即Redis節點需要動態變化的情況),必須使用可以在運行時進行數據再平衡的一套系統,而當前只有Redis集羣可以做到這樣。
37. 分佈式Redis是前期做還是後期規模上來了再做好?爲什麼?
高級
Redis
既然Redis是如此的輕量(單實例只使用1M內存),爲防止以後的擴容,最好的辦法就是一開始就啓動較多實例。即便你只有一臺服務器,你也可以一開始就讓Redis以分佈式的方式運行,使用分區,在同一臺服務器上啓動多個實例。
一開始就多設置幾個Redis實例,例如32或者64個實例,對大多數用戶來說這操作起來可能比較麻煩,但是從長久來看做這點犧牲是值得的。
這樣的話,當你的數據不斷增長,需要更多的Redis服務器時,你需要做的就是僅僅將Redis實例從一臺服務遷移到另外一臺服務器而已(而不用考慮重新分區的問題)。一旦你添加了另一臺服務器,你需要將你一半的Redis實例從第一臺機器遷移到第二臺機器。
38. Twemproxy是什麼?
高級
Redis
Twemproxy是Twitter維護的(緩存)代理系統,代理Memcached的ASCII協議和Redis協議。它是單線程程序,使用c語言編寫,運行起來非常快。它是採用Apache 2.0 license的開源軟件。 Twemproxy支持自動分區,如果其代理的其中一個Redis節點不可用時,會自動將該節點排除(這將改變原來的keys-instances的映射關係,所以你應該僅在把Redis當緩存時使用Twemproxy)。 Twemproxy本身不存在單點問題,因爲你可以啓動多個Twemproxy實例,然後讓你的客戶端去連接任意一個Twemproxy實例。 Twemproxy是Redis客戶端和服務器端的一箇中間層,由它來處理分區功能應該不算複雜,並且應該算比較可靠的。
39. 支持一致性哈希的客戶端有哪些?
高級
Redis
Redis-rb、Predis等。
40. Redis與其他key-value存儲有什麼不同?
高級
Redis
Redis有着更爲複雜的數據結構並且提供對他們的原子性操作,這是一個不同於其他數據庫的進化路徑。Redis的數據類型都是基於基本數據結構的同時對程序員透明,無需進行額外的抽象。
Redis運行在內存中但是可以持久化到磁盤,所以在對不同數據集進行高速讀寫時需要權衡內存,應爲數據量不能大於硬件內存。在內存數據庫方面的另一個優點是, 相比在磁盤上相同的複雜的數據結構,在內存中操作起來非常簡單,這樣Redis可以做很多內部複雜性很強的事情。 同時,在磁盤格式方面他們是緊湊的以追加的方式產生的,因爲他們並不需要進行隨機訪問。
41. Redis的內存佔用情況怎麼樣?
高級
Redis
給你舉個例子: 100萬個鍵值對(鍵是0到999999值是字符串“hello world”)在我的32位的Mac筆記本上 用了100MB。同樣的數據放到一個key裏只需要16MB, 這是因爲鍵值有一個很大的開銷。 在Memcached上執行也是類似的結果,但是相對Redis的開銷要小一點點,因爲Redis會記錄類型信息引用計數等等。
當然,大鍵值對時兩者的比例要好很多。
64位的系統比32位的需要更多的內存開銷,尤其是鍵值對都較小時,這是因爲64位的系統裏指針佔用了8個字節。 但是,當然,64位系統支持更大的內存,所以爲了運行大型的Redis服務器或多或少的需要使用64位的系統。
42. 都有哪些辦法可以降低Redis的內存使用情況呢?
高級
Redis
如果你使用的是32位的Redis實例,可以好好利用Hash,list,sorted set,set等集合類型數據,因爲通常情況下很多小的Key-Value可以用更緊湊的方式存放到一起。
43. 查看Redis使用情況及狀態信息用什麼命令?
中級
Redis
info
44. Redis的內存用完了會發生什麼?
高級
Redis
如果達到設置的上限,Redis的寫命令會返回錯誤信息(但是讀命令還可以正常返回。)或者你可以將Redis當緩存來使用配置淘汰機制,當Redis達到內存上限時會沖刷掉舊的內容。
45. Redis是單線程的,如何提高多核CPU的利用率?
高級
Redis
可以在同一個服務器部署多個Redis的實例,並把他們當作不同的服務器來使用,在某些時候,無論如何一個服務器是不夠的, 所以,如果你想使用多個CPU,你可以考慮一下分片(shard)。
46. 一個Redis實例最多能存放多少的keys?List、Set、Sorted Set他們最多能存放多少元素?
高級
Redis
理論上Redis可以處理多達232的keys,並且在實際中進行了測試,每個實例至少存放了2億5千萬的keys。我們正在測試一些較大的值。
任何list、set、和sorted set都可以放232個元素。
換句話說,Redis的存儲極限是系統中的可用內存值。
47. Redis常見性能問題和解決方案?
高級
Redis
- Master最好不要做任何持久化工作,如RDB內存快照和AOF日誌文件
- 如果數據比較重要,某個Slave開啓AOF備份數據,策略設置爲每秒同步一次
- 爲了主從複製的速度和連接的穩定性,Master和Slave最好在同一個局域網內
- 儘量避免在壓力很大的主庫上增加從庫
- 主從複製不要用圖狀結構,用單向鏈表結構更爲穩定,即:Master <- Slave1 <- Slave2 <- Slave3…
這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啓用Slave1做Master,其他不變。
48. Redis提供了哪幾種持久化方式?
高級
Redis
RDB持久化方式能夠在指定的時間間隔能對你的數據進行快照存儲.
AOF持久化方式記錄每次對服務器寫的操作,當服務器重啓的時候會重新執行這些命令來恢復原始的數據,AOF命令以redis協議追加保存每次寫的操作到文件末尾.Redis還能對AOF文件進行後臺重寫,使得AOF文件的體積不至於過大.
如果你只希望你的數據在服務器運行的時候存在,你也可以不使用任何持久化方式.
你也可以同時開啓兩種持久化方式, 在這種情況下, 當redis重啓的時候會優先載入AOF文件來恢復原始的數據,因爲在通常情況下AOF文件保存的數據集要比RDB文件保存的數據集要完整.
最重要的事情是瞭解RDB和AOF持久化方式的不同,讓我們以RDB持久化方式開始。
49. 如何選擇合適的持久化方式?
高級
Redis
一般來說, 如果想達到足以媲美PostgreSQL的數據安全性, 你應該同時使用兩種持久化功能。如果你非常關心你的數據, 但仍然可以承受數分鐘以內的數據丟失,那麼你可以只使用RDB持久化。
有很多用戶都只使用AOF持久化,但並不推薦這種方式:因爲定時生成RDB快照(snapshot)非常便於進行數據庫備份, 並且 RDB 恢復數據集的速度也要比AOF恢復的速度要快,除此之外, 使用RDB還可以避免之前提到的AOF程序的bug。
50. 修改配置不重啓Redis會實時生效嗎?
高級
Redis
針對運行實例,有許多配置選項可以通過 CONFIG SET 命令進行修改,而無需執行任何形式的重啓。 從 Redis 2.2 開始,可以從 AOF 切換到 RDB 的快照持久性或其他方式而不需要重啓 Redis。檢索 ‘CONFIG GET * 命令獲取更多信息。但偶爾重新啓動是必須的,如爲升級 Redis 程序到新的版本,或者當你需要修改某些目前 CONFIG 命令還不支持的配置參數的時候。
部署模塊
Nginx
01.什麼是Nginx
初級
Nginx
Nginx是一個高性能代理服務,接收客戶端發送過來的HTTP請求和websocket請求,響應靜態文件請求和轉發動態請求。
返回目錄
02.負載均衡什麼意思
中級
Nginx
負載均衡(Server Load Balancer)是將訪問流量根據轉發策略分發到後端多臺服務器的流量分發控制服務。負載均衡擴展了應用的服務能力,增強了應用的可用性。
返回目錄
03.如何部署Django項目
高級
Nginx
- Nginx+uWSGI+Django
- Nginx+Tornado+Django
04.爲什麼正式部署時不要開啓DEBUG = True配置
中級
Nginx
因爲對於一個在線網站, 將路由暴露出來, 是一件非常危險的事情, 所以我們要關掉django的debug模式
常用算法模塊
01.你知道的python排序算法
中級
python
- 冒泡排序(Bubble Sort)
- 選擇排序(Selection Sort)
- 插入排序(Insertion Sort)
- 希爾排序(Shell Sort)
- 歸併排序(Merge Sort)
- 快速排序(Quick Sort)
- 堆排序(Heap Sort)
- 計數排序(Counting Sort)
- 桶排序(Bucket Sort)
- 基數排序(Radix Sort)
02.你瞭解的高級語言中的垃圾回收機制有哪些?Python中用的是什麼?
03.介紹下你知道的緩存相關的算法
04.介紹下你知道的負載均衡相關的算法
高級
- 輪詢
將所有請求,依次分發到每臺服務器上,適合服務器硬件相同的場景。
優點:服務器請求數目相同;
缺點:服務器壓力不一樣,不適合服務器配置不同的情況; - 隨機
請求隨機分配到各臺服務器上。
優點:使用簡單;
缺點:不適合機器配置不同的場景 - 最少鏈接
將請求分配到連接數最少的服務器上(目前處理請求最少的服務器)。
優點:根據服務器當前的請求處理情況,動態分配;
缺點:算法實現相對複雜,需要監控服務器請求連接數; - Hash(源地址散列)
根據IP地址進行Hash計算,得到IP地址。
優點:將來自同一IP地址的請求,同一會話期內,轉發到相同的服務器;實現會話粘滯。
缺點:目標服務器宕機後,會話會丟失; - 加權
在輪詢,隨機,最少鏈接,Hash等算法的基礎上,通過加權的方式,進行負載服務器分配。
優點:根據權重,調節轉發服務器的請求數目;
缺點:使用相對複雜;
其他模塊
01.介紹你項目的架構設計
02.Tornado是什麼
高級
Tornado
Tornado是使用Python編寫的Web服務器兼Web應用框架,與主流Web服務器框架不同的是,Tornado是異步非阻塞式服務器,得益於非阻塞式和對epoll模型的運用,Tornado是實時Web服務的一個理想框架,它非常適合開發長輪詢、WebSocket和需要與每個用戶建立持久連接的應用。
- 特點
- 輕量級Web框架
- 異步非阻塞IO處理方式
- Tornado採用的單進程單線程異步IO的網絡模式,其高性能源於Tornado基於Linux的Epoll(UNIX爲kqueue)的異步網絡IO。
- 出色的抗負載能力
- 不依賴多進程或多線程
- WSGI全棧替代產品
- WSGI把應用(Application)和服務器(Server)結合起來,Tornado既可以是WSGI應用也可以是WSGI服務。
- 既是WebServer也是WebFramework
03.Tornado和Django區別
高級
Tornado
Django | Tornado | |
---|---|---|
優點 | 大和全(重量級框架) | 少而精(輕量級框架) |
自帶orm,template,view | 注重性能優越,速度快 | |
需要的功能也可以去找第三方的app | 異步非阻塞,解決高併發 (請求處理是基於回調的非阻塞調用) |
|
注重高效開發 | 內嵌了HTTP服務器,合適websockets和長連接 | |
全自動化的管理後臺 (只需要使用起ORM,做簡單的定義, 就能自動生成數據庫結構,全功能的管理後臺) |
單線程的異步網絡程序, 默認啓動時根據CPU數量運行多個實例; 利用CPU多核的優勢 |
|
缺點 | template不怎麼好用(來自自身的缺點) | 模板和數據庫部分有很多第三方的模塊可供選擇,這樣不利於封裝爲一個功能模塊 |
數據庫用nosql不方便(來自自身的缺點) | ||
如果功能不多,容易臃腫 |
總結:
- 要性能, Tornado 首選;
- 要開發速度,Django 和 Flask 都行,區別是 Flask 把許多功能交給第三方庫去完成了,因此 Flask 更爲靈活。
綜上所述:
- Django適合初學者或者小團隊的快速開發,適合做管理類、博客類網站、或者功能十分複雜需求十分多的網站
- Tornado適合高度定製,適合訪問量大,異步情況多的網站
雲服務模塊
01.你使用過哪些雲服務技術?
高級
雲
返回目錄
02.常用的雲技術有哪些,請列舉4個
高級
雲
- ECS實例
- OSS
- RDS
- CDN