刚刷到这个帖子,多少有点扎心。

一个35岁的大厂员工,被裁后折腾了半年,创业试了,考公也报了,最后跑来给大家交作业。

他最大的感受是,别觉得裁员离自己很远。在大厂待久了,工资看着挺稳,其实哪天名单下来,根本不给你反应时间。

打开网易新闻 查看精彩图片

创业也没想象中那么热血。钱先花出去,结果半天看不见,反馈慢得能把人磨没脾气。

至于考公,他的建议挺实在:先报名。别管最后去不去,起码逼自己看一眼岗位、时间和门槛。很多人嘴上说不考,其实连自己能报啥都不知道。

35岁以后最麻烦的不是没路,是每条路都得赶紧试。

这条连接一断,整个集群就裂开了

集群监控突然报了一条链路异常:节点 1 到节点 3 的连接断开后,节点 3 再也访问不到其他机器。

这种连接不能只当普通网络抖动处理。它在图结构里有个名字: 关键连接 。删掉它,原本连通的集群会被切成两部分,也叫“桥”。

比如下面这组连接:

0 -- 1
| |
2 -- 1 -- 3

0、1、2 组成了一个环,断掉其中任意一条边,节点之间还能绕路。但 1-3 不一样,它一断,节点 3 就彻底掉队。

这题我不会真的去一条条删边再检查连通性。连接数量一大,这种写法基本没法看。更合适的是在一次深度优先搜索里,记录两个值:

visit[x]:节点 x 第一次被访问的顺序
low[x]:从 x 出发,最多能回到多早的节点

假设 DFS 从节点 u 走到节点 v 。递归结束后,如果发现:

low[v] > visit[u]

说明 v 以及它下面的节点,根本找不到另一条路回到 u 或更早的位置。此时 u-v 就是关键连接。

Java 代码我更愿意给每条边加一个编号。只判断“父节点”看着省事,遇到重复连接时很容易把真正的回边一起跳过去。

classSolution{

private List links;
privateint visit;
privateint low;
privateint clock;
privatefinal List> brokenPoints = new ArrayList<>;

public List> criticalConnections(
int nodeCount, List> connections) {

links = new List[nodeCount];
for (int i = 0; i < nodeCount; i++) {
links[i] = new ArrayList<>;
}

for (int edgeId = 0; edgeId < connections.size; edgeId++) {
int left = connections.get(edgeId).get(0);
int right = connections.get(edgeId).get(1);
links[left].add(newint[]{right, edgeId});
links[right].add(newint[]{left, edgeId});
}

visit = newint[nodeCount];
low = newint[nodeCount];

for (int node = 0; node < nodeCount; node++) {
if (visit[node] == 0) {
scan(node, -1);
}
}
return brokenPoints;
}

privatevoidscan(int current, int incomingEdge){
visit[current] = low[current] = ++clock;

for (int[] nextLink : links[current]) {
int next = nextLink[0];
int edgeId = nextLink[1];

if (edgeId == incomingEdge) {
continue;
}

if (visit[next] == 0) {
scan(next, edgeId);
low[current] = Math.min(low[current], low[next]);

if (low[next] > visit[current]) {
brokenPoints.add(List.of(current, next));
}
} else {
low[current] = Math.min(low[current], visit[next]);
}
}
}
}

这里最容易写错的不是 DFS,而是 low 的更新。

子节点递归返回时,用的是 low[next] ,因为要把它下面能绕回去的最早位置带上来。碰到已经访问过的节点时,用的是 visit[next] ,表示当前找到了一条回边。两个地方混着写,环形网络也可能被误判成关键连接。

整个过程每个节点访问一次,每条连接最多检查两次,时间复杂度是 O(n + m)

线上做集群链路分析时,关键连接通常需要优先告警。普通连接断了可能还有备用路径,桥断了,后面的节点是真会直接失联。这个区别,监控系统最好别等事故发生后再知道。