天天看點

簡記微軟實習生面試

26号下午,收到了微軟的電話,内容很簡單,說我們看到了你的履歷,希望明天見面聊聊。我問位址,他說微軟研究院自己查吧,很好找...說話很可親,聊聊嘛

首先介紹下自己:小碩,2015年畢業,北郵,模式識别方向,大學是學通信的,計算機初等水準吧,熟練使用C++,了解STL吧,C#/Java/Python/R也都用過,面比較廣,碼農低等水準,複雜的算法看懂就不錯了...(文章長些,不喜勿噴)

2014年剛開學,實驗時開學後沒什麼任務,年假裡看了些安卓的書,于是花費5天用Andengine開發了一款小遊戲,純屬自娛自樂了,“暗獸器”(象獅虎豹那種)。2月20号的時候,師兄要收履歷說幫阿裡巴巴内推實習,頓時就感覺慌了,什麼知識也沒有準備,劣性不該,想幹什麼做什麼…匆忙做了份履歷發給了師兄。24号的時候發現論壇上微軟招實習生的消息,軟體開發,履歷也都有了就投了一份,然後生活照舊,寫寫程式,看看書,還有實驗室的小活。

26号下午,收到了微軟的電話,内容很簡單,說我們看到了你的履歷,希望明天見面聊聊。我問位址,他說微軟研究院自己查吧,很好找...說話很可親,聊聊嘛,我說時間可以,然後就屁颠地挂了電話,繼續寫實驗室的層次聚類的一個程式。吃完晚飯,感覺明天就要面試了,第一次找實習還是很緊張的,好好準備下吧,看看C++準備點什麼,于是先上網搜了下别人的面經,頓時就吓壞了,看到了這個:

http://blog.csdn.net/uestcleo/article/details/7556364;

還看到了這個:

http://topic.yingjiesheng.com/mianshi/jingyan/2012/0420/422268.html,

等等吧,看完後精神頓時高漲了很多,心裡那個委屈啊(大學我怎麼沒學計算機了,學那些大學實體、電磁場、高頻什麼的現在也用不到啊),總之,還沒去感覺自己就要挂了,主要是我還什麼也沒準備呢,開學一直沒想這事啊。趕快指定了計劃:看遍以前的C++筆記、看完資料結構(查找和圖有幾節沒學)、看點作業系統吧,忙碌了一晚上,第二天中午又繼續看了3個小時,又分析了下上面那些網頁裡的微軟面試題。看着就害怕...下午1點就硬着頭皮出發了。

到微軟1點50多,在前台等了一會,來了個技術人員(一面面試官)把我帶了進去,17樓,出樓梯,說等會,我去那套題...,看來真不是隻聊聊,被電話騙了吧。找了個房間,遞給我題,面試官說你做着,20分鐘我過來,說着他看看表:诶,正好2點整。我也看了下表,咦,這不明明是2:02嘛。。。看看卷子20分鐘15道題,隻有一個想法了:挂了。

說一下題目吧,整個試卷是以C#為主吧,可能每個部門不一樣,但能感覺出來C#都很基礎,不難,隻要真正學過C#的(不要像我隻在C#中寫過點處理程式),了解下C#的底層,至少4道題應該沒問題。話說回來,可惜我沒真正學過,C#的還有ASP.NET的我就直接放棄了,隻回答了下C++中知道的,當然最後C#的也蒙了點。

1.抽象類和接口的差別?

    1、抽象類是類,它的子類不能再繼承其它類了,但可以實作一個和多個接口。接口不是類,它的子接口可以繼承多個接口。 

    2、抽象類中是可以有不用abstract修飾的方法,而接口中隻能有抽象方法,即方法都要用abstract修飾。 

    3、抽象類可以實作接口,而接口是不能繼承或實作抽象類的。

2.程序和線程的差別和關系?

程序是資源配置設定的基本機關,線程基本上不擁有資源;線程是程式執行的基本機關,程序建立時一般隻有一個線程,需要時可由這個線程建立其他線程;一個程序可以有多個線程,它們共享程序資源,在程序的空間中并發活動。

3.UDP和TCP協定的差別?

TCP是面向連接配接的,可靠傳輸,适于傳輸大量資料;UDP是面向非連接配接的不可靠傳輸,适于小量資料的傳輸。

4.異步的概念和實作方式?

當一個異步過程調用發出後,調用者不能立刻得到結果。實際處理這個調用的部件在完成後,通過狀态、通知和回調來通知調用者。

執行部件和調用者通過三種途徑傳回結果:狀态、通知和回調。可以使用哪一種依賴于執行部件的實作,除非執行部件提供多種選擇,否則不受調用者控制。如果執行部件用狀态來通知,那麼調用者就需要每隔一定時間檢查一次,效率就很低(有些初學多線程程式設計的人,總喜歡用一個循環去檢查某個變量的值,這其實是一種很嚴重的錯誤)。如果是使用通知的方式,效率則很高,因為執行部件幾乎不需要做額外的操作。至于回調函數,其實和通知沒太多差別。

5. .NET的記憶體回收機制?

每次當開發人員使用 new 運算符建立對象時,運作庫都從托管堆為該對象配置設定記憶體。新建立的對象被放在上次建立的對象之後。垃圾回收器儲存了一個指針,該指針總是指向托管堆中最後一個對象之後的記憶體空間。

當垃圾回收器的指針指向托管堆以外的記憶體空間時,就需要回收記憶體中的垃圾了。在這個過程中,垃圾回收器首先假設在托管堆中所有的對象都需要被回收。然後它在托管堆中尋找被根對象引用的對象(根對象就是全局,靜态或處于活動中的局部變量以及寄存器指向的對象),找到後将它們加入一個有效對象的清單中,并在已經搜尋過的對象中尋找是否有對象被新加入的有效對象引用。直到垃圾回收器檢查完所有的對象後,就有一份根對象和根對象直接或間接引用了的對象的清單,而其它沒有在表中的對象就被從記憶體中回收。

6.堆和棧的差別?

棧區由編譯器自動配置設定釋放,存放函數的參數值,局部變量的值等。堆區一般由程式員配置設定釋放, 若程式員不釋放,程式結束時可能由OS回收 。

C#中值類型存放在堆棧中,引用類型存放在托管堆上。

7.泛型的概念和泛型類型

這裡問的應該是C#的,我不太了解,回答的C++的泛型程式設計:通過模闆實作同一算法,并使其适用于不同的資料類型。(容器)類型有:string、vector、list、queue等。

8.考慮有個資料庫表manager(employee_name,manger_name)表示職員被那個經理管理,現在要找到直接或間接被某個經理管理的雇員?

這是《資料庫系統概念》書中第四章的遞歸查詢,可惜星号部分,看的時候一掃而過,隻寫了四個字:遞歸查詢。其實程式應該是:

with recursive empl(employee_name,manager_name) as 
( 
select employee_name,manager_name 
from manager  where manager_name = 'XXX' 
union
select manager.employee_name,empl.manager_name
from maneger,empl
where manager.manager_name =empl. employee_name
)
select * from empl;      

9.按指定位置交換字元串兩部分的位置比如:函數輸入("abcde", 2) 輸出"cdeab"

int SwapStr(char* input, int pos)
{
     char* p = input+pos;
     int nLen = strlen(input);
     //對輸入資料檢查
     if (input==NULL || nLen<pos)
     {return -1;}
     char* temp= new char[pos+1];
     if (temp == NULL) return -1;
     memcpy(temp, input, pos);
     temp[pos]='\0';
     memcpy(input, p, nLen-pos);
     memcpy(input+nLen-pos, temp, pos);
     delete[] temp;
     temp = NULL;
     return 0;
}      

10.給定連結清單的頭指針和一個結點指針,在O(1)時間内删除該結點,連結清單結點的定義如下:

struct ListNode 
{ 
    int m_nKey; 
    ListNode* m_pNext; 
};      

函數的聲明如下:void DeleteNode(ListNode *pListHead, ListNode *pToBeDeleted);

void DeleteNode(ListNode *pListHead, ListNode *pToBeDeleted) 
{ 
    if (NULL != pToBeDeleted->m_pNext) 
    { 
        ListNode *pRealDeleted = pToBeDeleted->m_pNext; 

        pToBeDeleted->m_nKey = pRealDeleted->m_nKey; 

        pToBeDeleted->m_pNext = pRealDeleted->m_pNext; 

        delete pRealDeleted; 
    } 
    else 
    { 
        ListNode *pNode = pListHead; 
        while (NULL != pNode) 
        { 
            if (pNode->m_pNext == pToBeDeleted) 
            { 
                pNode->m_pNext = NULL; 
                delete pToBeDeleted; 
                break; 
            } 
            pNode = pNode->m_pNext; 
        } 
    } 
}      

大緻就記得這些題目了,感覺還是都比較基礎,就是時間不夠...,當時的感覺就是要挂了,趕快放我走吧。二十分鐘後,開始面試,面試官很嚴肅,有些題隻是簡單寫了幾個字,本以為面試時會問試卷的題目,結果提都沒提考卷的題目,看見了一堆錯号...改完試卷繼續面試,說下面試題目。

什麼是時間複雜度和空間複雜度?答:時間複雜度就是随着問題規模n的增大,算法運作時間的增長率;空間複雜度就是算法的空間需求。

是不是資料越多,空間複雜度越大?答:不是,針對某個問題,算法的空間複雜度隻和實作中所需的輔助變量有關。不知道答得對不對,總之,面試官是面無表情,繼續追問。

怎麼降低時間複雜度?答:針對某個問題,采用不同的算法就會有不同的時間運作效率,比如快排在大多場合就優于簡單排序。

繼續被問:同一個算法呢?答:減少循環的使用,減少循環的嵌套,将多元數組盡可能拆分為1維數組。

面試官笑笑:咱們假設這個程式不是比較2的程式員寫的,是專家寫的?答:不知道,沒有遇到過(我也不是專家啊)。

然後面試官說好,咱們談談你做的項目吧,我說給你履歷,他說不用了,你就說說吧。心裡頓時感覺我快走了,面試官很不屑啊。我說了做的項目,問了我搜尋引擎的一個問題,答得還可以吧,然後就面試結束了,讓我等下一個面試官。心裡想微軟面試官真的不錯,即使我自己都鄙視自己了,他還要走個流程,讓我面完再Pass掉。

稍等片刻,我把履歷趕快從包裡拿出來了,想待會可能有用。第二個面試官來了,我說這是我的履歷,他說不用...這次他帶了筆記本,然後問我項目,我說了我研究所學生一直跟着老師做的863項目,但他并沒有太大興趣,隻是說,這個很多人都再做。然後問,其他的呢?我又說了幾個自己接的私活,他問的特别多,非常有興趣,他直接就說:這是你自己接的私活吧,實驗室接的任務沒有這麼明确的商業目的的。然後詢問了我做着兩個私活過程中的解決方法,基本是我回顧了一下當時做程式時所遇到的各種問題,采取的各個方案。後面的聊天非常開心,他說分析能力不錯,但看你的答題,程式設計很不理想啊...介紹了他們的工作,希望我能去,還留了他的聯系方式。180度大轉彎,回來給他發了封郵件,問下一步安排,說HR will contact you later。

28号收到了HR的電話,基本就是咨詢下我的情況,安排Onbroad時間,Mentor去美國了等他回來,三月中旬後就可以去實習了。不懂的知識太多了,想起三字經:“幼不學,老何為!”。

這是我研究所學生第一次實習面試,還是比較“青澀”吧,大緻總結下這次面試的經驗吧:

1.微軟的面試官都比較簡單,凡事從簡,直截了當,很少給人一種親和感,交談有時壓抑了些(也可能是我跟不上他們吧)。

2.微軟的面試題比較簡單,仔細想想網上其他的面試題也是很簡單的,無非是思路巧妙一些,看看程式員面試寶典、程式設計之美什麼的基本都有(我要開始看了),但是面還是比較廣的。

3.普适面試場合上,要跟着面試官的思路走,自己認為重要的可能不是他感興趣的;面試官感興趣的就是他看重的,就要多介紹、多說。

繼續閱讀