參考書籍:《C++ primer》,《effective C++》,《STL源碼解析》,《深度搜索C++對象模型》html
extern關鍵字做用linux
static關鍵字做用c++
volatile是幹啥的git
說說const的做用,越多越好程序員
new與malloc區別github
C++多態性與虛函數表web
可是虛函數在設計上還具備封裝和抽象的做用。好比抽象工廠模式。面試
動態綁定是如何實現的?
第一個問題中基本回答了,主要都是結合虛函數表來答就行。算法
靜態多態和動態多態。靜態多態是指經過模板技術或者函數重載技術實現的多態,其在編譯器肯定行爲。動態多態是指經過虛函數技術實如今運行期動態綁定的技術。數據庫
純虛函數如何定義,爲何對於存在虛函數的類中析構函數要定義成虛函數
爲了實現多態進行動態綁定,將派生類對象指針綁定到基類指針上,對象銷燬時,若是析構函數沒有定義爲析構函數,則會調用基類的析構函數,顯然只能銷燬部分數據。若是要調用對象的析構函數,就須要將該對象的析構函數定義爲虛函數,銷燬時經過虛函數表找到對應的析構函數。
C++標準指明析構函數不能、也不該該拋出異常。C++異常處理模型最大的特色和優點就是對C++中的面向對象提供了最強大的無縫支持。那麼若是對象在運行期間出現了異常,C++異常處理模型有責任清除那些因爲出現異常所致使的已經失效了的對象(也即對象超出了它原來的做用域),並釋放對象原來所分配的資源, 這就是調用這些對象的析構函數來完成釋放資源的任務,因此從這個意義上說,析構函數已經變成了異常處理的一部分。
(2) 一般異常發生時,c++的機制會調用已經構造對象的析構函數來釋放資源,此時若析構函數自己也拋出異常,則前一個異常還沒有處理,又有新的異常,會形成程序崩潰的問題。
構造函數和析構函數中調用虛函數嗎?
指針和引用的區別
指針與數組千絲萬縷的聯繫
C++四種類型轉換:static_cast, dynamic_cast, const_cast, reinterpret_cast
內存對齊的原則
內聯函數有什麼優勢?內聯函數與宏定義的區別?
C++內存管理
STL裏的內存池實現
STL內存分配分爲一級分配器和二級分配器,一級分配器就是採用malloc分配內存,二級分配器採用內存池。
二級分配器設計的很是巧妙,分別給8k,16k,…, 128k等比較小的內存片都維持一個空閒鏈表,每一個鏈表的頭節點由一個數組來維護。須要分配內存時從合適大小的鏈表中取一塊下來。假設須要分配一塊10K的內存,那麼就找到最小的大於等於10k的塊,也就是16K,從16K的空閒鏈表裏取出一個用於分配。釋放該塊內存時,將內存節點歸還給鏈表。
若是要分配的內存大於128K則直接調用一級分配器。
爲了節省維持鏈表的開銷,採用了一個union結構體,分配器使用union裏的next指針來指向下一個節點,而用戶則使用union的空指針來表示該節點的地址。
STL裏set和map是基於什麼實現的。紅黑樹的特色?
STL裏的其餘數據結構和算法實現也要清楚
這個問題,把STL源碼剖析好好看看,不只面試不慌,本身對STL的使用也會上升一個層次。
必須在構造函數初始化式裏進行初始化的數據成員有哪些
(1) 常量成員,由於常量只能初始化不能賦值,因此必須放在初始化列表裏面
(2) 引用類型,引用必須在定義的時候初始化,而且不能從新賦值,因此也要寫在初始化列表裏面
(3) 沒有默認構造函數的類類型,由於使用初始化列表能夠沒必要調用默認構造函數來初始化,而是直接調用拷貝構造函數初始化
模板特化
(1) 模板特化分爲全特化和偏特化,模板特化的目的就是對於某一種變量類型具備不一樣的實現,所以須要特化版本。例如,在STL裏迭代器爲了適應原生指針就將原生指針進行特化。
定位內存泄露
(1)在windows平臺下經過CRT中的庫函數進行檢測;
(2)在可能泄漏的調用先後生成塊的快照,比較先後的狀態,定位泄漏的位置
(3)Linux下經過工具valgrind檢測
手寫strcpy
這一塊考察範圍太廣,主要靠多刷題吧,牛客網,劍指OFFER,LeetCode等。
樹的各類常見算法題(http://blog.csdn.net/xiajun07061225/article/details/12760493);
什麼是紅黑樹?
紅黑樹與AVL樹的區別
十億整數(隨機生成,可重複)中前K最大的數
相似問題的解決方法思路:首先哈希將數據分紅N個文件,而後對每一個文件創建K個元素最小/大堆(根據要求來選擇)。最後將文件中剩餘的數插入堆中,並維持K個元素的堆。最後將N個堆中的元素合起來分析。能夠採用歸併的方式來合併。在歸併的時候爲了提升效率還須要建一個N個元素構成的最大堆,先用N個堆中的最大值填充這個堆,而後就是彈出最大值,指針後移的操做了。固然這種問題在如今的互聯網技術中,通常就用map-reduce框架來作了。
大數據排序相同的思路:先哈希(哈希是好處是分佈均勻,相同的數在同一個文件中),而後小文件裝入內存快排,排序結果輸出到文件。最後建堆歸併。
十億整數(隨機生成,可重複)中出現頻率最高的一千個
幾十億個數常常要查找某一個數在不在裏面,使用布隆過濾器,布隆過濾器的原理。布隆過濾器可能出現誤判,怎麼保證無偏差?
參考書籍:《圖解TCP/IP》,《TCP/IP詳解 卷一》,《圖解HTTP》,《HTTP權威指南》
TCP與UDP之間的區別
(1) IP首部,TCP首部,UDP首部
(2) TCP和UDP區別
(3) TCP和UDP應用場景
(4) 如何實現可靠的UDP
詳細說明TCP狀態遷移過程
(1) 三次握手和四次揮手狀態變化;
(2) 2MSL是什麼狀態?做用是什麼?
(3)三次握手爲何不是兩次或者四次?
Ping和TraceRoute實現原理
http的主要特色:
簡單快速:當客戶端向服務器端發送請求時,只是簡單的填寫請求路徑和請求方法便可,而後就能夠經過瀏覽器或其餘方式將該請求發送就好了
靈活: HTTP 協議容許客戶端和服務器端傳輸任意類型任意格式的數據對象
無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接,採用這種方式能夠節省傳輸時間。(當今多數服務器支持Keep-Alive功能,使用服務器支持長鏈接,解決無鏈接的問題)
無狀態:無狀態是指協議對於事務處理沒有記憶能力,服務器不知道客戶端是什麼狀態。即客戶端發送HTTP請求後,服務器根據請求,會給咱們發送數據,發送完後,不會記錄信息。(使用 cookie 機制能夠保持 session,解決無狀態的問題)
http1.1的特色
a、默認持久鏈接節省通訊量,只要客戶端服務端任意一端沒有明確提出斷開TCP鏈接,就一直保持鏈接,能夠發送屢次HTTP請求
b、管線化,客戶端能夠同時發出多個HTTP請求,而不用一個個等待響應
c、斷點續傳
http2.0的特色
a、HTTP/2採用二進制格式而非文本格式
b、HTTP/2是徹底多路複用的,而非有序並阻塞的——只需一個HTTP鏈接就能夠實現多個請求響應
c、使用報頭壓縮,HTTP/2下降了開銷
d、HTTP/2讓服務器能夠將響應主動「推送」到客戶端緩存中
http數據由請求行,首部字段,空行,報文主體四個部分組成
首部字段分爲:通用首部字段,請求首部字段,響應首部字段,實體首部字段
瀏覽器中輸入URL,首先瀏覽器要將URL解析爲IP地址,解析域名就要用到DNS協議,首先主機會查詢DNS的緩存,若是沒有就給本地DNS發送查詢請求。DNS查詢分爲兩種方式,一種是遞歸查詢,一種是迭代查詢。若是是迭代查詢,本地的DNS服務器,向根域名服務器發送查詢請求,根域名服務器告知該域名的一級域名服務器,而後本地服務器給該一級域名服務器發送查詢請求,而後依次類推直到查詢到該域名的IP地址。DNS服務器是基於UDP的,所以會用到UDP協議。
獲得IP地址後,瀏覽器就要與服務器創建一個http鏈接。所以要用到http協議,http協議報文格式上面已經提到。http生成一個get請求報文,將該報文傳給TCP層處理。若是採用https還會先對http數據進行加密。TCP層若是有須要先將HTTP數據包分片,分片依據路徑MTU和MSS。TCP的數據包而後會發送給IP層,用到IP協議。IP層經過路由選路,一跳一跳發送到目的地址。固然在一個網段內的尋址是經過以太網協議實現(也能夠是其餘物理層協議,好比PPP,SLIP),以太網協議須要直到目的IP地址的物理地址,有須要ARP協議。
至少了解攻擊的原理和基本的防護方法,常見的攻擊方法有一下幾種
主要參考書籍:《數據庫系統概念》,《高性能MySQL》
主要參考書籍:《現代操做系統》,《APUE》,《UNP》,《LINUX內核設計與實現》,《深刻理解LINUX內核》
(1) 進程與線程區別?
(2) 線程比進程具備哪些優點?
(3) 何時用多進程?何時用多線程?
(4) LINUX中進程和線程使用的幾個函數?
(5) 線程同步?
在Windows下線程同步的方式有:互斥量,信號量,事件,關鍵代碼段
在Linux下線程同步的方式有:互斥鎖,自旋鎖,讀寫鎖,屏障(併發完成同一項任務時,屏障的做用特別好使)
知道這些鎖之間的區別,使用場景?
管道( pipe ):管道是一種半雙工的通訊方式,數據只能單向流動,並且只能在具備親緣關係的進程間使用。進程的親緣關係一般是指父子進程關係。
命名管道 (FIFO) : 有名管道也是半雙工的通訊方式,可是它容許無親緣關係進程間的通訊。
信號量:信號量用於實現進程間的互斥與同步,而不是用於存儲進程間通訊數據,有XSI信號量和POSIX信號量,POSIX信號量更加完善。
消息隊列( message queue ) : 消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。
共享內存( shared memory ) :共享內存就是映射一段能被其餘進程所訪問的內存,這段共享內存由一個進程建立,但多個進程均可以訪問。共享內存是最快的 IPC 方式,它是針對其餘進程間通訊方式運行效率低而專門設計的。它每每與其餘通訊機制,如信號兩,配合使用,來實現進程間的同步和通訊。(原理必定要清楚,常考)
信號 ( sinal ) : 信號是一種比較複雜的通訊方式,用於通知接收進程某個事件已經發生,常見的信號。
套接字( socket ) : 套解口也是一種進程間通訊機制,與其餘通訊機制不一樣的是,它可用於不一樣及其間的進程通訊。
共享文件映射mmap
mmap創建進程空間到文件的映射,在創建的時候並不直接將文件拷貝到物理內存,一樣採用缺頁終端。mmap映射一個具體的文件能夠實現任意進程間共享內存,映射一個匿名文件,能夠實現父子進程間共享內存。
常見的信號有哪些?:SIGINT,SIGKILL(不能被捕獲),SIGTERM(能夠被捕獲),SIGSEGV,SIGCHLD,SIGALRM
(1) 死鎖產生的條件;
(2) 死鎖的避免;
與CPU,內存,磁盤相關的命令(top,free, df, fdisk)
網絡相關的命令netstat,tcpdump等
sed, awk, grep三個超強大的命名,分別用與格式化修改,統計,和正則查找
ipcs和ipcrm命令
查找當前目錄以及字母下以.c結尾的文件,且文件中包含」hello world」的文件的路徑
建立定時任務
五種IO模型:阻塞IO,非阻塞IO,IO複用,信號驅動式IO,異步IO
select,poll,epoll的區別
select:是最初解決IO阻塞問題的方法。用結構體fd_set來告訴內核監聽多個文件描述符,該結構體被稱爲描述符集。由數組來維持哪些描述符被置位了。對結構體的操做封裝在三個宏定義中。經過輪尋來查找是否有描述符要被處理,若是沒有返回**
存在的問題:
1. 內置數組的形式使得select的最大文件數受限與FD_SIZE;
2. 每次調用select前都要從新初始化描述符集,將fd從用戶態拷貝到內核態,每次調用select後,都須要將fd從內核態拷貝到用戶態;
3. 輪尋排查當文件描述符個數不少時,效率很低;
poll:經過一個可變長度的數組解決了select文件描述符受限的問題。數組中元素是結構體,該結構體保存描述符的信息,每增長一個文件描述符就向數組中加入一個結構體,結構體只須要拷貝一次到內核態。poll解決了select重複初始化的問題。輪尋排查的問題未解決。**
epoll:輪尋排查全部文件描述符的效率不高,使服務器併發能力受限。所以,epoll採用只返回狀態發生變化的文件描述符,便解決了輪尋的瓶頸。
- 爲何使用IO多路複用,最主要的緣由是什麼?
- epoll有兩種觸發模式?這兩種觸發模式有什麼區別?編程的時候有什麼區別?
- 上一題中編程的時候有什麼區別,是在邊緣觸發的時候要把套接字中的數據讀乾淨,那麼當有多個套接字時,在讀的套接字一直不停的有數據到達,如何保證其餘套接字不被餓死(面試網易遊戲的時候問的一個問題,答不上來,印象賊深入)。
fork與vfork區別
fork和vfork都用於建立子進程。可是vfork建立子進程後,父進程阻塞,直到子進程調用exit()或者excle()。
對於內核中過程fork經過調用clone函數,而後clone函數調用do_fork()。do_fork()中調用copy_process()函數先複製task_struct結構體,而後複製其餘關於內存,文件,寄存器等信息。fork採用寫時拷貝技術,所以子進程和父進程的頁表指向相同的頁框。可是vfork不須要拷貝頁表,由於父進程會一直阻塞,直接使用父進程頁表。
exit()與_exit()區別
exit()清理後進入內核,_exit()直接陷入內核。
孤兒進程與僵死進程
Linux是如何避免內存碎片的
共享內存的實現原理?
共享內存實現分爲兩種方式一種是採用mmap,另外一種是採用XSI機制中的共享內存方法。mmap是內存文件映射,將一個文件映射到進程的地址空間,用戶進程的地址空間的管理是經過vm_area_struct結構體進行管理的。mmap經過映射一個相同的文件到兩個不一樣的進程,就能實現這兩個進程的通訊,採用該方法能夠實現任意進程之間的通訊。mmap也能夠採用匿名映射,不指定映射的文件,可是隻能在父子進程間通訊。XSI的內存共享實際上也是經過映射文件實現,只是其映射的是一種特殊文件系統下的文件,該文件是不能經過read和write訪問的。
兩者區別:
一、 系統V共享內存中的數據,歷來不寫入到實際磁盤文件中去;而經過mmap()映射普通文件實現的共享內存通訊能夠指定什麼時候將數據寫入磁盤文件中。注:前面講到,系統V共享內存機制實際是經過映射特殊文件系統shm中的文件實現的,文件系統shm的安裝點在交換分區上,系統從新引導後,全部的內容都丟失。
二、 系統V共享內存是隨內核持續的,即便全部訪問共享內存的進程都已經正常終止,共享內存區仍然存在(除非顯式刪除共享內存),在內核從新引導以前,對該共享內存區域的任何改寫操做都將一直保留。
三、 經過調用mmap()映射普通文件進行進程間通訊時,必定要注意考慮進程什麼時候終止對通訊的影響。而經過系統V共享內存實現通訊的進程則否則。注:這裏沒有給出shmctl的使用範例,原理與消息隊列大同小異。
系統調用與庫函數(open, close, create, lseek, write, read)
同步方法有哪些?
++i是不是原子操做
明顯不是,++i主要有三個步驟,把數據從內存放在寄存器上,在寄存器上進行自增,把數據從寄存器拷貝會內存,每一個步驟均可能被中斷。
判斷大小端
部分問題只是列出思考的概要,去書中和實踐中找到這些問題的答案才能真正的消化。
PS:歡迎轉載,轉載請標明出處!