背景
2018年的冬天很冷,整個(gè)行業(yè)都不景氣,很多公司面臨裁員、倒閉。我們公司也沒(méi)能逃過(guò)此劫,公司融資不到位欠薪2個(gè)月,實(shí)在沒(méi)有辦法,樓主也開(kāi)始加入找工作的大軍。在招聘網(wǎng)站上投了好幾個(gè)自己感興趣的公司,也僅僅收到一個(gè)面試邀請(qǐng),面試結(jié)果也不理想,被刷了。在這里給大家分享下面試題。
面試題
面試主要考察了以下幾個(gè)方面:
- 對(duì)敏捷開(kāi)發(fā)的理解
- 測(cè)試流程
- BUG管理
- 用例設(shè)計(jì)
- UI自動(dòng)化,接口自動(dòng)化
- 持續(xù)集成
- 算法題
- Linux命令
- 性能測(cè)試
回答1. 對(duì)敏捷開(kāi)發(fā)的理解
雖然目前公司處于敏捷開(kāi)發(fā)的模式中,但平時(shí)自己也只是服從公司的流程,沒(méi)有仔細(xì)去思考過(guò)敏捷開(kāi)發(fā)。所以這個(gè)問(wèn)題回答的也不好。
維基百科: 敏捷軟件開(kāi)發(fā)(英語(yǔ):Agile software development),又稱敏捷開(kāi)發(fā),是一種從1990年代開(kāi)始逐漸引起廣泛關(guān)注的一些新型軟件開(kāi)發(fā)方法,是一種應(yīng)對(duì)快速變化的需求的一種軟件開(kāi)發(fā)能力。它們的具體名稱、理念、過(guò)程、術(shù)語(yǔ)都不盡相同,相對(duì)于“非敏捷”,更強(qiáng)調(diào)程序員團(tuán)隊(duì)與業(yè)務(wù)專家之間的緊密協(xié)作、面對(duì)面的溝通(認(rèn)為比書(shū)面的文檔更有效)、頻繁交付新的軟件版本、緊湊而自我組織型的團(tuán)隊(duì)、能夠很好地適應(yīng)需求變化的代碼編寫(xiě)和團(tuán)隊(duì)組織方法,也更注重軟件開(kāi)發(fā)過(guò)程中人的作用。
個(gè)人理解:
實(shí)施敏捷開(kāi)發(fā)的流程:要去所有人參加需求評(píng)審,功能分卡,估點(diǎn),每日站會(huì),迭代回顧
為了能夠響應(yīng)快速變化的需求或頻繁的交付,必須依賴完善的自動(dòng)化工具鏈,從單元測(cè)試---接口自動(dòng)化---UI自動(dòng)化---部署---線上監(jiān)控 整套的流程實(shí)現(xiàn)自動(dòng)化
測(cè)試驅(qū)動(dòng)開(kāi)發(fā),在編寫(xiě)功能實(shí)現(xiàn)代碼前編寫(xiě)單元測(cè)試代碼(實(shí)施上來(lái)講比較困難,開(kāi)發(fā)能夠完成單元測(cè)試就不錯(cuò)了)
持續(xù)集成,原則是盡量使用master分支進(jìn)行開(kāi)發(fā),頻繁地集成,即使編譯報(bào)錯(cuò)也能夠迅速定位修復(fù)。杜絕多分支的開(kāi)發(fā)方式,合并分支是一個(gè)繁瑣的工作,容易產(chǎn)生眾多沖突問(wèn)題,對(duì)測(cè)試也增加了工作量
注重面對(duì)面的溝通,減少冗余的文檔
重構(gòu)貫穿整個(gè)開(kāi)發(fā)流程,每次check代碼時(shí)對(duì)代碼進(jìn)行重構(gòu),使代碼盡量簡(jiǎn)單,優(yōu)美,可擴(kuò)展,完善的單元測(cè)試是你重構(gòu)的保障
定時(shí)進(jìn)行Code Review
2. 測(cè)試流程和BUG管理
根據(jù)自己公司實(shí)際情況回答
3. UI自動(dòng)化和接口自動(dòng)化
簡(jiǎn)單的問(wèn)了下框架的架構(gòu)
UI自動(dòng)化怎么處理界面展示延遲的問(wèn)題?
Robotium查找元素默認(rèn)20s等待時(shí)間
HTTP常見(jiàn)狀態(tài)碼
接口自動(dòng)化中怎么測(cè)試重定向的接口?(記不清了)
不懂。這個(gè)沒(méi)答上來(lái)
4. 持續(xù)集成
- 自動(dòng)化測(cè)試多久構(gòu)建一次?如何搭建jenkins?代碼管理使用的是什么?jenkins上如何配置ssh的方式從git拉取代碼?
5. 算法題
題目:完成一個(gè)函數(shù),實(shí)現(xiàn)功能為判斷一個(gè)字符串是否是一個(gè)合法的ip地址
輸入:任意字符串
輸出:如果是一個(gè)合法ip地址,返回true;否則,返回false
舉例:輸入10.0.0.1,輸出true;輸入aaaa,輸出false
要求:
1.可以用c/c++/java/php/python等任意熟悉語(yǔ)言,但不能使用正則表達(dá)式等已有算法;
2.根據(jù)等價(jià)類和邊界值劃分等測(cè)試方法,對(duì)寫(xiě)好的代碼羅列出測(cè)試點(diǎn)并完成單元測(cè)試用例的代碼部分
分析:此題考察了基本網(wǎng)絡(luò)知識(shí),代碼能力,用例設(shè)計(jì)能力
合法IP地址當(dāng)時(shí)寫(xiě)的是0.0.0.0~255.255.255.255 其實(shí)錯(cuò)了,應(yīng)該是1.0.0.0~255.255.255.255
0.0.0.0表示的是所有IP的一個(gè)集合,不算真正意義上的IP地址
import unittest
# 舉例:輸入10.0.0.1,輸出true;輸入aaaa,輸出false # 1.0.0.0 ~ 255.255.255.255
def assert_ip(ip_str):
# 字符串切割 ip_list = ip_str.strip().split('.') if len(ip_list) != 4: print('列表元素不等于4') return False try: # 0開(kāi)始的IP不合法 if int(ip_list[0]) == 0: print('以0開(kāi)始不合法') return False for ip in ip_list: if len(ip) > 1 and ip.startswith('0'): print('長(zhǎng)度大于1不能以0開(kāi)始') return False if 0 <= int(ip) <= 255: pass else: print('大小不在0-255') return False except Exception as e: print(e) return False return True
class TestIp(unittest.TestCase):
def test_01(self): ip1 = '10.0.0.1' self.assertTrue(assert_ip(ip1))
def test_02(self): ip2 = '0.0.0.0' self.assertFalse(assert_ip(ip2))
def test_03(self): ip3 = '255.255.255.255' self.assertTrue(assert_ip(ip3))
def test_04(self): ip4 = '255.255.255.256' self.assertFalse(assert_ip(ip4))
def test_05(self): ip5 = '0.0.0.1' self.assertFalse(assert_ip(ip5))
def test_06(self): ip6 = '-1.2.3.4' self.assertFalse(assert_ip(ip6))
def test_07(self): ip7 = '' self.assertFalse(assert_ip(ip7))
def test_08(self): ip8 = '0.2.11' self.assertFalse(assert_ip(ip8))
def test_09(self): ip9 = '10.0.0.0.1' self.assertFalse(assert_ip(ip9))
def test_10(self): ip10 = 'aa.bb.cc.dd' self.assertFalse(assert_ip(ip10))
def test_11(self): ip11 = '1 192.168.1.1 ' self.assertFalse(assert_ip(ip11))
def test_12(self): ip12 = '1.00.0.0' self.assertFalse(assert_ip(ip12))
def test_13(self): ip13 = 'aaaaa' self.assertFalse(assert_ip(ip13))
if __name__ == '__main__':
unittest.main()
單元測(cè)試點(diǎn):
- IP不含字符’ . ’
- IP切割字符串后列表大小 =4 < 4 >4 的三種情況
- 字符串中包含空格(左右空格,中間空格)
- 輸入字符串為空
- 輸入合法IP 10.0.0.1
- 輸入合法IP 1.0.0.0
- 輸入合法IP 255.255.255.255
- 輸入非法IP 0.0.0.1
- 輸入非法IP 255.255.255.256
- 輸入非法IP -1.2.3.4
- 輸入字符串中包含非數(shù)字aa.10.11.dd
- 輸入特殊字符串 .@ddj.%^&111.1.
- 輸入非法IP 172.16.01.06
面試官又讓我分析unittest源碼...我表示沒(méi)看過(guò)...GG(我簡(jiǎn)歷可沒(méi)寫(xiě)精通unittest~~~)
于是又讓我用正則表達(dá)來(lái)寫(xiě),心中一群草泥馬飄過(guò),雖說(shuō)平時(shí)會(huì)使用正則,但都是百度現(xiàn)成的,真要自己寫(xiě)都點(diǎn)難度。。。
網(wǎng)上找的:
^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$
import re
def assert_ip_by_re(ip_str): pattern = '^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.' \ '(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.' \ '(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.' \ '(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$' re_compile = re.compile(pattern) if re_compile.match(ip_str): return True else: return False
注意:IPy不會(huì)處理0.0.0.0這種IP,認(rèn)為是合法的。類似 198.01.003.001 這種輸入,會(huì)自動(dòng)舍去前面的0,也認(rèn)為是合法的。
import IPy
def assert_ip(address): try: IPy.IP(address) return True except Exception as e: return False
6. Linux命令
cat xxx.log | gerp 'username' 忽略大小寫(xiě)cat xxx.log | gerp -i 'username'
- 獲取當(dāng)前目錄下占用磁盤(pán)空間最大的3個(gè)文件或目錄
當(dāng)時(shí)沒(méi)寫(xiě)出來(lái),只知道可以用ls head命令,平時(shí)用sort命令太少了
ls -al | sort -rnk 5 | head -3
sort -n是按照數(shù)字大小排序,-r是以相反順序,-k是指定需要排序的欄位,-t指定欄位分隔符(不寫(xiě)默認(rèn)是空格和\t)
top
7. 性能測(cè)試
沒(méi)做過(guò),略
8. 用例設(shè)計(jì)
對(duì)客戶端重構(gòu)登錄模塊進(jìn)行用例設(shè)計(jì),只有用戶名,密碼和登錄。不考慮其他功能。
這個(gè)題雖然簡(jiǎn)單,但我答得沒(méi)條理,上來(lái)就開(kāi)始陳述我的測(cè)試用例,只考慮了功能方面,沒(méi)有養(yǎng)成多維度系統(tǒng)得用例設(shè)計(jì)習(xí)慣,估計(jì)也是這個(gè)原因面試掛了。。。
重新整理用例:
功能性
輸入框的字符長(zhǎng)度限制、特殊字符處理、密碼輸入顯示*、不輸入用戶名和密碼點(diǎn)擊登錄是否調(diào)用接口?只輸入用戶名、只輸入密碼?錯(cuò)誤用戶名、錯(cuò)誤密碼?登錄成功后是否有其他配置項(xiàng)拉???登錄按鈕防重按?
安全性
密碼是否加密傳輸?SQL注入?
易用性
錯(cuò)誤提示是否友好?UI界面風(fēng)格?
兼容性
app升級(jí)后老用戶是否能登錄成功?新用戶登錄?
總結(jié)
從最近找工作發(fā)現(xiàn)測(cè)試的要求是越來(lái)越高了,需要會(huì)的技能也越來(lái)越多,功能、自動(dòng)化、性能、安全、寫(xiě)測(cè)試工具、測(cè)試平臺(tái)...甚至運(yùn)維的活也要測(cè)試來(lái)干 - -! 只能說(shuō)路漫漫其修遠(yuǎn)兮~ 繼續(xù)找窩。
|