Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否值得尝试编写万无一失的数据结构?

是否值得尝试编写万无一失的数据结构?
EN

Software Engineering用户
提问于 2013-03-02 19:10:44
回答 3查看 616关注 0票数 3

问题

我们需要以类似于表的方式存储数据,但是我们有非常严格的空间限制(每个10k+行表的~1MB)。我们存储这样的数据:

代码语言:javascript
运行
AI代码解释
复制
ID | reviews | factor | score | interval | etc.
---+---------+--------+-------+----------+-----
 1 |     244 |    2.4 |    10 |     4268 | ...

在一个简单的二进制格式(一个一维字节数组,其中每一行的索引可以简单地通过了解每一行的长度,这是固定的)。

只有一个函数读取此数据(按其索引获取一行),只有一个函数追加一个新行(到末尾)。从表中移除项是永远不需要的(该表仅附加)。这两个功能都包含了相当数量的单元测试。

问题是:我们需要能够快速地遍历按不同列排序的行。换句话说,我们需要至少按两列对数据进行排序。

--一个简单的解决方案

为了解决这个问题,我们将实现同样是二进制数据块的索引。现在,我将通过创建只列出原始表中行的索引的有序数据结构来直观地做到这一点:

代码语言:javascript
运行
AI代码解释
复制
factor_index        score_index
------------        -----------
          6                  2
          2                  1
          3                  6
          1                  4
          .                  .

将新行附加到表中的函数必须更新,才能使索引也被更新。

示例:要获得按得分排序的第一项,我们只需在索引表中查找score (2)的第一个值,并从原始表中获得相应的行(如果我们同意该表是零索引的,则为第三行)。

然而,有人建议我采取不同的办法。

--一个更复杂但更安全的

版本

我们不只是存储索引,而是在每个索引表中复制ID字段:

代码语言:javascript
运行
AI代码解释
复制
factor_index | ID        score_index | ID
-------------+---        ------------+---
          6  | 46                  2 |  8
          2  |  8                  1 | 14
          3  | 91                  6 | 46
          1  | 14                  4 | 60
          .  |  .                  . |  .

然后保持原始表按ID排序,并仅将索引用作原始表中二进制搜索的起始位置。

添加新记录的函数现在必须按ID执行二进制搜索,以查找插入新行的位置,并使索引更新。

为了获得按分数排序的第一项,我们在索引表中查找分数(2,8)的第一行,并使用索引(2)作为表中二进制搜索的起始位置。如果数据是有效的,我们甚至不需要进行二进制搜索,因为在位置2,我们将找到ID为8的行。但是,如果我们发现位置2的记录有不同的索引,我们继续进行二进制搜索以找到正确的数据,并记录错误。

这种方法的论点是,即使索引指向表中的错误行,它也会工作。

不过,我很难相信这种方法确实更好,原因如下:

  • 它需要一个二进制搜索,这可能是一个新的bug来源。
  • 它要求保持表的有序性,这意味着更复杂的插入(相对于简单的附加)。
  • 它并不能防止主表出现故障:如果出现这种情况,索引甚至可能无法通过二进制搜索找到记录。
  • 它需要编写(和测试)从未打算运行的代码。
  • 它使用的数据比所需的要多。

问题

对于我们的应用程序来说,非常高的优先级是,上面的数据始终是有效的。但是,这是否有理由编写更复杂的数据结构和查找机制,以防止可能发生或不可能发生的边缘情况?难道不应该把时间和精力花在为更简单的版本编写更健壮的测试用例上吗?

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2013-03-02 22:09:02

如果我正确地理解了您的索引,它们不是存储它们的最有效的方法。

无论如何,你不能同时在两把钥匙上整理你的桌子,所以我认为你根本不应该试着把它分类。相反,对索引进行排序。

10k行--一个两个字节的值可以指表中的任何条目。因此,构建最初以1..10k为种子的两个数组(或表中有多少个条目)。虽然这些不是CPU意义上的指针,但无论如何都要使用它们作为指针。根据表中的值对两个数组进行排序。

Insert是通过简单地追加记录,然后重建数组来处理的。是的,这是一项相当昂贵的操作,但是由于您已经指定了数组,所以数组并不大,不能增长太多,因此不应该经常这样做。你做的任何事都是天生的至少O(n),一个完整的度假村只有O(n log n),我会走后一条路。(你甚至可能会发现它更快,因为与移动记录相比,对主内存的写入要少得多。)

请注意,这些数组只是两个字节的值,而不是像您所指示的那样的键值对。

还有一些其他的事情也浮现在脑海中--你似乎异常关注数据的大小。这告诉我,要么您正在传输这些块(此时可以省略这些索引,因为它们可以在另一端重新创建),要么您立即在内存中存储了大量这些数据。在后一种情况下,如果您使用的是支持弱引用的语言,则可以使用它们--让块的索引没有被积极地用于垃圾收集,然后在需要时重新创建。

票数 3
EN

Software Engineering用户

发布于 2013-03-02 20:03:47

如果数据有效性至关重要,那么对数据的任何转换都必须将数据从有效状态转换为有效状态。转换机制应确保给定有效输入的输出的有效性。不成功的转换应该安全地失败,使数据处于有效状态。

单元测试只能确保在编写测试时考虑的每个条件下转换都是有效的。在所有数据转换方法中建立一致性可以确保数据在所有可能的条件下都是有效的。

因此,如果数据有效性是一个高优先级,我建议您构建始终有效的数据修改方法,并对它们进行彻底的测试。不要相信一致性是巧合。

票数 2
EN

Software Engineering用户

发布于 2013-03-03 00:00:16

首先,有一件事可以反驳你的论点:

  • 如果一个人想要像你写的那样使用ID,他肯定会首先实现一个ID到行索引(这样ID查找就不需要按特定的顺序查找原始表,并且您也不必在该表上实现二进制搜索)。

但是如果你想一想这一点,你就会发现现在你已经把原来的问题转移到了一个不同的层次--你必须确保ID到行索引没有不同步。当然,现在的优点是,当原始表的行顺序发生变化时,您可以独立地重建这个索引。这是有意义的,当你必须期待这样的变化,你知道它们何时发生,它们很少/在特定的时间点发生。

不过,这真的值得吗?当您100%确信原始表中的行号是有效且不可变的主键时,根据行号构建最简单的可能解决方案,其他一切都更容易出错和“过早无意义”。否则使用ID。

以下是一些无法确定行号是有效主键的方案:

  • 关系数据库中的行通常不会有特殊的顺序。
  • 在基于文件的场景中:数据量不断增长,由于空间限制,您必须将其拆分到多个物理表中。然后ID可能仍然是有效的主键,但行号不是。

在采用基于行号的方法时,请确保不处于这种情况。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/189044

复制
相关文章
一次爬虫的编写尝试
近期有想法,想要拿到指定时间段的新闻/文章信息,简单做个舆情分析。那么最基础的就是先获取文章列表。舆情相关的现成接口有一些,例如 微博的舆情监测平台,里面有比较成熟的api提供;阿里云,百度云也都有舆情接口。不过受限于某些因素,或是费用问题,或是api本身能提供的新闻时间范围不符合预期,导致无法直接使用。那么就考虑临时通过spider去抓取一些信息,用于支持本次的工作内容。
程序员架构进阶
2021/10/11
2900
依赖注入是否值得?
在博客的世界里进行了一场关于使用依赖注入(DI)之优点和缺点的有趣讨论。论题是:依赖注入是否真的值得? 讨论始自Jacob Proffitt,他撰文解释他的观点说,依赖注入的伸缩性不好。据Proffitt认为,DI流行的唯一原因是Mocking。 DI进来这么流行的真实原因,和正交性、封装性或者其他“纯粹的”架构考量都没有关系。真正的原因是很多开发者都用DI来帮助使用Mock对象进行单元测试。随你怎么说,这个因素实际上说服了聪明的开发者选择DI而不是更简单的实现。 Proffitt甚至声称DI只对单元
张善友
2018/01/30
8350
Java 编写Vue组件(VueGWT的初尝试)
在之前,我曾写过这样的文章《不会前端没事,用GWT Boot和Spring Boot构建Web程序》,这篇文字使用的Domino UI来做前端页面,由于现在更流行VUE,并且VUE的页面更具现代化,所以我尝试了一下VueGWT。
阿提说说
2023/03/07
5800
Java 编写Vue组件(VueGWT的初尝试)
Kubernetes 是否值得学习吗?
Original image by Myriam Zilles from Pixabay
YP小站
2020/06/10
1.3K0
Python编写规则值得收藏
Python中采用PEP8作为编码规范,其中PEP是 python enhancement proposal 的缩写,而“PEP8”中的“8”表示版本号。PEP8是Python代码的样式指南。下面给出PEP8编码规范中的一些应该严格遵守的条目。 1、每个inport语句只导入一个模块,尽量避免一次导入多个模块。 2、不要在行尾添加分号“;”,也不要用分号将两条命令放在同一行。 3、建议每行不超过80个字符,如果超过,建议使用小括号“()”将多行内容隐式的连接起来,而不推荐使用反斜杠“\"进行连接。 不过以下两种情况除外 导入模块的语句过长 注释里的URL
py3study
2020/01/08
5530
2024年最值得尝试的5个CSS框架
在2024年选择适合项目的CSS框架至关重要。这将为构建新的用户界面(UI)组件所需的总体努力定下基调。目前,最重要的是更快地发布新功能,以保持客户的满意度。因此,你需要一个易于使用的CSS框架,它能够提供现成的UI元素。
前端达人
2024/02/21
1.8K0
2024年最值得尝试的5个CSS框架
5 款值得尝试的 Linux 音乐播放器
糖豆贴心提醒,本文阅读时间8分钟 目前 Linux 上有几十个音乐播放器,这使得找到一个最好用的变成很困难。我们已经尝试了很多,如 Cantata,Exaile,甚至不那么出名的 Clementine,Nightingale 和 Quod Libet,但这些软件或多或少的总有一些问题。 在本篇文章中我们将从尝试过的很多个播放器里挑出几个最好用的呈现给大家,但是因为个人使用并不能覆盖到所有播放器,同时这种评测也基于主观意识,所以难免有不到位的地方,请大家指正。 1、 Qmmp Qmmp 算不上是最稳定或者
小小科
2018/05/04
5.7K0
5 款值得尝试的 Linux 音乐播放器
姗姗来迟的疫苗是否值得等待
本期「熊言熊语」是我们科普系列的第一期节目,听日本京都大学的医学博士斯佳聊聊疫苗那些事儿。
生信菜鸟团
2020/05/18
3210
姗姗来迟的疫苗是否值得等待
2025 年最值得尝试的几款 DevOps 平台工具推荐
在当今软件开发与运维紧密融合的大趋势下,DevOps 平台对于众多企业加速推进数字化转型起着至关重要的作用。步入 2025 年,面对市场持续快速变化的需求以及日益复杂的技术架构,挑选一款契合度高、功能完善的 DevOps 平台,既是优化研发流程的重要手段,也是企业达成高效协作与持续交付目标的基础保障。接下来,我们将介绍几款涵盖代码管理、自动化部署、监控运维等功能的 DevOps 平台工具,助力企业在技术竞争中占据有利地位。
用户11533487
2025/03/03
1840
2022 年值得尝试的 7 个 MQTT 客户端工具
随着物联网行业的飞速发展,MQTT 协议也被越来越多的公司及开发者所使用。在学习和使用 MQTT 的过程中,一个得心应手的客户端工具可以极大的方便开发者进行 MQTT 特性的探索及物联网应用的调试,缩短开发周期。
EMQ映云科技
2022/08/02
3.9K0
ChatGPT Plus 经验分享:是否值得花钱升级?
ChatGPT 的每月订阅方案- ChatGPT Plus 已经推出一段时间了,目前的费用是$20 USD / 月(约TWD 610 / 月)。
一个正经的AI
2024/01/22
5340
ChatGPT Plus 经验分享:是否值得花钱升级?
Linux 开发过程那么麻烦,是否值得?
Linux 从诞生至今,已经快有 30 年了。这期间 Linux 一直延续着通过邮件来提交变更、审查、讨论直至批准的研发过程,这一流程非常费时费力,不仅成为新人的进入门槛,也成了可持续生产的障碍。那么,为什么 Linux 一直要坚持遵循这一过程呢,它能带来什么好处?存在哪些弊端?有什么解决办法吗?
逆锋起笔
2020/11/30
4620
编写 Shell脚本 ,监控内存是否溢出
threshold 变量用于设置内存使用的阈值,这里设置为90,表示当内存使用超过90%时触发警报。
一写代码就开心
2023/08/13
4210
如何判断一个项目是否值得投资?
评判一个项目是否赚钱主要看他的投资回报率。现在生活中有很多项目宣称自己有多赚钱,其实稍微想一下,就会知道不太可能。
石云升
2022/08/25
5560
解惑:Python是否值得学习?最强语言展露端倪
5 月 13 日,由 ThoughtWorks 主办的 2017 技术雷法峰会在北京召开。 正如官方宣传提到的:“ThoughtWorks 技术雷达” 并非一个客观的行业分析或者报告,也无意成为一份权威的官方文档。由各行各业诸多顶尖技术专家组成的 ThoughtWorks 全球技术委员会(TAB)每年定期讨论全球热门技术的发展现状,并以雷达形式对各类技术的成熟度进行评估并给出建议,为从程序员到 CIO/CTO 的利益相关者提供参考。而这也是大会名称之所以叫 “雷达” 的意义所在。 13 日上午,Though
AI研习社
2018/03/28
8570
解惑:Python是否值得学习?最强语言展露端倪
【企业架构】2022年TOGAF认证是否仍然值得
TOGAF可以帮助组织设计和开发IT基础架构,而不会带来很多麻烦。TOGAF专家对于实施优秀的IT基础设施开发战略至关重要,目前正在广泛寻找。目前,拥有TOGAF认证的人不够多,这对专业人士非常有益。TOGAF专家通过与部门主管沟通,帮助快速有效地设计IT基础架构。 现在进入主要问题,让我们知道,在2022年TOGAF认证仍然值得吗? 2022年TOGAF认证是否仍然值得? 2020年是一切发生剧烈变化的一年。全世界的专业人士都受到了影响,企业现在已经意识到员工技能的价值,因此他们急切地寻找更多的技能型员
架构师研究会
2022/03/08
1.1K0
2018值得尝试的无参数全局优化新算法,所有测试取得最优结果
该文介绍了如何使用dlib库实现一个无参数、无梯度的黑盒优化算法,该算法可以用于机器学习和深度学习中的超参数优化,并且与现有的方法相比具有更好的性能。该算法可以用于解决机器学习中的特征选择问题,以及机器学习、深度学习中的超参数优化问题。
企鹅号小编
2018/01/05
1.3K0
2018值得尝试的无参数全局优化新算法,所有测试取得最优结果
Python利用Toshare:给上证50的股票是否值得投资评级
https://yuyy.info/big_data/class_4_Toshare:给上证50的股票是否值得投资评级/实验二_上证50是否值得投资.html
Yuyy
2022/06/28
3500
Python利用Toshare:给上证50的股票是否值得投资评级
社会化登录是什么?企业是否值得实施?
社会化登录,是指用户使用社交平台的身份认证信息在第三方应用或网址进行认证登录的流程,比如大家经常使用个人微信、QQ、微博等社交账号登录滴滴、网易云音乐等。社会化登录不仅有助于简化用户在第三方平台的登录体验,同时也为用户在第三方平台创建新账号提供了一种更为简单便捷的方式。不论是对于普通用户来说,还是企业来说,社会化登录都有着无可比拟的优势。
玉符IDaaS
2020/10/13
1.4K0
【干货】2018值得尝试的无参数全局优化新算法,所有测试取得最优结果
来源:blog.dlib.net 作者:Davis King 【新智元导读】本文介绍了一个名为LIPO的全局优化方法,这个方法没有参数,而且经验证比随机搜索方法好。基于此,作者提出了MaxLIPO和置信域方法混合使用的优化方法,在所有测试中,都取得了最优结果,而且不需要任何参数。你还在手动调参?不如试一下更好的方法。 有一个常见的问题:你想使用某个机器学习算法,但它总有一些难搞的超参数。例如权重衰减大小,高斯核宽度等等。算法不会设置这些参数,而是需要你去决定它们的值。如果不把这些参数设置为“良好”的值,这个
新智元
2018/03/20
1.9K0
【干货】2018值得尝试的无参数全局优化新算法,所有测试取得最优结果

相似问题

创建重复资源(例如用户)的尝试是否值得抛出异常?

20

MSDN是否值得个人使用?

40

是否值得为具有最基本的getter/setter的DTO编写单元测试?

10

Asp.Net标识值是否值得开销?

10

是否值得将Django项目转换为Rails?

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档