序言
做完季度绩效考核,程序员小王找到了自己的导师,架构师大刘,倾诉自己的迷茫。
“大刘,我毕业也两年多了,一直就是做业务,上线,做业务,上线,感觉根本得不到任何提升。我找了一些架构师的讨论组,发现他们聊的什么高可用、分布式什么的每个词好像都能懂,但是加一起是什么意思,为什么要这么弄还是完全不明白,读他们的架构设计文档也是一种不明觉厉的感觉,自己尝试做了一个模块设计发现在大佬眼里到处都是漏洞。都说搞架构主要靠经验,但是我刷了这么多业务,到底是哪里经验不够呢?到底怎么学习才能脱胎换骨,从程序员成长为架构师呢?”
“嗯,这个问题比较复杂,让我们先重新梳理一下你的基础能力,看看是不是时候打开通往架构师的大门了。”
接下来,大刘带着小王,开始复盘小王的能力基础。
注意:本章还不涉及架构设计的方法论,但是以下基础能力是成为架构师的必备基础。如果你看完了序言发现自己的基础能力还有很大的提升空间,建议先放下本书,进行基础能力的积累和锻炼。希望本书的序言也能给你带来足够的帮助。当然,你也可以继续阅读本书,同时进行积累和锻炼,说不定也能有一些收获呢!
代码掌控力
我们来先问自己几个问题:
你能在一个大型的代码仓库中迅速找到你想要修改的地方吗?(你需要花很多时间翻找代码结构吗?)
你清楚你的每一个修改可能会影响到的上下游吗?(你会担心自己的提交影响到一个你不知道的地方吗?)
面对一个Bug,你能迅速的列举该Bug可能的原因吗?(你会浪费很多时间在排查一个已经复现的问题上吗?)
现在去看你三个月之前的提交,能迅速明确每个提交的作用吗?(你的提交会在一段时间之后就无法被理解了吗?)
对同事的代码进行CodeReview时,你能够在短时间内获取充分的信息、发现足够隐蔽的问题吗?(CodeReview时,你的时间基本都在理解“他在干什么”吗?)
本书不讨论是应该多写注释还是应该由清晰代码来表述自身的含义,是应该测试驱动还是应该专注在代码本身等等;不论采用什么样的方法/习惯/风格,你需要能够掌控自己和同事的代码这一点是不变的。
程序大牛往往能“把自己的脑子当做CPU使”,也就是阅读代码的同时,能在脑内类似解释执行的方式模拟代码的执行过程。这看起来很神奇,其实无关脑容量或者智商,而是需要两个方面的积累:
足够多的阅读代码练习、查错和调试经验
足够好&统一的代码结构、团队代码风格
也就是说,是读足够多的代码和代码本身足够易读两方面的作用。
代码掌控力不仅仅影响你堆代码的速度,也影响你在代码层面迅速了解他人工作、或是在大型系统中发现与解决问题的能力。毕竟所有的软件架构设计最后都是需要表示成代码才能产生价值,越大型的系统越需要更多人的协作,也就需要越强的代码掌控力。
充分理解行业与业务
程序员很容易产生的一个观念就是,我只要技术好,代码写的好,什么行业啊需求啊那都是产品经理的事情。但是事实上,一个优秀的软件工程师和新手程序员之间的差别就在于此。软件工程师的工作是解决现实问题,而非写出“漂亮的代码”,对业务和行业充分了解有着非常大的意义:
极大幅降低与非研发角色之间沟通的成本。当你所处在一个行业时,沟通中必然充满了这个行业专属的各种“术语”。如果对这些术语,以及背后的原因、行业惯例等缺乏了解,一定会大幅提升和其它角色之间的沟通成本。
能够站在团队视角提供更多候选方案,共同决策。并非所有产品经理对技术(尤其是你的项目中的技术细节)有充分的了解,所以他们提出的方案有时候并非最佳方案。通过对技术和业务的双向了解,工程师可以参考产品经理的最终目标提出一些候选方案进行讨论,经常能够达成更高投入产出比的方案,甚至是超过产品经理原本预期的方案(产品经理在设计方案时低估技术的实现能力也并不罕见)。
能够更准确的“预测”未来的迭代方向。并非所有项目都有充足的时间评估未来的迭代计划,因此工程师在设计方案与实施时,需要根据自己对未来迭代的大致判断进行扩展性/性能和开发代价之间的平衡。对行业和业务越了解,就越容易准确的预测未来的迭代方向。
能够更准确的评估或调整需求之间的优先级和重要程度。这大部分时候是项目经理的职责,但是,由研发来担任项目经理有诸多好处,在很多公司也是现实的惯例。即使不身为项目经理,对自己进行任务管理的过程也非常需要这种能力。
有一句给我印象很深但是我忘记了出处的话,大意是:做程序员最棒的事情是在于你可以拥有两个专业,一个是程序本身,一个是你所在的行业。
技术深度及广度
技术深度通常衡量你对系统原理性的了解。优秀的程序员通常具备强烈的好奇心,不仅仅了解什么样的代码能够工作,还需要了解为什么它能够工作,经历了哪些过程,工作的状况如何。了解这些原理性的东西会产生几方面的作用:
可以让你拥有更多不同层面的解决方案,从而解决更多的问题。譬如有的问题在业务层面很难解决,但在框架层面很容易解决;有的问题在应用层面很难解决,但是在驱动层面很容易解决;有的问题在代码层面很难解决,但是在编译器层面非常容易解决;等等……
让你能够更好的衡量现有的技术方案,更准确的进行方案选型。譬如数据库应该在 k8s 内自建吗? Sidecar proxy 的性能开销大概在什么规模?
对于性能优化和安全等方向,拥有足够的技术深度是唯一能够达到目标的途径。
锻炼你了解、分析、对接、改进大型系统的能力。很多我们直接“拿来就用”的方案本身也是一个非常大型的系统,去了解、分析它的过程,以及把“使用”它的过程看做“与它对接”,发现问题或不足时甚至可以尝试对它进行改进,这个过程的每一个步骤都是一种能力的锻炼。
反哺开源生态,提升技术影响力。有了足够的技术深度,你才有机会接触、修复、修改很多开源项目的更底层代码,从而成为更多优秀开源项目的 contributor ,从而提升技术影响力。
技术广度则让你能了解更多不同领域的方案,从而:
提升和不同领域的软件/开发人员协作的能力,从而能够接触、掌握更大型的系统。举例来说,很多业务方案需要对前后端都拥有一定程度的了解才能完善设计。有些数据存储方案需要对事务需求(OLTP)和分析需求(OLAP)均有一定的了解才能完善设计。
让你拥有更多的项目机遇。我们经常会遇到一家公司的团队和整体招聘策略倾向于一个主要方向,但是偶然突然遇到一个特定需求需要一个特定领域的知识。此时技术广度更加优秀的人才将会脱颖而出。
让你拥有更多的优秀方案参考。很多现有的方案都经过了很多前辈长年的努力和积累,在原理上、设计上、算法上、实现上等等方面都有非常多值得学习和参考的内容,其中有很多内容可能可以用于以后的架构设计工作。很多不同领域/不同思想的方案也都起到很大的参考意义。
让你在技术选型时拥有更多的候选项。很多时候我们在架构设计中面临的问题,都不是只有我们才会遇见的问题。行业内是否已经有了足够成熟的方法?是否有尚不成熟但值得尝试的方法?除非你的问题复杂程度已经走在了行业最前列,否则大部分时候回答都是肯定的。
随着技术广度的提升,逐渐形成知识体系和方法论,会大大提高你进行学习、钻研技术深度的效率,从而让你更容易提升自己的技术深度和广度。
本书暂时不对具体如何提升技术深度与广度,以及如何平衡技术深度与广度的精力分配做探讨。可以明确的是拥有充分的技术深度与广度对于架构设计有着非常重要的意义。
同时拥有技术广度和深度的就是所谓的“T型人才”,所谓的“一专多能”。拥有“宽泛扎实的理论基础+专业深入的技术技能+精准娴熟的实践经验”的人才。这种人才无论在理论知识架构、岗位工作技能,还是项目的实践操作上,都会成为企业的“多面手”。
算法与数据结构
我经常被人问到的一个问题就是,我工作这么多年也没用到过什么算法,学那么多算法有什么用?或者是现在普遍都是分布式/并行架构,进行那些连线程都不让开的算法练习有什么意义吗?
事实上,算法练习对于基础的业务编码也许作用有限,但当你逐步提高,开始深入系统底层,或面临更大型的系统架构时,算法练习的作用就会越来越明显的体现出来:
锻炼对程序执行开销的评估能力。很多新人程序员经过一定的项目实践,往往都能写出“正确”的代码,但很多人很难对自己代码执行的开销有个清晰认识,这在进行大型系统方案设计时,会成为致命的问题。
养成面向问题规模的思考习惯。在架构设计和方案选型的过程中,“问题规模”是一个非常重要的因素。养成时刻把问题规模放在心上,能够更准确的平衡方案的性能开销与开发代价。
掌握分析问题与解决问题的大量方法。在算法领域的很多思想,譬如递归、图,以及很多通用方法,譬如问题的抽象、变形、分治,在架构设计的过程中都有大量的应用。即使是那些不太常用的算法,其实也都有相当多的用武之地。当你面对的系统足够复杂,问题足够困难时,迟早会遇到它们。
进行高速、高要求代码的练习。算法练习通常针对一个足够抽象的问题,要求短时间迅速编码解决,这对训练如何同时确保代码的速度和质量、训练短时间分析问题、思考方案、编码解决能起到非常大的作用。经过足够多的练习,你的思路才能往往比别人“更快一步”。
进行学习本身的练习。算法练习的学习路径足够长,随着学习的深入必然会面临更多的挑战。此时如何搜索资料,加入讨论,提问,甚至是阅读论文,都可以得到非常有效的锻炼。
整体上,在项目实践中去进行很多基础能力的锻炼存在周期长、反馈慢的问题,而进行抽象的算法练习,能够更有效率的提升这些能力。因此在工作之余花费一定的时间进行算法练习,对于自身基础的提升和架构设计,都是有相当多的好处的。当然,算法练习也是一个非常需要耐心、回报周期相当长的事情。可是哪里有免费的午餐呢?
后记
经过一番梳理,小王发现自己虽然也都有了一定的基础,但平常的训练与自我提升还不够有目的性。经过和老刘的探讨,小王决定一边继续进行上述练习,一边也开始由浅入深的练习架构设计,架构师的大门从此向小王缓缓打开——
最后更新于