2012微软校园实习生笔试题

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

分析:int const *p = &i;  p所指向的内容是常量,p++是指向下一个地址。。故是垃圾值

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

(A) 722字节 UTF-16 (这个不对,因为UTF-16有Big Endian和Little Endian两种,必须要加BOM)(这个我答错了) 
(B) 724字节 UTF-16 (这个是对的,UTF-16两字节表示一个汉字,外加一个BOM两字节) 
(C) 1083字节 UTF-8 (这个是对的,UTF-8通常三字节一个汉字,选用不加BOM的方式) 
(D) 1086字节 UTF-8 (这个是对的,UTF-8通常三字节一个汉字,选用加BOM的方式)

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
分析:考察B-树知识

(这个我选了A。 
M阶B树只能在叶子结点存储数据,其他结点的孩子个数必须在[ceiling(M/2), M]之间,根节点要么是叶子结点,要么至少有两个孩子。 
根据该定义,如果3阶B树有2048个元素,那高度最大时每个结点都取孩子个数下限(2),高度为12(即log(2048)+1)。 
然后去掉一个叶子结点,则从叶子向根一路发生结点合并,一个2孩子结点和一个1孩子结点合并成为一个3孩子结点。 
这不是高潮,高潮是,根节点的两个孩子也发生了结点合并,变成了一个结点,根不再满足B树的要求,被删除,其唯一的孩子成为了新的根。 
于是,树的高度变为了11。 

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?

 

#include<iostream>
using namespace std;

char* f(char *str, char ch)
{
    char *it1 = str;
    char *it2 = str;
    while (*it2!='\0') 
    {
        while (*it2 == ch) 
        {
            it2++;
        }
        *it1++ = *it2++;
    }
    return str;
}

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

    strcpy(a, "abcdcccd");

    cout << f(a,'c');
    system("pause");
}

(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;
    }
}

int main()
{
    Item *x,
    d = {'d',NULL},
    c = {'c',&d},
    b = {'b',&c},
    a = {'a',&b};

    x = Routine1(&a);
    Routine2(x);
    system("pause");
}

(A) cbad (B) badc (C) dbca (D) abcd (E) dcba

  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。最长递增子序列。线性规划思想,具体如下:
#include <iostream>
using namespace std;

//动态规划基本算法,算法时间复杂度为O(n^2),空间复杂度为O(n)
void longestIncreaseSequence(int* a, int len, 
    int* outputa, int& outputlen)//outputa应该在函数外面已经有空间分配了。
{
    //s[i]表示以a[i]为结尾的最长子序列的长度,这个长度包括a[i]自身
    int *s = new int[len];
    int *fromIndex = new int[len];//记录以a[i]为结尾的最长子序列的前一个元素
    s[0] = 1;
    fromIndex[0] = -1;
    int globalMaxIndex = 0;
    int globalMaxLength = 1;

    for(int i = 1; i < len; ++i)
    {
        int localMaxLength = 0;
        for(int j = 0; j <= i - 1; ++j)
        {
            if(a[j] < a[i] && s[j] > localMaxLength)
            {
                fromIndex[i] = j;
                localMaxLength = s[j];
            }
        }
        s[i] = localMaxLength + 1;
        if(s[i] > globalMaxLength)
        {
            globalMaxLength = s[i];
            globalMaxIndex = i;
        }
    }
    int findIndex = globalMaxIndex;
    int k = 0;
    while(findIndex >= 0)
    {
        outputa[k++] = a[findIndex];
        findIndex = fromIndex[findIndex];
    }
    outputlen = k;

    //数组反序
    int i = 0, j = k - 1;
    while(i < j)
    {
        int temp = outputa[i];
        outputa[i] = outputa[j];
        outputa[j] = temp;
        ++i;
        --j;
    }

    delete [] s;
    delete [] fromIndex;
}


//改进的动态规划基本算法,用到二分查找法,算法时间复杂度为O(nlogn),空间复杂度为O(n)
void longestIncreaseSequenceModified(int* a, int len, 
    int* outputa, int& outputlen)//outputa应该在函数外面已经有空间分配了。
{
    int *B = new int[len + 1];//用于二分查找的数组,B的下标为s的值,B的值为序列元素的末尾值
    B[0] = -10000;//假定输入的元素不可能小于-10000
    B[1] = a[0];
    int maxLength = 1;
    for(int i = 1; i < len; ++i)
    {
        
        int high = maxLength;//二分查找上限
        int low = 0;//二分查找下限
        int middle = (low + maxLength) / 2;//中间值
        while(low <= high)
        {
            
            if(a[i] > B[middle])
            {
                low = middle + 1;
            }
            else
            {
                high = middle - 1;
            }
            middle = (low + high) / 2;
        }
        B[middle + 1] = a[i];
        maxLength = middle + 1;
    }
    
    //输出
    outputlen = maxLength;
    for(int i = 0; i < maxLength; ++i)
    {
        outputa[i] = B[i + 1];
    }

    delete [] B;
}


int main()
{
    int a[8] = {2,1,4,2,3,7,4,6};
    int output[8];
    int outputlen;
    //longestIncreaseSequence(a, 8, output, outputlen);
    longestIncreaseSequenceModified(a, 8, output, outputlen);
    for(int i = 0; i < outputlen; ++i)
    {
        cout << output[i] << "  ";
    }
    cout << endl;
    return 0;
}

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

你可能感兴趣的:(2012)