面試整理要背的

一.c\c++語言部分

1. 在C語言中,關鍵字static有三個明顯的作用:

A、一旦聲明爲靜態變量,在編譯時刻開始永遠存在,不受作用域範圍約束,但是如果是局部靜態變量,則此靜態變量只能在局部作用域內使用,超出範圍不能使用,但是它確實還佔用內存,還存在.
B、在模塊內(但在函數體外),一個被聲明爲靜態的變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變量。
C、在模塊內,一個被聲明爲靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地範圍內使用。

2. 關鍵字volatile有什麼含意?並給出三個不同的例子。

定義爲volatile的變量表明變量可能會被意想不到地改變,編譯器就不會去假設這個變量的值。準確地說,優化器在用到volatile修飾的變量時必須每次都小心地重新讀取變量的值,而不是使用保存在寄存器裏的備份。
使用volatile變量的例子:
A、並行設備的硬件寄存器(如:狀態寄存器)
B、一箇中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)
C、多線程應用中被幾個任務共享的變量

深入理解:

(1)一個參數既可以是const還可以是volatile嗎?解釋爲什麼。
是的。一個例子是隻讀的狀態寄存器。它是volatile因爲它可能被意想不到地改變。它是const因爲程序不應該試圖去修改它。
(2)一個指針可以是volatile 嗎?解釋爲什麼。
是的。儘管這並不很常見。一個例子是當一箇中服務子程序修改一個指向一個buffer的指針時。

3.引用和指針有什麼區別?

A、應用必須初始化,指針不必;

B、引用處畫化後不能改變,指針可以被改變;

C、不存在指向空值的引用,但存在指向空值的指針;

4.h頭文件中的ifndef/define/endif 的作用?
答:防止該頭文件被重複引用。
5.程序內存分配

A、棧區(stack)—由編譯器自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。
B、堆區(heap)—一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。
C、全局區(靜態區)(static)—全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。程序結束後由系統釋放。
D、文字常量區—常量字符串就是放在這裏的。程序結束後由系統釋放。
E、程序代碼區—存放函數體的二進制代碼

這是一個前輩寫的,非常詳細
//main.cpp
  int a=0;    //全局初始化區
  char *p1;   //全局未初始化區
  main()
  {
   intb;棧
   char s[]="abc";   //棧
   char *p2;         //棧
   char *p3="123456";   //123456\0在常量區,p3在棧上。
   static int c=0;   //全局(靜態)初始化區
   p1 = (char*)malloc(10);
   p2 = (char*)malloc(20);   //分配得來得10和20字節的區域就在堆區。
   strcpy(p1,"123456");   //123456\0放在常量區,編譯器可能會將它與p3所向"123456"優化成一個地方。
}

6.typedef和define和const的區別

typedef是C語言中用來聲明自定義數據類型,配合各種原有數據類型來達到簡化編程的目的的類型定義關鍵字。 #define是預處理指令,是宏定義

7.單元測試

  • 單元測試:  單元測試是對軟件基本組成單元(軟件設計的最小單位)進行正確性檢驗的測試工作,如函數、過程(function,procedure)或一個類的方法(method)。

  • 集成測試:  集成測試是在單元測試的基礎上,將所有模塊按照概要設計要求組裝成爲子系統或系統,驗證組裝後功能以及模塊間接口是否正確的測試工作。集成測試也叫組裝測試、聯合測試、子系統測試或部件測試。

  • 系統測試:  系統測試是將經過集成測試的軟件,作爲計算機系統的一個部分,與系統中其他部分結合起來,在實際運行環境下對計算機系統進行的一系列嚴格有效地測試,以發現軟件潛在的問題,保證系統的正常運行。

8. const常量

  • const 聲明的變量只讀
  • const 一定要要賦予初值
  • const 修飾的成員函數不可以改變
  • const 修飾的類只能夠調用const的成員函數
  • const 指針
  • const優於define 因爲有安全性檢查

9.sizeof和strlen區別

(1)sizeof是一個操作符,strlen是庫函數;
(2)sizeof的參數可以是數據的類型,也可以是變量,而strlen只能以結尾爲’\0’的字符串做參數;
(3)編譯器在編譯時就計算出了sizeof的結果。而strlen函數必須在運行時才能計算出來。並且sizeof計算的是數據類型佔內存的大小,而strlen計算的是字符串實際的長度;
(4)數組做sizeof的參數不退化,傳遞給strlen就退化爲指針

10.memcpy和strcpy的區別

(1)操作對象不同:
strcpy的兩個操作對象均是字符串
sprintf的操作源對象可以是多種數據類型,目的操作對象是字符串
memcpy的兩個對象就是兩個人一可操作的內存地址,不限於何種數據類型。
(2)執行效率不同:
memcpy最高,strcpy次之,sprintf效率最低。
(3)實現功能不同:
strcpy主要實現字符串變量間的拷貝
sprintf主要實現其他數據類型格式到字符串的轉化
memcpy主要是內存塊間的拷貝

11.面向對象的三大特徵
面向對象的三大特徵:封裝性,繼承性,多態性
12 malloc和new的區別

①、malloc/ free是 C++/C語言的標準庫函數,而new/ delete是C++的運算符。
②、malloc內存分配成功返回的類型爲void*,需要通過強制類型轉換將void*轉換爲我們需要的類型。
③、new內存分配失敗時會拋出bac_alloc異常,不會返回NULL;而malloc分配失敗時則返回NULL。
④、使用new操作符申請內存分配是無需指定內存塊的大小,而malloc則需要顯式地指出所需的內存大小。

13C語言的關鍵字static和C++的關鍵字static有什麼區別?

在C中static用來修飾局部靜態變量和外部靜態變量、函數。
而C++中除了以上功能之外,還可以用來定義類的成員變量和函數。即靜態成員和靜態成員函數。

編程時static的記憶性和全局性的特點可以讓在不同時期調用的函數進行通信,傳遞信息,而C++的靜態成員則可以在多個對象實例間進行通信,傳遞信息。

14 .變量的聲明和定義有什麼區別?

爲變量分配地址和存儲空間的稱爲定義,不分配地址的稱爲聲明。一個變量可以在多個地方聲明,但是隻能在一個地方定義。加入extern修飾的是變量的聲明,說明此變量將在文件以外或在文件後面部分定義。

15.簡述多態實現的原理

編譯器發現一個類裏面有虛函數,便會立即爲此類生成虛函數表vtable,虛函數表的各項爲指向對應虛函數的指針。編譯器還會爲此類中隱含插入一個指針vptr(對vc編譯器會插在第一個位置),指向虛函數表。調用此類的構造函數時,在類的構造函數中,編譯器會隱含執行vptr和vtable的關聯代碼,將vptr指向相應的vtable,將類與此類的vtable聯繫起來,另外在調用類的構造函數時,指向基礎類的指針此時已經變成指向具體類的this指針,這樣依靠this就可以指向vtable ,如此才能夠真正與函數進行鏈接,這就是動態的聯編,實現多態的基本原理-----虛函數是多態的基礎

16.談談對面向對象的認識

面向對象可以理解成對待每一個問題,都是首先要確定這個問題由幾個部分組成,而每一個部分其實就是一個對象。然後再分別設計這些對象,最後得到整個程序。傳統的程序設計多是基於功能的思想來進行考慮和設計的,而面向對象的程序設計則是基於對象的角度來考慮問題。這樣做能夠使得程序更加的簡潔清晰。
說明:編程中接觸最多的“面向對象編程技術”僅僅是面向對象技術中的一個組成部分。發揮面向對象技術的優勢是一個綜合的技術問題,不僅需要面向對象的分析,設計和編程技術,而且需要藉助必要的建模和開發工具。

17.構造函數能否成爲虛函數

  • 構造函數不能是虛函數。而且不能在構造函數中調用虛函數,因爲那樣實際執行的是父類的對應函數,因爲自己還沒有構造好。
  • 析構函數可以是虛函數,而且,在一個複雜類結構中,這往往是必須的。析構函數也可以是純虛函數,但純虛析構函數必須有定義體,因爲析構函數的調用是在子類中隱含的。
  • 說明:虛函數的動態綁定特性是實現重載的關鍵技術,動態綁定根據實際的調用情況查詢相應類的虛函數表,調用相應的虛函數

18野指針產生的原因和避免方法

  • 情況一
    原因 指針變量聲明時沒有被初始化。
    解決辦法 指針聲明時初始化,可以是具體的地址值,也可讓它指向NULL。
  • 情況二
    原因 指針 p 被 free 或者 delete 之後,沒有置爲 NULL。
    解決辦法 指針指向的內存空間被釋放後指針應該指向NULL。
  • 情況三
    原因 指針操作超越了變量的作用範圍。
    解決辦法 在變量的作用域結束前釋放掉變量的地址空間並且讓指針指向NULL。
  • 注意 “野指針”的解決方法也是編程規範的基本原則,平時使用指針時一定要避免產生“野指針”,在使用指針前一定要檢驗指針的合法性.

19.常考代碼

1.排序:快拍,冒泡,shell
2.單雙鏈表:
3.計算二叉樹的深度
4.二叉樹的增刪查改
5.查找數組裏面第幾大的數
6.判斷字符串是否相等
7.字符串的複製

20.鏈表和數組什麼區別

>指針和數組區別
  • 數組要麼在靜態存儲區被創建(如全局數組),要麼在棧上被創建。指針可以隨時指向任意類型的內存塊。
    用運算符sizeof 可以計算出數組的容量(字節數)。sizeof§,p 爲指針得到的是一個 指針變量的字節數,而不是p 所指的內存容量。C++/C 語言沒有辦法知道指針所指的內存容量,除非在申請內存時記住它。注意當數組作爲函數的參數進行傳遞時,該數組自動退化爲同類型的指針。

數組和鏈表有以下不同:
(1)存儲形式:數組是一塊連續的空間,聲明時就要確定長度。鏈表是一塊可不連續的動態空間,長度可變,每個節點要保存相鄰結點指針;
(2)數據查找:數組的線性查找速度快,查找操作直接使用偏移地址。鏈表需要按順序檢索結點,效率低;
(3)數據插入或刪除:鏈表可以快速插入和刪除結點,而數組則可能需要大量數據移動;
(4)越界問題:鏈表不存在越界問題,數組有越界問題。

21、堆棧溢出一般是由什麼原因導致的?
答 :1.沒有回收垃圾資源
2.層次太深的遞歸調用

22、不能做switch()的參數類型
答 :switch的參數不能爲實型(float double之類的)。

2.網絡編程部分

1、TCP與UDP的區別

  • TCP:是面向連接的流傳輸控制協議,具有高可靠性,確保傳輸數據的正確性,有驗證重發機制,不會出現丟失或亂序。

  • UDP:是無連接的數據報服務,不對數據報進行檢查與修改,無須等待對方的應答,會出現分組丟失、重複、亂序,但具有較好的實時性,UDP段結構比TCP的段結構簡單,因此網絡開銷也小
    2、流量控制和擁塞控制

  • 擁塞控制
    網絡擁塞現象是指到達通信子網中某一部分的分組數量過多,使得該部分網絡來不及處理,以致引起這部分乃至整個網絡性能下降的現象,嚴重時甚至會導致網絡通信業務陷入停頓,即出現死鎖現象。擁塞控制是處理網絡擁塞現象的一種機制。

  • 流量控制
    數據的傳送與接收過程當中很可能出現收方來不及接收的情況,這時就需要對發方進行控制,以免數據丟失。

3. tcp連接建立的時候3次握手,斷開連接的4次握手的具體過程

  • 建立連接採用的3次握手協議,具體是指:
    第一次握手是客戶端connect連接到server,server accept client的請求之後,向client端發送一個消息,是第二次握手,第3次握手就是client向server發送的,就是對第二次握手消息的確認。之後client和
    server就開始通訊了。
  • 斷開連接的4次握手,具體如下:
    斷開連接的一端發送close請求是第一次握手,另外一端接收到斷開連接的請求之後需要對close進行確認,發送一個消息,這是第二次握手,發送了確認
    消息之後還要向對端發送close消息,要關閉對對端的連接,這是第3次握手,而在最初發送斷開連接的一端接收到消息之後,進入到一個很重要的狀態
    time_wait狀態,最後一次握手是最初發送斷開連接的一端接收到消息之後對消息的確認。

4、epoll與select的區別

  • select在一個進程中打開的最大fd是有限制的,由FD_SETSIZE設置,默認值是2048。不過
  • epoll則沒有這個限制,它所支持的fd上限是最大可以打開文件的數目,這個數字一般遠大於2048,一般來說內存越大,fd上限越大,1G內存都能達到大約10w左右。
  • select的輪詢機制是系統會去查找每個fd是否數據已準備好,當fd很多的時候,效率當然就直線下降了,epoll採用基於事件的通知方式,一旦某個fd數據就緒時,內核會採用類似callback的回調機制,迅速激活這個文件描述符,而不需要不斷的去輪詢查找就緒的描述符,這就是epoll高效最本質的原因。
  • 無論是select還是epoll都需要內核把FD消息通知給用戶空間,如何避免不必要的內存拷貝就很重要,在這點上,epoll是通過內核於用戶空間mmap同一塊內存實現的,而select則做了不必要的拷貝.

5、epoll中et和lt的區別與實現原理

  • LT:水平觸發,效率會低於ET觸發,尤其在大併發,大流量的情況下。但是LT對代碼編寫要求比較低,不容易出現問題。LT模式服務編寫上的表現是:只要有數據沒有被獲取,內核就不斷通知你,因此不用擔心事件丟失的情況。
  • ET:邊緣觸發,效率非常高,在併發,大流量的情況下,會比LT少很多epoll的系統調用,因此效率高。但是對編程要求高,需要細緻的處理每個請求,否則容易發生丟失事件的情況。

6、多線程如何同步

Linux系統中多線程同步有最常用的是:互斥鎖、條件變量和信號量。
https://blog.csdn.net/qq_17308321/article/details/79929623

4、進程間通訊的方式及優缺點

  • A、管道( pipe )
    管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用。進程的親緣關係通常是指父子進程關係。
  • B、有名管道
    有名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。
  • C、信號量( semophore )
    信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
  • D、消息隊列( message queue )
    消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。
  • E、信號 ( sinal )
    信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。
  • F、共享內存( shared memory)
    共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的IPC方式,它是 針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。
  • G、套接字( socket ) 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同及其間的進程通信。

優缺點

  • A、無名管道簡單方便,但侷限於單向通信的工作方式,並且只能在親緣進程之間實現管道的共享;有名管道雖然可以提供給任意關係的進程使用,但是由於其長期存在於系統之中,使用不當容易出錯
  • B、消息隊列可以不再侷限於父子進程,而允許任意進程通過共享消息隊列來實現進程間通信,並由系統調用函數來實現消息發送和接收之間的同步,從而使得用戶在使用消息緩衝進行通信時不再需要考慮同步問題。使用方便,但是信息的複製需要額外消耗CPU的時間,不適宜於信息量大或操作頻繁的場合。
  • C、共享內存針對消息緩衝的缺點改而利用內存緩衝區直接交換信息,無須複製,快捷、信息量大是其優點。但是共享內存的通信方式是通過將共享的內存緩衝區直接附加到進程的虛擬地址空間中來實現的。因此,進程之間的讀寫操作的同步問題操作系統無法實現,必須由各進程利用其他同步工具解決。另外,由於內存實體存在於計算機系統中,所以只能由處於同一個計算機系統中的諸進程共享,不能網絡通信。

5.信號量

信號量是用來解決進程間的同步與互斥問題的一種進程間通信機制,包括一個稱爲信號量的變量和在該信號量下等待資源的進程等待隊列,以及對信號量進行的兩個原子操作(P/V操作)。其中,信號量對應於某一種資源,取一個非負的整形值。信號量值(常用sem_id表示)指的是當前可用的該資源的數量,若等於0則意味着目前沒有可用的資源。

● P操作:如果有可用的資源(信號量值>0),則此操作所在的進程佔用一個資源(此時信號量值減1,進入臨界區代碼);如果沒有可用的資源(信號量值=0),則此操作所在的進程被阻塞直到系統將資源分配給該進程(進入等待隊列,一直等到資源輪到該進程)。
● V操作:如果在該信號量的等待隊列中有進程在等待資源,則喚醒一個阻塞進程;如果沒有進程等待它,則釋放一個資源(即信號量值加1)。

6.在瀏覽器中輸入 www.baidu.com 後執行的全部過程*
7.TCP 的可靠性如何保證?
TCP的可靠性是通過順序編號和確認(ACK)來實現的。
8.OSI

1、OSI的七層協議是
應用層、表示層、會話層、傳輸層、網絡層、物理鏈路層、物理層
1.1、TCP/IP分層(4層)
鏈路層、網絡層、運輸層、應用層
1.2、五層協議(5層)
物理層、數據鏈路層、網絡層、運輸層、應用層

9、分頁和分段有什麼區別(內存管理)?

段式存儲管理是一種符合用戶視角的內存分配管理方案。在段式存儲管理中,將程序的地址空間劃分爲若干段(segment),如代碼段,數據段,堆棧段;這樣每個進程有一個二維地址空間,相互獨立,互不干擾。段式管理的優點是:沒有內碎片(因爲段大小可變,改變段大小來消除內碎片)。但段換入換出時,會產生外碎片(比如4k的段換5k的段,會產生1k的外碎片)

頁式存儲管理方案是一種用戶視角內存與物理內存相分離的內存分配管理方案。在頁式存儲管理中,將程序的邏輯地址劃分爲固定大小的頁(page),而物理內存劃分爲同樣大小的幀,程序加載時,可以將任意一頁放入內存中任意一個幀,這些幀不必連續,從而實現了離散分離。頁式存儲管理的優點是:沒有外碎片(因爲頁的大小固定),但會產生內碎片(一個頁可能填充不滿)。

兩者的不同點:

目的不同:分頁是由於系統管理的需要而不是用戶的需要,它是信息的物理單位;分段的目的是爲了能更好地滿足用戶的需要,它是信息的邏輯單位,它含有一組其意義相對完整的信息;

大小不同:頁的大小固定且由系統決定,而段的長度卻不固定,由其所完成的功能決定;

地址空間不同: 段向用戶提供二維地址空間;頁向用戶提供的是一維地址空間;

信息共享:段是信息的邏輯單位,便於存儲保護和信息的共享,頁的保護和共享受到限制;

內存碎片:頁式存儲管理的優點是沒有外碎片(因爲頁的大小固定),但會產生內碎片(一個頁可能填充不滿);而段式管理的優點是沒有內碎片(因爲段大小可變,改變段大小來消除內碎片)。但段換入換出時,會產生外碎片(比如4k的段換5k的段,會產生1k的外碎片)。

10、什麼是虛擬內存?
1).內存的發展歷程
  沒有內存抽象(單進程,除去操作系統所用的內存之外,全部給用戶程序使用) —> 有內存抽象(多進程,進程獨立的地址空間,交換技術(內存大小不可能容納下所有併發執行的進程)
)—> 連續內存分配(固定大小分區(多道程序的程度受限),可變分區(首次適應,最佳適應,最差適應),碎片) —> 不連續內存分配(分段,分頁,段頁式,虛擬內存)
2).虛擬內存
  虛擬內存允許執行進程不必完全在內存中。虛擬內存的基本思想是:每個進程擁有獨立的地址空間,這個空間被分爲大小相等的多個塊,稱爲頁(Page),每個頁都是一段連續的地址。這些頁被映射到物理內存,但並不是所有的頁都必須在內存中才能運行程序。當程序引用到一部分在物理內存中的地址空間時,由硬件立刻進行必要的映射;當程序引用到一部分不在物理內存中的地址空間時,由操作系統負責將缺失的部分裝入物理內存並重新執行失敗的命令。這樣,對於進程而言,邏輯上似乎有很大的內存空間,實際上其中一部分對應物理內存上的一塊(稱爲幀,通常頁和幀大小相等),還有一些沒加載在內存中的對應在硬盤上,如圖5所示。
注意,請求分頁系統、請求分段系統和請求段頁式系統都是針對虛擬內存的,通過請求實現內存與外存的信息置換。
3). 頁面置換算法

FIFO先進先出算法:在操作系統中經常被用到,比如作業調度(主要實現簡單,很容易想到);

LRU(Least recently use)最近最少使用算法:根據使用時間到現在的長短來判斷;

LFU(Least frequently use)最少使用次數算法:根據使用次數來判斷;

OPT(Optimal replacement)最優置換算法:理論的最優,理論;就是要保證置換出去的是不再被使用的頁,或者是在實際內存中最晚使用的算法。
4). 虛擬內存的應用與優點

虛擬內存很適合在多道程序設計系統中使用,許多程序的片段同時保存在內存中。當一個程序等待它的一部分讀入內存時,可以把CPU交給另一個進程使用。虛擬內存的使用可以帶來以下好處:

  • 在內存中可以保留多個進程,系統併發度提高
  • 解除了用戶與內存之間的緊密約束,進程可以比內存的全部空間還大

11、顛簸

顛簸本質上是指頻繁的頁調度行爲,具體來講,進程發生缺頁中斷,這時,必須置換某一頁。然而,其他所有的頁都在使用,它置換一個頁,但又立刻再次需要這個頁。因此,會不斷產生缺頁中斷,導致整個系統的效率急劇下降,這種現象稱爲顛簸(抖動)。

內存顛簸的解決策略包括:

  • 如果是因爲頁面替換策略失誤,可以修改替換算法來解決這個問題;
  • 如果是因爲運行的程序太多,造成程序無法同時將所有頻繁訪問的頁面調入內存,則要降低多道程序的數量;
  • 否則,還剩下兩個辦法:終止該進程或增加物理內存容量。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章