Archives
-
封闭笔记——第十八天,收官
2010-03-18 晴 今天应该是封闭的最后一天,我们要在最后一天把这次封闭的成果上线展示出来。这次封闭其实更多的是一个练兵,是让兄弟姐妹们能够学习和提高。 今天是我们的收官之战,同志们还在前沿阵地奋战。一拨人公司配合上线的,另外一拨人测试这次开发的功能,还有继续改代码的,还有我这样记录的。 今天大家都很辛苦,几拨人都是到了中午下午才把代码全部搞定提测。需要上线的有两部分,一部分人是这次封闭做的新的小的任务,我们姑且叫做团队A。一部分是和公司一起搞的一个大版本升级,我们不妨叫做团队B。两个任务同时上线,刚刚好可以做一个不是那么精准的比较。 人员组成 A组是一个中级程序员和三个初级程序员组成的团队,每人认领几个指令任务进行开发。 B组是一个半高级程序员,而那一个全人的水平是很不错的。 任务类型 A组是一个组合指令的任务,可以明确的拆分任务,而且B组的负责人前期已经制作好了一个框架。 B组是一个现有系统的升级,牵扯到新老平台的切换,而且要修改的代码很难界定范围。 开发模式 A组采用的是这次封闭尝到的单元测试先行的开发模式。 B组由于是修改现有系统,而且以前没有任何的测试类代码,所以还是传统的开发模式。 任务难度 A组的每一个细分的任务都不是很难,但是比较庞杂,想要做好了必须完全吃透需求和无数的场景。 B组的难度比较大,是公司的一个重点项目,牵扯的系统都很多。 任务强度 A组是这次封闭的主要项目。 B组时间非常紧张,本周才开始。 测试人员数量 A组一个半人,最后这半个测试人员也并入到B组的测试中。 B组的专职测试人员4+人,还有很多不明真相的志愿者。 测试时间 A组采用单元测试,从第一天可以说就在测试,从全部提测到测试结束大约3天。 B组由于任务重,所以测试时间并不多,但是从开发开始没多长时间就开始测试了。 Bug A组的Bug不能算少,但是严重的bug并不多,只是几个。大多数的bug集中在类似文案调整的类型。 B组的Bug并不是很多,但是每一个bug都很纠结。 Bug的修复 A组的Bug由于存在测试用例,所以很容易定位,基本上每一个Bug修复的时间都不长。 B组由于没有测试用例,加之系统复杂,所以每一个bug都无法快速定位,必须依靠经验和对代码的熟悉程度。而且中间还出现了相关人员集中在白板前思索可能的坑在哪的问题。 上面是一个比较不靠谱的比较,也许并不公平。但是我们从中还是能看到一些问题的。比如有了测试用例可以快速的定位bug,比如如果没有我们会很纠结。比如我们每次修改的系统如果牵扯的非常多我们就很抓狂(应该把系统隔离的更好)。 现在已经早上6点了,我们还在准备上线。两个组都还纠结,但是看到曙光了。凡是我们用例定义的好的,测试覆盖的好的,很快就过了,否则都很缓慢。我们还有很长的路要走。 记得第一天我说,行百里者半九十,我们现在还远没有走到九十里。前面的路还很长。 前方的路不知是洒满阳光还是布满荆棘,我都会掸掸身上的土,继续走下去。
-
封闭笔记——第十六天,感悟
2010-03-16 晴 今天大家的工作非常紧张,都进入了冲刺阶段。 今天的感悟非常多。 程序开发,吃透需求非常重要 前天晚上,我在写基础代码的时候,有一个相关的兄弟一直围观。我边写边讲,说根据需求为什么要有这个方法,为什么要这样使用。他一边听一边跟我熬夜,很是辛苦。而且,在昨天拆分需求的时候,他的问题是最多,稍有不明白的就马上询问,对需求的理解也是最清晰的。 结果今天的进度,他是最快的,而且很多看起来可能比较绕的流程也顺利听过。加之TestCase辅助,晚上就已经写得七七八八了。赞一个。 反观另外两个童鞋,这里不得不批评一下。他们的进度主要被耽误在对场景的不理解,不能整体理解需求、把握场景,导致途中频频趟雷。速度起不来,情绪也起不来。 程序开发,从更高的层次思考很重要 我们为了需求,写了一个很小的算是框架的东西,其实就是一个分发器。分发器接收请求,然后轮询问注册进来的指令类是否需要处理,如果需要则分发下去,否则询问下一个。这是一个非常简单和标准的做法,但是我发现很多工程师并不能理解这个模式。甚至到现在,已经基于这个结构作了一些东西之后还是不能完全理解。所以导致很多东西写起来很慢。 程序员要提高自己,其中很重要的一点就是越发的从高一层的角度来看待自己的工作。如果能够高屋建瓴,那么再脚踏实地会事半功倍,而且出错少很多。哪怕我们不能站上去,我们也要吃透自己涉及的相关的代码。 团队遇到的问题是隐藏在平稳下的 最大的感受,其实还是在团队。分配了任务之后,每个人都按照认领的任务开始了工作,一切平静。但是往往是危机四伏,如果此时跟进不及时,往往会出问题。因为我们总是有一些问题是无法预计的,碰到了是想凭自己死磕过去的,或者是根本没意识到这时一个问题的。如果这时候作为一个协调者和后勤人员,及时的在每个人遇到困难时候就跟进,能够在过程中解决大量的问题,节省很多时间。 我觉得,管理对我的要求就是对每个人,每个环节的了解,预判哪里可能出现什么困难,然后第一时间赶过去把问题消灭,让团队顺利的前进。 我的职责是预判可能的问题,并主动的去想办法帮助解决(潜在的)问题,让团队更好的去继续进行任务。
-
封闭笔记——第十四天,上线
2010-03-14 大雪 难道真的2012?现在还下雪,还是鹅毛大雪。娘列~~ 今天重温了一下进度,感觉还是有点紧张的,实在不行就只能砍掉一些需求了。现在给兄弟们的压力太大了,工作很辛苦。不过按照我的说法第三周效率会有一定的提高,因为测试用例大家已经熟悉一些了。不过这个还有观后效。 中午围观了一下上线流程,真是帅呆,累呆。 上线应该是包含哪些呢? 各小组把代码提交到自己的分支 把不同分支的代码(不同小组的代码)合并到上线分支(有些是从分支上线,在此并不讨论,这两种方式没有好坏之分) 把上线分支的代码同步到线上环境 把上线分支的代码合并到其他的分支 这里面说起来挺简单的,而且第三步我们已经有了上线工具可以做到,按道理应该是不难的。但是我们却花了至少一个小时才完成。真是杯具啊。 说起来我们在哪里费时间了呢? 各小组代码提交到自己分支,很快。 把不同分支的代码合并到上线分支,这个费时间很长。 原因是上次的第四步没做好。而且我们每次都做这两步都是基于文件的(而不是基于提交或者 ChangeSet),每次挑选到底哪个文件(甚至哪个部分)要上到上线代码是一项人类体力与智力的考验。如果没有拜过春哥或者你不是从娜美克星来的你可得小心。 使用上线工具,很快。问题也是基于文件的,但是现在还没有遇到问题。 貌似这次又忘了? 这里面最耽误时间的是第二步。今天的花销其中95%以上都是消耗在这里。 个人觉得这里面的问题并不容易解决。比如我们总有一些文件不得不提交,但是这些文件却不需要上线。 这里如何解决呢? 最简单的办法当然是一次性用新的代码合并上去最好,但是如何保证合并后的代码没有问题呢?尤其是一些比如负责分发判断等代码,贸然的合并一定出现问题。而其一些常量定义的文件在多团队开发下,也一定会出现冲突的情况。 根本上我觉得现在上线和多团队开发还不是那么的爽,还需要大量的人力参与,可能还是开发模式的一些有待提高的地方。试想,如果linux也有我们这样的问题,那就真的没法混了。 这个我会好好的考虑一下如何推进。既要让效率提升,又要每次改动都让现行的开发人员平滑的升级,这并不简单。 程序开发是一个团队作战,我们需要明星战士,但是我们更需要一个能捏合整体的有效的方法。而且还要考虑到产品和运营的需求,在市场、产品、研发、积累等等方面做到平衡。管理,则应该是这个粘合剂,我也应该是这个粘合剂。
-
封闭笔记——第十一天,团队
2010-03-11 晴,开始暖和 今天大家已经开始进入到一种稍微憋闷的状态了。有些兄弟开始出现了身体不适的反应,我很担忧。早上没有叫大家,让大家自然地醒来。工作中也第一次允许开放音乐了,必须开始调整气氛了,已经近乎癫狂了。 某个哥们也开始说像他这样不爱说话的人也开始有想见人就拉住聊天的冲动了。 现在我已经开始轰人回去睡觉了。 状态的调整是一个很重要的事情,如何让团队保证一个持续的战斗力是一个很高深的话题。 今天也第一次透彻的感觉到团队的力量。以往看到很多的人说,在一切的资源中,团队是最重要的,但是从来没有过这么直接和透彻的感受。 一个合理的团队搭配是保证高质量战斗力的前提条件。这个团队必须有教练的角色,也必须有核心队员和明星队员。但是最重要的则是梯队的合理。试想,当年风头最劲的黄色潜水艇就是因为其他球员太弱,就算里克尔梅赔上老命也无法杀入欧冠决赛。 现在我的团队就是梯队有些不合理,导致几个兄弟十分疲劳但是任务其他人也无法分担,看得我心焦又心疼。 兄弟们,快快成长起来吧。 晚上和组里的一个童鞋一起看他的测试用例和代码,写的还算不错。和他一起又探讨了一些关于TDD、重构的思维方式以及最佳实践。一次可能灌得有点多了,慢慢来,成长也是一个过程的。 我准备在这几天单独给他开小灶了,必须拔苗助长了,会很辛苦,但是也会很有收获。 有这样的一个机会,我能够近距离的,透彻的观察我的团队,思考团队应该如何进行人员配比、如何建设、团队的弱点、团队的潜力等。这是一个最佳的实践机会,也让我自身提高去更好地履行教练的职责。 知难行易,任重道远。加油。
-
封闭笔记——第八天,第一次全员思想碰撞
2010-03-08 鹅毛中雪 今天早上中午还都是平平淡淡的过去的,没有波澜,只有不惊。唯一的不同时窗外白茫茫的世界。从夜里开始下雪,周围已经都白了,天气也冷了,这是什么天啊。2012? 下午吃饭前1小时的时候,我们决定提前进行CodeReview,按照某些人的说法就是“爽一下,然后去吃饭”。 今天上战场的小哥是一个测试开发人员,我已经单独的给他Review过至少三次代码,代码的质量已经好了很多了,让他上去游街我还是比较放心的。 不明真相的群众纷纷前来围观,我们又开始激烈的讨论,今天的讨论让人为之一振。 今天我们没有过多的纠缠在编码风格等地方,究其原因应该是: 经过一周的训练,小哥的编码已经没有太大的问题了 经过一周的围观,群众的见识已经大大的不一样了 取而代之的是,我们花了很大的篇幅来讨论 TestCase 应该怎么写;测试断言应该到什么粒度;测试时候是否相信(一个)函数的功能;重构时候函数抽取到底应该包含那些;等等,不一而足。讨论非常激烈,而且也第一次出现了双方的论述都有道理,都无法彻底的说服对方的情况。这是一个好的现象,说明我们已经上升到了一个思辨的层面,也说明我们已经开始有能力站在稍微高一点的层次来看待开发这点事儿了。 今天分歧最大的一点在于几个开发人员认为用例覆盖的太过于细致,被抽象出来的一个创建对象的方法里面进行了大量的检查,这是没必要的。而负责写用例的童鞋是测试人员,他认为是非常有必要的。从而展开了一场声势浩大的拉歌比赛。 我个人从如下三点来理解这个问题和分歧的: 要考虑代码是经过多次重构长起来的 今天大家看到的代码其实是重构了多次,一点点的生长起来的。在重构的过程中,一定会出现为了几个地方差不多,略有不同但是本质上可以放在一起的情况,这时候把他们重构到一个方法中不能说不合适。而这时候造成的结果可能就是这个方法只能上稍微有一些臃肿。这时候我们可以选择职能继续拆分,或者是忍。可是忍了,这些(逻辑上可能)多余的代码怎么办? TestCase 中无副作用的多余的代码如何处理 我个人写 TestCase 的习惯是这样的。写好的断言,如果不是非要删除不可,一般我都会留下。因为这不是功能性代码,这地方稍微罗嗦一点没关系,而且说不准哪天会用上。而最重要的理由则是,这些代码没有副作用。当然了,如果某些断言耗时很长,那就属于有副作用了,如果没用,坚决干掉。 每个人的职责不同,看问题的角度不同 还有一个问题就是大家看到的问题的角度是不同的,开发看的是用例应该体现设计思路、单一职能,要简洁。而测试人员看到的是我不相信一切,我要覆盖到一切可以覆盖的地方。而引申出来则是开发童鞋看到的用例应该测试单元,而测试童鞋的用例则是为了覆盖场景。 这个思辨的过程是我第一次想到的,也是我觉得收获最大的一点。如果我们认为测试和开发是站两边,现在团队已经开始在朝着中间靠拢了。我记得我说过一句话,就是开发的单元测试用熟练以后是应该朝着覆盖场景前进的。这也算是我们为了以后更大规模的自动测试前进了一小步吧。 随着测试驱动开发的锻炼,我相信开发人员都会有一颗测试的心。 还有,期间有童鞋说,写断言没错,但是如果是多个断言,可能会打断正常的思路。 这里面我给出的答案是“采用占位方法”。说起来很简单,就是在需要写大量代码的地方,给出一个占位的方法,这个方法的职责就是去完成那需要多行代码组合起来的功能。这时候就不怕思绪被打乱了,而且这个方法还没有,编译/运行肯定不过,也不怕回来忘了。 今日Milestone,测试人员已经开始测试了。给出了一个任务,要求测试的MM和功能开发的兄弟明天一起给出一个报告。这个报告是要对比使用 TestCase 前后的不同的。其中应该包括Bug的数量、回归的时间、问题的定位等。 完成了这一步,我们的测试驱动开发才能算是完成了一个完整的循环。
-
封闭笔记——第六天,调整状态
2010-03-06 晴 小风 貌似某些地方有雪 今天总体上就是某些人的幸福和郁闷。 早上领导来探班,带来了很多吃的喝的,鼓励一番大家后,考察了进度等情况,还算不错。中午一起去吃饭,可算换了一个饭店,这才好点。 下午大家就是休息,毕竟太累了。等晚上吃饭的时候,发现各个食堂都没地方了,只好回来CodeReview。这下某些人郁闷了。我们这群不明真相的群众不断的挑出了很多的问题,搞的当事人很是xxxx。 问题很多,等我稍后一起总结。 然后CodeReview被强行终止,因为太饿了,鉴于食堂还是没有地方,我们出去吃了一顿野食。比较丰盛。回来打了一下牌,强行要求所有人休息。 明天早上睡个懒觉,然后继续拼杀。
-
封闭笔记——第五天,开始进入状态
2010-03-05 大风 今天感觉大家已经开始进入状态了,进入测试先行的状态了。 任务最艰巨的一个组已经画完了燃尽图,看上去排列的非常紧密。而且大家也都把 TestCase 相关的东西用起来了。 给几个童鞋 Review 了一下 TestCase,感觉到了成长和差距。很多童鞋总是太纠结于实现和细节,总是想这个东西是怎么做出来的,但是对他们应该怎么提供给别人使用和担负着什么职责明显关注不够。 如下的几个问题可能大家都会遇到: 能写程序但是不会写程序 写出来能运行的程序不难,但是写出来能正确运行并且优雅的程序很难。很多的程序从功能实现的角度没问题,但是从使用者的角度去看,就觉得用起来总有一些地方不爽和别扭。 解决的办法就是我说的用 TestCase 来规范你的编码设计,把 TestCase 当做你使用的场景。让每一个调用,每一个判断都自然而然的,思绪就好像小溪一样流到你的指尖,自然的形成一种被调用的代码。简简单单,自然而然。重剑无锋,大巧不工。 程序不够简洁、美观 很多人认为程序是完成功能的。但是我记得看过这样一句话,“程序首先是给人看的,然后才是给机器运行的”。我非常赞同这句话。现在的团队协作越发紧密,一个人是无力支撑一个系统的。这时候代码的沟通需要的是简单、清晰,目的是传达你的思想,而不是炫耀你的奇技淫巧。还是那句话,重剑无锋,大巧不工。 多几个空格,多几个空行,好一点的排版,这样同样的代码就清爽很多。我总说好的代码就好像身材曼妙的女人——凹凸有致。后退一大步,看看屏幕,如果一坨一坨的,你都看着恶心,那哥们,还是修饰一下吧。 代码的美,也在于留白。 对面向对象程序设计理解使用不当 什么是面向对象?为什么使用面向对象?应该怎么使用面向对象? 这些问题很多人并不能回答,很多的对面向对象的使用,更多的就是把类当做一个方法的容器,所有的调用都是静态的方法,使用起来很丑陋。 今天给他们讲了一下对象的概念,看上去他们有了一些理解,也做出了一些看上去像点样子的代码了。还要持续观察。 但是让我最欣慰的是大家已经上道了。主动的让我去 Review 代码和 TestCase,让我帮忙一起分析用例和实现代码级别的 TestCase,愿意听我絮叨程序设计和开发中的一些经验,并且努力的尝试着去理解和实践。这些非常让我开心,我愿意这样做大家的召唤兽。 今天晚上没有计划没有安排什么工作。每天工作到凌晨零点,并且有些童鞋连续两天工作到凌晨一点,今天算是强制性的休息。但是晚上还是有些不自觉的人去写代码,我们都想把他按到床上绑起来睡觉。 程序员,请注意和照顾你自己的身体,这真的很重要。 另:今天晚上 QQ 同时在线突破 1亿 人,真NB。
-
封闭笔记——第四天,平静的前行
2010-03-04 晴 又是微凉 今天的工作比较平淡,只是一切按部就班的前行。各个项目组也开始拆分场景和任务并且入Trac了。 这里面突然发现团队梯队建设的重要性。其实我一直自认为梯队做的还是不错的,高中低错落有致,但是在此次封闭中,还是发现了一些问题。 能够全面把控和影响队友的人还是少。如果说是因为我们第一次采用全新的开发方式导致了很多初级工程师不习惯,很纠结,那么我们在流程制度的推行上是否要更加的慎重和考虑更多的东西呢? 这些恼人的问题值得总结和深思。 晚上还是照例的 Code Review,之后和几个同事针对 TestCase 进行了一些思辨。发现了几个问题,总结一下 从开发的角度,是从下往上看,还是从上往下看? TestCase 是否真的节省时间? 第一次用 TestCase 怎么估计开发时间? 为什么功能性代码写起来很快,而 TestCase 耗时巨长? 其实这些都是我们成长中必经的一些道路。我们每个人都无法停留在 舒适区,我们必然要痛苦和茫然的跨过恐慌区,走进学习区。逆水行舟不进则退,要相信,我们一直在成长、前行。
-
封闭笔记——第二天,开始优化流程
2010-03-02 晴 微凉 今天我们进入了正式的开发阶段,各个项目组也都开始按照自己的步骤进行下去了。 今天非常显著的几点进步如下: 产品、测试拆分场景 研发拆分用例为 TestCase Git 初步使用 今天我一直在整理新的开发流程,相对于以往,新的流程非常强调场景的概念。从产品的需求到最终上线,都是围绕场景的。(具体我会稍后详细解说) 对于场景,第一步也是关系着流程能否跑起来的关键的一部就是产品的用户“场景”。今天我们伟大的产品人员抽象了每一个用户场景,让我们测试和研发的童鞋非常容易入手。 对应着“场景” ,我们的产品、测试、研发都进入了角色,都开始了围绕着场景的战斗。 花开两朵各表一枝,我们先说产品和测试的用户场景。早上,产品和测试的童鞋采取了半结对的方式拆分用户场景,把每一个场景都拆分成为逻辑上可以测试的用例,并记录为Wiki。这样以后对产品的需求覆盖有据可循,也对研发的开发边界有了一个良好的指导。 我们再看另一路的研发。携昨晚测试童鞋拆分用例之威,今天研发的童鞋就已经开始撰写 TestCase,并且已经跑起来了。来,为他们呱唧呱唧。 TestCase 就没什么可说的,今天说说在使用过程中,尤其是初次使用的时候可能遇到的一些问题和疑问。最常见的是: TestCase 和功能性代码貌似只能迭代进行,无法先写完整的TestCase TestCase 中的那些只有名称没有实现的代码,看上去怪怪的。 先说第一个问题,如果是个人开发,当然是迭代进行最为爽快,用例完成,代码也完成。但是对于团队开发,而且是从业人员有梯度的情况,情况可能不同。因为有时候要以一个设计者的身份,有时候要以一个管理者的身份。这时候,我们可能需要更多的统管的一些责任,那么完成大多的TestCase是一种比较可行的办法。 对于第二个问题,其实使我们在开发中身份转换的一个情况。大多的场合,我们是开发的身份是开发人员,我们是细节,这时候我们的视角是从下向上看的。而在我们撰写TestCase时候,是一个使用者和设计者,这时候我们是需要从上往下看的。我们是API的第一批使用者,如果这些API我们自己用着都不爽,那么别人一定会来砍我们的。 另外,我们这次还有很重要的一个环节,就是每天晚上的Review。这里既包含对代码的Review,也包含对TestCase的Review。这里不再废过多的笔墨,我会找时间专项讲解的。 第二天的工作是充实的,我们感受到了团队在成长,感受到每个人在成长。真不错。
-
bzr快速入门(3)—- 使用看门人,Gatekeeper
有没有遇到过这样的时候,一个手欠,或者没注意,一个还没有完全写好的功能就放到主分支上了,而且还很幸运的打到release里面。好吧,你没那么幸运,但是几个经验不是很丰富的小弟把代码随便传上来,你总得看一下吧。 这个怎么搞呢?难道你跑去每个人的地方看看?看着他们跑测试用例?跟着他们做Code Review?一两个人还行,人多呢?要是人不在你身边呢?比如远程开发?如果组织结构更大一点呢?开发团队在开发,测试团队在测试,这样很可能一个没有经过充分测试、检查过的代码版本,就被测试团队抓走了,然后可能就是一堆的问题咯。其实有问题还好,要是有问题没检查出来,那就更麻烦了。 所以,利用bzr的这种天然的DVCS的优势,添加了一个叫做Gatekeeper,看门人的概念。这个概念说起来是很简单的,就是所有的代码,该提交提交,该搞啥搞啥,但是呢,不是提交到主开发分支哪里,而是提交到看门人负责的一个分支上,由他来进行统一的测试审查等等。等完事OK了,他(只有他)再提交到主分支上就好了。这样就保证了所有的问题,低质量的代码,都被看门人挡住了。 看门人可以是一个人,也可以是一个团队,只要能够保证产品的质量就可以了。 比如在服务器,代码都是放在/repo/main上面的,哪么现在根据main生成一个dev.main的分支,所有的人都是基于dev.main进行开发。而测试团队则选择main进行测试,这样开发和测试就已经分开了。然后看门人保证dev.main的质量,当质量达到一定的水平之后,并且代码稳定了,就可以把dev.main merge到main上面了。
Sep 11th, 2008 | Filed under bzr