1.extern关键字
1)诞生动机:在一个C语言项目中,需要再多个文件中使用同一全局变量或是函数,那么就需要在这些文件中再声明一遍
2)用于声明在其他地方定义的一个变量或是函数,在当前位置只是声明,告诉编译器在链接阶段去其他地方找。
2.strcpy的缺陷
1.没有长度检查。
2.不返回有用的错误信息。
3.安全性问题。
2.1如何避免
1.可以使用strncpy函数,这个函数允许指定要复制的最大字符数,从而可以避免缓冲区溢出。
注意事项:如果源字符串的长度大于 n,那么目标字符串可能不会以空字符结尾。所以在使用 strncpy 后,可能需要手动确保目标字符串以空字符结尾,以避免后续字符串操作出现问题。
2.可以使用strlcpy函数,这个函数保证strlcpy 函数在复制字符串时会确保目标字符串以空字符结尾,并且最多复制指定的长度减一的字符数,以留出空间给空字符。
3.重载,重写,覆盖,隐藏的区别
重载:在一个类中,函数名相同,参数列表不同。
重写:在派生类中,有和基类虚函数同名,同参数列表,同返回类型的函数,用于改变基类虚函数的行为。
覆盖:在C++中覆盖和重写同义
隐藏:在派生类中有与基类中非虚函数同名的函数,可以导致在派生类作用域中基类函数被隐藏。
4.踩内存
“踩内存”(memory corruption)通常是指程序错误地访问或修改了不属于它应该访问的内存区域。
4.1产生原因:
缓冲区溢出
野指针
数组越界访问
5.水平触发和边缘触发
6.select/poll和epoll
select 和 poll 并没有本质区别,它们内部都是使用「线性结构」来存储进程关注的 Socket 集合。 在使用的时候,首先需要把关注的 Socket 集合通过 select/poll 系统调用从用户态拷贝到内核态,然后由内核检测事件,当有网络事件产生时,内核需要遍历进程关注 Socket 集合,找到对应的 Socket,并设置其状态为可读/可写,然后把整个 Socket 集合从内核态拷贝到用户态,用户态还要继续遍历整个 Socket 集合找到可读/可写的 Socket,然后对其处理。
很明显发现,select 和 poll 的缺陷在于,当客户端越多,也就是 Socket 集合越大,Socket 集合的遍历和拷贝会带来很大的开销,因此也很难应对 C10K。
epoll 在内核里使用「红黑树」来关注进程所有待检测的 Socket,红黑树是个高效的数据结构,增删改一般时间复杂度是 O(logn),通过对这棵黑红树的管理,不需要像 select/poll 在每次操作时都传入整个 Socket 集合,减少了内核和用户空间大量的数据拷贝和内存分配。 epoll 使用事件驱动的机制,内核里维护了一个「链表」来记录就绪事件,只将有事件发生的 Socket 集合传递给应用程序,不需要像 select/poll 那样轮询扫描整个集合(包含有和无事件的 Socket ),大大提高了检测的效率。