2013腾讯实习笔试题

1)32位机上根据下面的代码,问哪些说法是正确的?(C)

2013腾讯实习笔试题

signed char a = 0xe0;

unsigned int b = a;

unsigned char c = a;

A. a>0 && c>0 为真

B. a == c 为真

C. b 的十六进制表示是:0xffffffe0

D.上面都不对

解析:这个题目涉及到 有符号数和无符号数之间的转换0xe0的最高位是1,因此作为有符号数就是负数,作为无符号数就是正数

所以 A 肯定是错的, B也错,c = 0xe0是正数,原因是正数和负数怎么可能相等呢,C是对的 负数的高位用1补齐,这样分析的话 D 自然不会对

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)下面哪些说法正确?(B)

A. 数组和链表都可以随机访问

B. 数组的插入和删除可以 O(1)

C. 哈希表没有办法做范围检查

D. 以上说法都不正确

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

5)基于比较的排序的时间复杂度下限是多少?(C)

A. O(n)

B. O(n^2)

C. O(nlogn)

D. O(1)

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

6)有两个线程,最初 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的执行结果

7)下面哪些函数调用必须进入内核才能完成?(AB)

A. fopen

B. exit

C. memcpy

D. strlen

解析:我觉得这题 肯定是 fopen 和 exit

fopen是打开文件的函数,文件也可以看成是一个设备,打开一个设备将导致给设备所属的驱动程序发送一个IRP,而与真实硬件相关的驱动程序都运行于内核.

exit函数是结束进程的函数,结束进程需要访问PCB(进程控制块)和TCB(线程控制块)等等一些数据结构,而这些数据都存在于内核中.原因很简单 memcpy 和 strlen 我们可以直接不调用任意函数写出来这种函数肯定不会实现在内核的

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

A. 互斥条件

B. 请求和保持

C. 不可剥夺

D. 循环等待

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

9)填空题

#include

#include

#define M 3

#define N 4

int get(int *a, int i, int j)

{

return *(a+i*N+j);

}

int main()

{

int a[M][N] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};

int v;

v = get(a, 2, 1);

printf("a[2][1] == %dn", v );

return 0;

}

解析:大家注意原型中的指针是int* a,所以必须用二维数组在内存中是一维排布这个知识点来做,直接 return *(a+i*N+j);

而不是 return *(*(a+i)+j);