qileilove

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

浅谈软件项目管理之测试

 笔者从事软件行业相关工作将近十年,其中与测试相关时间有7年之久,现浅谈软件项目管理中测试的必要性,供大家参考。

  一、测试的必要性

  为什么需要测试,那是因为由于分工的精细化,软件开发必须经历客户、需求、设计、开发多个环节。为了保证最终的结果符合要求,上下游是需要确认的。

  用户告诉我们:我需要什么?软件企业需要在理解正确、表达正确的情况下完成需求规则说明书,把客户的原始需求转变为IT需求,表达出能够提供什么

  需求的下一环节是设计,设计主要是要要说清楚:我要让软件做什么。需要与前一环节确认理解正确了、设计正确了、表达也正确了

  接下来就是实现了,程序告诉计算机怎么做,最终保证能够运行出结果,而且运行的结果与用户要求是相符的。

  正式因为一个项目参与环境众多,为了保证客户需求在传递过程中尽可能少的丢失,我们需要反复的校验、确认,也就产生了测试。

  传统的观念中把测试定位于从程序员到运行结果这一段,实际上强化每个阶段的确认、特别是用户需求到需求规格的确认,是更能节省时间和成本的方法。

  二、测试管理质量管理之间的关系

  首先回顾一下PMI协会关于质量管理的一些观点:

  第一点就是质量管理的最终目标是使客户满意,质量管理的定义就是理解、评估、定义和管理客户需求,以达到客户期望;能使客户满意的标准就是符合要求且易于使用。这是一个从项目角度出发提出的概念,针对产品研发也应该是吻合的。研发出的产品是为了卖给客户的,不是为了孤芳自赏的,所以研发成果是否满足客户要求也是至关重要的。

  另外一点就是关于功能性符合度和易用性符合的强调,现在很多企业很容易聚焦于功能而忽视软件最终是给人使用,是给不同文化层次的客户使用的,软件的易用性往往能够推翻软件企业为了实现功能所做的一切努力。

  举例来说,有一个项目,需要实现两种产品单据的传递,因为交付工期很短,我们的开发人员加班加点的完成了功能,但是客户却拒绝接收。原因在于引入单据之前需要进行两种产品基础资料的匹配,开发实现了这个功能,却忽视了客户有大概2000条基础资料需要匹配,没有提供批量匹配的功能,最终客户试用中感觉工作量无法接受,拒绝验收了。前面所有加班所有的努力都白费,原因就是忽略客户的易用性需求。

  可能对于产品研发而言,没有这么强硬的结果,但是一些功能不好用对客户满意度的影响还是相当多的。所以个人认为把产品通过测试的标准定位与符合要求且易于使用是非常恰当的。

  第二个观点是预防胜于检查,这是很容易明白,但是实际过程中又不大容易做到的。因为客户的压力,很多企业的发版是很频繁的,发版之后是否有人来总结这次版本研发中碰到了什么问题,哪些缺陷影响了发版时间,下次版本中需要一些什么预防措施?如果没有这样的一个过程,没有缺陷的一套分析和预防机制,很多类似的问题会不断的出现,版本的质量以及补丁的压力会像滚雪球一样越滚越大,最终使得整个研发团队难以负荷。

  第三个观点是关于管理层责任的,提出PDCA循环的戴明就说,85%的质量问题应该由管理层负责,只有15%的责任是团队负责。很浅显易懂的一个道理,假设公司老板对你说,这个版本你一定要保证质量,有一个问题都不能放行!你想这个版本质量能差吗?


  换一种场景,你告诉老板有几个核心问题还没有解决,没有达到发版条件,老板却说,客户压力大,你先发出去,后面再出补丁!结果又会如何呢?

  老板当然不可能忽视客户对工期的要求,不惜一切代价的保证质量,但是当成本和质量进行权衡的时候,老板会偏重哪一个,直接影响最终产品的质量;

  老板在质量文化减少方面、过程改进方面重视的程度,也将直接影响这个公司所有产品的质量。

  这就是管理层的责任!

  提出这个观点的戴明还有一个观点与PMP相关体系非常符合,即质量并不是由工作人员的能力决定的,而是取决于如何开展工作的程序和制度。之所以要进行项目管理的认证,就是要让项目管理的整体能力不因为个人能力产生较大起伏,如果都能按照组织确定的流程进行相关活动,最低水平也能被保证。

  第四个观点是持续改进原则,持续地、渐进地改变来改善情况,中国的俗话也说的好:饭要一口一口的吃,别想一口吃成一个胖子。

  那测试管理到底与质量管理有什么关系呢?

  在量管理活动中,测试是质量控制的重要手段。

  三、测试相关原则

  上图中也提到了测试的基本原则,在此做简单描述,欢迎大家拍砖。

  1、尽早测试原则

  尽早测试原则与马丁分析出来的结论有非常大的关系,一个缺陷在需求阶段被发现所产生的纠正费用是产品交付后维护阶段发生费用的两百分之一。

  有软件公司也曾经做了简单测算,1个缺陷留到客户处被发现,所耗费的成本在50万左右。

  或许引起客户怨声载道的严重缺陷,在需求环节解决只需要增加一行字的清晰描述,在编码阶段只需要多增加几行代码,可是一旦到了客户哪里,便成了投诉、安抚、补丁、责任追究等一系列的紧急事件。

  2、Good-enough原则

  Good-enough原则其实是针对测试本环节来说的,也体现了项目管理思想中关于质量和成本直接的关系。如果以精益求精的思想,能够到底“零缺陷”是最为完美的一种状态。可是从投入产出的衡量来说,零缺陷是很不划算的。理想状态下的测试系统,根据帕累托的二八原则,研发测试应该至少发现80%的bug,而最好只有5%的缺陷是由客户发现的。之所以要推行good-enough的原则,是因为在项目中时间、成本、质量是永远不可调和的矛盾,不论是高层还是基层的测试负责人,软件项目管理人员都需要对自己负责领域进行一定平衡和妥协。

  总而言之,做好了测试的管理,对于软件项目的成本、工期和质量管理都有非常大的好处,但是目前国内的很多软件企业却不重视,特别是针对客户的定制项目,希望未来一段时间能够得到改观。

posted @ 2011-11-21 13:44 顺其自然EVO 阅读(137) | 评论 (0)编辑 收藏

跨出编写300个用例的第一步

接到一个项目,一个大日常,跨很多应用,形成了标准的开发测试N:1,满心欢喜觉得自己终于可以独当一面了。可是当拿到N个UC的时候,就有种瞬间傻眼的感觉。

  但是由于越觉得这个工程很庞大,越想早点开始启动自己的工作,遂会好不容易找到一个突破口就急于开始写用例。

  刚冥思苦想出第一个文件夹的名字后,在这个模块下,想到什么写什么,想不出来的时候,又开始想第二个文件夹的名字,想下一个模块要写什么。当写到第十几个文件夹的时候突然想起第N个文件夹中好像少了一个用例,又每个文件夹,点开看里面的内容,回顾这个文件夹大致覆盖了哪些用例,看看缺少的这个用例该怎么补。也许庆幸的是,找到了那个文件夹补充好这个用例,但是当你写到第几十个文件夹时,过了几天以后,想到好像漏覆盖了什么功能点,那可能不是就仅仅浪费几分钟去找这个文件夹,而是可能会花上大段的时间去回想自己写了什么,这个时候的思路打断就会让你觉得不知道下一步该怎么走,思路越来越乱,下面的用例到底应该以什么纬度进行下去,还有多少的用例被遗漏掉了,什么用例是不需要写,什么用例是需要覆盖的,突然就会对用例有种不可控的感觉。

  但是,如果一个测试人员对自己的用例都无法控制,那还有谁可以来了解用例的覆盖度,用例的纬度。后面的回归测试同学,如何来有序的进行回归,用例的迁移该会是多么痛苦的一件事。

  其实每个人的测试思路会不同,测试习惯也会不同,所以用例可能就会用不同的方式来写。这些都固然没错,但是用例必须要有个纬度划分,有个整体的一个流线。有利于测试,也有利于用例的review及评审,思维可以顺着下来。

  老人是一个很好的灯塔,他可以指引你怎么前进,有时候自己真的一点没有头绪的时候,可以看看以前的用例以怎样的纬度划分,找个较熟悉该应用的老大,问问如果是你,会怎么着手写这些用例。千万不要在自己没有头绪的时候就开始写第一个用例,有可能会越写越乱,写到最后漏了一大片,冗余了一大片。先确定好用例大体以怎么样的几个大方向来写,比如,按照应用来分,sell一块,mickley一块,forest一块;按照测试顺序,先后台建类目,再前台发布,等等。

  确定一个方案还不够的,这个只是个骨架,这些只是好让你定好一级的文件夹名字。不要就开始写用例了,要不然你定好了几个文件夹名字后又会开始不知道怎么入手了,文件夹下要测试哪些东西呢?所以下面的测试设计很重要,列好几个一级文件夹,对照UC看下一级文件夹是什么,一直设计到叶子文件夹要写哪些功能点。最好可以进行测试设计评审,让开发和老人一起评估下,有没有测试用例覆盖漏掉的点,这个时候修改方向,补充漏写的点,很容易,一目了然。

  虽然这可能会花去你一天的时间,你会觉得很可惜,但是这对后面的工作将会有很大的作用,对功能点已经比较熟悉,对用例编写的思路也很清晰,只要对照设计一步一步往下写就可以了,就不用说动不动就停下来绞尽脑汁在想要写什么东西,尤其是对新人来说,对已有的用例也不熟悉,不知道到底应该写哪些用例,需要测试哪些点,这个就尤为重要了。

  300个用例并不可怕,但是不可控的100个用例就会让人很昏头转向。定好方向,做好设计,建好层级,个个攻破,500个用例都将是可控的。

posted @ 2011-11-21 13:44 顺其自然EVO 阅读(141) | 评论 (0)编辑 收藏

B/S架构测试环境搭建_SybaseASE篇(Win32系统)

 前言:测试过程中需要使用SybaseASE数据库,抽空安装测试下,由于是摸索,也遇到些问题,刚入门,不对之处还请多多指教。

  一、创建服务器:

  (1)在安装的结束阶段Sybase ASE已经提示创建服务器了。如果接手的是别人的环境,那么先创建,在开始-->所有程序—>Sybase—>Sybase Central v4.3,打开Sybase Central界面如图一,点击“实用程序”,查看其详细,双击“服务器配置”打开其配置服务器的对话框。

图1 Server服务器配置页面

  (2)点击创建服务器,输入服务器名称,进入服务器页大小,这个根据Sybase的使用情况来选择,如果使用量比较大的话建议选择8K或者16K,只是一般使用的话4K就可以了。

  (3)接下来是设置Master(系统数据库)设备大小和位置,此处有Master的初始数据,你可以使用,不过如果你不是第一个建立这个服务器的话,还是选择一个自定义的比较好。如果使用别的服务器的Master,其他服务器的系统数据库将被覆盖,导致别人的服务器无法被正常使用。

图2 设置Master的大小和位置

  (4)接下来设置系统过程设备大小,系统都提供了缺省值,如果需要修改又不知道是否正确,帮助中有有关此处的详细说明。继续后设置系统DB的大小,个人觉得设置5M就可以了。毕竟系统数据库在创建完成后不会有大的动作了。

  (5)接下来就是配置缺省的XP服务器了(网络地址),默认情况下当然是指向本机了,除非你保证你的默认Server永久性开机,否则最好还是本机,方便出问题时快速检查。点击“配置默认服务器”-->网络地址—>增加,协议选择TCP,输入本机IP,两次确定后设置完成。

  创建数据大约需要一分钟,创建完成,在Sybase Central页面上测试连接。

图3 测试连接

  系统有默认的用户sa,没有密码。

 二、创建数据库:

  (1)前面已经提及,在创建服务器过程中附带创建的是系统数据库,日常测试使用的用户数据库需要单独创建。在创建数据库之前,我们需要先创建数据库设备,相当于表空间(和Oracle有那么点区别,Oracle是建用户(Schema)时用的Default Tablespace,此处是建数据库时选择存储空间),填写对应的大小,序号系统会默认分配,不用管。

图4 使用创建的数据库设备

  (2)创建数据库,此处即没什么需要注意的地方了,选择刚刚创建的数据库设备,并填写该数据库需要使用的大小,其他按照提示一步步走完数据库就创建成功了。

  三、创建用户及授权:

  (1)首先创建登陆名,在登录选项中添加新的登录名,输入密码,选择默认的数据库,提交完成。

  (2)双击刚刚创建的登录名,在“角色”一栏中给其授权。

  (3)我们可以看到在登录名最后一栏中的用户,用于该登录名映射的用户名。再打开数据库查看,果然,里面有用户和允许对用户的CRUD和对用户的分组(缺省的是public组)、授权。和什么数据库很像?对咯,SQLServer。登录名和用户名的区别和联系已经在前一篇讲过,不再啰嗦。

  至此,SybaseASE的表空间(数据库设备)、数据库,登录名、用户已经创建完成,以后会把常用的SQL语句总结放上来,方便我们的环境更好的工作。

posted @ 2011-11-21 13:37 顺其自然EVO 阅读(228) | 评论 (0)编辑 收藏

B/S架构测试环境搭建_SybaseASE篇(Win32系统)

 序言:什么是自动化测试平台?这个是没有一个好的定义的,个人拙见,自动化测试平台就是根据自身公司或者部门的流程,将自动化测试的需求融于上述测试流程,然后提供一个软件平台的形式表现出来,也就是用规范和协议的形式表现出的一套自动化测试体系。

  一、编程工具中的“即插即用”型

  Eclipse平台是IBM向开发源码社区捐赠的开发框架,其是一个成熟的、精心设计的以及可扩展的体系结构。这个平台允许任何人构建与环境和其它工具无缝集成的工具。工具与Eclipse无缝集成的关键是插件。除了小型的运行时内核之外,Eclipse中的所有东西都是插件。从这个角度来讲,所有功能部件都是以同等的方式创建的。

  你可以在安装好的eclipse的文件夹下有一个plugins的文件夹中有其各种插件,eclipse的核心较小,几乎都是由插件组成,而所有的插件库有四个基础库:

  ● 标准Widget工具包(SWT):Eclipse中处处使用的图形化组件:按钮,图像、光标、标签等等。布局管理类。通常这个库被用于代替Swing。

  ● JFace:菜单、工具条、对话框、参数选择、字体、图像、文本文件的类和向导基类。

  ● 插件开发环境(PDE):辅助数据操作、扩展、建立过程和向导的类。

  ● Java开发者工具包(JDT):用于编程操作Java代码的类。

  基于这个基础库,然后遵照其eclipse开发插件的过程,你就可以将自己的工具与eclipse集成起来,即根据自己的需要去定制自己的开发平台的需求。

  二、软件交付平台的“即插即用”型

  IBM其软件产品有一个词叫jazz,之前很不理解这种想法,后来慢慢的为其庞大的理念而感到心动,虽心动却也只能研究一下。

  Jazz是一个用于整个软件生命周期的团队协作平台,旨在支持跨所有软件生命周期阶段的任务的无缝集成。Jazz平台的主要作用是为工具编写人员提供要使用的机制和要遵循的规则,这些机制和规则可产生无缝集成的生命周期工具。这些机制通过定义良好的API来公开。

  Jazz是一个基于客户端-服务器体系结构的平台。通常在受保护的服务器级计算机上运行的Jazz服务器承载一组服务,并在其存储库中存放数据。远程客户端通过网络使用HTTP与Jazz服务器通信。

  个人理解的话:jazz提供了一个开放式的平台,其中基于了一些国际上的组件规范(例如:OSGi等,OSGi称做Java语言的动态模块系统,它为模块化应用的开发定义了一个基础架构。这样,一个大的系统可以被划分为很多模块或组件,其通过标准化的接口进行交互通信),然后,IBM的大多数工具可以集成到这个平台上成为软件交互生命周期的一个整体,尽量使得各个工具在使用上能够进行交互,之后,可以根据自身的开发流程情况,基于软件实现定制自己的开发和交付流程。

  三、自动化测试平台的“即插即用”型

  自动化测试中因为其应用特殊性,所以,会有各种工具的使用(界面测试工具、命令行测试工具等)以及各种自动化测试的模式(例如:回归测试、例行测试等)来提高测试效率。所以,个人觉得,自动化测试也需要提供一个开放式的平台来集成这些工具和测试模式。

  可以参考的是:开源的自动化测试框架STAF,其提供了一个“即插即用”型的概念,任何工具或者模块只要遵从其规范,则能作为其中的一个服务与构建与其上的各种服务进行通信。其还是作为一个分布式的框架,其意思即每台运行STAF的机器都是等同的,都可以拥有各自的功能模块与数据,也可以在分布式网络中进行共享与交互。或者,不基于STAF也可以自己进行类似框架的开发,需要的是提供一个标准的接口形式,各个模块能通过这个标准的接口互相进行交互。

  当然,以上的形式需要根据自身的情况来定,是在自动化测试需求发展到一定程度上,如果连自动化测试需求和流程都没有定义下来,那么,开发这套平台的意义将会变得很空洞,而且容易脱离实际需求,反而越走越远,浪费了成本,所以,“效率为上、需求为导”,不同的时候应该采取不同的策略来应用自动化测试来提高自身的测试效率。

posted @ 2011-11-21 13:24 顺其自然EVO 阅读(644) | 评论 (0)编辑 收藏

我对软件测试行业的看法

 有几个文章大概的题目如:

  软件测试行业缺口多少多少万;
  软件测试人员比博士还值钱;
  软件测试越老越吃香;
  软件测试是金饭碗;

  等等等等。

  以下是我的一些个人看法。

  1、行业

  我们都知道媒体的报到都是因为一些利益驱动的,并不是为了良心和行业的良性发展,要是从工作的角度来说,我觉得他们很到位,但是少了一点,就是社会责任心。做为一个有良知的知识分子,我觉得应该说点事实,不要把一个本来挺好的行业最后糟蹋的不像样子。做为一个软件测试从业人员(我从一毕业就开始做软件测试),我觉得这些都不靠谱。

  在我的记忆中,跟测试同行聊天时,软件测试行业的缺口是一个所谓的牛人被媒体采访时问到的。但是这个牛人,自己也没有做过统计,于是乎,两眼一转,把心一横,在我不知道别人也不可能知道的心态下说出了这么一个数据:大概30万吧。实际上,这个数据没有经过任何公开的媒体调查(如果调查了后,就是这个数据,我觉得还有点借鉴意义)。结果就被一些写手们越扯越大。反正写错了,也没人打屁股,要写就要引人眼球,可劲的造吧。这种鼓吹的结果就是让一群人很盲目的进入了这个行业,结果发现根本不是那么一回事。于是经常看到有人问,我什么什么经历,转测试行不行呀?就有些人很不负责任的回答:只要努力,就行!我靠,也不想想,人家那么多年的其他行业的经验,为什么还要转测试呀?工资也不见得就高(这个问题稍后细说),也不见得轻松,上升空间也不见得有原来的行业多,干吗要鼓励人家换这个行业呀?(排除有些人骨子里就喜欢测试这个行业的。另:大部分人工作还是工作,并不是当成事业来做的,所以谈不上对哪个行业有非常深的兴趣)。

  所以在选择这个行业的时候,还是需要理智的思考的,曾经有一个朋友,工作大概四五年了,做过:网管、保安、保险推销等等的工作,技术基本没有积累。问我:我能不能转行做测试?我问了他一些基本的计算机知识和测试的基本知识,我说:你还是别转了,不如做点其他的事情。不过我也说了,我只是提个你不要转的建议,你要是非想转,我也可以告诉你要学什么。在很多情况下,我觉得更理性的思考才说出建议和决定比较合理,不要以为有了一份心就什么都有了,两码事。因为人的激情是有时间间隔的。

  测试人员的素质要求。可能是因为我进入了这个行业,老是有人在说这个行业的人需要什么样的技术和素质。大多数的都会提到一个字眼:浮躁。就是测试人员切忌浮躁。我晕,什么人不忌浮躁呀?这是对人的基本素质要求,而不是对测试行业的人的素质要求。可能有人说了,测试嘛,要细心,浮躁了就不能细心了。这种说法貌似合理了。但是,这绝不是测试人员的核心要求。极端一些说(因为极端的假设可以让问题更清晰),如果一个人只有细心,你是测试招聘人员,你会招吗?那这里就涉及到另一个问题了:就是要有技术。什么是技术呢?测试行业什么是技术呢?突然有这个问题似乎让人不知道怎么回答,有一种满肚子都是话突然之间倒不出来的感觉。于是,冷静一会,这种喜欢吹嘘的人就会摆出一堆话来:测试理论呀、测试方法呀、测试工具呀、测试流程呀等等等不都是技术吗?在我有限的知识体系里,个人觉得,这些都不是技术,只是测试人员应该有的常识。测试工具的使用只是测试人员应该掌握的技巧。

  2、薪水

  薪水的诱惑。我看到过很多次说软件测试行业薪水如何如何高?XX出来不是八千就是五千的。还有人说,软件测试行业是IT中最高薪的行业,越老越值钱!我个人觉得软件测试行业绝对不是常青树。也不可能越老越值钱。现在做软件测试,找工作的人,一堆一堆的。好好看看这个市场,它不是缺少要做软件测试的人,而是缺少有经验的人。并且一般的经验,也不值什么钱。工作三四年(甚至更多)的人,5-6千的人,大有人在,而不是像有些广告上说的,这个行业进来就是万儿八千的。以为是找BUG是捡钱玩呀?我遇到的做测试的,工作十年左右的,也不过是在万元左右。人家这么多年都是白混的呀?在软件测试行业,从纯技术的角度来说:能拿到2万/月的人,很少很少。(请不要以某个个例来反驳,因为个例没有意义)。有些人挤破的头皮进外企。从大局来看(仅个人观点),外企在国内就没有真正把技术拿进来过(这里应该说大部分,不能一棍子全打了),所做的也无非是些边边角角的苦力活。所以外包才有市场,才会发展起来。几乎我认识的所有的测试行业的人都说外包没有技术含量,国内的外企难道不像外包吗?只是形式不同罢了。就拿中国的某些制造业来说,也有一部分属于这种状况,结果金融风暴来了,人家倒了,你也倒了。曾经有不止两个在软件业混了十几年的人跟我说:中国没有什么技术(我知道这句话有失偏颇,但它反应了一些现状)。再回到软件测试这个行业,首先,我认为刚毕业的大学生,不要指望一下子能爬多高。走的不稳总有一天摔倒。如果家里特有钱,像我一华为的同学跟我说的,那里有开着奔驰去上班的,一个月拿几千块钱的。人家那是自我实现追求。而我们大部分的人,还是老老实实的,想想这一生应该怎么过,才能买得起房子,买得起个二十万以下的车吧。软件测试从业人员,自己把自己一辈子能赚的钱都算算。你这一辈子的闲钱能达到十万吗?你敢乱花乱玩吗?你没有先消费后还贷吗?这是时尚,还是不得已而为之?是你的能力不足,还是这个行业已经限制了你的上限?就算是你到了级别,有多少人可以到副总?有多少人是技术总监?就算你是技术总监,又有多少公司的技术总监一年超过30W?我出来工作两三年之后,就有人说,我的工资涨的飞快。我个人在想,这些钱,还不够我的生活。因为我也要买房,买车,生儿育女,赡养老人。有没有想过这些事情,如果全压在你和你老婆(老公)身上的时候,多少的薪水够用的?有人也说了,有钱就过有钱人的生活,没钱就过没钱人的生活,反正过穷富不是一样过吗?一辈子很快就过去了。这种说法是无奈还是满足现状?说的时候心酸吗?看着自己的孩子和别人的孩子上的不一样的学校。玩的游戏没有人家玩的好,你什么感觉?就告诉自己,我的能力只能是这样了吗?选择一个行业,你就要知道,这个行业的薪水段在什么样的层次,就像一个同事跟我说的:一个片警拿一个包出去赌钱,里面都是几百万的人民币。你是不是遗憾自己选错了行呢?当然不能这样对比对吧。因为我们靠自己的能力,吃自己的饭。呵呵,这么对比一下就是要看这个文章的人想清楚,你想拿多少工资?这个行业能给你的只有这么多,你自己选择去吧。当然,也要看清楚的是,这个行业,比出去在大太阳下搬砖强多了。

  好吧,薪水暂时靠一段落。


 3、技术

  技术,真实认真做软件测试的人应该有这样一种感觉。软件测试不容易做。它需要的知识太多了。如果仅玩数据库,只要把oracle搞的特别精通,我想一年工资二十万应该没有什么问题吧。但是软件测试行业是你要把好几种工具和语言都玩精通可能才值那么多钱。就拿性能测试来说吧(因为这一块是我一直做的,拿来打比方应该偏差不会太大),你只会性能测试工具就敢出去要万元/月以上的工资了吗?你敢要,谁愿意给呀?别以为自己可以是根葱了,其实还没发芽。我们都知道,在软件测试行业的JD一般都是:OS/network/DB/tools/applications/middleware、还有一些语言呀,脚本(脚本也是一种语言这里分开一下)呀,都包括的,就算不全包括,也要有一部分。你得懂呀?不懂全部,你得懂几个吧?你不懂,有人懂呀。那工作机会不就没了吗?怎么办呢?学吧。每天晚上搞到一两点,死劲的玩这些东西,大概找工作的时候,可以跟人侃了。我这个也会了那个也会了。但是呢,不能问深。因为学的广嘛。所以哪有时间细细的琢磨呢。所以问深了就晕了。人家一看,唉,这个人不求甚解,算了吧。也许很巧合,面试了一家公司,人家问的,也都被你忽悠上来了。总算找一工作。也是刷了好多人的。要是能把上面所说的每个东西,都玩了个精通,那出去找工作,问什么会什么,太牛B了。但是公司毛了,这样的人,我们能养得起吗?这种情况很少出现,我们就不去说它了。还要说软件测试行业。其实我们也知道,软件测试行业,在要求广泛的同时,也开始慢慢细化。越来越强调专向发展的人。所以,在进入这个行业的人,不要指望能把所有的公司JD都拿得下来,你只需要考虑是不是能满足其中一两种就可以了。并且仅这一两种也大概够你玩个十多二十年的。到那时,你已经不值钱了,因为还有一堆堆的年轻人在嗷嗷的叫着找这类的工作。国内工作到四十岁的技术人员,还有纯干技术的吗?(当然是有的,这里我说的是大部分情况下)我也有纯技术做了一二十年的同事,他自己也说他这种现象不正常。(这个和国家的福利待遇等都有关系,我这里不再展开说了。)

  4、追逐

  追逐,如果从现在的大学生失业率来看的话,进入这个尚末成熟的软件测试行业,不见得是件坏事,因为乱世出英雄嘛。当然,在出英雄的前提下,就会有些怀才不遇的人很快的被糊里糊涂地砍倒在战场上。所以进入这个战场,就做好看清流弹的准备。不要报怨,认真的走好自己的路,不要和别人对比,因为不成熟的市场是没有什么可比性的。技术路线和泡沫市场的路线差距还是很大的。当然IT的技术路线和传统工业的技术路线差距也是很大的。我们基本上也算是产业工人的一部分,但是,我们并不是越老越值钱,如果不尽快在自己老到被人推倒在沙滩上之前赶紧找到自己的位置,相信在自己没有可利用的价值之后,很快就被淘汰。一个人被利用并不悲哀,悲哀的是没有可利用的价值。从比较职场的语言来说,我们之所以有工作,是因为老板们或者领导们认为我们还可用,想拿的工资更多,就让领导们觉得我们还有更多可用的地方。所以,尽量的去追逐那些在市场上看来有价值的知识,从而让自己的打工路,更平坦。(如果不想打工的话,那就追逐当老板应该有的知识。)不过,要注意这条路上,重点要知道自己追逐的是什么,而不是随大潮,看着别人玩什么自己也玩什么。很快那些大众型的知识都不值钱了(IT的更新也是很快的),所以要找准自己的位置。

  谨以此文,描述个人对测试行业的看法。如果打击到某些人或某类人,请见谅。

posted @ 2011-11-21 11:59 顺其自然EVO 阅读(1163) | 评论 (0)编辑 收藏

敏捷测试理论以及实践(6)

  2、编码阶段:

  完成了需求设计阶段,就要开始进入编码阶段了,虽然说开发与测试需要同步的,但是功能还没做完也没法同步去测吧,不过还是有事做的,就是可以同步开始写测试用例,这个就用到DevTest工具了。DevTest主要用于管理测试用例,以及根据测试用例来进行在不同环境下、不同时间下和不同的范围里进行的手动测试与自动测试,并且可以生成报表供评估测试质量和产品质量。

  也许有人有疑问,敏捷测试还需要测试用例?我的答案还是“是”又“不是”。

  先说“不是”,对于敏捷测试本身而言,我们实际新功能测试中其实没有用到测试用例,完全是根据设计文档来进行测试的(也许又有人来问敏捷好像不需要测试文档,这个在这里不多说,详见我另外一篇文章《结合工具来实现敏捷开发》),所以这个时候是不需要测试用例的;

  而为什么又说“是”呢?因为敏捷在不同的公司不同的情况可以有不同的实现方式,我们公司不是做项目的而是做产品的,也就是说像微软Windows一样,我们公司的产品也是1.0,2.0这样做下去,现在已经9.0了,在这期间,或多或少有很多功能是在不同版本里都有的,特别是那些基本功能,为了测试新功能是否破坏原有功能,我们需要测试这些老功能是否能正常工作,也许有人说,那我只要在测试新功能时测一下老功能就行了,测试用例也不需要吧?是的,也许你们公司不需要,但是对于我们公司而言,特别对于9.0而言,之前所有版本的功能都是老功能,之前的老功能有几百个,几千个,你能在测试新功能时测一下吗?很显然,这个是很难做到的,新功能做完时,一般情况,测试人员会检查是否能正常工作,是否对一些基本功能没影响,至于对其他看起来不怎么搭嘎的功能其实不太会去关注,而且时间上也不允许。这样子的话,测试用例就显得很重要了,因为测试用例从本质上来说就是介绍需要测试的功能点以及怎么去测试它们,把每个版本的每个的功能点都通过测试用例的方式保存下来,测试时想漏掉一个测试点都难。所以测试新功能时没测到的地方,都可以在用测试用例生成测试任务时重新覆盖全面,不过这一步由于测试覆盖面太广,也就意味着所花时间会很多,所以一般情况下,一部分测试点会用自动化测试工具跑掉,另一部分只能人工来跑的也只在最后系统测试的时候做掉。

  看了这个“是”与“不是”,大家应该知道我们公司的“敏捷测试”其实是结合了敏捷测试与传统测试,也即是兼顾速度与质量,所以有时候我们称之为有我们公司特色的敏捷测试,呵呵。

  在写测试用例的时候,测试人员需要和设计人员进行大量的沟通,以彻底理解这个功能为接下来的实际测试做好准备,“沟通”在敏捷里是一个重要的原则,在实际工作,我们也真正体验到它的好处,只有通过沟通,几个部门之间对于产品才有一个认识高度上统一,才能设计出、开发出、测试出一个好的产品来。不过这点,我觉得大家也只能真正通过实践才能体验,我说得太多,其实也没法让大家信服的。

  3、敏捷测试阶段:

  好了,写完测试用例了,开发也做完几个功能了,咱们也可以开始测试了,《结合工具来实现敏捷开发》里也讲过,我们公司是采用Scrum方式的,所以会生成很多迭代周期(Sprint),每个迭代周期中会从Backlog里分配一些Story来做,咱们测的也就是做好的Story,其实也就是功能点了。

  这部分工作主要在DevTrack中完成

  DevTrack的主要用于开发完成功能点编码以及测试人员完成敏捷测试。当需求设计完成后,项目经理会通过DevSpec/DevPlan来分配开发任务给相应的开发人员,并且同时生成敏捷测试任务,而开发一旦完成功能以后,就会在DevTrack中把相应的敏捷测试任务打到“可测试”状态,这样子,测试人员就开始进行测试了,测试完了,就把任务关掉,这个功能点就算测试完成了,项目经理会通过检查测试任务是否已经关掉来判断这个功能是否已经完成。

  由于之前测试人员已经把当前迭代周期中的功能点写成测试用例了,对于做好的功能点其实已经从理论上很了解了,所以测试起来就“轻车熟路”了。测试总会发现Bug,但是Bug有严重和不严重之分,我们现在处理Bug的原则是,对于影响到这个功能让客户评估的Bug都必须在这个迭代周期和下个迭代周期中修复,这些Bug可能包括报错,功能彻底没法工作,也可能包括一些页面上的美观,因为我们的产品会定期给客户做评估,以让客户看看做完的功能是否符合他们的要求,所以对于做好的功能点起码需要能让客户能用起来,所以客户会最直接用到的看到的地方就需要优先处理掉。而对于其他普通的Bug,DevTrack会有专门的一个文件夹保存,这些Bug会在Release之前通过优先级来一一进行修复,有些实在优先级很低的或者暂时不能完成的可能就会推迟到下个版本再做或者直接就不修了,因为有时候修一个Bug可能会带来一些意想不到的问题,如果可修可不修的Bug,就不需要冒影响产品质量的风险去修了。

  不知道大家有没有注意到,上面说了Bug需要在这个迭代周期与下个迭代周期中修复,为什么不在这个迭代周期中修复呢,其实是这样的,因为测试总是在开发后面开始的,如果一个功能点在一个迭代周期的后期完成,从时间上可能测试无法在这个迭代中完成,但是迭代周期的时间又不是想改就可以改的,所以这种情况下,我们就会在下个迭代周期中把这个功能点测完。不过一般情况下,我们还是建议不要延迟到下个迭代周期中完成,因为一个迭代完成后,我们会给一个Build给客户做评估,如果有没测试完的功能,可能就有一些潜在的影响客户使用的Bug,这样子对销售就会产生不好的影响。所以,解决的方法就是一个功能点开发完成就必须马上让测试测,发现Bug马上修复,如果有功能点到了迭代末期才做好,则已经Check In代码确保没有严重Bug(主要是表明和这个功能最基本的使用),没有Check In 代码的就等到下一个迭代周期再Check In代码,测试也推迟到下个迭代中测试。

  就这样子,迭代周期一个个进行中,开发做了一个个的功能点,然后测试就会把这些测完,在这个周期中,开发与测试的工作量都会在DevTrack中被记录,主要是花费时间与剩余时间,从而得到了产品未来的一个进度趋势图,也就是所谓的燃尽图。

  4、需求变更:

  敏捷是欢迎变更的,客户有啥想法可以随时提出随时改进,我们公司的产品是定期给客户一个Build来进行评估的,所以客户经常会要求做一些更改,对于还没有测的功能点稍微好一点,因为只要改设计文档,但是对于已经做完或者正在做的,已经测完或者正在测的呢?答案当然是也得更改,做好的重做,测好的做完重测,对于瀑布模型来说,这个也许是难以想象的,但是对于敏捷来说,这个是家常便饭了。

  在实际操作中,我们可能会用到一个DevSpec的功能,这个功能比较不错,所以我单独提出来说一下。有些时候,如果一个功能已经在测试了,如果突然有了改动,而这个改动也已经做完了,如何通知测试人员重新测一下呢?口头通知?Email?其实都可以,只是有些时候,改动太多,需要知会的人太多,或者改功能的人不知道要通知哪些人,那怎么办?DevSpec有个功能可以自动提醒跟这个功能点有关任何开发、测试人员,让他们知道他们做的事情有改变了。

posted @ 2011-11-21 11:50 顺其自然EVO 阅读(168) | 评论 (0)编辑 收藏

操作系统之死锁

 死锁其实在信号量时已经提到过,当一个进程想要申请资源A,拥有资源B,而另一个进程想申请资源B,但是拥有资源A,那么就会产生死锁。

  信号量本身就是个资源,有一定数量。资源分为很多很多,如内存空间,CPU周期,I/O设备等,每个资源有一定数量的资源实例。

  资源和信号量一样,有等待队列,当一个进程想要申请资源,但需要其他进程释放此资源,则进入该资源的等待队列。

  死锁的必要条件:

  1、互斥。即资源不能被多个进程所占有。这点其实除了只读文件,其他基本都满足。

  2、占有并等待:A进程占有一些资源,还需要的一些资源被其他进程占有,所以处在等待状态。

  3、非抢占:资源不能被中途抢占。

  4、循环等待:{P0,P1,P2....}进程队列,P0等待P1占用的资源,类似。

  只要4个条件满足,则说明必定死锁。

  资源分配图:为了清晰的看是否有死锁。P->R实线 申请;R->P实线 分配;P->R虚线 需求。

  当每个资源类型只有一个实例,则有环等价于死锁。

  当存在资源类型有多个实例,则死锁必有环,有环不一定死锁。

  死锁处理:

  1.1 死锁预防。通过不满足四个必要条件之一。

  (1)互斥:很难不满足。

  (2)占有并等待:第一,可要求进程创建就要申请好全部的资源;或第二,进程申请资源时要释放占有的资源。

  但是第一种情况会发生饥饿。因为如果一个进程需要很多很多进程,这些资源几乎不会同时有,则这个进程永远不会执行。

  (3)非抢占:如果A进程想要申请资源a,但是a被B进程占有,且B进程在等待资源b,则A进程可以抢占B进程的资源a执行。等到B进程得到原本

  拥有的资源a和申请的b,则执行。 抢占和被抢占

  (4)循环等待:规定资源被申请的顺序,每个进程申请资源的顺序被规定了。如果需要Rj(j<i)则需要先释放Ri。

  1.2 死锁避免。前面讨论的预防死锁的解决方案中包括限制资源的申请,但是这对资源的利用率来说下降太多了。

  所以引出了死锁避免:要求事先得到进程申请资源和拥有的资源的信息 来判定是否值得等待。(想起了管程的条件变量选择重启进程的解决方

  法就是得知进程的最大需求)

  最简单的方法是事先告诉每个进程对于每个资源类型的最大需求。从而使得循环等待不成立。

  (1)安全状态:能确定一个进程序列<p1,p2...>,按照这种顺序执行进程就不会死锁(一个结束一个开始)。使得当Pi申请资源时,申请的资

  源一定要小于剩余可用资源+pi队列前面的进程所占有的资源,则称为安全的。因为你想,Pi最多就等的长一点时间,但是最终还是能行的。

  安全则不会死锁。不安全不一定会死锁。

  只有资源分配后能安全状态,才允许申请。

  (2)资源分配图算法:适用于每个资源类型只有一个实例。

  分配边释放就变成需求边。

 2、允许进入死锁,但可以检测并恢复。

  3、忽略死锁。

  银行家算法: 银行有一些资源,一个客户一会要一点资源,一会要一点资源,银行耐着性子分配。 预先知道Max,Allocation,Available

  在新进程进入时,必须说明需要资源类型的种类和数量,但是不能超过系统总资源。

  n为进程个数,m为资源类型种类,available为长度为m的向量,表示每种资源拥有多少的资源。

  Max是n*m的矩阵,Max[i]表示特定进程需要的每个资源的最大需求。

  Allocation是n*m的矩阵,Allocation[i]表示特定进程已经分配的每个资源的数量。

  Need是n*m的矩阵,Need[i]是特定进程需要的剩余资源。

  两个向量比较,只有每个分量都大,才大。

  安全性算法:

  设work是长度m的向量,finish是长度n的向量

work=available;
for(int i=0;i<n;i++)
 finish[i]=false;
for(int i=0;i<n;i++) O(n)
{
 if(finish[i]==false&&Need[i]<work)  O(m)   //如果进程i的最大剩余需求小于系统剩余的资源量
 {
  work=work+allocation[i];  O(m)   //执行完后释放,则系统剩余资源变多
  finish[i]=true;                  //进程i执行结束
 }
 else break;
}
for(int i=0;i<n;i++)
{
 if(finish[i]==false) return false;
}
return true;

  资源请求算法:

  Request[i]是进程i的请求向量。

  if Request[i]<Need[i] 说明能申请
  if Request[i]<Available 说明能分配
  if能分配
  {
  Available-=Request[i]; //系统剩余减少
  Allocation[i]+=Request[i];  //已分配增多
  Need[i]-=Request[i];  //剩余需求减少
  }

  分配完执行安全性算法,即看看是不是安全。

  系统不采用预防或避免提前去除死锁时,可以

  1、有一个算法可以检索死锁的发生。

  2、有一个算法可以让死锁恢复。

  当资源类型只有一个资源实例时,可以用等待图(只有进程)解决。当有环时,则死锁。

  当资源类型可以有多个实例时,则可以用银行家算法解决。

  有一个好办法解决死锁,就是当CPU使用率低于多少多少时,才调用死锁检测,再去除死锁。

  恢复死锁可以:

  1、随便终止一个进程打破循环等待。

  当选择进程的终止时,需要考虑很多方面,就像CPU调度里的优先队列法,可以以不同方面考虑优先。可以以进程执行时间、进程还需资源多少、进程是交互的还是批处理的。

  2、抢占死锁进程资源。

  抢占要抢占谁的又是个问题。自己选呗~而被抢占资源的进程必须回滚到不会发生死锁的时刻。而且不能一直欺负一个进程,这样该进程会发生饥饿。

posted @ 2011-11-21 10:27 顺其自然EVO 阅读(225) | 评论 (0)编辑 收藏

步步学LINQ to SQL:将类映射到数据库表

 该系列教程描述了如何采用手动的方式映射你的对象类到数据表(而不是使用象SqlMetal这样的自动化工具)以便能够支持数据表之间的M:M关系和使用实体类的数据绑定。即使你选择使用了自动生成类的工具,理解这一实现过程可以让你更加方便地对你的应用程序加以扩展。

  下面阐述本文的目标以及该示例程序为初级开发人员介绍如何学习LINQ的基本要点:

  ·使用LINQ to SQL将SQL Server数据库表映射到与之关联的对象上。

  ·执行一些简单的LINQ查询来检索数据。

  本文详细为你阐述了如何在你的应用程序中实现LINQ to SQL。附件的示例程序包括了这里探讨的所有代码,还提供了一个简单的WPF图形界面程序来显示通过数据绑定返回的结果集。

  开始部分:LINQ to SQL是一种对象关系隐射工具,该工具允许你在.NET 3.5框架平台上将SQL Server数据库映射成对象类。

  数据库:该示例使用SQL Server Express作为数据库,在该数据库中包涵了Books, Authors, 和 Categories三张数据表。每本书仅仅属于某一图书类别,但是每本书可有多个作者,每个作者可以写多本书。BookAuthors表用于处理books表和authors表之间的多对多关系。为简单起见,除了Books.Category列以外,其余列都不允许为空。

  这些表可以允许我们针对每个主类型进行关系(1:M,M:1,和M:M)之间的映射。

  本文的其余部分将描述如何将应用程序的数据表与它们的对象类关联起来以及如何使用LINQ来检索结果集。LINQ将使用这些数据表作为示例来阐述这些概念。

  应用程序:使用LINQ to SQL, 创建一个.NET 3.5框架之上的工程并添加对程序集 System.Data.Linq的引用。

  1、映射DataContext到数据库

  如果你为数据库创建了一个强类型的DataContext,则该类只会对外提供一个单一的入口点,使得外界可以方便地的访问你的数据。该类将负责处理数据库的连接并定义你需要连接的每张数据库表。

  *注意: 在DataContext类中你可以忽略M:M的表连接(例如:BookAuthor),因为它们仅仅使用they're only used behind the scenes to hook up M:M relationships(在本文的后半部分会进行阐述)。

  (1)创建一个使用了 [Database]特性的类来扩展 DataContext

  创建一个扩展自DataContext的数据库类,并为其添加[Database]特性以表明该类被映射到了数据库。

  如果你使用的类名与数据库的名称不一样,那么你可以通过使用特性的Name参数进行设定([Database (Name="BookCatalog")])。如果名称是相同的,此时你可以忽略该参数。

using System.Data.Linq.Mapping;
namespace LINQDemo
{
[Database]
public class BookCatalog : DataContext{}
}


(2)添加一个带数据库连接字符串的构造函数

  添加一个带有数据库连接字符串为参数的构造函数,并调用base()方法以告诉父类如何连接你的数据库。

  该构造函数的数据库连接字符串以参数的形式读取,它可以是从一个属性文件读取,或者直接硬编码到函数中,在本文的示例中我们就采用了硬编码这样的方式(假设这里的字符串连接到SQL Server Compact数据库,BookCatalog.sdf,该文件与BookCatalog.mdf位于相同的目录):

public BookCatalog( ) : base( "Data Source=.\\SQLEXPRESS;" +
"AttachDbFilename=|DataDirectory|\\BookCatalog.mdf;" +
"Integrated Security=True;User Instance=True" ) { }

  注意,在工程中,Book Catalog示例包括了数据库,和BookCatalog.sdf文件。对于使用LINQ to SQL来说,这不是必要的,在这里仅仅只是加以说明而已。

  (3)申明数据表

  最后,你可以为每张数据表创建一个类型为Table的对象类集合。

  通常,你可以先创建这些类,下面我们来看看这一创建过程。我们将创建三个类(Author, Book, 和Category)--每个类对应一张数据表。因此,我们将为每个类类型添加一个Table集合并将这些集合命名为一个有意义的名字。注意,为数据库表名对应的类或集合命名不是必须的。我们将在下一节了解如何为数据表指定名称。

using System.Data.Linq;
using System.Data.Linq.Mapping;
namespace LINQDemo
{
[Database]
public class BookCatalog : DataContext
{
public BookCatalog( ) : base( ... );
public Table Authors;
public Table Books;
public Table Categories;
}
}

  2、将实体类映射到数据库表

  为连接到应用程序的每张数据库表创建类对象。我们将以Book表为例子阐述这一实现过程。

  (1)创建带有[Table]特性的类

  创建一个特性为Table的Book类将其映射到对应的数据库表。

  为数据库表的Name参数指定名称([Table( Name = "Books" )])。这里我们这样做是因为表的名称(Books)和我们的类名(Book)不同。如果它们相同,可以忽略该Name参数的设置。

using System.Data.Linq.Mapping;
namespace LINQDemo
{
[Table( Name = "Books" )]
public class Book{}
}

  (2)使用[Column( IsPrimaryKey = true )]特性添加一个字段作为表的主键。

  如果你喜欢,你也可以为为其添加一个Column特性,这也是Book Catalog应用程序所采用的方式。

  如果你的主键在数据库中设置成了Identity,那么需要添加一个参数IsDbGenerated = true。

 相对于数据库列名,如果你想为字段或属性设置成不同的名字,可以使用(Name="")标签来实现.否则程序会默认以你的字段或属性名称作为列名,正如我们这里的Book's主键:Id那样。

[Column( IsPrimaryKey = true, IsDbGenerated = true )]
public int Id { get; set; }

  (3)使用[Column]特性为表添加其他非关系列

  后面部分我们将会回到关系对象上来。现在,咱们开始了解表对象的非主键,外键列。Book有两个这样的列:Title 和 Price。其数据类型由数据库的money类型转换到了.NET的decimal类型,以及由varchars类型转换到了.NET的string类型。LINQ会自动为你处理这些数据类型之间的转换。

[Column] public string Title { get; set; }
[Column] public decimal Price { get; set; }

  Book Catalog应用程序的Author和Category也进行了这样的处理,即这三个类对象都对应于自己的数据表:

using System.Data.Linq.Mapping;
namespace LINQDemo
{
[Table( Name = "Books" )]
public class Book
{
[Column( IsPrimaryKey = true, IsDbGenerated = true )] public int Id { get; set; }
[Column] public string Title { get; set; }
[Column] public decimal Price { get; set; }
}
[Table (Name="Authors")]
public class Author
{
[Column (IsPrimaryKey = true, IsDbGenerated = true )] public int Id { get; set; }
[Column] public string Name { get; set; }
}
[Table (Name="BookCategories")]
public class Category
{
[Column (IsPrimaryKey = true, IsDbGenerated = true )] public int Id { get; set; }
[Column] public string Name { get; set; }
}
}

posted @ 2011-11-21 10:22 顺其自然EVO 阅读(308) | 评论 (0)编辑 收藏

类的生命周期回顾篇

 一、JAVA虚拟机和JAVA程序的生命周期

  JAVA虚拟机的生命周期和JAVA程序的生命周期一致,当我们在命令行中敲入java命令运行java程序时,java虚拟机进程启动,程序运行,当程序终止时,则JAVA虚拟机的生命也结束。

  二、类的生命周期

  1、加载:将.class文件的二进制数据放到内存方法区中,并在堆区中创建一个Class对象,这个Class对象封装了方法区的数据结构,用户能通过Class对象访问到方法区中。

  2、连接

  (1)验证:验证.class文件是否是通过JAVA程序编译出来的,因为有可能这个.class文件是黑客特意制造出来的。

  (2)准备:为类中的静态变量分配空间,并初始化为默认值。

  (3)解析:把类的符号引用变为直接引用。

  3.初始化:为静态变量和静态块赋予值。

  JAVA程序对于类的使用方式:

  (1)主动使用。

  (2)被动使用。

  这里注意:

  JAVA虚拟机对于加载和连接的时间节点是很宽松的,没有严格规定,可以提前加载也可以;但是对于初始化,JAVA虚拟机规定当某个类被主动使用时才能初始化。

  我们把3个步骤细讲一下:

  1、类的加载:类是通过类加载器进行加载。

  类加载的来源:

  (1)文件系统中的class文件

  (2)jar包

  (3)网络中下载。

  类加载目的地:内存。

  类加载器分类:

  (1)根类加载器:没有父类,加载java.lang.*。

  (2)扩展类加载器:父类是根类加载器,用于加载jre\lib\ext的jar包。

  (3)系统类加载器:父类是扩展类加载器,用于加载classpath的jar包。Class scl = Class.getSystemClassLoader();

 (4)自定义加载器:自定义加载,通常父类是系统类加载器。

  注意:通过类虚拟机自带的(1)(2)(3)加载器是JAVA虚拟机创建的,而他们加载的类,他的生命周期是虚拟机的生命周期,因为始终被加载器锁引用。

  2、类的解析

  将符号引用转换成直接引用。比如:

  A函数调用了B函数,原本只是符号引用即标明引用了B函数,直接引用是将符号改成指针指向B函数。

  3、类的初始化

  规则:

  (1)初始化的静态变量都是运行时变量,即不能在编译时就能判断值是多少。

  (2)初始化的顺序就是按照代码的顺序执行。

  (3)如果初始化子类时父类还没有被初始化,则先初始化父类。

  初始化时机:当遇到以下情况会进行初始化。

  (1)new创建实例、反射创建实例、clone创建实例、反序列化创建实例。

  (2)访问静态变量,即读和写。

  (3)调用静态方法。

  (4)启动类需要首先初始化。

  (5)Class.forName();

  注意:

  (1)当遇到编译时常量,则直接用数字替换,而不会导致类初始化。比如public static final int a= 3;这就是一个编译时常量。

  (2)当子类对象调用父类的静态变量或方法,则只对父类进行初始化。比如:Sub.a,其中a是父类的静态变量,则只对Base初始化。

  (3)当子类被初始化时,父类一定要先初始化;

  但是如果一个类实现了一个接口,当类被初始化时,不用初始化父接口。

  只有对这个接口进行访问时,才会对接口进行初始化。

  (4)loader.loadClass("....");只是对类的加载,而不是初始化。

  类加载过程采用“父亲委托机制”,即如果loader2的父类是loader1,loader2想要加载test类,则先会检查loader1是否能够加载test类,如果能,则通过父类加载。

  运行时包的概念:包名相同,类加载器相同。


posted @ 2011-11-21 10:17 顺其自然EVO 阅读(192) | 评论 (0)编辑 收藏

异曲同工 WinForm和ASP.NET如何选?

在.NET平台开发中,我们经常使用WinForm进行C/S架构的开发,也用过ASP.NET作为B/S架构开发。那么有些人可能糊涂了,不知道在这两者之间如何做选择了。其实作为将来要在.NET平台上做开发的工作者来说,无论如何都要同时掌握WinForm编程和ASP.NET编程。

  当我们开始开发带有用户界面的应用程序时,可以使用WinForm或ASP.NET。两者在开发环境(Visual Studio系列)中都具有完全的设计时支持,并且可以提供丰富的用户界面和高级应用程序功能解决现实业务问题。由于这种“相似”,要决定采用哪种技术来实现软件可能有些困难。

  关注软件的最终用途可以使选择变得相对容易。如果我们要开发的是一个公众可以通过Internet访问的电子商务网站,肯定采用ASP.NET来开发软件项目。如果我们要充分发挥客户端电脑的计算能力,并且客户端的处理工作量很大,需要快速响应用户请求,无疑应该使用WinForm。但是在其他情况下,选择也真的不是很明晰。

  何时选择WinForm

  如果客户端应用程序负责应用程序中的大部分处理任务,应该使用WinForm开发应用程序。这些客户端应用程序包括传统上在早期版本的VB和VC中开发的Win32桌面应用程序。绘图或图形应用程序、数据输入系统、POS系统和游戏都属于这类应用程序。

  这些应用程序都依靠桌面计算机的处理能力和高性能数据显示。有些应用程序可能完全独立,它们在用户的计算机上执行所有的应用程序处理。通常以这种方式来编写游戏。其他应用程序可能是大型系统的一部分,它们主要使用桌面计算机来处理用户输入。例如,POS系统常要求在桌面计算机上创建具有响应能力的复杂用户界面,同时将该界面链接到其他执行后端处理的组件。

  使用WinForm的应用程序是在Windows框架中生成的,因此它可以访问客户端计算机上的系统资源,包括本地文件、系统注册表、打印机等。可限制该访问级别,以消除由不希望的访问引起的任何安全性风险或潜在问题。另外,WinForm可以利用.NET Framework GDI+图形类创建丰富界面,而这常常是数据挖掘或游戏应用程序所必需的。

  何时选择ASP.NET

  使用ASP.NET创建主要由浏览器用户界面组成的应用程序。这自然包括希望让公众可通过万维网使用的应用程序,比如电子商务应用程序。但是ASP.NET并不仅仅用于创建网站,许多其他应用程序同样适用于“瘦客户端”,如基于Internet的雇员手册或津贴应用程序。任何ASP.NET应用程序都有一个重要的优点,就是没有客户端安装和维护的成本。用户已经安装了所需的唯一一个应用程序——浏览器。

  ASP.NET应用程序与平台无关,即它们是“延伸”的应用程序。不论用户的浏览器类型是什么,也不论使用的计算机类型是什么,他们都可以与应用程序进行交互。同时,可优化ASP.NET应用程序,以利用最新浏览器中的内置功能来增强性能和响应能力。在许多情况下,此优化内置于使用的Web窗体组件。这些组件可以自动检测浏览器级别,并相应检测呈现页。

  ASP.NET应用程序提供了一些即使在非Web环境中依然有用的功能。因为这些功能依赖于HTML,ASP.NET应用程序适合任何种类的文本密集型应用程序,尤其适合那些文本格式设置对其很重要的应用程序。基于浏览器的应用程序对用户的系统资源的访问权限有限,在希望防止用户访问某些应用程序的情况下,这种限制使ASP.NET应用程序很有价值。

  WinForm与ASP.NET的比较

功能/标准WinFormASP.NET
安装部署WinForm允许使用ClickOnce进行“非接触”部署,即可以直接在用户的计算机上下载、安装和运行应用程序,而不必改变注册表。ASP.NET没有客户端部署;客户端只需要一个浏览器。服务器必须运行Microsoft .NET Framework。对应用程序的更新通过在服务器上更新代码来完成。
图形WinForm包括 GDI+,它使得游戏和其他有非常丰富的图形的环境可以有复杂的图形。在ASP.NET时,交互式图形或动态图形需要来回访问服务器以进行更新。可以在服务器上使用GDI+来创建自定义图形。
响应WinForm可以完全在客户端计算机上运行;它们能够为需要高度交互的应用程序提供最快的响应速度。如果用户用较新的浏览器(IE5.0以上),ASP.NET应用程序可以利用浏览器的动态HTML(DHTML)功能来创建丰富的、具有响应能力的用户界面(UI)。如果用户有其他浏览器,大多数处理(包括与用户界面相关的任务,比如验证)需要往返于Web服务器,而这会影响响应,当然我们可以采用AJAX技术来改善应用体验。
窗体和文本流控制WinForm网格定位可以对控件的位置提供精确的二维(x和y坐标)控制。若要在Windows窗体上显示文本,一般将文本插入到控件(例如 Label控件、TextBox控件或RichTextBox控件)中。格式化将受到限制。ASP.NET界面基于HTML样式流布局,因此支持网页面布局的所有功能。它在文本格式设置方面的功能尤其强大。可以充分地管理控件布局(有某些限制,例如不能重叠控件)。如果用户有支持DHTML的浏览器,可以用二维(x和y坐标)布局来指定更精确的布局。
对于.NET Framework的依赖WinForm需要在客户端计算机上运行.NET Framework。ASP.NET客户端只需要一个浏览器。支持DHTML的浏览器可以利用额外的功能,而Web窗体可以被设计为适用于所有的浏览器。ASP.NET系统只需要在服务器运行.NET Framework。
访问本地资源(文件系统、系统注册表等)如果允许,应用程序对本地计算机资源可拥有完全访问权。如果需要,可以精确地限制应用程序,使其不能使用特定的资源。浏览器安全性防止应用程序访问本地计算机上的资源。
编程模型WinForm基于客户端Win32消息转储模式,开发人员在此模式中创建、使用和销毁组件的实例。ASP.NET依赖于在很大程度上异步的断开连接模型,在此模型中,组件松散地耦合到应用程序前端。通常,应用程序组件通过HTTP协议调用。此模型可能不适合要求用户端有极大吞吐量的应用程序或具有大量事务处理的应用程序。同样,ASP.NET应用程序可能不适合需要高级别并发控制的数据库应用程序。
安全性WinForm在其代码访问安全性实现中使用权限,以保护计算机资源和敏感信息。这使功能得以被小心公开,同时保留安全性。例如打印权限,在某一级别上只允许在默认打印机上打印,在另一级别上则允许在任何一台打印机上打印。使用ClickOnce部署技术,开发人员可以轻松地配置应用程序应该和不应该向客户端要求什么权限。通常,通过验证请求者的凭据(例如,名称/密码对),按URL控制获得访问ASP.NET应用程序资源的授权。ASP.NET允许开发人员控制执行服务器应用程序代码所使用的标识。应用程序可以用请求实体的标识来执行代码。应用程序也可以根据请求者的标识或角色来动态调整内容。例如,经理可以访问某一站点或更高级别的内容,而拥有较低权限的人则不能这样做。

posted @ 2011-11-18 15:30 顺其自然EVO 阅读(181) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 361 362 363 364 365 366 367 368 369 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜