python后端面試題


 

 


===============第一部分 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、01、10、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-8、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. 1、2、3、4、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. 什么是局域網和廣域網?

  一、局域網 
  局域網(Local Area Network),簡稱LAN,是指在某一區域內由多台計算機互聯成的計算機組。“某一區域”指的是同一辦公室、同一建築物、同一公司和同一學校等,一般是方圓幾千米以內。局域網可以實現文件管理、應用軟件共享、打印機共享、掃描儀共享、工作組內的日程安排、電子郵件和傳真通信服務等功能。局域網是封閉型的,可以由辦公室內的兩台計算機組成,也可以由一個公司內的上千台計算機組成。 二、廣域網 廣域網(Wide Area Network),簡稱WAN,是一種跨越大的、地域性的計算機網絡的集合。通常跨越省、市,甚至一個國家。廣域網包括大大小小不同的子網,子網可以是局域網,也可以是小型的廣域網。 三、局域網和廣域網的區別 局域網是在某一區域內的,而廣域網要跨越較大的地域,那么如何來界定這個區域呢?例如,一家大型公司的總公司位於北京,而分公司遍布全國各地,如果該公司將所有的分公司都通過網絡聯接在一起,那么一個分公司就是一個局域網,而整個總公司網絡就是一個廣域網。

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等待的過程,再去干一些其他的事)

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

  1、進程和線程的區別? 答:進程擁有一個完整的虛擬地址空間,不依賴於線程而獨立存在;反之,線程是進程的一部分,沒有自己的地址空間,與進程內的其他線程一起共享分配給該進程的所有資源。 比如:開個QQ,開了一個進程;開了迅雷,開了一個進程。在QQ的這個進程里,傳輸文字開一個線程、傳輸語音開了一個線程、彈出對話框又開了一個線程。所以運行某個軟件,相當於開了一個進程。在這個軟件運行的過程里(在這個進程里),多個工作支撐的完成QQ的運行,那么這“多個工作”分別有一個線程。所以一個進程管着多個線程。通俗的講:“進程是爹媽,管着眾多的線程兒子”。 參考自:https://www.zhihu.com/question/25532384 2、為什么說python的線程是偽線程? 答:在python的原始解釋器CPython中存在着GIL(Global Interpreter Lock,全局解釋器鎖),因此在解釋執行python代碼時,會產生互斥鎖來限制線程對共享資源的訪問,直到解釋器遇到I/O操作或者操作次數達到一定數目時才會釋放GIL。 所以,雖然CPython的線程庫直接封裝了系統的原生線程,但CPython整體作為一個進程,同一時間只會有一個線程在跑,其他線程則處於等待狀態。這就造成了即使在多核CPU中,多線程也只是做着分時切換而已。 參考自:https://www.zhihu.com/question/23474039 3、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. 什么是索引合並?

  1、索引合並是把幾個索引的范圍掃描合並成一個索引。
  2、索引合並的時候,會對索引進行並集,交集或者先交集再並集操作,以便合並成一個索引。
  3、這些需要合並的索引只能是一個表的。不能對多表進行索引合並。

  簡單的說,索引合並,讓一條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的常見指令。

  1、v-if指令:判斷指令,根據表達式值得真假來插入或刪除相應的值。 2、v-show指令:條件渲染指令,無論返回的布爾值是true還是false,元素都會存在在html中,只是false的元素會隱藏在html中,並不會刪除. 3、v-else指令:配合v-if或v-else使用。 4、v-for指令:循環指令,相當於遍歷。 5、v-bind:給DOM綁定元素屬性。 6、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的值相同,這樣做的原理如下:

  1、在用戶訪問django的可信站點時,django反饋給用戶的表單中有一個隱含字段csrftoken,這個值是在服務器端隨機生成的,每一次提交表單都會生成不同的值 2、當用戶提交django的表單時,服務器校驗這個表單的csrftoken是否和自己保存的一致,來判斷用戶的合法性 3、當用戶被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框架的優勢?

  一、整體設計方面
  首先,兩者都是非常優秀的框架。整體來講,兩者設計的哲學是區別最大的地方。Django提供一站式的解決方案,從模板、ORM、Session、Authentication等等都分配好了,連app划分都做好了,總之,為你做盡量多的事情,而且還有一個killer級的特性,就是它的admin,配合django-suit,后台就出來了,其實最初Django就是由在新聞發布公司工作的人設計的。Flask只提供了一些核心功能,非常簡潔優雅。它是一個微框架,其他的由擴展提供,但它的blueprint使它也能夠很方便的進行水平擴展。 二、路由設計 Django的路由設計是采用集中處理的方法,利用正則匹配。Flask也能這么做,但更多的是使用裝飾器的形式,這個有優點也有缺點,優點是讀源碼時看到函數就知道怎么用的,缺點是一旦源碼比較長,你要查路由就不太方便了,但這也促使你去思考如何更合理的安排代碼。 三、應用模塊化設計 Django的模塊化是集成在命令里的,也就是說一開始Django的目標就是為以后玩大了做准備的。每個都是一個獨立的模塊,為以后的復用提供了便利。Flask通過Blueprint來提供模塊化,自己對項目結構划分成不同的模塊進行組織。 四、配置 Django的配置主要還是靠settings.py來做,當然為了Development和Production環境分離,還有一些方法來處理配置。Flask的配置很靈活,有多種方法配置,不同環境的配置也非常方便。 五、文檔 兩者都提供了詳盡的文檔,Flask的文檔風格很受我個人喜好,Django的文檔也非常優秀,當時用學Django時,就是只看了Django的文檔。 六、社區 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. 公司如何實現代碼發布?

  1、開發人員提交代碼更新,主要提交的字段包括“更新理由”,“svn代碼路徑”; 2、后端收到請求后,把此數據插入到數據庫,標記此更新單為“等待預發布環境更新”的狀態; 3、后台進程定時查詢是否有等待預發布環境更新的更新單,如果有,讀取svn路徑,執行svn up更新代碼操作,並標記此更新單為“預發布環境已更新,等待完成測試”; 4、開發人員或者測試人員通過預發布環境的域名來測試功能是否正常,如果不正常,作代碼修改后提交svn,再到web發布后台點擊“返回修改”,對svn路徑或者不做任何修改再點擊“重新提交”,然后更新單又一次回到”等待預發布環境更新“狀態。循環3、4步驟,直至預發布環境測試通過為止; 5、在確認測試通過后,開發人員點擊”測試通過“,這時更新單進入”等待審核狀態“; 6、負責人確認可以發布后,點擊”審批“按鈕,這時更新單進入”審核通過,等待執行發布操作“的狀態。這時,開發人員得到發布代碼的授權; 7、開發人員點擊”發布代碼“按鈕,更新單進入”已執行發布,等待系統完成發布“狀態; 8、后台進程查詢狀態為”已執行發布,等待系統完成發布“的更新單,執行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框架中各組件的工作流程?

  #1、生成初始的Requests來爬取第一個URLS,並且標識一個回調函數 第一個請求定義在start_requests()方法內默認從start_urls列表中獲得url地址來生成Request請求,默認的回調函數是parse方法。回調函數在下載完成返回response時自動觸發 #2、在回調函數中,解析response並且返回值 返回值可以4種: 包含解析數據的字典 Item對象 新的Request對象(新的Requests也需要指定一個回調函數) 或者是可迭代對象(包含Items或Request) #3、在回調函數中解析頁面內容 通常使用Scrapy自帶的Selectors,但很明顯你也可以使用Beutifulsoup,lxml或其他你愛用啥用啥。 #4、最后,針對返回的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
 

 

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

  Domain-Driven Design
  https://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM