python面試手冊(cè)(補(bǔ)充ing)

一、理論部分(語言特性)

1. 元類metaclass

2. args,*kwargs

當(dāng)函數(shù)的參數(shù)前面有一個(gè)星號(hào)*號(hào)的時(shí)候表示這是一個(gè)可變的位置參數(shù),兩個(gè)星號(hào)**表示這個(gè)是一個(gè)可變的關(guān)鍵詞參數(shù)。
星號(hào)``*把序列或者集合解包(unpack)成位置參數(shù),兩個(gè)星號(hào)**把字典解包成關(guān)鍵詞參數(shù)。
或者我們希望以元組(tuple)或者列表(list)的形式傳參數(shù)

2.1 重載

結(jié)論放在前:python 不需要函數(shù)重載
函數(shù)重載主要是為了解決兩個(gè)問題。

  1. 可變參數(shù)類型。(Python可以接受任何類型的參數(shù))
  2. 可變參數(shù)個(gè)數(shù)。(設(shè)置缺省參數(shù))

一個(gè)基本的設(shè)計(jì)原則是,僅僅當(dāng)兩個(gè)函數(shù)除了參數(shù)類型和參數(shù)個(gè)數(shù)不同以外,其功能是完全相同的,此時(shí)才使用函數(shù)重載,如果兩個(gè)函數(shù)的功能其實(shí)不同,那么不應(yīng)當(dāng)使用重載,而應(yīng)當(dāng)使用一個(gè)名字不同的函數(shù)

3. 裝飾器(decorator)

裝飾器本質(zhì)上是一個(gè)Python函數(shù),它可以讓其它函數(shù)在不作任何變動(dòng)的情況下增加額外功能,裝飾器的返回值也是一個(gè)函數(shù)對(duì)象。它經(jīng)常用于有切面需求的場(chǎng)景。比如:插入日志、性能測(cè)試、事務(wù)處理、緩存、權(quán)限校驗(yàn)等。有了裝飾器我們就可以抽離出大量的與函數(shù)功能無關(guān)的雷同代碼進(jìn)行重用。

4. 垃圾回收機(jī)制

Python中的垃圾回收是以引用計(jì)數(shù)為主,標(biāo)記-清除和分代收集為輔。

  • 引用計(jì)數(shù):Python在內(nèi)存中存儲(chǔ)每個(gè)對(duì)象的引用計(jì)數(shù),如果計(jì)數(shù)變成0,該對(duì)象就會(huì)消失,分配給該對(duì)象的內(nèi)存就會(huì)釋放出來。
  • 標(biāo)記-清除:一些容器對(duì)象,比如list、dict、tuple,instance等可能會(huì)出現(xiàn)引用循環(huán),對(duì)于這些循環(huán),垃圾回收器會(huì)定時(shí)回收這些循環(huán)(對(duì)象之間通過引用(指針)連在一起,構(gòu)成一個(gè)有向圖,對(duì)象構(gòu)成這個(gè)有向圖的節(jié)點(diǎn),而引用關(guān)系構(gòu)成這個(gè)有向圖的邊)。
  • 分代收集:Python把內(nèi)存根據(jù)對(duì)象存活時(shí)間劃分為三代,對(duì)象創(chuàng)建之后,垃圾回收器會(huì)分配它們所屬的代。每個(gè)對(duì)象都會(huì)被分配一個(gè)代,而被分配更年輕的代是被優(yōu)先處理的,因此越晚創(chuàng)建的對(duì)象越容易被回收。

5. 多線程(multi-threading)

Python并不支持真正意義上的多線程,Python提供了多線程包。Python中有一個(gè)叫Global Interpreter Lock(GIL)的東西,它能確保你的代碼中永遠(yuǎn)只有一個(gè)線程在執(zhí)行。經(jīng)過GIL的處理,會(huì)增加執(zhí)行的開銷。這就意味著如果你先要提高代碼執(zhí)行效率,使用threading不是一個(gè)明智的選擇,當(dāng)然如果你的代碼是IO密集型,多線程可以明顯提高效率,相反如果你的代碼是CPU密集型的這種情況下多線程大部分是雞肋。

6. os,sys模塊的不同

  • os模板提供了一種方便的使用操作系統(tǒng)函數(shù)的方法
  • sys模板可供訪問由解釋器使用或維護(hù)的變量和與解釋器交互的函數(shù)
    os模塊負(fù)責(zé)程序與操作系統(tǒng)的交互,提供了訪問操作系統(tǒng)底層的接口。sys模塊負(fù)責(zé)程序與Python解釋器的交互,提供了一系列的函數(shù)和變量用戶操作Python運(yùn)行時(shí)的環(huán)境。

7. lambda表達(dá)式

lambda表達(dá)式一般的形式是:關(guān)鍵詞lambda后面緊接一個(gè)或多個(gè)參數(shù),緊接一個(gè)冒號(hào)“:”,緊接一個(gè)表達(dá)式。lambda表達(dá)式是一個(gè)表達(dá)式不是一個(gè)語句。

8. 深淺拷貝

copy.copy:淺拷貝,只拷貝父對(duì)象,不拷貝父對(duì)象的子對(duì)象。
copy.deepcopy:深拷貝,拷貝父對(duì)象和子對(duì)象。

import copy
myList = [1, 2, [3, ]]
myCopyList = myList
myCCopyList = copy.copy(myList)
myDCopyList = copy.deepcopy(myList)
myList[2].append(4)
print("復(fù)制:{} || 淺拷貝: {} || 深拷貝:{} ".format(myCopyList, myCCopyList, myDCopyList))

>>復(fù)制:[1, 2, [3, 4]] || 淺拷貝: [1, 2, [3, 4]] || 深拷貝:[1, 2, [3]]

9. Python2.x與3.x版本區(qū)別

9.1 print函數(shù)

2是語句 3是函數(shù)

9.2 Unicode

  • Python 2 有 ASCII str() 類型,unicode() 是單獨(dú)的,不是 byte 類型
  • Python 3有了 Unicode (utf-8) 字符串,以及一個(gè)字節(jié)類:byte 和 bytearrays
  • Python3.X 源碼文件默認(rèn)使用utf-8編碼

9.3 除法運(yùn)算

  • Python中的除法有兩個(gè)運(yùn)算符,/和//
  • 在python 2.x中/除法就跟我們熟悉的大多數(shù)語言,比如Java啊C啊差不多,整數(shù)相除的結(jié)果是一個(gè)整數(shù),把小數(shù)部分完全忽略掉,浮點(diǎn)數(shù)除法會(huì)保留小數(shù)點(diǎn)的部分得到一個(gè)浮點(diǎn)數(shù)的結(jié)果
  • 在python 3.x中/除法,對(duì)于整數(shù)之間的相除,結(jié)果也會(huì)是浮點(diǎn)數(shù)。
  • 而對(duì)于//除法,這種除法叫做floor除法,會(huì)對(duì)除法的結(jié)果自動(dòng)進(jìn)行一個(gè)floor操作,在python 2.x和python 3.x中是一致的。

9.4 異常

捕獲異常的語法由 except exc, var 改為 except exc as var。

9.5 xrange

9.6 八進(jìn)制字面量表示

在Python 3.x中,表示八進(jìn)制字面量的方式只有一種,就是0o1000。
原來的形式0777不能用了
二進(jìn)制必須寫成0b111

9.7 不等運(yùn)算符

Python 2.x中不等于有兩種寫法 != 和 <>
Python 3.x中去掉了<>, 只有!=一種寫法

9.8 數(shù)據(jù)類型

Py3.X去除了long類型,現(xiàn)在只有一種整型——int,但它的行為就像2.X版本的long
新增了bytes類型,對(duì)應(yīng)于2.X版本的八位串,定義一個(gè)bytes字面量的方法如下:b = b'china'
str對(duì)象和bytes對(duì)象可以使用.encode() (str -> bytes) or .decode() (bytes -> str)方法相互轉(zhuǎn)化

10. newinit的區(qū)別

__init__為初始化方法,__new__方法是真正的構(gòu)造函數(shù)。
__new__是實(shí)例創(chuàng)建之前被調(diào)用,它的任務(wù)是創(chuàng)建并返回該實(shí)例,是靜態(tài)方法
__init__是實(shí)例創(chuàng)建之后被調(diào)用的,然后設(shè)置對(duì)象屬性的一些初始值。 
__new__方法在__init__方法之前被調(diào)用,并且__new__方法的返回值將傳遞給__init__方法作為第一個(gè)參數(shù),最后__init__給這個(gè)實(shí)例設(shè)置一些參數(shù)。

我們可以分別使用__metaclass__,__new____init__來分別在類創(chuàng)建,實(shí)例創(chuàng)建和實(shí)例初始化的時(shí)候做處理

11. 方法中單下劃線和雙下劃線

  • __name__:一種約定,Python內(nèi)部的名字,用來與用戶自定義的名字區(qū)分開,防止沖突
  • _name:一種約定,用來指定變量私有
  • __name:解釋器用_classname__name來代替這個(gè)名字用以區(qū)別和其他類相同的命名

12. python自省

自省就是面向?qū)ο蟮恼Z言所寫的程序在運(yùn)行時(shí),所能知道對(duì)象的類型。
type()、dir()、getattr()、hasattr()、isinstance()

13. 單例模式

單例模式是一種常用的軟件設(shè)計(jì)模式。在它的核心結(jié)構(gòu)中只包含一個(gè)被稱為單例類的特殊類。通過單例模式可以保證系統(tǒng)中一個(gè)類只有一個(gè)實(shí)例而且該實(shí)例易于外界訪問,從而方便對(duì)實(shí)例個(gè)數(shù)的控制并節(jié)約系統(tǒng)資源。

1.用__new__方法
class Singleton(object):
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)
            cls._instance = orig.__new__(cls, *args, **kw)
        return cls._instance

class MyClass(Singleton):
    a = 1

2.共享屬性
創(chuàng)建實(shí)例時(shí)把所有實(shí)例的__dict__指向同一個(gè)字典,這樣它們具有相同的屬性和方法.
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

3.裝飾器版本
def singleton(cls):
    instances = {}
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance

@singleton
class MyClass:
  ...

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

本文參考Github 關(guān)于Python的面試題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容