===============第一部分 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. 列舉面向對象中帶雙下劃線的特殊方法,如:new、init
__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