一转眼从学校毕业已经超过10年了,从一名普通的程序员成长为500强企业的架构师,如今也开始做IT管理工作,可以算是一个过来人。前两天公司一位初入职场的同事希望我给一些建议与经验。我觉得这个话题很有价值,这里以个人的想法与经历写成此文,希望给年轻的开发者们一些启发。
我工作过的公司有4家,NVIDIA, google, SlIDE和Glow。其中两家是知名的大公司,Slide我是D轮过后加入的,那时约150人。Glow则是从它第一天创立,一直走到现在。个人的工作也从Developer,Tech Lead,Engineering Manager到CTO。这些经历使我对程序员的个人发展之路有比较全面的看法。这一路走来,自己有一些感悟,也看到其他人的一些经验教训,对于如何掌控自己的职业生涯,总结了些建议,希望对那些处在迷茫中的年轻朋友们有些许帮助。
工作前三年是职业生涯中成长最快的几年,在这段时间里你会充满激情,做事专注,也容易养成良好的习惯。在我们公司有些同学在前三年中就快速成为某一个领域的技术专家,有些同学也可能止步不前。
如果你问一个年轻的前端开发人员,你在今后的3年内如何提升自己的能力?他可能会说“我现在对Web前端比较熟悉,但我想深入了解AngularJS,另外React现在发展的很快我也想看一下。之后,我会花时间去学习IOS和Android开发。”看上去不错,但缺乏系统性的目标。或者说,他制定了学什么,但对为什么要学这些并没有仔细地思考。
在技术领域,有太多的东西会迅速地过时,如何利用有限时间,最大化你的长期收益?
学习方法
1:掌握良好的学习心态
2:掌握系统化的学习方法
3:知识如何内化成能力
4:广度和深度的选择
实战技巧
1:你需要学会的编码习惯
2:在业务团队做开发如何成长
打造你的工具箱
工欲善其事,必先利其器。每个开发者都应该有一把自己的瑞士军刀,在将来漫长的职业生涯中,这些工具可以为你省下宝贵的时间,并帮助你更好的组织个人知识库。举两个例子
空杯心态
首先要有空杯的学习心态,而不是傲娇自满,故步自封,空杯子才可以装下更多的东西。首先要学会取百家之长,带着欣赏的眼光看团队的同事或学校的同学,欣赏每位同事或同学的优点,然后吸取他们的优点,每个同事都有其擅长的能力,比如有的同事技术能力强,那么可以观察下他如何学习的(或者找他请教学习方法),有的同学擅长解决线上问题,那么观察他是如何解决线上问题的,解决思路是什么?如果他解决不了时,他是如何寻求帮助。有的同学擅长使用IDE或mac的快捷键,那么可以向他学习提高工作效率。有的同学能快速理解业务知识,观察他是如何做到的,自己如何达到他的程度。沟通能力,解决问题能力以及规划能力都可以向同事学习。
挑战权威
从书上看到一个知识点,或者从别人那里听到一个知识点,一定要去挑战和质疑这个知识点的正确性,否则学到的知识点可能是错误的。先用逻辑思维推测下,再实战检测下,一定要记住实践是检验真理的唯一标准。比如同事说这个SQL加这个索引是最快的,首先要思考同事的结论是如何得出的,是靠历史经验还是测试过,如果我们没有经验,就加上这个索引跑下SQL,看看执行计划和执行时间,再换下其他索引试试会不会更快。依次类推,并发一定比串行快吗?无锁一定比加锁快吗? 很多结论都是在特定的场景下才会产生的,一定要自己亲手实践验证下。
坚持学习
有的同学可能工作了五年,但是学习的时间可能一年都不到。学技术不能急于求成,只要学习方法正确,量变一定会引起质变。我在大学刚学JAVA时,怎么都学不会,但是坚持学习了几个月,每天看张老师的JAVA视频教学,买书按照书里的代码一行一行的敲代码,白天睡觉,晚上学习和写代码,写到宿舍关灯时就去避风塘呆一晚上,早上6点钟回宿舍睡觉,学到一定时间后,突然恍然大悟,才入了门。
在工作中,我曾经花了一个月的时间学习AOP的实现原理,学习了各种方式来实现AOP的原理,并写了几种实现方式的代码,虽然花的时间很多,但是到现在仍记忆犹新,对于排查问题和学习其他知识都非常有帮助。
要做到坚持学习,学习的环境非常重要。如果你想学,但是又不在学习状态,可以考虑换个学习环境,我经常会去星巴克看书和学习。我听说有的同事会周末抽一天去大学教师上自习。
把事做精
对自己要求越高,进步越快。要有强烈的把事情做完美的心态,我刚开始工作的时候,总是快而不精,做事做得不够细致,总希望快速拿出结果证明自己,但是反而证明不了什么,技术能力也得不到提升,缺少技术亮点,在团队中也没什么影响力,后面就开始锻炼一次就把事情做对的心态和方法。我观察过,很多人都擅长快速做事情,但是把事情做好做精致的人会比较少,但是结果却是 在精益求精的路上才会快速提高自己的能力 。比如用100行代码实现的功能,思考下是否可以用10行来实现,以便于降低运维成本,提高下次的编码效率。引用GUAVA等类库,提取公共方法,和使用JDK8新特性等。系统的方法压测过后,单机只能承受1700QPS,可以思考和实践能否优化下程序提高QPS,减少服务器数量。
把事情做精,一定是要强迫自己多花心思多花时间在这件事情上。有位技术牛人给我分享了一个心得,我觉得说得非常好,老板给你布置了一个任务, 你要花百分之150的精力做到100分,这样在老板那里你就能拿到80分或者60分 。
广度和深度的选择
技术人员的学习路径有两个维度,深度和广度。很多程序员都有这个疑问,是先深后广,还是先广后深呢?
通过这么多年的学习和思考,我的建议先深后广,因为当技术学到一定深度后,就会有触类旁通的能力,自己掌握的广度也自然有了深度。但是在实际学习过程中,深度和广度相互穿插着学习,比如学习并发编程时,首先学习JDK源码,然后学进去之后,开始看JVM源码,最后看CPU架构,在技术点逐渐深度研究的过程中,广度也得到了完善。
所以无论哪种学习方式,学习态度才是最重要的,在广度学习的时候有深入研究的态度就能达到一定的深度,在深度学习的时候,主动学习相关的技术点,广度也得到拓宽。
高效的开发环境
我们可以从编缉器谈起,这里有IDE vs Text Editor,有Vim vs Emacs,有Sublime vs Atom,那该如何选择呢?在做选择之前,我们先想想自己的目标。我们希望这是一个长期的投资,这款编缉器能被长期使用,在这个过程不断地打磨,使其能完全适合自己的习惯,最大化编缉效率。如果程序员是侠客,编缉器则是他手中的剑。
虽然我是Vim的重度用户,但我觉得当年选择Vim时有欠考虑。如果让我重选一次,我的第一选择会是Emacs,第二选择会是Atom。Emacs已存在30年,社区仍然活跃,其可扩展性在编缉器中无人能出其右。Emacs的脚本语言elisp又是lisp的一种dialect,我觉得对lisp的学习可以提升程序员对编程核心思想的理解。另一个加分点是Emacs由于其本身的高门槛及lisp特质,吸引了大批高质素的程序员,其社区可谓藏龙卧虎,更诞生了像Org-mode这样神级的插件。反观Vim,Vim的精髓在于Mode editing,这是值得学习的,可以极大提高文本编缉的效率。
但当你熟悉了这一理念后,我觉得可以转投其他编缉器,因为Vim的架构与Vimscript限制了其扩展性。Emacs通过Evil插件非常完整的支持了Mode editing,其他主流的编辑器也有类似插件,所以你一旦掌握了这个理念,在别的编辑器中也可以发挥作用。可能有人会说没有一个Vim emulator能做到Vim 100%的功能,但重点不在于某条指令是否被移植,而是mode editing思想的精髓能否被移植,我觉得答案是肯定的。
再看Atom vs Sublime,Atom的可扩展性非常好,它的大部分核心功能也是以插件的方式实现,这点与Emacs有异曲同工之妙。并且其开源的特性,使我相信它有比Sublime更持久的生命力。
关于IDE,我的看法是,我不排斥IDE,但每个IDE都是为了某个特定的任务或是编程语言服务的。做为一个有追求的程序员,可以用IDE,但依然需要精通一个强大的通用编缉器。
类似编缉器,高效的开发环境还包括Shell,Launcher,窗口管理器,文档阅读器等等。其中有一部分只需要你化很少的时间就可以完成配置,它们的投资回报率是非常高。
信息采集器和笔记本
前者是用来收集别人产生的信息,后者则是收集自己产生的信息。前者一个简单的例子就是浏览器的Bookmark。你需要能随时将一组有用的信息归档,并在未来的某个时刻快速找到它。后者最直观的例子则是Mac OS或是iOS自带的笔记本,这里的目的是能随时随地记录你自己的想法。从本质上讲,就是你需要有一套好用的工具来做你的知识库管理(Knowledge management),也可以说是你知识和思想的外部备份。我个人现在是用Evernote同时来做信息采集与笔记的。如果有一个好的流程,你也完全可以用两个工具来分别把这两件事做好。但我建议你花足够多的时间来思考如何组织你的个人知识库。
以上只是两个典型的例子,你需要做的是发现那些你要长期从事的任务(往往不随技术而改变,也不随公司而改变),将完成这些任务所需的工具调整至最优。再举一个例子,我会留意身边的程序员所用的键盘。只有少部分的程序员会买高端的静电容键盘,比如HHKB。而在我看来,这明显是一笔很划得来的投资,程序员在工作的大部分时间里都需要和键盘打交道,一个舒适的打字体验是非常有收益的,更何况这类高品质的键盘都非常的耐用。
你需要学会的编码习惯
程序员应该学会通过技术的手段来提高效率。几个常用的手段是使用工具,快捷键和编写脚本。
使用各种工具
技术人员电脑尽量用MAC,使用命令行效率一定比在 10241024 像素中找一个 1010 像素的按钮更快。IDE用IDEA,比Eclipse更智能。命令行工具用iTerm和IDEA里的Terminal。写文章用MAC的客户端工具MacDown,左边编写,右边展示,比word等工具方便快速很多。有时候我还会用按键精灵里配置脚本需要解决工作问题,比如通过点击我们的系统,来执行任务。这样的工具很多,只要能提高工作效率的工具,大家都可以尝试使用。
使用快捷键
MAC,IDEA和Eclipse有很多快捷键都要学会使用,比如在MAC命令行中通过idea .快速打开工程,通过open . 快速的打开文件夹,把IDEA里通过快捷键把一段代码抽成一个单独的方法,快速生成getter setter方法。
用脚本写工具
当我们用人工的方式做一件重复性很强的事情,首先要考虑使用工具来帮我们自动完成,如果没有类似工具,可以自己写个脚本来实现,这样除了能快速解决问题,还能提高自己的技术能力。
比如,我经常要在两个maven仓库发布jar包,我就写了个脚本来实现jar包的发布, deploy.sh代码如下:
cp pom.xml pom.xml.bakrm pom.xmlln -s pom-2-deploy.xml pom.xmlmvn deployrm -rf pom.xmlcp pom.xml.bak pom.xmlrm pom.xml.bak
在业务团队做开发如何成长
我一直在业务团队中做开发,在业务团队最主要的提高的能力是业务抽象和架构能力,通过业务场景,不断思考如何通过合理的架构和业务抽象能快速支持业务,降低运维成本。同时在这个过程中锻炼技术能力,比如写一些技术框架来快速支持业务,做到技术驱动业务。
可配置化的方式支持业务
设计业务的领域模型,把不随着业务逻辑变化的领域模型做成系统能力,把随着业务逻辑变化功能,做成可配置化,上一个新业务,通过配置的方式或少量开发就能支持。
在做客户后台功能时,由于需要展示的数据种类非常多,每种数据展示可能需要花费几天的时间,所以设计了一个通用的技术框架,实现了通过配置化的方式展示各种数据。
写框架解决业务问题
我在上家公司经常做一些CRUD的业务功能,我就自己开发了一个快速做CRUD的框架 jdbcutil,通过配置实体生成SQL语句,实现了子类只要继承父类,就自动拥有CRUD的能力。后面还写过生成CRUD页面代码的程序。
目前我们团队在做的TITAN框架通过模块化开发的方式,解决易变的业务系统在多人开发时遇到的问题。
技术驱动业务
在业务团队,一定要不断的思考如何利用技术来支持快速支持业务,配置化是一种思路,但是有些功能配置复杂度比较高,配置加验证的工作量,可能需要一个星期的时间,那么能不能减少人工配置,实现系统自动化配置,于是可以研究下人工智能,通过人工智能的方式实现,系统告诉人需要配置哪些东西,然后交给人来进行确认,这样可以大大减少人工成本,更快的支持业务。
系统化学习不断的提升自己的能力
掌握系统化的学习方法
如果学习到的知识不成体系,那么遇到问题时就会非常难解决。有些同学会出现这些情况,比如编码时遇到问题百度搜索,如果百度上找不到答案,这个问题就解决不了。再比如,在开发中要用到某个技术点,就学习下API,程序调通后就不再深入研究,浅尝辄止,如果程序遇到其他问题也不知道如何解决。
以上情况我认为叫 点状学习 。遇到一个问题,解决一个问题,需要一项技术,学习一项技术。那么如何由点到面,由面到体,形成系统化学习呢。
首先要确定学习的知识领域,需要达成的学习目标,针对目标制定学习计划,就像你要写一本书一样,先把目录写出来,然后根据目录上的知识点逐步去学习,最后把这些知识点关联起来,形成一个系统化的知识体系。学习的时候,可以制定一个计划,以周为单位,比如第一周学什么,第二周学什么。
有不少朋友会问,那怎么算系统化学习,系统化学习还要系统学习哪些Java相关的技术,这里我也分享自己收集的系统的学习资料,互联网Java技术学习路线图,真心的希望能帮助到大家。架构师必须具备的一些技术总结出来一套思维导图和录制了一些相关视频,分享给大家,供大家参考。感兴趣的铁子们可以后台私信【架构】免费获取高清知识体系思维导图及相关资料。
一:常见模式与工具
学习Java技术体系,设计模式,流行的框架与组件是必不可少的:
常见的设计模式,编码必备
Spring5,做应用必不可少的最新框架
MyBatis,玩数据库必不可少的组件
二:工程化与工具
工欲善其事必先利其器,不管是小白,还是资深开发,玩Java技术体系,选择好的工具,提升开发效率和团队协作效率,是必不可少的:
Maven,项目管理
Jenkins,持续集成
Sonar,代码质量管理
Git,版本管理
三:分布式架构
高并发,高可用,海量数据,没有分布式的架构知识肯定是玩不转的:
分布式架构原理
分布式架构策略
分布式中间件
分布式架构实战
四:微服务架构
业务越来越复杂,服务分层,微服务架构是架构升级的必由之路,Java技术体系,和微服务相关的技术有哪些呢?
微服务框架
Spring Cloud
Docker与虚拟化
微服务架构
五:性能优化
任何脱离细节的ppt架构师都是耍流氓,向上能运筹帷幄,向下能解决一线性能问题,Java技术体系,需要了解:
性能指标体系
JVM调优
Web调优
DB调优
六:底层知识
从架构设计,到应用层调优,再深入了解底层原理,扎实的Java基本功才能让自己变为扫地神僧:
内存模型
并发模式
线程模型
锁细节
我觉得步入职场的前3年对今后的发展尤其重要, 所以,大家如果想往技术路上走的,想成为架构师的,一定要保持终生学习的态度,让学习力成为核心竞争力,才能不被时代所淘汰,知易行难,知道了上面的一些经验,并不代表年轻程序员们就能马上成功,毕竟这需要一个凤凰涅槃和实践的过程,但是肯定能帮助有志于于此的年轻程序员们少走一些弯路。希望此文能对年轻的程序员们有所帮助。
最后
希望大家能从文章中得到帮助获得收获,也可以评论出你想看哪方面的技术。文章会持续更新,希望能帮助到大家,哪怕是让你灵光一现。喜欢的朋友可以点点赞和关注,也可以分享出去让更多的人看见,一起努力一起进步!