当前位置: 首页 > news >正文

跳跃表与跳跃树:Antithesis 如何用奇特数据结构解决测试难题?

BugBash 2026导航栏信息

导航栏包含产品相关、解决方案、公司信息和资源四个板块。产品相关板块有 What is Antithesis?、How Antithesis works、How we're different 等内容;解决方案板块涵盖 Problems we solve、Security approach、Fintech、Blockchain、Databases、Cloud infrastructure、Customer stories、Working with Antithesis 等;公司信息板块包含 Contact us、Backstory、Leadership、Careers、Brand;资源板块有 Docs、Blog、Log in、Book a demo。

博客文章:跳跃表有什么用?

文章作者是 Will Wilson,CEO,发表于 2026 年 4 月 16 日。不久前,作者加入 Phil Eaton 的读书俱乐部研读《多核编程的艺术》,期间谈到了跳跃表。在作者职业生涯大部分时间里,跳跃表是小众数据结构,应用场景不多。但大约六年前,Antithesis 遇到问题,其扩展结构发挥了作用。

什么是跳跃表?

跳跃表是随机化的数据结构,可作为二叉搜索树的直接替代品,具有相同接口和渐近复杂度。有人喜欢它是因为可实现相对简单且易于理解的无锁并发版本,也有人出于个人喜好。从实现看,可看作链表加“快速通道”。从基本链表开始,添加一系列链表,每层节点数量逐渐减少,高层节点通过概率随机选择,每个节点有 50% 概率被提升到上一层。这有助于搜索,可利用高层链表更快跳到目标节点。在普通链表中查找节点需 O(n) 时间,而跳跃表查找节点时间复杂度为 O(log n)。

问题所在

Antithesis 多次运行客户软件查找漏洞,模糊测试器注入不同故障,测试代码做不同随机决策,形成时间线分支树。有很多查询需求,相当于对树进行折叠操作。但测试软件输出数据量大,存入分析型数据库(当时用 Google BigQuery),该数据库并行扫描大量数据计算聚合结果快,但按 ID 获取特定行的点查询慢。而在数据库中用父指针表示树,回答查询需逐个节点遍历树,在 BigQuery 中每次操作会全表扫描,基本查询会对整个数据集进行 O(深度) 次读取。拆分数据存储在不同数据库会带来新问题,如插入需同时写入两个系统,保持一致性需类似两阶段提交技术,且当时 BigQuery 一致性语义宽松,不清楚能否保持同步。

什么是跳跃树?

跳跃树类似跳跃表,是一棵树。它有 0 层树,上面有一系列树,每棵树节点数量约是下一层的 50%。从根节点到叶子节点的路径上的节点及高层树对应节点形成跳跃表,所以跳跃树是共享结构的跳跃表集合。存储跳跃树需为每一层创建 SQL 表,每个表为节点创建一行,有列存储上一层最近祖先节点和当前节点与上一层祖先节点间所有节点。可通过链式 JOIN 操作查找节点祖先,用固定数量 JOIN 的非递归 SQL 查询查找祖先节点,约需 40 次 JOIN 操作。当时 BigQuery 按扫描数据量收费,表大小几何分布使查询费用相当于两次普通表扫描。不过也有缺点,如查询文本大,但用 JavaScript 编译器生成 SQL。在公司前六年,Antithesis 多数测试属性通过这种方式评估,直到编写了自己的分析型数据库。

跳跃表、跳跃树、跳跃图……

后来发现跳跃树与跳跃图密切相关,跳跃图是基于跳跃表的分布式数据结构。这说明奇特数据结构可能节省大量时间和金钱。此外,Andy Pavlo 称“编写良好”的树比跳跃表更高效,但跳跃表“完全朴素的实现”也有足够性能,在 SQL 编写代码时有用。感谢 Phil Eaton 建议撰写此文。

结尾福利

读到文章结尾可领取免费贴纸,把它们贴在任何地方,等着收获赞美。

http://www.jsqmd.com/news/668275/

相关文章:

  • XML CDATA
  • 互联网大厂 Java 求职面试:音视频场景中的技术挑战
  • Halcon单图自标定:从直线提取到畸变校正的实战解析
  • SAP Analysis Office 部署与维护实战指南
  • 别再混淆了!5分钟搞懂5G里的SUPI、SUCI和IMSI到底啥关系
  • 互联网大厂 Java 求职面试:音视频场景下的技术挑战
  • 从技术黑箱到法律可溯:2026奇点大会强制推行的AGI“行为日志双签名”标准(含ISO/IEC 27001-AI附录草案)
  • 从Docker容器到可复用的镜像:Vitis AI 2.5环境自定义与持久化保存指南
  • Nginx编译安装踩坑记:除了PCRE,这几个依赖库也别忘了装(CentOS 7/8实测)
  • 体验 ROCm 和 Strix Halo:从系统设置到模型运行全流程分享!
  • 【3D视觉实战】ShapeNet数据集:从核心结构到语义扩展的完整指南
  • 谷歌开源大模型Gemma 4实测:千元机跑本地模型,速度慢、易出错?
  • Kali Linux 2023 上 Burp Suite Pro 2024 的保姆级安装与激活指南(含JDK 11配置)
  • PCHMI权限开发避坑指南:从用户等级映射到实际功能锁定的完整流程
  • 从LCD到MicroLED:手把手拆解主流显示技术演进史,看懂未来屏幕长啥样
  • 2025届学术党必备的AI写作网站横评
  • 人形机器人半马:进步与失控并存,短板暴露促进行业迭代
  • 从FGM到FreeLB:一次讲透对抗训练怎么“卷”起来的(附代码避坑指南)
  • DeepSeek融资3亿美元背后:算力人才两手抓,国产适配成行业变量
  • nRF52832串口DMA效率翻倍秘籍:从“定长接收”到“伪不定长”的完整配置流程
  • FanControl终极中文设置指南:5分钟让风扇控制说中文的完整教程
  • 告别手动敲命令:用Ansible CE模块批量管理华为交换机端口(附完整Playbook)
  • 用Rainmeter打造你的专属桌面:从零开始配置农历、股票和圆盘时钟插件
  • 【Java学习新手第一篇】:Hello World !
  • 别再乱选启动盘格式了!用Rufus烧录Windows安装盘时,GPT和MBR到底怎么选?(附DiskGenius查看方法)
  • 用STM32F407的TIM1驱动舵机:CubeMX配置PWM详解与避坑指南
  • 如何用TsubakiTranslator轻松翻译Galgame,打破语言障碍?
  • MMC并网逆变器:基于滑模控制的优化策略与实验结果分析
  • C#连接OPC UA服务器的三种身份验证方式详解:匿名、用户名密码和证书(附完整代码)
  • 告别驱动冲突:多维度解决AMD显卡驱动版本不匹配难题