当前位置:文档之家› 微软部分笔试题解析与答案

微软部分笔试题解析与答案

(微软2004-11-13的笔试题解析)

1、求函数返回值,输入x=9999;
int func(x)
{?
????int countx = 0;?
????while(x)
????{
????????countx ++;
????????x = x&(x-1);
????}
? ? return countx;
}
【试题解析】
??? 解这道题的时候,如果拿出一个二进制数来分析就会容易的多了,x=x&(x-1)实际上就是把x的二进制形式的最后一个“1”变成“0”,x的二进制形式有多少个“1”循环就执行多少次。

9999/256 = 39 余 15,把这两个数分别转化一下就很快了
39 = 32 + 4 + 2 ?+1 = 00100111
15 = 0F = 00001111
所以 9999=0010011100001111,共有8个1,答案就是 8 了

2、实现以下程序,以方便binary search.
.要有处理错误语句
.队列的分配的大小是固定的MAX_LEN,由第二个参数输入
.不能复制队列
insert (int *arr, ? ? ? ? ? //队列
? ? ? ? size_l len, ? ? ? ? ?// 队列大小
? ? ? ? size_l count, ? ? ? ?//队列元素的数目
? ? ? ? int varl ? ? ? ? ? ? //要处理的数据
)返回插入数据的索引
remove(int *arr,size_l len,size_l count,int varl)返回删除元素的索引
search(int *arr,size_l len,size_l count,int varl)返回搜索道元素的索引
【试题解析】
??? 略。数据结构书上都有的。

3、堆栈R,从顶到底:{2,4,6,8,10},逐个取出放入队列Q中 ,再从Q中逐个取出放入R中,问现在堆栈R中从顶到底的顺序。
【试题解析】
??? 这个也不用了吧,{10,8,6,4,2}

4、写出程序的结果:___________
int funa(int *a)
{
? ?a[0] ++;
}

int funb(int b[])
{
? ?b[1] += 5;
}

main()
{?
???int a[5] = {2,3,4,5,6};?
???int b[5] = {2,3,4,5,6};?
???int *p;
? ?p = &a[0];
? ?(*p)++;?
???funa(p);
? ?for(int i = 0; i<3; i++)
? ?printf("%d,",a[i]);
? ?p = &b[1];?
???funb(p);
? ?for(i = 0; i<3; i++)
? ?printf("%d,",b[i]);
}
【题目解析】
结果是:
4,3,4,2,3,9

(*p)++;?也就是a[0]++;
funa(p);中的 a[0]++ 是将 main 中的数组 a[0]++,
数组 a 中只有第一个元素加了两次 1 ,

p = &b[1];把p指向了数组 b 的第二个元素
funb(p);中的 b[1]+=5 是将 main 中的数组 b[2]+=5
数组 b 中的第三个元素加了 5


5、找出下面程序的 BUG
int CopyStringAndCount(char * Str) ①
{?
????int nCount = 0;?
????char * pBuffer;?②
??
????pBuffer = new char[MAX_PATH_LENGTH];?
????③

????④
????strcpy(pBuffer, Str);?

????for ( ; pBuffer⑤; pBuffer++ )
????????if ( pBuffer⑥=='\\' ) nCount ++;?
????
????⑦
????return nCount;
}

【题目解析】
① (const char * Str)
?? 如果在函数体内不需要改变字符串的内容,最好加上 const 以免误修改字符串内容
② char * pBuffer = NULL;
?? 指针声明的时候最好赋初值 NULL
③ if ( !pBuffer ) return -1;
?? 开辟空间之后没有检查是否成功,没有错误检查
④ if ( strlen(Str)>(MAX_PATH_LENGTH-1) ) return -2;
?? 没有检

查新开辟的空间能否容纳传进来的字符串,否则有可能越界
⑤ *pBuffer
???题中的原意是当到字符串末尾的时候跳出循环,所以应该是取字符串的内容
⑥ 同⑤
⑦ delete pBuffer; pBuffer=NULL;
???没有释放新开辟的空间,会造成内存泄漏


6、你觉得下一代浏览器应该添加什么功能?
【题目解析】
??? 当时随便写的,比如安全性,搜索功能等。


7、给出函数strcmp()的测试方案
?? int strcmp(const char * str1, const char *str2)
【题目解析】
??? 主要考查考虑问题的全面型,我觉得有一个电冰箱测试的例子不错
?我写了几个(仅供参考):
????????????str1????????str2
????????????NULL????????NULL
????????????"a"?????????NULL
????????????NULL????????"a"
????????????"a"???????? "abc"
????????????"abc"???????"acd"
????????????".xj"???????"sefn"


8、测试一个 DVD Player,如果你仅有有限的时间,你会如何做?
【题目解析】
??? 只是说说我的思路,不是标准答案。首先测试基本功能,然后是常用功能,然后是高级功能。


9、在过去的这些年,你遇到了哪一个最大的困难,你是如何解决它的?你是单独做的还是和别人一起做的决定?为什么做这个决定?现在结果如何?


10、逻辑题:
有一5节车厢的过山车,每节能座两人,现有Luair,Jack,Gwen,Tom,Mark,Paul,6人去乘车,有以下条件
1,Luair和别人同乘
2,Mark 不合别人同乘,而且Mark的前一节车厢是空的
3,Tom 不和Gwen 与 Paul 中的任何一人同乘
4,Gwen乘3,或者4节
....下面是一些断言性的语句,让你判断对错

【题目解析】
??? Mark和那节空车厢可以当作一个整体,剩下的就是按照规则做排列组合就可以了,可能的种类不是太多。如果用笔画个草图的话就比较容易了。


11、链表反转:?(这道题不是微软的,不过考的比较多,就不另外开贴了)

数据结构如下:
typedef struct _Node
{
????int data;
????struct _Node *next;
} Node;
完成函数 Node *Reverse(Node *head),head为不带头节点的链表的首部。

Node *Reverse(Node *head)
{
????Node *tmp???? = NULL;????????????????//?缓冲变量
????Node *newHead = NULL;????????????????//?反转后的新头节点
????
????if ( head==NULL ) return head;???????// 空链表的情况
????if ( head->next==NULL ) return head;?// 链表只有一个节点的情况
?
????while ( head )???????????????????????// 判断有没有移动到最后
????{
????????tmp=head->next;??????????????????//?临时记录下一个节点

????????head->next = newHead;????????????// 把原来链表中的节点放到新的链表的首部
????????newHead = head;

????????head = tmp;
????}?// end of while

????return newHead;

} // end of Reverse

1、下面的程序运行时哪里会出现错误:

struct S
{
int i;

int * p;
};

int main()
{
S s;
int * p = &s.i;
p[0] = 4;
p[1] = 3;
s.p = p;
s.p[1] = 1;
s.p[0] = 2;

return 0;
}


【题目解析】
这道题考的是对结构体内存使用情况的理解。在32位的操作系统中,int和指针类型的变量占用空间都是4个字节。在本题中 &s.i的值实际就是 &s的值,所以“int * p = &s.i”也就相当于把p指向了结构体s的地址的起始位置。如图1所示。


图1
假设 &s的值为0x12300,则p的值也是0x12300,p[0]指的是从0x12300开始的连续4个字节的空间,p[1]指的是从0x12304(注意!不是0x12301)开始的连续4个字节的空间。这样,p[0]也就相当于s.i,p[1]也就相当于s.p,分析到这一步,可以确定程序运行到“s.p=p;”这里不会出错。继续往下看。
在进行了“s.p=p;”的赋值之后,s.p指向的是s的首地址,此时s.p[0]相当于s.i,s.p[1]相当于s.p。
下一句“s.p[1]=1”执行过之后,此时s.p的值为1,也就是指向内存的0x00001处,隐患出现了。在执行“s.p[0]=2”的时候,实际上是向内存0x00001起始的连续四个字节写入0x00000002,而那块内存不属于这个程序,会出现访问非法内存的错误。
VC解析的汇编代码如下(部分),有兴趣的可以参考一下。
;?? 14:?????? S s;
;?? 15:?????? int * p = &s.i;
00401028??? lea???????? eax,[ebp-8]
0040102B??? mov???????? dword ptr [ebp-0Ch],eax
;?? 16:?????? p[0] = 4;
0040102E??? mov???????? ecx,dword ptr [ebp-0Ch]
00401031??? mov???????? dword ptr [ecx],4
;?? 17:?????? p[1] = 3;
00401037??? mov???????? edx,dword ptr [ebp-0Ch]
0040103A??? mov???????? dword ptr [edx+4],3
;?? 18:?????? s.p = p;
00401041??? mov???????? eax,dword ptr [ebp-0Ch]
00401044??? mov???????? dword ptr [ebp-4],eax
;?? 19:?????? s.p[1] = 1;
00401047??? mov???????? ecx,dword ptr [ebp-4]
0040104A??? mov???????? dword ptr [ecx+4],1
;?? 20:?????? s.p[0] = 2;
00401051??? mov???????? edx,dword ptr [ebp-4]
00401054??? mov???????? dword ptr [edx],2


2、ABCDEF各是一个0~9的数字,根据下面的条件确定A~F的值
ABCDEF*2 = CDEFAB
CDEFAB*2 = EFABCD

【题目解析】
以下答案由winion提供
ABCDEF各是一个0~9的数字,根据下面的条件确定A~F的值
ABCDEF*2 = CDEFAB
CDEFAB*2 = EFABCD
一看到题目,我立即就想到了1/7,它正好满足这个数字的性质。所以答案是142857.
......
1/7=0.142857
2/7=0.285714
3/7=0.428571
4/7=0.571428
5/7=0.714285
6/7=0.857142
然后是循环,注意到没有,都是142857这六个数字。
以下答案由大辉提供
ABCDEF*2 = CDEFAB
CDEFAB*2 = EFABCD

2*AB = CD
2*EF = 1AB
2*CD+1 = EF

8AB+2 = 100+AB

AB = 14
以下答案由dawangzi16 提供
1. E>2C>4A;==>a=1or2;

2. 因为EF*2=AB ,结合式子1得:(if A=2 then E=8 or 9 此时不成立) 所以 A=1; E=5;
同时得

出F大于5; 此时:1BCD5F*2=CD5F1B;CD5F1B*2=5F1BCD;

3。因为1B*2=CD 所以推出:c=3或2; 又由CD*2=5F; 推出C=2 ; D>5;
此时:1B2D5F*2=2D5F1B;2D5F1B*2=5F1B2D;

4。因为1B*2 = 2D 而且D>5,推出B<5 ;当 B=3时 D=6;B=4时D=8;
又因为5F*2=1B 所以 B为偶数。 从而 B=4 ,D=8;
此时 14285F*2=285F14;285F14*2=5F1428;

5。不难看出 F=7;
从而得解
以下答案由 xiahui?提供
令AB=x, CDEF=y;
则(10000x+y)*2 = 100y+x;
19999x = 98y
2857*7x = 7*14y

故得AB=14,CDEF=2857


相关主题
文本预览
相关文档 最新文档