1. 程式人生 > >python面試題目彙總

python面試題目彙總

參考:https://www.cnblogs.com/JetpropelledSnake/p/9396511.html#_label1

1、常見的PEP8規範?

縮排:4個空格

空行:函式與函式之間空兩行,類內部的函式之間空一行

命名:
1、函式名小寫,可採用下劃線加字母;類名單詞第一個字母大寫,採用駝峰式命名;
2、命名必須有意義,可識別性,不能重複;

長度:每行長度不能超過79,可以採用下劃線隔開並另起一行

空格:逗號之後和操作符前後採用空格隔開;

import:不要一次匯入多個不是一個型別的庫;

常量採用大寫

2、進位制之間轉換?

bin:十進位制轉二進位制,例如 bin(10)=0b1010
oct:十進位制轉八進位制, octonary number system(八進位制)
hex:十進位制轉十六進位制,hexadecimal
int:將對應的進位制轉換成十進位制
手動轉換參考:

https://jingyan.baidu.com/article/495ba84109665338b30ede98.html

3、請編寫一個函式實現將IP地址轉換成一個整數?

def convert_to_int(ip):
    lst = [int(item) for item in ip.split('.') if item]
    return sum(lst) 

4、python最大遞迴層數?996

def foo(n):
        print(n)
        n += 1
        foo(n)

    if __name__ == '__main__':
        foo(1)

5、and or or?

x or y:若x為真,則為x,否則為y;
x and y:若x為真,則為y,反之為x。
x and y or z:等價於 x and (y or z)

6、按位運算子:

二進位制下運算子號。
&:按位與,都為1則為1
例如 print(10&8)=0b1010 & 0b1000 = 0b1000 = 8

|:有一個為真則為真

:當兩個對應的二進位制相異時,則結果為1,例如print(10^8)=0b0010=2

7、ascii、unicode、utf8、gbk的區別?

都是編碼型別,都包含二進位制與字元的對應關係。
ascii:僅僅包含 阿拉伯字母以及某些運算子與二進位制的對應關係,最早的編碼型別,但最多隻能表示一個位元組。

unicode:全球通用的編碼,包含所有字元與二進位制的對應關係;任何字元==2Bytes,所以用來儲存英文字元浪費空間。

gbk:本國語言與二進位制的對應關係,每個國家都有自己的GBK編碼,沒有統一起來。一箇中文字元2Bytes,一個英文字元1Bytes。

utf8:unicode的升級版本,一箇中文字元3Bytes,英文字元1Bytes,歐洲字元==2Bytes。

8、位元組碼和機器碼的區別?

機器碼:Native code,原生碼,cpu可以直接解讀的資料,執行速度最快;
位元組碼:Byte-code中間狀態的二進位制程式碼(檔案),需要直譯器轉譯才難成為機器碼。

9、is 和 ==?

is比較的是記憶體地址,可以用id()檢視;
==比較的是 值是否相等。

10、可變資料型別和不可變資料型別?

可變資料型別:該資料型別對應的變數的值發生改變,那麼它對應的記憶體地址也會發生改變。例如:list、dict、set。
不可變資料型別:該資料型別對應的值發生改變,它對應的記憶體地址不會發生改變,例如:str,int,float,tuple。

12、小資料池子

int和str,都存在一個小資料池,在這個範圍內,若變數值相同,都會指向同一個記憶體地址。

int小資料池:int在【-5,256】範圍內,建立相同的數字會指向同一個記憶體地址,超過了這個範圍,就會指向不同的地址。

字串小資料池範圍:
1、不能有空格:若有空格,則指向兩個記憶體地址;
2、不能包含特殊字元,若包含特殊字元,則指向兩個記憶體地址。

12、三元運算寫法以及應用場景?

結構:結果1 + if + 條件 + else + 結果2,若條件為True,則返回結果1,反之返回結果2。

13、py2和py3的區別?

print格式不同。

range()不同:在py2中是range是列表,xrange才是生成器,在py3只有range且是生成器。

預設編碼不同:py2的預設編碼是ascii,py3的預設編碼是utf8。

14、一行程式碼實現數值交換?

a,b=b,a

15、列舉布林值為False的常見值?

可以通過三元表示式判斷,例如:'true' if 1 else 'else'
數字型別:0為False,其餘的為True
None為False
列表、tupe、字典、set等:長度為0為false

16、list、str、tuple、dict每個常用的5個方法?

str:字串為不可變型別,沒有增刪改查
    統計:
        count(s):統計s出現的次數

    查詢:
        index(s):在指定的索引範圍內從左到右找出元素s的索引並返回;
        find(s,begin,end):同index方法;

    格式輸出:
        lower():將字母改為小寫格式;
        upper():將字母改為大寫格式;
        capitalize():將首個字母改為大寫;
        strip():刪除字串兩側的空格並返回,但是不改變原字串;
        format():
            In [32]: '{}-{}-{}'.format('alex','kate','bo')                                  
            Out[32]: 'alex-kate-bo'

            In [33]: '{1}-{0}-{2}'.format('alex','kate','bo')                               
            Out[33]: 'kate-alex-bo'
        swapcase(): 大小寫反轉。

    型別轉換:
        s.split(sep):轉換成列表

    替換:
        s.replace(old,new)

    判斷is系列:
        isdigits()
        isalpha()
        isnumeric()
        islowe()
        isupper()

    判斷開頭和結尾:
        startwith(s)
        endwith(s)


list:可變資料型別,可以進行增刪改查
    建立列表:list('iterable')

    增加:
    append(s):在列表右側追加元素;
    extend(iterable):迴圈可迭代物件並新增到列表中,例如:[1].extend('abcd')=[1,'a','b','c','d'];

    刪除:
    pop(index):根據index刪除元素並返回index;
    clear():刪除所有元素;
    remove(s):從左至右刪除找到的第一個元素,沒找到匹配的元素則ValueError異常;

    統計:
    count(s):統計s出現的次數

    排序:
    sort(reverse=False):升序,可以指定為降序
    reverse():僅僅顛倒當前列表順序


字典dict:
    建立字典:
        {}.fromkeys(iterable,val)

    增加或修改:
        d.update({'k1':'v2'}):若字典d存在鍵k1,則更新其值為v2;若不存在鍵k1,則增加鍵值對;
        d.setdefault('k1','v2'):若字典d存在k1,則返回其對應的值,若不存在,則增加鍵值對{'k1':'v2'}

    刪除:
        d.pop('k1'):若k1存在,則刪除該鍵值對,並返回value;若不存在,則報KeyError異常。       
        d.clear():清空字典;
        d.popitem():隨機刪除鍵值對;

    查詢:
        get('k1','not found')
        d.keys():結構類似[k1,k2,k3],主要這個不是列表,還需要經過轉換才難成為列表
        d.values():結構類似[v1,v2,v3]
        d.items():返回結構類似 [(k1,v2),(k2,v2)]


tuple元組:不可變資料型別
    建立字典:tuple(iterable)
    統計:
        count(s)
        index(s)

集合set:無序,且不重複
    增加:
        add(item)
        s.update(s1)
        s.union(s1)

    刪除:
        discard(item)
    
    差集:
        s1中但是s2中沒有的元素:s1.difference(s2) == s1 - s2  

    交集:
        s1.intersection(s2)

    也可以運用 +、- 運算子。

17、lambda表示式以及應用場景?

函式名=lambda 引數(多個時以逗號隔開):返回值
f=lambda x, y : x*y
引數可以有多個,且只能寫一行。

18、pass的作用?

保證程式結構完整,無其他任何作用。

19、*args 和 **kwargs作用?

在函式不確定有多少個引數時候,可以採用可變引數。
*args會將接收到的所有的位置引數轉換成列表格式,存放在函式內部作用域內;
**kwargs會將接收到的鍵值對引數轉換成字典格式,存放在函式內部作用域內。

20、深淺拷貝:

淺拷貝只是增加了一個指標指向一個存在的記憶體地址。
而深拷貝是增加了一個指標並且重新開闢一個記憶體空間。

單層
import copy
# 淺拷貝
li1 = [1, 2, 3]
li2 = li1.copy()
li1.append(4)
print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3,4]
 
# 深拷貝
li1 = [1, 2, 3]
li2 = copy.deepcopy(li1)
li1.append(4)
print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3]


#多層
import copy 
# 淺拷貝 指向共有的地址
li1 = [1, 2, 3,[4,5],6]
li2 = li1.copy()
li1[3].append(7)
print(li1, li2)  # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5, 7], 6]
 
# 深拷貝 重指向
li1 = [1, 2, 3,[4,5],6]
li2 = copy.deepcopy(li1)
li1[3].append(7)
print(li1, li2)  # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5], 6]

21、python垃圾回收機制?

參考:
http://www.cnblogs.com/Xjng/p/5128269.html
http://python.jobbole.com/87843/

1、引用計數:
python裡每一個東西都是物件,當物件多了一個引用,則此物件的(PyObject)的計數變數(ob_refcnt)+1,反之-1,
當ob—refcnt=0,此物件會被系統回收;
迴圈引用:
當物件A和B相互引用,但是沒有外部再引用它們任何一個,它們的引用計數雖然都為1,但顯然應該被回收。

2、標記清除:
解決迴圈引用的問題,主要是list、set、dict、instance等容器物件,步驟:
I、先標記上所有活動物件
II、再將所有未活動的物件清除

怎麼標記?
從根物件(全域性變數、呼叫棧、暫存器)出發,以引用作為線,來連線記憶體中的物件。
缺點:簡單粗暴,清除非活動物件前必須順序掃描整個堆記憶體。

3、分代回收:
將記憶體根據物件存活的時間由短到長分為三代:年輕代、中年代、老年代,垃圾回收頻率以此減少,所以老年代的物件可能存活於系統的整個記憶體空間。
以空間換時間,具體步驟如下:
新建立的物件會被存放在年輕代,當連結串列總數(gc計數器)達到上限時,會觸發垃圾回收(gc.collect),將那些非活動物件和迴圈引用的物件回收,將剩餘的活動物件轉移到中年代,以此類推。

22、匿名函式的應用?

題目1:求結果

def multipliers():
    # 返回包含四個匿名函式的列表
    return [lambda x:i*x for i in range(4)]
    # 注意,若返回生成器,則結果未[0,2,4,6]

print([m(2) for m in multipliers()])

由於函式未被呼叫,迴圈中的i值未被寫入函式,經過多次替代,迴圈結束後i值為3,
故結果為:6,6,6,6

題目2:現有兩個元組(('a'),('b')),(('c'),('d')),請使用python中匿名函式生成列表[{'a':'c'},{'b':'d'}]