qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

Sybase系统维护经验谈

 Sybase数据库系统作为C/S构架的主流产品在我国有着广泛的应用,因此,对Sybase系统的维护也显得至关重要。笔者在对Sybase系统维护工作中,总结了一些技巧和经验,现介绍给大家。

  1、实现开机时自动装载Sybase数据库

  原先要使Sybase SQL Server启动,一般需要先以sybase用户登录,然后运行$SYBASE/install目录下

  的startserver命令启动SYBASE_XXXX服务进程和SYB_BACKUP_XXXX备份服务进程。

  要实现Unix系统启动时就能在后台装载Sybase的功能,我们可在/etc/rc2.d/目录下新建一文件S99sybase,

  内容如下:

以下是代码片段:
    SYBASE=/usr/sybase
  PATH=$PATH:$SYBASE/bin
  export $SYBASE $PATH
  $SYBASE/install/startserver -f $SYBASE/install/RUN_SYBASE_XXXX > /dev/null
  $SYBASE/install/startserver -f $SYBASE/install/RUN_SYB_BACKUP_XXX >/dev/null

  然后修改Sybase的权限,重启系统即可。

  2、实现关机时自动卸载Sybase数据库

  为保证Sybase系统的正常运行,每次在关闭Unix系统时要先结束Sybase SQL Server 的服务进程,从减轻

  系统管理人员操作的角度出发建立一用户halt,修改/etc/passwd文件,将halt用户的uid改为0(或其他可运行

  shutdown的用户id),在/usr/halt/.profile中添加以下语句:

以下是代码片段:
    SYBASE=/usr/sybase
  DSQUERY=SYBASE_XXXX
  PATH=$PATH:$SYBASE/bin
  export SYBASE DSQUERY PATH
  isql -Usa -Pabcabc -ihalt.sql > /dev/null
  shutdown -y -g0

  其中“abcabc”为sa用户的口令,halt.sql是一简单的文本文件,内容如下:

以下是代码片段:
    shutdown
  go

  这样每次只要以halt用户登录,就实现了自动卸下Sybase数据库,然后关闭Unix系统。

  3、Sybase库备份技巧

  一般对Sybase库进行备份都用磁带作介质进行,但还有一更好的方法,即先备份到硬盘上然后经压缩,

  拷贝到磁带上,这样便于恢复,多了一个备份拷贝,同时也节省了备份时间。具体实现步骤如下:

  (1)建立磁盘备份设备

  运行isql,以sa进入Sybase系统,运行如下内容:

以下是代码片段:
    sp_addumpdevice "disk",disk_bkupdevice ,/tmp/dumpdb ,2
  go

  这样就在Sybase中建立了一个名为“disk_bkupdevice”的备份设备,它对应Unix系统下的/tmp/dumpdb文件。

  (2)创建备份用户

  以root身份进入Unix系统,新建用户backupdb,并归属于sybase组。

  (3)修改相关文件

  在/usr/backupdb/.profile中添加以下语句:

以下是代码片段:
    SYBASE=/usr/sybase
  DSQUERY=SYBASE_XXXX
  PATH=$PATH:$SYBASE/bin
  export SYBASE DSQUERY PATH
  rm /tmp/backupdb.Z
  echo"开始备份SYBASE数据库…"
  isql -Usa -Pabcabc -ibackup.sql > /tmp/dbbackup.log
  echo"硬盘备份完成,正在压缩备份的数据文件…"
  compress /tmp/backupdb
  echo "正在将备份的压缩数据拷入磁带…"
  tar c8v /tmp/backupdb.Z
  echo "备份完成!"

  其中"abcabc"为sa用户的口令,backup.sql是一简单的文本文件,内容如下:

以下是代码片段:
    dump database db_main to disk_bkupdevice
  go

  备份的执行日志被记录在/tmp/dbbackup.log中,当然系统管理员也可通过查看$SYBASE/install/backup.log获知备份日志。

  这种备份方法要求硬盘空间足够大,这点请系统管理员在为Unix建分区时特别注意。

  在SCO Open Server 5.0.4、Sybase 11.0.3平台上,以上几个小技巧已应用成功,为笔者的日常维护节省了许多时间,取得了非常好的效果。

posted @ 2011-12-05 13:35 顺其自然EVO 阅读(138) | 评论 (0)编辑 收藏

精解Java中代理模式的实现

  简介摘要: 代理模式是GOF设计模式中的一种,常用于权限模块的架构设计,其根本的原理是通过将一个代理对象交给调用者,使得调用者不能直接使用相应的功能模块,所 有的调用被传递给代理对象,代理对象负责对真实模块完成调用,在调用者与被调用者之间建立了一个隔离带,我们可以使 代理模式是GOF设计模式中的一种,常用于权限模块的架构设计,其根本的原理是通过将一个代理对象交给调用者,使得调用者不能直接使用相应的功能模块,所有的调用被传递给代理对象,代理对象负责对真实模块完成调用,在调用者与被调用者[bei tiao yong zhe]之间建立了一个隔离带,我们可以使用这个隔离带进行权限检查、对象的延迟[yan chi] 加载等功能的实现。这里不对这个设计模式的具体原理多加解释[jie shi],我们直接通过一个实例的编写来完成对代理模式的应用[ying yong],在理解了代理模式之后,我们将继续介绍 java中提供的一种动态[dong tai]代理技术与其实现。

  这里我们假设有一个用户管理模块,这个模块提供了添加用户、删除用户的功能。我们现在要使用代理模式来检查权限该如何实现呢?首先我们需要具有一个类叫User用来表示一个用户的信息[xin xi],代码如下:

  • public class User { 
  •        private String username; 
  •        private String password; 
  •        public User() { 
  •        } 
  •        public User(String username, String password) { 
  •                this.username = username; 
  •                this.password = password; 
  •        } 
  •  }
  •   为了提供功能模块,并且希望能够隔离模块,我们需要设计一个接口来定义用户管理模块的接口,这里我们定义IUserFace接口,代码如下:

  • public interface IUserFace { 
  •        public void addUser(User user); 
  •        public void removeUser(User user); 
  • }
  •   接下来为这个接口编写一个真正实现具体功能的类出来,定义为UserFaceImpl,代码如下:

  • public class UserFaceImpl implements IUserFace { 
  •        public void addUser(User user) { 
  •                //这里处理相关的添加用户的代码任务 
  •                //比如说连接数据库,执行相关的SQL语句 
  •                System.out.println("Add User Successfully"); 
  •        } 
  •        public void removeUser(User user) { 
  •                //这里处理相关的删除用户的代码任务 
  •                //比如说连接数据库,执行相关的SQL语句 
  •                System.out.println("Remove User Successfully"); 
  •        } 
  • }
  •   好了,现在我们对外提供的功能具备了,那么使用者该如何使用这个功能的实现类呢?为了让外界对具体功能类的使用透明化,我们实现一个工厂类来负责创造具体功能模块的对象,并以接口的形式提供外界使用,这样将来更换相关模块的使用将会比较方便。具体工厂类(FaceFactory)代码如下:

  • public class FaceFactory { 
  •        private static FaceFactory instance; 
  •        private FaceFactory() { 
  •        } 
  •        public static FaceFactory getInstance() { 
  •                if(instance == null) { 
  •                        instance = new FaceFactory(); 
  •                } 
  •                return instance; 
  •        } 
  •        public IUserFace createUserFace() { 
  •                return new UserFaceImpl(); 
  •        } 
  • }

  •  完成了工厂类的代码,我们可以使用具体模块,这里我们编写一个App.java来使用以下具体功能模块,代码如下:

  • public class App { 
  •        public static void main(String args[]) { 
  •                User u = new User(); 
  •                IUserFace uf = FaceFactory.getInstance().createUserFace(); 
  •                uf.addUser(u); 
  •        } 
  • }
  •   从上面代码我们可以看到,代码中并没有提及UserFaceImpl这个类,这保证了将来如果需要跟换UserFaceImpl这个类的使用,调用者的代码将不需要做任何的修改。好了,现在我们要来研究一下权限的问题,在这个例子中,我们可能需要在添加用户或者删除用户的时候进行权限检查,符合权限的才能执行相关动作,否则不能执行,那么该如何修改代码才能更加贴切,而且在实际的编写过程中,虽然我们需要权限模块,但有时候为了更好地快速测试,我们常常希望暂时关闭权限模块,如何才能让这样的临时需求变得更加容易处理呢?我们现在使用代理模式来完成这样的任务,现在继续编写一个类叫 UserFaceProxy,让它也实现IUserFace接口,也许你会说,不是已经有一个类实现了这个接口了吗?为什么还要写一个?不要着急,看完这个代码,你就会了解其中的道理了。

  • public class UserFaceProxy implements IUserFace { 
  •        private IUserFace userFace; 
  •        public UserFaceProxy(IUserFace userFace) { 
  •                this.userFace = userFace; 
  •        } 
  •        public void addUser(User user) { 
  •                //在这里检查权限,如果权限不合法则抛出异常
  •                userFace.addUser(user); 
  •        } 
  •        public void removeUser(User user) { 
  •                //在这里检查权限,如果权限不合法则抛出异常
  •                //如果权限通过则完成下面的工作 
  •                userFace.removeUser(user); 
  •        } 
  • }
  •   在代码中你可以看到,这个代理类在构造对象的时候需要传入一个实现了IUserFace接口的类的对象,当代理类对象的方法被调用的时候,首先检查权限,如果权限检查不通过,那么则抛出异常,通过的话则调用构造时传入对象的相应方法]来完成真是的工作。这样的话,我们需要继续修改工厂类的代码如下:

  • public class FaceFactory { 
  •        private static FaceFactory instance; 
  •        private FaceFactory() { 
  •        } 
  •        public static FaceFactory getInstance() { 
  •                if(instance == null) { 
  •                        instance = new FaceFactory(); 
  •                } 
  •                return instance; 
  •        } 
  •        public IUserFace createUserFace() { 
  •                IUserFace userFace = new UserFaceImpl(); 
  •                IUserFace proxy = new UserFaceProxy(userFace); 
  •                return proxy; 
  •        } 
  • }
  •   好了,到这里你是不是已经明白了?通过这样的代理模式我们完成了权限检查的隔离处理,当需要临时关闭权限检查的时候,我们只需要在如上的代码中return userFace;就可以了。这就是代理模式在实际中的应用步骤。


    posted @ 2011-12-05 13:32 顺其自然EVO 阅读(140) | 评论 (0)编辑 收藏

    软件质量保证管理办法

    本文档的目的是为特定产品、项目或合同的质保工作提供指导,帮助项目组其他成员了解质量保证要素,明确质量保证活动,确定质量保证范围。本文档将规定项目质量管理员的职责和权利,资源要求,活动安排,进度,要求质量保证活动中必须生成的文档,反馈问题的方法和频度等。
      一、管理组织
      本公司的软件质量保证活动统一由质量管理员进行管理、检查与汇报,公司相关部门经理及项目中的项目经理、程序经理、开发经理、测试经理、产品经理、测试经理、用户教育经理是质量保证活动中的第一责任人。
      二、软件开发过程
      本公司的软件开发过程分为以下8个阶段:项目策划阶段、需求分析阶段、设计阶段、开发阶段、测试阶段、实施阶段、验收阶段、维护阶段,每个阶段的主要活动分别为:业务启动和项目规划、需求分析、逻辑设计和物理设计、软件开发、软件测试、系统实施及用户培训、用户试用及验收、维护,里程碑分别为:策划完成、需求明确、设计完成、开发完成、测试通过、系统上线、验收通过、合同结束。每阶段结束后,必须对相应的里程碑进行检查,方式为评审或批准。
      三、项目文档
      项目文档分为两种:管理类文档与技术类文档,所有文档必须保存于知识库及相应的VSS库中。文档共有三种状态:编制完成、审核通过、批准通过。其中管理类文档只有编制和批准两种状态,技术类文档拥有所有三种状态。所有文档必须明确说明当前文档版本号。
      管理类文档包含以下类型:计划、总结、报告、会议纪要、备忘录、申请等。技术类文档包含:设计文档、需求文档、测试设计文档、界面原型软件、使用手册、安装手册、技术白皮书、培训资料、源代码、软件产品等。除VSS库中的文档以外,放入知识库中的文档由部门助理统一放入,文档必须批准通过。
      文档的编制、审核、批准可在文档中直接写明,也可使用单独的审批文档进行说明。
      每个项目在不同阶段必须产生的文档如下,但不限于此:
      1、项目开始前:
      合同、技术方案、市场立项表。以上文档存放于知识库。
      2、项目策划阶段:
      业务启动表(EXCEL格式)、项目规划(WORD格式)、项目进度(PROJECT格式)等。必须使用规定模板编写。以上文档存放于知识库。
      3、需求分析阶段:
      需求模型(EA格式)、软件需求规格说明书(WORD格式)、单据报表格式(EXCEL格式)、需求分析评审表(WORD格式)、需求分析计划(WORD格式和PROJECT两种格式)。必须使用规定模板编写。以上文档存放于知识库。
      4、设计阶段
      软件开发计划(PROJECT格式)、逻辑设计(EA格式)、物理设计(VS.NET格式)、设计评审表(WORD格式),必须使用规定模板编写。物理设计存放于VSS库,其它文档存放于知识库。
      5、开发阶段
      源代码、可安装的软件、安装手册、评审表(WORD格式)。源代码、可安装的软件存放于VSS库,其它文档存放于知识库。
      6、测试阶段
      测试用例设计、软件BUG、测试计划(WORD格式和PROJECT两种格式)、测试报告(WORD格式)、开发的测试工具源代码及软件、测试通过的软件产品、软件评审表(WORD格式)。开发的测试工具源代码及软件、测试通过的软件产品存放于VSS库,其它文档存放于知识库。软件BUG存于TD中。

     7、实施阶段
      实施计划(WORD格式和PROJECT两种格式)、实施报告(WORD格式)、用户使用手册、用户培训资料、用户培训记录、软件问题反馈表(EXCEL格式)、上线报告(书面、电子扫描件)等。必须使用规定模板编写。以上文档存放于知识库。
      8、验收阶段
      验收材料、验收报告(书面、电子扫描件)。以上文档存放于知识库。
      9、维护阶段
      维护报告(WORD格式),以上文档存放于知识库。
      四、检查和审查
      本公司的项目关键检查点有以下8个,采取评审和批准的方式,由质量管理员进行跟踪。
      1、策划完成里程碑
      以总经理批准通过业务启动表为标志,质量管理员检查业务启动表、项目规划、项目风险控制计划、项目进度、技术方案文档是否进入知识库。负责人为项目经理。
      2、需求明确里程碑
      以软件需求评审通过为标志,评审通过后由配置管理员建立软件功能基线。项目由用户代表、公司代表、同行、下游人员(程序经理、开发经理、测试经理、用户教育经理)进行评审,评审记录上必须有以上几类角色的人员进行签名。质量管理员检查需求规格说明书、需求模型、需求评审表是否进入知识库。负责人为产品经理。
      3、设计完成里程碑
      以逻辑设计和物理设计通过评审为标志,它包含两个部分:逻辑设计与物理设计。逻辑设计评审通过后由配置管理员建立指派基线1,物理设计评审通过后由配置管理员建立指派基线2。逻辑设计评审参与人员必须包括:公司代表、产品经理、开发经理、测试经理、同行。物理设计评审参与人员必须包括:公司代表、程序经理、测试经理、同行。质量管理员检查逻辑设计、物理设计、设计评审表是否进入知识库或VSS库。逻辑设计负责人为程序经理、物理设计负责人为开发经理。
      4、开发完成里程碑
      以软件所有功能开发完成,并通过评审为标志,它的评审必须包括:公司代表、产品经理、程序经理、测试经理。质量管理员检查评审表是否进入知识库。负责人为开发经理。
      5、测试通过里程碑
      以软件评审通过作为标志,评审通过后将建立产品基线。评审参与人员必须包括:公司代表、产品经理、开发经理、实施经理、用户教育经理。质量管理员检查测试报告、软件评审表是否进入知识库。负责人为测试经理。
      6、系统上线里程碑
      以用户签署通过上线报告为标志,评审参与人员必须包括:用户代表、公司代表、项目经理。质量管理员检查上线报告、实施计划、培训材料等文档是否进入知识库。如上线报告为纸质文档,则扫描后入库。负责人为实施经理。
      7、验收通过里程碑
      以用户签署通过验收报告为准,评审参与人员必须包括:用户代表、公司代表、项目经理。质量管理员检查验收报告文档是否进入知识库,如上线报告为纸质文档,则扫描后入库。负责人为项目经理。
      8、合同结束里程碑
      合同结束,项目跟踪完成。负责人为软件业务部技术服务组长。

      五、测试
      本公司的软件必须通过测试。测试工作由开发部测试组负责,所有测试出来的BUG必须统一存放,由测试组负责管理。在测试活动进行前必须有测试计划,测试完成后必须编写测试报告。测试报告由测试经理负责编写,测试组长批准。
      六、配置管理
      软件开发过程中的配置管理工作由配置管理员负责,配置管理工作详细要求依据《配置管理规范》进行。
      七、媒体控制
      在软件开发过程中产生的正式文档必须存入于知识库中或VSS库中,由公司系统管理员负责每天进行物理备份。在项目进行过程中的备份采用移动硬盘进行,已结项的项目使用刻录光盘存档备份。
      八、质量记录
      质量记录主要包括各种评审记录和审批记录,形式有评审表、签名文件、会议纪要、质量报告等。所有的质量记录由质量管理员统一管理,纸质的保存在指定的文件柜中,电子的保存在知识库中。质量记录的保存期限是3年。
      九、风险和应急
      公司所有的项目必须有独立的风险控制计划,风险控制计划由项目经理负责编写并跟踪,风险控制计划由项目管理部门批准。风险计划中必须包括风险列表、风险度、应急方案、缓解方案、责任人、风险状态。风险度由风险发生可能性和风险造成的危害程度相乘得到。
      十、质量报告
      项目的质量管理员必须在每周五12:00以前制作当前的项目质量报告,报告公司当前正在进行的项目的质量状态。主要包括:项目文档的审核情况、存放情况、完备情况;各里程碑的评审执行情况;各种计划的跟踪情况,责任人是否及时更新计划;各项规范的符合程度;等等。质量报告属于项目状态报告的一部分,与其一同填写。具体格式参见《项目状态报告》。
      十一、质量会议
      质量会议与公司的项目月例会合并召开,开会时必须提交质量报告。参会人员必须包括软件业务部部门经理、产品组组长、实施组组长和开发部部门经理、开发组组长、技术支持组组长、测试组组长、各项目经理。如遇特殊情况,质量管理员可临时针对某类问题发起会议,会议结束时必须有会议纪要并存档。
      十二、工具及技术
      在进行质量保证活动中,主要使用两种工具软件:知识管理系统和MS Visual SourceSafe。前者用来存放项目产生的各种文档,后者主要用于存放源码。公司在所有正式场合中所使用的项目文档均以这两个系统中的数据为准。在使用工具软件的过程中,各项目成员的权限统一由公司文档管理员进行分配。
      十三、变更控制委员会
      公司所有在建项目必须成立变更控制委员会,该委员会最小要包括以下人员:用户代表、市场代表、软件业务代表、开发代表、项目经理,但不限于此。一般情况下,产品经理、程序经理、开发经理、测试经理、实施经理、用户教育经理也可包括在该组织中。对于维护性项目,变更控制委员会由营销中心主任、软件业务部经理、开发部经理组成。

    posted @ 2011-12-05 09:41 顺其自然EVO 阅读(266) | 评论 (0)编辑 收藏

    测试用例及时更新的可实施性

      1、案例描述

      测试团队目前面临一个非常严峻的问题:测试用例得不到有效执行的问题。

      导致此问题的主要原因在于当前的测试用例可用性较差,针对系统原有功能的测试用例主要存在以下三个问题:

      第一,存在较多冗余的测试用例,在测试执行过程中执行此类用例浪费时间而且没有价值;

      第二,存在较多与当前系统实现不一致的用例,此类用例严重误导测试执行人员,并容易造成新加入项目的测试人员对系统理解的混乱;

      第三,存在一些重复的测试用例,此类用例的反复执行虽然可能可以确保某一功能实现的正确性,但确可能造成严重的资源浪费,特别是当此类功能并非系统的主要功能时这样的时间浪费在项目时间非常紧迫的情况下是非常不值得的。

      虽然一再要求测试人员及时更新测试用例,一再强调测试用例的重要性,但仍存在大量的测试用例未能得到有效的维护。

      2、案例分析

      相信每一个做测试的都清楚的知道测试用例对于测试工作的重要性,但是由于主观或客观的种种因素导致很多测试人员或测试组对测试用例的编写/维护不够重视,那么为了让我们的测试用例能够真正的发挥其作用,我们就在此再次重申一下测试用例编写及维护的意义,以及测试用例维护需要注意的问题。

      我们先说一下测试用例编写及维护的意义。

      首先,在测试过程中测试用例可以帮你理清头绪,从而让你能够进行比较系统的测试,避免在测试过程中产生遗漏;

      其次,便于bug的记录及重现,从而方便与开发人员的沟通交流;

      第三,确保对系统功能的全覆盖测试,同时方便将系统使用过程中或测试执行过程偶然遇到的一些问题添加到测试用例中,从而避免以后同样的问题再次发生;

      第四,在测试时间紧迫的情况下,测试用例可以帮你分清重点(前提当然是测试用例中有标注重要程度和优先级),以确保在紧急情况对重点功能的保障;

      最后,测试用例执行情况的记录可以方便测试经理或项目经理及时了解测试进度,以及方便对测试人员的工作效率进行考核。

      基于测试用例的上述作用那就要求测试用例必须与产品功能/特性保持一致,而由于我们的产品在不断地升级/完善,为了确保测试用例与产品的功能/特性的变化保持一致,那就需要我们的测试用例也要不断地更新完善,只有及时进行测试用例的维护才能确保测试用例的完整性和有效性。

      如果不能及时对测试用例进行维护,那将会使其成为一堆废纸,而由于系统需求与设计的不断变更,将导致新加入的测试工程师或对系统不是很了解的测试人员在执行测试用例时不知所措,开发人员在多次被无效的缺陷打扰后,进而导致开发人员对测试人员的信任度严重降低,这对于系统测试工作的推进及合作是非常不利的。

      测试用例的维护是一个不间断的过程,维护的主要内容包括以下几个方面:

      (1)删除过时的测试用例因为需求的改变等原因可能会使一个基线测试用例不再适合被测试系统,这些测试用例就会过时。例如,某个功能被取消了,原来针对此功能的测试就无法完成对新功能的测试。所以,在软件的每次修改后都应进行相应的过时测试用例的删除。

      (2)改进不受控制的测试用例随着软件项目的进展,测试用例库中的用例会不断增加,其中会出现一些对输入或运行状态十分敏感的测试用例。这些测试不容易重复且结果难以控制,会影响回归测试的效率,需要进行改进,使其达到可重复和可控制的要求。

      (3)删除冗余的测试用例如果存在两个或者更多个测试用例针对一组相同的输入和输出进行测试,那么这些测试用例是冗余的。冗余测试用例的存在降低了回归测试的效率。所以需要定期的整理测试用例库,并将冗余的用例删除掉。

      (4)增添新的测试用例如果某个程序段、构件或关键的接口在现有的测试中没有被测试,那么应该开发新测试用例重新对其进行测试。并将新开发的测试用例合并到基线测试包中。

      (5)测试用例需要经常的按其逻辑性对其顺序进行整理,杂乱无章也不利于测试人员的执行,带有一定的逻辑性顺序,可方便测试人员的执行,极大地提高了工作效率。

      3、解决过程

      通过上述分析我们可以看到及时有效地维护测试用例可以最大限度的实现测试用例的重复使用,同时可以最大可能确保测试用例的完整性和有效性。而一份完整、有效地测试用例可以很好的发挥其测试指导的功能,实现其帮助新加入项目人员快速学习了解系统使用的功能,同时还可以缩短用例的编写时间,从而有效提高测试工作的效率。

      基于上述因素的考虑,以及测试组目前已积累了不少测试用例,但长期无人维护,因此现在我们正尝试着在每一个项目的测试计划中安排用例的编写及更新的时间,在每一个项目的测试过程中完成新增功能的用例编写同时,逐步完成早期被复用的用例的更新完善,要求做到被复用的用例至少与当前项目的规格是保持一致的;而对于早期用例与早期版本的相关性则尝试通过技术支持组在做外部技术支持的过程中逐步进行更新完善;当然为了能较好的执行用例的及时更新完善还需要以下配套措施:

      (1)为每个项目组成员指定负责更新完善的某一模块的测试用例,用例的更新完善做为工作内容安排进工作计划,各LTM在制定周计划时考虑用例完善的时间(可以利用固定加班时间完成用例的编写),尽量避免由于时间不够导致的用例更新完善的时间被延后,同时鉴于测试用例编写的工作是可以进行基本的预估的,因此用例编写及维护工作完成的及时性将作为个人工作绩效考核的参考依据;

      (2)要求每个项目组成员在执行用例的过程中发现当前用例与实际实现/规格不一致时,要主动进行确认,若确认后发现确实是用例的问题,可进行用例的修改,修改完成后要求填上自己的大名,同时邮件通知组内其他人员,以便LTM进行用例更新完善有效性的统计,此统计数据将会作为个人工作绩效考核的参考依据;(注:此处的用例有效性包括:所修改的用例修改是否正确、新增的用例是否有助于覆盖当前业务功能的所有逻辑、新增用例是否有助于发现当前系统中的更多bug)

      (3)为了使测试用例尽可能全面覆盖其对应的系统规格及系统实现,无论是新增的测试用例还是维护的测试用例都需要经过组内人员的共同讨论评审。一个人对整个系统/某个功能的理解及经验始终是有限的。测试用例的评审的主要目的就是集众人的经验及认识于一体,对测试用例进行查漏补缺,使得测试用例的有效性进一步提升。因此就要求所有参与评审的人员都要贡献出自己的智慧、积极主动的参与到评审中。同样为了使用例评审能真正发挥其作用,用例的编写/维护人员就需要提前至少一天将需要评审的内容以邮件的形式发送给评审会议相关人员。并注明详审时间、地点及参与人员,而参与评审的人员在评审之前至少简读一遍用例,在会议进行中,会议主持者/会议记录人需记录评审过程中每一个建议/问题以及建议/问题的提出人,而每一个建议/问题都应该有相应的解决方案,只有这样才能真正提高测试用例的有效性。通过用例评审会议的会议纪要考核每一个参与人员对用例评审的积极性,同时此类数据可作为个人工作绩效考核的参考依据;

      (4)为了确保测试用例的正确性及完整性,无论是新增的测试用例还是更新完善的测试用例都需要经过组内资深人员参与的评审,而作为用例编写者/用例的更新人需要负责发起用例的评审,对于当前进行中的项目,用例在完成组内评审后还需进行项目组内的评审,只有经过评审的并且所有参与评审人员达成共识的测试用例才是有效的可用的用例,才是可以指导测试工作顺利进行的测试用例,因此对于当前进行中的项目的测试用例的评审可以利用常规的工作时间进行,从而确保用例的及时评审测试工作的及时进行,而对于一些早期维护用例的评审建议安排常规加班时间进行,从而确保当前测试工作的正常进行,尽可能减少用例评审对当前测试工作的冲击。

      4、解决结果

      希望通过上述努力能使我们的测试用例逐步完善,同时测试人员养成及时更新维护用例的习惯,从而有效地改善我们测试用例的可用性,实现其指导测试的作用,并帮助新人快速学习了解系统的应用,从而有效地提高测试人员的工作效率,同时尽可能通过用例的有效复用缩短项目的测试周期,并提供项目的测试质量。

    posted @ 2011-12-05 09:39 顺其自然EVO 阅读(440) | 评论 (0)编辑 收藏

    边界测试——让BUG现形

      题目:写一个函数,输入一行字符,将此字符串中最长的单词输出。

    #include <stdio.h>

    #include <string.h>

    int main()

    {int alphabetic(char);

    int longest(char []);

    int i;

    char line[100];

    printf("input one line:\n");

    gets(line);

    printf("The longest word is:");

    for(i=longest(line);alphabetic(line[i]);i++)

    printf("%c",line[i]);

    printf("\n");

    return 0;

    }



    int alphabetic(char c)

    {

    if((c>='a'&&c<='z')||(c>='A'&&c<='z'))

    return(1);

    else

    return(0);

    }



    int longest(char string[])

    {int len=0,i,length=0,flag=1,place=0,point;

    for(i=0;i<=strlen(string);i++)

    if(alphabetic(string[i]))

    if(flag)

    {point=i;

    flag=0;

    }

    else

    len++;

    else

    {flag=1;

    if(len>=length)

    {length=len;

    place=point;

    len=0;

    }

    }

    return(place);

    }

      运行结果:

      input a line:             
      I am a student.           
      The longest word is : student

      题目要求“写一个函数,输入一行字符,将此字符串中最长的单词输出”,可是无论alphabetic()还是longest()函数都没有实现“输入一行字符,将此字符串中最长的单词输出”这个功能要求。疑惑很久,发现实现这个功能的函数居然是main()。这就难免让人贻笑大方了。因为按照常规的惯例,要求写一个函数实现某个功能,从来不是要求写main(),尽管不能说main()不是“一个函数”。然而如果是要求main()完成的事情,通常是作为一个完整的问题提出的,不会提出“写一个函数”这样的要求。如果硬要狡辩“写一个函数”也不排除是写main(),就牵强的近乎强词夺理了。不过设若真的有人如此嘴硬,你还真拿他没什么办法。

      既然是不见棺材不掉泪,那就不妨继续往下看。

      在代码中一眼瞄见了flag这个变量。经验表明,凡是有这个flag变量的代码,80%以上都是垃圾代码。道理很简单:首先,多数问题根本不需要设置这个别别扭扭标志变量,只有那些善于把自己的思维扭曲得如同烂麻花一样的人才喜欢时不时地祭出flag这个破烂的法宝。其次,即使需要设置标准变量,优秀的代码作者也不会使用这个含义模糊不清的名字作为标志变量名,而会用一个更贴切、意义更明确恰当更适合描述问题的名字。所以,一般来说,flag往往反映了代码的垃圾度。


      对于垃圾代码,没必要进行过于细致的分析,只要指出错误即可。不要试图了解这种代码的思路,因为这种代码的思路本来就是错乱不堪的,就如同不要试图理解疯子的胡言乱语一样。不要试图修缮一座胡乱搭建起来的破烂不堪的危房,推倒重来才是明智的选择。

      然而,找出程序的漏洞或错误,往往比完成程序要难得多。而且越是垃圾的代码越难查错,因为垃圾代码往往也不具备良好的可测试性。

      但是对付这种可测试性极差的垃圾代码,有一些简单的办法往往非常容易奏效,比如边界检查。训练有素的程序员通常都特别注意边界,无论是写代码时还是检查代码时。因为他们知道这里非常容易出错,而且往往失之毫厘谬之千里。但垃圾代码的作者,由于代码是东拼西补、胡乱拼凑而成的,所以往往顾不上或考虑不到这些,因此垃圾代码很容易被“边界检查”这把小刀轻而易举地戳破。以alphabetic()函数为例,只要简单地考察一下其中if语句所要求的表达式——(c>='a'&&c<='z')||(c>='A'&&c<='z'),就不难发现c<='z'这个子表达式是c<='Z'之误。这样就充分说明原代码中存在着BUG。

      顺便说一下,alphabetic()函数中的if-else语句用得非常愚蠢,因为(c>='a'&&c<='z') || (c>='A'&&c<='Z')这个表达式的值本身就只能为0或1,所以直接返回这个表达式的值就可以了。压根用不着脱裤子放屁地写一个if-else语句。

    int alphabetic(char c)
    {
       return   (c>='a'&&c<='z'
            ||  (c>='A'&&c<='Z');
    }

      或许,有人会认为这是一个简单的笔误或印刷错误,修正了这个错误原来的代码是正确的。那么好吧,下面改正这个错误后再来运用一次简单的边界测试。

      由于问题要求输出一行字符中最长的单词,而一行字符中可能有0个单词、1个单词、2个单词……。注意,这里0个单词的情况就是一种边界情况,运行这个程序并输入0个单词(输入一行不含任何字母的字符,因为代码作者把连续的若干字母字符作为一个单词),后果居然是——运行时程序崩溃了。这个结果绝对可以充分说明原来的代码是错误的。

      这个结果是如何产生的呢?只要在纸上走查一遍,就不难发现,输入一行不含任何字母的字符时,longest()函数中嵌套在for语句内部的if语句将毫无意义地反复执行

        {flag=1;
    if(len>=length)
    {length=len;
    place=point;
    len=0;
    }
    }

      部分,而其中的赋值给place的point却居然是一个不确定的垃圾值。

      应该如何正确地给出这个问题的代码呢?正确解决问题的前提是正确地提出问题。原来问题的提法本身就有很多不正确或不严谨的地方。例如,“将此字符串中最长的单词输出”,这个要求本身就是似是而非很不明确的。比如,字符串中有两个单词长度相同且都长于其他单词,究竟应该输出这两个单词中的任何一个还是需要同时输出这两个单词?再有,要求函数“输入一行字符”也非常无聊。为了能正确地解决问题,有必要对原问题的错误要求进行如下更正:

      写一个函数,输出字符串中的任一长度最长的单词。这里所谓的单词,是指不含空白字符的连续字符序列。

    #include <stdio.h>  
       
    void print_a_longestword ( const char [] ) ;  
    int  be_white  ( const char )  ;  
    int  find_begin( char const [] , unsigned ) ;  
    int  find_end  ( char const [] , unsigned ) ;  
    void output    ( char const [] , unsigned , unsigned ) ;  
       
    int main( void )  
    {  
       printf("%s中一最长单词为:","");            //测试""   
       print_a_longestword("");  
          
       printf("%s中一最长单词为:"," \n\t ");      //测试" \n\t "  
       print_a_longestword(" \n\t ");  
       
       printf("%s中一最长单词为:"," abc ");       //测试" abc "  
       print_a_longestword(" abc ");  
       
       printf("%s中一最长单词为:"," abc \tabcd  "); //测试" abc \tabcd  "  
       print_a_longestword(" abc \tabcd  ");  
             
       return 0;  
    }  
       
    void output( char const str[] , unsigned from , unsigned to )  
    {  
       while(from < to)  
          putchar(str[from ++]);  
       putchar('\n');     
    }  
       
    int find_end (  const char str[] , unsigned from )  
    {  
          while( str[from]!='\0' && ! be_white( str[from] ) )  
             from ++ ;  
          return from ;     
    }  
       
    int find_begin (  const char str[] , unsigned from )  
    {  
          while( be_white( str[from] ) )  
             from ++ ;  
          return from ;     
    }  
       
    int be_white( const char c )  
    {  
       return       c == ' '    ||  
                 c == '\t'  ||  
                 c == '\n'  ;  
    }  
       
    void print_a_longestword ( char const line[] )  
    {  
       unsigned site = 0U ;     
       unsigned begin_longest , end_longest ;  
       begin_longest = end_longest = site    ;  
          
       do{  
          int this_begin , this_end  ;  
             
          site = this_begin = find_begin ( line , site )    ;//单词开头   
          site = this_end  = find_end   ( line , site )     ;//单词结尾        
       
          if(   ( this_end    - this_begin )   
              > ( end_longest - begin_longest ) ){  
             begin_longest = this_begin ;  
             end_longest   = this_end   ;       
          }       
       
       }while( line[ site ] != '\0') ;     
       
       output( line , begin_longest , end_longest );  
    }

    posted @ 2011-12-05 09:38 顺其自然EVO 阅读(138) | 评论 (0)编辑 收藏

    如何在面试时选择合适的测试人员?

     各位,大家好!今天分享一下我在面试测试人员时常问的一些问题及为什么,仅供各位参考,谢谢!

      1、你最近3-5年的职业规划是什么?

      重点考察测试人员的职业发展方向是否与当前职位招聘相符? 从其中可以侧面看出来其员工稳定性。

      2、一个项目测试结束,有没什么经验总结?如果有,具体是如何开展的?

      重点考察测试人员对自己能力提升方面,有没有提高总结的地方,从项目中吸取的经验与教训。从中可以看出来,测试人员是否属行自我驱动型人才!

      3、为什么会选择做测试这份工作

      重点考察测试人员对待测试工作的态度及是否有发展潜力?面试过很多测试人员,经常见到的回答,自己是女孩子,做测试细心,各位你认为这样回答你会满意吗?其码不是我想要的答案!

      4、请说出一个你以前参与项目,对你测试经验提升很高的,具体是哪方面?

      重点考察测试人员在以往的测试工作中能力提升方面,有哪些?然后重点询问此部分内容,是否测试经验增长,具备一定的深度?

      5、通常做测试时会碰到,提交的某个bug开发人员不认同你的观点?这时你如何办?

      重点考察测试人员是否坚持自已的价值观?是否具备协调沟通处理问题能力?

      6、有没有看过什么测试书,具体是哪本?带给你的收获是?

      重点考察测试人员是否为测试这个职业肯付出多少?从中也可以看出这个测试人员是否上进心?是否有求知心?我的定义是如果哪个应聘者来面试时,都没系统的看过一本测试书籍,基本上不会录取!

      7、如果安排一项测试技术研究工作,你如何应对?

      重点考察测试人员是否具体测试技术专研精神?是否喜欢接受挑战?是否属于以后培养骨干对象?

      8、某个项目上线后,出现问题,恰巧你是负责的,你如何应对这突如其来的事件?

      重点考察测试人员应对问题的压力,责任感,及如何处理项目上线后的技术问题及应对解决能力。

      9、周末放假有什么业余爱好?

      重点考察面试测试人员性格特质,测试工作本身就是复杂且富有技术性的工作,而且不同的职位所需要的测试人员性格品质差异性很大。

      10、公司产品,具体应用什么编程技术?具体的架构是?具体的应用场景有哪些?

      重点考察测试人员对以往的工作所负责的产品测试,是否具备一定的深度!通常我都是让面试者自己讲述或是在纸上画出具体系统架构的图!

      11、公司测试团队的规模如何,具体你所处的角色是什么?

      重点考察测试人员在以往的公司测试团队中,具体的工作职责,评判其工作是否与当要求职位是否符合?是否有哪些优缺点?

      12、特定测试技术考察:性能测试,安全性测试,自动化测试等以前有开展过没?如果有,具体是如何实施的?

      重点考察测试人员技术能力,是否在各方面都有所涉及?或是在各方面技术上都有一定深度?当然从中也能看出一个测试人员是否属于是技术路线发展方向!

      13、你自己所期待加入的测试团队是什么样的?

      重点考察测试人员在以前测试团队中有哪些不协调?当然最重要的是也能提供给你一些信息,这个员工以后如何更好的管理与沟通!

    posted @ 2011-12-05 09:37 顺其自然EVO 阅读(155) | 评论 (0)编辑 收藏

    从项目、产品、运营型看发展

     序言:自己身处通信界一段时间,偶然网上看到一些公司的正积极的转型,突然将公司的发展对照着个人的发展以及自己自动化测试工作的进展,深有感悟,也许:一个怎样的公司能持续发展,渐渐在市场上占有一席之地;一个怎样的个人才能持续进步,渐渐的在人群稍有突显;一个怎么的自动化测试策略才能持续提高,渐渐在软件中真正起到至关重要的角色。这都是需要思考的吧。现在就说说自己一点认知吧。
      一、从项目、产品、运营看公司的发展
      首先声明,这些都是我听到的、查阅的再加自己的一点感悟,因为视野局限性,不一定适用,但却是值得去感悟一下;
      在通信业界,公司分为三类,项目型公司、产品型公司以及运营型公司;
      1、项目型公司,项目型公司指那些业务是以项目运作方式为主的公司,其针对不同的客户需求提供不同的项目,排除公司规模性的方面,据说这种公司盈利很辛苦,因为其针对每一个的需求就需要对应一个项目,这就是一个开发成本;然后需要对开发过的每一个项目进行维护,这就是一个维护成本。所以,每一个项目都会耗费大量的成本,成本越高,盈利越少。
      这种项目型公司需要的是将其项目的技术或者框架进行抽象,使得其项目间能够共享、甚至可以将其满足一定需求的项目拓展成产品。
      2、产品型公司,即拥有一定产品型组织结构,针对一定市场有专门的产品线支撑。在通信界。很多设备提供商都属于这类,而产品型公司的追求向服务型公司转型,其服务型公司是以顾客的需求为中心、以产品为载体、为顾客提供端到端的完整服务,其利润总额,提供服务所创造的利润将占很大一部分;例如:看看大家总说的IBM,其Rational的软件产品,你会发现其主要介绍产品的方式是从能够提供的服务方向来介绍的,而其主要服务理念是为其打造一条完整的软件交付平台。
      3、运营型公司,在通信业界,其三大运行商就是属于运营型公司,其需要从网络角度知道网络运行状况,还需要从服务角度知道网络运行状况。此外,他们需要在提供多媒体服务和应用时有效利用网络资源。在通信业界,因为其特殊性,其运营型体制无可替代。但与通信界不同,互联网的特殊性又决定了一个个大型的运营型公司的兴起,他们以互联网资源为优势,打造了一系列的运营平台,提供给广大客户一个享受服务的通道。
      二、从项目、产品、运营看个人的发展
      也许很多人都有过的疑虑,我在这个公司所学的知识出了公司之后是否还能使用?到底如何建立我的核心竞争力?
      1、 项目型个人,即只针对当前公司的状况而获得的技能,而等到了出了这个公司,还需要去学习新的技能。例如:做手工测试,只会对当前公司的产品进行黑盒测试,也许你可以针对这个产品的特性测试的很好,可以出了这个公司,这个技能就不一定适合与另外一个公司了。
      2、产品型个人,即拥有针对一定范围的行业或者公司而拥有的技能,例如:编程的技能、撰写测试用例的技能、性能测试的技能。为什么有一些知识面很广的人却没有竞争力,那是因为就如一个公司,他把市场铺的太大,他也无法去顾及其主要市场,所以一个人不断学习,然后针对其公司和行业需求,抽象出自己的核心竞争力即可。而什么样的核心竞争力,就需要自己对其需求的把握了。
      3、运营型个人,个人认为,此人是一个整合型的人才,也许很多人有疑问,为什么有的人不懂技术,却能位于很高的位置,那是因为他能利用好人力的资源,就像互联网中能利用好互联网资源一样,将其各人的优势进行整合,打造了一个运转的平台。
      三、从项目、产品、运营看自动化测试的发展
      从以后可以联系一下,自动化测试的发展
      1、项目型自动化测试;即脚本开发式,测试开发人员负责给不同测试的测试需求开发不同的脚本,这样就导致了测试开发人员总需要帮助测试人员维护脚本,而且由于开发效率不高,导致自动化测试效果缓慢。
      2、产品型自动化测试,即开发了一系列的自动化测试框架与自动化测试工具,测试人员可以应用这些框架和工具去自己进行自动化测试,测试开发人员只对这些框架与工具负责。
      3、运营型自动化测试,即一个整体的自动化测试平台,这需要与软件产品流程相结合,利用软件开发的资源,把握住软件开发的每一个过程,例如:现在流程的每日构建感觉就是这么一个概念吧。
      总结:以上只是我的个人一些看法,同意或者不同意的都可以一起探讨,我觉得对与不对,都值得思考,思想碰撞才能提高自身的一些眼界吧。

    posted @ 2011-12-05 09:36 顺其自然EVO 阅读(271) | 评论 (0)编辑 收藏

    DB2数据库应用系统性能优化深入探究

      DB2是一种高性能的大型关系数据库管理系统,广泛的应用在客户/服务器体系结构中。评价系统性能优化的标准有:吞吐量、响应时间、并行能力等。
      设计数据库
      1、熟悉业务系统
      对业务系统的熟悉程度对整个数据库系统的性能有很大影响,一个对业务不熟悉的设计人员,尽管有丰富的数据库知识,也很难设计出性能最佳的数据库应用系统。
      2、规范化与非规范化
      数据库被规范化后,减少了数据冗余,数据量变小,数据行变窄。这样DB2的每一页可以包括更多行,那么每一区里的数据量更多,从而加速表的扫描,改进了单个表的查询性能。但是,当查询涉及多个表的时候,需要用很多连接操作把信息从各个表中组合在一起,导致更高的CPU和I/O花销。那么,有很多时候需要在规范化和非规范化之间保持平衡,用适当的冗余信息来减少系统开销,用空间代价来换取时间代价。有订单信息表OrderDetail,它里面记录了投递员信息,收款员信息,物品信息,价格策略,客户信息…..这些信息分别在投递员信息表、收款员信息表、物品信息表、价格策略表、客户信息表中存放。如果按照规范化的要求,OrderDetail查询时就必须要与这么多个表进行连接或者嵌套查询。如果OrderDetail表中的数据量是在百万级的,那么一次查询所需要的时间可能会达到好几个小时。事实上,只要在设计时保证数据的逻辑有效性,很多信息都可以直接冗余在OrderDetail表中,这些冗余的数据能够极大的提高查询的效率,从而减少CPU和I/O操作。
      3、数据条带化
      如果一个表的记录条数超过一定的规模,那么最基本的查询操作也会受到影响,需要将该表根据日期水平划分,把最近、最经常用的数据和历史的、不经常用的数据划分开来,或是根据地理位置、部门等等进行划分。还有一种划分方式――垂直划分,即把一个属性列很多的表分割成好几个小表,比如把经常用到的属性放在一个表里,不经常用到的属性放在另一个表里,这样可以加快表的扫描,提高效率。
      4、选择数据类型
      对每一属性选择什么样的数据类型很大程度上依据表的要求,但是在不违背表要求的前提下,选择适当的数据类型可以提高系统性能。比如有text列存放一本书的信息,用BLOB而不是character(1024),BLOB存放的是指针或者文件参照变量,真正的文本信息可以放在数据库之外,从而减少数据库存储空间,使得程序运行的速度提高。DB2提供了UDT(User Defined Datatypes)功能,用户可以根据自己的需要定义自己的数据类型。
      5、选择索引
      索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。使用索引可以快速、直接、有序的存取数据。索引的建立虽然加快了查询,另一方面却将低了数据更新的速度,因为新数据不仅要增加到表中,也要增加到索引中。另外,索引还需要额外的磁盘空间和维护开销。因此,要合理使用索引:
      在经常进行连接,但是没有指定为外键的属性列上建立索引。
      在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。按索引来排序或分组,可以提高效率。
      在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。
      如果待排序的列有多个,可以在这些列上建立复合索引(compound index),即索引由多个字段复合而成。
      查询优化
      现在的数据库产品在系统查询优化方面已经做得越来越好,但由于用户提交的SQL语句是系统优化的基础,很难设想一个原本糟糕的查询计划经过系统的优化之后会变得高效,因此用户所写语句的优劣至关重要。下面重点说明改善用户查询计划的解决方案。
      1、排序
      在很多时候,应当简化或避免对大型表进行重复的排序。当能够利用索引自动以适当的次序产生输出时,可以避免排序的步骤,当以下的情况发生时,排序就不能省略:
      索引中不包括一个或几个待排序的列;
      group by或order by子句中列的次序与索引的次序不一样;
      排序的列来自不同的表。
      为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表,尽管有时可能影响表的规范化,但相对于效率的提高是值得的。如果排序不可避免,那么应当试图简化它,如缩小排序列的范围等。

      2、主键
      主键用整型会极大的提高查询效率,而字符型的比较开销要比整型的比较开销大很多,用字符型数据作主键会使数据插入、更新与查询的效率降低。数据量小的时候这点降低可能不会被注意,可是当数据量大的时候,小的改进也能够提高系统的响应速度。
      3、嵌套查询
      在SQL语言中,一个查询块可以作为另一个查询块中谓词的一个操作数。因此,SQL查询可以层层嵌套。例如在一个大型分布式数据库系统中,有订单表Order、订单信息表OrderDetail,如果需要两表关联查询:
    以下是代码片段:
        SELECT CreateUser 
      FROM Order 
      WHERE OrderNo IN 
      ( SELECT OrderNo 
      FROM OrderDetail 
      WHERE Price=0.5)
      在这个查询中,找出报纸单价为0.5元的收订员名单。下层查询返回一组值给上层查询,然后由上层查询块再根据下层块提供的值继续查询。在这种嵌套查询中,对上层查询的每一个值OrderNo,下层查询都要对表OrderDetail进行全部扫描,执行效率显然不会高。在该查询中,有2层嵌套,如果每层都查询1000行,那么这个查询就要查询100万行数据。在系统开销中,对表Order的扫描占82%,对表OrderDetail的搜索占16%。如果我们用连接来代替,即:
    以下是代码片段:
        SELECT CreateUser 
      FROM Order,OrderDetail 
      WHERE Order.OrderNo=OrderDetail.OrderNo AND Praice=0.5
      那么对表Order的扫描占74%,对表OrderDetail的搜索占14%。
      而且,一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。
      4、通配符
      在SQL语句中,LIKE关键字支持通配符匹配,但这种匹配特别耗费时间。例如:SELECT * FROM Order WHERE CreateUser LIKE ‘M_ _ _’ 。即使在CreateUser字段上建立了索引,在这种情况下也还是采用顺序扫描的方式,Order表中有1000条记录,就需要比较1000次。如果把语句改为SELECT * FROM Order WHERE CreateUser >’M’ AND CreateUser <’N’,在执行查询时就会利用索引来查询,显然会大大提高速度。
      5、distinct
      使用distinct是为了保证在结果集中不出现重复值,但是distinct会产生一张工作表,并进行排序来删除重复记录,这会大大增加查询和I/O的操作次数。因此应当避免使用distinct关键字。
      6、负逻辑
      负逻辑如!=、<>、not in等,都会导致DB2用表扫描来完成查询。当表较大时,会严重影响系统性能,可以用别的操作来代替。
      7、临时表
      使用临时表时数据库会在磁盘中建立相应的数据结构,因为内存的访问速度远远大于外部存储器的访问速度,在复杂查询中使用临时表时,中间结果会被导入到临时表中,这种磁盘操作会大大降低查询效率。另外,在分布式系统中,临时表的使用还会带来多个查询进程之间的同步问题。所以,在进行复杂查询时最好不要使用临时表。
      8、存储过程
      DB2中的Stored Procedure Builder可以产生存储过程,运行并测试存储过程。存储过程可以包含巨大而复杂的查询或SQL操作,经过编译后存储在DB2数据库中。用户在多次使用同样的SQL操作时,可以先把这些SQL操作做成存储过程,在需要用到的地方直接引用其名字进行调用。存储过程在第一次执行时建立优化的查询方案,DB2将查询方案保存在高速缓存里,以后调用运行时可以直接从高速缓存执行,省去了优化和编译的阶段,节省了执行时间,从而提高效率和系统利用率。
      最优的查询方案按照某些标准选择往往不可行,要根据实际的要求和具体情况,通过比较进行选择。DB2提供的Query Patroller可以对不同的查询方案的查询代价进行比较,通过追踪查询语句,返回查询不同阶段的系统开销,从而作出最佳选择。DB2提供的Performance Monitor也对整个数据库系统的性能进行监控,包括I/O时间、查询次数、排序时间、同步读写时间等等。
      数据库系统的并发控制也能影响系统性能。多个用户的同时操作可能导致数据的不一致性,DB2为了防止同时修改造成数据丢失和访问未被提交的数据,以及数据的保护读,采用Lock机制来实现控制。
      DB2中可以对表空间、表、表列和索引加锁。锁的粒度越大,锁越简单,开销小,并发度低;粒度小,锁机制复杂,开销大,并发度高。大型系统在并发处理中如果遇到所要分配的资源处于锁定状态,系统会把进程挂起等待。如果一个很耗时的查询操作工作于一个经常使用的表上,此时使用表一级锁,意味着整个系统都要等待你的查询结束以后才能够继续运行。所以在复杂查询中,尽量避免使用表一级锁。如果有这一类的需要该怎么办呢?可以利用视图来解决这一类问题。视图避免了对表的直接操作,同时有能够保证数据库的高效运转。

    posted @ 2011-12-05 09:34 顺其自然EVO 阅读(139) | 评论 (0)编辑 收藏

    性能测试报告(实例)

      上一篇博文主要通过两个例子让测试新手了解一下测试思想,和在做测试之前应该了解人几点,那么我们在如何完成一次完整的性能测试呢?

      测试报告是一次完整性能测试的体现,所以,这里我给出一个完整的性能测试报告,相信通过这个报告,我们会整性能测试有个整体的了解,知道我们在以后做性能测试时需要做哪些工作

      注明:1)性能测试报告模板很多,这不是一个空洞的模板,是一个完整的测试报告。

      2)由于商业原因,关于项目明,用XXX代替

      3)我一直觉得,关于性能工具重要,但不是很重要,要学习性能测试,需要了解的知识面很多,工具只是工具,是为我们服务的,会用性能测试工具并不代表你就会做性能测试了

      ----//性能测试报告(某网站用户登陆性能测试)

      1、概述

      1.1 目的

      本测试报告为XXXX网站的性能测试报告,目的在于总结测试阶段的测试以及分析测试结果,描述网站是否符合需求。

      1.2 背景

      XXXX网站,XXXXXX科技有限公司目前正在进行性能测试。考虑到用户数量及数据的增多给服务器造成压力不可估计,因此计划对XXXX网站负载性能测试,在系统配置不变的情况下,在一定时间内,服务器在高负载情况下的性能行为表现,便于对系统环境进行正确的分析及评估。

      1.3 范围

      本次测试主要是XXXX网站系统的性能测试。

      1.1 引用文档

      下表列出了执行测试过程所引用的文档:

    文档名称 

    版本号 

    作者 

    备注 

    XXX系统压力测试方案 

     

    虫师 

     
        
        
        

      2、测试概要

      2.1 测试环境

      下图描述测试该项目所需要的硬件环境:

    客户机 Intel(R) Xeon(TM) CUP 3.06GHz 四核至强处理器、内存:4GB RAM 
    NAS服务器 

    PowerVault(TM) NAS1950,

    四核至强处理器 E5430, 2.66GHz, 2x6M缓存,1333MHz前端总线,80W 数量1

    8GB(2x4G),DDR-2 667MHz ECC 4R Memory

    1TB 3.5-inch 5.4K RPM SATA II Hard Drive with interposer 数量12 

    数据库服务器 Intel(R) Quad Core E5504  Xeon(R) CPU,  2.0GHz,  4M Cache,  4.86GT/s QPI 数量2
    500GB 7.2K RPM  Near Line SAS 3.5” Hot Plug H ard Drive 数量2 RAID
    8GB Memory(4x2GB),1066MHz, Dual Ranked RDI MMs for 1 Processor 

      下图描述测试网络的拓扑结构:

                        客户机测试环境                 服务器测试环境

      测试机与被测服务器在同一局域网进行,排除了网速限制及网速度不稳定性。

      系统采用B/S架构模式,客户端通过中间件访问数据库,中间件和数据库分别部署在两台服务器上。

      2.2 人力资源

      下表列出了所有参与此项目的测试人员:

    角色 资源数量/具体人员 
    测试员 XXXX科技有限公司:虫师 

      2.1 测试工作量

    任务 开始时间 结束时间 总计(天数) 总计(人时) 
    计划 2011-11-19 2011-11-19  
    实际 2011-11-19 2011-11-19  

      3、测试内容及方法

      3.1 测试需求/目标

      在大用户量、数据量的超负荷下,获得服务器运行时的相关数据,从而进行分析,找出系统瓶颈,提高系统的稳定性。

      3.2 测试内容

      本次测试主要是对宝宝足迹网站“首页登录”、后台“成长记录”及网站信息页面访问操作在大负荷情况下处理数据的能力及承受能力。

      测试方法:

    场景 并发用户数量 运行场景设置 测试点 
    登录 200 40分钟 服务器稳定性及操作响应时间 

      注释:所有用户登陆、没有权限限制。

      3.3 测试工具

      主要测试工具为:LoadRunner性能测试工具

      辅助软件:截图工具,Word

      4、测试结果及分析

      4.1 宝宝足迹处理性能评估

      这次测试属于局域网环境进行,排除了外网的网速限制及不稳定性。

      并发登录用户测试

      测试内容:

      这次测试属于模拟真实环境,加入思考时间(think time);用户输入网址登录首页,加入1~5秒思考时间,输入用户名密码,点击登录按钮。



    说明:用户的整个执行流程都录制在Action(循环)部分,所以Vuser_int (开始)和Vuser_end(结束)部分为空。Action_Transaction部分的时间为运行整个Action脚本所需的时间。

      整个Action的平均响应时间为:3.945秒;登录操作的平均响应时间为:1.185秒。

      说明:所有响应事务数为:8720次(个)

      服务器平均每秒响应事件:6.664次/秒;其中登录的平均每秒响应事件为:3.257次/秒

      结果分析:

      此次测试用户操作流程简单,所以并未对服务器造成高度负载,从NAS服务器服务器曲线图来看,0到70%区间浮动,运行相当平稳。从模拟环境来看,加入1到5的思考时间,更符合真实用户的操作。

      从设置200人的压力分析,响应速度很快,完全在用户的感觉快速响应时间内,从整个Action脚本分析,把整个Action时间减去登录时间为:2.76秒,首页的访问时间相比较长,首页部分图片和动画较多,如果用户量访问量继续加大,必定会影响系统性能。

     

     

    posted @ 2011-12-05 09:32 顺其自然EVO 阅读(648) | 评论 (0)编辑 收藏

    java实现后台自动发邮件功能

         摘要: java实现后台自动发邮件功能www.diybl.com    时间 : 2008-09-13  作者:佚名   编辑:本站 点击:  1390 [ 评论 ]web.xml文件 <?xml version="1.0" encoding...  阅读全文

    posted @ 2011-12-01 17:47 顺其自然EVO 阅读(4899) | 评论 (6)编辑 收藏

    仅列出标题
    共394页: First 上一页 353 354 355 356 357 358 359 360 361 下一页 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    导航

    统计

    常用链接

    留言簿(55)

    随笔分类

    随笔档案

    文章分类

    文章档案

    搜索

    最新评论

    阅读排行榜

    评论排行榜