C++面試題面經

  1. STL.

    1. 順序性容器:元素間有順序關係的線性表。

      1. vector動態數組,線性結構,連續存儲,隨機訪問,檢索快,只能在後端添加刪除

      2. list雙向循環鏈表,不連續存儲,不支持隨機訪問,支持任意位置插入刪除

      3. deque雙向隊列,支持隨機 訪問,支持內部插入刪除

    2. 關聯式容器:非線性,包括二叉樹結構和哈希表結構。有排序功能

      1. set集合,元素值唯一,按序排列

      2. multiset多重集合,不要求元素唯一

      3. unordered_set

      4. map鍵值對,鍵唯一且有序。其按鏈表存儲。底層爲紅黑樹

      5. multimap,鍵可以不唯一

      6. unordered_map,鍵值對不根據key大小排序,無序,可以按插入順序建立哈希表

    3. 容器適配器:stack,queue,priority_queue

      1. stack棧,先進後出

      2. queue隊列,先進先出

      3. priority_queue

  • 二叉樹特例:堆和紅黑樹。

    • 堆分爲最大堆和最小堆,很多需要快速找到最大值或者最小值的問題都可以用堆來解決。

    • 紅黑樹是把樹種的節點定義爲紅,黑兩種顏色,並通過規則確保從根節點到葉節點的最長路徑的長度不超過最短路徑的兩倍

    • c++的STL中,set,multiset,map,multimap等數據結構都是基於紅黑樹實現的

        

  1. 虛函數virtual

    1. c++虛函數主要作用是“運行時多態”,父類中提供虛函數的實現,爲子類提供默認的函數實現

    2. 子類可以重寫父類的虛函數實現子類的特殊化。純虛函數“只提供聲明沒有實現”,是對子類的約束,是“接口繼承”

    3. 純虛函數被稱爲“抽象類”。抽象類不能使用new出對象,只有實現了這個純虛函數的子類才能new出對象

  1. set,map底層數據結構,紅黑樹的細節。map,m[1]="str";這句低層是怎麼實現的,發生了什麼

  2. b+樹的細節,查找過程

  3. 多態:多態性可以簡單概括爲一個接口,多種方法。通常是指對於同一個消息,同一種調用,在不同的場合不同情況下,執行不同的行爲

    1. 靜態多態性,包括函數重載,運算符重載

    2. 動態多態性,虛函數。c++通過虛函數實現動態聯編

    3. 基類函數爲virtual,子類派生也是virtual。

    4. 派生類要對虛函數重定義,應保持相同參數個數,相同參數類型,相同返回值類型

  4. 宏定義和替換: #define 標識符  字符串      #define  標識符(參數列表)   字符串。

    1. 編譯前進行,不分配空間

    2. 結尾不需要分號

  5. 文件包含:

    1. #include <standard_header>   <>表示標準頭文件。編譯器將會在預定義位置集合中查找頭文件

    2. #include "my_file.h"  非系統頭文件,通常從源文件所在路徑查找

  6. 全局變量和局部變量:

    1. 全局變量作用域全局,或用extern 表示

    2. 局部變量作用域部分,若與全局變量同名,屏蔽全局變量

  7. static作用

    1. 隱藏,當同事編譯多個文件時,所有未加static前綴的全局變量和函數都具有全局可見性。若加了static,會對其他源文件隱藏

    2. 默認初始化爲0

    3. 靜態局部變量生存週期爲整個源程序,但其作用域仍然與局部變量相同,只能在定義該變量的函數內使用該變量。退出函數後,該變量還存在,但不能使用

    4. 類中static作用:表示屬於一個類而不是屬於此類任何特定對象的變量和函數

      1. 靜態數據成員(靜態(全局)存儲區)

        1. static數據成員獨立於該類的任意對象而存在,只與該類關聯。當某類修改了靜態成員變量,修改值對其他所有實例所見

        2. static數據成員必須在類定義體的外部定義

        3. 非靜態成員在類對象中的排列順序和聲明順序一致,任何在其中間聲明的靜態成員都不會被放進對象佈局。靜態數據成員存放在程序的全局(靜態)存儲中,和個別類對象無關。

      2. 靜態成員函數:屬於類的一部分,爲整個類服務,不是爲某一對象服務

        1. 普通成員函數總是爲具體某個對象服務,因爲普通成員函數都隱含了一個this指針,this指針指向對象本身

        2. static成員函數不具有this指針,爲整個類服務。因而無法訪問屬於類對象的非靜態數據成員,也無法訪問非靜態成員函數,只能調用靜態成員和靜態成員函數

        3. static不是任何對象組成部分,所以static成員函數不能聲明爲const。將成員函數聲明爲const就承諾不會修改函數所屬的對象,而static不屬於任何對象

        4. 非靜態成員函數可以訪問靜態成員變量和靜態成員函數。靜態成員函數沒有this指針額外開銷,所以速度快些

  8. const常量,定義後無法修改,所以定義的時候必須初始化

    1. 全局作用域定義非const變量,在整個程序中都可以訪問

    2. 全局作用域聲明const變量是定義該對象的文件的局部變量,該變量只存在於當前變量中,不能被其他文件訪問。通過將const變更爲extern可以再整個程序中訪問、

    3. const代替#define的值替換功能

      1. const有數據類型,宏定義沒有

      2. const只會產生更小的目標哦代碼,因爲宏是直接替換

    4. 指針和const修飾符

      1. 指向const的指針:const double *p;  p是一個指針,指向const double,也就是p可以指向任何東西,但指向的東西是不能變的,是const

      2. const指針:使指針本身成爲一個const指針,必須吧const標明的部分放在*右邊; double d=1.0;  double * const p=&d;讀作p是指針,指向double 的const指針,指針本身是const,必須初始化,不能改變指向,但可以改變指向的值的內容。

    5. 修飾函數參數與返回值

      1. const修飾返回值:若返回值是值類型(非指針,引用),用不用const無所謂。若是返回指針類型。函數不能返回指向局部棧變量的指針,因爲在函數返回後它是無效的,棧也被清理了。可返回的指針是指向堆中分配的存儲空間的指針或指向靜態存儲區的指針,函數返回後它仍然有效

      2. const用來修飾函數的參數:用值傳遞,表示參數在函數內也不會修改

    6. const在類中的應用

      1. 類成員函數後面加const,爲了確保該函數成員可作用域const對象身上,表示const成員函數不能修改調用該函數的對象。const對象,指向const對象的指針或引用只能調用其const成員函數。

      2. const數據成員:常量成員變量必須在構造函數的成員初始化列表中進行初始化(必須有構造函數)。當 常量數據成員同時被聲明爲static時,此時可以使用外部 初始化。類可以創建多個對象,不同的對象其const數據成員的值可以不同,所以不能在類聲明時初始化const數據成員

  9. 內存管理與釋放:主要內存有:棧區,堆區,全局(靜態)存儲區,文字常量區,代碼區

    1. 堆和棧的區別:

      1. 棧區:類似於數據結構棧,編譯器自動分配釋放,存放函數的參數值,局部變量的值等。如函數中聲明一個局部變量int b;

      2. 堆區:程序員分配釋放,否則程序結束自動收回。分配方式類似於鏈表。速度慢,容易產生內存碎片,用起來方便。malloc,new在堆上分配空間

        1. char *p =(char*)malloc(10);   p本身在棧中,他們指向在堆上分配的內存。

  10. c++內存管理:malloc/free, new/delete

    1. int *p=new int;//無初始化    int *p=new int(); //p指向一個初始化爲0的int值

    2. const int *p = new const int(1024);  //動態創建的const對象必須在創建時初始化,並且一經初始化,其值就不能再修改。

    3. malloc/free與new/delete的區別

      1. 操作對象不同:malloc/free是c/c++的標準庫函數,new/delete是c++的運算符

        1. new執行過程是:先調用名爲operator new的標準庫函數,分配足夠大的原始未類型化的內存,以保存指定類型的一個對象;接下來運行該類型的一個構造函數,用於指定初始化式構造對象;最後返回指向新分配並構造的對象的指針

        2. delete的執行過程是:先對sp指向的對象運行適當的析構函數;然後通過調用名爲operator delete的標準庫函數釋放該對象所用內存

        3. 以上operator new與operator delete分別對應於malloc與free

      2. 用法上也不同

        1. malloc不識別需要申請的內存是什麼類型,只關心內存的總字節數。返回值是void*型,所以在調用malloc時要顯示轉換成所需要的類型

        2. free(p)用來釋放指針,如果p是NULL,對p釋放多少次都沒問題,若不是NULL,對p連續釋放兩次就會導致程序運行錯誤。

        3. 用new創建對象數組,只能使用對象的無參數構造函數,釋放對象數組時delete p[]。。obj *p=new obj[100](1);//創建100個動態對象的同時賦初始值1

      3. 不同之處總結如下:

        1. malloc與free是c/c++標準庫函數,new/delete是c++運算符

        2. new自動計算需要分配的空間,而malloc需要手工計算字節數

        3. new類型是安全的,malloc不是

        4. new調用operator new分配足夠空間,並調用相關對象的構造函數,而malloc不能調用構造函數;delete將調用該實例的析構函數,然後調用類的operator delete,以釋放該實例佔用的空間,而free不能調用析構函數

        5. malloc/free需要庫文件支持,new/delete不需要

  11. 引用:對象的另一個名字。c++規定一旦引用,就必須把它跟一個變量綁定起來,並不能修改這個綁定。引用不能爲空

    1. 成員初始化列表:c++中成員變量的初始化順序與變量在類型中的聲明順序相同,而與他們在構造函數的初始化列表中的順序無關

  12.  

底下是曠世面試的問題

虛函數是什麼原理,c++是如何實現多態的。

有沒有用過智能指針,智能指針的原理和作用。

STL當中的容器用過哪些,瞭解哪些都是什麼作用大概說下。

知道哈希函數麼,STL當中那個容器是哈希實現的哪個是紅黑樹實現的,具體的複雜度是多少。

給你一個對象你只知道他的類型,你也知道這個類型只有一個方法,但是你不知道這個方法的名稱,你該怎麼調用這個方法?

析構函數可以是虛函數麼?爲什麼要將析構函數設爲虛函數,可以將所有的析構函數設置爲虛函數麼?

 

以C++爲例,列出筆試一般會考的內容:

  • 語言基礎,C++中的定義,指針,模板,多態,重載等(尤其是多態,給定一個程序,基類子類有不同實現,考慮輸出結果,這一類的題目面試題極爲高頻)

  • TCP/IP協議及其編程:計算機網絡基礎,socket編程,其中子網劃分,七層協議(例如交換機屬於數據鏈路層一類題目),五層協議,協議名稱及其作用,常用端口號,https1.0 1.1特性與區別,三次握手四次揮手(可能出現的服務器攻擊),加密(對稱,非對稱),IO複用等

  • 操作系統:進程通信方式(linux/windows,每種方式的特點),線程通信(linux/windows),進程與線程區別,頁面置換策略(考察置換幾次),進程/線程狀態圖,進程調度方式,死鎖(必要條件,哲學家就餐,銀行家,讀者寫者問題)

  • 數據庫:索引作用,應該/不應該創建索引的列,索引底層實現,sql語法,常見引擎特點,事務特點,隔離級別(引擎默認級別),隔離級別的問題,鎖等

  • 智力題:大廠一般筆試面試喜歡出,重在考察思維能力,也是爲了選出潛力更大的人來。如果欠缺可以在牛客上刷題

  • 算法:劍指offer,leetcode,左神的書和視頻,任意兩個搞定都沒問題

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