以人为主的测试,到以测试用例为主的测试用例

发布新日志

  • IT人必读:写给浮躁的IT同仁(请不要做浮躁的人) -转

    2007-07-04 18:09:26

     

    1.不要看到别人的回复第一句话就说:给个代码吧!你应该想想为什么。当你自己想出来再参考别人的提示,你就知道自己和别人思路的差异。
     
    2.初学者请不要看太多太多的书那会误人子弟的,先找本系统的学,很多人用了很久都是只对部分功能熟悉而已,不系统还是不够的。
     
    3.看帮助,不要因为很难而自己是初学者所以就不看;帮助永远是最好的参考手册,虽然帮助的文字有时候很难看懂,总觉得不够直观。

    4.不要被对象、属性、方法等词汇所迷惑;最根本的是先了解最基础知识。

    5.不要放过任何一个看上去很简单的小问题--他们往往并不那么简单,或者可以引伸出很多知识点;不会举一反三你就永远学不会。

    6.知道一点东西,并不能说明你会写脚本,脚本是需要经验积累的。

    7.学脚本并不难,JSP、ASP、PHP等等也不过如此--难的是长期坚持实践和不遗余力的博览群书。

    8.看再多的书是学不全脚本的,要多实践。

    9.把时髦的技术挂在嘴边,还不如把过时的技术记在心里。

    10.学习脚本最好的方法之一就是多练习。

    11.在任何时刻都不要认为自己手中的书已经足够了。

    12.看得懂的书,请仔细看;看不懂的书,请硬着头皮看。

    13.别指望看第一遍书就能记住和掌握什么——请看第二遍、第三遍;

    14.请把书上的例子亲手到电脑上实践,即使配套光盘中有源文件;

    15.把在书中看到的有意义的例子扩充;并将其切实的运用到自己的工作中。

    16.不要漏掉书中任何一个练习——请全部做完并记录下思路;

    17.当你用脚本到一半却发现自己用的方法很拙劣时,请不要马上停手;请尽快将余下的部分粗略的完成以保证这个代码的完整性,然后分析自己的错误并重新编写和工作。

    18.别心急,写脚本确实不容易;水平是在不断的实践中完善和发展的;

    19.每学到一个脚本难点的时候,尝试着对别人讲解这个知识点并让他理解----你能讲清楚才说明你真的理解了。

    20.记录下在和别人交流时发现的自己忽视或不理解的知识点。

    21.保存好你做过的所有的源文件----那是你最好的积累之一。

    22.对于网络,还是希望大家能多利用一下,很多问题不是非要到论坛来问的,首先你要学会自己找答案,比如google、百度都是很好的搜索引擎,你只要输入关键字就能找到很多相关资料,别老是等待别人给你希望,看的出你平时一定也很懒!

    23.到一个论坛,你学会去看以前的帖子,不要什么都不看就发帖子问,也许你的问题早就有人问过了,你再问,别人已经不想再重复了,做为初学者,谁也不希望自己的帖子没人回的。

    24,虽然不是打击初学者,但是这句话还是要说:论坛论坛,就是大家讨论的地方,如果你总期望有高手总无偿指点你,除非他是你亲戚!!讨论者,起码是水平相当的才有讨论的说法,如果水平真差距太远了,连基本操作都需要别人给解答,谁还跟你讨论呢。
     
    25、不要因为工作简单就不重视,简单的工作做好了能体现个人的态度,简单的工作做好之后才能够有效管理作简单工作的人。

    26、少发牢骚,多提建设性意见,前者说不定哪天会被领导听见,也影响自己的心情;后者可能会得到领导重视,说不定哪天机会就来了,再说以解决问题的思路来看待问题,不断的思考就会不断进步,也有利于良好心态的形成

    27、做好自己能够掌控的事情,对于自己无法影响的东西,少想、少说

    28、吃亏就是占便宜

    29、不要追求绝对公平,否则是自寻烦恼

    浮躁的人容易问:我到底该学什么;----别问,学就对了;

    浮躁的人容易问:Js有钱途吗;----建议你去抢银行;

    浮躁的人容易说:我要中文版!我英文不行!----不行?学呀!

    浮躁的人经常说:啊呀,今天放松一下,从明天开始我一定认真学!

    浮躁的人分两种:只观望而不学的人;只学而不坚持的人;

    浮躁的人永远不是一个高手。

  • 软件测试员的发展路线-老徐

    2007-07-04 17:46:49

     

                                                                  
     
    :老徐 新闻来源:STTE  更新时间:2007-4-3 18:30:22
  • 学习C++的50条忠告

    2007-07-03 21:18:50

    1.把C++当成一门新的语言学习(和C没啥关系!真的)

    2.看 Thinking In C++ ,不要看 C++变成死相 ;

    3.看 The C++ Programming Language 和 Inside The C++ Object Model,
      不要因为他们很难而我们自己是初学者所以就不看;

    4.不要被VC,BCB,BC,MC,TC等词汇所迷惑—-他们都是集成开发环境,而我们要学的是
     一门语言.

    5.不要放过任何一个看上去很简单的小编程问题——他们往往并不那么简单,或者可
      以引伸出很多知识点.

    6.会用Visual C++,并不说明你会C++.

    7.学class并不难,template,STL,generic programming也不过如此——难的是长期
      坚持实践和不遗余力的博览群书.

    8.如果不是天才的话,想学编程就不要想玩游戏——你以为你做到了,其实你的C++水
      平并没有和你通关的能力一起变高——其实可以时刻记住:学C++是为了编游戏的.

    9.看Visual C++的书,是学不了C++语言的.

    10.浮躁的人容易说:XX语言不行了,应该学YY.——是你自己不行了吧!

    11.浮躁的人容易问:我到底该学什么.——别问,学就对了.

    12.浮躁的人容易问:XX有钱途吗.——建议你去抢银行.

    13.浮躁的人容易说:我要中文版!我英文不行!——不行?学呀!

    14.浮躁的人容易问:XX和YY哪个好.——告诉你吧,都好——只要你学就行.

    15.浮躁的人分两种:a)只观望而不学的人;b)只学而不坚持的人;

    16.把时髦的技术挂在嘴边,还不如把过时的技术记在心里.

    17.C++不仅仅是支持面向对象的程序设计语言.

    18.学习编程最好的方法之一就是阅读源代码.

    19.在任何时刻都不要认为自己手中的书已经足够了.

    20.请阅读 The Standard C++ Bible (中文版:标准C++宝典),掌握C++标准.

    21.看得懂的书,请仔细看.看不懂的书,请硬着头皮看.

    22.别指望看第一遍书就能记住和掌握什么——请看第二遍,第三遍.

    23.请看 Effective C++ 和 More Effective C++ 以及Exceptional C++;

    24.不要停留在集成开发环境的摇篮上,要学会控制集成开发环境 还要学会用命令
      行方式处理程序.

    25.和别人一起讨论有意义的C++知识点,而不是争吵XX行不行或者YY与ZZ哪个好.

    26.请看 程序设计实践 ,并严格的按照其要求去做.

    27.不要因为C和C++中有一些语法和关键字看上去相同,就认为它们的意义和作用完
      全一样.

    28.C++绝不是所谓的C的"扩充"——如果C++一开始就起名叫Z语言,你一定不会把C
      和Z语言联系得那么紧密.

    29.请不要认为学过XX语言再改学C++会有什么问题——你只不过又在学一门全新的
      语言而已.

    30.读完了 Inside The C++ Object Model 后再来认定自己是不是已经学会了C++.

    31.学习编程的秘诀是:编程,编程,再编程.

    32.请留意下列书籍:
      C++面向对象高效编程(C++ Effective Object-Oriented Software Construction)
      面向对象软件构造(Object-Oriented Software Construction) 
      设计模式(Design Patterns)
      The Art of Computer Programming 

    33.记住:面向对象技术不只是C++专有的.

    34.请把书上的程序例子亲手输入到电脑上实践,即使配套光盘中有源代码.

    35.把在书中看到的有意义的例子扩充.

    36.请重视C++中的异常处理技术,并将其切实的运用到自己的程序中.

    37.经常回顾自己以前写过的程序,并尝试重写,把自己学到的新知识运用进去.

    38.不要漏掉书中任何一个练习题——请全部做完并记录下解题思路.

    39.C++语言和C++的集成开发环境要同时学习和掌握.

    40.既然决定了学C++,就请坚持学下去,因为学习程序设计语言的目的是掌握程序设
      计技术,而程序设计技术是跨语言的.

    41.就让C++语言的各种平台和开发环境去激烈的竞争吧,我们要以学习C++语言本身
      为主.

    42.当你写C++程序写到一半却发现自己用的方法很拙劣时,请不要马上停手.请尽快
      将余下的部分粗略的完成以保证这个设计的完整性,然后分析自己的错误并重新设
      计和编写(参见43).

    43.别心急,设计C++的class确实不容易.自己程序中的class和自己的class设计水平
      是在不断的编程实践中完善和发展的.

    44.决不要因为程序"很小"就不遵循某些你不熟练的规则——好习惯是培养出来的,
      而不是一次记住的.

    45.每学到一个C++难点的时候,尝试着对别人讲解这个知识点并让他理解——你能
      讲清楚才说明你真的理解了.

    46.记录下在和别人交流时发现的自己忽视或不理解的知识点.

    47.请不断的对自己写的程序提出更高的要求,哪怕你的程序版本号会变成
       Version 100.XX.

    48.保存好你写过的所有的程序——那是你最好的积累之一.

    49.请不要做浮躁的人.

    50.请热爱C++!

  • Rational ClearQuest 使用手册

    2007-07-03 09:03:28

    Rational ClearQuest 使用手册
  • “快乐男声”

    2007-06-30 09:10:15

    “快乐男声”全国总决赛5进4比赛结束,魏晨、苏醒、陈楚生、 成功晋级成为全国4强。
  • 五个故事

    2007-06-27 21:20:54

    1、 情况不同 
    一只小猪、一只绵羊和一头乳牛,被关在同一个畜栏里。有一次,牧人捉住小猪,牠大声号叫,猛烈地抗拒。绵羊和乳牛讨厌牠的号叫,便说:「他常常捉我们,我们并不大呼小叫。小猪听了回答道:「捉你们和捉我完全是两回事,他捉你们,只是要你们的毛和乳汁,但是捉住我,却是要我的命呢! 
    立场不同、所处环境不同的人,很难了解对方的感受;因此对别人的失意、挫折、伤痛,不宜幸灾乐祸,而应要有关怀、了解的心情。要有宽容的心! 

    2、 靠自己 
    小蜗牛问妈妈:为什么我们从生下来,就要背负这个又硬又重的壳呢? 
      妈妈:因为我们的身体没有骨骼的支撑,只能爬,又爬不快。所以要这个壳的保护! 
      小蜗牛:毛虫姊姊没有骨头,也爬不快,为什么她却不用背这个又硬又重的壳呢? 
      妈妈:因为毛虫姊姊能变成蝴蝶,天空会保护她啊。 
      小蜗牛:可是蚯蚓弟弟也没骨头爬不快,也不会变成蝴蝶他什么不背这个又硬又重的壳呢? 
      妈妈:因为蚯蚓弟弟会钻土, 大地会保护他啊。 
      小蜗牛哭了起来:我们好可怜,天空不保护,大地也不保护。 
      蜗牛妈妈安慰他:「所以我们有壳啊!」我们不靠天,也不靠地,我们靠自己。 

    3、 鲨鱼与鱼 
       曾有人做过实验,将一只最凶猛的鲨鱼和一群热带鱼放在同一个池子,然后用强化玻璃隔开,最初,鲨鱼每天不断冲撞那块看不到的玻璃,耐何这只是徒劳,它始终不能过到对面去,而实验人员每天都有放一些鲫鱼在池子里,所以鲨鱼也没缺少猎物,只是它仍想到对面去,想尝试那美丽的滋味,每天仍是不断的冲撞那块玻璃,它试了每个角落,每次都是用尽全力,但每次也总是弄的伤痕累累,有好几次都浑身破裂出血,持续了好一些日子,每当玻璃一出现裂痕,实验人员马上加上一块更厚的玻璃。后来,鲨鱼不再冲撞那块玻璃了,对那些斑斓的热带鱼也不再在意,好像他们只是墙上会动的壁画,它开始等着每天固定会出现的鲫鱼,然后用他敏捷的本能进行狩猎,好像回到海中不可一世的凶狠霸气,但这一切只不过是假像罢了,实验到了最后的阶段,实验人员将玻璃取走,但鲨鱼却没有反应,每天仍是在固定的区域游着它不但对那些热带鱼视若无睹,甚至于当那些鲫鱼逃到那边去,他就立刻放弃追逐,说什么也不愿再过去,实验结束了,实 验人员讥笑它是海里最懦弱的鱼。 

    4、 神迹 
    法国一个偏僻的小镇,据传有一个特别灵验的水泉,常会出现神迹,可以医治各种疾病。有一天,一个拄着拐杖,少了一条腿的退伍军人,一跛一跛的走过镇上的马路,旁边的镇民带着同情的回吻说:「可怜的家伙,难道他要向上帝祈求再有一条腿吗??」这一句话被退伍的军人听到了,他转过身对他们说:「我不是要向上帝祈求有一条新的腿,而是要祈求祂帮助我,叫我没有一条腿后,也知道如何过日子。」 
    试想:学习为所失去的感恩,也接纳失去的事实,不管人生的得与失,总是要让自已的生命充满了亮丽与光彩,不再为过去掉泪,努力的活出自己的生命。 

    5、 钓竿 
    有个老人在河边钓鱼,一个小孩走过去看他钓鱼,老人技巧纯熟,所以没多久就钓上了满篓的鱼,老人见小孩很可爱,要把整篓的鱼送给他,小孩摇摇头,老人惊异的问道:「你为何不要?」小孩回答:「我想要你手中的钓竿。」老人问:「你要钓竿做什么?」小孩说:「这篓鱼没多久就吃完了,要是我有钓竿,我就可以自己钓,一辈子也吃不完。」我想你一定会说:好聪明的小孩。错了,他如果只要钓竿,那他一条鱼也吃不到。因为,他不懂钓鱼的技巧,光有鱼竿是没用的,因为钓鱼重要的不在<钓竿>,而在<钓技>有太多人认为自己拥有了人生道上的钓竿,再也无惧于路上的风雨,如此,难免会跌倒于泥泞地上。就如小孩看老人,以为只要有钓竿就有吃不完的鱼,像职员看老板,以为只要坐在办公室,就有滚进的财源。
  • 人生哲理

    2007-06-27 21:16:27

    我们是为了什么而工作
      英国某小镇。这儿,有一个青年人,整日以沿街为小镇的人说唱为生;这儿,有一个华人妇女,远离家人,在这儿打工。
      他们总是在同一个小餐馆用餐,于是他们屡屡相遇。
      时间长了,彼此已十分的熟悉。有一日,我们的女同胞,关切地对那个小伙子说:“不要沿街卖唱了,去做一个正当的职业吧。我介绍你到中国去教书,在那儿,你完全可以拿到比你现在高得多的薪水。”
      小伙子听后,先是一愣,然后反问道:“难道我现在从事的不是正当的职业吗?我喜欢这个职业,它给我,也给其他人带来欢乐。有什么不好?我何必要远渡重洋,抛弃亲人,抛弃家园,去做我并不喜欢的工作?”
      邻桌的英国人,无论老人孩子,也都为之愕然。他们不明白,仅仅为了多挣几张钞票,抛弃家人,远离幸福,有什么可以值得羡慕的。在他们的眼中,家人团聚,平平安安,才是最大的幸福。它与财富的多少,地位的贵贱无关。
      于是,小镇上的人,开始可怜我们的女同胞了。
    --------------------------------------------------------------------------------------------------
      中国山东,有这样一对夫妇。
      刚刚结婚时,妻子在济宁,丈夫在枣庄;过了若干年,妻子调到了枣庄,丈夫却一纸调令到了菏泽。若干年后,妻子又费尽周折,调到了菏泽,但不久,丈夫又被提拔到了省城济南。妻子又托关系找熟人,好不容易调到了济南。可是不到一年,丈夫又被国家电业总公司调到重庆。于是,她所有的朋友,就给她开玩笑——你们俩呀,天生就是牛郎织女的命。要我们说呀,你也别追了,干脆辞职,跟着你们家老张算了。
      但是,她以及公婆、父母,都一致反对。“干了这么多年,马上就退休了,再说,你的单位效益这么好,辞职多可惜。要丢掉多少钱呀!再干几年吧,也给孩子多挣一些。”
      其实,他们家的经济条件已经非常优越。早已是中层阶级,但是他们仍然惦念着那一点退休金。
      于是,夫妻两个至今依然是牛郎织女。
    --------------------------------------------------------------------------------------------------
      我们,是一个尚义轻利的民族。中国人一直是为了某种自己未必真正明白的主义而活着。
      于是,中国人,不能在没有目标的生活中活着。而这个目标,可以是工作,可以是理想,可以是金钱,可以是孩子,可以是老人……但是,唯一不可能是的,就是自己。
      中国人,可以很委屈的活着。可以是工作上的极不顺心,可以是婚姻上的勉强维持,可以是人际关系上的强作笑颜,可以是所有欲望的极端压制,可以是为了一个所谓的户口……哪怕牺牲自己一生的幸福,也在所不惜。
      中国人,可以过异常艰难的日子,但并不能安贫乐道,他所遭受的一切不幸,必定有一个近乎玩笑的借口;中国人,可以把高官厚禄当作成功,中国人可以把身家百万当作理想,中国人可以抛却天伦之乐四海飘荡,但是,中国人唯一不认可的成功——就是家庭的和睦,人生的平淡。
      于是,一个有着五千年文明历史的国度,把爱国、崇高、献身、成功、立业的情结推向了极致——他们要么在大公无私,其实是舍本逐末的漩涡里苦苦挣扎,要么在肩负重任,其实是徒有其名的怪圈里受尽折磨……唯一遗漏的就是自由和自我。
      于是,在外国,妇孺皆知的道理;在中国,没人能整治明白。
    --------------------------------------------------------------------------------------------------
      人的一生,到底在追求甚么?
      有一个美国商人坐在墨西哥海边一个小渔村的码头上, 看着一个墨西哥渔夫划着一艘小船靠岸。小船上有好几尾大黄鳍鲔鱼,这个美国商人对墨西哥渔夫能抓这么高档的鱼恭维了一番,还问要多少时间才能抓这么多?墨西哥渔夫说,才一会儿功夫就抓到了。美国人再问,你为甚么不待久一点,好多抓一些鱼?墨西哥渔夫觉得不以为然: 这些鱼已经足够我一家人生活所需啦!美国人又问:那么你一天剩下那么多时间都在干甚么?墨西哥渔夫解释:我呀?我每天睡到自然醒,出海抓几条鱼,回来后跟孩子们玩一玩,再跟老婆睡个午觉,黄昏时晃到村子里喝点小酒,跟哥儿们玩玩吉他,我的日子可过得充满又忙碌呢!美国人不以为然,帮他出主意,他说:我是美国哈佛大学企管硕士,我倒是可以帮你忙!你应该每天多花一些时间去抓鱼,到时候你就有钱去买条大一点的船。自然你就可以抓更多鱼,在买更多渔船。然后你就可以拥有一个渔船队。到时候你就不必把鱼卖给鱼贩子,而是直接卖给加工厂。然后你可以自己开一家罐头工厂。如此你就可以控制整个生产、加工处理和行销。然后你可以离开这个小渔村,搬到墨西哥城,再搬到洛杉矶,最后到纽约。在那经营你不断扩充的企业。墨西哥渔夫问:这又花多少时间呢?美国人回答:十五到二十年。墨西哥渔夫问:然后呢?美国人大笑着说:然后你就可以在家当皇帝啦!时机一到,你就可以宣布股票上市,把你的公司股份卖给投资大众。到时候你就发啦!你可以几亿几亿地赚!然后呢?美国人说:到那个时候你就可以退休啦!你可以搬到海边的小渔村去住。每天睡到自然醒,出海随便抓几条鱼,跟孩子们玩一玩,再跟老婆睡个午觉,黄昏时,晃到村子里喝点小酒,跟哥儿们玩玩吉他?!墨西哥渔夫疑惑的说:我现在不就是这样了吗?人的一生,到底在追求甚么?
  • 感悟人生

    2007-06-27 20:35:44

     

    这不是为了向您讲述一个神话故事,而是为了使您领悟一个道理

      从前,有一座圆音寺,每天都有许多人上香拜佛,香火很旺。在圆音寺庙前的横梁上有个蜘蛛结了张网,由于每天都受到香火和虔诚的祭拜的熏托,蛛蛛便有了佛性。经过了一千多年的修炼,蛛蛛佛性增加了不少。

      忽然有一天,佛主光临了圆音寺,看见这里香火甚旺,十分高兴。离开寺庙的时候,不经意间抬头看见了横梁上的蛛蛛。佛主停下来,问这只蜘蛛:“你我相见总算是有缘,我来问你个问题,看你修炼了这一千多年来,有什么真知 灼见。怎么样?”蜘蛛遇见佛主很是高兴,连忙答应了。佛主问到:“世间什么才是最珍贵的?”蜘蛛想了想,回答到:“世间最珍贵的是‘得不到’和‘已失去’。”佛主点了点头,离开了。

      就这样又过了一千年的光景,蜘蛛依旧在圆音寺的横梁上修炼,它的佛性大增。一日,佛主又来到寺前,对蜘蛛说道:“你可还好,一千年前的那个问题,你可有什么更深的认识吗?”蜘蛛说:“我觉得世间最珍贵的是‘得不到’和‘已失去’。”佛主说:“你再好好想想,我会再来找你的。”

      又过了一千年,有一天,刮起了大风,风将一滴甘露吹到了蜘蛛网上。蜘蛛望着甘露,见它晶莹透亮,很漂亮,顿生喜爱之意。蜘蛛每天看着甘露很开心,它觉得这是三千年来最开心的几天。突然,又刮起了一阵大风,将甘露吹走了。蜘蛛一下子觉得失去了什么,感到很寂寞和难过。这时佛主又来了,问蜘蛛:“蜘蛛这一千年,你可好好想过这个问题:世间什么才是最珍贵的?”蜘蛛想到了甘露,对佛主说:“世间最珍贵的是‘得不到’和‘已失去’。”佛主说:“好,既然你有这样的认识,我让你到人间走一 遭吧。”

      就这样,蜘蛛投胎到了一个官宦家庭,成了一个富家小姐,父母为她取了个名字叫蛛儿。一晃,蛛儿到了十六岁了,已经成了个婀娜多姿的少女,长的十分漂亮,楚楚动人。

      这一日,皇帝决定在后花园为新科状元郎甘鹿举行庆功宴席。来了许多妙龄少女,包括蛛儿,还有皇帝的小公主长风公主。状元郎在席间表演诗词歌赋,大献才艺,在场的少女无一不被他折 服。但蛛儿一点也不紧张和吃醋,因为她知道,这是佛主赐予她的姻缘。

      过了些日子,说来很巧,蛛儿陪同母亲上香拜佛的时候,正好甘鹿也陪同母亲而来。上完香拜过佛,二位长者在一边说上了话。蛛儿和甘鹿便来到走廊上聊天,蛛儿很开心,终于可以和喜欢的人在一起了,但是甘鹿并没有表现出对她的喜爱。蛛儿对甘鹿说:“你难道不曾记得十六年前,圆音寺的蜘蛛网上的事情了吗?”甘鹿很诧异,说:“蛛儿姑娘,你漂亮,也很讨人喜欢,但你想象力未免 太丰富了一点吧。”说罢,和母亲离开了。

      蛛儿回到家,心想,佛主既然安排了这场姻缘,为何不让他记得那件事,甘鹿为何对我没有一点的感觉?

      几天后,皇帝下召,命新科状元甘鹿和长风公主完婚;蛛儿和太子芝草完婚。这一消息对蛛儿如同晴空霹雳,她怎么也想不通,佛主竟然这样对她。几日来,她不吃不喝,穷究急思,灵魂就将出壳,生命危在旦夕。太子芝草知道了,急忙赶来,扑倒在床边,对奄奄一息的蛛儿说道:“那日,在后花园众姑娘中,我对你一见钟情,我苦求父皇,他才答应。如果你死了,那么我也就不活了。”说着就拿起了宝剑准备自刎。

      就在这时,佛主来了,他对快要出壳的蛛儿灵魂说:“蜘蛛,你可曾想过,甘露(甘鹿)是由谁带到你这里来的呢?是风(长风公主)带来的,最后也是风将它带走的。甘鹿是属于长风公主的,他对你不过是生命中的一段插曲。而太子芝草是当年圆音寺门前的一棵小草,他看了你三千年,爱慕了你三千年,但你却从没有低下头看过它。蜘蛛,我再来问你,世间什么才是最珍贵的?”蜘蛛听了这些真相之后,好象一下子大彻大悟了,她对佛主说:“世间最珍贵的不是‘得不到’和‘已失去’,而是现在能把握的幸福。”刚说完,佛主就离开了,蛛儿的灵魂也回位了,睁开眼睛,看到正要自刎的太子芝草,她马上打落宝剑,和太子深深的抱着……

      故事结束了,你能领会蛛儿最后一刻的所说的话吗?“世间最珍贵的不是‘得不到’和‘已失去’,而是现在能把握的幸福。”

  • Linux基本操作命令

    2007-06-26 19:37:26

    Linux基本操作命令

    首先介绍一个名词控制台(console,它就是我们通常见到的使用字符操作界面的人机接口,例如dos。我们说控制台命令,就是指通过字符界面输入的可以操作系统的命令,例如dos命令就是控制台命令。我们现在要了解的是基于Linux操作系统的基本控制台命令。有一点一定要注意,和dos命令不同的是,Linux的命令(也包括文件名等等)对大小写是敏感的,也就是说,如果你输入的命令大小写不对的话,系统是不会做出你期望的响应的。

    ls
    这个命令就相当于dos下的dir命令一样,肯定是我第一个就要介绍的,这也是Linux控制台命令中最为重要几个命令之一。ls最常用的参数有三个: -a -l -F

    ls -a

    Linux
    上的文件以.开头的文件被系统视为隐藏文件,仅用ls命令是看不到他们的,而用ls -a除了显示 一般文件名外,连隐藏文件也会显示出来。

    ls -l
    (这个参数是字母L的小写,不是数字1

    这个命令可以使用长格式显示文件内容,如果需要察看更详细的文件资料,就要用到ls -l这个指令。例如我在某个目录下键入ls -l可能会显示如下信息(最上面两行是我自己加的):
    位置1 2 3 4 5 6 7
    文件属性 文件数 拥有者 所属的group 文件大小 建档日期 文件名
    drwx------ 2 Guest users 1024 Nov 21 21:05 Mail
    -rwx--x--x 1 root root 89080 Nov 7 22:41 tar*
    -rwxr-xr-x 1 root bin 5013 Aug 15 9:32 uname*
    lrwxrwxrwx 1 root root 4 Nov 24 19:30 zcat->gzip
    -rwxr-xr-x 1 root bin 308364 Nov 29 7:43 zsh*
    -rwsr-x--- 1 root bin 9853 Aug 15 5:46 su*
    下面,我为大家解释一下这些显示内容的意义。
    第一个栏位,表示文件的属性。Linux的文件基本上分为三个属性:可读(r),可写(w),可执行(x)。但是这里有十个格子可以添(具体程序实现时,实际上是十个bit位)。第一个小格是特殊表示格,表示目录或连结文件等等,d表示目录,例如drwx------;l表示连结文件,如lrwxrwxrwx;如果是以一横“-”表示,则表示这是文件。其余剩下的格子就以每3格为一个单位。因为Linux是多用户多任务系统,所以一个文件可能同时被许多人使用,所以我们一定要设好每个文件的权限,其文件的权限位置排列顺序是(以-rwxr-xr-x为例):
    rwx(Owner)r-x(Group)r-x(Other)
    这个例子表示的权限是:使用者自己可读,可写,可执行;同一组的用户可读,不可写,可执行;其它用户可读,不可写,可执行。另外,有一些程序属性的执行部分不是X,而是S,这表示执行这个程序的使用者,临时可以有和拥有者一样权力的身份来执行该程序。一般出现在系统管理之类的指令或程序,让使用者执行时,拥有root身份。
    第二个栏位,表示文件个数。如果是文件的话,那这个数目自然是1了,如果是目录的话,那它的数目就是该目录中的文件个数了。
    第三个栏位,表示该文件或目录的拥有者。若使用者目前处于自己的Home,那这一栏大概都是它的账号名称。
    第四个栏位,表示所属的组(group)。每一个使用者都可以拥有一个以上的组,不过大部分的使用者应该都只属于一个组,只有当系统管理员希望给予某使用者特殊权限时,才可能会给他另一个组。
    第五栏位,表示文件大小。文件大小用byte来表示,而空目录一般都是1024byte,你当然可以用其它参数使文件显示的单位不同,如使用ls –k就是用kb莱显示一个文件的大小单位,不过一般我们还是以byte为主。
    第六个栏位,表示创建日期。以月,日,时间的格式表示,如Aug 15 5:46表示815早上5:46分。
    第七个栏位,表示文件名。我们可以用ls –a显示隐藏的文件名。

    ls –F
    (注意,是大写的F

    使用这个参数表示在文件的后面多添加表示文件类型的符号,例如*表示可执行,/表示目录,@表示连结文件,这都是因为使用了-F这个参数。但是现在基本上所有的Linux发行版本的ls都已经内建了-F参数,也就是说,不用输入这个参数,我们也能看到各种分辨符号。

    cd
    这个命令是用来进出目录的,它的使用方法和在dos下没什么两样,所以我觉得没什么可说的,但有两点我补充一下。首先,和dos不同的是Linux的目录对大小写是敏感的,如果大小写没拼对,你的cd操作是成功不了的。其次,cd如果直接输入,cd后面不加任何东西,会回到使用者自己的Home Directory。假设如果是root,那就是回到/root.这个功能同cd ~是一样的。

    mkdir
    rmdir
    mkdir
    命令用来建立新的目录,rmdir用来删除以建立的目录,这两个指令的功能不再多加介绍,他们同dos下的md,rd功能和用法都是基本一样的。

    cp
    这个命令相当于dos下面的copy命令,具体用法是:cp –r 源文件(source) 目的文件(target)
    参数r是指连同元文件中的子目录一同拷贝。熟悉dos的读者用起这个命令来会觉得更方便,毕竟比在dos下面要少敲两下键盘。

    rm
    这个命令是用来删除文件的,和dos下面的rm(删除一个空目录)是有区别的,大家千万要注意。Rm命令常用的参数有三个: -i,-r,-f
    比如我现在要删除一个名字为text的一个文件:rm –i test
    系统会询问我们:“rm:remove ‘test’?y”,敲了回车以后,这个文件才会真的被删除。之所以要这样做,是因为linux不象dos那样有undelete的命令,或者是可以用pctool等工具将删除过的文件救回来,linux中删除过的文件是救不回来的,所以使用这个参数在删除前让你再确定一遍,是很有必要的。
    rm –r
    目录名:这个操作可以连同这个目录下面的子目录都删除,功能上和rmdir相似。
    rm –f
    文件名(目录名):这个操作可以进行强制删除。

    mv
    这个命令的功能是移动目录或文件,引申的功能是给目录或文件重命名。它的用法同dos下面的move基本相同,这里不再多讲。当使用该命令来移动目录时,他会连同该目录下面的子目录也一同移走。另外因为linux下面没有rename的命令,所以如果你想给一个文件或目录重命名时可以用以下方法:mv 原文件(目录)名 新的文件(目录)名。

    du
    df
    du
    命令可以显示目前的目录所占的磁盘空间,df命令可以显示目前磁盘剩余的磁盘空间。如果du命令不加任何参数,那么返回的是整个磁盘的使用情况,如果后面加了目录的话,就是这个目录在磁盘上的使用情况(这个功能可是dos没有的呦)。不过我一般不喜欢用du,因为它给出的信息是在是太多了,我看不过来,而df这个命令我是最常用的,因为磁盘上还剩多少空间对我来说是很重要的。

    cat
    这个命令是linux中非常重要的一个命令,它的功能是显示或连结一般的ascii文本文件。catconcatenate的简写,类似于dos下面的type命令。它的用法如下:
    cat text
    显示text这个文件;
    cat file1 file2
    依顺序显示file1,file2的内容;
    cat file1 file2>file3
    file1,file2的内容结合起来,再重定向(>file3文件中。
    是一个非常有趣的符号,是往右重定向的意思,就是把左边的结果当成是输入,然后输入到file3这个文件中。这里要注意一点是file3是在重定向以前还未存在的文件,如果file3是已经存在的文件,那么它本身的内容被覆盖,而变成file1+file2的内容。如果〉左边没有文件的名称,而右边有文件名,例如:
    cat >file1
    :结果是会空出一行空白行,等待你输入文字,输入完毕后再按[Ctrl]+[c][Ctrl]+[d],就会结束编辑,并产生file1这个文件,而file1的内容就是你刚刚输入的内容。这个过程和dos里面的copy con file1的结果是一样的。
    另外,如果你使用如下的指令:
    cat file1>>file2
    :这将变成将file1的文件内容附加file2的文件后面,而file2的内容依然存在,这种重定向符〉〉比〉常用,可以多多利用。

    more,less
    这是两个显示一般文本文件的指令。如果一个文本文件太长了超过一个屏幕的画面,用cat来看实在是不理想,就可以试试moreless两个指令。More指令可以使超过一页的文件临时停留在屏幕,等你按任何的一个键以后,才继续显示。而less除了有more的功能以外,还可以用方向键往上或网下的滚动文件,所以你随意浏览,阅读文章时,less是个非常好的选择。

    clear
    这个命令是用来清除屏幕的,它不需要任何参数,和dos下面的clr具有相同的功能,如果你觉得屏幕太紊乱,就可以使用它清除屏幕上的信息。

    pwd
    这个命令的作用是显示用户当前的工作路径,这个命令不用多说,大家一试即知。

    ln
    这是linux中又一个非常重要命令,请大家一定要熟悉。它的功能是为某一个文件在另外一个位置建立一个同不的链接,这个命令最常用的参数是-s,具体用法是:ln –s 源文件 目标文件。
    当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在其它的目录下用ln命令链接(link)它就可以,不必重复的占用磁盘空间。例如:ln –s /bin/less /usr/local/bin/less
  • 《Rational Purify中文使用手册》

    2007-06-22 14:52:52

  • Purify检测的代码错误类型

    2007-06-22 14:31:42

     

    一、红色叹号提示

    1、  ABR: Array Bounds Read

    数组越界读(只检测动态内存分配的数组,对Global、Local、Static的数组无法检测)。

    2、  ABW: Array Bounds Write

    数组越界写(只检测动态内存分配的数组,对Global、Local、Static的数组无法检

    3、  ABWL: Late Detect Array Bounds Write (An ABWL message indicates that the program wrote a value before the beginning or after the end of an allocated block of memory)
    4、  BSR: Beyond Stack Read

    函数可能读了一个当前堆栈之外的指针。例如在写变量值的时候程序出现了异常,那么读此变量时,就会发生BSR错误。(不适用于堆栈内的本地数组)

    5、  BSW: Beyond Stack Write

    函数可能写了一个当前堆栈之外的指针。(不适用于堆栈内的本地数组)

    6、  EXU: Unhandled Exception

    未经处理的异常

    7、  FFM: Freeing Freed Memory

    正在释放已经释放过的内存。
    8、  FIM: Freeing Invalid Memory

    试图释放未分配的、无效的内存。

    9、  FMM: Freeing Mismatched Memory

    释放不匹配的内存,用不正确的API函数释放某类内存。

    10、FMR: Free Memory Read

    读取已经释放或者未经分配的内存内容。

    11、 FMW: Free Memory Write

    对已经释放或者未经分配的内存做写入操作。

    12、 FMWL: Late Detect Free Memory Write

    13、IPR: Invalid Pointer Read

    程序正在读取一个无效的,不可以设定地址的内存区域。

    14、IPW: Invalid Pointer Write

    程序正在对一个无效的,不可以设定地址的内存区域进行写操作。

    red zone

    For error detection runs, the bytes that are placed at the beginning and end of each allocated block of memory in a program at run time. The red zone is used to detect Array Bounds Read (ABR), Array Bounds Write (ABW), and Late Detect Array Bounds Write (ABWL) errors.

    15、NPR: Null Pointer Read

    空指针读。

    16、NPW: Null Pointer Write

    空指针写。

    二、黄色警告信息

    1、COM: COM API/Interface Failure

    COM操作失败。在每一个COM API或COM接口调用后,Purify都会检查HRESULT,如果它的值不是标明操作成功的S_OK,就会显示此错误。

    2、HAN: Invalid Handle

    无效句柄。在期望出现句柄的地方出现了一个非句柄的值或者是一个错误类型的句柄。

    3、ILK: COM Interface Leak

    COM接口漏洞。当一个COM接口的引用总数大于1时,会出现此提示。

    4、MLK: Memory Leak

    堆内存泄露。指内存块中没有任何内容或者内存块没有被任何指针引用。以下两种情况都会出现此错误提示。

    A、在函数中分配了本地内存,但在退出函数的时候没有Free。

    B、内存块的指针被清除或改变或不在其作用域内。

    If the section of the program where the memory is allocated and leaked is executed repeatedly, you might eventually run out of swap space, causing slow downs and crashes. This is a serious problem for long-running, interactive programs.

    5、PAR: Bad Parameter

    程序在调用Win32API或者C运行时常规函数时传递了一个错误的参数。

    6、UMC: Uninitialized Memory Copy

    将一个未初始化的值从一个内存区拷贝到另外一个。

    7、UMR: Uninitialized Memory Read

    读取未初始化的内存块的值。

    三、兰色提示信息

    1、BOX: MessageBox

    如果程序中用到了MessageBox()或者MessageBoxEx()两个函数,Purify运行结束后就会出现此项提示信息。

    2、EXC: Continued Exception

    3、EXH: Handled Exception

    4、EXI: Ignored Exception

    5、HIU: Handle In Use

    句柄被分配后,没有释放。

    6、MAF: Memory Allocation Failure

    内存分配失败。

    7、MIU: Memory In Use

    正要分配的堆内存上已经有指针了。

    8、MPK: Potential Memory Leak

    堆内存可能泄露。在内存块的开始没有指针,但在块的内部看起来有指针指向。

    9、ODS: OutputDebugString

    程序中调用了OutputDebugString函数。

  • 检测并排除内存泄漏

    2007-06-21 21:33:45

     

     摘要:
     本文描述了如何使用VC++和CRT库提供的工具定位和排除内存泄漏,检测的难度使得使用C/C++编程语言的应用开发产生问题。
     介绍:
     动态分配、回收内存是C/C++编程语言一个最强的特点,但是中国哲学家孙(Sun Tzu,我不知道是谁?那位知道?) 指出,最强的同时也是最弱的。这句话对C/C++应用来说非常正确,在内存处理出错的地方通常就是BUGS产生的地方。一个最敏感和难检测的BUG就是内存泄漏-没有把前边分配的内存成功释放,一个小的内存泄漏可能不需要太注意,但是程序泄漏大块内存,或者渐增式的泄漏内存可能引起的现象是:先是性能低下,再就是引起复杂的内存耗尽错误。最坏的是,一个内存泄漏程序可能用完了如此多的内存以至于引起其他的程序出错,留给用户的是不能知道错误到底来自哪里。另外,一个看上去无害的内存泄漏可能是另一个问题的先兆。幸运的是VC++DEBUGER和CRT库提供了一组有效的检测和定位内存泄漏的工具。本文描述如何使用这些工具有效和系统的排除内存泄漏。

     启动内存泄漏检测:
     主要的检测工具是DEBUGER和CRT堆除错函数。要使除错函数生效,必须要在你的程序中包含以下几个语句:
    #define _CRTDBG_MAP_ALLOC
    #include <stdlib.h>
    #include <crtdbg.h>
     并且这些#include 语句必须按上边给出的顺序使用。如果你改变了顺序,可能导致使用的函数工作不正常。包含crtdbg.h的作用是用malloc和free函数的debug版本(_malloc_dbg 和 _free_dbg)来替换他们,他们能跟踪内存分配和回收。这个替换仅仅是在debug状态下生效,Relese版本中还是使用普通的malloc和free函数。
     上面的#define语句使用crt堆函数相应的debug版本来替换正常的堆函数。这个语句不是必需的,但是没有他,你可能会失去一些有用的内存泄漏信息。
     你一旦在你的程序中增加了以上的语句,你可以通过在程序中增加_CrtDumpMemoryLeaks();函数来输出内存泄漏信息。
     当你在debuger下运行你的程序时,_CrtDumpMemoryLeaks 显示内存泄漏信息在OutPut窗口的Debug标签项里。内存泄漏信息举例如下:

    Detected memory leaks!
    Dumping objects ->
    C:PROGRAM FILESVISUAL STUDIOMyProjectsleaktestleaktest.cpp(20) : {18}
       normal block at 0x00780E80, 64 bytes long.
     Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
    Object dump complete.
    如果你没有使用 #define _CRTDBG_MAP_ALLOC语句的话,输出信息将如下:

    Detected memory leaks!
    Dumping objects ->
    {18} normal block at 0x00780E80, 64 bytes long.
     Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
    Object dump complete.
     像你所看到的,当_CRTDBG_MAP_ALLOC 被定义后_CrtDumpMemoryLeaks给了你很多有用的信息。在没有定义_CRTDBG_MAP_ALLOC 的情况下,显示信息包含:
    1.内存分配的编号(大括弧中的数字);
    2.内存快的类型(普通型、客户端型、CRT型);
    3.16进制表示的内存位置;
    4.内存快的大小;
    5.前16bytes的内容。
     如果定义了_CRTDBG_MAP_ALLOC ,输出信息还包含当前泄漏内存是在那个文件中被分配的定位信息。文件名后圆括弧中的数字是行数。如果你双击这行信息,
    C:PROGRAM FILESVISUAL STUDIOMyProjectsleaktestleaktest.cpp(20) : {18}
       normal block at 0x00780E80, 64 bytes long.
    光标就会跳转到原文件中分配这个内存的行前。选择Output中的题是行,按F4能达到同样的效果。

     使用Using _CrtSetDbgFlag:
     如果你的程序的退出点只有一个的话,调用_CrtDumpMemoryLeaks将是非常容易。但是,如果你的程序有多个退出点话会是什么样一个情况?如果不想在每个退出点都调用_CrtDumpMemoryLeaks,你可以在程序的开始包含以下调用:
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    这个语句会在你的程序结束时自动调用_CrtDumpMemoryLeaks,但是你必须象前边提到的那样设置_CRTDBG_ALLOC_MEM_DF 和 _CRTDBG_LEAK_CHECK_DF这两个标志位。

     介绍一下内存块的类型:
     就象前面指出的,一个内存泄漏信息指出每个内存泄漏块的类型为普通、客户端或者CRT型。在实际程序中,普通型和客户端型式最常见的类型。
     普通型内存块是你的程序平常分配的内存类型。
     客户端型内存块是MFC程序给需要析构的对象分配的内存块。MFC的new操作可以选择普通型或客户端型中合适的一种作为将要被创建的对象的内存块类型。
     CRT内存块是CRT库为自己使用而分配的内存块。CRT在处理自己的释放内存操作时使用这些块,所以在内存泄漏报告中这种类型并不常见,除非发生严重异常(例如:CRT库出错)。
     还有两种类型你在内存泄漏信息中看不到:
     自由块,它是已经被释放的内存块;
     忽略块,它是已经被特殊标示的内存块。

     设置CRT报告的格式:
     在默认情况下,_CrtDumpMemoryLeaks输出的内存泄漏信息就象前边描述的那样。你可以使用_CrtSetReportMode让这些输出信息输出到其他地方。如果你使用一个库,它可能要使输出信息到其他的地方,在这种情况下,你可以使用_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );语句使输出信息重新定位到Output窗口。

     根据内存分配编号设置断点:
     内存泄漏报告中的文件名和行数告诉你内存泄漏的位置,但是知道内存泄漏位置不是总是能找到问题所在。在一个运行的程序中一个内存分配操作可能被调用多次,但是内存泄漏可能只发生在其中的某次操作中。为了确认问题所在,你除了知道泄漏的位置之外,你还必须要知道发生泄漏的条件。内存分配编号使得解决这个问题成为可能。这个数字就在文件名、行数之后的大括弧内。例如,在上面的输出中“18”就是内存分配编号,它的意思是你程序中的内存泄漏发生在第18次分配操作中。
     CRT库对正在运行程序中所有的内存块分配进行计数,包括自身的内存分配,或者其他库(象MFC)。一个对象的分配编号是n表示第n个对象被分配,但是它可能并不表示第N个对象通过代码被分配(在大多数情况下它们并不相同)。
     你可以根据内存分配编号在内存被分配的位置设置断点。先在程序开始部分附近设置一个断点,当你的程序在断点处停止后,你可以通过QuickWatch对话框或者Watch窗口来设置内存分配断点。在Watch窗口中的Name列中输入_crtBreakAlloc,如果你使用的是多线程DLL版本的CRT库的话你必须包含上下文转换 {,,msvcrtd.dll}_crtBreakAlloc。完成后按回车,debugger处理这次调用,并且把返回值显示在Value列中。如果你没有设置内存分配断点的话返回值是-1。在Value列中输入你想设置的分配数,例如18。
     你在自己感兴趣的内存分配位置设置断点后,你可以继续debugging。细心的运行你的程序在相同的条件下,这样才能保证内存分配的顺序不致发生变化。当程序在特定的内存分配处停下来后, 你可以查看Call 窗口和其他的debugger信息来分析此次内存分配的条件。如果有必要你可以继续运行程序,看一看这个对象有什么变化,或许可以得知为什么内存没有被正确的释放。
     尽管这个操作非常容易,但是如果你高兴的话也可以在代码中设置断点。在代码中增加一行代码_crtBreakAlloc = 18;另外也可以通过_CrtSetBreakAlloc(18)来完成设置。

     比较内存状态
     另一个定位内存泄漏的方法是在重要位置捕捉应用程序的“内存快照”。CRT库提供了一个结构体类型 _CrtMemState,使用它你可以保存内存状态的快照(当前状态)。
    _CrtMemState s1, s2, s3;
     为了得到一个快照,可以把一个_CrtMemState 结构体传给_CrtMemCheckpoint 函数,这个函数可以把当前的内存状态填充在结构体中:
    _CrtMemCheckpoint( &s1 );
     你可以通过把结构体_CrtMemState 传给_CrtMemDumpStatistics函数来输出结构体中的内容。
    _CrtMemDumpStatistics( &s3 );( &s1 );
     它输出的信息如下:
    0 bytes in 0 Free Blocks.
    0 bytes in 0 Normal Blocks.
    3071 bytes in 16 CRT Blocks.
    0 bytes in 0 Ignore Blocks.
    0 bytes in 0 Client Blocks.
    Largest number used: 3071 bytes.
    Total allocations: 3764 bytes.
     为了得知一段代码中是否有内存泄漏,你可以在这段代码的开始和完成处分别拍一个快照,然后调用_CrtMemDifference函数来比较两个状态:
    _CrtMemCheckpoint( &s1 );
    // memory allocations take place here
    _CrtMemCheckpoint( &s2 );

    if ( _CrtMemDifference( &s3, &s1, &s2) )
       _CrtMemDumpStatistics( &s3 );
     就像名字中暗示的那样,_CrtMemDifference比较两个内存状态,并且产生一个结果(第一个参数)。把 _CrtMemCheckpoint 放在程序的开始和结尾,调用_CrtMemDifference 来比较结果,这也是一种检测内存泄漏的方法。如果发现内存泄漏,你可以使用_CrtMemCheckpoint把程序分成两半分别使用上述方法来检测内存泄漏,这样就是使用二分法来检查内存泄漏。

  • C/C++内存泄漏

    2007-06-21 21:28:06

        对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题。已经有许多技术被研究出来以应对这个问题,比如Smart Pointer,Garbage Collection等。Smart Pointer技术比较成熟,STL中已经包含支持Smart Pointer的class,但是它的使用似乎并不广泛,而且它也不能解决所有的问题;Garbage Collection技术在Java中已经比较成熟,但是在c/c++领域的发展并不顺畅,虽然很早就有人思考在C++中也加入GC的支持。现实世界就是这样的,作为一个c/c++程序员,内存泄漏是你心中永远的痛。不过好在现在有许多工具能够帮助我们验证内存泄漏的存在,找出发生问题的代码。

      内存泄漏的定义

      一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显示释放的内存。应用程序一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。以下这段小程序演示了堆内存发生泄漏的情形:

    void MyFunction(int nSize)
    {
     char* p= new char[nSize];
     if( !GetStringFrom( p, nSize ) ){
      MessageBox(“Error”);
      return;
     }
     …//using the string pointed by p;
     delete p;
    }

      例一

      当函数GetStringFrom()返回零的时候,指针p指向的内存就不会被释放。这是一种常见的发生内存泄漏的情形。程序在入口处分配内存,在出口处释放内存,但是c函数可以在任何地方退出,所以一旦有某个出口处没有释放应该释放的内存,就会发生内存泄漏。

      广义的说,内存泄漏不仅仅包含堆内存的泄漏,还包含系统资源的泄漏(resource leak),比如核心态HANDLE,GDI Object,SOCKET, Interface等,从根本上说这些由操作系统分配的对象也消耗内存,如果这些对象发生泄漏最终也会导致内存的泄漏。而且,某些对象消耗的是核心态内存,这些对象严重泄漏时会导致整个操作系统不稳定。所以相比之下,系统资源的泄漏比堆内存的泄漏更为严重。

      GDI Object的泄漏是一种常见的资源泄漏:

    void CMyView::OnPaint( CDC* pDC )
    {
     CBitmap bmp;
     CBitmap* pOldBmp;
     bmp.LoadBitmap(IDB_MYBMP);
     pOldBmp = pDC->SelectObject( &bmp );
     …
     if( Something() ){
      return;
     }
     pDC->SelectObject( pOldBmp );
     return;
    }

      例二

      当函数Something()返回非零的时候,程序在退出前没有把pOldBmp选回pDC中,这会导致pOldBmp指向的HBITMAP对象发生泄漏。这个程序如果长时间的运行,可能会导致整个系统花屏。这种问题在Win9x下比较容易暴露出来,因为Win9x的GDI堆比Win2k或NT的要小很多。

      内存泄漏的发生方式:

      以发生的方式来分类,内存泄漏可以分为4类:

      1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。比如例二,如果Something()函数一直返回True,那么pOldBmp指向的HBITMAP对象总是发生泄漏。

      2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。比如例二,如果Something()函数只有在特定环境下才返回 True,那么pOldBmp指向的HBITMAP对象并不总是发生泄漏。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。

      3. 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,但是因为这个类是一个Singleton,所以内存泄漏只会发生一次。另一个例子:

    char* g_lpszFileName = NULL;

    void SetFileName( const char* lpcszFileName )
    {
     if( g_lpszFileName ){
      free( g_lpszFileName );
     }
     g_lpszFileName = strdup( lpcszFileName );
    }

      例三

      如果程序在结束的时候没有释放g_lpszFileName指向的字符串,那么,即使多次调用SetFileName(),总会有一块内存,而且仅有一块内存发生泄漏。

      4. 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。举一个例子:

    class Connection
    {
     public:
      Connection( SOCKET s);
      ~Connection();
      …
     private:
      SOCKET _socket;
      …
    };

    class ConnectionManager
    {
     public:
      ConnectionManager(){}
      ~ConnectionManager(){
       list::iterator it;
       for( it = _connlist.begin(); it != _connlist.end(); ++it ){
        delete (*it);
       }
       _connlist.clear();
      }
      void OnClientConnected( SOCKET s ){
       Connection* p = new Connection(s);
       _connlist.push_back(p);
      }
      void OnClientDisconnected( Connection* pconn ){
       _connlist.remove( pconn );
       delete pconn;
      }
     private:
      list _connlist;
    };

      例四

      假设在Client从Server端断开后,Server并没有呼叫OnClientDisconnected()函数,那么代表那次连接的 Connection对象就不会被及时的删除(在Server程序退出的时候,所有Connection对象会在ConnectionManager的析构函数里被删除)。当不断的有连接建立、断开时隐式内存泄漏就发生了。

      从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。

  • 软件界面的美观性及软件的易用性方面

    2007-06-21 19:25:16

     

    易用性 
    考察评定软件的易学易用性,各个功能是否易于完成,软件界面是否友好等方面进行测试,这点在很多类型的管理类软件中是非常重要的。 

    通常对易用性有如下定义: 
      易见Easy to discover:单单凭观察,用户就应知道设备的状态,该设备供选择可以采取的行动。 
      易学Easy to learn:不通过帮助文件或通过简单的帮助文件,用户就能对一个陌生的产品有清晰的认识。 
      易用Easy to use:用户不翻阅手册就能使用软件。 

    对于易用性测试可遵循以下原则:

    1、完成相同或相近功能的按钮用Frame 框起来,常用按钮要支持快捷方式。

    2、完成同一功能或任务的元素放在集中位置,减少鼠标移动的距离。

    3、按功能将界面划分局域块,用Frame 框起来,并要有功能说明或标题。

    4、界面要支持键盘自动浏览按钮功能,即按Tab 键的自动切换功能。

    5、界面上首先应输入的信息和重要信息的控件在Tab 顺序中应当靠前,位置也应放在窗口上较醒目的位置。

    6、同一界面上的控件数最好不要超过10 个,多于10 个时可以考虑使用分页界面显示。

    7、分页界面要支持在页面间的快捷切换,常用组合快捷键Ctrl+Tab

    8、默认按钮要支持Enter 操作,即按Enter 后自动执行默认按钮对应操作。

    9、可输入控件检测到非法输入后应给出说明信息并能自动获得焦点。

    10、Tab 键的顺序与控件排列顺序要一直,目前流行总体从上到下,同时行间从左到右的方式。

    11、复选框和选项框按选择几率的高底而先后排列。

    12、复选框和选项框要有默认选项,并支持Tab 选择。

    13、选项数相同时多用选项框而不用下拉列表框。

    14、界面空间较小时使用下拉框而不用选项框。

    15、选项数较少时使用选项框,相反使用下拉列表框。

    16、专业性强的软件要使用相关的专业术语,通用性界面则提倡使用通用性词眼。

    17、对于界面输入重复性高的情况,该界面应全面支持键盘操作,即在不使用鼠标的情况下采用键盘进行操作。

    对于易用性测试还可从以下几个方面入手:

    1、导航测试
     

    导航描述了用户在一个页面内操作的方式,在不同的用户接口控制之间,例如按钮、对话框、列表和窗口等;或在不同的连接页面之间。通过考虑下列问题,可以决定一个应用系统是否易于导航:导航是否直观?系统的主要部分是否可通过主页存取?系统是否需要站点地图、搜索引擎或其他的导航帮助? 
    在一个页面上放太多的信息往往起到与预期相反的效果。应用系统的用户趋向于目的驱动,很快地扫描一个应用系统,看是否有满足自己需要的信息,如果没有,就会很快地离开。很少有用户愿意花时间去熟悉应用系统的结构,因此,应用系统导航帮助要尽可能地准确。导航的另一个重要方面是应用系统的页面结构、导航、菜单、连接的风格是否一致。确保用户凭直觉就知道应用系统里面是否还有内容,内容在什么地方。
    应用系统的层次一旦决定,就要着手测试用户导航功能,让最终用户参与这种测试,效果将更加明显。

    2、图形测试 

    在应用系统中,适当的图片和动画既能起到广告宣传的作用,又能起到美化页面的功能。一个应用系统的图形可以包括图片、动画、边框、颜色、字体、背景、按钮等。图形测试的内容有:

    (1)要确保图形有明确的用途,图片或动画不要胡乱地堆在一起,以免浪费传输时间。应用系统的图片尺寸要尽量地小,并且要能清楚地说明某件事情,一般都链接到某个具体的页面。

    (2)验证所有页面字体的风格是否一致。

    (3)背景颜色应该与字体颜色和前景颜色相搭配。

    (4)图片的大小和质量也是一个很重要的因素,一般采用JPG或GIF压缩。

    3、内容测试

    内容测试用来检验应用系统提供信息的正确性、准确性和相关性。
    信息的正确性是指信息是可靠的还是误传的。例如,在商品价格列表中,错误的价格可能引起财政问题甚至导致法律纠纷;信息的准确性是指是否有语法或拼写错误。这种测试通常使用一些文字处理软件来进行,例如使用Microsoft Word的"拼音与语法检查"功能;信息的相关性是指是否在当前页面可以找到与当前浏览信息相关的信息列表或入口,也就是一般Web站点中的所谓"相关文章列表"。

    4、整体界面测试

    整体界面是指整个应用系统的页面结构设计,是给用户的一个整体感。例如:当用户浏览应用系统时是否感到舒适,是否凭直觉就知道要找的信息在什么地方?整个应用系统的设计风格是否一致?
    对整体界面的测试过程,其实是一个对最终用户进行调查的过程。一般应用系统采取在主页上做一个调查问卷的形式,来得到最终用户的反馈信息。对所有的可用性测试来说,都需要有外部人员(与应用系统开发没有联系或联系很少的人员)的参与,最好是最终用户的参与。  


    界面

    界面是软件与用户交互的最直接的层面,界面的好坏决定用户对软件的第一印象。而设计优良的界面能够引导用户自己完成相应的操作,起到向导的作用。同时界面如同人的面孔,具有吸引用户的直接优势。设计合理的界面能给用户带来轻松愉悦的感受和成功的感觉,相反由于界面设计的失败,让用户有挫败感,再实用强大的功能都可能在用户的畏惧与放弃中付诸东流。
    目前流行的界面风格有三种方式:多窗体、单窗体以及资源管理器风格,无论那种风格,以下原则应该得到重视或参考。在测试人员进行测试过程中,也可参考以下原则对产品进行评价。

    1、规范性原则

    通常界面设计都按Windows 界面的规范来设计,即包含“菜单条、工具栏、工具厢、状态栏、滚动条、右键快捷菜单”的标准格式,可以说:界面遵循规范化的程度越高,则易用性相应的就越好。小型软件一般不提供工
    具厢。
    规范性细则:

    (1)常用菜单要有命令快捷方式。

    (2)完成相同或相近功能的菜单用横线隔开放在同一位置。

    (3)菜单前的图标能直观的代表要完成的操作。

    (4)菜单深度一般要求最多控制在三层以内。

    (5)工具栏要求可以根据用户的要求自己选择定制。

    (6)相同或相近功能的工具栏放在一起。

    (7)工具栏中的每一个按钮要有及时提示信息。

    (8)一条工具栏的长度最长不能超出屏幕宽度。

    (9)工具栏的图标能直观的代表要完成的操作。

    (10)系统常用的工具栏设置默认放置位置。

    (11)工具栏太多时可以考虑使用工具厢。

    (12)工具厢要具有可增减性,由用户自己根据需求定制。

    (13)工具厢的默认总宽度不要超过屏幕宽度的1/5。

    (14)状态条要能显示用户切实需要的信息,常用的有:目前的操作、系统状态、用户位置、用户信息、提示信息、错误信息、使用单位信息及软件开发商信息等,如果某一操作需要的时间较长,还应该显示进度条和进程提示


    (15)滚动条的长度要根据显示信息的长度或宽度能及时变换,以利于用户了解显示信息的位置和百分比。

    (16)状态条的高度以放置五好字为宜,滚动条的宽度比状态条的略窄。

    (17)菜单和工具条要有清楚的界限;菜单要求凸出显示,这样在移走工具条时仍有立体感。

    (18)菜单和状态条中通常使用5 号字体。工具条一般比菜单要宽,但不要宽的太多,否则看起来很不协调。

    (19)右键快捷菜单采用与菜单相同的准则。

    2、帮助设施原则

    系统应该提供详尽而可靠的帮助文档,在用户使用产生迷惑时可以自己寻求解决方法。
    帮助设施细则:

    (1)帮助文档中的性能介绍与说明要与系统性能配套一致。

    (2)打包新系统时,对作了修改的地方在帮助文档中要做相应的修改,做到版本统一。

    (3)操作时要提供及时调用系统帮助的功能。常用F1。

    (4)在界面上调用帮助时应该能够及时定位到与该操作相对的帮助位置。也就是说帮助要有即时针对性。

    (5)最好提供目前流行的联机帮助格式或HTML 帮助格式。

    (6)用户可以用关键词在帮助索引中搜索所要的帮助,当然也应该提供帮助主题词。

    (7)如果没有提供书面的帮助文档的话,最好有打印帮助的功能。

    (8)在帮助中应该提供我们的技术支持方式,一旦用户难以自己解决可以方便的寻求新的帮助方式。


    3、合理性原则

    屏幕对角线相交的位置是用户直视的地方,正上方四分之一处为易吸引用户注意力的位置,在放置窗体时要注意利用这两个位置。
    合理性细则:

    (1) 父窗体或主窗体的中心位置应该在对角线焦点附近。

    (2) 子窗体位置应该在主窗体的左上角或正中。

    (3) 多个子窗体弹出时应该依次向右下方偏移,以显示窗体出标题为宜。

    (4) 重要的命令按钮与使用较频繁的按钮要放在界面上注目的位置。

    (5)错误使用容易引起界面退出或关闭的按钮不应该放在易点位置。横排开头或最后与竖排最后为易点位置。

    (6) 与正在进行的操作无关的按钮应该加以屏蔽。

    (7) 对可能造成数据无法恢复的操作必须提供确认信息,给用户放弃选择的机会。

    (8) 非法的输入或操作应有足够的提示说明。

    (9)对运行过程中出现问题而引起错误的地方要有提示,让用户明白错误出处,避免形成无限期的等待。

    (10)提示、警告、或错误说明应该清楚、明了、恰当并且应避免英文提示的出现。

    4、美观与协调性原则

    界面应该大小适合美学观点,感觉协调舒适,能在有效的范围内吸引用户的注意力。
    美观与协调性细则:

    (1)长宽接近黄金点比例,切忌长宽比例失调、或宽度超过长度。

    (2)布局要合理,不宜过于密集,也不能过于空旷,合理的利用空间。

    (3)按钮大小基本相近,忌用太长的名称,免得占用过多的界面位置。

    (4)按钮的大小要与界面的大小和空间要协调。

    (5)避免空旷的界面上放置很大的按钮。

    (6)放置完控件后界面不应有很大的空缺位置。

    (7)字体的大小要与界面的大小比例协调,通常使用的字体中宋体9-12 较为美观,很少使用超过12号的字体。

    (8)前景与背景色搭配合理协调,反差不宜太大,最好少用深色,如大红、大绿等。常用色考虑使用Windows 界面色调。

    (9)如果使用其他颜色,主色要柔和,具有亲和力与磁力,坚决杜绝刺目的颜色。

    (10)大型系统常用的主色有"#E1E1E1"、"#EFEFEF"、"#C0C0C0"等。

    (11)界面风格要保持一致,字的大小、颜色、字体要相同,除非是需要艺术处理或有特殊要求的地方。

    (12)如果窗体支持最小化和最大化或放大时,窗体上的控件也要随着窗体而缩放;切忌只放大窗体而忽略控件的缩放。

    (13)对于含有按钮的界面一般不应该支持缩放,即右上角只有关闭功能。

    (14)通常父窗体支持缩放时,子窗体没有必要缩放。

    (15)如果能给用户提供自定义界面风格则更好,由用户自己选择颜色、字体等。

    5、菜单位置原则

    菜单是界面上最重要的元素,菜单位置按照按功能来组织。
    菜单设置细则:

    (1)菜单通常采用“常用--主要--次要--工具--帮助”的位置排列,符合流行的Windows 风格。

    (2)常用的有“文件”、“编辑”,“查看”等,几乎每个系统都有这些选项,当然要根据不同的系统有所取舍。

    (3)下拉菜单要根据菜单选项的含义进行分组,并切按照一定的规则进行排列,用横线隔开。

    (4)一组菜单的使用有先后要求或有向导作用时,应该按先后次序排列。

    (5)没有顺序要求的菜单项按使用频率和重要性排列,常用的放在开头,不常用的靠后放置;重要的放在开头,次要的放在后边。

    (6)如果菜单选项较多,应该采用加长菜单的长度而减少深度的原则排列。

    (7)菜单深度一般要求最多控制在三层以内。

    (8)对常用的菜单要有快捷命令方式,组合原则见7。

    (9)对与进行的操作无关的菜单要用屏蔽的方式加以处理,如果采用动态加载方式—即只有需要的菜单才显示—最好。

    (10)菜单前的图标不宜太大,与字高保持一直最好。

    (11)主菜单的宽度要接近,字数不应多于四个,每个菜单的字数能相同最好。

    (12)主菜单数目不应太多,最好为单排布置。

    6、独特性原则

    如果一味的遵循业界的界面标准,则会丧失自己的个性。在框架符合以上规范的情况下,设计具有自己独特风格的界面尤为重要。尤其在商业软件流通中有着很好的迁移默化的广告效用。
    独特性细则:

    (1)安装界面上应有单位介绍或产品介绍,并有自己的图标或徽标。

    (2)主界面,最好是大多数界面上要有公司图标或徽标。

    (3)登录界面上要有本产品的标志,同时包含公司图标或徽标。

    (4)帮助菜单的“关于”中应有版权和产品信息。

    (5)公司的系列产品要保持一直的界面风格,如背景色、字体、菜单排列方式、图标、安装过程、按钮用语等应该大体一致。

    (6)应为产品制作特有的图标并区别于公司图标或徽标

    7、快捷方式的组合原则

    在菜单及按钮中使用快捷键可以让喜欢使用键盘的用户操作得更快一些,在西文Windows 及其应用软件中快捷键的使用大多是一致的。
    菜单中:

    (1)面向事务的组合有:Ctrl-D 删除;Ctrl-F 寻找;Ctrl –H 替换;Ctrl-I 插入;Ctrl-N 新记录;Ctrl-S 保存Ctrl-O 打开。

    (2)列表:Ctrl-R ,Ctrl-G 定位;Ctrl-Tab 下一分页窗口或反序浏览同一页面控件。

    (3)编辑:Ctrl-A 全选;Ctrl-C 拷贝;Ctrl-V 粘贴;Ctrl-X 剪切;Ctrl-Z 撤消操作;Ctrl-Y 恢复操作。

    (4)文件操作:Ctrl-P 打印;Ctrl-W 关闭。

    (5)系统菜单:Alt-A 文件;Alt-E 编辑;Alt-T 工具;Alt-W 窗口;Alt-H 帮助。

    (6)MS Windows 保留键:Ctrl-Esc 任务列表;Ctrl-F4 关闭窗口;Alt-F4 结束应用;Alt-Tab 下一应用;Enter 缺省按钮/确认操作;Esc取消按钮/取消操作;Shift-F1 上下文相关帮助。

    按钮中:可以根据系统需要而调节,以下只是常用的组合。

    Alt-Y 确定(是);Alt-C 取消;Alt-N 否;Alt-D 删除;Alt-Q 退出;Alt-A 添加;Alt-E 编辑;Alt-B 浏览;Alt-R 读;Alt-W 写。
    这些快捷键也可以作为开发中文应用软件的标准,但亦可使用汉语拼音的开头字母。

    8、排错性考虑原则

    在界面上通过下列方式来控制出错几率,会大大减少系统因用户人为的错误引起的破坏。开发者应当尽量周全地考虑到各种可能发生的问题,使出错的可能降至最小。如应用出现保护性错误而退出系统,这种错误最容易使用户对软件失去信心。因为这意味着用户要中断思路,并费时费力地重新登录,而且已进行的操作也会因没有存盘而全部丢失。
    排错性细则:

    (1)最重要的是排除可能会使应用非正常中止的错误。

    (2)应当注意尽可能避免用户无意录入无效的数据。

    (3)采用相关控件限制用户输入值的种类。

    (4)当用户作出选择的可能性只有两个时,可以采用单选框。

    (5)当选择的可能再多一些时,可以采用复选框,每一种选择都是有效的,用户不可能输入任何一种无效的选择。

    (6)当选项特别多时,可以采用列表框,下拉式列表框。

    (7)在一个应用系统中,开发者应当避免用户作出未经授权或没有意义的操作。

    (8)对可能引起致命错误或系统出错的输入字符或动作要加限制或屏蔽。

    (9)对可能发生严重后果的操作要有补救措施。通过补救措施用户可以回到原来的正确状态。

    (10)对一些特殊符号的输入、与系统使用的符号相冲突的字符等进行判断并阻止用户输入该字符。

    (11)对错误操作最好支持可逆性处理,如取消系列操作。

    (12)在输入有效性字符之前应该阻止用户进行只有输入之后才可进行的操作。

    (13)对可能造成等待时间较长的操作应该提供取消功能。

    (14)特殊字符常有;;’”><,`‘:“[”{、\|}]+=")-(_*&&^%$#@!
    ,。?/还有空格。

    (15)与系统采用的保留字符冲突的要加以限制。

    (16)在读入用户所输入的信息时,根据需要选择是否去掉前后空格。

    (17)有些读入数据库的字段不支持中间有空格,但用户切实需要输入中间空格,这时要在程序中加以处理。

    9、多窗口的应用与系统资源原则

    设计良好的软件不仅要有完备的功能,而且要尽可能的占用最底限度的资源。

    (1)在多窗口系统中,有些界面要求必须保持在最顶层,避免用户在打开多个窗口时,不停的切换甚至最小化其他窗口来显示该窗口。

    (2)在主界面载入完毕后自动卸出内存,让出所占用的WINDOWS 系统资源。

    (3)关闭所有窗体,系统退出后要释放所占的所有系统资源,除非是需要后台运行的系统。

    (4)尽量防止对系统的独占使用。

  • 内存泄漏检查-Rational Test Suite-Purify

    2007-06-21 14:53:45

     

           大家在测试过程中最头痛的是什么问题,我想大概是服务器运行时不知不觉的服务器就出现异常,通过SystemMonitor发现系统的内存随时间不断的减少,特别在C++的开发下由于没有像Java,C#有比较好的GC,所有的内存都是开发员进行控制,很容易出现内存泄漏的情况,那么如何高效的发现内存问题,成为高级测试人员与开发人员关注的问题。

         
    工欲善其事,必先利其器,要快速的在大型的应用中人工的排查内存问题,就有如大海捞针。如何在几百万代码定位问题,人工!显然是不可能的,那必须要借助工具,现在有许多比较好的内存检查工具,比如下面给大家介绍的Purify,PurifyIBM公司出的面象C++VBJava的内存检查工具。

    Purify可检查的常见错误类型如下:

    1 堆阵相关错误。

    2 堆栈相关错误。

    3 垃圾内存收集-Java 代码中相关的内存管理问题。

    4 COM 相关错误。

    5 指针错误。

    6 内存使用错误。

    7 Windows API 相关错误。

    8 句柄错误。

    当然可检查的错误类型还有很多,大家可以参考联机帮助,但我认为常见的错误大多数都发生上面提到的一些错误。

           下面主要给大家以一个例子来说明Purify的使用:

     

    1

    Purify的使用还是比较简单的,一般只要把程序写成.EXE,然后直接运行就行了,当然如果程序比较大时,则需要重新组织一下,分几个段进行测试,最好的办法就是用CPPUnit来写测试框架,直接调用单个的函数进行测试是最好的,我的例子就是用CPPunit来写的,单独调用相关的测试函数进行测试,由于这里不是介绍CppUint,所以只是给大家提一下,单元测试可以这样写。Purify的启动还是比较简单的,就是运行一个.EXE

           运行完后结果如下图:

     

     

     

    2

    大家可以看到报以下几个出错,有位未初始化内存,数组越界读写,内存泄露等几个大家比较头痛的问题,以前代码比较多时是无法查到的,现在有了这个工具,就可以很快的查到问题。

           同时Purify不光可以显示出错还可以定位是那段代码出错,当然你要有代码,不过它是把相关的模块全部显示出来,你要从里面找出是由你的代码引起的问题才行,这是一个比较晕的事情,不过多做几次就行,当然如果程序是你写的就更好了,就更容易找到问题,对上面的出现问题的点进行展开,跟据一些使用的经验我一般不会找系统相关的函数,而是先找与自己工程相关的函数,比如下图中的内存演示 int CMabString::LeakMemory():

    3

    就是工程中的代码,一般问题都是由自己的代码引起的,但Purify把所有与此相关的模块都引入,所以你要过滤出什么是真正问题的所在,同时你们还可以看到如果程序有代码的话,Purify可以把代码中的错误都标出,从而减小你再去查找代码的难度,从而快速的定位问题。

    当然,Purify还有许多比较好的特性,比如过滤,错误显示设定等等,通过它你可以更快更好的发现问题。

           Purify是一款非常不错的内存检查工作,结合PureCoverage,QuantifyRose Test Suite下的工具,就可以对代码级进行很好的测试,当然如果再结合测试框架,形成自动化测试则能大幅度的节约测试成本,提高工作效率,当然实施单元测试还是要看整个测试团队的能力,不能强推J。如果你要了解其它两个工具,可以看我专栏的其它介绍,谢谢大家。

  • 资源泄漏

    2007-06-21 14:52:20

    重复执行可能存在资源泄漏的操作,这一点非常关键。测试前首先应该分析一下,程序的哪里可能存在资源泄漏,然后重复大量的执行这些操作,操作的同时可以查看“windows任务管理器”中相应测试计数器检查是否存在资源泄漏。如果程序存在资源泄漏,但是在测试时没有执行存在资源泄漏的代码,也是不能发现资源泄漏的。

    资源泄漏判断标准:资源使用的一般步骤是申请资源--使用资源--释放资源。如果程序使用后没有及时释放资源,程序占用的资源就会越来越多,而系统的资源是有限的,当系统的资源被耗尽时,系统就会因为资源不足而出错。如果在重复执行某一操作时,程序占用的资源持续增加。
  • 内存泄漏

    2007-06-21 14:50:50

    内存泄漏的定义

      一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显示释放的内存。应用程序一般使用mallocreallocnew等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用freedelete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了

    广义的说,内存泄漏不仅仅包含堆内存的泄漏,还包含系统资源的泄漏(resource leak),比如核心态HANDLEGDI ObjectSOCKET Interface等,从根本上说这些由操作系统分配的对象也消耗内存,如果这些对象发生泄漏最终也会导致内存的泄漏。而且,某些对象消耗的是核心态内存,这些对象严重泄漏时会导致整个操作系统不稳定。所以相比之下,系统资源的泄漏比堆内存的泄漏更为严重。

     

    内存泄漏的发生方式

      以发生的方式来分类,内存泄漏可以分为4类:

      1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
      2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。
      3. 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。

    4. 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

     

    从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。

  • 测试->提醒!

    2007-06-18 18:08:31

    1.不要为错误找借口;不要认为程序的出错是由于误操作所引起,只要是在操作程序时所引起的错误都是应该改正或避免!

    2.做测试就如解一道数学题,你想拿分那就考虑全面一点,一个小疏忽,在客户眼里都是一根刺.

     

  • MYSQL错误信息列表

    2007-06-15 16:11:59

    本章列出了当你用任何主机语言调用MySQL时可能出现的错误。首先列出了服务器错误消息。其次列出了客户端程序消息。

    B.1. 服务器错误代码和消息

    服务器错误信息来自下述源文件:

    ·         错误消息信息列在share/errmsg.txt文件中。“%d”“%s”分别代表编号和字符串,显示时,它们将被消息值取代。

    ·         错误值列在share/errmsg.txt文件中,用于生成include/mysqld_error.hinclude/mysqld_ername.h MySQL源文件中的定义。

    ·         SQLSTATE值列在share/errmsg.txt文件中,用于生成include/sql_state.h MySQL源文件中的定义。

    由于更新很频繁,这些文件中可能包含这里未列出的额外错误消息。

    ·         错误:1000 SQLSTATE: HY000 (ER_HASHCHK)

    消息:hashchk

    ·         错误:1001 SQLSTATE: HY000 (ER_NISAMCHK)

    消息:isamchk

    ·         错误:1002 SQLSTATE: HY000 (ER_NO)

    消息:NO

    ·         错误:1003 SQLSTATE: HY000 (ER_YES)

    消息:YES

    ·         错误:1004 SQLSTATE: HY000 (ER_CANT_CREATE_FILE)

    消息:无法创建文件'%s' (errno: %d)

    ·         错误:1005 SQLSTATE: HY000 (ER_CANT_CREATE_TABLE)

    消息:无法创建表'%s' (errno: %d)

    ·         错误:1006 SQLSTATE: HY000 (ER_CANT_CREATE_DB)

    消息:无法创建数据库'%s' (errno: %d)

    ·         错误:1007 SQLSTATE: HY000 (ER_DB_CREATE_EXISTS)

    消息:无法创建数据库'%s',数据库已存在。

    ·         错误:1008 SQLSTATE: HY000 (ER_DB_DROP_EXISTS)

    消息:无法撤销数据库'%s',数据库不存在。

    ·         错误:1009 SQLSTATE: HY000 (ER_DB_DROP_DELETE)

    消息:撤销数据库时出错(无法删除'%s'errno: %d

    ·         错误:1010 SQLSTATE: HY000 (ER_DB_DROP_RMDIR)

    消息:撤销数据库时出错(can't rmdir '%s', errno: %d

    ·         错误:1011 SQLSTATE: HY000 (ER_CANT_DELETE_FILE)

    消息:删除'%s'时出错 (errno: %d)

    ·         错误:1012 SQLSTATE: HY000 (ER_CANT_FIND_SYSTEM_REC)

    消息:无法读取系统表中的记录。

    ·         错误:1013 SQLSTATE: HY000 (ER_CANT_GET_STAT)

    消息:无法获取'%s'的状态(errno: %d)

    ·         错误:1014 SQLSTATE: HY000 (ER_CANT_GET_WD)

    消息:无法获得工作目录(errno: %d)

    ·         错误:1015 SQLSTATE: HY000 (ER_CANT_LOCK)

    消息:无法锁定文件(errno: %d)

    ·         错误:1016 SQLSTATE: HY000 (ER_CANT_OPEN_FILE)

    消息:无法打开文件:'%s' (errno: %d)

    ·         错误:1017 SQLSTATE: HY000 (ER_FILE_NOT_FOUND)

    消息:无法找到文件: '%s' (errno: %d)

    ·         错误:1018 SQLSTATE: HY000 (ER_CANT_READ_DIR)

    消息:无法读取'%s'的目录 (errno: %d)

    ·         错误:1019 SQLSTATE: HY000 (ER_CANT_SET_WD)

    消息:无法为'%s'更改目录 (errno: %d)

    ·         错误:1020 SQLSTATE: HY000 (ER_CHECKREAD)

    消息:自上次读取以来表'%s'中的记录已改变。

    ·         错误:1021 SQLSTATE: HY000 (ER_DISK_FULL)

    消息:磁盘满(%s);等待某人释放一些空间...

    ·         错误:1022 SQLSTATE: 23000 (ER_DUP_KEY)

    消息:无法写入;复制表'%s'的 键。

    ·         错误:1023 SQLSTATE: HY000 (ER_ERROR_ON_CLOSE)

    消息:关闭'%s'时出错 (errno: %d)

    ·         错误:1024 SQLSTATE: HY000 (ER_ERROR_ON_READ)

    消息:读取文件'%s'时出错 (errno: %d)

    ·         错误:1025 SQLSTATE: HY000 (ER_ERROR_ON_RENAME)

    消息:将'%s'重命名为'%s'时出错 (errno: %d)

    ·         错误:1026 SQLSTATE: HY000 (ER_ERROR_ON_WRITE)

    消息:写入文件'%s'时出错 (errno: %d)

    ·         错误:1027 SQLSTATE: HY000 (ER_FILE_USED)

    消息:'%s'已锁定,拒绝更改。

    ·         错误:1028 SQLSTATE: HY000 (ER_FILSORT_ABORT)

    消息:分类失败

    ·         错误:1029 SQLSTATE: HY000 (ER_FORM_NOT_FOUND)

    消息:对于'%s',视图'%s'不存在。

    ·         错误:1030 SQLSTATE: HY000 (ER_GET_ERRNO)

    消息:从存储引擎中获得错误%d

    ·         错误:1031 SQLSTATE: HY000 (ER_ILLEGAL_HA)

    消息:关于'%s'的表存储引擎不含该选项。

    ·         错误:1032 SQLSTATE: HY000 (ER_KEY_NOT_FOUND)

    消息:无法在'%s'中找到记录。

    ·         错误:1033 SQLSTATE: HY000 (ER_NOT_FORM_FILE)

    消息:文件中的不正确信息:'%s'

    ·         错误:1034 SQLSTATE: HY000 (ER_NOT_KEYFILE)

    消息:对于表'%s', 键文件不正确,请尝试修复。

    ·         错误:1035 SQLSTATE: HY000 (ER_OLD_KEYFILE)

    消息:旧的键文件,对于表'%s',请修复之!

    ·         错误:1036 SQLSTATE: HY000 (ER_OPEN_AS_READONLY)

    消息:表'%s'是只读的。

    ·         错误:1037 SQLSTATE: HY001 (ER_OUTOFMEMORY)

    消息:内存溢出,重启服务器并再次尝试(需要%d字节)。

    ·         错误:1038 SQLSTATE: HY001 (ER_OUT_OF_SORTMEMORY)

    消息:分类内存溢出,增加服务器的分类缓冲区大小。

    ·         错误:1039 SQLSTATE: HY000 (ER_UNEXPECTED_EOF)

    消息:读取文件'%s'时出现意外EOF (errno: %d)

    ·         错误:1040 SQLSTATE: 08004 (ER_CON_COUNT_ERROR)

    消息:连接过多。

    ·         错误:1041 SQLSTATE: HY000 (ER_OUT_OF_RESOURCES)

    消息:内存溢出,请检查是否mysqld或其他进程使用了所有可用内存,如不然,或许应使用'ulimit'允许mysqld使用更多内存,或增加交换空间的大小。

    ·         错误:1042 SQLSTATE: 08S01 (ER_BAD_HOST_ERROR)

    消息:无法获得该地址给出的主机名。

    ·         错误:1043 SQLSTATE: 08S01 (ER_HANDSHAKE_ERROR)

    消息:不良握手

    ·         错误:1044 SQLSTATE: 42000 (ER_DBACCESS_DENIED_ERROR)

    消息:拒绝用户'%s'@'%s'访问数据库'%s'

    ·         错误:1045 SQLSTATE: 28000 (ER_ACCESS_DENIED_ERROR)

    消息:拒绝用户'%s'@'%s'的访问(使用密码:%s

    ·         错误:1046 SQLSTATE: 3D000 (ER_NO_DB_ERROR)

    消息:未选择数据库。

    ·         错误:1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR)

    消息:未知命令。

    ·         错误:1048 SQLSTATE: 23000 (ER_BAD_NULL_ERROR)

    消息:列'%s'不能为空。

    ·         错误:1049 SQLSTATE: 42000 (ER_BAD_DB_ERROR)

    消息:未知数据库'%s'

    ·         错误:1050 SQLSTATE: 42S01 (ER_TABLE_EXISTS_ERROR)

    消息:表'%s'已存在。

    ·         错误:1051 SQLSTATE: 42S02 (ER_BAD_TABLE_ERROR)

    消息:未知表'%s'

    ·         错误:1052 SQLSTATE: 23000 (ER_NON_UNIQ_ERROR)

    消息:%s中的列'%s'不明确。

    ·         错误:1053 SQLSTATE: 08S01 (ER_SERVER_SHUTDOWN)

    消息:在操作过程中服务器关闭。

    ·         错误:1054 SQLSTATE: 42S22 (ER_BAD_FIELD_ERROR)

    消息:'%s'中的未知列'%s'

    ·         错误:1055 SQLSTATE: 42000 (ER_WRONG_FIELD_WITH_GROUP)

    消息:'%s'不在GROUP BY中。

    ·         错误:1056 SQLSTATE: 42000 (ER_WRONG_GROUP_FIELD)

    消息:无法在'%s'上创建组。

    ·         错误:1057 SQLSTATE: 42000 (ER_WRONG_SUM_SELECT)

    消息:语句中有sum函数和相同语句中的列。

    ·         错误:1058 SQLSTATE: 21S01 (ER_WRONG_VALUE_COUNT)

    消息:列计数不匹配值计数。

    ·         错误:1059 SQLSTATE: 42000 (ER_TOO_LONG_IDENT)

    消息:ID名称'%s'过长。

    ·         错误:1060 SQLSTATE: 42S21 (ER_DUP_FIELDNAME)

    消息:重复列名'%s'

    ·         错误:1061 SQLSTATE: 42000 (ER_DUP_KEYNAME)

    消息:重复键名称'%s'

    ·         错误:1062 SQLSTATE: 23000 (ER_DUP_ENTRY)

    消息:键%d的重复条目'%s'

    ·         错误:1063 SQLSTATE: 42000 (ER_WRONG_FIELD_SPEC)

    消息:对于列'%s',列分类符不正确。

    ·         错误:1064 SQLSTATE: 42000 (ER_PARSE_ERROR)

    消息:在行%d上,%s靠近'%s'

    ·         错误:1065 SQLSTATE: 42000 (ER_EMPTY_QUERY)

    消息:查询为空。

    ·         错误:1066 SQLSTATE: 42000 (ER_NONUNIQ_TABLE)

    消息:非唯一的表/别名:'%s'

    ·         错误:1067 SQLSTATE: 42000 (ER_INVALID_DEFAULT)

    消息:关于'%s'的无效默认值。

    ·         错误:1068 SQLSTATE: 42000 (ER_MULTIPLE_PRI_KEY)

    消息:定义了多个主键。

    ·         错误:1069 SQLSTATE: 42000 (ER_TOO_MANY_KEYS)

    消息:指定了过多键:允许的最大键数是%d

    ·         错误:1070 SQLSTATE: 42000 (ER_TOO_MANY_KEY_PARTS)

    消息:指定了过多键部分:允许的最大键部分是%d

    ·         错误:1071 SQLSTATE: 42000 (ER_TOO_LONG_KEY)

    消息:指定的键过长,最大键长度是%d字节。

    ·         错误:1072 SQLSTATE: 42000 (ER_KEY_COLUMN_DOES_NOT_EXITS)

    消息:键列'%s'在表中不存在。

    ·         错误:1073 SQLSTATE: 42000 (ER_BLOB_USED_AS_KEY)

    消息:BLOB'%s'不能与已使用的表类型用在 键说明中。

    ·         错误:1074 SQLSTATE: 42000 (ER_TOO_BIG_FIELDLENGTH)

    消息:对于列'%s',列长度过大 (max = %d),请使用BLOBTEXT取而代之。

    ·         错误:1075 SQLSTATE: 42000 (ER_WRONG_AUTO_KEY)

    消息:不正确的表定义,只能有1auto列,而且必须将其定义为 键。

    ·         错误:1076 SQLSTATE: HY000 (ER_READY)

    消息:%s,连接就绪。版本:'%s',套接字:'%s',端口:%d

    ·         错误:1077 SQLSTATE: HY000 (ER_NORMAL_SHUTDOWN)

    消息:%s,正常关闭。

    ·         错误:1078 SQLSTATE: HY000 (ER_GOT_SIGNAL)

    消息:%s,获得信号%d。放弃!

    ·         错误:1079 SQLSTATE: HY000 (ER_SHUTDOWN_COMPLETE)

    消息:%s,关闭完成

    ·         错误:1080 SQLSTATE: 08S01 (ER_FORCING_CLOSE)

    消息:%s,强制关闭线程%ld,用户:'%s'

    ·         错误:1081 SQLSTATE: 08S01 (ER_IPSOCK_ERROR)

    消息:无法创建IP套接字

    ·         错误:1082 SQLSTATE: 42S12 (ER_NO_SUCH_INDEX)

    消息:表'%s'中没有与CREATE INDEX中索引类似的索引,重新创建表。

    ·         错误:1083 SQLSTATE: 42000 (ER_WRONG_FIELD_TERMINATORS)

    消息:字段分隔符参量不是预期的,请参考手册。

    ·         错误:1084 SQLSTATE: 42000 (ER_BLOBS_AND_NO_TERMINATED)

    消息:不能与BLOB一起使用固定行长度,请使用'fields terminated by'

    ·         错误:1085 SQLSTATE: HY000 (ER_TEXTFILE_NOT_READABLE)

    消息:文件'%s'必须在数据库目录下,或能被所有人读取。

    ·         错误:1086 SQLSTATE: HY000 (ER_FILE_EXISTS_ERROR)

    消息:文件'%s'已存在。

    ·         错误:1087 SQLSTATE: HY000 (ER_LOAD_INFO)

    消息:记录,%ld;已删除,%ld;已跳过,%ld;警告,%ld

    ·         错误:1088 SQLSTATE: HY000 (ER_ALTER_INFO)

    消息:记录,%ld;重复,%ld

    ·         错误:1089 SQLSTATE: HY000 (ER_WRONG_SUB_KEY)

    消息:不正确的子部分键,使用的键部分不是字符串,所用的长度长于键部分,或存储引擎不支持唯一子键。

    ·         错误:1090 SQLSTATE: 42000 (ER_CANT_REMOVE_ALL_FIELDS)

    消息:不能用ALTER TABLE删除所有列,请使用DROP TABLE取而代之。

    ·         错误:1091 SQLSTATE: 42000 (ER_CANT_DROP_FIELD_OR_KEY)

    消息:不能撤销'%s',请检查列/键是否存在。

    ·         错误:1092 SQLSTATE: HY000 (ER_INSERT_INFO)

    消息:记录,%ld;复制,%ld;告警,%ld

    ·         错误:1093 SQLSTATE: HY000 (ER_UPDATE_TABLE_USED)

    消息:不能在FROM子句中制定要更新的目标表'%s'

    ·         错误:1094 SQLSTATE: HY000 (ER_NO_SUCH_THREAD)

    消息:未知线程ID%lu

    ·         错误:1095 SQLSTATE: HY000 (ER_KILL_DENIED_ERROR)

    消息:你不是线程%lu的所有者。

    ·         错误:1096 SQLSTATE: HY000 (ER_NO_TABLES_USED)

    消息:未使用任何表。

    ·         错误:1097 SQLSTATE: HY000 (ER_TOO_BIG_SET)

    消息:列%sSET的字符串过多。

    ·         错误:1098 SQLSTATE: HY000 (ER_NO_UNIQUE_LOGFILE)

    消息:不能生成唯一的日志文件名%s.(1-999)

    ·         错误:1099 SQLSTATE: HY000 (ER_TABLE_NOT_LOCKED_FOR_WRITE)

    消息:表'%s'已用READ锁定,不能更新。

    ·         错误:1100 SQLSTATE: HY000 (ER_TABLE_NOT_LOCKED)

    消息:未使用LOCK TABLES锁定表'%s'

    ·         错误:1101 SQLSTATE: 42000 (ER_BLOB_CANT_HAVE_DEFAULT)

    消息:BLOB/TEXT'%s'不能有默认值。

    ·         错误:1102 SQLSTATE: 42000 (ER_WRONG_DB_NAME)

    消息:不正确的数据库名'%s'

    ·         错误:1103 SQLSTATE: 42000 (ER_WRONG_TABLE_NAME)

    消息:不正确的表名'%s'

    ·         错误:1104 SQLSTATE: 42000 (ER_TOO_BIG_SELECT)

    消息:SELECT将检查超过MAX_JOIN_SIZE的行,如果SELECT正常,请检查WHERE,并使用SET SQL_BIG_SELECTS=1SET SQL_MAX_JOIN_SIZE=#

    ·         错误:1105 SQLSTATE: HY000 (ER_UNKNOWN_ERROR)

    消息:未知错误。

    ·         错误:1106 SQLSTATE: 42000 (ER_UNKNOWN_PROCEDURE)

    消息:未知过程'%s'

    ·         错误:1107 SQLSTATE: 42000 (ER_WRONG_PARAMCOUNT_TO_PROCEDURE)

    消息:对于过程'%s',参数计数不正确

    ·         错误:1108 SQLSTATE: HY000 (ER_WRONG_PARAMETERS_TO_PROCEDURE)

    消息:对于过程'%s',参数不正确

    ·         错误:1109 SQLSTATE: 42S02 (ER_UNKNOWN_TABLE)

    消息:%s中的未知表%s

    ·         错误:1110 SQLSTATE: 42000 (ER_FIELD_SPECIFIED_TWICE)

    消息:列'%s'被指定了两次。

    ·         错误:1111 SQLSTATE: HY000 (ER_INVALID_GROUP_FUNC_USE)

    消息:无效的分组函数使用

    ·         错误:1112 SQLSTATE: 42000 (ER_UNSUPPORTED_EXTENSION)

    消息:表'%s'使用了该MySQL版本中不存在的扩展。

    ·         错误:1113 SQLSTATE: 42000 (ER_TABLE_MUST_HAVE_COLUMNS)

    消息:1个表至少要有1列。

    ·         错误:1114 SQLSTATE: HY000 (ER_RECORD_FILE_FULL)

    消息:表'%s'已满。

    ·         错误:1115 SQLSTATE: 42000 (ER_UNKNOWN_CHARACTER_SET)

    消息:未知字符集'%s'

    ·         错误:1116 SQLSTATE: HY000 (ER_TOO_MANY_TABLES)

    消息:表过多,MySQL1个联合操作中只能使用%d个表。

    ·         错误:1117 SQLSTATE: HY000 (ER_TOO_MANY_FIELDS)

    消息:列过多。

    ·         错误:1118 SQLSTATE: 42000 (ER_TOO_BIG_ROWSIZE)

    消息:行的大小过大。对于所使用的表类型,不包括BLOB,最大行大小为%ld。必须将某些列更改为TEXTBLOB

    ·         错误:1119 SQLSTATE: HY000 (ER_STACK_OVERRUN)

    消息:线程堆栈溢出,已使用,%ld堆栈的%ld。如果需要,请使用'mysqld -O thread_stack=#'指定较大的堆栈。

    ·         错误:1120 SQLSTATE: 42000 (ER_WRONG_OUTER_JOIN)

    消息:在OUTER JOIN中发现交叉关联,请检查ON条件。

    ·         错误:1121 SQLSTATE: 42000 (ER_NULL_COLUMN_IN_INDEX)

    消息:列'%s'UNIQUEINDEX一起使用,但未定义为NOT NULL

    ·         错误:1122 SQLSTATE: HY000 (ER_CANT_FIND_UDF)

    消息:无法加载函数'%s'

    ·         错误:1123 SQLSTATE: HY000 (ER_CANT_INITIALIZE_UDF)

    消息:无法初始化函数'%s'; %s

    ·         错误:1124 SQLSTATE: HY000 (ER_UDF_NO_PATHS)

    消息:对于共享库,不允许任何路径。

    ·         错误:1125 SQLSTATE: HY000 (ER_UDF_EXISTS)

    消息:函数'%s'已存在。

    ·         错误:1126 SQLSTATE: HY000 (ER_CANT_OPEN_LIBRARY)

    消息:不能打开共享库'%s' (errno: %d %s)

    ·         错误:1127 SQLSTATE: HY000 (ER_CANT_FIND_DL_ENTRY)

    消息:不能发现库中的符号'%s'

    ·         错误:1128 SQLSTATE: HY000 (ER_FUNCTION_NOT_DEFINED)

    消息:函数'%s'未定义。

    ·         错误:1129 SQLSTATE: HY000 (ER_HOST_IS_BLOCKED)

    消息:由于存在很多连接错误,主机'%s'被屏蔽,请用'mysqladmin flush-hosts'解除屏蔽。

    ·         错误:1130 SQLSTATE: HY000 (ER_HOST_NOT_PRIVILEGED)

    消息:不允许将主机'%s'连接到该MySQL服务器。

    ·         错误:1131 SQLSTATE: 42000 (ER_PASSWORD_ANONYMOUS_USER)

    消息:你正在已匿名用户身份使用MySQL,不允许匿名用户更改密码。

    ·         错误:1132 SQLSTATE: 42000 (ER_PASSWORD_NOT_ALLOWED)

    消息:必须有更新mysql数据库中表的权限才能更改密码。

    ·         错误:1133 SQLSTATE: 42000 (ER_PASSWORD_NO_MATCH)

    消息:无法在用户表中找到匹配行。

    ·         错误:1134 SQLSTATE: HY000 (ER_UPDATE_INFO)

    消息:行匹配,%ld;已更改,%ld;警告,%ld

    ·         错误:1135 SQLSTATE: HY000 (ER_CANT_CREATE_THREAD)

    消息:无法创建新线程(errno %d),如果未出现内存溢出,请参阅手册以了解可能的与操作系统有关的缺陷。

    ·         错误:1136 SQLSTATE: 21S01 (ER_WRONG_VALUE_COUNT_ON_ROW)

    消息:列计数不匹配行%ld上的值计数。

    ·         错误:1137 SQLSTATE: HY000 (ER_CANT_REOPEN_TABLE)

    消息:无法再次打开表'%s'

    ·         错误:1138 SQLSTATE: 22004 (ER_INVALID_USE_OF_NULL)

    消息:NULL值使用无效。

    ·         错误:1139 SQLSTATE: 42000 (ER_REGEXP_ERROR)

    消息:获得来自regexp的错误'%s'

    ·         错误:1140 SQLSTATE: 42000 (ER_MIX_OF_GROUP_FUNC_AND_FIELDS)

    消息:如果没有GROUP BY子句,GROUP (MIN(),MAX(),COUNT(),...)与非GROUP列的混合不合法。

    ·         错误:1141 SQLSTATE: 42000 (ER_NONEXISTING_GRANT)

    消息:没有为主机'%s'上的用户'%s'定义这类授权。

    ·         错误:1142 SQLSTATE: 42000 (ER_TABLEACCESS_DENIED_ERROR)

    消息:拒绝用户'%s'@'%s'在表'%s'上使用%s命令。

    ·         错误:1143 SQLSTATE: 42000 (ER_COLUMNACCESS_DENIED_ERROR)

    消息:拒绝用户'%s'@'%s'在表'%s''%s'上使用%s命令。

    ·         错误:1144 SQLSTATE: 42000 (ER_ILLEGAL_GRANT_FOR_TABLE)

    消息:非法GRANT/REVOKE命令,请参阅手册以了解可使用那种权限。

    ·         错误:1145 SQLSTATE: 42000 (ER_GRANT_WRONG_HOST_OR_USER)

    消息:GRANT的主机或用户参量过长。

    ·         错误:1146 SQLSTATE: 42S02 (ER_NO_SUCH_TABLE)

    消息:表'%s.%s'不存在。

    ·         错误:1147 SQLSTATE: 42000 (ER_NONEXISTING_TABLE_GRANT)

    消息:在表'%s'上没有为主机'%s'上的用户'%s'定义的这类授权。

    ·         错误:1148 SQLSTATE: 42000 (ER_NOT_ALLOWED_COMMAND)

    消息:所使用的命令在该MySQL版本中不允许。

    ·         错误:1149 SQLSTATE: 42000 (ER_SYNTAX_ERROR)

    消息:存在SQL语法错误,请参阅与你的MySQL版本对应的手册,以了解正确的语法。

    ·         错误:1150 SQLSTATE: HY000 (ER_DELAYED_CANT_CHANGE_LOCK)

    消息:对于表%s,延迟的插入线程不能获得请求的锁定。

    ·         错误:1151 SQLSTATE: HY000 (ER_TOO_MANY_DELAYED_THREADS)

    消息:使用的延迟线程过多。

    ·         错误:1152 SQLSTATE: 08S01 (ER_ABORTING_CONNECTION)

    消息:与数据库'%s'和用户'%s'的连接%ld失败 (%s)

    ·         错误:1153 SQLSTATE: 08S01 (ER_NET_PACKET_TOO_LARGE)

    消息:获得信息包大于'max_allowed_packet'字节。

    ·         错误:1154 SQLSTATE: 08S01 (ER_NET_READ_ERROR_FROM_PIPE)

    消息:获得来自连接管道的读错误。

    ·         错误:1155 SQLSTATE: 08S01 (ER_NET_FCNTL_ERROR)

    消息:获得来自fcntl()的错误。

    ·         错误:1156 SQLSTATE: 08S01 (ER_NET_PACKETS_OUT_OF_ORDER)

    消息:获得信息包无序。

    ·         错误:1157 SQLSTATE: 08S01 (ER_NET_UNCOMPRESS_ERROR)

    消息:无法解压缩通信信息包。

    ·         错误:1158 SQLSTATE: 08S01 (ER_NET_READ_ERROR)

    消息:读取通信信息包时出错。

    ·         错误:1159 SQLSTATE: 08S01 (ER_NET_READ_INTERRUPTED)

    消息:读取通信信息包时出现超时。

    ·         错误:1160 SQLSTATE: 08S01 (ER_NET_ERROR_ON_WRITE)

    消息:写入通信信息包时出错。

    ·         错误:1161 SQLSTATE: 08S01 (ER_NET_WRITE_INTERRUPTED)

    消息:写入通信信息包时出现超时。

    ·         错误:1162 SQLSTATE: 42000 (ER_TOO_LONG_STRING)

    消息:结果字符串长于'max_allowed_packet'字节。

    ·         错误:1163 SQLSTATE: 42000 (ER_TABLE_CANT_HANDLE_BLOB)

    消息:所使用的表类型不支持BLOB/TEXT列。

    ·         错误:1164 SQLSTATE: 42000 (ER_TABLE_CANT_HANDLE_AUTO_INCREMENT)

    消息:所使用的表类型不支持AUTO_INCREMENT列。

    ·         错误:1165 SQLSTATE: HY000 (ER_DELAYED_INSERT_TABLE_LOCKED)

    消息:由于用LOCK TABLES锁定了表,INSERT DELAYED不能与表'%s'一起使用。

    ·         错误:1166 SQLSTATE: 42000 (ER_WRONG_COLUMN_NAME)

    消息:不正确的列名'%s'

    ·         错误:1167 SQLSTATE: 42000 (ER_WRONG_KEY_COLUMN)

    消息:所使用的存储引擎不能为列'%s'编制索引。

    ·         错误:1168 SQLSTATE: HY000 (ER_WRONG_MRG_TABLE)

    消息:MERGE表中的所有表未同等定义。

    ·         错误:1169 SQLSTATE: 23000 (ER_DUP_UNIQUE)

    消息:由于唯一性限制,不能写入到表'%s'

    ·         错误:1170 SQLSTATE: 42000 (ER_BLOB_KEY_WITHOUT_LENGTH)

    消息:在未指定键长度的键说明中使用了BLOB/TEXT'%s'

    ·         错误:1171 SQLSTATE: 42000 (ER_PRIMARY_CANT_HAVE_NULL)

    消息:PRIMARY KEY的所有部分必须是NOT NULL,如果需要为NULL的关键字,请使用UNIQUE取而代之。

    ·         错误:1172 SQLSTATE: 42000 (ER_TOO_MANY_ROWS)

    消息:结果有1个以上的行组成。

    ·         错误:1173 SQLSTATE: 42000 (ER_REQUIRES_PRIMARY_KEY)

    消息:该表类型要求主键。

    ·         错误:1174 SQLSTATE: HY000 (ER_NO_RAID_COMPILED)

    消息:该MySQL版本是未使用RAID支持而编译的。

    ·         错误:1175 SQLSTATE: HY000 (ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE)

    消息:你正在使用安全更新模式,而且试图在不使用WHERE的情况下更新使用了KEY列的表。

    ·         错误:1176 SQLSTATE: HY000 (ER_KEY_DOES_NOT_EXITS)

    消息:在表'%s'中,键'%s'不存在。

    ·         错误:1177 SQLSTATE: 42000 (ER_CHECK_NO_SUCH_TABLE)

    消息:无法打开表。

    ·         错误:1178 SQLSTATE: 42000 (ER_CHECK_NOT_IMPLEMENTED)

    消息:用于表的引擎不支持%s

    ·         错误:1179 SQLSTATE: 25000 (ER_CANT_DO_THIS_DURING_AN_TRANSACTION)

    消息:不允许在事务中执行该命令。

    ·         错误:1180 SQLSTATE: HY000 (ER_ERROR_DURING_COMMIT)

    消息:在COMMIT期间出现错误%d

    ·         错误:1181 SQLSTATE: HY000 (ER_ERROR_DURING_ROLLBACK)

    消息:在ROLLBACK期间出现错误%d

    ·         错误:1182 SQLSTATE: HY000 (ER_ERROR_DURING_FLUSH_LOGS)

    消息:在FLUSH_LOGS期间出现错误%d

    ·         错误:1183 SQLSTATE: HY000 (ER_ERROR_DURING_CHECKPOINT)

    消息:在CHECKPOINT期间出现错误%d

    ·         错误:1184 SQLSTATE: 08S01 (ER_NEW_ABORTING_CONNECTION)

    消息:与数据库'%s'、用户'%s'和主机'%s'的连接%ld失败 (%s)

    ·         错误:1185 SQLSTATE: HY000 (ER_DUMP_NOT_IMPLEMENTED)

    消息:针对表的存储引擎不支持二进制表转储。

    ·         错误:1186 SQLSTATE: HY000 (ER_FLUSH_MASTER_BINLOG_CLOSED)

    消息:Binlog已关闭,不能RESET MASTER

    ·         错误:1187 SQLSTATE: HY000 (ER_INDEX_REBUILD)

    消息:重新创建转储表'%s'的索引失败。

    ·         错误:1188 SQLSTATE: HY000 (ER_MASTER)

    消息:来自主连接'%s'的错误。

    ·         错误:1189 SQLSTATE: 08S01 (ER_MASTER_NET_READ)

    消息:读取主连接时出现网络错误。

    ·         错误:1190 SQLSTATE: 08S01 (ER_MASTER_NET_WRITE)

    消息:写入主连接时出现网络错误。

    ·         错误:1191 SQLSTATE: HY000 (ER_FT_MATCHING_KEY_NOT_FOUND)

    消息:无法找到与列列表匹配的FULLTEXT索引。

    ·         错误:1192 SQLSTATE: HY000 (ER_LOCK_OR_ACTIVE_TRANSACTION)

    消息:由于存在活动的锁定表或活动的事务,不能执行给定的命令。

    ·         错误:1193 SQLSTATE: HY000 (ER_UNKNOWN_SYSTEM_VARIABLE)

    消息:未知的系统变量'%s'

    ·         错误:1194 SQLSTATE: HY000 (ER_CRASHED_ON_USAGE)

    消息:表'%s'被标记为崩溃,应予以修复。

    ·         错误:1195 SQLSTATE: HY000 (ER_CRASHED_ON_REPAIR)

    消息:表'%s'被标记为崩溃,而且上次修复失败(自动?)

    ·         错误:1196 SQLSTATE: HY000 (ER_WARNING_NOT_COMPLETE_ROLLBACK)

    消息:不能回滚某些非事务性已变动表。

    ·         错误:1197 SQLSTATE: HY000 (ER_TRANS_CACHE_FULL)

    消息:多语句事务要求更多的'max_binlog_cache_size'存储字节,增大mysqld变量,并再次尝试。

    ·         错误:1198 SQLSTATE: HY000 (ER_SLAVE_MUST_STOP)

    消息:运行从实例时不能执行该操作,请首先运行STOP SLAVE

    ·         错误:1199 SQLSTATE: HY000 (ER_SLAVE_NOT_RUNNING)

    消息:该操作需要运行的从实例,请配置SLAVE并执行START SLAVE

    ·         错误:1200 SQLSTATE: HY000 (ER_BAD_SLAVE)

    消息:服务器未配置为从服务器,请更正config文件,或使用CHANGE MASTER TO

    ·         错误:1201 SQLSTATE: HY000 (ER_MASTER_INFO)

    消息:无法初始化主服务器信息结构,在MySQL错误日志中可找到更多错误消息。

    ·         错误:1202 SQLSTATE: HY000 (ER_SLAVE_THREAD)

    消息:无法创建从线程,请检查系统资源。

    ·         错误:1203 SQLSTATE: 42000 (ER_TOO_MANY_USER_CONNECTIONS)

    消息:用户%s已有了超过'max_user_connections'的活动连接。

    ·         错误:1204 SQLSTATE: HY000 (ER_SET_CONSTANTS_ONLY)

    消息:或许仅应与SET一起使用常量表达式。

    ·         错误:1205 SQLSTATE: HY000 (ER_LOCK_WAIT_TIMEOUT)

    消息:超过了锁定等待超时,请尝试重新启动事务。

    ·         错误:1206 SQLSTATE: HY000 (ER_LOCK_TABLE_FULL)

    消息:总的锁定数超出了锁定表的大小。

    ·         错误:1207 SQLSTATE: 25000 (ER_READ_ONLY_TRANSACTION)

    消息:在READ UNCOMMITTED事务期间,无法获得更新锁定。

    ·         错误:1208 SQLSTATE: HY000 (ER_DROP_DB_WITH_READ_LOCK)

    消息:当线程保持为全局读锁定时,不允许DROP DATABASE

    ·         错误:1209 SQLSTATE: HY000 (ER_CREATE_DB_WITH_READ_LOCK)

    消息:当线程保持为全局读锁定时,不允许CREATE DATABASE

    ·         错误:1210 SQLSTATE: HY000 (ER_WRONG_ARGUMENTS)

    消息:为%s提供的参量不正确。

    ·         错误:1211 SQLSTATE: 42000 (ER_NO_PERMISSION_TO_CREATE_USER)

    消息:不允许'%s'@'%s'创建新用户。

    ·         错误:1212 SQLSTATE: HY000 (ER_UNION_TABLES_IN_DIFFERENT_DIR)

    消息:不正确的表定义,所有的MERGE表必须位于相同的数据库中。

    ·         错误:1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)

    消息:试图获取锁定时发现死锁,请尝试重新启动事务。

    ·         错误:1214 SQLSTATE: HY000 (ER_TABLE_CANT_HANDLE_FT)

    消息:所使用的表类型不支持FULLTEXT索引。

    ·         错误:1215 SQLSTATE: HY000 (ER_CANNOT_ADD_FOREIGN)

    消息:无法添加外键约束。

    ·         错误:1216 SQLSTATE: 23000 (ER_NO_REFERENCED_ROW)

    消息:无法添加或更新子行,外键约束失败。

    ·         错误:1217 SQLSTATE: 23000 (ER_ROW_IS_REFERENCED)

    消息:无法删除或更新父行,外键约束失败。

    ·         错误:1218 SQLSTATE: 08S01 (ER_CONNECT_TO_MASTER)

    消息:连接至主服务器%s时出错。

    ·         错误:1219 SQLSTATE: HY000 (ER_QUERY_ON_MASTER)

    消息:在主服务器%s上执行查询时出错。

    ·         错误:1220 SQLSTATE: HY000 (ER_ERROR_WHEN_EXECUTING_COMMAND)

    消息:执行命令%s: %s时出错。

    ·         错误:1221 SQLSTATE: HY000 (ER_WRONG_USAGE)

    消息:%s%s的用法不正确。

    ·         错误:1222 SQLSTATE: 21000 (ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT)

    消息:所使用的SELECT语句有不同的列数。

    ·         错误:1223 SQLSTATE: HY000 (ER_CANT_UPDATE_WITH_READLOCK)

    消息:由于存在冲突的读锁定,无法执行查询。

    ·         错误:1224 SQLSTATE: HY000 (ER_MIXING_NOT_ALLOWED)

    消息:禁止混合事务性表和非事务性表。

    ·         错误:1225 SQLSTATE: HY000 (ER_DUP_ARGUMENT)

    消息:在语句中使用了两次选项'%s'

    ·         错误:1226 SQLSTATE: 42000 (ER_USER_LIMIT_REACHED)

    消息:用户'%s'超出了'%s'资源(当前值:%ld)。

    ·         错误:1227 SQLSTATE: 42000 (ER_SPECIFIC_ACCESS_DENIED_ERROR)

    消息:拒绝访问,需要%s权限才能执行该操作。

    ·         错误:1228 SQLSTATE: HY000 (ER_LOCAL_VARIABLE)

    消息:变量'%s'1SESSION变量,不能与SET GLOBAL一起使用。

    ·         错误:1229 SQLSTATE: HY000 (ER_GLOBAL_VARIABLE)

    消息:变量'%s'1GLOBAL变量,应使用SET GLOBAL来设置它。

    ·         错误:1230 SQLSTATE: 42000 (ER_NO_DEFAULT)

    消息:变量'%s'没有默认值。

    ·         错误:1231 SQLSTATE: 42000 (ER_WRONG_VALUE_FOR_VAR)

    消息:变量'%s'不能设置为值'%s'

    ·         错误:1232 SQLSTATE: 42000 (ER_WRONG_TYPE_FOR_VAR)

    消息:变量'%s'的参量类型不正确。

    ·         错误:1233 SQLSTATE: HY000 (ER_VAR_CANT_BE_READ)

    消息:变量'%s'只能被设置,不能被读取。

    ·         错误:1234 SQLSTATE: 42000 (ER_CANT_USE_OPTION_HERE)

    消息:不正确的'%s'用法/位置。

    ·         错误:1235 SQLSTATE: 42000 (ER_NOT_SUPPORTED_YET)

    消息:该MySQL版本尚不支持'%s'

    ·         错误:1236 SQLSTATE: HY000 (ER_MASTER_FATAL_ERROR_READING_BINLOG)

    消息:从二进制日志读取数据时,获得来自主服务器的致命错误%d: '%s'

    ·         错误:1237 SQLSTATE: HY000 (ER_SLAVE_IGNORED_TABLE)

    消息:由于“replicate-*-table”规则,从SQL线程忽略了查询。。

    ·         错误:1238 SQLSTATE: HY000 (ER_INCORRECT_GLOBAL_LOCAL_VAR)

    消息:变量'%s'是一种%s变量。

    ·         错误:1239 SQLSTATE: 42000 (ER_WRONG_FK_DEF)

    消息:对于 '%s': %s, 外键定义不正确。

    ·         错误:1240 SQLSTATE: HY000 (ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)

    消息:键引用和表引用不匹配。

    ·         错误:1241 SQLSTATE: 21000 (ER_OPERAND_COLUMNS)

    消息:操作数应包含%d列。

    ·         错误:1242 SQLSTATE: 21000 (ER_SUBQUERY_NO_1_ROW)

    消息:子查询返回1行以上。

    ·         错误:1243 SQLSTATE: HY000 (ER_UNKNOWN_STMT_HANDLER)

    消息:指定给%s的未知预处理语句句柄。

    ·         错误:1244 SQLSTATE: HY000 (ER_CORRUPT_HELP_DB)

    消息:帮助数据库崩溃或不存在。

    ·         错误:1245 SQLSTATE: HY000 (ER_CYCLIC_REFERENCE)

    消息:对子查询的循环引用。

    ·         错误:1246 SQLSTATE: HY000 (ER_AUTO_CONVERT)

    消息:将列'%s'%s转换为%s

    ·         错误:1247 SQLSTATE: 42S22 (ER_ILLEGAL_REFERENCE)

    消息:引用'%s'不被支持 (%s)

    ·         错误:1248 SQLSTATE: 42000 (ER_DERIVED_MUST_HAVE_ALIAS)

    消息:所有的导出表必须有自己的别名。

    ·         错误:1249 SQLSTATE: 01000 (ER_SELECT_REDUCED)

    消息:在优化期间简化了选择%u

    ·         错误:1250 SQLSTATE: 42000 (ER_TABLENAME_NOT_ALLOWED_HERE)

    消息:来自某一SELECT的表'%s'不能在%s中使用。

    ·         错误:1251 SQLSTATE: 08004 (ER_NOT_SUPPORTED_AUTH_MODE)

    消息:客户端不支持服务器请求的鉴定协议,请考虑升级MySQL客户端。

    ·         错误:1252 SQLSTATE: 42000 (ER_SPATIAL_CANT_HAVE_NULL)

    消息:SPATIAL索引的所有部分必须是NOT NULL

    ·         错误:1253 SQLSTATE: 42000 (ER_COLLATION_CHARSET_MISMATCH)

    消息:对于CHARACTER SET '%s'COLLATION '%s'无效。

    ·     &n

  • 男儿当自强

    2007-06-15 10:55:19

    暂无
472/3<123>
Open Toolbar