SGI STL面試題總結

decltype:取expression的類型

常用數據結構

STL的使用和背後數據結構,vector string map set(RB-Tree) 和hash_map,hash_set(Hash函數)

deque:重點考察去push_back() push_front() erase() insert()函數的實現過程;
string
vector
set<int, greater<int> >:可以用set來實現最大堆和最小堆。
multiset
map
multimap
unordered_set
unordered_map 1) splice
list(劍指offer,p230):它是環狀雙向鏈表;

int LastRemaining(unsigned int n, unsigned int m){
    if(n < 1 || m < 1)
        return -1;
    unsigned int i = 0;
    std::list<int> numbers;
    for(int i = 0;i < n; i++)
        numbers.push_back(i);
    std::list<int>::iterator current = numbers.begin();
    while(numbers.size() > 1){
        for(int i =0;i < m; ++i){
            current++;
            if(current == numbers.end())
                current = numbers.begin();
        }
        std::list<int>::iterator next = ++current;
        if(next == numbers.end())
            next = numbers.begin();
        --current;
        numbers.erase(current);
        current = next;
    }
    return *(current);
}


priority_queue
關於heap的四個函數:必須是隨機迭代器(vector, deque)
http://blog.csdn.net/morewindows/article/details/6967409

STL中的容器都有哪些,優缺點?
介紹一下STL,詳細說明STL如何實現vector。

STL(標準模板庫)可分爲容器(containers)、迭代器(iterators)、空間配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函數(functors)六個部分。
STL (標準模版庫,Standard Template Library.它由容器、算法、迭代器組成。
STL有以下的一些優點:
可以方便容易地實現搜索數據或對數據排序等一系列的算法;
調試程序時更加安全和方便;
即使是人們用STL在UNIX平臺下寫的代碼你也可以很容易地理解(因爲STL是跨平臺的)。
vector實質上就是一個動態數組,會根據數據的增加,動態的增加數組空間。
deque從邏輯上來看是連續的內存,本質上是由一段段固定大小 的連續空間組成。deque採用類似索引的結構管理內存。
vector有capacity和reserve函數,deque和list一樣,沒有capacity和reserve函數。

總結如下:
1. 在deque中間 插入或者刪除將使所有deque元素的迭代器、引用、指針失效
2. 在deque首部或者尾部插入元素會使迭代器失效,但不會引起引用和指針失效
3. 在其首部或尾部刪除元素則只會使指向被刪除元素的迭代器失效

vector模板的數據在內存中連續的排列,所以隨機存取元素(即通過[]運算符存取)的速度最快,這一點和數組是一致的。同樣由於它的連續排列,所以它在除尾部以外的位置刪除或添加元素的速度很慢,在使用vector時,要避免這種操作。
list模板的數據是鏈式存儲,所以不能隨機存取元素。它的優勢在於任意位置添加 刪除元素的速度。
deque模板是通過鏈接若干片連續的數據實現的,所以均衡了以上兩個容器的特點

一個改錯題:http://blog.csdn.net/yahohi/article/details/7552025

題目感覺很無聊,注意,puch_back()調用ctor, pop_back()調用dtor


hash_map(非標準的)和map的區別在哪裏?
構造函數。hash_map需要hash函數,等於函數;map只需要比較函數(小於函數).
存儲結構。hash_map採用hash表存儲,map一般採用紅黑樹(RB Tree)實現。因此其memory數據結構是不一樣的。

基本功:C++ 棧的實現(STL:stack 利用deque實現)(別忘了,default cotor, copy cotor, assignment cotor)


c++中的多線程:跟具體操作系統有關,如windows和Linux;在C++裏面,對多線程的支持由具體操作系統提供的函數接口支持。


用過智能指針嗎,智能指針能放在容器裏面嗎?

智能指針是怎麼實現的,你來實現一個智能指針。在構造函數裏進行指針賦值,析構裏delete。其實還有很多的,比如實現get方法,拷貝構造函數、賦值運算符行爲。(shared_ptr<>)

// 自動管理一個int* p
class U_Ptr{
    friend class HasPtr;
    int *ip;
    size_t use;
    U_Ptr(int *p):ip(p),use(1){}
    ~U_Ptr(){delete ip;}
};
class HasPtr{
public:
    HasPtr(int *p, int i):ptr(new U_Ptr(p)), val(i){}
    HasPtr(const HasPtr &orig):ptr(orig.ptr),val(orig.val){
        ptr->use++;
    }
    HasPtr& operator=(const HasPtr& rhs){
        if(rhs != *this){
            rhs.ptr->use++;
            if(--ptr->use == 0)
                delete ptr;
            ptr = rhs.ptr;
            val = rhs.val;
            return *this;
        }
    }
    ~HasPtr(){
        if(--ptr->use == 0)
            delete ptr;
    }
private:
// 自身有管理功能。即使這個對象delete了,但是ptr指向的東西還在。
    U_Ptr *ptr; 
    int val;
};

如果是多線程環境下,必須加入鎖機制,



包括stl中實現了那些排序算法(不是僅僅是quicksort,是個混合算法,quicksort+heapsort+insertsort)
爲什麼用仿函數(爲了配合STL 算法用的,可以實現一般化的算法),不用函數指針(爲什麼不用函數指針呢?因爲不能滿足STL對抽象性的要求,無法和STL其他組件搭配,如適配器adapter)
配接器:包括三個:容器適配器,迭代器適配器,仿函數適配器。
一元、二元仿函數的區別(操作數爲幾個)和使用情景。

STL容器的參數allocate是用來做什麼的?
答:一般用在容器中,作爲容器的一個成員,但一般是用模版參數傳入,這樣纔可以讓我們換成我們自定義的allocator;分配器用於封裝STL容器在內存管理上的低層細節。

Map的Key有什麼要求?
答:http://blog.csdn.net/xiexievv/article/details/8611763 可複製和可賦值,還要可比較(operator <)。

C++的string拷貝構造是深拷貝還是淺拷貝?

答:如果不是深拷貝,那麼肯定是不對的(舉例子),所以肯定是深拷貝。


auto_ptr(實現)與shared_ptr的不同,shared_ptr線程不安全,問我如何解決線程安全,我說對引用計數操作加鎖,然後要我寫下線程安全的shared_ptr的reset成員函數,唐在這他提示我當引用計數到0後,析夠是在鎖外還在鎖內,我簡單寫了代碼,然後他又問我加鎖的代價

auto_ptr缺陷:通過復構造函數,通過操作符=賦值後,原來的那個智能指針對象就失效了.只有新的智能指針對象可以有效使用了(所有權的轉移)。

auto_ptr實現:

/**
    下面的就是auto_ptr的實現細節
*/
template<typename T>
class auto_ptr{
public:
        //使用explicit關鍵字避免隱式轉換
        explicit auto_ptr(T* p=0);
        ~auto_ptr();

        //使用另一個類型兼容的auto_ptr來初始化一個新的auto_ptr
        template<typename U>
        auto_ptr(auto_ptr<U>& rhs);

        template<typename U>
        auto_ptr<T>& operator=(auto_ptr<U>& rhs);

        T& operator*() const;
        T* operator->() const;

        //返回原始對象的指針
        T* get() const;
        //放棄指針的所以權
        T* release();
        //刪除原有指針並獲得指針的p的所有權
        void reset(T* p=0);
private:
        T* pointee;
};

template<typename T>
auto_ptr<T>::auto_ptr(T* p)
    :pointee(p){}

template<typename T>
auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
    :pointee(rhs.release()){}

template<typename T>
auto_ptr<T>::~auto_ptr(){
    delete pointee;
}

template<typename T>
auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs){
    if(this!=&rhs)
        reset(rhs.release());
    return *this;
}

template<typename T>
T& auto_ptr<T>::operator*() const{
    return *pointee;
}

template<typename T>
T* auto_ptr<T>::operator->() const{
    return pointee;
}

template<typename T>
T* auto_ptr<T>::get() const{
    return pointee;
}

template<typename T>
T* auto_ptr<T>::release(){
    T* oldpointee=pointee;
    pointee=0;
    return oldpointee;
}

template<typename T>
void auto_ptr<T>::reset(T* p){
    if(pointee!=p){
        delete pointee;
        pointee=p;
    }
}

仿函數:即函數對象,就是自定義(重載)function call運算子(operator() ),那麼我們就可以調用了,greater<int> ig;

#include<functional>
#include<iostream>
using namespace std;
int main(){
    greater<int> ig;
    cout << boolalpha << ig(4,6) << endl;
    return 0;
}

STL仿函數按操作數分爲一元和二元仿函數,以功能劃分,可分爲算術運算,關係運算,邏輯運算三大類。他的最主要用途是爲了搭配STL算法。

一元仿函數

template<class Arg, class Result>
struct unary_function{
    typedef Arg     argument_type;
    typedef Result  result_type;
};
template<class T>
struct negate:public unary_function<T,T>{
    T operator()(const T& x)const{return -x;}
};


Iterator(迭代器)用於提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示,相當於智能指針。包括Input Iterator, Output Iterator, Forward Iterator, Bidirectional Iterator, Random Access Iterator.


空間配置器(allocator)


一個簡單的空間配置器,JJ::allocator(《STL源碼解析》,p44)

重點講解SGI STL的內存池機制。


STL線程安全問題(有用:http://www.cppblog.com/baby-fly/archive/2009/10/24/99369.html)

多線程編程,需要加鎖機制


STL各個版本比較?

常見一共三個版本

SGI STL,技術比較新,很規範

一個是Visual C++裏的STL,作者P.J. Plauger,所以一般也說pj stl。






寫了三個類A、B、C,B、C均繼承自A,均有虛函數f,然後定義了3個指針,讓我畫下虛表,虛表放在哪裏?(http://blog.csdn.net/xhu_eternalcc/article/details/22274489)這是陳皓的一篇博客,講的很好。


邏輯推理題:問101個硬幣,有一個是假的,重量同真的不一樣,給你一個天平,讓你用最少的次數稱出假幣是重還是輕。??

只需兩次,真的是太巧妙啦。50-50 25-25


線程和進程的區別,還有就是什麼時候用線程,什麼時候用進程(http://blog.csdn.net/wang_8910/article/details/6384061)

虛繼承的作用:
通過虛繼承可以共享其虛基類,對於給定虛基類,無論該類在派生層中作爲虛基類多少次,值繼承一個共享的基類子對象;


C++中的異常可不可以是引用?
答:異常可以是引用,並且效率高。



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