數據庫部分,前端

數據庫部分                         css

 

 

1. 列舉常見的關係型數據庫和非關係型都有那些?html

 

關係型數據庫前端

 

Oracle、DB二、Microsoft SQL Server、Microsoft Access、MySQLvue

 

非關係型java

 

NoSql、Cloudant、MongoDb、redis、HBasenode

 

 

 

2. MySQL常見數據庫引擎及比較?python

 

MyISAM:默認的MySQL插件式存儲引擎,它是在Web、數據倉儲和其餘應用環境下最常使用的存儲引擎之一。mysql

 

注意,經過更改STORAGE_ENGINE配置變量,可以方便地更改MySQL服務器的默認存儲引擎。react

 

  InnoDB:用於事務處理應用程序,具備衆多特性,包括ACID事務支持。(提供行級鎖)jquery

 

  BDB:可替代InnoDB的事務引擎,支持COMMIT、ROLLBACK和其餘事務特性。

 

  Memory:將全部數據保存在RAM中,在須要快速查找引用和其餘相似數據的環境下,可提供極快的訪問。

 

  Merge:容許MySQL DBA或開發人員將一系列等同的MyISAM表以邏輯方式組合在一塊兒,並做爲1個對象引用它們。對於諸如數據倉儲等VLDB環境十分適合。

 

  Archive:爲大量不多引用的歷史、歸檔、或安全審計信息的存儲和檢索提供了完美的解決方案。

 

  Federated:可以將多個分離的MySQL服務器連接起來,從多個物理服務器建立一個邏輯數據庫。十分適合於分佈式環境或數據集市環境。

 

  Cluster/NDB:MySQL的簇式數據庫引擎,尤爲適合於具備高性能查找要求的應用程序,

 

這類查找需求還要求具備最高的正常工做時間和可用性。

 

  Other:其餘存儲引擎包括CSV(引用由逗號隔開的用做數據庫表的文件),

 

Blackhole(用於臨時禁止對數據庫的應用程序輸入),以及Example引擎

 

(可爲快速建立定製的插件式存儲引擎提供幫助)。

 

 

 

3. 簡述數據庫三大範式?

 

第一範式

 

   一、每一列屬性都是不可再分的屬性值,確保每一列的原子性

 

   二、兩列的屬性相近或類似或同樣,儘可能合併屬性同樣的列,確保不產生冗餘數據。

 

第二範式

 

每一行的數據只能與其中一列相關,即一行數據只作一件事。只要數據列中出現數據重複,就要把表拆分開來。

 

第三範式

 

數據不能存在傳遞關係,即沒個屬性都跟主鍵有直接關係而不是間接關係。

 

像:a-->b-->c  屬性之間含有這樣的關係,是不符合第三範式的。

 

 

 

4. 什麼是事務?MySQL如何支持事務?

 

事務是由一步或幾步數據庫操做序列組成邏輯執行單元,這系列操做要麼所有執行,要麼所有放棄執行。

 

程序和事務是兩個不一樣的概念。通常而言:一段程序中可能包含多個事務。

 

(說白了就是幾步的數據庫操做而構成的邏輯執行單元)

 

事務具備四個特性:原子性(Atomicity)、一致性(Consistency)、

 

隔離性(Isolation)和持續性(Durability)。這四個特性也簡稱ACID性。

 

 

 

MYSQL的事務處理主要有兩種方法

 

  1.用begin,rollback,commit來實現

 

    begin開始一個事務

 

    rollback事務回滾

 

       commit 事務確認

 

  2.直接用set來改變mysql的自動提交模式

 

          mysql默認是自動提交的,也就是你提交一個query,就直接執行!能夠經過

 

          set autocommit = 0 禁止自動提交

 

          set autocommit = 1 開啓自動提交

 

 

 

5. 簡述數據庫設計中一對多和多對多的應用場景?

 

數據庫實體間有三種對應關係:一對一,一對多,多對多。

 

       一對一關係示例:

 

一個學生對應一個學生檔案材料,或者每一個人都有惟一的身份證編號。

 

       一對多關係示例:

 

一個學生只屬於一個班,可是一個班級有多名學生。

 

       多對多關係示例:

 

一個學生能夠選擇多門課,一門課也有多名學生。

 

6. 如何基於數據庫實現商城商品計數器?

 

建立一個商城表---包含(id,商品名,每個商品對應數量)

 

7. 簡述觸發器、函數、視圖、存儲過程?

 

觸發器:觸發器是一個特殊的存儲過程,它是MySQL在insert、update、delete的時候自動執行的代碼塊。

 

函數:MySQL中提供了許多內置函數,還能夠自定義函數(實現程序員須要sql邏輯處理)

 

視圖:視圖是由查詢結果造成的一張虛擬表,是表經過某種運算獲得的一個投影

 

存儲過程:把一段代碼封裝起來,當要執行這一段代碼的時候,能夠經過調用該存儲過程來實現

 

(通過第一次編譯後再次調用不須要再次編譯,比一個個執行sql語句效率高)

 

 

 

8. MySQL索引種類

 

索引是一種特殊的文件(InnoDB數據表上的索引是表空間的一個組成部分),更通俗的說,

 

數據庫索引比如是一本書前面的目錄,能加快數據庫的查詢速度MySQL索引的類型:  

 

1. 普通索引:這是最基本的索引,它沒有任何限制  

 

2.惟一索引:索引列的值必須惟一,但容許有空值,若是是組合索引,則列值的組合必須惟一  

 

3.全文索引:全文索引僅可用於 MyISAM 表,能夠從CHAR、VARCHAR或TEXT列中做爲

 

CREATE TABLE語句的一部分被建立,或是隨後使用ALTER TABLE 或CREATE INDEX被添加

 

(切記對於大容量的數據表,生成全文索引是一個很是消耗時間很是消耗硬盤空間的作法)  

 

4. 單列索引、多列索引:多個單列索引與單個多列索引的查詢效果不一樣,

 

由於執行查詢時,MySQL只能使用一個索引,會從多個索引中選擇一個限制最爲嚴格的索引。  

 

5.組合索引(最左前綴):簡單的理解就是隻從最左面的開始組合(

 

實在單列索引的基礎上進一步壓榨索引效率的一種方式

 

 

 

9. 索引在什麼狀況下遵循最左前綴的規則?

 

mysql在使用組合索引查詢的時候須要遵循「最左前綴」規則

 

 

 

10. 主鍵和外鍵的區別?

 

1.主鍵是能肯定一條記錄的惟一標識

 

2.外鍵用於與另外一張表的關聯,是能肯定另外一張表記錄的字段,用於保持數據的一致性

 

 

 

11. MySQL常見的函數?

 

聚合函數:  

 

AVG(col)返回指定列的平均值  

 

COUNT(col)返回指定列中非NULL值的個數  

 

MIN(col)返回指定列的最小值  

 

MAX(col)返回指定列的最大值  

 

SUM(col)返回指定列的全部值之和  

 

GROUP_CONCAT(col) 返回由屬於一組的列值鏈接組合而成的結果

 

數學函數:  

 

ABS(x) 返回x的絕對值  

 

BIN(x) 返回x的二進制(OCT返回八進制,HEX返回十六進制)

 

 

 

12. 列舉 建立索引可是沒法命中索引的8種狀況。

 

1.若是條件中有or,即便其中有條件帶索引也不會使用(這也是爲何儘可能少用or的緣由)

 

2.對於多列索引,不是使用的第一部分,則不會使用索引

 

3.like查詢是以%開頭

 

4.若是列類型是字符串,那必定要在條件中將數據使用引號引用起來,不然不使用索引

 

5.若是mysql估計使用全表掃描要比使用索引快,則不使用索引

 

6 對小表查詢

 

7 提示不使用索引

 

8 統計數據不真實

 

9.單獨引用複合索引裏非第一位置的索引列.

 

 

 

13. 如何開啓慢日誌查詢?

 

1 執行 SHOW VARIABLES LIKE 「%slow%」,獲知 mysql 是否開啓慢查詢 slow_query_log

 

慢查詢開啓狀態 OFF 未開啓 ON 爲開啓 slow_query_log_file 慢查詢日誌存放的位置(

 

這個目錄須要MySQL的運行賬號的可寫權限,通常設置爲MySQL的數據存放目錄)

 

2 修改配置文件( 放在[mysqld]下),重啓 long_query_time 查詢超過多少秒才記錄

 

3 測試是否成功

 

4 慢查詢日誌文件的信息格式

 

 

 

14.數據庫導入導出命令(結構+數據)?

 

1.導出整個數據庫   mysqldump -u用戶名 -p密碼 數據庫名 > 導出的文件名   

 

例如:C:\Users\jack> mysqldump -uroot -pmysql sva_rec > e:\sva_rec.sql   

 

2.導出一個表,包括表結構和數據   mysqldump -u用戶名 -p 密碼 數據庫名 表名> 導出的文件名   

 

例如:C:\Users\jack> mysqldump -uroot -pmysql sva_rec date_rec_drv> e:\date_rec_drv.sql   

 

3.導出一個數據庫結構   

 

例如:C:\Users\jack> mysqldump -uroot -pmysql -d sva_rec > e:\sva_rec.sql

 

4.導出一個表,只有表結構   mysqldump -u用戶名 -p 密碼 -d數據庫名 表名> 導出的文件名    

 

例如:C:\Users\jack> mysqldump -uroot -pmysql -d sva_rec date_rec_drv> e:\date_rec_drv.sql   

 

5.導入數據庫   經常使用source 命令   進入mysql數據庫控制檯,   

 

mysql -u root -p   mysql>use 數據庫   而後使用source命令,後面參數爲腳本文件(如這裏用到的.sql)   

 

mysql>source d:wcnc_db.sql

 

 

 

15. 數據庫優化方案?

 

整體思路從如下幾個方面:

 

一、選取最適用的字段屬性

 

二、使用鏈接(JOIN)來代替子查詢(Sub-Queries)

 

三、使用聯合(UNION)來代替手動建立的臨時表

 

四、事務(當多個用戶同時使用相同的數據源時,它能夠利用鎖定數據庫的方法來爲用戶提供一種安全的訪問方式,

 

這樣能夠保證用戶的操做不被其它的用戶所幹擾)

 

5.鎖定表(有些狀況下咱們能夠經過鎖定表的方法來得到更好的性能)

 

六、使用外鍵(鎖定表的方法能夠維護數據的完整性,可是它卻不能保證數據的關聯性。

 

這個時候咱們就能夠使用外鍵)

 

七、使用索引

 

八、優化的查詢語句(絕大多數狀況下,使用索引能夠提升查詢的速度,但若是SQL語句使用不恰當的話,

 

索引將沒法發揮它應有的做用)

 

 

 

16. char和varchar的區別?

 

char:定長,char的存取數度相對快

 

varchar:不定長,存取速度相對慢

 

 

 

17. 簡述MySQL的執行計劃?

 

執行計劃explain命令是查看查詢優化器如何決定執行查詢的主要方法。

 

這個功能有侷限性,並不總會說出真相,但它的輸出是能夠獲取的最好信息,經過輸出結果反推執行過程

 

 

 

18. 在對name作了惟一索引前提下,簡述如下區別:


 

        select * from tb where name = ‘Oldboy-Wupeiqi’ 


 

        select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1

 

select * from tb where name = ‘Oldboy’ -------------

 

查找到tb表中全部name = ‘Oldboy’的數據

 

select * from tb where name = ‘Oldboy’ limit 1------

 

查找到tb表中全部name = ‘Oldboy’的數據只取其中的第一條

 

 

 

19. 1000w條數據,使用limit offset 分頁時,爲何越日後翻越慢?如何解決?

 

當一個數據庫表過於龐大,LIMIT offset, length中的offset值過大,則SQL查詢語句會很是緩慢,

 

你需增長order by,而且order by字段須要創建索引。

 

 

 

20. 什麼是索引合併?

 

1.索引合併是把幾個索引的範圍掃描合併成一個索引。

 

二、索引合併的時候,會對索引進行並集,交集或者先交集再並集操做,以便合併成一個索引。

 

三、這些須要合併的索引只能是一個表的。不能對多表進行索引合併。

 

 

 

21. 什麼是覆蓋索引?

 

覆蓋索引又能夠稱爲索引覆蓋。

 

  解釋一: 就是select的數據列只用從索引中就可以取得,沒必要從數據表中讀取,

 

換句話說查詢列要被所使用的索引覆蓋。

 

  解釋二: 索引是高效找到行的一個方法,當能經過檢索索引就能夠讀取想要的數據,

 

那就不須要再到數據表中讀取行了。若是一個索引包含了(或覆蓋了)知足查詢語句中字段

 

與條件的數據就叫作覆蓋索引。

 

  解釋三: 是非彙集組合索引的一種形式,它包括在查詢裏的Select、Join和Where子句用到的全部列

 

(即創建索引的字段正好是覆蓋查詢語句[select子句]與查詢條件[Where子句]中所涉及的字段,

 

也即,索引包含了查詢正在查找的全部數據)。

 

 

 

22. 簡述數據庫讀寫分離?

 

讀寫分離從字面意思就能夠理解,就是把對數據庫的讀操做和寫操做分離開。

 

讀寫分離在網站發展初期能夠必定程度上緩解讀寫併發時產生鎖的問題,

 

將讀寫壓力分擔到多臺服務器上,一般用於讀遠大於寫的場景。

 

*讀寫分離的好處*

 

1)數據是網站的生命,讀寫分離經過主從備份數據,保證了系統的冗餘,保護了珍貴的數據。

 

2)提升了系統性能,必定程度提升了數據庫負載能力。

 

*適用讀寫分離場景*

 

1)網站初期想要緩解數據負載最簡單可行的方案。

 

2)服務器面對的是讀遠大於寫的場景,而且業務可以容許時間上一些延遲。

 

*讀寫分離實現方式*

 

目前讀寫分離方案網上找了幾個並作了對比。

 

1.mycat 基於阿里的cobar改版的(比較穩定,論壇活躍)

 

2.atlas 360開發的 網友說不是很穩定 (已經好久沒更新)

 

3.mysql-proxy mysql自帶 (不是很穩定)

 

4.oneproxy 比較穩定 性能也很好 (須要付費)

 

5.amoeba 好像還行,有一些公司使用 (可是好久沒有更新了)

 

 

 

 

 

23. 簡述數據庫分庫分表?(水平、垂直)

 

從字面上簡單理解,就是把本來存儲於一個庫的數據分塊存儲到多個庫上,

 

把本來存儲於一個表的數據分塊存儲到多個表上。

 

 

 

數據庫中的數據量不必定是可控的,在未進行分庫分表的狀況下,隨着時間和業務的發展,

 

庫中的表會愈來愈多,表中的數據量也會愈來愈大,相應地,數據操做,增刪改查的開銷也會愈來愈大;

 

另外,因爲沒法進行分佈式式部署,而一臺服務器的資源(CPU、磁盤、內存、IO等)是有限的,

 

最終數據庫所能承載的數據量、數據處理能力都將遭遇瓶頸。

 

 

 

分庫分表有垂直切分和水平切分兩種。

 

何謂垂直切分,即將表按照功能模塊、關係密切程度劃分出來,部署到不一樣的庫上。

 

例如,咱們會創建定義數據庫workDB、商品數據庫payDB、用戶數據庫userDB、日誌數據庫logDB等,

 

分別用於存儲項目數據定義表、商品定義表、用戶數據表、日誌數據表等。

 

 

 

何謂水平切分,當一個表中的數據量過大時,咱們能夠把該表的數據按照某種規則,

 

例如userID散列,進行劃分,而後存儲到多個結構相同的表,和不一樣的庫上。

 

例如,咱們的userDB中的用戶數據表中,每個表的數據量都很大,

 

就能夠把userDB切分爲結構相同的多個userDB:part0DB、part1DB等,

 

再將userDB上的用戶數據表userTable,切分爲不少userTable:userTable0、userTable1等,

 

而後將這些表按照必定的規則存儲到多個userDB上。

 

 

 

 

 

 

 

24. redis和memcached比較?

 

一、Redis和Memcache都是將數據存放在內存中,都是內存數據庫。不過memcache還可用於緩存其餘東西。例如圖片、視頻等等;

 

二、Redis不只僅支持簡單的k/v類型的數據,同時還提供list,set,hash等數據結構的存儲;

 

三、虛擬內存--Redis當物理內存用完時,能夠將一些好久沒用到的value

 

 交換到磁盤;

 

四、過時策略--memcache在set時就指定,例如set key1 0 0 8,即永不過時。Redis能夠經過例如expire 設定,

 

例如expire name 10;

 

五、分佈式--設定memcache集羣,利用magent作一主多從;redis能夠作一主多從。均可以一主一從;

 

六、存儲數據安全--memcache掛掉後,數據沒了;redis能夠按期保存到磁盤(持久化);

 

七、災難恢復--memcache掛掉後,數據不可恢復;

 

 redis數據丟失後能夠經過aof恢復;

 

八、Redis支持數據的備份,即master-slave模式的數據備份;

 

九、應用場景不同:Redis出來做爲NoSQL數據庫使用外,還能用作消息隊列、數據堆棧和數據緩存等;

 

Memcached適合於緩存SQL語句、數據集、用戶臨時性數據、延遲查詢數據和session等。

 

 

 

25. redis中數據庫默認是多少個db 及做用?

 

#redis默認有16dbdb0~db15(能夠經過配置文件支持更多,無上限)

 

而且每一個數據庫的數據是隔離的不能共享

 

能夠隨時使用SELECT命令更換數據庫:redis> SELECT 1#

 

注意:     

 

多個數據庫之間並非徹底隔離的

 

       好比FLUSHALL命令能夠清空一個Redis實例中全部數據庫中的數據。

 

 

 

26. python操做redis的模塊?

 

一、基本操做

 

redis提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令,Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py。

 

redis鏈接實例是線程安全的,能夠直接將redis鏈接實例設置爲一個全局變量,直接使用。若是須要另外一個Redis實例(or Redis數據庫)時,就須要從新建立redis鏈接實例來獲取一個新的鏈接。同理,python的redis沒有實現select命令。

 

鏈接redis,加上decode_responses=True,寫入的鍵值對中的value爲str類型,不加這個參數寫入的則爲字節類型。

 

鏈接池

 

(1) redis-py使用connection pool來管理對一個redis server的全部鏈接,避免每次創建、釋放鏈接的開銷。默認,每一個Redis實例都會維護一個本身的鏈接池。
能夠直接創建一個鏈接池,而後做爲參數Redis,這樣就能夠實現多個Redis實例共享一個鏈接池

 

二、管道

 

redis默認在執行每次請求都會建立(鏈接池申請鏈接)和斷開(歸還鏈接池)一次鏈接操做,
若是想要在一次請求中指定多個命令,則能夠使用pipline實現一次請求指定多個命令,而且默認狀況下一次pipline 是原子性操做。

 

管道(pipeline)是redis在提供單個請求中緩衝多條服務器命令的基類的子類。它經過減小服務器-客戶端之間反覆的TCP數據庫包,從而大大提升了執行批量命令的功能。

 

三、發佈訂閱

 

 

 

27. 若是redis中的某個列表中的數據量很是大,若是實現循環顯示每個值?

 

經過scan_iter分片取,減小內存壓力

 

scan_iter(match=None, count=None)增量式迭代獲取redis裏匹配的的值# match,匹配指定key

 

# count,每次分片最少獲取個數

 

     r = redis.Redis(connection_pool=pool)

 

     for key in r.scan_iter(match='PREFIX_*', count=100000):

 

         print(key)

 

 

 

28. redis如何實現主從複製?以及數據同步機制?

 

Redis中的主從複製,也就是Master-Slave模型,其實現相對比較簡單,通常使用在多個Redis實例間

 

的數據同步以及Redis集羣中用的比較多。

 

Redis的主從同步機制能夠確保redis的master和slave之間的數據同步。按照同步內容的多少能夠分爲

 

全同步和部分同步;按照同步的時機能夠分爲slave剛啓動時的初始化同步和正常運行過程當中的數據

 

修改同步;本文將對這兩種機制的流程進行分析。

 

# 實現主從複製

 

    '建立63796380配置文件'

 

    redis.conf6379爲默認配置文件,做爲Master服務配置;

 

    redis_6380.conf6380爲同步配置,做爲Slave服務配置;

 

    '配置slaveof同步指令'

 

    Slave對應的conf配置文件中,添加如下內容:

 

    slaveof 127.0.0.1 6379# 數據同步步驟:

 

    (1)Slave服務器鏈接到Master服務器.

 

    (2)Slave服務器發送同步(SYCN)命令.

 

    (3)Master服務器備份數據庫到文件.

 

    (4)Master服務器把備份文件傳輸給Slave服務器.

 

    (5)Slave服務器把備份文件數據導入到數據庫中.

 

 

 

29. redis中的sentinel的做用?

 

Redis SentinelSentinel(哨兵)是用於監控redis集羣中Master狀態的工具,其已經被集成在redis2.4+的版本中。

 

Sentinel做用:

 

  1):Master狀態檢測

 

  2):若是Master異常,則會進行Master-Slave切換,將其中一個Slave做爲Master,將以前的Master做爲Slave

 

  3):Master-Slave切換後,master_redis.conf、slave_redis.conf和sentinel.conf的內容都會發生改變,

 

master_redis.conf中會多一行slaveof的配置,sentinel.conf的監控目標會隨之調換

 

 

 

  1. 如何實現redis集羣?

 

#基於【分片】來完成。

 

    - 集羣是將你的數據拆分到多個Redis實例的過程

 

    - 能夠使用不少電腦的內存總和來支持更大的數據庫。

 

    - 沒有分片,你就被侷限於單機能支持的內存容量。#redis將全部能放置數據的地方建立了 16384 個哈希槽。

 

#若是設置集羣的話,就能夠爲每一個實例分配哈希槽:

 

    - 192.168.1.200-5000

 

    - 192.168.1.215001-10000

 

    - 192.168.1.2210001-16384#之後想要在redis中寫值時:set k1 123

 

    - k1經過crc16的算法轉換成一個數字,而後再將該數字和16384求餘,

 

    - 若是獲得的餘數 3000,那麼就將該值寫入到 192.168.1.20 實例中。#集羣方案:

 

    - redis cluster:官方提供的集羣方案。

 

    - codis:豌豆莢技術團隊。

 

    - tweproxyTwiter技術團隊

 

 

 

一般有3個途徑:官方Redis Cluster;經過Proxy分片;客戶端分片(Smart Client)

 

Redis Cluster(官方):雖然正式版發佈已經有一年多的時間,但還缺少最佳實踐;

 

對協議進行了較大修改,致使主流客戶端也並不是都已支持,部分支持的客戶端也沒有通過大規模生產環境的驗證;

 

無中心化設計使整個系統高度耦合,致使很難對業務進行無痛的升級。

 

Proxy:如今不少主流的Redis集羣都會使用Proxy方式,例如早已開源的Codis。這種方案有不少優勢,

 

由於支持原聲redis協議,因此客戶端不須要升級,對業務比較友好。而且升級相對平滑,能夠起多個Proxy後,

 

逐個進行升級。可是缺點是,由於會多一次跳轉,平均會有30%左右的性能開銷。

 

並且由於原生客戶端是沒法一次綁定多個Proxy,鏈接的Proxy若是掛了仍是須要人工參與。除非相似Smart

 

 Client同樣封裝原有客戶端,支持重連到其餘Proxy,但這也就帶來了客戶端分片方式的一些缺點。而且雖然Proxy能夠使用多個,而且能夠動態增長proxy增長性能,可是全部客戶端都是共用全部proxy,那麼一些異常的服務有可能影響到其餘服務。爲每一個服務獨立搭建proxy,也會給部署帶來額外的工做。而咱們選擇了第三種方案,客戶端分片(SmartClient)。客戶端分片相比Proxy擁有更好的性能,及更低的延遲。固然也有缺點,就是升級須要重啓客戶端,並且咱們須要維護多個語言的版本,但咱們更愛高性能。

 

 

 

31. redis中默認有多少個哈希槽?

 

Redis 集羣有16384個哈希槽,每一個key經過CRC16校驗後對16384取模來決定放置哪一個槽.

 

集羣的每一個節點負責一部分hash槽

 

 

 

  1. 簡述redis的有哪幾種持久化策略及比較?

 

#RDB:每隔一段時間對redis進行一次持久化。

 

     - 缺點:數據不完整

 

     - 優勢:速度快

 

#AOF:把全部命令保存起來,若是想從新生成到redis,那麼就要把命令從新執行一次。

 

     - 缺點:速度慢,文件比較大

 

     - 優勢:數據完整

 

 

 

Redis的持久化策略:2種

 

    ---------rdb:快照形式是直接把內存中的數據保存到一個dump文件中,定時保存,保存策略

 

    ---------aof:把全部的對redis的服務器進行修改的命令都存到一個文件裏,命令的集合

 

RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤,實際操做過程是fork一個子進程,

 

先將數據集寫入臨時文件,寫入成功後,再替換以前的文件,用二進制壓縮存儲。

 

AOF持久化以日誌的形式記錄服務器所處理的每個寫、刪除操做,查詢操做不會記錄,以文本的方式記錄,能夠打開文件看到詳細的操做記錄

 

 

 

33. 列舉redis支持的過時策略。

 

maxmemory-policy 六種方式

 

volatile-lru:只對設置了過時時間的key進行LRU(默認值) 

 

allkeys-lru  刪除lru算法的key   

 

volatile-random:隨機刪除即將過時key   

 

allkeys-random:隨機刪除   

 

volatile-ttl  刪除即將過時的   

 

noeviction  永不過時,返回錯誤  

 

 

 

34. MySQL 裏有 2000w 數據,redis 中只存 20w 的數據,如何保證 redis 中都是熱點數據?

 

redis 內存數據集大小上升到必定大小的時候,就會施行數據淘汰策略。redis 提供 6種數據淘汰策略:

 

volatile-lru:從已設置過時時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰

 

volatile-ttl:從已設置過時時間的數據集(server.db[i].expires)中挑選將要過時的數據淘汰

 

volatile-random:從已設置過時時間的數據集(server.db[i].expires)中任意選擇數據淘汰

 

allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰

 

allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰

 

no-enviction(驅逐):禁止驅逐數據

 

 

 

# 限定Redis佔用的內存,根據自身數據淘汰策略,淘汰冷數據,把熱數據加載到內存。

 

# 計算一下 20W 數據大約佔用的內存,而後設置一下Redis內存限制便可。

 

 

 

 

 

35. 寫代碼,基於redis的列表實現 先進先出、後進先出隊列、優先級隊列。

 

 

 

36. 如何基於redis實現消息隊列?

 

能夠利用redis存儲數據類型的list類型實現消息發送與消費的一對一模式,使用lpush向list的左端推送數據(發送消息),使用rpop從右端接收數據(消費消息)。因爲rpop須要週期性的從list中獲取數據,能夠考慮使用brpop代替rpop,brpop是一個阻塞方法,直到獲取到數據

 

# 經過發佈訂閱模式的PUBSUB實現消息隊列

 

# 發佈者發佈消息到頻道了,頻道就是一個消息隊列。

 

# 發佈者:import redis

 

conn = redis.Redis(host='127.0.0.1',port=6379)

 

conn.publish('104.9MH', "hahahahahaha")# 訂閱者:import redis

 

conn = redis.Redis(host='127.0.0.1',port=6379)

 

pub = conn.pubsub()

 

pub.subscribe('104.9MH')while True:

 

    msg= pub.parse_response()

 

    print(msg)

 

對了,redis 作消息隊列不合適業務上避免過分複用一個redis,用它作緩存、作計算,還作任務隊列,壓力太大,很差。

 

 

 

 

 

37. 如何基於redis實現發佈和訂閱?以及發佈訂閱和消息隊列的區別?

 

# 發佈和訂閱,只要有任務就全部訂閱者每人一份。

 

發佈者: #發佈一次

 

    import redis

 

    conn = redis.Redis(host='127.0.0.1',port=6379)

 

    conn.publish('104.9MH', "hahahahahaha")

 

訂閱者: #'while True'一直在接收

 

    import redis

 

    conn = redis.Redis(host='127.0.0.1',port=6379)

 

    pub = conn.pubsub()

 

    pub.subscribe('104.9MH')

 

    while True:

 

        msg= pub.parse_response()

 

        print(msg)

 

 

 

38. 什麼是codis及做用?

 

Codis 是一個分佈式 Redis 解決方案, 對於上層的應用來講, 鏈接到 Codis Proxy 和鏈接原生的

 

Redis Server 沒有明顯的區別 (不支持的命令列表), 上層應用能夠像使用單機的 Redis 同樣使用,

 

Codis 底層會處理請求的轉發, 不停機的數據遷移等工做, 全部後邊的一切事情,

 

對於前面的客戶端來講是透明的, 能夠簡單的認爲後邊鏈接的是一個內存無限大的 Redis 服務.

 

 

 

39. 什麼是twemproxy及做用?

 

Twemproxy 也叫 nutcraker。是 Twtter 開源的一個 Redis 和 Memcache 代理服務器,

 

主要用於管理 Redis 和 Memcached 集羣,減小與Cache 服務器直接鏈接的數量

 

其功能:

 

經過代理的方式減小緩存服務器的鏈接數。

 

自動在多臺緩存服務器間共享數據。

 

經過不一樣的策略與散列函數支持一致性散列。

 

經過配置的方式禁用失敗的結點。

 

運行在多個實例上,客戶端能夠鏈接到首個可用的代理服務器。

 

支持請求的流式與批處理,於是可以下降來回的消耗。

 

 

 

40. 寫代碼實現redis事務操做。

 

使用MULTI命令即可以進入一個Redis事務。這個命令的返回值老是OK。此時,用戶能夠發出多個Redis命令。Redis會將這些命令放入隊列,而不是執行這些命令。一旦調用EXEC命令,那麼Redis就會執行事務中的全部命令。相反,調用DISCARD命令將會清除事務隊列,而後退出事務。

 

import redis

 

pool = redis.ConnectionPool(host='10.211.55.4', port=6379)

 

conn = redis.Redis(connection_pool=pool)# pipe = r.pipeline(transaction=False)

 

pipe = conn.pipeline(transaction=True)# 開始事務pipe.multi()

 

pipe.set('name', 'zgc')

 

pipe.set('role', 'haha')

 

pipe.lpush('roless', 'haha')# 提交pipe.execute()'注意':諮詢是否當前分佈式redis是否支持事務

 

 

 

41. redis中的watch的命令的做用?

 

watch 用於在進行事務操做的最後一步也就是在執行exec 以前對某個key進行監視

 

若是這個被監視的key被改動,那麼事務就被取消,不然事務正常執行.

 

通常在MULTI 命令前就用watch命令對某個key進行監控.若是想讓key取消被監控,能夠用unwatch命令

 

 

 

42. 基於redis如何實現商城商品數量計數器?

 

指定鍵的值作加加操做,返回加後的結果。

 

'經過rediswatch實現'import redis

 

conn = redis.Redis(host='127.0.0.1',port=6379)# conn.set('count',1000)

 

val = conn.get('count')print(val)

 

with conn.pipeline(transaction=True) as pipe:

 

    # 先監視,本身的值沒有被修改過

 

    conn.watch('count')

 

    # 事務開始    pipe.multi()

 

    old_count = conn.get('count')

 

    count = int(old_count)

 

    print('如今剩餘的商品有:%s',count)

 

    input("問媳婦讓不讓買?")

 

    pipe.set('count', count - 1)

 

    # 執行,把全部命令一次性推送過去    pipe.execute()

 

數據庫的鎖

 

 

 

43. 簡述redis分佈式鎖和redlock的實現機制。

 

在不一樣進程須要互斥地訪問共享資源時,分佈式鎖是一種很是有用的技術手段。  

 

一個Client想要得到一個鎖須要如下幾個操做:

 

獲得本地時間Client使用相同的key和隨機數,按照順序在每一個Master實例中嘗試得到鎖。在得到鎖的過程當中,爲每個鎖操做設置一個快速失敗時間(若是想要得到一個10秒的鎖, 那麼每個鎖操做的失敗時間設爲5-50ms)。這樣能夠避免客戶端與一個已經故障的Master通訊佔用太長時間,經過快速失敗的方式儘快的與集羣中的,其餘節點完成鎖操做。客戶端計算出與master得到鎖操做過程當中消耗的時間,當且僅當Client得到鎖消耗的時間小於鎖的存活時間,

 

而且在一半以上的master節點中得到鎖。才認爲client成功的得到了鎖。

 

若是已經得到了鎖,Client執行任務的時間窗口是鎖的存活時間減去得到鎖消耗的時間。

 

若是Client得到鎖的數量不足一半以上,或得到鎖的時間超時,那麼認爲得到鎖失敗。

 

客戶端須要嘗試在全部的master節點中釋放鎖, 即便在第二步中沒有成功得到該Master節點中的鎖,

 

仍要進行釋放操做。

 

# redis分佈式鎖?

 

# 不是單機操做,又多了一/多臺機器

 

# redis內部是單進程、單線程,是數據安全的(只有本身的線程在操做數據)

 

----------------------------------------------------------------#ABC,三個實例()

 

1、來了一個'隔壁老王'要操做,且不想讓別人操做,so,加鎖;

 

    加鎖:'隔壁老王'本身生成一個隨機字符串,設置到ABC(xxx=666)2、來了一個'鄰居老李'要操做ABC,一讀發現裏面有字符串,擦,被加鎖了,不能操做了,等着吧~

 

3'隔壁老王'解決完問題,不用鎖了,把ABC裏的key'xxx'刪掉;完成解鎖4'鄰居老李'如今能夠訪問,能夠加鎖了# 問題:

 

1、若是'隔壁老王'加鎖後忽然掛了,就沒人解鎖,就死鎖了,其餘人幹看着無法用咋辦?2、若是'隔壁老王'去給ABC加鎖的過程當中,剛加到A,'鄰居老李'就去操做C了,加鎖成功or失敗?3、若是'隔壁老王'去給ABC加鎖時,C忽然掛了,此次加鎖是成功仍是失敗?4、若是'隔壁老王'去給ABC加鎖時,超時時間爲5秒,加一個鎖耗時3秒,這次加鎖能成功嗎?# 解決

 

1、安全起見,讓'隔壁老王'加鎖時設置超時時間,超時的話就會自動解鎖(刪除key'xxx')2、加鎖程度達到(1/2+1個就表示加鎖成功,即便沒有給所有實例加鎖;3、加鎖程度達到(1/2+1個就表示加鎖成功,即便沒有給所有實例加鎖;4、不能成功,鎖還沒加完就過時,沒有意義了,應該合理設置過時時間# 注意

 

    使用須要安裝redlock-py----------------------------------------------------------------from redlock import Redlock

 

dlm = Redlock(

 

    [

 

        {"host": "localhost", "port": 6379, "db": 0},

 

        {"host": "localhost", "port": 6379, "db": 0},

 

        {"host": "localhost", "port": 6379, "db": 0},

 

    ]

 

)# 加鎖,acquire

 

my_lock = dlm.lock("my_resource_name",10000)if  my_lock:

 

    # 進行操做

 

    # 解鎖,release    dlm.unlock(my_lock)else:

 

    print('獲取鎖失敗')#經過sever.eval(self.unlock_script)執行一個lua腳本,用來刪除加鎖時的key

 

 

 

44. 什麼是一致性哈希?Python中是否有相應模塊?

 

# 一致性哈希一致性hash算法(DHT)能夠經過減小影響範圍的方式,解決增減服務器致使的數

 

據散列問題,從而解決了分佈式環境下負載均衡問題;

 

若是存在熱點數據,能夠經過增添節點的方式,對熱點區間進行劃分,將壓力分配至其餘服務器, 從新達到負載均衡的狀態。# 模塊:hash_ring

 

 

 

45. 如何高效的找到redis中全部以zhugc開頭的key?

 

redis 有一個keys命令。

 

# 語法:KEYS pattern

 

# 說明:返回與指定模式相匹配的所用的keys該命令所支持的匹配模式以下:1?:用於匹配單個字符。例如,h?llo能夠匹配hellohallohxllo等;2*:用於匹配零個或者多個

 

字符。例如,h*llo能夠匹配hlloheeeello等;2[]:能夠用來指定模式的選擇區間。例如h[ae]llo能夠匹配hellohallo,可是不能匹配hillo。同時,能夠使用「/」符號來轉義特殊的字符# 注意KEYS 的速度很是快,但若是數據太大,內存可能會崩掉,

 

若是須要從一個數據集中查找特定的key,最好仍是用Redis的集合結構(set)來代替。

 

4八、悲觀鎖和樂觀鎖的區別?

 

# 悲觀鎖    從數據開始更改時就將數據鎖住,直到更改完成才釋放;會形成訪問數據庫時間較長,併發性很差,特別是長事務。# 樂觀鎖    直到修改完成,準備提交修改到數據庫時纔會鎖住數據,完成更改後釋放;相對悲觀鎖,在現實中使用較多。

 

 前端及其餘                     

 

 

1. 談談你對http協議的認識。

 

HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它能夠使瀏覽器更加高效,使網絡傳輸減小。它不只保證計算機正確快速地傳輸超文本文檔,還肯定傳輸文檔中的哪一部分,以及哪部份內容首先顯示(如文本先於圖形)等。 

 

HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端服務器模型。HTTP是一個無狀態的協議。端口號爲80

 

 

 

2. 談談你對websocket協議的認識。

 

WebSocket是HTML5開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。

 

WebSocket API中,瀏覽器和服務器只須要作一個握手的動做,而後,瀏覽器和服務器之間就造成了,一條快速通道。二者之間就直接能夠數據互相傳送。

 

瀏覽器經過 JavaScript 向服務器發出創建 WebSocket 鏈接的請求,鏈接創建之後,

 

客戶端和服務器端就能夠經過 TCP 鏈接直接交換數據。

 

 

 

websocket是給瀏覽器新建的一套(相似與http)協議,協議規定:(\r\n分割)瀏覽器和服務器鏈接以後不斷開,

 

以此完成:服務端向客戶端主動推送消息。

 

 

 

websocket協議額外作的一些操做

 

握手  ---->  鏈接錢進行校驗

 

加密  ----> payload_len=127/126/<=125   --> mask key

 

本質

 

建立一個鏈接後不斷開的socket

 

當鏈接成功以後:

 

客戶端(瀏覽器)會自動向服務端發送消息,包含: Sec-WebSocket-Key: iyRe1KMHi4S4QXzcoboMmw==

 

服務端接收以後,會對於該數據進行加密:base64(sha1(swk + magic_string))

 

構造響應頭:

 

HTTP/1.1 101 Switching Protocols\r\n

 

Upgrade:websocket\r\n

 

Connection: Upgrade\r\n

 

Sec-WebSocket-Accept: 加密後的值\r\n

 

WebSocket-Location: ws://127.0.0.1:8002\r\n\r\n

 

發給客戶端(瀏覽器)

 

創建:雙工通道,接下來就能夠進行收發數據

 

發送數據是加密,解密,根據payload_len的值進行處理

 

payload_len <= 125

 

payload_len == 126

 

payload_len == 127

 

獲取內容:

 

mask_key

 

數據

 

根據mask_key和數據進行位運算,就能夠把值解析出來。

 

 

 

3. 什麼是magic string ?

 

有觸發時機在知足條件時自動觸發就是魔術方法,客戶端向服務端發送消息時,會有一個'sec-websocket-key''magic string'的隨機字符串(魔法字符串)

 

# 服務端接收到消息後會把他們鏈接成一個新的key串,進行編碼、加密,確保信息的安全性

 

 

 

4. 如何建立響應式佈局?

 

響應式佈局是經過@media實現的

 

@media min-width768px{

 

     .pg-header{

 

           

 

      }      

 

}

 

@media   (min-width:992px){

 

     .pg-header{

 

            

 

     }

 

}    

 

 

 

代碼

 

<!DOCTYPE html>

 

<html lang="en">

 

<head>

 

    <meta charset="UTF-8">

 

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

 

    <meta name="viewport" content="width=device-width, initial-scale=1">

 

    <title>Title</title>

 

    <style>

 

        body{

 

            margin: 0;

 

        }

 

        .pg-header{

 

            

 

            height: 48px;

 

        }

 

 

 

        @media (min-width: 768px) {

 

            .pg-header{

 

                

 

            }

 

        }

 

        @media (min-width: 992px) {

 

            .pg-header{

 

                

 

            }

 

        }

 

    </style>

 

</head>

 

<body>

 

    <div class="pg-header"></div>

 

</body>

 

</html>

 

 

 

 

 

5. 你曾經使用過哪些前端框架?

 

Bootstrap / vue、Django

 

jQuery

 

 Vue.js(vue齊名的前端框架ReactAngular)

 

 

 

6. 什麼是ajax請求?並使用jQuery和XMLHttpRequest對象實現一個ajax請求。

 

AJAX是在不加載整個頁面的狀況異步下與服務器發送請求交換數據並更新部分網頁的藝術

 

 

 

$.ajax({    url:'user/add',//當前請求的url地址    

 

type:'get',//當前請求的方式 get post   

 

data:{id:100},//請求時發送的參數    

 

dataType:'json',//返回的數據類型    

 

success:function(data){        //ajax請求成功後執行的代碼        

 

console.log(data);    },    

 

error:function(){        //ajax執行失敗後執行的代碼        

 

alert('ajax執行錯誤');    },    

 

timeout:2000,//設置當前請求的超時時間 異步請求生效    

 

async:true //是否異步 false同步 true異步})

 

 

 

7. 如何在前端實現輪訓?

 

特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP request,

 

而後由服務器返回最新的數據給客戶端的瀏覽器。

 

<!DOCTYPE html>

 

<html lang="zh-cn">

 

<head>

 

    <meta charset="UTF-8">

 

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

 

    <meta name="viewport" content="width=device-width, initial-scale=1">

 

    <title>Title</title>

 

</head>

 

<body>

 

    <h1>請選出最帥的男人</h1>

 

    <ul>

 

        {% for k,v in gg.items() %}

 

            <li>ID:{{ k }}, 姓名:{{ v.name }} ,票數:{{ v.count }}</li>

 

        {% endfor %}

 

    </ul>

 

 

 

    <script>

 

        setInterval(function () {

 

            location.reload();

 

        },2000)

 

    </script>

 

</body>

 

</html>

 

 

 

8. 如何在前端實現長輪訓?

 

ajax實現:在發送ajax後,服務器端會阻塞請求直到有數據傳遞或超時纔會返回,

 

客戶端js響應處理函數會在處理完服務器返回的信息後在次發出請求,

 

從新創建鏈接

 

 

 

<!DOCTYPE html>

 

<html lang="zh-cn">

 

<head>

 

    <meta charset="UTF-8">

 

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

 

    <meta name="viewport" content="width=device-width, initial-scale=1">

 

    <title>Title</title>

 

</head>

 

<body>

 

    <h1>請選出最帥的男人</h1>

 

    <ul>

 

        {% for k,v in gg.items() %}

 

            <li style="cursor: pointer" id="user_{{ k }}" ondblclick="vote({{ k }});">ID:{{ k }}, 姓名:{{ v.name }} ,票數:<span>{{ v.count }}</span></li>

 

        {% endfor %}

 

    </ul>

 

 

 

    <script src="/static/jquery-3.3.1.min.js"></script>

 

    <script>

 

        $(function () {

 

            get_new_count();

 

        });

 

        

 

        function get_new_count() {

 

            $.ajax({

 

                url: '/get_new_count',

 

                type:'GET',

 

                dataType:'JSON',

 

                success:function (arg) {

 

                    if (arg.status){

 

                        // 更新票數

 

                        var gid = "#user_" + arg.data.gid;

 

                        $(gid).find('span').text(arg.data.count);

 

                    }else{

 

                        // 10s內沒有人投票                    }

 

                    get_new_count();

 

 

 

                }

 

            })

 

        }

 

 

 

        function vote(gid) {

 

            $.ajax({

 

                url: '/vote',

 

                type:'POST',

 

                data:{gid:gid},

 

                dataType:"JSON",

 

                success:function (arg) {

 

 

 

                }

 

            })

 

        }

 

    </script>

 

</body>

 

</html>

 

 

 

 

 

9. vuex的做用?

 

多組件之間共享:vuex

 

補充luffyvue

 

1:router-link / router-view

 

2:雙向綁定,用戶綁定v-model

 

3:循環展現課程:v-for

 

4:路由系統,添加動態參數

 

5cookie操做:vue-cookies

 

6:多組件之間共享:vuex

 

7:發送ajax請求:axios (js模塊)

 

 

 

10. vue中的路由的攔截器的做用?

 

vue-resourceinterceptors攔截器的做用正是解決此需求的妙方。
在每次http的請求響應以後,若是設置了攔截器以下,會優先執行攔截器函數,獲取響應體,而後纔會決定是否把response返回給then進行接收

 

 

 

11. axios的做用?

在瀏覽器中發送 XMLHttpRequests 請求

node.js 中發送 http請求

支持 Promise API

攔截請求和響應

轉換請求和響應數據

自動轉換 JSON 數據

客戶端支持保護安全免受 XSRF 攻擊

 

12. 列舉vue的常見指令。

1v-if指令:判斷指令,根據表達式值得真假來插入或刪除相應的值。

   2v-show指令:條件渲染指令,不管返回的布爾值是true仍是false,元素都會存在在 html中,只是false的元素會隱藏在html中,並不會刪除.

   3v-else指令:配合v-ifv-else使用。

   4v-for指令:循環指令,至關於遍歷。

   5v-bind:DOM綁定元素屬性。

   6v-on指令:監聽DOM事件。

 

13. 簡述jsonp及實現原理?

JSONP是用來解決跨域請求問題的 

跨域:協議 域名 端口號有一個不同就是跨域 

實現原理: 

script標籤src屬性中的連接卻能夠訪問跨域的js腳本,利用這個特性,服務端再也不返回JSON格式的數據,

而是返回一段調用某個函數的js代碼,在src中進行了調用,這樣實現了跨域。

 

14.什麼是什麼cors ?

CORS

瀏覽器將CORS請求分紅兩類:簡單請求和賦複雜請求

 

簡單請求(同時知足如下兩大條件)

1)請求方法是如下三種方法之一:

HEAD

GET

POST

2HTTP的頭信息不超出如下幾種字段:

Accept

Accept-Language

Content-Language

Last-Event-ID

Content-Type  :只限於三個值application/x-www-form-urlencodedmultipart/form-datatext/plain

凡是不一樣時知足上面兩個條件,就屬於非簡單請求

 

15. 列舉Http請求中常見的請求方式?

GET/POST

 

16. 列舉Http請求中的狀態碼?

1**  信息,服務器收到請求,須要請求者繼續執行操做

2**  成功,操做被成功接收並處理

3** 重定向,須要進一步的操做以完成請求

4** 客戶端錯誤,請求包含語法錯誤或沒法完成請求

5** 服務器錯誤,服務器在處理請求的過程當中發生了錯誤

 

常見的狀態碼

200 -請求成功
202 -已接受請求,還沒有處理
204 -請求成功,且不需返回內容

301 - 資源(網頁等)被永久轉移到其餘url
400 - 請求的語義或是參數有錯
403 - 服務器拒絕請求

404 - 請求資源(網頁)不存在

500 - 內部服務器錯誤
502 - 網關錯誤,通常是服務器壓力過大致使鏈接超時
503 - 因爲超載或系統維護,服務器暫時的沒法處理客戶端的請求

 

17.列舉Http請求中常見的請求頭?

User-Agent:瀏覽器類型,若是Servlet返回的內容與瀏覽器類型有關則該值很是有用。

Cookie:這是最重要的請求頭信息之一

Content-Type:請求類型

 

18.alert(李傑)

 

19.console.log('武沛齊')

 

20.

console.log(‘老男孩’)

 

21.結果什麼也沒有 由於console.log.的時候xo尚未定義

 

22.alert(」武沛齊’)

 

23.alert(」武沛齊’)

 

24.

Django:Python 界最全能的 web 開發框架,battery-include 各類功能完備,可維護性和開發速度一級棒。

常有人說 Django 慢,其實主要慢在 Django ORM 與數據庫的交互上,因此是否選用 Django,

取決於項目對數據庫交互的要求以及各類優化。而對於 Django 的同步特性致使吞吐量小的問題,

其實能夠經過 Celery 等解決,倒不是一個根本問題。Django 的項目表明:Instagram,Guardian。

Tornado:天生異步,性能強悍是 Tornado 的名片,然而 Tornado 相比 Django 是較爲原始的框架,諸多內容須要本身去處理。固然,隨着項目愈來愈大,框架可以提供的功能佔比愈來愈小,

更多的內容須要團隊本身去實現,而大項目每每須要性能的保證,這時候 Tornado 就是比較好的選擇。Tornado項目表明:知乎。

Flask:微框架的典範,號稱 Python 代碼寫得最好的項目之一。Flask 的靈活性,也是雙刃劍:

能用好 Flask 的,能夠作成 Pinterest,用很差就是災難(顯然對任何框架都是這樣)。

Flask 雖然是微框架,可是也能夠作成規模化的 Flask。加上 Flask 能夠自由選擇本身的數據庫交互組件

(一般是 Flask-SQLAlchemy),並且加上 celery +redis 等異步特性之後,Flask 的性能相對

Tornado 也不逞多讓,也許Flask 的靈活性多是某些團隊更須要的。

 

25.什麼是wsgi?

WSGI(Web Server Gateway Interface,Web 服務器網關接口)則是Python語言中1所定義的Web服務器和Web應用程序之間或框架之間的通用接口標準。

WSGI就是一座橋樑,橋樑的一端稱爲服務端或網關端,另外一端稱爲應用端或者框架端,WSGI的做用就是在協議之間進行轉化。WSGI將Web組件分紅了三類:Web 服務器(WSGI Server)、Web中間件(WSGI Middleware)與Web應用程序(WSGI Application)。

Web Server接收HTTP請求,封裝一系列環境變量,按照WSGI接口標準調用註冊的WSGI Application,最後將響應返回給客戶端。

 

 

26.django請求的生命週期?

前端請求—>nginx—>uwsgi.—>中間件—>url路由—->view試圖—>orm—->拿到數據返回給view—->試圖將數據渲染到模版中拿到字符串—->中間件—>uwsgi—->nginx—->前端渲染

 

 

27. 列舉django的內置組件?

url 、view、model、template、中間件

 

28. 列舉django中間件的5個方法?以及django中間件的應用場景?

process_request(self,request)  先走request 經過路由匹配返回

process_view(self, request, callback, callback_args, callback_kwargs) 再返回執行view

process_template_response(self,request,response)   當視圖函數的返回值

process_exception(self, request, exception)  當視圖函數的返回值對象中有render方法時,該方法纔會被調用

process_response(self, request, response)

 

29. 簡述什麼是FBV和CBV?

django中請求處理方式有2種:FBV 和 CBV

FBV(function base views) 就是在視圖裏使用函數處理請求。

CBV(class base views)就是在視圖裏使用類處理請求 類須要繼承view

 

30. django的request對象是在何時建立的?

當請求一個頁面時,Django會創建一個包含請求元數據的 HttpRequest 對象。

Django 加載對應的視圖時,HttpRequest 對象將做爲視圖函數的第一個參數。

每一個視圖會返回一個HttpResponse 對象。

 

31. 如何給CBV的程序添加裝飾器?

from django.views import View  

from django.utils.decorators import method_decorator   

def auth(func):      

def inner(*args,**kwargs):          

return func(*args,**kwargs)      

return inner   

class UserView(View):                             

@method_decorator(auth)      

def get(self,request,*args,**kwargs):          

return HttpResponse('...')

 

 

32. 列舉django orm 中全部的方法(QuerySet對象的全部方法)

返回Query Set對象的方法有: 

* all() * filter() * exclude() * order_by() * reverse() * dictinct()

 

特殊的QuerySet: 

* values() 返回一個可迭代的字典序列 

* values_list() 返回一個可迭代的元祖序列

 

返回具體對象的: 

* get() * first() * last()

 

返回布爾值的方法有: * existe()

 

返回數學的方法有: * count( )

 

  1. only和defer的區別?

 

def defer(self, *fields):

    models.UserInfo.objects.defer('username','id')

    

    models.UserInfo.objects.filter(...).defer('username','id')

    #映射中排除某列數據

 

 def only(self, *fields):

    #僅取某個表中的數據

     models.UserInfo.objects.only('username','id')

     

     models.UserInfo.objects.filter(...).only('username','id')

 

34. select_related和prefetch_related的區別?

select_related經過多表join關聯查詢,一次性得到全部數據,經過下降數據庫查詢次數來提高性能,

但關聯表不能太多,由於join操做原本就比較消耗性能

prefetch_related()的解決方法是,分別查詢每一個表,而後用Python處理他們之間的關係! 

都是爲了減小SQL查詢的數量

 

 

35. filter和exclude的區別?

filter是查詢知足條件的數據

exclude是查詢不知足添加的數據

def filter(self, *args, **kwargs)

      # 條件查詢(符合條件)

       # 查出符合條件

      # 條件能夠是:參數,字典,Q

 

  def exclude(self, *args, **kwargs)

      # 條件查詢(排除條件)

      # 排除不想要的

      # 條件能夠是:參數,字典,Q

 

36. 列舉django orm中三種能寫sql語句的方法。

原生SQL --->  connection

from django.db import connection, connections

cursor = connection.cursor()  # cursor = connections['default'].cursor()

cursor.execute("""SELECT * from auth_user where id = %s""", [1])

row = cursor.fetchone() # fetchall()/fetchmany(..)
靠近原生SQL-->extra\raw

extra

- extra

    def extra(self, select=None, where=None, params=None, tables=None, order_by=None,

select_params=None)

        # 構造額外的查詢條件或者映射,如:子查詢

        Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"},

 select_params=(1,))

        Entry.objects.extra(where=['headline=%s'], params=['Lennon'])

        Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])

        Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, s

elect_params=(1,), order_by=['-nid'])

 

- raw

def raw(self, raw_query, params=None, translations=None, using=None):

    # 執行原生SQL

    models.UserInfo.objects.raw('select * from userinfo')

    # 若是SQL是其餘表時,必須將名字設置爲當前UserInfo對象的主鍵列名

    models.UserInfo.objects.raw('select id as nid,name as title  from 其餘表')

    # 爲原生SQL設置參數

    models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,])

    # 將獲取的到列名轉換爲指定列名

    name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}

    Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)

    # 指定數據庫

    models.UserInfo.objects.raw('select * from userinfo', using="default")

 

37. django orm 中如何設置讀寫分離?

 

方式一:手動使用querysetusing方法

from django.shortcuts import render,HttpResponse

from app01 import models

def index(request):

 

    models.UserType.objects.using('db1').create(title='普通用戶')

  # 手動指定去某個數據庫取數據

    result = models.UserType.objects.all().using('db1')

    print(result)

 

    return HttpResponse('...')

 

方式二:寫配置文件

class Router1:

  #  指定到某個數據庫取數據

    def db_for_read(self, model, **hints):

        """

        Attempts to read auth models go to auth_db.

        """

        if model._meta.model_name == 'usertype':

            return 'db1'

        else:

            return 'default'

   # 指定到某個數據庫存數據

    def db_for_write(self, model, **hints):

        """

        Attempts to write auth models go to auth_db.

        """

        return 'default'

再寫到配置

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.sqlite3',

        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

    },

    'db1': {

        'ENGINE': 'django.db.backends.sqlite3',

        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

    }

}

DATABASE_ROUTERS = ['db_router.Router1',]

 

38. F和Q的做用?

F:操做數據表中的某列值,F( )容許Django在未實際連接數據的狀況下具備對數據庫字段的值的引用,

不用獲取對象放在內存中再對字段進行操做,直接執行原生產sql語句操做。

一般狀況下咱們在更新數據時須要先從數據庫裏將原數據取出後方在內存裏,而後編輯某些屬性,最後提交

Q:對對象進行復雜查詢,並支持&(and),|(or),~(not)操做符。

 

39. values和values_list的區別?

values方法能夠獲取number字段的字典列表。

values_list能夠獲取number的元組列表。

values_list方法加個參數flat=True能夠獲取number的值列表。

 

def values(self, *fields):

     # 獲取每行數據爲字典格式

 

def values_list(self, *fields, **kwargs):

     # 獲取每行數據爲元祖

 

40. 如何使用django orm批量建立數據?

  def bulk_create(self, objs, batch_size=None):

        # 批量插入

        # batch_size表示一次插入的個數

        objs = [

            models.DDD(name='r11'),

            models.DDD(name='r22')

        ]

        models.DDD.objects.bulk_create(objs, 10)

 

41. django的Form和ModeForm的做用?

- 做用:

      - 對用戶請求數據格式進行校驗

      - 自動生成HTML標籤

  - 區別:

      - Form,字段須要本身手寫。

          class Form(Form):

              xx = fields.CharField(.)

              xx = fields.CharField(.)

              xx = fields.CharField(.)

              xx = fields.CharField(.)

      - ModelForm,能夠經過Meta進行定義

          class MForm(ModelForm):

              class Meta:

                  fields = "__all__"

                  model = UserInfo                            

  - 應用:只要是客戶端向服務端發送表單數據時,均可以進行使用,如:用戶登陸註冊

 

42. django的Form組件中,若是字段中包含choices參數,請使用兩種方式實現數據源實時更新。

方式一:重寫構造方法,在構造方法中從新去數據庫獲取值

  class UserForm(Form):

      name = fields.CharField(label='用戶名',max_length=32)

      email = fields.EmailField(label='郵箱')

      ut_id = fields.ChoiceField(

          # choices=[(1,'普通用戶'),(2,'IP用戶')]

          choices=[]

      )

 

      def __init__(self,*args,**kwargs):

          super(UserForm,self).__init__(*args,**kwargs)

 

          self.fields['ut_id'].choices = models.UserType.objects.all().values_list('id','title')

  
方式二: ModelChoiceField字段

  from django.forms import Form

  from django.forms import fields

  from django.forms.models import ModelChoiceField

  class UserForm(Form):

      name = fields.CharField(label='用戶名',max_length=32)

      email = fields.EmailField(label='郵箱')

      ut_id = ModelChoiceField(queryset=models.UserType.objects.all())    

 

  依賴:

      class UserType(models.Model):

          title = models.CharField(max_length=32)

 

          def __str__(self):

              return self.title

 

43. django的Model中的ForeignKey字段中的on_delete參數有什麼做用?

on_delete有CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET()五個可選擇的值

CASCADE:此值設置,是級聯刪除。

PROTECT:此值設置,是會報完整性錯誤。

SET_NULL:此值設置,會把外鍵設置爲null,前提是容許爲null。

SET_DEFAULT:此值設置,會把設置爲外鍵的默認值。

SET():此值設置,會調用外面的值,能夠是一個函數。

 

44. django中csrf的實現機制

Django預防CSRF攻擊的方法是在用戶提交的表單中加入一個csrftoken的隱含值,這個值和服務器中保存的csrftoken的值相同,這樣作的原理以下:

一、在用戶訪問django的可信站點時,django反饋給用戶的表單中有一個隱含字段csrftoken,這個值是在服務器端隨機生成的,每一次提交表單都會生成不一樣的值

二、當用戶提交django的表單時,服務器校驗這個表單的csrftoken是否和本身保存的一致,來判斷用戶的合法性

三、當用戶被csrf攻擊從其餘站點發送精心編制的攻擊請求時,因爲其餘站點不可能知道隱藏的csrftoken字段的信息這樣在服務器端就會校驗失敗,攻擊被成功防護

具體配置以下:template中添加{%csrf_token%}標籤

 

45. django如何實現websocket?

利用dwebsocket在Django中使用Websocket

django中能夠經過channel實現websocke

 

46. 基於django使用ajax發送post請求時,均可以使用哪一種方法攜帶csrf token?

//方式一給每一個ajax都加上上請求頭

    function Do1(){

        $.ajax({

            url:"/index/",

            data:{id:1},

            type:'POST',

       data:{csrfmiddlewaretoken:'{{ csrf_token }}',name:'alex'}

            success:function(data){

                console.log(data);

            }

        });

    }

方式二:須要先下載jQuery-cookie,才能去cookie中獲取token

        function Do1(){

        $.ajax({

            url:"/index/",

            data:{id:1},

            type:'POST',

            headers:{

              'X-CSRFToken':$.cookie('csrftoken')  // cookie中獲取

            },

            success:function(data){

                console.log(data);

            }

        });

    }

方式三:搞個函數ajaxSetup,當有多的ajax請求,即會執行這個函數

        $.ajaxSetup({

           beforeSend:function (xhr,settings) {

               xhr.setRequestHeader("X-CSRFToken",$.cookie('csrftoken'))

           }

        });

 

函數版本

<body>

<input type="button" onclick="Do1();"  value="Do it"/>

<input type="button" onclick="Do2();"  value="Do it"/>

<input type="button" onclick="Do3();"  value="Do it"/>

 

<script src="/static/jquery-3.3.1.min.js"></script>

<script src="/static/jquery.cookie.js"></script>

<script>

    $.ajaxSetup({

        beforeSend: function(xhr, settings) {

            xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));

        }

    });

 

     function Do1(){

        $.ajax({

            url:"/index/",

            data:{id:1},

            type:'POST',

            success:function(data){

                console.log(data);

            }

        });

    }

 

     function Do2(){

        $.ajax({

            url:"/index/",

            data:{id:1},

            type:'POST',

            success:function(data){

                console.log(data);

            }

        });

    }

 

     function Do3(){

        $.ajax({

            url:"/index/",

            data:{id:1},

            type:'POST',

            success:function(data){

                console.log(data);

            }

        });

    }

</script>

</body>

 

47. django中如何實現orm表中添加數據時建立一條日誌記錄。

 

settings.py中添加:

LOGGING = {

'disable_existing_loggers': False,

'version': 1,

'handlers': {

'console': {

# logging handler that outputs log messages to terminal

'class': 'logging.StreamHandler',

'level': 'DEBUG', # message level to be written to console

},

},

'loggers': {

'': {

# this sets root level logger to log debug and higher level

# logs to console. All other loggers inherit settings from

# root level logger.

'handlers': ['console'],

'level': 'DEBUG',

'propagate': False, # this tells logger to send logging message

# to its parent (will send if set to True)

},

'django.db': {

# # django also has database level logging

'handlers': ['console'],

'level': 'DEBUG',

'propagate': False,

},

},

}

 

 

48. django緩存如何設置?

  三種粒度緩存

   1 中間件級別

       'django.middleware.cache.UpdateCacheMiddleware',

       'django.middleware.cache.FetchFromCacheMiddleware',

        CACHE_MIDDLEWARE_SECONDS=10

 

   2 視圖級別

      from django.views.decorators.cache import cache_page

      @cache_page(15)

      def index(request):

          import time

          t=time.time()

          return render(request,"index.html",locals())

 

   3 局部緩存

      {% load cache %}

          ...

          ...

      {% cache 15 "time_cache" %}

      <h3>緩存時間:{{ t }}</h3>

      {% endcache %}

 

49. django的緩存能使用redis嗎?若是能夠的話,如何配置?

pip install django-redis  

   apt-get install redis-serv

 

setting添加配置文件

CACHES = {

    "default": {

        "BACKEND": "django_redis.cache.RedisCache", # 緩存類型

        "LOCATION": "127.0.0.1:6379", # ip端口

        "OPTIONS": {

            "CLIENT_CLASS": "django_redis.client.DefaultClient",  #

            "CONNECTION_POOL_KWARGS": {"max_connections": 100} # 鏈接池最大鏈接數

            # "PASSWORD": "密碼",        }

    }

}

 

 

使用

from django.shortcuts import render,HttpResponse

from django_redis import get_redis_connection

  

def index(request):

# 根據名字去鏈接池中獲取鏈接

conn = get_redis_connection("default")

    conn.hset('n1','k1','v1') # 存數據

    return HttpResponse('...')

 

50. django路由系統中name的做用?

反向解析路由字符串

路由系統中name的做用:反向解析
url(r'^home', views.home, name='home')
在模板中使用:{ % url 'home' %}
在視圖中使用:reverse(「home」

51. django的模板中filter和simple_tag的區別?

filter : 相似管道,只能接受兩個參數第一個參數是|前的數據

simple_tag : 相似函數

一、模板繼承:{ % extends 'layouts.html' %}
二、自定義方法
     'filter':只能傳遞兩個參數,能夠在if、for語句中使用
     'simple_tag':能夠無線傳參,不能在if for中使用
     'inclusion_tags':能夠使用模板和後端數據
三、防xss攻擊: '|safe''mark_safe'

52. django-debug-toolbar的做用?

django_debug_toolbar 是django的第三方工具包,給django擴展了調試功能。

包括查看執行的sql語句,db查詢次數,request,headers,調試概覽等。

https://blog.csdn.net/weixin_39198406/article/details/78821677

 

53. django中如何實現單元測試?

對於每個測試方法都會將setUp()tearDown()方法執行一遍

會單獨新建一個測試數據庫來進行數據庫的操做方面的測試,默認在測試完成後銷燬。

 

 

 

 

在測試方法中對數據庫進行增刪操做,最後都會被清除。也就是說,在test_add中插入的數據,在test_add測試結 束後插入的數據會被清除。

 

django單元測試時爲了模擬生產環境,會修改settings中的變量,例如, DEBUG變量修改成True, ALLOWED_HOSTS修改成[*]

 

 

 

 

 

  1. 解釋orm中 db first 和 code first的含義?

 

db first: 先建立數據庫,再更新表模型

 

code first:先寫表模型,再更新數據庫

 

 

 

datebase first就是表明數據庫優先,那麼前提就是先建立數據庫。

 

model first就是表明model優先,那麼前提也就是先建立model,而後根據model自動創建數據庫。

 

 

 

55. django中如何根據數據庫表生成model中的類?

 

1、修改seting文件,在setting裏面設置要鏈接的數據庫類型和名稱、地址

 

2、運行下面代碼能夠自動生成models模型文件

 

       - python manage.py inspectdb

 

3、建立一個app執行下下面代碼:

 

       - python manage.py inspectdb > app/models.py

 

 

 

56. 使用orm和原生sql的優缺點?

 

ORM框架:

 

  對象關係映射,經過建立一個類,這個類與數據庫的表相對應!類的對象代指數據庫中的一行數據。

 

簡述ORM原理:

 

  讓用戶再也不寫SQL語句,而是經過類以及對象的方式,和其內部提供的方法,進行數據庫操做!把用戶輸入的類或對象轉換成SQL語句,轉換以後經過pymysql執行完成數據庫的操做。

 

ORM的優缺點:

 

優勢: 

 

* 提升開發效率,下降開發成本 

 

* 使開發更加對象化 

 

* 可移植 

 

* 能夠很方便地引入數據緩存之類的附加功能

 

缺點: 

 

* 在處理多表聯查、where條件複雜之類的查詢時,ORM的語法會變得複雜。就須要寫入原生SQL

 

 

 

57. 簡述MVC和MTV

 

MVC: 模型 視圖 控制器

 

MTV: 模型 模板 視圖

 

 

 

58. django的contenttype組件的做用?

 

django內置的ContentType組件就是幫咱們作連表操做

 

若是一個表與其餘表有多個外鍵關係,咱們能夠經過ContentType來解決這種關聯

 

http://www.cnblogs.com/iyouyue/p/8810464.html

 

 

 

59. 談談你對restfull 規範的認識?

 

restful其實就是一套編寫接口的協議,協議規定如何編寫以及如何設置返回值、狀態碼等信息。 

 

最顯著的特色: 

 

restful: 給用戶一個url,根據method不一樣在後端作不一樣的處理,好比:post 建立數據、get獲取數據、put和patch修改數據、delete刪除數據。 

 

no rest: 給調用者不少url,每一個url表明一個功能,好比:add_user/delte_user/edit_user/

 

固然,還有協議其餘的,好比: 

 

版本,來控制讓程序有多個版本共存的狀況,版本能夠放在 url、請求頭(accept/自定義)、GET參數

 

狀態碼,200/300/400/500

 

url中儘可能使用名詞,restful也能夠稱爲「面向資源編程」

 

api標示: 

 

api.YueNet.com 

 

www.YueNet.com/api/

 

 

 

 

 

60. 接口的冪等性是什麼意思?

 

一個接口經過首先進行1次訪問,而後對該接口進行N次相同訪問的時候,對訪問對象不形成影響,那麼就認爲接口具備冪等性。 

 

好比: 

 

* GET, 第一次獲取數據、第二次也是獲取結果,冪等。 

 

* POST, 第一次新增數據,第二次也會再次新增,非冪等。 

 

* PUT, 第一次更新數據,第二次不會再次更新,冪等。 

 

* PATCH,第一次更新數據,第二次可能再次更新,非冪等。 

 

* DELTE,第一次刪除數據,第二次不會再次刪除,冪等。

 

 

 

 

 

61. 什麼是RPC?

 

RPC(Remote Procedure Call)—遠程過程調用,它是一種經過網絡從遠程計算機程序上請求服務,而不須要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,爲通訊程序之間攜帶信息數據。在OSI網絡通訊模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分佈式多程序在內的應用程序更加容易。

 

 

 

62. Http和Https的區別?

 

超文本傳輸協議HTTP協議被用於在Web瀏覽器和網站服務器之間傳遞信息,HTTP協議以明文方式發送內容,不提供任何方式的數據加密,若是攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就能夠直接讀懂其中的信息,所以,HTTP協議不適合傳輸一些敏感信息,好比:信用卡號、密碼等支付信息。

 

爲了解決HTTP協議的這一缺陷,須要使用另外一種協議:安全套接字層超文本傳輸協議HTTPS,爲了數據傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證服務器的身份,併爲瀏覽器和服務器之間的通訊加密。

 

#Http: 80端口

 

#https: 443端口

 

# http信息是明文傳輸,https則是具備安全性的ssl加密傳輸協議。

 

#- 自定義證書

 

    - 服務端:建立一對證書

 

    - 客戶端:必須攜帶證書

 

#- 購買證書

 

    - 服務端: 建立一對證書,。。。。

 

    - 客戶端: 去機構獲取證書,數據加密後發給我們的服務單

 

    - 證書機構:公鑰給改機構

 

 

 

6三、爲何要使用django rest framework框架?

 

 

 

1.客戶端-服務端分離 

 

優勢:提升用戶界面的便攜性,經過簡化服務器提升可伸縮性…. 

 

2.無狀態(Stateless):從客戶端的每一個請求要包含服務器所須要的全部信息 

 

優勢:提升可見性(能夠單獨考慮每一個請求),提升了可靠性(更容易從局部故障中修復),提升可擴展性(下降了服務器資源使用) 

 

3.緩存(Cachable):服務器返回信息必須被標記是否能夠緩存,若是緩存,客戶端可能會重用以前的信息發送請求 

 

優勢:減小交互次數,減小交互的平均延遲 

 

4.統一接口 

 

優勢:提升交互的可見性,鼓勵單獨改善組件 

 

5.支持按需代碼(Code-On-Demand 可選) 

 

優勢:提升可擴展性

 

 

 

6四、django rest framework框架中都有那些組件?

 

 

 

#- 路由,自動幫助開發者快速爲一個視圖建立4url

 

        www.oldboyedu.com/api/v1/student/$

 

        www.oldboyedu.com/api/v1/student(?P<format>\w+)$

 

        www.oldboyedu.com/api/v1/student/(?P<pk>\d+)/$

 

        www.oldboyedu.com/api/v1/student/(?P<pk>\d+)(?P<format>\w+)$

 

#- 版本處理

 

    - 問題:版本均可以放在那裏?

 

            - url

 

            - GET

 

            - 請求頭

 

#- 認證

 

    - 問題:認證流程?

 

#- 權限

 

    - 權限是否能夠放在中間件中?以及爲何?

 

#- 訪問頻率的控制    匿名用戶能夠真正的防止?沒法作到真正的訪問頻率控制,只能把小白拒之門外。

 

    若是要封IP,使用防火牆來作。

 

    登陸用戶能夠經過用戶名做爲惟一標示進行控制,若是有人註冊不少帳號,則沒法防止。

 

#- 視圖

 

#- 解析器 ,根據Content-Type請求頭對請求體中的數據格式進行處理。request.data

 

#- 分頁

 

#- 序列化

 

    - 序列化

 

        - source

 

        - 定義方法

 

    - 請求數據格式校驗

 

#- 渲染器 

 

 

 

6五、django rest framework框架中的視圖均可以繼承哪些類?

 

a. 繼承APIView(最原始)但定製性比較強

 

    這個類屬於rest framework中的頂層類,內部幫助咱們實現了只是基本功能:認證、權限、頻率控制,

 

但凡是數據庫、分頁等操做都須要手動去完成,比較原始。

 

    class GenericAPIView(APIView)

 

    def post(...):

 

          pass

 

 

 

b.繼承GenericViewSetViewSetMixingenerics.GenericAPIView

 

  首先他的路由就發生變化

 

    若是繼承它以後,路由中的as_view須要填寫對應關係

 

  在內部也幫助咱們提供了一些方便的方法:

 

  get_queryset

 

  get_object

 

  get_serializer

 

  get_serializer_class

 

  get_serializer_context

 

  filter_queryset

 

注意:要設置queryset字段,不然會拋出斷言的異常。

 

 

 

代碼

 

只提供增長功能 只繼承GenericViewSet

 

 

 

class TestView(GenericViewSet):

 

  serialazer_class = xxx

 

  def creat(self,*args,**kwargs):

 

    pass  # 獲取數據並對數據

 

c. 繼承  modelviewset  --> 快速快發

 

    -ModelViewSet(增刪改查全有+數據庫操做)

 

    -mixins.CreateModelMixin(只有增),GenericViewSet

 

    -mixins.CreateModelMixin,DestroyModelMixin,GenericViewSet

 

  對數據庫和分頁等操做不用咱們在編寫,只須要繼承相關類便可。

 

  

 

示例:只提供增長功能

 

class TestView(mixins.CreateModelMixin,GenericViewSet):

 

    serializer_class = XXXXXXX

 

***

 

  modelviewset --> 快速開發,複雜點的genericviewapiview

 

 

6六、簡述 django rest framework框架的認證流程。

 

如何編寫?寫類並實現authticate

方法中能夠定義三種返回值: 

user,auth),認證成功

None , 匿名用戶

異常 ,認證失敗

流程: 

dispatch

再去request中進行認證處理

 

6七、django rest framework如何實現的用戶訪問頻率控制?

a. 基於用戶IP限制訪問頻率

b. 基於用戶IP顯示訪問頻率(利於Django緩存) 

c. view中限制請求頻率

d. 匿名時用IP限制+登陸時用Token限制

# 對匿名用戶,根據用戶IP或代理IP做爲標識進行記錄,爲每一個用戶在redis中建一個列表    {

        throttle_1.1.1.1:[1526868876.497521,152686885.497521...]

        throttle_1.1.1.2:[1526868876.497521,152686885.497521...]

        throttle_1.1.1.3:[1526868876.497521,152686885.497521...]

    }

 每一個用戶再來訪問時,需先去記錄中剔除過時記錄,再根據列表的長度判斷是否能夠繼續訪問。

 '如何封IP':在防火牆中進行設置

--------------------------------------------------------------------------

# 對註冊用戶,根據用戶名或郵箱進行判斷。    {

        throttle_xxxx1:[1526868876.497521,152686885.497521...]

        throttle_xxxx2:[1526868876.497521,152686885.497521...]

        throttle_xxxx3:[1526868876.497521,152686885.497521...]

    }

每一個用戶再來訪問時,需先去記錄中剔除過時記錄,再根據列表的長度判斷是否能夠繼續訪問。

\1分鐘:40次,列表長度限制在40,超過40則不可訪問

 

6八、Flask框架的優點?

1、總體設計方面

首先,二者都是很是優秀的框架。總體來說,二者設計的哲學是區別最大的地方。Django提供一站式的解決方案,從模板、ORM、Session、Authentication等等都分配好了,連app劃分都作好了,總之,爲你作儘可能多的事情,並且還有一個killer級的特性,就是它的admin,配合django-suit,後臺就出來了,其實最初Django就是由在新聞發佈公司工做的人設計的。Flask只提供了一些核心功能,很是簡潔優雅。它是一個微框架,其餘的由擴展提供,但它的blueprint使它也可以很方便的進行水平擴展。

2、路由設計

Django的路由設計是採用集中處理的方法,利用正則匹配。Flask也能這麼作,但更多的是使用裝飾器的形式,這個有優勢也有缺點,優勢是讀源碼時看到函數就知道怎麼用的,缺點是一旦源碼比較長,你要查路由就不太方便了,但這也促使你去思考如何更合理的安排代碼。

3、應用模塊化設計

Django的模塊化是集成在命令裏的,也就是說一開始Django的目標就是爲之後玩大了作準備的。每一個都是一個獨立的模塊,爲之後的複用提供了便利。Flask經過Blueprint來提供模塊化,本身對項目結構劃分紅不一樣的模塊進行組織。

 

6九、Flask框架依賴組件?

Route(路由)

templates(模板)

Models(orm模型)

blueprint(藍圖)

Jinja2模板引擎

     依賴werkzurg協議

 

70、Flask藍圖的做用?

將不一樣的功能模塊化

構建大型應用

優化項目結構

加強可讀性,易於維護(跟Django的view功能類似)

# blueprint把實現不一樣功能的module分開.也就是把一個大的App分割成各自實現不一樣功能的module.

# 在一個blueprint中能夠調用另外一個blueprint的視圖函數, 但要加相應的blueprint.

 

7一、列舉使用過的Flask第三方組件?

 

內置: - 配置 - 路由 - 視圖 - 模板 - session - 閃現 - 藍圖 - 中間件 - 特殊裝飾器 

第三方: - Flask組件: - flask-session - flask-SQLAlchemy - flask-migrate 

- flask-script - blinker -

公共組件: - wtforms - dbutile - sqlalchemy - 自定義Flask組件 - auth ,參考flask- login組件

 

7二、簡述Flask上下文管理流程?

 

a、簡單來講,falsk上下文管理能夠分爲三個階段:

  1'請求進來時':將請求相關的數據放入上下問管理中

  2'在視圖函數中':要去上下文管理中取值

  3'請求響應':要將上下文管理中的數據清除

# b、詳細點來講:

  1'請求剛進來'

        requestsession封裝在RequestContext類中

        appg封裝在AppContext類中

        並經過LocalStackrequestcontextappcontext放入Local類中

  2'視圖函數中'

        經過localproxy--->偏函數--->localstack--->local取值

  3'請求響應時'

        先執行save.session()再各自執行pop(),local中的數據清除

 

7三、Flask中的g的做用?

 g是貫穿於一次請求的全局變量,當請求進來將gcurrent_app封裝爲一個APPContext類,再經過LocalStackAppcontext放入Local中,取值時經過偏函數在LocalStacklocal中取值;響應時將local中的g數據刪除

 

7四、Flask中上下文管理主要涉及到了那些相關的類?並描述類主要做用?

 

RequestContext  #封裝進來的請求(賦值給ctx

AppContext      #封裝app_ctx

LocalStack      #local對象中的數據維護成一個棧(先進後出)

Local           #保存請求上下文對象和app上下文對象

 

7五、爲何要Flask把Local對象中的的值stack 維護成一個列表?

# 由於經過維護成列表,能夠實現一個棧的數據結構,進棧出棧時只取一個數據,巧妙的簡化了問題。

# 還有,在多app應用時,能夠實現數據隔離;列表裏不會加數據,而是會生成一個新的列表

# local是一個字典,字典裏keystack)是惟一標識,value是一個列表

 

7六、Flask中多app應用是怎麼完成?

 

請求進來時,能夠根據URL的不一樣,交給不一樣的APP處理。藍圖也能夠實現。

    #app1 = Flask('app01')

    #app2 = Flask('app02')

    #@app1.route('/index')

    #@app2.route('/index2')

源碼中在DispatcherMiddleware類裏調用app2.__call__

   原理其實就是URL分割,而後將請求分發給指定的app

以後app也按單app的流程走。就是從app.__call__走。

 

7七、在Flask中實現WebSocket須要什麼組件?

 

Flask-SocketIO

Flask-Sockets是Flask框架的一個擴展,經過它,Flask應用程序能夠使用WebSocket。

gevent-websocket

 

7八、wtforms組件的做用?

WTForms是一個支持多個web框架的form組件,主要用於對用戶請求數據進行驗證。

 

7九、Flask框架默認session處理機制?

Flask的默認session利用了Werkzeug的SecureCookie,把信息作序列化(pickle)後編碼(base64),放到cookie裏了。

 

過時時間是經過cookie的過時時間實現的。

 

爲了防止cookie內容被篡改,session會自動打上一個叫session的hash串,這個串是通過session內容、SECRET_KEY計算出來的,看得出,這種設計雖然不能保證session裏的內容不泄露,但至少防止了不被篡改。

 

80、解釋Flask框架中的Local對象和threading.local對象的區別?

# a.threading.local做用:爲每一個線程開闢一塊空間進行數據存儲(數據隔離)

 

問題:本身經過字典建立一個相似於threading.local的東西。

storage = {

   4740: {val: 0},

   4732: {val: 1},

   4731: {val: 3},

   }

 

# b.自定義Local對象做用:爲每一個線程(協程)開闢一塊空間進行數據存儲(數據隔離)

class Local(object):

   def __init__(self):

      object.__setattr__(self, 'storage', {})

   def __setattr__(self, k, v):

      ident = get_ident()

      if ident in self.storage:

         self.storage[ident][k] = v

      else:

         self.storage[ident] = {k: v}

   def __getattr__(self, k):

      ident = get_ident()

      return self.storage[ident][k]

obj = Local()

def task(arg):

   obj.val = arg

   obj.xxx = arg

   print(obj.val)

for i in range(10):

   t = Thread(target=task, args=(i,))

   t.start()

8一、Flask中 blinker 是什麼?

Flask框架中的信號基於blinker,可讓開發者在flask請求過程當中 定製一些用戶行爲執行。 

在請求先後,模板渲染先後,上下文先後,異常 的時候

 

8二、SQLAlchemy中的 session和scoped_session 的區別?

使用scoped_session的目的主要是爲了線程安全。 

scoped_session相似單例模式,當咱們調用使用的時候,會先在Registry裏找找以前是否已經建立session了。 

要是有,就把這個session返回。 

要是沒有,就建立新的session,註冊到Registry中以便下次返回給調用者。 

這樣就實現了這樣一個目的:在同一個線程中,call scoped_session 的時候,返回的是同一個對象

 

8三、SQLAlchemy如何執行原生SQL?

 

  from sqlalchemy import create_engine  from sqlalchemy.orm import sessionmaker   engine = create_engine('mysql://root:*****@127.0.0.1/database?charset=utf8')  DB_Session = sessionmaker(bind=engine)  session = DB_Session()  session.execute('alter table mytablename drop column mycolumn ;')

 

8四、ORM的實現原理?

 

概念: 對象關係映射(Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping),是一種程序技術,用於實現面向對象編程語言裏不一樣類型系統的數據之間的轉換。

詳細介紹: 讓咱們從O/R開始。字母O起源於」對象」(Object),而R則來自於」關係」(Relational)。幾乎全部的程序裏面,都存在對象和關係數據庫。在業務邏輯層和用戶界面層中,咱們是面向對象的。當對象信息發生變化的時候,咱們須要把對象的信息保存在關係數據庫中。

當你開發一個應用程序的時候(不使用O/R Mapping),你可能會寫很多數據訪問層的代碼,用來從數據庫保存,刪除,讀取對象信息,等等。你在DAL中寫了不少的方法來讀取對象數據,改變狀態對象等等任務。而這些代碼寫起來老是重複的。 

ORM解決的主要問題是對象關係的映射。域模型和關係模型分別是創建在概念模型的基礎上的。域模型是面向對象的,而關係模型是面向關係的。通常狀況下,一個持久化類和一個表對應,類的每一個實例對應表中的一條記錄,類的每一個屬性對應表的每一個字段。

 

ORM技術特色: 

* 提升了開發效率。因爲ORM能夠自動對Entity對象與數據庫中的Table進行字段與屬性的映射,因此咱們實際可能已經不須要一個專用的、龐大的數據訪問層。 

* ORM提供了對數據庫的映射,不用sql直接編碼,可以像操做對象同樣從數據庫獲取數據。

 

8五、DBUtils模塊的做用?

使用DBUtils模塊

兩種使用模式: 

1. 爲每一個線程建立一個鏈接,鏈接不可控,須要控制線程數 

1. 建立指定數量的鏈接在鏈接池,當線程訪問的時候去取,若是不夠了線程排隊,直到有人釋放。平時建議使用這種!

 

8六、如下SQLAlchemy的字段是否正確?若是不正確請更正:

 

fromdatetime importdatetimefromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy importColumn, Integer, String, DateTimeBase = declarative_base()classUserInfo(Base):     __tablename__ = 'userinfo'    id = Column(Integer, primary_key= True, autoincrement= True)    name = Column(String( 64), unique= True)    ctime = Column(DateTime, default=datetime.now())ctime字段中的參數應該爲default=datetime.now, now後面不該該加括號.若是加了,字段不會隨時更新

 

8七、SQLAchemy中如何爲表設置引擎和字符編碼?

 

sqlalchemy設置編碼字符集必定要在數據庫訪問的URL上增長charset=utf8,不然數據庫的鏈接就不是utf8的編碼格式 

eng = create_engine(‘mysql://root:root@localhost:3306/test2?charset=utf8’,echo=True)

 

88. SQLAlchemy中如何設置聯合惟一索引?

UniqueConstraint 設置聯合惟一索引

 

8九、簡述Tornado框架的特色。

 

Tornado的獨特之處在於其全部開發工具可以使用在應用開發的任意階段以及任何檔次的硬件資源上。並且,完整集的Tornado工具能夠使開發人員徹底不用考慮與目標鏈接的策略或目標存儲區大小。

 

Tornado 結構的專門設計爲開發人員和第三方工具廠商提供了一個開放環境。已有部分應用程序接口能夠利用並附帶參考書目,內容從開發環境接口到鏈接實現。Tornado包括強大的開發和調試工具,尤爲適用於面對大量問題的嵌入式開發人員。這些工具包括C和C++源碼級別的調試器,目標和工具管理,系統目標跟蹤,內存使用分析和自動配置. 另外,全部工具能很方便地同時運行,很容易增長和交互式開發。

90、簡述Tornado框架中Future對象的做用?

# 實現異步非阻塞視圖函數yield一個futrue對象,futrue對象默認:

    self._done = False   ,請求未完成

    self._result = None  ,請求完成後返回值,用於傳遞給回調函數使用。

 

tornado就會一直去檢測futrue對象的_done是否已經變成True

 

若是IO請求執行完畢,自動會調用futureset_result方法:

            self._result = result

            self._done = True

 

91. Tornado框架中如何編寫WebSocket程序?

Tornadowebsocket模塊中提供了一個WebSocketHandler類。

這個類提供了和已鏈接的客戶端通訊的WebSocket事件和方法的鉤子。

當一個新的WebSocket鏈接打開時,open方法被調用,

on_messageon_close方法,分別在鏈接、接收到新的消息和客戶端關閉時被調用。

 

此外,WebSocketHandler類還提供了write_message方法用於向客戶端發送消息,close方法用於關閉鏈接。

 

9二、Tornado中靜態文件是如何處理的?如: <link href="{{static_url("commons.css")}}" rel="stylesheet" />

 

# settings.py

settings = {

    "static_path": os.path.join(os.path.dirname(__file__), "static"),

   # 指定了靜態文件的位置在當前目錄中的"static"目錄下

    "cookie_secret": "61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=",

    "login_url": "/login",

    "xsrf_cookies": True,

}

 

經上面配置後

static_url()自動去配置的路徑下找'commons.css'文件

 

9三、Tornado操做MySQL使用的模塊?

torndb是一個輕量級的基於MySQLdb封裝的一個模塊,從tornado3.0版本之後,其已經做爲一個獨立模塊發行了。torndb依賴於MySQLdb模塊,所以,在使用torndb模塊時,要保證系統中已經有MySQLdb模塊。

 

9四、Tornado操做redis使用的模塊?

tornado-redis

9五、簡述Tornado框架的適用場景?

 

Tornado是使用Python編寫的一個強大的、可擴展的Web服務器。它在處理嚴峻的網絡流量時表現得足夠強健,但卻在建立和編寫時有着足夠的輕量級,並可以被用在大量的應用和工具中。

 

咱們如今所知道的Tornado是基於Bret Taylor和其餘人員爲FriendFeed所開發的網絡服務框架,當FriendFeed被Facebook收購後得以開源。不一樣於那些最多隻能達到10,000個併發鏈接的傳統網絡服務器,Tornado在設計之初就考慮到了性能因素,旨在解決C10K問題,這樣的設計使得其成爲一個擁有很是高性能的框架。此外,它還擁有處理安全性、用戶驗證、社交網絡以及與外部服務(如數據庫和網站API)進行異步交互的工具。

 

96. git常見命令做用

 

某個文件夾中的內容進行版本管理:

進入文件夾,右鍵git bash

git init 初始化,當前所在的文件夾能夠被管理且之後版本相關的數據都會存儲到.git文件中

git status 查看當前文件夾以及子目錄中文件是否發生變化:內容修改/新增文件/刪除,已經變化的文件會變成紅色,已經add的文件會變成綠色

git add .  給發生變化的文件(貼上一個標籤)或 將發生變化的文件放到某個地方,只寫一個句點符就表明把git status中紅色的文件所有打上標籤

git commit -m ‘新增用戶登陸認證功能以及xxx功能’ 將「綠色」文件添加到版本中

git log 查看全部版本提交記錄,能夠獲取版本號

git reset –hard 版本號   將最新的版本回退到更早的版本

git reflog   回退到以前版本後悔了,再更新到最新或者最新以前的版本

git reset –hard 版本 回退    

 

97. 簡述如下git中stash命令做用以及相關其餘命令。

 

stash用於將工做區發生變化的全部文件獲取臨時存儲在「某個地方」,將工做區還原當前版本未操做前的狀態;stash還能夠將臨時存儲在「某個地方」的文件再次拿回到工做區。

 

git stash             將當前工做區全部修改過的內容存儲到「某個地方」,將工做區還原到當前版本未修改過的狀態

git stash list        查看「某個地方」存儲的全部記錄

git stash clear     清空「某個地方」

git stash pop       將第一個記錄從「某個地方」從新拿到工做區(可能有衝突)

git stash apply     編號, 將指定編號記錄從「某個地方」從新拿到工做區(可能有衝突)

git stash drop      編號,刪除指定編號的記錄

 

98. git 中 merge 和 rebase命令 的區別。

merge

會將不一樣分支的提交合併成一個新的節點,以前的提交分開顯示,

注重歷史信息、能夠看出每一個分支信息,基於時間點,遇到衝突,手動解決,再次提交

rebase

將兩個分支的提交結果融合成線性,不會產生新的節點;

注重開發過程,遇到衝突,手動解決,繼續操做

 

99. 公司如何基於git作的協同開發?

1、大家公司的代碼review分支怎麼作?誰來作?

答:組長建立review分支,咱們小功能開發完以後,合併到review分支交給老大(小組長)來看,

1.1、你組長不開發代碼嗎?

        他開發代碼,可是它只開發核心的東西,任務比較少。或者抽出時間,咱們一塊兒作這個事情

2、大家公司協同開發是怎麼協同開發的?

每一個人都有本身的分支,階段性代碼完成以後,合併到review,而後交給老大看

--------------------------------------------------------------------------

# 大體工做流程公司:

    下載代碼

        git clone https://gitee.com/wupeiqi/xianglong.git

        或建立目錄

        cd 目錄

        git init

        git remote add origin https://gitee.com/wupeiqi/xianglong.git

        git pull origin maste

    建立dev分支

        git checkout dev

        git pull origin dev

        繼續寫代碼

        git add .

        git commit -m '提交記錄'

        git push origin dev

回家:

    拉代碼:

        git pull origin dev

    繼續寫:

        繼續寫代碼

        git add .

        git commit -m '提交記錄'

        git push origin dev

100、如何基於git實現代碼review?

利用github/gitlab自帶的在線Diff展現功能作。

https://blog.csdn.net/maray/article/details/50206927

 

101. git如何實現v1.0 、v2.0 等版本的管理?

在命令行中,使用「git tag –a tagname –m 「comment」能夠快速建立一個標籤。

須要注意,命令行建立的標籤只存在本地Git庫中,還須要使用Git push –tags指令發 布到服務器的Git庫中

 

102. 什麼是gitlab?

gitlab是公司本身搭建的項目代碼託管平臺

GitLab 是一個用於倉庫管理系統的開源項目,使用Git做爲代碼管理工具,並在此基礎上搭建起來的web服務。安裝方法是參考GitLab在GitHub上的Wiki頁面。

 

10三、github和gitlab的區別?

 

先說一下相同點,兩者都是基於web的Git倉庫,在很大程度上GitLab是仿照GitHub來作的,它們都提供了分享開源項目的平臺,爲開發團隊提供了存儲、分享、發佈和合做開發項目的中心化雲存儲的場所。

GitHub做爲開源代碼庫及版本控制系統,擁有超過900萬的開發者用戶,目前仍然是最火的開源項目託管系統。GitHub同時提供公共倉庫和私有倉庫,但若是要使用私有倉庫,是須要付費的。

GitLab解決了這個問題,你能夠在上面建立私人的免費倉庫。

GitLab讓開發團隊對他們的代碼倉庫擁有更多的控制,相比於GitHub,它有很多的特點:

容許免費設置倉庫權限;容許用戶選擇分享一個project的部分代碼;容許用戶設置project的獲取權限,進一步的提高安全性;能夠設置獲取到團隊總體的改進進度;經過innersourcing讓不在權限範圍內的人訪問不到該資源。

從代碼私有性方面來看,有時公司並不但願員工獲取到所有的代碼,這個時候GitLab無疑是更好的選擇。但對於開源項目而言,GitHub依然是代碼託管的首選。

 

10四、如何爲github上牛逼的開源項目貢獻代碼?

 

1fork須要協做項目

2、克隆/關聯fork的項目到本地

3、新建分支(branch)並檢出(checkout)新分支

4、在新分支上完成代碼開發

5、開發完成後將你的代碼合併到master分支

6、添加原做者的倉庫地址做爲一個新的倉庫地址

7、合併原做者的master分支到你本身的master分支,用於和做者倉庫代碼同步

8push你的本地倉庫到GitHub

9、在Github上提交 pull requests

10、等待管理員(你須要貢獻的開源項目管理員)處理

 

10五、git中 .gitignore文件的做用?

 

通常來講每一個Git項目中都須要一個「.gitignore」文件,

這個文件的做用就是告訴Git哪些文件不須要添加到版本管理中。

實際項目中,不少文件都是不須要版本管理的,好比Python的.pyc文件和一些包含密碼的配置文件等等。

106. 什麼是敏捷開發?

敏捷開發以用戶的需求進化爲核心,採用迭代、按部就班的方法進行軟件開發。在敏捷開發中,軟件項目在構建初期被切分紅多個子項目,各個子項目的成果都通過測試,具有可視、可集成和可運行使用的特徵。換言之,就是把一個大項目分爲多個相互聯繫,但也可獨立運行的小項目,並分別完成,在此過程當中軟件一直處於可以使用狀態。

11九、簡述 requests模塊的做用及基本使用?

使用requests能夠模擬瀏覽器發送的請求

發送get請求:requests.get()

發送post請求:requests.post()

讀取請求返回內容:requests.text()

保存cookie:requests.cookie()

# 做用:使用requests能夠模擬瀏覽器的請求

# 經常使用參數:   urlheaderscookiesdata

   jsonparamsproxy

# 經常使用返回值:   content

   iter_content

   text

   encoding="utf-8"

   cookie.get_dict()

 

120、簡述 beautifulsoup模塊的做用及基本使用?

 

# BeautifulSoup用於從HTMLXML文件中提取、過濾想要的數據形式

#經常使用方法解析:html.parser 或者 lxml(須要下載安裝)

   findfind_alltextattrsget

 

12一、簡述 seleninu模塊的做用及基本使用?

 

selenium最初是一個自動化測試工具,而爬蟲中使用它主要是爲了解決requests沒法直接執行JavaScript代碼的問題

selenium本質是經過驅動瀏覽器,徹底模擬瀏覽器的操做,好比跳轉、輸入、點擊、下拉等,來拿到網頁渲染以後的結果,可支持多種瀏覽器

 

12二、scrapy框架中各組件的工做流程?

Scrapy Engine(引擎):

負責Spider、ItemPipeline、Downloader、Scheduler中間的通信,信號、數據傳遞等。

Scheduler(調度器): 它負責接受引擎發送過來的Request請求,並按照必定的方式進行整理排列,入隊,當引擎須要時,交還給引擎。

Downloader(下載器):

負責下載Scrapy Engine(引擎)發送的全部Requests請求,並將其獲取到的Responses交還給Scrapy Engine(引擎),由引擎交給Spider來處理,

Spider(爬蟲):

它負責處理全部Responses,從中分析提取數據,獲取Item字段須要的數據,並將須要跟進的URL提交給引擎,再次進入Scheduler(調度器),

Item Pipeline(管道):它負責處理Spider中獲取到的Item,並進行進行後期處理(詳細分析、過濾、存儲等)的地方.

Downloader Middlewares(下載中間件):

你能夠看成是一個能夠自定義擴展下載功能的組件。

Spider Middlewares(Spider中間件):

你能夠理解爲是一個能夠自定擴展和操做引擎和Spider中間通訊的功能組件(好比進入Spider的Responses;和從Spider出去的Requests)

#1、生成初始的Requests來爬取第一個URLS,而且標識一個回調函數第一個請求定義在start_requests()方法內默認從start_urls列表中得到url地址來生成Request請求,

默認的回調函數是parse方法。回調函數在下載完成返回response時自動觸發

#2、在回調函數中,解析response而且返回值返回值能夠4種:

    a、包含解析數據的字典

    bItem對象

    c、新的Request對象(新的Requests也須要指定一個回調函數)

    d、或者是可迭代對象(包含ItemsRequest

#3、在回調函數中解析頁面內容一般使用Scrapy自帶的Selectors,但很明顯你也能夠使用Beutifulsouplxml或其餘你愛用啥用啥。

#4、最後,針對返回的Items對象將會被持久化到數據庫    經過Item Pipeline組件存到數據庫

    或者導出到不一樣的文件(經過Feed exports

 

12三、在scrapy框架中如何設置代理(兩種方法)?

 

方式一:內置添加代理功能

# -*- coding: utf-8 -*-

import os

import scrapy

from scrapy.http import Request

 

class ChoutiSpider(scrapy.Spider):

    name = 'chouti'

    allowed_domains = ['chouti.com']

    start_urls = ['https://dig.chouti.com/']

 

    def start_requests(self):

        os.environ['HTTP_PROXY'] = "http://192.168.11.11"

 

        for url in self.start_urls:

            yield Request(url=url,callback=self.parse)

 

    def parse(self, response):

        print(response)

 

方式二:自定義下載中間件

import random

import base64

import six

def to_bytes(text, encoding=None, errors='strict'):

    """Return the binary representation of `text`. If `text`

    is already a bytes object, return it as-is."""

    if isinstance(text, bytes):

        return text

    if not isinstance(text, six.string_types):

        raise TypeError('to_bytes must receive a unicode, str or bytes '

                        'object, got %s' % type(text).__name__)

    if encoding is None:

        encoding = 'utf-8'

    return text.encode(encoding, errors)

    

class MyProxyDownloaderMiddleware(object):

    def process_request(self, request, spider):

        proxy_list = [

            {'ip_port': '111.11.228.75:80', 'user_pass': 'xxx:123'},

            {'ip_port': '120.198.243.22:80', 'user_pass': ''},

            {'ip_port': '111.8.60.9:8123', 'user_pass': ''},

            {'ip_port': '101.71.27.120:80', 'user_pass': ''},

            {'ip_port': '122.96.59.104:80', 'user_pass': ''},

            {'ip_port': '122.224.249.122:8088', 'user_pass': ''},

        ]

        proxy = random.choice(proxy_list)

        if proxy['user_pass'] is not None:

            request.meta['proxy'] = to_bytes("http://%s" % proxy['ip_port'])

            encoded_user_pass = base64.encodestring(to_bytes(proxy['user_pass']))

            request.headers['Proxy-Authorization'] = to_bytes('Basic ' + encoded_user_pass)

        else:

            request.meta['proxy'] = to_bytes("http://%s" % proxy['ip_port'])

 

 

 

配置:

    DOWNLOADER_MIDDLEWARES = {

       # 'xiaohan.middlewares.MyProxyDownloaderMiddleware': 543,

    }

 

 

12四、scrapy框架中如何實現大文件的下載?

from twisted.web.client import Agent, getPage, ResponseDone, PotentialDataLoss

from twisted.internet import defer, reactor, protocol

from twisted.web._newclient import Response

from io import BytesIO

 

class _ResponseReader(protocol.Protocol):

    def __init__(self, finished, txresponse, file_name):

        self._finished = finished

        self._txresponse = txresponse

        self._bytes_received = 0

        self.f = open(file_name, mode='wb')

    def dataReceived(self, bodyBytes):

        self._bytes_received += len(bodyBytes)

        # 一點一點的下載        self.f.write(bodyBytes)

        self.f.flush()

    def connectionLost(self, reason):

        if self._finished.called:

            return

        if reason.check(ResponseDone):

            # 下載完成

            self._finished.callback((self._txresponse, 'success'))

        elif reason.check(PotentialDataLoss):

            # 下載部分

            self._finished.callback((self._txresponse, 'partial'))

        else:

            # 下載異常            self._finished.errback(reason)

        self.f.close()

 

12五、scrapy中如何實現限速?

修改setting文件的AUTOTHROTTLE_START_DELAY 打開後默認限速爲5秒

 

12六、scrapy中如何實現暫定爬蟲?

 

cmd上cd 進入項目

而後在項目目錄下建立 記錄文件:remain/001

而後輸入:scrapy crawl  zhihu  -s JOBDIR=remain/001

回車運行就好了

ctrl+c 暫停

繼續運行只要再次輸入:scrapy crawl  zhihu  -s JOBDIR=remain/001就好了

須要從新爬取就換個文件 002就好了

 

12七、scrapy中如何進行自定製命令?

 

spiders同級建立任意目錄,如:commands

在其中建立'crawlall.py'文件(此處文件名就是自定義的命令)

from scrapy.commands import ScrapyCommand

    from scrapy.utils.project import get_project_settings

    class Command(ScrapyCommand):

        requires_project = True

        def syntax(self):

            return '[options]'

        def short_desc(self):

            return 'Runs all of the spiders'

        def run(self, args, opts):

            spider_list = self.crawler_process.spiders.list()

            for name in spider_list:

                self.crawler_process.crawl(name, **opts.__dict__)

            self.crawler_process.start()

'settings.py'中添加配置'COMMANDS_MODULE = '項目名稱.目錄名稱''

在項目目錄執行命令:'scrapy crawlall'

 

12八、scrapy中如何實現的記錄爬蟲的深度?

'DepthMiddleware'是一個用於追蹤每一個Request在被爬取的網站的深度的中間件。

其能夠用來限制爬取深度的最大深度或相似的事情。

'DepthMiddleware'能夠經過下列設置進行配置(更多內容請參考設置文檔):

 

'DEPTH_LIMIT':爬取所容許的最大深度,若是爲0,則沒有限制。

'DEPTH_STATS':是否收集爬取狀態。

'DEPTH_PRIORITY':是否根據其深度對requet安排優先

12九、scrapy中的pipelines工做原理?

Scrapy 提供了 pipeline 模塊來執行保存數據的操做。

在建立的 Scrapy 項目中自動建立了一個 pipeline.py 文件,同時建立了一個默認的 Pipeline 類。咱們能夠根據須要自定義 Pipeline 類,而後在 settings.py 文件中進行配置便可

 

130、scrapy的pipelines如何丟棄一個item對象?

經過raise DropItem()方法

pipelines的時候不執行持久化保存就會什麼也不執行也就是丟棄

13一、簡述scrapy中爬蟲中間件和下載中間件的做用?

下載器中間件(Downloader Middlewares)

位於Scrapy引擎和下載器之間的框架,主要是處理Scrapy引擎與下載器之間的請求及響應。

爬蟲中間件(Spider Middlewares)

介於Scrapy引擎和爬蟲之間的框架,主要工做是處理蜘蛛的響應輸入和請求輸出。

13二、scrapy-redis組件的做用?

實現了分佈式爬蟲,url去重、調度器、數據持久化

scheduler - 調度器

   dupefilter - URL去重規則(被調度器使用)

   pipeline   - 數據持久化

 

13三、scrapy-redis組件中如何實現的任務的去重?

a. 內部進行配置,鏈接Redis
b.去重規則經過redis的集合完成,集合的Key爲:
   key defaults.DUPEFILTER_KEY % {'timestamp': int(time.time())}
   默認配置:
      DUPEFILTER_KEY = 'dupefilter:%(timestamp)s'
c.去重規則中將url轉換成惟一標示,而後在redis中檢查是否已經在集合中存在
   from scrapy.utils import request
   from scrapy.http import Request
   req Request(url='http://www.cnblogs.com/wupeiqi.html')
   result request.request_fingerprint(req)
   print(result)  # 8ea4fd67887449313ccc12e5b6b92510cc53675c

scrapyscrapy-redis的去重規則(源碼)

1. scrapy中去重規則是如何實現?

class RFPDupeFilter(BaseDupeFilter):

    """Request Fingerprint duplicates filter"""

 

    def __init__(self, path=None, debug=False):

        self.fingerprints = set()

 

    @classmethod

    def from_settings(cls, settings):

        debug = settings.getbool('DUPEFILTER_DEBUG')

        return cls(job_dir(settings), debug)

    def request_seen(self, request):

        # request對象轉換成惟一標識。

        fp = self.request_fingerprint(request)

        # 判斷在集合中是否存在,若是存在則返回True,表示已經訪問過。

        if fp in self.fingerprints:

            return True

         # 以前未訪問過,將url添加到訪問記錄中。        

self.fingerprints.add(fp)

    def request_fingerprint(self, request):

        return request_fingerprint(request)

2. scrapy-redis中去重規則是如何實現?

class RFPDupeFilter(BaseDupeFilter):

    """Redis-based request duplicates filter.

    This class can also be used with default Scrapy's scheduler.

    """

    logger = logger

    def __init__(self, server, key, debug=False):

        # self.server = redis鏈接

        self.server = server

        # self.key = dupefilter:123912873234

        self.key = key

 

    @classmethod

    def from_settings(cls, settings):  

        # 讀取配置,鏈接redis

        server = get_redis_from_settings(settings)

        #  key = dupefilter:123912873234

        key = defaults.DUPEFILTER_KEY % {'timestamp': int(time.time())}

        debug = settings.getbool('DUPEFILTER_DEBUG')

        return cls(server, key=key, debug=debug)

 

    @classmethod

    def from_crawler(cls, crawler):        

        return cls.from_settings(crawler.settings)

    def request_seen(self, request):

        fp = self.request_fingerprint(request)

        # This returns the number of values added, zero if already exists.

        # self.server=redis鏈接

        # 添加到redis集合中:1,添加工程;0,已經存在

        added = self.server.sadd(self.key, fp)

        return added == 0

    def request_fingerprint(self, request):

        return request_fingerprint(request)

    def close(self, reason=''):

        self.clear()

    def clear(self):

        """Clears fingerprints data."""

        self.server.delete(self.key)

13四、scrapy-redis的調度器如何實現任務的深度優先和廣度優先

簡述 jenkins 工具的做用?

'Jenkins'是一個可擴展的持續集成引擎。

主要用於:

   持續、自動地構建/測試軟件項目。

   監控一些定時執行的任務。

公司如何實現代碼發佈?

nginx+uwsgi+django

簡述 RabbitMQ、Kafka、ZeroMQ的區別?

RabbitMQ如何在消費者獲取任務後未處理完前就掛掉時,保證數據不丟失?

爲了預防消息丟失,rabbitmq提供了ack

即工做進程在收到消息並處理後,發送ack給rabbitmq,告知rabbitmq這時候能夠把該消息從隊列 中刪除了。

若是工做進程掛掉 了,rabbitmq沒有收到ack,那麼會把該消息 從新分發給其餘工做進程。

不須要設置timeout,即便該任務須要很長時間也能夠處理。

 

ack默認是開啓的,工做進程顯示指定了no_ack=True

RabbitMQ如何對消息作持久化?

一、建立隊列和發送消息時將設置durable=Ture,若是在接收到消息尚未存儲時,消息也有可能丟失,就必須配置publisher confirm

    channel.queue_declare(queue='task_queue', durable=True)

二、返回一個ack,進程收到消息並處理完任務後,發給rabbitmq一個ack表示任務已經完成,能夠刪除該任務

三、鏡像隊列:將queue鏡像到cluster中其餘的節點之上。

在該實現下,若是集羣中的一個節點失效了,queue能自動地切換到鏡像中的另外一個節點以保證服務的可用法。

RabbitMQ如何控制消息被消費的順序?

默認消息隊列裏的數據是按照順序被消費者拿走,

例如:消費者1 去隊列中獲取奇數序列的任務,消費者2去隊列中獲取偶數序列的任務。

channel.basic_qos(prefetch_count=1)

表示誰來誰取,再也不按照奇偶數排列(同時也保證了公平的消費分發)

如下RabbitMQ的exchange type分別表明什麼意思?如:fanout、direct、topic

amqp協議中的核心思想就是生產者和消費者隔離,生產者從不直接將消息發送給隊列。

生產者一般不知道是否一個消息會被髮送到隊列中,只是將消息發送到一個交換機。

先由Exchange來接收,而後Exchange按照特定的策略轉發到Queue進行存儲。

同理,消費者也是如此。Exchange 就相似於一個交換機,轉發各個消息分發到相應的隊列中。

type=fanout 相似發佈者訂閱者模式,會爲每個訂閱者建立一個隊列,而發佈者發佈消息時,會將消息放置在全部相關隊列中

type=direct 隊列綁定關鍵字,發送者將數據根據關鍵字發送到消息exchange,exchange根據 關鍵字 斷定應該將數據發送至指定隊列。

type=topic  隊列綁定幾個模糊的關鍵字,以後發送者將數據發送到exchange,exchange將傳入」路由值「和 」關鍵字「進行匹配,匹配成功,
則將數據發送到指定隊列。

發送者路由值              隊列中

old.boy.python          old.*  -- 不匹配    *表示匹配一個

old.boy.python          old.#  -- 匹配      #表示匹配0個或多個

簡述 celery 是什麼以及應用場景?

# Celery是由Python開發的一個簡單、靈活、可靠的處理大量任務的分發系統,

# 它不只支持實時處理也支持任務調度。

簡述 vitualenv 及應用場景?

'vitualenv'是一個獨立的python虛擬環境

如:

   當前項目依賴的是一個版本,可是另外一個項目依賴的是另外一個版本,這樣就會形成依賴衝突,

   virtualenv就是解決這種狀況的,virtualenv經過建立一個虛擬化的python運行環境,

   將咱們所需的依賴安裝進去的,不一樣項目之間相互不干擾

簡述 pipreqs 及應用場景?

能夠經過對項目目錄掃描,自動發現使用了那些類庫,而且自動生成依賴清單。

pipreqs ./ 生成requirements.txt

Python中使用過什麼代碼檢查工具?

1PyFlakes:靜態檢查Python代碼邏輯錯誤的工具。

2Pep8: 靜態檢查PEP8編碼風格的工具。

3NedBatchelder’s McCabe script:靜態分析Python代碼複雜度的工具。

Python代碼分析工具:PyCheckerPylint

簡述 saltstack、ansible、fabric、puppet工具的做用?

 

B Tree和B+ Tree的區別?

1.B樹中同一鍵值不會出現屢次,而且有可能出如今葉結點,也有可能出如今非葉結點中。

  B+樹的鍵必定會出如今葉結點中,並有可能在非葉結點中重複出現,以維持B+樹的平衡。

2.由於B樹鍵位置不定,且在整個樹結構中只出現一次,

請列舉常見排序並經過代碼實現任意三種。

冒泡/選擇/插入/快排

 請列舉常見查找並經過代碼實現任意三種。

無序查找、二分查找、插值查找

請列舉你熟悉的設計模式

工廠模式/單例模式等

有沒有刷過leetcode?

leetcode是個題庫,裏面有多很編程題目,能夠在線編譯運行。

https://leetcode-cn.com/problemset/all/

列舉熟悉的的Linux命令。

1建立目錄

mkdir /data

cd /

mkdir data

2:查看目錄

ls

ls -l  顯示詳細信息

公司線上服務器是什麼系統?

Linux/Centos

解釋 PV、UV 的含義?

PV訪問量(Page View),即頁面訪問量,每打開一次頁面PV計數+1,刷新頁面也是。

UV訪問數(Unique Visitor)指獨立訪客訪問數,一臺電腦終端爲一個訪客。

解釋 QPS的含義?

'QPS(Query Per Second)' 每秒查詢率,是對一個特定的查詢服務器在規定時間內所處理流量多少的衡量標準

uwsgi和wsgi的區別?

wsgi是一種通用的接口標準或者接口協議,實現了python web程序與服務器之間交互的通用性。

uwsgi:WSGI同樣是一種通訊協議

uwsgi協議是一個'uWSGI服務器'自有的協議,它用於定義傳輸信息的類型,

'uWSGI'是實現了uwsgiWSGI兩種協議的Web服務器,負責響應pythonweb請求。

 

supervisor的做用?

 

# Supervisor:是一款基於Python的進程管理工具,能夠很方便的管理服務器上部署的應用程序。

 

C/S模型的程序,其服務端是supervisord服務,客戶端是supervisorctl命令

 

# 主要功能:

 

1 啓動、重啓、關閉包括但不限於python進程。

 

2 查看進程的運行狀態。

 

3 批量維護多個進程。

 

什麼是反向代理?

 

正向代理代理客戶端(客戶端找喲個代理去訪問服務器,服務器不知道你的真實IP)

 

反向代理代理服務器(服務器找一個代理給你響應,你不知道服務器的真實IP)

 

簡述SSH的整個過程。

 

SSH 'Secure Shell' 的縮寫,是創建在應用層基礎上的安全協議。

 

SSH 是目前較可靠,爲遠程登陸會話和其餘網絡服務提供的安全性協議。

 

利用 SSH 協議能夠有效防止遠程管理過程當中的信息泄露問題。

 

有問題都去那些找解決方案?

 

起初是百度,發現搜到的答案不精準,淨廣告

 

轉戰谷歌,但牆了;搗鼓怎麼FQ

 

還會去知乎、stackoverfloow、必應、思否(segmentfault)

 

是否有關注什麼技術類的公衆號?

 

python之禪(主要專一Python相關知識,做者:劉志軍)

 

碼農翻身(主要是Java的,但不光是java,涵蓋面很廣,做者:劉欣)

 

實驗樓(在線練項目)

 

最近在研究什麼新技術?

 

Numpy pandas(金融量化分析、聚寬) 百度AI 圖靈API 智能玩具

 

是否瞭解過領驅動模型

 

Domain-Driven Design

 

二進制與十進制之間的轉換

 

一、十進制 與 二進制之間的轉換
    (1)、十進制轉換爲二進制,分爲整數部分和小數部分

 

整數部分

 

方法:除2取餘法,即每次將整數部分除以2,餘數爲該位權上的數,而商繼續除以2,餘數又爲上一個位權上的數。

 

這個步驟一直持續下去,直到商爲0爲止,最後讀數時候,從最後一個餘數讀起,一直到最前面的一個餘數。下面舉例:

 

小數部分

 

方法:乘2取整法,即將小數部分乘以2,而後取整數部分,剩下的小數部分繼續乘以2,而後取整數部分,
剩下的小數部分又乘以2,一直取到小數部分爲零爲止。若是永遠不能爲零,就同十進制數的四捨五入同樣,
按照要求保留多少位小數時,就根據後面一位是0仍是1,取捨,若是是零,舍掉,若是是1,向入一位。
換句話說就是01入。讀數要從前面的整數讀到後面的整數

 

二進制轉換爲十進制 (不分整數和小數部分)

 

方法:按權相加法,即將二進制每位上的數乘以權,而後相加之和便是十進制數。

 

例:將二進制數101.101轉換爲十進制數。

 

得出結果:(101.1012=(5.625)10

 

在作二進制轉換成十進制須要注意的是

 

1)要知道二進制每位的權值

 

2)要能求出每位的值 101.101 轉換爲十進制

 

整數部分:2^2 + 2^0 = 5

 

小數部分:2^(-1) + 2^(-3) = 1/2 + 1/8 = 0.5 + 0.125 = 0.625

 

十進制: 2^2 + 2^0 + 2^(-1) + 2^(-3) = 5.625

相關文章
相關標籤/搜索