现在的位置: 首页 > 综合 > 正文

微软2013校园招聘笔试试题及详细解答

2014年03月18日 ⁄ 综合 ⁄ 共 10307字 ⁄ 字号 评论关闭

版权所有,转载请注明出处,谢谢!
http://blog.csdn.net/walkinginthewind/article/details/8770201

(不定项选择题)

1. Which of the following calling conversion(s) support(s) variable-lengt parameter(e.g. printf)?
   A. cdecl
   B. stdcall
   C. pascal
   D. fastcall
解答:printf在VS2010的stdio.h中的声明为
_Check_return_opt_ _CRTIMP int __cdecl printf(_In_z_ _Printf_format_string_ const char * _Format, ...);
即printf为cdecl调用。下面对各种调用简要说明:
各种调用方式的区别主要有参数的压栈顺序,是从左到右还是从右到左;函数执行结束由谁来负责清除调用前压入栈中的参数,调用方还是被调用方;是否使用寄存器传递参数。
(1)cdecl:c/c++默认的调用方式。参数从右向左传递,放在栈中;栈平衡由调用函数来执行;不定参数函数可以使用。C语言中的printf就是典型的cdecl调用方式。因为printf函数不知道具体传入的参数的个数,所以printf内部不能完成平衡栈的操作,只能由被调用方负责平衡栈的操作。printf是通过例如%d、%c、%s等进行参数解析,但它不能确定传入参数个数,如printf("%d\n", 0, "Hello world!")也是合法的,但printf意识不到"Hello world"(实际是首地址)。
(2)stdcall:参数从右向左传递,放在栈中;栈平衡操作由被调用函数执行;不定参数的函数无法使用。Win32 API函数绝大部分都是采用__stdcall调用约定的。WINAPI其实也只是__stacall的一个别名而已。由于被调用函数完成栈平衡平衡操作,因此函数参数个数必须确定,不能使用不定参数。
(3)pascal:参数由左到右的顺序入栈;由被调用函数负责栈平衡操作;也不能使用不定参数。
(4)fastcall: 最左边的两个不大于4字节的参数分别放在ecx和edx寄存器,其余参数仍然从右到左压入栈,但是,对于浮点值、远指针和__int64类型总是通过栈来传递;被调用方平衡栈;不定参数无法使用。

2. What's the output of the following code?
        class A
        {
        public:
            virtual void f()
            {
                cout << "A::f()" << endl;

            }
            void f() const
            {
                cout << "A::f() const" << endl;
            }
        };

        class B : public A
        {
        public:
            void f()
            {
                cout << "B::f()" << endl;
            }
            void f() const
            {
                cout << "B::f() const" << endl;
            }
        };
        void g(const A * a)
        {
            a->f();
        }

        int main()
        {
            A * a = new B();
            a->f();
            g(a);
            delete a;
        }
   A. B::f() B::f() const
   B. B::f() A::f() const
   C. A::f() B::f() const
   D. A::f() A::f() const
解答:首先,两个成员函数如果只是常量性不同,可以被重载。
先看main函数中的a->f(),由于a不是常量的指针,所以编译器首先匹配到的是void f(),由于此函数是虚函数,因此实行动态绑定,因为a所指的实际类型是class B,所以执行过程中实际调用的是void B::f()。
函数g中的调用,因为参数a是const A*,所以a->f()匹配的是void f() const,由于该函数不是虚函数,因此执行静态绑定,a所指的静态类型是class A,所以执行的是void A::f() const。

3. What is the difference bewteen a linked list and an array?
   A. Search complexity when both are sorted
   B. Dynamically add/remove
   C. Random access efficiency
   D. Data storage type
解答:链表与数组的区别。ABCD都是。
数组:元素在内存中连续;可通过下标随机访问;插入删除元素需要移动大量元素。
链表:元素在内存中不一定连续,通过指针联系在一起;不能随机访问某元素。增加删除简单,只操作指针即可。

4. About the Thread and Process in Windows, which description(s) is(are) correct:
   A. One application in OS must have one Process, but not a necessary to have one Tread
   B. The Process could have its own Stack but the thread only could share the Stack of its parent Process
   C. Thread must belongs to a Process
   D. Thread could change its belonging Process
解答:此题考察进程与线程的概念。
进程是系统进行资源分配的基本单位,有独立的内存地址空间;线程是CPU调度的基本单位,没有单独地址空间,有独立的栈、局部变量、寄存器、程序计数器等。
创建进程的开销大,包括创建虚拟地址空间等需要大量系统资源;创建线程开销小,基本上只有一个内核对象和一个堆栈。
进程切换开销大,线程切换开销小。进程间通信开销大,线程间通信开销小。
线程属于进程,不能独立执行。每个进程至少有一个线程,成为主线程。

5. What is the output of the following code?

        {
            int x = 10;
            int  y = 10;
            x = x++;
            y = ++y;
            printf("%d, %d\n", x, y);
        }

   A. 10, 10
   B. 10, 11
   C. 11, 10
   D. 11, 11
解答:前置++与后置++。这个问题不同编译器表现的结果常常有差异,特别是多余连续多个出现在同一个语句中时。这里以VS2010的处理方式为例,不保证其他编译器下能得到相同结果。
++i表示,i自增1后再参与其它运算;而i++ 则是i参与运算后,i的值再自增1。自减运算符--与之类似。
语句x = x++; VS2010将其处理成x = x; x = x+1; 对应的汇编代码为:
mov         eax,dword ptr [x]  
mov         dword ptr [x],eax  
mov         ecx,dword ptr [x]  
add         ecx,1  
mov         dword ptr [x],ecx
语句y = ++y; VS2010将其处理成y = y+1; y = y; 对应的汇编代码为:
mov         eax,dword ptr [y]  
add         eax,1  
mov         dword ptr [y],eax  
mov         ecx,dword ptr [y]  
mov         dword ptr [y],ecx
所以结果是11, 11。
下面看一下以下两个语句:
int a = (x++)+(x++);
int b = (++y)+(++y);
按照上面的方式,可以解释成:
int a = x + x;
x = x + 1;
x = x + 1;
y = y + 1;
y = y + 1;
int b = y + y;
最后a = 20,y = 24(VS2010结果)。

6. For the following Java or C# code

        int[][] myArray3 = 
            new int[3][]{
                    new int[3]{5, 6, 2},
                    new int[5]{6, 9, 7, 8, 3},
                    new int[2]{3, 2}};

   what will
            myArray3[2][2]
    returns?

   A. 9
   B. 2
   C. 6
   D. overflow
解答:数组下标问题。越界,所以overflow。

7. Please choose the right statement about const usage:
   A. const int a; // const integer
   B. int const a; // const integer

   C. int const *a; // a pointer which point to const integer
   D. const int *a; // a const pointer which point to integer
   E. int const *a; // a const pointer which point to integer
解答:const写在类型前和类型后是一样的。因此const int a和int const a一样,int const *a和const int *a一样。这里主要是看一下指针的情况。
如果const出现在星号左边,表示被指物是常量,即不能通过指针修改所指植物,但是指针可以指向其他常量;如果出现在星号右边,表示指针自身是常量,指针的值不能被修改,但是可以通过指针修改指针所指之物的值;如果出现在星号两边,表示被指物和指针两者都是常量。
强化练习: const char * const * pp,解释该指针的类型。
首先,该指针是指针的指针,指向的是一个const char * const,即一个指向const char的const指针。因此(*pp)++是非法表达式,(**pp) = 'c'也是非法表达式,pp++是合法的。

8. Given the following code:
        #include<iostream>
        class A
        {
        public:
            long a;
        };
        class B : public A
        {
        public:
            long b;
        };
        void seta(A* data, int idx)
        {
            data[idx].a = 2;
        }
        int _tmain(int argc, _TCHAR * argc[])
        {
            B data[4];
            for(int i = 0; i < 4; i++)
            {
                data[i].a = 1;
                data[i].b = 1;
                seta(data, i);
            }
            for(int i = 0; i < 4; ++i)
            {
                std::cout << data[i].a << data[i].b;

            }
            return 0;
        }
   What is the correct result?
   A. 11111111
   B. 12121212
   C. 11112222
   D. 21212121
解答:此题答案应该是22221111,选项中没有。
首先为了区分,我们重命名如下:
B data[4];
A *pA = (A*)data;
这样上面的函数调用seta就转换为
pA[i] = 2;
通过data[i]和pA[i]操作数据并没有什么关系,不要受B继承自A影响。data和pA只是指向相同的起始地址,但它们对内存的解释方式不同,data[i]  = data + i*sizeof(B),pA[i] = pA+i*sizeof(A)。下面看一下内存说明图:


这样执行结果就明晰了。

9. 1 of 1000bottles of water is poisoned which will kill a rat in 1 week if the rat drunk any amout of the water. Given the bottles of water have no visual difference, how many rats are needed at least to find the poisoned
one in 1 week?

   A. 9
   B. 10
   C. 32
   D. 999
   E. None of the above
解答:此题巧妙的使用二进制的思想。把所有瓶子编号00 0000 0001 ~ 11 1110 1000(1~1000),老鼠编号0~9,从第一个瓶子开始,若该编号的二进制表示中第k位为1则就给第k个老鼠喝。一个星期后,若第0只老鼠没死,则代表有毒瓶子的二进制表示的第0位不是1,若死了就代表是1,逐一下去,最后就确定了有毒的瓶子的编号。
此问题还有一个变种,如果你有两个星期的时间(换句话说你可以做两轮实验),为了从 1000 个瓶子中找出毒药,你最少需要几只老鼠?注意,在第一轮实验中死掉的老鼠,就无法继续参与第二次实验了。

10. Which of following statement(s) equal(s) value 1 in C programming language?
   A. the return value of main function if program ends normally
   B. return (7&1);
   C. char *str = "microsoft"; return str == "microsoft";
   D. return "microsoft" == "microsoft";
   E. None of the above
解答:c语言中main函数若执行成功返回0,故A不对。7&1 = (00000111b & 00000001b ) = 1,B正确。C和D相同,先说D,常量字符串“microsoft”位于常量区,编译器一般都只保留一份,不会有重复,故D正确。C也是,char *str = "microsoft",也是将常量区中字符串的起始地址赋值给str,但我们不能通过str修改那个字符串,否则程序会崩溃,因为它在常量区。
VS2010汇编代码参考:
char *str = "microsoft"; 
 mov         dword ptr [str],offset string "microsoft" (12F7830h)  
int flag1 = (str == "microsoft");
 xor         eax,eax  
 cmp         dword ptr [str],offset string "microsoft" (12F7830h)  
 sete        al  
 mov         dword ptr [flag1],eax  
int flag2 = ("microsoft" == "microsoft");
 mov         eax,offset string "microsoft" (12F7830h)  
 xor         ecx,ecx  
 cmp         eax,offset string "microsoft" (12F7830h)  
 sete        cl  
 mov         dword ptr [flag2],ecx  

11. If you computed 32 bit signed integers F and G from 32 bit signed integer X using F = X / 2 and G = (X >> 1), and you found F != G, this implies that
   A. There is a complier error
   B. X is odd
   C. X is negative
   D. F - G = 1
   E. G - F = 1
解答:X为正整数或负偶数时,没有问题,F等于G。X为负奇数时F-1等于G,F = abs(X)/2,G = (X-1)/2。所以BCD正确。

12. How many rectangles you can find from 3*4 grid?
   A. 18
   B. 20
   C. 40
   D. 60
   E. None of above is correct
解答:3*4个格子,4*6条线。每个长方形都是由两条横线和两条竖线围成,求长方形的个数也就是求选出2条横线并和2条竖线共有多少种选法,在横线中选2条的选法有C(4,2),在竖线中选2条的选法有C(5,2),相乘得60。

13. One line can split a surface to 2 part, 2 line can split a surface to 4 part. Give 100 lines, no two parallel lines, no three lines join at same point, how many parts can 100 line split?
A. 5051
B. 5053
C. 5510
D. 5511
解答:若当前有k条线,已经分成了f(k)个区域,则增加一条线会增加多少区域呢?分割一个区域要么是一条线段将一个区域分割成两个区域,要么是一条线段将一个区域分成两个区域,增加的区域就是增加的线段(或射线)的个数。由于没有三条线交于一点,因此新增加的线与之前k条线都有一个交点,因此就增加了k+1条线段(或射线),也就增加了k+1个区域。由此可得f(n) = f(n-1) + n。f(100) = f(99) + 100 = f(98) + 99 + 100
= f(1) + 2 + 3 + ... + 100 = 5051。

14. Which of the following sorting algorithm(s) is(are) stable sorting?
   A. bubble sort
   B. quicksort
   C. heap sort
   D. merge sort
   E. selection sort
解答:快速排序不稳定。如 5 6 3 16 2,以5作为partition的划分元素,一趟partition之后,绿色的6和2交换,然后5和1交换,变为1
2 3 5 
66,所以不稳定。
堆排序不稳定。如最大堆3 2 1,堆排序的结果是1
2 3。
      3
    /    \
   2    1
  /
1

交换堆顶和尾部元素
      1
    /    \
   2    1
  /
3
调整堆为最大堆
      2
    /    \
   1    1
  /
3
交换堆顶和尾部元素
      1
    /    \
   1    2
  /
3
已是最大堆,交换堆顶和尾部元素
      1
    /    \
   1    2
  /
3
排序完成,黄色1到绿色1前面了。所以堆排序不稳定。
选择排序不稳定。如6 5 2 6 3 1,选择排序第一趟执行完后,绿色6和1交换,变为1 5 2 6
3
6,所以不稳定。

15. Model-View-Controller(MVC) is an architecture pattern that frequently used in web applications. Which of the following statement(s) is(are) correct:
   
A. Models often represent data and the business logics needed to manipulate the data in the application
   B. A view is a (visual) representation of its model. It renders the model into a form suitable for interaction, typically a user interface element
   C. A controler is the link between a user and the system. It accepts input from the user and instructs the model and a view to perform actions based on that input
   D. The common practice of MVC in web applications is, the model receives GET or POST input from user and decides what to do with it, handing over to controller and which hand control to views(HTML-generating components)
   E. None of the above
解答:MVC模型。
模型(Model):模型持有所有的数据、状态和程序逻辑。模型没有注意到视图和控制器,虽然它提供了操纵和检索状态的接口,并发送状态改变通知给观察者。
视图(View):用来呈现模型。视图通常直接从模型中取得它需要显示的数据。视图对象通常是空间,用来显示和编辑。
控制器(Controller):取得用户的输入并解读其对模型的意思。

16. We can revocer the binary tree if given the output of

   A. Preorder traversal and inorder traversal
   B. Preorder traversal and postorder traversal
   C. Inorder traversal and postorder traversal
   D. Postorder traversal 
解答:前序遍历和后续遍历不能恢复出原来的二叉树结构,因为存在不同的二叉树树,前序遍历和后续遍历都相同。如:
第一棵二叉树
        1
      /
    2
前序遍历是1 2, 后序遍历是2 1。
另一棵二叉树
       1
          \
           2
前序遍历是1 2, 后序遍历是2 1。
所以B不正确,D就更不正确了。

17. Given a string with n characters, suppose all the characters are different from each other, how many different substrings do we have?
   A. n+1
   B. n^2
   C. n(n+1)/2
   D. 2^n-1
   E. n!
解答:长度为1的子串有n个,长度为2的子串有n-1个,长度为3的子串有n-2个,... ,长度为n的有1个,总共n(n+1)/2。

18. Given the following database table, how many rows will the following SQL statement update?
            update Books set NumberOfCopies = NumberOfCopies+1 where AuthorID
            in
            Select AuthorID from Books
            group by AuthorID
            having sum(NumberOfCopies) <= 8

   A. 1
   B. 2
   C. 3
   D. 4
   E. 5
解答:先看最内层,是选出以AuthorID分组的每组内NumberOfCopies之和小于等于8的AuthorID,结果只有2。然后外层,对所有AuthorID为2的元组的NumberOfCopies加1。共更新了两行。

19. What is the shortest path between node S and node T, given the graph below? Note: the numbers represent the lengths of the connected nodes.

   A. 17
   B. 18
   C. 19
   D. 20
   E. 21
解答:最短路径问题。不多说了,看就能看出来,看不出来就按Dijkstra一步步来。

20. Given a set of N balls and one of which is defective(weighs less than others), you are allowed to weigh with a balance 3 times to find the defective. Which of the following are possible N?
   A. 12
   B. 16
   C. 20
   D. 24
   E. 28
解答:12个,分成三组4,4,4,先拿出其中两组称量,若左边轻,则坏球在左边,若右边轻则坏球在右边,若平衡,则坏球在剩下的四个当中。这样一次称量就将球减少到4个。将4个分成两组2,2,若左边轻则坏球在左边,反之在右边。第二次称量将球减少到2个。剩下两个再称量一次显然就确定了。也有其他可行的分组方法。A正确。
16个,分成三组6,6,4,先称量两组6个球的,则坏球要么在4个当中,要么在两组6个当中的一组,4个的用两次可以确定坏球。6个的再分成2,2,2三组,同样可以用一次减少到两个球,最后确定坏球。也有其他可行的分组方法。B正确。
20个,分成6,6,8三组,若在6个当中,两次可以找出,若在8个当中,将其分成3,3,2三组,两次也可以确定。也有其他可行的分组方法
24个,分成8,8,8。第一次称量减少到8个,剩下8个两次可以确定,也有其他可行的分组方法
28个无法三次确定。
总之,3个球以内一次,可一次称量确定。4~9个球可两次称量确定。10~27个球可三次称量确定。对于三次称量,只要第一次分成的三组,每组不多于9个即可。

抱歉!评论已关闭.