知难而进 ——反思我带的第一个版本

知难而进

——反思我带的第一个版本

这个版本是公司推向海外市场,全面推进虚拟化(Windows Hyper-V平台、VMWare平台)以及AWS云平台的第一个试水版本,总耗时近3个月。

下面逐个阶段回顾,并就出现的问题进行反思。

1、需求阶段

仅仅花费2周左右的时间,简单从互联网获取资料、竞争对手网站/试用包分析、基础云平台部署预研,就开始了版本。

对于研发人员的我们拿到的是一份很宽泛的需求文档,涉及范围很广。包含:

(1)产品易用性改进:向导部署、图形化界面&命令行接口的后台、多序列号合一、非IE内核浏览器(Chrome、Safari浏览器)支持。

(2)产品功能改进:部署模式变化、非产品相关功能删减。

(3)产品性能改进:保证速度达标且保证有好的削减效果。

反思:

需求点(3)是真正到了集成测试阶段中期才识别出来的。且属于历史遗留问题,和早期的架构和设计有关,只能做边边角角的缝补,即便花了很长时间,但仍然难得到既定目标。

这种问题,应该放到版本的早期识别,且定好改动目标和截至时间,不能达标走规避方案。

2、设计阶段

两个模块向导部署CGI后台以及序列号模块是进行了方案选型和微型/概要设计的。其中序列号方案时候对于场景考虑是不充分的。

在虚拟化平台上,由于安装包可以任意Copy,同时序列号也是可以任意Copy的。是不是用户买一个序列号就可以任意使用了呢?

这里就需要提防:

(1)两个相同序列号对接,校验判定,结果:不允许对接。

(2)多个相同序列号的分支接入一个总部,结果:不允许对接。

(3)一个分支接入多个相同序列号的总部,结果:不允许对接。(当时想到这种场景,但因为是小概率场景,就没有关注)

反思:

小概率场景对于开发来说也必须考虑,一旦出问题就是灾难性后果。不要把问题留给用户,有可能预见到的问题要一网打尽、消灭在萌芽状态。

事实也证明,后期再去处理该问题,一是本身实现机制不便于扩展,很难改动,且改动可能引发。二是项目进度很紧张,不可能留太多时间处理。

3、编码阶段

(1)典型越界Bug如下所示:(仅是示例,实际比这难排查N倍,要是面试题大家谁也不会错,平时运行都是32767之内的值也不会错,但一旦出错就是越界溢出,后果很严重)

<span style="font-size:14px;"><span style="font-size:12px;">#include <stdio.h>
#include <stdlib.h>

int main()
{
       short int ival_1 = 32767;
       short int ival_2 = -32768;
       short int ival_1t = 0;
       short int ival_2t = 0;
       int i = 0;

       for ( ; i < 10; i++)
        {
               ival_1t = ival_1 + i;
               ival_2t = ival_2 - i;
               printf("ival_1t = %d, ival_2t = %d\n", ival_1t, ival_2t);  //都会越界
        }

       unsigned int uival_1 = 32767;
       unsigned int uival_t = 0;
       for (i = 0; i < 10; i++)
        {
               uival_t = uival_1 + i;
               printf("uival_t = %d\n", uival_t);
        }
       return 0;

}</span></span>

(2)典型使用方法错误Bug如下

在定时脚步里面不要使用Popen类似的接口。原因如下:popen() 函数通过创建一个管道,调用 fork产生一个子进程,执行一个 shell 以运行命令来开启一个进程。

而对于一直在跑的系统,1天、2天可能不出问题,对于性能环境要求24×365运行的话。会很容易出问题,很耗费性能,导致连接中断。且非常难排查。

反思:

这些最终排查出来都是细节不注意的小问题,但是如何在高压的项目环境下最快排查问题所在、并修正问题,着实需要花精力去学习、去积累。

4、集成测试阶段

分模块之后,利大于弊。利是:独立的模块可以分开转集成,提交测试部测试。但注意此时关键路径就成为后面才开始模块。

团队里面就可能出现:后台已经实现,在等待与前台对接。几个独立模块都完成了,就等待合入。

反思:

如果模块之间有等待关系,比如后台CGI等待前台html、JS页面对接。此时后台可以自己构造数据进行手动或者自动化测试。

有等待关系的模块也可以先开始BVT案例执行。总之,不要等待,这样整个版本的进度才有保障。

5、系统测试阶段

在所有模块转集成之后就是系统测试阶段。这个时候最容易出问题的地方就是模块间的对接。如:向导部署的一个页面就需要客户输入序列号,并在后台调用序列号相关解码程序进行校验。一是校验序列号格式的正确性,二是校验序列号的合法性(如解析出网关ID进行字节匹配)。

反思:

到了预发布的冲刺阶段,任何一点代码改动都要慎之又慎。

一是重新打包要耗费半小时时间。且要导出VMWare支持OVA数据包,导出Hyper-V的数据包,以及导出不同平台的包要4个小时左右的时间。

二是一点改动都要进行验证,而验证需要耗费的时间远大于我们改动的时间。

时间非常重要,稍有不慎,是拖延的整个团队的工时。

这点,我做的也非常不好。自动打包脚本前期由于打包速度的考虑,没有重新编译内核(2015-1-5月份之后,主要内核改动代码的确很少),但是直到3-20号才发现,之前的两个Bug都涉及修改驱动、需要重编内核。(非常抱歉,个人失误影响团队)

6、预发布阶段

包已基本稳定,等待验收中。

整体反思——我究竟学到了什么?

从历史的角度,我们的经历的大部分我们都会淡忘。但那些深思过、你通过、你被鄙视过的经历、你为某个问题争得面红耳赤的经历,我都不会忘记。

1、 我有了全局的视野。

早期的几个版本都是站在模块的角度看待问题,只知道自己模块的实现的功能。多点就是知道与自己对接的模块的功能。视野停留在接口实现、接口对接、模块功能实现、模块案例测试与联调,模块最终无Bug。

现在对产品的过去和未来,尤其对产品的功能和市场需求角度都有了新的认识。会对后面的模块开发从思维角度有“洞开”的效果。

2、我更会从客户的角度考虑问题。

作为研发编码实现人员,面对突入起来的需求变化,真的不忍心改掉自己“滚烫”的代码。但如果这个变化更有利于客户理解,更利于客户操作,我们就得“拥抱变化”。

骂两句后,还得伏下身子改代码。

3、我学会了在高压环境下更加高效的工作。

没有压力的IT不是IT码农。在高压的环境下不盲目保持清醒头脑。之前一年前也说过的,要在每天早上列举今天需要完成的任务。这样每天就是解决一个个问题的过程。

碰到比较难解决的Bug的,也要列举上每天解决的步骤和思路。便于理清思路和把握方向和进度。

      4、我知道了Bug是改不完的。

项目后期,或许测试兄弟是为了绩效还是什么原因,会“往死里测”。但一个10余年工作经验的老专家审视我们的项目的时候,笑着说了句“Bug是永远改不完的”。

要根据需求、计划进行修改,后期功能性的Bug必须改。非功能的体验、无关痛痒的Bug可以不用改。这点要勇敢说不,我做的还不够好!

      5、我知道了影响版本整体进度的关键路径的重要性

版本是模块的集合,如果一个模块“拖了后腿”,其他模块再快也是未完成、未达标。而“拖了后腿”的模块就成为关键路径。

尽早识别关键路径的风险并及时采取跟进措施,对团队开发有很大帮助。

6、 我收获了英语口语的长进,我更加敢说了。

2014-3-20 pm23:47 思于家中床前

作者:铭毅天下

转载请标明出处,原文地址:http://blog.csdn.net/laoyang360/article/details/44500851

如果感觉本文对您有帮助,请点击‘顶’支持一下,您的支持是我坚持写作最大的动力,谢谢!

时间: 2024-07-29 01:01:28

知难而进 ——反思我带的第一个版本的相关文章

CINATRA发布第一个版本

cinatra是什么? cinatra是C++开源社区–purecpp发起的一个开源项目,现在正式发布第一个版本cinatra0.9.0,cinatra是一个现代C++写的web framework,它的目的是给用户提供一个易用.灵活和高性能的web框架,让用户能完全专注于核心逻辑而无需关注http细节.它的灵感来源于sinatra,但又有自己的特色. 如何使用 1.从github上下载源码. 2.安装boost,因为框架用到asio和coroutine,需要1.57及以上的版本. 3.编译.已

Mint17下安装TFS(taobao file sysytem)(带gcc4.8.2版本)

最近研究了一下淘宝的分布式文件系统TFS(Taobao file system). TFS(taobao file system)是一个高可扩展.高可用.高性能.面向互联网服务的分布式文件系统,其设计目标是支持海量的非结构化数据的存储:TFS使用C++语言开发,需要运行在64bit Linux OS上,本文介绍如何在Linux环境编译安装TFS. 在安装的过程中,遇到了许多奇葩的问题,在此吐槽一下淘宝的团队真是懒.TFS介绍里面提到他们团队是用的gcc4.1.2进行编译的,高版本可能会报错,不过

[原创] 更新Ubuntu自带的python2.X版本

Ubuntu自带的Python2版本,是2.7.6的,想更新为最新的2.7.11,操作如下: 1. 从python官网下载2.7.11的source源码包 Python-2.7.11.tgz 2. 解压压缩包  tar -zvf Python-2.7.11.tgz 3. cd Python-2.7.11 4. ./configure 5. make 6. make -i install 说明: 这一步,很多博客或教程,给的都是make install ,我试了,报错 make: *** [lib

Bean Query 第一个版本(1.0.0)已发布

BeanQuery 是一个把对象转换为Map的Java工具库.支持选择Bean中的一些属性,对结果进行排序和按照条件查询.不仅仅可以作用于顶层对象,也可以作用于子对象.更多详细的介绍可以看我的博文: http://blog.csdn.net/justfly/article/details/40486881 我刚刚发布了版本1.0.0. 现在已经在Sonatype OSS库上了,2个小时后将会被同步到Maven中央库上. Sonatype OSS 库下载地址: https://oss.sonaty

总结一下我的dmp第一个版本 也是最后一个版本

刚刚接手了一个新项目-DMP,目前已经开发联调完成,等待测试上线,所以现在来总结一下. 本来是一个前辈在负责,四月底离职了,他离职前我花了一周把这个项目交接了过来,大致熟悉了项目的业务流程以及代码结构, 第二周就开始评审排期开始开发了,其实略略有点方~ DMP是一个管理人群的系统,主要功能有新建和编辑四种不同类型人群,人群分布的一些可视化分析,人群下的广告组的数据分析等等. 目前我做的是1.4版本,本次功能主要是新增数据接入模块,让客户自己新建数据源并查看,新增了三种类型的人群创建,创建时需要选

升级centos6自带的python2.6版本至python2.75

背景: 在部署flask程序时,用到了SQLAlchemy,要求最低是python2.7版本的环境才可以,所以决定升级python版本,由此引发了一系列的问题. 环境: CentOS release 6.9 (Final) Python 2.6.6 开干: 参考文档:https://www.cnblogs.com/smileyes/p/7288487.html 下载软件包 wget https://www.python.org/ftp/python/2.7.15/Python-2.7.15.tg

吃午饭前,按书上的代码写会儿--Hunt the Wumpus第一个版本

有空就要慢慢练起~~~~脑袋动起来是很快乐的事儿....:) <易学PYTHON>演练一遍. from random import choice cave_numbers = range(1,21) wumpus_location = choice(cave_numbers) player_location = choice(cave_numbers) while player_location == wumpus_location: player_location = choice(cave

PowerDesigner 生成带注释SQL 各个版本通用10(12、15)

做数据库是设计时最苦恼的事就是用PowerDesigner工具设计完数据库执行SQL文件后没有注释,那么怎么才能让PowerDesigner设计完有注释呢,下边教你一个笨的方法,方法虽然笨,但是能实现效果. 在物理模型下 操作:Database-->Edit Current DBMS,进入下图页面, 然后分别将 Script-->Objects-->Table-->TableComment Script-->Objects-->Column-->ColumnCom

轻量级ORM《sqlcommon》第一个版本发布了!!!

一.sqlcommon的特色 1. 轻量级,整个包只有123kb 2. 性能好,自测... 3. API和功能简单.代码简短.可维护性好基本都能看懂.这个点我认为很重要,这意味着这个包你可以自行维护修改(修改版只限自己使用尊重一下作者创作权). 4. 面向ADO.NET标准接口实现强大的兼容,不依赖具体数据库驱动程序. 5. 组件独立,sqlcommon的几大核心组件,都是可以独立起来使用的,比如你不会写IL你就可以利用我写的继续扩展查询API 二.sqlcommon的极大核心组件 sqlcom