CodeQL学习笔记(2)-QL语法(递归)
最近在学习CodeQL,对于CodeQL就不介绍了,目前网上一搜一大把。本系列是学习CodeQL的个人学习笔记,根据个人知识库笔记修改整理而来的,分享出来共同学习。个人觉得QL的语法比较反人类,至少与目前主流的这些OOP语言相比,还是有一定难度的。与现在网上的大多数所谓CodeQL教程不同,本系列基于官方文档和情景实例,包含大量的个人理解、思考和延伸,直入主题,只切要害,几乎没有废话,并且坚持用从每一个实例中学习总结归纳,再到实例中验证。希望能给各位一点不一样的见解和思路。当然,也正是如此必定会包含一定的错误,希望各位大佬能在评论区留言指正。
CodeQL学习笔记(1)
递归
我们逐渐来理解递归。先设定一个目标–查询国王是否有活着的兄弟姐妹
// 表示p和“King Basil”的父母是相同的,则p是其兄弟姐妹
from Person p
where parentOf(p) = parentOf("King Basil") and // parentOf(Person p)返回p的父母not p = "King Basil"and not p.isDeceased() // isDeceased()谓词,判断是否死亡
select p
// 没有结果
然后尝试查找这些兄弟姐妹们是否有孩子
根据paretOf定义一个childOf谓词(反逻辑)
Person childOf(Person p){ // 这里的返回值是一个Person类型p = paretOf(result)
}
select childOf(p)
// 依旧没有结果
在QL谓词中,约定result为返回值。
理解代码:这里有两个身份,p和result,要搞清楚它们间的关系。定义的childOf谓词在这里表示–childOf§ = result,p的孩子是result。那么在谓词实现中,要把这个逻辑反过来,类似于数学中的反函数的概念,p = parentOf(result),当且仅当 p 是某人的父亲时,某人是 p 的孩子
在谓词中不一定要在谓词定义中直接写明result = ,也可以把result放到后面来作为一个“已知”变量来表达关系。(引用官方文档:相反,您还可以通过用 result 来“反向”表示 p 和 result 之间的关系。)
再尝试找是否有活着的堂兄弟、堂兄弟的孩子、二表兄弟等……这里面会涉及到非常复杂的关系,最好是能够定义一个谓词列出所有的亲戚relativeOf(Person p):如果两个人拥有同一个祖先,那么他们就是亲戚
如果我们定义一个谓词ancestorOf(Person p),列出某个人所有的祖先,这其中包含它的parent,parent的parent……无穷尽,这里就存在了一个递归的思想。我们可以把祖先的定义进行拆分,分为直接父母和已经确定是祖先的直接父母
对于祖先定义的拆分的理解,如果某人已经被确定是祖先了,那么它的直接父母肯定也是祖先
Person ancestorOf(Person p){result = parentOf(p) orresult = parentOf(ancestorOf(p))
}
下面看一个递归的具体例子
// 列出0-100
int getANumber(){result = 0orresult <= 100 and result = getANumber() + 1
}
select getANumber() as number // 列名为“number”,列名不用加引号
这里需要与传统函数式编程严格区分开,不是按传统编程语言的“从上到下执行”模式。ql中在处理递归时,会根据查询逻辑查找所有满足条件的可能结果。因此,select getANumber() 其实是在寻找 所有可能满足 getANumber() 定义条件的 result 值,而不是只运行一次 getANumber() 函数。
- QL 会首先满足 result = 0,这是递归的基础条件。所以getANumber()在没有其他限制的情况下,可以返回 0。
- 然后CodeQL 会继续尝试满足其他条件,以找到 所有可能的 result 值。
• 递归条件result = getANumber() + 1意味着 QL 还会去找 比 0 大的所有整数结果,直到达到 result = 100 的上限。
• 例如,在 result = 0 确定之后,递归条件允许 result = 1(通过 result = getANumber() + 1 得到),接着再允许 result = 2,以此类推,直到 100。(可以看成是result <= 100 and result = 1, result <= 100 and result = 2……)
闭包
我们把上面的递归ancestorOf(Person p)改写一下
Person getAncestor(){result = this.getAParent()orresult = this.getAParent().getAnAncestor()
}
其实它的本质就是不断的在找parent,parent的parent……,在QL里有个概念叫做闭包,简单理解就是对某个类的谓词重复执行的简化,不需要我们再去写复杂的递归谓词。
传递闭包(+)
直接对getParent这个谓词使用传递闭包p.getAParent+(),这里得到的是p的parent、p的parent的parent……,是不包含p自身的,即递归一次或多次(>=1,和正则表达式中+、*的用法一致)。
from Person p
where p = "Cornelius"
select p.getAParent+() as name // 找到Cornelius的所有ancestor,getAnAncestor()等价于getAParent+()
自反传递闭包(*)
与传递闭包唯一的差别是包含p本身,递归0次或多次(>=0)
select p.getAParent*() as name
其他详细的递归深入用法等到后期专题再展开。当前学习的目的仅是快速入门。
完善代码
在学习完闭包之后,就可以实现前面我们的需求–找出国王的所有亲戚relativeOf(Person p)
Person relativeOf(Person p){parentOf*(p) = parentOf*(result)andnot result = p // 由于这个具体例子中的国王已经死了,在where中也已经过滤了,所以可以不加。正常来说自反传递闭包需要排除自身
}from Person p
wherenot p.isDeceased() andp = relativeOf("King Basil")
select p
相关文章:
CodeQL学习笔记(2)-QL语法(递归)
最近在学习CodeQL,对于CodeQL就不介绍了,目前网上一搜一大把。本系列是学习CodeQL的个人学习笔记,根据个人知识库笔记修改整理而来的,分享出来共同学习。个人觉得QL的语法比较反人类,至少与目前主流的这些OOP语言相比&…...

Video-XL:面向小时级视频理解的超长视觉语言模型
在人工智能领域,视频理解一直是一个挑战性的任务,尤其是对于长时间视频内容的理解。现在,Video-XL的问世标志着我们在这一领域迈出了重要的一步。Video-XL是一个专为小时级视频理解设计的超长视觉语言模型,它能够处理超长视频序列…...
postgresql subtransaction以及他的效能
文章目录 什么是subtransaction使用子事务PL/pgSQL 中的子事务与其他数据库的兼容性运行性能测试Subtransaction的实现子事务和可见性解释测试结果诊断子事务过多的问题结论 什么是subtransaction 在 PostgreSQL 中,当处于自动提交模式时,必须使用 BEGI…...

新手逆向实战三部曲之二——通过更改关键跳注册软件(爆破)
教程开始: 软件已无壳,具体脱壳请移步"新手逆向实战三部曲之一",这里略去查壳脱壳。 先用OD打开软件试运行了解下注册流程,以便找到突破口 经过对软件的了解,本次教程采用的是下bp MessageBoxA断点的方法找…...
高级SQL技巧:提升数据查询与分析能力的关键
高级SQL技巧:提升数据查询与分析能力的关键 在数据驱动的时代,SQL(结构化查询语言)是数据分析和数据库管理的基础工具。掌握高级SQL技巧不仅能提高查询效率,还能优化数据库结构,使数据分析和报告更加精准高…...
IntelliJ IDEA 安装 Maven 工具并更换阿里源
Maven是一个强大的项目管理工具,可以帮助Java开发者管理项目依赖、构建项目等。在IntelliJ IDEA中安装Maven工具并将其源更改为阿里源的步骤如下: 1. 安装 Maven 通过 IntelliJ IDEA 自带 Maven 打开 IntelliJ IDEA。创建或打开一个项目。点击菜单栏中…...

MIT 6.824 Lab1记录
MapReduce论文阅读 1. 编程模型 Map 函数(kv -> kv) Map 函数将输入的键值对处理为一系列中间值(键值对),并将所有的中间结果传递给 Reduce 处理。 map(String key, String value):// key: document name// val…...
C语言数据结构学习:[汇总]
介绍 这些是我在学习C语言数据结构时练习的一些题目以及个人笔记 大家也可以参考着来学习 正在更新 大家可以在我的gitee仓库 中下载笔记源文件 笔记源文件可以在Notion中导入 内容导航 C语言数据结构学习:单链表-CSDN博客...

unity游戏开发之塔防游戏
如何制作塔防游戏 让我们以迷你游戏的形式创建一个休闲塔防。 从基本处理到适用技术,应有尽有,因此您只需制作一次即可获得 Unity 中的游戏制作专业知识。 与背景素材结合使用时,您将获得以下游戏视图: 由于在创建过程中使用了 …...
前端项目接入sqlite轻量级数据库sql.js指南
前端项目接入sqlite轻量级数据库sql.js指南 引言 sql.js 是一个强大的JavaScript库,它使得SQLite数据库能够在网页浏览器中运行。这个开源项目提供了一种方式,让开发者可以在前端环境中实现轻量级的数据库操作,无需依赖服务器端数据存储&…...
模拟退火算法(Simulated Annealing)详细解读
模拟退火算法(Simulated Annealing) 是一种随机优化算法,受到物理学中金属退火过程的启发。它用于寻找全局最优解,特别适合解决组合优化问题。模拟退火算法通过模拟物质在加热和冷却过程中粒子位置的变化,逐渐寻找系统…...

(二十一)、Docker 部署 Minikube 使用可视化管理工具 Kuboard
文章目录 1、介绍docker 运行 minikube 集群节点(kube-apiserver )无法被直接访问的问题Kuboard 需要访问到 k8s 集群的kube-apiserver 2、安装 Kuboard2.1、k8s 集群节点可以被外部直接访问的情况2.1.1、下载镜像2.1.2、运行 deployment.yml2.1.3、访问…...

代码编辑组件
代码编辑组件 文章说明核心代码运行演示源码下载 文章说明 拖了很久,总算是自己写了一个简单的代码编辑组件,虽然还有不少的bug,真的很难写,在写的过程中感觉自己的前端技术根本不够用,好像总是方案不够好;…...

裴蜀定理与欧几里得算法——蓝桥杯真题中的应用
目录 裴蜀定理(Bzouts Theorem)1、定义2、推论3、欧几里得算法4、多个整数的裴蜀定理扩展 真题挑战解题思路代码实现与详细注释代码解析 裴蜀定理(Bzout’s Theorem) 1、定义 对于任意两个整数 a 和 b ,如果它们的最…...

冯诺依曼架构及CPU相关概念
一. 操作系统的概念 1. 概念 操作系统(Operating System). 首先, 所有的计算机都是由软件和硬件构成的. 而操作系统就是许许多多软件中的一种软件, 操作系统可以看作是由两部分组成: 操作系统内核系统级应用程序. 2. 作用 (1) 管理硬件设备, 调度和协调各个硬件之间的工作.…...

智能管线巡检系统:强化巡检质量,确保安全高效运维
线路巡检质量的监控是确保线路安全、稳定运行的重要环节。为了有效监控巡检质量,采用管线巡检系统是一种高效、科学的手段。以下是对如何通过管线巡检系统实现线路巡检质量监控的详细分析: 一、巡检速度监控 管线巡检系统能够实时监控巡检人员的巡检速度…...

React写关键字高亮的三个方案
1.js正则replaceAlldangerouslySetInnerHTML{{ __html: xxx }}危险属性 步骤最简单,但是是危险属性,不推荐使用,项目中实在没有头绪,可以使用它应急 通过useMemo计算得到新的状态值,赋值给dangerouslySetInnerHTML属性的__html 关键代码: const [state1, setState1] useSt…...
重塑在线软件开发新纪元:集成高效安全特性,深度解析与评估会员与促销管理系统的系统架构设计
案例 阅读以下关于软件架构设计与评估的叙述,回答问题1和问题2。 【题目】 某电子商务公司拟升级其会员与促销管理系统,向用户提供个性化服务,提高用户的粘性。在项目立项之初,公司领导层一致认为本次升级的主要目标是提升会员管…...

多层感知机的从零实现与softmax的从零实现(真·0000零基础)
今天再读zh.d2l书(4.2. 多层感知机的从零开始实现 — 动手学深度学习 2.0.0 documentation), 看了关于多层感知机的从零实现与softmax的从零实现 目录 mlp从零实现, 点击“paddle”的代码 点击“torch”的代码 训练 参数解…...
【Rust练习】18.特征 Trait
练习题来自:https://practice-zh.course.rs/generics-traits/traits.html 1 // 完成两个 impl 语句块 // 不要修改 main 中的代码 trait Hello {fn say_hi(&self) -> String {String::from("hi")}fn say_something(&self) -> String; }str…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...