数据结构与算法学习笔记(Acwing 提高课)----动态规划·树形DP
数据结构与算法学习笔记----动态规划·树形DP
@@ author: 明月清了个风
@@ first publish time: 2025.6.4ps⭐️树形动态规划(树形DP)是处理树结构问题的一种动态规划方法,特征也很明显,会有一个树形结构,其实是DFS的优化。
Acwing 1072. 树的最长路径
给定一棵树,树中包含 n n n个节点(编号 1 ∼ n 1 \sim n 1∼n)和 n − 1 n - 1 n−1条无向边,每条边都有一个权值。
现在请你找到树中最长的一条路径。
换句话说,要找到两个点,使得他们之间的距离最远。
输入格式
第一行包含整数 n n n,
接下来 n − 1 n - 1 n−1行,每行包含三个整数 a i , b i , c i a_i, b_i,c_i ai,bi,ci,表示点 a i a_i ai和 b i b_i bi之间存在一条权值为 c i c_i ci的边。
输出格式
输出一个整数,表示树的最长路径的长度。
数据范围
1 ≤ n ≤ 10000 1 \le n \le 10000 1≤n≤10000,
1 ≤ a i , b i ≤ n 1 \le a_i,b_i \le n 1≤ai,bi≤n,
1 ≤ c i ≤ 10 5 1 \le c_i \le 10^5 1≤ci≤105
思路
找树的最长路径(直径)有一个通用的思路:
- 任选一个点,找出离这个点最远的点 u u u。
- 再找到离 u u u最远的点 v v v
u u u与 v v v之间的路径就是直径。
证明如下;
假设任选的这个点是 a a a,找到离他最远的点为 u u u,只要证明 u u u是某条直径的一个端点就行了。
假设一条直径为 b c bc bc,那他可能会与 a u au au之间没有交点,由于树是连通的,所以从 a a a开始走一定能走到 c c c点,假设这条路径是 a x y c axyc axyc,其中 x x x在 a u au au上, y y y在 b c bc bc上,由于 u u u是离 a a a最远的点,那么 x u xu xu的长度大于等于 x y + y c xy + yc xy+yc,那么就有 b y + y x + x u ≥ y c by + yx + xu \ge yc by+yx+xu≥yc,因此 b u bu bu之间的距离一定大于等于 b c bc bc的长度,因此 b u bu bu一定是一条直径的端点。
另一种情况是两条线相交,假设交点是 x x x,那么由于 u u u是离 a a a最远的点,就有 u x ≥ x c ux \ge xc ux≥xc,那么 b x + x u ≥ b c bx + xu \ge bc bx+xu≥bc,因此 u u u也一定是一条直径的端点。
由于这道题目并没有指定根节点,因此可以任选一个点将整棵树构建起来,然后对于每个点记录经过该点的最长路径。
对于一个点的最长路径,对于每个点来说可以分为两种情况,一种是往下走,一种是往上走。就是枚举他的每个子节点存的最大距离再加上他到这个子节点的距离;另一种情况是穿过一个点的路径,那么就可以计算这个点往下的最长的路径以及第二长的路径相加。
代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;const int N = 10010, M = N * 2;int n;
int h[N], e[M], ne[M], w[M], idx;
int ans;void add(int a, int b, int c)
{w[idx] = c, e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}int dfs(int u, int father)
{int dist = 0;int d1 = 0, d2 = 0;for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];if(j == father) continue;int d = dfs(j, u) + w[i];dist = max(dist, d);if(d >= d1){d2 = d1;d1 = d;} else if(d > d2) d2 = d;}ans = max(ans, d1 + d2);return dist;
}int main()
{cin >> n;memset(h, -1, sizeof h);for(int i = 0; i < n - 1; i ++){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a, c);}dfs(1, -1);cout << ans << endl;return 0;
}
Acwing 1073. 树的中心
给定一棵树,树中包含 n n n个节点(编号 1 ∼ n 1 \sim n 1∼n)和 n − 1 n - 1 n−1条无向边,每条边都有一个权值。
请你在树中找到一个点,使得该点到树中其他结点的最远距离最近。
输入格式
第一行包含整数 n n n,
接下来 n − 1 n - 1 n−1行,每行包含三个整数 a i , b i , c i a_i, b_i,c_i ai,bi,ci,表示点 a i a_i ai和 b i b_i bi之间存在一条权值为 c i c_i ci的边。
输出格式
输出一个整数,表示所求点到树中其他结点的最远距离。
数据范围
1 ≤ n ≤ 10000 1 \le n \le 10000 1≤n≤10000,
1 ≤ a i , b i ≤ n 1 \le a_i,b_i \le n 1≤ai,bi≤n,
1 ≤ c i ≤ 10 5 1 \le c_i \le 10^5 1≤ci≤105
思路
与上一题一样,对于树中的一点有向上走与向下走两种方案,每个点都记录一个向上走与向下走的最大值,假设点 2 2 2向其父节点 1 1 1走,那么这就是向上走,在 1 1 1点可以继续向上走,也可以向下不经过点 2 2 2的子节点走,若向下走,那就要考虑点 2 2 2是否是向下走的最大长度,如果是,那就使能选择次大值更新。
这一题复杂的地方在于,更新的过程同时用到了子节点更新父节点和父节点更新子节点。
代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;const int N = 100010, M = N * 2, inf = 0x3f3f3f3f;int n;
int h[N], e[M] ,w[M], ne[M], idx;
int d1[N], d2[N], up[N];
int p1[N], p2[N];void add(int a, int b, int c)
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}int dfs_d(int u, int father)
{if(h[u] == -1) return 0;d1[u] = d2[u] = -inf;for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];if(j == father) continue;int d = dfs_d(j, u) + w[i];if(d >= d1[u]){d2[u] = d1[u], d1[u] = d;p2[u] = p1[u], p1[u] = j; // 记录最大值和次大值是从向哪个子节点走的} else if(d > d2[u])d2[u] = d, p2[u] = j;}if(d1[u] == -inf) d1[u] = d2[u] = 0; // 如果是叶子结点无法往下,置为0return d1[u];
}int dfs_u(int u, int father)
{if(h[u] == -1) return 0;for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];if(j == father) continue;if(p1[u] == j) up[j] = max(up[u], d2[u]) + w[i];else up[j] = max(up[u], d1[u]) + w[i];dfs_u(j, u);}
}int main()
{cin >> n;memset(h, -1, sizeof h);for(int i = 0; i < n - 1; i ++){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a, c);}dfs_d(1, -1);dfs_u(1, -1);int res = inf;for(int i = 1; i <= n; i ++) res = min(res, max(up[i], d1[i]));cout << res << endl;return 0;}
Acwing 1075. 数字转换
如果一个数 x x x的约数之和 y y y(不包括他本身)比他本身小,那么 x 可以变成 x可以变成 x可以变成 y y y, y y y也可以变成 x x x。
例如 4 4 4可以变成 3 3 3, 1 1 1可以变成 7 7 7
限制所有数字变换在不超过 n n n的正整数范围内进行,求不断进行数字变换且不出现重复数字的最多变换步数。
输入格式
输入一个正整数 n n n。
输出格式
输出断进行数字变换且不出现重复数字的最多变换步数
数据范围
1 ≤ n ≤ 50000 1 \le n \le 50000 1≤n≤50000
思路
对于每个数 x x x都会有一个约数之和 y y y与之对应,且 x x x到 y y y的关系是唯一的,但需要注意的是 y y y可能会对应于多个数,因此要将 y y y作为父节点。那么对于所有数就可以构建出一堆树(注意不是一棵树,因为不一定所有数都能连通),最多变换步数就是这堆树中最长的树的直径,就是上面的第一题。
问题就是建树,也就是找到 1 ∼ n 1 \sim n 1∼n中所有数的约数之和。当然可以枚举每个数进行计算(试除法),但是如果 n n n的范围进一步扩大就会超时。可以反向思考,不是求每个数的约数是哪些数,而是求每个数是哪些数的约数,也就是枚举每个数的倍数
for(int i = 1; i <= n; i ++)for(int j = 2; j * i <= n; j ++) // 从2开始枚举
这样的时间复杂度是 n ln n n \ln{n} nlnn,因为 n + n 2 + n 3 + ⋯ n + \frac{n}{2} + \frac{n}{3} + \cdots n+2n+3n+⋯是一个调和级数,
代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;const int N = 50010;int n;
int sum[N];
int h[N], e[N], ne[N], idx;
bool st[N];
int ans;void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}int dfs(int u)
{int d1 = 0, d2 = 0;for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];int d = dfs(j) + 1;if(d >= d1) d2 = d1, d1 = d;else if(d > d2) d2 = d;}ans = max(ans, d1 + d2);return d1;
}int main()
{cin >> n;memset(h, -1, sizeof h);for(int i = 1; i <=n; i ++)for(int j = 2; j <= n / i; j ++)sum[i * j] += i;for(int i = 2; i <= n; i ++) // 建立边的时候要从2开始,因为对于1来说,他会和0建边,题目要求是正整数。if(sum[i] < i){add(sum[i], i);st[i] = true;}for(int i = 1; i <= n; i ++)if(!st[i])dfs(i);cout << ans << endl;return 0;
}
Acwing 1074. 二叉苹果树
有一颗苹果树,如果树枝有分岔,一定是分两叉,即没有只有一个儿子的节点。
这棵树共 N N N个节点,编号为 1 1 1至 N N N,树根编号一定是 1 1 1。
我们用一根树枝两端连接的节点编号描述一根树枝的位置。
一棵苹果树的树枝太多了,需要剪枝,但是一些树枝上长有苹果,给定需要保留的树枝数量,求最多能留住多少苹果,这里的保留是指最终与 1 1 1号点连通。
输入格式
第一行包含两个整数 N N N和 Q Q Q,分别表示树的节点数以及要保留的树枝数量。
接下来 N − 1 N - 1 N−1行描述树枝信息,每行三个整数,前两个是它连接的节点的编号,第三个数是这根树枝上苹果数量。
输出格式
输出仅一行,表示最多能留住的最多的苹果数量。
数据范围
1 < Q < N ≤ 100 1 < Q < N \le 100 1<Q<N≤100
每根树枝上苹果不超过 30000 30000 30000个。
思路
在[背包模型四](数据结构与算法学习笔记(Acwing提高课)----动态规划·背包模型(四)-CSDN博客)中讲过一道有依赖的背包问题,其实这道题和那道题是一样的,将苹果数量放到每个点上,要选择一个点就要选择它的父节点,将所有点的体积看为 1 1 1,总的体积就是 Q Q Q。
但是这题可以进一步简化,使用 f [ i ] [ j ] f[i][j] f[i][j]表示以 i i i为根的子树中选择 j j j个树枝的最大价值。
对于状态划分来说,对于每个具有两个分岔的小子树,将其两个子节点看成是一个分组背包问题里的两个物品组,也就是对于以 i i i为根的子树有两个物品 s 1 s_1 s1与 s 2 s_2 s2,划分为在 s 1 s_1 s1中选择 0 0 0条边,那就是 f [ s 1 ] [ 0 ] f[s_1][0] f[s1][0];选择 1 1 1条边,那就是 f [ s 1 ] [ 1 ] f[s_1][1] f[s1][1];以此类推,最多是 f [ s 1 ] [ j − 1 ] f[s_1][j - 1] f[s1][j−1],因为要选择 s 1 s_1 s1就要选择 i i i,也就是必选 i → j i \rightarrow j i→j这条边,当然计算的时候要加上这条边的权重。对于子树 s 2 s_2 s2也是一样的。
代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;const int N = 110, M = N * 2;int n, m;
int f[N][N];
int h[N], e[M], ne[M], w[M], idx;void add(int a, int b, int c)
{w[idx] = c, e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}void dfs(int u, int father)
{for(int i = h[u]; i != -1; i = ne[i]) // 枚举物品组{if(e[i] == father) continue;dfs(e[i], u);for(int j = m; j >= 0; j --) // 体积for(int k = 0; k < j; k ++) // 决策f[u][j] = max(f[u][j], f[u][j - k - 1] + f[e[i]][k] + w[i]);}
}int main()
{cin >> n >> m;memset(h, -1, sizeof h);for(int i = 0; i < n - 1; i ++){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a, c);}dfs(1, -1);cout << f[1][m] << endl;return 0;
}
Acwing 323. 战略游戏
鲍勃喜欢玩电脑游戏,特别是战略游戏,但有时他找不到解决问题的方法,这让他很伤心。
现在他有以下问题。
他必须保护一座中世纪城市,这条城市的道路构成了一棵树。
每个节点上的士兵可以观察到所有和这个点相连的边。
他必须在节点上放置最少数量的士兵,以便他们可以观察到所有的边。
你能帮助他吗?
例如,下面的树:
只需要放置 1 1 1名士兵(在节点 1 1 1处),就可观察到所有的边。
输入格式
输入包含多组测试数据,每组测试数据用以描述一棵树。
对于每组测试数据,第一行包含整数 N N N,表示树的节点数目。
接下来 N N N 行,每行按如下方法描述一个节点。
节点编号:(子节点数目) 子节点 子节点 …
节点编号从 0 0 0 到 N − 1 N−1 N−1,每个节点的子节点数量均不超过 10 10 10,每个边在输入数据中只出现一次。
输出格式
对于每组测试数据,输出一个占据一行的结果,表示最少需要的士兵数。
数据范围
0 < N ≤ 1500 0 < N \le 1500 0<N≤1500
思路
这道题的题意是对于一颗树,选择最少的节点数覆盖所有的边,这个其实和没有上司的舞会很像,在没有上司的舞会中,我们求的是每条边上最多仅选择一个点求最大值,属于最大独立集问题,而这道题中,每条边上至少选择一个点求最小值,这两个是对称的问题。
状态计算和状态转移也很简单,直接看代码叭。
代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;const int N = 1600;int n;
int f[N][2];
int h[N], e[N], ne[N], idx;
bool st[N];void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}void dfs(int u)
{f[u][0] = 0;f[u][1] = 1;for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];dfs(j);f[u][0] += f[j][1];f[u][1] += min(f[j][0], f[j][1]);}
}int main()
{while(scanf("%d", &n) != -1){idx = 0;memset(h, -1, sizeof h);memset(st, 0, sizeof st);for(int i = 0; i < n; i ++){int cnt;int id;scanf("%d:(%d)", &id, &cnt);while(cnt --){int ver;cin >> ver;add(id, ver);st[ver] = true;}}int root = 0;while(st[root]) root ++;dfs(root);cout << min(f[root][1], f[root][0]) << endl;}return 0;
}
Acwing 1077. 皇宫看守
太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫。
皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状,某些宫殿间可以互相望见。
大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用不同。
可是陆小凤手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫。
帮助陆小凤布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少。
输入格式
输入中数据描述一棵树,描述如下:
第一行 n n n,表示树中结点的数目。
第二行至第 n + 1 n + 1 n+1行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号为 i i i,在该宫殿内安置侍卫所需的经费 k k k,该边的儿子数 m m m,接下来 m m m个数,分别是这个结点的 m m m个儿子的编号 r 1 , r 2 , ⋯ , r m r_1, r_2, \cdots, r_m r1,r2,⋯,rm
对于一个 n n n个节点的树,结点标号在 1 1 1到 n n n之间,且标号不重复。
输出格式
输出最少的经费。
数据范围
0 < N ≤ 1500 0 < N \le 1500 0<N≤1500
思路
在这题中,同样是挑选足够的点完成整颗树的覆盖,但是对于每条边来说,这一题的状态表示与之前并不一样,使用 f [ i ] [ 0 ] f[i][0] f[i][0]表示点 i i i被父节点看到的最小花费, f [ i ] [ 1 ] f[i][1] f[i][1]表示点 i i i被子节点看到的最小花费, f [ i ] [ 2 ] f[i][2] f[i][2]表示点 i i i上摆放守卫的最小花费。
对于状态转移,当节点状态为 f [ i ] [ 0 ] f[i][0] f[i][0]时,那么他的最小花费就是他的所有子节点状态为 1 1 1或 2 2 2时的和,但是他的子节点不可能是 0 0 0,因为 i i i是 0 0 0,表示没有放侍卫,就不可能看到他的子节点,所以他的子节点只能是另外两种状态;当节点状态为 f [ i ] [ 2 ] f[i][2] f[i][2]时,它的子节点可以是三种状态,因为它上面放了侍卫;当节点状态为 f [ i ] [ 1 ] f[i][1] f[i][1]时,表示他是被子节点看到的,因此需要枚举是哪个子节点看到的它,然后取最小值就行,假设是 k k k这个结点看到了 i i i,那么一定要有 f [ k ] [ 2 ] f[k][2] f[k][2],其他的子节点可以是 1 1 1和 2 2 2。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;const int N = 1510;int n;
int f[N][3];
int h[N], e[N], w[N], ne[N], idx;
bool st[N];void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}void dfs(int u)
{f[u][2] = w[u];for(int i = h[u]; i != -1; i = ne[i]){int j = e[i];dfs(j);f[u][0] += min(f[j][1], f[j][2]);f[u][2] += min(f[j][0], min(f[j][1], f[j][2]));}f[u][1] = 1e9;for(int i = h[u]; i != -1; i = ne[i]){int j = e[i]; // 枚举是哪个子节点看到当前节点uf[u][1] = min(f[u][1], f[j][2] + f[u][0] - min(f[j][1], f[j][2]));}
}int main()
{cin >> n;memset(h, -1, sizeof h);for(int i = 1; i <= n; i ++){int id, cnt, cost;cin >> id >> cost >> cnt;w[id] = cost;while(cnt --){int ver;cin >> ver;add(id, ver);st[ver] = true;}}int root = 1;while(st[root]) root ++;dfs(root);cout << min(f[root][1], f[root][2]) << endl;return 0;
}
相关文章:

数据结构与算法学习笔记(Acwing 提高课)----动态规划·树形DP
数据结构与算法学习笔记----动态规划树形DP author: 明月清了个风 first publish time: 2025.6.4 ps⭐️树形动态规划(树形DP)是处理树结构问题的一种动态规划方法,特征也很明显,会有一个树形结构,其实是DFS的优化。…...
FTP 和 SFTP 介绍及 C/C++ 实现分析
1. FTP 协议概述 FTP(File Transfer Protocol)是一种用于在网络上进行文件传输的标准协议,诞生于 1971 年,是互联网上最早的应用层协议之一。它基于客户端 - 服务器模型,使用 TCP 作为传输层协议,默认通过 …...

leetcode hot100刷题日记——36.最长连续序列
解答: 实际上在哈希表中存储不重复的数字。 然后遍历哈希表,找间隔,更新最大间隔。 class Solution { public:int longestConsecutive(vector<int>& nums) {unordered_set<int>hash;for(int num:nums){hash.insert(num);}in…...

CentOS7关闭防火墙、Linux开启关闭防火墙
文章目录 一、firewalld开启、关闭防火墙1、查看防火墙状态 一、firewalld开启、关闭防火墙 以下命令在linux系统CentOS7中操作开启关闭防火墙 # 查询防火墙状态 systemctl status firewalld.service # 开启防火墙 systemctl start firewalld.service # 开机自启动防火墙 syste…...

PyTorch——搭建小实战和Sequential的使用(7)
import torch from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linearclass TY(nn.Module):def __init__(self):"""初始化TY卷积神经网络模型模型结构:3层卷积池化,2层全连接设计目标:处理32x32像素的…...
基于大模型的腔隙性脑梗塞风险预测及治疗方案研究
目录 一、引言 1.1 研究背景与意义 1.2 研究目的与方法 1.3 国内外研究现状 二、腔隙性脑梗塞概述 2.1 定义与分类 2.2 发病机制与病理生理过程 2.3 临床表现与诊断方法 三、大模型技术原理与应用现状 3.1 基本概念与技术架构 3.2 在医疗领域的应用案例与优势 3.3 …...

Python 开发效率秘籍:PyCharm、VS Code 与 Anaconda 配置与实战全解
目录 一、IDE(集成开发环境)是什么?二、Python IDE有哪些,哪款适合初学者?三、Visual Studio Code下载和安装教程3.1 VS Code下载和安装3.2 VS Code运行Python程序 四、PyCharm下载和安装教程4.1 PyCharm下载4.2 PyCharm安装4.3 运行PyCharm4.4 创建工程…...
[C]C语言日志系统宏技巧解析
代码解释:日志标签字符串化宏 这段代码定义了一个名为 _LOG_TAG 的宏,用于将 LOG_TAG_CONST 转换为字符串形式。这在日志系统中很常见,用于为不同模块添加标识前缀。 宏结构分析 #define _LOG_TAG STR(LOG_TAG_CON…...
自动驾驶系统研发系列—激光雷达感知延迟:自动驾驶安全的隐形隐患?
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中一起航行,共同成长,探索技术的无限可能。 🚀 探索专栏:学…...
内网应用如何实现外网访问?无公网IP本地端口网址服务提供互联网连接
一、应用程序外网访问遇到的问题 在现实的工作场景中,在公司内网的服务器上有很多的应用系统,这些系统只能局限于在公司内部使用,而在外网却无法使用。 二、外网访问内网应用常见的解决方案 如何在外网使用这些系统呢?下面简单…...

大话软工笔记—组合要素1之要素
1. 要素来源 对象是要素的来源,要素是从对象分解而来的。可将对象分为优化类和非优化类,如下图所示。 对象分类图 2. 要素的概念 2.1 要素的定义 要素,是构成事物必不可少的因素,要素的集合体构成了对象。 2.2 要素的内容 要…...
oracle从表B更新拼接字段到表A
oracle中表A怎么从表B中追加相对应的编码到表A字段里, 在Oracle数据库中,如果你想从表B中获取数据并更新到表A的某个字段里,可以使用UPDATE语句结合子查询来实现。假设表A有一个字段叫做code,你希望根据某个键(比如id&…...

平台化 LIMS 系统架构 跨行业协同与资源共享的实现路径
在科技快速发展的今天,质检行业正面临着效率、合规和数据安全的多重挑战。新一代质检 LIMS 系统以智能化与平台化为核心,为实验室管理提供了全新的解决方案。 一、智能化:从数据采集到分析的全流程升级 传统质检流程中,人工数据录…...

RedisTemplate查询不到redis中的数据问题(序列化)
RedisTemplate查询不到redis中的数据问题(序列化) 一.问题描述 存入Redis中的值取出来却为null,问题根本原因就是RedisTemplate和StringRedisTemplate的序列化问题、代码示例: SpringBootTest class Redis02SpringbootApplicationTests {Autowiredprivate RedisTe…...
如何利用乐维网管进行IP管理
IP管理是网络管理中的关键环节,对于保障网络的正常运行、提升资源利用效率以及保障网络安全等方面都具有不可忽视的重要性。乐维网管在IP管理方面具有多种实用功能,以下从IP规划与分配、IP状态监测、IP冲突处理、IP审计与报表生成四个方面,介…...
unix/linux,sudo,其历史争议、兼容性、生态、未来展望
sudo作为一个广泛应用的系统工具,在其发展历程中,自然也伴随着一些讨论、挑战和对未来的展望。 一、 历史争议与讨论 (Historical Controversies and Discussions) 虽然sudo被广泛认为是成功的,但也存在一些历史上的讨论点或潜在的争议: 复杂性 vs. 简洁性 (sudoers语法)…...
git stash命令用法
git stash 是 Git 中一个非常有用的命令,它可以临时保存当前工作区的修改,让你可以切换到其他分支或者处理其他任务,而不需要提交这些还未完成的修改。 一、基本用法 1. 保存当前修改(包括暂存区和工作区的内容) git…...

SkyWalking如何实现跨线程Trace传递
一、概述 SkyWalking 的中构建 Trace 信息时会借助 ThreadLocal来存储一些上下文信息,当遇到跨线程的时候,如果 Trace 的上下文信息没有传递到新线程的ThreadLocal 中,那么链路就断开了。那么SkyWalking是如何解决这个问题的呢? …...
软件工程专业的本科生应该具备哪些技能
软件工程专业的本科生需要具备扎实的技术基础、良好的开发流程认知和一定的软技能,以适应软件开发行业的需求。以下从技术技能、开发流程与工具、软技能、实践能力等维度整理核心技能清单,供参考: 一、核心技术技能 1. 编程语言 - 必学基础语…...

使用 Spring Boot 3.3 和 JdbcTemplate 操作 MySQL 数据库
在现代的 Java 应用开发中,Spring Boot 提供了强大的工具来简化数据库操作。JdbcTemplate 是 Spring 提供的一个核心类,用于简化 JDBC 操作,减少样板代码。本文将介绍如何在 Spring Boot 3.3 项目中使用 JdbcTemplate 来操作 MySQL 数据库&am…...
CentOS 7 修改为静态 IP 地址完整指南
在企业网络环境中,服务器通常需要配置静态 IP 地址以确保网络连接的稳定性和可管理性。以下是使用 NetworkManager 工具在 CentOS 7 系统中将动态 IP 配置修改为静态 IP 的完整指南: 一、检查当前网络配置 查看网络连接状态: 使用 nmcli connection show 命令列出所有网络连…...
企业级高防CDN选型指南
#!/bin/bash # 高防CDN性能压测工具 # 使用方法:./stress_test.sh <防护域名>DOMAIN$1 TEST_IP$(dig short $DOMAIN | head -n1) # 获取CDN节点IPecho "[压力测试] 目标: $DOMAIN ($TEST_IP)" echo "----------------------------------"…...
Redis-6.2.9 cluster集群部署和扩容缩容
目录 1 操作系统信息和redis软件版本 2 redis集群架构 3 redis软件安装 4 cluster创建 6 Redis集群节点扩容 7 redis集群节点缩容节点 1 操作系统信息和redis软件版本 rootu24-redis-120:~# cat /etc/issue Ubuntu 24.04.2 LTS \n \l rootu24-redis-120:~# redis-server…...
Java求职者面试指南:DevOps技术栈深度解析
Java求职者面试指南:DevOps技术栈深度解析 一、基础概念问题 1. 请解释什么是Docker? Docker是一个开源的应用容器引擎,它允许开发者将应用程序及其依赖打包到一个可移植的容器中,然后在任何支持Docker的环境中运行。Docker的核…...
生产环境中安装和配置 Nginx 以部署 Flask 应用的详细指南
在生产环境中部署 Flask 应用时,Nginx 常被用作反向代理服务器,与 WSGI 服务器(如 Gunicorn)协同工作。Nginx 可以处理静态文件、提供 SSL/TLS 加密、实现负载均衡等功能。本文将详细介绍如何在 Ubuntu/Debian 系统上安装 Nginx&a…...

Axure高保真LayUI框架 V2.6.8元件库
点击下载《Axure高保真LayUI框架 V2.6.8元件库》 原型效果:https://axhub.im/ax9/bf36e6dd89bc4c9f/#g1 摘要 本文详细阐述了在 Axure 环境下打造的一套高度还原 LayUI 框架的组件元件集。通过对 LayUI 框架组件的深入剖析,结合 Axure 的强大功能&…...

通讯录实现(Linux+Cpp)
通讯录实现(LinuxCpp) 产品底层思考: 人员如何存储 -> 链表 (增删改 但是排序不适合) 文件存储 -> 人员数据的格式 name:xxx,phone:xxx 人员信息 -> 姓名、电话 引出2 name: xxx,phone: xxx,age: xxx,addr…...
K8S主机漏洞扫描时检测到kube-服务目标SSL证书已过期漏洞的一种永久性修复方法
1、背景 PaaS平台102xx、102xx端口检测到目标SSL证书已过期漏洞,分别对应kube-controller-manager证书、kube-scheduler证书。 2、系统版本 1.0、2.0版本均涉及。 k8s 1.19、1.23版本均涉及。 3、故障现象 PaaS平台部署1年以后,在主机漏洞扫描时&a…...

质检 LIMS 系统数据防护指南 三级等保认证与金融级加密方案设计
面对频发的数据泄露事件,企业亟需构建一套 “防得住、追得回、打得赢” 的防护体系。质检 LIMS 系统通过三级等保认证与金融级加密的结合,为这一目标提供了可行路径。 一、金融级加密:构建数据防护的 “铜墙铁壁” 金融级加密技术通过协议加密…...

Spring Boot 从Socket 到Netty网络编程(上):SOCKET 基本开发(BIO)与改进(NIO)
前言 无论是软件还是硬件的本质都是要解决IO问题(输入、输出),再说回网络编程本质上都是基于TCP/UP的开发,socket是在此基础上做的扩展与封装,而Netty又是对socket做的封装。本文旨在通过相关案例对socket进行探讨。 一…...