其实关于这个主题,我也仔细想过,是放在生存发展篇合适,还是放在职业素养篇合适。最终还是觉得,作为程序员,发挥主观能动性应该算是一个基本的职业素养。
很多时候,只要我们勤勤恳恳,认真负责地做好老大交代的任务,就算是一个合格甚至优秀的员工了。但是程序员这份工作,如果只是做到这一点,最多算是合格。由于软件开发的特殊性,一个任务完成的界限是非常模糊的,而且会根据具体的情况而变化。那么这时候,就要求程序员发挥自己的主观能动性,才能把事情做成,能够交付,而不仅仅字面意义上的“完成工作”。
你可能会想,说得这么玄乎,是真的么?我们来看两个例子。
数据清理和数据标准化背后的要求
在一个数据处理和分析的项目中,有两个功能是对订单数据进行数据清理(data cleaning)和数据标准化(data normalization)。
我首先简单介绍一下数据清理和数据标准化。我们要知道,来自不同的订单数据源的数据质量是不一样的。有的会缺失重要的信息,比如说购买者的ID、商品详情、订单时间等等。过滤掉这种缺失信息的不合格的数据,这就是数据清理。
数据标准化则是对数据中的数据格式进行标准化转换。比如有的时间用毫秒表示,有的用秒数表示,有的用不同的格式“2020年5月15日 15点30分15秒”“2020-3-15 15:34:45”,有的甚至用不同时区的时间。再比如对于苹果这个品牌,有的数据用“Apple”表示,有的用“苹果”表示,有的用“苹果(Apple)”表示等等。那么数据标准化的任务就是要将这些数据转换成统一的格式。
怎样才叫“任务完成了”?
如果按照需求文档里的描述,我们完成了数据清理和数据标准化处理,这样是不是就叫完成了呢?如果你是负责开发的程序员,你还会做些什么呢?
你可能会想到单元测试,代码覆盖率等。不错,这说明你已经是一个“摸着良心”干活的程序员了。那么除此之外呢?还有什么可以做的呢?如果就这么交付出去可以吗?
一个有经验的程序员会想到,这种功能可能会用到不同的计算框架上,比如 Spark、Flink 甚至 是Hive。而之前蹚过的坑会告诉他,不同的计算框架内置的Jar 包的版本都是不一样的,自己的程序要能够尽可能少用兼容性差的 Jar 包。那么也许他就会在开发期间,跑去问相关的用户,这个功能可能会跑在什么框架的什么版本上,然后按照计算框架的版本,确定自己使用的 Jar 包的版本。当然,系统架构设计等也是一个需要用心的地方,我们在后面再细聊。在这里先不涉及。
做了这一步,用户集成的过程就会顺畅很多,虽然你自己确实付出了一些额外的时间,但可以帮助整个项目的进度不被 Jar 包兼容性的问题所阻塞。
当然,从责任上来说,功能是否要适配到不同的计算框架,应该是在需求上写清楚的。但是道理归道理,实际归实际。没有人能把所有的细枝末节都考虑全面,互联网时代,软件开发和迭代速度并没有给我们这么宽裕的时间。
如果因为各种需求没有说清楚,导致最终做出来的功能无法使用,我们程序员虽然可以把锅甩出去,但程序员作为一线工作人员,很多细节可能只有走到那一步的时候,才能想得全面。如果一个程序员做事情永远只知道按照需求中写的做,不多考虑一分,实际上就是自己的失职。从结果上看,就是程序员没能交付自己的工作。长期如此,是很难成长为一名合格的、让人觉得可靠的程序员的。
站在用户的角度试想一下,如果用户的这个项目要在 Spark 上用到两个功能。一个功能出现了各种 Jar 包版本兼容性问题,各种跑不起来,各种修改 Jar 包版本,甚至还需要修改代码,整个集成过程从原计划的三天拖延到了三周。另一个功能一下就用上了,一点毛病没有,原计划三天的集成时间,一天就搞定了。你会给这两个功能打多少分呢?又会倾向和谁合作呢?
当然,这里的例子其实是一个比较明显的例子,确实应该在需求中写清楚平台和版本。但是在程序员的工作中,确实有很多我们需要考虑的细节,有很多考验我们“良心”的地方。发挥自己的主观能动性,多为用户考虑一点,是评判一个程序员是否合格的重要标准。
一个合格的Dashboard是怎样的?
聊完了数据清洗和数据标准化,我们接着聊下一个需求。这个需求是设计一个Dashboard,把每天的销量和销售额用一个Dashboard展示出来。
这个需求看似很简单,就是把数据按天展示出来嘛。按照需求,我们先原封不动地作出一张如下图所示的Dashboard。

我相信,大部分用户看到这个图,第一个问题都会是:怎么就一根线?你可能会说,我确实把销量和销售额都展现在图上了啊,按照需求做的没毛病啊。用户有问题那是他们需求有问题,用户只看到一条线那是用户不会看。
这种看似忠于需求的工作态度,其实并不能真正地让用户对工作成果感到满意。当然,程序员将需求做出来了,确实只是如此,没有人能挑出毛病,但也不会有人喜欢跟这种程序员合作。
为什么呢?正如上面的例子所说,在互联网快速迭代的今天,需求可能不会那么细致。我们依然要站在用户的角度看问题。
那么这张图到底有什么毛病?
在上图中,因为销售额比销量大很多,销量被销售额的数字“压”得几乎成了一条底部的直线。那么这样一来,有一个很明显的事实就是,销量这根线,已经不能传递任何信息了。除非用户是列文·虎克,有耐心还喜欢拿着显微镜看报表。
所以用上面两个例子我想说明什么呢?
完成明面上的用户需求,仅仅只是我们工作的合格线而已。一个程序员应该基于需求,把自己的触角延伸到需求之外,交付用户真正想要的东西。比如给报表增加按照对数设置Y轴坐标的功能,让数据相差特别大的两根线,也能在同一个Dashboard里展现自己的“曲线”,如下图所示:

我相信,任何一个用户都会更喜欢第二种方案。虽然需求没有明确说要支持这种功能。但是从交付的角度,第二种方案才能对用户产生实际的价值。
那么前面通过两个例子,我描述了一下程序员这个工种对发挥主观能动性的要求。下面我们来谈谈如何发挥主观能动性。
如何发挥主观能动性
其实发挥主观能动性的方式会随着程序员具体工作内容的变化而变化,比如说前端工程师、后端软件开发师、架构师等等。但总有一些东西是共性的,那么在这里,我就说说我的几点建议以及需要注意的东西。
我在上面反复强调交付思维,所以我觉得这一条应该列在第一位。
交付思维
发挥主观能动性,究其核心,我觉得就是一点:站在用户的角度,交付用户想要的东西。也就是说,不能止步于用户的需求。程序员作为冲在第一线的人,对细节的掌握是最多的。我们需要依靠这些细节,结合用户的需求,理解用户需求背后真正想要的东西,然后努力向这个目标发展。
正如前面的两个例子,其实做得好的标准,就是理解用户没说出来的需求,能够为用户着想,交付用户想要的东西。
注意时间
发挥主观能动性的一个代价,就是会用掉更多的时间。这方面一定要注意。比起功能的完美,在规定的时间内实现基本功能,才是优先级更高的事情。
假如你突然对一件事情有了想法,但是时间来不及,或者不确定是不是对用户有价值,那么可以及时和用户交流。如果用户觉得这个细节确实很重要,即使延期也值得做,那么大家可以商量新的时间线。如果用户觉得可有可无,或者可以放在后续迭代来做,那么就专心做好需求里描述好的功能。
程序员在发挥主观能动性的时候,也难免会“夹带私货”。比如说,自己想用个什么新技术,试试不同的做法。这时候也要注意时间。用户可能一时无法理解新东西给自己带来的好处,但是用户肯定知道项目无法按时完工的坏处。所以在“夹带私货”的时候,一定要保证自己对项目的进度有所把控,不要因为自己的私欲让整个项目无法完成。
总结
程序员这个职业,已经远远延伸到了写代码之外。对内我们要DevOps,对外我们要交付对用户有价值的东西。而发挥主观能动性,就是帮助我们做对用户有价值的事情。程序员接到需求之后,要进一步理解需求背后的用户意图,理解用户的问题。
正所谓,将在外,军令有所不受。又有言:让听得见炮声的人决策。程序员就是那个拿着作战目标,冲在一线,能够听得到炮声的人。面对系统实现时各种复杂的情况,我们有责任,也有义务发挥自己的主观能动性,达成最终的作战目标。

思考题
你在工作中,有发挥自己主观能动性的习惯吗?有发挥自己主观能动性的场景吗?
欢迎你在评论区和我分享你的留言,也欢迎你把这篇文章分享给你的朋友或者同事,一起交流进步一下。
精选留言
2020-05-25 09:08:40
2020-06-04 08:31:54
2020-05-26 01:04:01
发挥主观能动性对比恋爱中如何在节日里制造原定之外的surprised,
但是要考虑一个问题也就是说这个surprised对方是不是会肯定喜欢,
同时也要考虑到制造这个surprised的时间,精力成本。
2020-05-25 09:37:37
2020-08-05 00:12:11
文章提到: 如果一个程序员做事情永远只知道按照需求中写的做,不多考虑一分,实际上就是自己的失职。
如果我们多考虑了(比如实现了可扩展、松散耦合等等), 也跟需求方交流了,按期完成了一个堪称完美的可交付物。皆大欢喜了吗?
问题来了, 由于自己做的太好了,以至于这个需求从开发到上线,一点问题没有,长期下去,同事或者领导眼里觉得你手上事情太少。 反倒是那些没有主管能动性的, 天天有人来找(为什么?需求有问题,考虑不全面, 但开发人员还是按需求去实现了,没有多考虑),结果这些人天天忙的焦头烂额的,工作周报上写的满满的,解决了什么什么问题,修复了什么什么缺陷,一月下来,名下的需求和缺陷在Redmine上能翻好几页。
而那些主动的人呢? Redmine上,3-5个条目,一页都不到。周报上再怎么写,领导眼里也觉得这是个大闲人。
公司恰好是以git代码量和Redmine条目衡量每个人的工作量。
我心里就想: 以数量衡量工作量,不看质量的吗? 那么我可以明知道需求有问题的情况下,就按需求做, 到时候有问题提缺陷, 我也可以把周报写的漂漂亮亮的,git上满满的代码,Redmine上好几页的条目。
需求定的有问题,需求方就有错吗?我们不主动,我们就不合格吗? 这时候我们去适应环境,做一个职场“老油条”,更加顺风顺水。
2020-05-25 08:11:48
2020-08-02 11:45:19
刚入职新企业没多久,老大给了一个任务,对一个网站开源项目进行调研,然后进行改造以契合公司内部业务。经过和一个同事一起调研,发觉这个开源项目并不好用,issue很少,star也很少。但老大还是比较乐观,坚持用这个。所以,开始对其改造,整个过程我觉得挺难受的,思前想后考虑各种因素,每当遇到一个问题我都找老大确认,这样以来可能给老大的感觉不是主动,而是我自己没有思考。
不过最后,还是确认了最终的方案,尽管并不完美。——这里引用课里一句话“比起功能的完美,在规定的时间内实现基本功能,才是优先级更高的事情。”
回顾整个过程,我觉得最难受的就是自己的完美方案构想,跟老大的想法在刚开始的时候脱节了。自己拿一个完美的标准去衡量了老大的标准,直到在最终方案确认时我才发现,老大并不是非得要那个理想的,完美的东西。他要的一个最低标准只不过是解决当前公司内部存在的问题。如果我一开始知道这点,可能不会那么觉得那么难受了😣!
2020-06-05 19:23:21
2020-05-26 16:05:35
2022-04-16 16:10:56
1. 直接对接客户需求和有专门产品对接客户需求这两个方式谁好谁坏?如果加了中间产品对接的角色,那么势必会导致信息失真,有可能客户说的a,产品理解并转成了b,然后我们理解实现变成了c,那么a->c就有一定的偏差?如何纠正这个偏差呢?
2. 在有客户经理和产品经理的角色介入下,如何也能按照本章讲的发挥我们主观能动性呢?
3. 本章讲的核心内容都是完成的基础上,然后再多想多思考,然后完成好的的基础一步步迭代变成完美的东西,可是我们项目基本做的都是一锤子买卖,实际上并没有很大的程度的可持续交付,虽然在之后的用户使用的过程中,总会产生一些不大不小问题,我们采取的策略都是客服尽量安抚,安抚过去了这事就算了事了,安抚不过去,才考虑如何处理,如果问题不大,比如数据问题,那就改数据等等这些不痛不痒的解决行为,我想请问我在这种场景下,如何做到多想多思考,多为用户解决问题呢?
还请大佬解答,谢谢!
2020-11-12 17:18:19
2020-11-06 13:40:43
2020-06-21 04:29:00
时间永远不够,延期交付会让你成果失去价值。交付期限内先行推出,告知问题与待解决的方案和时间。先求有再求好,因为没有产品或任务是可以一件完美,可以完成,但要不停的维修升级,达到需求完善。
2020-06-06 02:17:33
如果用户有提出需求,我们能做的就是花心思和时间去思考用户想要解决的问题是什么,根问题又是什么,借鉴自己以往的经验想出解决方案,并不断和用户交流以致完善解决方案中的细节。不管最后的结果如何,以及我们是否能够达到用户的期待,在这个过程之中,用心了,就会有成长和经验的积累
有些时候比较棘手的是,用户没有提出需求,你需要根据用户的表现找出背后隐藏的需求。比如说要在类似淘宝的购物平台上设计一个根据用户信息推荐商品的功能,问题在于用户需要的是什么我们其实并不清楚,唯一可以依赖的就是数据,另外能想到的就是和同组的前辈多多交流经验。不过这种情况下,想要做好,更加需要主观能动性,另外,有些时候,方案 A 可以,方案 B 也行,不知道选了个的时候,可能要做的还是多尝试,多积累,见的多了就不怕了。不知道老师如何看
2020-06-01 09:00:29
2020-05-30 17:31:09
总结来说,时时换位思考,考虑如何有利于其他人的工作,帮避免一些不必要的麻烦,他们
2020-05-26 15:32:09
2020-05-26 11:54:07
2020-05-25 08:36:49
想着本质进步,是成稀缺人才的方式。
2020-05-25 08:28:57