过长参数列表(Long Parameter List):坏味道识别与重构实战指南
过长参数列表(Long Parameter List):坏味道识别与重构实战指南24种代码坏味道系列 · 第4篇
1. 开篇场景你是否遇到过这样的函数调用:需要传递12个参数,每次调用时都要翻看函数定义才能确定参数顺序,稍有不慎就会传错参数?
12bad.createUser("John", "Doe", "john@example.com", "123-456-7890", "123 Main St", "New York", "USA", 30, true, 1000.0, "admin");
这就是过长参数列表的典型症状。函数需要太多参数才能工作,就像一台需要12个旋钮才能调节的机器,每次使用都要记住每个旋钮的作用和顺序。
当你需要添加新参数时(比如添加”生日”字段),所有调用这个函数的地方都需要修改。更糟糕的是,参数顺序容易搞混——firstName 和 lastName 的位置对调了, ...
过长函数(Long Function):坏味道识别与重构实战指南
过长函数(Long Function):坏味道识别与重构实战指南24种代码坏味道系列 · 第3篇
1. 开篇场景你是否遇到过这样的函数:一个 processOrder 函数包含了验证、计算、日志、邮件、库存更新、发票生成等所有逻辑,函数体超过100行,每次修改都需要在长长的代码中寻找目标位置,就像在一本没有目录的厚书中查找特定章节?
1234567891011void processOrder(std::string customerName, std::vector<int> items, double discount, bool isVip) { // 验证客户 if (customerName.empty()) { std::cout << "Error: Invalid customer" << std::endl; return; } // ... 50多行代码 ... // 计算总价、应用折扣 ...
重复代码(Duplicated Code):坏味道识别与重构实战指南
重复代码(Duplicated Code):坏味道识别与重构实战指南24种代码坏味道系列 · 第2篇
1. 开篇场景你是否遇到过这样的场景:在 processUsers 方法中写了一段验证逻辑,然后在 processProducts 方法中又写了几乎相同的验证代码?当你需要修改验证规则时,必须在多个地方同步修改,稍有不慎就会遗漏某个地方,导致系统行为不一致。
12345678910111213141516171819202122232425262728void processUsers(std::vector<std::string>& users) { for (auto& user : users) { if (user.empty()) { std::cout << "Error: Empty user name" << std::endl; continue; } if ( ...
神秘命名(Mysterious Name):坏味道识别与重构实战指南
神秘命名(Mysterious Name):坏味道识别与重构实战指南24种代码坏味道系列 · 第1篇
1. 开篇场景你是否遇到过这样的代码:看到一个函数调用 calc(x, y, z),却完全不知道这三个参数代表什么?或者遇到变量名 m1、m2,需要翻遍整个文件才能理解它们的含义?
12BadExample bad;bad.calc(100, 2, 50); // 完全不知道这些参数是什么意思
这就是神秘命名的典型症状。代码中的变量、函数、类名没有清晰表达其意图,就像在阅读一本没有注释的古籍,每个字都认识,但组合在一起却不知所云。
当你在维护这样的代码时,每次修改都需要花费大量时间理解代码的真实意图。更糟糕的是,这种理解往往是不完整的,导致引入新的bug。团队成员之间的沟通成本也会急剧增加——“那个 proc 函数是做什么的?”、”fn 和 dt 是什么意思?”
2. 坏味道定义神秘命名是指代码中的标识符(变量、函数、类名等)没有清晰表达其用途和含义,导致代码可读性差、维护困难。
就像厨房里没有标签的调料瓶,虽然你知道里面是调料,但不知道是盐、糖还是味精,每次使用都要尝一尝才 ...
SIGSYS (31) 系统调用错误详解
SIGSYS (31) 系统调用错误详解:C++ 开发者的崩溃调试指南一、信号基础认知(开篇 5 分钟入门)信号核心信息
信号编号:31
信号名称:SIGSYS (Bad System Call)
POSIX 标准:是(POSIX.1-2001 定义)
可捕获:是
默认行为:终止进程并生成 coredump
核心定位SIGSYS 的本质作用是系统调用错误告警。当进程执行了无效的系统调用(如系统调用号不存在、参数无效、或系统调用被 seccomp 等安全机制阻止)时,操作系统会发送 SIGSYS 信号。
默认行为Linux 内核的默认处理逻辑:
终止进程:立即终止当前进程
生成 coredump:如果系统配置允许,会生成 core 文件
可捕获:可以捕获,但通常应该让程序终止
与 C++ 的关联性SIGSYS 在 C++ 开发中的高发场景:
无效系统调用:使用了不存在的系统调用号
seccomp 限制:程序被 seccomp 沙箱限制,禁止某些系统调用
架构不匹配:在不同架构间移植代码时,系统调用号可能不同
安全策略:容器或沙箱环境中的安全策略限制
调试工具:某些调试或分析工具 ...
SIGSEGV (11) 段错误详解
SIGSEGV (11) 段错误详解:C++ 开发者的崩溃调试指南一、信号基础认知信号核心信息
信号编号:11
信号名称:SIGSEGV (Segmentation Violation)
POSIX 标准:是(POSIX.1-2001 定义)
可捕获:是
默认行为:终止进程并生成 coredump
核心定位SIGSEGV 的本质作用是内存访问违规告警。当进程尝试访问不属于它的内存区域,或者访问被保护的内存区域时,操作系统会发送 SIGSEGV 信号。
默认行为Linux 内核的默认处理逻辑:
终止进程:立即终止当前进程
生成 coredump:如果系统配置允许,会生成 core 文件用于后续调试
不可忽略:虽然可以捕获,但默认行为是终止
与 C++ 的关联性SIGSEGV 在 C++ 开发中是最常见的崩溃信号,高发场景包括:
STL 容器使用:std::vector、std::string 等容器的越界访问
指针操作:空指针解引用、野指针访问、悬垂指针
多线程内存共享:数据竞争、未同步的内存访问
智能指针误用:std::shared_ptr、std::unique_ptr 的 ...
SIGFPE (8) 浮点异常详解
SIGFPE (8) 浮点异常详解:C++ 开发者的崩溃调试指南一、信号基础认知(开篇 5 分钟入门)信号核心信息
信号编号:8
信号名称:SIGFPE (Floating Point Exception)
POSIX 标准:是(POSIX.1-2001 定义)
可捕获:是
默认行为:终止进程并生成 coredump
核心定位SIGFPE 的本质作用是算术运算异常告警。虽然名称是”浮点异常”,但实际上 SIGFPE 可以表示多种算术错误,包括整数除以零、浮点运算异常、整数溢出等。
默认行为Linux 内核的默认处理逻辑:
终止进程:立即终止当前进程
生成 coredump:如果系统配置允许,会生成 core 文件
可捕获:可以捕获并处理,但通常应该让程序终止
与 C++ 的关联性SIGFPE 在 C++ 开发中的高发场景:
除零错误:整数或浮点数除以零
整数溢出:有符号整数溢出(在某些架构上)
浮点运算异常:浮点数溢出、下溢、无效操作
数学库函数:某些数学函数在特定输入下可能触发
数值计算:科学计算、金融计算中的边界情况
二、信号触发场景(结合 C++ 代码实例)核心触发 ...
SIGBUS (7) 总线错误详解
SIGBUS (7) 总线错误详解:C++ 开发者的崩溃调试指南一、信号基础认知(开篇 5 分钟入门)信号核心信息
信号编号:7
信号名称:SIGBUS (Bus Error)
POSIX 标准:是(POSIX.1-2001 定义)
可捕获:是
默认行为:终止进程并生成 coredump
核心定位SIGBUS 的本质作用是内存访问权限不足告警。与 SIGSEGV(地址无效)不同,SIGBUS 表示访问的地址是有效的,但由于对齐错误、访问只读内存、或访问了无效的内存区域等原因,无法完成访问。
默认行为Linux 内核的默认处理逻辑:
终止进程:立即终止当前进程
生成 coredump:如果系统配置允许,会生成 core 文件
可捕获:可以捕获,但通常应该让程序终止
与 C++ 的关联性SIGBUS 在 C++ 开发中的高发场景:
内存对齐错误:在某些架构(如 SPARC、某些 ARM 配置)上访问未对齐的内存
只读内存写入:尝试写入只读内存区域(如代码段、常量数据)
内存映射问题:访问了无效的内存映射区域
多线程同步:数据竞争导致的内存损坏
硬件相关:某些硬件限制导致的内存访问 ...
SIGABRT (6) 中止信号详解
SIGABRT (6) 中止信号详解:C++ 开发者的崩溃调试指南一、信号基础认知信号核心信息
信号编号:6
信号名称:SIGABRT (Abort)
POSIX 标准:是(POSIX.1-2001 定义)
可捕获:是
默认行为:终止进程并生成 coredump
核心定位SIGABRT 的本质作用是程序主动请求中止。与 SIGSEGV 等由操作系统触发的信号不同,SIGABRT 通常由程序自身调用 abort() 函数触发,用于在检测到严重错误时立即终止程序。一般用于调试模式下,做异常或非法值得检测,强制程序退出
默认行为Linux 内核的默认处理逻辑:
终止进程:立即终止当前进程
生成 coredump:如果系统配置允许,会生成 core 文件
可捕获但不应忽略:虽然可以捕获,但通常应该让程序终止
与 C++ 的关联性SIGABRT 在 C++ 开发中的高发场景:
断言失败:assert() 宏在调试模式下失败
标准库异常:某些标准库函数检测到错误时调用 abort()
内存管理错误:new 操作符在无法分配内存时可能调用 abort()
调试工具:Address Sani ...
SIGILL (4) 非法指令详解
SIGILL (4) 非法指令详解:C++ 开发者的崩溃调试指南一、信号基础认知(开篇 5 分钟入门)信号核心信息
信号编号:4
信号名称:SIGILL (Illegal Instruction)
POSIX 标准:是(POSIX.1-2001 定义)
可捕获:是
默认行为:终止进程并生成 coredump
核心定位SIGILL 的本质作用是非法指令触发中断。当 CPU 尝试执行一条它无法识别或不允许执行的指令时,操作系统会发送 SIGILL 信号。这通常发生在执行了未定义的指令、特权指令或架构不支持的指令时。
默认行为Linux 内核的默认处理逻辑:
终止进程:立即终止当前进程
生成 coredump:如果系统配置允许,会生成 core 文件
可捕获:可以捕获,但通常应该让程序终止
与 C++ 的关联性SIGILL 在 C++ 开发中的高发场景:
内联汇编错误:手写汇编代码包含非法指令
动态库兼容性:加载了不兼容架构的动态库
代码注入攻击:恶意代码尝试执行非法指令
编译器优化问题:某些极端优化可能导致问题
JIT 编译错误:即时编译生成的代码包含非法指令
二、信号触发场 ...
