《程序员的底层思维》:解密软件背后的16种底层思维能力
本文是关于《程序员底层思维》的阅读笔记,读后有较大收获,分享给大家。书中介绍了程序员应该具备的16中底层底层思维能力,只有意识到思维能力的存在,我们才有可能去学习、练习和提升。
基础思维能力
抽象思维
抽象思维是程序员最重要的思维能力之一,抽象的过程就是通过归纳概括、分析综合来寻找共性、提炼相关概念的过程。
软件工程师每天都要动用抽象思维,首先对问题域进行分析、归纳、综合、判断、推理,然后抽象出各种概念,挖掘概念和概念之间的关系,再对问题域进行建模,最后通过编程语言实现业务功能。
抽象具有层次性,抽象层次越高,内涵越小,外延越大,扩展性越好;反之,抽象层次越低,内涵越大,外延越小,扩展性越差,但语义表达能力越强。
逻辑思维
逻辑思维基本包含3个方面的要素。(1)概念:概念是思维的基本单位。(2)判断(proposition,在逻辑学中也叫命题):通过概念对事物是否具有某种属性进行肯定或否定的回答,就是判断。(3)推理(argument,在逻辑学中也叫论证):由一个或几个判断推出另一判断的思维形式,就是推理。
判断是概念的展开,没有判断,就不能揭示和说明概念。同时,判断也是推理的前提,是正确运用各种推理的必要条件。所谓推理,就是研究语句、判断、命题之间相互关系的学问。建模是一个归纳工作,我们通过抽象问题域里具有共同特性的类来建立模型。为了验证模型的有效性,我们会使用演绎的方法去推演不同的业务场景,看看模型是否能满足业务的需要。
大多数情况下,我们的思维逻辑链都比较短,短就意味着肤浅,找不到问题的根本原因。延长思维逻辑链的方法之一是5Why思考法,它能够帮助我们找到问题的根本原因。5Why思考法,是指对一个问题连续多次追问为什么,直到找出问题的根本原因。
丰田汽车公司前副社长大野耐一曾经举了一个通过5Why提问法找到问题根本原因的实例。有一次,大野耐一先生见到生产线上的机器总是停转,虽然修过多次但仍不见好转,便上前询问现场的工作人员。
问:“为什么机器停了?”(1Why)
答:“因为机器超载,保险丝烧断了。”
问:“为什么机器会超载?”(2Why)
答:“因为轴承的润滑不足。”
问:“为什么轴承会润滑不足?”(3Why)
答:“因为润滑泵吸不上来油。”
问:“为什么润滑泵吸不上来油?”(4Why)
答:“因为油泵轴磨损、松动了。”
问:“为什么油泵轴磨损了?”(5Why)
答:“因为没有安装过滤器,润滑油里混进了铁屑等杂质。”
结构化思维
结构化思维是一种以逻辑(事物内在规律)为基础,从无序到有序搭建结构的思维过程,其目的是降低复杂度和认知成本,因为大脑更喜欢概念少、有规律的信息。
结构是万物之本,小到分子,大到宇宙,只有了解其结构才能真正认识它。
批判性思维
批判性思维中的“批判”一词其实不太准确,甚至在中文里有点否定、批评和抨击的负面意思。批判的英文是critical,这个词来自古希腊词kriticos,是分辨力、决断力或决策能力的意思。它强调的是理性和逻辑在思维中的重要性,目的是形成正确的结论,并做出明智的决策和判断。所以批判性思维并不是让你批评、否定或者抨击别人,而是教你如何提升分辨能力、判断力。
简而言之,批判性思维就是对思维过程的再思考。古希腊哲学家苏格拉底说,未经审视的人生不值得过。同样,未经批判性思维审视过的结论也是不值得相信的。
维度思维
一个人的思维层级与其思考的维度是正相关的,这一点可以通过我们的日常语言得到佐证。当我们说这个人很“轴”“一根筋”的时候,实际上是在说他只有一维的线性思维;高手的思考会更加“全面”,因为涉及“面”,所以至少是两个维度的思考;而真正的高手,其思考是成“体系化”的,“体”至少是三维的,也就是说他考虑到了“方方面面”。
多维度思考是思考的高级阶段,是体系化思考的必备,是解决复杂问题的一把利器。
分类思维
当信息量过大时,归类分组能帮助我们理解和处理问题。分类是人类大脑的识别模式,是我们化繁为简的不二法宝。在我们处理问题,特别是复杂问题的时候,分类思维扮演了极其重要的角色。
分类的目的是找到问题域中的“核心抽象”,基于这些“核心抽象”,我们才能设计相应的领域模型和数据模型;基于这些模型,我们才能构建相应的系统。
没有完美的分类,任何分类都与进行分类的观察者的视角和目的有关。
分治思维
分治的价值在于,我们不应该试着在同一时间把整个问题域都塞进自己的大脑,而应该试着以某种方式去组织问题,以便能够在一个时刻专注于一个特定的部分。
分治算法主要包含3个步骤:分、治、并。“分”是递归地将原问题分解成小问题;“治”是在解决了各个小问题之后(各个击破之后)合并小问题的解,从而得到整个问题的解;“并”是按原问题的要求,将子问题的解逐层合并,构成原问题的解。
软件中存在大量的分治思想,比如管道模式、分层架构、分布式架构等,无不体现了分治的强大。
简单思维
把一件事情搞复杂是一件简单的事,但要把一件复杂的事变简单,这是一件复杂的事。
简化本质上是一个熵减活动。所有的事物都在缓慢熵增,就像凯文·凯利在《必然》一书中提到,世间万物都需要额外的能量和秩序来维持自身,无一例外。这就是著名的热力学第二定律,即所有的事物都在缓慢地分崩离析。而熵减就是逆向做功,即通过更多的努力让混乱的系统重新归于秩序。
简单不是一个简单的目标,而是一个非常高的目标。所有的UNIX哲学浓缩为一条铁律就是KISS原则。
简单不是简陋。简单是一种洞察问题本质、化繁为简的能力,简陋是对问题不加思考地简单处理,二者有本质区别。简单需要我们付出很多的精力,对问题深入思考,进行熵减逆向做功。往往需要经历简单—复杂—简单的演化过程。
成长型思维
想要培养自己的成长型思维,首先要学会正确评价自己,也就是要学会客观地看待自己的状况和水平,不要自视过高,也不要妄自菲薄。其次,不要过分相信天分。一个人一旦相信了天分,就等于相信了自己的水平是基本不变的,就会给自己设限,觉得我只能做这个,我不适合干那个,甚至会觉得努力是一件丢脸的事情,只有笨人才需要努力。
看过《刻意练习:如何从新手到大师》一书的人应该知道,很多所谓的天才,其实靠的并不是天分,而是努力!想要让自己获得成长和改变,就一定要学会用成长型思维去看待和处理问题,其关键在于不要自我设限。
专业思维能力
解耦思维
在软件领域,“耦合”是指两个事物之间联系的紧密程度。联系越紧密,耦合性越高;联系越少,耦合性越低。解耦就是要减少事物之间联系的紧密程度。
“计算机中的任何问题,都可以通过加一层来解决”,中间层的价值也在于解耦。
“高内聚、低耦合”是软件设计追求的重要目标之一,组件、模块、层次设计都应该遵循“高内聚、低耦合”的设计原则。
应用架构之道,就是要实现业务逻辑和技术细节的解耦。
契约思维
“人是生而自由的,但却无往不在枷锁之中”,同样,“写代码是自由的,但无往不在规则之下”。这里的规则包括工程师必须要遵守的程序语言语法、编程规范,以及协议标准。
为了保证软件编程风格的一致性,减少随心所欲带来的复杂度,我们有必要使用契约思维制定一定程度上的编程规范,去约束团队的行为。规范的价值,就在于它能保证代码的一致性,而一致性在很大程度上可以降低认知成本和复杂度。
通过在团队中落实命名规范、异常处理规范、架构规范等,可以有效地帮助团队治理代码复杂度。
社会大规模分工协作离不开契约思维,编程在很大程度上是一种“制定契约”。
模型思维
在软件工程中,有两个高阶工作,一个是架构,另一个是建模。如果把写代码比喻成“搬砖”,那么架构和建模就是“设计图纸”了。相比于编码,建模的确是对设计经验和抽象能力要求更高的一种技能。
简单来说,模型就是对现实的简化抽象。
领域模型将现实世界抽象为了信息世界,把现实世界中的客观对象抽象为某一种信息结构,而这种信息结构并不依赖于具体的计算机系统。
领域模型对软件开发至关重要。因为从本质上来说,软件开发就是从问题空间到解决方案空间的映射转化,而领域模型是连接问题和解决方案的桥梁。
领域模型关注的是领域知识,是业务领域的核心实体,体现了问题域中的关键概念,以及概念之间的联系。领域模型建模的关键在于模型能否显性化、清晰地表达业务语义,其次才是扩展性。
数据模型关注的是数据存储,所有的业务都离不开数据,以及对数据的CRUD。数据模型建模的决策因素主要是扩展性、性能等非功能属性,无须过多考虑业务语义的表征能力。
工具化思维
我们可以把“懒”分为3个境界。(1)最低境界是“实在懒”,拖延症,不到万不得已,不去完成任务。(2)其次是“开明懒”,迅速做完不喜欢的任务,以摆脱之。(3)最高境界是“智慧懒”,使用工具完成不喜欢的任务,以便再也不用做无谓的重复工作,从而一劳永逸。
量化思维
No measurement,no improvement.(没有量化,就无法优化。)——“科学管理之父”温斯洛·泰勒
一个量化的过程大体上可以分为以下3步。(1)定义指标:仔细分析问题,找到那个可以用来量化问题的关键指标。(2)将指标数字化:围绕关键指标,明确需要哪些数据来实现指标的计算,通过数据收集、数据存储、数据展现去呈现指标,也就是数字化的过程。(3)优化指标:有了数据指标之后,要围绕指标数据迭代优化,达成业务目标。
量化工作本身是一件非常困难和极具挑战的事情,但量化思维要求我们不要轻易放弃关于量化的思考和尝试。没有量化的目标,就像是断了线的风筝,没有方向,缺少指引,飞到哪里是哪里,而量化后的目标可以为我们清楚地指引方向。
数据思维
一切业务数据化,一切数据业务化。
用户在App上的每一次浏览、每一次点击、每一次搜索等业务行为,都会被沉淀为数据保存起来,这种保存业务过程数据的做法叫作业务数据化。这些数据会帮助App更好地认识用户,当用户下次打开App时,利用这些数据,App就可以更精准地为用户进行智能推荐和广告精准投放,这种用数据赋能业务的方法叫作数据业务化。
产品思维
工程思维和产品思维是不一样的。工程师追求技术至上,产品经理追求商业价值和用户体验;工程师关注细节,产品经理关注全局;工程师关注How(如何做),产品经理关注Why(为什么)。结合两种思维方式,可以让思考更全面和系统化。
作为技术人员,我们必须要具备一定的产品思维,这样才能辨别产品需求的真伪,把伪需求挡在外面,从而可以把时间放在真正有价值的项目上,少做一些无效的投入。对于团队的技术负责人来说,这种把关尤为重要。
了解产品思维,关键要理解产品的三个核心要素:用户、需求、场景。(1)用户是产品要服务的对象,即使用产品的人。(2)需求即产品要解决的核心问题是什么。需要注意的是,需求是分层次的,最浅一层是需求的表象;第二层是观点和背后的目的;最深一层是人性,每个需求挖到最后,都可以归结到人性层面。(3)场景即用户何时何地需要使用产品。
后记
希望读者能够把这些底层思维能力内化成自己的“不知道自己知道”。这些底层思维中蕴藏着解决问题的强大力量,当它们与软件设计相遇时,会擦出耀眼的“火花”。
软件开发行业的匠心和传统行业的匠心不一样,不是重复做简单的事情,你就能把它做好。这就好比你即使做了10年的收银员,也只是一个收银员,无法成为财务总监。在软件开发行业,你需要不断地学习、不断地思考、不断地积累、不断地尝试、不断地失败、不断地创新,才有可能做得好。
优秀的工程师,心中都有一团火——一种对美的追求和渴望。这需要我们经历无数个不眠之夜,承受很大的压力,受很多委屈,看很多的书,尝试很多别人没有实践过的东西,要具有一颗“不妥协、不将就、不放弃”的倔强的心。这样我们才能做出一些不同凡响的东西,才能活成自己所期望的样子。
来源:juejin.cn/post/7277830857422602252