阿里云毕玄:我的十年技术感悟
来源:阿里云官方账号

我的程序员起步比同龄人都晚了很多,更不用说跟现在的年轻人比了。我大学读的是生物专业,在上大学前,算是完全没接触过计算机。
到大二后,买了一些书开始学习当时最火的网页三剑客,学会了手写HTML、PS的基本玩法,课余、暑假也能开始给人做做网站。
后来开始学ASP,写些简单的CRUD,做做留言板、论坛这些动态程序,应该算是在这个阶段接触编程了。
毕业后加入了深圳的一家做政府行业软件的公司,跟了一个非常靠谱和给我空间的Leader,使我在那几年有了不错的成长,终于成了一个职业的程序员。
作为程序员,最重要的能力始终是编程能力,就我自己的感受而言,我觉得编程能力的成长主要有这么几个部分。


  • 编程能力初级:会用


编程,首先都是从学习编程语言的基本知识学起的。我比较建议在刚刚开始学一门编程语言的时候,看看编程语言的一些文档就好,不要上来就去看一些高阶的书。我当年学Java的时候,一上来就看Think in Java、Effective Java之类的,真心好难懂。
除了看文档以外,编程是个超级实践的活,所以一定要多写代码。很多人会说,由于写代码都是高度依赖IDE的,导致手写很难,但我绝对相信,写代码写了很多的人,手写一段不是太复杂的可运行的代码是不难的。
我觉得编程能力初级这个阶段对于大部分程序员来说都不会是问题,勤学苦练,是这个阶段的核心。


  • 编程能力中级:会查和避免问题

除了初级要掌握的会熟练地使用编程语言去解决问题外,中级我觉得首先是提升查问题的能力。
在写代码的过程中,出问题是非常正常的,怎么有效且高效地排查问题,才是一个程序员体现编程能力的关键。
解决问题能力强,很容易在程序员群体里得到很高的认可。
在查问题的能力上,首先要掌握的是一些基本的调试技巧,好用的调试工具,就像在Java里JDK自带的jstat、jmap、jinfo,不在JDK里的mat、gperf、btrace等。
除了调试技巧和工具外,查问题的更高境界会和编程能力的高级阶段有非常大的关系,就是懂原理。
就像我自己,排查问题能力的提升主要是在2009年和2010年,那两年作为“淘宝消防队”(处理各种问题和故障的虚拟团队)的成员,处理了很多的故障和问题。
当时“消防队”还有阿里最公认的技术大神——多隆,向他学习到了很多排查问题的技巧,和他比,我排查问题的能力就是初级的那种。
我印象最深刻的是有一次我们一起查一个应用CPU us高的问题。我们定位到一段代码在某种输入参数的时候会造成CPU us高的原因后,我能想到的继续查的方法是去生产环境抓输入参数,然后再用参数来本地debug看是什么原因。但多隆在看了一会那段代码后,给了我一个输入参数,我拿这个参数一运行,果然CPU us很高。
而且,这种case不是一次两次,所以我经常和别人说,我是需要有问题场景才能排查出问题的,但多隆是完全有可能直接看代码就能看出问题的,这是本质的差距。
除了查问题外,更厉害的程序员是在写代码的过程就会很好地去避免问题。
举一个小case大家感受下。当年有一个严重故障,最后查出的原因是输入的参数里有一个是数组,把这个数组里的值作为参数去查数据库,结果前面输入了一个很大的数组,导致从数据库查了大量的数据,内存溢出了。
很多程序员现在看都会明白对入参、出参的保护check,但类似这样的case在我自己排查问题的经历里真的碰到了好多。
在中级这个阶段,我会推荐大家尽可能多地、刻意地去培养下自己这两个方面的能力,成为一个能写出高质量代码、有效排查问题的优秀程序员。


  • 编程能力高级:懂高级API和原理

就我自己的经历而言,我是在写了多年的Java代码后,才开始真正更细致地学习和掌握Java的一些更高级的API。我相信多数Java程序员也是如此。
我算是从2003年开始用Java写商业系统的代码,但直到2007年加入淘宝后,才开始非常认真地学习Java的IO通信、并发这些部分的API。尽管以前也学过,也写过一些这样的代码,但完全就是皮毛。
当然,这些通常来说有很大部分的原因会是工作的相关性,多数的写业务系统的程序员可能基本就不需要用到这些,所以导致很难懂这些相对高级一些的API。但这些API对真正地理解一门编程语言,我觉得至关重要。
在之前的关于程序员成长路线的文章里,我也讲到了这个部分,在没有场景的情况下,只能靠自己去创造场景来学习。
我觉得只要有足够的兴趣,这个问题还是不大的,毕竟现在有各种开源,这些是可以非常好地帮助自己创造机会学习的。例如学Java NIO,可以自己基于NIO包一个框架,然后对比Netty,看看哪些写的是不如Netty的,这样会非常有助于真正地理解。
在学习高级API以及排查问题的过程中,我自己越来越明白懂编程语言的运行原理是非常重要的。因此,到了后面的阶段,我开始学习Java的编译机制、内存管理、线程机制等。对于我这种非科班出身的而言,学这些会更难一些,因为缺乏基础。但这些更原理性的东西学会了后,编程能力会有质的提升,包括以后学习其他编程语言的能力。
学这些原理最好的方法我觉得是先看看一些讲相关知识的书,然后去翻看源码,这样才能真正更好地掌握。
最后是在写代码、查问题的过程中多结合掌握的原理,才能做到即使在N年后也不会忘。
在编程能力的成长上,我觉得没什么捷径,非常赞同1万小时理论,在中级、高级阶段,如果有人指点或和优秀的程序员们共事,会好非常多。我觉得这个和读书也有点像,到了一定阶段后(例如高中),天分会成为最重要的分水岭。不过,就和大部分行业一样,大部分情况下都还没到拼天分的时候,只需要拼勤奋就好。


  • 系统设计能力的成长

除了少数程序员会进入专深的领域,例如Linux Kernel、JVM,其他多数的程序员除了编程能力的成长外,也会越来越需要在系统设计能力上成长。
通常一个编程能力不错的程序员,在一定阶段后就会开始承担一个模块的工作,进而承担一个子系统、系统、跨多领域的更大系统等。
在阿里有一次做分享,讲到我在系统设计能力方面的成长,主要是因为三段经历,负责专业领域系统的设计>负责跨专业领域的专业系统的设计> 负责阿里电商系统架构级改造的设计。

第一段经历,是我负责HSF。

HSF是一个从0开始打造的系统,它主要是作为支撑服务化的框架,是个非常专业领域的系统,放在整个淘宝电商的大系统来看,其实它就是一个很小的子系统。
这段经历里让我最深刻的有三点:
1)要设计好这种非常专业领域的系统,专业的知识深度是非常重要的。我在最早设计HSF的几个框的时候,是没有设计好服务消费者/提供者要怎么和现有框架结合的,在设计负载均衡这个部分也反复了几次,这个主要是因为自己当时对这个领域掌握不深。
2)太技术化。在HSF的阶段,出于情怀,在一个版本里投入了非常大的精力去引进OSGi,以及去做动态化,后来事实证明这是个非常非常错误的决定,我这才真正明白,在设计系统时一定要想清楚目标,而目标很重要的是和公司发展阶段结合。
3)可持续性。作为一个要在生产环境持续运行很多年的系统,怎样在未来更可持续地发展,这个对设计阶段来说至关重要。这里最low的例子是最早设计HSF协议的时候,协议里竟然没有版本号,导致后来升级都特别复杂;最典型的例子是HSF在早期缺乏服务Tracing这方面的设计,导致后面发现了这个地方非常重要后,全部落地花了长达几年的时间;又例如HSF早期缺乏Filter Chain的设计,导致很多扩展、定制化做起来非常不方便。

第二段经历,是做T4。

T4是基于LXC的阿里容器,它和HSF不同的是,它其实是一个跨多领域的系统,包括了单机上的容器引擎、容器管理系统、容器管理系统对外提供API,其他系统或用户通过这个来管理容器,这个系统发展过程也是各种犯错。
犯错的主要原因也是因为领域掌握不深,在做T4的日子里,学到的最重要的是怎么去设计这种跨多个专业领域的系统,怎么更好地划分模块的职责,设计交互逻辑。
这段经历对我自己更为重要的意义是我有了做更大一些系统的架构的信心。

第三段经历,是做阿里电商的异地多活。

这对我来说是真正地去做一个巨大系统的架构师,尽管我以前做HSF的时候参与了淘宝电商从2.0到3.0的重大技术改造。
但参与和自己主导是有很大区别的,这个架构改造涉及到了阿里电商众多不同专业领域的技术团队,在这个阶段,我学会的最主要的:
1)子系统职责划分。在这种超大的技术方案中,很容易出现某些部分的职责重叠和冲突,这个时候怎么去划分子系统就非常重要了。作为大架构师,这个时候要从团队的职责、团队的可持续性上去选择团队。
2)大架构师最主要的职责是控制系统风险,对于这种超大系统,一定是多个专业领域的架构师和大架构师共同设计。怎么确保在执行的过程中控制住对于系统而言最重要的风险,这是我真正理解什么叫系统设计文档里设计原则的部分。
设计原则我自己觉得就是用来确保各个子系统在设计时都会遵循和考虑的,一定不能是虚的东西。例如在异地多活架构里,最重要的是如何控制数据风险,这个需要在原则里写上,最基本的原则是可接受系统不可用,但也要保障数据一致。而我看过更多的系统设计里设计原则只是写写的或者千篇一律的。
设计原则切实地体现了架构师对目标的理解、技术方案层面上的选择原则,并确保在细节的设计方案里有对于设计原则的承接以及执行。
3)考虑问题的全面性。像异地多活这种大架构改造,涉及业务层面、各种基础技术层面、基础设施层面,对于执行节奏的决定要综合考虑人力投入、机器成本、基础设施布局诉求、稳定性控制等,这会比只是做一个小的系统的设计复杂非常多。
d052a50123334f02a142ea7f93596e11?from=pc.jpg
我认为程序员的价值关键体现在作品上,被打上作品标签是一种很大的荣幸。我觉得,作品影响程度的大小决定了金字塔的层次,所以我会这么去理解程序员的金字塔。
当然,要打造一款作品,仅有上面的两点能力是不够的,作品里很重要的一点是对业务、技术趋势的判断。希望作为程序员的大伙儿,都能有机会打造一款世界级的作品,去为技术圈的发展做出贡献。
由于目前IT技术更新速度是很快的,程序员这个行当是特别需要学习能力的,我一直认为,只有对程序员这个职业真正充满兴趣、保持自驱,才有可能在这个职业上做好。