软件测试两年经验,感觉这两年成长还是不错的,主攻性能测试,望有相关 共同理想的朋友一起探讨交流职业路~

发布新日志

  • 【转】写给一名软件测试工程师

    2012-10-04 19:45:06

    你要为自己每一次的懦弱而忏悔:曾经不愿承认自己出生于农村,曾经不敢面对自己是一名外包员工,曾经一次次的不甘心自己只是一名测试工程师

      不做失败者

      微软IBMOracle华为等等,这些公司选拔的测试工程师应该都是出类拔萃的人才。可惜不是你,说起你的大学,就想起郭敬明的《一梦三四年》。你开始想做测试是因为数次面试程序员被拒,但是却看见了“月薪8000不是梦”的广告。比起进入外企、国企、名企的同学,比起考上公务员的同学,比起做软件开发的同学,你在心里问自己“我是个失败者吗?”。我只能说你还没有成功,但是你已经开始挑战失败。

      一名测试工程师

      你有了正式的Title:“测试工程师”,我只能改编《双城记》里语句来形容“这是一个最美好的职业,这是一个最糟糕的职业。”

      你的脑子里充斥了各种词汇“白盒测试自动化测试、测试工具”,可是开始测试任务以后才发现自己用的最多的测试工具就是缺陷管理工具,用到最多的测试技术就是点、点、点,测试组里最受重视的是懂业务的老员工,项目组里最低三下四的是测试。被开发说“这不是BUG,你操作有误,就是这样设计的”,被需求人员鄙视“怎么最基本的业务也不知道?”,测试经理找你谈话时委婉的说“在发现BUG的数量上你还需要努力”,马上就要发版本了,项目经理召集测试组开会“今天开始不要再关注界面的、易用性的、与核心业务无关紧要的BUG”…

      受了最多的委屈,拿着项目组里最低的工资,你都承受下来了,我佩服你。

      今天你再回头看看,肯定会微笑的领会当时的收获。高强度的手工测试培养了测试的Sense,BUG数量的压力激发了逆向发散的潜力,研究复杂的业务锻炼了测试思维。经过与开发、与需求的交锋,逐渐从逆来顺受转变为对抗。逐渐学着站在项目的角度思考测试,为什么要提前测试?为什么要首先关注核心业务?有些BUG为什么不应该提?

      最重要的是你加入了一个团队。当发现一个牛X的BUG,只有在给大家分享时才觉得无限光荣;当抱怨需求变更时,那么一帮人一起泄愤才最解气;当测试一个模块时,几个人一起抢BUG那才刺激。

      跳出去

      逐渐适应了环境,你就开始了几个阶段的胡思乱想:“我不要做手工测试了,我要做自动化测试”;“我不要做测试了,我要转开发”;“我不要做测试了,我要转管理”;“我不要在这个公司了,我要换更好的公司”。

      当你开始在组里照葫芦画瓢的录起来自动化测试脚本,你问自己“这就是自动化?”。你觉得用录制工具没有技术含量,就开始用开源工具、开始自己写测试框架,一遍遍调试,面对需求的变更整晚加班来特性化自动测试程序,你对自己说“写程序真繁琐”。你受够了技术工作,开始主动承担些带新人、任务分配、计划文档编写等工作,你和别人抱怨说“我怎么成了个打杂的了?”

      那么回过头来发现,认认真真投入项目中,仔细研究需求、认真的设计用例、严谨的来执行测试、适度的实现自动化、积极的分担别人的任务,只有这样才感觉最充实。当面对繁杂的需求文档,理清了思路画出了流程图;当看着自己设计密密麻麻的测试用例;当发现自己在原有框架上所作的特性化修改可以完美地运行;当看着自己负责的测试任务井井有条的进行着,自己辅导的新人积极向上的成长着;这一切的喜悦的感觉,都是全身心投入你目前的工作所换来的。

      学无先后

      你已经不再是二十岁出头,开始怀疑自己还能学会新的技术吗?不是说过了25岁就开始记忆衰退了吗?那你知不知道,随着年龄增长,阅历的丰富,理解和领悟能力会越来越强,虽然你比新人学得慢,但是在项目经验方面的优势却能帮助你有更深入的理解。知识是相通的,就比如当你研究明白了一门编程语言,那么再学习新的就会很快。测试也一样,测试工具、测试思想、测试流程都有很多种,不可能样样都会,深度的扩展是广度的前提。

      有人说程序员几天不学习新技术就跟不上时代了,那么测试工程师在工作中用到的技术却是稳定的。不断地重复类似的项目,不断地重复测试、修改测试脚本,你被惰性包围了吗?开始觉得不需要学习了吗?即使学习了新的技术和思想在项目中用不上又有什么用?

      学了一定要用,大多数时候领导为了规避风险,不会太支持你把新的技术或思想引入测试项目中。原来是传统迭代流程,你说要学习敏捷;原来是QTP,你说要换Selenium;原来是ST测试,你说要开展ET测试。你必须要私底下多做研究、多做实践、有较成熟的方案和技术。那么在真正有机会实施的时候,你才能够一展拳脚。实践----学习----实践,循环中不断进步。

      学习分享,在公司里,你开始学习了一门新技术,很新鲜,很有成就感,心里窃喜“看他们都不会”。这样下去有一天你会失落的发现,同事们开始对你的新技术不感兴趣,因为他们不理解,你提倡的技术思想因为无人认同而无法执行下去。与同行交流,你想炫耀一下刚学习来的“探索性测试”思想,她给你来一句“和自由测试有啥区别?我早就知道这个”,你想推广一下敏捷,她给你说“敏捷就是没有文档吗?好啊,终于不用写文档了。”你哭笑不得。

      这时才会发现,个人的发展和进步,需要团队的共同进步,需要行业的共同发展。这一切都来源每一个你这样的测试工程师的进步与分享。

  • (转)如何学习性能测试

    2012-06-24 01:59:57

    摘要:随着Internet的普及与迅速发展,企业业务量的迅速加大,数据大集中成为一种趋势,IT系统承载的负荷越来越重,系统性能的好坏严重的影响了企业对外提供的服务质量。从而对IT系统的性能进行测试和调优引起企业的重视,进而性能测试工程师成为IT市场的”香悖悖”,并且性能测试有着极高的技术挑战。于是吸引了大量的测试爱好者来学这方面的技术,而一谈到性能测试很多人便会想到鼎鼎大名的LoadRunner这款优秀的性能测试工具,然而到这里问题就产生了?

      关建字:LoadRunner 性能测试 网络基础编程语言数据库操作系统

      LoadRuner与性能测试的关系:LoadRunner初学者的误点:把LoadRunner神化了。很多初学LoadRunner的朋友认为掌握了使用LoadRunner这款性能测试工具,就能够做性能测试了。常在网上看到好多人在学习怎么去使用这款优秀的性能测试工具,本来学习怎么去使用LoadRunner这个工具没有错,却把LoadRunner神化了,”天真的”以为它什么都能做,以为学会了LoadRunner的使用就能做性能测试了。尽管用了大量的时间学会了如何使用LoadRunner录制脚本,如何进行关联,如何进行参数化,如何设置集合点等等?可到头来,性能测试还是不会做。为什么?对于产生的性能报告不知道怎么去分析?不知道如何利用得到的分析报告分析出系统存在的瓶颈?不知道如何进行性能调优?像这些事光会使用LoadRunner是做不到的?说白了LoadRunner只是我们做性能测试的一个工具,它并不是万能的,是死的,具体怎么做还得依靠人去操作与分析。会使用LoadRunner的人,并不一定会做性能测试,会做性能测试的人并不一定都会使用 LoadRunner。LoadRunner只是一个性能测试工具而已。我们应该意识到,测试工具只是性能测试中的一部分,仅是为达到性能测试目的而采用的一种手段

      性能测试与系统性能的关系:高性能,高安全的系统,不是测试出来的,而是构架,设计,编写出来的。当然在这里我并不否认性能测试的重要性,甚至可以说没有经过性能测试的系统,一定不会是优秀的系统,软件是人开发出来的,而人总是会出错的,所谓智者千虑,必有一失……要想做好性能测试,在软件系统需求,设计,编写代码的这些阶段就应该进行性能测试,而不仅仅是系统测试这个阶段才去做性能测试,性能测试应该贯穿于整个软件开发周期中。

      对初学LoadRunner朋友的建意:常看到网上一些网友发贴子问,怎么对性能测试产生的结果进行分析?测试系统时怎么去选择合适的协议?对于发这些贴子的人我想请问你?你能够详细的说下HTTP协议吗?TCP建立连接和释放连接的过程是怎样进行的?什么是协议?协议是用来做什么的?在OSI参考模型中各层的作用?数据库中产生并发的冲突的原因?不要太依赖于LoadRunner工具本身的学习,而去忽略计算机其它基础知识的学习,我们更应该去掌握一门编程语言,良好的网络基础知识,计算机原理与操作系统知识,数据库知识。这些是我们去学习怎么去使用LoadRunner前提与基础。。

      1、为什么要掌握一门编程语言

      其一,大家在使用LoadRunner时常会遇到一些不能录制脚本的情况发生,或者需要录制一些复杂的脚本,这时候我们就必须手动的开发脚本。其二 LoadRunner虽然强大,易于使用,可是它却属于商业软件,价格昂贵,并且代码不开源,我们无法了解LoadRunner具体的实现细节,甚至我们会怀疑LoadRunner收集的性能数据准确吗?它有是如何实现的等等,而这些我们通过LoadRunner的帮助文档无法得知。性能测试工具并不只有 LoadRunner,做性能测试还有许多优秀的性能测试工具可以选择,像JMeter,Curl- Loader等等这些非常优秀的开源工具,在全能上虽然并不上LoadRunner,但在某些方面却比LoadRunner还要强大。例如Curl- Loader这个工具,它虽然支持的协议不多,但是对于http协议它最高能产生10万的并发用户,这是LoadRunner远远所不及的。并且这些工具代码是公开的,我们能够从这些代码中去分析具体实现的细节,并且还可以自已编写代码,增强软件的功能,这也是成为性能测试高手的一条途径。LoadRunner好比我们的Windows操作系统,易于使用,功能强大,代码封闭,论全能比Linux要强大。我们的开源性能测试工具好比Linux操作系统代码开源,不易于使用,但很多方面比我们的Windows要强大。也许这个时候有人会问对于初学者学哪门语言最好最有前途C,C++,VB,JAVA,C#?其实每一种语言能够生存下来,自有其生存的道理,每一种语言都有自已优势和缺点,并且编程语言具有相通信,学好了一门,再去学另外的编程语言,非常快就能上手。对于初学者我建意学习C语言,理由有很多,例如很多优秀的开源性能测试工具就是用C语言开发的…。当然不管选择什么编程语言,或者数据库,或者操作系统,我们不要去想学哪门最好,学哪方面最有前途。我们更应该结合自身的情况,选择最合适的,而不是选择最好的。

      2、为什么要掌握计算机原理和操作系统知识

      论坛上常会看到这些问题?LoadRunner中线程与进程的关系?在什么时候用到它们,怎么区别用线程还是进程呢?LoadRunner录制产生了乱码怎么解决?怎么去发现内存泄漏?对那些发贴问这些问题的朋友,我依然想请问你你知道进程和线程的概念吗?知道进程有几种状态吗?知道进程间的通信是怎么进行的吗?死锁,进程与线程的区别这些概念你明白吗?如果你连内存的概念,内存的作用,内存泄露的概念都搞不清楚,你怎么去发现内存泄露?如果这些你都不知道,自然就不知道怎么去做性能测试分析?一些网友录制脚本常常会产生一些莫名奇妙的错误?还震震有词的说这是LoadRunner的原因。其实要说到底要解决这些问题就必需得有良好的计算机原理和操作系统知识。弄清了进程和线程的区别,你自然就明白了使用进程资源使用高,但安全性要强于线程,线程资源利用率少,使用线程能在一个负载生成器上运行更多的Vuser,但可能存在安全问题。LoadRunner录制产生了乱码怎么解决?为什么会产生乱码,你知道什么是字符集吗?什么是编码吗?字符串在我们内存中有是如何存放的?ASCII编码,ANSI编码,UNICODE编码它们的区别是什么?这些都是操作系统的基础基础。掌握好了这些你自然明白LoadRunner中产生乱码的原因。当然计算机原理和操作系统的基础知识还有很多得掌握的知识。像操作系统的体系架构、操作系统的重要基础概念,内存管理、存储/文件系统、驱动/硬件的管理。要做好性能测试计算机原理和操作系统知识必不可少。

    3、为什么要有良好的网络基础

      经常在51testing论坛中看到很多人发贴子。像LoadRuner中为什么要进行关联?LoadRunner测试系统时如何选择协议?LoadRunner中的如何进行IP欺骗?等等。这些问题随便一搜就能发现大量的贴子,其实说到底这些问题和LoadRunner的关系并不是很大,要去解决这些问题并不在于你对LoadRunner这个工具使用是否熟练,而在于我们网络基础知识是否扎实。例如第一个问题LoadRunner中为什么要进行关联?相信很多朋友都知道HTTP协议知道它是超文本传输协议,但是对于一些新手往往不能够详细的说出HTTP具体的内容,像HTTP工作的原理,HTTP协议为什么要使用基于TCP的协议而不使用UDP的协议,HTTP工作在OSI参考模型的哪一层?在HTTP协议上数据是怎么传输的等等。而只有当我们明白了这一切,自然而然就会明白为什么要使用关联,到最后你会发现这些问题其实根LoadRunner关系并不是很大。HTTP协议本质上是无状态的;对页面的每个请求都将被视为新请求,而且默认情况下,来自一个请求的信息对下一个请求不可用。在传统的Web编程中,这通常意味着在每一次往返行程中,与该页及该页上的控件相关联的所有信息都会丢失。例如,如果用户将信息输入到文本框,该信息将在从浏览器或客户端设备到服务器的往返行程中丢失,为了使用浏览网页,页与页是相互联系不去丢失这些信息,于是了就从现了Cookie,Session,查询字符串等等保持状态的技术。什么是Cookie?什么是Session?Cookie 和Session 有是怎么工作的?当我们明白了这些,很多的问题就自然而然的明白了,像这些都是基础的知识和LoadRunner关系大吗?不大。

      Cookie 是一些少量的数据,这些数据存储在客户端文件系统的文本文件中,或者存储在客户端浏览器会话的内存中。Cookie 包含特定于站点的信息(像用户名密码以及我们在网站一些个性化的设置等等),这些信息是随页输出一起由服务器发送到客户端的。如果浏览器使用的是 cookie,那么所有的数据都保存在浏览器端,比如我们登录以后,服务器设置了cookie用户名,那么当你再次请求服务器的时候,浏览器会将用户名一块发送给服务器,这些变量有一定的特殊标记。服务器会解释为cookie变量,所以只要不关闭浏览器,那么cookie变量一直是有效的,所以能够保证长时间不掉线。。如果设置了的有效时间,那么它会将 cookie保存在客户端的硬盘上,下次再访问该网站的时候浏览器先检查有没有 cookie,如果有的话,就读取该 cookie,然后发送给服务器。这些是Cookie的工作过程,常看到论坛上一些朋友发贴子问使用LoadRunner时录制到了一些Cookie的信息,它是用来做什么的,看起来很烦可不可以把它删除掉?明白了这些细节的知识,你自然能明白那个Cookie的信息能不能删除掉。如果web服务器端使用的是session,那么所有的数据都保存在服务器上,客户端每次请求服务器的时候会发送当前会话的SessionId,服务器根据当前 SessionId唯一地标识在服务器上包含会话数据的浏览器,以确定用户是否登录或具有某种权限。不同的用户发送请求Web服务器会随机发送一个唯一的 SessionID。而我们使用LoadRunner录制时它会把我们SessionID写死,所以导致出错。这时候就得使用关联了,这样不仅明白了 LoadRunner怎样使用关联,而且还明白了为什么要使用关联?对于LoadRunner测试系统时如何选择协议?这个问题也是网络论讨的比较多的问题。要解决这个问题同样得依靠我们的扎实的网络基础,而不是对LoadRunner使用的熟练程度,首先我们得了解LoadRunner录制时的工作原理了,LoadRunner的录制和QTP不一样,它不关心你的对象识别什么的,不关心你的什么界面之类的,不关心你使用什么语言编写的,LoadRunner有一个Agent进程,来专门监控客户端和服务器之间的通信,然后用自己的函数进行录制。LoadRunner录制的时候关心的是通信包,是客户端和服务器之间的数据包。说到这里,大家就比较清楚了,为什么有的时候不能录制呢?因为,协议不认识,导致LoadRunner截获的数据包不能解析,所以录制下来是空的。所以我们得熟悉什么是协议, 熟悉OSI参考模型,OSI参考模型中各层的作用,TCP协议栈各层的作用,熟悉TCP,UDP,ICMP等等协议。当我们明白了这些网络的基础知识后我们自然会明白应该如何去选择协议。另外关于LoadRunner中的如何进行IP欺骗?要解决这个问题同样得有良好的网络基础知识。其实当我们理解了IP 地址的格式,IP地址的分类,子网掩码的概念,以及知道怎么去进行非标准子网的划分方法 ,掌握了这些原理的东西,那么具体怎么在LoadRunner中如何进行IP欺骗,就非常简单了。 当然网络基础知识并不只是上面的而已,还包括路由器,交换机,加密技术等等这些基础的网络知识,这些远远比我们去学习怎么去使用LoadRunner更重要。

      4、为什么要掌握数据库知识

      数据库的重要性我想是不言而喻的,性能测试产生的一个非常大的原因是因为数据大集中的趋势,测试从某种意义来讲就是对数据测试,而我们企业的核心数据是放在数据库中的。现在大型的WEB应用程序,都采用多层结构,像典型三层,用户界面层,数据逻辑层,数据层。而数据层,而数据层对我们整个WEB应用程序的性能是非常大的,对数据库的基础知识不懂,我们怎么去进行性能测试分析?怎么知道确定性能产生的瓶颈是否是数据库的原因,如何对系统进行调优?例如数据库模型设计不合理,一条坏的SQL语句就能影响到整个WEB应用程序的性能,所以熟悉SQL语句,建表,索引,存储过程,事务,触发器,并发等这些基础知识是必需得掌握的。

      路漫漫其修远兮,吾将上下而求索:性能测试难点不在于Loadrunner工具本身,难在对整个系统的全局把握,而对全局的把握你就必需得有丰富的知识面。 并不是学好了LoadRunner的使用就能做性能测试 。目前,国内性能测试领域正处于起步阶段,要做好性能测试还需学习更多的知识,技术性和非技术。性能测试这条路充满着挑战,也充满着机遇。但正如鲁迅先生所说这世上本来没有路,走的人多了,也就成了路。最后祝愿喜爱性能测试的爱好这条道路上能够不鸣则已,一鸣惊人,不飞则已,一飞冲天。


  • Linux安装apache

    2012-06-24 01:50:11

    前置条件:
    WinXP系统安装VMware server 2虚拟机
    虚拟机安装CentOS6.2系统
    1解决no acceptable C compiler found in $PATH问题
    虚拟机联网方式选择Bridged
    虚拟机网络设置中IPv4设置选择自动(DHCP)
    重启虚拟机,在联网条件下安装gcc和gcc-c+
    # yum -y install gcc
    # yum -y install gcc-c++
    2解决 APR not found问题
    下载apr-1.4.6.tar.bz2
    # tar jxvf apr-1.4.6.tar.bz2
    # cd apr-1.4.6
    # ./configure
    # make
    # make install
    3解决APR-util not found问题
    下载apr-util-1.4.1.tar.bz2
    # tar jxvf apr-util-1.4.1.tar.bz2
    # cd apr-util-1.4.1
    # ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
    # make
    # make install
    4解决pcre-config for libpcre not found问题
    下载pcre-8.30.zip
    # unzip -o pcre-8.30.zip
    # cd pcre-8.30
    # ./configure --prefix=/usr/local/pcre
    # make
    # make install
    5安装apache
    下载httpd-2.4.1.tar.bz2
    # tar jxvf httpd-2.4.1.tar.bz2
    # cd httpd-2.4.1
    # ./configure --prefix=/opt/www --with-apr=/usr/local/apr/ --with-apr-util=/usr/local/apr-util/ --with-pcre=/usr/local/pcre
    # make
    # make install
  • 性能测试之Web篇

    2012-04-01 00:22:52

    随着网络世界的迅猛发展,网站的性能变得日益重要,性能不好的网站将被用户所抛弃。所以性能是用户对软件系统是否满意的一个重要方面。本文将对什么是性能,如何测试性能等方面进行论述。

      那么性能是什么呢,性能是特定功能占用的时间和资源。他可以是功能的开销或者是同步运行功能的数目。Web性能测试就是模拟大量用户操作给网站造成压力,并评测web系统在不同负载和不同配置下能否达到已经定义的标准。性能测试更加关注分析和消除与软件结构中相关联的性能瓶颈。

      性能是每个软件系统必须考虑的指标,在性能测试中我们通常注意以下四方面数据:一、负载数据;二、数据流量;三、软件本身消耗资源情况;四、系统使用情况。由于性能测试的特殊性,一般情况下都是利用特殊的测试工具(如LoadRunner,TestManager,ACT等)模拟多用户操作,对需要评测的系统造成压力。找出系统的瓶颈,并提交给开发人员进行修正。所以性能测试的目的是找出系统性能瓶颈并纠正需要纠正的问题。

      制定WEB性能测试的策略可以遵循对系统中最重要的模块,经常使用的模块,系统开销最大的地方(代码最复杂的部分),对用户来说最重要的部分进行测试。我们从整体的角度分析一下性能可能出现问题的地方,作为web程序不管是两层,还是多层系统架构的程序。系统都是通过http协议(超文本传输协议(HypertemxTransferProtocol,HTTP)是一个“请求-回应”的应用协议,这个协议支持一套固定的方法如Get,Post,Put,Delete等)来传输数据,发送命令。中间的过程大致为客户端(浏览器)发送数据操作请求给服务器,服务器接收命令请求后进行处理,然后把结果返回给客户端,客户端处理响应结果。这个过程中客户端发送请求进行数据处理的过程一般不是系统的性能瓶颈,这个时候一般是大量用户同时操作,发送数据请求才是系统的瓶颈。系统的服务器硬件资源最有可能是软件系统的瓶颈。我们需要调整软件和环境(最优化响应时间和资源),确认应用和系统可以处理的高负载和压力条件。而这个时候系统硬件中最可能的是cpu造成的瓶颈。系统中其他硬件资源所造成的瓶颈,我们可以替换相应的硬件资源,进行调整。而系统中另一个瓶颈可能是服务器把处理数据发送给客户端,这个过程硬件资源就不可能是性能的限制因素,最有可能是带宽的原因。

      其实性能的问题大多数情况下是由于软件体系结构或设计不合理造成的,而不是编码引起的。如果在性能测试中发现CPU占用率居高不下,内存占用异常,经常报错的情况问题的时候,排除上边分析的原因外,应及时提交情况汇总给开发人员,让开发人员察看代码中出错环节是否有死循环等逻辑错误,检查应用部署后所使用的数据连接驱动是否有误或者代码未及时更新,查看数据库查询或者其他语句是否有异常,中断测试,只运行响应时间最长的页面并验证结果。分析系统可能的性能瓶颈。

      我们需要在测试中注意不同的带宽条件对测试结果所造成的结果,所以应该在性能测试前要制定系统性能标准,这样才能合理分析测试结果。把不同带宽的测试结果进行分析量化,找到测试系统瓶颈。

      一般性能测试中最常见的基本类型为基准测试,配置测试,负载测试,压力测试,我们知道在软件测试的过程中,不同阶段,不同类型所进行的性能测试关注测试目标是不同的,不同软件架构也决定了性能测试存在差异。这样就要对所进行的测试类型有一定的了解,才能更好的进行性能测试工作。下边是各种测试类型的具体概念:

      基准测试——把新服务器或者未知服务器的性能和已知的参考标准进行比较

      配置测试——确认服务器在不同的配置下性能的可接受性。(操作条件不变)

      负载测试——确认服务器在不同的负载条件下性能的可接受性。(操作条件不变)

      压力测试——确认服务器在异常或者极限的条件时性能的可接受性,例如,减少资源或大数量的用户。

      竞争测试——确认服务器可以处理多个客户对同一个资源的请求竞争

      通过系统基准测试提供的一定条件下服务器如何处理数据的基线,作为评估其他性能指标的参考数据起点。进行配置测试则是测试系统配置在不同的机器上能否正常运行。用配置测试来确保系统在多个平台上正常运行。而负载测试用来测试在不同负载条件下客户端或者服务器端的响应时间。帮助测试人员计算在限定时间内服务器响应处理的请求的最大数量的事务数。压力测试则是在极限条件下运行系统的过程,检查什么条件下服务器或者客户端崩溃。竞争测试则是在一台或者多台pc上操作系统功能来模拟实际环境。

      部分测试人员可能面对的是一个已经发布的Web系统,这种情况如何进行性能测试呢。在没有进行测试之前,可以通过网站的管理人员收集测试数据,为以后进行性能测试做好准备,收集的信息包括每小时在线用户数量,平均每小时的在线用户数量,不同时段的在线用户峰值比较,收集被访问次数最多的的页面,系统正常运行时CPU的使用率。所有这些作为性能测试的依据,避免盲目进行性能测试。在不了解系统的真实情况下进行的性能测试,很可能是错误的测试。把过多的精力放在了错误的地方。那样测试结果就不具有真实性,并且会浪费大量的测试资源。

      而对于一个开发中的web系统进行性能测试,就要根据开发目标和用户需求在体系结构的迭代过程中,不断调整测试目标,对系统性能有个很好的评估。那么如何才能成功的进行性能测试呢,我觉得进行性能测试前应有一个测试计划,这样才能保证性能测试有序的进行。下边给出了性能测试的一般步骤:

      ● 评估系统:在这个阶段,主要是明确确定系统期望目标,包括:确定系统功能,确定用户活动,确定系统架构,确定可接受的极限,验证可接受的极限,确定系统风险等。

      开发测试资源:进行性能测试的资源,主要覆盖三种活动:开发风险减低计划,开发测试策略,开发自动化脚本。

      ● 执行基准测试:利用基线对比将来的测试结果对系统评估负载,压力,竞争测试结果中的相关性能。主要通过压力场景验证自动化测试脚本的正确性。在测试周期早期中标示可见的性能指标。性能工程包括个体脚本基线,建立初始化基准。

      ● 分析测试结果:对结果进行分析是为了决定是否对系统继续进行测试,是否结果达到了期望值。这个阶段包含评估结果,确定是否是可接受的极限,确定是否继续进行测试,确定需求调整。

      ● 预定测试:强制验证系统性能,这些测试是必须执行的即使性能和需求都没有调整的情况下。它包含执行用户体验测试,执行稳定性测试,执行产品确认测试等活动。

      ● 结束测试:实际工作中由于软件架构和其他资源限制,软件无法继续优化,此时建议将测试资源转移,测试其他方面,避免测试资源浪费。

      通过上边一系列阐述,大家对Web性能测试的目的方法应该有了一定了解。实际工作中千差万别,需要大家具体问题具体分析,才能做好性能测试。

  • LR11 licenece

    2012-03-23 00:02:31

    LoadRunner11:

    http://219.239.26.11/download/8009651/9327422/3/zip/49/108/1286952922673_876/Software_HP_LoadRunner_11.00_T7177_15013.zip

    http://h30316.www3.hp.com/prdownloads/Software_HP_LoadRunner_11.00_T7177_15013.z01?ordernumber=520699787&itemid=1&downloadid=57459549&merchantId=SGBU_ECATALOG&dlm=ON

     

    官方地址

    https://h10078.www1.hp.com/cda/hpdc/display/main/secure/download_bin.jsp?zn=bto&cp=54_4012_100__

    破解方法:
    安装好loadrunner11后
    1)退出程序,把下载文件中的lm70.dll和mlr5lprg.dll覆盖掉..\HP\LoadRunner\bin下的这两个文件
    2) 注意,win7的话一定要以管理员身份运行启动程序,启动后,点击 configuration->loadrunner license,此时可能会有两个许可证信息存在,退出程序,点击deletelicense.exe文件,来删除刚才得许可证信息(即时原来没有 lisense最好也运行一下)
    3)再次打开程序, configuration->loadrunner license->new license,在弹出的输入框中输入license序列号AEABEXFR-YTIEKEKJJMFKEKEKWBRAUNQJU-KBYGB,点击确定,验证通过后,则破解成功!

    注册码:golba-100: AEAMAUIK-YAFEKEKJJKEEA-BCJGI
            web-10000: AEABEXFR-YTIEKEKJJMFKEKEKWBRAUNQJU-KBYGB
    提供一个超级license 最高支持6.5w个并发:AEACFSJI-YJKJKJJKEJIJD-BCLBR

  • 测试工程师如何提升自己

    2012-03-11 23:22:17

     2011年到了目前这个公司,负责建立测试团 队,刚来公司的时候,领导一句话就是你自己招兵买马。而这之前我最高的岗位就是资深测试工程师,现在转过来负责招聘和管理,确实有诸多困难,但是想着我自 己的座右铭:挑战就是机会。因此耐下性子琢磨如何建立团队,如何给自己找一帮合格的同伴。经过这么久的总结和实践,总算把自己的这套理论验证了一下,顺便 发出来供大家拍砖。

      首先,我们还是回到很多人想知道的问题:怎么样的测试工程师才合格?

      目前,说法很多,而我以前的文章也提到过,总结起来不外乎:博大精深四个字,但是这四个字不是时间可以证明的,说易行难。但是对于工薪阶层的我们来说,高薪就意味着一切,因此不管多难我们都得上,对吧?

      第二,拆解“博大精深”

      我根据自己多年的经验积累以及和同行们之间的交流,将这四个字做了以下拆解:

      1、业务能力
      2、技术能力
      3、辅助能力

      以上三类能力属于大块的,接下来进一步拆解:

      1、业务能力

      我们了解的各种领域的知识,如电子商务,医疗,金融,电信,无线通信,军事,财务,进销存仓储等等,我们在工作中 会接触到这些领域,那么我们要做的就是去理解这些业务的实现流程,各个环节,模块,它们是如何配合形成了一整套能够为顾客提供服务的系统。这些环节中,那 些部分是关键,那些部分是目前技术无法解决的,那些部分是目前同行中最优秀的。当我们能够随口描述出这个系统的各个组成部分,以及其功能的目的和作用时, 那么你就离领域专家不远了。

      2、技术能力

      这主要帮助我们在执行测试任务的时候能否尽快,独立,可控的完成任务的东西。

      首先是测试流程及设计

      要熟悉当前流行的,常用的,经典的那些测试流程,要熟悉这些流程中各个环节以及在这些环节中作为测试人员的我们应该做哪些工作,以免在开展工作时不知道如何开始,如何评估,如何结束。常用的,流行的,经典的测试设计方法,评估方法,这些必须有。

      其次是技术

      数据库技 能属于基础技能,我这里把数据库技能分为三级:入门级,会基本的sql语句,增删改查,连接查询,子查询等。熟练级,会建库,导表,分配用户,备份数据, 能读懂存储过程等。DBA级,熟悉DBMS的参数及其作用,能够运用范式概念来理解数据表的逻辑设计,掌握数据库的优化方法等。

      编码技术:我经常给我的同事们说,我们也许找了成千上万的bug,但是我们却没有生产出一个bug,这算不算遗憾?那么编码能力就会弥补这个遗憾,因此我们要去学习一 门编程语言,然后用它在日常的测试工作中去生产一下bug,呵呵。编码技术我分为五层:第一层,了解一门编程语言,会用它写一些小东西。第二层,熟悉一门 语言的常用的内库,并且在工作中灵活的运用这些现成的玩意儿。第三层,有一定编程思想,对线程,网络编程,数据库编程都比较熟悉了,能够随时从语言自带的 lib中找到这些现成的模块,并且熟悉它们的具体用法。第四层,熟悉各类常用的设计模式,并且能够顺畅的利用这些模式来完成自己的工作,脑袋不在只是考虑 语言和lib,而是产品,模型。第五层,没有产品,没有模型,没有架构,只有公司的策略,未来的技术走向,这个算什么?我私下定义的:人妖!^^

      3、辅助能力

      首先是执行力

      没有执行力,说什么都是空的,除非能够一开始我们就是领导者,否则就必须要有执行力。没有也要给锻炼出来,比如最简单的方法,闹钟一响必须起床,计划制定之后无论如何都要去按时完成。

      其次是学习能力

      很多人在简历里面写自己学习能力怎么样怎么样,但是一问你如何去学习一个陌生的技术的时候,回答往往不靠谱。我这简单描述下:学习分为四个阶段:学,习,去粗存菁,融会贯通。多了不说,各自琢磨,免得被用来忽悠面试官。

      再次解决问题的能力

       看到这里肯定有人会说:这玩意儿也可以考核?度量?我确实想这么说:解决问题的能力在书面上叫方法学或方法论。每个人每天都在解决不同的问题,而不同的 人在解决同样的问题的时候有不同的风格,这里的风格就是方法。这个网上有很多的资料可以查,我就省了,只说一个大概:确认问题的表象,拆解细分,对拆分后 的列表进行从易到难的排序,然后按这个顺序进行解答,综合所有解答得出最后答案,评估问题是否得到解决。

      最后,悟性

      我就要把这个放到网上来,不怕被拍砖,没有悟性的人做啥都是死的,没有生命。大道从简,世界万物都有自己的道,成就的高低最终还是由自己领悟的道来决定,不管人们是否承认。道可道,非常道,我只能说到这里,再说就是瞎说,这只能靠自己。

      综述:

       以上三类能力可以全修,也可以偏修,建议入门的先专其一,其他的先入门,可以博一个入职机会,然后在逐个攻取。最终成就自己的道。这三类能力辅助能力尤 为重要,我故意放到辅助这里来说就是这个意思,辅助能力突出的人,哪怕前面的两项能力都没有,我也觉得是可造之才,否则只能算一般人才尔。

  • 转载:性能结果分析方法

    2011-09-18 15:53:52

    1.前言:

      LoadRunner 最重要也是最难理解的地方--测试结果的分析.其余的录制和加压测试等设置对于我们来讲通过几次操作就可以轻松掌握了.针对 Results Analysis 我用图片加文字做了一个例子,希望通过例子能给大家更多的帮助.这个例子主要讲述的是多个用户同时接管任务,测试系统的响应能力,确定系统瓶颈所在.客户要求响应时间是1 个人接管的时间在5S 内.

      2.系统资源:

      2.1 硬件环境:

      CPU:奔四2.8E

      硬盘:100G

      网络环境:100Mbps

      2.2 软件环境:

      操作系统:英文windowsXP

      服务器:tomcat 服务

      浏览器:IE6.0

      系统结构:B/S 结构

      3.添加监视资源

      下面要讲述的例子添加了我们平常测试中最常用到的一些资源参数.另外有些特殊的资源暂时在这里不做讲解了.我会在以后相继补充进来。

      Mercury Loadrunner Analysis 中最常用的5 种资源.

      1. Vuser

      2. Transactions

      3. Web Resources

      4. Web Page Breakdown

      5. System Resources

      在Analysis 中选择“Add graph”或“New graph”就可以看到这几个资源了.还有其他没有数据的资源,我们没有让它显示.

      

      如果想查看更多的资源,可以将左下角的display only graphs containing data 置为不选.然后选中相应的点“open graph”即可.

      打开Analysis 首先可以看的是Summary Report.这里显示了测试的分析摘要.应有尽有.但是我们并不需要每个都要仔细去看.下面介绍一下部分的含义:

      Duration(持续时间):了解该测试过程持续时间.测试人员本身要对这个时期内系统一共做了多少的事有大致的熟悉了解.以确定下次增加更多的任务条件下测试的持续时间。

      Statistics Summary(统计摘要):只是大概了解一下测试数据,对我们具体分析没有太大的作用.

      Transaction Summary(事务摘要):了解平均响应时间Average单位为秒.

      其余的看不看都可以.都不是很重要.
    4.分析集合点

      在录制脚本中通常我们会使用到集合点,那么既然我们用到了集合点,我们就需要知道Vuser 是在什么时候集合在这个点上,又是怎样的一个被释放的过程.这个时候就需要观察Vuser-Rendezvous 图.

      

      图1

      可以看到大概在3 分50 的地方30 个用户才全部集中到start 集合点,持续了3 分多,在7 分30 的位置开始释放用户,9 分30 还有18 个用户,11 分10 还有5 个用户,整个过程持续了12 分.

      

      图2

      上面图2 是集合点与平均事务响应时间的比较图.

      注:在打开analysis 之后系统LR 默认这两个曲线是不在同一张图中的.这就需要自行设置了.具体步骤如下:

      点击图上.右键选择merge graphs.然后在select graph to merge with 中选择即将用来进行比较的graph.如图3:

      

      图3

      图2 中较深颜色的是平均响应时间,浅色的为集合点,当Vuser 在集合点持续了1分后平均响应时间呈现最大值,可见用户的并发对系统的性能是一个很大的考验.接下来看一下与事务有关的参数分析.下看一张图.

      

      图4

      这张图包括Average Transaction Response Time 和Running Vuser 两个数据图.从图中可以看到Vuser_init_Transaction(系统登录)对系统无任何的影响,Vuser 达到15 个的时候平均事务响应时间才有明显的升高,也就是说系统达到最优性能的时候允许14 个用户同时处理事务,Vuser 达到30 后1 分,系统响应时间最大,那么这个最大响应时间是要推迟1 分钟才出现的,在系统稳定之后事务响应时间开始下降说明这个时候有些用户已经执行完了操作.同时也可以看出要想将事务响应时间控制在10S 内.Vuser 数量最多不能超过2 个.看来是很难满足用户的需求了.

      做一件事有时候上级会问你这件事办得怎么样了.你会说做完一半了.那么这个一半的事情你花了多少时间呢?所以我们要想知道在给定时间的范围内完成事务的百分比就要靠下面这个图(Transaction Response Time(Percentile)

      

      图中画圈的地方表示10%的事务的响应时间是在80S 左右.80S 对于用户来说不是一个很小的数字,而且只有10%的事务,汗.你觉得这个系统性能会好么!

      实际工作中遇到的事情不是每一件事都能够在很短的时间内完成的,对于那些需要时间的事情我们就要分配适当的时间处理,时间分配的不均匀就会出现有些事情消耗的时间长一些,有些事情消耗的短一些,但我们自己清楚.LR 同样也为我们提供了这样的功能,使我们可以了解大部分的事务响应时间是多少?以确定这个系统我们还要付出多少的代价来提高它.

      Transaction Response Time(Distribution)-事务响应时间(分布)

      显示在方案中执行事务所用时间的分布.如果定义了可以接受的最小和最大事务性能时间,可以通过此图确定服务器性能是否在可接受范围内.

      

      很明显大多数事务的响应时间在60-140S.在我测试过的项目中多数客户所能接受的最大响应时间也要在20S 左右.140S 的时间!很少有人会去花这么多的时间去等待页面的出现吧!

      通过观察以上的数据表.我们不难看到此系统在这种环境下并不理想.世间事有果就有因,那么是什么原因导致得系统性能这样差呢?让我们一步一步的分析.

      系统性能不好的原因多方面,我们先从应用程序看.有的时候我不得不承认LR 的功能真的很强大,这也是我喜欢它的原因.先看一张页面细分图.

      

      一个应用程序是由很多个组件组成的,整个系统性能不好那我们就把它彻底的剖析一下.图片中显示了整个测试过程中涉及到的所有web 页.web page breakdown中显示的是每个页面的下载时间.点选左下角web page breakdown 展开,可以看到每个页中包括的css 样式表,js 脚本,jsp 页面等所有的属性.

      在select page to breakdown 中选择页面.

      

      见图.

      在 Select Page To Breakdown 中选择http://192.168.0.135:8888/usertasks 后,在下方看到属于它的两个组件,第一行中Connection 和First Buffer 占据了整个的时间,那么它的消耗时间点就在这里,我们解决问题就要从这里下手.

      

      

      也有可能你的程序中client 的时间最长.或者其他的,这些就要根据你自己的测试结果来分析了.下面我们来看一下CPU,内存.硬盘的瓶颈分析方法:

      首先我们要监视CPU,内存.硬盘的资源情况.得到以下的参数提供分析的依据.
           %processor time(processor_total):器消耗的处理器时间数量.如果服务器专用于sql server 可接受的最大上限是80% -85 %.也就是常见的CPU 使用率.

      %User time(processor_total)::表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。

      %DPC time(processor_total)::越低越好。在多处理器系统中,如果这个值大于50%并且Processor:% Processor Time非常高,加入一个网卡可能会提高性能,提供的网络已经不饱和。

      %Disk time(physicaldisk_total):指所选磁盘驱动器忙于为读或写入请求提供服务所用的时间的百分比。如果三个计数器都比较大,那么硬盘不是瓶颈。如果只有%Disk Time比较大,另外两个都比较适中,硬盘可能会是瓶颈。在记录该计数器之前,请在Windows 2000 的命令行窗口中运行diskperf -yD。若数值持续超过80%,则可能是内存泄漏。

      Availiable bytes(memory):用物理内存数. 如果Available Mbytes的值很小(4 MB 或更小),则说明计算机上总的内存可能不足,或某程序没有释放内存。

      Context switch/sec(system): (实例化inetinfo 和dllhost 进程) 如果你决定要增加线程字节池的大小,你应该监视这三个计数器(包括上面的一个)。增加线程数可能会增加上下文切换次数,这样性能不会上升反而会下降。如果十个实例的上下文切换值非常高,就应该减小线程字节池的大小。

      %Disk reads/sec(physicaldisk_total):每秒读硬盘字节数.

      %Disk write/sec(physicaldisk_total):每秒写硬盘字节数.

      Page faults/sec:进程产生的页故障与系统产生的相比较,以判断这个进程对系统页故障产生的影响。

      Pages per second:每秒钟检索的页数。该数字应少于每秒一页Working set:理线程最近使用的内存页,反映了每一个进程使用的内存页的数量。如果服务器有足够的空闲内存,页就会被留在工作集中,当自由内存少于一个特定的阈值时,页就会被清除出工作集。

      Avg.disk queue length:读取和写入请求(为所选磁盘在实例间隔中列队的)的平均数。该值应不超过磁盘数的1.5~2 倍。要提高性能,可增加磁盘。注意:一个Raid Disk实际有多个磁盘。

      Average disk read/write queue length: 指读取(写入)请求(列队)的平均数Disk reads/(writes)/s:理磁盘上每秒钟磁盘读、写的次数。两者相加,应小于磁盘设备最大容量。

      Average disk sec/read:以秒计算的在此盘上读取数据的所需平均时间。Average disk sec/transfer:指以秒计算的在此盘上写入数据的所需平均时间。

      Bytes total/sec:为发送和接收字节的速率,包括帧字符在内。判断网络连接速度是否是瓶颈,可以用该计数器的值和目前网络的带宽比较Page read/sec:每秒发出的物理数据库页读取数。这一统计信息显示的是在所有数据库间的物理页读取总数。由于物理 I/O 的开销大,可以通过使用更大的数据高速缓存、智能索引、更高效的查询或者改变数据库设计等方法,使开销减到最小。

      Page write/sec:(写的页/秒)每秒执行的物理数据库写的页数。

    1. 判断应用程序的问题

      如果系统由于应用程序代码效率低下或者系统结构设计有缺陷而导致大量的上下文切换(context switches/sec显示的上下文切换次数太高)那么就会占用大量的系统资源,如果系统的吞吐量降低并且CPU的使用率很高,并且此现象发生时切换水平在15000以上,那么意味着上下文切换次数过高.

      

      从图的整体看.context switches/sec变化不大,throughout曲线的斜率较高,并且此时的contextswitches/sec已经超过了15000.程序还是需要进一步优化.

      2. 判断CPU瓶颈

      如果processor queue length显示的队列长度保持不变(>=2)个并且处理器的利用率%Processortime超过90%,那么很可能存在处理器瓶颈.如果发现processor queue length显示的队列长度超过2,而处理器的利用率却一直很低,或许更应该去解决处理器阻塞问题,这里处理器一般不是瓶颈.

      

      %processor time平均值大于95,processor queue length大于2.可以确定CPU瓶颈.此时的CPU已经不能满足程序需要.急需扩展.

      3. 判断内存泄露问题

      内存问题主要检查应用程序是否存在内存泄漏,如果发生了内存泄漏,process\private bytes计数器和process\working set 计数器的值往往会升高,同时avaiable bytes的值会降低.内存泄漏应该通过一个长时间的,用来研究分析所有内存都耗尽时,应用程序反应情况的测试来检验.

      

      图中可以看到该程序并不存在内存泄露的问题.内存泄露问题经常出现在服务长时间运转的时候,由于部分程序对内存没有释放,而将内存慢慢耗尽.也是提醒大家对系统稳定性测试的关注.

      附件:

      CPU信息:

      Processor\ % Processor Time 获得处理器使用情况。

      也可以选择监视 Processor\ % User Time 和 % Privileged Time 以获得详细信息。

      Server Work Queues\ Queue Length 计数器会显示出处理器瓶颈。队列长度持续大于 4 则表示可能出现处理器拥塞。

      System\ Processor Queue Length 用于瓶颈检测通过使用 Process\ % Processor Time 和 Process\ Working Set

      Process\ % Processor Time过程的所有线程在每个处理器上的处理器时间总和。

      硬盘信息:

      Physical Disk\ % Disk Time

      Physical Disk\ Avg.Disk Queue Length

      例如,包括 Page Reads/sec 和 % Disk Time 及 Avg.Disk Queue Length。如果页面读取操作速率很低,同时 % Disk Time 和 Avg.Disk Queue Length的值很高,则可能有磁盘瓶径。但是,如果队列长度增加的同时页面读取速率并未降低,则内存不足。

      Physical Disk\ % Disk Time

      Physical Disk\ Avg.Disk Queue Length

      例如,包括 Page Reads/sec 和 % Disk Time 及 Avg.Disk Queue Length。如果页面读取操作速率很低,同时 % Disk Time 和 Avg.Disk Queue Length的值很高,则可能有磁盘瓶径。但是,如果队列长度增加的同时页面读取速率并未降低,则内存不足。

      请观察 Processor\ Interrupts/sec 计数器的值,该计数器测量来自输入/输出 (I/O) 设备的服务请求的速度。如果此计数器的值明显增加,而系统活动没有相应增加,则表明存在硬件问题。

      Physical Disk\ Disk Reads/sec and Disk Writes/sec

      Physical Disk\ Current Disk Queue Length

      Physical Disk\ % Disk Time

      LogicalDisk\ % Free Space

      测试磁盘性能时,将性能数据记录到另一个磁盘或计算机,以便这些数据不会干扰您正在测试的磁盘。

      可能需要观察的附加计数器包括 Physical Disk\ Avg.Disk sec/Transfer 、Avg.DiskBytes/Transfer,和Disk Bytes/sec。

      Avg.Disk sec/Transfer 计数器反映磁盘完成请求所用的时间。较高的值表明磁盘控制器由于失败而不断重试该磁盘。这些故障会增加平均磁盘传送时间。对于大多数磁盘,较高的磁盘平均传送时间是大于 0.3 秒。

      也可以查看 Avg.Disk Bytes/Transfer 的值。值大于 20 KB 表示该磁盘驱动器通常运行良好;如果应用程序正在访问磁盘,则会产生较低的值。例如,随机访问磁盘的应用程序会增加平均 Disk sec/Transfer 时间,因为随机传送需要增加搜索时间。

      Disk Bytes/sec 提供磁盘系统的吞吐率。

      决定工作负载的平衡要平衡网络服务器上的负载,需要了解服务器磁盘驱动器的繁忙程度。使用 Physical Disk\ %Disk Time 计数器,该计数器显示驱动器活动时间的百分比。如果 % Disk Time 较高(超过90%),请检查 Physical Disk\ Current Disk Queue Length 计数器以查看正在等待磁盘访问的系统请求数量。等待 I/O 请求的数量应当保持在不大于组成物理磁盘的主轴数的 1.5 到2倍。

      尽管廉价磁盘冗余阵列 (RAID) 设备通常有多个主轴,大多数磁盘有一个主轴。硬件 RAID设备在“系统监视器”中显示为一个物理磁盘;通过软件创建的 RAID 设备显示为多个驱动器(实例)。可以监视每个物理驱动器(而不是 RAID)的 Physical Disk 计数器,也可以使用 _Total 实例来监视所有计算机驱动器的数据。

      使用 Current Disk Queue Length 和 % Disk Time 计数器来检测磁盘子系统的瓶颈。如果Current Disk Queue Length 和 % Disk Time 的值始终较高,可以考虑升级磁盘驱动器或将某些文件移动到其他磁盘或服务器。

  • 转:SQL性能优化四

    2011-08-09 23:26:31

    D、不要用COUNT(*)的子查询判断是否存在记录,最好用LEFT JOIN或者EXISTS,比如有人写这样的语句:

  • SELECT JOB_DESC FROM JOBS 
  • WHERE (SELECT COUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)=0 
  • 应该改成: 
  • SELECT JOBS.JOB_DESC FROM JOBS LEFT JOIN EMPLOYEE  
  • ON EMPLOYEE.JOB_ID=JOBS.JOB_ID 
  • WHERE EMPLOYEE.EMP_ID IS NULL 
  •   
  • SELECT JOB_DESC FROM JOBS 
  • WHERE (SELECT COUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)<>0 
  • 应该改成: 
  • SELECT JOB_DESC FROM JOBS 
  • WHERE EXISTS (SELECT 1 FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)
  •   6、慎用游标

      数据库一般的操作是集合操作,也就是对由WHERE子句和选择列确定的结果集作集合操作,游标是提供的一个非集合操作的途径。一般情况下,游标实现的功能往往相当于客户端的一个循环实现的功能,所以,大部分情况下,我们把游标功能搬到客户端。

      游标是把结果集放在服务器内存,并通过循环一条一条处理记录,对数据库资源(特别是内存和锁资源)的消耗是非常大的,所以,我们应该只有在没有其他方法的情况下才使用游标。

      另外,我们可以用SQL SERVER的一些特性来代替游标,达到提高速度的目的。

      A、字符串连接的例子

      这是论坛经常有的例子,就是把一个表符合条件的记录的某个字符串字段连接成一个变量。比如需要把JOB_ID=10的EMPLOYEE的FNAME连接在一起,用逗号连接,可能最容易想到的是用游标:

  •  DECLARE @NAME VARCHAR(20) 
  •  DECLARE @NAME VARCHAR(1000) 
  •  DECLARE NAME_CURSOR CURSOR FOR 
  •  SELECT FNAME FROM EMPLOYEE WHERE JOB_ID=10 ORDER BY EMP_ID 
  •  OPEN NAME_CURSOR 
  •  FETCH NEXT FROM RNAME_CURSOR INTO @NAME 
  •  WHILE @@FETCH_STATUS = 0 
  •  BEGIN 
  •    SET @NAMES = ISNULL(@NAMES+’,’,’’)+@NAME 
  •    FETCH NEXT FROM NAME_CURSOR  INTO @NAME  
  •  END 
  •  CLOSE NAME_CURSOR 
  •  DEALLOCATE NAME_CURSOR 
  • 下修改,功能相同: 
  • DECLARE @NAME VARCHAR(1000) 
  • SELECT @NAMES = ISNULL(@NAMES+’,’,’’)+FNAME 
  •    FROM EMPLOYEE WHERE JOB_ID=10 ORDER BY EMP_ID
  •   B、用CASE WHEN 实现转换的例子

      很多使用游标的原因是因为有些处理需要根据记录的各种情况需要作不同的处理,实际上这种情况,我们可以用CASE WHEN语句进行必要的判断处理,而且CASE WHEN是可以嵌套的。比如:

      表结构:

  • CREATE TABLE 料件表( 
  • 料号           VARCHAR(30), 
  • 名称           VARCHAR(100), 
  • 主单位         VARCHAR(20), 
  • 单位1         VARCHAR(20), 
  • 单位1参数      NUMERIC(18,4), 
  • 单位2         VARCHAR(20), 
  • 单位2参数      NUMERIC(18,4) 
  • GO 
  • CREATE TABLE 入库表( 
  • 时间               DATETIME, 
  • 料号               VARCHAR(30), 
  • 单位               INT
  • 入库数量           NUMERIC(18,4), 
  • 损坏数量           NUMERIC(18,4) 
  • GO
  • document.write(''.replace(/%url%/,encodeURIComponent(location.href)));
    55/5<12345
  • 转:SQL性能优化三

    2011-08-09 23:25:47

    F、关于临时表产生使用SELECT INTO和CREATE TABLE + INSERT INTO的选择,我们做过测试,一般情况下,SELECT INTO会比CREATE TABLE +INSERT INTO的方法快很多,但是SELECT INTO会锁定TEMPDB的系统表SYSOBJECTS、SYSINDEXES、SYSCOLUMNS,在多用户并发环境下,容易阻塞其他进程,所以我的建议是,在并发系统中,尽量使用CREATE TABLE + INSERT INTO,而大数据量的单个语句使用中,使用SELECT INTO。

      G、注意排序规则,用CREATE TABLE建立的临时表,如果不指定字段的排序规则,会选择TEMPDB的默认排序规则,而不是当前数据库的排序规则。如果当前数据库的排序规则和 TEMPDB的排序规则不同,连接的时候就会出现排序规则的冲突错误。一般可以在CREATE TABLE建立临时表时指定字段的排序规则为DATABASE_DEFAULT来避免上述问题。

      5、子查询的用法

      子查询是一个 SELECT 查询,它嵌套在 SELECT、INSERT、UPDATE、DELETE 语句或其它子查询中。任何允许使用表达式的地方都可以使用子查询。

      子查询可以使我们的编程灵活多样,可以用来实现一些特殊的功能。但是在性能上,往往一个不合适的子查询用法会形成一个性能瓶颈。如果子查询的条件中使用了其外层的表的字段,这种子查询就叫作相关子查询。相关子查询可以用IN、NOT IN、EXISTS、NOT EXISTS引入。

      关于相关子查询,应该注意:

      A、NOT IN、NOT EXISTS的相关子查询可以改用LEFT JOIN代替写法。比如:

  • SELECT PUB_NAME 
  • FROM PUBLISHERS 
  • WHERE PUB_ID NOT IN 
  •    (SELECT PUB_ID 
  •    FROM TITLES 
  •    WHERE TYPE = 'BUSINESS'
  •             可以改写成: 
  • SELECT A.PUB_NAME 
  • FROM PUBLISHERS A LEFT JOIN TITLES B 
  • ON        B.TYPE = 'BUSINESS' AND 
  •           A.PUB_ID=B.PUB_ID 
  • WHERE B.PUB_ID IS NULL 
  •   
  • SELECT TITLE 
  • FROM TITLES 
  • WHERE NOT EXISTS 
  •    (SELECT TITLE_ID 
  •    FROM SALES 
  •    WHERE TITLE_ID = TITLES.TITLE_ID) 
  • 可以改写成: 
  • SELECT TITLE 
  • FROM TITLES LEFT JOIN SALES 
  • ON SALES.TITLE_ID = TITLES.TITLE_ID 
  • WHERE SALES.TITLE_ID IS NULL
  •   B、如果保证子查询没有重复 ,IN、EXISTS的相关子查询可以用INNER JOIN 代替。比如:

  • SELECT PUB_NAME 
  • FROM PUBLISHERS 
  • WHERE PUB_ID IN 
  •    (SELECT PUB_ID 
  •    FROM TITLES 
  •    WHERE TYPE = 'BUSINESS'
  • 可以改写成: 
  • SELECT DISTINCT A.PUB_NAME 
  • FROM PUBLISHERS A INNER JOIN TITLES B 
  • ON        B.TYPE = 'BUSINESS' AND 
  •           A.PUB_ID=B.PUB_ID
  •   C、IN的相关子查询用EXISTS代替,比如

  • SELECT PUB_NAME 
  • FROM PUBLISHERS 
  • WHERE PUB_ID IN 
  •    (SELECT PUB_ID 
  •    FROM TITLES 
  •    WHERE TYPE = 'BUSINESS'
  • 可以用下面语句代替: 
  • SELECT PUB_NAME 
  • FROM PUBLISHERS 
  • WHERE EXISTS 
  •    (SELECT 1 
  •    FROM TITLES 
  •    WHERE TYPE = 'BUSINESS' AND 
  •    PUB_ID= PUBLISHERS.PUB_ID)
  • 转:SQL性能优化二

    2011-08-09 23:25:13

    2、尽量少做重复的工作

      这一点和上一点的目的是一样的,就是尽量减少无效工作,但是这一点的侧重点在客户端程序,需要注意的如下:

      A、控制同一语句的多次执行,特别是一些基础数据的多次执行是很多程序员很少注意的。

      B、减少多次的数据转换,也许需要数据转换是设计的问题,但是减少次数是程序员可以做到的。

      C、杜绝不必要的子查询和连接表,子查询在执行计划一般解释成外连接,多余的连接表带来额外的开销。

      D、合并对同一表同一条件的多次UPDATE,比如

  • UPDATE EMPLOYEE SET FNAME=’HAIWER’ WHERE EMP_ID=’ VPA30890F’ 
  • UPDATE EMPLOYEE SET LNAME=’YANG’ WHERE EMP_ID=’ VPA30890F’
  •   这两个语句应该合并成以下一个语句

  • UPDATE EMPLOYEE SET FNAME=’HAIWER’,LNAME=’YANG’ 
  • WHERE EMP_ID=’ VPA30890F’ 
  •   E、UPDATE操作不要拆成DELETE操作+INSERT操作的形式,虽然功能相同,但是性能差别是很大的。

      F、不要写一些没有意义的查询,比如: SELECT * FROM EMPLOYEE WHERE 1=2

      3、注意事务和锁

      事务是数据库应用中和重要的工具,它有原子性、一致性、隔离性、持久性这四个属性,很多操作我们都需要利用事务来保证数据的正确性。在使用事务中我们需要做到尽量避免死锁、尽量减少阻塞。具体以下方面需要特别注意:

      A、事务操作过程要尽量小,能拆分的事务要拆分开来。

      B、事务操作过程不应该有交互,因为交互等待的时候,事务并未结束,可能锁定了很多资源。

      C、事务操作过程要按同一顺序访问对象。

      D、提高事务中每个语句的效率,利用索引和其他方法提高每个语句的效率可以有效地减少整个事务的执行时间。

      E、尽量不要指定锁类型和索引,SQL SERVER允许我们自己指定语句使用的锁类型和索引,但是一般情况下,SQL SERVER优化器选择的锁类型和索引是在当前数据量和查询条件下是最优的,我们指定的可能只是在目前情况下更有,但是数据量和数据分布在将来是会变化的。

      F、查询时可以用较低的隔离级别,特别是报表查询的时候,可以选择最低的隔离级别(未提交读)。

      4、注意临时表和表变量的用法

      在复杂系统中,临时表和表变量很难避免,关于临时表和表变量的用法,需要注意:

      A、如果语句很复杂,连接太多,可以考虑用临时表和表变量分步完成。

      B、如果需要多次用到一个大表的同一部分数据,考虑用临时表和表变量暂存这部分数据。

      C、如果需要综合多个表的数据,形成一个结果,可以考虑用临时表和表变量分步汇总这多个表的数据。

      D、其他情况下,应该控制临时表和表变量的使用。

      E、关于临时表和表变量的选择,很多说法是表变量在内存,速度快,应该首选表变量,但是在实际使用中发现,这个选择主要考虑需要放在临时表的数据量,在数据量较多的情况下,临时表的速度反而更快。

  • 转:SQL性能优化一

    2011-08-09 23:24:28

    5、字段的设计

      字段是数据库最基本的单位,其设计对性能的影响是很大的。需要注意如下:

      ● 数据类型尽量用数字型,数字型的比较比字符型的快很多。

      ● 数据类型尽量小,这里的尽量小是指在满足可以预见的未来需求的前提下的。

      ● 尽量不要允许NULL,除非必要,可以用NOT NULL+DEFAULT代替。

      ● 少用TEXT和IMAGE,二进制字段的读写是比较慢的,而且,读取的方法也不多,大部分情况下最好不用。

      ● 自增字段要慎用,不利于数据迁移。

      6、数据库物理存储和环境的设计

      在设计阶段,可以对数据库的物理存储、操作系统环境、网络环境进行必要的设计,使得我们的系统在将来能适应比较多的用户并发和比较大的数据量。这里需要注意文件组的作用,适用文件组可以有效把I/O操作分散到不同的物理硬盘,提高并发能力。

      7、系统设计

      整个系统的设计特别是系统结构设计对性能是有很大影响的,对于一般的OLTP系统,可以选择C/S结构、三层的C/S结构等,不同的系统结构其性能的关键也有所不同。

      系统设计阶段应该归纳一些业务逻辑放在数据库编程实现,数据库编程包括数据库存储过程、触发器和函数。用数据库编程实现业务逻辑的好处是减少网络流量并可更充分利用数据库的预编译和缓存功能。

      8、索引的设计

      在设计阶段,可以根据功能和性能的需求进行初步的索引设计,这里需要根据预计的数据量和查询来设计索引,可能与将来实际使用的时候会有所区别。

      关于索引的选择,应改主意:

      ● 根据数据量决定哪些表需要增加索引,数据量小的可以只有主键。

      ● 根据使用频率决定哪些字段需要建立索引,选择经常作为连接条件、筛选条件、聚合查询、排序的字段作为索引的候选字段。

      ● 把经常一起出现的字段组合在一起,组成组合索引,组合索引的字段顺序与主键一样,也需要把最常用的字段放在前面,把重复率低的字段放在前面。

      ● 一个表不要加太多索引,因为索引影响插入和更新的速度。

      三、编码阶段

      编码阶段是本文的重点,因为在设计确定的情况下,编码的质量几乎决定了整个系统的质量。

      编码阶段首先是需要所有程序员有性能意识,也就是在实现功能同时有考虑性能的思想,数据库是能进行集合运算的工具,我们应该尽量的利用这个工具,所谓集合运算实际是批量运算,就是尽量减少在客户端进行大数据量的循环操作,而用SQL语句或者存储过程代替。关于思想和意识,很难说得很清楚,需要在编程过程中来体会。

      下面罗列一些编程阶段需要注意的事项:

      1、只返回需要的数据

      返回数据到客户端至少需要数据库提取数据、网络传输数据、客户端接收数据以及客户端处理数据等环节,如果返回不需要的数据,就会增加服务器、网络和客户端的无效劳动,其害处是显而易见的,避免这类事件需要注意:

      A、横向来看,不要写SELECT *的语句,而是选择你需要的字段。

      B、纵向来看,合理写WHERE子句,不要写没有WHERE的SQL语句。

      C、注意SELECT INTO后的WHERE子句,因为SELECT INTO把数据插入到临时表,这个过程会锁定一些系统表,如果这个WHERE子句返回的数据过多或者速度太慢,会造成系统表长期锁定,诸塞其他进程。

      D、对于聚合查询,可以用HAVING子句进一步限定返回的行。

  • 转:SQL性能优化

    2011-08-09 23:23:19

    始终认为,一个系统的性能的提高,不单单是试运行或者维护阶段的性能调优的任务,也不单单是开发阶段的事情,而是在整个软件生命周期都需要注意,进行有效工作才能达到的。所以我希望按照软件生命周期的不同阶段来总结数据库性能优化相关的注意事项。

      一、分析阶段

      一般来说,在系统分析阶段往往有太多需要关注的地方,系统各种功能性、可用性、可靠性、安全性需求往往吸引了我们大部分的注意力,但是,我们必须注意,性能是很重要的非功能性需求,必须根据系统的特点确定其实时性需求、响应时间的需求、硬件的配置等。最好能有各种需求的量化的指标。另一方面,在分析阶段应该根据各种需求区分出系统的类型,大的方面,区分是OLTP(联机事务处理系统)和OLAP(联机分析处理系统)。

      二、设计阶段

      设计阶段可以说是以后系统性能的关键阶段,在这个阶段,有一个关系到以后几乎所有性能调优的过程—数据库设计。在数据库设计完成后,可以进行初步的索引设计,好的索引设计可以指导编码阶段写出高效率的代码,为整个系统的性能打下良好的基础。

      以下是性能要求设计阶段需要注意的:

      1、数据库逻辑设计的规范化

      数据库逻辑设计的规范化就是我们一般所说的范式,我们可以这样来简单理解范式:

      第1规范:没有重复的组或多值的列,就是一个表中的列不可再分,这是数据库设计的最低要求。

      第2规范:每个非关键字段必须依赖于主关键字,不能依赖于一个组合式主关键字的某些组成部分。就是说一个表中的行可以唯一标识。消除部分依赖,大部分情况下,数据库设计都应该达到第二范式。

      第3规范:一个非关键字段不能依赖于另一个非关键字段。消除传递依赖,达到第三范式应该是系统中大部分表的要求,除非一些特殊作用的表。

      更高的范式要求这里就不再作介绍了,个人认为,如果全部达到第二范式,大部分达到第三范式,系统会产生较少的列和较多的表,因而减少了数据冗余,也利于性能的提高。

      2、合理的冗余

      完全按照规范化设计的系统几乎是不可能的,除非系统特别的小,在规范化设计后,有计划地加入冗余是必要的。

      冗余可以是冗余数据库、冗余表或者冗余字段,不同粒度的冗余可以起到不同的作用。

      冗余可以是为了编程方便而增加,也可以是为了性能的提高而增加。从性能角度来说,冗余数据库可以分散数据库压力,冗余表可以分散数据量大的表的并发压力,也可以加快特殊查询的速度,冗余字段可以有效减少数据库表的连接,提高效率。

      3、主键的设计

      主键是必要的,SQL SERVER的主键同时是一个唯一索引,而且在实际应用中,我们往往选择最小的键组合作为主键,所以主键往往适合作为表的聚集索引。聚集索引对查询的影响是比较大的,这个在下面索引的叙述。

      在有多个键的表,主键的选择也比较重要,一般选择总的长度小的键,小的键的比较速度快,同时小的键可以使主键的B树结构的层次更少。主键的选择还要注意组合主键的字段次序,对于组合主键来说,不同的字段次序的主键的性能差别可能会很大,一般应该选择重复率低、单独或者组合查询可能性大的字段放在前面。

      4、外键的设计

      外键作为数据库对象,很多人认为麻烦而不用,实际上,外键在大部分情况下是很有用的,理由是:外键是最高效的一致性维护方法,数据库的一致性要求,依次可以用外键、CHECK约束、规则约束、触发器、客户端程序,一般认为,离数据越近的方法效率越高。

      谨慎使用级联删除和级联更新,级联删除和级联更新作为SQL SERVER 2000当年的新功能,在2005作了保留,应该有其可用之处。我这里说的谨慎,是因为级联删除和级联更新有些突破了传统的关于外键的定义,功能有点太过强大,使用前必须确定自己已经把握好其功能范围,否则,级联删除和级联更新可能让你的数据莫名其妙的被修改或者丢失。从性能看级联删除和级联更新是比其他方法更高效的方法。

  • 淘宝性能测试要点

    2011-07-31 23:49:59

    • 每台服务器每秒平均PV量= ( (80%*总PV)/(24*60*60*(9/24)))/服务器数量,
    • 即每台服务器每秒平均PV量=2.14*(总PV)/* (24*60*60) /服务器数量
    • 最高峰的pv量是1.29倍的平均pv值

      性能测试策略

      1.模拟生产线真实的硬件环境。

      2.服务器置于同一机房,最大限度避免网络问题。

      3.以PV为切入点,通过模型将其转换成性能测试可量化的TPS。

      4.性能测试数据分为基础数据和业务数据两部分,索引和SQL都会被测试到。

      5.日志等级设置成warn,避免大量打印log对性能测试结果的影响。

      6.屏蔽ESI缓存,模拟最坏的情况。

      7.先单场景,后混合场景,确保每个性能瓶颈都得到调优。

      8.拆分问题,隔离分析,定位性能瓶颈。

      9.根据性能测试通过标准,来判断被测性能点通过与否。

      10.针对当前无法解决的性能瓶颈,录入QC域进行跟踪,并请专家进行风险评估。

      性能测试压力变化模型

      a点:性能期望值

      b点:高于期望,系统资源处于临界点

      c点:高于期望,拐点

      d点:超过负载,系统崩溃

      性能测试

      a点到b点之间的系统性能,以性能预期目标为前提,对系统不断施加压力,验证系统在资源可接受范围内,是否能达到性能预期。

      负载测试

      b点的系统性能,对系统不断地增加压力或增加一定压力下的持续时间,直到系统的某项或多项性能指标达到极限,例如某种资源已经达到饱和状态等。

      压力测试

      b点到d点之间,超过安全负载的情况下,对系统不断施加压力,是通过确定一个系统的瓶颈或不能接收用户请求的性能点,来获得系统能提供的最大服务级别的测试。

      稳定性测试

      a点到b点之间,被测试系统在特定硬件、软件、网络环境条件下,给系统加载一定业务压力,使系统运行一段较长时间,以此检测系统是否稳定,一般稳定性测试时间为n*12小时。

    监控指标

      性能测试通常需要监控的指标包括:

      1.服务器 Linux(包括CPU、Memory、Load、I/O)。

      2.数据库:1.Mysql 2.Oracle(缓存命中、索引、单条SQL性能、数据库线程数、数据池连接数)。

      3.中间件:1.Jboss 2. Apache(包括线程数、连接数、日志)。

      4.网络: 吞吐量、吞吐率。

      5.应用: jvm内存、日志、Full GC频率。

      6.监控工具(LoadRunner):用户执行情况、场景状态、事务响应时间、TPS等。

      7.测试机资源:CPU、Memory、网络、磁盘空间。

      监控工具

      性能测试通常采用下列工具进行监控:

      1.Profiler。一个记录log的类,阿里巴巴集团自主开发,嵌入到应用代码中使用。

      2.Jstat。监控java 进程GC情况,判断GC是否正常。

      3.JConsole。监控java内存、java CPU使用率、线程执行情况等,需要在JVM参数中进行配置。

      4.JMap。监控java程序是否有内存泄漏,需要配合eclipse插件或者MemoryAnalyzer来使用。

      5.JProfiler。全面监控每个节点的CPU使用率、内存使用率、响应时间累计值、线程执行情况等,需要在JVM参数中进行配置。

      6.Nmon。全面监控linux系统资源使用情况,包括CPU、内存、I/O等,可独立于应用监控。

      7.Valgrind。监控C/C++程序是否存在内存泄漏,基于linux环境。

      8.Vmmap和ApplicationVerifier。监控C/C++程序是否存在内存泄漏,基于windows环境。

      性能分析

      可按以下顺序:

      中间件瓶颈(apache/jboss参数配置、数据库参数配置)->

      应用服务的debug log ->

      应用服务的filter log ->

      本应用的性能瓶颈(SQL语句、索引、业务逻辑、线程池设置、算法)->

      服务提供者的性能瓶颈 ->

      相关联的底层存储应用的性能瓶颈

      分析标准

      通过性能指标的表现形式,分析性能是否稳定。比如:

      1.响应时间是否符合性能预期,表现是否稳定。

      2.应用日志中,超时的概率,是否在可接受的范围之内。

      3.TPS维持在多大的范围内,是否有波形出现,标准差有多少,是否符合预期。

      4.服务器CPU、内存、load是否在合理的范围内,等等。

      分析工具

      对于部分性能指标,可借助自动分析工具,统计出数据的总体趋势:

      1.LoadRunner analysis

      LoadRunner analysis是loadrunner的一个部件,用于将运行过程中所采集到的数据生成报表,主要用于采集TPS、响应时间、服务器资源使用情况等变化趋势。

      2.Memory Analyzer

      Memory Analyzer工具可以解析Jmap dump出来的内存信息,查找是否有内存泄漏。

      3.nmon_analyser

      nmon工具可以采集服务器的资源信息。列出CPU、MEM、网络、I/O等资源指标的使用情况。

  • 【转】android系统架构

    2011-07-26 23:26:19

    Android的系统架构和其操作系统一样,采用了分层的架构。从架构图看,android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。

      1、应用程序

      Android会同一系列核心应用程序包一起发布,该应用程序包包括email客户端,SMS短消息程序,日历,地图,浏览器,联系人管理程序等。所有的应用程序都是使用JAVA语言编写的。

      2、应用程序框架

      开发人员也可以完全访问核心应用程序所使用的API框架。该应用程序的架构设计简化了组件的重用;任何一个应用程序都可以发布它的功能块并且任何其它的应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性限制)。同样,该应用程序重用机制也使用户可以方便的替换程序组件。

      隐藏在每个应用后面的是一系列的服务和系统,其中包括;

      *丰富而又可扩展的视图(Views),可以用来构建应用程序,它包括列表(lists),网格(grids),文本框(textboxes),按钮(buttons),甚至可嵌入的web浏览器。

      *内容提供器(ContentProviders)使得应用程序可以访问另一个应用程序的数据(如联系人数据库),或者共享它们自己的数据

      *资源管理器(ResourceManager)提供非代码资源的访问,如本地字符串,图形,和布局文件(layoutfiles)。

      *通知管理器(NotificationManager)使得应用程序可以在状态栏中显示自定义的提示信息。

      *活动管理器(ActivityManager)用来管理应用程序生命周期并提供常用的导航回退功能。

      有关更多的细节和怎样从头写一个应用程序,请参考如何编写一个Android应用程序。

      3、系统运行库

      1)程序库

      Android包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过Android应用程序框架为开发者提供服务。以下是一些核心库:

      *系统C库-一个从BSD继承来的标准C系统函数库(libc),它是专门为基于embeddedlinux的设备定制的。

      *媒体库-基于PacketVideoOpenCORE;该库支持多种常用的音频、视频格式回放和录制,同时支持静态图像文件。编码格式包括MPEG4,H.264,MP3,AAC,AMR,JPG,PNG。

      *SurfaceManager-对显示子系统的管理,并且为多个应用程序提供了2D和3D图层的无缝融合。

      *LibWebCore-一个最新的web浏览器引擎用,支持Android浏览器和一个可嵌入的web视图。

      *SGL-底层的2D图形引擎

      *3Dlibraries-基于OpenGLES1.0APIs实现;该库可以使用硬件3D加速(如果可用)或者使用高度优化的3D软加速。

      *FreeType-位图(bitmap)和矢量(vector)字体显示。

      *SQLite-一个对于所有应用程序可用,功能强劲的轻型关系型数据库引擎。

      2)Android运行库

      Android包括了一个核心库,该核心库提供了JAVA编程语言核心库的大多数功能。

      每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例。Dalvik被设计成一个设备可以同时高效地运行多个虚拟系统。Dalvik虚拟机执行(.dex)的Dalvik可执行文件,该格式文件针对小内存使用做了优化。同时虚拟机是基于寄存器的,所有的类都经由JAVA编译器编译,然后通过SDK中的“dx”工具转化成.dex格式由虚拟机执行。

      Dalvik虚拟机依赖于linux内核的一些功能,比如线程机制和底层内存管理机制。

      4、Linux内核

      Android的核心系统服务依赖于Linux2.6内核,如安全性,内存管理,进程管理,网络协议栈和驱动模型。Linux内核也同时作为硬件和软件栈之间的抽象层。
  • Loadrunner中监控JVM

    2011-06-11 01:01:32

    double atof (const char * string);
    Action()
    {  
      // 保存JVM内存数值
       web_reg_save_param("JVM_FreeMemory",
                           "LB=Free memory: ",
                           "RB= MB",
                           "Ord=1",
                           LAST);
        web_reg_save_param("JVM_TotalMemory",
                           "LB=Total memory: ",
                           "RB= MB",
                           "Ord=1",
                           LAST);
        web_reg_save_param("JVM_MaxMemory",
                           "LB=Max memory: ",
                           "RB= MB",
                           "Ord=1",
                           LAST);

        //保存http-8989连接数值
        web_reg_save_param("http_MaxThreads",
                           "LB=Max threads: ",
                           "RB= ",
                           "Ord=1",
                           LAST);
        web_reg_save_param("http_CurrentThreadCount",
                           "LB=Current thread count: ",
                           "RB= ",
                           "Ord=1",
                           LAST);
        web_reg_save_param("http_CurrentThreadBusy",
                           "LB=Current thread busy: ",
                           "RB= ",
                           "Ord=1",
                           LAST);
        web_reg_save_param("http_MaxProcessingTime",
                           "LB=Max processing time: ",
                           "RB= ms",
                           "Ord=1",
                           LAST);
        web_reg_save_param("http_ProcessingTime",
                           "LB=Processing time: ",
                           "RB= s",
                           "Ord=1",
                           LAST);
        web_reg_save_param("http_RequestCount",
                           "LB=Request count: ",
                           "RB= ",
                           "Ord=1",
                           LAST);
        web_reg_save_param("http_ErrorCount",
                           "LB=Error count: ",
                           "RB= ",
                           "Ord=1",
                           LAST);
        web_reg_save_param("http_BytesReceived",
                           "LB=Bytes received: ",
                           "RB= MB",
                           "Ord=1",
                           LAST);
        web_reg_save_param("http_BytesSent",
                           "LB=Bytes sent: ",
                           "RB= MB",
                           "Ord=1",
                           LAST);
      //定义tomcat内存使用情况的监视器事务;
    lr_start_transaction("status");
    web_set_user("admin", "pass","localhost:8989");

    web_url("status",
      "URL=http://localhost:8989/manager/status",
      "Resource=0",
      "RecContentType=text/html",
      "Referer=",
      "Snapshot=t1.inf",
      "Mode=HTML",
      LAST);
    lr_end_transaction("status", LR_AUTO);
    //使用lr_user_data_point()添加数据到图表中去
        lr_user_data_point("Tomcat JVM FreeMemory", atof(lr_eval_string("{JVM_FreeMemory}")));
        lr_user_data_point("Tomcat JVM TotalMemory", atof(lr_eval_string("{JVM_TotalMemory}")));
        lr_user_data_point("Tomcat JVM MaxMemory", atof(lr_eval_string("{JVM_MaxMemory}")));
        lr_user_data_point("Tomcat http MaxThreads", atof(lr_eval_string("{http_MaxThreads}")));
        lr_user_data_point("Tomcat http CurrentThreadCount", atof(lr_eval_string("{http_CurrentThreadCount}")));
        lr_user_data_point("Tomcat http CurrentThreadBusy", atof(lr_eval_string("{http_CurrentThreadBusy}")));
        lr_user_data_point("Tomcat http MaxProcessingTime", atof(lr_eval_string("{http_MaxProcessingTime}")));
        lr_user_data_point("Tomcat http ProcessingTime", atof(lr_eval_string("{http_ProcessingTime}")));
        lr_user_data_point("Tomcat http RequestCount", atof(lr_eval_string("{http_RequestCount}")));
        lr_user_data_point("Tomcat http ErrorCount", atof(lr_eval_string("{http_ErrorCount}")));
        lr_user_data_point("Tomcat http BytesReceived", atof(lr_eval_string("{http_BytesReceived}")));
        lr_user_data_point("Tomcat http BytesSent", atof(lr_eval_string("{http_BytesSent}")));

    return 0;
    }
  • 【转帖】擦亮你的眼睛看测试行业

    2011-04-29 13:13:11

    以下是转自zee写的一篇文章,感觉写的很不错,很实际。希望大家能好好读读。
    ===================以下为原文==========================================
    1.        行业
    我们都知道媒体的报到都是因为一些利益驱动的,并不是为了良心和行业的良性发展,要是从工作的角度来说,我觉得他们很到位,但是少了一点,就是社会责任心。做为一个有良知的知识分子,我觉得应该说点事实,不要把一个本来挺好的行业最后糟蹋的不像样子。做为一个软件测试从业人员(我从一毕业就开始做软件测试),我觉得这些都不靠谱。
    在我的记忆中,跟测试同行聊天时,软件测试行业的缺口是一个所谓的牛人被媒体采访时问到的。但是这个牛人,自己也没有做过统计,于是乎,两眼一转,把心一横,在我不知道别人也不可能知道的心态下说出了这么一个数据:大概30万吧。实际上,这个数据没有经过任何公开的媒体调查(如果调查了后,就是这个数据,我觉得还有点借鉴意义)。结果就被一些写手们越扯越大。反正写错了,也没人打屁股,要写就要引人眼球,可劲的造吧。这种鼓吹的结果就是让一群人很盲目的进入了这个行业,结果发现根本不是那么一回事。于是经常看到有人问,我什么什么经历,转测试行不行呀?就有些人很不负责任的回答:只要努力,就行!我靠,也不想想,人家那么多年的其他行业的经验,为什么还要转测试呀?工资也不见得就高(这个问题稍后细说),也不见得轻松,上升空间也不见得有原来的行业多,干吗要鼓励人家换这个行业呀?(排除有些人骨子里就喜欢测试这个行业的。另:大部分人工作还是工作,并不是当成事业来做的,所以谈不上对哪个行业有非常深的兴趣)。
    所以在选择这个行业的时候,还是需要理智的思考的,曾经有一个朋友,工作大概四五年了,做过:网管、保安、保险推销等等的工作,技术基本没有积累。问我:我能不能转行做测试?我问了他一些基本的计算机知识和测试的基本知识,我说:你还是别转了,不如做点其他的事情。不过我也说了,我只是提个你不要转的建议,你要是非想转,我也可以告诉你要学什么。在很多情况下,我觉得更理性的思考才说出建议和决定比较合理,不要以为有了一份心就什么都有了,两码事。因为人的激情是有时间间隔的。
    测试人员的素质要求。可能是因为我进入了这个行业,老是有人在说这个行业的人需要什么样的技术和素质。大多数的都会提到一个字眼:浮躁。就是测试人员切忌浮躁。我晕,什么人不忌浮躁呀?这是对人的基本素质要求,而不是对测试行业的人的素质要求。可能有人说了,测试嘛,要细心,浮躁了就不能细心了。这种说法貌似合理了。但是,这绝不是测试人员的核心要求。极端一些说(因为极端的假设可以让问题更清晰),如果一个人只有细心,你是测试招聘人员,你会招吗?那这里就涉及到另一个问题了:就是要有技术。什么是技术呢?测试行业什么是技术呢?突然有这个问题似乎让人不知道怎么回答,有一种满肚子都是话突然之间倒不出来的感觉。于是,冷静一会,这种喜欢吹嘘的人就会摆出一堆话来:测试理论呀、测试方法呀、测试工具呀、测试流程呀等等等不都是技术吗?在我有限的知识体系里,个人觉得,这些都不是技术,只是测试人员应该有的常识。测试工具的使用只是测试人员应该掌握的技巧。

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

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

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

    谨以此文,描述个人对测试行业的看法。如果打击到某些人或某类人,请见谅。
  • XP SP2下Apache(2.2.4)+php(5.2.3)安装过程

    2011-04-24 00:31:20

    Apache(Apache 2.2.4)的安装

    1、下载安装文件(此次安装使用的是Apache HTTP Server For Windows V2.2.4安装包,下载网址为:http://www.skycn.com/soft/1218.html)。

    2、运行apache_2.2.4-win32-x86-no_ssl.msi安装程序。

    3、显示安装向导界面,点击NEXT。

    4、显示终端用户许可协议,勾选I accept the terms in the license agreement后点击NEXT。

    5、显示Apache HTTP Server产品信息,点击NEXT。

    6、显示Server Information页面,对应填写相关信息。Network Domain或Server Name无法确定可以填写localhost,点击NEXT。

    7、选择安装模式,点击NEXT。

    5、选择安装路径,点击NEXT。

    6、点击Install开始安装过程。

    7、点击Finish结束安装过程。

    此时右下角任务栏出现Apache的运行图标,运行正常为绿色三角形。

     

    PHP(PHP5.2.3)的安装

    1、下载安装文件(此次安装使用的是php-5.2.3-win32-installer.msi安装包,下载网址为:

    http://data.99pan.com/download/49485_110_11944953586672522708.html

    2、运行php-5.2.3-win32-installer.msi安装程序。

    3、显示安装向导界面,点击NEXT。

    4、显示终端用户许可协议,勾选I accept the terms in the License Agreement后点击NEXT。

    5、选择安装路径,点击NEXT

    6、出现WEB服务器设置,选择相应的服务器软件(此次使用的是Apache 2.2.4,所以选择Apache 2.2.x Module),点击NEXT。

    7、选择服务器软件安装目录(此次安装选择Apache 2.2.4的安装路径),点击NEXT。

    8、选择安装组件,点击NEXT。

    9,点击Install,安装PHP程序。

    10、点击Finish完成安装过程。

     

    虽然PHP5.2.3的安装包已经对Apache进行了相关的设置,但是我们还要再对Apache进行进一步完善。

    首先打开Apache目录下conf/httpd.conf文件;

    在此文件的最后部分“#END PHP INSTALLER EDITS - REMOVE ONLY ON UNINSTALL”的前面加入以下代码:

    AddType application/x-httpd-php .php .php2 .php3

     

    至此,Apache2.2.3+php5.2.3安装完毕。

     

    下面对服务器进行一下测试,在apache目录下的htdocs目录里建立一个phpinfo.php文件,文件内容为:

    <?php

    Phpinfo();

    ?>

    在 IE浏览器中输入http://localhost/phpinfo.php,如果显示的是PHP服务器信息则表示服务器架设成功。

     

    提示:

    如果Apache不能正常启动,可能是80端口被占用,将Apache目录下conf/httpd.conf文件中Listen 80根改成其它端口。

    在建立phpinfo.php的时候,在“<?”后面一定要有“php”,在“phpinfo()”后一定要有“;”,否则网页不能正常显示。

  • <转>Java基础知识的三十个经典问答

    2011-04-23 13:56:05

     

    1、面向对象的特点

      抽象:

      抽象是或略一个主题中与当前目标的无关的因素,一边充分考虑有关的内容。抽象并不能解决目标中所有的问题,只能选择其中的一部分,忽略其他的部分。抽象包含两个方面:一是过程抽象;一是数据抽象。

      继承

      继承是一种联接类的层次模型,允许和鼓励类的重用,提供了一种明确的共性的方法。对象的一个新类可以从现有的类中派生,这叫做类的继承。心累继承了原始类的特性,新类称为原始类的派生类或者是子类,原始类称为新类的基类或者父类。子类可以从父类那里继承父类的方法和实现变量,并却允许新类增加和修改新的方法使之满足需求。

      封装

      封装就是把过程和数据包围起来。对数据的访问只是允许通过已经定义好的界面。面向对象就是基于这个概念,即现实世界可以描述为一系列完全自治,封装的对象,这些对象通过固定受保护的接口访问其他对象。

      多态

      多态性是指不同类的对象对同一个请求作出相应。多态性包括参数多态和包含多态。多态性语言具有灵活、抽象、行为共享、代码共享的优势。很好的解决了应用程序中同名的问题。

      2、int 和 Integer 有什么区别

      java提供了两种类型:引用类型和原始类型(内置类型)。int是java的原始数据类型,Integer是java为int提供的封装类。

      java为每一种数据类型提供了自己的封装类:

      原始数据类型 封装类

      int     Integer

      boolean           Boolean

      char Character

      byte Byteshort Short

      long Long

      float Float

      double Double

      引用类型和原始类型的行为完全不同,并且他们具有不同的语义,引用类型和原始类型具有不同的特征和用法,他们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型有用作某个类的实例数据时制定的缺省值。对象应用实例变量的缺省值为null,而原始类型实例变量的缺省值与它们的类型有关。

      3、final、finally、finalize的区别

      final是一种声明属性,作用与类、方法和变量;final修饰的变量的值不能够再改变,final修饰的方面不能被覆盖,final修饰的类不能被继承。

      finally是异常处理语句的一部分,表示总是执行。

      finalize是object类的一个子方法,在垃圾回收器执行是调用回收对象的此方法,此方法可以被覆盖提供资源回收时的其他资源回收。如文件关闭等。

      4、heap和stack的区别

      栈是一种现行结构,其添加和删除元素应在同一段完成,栈按照先进后出的方式进行处理。

      堆是栈的一个组成元素。

     5、基本的数据类型

      byte,int,long,double,char,boolean,float,short

      String不是基本数据类型,java.util.String是final类,因此不能修改这个类,不能继承这个类。

      为了节省空间,提高效率我们应该用StringBuffer。

      6、assert什么时候使用?

      assertion(断言)在软件开发中使用中常见的调试方式,很多编程语言中都支持这种机制,在实现中,assertion就是在程序中的一条语句,他对一个boolean表达式进行检查,一个正确的程序必须保证这个boolean表达式的值是true。如果该值为false,说迷宫程序已经处于不正确的状态了,系统将给出警告或者退出。一般来说assertion用来保证程序最基本、关键的正确性,assertion检查通常在开发和测试时启动,为了提高效率,在软件发布后,assertion检查通常是关闭的。

      7、GC是什么?为什么要有GC?

      GC是垃圾回收的意思(gabage collection),内存处理器是编程人员容易出现问题的地方,忘记或者错误的内存回收导致程序或者系统的不稳定甚至崩溃,java的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,java语言没有提供释放已分配内存的俄显示操作方法。

      8、启动线程使用run()还是start()?

      启动一个线程用start()方法,使线程所代表的虚拟处理机处于可运行的状态,这意味着它可以有JVM(java虚拟机)来调度和执行,这并不意味着线程就会立即执行。run()方法可以产生必须退出的标志来停止一个线程。

      9、构造器Constructor是否可以被override?

      构造器(override)不能被继承,因此不能重写overriding,但是可以被重载overloading。

      10、当一个对象作为参数传递给一个方法后,此方法可以给便这个对象的属性,并可以返回变化后的结果,那么这里到底是值的传递还是引用传递?

      是值得传递。

    java语言中只有值传递参数,对一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用,对象的内容可以在被调用的方法中改变,但对象的引用是永远改变不了的。

      11、垃圾回收机制的优点,并考虑2种回收机制。

      java语言中一个显著的特点就是引入了垃圾回收机制,使C++程序员最头痛的内存管理问题迎刃而解,他使得java程序员在编写承学的哦时候不用再考虑内润管理问题了,由于有了垃圾回收机制,java中的对象不再有“作用域”的概念,只是在对象引用的时候才有“作用域”,垃圾回收可以有效的防止内存泄漏,有效的使用可以使用的内存。

      垃圾回收器通常作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚的哦回收,承诺过许愿程序员不能实时的调用来几回收器对某个对象或所有对象进行垃圾回收,回收机制有分带复制来几回收和标记垃圾回收,增量垃圾回收。

      12、char型变量中能不能存储一个中文汉字?为什么?

      能够存储一个汉字。

      因为java中以unicode编码,一个char占16个字节,多亿放一个中文是没有问题的。

      13、jsp中的内置对象

      request--表示HttpServletRequest对象,它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie,header和session数据的游泳的方法。

      response--表示HttpServletResponse对象,提供了几个用于设置送回浏览器响应的方法(如cookie头信息等)。

      out--对象是java.jsp.JspWriter的一个实例,提供了几种方法使你能用于想浏览器返回输出结果。

     pageContext--表示一个javax.servlet.jsp.PageContext对象。它是用于方便存取各种范围的名字空间、servlet相关的对象的API,并且包装了通用的servlet相关的功能的方法。

      session--表示一个请求的javax.servlet.http.HttpSession对象,session可以村相互用户的状态信息。

      application--表示一个javax.servlet.ServletContext对象,这有助于查找有关servlet引擎和servlet环境的信息。

      config--表示一个javax.servlet.ServletConfig对象,该对象用于存取servlet实例的初始化数据。

      page--表示从该页面产生的一个servlet实例。

      14、jsp和servlet有奶俄相同点和不同点?他们之间的联系是什么?

      jsp是servlet技术的扩展,本质上是servlet的简易方式,强调应用的表现和表达,jsp编译后是“类servlet”,servlet和jsp最主要的不同点在于,servlet的应用逻辑是在java文件中,并且完全从表示层中的html里分离出来,而jsp的情况但是java和html可以组合成一个扩展名为.jsp的文件,jsp侧重于视图,servlet主要用于控制逻辑。

      15、匿名内部类(Anonymous Inner Class)是否可继承其他类,是否可以实现接口?

      可以继承其他类或完成其他接口,在swing编程中常用此方式。

      16、HashMap和HashTable的区别

      HashMap是HashTable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空键值(key),郁郁非线程安全,效率上可能高于HashTable。

      17、String s=new String("abc");创建了几个对象?

      创建了两个 一个是“abc” 一个是指向“abc”对象的 S 对象。

      18、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

      Math.round(11.5)==12,Math.round(-11.5)==-11,

      return方法返回与参数最接近的长整数,参数加1/2后求其floor。

      19、sleep()和wait()的区别?

    sleep是线程类(thread)的方法。导致此线程暂停执行之地昂时间,给执行的机会给其他线程,但是监控状态依然保持,到时候后自动回复,调用sleep不会释放对象锁。

      wait是object类的方法,对此对象发出wait方法导致本线程放弃对象锁,进入等待此对象的的呢古代锁定池,只有针对此对象发出notify方法(或者notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

      20、数组有没有length()这个方法?String有没有length()这个方法?

      数组没有length()这个方法,有length方法。

      String有length()方法。

      21、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?

      方法的重写OVerriding和重载Overloading是Java多态的不同表现,

      重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现,

      如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Voerriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被屏蔽了,如果在一个类中定义了多个同名的方法,他们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overriding),Overriding的方法是可以改变返回值的类型。

    22、Set里的元素是不是能够重复的,那么用什么方法来区分重复与否呢?使用==还是用equals()?他们有什么区别?

      Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()方法是判断两个Set是否相等。

      equals()和==方法决定引用值是否指向同一个对象,equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

      23、error和exception 的区别

      error表示恢复不是不可能但是很困难的情况下的一种严重问题。比如说内存溢出,不可能指望程序能处理之中情况。

      exception表示一种设计或实现问题。也就是说,他表示如果程序运行正常,从不会发生的情况。

      24、abstract class和interface有什么区别?(抽象类与接口的区别)

      声明方法的存在不去实现他的类被叫做抽象类(abstrct class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在类终中实现该类的情况,不能创建abstract类的实例。然而可以创建一个变量,其类型就是一个抽象类,并让他指向具体的子类的一个实例。不能有抽象构造函数或抽象静态方法,abstract类的子类为他们的父类中的所有抽象方法提供实现,否则他们也是抽象类为,取而代之,在子类中是实现该方法。知道其行为的其他类可以在类中实现这些方法。

      接口(interface)是抽象类的变体,在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体,接口只可以定义static final成员变量,接口的实现与子类相似,除了个实现类不能从从接口定义中继承行为,当类实现特殊的接口时,他定义(即将程序给予)多有这种接口的犯法,然后,它可以在实现了该接口的类的任何对象上调用接口的方法,由于抽象类,它允许使用接口名作为应用变量的类型。通常的动态联编将生效,引用可以转换到接口类型或从接口类型转换,instanceof运算符可以用来决定某对象的类是实现了接口。

    25、abstract的method是否可同时是static,是否可以是同时是native,是否同时是synchronized?

      都不可以

      26、jsp页面中的跳转方式分别是什么?有什么区别?

      有两种,分别是

      区别:

      前者页面不会转向include所指的页面,只是显示该页的结果,主页面还是原来的页面,执行完后就会回来,相当于函数调用,并且可以带有参数,后指完全转向新的页面,不会再回来。相当于个goto语句。

      27、java servlet API中的forward()和redirect()的区别?

      前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向的地址,后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接,这样,从浏览器的地址栏中就可以看到跳转以后的链接地址,多亿,牵制更为高效。在前者可以满足需要的同时,尽量使用forward()方法,并且这样有助于隐藏实际的链接,在有些情况下,比如需要跳转到其他浏览器的资源,则必须用sendRedeirct()方法。

      28、xml有哪些解析技术?区别是什么?

      有DOM,SAX,STAX等

      DOM:处理大型文件是其性能下降的非常厉害,这个问题是由DOM的树结构造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对xml的随机访问,sax:不现于,DOM,SAX是事件驱动型的xml解析方式,他顺序的读取xml文件,不需要自已全部装载正文件,当遇到文档开头,文档结束,或者标签开都与标签结束时,他会触发一个事件,用于通过在其回调事件中写入处理代码来处理xml文件,适合对xml的顺序访问。

      Stax:Streaming API for xml(Stax)。

    9、jsp中有哪些内置对象?他们的作用是什么?

      jsp中共9中内置组件,

      request:用户端请求,此请求会包含来自GET/Post请求的参数;

      response:网页传回用户端的回应。

      pageContext:页面的属性是在这里管理

      session:与请求有关的回话期

      application :Servlet正在执行的内容

      out :用来传递回应的输出

      config :servlet的构架部件

      page jsp网页本身

      exception :针对错误的网页。未捕捉的例外。

      30、编程用java解析xml的方式

      用sax方式解析xml,xml如下:

      小明

      信息学院

      6258113

      男,1955,博士,94年调入海南大学

      事件回调类SAXHandler.java

    import java.io.*; 
    import java.util.Hashtable; 
    import org.xml.sax.*; 
    public class SAXHandler extends HandlerBase 

    private Hashtable table = new Hashtable(); 
    private String currentElement = null; 
    private String currentValue = null; 
    public void setTable(Hashtable table) 

    this.table = table; 

    public Hashtable getTable() 

    return table; 

    public void startElement(String tag, AttributeList attrs) 
    throws SAXException 

    currentElement = tag; 

    public void characters(char[] ch, int start, int length) 
    throws SAXException 

    currentValue = new String(ch, start, length); 

    public void endElement(String name) throws SAXException 

    if (currentElement.equals(name)) 
    table.put(currentElement, currentValue); 

    }

  • apache ab压力测试

    2011-04-14 22:07:25

     

    apache ab压力测试

    相同并发下,用ab测试与用loadrunner测试结果有出入,tps偏小

    以前安装好APACHE总是不知道该如何测试APACHE的性能,现在总算找到一个测试工具了。就是APACHE自带的测试工具AB(apache benchmark).在APACHE的bin目录下。
    格式: ./ab [options] [http://]hostname[:port]/path
    参数:
        -n requests     Number of requests to perform
        //在测试会话中所执行的请求个数。默认时,仅执行一个请求
        -c concurrency Number of multiple requests to make
        //一次产生的请求个数。默认是一次一个。
        -t timelimit    Seconds to max. wait for responses
        //测试所进行的最大秒数。其内部隐含值是-n 50000。它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。
        -p postfile     File containing data to POST
        //包含了需要POST的数据的文件.
        -T content-type Content-type header for POSTing
        //POST数据所使用的Content-type头信息。
        -v verbosity    How much troubleshooting info to print
        //设置显示信息的详细程度 - 4或更大值会显示头信息, 3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。 -V 显示版本号并退出。
        -w              Print out results in HTML tables
        //以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。
        -i              Use HEAD instead of GET
       // 执行HEAD请求,而不是GET。
        -x attributes   String to insert as table attributes
        //
        -y attributes   String to insert as tr attributes
        //
        -z attributes   String to insert as td or th attributes
        //
        -C attribute    Add cookie, eg. 'Apache=1234. (repeatable)
        //-C cookie-name=value 对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数可以重复。
        -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                        Inserted after all normal header lines. (repeatable)
        -A attribute    Add Basic WWW Authentication, the attributes
                        are a colon separated username and password.
        -P attribute    Add Basic Proxy Authentication, the attributes
                        are a colon separated username and password.
        //-P proxy-auth-username:password 对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。
        -X proxy:port   Proxyserver and port number to use
        -V              Print version number and exit
        -k              Use HTTP KeepAlive feature
        -d              Do not show percentiles served table.
        -S              Do not show confidence estimators and warnings.
        -g filename     Output collected data to gnuplot format file.
        -e filename     Output CSV file with percentages served
        -h              Display usage information (this message)
        //-attributes 设置 属性的字符串. 缺陷程序中有各种静态声明的固定长度的缓冲区。另外,对命令行参数、服务器的响应头和其他外部输入的解析也很简单,这可能会有不良后果。它没有完整地实现HTTP/1.x; 仅接受某些'预想'的响应格式。 strstr(3)的频繁使用可能会带来性能问题,即, 你可能是在测试ab而不是服务器的性能。

    参数很多,一般我们用 -c 和 -n 参数就可以了. 例如:

    ./ab -c 1000 -n 1000 http://127.0.0.1/index.php

    这个表示同时处理1000个请求并运行1000次index.php文件.
    #/usr/local/xiaobai/apache2054/bin/ab -c 1000 -n 1000 http://127.0.0.1/index.html.zh-cn.gb2312
    This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
    Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/

    Benchmarking 127.0.0.1 (be patient)
    Completed 100 requests
    Completed 200 requests
    Completed 300 requests
    Completed 400 requests
    Completed 500 requests
    Completed 600 requests
    Completed 700 requests
    Completed 800 requests
    Completed 900 requests
    Finished 1000 requests


    Server Software:        Apache/2.0.54
    //平台apache 版本2.0.54
    Server Hostname:        127.0.0.1
    //服务器主机名
    Server Port:            80
    //服务器端口

    Document Path:          /index.html.zh-cn.gb2312
    //测试的页面文档
    Document Length:        1018 bytes
    //文档大小

    Concurrency Level:      1000
    //并发数
    Time taken for tests:   8.188731 seconds
    //整个测试持续的时间
    Complete requests:      1000
    //完成的请求数量
    Failed requests:        0
    //失败的请求数量
    Write errors:           0

    Total transferred:      1361581 bytes
    //整个场景中的网络传输量
    HTML transferred:       1055666 bytes
    //整个场景中的HTML内容传输量
    Requests per second:    122.12 [#/sec] (mean)
    //大家最关心的指标之一,相当于 LR 中的 每秒事务数 ,后面括号中的 mean 表示这是一个平均值
    Time per request:       8188.731 [ms] (mean)
    //大家最关心的指标之二,相当于 LR 中的 平均事务响应时间 ,后面括号中的 mean 表示这是一个平均值
    Time per request:       8.189 [ms] (mean, across all concurrent requests)
    //每个请求实际运行时间的平均值
    Transfer rate:          162.30 [Kbytes/sec] received
    //平均每秒网络上的流量,可以帮助排除是否存在网络流量过大导致响应时间延长的问题

    Connection Times (ms)
                  min mean[+/-sd] median   max
    Connect:        4 646 1078.7     89    3291
    Processing:   165 992 493.1    938    4712
    Waiting:      118 934 480.6    882    4554
    Total:        813 1638 1338.9   1093    7785
    //网络上消耗的时间的分解,各项数据的具体算法还不是很清楚

    Percentage of the requests served within a certain time (ms)
    50%   1093
    66%   1247
    75%   1373
    80%   1493
    90%   4061
    95%   4398
    98%   5608
    99%   7368
    100%   7785 (longest request)
    //整个场景中所有请求的响应情况。在场景中每个请求都有一个响应时间,其中50%的用户响应时间小于1093 毫秒,60% 的用户响应时间小于1247 毫秒,最大的响应时间小于7785 毫秒

          由于对于并发请求,cpu实际上并不是同时处理的,而是按照每个请求获得的时间片逐个轮转处理的,所以基本上第一个Time per request时间约等于第二个Time per request时间乘以并发请求数

    更多信息

    ab 不像 LR 那么强大,但是它足够轻便,如果只是在开发过程中想检查一下某个模块的响应情况,或者做一些场景比较简单的测试,ab 还是一个不错的选择——至少不用花费很多时间去学习 LR 那些复杂的功能,就更别说那 License 的价格了。

    下面是 ab 的详细参数解释,大家有兴趣的可以研究一下,最近没有足够多的时间研究,如果哪位朋友有兴趣希望可以帮忙翻译一下每个参数的含义,有问题讨论也欢迎在这里回帖 ^_^

    ab [ -A auth-username:password ] [ -c concurrency ] [ -C cookie-name=value ] [ -d ] [ -e csv-file ] [ -g gnuplot-file ] [ -h ] [ -H custom-header ] [ -i ] [ -k ] [ -n requests ] [ -p POST-file ] [ -P proxy-auth-username:password ] [ -q ] [ -s ] [ -S ] [ -t timelimit ] [ -T content-type ] [ -v verbosity] [ -V ] [ -w ] [ -x <table>-attributes ] [ -X proxy[:port] ] [ -y <tr>-attributes ] [ -z <td>-attributes ] [http://]hostname[:port]/path

     

    -A auth-username:password

    Supply BASIC Authentication credentials to the server. The username and password are separated by a single : and sent on the wire base64 encoded. The string is sent regardless of whether the server needs it (i.e., has sent an 401 authentication needed).

    -c concurrency

    Number of multiple requests to perform. at a time. Default is one request at a time.

    -C cookie-name=value

    Add a Cookie: line to the request. The argument is typically in the form. of a name=value pair. This field is repeatable.

    -d

    Do not display the "percentage served within XX [ms] table". (legacy support).

    -e csv-file

    Write a Comma separated value (CSV) file which contains for each percentage (from 1% to 100%) the time (in milliseconds) it took to serve that percentage of the requests. This is usually more useful than the 'gnuplot' file; as the results are already 'binned'.

    -g gnuplot-file

    Write all measured values out as a 'gnuplot' or TSV (Tab separate values) file. This file can easily be imported into packages like Gnuplot, IDL, Mathematica, Igor or even Excel. The labels are on the first line of the file.

    -h

    Display usage information.

    -H custom-header

    Append extra headers to the request. The argument is typically in the form. of a valid header line, containing a colon-separated field-value pair (i.e., "Accept-Encoding: zip/zop;8bit").

    -i

    Do HEAD requests instead of GET.

    -k

    Enable the HTTP KeepAlive feature, i.e., perform. multiple requests within one HTTP session. Default is no KeepAlive.

    -n requests

    Number of requests to perform. for the benchmarking session. The default is to just perform. a single request which usually leads to non-representative benchmarking results.

    -p POST-file

    File containing data to POST.

    -P proxy-auth-username:password

    Supply BASIC Authentication credentials to a proxy en-route. The username and password are separated by a single : and sent on the wire base64 encoded. The string is sent regardless of whether the proxy needs it (i.e., has sent an 407 proxy authentication needed).

    -q

    When processing more than 150 requests, ab outputs a progress count on stderr every 10% or 100 requests or so. The -q flag will suppress these messages.

    -s

    When compiled in (ab -h will show you) use the SSL protected https rather than the http protocol. This feature is experimental and very rudimentary. You probably do not want to use it.

    -S

    Do not display the median and standard deviation values, nor display the warning/error messages when the average and median are more than one or two times the standard deviation apart. And default to the min/avg/max values. (legacy support).

    -t timelimit

    Maximum number of seconds to spend for benchmarking. This implies a -n 50000 internally. Use this to benchmark the server within a fixed total amount of time. Per default there is no timelimit.

    -T content-type

    Content-type header to use for POST data.

    -v verbosity

    Set verbosity level - 4 and above prints information on headers, 3 and above prints response codes (404, 200, etc.), 2 and above prints warnings and info.

    -V

    Display version number and exit.

    -w

    Print out results in HTML tables. Default table is two columns wide, with a white background.

    -x <table>-attributes

    String to use as attributes for <table>. Attributes are inserted <table here >.

    -X proxy[:port]

    Use a proxy server for the requests.

    -y <tr>-attributes

    String to use as attributes for <tr>.

    -z <td>-attributes

    String to use as attributes for <td>.

     

    相关链接

    ab 是 Apache 的一个安装组件,所以需要下载 Apache 安装后才能使用,可以访问 Apache 的项目主页来下载 http://httpd.apache.org/download.cgi

    ab 的更多信息可以参加 Apache 主页上的描述

    http://httpd.apache.org/docs/2.0/programs/ab.html

     
  • 怎样做一个人见人爱的测试经理

    2011-04-09 01:19:22

    引自每周一问http://bbs.51testing.com/thread-123267-1-1.html

    1.具有较好的人格魅力和亲和力:

    真正来说做到这一点非常难。这不仅要求测试经理有宽广的胸怀,良好的沟通能力和语言表达能力,还要求测试经理具有较强的应对能力。向上能把工作汇报的让领导满意,令领导信任。能把工作任务轻松, 无异意的下发给下属, 并让他们饱含工作热情共同协作去完成测试任务。如果您能够把扭转下属的思想,把“要我测试,变成我要测试”,我想你一定很强了。如果陌生的人一见到你,通过谈话就觉的你很强,都愿意和你交朋友,那你的人格魅力一定不错了,呵呵。

    2.最好具备较强的测试技术水平

    一般来说,作为测试经理,在一个测试技术性的团队里,如果你有很强的技术,并且你的技术是最棒的,下属不能够搞定的问题,你都能够做的很好,即时有时候你凶了点,团队里的成员心底里都还是很敬佩你。如果你有技术,但是技术不高,你组内的技术高手一定是你的亲密战友,这个时候唯一的出路就是凝聚团队的力量,取长补短,也能够取得较高的效率。还有一点值得注意:在分派工作的时候,找一下组内的骨干,看看是否有新的或者好的处理办法,这样一来,避免在开会的时候遇到分工或者技术上的尴尬局面。但有的测试经理具备了很强的技术,整天对团队的成员都板副面孔,那你也很难做到人见人爱。唯有为人处事比较圆滑,待人真诚中肯、随和亲切,整天都是笑脸相迎,那呆在这样的团队里工作,一定很开心。所以要做到人见人爱的测试经理,较强的测试技术水平不能够忽视。

    3.乐意处理下属在项目中碰到的困难:

    在带领一个团队开展测试工作的时候,当你的下属碰到困难的时候,你更多的是给下属鼓励和安慰,帮助下属分析出现问题的原因。比如说一下:“幸苦了”!“干得不错”!“慢慢来,没关系的”!下属听了也很开心的,并且以后干活可能会很卖命,因为他的工作得到了领导的认可。或许该问题你也不一定解决得了,这时候你一定要挺身而出,协调测试团队的资源尽力帮他解决问题,久而久之,你的威信就树立起来了,之后就好办事了。

    4.勇于承担责任,把功劳推给测试团队:

    软件测试经理,作为一个中层经理。管理者一定要想管好下属,必须“身先士卒”、“以身作则”,事事为先、严格要求自己,处处起到表率作用。示范的力量是惊人的,一旦通过表率在团队中树立起在员工中的威望。将会上下同心,大大提高团队的整体战斗力。常言到:“得人心者得天下”,做下属敬佩的领导,将使管理事半功倍。如果下属在测试项目中出现问题,上级领导怪罪下来,自己勇于承担,多检讨自己,少怪罪他人。始终用平和语气与下属沟通,最后一定要找出出现问题的真正原因。让出现问题的下属,自己过意不去,从心底里佩服你,想法补偿你。项目得到喜讯,比如:某个测试项目做的很好,领导表扬的时候,把功劳推给大家,很多时候,容易让人感动,让人佩服得“五体头地”哈哈。

    5.对下属多一些宽容和生活关心:

    特别是对下属不懂,自己懂得很精的地方,下属问的时候,一定要有耐心,给下属详细讲解。切忌:看不起下属。如果真是这样,你这个经理就很失败了。反正对下属,在很多地方,要多一些理解和包容,最好能和下属打成一片,当下属不认为你是领导的时候,你就真是领导了。如果做领导做到别人都当你是朋友,那你真的就成功了。
    还有一点就是要察言观色,随时发现和了解下属的困难,不管是工作方面,还是私人方面,都要关心。比如说:某个下属买了房子,准备装修,那他一定很关心装修方面的东西。如果你懂得很多,那和他交谈时,多一些这方面的话题,他也会很开心,觉的你这个人相当热心,并且也会觉的大家有共同语言,以后当你碰到问题的时候,他一定会鼎立帮助你,因为他认为你是他最信任的知己。也可以多在生活上关心下属。比如有项目要加班什么的,有时候陪陪下属加班呀,吃个午饭宵夜呀,聊点家常呀什么的,自己买单后,公司报销,效果真的不错哟!

    6.力争多给下属争取福利

    在公司条件允许的条件下,多给下属争取福利!但是做这件事的时候,一定要在公司利益和员工利益之前要平衡。若过分的给员工争取福利,会造成公司对你有意见,同样,过分的以公司利益为重,员工对你也会意见大!总之,每种情况都要有度,力所能及的事,一定不能放过。很多时候,为员工申请比较多的福利,即时没有成功或者工资变化不大,但是下属都看在眼里,还是很感激你的,因为他知道你已经尽力了,觉的你很够哥们,为你工作很值。

    7.多给下属锻炼机会,培养下属能力:

    作为测试经理不可能向测试工程师那样什么事情都自己做,并且事事都自己做也不现实。可以在不同的测试项目中,安排测试主管。然后对测试工作进行协调,参与测试中发现重大问题的讨论。这就要求测试经理懂得用人,懂得计划。在制定详细的测试计划的同时,自己把握测试项目中的关键点和时间表,给下属更多的实践机会,让下属做事更具有责任心和成就感。测试主管在做好测试项目的同时,又减少了测试经理的工作量,学到了不少东西,能力变强了,开心了,达到了上下级和谐共处的双丰收。

    8.多给下属精神鼓励,奖惩公私分明:

    很多时候,部门周例会上偶尔的一个口头表扬,更会让下属铭记于心,因为他觉的很有面子,很体面,也许他会再接再厉,给自己创造机会,争取后面再受表扬。下属也乐开了,工作也更加努力、拼命了,效果相当明显。并且奖赏要公私分明,不能有所偏袒,更不能让部门的人觉得你搞私人关系,力争做到一视同仁,对事不对人,也许你就成功了一半。但是,对于工作做的比较差的下属,也要私下单独谈心,帮助找出原因,给他打气,并鼓励他继续努力工作。

    9.知人善用,用人之长,合理分工:

    现在很多公司的测试工程师,都是网上外招的,分别来自不同的行业和不同的工作岗位,他们有着不同的专业知识和行业、业务背景。这就要求测试经理,对每个人的长处非常了解,将合适的人安排到合适的工作岗位上,用人之长,避人之短,合理分工,争取达到双赢。

    10.较强的行业和业务知识背景:

    测试经理作为一个部门的Leader必须对相关的产品和行业的知识背景了如指掌,要不然下属做了什么,怎么做的,正确与否,你都没法判断。一般来说,在某个行业待3年左右,做了几年的测试,那你对这个行业就非常了解。即使你不参加项目的测试,你问很多的问题,下属也不敢乱讲,毕竟你了解很多。再比如说:某些税务的项目,很多的业务知识,你不是很了解,那也没法做,还有一些隐含的行业需求,没有3、5年的行业背景,更是没法发掘出来,到了客户缺陷才被发现,你就太被动了。当然,如果时间允许的话,你也可以介入部分模块的测试,这样虽然你测试不是很多,往往会发现很多问题,检验检验下属测试成果。

    11.多给下属讲解一些职业发展方面的东西:

    从我带过的团队成员来说,一般干了3、4年测试的测试工程师,大部分的测试工程师,对自己的职业生涯都很迷茫,没有完整的规划。由于大部分都是做黑盒测试,技术含量较低,抱怨时常是有的。尤其在这个关键的节骨眼上,对他们的心里辅导和安慰非常必要。多给他们展望一些测试的前景,经常组织测试职业发展的方向类似的讨论会,让大家有一个稳定的心,认真干活,而不是时时刻刻在寻找机会,想立马跳槽。

701/41234>
Open Toolbar