2015第32周四

    团队成员的沟通只限于“业务沟通”。大家只忙着干活,项目经理和成员之间,成员和成员之间,都只谈工作上的事情。除此之外的交流,都好像搞运动,完成任务,推一下就动一下,不推就停止了。

  明眼人都知道,这样的状态是不对的,长远来看,工作效率是上不来的。工作,尤其是创造性工作,其中是有大量不确定的模糊地带的,需要大家具体协商解决,而不能依靠刚性的制度来事先规定。虽然沟通的问题是工作问题,但离不开工作之外的关系、情商等等“软实力”。否则,日常的协作很容易变成公事公办,大家的分工也成为“铁路公安各管一段”。更重要的是,团队失去了凝聚力,成员失去了归属感,引发大幅的人员流动。

  为什么会出现这种情况呢?我仔细问他,找到了问题所在:招人的标准过于一致,挑选的大都是技术不错、扎实肯干,能投入做工作的人。

  对具体的招聘岗位来说,技术不错、扎实肯干、能投入工作,这样的标准作为基础当然没有问题。但作为团队的统一标准,就未必合适了。因为团队是个综合的有机体,不能以绝对单一标准来衡量。即便是软件公司,即便招聘的是技术人才,也不能以这样做。如果全是同样的人,一方面大家不太容易因为差异产生新奇的感觉,所以难免感到乏味单调。更何况,许多程序员自己是闷瓜型,并不代表他希望呆在一个闷瓜型的团队中工作(可以参考我写过的《软件开发的人文关怀》)。

我自己经常会观察软件开发团队的现状,对比理想的软件开发团队,继而决定在招人时需要侧重哪些方面,为团队引入差异性:

  1. 对于技术上不思进取的团队,就要引入技术精纯的人来抬高大家的眼界,激发大家对技术的热爱;

  2. 对于沟通沉闷的团队,就要引入性格开朗、能说会道的人来促进交流,让大家习惯更密切更频繁的交流;

  3. 对于生活比较单调的团队,就要引入有健康兴趣爱好而且有足够魅力的人来带动大家,让大家的生活丰富起来……

  按照这样的做法,或许短时间内确实“错过”了一些还不错的人。但总的来看,能够始终把团队保持在一个比较健康的状态,营造不错的凝聚力和工作氛围——不要忘了,带领团队是长跑。


  软件开发工作无论是从宏观还是微观上看,都可以看作一个问题解决的过程。从宏观上看,软件开发,简单来说,就是弄清楚客户的需求是什么,然后通过分析、设计、编码和测试等一系列活动解决如何将需求转换为代码的问题。从微观上看,开发人员的日常工作中也面临各式各样的问题。比如,用于调试代码的Web服务器突然启动不了,开发人员必须先解决这个问题,否则手头上的工作可能无法进展。

  作为开发人员,与其抱怨加班,不如去反思下自己的时间都去哪里了。我相信开发人员的大部分时间都花在解决各种各样的问题上了。不管是资深的开发者、还是新手,在日常的工作中都会遇到各式各样的问题。所不同的是,资深开发者可以在几秒内解决的问题,新手却可能要花上几个小时,甚至一两天的时间!可见,提高开发者的问题解决能力,无论对于个人还是对于团队,都有着重要的意义。

  其实,心理学作为一门独立的学科,对于问题解决有其专门的研究。其研究成果值得我们借鉴,以提高我们自身以及团队中的其他成员的问题解决能力。本文将为读者介绍心理学关于问题解决方面的知识,并结合软件开发工作的特点给出提高问题解决能力的相关指导意见。没有心理学背景的读者,也不必担心“隔行如隔山”,本文所涉及到的一些心理学术语,大多都是浅显易懂的。

  重新审视什么是“问题”

  提高问题解决能力,首先要弄清楚究竟什么是“问题”,然后才能谈如何更有效率地去解决问题。

  心理学将“问题”定义为“给定信息和目标之间有某些障碍需要被克服的刺激情境”。通俗的理解就是,对于给定的事物的初始状态(所谓“给定信息”)和目标状态,我们不清楚如何将初始状态转换为目标状态(所谓“障碍”),“问题”就产生了。例如,著名的梵诺塔问题,其初始状态是64个盘子在A杆,目标状态是所有盘子在C杆,并且每个小盘都在大盘之上。所存在的需要被克服的“障碍”就是如何将64个盘子从A处移动到C杆。

图 1. 梵诺塔问题

  按照上述定义,解决问题就是克服“障碍”的过程,即寻找到一条从初始状态通往目标状态的通路的过程。如梵诺塔问题中,我们反复借助B杆,最终将A杆上的所有盘子“原封不动”地移动到C杆的过程就是问题解决的过程。

  那么,提高问题解决的能力就是提高我们找到一条从初始状态通往目标状态的路径的能力。

  为了下文讨论方便,这里简单地将软件开发领域的“问题”划分为界定清晰的问题(Well-defined problem)和界定含糊的问题(Ill-defined problem)。前者指初始状态和目标状态都很清楚的问题,如梵诺塔问题。后者指初始状态、目标状态或者二者都很模糊的问题,这类问题往往更难解决,对问题解决者的要求也更高。与软件运维有关的问题多属于这类问题。比如这样一个问题:某个生产环境上的数据库系统自动重启,需要查明其原因。

  解决问题的心理过程

  就像了解计算机处理信息的原理有助于我们更好地使用计算机,了解人类解决问题的过程有助于我们更好地解决问题。

  心理学家一般把问题解决的过程分解为问题表征、设计解题计划、执行解题计划和监控这四个步骤。

  问题表征指明确问题的初始状态、目标状态和允许的操作和必须满足的限制。梵诺塔问题中,问题解决者首先对问题进行表征,即弄清楚:64个盘子在A杆上,小的盘子在大的盘子上面(初始状态)、目标是将这64个盘子移动到C杆上,C杆上的每个盘子仍然保持小盘在上,大盘在下(目标状态)、移动过程中可以借助B杆,但是移动过程中保证小盘始终在大盘上面(允许的操作和必须满足的限制)。

  设计解题计划指确定解题的步骤。梵诺塔问题的问题解决者通过比较问题的初始状态和目标状态,准备借助B杆递归地将A杆的所有盘子逐步地移动到C杆,就是设计解题计划。

  问题解决者设计好解题计划后,就执行解题计划,并在执行过程中时刻进行自我检查当前的操作是否有助于解决问题、相关操作是否满足问题的限制,即执行监控。如梵诺塔问题的问题解决者在移动盘子过程中要注意小的盘子是否在大的盘子上面,移动盘子的结果是否如事先预期的那样能够使越来越多的盘子放在了C杆上。

  下面我们讨论,影响问题解决的心理因素。

  影响问题解决的心理因素

  问题的表征方式

  问题解决的第一个步骤中的问题表征,还可以再分为两个小步骤:问题表层理解和深层理解。

  问题表层理解就是将问题用问题解决者自身的语言来描述的过程,这是解决问题的最基础的一步。问题的深层理解是在问题表层理解的基础上,进一步把问题的每一陈述综合成条件和目标的统一体。这一子步骤中,非常重要的一点是区分问题中有关的信息和无关的信息。对于无关的信息,可以忽略之,也可以采用不同的方式去理解和表示之(即表征)。

  在问题深层理解的过程中,问题的表征采用的方式不同对问题的解决难度可能有很大的影响。这点,可以从典型的一个问题——和尚上山问题(见左边侧栏)反映出来。

  和尚上山问题给人的直觉的反映是似乎不大可能存在这样一个点,因为和尚上下山的速度不一样。然而,当我们发现这个问题可以看作这样一个问题时:两个和尚在同一时间点,沿着同一条山路,一个下山,另一个上山,答案就非常直白:这条山路上必然存在一个点,在某一时刻这两个和尚会相遇。那么,原问题的答案也是肯定的。这个问题的解决中关键的一步是,在对问题进行深层理解的过程中,我们采用与问题表层理解中不同的方式来表征问题:表层理解中问题描述的是同一个和尚上下山,而深层理解时我们发现是否是一个和尚上下山是一个“无关”的信息,我们可以将这个信息理解成两个和尚同时上下山。

  下面看一个软件开发中的实际例子:我们要对网页上的一个表示文章关键字列表的字段的值进行合法性校验。校验的规则是该字段的值不能为空,若字段值不为空,则多个关键字间用英文分号分隔。例如:“keyword1;keyword2;keyword3”。显然,这个可以用正则表达式来校验。问题就转化为这个正则表达怎么写。按照问题的表层理解(如上面文字的描述),关键字列表的字段值的格式会被表征为:

(关键字1)+;+(关键字2)+;+(关键字3)+...

  这样的表征固然直白简单,但依照这个表征,相应的校验正则表达式不是那么容易写。相反,如果把字段值的格式换作另外一种表征,相应的正则表达式就容易写得多:

(关键字1)+(;关键字2)+(;关键字3)+ ...

  依照上述表征(即从第二个关键字开始,每个关键字都需要以";"为前缀),可以得出相应的正则表达式(Javascript语言表述)为:“^[^;]*(;[^;]+)*$”。

  因此,当我们在解决问题,尤其是一些比较困难的问题时,若没有什么进展,而又没有什么新的思路时,不妨回到问题的原点,重新去表征问题,换一种新的方式去表征问题。或许,这个时候就会豁然开朗。这就好比我们在侦探题材的影视作品中经常看到的情景:侦探在查案过程中,费了许多人力和时间案情都没有什么进展,这个时候要突破困境的一个好的方法是从“零”开始:重新回到案发现场,重新去寻找蛛丝马迹,重新进行推敲。这个时候,案情往往就柳暗花明了!

  问题的表征充分程度

  若我有一小时的时间来拯救世界,我会花59分钟来定义这个问题,并花一分钟的时间来寻找解决方案(If I had an hour to save the world, I would spend 59 minutes defining the problem and one minute finding solutions––– Albert Einstein)。

  心理学研究表明,在解决常规问题时,专家比新手快得多。而在解决困难问题时,专家用于表征问题的时间比新手要长一些,他们会用更多的时间去收集问题的相关信息,因而对问题的表征更加充分。

  有这样一个个案。运维人员报告某个生产环境的进程数过多,向研发人员求助定位该问题。而对方所提供的信息仅仅是说“主机上的进程数过多”,附带一款监控软件所报的告警信息:“XXX主机上的进程数超过260”。

  该问题的解决过程是:首先,弄清所谓“进程数过多”,具体是什么意思。结合监控软件的告警信息,可以回答该疑问:所谓进程数过多,是指主机上所启动的进程数大于监控软件所预设的进程数量(如260)。此时,问题似乎明朗了:找出260个进程之外的进程是哪些,问题应该就能解决。但这也存在一个问题,假设进行问题定位的时候,该主机的进程数是265个,这其中的每个进程对我们来说都是没有差别的,我们又如何将这些进程区分为两部分呢?

  进一步向对方询问得知,问题所涉及的主机系一个集群环境(共几十台主机)中的一台,而经过确认其它主机上并没有出现该问题。那么,通过比较该主机上的进程名称列表和集群环境中另外一台主机的进程名称列表,可以发现出现问题的主机“多出”了哪些进程。最后发现,该问题系运维人员定制了一个定时任务,该定时任务调用的Shell脚本重复运行(前一次脚本运行对应的进程未结束,新的脚本运行又开始了),从而导致进程数越来越多。

  当笔者将上述问题写为问题定位案例给新手进行定位时,新手的反应是懵了,不知从何下手。

  正如上述个案所展示的,软件行业中遇到的问题多数是定义模糊的问题,尤其是一些生产环境中出现的问题。对于这样的问题,专家能够通过自己的分析判断、进一步收集与问题有关的信息,使问题逐步转化为定义良好的问题,再通过适当的问题解决策略(如上述的比较法),从而解决问题。而新手往往不知所措。

  因此,对于定义模糊的问题,其解决思路大体上是试图将其转化为定义良好的问题,途径是通过分析判断,收集有关问题的更多信息。而对于新手,平时通过观察专家解决问题的过程,并试图模仿之,也是一个提高解决问题能力的方法。

  观察能力

一切推理都应该从观察和实验中得来。

––– 伽利略

  在解决软件行业的问题过程中,视觉是人脑获取信息的主要途径。解决问题的过程中,人脑并不是被动地接受视觉信息,而是通过有意识的、带有目的性的主动观察获取信息。另外,软件开发过程中遇到的问题多数是界定含糊的问题,通过观察获得有关问题的更多信息有助于对问题进行充分的表征。因此,观察能力在解决问题的过程中显得非常重要。在我们的日常工作中也不难发现一点:专家在解决问题过程往往能够从一堆视觉信息中快速捕捉到其所需的关键信息,而新手面对专家所赖以解决问题的信息时却往往视若无睹!

  例如,如图2所示的一个几十行的Call Stack信息中,专家可以快速地定位到第35行这行关键信息,从而断定问题系磁盘空间不足所致,而新手则可能不知从何下手。

图 2. 从错误信息中快速定位关键信息

  日志文件、软件界面等所呈现的错误信息是问题定位的一个重要信息来源。但是经验告诉我们,“二八原则”在此也是适用的:这些错误信息中的大部分对于解决问题来说是无用或者用处不大的,而那些对问题的定位和解决能够起到决定性作用的关键信息往往就那么几行甚至一行。因此,能否在这些大量的错误信息快速找出那些我们需要的关键信息,往往决定了问题解决的效率。

  快速找到我们所需的关键信息,需要问题定位者的拥有敏锐的观察能力。提高观察能力,首先需要意识到观察能力的重要性。其次,在日常工作中逐步地学会区分自己在问题定位过程中所遇到的错误信息,哪些是关键的,哪些是帮助不大的。再次,掌握一些获取关键信息的基本技能。例如,对于与数据库有关的错误信息,要能够重点关注数据库系统所报的错误码。对于Java Call Stack信息,重点关注“Caused by”部分的头几行。

  笔者曾经通过引导组员意识到其观察能力的薄弱和观察能力的重要性,并通过实际的问题定位向其展示如何快速获取关键信息,帮助了组员一定程度上提高了观察能力。

  小结

  本篇介绍了问题解决的心理过程以及问题表征阶段影响问题解决的一些心理因素。并结合笔者实际经历的例子通过比较专家与新手在解决问题时表现出的差异给出提高问题定位与解决能力的指导意见。下篇将介绍影响问题解决的其它心理因素,并给出相关指导意见。


 

 影响问题解决的心理因素

  自我监控技能

大胆假设,小心求证

––– 胡适

  在设计好解题计划后,问题解决者并不是简单地执行解题计划,而是要时刻自己监控自己对解题计划的执行是否正确、解题计划本身是否正确。这有点类似行车过程中,GPS导航软件时刻检查车辆当前的行车路线与之事先规划的路线是否吻合。若不吻合,则导航软件会提示车主车辆已偏离规划的路线。。

  问题解决者自我监控技能的强弱可能对问题解决的效果和效率产生决定性的影响。例如,解决某道数学题时,解题过程中需要计算出某事件出现的概率,然后再以此数据继续解题。若经过很多步骤才算出这个事件的概率是1.02,通过自我监控则可以发现这个概率值的计算显然是错误的。那么,应该重新计算这个概率值,而不是继续执行其它解题步骤。相反,此时若未觉察到这个错误,继续执行其它解题步骤,最终的答案很可能是错的。

  专家在解决问题过程倾向于更加频繁地进行自我监控,并且其自我监控的效果比新手更好。专家在解决问题,尤其是一些难题,往往更加频繁地提出各种假设,并通过逻辑推理和寻找数据证据对其进行检验,然后再根据检验的结果提出新的假设,再对这些新假设逐一验证,通过这样的自我监控逐步向解决方案靠近。就好比拨洋葱皮,每拨一层皮,就离洋葱核心更进了一步,最终解决问题。而新手在解决问题过程往往很难提出假设,即便提出假设,他可能不能清晰地意识到那仅仅是个假设,便在此基础进行其它操作了。最后他们得到的所谓“结论”,可能通过简单的逻辑推理就可以发现是错误、甚至是自相矛盾的。

  笔者曾经遇到这样的问题求助。求助人在写一段服务端的Java代码,用于获取网页表单中提交的某个字段的值。求助人传达给我的信息是:网页中确实存在服务端代码中所要获取值的字段,但是服务端代码就是取不到该值,“原因”是浏览器并没有把该字段的值提交到服务器。我问对方得出这个“结论”的证据是什么?他又回答不出来。显然,他只是把“假设”和猜想一厢情愿地当作结论了。如果求助人在该问题的定位过程中做到了自我监控,他可能会问我如何去验证客户端某个字段是否被提交到了服务端,而不是问我这个问题如何解决。最后,通过简单的Debug查看变量,发现浏览器事实上提交了服务端所要获取值的字段,只不过服务端代码中所用的字段名的大小写弄错了!

  提高自我监控能力,不是能够一蹴而就的事情。需要问题解决者清楚地明白“结论”和“假设”的区别。在问题解决过程中,任何中间结论的得出都必须经过逻辑推敲和相应的事实证据(数据)。另外,也可以对自己的解决问题过程进行反思:在问题解决后第一时间,自己问自己在问题解决过程中,自己犯了哪些错误,有没有及时自己发现这些错误(而非求助于他人)。通过这样的反思,问题解决者能够跟好地理解自我监控的重要作用,有助于以后在问题解决过程中逐步加强自我监控。笔者有时在遇到一些问题定位的求助时,尤其是对方是新人时,往往会先问对方目前的结论和进展是什么。若发现对方的结论(或者中间结论)是错误的,我可能不直接指出,而是引导其思考,让对方自己发现自己的错误。这种方法一定程度上也能提高问题解决者的自我监控能力。

  短时记忆容量

  根据记忆保存时间的长短,人脑的记忆可以分为短时记忆和长时记忆。前者类似于计算机的内存,其特点是记忆保持时间短(约为5秒到2分钟),容量小。后者类似于磁盘,其特定是记忆保持时间长(永久保存)、容量大。人脑在解决问题过程中,需要将长时记忆中的内容提取到短时记忆中参与信息加工。而短时记忆的容量很小,它只能容纳7±2个块的信息。这个“块”是一个相对的单位,一个英文字母可以算一块,而一个英文单词也可以算一块。因此,适当增加“块”的长度可以增加短时记忆的容量。例如,手机号码”13612345678“按“136-1234-5678”这样3块来记忆比“136-12345678”这样2块来记忆要容易一些。

  尽管如此,对于复杂问题的解决,或许减轻短时记忆的负担比设法提高短时记忆容量要重要。毕竟人脑此时的主要任务是解决问题,而不是记忆。减轻短时记忆负担可以使人脑集中力量到其它更加重要的活动上,如逻辑推理、提出假设和验证假设。一种简单可行的减轻短时记忆负担的方法就在解决问题过程中打草稿。例如,将问题的已知条件、待确认的细节、问题解决过程中获得的新知识、新经验以及中间结论(它可以看作新的已知条件)都列在纸上,这样既不增加短时记忆负担,又便于综合考虑。同时,也便于同他人就问题进行讨论。

  动机强度与情绪

  相信大家都遇到过这样的情形。解决问题时,尤其是遇到困难时,自己越是强烈地希望去解决它,问题解决越是没有什么进展。相反,当我们适当地停下来,把注意力转移到这个问题之外一段时间,回头再重新继续这个问题的解决。这个时候往往灵感闪现,有可能问题一下子就被解决了。这个过程中,其中一个影响问题解决的因素就叫做动机。动机简单来讲就是指心理动力。术语化的表述就是激发并维持个体活动的一种内在心理过程或内部动力。它与问题解决的效率呈一个倒U型关系,如图3所示。

  图 3. 动机强度与问题解决效率的关系

  可见,最有利于问题解决的动机强度是中等的(并非越高或者越低才是越好的),并且对于不同困难程度的问题,其所需的最佳动机强度也是不同的。困难的问题比起容易的问题,所需的最佳动机强度要低。这就说,面对难题,问题解决者适度调低动机强度,心里不要抱着过大的意愿要去解决它,反而有利于问题的解决。

  情绪在问题解决过程可能起到积极的作用,也可能起到消极的作用。乐观、平静和积极的情绪有助于问题的解决,而紧张、惶恐、烦躁、压抑等消极的情绪会阻碍问题的解决。不难发现,不少新手遇到问题时的第一反应是害怕和紧张,甚至于烦躁。而专家在面对问题甚至是难题时往往也从容不迫。在问题解决过程中,如果我们觉察到自己的情绪有些紧张和烦躁时,不妨先暂时停顿下,先调节好情绪再继续问题的解决,这样效率可能比一头扎到问题中要高一些。

  因此,团队的直接主管在日常工作中也可以多关注组员在工作中表现出的动机强度和情绪状态,并在必要的时候指导组员对它们进行调节,而不是一味地施加压力和有意无意地制造紧张的气氛。这点,和中国古代各种兵书所重视的士气其实是一个道理。

  自动化加工与直觉思维

  熟练的打字员打字的时候无需思索要敲击的字母位于键盘的哪个位置,熟练的汽车司机可以边开车边与人聊天。这些都是自动化加工的例子。当人们对解决问题的某些部分的操作已经达到充分熟练的程度,这些操作就形成了自动化加工。这有助于在解决问题时将个体有限的心理能量集中到整个问题中最难、最关键的部分。从而提高了问题的解决效率。自动化加工也有助于形成直觉思维。下面看一个笔者经历过的直觉思维的例子。

  笔者曾经遇到这样的求助。对方称其在远程Debug一段Java代码时遇到了一个奇怪的问题:有个变量的值始终赋不上去。我的直觉的反应是对方Debug时所看的代码与远程主机上运行的代码不匹配导致该现象的。因此建议对方将远程主机上的jar包下载下来反编译相关class看看其代码与本地代码有何区别,以验证我的想法。最后发现是欲进行赋值的变量其值来自另外一个class中定义的常量,对方更改了该常量的值后仅仅将该变量所在class更新到远程主机,而未将该常量所有引用类重新编译后更新到远程主机,从而在编译器的作用下使得远程主机上的class读取到的仍然是该常量的先前值。

  上述问题的解决关键的一步其实是靠直觉思维:直觉给了我们一个问题的解决方向,接着才是在这个方向的指引下去求证,最后解决问题。可见,直觉思维往往可以使我们快速得到问题的解决思路,从而提高问题解决效率。但问题是新手通常不具备直觉思维的能力。直觉思维需要在解决问题方面长期的练习和积累才能逐渐形成。另一方面,软件开发人员在学习新技术新事物的过程中,需要注意理解和掌握基本概念和原理,并在日常工作中遇到问题时联系这些概念和原理进行分析,这样有助于问题解决,并通过一个个问题的解决逐步达到问题解决过程中能够形成直觉思维的境界。

  心理定势

  心理定势指预先存在的心理状态、习惯或态度。日常生活中我们提到的思维定势就是心理定势的一种。下面看一个实际的例子。

  测试人员要对一个数据库过期记录删除脚本的性能进行评估。测试该脚本时需要数量较大的数据库表记录(如30万条)。对于这些记录,有的测试人员仍然会采用提高负载测试工具给应用发送请求的方式由应用去生成数据库记录,因为他们经常接触到数据库记录多数是这么生成的。而事实上,这些记录完全可以由专门编写的脚本(如存储过程)去负责生成。这样不仅方便具体控制记录中的数据,也可以提高记录生成的速度,便于反复测试。

  可见,心理定势使得我们在面对“新问题”时倾向于采用过去使用过的方法和方式,从而可能不利于问题的解决。这是心理定势在问题解决中表现出来的消极作用。值得注意的是,心理定势也能对问题解决起到积极的作用,其表现在于通过复用过去的经验和方式方法可以减少问题解决所需的心理能量,有助于问题解决的自动化加工。

  因此,问题解决过程中一方面我们可以借助心理定势,以减少问题解决所需的心理能量,另一方面又要注意打破心理定势,避免其束缚我们采取更优的问题解决方法。

  当我们试图沿用以前的方式方法去解决现有问题而无法解决时,不妨再仔细分析下当前问题与以前遇到的问题究竟还有什么不同之处,以前的方法是否仍然适用。或者说,问题解决的更高境界是面对一个问题时我们能够敏锐地发现现有问题与以前问题的不同之处,从而在第一时间选择与以往不同的、更为适用的方法。例如上面例子中,如果问题解决者能在第一时间意识到其目标是生成一批记录,而这批记录是如何生成的是一个与其目标无关的因素,那么他可能就会去想有什么方法比通过发请求给应用更高效。

  人际关系

  软件开发毕竟是一个社会化的团队活动,从这个角度来看,可以说个人在问题解决中所起的作用有时是非常有限的。良好的人际关系有助于个人在团队中找到愿意协助其解决问题的人。而紧张的人际关系则使个人解决问题时能够使用的资源变得非常有限。

  观点采择

  团队开发中遇到的问题有时不是靠一个人的力量就能够解决的。当个人在解决问题过程中需要求助他人的时候,就需要涉及与他人的沟通。沟通是否顺畅会影响问题的解决效率。而沟通过程中当事人是否能够站在对方的角度去理解和思考可能成为沟通效果、效率的瓶颈。

  观点采择指采用他人的视角来理解他人的想法和感受的能力。心理学的研究认为观点采择这方面能力强的儿童能够更好地理解同伴的需求,因而他们能够更有效地和同伴进行沟通。如果拿实际的经验来对比,我们不难发现这点在成年人(同事)之间也是适用的。

  有心理学理论认为人的观点采择经历从3岁到青春期(12-15岁)的发展已经到达了“深入”的程度。但是,笔者也经历过不少个案,这些个案中的当事人在工作过程中与其他同事进行沟通时很难站在对方的角度去理解和思考对方的观点和思路,因而降低了他们在问题解决过程中求助的效果、效率。

  总结

  本文介绍了问题解决的心理过程,并在此基础上介绍了影响问题解决的心理因素。然后,以笔者实际经历的例子为基础通过比较专家与新手在问题解决过程中表现出的差异分享了提高软件开发人员问题定位与解决能力的指导意见。需要指出的是,本文所给出的相关指导意见,也可将其看成其有助于我们形成心理定势。因此,面对问题是我们一方面可以借鉴它们,另一方面要注意打破和超越它们。


 鉴别诊断是医生用来匹配系列症状及其可能病因的系统化方法。一个好的鉴别诊断包括以下4个步骤:
  1. 列出所有观察到的症状。
  2. 列出可能的病因。
  3. 按轻重缓急给这些病因排名。
  4. 按照优先顺序进行测试,以排除病因。

  虽然上面这4个步骤是为医生而整理的,但是我们同样可以像一个医生一样思考,用一种强有力的方式来找到并消除软件缺陷。将诊断过程分解为一个一个目的单一的步骤,确保每个步骤都能得到应有的重视。按照优先顺序是为了保证专注检查的重点,并作出务实的干预措施。然后进行测试,排除假设,以确保调试的严谨。


  对于很多公司来说,代码审查是开发人员日常工作中的重要环节。通过代码审查,可以及早发现项目中存在的问题、促进同事之间的沟通与交流,并且可以在讨论中迸发出智慧的火花。但要想成功实施代码审查却并不是一件轻松的事情,为什么要进行代码审查、何时做、如何做,这是摆在我们面前的3个重要问题。针对于这3个问题,开发者Lisa Tjapkes撰文谈到了自己的经验与教训。
在我最近的项目经历中,我们进行了广泛且正式的代码审查。这个过程极大地改进了项目的代码质量,降低了项目中新特性开发的等待时间,同时还促进了知识在整个团队间的传播与共享。我还发现代码审查并不会延误项目开发的时间,反而会提升开发人员的生产力。

  代码审查的好处

  我们发现代码审查对于项目的各个阶段都会带来很多好处:

  • 在项目起始阶段进行代码审查会帮助我们更好地使用已经建立起来的代码基,因为如果我们没有使用过某些现有代码,那么可以从当前的开发者中获得反馈信息。
  • 在项目进行过程中,我们会时不时地向团队增加新的开发人员,代码审查可以极大地降低这些新加入人员的熟悉时间。特别地,我们可以让新加入的开发人员很有信心地开发新特性,因为我们可以在合并前审查代码并且对于他们所编写的任何代码提供有价值的反馈信息。
  • 对于我们这个分布式团队来说,代码审查更加具有实际意义。团队协同在构建协作环境上会带来很大的帮助作用,我们可以即时提出想法,然后讨论,再进行开发。虽然由于不在同一地点我们会失去一些东西,不过我们却可以在代码审查过程中通过深入的讨论来获得好处。

  高效代码审查的技巧

  代码审查的方式如果处理不当可能会导致项目延期。使用正确的工具与技术可以防止在审查上浪费大量的时间,提升代码的品质。

  使用特性分支

  这个实践的好处就不用多说了,不过它对代码审查提供了更加具体的好处。特性分支意味着你可以将需要审查的代码隔离到只与某个具体的特性相关。在代码已经准备好了审查时,特性分支还考虑到了快速的上下文切换。在当前的代码进行审查时,你可以切换到新的特性上来,如果需要对审查特性的反馈进行讨论时还可以快速切换回来。

  将审查隔离为小的修改

  相对于大的修改来说,小修改的审查时间会更少。在审查大的修改时,你不仅要看很多行代码,还要查看大量的依赖代码才能真正理解,结果就是花在审查代码上的时间与修改的代码量之间并不是呈线性关系。将待审查的代码隔离为小的修改可以降低审查者的精神负担并让审查过程更加顺畅。

  使用专门为代码审查而设计的工具

  这看起来似乎很简单,但却非常重要。一些重要的特性需要包含差异比较、能够逐行注释修改,并且在审查的代码发生改变时通知大家。我所在的团队使用GitHub来管理项目代码,并且使用GitHub的pull request特性来管理代码审查。

  检查清单

  可能没必要使用非常复杂或是过于结构化的东西,如果突然出现了某些问题,使用检查清单或许是个不错的主意。

  有建设性的输入

  类似于“多加点注释”这样的话显得太没意义了,帮助也不大。假如某个接口没有注释,但也许有专门的文档用来说明呢。如果发现了某些不合理的地方,那就要明确指出来,判断设计上是否能改进或是逻辑上是否存在着错误。

  要把精力放在真正理解代码的行为上,确保当其他人需要维护它时也能够快速理解代码。

  人人参与

  即便是最有经验的架构师或是明星开发者也会犯错。因此,最好每个人都能参与到代码审查的过程中来。特别地,对于很多初级开发者或是新加入项目的开发者来说,这也是个很不错的学习机会。

  要有审查流程

  一开始,我们的项目并没有正规的审查流程。我们只是开启一个pull request,等待有人来审查,最后会有人合并修改。这种工作方式效率非常差,有时好几天都没人审查一个pull request,有时一个人给出反馈前其他人却合并了请求。此外,有些开发者审查的代码量要比其他人多不少。总而言之,没有流程导致我们的效率极低。

  最后我们认识到了这一点,创建了一个正式的结构来指导该如何进行代码审查,这加速了审查的效率。一个审查过程至少应该涵盖如下几点:

  • 如何将审查任务分派给不同的人
  • 期待审查者给出反馈的最迟时间
  • 如何标识某个审查已经完成
  • 谁负责合并已经完成审查的代码

  我在项目中是否应该进行代码审查?

  我认为代码审查对于很多项目来说都是一件好事,不过它也并非通用的解决方案。代码审查适合于如下这些项目:

  • 至少有5名开发人员
  • 在向团队增加新的开发人员时
  • 团队是分布式的
  • 项目有各种不同的组件构成,这些组件是由不同团队开发的
  • 当还处在为代码基设定约定以及最佳实践的阶段
  • 团队中有些成员对于当前所使用的技术栈还不太熟悉时

  相反,代码审查在如下的情形中并不会为项目带来更多的附加值:

  • 12.总结

1.背景

最近对软件开发有了一个新的认识,这个认识源自连续看了两本Craig larman大师的书籍《UML与模式应用》《精益与敏捷开发大型应用实战》和公司目前的项目情况这两件事情一起碰撞导致的感悟。

先说下前者,为什么会想到看Craig larman大师的书籍。其实我收藏的书籍已经上千本,在各个电商平台上都有帐号,目的只有一个就是收藏好的书籍。家里也堆了很多,没事浏览新书是我现在最大的乐趣。我相信有这种感觉和爱好的不止我一个人,家里堆上几十本书的在IT行业算是很正常的。

书多了有时候不知道要看些什么也很正常,我的原则就是随时调整,看目前所面临的困惑。根据我以往的经验总结,在实际问题面前寻找答案最容易让你有新的感悟和提升。我相信书中自有黄金屋、书中自有颜如玉,要在对的时间看对的书,说白了就是在有困惑的时候就去寻找给你答案的这方面书籍。为什么要看Craig larman大师的书,是因为最近的工作内容有很多自己搞不懂的地方,希望能通过大师的指点有所感悟,果然受益匪浅。

再说下后者,最近一直在和这几个事情打交道:遗留代码技术债务项目管理项目质量开发进度快速开发重构单元测试敏捷开发ScrumXP,你可能会有点疑惑,有些东西是重复的,比如项目管理中包含了项目质量、开发进度,再比如敏捷开发与Scrum和XP,似乎我在把一个大的概念拆解成多个小重复的概念。我之所以这么做,是因为我想强调这些概念的区别和真正的相互作用,从软件工匠的艺术角度出发来真正的看待这些概念。比如说,项目质量与代码有关系吗,开发进度与遗留代码有关系吗,项目管理与技术债务有关系吗等等,这些问题的本质是完全不同的,作为技术人员尤其是应用开发的技术人员一定要强调概念,一定要明白不同的概念的本质含义,如果你不强调概念我想你的代码是写不好的,对业务的理解也不会深刻。

最近我将自己的技术生涯的目标定为“软件工匠”,其实说实话我不在乎title,我只在乎自己的工作内容是什么。软件工匠是没有边界的,只要和软件开发有关系的内容都是属于工匠需要去专研的领域。如果工匠离开工具就丧失了工匠的真正价值所在,所以说千万别放弃写代码。不管你是一名架构师还是一名开发经理,代码永远是产品的最终设计,一旦你离他而去就离产品的质量越来越远,后面我也会讲下为什么代码如此重要。

2.项目管理,质量、度量、进度

这节的标题是不受欢迎的,大家知道为什么吗。技术人员是能明白的,有过长达5-10年的开发出生的管理者也是能明白的,唯一不明白的就是没有太多开发经验的管理者,或者那些不喜欢开发的管理者,那些逃避开发的管理者,因为他们离真正的产品实现太遥远,他们离软件开发领域真正的问题太遥远,管理一旦忽视代码质量问题就会慢慢找上你,你的项目往后的质量越无法控制,度量、开发进度都会遇到瓶颈。

说个当下的现象,我从事一线开发也有好几年了,陆陆续续看到很多人转作管理,但是你会发现做管理的人一般都是技术水平一般的人,或者对技术没有太多追求的人,更夸张的是在有些小公司的管理者可能就没写过代码。

为什么会出现这种现象,其实主要原因有两个,首要的就是个人的职业规划,在就是公司的价值导向。先说价值导向,往往写代码的人的价值没有项目管理的价值大,这在一些中小公司还是很普遍的,真正的科技型公司这类问题几乎没有。而职业规划是完全可以接受的,毕竟每个人的兴趣和追求不同,这无可厚非,应该尊重每个人的选择。但是这里的问题是,一旦没有太多技术底蕴的技术人员坐上项目管理者的职位后会对技术的理解360度大转弯。这其实是不对的,项目的成败不可忽视技术。

不继续讨论这个话题了,这不是本篇文章的重点,人各有志,选择是正常的,但是要明白的是选择的本质不是价值导向,而是兴趣导向,这才不会让你忽视另外一个角度,因为一个软件产品的最终成功是要靠项目管理和软件工程相共同的努力,缺一不可。

这里想聊聊项目管理的三个重要的方面,质量、度量、进度。首先我不是一个专业的项目管理者,但是我是一名专业的软件工程师,我不知道项目管理的具体内容有哪些,但是我知道项目管理的最终目标是和软件工程的目标是一致的,都是为了项目高质量的完成。

项目的成败光靠项目管理是解决不了的,如果可以就不会出现《软件工程》《设计原本》了。保证软件项目的真正成功是需要软件工程的支撑才行,而管理更加是对开发的组织、协调、沟通上的,这是两个层面两个角度互相作用的。项目管理中不会有设计、抽象、可维护性等这些内容。

这里尤其想讨论的就是软件项目的质量,现在看来衡量软件项目的质量忽视了代码的质量,客户验收、功能完成、稳定上线,没耽误进度,这就是完成了一个项目,我们忽视了一个就是代码的质量,为什么要关心代码的质量。

度量,度量是对开发周期内所有发生的事情进行数据可视化,BUG数、发布回退数、代码行数(比较特殊)、需求变更数等等,还有些我不是太清楚的度量数据,总之应该会有很多。度量的目的是为了什么,是为了能够在这些数据出来后改善项目的各方面质量,控制各个不稳定的方面。

开发进度,“质量”一段中我最后抛出了一个问题“为什么要关心代码的质量”,因为他直接决定了你的项目进度,当你的代码质量越来越差的时候你就失去了对项目进度的控制。你再多的度量指标都是无意义的,就算你可以统计出BUG数上升了,但是你也控制不了BUG数下降,因为你已经偏离正常航线太远,就算你可以控制需求变更的速度和次数,但是你无法控制适应变更的代码的速度和次数。变更是无法避免的,你的代码无法面对这些复杂的变化,因为你的代码不是设计出来的而是堆出来的。最后你的项目质量也无法很好的保证。

(图1:项目管理与软件工程的结合才是完整的软件开发)

最近在看Michael C. Feathers 大师的《修改代码的艺术》一书,感触颇多。里面讲到了我们面对遗留代码的时候,为了增加一个新的功能要付出多少时间和精力,出现明显的BUG机率有多高,出现隐藏的BUG机率有多高。遗留代码直接决定了上述三个项目管理的方面。Michael C. Feathers 大师强调了很多关于我上面讲到的项目管理和代码质量之间的关系,这本书很值得看。

其实真正推动软件开发不断发展的是软件工程、开发方法论,项目管理只是辅助于软件工程在时间和空间上有效实施。

这里还要区别下就是项目管理和团队管理的区别,这两个东西是不一样的。项目管理基本上不需要软件工程的支持,但是团队管理在某些方面是需要软件工程的支持才能做的更好。

3.软件开发是一种设计活动而不是建筑活动

在《精益与敏捷开发大型应用实践》一书中是这样描述软件设计和架构的:

1:“软件架构借鉴了建筑的架构,但结果证实这是个不太恰当的类比,而且给软件开发带来了有趣的副作用。建筑是硬的,因为在这个领域,设计只在施工前进行一次,然后该建筑或者设计就几乎是永久不变的了。注意建筑师和施工工人是不同的。但是软件不是一座建筑,软件是软的,而且编程也不是施工的过程,“软件架构”只不过是一大堆比喻列表中可以选择的一个不太完美类比而已”。

2:“......唯一确实看起来满足工程设计条件的软件文档是源代码“。

3:"我意识到图表和文档并不是真正的设计,而源代码才是真正的设计。再次重申“......唯一确实看起来满足工程设计条件的软件文档是源代码“。

这几句话足以证明软件开发是一个非常复杂的过程,是思维密集型脑力活动,而且体现在每一个编码过程中。在很多项目管理中都认为软件开发是一个非常简单的活动,主要架构设计好编码是比较简单的,难道真的是这样吗,我们再看看书中怎么说的:

1:”源代码是真正的蓝图“。

2:”真正的架构在哪里,无论好坏、有意或偶然的?是在架构团队维护的文档中?还是在上万个文件中?显然是后者,源代码是真正的设计,而且它的总和反映了真实的大型设计或架构。架构就是架构,不是某人的意愿“。

现在很多开发者还有一个明显的技术理解错误就是”写代码“是比较简单的活动。复杂的是软件架构,只要架构设计好后写代码应该是程序员的事儿,这里明显有一个错误的价值观,认为写代码的人都是廉价的,不具有任何的设计和创造新。这其实是一个很不专业的看法。真以为一个简单的PPT、WORD文档中的架构图就表示架构了。其实这个想法是很幼稚和肤浅的。用Craig larman大师的话讲,在整个软件生命周期的活动中,复杂的是编写代码,而代码才是架构,所以说架构的就是代码。你原本理解的架构才是真正难的地方其实也就是代码才是真正难的地方,不可浮于表面,这样才能更加的接地气才能真正的有价值。

架构师应该深入到一线参与一些开发,这时会发现很多问题,然后将问题带到架构的位置,用架构的视角设计方案,在亲自把这个方案带到一线落实下去,这才是架构落地一个技术方案的正确方法。

软件开发是一项设计活动而不是建筑活动,软件是会不断变化的,而建筑一旦敲定是不会改变的。

4.快速开发(简单的系统结构与复杂的业务模型)

这节我想聊聊快速开发。在圈子里面对快速开发的理解大部分都是和快速开发框架对应起来,觉得应该有一个框架来支持快速开发。只要有了一个框架就可以进行快速开发。这样的看法或想法其实是错误的,对快速开发的理解太狭隘。

《设计原本》作者,计算机科学巨匠Frederick P. Brooks说过,对于软件开发来说没有银弹存在,没有所谓的能够用简单发方法来开发复杂的系统。越复杂的系统开发起来不会简单的,开发一个满足100个人使用的系统和开发一个满足1000个人使用的系统在复杂性上已经完全不同了。量变引起质变,当业务量、访问量、数据量等等这些软件指标超出一定的范围之后就和最初的设计完全不同,设计思路也完全不同。

回到当下。我现在经常面临这样的一个问题,我现在所从事的业务是比较复杂的,对系统的设计要求很高。如果用量来比喻的化,其实我现在所面对的业务量是比较大的,业务量中的业务复杂性的量其实相比于访问量、数据量等方面的量在设计方法要难的很多。通常做设计的架构师都只会考虑并发量、访问量而忽视业务量,比如业务的多变性、业务的扩展性,业务本身的复杂性,这尤其考研设计能力,考验抽象能力。这跟你用什么编程语言用什么数据库是没太大关系的。你脑袋里运用的是OO、实体关系,这些与具体技术框架没关系的设计思维。

业务量对于编写代码要求要高很多,同比于其他几个量来说很难落地。访问量、并发量可以通过基础架构的调整优化升级来解决,而业务量的问题域是业务逻辑,是领域模型,当前所面对的业务域,任何一个细小的业务都需要在代码中体现。

最近陆续在做一些系统重构的工作,就在前两天我重构了一段代码,不是基础性的代码,是业务逻辑代码。大概情况是这样的。

在系统中有一个重要的领域概念“重量”,这个重量的概念存在很多个业务量的质变可能性,就是说它本身不是简单不变的,随时存在着变化,当我们品类扩充的时候就立马会变化。

重量的定义是这样的:重量=单件重×数量,看上去好像很简单的样子,其实不是,这里的单件重是会变化的,有些时候是保留3位小数有些时候是保留6位小数。而且这个重量的业务逻辑是在N多个地方都需要用到的,查看代码下来大概有几十个地方都在重复着编写“重量“的业务逻辑。

后来我在同事的协助下重构了这块业务模型,为什么我这里不用业务逻辑来形容我的重构工作,是因为我考虑业务的时候不会是过程式的,如果用”业务逻辑“来思考业务就会给人造成一个错觉就是”过程式“的代码结构。所以我考虑任何业务都是”模型驱动开发“方法,业务要抽象为模型才能重用、扩展、抗变化性。这其实是OOA/D的精髓。业务逻辑只是在模型中的一小块一小块的具体动作,它是在模型的范围内使用的,而不能一上来就是业务逻辑,业务逻辑太细小不便于抽象化。

(图2:重量、单件重模型)

我用上面的这个模型对重量业务模型进行了重构。将原本很重要的业务概念重量、单件重、不同类型的单件重,进行了概念显示化,保证这些重要的领域模型不被过程式的代码淹没。且用两个工厂封装了创建重量和单件重的业务逻辑。这样做之后我们的模型就具有抗变化性,以后要是对Weight有任何的创建逻辑的变动我们就可以在WeightFactory中处理,如果有新的品类扩充进来后需要对单件重相关的处理我们只需要扩展下ItemCategory和PieceWeightFactory两个模型。如果你需要做为完全配置化,这个时候模型就更有价值。比如,我们可以将IitemCategory拿出去,通过品类扩展的时候自动生成相关的类型,如果你觉得这还不够完美,我们可以进一步将PieceWeightFactory中有关于“根据ItemCategory创建PieceWeight(Decimal) “,做成”Mapper模型“在进行配置化。

这里你会发现一个很奇妙的地方就是,一旦模型化后业务的量变引起的质变可以通过逐步重构模型、提取模型、精华模型来解决。

所以说简单的系统结构是无法表示复杂的业务模型的,如果可以的话OO语言就不会发展成今天的这样子。复杂的业务无法通过简单的系统结构或者说所谓的简单的快速开发框架之类的东西可以解决的。

5.技术人员的业务理解与产品经理的业务理解的最终业务模型

很多时候我们都在强调“多去了解业务、多去熟悉业务”,在业务驱动型公司这是必须的,公司中的任何角色的单位都需要熟悉公司的业务范围。这没有问题,我想说的是不同的角色对于业务的理解最终的业务模型是不同的。

不管是在传统的软件企业中还是互联网企业中,我们要用软件来服务于我们或者客户,当然这里所说的是业务系统。业务系统的核心就是业务,系统的精神就是业务模型及模型之间的关系。

这节我想说的是,技术人员去了解业务后和产品经理去了解业务后最终的业务模型是怎样的。技术人员与产品经理是不同的角色,具有不同的职业背景,不同的知识结构和专业度。现在存在一个普遍的认识错误是,技术人员理解业务后与产品经理理解的业务后的最终的模型是一样的,是怎样的呢。是无法抽象的业务,大概的业务,场景化的业务,无法落地到系统中的业务。此时技术人员并没有用自己的专业度来对业务进行抽象和建模,并没有直接带来真正的价值,而是在交谈和理解需求的时候感觉上的价值错觉。

技术人员不能够业务技术化其实对于公司所说的“当技术人员理解业务后产生的价值是巨大的”其实是不准确的。

5.1.产品的业务理解(业务流程、数据流程及场景)

产品对于业务的理解是整体上的,包括业务流程、数据流程,场景,在他们的脑子里是真实的业务场景,是必须要还原的业务场景,不能够有任何的其他模型在作怪。如果产品用任何的其他知识来抽象和强制理解业务是会出现问题的。

产品对于业务的最终模型是业务流程、数据流程和一个不需要表现的场景。

(图3:产品的业务理解最终模型—业务流程图)

由于数据流程图比较简单,当前例子中只会有“订单”的数据实体,画出来意义不大,我这里就只画一个业务流程图来表达意思即可。

在这个程度上是无法直接将流程图落到系统上的,它距离真正编写软件还有一段过程要进化,而下面那段过程才是技术人员理解业务后要发挥的价值和作用。

5.2.技术人员的业务理解(领域模型、设计模型、抽象建模)

技术人员的了解业务要有所侧重,你理解的业务和产品理解的业务是不一样的,技术人员需要将业务最终技术化才行。技术人员的最终的业务模型是有正确的模式可以参考的,就拿“创建订单”这个流程来说,等待技术人员需要去提取和抽象的东西是比较多的也是比较复杂的,需要结合很多的知识来进行设计活动。

比如订单,你需要结合“四色原型”模式来提取“订单”的模型,包括“订单的类型“、”订单的跟踪“,需要结合设计模式来抽象”创建订单的逻辑“,根据”不同的订单类型创建不同的最终订单“。还需要进行设计模型的抽象,比如创建订单,各个对象的交互是如何的,每个交互的输入和输出是什么。这些都需要技术人员理解了业务后应该具有的业务模型,如果需要将模型语言化就需要结合使用UML来建模。

如果技术人员理解业务后和产品经理理解业务后的结果是一样的,那技术人员要去理解有什么价值。技术人员理解业务后要系统化的将各个业务模型落地到具体的领域内或者说某个子系统子服务中,然后各个系统和服务是如何交互的,逻辑的归属到底是哪边的。最终你写出来的代码才是满足业务的代码模型,才是有核心竞争力的业务系统有别于无核心竞争力的系统差距。

技术人员了解业务后,针对不同的业务场景开始创建领域模型草图,根据领域草图再进行设计模型草图创建,当然这是一个敏捷的迭代的过程。

(图4:“创建订单”相关的领域模型)

有了领域模型之后就需要创建设计模型,也就是各个模型之间的协作关系。还是要强调下,这是一个快速迭代的过程,且勿将其看成是瀑布的依赖过程。领域模型的精华也是没有止境的,当后面进行设计模型的过程时会有对领域模型有补充的灵感,此时不可以教条,要快速的精华领域模型然后再进行设计模型的过程。

(图5:“创建订单”相关的设计模型)

基于领域模型创建设计模型中的对象协作模型,设计模型不仅仅只有协作模型一种还有其他的。协作模型是必须的也是最重要的。有了协作模型之后我们就可以走查场景是否满足“创建订单”的这么一个业务动作。当八九不离十的时候就可以进入到编写代码阶段,进行一个快速的构建代码模型,因为这个时候还是会有问题出现,只有在代码模型中没有问题后才是真的没有了。

我这里只是假设一个简单的业务场景作为示例,目的是为了介绍技术人员区别于产品对于业务理解后的最终模型是不同的。技术人员一定要有完善的能将业务技术化的知识结构,这样才能真正的将业务发挥价值。

6.技术债务(腐烂的遗留代码)

技术债务其实是无法避免的,各种原因,时间进度、需求变更、市场迫切等,都迫使研发开始堆积技术债务,代码逐渐开始腐烂,难道我们作为技术人员就只有抱怨和推卸责任吗。这里我有一些个人看法,这些个人看法可能跟你的理解不一样,你可能会说我太理想主义了,但是我想说的是:“作为一个技术人员一定要有情怀,一定要有追求。”用我最尊敬好朋友冯老师的话说:“写代码一定要考究“。就算在时间比较紧的时候可以先写,但是要记住你的工作并没有完全完成。

我是从开发做到架构,经历过很多项目磨练,也深知在项目时间比较紧急的时候自己是在一个什么精神状态下写代码的,自己也干过到处复制代码粘贴代码的时候,加班到12点,眼睛基本上已经很难看清代码,敲代码的速度已经赶不上功能交付的速度。我只能说这也没有办法,市场决定了项目的进度。我们可以吐槽,但是不能抱怨,更不能消极。

其实现实情况下我们做开发的基本上都是在这个节奏下工作,但是我是怎么处理这个问题的呢。首先写好代码是个人对技术的一个追求和职业素养的问题,如果你对代码没有美感你很难能编写出好的代码,你的代码也会到处留有坏味道,时间长了就是腐烂的遗留代码,严重的技术债务,研发整天怨声四起,各种抱怨,吐槽,这样下去其实是不好的,团队里有追求的技术人员会流失。

实话实说,当自己今天晚上12点写好了代码提交了测试,但是我的工作并没有完成,我通常会在早上很早就醒了,我会很早的来到公司对自己的代码进行重构和梳理,早上是大脑特别清醒的时候,在这个时候你进行代码的整理是非常不错的,而且这个时候公司一般都没什么人,特别安静,当你重构完代码舒服舒服的再去整理自己每天早上来的其他事务。

你可能会说那是你个人问题,我不一定会在第二天早上能起的那么早,就算起的来我到了公司也不会对第二天的代码进行整理,因为那已经上线了已经是完成的功能,我该继续下一个需求。

用我的价值观来看的话,其实你的工作只完成了一半,你并没有保质保量的完成工作,你的软件交付质量在产品层面是完成了,但是你在技术层面是有残缺的。你给软件带来了很多的技术债务,你给某个对象带来了腐烂代码的开始。

这点我现在的公司是非常不错的,公司高层对项目的管理者首要的要求就是必须懂技术。

我一没事就会和我的好朋友也是好同事冯老师交流技术,互相review代码,提意见,在互相重构,彼此学习。我们有一个共鸣,就是让写代码有追求的人来把控项目是非常不错的,可以保质保量的完成功能,当然不是光说有写代码能力就OK的,需要综合性的。其实说白了,让一个精通技术的人在去精通业务做出来的软件应该是不错的。 (这里所说的精通技术是指应用开发方面的精通,不是指技术专家、系统层的技术专家)

作为应用开发人员,要时刻记住你所应该具有的专业的职业素养,写代码要讲究,要记住对你来说代码意味着什么。


 




posted on 2015-08-06 20:41  时间朋友  阅读(279)  评论(0编辑  收藏  举报

导航