某日二師兄參加XXX科技公司的C++工程師開發崗位第21面:
面試官:用過STL嗎?
二師兄:(每天都用好嗎。。)用過一些。
面試官:你知道STL是什麼?
二師兄:STL是指標準模板庫(
Standard Template Library
),是C++區別於C語言的特徵之一。面試官:那你知道STL的六大部件是什麼?
二師兄:分別是容器(
container
)、迭代器(iterator
)、介面卡(adaptor
)、分配器(allocator
)、仿函數(functor
)和演演算法(algorithm
)。面試官:那你知道有哪些容器嗎?
二師兄:STL中容器的數量比較多,按照型別可以分為順序容器和關聯容器。
二師兄:順序容器主要有
vector
、deque
、list
、forward_list
和array
。其中forward_list
和array
是C++11引入的。二師兄:關聯容器主要有
set
、map
、multiset
、multimap
、unordered_set
、unordered_map
、unordered_multiset
、unordered_multiamp
。其中後四種是C++11新引入的。面試官:好的。那你知道迭代器分為哪些種類嗎?
二師兄:分別是輸入迭代器(
Input Iterator
)、輸出迭代器(Output Iterator
)、前向迭代器(Forward Iterator
)、雙向迭代器(Bidirectional Iterator
)和隨機存取迭代器(Random Access Iterator
)。二師兄:其中輸入和輸出迭代器分別用於讀取和寫入資料,前向迭代器只能向前存取而不能向後存取(
forward_list
),雙向迭代器既可向前也可向後(list
),隨機存取迭代器可以通過下標存取任何合法的位置(vector
)。面試官:你知道介面卡是做什麼的嗎?
二師兄:介面卡是一種設計模式。主要起到將不同的介面統一起來的作用。STL中的容器介面卡如
stack
和queue
,通過呼叫容器的介面,實現介面卡所需的功能。面試官:有了解過分配器嗎?
二師兄:分配器主要用於記憶體的分配與釋放。一般容器都會自帶預設分配器,很少會自己實現分配器。
面試官:有使用分配器做一些記憶體分配的工作嗎?
二師兄:沒有。。。
面試官:知道仿函數是做什麼用的嗎?
二師兄:是一個可執行的物件,型別過載了
operator()()
運運算元。
struct Add
{
int operator()(int a, int b) {return a +b;}
}
int a = 42, b = 1024;
auto sum = Add()(a,b);
//OR
Add add;
auto sum = add(1,2);
面試官:STL中常見的演演算法有哪些?
二師兄:一般分為三類,查詢、排序和數值操作。
二師兄:查詢常用的有
std::find
、std::find_if
、std::find_first_of
等。二師兄:排序主要用
std::sort
及其家族的一系列演演算法。二師兄:數值操作主要用
std::accumulate
求和。面試官:那你知道STL六大部件之間的聯絡嗎?
二師兄:(想了想)不是特別清楚。。。
面試官:好的,回去等通知吧。
讓我們回顧一下二師兄的表現:
有使用分配器做一些記憶體分配的工作嗎?
這裡主要是問有沒有手寫過分配器:
template <typename T>
class MyAllocator {
public:
typedef T value_type;
MyAllocator() noexcept {}
template <typename U>
MyAllocator(const MyAllocator<U>&) noexcept {}
T* allocate(std::size_t n) {
if (n > std::size_t(-1) / sizeof(T)) throw std::bad_alloc();
if (auto p = static_cast<T*>(std::malloc(n * sizeof(T)))) return p;
throw std::bad_alloc();
}
void deallocate(T* p, std::size_t) noexcept {
std::free(p);
}
};
範例中定義了一個名為MyAllocator
的模板類,它過載了allocate
和deallocate
運運算元用於分配記憶體和釋放記憶體。範例中malloc
和free
函數來分配和釋放記憶體,也可以用new
和delete
。
我們可以在allocate
和deallocate
中做很多事情,比如我們可以統計申請和釋放記憶體的總量,可以申請一塊大記憶體做記憶體池等等。
知道STL六大部件之間的聯絡嗎?
這個問題比較開放,需要對STL六大部件有一定的理解。首先是分配器,主要是為容器分配管理記憶體的。其次是迭代器,是容器和演演算法的橋樑。再次是仿函數,一般用作演演算法中,介面卡提供各種粘合劑的功能,把不同部件之間的介面連線起來。
今天二師兄的面試就這些內容了,感謝小夥伴的耐心。二師兄的C++面試之旅,明天繼續。
關注我,帶你21天「精通」C++!(狗頭)