天天看點

python面試題彙總(下)

前言

  我們上篇文章為大家介紹了Python常見的部分面試題,今天的文章給大家吧剩下的常見的面試題全部介紹給大家,希望能夠幫到大家。

  • 一、Python如何實作單例模式?
  Python有三種方式可以實作單例模式,首先就是通過子產品。其實,Python 的子產品就是天然的單例模式,因為子產品在第一次導入時,會生成 .pyc 檔案,當第二次導入時,就會直接加載 .pyc 檔案,而不會再次執行子產品代碼。是以,我們隻需把相關的函數和資料定義在一個子產品中,就可以獲得一個單例對象了。如果我們真的想要一個單例類,可以考慮這樣做:
class Singleton(object):
    def foo(self):
        pass
singleton = Singleton()
      
  将上面的代碼儲存在檔案 mysingleton.py 中,要使用時,直接在其他檔案中導入此檔案中的對象,這個對象即是單例模式的對象,即:from a import singleton。其次是使用裝飾器,具體使用如下:
def Singleton(cls):
    _instance = {}

    def _singleton(*args, **kargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kargs)
        return _instance[cls]

    return _singleton
@Singleton
class A(object):
    a = 1
    def __init__(self, x=0):
        self.x = x
a1 = A(2)
a2 = A(3)
      

  另外使用類,具體實作如下:

class Singleton(object):

    def __init__(self):
        pass

    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance
      

  一般情況,大家以為這樣就完成了單例模式,但是這樣當使用多線程時會存在問題。具體實作如下:

class Singleton(object):
    def __init__(self):
        pass
    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance
import threading
def task(arg):
    obj = Singleton.instance()
    print(obj)
for i in range(10):
    t = threading.Thread(target=task,args=[i,])
    t.start()
      

  具體的執行結果如下:

python面試題彙總(下)
  • 二、Python是如何進行類型轉換的?
  Python提供了将變量或值從一種類型轉換成另一種類型的内置函數。int函數能夠将符合數學格式數字型字元串轉換成整數。否則,傳回錯誤資訊。
  • 函數int也能夠把浮點數轉換成整數,但浮點數的小數部分被截去
  • 函數float将整數和字元串轉換成浮點數
  • 函數str将數字轉換成字元

      整數1和浮點數1.0在python中是不同的。雖然它們的值相等的,但卻屬于不同的類型。這兩個數在計算機的存儲形式也是不一樣。具體案例如下:

print(int('34'))
print(int(34.1234))
print(int(-2.46))
print(float('12'))
print(float('1.11111111'))
print(str(98))
print(str('76.765'))
      

  具體執行結果如下:

python面試題彙總(下)
  • 三、Python如何定義一個函數
  函數的定義形式如下:
def <name>(arg1, arg2,… argN):
<statements>
      

  函數的名字也必須以字母開頭,可以包括下劃線“ ”,但不能把Python的關鍵字定義成函數的名字。函數内的語句數量是任意的,每個語句至少有一個空格的縮進,以表示此語句屬于這個函數的縮進結束的地方,函數自然結束。

  下面定義了一個兩個數相加的函數:

def add(p1, p2):
    print(p1, "+", p2, "=", p1+p2)
add(1,2)
      

  具體執行結果如下圖所示:

python面試題彙總(下)
  函數的目的是把一些複雜的操作隐藏,來簡化程式的結構,使其容易閱讀。函數在調用前,必須先定義。也可以在一個函數内部定義函數,内部函數隻有在外部函數調用時才能夠被執行。程式調用函數時,轉到函數内部執行函數内部的語句,函數執行完畢後,傳回到它離開程式的地方,執行程式的下一條語句。
  • 四、如何反序的疊代一個序列?

      如果是一個list, 最快的解決方案是:

list.reverse()
try:
    for x in list:
        'do something with x'
finally:
    list.reverse()
      

  如果不是list, 最通用但是稍慢的解決方案是:

for i in range(len(sequence)-1, -1, -1):
    x = sequence[i]
    '<do something with x>'
      
  • 五、Python檔案操作的面試題
  • 如何用Python删除一個檔案?

      使用os.remove(filename)或者os.unlink(filename);

  • Python如何copy一個檔案?

    shutil子產品有一個copyfile函數可以實作檔案拷貝

  • 六、如何用Python來發送郵件?
  可以使用smtplib标準庫。以下代碼可以在支援SMTP監聽器的伺服器上執行;
import sys, smtplib
from click._compat import raw_input
fromaddr = raw_input('From: ')
toaddrs = raw_input('To: ').split(',')
print ('Enter message, end with ^D:')
msg = ''
while 1:
    line = sys.stdin.readline()
    if not line:
        break
    msg = msg + line
# 發送郵件部分
server = smtplib.SMTP('localhost')
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
      
python面試題彙總(下)
  • 七、有兩個序列a,b,大小都為n,序列元素的值任意整形數
  無序;要求:通過交換a,b中的元素,使[序列a元素的和]與[序列b元素的和]之間的差最小。将兩序列合并為一個序列,并排序,為序列Source。拿出最大元素Big,次大的元素Small。在餘下的序列S[:-2]進行平分,得到序列max,min。将Small加到max序列,将Big加大min序列,重新計算新序列和,和大的為max,小的為min。具體實作如下:
def abs_test(a,b):
    # 假設剛開始就是內插補點最小的
    # 此時的內插補點絕對值為:
    min = abs(sum(a)-sum(b))
    # x,y分别為a,b清單的下标值
    x=y=0
    # 當a的下标小于a的長度時,依次用b的每一個值和a的值交換
    # 比較他們的內插補點絕對值的大小
    while x<len(a):
        #依次用b的每一個值和目前a的值交換
        while y<len(b):
            a[x],b[y] = b[y],a[x]
            # 交換後2個清單的內插補點絕對值
            tmp = abs(sum(a)-sum(b))
            # 如果此時的內插補點小,則指派給min
            # 否則還将交換回去
            if min>tmp:
                min = tmp
            else:
                a[x],b[y] = b[y],a[x]
            y += 1
        x += 1
        y = 0
    return a,b
a = [1000, 999, 998, 997, 996, 995]
b = [994, 993, 992, 3, 2, 1]
val = abs_test(a,b)
print(val)
      
python面試題彙總(下)
  • 八、下面這段段代碼的輸出結果是什麼?請解釋
def extendList(val, list=[]):
    list.append(val)
    return list
list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')
print ("list1 = %s" % list1)
print ("list2 = %s" % list2)
print ("list3 = %s" % list3)
      

  以上輸出的結果如下:

python面試題彙總(下)

  怎樣修改extendList的定義能夠産生以下預期的行為?

list1 = [10, ‘a’]

list2 = [123]

list3 = [10, ‘a’]

  很多人都會誤認為list1=[10],list3=[‘a’],因為他們以為每次extendList被調用時,清單參數的預設值都将被設定為[].但實際上的情況是,新的預設清單隻在函數被定義的那一刻建立一次。

  當extendList被沒有指定特定參數list調用時,這組list的值随後将被使用。這是因為帶有預設參數的表達式在函數被定義的時候被計算,不是在調用的時候被計算。是以list1和list3是在同一個預設清單上進行操作(計算)的。而list2是在一個分離的清單上進行操作(計算)的。(通過傳遞一個自有的空清單作為清單參數的值)。

  extendList的定義可以作如下修改。盡管,建立一個新的清單,沒有特定的清單參數。下面這段代碼可能能夠産生想要的結果:

def extendList(val, list=None):
    if list is None:
        list = []
        list.append(val)
        return list
list1 = extendList(10)
list2 = extendList(123)
list3 = extendList('a')
print ("list1 = %s" % list1)
print ("list2 = %s" % list2)
print ("list3 = %s" % list3)
      

  以上代碼輸出的結果如下:

python面試題彙總(下)
  • 九、給定以下字典的子類,下面的代碼能夠運作麼?為什麼?
class DefaultDict(dict):
    def __missing__(self, key):
        return []
d = DefaultDict()
d['florp'] = 127
print(d)
      
  能夠運作。因為當key缺失時,執行DefaultDict類,字典的執行個體将自動執行個體化這個數列。具體執行結果如下:
python面試題彙總(下)
  • 十、重新實作str.strip()
def rightStrip(tempStr,splitStr):
    endindex = tempStr.rfind(splitStr)
    while endindex != -1 and endindex == len(tempStr) - 1:
        tempStr = tempStr[:endindex]
        endindex = tempStr.rfind(splitStr)
        return tempStr
def leftStrip(tempStr,splitStr):
    startindex = tempStr.find(splitStr)
    while startindex == 0:
        tempStr = tempStr[startindex+1:]
        startindex = tempStr.find(splitStr)
        return tempStr
str = " H "
print (str)
print (leftStrip(str,' '))
print (rightStrip(str,' '))
      

  具體執行的結果如下:

python面試題彙總(下)
  • 十一、super的原理
class A(object):
    def __init__(self):
        print ("enter A")
        super(A, self).__init__() # new print "leave A"
class B(object):
    def __init__(self):
        print ("enter B")
        super(B, self).__init__() # new print "leave B"
class C(A):
    def __init__(self):
        print ("enter C")
        super(C, self).__init__()
        print ("leave C")
class D(A):
    def __init__(self):
        print ("enter D")
        super(D, self).__init__()
        print ("leave D")
class E(B, C):
    def __init__(self):
        print ("enter E")
        super(E, self).__init__() # change print "leave E"
class F(E, D):
    def __init__(self):
        print ("enter F")
        super(F, self).__init__() # change print "leave F"
      
python面試題彙總(下)
  • 十二、閉包
  常用的裝飾器就是閉包的一種,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數。這個被引用的自由變量将和這個函數一同存在,即使已經離開了創造它的環境也不例外 。
def make_adder(addend):
    def adder(augend):
        return augend + addend
    return adder

p1 = make_adder(4)
p2 = make_adder(5)
print(p1(10))
print(p2(10))
      

  執行結果如下:

python面試題彙總(下)
  • 十三、.給清單中的字典排序
   list 對象 alist [{“name”:”a”,”age”:20},{“name”:”b”,”age”:30},{“name”:”c”,”age”:25}]按照 age 從大到小排序。具體實作如下:
alist = [{"name": "a", "age": 20}, {"name": "b", "age": 30}, {"name": "c", "age": 25}]
alist.sort(key=lambda x: x['age'])
print(alist)
      
python面試題彙總(下)
  • 十四、合并兩個清單排除重複元素
  用簡潔的方法合并alist = [‘a’,’b’,’c’,’d’,’e’,’f’] blist = [‘x’,’y’,’z’,’e’,’f’]并且元素不能重複
alist = ['a','b','c','d','e','f']
blist = ['x','y','z','e','f']
def merge_list(*args):
    s = set()
    for i in args:
        s = s.union(i)
        print(s)
        return s
merge_list(alist,blist)
      

  具體實作結果如下:

python面試題彙總(下)
  • 十五、打亂一個排好序的清單
import random
a = [1, 2, 3, 4, 5, 6]
random.shuffle(a)
print(a)
      
python面試題彙總(下)
  • 十六、簡單的實作一個棧結構 stack
class Stack:  # 定義一個棧
    def __init__(self):  # 初始化棧為空清單
        self.items = []

    def isEmpty(self):
        return self.items == []

    def push(self, item):
        self.items.append(item)  # append()尾段加入資料

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[len(self.items) - 1]

    def size(self):
        return len(self.items)
s = Stack()
print(s.isEmpty())
s.push(4)
s.push("dog")
s.push(True)
print(s.peek())
print(s.pop())
print(s.peek())
      
python面試題彙總(下)
  • 十七、輸入一個日期,傳回時一年中的哪一天
from datetime import datetime
def which_day(year,month,day):
    return (datetime(year,month,day)-datetime(year,1,1)).days+1
print(which_day(2021,7,4))
      
python面試題彙總(下)
  • 十八、把字元串”k1:1|k2:2|k3:3”處理成 python 字典的形式:{k1:1,k2:2,k3:3}
def string_to_dict(string):
    d = {}
    for kv in string.split("|"):
        k,v = kv.split(":")
        if v.isdigit():
            v=int(v)
            d[k]=v
            return d
print(string_to_dict("k1:1|k2:2|k3:3"))
      
python面試題彙總(下)
  • 十九、判斷輸入的值是否在矩陣之中(楊氏矩陣)
  在一個二維數組之中,每一行都按照從走到右遞增的順序排序,每一列到按照從上到下的順序排序.請完成一個函數,輸入這樣的一個二維手術和一個整數,判斷數組中是否含有該整數
arr = [[1,4,7,10,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]]
def get_num(num,data=None):
    while data:
        if num > data[0][-1]:
            del data[0]
        elif num<data[0][-1]:
            data = list(zip(*data))
            del data[-1]
            data = list(zip(*data))
        else:
            return True
            data.clear()
            return False
print (get_num(18,arr))
      
python面試題彙總(下)
  • 二十、擷取最大公約數(歐幾裡得算法)
a= 25
b=15
def max_common(a,b):
    while b:
        a,b=b,a%b
        return a
print(max_common(a, b))
      
python面試題彙總(下)
  • 二十一、求兩個數的最小公倍數(公式法)
  兩個數的乘積等于這兩個數的 最大公約數與最小公倍數的積
a= 25
b=15
def min_common(a,b):
    c= a*b
    while b:
        a,b=b,a%b
        return c//a
print(min_common(a, b))
      
python面試題彙總(下)
  • 二十二、擷取中位數
  如果總數個數是奇數,按從小到大的順序,取中間的那個數;如果總數個數是偶數個的話,按從小到大的順序,取中間那兩個數的平均數。
#計算中位數
def mediannum(num):
    listnum = [num[i] for i in range(len(num))]
    listnum.sort()
    lnum = len(num)
    if lnum % 2 == 1:
        i = int((lnum + 1) / 2)-1
        return listnum[i]
    else:
        i = int(lnum / 2)-1
        return (listnum[i] + listnum[i + 1]) / 2
def medin(data):
    data.sort()
    half = len(data)//2
    return (data[half]+data[half])/2
l = [1,3,4,53,2,46,8,42,82]
print (medin(l))
print(mediannum(l))
      

總結