首页
社区
课程
招聘
[旧帖] [原创]趣味面试题集锦 0.00雪花
发表于: 2009-6-3 10:34 6752

[旧帖] [原创]趣味面试题集锦 0.00雪花

2009-6-3 10:34
6752
最近看了不少关于求职面试的试题,在其中发现了不少有意思的题目。特整理后发表上来与大家一起分享。

为了方便与以后添加的题目区别,每次更新会以A、B……的方式标注。

A-1:如何将a、b的值进行交换,并且不使用任何中间变量?

    解析:一般可以选择两种方式:

    (1)使用加法运算:a = a+b; b = a-b; a = a-b;

    (2)使用异或运算:a = a^b; b = a^b; a = a^b;

    其中,如果a、b的值比较大,那么选择第一种方式可能会导致越界,因此,最佳答案是异或方式。

A-2:main主函数执行完毕后,是否可能会再执行一段代码?

    解析:回答是肯定的。可以使用atexit()函数注册一个函数,使得主函数在退出前先执行该注册地函数。

A-3:写出下面程序的运行结果
#include <stdlib.h>
#include <time.h>
 
#define LOOP 1000
 
int main()
{
 
        int count = 0,i;
        int x,y;
 
        srand(time(0));
        for(i=0;i<LOOP;i++){
                x = rand();
                y = rand();
                if(x*x+y*y < RAND_MAX*RAND_MAX)
                        count++;
        }
 
        printf("%d\n", count);
 
        return 0;
}


    解析:据说这是一个很好的概率题。该题中暗含了一个1/4圆和一个正方形比较大小的问题。其中,RAND_MAX是随机数中的最大值,也就是相当于最大半径R;而x、y值则相当于横纵轴的坐标值,它们的平方和开根号就是原点到该点(x, y)的距离,当然这个距离可能大于R也有可能小于R。

    通过上面的分析,该问题则可以蜕化为:随机在正方形里落LOOP个点,落在半径里面的点有多少个。鉴于1/4圆面积是(1/4)*π*R*R,正方形面积是R*R,两者之比为(1/4)*π,所以落点数为LOOP*(1/4)*π个。鉴于题意中LOOP为1000,则可计算出大约为785个点。

    然而,我在Linux ubuntu 2.6.24-22-generic运行该程序得到的结果却是500左右,Why?

A-4:写出下列程序的执行结果:

#include <stdio.h>
 
int main()
{
        printf("%f\n", 5);
        printf("%d\n", 5.01);
 
        return 0;
}


    解析:首先5为int型,在32平台上会由编译器分配4个字节;当以%f方式输出时,编译器将从该值所在地址上读出8个字节。很显然地,内存访问越界,因此输出结果不确定。同理以%d方式显示浮点数5.01时,结果也将不确定。从实际测试来说,第一个答案往往是0.000000;第二个很可能是大数。

A-5:写出下面程序的执行结果:

#include <iostream>
using namespace std;
 
union {
        unsigned char a;
        unsigned int i;
} u;
 
int main(void)
{
        u.i = 0xf0f1f2f3;
 
        cout<<hex<<u.i<<endl;
        cout<<hex<<int(u.a)<<endl;
 
        return 0;
}


    解析:该程序主要考察内存中数据如何存储。在冯·诺依曼体系中,在内存中数据的低位字节存储在低地址上;而数据的地址则采用它的低地址来表示,具体情况如下所示:


    因此该结果将是:f0f1f2f3,f3。

B-1:写出下面程序的执行结果:
#include <stdio.h>
#include <string.h>

int main(void)
{
        char s[] = "123456789";
        char d[] = "123";

        strcpy(d,s);
        printf("%s, %s\n", d, s);

        return 0;
}


    解析:这是一个典型的溢出问题。首先数组s被分配了10个字符(包含字符串串尾的空字符),而数组d只被分配了4个字符;所以当使用strcpy()函数进行字符串复制时,数组d会溢出。由于数组s和d都是自动变量,它们存在于stack中,而数组s先被分配在高地址上,而数组d则被分配在后续的低地址上,当数组d越界时,则会造成数组s中的数据被覆盖,原来的“123456789”则被覆盖为“56789\0789”,其中’\0’代表字符串尾的空字符。

    因此,该输出应该是123456789,56789。

=====================================================
  欢迎访问我的博客:http://billstone.cublog.cn

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (18)
雪    币: 22
活跃值: (94)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
有点意思
2009-6-3 11:12
0
雪    币: 118
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
确实不错,顶一个
2009-6-3 12:46
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
4
好像只会第一题。。。
第3题VC6下编译输出结果为790左右,LZ的500左右
关于第4题:在VC里调试:
10: printf("%f\n", 5);
00401028 push 5
0040102A push offset string "%f\n" (0042601c)
0040102F call printf (00401080)
00401034 add esp,8
11: printf("%d\n", 5.01);
00401037 push [COLOR=red]40140A3Dh[/COLOR]
0040103C push [COLOR=red]70A3D70Ah[/COLOR]
00401041 push offset string "%d\n" (00427008)
00401046 call printf (00401080)


注意看红字部分,5.01已经被编译器转换为了十六进制,红字标识出来的就是5.01的十六进制形式.以%d的形式输出时,只能读出70A3D70Ah,所以显示结果应该为70A3D70Ah的十进制形式1889785610若改%d%d%d则可以完整的把70a3d70a40140a3d显示出来。。。
要是把题目稍加修改又考到一部分人了
2009-6-3 13:31
0
雪    币: 339
活跃值: (10)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
5
to cntrump:

  790应该比较合理,看来是Ubuntu的底层实现比较特别
2009-6-3 13:42
0
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
第三题是不是溢出了,在gcc下RAND_MAX = 0x7fffffff
vc8下 RAND_MAX = 0x7fff
2009-6-3 14:22
0
雪    币: 339
活跃值: (10)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
7
to bhltwrn:

  我去看一下,如果RAND_MAX真是如此的话,那应该是溢出造成的问题;我看看能不能修改RAND_MAX后再试试,3x
2009-6-3 14:58
0
雪    币: 339
活跃值: (10)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
8
刚刚又添加了一个关于溢出的题目,还是比较有意思的
2009-6-3 14:59
0
雪    币: 50
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
很有创意,也很新颖。不错的。
2009-6-3 15:03
0
雪    币: 339
活跃值: (10)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
10
第三题的问题(红色标记)确实是在计算(x*x+y*y < RAND_MAX*RAN_MAX)时出现溢出所造成的。我简单修改了代码,在Ubuntu下用gcc测试的结果确实是785左右。代码如下:
#include <stdlib.h>
#include <time.h>

#define LOOP 1000

int main()
{
        int count = 0,i;
        [COLOR="Red"]float x,y;[/COLOR]

        srand(time(0));
        for(i=0;i<LOOP;i++){
                x = [COLOR="red"](float)rand() / RAND_MAX;[/COLOR]
                y = [COLOR="red"](float)rand() / RAND_MAX[/COLOR];
                if([COLOR="red"]x*x+y*y < 1[/COLOR])
                        count++;
        }

        printf("%d\n", count);

        return 0;
}
2009-6-3 15:11
0
雪    币: 1450
活跃值: (35)
能力值: (RANK:680 )
在线值:
发帖
回帖
粉丝
11
不错不错, 虽然部分东西很老 , 路过帮顶~~
2009-6-3 18:13
0
雪    币: 125
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
A-1:如何将a、b的值进行交换,并且不使用任何中间变量?
//这个题目有奇异,应该限定ab为整型的前提下 不使用任何中间变进行交换?
2009-6-3 18:31
0
雪    币: 235
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
A-1:如何将a、b的值进行交换,并且不使用任何中间变量?

汇编中不是有一个直接把两个数交换的吗??  xchg

如楼上所说,ab的类型怎么没定?
2009-6-3 23:08
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
B-1题
将d改成    char d[] = "1234";
运行结果是123456789,123456789   
能否解释解释?
2009-6-4 01:28
0
雪    币: 339
活跃值: (10)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
15
to 大孩子:
  A-1中a、b的值应该只要不是浮点型就可以,我看得原题并没有突出这一点
2009-6-4 09:17
0
雪    币: 339
活跃值: (10)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
16
to kuhot:

  请问你是在什么环境下测试的?貌似Ubuntu 2.4环境就有针对溢出的机制,B-1例程在它的环境下运行从外面来看是没有溢出发生地。
2009-6-4 09:19
0
雪    币: 339
活跃值: (10)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
17
貌似大家对这些基础题目兴趣不大啊,自己顶
2009-6-6 12:36
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
18
我悟性低,还在慢慢参透。。。。
2009-6-7 10:14
0
雪    币: 339
活跃值: (10)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
19
to cntrump:

   有什么不明白的可以提出来啊,呵呵;大家一起探讨一下
2009-6-7 18:13
0
游客
登录 | 注册 方可回帖
返回
//