posts - 59,  comments - 323,  trackbacks - 0
  各位一定非常惊讶(如果是读过前面几篇连载《定论》的人),怎么这就完了呢?看着架势,应该还早啊。
 
  是啊,按照原定的计划呢,的确是还早,但是那样的写法,我自己都不知道会写到何年何月去了,因此打算结束这个东西,把我要表达的想法,一口气跟大家说了,也是一种解脱。
 
  总结我的想法,主要有以下几点:
 
  1、现有的软件开发方法,都不是定论,不过是你说你的好,我说我的好罢了。要能够得到定论,必须要有一种能够判断方法好坏的方法。也就是说,能够判断一个方法,用或不用,有多少好处。几个方法比较,哪个能够胜出的“检验标准”。
 
  2、要能够检验软件开发方法的优劣,必须基于对于软件开发本质的正确认识,这样才能量化两个因素:软件需求的复杂程度以及软件开发的实际工作量。而现在的软件复杂度的度量,并未区分“需求”与“实际”的不同,或者“代码行数”,或者“功能点”,都是如此。
 
  3、在能够正确度量需求复杂度与实际工作量之后,我们会发现,过去那么多号称是为了保证软件顺利开发的手段,往往只会坏事,耽误事。但是,完全不提前设计的方法,也并不可取。
posted @ 2005-11-21 23:27 读书、思考、生活 阅读(238) | 评论 (0)编辑 收藏
posted @ 2005-11-19 12:47 读书、思考、生活 阅读(295) | 评论 (0)编辑 收藏


My blog is worth $33,307.86.
How much is your blog worth?

 

网上有人贴出了直接计算的代码,在这里,填入你的Blog地址即可。


文章来源:http://spaces.msn.com/members/zbw25/Blog/cns!1pA6-3FOo9yNp_4lmEHxdDqA!722.entry
posted @ 2005-11-19 10:56 读书、思考、生活 阅读(257) | 评论 (0)编辑 收藏
  昨天看完《一九八四》了,联想到之前看过的《林昭》《兄弟》,颇有些感想。
 
  《兄弟》是最能让人动情的一部书,但是也是最感性的一部书。而对于极权主义的批判,仅仅有感性是远远不够的。这一点,《一九八四》就实在是太到位了。深刻的,理性的,不动声色的,镇定自若的分析,越读越让人感到毛骨悚然。
  一种绝对不会让你变成烈士的权力。你一定能够被改造好。你会真诚的相信,2+2=5,或者是4,是3,都有可能。每一个被送入101房间的人,都会出卖一切,出卖人类所能拥有的一切美好的事物。真、善、美、爱,全部都可以出卖。
 
  太绝望了!
 
  林昭的死,给了我信心。是的,不是让我绝望,反而是给了我信心。因为,有这样的人,在这个世界上存在过,她可以被消灭,但是不可战胜!
 
  另外推荐一篇blog,不像书评的书评。主题有点相关,但是并不直接。大多数人,既不是强者,也不是弱者,仅仅是在中间。这些在中间的人,如果他勇于欺凌弱者,也往往会非常痛快的屈服于强者。换句话说,那些在极权主义制度下,快速屈服的人们,才是迫害弱者的主力军。这样的人,实在是太多了!
posted @ 2005-11-18 22:40 读书、思考、生活 阅读(584) | 评论 (0)编辑 收藏
  讨论软件开发的特征,需要站在一个大的背景下来看。我以前考过PMP,在PMBOK中,软件项目管理,是作为项目管理下的子课题来讨论的。看看下面这张图:
  按照PMBOK的知识结构图,PMBOK已经告诉了我们那么大一个园。而要进一步搞好软件的项目管理,我们只需要再掌握相关应用领域的知识和实践,就ok了。
 
   这其实是大多数项目管理的理论,对于软件项目管理的看法,所有的项目,都是项目。软件项目与大多数其它项目,大同而小异。至于差异部分,往往被归入“风险管理”的领域,就算是“一切尽在掌握了”。
 
  而事实上,软件项目与其它项目的差异是如此之大,以至于由量变而导致了质变,使得我们以传统的工程项目管理的方式来管理软件开发项目,注定是要失败的。
 
  我们来看看这样一个关键词:“迭代”。这是其它的项目管理中,基本上不可能出现的概念,而在软件项目管理领域,却是几乎每一种方法学中,都要极力强调的概念。这就是最大的区别。如果我们能够搞清楚迭代的本质,也就能够搞清楚软件项目与其它项目的本质区别了。
 
  在我看来,在软件开发的过程中,引入迭代,就是承认,软件开发需要承受大大小小的失败,而减少失败的办法,就是不跑步,不走路,尽可能的爬行,这样就算跌倒,也不会跌得太重。我们来看一个有趣的数据。这是我在竹笋炒肉的blog上看到的一段话。
 
  1994年,由于其非凡的软件开发能力和优秀的软件质量,SEL成为第一个因软件过程的成就而赢得IEEE奖励的软件开发组织。与普通的软件开发组织相比,在同样的软件开发条件下,NASA所开发的软件的质量要好10到20倍。
 
  这个成就是如何得出的呢?那么是怎样的项目呢?我搜索了一个google,找到另外一段话
 
  To put it a little differently, the average MIS shop would need about 14 calendar months and 110 staff-months to deliver a 100,000 line-of-code MIS system, and it would typically contain about 850 defects when delivered. The NASA SEL would deliver a system of that size with about the same amount of time and effort, but it would contain only about 50 defects.
 
  也就是说,10万行代码的一个MIS系统,他们花了110个人月,一共14个月,才完成。平均下来,每个人每天大约需要写30行代码!如果这样也算成功的软件项目管理的话,我以后只要将所有的项目工作量估算,乘以10,就能同样拿到IEEE的奖励了,如果我的老板允许的话。
 
(未完待续)
posted @ 2005-11-18 08:47 读书、思考、生活 阅读(281) | 评论 (0)编辑 收藏
  最近一段时间,特别容易买书。11月5日,本来是打算给我的外甥女买一本小学生词典的,想想干脆上当当搜一下。结果发现还真是挺便宜的,会员价只要12.6,实在是不好意思,就另外挑了两本,一本《世界尽头与冷酷仙境》,一本余华的《兄弟》。但是,那该死的当当,竟然在订单完成之后的第二天,才告诉我只有一本《兄弟》。我当时就想,干脆一本都不要,反正是货到付款。
 
  结果,11月6日那天下班回到家里,我爸妈跟我说:“你买的书来了,钱已经帮你付掉了。”效率真是高的不得了啊!
 
  《兄弟》我一口气就看完了,实在是好看啊!
 
  11月9日,一帮老朋友聚会,还去了一个朋友的家里,他们家也是喜欢读书的,我在那里又发现几本好书,结果呢,借不成
 
  因为对当当送书的速度印象相当深刻,于是还是去当当又订了三本书《非常道》、《杨柳风》、《一九八四》。当当还是以非常迅速的速度,分两次,给我送来了。他们这样做,唯一的目的是,能够收我两次的送货费。值得庆幸的是,书的确是不错。《非常道》我已经看完了,现在在看《一九八四》。
 
  我之前写过一篇关于林昭的blog。因此而认识了一个朋友,他也是林昭的老乡,苏州人。看到我这么喜欢林昭,于是说要送一本林昭的书给我,今天,书又寄到家里来了。《追寻林昭》,另外还有一本他们出版社的《挡不住的趋势》。
 
  今天早上,我还在蔚蓝书店订了三本书。《随想录》、《人类群星闪耀的时刻》、《断头王后》。然后呢,今天还收到一封邮件,我邮购的一本《读库0600》也已经寄出来了。
 
  唉,实在是太多了一点,来不及看啊。俗话说:书籍是人类的朋友。又说:有朋自远方来,不亦乐乎。所以,有好书自远方来,不亦乐乎!
 
 
还有一本,属于“地下刊物”,只能搞到很大的照片。
 
这本书的介绍,可以去看这个blog:见招拆招
posted @ 2005-11-15 21:32 读书、思考、生活 阅读(354) | 评论 (0)编辑 收藏

  我是豆瓣的会员,又用的是MSN Spaces的BLOG,目前用得还不错,都不打算退出。但是豆瓣提供的那个豆瓣秀服务,在MSN Spaces上用不成

  没办法,只能自己动手了。实际效果,见:http://spaces.msn.com/members/zbw25/

  1、搞一个Custom HTML
  2、在公司的服务器上,装一个软件,ImageMagick。下载地址:http://www.imagemagick.org/download/binaries/ImageMagick-6.2.5-4-Q16-windows-dll.exe

  3、下载一个JMagick。下载地址:
http://www.yeo.id.au/jmagick/quickload/win-6.2.4/jmagick-6.2.4-1-IM-6.2.5.zip

  4、将dll文件,copy到Windows的System32目录下。将jar文件copy到某lib目录下。

  5、写一个Servlet,代码如下:

  1 package tv.recool.misc;
  2 
  3 import java.io.*;
  4 import java.text.*;
  5 import java.util.*;
  6 import javax.servlet.*;
  7 import javax.servlet.http.*;
  8 import java.net.MalformedURLException;
  9 import java.net.URL;
 10 import java.net.URLConnection;
 11 
 12 import magick.ImageInfo;
 13 import magick.MagickImage;
 14 import magick.MontageInfo;
 15 
 16 public class PutBooks extends HttpServlet {
 17 
 18     //根据url,取得图片的byte[]
 19     private static byte[] getImageBytes(String url){
 20         try {
 21             return StreamUtils.read((new URL(url)).openStream());
 22         } catch (Exception e) {
 23             return null;
 24         }
 25     }
 26     
 27     //根据url,取得文字
 28     private static String getImageText(String url){
 29         try {
 30             URL u=new URL(url);
 31             URLConnection uc=u.openConnection();
 32 
 33             //要做足功夫,不然豆瓣就会拒绝你的请求
 34             uc.setRequestProperty("Host","www.douban.com");
 35             uc.setRequestProperty("Accept","*/*");
 36             uc.setRequestProperty("Referer","http://www.douban.com/");
 37             uc.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)");
 38             uc.setRequestProperty("Pragma","no-cache");
 39             uc.setRequestProperty("Cache-Control","no-cache");
 40             uc.setRequestProperty("Connection","close");
 41 
 42             //StreamUtils是一个辅助工具,就不再给出了
 43             return new String(StreamUtils.read(uc.getInputStream()),"utf-8");
 44         }  catch (Exception e) {
 45             return "";
 46         }
 47     }
 48 
 49     public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{
 50         //取得参数
 51         String uid=req.getParameter("uid");
 52         String n=req.getParameter("n");
 53         String columns=req.getParameter("columns");
 54         String select=req.getParameter("select");
 55         String picsize=req.getParameter("picsize")+"";
 56         String show=req.getParameter("show");        
 57 
 58         try {
 59             //设置JMagick的ClassLoader,否则会报错
 60             System.setProperty("jmagick.systemclassloader","no");
 61 
 62             String str= getImageText("http://www.douban.com/service/badge/"+
 63                 uid+"/?show="+show
 64                 +"&select="+select
 65                 +"&n="+n
 66                 +"&picsize="+picsize
 67                 +"&columns="+columns);
 68 
 69             int getSize=Integer.parseInt(n);
 70             int colSize=Integer.parseInt(columns);
 71             int len=getSize/colSize;
 72 
 73             //申请一个数组
 74             MagickImage images[] = new MagickImage[getSize];
 75 
 76             //用最简单的办法解析字符串,因为豆瓣的输出是固定的
 77             String imgstr[]=str.split(".jpg");
 78 
 79             for(int i=0;i<getSize;i++){
 80                 if(i<imgstr.length){
 81                     String picurl="";
 82 
 83                     //根据图片大小的设定,解析有所不同
 84                     if(picsize.equals("medium")){
 85                         String temps[]=imgstr[i].split("http://www.douban.com/mpic/");
 86                         picurl="http://www.douban.com/mpic/"+temps[1]+".jpg";
 87                     } else {
 88                         String temps[]=imgstr[i].split("http://www.douban.com/spic/");
 89                         picurl="http://www.douban.com/spic/"+temps[1]+".jpg";
 90                     }
 91                     MagickImage image = new MagickImage(new ImageInfo(),getImageBytes(picurl));
 92                     images[i]=image;
 93                 }
 94             }
 95 
 96             //建立一个图片组
 97             MagickImage seqImage = new MagickImage(images);
 98 
 99             //建立一个图片框架
100             MontageInfo montageInfo = new MontageInfo(new ImageInfo());
101 
102             //setGeometry(String)设置图片的几何特征
103             if(picsize.equals("medium")){
104                 montageInfo.setGeometry("99x149+1+1>");
105             } else {
106                 montageInfo.setGeometry("66x99+1+1>");
107             }
108 
109             //NxM的一个表格
110             montageInfo.setTile(colSize+"x"+len);
111             montageInfo.setBorderWidth(0);
112 
113             //得到一张组合后的图片
114             MagickImage montage = seqImage.montageImages(montageInfo);
115             montage.writeImage(new ImageInfo());
116             montage.setMagick("JPG");
117 
118             //输出到byte[]
119             byte data[]=montage.imageToBlob(new ImageInfo());
120 
121             //通过Servlet输出
122             res.setContentType("image/*");
123             OutputStream toClient=res.getOutputStream();
124             toClient.write(data);
125             toClient.close();
126         }
127         catch (Exception ex) {
128         }
129     }
130 }


  6、在MSN Spaces的Custom HTML中,写以下HTML:

<href="http://www.douban.com/people/1019112/"><img src="http://www.recool.tv:8080/Recool-WebServer/putBooks?uid=1019112&show=collection&select=random&n=12&columns=3" border=0 width=178></a>

  7、搞定,收工。

posted @ 2005-11-14 21:20 读书、思考、生活 阅读(1237) | 评论 (2)编辑 收藏
新家注册成功,特此告示。
posted @ 2005-11-14 15:25 读书、思考、生活 阅读(143) | 评论 (0)编辑 收藏
  昨天我老婆也看完了余华的《兄弟》,突然想到儿子的发展趋势,我们两个人讨论了一下,认为如果宋凡平不死的话,李光头也不至于那么堕落。所以我们的儿子就算不能成为宋钢,起码也不至于成为李光头吧。
 
  家里请了一个钟点工阿姨,每天4点来,6点走。一般快到6点的时候,点点就会一直头转来转去的盯着阿姨看。那意思是,阿姨你怎么还不走呀?我好跟你说再见呀。
 
  今天快到点的时候,我儿子也是一直盯着阿姨看。看到阿姨走到门口,弯腰下去穿鞋,裤子的腰比较低。然后我儿子就笑起来了:“阿姨的屁股都露出来了。”
 
  点点、爷爷、还有我,我们三个男的都面无表情的坐在那里。奶奶一个人在那里狂笑。阿姨的脸通红。我心里在想:“完了,家里真的出了‘李光头’了。”
 
 

文章来源:http://spaces.msn.com/members/zbw25/Blog/cns!1pA6-3FOo9yNp_4lmEHxdDqA!701.entry
posted @ 2005-11-11 21:56 读书、思考、生活 阅读(139) | 评论 (0)编辑 收藏
三、软件开发的特征
 
  软件开发究竟是怎么一回事呢?在我的前一个连载《敲响OO时代的丧钟》里,我也讨论到了软件开发的实质,自己引一段来用用。 
软件开发的定义:“软件开发,就是在一个受到限制的环境中,利用环境提供的可能性,修改或添加环境允许的各种状态,去满足某一组需求。

1) 软件开发所处的环境,不仅仅是一个限制,同时也是一个可能性。软件的能力,局限性与硬件的能力,比如说,如果计算机没有喇叭,那么任何软件都不能使计算机播放音乐。但是,另一个必须考虑的方面是,同样有能力发声的计算机,要想使他播放音乐,可能很容易,也可能很困难。用专业一点话来描述就是:“有些硬件的API设计很合理,有些则非常愚蠢。”由于我们对于软、硬件的定义是一个连续体,因此,这个观点不只是可以用来评价硬件API设计,也可以用来评价语言、虚拟机、框架、平台等等软件的一个方面的优缺点——是否有利于二次开发,这是一个重要的评价标准。

2) 修改、添加状态,比较拗口,其实就是编程的意思。在一个受限制的范围内编程,我们需要考虑很多东西,语法、接口、规范、内存大小诸如此类,当然,不同级别的,不同领域的编程,需要考虑的限制是有巨大差别的。软件开发的水平高低也就体现在,满足同样的需求,有些方法速度更快,有些方面却要慢很多。而软件开发的方法的选择,受到很多因素的影响:环境限制,经验多少以及对于需求的了解程度等等。

3) 满足需求,是啊!提起这个需求,每一个程序员都会有好多的苦水要倒出来。为什么满足需求就这么难呢?因为,对于程序员来说,那是另外一个世界(这是比较客气的说法),那些提需求的家伙根本不懂怎么说话(这个说法稍为激烈一些),那是一些不知道自己要什么的蠢货(你遇到过这样的用户吗?)作为程序员,我知道我有很多同行,非常苦恼于与客户谈需求这样的任务——“至少电脑不会出现前后矛盾的逻辑错误”——这就是做程序员的难处。如果我们不仅仅是抱怨的话,也必须承认,程序员是非常挑战的职业,一个好的程序员,不但得是软件开发领域的专家,还得是他开发的那一类软件所在领域的专家。但事实上,其他行业的人,只需要做一种专家就能够混得很好了。

  软件开发的实质,与软件开发的特征之间,还是有区别的。毕竟我的前一篇文章,是从技术的角度出发来看软件开发,而现在我们的要讨论的是从管理的角度来看待,它又有哪些特征呢?

  软件开发的管理特征,在外行看来,也就是一堆人在做个东西。但是,软件开发的独特之处就在于,软件开发是由一堆独特的人,以独特的方式,做独特的东西。我们先来看看软件开发,遇到了哪些独特的困难:

 

  1、沟通困难:同为软件开发,可能面对的思维模式,是完全不同的世界。比如二进制的世界,函数的世界、逻辑的世界、过程的世界、对象的世界、二维表的世界等等等等。在这些不同的世界中开发软件,需要的思考方式、思维习惯都是不同的。开发项目大到一定程度以后,不同的世界必须在一个完整的项目中和谐并存,这些差异,有时候就会带来沟通障碍。再加上技术与需求世界之间的差异,沟通成为一个非常重要的工作。软件开发中的人与事,如何才能有效沟通,是一个非常重大的课题。

  2、控制困难:程序员都是些怪人,至少都是些聪明人。要让他们听话,很难啊。一个项目,要想顺利进行,程序员们能够接受的,必须是“稳定而合理的命令”。而在软件开发过程中,往往需求频繁变动,领导层层叠叠,用户花样百出,计划一改再改。程序员们经常会接到朝令夕改的命令,而且还来自于那些莫名其妙,连说话的逻辑都成问题的家伙。如何才能知道,那些小伙子是在严格地执行命令而不是在那里磨洋工呢?

  3、评价困难:要控制,必须要能够赏善罚恶,但是在软件开发中,何为善?何为恶?如何评价一个程序员的工作?我们当然可以在项目计划该结束的时候,再去问他们,做完了吗?但是如果他们那时候没有完成,再要挽救就来不及了。必须在项目开发过程中建立即使有效的反馈机制。以小而高密度的评价手段,来对开发过程进行较为准确的控制,这一切,都必须建立在合理的评价机制的基础上。但是,这样一套评价机制,非常困难。什么才算是好的需求分析?好的代码?好的设计?好的测试用例?没有定论。举个例子:两三年前,在项目中加入EJB的成分,越多越好。现在呢?设计人员,随时都可能被人指责滥用EJB。这风向变得也太快了。

  4、估算困难:这个在上一章我们也讨论到了,软件开发与其它行业的一个重大区别,就在于对于软件开发的估算成本,不能忽略不计。想要估算变动剧烈的项目的时间、人力、成本,简直就是不可能的任务。

 

  怎么办?

 

(未完待续)


文章来源:http://spaces.msn.com/members/zbw25/Blog/cns!1pA6-3FOo9yNp_4lmEHxdDqA!693.entry
posted @ 2005-11-11 08:55 读书、思考、生活 阅读(185) | 评论 (0)编辑 收藏
仅列出标题
共6页: 上一页 1 2 3 4 5 6 下一页 
<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿(20)

随笔档案

友情BLOG

搜索

  •  

最新评论

阅读排行榜

评论排行榜