聊聊程序员的职业生涯,我对程序员这个职业的理解

工作这些年来,一直在思考着程序员这个职业究竟是在做什么,随着经验增多,其实也一直在刷新着认知。现在写这篇文章,一方面是为了分享,另一方面也是想留下一份记录,过两年再回头来看看自己的认知又有了什么更新。

我想从两个方面来说。一是从做的事儿上,在我看来,程序员的工作就是发现问题、分析问题、解决问题三类。事实上,世界上绝大多数工作都可以囊括进这三类事中。二是从能力上来看,我把能力分为两种:对现实世界的认知能力,和将现实世界映射成程序语言的能力。

对于三种类型的事,按发现问题,分析问题,解决问题的顺序,是从宏观到细节的区别,平时做的事,肯定是以解决问题为主,各种琐碎的事,也都是在解决问题。发现问题和分析问题对人的思维深度会有更高的要求,不过对于工作来说,我倒并不觉得这三类事有什么高下之分。如果对确定的问题,总能给出恰当的解决方案,这也是职场上非常硬核的核心竞争力。而对于两类能力,一般还是更关注第二种。但是我觉得对现实世界的认知能力,对于程序员的职业发展是非常重要的。就像抠业务,抠CRUD这事,有门槛吗?我觉得是有的,至少把业务做的很好门槛非常高。有些人总是以非常奇特的方式去实现业务,然后赖产品经理需求描述不清楚,很可能就是缺少对现实的认知。

接下来,就按发现问题、分析问题、解决问题的顺序,分别详细说一下。

发现问题的能力,对程序员来说,其实不是必需的。很多问题,即便你发现不了,或者发现了然后假装它不存在,系统一样可以运行的很好。但是,逐步的累积这种问题,最终必然会导致代码不可维护。下面,我拿一个自己的实际经历来举个例子。之前做过一个旅客飞行记录的项目,国内航班的数据,我们几乎都能拿到。数据存储的时候,主键是用的证件号,为什么呢,因为所有的订票系统,都是用证件号去做key的。但是我们的产品形态并不是这样,而是以用户的维度去显示,一个用户会有多个证件。这样就导致了一个问题:任何一个非常简单的问题,比如要查用户最近一条飞行记录,最近十条飞行记录,都会有一套复杂的处理流程。更不用说随着数据量增加,要分库分表,但同一个用户的证件没法往一张表上落,逻辑复杂度再提升一级。在这个时候,不发现这个问题,其实业务也完全开展的下去,但是很显然,做这块业务就会做的很难受。而意识到这是个问题,再做相应的调整后,才会发现原来这一块的业务如此简单。

那么,怎么才能发现问题呢。这需要我们有对现实世界的认知能力,也需要对设计模式等基础知识有足够的理解。要发现问题,我们首先得有“正常状态”是什么样子的概念,与正常状态不一样的,就是问题。比如前边的例子,一个“正常状态”是查询用户最近的飞行记录,这个需求应该非常简单,还有一个“正常状态”是我们的用户是一个人,而不是一个证件,发现了和政策状态不一致,也就发现了问题。再举一些例子,写单元测试应该是很简单的,当发现单元测试不好写的时候,就需要考虑一下是不是代码的设计出了问题;mysql的一次batch请求,耗时的数量级应该在毫秒级, 而且数据量不应该严重影响耗时,当发现数据量和耗时的关系成了一个非常陡的线性关系,就要考虑一下是不是真的做了次batch(参考 http://lichuanyang.top/posts/63688)。

接下来是分析问题。对于分析问题,我觉得说白了就是把一个表现出来的问题,拆解成一个或若干个“指标”出了问题。这些“指标”,可以是内存、cpu这样实际的指标,也可以是一些基本的概念理解、设计思路。还是上一个例子,我们发现的问题就是一些很简单的需求实现起来很难,最后拆解出来的出问题的“指标”就是存储记录主键的选择。

对于分析问题,要会做合理的可能性推测,然后多利用工具验证或者推翻猜测。之前有一次发现数据存不进数据库,这时候就可以做出若干个合理的推测:数据库本身有问题;和数据库的连接有问题;事务未能正常提交;逻辑错误导致数据未能生成;等等。然后去翻日志,看有没有报错,看Mysql监控,有没有大量未能提交的事务。逐步就定位到问题了。

最后说解决问题,对大部分程序员来说,这个一直会是做的最多的事。而程序员的解决问题,也就是把现实中的概念在计算机中表示出来。其中最关键的,我理解有两个,一是分解任务,把一个大任务拆分成若干个独立的子任务;二是迅速的理解并使用新工具能力,也就是持续学习的能力。很多人会经常抱怨程序员要学的东西太多了,学不过来了。不过一定要注意哪些东西是值得花费大量时间去学的,哪些东西是简单看看就足够了的。发现有很多人热衷于工具的学习,喜欢写各种版本的Hello World, 这个在我看来就是无效的学习。编程方面的学习,需要兼顾深度和广度,深度,是需要非常透彻的研究一些技术,这个看了一些之后,你会发现各种技术,看起来可能没什么关系,比如数据库和消息队列,但是其中就是会有非常多相似的概念和思想。学过一些之后,就可以建立起自己的知识体系了,然后再去学其他的东西,就会非常快。

因为一个新技术的产生,必然是迫切的要解决一些实际问题。比如为什么会有clickHouse, 因为mysql等的按行存储不适合数据分析,而市面上又没有性能、稳定性都比较好的列存储数据库。再比如jedis直接连redis-server, 在多线程环境下表现不好,所以有了Lettuce。当知道要解决什么问题后,就可以先试着想一下换成你的话,有什么解决方案。然后再去看看人家实际的解决方案。如果方案很接近,那么恭喜你,你对技术的理解已经又上了一个高度。如果不一样,那也恭喜你,又学到了一种新的思想。这些思想,在以后做业务的时候,随时都可以化用。

共勉。

原文地址: http://lichuanyang.top/posts/27398/