感覺牛客網的整理有丟丟凌亂
● 請你來說一下map和set有什麼區別,分別又是怎麼實現的?
map和set都是c++的關聯容器,其底層實現都是紅黑樹(rb-tree)。
map和set區別在於:
(2)set的迭代器是const的,不允許修改元素的值;map允許修改value,但不允許修改key。其原因是因為map和set是根據關鍵字排序來保證其有序性的,如果允許修改key的話,那麼首先需要刪除該鍵,然後調節平衡,再插入修改後的鍵值,調節平衡,如此一來,嚴重破壞了map和set的結構,導致iterator失效,不知道應該指向改變前的位置,還是指向改變後的位置。所以stl中將set的迭代器設定成const,不允許修改迭代器的值;而map的迭代器則不允許修改key值,允許修改value值。
(3)map支援下標操作,set不支援下標操作。map可以用key做下標,map的下標運算子[ ]將關鍵碼作為下標去執行查詢
(4)set適用:有序無重複的集合,map適用:有序鍵值對不重複的對映
● 請你來介紹一下stl的allocator參考
我不知道的東西太多了,,,
new將記憶體分配和物件構造組合在了一起,
delete將物件析構和記憶體釋放組合在了一起.
標準庫中allocator的類,允許我們將分配和初始化分離。使用allocator通常會提供更好的效能和更靈活的記憶體管理能力。
stl allocator將兩個階段操作區分開來:記憶體配置有allocate()負責,記憶體釋放由deallocate()負責;
物件構造由construct()負責,物件析構由destroy()負責。
● 請你來說一說stl迭代器刪除元素
參考1參考2
1.對於序列容器vector,deque來說,刪除當前的iterator會使後面所有元素的iterator都失效。這是因為vector,deque使用了連續分配的記憶體,刪除乙個元素導致後面所有的元素會向前移動乙個位置。不過erase方法可以返回下乙個有效的iterator。
2.對於關聯容器map set來說,使用了erase(iterator)後,當前元素的迭代器失效,但是其結構是紅黑樹,刪除當前元素的,不會影響到下乙個元素的迭代器,只要在erase時,遞增當前的iterator即可。
3.對於list來說,它使用了不連續分配的記憶體,並且它的erase方法也會返回下乙個有效的iterator,因此上面兩種正確的方法都可以使用。
list是由雙向鍊錶實現的,因此記憶體空間是不連續的。
● 請你說一說stl中map資料存放形式參考
map: map內部實現了乙個紅黑樹(紅黑樹是非嚴格平衡二叉搜尋樹),紅黑樹具有自動排序的功能,因此map內部的所有元素都是有序的,紅黑樹的每乙個節點都代表著map的乙個元素。因此,對於map進行的查詢,刪除,新增等一系列的操作都相當於是對紅黑樹進行的操作。map中的元素是按照二叉搜尋樹儲存的,使用中序遍歷可將鍵值按照從小到大遍歷出來。
unordered_map: unordered_map內部實現了乙個雜湊表,因此其查詢速度非常的快(也叫雜湊表,通過把關鍵碼值對映到hash表中乙個位置來訪問記錄,查詢的時間複雜度可達到o(1),其在海量資料處理中有著廣泛應用)。因此,其元素的排列順序是無序的。
● 請你講講stl有什麼基本組成
stl主要由:以下幾部分組成:
容器、迭代器、仿函式、演算法、分配器、介面卡
分配器給容器分配儲存空間
演算法通過迭代器獲取容器中的內容
仿函式可以協助演算法完成各種操作
介面卡是用來修改其他元件介面的stl元件
● 請你說說stl中map與unordered_map
● 請你說一說vector和list的區別,應用,越詳細越好
參考
區別vector
list
底層結構
動態順序表——陣列,在記憶體中是一段連續的空間。
雙向鍊錶,在記憶體中不是一段連續的空間
隨機訪問
vector支援隨機訪問,可以利用下標精準定位到乙個元素上,訪問某個元素的時間複雜度是o(1)。
list不支援隨機訪問,時間複雜度是o(n)。
插入vector一次性分配好記憶體,不夠時才進行2倍擴容
考慮插入的位置和是否擴容
在新增資料的時候,就要分配一塊更大的記憶體,vector是以2倍的方式擴容的,將原來的資料複製過來,釋放之前的記憶體,在插入新增的元素;
list每次插入新節點都會進行記憶體申請。
不需要搬移元素,只需要改變插入或刪除位置的前後兩個節點的指向即可,時間複雜度為o(1)。
刪除考慮刪除的位置——記憶體拷貝
不需要搬移元素,只需要改變插入或刪除位置的前後兩個節點的指向即可,時間複雜度為o(1)。
● 請你來說一下stl中迭代器的作用,有指標為何還要迭代器
1、迭代器
iterator(迭代器)用於提供一種方法順序訪問乙個聚合物件中各個元素, 而又不需暴露該物件的內部表示。或者這樣說可能更容易理解:iterator模式是運用於聚合物件的一種模式,通過運用該模式,使得我們可以在不知道物件內部表示的情況下,按照一定順序(由iterator提供的方法)訪問聚合物件中的各個元素。
2、迭代器和指標的區別
迭代器不是指標,是類模板,表現的像指標。他只是模擬了指標的一些功能,通過過載了指標的一些操作符,->、*、++、--等。
迭代器封裝了指標,是乙個可遍歷stl( standard template library)容器內全部或部分元素」的物件
迭代器返回的是物件引用而不是物件的值,所以cout只能輸出迭代器使用*取值後的值而不能直接輸出其自身。
● 請你說一說epoll原理
linux完全的知識盲區,,,參考
1. epoll_create:建立乙個epoll物件(在epoll檔案系統中給這個控制代碼分配資源);
2. 呼叫epoll_ctl:可以向epoll控制代碼新增或者刪除要監聽的檔案控制代碼
3.epoll_wait:等待事件發生了
● n個整數的無序陣列,找到每個元素後面比它大的第乙個數,要求時間複雜度為o(n)
參考 需要借用乙個棧stack
vectorfunc(vectornum){
if(num.size()==0) return num;
vectorres(num.size());
stacks;
int i=0;
while(i● 請你回答一下stl裡resize和reserve的區別參考
resize():改變當前容器內含有元素的數量
eg: vectorv; v.resize(len);v的size變為len,如果原來v的size小於len,那麼容器新增(len-size)個元素,元素的值為預設為0.當v.push_back(3);之後,則是3是放在了v的末尾,即下標為len,此時容器是size為len+1;
reserve():改變當前容器的最大容量,它不會生成元素,只是確定這個容器允許放入多少物件如果reserve(len)的值大於當前的capacity(),那麼會重新分配一塊能存len個物件的空間,然後把之前v.size()個物件通過copy construtor複製過來,銷毀之前的記憶體;
牛客網 C 面試寶典 基礎知識(3)
如果同時定義了兩個函式,乙個帶const,乙個不帶,會有問題嗎?不會,這相當於函式的過載。請你來說一說隱式型別轉換參考 對於內建型別,低精度的變數給高精度變數賦值會發生隱式型別轉換 可以用單個形參來呼叫 的建構函式定義了從 形參型別 到 該類型別 的乙個隱式轉換。說說你了解的型別轉換 const c...
C 面試寶典 C 基礎知識
1.c 和c的區別 設計思想上 c 是物件導向的語言,而c是面向過程的結構化程式設計語言 語法上 c 具有封裝 繼承 多型三種特性 c 相比於c,增加多許多態別安全的功能,比如強制轉換 c 支援正規化,比如模板類 函式模板等 2.野指標是什麼?3.說一下static關鍵字的作用?1.全域性靜態變數 ...
牛客網 C 面試寶典 作業系統(2)
1 互斥鎖和讀寫鎖區別 互斥鎖 mutex,用於保證在任何時刻,都只能有乙個執行緒訪問該物件。當獲取鎖操作失敗時,執行緒會進入睡眠,等待鎖釋放時被喚醒。讀寫鎖 rwlock,分為讀鎖和寫鎖。處於讀操作時,可以允許多個執行緒同時獲得讀操作。但是同一時刻只能有乙個執行緒可以獲得寫鎖。其它獲取寫鎖失敗的執...