1. 程式人生 > >Python 面試題收集

Python 面試題收集

  1. python中is和==的區別
    1. Python中物件包含的三個基本要素,分別是:id(身份標識) 、type(資料型別)和value(值)。
    2. ‘==’比較的是value值
    3. ‘is’比較的是id
       
  2. 簡述read、readline、readlines的區別
    1. read讀取整個檔案
    2. readline讀取下一行資料
    3. readlines讀取整個檔案到一個迭代器以供我們遍歷(讀取 到一個list中,以供使用,比較方便)
  3. 舉例說明建立字典的至少兩種方法
     

    # 1

    dict1 = {key1:v1,key2:v2}

    # 2

    dict2 = {}

    dict2[key1] = v1

    dict2[key2] = v2

    # 3

    dict3 = dict(key1=v1,key2=v2)

  4. *args,**kwargs的作用是什麼?如何使用?                                                                           
           *args和**kwargs通常使用在函式定義裡,*args允許函式傳入不定量個數的非關鍵字引數,**kwargs允許函式傳入不定量個數的關鍵字引數
  1. python中match()和search()的區別?
    1. match()函式只檢測RE是不是在string的開始位置匹配, search()會掃描整個string查詢匹配, 也就是說match()只有在0位置匹配成功的話才有返回,如果不是開始位置匹配成功的話,match()就返回none
  2. 一個函式接收資料夾的名稱作為引數,返回該檔案中所有檔案的全路徑,請補全缺失的程式碼。
 

def print_directry_contents(spath):

import os

files_list = os.listdir(spath)

for file in files_list:

print(os.path.realpath(file))

  1. 閱讀下面的程式碼,寫出A0,A1至An的最終值
 

A0 = dict(zip(('a','b','c','d','e'),(1,2,3,4,5)))

A0 = {'a':1,'b':2,'c':3,'d':4,'e':5}

A1 = range(10)

A1 = [0,1,2,3,4,5,6,7,8,9]

A2 = [i for i in A1 if i in A0]

A2 = [] # 當對字典進行in判斷是,判斷的是key

A3 = [A0[s] for s in A0]

A3 = [1,2,3,4,5]

A4 = [i for i in A1 if i in A3]

A4 = [1,2,3,4,5]

  1. 請寫一段程式碼實現Python中list去重。
 

# 方法1

list1 = [1,1,2,3,3,4]

set1 = set(list1)

list1 = list(set1)

# 方法2

list2 = []

for i in list1:

if i not in list2:

list2.append(i)

  1. 建立一個裝飾器將下面函式輸入的字串首字母大寫。
 

def greetins(word='hi there'):

return word.lower()

from functools import wraps

def start_word_upper(func):

@wraps(func)

def inner(*args,**kwargs):

word = func(*args,**kwargs)

return word.capitalize()

return inner

# 裝飾器可以在:

# 1.函式呼叫之前對函式引數進行操作,直接返回被裝飾函式的返回值

# 2.對返回值進行‘裝飾’並返回(本題案例)

  1. 描述yield作用。
    1. 儲存當前執行狀態(斷點),然後暫停執行,即將函式掛起
    2. 將yeild關鍵字後面表示式的值作為返回值返回,此時可以理解為起到了return的作用,當使用next()、send()函式讓函式從斷點處繼續執行,即喚醒函式。
  2. 裝飾器。
    1. 裝飾器本質上是一個Python函式,它可以讓其他函式在不需要做任何程式碼變動的前提下增加額外功能,裝飾器的返回值也是一個函式物件。
    2. 功能:1.引入日誌;2.函式執行時間統計;3.執行函式前預備處理;4.執行函式後清理功能;5.許可權校驗;6.快取
  3. 你對多執行緒和多程序的理解。
    1. 程序是系統進行資源分配和排程的一個獨立單位,執行緒是程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位.執行緒自己基本上不擁有系統資源,只擁有一點在執行中必不可少的資源(如程式計數器,一組暫存器和棧),但是它可與同屬一個程序的其他的執行緒共享程序所擁有的全部資源;
    2. 一個程式至少有一個程序,一個程序至少有一個執行緒;
    3. 執行緒的劃分尺度小於程序(資源比程序少),使得多執行緒程式的併發性高;
    4. 程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行效率 ;
    5. 線執行緒不能夠獨立執行,必須依存在程序中;
    6. 優缺點:執行緒和程序在使用上各有優缺點:執行緒執行開銷小,但不利於資源的管理和保護;而程序正相反。
  4. 執行緒中start方法和run方法的區別?
    1. 若呼叫start,則先執行主程序,後執行子程序;
    2. 若呼叫run,相當於正常的函式呼叫,將按照程式的順序執行
  5. linux命令 grep awk sed是怎麼用的?
    1. grep:Global Regular Expression Print
    2.  
  6. python是怎麼進行記憶體管理的?
    1. 引用計數:python內部使用引用計數,來保持追蹤記憶體中的物件,Python內部記錄了物件有多少個引用,即引用計數,當物件被建立時就建立了一個引用計數,當物件不再需要時,這個物件的引用計數為0時,它被垃圾回收。
      1. 引用計數加1的情況:
        1. 物件被建立:x=4
        2. 另外的別人被建立:y=x
        3. 被作為引數傳遞給函式:foo(x)
        4. 作為容器物件的一個元素:a=[1,x,'33']
      2. 引用計數減少情況
        1. 一個本地引用離開了它的作用域。比如上面的foo(x)函式結束時,x指向的物件引用減1。
        2. 物件的別名被顯式的銷燬:del x ;或者del y
        3. 物件的一個別名被賦值給其他物件:x=789
        4. 物件從一個視窗物件中移除:myList.remove(x)
        5. 視窗物件本身被銷燬:del myList,或者視窗物件本身離開了作用域
    2. 垃圾回收
      1. 當記憶體中有不再使用的部分時,垃圾收集器就會把他們清理掉。它會去檢查那些引用計數為0的物件,然後清除其在記憶體的空間。當然除了引用計數為0的會被清除,還有一種情況也會被垃圾收集器清掉:當兩個物件相互引用時,他們本身其他的引用已經為0了。
      2. 垃圾回收機制還有一個迴圈垃圾回收器, 確保釋放迴圈引用物件(a引用b, b引用a, 導致其引用計數永遠不為0)。
    3. 記憶體池機制:在Python中,許多時候申請的記憶體都是小塊的記憶體,這些小塊記憶體在申請後,很快又會被釋放,由於這些記憶體的申請並不是為了建立物件,所以並沒有物件一級的記憶體池機制。這就意味著Python在執行期間會大量地執行malloc和free的操作,頻繁地在使用者態和核心態之間進行切換,這將嚴重影響Python的執行效率。為了加速Python的執行效率,Python引入了一個記憶體池機制,用於管理對小塊記憶體的申請和釋放。
      1. Python提供了對記憶體的垃圾收集機制,但是它將不用的記憶體放到記憶體池而不是返回給作業系統。
      2. Python中所有小於256個位元組的物件都使用pymalloc實現的分配器,而大的物件則使用系統的 malloc。另外Python物件,如整數,浮點數和List,都有其獨立的私有記憶體池,物件間不共享他們的記憶體池。也就是說如果你分配又釋放了大量的整數,用於快取這些整數的記憶體就不能再分配給浮點數。
  7. 什麼是lambda函式?他有什麼好處? lambda函式是匿名函式;使用lambda函式能夠建立小型匿名函式。這種函式得名於省略了用def宣告函式的標準步驟; 例:
    f = lambda x,y:x+y # 求兩個函式的和。 x,y是引數,x+y是函式返回值
  8. python中tuple和list的轉換
 

# tuple ---> list

tuple1 = (1,2,3)

list1 = list(tuple1)

# list ---> tuple

list2 = [1,2,3]

tuple2 = tuple(list2)

  1. python中如何拷貝一個物件?(賦值,淺拷貝,深拷貝的區別)
    答:賦值(=),就是建立了物件的一個新的引用,修改其中任意一個變數都會影響到另一個。

    淺拷貝:建立一個新的物件,但它包含的是對原始物件中包含項的引用(如果用引用的方式修改其中一個物件,另外一個也會修改改變){1,完全切片方法;2,工廠函式,如list();3,copy模組的copy()函式}

    深拷貝:建立一個新的物件,並且遞迴的複製它所包含的物件(修改其中一個,另外一個不會改變){copy模組的deep.deepcopy()函式}

  2. 介紹一下except的用法和作用?

     

    try:

    pass

    except Exception as e:

    print(e)

    finally:

    pass

    捕獲try except中間程式碼發生的異常,如果發生異常執行except的程式碼,不管是否發生異常都執行finally中的程式碼

    except可以有0個或多個,如果有多個從上到下依次根據異常型別匹配,匹配某個Exception這執行對應的except中程式碼

  3. 用python匹配HTML tag的時候,<.*>和<.*?>有什麼區別?

    1. <.*>匹配結果是:HTML tag;
    2. <.*?>匹配到的結果是:""。 ? 表示非貪婪,搜到符合的結果既返回
  4. 有沒有一個工具可以幫助查詢Python的bug和進行靜態的程式碼分析?

    • PyChecker是一個python程式碼的靜態分析工具,它可以幫助查詢python程式碼的bug, 會對程式碼的複雜度和格式提出警告

    • Pylint是另外一個工具可以進行codingstandard檢查

  5. 請寫一段指令碼,查詢/data/test 目錄下3天前的檔案,從中挑選出大小超過10M的刪除掉。

 

#!/bin/sh

find "/data/test" -mtime +3 -size +10M -exec rm {} \

  1. 請寫一段python程式碼,替換掉目標字串中的[北京市,技術,有限,公司]等字元,比如:目標字串:北京市麥達技術數字有限公司,要求替換輸出 麥達數字。
 

str1 = "北京市麥達技術數字有限公司"

str2 = str1.replace("北京市","").replace("技術","").replace("有限","").replace("公司","")

  1. 有三張表分別存放省市(province),地市(city)和縣區(area)的名稱和編碼,表名如下表格:
省份表 Province 地市表 City 縣表 Area
province_id 省編號 city_id 市編號 area_id 縣區編號
province city 城市名 area 區縣名稱
    province_id 省編號 city_id 市編號

請寫出一段sql語句,挑選出江蘇省的地市和區縣。
輸出這樣:
  南京市 秦淮區
  南京市 玄武區
  ···
  徐州市 鼓樓區
  徐州市 沛縣

 

select City.city,Area.area from City inner Area on City.city_id = Area.city_id where
City.province_id = (select province_id from Province where province = "江蘇省")

25.有一個純字串,編寫一段程式碼,列出其所有字元的大小寫組合
如 :字串“ji”,字母組合['ji','jI','Ji','JI']
即每個字元的大小寫組合

 

def word_group(word):

word = word.lower()

dict = {}

list = []

for letter in word:

if not dict:

list.append(letter)

list.append(letter.upper())

dict[word.index(letter)] = list

else:

list = []

for i in dict[word.index(letter)-1] :

list.append(i + letter)

list.append(i+ letter.upper())

dict[word.index(letter)] = list

print(dict[len(word)-1])

 

  1. 簡述一下你熟悉的NOSQL,它有什麼優點和缺點?
    redis:

優點:

 
  1. - 讀寫效能優異;

  2. - 支援資料持久化,支援AOF和RDB兩種持久化方式;

  3. - 支援主從複製,主機會自動將資料同步到從機,可以進行讀寫分離;

  4. - 資料結構豐富:除了支援string型別的value外還支援string、hash、set、sortedset、list等資料結構。

缺點:

 
  1. - Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復;

  2. - 主機宕機,宕機前有部分資料未能及時同步到從機,切換IP後還會引入資料不一致的問題,降低了系統的可用性;

  3. - Redis的主從複製採用全量複製,複製過程中主機會fork出一個子程序對記憶體做一份快照,並將子程序的記憶體快照儲存為檔案傳送給從機,這一過程需要確保主機有足夠多的空餘記憶體。若快照檔案較大,對叢集的服務能力會產生較大的影響,而且複製過程是在從機新加入叢集或者從機和主機網路斷開重連時都會進行,也就是網路波動都會造成主機和從機間的一次全量的資料複製,這對實際的系統運營造成了不小的麻煩;

  4. - Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。為避免這一問題,運維人員在系統上線時必須確保有足夠的空間,這對資源造成了很大的浪費。

  1. 使用一個正則表示式設計一個程式,將字串"<a href=www.baidu.com>正則表示式題庫</a><a href=www.cdtest.cn></a>"的www.baidu.com和www.cdtest.cn同時匹配出來。
 

import re

str = "\<a href=www.baidu.com\>正則表示式題庫\</a>\<a href=www.cdtest.cn\>\</a>"

regex = r"href=(.*?)>"

ret_list = re.findall(regex,str)

  1. 設計一個程式,求出1+3!+5!+7!+9!+50!的和。
 

# 求1+3!+5!+7!+9!

m = 0

for i in range(1,6):

n = 1

for j in range(1,2*i):

n = n*j

m += n

# 求50!

l = 1

for x in range(1,51):

l = l*x

# 和

sum = m+l

print(sum)

  1. 把字串“HELLO PYTHON”從大寫字母全部轉換成小寫字母並換行顯示,然後輸出到計算機c盤的hello.txt檔案中儲存。
 

str = 'HELLO PYTHON'

with open(r'C:/hello.txt','a') as f:

for letter in str:

letter = letter.lower()

f.write(letter)

f.write('\n')

  1. 設計一個小程式,採用任意資料結構方法,輸入年、月、日後能判定當前日期在本年是第幾天。
 

def judge_dayth(y=None,m=None,d=None):

# 判斷是否是潤年

if y%4==0 and y%100!=0 or y%400==0:

m_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

else:

m_list = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

if m == 1:

dayth = d

else:

m_days = 0

for i in range(m-1):

m_days += m_list[i]

dayth = m_days + d

print(dayth)

  1. 給定一個值為整數的陣列int_array,找出int_array中第二大的整數。
    說明:如果最大的整數在int_array中出現不止一次,則最大整數為第二大整數。
    例:
    輸入:[1,2,3,4,5]
    輸出:4
    輸入:[5,5,4,4,3]
    輸出:5
 

import json

def find_max(int_array):

max_int = 0

for i in int_array:

if i > max_int:

max_int = i

return max_int

int_array = json.loads(input()) # 將字串轉化為列表

max_int = find_max(int_array)

int_array.remove(max_int)

max_int = find_max(int_array)

print(max_int)

  1. 使用python將字串“1.2.3.4.5”轉換為字串“5|4|3|2|1”
 

str = "1.2.3.4.5"

li = str.split(".") # li = [1,2,3,4,5]

# 列表倒序

li = li[::-1] # li = list(reversed(li)) 或者 li = sorted(li,reverse=True)

# 字串拼接

str = "|".join(li)

  1. 請分別描述python2.x和python3.x中import包時的路徑搜尋順序

    import sys

    sys.path # 檢視搜尋路徑

  2. 用Python的正則表示式匹配時間資訊。

    import re

    data_info = "現在的時間是:2018-3-10 11:52"

    regex = r"\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{2}"

    ret = re.search(regex,data_info).group

    print(ret)

  3. 使用python編寫一個裝飾器,列印被裝飾函式的輸入與輸出。

    from functools import wraps

    def print_io(func):

    @wraps(func)

    def inner(*args,**kwargs):

    print("函式的輸入:{}".format(*args,**kwargs))

    ret = func(*args,**kwargs)

    print("函式的輸出:{}".format(ret))

    return ret

    return inner

  4. 闡述range和xrange的區別,並且用Python仿寫xrange函式。                                                                Python 2.x 中:
    range 函式說明:range([start,] stop[, step]),根據start與stop指定的範圍以及step設定的步長,生成一個序列。
    xrange 函式說明:用法與range完全相同,所不同的是生成的不是一個數組,而是一個生成器。  python 3.x中:
    已經將xrange函式刪除,range函式同Python2.x 中的xrange函式用法相同

    def xrange(*args,**kwargs):

    for i in range(*args,**kwargs):

    yield i

  5. 列舉幾種你曾經常用的python包並且解釋其功能及用法

    os模組:os模組包裝了不同作業系統的通用介面,使使用者在不同作業系統下,可以使用相同的函式介面,返回相同結構的結果。

    sys模組:給命令列傳參

    time、re、requests...

    # 我覺得這個題的根據要應聘的崗位填一些對應的模組,比方說爬蟲方向就寫requests,lxml,selenium...

  6. 合併列表a=[1,2,3,4]和b=[5,6,7,8]

    a.extend(b)

  7. 列表a,請寫出實現正序排列,倒序排列,逆序排列的內建方法。

    # 正序

    a.sort()

    # 倒序

    a.sort(reverse=Ture)

    # 逆序

    a.reverse()

  8. 字典d={"k":1,"v":2},請寫出d.items()的結果。

    dict_items([("k",1),("v",2)])

  9. 複雜列表[{"k":1,"v":2},{"k":12,"v":22},{"k":13,"v":32}],請用內建方法寫出k的倒序排列的程式碼。

    li = [{"k":1,"v":2},{"k":12,"v":22},{"k":13,"v":32}]

     

    li.sort(key=lambda dict:dict["k"],reverse=True)

     

    print(li)

  10. 集合s = set([1,2,3,4]),d = set([2,4,9,0,3]),請用內建方法寫出它們的並集,交集,對稱公差。

    # 交集

    s|d # {2, 3, 4}

    # 並集

    s&d # {0, 1, 2, 3, 4, 9}

    # 對稱差集

    s^d # {0, 1, 9}

  11. 請隨機輸出一個大於0小於1的數;請隨機輸出一個100以內的整數。

    import random

    print(random.random()) # 0<1

    print(random.randint(1,100)) # 100以內整數

  12. 長度未知的元組a=(1,3,4,5,6,...),請隨機輸出n項

    import random

    a=(1,3,4,5,6,...)

    a = list(a)

     

    for i in range(n):

    b = a[random.randint(0,len(a))-1]

    print(b)

    a.remove(b)。

  13. 程式碼a=[{i:j} for i,j in enumerate(range(5))],請寫出a的最終結果。

    a = [{0:0},{1:1},{2:2},{3:3},{4:4}]

    # enumerate()函式:列舉、列舉,返回一個可迭代物件的索引和索引對應的值

  14. 分別說說cmp,map,filter的作用?

    # cmp:compare比較

    cmp(a,b) # a<b 返回-1 a>b 返回1 a=b返回0

     

    # map:對映

    map(function, iterable) # 將function作用於iterable,每個元素,將對應輸出結果儲存為一個list

    # 例:

    def plus_one(x):

    return x+1

    map(plus_one,[1,2,3,4]) ===>[2,3,4,5]

     

    # filter:過濾器

    filter(function, iterable) # 將 function依次作用於iterable的每個元素,如果返回值為true, 保留元素,否則從iterable裡面刪除

    # 例:

    def bigger_than_three(x):

    return (x>3)

    filter(bigger_than_three,[1,2,3,4,5]) ===>[4,5]

  15. 請闡述__new__和__init__的區別?

    __new__:建立物件時呼叫,會返回當前物件的一個例項

    __init__:建立完物件後呼叫,對當前物件的一些例項初始化,無返回值

    呼叫順序:先呼叫__new__生成一個例項再呼叫__init__方法對例項進行初始化,比如新增屬性。

  16. 寫一段程式碼實現單例模式。

    class Singleton(object):

    def __new__(cls):

    # 關鍵在於這,每一次例項化的時候,我們都只會返回這同一個instance物件

    if not hasattr(cls, 'instance'):

    cls.instance = super(Singleton, cls).__new__(cls)

    return cls.instance

  17. 用yield寫出一個生成器。

    def generator():

    for i in range(5):

    yield i

  18. 說明os、sys模組不同,並列舉常用的模組方法。https://www.cnblogs.com/mako/p/4890676.html
  19. @classmethod、@staticmethod、@property都是啥意思?

    @classmethod:類方法,類方法是給類用的,類在使用時會將類本身當做引數傳給類方法的第一個引數,python為我們內建了函式classmethod來把類中的函式定義成類方法。

    @staticmethod:靜態方法

    @property:將一個例項方法提升為屬性,便於訪問

  20. 請解釋一下Gevent和threading/multiprocessing的關係。
  21. 請解釋一下cookie和session的關係,以及csrf的攻擊和防範方法。
    • cookie儲存在瀏覽器端,session儲存在伺服器端,但是為了區分不同的客戶端,伺服器會在瀏覽器中傳送一個對應的sessionid儲存到cookies中,下次瀏覽器請求伺服器的時候會將sessionid一併傳送給伺服器。所以session機制依賴於cookie機制。
    • csrf攻擊:cross site request forgery 跨站請求偽造
      • 原理:
        • 1.User(C)訪問信任網站Web(A),Web(A)會在User(C)處設定A的cookie;
        • 2.User(C) 在沒有登入A的情況下,訪問危險網站Web(B),B要求User(C)訪問Web(A);
        • 3.User(C)在Web(B)的要求下,帶著Web(A)的cookie訪問Web(A),這樣Web(B)就達到了模擬使用者操作的目的
      • 防禦:
        • 1.通過 referer、token 或者 驗證碼 來檢測使用者提交。
        • 2.儘量不要在頁面的連結中暴露使用者隱私資訊。
        • 3.對於使用者修改刪除等操作最好都使用post 操作 。
        • 4.避免全站通用的cookie,嚴格設定cookie的域。
  22. 描述對super,pass,yield,lambda關鍵字修飾的理解。

    - super:在繼承中充當父類的代理物件,在多繼承中,super的呼叫順序是MRO的順序。

    - pass:空語句,什麼也不做,在特別的時候用來保證格式或是語義的完整性。

    - yield:

    - 1.儲存當前執行狀態(斷點),然後暫停執行,即將函式掛起

    - 2.將yeild關鍵字後面表示式的值作為返回值返回,此時可以理解為起到了return的作用,當使用next()、send()函式讓函式從斷點處繼續執行,即喚醒函式。

    - lambda:定義匿名函式

轉載:https://blog.csdn.net/weixin_40862231/article/details/79504455?utm_source=copy 如有侵權,請聯絡刪除