导图社区 《程序员的底层思维》
《程序员的底层思维》是一本涵盖程序员应知应会的16种思维能力的书籍。它分为三个部分,介绍了基础思维能力和专业思维能力,可以帮助程序员培养底层意识和编程逻辑思维,更好地理解计算机系统和掌握编程语言的本质。这本书适合几乎所有IT从业者阅读,内容零门槛,具有启发性。
编辑于2023-11-18 17:44:19这本书主要讲述的是,作为一名软件工程师,在掌握如何编写代码之外,还需要掌握学校没有教授的技能。它解释了构建、测试和运行生产软件的现代实践,以及加强团队合作和有效沟通的行为和方法。书中还给出了一些建议,例如如何获得帮助、如何撰写设计文档、如何维护旧代码、如何处理待命工作、如何规划工作等。此外,书中还介绍了敏捷计划、与管理者合作以及职业生涯规划等软技能。总的来说,这本书旨在帮助读者成为一名专业的软件工程师,并提供了一些实用的经验和知识。
《程序员的底层思维》是一本涵盖程序员应知应会的16种思维能力的书籍。它分为三个部分,介绍了基础思维能力和专业思维能力,可以帮助程序员培养底层意识和编程逻辑思维,更好地理解计算机系统和掌握编程语言的本质。这本书适合几乎所有IT从业者阅读,内容零门槛,具有启发性。
后端架构师学习大纲的思维导图,内容有网络协议、 数据库、缓存、消息队列、微服务、高可用、安全、监控与运维、设计模式、 算法与数据结构、编程语言...
社区模板帮助中心,点此进入>>
这本书主要讲述的是,作为一名软件工程师,在掌握如何编写代码之外,还需要掌握学校没有教授的技能。它解释了构建、测试和运行生产软件的现代实践,以及加强团队合作和有效沟通的行为和方法。书中还给出了一些建议,例如如何获得帮助、如何撰写设计文档、如何维护旧代码、如何处理待命工作、如何规划工作等。此外,书中还介绍了敏捷计划、与管理者合作以及职业生涯规划等软技能。总的来说,这本书旨在帮助读者成为一名专业的软件工程师,并提供了一些实用的经验和知识。
《程序员的底层思维》是一本涵盖程序员应知应会的16种思维能力的书籍。它分为三个部分,介绍了基础思维能力和专业思维能力,可以帮助程序员培养底层意识和编程逻辑思维,更好地理解计算机系统和掌握编程语言的本质。这本书适合几乎所有IT从业者阅读,内容零门槛,具有启发性。
后端架构师学习大纲的思维导图,内容有网络协议、 数据库、缓存、消息队列、微服务、高可用、安全、监控与运维、设计模式、 算法与数据结构、编程语言...
程序员的底层思维
1. 基础思维能力
1.1. 抽象思维
若想捉大鱼,就得潜入深渊。深渊里的鱼更有力,也更纯净。硕大而抽象,且非常美丽。——大卫·林奇
抽象=抽离+具象
图1-1 具象牛与抽象牛
抽象是哲学思维的基础
柏拉图的洞穴之喻(Allegory of the Cave)
软件设计中的抽象
面向对象的核心是抽象
面向对象(Object Oriented, OO)技术实际上由3个部分组成,分别是面向对象分析(Object Oriented Analysis, OOA)、面向对象设计(Object Oriented Design, OOD)和面向对象编程(Object Oriented Programming, OOP)。
OOA、OOD和OOP之间的关系是,OOA的结果可以帮助我们设计OOD的模型,而OOD的结果可以作为蓝图,最终利用OOP方法实现一个系统。
抽象设计的评判标准
怎样才能知道某个类的抽象设计是否良好呢?我们可以通过它的耦合性、内聚性、充分性和完整性4个指标来度量。
抽象缺失之基础类型偏执
抽象缺失之重复代码
提取重复代码只是重构工作的第一步。对重复代码进行概念抽象,寻找有意义的命名才是我们工作的重点。
抽象设计要完整
一些常见的互补方法对
不要为了抽象而抽象
抽象的层次性
对抽象层次的权衡
牛的抽象层次
抽象的3个特点
(1)抽象是忽略细节的。抽象类是最抽象的,忽略的细节也最多,就像抽象牛,只是几根线条而已。在代码中,这种抽象既可以是抽象类,也可以是接口(Interface)。
(2)抽象代表了共同性质。类代表了一组实例的共同性质,抽象类代表了一组类的共同性质。对于上面的案例来说,共同性质就是抽象牛的那几根线条。
(3)抽象具有层次性。抽象层次越高,其内涵越小、外延越大,也就是说它的含义越小、泛化能力越强。比如,牛就要比水牛的抽象层次更高,因为它可以表达所有的牛,水牛只是牛的一个种类。
抽象的层次性主要体现在概念的内涵和外延上,而这种层次性基本可以体现在任何事物上。比如一份报纸就存在多个层次上的抽象,“出版物”最抽象,其内涵最小,但外延最大,因为“出版物”不仅可以包含报纸,还可以包含书籍、期刊、杂志等。报纸的抽象层次如下。• 第一层:一个出版物。 • 第二层:一份报纸。 • 第三层:《旧金山纪事报》。 • 第四层:5月18日的《旧金山纪事报》。
对于程序员来说,对抽象层次的权衡是对我们设计能力的考验,要根据业务的需要,选择合理的抽象层次,既不能太高,也不能太低。
苹果的抽象层次
越抽象、越通用、可扩展性越强,其语义的表达能力就越弱;越具体、越不好延展,其语义表达能力却越强。所以,对于抽象层次的权衡是我们系统设计的关键所在,也是区分普通程序员和优秀程序员的重要参考指标。
软件中的分层抽象
举例
网络协议的分层抽象
编程语言的分层抽象
强制类型转换中的抽象层次问题
Liskov Substitution Principle(里氏替换原则)
抽象层次一致性原则
抽象层次一致性原则(Single Level of Abstration Principle, SLAP)
锻炼抽象思维能力
1.多阅读
2.勤总结
记录也是很好的总结习惯。就拿读书笔记来说,最好不要原文摘录书中的内容,而是要用自己的话总结和归纳书中的内容,这样不仅可以让我们加深理解,还可以提升抽象思维能力。
3.命名训练
4.领域建模训练
1.2. 逻辑思维
逻辑就是关系
逻辑思维基本包含3个方面的要素
(1)概念:概念是思维的基本单位。
(2)判断(proposition,在逻辑学中也叫命题):通过概念对事物是否具有某种属性进行肯定或否定的回答,就是判断。
(3)推理(argument,在逻辑学中也叫论证):由一个或几个判断推出另一判断的思维形式,就是推理。
逻辑三要素之概念
概念要明确且清晰
制定团队通用语言
管理者的概念技能
罗伯特卡茨模型,其中提出管理者必须具备3种必要的技能,分别是技术技能(Technical Skill)、人际关系技能(Human Skill)和概念技能(Conceptual Skill)
逻辑三要素之判断
判断是概念的展开,没有判断,就不能揭示和说明概念。同时,判断也是推理的前提,是正确运用各种推理的必要条件。
判断的两个重要特征
(1)判断有肯定或者否定之分,即有肯定判断和否定判断。
(2)判断有真假之分,一个判断要么真、要么假,不能非真非假。
逻辑三要素之推理
逻辑推理可以分为演绎推理(Deductive Inference)、归纳推理(Inductive Inference)和溯因推理(Abductive Inference)
演绎推理:因为,因为,所以
演绎推理是一个从一般到特殊的过程。我们通常说的“大前提、小前提、结论”的三段论形式就是典型的演绎推理。
例如,“所有人都会死,苏格拉底是一个人,因此苏格拉底会死”。大前提是“所有人都会死”,小前提是“苏格拉底是一个人”,结论是“苏格拉底会死”。这是一种必然性推理(保真推理),因为其结论就包含在前提之中,“所有人会死”本身就包含“苏格拉底会死”。
古典逻辑和符号逻辑都是研究演绎推理的形式(form),所以也被称为形式逻辑。
归纳推理:从特殊到一般
归纳推理是以一类事物中的若干个别对象的具体知识为前提,得出有关该类事物的普遍性知识的结论的过程。
猫A喜欢吃鱼 猫B喜欢吃鱼 猫C喜欢吃鱼 猫D喜欢吃鱼 因此,猫喜欢吃鱼
实际上,归纳和演绎并不是割裂的,而是彼此联系的,主要有以下两个原因
这一点在软件工程的建模工作中得到了充分的体现,建模是一个归纳工作,我们通过抽象问题域里具有共同特性的类来建立模型。为了验证模型的有效性,我们会使用演绎的方法去推演不同的业务场景,看看模型是否能满足业务的需要。这样的工作往往不是一次成型的,而是交替往复,最终才能得到一个相对合理的模型。
(1)为了提高归纳推理的可靠程度,需要运用已有的理论知识对归纳推理的个别性前提进行分析,把握其中的因果性、必然性,这就要用到演绎推理。
(2)归纳推理依靠演绎推理来验证自己的结论。同样,演绎推理要以一般性知识为前提,这通常要依赖归纳推理来提供一般性知识。
溯因推理:大胆假设,小心求证
溯因推理就是我先知道了答案,再去追溯原因的推理。
对于程序员来说,基本每天都在运用这种溯因推理。我们通常说的故障排查(Trouble Shooting)就是溯因推理,用的手段基本上也是假设和求证。
逻辑链
5Why思考法
5Why思考法,是指对一个问题连续多次追问为什么,直到找出问题的根本原因。
5So思考法
5So思考法,是指对一个现象连续追问其产生的结果,以探求它对未来可能造成的深远影响
如果说5Why是在“因”的方向上进行拓展,回溯问题的根本原因,那么5So就是在“果”的链路上进行拓展,旨在洞悉事物未来的发展趋势。
逻辑谬误
所谓谬误(Fallacy),就是推理中的欺骗手段。
这些谬误包括偷换概念、错误假设、以偏概全、转移话题、人身攻击、以势压人、以众压人、循环论证、不适当地诉诸权威、不适当地诉诸情感、窃取论题、得寸进尺,等等。
非理性思考
逻辑思维需要理性的思考,但是人类并不是纯粹理性的动物,因为有时纯粹理性是无法做决策的。就像“布里丹之驴”这个故事:一只完全理性的驴恰处于两堆等量等质的干草中间,将会饿死,因为它不能对究竟该吃哪一堆干草做出任何理性的决定。
1.3. 结构化思维
金字塔原理是思考、表达和解决问题的逻辑。——芭芭拉·明托
结构与架构
架构的核心也是结构。所谓架构,就是“要素+结构”。
从无序到有序
所谓结构化思维,就是从无序到有序的一种思考过程,将搜集到的信息、数据、知识等素材按照一定的逻辑进行分析和整理,呈现出有序的结构,继而化繁为简。有结构的信息更易于大脑记忆和理解。
金字塔结构
采购清单
结构化的采购清单
这种结构化的表达明显更清晰、更易于记忆。转变的关键就在于结构,金字塔结构满足了我们大脑处理信息的两个要求。
(1)寻找逻辑关系。
在上面的结构中,我们首先对需要采购的物品进行了归类分组,这里的逻辑关系是葡萄、苹果、橘子是一类的,都属于水果;牛奶、鸡蛋、咸鸭蛋是一类的,都属于蛋奶。这种分类是为我们接下来抽象概念做准备,并且是符合逻辑认知的。
(2)概念不能多。
找出逻辑关系并分组归类只是结构化的第一步,接下来我们要对分组进行抽象概括,提升一个抽象层次,将原来大脑需要处理的6个概念(葡萄、苹果、橘子、牛奶、鸡蛋、咸鸭蛋)减少为2个概念(水果、蛋奶)。处于较高层次上的思想总是能提示其下面一个层次的思想,因而也更容易被记住。
金字塔中的逻辑
金字塔结构的基本原则
纵向逻辑关系
演绎逻辑
归纳逻辑
横向逻辑关系
(1)时间顺序:例如解决问题的3个步骤。
运营活动的时间顺序
(2)空间顺序:例如组成某公司的3个部门、化整为零(将整体分解为部分)等。
(1)MECE原则
(2)满足MECE原则的划分方法
(3)程度顺序:例如某公司存在的最严重的3个问题。
如何搭建结构
一是自上而下地搭建金字塔结构,即问题分解,也叫作疑问回答分解;二是自下而上地搭建金字塔结构,即概括总结做聚合。
自上而下
2W1H
5W2H
自下而上
上下结合
更多结构思维框架
(1)制定市场营销策略的“4P”模型:即产品策略(Product Strategy)、价格策略(Price Strategy)、渠道策略(Place Strategy)、促销策略(Promotion Strategy)。
(2)思考组织战略的“7S”模型:即经营策略(Strategy)、组织结构(Structure)、运营系统(System)、经营风格(Style)、职员(Staff)、组织技能(Skill)和共享价值观(Shared Value)。
(3)分析竞争力的SWOT模型:SWOT分析代表分析企业优势(Strengths)、劣势(Weakness)、机会(Opportunity)和威胁(Threats)。
(4)制定目标的SMART模型:即制定目标要满足确定性(Specific)、可度量性(Measurable)、可实现性(Attainable)、相关性(Relevant)和时效性(Time-based)。
1.4. 批判性思维
为什么需要批判思维
原因
(1)信息太多,我们的辨别能力需要加强。
(2)选择变多,我们需要更加理性和谨慎地做出决策。
批判中台
中台的底层逻辑
中台的底层逻辑,用一句话解释就是通过复用提升研发效率。
业务中台为何低效
业务中台低效的根本原因在于,前台业务和业务中台的“深度单体耦合”
1.协作成本
2.认知成本
3.稳定性成本
解决中台的困境
(1)把业务能力做薄。
(2)把中台能力做强。
(3)把系统结构做简单。
批判架构师
尴尬的架构师
尴尬的架构部门
人人都是架构师
批判技术管理者
技术不作为
Manager和Leader的区别
业务不思考
雷军说过,永远不要试图用战术上的勤奋,去掩盖你战略上的懒惰。
这里给PD的意见是:请一定要深入理解并思考业务,不要退化成一个PPT设计师和业务需求的传话筒,不要只停留在写PRD、画Demo上,要用系统化的思维来规划产品并解决业务问题,从而赢得技术人员的尊重。
给TL的意见是:TL必须深入思考业务,严格把控PD提出的“客户需求”,把伪需求、无价值需求挡在门外,防止它们侵占团队原本有限的技术资源,从而让技术团队将更多的精力投入到系统优化上去。
脾气超火爆
自我批判
不要把自信建立在贬低他人的基础上,什么时候你能发自内心地欣赏你不喜欢的人,你就成长了。——玄难
1.5. 维度思维
维度究竟是什么
多维度思考
思维的维度
不做if else程序员
重用是指用面向对象的多态扩展来支持不同的业务场景差异; 重复是指用不同的代码分支来支持。
多态扩展
代码分离
矩阵分析
当复杂的业务在大脑中纠缠不清的时候,我们可以利用矩阵的形式把问题显性化,从而更好地做决策和判断,把复杂的问题变成“填空题”。
业务矩阵框架
殊途同归
设计模式中的维度思维
无处不在的矩阵分析
波士顿矩阵
订单要素分析
RFM模型
在电商领域中,有一个被反复提及和使用的用户分群模型——RFM模型。它是衡量用户对企业价值的经典度量工具,依托于用户最近消费时间(Recency, R)、消费频率(Frequency, F)、消费金额(Monetary, M)3个维度进行评估。
逻辑推理中的矩阵
相关系数矩阵
设计模式中的维度思维
我们说“组合优于继承”,原因在于组合会带来更好的灵活性和可扩展性。
组织管理中的维度思维
人员分工矩阵
组织管理矩阵
人才盘点矩阵
阿里巴巴的人才矩阵
需求管理矩阵
需求管理矩阵图
1.6. 分类思维
设计就是分类。——“微信之父”张小龙
分类是本能
分类无处不在
分类的本质
寻找共同属性
1.特有属性和共有属性
2.本质属性和非本质属性
经典分类与概念聚集分类
1.经典分类
2.概念聚集分类
多种多样的分类角度
没有“完美”分类
软件设计中的分类
对象分类
构建分类
软件构建的表示法
领域分类
社区团购的领域边界划分
组织架构中的分类
业务型组织
职能型组织
互联网产业分类
1.7. 分治思维
分治设计模式
管道模式
责任链模式
分布式系统
AKF扩展立方
x轴拆分
x轴拆分,通常叫作水平扩展,通过复制服务(也就是集群)或数据库已分散事务处理负载压力。
y轴拆分
y轴拆分,通常叫作领域拆分
y轴拆分更大的价值体现在代码库拆分及其带来的研发效率的提升上。
布鲁克斯定律[插图]:向进度落后的项目中增加人手,只会使项目更加落后。
z轴拆分
z轴拆分,通常叫作数据分片(Partitioning),是把一个大数据集分割成多个小数据集的方法。
具体到数据库层面,主要有两种扩展方案。
一种是基于领域的垂直切分,也叫竖切。
另一种是基于数据区间的水平切分,也叫横切。
xyz轴拆分对比
• x轴,通过克隆进行扩展。通过克隆或复制服务和数据,以便于扩展事务。 • y轴,通过拆分不同的东西进行扩展。通过领域拆分,将复杂系统拆分成多个小系统,由不同的技术团队“分而治之”。如果正确完成,那么可以显著降低复杂度,提升研发效率及系统的可扩展性。 • z轴,通过拆分类似的东西进行扩展。通过对数据进行分片(即对数据进行按领域“竖切”),以及依据数据属性(比如客户id)散列或取模的方式进行“竖切”,降低单个数据库承载的数量,这种方式可以实现无限扩展。
实践证明,使用xyz轴拆分方案,可以实现接近无限的业务发展需要。
分治算法
分治算法主要包含3个步骤:分、治、并
“分”是递归地将原问题分解成小问题;“治”是在解决了各个小问题之后(各个击破之后)合并小问题的解,从而得到整个问题的解;“并”是按原问题的要求,将子问题的解逐层合并,构成原问题的解。
归并排序算法
解决问题的黄金三步
• 第一步:定义问题,弄清楚我们要解决的问题究竟是什么。 • 第二步:分解问题,把一个大问题拆解成多个子问题。 • 第三步:合并问题,对拆解后的子问题,我们有必要再进行一次合并归类。
分治并”的应用
流式计算
分布式数据库
1.8. 简单思维
一旦做到了简洁,你将无所不能。——乔布斯
把一件事情搞复杂是一件简单的事,但要把一件复杂的事变简单,这是一件复杂的事。
简化是逆向做功
压缩、隐藏与赋予
减少选择
奥卡姆剃刀
奥卡姆剃刀原理,是指如无必要,勿增实体(Entities should not be multiplied unnecessarily),即“简单有效原理”。
干掉流程引擎
我的建议是,除非你的应用有极强的流程可视化和编排的诉求,比如对灵活性要求极高的SaaS低代码(low-code)平台,否则不推荐使用流程引擎等工具。
极简状态机的实现
领域专用语言的分类
极简状态机的模型设计
连贯接口设计
无状态设计
极简状态机的使用
COLA的壮士断腕
复杂的产品没人用
1.9. 成长思维
决定你成长的第一步不是你是否努力,而是你是否相信努力。
成长型思维与固定型思维
大脑的可塑性
培养成长型思维
明确努力的意义
龟兔赛跑
改变归因习惯
将失败相对化,归因于偶发的因素,而不是归因于普遍化、人格化,也是培养成长型思维的重要方法。
摆脱精神内耗
对于一件事情,如果你想不到特别有力的不去做的原因,那么就优先选择去做。
持续精进
精进的力量
保持好奇心
成长需要好奇心的牵引,要学会苦中作乐。
守住平常心
追求内心平和有一个简单技巧——正念呼吸,即每天花一些时间,把思绪都集中到呼吸上,抛开杂念,只专注呼吸,让眉头舒展开,让僵硬的肩膀放松下来……经常这样锻炼,可以让自己平静。比如,在跑完步之后,我喜欢闭上眼睛坐在那里,感受汗水,聆听心跳,享受运动带来的“成就感”;在吃柚子之前,我喜欢闻一闻柚子的清香味,感受食物的美好。 另一种锻炼方式是先停下手头在做的一切事情,先深呼吸一到两次,然后按顺序问自己:我现在看到了什么东西?听到了什么声音?嗅到了什么味道?我的手和脚触碰到了什么?感觉是什么样的?也可以闭上眼睛,依靠自己的感官走几步,在这个过程中专注于感受感官传来的信息。
慢也是快
掌握表扬的技巧
培养成长型思维,最好从娃娃抓起,为人父母的我们要注意和孩子的沟通语言。
错误夸奖方式
当孩子表现良好时,夸大他的“棒”和“聪明”,这会使他认为自己的能力只与那些定量的天赋有关。因此在表扬孩子时,不要夸孩子“你真棒”。
正确夸奖方式
(1)你很努力啊——表扬努力。当孩子给你看一件漂亮的作品时,不要被喜悦所迷惑,请记住要肯定他所付出的艰辛和努力。
(2)这很难,但你并没有放弃——表扬毅力。当孩子完成了一些有挑战性的事情,比如破围棋阵局、尝试攀岩,在他经历了数次尝试和失败后,请记住肯定他的耐心和毅力。
(3)你做事的态度很好——表扬态度。当孩子用很积极的态度去完成任务时,不要忘了抓住机会说些好话。
(4)你取得了很大的进步——表扬细节。当孩子的能力在某种程度上得到了提高,记得表扬细节,越具体越好。例如,宝宝,你现在的游泳姿势更标准了,而换气频率更均匀,与之前相比取得了很大的进步,真棒!
(5)这个方法真的很有新意——表扬创意。这是最重要、最需要注意的地方,看到孩子那些天马行空的想法,最容易让人与“聪明”联系起来,但天马行空甚至奇怪真的是“聪明”吗?它应该是创造性和思维的积累。在尝试无数的可能性之后,孩子脑洞大开,所以表扬孩子有创意就行了!
(6)你和你的伙伴合作得真棒——表扬合作精神。一个人无论多么能干,能力也是有限的。如果孩子和小伙伴一起努力完成了某件事,请一定抓住机会,肯定孩子的合作和沟通技巧。
(7)这件事你负责得很好——表扬领导能力。虽然有些事情不是完全由孩子自己做的,但他负责管理,也证明他做得很好,因为他有很强的责任感和领导能力。这一点一定要表扬,让孩子知道虽然他没有亲自参与每一步,但是实现了结果,这是一个非常重要的因素。
(8)你一点也不怕困难,太难得了——表扬勇气。表扬孩子的勇气是帮助他提高自信指数的最佳方式。
(9)我相信你,因为……——表扬信用。良好的信用会使孩子的生活更顺利,所以我们应该及时帮助他建立信用的概念。例如,当你和孩子有一个约定时,你可以说“我相信你,因为你以前说的话都兑现了”或“我相信你,你会找到一个好办法”……
(10)你尊重别人的意见,你做得很好——表扬虚心开放。从别人那里汲取好的建议和经验,也会提高自己的能力,具有成长型思维的人一般都有虚心开放的心态。
(11)我很高兴你做出了这样的选择——表扬选择。孩子能够很好地完成任务,有时是因为努力,有时是因为做出了正确的选择,表扬策略和选择也是培养成长型思维的关键。
(12)你还记得这样做,想得真棒——表扬细心。细节往往体现在一些小事上,而且体现在孩子具有综合性和多角度的思考上。当你出去玩的时候,孩子提醒你不要忘记带雨伞,或者出门前孩子会留意天气预报,这时爸爸妈妈应该表扬他细心周到。
成功人士的成长型思维
2. 专业思维能力
2.1. 解耦思维
软件设计的一大目标就是“解耦”。
耦合与解耦
在软件领域,“耦合”是指两个事物之间联系的紧密程度。联系越紧密,耦合性越高;联系越少,耦合性越低。解耦就是要减少事物之间联系的紧密程度。
在软件世界中,解耦有两种主要方式——依赖倒置解耦和中间层映射解耦。
依赖倒置解耦
依赖倒置是SOLID设计原则中的“D”,全称是Dependence Inversion Principle,即依赖倒置原则
其定义如下: (1)上层模块不应该依赖底层模块,它们都应该依赖于抽象。(High level modules should not depend upon low level modules.Both should depend upon abstractions.) (2)抽象不应该依赖于细节,细节应该依赖于抽象。(Abstractions should not depend upon details.Details should depend upon abstractions.)
依赖倒置解耦
为什么要依赖倒置呢,又有什么好处呢?
抽象比具体灵活
解决方案中立原则(Principle of Solution-Neutral Function)
所谓的解决方案中立,是指我们在思考解决方案的时候,不要一开始就陷入功能细节中,要尽量抽象一点,保留更多的可能性,为创新留下空间。
特定解决方案和非特定解决方案对比
面向接口编程
应用与日志框架的解耦
中间层映射解耦
DNS的解耦设计
CDN的解耦设计
解耦的技术演化
应用架构中的解耦
应用架构之道,就是要实现业务逻辑和技术细节的解耦。
2.2. 契约思维
人是生而自由的,但却无往不在枷锁之中。——卢梭
在软件工程中,契约思维有规范和标准两个方面的重要价值。
1)规范价值:一致性可以降低认知成本和复杂度,一个系统如果没有任何的规范约束,那么呈现出来的结果就是混乱。
(2)标准价值:大规模社会分工协作离不开标准,如果螺丝钉没有标准,那么每个企业就不得不自己生产适合自己的螺丝钉。
“一流的企业定标准,二流的企业做品牌,三流的企业卖产品”。
软件设计中的规范
规范的价值,就在于它能保证代码的一致性,而一致性在很大程度上可以降低认知成本和复杂度。
根据我的经验,我一般至少会在团队中落实命名规范、异常处理规范、架构规范。实践证明,这3个规范可以有效地帮助团队治理代码复杂度。
命名规范
每个开发团队都应该有自己的命名规范,确保命名的一致性。
异常处理规范
服务提供者的异常处理
对于业务系统而言,基本上只需要定义两类异常(Exception),一个是BizException(业务异常),另一个是SysException(系统异常),而且这两个异常都应该是Unchecked Exception。

不建议使用Checked Exception,是因为它破坏了开闭原则。
服务调用者的异常处理
在分布式环境下,一个功能往往需要多个服务的协作才能完成。在使用远程服务的过程中,难免会出现各种异常,比如网络异常、服务自身的异常等。对于那些对可用性要求非常高的场景,我们有必要制定一个服务重试、服务降级的策略,以便当其中一个服务不可用的时候,我们仍然能够对外提供服务。 对于服务重试(Retry),我们需要查看异常种类,如果是BizException,则说明是服务调用者自己的问题(缺少参数、参数不正确,或者不满足业务规则),这时不需要重试;如果是SysException或者其他的系统Error,则可以进行重试。
架构规范
我和我的团队研发了一个应用架构规范,名字叫COLA
规范的维护
所有成员会轮值负责一周的Code Review工作,当期的负责人要在周五发出一个Code Review周报,摘要一些典型问题,并在周会上供团队成员进行讨论和互相学习。
软件设计中的标准
前端标准化之路
Java规范
API设计标准
良好的API设计要至少遵循3个标准,分别是可理解性、封装性和可扩展性。
可扩展性
依赖契约的扩展机制
基于接口的扩展
基于接口的扩展主要利用面向对象的多态机制,需要先在组件中定义一个接口(或抽象方法)和处理该接口的模板,然后由用户实现自己的定制。

基于配置数据的扩展
基于配置数据的扩展,首先要约定一个数据格式,然后利用用户提供的数据组装成实例对象,用户提供的数据是对象中的属性(有时也可能是类,比如SLF4J中的StaticLoggerBinder)
掌握标准制定权
API和SPI对比
Java SPI
JDBC的驱动器(Driver)加载就使用了SPI机制
SLF4J也使用了SPI的思想,但是其实现方式和正统的SPI机制不大一样,它通过org.slf4j.impl.StaticLoggerBinder来实现SLF4J的接口和具体日志实现框架之间的连接。
2.3. 模型思维
建模的艺术就是去除实在中与问题无关的部分。——菲利普·安德森(1977年诺贝尔物理学奖得主)
在软件工程中,有两个高阶工作,一个是架构,另一个是建模
如果把写代码比喻成“搬砖”,那么架构和建模就是“设计图纸”了。相比于编码,建模的确是对设计经验和抽象能力要求更高的一种技能。
模型及其分类
简单来说,模型就是对现实的简化抽象。
根据使用场景,模型大致可以分为物理模型、数学模型、概念模型和思维模型等。
模型不能代替实物
世界上没有完美的模型,甚至连正确的模型也没有。
UML建模工具
UML建模语言
类的UML表示法
类的关联关系
1.双向关联
2.限定关联
3.单向关联
4.自关联
5.聚合关系
6.组合关系
类的依赖关系
类的泛化关系
类与接口的实现关系
领域模型
领域模型是对领域内的概念类或现实世界中对象的可视化表示,又称为概念模型、领域对象模型、分析对象模型。它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领域概念之间的关系。 领域模型将现实世界抽象为了信息世界,把现实世界中的客观对象抽象为某一种信息结构,而这种信息结构并不依赖于具体的计算机系统。领域模型不是对软件设计的描述,和技术无关。
限界上下文
任何问题都是有边界的,问题的边界也叫领域边界。也就是说,我们要对一个问题进行分析或建模,一定是在一个特定的上下文(Bounded Context,限界上下文)中讨论的,而不可能漫无边际地讨论。
限界上下文告诉我们,同一个概念不必总是对应单一的模型,也可以对应多个模型。
上下文映射
1.共享内核
2.防腐层
领域模型和数据模型
领域模型和数据模型的区别

数据模型负责数据存储,其要义是扩展性、灵活性、性能;而领域模型负责业务逻辑的实现,其要义是业务语义显性化的表达,以及充分利用面向对象的特性增强代码的业务表征能力。
错把领域模型当数据模型
错把数据模型当领域模型
两种模型各司其职
领域模型是面向领域对象的,要尽量具体,尽量语义明确,显性化地表达业务语义是其首要任务,扩展性是其次;数据模型是面向数据存储的,要尽量可扩展。
2.4. 工具化思维
懒人的逻辑中也有其合理的一面,勤劳奋斗的逻辑中也必定有其荒唐的一面。——张方宇
工具化的一般步骤
(1)3表示重复3次。
(2)2表示“现状”和“期望”二者之间的差距。
(3)1表示1个工具。
TestsContainer小工具
组合创新也是创新
ORM工具
基础设施即代码
巧用便签贴
Affinity Grouping
这样做有两个好处,一是集思广益,二是由大家共同制定目标,有助于打破部门壁垒,有利于目标的达成。
2.5. 量化思维
No measurement,no improvement.(没有量化,就无法优化。)——“科学管理之父”温斯洛·泰勒
量化的步骤
定义指标
AARRR增长漏斗模型
将指标数字化
“有数据呈现数据,没有数据呈现案例,没有案例呈现观点,如果都没有的话,就请闭嘴”
优化指标
研发效能度量
度量不是“指标游戏”
力求合理的度量
度量的设计目标是能够引导出正确的行为。度量是为目的服务的,所以好的度量设计一定对目的有正向牵引的作用。如果度量对目标的负向牵引大于正向牵引,那么这样的度量在本质上就是失败的。
平均缺陷修复时间(Mean Time To Repair)
目标管理
SMART原则
SMART原则是指在制定工作目标时必须谨记的5项要点:目标是具体的;目标是可衡量的;目标是可接受的,不可过高和过低;目标是可证明的、可实现的;目标是有完成时限的。
摩尔定律
当价格不变时,集成电路上可容纳的元器件的数目约每隔18个月便会增加一倍,处理器的性能每隔2年翻一倍。
OKR考核指标
OKR中的目标必须是有野心的。因为只有高远的目标,才能最大程度地激发人的潜能。
示例

不要迷信指标
指标是为了实现目标的,但是在实践过程中,指标却经常是与目标为敌的。管理者常常把目标拆解为指标,时间久了,他就只记得指标,而忘了其背后更重要的目标。如果目标是“林”,那么指标就是“木”,管理者一旦开始“只见树木,不见森林”,就会变得非常短视。那些不懂数据的人很糟糕,而最糟糕的是那些只看数字的人。
举例
在福特汽车的发展史上,有一段至暗时期。那些实践经验丰富但没有读过商学院的老一辈管理层被撤掉,取而代之的拥有名校管理背景的数据分析师。公司试图通过精细化的数字管理来实现业务的增长,然而这些数据分析师并不熟悉业务,只能看度量数据,越是不懂业务就越依赖度量数据来做决策,最后使整个公司陷入了泥潭。 软件研发过程也有类似的尴尬,比如为了追求更好的代码质量而制定了严格的代码测试覆盖率要求。时间一久,大家都机械性地追求这个指标,而忘记了当时设立这个指标的初衷,于是出现了高覆盖率的大量单元测试中没有断言这样尴尬的局面。
量化网站运营
前端埋点技术也是对量化思维非常好的实践
淘宝的做法是设计一个超级位置模型(Super Position Model, SPM)
量化技术贡献
(1)应用质量分:我们有一套算法为应用打分,影响应用质量的因素包括代码重复率、圈复杂度、分层合理性。如果你负责或者与他人共同负责的应用分数越高,则说明应用质量越高。
(2)技术影响力分:我们提供了一套量化标准来尝试量化你的影响力。比如,你写了一篇技术文章,如果这篇文章被浏览、收藏、点赞的次数越多,那么分数越高;你做了一次演讲分享,分享的范围越广,则分数越高。在团队内分享是3分,在部门内是8分,在QCon上分享是30分等。此外,发表论文、创新专利等都可以增加影响力分数。
(3)技术贡献分:主要从Code Review、重构、技术亮点等角度衡量。这部分有一定的主观性,比如重构的质量如何、技术亮点是否足够亮,仍然需要结合人为的主观判断。
(4)开发质量分:主要包括项目的Bug数、线上的故障数、单测覆盖率等指标,能相对比较客观地反映真实情况。
2.6. 数据思维
一切业务数据化,一切数据业务化。——阿里巴巴
“精通”数据
(1)要了解公司的数据技术体系。比如,对大数据处理框架、数据仓库、数据分析等有基本的认知,知道其背后的基本原理和运行逻辑。有了这个认知之后,我们就能更好地与数据工程师、数据分析师、商业智能分析师等人员进行分工协作。
(2)要知道用数据去说话。我们要学会用数据作为决策的依据,而不是靠猜测、“拳头”或“屁股”去做决策。
数据体系概览
一个公司的数据架构可以分为源数据、数据仓库、ETL、元数据管理和数据应用这5个部分。

数据源
数据源通常是工程师最熟悉的部分,这些数据一般存储在数据库,比如关系数据库、NoSQL中。
关系数据库,是联机事务处理(On-Line Transaction Processing, OLTP)的典型应用。其重点在于“T”,即Transaction,表示面向事务处理。比如,在银行存取一笔钱款,这就是事务交易。
数据仓库
数据库专注于OLTP,而数据仓库专注于联机分析处理(On-Line Analytical Processing, OLAP)。OLAP关注的重点是“A”,即Analytical,以分析为目的。
ETL
ETL,是Extract-Transform-Load的缩写,用来描述将数据从来源端经过数据抽取(Extract)、数据转换(Transform)、数据加载(Load)至目的端的过程。
1.数据抽取
2.数据转换
不符合要求的数据主要有不完整的数据、错误的数据、重复的数据三大类。
3.数据加载
加载过程负责将已经提取好并经过转换能保证数据质量的数据加载到目标数据仓库。加载分为首次加载(first load)和刷新加载(refresh load)。首次加载会涉及大量数据,而刷新加载属于一种微批量式的加载。
元数据
数据应用
数仓建模
Linux的创始人Linus Torvalds有一段关于“什么才是优秀程序员”的经典言论:“烂程序员关心的是代码,好程序员关心的是数据结构和它们之间的关系”
维度模型
维度模型是数据仓库领域的权威专家Ralph Kimball所倡导的,他的《数据仓库工具箱:维度建模权威指南》(The Data Warehouse Toolkit: The Complete Guide to Dimensional Modeling)是数据仓库工程领域最流行的数据仓库建模的经典图书。
事实明细表
事实汇总表
数据产品平台
看我情
看行情
看敌情
用数据说话
如果所有的产品决定都是业务方说了算,作为技术方的你只做执行,那么你在公司的角色就是资源;如果很多产品方案是你和业务方一起讨论、共创的结果,那么你们就是伙伴。
2.7. 产品思维
产品就是用来解决某个问题的东西。——苏杰《人人都是产品经理》
产品的三要素
用户
用户是产品要服务的对象,即使用产品的人。
需求
需求即产品要解决的核心问题是什么。
场景
场景即用户何时何地需要使用产品。
产品的分类
用户关系角度
从产品与用户关系的角度,可以把产品分为3类:单点、单边、多边。其中,多边又可以分为双边、三边等。
用户需求角度
从用户需求角度,可以把产品分为6类:工具、内容、社交、交易、平台、游戏。
(1)工具:解决单点问题。
(2)内容:价值观过滤器。
(3)社交:彼此相互吸引。
(4)交易:做生意卖东西。
(5)平台:复杂的综合体。
(6)游戏:打造平行世界。
用户类型角度
产品的用户多种多样,但我们最常听到是2B和2C这两类,它们分别是英文to Business与to Customer的缩写。
产品形态角度
互联网和IT行业中,常见的产品形态有手机App、网站、智能硬件等。按照技术实现的不同,可以分为两种形式:BS结构和CS结构。
产品架构
产品的核心要素是用户、需求和场景,为了实现客户价值,我们需要用产品功能去满足用户在不同场景下的需求。因此,从产品实现的视角来看,一个产品架构至少应该包含以下3个层次。
(1)用户感知层:在何种场景下通过何种方式触达用户。
(2)功能模块层:通过哪些功能模块实现产品的核心功能,以及哪些外部平台功能有信息交互。
(3)数据层:产品的数据从哪里来,产品的数据沉淀到何处去。
产品化
产品化是指把一种技术、一种服务通过标准化、规范化的流程形成可大规模复制生产和发布的能力。它主要体现的是一种能力的复用性和可移植性。一种技术或一种成果一旦产品化,就可以真正转化为生产力,并实现规模效益,通过效率最大化实现利润和回报的最大化。
需求
(1)可靠性和稳定性需求。
(2)易用性和文档。
平台化
平台也是一种产品,即平台型产品。
企业平台化
在企业IT建设中,所谓的平台化,是指抽取公共模块,解决技术复用问题。
企业的平台化建设无外乎以下两种。(1)基于快速开发目的的技术平台。(2)基于业务逻辑复用的业务平台。
平台化建设
关于企业内部平台化建设,关键在于抽象和复用。
平台产品化
作为一名架构师,我们如果需要按照产品化的思维去打造这个平台,应该怎样去做呢?
我们可以用产品的三要素(用户、需求、场景)来思考这个问题,不妨站在用户的角度,尝试问自己以下问题。 (1)平台的愿景是什么? (2)平台的用户是谁? (3)为用户解决什么问题? (4)如何验证产品价值? (5)如何保证服务质量?
1.平台愿景
2.平台用户
3.解决什么问题
4.验证产品价值
5.保证服务质量
3. 思维能力的综合应用
3.1. 我的商品团队之旅
人是能够习惯于任何环境的生物,之前你认为自己难以克服的困难,慢慢都会适应了。——维克多·弗兰克《活出生命的意义》
落地新团队的挑战
要解决新人落地的问题,也就是要解决如何从“陌生”到“熟悉人、业务、技术和文化”的问题。
结构化落地新团队后的金字塔结构
熟悉人
(1)组织结构
(2)人员分工
(3)建立关系
熟悉业务
业务主要由产品(业务功能)和业务流程组成,我们可以通过以下方式去熟悉业务。
(1)了解产品
(2)了解流程
(3)走访客户
熟悉技术
(1)系统架构
(2)领域模型
(3)代码结构
熟悉文化
(1)使命:让天下没有难做的生意。
(2)愿景:构建未来的商务生态系统,让客户相会、工作和生活在阿里巴巴,并持续发展最少102年。
(3)价值观:客户第一、团队合作、拥抱变化、诚信、激情、敬业。
深入商品领域
领域概念
1.SKU和SPU
SKU是商品领域中最核心的概念,SKU的全称是Stock Keeping Unit,表示最小库存单元。
SPU的全称是Standard Product Unit,表示标准化产品单元。SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
2.标品和非标品
所谓标品,即有明确的规格、型号的标准产品。
非标品,指不按照国家颁布的统一行业标准和规格制造的产品或设备,而是根据自己的用途需要,自行设计制造的产品或设备,其外观或性能不在国家设备产品目录内。
3.商品属性
4.商品分类
5.前台类目和后台类目
概念模型
产品架构
产品架构的3个层次分别是用户感知层、功能模块层和数据层
商品管理系统产品架构
商品上架重构
复杂的商品上架流程
无用的流程引擎
问题的本质在于结构
结构化分解后的问题
1.领域知识被割裂和肢解
2.代码的业务表达能力弱
3.代码的扩展性低
复杂业务应对之道
有结构化分解要好于没有分解,结构化分解+抽象建模要好于单纯的结构化分解。
方法论就是“上下结合,能力下沉”
上下结合
上下结合,是指通过自上而下的结构化分解+自下而上的抽象建模,螺旋式地构建应用系统。
结构化分解(上)+抽象建模(下)
能力下沉
一般来说,实践DDD有两个层次。
第一个层次是套概念
第二个层次是融会贯通
能力下沉有两个关键指标:代码的复用性和内聚性。
3.2. COLA的演进过程
COLA 1.0
复杂度来自哪里
1.随心所欲
2.面向过程
3.分层不合理
分层最大的好处就是分离关注点,让每一层只解决该层关注的问题,从而将复杂问题简单化,达到分而治之的效果。
4.扩展性差
COLA 1.0的设计
1.规范设计
2.面向对象设计
3.分层设计
4.扩展设计
COLA 1.0的整体架构
COLA 2.0
新架构分层
新组件划分
模块(Module):和Maven中Module定义保持一致,简单理解就是Jar,用长方体表示。
组件(Component):和UML中的定义类似,简单理解就是Package,用UML的组件图表示。
新扩展点设计
首先我们要明确3个新概念:业务、用例、场景。
业务(Business):就是一个自负盈亏的财务主体,比如天猫、淘宝和零售通就是3个不同的业务。
用例(Use Case):描述了用户和系统之间的互动,每个用例提供了一个或多个场景,比如支付订单就是一个典型的用例。
场景(Scenario):场景也被称为用例的实例(Instance),包括用例所有的可能情况(正常的和异常的)。比如,对于“订单支付”这个用例,就有“可以使用花呗”“支付宝余额不足”“银行账户余额不足”等多个场景。
简单来说,一个业务是由多个用例组成的,一个用例又是由多个场景组成的。
淘宝业务身份示例
新二方库定位
COLA 3.0
去掉Command
去掉Interceptor
去掉Validator等
优化类扫描
在原生的Spring中,至少有2种方式可以获取用户自定义Annotation的Bean,最简洁的方式是利用ListableBeanFactory.getBeansWithAnnotation()方法,另一种方式是使用ClassPathScanningCandidateComponentProvider进行扫包。
用Adatper代替Controller
COLA 4.0
架构的顶层设计
架构的顶层设计——技术划分和领域划分
技术维度与领域维度的划分
COLA组件
COLA 4.0的改动点
1.分层架构
2.分包架构
3.总体架构
最重要的事情就是分离了架构和框架组件,让架构更纯粹,让组件更实用
COLA 4.0 的整体架构
如何使用COLA
第一步:安装cola archetype。下载cola-archetypes的源码到本地,然后在本地运行mvn install进行安装。
第二步:安装cola components。下载cola-components的源码到本地,然后在本地运行mvn install进行安装。
第三步:创建应用。执行以下Maven命令,生成一个demoWeb应用:
第四步:运行应用。首先在demoWeb目录下运行mvn install(如果不想运行测试,可以加上-DskipTests参数),然后进入start目录,执行mvn spring-boot:run。如果运行成功,则可以看到Spring Boot启动成功的界面。
4. 引用书籍
4.1. 《卓有成效的程序员》
4.2. 《逻辑学导论》
4.3. 《如何阅读一本书》
4.4. 《思辨与立场》
4.5. 《工具论》
4.6. 《学会提问》
4.7. 《快思慢想》
4.8. 《金字塔原理》
4.9. 《设计模式解析》
4.10. 《万物简史》
4.11. 《生命的多样性》
4.12. 《面向对象分析与设计》
4.13. 《架构真经》
4.14. 《UNIX编程艺术》
4.15. 《必然》
4.16. 《简单法则:设计、技术、商务、生活的完美融合》
4.17. 《终身成长:重新定义成功的思维模式》
4.18. 《人类简史:从动物到上帝》
4.19. 《系统架构:复杂系统的产品设计与开发》
4.20. 《社会契约论》
4.21. 《面向对象分析与设计》
4.22. 《UML和模式应用》
4.23. 《数据仓库工具箱:维度建模权威指南》
4.24. 《领域驱动设计:软件核心复杂性应对之道》
4.25. 《软件架构:架构模式、特征及实践指南》