python基礎之面試常問


參考:

python面試常問



python內存管理機制,gc機制的了解,gc回收三種算法。

python內存管理(原博文——python內存管理

  • python是動態語言,對象與引用分類,一個變量使用不需要事先聲明,而在賦值時,變量可以重新賦值為任意值。

  • python中,整數和短小的字符,Python都會緩存這些對象,以便重復使用。當我們創建多個等於1的引用時,實際上是讓所有這些引用指向同一個對象。(可以通過is判斷是不是同一個對象)

  • 在python中,每個對象都有存有指向該對象的引用總數,即引用計數(reference count)。我們可以使用sys包中的getrefcount(),來查看某個對象的引用計數。需要注意的是,當使用某個引用作為參數,傳遞給getrefcount()時,參數實際上創建了一個臨時的引用。因此,getrefcount()所得到的結果,會比期望的多1。

  • python的一個容器對象(container),比如表、詞典等,可以包含多個對象。實際上,容器對象中包含的並不是元素對象本身,是指向各個元素對象的引用。

  • python中對象可以引用對象,對象的相互引用會構成引用環。

  • 引用減少的情況:1. del刪除某一個對象的引用;2. 如果某個引用指向對象A,當這個引用重新被定義到其他對象時,引用數減少。

python垃圾回收

  • 從基本原理上,當Python的某個對象的引用計數降為0時,說明沒有任何引用指向該對象,該對象就成為要被回收的垃圾了。但是,垃圾回收時,Python不能進行其它的任務。頻繁的垃圾回收將大大降低Python的工作效率。如果內存中的對象不多,就沒有必要總啟動垃圾回收。所以,Python只會在特定條件下,自動啟動垃圾回收。當Python運行時,會記錄其中分配對象(object allocation)和取消分配對象(object deallocation)的次數。當兩者的差值高於某個閾值時,垃圾回收才會啟動。

  • 我們可以通過gc模塊的get_threshold()方法,查看該閾值:

    import gc
    print(gc.get_threshold())
    

    返回(700, 10, 10),后面的兩個10是與分代回收相關的閾值,后面可以看到。700即是垃圾回收啟動的閾值。可以通過gc中的set_threshold()方法重新設置。我們也可以手動啟動垃圾回收,即使用gc.collect()。

  • 分代回收: python同時采用了分代(generation)回收的策略。這一策略的基本假設是,存活時間越久的對象,越不可能在后面的程序中變成垃圾。我們的程序往往會產生大量的對象,許多對象很快產生和消失,但也有一些對象長期被使用。出於信任和效率,對於這樣一些“長壽”對象,我們相信它們的用處,所以減少在垃圾回收中掃描它們的頻率。python將所有的對象分為0,1,2三代。所有的新建對象都是0代對象。當某一代對象經歷過垃圾回收,依然存活,那么它就被歸入下一代對象。垃圾回收啟動時,一定會掃描所有的0代對象。如果0代經過一定次數垃圾回收,那么就啟動對0代和1代的掃描清理。當1代也經歷了一定次數的垃圾回收后,那么會啟動對0,1,2,即對所有對象進行掃描。這兩個次數即上面get_threshold()返回的(700, 10, 10)返回的兩個10。也就是說,每10次0代垃圾回收,會配合1次1代的垃圾回收;而每10次1代的垃圾回收,才會有1次的2代垃圾回收。同樣可以用set_threshold()來調整,比如對2代對象進行更頻繁的掃描。

  • 孤立的引用環: 引用環的存在會給上面的垃圾回收機制帶來很大的困難。這些引用環可能構成無法使用,但引用計數不為0的一些對象。比如我們創建了兩個表對象,並引用對方,構成一個引用環。刪除了a,b引用之后,這兩個對象不可能再從程序中調用,就沒有什么用處了。但是由於引用環的存在,這兩個對象的引用計數都沒有降到0,不會被垃圾回收。

    a = []
    b = [a]
    a.append(b)
    
    del a
    del b
    

    為了回收這樣的引用環,python復制每個對象的引用計數,可以記為gc_ref。假設,每個對象i,該計數為gc_ref_i。python會遍歷所有的對象i。對於每個對象i引用的對象j,將相應的gc_ref_j減1。在結束遍歷后,gc_ref不為0的對象,和這些對象引用的對象,以及繼續更下游引用的對象,需要被保留。而其它的對象則被垃圾回收。


lambda函數

lambda作為一個表達式,定義了一個匿名函數。lambda表達式是起到一個函數速寫的作用,允許在代碼內嵌入一個函數的定義。例如:

func1 = lambda x,y:x+y

def func2(x,y):
    return x+y

func1和func2其實作用相同。

lambda的優點是代碼比較簡潔,缺點是易讀性不好。


高級函數 map、reduce、filter、sorted等。

菜鳥教程——python內置函數

map()

map() 會根據提供的函數對指定序列做映射。第一個參數 function 以參數序列中的每一個元素調用 function 函數,返回包含每次 function 函數返回值的新列表。

map(function, iterable,...)

返回值:python 2.x返回列表,python3.x返回迭代器。

以python3為例:

a = map(lambda x:x**2,[1,2,3,4])
print(a)
print(list(a))

輸出:

<map object at 0x000001EB55F4C710>
[1, 4, 9, 16]

filter()

filter() 函數用於過濾序列,過濾掉不符合條件的元素,返回一個迭代器對象,如果要轉換為列表,可以使用 list() 來轉換。

該接收兩個參數,第一個為函數,第二個為序列,序列的每個元素作為參數傳遞給函數進行判,然后返回 True 或 False,最后將返回 True 的元素放到新列表中。

# 第一個參數是判斷函數,第二個參數是可迭代對象
filter(function, iterable)

實例:

a = filter(lambda x:x%2==0,[1,2,3,4])
print(a)
print(list(a))

輸出:

<filter object at 0x000001EB55F44F60>
[2, 4]

reduce()

reduce()函數也是Python內置的一個高階函數。reduce()函數接收的參數和 map()類似,一個函數 function,一個可迭代對象,但行為和 map()不同,reduce()傳入的函數必須接收兩個參數,reduce()對list的每個元素反復調用函數f,並返回最終結果值。

在python3中,reduce()函數已經從全局函數中移除了,放在fucntools,所以我們首先得導入從fucntools中導入reduce()函數。

reduce(function, iterable)

實例:

from functools import reduce
sum = reduce(lambda x,y:x+y,[1,3,5,7,9])
print(sum)

輸出:

25

sorted()

sorted() 函數對所有可迭代的對象進行排序操作。

sort與sorted的區別:

sort 是應用在 list 上的方法,sorted 可以對所有可迭代的對象進行排序操作。

list 的 sort 方法返回的是對已經存在的列表進行操作,而內建函數 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操作。

sorted(iterable, key=None, reverse=False)  
  • iterable -- 可迭代對象。
  • key -- 主要是用來進行比較的元素,只有一個參數,具體的函數的參數就是取自於可迭代對象中,指定可迭代對象中的一個元素來進行排序。
  • reverse -- 排序規則,reverse = True 降序 , reverse = False 升序(默認)。

實例:

nums = [[2,1],[3,4],[5,2],[4,10]]
# 將二維數組按第一列逆序排列
sorted(nums, key = lambda x:x[0], reverse = True)

輸出:

[[5, 2], [4, 10], [3, 4], [2, 1]]

簡述六種基本數據類型(number、string、list、tuple、dict、set)。

數字number菜鳥教程——python3數字

Python 支持三種不同的數值類型:

  • 整型(Int) - 通常被稱為是整型或整數,是正或負整數,不帶小數點。Python3 整型是沒有限制大小的,可以當作 Long 類型使用,所以 Python3 沒有 Python2 的 Long 類型。
  • 浮點型(float) - 浮點型由整數部分與小數部分組成,浮點型也可以使用科學計數法表示(2.5e2 = 2.5 x 102 = 250)
  • 復數( (complex)) - 復數由實數部分和虛數部分構成,可以用a + bj,或者complex(a,b)表示, 復數的實部a和虛部b都是浮點型。

python數字類型轉換:

  • int(x) 將x轉換為一個整數。

  • float(x) 將x轉換到一個浮點數。

  • complex(x) 將x轉換到一個復數,實數部分為 x,虛數部分為 0。

  • complex(x, y) 將 x 和 y 轉換到一個復數,實數部分為 x,虛數部分為 y。x 和 y 是數字表達式。

字符串string菜鳥教程——python3字符串

  • 創建:可以用單引號或者雙引號創建。

  • 切片:string類型支持切片。

  • 拼接:可以用加號拼接兩個字符串。

  • ...(內容比較多,參考上面的鏈接)

列表list菜鳥教程——python3列表

列表是最常用的Python數據類型,它可以作為一個方括號內的逗號分隔值出現。列表的數據項不需要具有相同的類型創建一個列表,只要把逗號分隔的不同的數據項使用方括號括起來即可。

其他的參見上面的鏈接。

元組tuple菜鳥教程——python3元組

Python 的元組與列表類似,不同之處在於元組的元素不能修改。

元組使用小括號(但是訪問元組中的元素用中括號,例如:tuple[0]),列表使用方括號。元組創建很簡單,只需要在括號中添加元素,並使用逗號隔開即可。

注意:元組中只有一個元素時,需要在該元素后面加一個逗號,如下:

tuple1 = (1)
tuple2 = (1,)
print(type(tuple1),type(tuple2))

輸出:

<class 'int'> <class 'tuple'>
  • 元組允許兩個元組相加得到新的元組。(tuple1 + tuple2 = tuple3)

  • 元組中元素不能刪除,但是可以刪除整個元組。(del tuple)

  • 元組很多方法跟列表都是互通的。

字典dict菜鳥教程——python3字典

  • 字典是另一種可變容器模型,且可存儲任意類型對象。

  • 字典的每個鍵值(key=>value)對用冒號(:)分割,每個對之間用逗號(,)分割,整個字典包括在花括號{}中。

  • 鍵必須是唯一的,但值則不必。值可以取任何數據類型,但鍵必須是不可變的,如字符串,數字或元組。

  • 字典方法很多,參見鏈接。

集合set菜鳥教程——python3集合

  • 集合(set)是一個無序的不重復元素序列。可以使用大括號 { } 或者 set() 函數創建集合,注意:創建一個空集合必須用 set() 而不是 { },因為 { } 是用來創建一個空字典。

  • 方法參見鏈接。


python中深拷貝與淺拷貝。

原博文——python 深拷貝與淺拷貝

  • Python中對象的賦值都是進行對象引用(內存地址)傳遞
  • 使用copy.copy(),可以進行對象的淺拷貝,它復制了對象,但對於對象中的元素,依然使用原始的引用。
  • 如果需要復制一個容器對象,以及它里面的所有元素(包含元素的子元素),可以使用copy.deepcopy()進行深拷貝
  • 對於非容器類型(如數字、字符串、和其他'原子'類型的對象)沒有被拷貝一說
  • 如果元祖變量只包含原子類型對象,則不能深拷貝

例如:

import copy
a = [1, [1,2]]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
print(b is a, c is a, d is a)
print('判斷copy函數淺拷貝之后,容器內部的對象是不是地址一致:',c[1] is a[1],c[0] is a[0])

a[1][1] = 3
print(a, b, c, d)

輸出:

True False False
判斷copy函數淺拷貝之后,容器內部的對象是不是地址一致: True True
[1, [1, 3]] [1, [1, 3]] [1, [1, 3]] [1, [1, 2]]

python中is和==的區別。

原博文——python中is和==的區別

Python中對象包含的三個基本要素,分別是:id(身份標識)、type(數據類型)和value(值)。

  • ==是python標准操作符中的比較操作符,用來比較判斷兩個對象的value(值)是否相等。

  • is也被叫做同一性運算符,這個運算符比較判斷的是對象間的唯一身份標識,也就是id是否相同。

例如:

a = [1]
c = [1]
print(a == c, a is c)

輸出:

True False
  • 事實上Python 為了優化速度,使用了小整數對象池,避免為整數頻繁申請和銷毀內存空間。而Python 對小整數的定義是 [-5, 257),只有數字在-5到256之間它們的id才會相等,超過了這個范圍就不行了,同樣的道理,字符串對象也有一個類似的緩沖池,超過區間范圍內自然不會相等了。 總的來說,只有數值型和字符串型,並且在通用對象池中的情況下,a is b才為True,否則當a和b是int,str,tuple,list,dict或set型時,a is b均為False。

例如:

a = 2
c = 2
print(a == c, a is c)

輸出:

True True

python中if __ name ==' main __'有什么含義?


python命令和python -m命令在執行腳本時的區別?


python中多進程、多線程、協程。


python中迭代器、生成器。

菜鳥教程——python3迭代器與生成器

迭代器:

  • 迭代是Python最強大的功能之一,是訪問集合元素(字符串、列表、元組、集合、字典)的一種方式。迭代器是一個可以記住遍歷的位置的對象。

  • 迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會后退。(迭代器可以使用for語句進行遍歷

  • 迭代器有兩個基本的方法:iter()next()

實例:

a =[1, 2, 3, 4]
b = iter(a)
print(type(b))
while True:
    try:
        print(next(b))
    except:
        print('over')
        break

輸出:

<class 'list_iterator'>
1
2
3
4
over

生成器:

在 Python 中,使用了 yield 的函數被稱為生成器(generator)。

跟普通函數不同的是,生成器是一個返回迭代器的函數,只能用於迭代操作,更簡單點理解生成器就是一個迭代器。在調用生成器運行的過程中,每次遇到 yield 時函數會暫停並保存當前所有的運行信息,返回 yield 的值, 並在下一次執行 next() 方法時從當前位置繼續運行。調用一個生成器函數,返回的是一個迭代器對象。

實例:

def helper(n):
    i = 0
    while i<n:
        yield i
        i += 1

f = helper(5)
while True:
    try:
        print(next(f))
    except:
        print('over')
        break

輸出:

0
1
2
3
4
over

python中裝飾器。


python中單引號、雙引號、三引號的應用場景與區別。


python如何體現面對對象的三大特性。


python中異常管理的機制。


python函數閉包。


免責聲明!

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



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