2004年05月21日

by mvm


这七十五条,是我这些年来,尤其是在微软工作两年来的体会的总结,关于如何用正确的方法来写出质量好的软件的体会的总结。或许看似平淡无奇,但大音希声,这七十五条的效用,未必及不上那几十页几百页的体系,却远远比那好用:


1. 你们的项目组使用源代码管理工具了么?
2. 你们的项目组使用缺陷管理系统了么?
3. 你们的测试组还在用Word写测试用例么?
4. 你们的项目组有没有建立一个门户网站?
5. 你们的项目组用了你能买到最好的工具么?
6. 你们的程序员工作在安静的环境里么?
7. 你们的员工每个人都有一部电话么?
8. 你们每个人都知道出了问题应该找谁么?
9. 你遇到过有人说“我以为…”么?
10. 你们的项目组中所有的人都坐在一起么?
11. 你们的进度表是否反映最新开发进展情况?
12. 你们的工作量是先由每个人自己估算的么?
13. 你们的开发人员从项目一开始就加班么?
14. 你们的项目计划中Buffer Time是加在每个小任务后面的么?
15. 值得再多花一些时间,从95%做到100%好
16. 登记新缺陷时,是否写清了重现步骤?
17. 写新代码前会把已知缺陷解决么?
18. 你们对缺陷的轻重缓急有事先的约定么?
19. 你们对意见不一的缺陷有三国会议么?
20. 所有的缺陷都是由登记的人最后关闭的么?
21. 你们的程序员厌恶修改老的代码么?
22. 你们项目组有Team Morale Activity么?
23. 你们项目组有自己的Logo么?
24. 你们的员工有印有公司Logo的T-Shirt么?
25. 总经理至少每月参加一次项目组会议
26. 你们是给每个Dev开一个分支么?
27. 有人长期不Check-In代码么?
28. 在Check-In代码时都填写注释了么?
29. 有没有设定每天Check-In的最后期限?
30. 你们能把所有源码一下子编译成安装文件吗?
31. 你们的项目组做每日编译么?
32. 你们公司有没有积累一个项目风险列表?
33. 设计越简单越好
34. 尽量利用现有的产品、技术、代码
35. 你们会隔一段时间就停下来夯实代码么?
36. 你们的项目组每个人都写Daily Report么?
37. 你们的项目经理会发出Weekly Report么?
38. 你们项目组是否至少每周全体开会一次?
39. 你们项目组的会议、讨论都有记录么?
40. 其他部门知道你们项目组在干什么么?
41. 通过Email进行所有正式沟通
42. 为项目组建立多个Mailing Group
43. 每个人都知道哪里可以找到全部的文档么?
44. 你做决定、做变化时,告诉大家原因了么?
45. Stay agile and expect change
46. 你们有没有专职的软件测试人员?
47. 你们的测试有一份总的计划来规定做什么和怎么做么?
48. 你是先写Test Case然后再测试的么?
49. 你是否会为各种输入组合创建测试用例?
50. 你们的程序员能看到测试用例么?
51. 你们是否随便抓一些人来做易用性测试?
52. 你对自动测试的期望正确么?
53. 你们的性能测试是等所有功能都开发完才做的么?
54. 你注意到测试中的杀虫剂效应了么?
55. 你们项目组中有人能说出产品的当前整体质量情况么?
56. 你们有单元测试么?
57. 你们的程序员是写完代码就扔过墙的么?
58. 你们的程序中所有的函数都有输入检查么?
59. 产品有统一的错误处理机制和报错界面么?
60. 你们有统一的代码书写规范么?
61. 你们的每个人都了解项目的商业意义么?
62. 产品各部分的界面和操作习惯一致么?
63. 有可以作为宣传亮点的Cool Feature么?
64. 尽可能缩短产品的启动时间
65. 不要过于注重内在品质而忽视了第一眼的外在印象
66. 你们根据详细产品功能说明书做开发么?
67. 开始开发和测试之前每个人都仔细审阅功能设计么?
68. 所有人都始终想着The Whole Image么?
69. Dev工作的划分是单纯纵向或横向的么?
70. 你们的程序员写程序设计说明文档么?
71. 你在招人面试时让他写一段程序么?
72. 你们有没有技术交流讲座?
73. 你们的程序员都能专注于一件事情么?
74. 你们的程序员会夸大完成某项工作所需要的时间么?
75. 尽量不要用Virtual Heads

用图表方式对几款主流的BLOG程序进行了比较


原文:
http://www.asymptomatic.net/blogbreakdown.htm


国内镜象:


来源:


http://www.dengjie.com/

2004年05月17日

前几天变卖了我的垃圾三星S108,入手水T618,版本R6B(现在客服最新版本R6C,这几天才提供升级,嘿嘿,还不错),两电两充。


终于入手了,一年前就想买的手机。可惜当时由于种种原因选择了三星,越用越觉得三星的手机垃圾,软件功能强大的都暴贵。我同学有款三星手机,现在行货还卖近4千吧,连彩信都不支持,有个照相机只能自己照了玩。


T618除了发短信时反应稍慢,内存太小,其他都蛮不错。我的T618入手时空闲内存有1700多K,真是爽啊。支持JAVA,MPN游戏,支持JAVA电子书。我还在上面安装了JAVA英汉字典。虽然反应不够快(JAVA嘛),但还是好用的。电子书还有书签功能。


所有东西都能通过红外从电脑里传到手机上,很方便啊,现在USB的红外适配器不到100吧。现在我用的就是传的蜡笔小新的主题^_^


照相功能马马虎虎,反正我也不在乎,玩玩的嘛。


听说内置的MINIGOLF可以删除,就是下载一个MINIGOLF,然后覆盖机子内的MINIGOLF,这样就可以删除了,删后可空出63K。我没有试过。


其他功能什么的评测报告里都有,不说了哈。

2004年05月11日

1、都是靠出卖为生。

2、吃青春饭,人老珠黄肯定混不下去。

3、越高级收入越高,当然中间人的抽头会更高。

4、生活没有规律。以夜生活为主,如果需要,凌晨也要加班。

5、名声越大,越容易受到青睐。

6、必须尽最大可能满足客户各种各样非正常的需求。

7、鼓励创新精神。

8、喜欢扎堆。程序员集中的地方称为软件园,妓女集中的地方叫红灯区。

9、流动性较大,正常情况下没有工会。

10、如果怀孕了,既不能做程序员,也不能做妓女。

11、都为防病毒的问题而烦恼…

12、当然,个中高手还专门以制毒传毒为乐

13、一个是microsoft,一个是plug & play

14、工作状态相同。工作时精神高度集中,最怕外界干扰。
  工作完毕身心放松,体会到一种不可替代的工作快乐。

15、女孩子最好还是不要做这两个职业,但还是有很多女孩子做。

16、除非在转行以后,否则都不愿意结婚。

17. 程序员怕查户口的。妓女怕查房的。

18. 妓女工作的地方(床)是程序员最向往的地方

19. 程序界的高手通常很讨厌微软,妓女界的高手嗯。。这个。。恐怕也如此

20. 都是吃青春饭,不过到人老珠黄后,凭着混个脸熟,程序员可以混个管理员,妓女也行,不过俗称老鸨

21. 妓女靠的本钱是三围,程序员靠的可是四围(思维)

22. 程序员为了拉客,通常会在交易前提供一个demo,妓女提供的那叫photo

23. 程序员现在出的活时兴叫吃霸、结霸,妓女大姐一律叫波霸

24. 心不在焉的妓女可以一边工作一边do { beep(1); sleep(9) } until overflow心不在焉的程序员也可以一边工作一边navigate到成人网站上去

25. 程序员手册:一套好的人机操作界面要求,对于新手,能够一步一步的引导他进入功能,相反对于熟客,能够直奔主题;妓女同样要遵守程序员手册对人鸡界面的规定

26. 妓女在工作中最怕的是临检,程序员最怕的是停电

27. 新上手的程序员叫菜鸟,刚入行的妓女叫雏鸡,都是好可怜的小动物

28. 程序界现在流行oo的方法,虽然在xxxx年前妓女已在床上掌握了o~o~~~的技术

29. 程序员为了拉客,无奈之时,也可以先让客人试玩,妓女当然有时也会先给你甜头


不过总之程序员比妓女还惨,补充如下:

1. 妓女每个月总有几天可以理直气壮的说不,程序员如果老板不发话,可要一年干到黑

2. 女人做程序那叫奇女、才女,男人要是做妓,那就叫鸭了

3. 妓女不干了人家那叫从良,程序员如果不干了,估计是下了岗

4. 程序员有千年虫问题,妓女好象没听说有

5. 妓女的工作隐蔽性很强,程序员的工作只怕亲戚朋友都知道,所以更加没脸皮

6. 程序员做的越好,要做的程序越多,妓女做的好,就可以挑三拣四

7. 程序员现在流行free、open什么的,说白了就是自己玩自己,妓女界好象还没这样恶性竞争

2004年05月07日

—————————-
注意你的思想,思想产生语言;
注意你的语言,语言会变成行动;
注意你的行动,行动将形成性格;
注意你的性格,性格将决定你的命运。

—————————-
I Love You means:


I — Inject — 投入


L — Loyal — 忠诚
O — Obligation — 责任
V — Valiant — 勇敢
E — Enjoyment — 喜悦


Y — Yes — 愿意
O — Observant — 用心
U — Unison — 和谐
—————————-

这世界变化快,多家媒体报道,红帽子返回到 Linux 桌面市场。

Red Hat Returns to Linux Desktop Market


Red Hat Inc. returned to the desktop Linux market on Tuesday, outlining a strategy to get more businesses to adopt the freely available operating system for running desktop personal computers.

Red Hat pulled out of the desktop market last year to focus on providing update and support services for Linux-based servers, the networked computers that serve up Web pages, store data and run complex applications.


Red Hat Inc.把Rad Hat Linux一直做到9,然后说不继续了,放出了Fedora,现在是core2了吧。现在又说出Red Hat Linux Desktop,晕死。绕了一圈还是回来了。可能新的RH Linux的定位和以前会不一样吧。


找了LFS(Linux From Scratch)的很多资料,准备花时间学习。我想与其频繁穿梭于各大商业发行版本之间不如自己从头打造一个Linux。


————————————


附: 什么是LFS? http://lfs.linuxsir.org/cgi-bin/wiki/moin.cgi


LFS–[WWW]Linux from Scratch,就是一种从 网上直接下载源码,从头编译LINUX的安装方式。它不是发行版,只是一个菜谱,告诉你到哪里去买菜(下载源码),怎么把这些生东西( raw code) 作成符合自己口味的菜肴—个性化的linux,不单单是个性的桌面。


LFS有什么优势呢?现在看来,它可以提供最快和最小的linux。但是最大的优势就是,安装LFS是菜鸟变成高手的捷径。第一次安装,需要按照LFS文档安装,如果在此期间所有文档内容你都认真的阅读,保证你受益匪浅;然后发现很多地方可以不按照别人的老路操作,这个时候用自己的方式参考第一次安装的经验,再一次建立linux,完成的时候,你会发现你在linuxsir上已经再也不是菜鸟了。

安装两次LFS,总共要用去你一个多礼拜(说不定一个多礼拜还装不完)的业余时间。但是这一个多礼拜将是你linux水平进步最快的一个多礼拜。

2004年05月05日

月之轮回·时间表

  2:48初亏


  月亮进入地球黑影,发生圆亏变化


  3:52食既


  月亮全部进入地球黑影,红月浮现


  4:30食甚


  月亮进入离地球黑影中心最近处


  5:08生光


  月亮开始离开地球的黑影


  6:12复圆


  月全食结束,一轮满月重现天空


  月之轮回·月全食


  月食是地球运行到太阳和月球中间、地球的影子遮掩月球时产生的一种奇特天象。月全食是地影遮掩了整个月球,月偏食只是月球的一部分在地影之内。发生月全食时,月亮并不是完全看不见,而是变成一个隐约可见的古铜色圆盘。这是因为地球挡住了太阳光对月亮的照射,而产生的阴影,而地球的大气层在此时仍然会折射一部分太阳光,因此会出现红月亮的情况。

2004年05月02日

基本篇


作者:flyingwcy 转载自:Java研究组织

本文介绍的JAVA规则的说明分为5个级别,级别1是最基本也是最重要的级别,在今后将陆续写出其他的规则。遵守了这些规则可以提高程序的效率、使代码有更好的可读性等。

(1) 避免使用NEW关键字来创建String对象。
把一个String常量copy到String 对象中通常是多余、浪费时间的
Public class test{
Public void method(){
System.out.print (str);
}
private String str = new String (“1″); //这里新建对象是完全没有必要的
private String str2=”2” //正确的应该如此
}
参考:Joshua Bloch: “Effective Java – Programming Language Guide”


(2) 避免使用不必要的嵌套。
过多的嵌套会使你的代码复杂化,减弱可读性。
Public class test {
String add (){
Int c=(a=a+b)+b; //过于复杂
Return c
}

}

参考:http://java.sun.com/docs/codeconv/html/CodeConventions.doc9.html#177

(3) 避免在同一行声明不同类型的多个变量
这样可以使程序更加清晰,避免混乱
private int index, index1[];
正确的应该如此:
private int index;
private int index1[];


参考:http://java.sun.com/docs/codeconv/html/CodeConventions.doc5.html#2992

(4) 在每一行里写一条语句
这条规则不包括for语句:比如:´for (int I = 0; I < 10; i++) x--;’可以增加代码的可读性。
public class OSPL {
int method (int a, int b) {
int I = a + b; return I; // 可读性不强
}
正确的:
public class OSPLFixed {
int method (int a, int b) {
int I = a + b;
return I;
}
}
参考:Section 7.1 of http://java.sun.com/docs/codeconv/html/CodeConventions.doc6.html#431


(5)经常从finalize ()中调用super.finalize ()
这里的finalize ()是java在进行垃圾收集的时候调用的,和finally不一样。如果你的父类没有定义finally()的话,你也应该调用。这里有两个原因:(1)在不改变代码的情况下能够将父类的finally方法加到你的类中。 (2)以后你会养成习惯调用父类的finally方法,即使父类没有定义finally方法的时候。
正确的方法应该如此:
public class parentFinalize {
protected void finalize () throws Throwable {
super.finalize(); // FIXED
}

参考:”The Java Programming Language” by Ken Arnold and James Gosling, page 49.

(6) 不要在finalize ()中注销listeners
不要再finalize ()方法中中注销listeners,finalize ()只有再没有对象引用的时候调用,如果listeners从finalize()方法中去除了,被finalize的对象将不会在垃圾收集中去除。
public void finalize () throws Throwable {
bButton.removeActionListener (act);
}

(7) 不要显式的调用finalize ()方法
虽然显式的调用这个方法可以使你确保你的调用,但是当这个方法收集了以后垃圾收集会再收集一次。

public class T7 { public void finalize() throws Throwable { close_resources (); super.finalize (); } public void close_resources() {}}class Test { void cleanup () throws Throwable { t71.finalize(); // 调用 t71 = null; } private t71 = new T7 ();}

对于这样的调用我们应该自己创建一个释放的方法,做最初finalize ()所作的事情,当你每次想显式的调用finalize ()的时候实际上调用了释放方法。然后再使用一个判断字段来确保这个方法只执行一次,以后再调用就没关系了。

public class T7 { public synchronized void release () throws Throwable{ if (!_released) { close_resources (); // do what the old ´finalize ()´ did _released = true; } } public void finalize () throws Throwable { release (); super.finalize (); } public void close_resources() {} private boolean _released = false;}class TestFixed { void closeTest () throws Throwable { t71 .release (); // FIXED t71 = null; } private T7 t71 = new T7 ();}


参考:Nigel Warren, Philip Bishop: “Java in Practice – Design Styles and Idioms
for Effective Java”. Addison-Wesley, 1999. pp.110-111


(8)不要使用不推荐的API
尽量使用JDK1.3推荐的API。在类和方法或者java组件里有很多方法是陈旧的或者是可以选择的。有一些方法SUN用了”deprecated“标记。最好不要使用例如:
private List t_list = new List ();
t_list.addItem (str);
如果查一下javadoc的话,会发现建议用add()来代替addItem()。
参考:http://java.sun.com/j2se/1.3/docs/api/index.html

(9)为所有序列化的类创建一个´serialVersionUID´
可以避免从你各种不同的类破坏序列的兼容性。如果你不特别制订一个UID的话,那么系统为自动产生一个UID(根据类的内容)。如果UID在你新版本的类中改变了,即使那个被序列化的类没改变,你也不能反序列化老的版本了。

public class DUID implements java.io.Serializable { public void method () {}}
在里面加一个UID,当这个类的序列化形式改变的时候,你也改变这个UID就可以了。

public class DUIDFixed implements java.io.Serializable { public void method () {} private static final long serialVersionUID = 1; }


参考:Joshua Bloch: “Effective Java – Programming Language Guide”
Addison Wesley, 2001, pp. 223

(10)对于private常量的定义
比较好的做法是对于这样的常量,加上final标记,这样的常量从初始化到最后结束值都不会改变。
private int size = 5;
改变后的做法是:
private final int size = 5;

(11)避免把方法本地变量和参数定义成和类变量相同的名字。
这样容易引起混扰,建议把任何的变量字都定义成唯一的。这样看来,SCJP里的那些题目在现实中就用不到了:)

public void method (int j) { final int I = 5; // VIOLATION } private int j = 2;


建议:
public void method (int j1) { final int I = 5; // VIOLATION } private int j = 2;

参考:Michael Daconta, Eric Monk, J Keller, Keith Bohnenberger: “Java Pitfalls”
John Wiley & Sons, ISBN: 0-471-36174-7 pp.17 – 25


 


中级篇

作者:flyingwcy 转载自:Java研究组织
本文介绍的JAVA规则的说明分为3个主要级别,中级是平时开发用的比较多的级别,在今后将陆续写出其他的规则。遵守了这些规则可以提高程序的效率、使代码又更好的可读性等。
(1) 在finally方法里关掉input或者output 资源
再方法体里面定义了input或者output流的话,需要在finally里面把它关掉。
以下这几种调用不需要遵守这条规则,因为colse()方法不起作用:)
java.io.StringWriter java.io.ByteArrayOutputStream java.io.ByteArrayInputStream
如果再方法返回的时候没有调用close()方法来释放input()和output()的资源的话,会导致一个系统资源泄漏。而且在任何情况下都要确定在返回全调用了close() 方法,包括出现异常的时候。所以需要在finally方法里面加入这个方法。这样就保证了在任何情况下都会关闭资源。
错误示例:
public class CIO {
public void method (java.io.File f) {
java.io.FileInputStream fis = null;
try {
fis = new java.io.FileInputStream (f);
fis.read ();
fis.close ();
} catch (java.io.FileNotFoundException e1) {
System.out.println(“File not found”);
} catch (java.io.IOException e2) {
System.out.println(“I/O Exception”);
}
// 如果出现异常,这里就不能保证关闭资源。
}
}
修正后的代码:
public class CIOFixed {
public void method (java.io.File f) {
java.io.FileInputStream fis = null;
try {
fis = new java.io.FileInputStream (f);
fis.read ();
} catch (java.io.FileNotFoundException e1) {
System.out.println(“File not found”);
} catch (java.io.IOException e2) {
System.out.println(“I/O Exception”);
} finally {
if (fis != null) {
try {
fis.close ();
} catch (java.io.IOException e) {
System.out.println(“I/O Exception”);
}
}
}
}
}

(2) else的注意问题.
一般总认为如果if语句只有一句的话,那么{}就是可要可不要的了。可是如果if有else嵌套的话,就不一样了,{}是必需的
错误示例:
if (I < 5)
if (I < 2)
i++;
else
i–;
修改后:
if (I < 5) {
if (I < 2)
i++;
}
else {
i–;
}

(3) 不要再catch()块里什么代码也不放
在catch()块里面放入一些错误处理代码是一个好的习惯。但是如果catch()里面有有关javadoc 的代码,那也是可以的。
错误示例:
try {
System.in.read ();
} catch (java.io.IOException e) {
// 错误
}

正确:
try {
System.in.read ();
} catch (java.io.IOException e) {
System.out.println(“Descriptive error”);
}
参考:Joshua Bloch: “Effective Java – Programming Language Guide”.
Addison-Wesley, 2001, pp. 187

(4)不要在if条件里面附值
如果这样做的话,系统会报告错误。在java的很多条件声明里面用附值是很不明智的,而且系统也会报告错误。很容易引起异常。遵守这条规者能够使维护简单,避免不一致。
错误示例:
if (b = true)
正确的:
if (b == true)
参考:Section 10.4 of http://java.sun.com/docs/codeconv/html/CodeConventions.doc9.html#547

(5) for语句需要循环体。
如果没有{}的话,for语句只会执行一次!
错误示例:
for (I = 0; I < 10; i++) ;
System.out.println (i);
这里print() 只会执行一次。
正确:
for (I = 0; I < 10; i++) { // FIXED
System.out.println (i);
}

(5) 不要把方法定义成main().
在java里,main()方法是一个特别的方法。所以在自己定义方法的时候不要定义这样的名字,以免引起混扰。

(6)不要直接或者间接的定义´Error´和´Throwable´的子类
´java.lang.Error´只在JVM出现反常的时候覆盖这个方法,如果你定义了直接或者不直接的类继承了类´Error´,也就指出了这个错误是JVM内部的,而不是这个类的。所以对于java编译器来说是不可见的,这样就不能检查错误的异常处理了。
´java.lang.Throwable´是´java.lang.Exception´和´java.lang.Error´的上级类,用户如果象定义异常类的话应该继承´java.lang.Exception´。
错误示例:public class ABC extends Error
正确:public class ABC extends Exception

(7)有关”switch”语句里面的”case”问题
最好在每一个 “case”里都定义一个”return”或者“break”来控制不要走到下面的 “case”里去。如果一个”case”语句在代码的最后没有一个”break”或者”return”句,程序就会走到下一个”case”。如果这个”case”是最后一个的话,那就没什么问题,如果后面还有”case” 的话,看起来就不太安全了。
错误示例:
switch (i) {
case 1:
x = 10;
break;
case 2:
x = 20;
default:
a = 40;
break;
正确:
switch (i) {
case 1:
x = 10;
break;
case 2: // VIOLATION
x = 20;
break;
default:
x = 40;
break;

(8)建议不要使用´System.getenv ()´
不建议使用´System.getenv ()´,这个方法看起来很好用,不过并不是所有的系统都有环境变量的。不用这个方法也可能带来一些不方便。
错误示例:
void method (String name) {
System.getenv (name); // 可以用其他方法来代替
}
如果不用这个方法,我们可以用其它的方法来代替。比如:´System.getProperty ()’,´getTypeName ()´等,这也可以找到java的系统属性。
参考:David Flanagan: “Java in a Nutshell”. O´Reilly
November, 1999: Third Edition, pp.190-192

(9)不要使用’\n’或者´\r´来分行
这两个标记看来很普遍,特别是’\n’。我们经常用来作为分行用。但是不同的系统用不同的分行字符,所以这些字符在某些意义上违背了java的平台无关性。
错误示例:
System.out.println(“Hello\n” + name);
我们可以用其它的一些方法来代替,比如println(),这个方法在不同的系统平台上都起到相同的作用。后者推荐大家用这个方法:System.getProperty(“line.separator”)
参考:David Flanagan: “Java in a Nutshell”. O´Reilly,
November 1999: Third Edition, pp. 191-192

(10) 使所有的内部类”private”.
Java允许一个类包含另外一个类,带是Java byte code没有这个概念。类被编译器解释成package-private类。从更深的程度来说,包含类的任何内部私有对象能被内部类访问的也能被同一个包内的其他类访问。
错误示例:
public class INNER {
class INNER_Class {
void setValue(int i) {
_value = I; // 现在包就可以访问了
}
}
private int _value;
}
所以需要加上private class INNER_Class
参考:Statically Scanning Java Code: Finding Security Vulnerabilities.
John Viega, Gary McGraw, Tom Mutdosch, and Edward W. Felten
IEEE SOFTWARE September/October 2000

(11)不要使接口序列化
如果一个字节数组包含了一个被序列化的对象。攻击者就能读到这个对象的内部状态合字段(包括private的)。
错误示例:
public interface sample extends java.io.Serializable


 


开发篇

作者:flyingwcy 转载自:Java研究组织
本文介绍的JAVA规则的说明分为3个主要级别,本篇抛弃了平时开发中很少遇到的情况,那些用得比较少的以后再高级篇里面出现。并有六个有用的国际软件开发重要注意的有关String的问题,遵守了这些规则可以提高程序的效率、使代码又更好的可读性等。
(1) 如果有JDBC连接没有关掉的话,需要在”finally”方法中关掉
如果数据库连接失败或者是没有释放连接,看上去无关紧要。但是其他的用户就需要用更长的时间等待连接,这样数据库利用效率就会下降。确保你的代码在任何情况下,包括出错或者程序异常终止的情况下都释放数据库连接。在”finally”方法中关掉连接,就可以确保这一点。
错误示例:
try {
Statement stmt = con.createStatement();
} catch(SQLException e) {
e.printStackTrace();
}
正确示例:
try {
Statement stmt = con.createStatement();
} finally {
if (con != null && !con.isClosed()) {
con.close();
}
}

(2) 尽量避免使用´Thread.resume ()´, ´Thread.stop ()´, ´Thread.suspend ()´和 ´Runtime.runFinalizersOnExit ()´ 方法。
这些方法在平时的开发或者是教科书里面也有用到过,但是这些方法会导致四锁的倾向。一下有充足的资料来说明为什么不建议用上述方法。
参考:1.”java.lang.Thread” in the JDK API documentation
2.http://java.sun.com/j2se/1.3/docs/guide/misc/threadPrimitiveDeprecation.html
3.Paul Hyde: “Java Thread Programming”
Sams, ISBN: 0-672-31585-8 pp. 270

(3) 在表示长整常量的时候,用L来代替l.
因为l很容易和1混一起。
错误示例:
long temp = 23434l;
正确示例:
long temp = 23434L;
参考:Ken Arnold, James Gosling: “The Java Programming Language Second Edition”Addison Wesley, 1997, pp.108

(4) 最好在jsp开头写一条注释
在 jsp文件头上面写一条注释,这样可以帮助别人来理解你的代码。这条规则不仅适用于jsp,更是用于任何开发的文档。
正确示例:<%-- JSP comment --%>


(5)明确的初始化一个构造类里面的所有的字段
因为没有初始化的字段会是一个潜在的bug,所以最好初始化类里面的所有的字段。特别是静态的字段,最好在一开始就分配一个初始值
错误示例:
public class CSI {
public CSI () {
this (12);
k = 0;
}

public CSI (int val) {
j = val;
}

private int I = 5;
private int j;
private int k;
}

正确示例:
public class CSIFixed {
public CSIFixed () {
this (12);
}

public CSIFixed (int val) {
j = val;
k = 0;
}

private int I = 5;
private int j;
private int k;
}
参考:http://www.ambysoft.com/javaCodingStandards.pdf

(5) 国际化开发建议:逻辑操作符不要再一个单个的字符的前面或者后面
一个单个字符的前后不要用逻辑操作符,如果代码要在一个国家环境中运行的话。我们可以使用字符比较方法,这些方法使用统一字符比较标准来定义字符的属性的。
错误示例:public class CLO {
public boolean isLetter (char ch) {
boolean _isLetter = ( ch >= ´a´ && ch <= ´z´) //错误
|| (ch >= ´A´ && ch <= ´Z´);
return _isLetter;
}
}

正确示例:
public class CLOFixed {
public boolean isLetter (char ch) {
boolean _isLetter = Character.isLetter(ch);
return _isLetter;
}
}
参考: http://java.sun.com/docs/books/tutorial/i18n/intro/checklist.html
更多的字符比较方法请参考:http://java.sun.com/docs/books/tutorial/i18n/text/charintro.html


(6) 国际化开发建议:不要对日期对象使用´Date.toString ()´
不要使用´Date.toString ()´方法,日期格式对于地区和语言不同的国家来说是不一样的,务必不要使用。
错误示例:´DateFormat´类提供了一个预定义的格式类型来指定本地的格式。
public void printToday () {
Date today = new Date ();
String todayStr = today.toString ();
System.out.println (todayStr);
}
正确示例:
public void printToday () {
Locale currentLocale = Locale.getDefault ();
DateFormat dateFormatter = DateFormat.getDateInstance (
DateFormat.DEFAULT, currentLocale);
Date today = new Date ();
String todayStr = dateFormatter.format (today);
System.out.println (todayStr);
}
参考:http://java.sun.com/docs/books/tutorial/i18n/intro/checklist.html
http://java.sun.com/docs/books/tutorial/i18n/format/dateFormat.html

(7) 国际化开发建议:不要对数字变量使用´toString ()´方法
在全球化的开发中,不要对数字变量使用´toString ()´方法,对于java.lang.Number的任何子类都适用。包括:BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, and Short.对于这样的情况,java里也与定义了”NumberFormat”方法来格式化。
错误示例:
public class NTS {
public void method (Double amount) {
String amountStr = amount.toString ();
System.out.println (amountStr);
}
}
正确示例:
public class NTSFixed {
public void method (Double amount) {
Locale currentLocale = Locale.getDefault ();
NumberFormat numberFormatter =
NumberFormat.getNumberInstance (currentLocale);
String amountStr = numberFormatter.format (amount); //
System.out.println (amountStr + ´ ´ + currentLocale.toString ());
}
}
参考:http://java.sun.com/docs/books/tutorial/i18n/intro/checklist.html
http://java.sun.com/docs/books/tutorial/i18n/format/numberFormat.html


(8) 国际化开发建议:不要使用´String.equals ()´方法
建议不要使用´String.equals ()´方法,因为在统一字符比较标准中不一定按照相关的顺序来比较。´Collator´提供的预定义整理规则来排序string,Collator类调用´getInstance ()´方法,一般来说,可以为默认的本地创建一个Collator。例如:Collator myCollator = Collator.getInstance ();创建Collator的时候你也可以指定一个特殊的locale。例如:Collator myFrenchCollator = Collator.getInstance (Locale.FRENCH);然后就可以调用´Collator.compare ()´来执行一个本地的字符比较myCollator.compare (s1,s2);从这里可以了解更多的有关Collator类的信息:http://java.sun.com/docs/books/tutorial/i18n/text/collationintro.html



错误示例:
public class SE {
public boolean compstr (String s1, String s2) {
boolean b = (s1.equals (s2));
return b;
}
}
正确示例:
public class SEFixed {
public boolean compstr (String s1, String s2) {
Collator myCollator = Collator.getInstance ();
boolean b = (myCollator.compare(s1,s2) == 0);
return b;
}
}

参考:http://java.sun.com/docs/books/tutorial/i18n/intro/checklist.html
http://java.sun.com/docs/books/tutorial/i18n/text/locale.html

(9) 国际化开发建议:不要使用´StringTokenizer()´方法
错误示例:StringTokenizer st = new StringTokenizer(str);
可以从这里得到更多的信息:‘
参考:http://java.sun.com/docs/books/tutorial/i18n/intro/checklist.html


(10) 国际化开发建议:不要使用´Time.toString ()´方法
因为时间的格式各个国家也不一样。如果你使用日期格式类,你的应用就能够在世界上各个地方正确的显示时间和日期了。首先,用´getTimeInstance ()´方法创建一个formatter。然后,调用´format ()´方法。
错误示例:
public class TTS {
public void printTime (Time t1) {
String timeStr = t1.toString ();
System.out.println (timeStr);
}
}
正确示例:
import java.sql.Time;
import java.text.DateFormat;
import java.util.Locale;

public class TTSFixed {
public void printTime (Time t1) {
DateFormat timeFormatter = DateFormat.getTimeInstance(
DateFormat.DEFAULT, Locale.getDefault ());
String timeStr = timeFormatter.format(t1);
System.out.println (timeStr);
}
}

在我们学习Java的过程中,掌握其中的基本概念对我们的学习无论是J2SE,J2EE,J2ME都是很重要的,J2SE是Java的基础,所以有必要对其中的基本概念做以归纳,以便大家在以后的学习过程中更好的理解java的精髓,在此我总结了30条基本的概念.

  Java概述:

  目前Java主要应用于中间件的开发(middleware)—处理客户机于服务器之间的通信技术,早期的实践证明,Java不适合pc应用程序的开发,其发展逐渐变成在开发手持设备,互联网信息站,及车载计算机的开发.Java于其他语言所不同的是程序运行时提供了平台的独立性,称许可以在windows,solaris,linux其他操作系统上使用完全相同的代码.Java的语法与C++语法类似,C++/C程序员很容易掌握,而且Java是完全的彻底的面向对象的,其中提出了很好的GC(Garbage Collector)垃圾处理机制,防止内存溢出.

  Java的白皮书为我们提出了Java语言的11个关键特性.

  (1)Easy:Java的语法比C++的相对简单,另一个方面就是Java能使软件在很小的机器上运行,基础解释其和类库的支持的大小约为40kb,增加基本的标准库和线程支持的内存需要增加125kb.

  (2)分布式:Java带有很强大的TCP/IP协议族的例程库,Java应用程序能够通过URL来穿过网络来访问远程对象,由于servlet机制的出现,使Java编程非常的高效,现在许多的大的web server都支持servlet.

  (3)OO:面向对象设计是把重点放在对象及对象的接口上的一个编程技术.其面向对象和C++有很多不同,在与多重继承的处理及Java的原类模型.

  (4)健壮特性:Java采取了一个安全指针模型,能减小重写内存和数据崩溃的可能性。

  (5)安全:Java用来设计网路和分布系统,这带来了新的安全问题,Java可以用来构建防病毒和防攻击的System.事实证明Java在防毒这一方面做的比较好.
(6)中立体系结构:Java编译其生成体系结构中立的目标文件格式可以在很多处理器上执行,编译器产生的指令字节码(Javabytecode)实现此特性,此字节码可以在任何机器上解释执行.

  (7)可移植性:Java中对基本数据结构类型的大小和算法都有严格的规定所以可移植性很好.

  (8)多线程:Java处理多线程的过程很简单,Java把多线程实现交给底下操作系统或线程程序完成.所以多线程是Java作为服务器端开发语言的流行原因之一

  (9)Applet和servlet:能够在网页上执行的程序叫Applet,需要支持Java的浏览器很多,而applet支持动态的网页,这是很多其他语言所不能做到的.

  基本概念:

  1.OOP中唯一关系的是对象的接口是什么,就像计算机的销售商她不管电源内部结构是怎样的,他只关系能否给你提供电就行了,也就是只要知道can or not而不是how and why.所有的程序是由一定的属性和行为对象组成的,不同的对象的访问通过函数调用来完成,对象间所有的交流都是通过方法调用,通过对封装对象数据,很大限度上提高复用率.

  2.OOP中最重要的思想是类,类是模板是蓝图,从类中构造一个对象,即创建了这个类的一个实例(instance)

  3.封装:就是把数据和行为结合起在一个包中)并对对象使用者隐藏数据的实现过程,一个对象中的数据叫他的实例字段(instance field)

  4.通过扩展一个类来获得一个新类叫继承(inheritance),而所有的类都是由Object根超类扩展而得,根超类下文会做介绍.

  5.对象的3个主要特性
  behavior—说明这个对象能做什么.
  state—当对象施加方法时对象的反映.
  identity—与其他相似行为对象的区分标志.
  每个对象有唯一的indentity 而这3者之间相互影响.
6.类之间的关系:
  use-a :依赖关系
  has-a :聚合关系
  is-a :继承关系–例:A类继承了B类,此时A类不仅有了B类的方法,还有其自己的方法.(个性存在于共性中)

  7.构造对象使用构造器:构造器的提出,构造器是一种特殊的方法,构造对象并对其初始化.
  例:Data类的构造器叫Data
  new Data()—构造一个新对象,且初始化当前时间.
  Data happyday=new
  Data()—把一个对象赋值给一个变量happyday,从而使该对象能够多次使用,此处要声明的使变量与对象变量二者是不同的.new返回的值是一个引用.
  构造器特点:构造器可以有0个,一个或多个参数
  构造器和类有相同的名字
  一个类可以有多个构造器
  构造器没有返回值
  构造器总是和new运算符一起使用.

  8.重载:当多个方法具有相同的名字而含有不同的参数时,便发生重载.编译器必须挑选出调用哪个方法.

  9.包(package)Java允许把一个或多个类收集在一起成为一组,称作包,以便于组织任务,标准Java库分为许多包.java.lang java.util java,net等,包是分层次的所有的java包都在java和javax包层次内.

  10.继承思想:允许在已经存在的类的基础上构建新的类,当你继承一个已经存在的类时,那么你就复用了这个类的方法和字段,同时你可以在新类中添加新的方法和字段.

  11.扩展类:扩展类充分体现了is-a的继承关系. 形式为:class (子类) extends (基类).

  12.多态:在java中,对象变量是多态的.而java中不支持多重继承.
13.动态绑定:调用对象方法的机制.
  (1)编译器检查对象声明的类型和方法名.
  (2)编译器检查方法调用的参数类型.
  (3)静态绑定:若方法类型为priavte static final 编译器会准确知道该调用哪个方法.
  (4)当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用x所指向的对象的实际类型相匹配的方法版本.
  (5)动态绑定:是很重要的特性,它能使程序变得可扩展而不需要重编译已存代码.

  14.final类:为防止他人从你的类上派生新类,此类是不可扩展的.

  15.动态调用比静态调用花费的时间要长,

  16.抽象类:规定一个或多个抽象方法的类本身必须定义为abstract例: public abstract string getDescripition

  17.Java中的每一个类都是从Object类扩展而来的.

  18.object类中的equal和toString方法.equal用于测试一个对象是否同另一个对象相等.toString返回一个代表该对象的字符串,几乎每一个类都会重载该方法,以便返回当前状态的正确表示.(toString 方法是一个很重要的方法)

  19.通用编程:任何类类型的所有值都可以同object类性的变量来代替.

  20.数组列表:ArrayList动态数组列表,是一个类库,定义在java.uitl包中,可自动调节数组的大小.

  21.class类 object类中的getclass方法返回ckass类型的一个实例,程序启动时包含在main方法的类会被加载,虚拟机要加载他需要的所有类,每一个加载的类都要加载它需要的类.

  22.class类为编写可动态操纵java代码的程序提供了强大的功能反射,这项功能为JavaBeans特别有用,使用反射Java能支持VB程序员习惯使用的工具.能够分析类能力的程序叫反射器,Java中提供此功能的包叫Java.lang.reflect反射机制十分强大.
  1.在运行时分析类的能力.
  2.在运行时探察类的对象.
  3.实现通用数组操纵代码.
  4.提供方法对象.
  而此机制主要针对是工具者而不是应用及程序.
  反射机制中的最重要的部分是允许你检查类的结构.用到的API有:
  java.lang.reflect.Field 返回字段.
  java.reflect.Method 返回方法.
  java.lang.reflect.Constructor 返回参数.
  方法指针:java没有方法指针,把一个方法的地址传给另一个方法,可以在后面调用它,而接口是更好的解决方案.
23.接口(Interface)说明类该做什么而不指定如何去做,一个类可以实现一个或多个interface.

  24.接口不是一个类,而是对符合接口要求的类的一套规范.若实现一个接口需要2个步骤:
  1.声明类需要实现的指定接口.
  2.提供接口中的所有方法的定义.
  声明一个类实现一个接口需要使用implements 关键字class actionB implements Comparable 其actionb需要提供CompareTo方法,接口不是类,不能用new实例化一个接口.

  25.一个类只有一个超类,但一个类能实现多个接口.Java中的一个重要接口Cloneable

  26.接口和回调.编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特定时间发生时回调对象上的方法.例:ActionListener 接口监听.
  类似的API有:java.swing.JOptionPane
        java.swing.Timer
        java.awt.Tookit

  27.对象clone:clone方法是object一个保护方法,这意味着你的代码不能简单的调用它.

  28.内部类:一个内部类的定义是定义在另一个内部的类
  原因是:1.一个内部类的对象能够访问创建它的对象的实现,包括私有数据
  2.对于同一个包中的其他类来说,内部类能够隐藏起来.
  3.匿名内部类可以很方便的定义回调.
  4.使用内部类可以非常方便的编写事件驱动程序.

  29.代理类(proxy):1.指定接口要求所有代码 2.object类定义的所有的方法(toString equals)

  30.数据类型:Java是强调类型的语言,每个变量都必须先申明它都类型,java中总共有8个基本类型.4种是整型,2种是浮点型,一种是字符型,被用于Unicode编码中的字符,布尔型.

虽然都能在JAVA API中找到,整理一下做个备份。


string->byte
Byte static byte parseByte(String s) 

byte->string
Byte static String toString(byte b)

char->string
Character static String to String (char c)

string->Short
Short static Short parseShort(String s)

Short->String
Short static String toString(Short s) 

String->Integer
Integer static int parseInt(String s)

Integer->String
Integer static String tostring(int i)

String->Long
Long static long parseLong(String s)

Long->String
Long static String toString(Long i)

String->Float
Float static float parseFloat(String s)

Float->String
Float static String toString(float f)

String->Double
Double static double parseDouble(String s)

Double->String
Double static String toString(Double d)