为您推荐:
精华内容
最热下载
问答
  • 5星
    924.54MB abear2 2021-01-20 02:18:31
  • 53KB m0_64350923 2022-01-22 18:09:40
  • 团队里面会学习的人挺少的,作为leader,不管效果如何,都有必要去帮助大家学习成长,于是发起了这样的一次交流会。 准备工作 在进行交流会的前几天,我用思维导图大概罗列了下交流讨论的思路,如何发给...

    背景

    去年底制定了2018年团队培训计划,培训内容包括业务介绍、linux、中间件、自动化测试、性能测试、安全测试等主题,排期上基本一周一次。
    年后进行了一两次,一次是白盒测试初体验,一次是测试小白的成长经历,效果还可以。后来因为一些事情,我不得不对培训计划做了一些调整,优先进行一些各产品线业务的分享,对业务分享也提了一些要求:必须包括系统架构、业务流程图、网络拓扑图、服务模块介绍、数据库表设计、系统演示和测试重点。由于对培训内容做了这样的调整,做了张问卷调查,收集下大家的反馈意见,调查结果是大多数人都想听技术培训,不太想听业务培训,这样的结果是在我的意料之中的,只能说现在国内的测试大环境下,很多人已经迷失了自己,很迷茫,不知道测试的真正价值是什么?人云亦云,会自动化测试、会性能测试、会写代码很吃香,这篇文章不去探讨这些人云亦云的东西对不对,适不适合当前的自己。假设我们需要具备这些能力,大家都是如何去学习的?如何去达成自己的目标的? 团队里面会学习的人挺少的,作为leader,不管效果如何,都有必要去帮助大家学习成长,于是发起了这样的一次交流会。

    准备工作

    在进行交流会的前几天,我用思维导图大概罗列了下交流讨论的思路,如何发给大家做一些准备工作,大致思路如下图:
    如何学习

    时长

    整个交流会时间大概1个半小时,每个人大概5分钟

    人员

    参与人员为团队所有同事,20人左右

    形式

    每一个人都围绕着这个思路聊聊自己是如何学习的,最后发表下自己的观点和感受

    过程

    一开始,我希望每个人都能主动的去分享自己是如何学习的,可惜主动的人很少。只能我一个一个点名来说,每个人发表的观点关键字我都写在白板上,字有点丑,里面就将就着看
    关键字

    然后从这些点进行归纳,罗列出最关键的内容,团队的一个实习生妹子做的会议纪要,把最关键的点用文字再组织了下,写的挺认真的。

    (1)学习要善于总结;

    (2)学以致用,代码需多动手多练习;

    (3)不要害怕麻烦;

    (4)敢于吃苦;

    (5)在学习中寻找成就感;

    (6)维护自尊心,不能被开发鄙视;

    (7)兴趣是最好的老师,培养学习的兴趣;

    (8)多与开发聊天,从中尽量减少自己的盲区;

    (9)一个知识点一个知识点的去学习,不要急于求成;

    (10)不懂的应该马上查资料,弄清楚原理;

    (11)学习最新的技术,感受危机感;

    (12)需求是测试的根本,要对需求理解透彻,学会切换不同的角色;

    (13)自身体验测试的产品整个流程;

    (14)提高自己的自律性,监督自己自学;

    (15)最难得可贵的是“坚持”二字;

    (16)自发性的学习,提高自己的主动性;

    (17)不要以忙为不学习的借口,告别惰性;

    (18)学习方法很重要,可提高学习效率,增强成就感。

    总结

    在交流会结束前几分钟,我做了最后的总结,人人都想学技术,每一个都扪心自问,你做到了下面几点?

    • 感兴趣:这个东西没兴趣,就很难坚持下去,就会三天打鱼两天晒网

    • 坚持吃苦:吃不了苦的人,很难坚持枯燥的学习,一有诱惑就抵挡不住,还给自己找一堆借口,不是自己不想学,而是因为。。。

    • 好的学习方法:这是一个信息量爆炸的时代,任何你想学习的技术,都有一大堆的心得经验,一大堆的最佳实践,自己无法鉴别无法找到适合自己的学习方法,可能事倍功半,也可能被淹没在这些知识海洋里,一无所获

    • 主动:不主动的人,学技术,只会关注事情的一个点,而不会去主动去关注一条线,更别说去关注一个面,不会主动去研究原理性的东西,最终学到的东西就只会是很肤浅很狭窄,知其然但不知其所以然

    最后,我想说的是:学习是自己的事情,没有人会手把手的教你,当你意识到自己想学习某个技术的时候,问问自己学习的目的是什么?你做好准备了吗?我建议那些想学技术的测试同行,不要盲目听别人的,要有自己的判断,确定自己要下决心学了,那么就拿出学习的态度来,做好枯燥、寂寞、吃苦的准备,坚持每天都学习,不要给自己找任何借口,要抵得住诱惑,然后在学习的过程中摸索自己的学习方法。不管是自己搭建环境捣鼓还是运用在工作中,不断的找到学习这个技术给你带来的成就感,有了成就感才会激发你下一个阶段的学习激情。当你回过头看看之前的你,是否成长了,还是一直徘徊在原地。

    温馨提示:对于那些对某个技术感兴趣,但不太主动和不知道如何学的测试同行,可以花钱报培训班,花钱了一定程度上会督促你坚持学下去

    展开全文
    kuangay 2018-04-08 17:33:36
  •   昨天在大学专业的交流群里看到某个学弟发了张自己打算学的算法列表图,然后瞟了一眼,看到了KM算法,而之前写的一篇深信服在线笔试-2018.9.22,的编程题的第四题:求一个二维数组或者说矩阵的不同行不同列的合的...

      昨天在大学专业的交流群里看到某个学弟发了张自己打算学的算法列表图,然后瞟了一眼,看到了KM算法,而之前写的一篇深信服在线笔试-2018.9.22,的编程题的第四题:求一个二维数组或者说矩阵的不同行不同列的合的最大值,我采用的是穷举方法,而看到别人说最好的方式是采用KM算法,穷举计算量实在过大了,所以来学习一下KM算法。
      (PS:这段话是闲扯)然后就去百度了一下KM算法,看到了很多篇大多都是先介绍匈牙利算法,然后KM算法,匈牙利算法让我突然想起了大四上学期学习的运筹学(忘光了),然后脑子抽了一下,突然想起可不可以用动态规划去解决之前的那个问题,即把问题模拟成一个最长路径单向图问题,这样的话就需要建立一个路径表,但是这是不可行的,因为动态规划有一个性质,如果某阶段状态给定后,则在这个阶段以后过程的发展不受这个阶段以前各段状态的影响,而不同行不同列的值计算,把每一列看成一个阶段,那么每个阶段会依赖于之前的各个段影响(受不同行的影响),那么就不适用于动态规划,所以还是老老实实学习KM算法怎么用吧。
      
      
      由于写的有些多,在这里大概介绍文章结构分布:
        1、KM算法步骤以及计算过程
        2、代码实现思路
        3、代码
      
      个人理解:KM算法,用通俗的话说其过程,其实就是对二分图中的两个顶点集合X、Y中的每个元素设置标杆(初始值),然后给其中的一个集合的所有元素标杆初始化为连接到另一个顶点的边的最大(小)权值,然后另一个集合的所有标杆初始化为0,这样二分图中的每个顶点与顶点的一开始的连接都是最大权值的边,为了让每个顶点都只匹配一个顶点(在我们解决的问题中就是解决不同行不同列),我们就需要对连接的边进行调适,让冲突的边(X集合中多个顶点连接Y集合中的一个顶点)进行换边,使换边过程造成的权值变化最小的顶点更换连接然后更新标杆值,通过这样的操作,将每个点与点进行匹配,然后不断的进行换边,从而达到全局最优(最大或最小)的匹配结果。

    KM算法:

      用于求二分图匹配的最佳匹配。何为最佳匹配?就是带权二分图的权值最大的完备匹配称为最佳匹配。 那么何为完备匹配?X部中的每一个顶点都与Y部中的一个顶点匹配,或者Y部中的每一个顶点也与X部中的一个顶点匹配,则该匹配为完备匹配。
      二分图:就是一个图中的顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集(如X、Y),两个子集内的顶点不相邻。
      这里我会一步一步的说明的,相关的名词也会慢慢介绍,对于增广路这个概念,我个人觉得在代码中没体现出来,所以就没打算说这个事,如果使用增广路,然后取反得到完备匹配的话,那么个人感觉是需要设置两种状态,一种是可匹配(未匹配),另一种是已匹配,然后取反操作,似乎这样就变得有些难理解了,所以在这里并不打算说这个。

    算法步骤如下:
      1.用邻接矩阵(或其他方法也行啦)来储存图,注意:如果只是想求最大权值匹配而不要求是完全匹配的话,请把各个不相连的边的权值设置为0。
      2.运用贪心算法初始化标杆。
      3.运用匈牙利算法找到完备匹配(遍历X集合的每个顶点)。
      4.如果找不到,则通过修改标杆,增加一些边。
      5.重复3,4的步骤,直到完全匹配时可结束。
      
      在这里设cx[i]为X集合的标杆,cy[i]为Y集合的标杆,w[i][j]为图的邻接矩阵表示X[i]–Y[j]边的权值。
      标杆:是为了求最大(小)权值而引入的一个概念,用于存储X集合每个顶点到Y顶点中的最大值,而Y集合的标杆值全初始化为0,如下图中,X集合为{A,B,C},而Y集合为{D,E,F},每个X的顶点标杆值为路径权值的最大值,而Y的顶点的标杆值初始化为0.
    在这里插入图片描述
      重点:因为使用了标杆这个概念,我们在使用匈牙利算法进行边匹配的时候就不能是看边是否存在,也就是判断w[i][j]==0来判断边是否存在,引入标杆后,我们判断边是否存在(这里指的是匹配的两个标杆的值的合是否与路径值相等,不相等就不存在),即cx[i]+cy[j]-w[i][j]==0,如果该等式成立的话,就表明这两个顶点可以匹配(连接),但并不表明这两个顶点可以直接匹配(连接),因为可能还有其他点与其连接,所以在这种条件下,存在两种情况:
      1、如果这个成立且Y[j]边没有被X集合中其他顶点匹配。
      2、Y[j]边已经被X集合中的某一顶点X[k]匹配,但是X[k]可以匹配其他的顶点,或者是X[i]可以改选其他的匹配。
      只要满足以上两个条件之一,X[i]与Y[j]就可以匹配,然后这里问题又来了,如果碰上情况2的话,如何让X[k]去匹配其他顶点呢?这时候,我们就要靠d值去更新标杆值,d=min(cx[i]+cy[j]-w[i][j]),这时候标杆的作用就体现出来了,不太了解是什么意思的话,我这里举一个例子:
      在上图中,首先A与D匹配,记作A-D,然后B的标杆值为14,而14+0=14,所以B也要去匹配D,此时就碰上条件2的问题,那么我们该让A、B两点谁去匹配其他点呢?,这时候就得根据d值进行选择,从图上,我们可以看出d=cx[A]+cy[E]-w[A]][E]=3,是A到除了被匹配的点以外的其他点(即除了D点以外的点)权值变化最小的d值,而B到除了D点以外的点的变化最小的d值为cx[B]+cy[F]-w[B][F]=6,这里我们就可以看出,如果要改动B的话,需要变化或者说是变动)的权值为6,相比起改动A的匹配点仅仅需要变化3来说,改动B是不划算(对于求最大权值来说是不划算),所以我们就更新各个标杆的值,让A可以去匹配E,即A-E,B-D,当然,这里并没完成匹配,只是更新标杆值。
      到这里,应该清楚如何添加新的边了,添加完新的边后,对应的标杆值也需要更新,即A、B的标杆值-d,D的标杆值+d,这里我们就需要清楚,到底是哪些值会受影响,如上面受影响的是集合X中的{A、B}与Y集合中的{D},也就是当我们遍历B点匹配的时候,匹配形成的路线是B-D-A,是一条不合法(冲突)的路径,此时设置一个集合S存储不合法路径中的X集合元素A、B,集合T存储不合法路径中的Y集合元素D,这样每次更新d值的时候,遍历S集合进行-d,遍历T集合进行+d即可。
      上面算是对步骤3、4进行详解了,接下来可以来手工模拟上图的求值步骤。
      1、遍历X集合,首先,A可匹配D,D没有被匹配过,A匹配D。
      2、B可匹配D,而A已经匹配D,形成B-D-A不合法路径,此时S集合为{A、B},T集合为{D},那么从A、B两者中找匹配E、F变动权值最小的点进行更改匹配,经过d值比较得出A匹配E变动较小,d=3,所以更新S集合与T集合中的标杆值,值的变化使得A可以匹配E,也仍旧可以匹配D。
      3、更新完值后清空集合S、T,再次遍历B点匹配,然后B与D匹配,A与E匹配。
      4、C无可匹配的点,此时S集合为{C},T集合为{},那么从C匹配D、E、F中找d值变动最小的进行匹配,此时D标杆值为3,所以d1=cx[C]+cy[D]-w[C][D]=3,d2=cx[C]+cy[E]-w[C][E]=1,d3=3,选取最小的d2=1,然后更新集合S中元素的值,此时S集合只有C,所以C标杆值=cx[C]-d=12。
      5、因为C没有匹配到值,所以还得继续匹配,此时C可以匹配E,而A已经匹配E了,形成C-E-A-D-B不合法路径,此时S集合为{A、B、C},T集合为{D、E},这时候找A、B、C到点F变动最小得值d,然后再更新S集合与T集合各顶点的标杆,在这里d=2,即C可匹配F变动最小。
      6、更新完值后清空集合S、T,C标杆值为10,再次为C进行匹配,此时F可匹配,因为X集合点遍历完成,所以程序结束。
      7、经过上面的匹配,得到的结果是A-E,B-D,C-F,则最大值就是12+14+10=36.
      
      

    代码实现思路:

      
      下面是伪代码,和实际代码其实差别不大…
      findpath函数,即找point到Y集合中每个点是否存在匹配路径,S、T则负责记录经过的路径用于在找不到匹配路径的情况下添加新的边,以及防止进入死递归。
      

    //邻接矩阵的行与列值
    int row,col;
    //记录X-Y顶点匹配的数组,即link[y]=x,表示集合Y的第y个顶点与X集合的第x顶点匹配
    int link[MAXLINE]={0};
    //存储图的权值的邻接矩阵
    int w[MAXLINE][MAXLINE]={0};
    //存储X、Y标杆权值的数组
    int cx[MAXLINE]={0},cy[MAXLINE]={0};
    
    bool findpath(int point,char *S,char *T){
    	//路径上X集合的点,加入S集合中
    	S[point]=1;
    	for y=1;y<=col;y++
    		if T[y]==0 and cx[point]+cy[y]==w[point][y]{
    		//point与y顶点可匹配,把y加入集合T中
    			T[y]=1;
    		//判断是否y顶点是否与其他顶点点k连接
    		//如果存在点k那就试图找其他路径
    			if link[y]==0 || findpath(link[y],S,T){
    				link[y]==point
    				return true;
    			}
    		}
    	return false;	
    }
    
    int KM(){
    	//初始化标杆
    	for i =1;i<=row;i++
    		cx[i]=w[i][1];
    		for j =2;j<col;j++
    			cx[i]=max(cx[i],w[i][j])
    	//从X集合种的第一个顶点开始匹配
    	int Xpoint=1; 
    	int d=INF;
    	while(Xpoint<=row){
    		//初始化集合S与T,存放不合法路径上的顶点,以便修改标杆值
    		char *S=new char[row](0);
    		char *T=new char[col](0);
    		//findpath为使用Xpoint遍历Y集合的顶点函数
    		//return true表示Xpoint匹配成功,进行下一个点匹配
    		//return false表示匹配不成功,需要加一条边或者说是让S集合中的某个顶点改选路径
    		if (findpath(Xpoint,S,T)){
    			Xpoint++;
    			delete []S;
    			delete []T;
    			continue;
    		}
    		//找出集合S中匹配除了T集合中的顶点的其他顶点权值变动最小的值
    		for x =1;x<=row;x++
    			if S[x]==1:
    				for y=1;y<=col;y++
    					if Y[y]!=1:
    						d=min(d,cx[x]+cy[y]-w[x][y])
    		//没找到匹配点
    		if d==INF
    			return -1;
    		//更新标杆值
    		for x=1;x<=row;x++
    			if S[x]==1:
    				cx[x]-=d;
    		for y=1;y<=col;y++
    			if T[y]==1:
    				cy[y]+=d;
    		delete []S;
    		delete []T;
    	}
    	int res=0;
    	for i=1;i<=row;i++
    		int flag=link[i];
    		if flag>0:
    			res+=w[flag][i]
    	return res;
    }
    

      
      

    代码

      
    实际代码采用的是别人写的,出自于:二分图(三)——KM算法
      个人仅仅修改了部分代码以及注释,因为逻辑挺清楚的,就不打算重写了,这里也挺佩服这些算法竞赛的人,初中高中就在学这些算法,想想我那时候还在网吧玩游戏…哈哈…

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const size_t SIZE = 1000;
    int w[SIZE][SIZE];
    const int inf = (1 << 20) - 1;
    int m, n;
    int cx[SIZE], cy[SIZE];
    bool usex[SIZE], usey[SIZE];//用于记录每轮的集合S与T
    int link[SIZE];//link[i]=x代表集合Y[i]中的顶点与x匹配或者连接
    
    //dfs 1、return false,用于记录集合S与T,通过深度遍历,找到连接路径上的点。
    //2、retrurn true,用于记录匹配,或者对已匹配的点进行再匹配。
    bool dfs(int u) {
    	usex[u] = 1;
    	for (int i = 1; i <= m; i++)
    		if (!usey[i] && cx[u] + cy[i] == w[u][i]) {
    			usey[i] = 1;
    			if (link[i] == 0 || dfs(link[i])) {
    				link[i] = u;
    				return 1;
    			}
    		}
    	return 0;
    }
    int KM() {
    	memset(cy, 0, sizeof(cy));
    	memset(cx, 0, sizeof(cx));
    	for (int i = 1; i <= n; i++)
    		for (int j = 1; j <= m; j++)
    			cx[i] = max(cx[i], w[i][j]);
    	for (int i = 1; i <= n; i++) {
    		while (1) {
    			int d = inf;
    			memset(usex, 0, sizeof(usex));
    			memset(usey, 0, sizeof(usey));
    			if (dfs(i))
    				break;
    			//以下为对S集合找变动最小的d值
    			for (int i = 1; i <= n; i++) {
    				if (usex[i]) {
    					for (int j = 1; j <= m; j++)
    						if (!usey[j])
    							d = min(d, cx[i] + cy[j] - w[i][j]);
    				}
    			}
    			if (d == inf)
    				return -1;
    			//更新S、T集合中的标杆值。
    			for (int i = 1; i <= n; i++)
    				if (usex[i])cx[i] -= d;
    			for (int i = 1; i <= m; i++)
    				if (usey[i])cy[i] += d;
    		}
    	}
    	int ans = 0;
    	for (int i = 1; i <= m; i++) {
    		int flag = link[i];
    		if (flag)
    			ans += w[flag][i];
    	}
    	return ans;
    }
    int main() {
    	while (scanf("%d%d", &n, &m)) {
    		memset(w, 0, sizeof(w));
    		memset(link, 0, sizeof(link));
    		for (int i = 1; i <= n; i++)
    			for (int j = 1; j <= m; j++)
    				scanf("%d", &w[i][j]);
    		printf("%d\n", KM());
    	}
    	return 0;
    }
    
    展开全文
    qq_21049875 2018-10-10 13:07:55
  • 老师接着说:如果同行评审是指审查(Inspection),代码也用正式同行评审是很理想,但可能太花人力,所以越来越多团队使用静态(代码)检查。 评审方法有很多,常见的包括: 审查(Inspection) - 最正规,最...

    如何提升(软件)交付质量
    大家可先看看下面 Xerox 公司的缺陷统计数据

     

     

     

     

    缺陷修复成本是越后越高,而且以倍数递增, 所以 软件工程有个重要原则,尽量第一次就把工作做好 (do it right the first time),减少返工。

    所以从软件质量管理,我们要:

    1. 尽力避免在整个开发过程中产生缺陷

    2. 如果有缺陷产生,要尽早排除。例如:瀑布性开发过程 - 要做需求评审,设计评审,代码走查 , 单元测试

    3. 在过程中收集不同阶段发现的缺陷数,两个目标:a)把总的缺陷降低;b)把缺陷的高峰尽量往前推

     

    下面首先会先介绍 CMMI V2.0 PR 与 VV 的 Practice 如何一一对应 以前 V1.3。

    接着用一些实例解答如何从1级升到2级再升到3级,量化管理等的常见问题:

    1. 从1级升到2级:我们做好测试,有系统测试,有QA保证不就可以了吗,为什么要花精力做评审,尤其现在讲究敏捷、简单,评审是否已经过时?

    2. 为什么要把在评审中发现的问题记录下来并跟踪,让成员自发完善不是更省事吗?

    3. 为什么要有固定的测试环境?为什么重要?

    4. 为什么极少公司能做好量化管理?收集哪些数据?成功要素是什么?

    5. 量化管理、度量,为什么要统计?自己依据发现的问题改好是否也可以?统计出来的数据应该如何有效利用才对整个团队的提升有帮助?

    例如:有效的量化管理必须依据有效的公司目标驱动,后面的金融产品开发组的量化管理例子告诉我们 - 除了要度量公司关心的结果外,也需要度量一些可控因素,才能更好帮我们改善。

    最后以 ‘质量之旅’总结,让大家了解质量改进的路径图,与不同成熟度的差异。

    整个讨论也对应CMMI V2.0 模型 的 ‘同行评审 PR’与 ‘验证确认(V&V)’各实践

     

    • 目录  

    • PA介绍

    • PR 1.1对工作产品进行评审并记录问题

    • VV 1.1执行验证来确保需求得到实现并记录和沟通结果

    • 从1级升到2级:同行评审案例分享

    • PR 2.1开发并持续更新用于准备和执行同行评审的程序与支持材料

    • PR 2.2选择要进行同行评审的工作产品

    • VV2.1 选择用于验证和确认的组件和方法

    • Agile Tips 敏捷又如何

    • PR 2.3使用既定程序准备和执行选定工作产品的同行评审

    • PR 2.4解决同行评审中发现的问题

    • VV 2.2开发,使用并保持更新支持验证和确认所需的环境

    • VV 2.3制定、保持更新并遵循验证和确认程序

    • 3级:从定性提升到度量与分析

    • 与一金融产品开发组长对话

    • 度量可控因素

    • PR 3.1分析从同行评审得到的结果和数据

    • VV 3.2分析和沟通验证和确认结果

    • VV 3.1制定、使用并保持更新验证和确认标准

    • 质量之旅

    • 附件1:敏捷团队如何有效利用度量数据分析

    • 附件2:Inspection审查

    • 反馈

    • References

    •  

    PA介绍

    PR (V2.0)

    VV (V2.0)

    VAL (V1.3)

    VER (V1.3)

     

    CMMI V2.0从V1.3特别抽出“验证”(VER) 中的第二目标“同行评审”作为一个单独的PA。 可见CMMI也认同同行评审确实可以帮助项目预早找出缺陷和问题,减少后面的返工。

    在V2.0, 同行评审的大部分实践属于CMMI 2级 (分析部分属于3级)。以前在V1.3,“验证”(VER),包括同行评审,和 “确认”(VAL) 都属于 3级,工程部分。

    2.0版本和1.3版本的对应:

    V2.0 对应 V1.3

    什么属于 验证(VER) 或 确认(VAL) , 一直有很多争议 (我确实见过 一些开发公司 V V 的 定义 与 CMMI 的定义刚刚相反)

    V1.3 的 VER 与 VAL 本来就很相近: 如果把VER 的 中间第二部分抽出来, V 与 V 的内容基本一致:

    PR 2.1 2.2 <= V1.3 VER SP2.1

    PR 2.3 2.4 <= V1.3 VER SP2.2

    PR 3.1 <= V1.3 VER SP2.3

    VV 2.1 <= V1.3 VER / VAL SP1.1

    VV 2.2 <= V1.3 VER / VAL SP1.2

    VV 2.3 <= V1.3 VER SP3.1 / VAL SP2.1

    VV 3.1 <= V1.3 VER / VAL SP1.3

    VV 3.2 <= V1.3 VER SP3.2 / VAL SP2.2

    PR 1.1对工作产品进行评审并记录问题

    Perform reviews of work products and record issues.

    对工作产品进行评审并记录问题。

    Value 价值

    Improves work product quality and reduces cost and rework by uncovering issues early.

    通过尽早发现问题,提高工作产品质量,降低成本和返工。

    VV 1.1执行验证来确保需求得到实现并记录和沟通结果

    Perform verification to ensure the requirements are implemented and record and communicate results.

    从1级升到2级:同行评审案例分享

    以下例子说明, 无论是敏捷或传统开发,都可以使用一些CMMI的最佳实践,如同行评审,帮助改善质量。

    敏捷开发越来越多人谈,在杭州客户现场,刚好就有本地咨询顾问,印度CMMI评估师 和我。 印度老师 除了有20年的CMMI经验外,也是敏捷的导师。有些人误解以为敏捷就是要减轻过程,可以不需要文档,只是把开发做好便可以。

    我们在和测试人员讨论他们如何评审测试用例,他们说直接把写好的测试用例发主管,主管觉得可以就可以。其中一位评估组成员觉得不合适,另一位偏敏捷的觉得同行评审测试用例这活动没有价值,可以节省掉不做。

    印度老师说:同行评审有多个不同的形式,有些较严格,有些较省力,如发邮件去让其他人看。

    问:对不同的产物有那些不同的评审方法? 这企业就展示出在项目计划中的一个列表:

    • 需求 - 需要客户评审

    • 设计 - 需要同行评审

    • 代码 - 也是同行评审

    问:同行评审如何定义? 规定怎样做?

    这企业不同人有不同的理解,公司级也没有明确定义。

    老师接着说:如果同行评审是指审查(Inspection),代码也用正式同行评审是很理想,但可能太花人力,所以越来越多团队使用静态(代码)检查。

    评审方法有很多,常见的包括:

    1. 审查(Inspection) - 最正规,最严谨的方法,通常用于重要的产物,比如框架的设计

    2. 走查(Walkthrough) - 要求低一些,例如 一起开会,把产物投出来一起看

    3. 最简单也可以是两个人互相查看,或者发邮件

     (附件2 详细介绍 Inspection 审查)

    老师接着说:计划时也要定那些工作产品选用那种评审;例如,像以上那种只说设计/代码都是采用某种评审方法便太笼统

    他还建议需要有一个项目的质量计划 (Quality Plan),预先列出对那些阶段的那有产物采取什么方法来评审。也预定每个阶段要达到什么质量要求,如发现多少缺陷。

    例如:代码评审 - 核心的代码你可能就需要做正规的同行评审。但是如果是一些用户界面那种就简单一点,但必须要质量计划(或项目计划)里面预先定好,然后按照计划去做。

    PR 2.1开发并持续更新用于准备和执行同行评审的程序与支持材料

    Develop and keep updated procedures and supporting materials used to prepare for and perform peer reviews.

    PR 2.2选择要进行同行评审的工作产品

    Select work products to be peer reviewed.

    VV2.1 选择用于验证和确认的组件和方法

    Select components and methods for verification and validation.

     

    因为不同的评审方式,各有利弊,所以首先要定义好每一种方法,让团队可以挑选最佳配搭。 同样原因,也需要选择哪些产物要怎样评审/测试。 上面同行评审案例分享中的质量计划(Quality Plan) 便是一个例子 - 预先策划好那些产物采取什么方法来评审最合适。

    质量计划(Quality Plan)例子

    因为团队有信心采用新的代码评审方法后,可以提高代码评审的缺陷发现率,在质量计划中,代码评审的缺陷密度设定比历史数据的基线高,但是比模型预测较高的缺陷密度数低一点。

     

    Agile Tips 敏捷又如何

     

    如果我们不是按传统的瀑布式开发,没有明确的需求、设计阶段,按敏捷迭代来做,是否同行评审这种最佳实践便用不上?

    大部分的敏捷团队都有用静态检查,效率比人工评审高;但复杂的代码还是要依赖人工评审。例如:有些金融的核心模块,因算法复杂,很难单靠测试找出缺陷,必须依赖专家查看代码(评审)。

    因直接看代码,评审还是会比测试更有效率。(测试发现有缺陷,还是要看代码) 所以不要以为敏捷就不需要评审,如果你还记得较早的一种敏捷方法叫极限编程 (Extreme Programming),它提倡的结对编程(Pair Programming)就是一种评审,只是不等到写完代码才做,而是写代码时,与坐在旁边的同伴编码与评审同时进行。而不是写完代码后才评审,发现缺陷。

    目的很简单,无论评审还是测试,尽可能早做,找出缺陷。

    从批量交付到持续交付的例子:

     

    构建测试环境,端对端持续测试。

    PR 2.3使用既定程序准备和执行选定工作产品的同行评审

    Prepare and perform peer reviews on selected work products using established procedures.

    PR 2.4解决同行评审中发现的问题

    Resolve issues identified in peer reviews.

     

    技术评审(例如:代码走查、设计评审,或者需求评审)的通病是缺乏检查单,也缺乏评审记录。为什么要检查单,其实是个经验的累积,哪些问题以前常常出现,就应该变成检查项,后面的评审要注意,评审好比测试,目的是,用最短的时间,最小的力度,找出最多的问题。

    很多人说自己有做互相代码的检查,但在问有什么发现,有什么记录就记不清。

    还有就是这些缺陷如果要修改,怎么确保修改正确?没有改错?因为有可能本来没有问题,改完反而出错。

    VV 2.2开发,使用并保持更新支持验证和确认所需的环境

    Develop, keep updated, and use the environment needed to support verification and validation.

     

    大家可能都遇过因为环境不一样,有些缺陷测不出来。

    我们一个香港政府部门客户IT部门,必须所有新开发的系统在他们一个固定的标准测试环境进行验收测试,通过后才允许放到投产环境。证明稳定的测试环境很重要。

    从批量交付到持续交付的例子:

     

    确保环境稳定并持续可用。

    VV 2.3制定、保持更新并遵循验证和确认程序

    Develop, keep updated, and follow procedures for verification and validation.

    如何写好测试用例,如何做好功能或性能测试 本身是一个很大的题目,也有很多专门针对测试的书籍,尤其是自动化测试,大家可能比我更熟悉。

    3级:从定性提升到度量与分析

     

    ”没有度量,就没有管理”这话大家都赞同 但有多少软件开发公司真正的使用一些可靠数据,帮助团队持续改进? 大部分公司都用一些工具来管理缺陷,但系统地统计并利用这些数据的团队不多。

    敏捷团队度量分析例子1
    当听到数据驱动,大家可能立马想到一些包含仪表板的工具,如SonarQube和Jira:

    • 如图1所示,SonarQube关注的是代码度量:复杂性、单元测试覆盖率、重复等等。

    • 如图2所示,Jira关注的是过程度量:问题解决时间、团队速度等等。

     

    一团队实现数据驱动连续改进过程时,领导只是单看 仪表板上的新增代码行数(LOC),导致开发人员。 只为了追求这数字,想尽办法出增加这个数,而不是如何提升生产率和代码质量,最终导致整个度量分析改进计划告吹。

    所以软件分析仪表板虽然是非常有用和重要,但必须谨慎引入,而且动机要正确。如组织缺乏敏捷文化,管理层很容易以为度量程序是用来从外部“”质量和生产力,导致团队会把它理解为管理者不信任他们,反而影响了团队的动力。

    测试也一样,如果只是单一的追求开发过程中缺陷密度(或缺陷数),效果也会一样。

    例子2

    研发主管问: 我们每个开发工程师都有用静态检查查代码质量,但为什么要统计?自己依据发现问题改好是否也可以? 你不是提倡研发人员自主管理吗?

    答:理论上是可以,但实际上如果公司没有系统地统计,你估计开发工程师会主动定期记录/统计吗?

    我的老同学在深圳东莞,有一家"知识工厂",专门为国外做英文输入。例如他有一美国老客户,提供网站专门为客户寻找自己的祖宗信息,需要把大量老报纸,书籍,船票的扫描,利用人工配合电脑辅助,输入成英文文档。因为项目的利润都很薄。生产率很关键,如果生产率低项目就亏本。同样质量也很重要,错误率也要很低。

    生产场所坐满时有二三百人,很多小组组成。每小组大概十人,有组长。每个组的大长桌上面都有一显示,显示当前的生产率与错误率。管理服务器也会不断收集与统计每个小组的度量。每个小组和组长都很清楚自己组的表现。组长会尽力帮自己组提升水平。生产总经理会与各组长每天回顾成绩和如何提升。

    我说完以上故事,便继续问研发主管,如果这"知识工厂"没有系统地收集,统计与显示生产数据,只靠每小组或每个工人自我管理,可以保证项目的利润吗?

    所以回应你的提问,我估计不会,或最多统计几轮便不继续。没有度量,没有压力,我没见过你说会自动不断自我提升的‘圣人’;而且人不是机器,骨子里是很厌恶不断做一些重复性工作 - 手工收集与统计数据。

    度量分析例子3

    问研发主管:你们怎么利用缺陷的统计工具来确保产品质量?

    答:我们现在用自动检测工具,比如:静态检查 / SonarQube,可以帮我发现一些问题,当我从这些报告发现有一些错误时,就会问相关的开发人员,叫他改正。

    当我在访谈下面的开发团队时,问他们怎么利用度量数据来帮助确保质量,他们都说不出来,只是说后面会有系统测试来做检测,QA人员也会定期检查来保证质量等。

    以上例子2可看成是McGregor XY管理理论中的X型管理(家长式),团队人员是受主管指挥,而不是自己主动来利用统计数据来不断改善。如果单靠X型管理,整个团队的质量就局限于主管有多少时间来检查,而不是由团队自发依据数据持续改进。

    与一金融产品开发组长对话

     

    从以上例子我们了解度量要与团队过程改进配合,也需要系统支撑,下面我们看看当主管与高层已经意识到数据的重要性,也有系统支撑,如何完善研发的度量与分析:

    一家专门做金融产品的公司。上层对团队都有很明确的目标, 例如:

    1. 2周:需求交付周期——从想法提出并确认,到上线的时间

    2. 1周:需求开发周期——从需求设计完成到上线的时间

    3. 1小时: 测试验证时长——在集成过程中,对变更的测试验证时长

    问:你们高层有这么高的要求, 你们究竟要度量什么?

    组长答:交付吞吐率 (单位时间内交付需求数)、交付周期、开发周期,发布频率、交付后线上的缺陷数,与修复缺陷所需时间,开发过程中发现的缺陷数与排除数等。(如图)

     

     

     

     

    问: 确实很多要求。但你们还度量什么来确保可以达到以上是要求?

    组长有点迷茫地望着我,然后答:我们主要就是度量这些。

    度量与分析有一个很重要的概念——不应仅仅度量结果,也要度量那些会影响结果的因素。

    好比如果要减肥就不能每天仅仅度量体重,还要每天收集运动量与吸收了多少卡路里。

    我继续问组长:你们团队用什么方法去提高交付率,也同保持质量?

    答:把本来复杂的大模块细分成小模块,也尽量减小之间的耦合度,本来是类似瀑布性的开发,最后才集中力量测试,改成持续的迭代开发,控制每两周发布。

    问:效果如何?

    答:非常好。

    他立马在电脑展示过去六个月他们用了新方法后的结果。

    虽然这组长没有度量可控因素,但他心里很明白以下的原理:

    • 软件越复杂,质量就越难控制

    • 控制每个迭代的周期:两周。持续交付是可以提高交付率,也保证质量。

    这些最佳实践在很多成熟的国外软件团队都验证过,证明有效。

    我表扬了组长的好成绩后。便介绍他可以利用 GQM(goal-question-metric)来找出一些会影响结果的度量来帮我们更好控制结果。

    我先沿用他已有的度量:

    G: 提高交付率,也同保持质量

    Q: 程序越复杂,模块越大,越容易出问题?

    M: 度量程序的复杂度、模块的大小、耦合度,
    也度量效果:交付周期,新增缺陷/关闭缺陷,线上缺陷与问题解决时长

    一方面帮我们验证一下他的假定是否正确?另一方面,如果我们发现有些模块,复杂度高便要预警。

    因这些很可能会导致后面出现质量问题。 GQM也可以系统地帮我们把要度量的可控因素与希望结果关联。

    我接着跟他分享了我们杭州案例:

    我们很清楚如代码本身不好,肯定会影响质量与交付,所以我们一开始便培训开发团队编程,避免一些陈旧的语法, 如 if - else, for, switch - case...。代码尽量简单直接。 培训后我们便要求团队每两周度量有多少陈旧语句,测试发现缺陷多少?交付了多少新功能点,我们收集了六轮,陈旧语句迅速降低,交付与质量也逐步提升。

    我再问组长:你估计每次变更代码多少,是否也会跟缺陷有关?

    答:很可能。

    问: 你们好像也开始用静态检测。

    答: 是的

    问: 是否对提高代码质量有帮助?

    答:肯定

    问: 有没有想过也应收集这方面的数据来预测交付质量?

    我便继续与组长把所有他觉得影响也可以收集的度量列出来。

     

     

    组长问:我们定了那些度量如何收集?

    答:比如代码变了多少是可以从配置管理系统收集。当我们帮企业改善度量时,常见问题是客户没有系统收集数据,大家可以想象,人工收集是无法长期的,也很难确保数据是否正确。 直接从系统导出可避免这些问题。因你们一直用 GIT , JIRA 与 SonarQube,可考虑类似下图,定期导出数据。

     

     

    我接着说:你们一直强调要定期做复盘。以前复盘时缺少中间影响因素数据。只有结果数据。后面做复盘分析是否会更全面?

    组长答:我们过去讨论时,大家都会说很多理由。但最终选择怎么改进还是依赖那些有经验的人士说的算。我估计多了这些数据讨论会全面多了。

    我说:你们有影响因素的数据,便可以针对问题,对症下药。比如确实某些语句的问题影响到质量。便要更新编码指南,加强培训等,预防后面质量出问题。

    不仅仅有这个好处,你们不是也做了一些大数据分析,机器学习项目?当我们不断收集数据,到了一定的数量便可以用这些新的方法去量化管理。 例如预测哪个模块会缺陷较多。

    度量可控因素

     

    当我学软件工程时,数据挖掘、机器学习没有这么流行。开发的环境工具和现在不一样。那时候的预测模型,比如预测缺陷、预测工作量会用一些很主观的因素,例如团队成员经验与能力、过程成熟度、团队合作性,也有一些较客观的因素,如语言、复杂度等,但如何校正模型的参数是个难题。导致模型很难可以在不同公司使用。而且那些时候大部分项目都是传统的瀑布性开发,不一定适用于现代迭代,持续交付的开发模式。


    请不要误会,以为上面这些因素,如经验、能力不重要,这些都重要,只是非‘可控因素’(controllable factor)。对度量分析的预测作用不大,预测其中一个目的是希望我们可以在过程中凭一些过程中的指标,预测结果。例如,我们发现静态检测的缺陷数与后面发布后的产品质量,或遗漏缺陷数相关。例如,我们发现代码模块大小与复杂度与后面的质量相关,就可以在开发过程中收集这些数据来预计最终的质量,不要等到发布后才发现质量不行。

    反过来,我们很难使用团队人员经验或能力来预测/控制结果。

    除了主观判断以外,主因是这些因素难以在过程中改变,一旦发现人的能力和经验达不到要求的话,你可以在团队开发中换人吗?估计不太可能。

    所以我们更需要一些过程中的客观、可系统收集并可控的因素来预测结果。

    下面让我们看看如何对应 上 CMMI V2.0 VV PR 3.X

     

    PR 3.1分析从同行评审得到的结果和数据

    Analyze results and data from peer reviews.

    VV 3.2分析和沟通验证和确认结果

    Analyze and communicate verification and validation results.

    从上面组长对话 与“附件1 :敏捷团队如何有效利用度量数据分析”,大家可看到数据分析与有效沟通同等重要,可以互补,所以在V2.0 也加入沟通。

    VV 3.1制定、使用并保持更新验证和确认标准

    Develop, keep updated, and use criteria for verification and validation.

    当我们有历史数据支撑,知道过程中的哪些因素会影响最终目标,我们便可以更具体规定开发过程中,无论是编码,静态检查,单元测试,系统测试, 要达到什么程度。

    质量之旅

     

    质量改善绝非一步到位,CMMI “创始者”已故Humphrey先生概述以下七步“质量之旅”:

    1. 尽快开发出产品,测试,改错 (Test and Fix)

    2. 开始在测试前做检查(评审)希望尽早找出缺陷并解决 (Inspect)

    3. 开始使用一些数据来改善评审过程 (Partial measurement)

    4. 开发工程师从参与回顾,开始意识到要预先自我评审自己的产出物,减少错误(Quality ownership)

    5. 为了提升,工程师开始记录自己的引入缺陷数,排除数,产出物规模,花费时间等 (Personal measurement)

    6. 工程师完善设计方法 (Design)

    7. 度量+设计已降低了大量缺陷引入,再系统地避免缺陷,进一步提升质量(Defect prevention)

    8. 最终应度量客户重视的质量要素,驱动整体质量的持续改进 (User – based measurement)

    我们也可以利用CMMIV2.0 判断公司质量改善的成熟度 (V2.0 比以前V1.3版更明确), 从下面汇总表,大家可以看到公司验证、确认、同行评审过程改善的阶段:(也可以把下图看成一张地图,帮我们更好理解上面案例 / 例子在整个“质量之旅”中的位置)

     

     

    从上面的总表,你是否觉得你认识的软件开发公司很少处于较高成熟度? 为什么? 因公司要推行度量与分析必须:

    1. 高层要有较高的交付与质量的量化要求。因要开始团队做度量分析,开始时要有不少投入,如果没有提升压力,很多时候会半途而废。

    2. 培训与系统同样重要。单靠团队自己摸索,或依赖人手收集数据都很难成功。

    3. 沟通也非常重要:团队必须有‘以数据说话’的文化,定期分析数据做改进。

    所以当质量工程师问我,如何帮他们公司推进量化管理,我会反问她领导的主要关注点。

    如果他们都觉得已经很清楚项目的情况,不需要客观数据,无论这质量工程师如何努力都不会有什么结果。

    附件1:敏捷团队如何有效利用度量数据分析

    公司已创立了十多年,正在使用敏捷方法,但没有使用很多度量标准来监视和优化。由于复杂性增加,团队面临着越来越多解答不了的问题,包括:

    • 是否和十年前一样快速高效?

    • 如果不是,什么原因可以解释慢速度吗?

    • 如果速度确实慢了一些,那么在质量和可持续性方面有什么提升?

    • 是否应该引入或调整一些过程来改进某些方面?

    这些都是复杂问题。没有数据就很难进行有根据和建设性的讨论,也很难评估为改善这种情况而采取的任何行动的影响。

    这个案例很有趣,因为开始时,有很多历史数据可用。版本管理系统中的数据、问题跟踪服务器、代码评审平台等。 越来越多研究如何应用数据挖掘和可视化技术,从这些知识库收集数据,被称作软件分析(software analytics)。

    最终目的是帮助他们发现有价值的信息。进行沟通,最后记录并分享他们的见解。步骤:

    1. 运用目标-问题-度量(GQM, Goal-Question-Metric) 方法来决定具体的分析目标,推导出一些相关的具体问题,并定义可以用什么度量来回答这些问题。。首轮选择的目标是:评估交付的速度是如何随着时间演进。

    2. 访问公司软件数据库:版本管理系统,问题跟踪,敏捷规划工具和代码评审平台等。利用一些软件从这些库中提取数据,为建立统一的模型和 可视化准备。

    3. 然后,组织了一个研讨会,让团队讨论软件和组织的演进。为了支持这讨论,我们将一些可视化结果打印在大型纸质海报上(请参见下图),该示例显示了跨存储库的团队活动和发布的频率。此外,我们还配合一些交互式可视化投影。在工作坊中,参与者走进房间,看着可视化展示的数据,很自然地参与了小组讨论。我们观察了这些参与者,并记录下讨论要点。

    4. 我们将在数据分析过程中获得的事实见解和在研讨会中获得的观点集成在交互式报告中。我们的软件分析平台使生产交互故事成为可能,它结合了叙述和数据可视化。这些故事总是为特定的读者而写。例子:

      1. 某人想写一篇关于测试驱动开发价值的故事,并针对加入团队的新开发人员

      2. CTO 想编写一故事来支持他与管理团队的交流

      3. 某团队想编写一故事来庆祝成功采用了一个新过程,以及在质量或交付时间上的好成绩

     

    从这个实验的经验教训:

    • 数据可视化和媒体的影响:在大家参与讨论的工作坊中,墙上的海报起到了吸引参与者积极主动参与的键作用,单靠幻灯片投影绝不会达到同样的效果。以视觉形式看到过去十年发生了什么,对参与者来说也有情感方面的影响,引发更多多讨论。

    • 讲故事的形式提供了有效的方式来传达信息,有效地补充仪表板数据的不足。这两个界面的目的不同,但它们都可以构建在相同的软件分析平台上。

    附件2:Inspection审查

    • 是一种正式评审, 目的是严格与正式地识别工作产品缺陷

    • 详细检查,明确地检测和识别缺陷

    • 作者不得担任主持人,管理者通常也不允许参加,以确保公正

    • 必须正式跟踪处理所有主要缺陷

    • 系统地收集缺陷数据并存储到检查数据库,对缺陷数据进行分析,以改进产品、过程和检查过程

    Inspection 包括:

    • 验证工作产品既满足其规格要求

    • 验证工作产品是否符合适用标准

    • 识别与标准和规范的偏差

    • 收集工程数据(如,缺陷和工作数据)

    • 不检查风格问题

    虽然它需要的投入比其他评审方法高,但它最能找出缺陷。

    审查员的职责

    选择审审员:

    • 识别和描述产品或产品组件中发现的主要和次要缺陷(检查)

    • 代表不同的观点(需求、设计、开发、测试、独立测试、项目管理、质量管理等等)

    • 分配特定的评审主题以确保有效的覆盖

    • 符合特定的标准

    • 整体的一致性

    最低进入条件:

    • 产品或产品组件完整,并符合标准

    • 可用自动错误检测工具

    • 有支持类文档

    • 对于重新检查,缺陷清单上的所有项目都已解决。

    • 有训练有素的主持人和足够数量的熟练审查员

    审查准备工作

    审查组长必须确认审查人员是否已做好准备。如果没有充分准备,组长可以重新安排日期;

    审查缺陷列表;

    记录员负责记录每个主要和次要的缺陷、与位置,缺陷列表上的描述和分类。作者应该准备好回答提问。如果对某个缺陷存在异议,则应在会议结束时记录并标记为潜在缺陷。主持人负责与团队一起评审缺陷列表,以确保它的完整性和准确性。

    反馈

     

    一位总工对文章初稿的反馈:

    从三年前,我们开始用静态代码检查工具,确实有效果。但需要注意两点:误报的剔除(有些问题其实严格讲不算问题),另外,不能为了消除警告把原本的业务逻辑改坏,或者是修改导致性能降低。

    一位很熟悉银行业务的IT顾问反馈:

    很棒,通俗易通。目前在企业中的软件开发过程PR、VV的实施中存在如下困境,你看是否对您编辑稿件有触发作用。

    1. 评审缺乏专家,耗时较多,但评审出来的问题质量不高,较多的问题并未被发现,参评人员参与度不够,存在部分评审过程只是走流程或形式。

    2. 评审材料本身需准备较长时间,领导层、技术人员比较看重技术实现的结果,对于评审的关注度不够,甚至认为浪费时间。

    3. 关于度量,目前过程中的数据类型很多,但前期度量规划、分析不到位,导致数据很多,但没有有效的汇总、分析和利用。

    References

    Humphrey, Watts: TSP; Leading a Development Team
    Kasse, Tim: Practical insight into CMMI 2/e
    Liechti, O.: Beyond dashboards: on the many facets of metrics and feedback in agile organizations

     

     

    展开全文
    u011250455 2019-10-29 21:15:53
  • 十一无事,在一个同行的推荐下,读了方莹所著的《成交》这本小说。  书中所写的是一家软件公司如何运作一个新兴的项目,从开始到结尾。形象地刻画了技术和销售他们的工作、生活,还有心理(感情)。小说的着力点在...

    前段时间,我把CSDN博客的签名加上了“读过100+本经典书籍”。

    一个经常关注我CSDN博客的老乡,问我是如何做到的。

    该老乡,准确来说是前辈,该前辈买了很多技术读物却没有耐心读完,所以很想知道我是如何做到的。

     

    为啥呢?我看的大部分书并不是纯粹的技术读物,有很多都是小说、管理、软件工程等相关的,而且趣味性较强的那种。

    象《算法导论》之类的,我也只看了几章,挺惭愧的。

     

    为了培养前辈的读书习惯,我建议他首先阅读《成交》这本IT职场小说。

    这本书趣味性较强,和软件开发密切相关,但和具体技术关联又不大,代表了很多公司的现状。

     

    读这本书,主要目的其实为了逐步培养他读书的习惯,让他体会到读书,尤其是具体语言技术之外的书籍的好处,有了动力,今后更容易坚持下去。

    很感动,老乡很信任我,连夜读完了这本书,并写了一篇文章。

     

    读《成交》有感

    十一无事,在一个同行的推荐下,读了方莹所著的《成交》这本小说。

          书中所写的是一家软件公司如何运作一个新兴的项目,从开始到结尾。形象地刻画了技术和销售他们的工作、生活,还有心理(感情)。小说的着力点在市场方面:如何压价,如何竞争,如何推广...偏重于讲销售,说技术的反而不是很多(这一点,我倒是不太满意)。这本小说更像是一本通俗化的软件工程,详尽的展示了一个软件公司的方方面面,对于这行涉世未深的人,还是很有教育意义的。

          除开各种细致的心理分析,小故事的生动到位...其实讲了一个道理:金钱万能。不管是软件公司、甲方、还是竞争对手,在追求各自的利益上都是无所不用其极,在令人感到酣畅淋漓的同时又觉得毛骨悚然,社会太可怕了,一不小心就会着了别人的道,如履薄冰。作者是销售出身,换做是程序员来写,可能又是另一番味道,但肯定不会这么”血淋林“。能够读到销售笔下的软件运作模式,也的确令人大开眼界,获益匪浅,比起程序员来说,销售的世界更为复杂,他们做的才是真正的技术活。而程序员,所谓的高智商,很多时候却是死脑筋,如果没有这些销售拿下的市场,程序员的价值又该如何体现?当然要是没有程序员的”搬砖“,销售也是”巧妇难为无米之炊“,总之是谁也离不开谁。

          此外,文中还写了主人翁们的感情生活,对于这些,我也不知该如何去评论,但是对于主人翁”唐帅“为了另一个女人跟怀孕妻子离婚的行为,不敢苟同。有时候,没有选择反倒是更好,否则会让人痛苦不堪,比写代码更让人抓狂,也给了对手有机可乘的空子。人心是最琢磨不定的东西。不过这却是人性最真实的展现。

          总结一下,这本书写出了“软件工程”中比代码本身更值钱的东西:市场。没有销售就没有市场(当然没有产品也不行)。身为程序员,眼里不能只有代码,不了解市场,无法准确把握需求,不能正确判断软件的价值,就永远写不出”完美“的软件。所以,身为程序员,要学习的还有很多很多,知道的越多,需要知道的就更多,而时间却不多,还有要时刻保持”空杯“心态...

         P.S 第一次这样写文章,纠结了很长时间才憋出这点字,佩服作者的文笔,也欢迎大家多提意见。

    原文链接:http://www.cnblogs.com/OldGlory/p/3351180.html

     

    读书总结

    过去几年和最近几个月,我都写了很多读书总结。

    我觉得,看看书,写写总结很有好处,自己的思想认识、做事方法、技术积累都有了很大改进和进步。

    有兴趣的同学可以到这来看 http://blog.csdn.net/fansunion/article/category/1243633

     

    送大家一句话

    不读书,不看报,永远老一套;多读书,多看报,从此换新貌。

     

    未来打算

    我将会向大家分享一些读书的方法,自己读过的书籍列表,读书体会,当然还有一些“败笔”。

     

    原文参见:http://FansUnion.cn/articles/2666

    展开全文
    FansUnion 2013-10-04 17:08:51
  • sxhelijian 2017-07-19 08:37:43
  • weixin_35370061 2021-02-04 10:15:01
  • 1.52MB eu169 2011-11-23 15:21:12
  • sxhelijian 2014-11-28 13:54:22
  • igorzhang 2012-05-28 11:40:39
  • oHanTanYanYing 2015-10-26 20:33:18
  • yuan2019035055 2021-12-16 09:08:40
  • handong106324 2012-08-13 17:35:02
  • comeon_data 2004-10-12 12:18:00
  • andywuchuanlong 2015-03-11 08:50:49
  • weixin_34277853 2014-08-22 13:42:30
  • cheny_com 2011-02-11 15:53:00
  • vinep 2008-12-08 11:49:00
  • tiger119 2011-06-12 14:38:00
  • ardo_pass 2017-11-22 22:03:37
  • xuedengshan 2012-08-25 09:14:44
  • linxingliang 2020-04-15 08:31:26
  • chaishen10000 2019-04-25 16:53:08
  • GitChat 2017-09-08 14:19:37
  • X8i0Bev 2018-11-17 10:29:04
  • emag_se 2005-03-08 17:53:00
  • yuanmeng001 2018-11-01 23:42:41
  • yH0VLDe8VG8ep9VGe 2018-09-29 11:49:09
  • woodcorpse 2017-08-02 07:45:01

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,151
精华内容 14,860
关键字:

同行交流会