腾讯2013笔试题


2.考试卷上的题:



1)
signed char a=0xe0;
unsigned int b=a;
unsigned char c=a;

下面说法正确的是:
A (a>0 )&&(b>0)为真 B c==a 为真 C b的16进制为0xffffffe0 D 都不对

// 答案:C
// 整形比较小于int的会扩宽的int再比较, 而有符号数扩宽填充符号位, 无符号数填充0, 导致扩宽后两个整形的二进制不再相等, 选择C.
编程测试:
printf (”%x %x %x",a,b,c);
结果: ffffffe0 ffffffe0 e0




2)问下面的数据都存放在哪些存储区?
int main()
{
char *p = "hello,world";
return 0;
}

解析:根据C语言中的特性和定义p是一个局部变量,而C语言中局部变量存在于栈中,"hello wrold"是一个字符串字面常量,因此存储于程序的只读存储区中,p在这里其实只是指向了"hello wrold"在只读存储区中的地址而已。

3)关于 int a[10]; 问下面哪些不可以表示 a[1] 的地址?(A)
A. a+sizeof(int)
B. &a[0]+1
C. (int*)&a+1
D. (int*)((char*)&a+sizeof(int))A. a+sizeof(int)

解析:

A. a+sizeof(int)
// 不正确, 在32位机器上相当于指针运算 a + 4
B. &a[0]+1
// 正确,数组首元素地址加1,根据指针运算就是a[1]的地址
C. (int*)&a+1
// 正确,数组地址被强制类型转换为int*,然后加1,这样和B表示的一个意思
D. (int*)((char*)&a+sizeof(int))
// 正确,数据地址先被转换为char*,然后加4,根据指针运算公式,向前移动4 * sizeof(char),之后被转换为int*,显然是a[1]的地址




4)
int main()
{
long long a=1;
long long b=2;
long long c=3;
printf("%d,%d,%d",a,b ,c);
return 0;
}
输出结果是什么?(32位环境,cpu为小端模式,所有参数用栈传递)

解答:
在32和64上面, long long都是8字节,printf("%d %d %d\n", a, b, c);会依次从a的地址开始输出3个整型数据(4B)一共是12B,调用printf时参数从右至左压栈,压栈顺序是c,b,a且地址是连续存放的,小端情况下从a开始的栈去内存内容如下:
0x 01 00 00 00 00 00 00 00
0x 02 00 00 00 00 00 00 00
0x 03 00 00 00 00 00 00 00
所以连续输出12个字节的结果就是:1 0 2


5)下面哪些说法正确?(B)
A. 数组和链表都可以随机访问
B. 数组的插入和删除可以 O(1)
C. 哈希表没有办法做范围检查
D. 以上说法都不正确

解析:数组可以直接通过下标得到存储的值 因此支持随机,访问链表是链式存储结构时无法支持随机访问,要访问一个指定位置的元素必须从头开始做指针移动。哈希表支持直接通过关键码得到值 其实数组就是一种哈希表 下标就是关键码 通过下标直接得到值 因此哈希表肯定需要做范围检查也有办法做范围检查的


6)基于比较的排序的时间复杂度下限是多少?(C)
A. O(n)
B. O(n^2)


C. O(nlogn)
D. O(1)

解析:大家记住这个结论就好 在当前计算机科学界对于基于比较的排序 最快只是O(n*logn)



7)有两个线程,最初 n=0,一个线程执行 n++; n++; 另一个执行 n+=2; 问,最后可能的 n 值?(BCD)
A. 1
B. 2
C. 3
D. 4


解析:大家要知道 C语言中的 ++ 和 += 并不是原子操作,而是通过多条微程序组成的,因此 ++ 和 += 在执行过程中可能被中断的
第一种可能情况:现在假设两个线程没有并行顺序执行的那么结果显然是 4。

第二种可能情况:再假设现在第一个n++ 已经执行完了 但是结果还没有写回内存 这个时候 n+=2 已经全部执行完 2 写进了内存 结束 然后回到n++的写回操作 这个时候内存就从2被改回1了,后面再来一次n++ 结果就为2。

第三种可能情况: 第n+=2 先读取n的值到寄存器 即0入寄存器 这个时候被中断 第一个n++开始执行 并直到结束 内存被改成了1 ,然后 n+=2 继续执行 结束后内存变为2 第二个n++再执行 结果就是3了。


我个人认为 不可能得到1的执行结果


8)下面哪些函数调用必须进入内核才能完成?(AB)
A. fopen
B. exit
C. memcpy
D. strlen
解析:我觉得这题 肯定是 fopen 和 exit
fopen是打开文件的函数,文件也可以看成是一个设备,打开一个设备将导致给设备所属的驱动程序发送一个IRP,而与真实硬件相关的驱动程序都运行于内核.
exit函数是结束进程的函数,结束进程需要访问PCB(进程控制块)和TCB(线程控制块)等等一些数据结构,而这些数据都存在于内核中.原因很简单 memcpy 和 strlen 我们可以直接不调用任意函数写出来这种函数肯定不会实现在内核的

8)死锁发生的必要条件?(ABCD)

A. 互斥条件
B. 请求和保持
C. 不可剥夺
D. 循环等待

解析:互斥条件,请求和保持,不可剥夺 ,循环等待,这些都可能发生死锁 所以以后大家在做多线程程序时一定要注意了。


3)
unsigned int a= 0x1234;
unsigned char b=*(unsigned char *)&a;
在32位大端模式处理器上变量b=


// 答案:0
// unsigned int a= 0x1234; 其中int是4字节, 大端存储 ,补齐16进制表示为: 0x00 00 12 34
// unsigned char b=*(unsigned char *)&a; 由于大端存储, 所以上述int a变量的最低地址存储的是
// 十六进制表示中最左边的1字节, 为0x00.

相关文档
最新文档