自己整理的一些面试题,不够完全和有误的地方欢迎指出交流,希望大家能够找到不错的机会
sizeof与strlen
1、用法:sizeof可用类型做参数也可以是函数,strlen只能用char做参数
2、功能不一:sizeof获得能容纳所建立的最大对象字节数。Strlen是返回字符串长度(从代表该字符串的第一个地址开始遍历,直到遇到结束符Null,返回的长度大小不包括NULL)
3、意思不同:sizeof是运算符(unsigned int),值在编译时计算好了,参数可以是数组、指针、类型、对象、函数等。Strlen是函数,运行时才能计算。参数必须是字符型指针(char),数组做参数传入时,退化成指针了
一个“标准”宏MIN, 这个宏输入两个参数并返回较小的一个
#define MIN(A,B)((A)<=(B)?(A):(B))
分别给出BOOL, int, float, 指针变量与“零值"比较的if语句
BOOL型变量:if(!var)
int型变量: if(var==0)
float型变量:
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
指针变量: if(var==NULL)
GCC编译器将C语言从源码转化成可执行文件可以分为几个阶段?每个阶段主要做什么事?
预编译,编译,汇编,链接
Hello.c->.i .i->.s .s->.o .o->hello
编写一个函数实现字符串翻转void rechange (char str)
void rechange (char *str)
{
int sSize = strlen(str)
char temp;
for(int i =0;i<=sSize/2;i++)
{
if(str[i]!=str[sSize-i-1])
{
temp=str[i];
str[i]=str[sSize-i-1];
str[sSize-i-1]=temp;
}
else
{
continue;
}
}
}
实现二 分查找算法
public boolean binarySearchNoRecur(int[ ] arr, int target) {
int head = 0, tail = arr.length - 1;
while (head <= tail) {
int mid=head+(tail-head)/2;
if (arr[mid] == target) {//如果目标数等于中间数
return true;
} else if (arr[mid] > target) {//如果中间数大于目标数
tail = mid - 1;//刷新右节点
} else {
head = mid + 1;// 否则刷新左节点
}
}
return false ;
}
方法二:
public boolean binarySearchWi thRecur(int[] arr, int target, int left, int right) {
if (1eft > right) {//先判断左右节点之间的关系
return false;
}
int mid = left + (right -left) / 2;
if (arr[mid] > target) {
return binarySearchWithRecur(arr, target, left,mid - 1);
}else if (arr[mid] < target) {
return binarySearchWithRecur(arr, target, mid + 1, right);
}else{
return arr[mid]==target ;
}
}
进程和线程的区别
(1)进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元
(2)同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进程至少包括一个线程。
(3)进程的创建调用fork或者vfork,而线程的创建调用pthread_create,进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
(4)线程的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的
(5)线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源
(6)线程有自己的私有属性TCB,线程id,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块PCB,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志
线程一般可以分为几种状态,请画出状态转换示意图?
请表述TCP和UDP协议的异同点
1、TCP面向连接的可靠运输(字节流),UDP面向无连接的不可靠运输(报文)
2、TCP适合传输数据准确,速度要求不高,UDP适用于实时性高的
3、TCP仅支持1对1通信,UDP适用于一对一,一对多,多对一等
4、TCP占最少20字节,最大60字节,UDP占8字节
TCP:每个包有一个序号,在合理的往返时延内未收到确认,对应数据重传
拥塞控制:当网络出现拥塞的时候,TCP能够减小向网络注 入数据的速率和数量,缓解拥塞
TCP全双工通信:TCP允许通信双方的应用程序在任何时候都能发送数据,因为TCP连接的两端都设有缓存,用来临时存放双向通信的数据。当然,TCP可以立即发送-个数据段,也可以缓存一段时间以便一 次发送更多的数据段(最大的数据段大小取决于
MSS)
在发送端,应用层将数据传递给传输层的UDP协议,UDP只会给数据增加一个UDP头标识下是UDP协议,然后就传递给网络层了在接收端,网络层将数据传递给传输层,UDP 只去除IP报文头就传递给应用层,不会任何拼接操作
发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文
TCP的三次握手,四次挥手
第一次握手
客户端向服务端发送连接请求报文段。该报文段中含自身的数据通讯初始序号。请求发送后,客户端便进入SYN-SENT状态。
第二次握手
服务端收到连接请求报文段后,如果同意连接,则会发送一个应答, 该应答中也会包含自身的数据通讯初始序号,发送完成后便进入SYN-RECEIVED状态。
第三次握手
当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。 客户端发完这个报文段后便进入ESTABLISHED状态,服务端收到这个应答后也进入ESTABLISHED状态,此时连接建立成功。
这里可能大家会有个疑惑:为什么TCP建立连接需要三三次握手,而不是两次?
这是因为这是为了防止出现失效的连接请求报文段被服务端接收的情况,从而产生错误。
第一次挥手
若客户端A认为数据发送完成,则它需要向服务端B发送连接释放请求。
第二次挥手
B收到连接释放请求后,会告诉应用层要释放TCP链接。然后会发送ACK包,并进入CLOSE _WAIT状态,此时表明A到B的连接已经释放,不再接收A发的数据了。但是因为TCP连接是双向的,所以B仍旧可以发送数据给A。
第三次挥手
B如果此时还有没发完的数据会继续发送,完毕后会向A发送连接释放请求,然后B便进入LAST-ACK状态。
第四次挥手
A收到释放请求后,向B发送确认应答,此时A进入TIME-WAIT状态。该状态会持续2MSL (最大段生存期,指报文段在网络中生存的时间,超时会被抛弃)时间, 若该时间段内没有B的重发请求的话,就进入CLOSED状态。当B收到确认应答后,也便进入CLOSED状态。
关键字static有哪几种作用
1、修饰局部变量-称为静态局部变量
2、修饰全局变量-称为静态全局变量
3、修饰函数-称为静态函数
详细介绍:https://blog.csdn.net/winkxw/article/details/125903392
TCP/IP 协议分为哪几层
TCP/ip协议采用4层的层级结构:1、网络接口层(主机-网络层);2、网际层,提供简单灵活的、无连接的、尽最大努力交付的数据报服务;3、运输层,为应用进程之间 提供端到端的逻辑通信;4、应用层,为用户提供应用程序