声明:本篇文章供为自己总结笔试面试,提供方便。不喜勿喷,还有希望原作者谅解
先贴一个别人推荐的网站:
程序员编程艺术http://blog.youkuaiyun.com/column/details/taopp.html;
秒杀99%的海量数据处理面试题http://blog.youkuaiyun.com/v_july_v/article/details/7382693;
微软面试100题系列http://blog.youkuaiyun.com/column/details/ms100.html;
《编程之美》;
《剑指offer》;
《Cracking the Coding Interview: 150 Programming Questions and Solutions》,顺便贴个此本书的题解:http://hawstein.com/posts/ctci-solutions-contents.html,且其中文版《程序员面试金典》即将由图灵教育出版社出版;
我个人举办的专为帮助大家找工作的面试&算法讲座:http://blog.youkuaiyun.com/v_july_v/article/details/7237351#t26;
一个刷面试题的leetcode:http://leetcode.com/,顺便附带一个leetcode的题解供参考:https://github.com/soulmachine/leetcode;
程序员面试网站careercup:http://www.careercup.com/;
一个IT面试论坛:http://www.itmian4.com/。
友人@陈利人 维护的一面试相关的微信公众账号“待字闺中”。
一、笔试面试经典题型
1.1 微软一面试题:输入两个数,相加求和,二进制输出
#include<stdio.h>
void print2(int n)
{
if(!n)
return ;
else
{
print2(n/2);
printf("%d",n%2);//递归 正好相反顺序打印
}
}
int main(){
int a,b;
while(scanf("%d%d",&a,&b) != EOF)
{
a += b;
print2(a);
}
}
1.2. TCP建立连接三次握手,以及断开连接四次握手
建立连接:(如果两次握手有可能造成服务器接收到SYN申请了缓冲区,而客户端没有接收到ACK不进行数据传输)
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
断开连接其实从我的角度看不区分客户端和服务器端,任何一方都可以调用close(or closesocket)之类的函数开始主动终止一个连接。这里先暂时说正常情况。当调用close函数断开一个连接时,主动断开的一方发送FIN(finish报文给对方。有了之前的经验,我想你应该明白我说的FIN报文时什么东西。也就是一个设置了FIN标志位的报文段。FIN报文也可能附加用户数据,如果这一方还有数据要发送时,将数据附加到这个FIN报文时完全正常的。之后你会看到,这种附加报文还会有很多,例如ACK报文。我们所要把握的原则是,TCP肯定会力所能及地达到最大效率,所以你能够想到的优化方法,我想TCP都会想到。当被动关闭的一方收到FIN报文时,它会发送ACK确认报文(对于ACK这个东西你应该很熟悉了)。这里有个东西要注意,因为TCP是双工的,也就是说,你可以想象一对TCP连接上有两条数据通路。当发送FIN报文时,意思是说,发送FIN的一端就不能发送数据,也就是关闭了其中一条数据通路。被动关闭的一端发送了ACK后,应用层通常就会检测到这个连接即将断开,然后被动断开的应用层调用close关闭连接。我可以告诉你,一旦当你调用close(or closesocket),这一端就会发送FIN报文。也就是说,现在被动关闭的一端也发送FIN给主动关闭端。有时候,被动关闭端会将ACK和FIN两个报文合在一起发送。主动关闭端收到FIN后也发送ACK,然后整个连接关闭(事实上还没完全关闭,只是关闭需要交换的报文发送完毕),四次握手完成。如你所见因为被动关闭端可能会将ACK和FIN合到一起发送,所以这也算不上严格的四次握手---四个报文段。
补充细节:
关于以上的四次握手,我补充下细节:
1. 默认情况下(不改变socket选项),当你调用close( or closesocket,以下说close不再重复)时,如果发送缓冲中还有数据,TCP会继续把数据发送完。
2. 发送了FIN只是表示这端不能继续发送数据(应用层不能再调用send发送),但是还可以接收数据。
3. 应用层如何知道对端关闭?通常,在最简单的阻塞模型中,当你调用recv时,如果返回0,则表示对端关闭。在这个时候通常的做法就是也调用close,那么TCP层就发送FIN,继续完成四次握手。如果你不调用close,那么对端就会处于FIN_WAIT_2状态,而本端则会处于CLOSE_WAIT状态。这个可以写代码试试。
4. 在很多时候,TCP连接的断开都会由TCP层自动进行,例如你CTRL+C终止你的程序,TCP连接依然会正常关
内存地址对齐,是一种在计算机内存中排列数据、访问数据的一种方式,包含了两种相互独立又相互关联的部分:基本数据对齐和结构体数据对齐。当今的计算机在计算机内存中读写数据时都是按字(word)大小块来进行操作的(在32位系统中,数据总线宽度为32,每次能读取4字节,地址总线宽度为32,因此最大的寻址空间为2^32=4GB,但是最低2位A[0],A[1]是不用于寻址,A[2-31]才能存储器相连,因此只能访问4的倍数地址空间,但是总的寻址空间还是2^30*字长=4GB,因此在内存中所有存放的基本类型数据的首地址的最低两位都是0,除结构体中的成员变量)。基本类型数据对齐就是数据在内存中的偏移地址必须等于一个字的倍数,按这种存储数据的方式,可以提升系统在读取数据时的性能。为了对齐数据,可能必须在上一个数据结束和下一个数据开始的地方插入一些没有用处字节,这就是结构体数据对齐。