python自動化測試面試題
A. python面試基礎題十大陷阱,你中招了嗎
我們在會碰到各種各樣的面試,有的甚至是HR專門為你設置的障礙,在python面試中也是,無論你是應聘Python web開發,爬蟲工程師,或是數據分析,還是自動化運維,這些python面試基礎題十大陷阱也許你會遇到,今天的python培訓總結出來給你以防萬一:
問題1:請問如何修改以下Python代碼,使得下面的代碼調用類A的show方法?
class A(object)
def show(self):
print 'derived show'
class B(A)
def show(self):
print 'derived show'
obj=B()
obj.show()
答:這道題的考點是類繼承,只要通過__class__ 方法指定類對象就可以了。補充的代碼如下:
obj._class_=A
obj.show()
問題2:請問如何修改以下Python代碼,使得代碼能夠運行?
class A(object):
def _init_ (self,a,b):
self._a = a
self._b = b
def myprint(self):
print 'a=',self._a,'b=',self._b
a1=A(10,20)
a1.myprint()
a1=(80)
答:此題考察得是方法對象,為了能讓對象實例能被直接調用,需要實現 __call__ 方法,補充代碼如下:
class A(object):
def _init_ (self,a,b):
self._a = a
self._b = b
def myprint(self):
print 'a=',self._a,'b=',self._b
def_call_(self,num):
print'call:',num+self._a
問題3:下面這段代碼的輸出是什麼?
class B(object):
def fn(self):
print"B fn"
def_init_(self):
print"B INIT"
class A(object):
def fn(self):
print"A fn"
def_new_(cls,a):
print"NEW",a
if a>10:
return super(A,cls)._new_(cls)
return B()
def_init_(self,a):
print "INIT",a
a1=A(5)
a1,fn()
a2=A(20)
a2,fn()
答:
NEW 5
B INIT
B fn
NEW 20
INIT 20
A fn
此題考察的是new和init的用法,使用 __new__ 方法,可以決定返回那個對象,也就是創建對象之前調用的,這個常見於於設計模式的單例、工廠模式。__init__ 是創建對象是調用的。
問題4:下面這段代碼輸出什麼?
1s=[1,2,3,4]
list1 =[i for i in ls if i>2
print list1
list2 =[1*2 for i in ls if 1>2
print list2
dicl={x: x**2 for x in(2, 4, 6)}
print dic1
dic2={x: ' item'+ str(x**2)for x in (2, 4, 6)}
print dic2
setl ={x for x in 'hello world' if x not in 'low level'}
print set1
答:
[3,4]
[6,8]
{2:4,4:16,6:36}
{2:'item4',4:'item16』,6:'item36"}set(["h",'r','d"])
此題考察的是列表和字典的生成。
問題5:下面這段代碼輸出什麼?
num= 9
def f1():
um=20
def f2():
print num
f2()
f1()
f2()
答:
9
9
此題考察全局變數和局部變數。num 不是個全局變數,所以每個函數都得到了自己的 num 拷貝,如果你想修改 num ,則必須用 global 關鍵字聲明。比如下面這樣
num=9
def f1():
global num
um=20
def f2():
print num
f2()
f1()
f2()
#prints:
#9
#20
問題6:如何使用一行代碼交換兩個變數值?
a=8
b=9
答:
(a,b)=(b,a)
問題7:如何添加代碼,使得沒有定義的方法都調用mydefault方法?
class A(object):
def_init_(self,a,b):
self.a1=a
self.b1=b
print'init'
def mydefault(self):
print'default'
a1=A(10,20)
a1.fn1()
a1.fn2()
a1.fn3()
答:
class A(object):
def_init_(self,a,b):
self.a1=a
self.b1=b
print'init'
def mydefault(self):
print'default'
def_getattr_(self,name):
return self.mydefault
a1=A(10,20)
a1.fn1()
a1.fn2()
a1.fn3()
此題的考的是Python的默認方法, 只有當沒有定義的方法調用時,才會調用方法 __getattr__。當 fn1 方法傳入參數時,我們可以給 mydefault 方法增加一個 *args 不定參數來兼容。
class A(object):
def_init_(self,a,b):
self.a1=a
self.b1=b
print'init'
def mydefault(self,*args):
print'default:'+str(args[0])
def_getattr_(self,name):
print"other fn:",name
return self.mydefault
a1=A(10,20)
a1.fn1(33)
a1.fn2('hello')
a1.fn3(10)
問題8:一個包里有三個模塊,mod1.py , mod2.py , mod3.py ,但使用 from demopack import * 導入模塊時,如何保證只有 mod1 、 mod3 被導入了。
答:在包中增加 __init__.py 文件,並在文件中增加:
_all_=['mod1','mod3']
問題9:寫一個函數,接收整數參數 n ,返回一個函數,函數返回n和參數的積。
答:
def mulby(num):
def gn(val):
return num*val
return gn
zw=mulby(7)
print(zw(9));
問題10:請問下面的代碼有什麼隱患?(Python2中)
def strtest1(num):
str='first'
for i in range(num):
str+="X"
return str
答:由於變數str是個不可變對象,每次迭代,python都會生成新的str對象來存儲新的字元串,num越大,創建的str對象越多,內存消耗越大。
B. BAT面試題28:Python是如何進行內存管理的
Python的內存管理,一般從以下三個方面來說:
1)對象的引用計數機制(四增五減)
2)垃圾回收機制(手動自動,分代回收)
3)內存池機制(大m小p)
1)對象的引用計數機制
要保持追蹤內存中的對象,Python使用了引用計數這一簡單的技術。sys.getrefcount(a)可以查看a對象的引用計數,但是比正常計數大1,因為調用函數的時候傳入a,這會讓a的引用計數+1
2)垃圾回收機制
吃太多,總會變胖,Python也是這樣。當Python中的對象越來越多,它們將占據越來越大的內存。不過你不用太擔心Python的體形,它會在適當的時候「減肥」,啟動垃圾回收(garbage
collection),將沒用的對象清除
從基本原理上,當Python的某個對象的引用計數降為0時,說明沒有任何引用指向該對象,該對象就成為要被回收的垃圾了
比如某個新建對象,它被分配給某個引用,對象的引用計數變為1。如果引用被刪除,對象的引用計數為0,那麼該對象就可以被垃圾回收。
然而,減肥是個昂貴而費力的事情。垃圾回收時,Python不能進行其它的任務。頻繁的垃圾回收將大大降低Python的工作效率。如果內存中的對象不多,就沒有必要總啟動垃圾回收。
所以,Python只會在特定條件下,自動啟動垃圾回收。當Python運行時,會記錄其中分配對象(object
allocation)和取消分配對象(object deallocation)的次數。當兩者的差值高於某個閾值時,垃圾回收才會啟動。
我們可以通過gc模塊的get_threshold()方法,查看該閾值。
3)內存池機制
Python中有分為大內存和小內存:(256K為界限分大小內存)
1、大內存使用malloc進行分配
2、小內存使用內存池進行分配
python中的內存管理機制都有兩套實現,一套是針對小對象,就是大小小於256K時,pymalloc會在內存池中申請內存空間;當大於256K時,則會直接執行系統的malloc的行為來申請內存空間。
C. 分享70個經典的 Shell 腳本面試題與答案
我們為你的面試准備選擇了 70 個你可能遇到的 shell 腳本面試問題及解答。了解腳本或至少知道基礎知識對系統管理員來說至關重要,它也有助於你在工作環境中自動完成很多任務。在過去的幾年裡,我們注意到所有的 linux 工作職位都要求腳本技能。
1) 如何向腳本傳遞參數 ?
./script argument
例子: 顯示文件名稱腳本
(LCTT 譯註:謝謝某匿名訪客的提醒,原題有誤,修改之。)
2) 如何在腳本中使用參數 ?
第一個參數 : 2
例子 : 腳本會復制文件(arg1) 到目標地址(arg2)
3) 如何計算傳遞進來的參數 ?
4) 如何在腳本中獲取腳本名稱 ?
5) 如何檢查之前的命令是否運行成功 ?
6) 如何獲取文件的最後一行 ?
7) 如何獲取文件的第一行 ?
8) 如何獲取一個文件每一行的第三個元素 ?
9) 假如文件中每行第一個元素是 FIND,如何獲取第二個元素
10) 如何調試 bash 腳本
將 -xv 參數加到 #!/bin/bash 後
例子:
11) 舉例如何寫一個函數 ?
12) 如何向連接兩個字元串 ?
輸出
HelloWorld
13) 如何進行兩個整數相加 ?
輸出
3
據 @kashu 的意見,本題的更佳回答為:
兩個整數相加,還有若干種方法實現:
14) 如何檢查文件系統中是否存在某個文件 ?
15) 寫出 shell 腳本中所有循環語法 ?
for 循環 :
while 循環 :
until 循環 :
16) 每個腳本開始的 #!/bin/sh 或 #!/bin/bash 表示什麼意思 ?
這一行說明要使用的 shell。#!/bin/bash 表示腳本使用 /bin/bash。對於 python 腳本,就是
17) 如何獲取文本文件的第 10 行 ?
18) bash 腳本文件的第一個符號是什麼
19) 命令:[ -z "" ] && echo 0 || echo 1 的輸出是什麼
20) 命令 「export」 有什麼用 ?
21) 如何在後台運行腳本 ?
在腳本後面添加 「&」。
據 @kashu 的意見,更好的答案是:
大部分時間我們可能是遠程使用Linux,我碰到過由於網路斷線使得在後台運行的command &沒了...
22) "chmod 500 script" 做什麼 ?
使腳本所有者擁有可執行許可權。
23) ">" 做什麼 ?
重定向輸出流到文件或另一個流。
24) & 和 && 有什麼區別
25) 什麼時候要在 [ condition ] 之前使用 「if」 ?
當條件滿足時需要運行多條命令的時候。
26) 命令: name=John && echo 'My name is $name' 的輸出是什麼
variable
27) bash shell 腳本中哪個符號用於注釋 ?
28) 命令: echo ${new:-variable} 的輸出是什麼
variable
29) ' 和 " 引號有什麼區別 ?
30) 如何在腳本文件中重定向標准輸出和標准錯誤流到 log.txt 文件 ?
在腳本文件中添加 "exec >log.txt 2>&1" 命令。
31) 如何只用 echo 命令獲取字元串變數的一部分 ?
例子:
32) 如果給定字元串 variable="User:123:321:/home/dir",如何只用 echo 命令獲取 home_dir ?
或
33) 如何從上面的字元串中獲取 「User」 ?
或
34) 如何使用 awk 列出 UID 小於 100 的用戶 ?
35) 寫程序為用戶計算主組數目並顯示次數和組名
36) 如何在 bash shell 中更改標準的域分隔符為 ":" ?
37) 如何獲取變數長度 ?
38) 如何列印變數的最後 5 個字元 ?
39) {variable: -10} 有什麼區別?
40) 如何只用 echo 命令替換字元串的一部分 ?
41) 哪個命令將命令替換為大寫 ?
42) 如何計算本地用戶數目 ?
43) 不用 wc 命令如何計算字元串中的單詞數目 ?
44) "export $variable" 或 "export variable" 哪個正確 ?
45) 如何列出第二個字母是 a 或 b 的文件 ?
46) 如何將整數 a 加到 b 並賦值給 c ?
或
或
47) 如何去除字元串中的所有空格 ?
48) 重寫這個命令,將輸出變數轉換為復數: item="car"; echo "I like $item" ?
49) 寫出輸出數字 0 到 100 中 3 的倍數(0 3 6 9 …)的命令 ?
或
50) 如何列印傳遞給腳本的所有參數 ?
或
51) [ b ] 和 [ b ] 有什麼區別
52) = 和 == 有什麼區別
53) 寫出測試 $a 是否大於 12 的命令 ?
[ $a -gt 12 ]
54) 寫出測試 $b 是否小於等於 12 的命令 ?
[ $b -le 12 ]
55) 如何檢查字元串是否以字母 "abc" 開頭 ?
[[ $string == abc* ]]
56) [[ string == "abc " ]] 有什麼區別*
57) 如何列出以 ab 或 xy 開頭的用戶名 ?
egrep " ab| xy" /etc/passwd|cut -d: -f1
58) bash 中 $! 表示什麼意思 ?
後台最近執行命令的 PID.
59) $? 表示什麼意思 ?
前台最近命令的結束狀態。
60) 如何輸出當前 shell 的 PID ?
echo $$
61) 如何獲取傳遞給腳本的參數數目 ?
echo $#
(LCTT 譯註:和第3題重復了。)
62) @ 有什麼區別
63) 如何在 bash 中定義數組 ?
64) 如何列印數組的第一個元素 ?
65) 如何列印數組的所有元素 ?
66) 如何輸出所有數組索引 ?
67) 如何移除數組中索引為 2 的元素 ?
68) 如何在數組中添加 id 為 333 的元素 ?
69) shell 腳本如何獲取輸入的值 ?
a) 通過參數
b) 通過 read 命令
70) 在腳本中如何使用 "expect" ?
D. 設整形變數x=10,則表達式2<x<8的值
編輯
:kenwoodjw
對於機器學習演算法工程師而言,Python是不可或缺的語言,它的優美與簡潔令人無法自拔。那麼你過Python編程面試題嗎?從Python基礎到網頁爬蟲你是否能全方位Hold住?今天,為讀者們推薦一個Github項目。
在這個項目中, kenwoodjw 准備了近 300 道 Python 面試題,同時還包含解決方案與代碼。主要從 Python 基礎、高級語句、網頁應用、資料庫和測試等角度提問,讀者可只自己需要的領域。目前該項目已經完成了很多基礎和高級面試題,本文主要摘取一些 Python 面試題供大家參考。
項目地址:https://github.com/kenwoodjw/python_interiew_question
總體而言,項目有近300道面試題。雖然該項目剛開始創建,但很多Python面試題都已經提供決方案。如下所示為面試題示例:
本文截取了一些面試題及解決方案:
Python 基礎文件操作模塊與包數據類型企業面試題Python 高級設計模式系統編程如果希望機器學習面試題,可閱讀:春招已近,這份GitHub萬星的ML演算法面試大全請收下
Python 基礎
什麼是 Python?根據Python 創建者 Guido an Rossum 所言,Python是一種高級編程語言,其設計的核心理念是代碼的易讀性,以及允許編程者通過若干行代碼輕松表達想法創意。實際上,很多開發者選擇學習 Python 的首要原因是其編程的優美性,用它編碼和表達想法非常自然。
文件操作
1.若有一個jsonline格式的文件file.txt,大小約為10K,我們的處理方式為:
defget_lines(): l = []with open('file.txt', 'rb') as f:for eachline in f: l.append(eachline)return lif __name__ == '__main__':for e in get_lines(): process(e) #處理每一行數據
現在要處理一個大小為10G的file.txt文件,但是內存只有4G。如果在只修改get_lines 函數而其他代碼保持不變的情況下,應該如何實現?需要考慮的問題都有那些?
defget_lines(): l = []with open('file.txt','rb') as f: data = f.readlines(60000) l.append(data)yield l
要考慮的問題有:內存只有4G,無法一次性讀入10G文件。而分批讀入數據要記錄每次讀入數據的位置,且分批每次讀取得太小會在讀取操作上花費過多時間。
模塊與包
2.如何輸入日期, 判斷這一天是這一年的第幾天?
import datetimedefdayofyear(): year = input("請輸入年份: ") month = input("請輸入月份: ") day = input("請輸入天: ") date1 = datetime.date(year=int(year),month=int(month),day=int(day)) date2 = datetime.date(year=int(year),month=1,day=1)return (date1-date2).days+1數據類型
3.如何反轉字元串"aStr"?
print("aStr"[::-1])4.下面代碼的輸出結果將是什麼?會報錯嗎?
list = ['a','b','c','d','e']print(list[10:])
代碼將輸出[],並不會產生IndexError 錯誤。如果嘗試用超出成員的個數的index來獲取某個列表的成員,那就會報錯。例如,嘗試獲取 list[10] 和之後的成員,會導致IndexError。然而當我們嘗試獲取列表的切片時,開始的index超過成員個數並不會產生IndexError,而是僅僅返回一個空列表。因為並不會報錯,所以這種Bug很難追蹤到。
5.請寫出一段Python代碼,實現刪除list裡面的重復元素?
l1 = ['b','c','d','c','a','a']l2 = list(set(l1))print(l2)用list類的sort方法可以保證順序不變:
l1 = ['b', 'c', 'd', 'c', 'a', 'a']l2 = list(set(l1))l2.sort(key=l1.index)print(l2)也可以這樣寫:
l1 = ['b', 'c', 'd', 'c', 'a', 'a']l2 = sorted(set(l1), key=l1.index)print(l2)
也可以用遍歷:
l1 = ['b', 'c', 'd', 'c', 'a', 'a']l2 = []for i in l1:ifnot i in l2: l2.append(i)print(l2)企業面試題
6.設計實現遍歷目錄與子目錄,抓取.pyc文件
第一種方法:
import osdefgetFiles(dir, suffix): res = []for root, dirs, files in os.walk(dir):for filename in files: name, suf = os.path.splitext(filename)if suf == suffix: res.append(os.path.join(root, filename)) print(res)getFiles("./", '.pyc')
第二種方法:
import osdefpick(obj):try:if obj.[-4:] == ".pyc": print(obj)except:returnNonedefscan_path(ph): file_list = os.listdir(ph)for obj in file_list:if os.path.isfile(obj): pick(obj)elif os.path.isdir(obj): scan_path(obj)if __name__ == '__main__': path = input('輸入目錄') scan_path(path)
7.如何反轉一個整數,例如-123--> -321?
classSolution(object):defreerse(self, x):if-10 < x=""><>return x str_x = str(x)if str_x[0] != "-": str_x = str_x[::-1] x = int(str_x)else: str_x = str_x[1:][::-1] x = int(str_x) x = -xreturn x if-2147483648 < x=""><>if __name__ == '__main__': s = Solution() reerse_int = s.reerse(-120) print(reerse_int)
Python高級
Python高級包含很多重要的模塊,例如函數、類和實例、系統編程、正則表達式、網路編程等等。根據這些高級屬性,Python可用於數據科學、網頁開發、機器學習等等。
設計模式
8.對設計模式的理解,簡述你的設計模式?
設計模式是為我們經常會碰到的一些編程問題構建的可重用解決方案,它是總結性和經優化的。一個設計模式並不像一個類或一個庫那樣能夠直接作用於我們的代碼,反之,設計模式更為高級,它是一種在特定情形下實現的方法模板。常見的是工廠模式和單例模式。
單例模式應用的場景一般發現在以下條件下: 資源共享的情況下,避免由於資源操作時導致的性能或損耗等,如日誌文件,應用配置。控制資源的情況下,方便資源之間的互相通信。
9.生成器和迭代器的區別?
迭代器是一個更抽象的概念,任何對象,如果它的類有 next 方法和 iter 方法返回自己本身,它就是可迭代的。對於 string、list、dict、tuple 等這類容器對象,使用for循環遍歷是很方便的,for 語句實際上會對容器對象調用 iter() 函數。iter() 會返回一個定義了 next() 方法的迭代器對象,它在容器中逐個訪問容器內元素,在沒有後續元素時,next()會拋出一個StopIteration異常。
生成器(Generator)是創建迭代器的簡單而強大的工具。它們寫起來就像是正規的函數,只是在需要返回數據的時候使用yield語句。生成器能做到迭代器能做的所有事,而且因為自動創建iter()和next()方法,生成器顯得特別簡潔,而且生成器也是高效的,使用生成器表達式取代列表解析可以同時節省內存。除了創建和保存程序狀態的自動方法,當發生器終結時,還會自動拋出StopIteration異常。
10.對裝飾器的理解,你能寫出一個計時器裝飾器,它能記錄函數的執行時間嗎?
裝飾器本質上是一個Python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。
import timedeftimeit(func):defwrapper(): start = time.clock() func() end = time.clock() print('used:',end-start)return wrapper @timeitdeffoo(): print('in foo()'foo())
系統編程
11.介紹一下你的進程。
程序運行在操作系統上的一個實例,就稱之為進程。進程需要相應的系統資源:內存、時間片、pid。創建進程: 首先要導入multiprocessing中的Process;創建一個Process對象;創建Process對象時,可以傳遞參數。
p = Process(target=XXX, args=(tuple,), kwargs={key: alue})target = XXX # 指定的任務函數,不用加()args = (tuple,)kwargs = {key: alue} # 給任務函數傳遞的參數使用start()啟動進程 結束進程 給子進程指定函數傳遞參數Demo
import osfrom mulitprocessing import Processimport timedefpro_func(name, age, **kwargs):for i in range(5): print("子進程正在運行中,name=%s,age=%d,pid=%d" % (name, age, os.getpid())) print(kwargs) time.sleep(0.2)if __name__ == "__main__":# 創建Process對象 p = Process(target=pro_func, args=('小明', 18), kwargs={'m': 20})# 啟動進程 p.start() time.sleep(1)# 1秒鍾之後,立刻結束子進程 p.terminate() p.join()12.談談你對多進程、多線程、以及協程的理解,項目是否用?
進程:一個運行的程序(代碼)就是一個進程,沒有運行的代碼叫程序,進程是系統資源分配的最小單位,進程擁有自己獨立的內存空間,所有進程間數據不共享,開銷大。線程: cpu調度執行的最小單位,也叫執行路徑,不能獨立存在,依賴進程存在,一個進程至少有一個線程,叫主線程,而多個線程共享內存可以極大地提高了程序的運行效率。協程: 是一種用戶態的輕量級線程,協程的調度完全由用戶控制,協程擁有自己的寄存器上下文和棧。協程調度時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操中棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變數,所以上下文的切換非常快。
關於系統編程還有很多問題,例如:
本文為編輯,請聯系本獲得授權。