您当前的位置: 首页 > 

凌云时刻

暂无认证

  • 1浏览

    0关注

    1437博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

一个程序员的成长进阶路径

凌云时刻 发布时间:2021-07-16 19:00:00 ,浏览量:1

凌云时刻

编者按:从业余爱好者到职业程序员,从编程能力到系统设计能力,作者通过亲身经历讲述了程序员硬实力的能力成长路线,案例详实丰富,希望对各位读者有所帮助。

从业余程序员到职业程序员

程序员刚入行时,我觉得最重要的是把自己培养成职业的程序员。

我大学读的是生物专业,在上大学前基本算是完全没接触过计算机,军训的时候因为很无聊,我和室友每天跑去学校的机房玩。

直到现在我都还印象很深刻,第一次走进机房的时候,别人问你是要玩windows还是dos,我那是完全的两眼一抹黑。后来只记得在机房一堆人都是在练习盲打,军训完盲打也练得差不多了,对计算机就这么产生了浓厚的兴趣。

大一的时候都是玩组装机,捣鼓了一通,对计算机硬件有了一些了解。到大二后,买了一些书开始学习当时最火的网页三剑客,学会了手写HTML、PS的基本玩法,课余、暑假也能开始给人做做网站什么的(PS: 那时候做网站真的好赚钱)。

这样过了一年左右,做静态的网页就不好赚钱了,也不好找实习工作,于是就开始学asp,写些简单的CRUD,做做留言板、论坛这些动态程序,应该算是在这个阶段接触编程了。

毕业后加入了深圳一家做政府行业软件的公司,很幸运遇到一个非常靠谱并且给我空间的Leader,终于让自己成长为了一个职业的程序员。

通常来说,业余或半职业的程序员,多数是一个人或者很小的团队一起开发,在开发流程、协作工具(例如jira、cvs/svn/git等)、测试上通常会有很大的欠缺,而职业的程序员在这方面则会专业很多。另外,通常职业程序员做的系统都要运行较长的时间,所以在可维护性上会特别注意,这点我是在加入阿里后理解更深的,一个运行10年的系统,和一个写来玩玩的系统显然是有非常大差别的。

这块自己感觉也很难讲清楚,只能说模模糊糊有个这样的概念,通常在有兴趣的基础上,从业余程序员跨越到成为职业程序员我觉得不会太难。

编程能力的成长

作为程序员,最重要的能力始终是编程能力,就我自己的感受而言,我觉得编程能力的成长主要有这么三个部分。

 编程能力初级:会用

编程,首先都是从学习编程语言的基本知识开始的,不论是什么编程语言,都有很多共同的基本知识,例如怎么写第一个Hello World、if/while/for、变量等,因此我比较建议在刚开始学一门编程语言的时候,先看看编程语言的一些文档就好,而不是上来就去看一些高阶的书。我当年学Java的时候上来就看Think in Java、Effective Java之类的,真心好难懂。

除了看文档以外,编程是个超级讲究实践的活儿,所以一定要多写代码,只有这样才能真正熟练起来,这也是为什么我觉得让面试者手写代码很重要的原因,这个过程是非常容易判断写代码的熟悉程度的。

很多人会说由于写代码都是高度依赖IDE的,导致手写很难,但我绝对相信写代码写了很多的人,手写一段不是太复杂的可运行代码是不难的,即使像我这种三年多没写过代码的人,让我现在手写一段不太复杂的可运行的Java程序,还是没问题的,前面N年的写代码生涯使得很多东西已经深入骨髓了。

我觉得编程能力初级这个阶段对于大部分程序员来说都不会是问题,勤学苦练,是这个阶段的核心。

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

除了要掌握熟练使用编程语言去解决问题的初级能力之外,中级我觉得首先是提升查问题的能力。

写代码的过程中出问题是非常正常的,怎么有效且高效地排查问题,这在程序员群体中是能感受到大家编程能力差距的,解决问题能力强的基本很容易在程序员群体里得到很高的认可。

在查问题的能力上,首先要掌握的是一些基本的调试技巧,好用的调试工具,就像在Java里JDK自带的jstat、jmap、jinfo,不在JDK里的mat、gperf、btrace等,工欲善其事必先利其器,在查问题上是非常典型的。有些时候大家在查问题时的能力差距,有可能仅仅是因为别人比你多知道一个工具而已。

除了调试技巧和工具外,查问题的更高境界和编程能力的高级阶段有非常大的关系,就是要懂原理。一个懂原理的程序员在查问题的水平上是有明显差距的,我想很多的同学应该能感受到,有些时候查出问题的原因仅仅是因为有效的工具,知其然不知其所以然。

我给很多阿里同学培训过Java排查问题的方法,在这个培训里,我经常也会讲到查问题能力的培养最主要的也是熟练,多尝试给自己写一些会出问题的程序,多积极地看别人是怎么查问题的,多积极地去参与排查问题,很多最后查问题能力强的人多数仅仅是因为“无他,但手熟尔。”

就像我自己,排查问题能力的提升主要是在2009年和2010年,那两年作为淘宝消防队(处理各种问题和故障的虚拟团队)成员处理了很多的故障和问题,当时消防队还有阿里最公认的技术大神多隆,向他学习到了很多排查问题的技巧。和他比,我排查问题的能力就是初级的那种。

我印象最深刻的是有一次我们一起查一个应用cpu us高的问题,我们两定位到是一段代码在某种输入参数的时候会造成cpu us高的原因后,我能想到的继续查的方法是去生产环境抓输入参数,然后再用参数来本地debug看是什么原因,但多隆在看了一会那段代码后,给了我一个输入参数,我拿这个参数一运行,果然cpu us很高……哎,而且这种case不是一次两次,所以我经常和别人说,我是需要有问题场景才能排查出问题的,但多隆是完全有可能直接看代码就能看出问题的,这是本质的差距。

除了查问题外,更厉害的程序员是在写代码的过程就会很好地去避免问题。写一段正向逻辑的代码,大部分情况下即使有差距,也不会太大,但怎么很好地处理这个过程中有可能出现的异常上,这个时候的功力差距会非常明显,很多时候一段代码里处理异常逻辑的部分都会超过正常逻辑的代码量。

我经常说,一个优秀程序员和普通程序员的差距,很多时候压根就不需要看什么满天飞的架构图,而只用show一小段代码就可以。在中级这个阶段,我推荐大家尽可能刻意地培养下自己这两个方面的能力,成为一个能写出高质量代码、有效排查问题的优秀程序员。

 编程能力高级:懂高级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. 要设计好这种非常专业领域的系统,专业的知识深度是非常重要的; 2. 在设计系统时一定要想清楚目标,而目标很重要的是和公司发展阶段结合; 3. 作为一个要在生产环境持续运行很多年的系统而言,怎么样让其在未来更可持续地发展,这个对设计阶段来说至关重要。  第二段经历,是做T4,学到最重要的是怎么去设计这种跨多个专业领域的系统,怎么更好地划分模块职责、设计交互逻辑,这段经历对我自己更为重要的意义是我有了做更大一些系统架构的信心。  第三段经历,是做阿里电商的异地多活,这对我来说是真正地去做一个巨大系统的架构师,这个架构改造涉及到了阿里电商众多不同专业领域的技术团队,在这个阶段,我学会最主要的是: 1. 子系统职责划分,在这种超大的技术方案中,很容易出现某些部分的职责重叠和冲突,这个时候怎么去划分子系统,就非常重要了,作为大架构师,这个时候要从团队的职责、团队的可持续性上去选择团队;

2. 大架构师最主要的职责是控制系统风险,对于这种超大系统,一定是多个专业领域的架构师和大架构师共同设计,怎么确保在执行的过程中对于系统而言最重要的风险能够被控制住,这是我真正的理解什么叫系统设计文档里设计原则的部分,设计原则我自己觉得就是用来确保各个子系统在设计时都会遵循和考虑的,一定不能是虚的东西;

3. 考虑问题的全面性,像异地多活这种大架构改造,涉及业务层面、各种基础技术层面、基础设施层面,对于执行节奏的决定要综合考虑人力投入、机器成本、基础设施布局诉求、稳定性控制等,这会比只是做一个小的系统的设计复杂非常多。

系统设计能力的成长,我觉得最重要的是先在一两个技术领域做到专业,然后尽量扩大自己的知识广度,例如除了自己的代码部分外,还应该知道具体是怎么部署的,部署到哪去了,部署的环境具体是怎么样的,和整个系统的关系是什么样的。

像我自己,是在加入基础设施团队后才更加明白有些时候软件上做的一个决策,会导致基础设施上巨大的硬件、网络或机房的投入,但其实有可能只需要在软件上做些调整就可以避免,做做研发、做做运维可能是比较好的把知识广度扩大的方法。

第二点是练习自己做tradeoff的能力,这个比较难,做tradeoff这事需要综合各种因素做选择,但这也是所有的架构师最关键的,可以回头反思下自己在做各种系统设计时做出的tradeoff是什么,这个最好是亲身经历,听一些有经验的架构师分享他们选择背后的逻辑也会很有帮助,尤其是如果恰好你也在同样的挑战阶段。

总结

我认为程序员的价值关键体现在作品上,被打上作品标签是一种很大的荣幸。

当然,要打造一款作品,很重要的一点是对业务、技术趋势的判断,希望作为程序员的大家,能有机会去打造影响公司级、中国级甚至世界级别的作品,去为技术圈的发展做出贡献。

由于IT技术更新速度还是很快的,程序员这个行当是特别需要学习能力的,我一直认为,只有对程序员这个职业真正充满兴趣,保持自驱,才有可能在这个职业上做好,否则的话是很容易淘汰的。

你可能还想看

1. 从Java到Go语言,我是这么入门的 2. “一云多Region”究竟能为企业解决什么问题? 3. 当Java遇上机密计算 4. 智能告警——企业IT系统神经中枢 5. 工作7年,我的10条经验总结

END

关注「凌云时刻」

每日收获前沿技术与科技洞见

关注
打赏
1663816507
查看更多评论
立即登录/注册

微信扫码登录

0.0410s