2013开发总结
今年在公司里,收获很多。从很多方面,都一个新的认识。因为参与公司的几个项目。有的是维护原有代码,有的是从需求开始,从0做起,有的做了一半,因为调整不做了,有的刚开了个头,因为其他项目需要暂停了。每一个项目,做的程度都不一样。但是每一个项目,都让自己对于完成一个项目,有了更深的认识。也慢慢在改变自己以前那种学校式的研发状态。由一开始想从每一个项目中学习新技术,到想办法确保每一个项目都能按照预期按时结束,做出能够交付的稳定产品。而这本身也是一种学习。
/* ---------------------------------------------------------------------------*/
年初,公司接到一个项目,给客户提供一套软硬件系统。其中自己负责的部分,需要对一年半前的代码进行维护,修复其中的Bug。对于这份代码由于是一年半前由两个人写就。当维护的时候,第一件事就是怎样读懂代码,找到能入手的地方。当开始研读代码的时候,发现全局变量定义实在是多。一个.c文件中,多的时候就会有二十几个。而代码之间的耦合,造成全局变量的定义和使用可能在几个.c文件中。函数间的参数传递,有些就是直接用全局变量实现的。代码过长的函数,就有好几个,有的函数一个switch就会有200行以上。当时,读到这些代码的时候,第一反应是一定要把这些当时认为不好的代码全部修改了。确实一开始也这样做了,以为只要费些时间就会弄完,然后,有了一个熟悉的代码理解也会更快。
但是一段时间后发现要改的地方真是很多,而且测试起来也很难办。因为是嵌入式上的程序,很多地方都要手动去一个个测试(当时如果知道了《重构》的经验与教训或许不会那么大刀阔斧的来)。测试的过程十分麻烦,而且会造成有些地方测试不到。由于源代码底层代码与应用层代码耦合比较厉害,如果有改动,底层的不稳定会导致整个系统的不稳定。而这个在最后发现了。由于中途临时需要交付一个Release版本,有些地方改了还没有测试,只好将没有测试的地方恢复。这样代码中就出现了改了一半的代码。由于自己在修改的过程中,也没有遵循原有代码的代码风格(由于原有代码tab键与空格混用,看不出风格,变量名也比较随意)。也有些地方遵循自己的编程习惯,修改了代码中存在递归的代码。
最后发现,程序并没有比原来更好理解,耦合性还是很高。在后期考虑到硬件有一个元件已经停产,所以建议更换新的模块。更换后,由于对于新的模块不是十分熟悉,导致出现了比较严重的问题。这个事后自己反思的时候,认为当时提的一个很错误的建议。在项目的后期,已经没有多少时间去测试稳定性了,而此时却将以前稳定的元件替换掉,而换新的元件,测试时间又没有那么多。直接导致了不稳定的存在。事后,也确实因为这个元件,导致了第一批出货出现了返修。为此,连续三个周末在公司解Bug。
整体的维护中,虽然改善了原有代码的的Bug,但是却也引入了新的Bug。在这个过程中,前期也是自己对于代码维护的理解有偏差。如果说重构,也要是用到的地方进行重构,而不是对于很多地方重构。更不应该在项目后期,进行元件的替换。如果说维护是为了保证产品的稳定性,那么就要在最小的范围内做修改。尽量避免修改不需要修改的代码。但是,这里边涉及一个问题,怎么判定那些是需要修改,那些事不需要修改的?有些容易判断,但是有些就十分模糊。
这里还有一点,如果说尽可能减少修改的地方,那么对于维护者而言是否会接受这样的概念?对于一个初做的人,总会想多做一些。是得过且过,还是精益求精?这个或许《重构》最后的一个建议很好“使重构成功的不是前面各种技术,而是这种节奏”,懂得重构是在于“可以自信地停止重构”。但是这种节奏的获得需要有大量的实践才会获得,这种自信也需要从实践中一点点获取。在此次维护结束后,想要找到自己在维护的过程中犯下的错,以期以后不会在同一个坑中栽倒第二次。如何在以后的类似工作中做地更好,在反思了一些以及看了一些书后。认为维护过程中有几点是严重犯错的地方:
没有做到对于不必要的地方不修改;
缺少质量管理的观念。
经过这次维护的经历,得出了以下几点:
确定code style,编写易读性代码,代码可读才会使维护更容易;
使用lint工具检查代码;
积累重构;
注意C的安全性与非安全性;
建立代码质量的观念,建立产品质量的观念;
/* ---------------------------------------------------------------------------*/
年中,接到另一个项目。和前一个项目完全不一样,这个是要从零开发。自己负责软件中的一部分。初期由自己做设计初步的通信协议,以及通信机制。在开发过程中,发现由于客户不了解元件的特性,推荐的元件型号不满足客户自己的要求。于是,进行了元件更换。在新的元件上,很容易做到客户要求的指标。这些完成后,要给客户提供一批样品进行测试。这个过程中发生了一些意外。试产的第一批在使用测试程序后,发现有一半测试不合格。经过测试分析,发现硬件的模拟部分不同PCBA之间存在差异,原有程序的初始值在差异较多的时候会出现异常。于是将程序的初始值,修改后重新测试发现大部分输出都正常了。
在后来生产的过程中,发现由于实际要装配的东西很多,装配的过程很多,而选择的外壳内部空间较小,造成内部空间很紧张,给装配人员实际造作中带来很**烦。直接的影响就是装配的效率偏低。在催促他们提高装配速度的时候,也确实很难提高速度。测试的项目很多,需要时间。外壳的尺寸和元器件之间内部空间的限制,以及外壳螺丝都成了影响的一个因素(采购的外壳,有些螺丝因为攻丝有问题,导致螺丝装卸较困难)。元件多,要装的步骤会相应多一些。
在这个过程中,反思为什么会出现这样的问题。
首先,软件上的设计一开始没有深入了解具体的硬件情况,导致软件上的参数设置和硬件的偏差配合不上很好。对于具体要应用的场合了解还欠缺深入。在提供给测试部的程序将测试程序与正式程序分开,导致测试人员在测试完成后还要重新烧录正式程序。如果当时,自己在设计程序的时候,将测试流程包含在正式程序中,通过特殊条件触发,能减少测试人员的测试时间,提高他们的速度。同样,在需要的一些测试环节,或许还有可以提高的地方。
其次,选择的外壳和连接线,PCBA之间配合不好。这方面如果考虑多一些,装配人员就能省下来很多时间,提高装配效率。也不会抱怨产品那么难装配。更降低了装配的主动性。
在这个过程中,深深感受到保证每一环正确的重要性,即使有一步缺失都会造成最后产品生产的进度与性能。
/* ---------------------------------------------------------------------------*/
后来又根据需要接手了两个,由于预期的调整,每一个都做了有一个月左右停下。
/* ---------------------------------------------------------------------------*/
在这个过程中,慢慢明白了,在一个团队中、在开发产品的工程中最重要的不是技术问题,因为对于一个开发者而言技术通常不是问题。技术可以一点点习得,技术可以google,可以研究,可以向别人请教。而一个开发者通常欠缺的是——建立项目的概念,进行有效沟通。项目进行过程中,每一步都是由有效的沟通驱动。了解需求,团队合作,协同开发,测试反馈,生产反馈……。如果这些过程中,有地方没有明确理解对方表达的意义,或者没有明确表达自己的意思,都会造成整个项目开发上的delay。没有正确了解需求,开发出来的将是一堆无用的代码;没有团队间的有效沟通,开发中成员间将会互相掣肘;没有有效的测试反馈,开发出来的将是质量无法保证的程序;没有生产部门的有效反馈,开发出的有可能是不利于生产的产品。同时建立一个项目管理的概念,也是十分必需。如果将项目广义化,我们工作中接到的每一个任务,对于我们自己而言都是一个项目,我们开发结果的使用放就是我们的客户,而我们自身就要做好对于这个任务的管理。保证给我们的“客户”是高质量的产品,只有每一个环节都有高质量的产出,才会做出最后高质量的产品(产品质量符合木桶理论,注1)。由此而言,作为一个开发者,要关心的不仅仅是技术,也要关心于有效沟通,建立项目管理的观念,将它们用于平时的工作。技术可以保证我们出色完成当前分配好的工作,但是并不能保证我们提供一个高质量的产出,更不能保证项目的顺利完成。所以,技术很重要,但它不是全部。
/* ---------------------------------------------------------------------------*/
整体而言,这一年在公司经历了很多。从技术,到其他感受也很深,收获也很大。
从一开始想要探究代码,到现在对代码三思而后行;
从一开始想要钻研,到现在工作上enough is good;
从一开始不知何为代码安全,到现在编程时刻将代码安全放在心头;
从一开始不知如何修改代码,到现在试着找找重构的节奏;
从一开始只知开发,到现在从测试、生产、使用的角度考虑设计;
从一开始把代码管理当做备份,到现在建立branches,打tags,查看版本graphic;
从一开始不会lint,到现在用lint工具检查C代码;
从一开始对项目一知半解,到现在慢慢建立项目管理的概念,指导平时的工作;
……
这些的这些,记录了一年的酸甜苦辣,记录了一年的变化。走过,“回首向来萧瑟处,也无风雨也无晴”,留下的是——成长。