1、写一个宏,可以将一个int型整数的二进制位的奇数位和偶数位交换
2、递归实现字符串逆置
void func (char *src)
{
if (strlen(src) == 0)
{
return;
}
else
{
func(&src[1]);
printf("%c", src[0]);
}
}
int main(int argc, const char *argv[])
{
char *s = "abcdefg";
func(s);
printf("\n");
return 0;
}
3、下面程序的输出是(D)
Void main( )
{
Unsigned char ucNum;
For (ucNum = 0; ucNum < 500; ucNum++){
......
}
Printf(“%d”, ucNum);
}
无输出,ucNum是一个无符号字符类型,取值范围是0~255,一直在执行循环
4、子网掩码255.255.192.0对于一个网络来说,网络容量是多大()
A.192
B.254
C.192*254
D.64*254
1100 0000 0000 0000 2^6*(2^8-2) 减去网关和广播地址
5、在bash shell中,假设str=abc,请写出以下的输出的结果:
(1)echo “$str”
(2)echo ’$str’
(3)echo “’$str’”
1) abc
2)$str
3) 'abc'
1、bash中的特殊符号
①$:使用变量的前导符
②“ ”:具有变量置换的功能
③‘ ’:两个“”中间为可以先执行的命令
2、shell字符串
字符串可以用单引号,也可以用双引号
单引号 str='this is $a',即使存在变量a,这句话执行结果也还是this is $a,单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
双引号 str = "this is $a",如果a变量值是world,那么这句话执行结果将是this is world,双引号的优点是可以有变量,双引号里可以出现准义
6、进程的写时拷贝
7、使用信号回收僵尸进程
1> 当子进程结束时,会向父进程发送一个SIGCHLD信号
2> 如果使用阻塞形式回收僵尸进程那么会造成可能因等待某个进程的退出导致其他子进程资源无法及时回收
3> 此时我们可以采用非阻塞的形式回收,如果单纯使用非阻塞形式回收,如果子进程没有退出,则该回收函数立即结束
4> 我们可以将信号与处理函数结合使用,捕获SIGCHLD信号,并在该信号处理函数中,以非阻塞的形式循环回收僵尸进程
8、链表逆置
Linklist rev_linklist(Linklist head)
{
//1,判断长度是否小于等于1
if(NULL ==head || NULL ==head->next)
{
return head;
}
//2,逆置
Linklist p=head->next;
head->next=NULL;
while(p!=NULL)
{
Linklist t=p;
p=p->next;
t->next=head;
head=t;
}
return head;
}
9、约瑟夫环
Linklist joseph(Linklist head,int n,int m)
{
Linklist p=head;
for(int i=0;inext;
}
//删除p的后继节点
Linklist del=p->next;
printf("%-4d",del->data);
p->next=del->next;
free(del);
del=NULL;
p=p->next;
}
head=NULL;
return NULL;
}
10、简单选择排序
int arr[]={12,34,23,4,665,23,6};
int n=sizeof(arr)/sizeof(arr[0]);
int min;
for(int i=0;i
11、快排
#include
#include
#include
//一次排序:确定基准值的位置,返回基准值的下表
int once_sort(int arr[],int low,int high)
{
//确定基准值,默认low对应的值
int key=arr[low];
while(low=arr[low])
low++;
//把low对应的值赋值给high
arr[high]=arr[low];
}
//把基准值存到low或high
arr[low]=key;
return low;
}
//快速排序
void quick_sort(int arr[],int low,int high)
{
//如果low==high 有一个元素
//如果low>high 没有元素
//如果low=high)
return;
//一次排序
int mid=once_sort(arr,low,high);
//递归左边
quick_sort(arr,low,mid-1);
//递归右边
quick_sort(arr,mid+1,high);
}
int main(int argc, const char *argv[])
{
int arr[]={12,43,654,234,76,45,87};
int len=sizeof(arr)/sizeof(arr[0]);
quick_sort(arr,0,len-1);
for(int i=0;i
12、插入排序
#include
#include
#include
void insert_sort(int arr[],int len)
{
int j;
for(int i=1;i=0;j--)
{
if(t < arr[j])
arr[j+1]=arr[j];
else
break;
}
//在j+1下表插入t
arr[j+1]=t;
}
}
int main(int argc, const char *argv[])
{
int arr[]={12,34,546,34,76,34,7};
int len=sizeof(arr)/sizeof(arr[0]);
insert_sort(arr,len);
for(int i=0;i
13、循环输入一维数组,交换最小值,和第二大值{不允许使用排序}
int arr[]={12,34,54,76,6,76,34,2};
int n=sizeof(arr)/sizeof(arr[0]);
//计算最大值和最小值
int first_max=arr[0],first_min=arr[0];
int first_maxi=0,first_mini=0;
for(int i=0;iarr[i])
{
first_min=arr[i];
first_mini=i;
}
}
//计算第二大
int second_max=first_min;
int second_maxi=0;
for(int i=0;i
d=1
16、缓冲区的大小
1>全缓存:和文件操作有关的缓冲区叫全缓存(fp指针, 4096字节)
2> 行缓存:和终端操作相关的缓冲区叫做行缓存(strdin\stdout, 1024字节)
3> 不缓存:和标准出错操作相关的缓冲区叫不缓存(stderr, 0字节)
17、何时不需要进行字节序的转换
1、已经能够确定对方的存储方式跟自己一致时,无需进行转换
2、如果传输的数据是1字节的整数,也无需进行字节序的转换
3、如果传输的是多字节字符串,也无需进行字节序的
18、三次握手和四次挥手
第一次握手:客户端发送SYN包(SYN=1, seq=0)给服务器,并进入SYN_SENT状态,等待服务器返回确认包。
第二次握手:服务器接收到SYN包,确认客户端的SYN,发送ACK包(ACK=1 , ack=1),同时发送一个SYN包(SYN=1, seq=0),并进入SYN_RCVD状态。
第三次握手:客户端接收到服务器的SYN包,以及ACK包,进入establish状态,同时向服务器发送ACK包(ACK=1, ack=1)。此时三次握手包发送完毕,服务器也进入establish状态
四次挥手的发起方可能是服务器,也可能是客户端
第一次挥手,主动关闭方发送一个FIN包(FIN=1, seq = u)给被动方,进入FIN_WAIT_1状态;
第二次挥手:被动方接收到FIN包,给主动方发送一个ACK包(ACK=1, ack=u+1);并进入CLOKSE_WAIT状态。主动方接受到ACK包后,进入FIN_WAIT_2状态。 如果有数据没有发送完毕,则继续发送,直到发送完毕为止;
第三次挥手:被动方发送一个FIN包(FIN=1, seq=w),进入LAST_ACK状态.
第四次挥手:主动关闭方收到FIN包,回复一个ACK包(ACK=1, ack=w+1)。被动关闭方收到主动关闭方的ACK后关闭连接。
19、结构体字节计算
1> 64位操作系统
1.结构体的总字节是各个成员的字节总和
2.结构体的大小计算需要满足字节对齐原则
1> 结构体的总字节是最宽成员字节的倍数,否则则填充空字节
2> 结构体的首地址必须是最宽成员的倍数
3> 结构体各个成员的偏移量是该成员的字节倍数,否则则填充空字节
1.结构体的总字节是各个成员的字节总和
2.结构体的大小计算需要满足字节对齐原则
1> 结构体的总字节是最宽成员字节的倍数,否则则填充空字节
如果最宽成员是1、2,则总字节是1、2的倍数
如果最宽成员是4、8,则总字节是4的倍数
2> 结构体的首地址必须是最宽成员的倍数
如果最宽成员是1,2,则首地址按1或2的倍数计算
如果最宽成员是4,8,则首地址按4的倍数计算
3> 结构体各个成员的偏移量是该成员的字节倍数,否则则填充空字节
如果该成员字节是1,2,则偏移量按1或2的倍数计算
如果该成员字节是4,8,则偏移量按4的倍数计算
20、内存泄漏的场景及解决办法以及如何避免
未释放分配的内存: 程序在动态分配内存后,如果没有及时调用对应的释放内存的函数,就会导致内存泄漏。
循环引用: 在C++中,如果存在循环引用(两个或多个对象互相引用,并且它们之间的引用计数无法降为零),可能导致对象无法被正确释放。
解决方法:
及时释放内存: 在动态分配内存后,确保在不再使用时调用对应的释放内存函数(如free、delete)。
使用智能指针
避免循环引用: 在C++中,可以使用智能指针来管理对象的生命周期,从而避免循环引用问题。
使用工具进行内存检测: 使用内存检测工具,如Valgrind(对C语言)或内存检测模块(如AddressSanitizer)来帮助发现潜在的内存泄漏问题。