萬(wàn)字長(zhǎng)文Python面試題郁稍,建議先收藏

精心整理的 Python 相關(guān)的基礎(chǔ)知識(shí),用于面試胜宇,或者平時(shí)復(fù)習(xí)耀怜,都是很好的!廢話不多說(shuō)桐愉,直接開(kāi)搞 由于文章過(guò)長(zhǎng)财破,蘿卜哥也貼心的把文章整理成了PDF文檔,在文末查看獲取方式 [TOC] ## 基礎(chǔ)篇 ### 1. 為什么學(xué)習(xí) Python Python 語(yǔ)言簡(jiǎn)單易懂从诲,上手容易左痢,隨著 AI 風(fēng)潮,越來(lái)越火 ### 2. 解釋型和編譯型語(yǔ)言的區(qū)別 編譯型語(yǔ)言:把做好的源程序全部編譯成二進(jìn)制的可運(yùn)行程序。然后俊性,可直接運(yùn)行這個(gè)程序略步。如:C,C++ 解釋型語(yǔ)言:把做好的源程序翻譯一句定页,然后執(zhí)行一句趟薄,直至結(jié)束!如:Python典徊, (Java 有些特殊杭煎,java程序也需要編譯,但是沒(méi)有直接編譯稱為機(jī)器語(yǔ)言宫峦,而是編譯稱為字節(jié)碼岔帽,然后用解釋方式執(zhí)行字節(jié)碼玫鸟。) ### 3. 簡(jiǎn)述下 Python 中的字符串导绷、列表、元組和字典 字符串(str):字符串是用引號(hào)括起來(lái)的任意文本屎飘,是編程語(yǔ)言中最常用的數(shù)據(jù)類(lèi)型 列表(list):列表是有序的集合妥曲,可以向其中添加或刪除元素 元組(tuple):元組也是有序集合,但是是無(wú)法修改的钦购。即元組是不可變的 字典(dict):字典是無(wú)序的集合檐盟,是由 key-value 組成的 集合(set):是一組 key 的集合,每個(gè)元素都是唯一押桃,不重復(fù)且無(wú)序的 ### 4. 簡(jiǎn)述上述數(shù)據(jù)類(lèi)型的常用方法 字符串: 1. 切片 ```Python mystr='luobodazahui' mystr[1:3] ``` output ```Text 'uo' ``` 2. format ```Python mystr2 = "welcome to luobodazahui, dear {name}" mystr2.format(name="baby") ``` output ```Text 'welcome to luobodazahui, dear baby' ``` 3. join 可以用來(lái)連接字符串葵萎,將字符串、元組唱凯、列表中的元素以指定的字符(分隔符)連接生成一個(gè)新的字符串 ```Python mylist = ['luo', 'bo', 'da', 'za', 'hui'] mystr3 = '-'.join(mylist) print(mystr3) ``` outout ```Text 'luo-bo-da-za-hui' ``` 4. replace String.replace(old,new,count) 將字符串中的 old 字符替換為 New 字符羡忘,count 為替換的個(gè)數(shù) ```Python mystr4 = 'luobodazahui-haha' print(mystr4.replace('haha', 'good')) ``` output ```Text luobodazahui-good ``` 5. split 切割字符串,得到一個(gè)列表 ```Python mystr5 = 'luobo,dazahui good' # 以空格分割 print(mystr5.split()) # 以h分割 print(mystr5.split('h')) # 以逗號(hào)分割 print(mystr5.split(',')) ``` output ```Text ['luobo,dazahui', 'good'] ['luobo,daza', 'ui good'] ['luobo', 'dazahui good'] ``` 列表: 1. 切片 同字符串 2. append 和 extend 向列表中國(guó)添加元素 ```Python mylist1 = [1, 2] mylist2 = [3, 4] mylist3 = [1, 2] mylist1.append(mylist2) print(mylist1) mylist3.extend(mylist2) print(mylist3) ``` outout ```Text [1, 2, [3, 4]] [1, 2, 3, 4] ``` 3. 刪除元素 del:根據(jù)下標(biāo)進(jìn)行刪除 pop:刪除最后一個(gè)元素 remove:根據(jù)元素的值進(jìn)行刪除 ```Python mylist4 = ['a', 'b', 'c', 'd'] del mylist4[0] print(mylist4) mylist4.pop() print(mylist4) mylist4.remove('c') print(mylist4) ``` output ```Text ['b', 'c', 'd'] ['b', 'c'] ['b'] ``` 4. 元素排序 sort:是將list按特定順序重新排列,默認(rèn)為由小到大磕昼,參數(shù) reverse=True 可改為倒序卷雕,由大到小。 reverse:是將list逆置 ```Python mylist5 = [1, 5, 2, 3, 4] mylist5.sort() print(mylist5) mylist5.reverse() print(mylist5) ``` output ```Text [1, 2, 3, 4, 5] [5, 4, 3, 2, 1] ``` 字典: 1. 清空字典 dict.clear() ```Python dict1 = {'key1':1, 'key2':2} dict1.clear() print(dict1) ``` output ```Text {} ``` 2. 指定刪除 使用 pop 方法來(lái)指定刪除字典中的某一項(xiàng) ```Python dict1 = {'key1':1, 'key2':2} d1 = dict1.pop('key1') print(d1) print(dict1) ``` output ```Text 1 {'key2': 2} ``` 3. 遍歷字典 ```Python dict2 = {'key1':1, 'key2':2} mykey = [key for key in dict2] print(mykey) myvalue = [value for value in dict2.values()] print(myvalue) key_value = [(k, v) for k, v in dict2.items() ] print(key_value) ``` output ```Text ['key1', 'key2'] [1, 2] [('key1', 1), ('key2', 2)] ``` 4. fromkeys 用于創(chuàng)建一個(gè)新字典票从,以序列中元素做字典的鍵漫雕,value 為字典所有鍵對(duì)應(yīng)的初始值 ```Python keys = ['zhangfei', 'guanyu', 'liubei', 'zhaoyun'] dict.fromkeys(keys, 0) ``` output ```Text {'zhangfei': 0, 'guanyu': 0, 'liubei': 0, 'zhaoyun': 0} ``` ### 5. 簡(jiǎn)述 Python 中的字符串編碼 計(jì)算機(jī)在最初的設(shè)計(jì)中,采用了8個(gè)比特(bit)作為一個(gè)字節(jié)(byte)的方式峰鄙。一個(gè)字節(jié)能表示的最大的整數(shù)就是255(二進(jìn)制11111111=十進(jìn)制255)浸间,如果要表示更大的整數(shù),就必須用更多的字節(jié) 最早吟榴,計(jì)算機(jī)只有 ASCII 編碼魁蒜,即只包含大小寫(xiě)英文字母、數(shù)字和一些符號(hào),這些對(duì)于其他語(yǔ)言梅惯,如中文宪拥,日文顯然是不夠用的。后來(lái)又發(fā)明了Unicode铣减,Unicode把所有語(yǔ)言都統(tǒng)一到一套編碼里她君,這樣就不會(huì)再有亂碼問(wèn)題了。當(dāng)需要保存到硬盤(pán)或者需要傳輸?shù)臅r(shí)候葫哗,就轉(zhuǎn)換為UTF-8編碼缔刹。UTF-8 是隸屬于 Unicode 的可變長(zhǎng)的編碼方式 在 Python 中,以 Unicode 方式編碼的字符串劣针,可以使用 encode() 方法來(lái)編碼成指定的 bytes校镐,也可以通過(guò) decode() 方法來(lái)把 bytes 編碼成字符串 encode ```Python "中文".encode('utf-8') ``` output ```Text b'\xe4\xb8\xad\xe6\x96\x87' ``` decode ```Python b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8') ``` output ```Text '中文' ``` ### 6.一行代碼實(shí)現(xiàn)數(shù)值交換 ```Python 1a = 1 2b = 2 3a, b = b, a 4print(a, b) ``` output ```Text 12 1 ``` ### 7. is 和 == 的區(qū)別 先來(lái)看個(gè)例子 ```Python c = d = [1,2] e = [1,2] print(c is d) print(c == d) print(c is e) print(c == e) ``` output ```Text True True False True ``` == 是比較操作符,只是判斷對(duì)象的值(value)是否一致捺典,而 is 則判斷的是對(duì)象之間的身份(內(nèi)存地址)是否一致鸟廓。對(duì)象的身份,可以通過(guò) id() 方法來(lái)查看 ```Python id(c) id(d) id(e) ``` output ```Text 88748080 88748080 88558288 ``` 可以看出襟己,只有 id 一致時(shí)引谜,is 比較才會(huì)返回 True,而當(dāng) value 一致時(shí)擎浴,== 比較就會(huì)返回 True ### 8.Python 函數(shù)中的參數(shù)類(lèi)型 位置參數(shù)员咽,默認(rèn)參數(shù),可變參數(shù)贮预,關(guān)鍵字參數(shù) ### 9.`*arg` 和 `**kwarg` 作用 允許我們?cè)谡{(diào)用函數(shù)的時(shí)候傳入多個(gè)實(shí)參 ```Python def test(*arg, **kwarg): if arg: print("arg:", arg) if kwarg: print("kearg:", kwarg) test('ni', 'hao', key='world') ``` output ```Text arg: ('ni', 'hao') kearg: {'key': 'world'} ``` 可以看出贝室, `*arg` 會(huì)把位置參數(shù)轉(zhuǎn)化為 tuple `**kwarg` 會(huì)把關(guān)鍵字參數(shù)轉(zhuǎn)化為 dict ### 10.一行代碼實(shí)現(xiàn)1-100之和 ```Python sum(range(1, 101)) ``` ### 11.獲取當(dāng)前時(shí)間 ```Python import time import datetime print(datetime.datetime.now()) print(time.strftime('%Y-%m-%d %H:%M:%S')) ``` output ```Text 2019-06-07 18:12:11.165330 2019-06-07 18:12:11 ``` ### 12.PEP8 規(guī)范 簡(jiǎn)單列舉10條: - 盡量以免單獨(dú)使用小寫(xiě)字母'l',大寫(xiě)字母'O'仿吞,以及大寫(xiě)字母'I'等容易混淆的字母 - 函數(shù)命名使用全部小寫(xiě)的方式滑频,可以使用下劃線 - 常量命名使用全部大寫(xiě)的方式,可以使用下劃線 - 使用 has 或 is 前綴命名布爾元素茫藏,如: is_connect = True; has_member = False - 不要在行尾加分號(hào), 也不要用分號(hào)將兩條命令放在同一行 - 不要使用反斜杠連接行 - 頂級(jí)定義之間空2行, 方法定義之間空1行误趴,頂級(jí)定義之間空兩行 - 如果一個(gè)類(lèi)不繼承自其它類(lèi), 就顯式的從object繼承 - 內(nèi)部使用的類(lèi)、方法或變量前务傲,需加前綴`_`表明此為內(nèi)部使用的 - 要用斷言來(lái)實(shí)現(xiàn)靜態(tài)類(lèi)型檢測(cè) ### 13.Python 的深淺拷貝 淺拷貝 ```Python import copy list1 = [1, 2, 3, [1, 2]] list2 = copy.copy(list1) list2.append('a') list2[3].append('a') print(list1, list2) ``` output ```Text [1, 2, 3, [1, 2, 'a']] [1, 2, 3, [1, 2, 'a'], 'a'] ``` 能夠看出凉当,淺拷貝只成功”獨(dú)立“拷貝了列表的外層,而列表的內(nèi)層列表售葡,還是共享的 深拷貝 ```Python import copy list1 = [1, 2, 3, [1, 2]] list3 = copy.deepcopy(list1) list3.append('a') list3[3].append('a') print(list1, list3) ``` output ```Text [1, 2, 3, [1, 2]] [1, 2, 3, [1, 2, 'a'], 'a'] ``` 深拷貝使得兩個(gè)列表完全獨(dú)立開(kāi)來(lái)看杭,每一個(gè)列表的操作,都不會(huì)影響到另一個(gè) ### 14.查看下面代碼的輸出 ```Python def num(): return [lambda x:i*x for i in range(4)] print([m(1) for m in num()]) ``` output ```Text [3, 3, 3, 3] ``` 通過(guò)運(yùn)行結(jié)果挟伙,可以看出 i 的取值為3楼雹,很神奇 ### 15.可變類(lèi)型與不可變類(lèi)型 可變數(shù)據(jù)類(lèi)型:list、dict、set 不可變數(shù)據(jù)類(lèi)型:int/float贮缅、str榨咐、tuple ### 16.打印九九乘法表 ```Python for i in range(1, 10): for j in range(1, i+1): print("%s*%s=%s " %(i, j, i*j), end="") print() ``` output ```Text 1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 ``` print 函數(shù),默認(rèn)是會(huì)換行的谴供,其有一個(gè)默認(rèn)參數(shù) end块茁,如果像例子中,我們把 end 參數(shù)顯示的置為""桂肌,那么 print 函數(shù)執(zhí)行完后数焊,就不會(huì)換行了,這樣就達(dá)到了九九乘法表的效果了 ### 17.filter崎场、map佩耳、reduce 的作用 filter 函數(shù)用于過(guò)濾序列,它接收一個(gè)函數(shù)和一個(gè)序列谭跨,把函數(shù)作用在序列的每個(gè)元素上干厚,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素 ```Python mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9] list(filter(lambda x: x%2 == 1, mylist)) ``` output ```Text [1, 3, 5, 7, 9] ``` 保留奇數(shù)列表 map 函數(shù)傳入一個(gè)函數(shù)和一個(gè)序列,并把函數(shù)作用到序列的每個(gè)元素上饺蚊,返回一個(gè)可迭代對(duì)象 ```Python mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9] list(map(lambda x: x*2, mylist)) ``` output ```Text [2, 4, 6, 8, 10, 12, 14, 16, 18] ``` reduce 函數(shù)用于遞歸計(jì)算萍诱,同樣需要傳入一個(gè)函數(shù)和一個(gè)序列,并把函數(shù)和序列元素的計(jì)算結(jié)果與下一個(gè)元素進(jìn)行計(jì)算 ```Python from functools import reduce reduce(lambda x, y: x+y, range(101)) ``` output ```Text 5050 ``` 可以看出污呼,上面的三個(gè)函數(shù)與匿名函數(shù)相結(jié)合使用,可以寫(xiě)出強(qiáng)大簡(jiǎn)潔的代碼 ### 18.re 的 match 和 search 區(qū)別 match()函數(shù)只檢測(cè)要匹配的字符是不是在 string 的開(kāi)始位置匹配包竹,search()會(huì)掃描整個(gè) string 查找匹配 ### 19.面向?qū)ο笾衊__new__` 和 `__init__` 區(qū)別 `__new__`是在實(shí)例創(chuàng)建之前被調(diào)用的燕酷,因?yàn)樗娜蝿?wù)就是創(chuàng)建實(shí)例然后返回該實(shí)例對(duì)象,是個(gè)靜態(tài)方法 `__init__`是當(dāng)實(shí)例對(duì)象創(chuàng)建完成后被調(diào)用的周瞎,然后設(shè)置對(duì)象屬性的一些初始值苗缩,通常用在初始化一個(gè)類(lèi)實(shí)例的時(shí)候,是一個(gè)實(shí)例方法 1声诸、`__new__`至少要有一個(gè)參數(shù) cls酱讶,代表當(dāng)前類(lèi),此參數(shù)在實(shí)例化時(shí)由 Python 解釋器自動(dòng)識(shí)別 2彼乌、`__new__`必須要有返回值泻肯,返回實(shí)例化出來(lái)的實(shí)例,這點(diǎn)在自己實(shí)現(xiàn)`__new__`時(shí)要特別注意慰照,可以 return 父類(lèi)(通過(guò) super(當(dāng)前類(lèi)名, cls))`__new__`出來(lái)的實(shí)例灶挟,或者直接是 object 的`__new__`出來(lái)的實(shí)例 3、`__init__`有一個(gè)參數(shù) self毒租,就是這個(gè)`__new__`返回的實(shí)例稚铣,`__init__`在`__new__`的基礎(chǔ)上可以完成一些其它初始化的動(dòng)作,`__init__`不需要返回值 4、如果`__new__`創(chuàng)建的是當(dāng)前類(lèi)的實(shí)例惕医,會(huì)自動(dòng)調(diào)用`__init__`函數(shù)耕漱,通過(guò) return 語(yǔ)句里面調(diào)用的`__new__`函數(shù)的第一個(gè)參數(shù)是 cls 來(lái)保證是當(dāng)前類(lèi)實(shí)例,如果是其他類(lèi)的類(lèi)名抬伺,那么實(shí)際創(chuàng)建返回的就是其他類(lèi)的實(shí)例孤个,其實(shí)就不會(huì)調(diào)用當(dāng)前類(lèi)的`__init__`函數(shù),也不會(huì)調(diào)用其他類(lèi)的`__init__`函數(shù) ### 20.三元運(yùn)算規(guī)則 ```Python a, b = 1, 2 # 若果 a>b 成立 就輸出 a-b 否則 a+b h = a-b if a>b else a+b ``` output ```Text 3 ``` ### 21.生成隨機(jī)數(shù) ```Python print(random.random()) print(random.randint(1, 100)) print(random.uniform(1,5)) ``` output ```Text 0.03765019937131564 18 1.8458555362279228 ``` ### 22.zip 函數(shù)用法 zip() 函數(shù)將可迭代的對(duì)象作為參數(shù)沛简,將對(duì)象中對(duì)應(yīng)的元素打包成一個(gè)個(gè)元組齐鲤,然后返回由這些元組組成的列表 ```Python list1 = ['zhangfei', 'guanyu', 'liubei', 'zhaoyun'] list2 = [0, 3, 2, 4] list(zip(list1, list2)) ``` output ```Text [('zhangfei', 0), ('guanyu', 3), ('liubei', 2), ('zhaoyun', 4)] ``` ### 23.range 和 xrange 的區(qū)別 range([start,] stop[, step]),根據(jù)start與stop指定的范圍以及step設(shè)定的步長(zhǎng)椒楣,生成一個(gè)序列 而 xrange 生成一個(gè)生成器给郊,可以很大的節(jié)約內(nèi)存 ### 24.with 方法打開(kāi)文件的作用 開(kāi)文件在進(jìn)行讀寫(xiě)的時(shí)候可能會(huì)出現(xiàn)一些異常狀況,如果按照常規(guī)的 f.open 寫(xiě)法捧灰,我們需要 try,except,finally淆九,做異常判斷,并且文件最終不管遇到什么情況毛俏,都要執(zhí)行 finally f.close() 關(guān)閉文件炭庙,with 方法幫我們實(shí)現(xiàn)了 finally 中 f.close ### 25.什么是正則的貪婪匹配 Python 中默認(rèn)是貪婪匹配模式 貪婪模式:正則表達(dá)式一般趨向于最大長(zhǎng)度匹配 非貪婪模式:在整個(gè)表達(dá)式匹配成功的前提下,盡可能少的匹配 ### 26.為什么不建議函數(shù)的默認(rèn)參數(shù)傳入可變對(duì)象 例如: ```Python def test(L=[]): L.append('test') print(L) ``` output ```Text test() # ['test'] test() # ['test', 'test'] ``` 默認(rèn)參數(shù)是一個(gè)列表煌寇,是可變對(duì)象[],Python 在函數(shù)定義的時(shí)候焕蹄,默認(rèn)參數(shù) L 的值就被計(jì)算出來(lái)了,是[]阀溶,每次調(diào)用函數(shù)腻脏,如果 L 的值變了,那么下次調(diào)用時(shí)银锻,默認(rèn)參數(shù)的值就已經(jīng)不再是[]了 ### 27.字符串轉(zhuǎn)列表 ```Python mystr = '1,2,3' mystr.split(',') ``` output ```Text ['1', '2', '3'] ``` ### 28.字符串轉(zhuǎn)整數(shù) ```Python mylist = ['1', '2', '3'] list(map(lambda x: int(x), mylist)) ``` output ```Text [1, 2, 3] ``` ### 29.刪除列表中的重復(fù)值 ```Python mylist = [1, 2, 3, 4, 5, 5] list(set(mylist)) ``` ### 30.字符串單詞統(tǒng)計(jì) ```Python from collections import Counter mystr = 'sdfsfsfsdfsd,were,hrhrgege.sdfwe!sfsdfs' Counter(mystr) output Counter({'s': 9, 'd': 5, 'f': 7, ',': 2, 'w': 2, 'e': 5, 'r': 3, 'h': 2, 'g': 2, '.': 1, '!': 1}) ``` ### 31.列表推導(dǎo)永品,求奇偶數(shù) ```Python [x for x in range(10) if x%2 == 1] ``` output ```Text [1, 3, 5, 7, 9] ``` ### 32.一行代碼展開(kāi)列表 ```Python list1 = [[1,2],[3,4],[5,6]] [j for i in list1 for j in i] ``` output ```Text [1, 2, 3, 4, 5, 6] ``` ### 33.實(shí)現(xiàn)二分法查找函數(shù) 二分查找算法也稱折半查找,基本思想就是折半击纬,對(duì)比大小后再折半查找鼎姐,必須是有序序列才可以使用二分查找 遞歸算法 ```Python def binary_search(data, item): # 遞歸 n = len(data) if n > 0: mid = n // 2 if data[mid] == item: return True elif data[mid] > item: return binary_search(data[:mid], item) else: return binary_search(data[mid+1:], item) return False list1 = [1,4,5,66,78,99,100,101,233,250,444,890] binary_search(list1, 999) ``` 非遞歸算法 ```Python def binary_search(data, item): # 非遞歸 n = len(data) first = 0 last = n - 1 while first <= last: mid = (first + last)//2 if data[mid] == item: return True elif data[mid] > item: last = mid - 1 else: first = mid + 1 return False list1 = [1,4,5,66,78,99,100,101,233,250,444,890] binary_search(list1, 99) ``` ### 34.字典和 json 轉(zhuǎn)換 字典轉(zhuǎn) json ```Python import json dict1 = {'zhangfei':1, "liubei":2, "guanyu": 4, "zhaoyun":3} myjson = json.dumps(dict1) myjson output '{"zhangfei": 1, "liubei": 2, "guanyu": 4, "zhaoyun": 3}' json 轉(zhuǎn)字典 mydict = json.loads(myjson) mydict ``` output ```Text {'zhangfei': 1, 'liubei': 2, 'guanyu': 4, 'zhaoyun': 3} ``` ### 35.列表推導(dǎo)式、字典推導(dǎo)式和生成器 ```Python import random td_list=[i for i in range(10)] print("列表推導(dǎo)式", td_list, type(td_list)) ge_list = (i for i in range(10)) print("生成器", ge_list) dic = {k:random.randint(4, 9)for k in ["a", "b", "c", "d"]} print("字典推導(dǎo)式",dic,type(dic)) ``` output ```Text 列表推導(dǎo)式 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 生成器 at 0x0139F070> 字典推導(dǎo)式 {'a': 6, 'b': 5, 'c': 8, 'd': 9} ``` ### 36.簡(jiǎn)述 read更振、readline炕桨、readlines 的區(qū)別 read 讀取整個(gè)文件 readline 讀取下一行,使用生成器方法 readlines 讀取整個(gè)文件到一個(gè)迭代器以供我們遍歷 ### 37.打亂一個(gè)列表 ```Python list2 = [1, 2, 3, 4, 5, 6] random.shuffle(list2) print(list2) ``` output ```Text [4, 6, 5, 1, 2, 3] ``` ### 38.反轉(zhuǎn)字符串 ```Python str1 = 'luobodazahui' str1[::-1] ``` output ```Text 'iuhazadoboul' ``` ### 39.單下劃線和雙下劃線的作用 `__foo__`:一種約定,Python 內(nèi)部的名字殃饿,用來(lái)區(qū)別其他用戶自定義的命名谋作,以防沖突,就是例如`__init__()`,`__del__()`,`__call__()`些特殊方法 `_foo`:一種約定乎芳,用來(lái)指定變量私有遵蚜。不能用 from module import * 導(dǎo)入帖池,其他方面和公有變量一樣訪問(wèn) `__foo`:這個(gè)有真正的意義:解析器用`_classname__foo` 來(lái)代替這個(gè)名字,以區(qū)別和其他類(lèi)相同的命名吭净,它無(wú)法直接像公有成員一樣隨便訪問(wèn)睡汹,通過(guò)對(duì)象名`._`類(lèi)名`__xxx` 這樣的方式可以訪問(wèn) ### 40.新式類(lèi)和舊式類(lèi) a. 在 python 里凡是繼承了 object 的類(lèi),都是新式類(lèi) b. Python3 里只有新式類(lèi) c. Python2 里面繼承 object 的是新式類(lèi)寂殉,沒(méi)有寫(xiě)父類(lèi)的是經(jīng)典類(lèi) d. 經(jīng)典類(lèi)目前在 Python 里基本沒(méi)有應(yīng)用 ### 41.Python 面向?qū)ο笾械睦^承有什么特點(diǎn) a. 同時(shí)支持單繼承與多繼承囚巴,當(dāng)只有一個(gè)父類(lèi)時(shí)為單繼承,當(dāng)存在多個(gè)父類(lèi)時(shí)為多繼承 b. 子類(lèi)會(huì)繼承父類(lèi)所有的屬性和方法友扰,子類(lèi)也可以覆蓋父類(lèi)同名的變量和方法 c. 在繼承中基類(lèi)的構(gòu)造(`__init__()`)方法不會(huì)被自動(dòng)調(diào)用彤叉,它需要在其派生類(lèi)的構(gòu)造中專門(mén)調(diào)用 d. 在調(diào)用基類(lèi)的方法時(shí),需要加上基類(lèi)的類(lèi)名前綴村怪,且需要帶上 self 參數(shù)變量秽浇。區(qū)別于在類(lèi)中調(diào)用普通函數(shù)時(shí)并不需要帶上 self 參數(shù) ### 42.super 函數(shù)的作用 super() 函數(shù)是用于調(diào)用父類(lèi)(超類(lèi))的一個(gè)方法 ```Python class A(): def funcA(self): print("this is func A") class B(A): def funcA_in_B(self): super(B, self).funcA() def funcC(self): print("this is func C") ins = B() ins.funcA_in_B() ins.funcC() ``` output ```Text this is func A this is func C ``` ### 43.類(lèi)中的各種函數(shù) 主要分為實(shí)例方法、類(lèi)方法和靜態(tài)方法 **實(shí)例方法** 定義:第一個(gè)參數(shù)必須是實(shí)例對(duì)象甚负,該參數(shù)名一般約定為“self”柬焕,通過(guò)它來(lái)傳遞實(shí)例的屬性和方法(也可以傳類(lèi)的屬性和方法) 調(diào)用:只能由實(shí)例對(duì)象調(diào)用 **類(lèi)方法** 定義:使用裝飾器@classmethod。第一個(gè)參數(shù)必須是當(dāng)前類(lèi)對(duì)象梭域,該參數(shù)名一般約定為“cls”斑举,通過(guò)它來(lái)傳遞類(lèi)的屬性和方法(不能傳實(shí)例的屬性和方法) 調(diào)用:實(shí)例對(duì)象和類(lèi)對(duì)象都可以調(diào)用 **靜態(tài)方法** 定義:使用裝飾器@staticmethod。參數(shù)隨意病涨,沒(méi)有“self”和“cls”參數(shù)富玷,但是方法體中不能使用類(lèi)或?qū)嵗娜魏螌傩院头椒? 調(diào)用:實(shí)例對(duì)象和類(lèi)對(duì)象都可以調(diào)用 靜態(tài)方法是類(lèi)中的函數(shù),不需要實(shí)例没宾。靜態(tài)方法主要是用來(lái)存放邏輯性的代碼凌彬,主要是一些邏輯屬于類(lèi),但是和類(lèi)本身沒(méi)有交互循衰。即在靜態(tài)方法中,不會(huì)涉及到類(lèi)中的方法和屬性的操作褐澎』岫郏可以理解為將靜態(tài)方法存在此類(lèi)的名稱空間中 類(lèi)方法是將類(lèi)本身作為對(duì)象進(jìn)行操作的方法。他和靜態(tài)方法的區(qū)別在于:不管這個(gè)方式是從實(shí)例調(diào)用還是從類(lèi)調(diào)用工三,它都用第一個(gè)參數(shù)把類(lèi)傳遞過(guò)來(lái) ### 44.如何判斷是函數(shù)還是方法 與類(lèi)和實(shí)例無(wú)綁定關(guān)系的 function 都屬于函數(shù)(function) 與類(lèi)和實(shí)例有綁定關(guān)系的 function 都屬于方法(method) 普通函數(shù): ```Python def func1(): pass print(func1) output 類(lèi)中的函數(shù): class People(object): def func2(self): pass @staticmethod def func3(): pass @classmethod def func4(cls): pass people = People() print(people.func2) print(people.func3) print(people.func4) ``` output ```Text > > ``` ### 45.isinstance 的作用以及與 type()的區(qū)別 isinstance() 函數(shù)來(lái)判斷一個(gè)對(duì)象是否是一個(gè)已知的類(lèi)型迁酸,類(lèi)似 type() 區(qū)別: type() 不會(huì)認(rèn)為子類(lèi)是一種父類(lèi)類(lèi)型,不考慮繼承關(guān)系 isinstance() 會(huì)認(rèn)為子類(lèi)是一種父類(lèi)類(lèi)型俭正,考慮繼承關(guān)系 ```Python class A(object): pass class B(A): pass a = A() b = B() print(isinstance(a, A)) print(isinstance(b, A)) print(type(a) == A) print(type(b) == A) ``` output ```Text True True True False ``` ### 46.單例模式與工廠模式 單例模式:主要目的是確保某一個(gè)類(lèi)只有一個(gè)實(shí)例存在 工廠模式:包涵一個(gè)超類(lèi)奸鬓,這個(gè)超類(lèi)提供一個(gè)抽象化的接口來(lái)創(chuàng)建一個(gè)特定類(lèi)型的對(duì)象,而不是決定哪個(gè)對(duì)象可以被創(chuàng)建 ### 47.查看目錄下的所有文件 ```Python import os print(os.listdir('.')) ``` ### 48.計(jì)算1到5組成的互不重復(fù)的三位數(shù) ```Python # 1到5組成的互不重復(fù)的三位數(shù) k = 0 for i in range(1, 6): for j in range(1, 6): for z in range(1, 6): if (i != j) and (i != z) and (j != z): k += 1 if k%6: print("%s%s%s" %(i, j, z), end="|") else: print("%s%s%s" %(i, j, z)) ``` output ```Text 123|124|125|132|134|135 142|143|145|152|153|154 213|214|215|231|234|235 241|243|245|251|253|254 312|314|315|321|324|325 341|342|345|351|352|354 412|413|415|421|423|425 431|432|435|451|452|453 512|513|514|521|523|524 531|532|534|541|542|543 ``` ### 49.去除字符串首尾空格 ```Python str1 = " hello nihao " str1.strip() ``` output ```Text 'hello nihao' ``` ### 50.去除字符串中間的空格 ```Python str2 = "hello you are good" print(str2.replace(" ", "")) "".join(str2.split(" ")) ``` output ```Text helloyouaregood 'helloyouaregood' ``` ### 51. 字符串格式化方式 1. 使用 % 操作符 ```Python print("This is for %s" % "Python") print("This is for %s, and %s" %("Python", "You")) ``` output ```Text This is for Python This is for Python, and You ``` 2. str.format 在 Python3 中掸读,引入了這個(gè)新的字符串格式化方法 ```Python print("This is my {}".format("chat")) print("This is {name}, hope you can {do}".format(name="zhouluob", do="like")) ``` output ```Text This is my chat This is zhouluob, hope you can like ``` 3. f-strings 在 Python3-6 中串远,引入了這個(gè)新的字符串格式化方法 ```Python name = "luobodazahui" print(f"hello {name}") ``` output ```Text hello luobodazahui ``` 一個(gè)復(fù)雜些的例子: ```Python def mytest(name, age): return f"hello {name}, you are {age} years old!" people = mytest("luobo", 20) print(people) ``` output ```Text hello luobo, you are 20 years old! ``` ### 52. 將"hello world"轉(zhuǎn)換為首字母大寫(xiě)"Hello World"(不使用 title 函數(shù)) ```Python str1 = "hello world" print(str1.title()) " ".join(list(map(lambda x: x.capitalize(), str1.split(" ")))) ``` output ```Text Hello World 'Hello World' ``` ### 53. 一行代碼轉(zhuǎn)換列表中的整數(shù)為字符串 如:[1, 2, 3] -> ["1", "2", "3"] ```Python list1 = [1, 2, 3] list(map(lambda x: str(x), list1)) ``` output ```Text ['1', '2', '3'] ``` ### 54. 合并兩個(gè)元組到字典 如:("zhangfei", "guanyu")宏多,(66, 80) -> {'zhangfei': 66, 'guanyu': 80} ```Python a = ("zhangfei", "guanyu") b = (66, 80) dict(zip(a,b)) ``` output ```Text {'zhangfei': 66, 'guanyu': 80} ``` ### 55. 給出如下代碼的輸入,并簡(jiǎn)單解釋 例子1: ```Python a = (1,2,3,[4,5,6,7],8) a[3] = 2 ``` output ```Text --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in 1 a = (1,2,3,[4,5,6,7],8) ----> 2 a[3] = 2 3 #a TypeError: 'tuple' object does not support item assignment ``` 例子2: ```Python a = (1,2,3,[4,5,6,7],8) a[3][2] = 2 a ``` output ```Text (1, 2, 3, [4, 5, 2, 7], 8) ``` 從例子1的報(bào)錯(cuò)中也可以看出澡罚,tuple 是不可變類(lèi)型伸但,不能改變 tuple 里的元素,例子2中留搔,list 是可變類(lèi)型螟蝙,改變其元素是允許的 ### 56. Python 中的反射 反射就是通過(guò)字符串的形式势木,導(dǎo)入模塊;通過(guò)字符串的形式,去模塊尋找指定函數(shù)青责,并執(zhí)行。利用字符串的形式去對(duì)象(模塊)中操作(查找/獲取/刪除/添加)成員绘盟,一種基于字符串的事件驅(qū)動(dòng)袭蝗! 簡(jiǎn)單理解就是用來(lái)判斷某個(gè)字符串是什么,是變量還是方法 ```Python class NewClass(object): def __init__(self, name, male): self.name = name self.male = male def myname(self): print(f'My name is {self.name}') def mymale(self): print(f'I am a {self.male}') people = NewClass('luobo', 'boy') print(hasattr(people, 'name')) print(getattr(people, 'name')) setattr(people, 'male', 'girl') print(getattr(people, 'male')) ``` output ```Text True luobo girl ``` getattr,hasattr,setattr,delattr 對(duì)模塊的修改都在內(nèi)存中進(jìn)行哺窄,并不會(huì)影響文件中真實(shí)內(nèi)容 ### 57. 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 API 使用 flask 構(gòu)造 web 服務(wù)器 ```Python from flask import Flask, request app = Flask(__name__) @app.route('/', methods=['POST']) def simple_api(): result = request.get_json() return result if __name__ == "__main__": app.run() ``` ### 58. metaclass 元類(lèi) 類(lèi)與實(shí)例: 首先定義類(lèi)以后捐下,就可以根據(jù)這個(gè)類(lèi)創(chuàng)建出實(shí)例,所以:先定義類(lèi)萌业,然后創(chuàng)建實(shí)例 類(lèi)與元類(lèi): 先定義元類(lèi)坷襟, 根據(jù) metaclass 創(chuàng)建出類(lèi),所以:先定義 metaclass生年,然后創(chuàng)建類(lèi) ```Python class MyMetaclass(type): def __new__(cls, class_name, class_parents, class_attr): class_attr['print'] = "this is my metaclass's subclass %s" %class_name return type.__new__(cls, class_name, class_parents, class_attr) class MyNewclass(object, metaclass=MyMetaclass): pass myinstance = MyNewclass() myinstance.print ``` output ```Text "this is my metaclass's subclass MyNewclass" ``` ### 59. sort 和 sorted 的區(qū)別 sort() 是可變對(duì)象列表(list)的方法婴程,無(wú)參數(shù),無(wú)返回值抱婉,sort() 會(huì)改變可變對(duì)象 ```Python dict1 = {'test1':1, 'test2':2} list1 = [2, 1, 3] print(list1.sort()) list1 ``` output ```Text None [1, 2, 3] ``` sorted() 是產(chǎn)生一個(gè)新的對(duì)象档叔。sorted(L) 返回一個(gè)排序后的L,不改變?cè)嫉腖蒸绩,sorted() 適用于任何可迭代容器 ```Python dict1 = {'test1':1, 'test2':2} list1 = [2, 1, 3] print(sorted(dict1))print(sorted(list1)) ``` output ```Text ['test1', 'test2'] [1, 2, 3] ``` ### 60. Python 中的 GIL GIL 是 Python 的全局解釋器鎖衙四,同一進(jìn)程中假如有多個(gè)線程運(yùn)行,一個(gè)線程在運(yùn)行 Python 程序的時(shí)候會(huì)占用 Python 解釋器(加了一把鎖即 GIL)患亿,使該進(jìn)程內(nèi)的其他線程無(wú)法運(yùn)行传蹈,等該線程運(yùn)行完后其他線程才能運(yùn)行。如果線程運(yùn)行過(guò)程中遇到耗時(shí)操作步藕,則解釋器鎖解開(kāi)惦界,使其他線程運(yùn)行。所以在多線程中咙冗,線程的運(yùn)行仍是有先后順序的沾歪,并不是同時(shí)進(jìn)行 ### 61. 產(chǎn)生8位隨機(jī)密碼 ```Python import random "".join(random.choice(string.printable[:-7]) for i in range(8)) ``` output ```Text 'd5^NdNJp' ``` ### 62. 輸出原始字符 ```Python print('hello\nworld') print(b'hello\nworld') print(r'hello\nworld') ``` output ```Text hello world b'hello\nworld' hello\nworld ``` ### 63. 列表內(nèi),字典按照 value 大小排序 ```Python list1 = [{'name': 'guanyu', 'age':29}, {'name': 'zhangfei', 'age': 28}, {'name': 'liubei', 'age':31}] sorted(list1, key=lambda x:x['age']) ``` output ```Text [{'name': 'zhangfei', 'age': 28}, {'name': 'guanyu', 'age': 29}, {'name': 'liubei', 'age': 31}] ``` ### 64. 簡(jiǎn)述 any() 和 all() 方法 all 如果存在 0 Null False 返回 False雾消,否則返回 True灾搏;any 如果都是 0挫望,None,F(xiàn)alse确镊,Null 時(shí)士骤,返回 True ```Python print(all([1, 2, 3, 0])) print(all([1, 2, 3])) print(any([1, 2, 3, 0])) print(any([0, None, False])) ``` output ```Text False True True False ``` ### 65. 反轉(zhuǎn)整數(shù) ```Python def reverse_int(x): if not isinstance(x, int): return False if -10 < x < 10: return x tmp = str(x) if tmp[0] != '-': tmp = tmp[::-1] return int(tmp) else: tmp = tmp[1:][::-1] x = int(tmp) return -x reverse_int(-23837) ``` output ```Text -73832 ``` 首先判斷是否是整數(shù),再判斷是否是一位數(shù)字蕾域,最后再判斷是不是負(fù)數(shù) ### 66. 函數(shù)式編程 函數(shù)式編程是一種抽象程度很高的編程范式拷肌,純粹的函數(shù)式編程語(yǔ)言編寫(xiě)的函數(shù)沒(méi)有變量,因此旨巷,任意一個(gè)函數(shù)巨缘,只要輸入是確定的,輸出就是確定的采呐,這種純函數(shù)稱之為沒(méi)有副作用若锁。而允許使用變量的程序設(shè)計(jì)語(yǔ)言,由于函數(shù)內(nèi)部的變量狀態(tài)不確定斧吐,同樣的輸入又固,可能得到不同的輸出,因此煤率,這種函數(shù)是有副作用的仰冠。由于 Python 允許使用變量,因此蝶糯,Python 不是純函數(shù)式編程語(yǔ)言 函數(shù)式編程的一個(gè)特點(diǎn)就是洋只,允許把函數(shù)本身作為參數(shù)傳入另一個(gè)函數(shù),還允許返回一個(gè)函數(shù)昼捍! 函數(shù)作為返回值例子: ```Python def sum(*args): def inner_sum(): tmp = 0 for i in args: tmp += i return tmp return inner_sum mysum = sum(2, 4, 6) print(type(mysum)) mysum() ``` output ```Text 12 ``` ### 67. 簡(jiǎn)述閉包 如果在一個(gè)內(nèi)部函數(shù)里识虚,對(duì)在外部作用域(但不是在全局作用域)的變量進(jìn)行引用,那么內(nèi)部函數(shù)就被認(rèn)為是閉包(closure) 附上函數(shù)作用域圖片 ![](https://upload-images.jianshu.io/upload_images/5803165-110e6222c6c5fbb1.png) 閉包特點(diǎn) 1.必須有一個(gè)內(nèi)嵌函數(shù) 2.內(nèi)嵌函數(shù)必須引用外部函數(shù)中的變量 3.外部函數(shù)的返回值必須是內(nèi)嵌函數(shù) ### 68. 簡(jiǎn)述裝飾器 裝飾器是一種特殊的閉包妒茬,就是在閉包的基礎(chǔ)上傳遞了一個(gè)函數(shù)担锤,然后覆蓋原來(lái)函數(shù)的執(zhí)行入口,以后調(diào)用這個(gè)函數(shù)的時(shí)候乍钻,就可以額外實(shí)現(xiàn)一些功能了 一個(gè)打印 log 的例子: ```Python import time def log(func): def inner_log(*args, **kw): print("Call: {}".format(func.__name__)) return func(*args, **kw) return inner_log @log def timer(): print(time.time()) timer() ``` output ```Text Call: timer 1560171403.5128365 ``` 本質(zhì)上妻献,decorator就是一個(gè)返回函數(shù)的高階函數(shù) ### 69. 協(xié)程的優(yōu)點(diǎn) 子程序切換不是線程切換,而是由程序自身控制 沒(méi)有線程切換的開(kāi)銷(xiāo)团赁,和多線程比,線程數(shù)量越多谨履,協(xié)程的性能優(yōu)勢(shì)就越明顯 不需要多線程的鎖機(jī)制欢摄,因?yàn)橹挥幸粋€(gè)線程,也不存在同時(shí)寫(xiě)變量沖突笋粟,在協(xié)程中控制共享資源不加鎖 ### 70. 實(shí)現(xiàn)一個(gè)斐波那契數(shù)列 斐波那契數(shù)列: 又稱黃金分割數(shù)列怀挠,指的是這樣一個(gè)數(shù)列:1析蝴、1、2绿淋、3闷畸、5、8吞滞、13佑菩、21、34裁赠、……在數(shù)學(xué)上殿漠,斐波納契數(shù)列以如下被以遞歸的方法定義:F(1)=1,F(xiàn)(2)=1, F(n)=F(n-1)+F(n-2)(n>=2佩捞,n∈N*) 生成器法: ```Python def fib(n): if n == 0: return False if not isinstance(n, int) or (abs(n) != n): # 判斷是正整數(shù) return False a, b = 0, 1 while n: a, b = b, a+b n -= 1 yield a [i for i in fib(10)] ``` output ```Text [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] ``` 遞歸法: ```Python def fib(n): if n == 0: return False if not isinstance(n, int) or (abs(n) != n): return False if n <= 1: return n return fib(n-1)+ fib(n-2) [fib(i) for i in range(1, 11)] ``` output ```Text [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] ``` ### 71. 正則切分字符串 ```Python import re str1 = 'hello world:luobo dazahui' result = re.split(r":| ", str1) print(result) ``` output ```Text ['hello', 'world', 'luobo', 'dazahui'] ``` ### 72. yield 用法 yield 是用來(lái)生成迭代器的語(yǔ)法绞幌,在函數(shù)中,如果包含了 yield一忱,那么這個(gè)函數(shù)就是一個(gè)迭代器莲蜘。當(dāng)代碼執(zhí)行至 yield 時(shí),就會(huì)中斷代碼執(zhí)行帘营,直到程序調(diào)用 next() 函數(shù)時(shí)票渠,才會(huì)在上次 yield 的地方繼續(xù)執(zhí)行 ```Python def foryield(): print("start test yield") while True: result = yield 5 print("result:", result) g = foryield() print(next(g)) print("*"*20) print(next(g)) ``` output ```Text start test yield 5 ******************** result: None 5 ``` 可以看到,第一個(gè)調(diào)用 next() 函數(shù)仪吧,程序只執(zhí)行到了 "result = yield 5" 這里庄新,同時(shí)由于 yield 中斷了程序,所以 result 也沒(méi)有被賦值薯鼠,所以第二次執(zhí)行 next() 時(shí)择诈,result 是 None ### 73. 冒泡排序 ```Python list1 = [2, 5, 8, 9, 3, 11] def paixu(data, reverse=False): if not reverse: for i in range(len(data) - 1): for j in range(len(data) - 1 - i): if data[j] > data[j+1]: data[j], data[j+1] = data[j+1], data[j] return data else: for i in range(len(data) - 1): for j in range(len(data) - 1 - i): if data[j] < data[j+1]: data[j], data[j+1] = data[j+1], data[j] return data print(paixu(list1, reverse=True)) ``` output ```Text [11, 9, 8, 5, 3, 2] ``` ### 74. 快速排序 快排的思想:首先任意選取一個(gè)數(shù)據(jù)(通常選用數(shù)組的第一個(gè)數(shù))作為關(guān)鍵數(shù)據(jù),然后將所有比它小的數(shù)都放到它前面出皇,所有比它大的數(shù)都放到它后面羞芍,這個(gè)過(guò)程稱為一趟快速排序,之后再遞歸排序兩邊的數(shù)據(jù) 挑選基準(zhǔn)值:從數(shù)列中挑出一個(gè)元素郊艘,稱為"基準(zhǔn)"(pivot) 分割:重新排序數(shù)列荷科,所有比基準(zhǔn)值小的元素?cái)[放在基準(zhǔn)前面,所有比基準(zhǔn)值大的元素?cái)[在基準(zhǔn)后面(與基準(zhǔn)值相等的數(shù)可以到任何一邊) 在這個(gè)分割結(jié)束之后纱注,對(duì)基準(zhǔn)值的排序就已經(jīng)完成 遞歸排序子序列:遞歸地將小于基準(zhǔn)值元素的子序列和大于基準(zhǔn)值元素的子序列排序 ```Python list1 = [8, 5, 1, 3, 2, 10, 11, 4, 12, 20] def partition(arr,low,high): i = ( low-1 ) # 最小元素索引 pivot = arr[high] for j in range(low , high): # 當(dāng)前元素小于或等于 pivot if arr[j] <= pivot: i = i+1 arr[i],arr[j] = arr[j],arr[i] arr[i+1],arr[high] = arr[high],arr[i+1] return ( i+1 ) def quicksort(arr,low,high): if low < high: pi = partition(arr,low,high) quicksort(arr, low, pi-1) quicksort(arr, pi+1, high) quicksort(list1, 0, len(list1)-1) print(list1) ``` output ```Text [1, 2, 3, 4, 5, 8, 10, 11, 12, 20] ``` ### 75. requests 簡(jiǎn)介 該庫(kù)是發(fā)起 HTTP 請(qǐng)求的強(qiáng)大類(lèi)庫(kù)畏浆,調(diào)用簡(jiǎn)單,功能強(qiáng)大 ```Python import requests url = "http://www.luobodazahui.top" response = requests.get(url) # 獲得請(qǐng)求 response.encoding = "utf-8" # 改變其編碼 html = response.text # 獲得網(wǎng)頁(yè)內(nèi)容 binary__content = response.content # 獲得二進(jìn)制數(shù)據(jù) raw = requests.get(url, stream=True) # 獲得原始響應(yīng)內(nèi)容 headers = {'user-agent': 'my-test/0.1.1'} # 定制請(qǐng)求頭 r = requests.get(url, headers=headers) cookies = {"cookie": "# your cookie"} # cookie的使用 r = requests.get(url, cookies=cookies) ``` ### 76. 比較兩個(gè) json 數(shù)據(jù)是否相等 ```Python dict1 = {"zhangfei": 12, "guanyu": 13, "liubei": 18} dict2 = {"zhangfei": 12, "guanyu": 13, "liubei": 18} def compare_dict(dict1, dict2): issame = [] for k in dict1.keys(): if k in dict2: if dict1[k] == dict2[k]: issame.append(1) else: issame.append(2) else: issame.append(3) print(issame) sum_except = len(issame) sum_actually = sum(issame) if sum_except == sum_actually: print("this two dict are same!") return True else: print("this two dict are not same!") return False test = compare_dict(dict1, dict2) ``` output ```Text [1, 1, 1] this two dict are same! ``` ### 77. 讀取鍵盤(pán)輸入 ```Python input() 函數(shù) def forinput(): input_text = input() print("your input text is: ", input_text) forinput() ``` output ```Text hello your input text is: hello ``` ### 78. enumerate enumerate() 函數(shù)用于將一個(gè)可遍歷的數(shù)據(jù)對(duì)象(如列表狞贱、元組或字符串)組合為一個(gè)索引序列刻获,同時(shí)列出數(shù)據(jù)和數(shù)據(jù)下標(biāo),一般用在 for 循環(huán)當(dāng)中 ```Python data1 = ['one', 'two', 'three', 'four'] for i, enu in enumerate(data1): print(i, enu) ``` output ```Text 0 one 1 two 2 three 3 four ``` ### 79. pass 語(yǔ)句 pass 是空語(yǔ)句瞎嬉,是為了保持程序結(jié)構(gòu)的完整性蝎毡。pass 不做任何事情厚柳,一般用做占位語(yǔ)句 ```Python def forpass(n): if n == 1: pass else: print('not 1') forpass(1) ``` ### 80. 正則匹配郵箱 ```Python import re email_list= ["test01@163.com","test02@163.123", ".test03g@qq.com", "test04@gmail.com" ] for email in email_list: ret = re.match("[\w]{4,20}@(.*)\.com$",email) if ret: print("%s 是符合規(guī)定的郵件地址,匹配后結(jié)果是:%s" % (email,ret.group())) else: print("%s 不符合要求" % email) ``` output ```Text test01@163.com 是符合規(guī)定的郵件地址沐兵,匹配后結(jié)果是:test01@163.com test02@163.123 不符合要求 .test03g@qq.com 不符合要求 test04@gmail.com 是符合規(guī)定的郵件地址别垮,匹配后結(jié)果是:test04@gmail.com ``` ### 81. 統(tǒng)計(jì)字符串中大寫(xiě)字母的數(shù)量 ```Python str2 = 'werrQWSDdiWuW' counter = 0 for i in str2: if i.isupper(): counter += 1 print(counter) ``` output ```Text 6 ``` ### 82. json 序列化時(shí)保留中文 普通序列化: ```Python import json dict1 = {'name': '蘿卜', 'age': 18} dict1_new = json.dumps(dict1) print(dict1_new) ``` output ```Text {"name": "\u841d\u535c", "age": 18} ``` 保留中文 ```Python import json dict1 = {'name': '蘿卜', 'age': 18} dict1_new = json.dumps(dict1, ensure_ascii=False) print(dict1_new) ``` output ```Text {"name": "蘿卜", "age": 18} ``` ### 83. 簡(jiǎn)述繼承 一個(gè)類(lèi)繼承自另一個(gè)類(lèi),也可以說(shuō)是一個(gè)孩子類(lèi)/派生類(lèi)/子類(lèi)扎谎,繼承自父類(lèi)/基類(lèi)/超類(lèi)碳想,同時(shí)獲取所有的類(lèi)成員(屬性和方法) 繼承使我們可以重用代碼,并且還可以更方便地創(chuàng)建和維護(hù)代碼 Python 支持以下類(lèi)型的繼承: 單繼承- 一個(gè)子類(lèi)類(lèi)繼承自單個(gè)基類(lèi) 多重繼承- 一個(gè)子類(lèi)繼承自多個(gè)基類(lèi) 多級(jí)繼承- 一個(gè)子類(lèi)繼承自一個(gè)基類(lèi)簿透,而基類(lèi)繼承自另一個(gè)基類(lèi) 分層繼承- 多個(gè)子類(lèi)繼承自同一個(gè)基類(lèi) 混合繼承- 兩種或兩種以上繼承類(lèi)型的組合 ### 84. 什么是猴子補(bǔ)丁 猴子補(bǔ)丁是指在運(yùn)行時(shí)動(dòng)態(tài)修改類(lèi)和模塊 猴子補(bǔ)丁主要有以下幾個(gè)用處: 在運(yùn)行時(shí)替換方法移袍、屬性等 在不修改第三方代碼的情況下增加原來(lái)不支持的功能 在運(yùn)行時(shí)為內(nèi)存中的對(duì)象增加 patch 而不是在磁盤(pán)的源代碼中增加 ### 85. help() 函數(shù)和 dir() 函數(shù) help() 函數(shù)返回幫助文檔和參數(shù)說(shuō)明: ```Python help(dict) ``` output ```Text Help on class dict in module builtins: class dict(object) | dict() -> new empty dictionary | dict(mapping) -> new dictionary initialized from a mapping object's | (key, value) pairs | dict(iterable) -> new dictionary initialized as if via: | d = {} | for k, v in iterable: | d[k] = v | dict(**kwargs) -> new dictionary initialized with the name=value pairs | in the keyword argument list. For example: dict(one=1, two=2) ...... ``` dir() 函數(shù)返回對(duì)象中的所有成員 (任何類(lèi)型) ```Python dir(dict) ``` output ```Text ['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', ...... ``` ### 86. 解釋 Python 中的`//`,`%`和`**`運(yùn)算符 `//` 運(yùn)算符執(zhí)行地板除法老充,返回結(jié)果的整數(shù)部分 (向下取整) `%` 是取模符號(hào)葡盗,返回除法后的余數(shù) `**` 符號(hào)表示取冪. a**b 返回 a 的 b 次方 ```Python print(5//3) print(5/3) print(5%3) print(5**3) ``` output ```Text 1 1.6666666666666667 2 125 ``` ### 87. 主動(dòng)拋出異常 使用 raise ```Python def test_raise(n): if not isinstance(n, int): raise Exception('not a int type') else: print('good') test_raise(8.9) ``` output ```Text --------------------------------------------------------------------------- Exception Traceback (most recent call last) in 4 else: 5 print('good') ----> 6 test_raise(8.9) in test_raise(n) 1 def test_raise(n): 2 if not isinstance(n, int): ----> 3 raise Exception('not a int type') 4 else: 5 print('good') Exception: not a int type ``` ### 88. tuple 和 list 轉(zhuǎn)換 ```Python tuple1 = (1, 2, 3, 4) list1 = list(tuple1) print(list1) tuple2 = tuple(list1) print(tuple2) ``` output ```Text [1, 2, 3, 4](1, 2, 3, 4) ``` ### 89. 簡(jiǎn)述斷言 Python 的斷言就是檢測(cè)一個(gè)條件,如果條件為真啡浊,它什么都不做觅够;反之它觸發(fā)一個(gè)帶可選錯(cuò)誤信息的 AssertionError ```Python def testassert(n): assert n == 2, "n is not 2" print('n is 2') testassert(1) ``` output ```Text --------------------------------------------------------------------------- AssertionError Traceback (most recent call last) in 2 assert n == 2, "n is not 2" 3 print('n is 2') ----> 4 testassert(1) in testassert(n) 1 def testassert(n): ----> 2 assert n == 2, "n is not 2" 3 print('n is 2') 4 testassert(1) AssertionError: n is not 2 ``` ### 90. 什么是異步非阻塞 同步異步指的是調(diào)用者與被調(diào)用者之間的關(guān)系 所謂同步,就是在發(fā)出一個(gè)功能調(diào)用時(shí)巷嚣,在沒(méi)有得到結(jié)果之前喘先,該調(diào)用就不會(huì)返回,一旦調(diào)用返回廷粒,就得到了返回值 異步的概念和同步相對(duì)窘拯,調(diào)用在發(fā)出之后,這個(gè)調(diào)用就直接返回了,所以沒(méi)有返回結(jié)果。當(dāng)該異步功能完成后坝茎,被調(diào)用者可以通過(guò)狀態(tài)涤姊、通知或回調(diào)來(lái)通知調(diào)用者 阻塞非阻塞是線程或進(jìn)程之間的關(guān)系 阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起(如遇到io操作)嗤放。調(diào)用線程只有在得到結(jié)果之后才會(huì)返回思喊。函數(shù)只有在得到結(jié)果之后才會(huì)將阻塞的線程激活 非阻塞和阻塞的概念相對(duì)應(yīng),非阻塞調(diào)用指在不能立刻得到結(jié)果之前也會(huì)立刻返回次酌,同時(shí)該函數(shù)不會(huì)阻塞當(dāng)前線程 ### 91. 什么是負(fù)索引 Python 中的序列是有索引的恨课,它由正數(shù)和負(fù)數(shù)組成。正的數(shù)字使用'0'作為第一個(gè)索引岳服,'1'作為第二個(gè)索引剂公,以此類(lèi)推 負(fù)數(shù)的索引從'-1'開(kāi)始,表示序列中的最后一個(gè)索引吊宋,' - 2'作為倒數(shù)第二個(gè)索引诬留,依次類(lèi)推 ### 92. 退出 Python 后,內(nèi)存是否全部釋放 不是的,那些具有對(duì)象循環(huán)引用或者全局命名空間引用的變量文兑,在 Python 退出時(shí)往往不會(huì)被釋放 另外不會(huì)釋放 C 庫(kù)保留的部分內(nèi)容 ### 93. Flask 和 Django 的異同 Flask 是 “microframework”,主要用來(lái)編寫(xiě)小型應(yīng)用程序腺劣,不過(guò)隨著 Python 的普及绿贞,很多大型程序也在使用 Flask。同時(shí)橘原,在 Flask 中籍铁,我們必須使用外部庫(kù) Django 適用于大型應(yīng)用程序。它提供了靈活性趾断,以及完整的程序框架和快速的項(xiàng)目生成方法拒名。可以選擇不同的數(shù)據(jù)庫(kù)芋酌,URL結(jié)構(gòu)增显,模板樣式等 ### 94. 創(chuàng)建刪除操作系統(tǒng)上的文件 ```Python import os f = open('test.txt', 'w') f.close() os.listdir() os.remove('test.txt') ``` ### 95. 簡(jiǎn)述 logging 模塊 logging 模塊是 Python 內(nèi)置的標(biāo)準(zhǔn)模塊,主要用于輸出運(yùn)行日志脐帝,可以設(shè)置輸出日志的等級(jí)同云、日志保存路徑、日志文件回滾等堵腹;相比 print炸站,具備如下優(yōu)點(diǎn): 可以通過(guò)設(shè)置不同的日志等級(jí),在 release 版本中只輸出重要信息疚顷,而不必顯示大量的調(diào)試信息 print 將所有信息都輸出到標(biāo)準(zhǔn)輸出中旱易,嚴(yán)重影響開(kāi)發(fā)者從標(biāo)準(zhǔn)輸出中查看其它數(shù)據(jù);logging 則可以由開(kāi)發(fā)者決定將信息輸出到什么地方腿堤,以及怎么輸出 簡(jiǎn)單配置: ```Python import logging logging.debug("debug log") logging.info("info log") logging.warning("warning log") logging.error("error log") logging.critical("critica log") ``` output ```Text WARNING:root:warning log ERROR:root:error log CRITICAL:root:critica log ``` 默認(rèn)情況下阀坏,只顯示了大于等于WARNING級(jí)別的日志。logging.basicConfig()函數(shù)調(diào)整日志級(jí)別释液、輸出格式等 ### 96. 統(tǒng)計(jì)字符串中單詞出現(xiàn)次數(shù) ```Python from collections import Counter str1 = "nihsasehndciswemeotpxc" print(Counter(str1)) ``` output ```Text Counter({'s': 3, 'e': 3, 'n': 2, 'i': 2, 'h': 2, 'c': 2, 'a': 1, 'd': 1, 'w': 1, 'm': 1, 'o': 1, 't': 1, 'p': 1, 'x': 1}) ``` ### 97. 正則 re.complie 的作用 re.compile 是將正則表達(dá)式編譯成一個(gè)對(duì)象全释,加快速度,并重復(fù)使用 ### 98. try except else finally 的意義 try..except..else 沒(méi)有捕獲到異常误债,執(zhí)行 else 語(yǔ)句 try..except..finally 不管是否捕獲到異常浸船,都執(zhí)行 finally 語(yǔ)句 ### 99.反轉(zhuǎn)列表 使用切片: ```Python $ python -m timeit -n 1000000 -s 'import numpy as np' 'mylist=list(np.arange(0, 200))' 'mylist[::-1]' 1000000 loops, best of 5: 15.6 usec per loop ``` 使用 reverse(): ```Python $ python -m timeit -n 1000000 -s 'import numpy as np' 'mylist=list(np.arange(0, 200))' 'mylist.reverse()' 1000000 loops, best of 5: 10.7 usec per loop ``` 這兩種方法都可以反轉(zhuǎn)列表,但需要注意的是內(nèi)置函數(shù) reverse() 會(huì)更改原始列表寝蹈,而切片方法會(huì)創(chuàng)建一個(gè)新列表李命。 顯然,內(nèi)置函數(shù) reverse() 比列表切片方法更快箫老! ### 100. 字符串中數(shù)字替換 使用 re 正則替換 ```Python import re str1 = '我是周蘿卜封字,今年18歲' result = re.sub(r"\d+","20",str1) print(result) ``` output ```Text 我是周蘿卜,今年20歲 ``` ## 綜合篇:網(wǎng)絡(luò)編程 ### 101. 簡(jiǎn)述 OSI 七層協(xié)議 是網(wǎng)絡(luò)傳輸協(xié)議,人為的把網(wǎng)絡(luò)傳輸?shù)牟煌A段劃分成不同的層次 七層劃分為:應(yīng)用層阔籽、表示層流妻、會(huì)話層、傳輸層笆制、網(wǎng)絡(luò)層绅这、數(shù)據(jù)鏈路層、物理層 五層劃分為:應(yīng)用層在辆、傳輸層证薇、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層匆篓、物理層 物理層:網(wǎng)線浑度,電纜等物理設(shè)備 數(shù)據(jù)鏈路層:Mac 地址 網(wǎng)絡(luò)層:IP 地址 傳輸層:TCP,UDP 協(xié)議 應(yīng)用層:FTP 協(xié)議鸦概,Email箩张,WWW 等 ### 102. 三次握手、四次揮手的流程 都發(fā)生在傳輸層 三次握手: TCP 協(xié)議是主機(jī)對(duì)主機(jī)層的傳輸控制協(xié)議完残,提供可靠的連接服務(wù)伏钠,采用三次握手確認(rèn)建立一個(gè)連接。 TCP 標(biāo)志位(位碼),有6種標(biāo)示:SYN(synchronous建立聯(lián)機(jī)) ACK(acknowledgement 確認(rèn)) PSH(push傳送) FIN(finish結(jié)束) RST(reset重置) URG(urgent緊急) Sequence number(順序號(hào)碼) Acknowledge number(確認(rèn)號(hào)碼) 第一次握手:主機(jī) A 發(fā)送位碼為 syn=1,隨機(jī)產(chǎn)生 seq number=1234567 的數(shù)據(jù)包到服務(wù)器谨设,并進(jìn)入 SYN_SEND 狀態(tài)熟掂,主機(jī) B 由 SYN=1 知道,A 要求建立聯(lián)機(jī) 第二次握手:主機(jī) B 收到請(qǐng)求后要確認(rèn)聯(lián)機(jī)信息扎拣,向 A 發(fā)送 ack number=(主機(jī) A 的 seq+1),syn=1,ack=1,隨機(jī)產(chǎn)生 seq=7654321 的包赴肚,并進(jìn)入 SYN_RECV 狀態(tài) 第三次握手:主機(jī) A 收到后檢查 ack number 是否正確,即第一次發(fā)送的 seq number+1,以及位碼 ack 是否為 1二蓝,若正確誉券,主機(jī) A 會(huì)再發(fā)送 ack number=(主機(jī) B 的 seq+1),ack=1,主機(jī) B 收到后確認(rèn) seq 值與 ack=1 則連接建立成功刊愚,兩個(gè)主機(jī)均進(jìn)入 ESTABLISHED 狀態(tài) 以上完成三次握手踊跟,主機(jī) A 與主機(jī) B 開(kāi)始傳送數(shù)據(jù) 四次揮手: 因?yàn)?TCP 連接是全雙工的,因此每個(gè)方向都必須單獨(dú)進(jìn)行關(guān)閉鸥诽。這個(gè)原則是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個(gè) FIN 來(lái)終止這個(gè)方向的連接商玫。收到一個(gè) FIN 只意味著這一方向上沒(méi)有數(shù)據(jù)流動(dòng),一個(gè) TCP 連接在收到一個(gè) FIN 后仍能發(fā)送數(shù)據(jù)牡借。首先進(jìn)行關(guān)閉的一方將執(zhí)行主動(dòng)關(guān)閉拳昌,而另一方執(zhí)行被動(dòng)關(guān)閉 服務(wù)器 A 發(fā)送一個(gè) FIN,用來(lái)關(guān)閉 A 到服務(wù)器 B 的數(shù)據(jù)傳送钠龙。 服務(wù)器 B 收到這個(gè) FIN炬藤,它發(fā)回一個(gè) ACK御铃,確認(rèn)序號(hào)為收到的序號(hào)加1。和 SYN 一樣沈矿,一個(gè) FIN 將占用一個(gè)序號(hào) 服務(wù)器 B 關(guān)閉與服務(wù)器 A 的連接上真,發(fā)送一個(gè) FIN 給服務(wù)器 A 服務(wù)器 A 發(fā)回 ACK 報(bào)文確認(rèn),并將確認(rèn)序號(hào)設(shè)置為收到序號(hào)加1 ### 103. 什么是 C/S 和 B/S 架構(gòu) B/S 又稱為瀏覽器/服務(wù)器模式细睡。比如各種網(wǎng)站谷羞,jupyter notebook 等。 優(yōu)點(diǎn):零安裝溜徙,維護(hù)簡(jiǎn)單,共享性好犀填。 缺點(diǎn):安全性較差蠢壹,個(gè)性化不足 C/S 又稱為客戶端/服務(wù)器模式。比如微信客戶端九巡,Oracle 客戶端等图贸。 優(yōu)點(diǎn):安全性好,數(shù)據(jù)傳輸較快冕广,穩(wěn)定疏日。 缺點(diǎn):對(duì) PC 機(jī)操作系統(tǒng)等有要求,當(dāng)客戶端較多時(shí)撒汉,服務(wù)器端負(fù)載較大 ### 104. TCP 和 UDP 的區(qū)別 TCP 和 UDP 都是 OSI 模型中運(yùn)輸層的協(xié)議沟优。TCP 提供可靠的通信傳輸,而 UDP 則常被用于廣播和細(xì)節(jié)控制交給應(yīng)用的通信傳輸睬辐。 UDP 不提供復(fù)雜的控制機(jī)制挠阁,利用 IP 提供面向無(wú)連接的通信服務(wù)。 TCP 充分實(shí)現(xiàn)了數(shù)據(jù)傳輸時(shí)各種控制功能溯饵,可以進(jìn)行丟包的重發(fā)控制侵俗,還可以對(duì)次序亂掉的分包進(jìn)行順序控制 TCP 應(yīng)用:FTP 傳輸,點(diǎn)對(duì)點(diǎn)短信等 UDP 應(yīng)用:媒體流等 ### 105. 局域網(wǎng)和廣域網(wǎng) 廣域網(wǎng)(WAN丰刊,Wide Area Network)也稱遠(yuǎn)程網(wǎng)(long haul network )隘谣。通常跨接很大的物理范圍啄巧,所覆蓋的范圍從幾十公里到幾千公里寻歧,它能連接多個(gè)城市或國(guó)家,或橫跨幾個(gè)洲并能提供遠(yuǎn)距離通信棵帽,形成國(guó)際性的遠(yuǎn)程網(wǎng)絡(luò) 域網(wǎng)(Local Area Network熄求,LAN)是指在某一區(qū)域內(nèi)由多臺(tái)計(jì)算機(jī)互聯(lián)成的計(jì)算機(jī)組。一般是方圓幾千米以內(nèi)逗概。局域網(wǎng)可以實(shí)現(xiàn)文件管理弟晚、應(yīng)用軟件共享、打印機(jī)共享、工作組內(nèi)的日程安排卿城、電子郵件和傳真通信服務(wù)等功能枚钓。局域網(wǎng)是封閉型的,可以由辦公室內(nèi)的兩臺(tái)計(jì)算機(jī)組成瑟押,也可以由一個(gè)公司內(nèi)的上千臺(tái)計(jì)算機(jī)組成 ### 106. arp 協(xié)議 ARP(Address Resolution Protocol)即地址解析協(xié)議搀捷, 用于實(shí)現(xiàn)從 IP 地址到 MAC 地址的映射,即詢問(wèn)目標(biāo) IP 對(duì)應(yīng)的 MAC 地址 ### 107. 什么是 socket多望?簡(jiǎn)述基于 TCP 協(xié)議的套接字通信流程 socket 是對(duì) TCP/IP 協(xié)議的封裝嫩舟,它的出現(xiàn)只是使得程序員更方便地使用 TCP/IP 協(xié)議棧而已。socket 本身并不是協(xié)議怀偷,它是應(yīng)用層與 TCP/IP 協(xié)議族通信的中間軟件抽象層家厌,是一組調(diào)用接口(TCP/IP網(wǎng)絡(luò)的API函數(shù)) “TCP/IP 只是一個(gè)協(xié)議棧,就像操作系統(tǒng)的運(yùn)行機(jī)制一樣椎工,必須要具體實(shí)現(xiàn)饭于,同時(shí)還要提供對(duì)外的操作接口。 這個(gè)就像操作系統(tǒng)會(huì)提供標(biāo)準(zhǔn)的編程接口维蒙,比如win32編程接口一樣掰吕。TCP/IP 也要提供可供程序員做網(wǎng)絡(luò)開(kāi)發(fā)所用的接口,這就是 Socket 編程接口颅痊≈呈欤” Server: ```Python import socket import threading def tcplink(sock, addr): print('Accept new connection from %s:%s...' % addr) sock.send(b'Welcome!') while True: data = sock.recv(1024) time.sleep(1) if not data or data.decode('utf-8') == 'exit': break sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8')) sock.close() print('Connection from %s:%s closed.' % addr) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 監(jiān)聽(tīng)端口: s.bind(('127.0.0.1', 9999)) s.listen(5) print('Waiting for connection...') while True: # 接受一個(gè)新連接: sock, addr = s.accept() # 創(chuàng)建新線程來(lái)處理TCP連接: t = threading.Thread(target=tcplink, args=(sock, addr)) t.start() ``` Client: ```Python import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立連接: s.connect(('127.0.0.1', 9999)) # 接收歡迎消息: print(s.recv(1024).decode('utf-8')) for data in [b'Michael', b'Tracy', b'Sarah']: # 發(fā)送數(shù)據(jù): s.send(data) print(s.recv(1024).decode('utf-8')) s.send(b'exit') s.close() ``` 例子來(lái)源于廖雪峰的官網(wǎng) ### 108. 簡(jiǎn)述 進(jìn)程、線程八千、協(xié)程的區(qū)別以及應(yīng)用場(chǎng)景 進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng)吗讶,進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。每個(gè)進(jìn)程都有自己的獨(dú)立內(nèi)存空間恋捆,不同進(jìn)程通過(guò)進(jìn)程間通信來(lái)通信 線程是進(jìn)程的一個(gè)實(shí)體照皆,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位沸停。線程自己基本上不擁有系統(tǒng)資源膜毁,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源 協(xié)程是一種用戶態(tài)的輕量級(jí)線程愤钾,協(xié)程的調(diào)度完全由用戶控制瘟滨。協(xié)程擁有自己的寄存器上下文和棧 多進(jìn)程:密集 CPU 任務(wù),需要充分使用多核 CPU 資源(服務(wù)器能颁,大量的并行計(jì)算)的時(shí)候杂瘸,用多進(jìn)程。 缺陷:多個(gè)進(jìn)程之間通信成本高伙菊,切換開(kāi)銷(xiāo)大 多線程:密集 I/O 任務(wù)(網(wǎng)絡(luò) I/O败玉,磁盤(pán) I/O敌土,數(shù)據(jù)庫(kù) I/O)使用多線程合適。 缺陷:同一個(gè)時(shí)間切片只能運(yùn)行一個(gè)線程运翼,不能做到高并行返干,但是可以做到高并發(fā) 協(xié)程:又稱微線程,在單線程上執(zhí)行多個(gè)任務(wù)血淌,用函數(shù)切換矩欠,開(kāi)銷(xiāo)極小。不通過(guò)操作系統(tǒng)調(diào)度悠夯,沒(méi)有進(jìn)程癌淮、線程的切換開(kāi)銷(xiāo)。缺陷:?jiǎn)尉€程執(zhí)行沦补,處理密集 CPU 和本地磁盤(pán) IO 的時(shí)候该默,性能較低。處理網(wǎng)絡(luò) I/O 性能還是比較高 多線程請(qǐng)求返回是無(wú)序的策彤,哪個(gè)線程有數(shù)據(jù)返回就處理哪個(gè)線程,而協(xié)程返回的數(shù)據(jù)是有序的 ### 109. 如何使用線程池和進(jìn)程池 池的功能是限制啟動(dòng)的進(jìn)程數(shù)或線程數(shù)匣摘。當(dāng)并發(fā)的任務(wù)數(shù)遠(yuǎn)遠(yuǎn)超過(guò)了計(jì)算機(jī)的承受能力時(shí)店诗,即無(wú)法一次性開(kāi)啟過(guò)多的進(jìn)程數(shù)或線程數(shù)時(shí),就應(yīng)該用池的概念將開(kāi)啟的進(jìn)程數(shù)或線程數(shù)限制在計(jì)算機(jī)可承受的范圍內(nèi) 多進(jìn)程 ```Python from multiprocessing import Pool import os import time import random def long_time_task(name): print('Run task %s (%s)...' % (name, os.getpid())) start = time.time() time.sleep(random.random() * 3) end = time.time() print('Task %s runs %0.2f seconds.' % (name, (end - start))) def test_pool(): print('Parent process %s.' % os.getpid()) p = Pool(4) for i in range(5): p.apply_async(long_time_task, args=(i,)) print('Waiting for all subprocesses done...') p.close() p.join() print('All subprocesses done.') if __name__ == '__main__': test_pool() ``` output ```Text Parent process 32432. Waiting for all subprocesses done... Run task 0 (15588)... Run task 1 (32372)... Run task 2 (12440)... Run task 3 (18956)... Task 2 runs 0.72 seconds. Run task 4 (12440)... Task 3 runs 0.82 seconds. Task 1 runs 1.21 seconds. Task 0 runs 3.00 seconds. Task 4 runs 2.95 seconds. All subprocesses done. ``` apply_async(func[, args[, kwds]]) :使用非阻塞方式調(diào)用 func(并行執(zhí)行音榜,堵塞方式必須等待上一個(gè)進(jìn)程退出才能執(zhí)行下一個(gè)進(jìn)程)庞瘸,args 為傳遞給 func 的參數(shù)列表,kwds 為傳遞給 func 的關(guān)鍵字參數(shù)列表赠叼; close():關(guān)閉 Pool擦囊,使其不再接受新的任務(wù); terminate():不管任務(wù)是否完成嘴办,立即終止瞬场; join():主進(jìn)程阻塞,等待子進(jìn)程的退出涧郊, 必須在 close 或 terminate 之后使用 也可以使用 concurrent.futures 模塊提供的功能來(lái)實(shí)現(xiàn) ```Python def test_future_process(): print('Parent process %s.' % os.getpid()) p = ProcessPoolExecutor(4) for i in range(5): p.submit(long_time_task, i) p.shutdown(wait=True) print('Finish') if __name__ == '__main__': # test_pool() test_future_process() ``` output ```Text Parent process 29368. Run task 0 (32148)... Run task 1 (31552)... Run task 2 (24012)... Run task 3 (29408)... Task 2 runs 0.52 seconds. Run task 4 (24012)... Task 3 runs 0.86 seconds. Task 1 runs 1.81 seconds. Task 0 runs 1.83 seconds. Task 4 runs 1.69 seconds. Finish ``` 多線程 ```Python def sayhello(a): print("hello: " + a) start = time.time() time.sleep(random.random() * 3) end = time.time() print('Task %s runs %0.2f seconds.' % (a, (end - start))) def test_future_thread(): seed = ["a", "b", "c", "d"] start = time.time() with ThreadPoolExecutor(3) as executor: for i in seed: executor.submit(sayhello, i) end = time.time() print("Thread Run Time: " + str(end - start)) ``` output ```Text hello: a hello: b hello: c Task a runs 0.40 seconds. hello: d Task b runs 0.56 seconds. Task d runs 1.70 seconds. Task c runs 2.92 seconds. Thread Run Time: 2.9195945262908936 ``` 可以看出贯被,由于是創(chuàng)建了限制為3的線程池,所以只有三個(gè)任務(wù)在同時(shí)執(zhí)行 ### 110. 進(jìn)程之間如何進(jìn)行通信 ```Python def write(q): print("write(%s), 父進(jìn)程為(%s)" % (os.getpid(), os.getppid())) for i in "Python": print("Put %s to Queue" % i) q.put(i) def read(q): print("read(%s), 父進(jìn)程為(%s)" % (os.getpid(), os.getppid())) for i in range(q.qsize()): print("read 從 Queue 獲取到消息: %s" % q.get(True)) def test_commun(): print("(%s) start" % os.getpid()) q = Manager().Queue() pw = Process(target=write, args=(q, )) pr = Process(target=read, args=(q, )) pw.start() pr.start() pw.join() pr.terminate() ``` output ```Text (23544) start write(29856), 父進(jìn)程為(23544) Put P to Queue Put y to Queue Put t to Queue Put h to Queue Put o to Queue Put n to Queue read(25016), 父進(jìn)程為(23544) read 從 Queue 獲取到消息: P read 從 Queue 獲取到消息: y read 從 Queue 獲取到消息: t read 從 Queue 獲取到消息: h read 從 Queue 獲取到消息: o read 從 Queue 獲取到消息: n ``` Python 的 multiprocessing 模塊包裝了底層的機(jī)制妆艘,提供了 Queue彤灶、Pipes 等多種方式來(lái)交換數(shù)據(jù) ### 111. 進(jìn)程鎖和線程鎖 進(jìn)程鎖:是為了控制同一操作系統(tǒng)中多個(gè)進(jìn)程訪問(wèn)一個(gè)共享資源,只是因?yàn)槌绦虻莫?dú)立性批旺,各個(gè)進(jìn)程是無(wú)法控制其他進(jìn)程對(duì)資源的訪問(wèn)的幌陕,但是可以使用本地系統(tǒng)的信號(hào)量控制。 信號(hào)量(Semaphore)汽煮,有時(shí)被稱為信號(hào)燈搏熄,是在多線程環(huán)境下使用的一種設(shè)施棚唆,是可以用來(lái)保證兩個(gè)或多個(gè)關(guān)鍵代碼段不被并發(fā)調(diào)用 線程鎖:當(dāng)多個(gè)線程幾乎同時(shí)修改一個(gè)共享數(shù)據(jù)的時(shí)候,需要進(jìn)行同步控制搬卒,線程同步能夠保證多個(gè)線程安全的訪問(wèn)競(jìng)爭(zhēng)資源(全局內(nèi)容)瑟俭,最簡(jiǎn)單的同步機(jī)制就是使用互斥鎖。 某個(gè)線程要更改共享數(shù)據(jù)時(shí)契邀,先將其鎖定摆寄,此時(shí)資源的狀態(tài)為鎖定狀態(tài),其他線程就能更改坯门,直到該線程將資源狀態(tài)改為非鎖定狀態(tài)微饥,也就是釋放資源吝岭,其他的線程才能再次鎖定資源啊易。互斥鎖保證了每一次只有一個(gè)線程進(jìn)入寫(xiě)入操作赞季。從而保證了多線程下數(shù)據(jù)的安全性 ### 112. 什么是并發(fā)和并行 并行:多個(gè) CPU 核心现恼,不同的程序就分配給不同的 CPU 來(lái)運(yùn)行肃续。可以讓多個(gè)程序同時(shí)執(zhí)行 并發(fā):?jiǎn)蝹€(gè) CPU 核心叉袍,在一個(gè)時(shí)間切片里一次只能運(yùn)行一個(gè)程序始锚,如果需要運(yùn)行多個(gè)程序,則串行執(zhí)行 ### 113. threading.local 的作用 ThreadLocal 叫做線程本地變量喳逛,ThreadLocal 在每一個(gè)變量中都會(huì)創(chuàng)建一個(gè)副本瞧捌,每個(gè)線程都可以訪問(wèn)自己內(nèi)部的副本變量,對(duì)其他線程時(shí)不可見(jiàn)的润文,修改之后也不會(huì)影響到其他線程 ### 114. 什么是域名解析 域名解析是指將域名解析為 IP 地址姐呐。也有反向的“逆解析”,將 IP 通過(guò) DNS 服務(wù)器查找到對(duì)應(yīng)的域名地址 DNS 是域名系統(tǒng) (Domain Name System)典蝌,域名系統(tǒng)為因特網(wǎng)上的主機(jī)分配域名地址和 IP 地址曙砂。用戶使用域名地址,該系統(tǒng)就會(huì)自動(dòng)把域名地址轉(zhuǎn)為 IP 地址 ### 115. LVS 是什么及作用 LVS 是 Linux Virtual Server 的簡(jiǎn)寫(xiě)赠法,意即 Linux 虛擬服務(wù)器麦轰,是一個(gè)虛擬的服務(wù)器集群系統(tǒng),即負(fù)載均衡服務(wù)器 LVS 工作模式分為 NAT 模式砖织、TUN 模式款侵、以及 DR 模式 ### 116. Nginx 的作用 Nginx 主要功能:1、反向代理 2侧纯、負(fù)載均衡 3新锈、HTTP 服務(wù)器(包含動(dòng)靜分離) 4、正向代理 正向代理:某些情況下眶熬,代理用戶去訪問(wèn)服務(wù)器妹笆,需要手動(dòng)設(shè)置代理服務(wù)器的 IP 和端口號(hào) 反向代理:是用來(lái)代理服務(wù)器的块请,代理要訪問(wèn)的目標(biāo)服務(wù)器。代理服務(wù)器接受請(qǐng)求拳缠,然后將請(qǐng)求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)的服務(wù)器(集群化)墩新,并將從服務(wù)器上得到的結(jié)果返回給客戶端,此時(shí)代理服務(wù)器對(duì)外就表現(xiàn)為一個(gè)服務(wù)器 負(fù)載均衡服務(wù)器類(lèi)似于 LVS HTTP 服務(wù)器類(lèi)似于 Tomcat 等 ### 117. keepalived 及 HAProxy HAProxy 提供高可用性窟坐、負(fù)載均衡海渊,以及基于 TCP 和 HTTP 的應(yīng)用程序代理。 keepalived 是集群管理中保證集群高可用的一個(gè)服務(wù)軟件哲鸳,其功能類(lèi)似于 heartbeat臣疑,用來(lái)防止單點(diǎn)故障 ### 118. 什么是 rpc RPC 是指遠(yuǎn)程過(guò)程調(diào)用,也就是說(shuō)兩臺(tái)服務(wù)器 A徙菠,B讯沈,一個(gè)應(yīng)用部署在 A 服務(wù)器上,想要調(diào)用 B 服務(wù)器上應(yīng)用提供的函數(shù)/方法婿奔,由于不在一個(gè)內(nèi)存空間缺狠,不能直接調(diào)用,需要通過(guò)網(wǎng)絡(luò)來(lái)表達(dá)調(diào)用的語(yǔ)義和傳達(dá)調(diào)用的數(shù)據(jù) ### 119. 從瀏覽器輸入一個(gè)網(wǎng)址到展示網(wǎng)址頁(yè)面的過(guò)程 瀏覽器通過(guò) DNS 服務(wù)器查找到域名對(duì)應(yīng)的 IP 地址 瀏覽器給 IP 對(duì)應(yīng)的 web 服務(wù)器發(fā)送 HTTP 請(qǐng)求 web 服務(wù)器接收到 HTTP 請(qǐng)求后萍摊,返回響應(yīng)給瀏覽器 瀏覽器接收到響應(yīng)后渲染頁(yè)面 ### 120. 什么是cdn CDN 的全稱是 Content Delivery Network儒老,即內(nèi)容分發(fā)網(wǎng)絡(luò)。CDN 是構(gòu)建在網(wǎng)絡(luò)之上的內(nèi)容分發(fā)網(wǎng)絡(luò)记餐,依靠部署在各地的邊緣服務(wù)器,通過(guò)中心平臺(tái)的負(fù)載均衡薇正、內(nèi)容分發(fā)片酝、調(diào)度等功能模塊,使用戶就近獲取所需內(nèi)容挖腰,降低網(wǎng)絡(luò)擁塞雕沿,提高用戶訪問(wèn)響應(yīng)速度和命中率。CDN 的關(guān)鍵技術(shù)主要有內(nèi)容存儲(chǔ)和分發(fā)技術(shù) ## 綜合篇:數(shù)據(jù)庫(kù)和框架 ### 121. 列舉常見(jiàn)的數(shù)據(jù)庫(kù) 關(guān)系型數(shù)據(jù)庫(kù):MySQL猴仑,Oracle审轮,SQLServer,SQLite辽俗,DB2 非關(guān)系型數(shù)據(jù)庫(kù):MongoDB疾渣,Redis,HBase崖飘,Neo4j ### 122. 數(shù)據(jù)庫(kù)設(shè)計(jì)三大范式 建立科學(xué)的榴捡,規(guī)范的的數(shù)據(jù)庫(kù)是需要滿足一些規(guī)范的,以此來(lái)優(yōu)化數(shù)據(jù)數(shù)據(jù)存儲(chǔ)方式朱浴,在關(guān)系型數(shù)據(jù)庫(kù)中這些規(guī)范就可以稱為范式 第一范式:當(dāng)關(guān)系模式 R 的所有屬性都不能在分解為更基本的數(shù)據(jù)單位時(shí)吊圾,稱 R 是滿足第一范式的达椰,簡(jiǎn)記為 1NF 關(guān)系模式R的所有屬性不能再分解 第二范式:如果關(guān)系模式 R 滿足第一范式,并且 R 的所有非主屬性都完全依賴于 R 的每一個(gè)候選關(guān)鍵屬性项乒,稱 R 滿足第二范式啰劲,簡(jiǎn)記為 2NF 非主屬性都要依賴于每一個(gè)關(guān)鍵屬性 三范式:設(shè) R 是一個(gè)滿足第一范式條件的關(guān)系模式,X 是 R 的任意屬性集檀何,如果 X 非傳遞依賴于 R 的任意一個(gè)候選關(guān)鍵字蝇裤,稱 R 滿足第三范式,簡(jiǎn)記為 3NF 數(shù)據(jù)不能存在傳遞關(guān)系埃碱,即每個(gè)屬性都跟主鍵有直接關(guān)系而不是間接關(guān)系 ### 123. 什么是數(shù)據(jù)庫(kù)事務(wù) 事務(wù)(Transaction)是并發(fā)控制的基本單位猖辫。所謂的事務(wù),它是一個(gè)操作序列砚殿,這些操作要么都執(zhí)行啃憎,要么都不執(zhí)行,它是一個(gè)不可分割的工作單位 在關(guān)系數(shù)據(jù)庫(kù)中,一個(gè)事務(wù)可以是一條 SQL 語(yǔ)句似炎、一組 SQL 語(yǔ)句或整個(gè)程序辛萍。 四個(gè)屬性:原子性,一致性羡藐,隔離性和持久性 ### 124. MySQL 索引種類(lèi) MySQL 目前主要有以下幾種索引類(lèi)型: - 普通索引 - 唯一索引 - 主鍵索引 - 組合索引 - 全文索引 ### 125. 數(shù)據(jù)庫(kù)設(shè)計(jì)中一對(duì)多和多對(duì)多的應(yīng)用場(chǎng)景 一對(duì)一關(guān)系示例: 一個(gè)學(xué)生對(duì)應(yīng)一個(gè)學(xué)生檔案材料贩毕,或者每個(gè)人都有唯一的身份證編號(hào) 一對(duì)多關(guān)系示例: 一個(gè)學(xué)生只屬于一個(gè)班,但是一個(gè)班級(jí)有多名學(xué)生 多對(duì)多關(guān)系示例: 一個(gè)學(xué)生可以選擇多門(mén)課仆嗦,一門(mén)課也有多名學(xué)生 ### 126. 簡(jiǎn)述觸發(fā)器辉阶、函數(shù)、視圖瘩扼、存儲(chǔ)過(guò)程 觸發(fā)器:觸發(fā)器是一個(gè)特殊的存儲(chǔ)過(guò)程谆甜,它是數(shù)據(jù)庫(kù)在 insert、update集绰、delete 的時(shí)候自動(dòng)執(zhí)行的代碼塊 函數(shù):數(shù)據(jù)庫(kù)中提供了許多內(nèi)置函數(shù)规辱,還可以自定義函數(shù),實(shí)現(xiàn) sql 邏輯 視圖:視圖是由查詢結(jié)果形成的一張?zhí)摂M表栽燕,是表通過(guò)某種運(yùn)算得到的一個(gè)投影 存儲(chǔ)過(guò)程:把一段代碼封裝起來(lái)罕袋,當(dāng)要執(zhí)行這一段代碼的時(shí)候,可以通過(guò)調(diào)用該存儲(chǔ)過(guò)程來(lái)實(shí)現(xiàn)(經(jīng)過(guò)第一次編譯后再次調(diào)用不需要再次編譯碍岔,比一個(gè)個(gè)執(zhí)行 sql 語(yǔ)句效率高) ### 127. 常用 SQL 語(yǔ)句 DML(數(shù)據(jù)操作語(yǔ)言) - SELECT - 從數(shù)據(jù)庫(kù)表中獲取數(shù)據(jù) - UPDATE - 更新數(shù)據(jù)庫(kù)表中的數(shù)據(jù) - DELETE - 從數(shù)據(jù)庫(kù)表中刪除數(shù)據(jù) - INSERT INTO - 向數(shù)據(jù)庫(kù)表中插入數(shù)據(jù) DDL(數(shù)據(jù)定義語(yǔ)言) - CREATE DATABASE - 創(chuàng)建新數(shù)據(jù)庫(kù) - ALTER DATABASE - 修改數(shù)據(jù)庫(kù) - CREATE TABLE - 創(chuàng)建新表 - ALTER TABLE - 變更(改變)數(shù)據(jù)庫(kù)表 - DROP TABLE - 刪除表 - CREATE INDEX - 創(chuàng)建索引(搜索鍵) - DROP INDEX - 刪除索引 ### 128. 主鍵和外鍵的區(qū)別 定義主鍵和外鍵主要是為了維護(hù)關(guān)系數(shù)據(jù)庫(kù)的完整性 主鍵是能確定一條記錄的唯一標(biāo)識(shí)浴讯。不能重復(fù),不允許為空 外鍵用于與另一張表關(guān)聯(lián)蔼啦。是能確定另一張表記錄的字段兰珍,用于保持?jǐn)?shù)據(jù)的一致性 主鍵外鍵索引定義唯一標(biāo)識(shí)一條記錄,不能重復(fù)询吴,不允許為空表的外鍵是另一表的主鍵掠河,外鍵可以重復(fù)亮元,可以是空值該字段沒(méi)有重復(fù)值,但可以有空值作用用來(lái)保證數(shù)據(jù)完整性用來(lái)和其他表建立聯(lián)系提高查詢排序的速度個(gè)數(shù)只能有一個(gè)可有多個(gè)可有多個(gè) ### 129. 如何開(kāi)啟 MySQL 慢日志查詢 修改配置文件唠摹,然后重啟服務(wù)生效 在linux下爆捞,vim /etc/my.cnf,在[mysqld]內(nèi)容項(xiàng)下增加: slow_query_log = ON long_query_time = 2 # 查詢超過(guò)2秒的就會(huì)記錄 命令行勾拉,但是重啟服務(wù)后會(huì)失效 SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2; ### 130. MySQL 數(shù)據(jù)庫(kù)備份命令 mysqldump -u 用戶名 -p 數(shù)據(jù)庫(kù)名 > 導(dǎo)出的文件名 ### 131. char 和 varchar 的區(qū)別 char:存儲(chǔ)定長(zhǎng)數(shù)據(jù)很方便煮甥,CHAR 字段上的索引效率級(jí)高,必須在括號(hào)里定義長(zhǎng)度藕赞,可以有默認(rèn)值成肘,比如定義 char(10) varchar:存儲(chǔ)變長(zhǎng)數(shù)據(jù),但存儲(chǔ)效率沒(méi)有 CHAR 高斧蜕,必須在括號(hào)里定義長(zhǎng)度双霍,可以有默認(rèn)值 ### 132. 最左前綴原則 mysql 建立多列索引(聯(lián)合索引)有最左前綴的原則,即最左優(yōu)先批销,如: 如果有一個(gè)2列的索引(col1,col2),則已經(jīng)對(duì)(col1)洒闸、(col1,col2)上建立了索引 如果有一個(gè)3列索引(col1,col2,col3),則已經(jīng)對(duì)(col1)均芽、(col1,col2)丘逸、(col1,col2,col3)上建立了索引 ### 133. 無(wú)法命中索引的情況 使用or關(guān)鍵字會(huì)導(dǎo)致無(wú)法命中索引 左前導(dǎo)查詢會(huì)導(dǎo)致無(wú)法命中索引,如 like '%a' 或者 like '%a%' 單列索引的索引列為 null 時(shí)全值匹配會(huì)使索引失效掀宋,組合索引全為 null 時(shí)索引失效 組合索引不符合左前綴原則的列無(wú)法命中索引深纲,如我們有4個(gè)列 a、b劲妙、c囤萤、d,我們創(chuàng)建一個(gè)組合索引 INDEX(a,b,c,d)是趴,那么能命中索引的查詢?yōu)?a,ab澄惊,abc唆途,abcd,除此之外都無(wú)法命中索引 強(qiáng)制類(lèi)型轉(zhuǎn)換會(huì)導(dǎo)致索引失效 負(fù)向查詢條件會(huì)導(dǎo)致無(wú)法使用索引掸驱,比如 NOT IN,NOT LIKE,!= 等 如果 mysql 估計(jì)使用全表掃描要比使用索引快肛搬,則不使用索引 ### 134. 數(shù)據(jù)庫(kù)讀寫(xiě)分離 讀寫(xiě)分離,就是將數(shù)據(jù)庫(kù)分為了主從庫(kù)毕贼,一個(gè)主庫(kù)用于寫(xiě)數(shù)據(jù)温赔,多個(gè)從庫(kù)完成讀數(shù)據(jù)的操作,主從庫(kù)之間通過(guò)某種機(jī)制進(jìn)行數(shù)據(jù)的同步鬼癣,是一種常見(jiàn)的數(shù)據(jù)庫(kù)架構(gòu) ### 135. 數(shù)據(jù)庫(kù)分庫(kù)分表 數(shù)據(jù)庫(kù)水平切分陶贼,是一種常見(jiàn)的數(shù)據(jù)庫(kù)架構(gòu)啤贩,是一種通過(guò)算法,將數(shù)據(jù)庫(kù)進(jìn)行分割的架構(gòu)拜秧。一個(gè)水平切分集群中的每個(gè)數(shù)據(jù)庫(kù)痹屹,通常稱為一個(gè)“分片”。每一個(gè)分片中的數(shù)據(jù)沒(méi)有重合枉氮,所有分片中的數(shù)據(jù)并集組成全部數(shù)據(jù)志衍。 水平切分分為庫(kù)內(nèi)分表和分庫(kù)分表,是根據(jù)表內(nèi)數(shù)據(jù)內(nèi)在的邏輯關(guān)系聊替,將同一個(gè)表按不同的條件分散到多個(gè)數(shù)據(jù)庫(kù)或多個(gè)表中楼肪,每個(gè)表中只包含一部分?jǐn)?shù)據(jù),從而使得單個(gè)表的數(shù)據(jù)量變小惹悄,達(dá)到分布式的效果 ### 136. redis 和 memcached 比較 redis 和 memcached 都是將數(shù)據(jù)存放在內(nèi)存中春叫,都是內(nèi)存數(shù)據(jù)庫(kù)。不過(guò) memcached 還可用于緩存其他東西俘侠,例如圖片象缀、視頻等等 redis 不僅僅支持簡(jiǎn)單的 k/v 類(lèi)型的數(shù)據(jù),同時(shí)還提供 list爷速,set央星,hash 等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ) 分布式設(shè)定, 都可以做一主多從或一主一從 存儲(chǔ)數(shù)據(jù)安全惫东,memcached 掛掉后莉给,數(shù)據(jù)完全丟失;redis 可以定期保存到磁盤(pán)(持久化) 災(zāi)難恢復(fù)廉沮,memcached 掛掉后颓遏,數(shù)據(jù)不可恢復(fù); redis 數(shù)據(jù)丟失后可以通過(guò) aof 恢復(fù) ### 137. redis中數(shù)據(jù)庫(kù)默認(rèn)是多少個(gè) db 及作用 redis 默認(rèn)有16個(gè)數(shù)據(jù)庫(kù),每個(gè)數(shù)據(jù)庫(kù)中的數(shù)據(jù)都是隔離的滞时,這樣叁幢,在存儲(chǔ)數(shù)據(jù)的時(shí)候,就可以指定把不同的數(shù)據(jù)存儲(chǔ)到不同的數(shù)據(jù)庫(kù)中坪稽。 且只有單機(jī)才有曼玩,如果是集群就沒(méi)有數(shù)據(jù)庫(kù)的概念 ### 138. redis 有哪幾種持久化策略 RDB 持久化:是將 Reids 在內(nèi)存中的數(shù)據(jù)庫(kù)記錄定時(shí) dump 到磁盤(pán)上的持久化 AOF(append only file)持久化:將 Reids 的操作日志以追加的方式寫(xiě)入文件 ### 139. redis 支持的過(guò)期策略 通用的三種過(guò)期策略 定時(shí)刪除 在設(shè)置 key 的過(guò)期時(shí)間的同時(shí),為該 key 創(chuàng)建一個(gè)定時(shí)器窒百,讓定時(shí)器在 key 的過(guò)期時(shí)間來(lái)臨時(shí)黍判,對(duì) key 進(jìn)行刪除 惰性刪除 key 過(guò)期的時(shí)候不刪除,每次從數(shù)據(jù)庫(kù)獲取 key 的時(shí)候去檢查是否過(guò)期篙梢,若過(guò)期顷帖,則刪除,返回 null 定期刪除 每隔一段時(shí)間執(zhí)行一次刪除過(guò)期 key 操作 redis 采用惰性刪除+定期刪除策略 ### 140. 如何保證 redis 中的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù) 限定 Redis 占用的內(nèi)存,Redis 會(huì)根據(jù)自身數(shù)據(jù)淘汰策略贬墩,加載熱數(shù)據(jù)到內(nèi)存榴嗅。 所以,計(jì)算一下所有熱點(diǎn)數(shù)據(jù)大約占用的內(nèi)存震糖,然后設(shè)置一下 Redis 內(nèi)存限制即可 ### 141. Python 操作 redis 使用 redis 第三方庫(kù)來(lái)操作 ```Python import redis # 創(chuàng)建一個(gè) redis 連接池 def redis_conn_pool(): pool = redis.ConnectionPool(host='redis-host', port=redis-port, decode_responses=True, password='redis-pwd') r = redis.Redis(connection_pool=pool) return r ``` ### 142. 基于 redis 實(shí)現(xiàn)發(fā)布和訂閱 訂閱者 ```Python if __name__ == "__main__": conn = redis.Redis(host='', port=12143, password='') ps = conn.pubsub() ps.subscribe('chat') # 從 chat 訂閱消息 for item in ps.listen(): # 監(jiān)聽(tīng)狀態(tài):有消息發(fā)布了就拿過(guò)來(lái) if item['type'] == 'message': print(item) print(item['channel']) print(item['data']) ``` 發(fā)布者 ```Python if __name__ == "__main__": number_list = ['300033', '300032', '300031', '300030'] signal = ['1', '-1', '1', '-1'] pool = redis.ConnectionPool(host='redis-12143.c8.us-east-1-3.ec2.cloud.redislabs.com', port=12143, decode_responses=True, password='pkAWNdYWfbLLfNOfxTJinm9SO16eSJFx') r = redis.Redis(connection_pool=pool) for i in range(len(number_list)): value_new = str(number_list[i]) + ' ' + str(signal[i]) print(value_new) r.publish("chat", value_new) ``` ### 143. 如何高效的找到 redis 中的某個(gè) KEY ```Python import redis con = redis.Redis() con.keys(pattern='key*') # *代表通配符 ``` ### 144. 基于 redis 實(shí)現(xiàn)先進(jìn)先出录肯、后進(jìn)先出及優(yōu)先級(jí)隊(duì)列 ```Python class Zhan: def __init__(self,conn): self.conn = conn def push(self,val): self.conn.rpush('aaa',val) def pop(self): return self.conn.rpop('aaa') class Dui: def __init__(self,conn): self.conn = conn def push(self,val): self.conn.rpush('bbb',val) def get(self): return self.conn.lpop('bbb') class Xu: def __init__(self,conn): self.conn = conn def push(self,val,count): self.conn.zadd('ccc',val,count) def get(self): a = self.conn.zrange('ccc', 0, 0)[0] self.conn.zrem('ccc', a) return a ``` ### 145. redis 如何實(shí)現(xiàn)主從復(fù)制 在從服務(wù)器中配置 SLAVEOF 127.0.0.1 6380 # 主服務(wù)器 IP,端口 ### 146. 循環(huán)獲取 redis 中某個(gè)非常大的列表數(shù)據(jù) ```python def list_iter(name): """ 自定義redis列表增量迭代 :param name: redis中的name吊说,即:迭代name對(duì)應(yīng)的列表 :return: yield 返回 列表元素 """ list_count = r.llen(name) for index in xrange(list_count): yield r.lindex(name, index) ``` ### 147. redis 中的 watch 的命令的作用 watch 用于在進(jìn)行事務(wù)操作的最后一步也就是在執(zhí)行 exec 之前對(duì)某個(gè) key 進(jìn)行監(jiān)視论咏,如果這個(gè)被監(jiān)視的 key 被改動(dòng),那么事務(wù)就被取消颁井,否則事務(wù)正常執(zhí)行 ### 148. redis 分布式鎖 為 redis 集群設(shè)計(jì)的鎖厅贪,防止多個(gè)任務(wù)同時(shí)修改數(shù)據(jù)庫(kù),其本質(zhì)就是為集群中的每個(gè)主機(jī)設(shè)置一個(gè)會(huì)超時(shí)的字符串雅宾,當(dāng)集群中有一半多的機(jī)器設(shè)置成功后就認(rèn)為加鎖成功养涮,直至鎖過(guò)期或解鎖不會(huì)有第二個(gè)任務(wù)加鎖成功 ### 149. http 協(xié)議 超文本傳輸協(xié)議(HTTP,HyperText Transfer Protocol)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議眉抬。HTTP 是一個(gè)客戶端和服務(wù)器端請(qǐng)求和應(yīng)答的標(biāo)準(zhǔn)贯吓。客戶端是終端用戶蜀变,服務(wù)器端是網(wǎng)站悄谐。一般由 HTTP 客戶端發(fā)起一個(gè)請(qǐng)求,建立一個(gè)到服務(wù)器指定端口(默認(rèn)是80端口)的 TCP 連接库北,HTTP 服務(wù)器則在那個(gè)端口監(jiān)聽(tīng)客戶端發(fā)送過(guò)來(lái)的請(qǐng)求爬舰,并給與響應(yīng) ### 150. uwsgi,uWSGI 和 WSGI 的區(qū)別 WSGI:全稱是 Web Server Gateway Interface寒瓦,是一種描述 web server 如何與 web application 通信的規(guī)范情屹。django,flask 等都遵循該協(xié)議 uwsgi:是服務(wù)器和服務(wù)端應(yīng)用程序的一種協(xié)議杂腰,規(guī)定了怎么把請(qǐng)求轉(zhuǎn)發(fā)給應(yīng)用程序和返回; uwsgi 是一種線路協(xié)議而不是通信協(xié)議垃你,在此常用于在 uWSGI 服務(wù)器與其他網(wǎng)絡(luò)服務(wù)器的數(shù)據(jù)通信 uWSGI:是一個(gè) Web 服務(wù)器,它實(shí)現(xiàn)了 WSGI 協(xié)議喂很、uwsgi惜颇、http 等協(xié)議。Nginx 中 HttpUwsgiModule 的作用是與 uWSGI 服務(wù)器進(jìn)行交換 ### 151. HTTP 狀態(tài)碼 1xx: 信息 2xx:成功 3xx:重定向 4xx:客戶端錯(cuò)誤 5xx:服務(wù)器錯(cuò)誤 ### 152. HTTP常見(jiàn)請(qǐng)求方式 GET恤筛,POST,PUT芹橡,DELETE毒坛,PATCH 等 ### 153. 響應(yīng)式布局 響應(yīng)式布局是 Ethan Marcotte 在2010年5月份提出的一個(gè)概念,簡(jiǎn)而言之,就是一個(gè)網(wǎng)站能夠兼容多個(gè)終端——而不是為每個(gè)終端做一個(gè)特定的版本 ### 154. 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 AJAX 請(qǐng)求 AJAX 是一種在無(wú)需重新加載整個(gè)網(wǎng)頁(yè)的情況下煎殷,能夠更新部分網(wǎng)頁(yè)的技術(shù)屯伞。 AJAX = 異步 JavaScript 和 XML ```JavaScript $(function(){ $('#send').click(function(){ $.ajax({ type: "GET", url: "test.json", data: {username:$("#username").val(), content:$("#content").val()}, dataType: "json", success: function(data){ $('#resText').empty(); //清空resText里面的所有內(nèi)容 var html = ''; $.each(data, function(commentIndex, comment){ html += '
' + comment['username'] + ':

'; }); $('#resText').html(html); } }); }); }); ``` ### 155. 同源策略 同源策略限制了從同一個(gè)源加載的文檔或腳本如何與來(lái)自另一個(gè)源的資源進(jìn)行交互。這是一個(gè)用于隔離潛在惡意文件的重要安全機(jī)制 如果兩個(gè)頁(yè)面的協(xié)議豪直,端口(如果有指定)和主機(jī)都相同劣摇,則兩個(gè)頁(yè)面具有相同的源。我們也可以把它稱為“協(xié)議/主機(jī)/端口 tuple”弓乙,或簡(jiǎn)單地叫做“tuple". ("tuple" 末融,“元”,是指一些事物組合在一起形成一個(gè)整體暇韧,比如(1勾习,2)叫二元,(1懈玻,2巧婶,3)叫三元) ### 156. 什么是 CORS CORS 全稱是跨域資源共享(Cross-Origin Resource Sharing),是一種 AJAX 跨域請(qǐng)求資源的方式涂乌,支持現(xiàn)代瀏覽器 ### 157. 什么是 CSRF CSRF(Cross-site request forgery)艺栈,中文名稱:跨站請(qǐng)求偽造,也被稱為:one click attack/session riding湾盒,縮寫(xiě)為:CSRF/XSRF ### 158. 前端實(shí)現(xiàn)輪詢湿右、長(zhǎng)輪詢 輪詢 ```JavaScript var xhr = new XMLHttpRequest(); setInterval(function(){ xhr.open('GET','/user'); xhr.onreadystatechange = function(){ }; xhr.send(); },1000) ``` 長(zhǎng)輪詢 ```JavaScript function ajax(){ var xhr = new XMLHttpRequest(); xhr.open('GET','/user'); xhr.onreadystatechange = function(){ ajax(); }; xhr.send(); } ``` ### 159. 簡(jiǎn)述 MVC 和 MTV 所謂 MVC 就是把 web 應(yīng)用分為模型(M),控制器(C)历涝,視圖(V)三層诅需,他們之間以一種插件似的,松耦合的方式連接在一起荧库。 模型負(fù)責(zé)業(yè)務(wù)對(duì)象與數(shù)據(jù)庫(kù)的對(duì)象(ORM)堰塌,視圖負(fù)責(zé)與用戶的交互(頁(yè)面),控制器(C)接受用戶的輸入調(diào)用模型和視圖完成用戶的請(qǐng)求 Django 中的 MTV 模式: Model(模型):負(fù)責(zé)業(yè)務(wù)對(duì)象與數(shù)據(jù)庫(kù)的對(duì)象(ORM) Template(模版):負(fù)責(zé)如何把頁(yè)面展示給用戶 View(視圖):負(fù)責(zé)業(yè)務(wù)邏輯分衫,并在適當(dāng)?shù)臅r(shí)候調(diào)用 Model 和 Template场刑,本質(zhì)上與 MVC 相同 ### 160. 接口的冪等性 接口冪等性就是用戶對(duì)于同一操作發(fā)起的一次請(qǐng)求或者多次請(qǐng)求的結(jié)果是一致的,不會(huì)因?yàn)槎啻吸c(diǎn)擊而產(chǎn)生了副作用 ### 161. Flask 框架的優(yōu)勢(shì) 簡(jiǎn)潔蚪战,輕巧牵现,擴(kuò)展性強(qiáng),自由度高 ### 162. 什么是 ORM ORM 的全稱是 Object Relational Mapping邀桑,即對(duì)象關(guān)系映射瞎疼。它的實(shí)現(xiàn)思想就是將關(guān)系數(shù)據(jù)庫(kù)中表的數(shù)據(jù)映射成為對(duì)象,以對(duì)象的形式展現(xiàn)壁畸,這樣開(kāi)發(fā)人員就可以把對(duì)數(shù)據(jù)庫(kù)的操作轉(zhuǎn)化為對(duì)這些對(duì)象的操作 ### 163. PV贼急、UV 的含義 PV:是(page view)訪問(wèn)量茅茂,頁(yè)面瀏覽量或點(diǎn)擊量,衡量網(wǎng)站用戶訪問(wèn)的網(wǎng)頁(yè)數(shù)量太抓。在一定統(tǒng)計(jì)周期內(nèi)用戶每打開(kāi)或刷新一個(gè)頁(yè)面就記錄1次空闲,多次打開(kāi)或刷新同一頁(yè)面則瀏覽量累計(jì) UV:是(Unique Visitor)獨(dú)立訪客,統(tǒng)計(jì)一段時(shí)間內(nèi)訪問(wèn)某站點(diǎn)的用戶數(shù)(以cookie為依據(jù)) ### 164. supervisor 的作用 supervisor 管理進(jìn)程走敌,是通過(guò) fork/exec 的方式將這些被管理的進(jìn)程當(dāng)作 supervisor 的子進(jìn)程來(lái)啟動(dòng)碴倾,所以我們只需要將要管理進(jìn)程的可執(zhí)行文件的路徑添加到 supervisor 的配置文件中即可 ### 165. 使用 ORM 和原生 SQL 的優(yōu)缺點(diǎn) 優(yōu)點(diǎn): - 方便的使用面向?qū)ο螅Z(yǔ)句清晰 - 有效的防止 SQL 注入 - 方便動(dòng)態(tài)構(gòu)造語(yǔ)句掉丽,對(duì)于不同的表的相同操作采用多態(tài)實(shí)現(xiàn)更優(yōu)雅跌榔; - 一定程度上方便重構(gòu)數(shù)據(jù)層 - 方便設(shè)置設(shè)置鉤子函數(shù) 缺點(diǎn): - 不太容易處理復(fù)雜查詢語(yǔ)句 - 性能較直接用 SQL 差 ### 166. 列舉一些 django 的內(nèi)置組件 Admin 組件:是對(duì) model 中對(duì)應(yīng)的數(shù)據(jù)表進(jìn)行增刪改查提供的組件 model 組件:負(fù)責(zé)操作數(shù)據(jù)庫(kù) form 組件:生成 HTML 代碼;數(shù)據(jù)有效性校驗(yàn)机打;校驗(yàn)信息返回并展示 ModelForm 組件:用于數(shù)據(jù)庫(kù)操作矫户,也可用于用戶請(qǐng)求的驗(yàn)證 ### 167. 列舉 Django 中執(zhí)行原生 sql 的方法 使用 execute 執(zhí)行自定義的 SQL 直接執(zhí)行 SQL 語(yǔ)句(類(lèi)似于 pymysql 的用法) ```Python from django.db import connection cursor = connection.cursor() cursor.execute("SELECT DATE_FORMAT(create_time, '%Y-%m') FROM blog_article;") ret = cursor.fetchall() print(ret) ``` - 使用 extra 方法:queryset.extra(select={"key": "原生的SQL語(yǔ)句"}) - 使用 raw 方法 - 執(zhí)行原始 sql 并返回模型 - 依賴于 model 模型,多用于查詢操作 ### 168. cookie 和 session 的區(qū)別 cookie 是保存在瀏覽器端的鍵值對(duì)残邀,可以用來(lái)做用戶認(rèn)證 sesseion 是將用戶的會(huì)話信息保存在服務(wù)端皆辽,key 值是隨機(jī)產(chǎn)生的字符串,value 值是 session 的內(nèi)容芥挣,依賴于 cookie 將每個(gè)用戶的隨機(jī)字符串保存到用戶瀏覽器中 ### 169. beautifulsoup 模塊的作用 BeautifulSoup 庫(kù)是解析驱闷、遍歷、維護(hù)“標(biāo)簽樹(shù)”的功能庫(kù) ```Python url = "http://www.baidu.com/" request = requests.get(url) html = request.content soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8") ``` ### 170. Selenium 模塊簡(jiǎn)述 Selenium 是模擬操作瀏覽器的庫(kù)空免,可以根據(jù)我們的指令空另,讓瀏覽器自動(dòng)加載頁(yè)面,獲取需要的數(shù)據(jù)蹋砚,甚至頁(yè)面截屏扼菠,或者判斷網(wǎng)站上某些動(dòng)作是否發(fā)生等 ```Python from selenium import webdriver browser = webdriver.Chrome() browser.get('https://www.taobao.com') print(browser.page_source) # browser.page_source 是獲取網(wǎng)頁(yè)的全部 html browser.close() ``` 好了,這就是今天分享的全部?jī)?nèi)容坝咐,如果喜歡就點(diǎn)個(gè)贊吧~ 后臺(tái)回復(fù)“面試題”獲取完整PDF版本 本文由[mdnice](https://mdnice.com/?platform=6)多平臺(tái)發(fā)布
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末循榆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子墨坚,更是在濱河造成了極大的恐慌秧饮,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泽篮,死亡現(xiàn)場(chǎng)離奇詭異盗尸,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)帽撑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)泼各,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人亏拉,你說(shuō)我怎么就攤上這事扣蜻〈绨” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵弱贼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我磷蛹,道長(zhǎng)吮旅,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任味咳,我火速辦了婚禮庇勃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘槽驶。我一直安慰自己责嚷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布掂铐。 她就那樣靜靜地躺著罕拂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪全陨。 梳的紋絲不亂的頭發(fā)上爆班,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音辱姨,去河邊找鬼柿菩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛雨涛,可吹牛的內(nèi)容都是我干的枢舶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼替久,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼凉泄!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起侣肄,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤旧困,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后稼锅,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體吼具,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年矩距,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拗盒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锥债,死狀恐怖陡蝇,靈堂內(nèi)的尸體忽然破棺而出痊臭,到底是詐尸還是另有隱情,我是刑警寧澤登夫,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布广匙,位于F島的核電站,受9級(jí)特大地震影響恼策,放射性物質(zhì)發(fā)生泄漏鸦致。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一涣楷、第九天 我趴在偏房一處隱蔽的房頂上張望分唾。 院中可真熱鬧,春花似錦狮斗、人聲如沸绽乔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)折砸。三九已至,卻和暖如春沙峻,著一層夾襖步出監(jiān)牢的瞬間鞍爱,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工专酗, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留睹逃,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓祷肯,卻偏偏與公主長(zhǎng)得像沉填,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子佑笋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容