审查Java代码的十一种常见错误

审查Java代码的十一种常见错误
审查Java代码的十一种常见错误

审查Java代码的十一种常见错误

代码审查是消灭Bug最重要的方法之一,这些审查在大多数时候都特别奏效。由于代码审查本身所针对的对象,就是俯瞰整个代码在测试过程中的问题和Bug。并且,代码审

查对消除一些特别细节的错误大有裨益,尤其是那些能够容易在阅读代码的时候发现的错误,这些错误往往不容易通过机器上的测试识别出来。本文就常见的Java代码中容易出现的问题提出一些建设性建议,以便您在审查代码的过程中注意到这些常见的细节性错误。

通常给别人的工作挑错要比找自己的错容易些。别样视角的存在也解释了为什么作者

需要编辑,而运动员需要教练的原因。不仅不应当拒绝别人的批评,我们应该欢迎别人来发现并指出我们的编程工作中的不足之处,我们会受益匪浅的。

正规的代码审查(code inspection)是提高代码质量的最强大的技术之一,代码审查—由同事们寻找代码中的错误—所发现的错误与在测试中所发现的错误不同,因此两者的关系是互补的,而非竞争的。

如果审查者能够有意识地寻找特定的错误,而不是靠漫无目的的浏览代码来发现错误,那么代码审查的效果会事半功倍。在这篇文章中,我列出了11个Java编程中常见的错误。你可以把这些错误添加到你的代码审查的检查列表(checklist)中,这样在经过代码审查后,你可以确信你的代码中不再存在这类错误了。

一、常见错误1# :多次拷贝字符串

测试所不能发现的一个错误是生成不可变(immutable)对象的多份拷贝。不可变对象是不可改变的,因此不需要拷贝它。最常用的不可变对象是String。

如果你必须改变一个String对象的内容,你应该使用StringBuffer。下面的代码会

正常工作:

1.String s = new String ("Text here");

但是,这段代码性能差,而且没有必要这么复杂。你还可以用以下的方式来重写上面

的代码:

1.String temp = "Text here";

2.String s = new String (temp);

但是这段代码包含额外的String,并非完全必要。更好的代码为:

1.String s = "Text here";

二、常见错误2#:没有克隆(clone)返回的对象

封装(encapsulation)是面向对象编程的重要概念。不幸的是,Java为不小心打破封装提供了方便——Java允许返回私有数据的引用(reference)。下面的代码揭示了这一点:

1.import java.awt.Dimension;

2./***Example class.The x and y values should never*be negative.*/

3.public class Example{

4. private Dimension d = new Dimension (0, 0);

5. public Example (){ }

6.

7. /*** Set height and width. Both height and width must be nonnegative

* or an exception is thrown.*/

8. public synchronized void setValues (int height,int width) throws

IllegalArgumentException{

9. if (height < 0 || width < 0)

10. throw new IllegalArgumentException();

11. d.height = height;

12. d.width = width;

13. }

14.

15. public synchronized Dimension getValues(){

16. // Ooops! Breaks encapsulation

17. return d;

18. }

19.}

Example类保证了它所存储的height和width值永远非负数,试图使用setValues()

方法来设置负值会触发异常。不幸的是,由于getValues()返回d的引用,而不是d的拷

贝,你可以编写如下的破坏性代码:

1.Example ex = new Example();

2.Dimension d = ex.getValues();

3.d.height = -5;

4.d.width = -10;

现在,Example对象拥有负值了!如果getValues() 的调用者永远也不设置返回的Dimension对象的width 和height值,那么仅凭测试是不可能检测到这类的错误。

不幸的是,随着时间的推移,客户代码可能会改变返回的Dimension对象的值,这

个时候,追寻错误的根源是件枯燥且费时的事情,尤其是在多线程环境中。

更好的方式是让getValues()返回拷贝:

1.public synchronized Dimension getValues(){

2.return new Dimension (d.x, d.y);

3.}

现在,Example对象的内部状态就安全了。调用者可以根据需要改变它所得到的拷贝

的状态,但是要修改Example对象的内部状态,必须通过setValues()才可以。

三、常见错误3#:不必要的克隆

我们现在知道了get方法应该返回内部数据对象的拷贝,而不是引用。但是,事情没

有绝对:

1./*** Example class.The value should never * be negative.*/

2.public class Example{

3. private Integer i = new Integer (0);

4. public Example (){ }

5.

6. /*** Set x. x must be nonnegative* or an exception will be thrown*/

7. public synchronized void setValues (int x) throws

IllegalArgumentException{

8. if (x < 0)

9. throw new IllegalArgumentException();

10. i = new Integer (x);

11. }

12.

13. public synchronized Integer getValue(){

14. // We can’t clone Integers so we makea copy this way.

15. return new Integer (i.intValue());

16. }

17.}

这段代码是安全的,但是就象在错误1#那样,又作了多余的工作。Integer对象,就

象String对象那样,一旦被创建就是不可变的。因此,返回内部Integer对象,而不是它

的拷贝,也是安全的。

方法getValue()应该被写为:

1.public synchronized Integer getValue(){

2.// ’i’ is immutable, so it is safe to return it instead of a copy.

3.return i;

4.}

Java程序比C++程序包含更多的不可变对象。JDK 所提供的若干不可变类包括:

> Boolean

> Byte

> Character

> Class

> Double

> Float

> Integer

> Long

> Short

> String

> 大部分的Exception的子类

四、常见错误4# :自编代码来拷贝数组

Java允许你克隆数组,但是开发者通常会错误地编写如下的代码,问题在于如下的循环用三行做的事情,如果采用Object的clone方法用一行就可以完成:

1.public class Example{

2. private int[] copy;

3. /*** Save a copy o f ’data’. ’data’ cannot be null.*/

4. public void saveCopy (int[] data){

5. copy = new int[data.length];

6. for (int i = 0; i < copy.length; ++i)

7. copy[i] = data[i];

8. }

9.}

这段代码是正确的,但却不必要地复杂。saveCopy()的一个更好的实现是:

1.void saveCopy (int[] data){

2. try{

3. copy = (int[])data.clone();

4. }catch (CloneNotSupportedException e){

5.// Can’t get here.

6. }

7.}

如果你经常克隆数组,编写如下的一个工具方法会是个好主意:

1.static int[] cloneArray (int[] data){

2. try{

3. return(int[])data.clone();

4. }catch(CloneNotSupportedException e){

5.// Can’t get here.

6. }

7.}

这样的话,我们的saveCopy看起来就更简洁了:

1.void saveCopy (int[] data){

2. copy = cloneArray ( data);

3.}

五、常见错误5#:拷贝错误的数据

有时候程序员知道必须返回一个拷贝,但是却不小心拷贝了错误的数据。由于仅仅做了部分的数据拷贝工作,下面的代码与程序员的意图有偏差:

1.import java.awt.Dimension;

2./*** Example class. The height and width values should never * be

3.negative. */

4.public class Example{

5. static final public int TOTAL_VALUES = 10;

6. private Dimension[] d = new Dimension[TOTAL_VALUES];

7. public Example (){ }

8.

9. /*** Set height and width. Both height and width must be nonnegative

* or an exception will be thrown. */

10. public synchronized void setValues (int index, int height, int width)

throws IllegalArgumentException{

11. if (height < 0 || width < 0)

12. throw new IllegalArgumentException();

13. if (d[index] == null)

14. d[index] = new Dimension();

15. d[index].height = height;

16. d[index].width = width;

17. }

18. public synchronized Dimension[] getValues()

19. throws CloneNotSupportedException{

20. return (Dimension[])d.clone();

21. }

22.}

这儿的问题在于getValues()方法仅仅克隆了数组,而没有克隆数组中包含的Dimension对象,因此,虽然调用者无法改变内部的数组使其元素指向不同的Dimension 对象,但是调用者却可以改变内部的数组元素(也就是Dimension对象)的内容。方法getValues()的更好版本为:

1.public synchronized Dimension[] getValues() throws

CloneNotSupportedException{

2. Dimension[] copy = (Dimension[])d.clone();

3. for (int i = 0; i < copy.length; ++i){

4.// NOTE: Dimension isn’t cloneable.

5. if (d != null)

6. copy[i] = new Dimension (d[i].height, d[i].width);

7. }

8. return copy;

9.}

在克隆原子类型数据的多维数组的时候,也会犯类似的错误。原子类型包括int,float 等。简单的克隆int型的一维数组是正确的,如下所示:

1.public void store (int[] data) throws CloneNotSupportedException{

2. this.data = (int[])data.clone();

3. // OK

4.}

拷贝int型的二维数组更复杂些。Java没有int型的二维数组,因此一个int型的二

维数组实际上是一个这样的一维数组:它的类型为int[]。简单的克隆int[][]型的数组会犯

与上面例子中getValues()方法第一版本同样的错误,因此应该避免这么做。下面的例子

演示了在克隆int型二维数组时错误的和正确的做法:

1.public void wrongStore (int[][] data) throws

CloneNotSupportedException{

2. this.data = (int[][])data.clone(); // Not OK!

3.}

4.public void rightStore (int[][] data){

5. // OK!

6. this.data = (int[][])data.clone();

7. for (int i = 0; i < data.length; ++i){

8. if (data != null)

9. this.data[i] = (int[])data[i].clone();

10. }

11.}

六、常见错误6#:检查new 操作的结果是否为null

Java编程新手有时候会检查new操作的结果是否为null。可能的检查代码为:

1.Integer i = new Integer (400);

2.if (i == null)

3.throw new NullPointerException();

检查当然没什么错误,但却不必要,if和throw这两行代码完全是浪费,他们的唯一功用是让整个程序更臃肿,运行更慢。

C/C++程序员在开始写java程序的时候常常会这么做,这是由于检查C中malloc()的返回结果是必要的,不这样做就可能产生错误。检查C++中new操作的结果可能是一个好的编程行为,这依赖于异常是否被使能(许多编译器允许异常被禁止,在这种情况下new操作失败就会返回null)。在java 中,new 操作不允许返回null,如果真的返回null,很可能是虚拟机崩溃了,这时候即便检查返回结果也无济于事。

七、常见错误7#:用== 替代.equals

在Java中,有两种方式检查两个数据是否相等:通过使用==操作符,或者使用所有对象都实现的.equals方法。原子类型(int, flosat, char 等)不是对象,因此他们只能使用==操作符,如下所示:

1.int x = 4;

2.int y = 5;

3.if (x == y)

4. System.out.println ("Hi");

5.// This ’if’ test won’t compile.

6.if (x.equals (y))

7. System.out.println ("Hi");

对象更复杂些,==操作符检查两个引用是否指向同一个对象,而equals方法则实现更专门的相等性检查。

更显得混乱的是由https://www.360docs.net/doc/4017237957.html,ng.Object 所提供的缺省的equals方法的实现使用==来简单的判断被比较的两个对象是否为同一个。

许多类覆盖了缺省的equals方法以便更有用些,比如String类,它的equals方法检查两个String对象是否包含同样的字符串,而Integer的equals方法检查所包含的int 值是否相等。

大部分时候,在检查两个对象是否相等的时候你应该使用equals方法,而对于原子类型的数据,你用该使用==操作符。

八、常见错误8#:混淆原子操作和非原子操作

Java保证读和写32位数或者更小的值是原子操作,也就是说可以在一步完成,因而不可能被打断,因此这样的读和写不需要同步。以下的代码是线程安全(thread safe)的:

1.public class Example{

2. private int value; // More code here...

3. public void set (int x){

4. // NOTE: No synchronized keyword

5. this.value = x;

6. }

7.}

不过,这个保证仅限于读和写,下面的代码不是线程安全的:

1.public void increment (){

2. // This is effectively two or three instructions:

3.// 1) Read current setting of ’value’.

4. // 2) Increment that setting.

5. // 3) Write the new setting back.

6. ++this.value;

7.}

在测试的时候,你可能不会捕获到这个错误。首先,测试与线程有关的错误是很难的,而且很耗时间。其次,在有些机器上,这些代码可能会被翻译成一条指令,因此工作正常,只有当在其它的虚拟机上测试的时候这个错误才可能显现。因此最好在开始的时候就正确地同步代码:

1.public synchronized void increment (){

2. ++this.value;

3.}

九、常见错误9#:在catch 块中作清除工作

一段在catch块中作清除工作的代码如下所示:

1.OutputStream os = null;

2.try{

3. os = new OutputStream ();

4. // Do something with os here.

5. os.close();

6.}catch (Exception e){

7. if (os != null)

8. os.close();

9.}

尽管这段代码在几个方面都是有问题的,但是在测试中很容易漏掉这个错误。下面列出了这段代码所存在的三个问题:

1. 语句os.close()在两处出现,多此一举,而且会带来维护方面的麻烦。

2. 上面的代码仅仅处理了Exception,而没有涉及到Error。但是当try块运行出现了Error,流也应该被关闭。

3. close()可能会抛出异常。

上面代码的一个更优版本为:

1.OutputStream os = null;

2.try{

3. os = new OutputStream ();

4. // Do something with os here.

5.}finally{

6. if (os != null)

7. os.close();

8.}

这个版本消除了上面所提到的两个问题:代码不再重复,Error也可以被正确处理了。但是没有好的方法来处理第三个问题,也许最好的方法是把close()语句单独放在一个

try/catch块中。

十、常见错误10#:增加不必要的catch 块

一些开发者听到try/catch块这个名字后,就会想当然的以为所有的try块必须要有与之匹配的catch块。

C++程序员尤其是会这样想,因为在C++中不存在finally块的概念,而且try块存在的唯一理由只不过是为了与catch块相配对。

增加不必要的catch块的代码就象下面的样子,捕获到的异常又立即被抛出:

1.try{

2. // Nifty code here

3.}catch(Exception e){

4. throw e;

5.}finally{

6. // Cleanup code here

7.}

不必要的catch块被删除后,上面的代码就缩短为:

1.try{

2. // Nifty code here

3.}finally{

4. // Cleanup code here

5.}

十一、常见错误11#;没有正确实现equals,hashCode,或者clone 等方法

方法equals,hashCode,和clone 由https://www.360docs.net/doc/4017237957.html,ng.Object提供的缺省实现是正确的。不幸地是,这些缺省实现在大部分时候毫无用处,因此许多类覆盖其中的若干个方法以提供更有用的功能。但是,问题又来了,当继承一个覆盖了若干个这些方法的父类的时候,子类通常也需要覆盖这些方法。在进行代码审查时,应该确保如果父类实现了equals,hashCode,或者clone等方法,那么子类也必须正确。正确的实现equals,hashCode,和clone需要一些技巧。

小结

我在代码审查的时候至少遇到过一次这些错误,我自己也犯过其中的几个错误。好消息是只要你知道你在找什么错误,那么代码审查就很容易管理,错误也很容易被发现和修改。即便你找不到时间来进行正规的代码审查,以自审的方式把这些错误从你的代码中根除会大大节省你的调试时间。花时间在代码审查上是值得的。

程序开发部代码审查制度

程序开发部代码审查制度 1.文档目的 (1) 2.适用范围 (1) 3.工作制度 (1) 3.1代码审查范围 (1) 3.2代码审查标准 (1) 3.2.1所开发的代码功能是否与详细设计文档中描述的保持一致。 (1) 3.2.2代码是否符合编码规范 (1) 3.2.3代码是否正确无误,没有隐含的错误。 (1) 3.3审查执行流程 (1) 3.4代码审查活动的监督 (2) 1.文档目的 该文档的阅读者主要为部门总监、部门经理、开发组长和程序员。通过该制度来规范代码编写,从而提高代码质量。 2.适用范围 该制度适用于程序开发部部门内部。 3.工作制度 3.1代码审查范围 审查任务目标包含的所有类。 3.2代码审查标准 3.2.1所开发的代码功能是否与详细设计文档中描述的保持一致。 此项检查设计部门会做抽查,开发部门需要做为重点执行项,保证代码和设计的一致性。3.2.2代码是否符合编码规范 此项检查作为开发部重点执行项,必须和编码规范保持一致。 3.2.3代码是否正确无误,没有隐含的错误。 此项检查要保证在组件功能无误的基础上进行,需要有经验的高级程序员对具体程序片段进行检查,纠正逻辑不合理代码、垃圾代码等。此工作在现阶段可以做为次要执行项。 3.3审查执行流程 1.检查的粒度――功能组件

2.当程序员开发完成一个组件,并且告知组长可以进行审查时,由开发组长或者指定的高级程序员来做审查工作。 3.审查人必须详细检查目标的代码编写,并且需要填写《代码审查表》。 4.如果审查未能通过,被审查人按照《代码审查表》的审查意见进行修改。 5.重复执行步骤2-4,直到审查通过。 3.4代码审查活动的监督 代码审查制度为代码质量的绩效考核提供参考,作为绩效考核代码质量评分的依据。

java源代码经典入门案例—光环java编程培训机构

java源代码经典入门案例 class Demo { public static void main(String[] args) { System.out.println("hello E盘"); } } class Demo { public static void main(String[] args) { System.out.println("hello E盘"); } } /* 需求:练习一个hello world程序。 思路: 1,定义一个类,因为java程序都定义类中,java程序都是以类的形式存在的,类的形式其实就是一个字节码文件最终体现。 2,定义一个主函数。为了让该类可以独立运行。 3,因为演示hello world,在控制台上看到该字样,所以需要使用输出语句完成。 步骤: 1,用class关键字来完成类的定义,并起一个阅读性强的类名。 2,主函数:public static void main(String[] args)这时固定格式的。jvm认识。 3,使用输出语句:System.out.println("hello world"); 代码仅仅是思想的一种体现形式。 */ class Demo

{ //定义一个主函数,为了保证程序的独立运行。 public static void main(String[] args) { System.out.println("hello world");//这是输出语句,用于将括号中的数据打印到控制台上,ln可以在数据的结尾处换行。 } } class OperateDemo { public static void main(String[] args) { //算术运算符。+ - * / %(取余,模运算) +(连接符) // ++(自增:就在原有数据基础上+1,在赋给原有数据) -- //int x = 6370; //x = x / 1000 * 1000; //System.out.println(x); // System.out.println(5%2); // System.out.println(3+"2"); //System.out.println("5+5="+(5+5));//"5+5=5"+5 "5+5=55" //int a = 4,b = 5; //System.out.println("a="+a+",b="+b);//a=4,b=5; int a = 3,b; //a++;//a = a+1; // b = a++; b = (a++)+(++a)+(a++)+a; // 3 5 5 6 System.out.println("a="+a+",b="+b); int i = 3; i = i++;

代码审查规范

1. Code Revie进行检查试过现的质量保机制,通这个机制我可以代码、注一种Code Revie来确认方案计和代码的要用在软件工程程中改进码质量,Code Revie以达到如下Code Review代码审查规范1. Code Review目的 Code Review是一种用来确认方案设计和代码实现的质量保证机制,通过这个机制我们可以对代码、测试过程和注释进行检查。 Code Review主要用来在软件工程过程中改进代码质量,通过Code Review可以达到如下目的: 在项目早期就能够发现代码中的BUG。?帮助初级开发人员学习高级开发人员的经验,达到知识共享。?避免开发人员犯一些很常见,很普通的错误。?保证项目组人员的良好沟通。?项目或产品的代码更容易维护。? 2. Code Review的前提条件 代码提交审核前,开发者必须确保代码符合如下条件,审核者需要确保所有前提条件都已满足方可开始审查,同时也是审查的主要检查点。 所有代码注释清晰,语法正确,编译通过。?日志代码完整,业务日志、系统日志分开,中文描述,脱敏处理,状态变更,?全部清晰明确。 测试代码覆盖全部分支和流程,暂时统一使用工具Emma(各编译器可下载对?应插件)进行Coverage Check。 项目引用关系明确,依赖关系清晰,配置文件描述。? 的审查范围3. Code Review 代码的一致性、编码风格、代码的安全问题、脱敏问题、代码冗余、是否正确设计以符合设计要求(性能、功能)与设计文档相同等等。)完整性检查(Completeness3.1、 代码是否完全实现了设计文档中所涉及的所有流程和功能点?代码是否已包含所有所需的业务日志、系统日志、异常日志,日志内容是否完?整,日志文件配置是否正确。 代码是否使用缓存等,配置信息是否正确可配置。?代码中是否存在任何没有定义或没有引用到的变量、常数或数据类型等?一致性检查(Consistency)3.2、 代码的逻辑是否符合设计文档?代码中使用的格式、符号、结构等风格是否保持一致?)Correctness3.3、正确性检查(代码是否符合制定的标准?所有的变量都被正确定义和使用?所有的注释都是准确的?所有的程序调用都使用了正确的参数个数? Modifiability)、3.4 可修改性检查(如使用配置、定义为类常量、使用专门的常量代码涉及到的常量是否易于修改(?)类等 代码中是否包含了交叉说明或数据字典,以描述程序是如何对变量和常量进行?访问的 代码是否只有一个出口和一个入口(严重的异常处理除外)?)可预测性检查(Predictability3.5、代码所用的开发语言是否具有定义良好的语法和语义?是否代码避免了依赖于开发语言缺省提供的功能?代码是否无意中陷入了死循环?代码是否避免了无穷递归?.

经典Java程序源代码

1.加法器(该java源文件的名称是)import .*; import .*; public class Adder implements ActionListener { JFrame AdderFrame; JTextField TOprand1; JTextField TOprand2; JLabel LAdd,LSum; JButton BAdd,BClear; JPanel JP1,JP2; public Adder() { AdderFrame=new JFrame("AdderFrame"); TOprand1=new JTextField("");

TOprand2=new JTextField(""); LAdd=new JLabel("+"); LSum=new JLabel("= "); BAdd=new JButton("Add"); BClear=new JButton("Clear"); JP1=new JPanel(); JP2=new JPanel(); (this); (new ActionListener() { public void actionPerformed(ActionEvent event) { (""); (""); ("="); }

}); (JP1); (TOprand1); (LAdd); (TOprand2); (LSum); (JP2); (BAdd); (BClear); ().setLayout(new BorderLayout()); ().add(JP1,; ().add(JP2,; (new WindowAdapter() {

Java源代码___聊天室

Java 聊 天 室 制作人:_____杨永生_____ 制作时间:2012.9.26 目录 1本文简介 (2) 2聊天室截图与说明 (2) 2.1用Java编译: (2) 2.2服务器登录界面 (2) 2.3服务器窗口 (2) 2.4客服端登录界面 (3) 2.5客服端窗口 (3) 3服务器端 (6) 3.1MyServer()方法 (6) 3.2Login()方法 (10) 3.3Time()方法 (13) 4客户端 (14) 4.1MyClient()方法 (14) 4.2Login()方法 (18) 4.3Time()方法 (20)

1 本文简介 这是一个简单的Java聊天室,仅提供给一些刚学Java的学生做实验,本文也是仅供参考. 本文代码都有注释,希望读者能读懂代码,本实验内部还有一些错误,比如只能一条一条的发信息,不能连发,希望能解决本问题的朋友能给我发信息,我的QQ号就是百度号! 2 聊天室截图与说明 2.1 用Java编译: 本代码有七个类,放在六个java文件中,类名在下方希望读者自己观看, 2.2 服务器登录界面 要先运行服务器端的程序 用户名:y 密码:1 用户名密码可以自己设定点击确定可以登录,2秒后到服务端界面 2.3 服务器窗口

聊天室的IP为本机的网络虚拟IP,在任何电脑上都能用,端口应设置在1024以后, 2.4 客服端登录界面 和服务器端的登录一样 2.5 客服端窗口

当登录上后客服端就显示已经连接了,此时服务器端的窗口如下

由于本程序设计的不是很完整,具体的聊天要先从客服端开始: 在客服端输入一条聊天内容后按确定,在服务器端就可以收到信息,之后客户端不能输入了,要等待服务器端来信息后才能继续输入信息. 想要结束聊天,直接可以关闭窗口,也可以输入’bye’后断开聊天

代码审查规范

代码审查规范 1. Code Review目的 Code Review是一种用来确认方案设计和代码实现的质量保证机制,通过这个机制我们可以对代码、测试过程和注释进行检查。 Code Review主要用来在软件工程过程中改进代码质量,通过Code Review可以达到如下目的: ?在项目早期就能够发现代码中的BUG。 ?帮助初级开发人员学习高级开发人员的经验,达到知识共享。 ?避免开发人员犯一些很常见,很普通的错误。 ?保证项目组人员的良好沟通。 ?项目或产品的代码更容易维护。 2. Code Review的前提条件 代码提交审核前,开发者必须确保代码符合如下条件,审核者需要确保所有前提条件都已满足方可开始审查,同时也是审查的主要检查点。 ?所有代码注释清晰,语法正确,编译通过。 ?日志代码完整,业务日志、系统日志分开,中文描述,脱敏处理,状态变更,全部清晰明确。 ?测试代码覆盖全部分支和流程,暂时统一使用工具Emma(各编译器可下载对应插件)进行Coverage Check。 ?项目引用关系明确,依赖关系清晰,配置文件描述。 3. Code Review的审查范围 代码的一致性、编码风格、代码的安全问题、脱敏问题、代码冗余、是否正确设计以符合设计要求(性能、功能)与设计文档相同等等。

3.1、完整性检查(Completeness) ?代码是否完全实现了设计文档中所涉及的所有流程和功能点 ?代码是否已包含所有所需的业务日志、系统日志、异常日志,日志内容是否完整,日志文件配置是否正确。 ?代码是否使用缓存等,配置信息是否正确可配置。 ?代码中是否存在任何没有定义或没有引用到的变量、常数或数据类型等 3.2、一致性检查(Consistency) ?代码的逻辑是否符合设计文档 ?代码中使用的格式、符号、结构等风格是否保持一致 3.3、正确性检查(Correctness) ?代码是否符合制定的标准 ?所有的变量都被正确定义和使用 ?所有的注释都是准确的 ?所有的程序调用都使用了正确的参数个数 3.4、可修改性检查(Modifiability) ?代码涉及到的常量是否易于修改(如使用配置、定义为类常量、使用专门的常量类等) ?代码中是否包含了交叉说明或数据字典,以描述程序是如何对变量和常量进行访问的 ?代码是否只有一个出口和一个入口(严重的异常处理除外) 3.5、可预测性检查(Predictability) ?代码所用的开发语言是否具有定义良好的语法和语义 ?是否代码避免了依赖于开发语言缺省提供的功能 ?代码是否无意中陷入了死循环 ?代码是否避免了无穷递归 3.6、健壮性检查(Robustness)

JAVA程序代码(20)

1百分制分数到等级分数 package pm; public class SwitchTest { //编写程序,实现从百分制分数到等级分数的转换 // //>=90 A // 80~89 B // 70~79 C // 60~69 D // <60 E public static void main(String[] args) { int s=871; switch(s/10){ case 10 :System.out.println("A");break; case 9 :System.out.println("A");break; case 8 :System.out.println("B");break; case 7 :System.out.println("c");break; case 6 :System.out.println("D");break; default :System.out.println("E");break; } } } 2成法口诀阵形 package pm; public class SwitchTest{ public static void main(String[] args){ for(int i=1;i<=19;i++){ for(int j=1;j<=i;j++){ System.out.print(j+"*"+i+"="+(i*j)+"\t"); } System.out.println(); }

} } 3华氏和摄氏的转换法 package pm; import java.util.Scanner; public class SwitchTest { public static void main(String[] args) { Scanner sc=new Scanner(System.in); while (true) { System.out.println("请输入要转换的温度类型:C 或F"); String s = sc.next().trim(); if ("c".equalsIgnoreCase(s)) { //做摄氏向华摄的转换 System.out.println("请输入要转换摄氏的温度:.."); double db = sc.nextDouble(); double db2 = (db * 9 / 5) + 32; System.out.println("对应的华氏温度:" + db2 + "F"); } else if ("f".equalsIgnoreCase(s)) { //做华摄向摄氏的转换 System.out.println("请输入要转换华氏的温度:.."); double db = sc.nextDouble(); double db2 = (db - 132) * 5 / 9; System.out.println("对应的摄氏温度:" + Math.round(db2) + "C"); }else if("exit".equalsIgnoreCase(s)){ break; } } } }

Java完整代码

Chapter01——初识Java 1.单词 公共的、公有的:public 静态的:static 主要的:main 打印:print 2.编写类名为HelloWorld的的程序框架 public class HelloWorld{} 3.编写main()方法的框架 public static void main(String[] args){} 4.编写代码输出HelloWorld后并换行 System.out.println(“HelloWorld”); Chapter02——变量、数据类型和运算符 1.单词 字符:character 布尔:boolean 扫描器:scanner 成绩:score 名字:name 2.写出本章节中学习过的五种数据类型 int、double、char、String、boolean 3.创建扫描器对象,并接收用户输入的年龄 Scanner input=new Scanner(System.in); System.out.print(“请输入年龄:”); int age=input.nextInt(); 4.目前有整型变量custNo,请分解出它的个位、十位、百位和千位

int gewei=custNo%10; int shiwei=custNo/10%10; int baiwei=custNo/100%10; int qianwei=custNo/1000; Chapter03——选择结构(一) 1.单词 如果:if 继续:continue 随机:random 数学:math 打断:break 2.如果张浩的Java成绩大于98分,那么老师奖励他一个MP4;否则老师罚他编码, 请补全以下代码: int score=91; if(score>98){ System.out.println(“奖励一个MP4”); }else{ System.out.println(“惩罚进行编码”); } 3.某人想买车,买什么车决定于此人在银行有多少存款。 如果此人的存款超过500万,则买凯迪拉克 否则,如果此人的存款超过100万,则买帕萨特 否则,如果此人的存款超过50万,则买伊兰特 否则。如果此人的存款超过10万,则买奥拓 否则此人买捷安特,请补全以下代码: int money=52; //我的存款,单位:万元 if(money>=500){ System.out.println(“买凯迪拉克”); }else if(money>=100){

Java_QQ_源程序代码

2010-06-23 20:24:11 TiBack import https://www.360docs.net/doc/4017237957.html,.*; import java.io.*; import java.sql.*; import java.util.*; public class QQServer { public static void main(String args[]) { try { //用户名同步(14) HashMap hm = new HashMap() ; // 服务器在8000端口监听(1) ServerSocket ss = new ServerSocket(8000); while (true) { "服务器正在8000端口监听....."); Socket s = ss.accept(); MyService t = new MyService(); t.setSocket(s); t.setHashMap(hm) ; t.start(); } } catch (Exception e) { } } } // 支持多用户登陆(13) class MyService extends Thread { private Socket s; private HashMap hm ; public void setHashMap(HashMap hm) { this.hm = hm ; } public void setSocket(Socket s) { this.s = s; } public void run() { try { // 接收客户端发送来的用户名和密码(2) InputStream is = s.getInputStream();

代码审计报告

一. 概述 1.1 源代码审计概述 源代码审计工作通过分析当前应用系统的源代码,熟悉业务系统,从应用系统结构方面检查其各模块和功能之间的关联、权限验证等内容;从安全性方面检查其脆弱性和缺陷。在明确当前安全现状和需求的情况下,对下一步的编码安全规范性建设有重大的意义。 源代码审计工作利用一定的编程规范和标准,针对应用程序源代码,从结构、脆弱性以及缺陷等方面进行审查,以发现当前应用程序中存在的安全缺陷以及代码的规范性缺陷。 审核目的 本次源代码审计工作是通过对当前系统各模块的源代码进行审查,以检查代码在程序编写上可能引起的安全性和脆弱性问题。 审核依据 本次源代码审计工作主要突出代码编写的缺陷和脆弱性,以OWASP TOP 10 2010为检查依据,针对OWASP统计的问题作重点检查。 点击打开文档OWASP TOP 10 2010 审计范围 根据XX给出的代码,对其WEB应用作脆弱性和缺陷、以及结构上的检查。通过了解业务系统,确定重点检查模块以及重要文件,提供可行性的解决方法。 审计方法 通过白盒(代码审计)的方式检查应用系统的安全性,白盒测试所采用的方法是工具审查+人工确认+人工抽取代码检查,依照OWASP 2010 TOP 10所披露的脆弱性,根据业务流来检查目标系统的脆弱性、缺陷以及结构上的问题。

本次源代码审计分为三个阶段: 信息收集 此阶段中,源代码审计人员熟悉待审计WEB应用的结构设计、功能模块,并与客户相关人员商议、协调审计重点及源代码提供等方面的信息。 代码安全性分析 此阶段中,源代码审计人员会使用工具对源代码的脆弱性和安全缺陷进行初步的分析,然后根据客户关注的重点对部分代码进行手工审计,主要包含以下内容: 输入/输出验证。SQL注入、跨站脚本、拒绝服务攻击,对上传文件的控制等因为未能较好的控制用户提交的内容造成的问题; 安全功能。请求的参数没有限制范围导致信息泄露,Cookie超时机制和有效域控制,权限控制、日志审计等方面的内容; 程序异常处理。忽略处理的异常、异常处理不恰当造成的信息泄露或是不便于进行错误定位等问题; 代码规范性检查 此阶段中,源代码审计人员主要是利用一些代码规范检查工具对网站各功能模块的代码进行合规性检查,主要目的在于提高代码质量,使其更符合编码规范的要求,主要包括以下内容: 代码质量。例如对象错误或不适合调用导致程序未能按预期的方式执行,功能缺失;类成员与其封装类同名,变量赋值后不使用等; 封装。多余的注释信息、调试信息问题导致应用系统信息暴露,错误的变量声明等。 API滥用。例如调用非本单位直接控制的资源、对象过于频繁调用、直接调用空对象导致系统资源消耗过大或是程序执行效率低下等问题。

中国象棋源代码Java程序

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; import java.io.*; public class Chess{ public static void main(String args[]){ new ChessMainFrame("中国象棋:观棋不语真君子,棋死无悔大丈夫"); } } class ChessMainFrame extends JFrame implements ActionListener,MouseListener,Runnable{ //玩家 JLabel play[] = new JLabel[32]; //棋盘 JLabel image; //窗格 Container con; //工具栏 JToolBar jmain;

//重新开始 JButton anew; //悔棋 JButton repent; //退出 JButton exit; //当前信息 JLabel text; //保存当前操作 Vector Var; //规则类对象(使于调用方法) ChessRule rule; /** ** 单击棋子 ** chessManClick = true 闪烁棋子并给线程响应 ** chessManClick = false 吃棋子停止闪烁并给线程响应*/ boolean chessManClick;

/** ** 控制玩家走棋 ** chessPlayClick=1 黑棋走棋 ** chessPlayClick=2 红棋走棋默认红棋** chessPlayClick=3 双方都不能走棋 */ int chessPlayClick=2; //控制棋子闪烁的线程 Thread tmain; //把第一次的单击棋子给线程响应 static int Man,i; ChessMainFrame(){ new ChessMainFrame("中国象棋"); } /** ** 构造函数 ** 初始化图形用户界面 */ ChessMainFrame(String Title){

代码审查的政策及标准要求

代码审核的政策及标准要求 根据IT研究与顾问咨询公司Gartner统计数据显示,75%的黑客攻击发生在应用层。而由NIST的统计显示92%的漏洞属于应用层而非网络层。因此,应用软件的自身的安全问题是我们信息安全领域最为关心的问题。鉴于信息安全发展中所面临的软件安全问题,各个标准化组织及相关管理部门分别从法规、信息安全管理体系建设及行业安全标准等角度对软件进行规范,对软件安全的代码审查工作提出了相应的要求。 1、《信息安全等级保护基本要求》 根据《基本要求》中关于外包软件开发的相关要求,一级要求开始就对外包开发软件在上线前进行恶意代码检测,“应在软件安装之前检测软件包中可能存在的恶意代码”。在测试验收中,提出了对系统进行安全性测试,“应对系统进行安全性测试验收”。在二级要求中,增加了对源代码进行后门检查的要求,“应要求开发单位提供软件源代码,并审查软件中可能存在的后门”。三级要求中明确指出要求由第三方测试单位实施系统安全性测试,“应委托公正的第三方测试单位对系统进行安全性测试,并出具安全性测试报告”。四级要求中增加了对源代码隐蔽信道的安全检查要求, 从《基本要求》关于系统安全性测试要求的变化可以看出,系统安全性测试强度不断提高,在四级要求中增加了对“隐蔽信道”的安全检查,测试机构从无要求转向了三级要求中明确规定的第三方测试单位。一级要求中的恶意代码检测和安全性测试,未明确要求进行源代码层面的安全测试,《基本要求》要求在测试验收时进行必要的软件安全性测试,代码审查可以作为软件安全性测试一项其重要手段,但未进行明确的规定。在二级要求中增加了对源代码进行后门检查及四级要求中对源代码进行隐蔽信道检查,提供了源代码检测的必要依据。 2、萨班斯法案 尽管萨班斯法案没有提及IT或者信息安全,但对绝大多数现代企业来说,财务报告无可避免地会与信息技术联系在一起;换句话说,如果某些关键系统失效了,企业正确报告其财务状况的能力就可能严重受限,甚至短期内丧失。在第404节管理层对内部控制的评价中,强调了管理层对内部控制的系统的责任,在IT审计过程中,审计师必须评估IT控制的设计效力,确定其是否为实现相关声

如何进行代码审查

如何进行代码审查 开始代码审查 从一开始,开发者就会互相帮助,如果测试中遇到了问题或是有新人加入到了团队,领导或是资深开发者就会审查他们的代码。除此之外,我们还聘请了外部专家进行安全代码审查。 系统发布后,我们决定更加主动一些,开始了基于风险的审查:项目中有人会编写一些风险较高的代码(比如说框架与安全代码、APIs、核心业务逻辑或是之前曾经出现过问题的地方),我们会审查他们的代码。在这个过程中,代码审查体现出了它的价值,我们收获颇丰。即便如此,我们还是更进一步,让代码审查成为一个标准的实践。 这并不是一夜之间就形成的。让团队相信代码审查的价值并不是什么难事,他们已经通过基于风险的审查获得了收益。不过要想改变人们的工作方式就不是那么简单的事情了,还要确保他们有足够的时间进行代码审查,理解并对反馈作出响应。此外,设计一个高效的代码审查流程也是需要花时间的。 一开始,我们让开发者选择好搭档并安排审查,但结果却有些混乱。有时,开发者会寻找那些好说话或是比较忙的人,这样审查就比较容易通过了;此外,两个开发者还有可能事先商量好,因此审查过程就会很快结束。由于人们并不知道要花费多少时间才能完成代码审查,因此审查经常会拖得很久,常常在代码已经完成测试甚至是发布后才完成。 由于大多数人并没有太多的代码审查经验,因此他们并不确定在审查时应该看什么,如何给出有意义的反馈等信息。开发者常常会被负面的批评搞得很沮丧,有时甚至会心烦意乱。 最后,我们决定由领导来完成大部分审查工作。虽然这会增加领导的工作量,也意味着他们没有太多时间编写代码了,不过这么做却是很有效果的。通常情况下,主开发者会对需求有着更好的理解,对代码的行为有着清晰的认识,这也意味着他们更有可能发现代码中的错误。由于是同一个人完成了大部分的代码审查,因此被审查的开发者会收到一致的反馈信息。 如何进行代码审查 在过去的几年间,我们进行代码审查的方式几乎没有发生过什么大的变化。 无论是谁编写的,无论代码的功能是什么,重要的代码变更是一定要审查的。我们并没有一个正式的审查会议,也没发现使用诸如Code Collaborator、Crucible等工具有什么必要性,不过现在看起来使用这些工具来管理和追踪审查有助于团队更好的起步。 有时,审查是面对面完成的,不过大多数时候都是离线进行的。审查者与开发者会交换信息,也许通过邮件发送文件,因为我们觉得这种方式更加便捷,也更加方便每一个人安排自己的时间。 随着时间的流逝,审查中的变化之处是审查者该看什么,以及看到的结果。

一个Java小程序源代码

一个Java小程序源代码 一个Java小程序源代码(反转字符串) //BorderLayoutTest.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; public class test1 { public static void main(String[] args) { cloneFrame frame = new cloneFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.show(); } } class cloneFrame extends JFrame { public cloneFrame() { setTitle("机试程序"); setSize(600, 400); JPanel buttonPanel = new JPanel(); buttonPanel.setBackground(new Color(56,43,85));

Button1 = new JButton("点击复制反转字符串"); Button1.addActionListener(new turnListener()); buttonPanel.add(Button1); JPanel textPanel = new JPanel(); textPanel.setBackground(new Color(100,100,100)); field1 = new JTextField("姓名:老孙;学号:2004132028", 20); field2 = new JTextField("反转", 20); field2.setEditable(false); textPanel.add(field1); textPanel.add(field2); JPanel tuPanel = new JPanel(); JLabel label = new JLabel(new ImageIcon("006.gif")); tuPanel.add(label); tuPanel.setBackground(new Color(100,100,100)); Container contentPane = getContentPane(); contentPane.add(buttonPanel, BorderLayout.SOUTH); contentPane.add(textPanel, BorderLayout.NORTH); contentPane.add(tuPanel, BorderLayout.CENTER); contentPane.setBackground(new Color(100,100,100)); } private class turnListener implements ActionListener { public void actionPerformed(ActionEvent event) {

java代码审查V1.0

一、概述 代码审查(Code Review)是消灭Bug最重要的方法之一,这些审查在大多数时候都特别奏效。由于代码审查本身所针对的对象,就是俯瞰整个代码在测试过程中的问题和Bug。并且,代码审查对消除一些特别细节的错误大有裨益,尤其是那些能够容易在阅读代码的时候发现的错误,这些错误往往不容易通过机器上的测试识别出来。 1.1主要工作 1、发现代码中的bug; 2、从代码的易维护性、可扩展性角度考察代码的质量,提出修改建议。 3、是否符合java开发规范和代码审核检查表 1.2 基本流程 1、代码编写者和代码审核者坐在一起,由代码编写者按照UC(Use Case)依次讲解自己负责的代码和相关逻辑,从表现层->持久层; 2、代码审核者在此过程中可以随时提出自己的疑问,同时积极发现隐藏的bug;对这些bug记录在案。 3、代码讲解完毕后,代码审核者给自己安排几个小时再对代码审核一遍。代码需要一行一行静下心看。同时代码又要全面的看,以确保代码整体上设计优良。 4、代码审核者根据审核的结果编写“代码审核报告”,“审核报告”中记录发现的问题及修改建议,然后把“审核报告”发送给相关人员。 5、代码编写者根据“代码审核报告”给出的修改意见,修改好代码,有不清楚的地方可积极向代码审核者提出。 6、代码编写者 bug fix完毕之后给出反馈。 7、代码审核者把Code Review中发现的有价值的问题更新到"代码审核检查表"的文档中,对于特别值得提醒的问题可群发email给所开发人员。 1.3 责任 代码编写者,代码审核者共同对代码的质量承担责任。这样才能保证Code Review不是走过场,其中代码编写者承担主要责任,代码审核者承担次要责任。

java小程序代码

1.从键盘键入三个整数,然后按照从小到大的顺序将其输出。package test; import https://www.360docs.net/doc/4017237957.html,ng.reflect.Array; import java.util.Arrays; import java.util.Scanner; public class Bidx { public static void main(String[] args) { Scanner sca=new Scanner(System.in); int[] a=new int[3]; for(int i=0;i

一个完整的JAVA源程序应该包括下列部分

一个完整的java源程序应该包括下列部分: package语句;//该部分至多只有一句,必须放在源程序的第一句 import语句;/*该部分可以有若干import语句或者没有,必须放在所有的 类定义之前*/ public classDefinition;//公共类定义部分,至多只有一个公共类的定义 //java语言规定该java源程序的文件名必须与该公共类名完全一致 classDefinition;//类定义部分,可以有0个或者多个类定义 interfaceDefinition;//接口定义部分,可以有0个或者多个接口定义 例如一个java源程序可以是如下结构,该源程序命名为HelloWorldApp.java: package javawork.helloworld;/*把编译生成的所有.class文件放到包 javawork.helloworld中*/ import java.awt.*;//告诉编译器本程序中用到系统的AWT包 import javawork.newcentury;/*告诉编译器本程序中用到用户自定义 的包javawork.newcentury*/ public class HelloWorldApp{......}/*公共类HelloWorldApp的定义, 名字与文件名相同*/ class TheFirstClass{......}//第一个普通类TheFirstClass的定义 class TheSecondClass{......}//第二个普通类TheSecondClass的定义 ......//其它普通类的定义 interface TheFirstInterface{......}/*第一个接口 TheFirstInterface的定义*/ ......//其它接口定义 package语句:由于java编译器为每个类生成一个字节码文件,且文件名与类名相同,因此同名的类有可能发生冲突。为了解决这一问题,java提供包来管理类名空间,包实际提供了一种命名机制和可见性限制机制。而在java 的系统类库中,把功能相似的类放到一个包(package)中,例如所有的图形界面的类都放在java.awt这个包中,与网络功能有关的类都放到https://www.360docs.net/doc/4017237957.html,这个包中。用户自己编写的类(指.class文件)也应该按照功能放在由程序员自己命名的相应的包中,例如上例中的javawork.helloworld就是一个包。包在实际的实现过程中是与文件系统相对应的,例如javawork.helloworld所对应的目录是path\javawork\helloworld,而path是在编译该源程序时指定的。比如在命令行中编译上述HelloWorldApp.java文件时,可以在命令行中敲入"javac-d f:\javaproject HelloWorldApp.java",则编译生成的HelloWorldApp.class文件将放在目录f:\javaproject\javawork\helloworld\目录下面,此时f:\javaprojcet相当于path。但是如果在编译时不指定path,则生成的.class文件将放在编译时命令行所在的当前目录下面。比如在命令行目录f:\javaproject下敲入编译命令"javac HelloWorldApp.java",则生成的HelloWorldApp.class文件将放在目录f:\javaproject下面,此时的package语句相当于没起作用。 但是,如果程序中包含了package语句,则在运行时就必须包含包名。例如,HelloWorldApp.java程序的第一行语句是:package p1.p2;编译的时候在命令行下输入"javac-d path HelloWorldApp.java",则HelloWorldApp.class将放在目录path\p1\p2的下面,这时候运行该程序时有两种方式: 第一种:在命令行下的path目录下输入字符"java p1.p2.HelloWorldApp"。 第二种:在环境变量classpath中加入目录path,则运行时在任何目录下输入"java p1.p2.HelloWorldApp"即可。 import语句:如果在源程序中用到了除https://www.360docs.net/doc/4017237957.html,ng这个包以外的类,无论是系统的类还是自己定义的包中的类,

代码审查(Code Review)

代码审查(Code Review) 一、概述 代码审查(Code Review)是软件开发中常用的手段,和QA测试相比,它更容易发现和架构以及时序相关等较难发现的问题,还可以帮助团队成员提高编程技能,统一编程风格等,目前监控团队虽然提倡代码审查,也有相关的辅助工具,但是一直没有真正的推行起来,这半年的时间里,一些线上的bug如果经过代码审查,基本上可以避免的,大家也逐渐认识到代码审查可以有效地提高代码质量。 二、代码审查的作用 1、提高代码质量。 通过代码审查来发现bug及代码中的不规范,这是不容置疑的,通过代码审查,代码将更加整洁,有更好的注释,更好的程序结构。 2、提高开发者开发水平。 开发者知道自己编写的代码会被同事审查,将会更加认真的编写代码,也将会督促开者不断地学习、向有经验的同事请教。 3、提高程序的可维护性。 一份程序代码将会有更多的同事熟悉,更好的代码质量,自

然地也增加程序的可维护性。 4、提高开发者的对编码的责任感。 如果你在编程,而且知道将会有同事检查你的代码,你编程态度就完全不一样了。你写出的代码将更加整洁,有更好的注释,更好的程序结构——因为你知道,那个你很在意的人将会查看你的程序。没有代码审查,你知道人们最终还是会看你的程序。但这种事情不是立即发生的事,它不会给你带来同等的紧迫感,它不会给你相同的个人评判的那种感受。 5、传播知识 在很多的开发团队里,经常每一个人负责一个核心模块,每个人都只关注他自己的那个模块。除非是同事的模块影响了自己的程序,他们从不相互交流。这种情况的后果是,每个模块只有一个人熟悉里面的代码。如果这个人休假或——但愿不是——辞职了,其他人则束手无策。通过代码审查,至少会有两个人熟悉这些程序——作者,以及审查者。审查者并不能像程序的作者一样对程序十分了解——但他会熟悉程序的设计和架构,这是极其重要的。 三、代码审查的执行障碍 1、缺少代码审查的标准 缺少代码审查的标准,往往审查人员习惯性地根据自身开发经验去进行代码审查,容易变成去挑毛病,找bug,容易产生

相关文档
最新文档