做了 6 年程序员,我学到的 10 条经验
保持一颗解决问题的心
按照我的观察,那些在工作中用技术取胜的人们共同点都在于他们能保持一颗解决问题的心。他们可以率先想到一种更优的手段解决存在的问题(一般是效率问题)。他们不是嗅觉特别灵敏或者技术特别强,而是当他们遇到了问题,不是把它作为抱怨的话题,而是开始思考这个问题为什么没人解决、应该怎么解决,然后把它实现出来。这种心态在职场上特别稀缺。
我在创业公司的时候做一个图文排版的 App, 设计师会设计一些模板,然后交给我来实现。当时我们有很多模板,为了测试这些模板实现在不同的手机屏幕大小会有什么问题,我们要花特别多的精力。可以想象测试的数量 = 模板数量 * 屏幕尺寸的数量。后来我用 puppeteer 写了个自动生成不同屏幕和模板的截图,直接交给设计师一个一个地看。节省了大量的时间。这个事情没什么技术含量,但它解决了很重要的问题。
工作中需要解决的问题不仅仅在代码上,也有可能出现在非技术问题上。工作中我特别喜欢和非技术同事聊天,了解他们的工作。因为我常常觉得影响项目前进的原因不一定出在我们用了不适合的技术或者不够「先进」的技术。了解非技术同事的工作流程让我大有收获,我会发现他们有一些工作是可以通过写一段程序把原本的工作量做到指数级的下降,而通常非技术同事是很难察觉到的。
这样的例子特别多。有次我和一个运营同事聊天,我们当时在开发一个新闻内容的管理后台,他们常常用这个后台捞一些内容做分析。聊天的时候了解到他们有一部份的工作就是在上面按条件查询一些内容,再一条条地粘贴到 excel 里面,他说这常常要花一下午。后来我帮她做了一个一键导出成 excel 的功能。
她觉得这很不可思议,但这在技术的角度来说太简单了。我也因此了解到,对于不是做技术的人来说,他们很难察觉到哪一些事情是可以用技术解决的,所以我们不能希望他们主动地提出一个需求,只能我们作为掌握技术的人主动地去了解他们。
又一次我和我们的测试吃饭,聊到他们怎么做测试。我发现他们会用 mindmap 先梳理出来一些测试流程,然后一个个地做。但是痛点在于他们常常要手动维护一个文档列出这些 case 的测试结果,这些结果包括截屏,以及证明测试通过的请求返回信息等等。不但麻烦,还很难追踪。
于是我做了一个小 demo Web App,他们可以直接上传他们做好的 Mindmap, 通过他们的 mindmap 直接生成出来 case item,在项目的开发环境页面代码里面,只要注入这个 case id,就可以在测试之前开始记录请求日志,结束之后会上传到这个平台,这样在这个平台就能直接看到每一个 case 操作的时候的整个过程的记录。这个小 demo 后来被用于花呗的大部份前端项目,当然听说现在已经做得和我当时做的小 demo 完全不同了。
了解你的用户
我自认为自己还算是一个有那么一些产品思维的程序员,因为经常也会写一些自己的小产品。但在刚出来工作的时候,我在工作中太沉迷于技术本身。把心思都放在了诸如怎么重构,怎么改进构建速度之类的问题。我在阿里 P5 升 P6 的答辩中,我被问了一个我至今印象深刻的问题:你有了解你的用户是怎么用你在做的这个东西吗?
这个问题是我从来没有想过的,我哑口无言。可能它只是一个晋升答辩问题模板中的一个问题,但对我来说这个问题让我清醒了许多。当时我们做的是内部用的新闻内容管理后台,这个后台的用户是一些小编。我们和这些小编有一个群,但基本是用来报 bug 的。我离这些用户这么近,却从来没有了解过他们的使用感受。我想,如果我当时找他们聊一聊,可能也会有意想不到的收获。或许他们会报怨这个后台的加载速度很慢,我们就可以着手解决加载速度的问题,而不是和同事纠结在用哪种前端状态管理库这种无聊事情上。用户并不关心我们用的是 MobX 还是 Redux.
不要拿自己的尺子去度量别人
我刚出来工作犯的最大的错误之一就是拿自己的尺子去度量别人。我因为从小对编程痴迷,写程序对我来说是人生中最大的兴趣,我把几乎所有的时间都花在了技术上。当时我天真地认为所有程序员都应该像我这样,对待技术也应该有一种理想主义,我在互联网上结交的技术朋友都是这样的。所以我当时对我的同事特别苛刻,甚至对那些把写程序只当成工作的人嗤之以鼻。后来回想起来,这是非常错误的想法。每个人有每个人的追求,技术也只是多个兴趣爱好的其中一种。在当时别人的眼里我可能是个「怪人」,甚至有点「装逼」。
保持学习、be open-mind
我每天都会在 Twitter 和 Hackernews 发现很多最新的技术和技术思考,我关注了很多开源库的作者,我可以第一时间了解到他们最近在思考什么,在接触什么。这种主动接收会扩大你的眼界,让你在解决问题的时候有更广的思路。
不要只关注自己的领域。我还关注了很多写 Rust, 写 Go, 写 iOS/Android 的人。学习主要是学习技术背后解决问题的方式,这些解决问题的方式说不准也能应用到你自己的领域。
保持学习一直是和同行拉开差距最重要的一点。
想清楚,再下手写代码
我写代码的速度非常快,因为我已经花了超过十年的时间在写代码了。很多东西想实现,对我来说基本是纯粹的堆代码。导致我非常容易不经过多的思考就开始动手写。我为此吃了不少亏,常常写到一半发现一些没有想到过的问题,导致需要重新设计,重新改写。我的一位前老板很了解我,他也是个多年经验的程序员了。有一次我们在讨论一个新东西,他对我说,「不要着急,想清楚了再写」。这句话我一直记在心里。后来每次动手写代码之前,我都会把整个流程的设计先思考清楚,避免了很多不必要的重写。
敬畏用户
在写自己的一些没什么人用的开源库或者公司内部用的平台的时候,通常不需要过多思考就能把代码发布出去。到了做花呗这种用户基数庞大的产品,才意识到代码发布和以前所体验到的完全不同。
蚂蚁金服有代码发布的「三板斧」,这是从入职培训到实际工作中就会被反复提及的 must-follow rule. 「三板斧」指的是「可灰度」、「可监控」、「可回滚」。在代码发布之前,要先想想自己的代码是不是符合这三个条件。
你的代码发布之后,如果出了问题,是不是可以被监控到的? 你的代码是不是可以灰度发布的,而不是一下子全量被推到线上的? 代码发布以后,出了问题,是不是可以回滚的?如何回滚?在经历了用户基数如此庞大的产品开发之后,我对代码发布变得尤为审慎。我记得有次只是单纯改了某段 HTML, 但我还是盯着这个 PR diff 看了几分钟,在想这个修改会不会导致什么问题。
虽然蚂蚁的基础建设可以让这三板斧很容易实现(有成熟的发布平台进行灰度和回滚,有成熟的监控库);虽然即使遵守了三板斧,还是会有 bug. 但是这种代码发布的思维模式是好的,即使我到了别的公司,我在代码发布前还是会问自己这三个问题。
跨团队合作是利益交换
在大公司里,有时在做一个事情的时候,需要别的团队一起合作,或许是用到别的团队的接口、或许是需要别的团队开发新的接口,但这通常很难。我以前天真地以为,只要我们做的事情是有利于业务的,别的团队自然就应该一起合作。但实际上,大家更看中的是这个事情对自己的团队有什么好处。
换位思考一下,我们和别的团队合作,对于他们来说,增加了工作量,增加了风险(带来更高的 qps, 写更多的代码会导致更多的维护成本)。决定是否合作,首先取决于这是否是自上而下的要求,其次就是合作对他们的 KPI 有没有好处。
所以我学会了在游说别的团队合作的时候,首先应该想明白合作能给别人带来什么好处,而不是对事情本身夸夸其谈。这样更容易促成合作。
用别人的语言交流,会有意想不到的收获
有研究发现如果你用别人的母语和他交流,他会更容易接受你的观点,对你也会更友好。我发现这个心理同样适用在技术交流中。作为一个前端程序员,在和后端程序员商量技术方案的时候,如果可以更多地使用后端的术语,从后端的角度反推前端的想法,他会更容易接受。
我自己业余是个 full stack 程序员,所以很容易切换到别人的语境,也能从别人的角度去理解他的想法。因此沟通会更加顺畅。
理解前人写的「烂代码」
这里的「理解」不是指理解烂代码的逻辑,而是理解为什么会写成烂代码。我经常会听到同事报怨他看到的旧代码写得如何烂,但是实际上很多烂代码产生的原因不是因为技术不行,而是受限于技术的发展和业务的复杂性。随着自己写的代码越来越多,就越能理解这些「烂代码」的存在。看出来了烂代码,也不要着急去重构,这些代码很有可能藏着一些你不知道的特殊业务需求。如果你不需要碰这些代码,那就尽量别碰。
在技术和工作之间找到平衡点
在刚出来工作的前几年,我特别陶醉在把自己学到的新东西试图用在工作中。我的想法是,只有我把这个技术用到实际的工作中,我才算学习了这个技术。
其实这个想法是不对的,学习技术并不一定要求你把他用到工作中。工作就是工作,学习就是学习。工作的内容是为了业务服务的。我在创业公司工作的时候,曾经因为把一个我刚学习到的库用在业务中,因为一些我不知道的坑导致业务进度出了点问题。老板生气地说:业务不是你的试验田。
我后来遇到很多「后辈」(我竟然也开始有后辈了) 请教我说觉得自己在工作中不能运用到自己平时学习的技术,因此觉得自己技术没什么长进。我认为这种想法不太正确。
能把学习到的技术运用到自己的工作中当然是最好的,但这是可遇不可求的事。但是这不代表没有用在工作中,就等于没有真正学习到这个技术。我认为很多人对技术学习有错误的理解,对我来说,学习技术的精髓在于理解这个技术的 Why, What, How. 和能不能用到工作中没有太大的关系。
举个例子,我在刚接触到 Redux 的时候,我去学习它,除了了解它怎么用以外,我特别关心的是,Redux 的哲学是什么?是什么启发了 Redux 的作者创造了 Redux? 他和别的库有什么不同?顺着这些问题,我就会了解更多的东西,比如我发现 Redux 是受了 Elm 的启发,我就会去了解 Elm -> 了解 Functional Programming -> 了解 Immutable, 然后关注 Dan (Redux 的作者) 的 Twitter, 看他日常会分享什么,看他对自己做的这个东西的理解是什么。即使我没有把 Redux 用在工作中(事实上我从来没有用过 Redux),但我在学习这个库的时候,我学习到的不仅仅是 Redux 本身,还有它背后的更多东西。我可能很快就会忘掉 Redux 的 API, 但那又如何,那些它背后的知识才是最有价值的,是不会被忘掉的。
而工作则相当于是一个真实的场景,是在你学习新的技术的时候,帮助你进行实际思考的场景。你需要有意识地去想,这个技术如果用到我的工作中,它是否适合?它能解决什么问题?它为什么适合?它为什么不适合。当你在学习新技术的时候,结合这个技术,多思考这些问题,这才是真正的学习。
文章来源:
Author:Randy's Blog
link:https://lutaonan.com/blog/things-i-learnt-after-6-years-as-software-engineer/