面試點滴

語言面試題

#include <iostream>

using namespace std;

class A
{
public:
    A() : m_ival(0)
    {
        test();
    }

    virtual void func()
    {
        cout << m_ival << endl;
    }

    void test()
    {
        func();
    }

public:
    int m_ival;
};

class B : public A
{
public:
    B()
    {
        test();
    }

    void func()
    {
        ++ m_ival;
        cout << m_ival << endl;
    }
};

int main()
{
    A* p = new B;

    p->test();
    
    delete p;

    return 0;
}
問 1:分析下面的程序,給出運行結果

輸出:ios

0
1
2
問 二 :在子類與父類構造函數中都調用test(), 那麼編譯器是怎麼肯定應該調用的哪一個 func() 函數版本呢?

相關概念:面試

  • 構造函數未結束前,虛函數表未初始化完成,所以不能發生多態
  • 動態聯編不等價於多態:
    動態聯編:編譯原理中的概念
    多 態:面向對象理論。 C++ 編譯器在實現面向對象的多態時,使用動態聯編的概念

發生了什麼?算法

  • 在構造 A 部分時:函數

    • 在構造 A 部分時,回去構造 A 部分的虛函數表。在執行 A 的構造函數的函數體時,虛函數表是【完整】的
    • 在 A 的構造函數中調用 Func(), 發生動態聯編,查找虛函數表獲得具體函數地址
    • A 中的 Func 被調用

clipboard.png

  • 在構造 B 部分時:學習

    • 在構造 B 部分時,【虛函數表被更新】
    • 在 B 的構造函數中調用 Func(), 發生動態聯編,查找虛函數表獲得具體函數地址
    • B 中的 Func 被調用

clipboard.png

總結:spa

  • 在構造函數中,調用虛函數不會發生多態,但虛函數是動態聯編的
  • 虛函數的調用,都是經過查找虛函數表完成的
問 三:上述的代碼是否有其它問題?
  • 問題 1, 未判斷內存是否申請成功
  • 問題 2指針

    • A* p = new B; delete p;
    • A 類指針 p 指向 B 類對象,在 delete 時,析構函數不是虛函數,所以,編譯器就只會根據 p 的類型調用 A 類的析構函數, B 類的析構函數不會被調用!!!
要點
  • 面試官須要的不僅是「正確答案」
  • 面試官會想要知道應試者的解題思路
  • 面試官會從題中間「隨機抓取」細節進行追問
  • 面試官會把問題進行擴展(如:從語言擴展到編譯器)

算法面試題

HR 問:編寫代碼將一個鏈表反轉打印

面試者:須要思考的問題code

  • 這具體是一個什麼樣的鏈表(單鏈表?雙向鏈表?循環鏈表)
  • 鏈表中節點的數據是否容許改變
  • 時間複雜度有沒有要求
  • 。。。
struct Node
{
    int v;
    struct Node* next;
};
void reversse_display_list(struct Node* list)
{
    if( list )
    {
        reversse_display_list(list->next);

        printf("%d ", list->v);
    }
}
void reversse_display_list_stack(struct Node* list)
{
    if( list )
    {
        LinkStack<int> stack;

        while( list )   // O(n)
        {
            stack.push(list->v);

            list = list->next;
        }

        while( stack.size() > 0 )   // O(n)
        {
            printf("%d ", stack.top());

            stack.pop();
        }

        printf("\n");
    }
}
struct Node* reverse_list(struct Node* list) // O(n)
{
    if( list )
    {
        struct Node* guard = NULL;
        struct Node* next = list->next;

        while( next )
        {
            list->next = guard;
            guard = list;
            list = next;
            next = list->next;
        }

        list->next = guard;
    }

    return list;
}
要點
  • 面試不是筆試,面試考察的不僅是技術
  • 面試官須要全方位考察應試者(溝通,品質,態度)
  • 面試中儘可能與面試官交流,獲取解題的有用信息
  • 面試中儘可能寫出完整代碼,而不是紙上談兵的忽悠
  • 。。。

發散性思惟問題

不用加減乘除運算符作整數加法

面試者: 須要思考的問題對象

  • 面試官想考察什麼?
  • 加法的底層本質是什麼?
  • 是否能夠繞開 「+」 操做符的使用
  • 。。。
int add_1(int a, int b)
{
    int ret = 0;

    asm volatile
    (
         "movl %%eax, %%ecx\n"
         "addl %%ebx, %%ecx\n"
         : "=c"(ret)
         : "a"(a), "b"(b)
    );


    return ret;
}

int add_2(int a, int b)
{
    int part = 0;
    int carry = 0;

    do
    {
        part = a ^ b;
        carry = (a & b) << 1;

        a = part;
        b = carry;
    } while( b != 0 );

    return a;
}
要點
  • 不一樣公司對人才的要求是不一樣的
  • 一些公司會更看重應試者的可塑性
  • 學習,分析,思考能力是工做中必備的(面試須要考察)
  • 計算機系統底層原理的學習必不可少
  • 。。。
相關文章
相關標籤/搜索