一、网络及基础
1、简述网络的五层协议模型。
    五层模型主要是结合了osi的七层和tcp/ip的四层得出,主要是物理层、数据链路层、网络层、传输层、应用层五层,下层向上层提供服务,上层向下层提供接口。
2、请简述TCP协议连接的建立和删除过程,并简述TCP协议进行拥塞控制的机制。
    TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN,ACK。这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议。第一次握手:建立连接时,客户端发送SYN包(SEQ=x)到服务器,并进入SYN_SEND状态,等待服务器确认。第二次握手:服务器收到SYN包,必须确认客户的SYN(ACK=x+1),同时自己也送一个SYN包(SEQ=y),即SYN+ACK包,此时服务器进入SYN_RECV状态。第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=y+1),此包发送完毕,客户端和服务器时入Established状态,完成三次握手.
    结束时两个两次握手,即A端告知B端它终止从A端到B端的连接,即A端不会再往B端发送数据了(通过向B端发送一个FIN标志)。A端的关闭即告完成,此时,我们说A到B的这条TCP连接处于半关闭状态(half-close)。
    但这时,B端还是可以向A端发送数据的,B端可以在将来的任一时间内向A端发送FIN来完成它这端的半关闭。此时,A端的socket可能已经不存在(超时删除),但A主机的TCP/IP协议栈中有一个tcp control socket会代为完成一个ACK动作,完成第二个两次握手,从而彻底断开这条TCP连接
最初的TCP协议只有基于窗口的流控制(flow control)机制而没有拥塞控制机制,流控制是一种局部控制机制,其参与者仅仅是发送方和接收方,它只考虑了接收端的接收能力,而没有考虑到网络的传输能力;而拥塞控制则注重于整体,其考虑的是整个网络的传输能力,是一种全局控制机制。  拥塞控制机制使得TCP连接在网络发生拥塞时回退(back off),也就是说TCP源端会对网络发出的拥塞指示(congestion notification)(例如丢包、重复的ACK等)作出响应。  针对TCP在控制网络拥塞方面的不足,后来又提出了“慢启动”(Slow Start)和“拥塞避免”(Congestion Avoidance)算法。  TCP Reno版本增加了“快速重传 ”(Fast Retransmit)、“快速恢复”(Fast Recovery)算法,避免了网络拥塞不严重时采用“
慢启动”算法而造成过大地减小发送窗口尺寸的现象,这样TCP的拥塞控制就由这4个核心部分组成。  近几年又出现TCP的改进版本如NewReno和选择性应答(selective acknowledgement,SACK)等。
3、简述路由表的作用以及普通路由器路由查过程。在Linux下如何配置一条默认路由?
路由表的主要作用是供路由器查目标网络,进而确定转发接口及下一跳路由,完成数据包的转发功能。
1,路由器根据数据包中的目的IP地址,查级别1路由:网络路由(包括父路由)、超网路由、默认路由;
2,如果最佳匹配(指的是最长子网掩码)是级别1的最终路由,这条路由被用来转发数据包;
3,如果最佳匹配是级别1中的父路由,继续下一步查;
4,如果在父路由中到了匹配,继续查该父路由下的子路由。
5,如果有一条子路由匹配,这条路由用来转发数据包;
6,如果没有子路由匹配,则看下一条分析:
7,如果路由器执行的是有类路由查,则执行第八步;如果执行的是无类路由查,则执行第九步;
8,有类路由查:终止查询,丢弃数据包;
9,无类路由行为:继续查级别1的超网路由和默认路由,有匹配就使用超网和默认路由转发数据包
10,没到超网路由也没配置默认路由,则终止查丢弃数据包。
route add default gw 192.168.0.1
添加192.168.0.1为默认路由(即网关)
也可以写成#route add -net 0.0.0.0 gw 192.168.0.1;
前提必须加上-net参数
4、SNMP是什么协议,请简述其get、set、next、walk操作的报文交互流程。
SNMP是在路由器里最为常用的网管协议。由一组网络管理的标准组成,包含一个应用层协议(application layer protocol)、数据库模型(database schema)和一组资料物件。
SNMP是一种简单的请求响应协议。网络管理系统发出一个请求,管理器则返回一个响应。这一行为的实现是通过使用四种协议操作中的其中任一种完成的。这四种操作分别是 GETGETNEXT 、 SET 和 TRAP 。 NMS 通过 GET 操作,从 SNMP 代理处得到一个或更多的对象(实例)值。如果代理处不能提供请求列表中所有的对象(实例)值,它也就不提供任何值。 NMS 使用 GETNEXT 操作请求代理从请求列表或对象列表中取出下一个对象实例值。 NMS 通过 SET 操作向 SNMP 代理发送命令,要求对对象值重新配置。 SNMP 代理通过 TRAP 操作不定时的通知 NMS 所发生的特定事件
get是获得单个数据。walk是从起始到最后的所有数据。具体是不是还有待考究。
5、请简述进程跟线程的概念及他们的关系,并简要介绍下你所知道的线程间数据交互方式。
进程概念
  进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的并发执行的单位。
在Mac、Windows NT等采用微内核结构的操作系统中,进程的功能发生了变化:它只是资源分配的单位,而不再是调度运行的单位。在微内核系统中,真正调度运行的基本单位是线程。因此,实现并发功能的单位是线程。
线程概念
  线程是进程中执行运算的最小单位,亦即执行处理机调度的基本单位。如果把进程理解为在逻辑上操作系统所完成的任务,那么线程表示完成该任务的许多可能的子任务之一。例如,假设用户启动了一个窗口中的数据库应用程序,操作系统就将对数据库的调用表示为一个进程。假设用户要从数据库中产生一份工资单报表,并传到一个文件中,这是一个子任务;
在产生工资单报表的过程中,用户又可以输人数据库查询请求,这又是一个子任务。这样,操作系统则把每一个请求――工资单报表和新输人的数据查询表示为数据库进程中的独立的线程。线程可以在处理器上独立调度执行,这样,在多处理器环境下就允许几个线程各自在单独处理器上进行。操作系统提供线程就是为了方便而有效地实现这种并发性
引入线程的好处
(1)易于调度。
(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。
(3)开销少。创建线程比创建进程要快,所需开销很少。。
(4)利于充分发挥多处理器的功能。通过创建多线程进程(即一个进程可具有两个或更多个线程),每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。
进程和线程的关系
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。 同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
1.是通过共享变量,线程之间通过该变量进行协作通信; 
2.通过队列(本质上也是线程间共享同一块内存)来实现消费者和生产者的模式来进行通信;
二、逻辑分析
请给出下面流程图的编码,并给出相应结果。
2、已知A、B、C、D四个消息类型,消息A、B、C为当前模块需要接收的消息类型。
请根据以下条件绘制流程图:
1)若收到消息A则直接转发出去;
2)若在收到消息B后5秒内收到消息C,则将发送消息D出去,否则则将B发出;
3)若只收到消息C则不进行任何处理。
三、C/C++
1、设有枚举类型定义:enum Drinking{cola,coffee=4,tea,water=0};
则枚举类型量tea的值是________。
A:3    B:2    C:5    D:-1
2、C++的STL库中,有哪些容器?
3、请出下述代码中的问题。
char *GetMemory(void)
{
char p[] = “hello world”;
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
4、请写出下边的函数声明中三个const各自的含义。
class CMyClass
{
public:
const①CMyClass& fun(const②std::string&)const③;socket通信在哪一层
};
5、写出下面代码的运行结果。
#include <iostream>
using namespace std;
class MyTestClass
{
private:
int NumA;
public:
MyTestClass(int a)
{
cout<<a<<’\t’<<”is Constructor.”<<endl;
NumA = a;
}
MyTestClass(MyTestClass &b)
{
cout<<”Copy Constructor.”<<endl;
NumA=b.NumA;
}
void Print()
{
cout<<”The private data is: NumA=”<<NumA<<endl;
}
~My    TestClass()
{
cout<<NumA<<’\t’<<”is Destructor.”<<endl;
}
};
int main()
{
MyTestClass Myclass1(10), Myclass2(Myclass1);
Myclass2.Print();
return 0;
}
运行结果为:
(1)
(2)
(3)
(4)
(5)
6、请说明PostMessage和SendMessage的区别
7、请实现以下结构体报文的序列化和反序列化函数
序列化,即将结构体内的数据放在一段尽可能短的内存中
反序列化,即根据序列化的情况,将内存中的数据解析到结构体中
struct A
{
bool b1;
std::    string str;
int num;
bool b2;
char[2] chars;
};
8、编程实现函数 int my_atoi(char *nptr)。
函数说明:该函数的功能与库函数int atoi(char *nptr)的功能相同。my_atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(‘\0’)才结束转换,并将结果返回。返回值返回转换后的整形数
注意:不能使用库函数int atoi(char  *nptr)。