1 首先是自定义宏:比较大小 #ifdefine MAX(a,b) ((a)> (b) ? (a):(b))
2关于a的定义:
int a;
1) int *a; 一个指向整型数的指针(A pointer to an integer)
2) int **a;一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to
a pointer to an integer)
3) int *a[10] 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10pointers to integers)
4) int (*a)[10]一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)
5) int (*a)(int); 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument andreturns an integer)
6)int (*a[10])(int);一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )
3 之后就是程序输出题
忘了。但是有关于那个传地址,然后输出是不是空的那个经典题。。
4 问数据一些东西:什么是索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构!
单索引:一个索引只有一个列
复合索引:一个索引有多个列
这里并不是复合索引就比单索引速度快,有时复合索引的比较需要占更多的系统资源,但是查找范围更广!什么是数据库的主键:
主关键字(主键,primary key)是被挑选出来,作表的行的惟一标识的候选关键字。一个表只有一个主关键字。主关键字又可以称为主键。 主键 可以由一个字段,也可以由多个字段组成,分别成为单字段主键或多字段主键。 作用 1)保证实体的完整性; 2)加快数据库的操作速度 3) 在表中添加新记录时,ACCESS会自动检查新记录的主键值,不允许该值与其他记录的主键值重复。 4) ACCESS自动按主键值的顺序显示表中的记录。如果没有定义主键,则按输入记录的顺序显示表中的记录。
5 进程和线程的区别:
首先每个程序都有一个进程,每个进程都有一个线程!
线程的划分尺度小于进程,所以多线程的并发性较高。。
进城拥有独立的内存单元,而线程共享内存单元。
总体来讲:进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
6 TCP/IP的七层模型
物理层,数据链路层,网络层,传输层,表示层,会话层,应用程!
什么是三次握手:
第一次 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。 第二次 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
7 堆和栈的区别
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
申请和管理方式不同!
还有就是先进先出,栈先进后出!
8 写一个简单服务器伪代码,客户端通信之后返回服务器的时间。。。。要求使用select函数
这里主要说明一下select函数式非阻塞函数,也就是说该函数不论是不是返回都执行,如果返回-1错误,如果是0继续,那么while(1)循环,如果返回
直接server
main()
{
int sock;
FILE *fp;
struct fd_set fds;
time_t local_time;
struct timeval timeout={3,0}; //select等待3秒,3秒轮询,要非阻塞就置0
char buffer[256]={0}; //256字节的接收缓冲区
/* 假定已经建立UDP连接,具体过程不写,简单,当然TCP也同理,主机ip和port都已经给定,要写的文件已经打开
sock=socket(...);
bind(...);
fp=fopen(...); */
while(1)
{
FD_ZERO(&fds); //每次循环都要清空集合,否则不能检测描述符变化
FD_SET(sock,&fds); //添加描述符
FD_SET(fp,&fds); //同上
maxfdp=sock>fp?sock+1:fp+1; //描述符最大值加1
switch(select(maxfdp,&fds,&fds,NULL,&timeout)) //select使用
{
case -1: exit(-1);break; //select错误,退出程序
case 0:break; //再次轮询
default:
if(FD_ISSET(sock,&fds)) //测试sock是否可读,即是否网络上有数据
{
recvfrom(sock,buffer,256,.....);//接受网络数据
//不论什么都返回本地时间。。。。
{
读取本地时间,并且写入buffer;
local_time = time(NULL); memset(buffer,0,256);
strncpy(buffer,ctime(&local_time),250);
}
if(FD_ISSET(fp,&fds)) //测试文件是否可写
fwrite(fp,buffer...);//写入文件
buffer清空;
}// end if break;
}// end switch
}//end while
}//end main
这里主要讲述非阻塞函数和阻塞函数。。都不是很难。。。
然后就是做过的项目,一定要说清楚。。这块才是最重要的