程序员如何培养解决复杂问题的能力?

怎甘沉沦 提交于 2019-11-29 06:14:50

今天在上网时候,突然看到了这篇文章,感觉非常的适合现在的自己去思考下,可能也适用在座的读者。程序员不仅仅是敲代码,更是一个复合能力的结合体,也不仅仅停留在技术和代码阶段。你想要成长就得重新审视下“程序员”,看看自己的基础是否牢固,万丈高楼平地起,说的就是这个意思,聊天时候很多人说“程序员只要懂得多,不需要那么深的。”其实这句话是错的,比如说,disruptor底层是个什么结构?为什么选这种结构?解决了什么问题?什么原理呢?你都知道吗?只知其然,不知其所以然是不行的!看看自己现在项目中你能发现什么问题,或者说能预料到什么问题,有什么解决方案,最优方案是如何定下来的?这一系列的问题都是进阶“程序员”所必备的,死写代码是不行的。(非原作者所述)

程序员大致可以分为三类:码农、工程师、高级工程师

  • Level 1 - 码农
    能做事,但缺乏思考,Coding只是体力活。
  • Level 2 - 工程师
    不盲目,懂得思考与进步。
  • Level 3 - 高级工程师
    不止有足够的思考,还具备解决复杂问题的能力

从码农到工程师并不难,只要懂得不盲从、主动思考、学习、改善就可以很容易进入工程师的行列,但是大多数就止步于工程师了,因为要从工程师成长到高级工程师,需要解决复杂问题的能力

什么是复杂问题

首先明确一点:
解决问题解决复杂问题

问题 = problem
复杂问题 = ( complex + complication ) problem

complex,说明问题是复合的,是多个领域复合在一起组成的问题
可以是技术上的复合,比如
数据结构 + 操作系统原理 + 网络 + 分布式 => 分布式数据库问题
也可以是非纯技术的复合,比如
产品思维 + 沟通能力 + 架构能力 + 代码能力 => 将业务需求落地

complication,说明问题是复杂的,需要系统性思维、严谨的问题分析能力,抽丝剥茧才能找到问题的根源并解决。

如何具备解决复杂问题的能力

引用曾经高级Node.js,如今的初级Ruby/Rust/Go工程师兼SRE对我说过的一句话:

未来最值钱的技能,第一个就是“解决复杂问题的能力”,
技能表上是没有 Node.js,没有Go,没有MySQL,没有Web开发的。
解决复杂问题的能力需要你有系统性思维,严谨的分析问题能力,沟通能力和组织管理能力。

技术变化得太快,每段时间都会有新的技术、新的工具出现,大多数程序员都觉得疲于应付,每当有新的技术出现,大多数程序员的学习路径是这样的:

看“Quick Start”/ 实操教程 => 跟着操作 => 好像会用了

遇到问题后却不知道原因在哪里,如何解决,开始Google,然后一个个解决方案地尝试,尝试到第 Math.random().toInteger() 种的时候,终于解决问题,然后觉得自己真牛逼,又解决了一个问题。
解决问题的路径是:

搜索解决方案 => 从里面看到别人分析的原因 => 自己不一定看懂了分析,但是先用这个方案试试再说 => 薛定谔的解决

其实这样并没有真的解决问题,因为他不知道原因在哪里,为什么采用这个方案,是否有其他方案,每个方案的优劣在哪里,下次再出现原因类似,但表现不同的问题,他就又不懂得该如何解决,甚至也同样找不到原因在哪里。
解决问题的步骤应该是:

分析问题 => 猜想 => 验证猜想 => 找到原因 => 构建解决方案 => 验证解决方案 => 解决

这才是一条完整的“解决问题”的路径。

很多人在第一步就失败了:分析问题,一头雾水不知道从哪里下手。

要分析和解决问题首先要求你有足够的前置知识,对这个问题所涉及到的原理有足够的了解,分析问题是知识的反推,解决问题是知识的顺推
只要提升相关知识的掌握程度,分析与解决问题的能力就能明显提高。

1. 基础知识很重要(深)

我们所使用的任何一门技术,都有一个漏斗状的知识体系,这门技术在漏斗最上层,而它基于它下层的所有基础知识构建,每一层都是基于下层构建,比如MySQL:

 
漏斗状知识体系


先问一个问题,数据库一个表中,频繁一起读取的数据,该怎么存,读取速度比较快?
你可能说得出,要把它们主键相邻存在一起,但是你可能不知道,为什么要把它们主键相邻存在一起。
因为主键相邻存在一起的数据会被写到连续的页(Page)中,相对连续的页,数据库会在磁盘上尽量分配连续、邻近的空间,可以将随机读变成顺序读,并且通过系统调用read(start, length)每次读出一页,每页中包括尽量多的结果,那么需要读取的总页数也会降低。如果不存在一起,那么随机读使得硬盘无法进行预读优化,如果是机械硬盘还需要增加额外的寻道时间,且需要读取的总页数也增加。
数据库的一个小常识,竟然涉及到了硬件、操作系统、数据库原理,你以为常识就是常识,但是其实这个常识也是被推论出来的,不懂得底层的知识,常识只能靠死记硬背,遇到更复杂的问题,就不知道如何分析了,因为分析是层层递进的,如果你只懂一层,不懂下面的层次,就没法深入。
程序员不学基础知识就像做医生不学解剖,不是需要上手术台的医生才需要学习解剖,了解人体的基本构造、各个生理组织间的协作关系是分析问题的基础要求,不了解这些基础,根本无法进行精确的诊断。

 

由于每个技术的知识体系都是漏斗状,所以大量的顶层技术、工具都依赖着少量的、同质化的基础知识,只要学习有限的基础知识,就能对大量的顶层技术触类旁通、举一反三,可以降低未来的学习成本与学习难度以及加深理解的深度。

2. 如何学习基础知识(由广及深)

学东西,结合应用场景很重要。重要的话说三遍,结合应用场景结合应用场景结合应用场景
相对于基础知识,现成的一些顶层技术、工具更容易让我们有兴趣去学习,原因就是顶层的技术能够马上被我们结合到相应的应用场景
学Node.js,我们知道它是可以做服务端编程的,30分钟让我们搭出一个服务器。
学MySQL,我们知道它是做数据存储的,几个SQL就满足应用的数据持久化。
学k8s,我们知道它是做容器编排的,能够让我们简单地部署应用集群。

但是学基础知识,就无法结合相应的应用场景:
学计算机组成原理,我又不去装电脑,它对于我有什么帮助?
学操作系统原理,我又不去开发操作系统,也不做什么基础开发,它对于我有什么帮助?
学数据结构,我又不是搞算法,它对于我有什么帮助?

这样一想,基础知识真的没有学习的动力…

所以我们应该先挑一门自己想要了解的顶层技术,先通过优秀的资料了解这个技术,把自己能学懂的先学懂,不懂的可以仅仅浏览,有个印象,知道哪里不懂,知道自己学不懂是因为对什么问题不了解。
然后总结这些自己不懂的点,是涉及到了哪些自己不了解的前置知识,所以学不懂。我们每次可能只能往下推一层,比如学习MySQL时,只能总结出自己遗漏的前置知识是数据库原理,而很难知道自己还应该补充操作系统的知识,这是很正常的,学习也是层层递进,越挖越深。当我们开始学习数据库原理的时候,又会在数据库原理学习的过程中发现自己有遗漏的前置知识,比如操作系统。这样学下来,不仅不会浪费时间学习无用的知识,且每个基础知识都是带着问题去学,带着问题往下挖,学到对应基础知识的时候,都能马上与上一层的应用场景相结合,更容易理解。

寻找优秀资料 => 能学懂的就学懂,不能学懂的浏览即可,记住自己迷惑的点 => 根据自己迷惑的点思考是缺少哪些前置知识 => 进入下一个循环(寻找前置知识的优秀资料)

3. 实践

由广及深学习了相关基础知识后,应该只是到了理解的地步,还不算是吸收
纸上得来终觉浅,绝知此事要躬行。
只有将理论上的理解实践起来,试一试才知道自己的想法是否正确,在现实系统各种复杂的情况下,如何将理论与实践结合。
第一步可以是自己试,随便搭一个环境尝试,但是这种情况有限制,就是这是“假”环境,过于简单了,也缺少真实数据填充与真实应用场景检验。
现实工作中所面临的问题会更加复杂也会更加丰富,能更快吸收一个知识,所以更好的方式是找到能够运用自己所学的平台,进入一家团队精炼、业务量大、并且发展速度快、重视技术的公司。

4. 表达与沟通

一个人的既有知识、技能、信息量都非常有限,工作中我们都是与他人配合才能做好一个业务。
项目前期需要与产品经理、业务部门讨论需求、理解需求,
项目中期需要与同事合作分工,如果是涉及多个系统的业务,还需要与其他技术团队的同事沟通技术实现,
项目后期需要与SRE团队协作部署上线。
其中涉及到人与人之间互相的信息传达,如果不能精确或者恰当地表达,对方可能无法理解我们的真实意思,导致无效或者失真的沟通,降低工作效率甚至无法获得预期结果。
所以锻炼自己的表达与沟通能力,也是在间接提升工作效率,并且能够使团队运作更顺利,使得同一件事有更优的工作结果。
写博客是锻炼表达能力的有效途径之一,将自己学会的东西、思考的东西以讲述给他人的角度写出来,思考怎么让读者理解自己要表达的意思,甚至思考怎么让读者更简单地理解自己要表达的意思。刚开始写博客可能不知道如何下笔,不知道刚怎么分配章节更合理,不知道怎么组织文章的逻辑使它更简洁、精炼、易懂,一篇博客可能要花上十几天才能完成,但是坚持写技术博客,会发现自己组织语言的能力也在提升,每过一年,再回头看以前的博客,会想:“我去,这竟然是我写的?这么烂?”,坏消息是,以前写的博客确实挺烂的,但好消息是,你现在一定进步了,所以看出了它有多烂。
读书时学渣一枚,我的作文能力也是非常非常差,逼着自己坚持写一些技术博客,不止是总结所学的东西,更是提升自己的表达能力。
自己学明白一个东西是最简单的,但怎么表达出来让别人也听懂,是非常非常难的,写博客是一件虽然困难但有收获还有成就感的事,值得坚持,等到写博客对我来说变得简单的那天,我一定很牛逼了。

5. 健身

有句古话:磨刀不误砍柴工
还有句比较新的话:坚持做不紧急但重要的事
深以为然。
当你在技能、思维等所有软件层面都成为高级工程师的时候,还需要让你的硬件跟上步伐。
“解决复杂问题的能力”就是说不止得有“能”,还得有“力”,身体健康非常重要,这不止是为了让自己过得开心,对自己的家人负责,更是让自己有精力和身体资本去应对各种压力。
保持每2 ~ 3天健身一次,每次1 ~ 1.5小时,坚持下去,就能保证自己在未来20年都有充足的精力和健康的身体去学习、工作、应对压力。
虽然健身暂时会占用你一些时间,但是它可以让你长跑下去,如果不健身,也许你每周可以多用几个小时工作、学习,但是这只是短时间的冲刺,冲刺的人能跑的距离还是不如长跑的人,人生几十年,是长跑不是冲刺。

写在最后

世界上有四类事,我们放眼整个人生来看一看:

  1. 重要且紧急:每天份内的工作、生存、生病了看医生
  2. 重要但不紧急:学习、健身,每一件长期坚持可以让未来变得更好的事
  3. 紧急但不重要:购买生活用品、食品
  4. 不紧急也不重要:刷淘宝、刷剧、睡懒觉
 
                            时间四象限法则

大多数人都只做了1、3、4,很少去做2,首先他们可能不清楚什么是重要但不紧急的事,其次是因为他们很难坚持长期做重要但不紧急的事。
如果无法坚持做重要但不紧急的事,生活中就有出现各种紧急的事让你焦头烂额,比如不坚持健身,就容易生病需要请假看医生也没有精力做其他事,由于缺少精力,又会使得工作能力下降收入降低生活质量降低。
坚持做重要但不紧急的事,会让未来稳步上升,只着眼于重要且紧急的事,那生活中只会有越来越多重要且紧急的事需要你处理应该用长远、发展的眼光去规划自己每段时间需要做的事

磨刀不误砍柴工,非常有道理。

感谢这篇文章点醒自己,感谢原作者!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!