鏈接:https://www.zhihu.com/question/34574154/answer/253165162
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
今年剛找完工作的應屆生來答一發,校招主要考察基礎和思維,主要涉及C++語言基礎,數據結構與算法,TCP/IP協議,網絡編程,Linux。
雖然面試技巧和心態也很重要,但這里只有24K純技術干貨。點贊后,收藏吧!
C和C++語言基礎
參考書籍:《C++ primer》,《effective C++》,《STL源碼解析》,《深度搜索C++對象模型》
- extern關鍵字作用
- static關鍵字作用
- volatile是干啥的
- 說說const的作用,越多越好
- new與malloc區別
- C++多態性與虛函數表
- C++多態的實現?
- 虛函數的作用?
- 虛函數用於實現多態,這點大家都能答上來但是虛函數在設計上還具有封裝和抽象的作用。比如抽象工廠模式。
- 動態綁定是如何實現的?
- 靜態多態和動態多態。靜態多態是指通過模板技術或者函數重載技術實現的多態,其在編譯器確定行為。動態多態是指通過虛函數技術實現在運行期動態綁定的技術。
- 虛函數表
- 虛函數表是針對類的還是針對對象的?同一個類的兩個對象的虛函數表是怎么維護的?
- 編譯器為每一個類維護一個虛函數表,每個對象的首地址保存着該虛函數表的指針,同一個類的不同對象實際上指向同一張虛函數表。
- 純虛函數如何定義,為什么對於存在虛函數的類中析構函數要定義成虛函數
- 析構函數能拋出異常嗎
- 構造函數和析構函數中調用虛函數嗎?
- 指針和引用的區別
- 指針與數組千絲萬縷的聯系
- 智能指針是怎么實現的?什么時候改變引用計數?
- 構造函數中計數初始化為1;
- 拷貝構造函數中計數值加1;
- 賦值運算符中,左邊的對象引用計數減一,右邊的對象引用計數加一;
- 析構函數中引用計數減一;
- 在賦值運算符和析構函數中,如果減一后為0,則調用delete釋放對象。
- share_prt與weak_ptr的區別?
- C++四種類型轉換:static_cast, dynamic_cast, const_cast, reinterpret_cast
- 內存對齊的原則
- 內聯函數有什么優點?內聯函數與宏定義的區別?
- C++內存管理
- STL里的內存池實現
- STL里set和map是基於什么實現的。紅黑樹的特點?
- STL里的其他數據結構和算法實現也要清楚
這個問題,把STL源碼剖析好好看看,不僅面試不慌,自己對STL的使用也會上升一個層次。 - 必須在構造函數初始化式里進行初始化的數據成員有哪些
- 模板特化
- 定位內存泄露
(1)在windows平台下通過CRT中的庫函數進行檢測;
(2)在可能泄漏的調用前后生成塊的快照,比較前后的狀態,定位泄漏的位置
(3)Linux下通過工具valgrind檢測 - 手寫strcpy,memcpy,strcat,strcmp等函數
數據結構與算法
這一塊考察范圍太廣,主要靠多刷題吧,牛客網,劍指OFFER,LeetCode等。
Hash表
- Hash表實現(拉鏈和分散地址)
- Hash策略常見的有哪些?
- STL中hash_map擴容發生什么?
(1) 創建一個新桶,該桶是原來桶兩倍大最接近的質數(判斷n是不是質數的方法:用n除2到sqrt(n)范圍內的數) ;
(2) 將原來桶里的數通過指針的轉換,插入到新桶中(注意STL這里做的很精細,沒有直接將數據從舊桶遍歷拷貝數據插入到新桶,而是通過指針轉換)
(3) 通過swap函數將新桶和舊桶交換,銷毀新桶。
樹
- 二叉樹結構,二叉查找樹實現;
- 二叉樹的六種遍歷;
- 二叉樹的按層遍歷;
- 遞歸是解決二叉樹相關問題的神級方法;
- 樹的各種常見算法題(http://blog.csdn.net/xiajun07061225/article/details/12760493);
- 什么是紅黑樹?
- 紅黑樹與AVL樹的區別
- Trie樹(字典樹)
鏈表
- 鏈表和插入和刪除,單向和雙向鏈表都要會
- 鏈表的問題考慮多個指針和遞歸
(1) 反向打印鏈表(遞歸)
(2) 打印倒數第K個節點(前后指針)
(3) 鏈表是否有環(快慢指針)等等。
棧和隊列
- 隊列和棧的區別?(從實現,應用,自身特點多個方面來闡述,不要只說一個先入先出,先入后出,這個你會別人也會,要展現出你比別人掌握的更深)
- 典型的應用場景
海量數據問題
- 十億整數(隨機生成,可重復)中前K最大的數
- 十億整數(隨機生成,可重復)中出現頻率最高的一千個
排序算法
- 排序算法當然是基礎內容了,必須至少能快速寫出,快排,建堆,和歸並
- 每種算法的時間空間復雜度,最好最差平均情況
位運算
布隆過濾器
幾十億個數經常要查找某一個數在不在里面,使用布隆過濾器,布隆過濾器的原理。布隆過濾器可能出現誤判,怎么保證無誤差?
網絡與TCP/IP
參考書籍:《圖解TCP/IP》,《TCP/IP詳解 卷一》,《圖解HTTP》,《HTTP權威指南》
- TCP與UDP之間的區別
(1) IP首部,TCP首部,UDP首部
(2) TCP和UDP區別
(3) TCP和UDP應用場景
(4) 如何實現可靠的UDP - TCP三次握手與四次揮手
- 詳細說明TCP狀態遷移過程
(1) 三次握手和四次揮手狀態變化;
(2) 2MSL是什么狀態?作用是什么?
(3)三次握手為什么不是兩次或者四次? - TCP相關技術
- TCP重發機制,Nagle算法
- TCP的擁塞控制使用的算法和具體過程
- TCP的窗口滑動
- TCP客戶與服務器模型,用到哪些函數
- UDP客戶與服務器模型,用到哪些函數
- 域名解析過程,ARP的機制,RARP的實現
- Ping和TraceRoute實現原理
HTTP
- http/https 1.0、1.1、2.0的特點和區別
- get/post 區別
- HTTP返回狀態碼
- http 協議頭相關
http數據由請求行,首部字段,空行,報文主體四個部分組成
首部字段分為:通用首部字段,請求首部字段,響應首部字段,實體首部字段
- https與http的區別?如何實現加密傳輸?加解密方式?
- 瀏覽器中輸入一個URL發生什么,用到哪些協議?
安全相關
至少了解攻擊的原理和基本的防御方法,常見的攻擊方法有一下幾種
- SQL注入
- XSS
- CSRF
- SYN洪水攻擊
- APR欺騙
數據庫
主要參考書籍:《數據庫系統概念》,《高性能MySQL》
- SQL語言(內外連接,子查詢,分組,聚集,嵌套,邏輯)
- MySQL索引方法?索引的優化?
- InnoDB與MyISAM區別?
- 事務的ACID
- 事務的四個隔離級別
- 查詢優化(從索引上優化,從SQL語言上優化)
- B-與B+樹區別?
- MySQL的聯合索引(又稱多列索引)是什么?生效的條件?
- 分庫分表
Linux
主要參考書籍:《現代操作系統》,《APUE》,《UNP》,《LINUX內核設計與實現》,《深入理解LINUX內核》
(1) 進程與線程區別?
(2) 線程比進程具有哪些優勢?
(3) 什么時候用多進程?什么時候用多線程?
(4) LINUX中進程和線程使用的幾個函數?
(5) 線程同步?
在Windows下線程同步的方式有:互斥量,信號量,事件,關鍵代碼段
在Linux下線程同步的方式有:互斥鎖,自旋鎖,讀寫鎖,屏障(並發完成同一項任務時,屏障的作用特別好使) 知道這些鎖之間的區別,使用場景?
- 匿名管道與命名管道的區別:匿名管道只能在具有公共祖先的兩個進程間使用。
- 共享文件映射mmap
mmap建立進程空間到文件的映射,在建立的時候並不直接將文件拷貝到物理內存,同樣采用缺頁終端。mmap映射一個具體的文件可以實現任意進程間共享內存,映射一個匿名文件,可以實現父子進程間共享內存。 - 常見的信號有哪些?:SIGINT,SIGKILL(不能被捕獲),SIGTERM(可以被捕獲),SIGSEGV,SIGCHLD,SIGALRM
- 虛擬內存的作用?
- 虛擬內存的實現?
- 操作系統層面對內存的管理?
- 內存池的作用?STL里內存池如何實現?
- 進程空間和內核空間對內存的管理不同?
- Linux的slab層,VAM?
- 伙伴算法
- 高端內存
- 進程調度
- Linux進程分為兩種,實時進程和非實時進程;
- 優先級分為靜態優先級和動態優先級,優先級的范圍;
- 調度策略
- 交互進程通過平均睡眠時間而被獎勵;
(1) 死鎖產生的條件;
(2) 死鎖的避免;
- 命令行
- Linux命令 在一個文件中,倒序打印第二行前100個大寫字母
cat filename | head -n 2 | tail -n 1 | grep '[[:upper:]]' -o | tr -d '\n'| cut -c 1-100 | rev
- 與CPU,內存,磁盤相關的命令(top,free, df, fdisk)
- 網絡相關的命令netstat,tcpdump等
- sed, awk, grep三個超強大的命名,分別用與格式化修改,統計,和正則查找
- ipcs和ipcrm命令
- 查找當前目錄以及字母下以.c結尾的文件,且文件中包含”hello world”的文件的路徑
- 創建定時任務
- IO模型
- 五種IO模型:阻塞IO,非阻塞IO,IO復用,信號驅動式IO,異步IO
- select,poll,epoll的區別
- 線程池,內存池 自己動手實現一遍
Linux的API
- 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是如何避免內存碎片的
- 伙伴算法,用於管理物理內存,避免內存碎片;
- 高速緩存Slab層用於管理內核分配內存,避免碎片。
- 共享內存的實現原理?
- 系統調用與庫函數(open, close, create, lseek, write, read)
- 同步方法有哪些?
- 互斥鎖,自旋鎖,信號量,讀寫鎖,屏障
- 互斥鎖與自旋鎖的區別:互斥鎖得不到資源的時候阻塞,不占用cpu資源。自旋鎖得不到資源的時候,不停的查詢,而然占用cpu資源。
- 死鎖
其他
- ++i是否是原子操作
明顯不是,++i主要有三個步驟,把數據從內存放在寄存器上,在寄存器上進行自增,把數據從寄存器拷貝會內存,每個步驟都可能被中斷。 - 判斷大小端
設計模式
- 單例模式線程安全的寫法
- STL里的迭代器模式,適配器模式
分布式系統
- map_reduce原理 (這篇文章講的很通俗易懂)
- 負載均衡
- CDN
主要列出考察內容的方向,問題的理解就得靠自己實踐和閱讀書籍了,相關問題的答案在我這篇博客中給出了自己理解的程度,歡迎交流!