面经 csig_0409
面经
tcp的四次挥手为什么需要time_wait?- 保证客户端发送的最后一个
ACK报文可以到达服务端; - 防止已经失效的连接请求报文重新出现在本连接;
- 保证客户端发送的最后一个
time_wait多了怎么解决?- 客户端: 短连接太多,本地临时端口耗尽
- 减少短连接,替换成长连接;
- 让服务端主动关闭;
- 扩大客户端可用端口资源
ip_local_port_range; - 复用
timewait对应的socket,内核参数:net.ipv4.tcp_tw_reuse; - 调整系统所能容纳的
timewait数量,内核参数:net.ipv4.tcp_max_tw_buckets;
- 服务端: 短连接太多,服务端在主动关闭连接
- 减少短连接,替换成长连接;
- 让客户端主动关闭;
SO_REUSEADDR帮助服务快速重启绑定;
- 客户端: 短连接太多,本地临时端口耗尽
- 讲讲
TCP长连接 和 短连接 的区别?- 短连接: 一次请求/响应完成后,就关闭
TCP连接。 - 长连接: 建立一次
TCP连接后,不立即关闭,而是复用这个连接传输多次数据。
- 短连接: 一次请求/响应完成后,就关闭
TCP长连接 和 短连接 分别适用什么场景?- 短连接: 请求频率低、一次性事务型请求、对实时性要求不高的系统;
- 长连接: 高频请求场景、实时通信场景;
- 怎么判断一个
socket fd已经关闭?- 判断本地
fd是否已失效:fcntl(fd, F_GETFD); - 判断 对端连接 是否已经关闭:
read的返回值为零;
- 判断本地
- 知道
epoll的边缘触发和水平触发?- 水平触发:只要
fd关联的内核缓冲区还有数据没读完,epoll_wait每次都会继续通知。 - 边缘触发:只有
fd关联的内核缓冲区从无到有,epoll_wait只会通知一次。导致触发读事件后必须把数据收取干净,因为下一次不一定有机会再收取数据了
- 水平触发:只要
- 怎么判断一个
socket fd可读?(最常见的方法是看它是否触发了读事件) UDP使不使用connect的区别?- 发送时是否每次指定对端
- 不使用
connect:每次sendto指定地址; - 使用
connect后:可以直接send;
- 不使用
- 接收时是否只收指定对端
- 不使用
connect:谁发来的都可以收,recvfrom能拿到来源地址; - 使用
connect后:只接收这个connect绑定的那个对端的数据;
- 不使用
- 发送时是否每次指定对端
- 知道
traceout?Traceroute反复发送IP数据报,并将TTL从1开始逐渐升高。每当路由器接收到IP报文以后则将TTL减1,当TTL减为0的时候路由器向源主机发送ICMP时间超过差错报告报文。- 当目的主机接收到
TTL恰为1的数据报时 ,由于IP数据报封装的是无法交付的UDP用户数据报(故意使用一个非法的UDP端口),目标主机回向源主机发送ICMP终点不可达差错报告报文。接收到该报文后Traceroute发送终止。 - 由此,使用
Traceroute源主机就获取了到达目的主机所经过的所有路由器和相应的跳数,以此可建立网络的拓扑结构。整个过程相当于进行了一个广度优先搜索。
ICMP的作用?- 为了更有效的转发
IP数据报和提高交付成功的机会,ICMP允许主机和路由器报告差错情况和提供有关异常情况的报告。
- 为了更有效的转发
- 知道
fork、vfork、clone嘛?fork():- 子进程和父进程有各自独立的进程地址空间,
fork后会重新申请一份资源,包括进程描述符、进程上下文、进程堆栈、内存信息、打开的文件描述符、进程优先级、根目录、资源限制、控制终端等,拷贝给子进程; - 为了减少工作量采用 写时拷贝 技术。子进程只复制父进程的页表,不会复制页面内容,页表的权限为
RD-ONLY。当子进程需要写入新内容时会触发 写时复制 机制,为子进程创建一个副本,并将页表权限修改为RW; - 由于需要修改页表,触发
page fault等,因此fork需要MMU的支持;
- 子进程和父进程有各自独立的进程地址空间,
vfork():vfork会将父进程除mm_struct的资源拷贝给子进程;vfork会阻塞父进程,直到子进程退出或释放虚拟内存资源,父进程才会继续执行;- 由于没有写时拷贝,不需要页表管理,因此
vfork不需要MMU;
clone():clone()创建用户线程时,clone不会申请新的资源,所有线程指向相同的资源;- 调用
pthread_create时,linux就会执行clone,并通过不同的clone_flags标记;
- 父进程通过
fork创建一个子进程,怎么知道程序当前处于 父进程 还是 子进程?- 通过
fork()的返回值判断- 在 父进程 中,返回 子进程的
pid - 在 子进程 中,返回
0
- 在 父进程 中,返回 子进程的
- 因为
fork()之后,父子进程都会从fork()这一行继续往下执行。
- 通过
- 知道
tcp网络编程的底层方法嘛?- 服务端:
socket、bind、listen、accept、send、recv、close; - 客户端:
socket、bind、connect;
- 服务端:
MySQL的覆盖索引?- 查询所需要的字段,全部都能从索引里直接拿到,不需要再 回表 去 主键索引 或数据页里取数据。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 GYu的妙妙屋!
