Python 面試題_未完

基礎部分

1. 爲何學習Python

家裏有在這個IT圈子裏面,也想讓我接觸這個圈子,而後給我建議學的Python,
而後本身經過百度和向有學過Python的同窗瞭解了Python,Python這門語言,入門比較簡單,
它簡單易學,生態圈比較強大,涉及的地方比較多,特別是在人工智能,和數據分析這方面。
在將來我以爲是往自動化,人工智能這方面發展的,因此學習了Python

balabala.....

2. 經過什麼途徑學習Python

剛開始接觸Python的時候,到網上裏面跟着視頻學基礎,
再後來網上到看技術貼,而後看到有人推薦廖雪峯的Python教程, 練項目到GitHub上面找一些小項目學習

balabala....

3. 談談對Python和其餘語言的區別

Python VS java 
  python
    動態強類型,定義無需聲明類型,崇尚鴨子類型
  java
    靜態強類型,定義必需要聲明定義類型

Python VS PHP
  PHP 弱類型 面向web
  Python 強類型 面向對象
Python VS C
  Python 壓倒性的代碼簡潔程度,縮進的使用。
  C 大量的修飾詞以及括號,代碼量龐大

4. Python的優點

簡易 :代碼簡單,易懂,易學
開源 可移植性強大

便於移植 :無需再次編譯
編程方式多樣 :函數編程,面向對象編程都支持 可擴展性和可嵌入性強大 豐富的庫

動態類型 : 鴨子類型所以更加方便類型選擇

5. python語言的缺點

運行速度比較C較弱

不能加密 : 開源性限制

構架選擇太多: 沒有官方框架

GIL : 全局解釋器鎖致使沒有多線程

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

解釋型:就是邊解釋邊執行
執行速度快、效率高;依賴編譯器、跨平臺性差些。如C、C++、Delphi、Pascal,Fortran

編譯型:編譯後再執行
執行速度慢、效率低;依賴解釋器、跨平臺性好。如Tcl、Perl、Ruby、VBScript、 JavaScript

7. Python的解釋器種類以及相關特色?

CPython
官方版本的解釋器:CPython。C語言 ,命令行下運行python就是啓動CPython解釋器。
CPython是使用最廣的Python解釋器。教程的全部代碼也都在CPython下執行。

IPython
IPython是基於CPython之上的一個交互式解釋器,
IPython只是在交互方式上有所加強,可是執行Python代碼的功能和CPython是徹底同樣的。

標識:
CPython用
>>>做爲提示符,而IPython用In [序號]:做爲提示符。

PyPy
由Python寫的解釋器,執行速度最快。
PyPy採用JIT技術,對Python代碼進行動態編譯(注意不是解釋),
絕大部分Python代碼均可以在PyPy下運行,可是PyPy和CPython有一些是不一樣的,這就致使相同的Python代碼在兩種解釋器下執行可能會有不一樣的結果。

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

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

取捨:
使用最普遍的仍是CPython。若是要和Java或.Net平臺交互,最好的辦法不是用Jython或IronPython,而是經過網絡調用來交互,確保各程序之間的獨立性。

8. 位和字節的關係

1字節 = 8 位
位(bit),數據存儲是以「字節」(Byte)爲單位,數據傳輸是以大可能是以「位」(bit,又名「比特」)爲單位,
一個位就表明一個0或1(即一個二進制),二進制是構成存儲器的最小單位,每8個位(bit,簡寫爲b)組成一個字節(Byte,簡寫爲B),
字節是最小一級的信息單位

9. b、B、KB、MB、GB的關係

b --->位(bit)    

B --->字節      一個字節等於8位

1B = 8 bit

1kb = 1024 B

1 MB = 1024 KB

1 GB = 1024 MB

10. PE8規範

1、使用4個空格而不是tab鍵進行縮進。
2、每行長度不能超過79
3、使用空行來間隔函數和類,以及函數內部的大塊代碼
4、必要時候,在每一行下寫註釋
5、使用文檔註釋,寫出函數註釋
6、在操做符和逗號以後使用空格,可是不要在括號內部使用
7、命名類和函數的時候使用一致的方式,好比使用CamelCase來命名類,
           使用lower_case_with_underscores來命名函數和方法
8、在類中老是使用self來做爲默認
9、儘可能不要使用魔法方法
十、默認使用UTF-8,甚至ASCII做爲編碼方式
11、換行可使用反斜槓,最好使用圓括號。
12、不要在一句import中多個庫,

空格的使用   1. 各類右括號前不要加空格。   2. 逗號、冒號、分號前不要加空格。   3. 函數的左括號前不要加空格。如Func(
1)   4. 序列的左括號前不要加空格。如list[2]   5. 操做符左右各加一個空格,不要爲了對齊增長空格   6. 函數默認參數使用的賦值符左右省略空格   7. 不要將多句語句寫在同一行,儘管使用‘;’容許

if/for/while語句中,即便執行語句只有一句,也必須另起一行 函數命名使用所有小寫的方式,常量命名使用大寫,類屬性(方法和變量)使用小寫 類的命名首字母大寫

11. 進制轉換

# 二進制轉換成十進制-->int
v = "0b1111011"
b = int(v,2)
print(b)  # 123


# 十進制轉換成二進制--->bin
v2 = 18
print(bin(int(v2)))
# 0b10010

# 八進制轉換成十進制
v3 = "011"
print(int(v3))
# 11

# 十進制轉換成八進制:---> oct
v4 = 30
print(oct(int(v4)))
# 0o36

# 十六進制轉換成十進制:
v5 = "0x12"
print(int(v5,16))
# 18

# 十進制轉換成十六進制:---> hex
v6 = 87
print(hex(int(v6)))
# 0x57

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

"""
請編寫一個函數實現將IP地址轉換成一個整數。
如 10.3.9.12 轉換規則爲:
        10            00001010

         3            00000011

         9            00001001

        12            00001100

再將以上二進制拼接起來計算十進制結果:00001010 00000011 00001001 00001100 = ?
"""

def v1(addr):
    # 取每一個數
    id = [int(x) for x in addr.split(".")]
    print(id)
    return sum(id[i] << [24, 16, 8, 0][i] for i in range(4))

print(v1("127.0.0.1"))

# [127, 0, 0, 1]
# 2130706433

13. python遞歸的最大層數?

998

視狀況而定,機器性能好的話也能夠超出此上限

14. 求結果(and or or)

1. 求結果:1 or 3
print(1 or 3)  # 1

2. 求結果:1 and 3
print(1 and 3)  # 3

3. 求結果:0 and 2 and 1
print(0 and 2 and 1)  # 0

4. 求結果:0 and 2 or 1
print(0 and 2 or 1)  # 1

5. 求結果:0 and 2 or 1 or 4
print(0 and 2 or 1 or 4)  # 1

6. 求結果:0 or Flase and 1
print(0 or False and 1)  # Flase

總結:
  # x or y 若是 x爲真,則值爲x,   不然爲y
  # x and y 若是 x 爲真,則值爲 y,不然爲 x
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
and:先後爲真才爲真
or:有一爲真就爲真
優先級:()>not>and>or 
同等優先級下,從左向右

15 運算符

1. 求結果:2 & 5

print(2 & 5)  # 10 & 101 => 000 => 0

2. 求結果:2 ^ 5

print(2 ^ 5)  # 10 ^ 101 => 111 => 1*2**0+1*2**1+1*2**2=1+2+4=7

16 . ascii、unicode、utf-八、gbk 區別

python2 默認 ascii
python3 默認 utf-8
ascii 最多隻能用8位來表示(一個字節),即:
2**8 = 256,因此,ASCII碼最多隻能表示 256 個符號。 unicode 萬國碼,任何一個字符==兩個字節 utf-8 萬國碼的升級版 一箇中文字符==三個字節 英文是一個字節 歐洲的是 2個字節 gbk 國內版本 一箇中文字符==2個字節 英文是一個字節
gbk 轉 utf
-8 需經過媒介 unicode

17. 字節碼和機器碼的區別

什麼是機器碼

機器碼(machine code),學名機器語言指令,有時也被稱爲原生碼(Native Code),是電腦的CPU可直接解讀的數據。
一般意義上來理解的話,機器碼就是計算機能夠直接執行,而且執行速度最快的代碼。

總結:機器碼是電腦CPU直接讀取運行的機器指令,運行速度最快,可是很是晦澀難懂,也比較難編寫

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

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

18. 簡述變量命名規範

  #一、以字母,數字,下劃線任由結合
  #二、不能以命名太長,不使用拼音,中文
  #三、不能以數字開頭
  #四、不能用關鍵詞

19. is 和 == 的區別

#is  比較的是內存地址
#== 比較的是值

is 比較的是兩個實例對象是否是徹底相同,它們是否是同一個對象,佔用的內存地址是否相同。

== 比較的是兩個對象的內容是否相等,即內存地址能夠不同,內容同樣就能夠了。默認會調用對象的 __eq__()方法。

20. 三元運算寫法和應用場景?

# 應用場景:簡化if語句
# 格式
  # 結果+ if  + 條件  + else + 結果
result='gt' if 1>3 else 'lt'
print(result)       # lt
# 理解:若是條件爲真,把if前面的值賦值給變量,不然把else後面的值賦值給變量。


lambda 表達式
temp = lambda x,y:x+y
print(temp(4,10))   # 14

可替代:
def foo(x,y):
    return x+y
print(foo(4,10))    # 14

21. Python3和Python2的區別?

1:打印時,py2須要能夠不須要加括號,py3 須要
python 2 :print ('lili')   ,   print 'lili'
python 3 : print ('lili')   
python3 必須加括號

exec語句被python3廢棄,統一使用exec函數

2:內涵
Python2:1,臃腫,源碼的重複量不少。
             2,語法不清晰,摻雜着C,php,Java,的一些陋習。
Python3:幾乎是重構後的源碼,規範,清晰,優美。

3、輸出中文的區別
python2:要輸出中文 需加 # -*- encoding:utf-8 -*-
Python3 : 直接搞

4:input不一樣
python2 :raw_input
python3 :input 統一使用input函數

5:指定字節
python2在編譯安裝時,能夠經過參數-----enable-unicode=ucs2 或-----enable-unicode=ucs4分別用於指定使用2個字節、4個字節表示一個unicode;
python3沒法進行選擇,默認使用 ucs4
查看當前python中表示unicode字符串時佔用的空間:

impor sys
print(sys.maxunicode)
#若是值是65535,則表示使用usc2標準,即:2個字節表示
#若是值是1114111,則表示使用usc4標準,即:4個字節表示

6:
py2:xrange
    range
py3:range  統一使用range,Python3中range的機制也進行修改並提升了大數據集生成效率

7:在包的知識點裏
包:一羣模塊文件的集合 + __init__
區別:py2 : 必須有__init__
   py3:不是必須的了

8:不相等操做符"<>"被Python3廢棄,統一使用"!="

9:long整數類型被Python3廢棄,統一使用int

10:迭代器iterator的next()函數被Python3廢棄,統一使用next(iterator)

11:異常StandardError 被Python3廢棄,統一使用Exception

12:字典變量的has_key函數被Python廢棄,統一使用in關鍵詞

13:file函數被Python3廢棄,統一使用open來處理文件,能夠經過io.IOBase檢查文件類型

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

a = 1 
b = 2

a, b = b, a

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

0,「」,{},[],(),set()
0 False 負數 不成立的表達式  None 等

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

字符串

字符串用單引號(')或雙引號(")括起來,不可變

1,find經過元素找索引,可切片,找不到返回-1 2,index,找不到報錯。 3,split 由字符串分割成列表,默認按空格。 4,captalize 首字母大寫,其餘字母小寫。 5,upper 全大寫。 6,lower 全小寫。 7,title,每一個單詞的首字母大寫。 8,startswith 判斷以什麼爲開頭,能夠切片,總體概念。 9,endswith 判斷以什麼爲結尾,能夠切片,總體概念。 10,format格式化輸出   #format的三種玩法 格式化輸出   res='{} {} {}'.format('egon',18,'male') ==> egon 18 male   res='{1} {0} {1}'.format('egon',18,'male') ==> 18 egon 18   res='{name} {age} {sex}'.format(sex='male',name='egon',age=18) 11,strip 默認去掉兩側空格,有條件, 12,lstrip,rstrip 14,center 居中,默認空格。 15,count查找元素的個數,能夠切片,若沒有返回0 16,expandtabs 將一個tab鍵變成8個空格,若是tab前面的字符長度不足8個,則補全8個, 17,replace(old,new,次數) 18,isdigit 字符串由字母或數字組成 isalpha, 字符串只由字母組成 isalnum 字符串只由數字組成 19,swapcase 大小寫翻轉 20,for i in 可迭代對象。

字典

key: 輸出全部的鍵
clear:清空                       
dic:刪除的鍵若是沒有則報錯
pop:鍵值對刪,有返回,沒有原來的鍵會報錯(自行設置返回鍵就不會報錯)
popitem:隨機刪鍵值對
del:刪除的鍵若是沒有則報錯
update :更新數據 get: 不報錯的查詢
# 沒有能夠返回設定的返回值

列表

append:在後面添加。
Insert:按照索引添加,
expend:迭代着添加。
pop 刪除並做爲返回值
remove 按照元素去刪
clear  清空列表
del 刪除列表
list.count(obj) - 統計某個元素在列表中出現的次數
list.index(obj) - 從列表中找出某個值第一個匹配項的索引位置
list.reverse() - 反向列表中元素
list.sort([func]) - 對原列表進行排序

元祖

1、cmp(tuple1, tuple2):比較兩個元組元素。
2、len(tuple):計算元組元素個數。
3、max(tuple):返回元組中元素最大值。
4、min(tuple):返回元組中元素最小值。
5、tuple(seq):將列表轉換爲元組。

集合

set:建立集合
add: 添加元素
update:更新元素
clear:清空
pop:隨機刪除並返回
remove:指定刪除
del: 刪除集合

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

匿名函數:爲了解決那些功能很簡單的需求而設計的一句話函數
函數名 = lambda 參數 :返回值

#參數能夠有多個,用逗號隔開
#匿名函數無論邏輯多複雜,只能寫一行,且邏輯執行結束後的內容就是返回值
#返回值和正常的函數同樣能夠是任意數據類型

lambda 表達式
temp = lambda x,y:x+y
print(temp(4,10))   # 14

可替代:
def foo(x,y):
    return x+y
print(foo(4,10))    # 14

26. pass的做用

pass是空語句,是爲了保持程序結構的完整性。pass 不作任何事情,通常用作佔位語句。

27. *arg和**kwarg做用

# 他們是一種動態傳參,通常不肯定須要傳入幾個參數時,可使用其定義參數,而後從中取參

'*args':按照位置傳參,將傳入參數打包成一個‘元組’(打印參數爲元組-- tuple)
'**kwargs':按照關鍵字傳參,將傳入參數打包成一個‘字典’(打印參數爲字典-- dict)

28. 談談Python的深淺拷貝?以及實現方法和應用場景。

淺拷貝只是增長了一個指針指向一個存在的地址,
數據半共享(複製其數據獨立內存存放,可是隻拷貝成功第一層)

深拷貝是增長一個指針而且開闢了新的內存,這個增長的指針指向這個新的內存
數據徹底不共享(複製其數據完徹底全放獨立的一個內存,徹底拷貝,數據不共享)

採用淺拷貝的狀況,釋放內存,會釋放同一內存,深拷貝就不會出現釋放同一內存的錯誤
字典套字典、列表套字典、字典套列表,列表套列表,以及各類複雜數據結構的嵌套中,會出現拷貝後的數據發生變化致使源數據發生變化
import copy
 
# 淺拷貝
l1 = [1,2,3,[11,22,33]]
l2 = l1.copy()
print(l2) #[1,2,3,[11,22,33]]
l2[3][2]='aaa'
print(l1) #[1, 2, 3, [11, 22, 'aaa']]
print(l2) #[1, 2, 3, [11, 22, 'aaa']]
l1[0]= 0
print(l1) #[0, 2, 3, [11, 22, 'aaa']]
print(l2) #[1, 2, 3, [11, 22, 'aaa']]
print(id(l1)==id(l2)) #False

# 深拷貝 
import copy
l1 = [1, 2, 3, [11, 22, 33]]
l2 = copy.deepcopy(l1)
print(l1,'>>>',l2)
# [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [11, 22, 33]]
l2[3][0] = 1111
print(l1,">>>",l2)
# [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [1111, 22, 33]]

29. Python垃圾回收機制?

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

'引用計數'
PyObject是每一個對象必有的內容,其中ob_refcnt就是作爲引用計數。
當一個對象有新的引用時,它的ob_refcnt就會增長,當引用它的對象被刪除,
它的ob_refcnt就會減小.引用計數爲0時,該對象生命就結束了。
    \優勢:1.簡單 2.實時性
    \缺點:1.維護引用計數消耗資源 2.循環引用

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

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

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

可變數據類型:列表、字典、可變集合

不可變數據類型:數字、字符串、元組、不可變集合

31. 求結果

def multipliers():
    return [lambda x:i*x for i in range(4)]
print([m(2) for m in multipliers()])
#解釋:

函數返回值爲一個列表表達式,通過4次循環結果爲包含四個lambda函數的列表, 因爲函數未被調用,循環中的i值未被寫入函數,通過屢次替代,循環結束後i值爲3, 故結果爲:6,6,6,6
現有兩個元組(('a'),('b')),(('c'),('d')),請使用python中匿名函數生成列表[{'a':'c'},{'b':'d'}]
#匿名函數形式:
l1=(('a'),('b'))
l2=(('c'),('d'))
ret=map(lambda n:{n[0]:n[1]},zip(l1,l2))
print(list(ret))
#列表表達式形式:
l1=(('a'),('b'))
l2=(('c'),('d'))
print([{n[0]:n[1]} for n in zip(l1,l2)])
v = dict.fromkeys(['k1', 'k2'], [])
v['k1'].append(666)
print(v)
v['k1'] = 777
print(v)
結果:
{'k1': [666], 'k2': [666]}
{'k1': 777, 'k2': [666]}

解釋:
Python 字典(Dictionary) fromkeys() 函數用於建立一個新字典,以序列seq中元素作字典的鍵,value爲字典全部鍵對應的初始值,默認爲None。
由於全部鍵對應同一個值,因此對鍵爲‘k1’的值作了添加操做後,其餘幾個鍵的值也都添加了相同的值 v1
= dict.fromkeys(['k1', 'k2']) print(v1) # {'k1': None, 'k2': None} v2 = dict.fromkeys(['k1', 'k2'], []) print(v2) # {'k1': [], 'k2': []}

32. 列舉常見的內置函數

map

根據函數對指定序列作映射
map()函數接收兩個參數,一個是函數,一個是可迭代對象,map將傳入的函數依次做用到序列的每一個元素,並把結果做爲新的list返回。

返回值:
  Python2  返回列表
  Python3  返回迭代器

例子1:
def mul(x):
    return x*x
n=[1,2,3,4,5]
res=list(map(mul,n))
print(res)  #[1, 4, 9, 16, 25]

例子2:abs()  返回數字的絕對值
ret = map(abs,[-1,-5,6,-7])
print(list(ret))
# [1, 5, 6, 7]

filter

filter()函數接收一個函數 f(函數)和一個list(可迭代對象),這個函數 f的做用是對每一個元素進行判斷,返回 True或 False,
filter()根據判斷結果自動過濾掉不符合條件的元素,返回由符合條件元素組成的新list。
def is_odd(x):
    return x % 2 == 1

v=list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17]))
print(v)  #[1, 7, 9, 17]

reduce

'''
reduce()  函數
reduce() 函數會對參數序列中元素進行累積
函數將一個數據集合(鏈表、元組等)中的全部數據進行下列操做
'''

注意:
Python3已經將reduce() 函數從全局名字空間裏移除了,
它如今被放置在 fucntools 模塊裏,若是想要使用它,則須要經過引入 functools 模塊來調用 reduce() 函數:
from functools import reduce

def add(x,y): return x + y
print(reduce(add,[1,2,3,4,5])) # 15 print(reduce(lambda x, y: x+y, [1,2,3,4,5])) # 15 print(reduce(add,range(1,101))) # 5050

zip

# zip 拉鍊函數,
# 將對象中對應的元素打包成一個個元組,
# 而後返回由這些元組組成的列表迭代器。
# 若是各個迭代器的元素個數不一致,則返回列表長度與最短的對象相同。
print(list(zip([0,1,3],[5,6,7],['a','b'])))
# [(0, 5, 'a'), (1, 6, 'b')]
zip() 函數用於將可迭代的對象做爲參數,將對象中對應的元素打包成一個個元組,而後返回由這些元組組成的列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包爲元組的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素個數與最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 與 zip 相反,可理解爲解壓,返回二維矩陣式
[(1, 2, 3), (4, 5, 6)]

isinstance\type

isinstance() 函數來判斷一個對象是不是一個已知的類型,相似 type()。
isinstance() 與 type() 區別: type() 不會認爲子類是一種父類類型,不考慮繼承關係。 isinstance() 會認爲子類是一種父類類型,考慮繼承關係。 若是要判斷兩個類型是否相同推薦使用 isinstance()。
# 例一 a = 2 print(isinstance(a,int)) # True print(isinstance(a,str)) # False # type() 與 isinstance() 區別 class A: pass class B(A): pass print("isinstance",isinstance(A(),A)) # isinstance True print("type",type(A()) == A) # type True print('isinstance',isinstance(B(),A) ) # isinstance True print('type',type(B()) == A) # type False

33. 內置函數:map、reduce、filter的用法和區別

    # map:遍歷序列,爲每個序列進行操做,獲取一個新的序列
        a = ["123", "sb_sdsd", "sb_456"]
        b = map(lambda i: i+("sb"), a)
        print(list(b)) # ['123sb', 'sb_sdsdsb', 'sb_456sb']
    # reduce:對於序列裏面的全部元素進行累計操做,可帶初始值
        a = [1, 2, 3]
        from functools import reduce
        b = reduce(lambda i, j: i * j, a, 5)
        print(b) # 30
    # filter:對序列裏面的元素進行判斷篩選,最終獲取符合條件的序列。
        a = ["123", "sb_sdsd", "sb_456"]
        b = filter(lambda i: i.startswith("sb"), a)
        print(list(b)) # ["sb_sdsd", "sb_456"]

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

print('\n'.join([' '.join(['%s*%s=%-2s' % (j, i, i * j) for j in range(1, i + 1)]) for i in range(1, 10)]))

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

# a、能夠在pycharm的settings裏面手動下載添加第三方模塊
# b、能夠在cmd終端下用pip insatll 安裝
# 用過的第三方模塊:requests、pymysql、DBUtils等
requests,pymysql,DbUtils,SQLAlchemy

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

re:正則
os:提供了一種方便的使用操做系統函數的方法。
sys:可供訪問由解釋器使用或維護的變量和與解釋器進行交互的函數。
random:隨機數
json:序列化
time:時間

37.  re的match和search區別?

re.match 嘗試從字符串的起始位置匹配一個模式,若是不是起始位置匹配成功的話,match()就返回none。

re.search 掃描整個字符串並返回第一個成功的匹配。

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

匹配一個字符串沒有節制,能匹配多少就去匹配多少,直到沒有匹配的爲止

39. 求結果

a. [ i % 2 for i in range(10) ]
 
b. ( i % 2 for i in range(10) )
# a結果是一個列表生成式,結果是一個列表(i % 2爲生成的元素): 
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

# b結果是一個生成器
a. 1 or 2
b. 1 and 2
c. 1 < (2==2)
d. 1 < 2 == 2
>>> 1 or 2
1
>>> 1 and 2
2
>>> 1 < (2==2)
False
>>> 1 < 2 == 2
True

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

def func(a,b = []):
    b.append(1)
    print(a,b)

func(a=2)
func(2)
func(2)


'''
    2 [1]
    2 [1, 1]
    2 [1, 1, 1]
    函數的默認參數是一個list 當第一次執行的時候實例化了一個list 
    第二次執行仍是用第一次執行的時候實例化的地址存儲 
    因此三次執行的結果就是 [1, 1, 1] 想每次執行只輸出[1] ,默認參數應該設置爲None

  函數傳參爲列表陷阱,列表是可變數據類型,可能會在過程當中修改裏面的值
'''

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

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

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

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

a = ['1','2','3']
b = [int(i) for i in a]
print(b)
# [1, 2, 3]

43. a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的區別?

前兩個元素是 int 
最後一個元素是元祖
>>> a = (1)
>>> type(a)
<class 'int'>
>>> a = (1,)
>>> type(a)
<class 'tuple'>
>>>

44. a=[1,2,3,4,5],b=a和b=a[:],有區別麼?

a = [1,2,3,4,5]
b = a
b1 = a[:]
print(b)    #  [1, 2, 3, 4, 5]


b.append(6)
print("a",a)  # a [1, 2, 3, 4, 5, 6]
print("b",b)  # b [1, 2, 3, 4, 5, 6]  傳遞引用
print("b1",b1) # b1 [1, 2, 3, 4, 5]   拷貝

45. 一個列表A=[2,3,4],Python如何將其轉換成B=[(2,3),(3,4),(4,2)]?

A = [2,3,4]
B = zip(A, A[1:]+A[:1])

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

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

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

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

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

python中的global語句是被用來聲明全局變量的。
x = 2
def func():
    global x
    x = 1
    return x
func()
print(x)  # 1

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

logging 
模塊定義的函數和類爲應用程序和庫的開發實現了一個靈活的事件日誌系統
# 做用:
    管理咱們程序的執行日誌,省去用print記錄操做日誌的操做,而且能夠將標準輸入輸出保存到日誌文件
# 場景:
    爬蟲爬取數據時,對爬取進行日誌記錄,方便分析、排錯。

50.  請用代碼簡答實現stack

Stack() 建立一個新的空棧
push(item) 添加一個新的元素item到棧頂
pop() 彈出棧頂元素
peek() 返回棧頂元素
is_empty() 判斷棧是否爲空
size() 返回棧的元素個數
class Stack:
    def __init__(self):
        self.items = []

    def is_empty(self):
        # 判斷是否爲空
        return self.items == []

    def push(self,item):
        # 加入元素
        self.items.append(item)

    def pop(self):
        # 彈出元素
        return self.items.pop()

    def peek(self):
        # 返回棧頂元素
        return self.items[len(self.items)-1]

    def size(self):
        # 返回棧的大小
        return len(self.items)

if __name__ == "__main__":
    stack = Stack()
    stack.push("H")
    stack.push("E")
    stack.push("L")
    print(stack.size())  # 3
    print(stack.peek())  # L 
    print(stack.pop())   # L
    print(stack.pop())   # E
    print(stack.pop())   # H

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

佔位符%

%d 表示那個位置是整數;%f 表示浮點數;%s 表示字符串。php

print('Hello,%s' % 'Python')
print('Hello,%d%s%.2f' % (666, 'Python', 9.99)) # 打印:Hello,666Python10.00

format 

print('{k} is {v}'.format(k='python', v='easy'))  # 經過關鍵字
print('{0} is {1}'.format('python', 'easy'))      # 經過關鍵字

 f" {} "

python 3.7 加入的新特性,基於 format 的簡易加強版html

a = yangtuo
b = f"{a} is good~~" 
print(a)  # yangtuo is good~~

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

迭代器

內部有__next__和__iter__方法的對象,幫助咱們向後一個一個取值,迭代器不必定是生成器

應用場景: - wtforms裏面對form對象進行循環時,顯示form中包含的全部字段 - 列表、字典、元組 (可讓一個對象被for循環)

生成器

一個函數內部存在yield關鍵字

應用場景:
   - rang/xrange
   - redis獲取值
      - conn = Redis(......)
        - v=conn.hscan_iter() # 內部經過yield 來返回值
    - stark組件中
        - 前端調用後端的yield
conn = Redis(...)

    def hscan_iter(self, name, match=None, count=None):
      """
      Make an iterator using the HSCAN command so that the client doesn't
      need to remember the cursor position.

      ``match`` allows for filtering the keys by pattern

      ``count`` allows for hint the minimum number of returns
      """
      cursor = '0'
      while cursor != 0:
        # 去redis中獲取數據:12
        # cursor,下一次取的位置
        # data:本地獲取的12條數數據
        cursor, data = self.hscan(name, cursor=cursor,match=match, count=count)
        for item in data.items():
          yield item
def index(request):
    data = [
      {'k1':1,'name':'alex'},
      {'k1':2,'name':'老男孩'},
      {'k1':3,'name':'小男孩'},
    ]
    new_data = []
    for item in data:
      item['email'] = "xxx@qq.com"
      new_data.append(item)

    return render(request,'xx.html',{'data':new_data})

裝飾器

可以在不修改原函數代碼的基礎上,在執行先後進行定製操做,閉包函數的一種應用

場景:
- flask 路由系統 - flask before_request - csrf - django 內置認證 - django 緩存

# 手寫裝飾器; import functools def wrapper(func): @functools.wraps(func) #不改變原函數屬性 def inner(*args, **kwargs): 執行函數前 return func(*args, **kwargs) 執行函數後 return inner 1. 執行wapper函數,並將被裝飾的函數當作參數。 wapper(index) 2. 將第一步的返回值,從新賦值給 新index = wapper(老index) @wrapper #index=wrapper(index) def index(x): return x+100


調用裝飾器實際上是一個閉包函數,爲其餘函數添加附加功能,不修改被修改的源代碼和不修改被修飾的方式,裝飾器的返回值也是一個函數對象。
好比:插入日誌、性能測試、事物處理、緩存、權限驗證等,有了裝飾器,就能夠抽離出大量與函數功能自己無關的雷同代碼並繼續重用。

可迭代對象

字典,元祖,列表等

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

二分查找算法:
  簡單的說,就是將一個列表先排序好,好比按照從小到大的順序排列好,
  當給定一個數據,好比3,查找3在列表中的位置時,
  能夠先找到列表中間的數li[middle]和3進行比較,
    當它比3小時,那麼3必定是在列表的右邊,
    反之,則3在列表的左邊,好比它比3小,
  則下次就能夠只比較[middle+1, end]的數,
    繼續使用二分法,將它一分爲二,直到找到3這個數返回或者列表所有遍歷完成(3不在列表中) 優勢:效率高,時間複雜度爲O(logN); 缺點:數據要是有序的,順序存儲。
def binary_chop(alist, data):
    n = len(alist)
    if n < 1:
        return False
    mid = n // 2
    if alist[mid] > data:
        return binary_chop(alist[0:mid], data)
    elif alist[mid] < data:
        return binary_chop(alist[mid + 1:], data)
    else:
        return True


lis = [2, 4, 5, 12, 14, 23]
print(binary_chop(lis, 2))

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

# 閉包函數就是內部的函數調用外部函數的變量,經常使用於裝飾器。
# 判斷閉包函數的方法:__closure__,輸出的__closure__有cell元素說明是閉包函數
# 閉包的意義與應用:
  # 延遲計算

54. os和sys模塊的做用?

os模塊負責程序與操做系統的交互,提供了訪問操做系統底層的接口;
sys模塊負責程序與python解釋器的交互,提供了一系列的函數和變量,用於操控python的運行時環境。

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

import random
 
print(random.random())          # 用於生成一個0到1的隨機符點數: 0 <= n < 1.0
print(random.randint(1, 1000))  # 用於生成一個指定範圍內的整數

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

import os
file = r'D:\test.txt'
if os.path.exists(file):
    os.remove(file)
    print('delete success')
else:
    print('no such file:%s' % file)

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

  先隨便扯些和別的語言的對比
        python 自己是支持函數式編程 和 面向對象式編程
        c,java是隻能基於面向對象
    
    在簡單說下面向對象的主要特色和好處
        - 基礎:面向對象自己擁有基礎的三大特性


                封裝
                    將方法封裝到類中
                        體如今 功能類上的整合
                    將數據封裝到對象中 
                        體如今類的對象初始化賦值等
                
                繼承
                    python 是支持多繼承的 是python的一個特點,java c# 是不支持的
                        基於 mro 的順序來決定繼承順序
                    多個類的對共同方法的,爲避免重複編寫,封裝到父(基)類中
                    應用 : rest framework 中的視圖類的繼承很是多
                    
                多態
                    python 做爲強類型的動態腳本語言,不支持多態,可是也不須要支持多態
                    在c# java裏面必需要指定類型,固然也能夠經過接口類實現目的
                    鴨子類型:
                        python 中的參數能夠傳入任何類型的對象,不會對類型進行強制限制
                    說法:
                        若是我有個類,這個類的傳入參數是不會有類型限制的 這體現了多態
                        我有多個類,這些都有個 send 方法 每一個類的分別的實例化對象在調用 send 的時候
                        都是obj.send() 的同樣的調用方式,可是倒是執行的他內部的本身的 send 方法,這體現了多態性

        - 進階:魔法方法 
            
            __init__          初始化
            __new__            建立對象
            __call__        對象()     
            __str__            print(對象)    
            __repr__            
            __iter__        含有此方法且返回迭代器 表明此對象可迭代    
            
            __getattr__        對象.xx
            __setattr__        
            __delattr__        對象.del
            
            __setiter__        對象["xx"]
            __getiter__
            __deliter__
            
            __mro__            查當作員順序 
            __dict__        查當作員順序 
            
            __add__            對象相加的時候觸發
            __...__            對象相減的時候觸發
            __...__            對象相乘的時候觸發
            __...__            對象相除的時候觸發
            
            __enter__        with 對象的開始前觸發
            __exit__        with 對象的結束時觸發
                應用: 在 SQLAlchemy 中有使用
            
        - 高階:metaclass 
            
            類的建立兩種方法:
                class Foo():pass
                type("Foo",(object,),{ })
            
            指定建立類的 mtype 
                class Foo(metaclass=MyType):    # python 3 
                    # __metaclass__ = MyType # python 2 
                    pass 
                
                MyType('Foo',(object,),{})
                # 若是一類本身或基類中指定了metaclass
                # 那麼該類就是由metaclass指定的type或mytype建立。
            
            對於源碼的閱讀須要注意 是否指定了 metaclass 
                未指定直接看 __new__ 而後 __init__ 便可
                若是指定了須要注意:
                    建立類
                        MyType.__init__ 
                    建立對象 
                        MyType.__call__ 
                        MyType.__new__ 
                        MyType.__init__ 
                            
             

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

繼承概念的實現方式主要有2類:實現繼承、接口繼承。

         實現繼承是指使用基類的屬性和方法而無需額外編碼的能力;
         接口繼承是指僅使用屬性和方法的名稱、可是子類必須提供實現的能力(子類重構爹類方法);

python 兩種類:經典類 新式類 python3 新式類 —— 都默認繼承object
class Animal(object): == class Animal: python2 經典類和新式類 並存 class Animal: 經典類 —— 繼承順序 個別使用方法 class Animal(object): 新式類 繼承分爲單繼承和多繼承 Python是支持多繼承的 若是沒有指定基類,python的類會默認繼承object類,
object是全部python類的基類,它提供了一些常見方法(如__str__)的實現。
class A:
    def get(self):
        self.say()

    def say(self):
        print('AAAAA')

class B(A):
    def say(self):
        print('BBBBB')

b = B()
b.get()   #輸出結果爲:BBBBB

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

Python的類能夠繼承多個類,Python的類若是繼承了多個類,那麼其尋找方法的方式有兩種
當類是經典類時,多繼承狀況下,會按照深度優先方式查找 py3 當類是新式類時,多繼承狀況下,會按照廣度優先方式查找 py2
簡單點說就是:經典類是縱向查找,新式類是橫向查找 經典類和新式類的區別就是,在聲明類的時候,新式類須要加上object關鍵字。在python3中默認全是新式類

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

用於子類繼承基類的方法

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

裝飾器中,會用到;functools.wraps()主要在裝飾器中用來裝飾函數

Stark上下文管理源碼中,走到視圖階段時有用到functools中的偏函數,

request
= LocalProxy(partial(_lookup_req_object, 'request'))

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

# __getattr__
 CBV
 django配置文件
 wtforms中的Form()示例化中 將"_fields中的數據封裝到From類中"
# __mro__  wtform中 FormMeta中繼承類的優先級
# __dict__ 是用來存儲對象屬性的一個字典,其鍵爲屬性名,值爲屬性的值
# __new__ 實例化可是沒有給當前對象 wtforms,字段實例化時返回:不是StringField,而是UnboundField est frawork many=Turn 中的序列化
# __call__ flask 請求的入口app.run() 字段生成標籤時:字段.__str__ => 字段.__call__ => 插件.__call__

# __iter__ 循環對象是,自定義__iter__ wtforms中BaseForm中循環全部字段時定義了__iter__
# -metaclass 做用:用於指定當前類使用哪一個類來建立 場景:在類建立以前定製操做 示例:wtforms中,對字段進行排序。

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

# 看他的調用者是誰,若是是類,須要傳入參數self,這時就是一個函數;
# 若是調用者是對象,不須要傳入參數值self,這時是一個方法。
(FunctionType/MethodType)
print(isinstance(obj.func, FunctionType))   # False

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

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

@property     將方法變成變量形式自動調用
@staticmethod  靜態方法,類能夠不用實例化就能夠調用該方法 C.f(),固然也能夠實例化後調用 C().f()。
@classmethod    類不需實例化就能夠調用內部方法,直接類名.方法便可調用
Classmethod必須有一個指向類對象的引用做爲第一個參數;
@classmethod
def class_func(cls):
   """ 定義類方法,至少有一個cls參數 """
   print('類方法')
---------------------------------------------------------
Staticmethod能夠沒有任何參數。
@staticmethod
def static_func():
   """ 定義靜態方法 ,無默認參數"""
   print('靜態方法')

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

1. __doc__:表示類的描述信息。
2.__module__:表示當前操做的對象在那個模塊;
3.__class__:表示當前操做的對象的類是什麼。
4.__init__:構造方法,經過類建立對象時,自動觸發執行。
5.__call__:對象後面加括號,觸發執行。
6.__dict__:類或對象中的全部成員。
7.__str__:若是一個類中定義了__str__方法,那麼在打印對象時,默認輸出該方法的返回值。
class Foo:
    def __str__(self):
        return 'aaa'
obj = Foo()
print(obj)
# 輸出:aaa

8.__getitem____setitem____delitem__:用於索引操做,如字典。以上分別表示獲取、設置、刪除數據。
9.__iter__:用於迭代器,之因此列表、字典、元組能夠進行for循環,是由於類型內部定義了 __iter__

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

題意理解:組成後的數值不相同,且組合的三個位數之間數字不重複。

使用python內置的排列組合函數(不放回抽樣排列)

product 笛卡爾積  (有放回抽樣排列)

permutations 排列  (不放回抽樣排列)

combinations 組合,沒有重複  (不放回抽樣組合)

combinations_with_replacement 組合,有重複  (有放回抽樣組合)
import itertools
 
print(len(list(itertools.permutations('12345', 3))))  # 60

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

反射的核心本質就是以字符串的形式去導入個模塊,利用字符串的形式去執行函數。

Django中的 CBV就是基於反射實現的。
rest framework裏面的CBV

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

# metaclass 實例     
class MyType(type):
    def __init__(self,*args,**kwargs):
        super(MyType,self).__init__(*args,**kwargs)

    def __call__(cls, *args, **kwargs):
        obj = cls.__new__(cls)

        cls.__init__(obj,*args, **kwargs)

        return obj

class Foo(object,metaclass=MyType):  # metaclass 指定由誰來建立這個類 
    a1 = 123
    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        return object.__new__(cls)

    def func(self):
        return 666
    
foo = Foo()
    
    # 建立類的時候會先執行 type 的 __init__  方法 ,由type 的 __init__ 來建立類
    # 當一個類在實例化時候,先執行 type 的 __call__ 方法 , __call__ 方法 的返回值就是實例化對象 
        # __call__ 內部調用:
            # 類.__new__ 方法 :建立對象
            # 類.__init__ 方法 :對象初始化

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

# 單例模式
'''單例模式是一種經常使用的軟件設計模式。在它的核心結構中只包含一個被稱爲單例類的特殊類。
經過單例模式能夠保證系統中一個類只有一個實例並且該實例易於外界訪問,從而方便對實例個數的控制並節約系統資源。
若是但願在系統中某個類的對象只能存在一個,單例模式是最好的解決方案。'''
# 一、使用__new__方法
class MyClass(object):
    _instance = False
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = object.__new__(MyClass)
        return cls._instance
# 二、共享屬性
# 建立實例時把全部實例的__dict__指向同一個字典,這樣它們具備相同的屬性和方法.
    class Borg(object):
        _state = {}
        def __new__(cls, *args, **kw):
            ob = super(Borg, cls).__new__(cls, *args, **kw)
            ob.__dict__ = cls._state
            return ob
    class MyClass2(Borg):
        a = 1
# 三、裝飾器版本
def singleton(cls, *args, **kw):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance
@singleton
class MyClass:
    ...
# 四、import方法
# 做爲python的模塊是自然的單例模式
    # mysingleton.py
    class My_Singleton(object):
        def foo(self):
            pass
    my_singleton = My_Singleton()
    # to use
    from mysingleton import my_singleton
    my_singleton.foo()

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

相關文章
相關標籤/搜索