微軟2012實習生筆試題+答案解析


2012 Microsoft Intern Hiring Written Test


1. Suppose that a Selection Sort of 80 items has completed 32 iterations of the main loop. How many items are now guaranteed to be in their final spot (never to be moved again)?
(A) 16 (B) 31 (C) 32 (D) 39 (E) 40

2. Which Synchronization mechanism(s) is/are used to avoid race conditions among processes/threads in operating systems?
(A) Mutex (B) Mailbox (C) Semaphore (D) Local procedure call

3. There is a sequence of n numbers 1, 2, 3,.., n and a stack which can keep m numbers at most. Push the n numbers into the stack following the sequence and pop out randomly. Suppose n is 2 and m is 3, the output sequence may be 1, 2 or 2, 1, so we get 2 different sequences. Suppose n is 7 and m is 5, please choose the output sequences of the stack:
(A) 1, 2, 3, 4, 5, 6, 7
(B) 7, 6, 5, 4, 3, 2, 1
(C) 5, 6, 4, 3, 7, 2, 1
(D) 1, 7, 6, 5, 4, 3, 2
(E) 3, 2, 1, 7, 5, 6, 4

4. What is the result of binary number 01011001 after multiplying by 0111001 and adding 1101110?
(A) 0001 0100 0011 1111
(B) 0101 0111 0111 0011
(C) 0011 0100 0011 0101

5. What is output if you compile and execute the following code?

void main()
{
int i = 11;
int const *p = &i;
p++;
printf(“%d”, *p);
}

(A) 11 (B) 12 (C) Garbage value (D) Compile error (E) None of above

6. Which of following C++ code is correct?
(A) int f()
{
int *a = new int(3);
return *a;
}

(B) int *f()
{
int a[3] = {1, 2, 3};
return a;
}

(C) vector<int> f()
{
vector<int> v(3);
return v;
}
(D) void f(int *ret)
{
int a[3] = {1, 2, 3};
ret = a;
return;
}

7. Given that the 180-degree rotated image of a 5-digit number is another 5-digit number and the difference between the numbers is 78633, what is the original 5-digit number?
(A) 60918 (B) 91086 (C) 18609 (D) 10968 (E) 86901

8. Which of the following statements are true?
(A) We can create a binary tree from given inorder and preorder traversal sequences.
(B) We can create a binary tree from given preorder and postorder traversal sequences.
(C) For an almost sorted array, insertion sort can be more effective than Quicksort.
(D) Suppose T(n) is the runtime of resolving a problem with n elements, T(n) = Θ(1) if n = 1; T(n) = 2T(n/2) + Θ(n) if > 1; so T(n) is Θ(n log n).
(E) None of the above.

9. Which of the following statements are true?
(A) Insertion sort and bubble sort are not effcient for large data sets.
(B) Quick sort makes O(n^2) comparisons in the worst case.
(C) There is an array: 7, 6, 5, 4, 3, 2, 1. If using selection sort (ascending), the number of swap operation is 6.
(D) Heap sort uses two heap operations: insertion and root deletion.
(E) None of above.

10. Assume both x and y are integers, which one of the followings returns the minimum of the two integers?
(A) y ^ ((x ^ y) & ~(x < y))
(B) y ^(x ^ y)
(C) x ^ (x ^ y)
(D) (x ^ y) ^ (y ^ x)
(E) None of the above

11. The Orchid Pavilion (蘭亭集序) is well known as the top of “行書” in history of Chinese literature. The most fascinating sentence “Well I know it is a lie to say that life and death is the same thing, and that longevity and early death make no difference! Alas!” (“周知一死生為虛誕, 齊彭殤為妄作。“) By counting the characters of the whole content (in Chinese version), the result should be 391 (including punctuation). For these characters written to a text file, please select the possible file size without any data corrupt.
(A) 782 bytes in UTF-16 encoding
(B) 784 bytes in UTF-16 encoding
(C) 1173 bytes in UTF-8 encoding
(D) 1176 bytes in UTF-8 encoding
(E) None of the above

12. Fill the blanks inside class definition

class Test
{
public:
____ int a;
____ int b;
public:
Test::Test(int _a, int _b) : a(_a) {b = _b;}
};

int Test::b;

int _tmain(int argc, __TCHAR *argv[])
{
Test t1(0, 0), t2(1, 1);
t1.b = 10;
t2.b = 20;
printf(“%u %u %u %u”, t1.a, t1.b, t2.a, t2.b);
}

Running result: 0 20 1 20

(A) static/const
(B) const/static
(C) –/static
(D) const static/static
(E) None of the above

13. A 3-order B-tree has 2047 key words, what is the maximum height of the tree?
(A) 11 (B) 12 (C) 13 (D) 14

14. In C++, which of the following keyword(s) can be used on both a variable and a function?
(A) static (B) virtual (C) extern (D) inline (E) const

15. What is the result of the following program?
char* f(char *str, char ch)
{
char *it1 = str;
char *it2 = str;
while (*it2 != ‘\0′) {
while (*it2 == ch) {
it2++;
}
*it1++ = *it2++;
}
return str;
}

void main(int argc, char *argv[])
{
char *a = new char[10];

strcpy(a, “abcdcccd”);

cout << f(a, ‘c’);
}

(A) abdcccd (B) abdd (C) abcc (D) abddcccd (E) Access Violation

16. Consider the following definition of a recursive function, power, that will perform exponentiation.

int power(int b, int e)
{
if (e == 0) return 1;
if (e %2 == 0) return power (b * b, e / 2);
return b * power(b * b, e / 2);
}

Asymptotically (漸進地) in terms of the exponent e, the number of calls to power that occur as a result of the call power(b, e) is
(A) logarithmic (B) linear (C) quadratic (D) exponential

17. Assume a full deck of cards has 52 cards, 2 black suits (spade and club) and 2 red suits (diamond and heart).
If you are given a full deck, and a half deck (with 1 red suit and 1 black suit), what’s the possibility for each one getting 2 red cards if taking 2 cards?
(A) 1/2, 1/2 (B) 25/102, 12/50 (C) 50/51, 24/25 (D) 25/51, 12/25 (E) 25/51, 1/2

18. There is a stack and a sequence of n numbers (i.e., 1, 2, 3, …, n). Push the n numbers into the stack following the sequence and pop out randomly. How many different sequences of the number we may get? Suppose n is 2, the output sequence may be 1, 2 or 2, 1, so we get 2 different sequences.
(A) C_2n^n
(B) C_2n^n – C_2n^(n + 1)
(C) ((2n)!) / (n + 1)n!n!
(D) n!
(E) None of the above

19. Longest Increasing Subsequence (LIS) means a sequence containing some elements in another sequence by the same order, and the values of elements keeps increasing.
For example, LIS of {2, 1, 4, 2, 3, 7, 4, 6} is {1, 2, 3, 4, 6}, and its LIS length is 5.
Considering an array with N elements, what is the lowest time and space complexity to get the length of LIS?
(A) Time: N^2, Space: N^2
(B) Time: N^2, Space: N
(C) Time: NlogN, Space: N
(D) Time: N, Space: N
(E) Time: N, Space: C

20. What is the output of the following piece of C++ code?

#include <iostream>
using namespace std;

struct Item
{
char c;
Item *next;
};

Item *Routine1(Item *x)
{
Item *prev = NULL, *curr = x;
while (curr) {
Item *next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}

void Routine2(Item *x)
{
Item *curr = x;

while (curr) {
cout << curr->c << ” “;
curr = curr->next;
}
}

void _tmain(void)
{
Item *x,
d = {‘d’, NULL},
c = {‘c’, &d},
b = {‘b’, &c},
a = {‘a’, &b};

x = Routine1(&a);
Routine2(x);
}
(A) cbad (B) badc (C) dbca (D) abcd (E) dcba

 

解答(若有疑問,歡迎共同討論)轉載請注明來源http://www.cnblogs.com/jerry19880126/

  1. C。選擇排序法,遍歷,選擇當前位置之后的序列的最小值,與當前位置元素交換。
  2. AC。進程同步(互斥)方法
  3. AC。注意對棧的長度有限制。A是進一個就彈一個;B的長度超過棧的容量了,6放不進去;C可以的;D是7放不進去。
  4. A。二進制乘法。因為是選擇題,所以只要看后三位就行了,乘法不用都做完就可以看到答案了。
  5. C。注意int const *p 和int* const p的區別,前者是指向常量的指針(指針所指向的值不可變),后者是常指針(指針指向不變),這里是指向常量的指針,所以p++不報錯。得到的是&i的下一個地址里面的值,所以是垃圾值。
  6. C。這里感覺沒說清楚,什么是correct?答案只給出了C,因為C不存在內存泄露的問題且可以得到想要結果,但所有選項都是可以編譯通過的,無語法錯誤。A是內存泄露,沒有delete,B數組是臨時的,根本傳不到主調函數里,D的問題同B一樣。
  7. D。把卷子倒過來看看就知道答案了,因為是多選題,所以每個選項都要算一下。
  8. ACD。AB選項是二叉樹的遍歷問題,可以自己舉個例子試一下,中序遍歷是必須的,前序遍歷和后序遍歷二選一就行了。C插入排序法在序列大部分有序時特別有優勢,而快速排序法有選主元的問題(可以簡單的選左邊第一個元素為主元,但若序列本身大部分有序,選出的主元很可能是最小的,這樣划分得到的兩個數組有一個將可能是空的,導致性能下降)。D是對的,推一下就知道了,一步步地展開,后面就看到規律了。
  9. ABD。大規模數據用排序中算法復雜度最低的歸並排序為好(O(nlog(n))),其變式外部排序專門用來處理大規模數據排序,插入排序和冒泡排序最壞情況下的復雜度都為O(n^2)。B當每次划分都得到一個空數組的話,快速排序的復雜度為O(n^2)(最差情況)。C選擇排序的swap只有在當前元素不是假定的最小元素時發生,所以這里的swap只有7與1交換,6與2交換,5與3交換,后面已經有序了,不用swap,交換次數為3次。堆排序主要是建立最大(最小)堆和拆堆(移除堆頂元素)的操作,建堆時就是插入結點,拆推時就是移除堆頂元素(並要通過交換來維持最大/最小堆特性)。

PS:最小堆特性:是完全二叉樹,父結點值小於等於它的兩個孩子的值。實現用線性表就行了,不要用鏈表,因為是完全二叉樹。

  1. E。異或操作滿足交換率和結合率,所以B的結果就是x,C的結果就是y,D的結果就是0,下面看A是否對,舉個例子,x=0x0100,y=0x0011,A的結果是0x0100,得到的是兩數中的大值,所以不對了。
  2. BC。中文編碼問題。Unicode是定長編碼,每個字符都是2字節,但有一個大尾和小尾的識別需要額外的2字節來作碼字頭(大尾是0xfe 0xff,表示字節的低位在高地址處,小尾是0xff 0xfe,表示字節的低位在低地址處,微機原理學的“低對低,高對高”說的是小尾系統),這樣一樣,A錯B對。UTF-8是變長字節編碼,但大部分中文用三字節完成,且沒有大小尾的區別,所以C是對的,也有一種稱之為帶BOM的UTF-8編碼方式,它有大小尾的碼字頭,但這里題目里沒有BOM,所以不選D。
  3. BC。觀察輸出,發現b的重復的,即仿佛“只有一份”,所以是靜態的,C不是靜態的,答案限定在BC中,B是可以的,程序在初始化后沒有改變a的值,C也是可以的,默認是auto變量。
  4. B。B樹很陌生,翻下書吧,3階表示說非葉結點的度(分叉個數)最大為3,最小為3/2的向上取整(也就是2),B樹還有一個特性:分叉個數是父結點關鍵字個數+1。這里要求最深的B樹,當然希望每個結點內包含的關鍵字越少越好,所以度取2,這樣每個非葉結點內包含的關鍵字個數為1。一個關鍵字和兩個分叉,B樹退化為我們熟悉的二叉樹了,深度為log2(N)的向上取整,高度為深度+1,所以答案12(不同的數據結構書對高度和深度的定義不同,有的是從0開始,有的是從1開始,Mark Allen Weiss所著《數據結構與算法分析 C語言描述》書中采用的是深度從0開始,高度為1開始)
  5. ACE。很容易漏選,特別是C,其實函數的聲明可以有extern,也可以不寫的。E函數的const應該指的是類成員函數的const,表示禁止改變數據成員的值。
  6. D。動筆划一下,注意最后一個’\0’是不操作的,所以答案不是B,而是D。
  7. A。每次數的大小都會折半,所以自然是對數漸進的。
  8. B。排列組合。第一問 第二問 
  9. B。看答案好像還是與組合有關,但數學不好推不出來。好在是選擇題,舉幾個特例用排除法做(但要相信是有答案的,不要選E),n=1時結果是1,n=2時結果是2,n=3時結果是5,n=4時結果是14。用排除法迅速解決掉A和D,C有些迷惑人,仔細看,除號后面不是一起作分母的,而只有n+1才是分母!都滿足特例的只有B了。
  10. C。最長遞增子序列。線性規划思想,具體如下:

    

View Code
  1 #include <iostream>
  2 using namespace std;
  3 
  4 //動態規划基本算法,算法時間復雜度為O(n^2),空間復雜度為O(n)
  5 void longestIncreaseSequence(int* a, int len, 
  6     int* outputa, int& outputlen)//outputa應該在函數外面已經有空間分配了。
  7 {
  8     //s[i]表示以a[i]為結尾的最長子序列的長度,這個長度包括a[i]自身
  9     int *s = new int[len];
 10     int *fromIndex = new int[len];//記錄以a[i]為結尾的最長子序列的前一個元素
 11     s[0] = 1;
 12     fromIndex[0] = -1;
 13     int globalMaxIndex = 0;
 14     int globalMaxLength = 1;
 15 
 16     for(int i = 1; i < len; ++i)
 17     {
 18         int localMaxLength = 0;
 19         for(int j = 0; j <= i - 1; ++j)
 20         {
 21             if(a[j] < a[i] && s[j] > localMaxLength)
 22             {
 23                 fromIndex[i] = j;
 24                 localMaxLength = s[j];
 25             }
 26         }
 27         s[i] = localMaxLength + 1;
 28         if(s[i] > globalMaxLength)
 29         {
 30             globalMaxLength = s[i];
 31             globalMaxIndex = i;
 32         }
 33     }
 34     int findIndex = globalMaxIndex;
 35     int k = 0;
 36     while(findIndex >= 0)
 37     {
 38         outputa[k++] = a[findIndex];
 39         findIndex = fromIndex[findIndex];
 40     }
 41     outputlen = k;
 42 
 43     //數組反序
 44     int i = 0, j = k - 1;
 45     while(i < j)
 46     {
 47         int temp = outputa[i];
 48         outputa[i] = outputa[j];
 49         outputa[j] = temp;
 50         ++i;
 51         --j;
 52     }
 53 
 54     delete [] s;
 55     delete [] fromIndex;
 56 }
 57 
 58 
 59 //改進的動態規划基本算法,用到二分查找法,算法時間復雜度為O(nlogn),空間復雜度為O(n)
 60 void longestIncreaseSequenceModified(int* a, int len, 
 61     int* outputa, int& outputlen)//outputa應該在函數外面已經有空間分配了。
 62 {
 63     int *B = new int[len + 1];//用於二分查找的數組,B的下標為s的值,B的值為序列元素的末尾值
 64     B[0] = -10000;//假定輸入的元素不可能小於-10000
 65     B[1] = a[0];
 66     int maxLength = 1;
 67     for(int i = 1; i < len; ++i)
 68     {
 69         
 70         int high = maxLength;//二分查找上限
 71         int low = 0;//二分查找下限
 72         int middle = (low + maxLength) / 2;//中間值
 73         while(low <= high)
 74         {
 75             
 76             if(a[i] > B[middle])
 77             {
 78                 low = middle + 1;
 79             }
 80             else
 81             {
 82                 high = middle - 1;
 83             }
 84             middle = (low + high) / 2;
 85         }
 86         B[middle + 1] = a[i];
 87         maxLength = middle + 1;
 88     }
 89     
 90     //輸出
 91     outputlen = maxLength;
 92     for(int i = 0; i < maxLength; ++i)
 93     {
 94         outputa[i] = B[i + 1];
 95     }
 96 
 97     delete [] B;
 98 }
 99 
100 
101 int main()
102 {
103     int a[8] = {2,1,4,2,3,7,4,6};
104     int output[8];
105     int outputlen;
106     //longestIncreaseSequence(a, 8, output, outputlen);
107     longestIncreaseSequenceModified(a, 8, output, outputlen);
108     for(int i = 0; i < outputlen; ++i)
109     {
110         cout << output[i] << "  ";
111     }
112     cout << endl;
113     return 0;
114 }

 



  11. E。鏈表反序,耐心沿着程序走。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM