1. 写一个C函数,判断计算机系统是大端模式(big endian)还是小端模式(small endian)。
答案参考自:http://blog.csdn.net/ce123_zhouwei/article/details/6971544
第一种思路:short int 强制转换为char,看转换的结果。代码如下:
void test1()
{
short int x;
char x0, x1;
x = 0x1122;
x0 = ((char*)&x)[0];//低地址
x1 = ((char*)&x)[1];//高地址
if(0x11 == x0)
{
printf("big endian
");
}else
{
printf("little endian
");
}
}
第二种思路:使用union类型
void test2()
{
union aword
{
unsigned int a;
char b[4];
} c;
c.a=1;
if(0==c.b[0])
{
printf("big endian
");
}else
{
printf("little endian
");
}
}
2. 给定一个单向链表的第一个结点,反转链表。
代码如下:
typedef struct Node{ int val; Node *next; } Node; Node* inverseList(Node *first){ if(first==NULL || first->next == NULL) return first; Node *pre = NULL; Node *curr = first; Node *nex = first->next; while(nex!=NULL){ curr->next = pre; pre = curr; curr = nex; nex = nex->next; } curr->next = pre; return curr; }
3. 解释volatile关键字的作用。
答:volatile属于类型修饰符,在多线程程序中使用较多,一般用来修饰被多个线程共享且修改的变量。被volatile修饰的变量,指令不会因为编译器优化而省略,这个关键字告诉程序,该变量随时可能会被改变,每次访问变量必须重新在内存读取变量的值,而不是在寄存器中提取变量值。嵌入式系统的程序用到volatile机会更多一些。
4. int a=1, b=2, c=3, d=4, 则 a<b?a:b<c?c:d 的结果是什么?
答:结果是 1,原题目相当于 (a<b)?(a):(b<c?c:d); 由于a<b是成立的,结果直接返回a的值,也就是1,后面的b<c?c:d不需要执行。
规则二叉树
题目:某规则二叉树的定义是:对于树中任意两个叶结点A、B,他们与根结点的距离分别是d1和d2,|d1-d2|<=1。请写出函数 bool isRuledTree(Node *root)的代码实现。如果该二叉树为规则树,则返回true,否则返回false。
思路:其实就是比较所有叶结点的深度,最大值和最小值之间相差不超过1,则为规则树,可以遍历所有的结点,如果碰到叶结点,记录该叶结点的深度到数组或任意什么结构中,然后找到这些记录中的最大值和最小值,求差即可。在我的代码中,用一个栈结构存储叶结点的深度。代码实现如下:
typedef struct Node{ int val; Node *right; Node *left; } Node; stack<int> record; void isRuledTreeCore(Node *n, int depth){ if(n->left == NULL && n->right == NULL){ record.push(depth); return; } if(n->left != NULL) isRuledTreeCore(n->left,depth+1); if(n->right != NULL) isRuledTreeCore(n->right,depth+1); return; } bool isRuledTree(Node *root){ if(root==NULL) return true; isRuledTreeCore(root,0); int big=0, small = INT_MAX; while(!record.empty()){ int temp = record.top(); if(temp>big) big = temp; if(temp<small) small = temp; record.pop(); } if(big-small>=-1 && big-small<=1) return true; return false; }
注意INT_MAX这个常量要#include<limits>,stack使用时要#include<stack>
IT面试中的一些基础问题
1. 面向对象的特征
继承,封装,多态
2. 重写和重载的区别
重写:在继承当中,子类重写父类的函数,函数声明完全一样,只是函数里面的操作不一样,这样叫做重写。
重载:与多态无关,即两个函数名一样的成员函数,只是他们的形参个数或数据类型不同,在调用函数的时候,程序可以自动根据调用函数时的参数个数和类型确定使用哪一个成员函数。这样叫做重载,是多态性的一种表现。
3. 引用和多态有什么关系
引用是除了指针以外另一种实现多态的方式,使用父类的指针指向子类的对象。
4. 计算机加载程序包括哪几个区?(答案是摘抄来的~)
一个由C/C++编译的程序占用的内存分为以下几个部分
(1)、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
(2)、堆区(heap) — 一般由程序员分配释放 , 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
(3)、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(BSS)。 - 程序结束后由系统释放
(4)、文字常量区 — 常量字符串就是放在这里的。 程序结束后由系统释放
(5)、程序代码区— 存放函数体的二进制代码。
5. 进程间有哪些通信方式?
信号量,消息队列,Socket,共享内存
6. TCP/IP三次握手协议
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
7. 什么是ARP协议?(这个问题没有答出来。。)
Address Resolution Protocol,地址解析协议。ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。属于数据链路层的协议。