MrYang's Blog

星期六, 四月 29, 2006

关于“石头汤(Stone Soup)”

近日在读《程序员修炼之道》一书时,读到这样的故事,很有些意思,故事大概如下:

  三个士兵从战场返回家乡,在路上饿了。他们看见前面有村庄,就来了精神——他们相信村民会给他们一顿饭吃。但当他们到了哪里,去发现门紧锁,窗户也关着。经历了多年战乱,村民们粮食匮乏,并把他们仅有的一点粮食藏了起来。

  士兵们并未气妥,他们开始煮一锅水,小心地把三块石头放进去,吃惊的村民们走出来看望着他们。

  “这是石头汤。”士兵们解释说。“就放石头吗?”村民们问。“一点没错——但有人说加一些胡萝卜味道更好……”一个村民跑开了,又很快带着他储藏的一篮胡萝卜跑回来。
  几分钟之后,村民们又问:“就是这些了吗?”

  “哦,”士兵说:“几个土豆会让汤更实在。”又一个村民跑开了。

  接下来的一小时,士兵们列举了更多让汤更加鲜美的配料:牛肉、韭菜、盐,还有香菜。每次都回又一个不同的村民跑回去搜寻自己的私人储藏品。

  最后他们煮出了一大锅热气腾腾的汤。士兵们拿掉石头,和所有村民一起享用了一顿美餐,这是几个月以来他们所有人第一次吃饱饭。

  看完后,又在Google搜了一下,发现这个故事还有其他的版本,比如有的说是一个乞丐到了一个地主家使用了该方法,有的有说是一群小孩中的一个小孩使用了该方法,不管什么样的版本,故事的大概都查不都,不过我更喜欢这本书上的版本,因为在里面一直都有一种相互合作的氛围,实际上团队软件开发也是这样,团队中需要有个催化剂来提高队员的协作能力,而上面的士兵就充当了这个催化剂,只要团队协作效果好,最后每个人都是赢家。

  当然,每个故事在不同的情形下都有自己不同的寓意,对于读到这则故事的你,得到些收获了吗?

最后在附上该故事的英文版:
The Story of Stone Soup

Once upon a time, somewhere in post-war Eastern Europe, there was a great famine in which people jealously hoarded whatever food they could find, hiding it even from their friends and neighbors. One day a wandering soldier came into a village and began asking questions as if he planned to stay for the night.

"There's not a bite to eat in the whole province," he was told. "Better keep moving on."

"Oh, I have everything I need," he said. "In fact, I was thinking of making some stone soup to share with all of you." He pulled an iron cauldron from his wagon, filled it with water, and built a fire under it. Then, with great ceremony, he drew an ordinary-looking stone from a velvet bag and dropped it into the water.

By now, hearing the rumor of food, most of the villagers had come to the square or watched from their windows. As the soldier sniffed the "broth" and licked his lips in anticipation, hunger began to overcome their skepticism.

"Ahh," the soldier said to himself rather loudly, "I do like a tasty stone soup. Of course, stone soup with cabbage -- that's hard to beat."

Soon a villager approached hesitantly, holding a cabbage he'd retrieved from its hiding place, and added it to the pot. "Capital!" cried the soldier. "You know, I once had stone soup with cabbage and a bit of salt beef as well, and it was fit for a king."

The village butcher managed to find some salt beef . . . and so it went, through potatoes, onions, carrots, mushrooms, and so on, until there was indeed a delicious meal for all. The villagers offered the soldier a great deal of money for the magic stone, but he refused to sell and traveled on the next day. The moral is that by working together, with everyone contributing what they can, a greater good is achieved.

星期日, 四月 23, 2006

《Google成功的七堂课》读后


去年年底买的书,前几天才读完,实际上是前几天才真正开始读的,读完后只感觉读得太晚了,应该早点读到此书。
  此书为台湾自由撰稿人罗耀宗所著,通过七个方面来介绍了问世才6年的Goole搜寻引擎,是如何掀起全球的“搜索”热,成了网络搜索的同义词,不但击败业务琳琅满目的雅虎,进而严重威胁软件业霸主微软。

  这七堂课分别为:

  • 屡屡打破规则,标新立异
  • 以更好的产品,后来居上
  • 拿整个世界当实验室,精益求精
  • 时时以顾客的体验为念
  • 因为分享,所以成功
  • 想方设法吸引顶尖的员工
  • 不使坏也能赚大钱
   整本书给我影响最深的是Google那些常常打破常规,标新立异的勇气,以及在产品设计中时时为顾客的体验为中心,在网络上充斥着以色情、暴力与无休止 的弹出广告来赢利今天,仍然不使坏的做法,都给我留下了深刻的影响。这也使得我在重新规划和设计“学生心理在线”的时候,更多的考虑到了这几个方面的因 素,同时在设计其他软件的时候也受益不少。

  其中,记忆犹新的一个例子是Google招人的广告。Google为了招到最优秀的人才,打出的招聘广告。广告很简单,白底黑字,巨大的看板广告,而且是在硅谷心脏地带的101公路车道旁,上面只有一行字:{e重复出现的第一个十位数指数}.com
   很多人看到这个广告都模不着头脑,不知道这是什么广告,实际上这是一个网址,只不过你要找出“e重复出现的第一个十位数指数”,在加上后面的.com, 就得到一个网址,通过这个网址可以登录到一个网站。如果你找到了这个网址,那么你过了第一关,在进了这个网站后,是第二关的开始,这又是一道数学题:
f(1)=7182818284
f(2)=8182845904
f(3)=8747135266
f(4)=7427466391
f(5)=__________

  如果你找到了f(5)的答案,那么这就是登录www.Linux.org的密码,登录后就会弹出Google Labs的邀请函。

  这就是Google,里面还有很多有趣的故事,如果你感兴趣,不妨看看。



星期一, 四月 17, 2006

AJax的开发步骤--XMLHttpRequest 对象

XMLHttpRequest对象简介
  XMLHttpRequest对象在我看来是AJax的核心, XMLHttpRequest 是XMLHTTP 组件的对象,通过这个对象,AJAX 可以像桌面应用程序一样只同服务器进行数据层面的交换,而不用每次都刷新界面,也不用每次将数据处理的工作都交给服务器来做;这样既减轻了服务器负担又加 快了响应速度、缩短了用户等待的时间。

  IE5.0 开始,开发人员可以在Web 页面内部使用XMLHTTP ActiveX 组件扩展自身的功能,不用从当前的Web 页面导航就可以直接传输数据到服务器或者从服务器接收数据。,Mozilla1.0 以及NetScape7 则是创建继承XML 的代理类XMLHttpRequest;对于大多数情况,XMLHttpRequest 对象和XMLHTTP 组件很相似,方法和属性类似,只是部分属性不同。

XMLHttpRequest对象的方法:


XMLHttpRequest对象的属性:


AJAX开发步骤(框架)
  AJAX 实质上也是遵循Request/Server 模式,所以这个框架基本的流程也是:对象初始化->发送请求->服务器接收->服务器返回->客户端接收->修改客户端页面内容。只不过这个过程是异步的。

A、初始化对象并发出XMLHttpRequest 请求
  为了让Javascript 可以向服务器发送HTTP 请求,必须使用XMLHttpRequest 对象。使用之前,要先将XMLHttpRequest 对象实例化。之前说过,各个浏览器对这个实例化过程实现不同。IE 以ActiveX 控件的形式提供,而Mozilla 等浏览器则直接以XMLHttpRequest 类的形式提供。为了让编写的程序能够跨浏览器运行,要这样写:

if (window.XMLHttpRequest) { // Mozilla, Safari, ...
http_request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
http_request = new ActiveXObject("Microsoft.XMLHTTP");
}

  有些版本的Mozilla 浏览器处理服务器返回的未包含XML mime-type 头部信息的内容时会出错。因此,要确保返回的内容包含text/xml 信息。

http_request = new XMLHttpRequest();
http_request.overrideMimeType('text/xml');


B、指定响应处理函数

  接下来要指定当服务器返回信息时客户端的处理方式。只要将相应的处理函数名称赋给XMLHttpRequest 对象的onreadystatechange 属性就可以了。比如:

http_request.onreadystatechange = processRequest;


  需要指出的时,这个函数名称不加括号,不指定参数。也可以用Javascript 即时定义函数的方式定义响应函数。比如:

http_request.onreadystatechange = function() {};


C、发出HTTP 请求
  指定响应处理函数之后, 就可以向服务器发出HTTP 请求了。这一步调用XMLHttpRequest 对象的open 和send 方法。

http_request.open('GET', 'http://www.example.org/some.file', true);
http_request.send(null);


  open 的第一个参数是HTTP 请求的方法,为Get、Post 或者Head。
  open 的第二个参数是目标URL。基于安全考虑,这个URL 只能是同网域的,否则会提示“没有权限”的错误。这个URL 可以是任何的URL,包括需要服务器解释执行的页面,不仅仅是静态页面。目标URL 处理请求XMLHttpRequest 请求则跟处理普通的HTTP 请求一样,比如JSP 可以用request.getParameter(“”)或者request.getAttribute(“”)来取得URL 参数值。
  open 的第三个参数只是指定在等待服务器返回信息的时间内是否继续执行下面的代码。如果为True,则不会继续执行,直到服务器返回信息。默认为True。
  按照顺序,open 调用完毕之后要调用send 方法。send 的参数如果是以Post 方式发出的话,可以是任何想传给服务器的内容。不过,跟form 一样,如果要传文件或者Post 内容给服务器,必须先调用setRequestHeader 方法,修改MIME 类别。如下:

http_request.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”);


D、处理服务器返回的信息
  在第二步我们已经指定了响应处理函数,这一步,来看看这个响应处理函数都应该做什么。
  首先,它要检查XMLHttpRequest 对象的readyState 值,判断请求目前的状态。参照前文的属性表可以知道,readyState 值为4 的时候,代表服务器已经传回所有的信息,可以开始处理信息并更新页面内容了。如下:

if (http_request.readyState == 4) {
// 信息已经返回,可以开始处理
} else {
// 信息还没有返回,等待
}


  服务器返回信息后,还需要判断返回的HTTP状态码,确定返回的页面没有错误。所有的状态码都可以在W3C的官方网站上查到。其中,200 代表页面正常。

if (http_request.status == 200) {
// 页面正常,可以开始处理信息
} else {
// 页面有问题
}


  XMLHttpRequest 对成功返回的信息有两种处理方式:
  responseText:将传回的信息当字符串使用;
  responseXML:将传回的信息当XML 文档使用,可以用DOM 处理。
E、一个初步的开发框架
  总结上面的步骤,我们整理出一个初步的可用的开发框架,供以后调用;这里,将服务器返回的信息用window.alert 以字符串的形式显示出来:

< script language="javascript">
var http_request = false;
function send_request(url) {//初始化、指定处理函数、发送请求的函数
http_request = false;
//开始初始化XMLHttpRequest 对象
if(window.XMLHttpRequest) { //Mozilla 浏览器
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {//设置MiME 类别
http_request.overrideMimeType("text/xml");
}
}
else if (window.ActiveXObject) { // IE 浏览器
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) { // 异常,创建对象实例失败
window.alert("不能创建XMLHttpRequest 对象实例.");
return false;
}
http_request.onreadystatechange = processRequest;
// 确定发送请求的方式和URL 以及是否同步执行下段代码
http_request.open("GET", url, true);
http_request.send(null);
}
// 处理返回信息的函数
function processRequest() {
if (http_request.readyState == 4) { // 判断对象状态
if (http_request.status == 200) { // 信息已经成功返回,开始处理信息
alert(http_request.responseText);
} else { //页面不正常
alert("您所请求的页面有异常。");
}
}
}
< /script>

财务处的程序告一段落了

  花了半个多月的时间为财务处写的程序,终于交付测试了,现在想起来,实际上也是很容易的程序,只是在这期间需求出现了很多问题,所以用了这么长时间。
  程序的整个功能就是登记职工的所有个人收入,同时记税,外加汇总,这里面难度大一点的是税收的计算,在税收计算方法不太完全的情况下,难度就更大了。不管怎么说,还是完成了。
  这一次程序设计中收获最大就是整个设计按照Web标准来做,将内容和表现彻底分开,同时也把模块之间的独立性加强了,这样后期维护就容易多了。这些在以前的程序开发中使用的很少,更准确的说以前的程序开发都是为了能按时完成任务和功能,从标准和技术上考虑的很少。
  这个记帐程序刚开是的时候有人建议使用C/S模式,但对我来说,更快的还是B/S,毕竟有这么多的有点,早期时候也用VB为银行的一部门写过记帐程序,花了不少的时间,可是效果却不明显,因此,这次就换了中方式。在第一次为领导演示时,领导也问为何不用JSP?实际上也不是不可以,但是在时间很短的情况下,我还是选择了ASP,更何况也只是在他们内部使用。实际上在很早的时候就看过一本书,我觉得说得很有道理,在项目的开发中,利用新技术并不一定能很快的按时的完成,选择一种你最熟悉的,又能很快完成项目的技术时很好的选择,正是这样。
  不管怎么说,这个程序告一段落了,虽然以后可能还要修改。

下面是一些截图:





星期一, 四月 10, 2006

DIV+CSS实现菜单特效

  DIV+CSS可以实现很多的页面效果,一下的代码就是利用DIV+CSS实现的菜单效果,当鼠标经过菜单链接时,菜单的页面背景会变化,这里需要两张图片,一张是链接时菜单的背景,另一张是鼠标经过时的图片,当然也可以使用背景颜色,我这里使用的带上圆角的背景图片。效果如下:
具体代码如下:
CSS代码

#topmenu {
height: 30px;
width: 500px;
margin: 0px;
clear: both;
}

#topmenulist{
width: 100%;
margin:0 0 0 6px;
padding: 0;
text-align: center;
}

#topmenulist ul, #topmenulist li{
margin: 0;
padding: 0;
display: inline;
list-style-type: none;
border: 0px none;
}

#topmenulist a:link, #topmenulist a:visited{
float: left;
line-height:14px;
font-size: 15px;
font-weight: bold;
margin: 0;
text-decoration: none;
color: #ffffff;
background-image: url(topmenubg.jpg);
padding: 7px 15px 5px 17px;
}

#topmenulist a:hover{
float: left;
line-height:14px;
font-size: 15px;
font-weight: bold;
margin: 0;
text-decoration: none;
color: #9c9a9c;
background-image: url(topmenubgblank.jpg);
padding: 7px 15px 5px 17px;
}




星期六, 四月 08, 2006

两个页面效果技巧

一个早上,终于完成了一个组合查询,有了这个基础,后面的组合查询就方便多了。
这里有两个Javascript页面效果的技巧,是在我的程序中使用到的:

1、在输入框中敲Enter,直接跳转到下一个输入框
实现这个功能实际上是将Enter转换成了Tab,这样就会实现顺序的跳转,但是必须要检测到现在敲的是Enter,在Javascript中有KeyDown事件,可以用来监测键盘事件,代码如下:

< script language="javascript">
function checkenter()
{
if(event.keyCode==13) //Enter的编码是13
event.keyCode=9; //Tab的编码是9
}
< /script>


在文本框的地方启用KeyDown事件调用checkenter()
< input name="employeename" type="text" id="employeename" size="10" maxlength="10" onkeydown="checkenter();" />
此代码只在IE浏览器内有效,Firefox和Opera无效。

2、鼠标经过表格的单元格或行时,背景颜色变化
这个是比较简单的,代码如下:
行的背景变化:
< tr onmouseover="this.bgColor='#eeeeee';" onmouseout="this.bgColor='#ffffff';">
单元格的背景变化:

整个表格的背景变化:
< table onmouseover="this.bgColor='#eeeeee';" onmouseout="this.bgColor='#ffffff';">

星期五, 四月 07, 2006

ASP访问Excel文件

很长时间没有象这几天这样集中精力来写代码了,写代码中遇到了这样的问题,需要把Excel文件的内容读出来,显示出来,查找了一下资料,解决方法如下:
实际上只要把Excel文件当作数据库,里面的Sheet当作数据库中的表来操作就可以,不同的只是驱动程序不一样,具体代码如下:

set excelconn=server.createobject("adodb.connection")
strAddr = Server.MapPath("uploaddata/testdata.xls") 'Excel源文件
Response.Write "源文件:"&strAddr&"
"
excelconn.open "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" & strAddr ‘打开此文件

'建立excel记录集
set excelrs=server.createobject("adodb.recordset")

sql="select * from [Sheet1$]" '查询
excelrs.open sql,excelconn,1,1
While not excelrs.Eof
Response.write excelrs(0) &","&excelrs(1) &","& excelrs(2) &","& excelrs(3)&"
"
excelrs.Movenext
wend
excelrs.close()
set excelrs=nothing
excelconn.Close()
set excelconn=nothing

星期日, 四月 02, 2006

页面加载时让光标聚焦默认的地方

  这个方法有一定的实用性,特别是在反复录入数据的情况下,比如,一个页面需要反复的录入用户数据,当前一个用户数据提交后,在输入下一个用户数据时,光标会自动聚焦到默认的输入框里,就省去了使用鼠标的过程,提高用户的处理速度和软件的方便性。
  这个问题只需要使用JavaScript中的对象事件focus就可以实现了。具体的代码如下:
首先是聚焦代码,这里将光标聚焦到默认的employeeid输入框中:
< script language="javascript">
function auto_focus()
{
if(document.getElementById('employeeid')!=null) //首先检查employeeid对象是否存在
document.employeeadd.employeeid.focus(); //将光标聚焦
}
< /script>


在body标签中调用该函数,也就是让页面加载时调用该函数:
< body onload="javascript:auto_focus()">
输入框页面代码:
< form id="employeeadd" name="employeeadd" method="post" action="addemployee.asp">
工号:< input name="employeeid" type="text" id="employeeid" size="6" maxlength="6" />
< /form>< /span>