如何提升技术水平?
本文主要是从笔者的经验出发,分享下对提升技术水平的看法。所谓因材施教、因地制宜,下文分享的方法不一定适合你,所以读者们取其精髓、去其糟粕吧,哪怕其中只有一两点你觉得受用,那我就很高兴了。
阅读对象:本文适用于刚毕业不久的新人、知识面较窄的工程同学、能胜任目前工作但感觉无挑战的同学、忙于工作感觉自己没有时间提升的同学等等。
# 前言
还记得2008年,刚参加工作时,啥都不会,一张白纸,一问三不知,一点点慢慢摸索、研究,那段时光很幸福,能感受到自己每天都在进步,每天都会学到新的知识。也曾非常苦闷,思索如何进一步提升自己的技术水平呢?到后来,技术上一次又一次遇到瓶颈,再突破瓶颈,并没有因为一次次的突破而感觉满足,反倒越来越感觉自己会的技术太少,更要虚心地学习。我总结出了一些提升技术水平的方法,下面一一分享。
# 大部分人在为懒惰找借口
有时,技术同学之间交流:过去一年,你觉得自己有哪些进步呀?经常会听到这样的回答:需求太多,工作太忙,感觉自己没啥大的进步。我们会听到各种各样的理由,比如:
# 1. 没时间是最大的借口
没时间吃早饭、没时间运动、没时间回去看望亲人、没时间去Review代码、没时间去调查线上Bug。。。这都是最常用的借口。再或者:等忙过了这一阵我就怎么样怎么样。最终结果一般是永远没有去落实。 时间其实是最公平的,每人每天24小时,不多不少。不是没时间,而是没选择而已。因为你潜意识里认为这事不重要,所以就去做了其他更重要的事。
# 2. 我做的工作QPS不太高、数据量不太大,不像xxx业务,很锻炼人
误区:工作挑战不够,每份工作都有自己的挑战,都有死掉N多脑细胞就难以解决的问题。反思下:你现在是否把本职工作做到了最佳?
# 3. 公司的技术培训、技术分享太少了
总有人希望技术培训、分享来提升知识,这是应试教育造成的后遗症,大家习惯了老师把知识灌输到脑子里,而不喜欢自己主动去获取。其实技术分享等,只是穿针引线,大致给你介绍某个东西是什么样的,要深入理解还得靠实践,以赛代练。
# 4. 那不是我该干的,那是前端的活、那是运维的活、那是DBA的活、那是xxx的活
其实你就错失了掌握前端、运维、数据库等知识的大好机会。我们不一定要懂得如何去操作,但是要大致知道这些事该怎么干。
# 5. 你们能不能把需求想的特别清楚了再来找我
技术同学都喜欢清楚的需求,然后自己写代码去实现,但每个需求都清晰是理想状态。提需求的同学又不知道技术细节,他怎么可能每个需求都特别清晰、合理。需求只是手段,不是目的,需求背后要解决的问题才是核心。技术同学应该走出舒适区,更多去了解业务,从而站在技术的角度,提出更好的解决方案,而不是仅仅实现需求。
# 转变思路、加速前进
上面列了很多常用的借口,这些都在制约着你的发展。绝大部分都是思想上的懒惰,待在舒适区,不愿意走出去。那要怎么做才能快速提升自己技术能力呢?
# 1. 转变思路,变被动为主动
你要主动去学习,不要等别人,不要被动学习,思想上首先要转变。青春就那么几年,毕业后的四五年是飞速发展的黄金时期。 需要有些好奇心,直播怎么做的?视频是怎么做的?推荐又是怎么回事?抱着对这些事的好奇心,然后主动去了解,能获取大量知识。 看如下两行代码:
Map<Long, UserCache> userCacheMap = userCacheService.getByIds(uids);
Map<Long, Photo> photoMap = photoService.getByIdsFailFast(photoIds, PhotoGetTimeout.DEFAULT);
2
这两行代码,我大钢厂的Java工程师肯定写过无数遍,熟的不能再熟了。但是你了解过如何实现的吗?如果要计算QPS,这两接口的QPS大的吓死你。这么高的QPS、这么大的数据量,是如何做到的呢?方案是什么,流程是什么。如果没有深入去了解过,还在抱怨工作无挑战的话,那就相当于你守着金山银山却仍在哭穷。并不是真穷,而是缺少发现财富的眼睛。
# 2. 从眼前工作入手,发扬极客精神,做到极致
有同学经常抱怨没有时间去提升、没有提升的方向,也有些同学很主动,买了很多书来看,但是这些书跟工作关系不太大。我的建议就是:把那些跟现有工作关系不大的书通通扔掉,那是在浪费你的时间。知识如海洋,学以致用,如果学到东西没有用,那学来干嘛呢?学的东西立刻能用,才会印象深刻,从而沉淀在你的脑海中。 一个人提升的过程,其实就是不断超越昨天的你的过程。因此,最好、最快速的提升就是从现有工作入手,对自己高标准、严要求,发扬极客精神,把每行代码都吃透,每行代码都精益求精,甚至连一个空格、一个标点符号都让人挑不出毛病来。第一遍写完的代码,自己反复review,直到感觉没啥问题为止。 有同学会说:项目非常紧,我完全没有时间去反复review自己的代码。对,项目紧是一定的,并不是让你去反复review以前的代码,而是在开发新需求的过程中,就把反复review融入进去,养成一种习惯。比如开发一个功能,编码5个小时,反复review反复修改顶多多花你一小时,总共6小时,对项目不会有太大影响。并且随着时间推移,你的代码质量越来越高,review的时间会逐步减少,整体效率也会越来越高,因为第一遍就能写出漂亮的代码了。 说到极致,我们看两个例子,第一个例子:
Map<Long, Integer> statisCount=new HashMap<Long, Integer>();
这是一个Map的定义,平时咱们都写了千百回了,当时看到这行代码我就给他挑了4个毛病。(1) 等号前后无空格;(2)后面的<Long, Integer>多余,写成<>即可;(3)英文全称是statistics,简称一般是stat,而不是statis,这个简称让人困惑;(4) 对于Map的命名,应该用名词,现在的 xxxCount更像是某个计数,只是一个数,并没有突出是个数据结构Map,当下文你看到statisCount.put(1, 2); 时就懵逼了,statisCount应该是++ 操作,怎么就put了呢?!因此叫 statCountMap 更恰当些。
第二个例子:有同学发企业微信不喜欢用标点符号,全用空格,有时会给别人的阅读造成些困难。比如“才哥 在吗”,有时空格可能看不太清,那请问到底是 “才哥在吗?” 还是 “才哥,在吗?” 这两句话是有差别的。不是说希望大家都用标点符号,而是希望用空格的同学,要考虑下对方的阅读体验,不要造成阅读困难,如果一个空格断句有困难的话,你就多加几个空格嘛,比如4个,这样就完美了。
刚才讲写代码,第二个例子是沟通,希望将极客精神发扬到工作中的方方面面,大到做项目、小到说每一句话,都要求精益求精,整个人会给人一种焕然一新的感觉。
# 3. 查故障是个捷径
咱们每天邮件报警上百封,有时也会碰到线上问题,比如CPU较高、流量较高、频繁Full GC、RpcMonitor报警,也会遇到各种Exception,等等。这些其实都是快速提升技术能力的捷径。 查线上问题,会逼你了解上下游业务,逼你深入下去,而不是停留在代码表面,逼你使用各种工具去分析,最终一定会获益良多。 当然,阻碍你进步的拦路虎也会有很多,比如:这个报警是其他小组的,负责人不是我,不关我事,忽略;问题是什么,没查出来,我也不知道,先用其他方式绕过吧,以后再说;DB查的慢是DBA的责任,得找DBA解决,不该我去查,等等等等。这些都是给自己找的借口,应该跨越系统边界,刨根问底,把问题彻底找出来,不找到真相誓不罢休。 另外:运营或者审核同学有时会在群里反馈问题,好多同学的第一反应是:躲!把这些问题当做没看见,或者觉得不是我负责就不管了。其实这都是在错失技术提升的良机!
# 4. 思考、思考、再思考
如果你去澡堂,大家都把衣服扒了,虽有高矮肥瘦,但都差距不大。人和人之间最大的差距,在于脖子以上的部分,也就是你的大脑。训练大脑就只有一种方式:思考。 思考什么内容呢?真正的需求到底是啥,他们要达到什么目的?我的技术方案是最优的吗,有没有改进空间,有没有哪个细节考虑不周,模型的建立上是否合理,是否符合生活中的模型,有没有杀马特的设计?我怎么去描述这个问题,用什么词语最恰当?我之前跟人沟通,有没有用词不当的地方,有没有沟通不到位的地方,做完事后我周知相关人了吗?这几个API的底层实现是什么样的,会不会有性能瓶颈?如果服务挂了一台怎么办,如果量翻了10倍,能抗住吗,如果抗不住我该如何改进呢?等等等等 吾日三省吾身才能不断进步。 咱们又来看个例子:
if (hashSet.contains(userId)) {
// 允许访问
} else {
// 不允许访问
}
2
3
4
5
假设你写了上面的几行代码,那如何描述你做了什么事呢?面对不同的人,比如技术、产品、运营、行政、七大姑八大姨、路边摊烤冷面师傅、爷爷奶奶等等,语言该如何表达呢?
大部分技术同学不管面前是什么人,只会一种解释:我判断用户是否在hashSet中,如果在就放过,如果不在就不让访问。如果对方是技术、产品能听懂,其他人估计就一脸懵逼,觉得这个技术同学很难交流了。
这其实体现一个人对这件事的理解和抽象能力,只有不断思考才能站位不同角度去看待问题。
你可以这么解释:(1) 我做了个白名单,只有白名单中的用户才能访问;(2)我做了个防火墙,只有可信任的人才允许访问,坏蛋或者陌生人拒之门外;(3) 我们对系统的安全性进行了一次升级,必须先授权后访问;(4) 我们对访问权限进行了更严格的控制;(5) 我开发了个电子门卫,门卫认识的人才让进;(6) 我相当于聘请了有个保安,对访客的身份进行严格验证。。。等等。
# 5. 工作上下游全部门儿清
当你对现有的工作了如指掌后,接下来就是要扩充知识广度了。而广度的提升会反过来让你的知识深度更深。方法就是:把工作相关的上下游业务全部理清。 有两个方向:1. 横向,2.纵向 横向是指业务的上下游,也就是数据流的上下游。举例说明:某同学做了热门一审相关的事,上下游就包括:视频如何产生、如何进入推荐系统、推荐系统如何推到热门、再到满足什么条件进入admin审核、审核完后如何通知推荐组、审核不过最后如何从热门中下掉,审核通过后如何在热门获得展示,等等。就是从数据的产生到消费,完整的闭环是什么样的?!最好全部捋清楚,这样,你就不仅仅是在做admin热门一审的需求,而是通过一个需求,把整条业务线都搞清楚,从而在技术方案设计上,就能更好地设计方案了。同时,你的技术知识又得到了一次升华。
纵向是指当前业务运行环境的深入。还是以热门一审为例,纵向包括了:热门一审相关的服务部署在什么机房、数据库&runner等部署在哪里、审核人员办公区在哪里、用什么浏览器访问后台、当地办公区网络是哪家运营商的、访问后台页面走哪条线路、通过哪个nginx转发过来等等等等。纵向的梳理对于业务出问题后,能第一时间准确地排查。
# 6. 只要跟你相关,你就是Owner
跟你相关的工作,你需要积极主动地去推动,去沟通其他团队,跟进进度,排除阻碍,从而更好地把自己的那部分工作完成。 大部分技术同学的态度是:那谁接口还没给我,我没法搞。但对方做到什么程度了,什么时候能给,大部分人就一问三不知了。 这样其实不好。你完全可以承担起PM的职责,去跟进相关的事宜,这样会让人觉得你特别靠谱、对你特别放心,同时你也锻炼了沟通协调能力,以及增进了对方业务的了解程度,开阔了眼界。
# 7. 全面了解业务,深入理解需求
技术是为业务服务的,如果你做的业务没人用,即使代码写的再好,价值恐怕也不会大;如果用的人特别多,不管技术上优劣,价值一定不小。 同样,我们要对自己的青春负责,所以,如果你只爱技术不爱业务,不关注业务是否合理,不帮着优化业务,那么可以说:你对自己的青春不太负责。一个公司只有极少数人才只关心架构不关心业务。 因此,技术同学需要了解你做的页面,都哪些人在用,他们怎么用,有哪些用的爽、哪些用的不爽,不爽的如何改进?你需要了解用你页面的人,他们从上班到下班都在干什么,遇事的处理流程大概是什么样的? 深入了解业务后,对于很多需求,你就有更深入的理解,从而在做需求时,能更好地设计架构,未来有哪些扩展,也能预见了。
人做事一定是这样的:遇到一个问题,着手解决;此时如果直接去找技术同学,请教解决问题的方案,一般会被怼:我忙着呢,你连做啥都不知道,让我怎么做?! 所以,人一定会先想个解决方案,也就是所谓的需求,再把这个解决方案提给技术,那么问题来了:请问这个解决方案是最优解吗?如果你不了解业务,傻乎乎就做了,后来发现不是最优解,结果又推翻重构,浪费人力,还在感慨程序员命苦:产品一句话技术十行泪啊。 怪谁?!只能怪你自己不懂业务。 因此,技术同学在面对需求时,仔细询问,问清楚需求背后要解决的问题,再来审视需求的合理性,如果你也同意,那就搞起;如果你不同意,你有更好的解决方案,立刻提出来,大家商量着来,把问题一起解掉。 在这个过程中,你已经从一个普通工程师迈向高级工程师、甚至技术经理迈进了。
# 8. 利用好业余时间
每天就24小时,金三胖再牛逼,每天最多工作24小时,不可能工作25小时。对于刚毕业不久的同学,由于处在高速发展期,建议你把业余时间都利用起来,除了吃喝玩乐,业余时间建议你给自己充电。投资黄金、股票、基金、期货等等,再好的投资品不如把时间都投资到自己身上,因为这个不会亏损,并且投资的复利效果会非常明显。除了技术,建议也阅读些其他著作,比如经济、历史、哲学、心理学等等。 对于毕业时间较长的同学,建议业余时间多思考,把所有问题分解的特别细;对于技术方面,更要站在宏观的角度来看待问题。
好了,暂时想到的就这么多,就先写这么多吧!回头有更多想法,我再补充上去!