阅读 674

回顾2019,一段从前端到全栈的艰辛旅程 | 掘金年度征文

使我洛阳有二顷良田,安能佩六国相印

这是战国时期的纵横家-苏秦的名言,也是郭德纲最喜欢的一句话,如果家里有矿,我也不至于北漂深漂了。

清风不识字,何故乱翻书

我是2018年从北京来深圳的,当时去的是“永远大”集团,毕竟世界五百强,所有的规章制度都很完善,以至于近乎苛刻。在里面,你的业务能力不需要特别优秀,搞好人际关系,做好公司安排的一些营销任务指标,完全可以在里面养老。每天朝八晚五,还包三餐,有健身房,在里面什么都好,唯独不适合搞技术。

直属领导待我很好,给了我很多机会,教了我很多管理经验,还让我组建了一个前端小组,战斗力几乎就是集团的中央军。但技术总监就很水了,业务不懂,还整天拿公司制度上纲上线,下面的人没一个拥护他,后来他还招了一个 Java 架构师,来替代原直属领导(因为他的业务主要在广州),也是水得不行,搞得后来很多后端同事直接公开怼他。后来公司战略调整,小组解散了,要么去二公子的公司,要么转外包,要么走人。

时人不具波斯眼,枉使明珠混俗尘

我想在这里待着也没意思,还遇到这么恶心的领导,干脆满一年直接走人。组里其他人的选择和我差不多,都去了比较好的公司,其中一个女生,还进了鹅厂。后来,我去了一家快递公司,开发人员很多,月薪很高,但时薪很低,社保医保基数也很低,老板还自诩张小龙,而且喜欢晚上来提需求,还要求当天看效果,产品都不敢拦,而且领导要求开发不要那么早下班,一个需求重复改,导致加班严重。这样下去,别说技术进步了,身体都要被拖垮了,于是没待多久直接跑路。

于是下一家,我很看中休息时间和开发流程,也就是现在这家了。公司不大不小,但有自己的盈利产品,这和上面两家 To B 项目是不一样的,开发有一定的话语权。加班也不是很多,一周也就3天到八点多而已,把自己的事情弄完后还是有时间提升技术的。

世间有人谤我、欺我、辱我、笑我、轻我、贱我、骗我,如何处置乎?

虽然刚来公司的时候,我还希望遇到个前端大牛啥的,但后来发现,自己就是大牛(虽然我有自知之明,但真架不住公司同行的衬托😂)。项目写得乱七八糟,毫无规范可言。当时前端组4人,一位快离职的,一位培训班出来的女生,一位看起来很强的前端(为什么说看起来很强呢?因为发量和技术完全不匹配)。要离职的接触时间不多,暂不评价。女生人还是挺不错的,就是脾气比较倔,很多建议都听不进去,加上我是个钢铁直男,有几次都吵起来了。后来是因为生产事故加上工作量相比去年徒然增长,于是那个女生自己离职了。

后来招了一位2年经验,颜值不错的女生来接她的工作。一开始是帮我分担了一些压力,但是公司高层被某些人蛊惑,非要做一个几乎没有市场份额的产品,把她借到其他项目组了(后来果然黄了,项目组解散,若干高层离职,这些都是后话了)。于是我那段时间异常愤怒,怼天怼地怼空气,一个是工作量大,本来2、3个人的活,只有我一个人干(光头除了运营活动,其他项目一问三不知);另一个是我辛辛苦苦培养的新人,被别人直接捡现成,就因为那边的领导官职大。

于是有很多人都开始说我的坏话,估计领导也对我有点微词,不过因为手里的项目实在太过重要,短期内根本找不到可替代的,也就默许了我的行为。

后来我也觉得这样下去也不太好,于是就开始保持沉默,非工作需要,不会主动搭话,只专心搞技术。

忍他、让他、避他、由他、耐他、敬他、不要理他,再过几年,你且看他。

最忙的时候,同时开发 + 维护5个项目,只要有新需求或线上有问题,都来找我。VSCode 至少同时开4个窗口,还要负责面试。而那位“资深”前端呢?一个已经成熟的活动做3、4天,复制粘贴、然后摸鱼。给他安排一些不是很复杂的工作(比如换图),他就告到领导那,说要分清楚职责,以前是3、4个人一起做活动,现在只有他一个人做活动BalaBala。当时真的是被惹火了,亏我当时还好心提醒他大致位置,直接截图聊天记录给领导,然后领导专门找我们谈话,他用他那丰富的扯皮经验和道德武器来攻击我,我也用做产品的怼人经验怼回他。当然,领导还是很开明的,最后还是安排给他做了,并私下跟我说:对于他这种人,没必要发火,显得自己很Low,迟早是要把他换掉的。

然后他换个图换了一天,扯什么之前少了一个月的,他离职后我自己换,10分钟搞定。。。

之后公司宣布了为期2个月的 995、大小周,来测试我们的抗压能力,然后“资深”前端就自己走了(据说离职原因是他说活动做得那么辛苦,运营部还是不满意,让他很不满)。其间,又招了两位 211 的前端来分担压力(不是我歧视学历,是公司要求最低 211 起步,好多比较有经验的面试者都没过 HR 那关)。其中一位还是刚毕业的大学生,因为大学时做过一些后端,就让他交接“光头”的工作。“光头”的交接还是挺负责的,但是灌输了太多的摸鱼思想,一度让我很不满,但时间和代码会证明,菜是原罪。

向上的道路从不拥挤,只是大多数人选择了安逸

“光头”离职后,我先让大学生按照他之前的方式复制粘贴熟悉流程,然后自己花了近1个月的时间,将 Node 以前95%的业务代码都抛弃了,按照自己的想法重写,因为是新开路由,所以和线上跑的项目也不会冲突。

这段时间非常痛苦,因为要先理解以前的代码做了啥,但之前的人毫无封装逻辑,居然在公共文件参入了大量的业务代码,而且很多都是全部复制,改个方法名,然后里面加了几句话,就成新方法了。。。各种文件绕来绕去,举个例子,用户进入活动,我需要知道活动信息,正常逻辑是将加密的参数解密得到活动id,然后查活动表就完事了,而老代码,居然绕了6、7个方法,同一个表居然查了3次,性能怎么不低?光头还号称引用了 Redis,将活动信息缓存起来了,读了源码发现,Redis 是用了,但是是在查表之后的,那么缓存的意义何在?因为这些那些,我索性摒弃这坨代码,直接问测试现有需求是什么样的,然后当做新需求,从0开始。

重构后的代码,逻辑清晰了很多,一个定制活动,就对应一个文件,以前做过的活动,能复用就尽量复用,反正只是活动id不同,发奖、插表的逻辑是一样的。而公共方法就做两件事,解密活动信息和发奖,其他的都放到业务代码去处理。

因为之前那坨代码,所以一开始很排斥 Redis,但后面需要做一个红包雨活动,这属于并发量比较高的,所以还是考虑使用 Redis。具体实现逻辑大致是:

  1. 用户进入页面获取活动、排名信息等操作都是查表,抢红包操作则是推入 Redis 队列中(其间涉及到查询活动是否结束、红包是否已抢完等限制条件,有些是查表,有些是查 Redis);
  2. 单独开一个 Node 常驻进程(使用pm2来管理的),专门用来处理红包发放。通过监听 Redis 队列并调用 brpoplpush 方法(用的是 ioredis 库),将抢红包操作的队列信息推入到待发奖队列;
  3. 从待发奖队列中取出,匹配获取的红包;
  4. 调用公共的发奖方法,完成;
  5. 若发奖失败,捕获 error 并记录日志,然后推回待发送队列。

测试压测数据是支持每秒400+次,虽然正式环境没有那么高的并发量,有几天甚至红包都没抢完,但比之前运营、测试说光头居然用红包雨把服务器搞宕机了这种事故要不知好多少倍。

不得不说,学会使用 Redis 后,很多操作都方便多了,比如后来运营那边要控制大红包数量,我也是通过 Redis 记录来控制,具体逻辑有点复杂,这里就不展开了。

如果不是生活所迫,没有人愿意一身才华。

后来,就让应届生在我重构后的代码上写业务了(他自己都吐槽原来的代码绕来绕去),不得不说,我还是很欣赏他的,才刚毕业,稍微点拨一下,就知道该怎么做了,而且生产大事故基本没有(有也是因为被老代码坑了),大部分活动都放心交给他了,比之前那位真的要好太多,可见年龄并不是衡量技术的标准。而另一位 211,因为非科班,且之前做的是纯前端,所以也就让她继续写页面,待时机成熟,再培养 Node 技能树。

有了他们的帮助,我终于有时间尝试新技术,将活动后台的逻辑抽离出来,使用 Nest 框架重构,降低以前的项目的耦合性(之前他们是将所有的Api都写到一个项目里,一个报错导致服务无限重启,所有的业务都用不了😡)。因为是从零开始,数据库连接、Redis 连接、跨域处理、日志的分类、记录并上传阿里云等等配置都要自己来,也是通过这个项目,学习了 TypeScript(虽然最后写着写着就变成了 AnyScript 😂)。从开发到部署再到正式运行,鬼知道我经历了什么,但从0到1的喜悦比中了500万还开心(虽然我更喜欢中500万)。

至于为什么选 Nest?一是因为觉得 TypeScript 是未来趋势,早学早好,还能顺带理解 Vue 3.0 源码;二是 Koa 写了大半年,有点腻了,而 Nest 的 MVC 设计模式很符合大学学的那套;三是使用 TS 能一定程度上降低因为不规范导致的 Bug。

再后来,领导说想使用 Flutter 框架重构,因为之前原生 + H5有很多兼容性问题,导致上面的领导不满意,于是我又抽时间研究 Flutter,但年底其他工作很多,又要准备年会节目,所以断断续续的,待春节后再仔细研究吧。

所以,很多时候,是求生欲促使自己不断前进,这一年学到的东西,比毕业那几年的总和还要多。

你要善良,但必须有锋芒

不得不说,经历了这段洗礼,对前端的理解又深入了许多,很多事情前端是可以做的,比如用 Node 做中间件转发、Mock 假数据等。而且知道从访问页面到数据库查询并返回的整个过程后,除了算法、性能、高并发等问题,再有其他后端欺负你只是个前端,甩锅给你时,你就可以降维打击怼回去了。

事实上,我也是这么做的,公司一个新项目,是其他项目组做的,但是从我这里借了一个女生过去,刚开始有个请求怎么弄都是显示 CORS 跨域,弄了好久都没弄好,然后求助我。我过去一看,Axios 配置没问题,只是 POST204预请求没通过,当时就猜到了七八分,就问那个后端有日志吗,他直接把 XShell 发过来,说他代码没问题,很忙,自己看。我当时就怼回去:“你见过让前端去看服务器日志的吗?”

然后他就怂了,打开日志,我一看果然是没处理 OPTIONS 请求:“你看,我们的请求是过来了的,你自己没处理而已”,然后他就默默去改了。

然后就是运营提需求时,也没那么过分了,毕竟都知道我有些锋芒,但只限于工作上,对事不对人。而且我有时会站在产品的角度上提一些建议,主动增加自己的工作量,他们也欣然接受,所以现在和他们的关系处于一种微妙的平衡吧。

我的直属领导属于比较好说话的,对兄弟也很好,很少见他和别人吵起来,包括很多无理的需求,他都无奈的接了下来,也跟他需要养家糊口有关吧,在公司不轻易得罪人,很能隐忍,和我这种一人吃饱全家不饿的不一样,这点我还是很佩服的。但也因为这样,开发部多了很多无谓的工作量,很多资源也争取不到,毕竟会哭的孩子有奶吃,所以这一点上,我觉得还是要适当放出一些锋芒,让其他部门知道乱提需求是要付出成本的,倒逼他们多想一些,才能让产品更好,开发也能少加班。当然,这种只适用于中小型公司,500强就算了。

你若盛开,清风自来

以前看过黄渤的一则采访,他曾云淡风轻地提起:“以前在剧组里,总能遇到各种各样的人,各种小心机,但现在(成名了),身边全是好人,每一张都是洋溢的笑脸。”

你不优秀,认识谁都没用

之前那位“资深”前端,似乎跟每个人都认识,总想讨好别人,尤其是女生,都加了微信,但那些女生私底下跟我说,他给她们的感觉只有一个词:油腻。

可是呢,讨好归讨好,但只要工作上有些争执,他就立刻拉黑对方。据我所知,从我入职到他离职,他拉黑好几个人了,包括我自己。有人可能会说,你不是对事不对人吗,怎么老说他?因为他的例子实在太典型了,再加上实在被他气得不行,工作那么多年,就没遇到过这么恶心的同行。

首先是技术,30+的老前端,技术停留在能用就行,天花板也就那么高了,解决问题速度极慢,测试给他提Bug,他就很不开心,然后能墨迹一天;其次是人品,以前怎么样是不知道,但是在这家公司的时候,几乎所有的人都对他不满(包括产品、运营、开发、测试、运维等同事,我也是头次见)。而且离职前一天还和领导大吵一架,具体原因是临时的一个紧急需求,我这边忙不过来,新人又不熟悉项目,领导无奈只能安排给他,他却说什么:“我都是要离职的人,还给我安排工作。”,领导说:“你现在还是在职,而且这个需求不是很难。”然后他就很生气的说:“我现在就是不想做!”

最后这个活还是安排给了新人,然后我又得抽时间给新人讲一些老项目注意事项,遇到这种同事,真的是倒了八辈子霉。看来这哥们三十多年也没活明白,技术圈就这么大,得罪那么多人,是准备35岁改行吗?

成年人的世界里,处处讲究势均力敌

既然当了程序员,就先把自己的技术提升到一定程度,再考虑其他。我不否认人脉的力量,但无数事实证明,你首先要有“利用”价值,才能形成人脉。作为程序员,本职工作都没做好,对于领导、同事而言,怎么可能是人脉呢?除非你是老板亲戚或家里有矿等优秀人士。显然,我不是,“光头”也不是,然而“光头”的油条行为已经严重损害了周围同事的利益,被众人吐槽、怨恨也在情理之中了。而我,历经公司2次大洗牌,青山依旧在,几度夕阳红。

所谓志,但兼有力者乃谓“今”。所谓弱者罪。

这是海贼王里最喜欢的台词之一,原句是:“所谓的梦想,是同时有实力的人,才能谈论的现实。 所谓的弱,本身就是一种罪。”

现在的大环境很不好,总有爆料说哪里裁员了啊,996了啊,251了啊,35岁之坎啊等等,弱者乞求公平,平庸者寻找公平,强者分配公平。没人在乎真正的公平,对凡人来说,有利于自己,便是公平。对于这种情况,我们能做的其实很少,只有持续学习,在诸多不确定性中寻求一些小确幸。

努力固然重要,但方向更重要,更不能忽视历史的进程

这里引用一段 HarryQu 的精彩评论:

有的程序员喜欢看书。有的程序员喜欢直接看源码。有的程序员喜欢看别人的博客。有的程序员喜欢看在线视频。有的程序员喜欢看别人的公众号。有的程序员喜欢凑成一个圈子(知识星球)。获取知识的途径不一样罢了。

我以前是 Android 程序员,后来有人告诉我现在流行 Hybrid App,后来有人告诉我 RN 很火,让我学 RN。后来又有人告诉我 Kotlin 是钦定的官方语言。后来又有人告诉我 Flutter 很香。后来又有人告诉我现在是大前端的天下。

我走了一圈兜兜转转,看似什么都会一点,其实什么也不会。我才突然明白编程语言只是工具,不要迷恋新技术,多去提升思维,学会思考,学会表达。

这个简单的道理,我却花了三年时间才明白,我是不是很可悲?

之前我学习的时候,也是东看看西看看,什么培训视频啊没少下载,看似啥都会,其实啥也不会,直到有一位大佬影响了我。他属于半路出家的,平时很少说话,一有时间就看书,犀牛书都给他翻破了,源码都敲了好几遍,还喜欢晨跑,真是自律得可怕。后面不满足这些,就去读英文原版、Vue 的源码,还直接在代码中调用源码方法。平时还会问我的看书进度之类的,还会分享一些他的读书心得,推荐书单等,能遇到他真是三生有幸。

在他的影响下,我也意识到,语言只是工具,但学精一门语言很重要,因为编程思维是相通的,学通一门,触类旁通。

人到中年,学习能力不如以前,Nest 框架也是看了一周多才上手,但后面就很顺畅了,重写那些逻辑也就花了半个月,并顺利上线。就因为我把公司的那套 Koa 项目摸透了,该用的中间件都了解了,潜在的坑都避开了。

最厉害的武器,是习惯

这句话出自一部很喜欢的日本电影,堺雅人大叔主演的《盗钥匙的方法》,讲述的是一次偶然的机会,完全不想交的两个人互换了身份,其中一个原本很成功的杀手意外失忆了,但是通过习惯的力量,又回到了人生的巅峰,而另一个人属于社会废柴,即使互换了身份,坐拥杀手豪宅,还是把日子过得一塌糊涂。

由此引出一个不得不提的很多人都会忽略的问题:编程习惯。

一是写代码一定要规范。代码是要给别人看的,实在不懂规范,就把 ESLint 打开,哪里不对改哪里。不要闲麻烦,如果随心所欲的编写,看似走了捷径,实际上等找 Bug 的时候,会让你付出几倍甚至几十倍的时间。公司的老项目我之所以决定重构,就是因为写得太不规范了,维护的时间远大于重构的时间,与其在危楼上修修补补,还不如推倒重来。

二是能读源码就读源码,能看原文就看原文。作者是最了解自己写代码的意图的,所以遇到问题,我都会优先找到 github 的源码(虽然看不懂),然后点开 issue,看有没有相关问题。看框架也是,优先选择官方文档,这是最权威的,即使是英文也要慢慢啃,如果实在看不懂,就去搜一下关于这章的译文。这里不得不说老外写的文档都挺平易近人的,代入感很强,虽然大多数时间,都要依靠词典才能读下去。🤣

三是不局限于能用就行(如果时间实在太赶且超出能力范围之外了,还是先上线再说)。之前做活动的时候,就遇到一个倒计时掉帧的问题,当时问“光头”,他说以前就是这样的,能用就行。

于是我很无语,然后潜心研究,查了很多资料,让测试小姐姐配合测试,折腾了近一周,最终解决了这个问题,并写成了人生中第一篇技术博客《记一次 Vue 移动端活动倒计时优化》(惭愧啊,工作那么久才有内容输出)。然后掘友们的点赞和评论激励着我不断前进,这里还是要谢谢大家的反馈。

通过两种完全不同的人生对比就可以发现,是习惯让我区别于“光头”,当他还在守着自己那一亩三分地的时候,我已经接触了公司80%的项目;当他还在网上摸鱼、东看看西看看的时候,我已经在做内容输出了;当他“自愿”离职的时候,我已经当上了前端组长(公司怕我跳槽,前阵子领导私下跟我说,年后会升主管,我心想:升不升的无所谓,反正事都是这么多,钱给够了就行😂);

当然,我也有很多缺点,比如不善于沟通和人际关系,这也是领导一直希望我提升的地方(然而这就是当初选择当程序员的原因之一呀,和机器打交道轻松多了);比如有时候会控制不住情绪;比如容易钻牛角尖等等。

鹰击长空扶风摇,千军万马避白袍

虽然这一年我学了很多,但自己很清楚,后端博大精深,我学到的只是皮毛而已,就像牛顿说的:

我好像是一个在海边玩耍的孩子,不时为拾到比通常更光滑的石子或更美丽的贝壳而欢欣鼓舞,而展现在我面前的是完全未探明的真理之海

说了这么多,还扯了一些和技术无关的人际关系,只是希望大家在新的一年里,借鉴我的经历,少走弯路,让程序员的队伍更壮大,让无良老板不敢轻易996,让我们说的话更有分量。

我努力奔跑,只为追上曾被寄予厚望的自己。

掘金年度征文 | 2019 与我的技术之路 征文活动正在进行中......