一个程序员的成长思考(持续更新)

546 阅读13分钟

我有一个体会很深的经验:学习最大的陷阱在于【缺乏 single source of truth】,总是在“狗熊掰棒子”,因为没有一个容器来放置你的知识,思考,经验,这些东西就会短暂的经过你的大脑,然后消散,像一个缓存被逐出了一样。

你需要建立自己的 single source,记录下知识,所思所想。这样的好处有三点:

  1. 有迹可循,能够【学而时习之】,当你需要这块知识时,可以最快时间将其 load 到你的“内存”里,而不是似是而非地重新去 google;
  2. 当关于同一个主题,从其他源头有不同意见时,你可以精确地比较,判断二者的高低,进而取其精华去其糟粕,更新你自己的 single source,而不是留下新的残存的印象,一段时间后继续忘记;
  3. 避免混淆,因为概念是清晰的,知识是明确的,不会迟疑。

这个 single source of truth,一定需要有一些【存储】辅助,你可以记笔记,发专栏,发视频。都ok,但一定保证根本的东西是稳定的,落地是坚定的,平稳的。

基于此,我希望把自己职场,生活中一些碎片化的思考记录下来,包括观点,经验,教训。因为如果不这样做,经常在同一个问题上踩坑,或者想不清楚。这个笔记我会保持更新,每次有一些新想法就会 append 到最前面,作为自己的一个 single source of truth。

九月

概要设计

比较大的项目的后端review我感觉应该分两次。第一次review概要设计,把一些核心抉择讨论清楚。概要设计达成共识后才去review详细设计。

概要设计,需要从前后端整体的角度来写,最好是前后端都能看懂。

八月

人脑是个 LFU 的内存

曾经获得的知识,技能,经验,一旦用不上,很快就会忘,只剩下残存的印象。所以一定要持久化,需要的时候能快速找到曾经内化的东西。

关于注释

合理的注释(更多靠代码自解释)> 过多的注释 > 少注释 > 无注释 > 错误的注释

什么时候做性能优化

今天看到一个大佬分享感觉说的挺对,做性能优化的两个时机:

  • 当你优化的价值大于你投入的时间价值时;
  • 写代码时。

写好了优化一定要有 benchmark 进行对照。

七月

不要靠人工保证机制

机制分两种:

  1. 有自动化卡点,有工具辅助的;
  2. 靠团队意识,靠人工。

很多时候我们受限于基础条件,跨团队合作,无法做到 1,所以变成 2 这种意识流。

2 的很重要的两个缺点在于:

  • 团队人员会变,业务会变,达不到【人】级别的覆盖;
  • 人的记性有限,内存有限,即便【人】都覆盖了,也会忘,也可能因为在开会,在处理问题,忽略机制或草草走一下。

所以,当然,可以走 2,这是被迫无奈之举,短期方案,但一定要想清楚长期,怎样落实到卡点,落实到工具,平台。 出了问题有什么机制来一步步follow 就 ok,千万不要把人想得太聪明,也不要把人的记性,内存想得太好。选 2 前,一定想清楚 1 怎么搞,尽快让 1 代替 2。如果各种其他事项的 2 已经很多,请谨慎加流程。

复盘不容易

今天参加一个事故复盘,很有感慨。事故本身原因不复杂,从写代码到 review,以及项目依赖机制,hotfix 机制,运维工具各个方面都有一些缺失,导致一个看起来并不隐蔽的 bug 暴露到了线上。事故复盘文档里大家洋洋洒洒写了一大堆【问题】,【思考】,【以后要做到的事】。非常专业,非常靠谱。

但坦率讲,这样的复盘,每年都有很多次,很多业务都有过。很多总结,想法甚至都能看出来套路的痕迹。出了问题就要找 CR 的人问责,归咎于一些流程问题,这个时候你会感觉怎么哪儿哪儿都是坑。

这并不是一件好事。

事故复盘是为了什么?

事故的本质是成本,由于一些事情不太对,所以你付出了成本(客户赔偿,声誉下降等)。重点是成本么?不是!

是你花了成本,那换回来什么呢?这个才是最重要的。

而能换回来什么,这是个很有技术性的问题。事故复盘属于你付出了成本,想拿【收益】也很不容易的,这个特点一定要记住。最忌讳的就是大家被流程束缚,出了问题就追责,就让涉及的同学意识流反思,定个级别,发个通报,一堆发散型问题,这是本末倒置。

你的反思,你的通报,你的定级,还是成本,这个一定要记住。这是你的 RD, QA,PM,所有相关同事的时间成本。

大量的业务,大量的组织,都花了大把时间在【堆积成本】。

那能换回来什么呢?

一定不是意识,不要相信意识,如果你的回报只是一些意识,无论是写代码的同事,还是 review 的同事,测试的同事,可以说这件事情和没有收益无区别。因为人是会换的,团队是越来越大的,业务是会调整的。做了一堆,哪怕意识真的具备了,又多大程度上能保证以后没有问题呢?

能换来的,一定是稳定,可固化的一些东西。比如:

  • 工具,平台能力的提升(能监控更多场景,能解决更多问题),从而降低事故发现时间,排查问题时间,解决问题时间;
  • 流程机制的【真实的,有效的】改善。

问题来了,大家也都在说机制,流程怎么改善呀,那这样是不是就够了?

并不!因为,流程机制是现在的这幅模样,是有原因的,也许跟组织有关,也许跟大家工作习惯,工作量有关。事故发生时我们当然可以提出一系列措施,一系列可以【加强重视】,【提高测试范围】,【上升周知】的机制。但这是现在出了事,你在这里当然重视。

一定要花大量的心思,精力,在【流程,机制】怎样合理这个角度上(不仅仅是解决当前的问题,更是如何落地,如何有效)。不要想当然的提出一系列措施,就直接执行。你想要真实的收益,就要谨慎,就要实实在在列 TODO,思考是否合理,跟进直到落地。

想想平常技术需求,重构需求的方案写了多少?复盘之后落地的措施文档又写了多少?是否足够重视?

落地的措施,要当成一个 P0 的需求来应对,因为这里还往往涉及更多跨团队协作,更多机制,杠杆是非常强的。要拆成一个个项目去跟,去落地,这些全部都要跟完的。确保你的方向没问题,然后持续微调,直到完整落地结束。

可惜的是,我们总是花 20% 到 40% 的时间修复事故带来的影响,50% 到 70% 的时间复盘,周知,花最后 < 10% 的时间来跟进TODO。

事故复盘是开始,你要去反思组织上,机制上,你希望做到的程度如何?如果你预期一些组织问题解决不了,就是可能有一些小事故,也 ok,作为业务负责人自己判断。

但如果你的态度是零容忍,希望解决问题,就要花至少 70% 以上的时间在跟进措施落实上。

讨论为什么出问题,很容易,拍脑门给出一些方向和措施,也不难。但这些措施有没有记录下来,评估合理性,出落地方案,去拉会,去沟通落地,这才是根本。

提出问题很容易,但大多数case里,我们总是有一大堆人提问题,拍脑门,给一些脑暴的想法,说一些政治正确的流程,但只有一两个人来实干。

跟进 TODO 的,一定得是专项owner,Team Leader,而不是触发事故的小兵。

如果做不到,那你只是在付出了直接的事故成本之后,又付出了复盘的成本,然后什么都不拿就溜了。

六月

不要兜底

"尝试给错误的输入返回正确的结果是万恶之源“,fail fast,既然不知道怎么处理,就报错退出,让用户自己来处理。这个观点特别好,你把要求明确,格式校验加好,是什么就是什么。用户心智负担也小,因为明确。

最讨厌让我输入一个链接,不说清楚是 http 还是 https,能不能带 query param,是只填 host 还是一个完整的请求,底层内部实际上做了很多兼容,适配,这类实际上非常恶心。

五月

遗忘

我们总是在跟遗忘作战。

忘记计划,忘记知识,忘记方法。。。然后重新来过。

这就是没有 single source of truth 的后果,因为没有聚焦,没有将重要的东西变成稳定的,可寻址的,经常 review的,所以无法更新,也无法精确地知道自己会什么,要干什么。

关于重构

今天从一个尊敬的前辈那里听到一句话,感觉很对:

战役式重构无法彻底解决问题,核心是需要更多高阶同学加入,亲自动手,持续重构和改进架构。

只写必须的代码

大家平常经常调侃,自己每天的任务就是写 bug。确实,写代码出bug是难免的,但 bug 之外,其实还有很多隐患。不合理的代码分层,没有和注释保持一致的变动,多余的代码,等等。

这些在当时写代码的瞬间,可能并不会在意。但软件开发避不开的一个现实是:你总会接手别人写的代码,你的代码也总会在未来的某天被review和改动。

开发时随意加代码(哪怕是无bug的),随后记忆模糊了就会傻眼,更何况常常是其他人来接手。我觉得有几个原则可以约束自己,避免出现【写码一时爽,迭代火葬场】:

  1. 只写当前必需的代码,删了再删,保证没有一行多余,将改动控制在最小范围;
  2. 注释附上足够的上下文(判断的依据,参考的文档),TODO, FIXME 标清楚;
  3. 保证日志,注释,代码一致。

政治正确

政治正确不可怕,leader要为结果负责,必然政治正确,我们讨厌政治正确的根源在于没方案,难落地。嘴上说说容易,不知道一线的难。

首先要找到一个来解决问题,来帮忙,提供资源的leader,而不是只会发号施令。如果这一点做不到,leader只是空口白话表表态,不想解决问题,建议尽快活水。判断的依据很简单,跟他交流遇到的问题,告诉他你的困境,被外部 push 的时候拉他进来评估,真正让他知道落地的难点,是缺人?还是跨部门协作问题?还是方向有问题?

同时,你要作为一个可以被信赖的一线主力,思考根源问题,你来给出答案,合理即可,你要给选项,给方案,体现你的思考和价值。

leader 满嘴政治正确不一定是坏事,不在一线跟需求,很多事情确实不熟悉,为了稳健保持政治正确是可以预料到的。这一点不惊讶,评估一个 leader 能力的关键在于,面对具体case,面对落地的困难,是想办法帮下属一起找到解决办法,还是只是嘴上说说,一点思考和资源都不提供。

多点主动,少点放空

每个人都会经历忙碌焦躁的时刻,感觉身心俱疲,希望休息。个人经历告诉我的是,不要无目的地休息,完全放空的状态其实并不能达到休息的效果。人啊,最怕没事干。你去睡觉,打游戏,看电影,跑步,刷短视频,ok 都可以,这些都很好,但记住一定是主动的。不要被动去放空,越放空,越感觉无聊,刷视频其实也挺累的,无所事事也会增加焦虑感,因为你知道放松的时间在流逝。哪怕主动放松去睡一觉,主动去发呆,也好过被动地这儿找点事情干,那儿找点事情干。

因为被动,代表着你没有充分的动机和心理预期去认真投入。进而导致你无法深入,自然无法专注,专注意味着清空其他杂念。无法专注,所以你会这儿看看,那儿看看,浅尝辄止,当有些地方需要你稍微投入的时候,你就会拒绝,因为我是来放松的,不是来给自己增加工作的。抑或是,我是要休息的,不要做家务,不要累。

四月

先给产出,再推进度

没有产出,等于没有投入。所以列任何计划前,一定明确自己想要什么结果。一定是明确的,可看的产出物(除非是完全没想清楚,只是先摸摸水,产出物可能就是自己的感觉,不用太严格)。

有了明确的产出物,比如一篇学习笔记,一篇分析调研报告,一份能跑通的代码,你自然就可以去拆每一步,倒退该干啥了,你自己就会驱动自己了。

最怕不知道产出是啥,不逼着自己产出,最后的结果只是,哦,我大概知道了。学习最忌讳把东西仅仅留在那一刻的脑子里,你讲不出来,就是不会,你没实操,大概明白,等于不明白。

Keep moving

跃迁并不是一蹴而就,跃迁甚至不是长时间能达到的,你需要成长,经历一些很难的时候,焦头烂额没法解决的时候,挺住,扛过去了,再去学习,去成长,才可能跃迁。

这些,跟时间并没有什么关系。你可能短时间快速成长,独当一面。也可能多年来原地踏步。

原地踏步,是个可怕的词。你的能力在原地踏步,而你的时间和身体并不会。所以,世上没有什么原地踏步,只有不断被抛下。你会和不如你的人越来越近,和你羡慕的人原来越远。

每天,进步一点点,一个明确的点,一个可以被执行,可以追踪,可以在你长久的职业生涯上留下痕迹的一个点。然后第二天,第三天,保持它。

如果感觉难以兼顾,没有内化为你的一部分(无论这是个能力,还是习惯),就巩固。但一定要可执行,可追踪,可回顾。

建立一个 Growth Log,每次 amend 一个记录,今天你内化了什么。

三月

Stupify your execution

世上没有执行力低,所有的执行力低,都来源于 方案不够细化。让你的方案事无巨细,把所有可能的问题,阻塞项,解决方案写清楚,解耦 planner 和 executor 两个阶段,会让你轻松很多。在需要执行力的时候,一定要让你的执行傻瓜化。如果是创造性的还好,可以放松一些,一边做,一边想,发散。出方案,和执行,一定是分开的两步。你把太多没想清楚问题都留到了执行阶段,就不要抱怨执行力低。

直面真我

不畏惧你觉得难的,不好做,可能被怼的事,因为事情总会来的,你可以主动去找到,面对,思考出当下最好的办法,让心理和大脑做好准备。也可以当个鸵鸟,只要事情没敲门我就当不存在。问题本身并不会因为你准备与否就变,但前者面对的是一个准备好的你,后者只会让你在这段时间内更加恐惧。我们不怕前面是绿灯或红灯,至少我知道能不能成,不行了再想办法。我们怕的是黄灯带来的不确定性。要消除这种不确定性,上吧,让自己做好准备,主动地直面它。哪怕你发现自己不行,至少你提前知道了,而不是临场被动。