6.8 note
paxos算法_初步感知
Paxos算法保证一致性主要通过以下几个关键步骤和机制:
准备阶段
- 提议者向所有接受者发送准备请求,请求中包含一个唯一的编号。
- 接受者收到请求后,会检查编号,如果编号比它之前见过的都大,就会承诺不再接受编号更小的提议,并回复提议者,告知自己已接受过的最大编号的提议。
提议阶段
- 提议者收到多数接受者的回复后,根据回复内容来确定提议的值。如果有接受者在回复中包含了已接受的提议值,提议者就从中选择编号最大的提议值作为自己要提议的值;如果没有,提议者就自己选择一个值。然后,提议者将选定的值和编号一起作为提议发送给接受者。
- 接受者收到提议后,只有在之前没有承诺过不接受该提议,并且提议的编号不小于它之前见过的最大编号时,才会接受该提议。
学习阶段
- 一旦有多数接受者接受了某个提议,这个提议就被认为是达成了一致。此时,系统中的其他节点可以通过学习这个已达成一致的提议来更新自己的状态,从而保证整个系统的一致性。
通过这一系列的步骤,Paxos算法能够在分布式系统中,即使存在节点故障、消息丢失等情况,也能保证最终达成一致的状态,确保数据的一致性和正确性
举个栗子🌰
假设你和一群朋友打算一起去看电影,但是对于看哪部电影大家有不同的想法,这时就可以用类似Paxos算法的方式来达成一致:
准备阶段
- 你主动站出来成为“提议者”,你先给每个朋友发消息说:“我准备提议看一部电影,我现在的提议编号是1(这个编号是唯一且不断递增的),你们之前有没有收到过其他人的提议呀?如果有,是关于看什么电影的,编号是多少呢?”
- 朋友们收到消息后,会查看自己收到过的提议编号。如果你的编号比他们之前收到的都大,他们就会回复你,比如有的朋友会说:“我之前没收到过提议。”有的朋友可能会说:“我之前收到过提议看电影A,编号是0。”同时,他们会承诺不再接受编号小于1的提议。
提议阶段
- 你收到朋友们的回复后,发现有朋友提到了之前看过的提议看电影A,编号是0,而你的编号是1更大,所以你可以选择自己重新提议看电影B,也可以选择就提议看电影A。然后你把你的提议(比如看电影B,编号是1)发给朋友们。
- 朋友们收到你的提议后,会检查这个提议的编号是不是不小于他们之前见过的最大编号,并且他们之前没有承诺过不接受这个提议。如果满足条件,他们就会接受这个提议,比如同意一起去看电影B。
学习阶段
- 当有超过一半的朋友都接受了看电影B这个提议,那么就相当于大家达成了一致,决定一起去看电影B。然后大家就可以一起去看电影,保证了所有人的行动一致。
在这个过程中,即使有朋友一开始没收到消息,或者中间有消息延迟等情况,只要最终大家都按照这个流程来,就能保证最终能就看哪部电影达成一致,就像Paxos算法在分布式系统中保证数据一致性一样。
Paxos算法这样的一致性算法的设计思路是基于对分布式系统中一致性问题的深刻理解和长期的研究探索逐渐形成的,主要考虑以下几个方面:
问题分析
- 分布式系统中存在节点故障、网络延迟、消息丢失等问题,要保证数据在多个节点间的一致性,需要设计一种能在复杂环境下达成共识的机制。
- 借鉴现实生活中类似议会投票等协商场景的经验,思考如何通过类似的投票、协商过程让分布式系统中的节点就某个值达成一致。
关键原则确定
- 安全性原则是确保只有被多数节点认可的值才能被选定,防止出现不一致的情况。就像在选举中,只有获得多数选票的候选人才能当选,保证结果的唯一性和确定性。
- 活性原则是保证系统能够不断推进,不会因为某些故障或异常而陷入死循环或无法做出决策的状态。例如,通过给提议编号等方式,让系统能够区分不同的提议,避免重复或无效的提议导致系统停滞。
逐步构建算法
- 先设计准备阶段,让提议者了解系统中已有的提议情况,同时让接受者承诺不接受低编号提议,为后续提议的顺利进行奠定基础。这一步就像在会议前先收集各方意见,确定大家的基本立场。
- 再设计提议阶段,提议者根据准备阶段的反馈确定提议值并发送给接受者,接受者根据一定规则决定是否接受提议。这个过程类似会议中的讨论和表决环节。
- 最后通过学习阶段,让系统中的其他节点能够得知达成一致的结果,从而实现整个系统的一致性更新。
通过这样从问题分析到关键原则确定,再到逐步构建算法的过程,经过不断地理论推导、实践验证和优化,最终形成了Paxos算法这种能够有效保证分布式系统一致性的经典算法。
rabbitmq 6种模式
sql连接
select p.FirstName,p.LastName,a.City,a.State
from
person p left join address a
on
p.personid=a.personid
2的幂再和,二进制取模相加==n
1. 分解n为2的幂次:
- 利用二进制特性,n的每一位1对应一个唯一的2的幂次(如n=10=8+2=2³+2¹,对应powers=[2,8])。
- 通过不断对n取余和整除2,提取每一位二进制位,将对应的幂次存入 powers 数组。
2. 处理查询:
- 每个查询给出一个区间 [l, r] ,表示求 powers[l] * powers[l+1] * ... * powers[r] 的结果。
- 由于结果可能很大,每次乘法后都对 1e9+7 取模(利用模运算性质防止溢出)。
3. 注意点:
- 使用 long long 存储中间结果,避免整数溢出。
- powers 数组的下标直接对应查询中的区间端点(如查询 [0,2] 表示取前3个幂次相乘)。
示例理解:
- - 若 n=15 (二进制 1111 ),则 powers = [1,2,4,8] 。
- - 查询 [0,2] 对应计算 1*2*4=8 ,查询 [1,3] 对应 2*4*8=64 。
class Solution {
public:
vector<int> productQueries(int n, vector<vector<int>>& queries) {
// 造powers数组
vector<int> powers;
// 由n变到1powers数组
for(int i=0,i1=1,j=0;n>0;)
{
i=n%2;
if(i==1) {powers.push_back(i1);j++;}
n/=2;i1*=2;
}
// return powers;
// 造answers数组
vector<int> answers;
for(int i=0; i<queries.size(); i++)
{
long long ans=1;
int c=1e7;
for(int k=queries[i][0]; k<=queries[i][1]; k++)
{ans=((ans%c)*(powers[k]%c))%c;}
//求区间乘积
//利用了(a*b)%c=((a%c)*(b%c))%c 拆分取模,防止溢出
answers.push_back(ans);
}
return answers;
}
};
爬楼梯
class Solution {
public:
int climbStairs(int n)
{
if(n<3) return n;
vector<int> dp(n+1);
dp[1]=1,dp[2]=2;
for(int i=3;i<=n;i++)
{
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
};
接雨水
这段代码用「栈」来计算接雨水的量,核心逻辑是:
从左到右遍历每个柱子,用栈记录「可能成为左边边界」的柱子下标。
当遇到更高的柱子(右边界)时,计算两者之间的「凹槽储水量」:
1. 弹出栈顶(中间柱子),若栈空则无法形成凹槽,跳过。
2. 确定左右边界:新栈顶是左边界,当前下标是右边界。
3. 计算高度差:左右边界的最小值 - 中间柱子高度,得到储水高度。
4. 计算宽度:右边界下标 - 左边界下标 - 1,乘高度得到水量,累加到结果。
举例:柱子高度为 [0,1,0,2,1,0,1,3,2,1,2,1] ,
遍历到 i=3 (高度2)时,栈中是 [0,1] (高度0,1),
弹出1(高度1),左边界是0(高度0),右边界是3(高度2),
储水高度 = min(0,2) - 1 = -1?不,这里实际是 min(左边界高度, 右边界高度) - 中间高度,
左边界高度是 height[0]=0 ,右边界是 height[3]=2 ,中间是 height[1]=1 ,
所以储水高度是 0-1?不对! 哦这里发现描述有误,正确逻辑是:只有左右边界都高于中间柱子时才有储水,
所以当右边界高度 > 中间柱子时,左边界必须存在且高度 > 中间柱子,
此时储水高度 = min(左边界高度, 右边界高度) - 中间高度,
宽度是右边界下标 - 左边界下标 - 1。
代码通过栈动态维护左右边界,逐个计算每个凹槽的水量,最终总和就是答案。
int trap(vector<int>& height)
{
int ans = 0;
stack<int> st;
for (int i = 0; i < height.size(); i++)
{
while (!st.empty() && height[st.top()] < height[i])
{
int cur = st.top();
st.pop();
if (st.empty()) break;
int l = st.top();
int r = i;
int h = min(height[r], height[l]) - height[cur];
ans += (r - l - 1) * h;
}
st.push(i);
}
return ans;
}
双指针
class Solution {
public:
int trap(vector<int>& height) {
int ans = 0, left = 0, right = height.size() - 1, pre_max = 0, suf_max = 0;
while (left < right) {
pre_max = max(pre_max, height[left]);
suf_max = max(suf_max, height[right]);
ans += pre_max < suf_max ? pre_max - height[left++] : suf_max - height[right--];
}
return ans;
}
};
dfs超时优化
注意到 十的九次方
原代码,超时
class Solution {
public:
int n=0;
vector<int> ans;
int findKthNumber(int n, int k)
{
this->n=n;
for(int i=1;i<10;i++)
{
dfs(i);
}
return ans[k-1];
}
void dfs(int num)
{
if(num>n)
{
return;
}
ans.push_back(num);
for(int i=0;i<10;i++)
{
dfs(num*10+i);
}
}
};
数学优化
class Solution {
public:
long getCount(long prefix, long n) {
long cur = prefix;
long next = cur + 1;
long count = 0;
while(cur <= n) {
count += min(n+1, next) - cur;
cur *= 10;
next *= 10;
}
return count;
}
int findKthNumber(int n, int k) {
long p = 1;
long prefix = 1;
while(p < k) {
long count = getCount(prefix, n);
if (p + count > k) {
/// 说明第k个数,在这个前缀范围里面
prefix *= 10;
p++;
} else if (p+count <= k) {
/// 说明第k个数,不在这个前缀范围里面,前缀需要扩大+1
prefix++;
p += count;
}
}
return static_cast<int>(prefix);
}
};
优化思路:
1. 字典序规则:
像查字典一样,先比首位,再比第二位。例如:
- - 1开头的数(1,10,11,12…)比2开头的数(2,20,21…)更小。
2. 关键函数 getCount :
计算以 prefix (如1、10)开头的数字有多少个≤n。
- - 比如 prefix=1 ,n=20时,包含1、10-19、20(共1+10+1=12个)。
- - 计算方式:逐层扩展(1→10→100),每次算当前层有多少个数在n以内。
3.理解
- p++ 是深入子节点找下一个数,
- p += count 是跳过当前前缀,去下一个前缀找。
十叉树
把数字看作树,用子树大小判断第k个数在左子树还是右兄弟:
- - 子树够大:钻进左子树( node*=10 )。
- - 子树不够大:跳过左子树,去右兄弟( node++ )。
通过这种方式,每次跳跃式减少k的范围,效率极高(对数级时间复杂度)。
class Solution {
public:
int findKthNumber(int n, int k) {
// 逐层统计 node 子树大小
auto count_subtree_size = [&](int node) -> int {
// 子树大小不会超过 n,所以 size 用 int 类型
// 但计算过程中的 left 和 right 会超过 int,所以用 long long 类型
int size = 0;
long long left = node, right = node + 1;
while (left <= n) {
// 这一层的最小值是 left,最大值是 min(right, n + 1) - 1
size += min(right, n + 1LL) - left;
left *= 10; // 继续,计算下一层
right *= 10;
}
return size;
};
int node = 1;
k--; // 访问节点 node
while (k > 0) {
int size = count_subtree_size(node);
if (size <= k) { // 向右,跳过 node 子树
node++; // 访问 node 右侧兄弟节点
k -= size; // 访问子树中的每个节点,以及新的 node 节点
} else { // 向下,深入 node 子树
node *= 10; // 访问 node 的第一个儿子
k--; // 访问新的 node 节点
}
}
return node;
}
};
线程
❗模拟➕贪心
要么都变成 1,要么都变成 -1,因此先枚举要变成哪个。
剩下的问题就是一个经典的贪心。
由于乘以 -1 两次之后会变回原数,因此每个下标最多选择一次,且下标选择的顺序没有关系。
不妨假设操作是从左到右进行的。
从左到右考虑每个下标,如果当前值不是目标值,由于后续操作只会影响右边的数,再不操作就没机会了,所以此时必须要选择该下标。
按该贪心思路算出最少操作次数即可,复杂度 O(n) 。
思维题:想到传递的目标判断即可
其实也还可以找奇偶的规律,但是还是这种更好
class Solution {
public:
bool canMakeEqual(vector<int>& nums, int K) {
int n = nums.size();
// 所有值都变成 x 的最少操作次数
auto check = [&](int x) {
int cnt = 0;
vector<int> vec = nums;
// 从左到右考虑每个下标,如果不是目标值,必须操作
for (int i = 0; i + 1 < n; i++) if (vec[i] != x) {
vec[i] *= -1;
vec[i + 1] *= -1;
cnt++;
}
return vec[n - 1] == x && cnt <= K;
};
// 枚举最后变成 1 还是 -1
return check(1) || check(-1);
}
};
总结:
1. 枚举目标:结果只有两种可能——全 1 或者全 -1 。所以我们分别试试这两种情况,看哪种能实现(这就是 “枚举” ,把可能的目标全列出来试)。
2. 贪心操作:确定目标(比如要全 1 )后,怎么操作最省次数?
- 规则是 “选一个下标 i , nums[i] 和 nums[i+1] 都变号” 。而且变号两次等于没变(比如 1 变 -1 再变 1 ),所以每个位置最多操作一次,从左到右处理最合理 。
- 举个例子:数字是 [-1, -1, 1] ,目标要全 1 。从左开始看,第一个数是 -1 (不是目标 1 ),必须操作下标 0 ,让 nums[0] 和 nums[1] 变号,变成 [1, 1, 1] ,这样一次就解决。如果不操作当前下标,后面操作不影响前面,就永远变不成目标了,所以 “遇到不一样的,必须当下操作” ,这就是贪心的 “贪”—— 抓住当下机会,保证结果最优。
移动模拟_优化
原代码
class Solution {
public:
int N;
void move(char c, vector<int>& pos, vector<int>& t) {
if (c == 'L') pos[1] -= 1;
if (c == 'R') pos[1] += 1;
if (c == 'U') pos[0] -= 1;
if (c == 'D') pos[0] += 1;
t = pos;
}
bool check(vector<int>& pos) {
if (pos[0] >= 0 && pos[0] < N && pos[1] >= 0 && pos[1] < N) return true;
else return false;
}
vector<int> executeInstructions(int n, vector<int>& startPos, string s) {
vector<int> res(s.size());
N = n;
for (int i = 0; i < s.size(); i ++ ) {
vector<int> tempos(startPos);
int temres = 0;
for (int j = i; j < s.size(); j ++ ) {
vector<int> t(2);
move(s[j], tempos, t);
if (check(t)) temres ++ ,tempos = t;
else break;
}
res[i] = temres;
}
return res;
}
};
优化:
改用迭代器并内联函数的 C++ 代码(主要修改循环和容器操作部分):
class Solution {
public:
int N;
// 内联移动函数(用引用避免拷贝)
inline void move(char c, vector<int>& pos, vector<int>& t) {
switch(c) {
case 'L': pos[1]--; break;
case 'R': pos[1]++; break;
case 'U': pos[0]--; break;
case 'D': pos[0]++;
}
t = pos; // 更新目标位置
}
// 内联边界检查
inline bool check(const vector<int>& pos) {
return pos[0] >= 0 && pos[0] < N && pos[1] >= 0 && pos[1] < N;
}
vector<int> executeInstructions(int n, vector<int>& startPos, string s) {
vector<int> res(s.size());
N = n;
// 使用迭代器遍历字符串
for(auto it_i = s.begin(); it_i != s.end(); ++it_i) {
vector<int> currentPos = startPos;
int count = 0;
// 从当前迭代器位置开始遍历
for(auto it_j = it_i; it_j != s.end(); ++it_j) {
vector<int> tempPos(2);
move(*it_j, currentPos, tempPos); // 传入字符值
if(check(tempPos)) {
count++;
currentPos = tempPos; // 更新当前位置
} else {
break; // 越界则终止
}
}
res[it_i - s.begin()] = count; // 计算索引
}
return res;
}
};
主要改动点:
1. 函数内联:使用 inline 关键字声明 move 和 check 函数(现代编译器可能自动优化,但显式声明更清晰)
2. 迭代器替代索引:
- 外层循环用 s.begin() / end() 迭代器遍历
- 内层循环从当前迭代器位置 it_i 开始
- 通过 it_i - s.begin() 计算结果数组索引
3. 代码优化:
- switch 替代多个 if 提高分支效率
- currentPos 直接修改减少拷贝(原代码中 tempos = t 可直接操作 currentPos )
- const 修饰 check 函数参数避免意外修改
注意:C++ 中容器迭代器在动态扩容时可能失效,但此处 string 是固定长度,迭代器始终有效,无需担心此问题。
内联函数
内联函数是一种用 inline 关键字声明的特殊函数,目的是让编译器在编译时直接把函数代码「嵌入」到调用它的地方,避免普通函数调用的「跳转开销」,提高程序运行速度。
举个简单例子:
假设有个函数计算两数之和:
int add(int a, int b) {
return a + b;
}
普通调用时,程序会「跳转到函数地址执行代码,再跳转回来」。
如果声明为内联函数:
inline int add(int a, int b) {
return a + b;
}
编译时,编译器会把 add(3,5) 直接替换成 3+5 ,就像你直接写在代码里一样,省去了跳转步骤。
关键特点:
1. 编译时替换:不是运行时调用,而是编译阶段直接「展开代码」。
2. 适合简单函数:通常用于代码量少(如几行)、调用频繁的函数(比如循环里的小操作)。
3. 可能被编译器忽略:最终是否内联由编译器决定(太复杂的函数会被拒绝)。
优点 vs 缺点:
- - 优点:减少函数调用开销,提升执行效率。
- - 缺点:如果函数被多次调用,会导致目标代码体积增大(用空间换时间)。
总结:内联函数就像「把常用的小工具直接粘在使用的地方」,省去了拿工具的步骤,但粘太多会占地方。
相关文章:

6.8 note
paxos算法_初步感知 Paxos算法保证一致性主要通过以下几个关键步骤和机制: 准备阶段 - 提议者向所有接受者发送准备请求,请求中包含一个唯一的编号。 - 接受者收到请求后,会检查编号,如果编号比它之前见过的都大,就会承…...

面试心得 --- 车载诊断测试常见的一些面试问题
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...
Vue项目PDF目录功能集成【一】——方案深度思考
文章目录 项目背景一、方案一:数据透传 外部开发模式二、方案二:内置组件 黑盒模式三、方案三:激活官方实现 可控定制总结 项目背景 本项目是Vue 3 项目,需要使用文件预览组件(pdfjs 当前是作为sdk二次封装引入&am…...
服务器中僵尸网络攻击是指什么?
随着网络业务的不断发展,网络攻击的手段也变得越来越多,各个企业都会受到网络攻击的威胁,其中常见的网络攻击主要有DDOS攻击和CC攻击等类型,今天小编则为大家来介绍僵尸网络攻击是指什么! 僵尸网络主要是指采用一种或者…...
Java编程中常见的条件链与继承陷阱
格式错误的if-else条件链 典型结构与常见错误模式 在Java编程中,if-else条件链是一种常见的多条件处理模式,其标准结构如下: if (condition1) {// 处理逻辑1 } else if (condition2) {// 处理逻辑2 } else...

跟进一下目前最新的大数据技术
搭建最新平台 40C64G服务器,搭建3节点kvm,8C12G。 apache-hive-4.0.1-bin apache-tez-0.10.4-bin flink-1.20.1 hadoop-3.4.1 hbase-2.6.2 jdk-11.0.276 jdk8u452-b09 jdk8终于可以不用了 spark-3.5.5-bin-hadoop3 zookeeper-3.9.3 trino…...
ubuntu 系统分区注意事项
ubuntu 系统分区大小,注意事项: 安装ubuntu系统时,需要进行分区,手动分区时,有一点需要注意。一开始我也没有注意,长时间使用后才发现的问题。 需要注意一点,如果不对 /usr 进行单独分区&…...
当前市场环境下,软件行业的突围之道:技术演进与商业模式重构
一、行业背景:软件行业进入结构性调整期 2024年至今,软件行业面临三重挑战: 宏观经济承压:全球经济放缓,企业IT预算趋于谨慎; 资本市场收缩:融资环境收紧,盈利能力成为生死线&…...
Redis——主从哨兵配置
目录 基础概念 一、核心原理 二、核心特性 三、技术意义与应用价值 四、典型应用场景 案例部署 一、主从复制配置命令 二、哨兵模式部署命令 关键注意事项 基础概念 一、核心原理 内存存储与高性能 Redis 所有数据存储于内存中&…...

系统模块与功能设计框架
系统模块与功能设计框架,严格遵循专业架构设计原则,基于行业标准(如微服务架构、DDD领域驱动设计)构建。设计采用分层解耦模式,确保可扩展性和可维护性,适用于电商、企业服务、数字平台等中大型系统。 系统…...

我爱学算法之—— 前缀和(中)
一、724. 寻找数组的中心下标 题目解析 这道题,给定数组nums,要求我们找出这个数组的中心下标。 **中心下标:**指左侧所有元素的和等于右侧所有元素的和。 如果存在多个中心数组下标,就返回最左侧的中心数组下标。 算法思路 暴…...
leetcode sql50题
在中文站没找到对应的集合,想来自己动手拷贝过来,方便大家面试复习用,对应英文站点: https://leetcode.com/studyplan/top-sql-50/ Select #1757. 可回收且低脂的产品 链接: https://leetcode.cn/problems/recyclable-and-low-fa…...
word操作(持续更新)
1、图片前面(无间隔格式),有像标题标记一样的黑点 word段落左边的黑色小方块小黑点是什么(段落的换行和分页属性)_哔哩哔哩_bilibili...
AURA智能助手在物联网(IoT)和数字化改造领域的使用
要设计一款在物联网(IoT)和数字化改造领域占据市场主导的AURA智能助手,产品经理需从行业痛点、技术架构、商业模式、生态整合四大维度切入,深度融合工业场景的特殊性。以下是系统性设计框架与落地策略: 一、精准定位:直击工业场景核心痛点 1. 解决企业级关键问题 场景痛…...
怎么把自己电脑设置成服务器?
将自己的电脑设置为服务器可以让您托管网站、文件共享或运行各种服务。以下是设置步骤: 基本设置步骤 选择操作系统: Windows:可使用IIS(Internet Information Services)Linux:常用Apache、Nginx等mac…...

Elasticsearch从安装到实战、kibana安装以及自定义IK分词器/集成整合SpringBoot详细的教程ES(三)
DSL官方地址: DSL查询分类 Elasticsearch提供了基于JSON的DSL(https://www.elastic.co/docs/explore-analyze/query-filter/languages/querydsl)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据࿰…...
神经网络 隐藏层
神经网络中隐藏层的数量是一个超参数,其选择取决于任务复杂度、数据规模和计算资源。以下是常见的架构类型及其适用场景: 1. 单层隐藏层(浅神经网络) 结构:输入层 → 1 个隐藏层 → 输出层特点: 仅需调整…...

React Hooks 指南:何时使用 useEffect ?
在 React 的函数组件中,useEffect Hook 是一个强大且不可或缺的工具。它允许我们处理副作用 (side effects)——那些在组件渲染之外发生的操作。但是,什么时候才是使用 useEffect 的正确时机呢?让我们深入探讨一下! 什么是副作用…...

API标准的本质与演进:从 REST 架构到 AI 服务集成
在当今数字化浪潮中,API 已成为系统之间沟通与协作的“语言”,REST(Representational State Transfer,表述性状态转移)是一种基于 HTTP 协议的 Web 架构风格。它不仅改变了 Web 应用开发的方式,也成为构建现…...
C++核心编程_继承同名成员处理方式
问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢? 访问子类同名成员 直接访问即可 访问父类同名成员 需要加作用域 class Base { public:Base(){m_A 100;}void func(){cout << "B…...
PHP文件读取漏洞全面剖析:触发点与利用技术
PHP文件读取漏洞全面剖析:触发点与利用技术 引言 PHP作为Web开发中最流行的语言之一,其文件操作功能强大但也暗藏风险。文件读取漏洞是PHP应用中最常见的安全问题之一,攻击者利用这些漏洞可以读取服务器敏感文件,甚至实现远程代…...
解决SQL Server SQL语句性能问题(9)——SQL语句改写(2)
9.4.3. update语句改写 与Oracle类似,SQL Server中,update语句被用户相关技术人员广泛应用于现实日常工作中。但是,有些情况下,尤其是海量数据场景中,update语句也许会带来性能方面的严重问题或极大隐患。因此,为了解决和消除update语句导致的性能问题或隐患,我们将需对…...
学习英语。
1. 先自己翻译一遍(葫芦背书法) 结构 补充修饰 最核心的记忆 然后再修饰 2.意群之间翻译: 1.意群 对于两个意群合起来翻译 方法1就是着重某一 6.或者意群之间 核心词一个介词 于 对于 介词化修饰 3.句子之间关系 主句1 after句子2 那么句…...
2480: 2020年06月2级T1:计算矩阵边缘元素之和
题目描述 2020年06月2级第一题题目:计算矩阵边缘元素之和 输入一个整数矩阵,计算位于矩阵边缘的元素之和。所谓矩阵边缘的元素,就是第一行和最后一行的元素以及第一列和最后一列的元素。 输入 第一行分别为矩阵的行数m和列数n࿰…...

html - <mark>标签
<mark> 标签在HTML中用于高亮显示文本,通常用于突出显示某些重要的部分。它的默认样式通常是背景色为黄色,但你可以通过CSS自定义其外观。 1. 基本用法 <mark> 标签用于标记文本的高亮显示。它常用于搜索结果中,突出显示匹配的…...

JavaWeb:前端工程化-Vue
Vue工程化 介绍 什么是Vue? 小白眼里前端开发 前端工程化 环境准备 D:\Program Files\nodejs Vue项目-快速入门 步骤 D:\front\vue 安装依赖 目录结构 code . vscode打开 启动 VScode侧边栏左下角,没有NPM脚本,如何打开?&…...

AT_abc409_e [ABC409E] Pair Annihilation
AT_abc409_e [ABC409E] Pair Annihilation 赛时没开longlong挂了。 思路 首先我们可以把这棵树转化为一颗有根树,且所有电子的都朝根节点移动。 那么接下来我们就需要选择一个最优的树根。 考虑换根dp。 但是可以发现换根时答案其实是没有变化的。 我们设 f…...
【CSS-6】深入理解CSS复合选择器:提升样式表的精确性与效率
CSS选择器是前端开发的基石,而复合选择器则是其中最强大且实用的工具之一。本文将全面解析CSS复合选择器的类型、用法、优先级规则以及最佳实践,帮助你编写更高效、更精确的样式表。 1. 什么是复合选择器? 复合选择器是通过组合多个简单选择…...
网站静态文件加速-Django项目静态文件存储到腾讯云COS存储提升网络请求速度
解决办法是通过在 Nginx 中把对 /static/ 路径的请求直接指向你的 COS 域名来实现让浏览器直接去拉取 COS 上的静态资源,而不再经过本地服务器。下面给出两种常见的做法,你可以任选其一: 方法一:使用 301/302 Redirect ࿰…...

开疆智能Ethernet/IP转Modbus网关连接西门子BW500积算仪配置案例
本案例是通过Ethernet转Modbus网关将皮带秤数据接入到罗克韦尔1769L32E型PLC中。 首先进行ABB PLC的设置 1, 运行 RSLogix 5000 程序加载Ethernet转Modbus网关的EDS 文件: 2,新建工程并添加PLC 3,New Module添加网关ÿ…...