tft每日頭條

 > 職場

 > python簡單編程面試

python簡單編程面試

職場 更新时间:2024-06-26 11:44:07

python簡單編程面試(Python高階編程面試題)1

python簡單編程面試(Python高階編程面試題)2

點擊上方頭像關注我,每周上午 09:00準時推送,每月不定期贈送技術書籍,小窗口回複“資源”、“測試工具包”領取測試資源。

本文6617字,閱讀約需17分鐘

在面試自動化測試、測試開發等職位時,經常會問到Python高階編程相關的問題,以下就介紹Python中一些常見的高階的面試題,果斷安排上惹,歡迎在文末留言評論喔。

python簡單編程面試(Python高階編程面試題)3

python簡單編程面試(Python高階編程面試題)4

Python 的内存管理機制及調優手段?

Python内存管理機制:引用計數、垃圾回收、内存池。

引用計數

引用計數是一種非常高效的内存管理手段, 當一個 Python 對象被引用時其引用計數增加 1, 當其不再被一個變量引用時則計數減 1, 當引用計數等于 0 時對象被删除。

垃圾回收

(1) 引用計數

引用計數也是一種垃圾收集機制,而且也是一種最直觀,最簡單的垃圾收集技術。當 Python 的某個對象的引用計數降為 0 時,說明沒有任何引用指向該對象,該對象就成為要被回收的垃圾了。比如某個新建對象,它被分配給某個引用,對象的引用計數變為 1。如果引用被删除,對象的引用計數為 0, 那麼該對象就可以被垃圾回收。不過如果出現循環引用的話,引用計數機制就不再起有效的作用了。

(2) 标記清除

如果兩個對象的引用計數都為 1,但是僅僅存在他們之間的循環引用,那麼這兩個對象都是需要被回收的,也就是說,它們的引用計數雖然表現為非 0,但實際上有效的引用計數為 0。所以先将循環引用摘掉,就會得出這兩個對象的有效計數。

(3) 分代回收

  • 分代回收是一種以空間換時間的操作方式,Python 将内存根據對象的存活時間劃分為不同的集合,每個集合稱為一個代,Python 将内存分為了 3“代”,分别為年輕代(第 0 代)、中年代(第 1 代)、老年代(第 2 代),他們對應的是 3 個鍊表,它們的垃圾收集頻率與對象的存活時間的增大而減小。
  • 新創建的對象都會分配在年輕代,年輕代鍊表的總數達到上限時,Python 垃圾收集機制就會被觸發,把那些可以被回收的對象回收掉,而那些不會回收的對象就會被移到中年代去,依此類推,老年代中的對象是存活時間最久的對象,甚至是存活于整個系統的生命周期内。
  • 同時,分代回收是建立在标記清除技術基礎之上。分代回收同樣作為 Python 的輔助垃圾收集技術處理那些容器對象。
内存池

Python在運行期間會大量地執行malloc和free的操作,頻繁地在用戶态和核心态之間進行切換,這将嚴重影響Python的執行效率。為了加速Python的執行效 率,Python引入了一個内存池機制,用于管理對小塊内存的申請和釋放。

調優手段

1、手動垃圾回收。對Python的垃圾回收進行調優的一個最簡單的手段便是關閉自動回收, 根據情況手動觸發。

2、調高垃圾回收阈值。調高阈值的方法能在一定程度上避免内存溢出的問題(但不能完全避免), 同時可能減少可觀的垃圾回收開銷. 根據具體項目 的不同, 甚至是程序輸入的不同, 合适的阈值也不同. 因此需要反複測試找到一個合适的阈值。

3、避免循環引用。使用良好的編程習慣盡可能的避免循環引用. 兩種常見的手段: 手動解循環引用和使用弱引用。

什麼是 lambda 函數,有什麼好處?

lambda 函數是一個可以接收任意多個參數(包括可選參數)并且返回單個表達式值的函數。

lambda 函數好處:

1、lambda 函數比較輕便,即用即扔,很适合需要完成一項功能,但是此功能隻在此一處使用, 連名字都很随意的情況下;

2、匿名函數,一般用來給 filter, map 這樣的函數式編程服務;

3、作為回調函數,傳遞給某些應用,比如消息處理。

舉個例子,提取列表中的偶數。

python簡單編程面試(Python高階編程面試題)5

你對裝飾器的理解?

裝飾器本質上是一個Python函數,它可以讓已有的函數不做任何改動的情況下增加功能。非常适合有切面需求的場景,比如權限校驗,日志記錄和性能測試等等。如果你想要執行某個函數前記錄日志或者記錄時間來統計性能,又不想改動這個函數,就可以通過裝飾器來實現。

寫出一個計時器裝飾器,記錄函數的執行時間。

python簡單編程面試(Python高階編程面試題)6

Python 排序算法的理解

以下主要介紹冒泡排序、選擇排序、插入排序、快速排序四種排序算法:

冒泡排序

思路:每相鄰的兩個數進行比較,如果前邊的比後邊的數大,則交換這兩個數,重複操作,這樣的話每一趟會确定一個最大值。

如下代碼所示,冒泡排序的時間複雜度為O(n2)。

python簡單編程面試(Python高階編程面試題)7

選擇排序

思路:第一趟遍曆選擇一個最小的數(或最大),放到第一個位置,下一趟遍曆繼續從列表中找最小的值放到已排序序列的末尾,說白了就是每趟找一個最小的值(或者最大的)~這個算法的關鍵在于最小數的【位置】。

選擇排序時間複雜度為O(n2)。

python簡單編程面試(Python高階編程面試題)8

插入排序

思路:将列表分為有序區和無序區,開始的時候有序區隻有一個元素,每次從無序區取一個元素插入到有序區内,直到無序區内的元素被取完~這個算法的關鍵是【有序區已有】的元素和【即将要插入】到有序區的元素。

插入排序的時間複雜度為O(n2)。

python簡單編程面試(Python高階編程面試題)9

快速排序

思路:從列表中取一個元素,假如取第一個元素,将這個元素排好後前面的元素都比這個元素小,後面的都比這個元素大,即這個元素所在的位置即是完全排序後該元素的位置,後面遞歸處理即可~這個算法的關鍵即【遞歸】。

快速排序的時間複雜度為O(nlogn)。

python簡單編程面試(Python高階編程面試題)10

Python常見的魔法方法

Python 的類⾥提供的,兩個下劃線開始,兩個下劃線結束的⽅法,就是魔法⽅法,魔法⽅法在恰當的時候就會被激活,⾃動執⾏。 使用Python的魔法方法可以使Python的自由度變得更高,當不需要重寫時魔法方法也可以在規定的默認情況下生效,在需要重寫時也可以讓使用者根據自己的需求來重寫部分方法來達到自己的預期。

__init__⽅法

__init__() ⽅法,在創建⼀個對象時默認被調⽤,不需要⼿動調⽤。在開發中,如果希望在創建對象的同時,就設置對象的屬性,可以對 __init__⽅法進⾏改造。

python簡單編程面試(Python高階編程面試題)11

__new__方法

__init__() ⽅法,當一個實例被創建的時候初始化的方法,但是它并不是實例化調用的第一個方法,__new__才是實例化對象調用的第一個方法。__new__執行後會返回實例對象(self),然後将self作為第一個參數傳給__init__()方法。__new__很少使用,但是也有它适合的場景,尤其是當類繼承自一個像元組或者字符串這樣不經常改變的類型的時候。

使用__new__實現單例模式。

class Person(object): def __init__(self, name, age): self.name = name self.age = age def __new__(cls, *args, **kwargs): if not hasattr(cls, 'instance'): cls.instance = super().__new__(cls) return cls.instancea = Person('coco', 18)b = Person('vivi', 20)print(id(a))print(id(b))

輸出結果:

python簡單編程面試(Python高階編程面試題)12

__str__⽅法

__str__ ⽅法返回對象的描述信息,使⽤ print() 函數打印對象時,其實調⽤的就是這個對象的 __str__ ⽅法。

class Cat: def __init__(self,name,color): self.name = name self.color = colortom = Cat('Tom','white')# 使⽤ print ⽅法打印對象時,會調⽤對象的 __str__ ⽅法,默認會打印類名和對象的内存地址名print(tom) # <__main__.Cat object at 0x0000021BE3B9C940>

如果想要修改對象的輸出的結果,可以重寫 __str__ ⽅法。

class Person: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return '哈哈'p = Person('vivi',18)print(p) # 哈哈 打印對象時,會⾃動調⽤對象的 __str__ ⽅法

⼀般情況下,我們在打印⼀個對象時,可能需要列出這個對象的所有屬性。

class Student: def __init__(self,name,score): self.name = name self.score = score def __str__(self): return '姓名是:{},成績是{}分'.format(self.name,self.score)s = Student('lisi',95)print(s) # 姓名是:lisi,成績是95分

__call__⽅法

讓一個類的實例像函數一樣被調用,對象後⾯加括号,觸發執⾏。

class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print('__call__方法被調用了')obj = Foo() # 執⾏ __init__obj() # 執⾏ __call__

__getitem__、__setitem__、__delitem__

__getitem__、__setitem__、__delitem__,取值、賦值、删除“三劍客”。Python中,标識符後面加圓括号,通常代表執行或調用方法的意思。而在标識符後面加中括号[],通常代表取值的意思。Python設計了__getitem__()、__setitem__()、__delitem__()這三個特殊成員,用于執行與中括号有關的動作。它們分别表示取值、賦值、删除數據。

也就是如下的操作:

a = 标識符[] :  執行__getitem__方法

标識符[] = a :  執行__setitem__方法

del 标識符[] :  執行__delitem__方法

class Foo: def __getitem__(self, key): print('__getitem__',key) def __setitem__(self, key, value): print('__setitem__',key,value) def __delitem__(self, key): print('__delitem__',key)obj = Foo()result = obj['k1'] # 自動觸發執行 __getitem__obj['k2'] = 'jack' # 自動觸發執行 __setitem__del obj['k1'] # 自動觸發執行 __delitem__

Python單例模式

單例模式是一種常用的軟件設計模式,在單例模式的核心結構中,隻包含一個被稱為單例類的特殊類,通過單例模式可以保證系統中一個類隻有一個實例,而且這個實例可以輕易被外界訪問,方便控制實例對象的個數以節約系統資源。

單例模式的要點有三個:

  • 某個類隻能有一個實例
  • 這個類必須自行創建其唯一實例
  • 這個類必須自行向整個系統提供這個唯一實例。

單例模式應用的場景一般發現在以下條件下:

資源共享的情況下,避免由于資源操作時導緻的性能或損耗等,如日志文件,應用配置。

控制資源的情況下,方便資源之間的互相通信,如線程池等。

以下介紹,單例模式實現的三種方式:

使用__new__方法

先定義一個類,類中定義__new__方法,然後将類的一個實例類綁定到類變量中。

如果類的_instance值為None,則說明這個類還沒有被實例化過,程序會自動實例化一個類的實例,然後返回。如果類的_instance值不為None,則程序會直接返回_instance。

代碼如下:

class Singleton(object): _instance = None def __init__(self): pass def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._instanceclass MyClass(Singleton): a = 1if __name__ == '__main__': cls1 = MyClass() cls2 = MyClass() print(id(cls1)) print(id(cls2)) print(cls1 == cls2) print(cls1 is cls2)

得到的結果:

python簡單編程面試(Python高階編程面試題)13

使用decorator裝飾器

我們知道,裝飾器(decorator)可以動态地修改一個類或函數的功能。在這裡使用裝飾器來裝飾某個類,使其隻能生成一個實例,代碼如下:

def singleton(cls): instances={} def getinstance(*args,**kwargs): if cls not in instances: instances[cls]=cls(*args,**kwargs) return instances[cls] return getinstance@singletonclass MyClass(object): a=1if __name__ == '__main__': cls1 = MyClass() cls2 = MyClass() print(id(cls1)) print(id(cls2)) print(cls1 == cls2) print(cls1 is cls2)

得到的結果為:

python簡單編程面試(Python高階編程面試題)14

使用元類(metaclass)

元類(metaclass)可以控制類的創建過程,它主要做三件事:

python簡單編程面試(Python高階編程面試題)15

用元類實現單例模式的代碼如下:

class Singleton(type): _inst = {} def __call__(self, *args, **kw): if self not in self._inst: self._inst[self] = super(Singleton, self).__call__(*args, **kw) return self._inst[self]class MyClass(metaclass=Singleton): def __init__(self): self.xx = 0if __name__ == '__main__': cls1 = MyClass() cls2 = MyClass() print(id(cls1)) print(id(cls2)) print(cls1 == cls2) print(cls1 is cls2)

得到的結果為:

python簡單編程面試(Python高階編程面試題)16

python簡單編程面試(Python高階編程面試題)17

更多系列文章

敬請期待


我是CoCo,計算機科學與技術專業,深漂大廠互聯網民工(女),坐标深圳。5年工作經驗,3年持續輸出技術文。ITester軟件測試小棧(ID:ITestingA)号主,專注于軟件測試技術和寶藏幹貨分享,每周準時更新原創技術文章,每月不定期贈送技術書籍,願我們在更高處相逢。喜歡記得星标⭐我,每周及時獲得最新推送,第三方轉載請注明出處。

python簡單編程面試(Python高階編程面試題)18

python簡單編程面試(Python高階編程面試題)19

想獲取更多最新幹貨内容

快來星标 置頂 關注

每周一、三、五 08:30見

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关職場资讯推荐

热门職場资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved