面向亿行 C/C++ 代码的静态分析系统设计及实践-肖枭Thx! DevOps: 代码质量责任应该左移 设计 代码 开发 代码 评审 入库 测试 发布 1. 非研发人员主导,沟通成本高,推动修复周期长 2. 很难形成标准推动研发实施 3. 形成技术债,偿债成本高 1. 代码签入前,研发人员有义务修复问题 2. 测试人员早期加入,更懂项目研发的情况,沟通成本低,加快上线 3. 能逐步形成好的编码规范和最佳实践 检查代码风格问题挺准,但是 我warning都不看,还看这个? 回忆下代码评审 时最不能忍的事 是啥?对,就是 不能像在IDE里 面一样查看符号 定义使用。 代码交叉索引 方法4:Bug生命周期跟踪 精确查找类似Bug,利用 标记数据排除潜在误报 通过修复率等参数对分析 器进行综合评价 降低感知误报率 方法5:防止误标和作弊 标记量,间隔时间,标记内容 用基线数据训练模型 用聚类和离群检测找到违反者 红黑榜鼓励参与者 降低感知误报率0 码力 | 39 页 | 6.88 MB | 1 年前3
Hello 算法 1.0.0b1 C++版,我们先将其添加到堆底。添加后,由于 val 可能大于堆中其它元素,此时堆的成立条件可能已 经被破坏,因此需要修复从插入结点到根结点这条路径上的各个结点,该操作被称为「堆化 Heapify」。 考虑从入堆结点开始,从底至顶执行堆化。具体地,比较插入结点与其父结点的值,若插入结点更大则将它们 交换;并循环以上操作,从底至顶地修复堆中的各个结点;直至越过根结点时结束,或当遇到无需交换的结点 时提前结束。 8. 堆 hello‑algo 开始,从底至顶堆化 */ void siftUp(int i) { while (true) { // 获取结点 i 的父结点 int p = parent(i); // 当“越过根结点”或“结点无需修复”时,结束堆化 if (p < 0 || maxHeap[i] <= maxHeap[p]) break; // 交换两结点 swap(maxHeap[i], maxHeap[p]); // 128 i = p; } } 堆顶元素出堆 堆顶元素是二叉树根结点,即列表首元素,如果我们直接将首元素从列表中删除,则二叉树中所有结点都会随 之发生移位(索引发生变化),这样后续使用堆化修复就很麻烦了。为了尽量减少元素索引变动,采取以下操 作步骤: 1. 交换堆顶元素与堆底元素(即交换根结点与最右叶结点); 2. 交换完成后,将堆底从列表中删除(注意,因为已经交换,实际上删除的是原来的堆顶元素);0 码力 | 187 页 | 14.71 MB | 1 年前3
Hello 算法 1.0.0b2 C++版,我们先将其添加到堆底。添加后,由于 val 可能大于堆中其它元素,此时堆的成立条件可能已 经被破坏,因此需要修复从插入结点到根结点这条路径上的各个结点,该操作被称为「堆化 Heapify」。 考虑从入堆结点开始,从底至顶执行堆化。具体地,比较插入结点与其父结点的值,若插入结点更大则将它们 交换;并循环以上操作,从底至顶地修复堆中的各个结点;直至越过根结点时结束,或当遇到无需交换的结点 时提前结束。 8. 堆 hello‑algo 开始,从底至顶堆化 */ void siftUp(int i) { while (true) { // 获取结点 i 的父结点 int p = parent(i); // 当“越过根结点”或“结点无需修复”时,结束堆化 if (p < 0 || maxHeap[i] <= maxHeap[p]) break; // 交换两结点 swap(maxHeap[i], maxHeap[p]); // 128 i = p; } } 堆顶元素出堆 堆顶元素是二叉树根结点,即列表首元素,如果我们直接将首元素从列表中删除,则二叉树中所有结点都会随 之发生移位(索引发生变化),这样后续使用堆化修复就很麻烦了。为了尽量减少元素索引变动,采取以下操 作步骤: 1. 交换堆顶元素与堆底元素(即交换根结点与最右叶结点); 2. 交换完成后,将堆底从列表中删除(注意,因为已经交换,实际上删除的是原来的堆顶元素);0 码力 | 197 页 | 15.72 MB | 1 年前3
Hello 算法 1.0.0b4 C++版,我们首先将其添加到堆底。添加之后,由于 val 可能大于堆中其他元素,堆的成立条件可能 已被破坏。因此,需要修复从插入节点到根节点的路径上的各个节点,这个操作被称为「堆化 Heapify」。 考虑从入堆节点开始,从底至顶执行堆化。具体来说,我们比较插入节点与其父节点的值,如果插入节点更 大,则将它们交换。然后继续执行此操作,从底至顶修复堆中的各个节点,直至越过根节点或遇到无需交换 的节点时结束。 8. 堆 hello‑algo 开始,从底至顶堆化 */ void siftUp(int i) { while (true) { // 获取节点 i 的父节点 int p = parent(i); // 当“越过根节点”或“节点无需修复”时,结束堆化 if (p < 0 || maxHeap[i] <= maxHeap[p]) break; // 交换两节点 swap(maxHeap[i], maxHeap[p]); // // 循环向上堆化 i = p; } } 堆顶元素出堆 堆顶元素是二叉树的根节点,即列表首元素。如果我们直接从列表中删除首元素,那么二叉树中所有节点的 索引都会发生变化,这将使得后续使用堆化修复变得困难。为了尽量减少元素索引的变动,我们采取以下操 作步骤: 8. 堆 hello‑algo.com 155 1. 交换堆顶元素与堆底元素(即交换根节点与最右叶节点)。 2. 交换完成后,0 码力 | 343 页 | 27.39 MB | 1 年前3
Hello 算法 1.1.0 C++ 版,我们首先将其添加到堆底。添加之后,由于 val 可能大于堆中其他元素,堆的成立条件可能 已被破坏,因此需要修复从插入节点到根节点的路径上的各个节点,这个操作被称为堆化(heapify)。 考虑从入堆节点开始,从底至顶执行堆化。如图 8‑3 所示,我们比较插入节点与其父节点的值,如果插入节 点更大,则将它们交换。然后继续执行此操作,从底至顶修复堆中的各个节点,直至越过根节点或遇到无须 交换的节点时结束。 第 8 章 堆 开始,从底至顶堆化 */ void siftUp(int i) { while (true) { // 获取节点 i 的父节点 int p = parent(i); // 当“越过根节点”或“节点无须修复”时,结束堆化 if (p < 0 || maxHeap[i] <= maxHeap[p]) break; // 交换两节点 swap(maxHeap[i], maxHeap[p]); // 循环向上堆化 i = p; } } 4. 堆顶元素出堆 堆顶元素是二叉树的根节点,即列表首元素。如果我们直接从列表中删除首元素,那么二叉树中所有节点的 索引都会发生变化,这将使得后续使用堆化进行修复变得困难。为了尽量减少元素索引的变动,我们采用以 下操作步骤。 1. 交换堆顶元素与堆底元素(交换根节点与最右叶节点)。 2. 交换完成后,将堆底从列表中删除(注意,由于已经交换,因此实际上删除的是原来的堆顶元素)。0 码力 | 379 页 | 18.47 MB | 1 年前3
Hello 算法 1.0.0b5 C++版,我们首先将其添加到堆底。添加之后,由于 val 可能大于堆中其他元素,堆的成立条件可能 已被破坏。因此,需要修复从插入节点到根节点的路径上的各个节点,这个操作被称为「堆化 heapify」。 考虑从入堆节点开始,从底至顶执行堆化。如图 8‑3 所示,我们比较插入节点与其父节点的值,如果插入节 点更大,则将它们交换。然后继续执行此操作,从底至顶修复堆中的各个节点,直至越过根节点或遇到无须 交换的节点时结束。 第 8 章 堆 开始,从底至顶堆化 */ void siftUp(int i) { while (true) { // 获取节点 i 的父节点 int p = parent(i); // 当“越过根节点”或“节点无须修复”时,结束堆化 if (p < 0 || maxHeap[i] <= maxHeap[p]) break; // 交换两节点 swap(maxHeap[i], maxHeap[p]); // 循环向上堆化 i = p; } } 4. 堆顶元素出堆 堆顶元素是二叉树的根节点,即列表首元素。如果我们直接从列表中删除首元素,那么二叉树中所有节点的 索引都会发生变化,这将使得后续使用堆化修复变得困难。为了尽量减少元素索引的变动,我们采用以下操 作步骤。 第 8 章 堆 hello‑algo.com 177 1. 交换堆顶元素与堆底元素(即交换根节点与最右叶节点)。 2. 交换完0 码力 | 377 页 | 30.69 MB | 1 年前3
Hello 算法 1.0.0 C++版,我们首先将其添加到堆底。添加之后,由于 val 可能大于堆中其他元素,堆的成立条件可能 已被破坏,因此需要修复从插入节点到根节点的路径上的各个节点,这个操作被称为「堆化 heapify」。 考虑从入堆节点开始,从底至顶执行堆化。如图 8‑3 所示,我们比较插入节点与其父节点的值,如果插入节 点更大,则将它们交换。然后继续执行此操作,从底至顶修复堆中的各个节点,直至越过根节点或遇到无须 交换的节点时结束。 第 8 章 堆 开始,从底至顶堆化 */ void siftUp(int i) { while (true) { // 获取节点 i 的父节点 int p = parent(i); // 当“越过根节点”或“节点无须修复”时,结束堆化 if (p < 0 || maxHeap[i] <= maxHeap[p]) break; // 交换两节点 swap(maxHeap[i], maxHeap[p]); // 循环向上堆化 i = p; } } 4. 堆顶元素出堆 堆顶元素是二叉树的根节点,即列表首元素。如果我们直接从列表中删除首元素,那么二叉树中所有节点的 索引都会发生变化,这将使得后续使用堆化进行修复变得困难。为了尽量减少元素索引的变动,我们采用以 下操作步骤。 1. 交换堆顶元素与堆底元素(交换根节点与最右叶节点)。 2. 交换完成后,将堆底从列表中删除(注意,由于已经交换,因此实际上删除的是原来的堆顶元素)。0 码力 | 378 页 | 17.59 MB | 1 年前3
Hello 算法 1.2.0 简体中文 C++ 版,我们首先将其添加到堆底。添加之后,由于 val 可能大于堆中其他元素,堆的成立条件可能 已被破坏,因此需要修复从插入节点到根节点的路径上的各个节点,这个操作被称为堆化(heapify)。 考虑从入堆节点开始,从底至顶执行堆化。如图 8‑3 所示,我们比较插入节点与其父节点的值,如果插入节 点更大,则将它们交换。然后继续执行此操作,从底至顶修复堆中的各个节点,直至越过根节点或遇到无须 交换的节点时结束。 第 8 章 堆 开始,从底至顶堆化 */ void siftUp(int i) { while (true) { // 获取节点 i 的父节点 int p = parent(i); // 当“越过根节点”或“节点无须修复”时,结束堆化 if (p < 0 || maxHeap[i] <= maxHeap[p]) break; // 交换两节点 swap(maxHeap[i], maxHeap[p]); // 循环向上堆化 i = p; } } 4. 堆顶元素出堆 堆顶元素是二叉树的根节点,即列表首元素。如果我们直接从列表中删除首元素,那么二叉树中所有节点的 索引都会发生变化,这将使得后续使用堆化进行修复变得困难。为了尽量减少元素索引的变动,我们采用以 下操作步骤。 1. 交换堆顶元素与堆底元素(交换根节点与最右叶节点)。 2. 交换完成后,将堆底从列表中删除(注意,由于已经交换,因此实际上删除的是原来的堆顶元素)。0 码力 | 379 页 | 18.48 MB | 10 月前3
C++高性能并行编程与优化 - 课件 - 14 C++ 标准库系列课 - 你所不知道的 set 容器短,但不保证稳定。 • 我个人推荐使用久经沙场的 set ,数据量小时更高效。 关于 set 和 map 还没有讲到的 • unordered_set> 会出错,如何修复? • std::less , std::hash ,用户如何自定义他们的特化? • set 的排序函子能否有状态(有捕获变量的 lambda 表达 式) • emplace , emplace_hint 0 码力 | 83 页 | 10.23 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 16 现代 CMake 模块化项目管理指南称为主版本号,出现功能重大变更,以至于和旧 API 不兼容的时候会增加该号。 • minor 称为次版本号,功能有所变更或增加,但依然和旧的 API 兼容时会增加该号。 • patch 称为补丁版号,功能没有改变,只是修复了一些 bug 就重新发布时会增加该号。 • 也有的软件不拘一格(例如我们的 zeno ),索性用发布的日期作为版本号的三个数字, 例如 2022.11.2 。不论采用哪种编号方案,都是几个用点分开的数字,并且数字越大越新0 码力 | 56 页 | 6.87 MB | 1 年前3
共 10 条
- 1













