基礎篇--【python】面試題匯總


1.盡可能多的列舉PEP8規范有哪些?

  1.   不要在行尾加分號,也不要用分號將兩條命令放在一行
  2.   每行不超過80個字符
  3.   不要使用反斜杠連接行
  4.   在注釋中,如果有必要,將長的url放在一行
  5.   除非用於實現行連接,否則不要在返回語句或條件語句中使用括號
  6.   用4個空格代替代碼縮進,不要使用TAB
  7.   頂級定義之間空2行,方法定義之間空1行

2.ascii,unicode,utf-8,gbk的區別

  ascii 8位 一個字節

  unicode A:32位,四個字節  中文:32位,四個字節

  utf-8 A:8位,一個字節    中文:16位,兩個字節

  gbk A:8位,一個字節   中文:16位,兩個字節

  區別:

    1.各個編碼之間的二進制是不能互相識別的

    2.文件的存儲,傳輸,不能是unicode,只能是utf-8,gbk,ascii

  轉換:

    encode str > bytes 編碼

    decode bytes > str 解碼

3.python遞歸的最大層數是多少以及如何修改

  python默認遞歸最大數為1000,用於防止無限遞歸造成內存溢出奔潰

  修改方法:

    import sys

    sys.setrecursionlimit(1500)  

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

  字節碼是一種中間狀態的二進制代碼,需要直譯器轉譯后才能成為機器碼

5.三元運算符是什么

  三元運算符就是在賦值變量的時候,可以直接加判斷

  res = a if a > b else b

6.列舉python2和python3的區別

  print : 2print語句,3print函數

  輸入函數:2 input_raw() ,3 input()

  super(): 2 必須顯示的在參數中寫上基類,3直接無參數調用即可

  沒有了int和long的區別

  編碼:2 默認ascii,3默認utf-8

  字符串:

    2.unicode表示字符串序列,str表示字節序列

    3.str表示字符串序列,byte類型表示字節序列

  true和false:

    2.可以賦值和操作

    3.不可變

  迭代器:

    2.當中許多返回列表的方法,如range,字典對象的dict.keys(),dict.values()方法,map,filter,zip:並且迭代器必須實現next方法

    3.將返回列表的方法改為了返回迭代器對象,內置了__next__,不用特意去實現next

 

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

  a,b = b,a

8.xrange和range的區別

  range和xrange都是在循環中使用,輸出結果一樣

  range返回一個list對象,xrange返回一個生成器對象

  xrange每次調用返回其中的一個值,內存占用少,性能好

9.字符串,列表,元組,字典各自常用的方法

string:
    去掉空格和特殊符號:
    name1 = name.strip() #去掉兩邊空格
    name2 = name.lstrip() #去掉左邊空格
    name3 = name.rstrip() #去掉右邊空格
    搜索和替換:
    name.count("e") #查找某個字符在字符串中出現的次數
    name.capitalize() #首字母大寫
    name.center(100,"-") #把字符串放中間,兩邊用-補齊到100
    name.find("a") #找到這個字符返回下標,存在多個返回第一個,不存在返回-1
    name.index("a") #找到這個字符返回下標,存在多個返回第一個,不存在報錯
    print(name.replace(name,"123"))  #字符串的替換
    name.replace("abc","123") #返回一個替換后的字符串
    驗證和替換函數:
    name.startswith("abc") #是否以abc開頭
    name.endswith("abc") #是否以abc結尾
    name.isalnum() #是否全十字母和數字,並且至少包含一個字符
    name.isalpha() #是否全是字母,並且至少包含一個字符
    name.isdigit() #是否全是數字,並且至少包含一個字符
    name.isspace() #是否全是空白字符,並且至少包含一個支付
    name.islower() #是否全是小寫
    name.isupper() #是否全是大寫
    name.istitle() #是否首字母大寫
    字符串的分割:
    name.split('') #默認按照空格進行分割,從前往后
    name.rsplit() #從后往前分割

    連接字符串:
    '.'.join(name) #用.號將一個可迭代的序列拼接起來

    切片:

    name1 = name[0:3] #截取第一位到第三位的字符
    name2 = name[:] #截取全部字符
    name3 = name[6:] #截取第6個字符到結尾
    name4 = name[:-3] #截取從開頭到最后一個字符之前
    name5 = name[-1] #截取最后一個字符
    name6 = name[::-1] #創造一個與原字符串順序相反的字符串
    name7 = name[:-5:-1] #逆序截取

列表:
    列表的特性:
    有序集合,通過偏移來索引,從而讀取數據,支持嵌套,可變類型
    
    創建列表:
    list1 = ["1","2","3","4"] #方法1
    list2 = list("1234") #方法2

    添加元素:
    末尾追加:
        list1.append(5)
    指定位置前面插入:
        list1.insert(2,6) #下標為2的前面插入6
    追加一個列表:
        list1.extend([7,8,9])

    遍歷列表:
    直接遍歷:
        for i in list1:
            print(i)
    帶索引遍歷:
        for index,i in enumerate(list1):
            print(i,index)

    通過下標取值:
    print(list1[2])

    刪除元素:
    list1.remove() #參數object,刪除靠前的重復元素,無重復返回None
    list1.pop() #可選參數 index,刪除指定位置的元素,默認為最后一個元素
    del list1[1] #刪除列表或者指定元素或者切片,刪除后無法訪問

    排序和反轉代碼:
    list1.reverse() #反轉列表
    list1.sort() #排序

字典:
    字典是無序的可變序列
    
    創建:
    空字典:
        dict1 = {} 
        dict2 = dict()
    值為None的字典:
        dict3 = dict.fromkeys(['a','b','c'])  ==> {'a':None,'b':None,'c':None}
    通過zip函數構建字典
        dict4 = dict(zip(keyslist,valueslist))
    通過賦值表達式元組構造字典
        dict5 = dict(name='bob',age=22) ==> {'name':'bob','age':22}
    成員關系:
    字典的成員關系只判斷key,與value無關
    列出所有的健,值,鍵值對:
    dict6.keys() #鍵 返回的是可迭代對象
    dict7.values() #值 返回的是可迭代對象
    dict8.items() #鍵值對 返回的是可迭代對象
    拷貝一個字典的副本:
     dict9 = dict8.copy() #淺拷貝
     dict10 = dict8.deepcopy() #深拷貝
    根據鍵獲取值,默認值default
          dict11 = dict12.get(key,default)
    合並更新字典
          dict13.updat(dict12)
    刪除字典
          d.pop(key)
    新增或者修改鍵對應的值
          D[2] = value #如果存在則修改,不存在則創建
    獲取字典鍵的列表,值的列表
          list(D.keys())
          list(D.values())
    字典推導式
          D = [x:x**2 for x in range(10) if x %2 == 0]
    字典使用事項
          序列運算無效,字典是映射機制
          對新索引的賦值會添加新的鍵值對
          鍵不一定總是字符串,但總是不可變對象

元組:
    概述:
        任意對象的有序集合,可以通過序列取值
        元組不可變的序列的操作類型
        固定長度,異構,嵌套(元組里也可以包含元組)
    創建:
        空元組
            t1 = ()
            t2 = tuple()
        單個元素要加,
            x = (40,) ==>一個元組,具有一個元素的值是40

        多元素元組的表達方式
            t = (1,2,3) 
            t1 = 1,2,3 #括號可以省略

        用一個可迭代對象生產元組
            t = tuple('abc')

        元組的訪問
            t[i] t[i][j]

        合並和重復
            t1 + t2
            t1 * 3

        迭代和成員關系
            for x in T:
                print(x)
            'spam' in T

        對元組進行排序
            對元組排序,通常先得將它轉換為列表並使得它成為一個可變對象,或者使用sorted方法,它接收任何序列對象

            T = ('c','a','b','d')
            tmp = list(T)
            tmp.sort() ==> ['a','b','c','d']

            T = tunple(tmp)
            sorted(T)

        為何有了列表還要用元組
            元組可以看成是簡單得對象組合,而列表是隨着時間而改變得數據集合
            元組得不可變性提供了某種完整性,這樣可以確保元組不會被另外一個引用來修改
            元組類似其他語言中的常數聲明

集合
    創建:
        a = set()
        b = set(iterable) #用可迭代對象創建一個集合
    集合的運算:
            & 生成兩個集合的交集 s3 = s1 & s2
            | 生成兩個集合的並集 s3 = s1 | s2
            - 生成兩個集合的補集 s3 = s1 - s2
            ^ 對稱補集 s3 = s1 ^ s2 (只能屬於s1或者s2,也就是去除掉s1和s2重合的部分)

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

  舉例:
        from functools import reduce
        add = lambda x,y:x+y
        print(add(1,2)) # 輸出3

    與map和用,遍歷序列,對序列中每個元素進行操作,獲取最終的新序列
        x = [11,22,33]
        print(list(map(lambda x:x=100,x))) #[111,122,133]

    與filter和用,對序列中的元素進行篩選,最終獲取符合條件的序列
        x2 = [11,22,33]
        print(list(filter(lambda x:x>20,x)))

    與reduce和用,對序列內所有元素進行累計操作
        x3 = [1,2,3,4]
        print(reduce(lambda x1,x2:x1+x2,x3))

11.*arg和**kwarg作用?    

  *arg和**kwarg都是用來傳不固定個數的參數到函數中的    

  *arg :可以理解為只有一列的元組,長度不固定
     **kwarg:可以理解為字典,長度不固定。

    二者可以單獨使用,或者組合使用,一起使用的時候,*arg要放在**kwarg之前。

12.is和==的區別    

  python中對象包含的三個基本要素,分別是:
          id(身份標識)
          type(數據類型)
          value(值)
      對象之間判斷是否相等就需要用到is 或者 ==:

        is 判斷兩個對象的id值是否相等,即兩個對象是否指向同一個內存地址
        == 判斷兩個對象的值是否相等

13.Python的賦值,深淺拷貝以及應用場景?

    import copy
    淺拷貝:copy.copy()
    深拷貝:copy.deepcopy()
    對於數字和字符串而言,賦值,深拷貝和淺拷貝無意義,因為其始終指向同一個內存地址。
    賦值:簡單的拷貝對象的引用,兩個對象的id相同
    淺拷貝指的是創建一個新的對象,僅僅拷貝數據集合的第一層數據,在內存中共享子對象
    深拷貝指的是創建一個新的組合對象,與原對象完全無關,真正獨立。

14.Python垃圾回收機制?

    python垃圾回收算法GC算法,分為以下三點:
        引用計數/標記-清除/分代回收

        引用計數
            對象在被方法引用的時候會自動計數加1,當引用該對象的對象被刪除的時候,那么該對象的引用計數就會減少,一直到它的引用計數變為0,垃圾回收機制就會自動回收。

            優點:
                簡單實用
            缺點:
                維護性高,需要占用額外的資源
                不能解決循環引用的問題

                循環引用:兩個列表相互引用

        標記-清除
            標記-清除就是用來解決循環引用的問題的。
            未來追蹤容器對象,需要每個容器對象維護兩個額外的指針,root鏈表和unreachable鏈表。

            因為unreachable可能存在被root鏈表引用的可能,所以要在標記過程中發現並將其從unreachable鏈表中轉移到root鏈表中,然后剩下的才做真正的回收。

        分代回收

            理論上講,創建量應該與釋放數量相等,但是如果存在循環引用,創建量就會大於釋放量,如果這個差值超出了GC的閾值,那么分代回收機制就會啟動。
            分代回收將對象分為三代:
                0代表幼年對象
                1代表青年對象
                2代表老年對象

            如果在第0代的gc垃圾回收中存活下來,就會進入第1代,第2代同理;
            然后如果在上一次檢查之后,第N代垃圾回收次數大於第N+1代,那么第N+1代就會做垃圾回收檢查。

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

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

16.列舉常見的內置函數?

    反射相關,總共4個
        hasattr 根據字符串的形式 , 去判斷對象中是否有成員
        getattr 根據字符串的形式,去對象中找成員
        setattr 根據字符串的形式 , 動態的設置一個成員(在內存中)
        delattr 用於刪除屬性
            delattr(x, 'foobar') 相等於 del x.foobar
    基礎數據類型相關,總共38個
        bool,int,float,complex(復數),bin(整型轉換為二進制),oct(整型轉換為八進制),hex(整型轉換為十六進制),abs(求絕對值),divmod(除,余數),round(值,小數后幾位),pow(冪運算),sum,max,min,list,tuple,reversed,slice,str,format,bytes,bytearry,memoryview,ord,chr,ascill,repr,dict,set(),frozenset,len,sorted,enumerate,all,any,zip,filter,map
    作用域相關
        locals 獲取執行本方法所在命名空間內的局部變量的字典
        globals 獲取全局變量的字典

    面向對象相關
        type 元類,類的最高層
        object
        classmethod  類方法,用來修改類變量
        staticmethod 類方法,用來處理一些和操作類無關的事
        propery    可以像調用一個變量一樣調用一個方法
        vars
        super    在多繼承中,可以保證頂層父類只被調用一次 ,用 _ _mro_ _ 查看多繼承規律時,遵循深度優先原則
        issubclass    檢查第一個參數是否是第二個參數的子子孫孫類  
        isinstance    檢查第一個參數(對象) 是否是第二個參數(類及父類)的實例.
    迭代/生成器相關
        next
        iter
        range    range 是一個生成器,他只用來存儲數據的生成方式,而不直接存儲數據

    其他
        eval    將字符串類型的代碼執行並返回結果
        exec    將自字符串類型的代碼執行
        compile
        input
        print
        id
        hash
        open
        __import__
        help
        callable     檢測一個對象能否被調用
        dir 查看內置屬性和方法

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

    pip install django  #通過pip安裝
    pip install -i https://pypi.douban.com/simple django  #通過豆瓣源加速安裝
    python setup.py build # 源碼下載解壓
    python setup.py install

    #常用第三方庫
    pillow #圖像相關的處理庫
    Scrapy # 一個快速,高級的屏幕抓取以及web爬蟲框架
    requests #一個關於http請求的優秀開源庫
    beautifulsoup # xml和html的解析庫,比較慢,效率很低

18.re的match和search區別?

    match()函數只檢測RE是不是在string的開始位置匹配,search()會掃描整個string查找匹配;

19.什么是正則的貪婪匹配?

    總是嘗試匹配盡可能多的字符,對應格式:xx*xx

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

    函數的第二個默認參數是一個list,當第一次指向的時候實例化了一個list,第二次執行還是用第一次執行的時候實例化的地址存儲。,默認參數應該設置為None


免責聲明!

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



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