數據庫、計算機網絡常見面試題整理

I 數據庫篇

數據庫的數據結構

B樹

B樹也稱B-樹,它是一顆多路平衡查找樹。我們描述一顆B樹時需要指定它的階數,階數表示了一個結點最多有多少個孩子結點,一般用字母m表示階數。當m取2時,就是我們常見的二叉搜索樹。

4階B樹
上圖:一棵4階B樹。

一顆m階的B樹定義如下:

1)每個結點最多有m-1個關鍵字。

2)根結點最少可以只有1個關鍵字。

3)非根結點至少有Math.ceil(m/2)-1個關鍵字。

4)每個結點中的關鍵字都按照從小到大的順序排列,每個關鍵字的左子樹中的所有關鍵字都小於它,而右子樹中的所有關鍵字都大於它。

5)所有葉子結點都位於同一層,或者說根結點到每個葉子結點的長度都相同。

B+樹

B+樹
各種資料上B+樹的定義各有不同,一種定義方式是關鍵字個數和孩子結點個數相同。這裏我們採取維基百科上所定義的方式,即關鍵字個數比孩子結點個數小1,這種方式是和B樹基本等價的。上圖就是一顆階數爲4的B+樹。

除此之外B+樹還有以下的要求。

1)B+樹包含2種類型的結點:內部結點(也稱索引結點)和葉子結點。根結點本身即可以是內部結點,也可以是葉子結點。根結點的關鍵字個數最少可以只有1個。

2)B+樹與B樹最大的不同是內部結點不保存數據,只用於索引,所有數據(或者說記錄)都保存在葉子結點中。

3) m階B+樹表示了內部結點最多有m-1個關鍵字(或者說內部結點最多有m個子樹),階數m同時限制了葉子結點最多存儲m-1個記錄。

4)內部結點中的key都按照從小到大的順序排列,對於內部結點中的一個key,左樹中的所有key都小於它,右子樹中的key都大於等於它。葉子結點中的記錄也按照key的大小排列。

5)每個葉子結點都存有相鄰葉子結點的指針,葉子結點本身依關鍵字的大小自小而大順序鏈接。

B樹、B+樹插入、刪除

B樹、B+樹對比

爲什麼說B+tree比B 樹更適合實際應用中操作系統的文件索引和數據庫索引?

  • 主要原因:B+樹只要遍歷葉子節點就可以實現整棵樹的遍歷,而且在數據庫中基於範圍的查詢是非常頻繁的,而B樹只能中序遍歷所有節點,效率太低。

  • B+tree的磁盤讀寫代價更低
    B+tree的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B 樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。
    舉個例子,假設磁盤中的一個盤塊容納16bytes,而一個關鍵字2bytes,一個關鍵字具體信息指針2bytes。一棵9階B-tree(一個結點最多8個關鍵字)的內部結點需要2個盤快。而B+樹內部結點只需要1個盤快。當需要把內部結點讀入內存中的時候,B 樹就比B+樹多一次盤塊查找時間(在磁盤中就是盤片旋轉的時間)。

  • B+tree的查詢效率更加穩定
    由於內部結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引,所以,任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當;



數據庫索引

索引(Index)是幫助MySQL高效獲取數據的數據結構
索引的目的:提高查詢效率
原理:通過不斷的縮小想要獲得數據的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是我們總是通過同一種查找方式來鎖定數據。

什麼情況下設置了索引但無法使用?

  • 以“%(表示任意0個或多個字符)”開頭的LIKE語句,模糊匹配;

  • OR語句前後沒有同時使用索引;

  • 數據類型出現隱式轉化(如varchar不加單引號的話可能會自動轉換爲int型);

  • 對於多列索引,必須滿足最左匹配原則 (eg:多列索引col1、col2和col3,則 索引生效的情形包括 col1或col1,col2或col1,col2,col3)。

什麼樣的字段適合創建索引?

  • 唯一索引
  • 經常作查詢選擇的字段
  • 經常作表連接的字段
  • 經常出現在order by, group by, distinct 後面的字段

創建索引時需要注意什麼?

  • 非空字段
  • 取值離散大的字段
  • 索引字段越小越好:數據庫的數據存儲以頁爲單位,字段小,索引節點就小,一頁存儲的數據越多,一次IO操作獲取的數據越大效率越高。

索引的分類

  • 普通索引和唯一性索引:索引列的值的唯一性

  • 單個索引和複合索引:索引列所包含的列數

  • 順序索引和散列索引
    順序索引:基於值的順序排序
    散列索引:基於哈希函數,把值平均分佈到若干散列桶

  • 稠密索引和稀疏索引
    稠密索引:搜索碼的每個值都有對應索引項
    稀疏索引:只有搜索碼的某些值有索引。只有索引是聚集索引時才能使用稀疏索引。

  • 聚簇索引/主索引與非聚簇索引/輔助索引
    聚簇索引是對磁盤上實際數據重新組織以按指定的一個或多個列的值排序的算法。特點是存儲數據的順序和索引順序一致。一般情況下主鍵會默認創建聚簇索引,且一張表只允許存在一個聚簇索引
    非聚集索引的邏輯順序與磁盤上行的物理存儲順序不同

聚簇索引的葉子節點就是數據節點,而非聚簇索引的葉子節點仍然是索引節點,只不過有指向對應數據塊的指針。聚集索引可以幫助把很大的範圍,迅速減小範圍。但是查找該記錄,就要從這個小範圍中Scan了;而非聚集索引是把一個很大的範圍,轉換成一個小的地圖,然後你需要在這個小地圖中找你要尋找的信息的位置,最後通過這個位置,再去找你所需要的記錄。

唯一索引 vs 主鍵

唯一索引 主鍵
唯一索引:索引列的值必須唯一,但允許有空值。主鍵是唯一索引,這樣說沒錯;但反過來說,唯一索引也是主鍵就錯誤了,因爲唯一索引允許空值,主鍵不允許有空值,所以不能說唯一索引也是主鍵。



數據庫引擎

就是將數據存儲到磁盤的接口~MySQL有SQL語句分析層和存儲引擎層,當分析出SQL語句需要執行什麼操作後,調用存儲引擎的接口既可。
DB Engine

MyISAM:非聚集索引

MyISAM引擎使用B+Tree作爲索引結構,MyISAM的索引文件僅僅保存數據記錄的地址

MyISAM中索引檢索的算法爲首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然後以data域的值爲地址,讀取相應數據記錄。

InnoDB:聚集索引

InnoDB是默認的MySQL引擎。雖然InnoDB也使用B+Tree作爲索引結構,但具體實現方式卻與MyISAM截然不同。

  • 第一個重大區別是InnoDB的數據文件本身就是索引文件
    MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。而在InnoDB中,表數據文件本身就是按B+Tree組織的一個索 引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB 表數據文件本身就是主索引
  • 第二個與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址
    首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。

具有事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全
(transaction-safe (ACID compliant))型表

InnoDB vs MyISAM

InnoDB vs MyISAM
區別:

  1. InnoDB 支持事務,MyISAM 不支持事務。這是 MySQL 將默認存儲引擎從 MyISAM 變成 InnoDB 的重要原因之一;
  2. InnoDB 支持外鍵,而 MyISAM 不支持。對一個包含外鍵的 InnoDB 錶轉爲 MYISAM 會失敗;
  3. InnoDB 是聚集索引,MyISAM 是非聚集索引。聚簇索引的文件存放在主鍵索引的葉子節點上,因此 InnoDB 必須要有主鍵,通過主鍵索引效率很高。但是輔助索引需要兩次查詢,先查詢到主鍵,然後再通過主鍵查詢到數據。因此,主鍵不應該過大,因爲主鍵太大,其他索引也都會很大。而 MyISAM 是非聚集索引,數據文件是分離的,索引保存的是數據文件的指針。主鍵索引和輔助索引是獨立的。
  4. InnoDB 不保存表的具體行數,執行 select count(*) from table 時需要全表掃描。而MyISAM 用一個變量保存了整個表的行數,執行上述語句時只需要讀出該變量即可,速度很快;
  5. InnoDB 最小的鎖粒度是行鎖,MyISAM 最小的鎖粒度是表鎖。一個更新語句會鎖住整張表,導致其他查詢和更新都會被阻塞,因此併發訪問受限。這也是 MySQL 將默認存儲引擎從 MyISAM 變成 InnoDB 的重要原因之一;

如何選擇:

  1. 是否要支持事務,如果要請選擇 InnoDB,如果不需要可以考慮 MyISAM;
  2. 如果表中絕大多數都只是讀查詢,可以考慮 MyISAM,如果既有讀寫也挺頻繁,請使用InnoDB。
  3. 系統奔潰後,MyISAM恢復起來更困難,能否接受,不能接受就選 InnoDB;
  4. MySQL5.5版本開始Innodb已經成爲Mysql的默認引擎(之前是MyISAM),說明其優勢是有目共睹的。如果你不知道用什麼存儲引擎,那就用InnoDB,至少不會差。

MEMORY存儲引擎

MEMORY存儲引擎將表中的數據存儲到內存中,未查詢和引用其他表數據提供快速訪問。

Archive

從archive單詞的解釋我們大概可以明白這個存儲引擎的用途,這個存儲引擎基本上用於數據歸檔;它的壓縮比非常的高,存儲空間大概是innodb的10-15分之一所以它用來存儲歷史數據非常的適合,由於它不支持索引同時也不能緩存索引和數據,所以它不適合作爲併發訪問表的存儲引擎。Archivec存儲引擎使用行鎖來實現高併發插入操作,但是它不支持事務,其設計目標只是提供高速的插入和壓縮功能。
由於高壓縮和快速插入的特點Archive非常適合作爲日誌表的存儲引擎,但是前提是不經常對該表進行查詢操作。

InnoDB :如果要提供提交、回滾、崩潰恢復能力的事務安全(ACID兼容)能力,並要求實現併發控制,InnoDB是一個好的選擇

InnoDB 和 MyISAM之間的區別:
1>.InnoDB支持事物,而MyISAM不支持事物

2>.InnoDB支持行級鎖,而MyISAM支持表級鎖

3>.InnoDB支持MVCC, 而MyISAM不支持

4>.InnoDB支持外鍵,而MyISAM不支持

5>.InnoDB不支持全文索引,而MyISAM支持。

如果要提供提交、回滾、崩潰恢復能力的事物安全(ACID兼容)能力,並要求實現併發控制,InnoDB是一個好的選擇

如果數據表主要用來插入和查詢記錄,則MyISAM引擎能提供較高的處理效率
MyISAM表太適合於有大量更新操作和查詢操作應用

如果只是臨時存放數據,數據量不大,並且不需要較高的數據安全性,可以選擇將數據保存在內存中的Memory引擎,MySQL中使用該引擎作爲臨時表,存放查詢的中間結果

如果只有INSERT和SELECT操作,可以選擇Archive,Archive支持高併發的插入操作,但是本身不是事務安全的。Archive非常適合存儲歸檔數據,如記錄日誌信息可以使用Archive

數據庫ER圖

ER圖分爲實體、屬性、關係三個核心部分。實體是長方形體現,而屬性則是橢圓形,關係爲菱形。

ER圖的實體(entity)即數據模型中的數據對象,例如人、學生、音樂都可以作爲一個數據對象,用長方體來表示,每個實體都有自己的實體成員(entity member)或者說實體對象(entity instance),例如學生實體裏包括張三、李四等,實體成員(entity member)/實體實例(entity instance) 不需要出現在ER圖中。

ER圖的屬性(attribute)即數據對象所具有的屬性,例如學生具有姓名、學號、年級等屬性,用橢圓形表示,屬性分爲唯一屬性( unique attribute)和非唯一屬性,唯一屬性指的是唯一可用來標識該實體實例或者成員的屬性,用下劃線表示,一般來講實體都至少有一個唯一屬性。

ER圖的關係(relationship)用來表現數據對象與數據對象之間的聯繫,例如學生的實體和成績表的實體之間有一定的聯繫,每個學生都有自己的成績表,這就是一種關係,關係用菱形來表示。

弱實體:一個實體必須依賴於另一個實體存在,那麼前者是弱實體,後者是強實體,弱實體必須依賴強實體存在,例如上圖的學生實體和成績單實體,成績單依賴於學生實體而存在,因此學生是強實體,而成績單是弱實體。
弱實體是完全參與聯繫的,因此弱實體與強實體之間的聯繫也是用的雙線菱形

複合實體:複合實體也稱聯合實體或橋接實體,常常用於實現兩個或多個實體間的M:N聯繫,它由每個關聯實體的主瑪組成,用長方體內加一個菱形來表示。

複合屬性(composite attribute):複合屬性是指具有多個屬性的組合

派生屬性(derivers attribute):是非永久性存於數據庫的屬性。派生屬性的值可以從別的屬性值或其他數據(如當前日期)派生出來,用虛線橢圓表示,如下圖。

可選屬性(optional attribute):並不是所有的屬性都必須有值,有些屬性的可以沒有值,這就是可選屬性,在橢圓的文字後用(O)來表示,如下圖的地址就是一個可選屬性。

聯繫屬性:聯繫屬於用戶表示多個實體之間聯繫所具有的屬性,一般來講M:N的兩個實體的聯繫具有聯繫屬性,在1:1和1:M的實體聯繫中聯繫屬性並不必要。

事務(4性質)

數據庫系統概念P356

數據庫事務的四個基本性質(ACID)

  1. 原子性(Atomicity)
    事務的原子性是指事務中包含的所有操作要麼全做,要麼全不做(all or none)。

  2. 一致性(Consistency)
    在事務開始以前,數據庫處於一致性的狀態,事務結束後,數據庫也必須處於一致性狀態。
    拿銀行轉賬來說,一致性要求事務的執行不應改變A、B 兩個賬戶的金額總和。如果沒有這種一致性要求,轉賬過程中就會發生錢無中生有,或者不翼而飛的現象。事務應該把數據庫從一個一致性狀態轉換到另外一個一致性狀態。

  3. 隔離性(Isolation)
    事務隔離性要求系統必須保證事務不受其他併發執行的事務的影響,也即要達到這樣一種效果:對於任何一對事務T1 和 T2,在事務 T1 看來,T2 要麼在 T1 開始之前已經結束,要麼在 T1 完成之後纔開始執行。這樣,每個事務都感覺不到系統中有其他事務在併發地執行。

  4. 持久性(Durability)
    一個事務一旦成功完成,它對數據庫的改變必須是永久的,即便是在系統遇到故障的情況下也不會丟失。數據的重要性決定了事務持久性的重要性。

非關係數據庫

非關係型數據庫提出另一種理念,例如,以鍵值對存儲,且結構不固定,每一個元組可以有不一樣的字段,每個元組可以根據需要增加一些自己的鍵值對,這樣就不會侷限於固定的結構,可以減少一些時間和空間的開銷。使用這種方式,用戶可以根據需要去添加自己需要的字段,這樣,爲了獲取用戶的不同信息,不需要像關係型數據庫中,要對多表進行關聯查詢。僅需要根據id取出相應的value就可以完成查詢。但非關係型數據庫由於很少的約束,他也不能夠提供像SQL所提供的where這種對於字段屬性值情況的查詢。並且難以體現設計的完整性。他只適合存儲一些較爲簡單的數據,對於需要進行較複雜查詢的數據,SQL數據庫顯的更爲合適。
不使用SQL語言

主要分爲以下幾類:
1).面向高性能併發讀寫的key-value數據庫:key-value數據庫的主要特點即使具有極高的併發讀寫性能Redis,Tokyo Cabinet,Flare就是這類的代表
Key-value數據庫是一種以鍵值對存儲數據的一種數據庫,類似java中的map。可以將整個數據庫理解爲一個大的map,每個鍵都會對應一個唯一的值。Key-value數據庫代表的有redis。Redis是一個Key-Value存儲系統。
2).面向海量數據訪問的面向文檔數據庫:這類數據庫的特點是,可以在海量的數據中快速的查詢數據,典型代表爲MongoDB以及CouchDB
3).面向可擴展性的分佈式數據庫:這類數據庫想解決的問題就是傳統數據庫存在可擴展性上的缺陷,這類數據庫可以適應數據量的增加以及數據結構的變化

Mysql主從複製/主備模式

MySQL主從複製是其最重要的功能之一。主從複製是指一臺服務器充當主數據庫服務器,另一臺或多臺服務器充當從數據庫服務器,主服務器中的數據自動複製到從服務器之中。對於多級複製,數據庫服務器即可充當主機,也可充當從機。MySQL主從複製的基礎是主服務器對數據庫修改記錄二進制日誌,從服務器通過主服務器的二進制日誌自動執行更新。

悲觀鎖和樂觀鎖的實現

悲觀鎖的實現:select … for update
樂觀鎖的實現:更新時的條件加入需要更新的列

數據庫的範式

1NF: 屬性不可再分
2NF: 非主鍵屬性,完全依賴於主鍵屬性
3NF:非主鍵屬性無傳遞依賴
數據庫系統概念P184

Redis

什麼是Redis內存數據庫?

Redis,本質上上一個KEY-VALUE類型的內存數據庫,整個數據庫都加載在內存當中進行操作,定期通過異步操作把數據庫數據flush到硬盤上進行保存。因此它是純內存操作,Redis的性能非常出色,每秒可以處理超過10萬次讀寫操作。雖然是內存數據庫,但是其數據可以持久化,而且支持豐富的數據類型。

Redis支持保存LIST列表和SET集合的數據結構,而且還支持對LIST進行各種操作,例如從LIST兩端進行PUSH和POP數據,取LIST區間,排序等等。對SET支持各種集合的並集交集操作,單個value的最大限制是1GB。

Redis主要的缺點是受到物理內存限制,不能用作海量數據的高性能讀寫,而且它沒有原生的可擴展機制,不具有擴展能力,要依賴客戶端來實現分佈式讀寫,因此其適合的應用場景主要侷限在較小數據量的高性能操作和運算上。

最佳應用場景:適用於數據變化快數據庫大小可預見(內存大小)的應用程序。

例如:股票軟件、數據分析、實時數據收集、實時通訊。

Redis屬於NoSQL範疇內,其含義爲:Not only SQL,是不僅僅是SQL,是一項新的技術,隨着WEB 2. 0的到來而得到廣泛應用。理念是運用非關係的數據存儲。

鍵值類型的數據庫主要使用哈希表,這個表中有一個特定的鍵和一個指針指向特定數據。KEY/VALUE模型對於IT系統來說的優勢在於簡單、容易部署。主要特點是具有極高的併發讀寫性能

Redis持久化 snapshot(rdb)/aof

Redis的所有數據都保存在內存中,然後不定期的通過異步方式保存到磁盤上(這稱爲半持久化);也可以把每一次數據變化都寫入到磁盤(這稱爲全持久化)。所謂持久化就是將內存數據轉換爲硬盤數據,內存模型到存儲模型的轉換,或者說是瞬時狀態與持久狀態的相互轉換

Redis有兩種持久化方式,默認是snapshot方式,實現方法是定時將內存的快照持久化到硬盤,這種方式的缺點是持久化之後如果出現crash則會丟失一段數據。另外一種是aof方式,在寫入內存數據的同時將操作命令保存到日誌文件中。

AOF方式的優點:

  • 丟失數據最小

AOF方式的缺點:

  • 同等數據量,AOF文件比RDB文件體積大
  • AOF恢復速度比RDB方式慢

Redis及底層實現

Redis支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

B樹、B+樹、B*樹

B樹的性質(m階的B樹)

  • 樹中每個結點最多含有m個孩子(m>=2);
  • 除根結點和葉子結點外,其它每個結點至少有[ceil(m / 2)]個孩子(其中ceil(x)是一個取上限的函數);
  • 根結點至少有2個孩子(除非B樹只包含一個結點:根結點);
  • 所有葉子結點都出現在同一層,葉子結點不包含任何關鍵字信息(可以看做是外部結點或查詢失敗的結點,指向這些結點的指針都爲null);(注:葉子節點只是沒有孩子和指向孩子的指針,這些節點也存在,也有元素。類似紅黑樹中,每一個NULL指針即當做葉子結點,只是沒畫出來而已)。
  • 每個非終端結點中包含有n個關鍵字信息: (n,P0,K1,P1,K2,P2,…,Kn,Pn)。其中:
    a) Ki (i=1…n)爲關鍵字,且關鍵字按順序升序排序K(i-1)< Ki。
    b) Pi爲指向子樹根的結點,且指針P(i-1)指向子樹種所有結點的關鍵字均小於Ki,但都大於K(i-1)。
    c) 關鍵字的個數n必須滿足: [ceil(m / 2)-1]<= n <= m-1。比如有j個孩子的非葉結點恰好有j-1個關鍵碼。

B+樹

B樹的一種變形樹,m階的B+樹和m階的B樹區別:

  • 所有葉子節點包含全部關鍵字信息,及指向含有這些關鍵字記錄的指針,且葉子節點中關鍵字進行有序鏈接
  • 非葉子結點相當於是葉子結點的索引(稀疏索引),葉子結點相當於是存儲(關鍵字)數據的數據層;

B*樹

B*樹是B+樹的變體,在B+樹的非根和非葉子結點再增加指向兄弟的指針

II 計算機網絡篇

網絡OSI七層模型

TCP IP 四層模型

在這裏插入圖片描述
1、主機到網絡層  
  實際上TCP/IP參考模型沒有真正描述這一層的實現,只是要求能夠提供給其上層-網絡互連層一個訪問接口,以便在其上傳遞IP分組。由於這一層次未被定義,所以其具體的實現方法將隨着網絡類型的不同而不同。  
  2、網絡互連層  
  網絡互連層是整個TCP/IP協議棧的核心。它的功能是把分組發往目標網絡或主機。同時,爲了儘快地發送分組,可能需要沿不同的路徑同時進行分組傳遞。因此,分組到達的順序和發送的順序可能不同,這就需要上層必須對分組進行排序。  
  網絡互連層定義了分組格式和協議,即IP協議(Internet Protocol)。  
  網絡互連層除了需要完成路由的功能外,也可以完成將不同類型的網絡(異構網)互連的任務。除此之外,網絡互連層還需要完成擁塞控制的功能。  
  3、傳輸層  
  在TCP/IP模型中,傳輸層的功能是使源端主機和目標端主機上的對等實體可以進行會話。在傳輸層定義了兩種服務質量不同的協議。即:傳輸控制協議TCP(transmission control protocol)和用戶數據報協議UDP(user datagram protocol)。  
  TCP協議是一個面向連接的、可靠的協議。它將一臺主機發出的字節流無差錯地發往互聯網上的其他主機。在發送端,它負責把上層傳送下來的字節流分成報文段並傳遞給下層。在接收端,它負責把收到的報文進行重組後遞交給上層。TCP協議還要處理端到端的流量控制,以避免緩慢接收的接收方沒有足夠的緩衝區接收發送方發送的大量數據。  
  UDP協議是一個不可靠的、無連接協議,主要適用於不需要對報文進行排序和流量控制的場合。  
  4、應用層  
  TCP/IP模型將OSI參考模型中的會話層和表示層的功能合併到應用層實現。  
  應用層面向不同的網絡應用引入了不同的應用層協議。其中,有基於TCP協議的,如文件傳輸協議(File Transfer Protocol,FTP)、虛擬終端協議(TELNET)、超文本鏈接協議(Hyper Text Transfer Protocol,HTTP),也有基於UDP協議的。

TCP/UDP

  • TCP連接點對點,UDP支持1對1,1對多,多對一,多對多
  • 擁塞控制(慢啓動,擁塞避免模式)
  • 滑動窗口
  • 傳輸可靠程度

TCP爲什麼不能兩次握手?

因爲網絡不穩定,之前可能網絡中會有很多失效的連接請求報文,如果沒有A再次確認的過程,那麼如果有些失效報文又被重新受到,那麼會影響當前的連接,因此是三次。這個時候,連接建立了,A與B可以相互通信。

滑動窗口協議 課本P145

TCP擁塞控制 P176

進程通信和線程通信的區別

線程間通信:由於多線程共享地址空間和數據空間,所以多個線程間的通信是一個線程的數據可以直接提供給其他線程使用,而不必通過操作系統(也就是內核的調度)

進程間的通信則不同,它的數據空間的獨立性決定了它的通信相對比較複雜,需要通過操作系統

TCP server最多可以建立多少個TCP連接?

“因爲TCP端口號是16位無符號整數, 最大65535, 所以一臺服務器最多支持65536個TCP socket連接.” - 一個非常經典的誤解!
系統通過一個四元組來唯一標識一條TCP連接. 這個四元組的結構是{local_ip, local_port, remote_ip, remote_port},

TCP客戶端(TCP的主動發起者)可以在同一ip:port上向不同的服務器發起主動連接, 只需在bind之前對socket設置SO_REUSEADDR選項.

如果某個客戶端向同一個TCP端點(ip:port)發起主動連接, 那麼每一條連接都必須使用不同的本地TCP端點, 如果客戶端只有一個IP則是使用不同的本地端口, 該端口的範圍在*nix系統上的一個例子是32768到61000, 可以通過如下命令查看:

[[email protected] ~]# cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
也就是說, 一個客戶端連接同一個服務器的同一個ip:port(比如進行壓力測試), 最多可以發起30000個左右的連接.

  • 結論:無論是對於服務器還是客戶端, 認爲"一臺機器最多建立65536個TCP連接"是沒有根據的, 理論上遠遠超過這個值.

Ddos

分佈式拒絕服務。一般來說是指攻擊者利用“肉雞”對目標網站在較短的時間內發起大量請求,大規模消耗目標網站的主機資源,讓它無法正常服務。在線遊戲、互聯網金融等領域是 DDoS 攻擊的高發行業。

如何應對 DDoS 攻擊?

  • 高防服務器
    高防服務器主要是指能獨立硬防禦 50Gbps 以上的服務器,能夠幫助網站拒絕服務攻擊,定期掃描網絡主節點等,這東西是不錯,就是貴~
  • 黑名單
    設置黑名單,此方法秉承的就是“錯殺一千,也不放一百”的原則,會封鎖正常流量,影響到正常業務。
  • DDoS 清洗
    DDoS 清洗會對用戶請求數據進行實時監控,及時發現DOS攻擊等異常流量,在不影響正常業務開展的情況下清洗掉這些異常流量。
  • CDN 加速
    在現實中,CDN 服務將網站訪問流量分配到了各個節點中,這樣一方面隱藏網站的真實 IP,另一方面即使遭遇 DDoS 攻擊,也可以將流量分散到各個節點中,防止源站崩潰。

TCP可靠傳輸

TCP爲了提供可靠傳輸:

(1)首先,採用三次握手來建立TCP連接,四次握手來釋放TCP連接,從而保證建立的傳輸信道是可靠的。
(2)其次,TCP採用了連續ARQ協議(回退N,Go-back-N;超時自動重傳)來保證數據傳輸的正確性,使用滑動窗口協議來保證接方能夠及時處理所接收到的數據,進行流量控制。(課本P145)
(3)擁塞控制:發送速率和讀取速率匹配,避免溢出
(4)超時重傳
(5)快速重傳,冗餘ACK (自頂向下P162)

HTTP狀態碼

200 OK:請求被正常處理
204:請求被受理但沒有資源可以返回
206:客戶端只是請求資源的一部分,服務器只對請求的部分資源執行GET方法,相應報文中通過Content-Range指定範圍的資源。
301 Moved Permanently:永久性重定向
302:臨時重定向
303:與302狀態碼有相似功能,只是它希望客戶端在請求一個URI的時候,能通過GET方法重定向到另一個URI上
304:發送附帶條件的請求時,條件不滿足時返回,與重定向無關
307:臨時重定向,與302類似,只是強制要求使用POST方法
400 Bad Request:請求報文語法有誤,服務器無法識別
401:請求需要認證
403:請求的對應資源禁止被訪問
404:服務器無法找到對應資源
500 Internal Server Error:服務器內部錯誤
503:服務器正忙

HTTP請求

1 GET 請求指定的頁面信息,並返回實體主體。
2 HEAD 類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭
3 POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改
4 PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。
5 DELETE 請求服務器刪除指定的頁面
6 CONNECT HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。
7 OPTIONS 允許客戶端查看服務器的性能
8 TRACE 回顯服務器收到的請求,主要用於測試或診斷。

IPTables

iptables通常被用作類UNIX系統中的防火牆,更準確的說,可以稱爲iptables/netfilter。管理員通過終端/GUI工具與iptables打交道,來添加和定義防火牆規則到預定義的表中。Netfilter是內核中的一個模塊,它執行包過濾的任務。

四次揮手的timewait爲什麼存在?

在tcp四次揮手中, B發FIN包(第三次揮手)後, A馬上回應最後的ACK, 此時, A的socket讓然不能立即進入CLOSED的狀態, 爲什麼呢? 其實這就是在問TIME_WAIT狀態存在的理由。

理由之一:A不能保證最後的ACK能達到B

假設tcp連接是: A(1.2.3.4:8888)------B(6.7.8.9:9999), 這就是一個tcp四元組。 當tcp連接關閉後, 四元組釋放。 後面的新連接可能會重用到這個四元組(有這個可能性), 那麼問題就來了: 新四元組和舊四元組完全一致, 他們的網絡包會混亂嗎? 所以, TIME_WAIT存在的理由之二是新舊四元組互不干擾

GET方法與POST方法的區別

區別一:
get重點在從服務器上獲取資源,post重點在向服務器發送數據;

區別二:
get傳輸數據是通過URL請求,以field(字段)= value的形式,置於URL後,並用"?“連接,多個請求數據間用”&"連接,如http://127.0.0.1/Test/login.action?name=admin&password=admin,這個過程用戶是可見的
post傳輸數據通過Http的post機制,將字段與對應值封存在請求實體中發送給服務器,這個過程對用戶是不可見的;

區別三:
Get傳輸的數據量小,因爲受URL長度限制,但效率較高;
Post可以傳輸大量數據,所以上傳文件時只能用Post方式;

區別四:
get是不安全的,因爲URL是可見的,可能會泄露私密信息,如密碼等;
post較get安全性較高;

區別五:
get方式只能支持ASCII字符,向服務器傳的中文字符可能會亂碼。
post支持標準字符集,可以正確傳遞中文字符。

POST和PUT的區別

在HTTP中,PUT被定義爲idempotent的方法,POST則不是,這是一個很重要的區別。

“Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.”

上面的話就是說,如果一個方法重複執行多次,產生的效果是一樣的,那就是idempotent的。

舉一個簡單的例子,假如有一個博客系統提供一個Web API,模式是這樣http://superblogging/blogs/post/{blog-name},很簡單,將{blog-name}替換爲我們的blog名字,往這個URI發送一個HTTP PUT或者POST請求,HTTP的body部分就是博文,這是一個很簡單的REST API例子。我們應該用PUT方法還是POST方法?取決於這個REST服務的行爲是否是idempotent的,假如我們發送兩個http://superblogging/blogs/post/Sample請求,服務器端是什麼樣的行爲?如果產生了兩個博客帖子,那就說明這個服務不是idempotent的,因爲多次使用產生了副作用了嘛;如果後一個請求把第一個請求覆蓋掉了,那這個服務就是idempotent的。前一種情況,應該使用POST方法,後一種情況,應該使用PUT方法。

URL/URI/URN

URI:Uniform Resource Identifier,統一資源標識符
URL:Uniform Resource Location統一資源定位符
它們有什麼關係
URI是一個用於標識互聯網資源名稱的字符串。 該種標識允許用戶對網絡中(一般指萬維網)的資源通過特定的協議進行交互操作。URI的最常見的形式是統一資源定位符(URL),經常指定爲非正式的網址。更罕見的用法是統一資源名稱(URN),其目的是通過提供一種途徑。用於在特定的命名空間資源的標識,以補充網址。
通俗地說,URL和URN是URI的子集,URI屬於URL更高層次的抽象,一種字符串文本標準。
三者關係如下圖:

URI,是統一資源標識符,用來唯一的標識一個資源。而URL是統一資源定位器,它是一種具體的URI,即URL可以用來標識一個資源,而且還指明瞭如何locate這個資源。而URN,統一資源命名,是通過名字來標識資源,比如mailto:[email protected]

HTTPS加密

  • HTTPS加密:對稱加密、非對稱加密
    – 客戶端和服務端建立 SSL 握手,客戶端通過 CA 證書來確認服務端的身份;
    – 互相傳遞三個隨機數,之後通過這隨機數來生成一個密鑰;
    – 互相確認密鑰,然後握手結束;
    – 數據通訊開始,都使用同一個對話密鑰來加解密;
  • 驗證碼,防止批量註冊
  • salt
  • 公鑰私鑰

Http與Https的區別:

HTTP 的URL 以http:// 開頭,而HTTPS 的URL 以https:// 開頭
HTTP 是不安全的,而 HTTPS 是安全的
HTTP 標準端口是80 ,而 HTTPS 的標準端口是443
在OSI 網絡模型中,HTTP工作於應用層,而HTTPS 的安全傳輸機制工作在傳輸層
HTTP 無法加密,而HTTPS 對傳輸的數據進行加密
HTTP無需證書,而HTTPS 需要CA機構wosign的頒發的SSL證書

SSL協議加密過程

  • 第一步:愛麗絲給出支持SSL協議版本號,一個客戶端隨機數(Client random,請注意這是第一個隨機數),客戶端支持的加密方法等信息;
  • 第二步:鮑勃收到信息後,確認雙方使用的加密方法,並返回數字證書,一個服務器生成的隨機數(Server random,注意這是第二個隨機數)等信息;
  • 第三步:愛麗絲確認數字證書的有效性,然後生成一個新的隨機數(Premaster secret),然後使用數字證書中的公鑰,加密這個隨機數,發給鮑勃。
  • 第四步:鮑勃使用自己的私鑰,獲取愛麗絲髮來的隨機數(即Premaster secret);(第三、四步就是非對稱加密的過程了)
  • 第五步:愛麗絲和鮑勃通過約定的加密方法(通常是AES算法),使用前面三個隨機數,生成對話密鑰,用來加密接下來的通信內容;

上傳圖片

HTTP POST請求
Fiddler: 監控HTTP請求

在瀏覽器中輸入網址之後執行會發生什麼?

  • 查找域名對應的IP地址。這一步會依次查找瀏覽器緩存,系統緩存,路由器緩存,ISPNDS緩存,根域名服務器
  • 瀏覽器向IP對應的web服務器發送一個HTTP請求
  • 服務器響應請求,發回網頁內容
  • 瀏覽器解析網頁內容

ARP

ARP是地址解析協議,簡單語言解釋一下工作原理。
1:首先,每個主機都會在自己的ARP緩衝區中建立一個ARP列表,以表示IP地址和MAC地址之間的對應關係。
2:當源主機要發送數據時,首先檢查ARP列表中是否有對應IP地址的目的主機的MAC地址,如果有,則直接發送數據,如果沒有,就向本網段的所有主機發送ARP數據包,該數據包包括的內容有:源主機 IP地址,源主機MAC地址,目的主機的IP 地址
3:當本網絡的所有主機收到該ARP數據包時,首先檢查數據包中的IP地址是否是自己的IP地址,如果不是,則忽略該數據包,如果是,則首先從數據包中取出源主機的IP和MAC地址寫入到ARP列表中,如果已經存在,則覆蓋,然後將自己的MAC地址寫入ARP響應包中,告訴源主機自己是它想要找的MAC地址。
4:源主機收到ARP響應包後。將目的主機的IP和MAC地址寫入ARP列表,並利用此信息發送數據。如果源主機一直沒有收到ARP響應數據包,表示ARP查詢失敗。

DHCP協議

四步:自頂向下P232

NAT

P233

ICMP

P236

網絡層選路算法

Link State / Distance Vector (P245)
OSPF / RIP
BGP

III 其他常見面試題

Linux命令

ps process situation
查看進程狀態
top
top命令是Linux下常用的性能分析工具,能夠實時顯示系統中各個進程的資源佔用狀況,類似於Windows的任務管理器。
netstat grep
查看佔用端口的進程號
netstat
顯示網絡相關的信息,如網絡連接,路由表(-r),接口狀態
-a (all) 顯示全部信息
-n 拒絕別名,能用數字的都用數字
tcpdump
對網絡上的數據包進行截獲的包分析工具。
ipcs ipcshow
提供進程間通信方式的信息,包括共享內存,信號量,消息隊列。
-a 輸出所有
-m 共享內存
-q 消息隊列
-s 信號
ipcrm ipcremove
移除一個消息對象、或者共享內存、或者信號量
ipcrm用法 (小寫是id標識)
ipcrm -M shmkey 移除用shmkey創建的共享內存段
ipcrm -m shmid 移除用shmid標識的共享內存段
ipcrm -Q msgkey 移除用msqkey創建的消息隊列
ipcrm -q msqid 移除用msqid標識的消息隊列
ipcrm -S semkey 移除用semkey創建的信號
ipcrm -s semid 移除用semid標識的信號
cat
cat主要有三大功能:
1.一次顯示整個文件。$ cat filename
2.從鍵盤創建一個文件。$ cat > filename
只能創建新文件,不能編輯已有文件.
3.將幾個文件合併爲一個文件: $cat file1 file2 > file

代碼的侷限性

  • 時間侷限性 某指令一旦執行,則不久後該指令可能再被執行;某數據被訪問過,則不久後該數據可能再次被訪問。
  • 空間侷限性 程序在一段時間內所

Web服務器高併發的解決方案

1、採用多線程

2、將耗時的操作剝離出來,用單獨的服務器進行處理,比如大文件的傳輸,會佔用較多的CPU時間

3、對流量進行監控和統計,制定具體的優化策略,比如檢測到某部分資源經常被用到,就將其放到緩存裏面。

C++

引用 vs 指針

引用很容易與指針混淆,它們之間有三個主要的不同:

不存在空引用。引用必須連接到一塊合法的內存。
一旦引用被初始化爲一個對象,就不能被指向到另一個對象。指針可以在任何時候指向到另一個對象。
引用必須在創建時被初始化。指針可以在任何時間被初始化。

STL Sort

在數據量很大時採用正常的快速排序,此時效率爲O(logN)。
一旦分段後的數據量小於某個閾值,就改用插入排序,因爲此時這個分段是基本有序的,這時效率可達O(N)。
在遞歸過程中,如果遞歸層次過深,分割行爲有惡化傾向時,它能夠自動偵測出來,使用堆排序來處理,在此情況下,使其效率維持在堆排序的O(N logN),但這又比一開始使用堆排序好。

Shared_ptr

解決內存泄漏最有效的辦法就是使用智能指針(Smart Pointer)。使用智能指針就不用擔心這個問題了,因爲智能指針可以自動刪除分配的內存。智能指針和普通指針類似,只是不需要手動釋放指針,而是通過智能指針自己管理內存的釋放,這樣就不用擔心內存泄漏的問題了。

爲了解決C++內存泄漏的問題,C++11引入了智能指針(Smart Pointer)。
智能指針的原理是,接受一個申請好的內存地址,構造一個保存在棧上的智能指針對象,當程序退出棧的作用域範圍後,由於棧上的變量自動被銷燬,智能指針內部保存的內存也就被釋放掉了(除非將智能指針保存起來)。
C++11提供了三種智能指針:std::shared_ptr, std::unique_ptr, std::weak_ptr,使用時需添加頭文件。
shared_ptr使用引用計數,每一個shared_ptr的拷貝都指向相同的內存。每使用他一次,內部的引用計數加1,每析構一次,內部的引用計數減1,減爲0時,刪除所指向的堆內存。shared_ptr內部的引用計數是安全的,但是對象的讀取需要加鎖。

C++內存泄露解決方案

  • RAII
    RAII是resource acquisition is initialization的縮寫,意爲“資源獲取即初始化”。它是C++之父Bjarne Stroustrup提出的設計理念,其核心是把資源和對象的生命週期綁定,對象創建獲取資源,對象銷燬釋放資源。在RAII的指導下,C++把底層的資源管理問題提升到了對象生命週期管理的更高層次。
    說起來,RAII的含義倒也不算複雜。用白話說就是:在類的構造函數中分配資源,在析構函數中釋放資源。這樣,當一個對象創建的時候,構造函數會自動地被調用;而當這個對象被釋放的時候,析構函數也會被自動調用。於是乎,一個對象的生命期結束後將會不再佔用資源,資源的使用是安全可靠的。

  • 智能指針

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