avatar
Articles
415
Tags
259
Categories
26

Theqiqi_blog
Search

Theqiqi_blog

03-反馈流
Created2026-08-21|架构|行为流•反馈流
反馈流——发现问题后回退到哪 反馈流问的是:发现问题后,回到哪一步重新执行? 它是十条流里最特殊的一条——在函数级几乎不存在,却随着组织规模的成长,一路长到「跨系统回退、回到用户」的最强形态。反馈流的强弱,直接等于软件组织的成熟度。本文追踪这条流从无到有的完整生长过程。 一、定义:什么是真正的反馈流先给反馈流下一个精确的定义: 1发现问题后,回到问题产生的那一步,重新执行后续流程。 注意关键词是「回退」,而不是「跳过」或「终止」: 123跳过 出错就跳过当前,继续下一个 (不是反馈)终止 出错就停下不干了 (不是反馈)回退 回到产生问题的那一步,从那里重来 (这才是反馈) 反馈流和错误流的区别: 12错误流:发现错误后怎么办(处理)反馈流:发现错误后回到哪(回退) 没有错误流就没有反馈流——但反过来,有了错误流也不一定有反馈流。反馈流是错误流之上更「高级」的能力。 二、单函数:几乎不存在函数内部发现了错误,能做什么? 1234567函数内部发现错误 ↓能做什么? → 返回错误码?(本函数没有返回值) ...
02-错误流
Created2026-08-21|架构|行为流•错误流
错误流——出错时怎么办 错误流问的是:程序出错时怎么办? 它和控制流、反馈流是一条绳上的三股线——控制流决定正常时往哪走,错误流决定异常时往哪走,反馈流决定发现错后回到哪。错误流最容易被写乱:不是错误处理得越多越好,而是每层只处理自己能处理的,处理不了的往上交。本文追踪错误流从头到尾的演化。 一、起点:函数内部出错错误流最原始的形态,发生在一个函数内部。函数发现错误时,选择有限: 1234567错误发生在函数内部 ↓函数可以选择: 1. 容忍(打印标记继续) 2. 返回错误码(本函数没有返回值,做不到) 3. 抛异常(C 语言没有) 4. 崩溃(最差选择) 12if (argv[i] == NULL) printf("(null)"); // 容忍:不崩溃,打印标记继续 函数级错误流的核心限制:函数能做的错误处理方式有限——最多返回错误码或打印日志,无法「回到上一步重试」。 还有一个隐蔽的问题:函数可能根本没处理某个错误(比如 argc 为负数时的行为未定义)。错误流的起点,就已经暴露了「谁该为错误负责」这个问题的模糊性。 二、单文 ...
01-控制流
Created2026-08-20|架构|行为流•控制流
控制流——程序走向由谁决定 控制流问的是一个最朴素的问题:程序在每一个分支点往哪走?由谁决定? 这个问题看似简单,却随着程序组织的演化不断变换答案。从单函数到多系统,控制权像接力棒一样,从「数据」手里传到「调用者」手里,再传到「接口」手里,最终分成「框架化 / 接口化」两条路。本文追踪这条流从头到尾的演化。 一、起点:一个分支点程序一旦出现判断,控制流就诞生了: 1234if (argv[i] == NULL) printf("(null)");else printf("%s", argv[i]); 在这个点,程序要「选择」。控制流关心的就是:这个选择由谁做出? 答案是:数据。 12argv[i] == NULL → 走第一条argv[i] != NULL → 走第二条 不是代码自己选了路,是数据告诉代码走哪条路。这是控制流最原始、最本质的形态。 二、单函数:数据决定,调用者掌握参数在一个函数内部,控制流由两样东西决定: 1函数内部的控制流由「参数 + 数据」决定 以 print_args 为例: 123 ...
05-多系统协作的十条流
Created2026-08-19|架构|七条流•行为流•多系统协作的十条流
多系统协作的十条流 当程序增长到多个子系统——每个子系统有自己的生命周期、自己的线程、自己的状态——十条流最终成型。启动流变成了「编排」,执行流变成了「跨系统调用」,状态流出现了「同步」,反馈流拥有了「跨系统回退」的能力。这是十条流最完整的形态。 一、从多层到多系统多层系统的每一层内部通常是「被动的」——业务层被入口层调用,基础设施层被业务层调用。但当程序足够复杂时,某些部分需要自己运行——它们有独立的线程、独立的生命周期、独立的状态。 123456789101112args_app/├── main.c ← 入口层:解析命令行,组装系统├── cli/ ← 入口子系统:CLI 解析│ ├── cli_parser.h/c├── format/ ← 业务子系统:格式化│ ├── formatter.h/c├── utils/log/ ← 全局工具框架化子系统:日志(有自己的线程)│ ├── log_system.h/c├── file_io/ ...
04-多层系统的十条流
Created2026-08-18|架构|七条流•行为流•多层系统的十条流
多层系统的十条流 当文件进一步增加,代码开始按职责分层——有些文件负责「接受外部输入」,有些负责「处理业务逻辑」,有些负责「调用操作系统」。分层让十条流发生了最大的一次质变:反馈流终于拥有了真正的「回退重试」能力;用户流程第一次有了明确的边界;控制流开始在层之间分配。 一、从多文件到分层上一篇的多文件结构是平面的——三个文件之间没有「层次」的概念。现在加入更多功能,文件开始自然地分层: 123456args/├── main.c ← 入口层:接收命令行,调用业务层├── parse_args.h/c ← 业务层:解析参数├── format.h/c ← 业务层:格式化输出├── file_api.h/c ← 基础设施层:库接口的原子化封装(读写文件)└── utils/log.h/c ← 全局工具层:写日志(横切,不属于三层) 三层结构: 12345入口层:main.c ↓ 调用业务层:parse_args.c, format.c ↓ 调用基础设施层:file_api(原子化接口,封装库提供的文件 ...
03-多文件的十条流
Created2026-08-17|架构|七条流•行为流•多文件的十条流
多文件的十条流 当代码从一个文件拆成多个文件时,最关键的变化不是「文件变多了」,而是接口出现了。头文件定义了函数签名,实现了「能做什么」和「怎么做」的分离。十条流在这个阶段发生了质变——控制流第一次有了明确的「边界」,反馈流终于可以跨文件回退(启动流仍未形成,链接顺序是编译期问题,见第二节)。 一、从一个文件到多个文件上一篇的 args.c 把 main、print_args、format_arg 写在一个文件里。现在拆开: 1234567891011// format.hvoid format_arg(char *buf, size_t size, int index, const char *value);// format.c#include "format.h"void format_arg(char *buf, size_t size, int index, const char *value) { if (value == NULL) snprintf(buf, size, "arg[%d] = (null)& ...
02-单文件多函数的十条流
Created2026-08-17|架构|七条流•行为流•单文件多函数的十条流
单文件多函数的十条流 当一个文件里不再只有一个函数,而是有若干个函数互相调用时,十条流开始发生变化。执行流不再是单棵树,而是多棵树组成的调用图;错误流第一次有了「传播」的可能;反馈流仍然很弱,但已经萌芽。 一、从一个函数到多个函数上一篇的 print_args 只有一个函数。现在把它拆成多个: 123456789101112131415161718192021222324// file: args.c// 函数 1:格式化单个参数void format_arg(char *buf, size_t size, int index, const char *value) { if (value == NULL) snprintf(buf, size, "arg[%d] = (null)", index); else snprintf(buf, size, "arg[%d] = %s", index, value);}// 函数 2:打印所有参数void print_args(int ar ...
01-单函数的十条流
Created2026-08-16|架构|七条流•行为流•单函数的十条流
单函数的十条流 一切从一个函数开始。在所有复杂的软件系统之前,程序只是若干条指令顺序执行。当这些指令被组织成一个函数,十条流就已经同时存在了——只是有几条还很微弱,甚至尚未诞生。这一篇用一个真实的小函数,把十条流全部展开。 一、从一条指令到一个函数最简单的程序: 1printf("hello"); 只有一条指令。没有分支,没有循环,没有函数调用。十条流在这里几乎全部退化成一个点——指令执行了,结果出现了,结束。 加一个判断: 1234if (argc > 1) printf("hello %s", argv[1]);else printf("hello"); 有了分支,程序不再只走一条路。控制流开始出现——程序在某个点要「选择」。 加一个循环: 12for (int i = 0; i < argc; i++) printf("arg[%d] = %s\n", i, argv[i]); 有了循环,同一段代码可以被执行多次。执行流不再是线性的。 把这些组织成一个函数: 1 ...
06-Protocol
Created2026-08-15|架构|网络系统组件•Protocol
Protocol——协议数据结构有什么 Protocol 回答的问题是:「收发的字节长什么样?」 它被逼出来的原因是「裸字节没法用,每个调用者都要自己猜」。这一篇讲它有什么。关键结论:Protocol 是数据结构,不是组件——它是「消息长什么样」的一份定义。 一、它解决什么问题网络收发的是原始字节: 1收到:0x00 0x00 0x00 0x10 0x00 0x00 0x00 0x02 ... 调用者需要知道「这 4 字节是长度、接下来 4 字节是命令、后面是数据」——每个调用者都要自己猜、自己定义。版本一改,所有地方都要跟着改。 Protocol 被逼出来的原因:把「消息长什么样」的定义统一起来,只写一份。 二、它有什么(就是一份 struct 定义)Protocol 的全部内容,就是一个数据结构: 12345struct Message { uint32_t length; // 消息长度 uint32_t command; // 命令类型 uint8_t payload[];// 消息体}; 1它有什么:只有「定义」,没有「 ...
05-Buffer
Created2026-08-15|架构|网络系统组件•Buffer
Buffer——缓冲区有什么 Buffer 回答的问题是:「收发的字节先存哪?」 它被逼出来的原因是「TCP 是流式协议,一次收不到整条消息」。这一篇讲它有什么——职责、内部结构、边界、异常、形态。注意:Buffer 是无状态工具,不是有状态组件。 一、它解决什么问题TCP 是流式协议,不是消息协议: 1234一次 recv 可能收到: → 半条消息(消息还没发完) → 一条半消息(两条粘在一起) → 恰好一条(运气好) 调用者不能假设「一次 recv = 一条消息」。需要一个地方先把字节攒起来,攒够一条消息再处理。这就是 Buffer 被逼出来的原因。 12接收:字节先存进 Buffer,攒够一条消息再取出处理发送:待发的数据先排进 Buffer,再逐步写出 二、它有什么(内部结构)Buffer 是「数据 + 算法 + 接口」,但无状态: 12345678910111213class Buffer { // —— 数据 —— std::vector<char> data_; // 字节存储 size_t re ...
12…42
avatar
Theqiqi
Articles
415
Tags
259
Categories
26
Follow Me
Announcement
This is my Blog
Recent Post
03-反馈流2026-08-21
02-错误流2026-08-21
01-控制流2026-08-20
05-多系统协作的十条流2026-08-19
04-多层系统的十条流2026-08-18
Categories
  • C with Socks16
  • C_Sound10
  • C_Windows_Graphi9
  • Cpp5
  • Cpp_Socket4
  • C语言在Windows中实现抓包4
  • C语言的万种用法9
  • Debian1
Tags
十阶段 接口先行 Qt主题架构 WindowsDriver python 从输入到交互 select LinuxDriver 入口系统 UDP服务器与可靠性 微服务与组装边界 DLL javascript 多系统组成的网络通信软件 Piano 拆解资源 游戏类型演化 Kali 建模与逆向 BSD Sockets x86汇编程序 IPV4 Drvier 认知能力分解 技术流 qemu Ninja 业务流程到功能点 用头文件验证依赖 引擎组装 Sound 从状态到系统 epoll QEMU 依赖接口 shell 依赖关系 Graphi 拆解美术 只有组件的子系统如何被加载
Archives
  • August 2026128
  • January 20261
  • April 20251
  • March 202595
  • February 202523
  • September 20242
  • August 202471
  • June 20242
Info
Article :
415
UV :
PV :
Last Update :
©2020 - 2026 By Theqiqi
Framework Hexo|Theme Butterfly
Search
Loading the Database