loveispopular

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  9 随笔 :: 0 文章 :: 0 评论 :: 0 Trackbacks

2008年11月25日 #

需求分析
需求分析在整个开发过程中占的工作量不大,但是产生的影响巨大(这又是一个二八原理的例子)。既然需求分析如此重要,照理说应该安排最强的人来搞。但实际情况往往不是如此:很多公司负责需求分析的人并不胜任这项工作。我经历过几个不太成功的项目,其问题的根源都和需求分析有关。
需求分析最要紧的是:搞清楚用户到底想要什么?如果这个问题搞错了、搞偏了,后面的步骤做得再好也是白搭(比如客户想要一个文本编辑器,结果你搞了个图形编辑器给他)。这方面其实有很多的道道,限于篇幅就不展开了,大伙儿如果有兴趣,以后可以单独说一下。
在搞清楚“用户想要什么”之后,接着要整理出功能列表(也有叫Feature List),并筛选出大约20%的重点功能。这个步骤是我今天主要想介绍的,因为这个步骤和后续的各项开发密切相关。一般来说,功能筛选的依据有如下几个:
1、用户经常用的功能(比如save、copy、cut、paste)
2、宣传的卖点(要能够超出同类软件,吸引眼球)
3、和用户利益密切相关的功能(这种功能不允许出错,比如存盘功能)
这个筛选的过程要尽早完成,而且最好是产品人员、开发人员、测试人员三方的头头一起讨论,以保证立场客观、观点全面。筛选出重要功能点后,其他人员的工作安排要"以重点功能为纲",有所侧重。

●项目管理
如果你是个项目经理,在排项目计划时,就得尽量优先安排重点功能的开发/测试,而且要安排能力强的人员来完成。按照我以前的做法,重点功能排计划至少得留出1/3的时间余量,以防万一(事实证明,几乎每个稍大点的项目都会出现万一)。至于重点功能,尽量排到后面,安排能力一般的人开发/测试。
然后,在项目进行过程中,肯定要有定期的例会。作为项目经理,你应该主要关注重点功能的进度情况和风险情况。
一旦项目有延期的风险,就从重点功能开始裁减(俗称砍功能)。由于是裁减重点功能,不至于产生致命的影响。

●设计界面
设计界面时,你得保证所有的常用功能都放在显著的位置(比如工具条);还得保证它们用起来方便(比如提供快捷键和右键菜单支持)。
对于卖点,它不一定是常用功能,它的目的是激起用户的购买欲望和使用欲望。因此你要把它们设计得比较酷,有噱头。
对于利益相关的功能,大部分情况下都是侧重于业务逻辑实现。如果它既不是常用功能、也不是卖点,那么界面设计方面倒不一定要额外花大力气。
其它的重点功能,只要按照常规方法设计,不用花太大精力。

●编写代码
我发现很多开发人员有几个通病:先做有趣或容易的功能,然后再做无聊或者繁琐的功能;对自己有兴趣的功能投入精力多,对自己没兴趣的简单应付。
以上这些都是开发的大忌。作为一个职业的开发人员,不应该以自己的兴趣和喜好来决定开发的轻重缓急。正确做法应该如下:
你首先得用主要精力完成上述所说的重点功能,而且要保证它们的代码质量尽可能好,尽可能方便维护(重点功能往往是经常有需求变更,经常被修改的)。
对于重点功能中的“常用功能”,要保证时间性能够好(能快速响应)。对于"用户利益相关的功能",要保证bug尽可能少(尤其是安全性、稳定性、健壮性的bug)。
至于其它的重点功能,只要不出明显bug,有点小缺陷无伤大雅。

●测试
如果你是个测试人员,你同样要把主要精力用于测试那些重点功能。对于"用户利益相关的功能",多进行一些健壮性测试、稳定性、安全性等测试(比如测试保存大文件是否会出错)。对于常用功能,主要进行易用性和性能测试(比如拷贝、粘贴是否易用)。
至于其它功能,只要进行普通的测试,保证它不出现明显和严重bug即可。要知道Windows 2000发布的时候,尚遗留上千个未修复的bug(当然都是低优先级的),微软不也照样发布。

●产品演示
有些软件开发完之后,会搞一些Demo进行宣传。如果你是负责进行Demo的人,你肯定要把主要的Demo时间用来秀软件的卖点,这样给客户的印象最深刻,效果最好;至于卖点的功能,都未必要提及。
几种和开发相关工作就介绍到这里,最后送给大伙一句话:Do not work hard, work smart!

-----------------------------------------------------------------------------------------------------------------

下面以我们的项目来介绍一个项目的开发过程:

1.首先进行用户需求调研,先弄明白用户想要什么(如果有老系统,可以先参观老系统,看有什么可以改进的,有什么可以继承的)熟悉业务。需求调研完成后,完成开发文档《用户调研报告》,然后根据调研,列出功能列表,同时区分重点功能和非重点功能。

2.调研完成后,画界面原型让用户来确认,如何使用等讲解清楚(这个过程中,可以会产生需求的变更),同时完成《用户需求规格说明书》,同时完成此文档的评审工作。此时,应该可以说到达了软件的一个里程碑。

3.需求评审完成后,进行数据库设计和详细设计,此时形成的文档有《数据库设计说明书》,《详细设计说明书》,同时完成文档的评审工作。

4.设计完成以后,就要进行开发工作了。依据详细设计说明书,此时要先进行重点功能的开发,然后进行非重点功能的开发。在此过程中开发人员进行模块的单测,确保系统的可运行。

5.开发完成后,由专门的测试人员进行单元测试、流程测试、性能测试等。(此时还可能有第三方测试人员和用户代表的参与)。此时会形成专门的测试文档。

6.用户测试。首先进行用户测试的培训,然后挑选部分用户进行系统的测试,此时一般会有开发人员进行现场的技术支持,使用用户尽快的熟悉系统的使用。

7.系统上线试运行。

posted @ 2009-06-07 20:07 george_chen 阅读(782) | 评论 (0)编辑 收藏

插入中的子查询语句,其中部分列来自指定字符:
insert into tablename
select col1,col2,'指定字符',变量1,'A',……
from table_name;
posted @ 2009-06-07 20:06 george_chen 阅读(138) | 评论 (0)编辑 收藏


阅读代码这个技能需要程序员能够具备读懂已经存在的代码的能力,这样的能力可以让程序员分析程序的行为,了解程序,这样才能和开发团队一起工作,继承维护或是改进现有的程序。
编写程序 编写程序并不包括程序设计。不要以为编程是一件很简单的事情,很多程序员都认为编程只需要懂得程序语言的语法,并把设计实现就可以了。但是这离编写程序还远远不够,使用什么样的编码风格成为编写程序员最需要具备的基本技能。能否使用非常良好的编程风格直接决写了程序员的级别。
软件设计 这一能力直接决定了需要吏用什么样的代码技术达到怎么样的功能,而系统架构设计直接决定了软件的质量、性能和可维护性。并不是所有的程序在这一方面都非常优秀,但每个程序员都需要或多或少的明白和掌握这一基本技能。
熟悉软件工程 每个程序员都应该明白软件工程是什么东西,都应该知道,需求分析,设计,编码,测试,Release和维护这几个阶段。当然,几乎所有的人都知道这些东西,但并不是每个人都很清楚这些东西。现在很多高级程序员都会混淆“需求规格说明书FS”和“概要设计HLD”。另外,程序员还需要知道一些软件开发的方法论,比如:敏捷开发或瀑布模型。
使用程序库或框架 一个程序员需要学会使用已有的代码,无论是标论的程序库,或是第三方的,还是自己公司内部的,都需要学会做。比如:C++中,需要学会使用STL,MFC,ATL,BOOST,ACE,CPPUNIT等等。使用这些东西,可以让你的工作事半功倍。
程序调试 程序调试是分析BUG和解决问题最直接的能力。没有人能够保证程序写出来不用调试就可以运行正常,也没有人可以保证程序永远不会出BUG。所以,熟练使用调试器是一个程序员需要具备的基本技能。
使用IDE 学会使用IDE工具也会让你的工作事半功倍。比如,VC++,Emacs,Eclipse等等,并要知道这些IDE的长处和短处。
使用版本控制 一定要学会使用版本控制工具,什么叫mainline/trunk,什么叫tag,什么叫branch,怎么做patch,怎么merge代码,怎么reverse,怎么利用版本控制工具维护不同版本的软件。这是程序员需要明的的软件配置管理中最重要的一块。
单元测试 单元测试是每个程序都需要做的。很多单元测试也是需要编码的。一定要学会在xUnit框架下进行单元测试。比如JUnit, NUnit, CppUnit等等。
重构代码 每个程序员都需要有最基本的能力去重构目前已有的代码,使代码达到最优但却不能影响任何的已有的功能。有一本书叫《软件的重构》,每个程序员都应该读一下。
自动化编译 程序员需要使用一个脚本,其能自动化编程所有的工程和代码,这样,整个开发团队可以不停地集成代码,自动化测试,自动化部署,以及使用一些工具进行静态代码分析或是自动化测试。

posted @ 2009-06-07 20:02 george_chen 阅读(384) | 评论 (0)编辑 收藏

需求

    你能给出一些非功能性(或者质量)需求的例子么?

    如果客户需要高性能、使用极其方便而又高度安全,你会给他什么建议?

    你能给出一些用来描述需求的不同技术么?它们各自适用于什么场景?

    需求跟踪是什么意思?什么是向前追溯,什么是向后追溯?

    你喜欢用什么工具跟踪需求?

    你怎么看待需求变化?它是好是坏?给出你的理由。

    你怎样研究需求,发现需求?有哪些资源可以用到?

    你怎么给需求制定优先级?有哪些技术?

    在需求过程中,用户、客户、开发人员各自的职责是什么?

    你怎么对待不完整或是令人费解的需求?

功能设计

    在功能设计中有哪些隐喻?给出几个成功的例子。

    如果有些功能的执行时间很长,怎么能让用户感觉不到太长的等待?

    如果用户必须要在一个很小的区域内,从一个常常的列表中选择多个条目,你会用什么控件?

    有哪些方法可以保证数据项的完整?

    建立系统原型有哪些技术?

    应用程序怎样建立对用户行为的预期?给出一些例子。

    如何入手设计一组数量庞大而又复杂的特性,你能举出一些设计思路吗?

    有一个列表,其中有10个元素,每个元素都有20个字段可以编辑,你怎样设计这种情况?如果是1000个元素,每个元素有3个字段呢?

    用不同的颜色对一段文本中的文字标记高亮,这种做法有什么问题?

    Web环境和Windows环境各有些什么限制?

技术设计

    什么是低耦合和高聚合?封装原则又是什么意思?

    在Web应用中,你怎样避免几个人编辑同一段数据所造成的冲突?

    你知道设计模式吗?你用过哪些设计模式?在什么场合下用的?

    是否了解什么是无状态的业务层?长事务如何与之相适应?

    在搭建一个架构,或是技术设计时,你用过几种图?

    在N层架构中都有哪些层?它们各自的职责是什么?

    有哪些方法可以确保架构中数据的正确和健壮?

    面向对象设计和面向组件设计有哪些不同之处?

    怎样在数据库中对用户授权、用户配置、权限管理这几项功能建模?

    怎样按照等级制度给动物王国(包括各种物种和各自的行为)建模?

程序设计

    你怎样保证你的代码可以处理各种错误事件?

    解释一下什么是测试驱动开发,举出极限编程中的一些原则。

    看别人代码的时候,你最关心什么地方?

    什么时候使用抽象类,什么时候使用接口?

    除了IDE以外,你还喜欢哪些必不可少的工具?

    你怎么保证代码执行速度快,而又不出问题?

    什么时候用多态,什么时候用委派?

    什么时候使用带有静态成员的类,什么时候使用单例?

    你在代码里面怎么提前处理需求的变化?给一些例子。

    描述一下实现一段代码的过程,从需求到最终交付。

算法

    怎样知道一个数字是不是2的乘方?怎样判断一个数是不是奇数?

    怎样找出链表中间的元素?

    怎样改变10,000个静态HTML页面中所有电话号码的格式?

    举出一个你所用过的递归的例子。

    在散列表和排序后的列表中找一个元素,哪个查找速度最快?

    不管是书、杂志还是网络,你从中所学到的最后一点算法知识是什么?

    怎样把字符串反转?你能不用临时的字符串么?

    你愿意用什么类型的语言来编写复杂的算法?

    有一个数组,里面是从1到1,000,000的整数,其中有一个数字出现了两次,你怎么找出那个重复的数字?

    你知道“旅行商问题(Traveling Salesman Problem)”么?

数据结构

    怎样在内存中实现伦敦地铁的结构?

    怎样以最有效的方式在数据库中存储颜色值?

    队列和堆栈区别是什么?

    用堆或者栈存储数据的区别是什么?

    怎样在数据库中存储N维向量?

    你倾向于用哪种类型的语言编写复杂的数据结构?

    21的二进制值是什么?十六制值呢?

    不管是书、杂志还是网络,你从中所学到的最后一点数据结构的知识是什么?

    怎样在XML文档中存储足球比赛结果(包括队伍和比分)?

    有哪些文本格式可以保存Unicode字符?

测试

    什么是回归测试?怎样知道新引入的变化没有给现有的功能造成破坏?

    如果业务层和数据层之间有依赖关系,你该怎么写单元测试?

    你用哪些工具测试代码质量?

    在产品部署之后,你最常碰到的是什么类型的问题?

    什么是代码覆盖率?有多少种代码覆盖率?

    功能测试和探索性测试的区别是什么?你怎么对网站进行测试?

    测试套件、测试用例、测试计划,这三者之间的区别是什么?你怎么组织测试?

    要对电子商务网站做冒烟测试,你会做哪些类型的测试?

    客户在验收测试中会发现不满意的东西,怎样减少这种情况的发生?

    你去年在测试和质量保证方面学到了哪些东西?

维护

    你用哪些工具在维护阶段对产品进行监控?

    要想对一个正在产品环境中被使用的产品进行升级,该注意哪些重要事项?

    如果在一个庞大的文件中有错误,而代码又无法逐步跟踪,你怎么找出错误?

    你怎样保证代码中的变化不会影响产品的其他部分?

    你怎样为产品编写技术文档?

    你用过哪些方式保证软件产品容易维护?

    怎样在产品运行的环境中进行系统调试?

    什么是负载均衡?负载均衡的方式有哪些种?

    为什么在应用程序的生命周期中,软件维护费用所占的份额最高?

    再造工程(re-engineering)和逆向工程(reverse engineering)的区别是什么?

配置管理

    你知道配置管理中基线的含义么?怎样把项目中某个重要的时刻冻结?

    你一般会把哪些东西纳入版本控制?

    怎样可以保证团队中每个人都知道谁改变了哪些东西?

    Tag和Branch的区别是什么?在什么情况下该使用tag,什么时候用branch?

    怎样管理技术文档——如产品架构文档——的变化?

    你用什么工具管理项目中所有数字信息的状态?你最喜欢哪种工具?

    如果客户想要对一款已经发布的产品做出变动,你怎么处理?

    版本管理和发布管理有什么差异?

    对文本文件的变化和二进制文件的变化进行管理,这二者有什么不同?

    同时处理多个变更请求,或是同时进行增量开发和维护,这种事情你怎么看待?

项目管理

    范围、时间、成本,这三项中哪些是可以由客户控制的?

    谁该对项目中所要付出的一切做出估算?谁有权设置最后期限?

    减少交付的次数,或是减少每个每个交付中的工作量,你喜欢哪种做法?

    你喜欢用哪种图来跟踪项目进度?

    迭代和增量的区别在哪里?

    试着解释一下风险管理中用到的实践。风险该如何管理?

    你喜欢任务分解还是滚动式计划?

    你需要哪些东西帮助你判断项目是否符合时间要求,在预算范围内运作?

    DSDM、Prince2、Scrum,这三者之间有哪些区别?

    如果客户想要的东西太多,你在范围和时间上怎样跟他达成一致呢?
posted @ 2009-05-24 15:42 george_chen 阅读(125) | 评论 (0)编辑 收藏

java1.5新特性

语法改动比较大的是泛型编程。使用泛型编程需要在声明的时候提供附加的声明信息。比如:
List words = new ArrayList();
需要替换成:
List<String> words = new ArrayList<String>();
这样做的一个优点是,如果你插入数组的数据类型不是字符串的话,你就可以在编译的时候发现和解决这个bug。如果不使用上面的声明,这个bug不可能在编译的时候发现,程序运行后会出现ClassCastException 的错误。
另一个好处是:你不在需要担心集合中的元素超出了范围:
String title = ((String) words.get(i)).toUppercase();
使用:
String title = words.get(i).toUppercase();
你能简单的介绍一下这些J2SE 1.5中改变最大的六个方面吗?
好的,
• 泛型编程 – 提供集合对象的编译时安全类型检查。
• 增强 for 循环 - 编程更容易,去掉了修正了导致迭代出错的问题。
• 装箱/拆箱 - 原始类型(int)和封装类型(Integer)的转换更容易。
• 类型安全的枚举 – 提供了最常使用的类型安全的枚举模式。(Effective Java, Item 21)
• 静态导入Static import - Lets you avoid qualifying static members with class names, without the shortcomings of the Constant Interface antipattern (Effective Java, Item 17).
• Metadata – 避免编写描述信息的代码,实现“声明”编程的模式。程序员声明需要做什么,然后由相关的工具来完成具体的工作。

一、泛型编程: 比如,过滤一个集合中的元素,现在的做法和j2se1.5中的做法有什么不同呢?
现在的做法是:
/**
* 从一个指定的集合中去掉一个4个字符的元素。
*/
static void expurgate(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); ) {
String s = (String) i.next();
if(s.length() == 4)
i.remove();
}}
上面的代码,有些缺陷,在运行的过程中可能出错。比如:在集合中如果包含一个StringBuffer类型的数据。
以后可以这样做:
static void expurgate(Collection<String> c) {
for (Iterator<String> i = c.iterator(); i.hasNext(); )
if (i.next().length() == 4)
i.remove();
}
二、增强的for循环!
一个集合中元素的迭代,原来的做法繁琐。J2SE1.5中大多数情况下你不需要使用Iterate 来遍历一个集合。增强的for循环,让编译器来完成具体的迭代工作。比如:
void cancelAll(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); ) {
TimerTask tt = (TimerTask) i.next();
tt.cancel();
}
}
现在可以这样做:
void cancelAll(Collection c) {
for (Object o : c)
((TimerTask)o).close();
}
注意:上面的冒号,它表示:in。在C#中或者很自然的一个替代是:foreach 和in 。但是考虑到兼容性,我们没有那样做。
泛型编程和增强的for结合后会是什么结果呢?
上面的例子中的代码,可以用下面的代码表示:
void cancelAll(Collection<TimerTask> c) {
for (TimerTask task : c)
task.cancel();
}
三、什么是装箱?
大家知道,java语言中有两种数据类型:一些是基本数据类型,另一些是对象引用类型。基本的数据类型无法直接放入到集合中,除非做相应的类型转换。这种转换非常枯燥。
举例:map数据类型的key用来存储单词,value用来存储单词重复的次数。这是一个计算单词出现频率的小程序。
public class Freq {
private static final Integer ONE = new Integer(1);
public static void main(String args[]) {
Map m = new TreeMap();
for (int i=0; i<args.length; i ) {
Integer freq = (Integer) m.get(args[i]);
m.put(args[i], (freq==null ? ONE :new Integer(freq.intValue() 1)));
}
System.out.println(m);
}
}
下面是采用装箱,泛型,和增强的for循环后的代码:
public class Freq {
public static void main(String args[]) {
Map<String, Integer> m = new TreeMap<String, Integer>();
for (String word : args)
m.put(word, m.get(word) 1);
System.out.println(m);
}
}
需要注意:上面的程序假定拆箱为null的时候,值为0。

J2SE1.5的新特点(下)
类型安全的枚举比以前的枚举有什么优点呢?
有如下特点:
• 提供编译时int枚举的安全检查,同时不再提供其他类型安全检查。
• 提供了枚举的命名空间
• 可以直接把它们放到集合中。
• 因为他们本质上是类,你可以向里面添加属性和方法。
上面的这些特点的确不错。能讲讲类型安全的枚举语言的特点和类型安全的枚举模式的关系吗?
一般来说:上面的那些特点简单的从语义上支持了模式。看下面的例子,和C/C++ 枚举的声明很相似:
enum Season { winter, spring, summer, fall }
声明虽然相似,但是确让编译器实现了上面提到的许多特性。你还可以把Season用到switch的判断语句中。
请举例说明“类型安全的枚举”的优点。
下面是一个表示美分枚举类型的例子。
public enum Coin {
penny(1), nickel(5), dime(10), quarter(25);
Coin(int value) { this.value = value; }
private final int value;
public int value() { return value; }
}
这是个创举。我们定义了value来作为读取Coin的公共变量。在枚举的构造函数中可以在声明枚举实例的时候来初始化它。
让我们看看进一步使用这个枚举的例子。
我把不的呢。下面的程序打印一个表格和其中coin的大小和颜色。
public class CoinTest {
public static void main(String[] args) {
for (Coin c : Coin.VALUES)
System.out.println(c + ":   "t"
+ c.value() +"¢ "t" + color(c));
}
private enum CoinColor { copper, nickel, silver }
private static CoinColor color(Coin c) {
switch(c) {
case Coin.penny:   return CoinColor.copper;
case Coin.nickel: return CoinColor.nickel;
case Coin.dime:
case Coin.quarter: return CoinColor.silver;
default: throw new AssertionError("Unknown coin: " + c);
}
}
}
太棒了。那么静态引入static import 的功能对程序员有什么帮助呢?
首先他避免了程序员使用前缀的静态成员。以前常见的的一个替代的做法是:
// "Constant Interface" antipattern – 不推荐的做法
public interface Physics {
public static final double AVOGADROS_NUMBER   = 6.02214199e23;
public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
public static final double ELECTRON_MASS      = 9.10938188e-31;
}

public class Guacamole implements Physics {
public static void main(String[] args) {
double moles = ...;
double molecules = AVOGADROS_NUMBER * moles;
...
}
}
上面的做法达到了效果,可是却违背了一些设计原则。接口是用来定义方法和类型的,不是提供常量声明的。而且只是由Guacamole使用的常量也暴露给了使用其的客户端。
静态引入功能提供了一个简单的实现。这个功能和包的import功能类似。
import static org.iso.Physics.*;

class Guacamole {
public static void main(String[] args) {
double molecules = AVOGADROS_NUMBER * moles;
...
}
}
明白,那么什么是元数据类型metadata的功能呢?
使用metadata和第三方工具提供商可以让程序员自己的日子好过点。
以前许多发布API需要大量的描述信息。比如:定义一个JAX-RPC 网络服务API你需要提供其接口和实现类。如下:
public interface CoffeeOrderIF extends java.rmi.Remote {
public Coffee [] getPriceList()
throws java.rmi.RemoteException;
public String orderCoffee(String name, int quantity)
throws java.rmi.RemoteException;
}

public class CoffeeOrderImpl implements CoffeeOrderIF {
public Coffee [] getPriceList() {
...
}
public String orderCoffee(String name, int quantity) {
...
}
}
使用元数据功能,你可以节省大量的工作。你所需要做的是在代码上加上特殊的注释。你所使用的开发工具可是使用这些注释自动生成相关的代吗。如下所示:
import javax.xml.rpc.*;

public class CoffeeOrder {
@Remote public Coffee [] getPriceList() {
...
}
@Remote public String orderCoffee(String name, int quantity) {
...
}
}

posted @ 2009-05-24 15:41 george_chen 阅读(151) | 评论 (0)编辑 收藏

今天项目的批处理日志发现报了以下的异常:

org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool exhausted

Caused by:
java.util.NoSuchElementException: Timeout waiting for idle object

在网上搜集答案,转载至此:

1 问题描述
Web程序在tomcat刚开始运行时速度很快,但过一段时间后发现速度变得很慢。
检查日志输出,发现异常如下:
org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted, cause:
java.util.NoSuchElementException: Timeout waiting for idle object
同时在SQLServer事件探查器中发现,每执行一次sql语句都要产生Audit login事件,语句执行后产生
Audit logout事件。说明每一次tomcat都是重新打开新的连接。
2 问题解决
tomcat 的数据源定义提供了三个参数:
a. 如果设为true则tomcat自动检查恢复重新利用,没有正常关闭的Connection.(默认是false)
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
b. 设定连接在多少秒内被认为是放弃的连接,即可进行恢复利用。
<parameter>
<name>removeAbandonedTimeout</name>
<value>60</value>
</parameter>
c. 输出回收的日志,可以详细打印出异常从而发现是在那里发生了泄漏
<parameter>
<name>logAbandoned</name>
<value>true</value>
</parameter>

posted @ 2009-05-24 15:36 george_chen 阅读(235) | 评论 (0)编辑 收藏

<html>
<head>
<script language=javascript>
<!--
function focusOn(){
document.f1.btn1.focus();
}
//-->
</script>
</head>
<body onload="focusOn()">
<form name="f1">
<input type="button" name="btn1">
</form>
</body>
</html>
posted @ 2008-11-25 08:26 george_chen 阅读(221) | 评论 (0)编辑 收藏