木鸟杂记

分布式系统,数据库,存储

生活工程学(一):多轮次拆解

我们在工程实践中,有些构建代码的小技巧,其背后所体现的思想,生活中也常常可见。本系列便是这样一组跨越生活和工程的奇怪联想。这是第一篇:多轮次拆解,也即,很多我们习惯一遍完成的事情,有时候拆成多个轮次完成,会简单、高效很多

我在进行 code review 时,常看到一些新手同学在一个 for 循环中干太多事情。常会引起多层嵌套,或者 for 循环内容巨大无比。此时,如果不损失太多性能,我通常建议同学将要干的事情拆成多少个步骤,每个步骤一个 for 循环。甚至,可以每个步骤一个函数。

当然,这些全是从维护角度着眼的。因为人一下总是记不了太多事情,一步步来,而不是揉在一块来,会让每个步骤逻辑清晰很多。后者,我通常称之为”摊大饼“式代码,这种代码的特点是写时很自然,但是维护起来很费劲——细节揉在一起总会让复杂度爆炸。软件工程中的最小可用原型,也是类似的理念。

作者:木鸟杂记 https://www.qtmuniao.com/2023/08/21/life-engineering-many-passes 转载请注明出处

这种理念,其实在”函数式“编程中也随处可见,即对一个数据集操作时,我们会链式的应用一系列变换函数,从而让数据流清晰的展示出来。在大数据处理中,这种范式就更常见了,比如 spark 论文中提到的:

1
2
3
errors.filter(_.contains("HDFS"))
.map(_.split(’\t’)(3))
.collect()

SQL 查询引擎在实现时也是用的类似机制,即将一个查询语句,转换成对一个行列组成的二维数据集,施加多轮次的算子变换。如下图所示。

图源:CMU15445,查询引擎讲义

我高中时学过一点点素描,虽然没有入门,但其多轮次的做图技法给我印象很深:先勾轮廓,再逐层完善。打线的时候也是一层层的打,而非一个地方画完再画另一个地方。我最近常常翻译文章,开始时,我总是务求一遍翻译好。但结果就是非常慢,且很容易放弃。后面开始使用多轮次、逐层打磨法。一开始用 ChatGPT 帮忙翻译一遍,然后自己再对照原文订正语义,最后扫一遍调换语序理顺词句等等。常言道,好文章是改出来的,应该也是这个道理。

滑铁卢大学教授 Srinivasan Keshav 在其 ”How to Read a Paper“ 中阐述了经典的”三遍(three-pas approach)读论文“方法,也是类似的思想:

  1. The first pass:鸟瞰式略读,抓摘要、章节标题、结论等重点内容。
  2. The second pass:稍微细一些,但不要陷入细节。
  3. The third pass:细读,完全理解。

其中任何一步都可以及时停止:这可能不是你需要的论文。但我之前读论文就长陷入一个误区,我愿称之为”地毯式读法“——逐字句过每一个细节。包括我刚开始进行 code review 时,也常常陷入这个误区。

一次性的、按顺序把事情做完,是大部分人的天性,但这种天性往往是低效的,我们要通过不断地训练来克服。说起来,我和老婆出去点菜的时候,也常用两遍法——第一遍把想吃的都加上,第二遍考虑各种约束(偏好强弱、价格高低、吃过与否等等)来将菜品去到一个合理的范围内。

我想背后的原因是:

  1. 人的注意力是有限的,因此只擅长一次专注的做好一件事情。
  2. 人的认知也是一个由浅入深的过程,一层层细化便是利用了这个特点。

本文来自我的小报童付费专栏《系统日知录》,专注分布式系统、存储和数据库,有图数据库、代码解读、优质英文播客翻译、数据库学习、论文解读等等系列,欢迎喜欢我文章的朋友订阅👉专栏支持,你的支持对我持续创作优质文章非常重要。下面是当前文章列表:

图数据库系列

  • 图数据库资料汇总
  • 译: Factorization & Great Ideas from Database Theory
  • Memgraph 系列(二):可串行化实现
  • Memgraph 系列(一):数据多版本管理
  • 【图数据库系列四】与关系模型的“缘”与“争”
  • 【图数据库系列三】图的表示与存储
  • 【图数据库系列二】 Cypher 初探
  • 【图数据库系列一】属性图模型是啥、有啥不足 🔥

数据库

  • 译:数据库五十年来研究趋势
  • 译:数据库中的代码生成(Codegen in Databas…
  • Facebook Velox 运行机制解析
  • 分布式系统架构(二)—— Replica Placement
  • 【好文荐读】DuckDB 中的流水线构建
  • 译:时下大火的向量数据库,你了解多少?
  • 数据处理的大一统——从 Shell 脚本到 SQL 引擎
  • Firebolt:如何在十八个月内组装一个商业数据库
  • 论文:NUMA-Aware Query Evaluation Framework 赏析
  • 优质信息源:分布式系统、存储、数据库 🔥
  • 向量数据库 Milvus 架构解析(一)
  • ER 模型背后的建模哲学
  • 什么是云原生数据库?

存储

  • 存储引擎概述和资料汇总 🔥
  • 译:RocksDB 是如何工作的
  • RocksDB 优化小解(二):Prefix Seek 优化
  • RocksDB 优化小解(三):Async IO
  • 大规模系统中使用 RocksDB 的一些经验

代码&编程

  • 影响我写代码的三个 “Code” 🔥
  • Folly 异步编程之 futures
  • 关于接口和实现
  • C++ 私有函数的 override
  • ErrorCode 还是 Exception ?
  • Infra 面试之数据结构(一):阻塞队列
  • 数据结构与算法(四):递归和迭代

每天学点数据库系列

  • 【每天学点数据库】Lecture #06:内存管理
  • 【每天学点数据库】Lecture #05:数据压缩
  • 【每天学点数据库】Lecture #05:负载类型和存储模型
  • 【每天学点数据库】Lecture #04:数据编码
  • 【每天学点数据库】Lecture #04:日志构型存储
  • 【每天学点数据库】Lecture #03:Data Layout
  • 【每天学点数据库】Lecture #03: Database and OS
  • 【每天学点数据库】Lecture #03:存储层次体系
  • 【每天学点数据库】Lecture #01:关系代数
  • 【每天学点数据库】Lecture #01:关系模型
  • 【每天学点数据库】Lecture #01:数据模型

杂谈

  • 数据库面试的几个常见误区 🔥
  • 生活工程学(一):多轮次拆解🔥
  • 系统中一些有趣的概念对
  • 系统设计时的简洁和完备
  • 工程经验的周期
  • 关于“名字”拿来
  • Cache 和 Buffer 都是缓存有什么区别?

我是青藤木鸟,一个喜欢摄影、专注大规模数据系统的程序员,欢迎关注我的公众号:“木鸟杂记”,有更多的分布式系统、存储和数据库相关的文章,欢迎关注。 关注公众号后,回复“资料”可以获取我总结一份分布式数据库学习资料。 回复“优惠券”可以获取我的大规模数据系统付费专栏《系统日知录》的八折优惠券。

我们还有相关的分布式系统和数据库的群,可以添加我的微信号:qtmuniao,我拉你入群。加我时记得备注:“分布式系统群”。 另外,如果你不想加群,还有一个分布式系统和数据库的论坛(点这里),欢迎来玩耍。

wx-distributed-system-s.jpg