链表高级问题总结

链表高级问题总计及其对应的C语言解决方案,结合算法优化与代码实现

链表高级问题及其对应的C语言解决方案,结合算法优化与代码实现:

一、合并K个有序链表问题描述:将K个已排序的单链表合并为一个升序链表。解决方案:分治法(时间复杂度O(N log K))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
if (!l1) return l2;
if (!l2) return l1;
if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
if (listsSize == 0) return NULL;
if (listsSize == 1) return lists&#91;0];

int mid = listsSize / 2;
struct ListNode* left = mergeKLists(lists, mid);
struct ListNode* right = mergeKLists(lists + mid, listsSize - mid);
return mergeTwoLists(left, right);
}

思路:递归将链表数组拆分为两半,合并后再合并结果。合并两个链表采用递归法简化指针操作。

二、复制带随机指针的链表问题描述:深拷贝包含随机指针的链表。解决方案:三次遍历法(时间复杂度O(N))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
struct Node* copyRandomList(struct Node* head) {
if (!head) return NULL;

// 1. 插入拷贝节点
struct Node* cur = head;
while (cur) {
struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
copy->val = cur->val;
copy->next = cur->next;
cur->next = copy;
cur = copy->next;
}

// 2. 处理random指针
cur = head;
while (cur) {
if (cur->random) {
cur->next->random = cur->random->next;
}
cur = cur->next->next;
}

// 3. 分离链表
struct Node* newHead = head->next;
cur = head;
while (cur) {
struct Node* copy = cur->next;
cur->next = copy->next;
if (copy->next) {
copy->next = copy->next->next;
}
cur = cur->next;
}
return newHead;
}

关键点:在原节点后插入拷贝节点,通过相对位置设置random指针,最后分离链表。

三、奇偶位链表排序问题描述:奇数位升序,偶数位降序的链表重排为完全升序。解决方案:分离奇偶链表+反转偶数链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
struct ListNode* sortSpecialList(struct ListNode* head) {
if (!head || !head->next) return head;

// 分离奇偶链表
struct ListNode oddDummy = {0}, evenDummy = {0};
struct ListNode *oddTail = &oddDummy, *evenTail = &evenDummy;
int index = 1;
while (head) {
if (index % 2 == 1) {
oddTail->next = head;
oddTail = oddTail->next;
} else {
evenTail->next = head;
evenTail = evenTail->next;
}
head = head->next;
index++;
}
oddTail->next = evenTail->next = NULL;

// 反转偶数链表
struct ListNode* prev = NULL, *cur = evenDummy.next;
while (cur) {
struct ListNode* next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
evenDummy.next = prev;

// 合并两个升序链表
return mergeTwoLists(oddDummy.next, evenDummy.next);
}

优化:通过奇偶分离和反转实现O(N)时间复杂度。

四、检测环形链表问题描述:判断链表是否有环,并找到环入口。解决方案:快慢指针法(Floyd算法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
slow = head;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
}
return NULL;
}

数学证明:相遇后重置慢指针到头部,同步移动再次相遇点即为入口。

五、链表反转(迭代法)问题描述:反转整个链表或每K个节点。

1
2
3
4
5
6
7
8
9
10
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode *prev = NULL, *cur = head;
while (cur) {
struct ListNode* next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
return prev;
}

扩展应用:局部反转可通过记录子链表头尾指针实现。

六、性能优化策略

内存池管理:预分配节点减少malloc调用次数。

缓存优化:通过顺序访问提升CPU缓存命中率。

无锁并发:使用原子操作实现线程安全链表。

以上方案覆盖链表操作的核心难点,通过合理选择数据结构和算法策略(如分治、哈希映射、指针操作),可高效解决复杂问题。

AC匹配算法

AC匹配算法(Aho-Corasick算法)与NFA(非确定有限自动机)的转换涉及多模式匹配理论与自动机模型的结合。以下是关键原理和实现路径的解析:

  1. AC自动机的本质结构AC自动机本质上是Trie树+失败指针的扩展结构,其核心功能是通过构建状态转移图实现多模式串的并行匹配。这种结构天然具备非确定性有限自动机(NFA) 的特性:
  • Trie树构建:将多个模式串存储为树形结构,每个节点代表一个字符,路径表示模式串的连续字符序列(如网页7所述)。

  • 失败指针(Failure Links):当匹配失败时,通过指针回溯到最长公共前缀节点,这种回溯机制类似于NFA中的ε-转移(空跳转)。

  • 输出函数:记录每个状态对应的完整匹配模式,这与NFA的接受状态功能类似。

  1. AC自动机到NFA的转换逻辑步骤1:构建Trie树作为NFA基础
  • 节点表示状态:AC自动机的每个Trie节点对应NFA的一个状态,根节点为初始状态。

  • 字符驱动转移:对于Trie中的边(即字符转移),在NFA中表现为确定性的状态转换(如从状态S经字符’a’转移到S’)。

  • 示例:模式集{“he”,”she”,”his”}的Trie树中,路径h→e对应匹配”he”,路径s→h→e对应”she”。

步骤2:添加失败指针作为ε-转移

  • 失败指针的NFA映射:AC自动机的失败指针在NFA中表现为无输入字符的ε-转移。例如,若状态S的失败指针指向状态F,则在NFA中添加一条从S到F的ε边。

  • 非确定性体现:当匹配失败时,NFA可以同时尝试两种路径:继续当前字符匹配或沿失败指针回溯,这与NFA的并行状态特性一致。

步骤3:输出函数的整合

  • 接受状态标记:在NFA中,若某状态对应AC自动机中某个模式串的结束节点,则标记为接受状态,并记录匹配的模式(如网页7中红色标记的接收态)。
  1. 性能与复杂度分析
  • 时间复杂度:AC自动机的匹配时间复杂度为O(n),与文本长度线性相关,而NFA模拟需要维护可能的状态集合,理论复杂度相同但实际性能依赖于ε-转移的优化。

  • 空间复杂度:NFA的状态数与AC自动机的Trie节点数一致,但需额外存储ε-转移边,可能高于原始AC自动机结构。

  1. 对比:AC自动机与经典NFA的差异

特性AC自动机经典NFA构建目的多模式串匹配单模式正则表达式匹配状态转移确定性字符转移 + 非确定性失败指针完全非确定性(含ε-转移)失败处理通过预计算的失败指针跳转回溯或并行状态探索适用场景关键词过滤、实体抽取正则表达式匹配(如(a|b)*c)

  1. 实现示例(Python伪代码)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class AC2NFA:
def __init__(self, patterns):
self.trie = {} # Trie树结构
self.failure = {} # 失败指针
self.output = {} # 输出函数
self.build_trie(patterns)
self.build_failure_links()

def build_trie(self, patterns):
# 构建Trie树,每个节点生成NFA状态
for pattern in patterns:
node = self.trie
for char in pattern:
node = node.setdefault(char, {})
node&#91;'#'] = pattern # 标记接受状态

def build_failure_links(self):
# 使用BFS构建失败指针(ε-转移)
queue = &#91;]
for char in self.trie:
queue.append((self.trie&#91;char], self.trie))
self.failure&#91;self.trie&#91;char]] = self.trie
while queue:
current_node, parent_node = queue.pop(0)
for char, child_node in current_node.items():
# 添加失败指针(ε边)
fail_node = self.failure&#91;parent_node].get(char, self.trie)
self.failure&#91;child_node] = fail_node
queue.append((child_node, current_node))

总结AC自动机通过Trie树和失败指针的机制,本质上实现了一个带有ε-转移的非确定有限自动机。其转换过程的核心在于将失败指针解释为NFA的ε-转移路径,从而允许并行状态探索。这种设计在多模式匹配场景下兼顾了效率与灵活性,是算法理论与工程实践的经典结合。

tcp包按比特过滤方法

在 tcpdump 中,基于比特(bit)或字节(byte)的过滤是一种高级功能,常用于精确匹配协议头中的特定字段或数据载荷。

关键词:tcp包按比特过滤方法, tcpdump 比特过滤技巧, tcpdump 字节过滤规则, 如何使用tcpdump进行比特级过滤, tcpdump高级过滤技术, 基于比特的tcp过滤方法, tcpdump协议过滤详解, tcpdump 比特和字节过滤区别, tcpdump 按位过滤命令, tcpdump 高级网络分析技巧

以下是其核心用法总结:

  1. 基本语法:proto[x:y]
  • 作用:提取协议头中从 x 字节开始的 y 字节数据。

  • 示例: • ip[2:2]:提取 IP 头的第 3、4 字节(总长度字段)。 • tcp[0:2]:提取 TCP 头的第 1、2 字节(源端口号)。

  1. 位运算过滤通过逻辑运算符(&、|、!)匹配特定比特位:
  • 语法:proto[x] & mask [operator] value。

  • 常用场景: • TCP 标志位: ◦ tcp[13] & 0x02 != 0:匹配 SYN 包(第 13 字节的第 2 位为 1)。 ◦ tcp[13] = 18:匹配 SYN-ACK 包(二进制 00010010,即十进制 18)。 • IP 头长度: ◦ ip[0] & 0x0f > 5:匹配 IP 头长度超过 20 字节的包(IHL 字段大于 5)。 • 广播/多播: ◦ ether[0] & 1 != 0:匹配以太网广播或多播包(目的 MAC 首比特为 1)。

  1. 高级字段匹配
  • 可变长度头部处理: • TCP 数据偏移:通过 tcp[12] >> 4 计算 TCP 头的实际偏移(如 tcp[(tcp[12]>>2):4] 跳过 TCP 头选项,直接读取应用层数据)。

  • 应用层协议匹配: • tcp[((tcp[12]>>2)+4):2] = 0x312E:匹配 SSH 协议的版本号(如 “SSH-1.99”)。

  1. 复合条件组合通过逻辑运算符(and、or、not)组合多个条件:
  • 示例: • ip[9] == 6:匹配 IP 协议为 TCP 的包(协议号 6)。 • tcp dst port 80 and (tcp[13] & 0x10 != 0):匹配目标端口 80 且带 ACK 标志的包。
  1. 注意事项
  • 字节偏移计算:协议头字段的偏移需参考协议标准(如 IP 头为 20 字节,TCP 头至少 20 字节)。

  • 工具辅助:使用 Wireshark 或协议文档确定字段位置,避免手动计算错误。

  • 完整抓包:建议配合 -s 0 参数抓取完整报文,确保数据完整性。

典型示例

1
2
3
4
5
6
7
8
# 抓取 HTTP 请求中的 "GET" 方法(应用层数据)
tcpdump 'tcp&#91;((tcp&#91;12]>>2)+4):4] = 0x47455420' # "GET " 的十六进制

# 匹配分片 IP 包(Flags 字段)
tcpdump 'ip&#91;6] & 0x20 != 0' # 第 6 字节的第 6 位为 1(More Fragments)

# 匹配 ICMP 回显请求(Type=8)
tcpdump 'icmp&#91;0] = 8'

通过以上方法,可以实现对网络报文的精细化过滤,适用于协议分析、故障排查等场景。具体协议字段定义可参考 RFC 文档或工具解析(如 Wireshark)。

在 tcpdump 中过滤 HTTP GET 数据包的核心方法是通过 TCP 载荷的十六进制特征 匹配,以下是具体实现方式和优化技巧:

tcpdump过滤http get方法

  1. 基础过滤命令通过匹配 TCP 载荷中 “GET “ 的十六进制值 0x47455420 实现:
1
tcpdump -i eth0 'tcp&#91;((tcp&#91;12]>>2)):4] = 0x47455420'
  • 原理: • tcp[12] 提取 TCP 头第 13 字节(数据偏移字段),>>2 计算 TCP 头长度(单位为 4 字节)。 • ((tcp[12]>>2)):4 跳过 TCP 头部,直接读取应用层数据的前 4 字节。 • 0x47455420 是 “GET “(含空格)的十六进制形式。
  1. 结合 TCP 标志位优化添加 tcp-push 标志过滤(PSH 标志表示数据推送,GET 请求通常伴随此标志):
1
tcpdump -i eth0 'tcp&#91;tcpflags] & tcp-push != 0 and tcp&#91;((tcp&#91;12]>>2)):4] = 0x47455420'
  • 优势:减少误匹配,更精准捕获实际传输的 GET 请求。
  1. 显示请求详情通过 -A 参数显示 ASCII 内容,结合 grep 提取关键信息:
1
tcpdump -i eth0 -A -l | grep -i 'GET /'
  • 适用场景:快速查看 GET 请求的 URL 路径,如 GET /index.html。
  1. 高级组合过滤按目标端口(如 80 或 8080)和 IP 地址进一步筛选:
1
tcpdump -i eth0 'port 80 and host 192.168.1.100 and tcp&#91;((tcp&#91;12]>>2)):4] = 0x47455420'
  • 用途:针对特定服务的流量分析。
  1. 保存抓包文件将结果保存为 .pcap 文件,供 Wireshark 深入分析:
1
tcpdump -i eth0 -w get_requests.pcap 'tcp&#91;((tcp&#91;12]>>2)):4] = 0x47455420'
  • 最佳实践:配合 -s 0 确保捕获完整数据包。

注意事项

偏移量计算:不同协议头的长度可能影响偏移量(如 IP 头含选项时需调整)。

数据分片:大文件请求可能分片传输,需结合 tcp.stream 或 follow stream 分析完整请求。

校验和错误:若出现 cksum incorrect 警告,可忽略(因校验由网卡硬件完成)。

典型示例

1
2
3
4
5
# 抓取所有 GET 请求并显示 URL
tcpdump -i eth0 -A -s0 'tcp&#91;((tcp&#91;12]>>2)):4] = 0x47455420' | grep "GET"

# 抓取目标为 80 端口的 GET 请求并保存
tcpdump -i eth0 -w http_get.pcap 'port 80 and tcp&#91;((tcp&#91;12]>>2)):4] = 0x47455420'

通过上述方法,可高效捕获并分析 HTTP GET 请求,适用于性能调优、安全审计等场景。如需更复杂过滤(如特定 URL 或参数),建议结合 Wireshark 的显示过滤器。

TCP协议栈中的定时器总结

TCP协议栈通过多种定时器机制确保可靠传输、流量控制和连接管理。以下是TCP协议栈中核心的定时器分类及其作用(基于RFC标准及主流实现):

一、连接建立阶段

连接建立定时器在发送SYN报文建立新连接时启动,若75秒内未收到响应则中止连接。此定时器防止因网络丢包导致客户端无限等待SYN-ACK响应。

SYN-ACK定时器用于监听状态的服务器,发送SYN-ACK后启动。若未收到客户端的ACK,触发重传并最终关闭连接。

二、数据传输阶段

重传定时器(Retransmission Timer)• 功能:确保数据段或ACK丢失时触发重传。每个发送的数据段启动独立的定时器,超时后指数退避重传(如1s, 3s, 6s等)。 • 动态计算:基于往返时间(RTT)和其平滑估计值(SRTT)动态调整超时时间(RTO)。 • Karn算法:重传时不更新RTT估计,避免混淆原始包和重传包的ACK。

延迟ACK定时器(Delayed ACK Timer)• 作用:减少ACK报文数量,通过捎带机制将ACK与数据合并发送。默认延迟200ms,超时后立即发送ACK。 • 优化场景:适用于批量数据传输,降低网络负载。

坚持定时器(Persistent Timer)• 触发条件:接收方通告零窗口时启动,防止死锁(如窗口更新ACK丢失)。 • 机制:周期性发送1字节探测包,采用指数退避策略(如1.5s, 3s, 6s)。

三、连接维护阶段

保活定时器(Keepalive Timer)• 功能:检测空闲连接是否存活。默认每2小时发送探测包,若连续多次未响应则关闭连接。 • 争议性:可能误判短暂网络故障,需手动启用(通过SO_KEEPALIVE选项)。

四、连接终止阶段

FIN_WAIT_2定时器主动关闭方进入FIN_WAIT_2状态后启动,若超时(默认10分钟)未收到FIN则强制关闭连接。

TIME_WAIT定时器(2MSL Timer)• 作用:确保最后一个ACK到达,并等待网络中旧报文段消亡。定时器设为2倍最大报文段生存时间(MSL),通常为60秒。 • 意义:防止新连接接收旧连接的延迟报文,避免数据混淆。

五、其他特殊定时器

零窗口探测定时器与坚持定时器协同工作,专用于处理接收方窗口为0的场景,确保发送方能及时恢复数据传输。

快速重传与恢复机制非严格定时器,但依赖重复ACK计数(如收到3次重复ACK立即触发重传,无需等待超时)。

总结对比

定时器类型触发场景核心算法/策略典型超时值重传定时器数据段未及时确认指数退避 + Karn算法动态计算(如1s, 3s…)坚持定时器接收方窗口为0指数退避探测初始1.5s,最大60s保活定时器连接长时间空闲固定间隔探测2小时探测 + 75s超时TIME_WAIT定时器主动关闭后的等待状态2MSL等待60秒(2×30秒MSL)

扩展知识

  • 糊涂窗口综合症:由小窗口通告引发,通过坚持定时器和延迟ACK机制缓解。

  • 拥塞控制算法:如慢启动、拥塞避免与快速恢复,虽非定时器,但依赖RTT动态调整窗口。

如需深入某个定时器的实现细节(如Linux内核中的tcp_retransmit_timer()),可参考TCP/IP协议栈源码分析。

TCP滑动窗口机制详解-提升网络性能的关键技术

TCP滑动窗口机制详细总结

TCP滑动窗口机制详解,全面解析数据传输原理与优化方法,提升网络性能与效率。以下是关于 TCP滑动窗口机制 的详细总结,涵盖其工作原理、发送端与接收端协同机制及核心作用:

一、滑动窗口的核心作用

滑动窗口机制是TCP实现 流量控制 和 可靠传输 的核心技术,通过动态调整发送速率与接收能力,确保网络高效稳定运行。

  • 流量控制:接收方通过通告窗口大小(rwnd)限制发送方的数据发送速率,防止接收缓冲区溢出。

  • 可靠传输:基于确认重传机制,确保数据按序到达且无丢失,通过窗口滑动实现数据的连续传输。

二、发送方窗口机制

发送方维护一个 发送窗口(Send Window, swnd),窗口内的数据分为四类:

已发送且已确认:无需保留,窗口滑动后释放。

已发送未确认:需等待ACK,超时后触发重传。

未发送但允许发送:可立即发送的新数据。

未发送且不允许发送:超出窗口容量或网络限制。

滑动规则:

  • 收到接收方的ACK确认后,窗口左边界右移,允许发送新数据。

  • 窗口大小受接收方通告的rwnd和拥塞窗口(cwnd)共同限制,即 swnd = min(rwnd, cwnd)。

三、接收方窗口机制

接收方维护一个 接收窗口(Receive Window, rwnd),数据分为三类:

已接收并确认:已提交给应用层处理。

未接收但准备接收:窗口内的待接收数据。

未接收且不准备接收:窗口外的数据将被丢弃。

滑动规则:

  • 仅当所有前置数据均接收成功后,窗口左边界才向右滑动。

  • 若接收乱序数据(如先收到序列号高的包),窗口暂不滑动,触发重复ACK通知发送方重传。

四、发送端与接收端的协同工作

初始化协商TCP三次握手阶段,双方交换初始窗口大小(如rwnd=300字节),确定发送速率上限。

动态调整流程• 接收方通告窗口:通过ACK报文中的Window Size字段更新rwnd,发送方据此调整swnd。 • 拥塞控制介入:若网络拥塞,拥塞窗口cwnd缩小(如慢启动、拥塞避免算法),进一步限制swnd。

丢包处理• 快速重传:接收方发送重复ACK(如连续3次相同ACK),发送方立即重传丢失包,无需等待超时。 • 选择确认(SACK):接收方通过SACK选项告知发送方已接收的非连续数据段,减少无效重传。

五、滑动窗口的进阶机制

零窗口与坚持定时器• 若接收方通告窗口为0,发送方暂停发送并启动坚持定时器,周期性发送1字节探测包以检测窗口恢复。

窗口缩放因子• 通过TCP选项扩展窗口大小(16位→31位),支持高速网络下的更大吞吐量(如万兆网络)。

拥塞控制算法结合• 慢启动:初始窗口较小(如1MSS),指数增长至阈值后转为线性增长。 • 拥塞避免:窗口线性增长,避免突发流量导致网络拥塞。

六、实际应用场景示例

企业广域网优化通过滑动窗口动态平衡跨国节点间的数据传输速率,减少延迟(如视频会议场景降低30%延迟)。

高吞吐文件传输发送方持续发送窗口内数据,接收方通过调整rwnd控制流量,避免缓冲区溢出。

七、总结对比

特性发送方窗口(swnd)接收方窗口(rwnd)控制目标流量控制 + 拥塞控制流量控制动态调整依据接收方通告窗口、网络拥塞状态应用处理能力、缓冲区剩余空间核心操作滑动确认数据、重传丢失包按序接收数据、发送ACK和窗口更新

滑动窗口机制通过精细的协同设计,在保障可靠性的同时最大化网络吞吐量。理解其原理对网络优化、故障排查(如零窗口阻塞)及协议调优(如调整初始窗口大小)至关重要。

相关文章:tcp滑动窗口详细原理、详细过程、优缺点总结

TCP滑动窗口机制, TCP滑动窗口原理, TCP滑动窗口工作原理, TCP流量控制机制, TCP滑动窗口详解, TCP滑动窗口技术, TCP窗口机制总结, TCP滑动窗口知识点, TCP滑动窗口优化方法, TCP滑动窗口应用场景

c语言-printf常用输出格式总结

在C语言中,printfsnprintf 是用于格式化输出的常用函数。它们支持多种格式说明符,用于处理不同类型的数据。以下是这些函数常用的格式说明符及其组合类型的总结:

基本格式说明符

| 格式说明符 | 描述 |

|————|——————————–|

| %d | 有符号十进制整数 |

| %u | 无符号十进制整数 |

| %o | 八进制整数 |

| %x | 十六进制整数(小写字母) |

| %X | 十六进制整数(大写字母) |

| %f | 浮点数 |

| %e | 科学计数法(小写字母e) |

| %E | 科学计数法(大写字母E) |

| %g | 通用浮点格式(自动选择%f或%e) |

| %G | 通用浮点格式(自动选择%f或%E) |

| %c | 字符 |

| %s | 字符串 |

| %p | 指针地址 |

| %n | 写入的字符数(存储在参数中) |

| %% | 百分号本身 |

长度和精度修饰符

| 修饰符 | 描述 |

|————–|——————————–|

| h | 短整型(用于 %d, %o, %x, %u) |

| hh | char 类型(用于 %d, %o, %x, %u) |

| l | 长整型(用于 %d, %o, %x, %u, %f) |

| ll | 长长整型(用于 %d, %o, %x, %u) |

| L | 长双精度浮点型(用于 %f, %e, %g, %G) |

| .n | 精度(用于浮点数和字符串) |

| * | 宽度和精度由参数指定 |

组合示例

  1. 整数类型

    %d:有符号十进制整数

    %u:无符号十进制整数

    %o:八进制整数

    %x:十六进制整数(小写)

    %X:十六进制整数(大写)

    %hd:短整型

    %hu:无符号短整型

    %hhd:char 类型(有符号)

    %hhu:char 类型(无符号)

    %ld:长整型

    %lu:无符号长整型

    %lld:长长整型

    %llu:无符号长长整型

  2. 浮点类型

    %f:单精度浮点数

    %lf:双精度浮点数(通常与 %f 相同)

    %Lf:长双精度浮点数

    %e:科学计数法(小写e)

    %E:科学计数法(大写E)

    %g:通用浮点格式(自动选择 %f%e

    %G:通用浮点格式(自动选择 %f%E

    %.2f:保留两位小数的浮点数

    %10.2f:总宽度为10,保留两位小数的浮点数

  3. 字符和字符串

    %c:单个字符

    %s:字符串

    %.*s:动态指定长度的字符串

  4. 指针

    %p:指针地址

  5. 其他

    %n:写入的字符数(存储在参数中)

    %%:百分号本身

示例代码

1
2
3
4
5

#include <stdio.h>

int main() {

int a = 123;

unsigned int b = 456;

char c = ‘A’;

float d = 123.456;

double e = 12345.6789;

char *str = “Hello, World!”;

void *ptr = &a;

printf(“a Integer: %d\n”, a);
printf(“a Octal: %o\n”, a);
printf(“a Hexadecimal (lower): %x\n”, a);
printf(“a Hexadecimal (upper): %X\n”, a);
printf(“a Short Integer: %hd\n”, (short)a);

printf(“b Unsigned Integer: %u\n”, b);
printf(“b Unsigned Short Integer: %hu\n”, (unsigned short)b);

printf(“c Char[%%c,%%d]: %c, %d\n”, c, c);
printf(“String[%%s]: %s\n”, str);
printf(“Pointer[%%p]: %p\n”, ptr);
printf(“Float[%%.2f]: %.2f\n”, d);
printf(“Float[%%.3f]: %.3f\n”, d);
printf(“Double:[%%.4lf] %.4lf\n”, e);
printf(“Double:[%%.5lf] %.5lf\n”, e);
printf(“Scientific Notation: %e\n”, e);
printf(“General Format: %g\n”, e);
printf(“Width and Precision: %10.2f\n”, d);
printf(“Dynamic String Length: %.*s\n”, 5, str);

int chars_written;
int ret = printf(“Number of characters written: %n\n”, &chars_written); // 注意:%n 不会输出任何内容,但会将写入的字符数存储在 chars_written 中

printf(“chars written:%d print return:%d\n”, chars_written,ret);

1
2
3

}

参考文档

如果你需要更详细的信息,可以参考以下官方文档:

  1. GNU C Library (glibc) 文档:

    printf

    snprintf

  2. C标准库文档:

    C11 Standard - The fprintf function

  3. cppreference.com:

    std::printf

    std::snprintf

这些文档提供了详细的格式说明符及其用法,可以帮助你更深入地理解和使用 printfsnprintf 函数。

Linux top命令完全指南:从基础到高阶运维实践

Linux top 命令完全指南:从基础到高阶运维实践

Linux top命令详解:从基础到高阶运维技巧,全面掌握系统监控与性能优化。Linux top命令教程, top命令使用详解, Linux top命令实战指南, Linux top命令基础操作, Linux top命令高级用法, top命令监控系统性能, Linux top命令实时监控, Linux top命令详解, Linux top命令运维实践, top命令参数说明

一、基础操作:实时监控核心界面

1. 启动与界面结构

1
2
3
4
# 默认3秒刷新(网页1/网页4)
top
# 指定5秒刷新(网页2/网页5)
top -d 5

2. 界面字段详解

区域关键字段说明系统统计load average1/5/15分钟平均负载(超核数表示过载)1,4CPU 状态%us(用户态)应用程序直接使用的CPU时间占比1,4,5内存统计buff/cache可回收的缓存内存(网页4/网页5)

二、高阶技巧:精准诊断与优化

1. 进程监控策略

1
2
3
4
# 监控指定用户进程(网页1/网页5)
top -u john
# 跟踪特定PID及其线程(网页2/网页5)
top -H -p 1234

2. 批处理模式实战

1
2
3
4
# 生成3次快照用于性能分析(网页2/网页5)
top -b -n 3 > system_profile.log
# 结合awk提取Java进程数据(网页5)
top -b | awk '/java/ {print $1, $6}'

三、运行态选项:参数化控制

参数功能应用场景-c显示完整命令路径排查异常进程来源2,5-S累计模式统计分析长期运行服务的资源消耗(网页2/网页5)-i隐藏闲置进程聚焦活跃进程分析(网页2)

四、交互式操作秘籍

快捷键速查表

  • Shift + >:横向滚动查看隐藏列(网页4)

  • R:反转排序顺序(网页2)

  • W:保存配置到 ~/.toprc(网页1/网页5)

  • z:开启高对比度配色(网页1/网页4)

典型场景操作示例

1
2
3
4
# 排查内存泄漏流程(网页3/网页5)
1. 按M按内存排序
2. 按f添加RES/SHR列
3. 结合pmap分析具体进程

https://www.calcguide.tech/2025/04/04/linux-top命令完全指南:从基础到高阶运维实践/

SSH免密登录配置指南与运维应用全景解析

SSH免密登录配置指南与运维应用全景解析

    body {font-family: 'Segoe UI', sans-serif; line-height: 1.6; max-width: 960px; margin: 0 auto; padding: 20px}
    h1 {color: #2c3e50; border-bottom: 3px solid #3498db}
    h2 {color: #2980b9; margin-top: 30px}
    .code-block {background: #f8f9fa; padding: 15px; border-radius: 5px; margin: 15px 0}
    .warning {background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px}
    .scenario-card {background: #f8f9fa; padding: 15px; margin: 15px 0; border-radius: 5px}


SSH免密登录完全指南与运维应用实践



    一、跨平台SSH免密登录配置详解
    
    1.1 密钥生成与部署
    
        生成ED25519密钥对(推荐):
        ssh-keygen -t ed25519 -C "your_email@example.com" -a 100
        三次回车确认存储路径和空密码(生产环境建议设置密钥密码)[1,8](@ref)
    

    
        公钥部署方式对比:
        
            自动部署:ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host(需当前密码登录权限)[1,3](@ref)
            手动部署:将公钥内容追加至目标服务器~/.ssh/authorized_keys[3,4](@ref)
        
    

    
        ❗ 关键权限设置:
        
            客户端私钥权限:chmod 600 ~/.ssh/id_ed25519
            服务器端目录权限:chmod 700 ~/.ssh && chmod 600 authorized_keys[4,9](@ref)
        
    




    二、大规模运维的典型应用场景

    
        2.1 自动化运维体系构建
        通过Ansible/SaltStack批量执行以下操作:
        
            跨服务器文件同步(如日志收集)
            集群配置统一下发(Nginx/Tomcat配置)
            系统补丁批量更新[6,7](@ref)
        
        
            批量部署脚本示例:
            
                #!/bin/bash
                while read host; do
                  sshpass -p "$PASS" ssh-copy-id -i key.pub $host
                done [6](@ref)
        
    

    
        2.2 持续交付流水线集成
        
            GitLab Runner自动部署到生产环境
            Jenkins节点间的可信通信
            容器镜像构建时的安全凭证传递[7](@ref)
        
    

    
        2.3 云原生环境下的特殊应用
        
            Kubernetes Pod之间的SSH隧道建立
            Serverless函数的安全初始化
            混合云架构的跨网络认证[7,8](@ref)
        
    




    三、企业级安全增强方案
    
        SSH服务端加固配置:
        
            # /etc/ssh/sshd_config
            PasswordAuthentication no
            PermitRootLogin prohibit-password
            MaxAuthTries 3
            ClientAliveInterval 300[8](@ref)
        
    

    
        🔐 密钥生命周期管理:
        
            定期轮换密钥(建议每90天)
            使用ssh-agent进行密钥托管
            审计authorized_keys文件变更[7,8](@ref)
        
    




    四、常见问题快速诊断
    
        
            症状
            解决方案
        
        
            Host key verification failed
            ssh-keygen -R problem_host清除旧指纹[8](@ref)
        
        
            Authentication refused
            检查目标服务器SELinux状态与日志/var/log/secure[9](@ref)

链路层协议总结

链路层协议总结-所有链路层协议总结,协议信息介绍,使用场景介绍

所有链路层协议总结,协议信息介绍,使用场景介绍;元宝:引用 9 篇资料作为参考1.计算机网络(自顶向下方法)学习笔记2.数据链路层协议概览-CSDN博客3.计算机网络学习笔记:数据链路层相关知识点全面总结 - 无名高地 - 博客园4.计算机网络之数据链路层协议总结-CSDN博客5.计算机网络之数据链路层协议总结6.OSI七层模型基础知识及各层常见应用要点 - 文档之家7.计算机网络基础:解析网络协议8.深度对比跨链协议LayerZero和deBridge-web3资讯-ODAILY9.【云服务通信协议创新】:IP5209与IP5109的协同创新案例以下为数据链路层协议的综合总结,结合多个权威来源整理,按协议类型分类并标注典型应用场景:
一、点对点协议(P2P)1. PPP(Point-to-Point Protocol)核心功能:在串行链路上封装IP数据报,支持异步/同步传输,提供链路控制(LCP)和网络层协议配置(NCP)。使用场景:拨号上网(ADSL)、路由器广域网连接、VPN隧道封装。特点:支持PAP/CHAP认证,支持多链路捆绑(MP)增加带宽。2. HDLC(High-Level Data Link Control)核心功能:面向比特的同步协议,提供可靠传输和流量控制,帧结构包含信息帧(I帧)、监督帧(S帧)。使用场景:专线通信(如银行专网)、SDH/SONET传输网络。特点:零比特填充实现透明传输,适用于高可靠性要求的场景。3. 帧中继(Frame Relay)核心功能:简化X.25协议,通过虚电路(PVC/SVC)实现带宽复用和动态分配。使用场景:企业分支机构互联、早期广域网数据传输。特点:高效处理突发流量,支持QoS优先级管理。
二、局域网协议1. 以太网协议(Ethernet)核心功能:基于CSMA/CD的多路访问控制,帧结构包含MAC地址、类型字段和FCS校验。使用场景:企业/家庭局域网、数据中心内部互联。变种协议:快速以太网(100Mbps)、千兆以太网(1Gbps)、万兆以太网(10Gbps)。2. ARPA(Address Resolution Protocol for Ethernet)核心功能:以太网接口默认封装类型,支持IP地址与MAC地址映射(ARP协议)。使用场景:局域网内主机通信、网关地址解析。3. CSMA/CD(载波侦听多路访问/冲突检测)核心功能:通过“先听后发,边听边发”机制解决共享信道冲突。使用场景:传统总线型以太网(如10BASE5)。特点:二进制指数退避算法实现冲突后重传。4. CSMA/CA(冲突避免)核心功能:通过ACK确认和随机退避避免无线信道冲突。使用场景:Wi-Fi网络(802.11标准)、物联网设备通信。特点:支持能量检测和虚拟载波侦听。
三、虚拟化与扩展协议1. VLAN(虚拟局域网)核心功能:逻辑划分广播域,基于端口、MAC或协议类型隔离流量。使用场景:企业网络分段、数据中心多租户隔离。扩展技术:QinQ(双层标签)实现跨运营商VLAN透传。2. MSTP(多生成树协议)核心功能:基于VLAN的生成树负载均衡,避免单生成树资源浪费。使用场景:大型企业网络核心层、多VLAN环境冗余设计。3. RRPP(快速环网保护协议)核心功能:以太网环网毫秒级故障恢复,支持主备链路切换。使用场景:工业控制网络、电力通信环网。
四、可靠传输协议1. 停止-等待协议(Stop-and-Wait)核心功能:发送方每帧等待确认后再发下一帧,适用简单低带宽场景。特点:信道利用率低(公式:利用率= (L/C)/T),但实现简单。2. 回退N帧(GBN)核心功能:滑动窗口机制,累积确认减少ACK数量,重传从错误点开始。应用场景:高延迟网络(如卫星通信)的批量数据传输。3. 选择重传(SR)核心功能:仅重传错误帧,接收窗口>1缓存乱序帧。应用场景:无线网络(如LTE)、高误码率环境。
五、广域网与城域网协议1. ATM(异步传输模式)核心功能:以固定长度信元(53字节)传输数据,支持QoS保障和多种速率适配。使用场景:早期视频会议、语音电话(VoATM)、HFC混合光纤同轴网。特点:面向连接,支持流量整形和拥塞控制。2. RPR(弹性分组环)核心功能:环形拓扑的快速保护倒换(小于50ms),支持带宽公平分配。使用场景:城域网骨干传输、地铁通信环网。特点:结合SDH可靠性和以太网经济性,支持多业务承载。3. X.25、LAPB核心功能:面向连接的可靠传输,通过LAPB协议实现差错控制和流量管理。使用场景:早期分组交换网络,如银行终端接入替代协议:帧中继和ATM因效率更高逐步取代X.25。
六、其他协议Trunk(链路聚合):Eth-Trunk(以太网)和IP-Trunk(POS链路)提升带宽和可靠性。SDLC(同步数据链路控制):IBM专用协议,支持全双工/半双工传输,应用于早期SNA网络。SMDS(交换多兆位数据服务):城域网的早期高速数据传输协议,支持多种上层协议。
协议选择建议场景| 推荐协议| 理由家庭拨号上网| PPP | 支持认证,兼容异步传输企业专线互联| HDLC | 高可靠性,适合同步链路数据中心内部网络| 以太网(VLAN+MSTP) | 高带宽,支持逻辑分段和冗余无线局域网| CSMA/CA | 冲突避免机制适配广播信道特性城域网骨干| RPR | 快速故障恢复,支持多业务QoS
如需更详细的技术参数或实现代码示例,可参考来源文档。

C语言中的宏函数

C语言中的宏函数,也称为带参数的宏定义,是一种预处理指令,它允许你定义一个代码片段作为宏,并在调用时传递参数。这种机制使得宏可以在编译前被预处理器替换为实际的代码片段,从而避免了函数调用的开销。下面我们将详细探讨宏函数的定义、使用场景、优点以及一些需要注意的地方。

宏函数的基本概念和定义

在C语言中,宏函数是通过#define指令来定义的。其基本形式如下:

#define MACRO_NAME(参数列表) 宏体

例如,定义一个简单的宏函数来计算两个数的最大值:

#define MAX(a, b) ((a) > (b) ? (a) : (b))

在这个例子中,MAX是宏名,ab是参数,而宏体是一个条件表达式,用于返回较大的值。注意这里每个参数和整个宏体都被括号包围,这是为了避免由于运算符优先级导致的潜在问题。

使用宏函数的优点

  1. 提高代码可读性:宏函数可以简化复杂的代码逻辑,使代码更加简洁易懂。
  2. 提高执行效率:由于宏函数在预处理阶段展开,避免了函数调用的开销,有助于提升程序性能。
  3. 灵活性高:宏函数可以根据不同的需求调整参数,适应各种场景。

宏函数的应用场景

  • 简化代码:如上文所述,宏函数可以用来简化重复出现的代码逻辑。
  • 条件编译:结合条件编译指令(如#ifdef),宏函数可以根据不同的编译选项生成不同的代码版本。
  • 调试信息输出:可以通过宏函数控制调试信息是否输出,便于开发过程中的调试工作。

注意事项

尽管宏函数有很多优点,但在使用时也有一些需要注意的地方:

  • 括号的使用:为了防止运算符优先级引起的问题,通常需要对宏函数的每个参数及整个宏体加上括号。
  • 副作用问题:如果宏函数的参数包含有副作用的操作(比如自增操作),可能会导致意外的行为。
  • 避免嵌套过多:过度嵌套的宏函数可能导致代码难以理解和维护。

高级应用

除了基本的宏定义之外,C语言还支持更高级的宏功能,比如变参宏(variadic macros)和字符串化操作符#、标识符连接操作符##等。这些特性进一步增强了宏函数的功能性和灵活性。

综上所述,宏函数是C语言中一种强大的工具,能够有效地提高代码的可读性和执行效率。然而,在享受这些好处的同时,开发者也需要谨慎对待宏函数可能带来的副作用和其他潜在问题。正确地使用括号、理解宏展开的过程以及合理设计宏结构,都是编写高效且无误的宏函数的关键所在。

1
2
3
4
<head>
<!-- 系统编程核心书籍深度解析-->
<meta name="description" content="C宏函数,宏函数是C语言中一种强大的工具,能够有效地提高代码的可读性和执行效率。然而,在享受这些好处的同时,开发者也需要谨慎对待宏函数可能带来的副作用和其他潜在问题。正确地使用括号、理解宏展开的过程以及合理设计宏结构,都是编写高效且无误的宏函数的关键所在">
</head>