腾讯PCG运营开发一面-2025-04-02
比如说这种连接过多的话、会导致除了内存和CPU还有什么样的资源问题。怎么去用指令去查看这台机器上面它的连接的个数、用什么样的指令。MySQL建立索引的原则(我回答的是什么字段适合加索引。怎么去看他那种TIME_WAIT的那种网络连接。TIME_WAIT状态过多连接会有什么问题。像CPU使用率跟CPU负载这两个有什么区别。TCP的连接构成(四元组五元组是什么)怎么看在历史里面怎么去看网络连接呢。你对
问了十五分钟 撕了10分钟
TIME_WAIT状态发生阶段
TIME_WAIT状态过多连接会有什么问题
TCP的连接构成(四元组五元组是什么)
比如说这种连接过多的话、会导致除了内存和CPU还有什么样的资源问题
Linux里面的端口数有没有限制 是否可以无上限
怎么看在历史里面怎么去看网络连接呢
网络连接查看指令
怎么去看他那种TIME_WAIT的那种网络连接
怎么去用指令去查看这台机器上面它的连接的个数、用什么样的指令
Redis的基本数据类型
缓存三兄弟
MySQL建立索引的原则(我回答的是什么字段适合加索引
如何定位慢查询
像CPU使用率跟CPU负载这两个有什么区别
你对CPU的使用率怎么看的呢
算法:
最长有效括号(hard)

1.TIME_WAIT状态发生阶段
发生在TCP四次挥手的四次挥手的时候
分析:
第四次挥手: 客户端收到服务端的FIN报文后、回一个ACK应答报文、确认收到了服务端的关闭请求。 客户端进入TIME_WAIT状态。
参考回答:
当TCP连接的主动关闭方关闭连接、与被动关闭方进行了四次挥手的时候、在主动关闭方发送完第四次挥手后、也就是最后一个 ACK 报文后、主动关闭方的 TCP 连接就会进入到 TIME_WAIT 状态
这个状态会持续 2MSL的时长、以确保对方已经收到了最后一个 ACK 报文
2.为什么 TIME_WAIT 状态要等待 2MSL
解析:
1.可靠地终止 TCP 连接:
-
在主动关闭连接的一方(通常是客户端)发送最后一个 ACK 报文后、进入 TIME_WAIT 状态。
-
这个 ACK 报文可能因为网络原因丢失。如果 ACK 丢失、被动关闭的一方(服务器)会重传 FIN 报文。
-
TIME_WAIT 状态的存在、使得主动关闭方可以重新发送 ACK 报文、确保被动关闭方能够收到 FIN 报文的确认,从而可靠地关闭连接。
-
如果主动关闭方不等待 TIME_WAIT、直接关闭连接、那么它就无法重传 ACK 报文、导致被动关闭方无法正常关闭连接、可能会出现连接半开的状态。
2.避免新连接收到旧连接的数据:
-
TCP 报文在网络中可能因为各种原因延迟到达,甚至在连接关闭后才到达。
-
MSL 表示 TCP 报文在网络中最大的存活时长。等待 2MSL 确保了:
-
两个方向的报文都消失: 一个 MSL 保证了从主动关闭方发出的最后一个 ACK 报文在网络中消失,另一个 MSL 保证了从被动关闭方重传的 FIN 报文在网络中消失。
-
避免旧连接的报文干扰新连接: 如果新的连接使用相同的 IP 地址和端口号,那么旧连接的延迟到达的报文可能会被新连接错误地接收,导致数据混乱。等待 2MSL 可以确保旧连接的所有报文都从网络中消失,从而避免这种情况发生。
-
解析:
-
主动关闭方发送的最后一个 ACK 报文: 这个报文需要一个 MSL 的时间在网络中消失。
-
被动关闭方可能重传的 FIN 报文: 如果主动关闭方发送的 ACK 报文丢失、被动关闭方会重传 FIN 报文、这个重传的 FIN 报文也需要一个 MSL 的时间在网络中消失。
防止历史连接的重复数据包干扰新的连接
-
网络环境的复杂性: 网络环境是复杂的、数据包可能会因为各种原因(路由变化、拥塞等)延迟到达、甚至被复制。
-
连接复用: TCP 协议允许在短时间内复用相同的端口号对(源 IP 地址、源端口、目的 IP 地址、目的端口)建立新的连接。
-
问题: 如果一个连接关闭后立即使用相同的端口号对建立新的连接、那么之前连接中延迟到达的数据包可能会被新的连接接收、导致数据混乱或错误。
-
2MSL 的作用: 2MSL (Maximum Segment Lifetime) 是 TCP 报文在网络中存活的最长时间。 等待 2MSL 确保了:
-
所有来自旧连接的数据包都已过期并从网络中消失。 即使有延迟的数据包、也肯定会在 2MSL 时间内到达或被丢弃。
-
新的连接不会接收到旧连接的数据包
-
来自旧连接的数据包会被丢弃。 这是 TIME_WAIT 状态的主要目的之一、防止旧连接的数据包干扰新连接。 判断是否是旧连接的数据包、主要是通过序列号和确认号来判断。 如果数据包的序列号在旧连接的范围内、或者确认号是旧连接期望的、那么就会被认为是旧连接的数据包而被丢弃。
-
参考回答:
我的理解主要有两个原因:
2MSL 的作用: 2MSL (Maximum Segment Lifetime) 是 TCP 报文在网络中存活的最长时间。 等待 2MSL 确保了:
第一个原因、主要是为了避免本次连接的历史报文、被新的连接接收到这些历史报文、从而导致出错。MSL 表示 TCP 报文在网络中最大的存活时长、等待 2MSL 就可以让两个方向的报文可以在网络中自然消失、 一个 MSL 保证了从主动关闭方发出的最后一个 ACK 报文在网络中消失、另一个 MSL 保证了从被动关闭方重传的 FIN 报文在网络中消失、这样新的连接就不会接收到历史报文了。
第二个原因、是为了确保第四次挥手 ACK 报文能被接收、从而帮助被动关闭方正常关闭连接。如果主动关闭方的第四次挥手的 ACK 报文丢失了、由于被动关闭方没有收到这个 ACK 报文、被动关闭方它会超时重传 FIN 包、主动关闭方 TIME_WAIT 状态等待期间会重新发送 ACK 报文、如果没有 TIME_WAIT 状态、那么就没办法重新发送 ACK 报文、也就没办法帮助被动关闭方正常关闭连接了。
以上就是我对 TIME_WAIT 状态的理解。
3.TIME_WAIT状态过多连接会有什么问题
分析
过多的 TIME-WAIT 状态主要的危害有两种:
-
第一是占用系统资源、比如文件描述符、内存资源、CPU 资源、线程资源等;
-
第二是占用端口资源、端口资源也是有限的、一般可以开启的端口为 32768~61000、也可以通过
net.ipv4.ip_local_port_range参数指定范围。
客户端和服务端 TIME_WAIT 过多、造成的影响是不同的
所以要从客户端过多 TIME_WAIT 状态和服务端过多 TIME_WAIT 状态来回答。
深度解析:
如果客户端(主动发起关闭连接方)的 TIME_WAIT 状态过多:
客户端的 TIME_WAIT 状态过多、占用了端口、端口是有数据限制的、最大的是 65535
连接四元组: TCP连接由四元组唯一确定:(源IP, 源端口, 目的IP, 目的端口)。
血的教训我当时不记得了😭😭😭😭😭😭 💪 💪 💪 💪 💪 💪
只要连接的是不同的服务器端、端口是可以重复使用的、所以客户端还是可以向其他服务器端发起连接的、这是因为内核在定位一个连接的时候、是通过四元组(源IP、源端口、目的IP、目的端口)信息来定位的、并不会因为客户端的端口一样、而导致连接冲突。
也就是说
-
连接目标相同: 只有当客户端需要连接到相同的服务器(相同的IP地址和端口号)时、TIME_WAIT过多才会成为问题。
-
连接目标不同: 如果客户端连接到不同的服务器(例如、
10.0.0.1:80、10.0.0.2:80、10.0.0.3:80)即使客户端端口号相同、也不会发生冲突。因为连接四元组是不同的。
参考回答
客户端和服务端 TIME_WAIT 过多、造成的影响是不同的。
如果客户端(主动发起关闭连接方)的 TIME_WAIT 状态过多:
就会占满了所有端口资源、端口是有数据限制的、那么就无法对「目的 IP+目的 PORT」都一样的服务器发起连接了、但是被使用的端口还是可以继续对另外一个服务器发起连接的。在四元组确定一个TCP连接的场景下、只有客户端端口的端口号是变量、其他三个都是固定的、那么随着
time_wait连接越多、占用的端口号就越多、客户端的端口号就会成为受限。因此客户端(发起连接方)都是和「目的 IP+目的 PORT」都一样的服务器建立连接的话、当客户端的 TIME_WAIT 状态连接过多的话、就会受端口资源限制、如果占满了所有端口资源、那么就无法再跟「目的 IP+目的 PORT」都一样的服务器建立连接了
不过即使是在这种场景下、只要连接的是不同的服务器端、端口是可以重复使用的、所以客户端还是可以向其他服务器端发起连接的、这是因为内核在定位一个连接的时候、是通过四元组(源IP、源端口、目的IP、目的端口)信息来定位的、并不会因为客户端的端口一样、而导致连接冲突。
如果服务端(主动发起关闭连接方)的
TIME_WAIT状态过多:它并不会导致端口资源受限、因为服务端只监听一个端口、而且由于一个四元组唯一确定一个 TCP 连接、因此理论上服务端可以建立很多连接、但是 TCP 连接过多、会占用系统资源、比如文件描述符、内存资源、CPU 资源、线程资源等。
4.TCP的连接构成(四元组五元组是什么)
四元组(源IP、源端口、目的IP、目的端口) 血的教训我当时不记得了😭😭😭😭😭😭 💪 💪 💪 💪 💪 💪
五元组包括:(源IP、源端口、目的IP、目的端口、传输层协议)
5.Linux里面的端口数有没有限制 是否可以无上限
有的 端口资源也是有限的、一般可以开启的端口为 32768~61000、也可以通过 net.ipv4.ip_local_port_range 参数指定范围。
6.怎么看在历史里面怎么去看网络连接呢命令是什么
网络连接查看指令
netstat -an 显示网络连接、路由表、接口统计等信息 此命令列出所有活动的网络连接及其状态。
ss -tuln 此命令显示所有监听的 TCP 和 UDP 端口
7.怎么去看他那种TIME_WAIT的那种网络连接
netstat -ant | grep TIME_WAIT
8.怎么去用指令去查看这台机器上面它的连接的个数、用什么样的指令
netstat -an 显示网络连接、路由表、接口统计等信息 此命令列出所有活动的网络连接及其状态。
9.CPU占用过高怎么看
可以理解为:
Java线上项目CPU飙高怎么办
思路1:
首先top 或 top -c命令 查看哪个进程占用较高 假设进程PID 是 1677
然后查这个进程对应的一些线程
top -H -p PID 或 top -hp PID找到线程占用率较高的线程PID 假设是1700
将线程PID(10进制)转换为16进制
printf "0x%x\n" 67890
然后通过
jstack PID > x.txt
vim x.txt
然后搜索 16进制的线程PID 查看相关代码
总结:
-
top: 找到 Java 进程 PID 假设是 12345。 -
top -H -p 12345: 找到 CPU 占用高的线程 PID 假设是 67890。 -
printf "0x%x\n" 67890: 输出0x10932。 -
jstack 12345 > jstack.log: 生成堆栈信息文件。 -
vim jstack.log: 打开文件、搜索/0x10932。 -
分析找到的线程堆栈信息 例如:
"Thread-1" #23 prio=5 os_prio=0 tid=0x00007f2a8c001000 nid=0x10932 runnable [0x00007f2a8bfff000] java.lang.Thread.State: RUNNABLE at com.example.MyClass.myMethod(MyClass.java:20) at com.example.MyClass.run(MyClass.java:10) at java.lang.Thread.run(Thread.java:745)
思路2:
CPU占用高问题的思路;
-
top: 找到 Java 进程 PID 假设是 12345。 -
top -H -p 12345: 查出 CPU 占用高的线程 PID 假设是 67890。H选项表示显示线程信息。-p 12345选项表示只显示PID为12345的进程的线程信息。 同样按P键按CPU使用率排序、找到CPU占用率最高的线程记录其PID。 -
printf "0x%x\n" 67890: 输出0x10932。 -
Jstack -l 进程ID 查看虚拟机当前时刻下的线程栈信息
10.Redis的基本数据类型
11.缓存三兄弟
参考上篇文章:
一文告诉你面试的时候要怎么回答缓存击穿、穿透、雪崩问题_缓存雪崩需要多少请求-CSDN博客
12.MySQL建立索引的原则
(我回答的是什么字段适合加索引)
我们一般选择什么样的字段来建立索引
分析
考察索引的使用场景。
适用索引的场景:
-
字段有唯一性限制的、比如商品编码(索引的区分度高 可以从索引层面保证数据安全)
-
经常用于
WHERE查询条件的字段、这样能够提高整个表的查询速度、如果查询条件不是一个字段、可以建立联合索引; -
经常用于
GROUP BY和ORDER BY的字段、这样在查询的时候就不需要再去做一次排序了、因为我们都已经知道了建立索引之后在 B+Tree 中的记录都是排序好的。
不适合索引的场景:
-
WHERE条件、GROUP BY、ORDER BY里用不到的字段、索引的价值是快速定位、如果起不到定位的字段通常是不需要创建索引的,因为索引是会占用物理空间的。 -
字段中存在大量重复数据、不需要创建索引、比如性别字段,只有男女、如果数据库表中、男女的记录分布均匀、那么无论搜索哪个值都可能得到一半的数据。在这些情况下还不如不要索引、因为 MySQL 还有一个查询优化器、查询优化器发现某个值出现在表的数据行中的百分比很高的时候、它一般会忽略索引、进行全表扫描。(直接
explan测试) -
经常更新的字段不用创建索引、比如不要对电商项目的用户余额建立索引、因为索引字段频繁修改、由于要维护 B+
Tree的有序性、那么就需要频繁的重建索引、这个过程是会影响数据库性能的。(因为索引的维护成本较高)
参考回答:
可以对频繁用于
WHERE查询条件的字段建立索引、这样能够提高整张表的查询速度、如果查询条件不是一个字段、可以考虑建立联合索引。还有对于经常用于排序、分组的字段建立索引,这样在查询的时候就不需要再去做一次排序了,因为建立索引之后在 B+ 树中的数据都是排序好的。不过对于一些区分度不高的字段、比如性别字段、只有男女、不建议建立索引、如果数据库表中、男女的记录分布均匀、那么无论搜索哪个值都可能得到一半的数据、在这种情况下、MySQL 的优化器发现某个值在表中出现的比例很高的时候、它一般会忽略索引、进行全表扫描、这时候建立的索引就没有起到作用、反而还占用了存储空间。
如何定位慢查询
像CPU使用率跟CPU负载这两个有什么区别
你对CPU的使用率怎么看的呢
算法手撕题:
最长有效括号(hard)题目链接: 32. 最长有效括号
import java.util.Stack;
class Solution {
public int longestValidParentheses(String s) {
int maxLen = 0;
Stack<Integer> stack = new Stack<>();
stack.push(-1); // 初始时,栈底放入 -1、应付s第一个是)
for (int i = 0; i < s.length(); i++) { // 从 i = 0 开始循环
char c = s.charAt(i);
if (c == '(') {
stack.push(i); // 遇到左括号入栈
} else {
stack.pop(); // 遇到右括号出栈
if (!stack.isEmpty()) {
// 栈不为空,说明有匹配的左括号,计算长度
maxLen = Math.max(maxLen, i - stack.peek());
} else {
// 栈为空,说明没有匹配的左括号,将当前右括号的索引入栈,作为新的起始位置
stack.push(i);
}
}
}
return maxLen;
}
}
后续补充一下相关知识
更多推荐


所有评论(0)