在去年世界读书日时,D瓜哥在 在世界读书日,推荐书单 中推荐了 《事实》 这本书。这周五,上班路上在地铁上把这本书看完了。受益匪浅,获益良多。做个笔记,摘录学习一下。
整本书主要分享了下面这十条事实的经验法则:
从这本书中,让D瓜哥感受最大的是:现在,不止中国,全世界范围内,所有人的生活都在整体地变好。这不仅仅是一种感觉,而是有很多相关国际机构的统计数据做支撑的。以前也有这种感觉,但那只是一种猜测,一种从自身生活感觉上的推断。虽然,新闻媒体中,全球各地各种灾难、冲突,甚至战争不断,但那些都是小范围内的小概率事件。为全世界人民,尤其是中国人民的生活提高,感到深深的自豪。
除了自豪以外,在做读书笔记时,还有一点趣闻,值得分享一二。这本书D瓜哥看的是纸版书。下文中的摘录也都是随手在书上划线出来的。但是,D瓜哥却可以利用一下午的时间,快速整理出来。之所以这么快速,完全得益于微信的“文字识别”功能:拍照,通过微信发送,然后在微信中打开图片,就会“文字识别”功能。这样就可以快速提取文字,整理出读书摘要。使用过程中,D瓜哥也发现,识别率依赖于图片和文字的清洗程度,偶尔也有识别出错的地方。
当然,这种方法也并非D瓜哥首创,而是在坐地铁上班时,看到一个人用同样的方法做笔记,原以为效率不高,试了一下竟然效率还挺高。感兴趣的小伙伴,不妨试试。
这本书与 《清醒思考的艺术》 有一种异曲同工之妙。《事实》侧重数据分析,从上往下从世界上更广阔的现象去分析人本身的一些偏见或错觉;而《清醒思考的艺术》则是侧重自我反思,从下往上从自身去透视普罗大众的一些思维偏误。两本书一起阅读,相信会相得益彰,妙趣横生的。
D瓜哥把读书笔记整理一下。按照章节,分二篇来分享:
《事实》之读书笔记(一)
《事实》之读书笔记(二)
我们面临的真正挑战是找到深层次的模型,这个模型不但能够捕捉到领域专家的微妙的关注点,还可驱动切实可行的设计。我们的最终目的是开发出能够捕捉到领域深层含义的模型。
要想成功地开发出实用的模型,需要注意以下 3 点:
复杂巧妙的领域模型是可以实现的,也是值得我们去花费力气实现的。
这样的模型离开不断的重构是很难开发出来的,重构需要领域专家和热爱学习领域知识的开发人员密切参与进来。
要实现并有效地运用模型,需要精通设计技巧。
重构就是在不改变软件功能的前提下重新设计它。
自动化的单元测试套件能够保证对代码进行相对安全的试验。
设计模式重构 — 为实现更深层模型而进行的重构。
代码细节重构
简称为“领域模型重构”。 学习以更高维度去看待问题。
《重构》一书中所列出的重构分类涵盖了大部分常用的代码细节重构。这些重构主要是为了解决一些可以从代码中观察到的问题。
领域模型会随着新认识的出现而不断变化,由于其变化如此多样,以至于根本无法整理出一个完整的目录。
建模和设计都需要你发挥创造力。
对象分析的传统方法是先在需求文档中确定名词和动词,并将其作为系统的初始对象和方法。
事实上,初始模型通常都是基于对领域的浅显认知而构建的,既不够成熟也不够深入。
不写,就无法思考。
— 卢曼 1992,53 最近把 《卡片笔记写作法》 读完了,深受启发,相见恨晚。
先分享一个小趣闻:看完这本书,想实践一下,就去购物网站搜合适的活页卡片。考虑到便利性,就选择了 A6 大小的活页。上网找了一圈,也没有找到标准尺寸的 A6 活页。考虑以后直接拿 A4 纸进行裁剪。现在的问题变成了如何把 A4 纸裁剪得标准一些。
看完全书,纵观卡曼的发展过程,特别叹服的一点是,他会不断反思自己的行为和学习方法,并且反复尝试改进自己的学习方法,以求达到最好的效率。反思自己,虽然总是耕读不断,虽然过程中也许捡了不少好砖,但是就像那个捡玉米的猴子,随捡随丢,终究没能垒起我的阅读城堡!可惜可惜!
闲言少叙,书归正传。读这本书,有几点印象特别深刻:
书中将记忆区分为两种机智:存储强度(storage strength)与提取强度(retrieval strength)。并且“存储与提取负相关”,也就是说,存入记忆越容易,提取出来越困难;反之,如果你有些吃力地存入,知识提取会更方便。这点有点意思。
书中一个比喻特别形象:卢曼卡片盒就像是复利投资,而特罗洛普的技术就像是储蓄罐。复利投资可以滚雪球,越滚越大,而且是指数增长。
书中还有一个概念很有意思:“思维网格”,如果知识既不是被孤立地保存,也不是被孤立地学习,而是聚集在一个思想网络中,或者说是“思维模型的网格”中,那么理解新的信息就变得更容易了。
卡片笔记学习法自然而然产生的自下而上写作法拥有一个巨大优势:我们所使用的想法都嵌入了丰富的上下文中,并且附带了可以使用的素材,而不是凭空产生的。这样做会带来另一个意想不到的收获,那就是我们会对新的想法持更加开放的态度。可以轻松避免由于预设结论导致的认知偏误。
卡片盒笔记的精华所在:以新的和意想不到的方式,将不同的想法汇集在一起,从而产生新的想法。卢曼的卡片不是简简单单地摘抄,而是自己组织语言的转述,需要加工再输出。不仅仅是摘录原文,更是思想的录像机与连接器,记录下当下的思想,建立与已有思想的链接。
一个巨大的误解是:如果不制订计划,就只能是漫无目的地乱写一气。其实我们真正该做的是构建适合自己的工作流程,让洞见和新想法成为推动我们前进的驱动力。
记笔记也不是最关键的工作,思考、阅读、理解和提出想法才是,笔记只是它们的具体成果。写,无疑是我们思考、阅读、学习、理解和产生想法的最佳催化剂。
不写,就无法思考。
— 卢曼 1992,53 最近把 《卡片笔记写作法》 读完了,深受启发,相见恨晚。
先分享一个小趣闻:看完这本书,想实践一下,就去购物网站搜合适的活页卡片。考虑到便利性,就选择了 A6 大小的活页。上网找了一圈,也没有找到标准尺寸的 A6 活页。考虑以后直接拿 A4 纸进行裁剪。现在的问题变成了如何把 A4 纸裁剪得标准一些。
看完全书,纵观卡曼的发展过程,特别叹服的一点是,他会不断反思自己的行为和学习方法,并且反复尝试改进自己的学习方法,以求达到最好的效率。反思自己,虽然总是耕读不断,虽然过程中也许捡了不少好砖,但是就像那个捡玉米的猴子,随捡随丢,终究没能垒起我的阅读城堡!可惜可惜!
闲言少叙,书归正传。读这本书,有几点印象特别深刻:
书中将记忆区分为两种机智:存储强度(storage strength)与提取强度(retrieval strength)。并且“存储与提取负相关”,也就是说,存入记忆越容易,提取出来越困难;反之,如果你有些吃力地存入,知识提取会更方便。这点有点意思。
书中一个比喻特别形象:卢曼卡片盒就像是复利投资,而特罗洛普的技术就像是储蓄罐。复利投资可以滚雪球,越滚越大,而且是指数增长。
书中还有一个概念很有意思:“思维网格”,如果知识既不是被孤立地保存,也不是被孤立地学习,而是聚集在一个思想网络中,或者说是“思维模型的网格”中,那么理解新的信息就变得更容易了。
卡片笔记学习法自然而然产生的自下而上写作法拥有一个巨大优势:我们所使用的想法都嵌入了丰富的上下文中,并且附带了可以使用的素材,而不是凭空产生的。这样做会带来另一个意想不到的收获,那就是我们会对新的想法持更加开放的态度。可以轻松避免由于预设结论导致的认知偏误。
卡片盒笔记的精华所在:以新的和意想不到的方式,将不同的想法汇集在一起,从而产生新的想法。卢曼的卡片不是简简单单地摘抄,而是自己组织语言的转述,需要加工再输出。不仅仅是摘录原文,更是思想的录像机与连接器,记录下当下的思想,建立与已有思想的链接。
一个巨大的误解是:如果不制订计划,就只能是漫无目的地乱写一气。其实我们真正该做的是构建适合自己的工作流程,让洞见和新想法成为推动我们前进的驱动力。
记笔记也不是最关键的工作,思考、阅读、理解和提出想法才是,笔记只是它们的具体成果。写,无疑是我们思考、阅读、学习、理解和产生想法的最佳催化剂。
不写,就无法思考。
— 卢曼 1992,53 最近把 《卡片笔记写作法》 读完了,深受启发,相见恨晚。
先分享一个小趣闻:看完这本书,想实践一下,就去购物网站搜合适的活页卡片。考虑到便利性,就选择了 A6 大小的活页。上网找了一圈,也没有找到标准尺寸的 A6 活页。考虑以后直接拿 A4 纸进行裁剪。现在的问题变成了如何把 A4 纸裁剪得标准一些。
看完全书,纵观卡曼的发展过程,特别叹服的一点是,他会不断反思自己的行为和学习方法,并且反复尝试改进自己的学习方法,以求达到最好的效率。反思自己,虽然总是耕读不断,虽然过程中也许捡了不少好砖,但是就像那个捡玉米的猴子,随捡随丢,终究没能垒起我的阅读城堡!可惜可惜!
闲言少叙,书归正传。读这本书,有几点印象特别深刻:
书中将记忆区分为两种机智:存储强度(storage strength)与提取强度(retrieval strength)。并且“存储与提取负相关”,也就是说,存入记忆越容易,提取出来越困难;反之,如果你有些吃力地存入,知识提取会更方便。这点有点意思。
书中一个比喻特别形象:卢曼卡片盒就像是复利投资,而特罗洛普的技术就像是储蓄罐。复利投资可以滚雪球,越滚越大,而且是指数增长。
书中还有一个概念很有意思:“思维网格”,如果知识既不是被孤立地保存,也不是被孤立地学习,而是聚集在一个思想网络中,或者说是“思维模型的网格”中,那么理解新的信息就变得更容易了。
卡片笔记学习法自然而然产生的自下而上写作法拥有一个巨大优势:我们所使用的想法都嵌入了丰富的上下文中,并且附带了可以使用的素材,而不是凭空产生的。这样做会带来另一个意想不到的收获,那就是我们会对新的想法持更加开放的态度。可以轻松避免由于预设结论导致的认知偏误。
卡片盒笔记的精华所在:以新的和意想不到的方式,将不同的想法汇集在一起,从而产生新的想法。卢曼的卡片不是简简单单地摘抄,而是自己组织语言的转述,需要加工再输出。不仅仅是摘录原文,更是思想的录像机与连接器,记录下当下的思想,建立与已有思想的链接。
一个巨大的误解是:如果不制订计划,就只能是漫无目的地乱写一气。其实我们真正该做的是构建适合自己的工作流程,让洞见和新想法成为推动我们前进的驱动力。
记笔记也不是最关键的工作,思考、阅读、理解和提出想法才是,笔记只是它们的具体成果。写,无疑是我们思考、阅读、学习、理解和产生想法的最佳催化剂。
加入公司以来,参与了很多个项目的开发维护;也排查处理过很多线上问题;为了写 Mock 测试,也专门去日志系统上扒拉过不少日志等等。在整个过程中,对日志的认识有了不少更深刻的认识和体会。也发现不少问题。这里先从存在的问题展开论述。
日志存在的问题 从个人的眼光上来看,当前的系统存在如下问题:
必要日志没有打印出来,导致在追踪问题或测试代码时,带来不必要的麻烦。比如查看一个接口的返回值用于 Mock 测试;再比如 RPC 调用报错,返回值以及错误信息没有打印到日志中,不知道具体错误原因是什么。
日志抽取中日志路径配置错误,导致日志重复收集,带来不必要的处理和存储成本。
日志代码不规范,导致不必要的性能消耗;或者大促时,日志降级不生效。
日志框架繁多,造成造成冲突,遗漏部分日志。
日志配置不规范,不利于日志的采集和清洗。
日志和调用链路物理隔离,查看一个请求的整个调用链路上的日志非常不方便,不利于问题的快速排查和定位。
大家的系统中,存在什么样的日志问题?欢迎留言交流讨论。
针对这些问题,我觉得有些地方值得发力一下。然后,做了一些探索,总结一下,以备后续使用。
日志最佳实践探索 对于日志的使用,相信所有的开发人员都比较清楚,网上也有大量资料,相关日志框架的官方文档,也写的非常详尽,这里就不再赘述。
本文从一个角度对日志规范进行探究:在排查问题时,能否通过日志来尽快地了解系统运行状态,定位问题原因?另外,由于 Java 的日志框架特别多,有一些比较容易迷惑的问题,尝试做出一点总结。
遵循“职责驱动设计”的原则,
“契约式设计”思想。
开发一个好的领域模型是一门艺术。
图 1. 模型驱动设计语言 第 4 章 分离领域 模式:Layered Architecture 在面向对象的程序中,常常会在业务对象中直接写入用户界面、数据库访问等支持代码。而一些业务逻辑则会被嵌入到用户界面组件和数据库脚本中。这么做是为了以最简单的方式在短期内完成开发工作。
如果与领域有关的代码分散在大量的其他代码之中,那么查看和分析领域代码就会变得异常困难。对用户界面的简单修改实际上很可能会改变业务逻辑,而要想调整业务规则也很可能需要对用户界面代码、数据库操作代码或者其他的程序元素进行仔细的筛查。这样就不太可能实现一致的、模型驱动的对象了,同时也会给自动化测试带来困难。考虑到程序中各个活动所涉及的大量逻辑和技术,程序本身必须简单明了,否则就会让人无法理解。
要想创建出能够处理复杂任务的程序,需要做到关注点分离——使设计中的每个部分都得到单独的关注。
Layered Architecture 的基本原则是层中的任何元素都仅依赖于本层的其他元素或其下层的元素。
图 2. 应用分层
这周需要处理一个日志文件,有一次体会到 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
序 控制复杂性的关键是有一个好的领域模型,这个模型不应该仅仅停留在领域的表面,而是要透过表象抓住领域的实质结构,从而为软件开发人员提供他们所需的支持。
在领域建模过程中不应将概念与实现割裂开来。
概念与实现密不可分的最主要原因在于,领域模型的最大价值是它提供了一种通用语言,这种语言是将领域专家和技术人员联系在一起的纽带。
领域模型并不是按照“先建模,后实现”这个次序来工作的。
真正强大的领域模型是随着时间演进的,即使是最有经验的建模人员也往往发现他们是在系统的初始版本完成之后才有了最好的想法。
既品尝过成功的美酒,也体验过失败的沮丧。
前言 真正决定软件复杂性的是设计方法。
很多应用程序最主要的复杂性并不在技术上,而是来自领域本身、用户的活动或业务。
领域驱动设计是一种思维方式,也是一组优先任务,它旨在加速那些必须处理复杂领域的软件项目的开发。
领域驱动设计的实质就是消化吸收大量知识,最后产生一个反映深层次领域知识并聚焦于关键概念的模型。
极端的简约主义是解救那些过度追求设计的执迷者的良方。
实际上, XP最适合那些对设计的感觉很敏锐的开发人员。 XP过程假定人们可以通过重构来改进设计,而且可以经常、快速地完成重构。
首先需要深入研究模型,然后基于最初的(可能是不成熟的)模型实现一个初始设计,再反复改进这个设计。每次团队对领域有了新的理解之后,都需要对模型进行改进,使模型反映出更丰富的知识,而且必须对代码进行重构,以便反映出更深刻的模型,并使应用程序可以充分利用模型的潜力。 第一部分 运用领域模型
模型是一种简化。它是对现实的解释——把与解决问题密切相关的方面抽象出来,而忽略无关的细节。
在一个项目开量验证过程中,发现 createDate 字段不正确,比正确时间晚了十四个小时。调研发现,这是一个非常典型的问题。现在把定位问题的思路和解决办法给大家做个分享。
首先,检查数据库配置,查询线上生产环境配置,结果如下:
图 1. MySQL 变量 同时,检查线上生产环境 MySQL 版本,为问题复现做准备:
图 2. MySQL 版本 从数据库配置上来说,基本正常,没有发现什么问题。(持续运行了这么长时间,有问题应该早就发现了。)
其次,检查数据库连接配置,正式环境的链接配置如下:
jdbc:mysql://<host>:3306/<schema>?createDatabaseIfNotExist=true &characterEncoding=utf-8&useUnicode=true&connectTimeout=2000 &socketTimeout=2000&autoReconnect=true