发布于 

《程序员的底层思维》

作者:张建飞,出版时间:2022-02

基础思维能力

抽象思维

若想捉大鱼,就得潜入深渊。深渊里的鱼更有力,也更纯净。硕大而抽象,且非常美丽。 ——大卫·林奇

  • 抽象思维是程序员最重要的思维能力之一,抽象的过程就是通过归纳概括、分析综合来寻找共性、提炼相关概念的过程。
  • 语言和抽象是一体的,抽象的概念只有通过语言才能表达出来,因此命名至关重要。
  • 过多地使用基础类型可能意味着抽象的缺失,需要对这些业务概念进行封装和抽象。
  • 重复代码通常意味着抽象缺失,提取重复代码只是完成了重构的第一步,关键是后续的命名。
  • 抽象具有层次性,抽象层次越高,内涵越小,外延越大,扩展性越好;反之,抽象层次越低,内涵越大,外延越小,扩展性越差,但语义表达能力越强。
  • 对抽象层次的拿捏体现了我们的设计功力,抽象层次要视具体情况而定,既不能太高,也不能太低。
  • 强制类型转换意味着抽象层次有问题,可以通过提升抽象层次来解决。
  • 抽象层次要保持一致性,即要遵循LSP,一致性可以减少混乱和降低理解成本。
    • Liskov Substitution Principle(里氏替换原则):子类应该可以替换任何父类会出现的地方,并且经过替换以后,代码还能正常工作。
  • 我们可以通过刻意练习来提升抽象能力,这些练习包括阅读、总结、命名训练、建模训练等。

逻辑思维

不合乎逻辑的观点只需一根绳索就可将它绞死。 ——比勒尔

  • 逻辑思维是最底层的思维能力,其本质是判断关系是否合理。
  • 逻辑的三要素是概念、判断和推理,只有概念清晰、判断无误、推理符合形式逻辑要求,才算逻辑正确。
  • 软件设计从理解问题域开始,而理解问题域的核心是要深入理解领域的核心概念。
  • 判断分为肯定判断和否定判断,判断要么真、要么假,不能非真非假。
  • 逻辑推理可以分为演绎推理、归纳推理和溯因推理。
    • 演绎推理:因为,因为,所以
    • 归纳推理:从特殊到一般
    • 溯因推理:大胆假设,小心求证
  • 思考的深度取决于逻辑链的深度,5Why和5So思考法是非常有用的深度思考工具。但是推导要注意逻辑的严密性,否则逻辑链很容易形成滑坡谬误。
  • 形式逻辑虽然强大但不实用,掌握常见的逻辑谬误能帮助我们更快地辨别真伪。
  • 逻辑需要理性,但感性同样重要,不要“得理不饶人”,把自己变成了“杠精”。

结构化思维

金字塔原理是思考、表达和解决问题的逻辑。 ——芭芭拉·明托

  • 结构是万物之本,小到分子,大到宇宙,只有了解其结构才能真正认识它。
  • 结构性问题是本质问题,不改变结构,再多的努力也白费。
  • 人脑记忆的特点是概念不能多,要有逻辑,金字塔结构能满足这样的特征。
  • 在金字塔结构里,纵向逻辑关系有演绎和归纳两种;横向逻辑关系有时间顺序、空间顺序和程度顺序三种。
  • 构建结构可以采用自上而下和自下而上两种方法,凡事没有绝对,更多的时候需要上下结合。
  • 针对不同的问题域,有很多现成的解决问题的框架,熟悉这些“套路”可以帮助我们快速搭建结构和解决问题。
    • 制定市场营销策略的“4P”模型
    • 组织战略的“7S”模型
    • 分析竞争力的SWOT模型
    • 制定目标的SMART模型

批判性思维

未经审视的人生不值得过。 ——苏格拉底

  • 批判要基于理性的逻辑思维,而不是耍嘴皮子。
  • 在当今信息爆炸的社会,我们需要批判精神来看待事情。
  • 业务多样性、多变性的特性决定了业务中台很难成功。
  • 代码复制也是一种复用,而且是耦合性最低的复用。
  • 架构是一种能力,而不仅仅是职位。
  • 技术管理者不能仅仅是一个管理者(Manager),也要是一个领导者(Leader)。
  • 坚持自我批判,才能持续成长。
  • 在软件领域,很多问题都要批判、辩证地来看。比如,敏捷开发就一定比瀑布式好吗?微服务就一定比单体好吗?

    “不要把自信建立在贬低他人的基础上,什么时候你能发自内心地欣赏你不喜欢的人,你就成长了。”
    寸有所长,尺有所短,要看得见别人的优(不妒忌,学会欣赏别人),用得上别人的劣(从他人错误中学习)。

维度思维

这个世界不是只有是非黑白,还有很多灰色地带。 ——白岩松

  • 维度思维的关键是理解维度,维度是问题域独立参数或变量的数量。
  • 不借助工具,大脑很难处理多维问题,矩阵分析是解决多维问题的利器。
  • 矩阵分析首先要找到影响问题域的核心要素,也可以叫变量、维度,然后显性化地构建矩阵,当维度和维度属性值比较少的时候,可以用四象限、九宫格或立方体进行视觉上的呈现。
  • 业务代码的复杂度主要取决于业务场景和业务流程的复杂度。再复杂的业务,其业务场景都是可以枚举的,关键是找到构成业务场景的核心要素。例如,商品业务的场景主要由商品类型、商品售卖方式、商品仓储方式3个要素组成。
  • 多维度思考是思考的高级形式,矩阵分析在其中是无处不在的。从商业分析的波士顿矩阵、RFM模型到逻辑推理,都能看到矩阵分析的身影。

分类思维

设计就是分类。 ——“微信之父”张小龙

  • 分类就是设计,分类对设计至关重要。
  • 人类有分类的本能,这和我们认识世界的方式有关。
  • 分类的本质是寻找共性,这些共性既可以是物理属性,也可以是概念属性。
  • 没有完美的分类,任何分类都与进行分类的观察者的视角和目的有关。
  • 分类是软件设计的基础,主要体现为对象分类、构建分类和领域分类。
  • 不同维度的分类选择造就了不同的组织,既可以按照业务划分,也可以按照职能划分。
  • 按照供给和履约的不同对互联网进行分类,可以更好地看清互联网。

分治思维

要把大象装进冰箱,拢共分几步? ——小品《钟点工》

  • 解决复杂问题要分治,计算机涉及的问题都比较复杂,需要分而治之来解决。
  • 软件中存在大量的分治思想,比如管道模式、分层架构、分布式架构等,无不体现了分治的强大。
  • “分治并”是分治的进阶,有些问题除了分治,还需要整合、合并。
  • “分治并”本质上对应的是定义问题、分析问题、解决问题的通用步骤。
  • 很多问题在解决过程中都显性或隐性地使用到了“分治并”,比如分治算法、流式计算、分布式数据库系统。

简单思维

一旦做到了简洁,你将无所不能。 ——乔布斯

  • 简单不是一个简单的目标,而是一个非常高的目标。所有的UNIX哲学浓缩为一条铁律就是KISS原则。
  • 简单不是简陋。简单是一种洞察问题本质、化繁为简的能力,简陋是对问题不加思考地简单处理,二者有本质区别。
  • 简单需要我们付出很多的精力,对问题深入思考,进行熵减逆向做功。往往需要经历简单—复杂—简单的演化过程。
  • 我们可以利用隐藏、减少选择及奥卡姆剃刀来实现简化的目的。
  • E = mc² (E能量 m质量 c光速)和 F = ma(F外力 m质量 a加速度) 证明,上帝似乎不是一个喜欢复杂的人。
  • 不管是弃用流程引擎、重新设计状态机引擎,还是COLA的迭代、产品的博弈,我总是能从化繁为简中受益。

成长型思维

  • 决定你成长的第一步不是你是否努力,而是你是否相信努力。
  • 固定型思维让信心和成功都充满脆弱性。因为相信能力是固定的,所以你需要不断证明自己的能力与价值。
  • 成长型思维认为成功是学习的结果,努力是通往成功的关键。成功个体的标志在于他们热爱学习、喜欢挑战、重视努力,并在面对苦难时坚韧不拔。
  • 研究表明,我们的大脑具有可塑性,这是成长型思维的生理基础。
  • 培养成长型思维,需要我们有一个好的心态,相信努力的意义,改变错误的归因习惯,摆脱精神内耗,相信水滴石穿,持续精进。
  • 培养成长型思维,最好从小开始,父母要更多地鼓励小孩的努力、过程、选择、策略……而不是天赋。不要做养成固定型思维的助推器。
  • 成功人士或多或少具备成长型思维,因为唯有如此,他们才能战胜磨难和逆境,没有人能随随便便成功。

专业思维能力

解耦思维

人生最难熬的痛苦,就是你跟本该远离的东西纠缠在了一起。

  • “高内聚、低耦合”是软件设计追求的重要目标之一,组件、模块、层次设计都应该遵循“高内聚、低耦合”的设计原则。
  • 正交的关键在于如何识别耦合性,我们可以通过识别系统需要扩展的地方来识别耦合性。比如,关于配置系统的设计不应该耦合于某一种特定的实现方式,而是应该更灵活一些。
  • 解耦主要有依赖倒置和中间层映射两种方式。
  • 我们要尽可能多地依赖抽象而不是具体,这能使系统更灵活,这种编程方式也叫作面向接口编程。
  • “计算机中的任何问题,都可以通过加一层来解决”,中间层的价值也在于解耦。

契约思维

人是生而自由的,但却无往不在枷锁之中。 ——卢梭

  • “写代码是自由的,但无往不在规则之下”。
  • 社会大规模分工协作离不开契约思维,编程在很大程度上是一种“制定契约”。
  • 在软件领域,契约思维主要有软件规范和软件标准两方面的重要价值。
  • 一致性可以降低复杂度,我们可以在命名、异常处理、应用架构等方面在团队内制定规范。
  • 不管是前端标准化,还是JCP(Java Community Process),都体现了规范和标准在软件中的重要作用。
  • “一流的企业定标准,二流的企业做品牌,三流的企业卖产品”,谁掌握了标准制定权,谁就掌握了主动权。从这个意义上来说,提供SPI(Service Provider Interface)要比调用他人的API更主动。

模型思维

建模的艺术就是去除实在中与问题无关的部分。 ——菲利普·安德森(1977年诺贝尔物理学奖得主)

  • 模型是对现实世界的抽象和映射。没有完美的模型,甚至连正确的模型都没有,就像类比永远不能代替问题本身一样。
  • 我们可以将模型分成物理模型、数学模型、概念模型、思维模型等。
  • UML是在软件工程中具有广泛共识的建模方法、语言和表示法,其类图也常被用来做领域建模。
  • 领域建模和技术实现无关,是问题域分析、明晰概念、获得关键实体对象的重要过程。领域模型反映了关键的业务概念,刻画了关键领域实体,以及实体之间关系。
  • 语言是有边界的,同样,模型也有其作用的上下文。我们可以通过共享内核、防腐层等技术实现模型在不同上下文中的映射和协作。
  • 领域模型数据模型有明显区别,领域模型关心的是业务概念,其要义是显性化地表达业务语义;数据模型关心的是数据存储,其核心是数据访问的性能、数据的扩展性等非功能属性。

工具化思维

懒人的逻辑中也有其合理的一面,勤劳奋斗的逻辑中也必定有其荒唐的一面。 ——张方宇

  • 工具化是一种“偷懒”的智慧,工作中要有阶段性地停下来思考,不要用战术上的勤奋掩盖战略上的懒惰。
  • 工具化的步骤:首先,发现问题,找到重复3次以上的手工劳动;其次,明确问题,找到现状和期望之间的差距;最后,制造工具,解决问题。
  • 创新不一定都是从无到有的,对现有工具的组合和整合也是一种创新和工具化。
  • 要不遗余力地提升研发效率,比如TestsContainer和通用的MyBatis Mapper。
  • 要善于利用工具,白板和便签贴是讨论问题时非常有用的工具。有价值的不是工具本身,而是如何利用它。

量化思维

No measurement,no improvement.(没有量化,就无法优化。) ——“科学管理之父”温斯洛·泰勒

  • No measurement,no improvement.(没有量化,就无法优化。)
  • 量化的一般步骤包括定义指标、数字化和优化指标。
  • 对于研发效能来说,目前还没有特别有效的度量手段,所以指标的设定非常关键。错误的度量不仅不会带来效率提升,反而会带来伤害。
  • 团队管理的首要任务是目标管理,我们可以采用OKR进行目标管理,在设定OKR时要遵循SMART原则。指标只是管理手段,不可完全迷信指标。
  • 量化工作本身是一件非常困难和极具挑战的事情,但量化思维要求我们不要轻易放弃关于量化的思考和尝试。没有量化的目标,就像是断了线的风筝,没有方向,缺少指引,飞到哪里是哪里,而量化后的目标可以为我们清楚地指引方向。

数据思维

一切业务数据化,一切数据业务化。 ——阿里巴巴

  • 一切业务数据化,一切数据业务化。数据是公司的重要资产,工程师必须了解公司的数据体系。
  • 整个大数据体系很庞大,对于应用开发者来说,不一定要面面俱到,非常精通,但至少要做到能理解、会使用。
  • 典型的企业的大数据解决方案包括数据仓库、ETL、元数据、分布式数据存储、流式计算等。
  • 数据库关注的是OLTP,数据仓库关注的是OLAP,数据仓库中对数据的操作通常包括切片切块、上卷下钻等。
  • 数仓建模通常采用Ralph Kimball提出的维度模型,其中针对维度表和事实表,为了提升查询性能和响应速度,通常采用大宽表代替雪花模型,用空间换时间的方式。
  • 阿里巴巴的生意参谋是数据业务化的典型代表和成功案例,通过大数据赋能商家,既让商家更好地在平台做生意,同时平台也实现了数据变现,可谓双赢。

产品思维

产品就是用来解决某个问题的东西。 ——苏杰《人人都是产品经理》

  • 产品就是用来解决某个问题的东西。产品无处不在,每个人都需要具备一些产品思维,人人都是产品经理。
  • 产品对上支撑业务价值,对下要求业务功能和质量属性的实现。产品的核心要素包括用户、需求和场景。
  • 产品有多种视角的分类,按照用户需求可以分为工具型产品、社交型产品、交易型产品、平台型产品;按照用户类型可以分为2C、2B和2G产品等。
  • 产品架构主要分为用户感知层、功能模块层和数据层3个层次。
  • 产品化是把一种技术、一种服务通过标准化、规范化的流程形成一种可大规模复制生产和发布的能力。
  • 平台也是一种产品形态,在不同的语境下,平台的含义不一样。在技术的上下文中,平台是指可复用的硬件或软件的操作环境,其目的是节约成本、提升软件研发效率。
  • 用产品思维去建设平台,我们可以从价值的角度出发,更多地关注用户体验,从而有机会做出不错的平台型产品。

思维能力的综合应用

我的商品团队之旅

人是能够习惯于任何环境的生物,之前你认为自己难以克服的困难,慢慢都会适应了。 ——维克多·弗兰克《活出生命的意义》

  • 看起来很困难的事,刻意练习多了,也就不困难了。我从一开始进入新团队的不知所措,到后来的从容谈定,就经历了刻意练习的过程。
  • 落地新团队,要抓住企业的核心要素——人、业务、技术和文化,可以做到事半功倍。
  • 再复杂的业务也可以进行结构化分解,一旦把业务的结构梳理清楚,工作就完成一半了。实现方式最好采用简洁朴素的CMP或管道模式,复杂的流程引擎通常不仅帮不上忙,还会增加额外的复杂度。
  • 复杂业务的应对之道是结合自上而下的结构化分解+自下而上的抽象建模,同时要在过程中随时调整、重构结构和模型,将可复用的能力下沉,从而提升系统的可维护性。

COLA的演进过程

Software’s primary technical imperative:managing complexity.(软件的首要技术使命:管理复杂度。) ——Steve McConnell

  • 架构的要义在于约束。
  • “在一个架构良好的系统中,评估代码改动点不应该是线性地按图索骥,而是应该像散列查找一样,直接定位到需要改动的地方,它们之间是O(n)和O(1)的差别。”

🥤 COLA: Clean Object-oriented & Layered Architecture