linux 後臺開發類常見問題及知識點

1、linux和os:

  • netstat :顯示網絡狀態html

  • tcpdump:主要是截獲經過本機網絡接口的數據,用以分析。可以截獲當前全部經過本機網卡的數據包。它擁有靈活的過濾機制,能夠確保獲得想要的數據。linux

  • ipcs:檢查系統上共享內存的分配c++

  • ipcrm:手動解除系統上共享內存的分配面試

      (若是這四個命令沒據說過或者不能熟練使用,基本上能夠回家,經過的機率較小 ^_^ ,這四個命令的熟練掌握程度基本上能體現面試者實際開發和調試程序的經驗)算法

      cpu 內存 硬盤 等等與系統性能調試相關的命令必須熟練掌握,設置修改權限 tcp網絡狀態查看 各進程狀態 抓包相關等相關命令 必須熟練掌握編程

awk sed需掌握數組

1. 共享內存的使用實現原理

(必考必問,而後共享內存段被映射進進程空間以後,存在於進程空間的什麼位置?共享內存段最大限制是多少?)緩存

  共享內存定義:共享內存是最快的可用IPC(進程間通訊)形式。它容許多個不相關的進程去訪問同一部分邏輯內存。共享內存是由IPC爲一個進程建立的一個特殊的地址範圍,它將出如今進程的地址空間中。其餘進程能夠把同一段共享內存段「鏈接到」它們本身的地址空間裏去。全部進程均可以訪問共享內存中的地址。若是一個進程向這段共享內存寫了數據,所作的改動會馬上被有訪問同一段共享內存的其餘進程看到。所以共享內存對於數據的傳輸是很是高效的。服務器

  共享內存的原理:共享內存是最有用的進程間通訊方式之一,也是最快的IPC形式。兩個不一樣進程A、B共享內存的意思是,同一塊物理內存被映射到進程A、B各自的進程地址空間。進程A能夠即時看到進程B對共享內存中數據的更新,反之亦然。網絡

2. c++進程內存空間分佈(注意各部分的內存地址誰高誰低,注意棧從高到低分配,堆從低到高分配)

3. 使用過哪些進程間通信機制,並詳細說明(重點)

4. makefile編寫,雖然比較基礎,可是會被問到

5. gdb調試相關的經驗,會被問到

6. 如何定位內存泄露?

  內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的、大小任意的(內存塊的大小能夠在程序運行期決定)、使用完後必須顯示釋放的內存。應用程序通常使用malloc、realloc、new等函數從堆中分配到一塊內存,使用完後,程序必須負責相應的調用free或delete釋放該內存塊。不然,這塊內存就不能被再次使用,咱們就說這塊內存泄漏了。

  C++程序缺少相應的手段來檢測內存信息,只能使用top指令觀察進程的動態內存總額。並且程序退出時,咱們沒法獲知任何內存泄漏信息

  使用Linux命令回收內存,可使用ps、kill兩個命令檢測內存使用狀況和進行回收。在使用超級用戶權限時使用命令「ps」,它會列出全部正在運行的程序名稱和對應的進程號(PID)。kill命令的工做原理是向Linux操做系統的內核送出一個系統操做信號和程序的進程號(PID)

7. 動態連接和靜態連接的區別

動態連接是指在生成可執行文件時不將全部程序用到的函數連接到一個文件,由於有許多函數在操做系統帶的dll文件中,當程序運行時直接從操做系統中找。 而靜態連接就是把全部用到的函數所有連接到exe文件中。

  動態連接是隻創建一個引用的接口,而真正的代碼和數據存放在另外的可執行模塊中,在運行時再裝入;而靜態連接是把全部的代碼和數據都複製到本模塊中,運行時就再也不須要庫了。

8. 32位系統一個進程最多有多少堆內存

9. 多線程和多進程的區別

重點 面試官最最關心的一個問題,必須從cpu調度,上下文切換,數據共享,多核cup利用率,資源佔用,等等各方面回答,而後有一個問題必須會被問到:哪些東西是一個線程私有的?答案中必須包含寄存器,不然悲催

10. 說出你所知道的linux系統的各種同步機制(重點)

11. 什麼是死鎖?如何避免死鎖(每一個技術面試官必問)

12. 死鎖的條件

(互斥條件(Mutual exclusion):

  一、資源不能被共享,只能由一個進程使用。

  二、請求與保持條件(Hold and wait):已經獲得資源的進程能夠再次申請新的資源。

  三、非剝奪條件(No pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。

  四、循環等待條件(Circular wait):系統中若干進程組成環路,該環路中每一個進程都在等待相鄰進程正佔用的資源。

13. 處理死鎖的策略:

  1. 忽略該問題。例如鴕鳥算法,該算法能夠應用在極少發生死鎖的的狀況下。爲何叫鴕鳥算法呢,由於傳說中鴕鳥看到危險就把頭埋在地底下,可能鴕鳥以爲看不到危險也就沒危險了吧。跟掩耳盜鈴有點像。
  2. 檢測死鎖而且恢復。
  3. 仔細地對資源進行動態分配,以免死鎖。
  4. 經過破除死鎖四個必要條件之一,來防止死鎖產生。)

14. 列舉說明linux系統的各種異步機制

15. exit()與_exit()的區別?

  _exit終止調用進程,但不關閉文件,不清除輸出緩存,也不調用出口函數。exit函數將終止調用進程。在退出程序以前,全部文件關閉,緩衝輸出內容將刷新定義,並調用全部已刷新的「出口函數」(由atexit定義)。

  ‘exit()’與‘_exit()’有很多區別在使用‘fork()’,特別是‘vfork()’時變得很突出。

  ‘exit()’與‘_exit()’的基本區別在於前一個調用實施與調用庫裏用戶狀態結構(user-mode constructs)有關的清除工做(clean-up),並且調用用戶自定義的清除程序

16. linux的內存管理機制是什麼?

  Linux虛擬內存的實現須要6種機制的支持:地址映射機制、內存分配回收機制、緩存和刷新機制、請求頁機制、交換機制和內存共享機制

  內存管理程序經過映射機制把用戶程序的邏輯地址映射到物理地址。當用戶程序運行時,若是發現程序中要用的虛地址沒有對應的物理內存,就發出了請求頁要求。若是有空閒的內存可供分配,就請求分配內存(因而用到了內存的分配和回收),並把正在使用的物理頁記錄在緩存中(使用了緩存機制)。若是沒有足夠的內存可供分配,那麼就調用交換機制;騰出一部份內存。另外,在地址映射中要經過TLB(翻譯後援存儲器)來尋找物理頁;交換機制中也要用到交換緩存,而且把物理頁內容交換到交換文件中,也要修改頁表來映射文件地址。

17. linux的任務調度機制是什麼?

18. 標準庫函數和系統調用的區別?

19. 系統如何將一個信號通知到進程

2、c語言:

  • 宏定義和展開(必須精通)

  • 位操做(必須精通)

  • 指針操做和計算(必須精通)

  • 內存分配(必須精通)

  • sizeof必考

  • 各種庫函數必須很是熟練的實現

  • 哪些庫函數屬於高危函數,爲何?(strcpy等等)

3、c++:

1. 一個String類的完整實現必須很快速寫出來(注意:賦值構造,operator=是關鍵)

2. 虛函數的做用和實現原理(必問必考,實現原理必須很熟)

  有虛函數的類內部有一個稱爲「虛表」的指針(有多少個虛函數就有多少個指針),這個就是用來指向這個類虛函數。也就是用它來肯定調用該那個函數。

  實際上在編譯的時候,編譯器會自動加入「虛表」。虛表的使用方法是這樣的:若是派生類在本身的定義中沒有修改基類的虛函數,就指向基類的虛函數;若是派生類改寫了基類的虛函數(就是本身從新定義),這時虛表則將原來指向基類的虛函數的地址替換爲指向自身虛函數的指針。那些被virtual關鍵字修飾的成員函數,就是虛函數。虛函數的做用,用專業術語來解釋就是實現多態性(Polymorphism),多態性是將接口與實現進行分離;用形象的語言來解釋就是實現以共同的方法,但因個體差別而採用不一樣的策略。

  每一個類都有本身的vtbl,vtbl的做用就是保存本身類中虛函數的地址,咱們能夠把vtbl形象地當作一個數組,這個數組的每一個元素存放的就是虛函數的地址,

  虛函數的效率低,其緣由就是,在調用虛函數以前,還調用了得到虛函數地址的代碼。

3. sizeof一個類求大小(注意成員變量,函數,虛函數,繼承等等對大小的影響)

4. 指針和引用的區別(通常都會問到)

指針指向一塊內存,它的內容是所指內存的地址;而引用是某塊內存的別名。

相同點: 都是地址的概念;

區別:

  1. 指針是一個實體,而引用僅是個別名;
  2. 引用使用時無需解引用(*),指針須要解引用;
  3. 引用只能在定義時被初始化一次,以後不可變;指針可變;
  4. 引用沒有 const,指針有 const;
  5. 引用不能爲空,指針能夠爲空;
  6. 「sizeof 引用」獲得的是所指向的變量(對象)的大小,而「sizeof 指針」獲得的是指針自己(所指向的變量或對象的地址)的大小;
  7. 指針和引用的自增(++)運算意義不同;
  8. 從內存分配上看:程序爲指針變量分配內存區域,而引用不須要分配內存區域。

5. 多重類構造和析構的順序

先調用基類的構造函數,在調用派生類的構造函數

先構造的後析構,後構造的先析構

6. stl各容器的實現原理(必考)

  STL共有六大組件

  一、容器。二、算法。三、迭代器。四、仿函數。六、適配器。

  序列式容器:

  vector-數組,元素不夠時再從新分配內存,拷貝原來數組的元素到新分配的數組中。

  list-單鏈表。

  deque-分配中央控制器map(並不是map容器),map記錄着一系列的固定長度的數組的地址.記住這個map僅僅保存的是數組的地址,真正的數據在數組中存放着.deque先從map中央的位置(由於雙向隊列,先後均可以插入元素)找到一個數組地址,向該數組中放入數據,數組不夠時繼續在map中找空閒的數組來存數據。當map也不夠時從新分配內存看成新的map,把原來map中的內容copy的新map中。因此使用deque的複雜度要大於vector,儘可能使用vector。

  stack-基於deque。

  queue-基於deque。

  heap-徹底二叉樹,使用最大堆排序,以數組(vector)的形式存放。

  priority_queue-基於heap。

  slist-雙向鏈表。

  關聯式容器:

  set,map,multiset,multimap-基於紅黑樹(RB-tree),一種加上了額外平衡條件的二叉搜索樹。

  hash table-散列表。將待存數據的key通過映射函數變成一個數組(通常是vector)的索引,例如:數據的key%數組的大小=數組的索引(通常文本經過算法也能夠轉換爲數字),而後將數據看成此索引的數組元素。有些數據的key通過算法的轉換多是同一個數組的索引值(碰撞問題,能夠用線性探測,二次探測來解決),STL是用開鏈的方法來解決的,每個數組的元素維護一個list,他把相同索引值的數據存入一個list,這樣當list比較短時執行刪除,插入,搜索等算法比較快。

  hash_map,hash_set,hash_multiset,hash_multimap-基於hash table。

7. extern c 是幹啥的,(必須將編譯器的函數名修飾的機制解答的很透徹)

8. volatile是幹啥用的,(必須將cpu的寄存器緩存機制回答的很透徹)

  volatile的本意是「易變的」 由於訪問寄存器要比訪問內存單元快的多,因此編譯器通常都會做減小存取內存的優化,但有可能會讀髒數據。當要求使用volatile聲明變量值的時候,系統老是從新從它所在的內存讀取數據,即便它前面的指令剛剛從該處讀取過數據。精確地說就是,遇到這個關鍵字聲明的變量,編譯器對訪問該變量的代碼就再也不進行優化,從而能夠提供對特殊地址的穩定訪問;若是不使用volatile,則編譯器將對所聲明的語句進行優化。(簡潔的說就是:volatile關鍵詞影響編譯器編譯的結果,用volatile聲明的變量表示該變量隨時可能發生變化,與該變量有關的運算,不要進行編譯優化,以避免出錯)

volatile的本質:

  1. 編譯器的優化

      在本次線程內, 當讀取一個變量時,爲提升存取速度,編譯器優化時有時會先把變量讀取到一個寄存器中;之後,再取變量值時,就直接從寄存器中取值;當變量值在本線程裏改變時,會同時把變量的新值copy到該寄存器中,以便保持一致。

      當變量在因別的線程等而改變了值,該寄存器的值不會相應改變,從而形成應用程序讀取的值和實際的變量值不一致。

      當該寄存器在因別的線程等而改變了值,原變量的值不會改變,從而形成應用程序讀取的值和實際的變量值不一致。

  2. volatile應該解釋爲「直接存取原始內存地址」比較合適,「易變的」這種解釋簡直有點誤導人。

9. static const等等的用法,(能說出越多越好)

4、數據結構或者算法:

  • 各種樹結構的實現和應用

  • 各種排序:大根堆的實現,快排(如何避免最糟糕的狀態?),bitmap的運用等等

  • hash, 任何一個技術面試官必問(例如爲何通常hashtable的桶數會取一個素數?如何有效避免hash結果值的碰撞)

5、網絡編程:

1. tcp與udp的區別(必問)

  1. 基於鏈接與無鏈接
  2. 對系統資源的要求(TCP較多,UDP少)
  3. UDP程序結構較簡單
  4. 流模式與數據報模式
  5. TCP保證數據正確性,UDP可能丟包,TCP保證數據順序,UDP不保證

      TCP—傳輸控制協議,提供的是面向鏈接、可靠的字節流服務。當客戶和服務器彼此交換數據前,必須先在雙方之間創建一個TCP鏈接,以後才能傳輸數據。TCP提供超時重發,丟棄重複數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另外一端。

      UDP—用戶數據報協議,是一個簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,可是並不能保證它們能到達目的地。因爲UDP在傳輸數據報前不用在客戶和服務器之間創建一個鏈接,且沒有超時重發等機制,故而傳輸速度很快

2. socket服務端的實現,select和epoll的區別(必問)

  select的本質是採用32個整數的32位,即32*32= 1024來標識,fd值爲1-1024。當fd的值超過1024限制時,就必須修改FD_SETSIZE的大小。這個時候就能夠標識32*max值範圍的fd。

  對於單進程多線程,每一個線程處理多個fd的狀況,select是不適合的。

  1.全部的線程均是從1-32*max進行掃描,每一個線程處理的均是一段fd值,這樣作有點浪費

  2.1024上限問題,一個處理多個用戶的進程,fd值遠遠大於1024

  因此這個時候應該採用poll,

  poll傳遞的是數組頭指針和該數組的長度,只要數組的長度不是很長,性能仍是很不錯的,由於poll一次在內核中申請4K(一個頁的大小來存放fd),儘可能控制在4K之內

  epoll仍是poll的一種優化,返回後不須要對全部的fd進行遍歷,在內核中維持了fd的列表。select和poll是將這個內核列表維持在用戶態,而後傳遞到內核中。可是隻有在2.6的內核才支持。

  epoll更適合於處理大量的fd ,且活躍fd不是不少的狀況,畢竟fd較多仍是一個串行的操做

  epoll哪些觸發模式,有啥區別?(必須很是詳盡的解釋水平觸發和邊緣觸發的區別,以及邊緣觸發在編程中要作哪些更多的確認)

  epoll能夠同時支持水平觸發和邊緣觸發(Edge Triggered,只告訴進程哪些文件描述符剛剛變爲就緒狀態,它只說一遍,若是咱們沒有采起行動,那麼它將不會再次告知,這種方式稱爲邊緣觸發),理論上邊緣觸發的性能要更高一些,可是代碼實現至關複雜。

  epoll一樣只告知那些就緒的文件描述符,並且當咱們調用epoll_wait()得到就緒文件描述符時,返回的不是實際的描述符,而是一個表明就緒描述符數量的值,你只須要去epoll指定的一個數組中依次取得相應數量的文件描述符便可,這裏也使用了內存映射(mmap)技術,這樣便完全省掉了這些文件描述符在系統調用時複製的開銷。

  另外一個本質的改進在於epoll採用基於事件的就緒通知方式。在select/poll中,進程只有在調用必定的方法後,內核纔對全部監視的文件描述符進行掃描,而epoll事先經過epoll_ctl()來註冊一個文件描述符,一旦基於某個文件描述符就緒時,內核會採用相似callback的回調機制,迅速激活這個文件描述符,當進程調用epoll_wait()時便獲得通知。

3. 大規模鏈接上來,併發模型怎麼設計

4. tcp結束鏈接怎麼握手,time_wait狀態是什麼,爲何會有time_wait狀態?哪一方會有time_wait狀態,如何避免time_wait狀態佔用資源(必須回答的詳細)

5. tcp頭多少字節?哪些字段?(必問)

頭20字節,選項12字節

6. connect會阻塞,怎麼解決?(必考必問)

最一般的方法最有效的是加定時器;也能夠採用非阻塞模式。

設置非阻塞,返回以後用select檢測狀態)

若是select返回可讀,結果只讀到0字節,什麼狀況?

某個套接字集合中沒有準備好,可能會select內存用FD_CLR清該位爲0;

參考:http://mianshi.cnrencai.com/mianshiwenti/3229_4.html

相關文章
相關標籤/搜索