软件(自动化)测试面试基础知识点汇总
為什么要做接口測試?
接口的由來: 連接前后端以及移動端。
因為不同端的工作進度不一樣,所以需要對開始出來的接口進行接口測試。
做接口測試的好處:
1、節約時間,縮短項目成本
2、提高工作效率
3、提高系統的健壯性
你在項目中如何做接口測試?
首先,當面試官問你這個問題的時候,不要忙著回答,因為我們知道:接口測試分為接口功能測試、接口性能測試、接口安全測試、接口自動化測試;所以你要先明確面試官的出發點是什么,可以進一步的明確面試官的問題,在進行回答。
其次,接口測試的幾大模塊你都要知道怎么做。
接口功能測試: 使用什么工具,比如使用Postman、Fillder、Jmeter來進行功能測試,請求參數是什么,返回的參數是什么,會去校驗返回的格式和值,校驗一些額外的什么內容。
接口性能測試: 使用測試工具或者自行編寫測試腳本,對接口進行壓力測試,當壓力測試并發值達到多少,當接口的響應值達到多少的時候,會根據報告去分析性能問題,定位問題。
接口安全測試: 在測試這個接口的時候,是否考慮到存在一些安全問題,要考慮在調用端的時候是否存在SQL注入,以及接口的參數是否做了一些強校驗,等等。
接口自動化測試: 使用的語言Java/Python + HttpRunner去做接口自動化測試;介紹你的接口自動化測試框架,以及框架內的各模塊的介紹,等等。
cookie、session和token
為什么要有cookie/session?
在客戶端瀏覽器向服務器發送請求,服務器做出響應之后,二者便會斷開連接(一次會話結束)。那么下次用戶再來請求服務器,服務器沒有任何辦法去識別此用戶是誰。比如web系統常用的用戶登錄功能,如果沒有cookie機制支持,那么只能通過查詢數據庫實現,并且要命的是每次刷新頁面都要重新輸入表單信息查詢一次數據庫才可以識別用戶,這會給開發人員帶來大量冗余工作并且簡單的用戶登錄功能會給服務器帶來巨大的壓力。
在此背景下,就急需一種機制來解決此問題。分析可知,以上需求的實現就要客戶端每次訪問服務器時從客戶端帶上一些數據(相當于身份證)告知服務器自己是誰。這個數據就是cookie!并且客戶端訪問服務器時不能將所有cookie都帶過去,比如訪問百度就不能把谷歌的cookie帶給百度,這個設置方式在后面介紹。
那么有了cookie,為什么還要有session呢?有了cookie可以向服務器證明用戶身份了,我們的web系統中是不是需要將用戶的詳細信息儲存在某個位置供頁面調用呢?用戶的詳細信息就包括姓名,年齡,性別等信息。而cookie是存在于客戶端的,將用戶詳細信息通過網絡發送到客戶端保存是極不安全的。且cookie大小不能超過4k,不能支持中文。這就限制cookie不能滿足存儲用戶信息的需求。這就需要一種機制在服務器端的某個域中存儲一些數據,這個域就是session。
總而言之,cookie/session的出現就是為了解決http協議無狀態的弊端,為了讓客戶端和服務端建立長久聯系而出現的。
cookie 概念
cookie是保存在本地終端的數據。cookie由服務器生成,發送給瀏覽器,瀏覽器把cookie以kv形式保存到某個目錄下的文本文件內,下一次請求同一網站時會把該cookie發送給服務器。由于cookie是存在客戶端上的,所以瀏覽器加入了一些限制確保cookie不會被惡意使用,同時不會占據太多磁盤空間,所以每個域的cookie數量是有限的。
cookie的組成有:名稱(key)、值(value)、有效域(domain)、路徑(域的路徑,一般設置為全局:"")、失效時間、安全標志(指定后,cookie只有在使用SSL連接時才發送到服務器(https))。下面是一個簡單的js使用cookie的例子:
用戶登錄時產生cookie:
document.cookie = “id=”+result.data[‘id’]+"; path=/";
document.cookie = “name=”+result.data[‘name’]+"; path=/";
document.cookie = “avatar=”+result.data[‘avatar’]+"; path=/";
session和token概念
session和token算是一類的,他們是兩種不同的服務器的驗證方式。
通俗來說,cookie會存一個value在客戶端本地,然后將value附到HTTP上發給服務器,那么服務器是怎么通過這個value來判斷用戶是否是登錄態的呢?這就是session和token做的事情。
session,服務器使用session把用戶的信息臨時保存在了服務器上,用戶離開網站后session會被銷毀。這種用戶信息存儲方式相對cookie來說更安全,可是session有一個缺陷:如果web服務器做了負載均衡,那么下一個操作請求到了另一臺服務器的時候session會丟失。
token的意思是“令牌”,是用戶身份的驗證方式,最簡單的token組成:uid(用戶唯一的身份標識)、time(當前時間的時間戳)、sign(簽名,由token的前幾位+以哈希算法壓縮成一定長的十六進制字符串,可以防止惡意第三方拼接token請求服務器)。還可以把不變的參數也放進token,避免多次查庫。
session過程
請求過程:
1、客戶端向服務器請求,發送用戶名和密碼
2、服務器生成sessionId,綁定用戶數據存儲在數據庫
3、服務器返回sessionId給客戶端
4、客戶端用cookie存儲sessionId,以后的請求都帶上這個sessionId
5、服務器如果收到這個sessionId,那么就去數據庫查找用戶數據,如果找到了說明驗證通過
6、服務器把驗證結果返回客戶端
token過程
請求過程:
1、客戶端向服務器請求,發送用戶名和密碼
2、服務器根據用戶信息通過加密生成token,用戶信息包括賬號,token過期時間等,具體由服務器自定義。
3、服務器返回token給客戶端
4、客戶端用cookie存儲token,以后的請求都帶上這個token
5、服務器把token解密,確認用戶信息是否正確,如經過正確就說明驗證通過。
6、服務器把驗證結果返回客戶端
cookie/session的區別與聯系
區別:
1、cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
2、cookie不是很安全,別人可以分析存放在本地的COOKIE并進行COOKIE欺騙
考慮到安全應當使用session。
3、session會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能
考慮到減輕服務器性能方面,應當使用COOKIE。
4、單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie,而session理論上沒有做限制。
5、所以個人建議:
將登陸信息等重要信息存放為SESSION
其他信息如果需要保留,可以放在COOKIE中
聯系:
session雖說存放在服務器端,但是仔細看剛才的執行流程你會明白,session是依賴于cookie的,這一點也是本篇文章想要著重強調的
cookie/session使用注意事項
1.cookie大小有限制 4k
2.cookie不能跨瀏覽器
3.cookie不支持中文
4.如果是安全性較高的數據應存放在session中,因為cookie存放在客戶端總會輕易被不法分子獲取
5.如果是訪問量特別大的網站,盡量不要在session中存儲用戶數據,因為每個用戶存一個session會給服務器造成很大的壓力
session、token優劣
session
由于sessionId和用戶信息相互綁定的數據庫存在服務器,所以服務器可以隨時讓發送出去的一個sessionId失效。這是保障安全的一種重要手段。
App通常用restful api跟server打交道。Rest是stateless的,也就是app不需要像browser那樣用cookie來保存session,因此用session token來標示自己就夠了,session/state由api server的邏輯處理。 如果你的后端不是stateless的rest api, 那么你可能需要在app里保存session.可以在app里嵌入webkit,用一個隱藏的browser來管理cookie session.
token
token的好處是比session更省空間和時間,服務器不需要去管理sessionId和用戶信息的數據庫,服務器收到token直接解密就可以驗證,不需要去數據庫查找驗證。
但是token發送出去之后,就只能等待它達到過期時間后才會失效,后臺無法對其進行控制。
新手使用session時常踩的坑
很多人使用session時希望用戶信息可以保存一段時間比如保存7天,于是配置了Tomcat的
<session-config><session-timeout>7天</session-timeout> </session-config>配置完后發現,關閉瀏覽器后再訪問還是取不到session。這是因為session的配置沒起作用嗎?不是的,其實session還是存在于服務器的,只是沒有設置cookie持久化,cookie默認就會在瀏覽器關閉時銷毀,所以叫做JSESSIONID的cookie也被銷毀了,再到服務器的時候沒有這個叫JSESSIONID的cookie就取不到相關的session了。
所以,如果想7天內都能訪問到session,需要將cookie也設置持久化!
以上內容來自博主:許佳佳333 、 IT_zhang81 、天空之城–
HTTPS與HTTP協議的區別,以及HTTP的8種請求方法
前言:
超文本傳輸協議HTTP協議被用于在Web瀏覽器和網站服務器之間傳遞信息,HTTP協議以明文方式發送內容,不提供任何方式的數據加密,如果攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就可以直接讀懂其中的信息,因此,HTTP協議不適合傳輸一些敏感信息,比如:信用卡號、密碼等支付信息。
為了解決HTTP協議的這一缺陷,需要使用另一種協議:安全套接字層超文本傳輸協議HTTPS,為了數據傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證服務器的身份,并為瀏覽器和服務器之間的通信加密。
一、HTTP和HTTPS的基本概念
HTTP:是互聯網上應用最為廣泛的一種網絡協議,是一個客戶端和服務器端請求和應答的標準(TCP),用于從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議,它可以使瀏覽器更加高效,使網絡傳輸減少。
HTTPS:是以安全為目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。
HTTPS協議的主要作用可以分為兩種:一種是建立一個信息安全通道,來保證數據傳輸的安全;另一種就是確認網站的真實性。
二、HTTP與HTTPS有什么區別?
HTTP協議傳輸的數據都是未加密的,也就是明文的,因此使用HTTP協議傳輸隱私信息非常不安全,為了保證這些隱私數據能加密傳輸,于是網景公司設計了SSL(Secure Sockets Layer)協議用于對HTTP協議傳輸的數據進行加密,從而就誕生了HTTPS。簡單來說,HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全。
HTTPS和HTTP的區別主要如下:
1、https協議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
2、http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是 80,后者是 443。
4、http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。
三、HTTPS的工作原理
我們都知道HTTPS能夠加密信息,以免敏感信息被第三方獲取,所以很多銀行網站或電子郵箱等等安全級別較高的服務都會采用HTTPS協議。
客戶端在使用HTTPS方式與Web服務器通信時有以下幾個步驟,如圖所示。
(1)客戶使用https的URL訪問Web服務器,要求與Web服務器建立SSL連接。
(2)Web服務器收到客戶端請求后,會將網站的證書信息(證書中包含公鑰)傳送一份給客戶端。
(3)客戶端的瀏覽器與Web服務器開始協商SSL連接的安全等級,也就是信息加密的等級。
(4)客戶端的瀏覽器根據雙方同意的安全等級,建立會話密鑰,然后利用網站的公鑰將會話密鑰加密,并傳送給網站。
(5)Web服務器利用自己的私鑰解密出會話密鑰。
(6)Web服務器利用會話密鑰加密與客戶端之間的通信。
四、HTTPS的優點
盡管HTTPS并非絕對安全,掌握根證書的機構、掌握加密算法的組織同樣可以進行中間人形式的攻擊,但HTTPS仍是現行架構下最安全的解決方案,主要有以下幾個好處:
(1)使用HTTPS協議可認證用戶和服務器,確保數據發送到正確的客戶機和服務器;
(2)HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全,可防止數據在傳輸過程中不被竊取、改變,確保數據的完整性。
(3)HTTPS是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增加了中間人攻擊的成本。
(4)谷歌曾在2014年8月份調整搜索引擎算法,并稱“比起同等HTTP網站,采用HTTPS加密的網站在搜索結果中的排名將會更高”。
五、HTTPS的缺點
雖然說HTTPS有很大的優勢,但其相對來說,還是存在不足之處的:
(1)HTTPS協議握手階段比較費時,會使頁面的加載時間延長近50%,增加10%到20%的耗電;
(2)HTTPS連接緩存不如HTTP高效,會增加數據開銷和功耗,甚至已有的安全措施也會因此而受到影響;
(3)SSL證書需要錢,功能越強大的證書費用越高,個人網站、小網站沒有必要一般不會用。
(4)SSL證書通常需要綁定IP,不能在同一IP上綁定多個域名,IPv4資源不可能支撐這個消耗。
(5)HTTPS協議的加密范圍也比較有限,在黑客攻擊、拒絕服務攻擊、服務器劫持等方面幾乎起不到什么作用。最關鍵的,SSL證書的信用鏈體系并不安全,特別是在某些國家可以控制CA根證書的情況下,中間人攻擊一樣可行。
六、http切換到HTTPS
如果需要將網站從http切換到https到底該如何實現呢?
這里需要將頁面中所有的鏈接,例如js,css,圖片等等鏈接都由http改為https。例如:http://www.baidu.com改為https://www.baidu.com
BTW,這里雖然將http切換為了https,還是建議保留http。所以我們在切換的時候可以做http和https的兼容,具體實現方式是,去掉頁面鏈接中的http頭部,這樣可以自動匹配http頭和https頭。例如:將http://www.baidu.com改為//www.baidu.com。然后當用戶從http的入口進入訪問頁面時,頁面就是http,如果用戶是從https的入口進入訪問頁面,頁面即是https的。
HTTP請求的方法:
1、OPTIONS
返回服務器針對特定資源所支持的HTTP請求方法,也可以利用向web服務器發送‘*’的請求來測試服務器的功能性
2、HEAD
向服務器索與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以再不必傳輸整個響應內容的情況下,就可以獲取包含在響應小消息頭中的元信息。
3、GET
向特定的資源發出請求。它本質就是發送一個請求來取得服務器上的某一資源。資源通過一組HTTP頭和呈現數據(如HTML文本,或者圖片或者視頻等)返回給客戶端。GET請求中,永遠不會包含呈現數據。
4、POST
向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。 Loadrunner中對應POST請求函數:web_submit_data,web_submit_form
5、PUT
向指定資源位置上傳其最新內容
6、DELETE
請求服務器刪除Request-URL所標識的資源
7、TRACE
回顯服務器收到的請求,主要用于測試或診斷
8、CONNECT
HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。
GET和 POST區別
1、區別:
get請求無消息體,只能攜帶少量數據
post請求有消息體,可以攜帶大量數據
2、攜帶數據的方式:
get請求將數據放在url地址中
post請求將數據放在消息體中(Body)
GET請求請提交的數據放置在HTTP請求協議頭中,而POST提交的數據則放在實體數據中;
GET方式提交的數據最多只能有1024字節,而POST則沒有此限制。
以上HTTP和HTTPS內容來自博主 豆豆蛙 和 開猿節流
HTTP 狀態碼詳解
1xx(臨時響應)
2xx(成功)
3xx(重定向)
4xx(請求錯誤)
5xx(服務器錯誤)
1xx(臨時響應)
100(繼續) 請求者應繼續進行請求。服務器返回此代碼以表示,服務器已收到某項請求的第一部分,正等待接收剩余部分。
101(切換協議) 請求者已要求服務器切換協議,服務器已確認并準備進行切換。
2xx(成功)
200(成功) 說明服務器成功處理了相應請求。通常,這表示服務器已提供了請求的網頁。如果您的 robots.txt 文件顯示為此狀態,則表示 檢測工具 已成功檢索到該文件。
201(已創建) 請求成功且服務器已創建了新的資源。
202(已接受) 服務器已接受相應請求,但尚未對其進行處理。
203(非授權信息) 服務器已成功處理相應請求,但返回了可能來自另一來源的信息。
204(無內容) 服務器已成功處理相應請求,但未返回任何內容。
205(重置內容) 服務器已成功處理相應請求,但未返回任何內容。與 204 響應不同,此響應要求請求者重置文檔視圖(例如清除表單內容以輸入新內容)。
206(部分內容) 服務器成功處理了部分 GET 請求。
3xx(重定向)
300(多種選擇) 服務器可以根據請求來執行多項操作,例如:按照請求者(用戶代理)的要求來選擇某項操作或者展示列表以便請求者選擇其中某項操作。
301(永久移動) 請求的網頁已永久移動到新位置。服務器返回此響應(作為對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。您應使用此代碼通知 檢測工具 某個網頁或網站已被永久移動到新位置
302(臨時移動) 服務器目前正從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以后的請求。此代碼與響應 GET 和 HEAD 請求的 301 代碼類似,會自動將請求者轉到不同的位置。但由于 檢測工具 會繼續抓取原有位置并將其編入索引,因此您不應使用此代碼來通知 檢測工具 某個頁面或網站已被移動。
303(查看其他位置) 當請求者應對不同的位置進行單獨的 GET 請求以檢索響應時,服務器會返回此代碼。對于除 HEAD 請求之外的所有請求,服務器會自動轉到其他位置
304(未修改) 請求的網頁自上次請求后再也沒有修改過。當服務器返回此響應時,不會返回相關網頁的內容。如果網頁自請求者上次請求后再也沒有更改過,您應當將服務器配置為返回此響應(稱為 If-Modified-Since HTTP 標頭)。服務器可以告訴 檢測工具 自從上次抓取后網頁沒有變更,進而節省帶寬和開銷。
305(使用代理) 請求者只能使用代理訪問請求的網頁。如果服務器返回此響應,那么,服務器還會指明請求者應當使用的代理。
307(臨時重定向) 服務器目前正從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以后的請求。此代碼與響應 GET 和 HEAD 請求的 301 代碼類似,會自動將請求者轉到不同的位置。但由于 檢測工具 會繼續抓取原有位置并將其編入索引,因此您不應使用此代碼來通知 檢測工具 某個頁面或網站已被移動。
4xx(請求錯誤)
400(錯誤請求) 服務器不理解相應請求的語法。
401(未授權) 請求要求進行身份驗證。登錄后,服務器可能會返回對頁面的此響應。
403(已禁止) 服務器正在拒絕相應請求。如果 檢測工具 在嘗試抓取網站的有效網頁時收到此狀態代碼(您可在網站站長工具中運行工具下的抓取錯誤頁上進行查看),則可能是因為您的服務器或主機正在阻止 檢測工具 進行訪問。
404(未找到) 服務器找不到請求的網頁。例如,如果相應請求是針對服務器上不存在的網頁進行的,那么服務器通常會返回此代碼。如果您的網站上沒有 robots.txt 文件,而您在 網站站長工具中的已攔截的網址頁上看到此狀態,那么這就是正確的狀態。然而,如果您有 robots.txt 文件而又發現了此狀態,那么,這說明您的 robots.txt 文件可能是命名錯誤或位于錯誤的位置。(該文件應當位于頂級域名上,且應當名為 robots.txt)。
405(方法禁用) 禁用相應請求中所指定的方法。
406(不接受) 無法使用相應請求的內容特性來響應請求的網頁。
407(需要代理授權) 此狀態代碼與 401(未授權)類似,但卻指定了請求者應當使用代理進行授權。如果服務器返回此響應,那么,服務器還會指明請求者應當使用的代理。
408(請求超時) 服務器在等待請求時超時。
409(沖突) 服務器在完成請求時遇到沖突。服務器必須在響應中包含該沖突的相關信息。服務器在響應與前一個請求相沖突的 PUT 請求時可能會返回此代碼,同時會提供兩個請求的差異列表。
410(已刪除) 如果請求的資源已被永久刪除,那么服務器會返回此響應。該代碼與 404(未找到)代碼類似,但在資源以前有但現在已經不復存在的情況下,有時會替代 404 代碼出現。如果資源已永久刪除,您應使用 301 指定資源的新位置。
411(需要有效長度) 服務器不會接受包含無效內容長度標頭字段的請求。
412(未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。
413(請求實體過大) 服務器無法處理相應請求,因為請求實體過大,已超出服務器的處理能力。
414(請求的 URI 過長) 請求的 URI(通常為網址)過長,服務器無法進行處理。
415(不支持的媒體類型) 相應請求的格式不受請求頁面的支持。
416(請求范圍不符合要求) 如果相應請求是針對網頁的無效范圍進行的,那么服務器會返回此狀態代碼。
417(未滿足期望值) 服務器未滿足“期望”請求標頭字段的要求。
5xx(服務器錯誤)
500(服務器內部錯誤) 服務器遇到錯誤,無法完成相應請求。
501(尚未實施) 服務器不具備完成相應請求的功能。例如,當服務器無法識別請求方法時,可能便會返回此代碼
502(錯誤網關) 服務器作為網關或代理,從上游服務器收到了無效的響應。
503(服務不可用) 目前無法使用服務器(由于超載或進行停機維護)。通常,這只是暫時狀態。
504(網關超時) 服務器作為網關或代理,未及時從上游服務器接收請求。
505(HTTP 版本不受支持) 服務器不支持相應請求中所用的 HTTP 協議版本。
.
.
TCP與UDP的區別
TCP和UDP的最完整的區別
TCP 是面向連接的,UDP 是面向無連接的
UDP程序結構較簡單
TCP 是面向字節流的,UDP 是基于數據報的
TCP 保證數據正確性,UDP 可能丟包
TCP 保證數據順序,UDP 不保證
什么是面向連接,什么是面向無連接
在互通之前,面向連接的協議會先建立連接,如 TCP 有三次握手,而 UDP 不會
TCP 為什么是可靠連接
- 通過 TCP 連接傳輸的數據無差錯,不丟失,不重復,且按順序到達。
- TCP 報文頭里面的序號能使 TCP 的數據按序到達
- 報文頭里面的確認序號能保證不丟包,累計確認及超時重傳機制
- TCP 擁有流量控制及擁塞控制的機制
UDP 的主要應用場景
- 需要資源少,網絡情況穩定的內網,或者對于丟包不敏感的應用,比如 DHCP 就是基于 UDP 協議的。
- 不需要一對一溝通,建立連接,而是可以廣播的應用。因為它不面向連接,所以可以做到一對多,承擔廣播或者多播的協議。
- 需要處理速度快,可以容忍丟包,但是即使網絡擁塞,也毫不退縮,一往無前的時候
基于 UDP 的幾個例子
- 直播。直播對實時性的要求比較高,寧可丟包,也不要卡頓的,所以很多直播應用都基于 UDP 實現了自己的視頻傳輸協議
- 實時游戲。游戲的特點也是實時性比較高,在這種情況下,采用自定義的可靠的 UDP 協議,自定義重傳策略,能夠把產生的延遲降到最低,減少網絡問題對游戲造成的影響
- 物聯網。一方面,物聯網領域中斷資源少,很可能知識個很小的嵌入式系統,而維護 TCP 協議的代價太大了;另一方面,物聯網對實時性的要求也特別高。比如 Google 旗下的 Nest 簡歷 Thread Group,推出了物聯網通信協議 Thread,就是基于 UDP 協議的
TCP/IP 四層協議
也可參考文章:TCP/IP協議組——完整工作過程分析
應用層
傳輸層
網絡層
數據鏈路層
(物理層)
2.分層的目的:
(1)將網絡的通信過程劃分為小一些、簡單一些的部件,有助于各個部件的開發、設計和故障排除;
(2)通過網絡組件的標準化,允許多個供應商開發,鼓勵產業標準化;
(3)允許各種類型的網絡硬件和軟件相互通信;
(4)防止某一層的改動影響到其它層,有利于開發(主要)。
3.各層的主要協議:
(1)應用層: HTTP(超文本傳輸協議 80), HTTPS(更安全的超文本傳輸協議 443), FTP(文件傳輸協議), SMTP(簡單郵件傳輸協議), DNS(域名服務),ping命令(調試網絡環境),OSPF(開放最短路徑優先);
應用層處理應用程序的邏輯,且應用層在用戶空間。
(2)傳輸層: UDP(用戶數據報協議), TCP(傳輸控制協議);
傳輸層采用端到端的通信方式,其中:
UDP:不可靠的,無連接的,基于數據報的協議;
TCP:可靠的,面向連接的,基于字節流的協議;
(3)網絡層: IP(因特網協議), ICMP(控制報文協議), ARP(地址解析協議), RARP(反向地址轉換協議);
網絡層主要實現數據包的選路和轉發。
(4)數據鏈路層: 傳輸單位是幀,分為邏輯鏈路控制子層(LLC),媒體訪問控制子層(MAC);
數據鏈路層是網卡接口的驅動程序,處理數據在物理媒介的傳輸
(5)物理層: 傳輸單位是比特流
傳輸的主要介質:集線器、中繼器、調制解調器、網線、雙絞線、同軸電纜。
1、一次完整的HTTP請求與響應涉及了哪些知識?(包括TCP三次握手和TCP的四次揮手)
TCP 的三次握手 建立連接
所有的問題,首先都要建立連接,所以首先是連接維護的問題
TCP 的建立連接稱為三次握手,可以簡單理解為下面這種情況
A:您好,我是 A
B:您好 A,我是 B
A:您好 B
至于為什么是三次握手我這里就不細講了,可以看其他人的博客,總結的話就是通信雙方全都有來有回
對于 A 來說它發出請求,并收到了 B 的響應,對于 B 來說它響應了 A 的請求,并且也接收到了響應。
TCP 的三次握手除了建立連接外,主要還是為了溝通 TCP 包的序號問題。
A 告訴 B,我發起的包的序號是從哪個號開始的,B 同樣也告訴 A,B 發起的 包的序號是從哪個號開始的。
雙方建立連接之后需要共同維護一個狀態機,在建立連接的過程中,雙方的狀態變化時序圖如下所示
狀態變化時序圖
這是網上經常見到的一張圖,剛開始的時候,客戶端和服務器都處于 CLOSED 狀態,先是服務端主動監聽某個端口,處于 LISTEN 狀態。然后客戶端主動發起連接 SYN,之后處于 SYN-SENT 狀態。服務端接收了發起的連接,返回 SYN,并且 ACK ( 確認 ) 客戶端的 SYN,之后處于 SYN-SENT 狀態。客戶端接收到服務端發送的 SYN 和 ACK 之后,發送 ACK 的 ACK,之后就處于 ESTAVLISHED 狀態,因為它一發一收成功了。服務端收到 ACK 的 ACK 之后,也處于 ESTABLISHED 狀態,因為它也一發一收了。
TCP 四次揮手
說完建立連接,再說下斷開連接,也被稱為四次揮手,可以簡單理解如下
A:B 啊,我不想玩了
B:哦,你不想玩了啊,我知道了
這個時候,只是 A 不想玩了,即不再發送數據,但是 B 可能還有未發送完的數據,所以需要等待 B 也主動關閉。
B:A 啊,好吧,我也不玩了,拜拜
A:好的,拜拜
這樣整個連接就關閉了,當然上面只是正常的狀態,也有些非正常的狀態(比如 A 說完不玩了,直接跑路,B 發起的結束得不到 A 的回答,不知道該怎么辦或則 B 直接跑路 A 不知道該怎么辦),TCP 協議專門設計了幾個狀態來處理這些非正常狀態
斷開的時候,當 A 說不玩了,就進入 FIN_WAIT_1 的狀態,B 收到 A 不玩了的消息后,進入 CLOSE_WAIT 的狀態。
A 收到 B 說知道了,就進入 FIN_WAIT_2 的狀態,如果 B 直接跑路,則 A 永遠處與這個狀態。TCP 協議里面并沒有對這個狀態的處理,但 Linux 有,可以調整 tcp_fin_timeout 這個參數,設置一個超時時間。
如果 B 沒有跑路,A 接收到 B 的不玩了請求之后,從 FIN_WAIT_2 狀態結束,按說 A 可以跑路了,但是如果 B 沒有接收到 A 跑路的 ACK 呢,就再也接收不到了,所以這時候 A 需要等待一段時間,因為如果 B 沒接收到 A 的 ACK 的話會重新發送給 A,所以 A 的等待時間需要足夠長。
2、知乎:TCP/IP 協議詳解
Linux查看某個特定的文件名路徑的命令
find . -name '*.py' #查看以.py結尾的文件路徑#獲得所有py文件路徑,去重復,刪除開頭的“./”字符 find . -name '*.py' -exec dirname {} \;Linux查看日志ERROR出現次數的命令
查找Error日志并統計次數
# 查找Error日志并統計次數 grep -o -E 'ERROR'| sort | uniq -c查找error日志并存儲到指定文件
#查找日志文件testLog.log中的ERROR并將其存儲到指定的文件error.log里面 tail -f testLog.log | grep -o -E 'Error' >> error.logLinux 替換文件內容
sed命令下批量替換文件內容
格式: sed -i “s/查找字段/替換字段/g” grep 查找字段 -rl 路徑 文件名
-i 表示inplace edit,就地修改文件
-r 表示搜索子目錄
-l 表示輸出匹配的文件名
s表示替換,d表示刪除
示例:sed -i “s/shan/hua/g” lishan.txt
把當前目錄下lishan.txt里的shan都替換為hua
Linux 面試題:
Linux命令,在當前目錄的所有log文件中找到包含error單詞的行,并把error替換成warn后,存入test文件。(并未實際驗證準確性)
Linux查看文件前幾行和后幾行的命令
可以使用head(查看前幾行)、tail(查看末尾幾行)兩個命令。例如:
查看/etc/profile的前10行內容,應該是:
查看/etc/profile的最后5行內容,應該是:
tail -n 5 /etc/profile如果想同時查看可以將前10行和后5行的顯示信息通過輸出重定向的方法保存到一個文檔,這樣查看文檔即可一目了然。
例如:
將內容輸出到/home/test文件中
查看的話只需要打開test文件即可。
cat /home/test
【一】從第3000行開始,顯示1000行。即顯示3000~3999行
cat filename | tail -n +3000 | head -n 1000
【二】顯示1000行到3000行
cat filename| head -n 3000 | tail -n +1000
*注意兩種方法的順序
分解:
tail -n 1000:顯示最后1000行
tail -n +1000:從1000行開始顯示,顯示1000行以后的
head -n 1000:顯示前面1000行
【三】用sed命令
sed -n '5,10p' filename這樣你就可以只查看文件的第5行到第10行。
Linux 查看錯誤日志的Shell命令:
awk命令: awk '/ERROR[12]/ { err1_cnt+=gsub(/ERROR1/, ""); err2_cnt+=gsub(/ERROR2/, ""); } END { print err1_cnt, err2_cnt; }' /tmp/a.logLinux系統監控命令整理匯總-掌握CPU,內存,磁盤IO等找出性能瓶頸
答案:
例子請點擊這里
Linux 壓縮與解壓命令
壓縮
// 將目錄里所有jpg文件打包成 tar.jpg tar –cvf jpg.tar *.jpg ? // 將目錄里所有jpg文件打包成 jpg.tar 后, //并且將其用 gzip 壓縮,生成一個 gzip 壓縮過的包,命名為 jpg.tar.gz tar –czf jpg.tar.gz *.jpg ? // 將目錄里所有jpg文件打包成 jpg.tar 后, //并且將其用 bzip2 壓縮,生成一個 bzip2 壓縮過的包,命名為jpg.tar.bz2 tar –cjf jpg.tar.bz2 *.jpg ? // 將目錄里所有 jpg 文件打包成 jpg.tar 后,并且將其用 compress 壓縮,生成一個 umcompress 壓縮過的包,命名為jpg.tar.Z tar –cZf jpg.tar.Z *.jpg ? // rar格式的壓縮,需要先下載 rar for linux rar a jpg.rar *.jpg ? // zip格式的壓縮,需要先下載 zip for linux zip jpg.zip *.jpg解壓
tar –xvf file.tar // 解壓 tar 包 tar -xzvf file.tar.gz // 解壓 tar.gz tar -xjvf file.tar.bz2 // 解壓 tar.bz2 tar –xZvf file.tar.Z // 解壓 tar.Z unrar e file.rar // 解壓 rar unzip file.zip // 解壓 zip總結
1、*.tar 用 tar –xvf 解壓 2、*.gz 用 gzip -d或者gunzip 解壓 3、*.tar.gz和*.tgz 用 tar –xzf 解壓 4、*.bz2 用 bzip2 -d或者用bunzip2 解壓 5、*.tar.bz2用tar –xjf 解壓 6、*.Z 用 uncompress 解壓 7、*.tar.Z 用tar –xZf 解壓 8、*.rar 用 unrar e解壓 9、*.zip 用 unzip 解壓Java系列
題目要求:給定一個字符串數組,判斷每個字符出現多少次?
解決思路: 利用Map的特性:即Map集合中如果兩個key(鍵)值是一樣相同的,那么,后放(put)入的值會將前面存在的value(值)替換掉,也就是覆蓋了前面的value。
所以把字符數組中的字符當作key,每遇到相同的key,value值加1即可。代碼如下:
Java面試題:兩個數組合并排序的java實現
答案:兩個數組合并排序的java實現
Java面試題:兩個有序數組合并到一個有序數組(時間復雜度低)
答案:java 兩個有序數組合并到一個有序數組(時間復雜度低)
Java面試題:統計一個字符串中最長連續子串
in:aabbbaa
out:aaa
in:abba
out:bb
答案:
Java面試題:編寫程序在控制臺輸出斐波那契數列前20項,每輸出5個數換行
參考博文:隨風fds
解法一:定義三個變量
public class Demo1 {// 定義三個變量方法public static void main(String[] args) {int a = 1, b = 1, c = 0;System.out.println("斐波那契數列前20項為:");System.out.print(a + "\t" + b + "\t");//輸出第一二項//因為前面還有兩個1、1 所以i<=18for (int i = 1; i <= 18; i++) {c = a + b;a = b;b = c;System.out.print(c + "\t");if ((i + 2) % 5 == 0)System.out.println();}} }解法二:定義數組方法
public class Demo2 {// 定義數組方法public static void main(String[] args) {int arr[] = new int[20];arr[0] = arr[1] = 1;for (int i = 2; i < arr.length; i++) {arr[i] = arr[i - 1] + arr[i - 2];}System.out.println("斐波那契數列的前20項如下所示:");for (int i = 0; i < arr.length; i++) {if (i % 5 == 0)System.out.println();System.out.print(arr[i] + "\t");}}}解法二:使用遞歸方法
public class Demo3 {// 使用遞歸方法private static int getFibo(int i) {if (i == 1 || i == 2)return 1;elsereturn getFibo(i - 1) + getFibo(i - 2);}public static void main(String[] args) {System.out.println("斐波那契數列的前20項為:");for (int j = 1; j <= 20; j++) {System.out.print(getFibo(j) + "\t");if (j % 5 == 0)System.out.println();}} }Java面試題:實現斐波那契數列輸出指定的第f(n)個
參考博主:瓜牛呱呱
1,1,2,3,5,8,13
輸出:
f(2)=2
f(3)=3
思路:
其實很簡單,可以理解為:
F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
比如這樣一個數列:1、1、2、3、5、8、13、21、34、……
下面我們就來實現,給定一個n,求f(n)的值
解法一:遞歸解法
遞歸方法其實是對方法定義完美的一對一實現,但是時間復雜度為O(2的n次方)
通過遞歸的代碼發現,其實有很大一部分是重復算的,如果n趨近于無限大,那么就有一半是重復計算的。
代碼如下:
/*** 采用遞歸的方式實現的* 時間復雜度為O(2的N次方)* @param n* @return*/public static int f1(int n){if (n == 0){return 0;}if (n == 1){return 1;}return f1(n-1) + f1(n-2);}解法二:遍歷解法
遍歷的方式相比于遞歸的方式時間復雜度好很多,為O(n)
但是遍歷的方式還不是時間復雜度最低的解決方案!更短請看解法三。
代碼如下:
/*** 采用遍歷的方式實現* 時間復雜度為O(N)* @param n* @return*/public static int f2(int n){int f0 = 0;if (n == 0) {return f0;}int f1 = 1;if (n == 1) {return f1;}int f2 = 0;for (int i=2; i<=n; i++){f2 = f0 + f1;f0 = f1;f1 = f2;}return f2;}解法三:矩陣解法
實現的推導原理如下:
數列的遞推公式為:f(1)=1,f(2)=2,f(n)=f(n-1)+f(n-2)(n>=3)
用矩陣表示為:
進一步,可以得出直接推導公式:
也有如下的推導(這一塊不是很理解,懂的可以幫忙在評論區解釋一下哈):
矩陣的解法時間復雜度為O(logn)
代碼如下:
方法四:利用數組
但是遞歸算法會增加整個過程的復雜度,例如我要求fib(7)的時候要算fib(6)+fib(5),而fib(6)=fib(5)+fib(4),此時計算機只會非常愚蠢的再算一次fib(5),從而增加了整體的復雜度,所以解決辦法是建立一個數組將每次前面算出來的fib(i)進行存儲,以免以后造成重復的運算,此時的代碼如下:
測試上述結果:
public static void main(String[] args) {//輸出前10個數for (int i = 0; i < 10; i++) {System.out.println("========"+i+"========");System.out.println("遞歸方式:" + f1(i));System.out.println("遍歷方式:" + f2(i));System.out.println("矩陣二分的方式:" + f3(i));}}Java面試題:輸出固定長度n的數字+字母的字符串
package TestDemo; import java.util.Random; public class GetNumberWords {public static void main(String[] args) {for(int i = 0;i < 10;i++){String password = getRandomPassword(8);System.out.println(password);}}//指定長度的隨機密碼生成public static String makeRandomPassword(int len){char charr[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890~!@#$%^&*.?".toCharArray();StringBuilder sb = new StringBuilder();Random r = new Random();for (int x = 0; x < len; ++x) {sb.append(charr[r.nextInt(charr.length)]);}return sb.toString();}//獲取驗證過的隨機密碼public static String getRandomPassword(int len) {String result = null;result = makeRandomPassword(len);if (result.matches(".*[a-z]{1,}.*") && result.matches(".*[A-Z]{1,}.*") && result.matches(".*[0-9]{1,}.*") && result.matches(".*[~!@#$%^&*\\.?]{1,}.*")) {return result;}return getRandomPassword(len);} }Java面試題:輸出9*9乘法表
public static void main(String[] args) {for(int i=1;i<10;i++) {for(int j=1;j<=i;j++) {System.out.print(j+"*"+i+"="+(i*j)+"\t");// \t 跳到下一個TAB位置} System.out.println(""); }輸出:
1×1=1
1×2=2 2×2=4
1×3=3 2×3=6 3×3=9
1×4=4 2×4=8 3×4=12 4×4=16
1×5=5 2×5=10 3×5=15 4×5=20 5×5=25
1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
變換一下順序如下:
public class MultiplicationTable {public static void main(String[] args) {for(int i=9;i>0;i--) {for(int j=1,k=10-i;j<=i;j++,k++) {System.out.print(j+"×"+k+"="+k*j+"\t");// \t 跳到下一個TAB位置}System.out.println();}} }輸出
11=1 22=4 33=9 44=16 55=25 66=36 77=49 88=64 99=81
12=2 23=6 34=12 45=20 56=30 67=42 78=56 89=72
13=3 24=8 35=15 46=24 57=35 68=48 79=63
14=4 25=10 36=18 47=28 58=40 69=54
15=5 26=12 37=21 48=32 59=45
16=6 27=14 38=24 49=36
17=7 28=16 39=27
18=8 29=18
1*9=9
==與equals的區別與聯系
== 比較的是變量(棧)內存中存放的對象的(堆)內存地址,用來判斷兩個對象的地址是否相同,即是否是指相同一個對象。比較的是真正意義上的指針操作。
equals用來比較的是兩個對象的內容是否相等,由于所有的類都是繼承自java.lang.Object類的,所以適用于所有對象,如果沒有對該方法進行覆蓋的話,調用的仍然是Object類中的方法,而Object中的equals方法返回的卻是== 的判斷。
java中的數據類型可以分為兩大類:
1、8種基本數據類型
byte, short, char, int, long, float, double, boolean
基本數據類型之間的比較需要用雙等號(==),因為他們比較的是值
封裝類:Byte, Short, Character, Integer, Long, Float, Double, Boolean
2、引用數據類型
接口、類、數組等非基本數據類型
Java中的字符串String屬于引用數據類型。因為String是一個類
equals()方法介紹
Java中所有的類都是繼承與Object這個基類的,在Object類中定義了一個equals方法,這個方法的初始行為是比較對象的內存地址,但在一些類庫中已經重寫了這個方法(一般都是用來比較對象的成員變量值是否相同),比如:String,Integer,Date 等類中,所以他們不再是比較類在堆中的地址了、
Object類中源碼
String類中重寫后的代碼
public boolean equals(Object var1) {if (this == var1) {return true;} else {if (var1 instanceof String) {String var2 = (String)var1;int var3 = this.value.length;if (var3 == var2.value.length) {char[] var4 = this.value;char[] var5 = var2.value;for(int var6 = 0; var3-- != 0; ++var6) {if (var4[var6] != var5[var6]) {return false;}}return true;}}return false;}}總結:
對于復合數據類型之加粗樣式間進行equals比較,在沒有覆寫equals方法的情況下,他們之間的比較還是內存中的存放位置的地址值,跟雙等號(==)的結果相同;如果被復寫,按照復寫的要求來。
== 的作用:
基本類型:比較的就是值是否相同
引用類型:比較的就是地址值是否相同
equals 的作用:
引用類型:默認情況下,比較的是地址值,重寫該方法后比較對象的成員變量值是否相同。
以上內容來自博主 流逝的青春
Java實現兩個字符串的比較
JAVA中字符串比較equals是用來比較字符串是否相等的,==比較是否為相同reference,不能用做字符串的比較.如果要比較大小應該用compareto(String),它是依次比較字符串的每個字符的大小。
字符串常用的比較如下:
equals() //作用:比較值
equalsIgnoreCase() //作用:比較值,不區分大小
regionMatches() //判斷string的子串是否相同
compareTo() //作用:按字典順序比較兩個字符串
contains() //作用:包含
Java重寫與重載的區別
1.重寫(Override)
從字面上看,重寫就是 重新寫一遍的意思。其實就是在子類中把父類本身有的方法重新寫一遍。子類繼承了父類原有的方法,但有時子類并不想原封不動的繼承父類中的某個方法,所以在方法名,參數列表,返回類型(除過子類中方法的返回值是父類中方法返回值的子類時)都相同的情況下, 對方法體進行修改或重寫,這就是重寫。但要注意子類函數的訪問修飾權限不能少于父類的。
例如:
重寫 總結:
- 發生在父類與子類之間
- 方法名,參數列表,返回類型(除過子類中方法的返回類型是父類中返回類型的子類)必須相同
- 訪問修飾符的限制一定要大于被重寫方法的訪問修飾符(public>protected>default>private)
- 重寫方法一定不能拋出新的檢查異常或者比被重寫方法申明更加寬泛的檢查型異常
2.重載(Overload)
在一個類中,同名的方法如果有不同的參數列表(參數類型不同、參數個數不同甚至是參數順序不同)則視為重載。同時,重載對返回類型沒有要求,可以相同也可以不同,但不能通過返回類型是否相同來判斷重載。
例如:
重載 總結:
- 重載Overload是一個類中多態性的一種表現
- 重載要求同名方法的參數列表不同(參數類型,參數個數甚至是參數順序)
- 重載的時候,返回值類型可以相同也可以不相同。無法以返回型別作為重載函數的區分標準
Java - 面試時,問:重載(Overload)和重寫(Override)的區別?
答:方法的重載和重寫都是實現多態的方式
區別在于重載實現的是編譯時的多態性,而重寫實現的是運行時的多態性。
重載發生在一個類中,同名的方法如果有不同的參數列表(參數類型不同、參數個數不同或者二者都不同)則視為重載;
重寫發生在子類與父類之間,重寫要求子類被重寫方法與父類被重寫方法有相同的參數列表,有兼容的返回類型,比父類被重寫方法更好訪問,不能比父類被重寫方法聲明更多的異常(里氏代換原則)。重載對返回類型沒有特殊的要求,不能根據返回類型進行區分。
淺談JDK、JRE、JVM區別與聯系
JDK是 Java 語言的軟件開發工具包(SDK)。在JDK的安裝目錄下有一個jre目錄,里面有兩個文件夾bin和lib,在這里可以認為bin里的就是jvm,lib中則是jvm工作所需要的類庫,而jvm和 lib合起來就稱為jre。
一、JDK
JDK(Java Development Kit) 是整個JAVA的核心,包括了Java運行環境(Java Runtime Envirnment),一堆Java工具(javac/java/jdb等)和Java基礎的類庫(即Java API 包括rt.jar)。
JDK是java開發工具包,基本上每個學java的人都會先在機器 上裝一個JDK,那他都包含哪幾部分呢?在目錄下面有 六個文件夾、一個src類庫源碼壓縮包、和其他幾個聲明文件。其中,真正在運行java時起作用的 是以下四個文件夾:bin、include、lib、 jre。有這樣一個關系,JDK包含JRE,而JRE包 含JVM。
(注意:這里的bin、lib文件夾和jre里的bin、lib是 不同的)
總的來說JDK是用于java程序的開發,而jre則是只能運行class而沒有編譯的功能。
二、JRE
JRE(Java Runtime Environment,Java運行環境),包含JVM標準實現及Java核心類庫。JRE是Java運行環境,并不是一個開發環境,所以沒有包含任何開發工具(如編譯器和調試器)
JRE是指java運行環境。光有JVM還不能成class的 執行,因為在解釋class的時候JVM需要調用解釋所需要的類庫lib。 (jre里有運行.class的java.exe)
JRE ( Java Runtime Environment ),是運行 Java 程序必不可少的(除非用其他一些編譯環境編譯成.exe可執行文件……),JRE的 地位就象一臺PC機一樣,我們寫好的Win64應用程序需要操作系統幫 我們運行,同樣的,我們編寫的Java程序也必須要JRE才能運行。
三、JVM
JVM(Java Virtual Machine),即java虛擬機, java運行時的環境,JVM是一種用于計算設備的規范,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。針對java用戶,也就是擁有可運行的.class文件包(jar或者war)的用戶。里面主要包含了jvm和java運行時基本類庫(rt.jar)。rt.jar可以簡單粗暴地理解為:它就是java源碼編譯成的jar包。Java虛擬機在執行字節碼時,把字節碼解釋成具體平臺上的機器指令執行。這就是Java的能夠“一次編譯,到處運行”的原因。
四、JDK、JRE、JVM三者的聯系與區別
1.三者聯系:
JVM不能單獨搞定class的執行,解釋class的時候JVM需要調用解釋所需要的類庫lib。在JDK下面的的jre目錄里面有兩個文件夾bin和lib,在這里可以認為bin里的就是jvm,lib中則是jvm工作所需要的類庫,而jvm和 lib和起來就稱為jre。JVM+Lib=JRE。總體來說就是,我們利用JDK(調用JAVA API)開發了屬于我們自己的JAVA程序后,通過JDK中的編譯程序(javac)將我們的文本java文件編譯成JAVA字節碼,在JRE上運行這些JAVA字節碼,JVM解析這些字節碼,映射到CPU指令集或OS的系統調用。
2.三者區別:
a.JDK和JRE區別:在bin文件夾下會發現,JDK有javac.exe而JRE里面沒有,javac指令是用來將java文件編譯成class文件的,這是開發者需要的,而用戶(只需要運行的人)是不需要的。JDK還有jar.exe, javadoc.exe等等用于開發的可執行指令文件。這也證實了一個是開發環境,一個是運行環境。
b.JRE和JVM區別:JVM并不代表就可以執行class了,JVM執行.class還需要JRE下的lib類庫的支持,尤其是rt.jar。
經典SQL面試題
sql查詢:部門工資前三高的員工和部門工資最高的員工
創建表:
Create table If Not Exists Employee (Id int, Name varchar(255), Salary int, DepartmentId int);
Create table If Not Exists Department (Id int, Name varchar(255));
Truncate table Employee;
insert into Employee (Id, Name, Salary,DepartmentId) values (‘1’, ‘Joe’, ‘70000’, ‘1’);
insert into Employee (Id, Name, Salary,DepartmentId) values (‘2’, ‘Henry’, ‘80000’, ‘2’);
insert into Employee (Id, Name, Salary,DepartmentId) values (‘3’, ‘Sam’, ‘60000’, ‘2’);
insert into Employee (Id, Name, Salary,DepartmentId) values (‘4’, ‘Max’, ‘90000’, ‘1’);
insert into Employee (Id, Name, Salary,DepartmentId) values (‘5’, ‘Randy’, ‘85000’, ‘1’);
Truncate table Department;
insert into Department (Id, Name) values(‘1’, ‘IT’);
insert into Department (Id, Name) values(‘2’, ‘Sales’);
部門工資前三高的員工
Employee 表包含所有員工信息,每個員工有其對應的 Id, salary 和 department Id 。
±-----±------±-------±-------------+
| Id | Name | Salary | DepartmentId |
±-----±------±-------±-------------+
| 1 | Joe | 70000 | 1 |
| 2 | Henry | 80000 | 2 |
| 3 | Sam | 60000 | 2 |
| 4 | Max | 90000 | 1 |
| 5 | Randy | 85000 | 1 |
±-----±------±-------±-------------+
Department 表包含公司所有部門的信息。
±—±---------+
| Id | Name |
±—±---------+
| 1 | IT |
| 2 | Sales |
±—±---------+
SQL題目: 編寫一個 SQL 查詢,找出每個部門工資前三高的員工。例如,根據上述給定的表格,查詢結果應返回:
±-----------±---------±-------+
| Department | Employee | Salary |
±-----------±---------±-------+
| IT | Max | 90000 |
| IT | Randy | 85000 |
| IT | Joe | 70000 |
| Sales | Henry | 80000 |
| Sales | Sam | 60000 |
±-----------±---------±-------+
答案:
SELECT Department.Name AS Department, e1.Name AS Employee, e1.Salary AS Salary FROM Employee e1 JOIN Department ON e1.DepartmentId = Department.Id WHERE 3 > ( SELECT COUNT(DISTINCT e2.Salary) FROM Employee e2 WHERE e2.Salary > e1.Salary AND e1.DepartmentId = e2.DepartmentId ) ORDER BY Department.Name, e1.Salary DESC解析:
不妨假設e1=e2=[6,5,4,3],則子查詢的過程如下:
1、e1.Salary=3;則e2.Salary可以取4、5、6;COUNT(DISTINCT e2.Salary)=3
2、e1.Salary=4;則e2.Salary可以取5、6;COUNT(DISTINCT e2.Salary)=2
3、e1.Salary=5;則e2.Salary可以取6;COUNT(DISTINCT e2.Salary)=1
4、e1.Salary=6;則e2.Salary無法取值;COUNT(DISTINCT e2.Salary)=0
則要令COUNT(DISTINCT e2.Salary) < 3 的情況有上述的4、3、2.
也即是說,這等價于取e1.Salary最大的三個值。
查詢部門工資最高的員工:
方法1:
方法2:
select d.Name as Department,e.Name as Employee,Salary from Employee e join Department d on e.DepartmentId=d.Id where (e.Salary,e.DepartmentId) in (select max(Salary),DepartmentId from Employee group by DepartmentId)SQL 查詢數據
–1.學生表
Student(S#,Sname,Sage,Ssex) --S# 學生編號,Sname 學生姓名,Sage 出生年月,Ssex 學生性別
–2.課程表
Course(C#,Cname,T#) --C# --課程編號,Cname 課程名稱,T# 教師編號
–3.教師表
Teacher(T#,Tname) --T# 教師編號,Tname 教師姓名
–4.成績表
SC(S#,C#,score) --S# 學生編號,C# 課程編號,score 分數
*/
–創建測試數據
1、查詢“01”課程比“02”課程成績高的所有學生的學號;
select a.S#,a.score,b.score from (select * from SC where SC.C#='01') a, (select * from SC where SC.C#='02') b where a.score>b.score and a.S#=b.S#2、查詢平均成績大于60分的同學的學號和平均成績;
select SC.S#,AVG(SC.score) avgScore from SC group by SC.S# having AVG(SC.score)>603、查詢所有同學的學號、姓名、選課數、總成績;
select SC.S#,Student.Sname,COUNT(SC.C#) 選課數, AVG(SC.score) 平均分from SC left join Student on SC.S#=Student.S#group by SC.S#,Student.Snameorder by SC.S#4、查詢姓“李”的老師的個數;
select COUNT(distinct(Teacher.TName)) from Teacher where Teacher.Tname like '李%'5、查詢沒學過“葉平”老師課的同學的學號、姓名;
select Student.S#,Student.Sname from Student where Student.S# not in(select SC.S# from Course,SC,Teacher where SC.C#=Course.C# and Teacher.T#=Course.T# and Teacher.Tname='葉平' )6、查詢學過“01”并且也學過編號“02”課程的同學的學號、姓名;
select *, Student.S#,Student.Sname from Student left join SC on Student.S#=SC.S# where SC.C# ='01' and exists (select * from SC SC_1 where SC_1.S#=Student.S# and SC_1.C#='02' )7、查詢沒有學全所有課的同學的學號、姓名;
select Student.S#,Student.Sname from Student,SC where Student.S#=SC.S#group by Student.S#,Student.Sname having COUNT(SC.C#)< (select COUNT(Course.C#) from Course)測試用例設計經典面試題——電梯,杯子,筆,桌子,洗衣機
例子請點擊這里
首先說明的是,遇到這樣的測試題目,首先應該反問面試官,需求是什么樣的,比如是測什么樣的杯子。
因為設計測試用例的規則應該是根據需求分析文檔設計用例,客戶需求什么,就測試什么。但是在沒有需求分析文檔的前提下, 來設計測試用例,可以考查一個測試人員的基本功,比如考慮問題是否全面,設計測試用例的方法是否合理等。一般是根據自己的日常經驗和測試的思維來設計測試用例。在設計測試用例時一般從以下幾個方面進行分析:功能測試,性能測試,界面測試,安全性測試,兼容性測試,可用性測試,可靠性測試,本地化/國際化測試。
1、測試項目——電梯
需求測試:查看電梯使用說明書,安全說明書等。功能測試:1、上升鍵和下降鍵,電梯的樓層按鈕是否正常;2、開關鍵是否正常,報警裝置是否安裝,報警電話是否可用;3、通風狀況如何,是否有手機信號;4、在電梯上升過程中的測試,比如電梯在1樓,有人按了18樓,在上升到5樓的時候,有人按了10樓,電梯會不會停;5、在電梯下降過程中的測試,比如電梯下降到10層時顯示滿員,若有人在5樓等待,此時還會不會停。壓力測試:看電梯的最大承重重量,在電梯超重時,報警裝置是否啟用,在一定時間內讓電梯連續的上升和下降,看在最大負載條件下平穩運行的時間。界面測試:查看電梯的外觀,電梯的按鈕是否好用(開和關按鈕設計的圖標不容易區分),電梯的說明書是否有錯別字。可用性測試:電梯的按鈕是否符合人的使用習慣。用戶文檔:使用手冊是否對電梯的使用,限制等有描述。2、測試項目——杯子
需求測試:查看杯子的使用說明書,安全說明書等。功能測試:1、杯子能否裝水;2、可以裝多少L的水;3、杯子是否可以放冰箱;4、水可不可以被喝到。安全性測試:1、杯子有沒有毒和細菌;2、杯子從高處墜落,是否已破;3、杯子是否有缺口,容易滑倒嘴巴;4、將杯子放入微波爐中,是否爆炸或融化;性能測試:1、看杯子能夠容納的最大體積和最高溫度;2、將杯子盛上水,經過24小時后查看杯子的泄露情況和時間(可分別使用水和汽油做測試);3、將杯子裝上填充物,看不會摔破的最高度;4、用根針并在針上面不斷加重量,看壓強多大時會穿透; 可用性測試:杯子是否好拿,是否燙手,是否防滑,是否方便飲用。兼容性測試:除了裝水,是否還可以裝其它的液體,比如果汁,汽油等。界面測試:查看杯子的外觀:杯子是什么材質的,顏色,外形,重量,圖案是否合理,是否有異味。用戶文檔:使用手冊是否對杯子的用法、限制、使用條件等有詳細描述。3、測試項目——筆
1、需求測試:查看使用說明書。2、功能測試:能不能寫字 。3、界面測試:查看筆的外觀 。 4、可靠性:筆從不同高度落下摔壞的程度。 5、安全性:筆有沒有毒或細菌 。 6、可移植性:筆在不同的紙質、溫度等環境下是否可以使用。 7、兼容性:筆是否可以裝不同顏色、大小的筆芯 。8、易用性:是否方便使用、方便攜帶 。 9、壓力測試:給筆不斷的增加重力,觀察壓力多大時壓壞。 10、震動測試:筆在包裝時,各面震動,檢查是否能應對惡劣的公路、鐵路、航空運輸。11、跌落測試:筆包裝時,在多高的情況下摔不壞。4、測試項目——桌子
需求測試:查看桌子相關的使用說明書。功能測試:桌子是辦公用的還是防治東西用的,桌子的面積大小是否適合;界面測試:桌子的桌面是否平滑,有沒有凹凸不平的地方;安全性測試:桌子的支撐點是否可靠;將桌子推倒后,它的損壞情況;壓力測試:桌子可以承受的重量;可用性測試:桌子是否好移動;它的重量是否合適;5、測試項目——洗衣機
需求測試:查看洗衣機的使用說明書。功能測試:洗衣機是否正常的洗衣服;安全性測試:洗衣機是否漏電;兼容性測試:除了洗衣服是否還可以洗其它的;性能測試:使用時電量如何,是否滿足客戶需求;加到一定量的衣服后,過一段時間,看洗衣機是否正常洗;通過逐步增加系統負 載,最終確定在什么負載條件下系統性能將處于崩潰狀態,以此獲得系統能提供的最大服務界面測試:洗衣機的外觀是否符合用戶的需求;可用性測試:洗衣機的操作是否簡單已操作;等價類劃分–三角形測試用例設計
詳細點擊這里
性能測試
JMeter學習 內存溢出解決方法
1、windows環境下,修改jmeter.bat:
set HEAP=-Xms256m -Xmx256m
set NEW=-XX:NewSize=128m -XX:MaxNewSize=128m
改為:
set HEAP=-Xms256m -Xmx1024m
set NEW=-XX:NewSize=128m -XX:MaxNewSize=512m
根據經驗,heap最多設置為物理內存的一半,默認設置為512M.如果heap超過物理內存的一半,可能運行jmeter會慢,甚至出現內存溢出,原因java比較吃內存,占CPU.
注意: JDK32位的電腦Xmx不能超過1500m,最大1378m.否則在啟動Jmeter時會報錯:
2、linux環境下,修改jmeter.sh:
java $JVM_ARGS -Xms1G -Xmx5G -XX:MaxPermSize=512m -Dapple.laf.useScreenMenuBar=true -jar dirname $0/ApacheJMeter.jar “$@”
微眾銀行面試
1、Linux基礎命令?如何查看Error日志?如何查看日志中出現Error的次數?
2、Java筆試題
3、說說Java的重載與重寫的區別
3、說說你自己的項目;然后從項目中挑選一些問題。
4、當你遇到測試任務與上線時間沖突的時候,如何面對?
5、你是如何在工作中提高工作效率的?
6、為什么離職?
7、你對我司的了解如何,說說看;你對我司的期待如何?
8、說說你的測試流程;說說你的自動化測試流程。
10、HTTP和HTTPS的區別
11、你常用的HTTP請求類型有哪些?簡單說說他們之間的區別(比如GET和POST)
數據結構部分
堆、隊列、棧的區別
隊列(Queue): 是限定只能在表的一端進行插入和在另一端進行刪除操作的線性表;
棧(Stack): 是限定只能在表的一端進行插入和刪除操作的線性表。
區別:
一、規則不同
1. 隊列:先進先出(First In First Out)FIFO
隊列 就像一條路,有一個入口和一個出口,先進去的就可以先出去。
2. 棧:先進后出(First In Last Out )FILO
棧就像一個箱子,后放的在上邊,所以后進先出
二、對插入和刪除操作的限定不同
1. 隊列:只能在表的一端進行插入,并在表的另一端進行刪除;
2. 棧:只能在表的一端插入和刪除。
三、遍歷數據速度不同
1. 隊列:基于地址指針進行遍歷,而且可以從頭部或者尾部進行遍歷,但不能同時遍歷,無需開辟空間,因為在遍歷的過程中不影響數據結構,所以遍歷速度要快;
2. 棧:只能從頂部取數據,也就是說最先進入棧底的,需要遍歷整個棧才能取出來,而且在遍歷數據的同時需要為數據開辟臨時空間,保持數據在遍歷前的一致性。
深信服軟件測試崗面試:
https://blog.csdn.net/xp731574722/article/details/82868560
https://zhuanlan.zhihu.com/p/346173389
1、面向對象編程與面向過程編程的區別
2、Java的特性:抽象,繼承,封裝,多態
3、冒泡排序過程
4、測試一個數字輸入框,可輸入的數字是5-10,說說你的測試思路。
5、靜態路由與動態路由的區別(原理)
靜態路由以及動態路由的區別
- 1、靜態路由是指由網絡管理員手工配置的路由信息。當網絡的拓撲結構或鏈路的狀態發生變化時,網絡管理員需要手工去修改路由表中相關的靜態路由信息。靜態路由信息在缺省情況下是私有的,不會傳遞給其他的路由器。當然,網管員也可以通過對路由器進行設置使之成為共享的。靜態路由一般適用于比較簡單的網絡環境,在這樣的環境中,網絡管理員易于清楚地了解網絡的拓撲結構,便于設置正確的路由信息。
靜態路由:安全,占用帶寬小,簡單,高效,轉發效率高;一般用于網絡規模不大、拓撲結構固定的網絡中。 - 2、動態路由是指路由器能夠自動地建立自己的路由表,并且能夠根據實際實際情況的變化適時地進行調整。動態路由機制的運作依賴路由器的兩個基本功能:對路由表的維護;路由器之間適時的路由信息交換。
動態路由:靈活性高;適用于網絡規模大、網絡拓撲復雜的網絡。
6、TCP的連接是如何實現的?
(如上)
7、安全測試的SQL注入是怎么實現的?
https://www.jianshu.com/p/078df7a35671
8、Java設計模式,單例模式,工廠模式
http://c.biancheng.net/view/1338.html
9、linux 查找文件名,查看日志,查看CPU
(如上)
TCL智能電視事業部測試工程師面試題
1、從您的實際工作案例中闡述,您是如何解決軟件測試“殺蟲劑”現象的?
PS 以下僅供參考
“【殺蟲劑”現象存在是因為測試人員個體之間的差異性導致的思維方式差異,測試人員往往容易陷入一種慣性思維,所以測試人員編寫測試用例的時就會存在一些局限性。
結合我的實際工作,我認為做到以下幾點可以盡可能的避免“殺蟲劑”現象:
1)、首先了解清楚業務需求和功能,在需求評審階段就帶領測試人員介入其中,第一時間掌握需求情況;
2)、測試人員定期評審測試用例:包括測試人員之間,以迭代周期或產品測試周期為準;每個月與開發和PO進行用例評審;
3)、借用“結對編程”的概念,同一個產品模塊的測試任務讓多個測試人員交叉領取測試任務,比如一個模塊的開發往往細分為多個開發Tickets,讓不同的QA一起負責該模塊的測試。
4)、重要功能邏輯提測通過后盡可能讓PO再次確認其是否滿足需求;
5)、測試人員需要維護用例,根據產品設計和功能需求的更新而進行相應的維護。】
2、‘能夠發現難以發現的缺陷的測試用例才是好的測試用例’,結合您的實際工作,是否認同,為什么?
PS 以下僅供參考
【不認同。
我們編寫的測試用例包括正/反向測試:等價類劃分、邊界值分析、錯誤推斷等,并不是所有的測試用例都能夠發現軟件缺陷,也不能說沒發現缺陷的測試用例就不是好的測試用例;編寫好的測試用例,應該按照設計測試用例的方法結合實際項目去覆蓋到軟件產品的功能和需求。】
3、請闡述一個軟件漏測事故,并寫出此事故給你帶來的啟迪。
PS 以下僅供參考
事故:跟日期相關的產品在2月29號的時候異常,4年才會出現一次,漏測。
啟迪:測試用例設計覆蓋不全;漏測是不可避免的,在整個軟件項目過程中,或多或少都會遇到漏測事故,為了避免更多類似情況的發生,我們有建立統一的漏測事故記錄,出現漏測之后與組員進行分享,一起改進后續的測試流程。
【漏測原因主要集中在:
1)需求不明確,導致用例不精確;
2)需求變更,測試用例未及時更新;
3)設計測試用例是場景覆蓋不全,漏測;
4)測試時間不足,無法覆蓋更多的細節測試;
解決:
團隊進行需求評審和測試用例評審;】
4、畫出軟件測試流程圖,拍照上傳附件。
5、請具體說明您上傳的測試流程不足之處,以及改進建議。
PS 以下僅供參考
【在用例設計、評審、執行階段可能會出現需要再次確認需求的情況,需要再次重新與需求人員進行需求確認,而提高測試覆蓋度。】
6、在測試用例中編寫UI的絕對路徑,例如: 文件->設置->高級->保存賬號,這樣寫的優缺點是什么,遇到這種情況你如何來設計?
PS 以下僅供參考
【優點:絕對路徑精準定位,一目了然;
缺點:復用性差;一旦位置發生改變,但功能不變,就得對應進行維護。
設計思路:
根據該功能的屬性,需求和設計是否會存在經常變動:
如果UI界面位置固定不變,使用絕對路徑;
如果UI界面位置會經常發生改動,使用相對路徑。】
7、python基礎面試題:python 列表 a=[1,2,3,4,5,6,7],將列表a的值賦值給列表b,在不影響列表a的情況下,將列表b的值每間隔一個元素替換成6,請寫代碼實現?
a = [1,2,3,4,5,6,7] b = [] for i in a:if i%2==0:i=6b.append(i)else:b.append(i)print(a) print(b)8、Python基礎面試題:讓用戶輸入用戶名密碼,成功打印歡迎信息,輸錯提示還剩幾次機會,三次機會仍然錯誤推出程序,請代碼實現?
user='peter zhang' pwd='szTCL666' count = 0 for i in range(3):username=input("UserName:")password=input('PassWord:')if username == user and password == pwd:print("歡迎登陸TCL, Peter!")count = 3break;else:print('您輸入的用戶名或密碼錯誤,請仔細檢查!')count += 1print("你還可以嘗試",2-i,"次")實用:python中求2個字符串的最長公共子串
s1 = 'abcdefg' s2 = 'cdefghi'def fn(s1,s2):if len(s1) < len(s2):s1,s2 = s2,s1maxstr = s1substr_maxlen = max(len(s1),len(s2))for sublen in range(substr_maxlen,-1,-1):for i in range(substr_maxlen-sublen+1):if maxstr[i:i+sublen] in s2:return maxstr[i:i+sublen] fn(s1,s2)Python編寫一個函數來查找字符串數組中的最長公共前綴。
如果不存在公共前綴,返回空字符串 “”。
示例 1:
輸入: [“flower”,“flow”,“flight”]
輸出: “fl”
示例 2:
輸入: [“dog”,“racecar”,“car”]
輸出: “”
解釋: 輸入不存在公共前綴。
說明:所有輸入只包含小寫字母 a-z 。
Python實現一個函數,功能如下:
輸入一個字符串、一個前綴、一個后綴,返回字符串中以【前綴開頭+后綴結尾的所有子串】
原型:def query_substring(string,prefix,postfix)
例如:輸入abxxb,a,b,返回[ab,abxxb]
例如:輸入xxabbxx,a,b,返回[ab,abb]
冒泡排序
冒泡排序原理:
- 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
- 對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數。
- 針對所有的元素重復以上的步驟,除了最后一個。
- 持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較
Python實現:
def bubble_sort(nums):for i in range(len(nums) - 1): # 這個循環負責設置冒泡排序進行的次數for j in range(len(nums) - i - 1): # j為列表下標if nums[j] > nums[j + 1]:nums[j], nums[j + 1] = nums[j + 1], nums[j]return numsprint(bubble_sort([45, 32, 8, 33, 12, 22, 19, 97])) # 輸出:[8, 12, 19, 22, 32, 33, 45, 97]Java實現
public static void bubbleSort(int arr[]) {for(int i =0 ; i<arr.length-1 ; i++) { for(int j=0 ; j<arr.length-1-i ; j++) { if(arr[j]>arr[j+1]) {int temp = arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}} }}Java面試題:
給定一個排序數組,你需要在原地刪除重復出現的元素,使得每個元素只出現一次,返回移除后數組的新長度。 不要使用額外的數組空間,你必須在原地修改輸入數組并在使用 O(1) 額外空間的條件下完成。
思路:
- 如果數組長度為0或者為1 ,直接返回數字長度;
- 定義一個臨時變量temp和一個計數器k(這個k就代表不重復的數字的個數,從1開始計數),初始值為nums [ 0 ] ,循環比較temp和nums[i],假設nums [ i ]不等于temp,說明下標位于0~i-1之間的數字等于nums[0],把nums[i]賦給temp和nums[k],k自增
明源云鏈筆試題:
1、SQL基礎:student(學生表)、class(班級表)結構如下、其中class表的主鍵id是student表c_id的外鍵:
Student(學生表):
1.1 查詢一班得分在80分以上的學生:
1.2 用一條SQL語句查詢出各個班級的男生人數和平均分:
SELECT c.id, c.name, count(1) AS man_count, avg(score) AS avg_score FROM student AS s, class AS c WHERE s.c_id=c.c_id AND sex='男' GROUP BY c.id, c.name2、接口測試題:接口測試中依賴登錄狀態的接口是如何測試的?
通常是使用Cookies/Token來驗證登錄態,在測試這類接口時需要獲取Cookie/Token然后再依次進行后續接口的測試事實上也就是上下接口的數據依賴,只不過依賴的數據是Cookies/Token。
- 1、如果已知的登陸接口,那就直接使用登錄接口來獲取Cookies/Token,已被后續接口的測試使用。
- 2、比如使用JMeter TokenbasedAuth等,或者是添加中間變量來進行存儲;使用Postman的話是創建環境變量或者全局變量,使用Pre-script通過代碼來獲取已經存儲的變量。
- 3、如果是未知登陸接口的話可以通過抓包來獲取Cookie/Token。
3、根據下面的報表完成下面的題目:
3.1 根據如上的PC報表,列出你的測試點。
3.2 列出這張報表內所有的BUG點。
- a、時間顯示錯誤,年度選框顯示2020年,表頭顯示2019
- b、若“生成Excel導出”是一個功能按鈕,則為UI顯示錯誤。
- c、“上年人數”與“2019年人數”與“人員浮動比”三列不在一起;“上年平均工資”列與“浮動比”三列不在一起;
- d、表內整體位置凌亂,可調整為統一居左/中,財務部的“備注”列導致整行寬度變寬。
- e、比例換成百分比更直觀
- f、單位“萬”可以單獨提取在列名背后備注
4、UI自動化執行用例不夠穩定(有時候正常有時候報錯),一般有幾種解決辦法?
UI自動化常見的5大不穩定因素:
- 非預計的彈出對話框。
- 頁面控件屬性的細微變化
- 別扯系統的A/B測試
- 隨機的頁面延遲造成控件識別失敗
- 測試的數據問題
a、解決辦法:
非預計的彈出對話框
產生原因:有的網站可能會某一時刻產生廣告之類的彈框。隨機出現,影響自動化用例的執行。
解決策略:在規定時間內,定位不到頁面屬性時,可能存在彈框,將異常捕獲,執行(確定,取消等按鈕)。
b、頁面控件屬性的細微變化
產生原因:前端稍微修改之后,導致頁面的控件定位發生錯誤。
解決策略:采用相對路徑,更重要的是對UI自動化進行封裝,當我對UI自動化腳本進行封裝4次之后,每次前端修改,只要不是大型的改動,只需要幾分鐘就可以更改調試成功。
c、被測系統的A/B測試
產生原因:一個網址可能跳轉到不同的一個或者幾個頁面
解決策略:針對不同的版本進行分支處理
d、隨機的頁面延遲造成控件識別失敗
產生原因: 網絡延遲或者丟包卡頓等。
解決辦法: 顯示等待,隱性等待機制。但是根據我個人的經驗,最好的做法是對selenium接口進行二次封裝,解決等待問題,而且,隱式等待機制最好是用在頁面跳轉上。
e、測試數據問題
產生原因: 有的網站測試數據只能使用一次,例如,注冊用戶姓名不能重復,訂單不能重復等問題
解決辦法: 在運行腳本之前,鏈接到數據庫,通過腳本,將原來的數據刪除掉。
.
.
.
以上說法僅供參考,Web UI自動化測試的不穩定性有兩個層面:
- 技術層面–沒有構造健壯的能穩定運行的腳本
- 非技術層面–項目原因或者用Web UI自動化企圖達到不合適的目標,造成腳本頻繁改動,維護成本高
5、編程題: 有字符串“aabbcdbaaabc”,用你熟悉的語言實現去除“ab”子串。
str = 'aabbcdbaaabc' excStr = str.replace('ab','') while 'ab' in excStr:excStr=excStr.replace('ab','') print(excStr)上題延伸:記錄一次筆試題:【去除str = [“aababbc”, “badabcab”] 中的“ab”,語言不限】
str = ["aababbc", "badabcab"] for str1 in str:str2 = str1.replace('ab', '')while 'ab' in str2:str2 = str2.replace('ab', '')print(str2)深信服二面:
1、Linux配置網絡在那里實現,或者說在哪個根目錄下?
2、如何查詢第10行日志?
3、Selenium你是如何定位的?
4、當有一個高并發的場景無法模擬的時候,你怎么處理?
編程題:
用你熟悉的語言,統計list中各個元素出現的次數
如:list=[“aa”,“b”,“c”,“aa”,“b”,“a”]
ps: 面試的時候沒想清楚,后來查了一下,發現真的是Python基礎,就一個List和字典的基礎。
Python:
總結
以上是生活随笔為你收集整理的软件(自动化)测试面试基础知识点汇总的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机控制器的简写,工业控制常用英语及缩
- 下一篇: 常用的工业控制计算机有哪几类,工业控制计