《卡片笔记写作法》之读书笔记(一):绪论

《卡片笔记写作法》之读书笔记(一):绪论

D瓜哥
不写,就无法思考。 — 卢曼 1992,53 最近把 《卡片笔记写作法》 读完了,深受启发,相见恨晚。 先分享一个小趣闻:看完这本书,想实践一下,就去购物网站搜合适的活页卡片。考虑到便利性,就选择了 A6 大小的活页。上网找了一圈,也没有找到标准尺寸的 A6 活页。考虑以后直接拿 A4 纸进行裁剪。现在的问题变成了如何把 A4 纸裁剪得标准一些。 看完全书,纵观卡曼的发展过程,特别叹服的一点是,他会不断反思自己的行为和学习方法,并且反复尝试改进自己的学习方法,以求达到最好的效率。反思自己,虽然总是耕读不断,虽然过程中也许捡了不少好砖,但是就像那个捡玉米的猴子,随捡随丢,终究没能垒起我的阅读城堡!可惜可惜! 闲言少叙,书归正传。读这本书,有几点印象特别深刻: 书中将记忆区分为两种机智:存储强度(storage strength)与提取强度(retrieval strength)。并且“存储与提取负相关”,也就是说,存入记忆越容易,提取出来越困难;反之,如果你有些吃力地存入,知识提取会更方便。这点有点意思。 书中一个比喻特别形象:卢曼卡片盒就像是复利投资,而特罗洛普的技术就像是储蓄罐。复利投资可以滚雪球,越滚越大,而且是指数增长。 书中还有一个概念很有意思:“思维网格”,如果知识既不是被孤立地保存,也不是被孤立地学习,而是聚集在一个思想网络中,或者说是“思维模型的网格”中,那么理解新的信息就变得更容易了。 卡片笔记学习法自然而然产生的自下而上写作法拥有一个巨大优势:我们所使用的想法都嵌入了丰富的上下文中,并且附带了可以使用的素材,而不是凭空产生的。这样做会带来另一个意想不到的收获,那就是我们会对新的想法持更加开放的态度。可以轻松避免由于预设结论导致的认知偏误。 卡片盒笔记的精华所在:以新的和意想不到的方式,将不同的想法汇集在一起,从而产生新的想法。卢曼的卡片不是简简单单地摘抄,而是自己组织语言的转述,需要加工再输出。不仅仅是摘录原文,更是思想的录像机与连接器,记录下当下的思想,建立与已有思想的链接。 一个巨大的误解是:如果不制订计划,就只能是漫无目的地乱写一气。其实我们真正该做的是构建适合自己的工作流程,让洞见和新想法成为推动我们前进的驱动力。 记笔记也不是最关键的工作,思考、阅读、理解和提出想法才是,笔记只是它们的具体成果。写,无疑是我们思考、阅读、学习、理解和产生想法的最佳催化剂。 书中的真知灼见数不胜数,可以通过D瓜哥的这几篇读书笔记“管中窥豹”。当然,更推荐大家去阅读原文。D瓜哥是在“微信读书”中阅读的免费版,礼尚往来,推荐一下。 D瓜哥把读书笔记整理一下。按照章节,分三篇来分享: 《卡片笔记写作法》之读书笔记(一):绪论 《卡片笔记写作法》之读书笔记(二):有效写作的四个基本原则 《卡片笔记写作法》之读书笔记(三):成功写作的六个步骤 中文版序 卡片盒笔记依赖一种非线性的方式,即缓慢而稳定的改进,促进思维产生持续、微妙的变化,并且事物间相生相依。朱利安发现这些主题在中国哲学中被讨论得更为广泛。 我欣喜地发现,并非我一人有此体验:卡片盒笔记法——关联的、分散的、自下而上的方法不仅比一些教育者们所推崇的线性的、自上而下的方法更为自然,而且衍生出了诸多写作及笔记记录工具。 卡片盒笔记的精华所在:以新的和意想不到的方式,将不同的想法汇集在一起,从而产生新的想法。 随着可使用工具的快速变化,我决定让这本书尽可能地与工具无关。书籍有着不同的生命周期,因此应该更多地关注不受时间影响的方面。 推荐序一 像卢曼一样写卡片 我写作时,手边会放着纸质的卡片。我一般会先在卡片上写下一些灵感,然后再用卡片写作软件将它们正式整合成文章。同样,在阅读时,我也会不断地使用纸质卡片盒与卡片写作软件写下读书心得。 日本知名学者梅棹忠夫在《智识的生产技术》中提到的“京大卡”,他认为卡片要大一些,大概是B6开本大小,更容易保存写作灵感。而我带队研发的“写匠”,更多地参考了美国知名作家纳博科夫的卡片写作法——使用索引卡,通过任意打乱卡片次序完成自己的写作。 尼克拉斯·卢曼是20世纪德国重要的社会学家,而且其影响力已远远超出了社会学领域。 传统的卡片写作法,像纳博科夫,是只使用一个盒子,用一个盒子来保存自己写作的内容。而卢曼多了一个盒子,对自己卡片写作的内容进行索引和整理。 比约克率先区分了记忆竞争的两种不同类型:存储强度(storage strength)与提取强度(retrieval strength)。 “存储与提取负相关”,也就是说,存入记忆越容易,提取出来越困难;反之,如果你有些吃力地存入,知识提取会更方便。 第一类是主题索引。当某个主题的内容积累得足够丰富,卢曼就会做一张主题索引卡,对这个主题进行概览。主题索引卡上会汇集所有相关笔记的编码或链接,每条笔记会用一两个词或一个短句简要说明核心内容。这类索引,相当于给了你一个进入某一主题的入口。第二类与主题索引类似,只不过不是对某一主题的概览,而是针对盒子里相近位置的卡片所涉及的所有不同主题进行概览。第三类是在当前卡片上做索引,标明这条笔记逻辑上的前一条是什么、后一条是什么(这些卡片在盒子里的位置可能并不挨着)。第四类,也是最常用的索引形式,就是简单的“笔记-笔记”连接。两条笔记可能完全没有关系,把它们关联在一起,往往会产生出乎意料的新思路。 我经常推荐的是德国科学家丹尼尔·卢德克(Daniel Lüdecke)开发的开源软件——卡片盒笔记(Zettelkasten)。 一是将文本的颗粒度拆分得更细。组块(block)是认知科学上的一个常用概念,文本组块正是这个概念的具象化。 以大的单位很难记住,拆分成小的单位就更容易记住。写作时,用大脑直接记住的东西越多,写作就越不容易被打断,节省的脑力就越多。 二是建立了一个“双向引用”关系。什么是“双向引用”? 推荐序二 外脑思考,突破思维局限的写作法 我和作者的兴趣一样,也是外脑思考(Thinking Outside the Brain)。 但工具功能很难改变人的思维习惯,而需要配合课程、书籍或教练服务。 千里之行始于跬步的道理中国人都懂,但没人教过我们在一步一步地、枯燥地踏在探索未知的路上时如何保持热情,如何坚持,如何充满信心,如何时刻和自己对话,以及如何走好每一步。书中介绍的工作流和原则,是卢曼等人利用卡片盒实践过的,他们完全无须坚持就充满乐趣地达成了非凡成就。 深知全世界的人仅凭意志力和坚持,绝无可能完成那种极限挑战。只有完全换另一种思维方式,才能心情愉悦地、安全地达成目标。创业如此,做产品如此,写论文亦如此。 把诸如拖延、坚持、压力、焦虑、知识管理、时间管理等热词从脑海里划掉。 使用卡片笔记写作法,我们可以不定期地提取先前的想法和事实,并将它们与其他信息联系起来,这正是专家们推荐的学习方式。 推荐序三 用卡片笔记积累你的知识复利 书中主要介绍的是德国社会学家尼克拉斯·卢曼自创的一套笔记方法,利用这套方法,他一生积累了90000个知识卡片,写了58本书和其他大量出版物。 就是把你感兴趣或者将来可能会用到的知识收集起来,然后用一种像集装箱一样标准化的方式,去处理这些笔记,建立笔记之间的联系,供你使用。 重要的不是记录,而是更好地思考。
日志最佳实践探究

日志最佳实践探究

加入公司以来,参与了很多个项目的开发维护;也排查处理过很多线上问题;为了写 Mock 测试,也专门去日志系统上扒拉过不少日志等等。在整个过程中,对日志的认识有了不少更深刻的认识和体会。也发现不少问题。这里先从存在的问题展开论述。 日志存在的问题 从个人的眼光上来看,当前的系统存在如下问题: 必要日志没有打印出来,导致在追踪问题或测试代码时,带来不必要的麻烦。比如查看一个接口的返回值用于 Mock 测试;再比如 RPC 调用报错,返回值以及错误信息没有打印到日志中,不知道具体错误原因是什么。 日志抽取中日志路径配置错误,导致日志重复收集,带来不必要的处理和存储成本。 日志代码不规范,导致不必要的性能消耗;或者大促时,日志降级不生效。 日志框架繁多,造成造成冲突,遗漏部分日志。 日志配置不规范,不利于日志的采集和清洗。 日志和调用链路物理隔离,查看一个请求的整个调用链路上的日志非常不方便,不利于问题的快速排查和定位。 大家的系统中,存在什么样的日志问题?欢迎留言交流讨论。 针对这些问题,我觉得有些地方值得发力一下。然后,做了一些探索,总结一下,以备后续使用。 日志最佳实践探索 对于日志的使用,相信所有的开发人员都比较清楚,网上也有大量资料,相关日志框架的官方文档,也写的非常详尽,这里就不再赘述。 本文从一个角度对日志规范进行探究:在排查问题时,能否通过日志来尽快地了解系统运行状态,定位问题原因?另外,由于 Java 的日志框架特别多,有一些比较容易迷惑的问题,尝试做出一点总结。 系统运行后,不严格地说,再去观察系统运行状态,就类似于在黑夜中行走。此时,向你扔过来一块板砖🧱,那么,事后如何追责呢? 请问:你能否成功躲开这块叫做 Bug 的板砖🧱? 日志用来记录用户操作、系统运行状态等,是一个系统的重要组成部分。然而,由于日志通常不属于系统的核心功能,但是在日志对于排查问题,有无可替代的作用,理应得到所有开发人员的重视(不重视,怎么甩锅?!)! If dog is a man’s best friend, logs are software engineer’s best friend. — Geshan Manandhar Logging best practices 好的日志可以帮助系统的开发和运维人员: 了解线上系统的运行状态 快速准确定位线上问题 发现系统瓶颈 预警系统潜在风险 挖掘产品最大价值 可以将一个流程完整串起来(比如orderId) …… 不好的日志导致: 对系统的运行状态一知半解,甚至一无所知 系统出现问题无法定位,或者需要花费巨大的时间和精力 无法发现系统瓶颈,不知优化从何做起 无法基于日志对系统运行过程中的错误和潜在风险进行监控和报警 对挖掘用户行为和提升产品价值毫无帮助 …… 日志从功能来说,可分为诊断日志、统计日志、审计日志。统计日志一般由运维组负责;而审计日志,一般是需要通过代码来实现。这里重点来说说诊断日志。 诊断日志, 典型的有: 请求入口和出口 外部服务调用和返回 资源消耗操作: 如读写文件等 容错行为: 如云硬盘的副本修复操作
《领域驱动设计》读书笔记(二):模型驱动设计的构造块

《领域驱动设计》读书笔记(二):模型驱动设计的构造块

遵循“职责驱动设计”的原则, “契约式设计”思想。 开发一个好的领域模型是一门艺术。 Figure 1. 模型驱动设计语言 第 4 章 分离领域 模式:Layered Architecture 在面向对象的程序中,常常会在业务对象中直接写入用户界面、数据库访问等支持代码。而一些业务逻辑则会被嵌入到用户界面组件和数据库脚本中。这么做是为了以最简单的方式在短期内完成开发工作。 如果与领域有关的代码分散在大量的其他代码之中,那么查看和分析领域代码就会变得异常困难。对用户界面的简单修改实际上很可能会改变业务逻辑,而要想调整业务规则也很可能需要对用户界面代码、数据库操作代码或者其他的程序元素进行仔细的筛查。这样就不太可能实现一致的、模型驱动的对象了,同时也会给自动化测试带来困难。考虑到程序中各个活动所涉及的大量逻辑和技术,程序本身必须简单明了,否则就会让人无法理解。 要想创建出能够处理复杂任务的程序,需要做到关注点分离——使设计中的每个部分都得到单独的关注。 Layered Architecture 的基本原则是层中的任何元素都仅依赖于本层的其他元素或其下层的元素。 Figure 2. 应用分层 给复杂的应用程序划分层次。在每一层内分别进行设计,使其具有内聚性并且只依赖于它的下层。采用标准的架构模式,只与上层进行松散的耦合。将所有与领域模型相关的代码放在一个层中,并把它与用户界面层、应用层以及基础设施层的代码分开。领域对象应该将重点放在如何表达领域模型上,而不需要考虑自己的显示和存储问题,也无需管理应用任务等内容。这使得模型的含义足够丰富,结构足够清晰,可以捕捉到基本的业务知识,并有效地使用这些知识。 关注点的清晰分离可以使每一层的设计更易理解和维护。 在连接各层的同时不影响分离带来的好处,这是很多模式的目的所在。 各层之间是松散连接的,层与层的依赖关系只能是单向的。上层可以直接使用或操作下层元素,方法是通过调用下层元素的公共接口,保持对下层元素的引用(至少是暂时的),以及采用常规的交互手段。 如果下层元素需要与上层元素进行通信(不只是回应直接查询),则需要采用另一种通信机制,使用架构模式来连接上下层,如回调模式或 Observers 模式。 最早将用户界面层与应用层和领域层相连的模式是 Model-View-Controller(MVC,模型—视图—控制器)框架。 只要连接方式能够维持领域层的独立性,保证在设计领域对象时不需要同时考虑可能与其交互的用户界面,那么这些连接方式就都是可用的。 最好的架构框架既能解决复杂技术问题,也能让领域开发人员集中精力去表达模型,而不考虑其他问题。 不妄求万全之策,只要有选择性地运用框架来解决难点问题,就可以避开框架的很多不足之处。 领域层是模型的精髓 “领域层”则是领域模型以及所有与其直接相关的设计元素的表现,它由业务逻辑的设计和实现组成。 如果领域逻辑与程序中的其他关注点混在一起,就不可能实现这种一致性。将领域实现独立出来是领域驱动设计的前提。 模式:The Smart UI“反模式” Smart UI是另一种设计方法,与领域驱动设计方法迥然不同且互不兼容。 如果一个经验并不丰富的项目团队要完成一个简单的项目,却决定使用 Model-Driven Design 以及 Layered Architecture,那么这个项目组将会经历一个艰难的学习过程。团队成员不得不去掌握复杂的新技术,艰难地学习对象建模。(即使有这本书的帮助,这也依然是一个具有挑战性的任务!)对基础设施和各层的管理工作使得原本简单的任务却要花费很长的时间来完成。简单项目的开发周期较短,期望值也不是很高。所以,早在项目团队完成任务之前,该项目就会被取消,更谈不上去论证有关这种方法的许多种令人激动的可行性了。 即使项目有更充裕的时间,如果没有专家的帮助,团队成员也不太可能掌握这些技术。最后,假如他们确实能够克服这些困难,恐怕也只会开发出一套简单的系统。因为这个项目本来就不需要丰富的功能。 在用户界面中实现所有的业务逻辑。将应用程序分成小的功能模块,分别将它们实现成用户界面,并在其中嵌入业务规则。用关系数据库作为共享的数据存储库。使用自动化程度最高的用户界面创建工具和可用的可视化编程工具。 如果一个架构能够把那些与领域相关的代码隔离出来,得到一个内聚的领域设计,同时又使领域与系统其他部分保持松散耦合,那么这种架构也许可以支持领域驱动设计。 如何让一个有效的领域模型和一个富有表达力的实现同时演进。 第 5 章 软件中所表示的模型 一个对象是用来表示某种具有连续性和标识的事物的呢(可以跟踪它所经历的不同状态,甚至可以跨不同的实现跟踪它),还是用于描述某种状态的属性呢?这是 Entity 与 Value Object 之间的根本区别。 领域中还有一些方面适合用动作或操作来表示,这比用对象表示更加清楚。这些方面最好用 Service 来表示,而不应把操作的责任强加到 Entity 或 Value Object 上,尽管这样做稍微违背了面向对象的建模传统。 Service 是应客户端请求来完成某事。
AWK 简介

AWK 简介

这周需要处理一个日志文件,有一次体会到 AWK 强大和方便,但也认识到自己对 AWK 了解的粗浅。所以,写篇文章再深入学习一下。 根据维基百科显示,AWK 于二十世纪七十年代在 Bell Labs 创建;其名字来源于三位创始人: Alfred Aho、Peter Weinberger and Brian Kernighan。AWK 是一个现在几乎每台 Linux 机器上都会有这个命令。 AWK 是一种领域专用语言,专用设计用于文本处理,常用于提取文本或者生成报告。 AWK 也像 Shell 一样,方言和实现众多。D瓜哥这里选择最常用的 GNU AWK 实现。 AWK 是以行为单位来处理文本的。它不仅仅是一个命令行,而且是一门语言。 先展示一下我们的实例程序: $ cat employee.txt ajay manager account 45000 sunil clerk account 25000 varun manager sales 50000 amit manager account 47000 tarun peon sales 15000 deepak clerk sales 23000 sunil peon sales 13000 satvik director purchase 80000 AWK 的基本用法如下: # ① 基本格式 $ awk 动作 文件名 # ② 标准 I/O 格式 $ cat 文件名 | awk 动作 先给大家来个 Hello World:
《领域驱动设计》读书笔记(一):运用领域模型

《领域驱动设计》读书笔记(一):运用领域模型

序 控制复杂性的关键是有一个好的领域模型,这个模型不应该仅仅停留在领域的表面,而是要透过表象抓住领域的实质结构,从而为软件开发人员提供他们所需的支持。 在领域建模过程中不应将概念与实现割裂开来。 概念与实现密不可分的最主要原因在于,领域模型的最大价值是它提供了一种通用语言,这种语言是将领域专家和技术人员联系在一起的纽带。 领域模型并不是按照“先建模,后实现”这个次序来工作的。 真正强大的领域模型是随着时间演进的,即使是最有经验的建模人员也往往发现他们是在系统的初始版本完成之后才有了最好的想法。 既品尝过成功的美酒,也体验过失败的沮丧。 前言 真正决定软件复杂性的是设计方法。 很多应用程序最主要的复杂性并不在技术上,而是来自领域本身、用户的活动或业务。 领域驱动设计是一种思维方式,也是一组优先任务,它旨在加速那些必须处理复杂领域的软件项目的开发。 领域驱动设计的实质就是消化吸收大量知识,最后产生一个反映深层次领域知识并聚焦于关键概念的模型。 极端的简约主义是解救那些过度追求设计的执迷者的良方。 实际上, XP最适合那些对设计的感觉很敏锐的开发人员。 XP过程假定人们可以通过重构来改进设计,而且可以经常、快速地完成重构。 首先需要深入研究模型,然后基于最初的(可能是不成熟的)模型实现一个初始设计,再反复改进这个设计。每次团队对领域有了新的理解之后,都需要对模型进行改进,使模型反映出更丰富的知识,而且必须对代码进行重构,以便反映出更深刻的模型,并使应用程序可以充分利用模型的潜力。 第一部分 运用领域模型 模型是一种简化。它是对现实的解释——把与解决问题密切相关的方面抽象出来,而忽略无关的细节。 模型正是解决此类信息超载问题的工具。模型这种知识形式对知识进行了选择性的简化和有意的结构化。 领域模型并非某种特殊的图,而是这种图所要传达的思想。 对这类知识严格的组织且有选择的抽象。 领域建模并不是要尽可能建立一个符合“现实”的模型。 建模更像是制作电影——出于某种目的而概括地反映现实。 在领域驱动的设计中,3个基本用途决定了模型的选择。 模型和设计的核心互相影响。 模型是团队所有成员使用的通用语言的中枢。 模型是浓缩的知识。 软件的核心是其为用户解决领域相关的问题的能力。所有其他特性,不管有多么重要,都要服务于这个基本目的。 第 1 章 消化知识 有效建模的要素: 模型和实现的绑定。 建立了一种基于模型的语言。 开发一个蕴含丰富知识的模型。 提炼模型。 头脑风暴和实验。 语言和草图,再加上头脑风暴活动,将我们的讨论变成“模型实验室”,在这些讨论中可以演示、尝试和判断上百种变化。 高效的领域建模人员是知识的消化者。 领域模型的不断精化迫使开发人员学习重要的业务原理,而不是机械地进行功能开发。领域专家被迫提炼自己已知道的重要知识的过程往往也是完善其自身理解的过程,而且他们会渐渐理解软件项目所必需的概念严谨性。 模型永远都不会是完美的,因为它是一个不断演化完善的过程。 高效率的团队需要有意识地积累知识,并持续学习。 业务活动和规则如同所涉及的实体一样,都是领域的核心,任何领域都有各种类别的概念。知识消化所产生的模型能够反映出对知识的深层理解。 当我们的建模不再局限于寻找实体和值对象时,我们才能充分吸取知识,因为业务规则之间可能会存在不一致。 知识消化是一种探索,它永无止境。 第 2 章 交流与语言的使用 领域模型可成为软件项目通用语言的核心。 模式:Ubiquitous Language 如果语言支离破碎,项目必将遭遇严重问题。领域专家使用他们自己的术语,而技术团队所使用的语言则经过调整,以便从设计角度讨论领域。 日常讨论所使用的术语与代码(软件项目的最重要产品)中使用的术语不一致。甚至同一个人在讲话和写东西时使用的语言也不一致,这导致的后果是,对领域的深刻表述常常稍纵即逝,根本无法记录到代码或文档中。 翻译使得沟通不畅,并削弱了知识消化。 然而任何一方的语言都不能成为公共语言,因为它们无法满足所有的需求。 Ubiquitous Language(通用语言)的词汇包括类和主要操作的名称。 将模型作为语言的支柱。确保团队在内部的所有交流中以及代码中坚持使用这种语言。在画图、写东西,特别是讲话时也要使用这种语言。 通过尝试不同的表示方法(它们反映了备选模型)来消除难点。然后重构代码,重新命名类、方法和模块,以便与新模型保持一致。解决交谈中的术语混淆问题,就像我们对普通词汇形成一致的理解一样。 要认识到, Ubiquitous Language 的更改就是对模型的更改。 领域专家应该抵制不合适或无法充分表达领域理解的术语或结构,开发人员应该密切关注那些将会妨碍设计的有歧义和不一致的地方。 改善模型的最佳方式之一就是通过对话来研究,试着大声说出可能的模型变化中的各种结构。
关于 MySQL 新版连接驱动时区对齐问题的研究

关于 MySQL 新版连接驱动时区对齐问题的研究

D瓜哥
在一个项目开量验证过程中,发现 createDate 字段不正确,比正确时间晚了十四个小时。调研发现,这是一个非常典型的问题。现在把定位问题的思路和解决办法给大家做个分享。 首先,检查数据库配置,查询线上生产环境配置,结果如下: Figure 1. MySQL 变量 同时,检查线上生产环境 MySQL 版本,为问题复现做准备: Figure 2. MySQL 版本 从数据库配置上来说,基本正常,没有发现什么问题。(持续运行了这么长时间,有问题应该早就发现了。) 其次,检查数据库连接配置,正式环境的链接配置如下: jdbc:mysql://<host>:3306/<schema>?createDatabaseIfNotExist=true &characterEncoding=utf-8&useUnicode=true&connectTimeout=2000 &socketTimeout=2000&autoReconnect=true 数据库连接也没有问题。 第三,询问 SA 线上服务器时区配置,回复上是 CST,这个和数据库对应,没有问题。 Figure 3. 与 SA 沟通 配置检查正常,那么只好在本地搭建环境,重现问题,再寻求解决方案。由于项目是基于 Spring Boot 2.3.7.RELEASE 开发的,相关依赖也尽量使用 Spring Boot 指定版本的,所以,很快把开发环境搭好了。 在配置服务器环境时,遇到一点小小的问题:我一直以为有个时区名称叫 CST,就在网上去查怎么设置,结果徒劳半天也没有找到。后来上开发机检查开发机时区配置,发现是 Asia/Shanghai。将测试服务器设置为该时区,数据库内部查询时区,显示和服务器一直。 调试代码中,发现 MySQL 连接驱动的代码中,有配置时区的相关代码,如下: com.mysql.cj.protocol.a.NativeProtocol#configureTimezone /** * Configures the client's timezone if required. * * @throws CJException * if the timezone the server is configured to use can't be * mapped to a Java timezone.
Raft 论文摘要(二)

Raft 论文摘要(二)

D瓜哥
在上一篇文章中,通过阅读 《In Search of an Understandable Consensus Algorithm》 前三节的内容,对论文的大致内容做了简介,简单说明了一下 Replicated state machines 的用途以及 Paxos 本身存在的问题。 4. Designing for understandability several goals in designing Raft: it must providea complete and practical foundation for system building; it must be safe under all conditions and available under typical operating conditions; it must be efficient for common operations. Our most important goal — and most difficult challenge — was understandability. 从这里可以看出,Raft 设计的初衷就是为了易于理解和便于构建。 There were numerous points in the design of Raft where we had to choose among alternative approaches.
Raft 论文摘要(一)

Raft 论文摘要(一)

D瓜哥
前一段时间,在一次开组会的时候,给小组成员简单介绍了一下 Raft 协议。大概四年前读过 Raft 的论文,这次分享的时候,好多好多细节都忘了。所以,再次把 《In Search of an Understandable Consensus Algorithm》 这篇论文找出来,重读一遍,做个笔记和摘要,方便后续学习和复习。 Abstract Raft is a consensus algorithm for managing a replicated log. 开篇摘要就点出了 Raft 的特点: Raft 是一种管理复制日志的共识算法。 In order to enhance understandability, Raft separates the key elements of consensus, such as leader election, log replication, and safety, and it enforcesa stronger degree of coherency to reduce the number of states that must be considered. 为了增强可理解性,Raft 将共识分解成几个关键元素,例如 Leader 选举,日志复制,以及安全性等;同时,为了降低需要考虑的状态的数量,还强制实施了更强的一致性。
从 Spring PR 中学习代码技巧

从 Spring PR 中学习代码技巧

D瓜哥
D瓜哥经常关注 Spring 的 PR 与 Issue。在众多 Contributor 中,除了 Spring 团队成员之外,我对 stsypanov (Сергей Цыпанов) 印象很深刻。这哥们给 Spring 提了非常多的 PR,请看列表 Pull requests · spring-projects/spring-framework,而且这个哥们的 PR 都非常有特点,绝大部分是性能提升方面的 PR,而且还会给出 JMH 的测试结果。不愧是毛熊人,做事细致严谨。 这周心血来潮,把这哥们的 PR 翻一翻,希望可以学习一些编码技巧。简单记录一下,以备以后回顾学习。 提高 Map 的遍历性能 请看: SPR-17074 Replace iteration over Map::keySet with Map::entrySet by stsypanov · Pull Request #1891 摘取一个示例如下: // --before update------------------------------------------------------ for (String attributeName : attributes.keySet()) { Object value = attributes.get(attributeName); // --after update------------------------------------------------------- for (Map.Entry<String, Object> attributeEntry : attributes.entrySet()) { String attributeName = attributeEntry.
在七夕“摘”情诗

在七夕“摘”情诗

D瓜哥
今天七夕情人节,选摘几首情诗做个纪念。 邶风 · 静女 静女其姝,俟我于城隅。爱而不见,搔首踟蹰。 静女其娈,贻我彤管。彤管有炜,说怿女美。 自牧归荑,洵美且异。匪女之为美,美人之贻。 郑风 · 子衿 青青子衿,悠悠我心。纵我不往,子宁不嗣音? 青青子佩,悠悠我思。纵我不往,子宁不来? 挑兮达兮,在城阙兮。一日不见,如三月兮! 舒婷 · 致橡树 我如果爱你—— 绝不像攀援的凌霄花, 借你的高枝炫耀自己; 我如果爱你—— 绝不学痴情的鸟儿, 为绿荫重复单调的歌曲; 也不止像泉源, 常年送来清凉的慰藉; 也不止像险峰, 增加你的高度,衬托你的威仪。 甚至日光。 甚至春雨。 不,这些都还不够! 我必须是你近旁的一株木棉, 作为树的形像和你站在一起。 根,紧握在地下, 叶,相触在云里。 每一阵风过, 我们都互相致意, 但没有人, 听懂我们的言语。 你有你的铜枝铁干, 像刀,像剑, 也像戟; 我有我红硕的花朵, 像沉重的叹息, 又像英勇的火炬。 我们分担寒潮、风雷、霹雳; 我们共享雾霭、流岚、虹霓。 仿佛永远分离, 却又终身相依。 这才是伟大的爱情, 坚贞就在这里: 爱—— 不仅爱你伟岸的身躯, 也爱你坚持的位置,足下的土地。 在 告别 2019,迎接 2020 中已经展示过这张照片了。但是,没有多做说明。这里就简要介绍一下。 2019 年端午自驾游时,在内蒙古的一座山上,无意间看到了上面照片中的这两棵树,形象神似《致橡树》中“站在一起的两棵树”。所以,就专门拍下了这张照片留作纪念。 席慕蓉 · 一棵开花的树 如何让你遇见我 在我最美丽的时刻为这 我已在佛前求了五百年 求它让我们结一段尘缘 佛于是把我化作一棵树 长在你必经的路旁 阳光下慎重地开满了花 朵朵都是我前世的盼望