測試面試準備知識點

1. 面經

Shopee

作者:嗚嗚祖卡

https://www.nowcoder.com/discuss/369302?type=2&order=0&pos=1&page=1來源:牛客網

爲什麼想做測試

以前實習是怎麼測試的 沒有實習過 所以沒談了

如果打不開百度網頁,怎麼排查錯誤

  • 先確定網絡是否連接

測試刪除文件功能

http狀態碼都說一下 單獨問了404

https瞭解嗎http+ssl

數據庫內連接外連接左連接右連接 用得不多 所以沒繼續問了

想怎麼建立索引?學生學號姓名年級成績老師入學時間 可以根據什麼來建立索引

linux常用命令 管道有常用嗎

作者:九月努力籤高薪好offer

https://www.nowcoder.com/discuss/249789?type=2&order=0&pos=5&page=1來源:牛客網

​ ***一面 1H2MIN* **

**1. 解釋一些項目;
\2. linux常用指令;
\3. sql瞭解嗎?
\4. 網絡基礎知識:http中的get和post有什麼區別;
\5. tcp三次握手、四次揮手
\6. 測試登錄功能【編寫測試用例】
\7. 智力題:一根繩子燒盡60分鐘,怎麼燒出75分鐘。
\8. new和malloc的區別
**

二面 20MIN 1. 介紹項目
\2. 一瓶水怎麼進行測試(口述測試用例)
這個面試進行的比較糟心,就是全程我自己在表演,時間有點久了也有點記不住了。

​ 三面 10MIN

主要就是hr考察一下你留在深圳的可能性,舔的太厲害有點後悔。然後就是問你的期望待遇,由於舔的太厲害說的很低,有點後悔。

作者:亭亭少年

https://www.nowcoder.com/discuss/247222?type=2&order=0&pos=6&page=1來源:牛客網

  1. 判斷兩個數組中是否存在相同的數字,兩個已經排好序的數組,寫代碼判斷這兩個數組中是否存在相同的數字?要求時間複雜度越低越好。

  2. 講輸入 url 到頁面呈現的過程(下面幾個很細節的問)

  3. 拿到 http 響應後,怎麼渲染頁面,html 的組成,js、css 這些靜態文件是存在哪裏?(不清楚前端,瞎講,我說到 http 緩存,面試官一臉疑惑,我也搞不懂)

  4. 服務端有很多服務,關於 http、ftp 等等,怎麼知道你發的是 http 請求,我要響應的是 http 請求(端口)

  5. 客戶端向服務器發一個 1kb 數據,怎麼保證是無損傳輸(答 tcp 保證可靠傳輸,超時重傳和 seq/ack 機制

  6. 一個 tcp 鏈接最多能同時發多少個 http 請求(可能是這個問題,記不清,又引申到高併發)

  7. 有沒有了解高併發,我說不了解,問不瞭解的話,那但你從學過的計算機基礎知識,來看怎麼實現這個過程(涼涼,完全不瞭解,一頓瞎扯)

  8. 老闆給一個需求,不具體,輸入一個生日,實現生日前一天給人發郵件祝福,從產品、開發、測試角度來怎麼設計、怎麼實現、怎麼測試(說產品的時候,告訴我要多問,去細化需求)

  9. 如果要實現生日可以修改,一直往後面推,怎麼做(我說直接覆蓋數據庫的數據,他最後說需要設置一個用戶登錄之類的)

  10. 這個數據庫要有哪些字段

  11. 實現方面,還問你怎麼能每天去執行,誰去掃庫嗎,我說可以用 linux crontab 去設置定時任務,每天去掃庫(瞎扯,不懂後臺)

  12. 測試方面,說還要考慮一年的最後一天的跳轉,閏年之類的

  13. 問對深圳,對未來有什麼規劃

  14. 問想做前端方面還是後臺服務器方面

另外附上一面面經

\1. 講項目
\2. 編程,找出一個字符串中所有迴文子串(長度 >=3,長度爲奇數的),並記錄他的起始位置(暴力)
\3. linux 命令講一下,打印某個進程查詢出來的第二列(pid)
\4. 在 student_course 表(sid, cid, score) 查詢課程 1(cid=1) 成績第2高的學生.
\5. appium 的原理了解嗎
\6. 實習用到哪些測試理論
\7. 測 QQ 登錄頁面
\8. 性能測試除了時間、併發還有哪些? (面試官說到錯誤率)
\9. http 有狀態嗎? cookie 和 session 區別,既然 session 比 cookie 更好,那隻用 session 可以嗎? http 緩存知道嗎? keep-alive?

作者:芣值棏、畱攣

https://www.nowcoder.com/discuss/238991?type=2&order=0&pos=7&page=1來源:牛客網

自我介紹

講項目

Linux用過哪些基礎命令

查看某個日誌(cat)

查找關鍵字的錯誤(grep)

數據庫按某列排序(order by)

數據庫的內聯和外聯,左聯和右聯

數據庫怎麼分頁

死鎖,四個必要條件,怎麼避免

給你一個杯子,要測試哪些屬性

一個細胞,1s分裂一次,由一個變成兩個,1分鐘後填滿一瓶子,問初始3個細胞,多久填滿瓶子?

瀏覽器輸入一個url,後面要經過哪些過程?

爲什麼發送http請求,卻建立的是TCP連接?

服務器返回響應結果後,客戶端要做什麼?

作者:☞Nothing☜

https://www.nowcoder.com/discuss/379545?type=2&order=0&pos=1&page=1來源:牛客網

2.給一個有序數組和它的大小,給定一個val,求這個數組裏有沒有這個val,有或者有不止一個的話,求第一次出現這個 val 的位置;

3.按照簡歷上面的語言提問(栽了 T-T );

4.給一瓶礦泉水,怎麼測試;

5.開發說沒有辦法解決的bug,你會怎麼做;

6.有什麼想問的

作者:菊池溫祁

https://www.nowcoder.com/discuss/379510?type=2&order=0&pos=2&page=1來源:牛客網

自我介紹

項目情況,主要負責什麼功能(我自己說了他沒問了)

如何分析ANR和崩潰,發生的時候怎麼做(因爲項目情況裏說了)

有沒有用過抓包軟件

測試用例題:測試一瓶礦泉水

場景題:如果開發說這個bug他無法解決或者不解決,怎麼辦

多表查詢(我答了會用到內外鏈接。。他就說我錯了)

事務一致性

數據索引優缺點

對加班怎麼看

對自己學習能力怎麼判斷,如果吸收能力弱是否會花時間跟上團隊節奏

作者:一隻大鹿鹿鹿鹿鹿鹿鹿

https://www.nowcoder.com/discuss/379343?type=2&order=0&pos=4&page=1來源:牛客網

中間還問了。數據庫。索引的優缺點。還有一個概念我不記得了。

web訪問域名經過啥步驟。

tcp三次握手。

測試一個登錄界面。

進程和線程的區別。

線程同步。

黑盒白盒的方法。

作者:古月dawn

https://www.nowcoder.com/discuss/378375?type=2&order=0&pos=5&page=1來源:牛客網

數據庫:索引的作用|group by|聚合函數|連接
數據結構:隊和棧的區別|樹的遍歷|求一棵樹的鏡像|排序算法|
操作系統:線程和進程區別|
項目介紹|難點|編程語言
http和https的區別?

招銀網絡

作者:大樹555
https://www.nowcoder.com/discuss/167676?type=2&order=3&pos=14&page=1來源:牛客網

1、tcp和udp的區別並說說他們實際的應用場景

2、說說tcp滑動窗口機制,還有是怎麼實現的

3、http和HTTPS區別

4、三次握手四次揮手

二、數據結構和算

1、數組和鏈表區別

2、說說你瞭解的排序算法

三、操作系統

1、進程和線程區別

2、什麼是死鎖,出現死鎖如何解決

四、測試

1、給一個登陸界面,設計相關測試用例

2、給一段代碼輸入兩個數還有操作符,也就是計算兩個數加減乘除。設計相關測試用例

五、數據庫

1.常見的增刪改查

2.連表查詢

3.數據庫存儲過程和觸發器區別

六、程序題

1、給三個數值,根據大小,輸出中間那個數

2、求N階矩陣的對角線數值之和

3、N個人,互相交換禮物,每個人不能拿到自己的禮物。設計一種算法

2. 準備

2.1 計算機網絡

2.1.1 http

超文本傳輸協議

2.1.2 http和https的區別

  • https協議需要到CA(Certificate Authority,證書頒發機構)申請證書,一般免費證書較少,因而需要一定費用。
  • http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議。
  • http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,後者是443。
  • http的連接很簡單,是無狀態的。Https協議是由SSL+Http協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。(無狀態的意思是其數據包的發送、傳輸和接收都是相互獨立的。無連接的意思是指通信雙方都不長久的維持對方的任何信息。)

https請求過程

WX20191127-133805@2x.png

2.1.3 session與cookies實現機制

https://harttle.land/2015/08/10/cookie-session.html

session與cookie的區別

  • session存儲在服務器,cookid存儲在客戶端
  • session比cookie安全,所以一般用來存儲一些敏感信息
  • 性能方面:
  • 數據存儲大小不同:單個cookie保存的數據不超過4k,session沒有限制

2.1.4 http緩存

  • 強緩存
  • 協商緩存
  • 瀏覽器啓用緩存的優點:減少頁面加載時間,減少服務器負載
  • 瀏覽器是否使用緩存,緩存多久,是由服務器控制的
    • 即服務器響應的 響應頭 中,某些字段指明瞭緩存的關鍵信息

強緩存和協商緩存的區別

  • 協商緩存跟強緩存不一樣,強緩存不發請求到服務器,所以有時候資源更新了瀏覽器還不知道,但是協商緩存會發請求到服務器,所以資源是否更新,服務器肯定知道。
  • 大部分web服務器都默認開啓協商緩存,而且是同時啓用Last-Modified,If-Modified-Since和ETag、If-None-Match
  • Last-Modified,If-Modified-Since和ETag、If-None-Match一般都是同時啓用,這是爲了處理Last-Modified不可靠的情況
  • // 分佈式系統裏多臺機器間文件的Last-Modified必須保持一致,以免負載均衡到不同機器導致比對失敗
  • // 分佈式系統儘量關閉掉ETag(每臺機器生成的ETag都會不一樣)

作者:woow_wu7鏈接:https://juejin.im/post/5e2aaa406fb9a02fb75d68df來源:掘金著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

2.1.5 http狀態碼

分類 描述
1** 指示信息-收到請求,繼續處理
2** 成功-請求被成功接收
3** 重定向-需要進一步的操作,以完成請求
4** 客戶端錯誤-請求包含語法錯誤或無法完成請求
5** 服務器錯誤-服務器在處理請求的過程中發生了錯誤

作者:吾兒濱濱鏈接:https://juejin.im/post/5e4d5af7518825492442c55d來源:掘金著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

200(OK):請求成功。

206(Partial Content):客戶端發送了一個Range的get請求,服務器完成了它。

301 (Moved Permanently):永久重定向至新的 url。

302(Found):臨時重定向至新的url。

304(Not Modified):服務器告訴瀏覽器緩存可以繼續使用。

400(Bad Request):客戶端請求有語法錯誤,服務器理解不了。

401 (Unauthorized/未授權)

403(Forbidden):請求頁面禁止訪問。

404 (Not Found):請求資源不存在。

**500 (Internal Server Error):**服務器內部錯誤,無法完成請求。

501 服務器不支持當前請求所需要的某個功能。當服務器無法識別請求的方法,並且無法支持其對任何資源的請求。
502 作爲網關或者代理工作的服務器嘗試執行請求時,從上游服務器接收到無效的響應。

作者:吾兒濱濱鏈接:https://juejin.im/post/5e4d5af7518825492442c55d來源:掘金著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

2.1.6 http請求以及響應

https://juejin.im/post/5e5152be6fb9a07ce31ee4bd#heading-25

1. DNS域名解析 // 將域名解析成IP地址
2. 建立TCP鏈接 // 三次握手
3. 客戶端發起HTTP請求
4. 服務器處理請求,並返回HTTP報文
5. 瀏覽器解析渲染頁面
6. 斷開TCP鏈接 // 四次揮手

url到頁面顯示的過程

  1. DNS域名解析
  • DNS是 ( domain name system ) 域名系統的縮寫
  • 將域名解析成ip地址
  • 一個域名對應一個以上的ip地址
  • 爲什麼要將域名解析成ip地址?
    • 因 ( 爲TCP/IP網絡 ) 是通過 ( ip地址 ) 來確定 ( 通信對象 ),不知道ip就無法將消息發送給對方
  • DNS域名解析的過程:// 遞歸查詢和迭代查詢
  1. ( 瀏覽器 ) 中查詢 DNS 緩存,有則進入建立tcp鏈接階段,下面同理

  2. ( 本機的系統 )中查詢 DNS 緩存

  3. ( 路由器 ) 中查詢 DNS 緩存

  4. ( 運營商服務器 ) 中查詢 DNS 緩存

  5. 遞歸查詢 // 根域名/一級域名/二級域名 …blog.baidu.com

    • .com
    • .baidu
    • blog
    • 還未找到就報錯
  6. 建立tcp鏈接 // 三次握手

  • 第一次握手

    • 客服端發送一個 標誌位SYN=1,序號Seq=x的鏈接包給服務端
      • SYN:表示發起一個新鏈接,( Synchronize Sequence Numbers )
      • Seq:序號是隨機的
  • 第二次握手

    • 服務端發送一個 標誌位SYN=1,ACK=1,確認號Ack=x+1,序號Seq=y的確認包給客戶端
    • 標誌位 ACK 表示響應
  • 第三次握手

    • 客戶端發送一個 SYN=0,ACK=1,確認號Ack=y+1,序號Seq=x+1的確認包給服務器

    • 爲什麼需要三次握手

      • 之所以要第三次握手,主要是因爲避免無效的連接包延時後又發送到服務器,造成服務器以爲又要建立鏈接的假象,造成錯誤
  1. 客戶端發送http請求

  2. 服務端處理請求,並返回http響應報文

  3. 瀏覽器解析渲染

  • 遇見HTML標記,瀏覽器調用HTML解析器,解析成Token並構建DOM樹
  • 遇見style/link標記,瀏覽器調用css解析器,解析成CSSOM樹
  • 遇見script標記,瀏覽器調用js解析器,處理js代碼(綁定事件,可能會修改DOM tree 和 CSSOM tree)
  • 將DOM 和 CSSOM 合併成 render tree
  • 根據render tree計算佈局(佈局)
  • 將各個節點的顏色繪製到屏幕上(渲染)
  1. 斷開TCP鏈接 // 四次揮手,( FIN : 表示釋放鏈接 )
  • 第一次揮手:瀏覽器發起,告訴服務器我請求報文發送完了,你準備關閉吧
  • 第二次揮手:服務器發起,告訴瀏覽器我請求報文接收完了,我準備關閉了,你也準備吧
  • 第三次揮手:服務器發起,告訴瀏覽器,我響應報文發送完了,你準備關閉吧
  • 第四次揮手:瀏覽器發起,告訴服務器,我響應報文接收完了,我準備關閉了,你也準備吧
  • 先是服務器先關閉,再是瀏覽器關閉

2.1.7 GET 和 POST 的區別

  • GET在瀏覽器回退時是無害的,而POST會再次提交請求。
  • GET產生的URL地址可以被Bookmark,而POST不可以。
  • GET請求會被瀏覽器主動cache,而POST不會,除非手動設置。
  • GET請求只能進行url編碼,而POST支持多種編碼方式。
  • GET請求參數會被完整保留在瀏覽器的歷史記錄裏,而POST中的參數不會被保留。
  • GET請求在URL中傳送的參數是有長度限制的,而POST無限制。
  • 參數的數據類型,GET只接受ASCII字符,而POST沒有限制。
  • GET比POST更不安全,因爲參數直接暴露在URL上,所以不能用來傳遞敏感信息。
  • GET參數通過URL傳遞,POST放在Request body中。

IP 是無連接的

IP 用於計算機之間的通信。

IP 是無連接的通信協議。它不會佔用兩個正在通信的計算機之間的通信線路。這樣,IP 就降低了對網絡線路的需求。每條線可以同時滿足許多不同的計算機之間的通信需要。

通過 IP,消息(或者其他數據)被分割爲小的獨立的包,並通過因特網在計算機之間傳送。

IP 負責將每個包路由至它的目的地。

TCP/IP

TCP/IP 意味着 TCP 和 IP 在一起協同工作。

TCP 負責應用軟件(比如你的瀏覽器)和網絡軟件之間的通信。

IP 負責計算機之間的通信。

TCP 負責將數據分割並裝入 IP 包,然後在它們到達的時候重新組合它們。

IP 負責將包發送至接受者。

短連接和長鏈接

在HTTP/1.0中,默認使用的是短連接。也就是說,瀏覽器和服務器每進行一次HTTP操作,就建立一次連接,但任務結束就中斷連接。

但從HTTP/1.1起,默認使用長連接,用以保持連接特性。使用長連接的HTTP協議,會在響應頭有加入這行代碼:Connection:keep-alive

在使用長連接的情況下,當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的 TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Apache)中設定這個時間。實現長連接要客戶端和服務端都支持長連接。

域名系統(英文:Domain Name System,縮寫:DNS)是互聯網的一項服務。它作爲將域名和IP地址相互映射的一個分佈式數據庫,能夠使人更方便地訪問互聯網。DNS使用TCP和UDP端口53[1]。

2.1.8 TCP和UDP的區別、特點

  • TCP的主要特點是:

    • 面向連接。
    • 每一條TCP連接只能是點對點的(一對一)。
    • 提供可靠交付的服務(無差錯,不丟失,不重複,且按序到達)(校驗和、重傳控制、序號標識、滑動窗口、確認應答實現可靠傳輸。如丟包時的重發控制,還可以對次序亂掉的分包進行順序控制。)。
    • 提供全雙工通信。
    • 面向字節流。
  • UDP的主要特點是:

    • 無連接。
    • 支持一對一、一對多、多對一和多對多的交互通信。
    • 盡最大努力交付(不保證可靠交付)。
    • 面向報文。
    • 無擁塞控制。
    • 首部開銷小(只有四個字段:源端口、目的端口、長度、檢驗和)。

採用TCP,一旦發生丟包,TCP會將後續的包緩存起來,等前面的包重傳並接收到後再繼續發送,延時會越來越大。

UDP對實時性要求較爲嚴格的情況下,採用自定義重傳機制,能夠把丟包產生的延遲降到最低,儘量減少網絡問題對遊戲性造成影響。

TCP與UDP的應用場景

TCP: 文件傳輸、發送接收郵件,遠程登錄。

UDP:( 對數據準確性和丟包要求比較低,但速度必須快 )在線視頻,語音電話、遊戲等

2.1.9 TCP爲什麼可靠?

[1] 確認和重傳機制

建立連接時三次握手同步 號 + 窗口大小信息”,是確認重傳、流控的基礎傳輸過程中,如果Checksum校驗失敗、丟包或延時,發送端重傳。

[2] 數據排序

[3] 流量控制

滑動窗口和計時器的使用。TCP窗口中會指明雙方能夠發送接收的最大數據量,發送方通過維持一個發送滑動窗口來確保不會發生由於發送方報文發送太快接收方無法及時處理的問題。

[4] 擁塞控制

TCP的擁塞控制由4個核心算法組成:

“慢啓動”(Slow Start)

“擁塞避免”(Congestion avoidance)

“快速重傳 ”(Fast Retransmit)

“快速恢復”(Fast Recovery)

三次握手,四次揮手

https://blog.csdn.net/hyg0811/article/details/102366854

ACK是標誌位、 確認號ack 、初始序列號seq、SYN同步序列編號

三次握手:

三次握手.png

四次揮手

image.png

ARP協議

  • 第一步:首先,每個主機都會有自己的ARP緩存區中建立一個ARP列表,以表示IP地址和MAC地址之間的對應關係
  • 第二步:當源主機要發送數據時,首先檢測ARP列表中是否對應IP地址的目的主機的MAC地址如果有,則直接發送數據。如果沒有,就向本網段的所有主機發送ARP數據包,內容:我是IP地址,mac地址,誰是IP地址,mac?
  • 第三步:當本網絡的所有主機收到該ARP數據包時,首先檢查數據包中的IP地址是否是自己的IP地址,如果不是,則忽略該數據包。如果是,則首先從數據包中取出源主機的IP和mac地址寫入到ARP列表中,如果以存在,則覆蓋。然後將自己的mac地址寫入arp響應包中,告訴源主機自己是它想要找的mac地址
  • 第四步:源主機收到ARP響應包後,將目的主機的IP和mac地址寫入arp列表,並利用此信息發送數據如果源主機一直沒有收到arp響應數據包,表示arp查詢失敗。

爲什麼要使用ARP協議
OSI模型把網絡工作分爲七層,彼此不直接打交道,只通過接口(layer interface)。IP地址工作在第三層,MAC地址工作在第二層。當協議在發送數據包時,需要先封裝第三層IP地址,第二層MAC地址的報頭,但協議只知道目的節點的IP地址,不知道目的節點的MAC地址,又不能跨第二、三層,所以得用ARP協議服務,來幫助獲取到目的節點的MAC地址。

ARP協議是第幾層協議
工作在二層,是三層協議。

ARP在生成環境產生的問題及解決辦法:

  • ARP病毒,ARP欺騙。
  • 高可用服務器對之間切換時要考慮ARP緩存的問題。
  • 路由器等設備無縫遷移時要考慮ARP緩存的問題,例如:更換辦公室的路由器。

OSI的七層模型

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-HY9mCqsr-1585126522514)(C:\Users\zhangboyi\AppData\Roaming\Typora\typora-user-images\1584096807131.png)]

img

DNS解析過程

  • 瀏覽器搜索自己的DNS緩存,緩存中維護一張域名與IP地址的對應表;
    • 若沒有,則搜索操作系統緩存中有沒有對應的解析結果;
    • 若沒有,則操作系統將域名發送至本地域名服務器(遞歸查詢方式),本地域名服務器查詢自己的DNS緩存,查找成功則返回結果,否則,通過以下方式迭代查找:
      • 本地域名服務器向根域名服務器發起請求,根域名服務器返回com域的頂級域名服務器的地址;
      • 本地域名服務器向com域的頂級域名服務器發起請求,返回權限域名服務器地址;
      • 本地域名服務器向權限域名服務器發起請求,得到IP地址;
      • 本地域名服務器將得到的IP地址返回給操作系統,同時自己將IP地址緩存起來;
      • 操作系統將IP地址返回給瀏覽器,同時自己也將IP地址緩存起來;
        至此,瀏覽器已經得到了域名對應的IP地址。

2.1.4瀏覽器中輸入一個URL後,按下回車後發生了什麼

  1. 瀏覽器查找域名的IP地址

img

  1. 瀏覽器與目標服務器建立TCP連接
  • http協議建立在tcp協議之上,http請求前,需先進行tcp連接,形成客戶端到服務器的穩定的通道。俗稱TCP的三次握手。
  • tcp連接完成後,http請求開始,請求有多種方式,常見的有get,post等。
  • http請求包含請求頭,也可能包含請求體兩部分,請求頭中包含我們希望對請求文件的操作的信息,請求體中包含傳遞給後臺的參數。
  • 服務器收到http請求後,後臺開始工作,如負載平衡,跨域等,這裏就是後端的工作了。
  • 文件處理完畢,生成響應數據包,響應也包含兩部分,響應頭和相應體,響應體就是我們所請求的文件。
  • 經過網絡傳輸,文件被下載到本地客戶端,客戶端開始加載。

1、查詢DNS,獲取域名對應的ip

2、得到目標服務器的IP地址以及其端口號,調用系統庫socket函數,請求一個TCP流套接字,客戶端向服務器發送http請求報文:

3、服務器端經過物理層、數據鏈路層、網絡層、傳輸層、應用層,解析請求報文,發送http響應報文

html頁面的解析與渲染

  • 客戶端瀏覽器加載了html文件後,由上到下解析html爲DOM樹(DOM Tree)。
  • 遇到css文件,css中的url發起http請求。
  • 這是第二次http請求,由於http1.1協議增加了Connection: keep-alive聲明,故tcp連接不會關閉,可以複用。
  • http連接是無狀態連接,客戶端與服務器端需要重新發起請求–響應。在請求css的過程中,解析器繼續解析html,然後到了script標籤。
  • 由於script可能會改變DOM結構,故解析器停止生成DOM樹,解析器被js阻塞,等待js文件發起http請求,然後加載。這是第三次http請求。js執行完成後解析器繼續解析。
  • 由於css文件可能會影響js文件的執行結果,因此需等css文件加載完成後再執行。
  • 瀏覽器收到css文件後,開始解析css文件爲CSSOM樹(CSS Rule Tree)。
  • CSSOM樹生成後,DOM Tree與CSS Rule Tree結合生成渲染樹(Render Tree)。
  • Render Tree會被css文件阻塞,渲染樹生成後,先佈局,繪製渲染樹中節點的屬性(位置,寬度,大小等),然後渲染,頁面就會呈現信息。
  • 繼續邊解析邊渲染,遇到了另一個js文件,js文件執行後改變了DOM樹,渲染樹從被改變的dom開始再次渲染。
  • 繼續向下渲染,碰到一個img標籤,瀏覽器發起http請求,不會等待img加載完成,繼續向下渲染,之後再重新渲染此部分。
  • DOM樹遇到html結束標籤,停止解析,進而渲染結束。

輸入一個URL,但是沒有訪問到預期的網站,是什麼原因?

1.PC網絡故障

2.400客戶端出錯

3.401服務器拒絕提供服務

  1. 403請求的資源不存在

5.500服務器內部錯誤

6.請求或者響應在網絡傳輸中途被劫走了

7.可能是DNS出錯了。

PC網絡故障

  1. 首先排除接觸故障,確保你的網線是可以正常使用
  2. 排除偶然故障,禁用網卡後再啓用。
  3. 使用ipconfig查看計算機的上網參數 ,輸入ipconfig/all,可以看到IP地址和網卡物理地址等相關網絡詳細信息。
  4. 使用ping命令測試網絡的連通性,定位故障範圍。Ping本地地址“127.0.0.1”,若丟包率爲0,則可以判斷本機網絡協議工作正常。否則表明本機網卡的安裝或TCP/IP協議有問題,接下來檢查網卡TCP/IP協議。
  5. 第四步正常的情況下,Ping本機IP地址,若不能ping通,則說明本機網卡驅動程序不正確,或者網卡與網線之間連接有故障
  6. Ping網關,若能被ping通,則本機網絡連接正常。否則可能是網關設備存在問題或者上網參數設置有誤,檢查網絡參數。

Socket

Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,

img

2.2 數據結構與算法

常見的數據結構

img

圖片中的數組的優缺點寫錯,參考下方

  1. 數組

    • 數組是可以在內存中連續存儲多個元素的結構,在內存中的分配也是連續的 。

    • 其查詢效率,修改的效率相對鏈表來說比較高。

    • 插入、刪除數據的時候

  2. 鏈表

    • 鏈表是物理存儲單元上非連續的、非順序的存儲結構
    • 查詢、修改效率低
    • 插入、刪除效率高,不用移動元素
  3. 隊列

  4. 散列表

    散列表,也叫哈希表,是根據關鍵碼和值 (key和value) 直接進行訪問的數據結構,通過key和value來映射到集合中的一個位置,這樣就可以很快找到集合中的對應元素。

    • 紅黑樹

      紅黑樹的特點:

      速度特別快,趨近平衡樹,查找葉子元素最少和最多次數不多於二倍。

      節點可以是紅色的或者黑色的
      根節點是黑色的
      葉子節點(特指空節點)是黑色的
      每個紅色節點的子節點都是黑色的
      任何一個節點到其每一個葉子節點的所有路徑上黑色節點數相同
      

2.2.1 排序算法

https://blog.csdn.net/racheil/article/details/90763011

冒泡排序

img
public static void BubbleSort(int[] array){
    for(int i=0;i<array.length-1;i++){// 趟數
        for(int j=0;j<array.length-1-i;j++){//每趟比較次數
            if(array[j]>array[j+1]){
                int temp = array[j];
                array[j] = array[j+1];
                a[j+1] = temp;
            }
        }
    }
}

選擇排序

基本思想:

每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的數據元素排完 。

img
public static void selectSort(int[] array){
    for(int i=0;i<array.length;i++){
        for(int j = i+1;j<array.length;j++){
            if(array[i]>array[j]){//從小到大排序
                int temp = array[i];
                array[i]= array[j];
                array[j] = temp;
            }
        }
     	   
    }
        
}

快速排序

  • 從數列中挑出一個元素,稱爲"基準"(pivot)。
  • 重新排序數列,所有比基準值小的元素擺放在基準前面,所有比基準值大的元素擺在基準後面(相同的數可以到任一邊)。在這個分區結束之後,該基準就處於數列的中間位置。這個稱爲分區(partition)操作。
  • 遞歸地(recursively)把小於基準值元素的子數列和大於基準值元素的子數列排序。
    ————————————————
    版權聲明:本文爲CSDN博主「Racheil」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
    原文鏈接:https://blog.csdn.net/racheil/article/details/90763011
img
 //找基準,返回第一趟排序後的基準(low)的位置
    public static int partion(int[] array,int low,int high){
         int tmp=array[low];
      //hign向前走找比tmp小的值
     while(low<high){
        while(low<high&&array[high]>=tmp){
             high--;
         }
         if(low>=high){  
             array[low] = tmp;
             break;
         }else{
             array[low] = array[high];
         }
         //low向後走找比tmp大的值
         while(low<high&&array[low]<=tmp){
             low++;
         }
         if(low>=high){   //low與high相遇,即沒有比tmp大的值了,此時需把基準放在相遇的位置
            array[low] = tmp;
             break;
         }else{
             array[high] = array[low];
         }
     }
     return low;//此時low和high相遇,返回第一趟排序後的基準(low)的位置
    }
 
    public static void quick(int[] array,int start,int end) {
        int par = partion(array,start,end); //找基準
        //遞歸左邊
        if(par>start+1){  //至少保證有兩個數據
            quick(array,start,par-1);
        }
        //遞歸右邊
        if(par<end-1){
            quick(array,par+1,end);
        }
    }
 
    public static void quickSort1( int[] array){
        quick(array,0, array.length-1);
    }

算法效率

算法名稱 平均時間複雜度 最好時間複雜度 最壞時間複雜度 空間複雜度 穩定性
直接插入排序 O(N^2) O(N) O(N^2) O(1) 穩定
希爾排序 O(nlogn) O(n^1.3) O(n^2) O(1) 不穩定
選擇排序 O(N^2) O(N^2) O(N^2) O(1) 不穩定
冒泡排序 O(N^2) O(N) O(N^2) O(1) 穩定
快速排序 O(nlogn) O(nlogn) O(N^2) O(logn)~ O(n) 不穩定
歸併排序 O(nlogn) O(nlogn) O(nlogn) O(n) 穩定

2.2.2 查找算法

二分法查找

//版本1
public int BinarySearch(int ary[] ,int value ,int n){
    int low,middle,high;
    low = 0;
    high = n-1;
    while(low<high){
        mid = low+(high-low)/2;
        if(ary[mid] == value){
            return mid;
        }
        if(ary[mid] > value){
            high = mid-1;
        }
        if(ary[mid] < value){
            low = mid+1;
    }
}
    
//版本2
int BinarySearch2(int ary[] ,int value, int low ,int high){
    int mid = low+(high-low)/2;
    if(a[mid] == value)
        return mid;
    if(a[mid]>value)
        return BinarySearch2(ary,value,low,mid-1);
    if(a[mid]<value)
        return BinarySearch2(ary,value,mid+1,high);
}

2.3 操作系統

2.3.1 Linux

linux命令,找出關鍵字出現的次數

  • 語法:grep 字符串 文件名|wc -l ,grep輸出,wc -l按行統計

  • 例子:

    • 統計task-hbase-transform.log中NullPointerException出現的次數:grep NullPointerException task-hbase-transform.log|wc -l
    • 如果是多個字符串出現次數,可使用: grep 'objStr1\|objStr2' filename|wc -l#直接用 | 鏈接起來即可。
  • “|”: 管道符“|”將兩個命令隔開,管道符左邊命令的輸出就會作爲管道符右邊命令的輸入。連續使用管道意味着第一個命令的輸出會作爲第二個命令的輸入,第二個命令的輸出又會作爲第三個命令的輸入,依此類推。

    • grep:-v 不顯示匹配上的內容;-n 顯示匹配上的內容
    • grep -v down,顯示不包含down的內容。
      • grep -n down,顯示包含down的內容。
    • du:(disk use)顯示每個文件和目錄的磁盤使用空間。
  • df:(disk free)顯示磁盤分區上可以使用的磁盤空間。

  • VI 顯示所有行的行號:vi set number

  • 找到共用80端口的線程

  • linux基本指令 awk、find、grep

  • shell腳本:統計一個文件中重複的行和重複次數

  • linux 如何將文件從一臺服務器轉移到另一臺服務器

  • 如何查找出現頻率最高的100個ip地址

查看進程:
1、ps 命令用於查看當前正在運行的進程
grep 是搜索
例如: ps -ef | grep java

2、查看自己的進程

ps -l

3、查看系統所有進程

ps aux

4、進程樹

查看所有進程樹

# pstree -A
  1. netstat

查看佔用端口的進程

示例:查看特定端口的進程

# netstat -anp | grep port

linux常用指令;

2.3.2 計算機操作系統

  1. 進程

    進程是資源分配的基本單位。

  2. 線程

    線程是獨立調度的基本單位。

    一個進程中可以有多個線程,它們共享進程資源

    進程與線程的區別

    • 擁有資源:進程是資源分配的基本單位。但是線程不擁有資源,線程可以訪問隸屬進程的資源
    • 調度:線程是獨立調度的基本單位,在同一進程中,線程的切換不會引起進程切換。 從一個進程中的線程切換到另一個進程中的線程時,會引起進程切換。
    • 系統開銷:創建和撤銷進程時,系統都要分配或者回收進程,其所付出的開銷遠大於創建或撤銷線程的開銷。
    • 通信方面:線程間可以通過讀寫同一進程中的數據進行通信,但是進程通信需要藉助IPC

    進程通信(IPC)

    https://mp.weixin.qq.com/s/5CbYGrylSKx1JwtOiW3aOQ

    • 管道:利用管道(“|”)的輸入輸出

      • 匿名管道
        • 只支持半雙工通信(單向交替傳輸);
        • 只能在父子進程或者兄弟進程中使用。
      • 命名管道FIFO
        • 只支持半雙工通信(單向交替傳輸);
        • 常用於客戶-服務器應用程序中
    • 消息隊列(類似於緩存)

    • 共享內存

      分配給進程的內存不是實際物理內存,而是虛擬內存空間

    • 信號量,相當於一個計數器。

    • socket

    死鎖

    死鎖是指兩個或兩個以上的線程在執行過程中,由於競爭資源或者由於彼此通信而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的進程稱爲死鎖進程。

    • 必要條件
      • 互斥:每個資源要麼已經分配給了一個進程,要麼就是可用的。
      • 佔有和等待:已經得到了某個資源的進程可以再請求新的資源。
      • 不可搶佔:已經分配給一個進程的資源不能強制性地被搶佔,它只能被佔有它的進程顯式地釋放。
      • 環路等待:有兩個或者兩個以上的進程組成一條環路,該環路中的每個進程都在等待下一個進程所佔有的資源。
    • 處理方法
      • 鴕鳥策略

      • 死鎖檢測與死鎖恢復

        • 一個資源的死鎖檢測:通過檢測有向圖是否存在環來實現 ( 深度優先搜索 )

        • 恢復:搶佔恢復、回滾恢復、殺死進程

        • 死鎖檢測

          • Jstack命令
          • JConsole工具
      • 死鎖預防:

        • 破壞必要條件
        • 超時放棄
      • 死鎖避免

        • 銀行家算法

2.4 數據庫

單表查詢、多表查詢、count、distinct、limit

數據庫事務

數據庫事務是數據庫管理系統執行過程中的一個邏輯單位,由一個有限的數據庫操作序列構成。

數據庫事務擁有以下四個特性,被稱之爲ACID特性:

原子性(Atomicity):事務作爲一個整體被執行,包含在其中的對數據庫的操作要麼全部被執行,要麼都不執行。

一致性(Consistency):事務應確保數據庫的狀態從一個一致狀態轉變爲另一個一致狀態。一致狀態的含義是數據庫中的數據應滿足完整性約束。

隔離性(Isolation):多個事務併發執行時,一個事務的執行不應影響其他事務的執行。

持久性(Durability):已被提交的事務對數據庫的修改應該永久保存在數據庫中

數據庫的四種隔離級別

來源: https://baijiahao.baidu.com/s?id=1611918898724887602&wfr=spider&for=pc

  1. 讀未提交(read uncommitted): 就是可以讀到未提交的內容

    在這種隔離級別下,查詢是不會加鎖的,也由於查詢的不加鎖,所以這種隔離級別的一致性是最差的,可能會產生“髒讀”、“不可重複讀”、“幻讀”。

    img
  2. 讀已提交(read committed): 就是隻能讀到已經提交了的內容。

    img
  3. 可重複讀(repeated read): 就是專門針對“不可重複讀”這種情況而制定的隔離級別

    普通的查詢同樣是使用的“快照讀”,但是,和“讀提交”不同的是,當事務啓動時,就不允許進行“修改操作(Update)”了

    img
  4. 序列化(serializable)

    這種級別下,事務“串行化順序執行”,也就是一個一個排隊執行。由於他大量加上鎖,導致大量的請求超時,因此性能會比較底下,再特別需要數據一致性且併發量不需要那麼大的時候纔可能考慮這個隔離級別。

    img

**“讀未提(Read Uncommitted)”能預防啥?**啥都預防不了。

**“讀提交(Read Committed)”能預防啥?**使用“快照讀(Snapshot Read)”,避免“髒讀”,但是可能出現“不可重複讀”和“幻讀”。

**“可重複讀(Repeated Red)”能預防啥?**使用“快照讀(Snapshot Read)”,鎖住被讀取記錄,避免出現“髒讀”、“不可重複讀”,但是可能出現“幻讀”。

**“串行化(Serializable)”能預防啥?**排排坐,喫果果,有效避免“髒讀”、“不可重複讀”、“幻讀”,不過效果誰用誰知道。

數據庫鎖機制

數據庫管理系統(DBMS)中的併發控制的任務是確保在多個事務同時存取數據庫中同一數據時不破壞事務的隔離性和統一性以及數據庫的統一性。

一、按操作劃分,可分爲DML鎖(數據鎖:data locks)、DDL鎖 (dictionary locks,數據字典鎖)

二、按鎖的粒度劃分,可分爲表級鎖行級鎖頁級鎖(mysql)

三、按鎖級別劃分,可分爲共享鎖排他鎖

四、按加鎖方式劃分,可分爲自動鎖顯示鎖

五、按使用方式劃分,可分爲樂觀鎖悲觀鎖

悲觀鎖( 具有強烈的獨佔和排他特性 )

顧名思義,很悲觀,每次去拿數據的時候都認爲別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人拿這個數據就會block(阻塞),直到它拿鎖。

  1. 共享鎖(S鎖)

    • 也叫讀鎖,用於所有的只讀數據操作。共享鎖是非獨佔的,允許多個併發事務讀取其鎖定的資源。
    • 性質
      • 多個事務可封鎖同一個共享頁
      • 任何事務都不能修改該頁
      • 通常是該頁被讀取完畢,S鎖立即被釋放。
  2. 排他鎖(X鎖)

    • 也叫寫鎖,表示對數據進行寫操作。如果一個事務對對象加了排他鎖,其他事務就不能再給他任何鎖。
    • 性質
      • 僅允許一個事務封鎖此頁。
      • 其他事務必須等到X鎖釋放才能對該頁就行訪問
      • X鎖一直到事務結束才釋放。
  3. 更新鎖

    • U鎖,在修改操作的初始化階段永安裏鎖定可能要被修改的資源,這樣可以避免共享鎖造成的死鎖現象。
    • 性質
      • 用來預定要對此頁施加X鎖,它允許其他事務讀,但不允許再施加U鎖或X鎖;
      • 當被讀取的頁要被更新時,則升級爲X鎖
      • U鎖一直到事務結束時才能被釋放。

    因爲當使用共享鎖時,修改數據的操作分爲兩步:

    1. 首先獲得一個共享鎖,讀取數據,
    2. 然後將共享鎖升級爲排他鎖,再執行修改操作。
      這樣如果有兩個或多個事務同時對一個事務申請了共享鎖,在修改數據時,這些事務都要將共享鎖升級爲排他鎖。這時,這些事務都不會釋放共享鎖,而是一直等待對方釋放,這樣就造成了死鎖。
      如果一個數據在修改前直接申請更新鎖,在數據修改時再升級爲排他鎖,就可以避免死鎖。
      原文鏈接:https://blog.csdn.net/weixin_39651041/article/details/79985715

樂觀鎖

顧名思義,就是很樂觀,每次去拿數據的時候都認爲別人不會修改,所以,不會上鎖。但是在更新的時候會判斷一下在此期間別人有沒有更新這個數據,可以使用版本號等機制。

  1. 版本號

  2. 時間戳

    使用數據庫服務器的時間戳

  3. 待更新字段

  4. 所有字段

併發控制會造成兩種鎖

  1. 活鎖

    定義:指的是T1封鎖了數據R,T2同時也請求封鎖數據R,T3也請求封鎖數據R,當T1釋放了鎖之後,T3會鎖住R,T4也請求封鎖R,則T2就會一直等待下去。
    解決方法:採用“先來先服務”策略可以避免。

  2. 死鎖

    定義:就是我等你,你又等我,雙方就會一直等待下去。比如:T1封鎖了數據R1,正請求對R2封鎖,而T2封住了R2,正請求封鎖R1,這樣就會導致死鎖,死鎖這種沒有完全解決的方法,只能儘量預防。
    預防方法:

    1. 一次封鎖法,指的是一次性把所需要的數據全部封鎖住,但是這樣會擴大了封鎖的範圍,降低系統的併發度;
    2. 順序封鎖法,指的是事先對數據對象指定一個封鎖順序,要對數據進行封鎖,只能按照規定的順序來封鎖,但是這個一般不大可能的。

    系統判定死鎖的方法:

    超時法:如果某個事物的等待時間超過指定時限,則判定爲出現死鎖;
    等待圖法:如果事務等待圖中出現了迴路,則判斷出現了死鎖。

髒讀、幻讀、可重複度

1.髒讀:

指一個事務A正在訪問數據,並且對該數據進行了修改,但是這種修改還沒有提交到數據庫中(也可能因爲某些原因Rollback了)。這時候另外一個事務B也訪問這個數據,然後使用了這個被A修改的數據,那麼這個數據就是髒的,並不是數據庫中真實的數據。這就被稱作髒讀。

解決辦法:把數據庫事務隔離級別調整到READ_COMMITTED

即讓用戶在更新時鎖定數據庫,阻止其他用戶讀取,直到更新全部完成才讓你讀取。

2.幻讀:

指一個事務A對一個表中的數據進行了修改,而且該修改涉及到表中所有的數據行;同時另一個事務B也在修改表中的數據,該修改是向表中插入一行新數據。那麼經過這一番操作之後,操作事務A的用戶就會發現表中還有沒修改的數據行,就像發生了幻覺一樣。這就被稱作幻讀。

解決辦法:把數據庫事務隔離級別調整到SERIALIZABLE_READ

3.不可重複讀:

指在一個事務A內,多次讀同一個數據,但是事務A沒有結束時,另外一個事務B也訪問該同一數據。那麼在事務A的兩次讀數據之間,由於事務B的修改導致事務A兩次讀到的數據可能是不一樣的。這就發生了在一個事務內兩次讀到的數據不一樣,這就被稱作不可重複讀。

解決辦法:把數據庫事務隔離級別調整到REPEATABLE_READ

注:

級別高低:髒讀 < 不可重複讀 < 幻讀

數據庫的三大範式

第一範式:保證列的原子性,保證列不可再分。

第二範式:唯一性 ;一個表只說明一個事物;有主鍵且非主鍵依賴主鍵;(限制多對多的關係,建立一個關聯表,通過外鍵和聯合主鍵來關聯兩張表)

第三範式:每列都與主鍵有直接關係,不存在傳遞依賴;(限制一對多的關係,在從表中建立一個外鍵,通過外鍵來引用主表的信息)

數據庫優化

https://www.jianshu.com/p/be44d846929d

  1. 選取最適用的字段屬性
  2. 使用連接(Join)來代替子查詢
  3. 使用聯合來代替手動創建臨時表
  4. 事務
  5. 鎖定表
  6. 使用外鍵
  7. 使用索引
  8. 優化的查詢語句

mysql查詢

  1. 自連接

    如果在一個連接查詢中涉及的兩個表其實是同一個表,這種查詢稱爲自連接查詢 。

    //要查詢王紅所在的部門的所有員工
    SELECT p1.*  FROM employee AS p1 JOIN employee AS p2 ON p1.did=p2.did WHERE p2.name='王紅';
    
  2. 外連接

    • 左連接(left join):返回左表中的所有記錄和右表中符合條件的記錄

      SELECT department.did,department.dname,employee.name 
      FROM department 
      LEFT JOIN employee ON department.did=employee.did
      

      img

    • 右連接(right join):返回右表中的所有記錄和左表中符合條件的記錄

      select department.did,department.dname,employee.name
      from department
      right join employee on department.did=employee.did
      

      img

  3. 內連接(inner join)

    又稱爲自然連接,內連接使用比較運算符對兩個表中的數據進行比較,並列出與連接條件匹配的數據行,組成新紀錄。

    SELECT employee.name,department.dname FROM department JOIN employee ON department.did=employee.did;
    

小表驅動大表

如果小的循環在外層,對於數據庫連接來說就只連接5次,進行5000次操作,如果1000在外,則需要進行1000次數據庫連接,從而浪費資源,增加消耗。這就是爲什麼要小表驅動大表。

MySql 中Char與VarChar的區別

  1. char
    • char類型是定長的類型,當輸入的字符長度超過指定的長度時,char會截取超出的字符;
    • 當存儲char值時,MySQL是自動刪除輸入字符串末尾的空格;
    • char是適合存儲很短的、一般固定長度的字符串。
  2. varchar
    • varchar(n)類型用於存儲可變長的。
    • 取數據的時候,不需要去掉多餘的空格
    • 另外它還需要使用1或2個額外字節記錄字符串的長度

group by 與 where, having以及順序

GROUP BY子句必須出現在WHERE子句之後,ORDER BY子句之前.

HAVING語句必須在ORDER BY子句之後。

(where先執行,再group by分組;having,order by。)

SELECT
`user`.roleId,
COUNT(`user`.userId) as total
FROM `user`
where ustatus = 1
GROUP BY roleId
HAVING total >1
ORDER BY sex DESC

img

where和having區別:
1.having只能用在group by之後,對分組後的結果進行篩選(即使用having的前提條件是分組)。
2.where肯定在group by 之前,即也在having之前。
3.where後的條件表達式裏不允許使用聚合函數,而having可以。

count函數用法

COUNT(*),COUNT(1),COUNT(column), COUNT(DISTINCT column)和COUNT(expression)

COUNT(*)函數返回由SELECT語句返回的結果集中的行數。COUNT(*)函數計算包含NULL和非NULL值的行,即:所有行。

count(1)這個用法和count(*)的結果是一樣的

COUNT(DISTINCT column)返回不包含NULL值且不包含重複的記錄算一條的唯一行數。

COUNT(column)返回不包含NULL值的所有行數

索引

https://www.cnblogs.com/wwxzdl/p/11116446.html

數據庫索引其實就是爲了使查詢數據效率快。

原理

索引就是通過事先排好序,從而在查找時可以應用二分查找等高效率的算法。

索引有哪些?

  1. 聚集索引(主鍵索引):在數據庫裏面,所有行數都會按照主鍵索引進行排序。
  2. 非聚集索引:就是給普通字段加上索引。
  3. 聯合索引:就是好幾個字段組成的索引,稱爲聯合索引。 聯合索引遵從最左前綴原則

索引的優缺點

索引的優點:
① 建立索引的列可以保證行的唯一性,生成唯一的rowId

② 建立索引可以有效縮短數據的檢索時間

③ 建立索引可以加快表與表之間的連接

④ 爲用來排序或者是分組的字段添加索引可以加快分組和排序順序

索引的缺點:
① 創建索引和維護索引需要時間成本,這個成本隨着數據量的增加而加大

② 創建索引和維護索引需要空間成本,每一條索引都要佔據數據庫的物理存儲空間,數據量越大,佔用空間也越大(數據表佔據的是數據庫的數據空間)

③ 會降低表的增刪改的效率,因爲每次增刪改索引需要進行動態維護,導致時間變長

什麼情況下需要建立索引
① 數據量大的,經常進行查詢操作的表要建立索引。

② 用於排序的字段可以添加索引,用於分組的字段應當視情況看是否需要添加索引。

③表與表連接用於多表聯合查詢的約束條件的字段應當建立索引。

原文鏈接:https://blog.csdn.net/m0_37925202/article/details/82939530

視圖

int count=0;
for(int i=1;i<5;i++){
    for(int j=1;j<5;j++){
    for(int k=1;k<5;k++){
    if(i!=j&&i!=k&&j!=k){
        System.out.println(i+j+k);
        count++;
    }
}
}
}

存儲過程

1.Hash

Hash索引的底層實現是由Hash表來實現的,非常適合以 key-value 的形式查詢,也就是單個key 查詢,或者說是等值查詢。其結構如下所示:

從上面結構可以看出,Hash 索引可以比較方便的提供等值查詢的場景,由於是一次定位數據,不像BTree索引需 要從根節點到枝節點,最後才能訪問到頁節點這樣多次IO訪問,所以檢索效率遠高於BTree索引。但是對於範圍查詢的話,就需要進行全表掃描了。

但爲什麼我們使用BTree比使用Hash多呢?主要Hash本身由於其特殊性,也帶來了很多限制和弊端:

  1. Hash索引僅僅能滿足“=”,“IN”,“<=>”查詢,不能使用範圍查詢。
  2. 聯合索引中,Hash索引不能利用部分索引鍵查詢。 對於聯合索引中的多個列,Hash是要麼全部使用,要麼全部不使用,並不支持BTree支持的聯合索引的最優前綴,也就是聯合索引的前面一個或幾個索引鍵進行查詢時,Hash索引無法被利用。
  3. Hash索引無法避免數據的排序操作 由於Hash索引中存放的是經過Hash計算之後的Hash值,而且Hash值的大小關係並不一定和Hash運算前的鍵值完全一樣,所以數據庫無法利用索引的數據來避免任何排序運算。
  4. Hash索引任何時候都不能避免表掃描 Hash索引是將索引鍵通過Hash運算之後,將Hash運算結果的Hash值和所對應的行指針信息存放於一個Hash表中,由於不同索引鍵存在相同Hash值,所以即使滿足某個Hash鍵值的數據的記錄條數,也無法從Hash索引中直接完成查詢,還是要通過訪問表中的實際數據進行比較,並得到相應的結果。
  5. Hash索引遇到大量Hash值相等的情況後性能並不一定會比BTree高 對於選擇性比較低的索引鍵,如果創建Hash索引,那麼將會存在大量記錄指針信息存於同一個Hash值相關聯。這樣要定位某一條記錄時就會非常麻煩,會浪費多次表數據訪問,而造成整體性能底下。

3. 擴展:B+/-Tree原理

B樹和B+樹 B樹和B+樹算是數據結構中出現頻率十分高的模型了,在筆者之前的幾篇博客,有對二叉查找樹和二叉平衡樹進行過講解和代碼分析,但是那些都是在程序中使用比較多的樹,在數據庫中,數據量相對較大,多路查找樹顯然更加適合數據庫的應用場景,接下來我們就介紹這兩類多路查找樹,畢竟作爲程序員,心裏沒點B樹怎麼能行呢?

B樹:B樹就是B-樹,他有着如下的特性:

1、B樹不同於二叉樹,他們的一個節點可以存儲多個關鍵字和多個子樹指針,這也是B+樹的特點;

2、一個m階的B樹要求除了根節點以外,所有的非葉子子節點必須要有[m/2,m]個子樹;

3、根節點必須只能有兩個子樹,當然,如果只有根節點一個節點的情況存在;

4、B樹是一個查找二叉樹,這點和二叉查找樹很像,他都是越靠前的子樹越小,並且,同一個節點內,關鍵字按照大小排序;

5、B樹的一個節點要求子樹的個數等於關鍵字的個數+1;

由於B樹將所有的查找關鍵字都放在節點中,所以查找方式和二叉查找十分相像,比如說查找E:

先通過根節點找到了左子樹,再順序地遍歷左子樹,發現E在F和J的中間,於是查找葉子節點,順序遍歷關鍵字以後就可以返回E了,如果未能查到E,則表示沒有找到。

B+樹

1、B+樹將所有的查找結果放在葉子節點中,這也就意味着查找B+樹,就必須到葉子節點才能返回結果;

2、B+樹每一個節點的關鍵字個數和子樹指針個數相同;

3、B+樹的非葉子節點的每一個關鍵字對應一個指針,而關鍵字則是子樹的最大,或者最小值;

mybatis

MyBatis有什麼優勢,他如何做事務管理

MyBatis優點:

1.易於上手和掌握

  1. sql寫在xml裏,便於統一管理和優化

  2. 提供xml標籤,支持編寫動態sql。

  3. 提供映射標籤,支持對象與數據庫的orm字段關係映射

  4. 提供對象關係映射標籤,支持對象關係組建維護

6. 解除sql與程序代碼的耦合。

Mybatis管理事務是分爲兩種方式:

(1)使用JDBC的事務管理機制,就是利用java.sql.Connection對象完成對事務的提交

(2)使用MANAGED的事務管理機制,這種機制mybatis自身不會去實現事務管理,而是讓程序的容器(JBOSS,WebLogic)來實現對事務的管理

redis

Redis 是什麼 ?

Redis 是 C 語言開發的一個開源的(遵從 BSD 協議)高性能鍵值對(key-value)的內存數據庫,可以用作數據庫、緩存、消息中間件等。 它是一種 NoSQL(not-only sql,泛指非關係型數據庫)的數據庫。

優點:

  • Redis 作爲一個內存數據庫: 性能優秀,數據在內存中,讀寫速度非常快,支持併發 10W QPS。
  • 單進程單線程,是線程安全的,採用 IO 多路複用機制。
  • 豐富的數據類型,支持字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。
  • 支持數據持久化。可以將內存中數據保存在磁盤中,重啓時加載。主從複製,哨兵,高可用。
  • 可以用作分佈式鎖。
  • 可以作爲消息中間件使用,支持發佈訂閱。

瞭解下 Redis 內部內存管理是如何描述這 5 種數據類型的

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kpfrvIIN-1585126522542)(https://pics6.baidu.com/feed/023b5bb5c9ea15ce598be46bdbb071f53b87b2a5.jpeg?token=3f5ccd21917fb33a2472bbb06b480a56&s=5AA834629B8961495EFDB0C70000E0B1)]

①String 是 Redis 最基本的類型,可以理解成與 Memcached一模一樣的類型,一個 Key 對應一個 Value。Value 不僅是 String,也可以是數字。

String 類型是二進制安全的,意思是 Redis 的 String 類型可以包含任何數據,比如 jpg 圖片或者序列化的對象。String 類型的值最大能存儲 512M。

②Hash是一個鍵值(key-value)的集合。Redis 的 Hash 是一個 String 的 Key 和 Value 的映射表,Hash 特別適合存儲對象。常用命令:hget,hset,hgetall 等。

③List 列表是簡單的字符串列表,按照插入順序排序。可以添加一個元素到列表的頭部(左邊)或者尾部(右邊) 常用命令:lpush、rpush、lpop、rpop、lrange(獲取列表片段)等。

④Set 是 String 類型的無序集合。集合是通過 hashtable 實現的。Set 中的元素是沒有順序的,而且是沒有重複的。常用命令:sdd、spop、smembers、sunion 等。

⑤Zset 和 Set 一樣是 String 類型元素的集合,且不允許重複的元素。常用命令:zadd、zrange、zrem、zcard 等。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-jW7ryrPT-1585126522547)(https://pics1.baidu.com/feed/7a899e510fb30f24c7a97030a6259a45ad4b030c.png?token=45944d39516c10989237aecc64801ed9&s=19A07D32159BD5CE12D591CA0000F0B3)]

緩存技術

Redis****可以實現緩存機制, Redis是一個key-value存儲系統。

Redis支持豐富的數據類型,最爲常用的數據類型主要由五種:String、Hash、List、Set和Sorted Set。

Redis通常將數據存儲於內存中,或被配置爲使用虛擬內存。

Redis有一個很重要的特點就是它可以實現持久化數據,通過兩種方式可以實現數據持久化:使用RDB快照的方式,將內存中的數據不斷寫入磁盤;或使用類似MySQL的AOF日誌方式,記錄每次更新的日誌。前者性能較高,但是可能會引起一定程度的數據丟失;後者相反。

Redis支持將數據同步到多臺從數據庫上,這種特性對提高讀取性能非常有益。

2.5 編程語言

2.5.1 Java

new Integer(123) 與 Integer.valueOf(123) 的區別在於:

  • new Integer(123) 每次都會新建一個對象;
  • Integer.valueOf(123) 會使用緩存池中的對象,多次調用會取得同一個對象的引用。

[String](https://cyc2018.github.io/CS-Notes/#/notes/Java 基礎?id=二、string)

String 被聲明爲 final,因此它不可被繼承。(Integer 等包裝類也不能被繼承)

String初始化之後就不可變

1. 可以緩存 hash 值

因爲 String 的 hash 值經常被使用,例如 String 用做 HashMap 的 key。不可變的特性可以使得 hash 值也不可變,因此只需要進行一次計算。

2. String Pool 的需要

如果一個 String 對象已經被創建過了,那麼就會從 String Pool 中取得引用。只有 String 是不可變的,纔可能使用 String Pool。

img

3. 安全性

String 經常作爲參數,String 不可變性可以保證參數不可變。

4. 線程安全

String 不可變性天生具備線程安全,可以在多個線程中安全地使用。

[String, StringBuffer and StringBuilder](https://cyc2018.github.io/CS-Notes/#/notes/Java 基礎?id=string-stringbuffer-and-stringbuilder)

1、可變性

  • String不可變
  • StringBuffer和StringBuuilder可變

2、線程安全

  • String不可變,因此線程是安全的
  • StringBuffer是線程安全的,內部使用synchronized進行同步
  • StringBuilder不是線程安全的

Array和ArrayList的區別:

1、Array類型的變量在聲明的同時必須進行實例化(至少得初始化數組的大小),而ArrayList可以只是先聲明;

2、Array對象的初始化必須指定大小,且創建後的數組大小是固定的;而ArrayList的大小可以動態指定,空間大小可以任意增加;

3、Array始終是連續存放的;而ArrayList的存放不一定連續;

4、Array不能隨意添加、刪除;而ArrayList可以在任意位置插入和刪除

ArrayList和LinkedList的區別

1.ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。
2.對於查詢和修改操做get和set,ArrayList覺得優於LinkedList,因爲LinkedList要移動指針。
3.對於新增和刪除操作add和remove,LinedList比較佔優勢,因爲ArrayList要移動數據 。

HashMap 和 Hashtable 的區別

  1. 線程安全: HashMap 是非線程安全的,而 Hashtable 是線程安全的,因爲 Hashtable 內部的方法,基本都經過 synchronized 修飾(如果要確保線程安全,建議使用 ConcurrentHashMap);

  2. 執行效率: 因爲線程安全的原因,HashMap 要比 Hashtable 效率高;此外,由於 Hashtable 基本被淘汰,最好不要在項目中使用它;

  3. 對 Null key 和 Null value 的支持: HashMap 中,null 可以作爲鍵,這樣的鍵最多可以有一個,但可以有一個或多個鍵所對應的值爲 null;在 Hashtable 中,鍵和值都不能爲 null,否則會直接拋出 NullPointerException;

  4. 初始容量大小和擴容的機制不同
    ① 創建時,如果未指定容量初始值,Hashtable 默認的初始大小爲11,之後每次擴充,容量變爲原來的 2n+1;HashMap 默認的初始大小爲16,之後每次擴充,容量變爲原來的2倍;
    ② 創建時,如果給定了容量初始值,Hashtable 將直接使用給定大小作爲初始容量;而 HashMap 會將其擴充爲2的冪次方大小,也就是說, HashMap 總是使用2的冪作爲哈希表的大小;

底層數據結構: JDK1.8 以後,HashMap 在解決哈希衝突時有了較大的變化,當鏈表長度大於閾值(默認爲8)時,會自動將鏈表轉化爲紅黑樹,以減少搜索時間,而 Hashtable 沒有這樣的機制。

數據類型轉換

自動數據類型轉換

自動轉換按從低到高的順序轉換。不同類型數據間的優先關係如下:
低--------------------------------------------->高
byte,short,char-> int -> long -> float -> double

強制數據類型轉換

多態的定義,三個必要條件

多態:允許不同類的對象對同一消息做出相應反應。同一消息可以根據發送對象的不同而採用不同的行爲方式。舉例按F1鍵獲取不同的幫助。

Java實現多態有三個必要條件:

1)繼承

2)重寫

3)向上轉型:多態中需要將子類的引用賦給父類對象,只有這樣該引用才能夠調用父類的方法和子類的方法(父類引用指向子類對象。)

重寫和重載的區別;

方法的重載和重寫都是實現多態的方式 。

區別在於前者實現的是編譯時的多態性,而後者實現的是運行時的多態性。

重寫發生在子類與父類之間,重寫要求子類被重寫方法與父類被重寫方法有相同的參數列表,有兼容的返回類型。

重載發生在一個類中,同名的方法有不同的參數列表(參數類型不同、參數個數不同或者二者都不同)。

class和interface的區別

1、接口類似於類,但接口的成員都沒有執行方法

2、不能實例化一個接口,而類可以實例化(abstract類除外)

3、接口沒有構造函數,類有構造函數

4、接口的成員沒有任何修飾符,其成員總是公共的,而類的成員則可以有修飾符(如:虛擬或者靜態)

接口與抽象類的區別

參數 抽象類 接口
默認的方法實現 它可以有默認的方法實現 接口完全是抽象的,不存在方法的實現
實現 子類使用extends關鍵字來繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有聲明的方法的實現。 子類使用關鍵字implements來實現接口。它需要提供接口中所有聲明的方法的實現
構造器 抽象類可以有構造器 接口不能有構造器
與正常Java類的區別 除了你不能實例化抽象類之外,它和普通Java類沒有任何區別 接口是完全不同的類型
訪問修飾符 抽象方法可以有public、protected和default這些修飾符 接口方法默認修飾符是public static final,不可以使用其它修飾符。
多繼承 抽象方法可以繼承一個類和實現多個接口 接口只可以繼承一個或多個其它接口
速度 它比接口速度要快 接口是稍微有點慢的,因爲它需要時間去尋找在類中實現的方法。
添加新方法 如果你往抽象類中添加新的方法,你可以給它提供默認的實現。因此你不需要改變你現在的代碼。 如果你往接口中添加方法,那麼你必須改變實現該接口的類。
變量 構造方法 方法
抽象類 無限制 子類通過構造方法鏈調用構造方法,抽象類不能用new操作符實例化 無限制
接口 所有變量必須是public static final 沒有構造方法,接口不能用new操作符實例化 所有方法必須是公共類的抽象實例

實例變量、實例方法、類變量、類方法

  • 實例方法可以直接訪問實例變量,調用實例方法;

  • 實例方法可以直接訪問類變量,調用類方法。但不推薦這麼做,原因是不清晰,容易把類變量誤認爲是實例變量,把類方法誤認爲是實例方法(藉助IDE,它會給出警告信息);

  • 類方法可以直接調用類變量和類方法;

  • 類方法不能直接調用實例變量和實例方法;

  • 類方法裏面不能使用“this”關鍵字,因爲沒有實例存在,“this”不知道引用哪個實例。

    原文鏈接:https://blog.csdn.net/qq_33704186/article/details/90311296

Integer與int的區別

1、integer是int的包裝類,int是Java的一種基本數據類型

2、integer變量必須實例化後才能使用,int變量不需要

3、integer實際是對對象的引用,int是直接存儲數據值

4、integer的默認值是null,int的默認值是0

Equals通常用來比較兩個對象的內容是否相等,==用來比較兩個對象的地址是否相等

java中創建線程的四種方法以及區別

Java使用Thread類代表線程,所有的線程對象都必須是Thread類或其子類的實例。Java可以用四種方式來創建線程,如下所示:

1)繼承Thread類創建線程

定義Thread類的子類,並重寫Thread類的run()方法,創建子類對象(即線程對象),調用線程對象的start()方法來啓動該線程。

2)實現Runnable接口創建線程

  • 定義Runnable接口的實現類
  • 重寫該接口的run()方法
  • 通過Thread類建立線程對象
  • 將Runable接口的子類對象作爲實際參數傳遞給Thread類的構造函數
  • 調用Thread類的start方法開啓線程並調用Runable接口子類的Run方法

3)使用Callable和Future創建線程

4)使用線程池例如用Executor框架

線程的五種狀態

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-IYsMSNCq-1585126522549)(C:\Users\zhangboyi\AppData\Roaming\Typora\typora-user-images\1584198984106.png)]

1、新生狀態

在程序中用構造方法(new操作符)創建一個新線程時,如new Thread®,該線程就是創建狀態,此時它已經有了相應的內存空間和其它資源,但是還沒有開始執行。

2、就緒狀態

新建線程對象後,調用該線程的**start()**方法就可以啓動線程。當線程啓動時,線程進入就緒狀態(runnable)。由於還沒有分配CPU,線程將進入線程隊列排隊,等待 CPU 服務,這表明它已經具備了運行條件。當系統挑選一個等待執行的Thread對象後,它就會從等待執行狀態進入執行狀態。系統挑選的動作稱之爲“CPU調度"。一旦獲得CPU線程就進入運行狀態並自動調用自己的run方法。

3、運行狀態

當就緒狀態的線程被調用並獲得處理器資源時,線程就進入了運行狀態。此時,自動調用該線程對象的run()方法。run()方法定義了該線程的操作和功能。運行狀態中的線程執行自己的run方法中代碼。直到調用其他方法或者發生阻塞而終止。

4、阻塞狀態

一個正在執行的線程在某些特殊情況下,如被人爲掛起或需要執行耗時的輸入輸出操作時,suspend()、 wait()等方法,線程都將進入堵塞狀態。堵塞時,線程不能進入排隊隊列,只有當引起堵塞的原因被消除後,線程轉入就緒狀態。重將讓出 CPU 並暫時中止自己的執行,進入堵塞狀態。在可執行狀態下,如果調用 sleep()、 新到就緒隊列中排隊等待,這時被CPU調度選中後會從原來停止的位置開始繼續執行。

5、死亡狀態

線程調用stop()方法、destory()方法或 run()方法執行結束後,線程即處於死亡狀態。處於死亡狀態的線程不具有繼續運行的能力。

Java虛擬機(JVM)

Java虛擬機(JVM)是運行Java字節碼的虛擬機,它是java編程語言的核心。

  • 當我們運行程序時,JVM負責將字節代碼轉換爲特定於機器的代碼
  • JVM還依賴於平臺,並提供核心Java函數,如內存管理,垃圾收集,安全性等。

JVM被稱爲虛擬,因爲它提供的接口不依賴於底層操作系統和機器硬件。這種與硬件和操作系統的獨立性使得java程序可以在任何地方進行一次寫入。

java jvm的內存機制

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-46CDxShJ-1585126522552)(C:\Users\zhangboyi\AppData\Roaming\Typora\typora-user-images\1584201825931.png)]

img

https://blog.csdn.net/sun337939896/article/details/79092356

程序計數器和虛擬機棧都是線程私有的內存。


1.程序計數器:

  • 可以看做是當前線程所執行的字節碼的行號指示器。每條線程都有一個獨立的程序計數器,所以程序計數器是線程私有的內存區域

  • 主要存放代碼執行的位置。分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要計數器來完成。

2.Java虛擬機棧:

  • 存放各種基本數據類型和對象引用。
  • Java虛擬機棧是線程私有的,它的生命週期與線程相同。

3.本地方法棧

本地方法棧與虛擬機棧的區別:虛擬機棧爲虛擬機執行Java方法服務(也就是字節碼),而本地方法棧爲虛擬機使用到的Native方法服務。

堆和方法區是各個線程共享的內存區域

4.Java堆:

  • 存放的是new創建的對象實例。幾乎所有對象都在此分配內存。
  • 所有的線程共享的一塊內存區域,在虛擬機啓動時創建。
  • 垃圾回收器管理的主要區域。
  • 可以處於物理上不連續的內存空間中,只要邏輯上是連續的即可

5.方法區:

  • 它用於存儲已被虛擬機加載的類信息常量靜態變量即時編譯器編譯後的代碼等數據
  • 所有的線程共享的一塊內存區域。

類的加載機制

類的加載過程是指將java編譯之後的class文件讀入到內存中,然後在堆區創建一個java.lang.Class對象,用於封裝類在方法區內的數據結構。類加載的最終目的是封裝類在方法區的數據結構,並向java程序員提供訪問方法區數據的接口

垃圾回收機制GC

https://www.jianshu.com/p/23f8249886c6

垃圾回收(Garbage Collection)是Java虛擬機(JVM)垃圾回收器提供的一種用於在空閒時間不定時回收無任何對象引用的對象佔據的內存空間的一種機制。

垃圾判斷算法

  • 引用計數法

    給每個對象添加一個計數器,當有地方引用該對象時計數器加1,當引用失效時計數器減1。用對象計數器是否爲0來判斷對象是否可被回收。缺點:無法解決循環引用的問題

  • 可達性分析算法

通過一系列的 GC Roots的對象作爲起始點,從這些節點出發所走過的路徑稱爲引用鏈。當一個對象到 GC Roots 沒有任何引用鏈相連的時候說明對象不可用。

可作爲 GC Roots 的對象:

  • 虛擬機棧(棧幀中的本地變量表)中引用的對象
  • 方法區中類靜態屬性引用的對象
  • 方法區中常量引用的對象
  • 本地方法棧中 JNI(即一般說的 Native 方法) 引用的對象

垃圾回收算法

在確定了哪些垃圾可以被回收後,垃圾收集器要做的事情就是開始進行垃圾回收,但是這裏面涉及到一個問題是:如何高效地進行垃圾回收。這裏我們討論幾種常見的垃圾收集算法的核心思想。

  • 標記-清除算法

    • 效率不高
    • 空間會產生大量碎片
  • 複製算法

    會造成空間利用率低下。

  • 標記-整理算法

    解決內存碎片化問題,把存活的對象移到內存一端。

  • 分代收集算法

    根據存活對象劃分幾塊內存區,一般是分爲新生代和老年代。然後根據各個年代的特點制定相應的回收算法。

    新生代

    每次垃圾回收都有大量對象死去,只有少量存活,選用複製算法比較合理。

    老年代

    老年代中對象存活率較高、沒有額外的空間分配對它進行擔保。所以必須使用 標記 —— 清除 或者 標記 —— 整理 算法回收。

內存泄露與內存溢出

內存泄漏:當一個對象已經不需要再使用本該被回收時,另外一個正在使用的對象持有它的引用從而導致它不能被回收,這導致本該被回收的對象不能被回收而停留在堆內存中,這就產生了內存泄漏。

**內存溢出:**爲每個應用程序分配的內存是有限的,而當一個應用中產生的內存泄漏比較多時,這就難免會導致應用所需要的內存超過系統分配的內存限額,這就造成了內存溢出。

java裏內存泄漏和溢出的區別

1、內存泄漏memory leak :是指程序在申請內存後,無法釋放已申請的內存空間,一次內存泄漏似乎不會有大的影響,但內存泄漏堆積後的後果就是內存溢出。

2、內存溢出 out of memory :指程序申請內存時,沒有足夠的內存供申請者使用,或者說,給了你一塊存儲int類型數據的存儲空間,但是你卻存儲long類型的數據,那麼結果就是內存不夠用,此時就會報錯OOM,即所謂的內存溢出。

內存溢出常見原因:

1.內存中加載的數據量過於龐大,如一次從數據庫取出過多數據;
2.集合類中有對對象的引用,使用完後未清空,使得JVM不能回收;
3.代碼中存在死循環或循環產生過多重複的對象實體;
4.使用的第三方軟件中的BUG;
5.啓動參數內存值設定的過小

解決方案:

1、修改JVM參數,直接增加內存

2、檢查錯誤日誌,查看內存溢出錯誤前是否有其他異常錯誤

3、對代碼進行走查分析,找出可能發生內存溢出的位置

類加載器

Java**類加載器(**Java Classloader)是Java運行時環境(Java Runtime Environment)的一部分,負責動態加載Java類到Java虛擬機的內存空間中。

類加載器的分類:

啓動類加載器擴展類加載器應用類加載器(系統類加載器)、用戶自定義類加載器
啓動類加載器:這個類負責將存放在JAVA_HOME/lib目錄或者被-Xbootclasspath參數所指定的路徑中的並且是虛擬機內存中。
擴展類加載器:負責加載JAVA_HOME/lib/ext目錄中或者被java.ext.dirs系統變量指定路徑中的所有類庫,開發者可以直接使用擴展類加載器。
應用程序類加載器:負責加載用戶類路徑上指定的類加載器,一般情況下就是程序中默認的類加載器。

隊列與棧的區別

1、隊列先進先出,棧先進後出。

2、對插入和刪除操作的"限定"不同。

  • 棧是限定只能在表的一端進行插入和刪除操作的線性表。

  • 隊列是限定只能在表的一端進行插入和在另一端進行刪除操作的線性表。

3、遍歷數據速度不同。

  • 棧只能從頭部取數據,也就最先放入的需要遍歷整個棧最後才能取出來,而且在遍歷數據的時候還得爲數據開闢臨時空間,保持數據在遍歷前的一致性。
  • 隊列則不同,它基於地址指針進行遍歷,而且可以從頭或尾部開始遍歷,但不能同時遍歷,無需開闢臨時空間,因爲在遍歷的過程中不影響數據結構,速度要快的多

棧與隊列的相同點:

1.都是線性結構。

2.插入操作都是限定在表尾進行。

3.都可以通過順序結構和鏈式結構實現。、

4.插入與刪除的時間複雜度都是O(1),在空間複雜度上兩者也一樣。

5.多鏈棧和多鏈隊列的管理模式可以相同。

堆和棧

堆和棧分別存放什麼東西?

  • 棧內存裏面存放基本類型的變量對象的引用變量

  • 堆內存裏面存放new創建的對象和數組

堆棧空間分配區別:

1、棧(操作系統):由操作系統自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧;

2、堆(操作系統):一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似於鏈表。

堆棧數據結構區別:

堆(數據結構):堆可以被看成是一棵樹,如:堆排序;

棧(數據結構):一種先進後出的數據結構。

申請效率的比較

棧:由系統自動分配,速度較快。但程序員是無法控制的。

堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便。

****Hash****表即散列表

其最突出的優點是查找和插入刪除具有常數時間的複雜度

其實現原理是:把Key通過一個固定的算法函數即所謂的哈希函數轉換成一個整型數字,然後就將該數字對數組長度進行取餘,取餘結果就當作數組的。

數組與鏈表的區別

數組:

1、在內存中,數組是一塊連續的區域。

2、數組需要預留空間,空間利用率較低

3、插入和刪除數據都要大量移動元素的位置,效率比較低下,但查詢效率比較高

4、數組的空間是從棧分配的。

鏈表

1、在內存中,空間是分散的,不是連續性的

2、鏈表的查詢效率低,但插入或刪除的效率高

3、空間不需要提前指定大小,是動態申請的,空間利用率較高。

4、鏈表的空間從堆中分配

2.6 智力題

1、 有25匹馬,5個跑道。沒有秒錶。爲了選出跑得最快的三匹馬,請問最少進行多少輪比賽?

​ 7場。思路如下:

  • 25匹馬分5組,分別選出每組的第一,+5場

  • 各組第一再比一場,+1場,(確定第一名,以及記錄本場賽跑前三名所在的小組)

  • 排除掉已確定的第一名和不可能排名前三名的馬,剩餘5匹,再比一場,取得前兩名,+1場。(即第6場比賽排名第一的小組的第二、三名,排名第二所在的小組,取第一第二名,排名第三所在的小組,取第一名,總共5匹)

2、有一個5L和一個3l 的無刻度水杯,還有一個水池。如何量出4L水

  • 5L杯裝滿水,用5L杯的水裝滿3L杯(此時5L杯還有2L水)
  • 將3L杯的水倒進水池,在將5L杯剩下的2L水倒入3L杯中
  • 又取水池的水裝滿5L杯,用5L杯的水裝滿3L杯(倒進1L水)
  • 5L杯還剩4L
    3、老王進貨一雙鞋30,標價40,但是一直賣不出去,後面決定以標價50%賣出。這時候來買的人,拿了張五十元的,老王沒零錢,去隔壁老李找了五張十塊的。交易完成顧客離開後,老李發現那張50的是假鈔,老王出於誠信賠老李50元,請問老王虧了多少錢?
  • 110元=假若不是假錢,虧了10塊錢
  • 現爲假錢,顧客那賠了50+10,老李那賠了50

4、有1001個珍愛幣,每次只能取1,2,4個。現有A,B兩個人。A先手,誰拿到最後一個珍愛幣,誰輸。請問A是否可以必勝?

  • A第一次先取1個,剩下1000個

  • 之後從B第一次取開始計數,保證每輪B+A所取的珍愛幣的數目爲奇數

編程題

1、 輸入一個數n,求比這個數大的最小的一個迴文數 。


2、判斷兩個數組中是否存在相同的數字,兩個已經排好序的數組,寫代碼判斷這兩個數組中是否存在相同的數字?要求時間複雜度越低越好。

//複雜度爲O(n)
public static boolean findColumn2(int[] a,int size_a,int[] b,int size_b){
    int i,j=0;
    while(i<size_a&&j<size_b){
        if(a[i]==b[j])
            return true;
        if(a[i]>b[j])
            j++;
        if(a[i]<b[j])
            i++;
    }
    return false;
}

//複雜度爲O(nlogn),使用了二分法
public static boolean findConlumn(int[] a,int size_a,int[] b,int size_b){
    for(int i=0;i<size_a;i++){
        
        int low=0,high = size_b-1,mid;
        while(low<high){
            mid = low+(high-low)/2;
            if(a[i]==b[mid])
                return true;
            if(a[i]>b[mid])
                low = mid +1;
            if(a[i]<b[mid])
                high = mid -1;
        }
    }
}

3、找出一個字符串中所有迴文子串(長度 >=3,長度爲奇數的),並記錄他的起始位置(暴力)

//中心拓展法
public static ArrayList<String> findAllHuiWen2(String s){
    ArrayList<String> list = new ArrayList<String>();
    if(s==null || s.length()==0) return list;
    if(s.length()==1) {
        list.add(s);
        return list;
    }
    for(int i=0; i<s.length(); i++){
        getSubList(s,i,i,list);
        getSubList(s,i,i+1,list);
    }
    return list;
}

public static void getSubList(String s, int left, int right, ArrayList<String> list){
    while (left>=0 && right<s.length() && s.charAt(left)==s.charAt(right)){
        String subString = s.substring(left, right+1);
        if(!list.contains(subString))
            list.add(subString);
        left--;
        right++;
    }
}

4、尋找最長迴文串

//中心拓展法    

public static String longestPalindrom(String s){

        if(s == null||s.length() == 0) return "";
        int start =0,end=0;
        for(int i = 0;i<s.length();i++){
            int len1 = expandAroundCenter(s,i,i);
            int len2 = expandAroundCenter(s,i,i+1);
            int len = Math.max(len1, len2);
            if(len>end-start){
                start = i-(len-1)/2;
                end = i+len/2;
            }
        }
        return s.substring(start,end+1);
    }

    public static int expandAroundCenter(String s,int left,int right){
        int L = left,R=right;
        while (L>0&&R<s.length()&&s.charAt(L) == s.charAt(R)){
            L--;
            R++;
        }
        //返回迴文串長度
        System.out.println(R-L-1);
        return R-L-1;

    }

4、給一個有序數組和它的大小,給定一個val,求這個數組裏有沒有這個val,有或者有不止一個的話,求第一次出現這個 val 的位置;

//二分法
public class firstBadVersion {
    public static void main(String[] args){
        //查找有序數組是否存在val,並輸出第一次出現的位置
        int[] arr ={1,2,3,3,3,4,4,6,7,8};
        int val = 3;

        System.out.println(firstPresent(arr,val));

    }
    public static int firstPresent(int[] arr,int val){
        int low=0;
        int high = arr.length -1;

        while (low<high){
            int mid = low+(high - low)/2;//寫法說明:反之整數溢出
            if(arr[mid]>=val){
                high = mid-1;
            }
            else{
                low = mid +1;
            }
        }

        return low;
    }
    
}

合併兩個有序鏈表

class Solution{
    public ListNode mergeTwoLists(ListNode l1,ListNode l2){
        if(l1 == null)
            return l2;
        else if(l2 == null){
            return l1;
        }
        else if(l1.val < l2.val){
            l1.next = mergeTwoLists(l1.next,l2);
            return l1;
        }else{
            l2.next = mergeTwoLists(l1,l2.next);
            return l2;
        }
       
    }
}

測試工具

fiddler抓包工具

  • 本質是一個web代理服務器,默認工作端口爲8888。

    • 代理服務器的優勢
      • 共享網絡
      • 提高訪問速度
      • 突破訪問限制
      • 隱藏身份
  • 工作原理

    • 瀏覽器與服務器之間通過建立TCP連接以HTTP協議進行通信,瀏覽器默認通過自己發送HTTP請求到服務器。
    • 而Fiddler是http代理服務器,fiddler工作於七層中的應用層,能夠捕獲到通過的http(s)請求。
    • fiddler啓動後會自動將代理服務器設置爲本機,端口是fiddler監聽端口。監聽的端口號在fiddler 菜單 Tools- TeleriK Fiddler options-connections中可以修改。
  • 代理模式

    • 流模式

      流模式可以理解爲是一種實時通信的模式,有請求就有返回,也就是實時返回!

    • 緩存模式

      等所有請求都到了再 一起返回,也就是等所有數據都準備好之後才返回給客戶端!

測試理論基礎

5種常見的測試用例設計方法

  1. 等價類劃分法
  2. 邊界值分析法
  3. 因果圖法
  4. 場景法
  5. 正交實驗設計法;
  6. 判定表驅動分析法;
  7. 錯誤推測法
  8. 功能圖分析法

https://blog.csdn.net/hongfuqiang/article/details/78840763

白盒測試方法有哪些?

單元測試、集成測試、系統測試、驗收測試、迴歸測試

1、單元測試完成最小的軟件設計單元(模塊)的驗證工作,目標是確保模塊被正確的編碼,使用過程設計描述作爲指南,對重要的控制路徑進行測試以發現模塊內的錯誤,通常情況下是白盒的,對代碼風格和規則、程序設計和結構、業務邏輯等進行靜態測試,及早的發現和解決不易顯現的錯誤。

2、集成測試:通過測試發現與模塊接口有關的問題。目標是把通過了單元測試的模塊拿來,構造一個在設計中所描述的程序結構,應當避免一次性的集成(除非軟件規模很小),而採用增量集成。

自頂向下集成:模塊集成的順序是首先集成主模塊,然後按照控制層次結構向下進行集成,隸屬於主模塊的模塊按照深度優先或廣度優先的方式集成到整個結構中去。

自底向上集成:從原子模塊開始來進行構造和測試,因爲模塊是自底向上集成的,進行時要求所有隸屬於某個給頂層次的模塊總是存在的,也不再有使用穩定測試樁的必要。

3、系統測試:是基於系統整體需求說明書的黑盒類測試,應覆蓋系統所有聯合的部件。系統測試是針對整個產品系統進行的測試,目的是驗證系統是否滿足了需求規格的定義,找出與需求規格不相符合或與之矛盾的地方。系統測試的對象不僅僅包括需要測試的產品系統的軟件,還要包含軟件所依賴的硬件、外設甚至包括某些數據、某些支持軟件及其接口等。因此,必須將系統中的軟件與各種依賴的資源結合起來,在系統實際運行環境下來進行測試。

4、迴歸測試:迴歸測試是指在發生修改之後重新測試先前的測試用例以保證修改的正確性。理論上,軟件產生新版本,都需要進行迴歸測試,驗證以前發現和修復的錯誤是否在新軟件版本上再次出現。根據修復好了的缺陷再重新進行測試。迴歸測試的目的在於驗證以前出現過但已經修復好的缺陷不再重新出現。一般指對某已知修正的缺陷再次圍繞它原來出現時的步驟重新測試。

5、驗收測試:驗收測試是指系統開發生命週期方法論的一個階段,這時相關的用戶或獨立測試人員根據測試計劃和結果對系統進行測試和接收。它讓系統用戶決定是否接收系統。它是一項確定產品是否能夠滿足合同或用戶所規定需求的測試。驗收測試包括Alpha測試和Beta測試。

Alpha測試:是由用戶在開發者的場所來進行的,在一個受控的環境中進行。

Beta測試:由軟件的最終用戶一個或多個用戶場所來進行的,開發者通常不在現場,用戶記錄測試中遇到的問題並報告給開發者,開發者對系統進行最後的修改,並開始準備發佈最終的軟件。

自動化測測試基礎

實施自動化測試的基本步驟

首先,需要已經完成了功能測試,此時測試版本穩定,屬性、功能穩定。
根據項目的特點、選擇合適的自動化測試工具,並搭建測試環境
提取手工測試的測試用例 轉化爲自動化測試用例
通過工具、代碼實現自動化的構造輸入、自動檢測輸出結果是否滿足預期
生成自動測試報告
持續改進、腳本優化

性能測試有哪些指標

性能測試常用指標:

從外部看,主要有

1、吞吐量:每秒鐘系統能夠處理的請求數,任務數

2、響應時間:服務處理一個請求或一個任務的耗時

3、錯誤率:一批請求中結果出錯的請求所佔比例

從服務器的角度看,性能測試關注CPU內存服務器負載網絡磁盤IO

負載均衡

負載均衡,英文名稱爲Load Balance,其含義就是指將負載(工作任務)進行平衡、分攤到多個操作單元上進行運行,例如FTP服務器、Web服務器、企業核心應用服務器和其它主要任務服務器等,從而協同完成工作任務。

負載均衡建立在現有網絡結構之上,它提供了一種廉價有效透明的方法擴展網絡設備服務器的帶寬、增加吞吐量、加強網絡數據處理能力、提高網絡的靈活性和可用性。

分類

  • 軟/硬件負載均衡
  • 本地/全局負載均衡

部署方式

  • 路由模式
  • 橋接模式
  • 服務直接返回模式

測試用例實現

如何測試一個用戶登錄界面?

https://blog.csdn.net/qq_42270373/article/details/95230866

測試用例的設計需要參考需求文檔。

  1. 界面測試
    • 界面佈局是否合理
    • 按鈕的大小是否易於點擊
    • 登錄界面是否美觀,無亂碼,無錯字
  2. 功能測試
    • 用戶名、密碼、驗證碼採用等價類劃分法
    • 用戶名和密碼是否大小寫敏感
    • 輸入密碼是時,大寫開啓是否有提示信息
    • 假如需要發送手機驗證碼,發送驗證碼功能是否正常
    • 多種登錄方式,各種登錄方式是否相互影響
    • 手機驗證碼的時效性是否在規定的時間內
    • 驗證碼刷新功能是否正常
  3. 兼容性測試
    • 主流的瀏覽器下是否顯示正常以及功能正常使用。
  4. 性能測試
    • 打開登錄頁面,需要的時間
    • 單用戶下,服務器處理的時間,登錄成功後跳轉頁面所需的時間。
    • 模擬大量用戶進行操作,服務器的吞吐量,錯誤率等是否正常。
    • 網絡延遲。弱網環境下,丟包率的問題。
    • App類的需要增加,耗電問題、流量問題、消耗內存問題。
  5. 安全性測試
    • 輸入的密碼是否可以隱藏,隱藏按鈕的切換是否正常。
    • 用戶名、密碼是否支持複製粘貼。
    • 用戶名和密碼是否通過加密的方式,發送給web服務器。
    • 錯誤登錄次數限制
    • 單用戶在多臺機器登錄
    • 多用戶在單臺機器登錄
    • 防止sql注入攻擊
    • 防止xss跨站腳本攻擊。
    • 根據不同的產品需求,驗證其安全性
  6. 易用性測試
  7. 本地化測試

測試刪除文件功能

  • 刪除前確認

  • 文件刪除成功/失敗,應該有相應的提示信息

  • 不選擇文件,點擊刪除按鈕,出現相應的提示信息

  • 刪除過程中,點擊取消按鈕,驗證取消是否成功

  • 成功刪除之後,是否可以撤銷刪除

  • 刪除文件,一定要對刪除權限和身份驗證

  • 文件刪除之後,是放入回收站還是徹底刪除

  • 若存在批量刪除,測試文件是否能夠被成功刪除

  • 測試批量刪除的性能

  • 模擬大量用戶進行批量刪除,檢查系統的穩定性

  • 對不允許存在的文件進行刪除,提示相應的信息

  • 文件刪除的過程中,網絡中斷,看是否能夠成功刪除

  • 是否有刪除日誌

  • 文件打開/文件正在複製,給出相應的提示信息

一瓶水怎麼進行測試

給你一個杯子,要測試哪些屬性

  1. 界面測試
    • 外觀整齊美觀,沒有瑕疵
    • 圖案是否合法
    • 圖案是否容易掉落
  2. 功能測試
    • 有沒有漏水
    • 燙手驗證
    • 杯子的容量刻度是否正確
    • 蓋子擰緊,倒過來,沒有水漏出
    • 裝有色飲料時,杯子是否會被染色,放置多久會被染色,染色之後是否能夠清洗乾淨。
  3. 性能測試
    • 可使用最大的次數
    • 掉在地上不容易損壞
    • 杯子的耐熱性、耐寒性測試
    • 長時間放置不會漏水
    • 杯子刻度,以及圖案、文字不會受到溫度,溼度的影響。
  4. 安全測試
    • 杯子材質是否安全
    • 高溫或低溫材質釋放毒性
    • 防滑測試
  5. 兼容性測試
    • 杯子能夠容納果汁、白水、酒精等。

微信發紅包

https://blog.csdn.net/qq_40891477/article/details/94395634

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5JZfwV3R-1585126522560)(C:\Users\zhangboyi\AppData\Roaming\Typora\typora-user-images\1585067861661.png)]

微信支付

img

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章