面試這塊兒,都給我整的明明白白的

===============第一部分 Python基礎篇(80題)===============

1. 爲何學習Python?

是愛嗎?是責任嗎?都不是,是TMD窮!

2. 經過什麼途徑學習的Python?

大街上有人看我骨骼精奇,是萬中無一的編程奇才,賣我本《21天精通Python》,而後……

3. Python和Java、PHP、C、C#、C++等其餘語言的對比?

PHP是世界上最好的語言,Python多少差點意思

4. 簡述解釋型和編譯型編程語言?

編譯型:運行前先由編譯器將高級語言代碼編譯爲對應機器的cpu彙編指令集,再由彙編器彙編爲目標機器碼,生成可執行文件,然最後運行生成的可執行文件。最典型的表明語言爲C/C++,通常生成的可執行文件及.exe文件。 

    解釋型:在運行時由翻譯器將高級語言代碼翻譯成易於執行的中間代碼,並由解釋器(例如瀏覽器、虛擬機)逐一將該中間代碼解釋成機器碼並執行(可看作是將編譯、運行合二爲一了)。最典型的表明語言爲JavaScript、Python、Ruby和Perl等。

5. Python解釋器種類以及特色?

CPython

  當 從Python官方網站下載並安裝好Python2.7後,就直接得到了一個官方版本的解釋器:Cpython,這個解釋器是用C語言開發的,因此叫 CPython,在命名行下運行python,就是啓動CPython解釋器,CPython是使用最廣的Python解釋器。

  IPython

  IPython是基於CPython之上的一個交互式解釋器,也就是說,IPython只是在交互方式上有所加強,可是執行Python代碼的功能和CPython是徹底同樣的,比如不少國產瀏覽器雖然外觀不一樣,但內核實際上是調用了IE。

  PyPy

  PyPy是另外一個Python解釋器,它的目標是執行速度,PyPy採用JIT技術,對Python代碼進行動態編譯,因此能夠顯著提升Python代碼的執行速度。

  Jython

  Jython是運行在Java平臺上的Python解釋器,能夠直接把Python代碼編譯成Java字節碼執行。

  IronPython

  IronPython和Jython相似,只不過IronPython是運行在微軟.Net平臺上的Python解釋器,能夠直接把Python代碼編譯成.Net的字節碼。

  在Python的解釋器中,使用普遍的是CPython,對於Python的編譯,除了能夠採用以上解釋器進行編譯外,技術高超的開發者還能夠按照本身的需求自行編寫Python解釋器來執行Python代碼,十分的方便!

6. 位和字節的關係?

1.位(bit) 
  來自英文bit,表示二進制位。位是計算機內部數據儲存的最小單位,11010100是一個8位二進制數。一個二進制位只能夠表示0和1兩種狀態;兩個二進制位能夠表示00、0一、十、11四種狀態;三位二進制數可表示八種狀態。  

  2.字節(byte)  
  字節來自英文Byte,習慣上用大寫的「B」表示。  
  字節是計算機中數據處理的基本單位。計算機中以字節爲單位存儲和解釋信息,規定一個字節由八個二進制位構成,即1個字節等於8個比特(1Byte=8bit)。八位二進制數最小爲00000000,最大爲11111111;一般1個字節能夠存入一個ASCII碼,2個字節能夠存放一個漢字國標碼。

7. b、B、KB、MB、GB 的關係?

1024

8. 請至少列舉5個 PEP8 規範(越多越好)。

縮進/空格/註釋/命名等
  http://blog.sae.sina.com.cn/archives/4781

9. 經過代碼實現進制轉換

## 二進制轉換成十進制:v = 「0b1111011」
  ## 十進制轉換成二進制:v = 18
  ## 八進制轉換成十進制:v = 「011」
  ## 十進制轉換成八進制:v = 30
  ## 十六進制轉換成十進制:v = 「0x12」
  ## 十進制轉換成十六進制:v = 87
  1) 二進制數、轉換爲十進制數的規律是:把二進制數按位權形式展開多項式和的形式,求其最後的和,就是其對應的十進制數——簡稱「按權求和」。
  2) 十進制整數轉換爲二進制整數採用"除2取餘,逆序排列"法。具體作法是:用2去除十進制整數,能夠獲得一個商和餘數;再用2去除商,又會獲得一個商和餘數,如此進行,直到商爲零時爲止,而後把先獲得的餘數做爲二進制數的低位有效位,後獲得的餘數做爲二進制數的高位有效位,依次排列起來。

  10進制,固然是便於咱們人類來使用,咱們從小的習慣就是使用十進制,這個毋庸置疑。
  2進制,是供計算機使用的,1,0表明開和關,有和無,機器只認識2進制。
  16進制,內存地址空間是用16進制的數據表示, 如0x8039326。

10. 請編寫一個函數實現將IP地址轉換成一個整數。

## 如 10.3.9.12 轉換規則爲:
  ##         10            00001010
  ##          3            00000011
  ##          9            00001001
  ##         12            00001100
  ## 再將以上二進制拼接起來計算十進制結果:00001010 00000011 00001001 00001100 = ?


  ip_addr='192.168.2.10'
  # transfer ip to int
  def ip2long(ip):
      ip_list=ip.split('.')
      result=0
      for i in range(4):  #0,1,2,3
          result=result+int(ip_list[i])*256**(3-i)
      return result


  long=3232236042

  # transfer int to ip
  def long2ip(long):
      floor_list=[]
      yushu=long
      for i in reversed(range(4)):   #3,2,1,0
          res=divmod(yushu,256**i)
          floor_list.append(str(res[0]))
          yushu=res[1]
      return '.'.join(floor_list)



  a=long2ip(long)
  print(a)

11. python遞歸的最大層數?

998

12. 求邏輯運算符的結果

##     v1 = 1 or 3      # 1
  ##     v2 = 1 and 3     # 3 
  ##     v3 = 0 and 2 and 1  # 0
  ##     v4 = 0 and 2 or 1   # 1
  ##     v5 = 0 and 2 or 1 or 4   #  1
  ##     v6 = 0 or Flase and 1   # False

結論:
真假比 若都真
or選前 and選後

13. ascii、unicode、utf-八、gbk 區別?

http://www.cnblogs.com/zhuwenlubin/p/5131026.html

14. 字節碼和機器碼的區別?

機器碼
  機器碼(machine code),學名機器語言指令,有時也被稱爲原生碼(Native Code),是電腦的CPU可直接解讀的數據。

  一般意義上來理解的話,機器碼就是計算機能夠直接執行,而且執行速度最快的代碼。

  用機器語言編寫程序,編程人員要首先熟記所用計算機的所有指令代碼和代碼的涵義。手編程序時,程序員得本身處理每條指令和每一數據的存儲分配和輸入輸出,還得記住編程過程當中每步所使用的工做單元處在何種狀態。這是一件十分繁瑣的工做,編寫程序花費的時間每每是實際運行時間的幾十倍或幾百倍。並且,編出的程序全是些0和1的指令代碼,直觀性差,還容易出錯。如今,除了計算機生產廠家的專業人員外,絕大多數的程序員已經再也不去學習機器語言了。

  機器語言是微處理器理解和使用的,用於控制它的操做二進制代碼。
  8086到Pentium的機器語言指令長度能夠從1字節到13字節。
  儘管機器語言好像是很複雜的,然而它是有規律的。
  存在着多至100000種機器語言的指令。這意味着不能把這些種類所有列出來。
  總結:機器碼是電腦CPU直接讀取運行的機器指令,運行速度最快,可是很是晦澀難懂,也比較難編寫,通常從業人員接觸不到。

  字節碼
  字節碼(Bytecode)是一種包含執行程序、由一序列 op 代碼/數據對 組成的二進制文件。字節碼是一種中間碼,它比機器碼更抽象,須要直譯器轉譯後才能成爲機器碼的中間代碼。

  一般狀況下它是已經通過編譯,但與特定機器碼無關。字節碼一般不像源碼同樣可讓人閱讀,而是編碼後的數值常量、引用、指令等構成的序列。

  字節碼主要爲了實現特定軟件運行和軟件環境、與硬件環境無關。字節碼的實現方式是經過編譯器和虛擬機器。編譯器將源碼編譯成字節碼,特定平臺上的虛擬機器將字節碼轉譯爲能夠直接執行的指令。字節碼的典型應用爲Java bytecode。

  字節碼在運行時經過JVM(JAVA虛擬機)作一次轉換生成機器指令,所以可以更好的跨平臺運行。

  總結:字節碼是一種中間狀態(中間碼)的二進制代碼(文件)。須要直譯器轉譯後才能成爲機器碼。

15. 三元運算規則以及應用場景?

簡化if語句

16. 列舉 Python2和Python3的區別?

py2和py3:
  1. 文件操做:  xreadlines

  f = open('x.log','rb')

  for line in f.xreadlines():
  print(line)

  f.close()

  2. 字符串:
  py2:
  str: 字符串   -> 字節
  unicode: u"sdfsdf"
  py3:
    bytes:
  str:
  3. 默認解釋器編碼
  py2: ascii
  py3: utf-8

  5. 
  py2: range/xrange 
  py3:       range 

  6. 
  py2: int / long
  py3: int 

  7. input/raw_input 

  8. 
  py2: yield
  py3: yield/yield from 

  9. 
  py2: 新式類和經典類
  py3: 新式類

17. 用一行代碼實現數值交換

a,b=b,a

18. Python3和Python2中 int 和 long的區別?

python3 完全廢棄了 long+int 雙整數實現的方法, 統一爲 int , 支持高精度整數運算.

19. xrange和range的區別?

函數說明:和range 的用法徹底相同,可是返回的是一個生成器。

20. 文件操做時:xreadlines和readlines的區別?

1) read([size])方法從文件當前位置起讀取size個字節,若無參數size,則表示讀取至文件結束爲止,它範圍爲字符串對象
    2) 從字面意思能夠看出,該方法每次讀出一行內容,因此,讀取時佔用內存小,比較適合大文件,該方法返回一個字符串對象。
    3) readlines()方法讀取整個文件全部行,保存在一個列表(list)變量中,每行做爲一個元素,但讀取大文件會比較佔內存。

21. 列舉布爾值爲False的常見值?

布爾型,False表示False,其餘爲True
  整數和浮點數,0表示False,其餘爲True
  字符串和類字符串類型(包括bytes和unicode),空字符串表示False,其餘爲True
  序列類型(包括tuple,list,dict,set等),空表示False,非空表示True
  None永遠表示False

22. 字符串、列表、元組、字典每一個經常使用的5個方法?

- 字符串  split/strip/replace/find/index ...
  - 列表     append/extend/insert/push/pop/reverse/sort ...
  - 元組     len/max/min/count/index ...
  - 字典     keys/values/pop/clear/del ...
  - 集合  add/remove/clear/交集&、並集 |、差集 - 
   
  - collections  Python內建的一個集合模塊,提供了許多有用的集合類。
      1.Counter是一個簡單的計數器,例如,統計字符出現的個數;
      2.OrderedDict能夠實現一個FIFO(先進先出)的dict,當容量超出限制時,先刪除最先添加的Key;
      3.deque是爲了高效實現插入和刪除操做的雙向列表,適合用於隊列和棧;
      4.defaultdict使用dict時,若是引用的Key不存在,就會拋出KeyError。若是但願key不存在時,返回一個默認值,就能夠用defaultdict;

23. lambda表達式格式以及應用場景?

省去函數命名的煩惱
  http://www.cnblogs.com/guigujun/p/6134828.html

24. pass的做用?

當你在編寫一個程序時,執行語句部分思路尚未完成,這時你能夠用pass語句來佔位,也能夠當作是一個標記,是要事後來完成的代碼。

25. arg和kwarg做用

*args:(表示的就是將實參中按照位置傳值,多出來的值都給args,且以元組的方式呈現)
  **kwargs:(表示的就是形參中按照關鍵字傳值把多餘的傳值以字典的方式呈現)
  http://www.cnblogs.com/xuyuanyuan123/p/6674645.html

26. is和==的區別

is 比較的是兩個實例對象是否是徹底相同,它們是否是同一個對象,佔用的內存地址是否相同。萊布尼茨說過:「世界上沒有兩片徹底相同的葉子」,這個is正是這樣的比較,比較是否是同一片葉子(即比較的id是否相同,這id相似於人的身份證標識)。

  == 比較的是兩個對象的內容是否相等,即內存地址能夠不同,內容同樣就能夠了。這裏比較的並不是是同一片葉子,可能葉子的種類或者脈絡相同就能夠了。默認會調用對象的 __eq__()方法。

27. 簡述Python的深淺拷貝以及應用場景?

Python採用基於值得內存管理模式,賦值語句的執行過程是:首先把等號右側標識的表達式計算出來,而後在內存中找一個位置把值存放進去,最後建立變量並指向這個內存地址。Python中的變量並不直接存儲值,而是存儲了值的內存地址或者引用
  簡單地說,淺拷貝只拷貝一層(若是有嵌套),深拷貝拷貝全部層。
  一層的狀況:
    import copy

    # 淺拷貝

    li1 = [1, 2, 3]
    li2 = li1.copy()
    li1.append(4)
    print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3]

    # 深拷貝

    li1 = [1, 2, 3]
    li2 = copy.deepcopy(li1)
    li1.append(4)
    print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3]
  多層的狀況:
    import copy

    # 淺拷貝

    li1 = [1, 2, 3, [4, 5], 6]
    li2 = li1.copy()
    li1[3].append(7)
    print(li1, li2)  # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5, 7], 6]

    # 深拷貝

    li1 = [1, 2, 3, [4, 5], 6]
    li2 = copy.deepcopy(li1)
    li1[3].append(7)
    print(li1, li2)  # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5], 6]

28. Python垃圾回收機制?

Python GC主要使用引用計數(reference counting)來跟蹤和回收垃圾。在引用計數的基礎上,經過「標記-清除」(mark and sweep)解決容器對象可能產生的循環引用問題,經過「分代回收」(generation collection)以空間換時間的方法提升垃圾回收效率。

  1 引用計數

  PyObject是每一個對象必有的內容,其中ob_refcnt就是作爲引用計數。當一個對象有新的引用時,它的ob_refcnt就會增長,當引用它的對象被刪除,它的ob_refcnt就會減小.引用計數爲0時,該對象生命就結束了。

  優勢:

  簡單 實時性 缺點:

  維護引用計數消耗資源 循環引用

  2 標記-清除機制

  基本思路是先按需分配,等到沒有空閒內存的時候從寄存器和程序棧上的引用出發,遍歷以對象爲節點、以引用爲邊構成的圖,把全部能夠訪問到的對象打上標記,而後清掃一遍內存空間,把全部沒標記的對象釋放。

  3 分代技術

  分代回收的總體思想是:將系統中的全部內存塊根據其存活時間劃分爲不一樣的集合,每一個集合就成爲一個「代」,垃圾收集頻率隨着「代」的存活時間的增大而減少,存活時間一般利用通過幾回垃圾回收來度量。

  Python默認定義了三代對象集合,索引數越大,對象存活時間越長。

  http://python.jobbole.com/82061/

29. Python的可變類型和不可變類型?

在Python中不可變對象指:一旦建立就不可修改的對象,包括字符串,元組,數字

  在Python中可變對象是指:能夠修改的對象,包括:列表、字典

30. 求可變數據類型結果

v = dict.fromkeys(['k1','k2'],[])
  v['k1'].append(666)
  print(v)    # {'k1': [666], 'k2': [666]}
  v['k1'] = 777
  print(v)    # {'k1': 777, 'k2': [666]}

31. 求匿名函數結果

def num():
    return[lambda x: i*x for i in range(4)]

  print([m(2) for m in num()])    # [6, 6, 6, 6]

32. 列舉常見的內置函數?

long(x)
    float(x)  # 把x轉換成浮點數
    complex(x) # 轉換成複數
    str(x)   # 轉換成字符串
    list(x)  # 轉換成列表
    tuple(x) # 轉換成元組
     
    進制相互轉換
     r= bin(10) #二進制
     r= int(10) #十進制

     r = oct(10) #八進制
     r = hex(10) #十六進制
     i= int("11",base=10)#進制間的相互轉換base後跟 2/8/10/16
     print(i)
     
    chr(x)//返回x對應的字符,如chr(65)返回‘A'
    ord(x)//返回字符對應的ASC碼數字編號,如ord('A')返回65
    abs(),all(),any(),bin(),bool(),bytes(),chr(),dict()dir(),divmod(),enumerate(),eval(),filter(),float(),gloabls(),help(),hex(),id(),input(),int(),isinstance(),len(),list(),locals(),map(),max(),min(),oct(),open(),ord(),pow(),print(),range(),round(),set(),type(),sorted(),str(),sum(),tuple()

33. filter、map、reduce的做用?

filter:對於序列中的元素進行篩選,最終獲取符合條件的序列
  map:遍歷序列,對序列中每一個元素進行操做,最終獲取新的序列
  reduce:對於序列內全部元素進行累計操做

34. 一行代碼實現9乘9乘法表

print("\n".join("\t".join(["%s*%s=%s" %(x,y,x*y) for y in range(1, x+1)]) for x in range(1, 10)) )

35. 如何安裝第三方模塊?以及用過哪些第三方模塊?

- pip包管理器
  - 源碼安裝
      - 下載->解壓->cd 到對應路徑
      - python setup.py build
      - python setup.py install

36. 經常使用模塊都有哪些?

- re/json/logging/os/sys/requests/beautifulsoup4

37. re的match和search區別?

match和search的區別

  re.match只匹配字符串的開始,若是字符串開始不符合正則表達式,則匹配失敗,函數返回None;
  re.search匹配整個字符串,直到找到一個匹配。

38. 什麼是正則的貪婪匹配?

貪婪和非貪婪
  正則表達式一般用於在文本中查找匹配的字符串。Python裏數量詞默認是貪婪的(在少數語言裏也多是默認非貪婪),老是嘗試匹配儘量多的字符;非貪婪則相反,老是嘗試匹配儘量少的字符。在"*","?","+","{m,n}"後面加上?,使貪婪變成非貪婪。

39. 求結果:a. [ i % 2 for i in range(10) ] b. ( i % 2 for i in range(10) )

[ i % 2 for i in range(10) ]  # [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
  ( i % 2 for i in range(10) )  # <generator object <genexpr> at 0x0000000003180FC0>

40. 求結果:a. 1 or 2 b. 1 and 2 c. 1 < (2==2) d. 1 < 2 == 2

1
  2
  False
  True

41. def func(a,b=[]) 這種寫法有什麼坑?

def func(a, b=[]):
      b.append(a)
      return b
   
   
  s = func(1)
  print(s)  # [1]
  s = func(1)
  print(s)  # [1, 1]
   
  # 第二次調用的時候 b的初始值是[1]了

42. 如何實現 「1,2,3」 變成 [‘1’,’2’,’3’] ?

list("1,2,3".split(','))

43. 如何實現[‘1’,’2’,’3’]變成[1,2,3] ?

[int(x) for x in ['1','2','3']]

44. 比較: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的區別?

前兩個列表內是int
  最後一個列表內是元組

45. 如何用一行代碼生成[1,4,9,16,25,36,49,64,81,100] ?

i*i for i in range(1,11)]

46. 一行代碼實現刪除列表中重複的值 ?

list(set([1, 2, 3, 4, 45, 1, 2, 343, 2, 2]))

47. 如何在函數中設置一個全局變量 ?

在函數中定義的局部變量若是和全局變量同名,則它會隱藏該全局變量。若是想在函數中使用全局變量,則須要使用global進行聲明。

48. logging模塊的做用?以及應用場景?

logging模塊是Python內置的標準模塊,主要用於輸出運行日誌,能夠設置輸出日誌的等級、日誌保存路徑、日誌文件回滾等;相比print,具有以下優勢:

    能夠經過設置不一樣的日誌等級,在release版本中只輸出重要信息,而沒必要顯示大量的調試信息;

    print將全部信息都輸出到標準輸出中,嚴重影響開發者從標準輸出中查看其它數據;logging則能夠由開發者決定將信息輸出到什麼地方,以及怎麼輸出。
    https://www.cnblogs.com/testdjt/p/7834856.html

49. 請用代碼簡單實現一個棧。

# 後進先出
  class Stack():
      def __init__(self, size):
          self.size = size
          self.stack = []
          self.top = -1

      # 入棧以前檢查棧是否已滿
      def push(self, x):
          if self.isfull():
              raise exception("stack is full")
          else:
              self.stack.append(x)
              self.top = self.top + 1

      # 出棧以前檢查棧是否爲空
      def pop(self):
          if self.isempty():
              raise exception("stack is empty")
          else:
              self.top = self.top - 1
              self.stack.pop()

      def isfull(self):
          return self.top + 1 == self.size

      def isempty(self):
          return self.top == '-1'

      def showStack(self):
          print(self.stack)


  s = Stack(10)
  for i in range(6):
      s.push(i)  # 入棧
  s.showStack()  # [0, 1, 2, 3, 4, 5]

  for i in range(2):
      s.pop()  # 出棧
  s.showStack()  # [0, 1, 2, 3]

50. 經常使用字符串格式化哪幾種?

Python的字符串格式化有兩種方式:%格式符方式,format方式

51. 簡述 生成器、迭代器、可迭代對象 以及應用場景?

若是給定一個list或tuple,咱們能夠經過for循環來遍歷這個list或tuple,這種遍歷咱們稱爲迭代(Iteration)剛纔說過,不少容器都是可迭代對象,此外還有更多的對象一樣也是可迭代對象,好比處於打開狀態的files,sockets等等。但凡是能夠返回一個 迭代器 的對象均可稱之爲可迭代對象
  那麼什麼迭代器呢?它是一個帶狀態的對象,他能在你調用 next() 方法的時候返回容器中的下一個值,任何實現了 __next__() (python2中實現 next() )方法的對象都是迭代器
  生成器算得上是Python語言中最吸引人的特性之一,生成器實際上是一種特殊的迭代器,不過這種迭代器更加優雅。生成器(yield)不須要再像上面的類同樣寫 __iter__() 和 __next__() 方法了,只須要一個 yiled 關鍵字。 生成器有以下特徵是它必定也是迭代器(反之不成立),所以任何生成器也是以一種懶加載的模式生成值。
  http://www.cnblogs.com/yuanchenqi/articles/5769491.html

52. 用Python實現一個二分查找的函數。

def bin_search_rec(data_set, value, low, high):
      if low <= high:
          mid = (low + high) // 2
          if data_set[mid] == value:
              return mid
          elif data_set[mid] > value:
              return bin_search_rec(data_set, value, low, mid - 1)
          else:
              return bin_search_rec(data_set, value, mid + 1, high)
      else:
          return

53. 談談你對閉包的理解?

https://www.cnblogs.com/Lin-Yi/p/7305364.html

54. os和sys模塊的做用?

os就是一個普通的python庫,用來向Python程序提供運行環境,特別是在文件系統、建立新進程、獲取操做系統自己的一些信息(好比uname),並屏蔽各類不一樣操做系統之間的細節差別。
  sys模塊則是python程序用來請求解釋器行爲的接口。好比關於調試類的(trace, frames,except)等,profiling類(stats, getsizeof),運行時環境類(python path, stderr, stdout),解釋器自己(如version)。inspect某種程度上能夠當作是在sys提供的功能上的一個包裝。

55. 如何生成一個隨機數?

random.randint(a,b)

56. 如何使用python刪除一個文件?

刪除子目錄
  os.rmdir( path )   # path: "要刪除的子目錄"

  產生異常的可能緣由:
  (1) path 不存在
  (2) path 子目錄中有文件或下級子目錄
  (3) 沒有操做權限或只讀

  刪除文件
  os.remove(   filename )   # filename: "要刪除的文件名"

  產生異常的可能緣由:
  (1)   filename 不存在
  (2) 對filename文件, 沒有操做權限或只讀。

57. 談談你對面向對象的理解?

從三大特性提及:繼承、封裝、多態
  
  封裝:
      起始就是將不少數據封裝到一個對象中,相似於把不少東西放到一個箱子中,
      如:一個函數若是好多參數,起始就能夠把參數封裝到一個對象再傳遞。
      
      在哪裏用過:
        - django rest framework中的request對象。
        - flask中:ctx_context/app_context對象
  繼承:
      若是多個類中都有共同的方法,那麼爲了不反覆編寫,就能夠將方法提取到基類中實現,
      讓全部派生類去繼承便可。
      
      在哪裏用過?
        - 視圖
        - 版本、認證、分頁
  多態:
      python自己就是多態的,崇尚鴨子模型,只要會呱呱叫的就是鴨子。
      def func(arg):
        arg.send()
  https://www.cnblogs.com/iyouyue/p/8535796.html

58. Python面向對象中的繼承有什麼特色?

Python3的繼承機制
    子類在調用某個方法或變量的時候,首先在本身內部查找,若是沒有找到,則開始根據繼承機制在父類裏查找。
    根據父類定義中的順序,以深度優先的方式逐一查找父類!
    繼承參數的書寫有前後順序,寫在前面的被優先繼承。

59. 面向對象深度優先和廣度優先是什麼?

繼承順序
  http://www.liujiangblog.com/course/python/44

60. 面向對象中super的做用?

咱們都知道,在子類中若是有與父類同名的成員,那就會覆蓋掉父類裏的成員。那若是你想強制調用父類的成員呢?使用super()函數!這是一個很是重要的函數,最多見的就是經過super調用父類的實例化方法__init__!

  語法:super(子類名, self).方法名(),須要傳入的是子類名和self,調用的是父類裏的方法,按父類的方法須要傳入參數。
  class A:
      def __init__(self, name):
          self.name = name
          print("父類的__init__方法被執行了!")
      def show(self):
          print("父類的show方法被執行了!")

  class B(A):
      def __init__(self, name, age):
          super(B, self).__init__(name=name)
          self.age = age

      def show(self):
          super(B, self).show()

  obj = B("jack", 18)
  obj.show()

61. 是否使用過functools中的函數?其做用是什麼?

1.functools.partial
  官網文檔說的真是很差理解,就看成是把一個函數,綁定部分或者所有參數後生成一個新版本的函數
  2.functools.partialwrap
  文檔說的比較詳細,若是不使用這個wraps,那麼原始函數的__name__和__doc__都會丟失
  https://blog.csdn.net/secretx/article/details/51700361

62. 列舉面向對象中帶雙下劃線的特殊方法,如:newinit

__init__ :      構造函數,在生成對象時調用
  __del__ :       析構函數,釋放對象時使用
  __repr__ :      打印,轉換
  __setitem__ :   按照索引賦值
  __getitem__:    按照索引獲取值
  __len__:        得到長度
  __cmp__:        比較運算
  __call__:       調用
  __add__:        加運算
  __sub__:        減運算
  __mul__:        乘運算
  __div__:        除運算
  __mod__:        求餘運算
  __pow__:        冪
  https://ltoddy.github.io/essay/2018/05/27/python-magic-methods.html

63. 如何判斷是函數仍是方法?

print(isinstance(obj.func, FunctionType))   # False
  print(isinstance(obj.func, MethodType))    # True

  示例:
  class Foo(object):
      def __init__(self):
          self.name = 'lcg'
   
      def func(self):
          print(self.name)
   
   
  obj = Foo()
  print(obj.func)  # <bound method Foo.func of <__main__.Foo object at 0x000001ABC0F15F98>>
   
  print(Foo.func)  # <function Foo.func at 0x000001ABC1F45BF8>
   
  # ------------------------FunctionType, MethodType------------#
   
   
  from types import FunctionType, MethodType
   
  obj = Foo()
  print(isinstance(obj.func, FunctionType))  # False
  print(isinstance(obj.func, MethodType))  # True
   
  print(isinstance(Foo.func, FunctionType))  # True
  print(isinstance(Foo.func, MethodType))  # False
   
  # ------------------------------------------------------------#
  obj = Foo()
  Foo.func(obj)  # lcg
   
  obj = Foo()
  obj.func()  # lcg
   
  """
  注意:
      方法,無需傳入self參數
      函數,必須手動傳入self參數
  """

64. 靜態方法和類方法區別?

classmethod 必須有一個指向類對象的引用做爲第一個參數,而 staticmethod 能夠沒有任何參數

  class Num:
      # 普通方法:能用Num調用而不能用實例化對象調用   
      def one():  
          print ('1')
   
      # 實例方法:能用實例化對象調用而不能用Num調用
      def two(self):
          print ('2')
   
      # 靜態方法:能用Num和實例化對象調用
      @staticmethod 
      def three():  
          print ('3')
   
      # 類方法:第一個參數cls長什麼樣不重要,都是指Num類自己,調用時將Num類做爲對象隱式地傳入方法   
      @classmethod 
      def go(cls): 
          cls.three() 
   
  Num.one()          #1
  #Num.two()         #TypeError: two() missing 1 required positional argument: 'self'
  Num.three()        #3
  Num.go()           #3
   
  i=Num()                
  #i.one()           #TypeError: one() takes 0 positional arguments but 1 was given         
  i.two()            #2      
  i.three()          #3
  i.go()             #3

65. 列舉面向對象中的特殊成員以及應用場景

http://www.cnblogs.com/bainianminguo/p/8076329.html

66. 一、二、三、四、5 能組成多少個互不相同且無重複的三位數

i = 0
  for x in range(1, 6):
      for y in range(1, 6):
          for z in range(1, 6):
              if (x != y) and (y != z) and (z != x):
                  i += 1
                  if i % 4:
                      print("%d%d%d" % (x, y, z), end=" | ")
                  else:
                      print("%d%d%d" % (x, y, z))
  print(i)

67. 什麼是反射?以及應用場景?

反射就是經過字符串的形式,導入模塊;經過字符串的形式,去模塊尋找指定函數,並執行。利用字符串的形式去對象(模塊)中操做(查找/獲取/刪除/添加)成員,一種基於字符串的事件驅動!
  https://www.cnblogs.com/vipchenwei/p/6991209.html

68. metaclass做用?以及應用場景?

metaclass用來指定類是由誰建立的。

  類的metaclass 默認是type。咱們也能夠指定類的metaclass值。
  http://www.cnblogs.com/0bug/p/8578747.html

69. 用盡可能多的方法實現單例模式。

http://python.jobbole.com/87294/
  http://www.cnblogs.com/0bug/p/8576802.html
  經常使用方式:
      使用模塊
      使用 __new__
      使用裝飾器(decorator)
      使用元類(metaclass)

70. 裝飾器的寫法以及應用場景。

裝飾器的應用場景:好比插入日誌,性能測試,事務處理,緩存等等場景。
  def outer(func):
      def inner(*args,**kwargs):
          print("認證成功!")
          result = func(*args,**kwargs)
          print("日誌添加成功")
          return result
      return inner

  @outer
  def f1(name,age):
      print("%s 正在鏈接業務部門1數據接口......"%name)

  # 調用方法
  f1("jack",18)
  http://www.cnblogs.com/iyouyue/p/8934547.html

71. 異常處理寫法以及如何主動跑出異常(應用場景)

while True:
    try:
        x = int(input("Please enter a number: "))
        break
    except ValueError:
        print("Oops!  That was no valid number.  Try again   ")


  raise主動拋出一個異常
  http://www.runoob.com/python3/python3-errors-execptions.html

72. 什麼是面向對象的mro

mro就是方法解析順序。
  方法解析順序Method Resolution Order
  參考:http://www.cnblogs.com/0bug/p/8728570.html#_label8

73. isinstance做用以及應用場景?

用於判斷一個對象是不是一個類或者其子類的實例。
  class A:
      pass
   
   
  class b(A):
      pass
   
   
  class c(b):
      pass
   
   
  bb = b()
   
  print(isinstance(bb, A))  # True
  print(isinstance(bb, b))  # True
  print(isinstance(bb, c))  # False

74. 寫代碼並實現LeetCode兩數之和:

## Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would 
  ## have exactly one solution, and you may not use the same element twice.
  ## Example:

  ##           Given nums = [2, 7, 11, 15], target = 9,
  ##            
Because nums[0] + nums[1] = 2 + 7 = 9,
  ##            return [0, 1]


  class Solution:  
    def twoSum(self,nums, target):  
        """ 
        :type nums: List[int] 
        :type target: int 
        :rtype: List[int] 
        """  
        #用len()方法取得nums列表長度  
        n = len(nums)  
        #x從0到n取值(不包括n)  
        for x in range(n):  
            a = target - nums[x]  
            #用in關鍵字查詢nums列表中是否有a  
            if a in nums:  
                #用index函數取得a的值在nums列表中的索引  
                y = nums.index(a)  
                #假如x=y,那麼就跳過,不然返回x,y  
                if x == y:  
                    continue  
                else:  
                    return x,y  
                    break  
            else :  
                continue  
  https://blog.csdn.net/linfeng886/article/details/79772348

75. json序列化時,能夠處理的數據類型有哪些?如何定製支持datetime類型?

import json
  from json import JSONEncoder
  from datetime import datetime
  class ComplexEncoder(JSONEncoder):
      def default(self, obj):
          if isinstance(obj, datetime):
              return obj.strftime('%Y-%m-%d %H:%M:%S')
          else:
              return super(ComplexEncoder,self).default(obj)
  d = { 'name':'alex','data':datetime.now()}
  print(json.dumps(d,cls=ComplexEncoder))
  # {"name": "alex", "data": "2018-05-18 19:52:05"}

  https://www.cnblogs.com/tkqasn/p/6005025.html

76. json序列化時,默認遇到中文會轉換成unicode,若是想要保留中文怎麼辦?

在序列化時,中文漢字老是被轉換爲unicode碼,在dumps函數中添加參數ensure_ascii=False便可解決。

77. 什麼是斷言?應用場景?

python assert斷言是聲明其布爾值必須爲真的斷定,若是發生異常就說明表達示爲假

  好比我想測試 a==1。就能夠用斷言。若是個人猜測錯誤就會拋出異常,能夠用於測試一段表達式是否成立。

78. 有用過with statement嗎?它的好處是什麼?

with語句適用於對資源進行訪問的場合,確保無論使用過程當中是否發生異常都會執行必要的「清理」操做,釋放資源,好比文件使用後自動關閉、線程中鎖的自動獲取和釋放等。

79. 使用代碼實現查看列舉目錄下的全部文件。

# 方法一:(不使用os.walk)
  def print_directory_contents(sPath):
      import os

      for sChild in os.listdir(sPath):
          sChildPath = os.path.join(sPath, sChild)
          if os.path.isdir(sChildPath):
              print_directory_contents(sChildPath)
          else:
              print(sChildPath)
              
  # 方法二:(使用os.walk)
  def print_directory_contents(sPath):
      import os
      for root, _, filenames in os.walk(sPath):
          for filename in filenames:
              print(os.path.abspath(os.path.join(root, filename)))


  print_directory_contents('已知路徑')

  sPath-- 是你所要便利的目錄的地址, 返回的是一個三元組(root,dirs,files)。
      root 所指的是當前正在遍歷的這個文件夾的自己的地址
      _ 是一個 list ,內容是該文件夾中全部的目錄的名字(不包括子目錄)
      filenames 一樣是 list , 內容是該文件夾中全部的文件(不包括子目錄)

80. 簡述 yield和yield from關鍵字。

https://blog.csdn.net/chenbin520/article/details/78111399?locationNum=7&fps=1

===============第二部分 網絡編程和併發(34題)===============

1. 簡述 OSI 七層協議。

a) 四層協議:應用層、傳輸層、網絡層、網絡接口層

  b) 五層協議:

  應用層:用戶使用的應用程序都歸屬於應用層,做用爲規定應用程序的數據格式。

  傳輸層:網絡層幫咱們找到主機,可是區分應用層的應用就是靠端口,因此傳輸層就是創建端口到端口的通訊。(端口範圍0-65535,0-1023爲系統佔用端口)

  網絡層:區分不一樣的廣播域或者子網(不然發送一條數據全世界都會受到,是災難)。

  數據鏈路層:定義電信號的分組方式。

  物理層:基於電器特性發送高低點電壓(電信號),高電壓對應數字1,低電壓對應數字0。

  c)七層協議:(應用層、表示層、會話層)、傳輸層、網絡層、(數據鏈路層、物理層)

2. 什麼是C/S和B/S架構?

1.什麼是C/S結構
  C/S (Client/Server)結構,即客戶機和服務器結構。它是軟件系統體系結構,經過它能夠充分利用兩端硬件環境的優點,將任務合理分配到Client端和Server端來實現,下降了系統的通信開銷。
  C/S結構能夠看作是胖客戶端架構。客戶端實現絕大多數的業務邏輯處理和界面展現,做爲客戶端的部分須要承受很大的壓力,從分利用客戶端的資源,對客戶機的要求較高。
  其實現能夠是客戶端包含一個或多個在用戶的電腦上運行的程序,而服務器端有兩種,一種是數據庫服務器端,客戶端經過數據庫鏈接訪問服務器端的數據;另外一種是Socket服務器端,服務器端的程序經過Socket與客戶端的程序通訊。
  目前大多數應用軟件系統都是Client/Server形式的兩層結構,因爲如今的軟件應用系統正在向分佈式的Web應用發展,Web和Client/Server 應用均可以進行一樣的業務處理,應用不一樣的模塊共享邏輯組件;所以,內部的和外部的用戶均可以訪問新的和現有的應用系統,經過現有應用系統中的邏輯能夠擴展出新的應用系統。這也就是目前應用系統的發展方向。
  傳統的C/S體系結構雖然採用的是開放模式,但這只是系統開發一級的開放性,在特定的應用中不管是Client端仍是Server端都還須要特定的軟件支持。因爲沒能提供用戶真正指望的開放環境,C/S結構的軟件須要針對不一樣的操做系統系統開發不一樣版本的軟件,加之產品的更新換代十分快,已經很難適應百臺電腦以上局域網用戶同時使用。並且代價高, 效率低。

  2.什麼是B/S結構
  B/S(Browser/Server)結構即瀏覽器和服務器結構。它是隨着Internet技術的興起,對C/S結構的一種變化或者改進的結構。在這種結構下,用戶工做界面是經過WWW瀏覽器來實現,極少部分事務邏輯在前端(Browser)實現,可是主要事務邏輯在服務器端(Server)實現,造成所謂三層3-tier結構。這樣就大大簡化了客戶端電腦載荷,減輕了系統維護與升級的成本和工做量,下降了用戶的整體成本(TCO)。
  B/S結構能夠看做是瘦客戶端,只是把顯示的較少的邏輯交給了Web瀏覽器,事務邏輯數據處理在放在了Server端,這樣就避免了龐大的胖客戶端,減小了客戶端的壓力。B/S結構的系統無須特別安裝,只有Web瀏覽器便可。固然AJAX\Flex等等的廣泛使用也有富客戶端的發展方向。
  以目前的技術看,局域網創建B/S結構的網絡應用,並經過Internet/Intranet模式下數據庫應用,相對易於把握、成本也是較低的。它是一次性到位的開發,能實現不一樣的人員,從不一樣的地點,以不一樣的接入方式(好比LAN, WAN, Internet/Intranet等)訪問和操做共同的數據庫;它能有效地保護數據平臺和管理訪問權限,服務器數據庫也很安全 。特別是在JAVA這樣的跨平臺語言出現以後,B/S架構管理軟件更是方便、快捷、高效。
  https://blog.csdn.net/sinat_35111396/article/details/51535784

3. 簡述 三次握手、四次揮手的流程。

1 三次握手
  客戶端經過向服務器端發送一個SYN來建立一個主動打開,做爲三次握手的一部分。客戶端把這段鏈接的序號設定爲隨機數 A。
  服務器端應當爲一個合法的SYN回送一個SYN/ACK。ACK 的確認碼應爲 A+1,SYN/ACK 包自己又有一個隨機序號 B。
  最後,客戶端再發送一個ACK。當服務端受到這個ACK的時候,就完成了三路握手,並進入了鏈接建立狀態。此時包序號被設定爲收到的確認號 A+1,而響應則爲 B+1。
  2 四次揮手
  注意: 中斷鏈接端能夠是客戶端,也能夠是服務器端. 下面僅以客戶端斷開鏈接舉例, 反之亦然.

  客戶端發送一個數據分段, 其中的 FIN 標記設置爲1. 客戶端進入 FIN-WAIT 狀態. 該狀態下客戶端只接收數據, 再也不發送數據.
  服務器接收到帶有 FIN = 1 的數據分段, 發送帶有 ACK = 1 的剩餘數據分段, 確認收到客戶端發來的 FIN 信息.
  服務器等到全部數據傳輸結束, 向客戶端發送一個帶有 FIN = 1 的數據分段, 並進入 CLOSE-WAIT 狀態, 等待客戶端發來帶有 ACK = 1 的確認報文.
  客戶端收到服務器發來帶有 FIN = 1 的報文, 返回 ACK = 1 的報文確認, 爲了防止服務器端未收到須要重發, 進入 TIME-WAIT 狀態. 服務器接收到報文後關閉鏈接. 客戶端等待 2MSL 後未收到回覆, 則認爲服務器成功關閉, 客戶端關閉鏈接.
  圖解: http://blog.csdn.net/whuslei/article/details/6667471

4. 什麼是arp協議?

ARP協議,全稱「Address Resolution Protocol」,中文名是地址解析協議,使用ARP協議可實現經過IP地址得到對應主機的物理地址(MAC地址)。
  https://www.cnblogs.com/luchuangao/articles/6053742.html

5. TCP和UDP的區別?

TCP 
  收發兩端(客戶端和服務器端)都要有成對的socket,所以,發送端爲了將多個發往接收端的包,更有效的發到對方,使用了優化方法(Nagle算法),將屢次間隔較小、數據量小的數據,合併成一個大的數據塊,而後進行封包。這樣接收端就難於分辨,必須提供拆包機制。
  若是利用TCP每次發送數據,就與對方創建鏈接,而後雙方發送完一段數據後,就關閉鏈接,這樣就不會出現粘包問題(由於只有一種包結構,相似於http協議)。關閉鏈接主要要雙方都發送close鏈接。
  若是發送數據無結構,如文件傳輸,這樣發送方只管發送,接收方只管接收存儲便可,也不用考慮粘包
  若是雙方創建鏈接,須要在鏈接後一段時間內發送不一樣結構數據,就須要考慮粘包問題。因此通常可能會在頭加一個數據長度之類的包,以確保接收。
  UDP
  對於UDP,不會使用塊的合併優化算法。實際上目前認爲,是因爲UDP支持的是一對多的模式(注意區分不是併發模式),因此接收端的skbuff(套接字緩衝區)採用了鏈式結構來記錄每個到達的UDP包,在每一個UDP包中有消息頭(消息來源地址,端口等信息),這樣對於接收端來講,就容易進行區分處理了,因此UDP不會出現粘包問題。

6. 什麼是局域網和廣域網?

1、局域網 
  局域網(Local Area Network),簡稱LAN,是指在某一區域內由多臺計算機互聯成的計算機組。「某一區域」指的是同一辦公室、同一建築物、同一公司和同一學校等,通常是方圓幾公里之內。局域網能夠實現文件管理、應用軟件共享、打印機共享、掃描儀共享、工做組內的日程安排、電子郵件和傳真通訊服務等功能。局域網是封閉型的,能夠由辦公室內的兩臺計算機組成,也能夠由一個公司內的上千臺計算機組成。 
  2、廣域網 
  廣域網(Wide Area Network),簡稱WAN,是一種跨越大的、地域性的計算機網絡的集合。一般跨越省、市,甚至一個國家。廣域網包括大大小小不一樣的子網,子網能夠是局域網,也能夠是小型的廣域網。 
  3、局域網和廣域網的區別 
  局域網是在某一區域內的,而廣域網要跨越較大的地域,那麼如何來界定這個區域呢?例如,一家大型公司的總公司位於北京,而分公司遍及全國各地,若是該公司將全部的分公司都經過網絡聯接在一塊兒,那麼一個分公司就是一個局域網,而整個總公司網絡就是一個廣域網。

7. 爲什麼基於tcp協議的通訊比基於udp協議的通訊更可靠?

tcp:可靠 對方給了確認收到信息,才發下一個,若是沒收到確認信息就重發
  udp:不可靠 一直髮數據,不須要對方迴應

8. 什麼是socket?簡述基於tcp協議的套接字通訊流程。

Socket是應用層與TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有。

  服務端:建立socket對象,綁定ip端口bind(),  設置最大連接數listen(),  accept()與客戶端的connect()建立雙向管道, send(), recv(),close()

  客戶端:建立socket對象,connect()與服務端accept()建立雙向管道 ,  send(), recv(),close()

9. 什麼是粘包? socket 中形成粘包的緣由是什麼?

粘包:數據粘在一塊兒,主要由於:接收方不知道消息之間的界限,不知道一次性提取多少字節的數據形成的
  數據量比較小,時間間隔比較短,就合併成了一個包,這是底層的一個優化算法(Nagle算法)

10. IO多路複用的做用?

I/O multiplexing就是所謂的select,poll,epoll,也稱這種I/O方式爲事件驅動I/O(event driven I/O)。
    select/epoll的好處就在於單個進程就能夠同時處理多個網絡鏈接的I/O。  它的基本原理就是select/poll/epoll這個function會不斷的輪詢所負責的全部socket,當某個socket有數據到達了,就通知用戶進程。
  I/O 多路複用的特色是經過一種機制使一個進程能同時等待多個文件描述符,而這些文件描述符(套接字描述符)其中的任意一個進入讀就緒狀態,select()函數就能夠返回。

  多道技術的實現就是爲了解決多個程序競爭或者共享同一個資源(好比cpu)的有序調度問題,解決方式便是多路複用。多路複用分爲時間上的複用和空間上的複用,空間上的多路複用是指將內存分爲幾部分,每一部分放一個程序,這樣同一時間內存中就有多道程序,前提保證內存是分割;時間上的多路複用是指多個程序須要在一個cpu上運行,不一樣的程序輪流使用cpu,當某個程序運行的時間過長或者遇到I/O阻塞,操做系統會把cpu分配給下一個程序,保證cpu處於高使用率,實現僞併發。

11. 什麼是防火牆以及做用?

http://www.cnblogs.com/loneywang/archive/2007/09/30/912029.html

12. select、poll、epoll 模型的區別?

https://www.cnblogs.com/Anker/p/3265058.html

13. 簡述 進程、線程、協程的區別 以及應用場景?

什麼是進程
  進程(有時稱爲重量級進程)是一個執行中的程序。每一個進程都擁有本身的地址空間、內存、數據棧以及其餘用於跟蹤執行的輔助數據。同一個程序執行兩次,屬因而兩個不一樣進程。
  什麼是線程
    線程,有時被稱爲輕量級進程(Lightweight Process,LWP),是程序執行流的最小單元。與同屬一個進程的其它線程共享進程所擁有的所有資源。一個線程能夠建立和撤消另外一個線程,同一進程中的多個線程之間能夠併發執行。因爲線程之間的相互制約,導致線程在運行中呈現出間斷性。線程也有就緒、阻塞和運行三種基本狀態。
    就緒狀態是指線程具有運行的全部條件,邏輯上能夠運行,在等待處理機; 運行狀態是指線程佔有處理機正在運行;
    阻塞狀態是指線程在等待一個事件(如某個信號量),邏輯上不可執行。
  什麼是協程
    協程是「微線程」,並不是實際存在;是由程序員人爲創造出來並控制程序:先執行某段代碼、再跳到某處執行某段代碼。
  若是遇到非IO請求來回切換:性能更低。
  若是遇到IO(耗時)請求來回切換:性能高、實現併發(本質上利用IO等待的過程,再去幹一些其餘的事)

  進程池與線程池
  基於多進程或多線程實現併發的套接字通訊,然而這種方式的缺陷是:服務的開啓的進程數或線程數都會隨着併發的客戶端數目地增多而增多,這對服務端主機帶來巨大的壓力,因而必須對服務端開啓的進程數或線程數加以控制,讓機器在一個本身能夠承受的範圍內運行,這就是進程池或線程池的用途,例如進程池,就是用來存放進程的池子,本質仍是基於多進程,只不過是對開啓進程的數目加上了限制。

  一、進程和線程的區別?

  答:進程擁有一個完整的虛擬地址空間,不依賴於線程而獨立存在;反之,線程是進程的一部分,沒有本身的地址空間,與進程內的其餘線程一塊兒共享分配給該進程的全部資源。

  好比:開個QQ,開了一個進程;開了迅雷,開了一個進程。在QQ的這個進程裏,傳輸文字開一個線程、傳輸語音開了一個線程、彈出對話框又開了一個線程。因此運行某個軟件,至關於開了一個進程。在這個軟件運行的過程裏(在這個進程裏),多個工做支撐的完成QQ的運行,那麼這「多個工做」分別有一個線程。因此一個進程管着多個線程。通俗的講:「進程是爹媽,管着衆多的線程兒子」。

  參考自:https://www.zhihu.com/question/25532384

  二、爲何說python的線程是僞線程?

  答:在python的原始解釋器CPython中存在着GIL(Global Interpreter Lock,全局解釋器鎖),所以在解釋執行python代碼時,會產生互斥鎖來限制線程對共享資源的訪問,直到解釋器遇到I/O操做或者操做次數達到必定數目時纔會釋放GIL。

  因此,雖然CPython的線程庫直接封裝了系統的原生線程,但CPython總體做爲一個進程,同一時間只會有一個線程在跑,其餘線程則處於等待狀態。這就形成了即便在多核CPU中,多線程也只是作着分時切換而已。

  參考自:https://www.zhihu.com/question/23474039

  三、python的append和extend有什麼區別?

  答:extend()接受一個列表參數,把參數列表的元素添加到列表的尾部,append()接受一個對象參數,把對象添加到列表的尾部。

14. GIL鎖是什麼鬼?

線程全局鎖(Global Interpreter Lock),即Python爲了保證線程安全而採起的獨立線程運行的限制,說白了就是一個核只能在同一時間運行一個線程.對於io密集型任務,python的多線程起到做用,但對於cpu密集型任務,python的多線程幾乎佔不到任何優點,還有可能由於爭奪資源而變慢。

  解決辦法就是多進程和下面的協程(協程也只是單CPU,可是能減少切換代價提高性能).

15. Python中如何使用線程池和進程池?

進程池:就是在一個進程內控制必定個數的線程
  基於concurent.future模塊的進程池和線程池 (他們的同步執行和異步執行是同樣的)
  http://www.cnblogs.com/haiyan123/p/7461294.html

16. threading.local的做用?

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

    問題:本身經過字典建立一個相似於threading.local的東西。
        storage={
            4740:{val:0},
            4732:{val:1},
            4731:{val:3},
            ...
        }

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

        try:
            from greenlet import getcurrent as get_ident
        except Exception as e:
            from threading import get_ident

        from threading import Thread
        import time

        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()

17. 進程之間如何進行通訊?

進程間通訊主要包括管道, 系統IPC(包括消息隊列,信號,共享存儲), 套接字(SOCKET).
  管道包括三種:
    1)普通管道PIPE, 一般有兩種限制,一是單工,只能單向傳輸;二是隻能在父子或者兄弟進程間使用.
    2)流管道s_pipe: 去除了第一種限制,爲半雙工,能夠雙向傳輸.
    3)命名管道:name_pipe, 去除了第二種限制,能夠在許多並不相關的進程之間進行通信.

18. 什麼是併發和並行?

若是某個系統支持兩個或者多個動做(Action)同時存在,那麼這個系統就是一個併發系統。若是某個系統支持兩個或者多個動做同時執行,那麼這個系統就是一個並行系統。併發系統與並行系統這兩個定義之間的關鍵差別在於「存在」這個詞。
  在併發程序中能夠同時擁有兩個或者多個線程。這意味着,若是程序在單核處理器上運行,那麼這兩個線程將交替地換入或者換出內存。這些線程是同時「存在」的——每一個線程都處於執行過程當中的某個狀態。若是程序可以並行執行,那麼就必定是運行在多核處理器上。此時,程序中的每一個線程都將分配到一個獨立的處理器核上,所以能夠同時運行。
  我相信你已經可以得出結論——「並行」概念是「併發」概念的一個子集。也就是說,你能夠編寫一個擁有多個線程或者進程的併發程序,但若是沒有多核處理器來執行這個程序,那麼就不能以並行方式來運行代碼。所以,凡是在求解單個問題時涉及多個執行流程的編程模式或者執行行爲,都屬於併發編程的範疇。

  摘自:《併發的藝術》 — 〔美〕佈雷謝斯

19. 進程鎖和線程鎖的做用?

線程鎖:你們都不陌生,主要用來給方法、代碼塊加鎖。當某個方法或者代碼塊使用鎖時,那麼在同一時刻至多僅有有一個線程在執行該段代碼。當有多個線程訪問同一對象的加鎖方法/代碼塊時,同一時間只有一個線程在執行,其他線程必需要等待當前線程執行完以後才能執行該代碼段。可是,其他線程是能夠訪問該對象中的非加鎖代碼塊的。

  進程鎖:也是爲了控制同一操做系統中多個進程訪問一個共享資源,只是由於程序的獨立性,各個進程是沒法控制其餘進程對資源的訪問的,可是能夠使用本地系統的信號量控制(操做系統基本知識)。

  分佈式鎖:當多個進程不在同一個系統之中時,使用分佈式鎖控制多個進程對資源的訪問。

  http://www.cnblogs.com/intsmaze/p/6384105.html

20. 解釋什麼是異步非阻塞?

同步異步指的是在客戶端
  同步意味着客戶端提出了一個請求之後,在迴應以前只能等待
  異步意味着 客戶端提出一個請求之後,還能夠繼續提其餘請求阻塞

  非阻塞 指的是服務器端
  阻塞意味着服務器接受一個請求後,在返回結果之前不能接受其餘請求
  非阻塞意味着服務器接受一個請求後,儘管沒有返回結果,仍是能夠繼續接受其餘請求

21. 路由器和交換機的區別?

交換機工做於數據鏈路層,用來隔離衝突域,鏈接的全部設備同屬於一個廣播域(子網),負責子網內部通訊。

  路由器工做於網絡層,用來隔離廣播域(子網),鏈接的設備分屬不一樣子網,工做範圍是多個子網之間,負責網絡與網絡之間通訊。
  https://www.zhihu.com/question/20465477

22. 什麼是域名解析?

域名解析是把域名指向網站空間IP,讓人們經過註冊的域名能夠方便地訪問到網站的一種服務。IP地址是網絡上標識站點的數字地址,爲了方便記憶,採用域名來代替IP地址標識站點地址。域名解析就是域名到IP地址的轉換過程。域名的解析工做由DNS服務器完成。

23. 如何修改本地hosts文件?

1)hosts文件的位置:C:\windows\system32\drivers\etc,文件夾中找到Hosts文件並用記事本打開。

  2)按照 ip地址  域名 的格式添加單獨的一行記錄。例如
  112.124.39.29 www.server110.com
  注意,IP地址前面不要有空格,ip地址和域名之間,要有至少1個空格。
  修改後,必定要記得保存文件。

  3)如何知道域名的IP地址已經生效?
  在您的電腦上請按以下步驟操做:開始-->運行-->輸入cmd-->ping 域名-->回車查看結果
  顯示結果相似 Reply from 220.181.31.183: bytes=32 time=79ms TTL=53
  中間的  220.181.31.183 就是域名的IP地址

  * 注意:有些瀏覽器會保存DNS緩存,好比Chrome。多按幾回F5刷新便可。
  https://www.cnblogs.com/cl-blogs/p/4160483.html

24. 生產者消費者模型應用場景及優點?

生產者消費者模型

  在併發編程中使用生產者和消費者模式可以解決絕大多數併發問題。該模式經過平衡生產線程和消費線程的工做能力來提升程序的總體處理數據的速度。

    爲何要使用生產者和消費者模式

  在線程世界裏,生產者就是生產數據的線程,消費者就是消費數據的線程。在多線程開發當中,若是生產者處理速度很快,而消費者處理速度很慢,那麼生產者就必須等待消費者處理完,才能繼續生產數據。一樣的道理,若是消費者的處理能力大於生產者,那麼消費者就必須等待生產者。爲了解決這個問題因而引入了生產者和消費者模式。

    什麼是生產者消費者模式

  生產者消費者模式是經過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通信,而經過阻塞隊列來進行通信,因此生產者生產完數據以後不用等待消費者處理,直接扔給阻塞隊列,消費者不找生產者要數據,而是直接從阻塞隊列裏取,阻塞隊列就至關於一個緩衝區,平衡了生產者和消費者的處理能力。

  http://www.cnblogs.com/huchong/p/7454756.html

25. 什麼是CDN?

CDN主要功能是在不一樣的地點緩存內容,經過負載均衡技術,將用戶的請求定向到最合適的緩存服務器上去獲取內容,好比說,是北京的用戶,咱們讓他訪問北京的節點,深圳的用戶,咱們讓他訪問深圳的節點。經過就近訪問,加速用戶對網站的訪問。解決Internet網絡擁堵情況,提升用戶訪問網絡的響應速度。
  CDN的全稱是Content Delivery Network,即內容分發網絡。其基本思路是儘量避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。經過在網絡各處放置節點服務器所構成的在現有的互聯網基礎之上的一層智能虛擬網絡,CDN系統可以實時地根據網絡流量和各節點的鏈接、負載情況以及到用戶的距離和響應時間等綜合信息將用戶的請求從新導向離用戶最近的服務節點上。其目的是使用戶可就近取得所需內容,解決 Internet網絡擁擠的情況,提升用戶訪問網站的響應速度。

26. LVS是什麼及做用?

LVS 是 Linux  Virtual Server ,Linux 虛擬服務器;是一個虛擬的服務器集羣【多臺機器 LB IP】。LVS 集羣分爲三層結構:

  1) 負載調度器(load balancer):它是整個LVS 集羣對外的前端機器,負責將client請求發送到一組服務器[多臺LB IP]上執行,而client端認爲是返回來一個同一個IP【一般把這個IP 稱爲虛擬IP/VIP】
  2) 服務器池(server pool):一組真正執行client 請求的服務器,通常是咱們的web服務器;除了web,還有FTP,MAIL,DNS
  3) 共享存儲(shared stored):它爲 server pool 提供了一個共享的存儲區,很容易讓服務器池擁有相同的內容,提供相同的服務[不是很理解]

  https://blog.csdn.net/caoshuming_500/article/details/8291940

27. Nginx是什麼及做用?

Nginx是一個輕量級、高性能、穩定性高、併發性好的HTTP和反向代理服務器。
  https://blog.csdn.net/b9x__/article/details/80400697
  https://www.cnblogs.com/xiohao/p/6433401.html

28. keepalived是什麼及做用?

https://baike.baidu.com/item/Keepalived/10346758?fr=aladdin

29. haproxy是什麼以及做用?

https://baike.baidu.com/item/haproxy/5825820

30. 什麼是負載均衡?

負載均衡 創建在現有網絡結構之上,它提供了一種廉價有效透明的方法擴展網絡設備和服務器的帶寬、增長吞吐量、增強網絡數據處理能力、提升網絡的靈活性和可用性。
  負載均衡,英文名稱爲Load Balance,其意思就是分攤到多個操做單元上進行執行,例如Web服務器、FTP服務器、企業關鍵應用服務器和其它關鍵任務服務器等,從而共同完成工做任務。
  https://baike.baidu.com/item/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1

31.什麼是RPC及應用場景?

RPC(Remote Procedure Call)—遠程過程調用,它是一種經過網絡從遠程計算機程序上請求服務,而不須要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,爲通訊程序之間攜帶信息數據。在OSI網絡通訊模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分佈式多程序在內的應用程序更加容易。
  RPC採用客戶機/服務器模式。請求程序就是一個客戶機,而服務提供程序就是一個服務器。首先,客戶機調用進程發送一個有進程參數的調用信息到服務進程,而後等待應答信息。在服務器端,進程保持睡眠狀態直到調用信息到達爲止。當一個調用信息到達,服務器得到進程參數,計算結果,發送答覆信息,而後等待下一個調用信息,最後,客戶端調用進程接收答覆信息,得到進程結果,而後調用執行繼續進行。

32.簡述 asynio模塊的做用和應用場景。

https://www.cnblogs.com/zhaof/p/8490045.html

33.簡述 gevent模塊的做用和應用場景。

https://www.cnblogs.com/zcqdream/p/6196040.html

34.twisted框架的使用和應用?

http://www.cnblogs.com/zhiyong-ITNote/p/7360442.html

===============第三部分 數據庫和緩存(46題)===============

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

MySQL/SqlServer  MongoDB/Redis
  https://db-engines.com/en/ranking

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

MyISAM 適合於一些須要大量查詢的應用,但其對於有大量寫操做並非很好。甚至你只是須要update一個字段,整個表都會被鎖起來,而別的進程,就算是讀進程都沒法操做直到讀操做完成。另外,MyISAM 對於 SELECT COUNT(*) 這類的計算是超快無比的。

  InnoDB 的趨勢會是一個很是複雜的存儲引擎,對於一些小的應用,它會比 MyISAM 還慢。他是它支持「行鎖」 ,因而在寫操做比較多的時候,會更優秀。而且,他還支持更多的高級應用,好比:事務。

  mysql 數據庫引擎: http://www.cnblogs.com/0201zcr/p/5296843.html
  MySQL存儲引擎--MyISAM與InnoDB區別: https://segmentfault.com/a/1190000008227211

3. 簡述數據三大範式?

第一範式:確保每列的原子性.
      若是每列(或者每一個屬性)都是不可再分的最小數據單元(也稱爲最小的原子單元),則知足第一範式.
      例如:顧客表(姓名、編號、地址、……)其中"地址"列還能夠細分爲國家、省、市、區等。
  第二範式:在第一範式的基礎上更進一層,目標是確保表中的每列都和主鍵相關.
      若是一個關係知足第一範式,而且除了主鍵之外的其它列,都依賴於該主鍵,則知足第二範式.
      例如:訂單表(訂單編號、產品編號、定購日期、價格、……),"訂單編號"爲主鍵,"產品編號"和主鍵列沒有直接的關係,即"產品編號"列不依賴於主鍵列,應刪除該列。
  第三範式:在第二範式的基礎上更進一層,目標是確保每列都和主鍵列直接相關,而不是間接相關.
      若是一個關係知足第二範式,而且除了主鍵之外的其它列都不依賴於主鍵列,則知足第三範式.
      爲了理解第三範式,須要根據Armstrong千米之必定義傳遞依賴。假設A、B和C是關係R的三個屬性,若是A-〉B且B-〉C,則從這些函數依賴中,能夠得出A-〉C,如上所述,依賴A-〉C是傳遞依賴。
      例如:訂單表(訂單編號,定購日期,顧客編號,顧客姓名,……),初看該表沒有問題,知足第二範式,每列都和主鍵列"訂單編號"相關,再細看你會發現"顧客姓名"和"顧客編號"相關,"顧客編號"和"訂單編號"又相關,最後通過傳遞依賴,"顧客姓名"也和"訂單編號"相關。爲了知足第三範式,應去掉"顧客姓名"列,放入客戶表中。

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

數據庫事務(Database Transaction) ,是指做爲單個邏輯工做單元執行的一系列操做,要麼徹底地執行,要麼徹底地不執行。
  完全理解數據庫事務: http://www.hollischuang.com/archives/898

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

一對一關係示例:
    一個學生對應一個學生檔案材料,或者每一個人都有惟一的身份證編號。
  一對多關係示例:(下拉單選)
    一個學生只屬於一個班,可是一個班級有多名學生。
  多對多關係示例:(下拉多選)
    一個學生能夠選擇多門課,一門課也有多名學生。

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

http://www.cnblogs.com/phpcoder/p/4665850.html

7. 常見SQL(必備)

## 詳見武沛齊博客:https://www.cnblogs.com/wupeiqi/articles/5729934.html

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

1)存儲過程?
    一組爲了完成特定功能的SQL 語句集,經編譯後存儲在數據庫。用戶經過指定存儲過程的名字並給出參數(若是該存儲過程帶有參數)來執行它。存儲過程在建立時即在服務器上進行編譯,因此執行起來比單個SQL語句快,由於調用存儲過程比直接向服務端發送大量SQL語句在執行速度快。
  對於存儲過程,能夠接收參數,其參數有三類:
   in          僅用於傳入參數用
   out        僅用於返回值用
   inout     既能夠傳入又能夠看成返回值
  2)函數?
    封裝一段sql代碼,完成一種特定的功能,必須返回結果。其他特性基本跟存儲過程相同
  3)函數與存儲過程的區別?
    3.1) 函數有且只有一個返回值,而存儲過程不能有返回值。
    3.2) 存儲過程能夠實現很複雜的業務邏輯,函數有不少限制。不能在函數中使用insert,update,delete,create等語句
    3.3)存儲過程能夠調用函數。但函數不能調用存儲過程。
    3.4)存儲過程通常是做爲一個獨立的部分來調用。而函數能夠做爲查詢語句的一個部分來調用。
  4)視圖?
    視圖是基於 SQL 語句的結果集的可視化虛擬表。
    視圖中的字段來自一個或多個數據庫中的真實表的字段。視圖並不在數據庫中以存儲數據值集形式存在,而存在於實際引用的數據庫表中,視圖的構成能夠是單表查詢,多表聯合查詢,分組查詢以及計算(表達式)查詢等。行和列數據在引用視圖時動態生成
  5)觸發器?
    觸發器(TRIGGER)與函數相似,須要聲明、執行。可是觸發器的執行不是由程序調用,而是由事件來觸發從而實現執行。對某個表進行【增/刪/改】操做的先後若是但願觸發某個特定的行爲時,能夠使用觸發器,觸發器用於定製用戶對錶的行進行【增/刪/改】先後的行爲

9. MySQL索引種類

MySQL目前主要有如下幾種索引類型:
  1.普通索引
  2.惟一索引
  3.主鍵索引
  4.組合索引
  5.全文索引
  https://www.cnblogs.com/luyucheng/p/6289714.html

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

https://www.cnblogs.com/jamesbd/p/4333901.html

11. 主鍵和外鍵的區別?

1.主鍵是能肯定一條記錄的惟一標識,好比,一條記錄包括身份正號,姓名,年齡。身份證號是惟一能肯定你這我的的,其餘均可能有重複,因此,身份證號是主鍵。 
  2.外鍵用於與另外一張表的關聯。是能肯定另外一張表記錄的字段,用於保持數據的一致性。一個表能夠有多個外鍵。

12. MySQL常見的函數?

https://blog.csdn.net/sugang_ximi/article/details/6664748

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

- like '%xx'
      select * from tb1 where name like '%cn';
  - 使用函數
      select * from tb1 where reverse(name) = 'wupeiqi';
  - or
      select * from tb1 where nid = 1 or email = 'seven@live.com';
      特別的:當or條件中有未創建索引的列才失效,如下會走索引
              select * from tb1 where nid = 1 or name = 'seven';
              select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'
  - 類型不一致
      若是列是字符串類型,傳入條件是必須用引號引發來,否則...
      select * from tb1 where name = 999;
  - !=
      select * from tb1 where name != 'alex'
      特別的:若是是主鍵,則仍是會走索引
          select * from tb1 where nid != 123
  - >
      select * from tb1 where name > 'alex'
      特別的:若是是主鍵或索引是整數類型,則仍是會走索引
          select * from tb1 where nid > 123
          select * from tb1 where num > 123
  - order by
      select email from tb1 order by name desc;
      當根據索引排序時候,選擇的映射若是不是索引,則不走索引
      特別的:若是對主鍵排序,則仍是走索引:
          select * from tb1 order by nid desc;

  https://www.cnblogs.com/iyouyue/p/9004018.html#_label34

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

https://www.jianshu.com/p/9f9c9326f8f4

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

- 導出現有數據庫數據:
          mysqldump -u用戶名 -p密碼 數據庫名稱 >導出文件路徑         # 結構+數據
          mysqldump -u用戶名 -p密碼 -d 數據庫名稱 >導出文件路徑     # 結構 
  - 導入現有數據庫數據:
          mysqldump -uroot -p密碼 數據庫名稱 < 文件路徑

16. 數據庫優化方案?

1. 避免全表掃描,首先應考慮在 where 及 orderby 涉及的列上創建索引。
  2. 避免在 where 子句中對字段進行 null 值判斷,致使引擎放棄使用索引而進行全表掃描 
  3. 避免在 where 子句中使用 != 或>操做符,引擎將放棄使用索引而進行全表掃描。
  4. 避免在 where 子句中使用or 來鏈接條件
  5. 慎用in 和 not, 能夠用 exists 代替 in
  6. 慎用 like 'XXX%',要提升效率,能夠全文檢索。
  7. 應儘可能避免在 where 子句中對字段進行表達式操做,如:
  select id from t where num/2=100
  應改成select id from t where num=100*2
  8. 避免在where子句中對字段進行函數操做
  select id from t where substring(name,1,3)='abc' 
  改成:
  select id from t where name like 'abc%'
  9. 在使用索引字段做爲條件時,若是該索引是複合索引,那麼必須使用到該索引中的第一個字段做爲條件時才能保證系統使用該索引,不然該索引將不會被使用,而且應儘量的讓字段順序與索引順序相一致。(索引的最左前綴原則) 
  10. 並非全部索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重複時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那麼即便在sex上建了索引也對查詢效率起不了做用。
  11. 索引不是越多越好,索引能夠提升select 的效率,同時也下降 insert 及 update 的效率,由於 insert 或 update 時有可能會重建索引。
  12. 任何地方都不要使用 select * from t ,用具體的字段列表代替「*」
  13. 避免頻繁建立和刪除臨時表,以減小系統表資源的消耗。
  14. 在新建臨時表時,若是一次性插入數據量很大,那麼能夠使用 select into 代替 create table,避免形成大量 log ,以提升速度;若是數據量不大,爲了緩和系統表的資源,應先create table,而後insert。
  15. 儘可能避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。
  數據庫中的數據在未進行分庫分表的狀況下,隨着時間和業務的發展,庫中的表會愈來愈多,表中的數據量也會愈來愈大,相應地,數據操做,增刪改查的開銷也會愈來愈大
  16. 讀寫分離。經過數據庫配置設置, mysql複製時,產生了多個數據副本(備庫),爲減小服務器壓力,備庫用於處理讀操做,主庫可同時處理讀寫。備庫的複製是異步的,沒法實時同步,讀寫分離的主要難點也在於備庫上的髒數據。一般若是使用備庫進行讀,通常對數據的實時性要求不能過高。
  17. 分庫、分表。
  分庫:當數據庫中的表太多,能夠考慮將表分到不一樣的數據庫
  分表
    水平分表:將一些列分到另外一張表
    垂直分表:將歷史信息分到另外一張表中,好久以前的記錄少有查詢
  18. 利用緩存存儲常常被查詢的數據。利用redis、memcache

17. char和varchar的區別?

區別一,定長和變長
  char 表示定長,長度固定,varchar表示變長,即長度可變。當所插入的字符串超出它們的長度時,視狀況來處理,若是是嚴格模式,則會拒絕插入並提示錯誤信息,若是是寬鬆模式,則會截取而後插入。若是插入的字符串長度小於定義長度時,則會以不一樣的方式來處理,如char(10),表示存儲的是10個字符,不管你插入的是多少,都是10個,若是少於10個,則用空格填滿。而varchar(10),小於10個的話,則插入多少個字符就存多少個。
  varchar怎麼知道所存儲字符串的長度呢?實際上,對於varchar字段來講,須要使用一個(若是字符串長度小於255)或兩個字節(長度大於255)來存儲字符串的長度。可是由於他須要有一個prefix來表示他具體bytes數是多少(由於varchar是變長的,沒有這個長度值他不知道如何讀取數據)。

  區別之二,存儲的容量不一樣
  對 char 來講,最多能存放的字符個數 255,和編碼無關。
  而 varchar 呢,最多能存放 65532 個字符。VARCHAR 的最大有效長度由最大行大小和使用的字符集肯定。總體最大長度是 65,532字節

18. 簡述MySQL的執行計劃?

EXPLAIN命令是查看優化器如何決定執行查詢的主要方法。能夠幫助咱們深刻了解MySQL的基於開銷的優化器,還能夠得到不少可能被優化器考慮到的訪問策略的細節,以及當運行SQL語句時哪一種策略預計會被優化器採用。
  http://www.cnblogs.com/clsn/p/8087501.html#auto_id_20

19. 在對name作了惟一索引前提下,簡述limit 1 做用

select * from tb where name = ‘Oldboy-Wupeiqi’ 
  select * from tb where name = ‘Oldboy-Wupeiqi’ 
  是這樣的的,用where條件過濾出符合條件的數據的同時,進行計數,好比limit 1,那麼在where過濾出第1條數據後,他就會直接把結果select出來返回給你,整個過程就結束了。

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

答案一:
      先查主鍵,在分頁。
      select * from tb where id in (
          select id from tb where limit 10 offset 30
      )
  答案二:
      按照也無需求是否能夠設置只讓用戶看200頁
      
  答案三:
      記錄當前頁  數據ID最大值和最小值
      在翻頁時,根據條件先進行篩選;篩選完畢以後,再根據limit offset 查詢。
      
      select * from (select * from tb where id > 22222222) as B limit 10 offset 0
      
      若是用戶本身修改頁碼,也可能致使慢;此時對url種的頁碼進行加密(rest framework )

21. 什麼是索引合併?

一、索引合併是把幾個索引的範圍掃描合併成一個索引。
  二、索引合併的時候,會對索引進行並集,交集或者先交集再並集操做,以便合併成一個索引。
  三、這些須要合併的索引只能是一個表的。不能對多表進行索引合併。

  簡單的說,索引合併,讓一條sql能夠使用多個索引。對這些索引取交集,並集,或者先取交集再取並集。從而減小從數據表中取數據的次數,提升查詢效率。

22. 什麼是覆蓋索引?

http://www.cnblogs.com/chenpingzhao/p/4776981.html

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

讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操做(INSERT、UPDATE、DELETE),而從數據庫處理SELECT查詢操做。數據庫複製被用來把事務性操做致使的變動同步到集羣中的從數據庫。
 https://blog.csdn.net/xybelieve1990/article/details/50830908

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

見23問題連接
  https://blog.csdn.net/xlgen157387/article/details/53976153

25. redis和memcached比較?

使用redis有哪些好處? 
  (1) 速度快,由於數據存在內存中,相似於HashMap,HashMap的優點就是查找和操做的時間複雜度都是O(1) 
  (2) 支持豐富數據類型,支持string,list,set,sorted set,hash 
  (3) 支持事務,操做都是原子性,所謂的原子性就是對數據的更改要麼所有執行,要麼所有不執行 
  (4) 豐富的特性:可用於緩存,消息,按key設置過時時間,過時後將會自動刪除

  redis相比memcached有哪些優點?   
  (1) memcached全部的值均是簡單的字符串,redis做爲其替代者,支持更爲豐富的數據類型 
  (2) redis的速度比memcached快不少 (3) redis能夠持久化其數據

  Memcache與Redis的區別都有哪些?   
  1)、存儲方式 Memecache把數據所有存在內存之中,斷電後會掛掉,數據不能超過內存大小。 Redis有部份存在硬盤上,這樣能保證數據的持久性。 
  2)、數據支持類型 Memcache對數據類型支持相對簡單。 Redis有複雜的數據類型。 
  3)、使用底層模型不一樣 它們之間底層實現方式 以及與客戶端之間通訊的應用協議不同。 Redis直接本身構建了VM 機制 ,由於通常的系統調用系統函數的話,會浪費必定的時間去移動和請求。 

  redis與 memcached相比,redis支持key-value數據類型,同時支持list、set、hash等數據結構的存儲。
  redis支持數據的備份,即master-slave模式的數據備份。
  redis支持數據的持久化。
  redis在不少方面支持數據庫的特性,能夠這樣說他就是一個數據庫系統,而memcached只是簡單地K/V緩存。
  它們在性能方面差異不是很大,讀取方面尤爲是針對批量讀取性能方面memcached佔據優點。固然redis也有他的優勢,如持久性、支持更多的數據結構。
  因此在選擇方面若是有持久方面的需求或對數據類型和處理有要求的應該選擇redis。
  若是簡單的key/value 存儲應該選擇memcached。

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

Redis默認支持16個數據庫(能夠經過配置文件支持更多,無上限),能夠經過配置databases來修改這一數字。客戶端與Redis創建鏈接後會自動選擇0號數據庫,不過能夠隨時使用SELECT命令更換數據庫
  Redis支持多個數據庫,而且每一個數據庫的數據是隔離的不能共享,而且基於單機纔有,若是是集羣就沒有數據庫的概念。

27. python操做redis的模塊?

https://www.cnblogs.com/Eva-J/p/5152841.html

28. 若是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)

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

https://blog.csdn.net/zhangguanghui002/article/details/78524533

30. redis中的sentinel的做用?

幫助咱們自動在主從之間進行切換
    檢測主從中 主是否掛掉,且超過一半的sentinel檢測到掛了以後才進行進行切換。
    若是主修復好了,再次啓動時候,會變成從。

    啓動主redis:
    redis-server /etc/redis-6379.conf  啓動主redis
    redis-server /etc/redis-6380.conf  啓動從redis
        
    在linux中:
        找到 /etc/redis-sentinel-8001.conf  配置文件,在內部:
            - 哨兵的端口 port = 8001
            - 主redis的IP,哨兵個數的一半/1
        
        找到 /etc/redis-sentinel-8002.conf  配置文件,在內部:
            - 哨兵的端口 port = 8002
            - 主redis的IP, 1 
    
        啓動兩個哨兵

31. 如何實現redis集羣?

redis集羣、分片、分佈式redis     
    redis-py-cluster
    集羣方案:
        - redis cluster 官方提供的集羣方案。
        - codis,豌豆莢技術團隊。
        - tweproxy,Twiter技術團隊。
    redis cluster的原理?
        - 基於分片來完成。
        - redis將全部能放置數據的地方建立了 16384 個哈希槽。
        - 若是設置集羣的話,就能夠爲每一個實例分配哈希槽:
            - 192.168.1.20【0-5000】
            - 192.168.1.21【5001-10000】
            - 192.168.1.22【10001-16384】
        - 之後想要在redis中寫值時,
            set k1 123 
          將k1經過crc16的算法,將k1轉換成一個數字。而後再將該數字和16384求餘,若是獲得的餘數 3000,那麼就將該值寫入到 192.168.1.20 實例中。

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

16384

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

RDB:每隔一段時間對redis進行一次持久化。
         - 缺點:數據不完整
         - 優勢:速度快
    AOF:把全部命令保存起來,若是想到從新生成到redis,那麼就要把命令從新執行一次。
         - 缺點:速度慢,文件比較大
         - 優勢:數據完整

34. 列舉redis支持的過時策略(數據淘汰策略)。

voltile-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(驅逐):禁止驅逐數據

35. 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(驅逐):禁止驅逐數據

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

from scrapy.utils.reqser import request_to_dict, request_from_dict

  from . import picklecompat


  class Base(object):
      """Per-spider base queue class"""

      def __init__(self, server, spider, key, serializer=None):
          """Initialize per-spider redis queue.

          Parameters
          ----------
          server : StrictRedis
              Redis client instance.
          spider : Spider
              Scrapy spider instance.
          key: str
              Redis key where to put and get messages.
          serializer : object
              Serializer object with ``loads`` and ``dumps`` methods.

          """
          if serializer is None:
              # Backward compatibility.
              # TODO: deprecate pickle.
              serializer = picklecompat
          if not hasattr(serializer, 'loads'):
              raise TypeError("serializer does not implement 'loads' function: %r"
                              % serializer)
          if not hasattr(serializer, 'dumps'):
              raise TypeError("serializer '%s' does not implement 'dumps' function: %r"
                              % serializer)

          self.server = server
          self.spider = spider
          self.key = key % {'spider': spider.name}
          self.serializer = serializer

      def _encode_request(self, request):
          """Encode a request object"""
          obj = request_to_dict(request, self.spider)
          return self.serializer.dumps(obj)

      def _decode_request(self, encoded_request):
          """Decode an request previously encoded"""
          obj = self.serializer.loads(encoded_request)
          return request_from_dict(obj, self.spider)

      def __len__(self):
          """Return the length of the queue"""
          raise NotImplementedError

      def push(self, request):
          """Push a request"""
          raise NotImplementedError

      def pop(self, timeout=0):
          """Pop a request"""
          raise NotImplementedError

      def clear(self):
          """Clear queue/stack"""
          self.server.delete(self.key)


  class FifoQueue(Base):
      """Per-spider FIFO queue"""

      def __len__(self):
          """Return the length of the queue"""
          return self.server.llen(self.key)

      def push(self, request):
          """Push a request"""
          self.server.lpush(self.key, self._encode_request(request))

      def pop(self, timeout=0):
          """Pop a request"""
          if timeout > 0:
              data = self.server.brpop(self.key, timeout)
              if isinstance(data, tuple):
                  data = data[1]
          else:
              data = self.server.rpop(self.key)
          if data:
              return self._decode_request(data)


  class PriorityQueue(Base):
      """Per-spider priority queue abstraction using redis' sorted set"""

      def __len__(self):
          """Return the length of the queue"""
          return self.server.zcard(self.key)

      def push(self, request):
          """Push a request"""
          data = self._encode_request(request)
          score = -request.priority
          # We don't use zadd method as the order of arguments change depending on
          # whether the class is Redis or StrictRedis, and the option of using
          # kwargs only accepts strings, not bytes.
          self.server.execute_command('ZADD', self.key, score, data)

      def pop(self, timeout=0):
          """
          Pop a request
          timeout not support in this queue class
          """
          # use atomic range/remove using multi/exec
          pipe = self.server.pipeline()
          pipe.multi()
          pipe.zrange(self.key, 0, 0).zremrangebyrank(self.key, 0, 0)
          results, count = pipe.execute()
          if results:
              return self._decode_request(results[0])


  class LifoQueue(Base):
      """Per-spider LIFO queue."""

      def __len__(self):
          """Return the length of the stack"""
          return self.server.llen(self.key)

      def push(self, request):
          """Push a request"""
          self.server.lpush(self.key, self._encode_request(request))

      def pop(self, timeout=0):
          """Pop a request"""
          if timeout > 0:
              data = self.server.blpop(self.key, timeout)
              if isinstance(data, tuple):
                  data = data[1]
          else:
              data = self.server.lpop(self.key)

          if data:
              return self._decode_request(data)


  # TODO: Deprecate the use of these names.
  SpiderQueue = FifoQueue
  SpiderStack = LifoQueue
  SpiderPriorityQueue = PriorityQueue

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

不要使用redis去作消息隊列,這不是redis的設計目標。
  但實在太多人使用redis去作去消息隊列,redis的做者看不下去,另外基於redis的核心代碼,另外實現了一個消息隊列disque:https://github.com/antirez/disque

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

發佈者:
      import redis

      conn = redis.Redis(host='127.0.0.1',port=6379)
      conn.publish('104.9MH', "hahaha")
  訂閱者:
      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)

39. 什麼是codis及做用?

Codis 是一個分佈式 Redis 解決方案, 對於上層的應用來講, 鏈接到 Codis Proxy 和鏈接原生的 Redis Server 沒有明顯的區別 (不支持的命令列表), 上層應用能夠像使用單機的 Redis 同樣使用, Codis 底層會處理請求的轉發, 不停機的數據遷移等工做, 全部後邊的一切事情, 對於前面的客戶端來講是透明的, 能夠簡單的認爲後邊鏈接的是一個內存無限大的 Redis 服務.

40. 什麼是twemproxy及做用?

是 Twtter 開源的一個 Redis 和 Memcache 代理服務器,主要用於管理 Redis 和 Memcached 集羣,減小與Cache 服務器直接鏈接的數量。

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

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', 'bendere')
  pipe.set('role', 'sb')

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

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

在Redis的事務中,WATCH命令可用於提供CAS(check-and-set)功能。假設咱們經過WATCH命令在事務執行以前監控了多個Keys,假若在WATCH以後有任何Key的值發生了變化,EXEC命令執行的事務都將被放棄,同時返回Null multi-bulk應答以通知調用者事務執行失敗。
  
  面試題:你如何控制剩餘的數量不會出問題?
      - 經過redis的watch實現
          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如何實現商城商品數量計數器?

Redis在內存中對數字進行遞增或遞減的操做實現的很是好。集合(Set)和有序集合(Sorted Set)也使得咱們在執行這些操做的時候變的很是簡單,Redis只是正好提供了這兩種數據結構。因此,咱們要從排序集合中獲取到排名最靠前的10個用戶–咱們
  稱之爲「user_scores」,咱們只須要像下面同樣執行便可:
  固然,這是假定你是根據你用戶的分數作遞增的排序。若是你想返回用戶及用戶的分數,你須要這樣執行:
  ZRANGE user_scores 0 10 WITHSCORES
  Agora Games就是一個很好的例子,用Ruby實現的,它的排行榜就是使用Redis來存儲數據的,你能夠在這裏看到

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

在不一樣進程須要互斥地訪問共享資源時,分佈式鎖是一種很是有用的技術手段。 有不少三方庫和文章描述如何用Redis實現一個分佈式鎖管理器,可是這些庫實現的方式差異很大,並且不少簡單的實現其實只需採用稍微增長一點複雜的設計就能夠得到更好的可靠性。 這篇文章的目的就是嘗試提出一種官方權威的用Redis實現分佈式鎖管理器的算法,咱們把這個算法稱爲RedLock。
  https://www.cnblogs.com/ironPhoenix/p/6048467.html
  https://blog.csdn.net/junli_chen/article/details/79228282

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

Python模塊--hash_ring,即Python中的一致性hash

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

redis 有一個keys命令。
  語法:KEYS pattern
  說明:返回與指定模式相匹配的所用的keys。
  該命令所支持的匹配模式以下:
  (1)?:用於匹配單個字符。例如,h?llo能夠匹配hello、hallo和hxllo等;
  (2)*:用於匹配零個或者多個字符。例如,h*llo能夠匹配hllo和heeeello等;
  (3)[]:能夠用來指定模式的選擇區間。例如h[ae]llo能夠匹配hello和hallo,可是不能匹配hillo。
  同時,能夠使用「/」符號來轉義特殊的字符

==============第四部分 前端、框架和其餘(155題)===============

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

流程:
      1.域名解析
      域名解析檢查順序爲:瀏覽器自身DNS緩存---》OS自身的DNS緩存--》讀取host文件--》本地域名服務器--》權限域名服務器--》根域名服務器。若是有且沒有過時,則結束本次域名解析。域名解析成功以後,進行後續操做
      2.tcp3次握手創建鏈接
      3.創建鏈接後,發起http請求
      4.服務器端響應http請求,瀏覽器獲得到http請求的內容
      5.瀏覽器解析html代碼,並請求html代碼中的資源
      6.瀏覽器對頁面進行渲染,展示在用戶面前

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

WebSocket是HTML5開始提供的一種瀏覽器與服務器間進行全雙工通信的網絡技術。依靠這種技術能夠實現客戶端和服務器端的長鏈接,雙向實時通訊。
  特色:
  事件驅動
  異步
  使用ws或者wss協議的客戶端socket

  可以實現真正意義上的推送功能

  缺點:
  少部分瀏覽器不支持,瀏覽器支持的程度與方式有區別。
  http://www.cnblogs.com/best/p/5695570.html#_label1

3. 什麼是magic string ?

魔法
  字符串

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

@media (min-width: 768px){
      .pg-header{
          background-color: green;
      }
  }
  @media (min-width: 992px){
      .pg-header{
          background-color: pink;
      }
  }

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

跳
  過

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

<script>
        function JqSendRequest(){
            $.ajax({
                url: "http://c2.com:8000/test/",
                type: 'GET',
                dataType: 'text',
                success: function(data, statusText, xmlHttpRequest){
                    console.log(data);
                }
            })
        }
    </script>
    http://www.cnblogs.com/wupeiqi/articles/5703697.html

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

輪詢:客戶端定時向服務器發送Ajax請求,服務器接到請求後立刻返回響應信息並關閉鏈接。 
  優勢:後端程序編寫比較容易。 缺點:請求中有大半是無用,浪費帶寬和服務器資源。 實例:適於小型應用。
  https://www.cnblogs.com/zhaowinter/p/5332681.html

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

客戶端向服務器發送Ajax請求,服務器接到請求後hold住鏈接,直到有新消息才返回響應信息並關閉鏈接,客戶端處理完響應信息後再向服務器發送新的請求。 
  優勢:在無消息的狀況下不會頻繁的請求,耗費資小。 
  缺點:服務器hold鏈接會消耗資源,返回數據順序無保證,難於管理維護。 Comet異步的ashx,
  實例:WebQQ、Hi網頁版、Facebook IM。

9. vuex的做用?

在使用庫或框架時,須要注意一個「適用性」的問題。
  Vuex 或者說實現了 Flux 思想的庫,解決了幾個問題:

  組件之間的數據通訊
  使用單向數據流的方式進行數據的中心化管理
  爲何要解決這樣的問題呢?實際上是由於當程序邏輯過於複雜的時候,非中心化的數據管理會讓整個 app 的邏輯很是混亂。
  舉一個不使用中心化的數據管理機制的具體例子:

  一個 app ,有四個 tab,每一個 tab 都須要讀取用戶的資料。若是數據在每一個 tab 的控制器裏(或者說組件裏)都存了一份,那麼在用戶手動更新了用戶資料以後,就須要在每個 tab 裏都更新一遍用戶資料,才能保證用戶看到的永遠是最新的資料。
  如你問題裏所說,我每進一個 tab 的時候從新請求一下不就行了嗎?
  這樣的解決方案不是不能夠,但弊端也很是明顯:

  1) 對於服務器端來講,頻繁的請求是很是佔用資源的,若是你的 app 用戶足夠多,那麼每多出一個請求,對公司來講,都是一大筆錢。若是數據存在了 store 中,而且全部的 tab 都讀取同一份數據,在用戶更新資料時,在前端更新了 store 中的數據,是否是在切換 tab 時就減小了四個請求呢?
  2) 對於前端開發者來講,若是你的項目足夠複雜,團隊的規模也不只是一我的,那麼前端代碼就會由於數據分散管理而產生很是嚴重的性能和穩定性的隱患(好比你的同事以爲進入模塊就刷新用戶資料太慢了,手賤把刷新的代碼刪了,你又沒發現)。
  https://segmentfault.com/q/1010000011402824

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

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

11. axios的做用?

https://blog.csdn.net/qq_27626333/article/details/76254888

12. 列舉Vue的常見指令。

一、v-if指令:判斷指令,根據表達式值得真假來插入或刪除相應的值。
  二、v-show指令:條件渲染指令,不管返回的布爾值是true仍是false,元素都會存在在html中,只是false的元素會隱藏在html中,並不會刪除.
  三、v-else指令:配合v-if或v-else使用。
  四、v-for指令:循環指令,至關於遍歷。
  五、v-bind:給DOM綁定元素屬性。
  六、v-on指令:監聽DOM事件。

13. 簡述JSONP及實現原理?

JSONP是json用來跨域的一個東西。原理是經過script標籤的跨域特性來繞過同源策略。(建立一個回調函數,而後在遠程服務上調用這個函數而且將json數據形式做爲參數傳遞,完成回調)。
  http://www.cnblogs.com/huchong/p/8469053.html

14. 是什麼CORS ?

跨域資源共享(CORS,Cross-Origin Resource Sharing),其本質是設置響應頭,使得瀏覽器容許跨域請求。
  http://www.cnblogs.com/huchong/p/8469063.html

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

請求方法有8種,分別爲:
    GET:請求獲取由 Request-URI 所標識的資源。
    POST:在 Request-URI 所標識的資源後附加新的數據。
    HEAD:請求獲取由 Request-URI 所標識的資源的響應消息報頭。
    OPTIONS:請求查詢服務器的性能,或查詢與資源相關的選項和需求。
    PUT:請求服務器存儲一個資源,並用 Request-URI做爲其標識。
    DELETE:請求服務器刪除由 Request-URI所標識的資源。
    TRACE:請求服務器回送收到的請求信息,主要用語測試或診斷。
    CONNECT:HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器。

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

常見的響應狀態碼有如下幾種,在各類下面分別列幾個常見的狀態碼:        
       1開頭(信息)
       2開頭(成功)
           200(OK):請求成功
           202(Accepted):已接受請求,還沒有處理
           204(No Content):請求成功,且不需返回內容
       3開頭(重定向)
           301(Moved Permanently):被請求的資源已永久移動到新位置
           301(Moved Temporarily):被請求的資源已臨時移動到新位置
       4開頭(客戶端錯誤)
           400(Bad Request):請求的語義或是參數有錯
           403(Forbidden):服務器拒絕了請求
           404(Not Found):未找到請求的資源
       5開頭(服務器錯誤)
          500(Internal Server Error):服務器遇到錯誤,沒法完成請求
          502(Bad Getway):網關錯誤,通常是服務器壓力過大致使鏈接超時       
          503(Service Unavailable):服務器宕機

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

Accept:
  瀏覽器端能夠接受的媒體類型,通配符 * 表明任意類型
  Accept-Encoding:
  瀏覽器申明本身接收的編碼方法,例如: Accept-Encoding: zh-CN,zh;q=0.8
  Accept-Language:
  瀏覽器申明本身接收的語言,
  Connection:
  如Connection: keep-alive 當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP鏈接不會關閉,
  若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接。
  Referer:
  當瀏覽器向web服務器發送請求的時候,通常會帶上Referer,告訴服務器我是從哪一個頁面連接過來的,服務器籍此能夠得到一些信息用於處理。
  User-Agent:
  告訴HTTP服務器, 客戶端使用的操做系統和瀏覽器的名稱和版本.
  Cookie:
  Cookie是用來存儲一些用戶信息以便讓服務器辨別用戶身份的(大多數須要登陸的網站上面會比較常見),好比cookie會存儲一些用戶的用戶名和密碼,
  當用戶登陸後就會在客戶端產生一個cookie來存儲相關信息,這樣瀏覽器經過讀取cookie的信息去服務器上驗證並經過後會斷定你是合法用戶,從而容許查看相應網頁。

18. 看圖寫結果:JS,略

19. 看圖寫結果:JS,略

20. 看圖寫結果:JS,略

21. 看圖寫結果:JS,略

22. 看圖寫結果:JS,略

23. 看圖寫結果:JS,略

24. django、flask、tornado框架的比較?

d:大而全
  f:微型靈活
  t:異步非阻塞

25. 什麼是wsgi?

Python Web服務器網關接口(Python Web Server Gateway Interface,縮寫爲WSGI)是Python應用程序或框架和Web服務器之間的一種接口,已經被普遍接受, 它已基本達成它的可移植性方面的目標。
  http://python.jobbole.com/88653/

26. django請求的生命週期?

a. wsgi, 建立socket服務端,用於接收用戶請求並對請求進行初次封裝。
  b. 中間件,對全部請求到來以前,響應以前定製一些操做。
  c. 路由匹配,在url和視圖函數對應關係中,根據當前請求url找到相應的函數。
  d. 執行視圖函數,業務處理【經過ORM去數據庫中獲取數據,再去拿到模板,而後將數據和模板進行渲染】
  e. 再通過全部中間件。
  f. 經過wsgi將響應返回給用戶。

27. 列舉django的內置組件?

form/modelform/admin

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

中間件中方法?5個方法,分別是:
      process_request(self,request)
      process_view(self, request, callback, callback_args, callback_kwargs)
      process_template_response(self,request,response)
      process_exception(self, request, exception)
      process_response(self, request, response)
      1 請求先執行全部中間件的process_request,而後作路由匹配,找到函數不執行。
      2 再執行全部的process_view,在執行視圖函數。
      3 再執行process_response
      4 若是程序報錯執行process_exception
      5 若是程序有render方法則執行process_template_response

29. 簡述什麼是FBV和CBV?

1 FBV方式請求的過程
  用戶發送url請求,Django會依次遍歷路由映射表中的全部記錄,一旦路由映射表其中的一條匹配成功了,
  就執行視圖函數中對應的函數名,這是fbv的執行流程

  2 CBV方式請求的過程
  當服務端使用CBV模式的時候,用戶發給服務端的請求包含url和method,這兩個信息都是字符串類型

  服務端經過路由映射表匹配成功後會自動去找dispatch方法,而後Django會經過dispatch反射的方式找到類中對應的方法並執行

  類中的方法執行完畢以後,會把客戶端想要的數據返回給dispatch方法,由dispatch方法把數據返回經客戶端

  把上面的例子中的視圖函數修改爲以下:
  from django.views import View

  class CBV(View):
      def dispatch(self, request, *args, **kwargs):
          print("dispatch......")
          res=super(CBV,self).dispatch(request,*args,**kwargs)
          return res

      def get(self,request):
          return render(request, "cbv.html")

      def post(self,request):
          return HttpResponse("cbv.get")

  3 FBV和CBV的區別?
      - 沒什麼區別,由於他們的本質都是函數。CBV的.as_view()返回的view函數,view函數中調用類的dispatch方法,在dispatch方法中經過反射執行get/post/delete/put等方法。
      - CBV比較簡潔,GET/POST等業務功能分別放在不一樣get/post函數中。FBV本身作判斷進行區分。

  http://www.cnblogs.com/renpingsheng/p/7534897.html

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

當請求一個頁面時, Django會創建一個包含請求元數據的 HttpRequest 對象. 當Django 加載對應的視圖時, HttpRequest對象將做爲視圖函數的第一個參數. 每一個視圖會返回一個HttpResponse對象.
  https://blog.csdn.net/mbl114/article/details/78090773

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('...')

  - csrf的裝飾器要加到dispath
      from django.views import View
      from django.utils.decorators import method_decorator
      from django.views.decorators.csrf import csrf_exempt,csrf_protect


      class UserView(View):
          @method_decorator(csrf_exempt)
          def dispatch(self, request, *args, **kwargs):
              return HttpResponse('...')
          
  或
      from django.views import View
      from django.utils.decorators import method_decorator
      from django.views.decorators.csrf import csrf_exempt,csrf_protect

      @method_decorator(csrf_exempt,name='dispatch')
      class UserView(View):
          def dispatch(self, request, *args, **kwargs):
              return HttpResponse('...')

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

返回QuerySet對象的方法有:
      all()
      filter()
      exclude()
      order_by()
      reverse()
      distinct()
  特殊的QuerySet:
      values()       返回一個可迭代的字典序列
      values_list() 返回一個可迭代的元組序列
  返回具體對象的:
      get()
      first()
      last()
  返回布爾值的方法有:
      exists()
  返回數字的方法有:
      count()

33. 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的區別?

title = models.CharField(max_length=32)

  class UserInfo(models.Model):
      name = models.CharField(max_length=32)
      email = models.CharField(max_length=32)
      ut = models.ForeignKey(to='UserType')
      ut = models.ForeignKey(to='UserType')
      ut = models.ForeignKey(to='UserType')
      ut = models.ForeignKey(to='UserType')
      
      
  # 1次SQL
  # select * from userinfo
  objs = UserInfo.obejcts.all()
  for item in objs:
      print(item.name)
      
  # n+1次SQL
  # select * from userinfo
  objs = UserInfo.obejcts.all()
  for item in objs:
      # select * from usertype where id = item.id 
      print(item.name,item.ut.title)

  示例1:        
  .select_related()
      # 1次SQL
      # select * from userinfo inner join usertype on userinfo.ut_id = usertype.id 
      objs = UserInfo.obejcts.all().select_related('ut')
      for item in objs:
          print(item.name,item.ut.title)
  示例2:
  .prefetch_related()
      # select * from userinfo where id <= 8
      # 計算:[1,2]
      # select * from usertype where id in [1,2]
      objs = UserInfo.obejcts.filter(id__lte=8).prefetch_related('ut')
      for obj in objs:
          print(obj.name,obj.ut.title)
  兩個函數的做用都是減小查詢次數

35. filter和exclude的區別?

def filter(self, *args, **kwargs)
      # 條件查詢(符合條件)
      # 條件能夠是:參數,字典,Q

  def exclude(self, *args, **kwargs)
      # 條件查詢(排除條件)
      # 條件能夠是:參數,字典,Q

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

1.使用execute執行自定義SQL
  # 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()

  2.使用extra方法 

  # 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"}, select_params=(1,), order_by=['-nid'])

  3.使用raw方法
    解釋:執行原始sql並返回模型
    說明:依賴model多用於查詢
    用法:
      book = Book.objects.raw("select * from hello_book")
      for item in book:
        print(item.title)
  https://www.cnblogs.com/413xiaol/p/6504856.html

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

class Router1:
      def allow_migrate(self, db, app_label, model_name=None, **hints):
          """
          All non-auth models end up in this pool.
          """
          if db=='db1' and app_label == 'app02':
              return True
          elif db == 'default' and app_label == 'app01':
              return True
          else:
              return False
          
          # 若是返回None,那麼表示交給後續的router,若是後續沒有router,則至關於返回True
          
      def db_for_read(self, model, **hints):
          """
          Attempts to read auth models go to auth_db.
          """
          if model._meta.app_label == 'app01':
              return 'default'
          else:
              return 'db1'

      def db_for_write(self, model, **hints):
          """
          Attempts to write auth models go to auth_db.
          """
          if model._meta.app_label == 'app01':
              return 'default'
          else:
              return 'db1'

38. F和Q的做用?

F:
  Django 支持 F() 對象之間以及 F() 對象和常數之間的加減乘除和取模的操做。
  修改操做也能夠使用F函數,好比將每一本書的價格提升30元

  例:把全部書名後面加上(初版)
      from django.db.models.functions import Concat
      from django.db.models import Value
      models.Book.objects.all().update(title=Concat(F("title"), Value("("), Value("初版"), Value(")")))
  Q:
  Q(條件1) | Q(條件2) 或
  Q(條件1) & Q(條件2) 且
  Q(條件1) & ~Q(條件2) 非

39. values和values_list的區別?

values()       返回一個可迭代的字典序列
    values_list() 返回一個可迭代的元組序列

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,'二B用戶'),(2,'山炮用戶')]
          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%}標籤
  https://blog.csdn.net/u012556900/article/details/57412707

45. django如何實現websocket?

https://www.cnblogs.com/huguodong/p/6611602.html

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

三種方式:
    https://www.cnblogs.com/wxp5257/p/7834090.html

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

LOGGING配置查看翻譯的SQL:
    在Django的日誌設置中,配置上一個名爲django.db.backends的logger實例便可查看翻譯後的SQL語句。
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }  
    http://www.cnblogs.com/owasp/p/5981355.html

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-server

  而後在settings.py 裏面添加CACHES = {
  'default': {
  'BACKEND': 'redis_cache.cache.RedisCache',
  'LOCATION': '127.0.0.1:6379',
  "OPTIONS": {
  "CLIENT_CLASS": "redis_cache.client.DefaultClient",
  },
  }

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

簡單說,name 能夠用於在 templates, models, views ……中獲得對應的網址,至關於「給網址取了個名字」,只要這個名字不變,網址變了也能經過名字獲取到。
    https://blog.csdn.net/liweiblog/article/details/77599604

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

simple_tag 
    -參數任意,可是不能做爲if條件判斷的條件
  filter 
    -參數最多隻能有兩個,可是能夠做爲if條件判斷的條件。
  http://www.cnblogs.com/cerofang/p/8367588.html

52. django-debug-toolbar的做用?

django_debug_toolbar 是django的第三方工具包,給django擴展了調試功能。 
  包括查看執行的sql語句,db查詢次數,request,headers,調試概覽等。 
  https://blog.csdn.net/weixin_39198406/article/details/78821677

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

https://www.jianshu.com/p/34267dd79ad6

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

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

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

https://jingyan.baidu.com/article/4ae03de3e513d23eff9e6bb7.html

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

ORM框架:

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

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

  ORM的優缺點:

  優勢: 
    提升開發效率,下降開發成本 
    使開發更加對象化 
    可移植 
    能夠很方便地引入數據緩存之類的附加功能 
  缺點: 
    在處理多表聯查、where條件複雜之類的查詢時,ORM的語法會變得複雜。就須要寫入原生SQL。

57. 簡述MVC和MTV

MTV和MVC?
        
  MVC: model view controller          
  MTV: model tempalte view

58. django的contenttype組件的做用?

contenttype是django的一個組件(app),爲咱們找到django程序中全部app中的全部表並添加到記錄中。
        
        能夠使用他再加上表中的兩個字段實現:一張表和N張表建立FK關係。
            - 字段:表名稱
            - 字段:數據行ID
            
        應用:路飛表結構優惠券和專題課和學位課關聯。
        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/
  -------------------------------------------------
    - https
    - 域名 
        - api.oldboy.com
        - www.oldboy.com/api
    - 版本:
        - www.oldboy.com/api/v1

    - URL資源,名詞
        - www.oldboy.com/api/v1/student

    - 請求方式:
        - GET/POST/PUT/DELETE/PATCH/OPTIONS/HEADERS/TRACE
    - 返回值:
        - www.oldboy.com/api/v1/student/    -> 結果集
        - www.oldboy.com/api/v1/student/1/  -> 單個對象
    - URL添加條件
        - www.oldboy.com/api/v1/student?page=11&size=9
    - 狀態碼:  
        - 200
        - 300
            - 301
            - 302
        - 400
            - 403
            - 404
        - 500
    - 錯誤信息
        {
            code:1000,
            meg:'xxxx'
        }
    - hyperlink
        {
            id:1
            name: ‘xiangl’,
            type: http://www.xxx.com/api/v1/type/1/
        }

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依靠證書來驗證服務器的身份,併爲瀏覽器和服務器之間的通訊加密。
  https://www.cnblogs.com/wqhwe/p/5407468.html

63. 爲何要使用django rest framework框架?

  1.客戶端-服務端分離

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

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

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

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

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

    4.統一接口

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

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

    優勢:提升可擴展性
  https://www.cnblogs.com/vipchenwei/p/7867028.html

64. django rest framework框架中都有那些組件?

- 路由,自動幫助開發者快速爲一個視圖建立4個url
            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
            - 定義方法
        - 請求數據格式校驗

    - 渲染器

65. django rest framework框架中的視圖均可以繼承哪些類?

a. 繼承 APIView
      這個類屬於rest framework中頂層類,內部幫助咱們實現了只是基本功能:認證、權限、頻率控制,但凡是數據庫、分頁等操做都須要手動去完成,比較原始。
      
  
  
     class GenericAPIView(APIView)
          
          def post(...):
              pass 
          
  b. 繼承 GenericViewSet(ViewSetMixin, generics.GenericAPIView)
      若是繼承它以後,路由中的as_view須要填寫對應關係    .as_view({'get':'list','post':'create'})
      在內部也幫助咱們提供了一些方便的方法:
          - get_queryset
          - get_object
          - get_serializer
      
      注意:要設置queryset字段,不然會跑出斷言的異常。
      # 只提供增長功能
      class TestView(GenericViewSet):
          serializer_class = XXXXXXX

          def create(self,*args,**kwargs):
              pass # 獲取數據並對數據進行操做
      
  c. 繼承 
          - ModelViewSet
          - mixins.CreateModelMixin,GenericViewSet
          - mixins.CreateModelMixin,DestroyModelMixin,GenericViewSet
  
      對數據庫和分頁等操做不用咱們在編寫,只須要繼承相關類便可。
      
      示例:只提供增長功能
      class TestView(mixins.CreateModelMixin,GenericViewSet):
          serializer_class = XXXXXXX
  http://www.cnblogs.com/iyouyue/p/8798572.html#_label3

66. 簡述 django rest framework框架的認證流程。

- 如何編寫?寫類並實現authticate
  - 方法中能夠定義三種返回值:
      - (user,auth),認證成功
      - None , 匿名用戶
      - 異常 ,認證失敗
  - 流程:
      - dispatch 
      - 再去request中進行認證處理
  https://www.cnblogs.com/haiyan123/p/8419872.html

67. django rest framework如何實現的用戶訪問頻率控制?

a. 基於用戶IP限制訪問頻率
  b. 基於用戶IP顯示訪問頻率(利於Django緩存) 
  c. view中限制請求頻率
  d. 匿名時用IP限制+登陸時用Token限制
  e. 全局使用
  REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'api.utils.throttles.throttles.LuffyAnonRateThrottle',
        'api.utils.throttles.throttles.LuffyUserRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/day',
        'user': '10/day',
        'luffy_anon': '10/m',
        'luffy_user': '20/m',
    },
  }
  https://www.cnblogs.com/vipchenwei/p/7867028.html

68. Flask框架的優點?

1、總體設計方面
  首先,二者都是很是優秀的框架。總體來說,二者設計的哲學是區別最大的地方。Django提供一站式的解決方案,從模板、ORM、Session、Authentication等等都分配好了,連app劃分都作好了,總之,爲你作儘可能多的事情,並且還有一個killer級的特性,就是它的admin,配合django-suit,後臺就出來了,其實最初Django就是由在新聞發佈公司工做的人設計的。Flask只提供了一些核心功能,很是簡潔優雅。它是一個微框架,其餘的由擴展提供,但它的blueprint使它也可以很方便的進行水平擴展。
  2、路由設計
  Django的路由設計是採用集中處理的方法,利用正則匹配。Flask也能這麼作,但更多的是使用裝飾器的形式,這個有優勢也有缺點,優勢是讀源碼時看到函數就知道怎麼用的,缺點是一旦源碼比較長,你要查路由就不太方便了,但這也促使你去思考如何更合理的安排代碼。
  3、應用模塊化設計
  Django的模塊化是集成在命令裏的,也就是說一開始Django的目標就是爲之後玩大了作準備的。每一個都是一個獨立的模塊,爲之後的複用提供了便利。Flask經過Blueprint來提供模塊化,本身對項目結構劃分紅不一樣的模塊進行組織。
  4、配置
  Django的配置主要仍是靠settings.py來作,固然爲了Development和Production環境分離,還有一些方法來處理配置。Flask的配置很靈活,有多種方法配置,不一樣環境的配置也很是方便。
  5、文檔
  二者都提供了詳盡的文檔,Flask的文檔風格很受我我的喜愛,Django的文檔也很是優秀,當時用學Django時,就是隻看了Django的文檔。
  6、社區
  Django社區很大,各類插件很齊全,大部分狀況下你都能找到你想要的。Flask起步晚,但社區也不小,以前有一次看在github上的star數,兩個相差並不遠,說明愈來愈多的人關注它,雖然插件沒那麼全,但經常使用的還都是有的,並且質量都比較高。

69. Flask框架依賴組件?

Flask依賴兩個外部庫:
    Jinja2模板引擎
    Werkzeng WSGI工具集。

70. Flask藍圖的做用?

將不一樣的功能 模塊化;
    構建大型的應用;
    優化項目結構;
    加強可讀性,易於維護;

71. 列舉使用過的Flask第三方組件?

內置:
      - 配置
          - 路由
          - 視圖
          - 模板
          - session
          - 閃現
          - 藍圖
          - 中間件
          - 特殊裝飾器
  第三方:
      - Flask組件:
          - flask-session 
          - flask-SQLAlchemy
          - flask-migrate 
          - flask-script 
          - blinker 
      - 公共組件:
          - wtforms
          - dbutile
          - sqlalchemy 
      - 自定義Flask組件
          - auth ,參考flask-login組件

72. 簡述Flask上下文管理流程?

每次有請求過來的時候,flask 會先建立當前線程或者進程須要處理的兩個重要上下文對象,把它們保存到隔離的棧裏面,這樣視圖函數進行處理的時候就能直接從棧上獲取這些信息。
  參考連接:http://python.jobbole.com/87398/

73. Flask中的g的做用?

g 至關於一次請求的全局變量,當請求進來時將g和current_app封裝爲一個APPContext類,在經過LocalStack將Appcontext放入Local中,取值時經過偏函數,LocalStack、loca l中取值,響應時將local中的g數據刪除

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

flask
  requestcontext
  request
  securecookiesessioninterface
  securecookiesession

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

當是web應用時:無論是單線程仍是多線程,棧中只有一個數據
   - 服務端單線程:
    {
    111:{stack: [ctx, ]}
    }
  - 服務端多線程:
    {
    111:{stack: [ctx, ]}
    112:{stack: [ctx, ]}
    }

76. Flask中多app應用是怎麼完成?

目的是想要將local中的值維護成一個棧,例如:在多app應用中編寫離線腳本時,能夠實用上。
  from m_app import app01,app02
  from flask import current_app
  """
  {
      1231: {
          stack: [app01,app02,]
      }
  }

  """

  with app01.app_context():
      print(current_app)
      with app02.app_context():
          print(current_app)
      print(current_app)

77. 在Flask中實現WebSocket須要什麼組件?

Flask-SocketIO
  Flask-Sockets是Flask框架的一個擴展,經過它,Flask應用程序能夠使用WebSocket。
  https://blog.csdn.net/u013793383/article/details/72848252
  https://github.com/miguelgrinberg/Flask-SocketIO

78. wtforms組件的做用?

WTForms是一個支持多個web框架的form組件,主要用於對用戶請求數據進行驗證。
 https://www.cnblogs.com/big-handsome-guy/p/8552079.html
 https://www.cnblogs.com/liuwei0824/p/8330985.html

79. Flask框架默認session處理機制?

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

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

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

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

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

    問題:本身經過字典建立一個相似於threading.local的東西。
        storage={
            4740:{val:0},
            4732:{val:1},
            4731:{val:3},
            ...
        }

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

        try:
            from greenlet import getcurrent as get_ident
        except Exception as e:
            from threading import get_ident

        from threading import Thread
        import time

        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()

81. Flask中 blinker 是什麼?

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

  在請求先後,模板渲染先後,上下文先後,異常 的時候
  http://www.cnblogs.com/big-handsome-guy/p/8551973.html

82. SQLAlchemy中的 session和scoped_session 的區別?

使用scoped_session的目的主要是爲了線程安全。
  scoped_session相似單例模式,當咱們調用使用的時候,會先在Registry裏找找以前是否已經建立session了。
  要是有,就把這個session返回。
  要是沒有,就建立新的session,註冊到Registry中以便下次返回給調用者。
  這樣就實現了這樣一個目的:在同一個線程中,call scoped_session 的時候,返回的是同一個對象
  https://www.cnblogs.com/geeklove01/p/8179220.html
  https://www.cnblogs.com/lianxuebin/p/8664401.html

83. 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 ;')

  https://www.cnblogs.com/franknihao/p/7268752.html

84. ORM的實現原理?

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

  詳細介紹:  讓咱們從O/R開始。字母O起源於"對象"(Object),而R則來自於"關係"(Relational)。幾乎全部的程序裏面,都存在對象和關係數據庫。在業務邏輯層和用戶界面層中,咱們是面向對象的。當對象信息發生變化的時候,咱們須要把對象的信息保存在關係數據庫中。 
          當你開發一個應用程序的時候(不使用O/R Mapping),你可能會寫很多數據訪問層的代碼,用來從數據庫保存,刪除,讀取對象信息,等等。你在DAL中寫了不少的方法來讀取對象數據,改變狀態對象等等任務。而這些代碼寫起來老是重複的。 
          ORM解決的主要問題是對象關係的映射。域模型和關係模型分別是創建在概念模型的基礎上的。域模型是面向對象的,而關係模型是面向關係的。通常狀況下,一個持久化類和一個表對應,類的每一個實例對應表中的一條記錄,類的每一個屬性對應表的每一個字段。 
  ORM技術特色: 
  1.提升了開發效率。因爲ORM能夠自動對Entity對象與數據庫中的Table進行字段與屬性的映射,因此咱們實際可能已經不須要一個專用的、龐大的數據訪問層。 
  2.ORM提供了對數據庫的映射,不用sql直接編碼,可以像操做對象同樣從數據庫獲取數據。

85. DBUtils模塊的做用?

使用DBUtils模塊
  兩種使用模式:
      1 爲每一個線程建立一個鏈接,鏈接不可控,須要控制線程數
      2 建立指定數量的鏈接在鏈接池,當線程訪問的時候去取,若是不夠了線程排隊,直到有人釋放。平時建議使用這種!
  https://www.cnblogs.com/ArmoredTitan/p/Flask.html

86. 如下SQLAlchemy的字段是否正確?若是不正確請更正:

## from datetime import datetime
  ## from sqlalchemy.ext.declarative
  ## import declarative_base
  ## from sqlalchemy import Column, Integer, String, DateTime
  ## 
  ## Base = declarative_base()
  ## class UserInfo(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後面不該該加括號.若是加了,字段不會隨時更新

87. SQLAlchemy中如何爲表設置引擎和字符編碼?

sqlalchemy設置編碼字符集必定要在數據庫訪問的URL上增長charset=utf8,不然數據庫的鏈接就不是utf8的編碼格式
  eng = create_engine('mysql://root:root@localhost:3306/test2?charset=utf8',echo=True)

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

UniqueConstraint 設置聯合惟一索引
    https://www.cnblogs.com/jasonwang-2016/p/5980237.html

89. 簡述Tornado框架的特色。

Tornado的獨特之處在於其全部開發工具可以使用在應用開發的任意階段以及任何檔次的硬件資源上。並且,完整集的Tornado工具能夠使開發人員徹底不用考慮與目標鏈接的策略或目標存儲區大小。Tornado 結構的專門設計爲開發人員和第三方工具廠商提供了一個開放環境。已有部分應用程序接口能夠利用並附帶參考書目,內容從開發環境接口到鏈接實現。Tornado包括強大的開發和調試工具,尤爲適用於面對大量問題的嵌入式開發人員。這些工具包括C和C++源碼級別的調試器,目標和工具管理,系統目標跟蹤,內存使用分析和自動配置. 另外,全部工具能很方便地同時運行,很容易增長和交互式開發。

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

http://python.jobbole.com/87310/

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

https://www.cnblogs.com/aguncn/p/5665916.html

92. Tornado中靜態文件是如何處理的?

如: <link href="{{static_url("commons.css")}}" rel="stylesheet" />
  處理方法:
  static_path = os.path.join(os.paht.dirname(__file__), "static") #這裏增長設置了靜態路徑
  另一個修改就是在實例化 tornado.web.Application() 的時候,在參數中,出了有靜態路徑參數 static_path ,還有一個參數設置 debug=True

  https://blog.csdn.net/hqzxsc2006/article/details/72833012

93. Tornado操做MySQL使用的模塊?

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

94. Tornado操做redis使用的模塊?

tornado-redis
  https://blog.csdn.net/guoqianqian5812/article/details/68587921

95. 簡述Tornado框架的適用場景?

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

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

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命令 的區別。

https://www.cnblogs.com/xueweihan/p/5743327.html

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

https://www.cnblogs.com/abelsu/p/5138136.html

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

https://blog.csdn.net/maray/article/details/50206927

101. git如何實現v1.0 、v2.0 等版本的管理?

https://blog.csdn.net/zhazhaji/article/details/75258426

102. 什麼是gitlab?

GitLab 是一個用於倉庫管理系統的開源項目,使用Git做爲代碼管理工具,並在此基礎上搭建起來的web服務。安裝方法是參考GitLab在GitHub上的Wiki頁面。

103. github和gitlab的區別?

先說一下相同點,兩者都是基於web的Git倉庫,在很大程度上GitLab是仿照GitHub來作的,它們都提供了分享開源項目的平臺,爲開發團隊提供了存儲、分享、發佈和合做開發項目的中心化雲存儲的場所。

  GitHub做爲開源代碼庫及版本控制系統,擁有超過900萬的開發者用戶,目前仍然是最火的開源項目託管系統。GitHub同時提供公共倉庫和私有倉庫,但若是要使用私有倉庫,是須要付費的。

  而GitLab解決了這個問題,你能夠在上面建立私人的免費倉庫。

  GitLab讓開發團隊對他們的代碼倉庫擁有更多的控制,相比於GitHub,它有很多的特點:

  容許免費設置倉庫權限;容許用戶選擇分享一個project的部分代碼;容許用戶設置project的獲取權限,進一步的提高安全性;能夠設置獲取到團隊總體的改進進度;經過innersourcing讓不在權限範圍內的人訪問不到該資源。

  從代碼私有性方面來看,有時公司並不但願員工獲取到所有的代碼,這個時候GitLab無疑是更好的選擇。但對於開源項目而言,GitHub依然是代碼託管的首選。

104. 如何爲github上的開源項目貢獻代碼?

對一個開源項目有足夠了解的狀況下,若是你發現問題或者更好的解決方案的話,能夠開個issue先。
  通常狀況下維護這個項目的人或者其餘使用這個項目的人會參與討論的,而後基於這些討論你能夠發一些pull requests。
  若是你的方案獲得不少人贊同的話,項目維護人員會把他們merge,你也就成了這個項目的contributor了。
  固然不少狀況下,你開的這個issue已經有人提過了,或者說是你本身誤解了,可是相信在和其餘開發人員交流的過程當中,你也能學到許多。

105. git中 .gitignore文件的做用?

通常來講每一個Git項目中都須要一個「.gitignore」文件,這個文件的做用就是告訴Git哪些文件不須要添加到版本管理中。

  實際項目中,不少文件都是不須要版本管理的,好比Python的.pyc文件和一些包含密碼的配置文件等等。

106. 什麼是敏捷開發?

敏捷開發以用戶的需求進化爲核心,採用迭代、按部就班的方法進行軟件開發。在敏捷開發中,軟件項目在構建初期被切分紅多個子項目,各個子項目的成果都通過測試,具有可視、可集成和可運行使用的特徵。換言之,就是把一個大項目分爲多個相互聯繫,但也可獨立運行的小項目,並分別完成,在此過程當中軟件一直處於可以使用狀態。

107. 簡述 jenkins 工具的做用?

Jenkins是一個開源軟件項目,是基於Java開發的一種持續集成工具,用於監控持續重複的工做,旨在提供一個開放易用的軟件平臺,使軟件的持續集成變成可能。

108. 公司如何實現代碼發佈?

一、開發人員提交代碼更新,主要提交的字段包括「更新理由」,「svn代碼路徑」;
  二、後端收到請求後,把此數據插入到數據庫,標記此更新單爲「等待預發佈環境更新」的狀態;
  三、後臺進程定時查詢是否有等待預發佈環境更新的更新單,若是有,讀取svn路徑,執行svn up更新代碼操做,並標記此更新單爲「預發佈環境已更新,等待完成測試」;
  四、開發人員或者測試人員經過預發佈環境的域名來測試功能是否正常,若是不正常,做代碼修改後提交svn,再到web發佈後臺點擊「返回修改」,對svn路徑或者不作任何修改再點擊「從新提交」,而後更新單又一次回到」等待預發佈環境更新「狀態。循環三、4步驟,直至預發佈環境測試經過爲止;
  五、在確認測試經過後,開發人員點擊」測試經過「,這時更新單進入」等待審覈狀態「;
  六、負責人確承認以發佈後,點擊」審批「按鈕,這時更新單進入」審覈經過,等待執行發佈操做「的狀態。這時,開發人員獲得發佈代碼的受權;
  七、開發人員點擊」發佈代碼「按鈕,更新單進入」已執行發佈,等待系統完成發佈「狀態;
  八、後臺進程查詢狀態爲」已執行發佈,等待系統完成發佈「的更新單,執行git發佈命令。git命令大概爲,進入預發佈代碼目錄,執行git add .;git commit -m 「更新緣由」;git tag 上一次版本號+1,再進入已發佈代碼的目錄,執行git pull同步預發佈代碼目錄的更改。最後調用rsync命令同步代碼到生產環境。

  http://blog.jobbole.com/110304/

109. 簡述 RabbitMQ、Kafka、ZeroMQ的區別?

RabbitMQ
  RabbitMQ是使用Erlang編寫的一個開源的消息隊列,自己支持不少的協議:AMQP,XMPP, SMTP, STOMP,也正因如此,它很是重量級,更適合於企業級的開發。同時實現了Broker構架,這意味着消息在發送給客戶端時先在中心隊列排隊。對路由,負載均衡或者數據持久化都有很好的支持。

  Redis
  Redis是一個基於Key-Value對的NoSQL數據庫,開發維護很活躍。雖然它是一個Key-Value數據庫存儲系統,但它自己支持MQ功能,因此徹底能夠當作一個輕量級的隊列服務來使用。對於RabbitMQ和Redis的入隊和出隊操做,各執行100萬次,每10萬次記錄一次執行時間。測試數據分爲128Bytes、512Bytes、1K和10K四個不一樣大小的數據。實驗代表:入隊時,當數據比較小時Redis的性能要高於RabbitMQ,而若是數據大小超過了10K,Redis則慢的沒法忍受;出隊時,不管數據大小,Redis都表現出很是好的性能,而RabbitMQ的出隊性能則遠低於Redis。

  ZeroMQ
  ZeroMQ號稱最快的消息隊列系統,尤爲針對大吞吐量的需求場景。ZeroMQ可以實現RabbitMQ不擅長的高級/複雜的隊列,可是開發人員須要本身組合多種技術框架,技術上的複雜度是對這MQ可以應用成功的挑戰。ZeroMQ具備一個獨特的非中間件的模式,你不須要安裝和運行一個消息服務器或中間件,由於你的應用程序將扮演這個服務器角色。你只須要簡單的引用ZeroMQ程序庫,能夠使用NuGet安裝,而後你就能夠愉快的在應用程序之間發送消息了。可是ZeroMQ僅提供非持久性的隊列,也就是說若是宕機,數據將會丟失。其中,Twitter的Storm 0.9.0之前的版本中默認使用ZeroMQ做爲數據流的傳輸(Storm從0.9版本開始同時支持ZeroMQ和Netty做爲傳輸模塊)。

  ActiveMQ
  ActiveMQ是Apache下的一個子項目。 相似於ZeroMQ,它可以以代理人和點對點的技術實現隊列。同時相似於RabbitMQ,它少許代碼就能夠高效地實現高級應用場景。

  Kafka/Jafka
  Kafka是Apache下的一個子項目,是一個高性能跨語言分佈式發佈/訂閱消息隊列系統,而Jafka是在Kafka之上孵化而來的,即Kafka的一個升級版。具備如下特性:快速持久化,能夠在O(1)的系統開銷下進行消息持久化;高吞吐,在一臺普通的服務器上既能夠達到10W/s的吞吐速率;徹底的分佈式系統,Broker、Producer、Consumer都原生自動支持分佈式,自動實現負載均衡;支持Hadoop數據並行加載,對於像Hadoop的同樣的日誌數據和離線分析系統,但又要求實時處理的限制,這是一個可行的解決方案。Kafka經過Hadoop的並行加載機制統一了在線和離線的消息處理。Apache Kafka相對於ActiveMQ是一個很是輕量級的消息系統,除了性能很是好以外,仍是一個工做良好的分佈式系統。

110. RabbitMQ如何在消費者獲取任務後未處理完前就掛掉時,保證數據不丟失?

111. RabbitMQ如何對消息作持久化?

https://www.cnblogs.com/xiangjun555/articles/7874006.html

112. RabbitMQ如何控制消息被消費的順序?

https://blog.csdn.net/varyall/article/details/79111745

113. 如下RabbitMQ的exchange type分別表明什麼意思?如:fanout、direct、topic。

https://www.cnblogs.com/shenyixin/p/9084249.html

114. 簡述 celery 是什麼以及應用場景?

Celery是由Python開發的一個簡單、靈活、可靠的處理大量任務的分發系統,它不只支持實時處理也支持任務調度。
  http://www.cnblogs.com/wupeiqi/articles/8796552.html

115. 簡述celery運行機制。

116. celery如何實現定時任務?

117. 簡述 celery多任務結構目錄?

118. celery中裝飾器 @app.task 和 @shared_task的區別?

119. 簡述 requests模塊的做用及基本使用?

模擬瀏覽器發送請求
  http://www.cnblogs.com/linhaifeng/articles/7785043.html

120. 簡述 beautifulsoup模塊的做用及基本使用?

Beautiful Soup 是一個能夠從HTML或XML文件中提取數據的Python庫
  http://www.cnblogs.com/linhaifeng/articles/7783586.html

121. 簡述 seleninu模塊的做用及基本使用?

selenium最初是一個自動化測試工具,而爬蟲中使用它主要是爲了解決requests沒法直接執行JavaScript代碼的問題

  selenium本質是經過驅動瀏覽器,徹底模擬瀏覽器的操做,好比跳轉、輸入、點擊、下拉等,來拿到網頁渲染以後的結果,可支持多種瀏覽器
  http://www.cnblogs.com/linhaifeng/articles/7783599.html

122. scrapy框架中各組件的工做流程?

#一、生成初始的Requests來爬取第一個URLS,而且標識一個回調函數
  第一個請求定義在start_requests()方法內默認從start_urls列表中得到url地址來生成Request請求,默認的回調函數是parse方法。回調函數在下載完成返回response時自動觸發

  #二、在回調函數中,解析response而且返回值
  返回值能夠4種:
          包含解析數據的字典
          Item對象
          新的Request對象(新的Requests也須要指定一個回調函數)
          或者是可迭代對象(包含Items或Request)

  #三、在回調函數中解析頁面內容
  一般使用Scrapy自帶的Selectors,但很明顯你也能夠使用Beutifulsoup,lxml或其餘你愛用啥用啥。

  #四、最後,針對返回的Items對象將會被持久化到數據庫
  經過Item Pipeline組件存到數據庫:https://docs.scrapy.org/en/latest/topics/item-pipeline.html#topics-item-pipeline)
  或者導出到不一樣的文件(經過Feed exports:https://docs.scrapy.org/en/latest/topics/feed-exports.html#topics-feed-exports)
  http://www.cnblogs.com/linhaifeng/articles/7811861.html

123. scrapy框架中如何設置代理(兩種方法)?

scrapy自帶的代理組件:
  from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware
  from urllib.request import getproxies

124. 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()

125. scrapy中如何實現限速?

http://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/autothrottle.html

126. scrapy中如何實現暫定爬蟲?

有些狀況下,例如爬取大的站點,咱們但願能暫停爬取,以後再恢復運行。

  Scrapy經過以下工具支持這個功能:

  一個把調度請求保存在磁盤的調度器
  一個把訪問請求保存在磁盤的副本過濾器[duplicates filter]
  一個能持續保持爬蟲狀態(鍵/值對)的擴展
  Job 路徑
  要啓用持久化支持,你只須要經過 JOBDIR 設置 job directory 選項。這個路徑將會存儲 全部的請求數據來保持一個單獨任務的狀態(例如:一次spider爬取(a spider run))。必需要注意的是,這個目錄不容許被不一樣的spider 共享,甚至是同一個spider的不一樣jobs/runs也不行。也就是說,這個目錄就是存儲一個 單獨 job的狀態信息。
  https://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/jobs.html?highlight=item

127. 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 

  http://www.cnblogs.com/wupeiqi/articles/6229292.html

128. scrapy中如何實現的記錄爬蟲的深度?

class scrapy.contrib.spidermiddleware.depth.DepthMiddleware
  DepthMiddleware是一個用於追蹤每一個Request在被爬取的網站的深度的中間件。 其能夠用來限制爬取深度的最大深度或相似的事情。

  DepthMiddleware 能夠經過下列設置進行配置(更多內容請參考設置文檔):

  DEPTH_LIMIT - 爬取所容許的最大深度,若是爲0,則沒有限制。
  DEPTH_STATS - 是否收集爬取狀態。
  DEPTH_PRIORITY - 是否根據其深度對requet安排優先級

129. scrapy中的pipelines工做原理?

Scrapy 提供了 pipeline 模塊來執行保存數據的操做。在建立的 Scrapy 項目中自動建立了一個 pipeline.py 文件,同時建立了一個默認的 Pipeline 類。咱們能夠根據須要自定義 Pipeline 類,而後在 settings.py 文件中進行配置便可
  https://blog.csdn.net/Ahri_J/article/details/72472170

130. scrapy的pipelines如何丟棄一個item對象?

131. scrapy中爬蟲中間件和下載中間件的做用?

http://www.cnblogs.com/wupeiqi/articles/6229292.html

132. scrapy-redis組件的做用?

scheduler - 調度器
  dupefilter - URL去重規則(被調度器使用)
  pipeline   - 數據持久化

133. scrapy-redis組件中如何實現的任務的去重?

定義去重規則(被調度器調用並應用)
   
      a. 內部會使用如下配置進行鏈接Redis
   
          # REDIS_HOST = 'localhost'                            # 主機名
          # REDIS_PORT = 6379                                   # 端口
          # REDIS_URL = 'redis://user:pass@hostname:9001'       # 鏈接URL(優先於以上配置)
          # REDIS_PARAMS  = {}                                  # Redis鏈接參數             默認:REDIS_PARAMS = {'socket_timeout': 30,'socket_connect_timeout': 30,'retry_on_timeout': True,'encoding': REDIS_ENCODING,})
          # REDIS_PARAMS['redis_cls'] = 'myproject.RedisClient' # 指定鏈接Redis的Python模塊  默認:redis.StrictRedis
          # REDIS_ENCODING = "utf-8"                            # redis編碼類型             默認:'utf-8'
       
      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
           
           
          PS:
              - URL參數位置不一樣時,計算結果一致;
              - 默認請求頭不在計算範圍,include_headers能夠設置指定請求頭
              示例:
                  from scrapy.utils import request
                  from scrapy.http import Request
                   
                  req = Request(url='http://www.baidu.com?name=8&id=1',callback=lambda x:print(x),cookies={'k1':'vvvvv'})
                  result = request.request_fingerprint(req,include_headers=['cookies',])
                   
                  print(result)
                   
                  req = Request(url='http://www.baidu.com?id=1&name=8',callback=lambda x:print(x),cookies={'k1':666})
                   
                  result = request.request_fingerprint(req,include_headers=['cookies',])
                   
                  print(result)
           
  """
  # Ensure all spiders share same duplicates filter through redis.
  # DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

134. scrapy-redis的調度器如何實現任務的深度優先和廣度優先?

http://www.cnblogs.com/wupeiqi/articles/6912807.html

135. 簡述 vitualenv 及應用場景?

virtualenv就是用來爲一個應用建立一套「隔離」的Python運行環境。
  https://www.cnblogs.com/technologylife/p/6635631.html

136. 簡述 pipreqs 及應用場景?

查找python項目依賴並生成requirements.txt
  https://www.cnblogs.com/bonelee/p/8183038.html

137. 在Python中使用過什麼代碼檢查工具?

1)PyFlakes:靜態檢查Python代碼邏輯錯誤的工具。
  2)Pep8: 靜態檢查PEP8編碼風格的工具。
  3)NedBatchelder’s McCabe script:靜態分析Python代碼複雜度的工具。
  Python代碼分析工具:PyChecker、Pylint

138. 簡述 saltstack、ansible、fabric、puppet工具的做用?

139. B Tree和B+ Tree的區別?

https://www.jianshu.com/p/0371c9569736

140. 請列舉常見排序並經過代碼實現任意三種。

冒泡/選擇/插入/快排
  https://www.cnblogs.com/Liqiongyu/p/5911613.html
  http://www.cnblogs.com/feixuelove1009/p/6143539.html

141. 請列舉常見查找並經過代碼實現任意三種。

無序查找/二分查找/插值查找
  http://www.cnblogs.com/feixuelove1009/p/6148357.html

142. 請列舉你熟悉的設計模式?

工廠模式/單例模式等
  https://www.cnblogs.com/Liqiongyu/p/5916710.html

143. 有沒有刷過leetcode?

刷過刷過刷過
  https://leetcode-cn.com/problemset/all/

144. 列舉熟悉的的Linux命令。

1.  mkdir –p  建立多級目錄
  2.  ls  -l 顯示詳細信息
  3.  cd  change directory 進入到目錄中
  4.  pwd print working directory 顯示當前所在位置
  5.  touch  建立文件   修改文件的時間戳
  6.  vi   編輯文件
  7.  cat  顯示文件內容
  8.  cp  copy 複製
  9.  mv  move 移動
  10. rm  刪除文件或目錄 -f  強制刪除不提示 -r  遞歸刪除目錄 慎用
  11. find 查找 -type  f(file)  d(dir)   -name  名字
  12. grep  過濾  -v  排除
  13. head  顯示文件的前幾行  默認顯示文件的前10行 -n2   === -2  顯示文件的前2行
  14. tail  顯示文件的最後幾行  默認顯示文件的後10行   
    -n1   === -1  顯示文件的最後1行
    -f    實時顯示文件的更新
  15. sed   取行  
      -n    取消默認輸出 
    -i    修改文件的內容
  16. tar   建立解壓查看壓縮包
  17. yum install  yum install -y
  18. ping  baidu.com

145. 公司線上服務器是什麼系統?

Linux/Centos

146. 解釋 PV、UV 的含義?

PV訪問量(Page View),即頁面訪問量,每打開一次頁面PV計數+1,刷新頁面也是。
  IP訪問數指獨立IP訪問數,計算是以一個獨立的IP在一個計算時段內訪問網站計算爲1次IP訪問數。在同一個計算時段內無論這個IP訪問多少次均計算爲1次。計算時段有以1天爲一個計算時段,也有以1個小時爲一個計算時段。
  UV訪問數(Unique Visitor)指獨立訪客訪問數,一臺電腦終端爲一個訪客。
  在同一個局域網中對互聯網訪問時對外一般是同一個IP,若是該局域網中有10臺終端在同一個計算時段內訪問同一個網站,對該網站的獨立IP訪問數貢獻爲1,而不是10。而此時UV訪問數則爲10。

147. 解釋 QPS的含義?

Query Per Second
  每秒查詢率QPS是對一個特定的查詢服務器在規定時間內所處理流量多少的衡量標準。

148. uwsgi和wsgi的區別?

WSGI:全稱是Web Server Gateway Interface,WSGI不是服務器,python模塊,框架,API或者任何軟件,只是一種規範,描述web server如何與web application通訊的規範。server和application的規範在PEP 3333中有具體描述。要實現WSGI協議,必須同時實現web server和web application,當前運行在WSGI協議之上的web框架有Bottle, Flask, Django。
  uwsgi:與WSGI同樣是一種通訊協議,是uWSGI服務器的獨佔協議,用於定義傳輸信息的類型(type of information),每個uwsgi packet前4byte爲傳輸信息類型的描述,與WSGI協議是兩種東西,聽說該協議是fcgi協議的10倍快。
  uWSGI:是一個web服務器,實現了WSGI協議、uwsgi協議、http協議等。
  https://www.jianshu.com/p/679dee0a4193

149. supervisor的做用?

supervisor管理進程,是經過fork/exec的方式將這些被管理的進程看成supervisor的子進程來啓動,因此咱們只須要將要管理進程的可執行文件的路徑添加到supervisor的配置文件中就行了。此時被管理進程被視爲supervisor的子進程,若該子進程異常終端,則父進程能夠準確的獲取子進程異常終端的信息,經過在配置文件中設置autostart=ture,能夠實現對異常中斷的子進程的自動重啓。

150. 什麼是反向代理?

反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的鏈接請求,而後將請求轉發給內部網絡上的服務器,並將從服務器上獲得的結果返回給internet上請求鏈接的客戶端,此時代理服務器對外就表現爲一個反向代理服務器。

151. 簡述SSH的整個過程。

SSH 爲 Secure Shell 的縮寫,由 IETF 的網絡小組(Network Working Group)所制定;SSH 爲創建在應用層基礎上的安全協議。SSH 是目前較可靠,專爲遠程登陸會話和其餘網絡服務提供安全性的協議。利用 SSH 協議能夠有效防止遠程管理過程當中的信息泄露問題。
  https://www.jianshu.com/p/33461b619d53

152. 有問題都去哪找解決方案?

風中

153. 是否有關注什麼技術類的公衆號?

藍翔技校/摩托車維修/脫單教程

154. 最近在研究什麼新技術?

NP徹底問題、霍奇猜測、龐加萊猜測、黎曼假設、楊-米爾斯存在性和質量缺口、納衛爾-斯托可方程、BSD猜測

155. 是否瞭解過領域驅動模型?

Domain-Driven Design
  https://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html
相關文章
相關標籤/搜索