发布新日志

  • 高手中的高手,巨搞笑!

    ypeony 发布于 2007-05-28 20:24:31

    一个电脑白痴跟一个黑客的对话!

    黑客:我控制了你的电脑    
    小白:怎么控制的?    
    黑客:用木马    
    小白:。。。。。。在哪里?我没看不见    
    黑客:打开你的任务管理器    
    小白:。。。。。。。任务管理器在哪?    
    黑客:。。。。。你的电脑下面!!    
    小白:“我的电脑”里面没有啊    
    黑客:算了,当我什么也没做过    

    黑客:我已经控制了你的电脑    
    小白:哦    
    黑客:害怕了吧?!嘿嘿    
    小白:来的正好,帮我杀杀毒吧,最近我的机子毛病很多耶    
    黑客:。。。。。。    

    小白:你怎么总是在我电脑里随便进进出出    
    黑客:你可以装防火墙    
    小白:装防火墙,你就不能进入了吗?    
    黑客:不啊,我只是想增加点趣味性,这样控制你的电脑让我觉得很白痴耶    

    小白:听说你会制造“病毒”?!    
    黑客:嗯    
    小白:你可以控制别人的电脑?!    
    黑客:一般是的    
    小白:那你可以黑掉那些网站吗?    
    黑客:当然,没听到人家叫我“黑客”吗?    
    小白:。。。。哦~~~`我还以为那是因为你长得很黑。。。。。    
    “咣~~”    

    黑客:我又来了!!    
    小白:你天天进来,不觉得很烦吗?    
    黑客:是很烦,你的机子是我见过的最烂的一台了    
    小白:不是吧,这可是名牌    
    黑客:我是说你的机子里除了弱智游戏就只有病毒了    
    小白:哦~~那你看到我的“连连看”了吗,不记得装在哪,找了好久了耶    
    黑客:。。。。。再见    

    黑客:嗨~~~我来了!    
    小白:好几天不见你,被我的防火墙挡住啦?    
    黑客:哈哈,笑话,上你的机子比我自己的还容易,不是想我了吧    
    小白:我是想请你帮一个忙    
    黑客:什么事?    
    小白:你能不能进入电力系统修改一点数据    
    黑客:。。。。。。你想干嘛!!    
    小白:求求你,帮我把我家这个月的电费消了吧。。。。。。    
    黑客:去死!!    

    黑客:你死哪去了?!!!    
    小白:。。。。出去玩了几天啊,找我干嘛    
    黑客:我要找点东西    
    小白:在我这儿找什么东西?    
    黑客:病毒,找一条前几年的老病毒,只有你的机子上病毒保存的最全啦    

    黑客:我来了!!    
    。。。。。。    
    黑客:怎么不说话?    
    小白:心情不好    
    黑客:谁欺负你了?    
    小白:我的一个Q号搞丢了,里面有我的网上初恋    
    黑客:这个简单,我帮你拿回来    
    小白:拿不回来了    
    黑客:不可能,告诉我,多少号?    
    小白:呜~~~~就是不记得了    

    小白:你给我出来!!!!    
    黑客:怎么啦?!    
    小白:你是不是用我的ID去论坛玩了?!!    
    黑客:。。。。不好意思,忘了告诉你了,不过,我没干坏事,就瞎编了个贴子,我保证下次再也不玩了    
    小白:那不行!!!    
    黑客:你还要怎么样?    
    小白:你发的贴子得红脸了耶,我第一次得红脸,好开心哦,你必须再给我编一个    
    黑客:倒!    

    黑客:嘿嘿,刚才我做了一件很有趣的事    
    小白:什么事    
    黑客:我到论坛上去顶贴了    
    小白:这很平常啊    
    黑客:我见贴就顶,尽情的骂楼主是猪,好解气    
    小白:哇塞,太过瘾了,我可从来不敢,会被封杀的!    
    黑客:没错,已经被封杀了。    
    小白:这还有趣?!    
    黑客:是啊,因为我用的是你的ID    

    小白:你是高手吗?    
    黑客:可以说是吧。    
    小白:高到什么程度?    
    黑客:嗯,我无聊的时候就自己黑自己    
    小白:哈,这个我也会!    
    黑客:#¥%!你也可以?!    
    小白:是啊,一关机它就黑了。。。。。    
    黑客:滚!  
  • 英语学习网站

    llzkgy_2006 发布于 2007-05-29 10:22:11

     

    国内主要英语学习网站

    沪江英语            http://www.hjenglish.com

    旺旺英语            http://www.wwenglish.com

    普特英语听力        http://www.putclub.com

    BBC中国            http://www.bbc.co.uk/china

    China daily           http://www.chinadaily.com.cn

    Shanghai daily        http://www.shanghaidaily.com

     

    英美主要商业网站

    财富                 http://www.fortune.com

    商业周刊             http://www.businessweek.com

            中文刊       http://www.businessweekchina.com

    哈佛商业评论         http://www.hbr.com

    福布斯                           http://www.forbs.com

    经济学家                       http://www.enconomist.com

    企业家               http://www.entrepreneur.com

    红鲱鱼                      http://www.redherring.com

    金融时报             http://www.ft.com

            中文版       http://www.ftchinese.com

    Stanford商学院       http://www.gsb.stanford.edu

    Harvard商学院       http://www.hbs.edu

    沃顿商学院           http://www.wharton.upenn.edu

    科学美国人           http://www.sciam.com

     

    美国主要杂志

    时代周刊             http://www.time.com

    新闻周刊             http://www.newsweek.com

    时尚                 http://www.style.com/vogue/index.html

    国家地理杂志         http://www.nationalgeographic.com

    人物                 http://people.aol.com/people/index.html

    美国新闻报道         http://www.usnews.com

    读者文摘             http://www.rd.com

    体育画报             http://sportsillustrated.snn.com

    美国周末             http://www.usaweekend.com

    纽约客               http://www.newyorker.com

    纽约书评             http://www.nybooks.com

     

    美国主要报纸

    洛杉矶时报           http://www.latimes.com

    美国新闻             http://www.usnews.com

    华尔街日报评论       http://www.opinionjournal.com

    今日美国             http://www.usatoday.com

    巴尔的摩太阳报       http://www.baltimoresun.com

    华盛顿邮报           http://www.washingtonpost.com

    华尔街日报           http://www.wsj.com

    新闻周刊             http://www.newsweekly.com

    基督教科学箴言报     http://www.csmonitor.com

    先驱日报             http://hjnews.townnews.com

    路透社               http://today.reuters.com/new/home.aspx

    纽约每日新闻         http://www.nydailynews/home.aspx

    远东经济评论         http://www.feer.com

    国际先驱论坛报       http://www.iht.com

    美国快报             http://home.americanexpress.com

    纽约时报             http://www.nytimes.com

    芝加哥论坛报         http://www.chicagotribune.com

    华盛顿新闻报         http://www.newsday.com

    商业日报             http://www.joc.com

    纽约邮报             http://www.nypost.com

    华盛顿每日新闻       http://www.wdnweb.com

     

    美国主要媒体

    全美广播电台         http://www.npr.org

    CNN                 http://www.cnn.org

    ABC                 http://abc.go.com

    Fox                  http://www.fox.com/home.htm

     

  • 从失败中涉取经验 网站设计的十种常见错误

    风在吹 发布于 2006-12-04 14:16:45

    网站是企业面向公众的脸面,本文将介绍10种商业网站设计常见的败笔,从以往的案例和教训中吸取经验可以帮助您避免重蹈覆辙,并可以将您的网站设计得具备实效同时为您的企业带来附加价值。

    在最初设计网站的时候,您有多种选择,机会看上去似乎是无穷无尽的,可以做的事情远远超出想象。尽管构建网站的潜力无限,但是有很多再平常不过的错误会导致网站设计的失败,使您无法实现为企业增加附加价值的目标。

    针对企业网站,我列出了十种常见的设计错误,当然这些问题对于个人网站、业余爱好者和非盈利性机构的网站来讲也是适用的,无论如何请您都要尽力避免这些常见的非常糟糕的错误。

    1.关于我们(About Us):每个网站都应该对此提供非常清晰和直观的信息,包括一段简短的夸大其词的描述,或者在主页上提供“关于我们”页面的突出而明显的链接,并描述您的网站及其所提供的价值。

    有些用户可能并没有发现这个网站对他们有帮助,对此进行解释也是非常重要的,提供足够的信息来说明,这样用户就不会对网站的目的感到迷惑了。您最好提供向访问者说明为什么他或她不会对这个网站感兴趣,这样可以打发走不感兴趣的访客,这比试图欺骗他们直到他们自己花费了大量时间之后才知道网站上并没有他们所须的内容要好很多。毕竟,一个直接表明自己功能的网站要比故弄玄虚而且难以使用的网站更能获得良好的口碑和认同。

    2.Alt和Title属性的文本描述:对于支持这些属性的网站,要确保您在每个XHTML标签上都使用了alt和title属性。如果用户使用的浏览器不支持网站的图片,那么对于可访问性而言这些信息是至关重要的,同时它们还能提供主要内容之外的信息。最常见的功能是为残障人士提供可访问性,比如使用屏幕阅读器访问网站的盲人。但是,也不要在alt或者title属性中写入过多的文字,应当让这些文字简明扼要,清晰易懂。不要让您的用户淹没在大段大段的模糊信息,或是毫无用处的弹出信息中,应当让网站实现最容易访问的状态,因为alt和title标签的基本作用就是提升可访问性。

    3.对URL进行存档管理:将网站上过期的页面放到存档中是网站更新中常见的变化,但对于搜索引擎而言,会造成很大的困难,比如指向您网站中某个页面的链接失效了。因此,在构建网站之初,就要确保转移到存档部分内容的URL不会发生变化。口碑是在国际互联网上营造人气和声望的基石,如果您网站上的页面链接隔不了几天就会发生变化,那么恐怕很难赢得良好的口碑。

    4.在内容上标注日期:通常,您需要经常更新网站才能赢得回头客,人们也只有在新内容出现的时候才会来浏览网站。在内容上标注日期,这样访客才能知道那些是新的,是按照什么顺序出现的。即使在某些罕见的情况下,网站内容可能并不需要经常更新,那么即使有一个页面被重新编辑过,那么也应当反应出改变的信息。

    对网站上所有的信息加上时间戳,可以帮助您的访客确认哪些信息是过期的,即使您只在每个页面的底部加上“最后更新”的字样,也会有所帮助。而且,这不仅仅给网站的访客带来了方便,对您也是有帮助的:如果读者发现您所说和他们在别处看到的不一致是由于信息的更新引起的,那么他们会增加您网站的口碑,并且会成为回头客,愿意经常访问您的网站以获取更多的信息。

    5.内容密度:在一个位置放太多的信息会把访问者吓跑的,虽然常识告诉我们要尽可能多地提供信息,但是物极必反,好东西多了也可能会有副作用。如果提供了太多的信息,读者在阅读时很容易疲劳,然后就开始略读,最后索性不读了。

    尽量保证您的初始信息与主题密切相关,并且简短,可以被读者一次消化,同时可以提供深入信息的链接。使用符号列表是一种非常棒的方法可以将信息分解为不同的部分,从而更容易理解,这样访客也就不会被吓跑。同样的原则对链接列表也是适用的,太多的链接挤在一起和静态的杂乱无章的信息毫无区别。让链接列表短一些,这样读者可以花费很少的力气就能找到他们所需的信息。如果您能帮助他们找到所需的信息,那就会为您的网站增加额外的价值,同时还要尽量保证这些信息容易消化
    6.装饰性图片:除了一些旗帜和表明品牌的图片之外,应当尽可能少使用装饰性的图片。如果对读者有帮助,才使用图片来进行辅助说明;如果这些信息是您希望提供的内容时,才使用这些图片。不要在网站上撒满图片来进行装饰,这样会把访问者吓跑的。因此,只使用有效的图片,而不是装饰性的图片,即使使用装饰图片也不要太多。载入图片往往很慢,这延缓了读者寻找文字的时间,而且很多浏览器中或者使用屏幕阅读器的时候图片是看不到的;而另一方面,文字则是通用的。

    7.间接链接/中转链接/重定向链接:不要阻止其它网站直接链接您的网站内容,有很多大型的内容提供商违反了这一规则,比如新闻网站将其它网站引用的链接重定向,这样访问者往往停留在您的首页。使用这种笨拙的手段似乎认为强迫访问者进入首页就能让他们对其它的内容感兴趣,但实际上,这样做的结果只会让人们扫兴而走。如果寻找某一篇文章遇到了麻烦,您的客户会放弃在您的网站中寻找而跑到其它的地方。更糟糕的情况是,其它网站带来的链接可能会显著地提升您在搜索引擎中的排名,如果让这些重定向的链接失效,那么等于您在反对被人对您的网站进行链接,因此,永远不要拒绝别人对您网站的链接。

    8.最新内容:在第四个问题中,我提到了对网站内容注明日期,从而显示出内容的变化,任何定期更新的网站都应该让这些变化容易被访问者了解,最近更新部分的内容绝不能和三年前的一样,这样就无法体现出丝毫变化。

    新的内容应当保持足够的新鲜度,这样您的读者才能从中获取信息中的价值。如果您的网站更新得非常快(比如Slashdot),那么对这些信息进行分类会有所帮助,比如将新闻分门别类地存放,这样读者就能轻而易举地找到他们感兴趣的话题中最新的内容。有效的搜索功能和优秀的网站管理可以帮助读者查找他们以前曾经看到过的信息,尽可能地帮助他们实现这些功能。

    9.缩略图的尺寸:当提供有大量图片的图库时,使用链接到每张图片的缩略图是一种常见的策略。所谓缩略图就是图片的缩小版本,可以让浏览者看到众多的图片。但是,在展示缩略图时,要切记不能将缩略图做得太小,因为这样网站的访客就无法从中获取有效的信息。

    对图片文件进行按比例的裁减是非常重要的,不要使用XHTML和CSS来变更图片的大小,因为文件的尺寸是不会变化的,发送到客户端浏览器的还是这些大尺寸的版本。在载入布满缩略图的网页时,如果这些缩略图仅仅是被标记语言和样式表改变了尺寸的话,那么浏览器依然会消耗掉大量的处理器时间和系统内存资源;这可能会导致浏览器崩溃和其它的问题,至少会导致漫长的加载时间。网站的访问者会因为缓慢的加载时间转而访问其它的网站,崩溃的浏览器更会吓跑访问者。

    10.网页标题:很多网页设计者并没有为他们的网页设定标题,这明显是个错误,搜索引擎会根据网页的标题来进行识别;而且,用户在浏览器的收藏夹中存储网页地址的时候,默认的名称也是网页的标题。

    一个不太明显的错误是网站的设计者在每个页面上都使用相同的标题,如果为每个页面都提供不同的标题来进行识别,那将会非常有帮助。当然,标题应当是简洁清晰的,冗长的网页标题和没有标题的网站是一样糟糕的。

    以上的这些注意事项对网站设计来讲是非常重要的,但常常没有受到重视或是曲解了其中的要领,也许其它方面的成功可以克服一些细微的失败,但是却永远无法弥补这些缺陷。在设计网站的时候牢记这些原则,可以让您的网站获得更高的成功机会。

  • 正确使用内存(转载)

    zengyi2008 发布于 2007-05-08 09:01:07

    对于初学者来说,内存是个神秘的空间。程序的绝大部分错误,也是在于内存的使用不当造成的,而且这些错误有些都是隐藏很深的。所以,如何掌握内存的使用,通晓系统对内存的管理手段,将是软件成功的一个非常关键的因素。

           首先我们要了解内存的分配方式。一般来说,内存的分配方式有三种:
    1.从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
    2.在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
    3.从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
           以上三种分配方式,我们要注意内存生命期的问题:
    1.静态分配的区域的生命期是整个软件运行期,就是说从软件运行开始到软件终止退出。只有软件终止运行后,这块内存才会被系统回收
    2.在栈中分配的空间的生命期与这个变量所在的函数和类相关。如果是函数中定义的局部变量,那么它的生命期就是函数被调用时,如果函数运行结束,那么这块内存就会被回收。如果是类中的成员变量,则它的生命期与类实例的生命期相同
    3.在堆上分配的内存,生命期是从调用new或者malloc开始,到调用delete或者free结束。如果不掉用delete或者free。则这块空间必须到软件运行结束后才能被系统回收。
    下面我们再看看,在使用内存的过程中,我们经常发生一些什么样的错误。以及我们应该采取哪些对策。
    发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。有时用户怒气冲冲地把你找来,程序却没有发生任何问题,你一走,错误又发作了。
    常见的内存错误及其对策如下:
    1 内存分配未成功,却使用了它。
    编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。
    2 内存分配虽然成功,但是尚未初始化就引用它。
    犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。
    内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。
    3 内存分配成功并且已经初始化,但操作越过了内存的边界。
    例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。
    4 忘记了释放内存,造成内存泄露。
    含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。
    动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。
    5 释放了内存却继续使用它。
    有三种情况:
    1)程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。
    2)函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。
    3)使用free或delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。
    综上所述,我们应该注意:
    1.用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
    2.不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
    3.避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
    4.动态内存的申请与释放必须配对,防止内存泄漏。
    5.用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”
    下面举几个经典的错误例子,大家不要犯同样的错误:
    1. 返回栈内存指针
    char *GetString(void)
    {
    char a[]="hello world";
    char *p =a;
    return p;
    }
    char* pGet = GetString();
    这段程序编译时没有错误,运行也没有错误,但是你却无法使得返回的pGet指针指向的数据是你想要的“hello world”,因为指针p的生命期是函数GetString内,运行完函数GetString后,p分配的栈空间马上被系统回收了。虽然pGet指向了p当初分配的内存地址,但是那块地址已经没有内容了。
    2.这是一个出现频率非常高的错误
    char* pChar = new char;
    ……
    int a ;
    pChar = &a;
    ……
    delete pChar;
    当然这是一个例子,具体的程序各有不同。
    这段程序有两个问题。一是pChar = &a;将导致pChar原先分配的空间无法再被获取,就象我们的丢失了朋友的电话号码一样,无法再联系这个朋友了。这就造成了内存泄漏。如果内存泄漏多了,可能导致系统的崩溃,因为可用的资源将越来越少,直到枯竭为止。第二个问题是delete pChar将导致异常发生,因为这时的pChar已经不是指向动态分配的内存了,而是指向了a分配的栈空间,而栈空间是不能使用delete来回收的,因此将导致内存异常。
  • [转]什么是shell

    Joan2005 发布于 2007-04-30 09:07:12

        操作系统与外部最主要的接口就叫做shell。shell是操作系统最外面的一层。shell管理你与操作系统之间的交互:等待你输入,向操作系统解释你的输入,并且处理各种各样的操作系统的输出结果。
      shell提供了你与操作系统之间通讯的方式。这种通讯可以以交互方式(从键盘输入,并且可以立即得到响应),或者以shell scrīpt(非交互)方式执行。shell scrīpt是放在文件中的一串shell和操作系统命令,它们可以被重复使用。本质上,shell scrīpt是命令行命令简单的组合到一个文件里面。
      Shell基本上是一个命令解释器,类似于DOS下的command.com。它接收用户命令(如ls等),然后调用相应的应用程序。较为通用的shell有标准的Bourne shell (sh)和C shell (csh)。

    交互式shell和非交互式shell
    交互式模式就是shell等待你的输入,并且执行你提交的命令。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当你签退后,shell也终止了。
    shell也可以运行在另外一种模式:非交互式模式。在这种模式下,shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾,shell也就终止了。

    shell的类型
    在UNIX中主要有两大类shell
    Bourne shell (包括 sh, ksh, and bash)
    Bourne shell ( sh)
    Korn shell ( ksh)
    Bourne Again shell ( bash)
    POSIX shell ( sh)
    C shell (包括 csh and tcsh)
    C shell ( csh)
    TENEX/TOPS C shell ( tcsh)

    Bourne Shell
    最初的UNIX shell是由Stephen R. Bourne于20世纪70年代中期在新泽西的AT&T贝尔实验室编写的,这就是Bourne shell。Bourne shell 是一个交换式的命令解释器和命令编程语言。Bourne shell 可以运行为login shell或者login shell的子shell(subshell)。只有login命令可以调用Bourne shell作为一个login shell。此时,shell先读取/etc/profile文件和$HOME/.profile文件。/etc/profile文件为所有的用户定制环境,$HOME/.profile文件为本用户定制环境。最后,shell会等待读取你的输入。

    C Shell
    Bill Joy于20世纪80年代早期,在Berkeley的加利福尼亚大学开发了C shell。它主要是为了让用户更容易的使用交互式功能,并把ALGOL风格的语法结构变成了C语言风格。它新增了命令历史、别名、文件名替换、作业控制等功能。

    Korn Shell
    有很长一段时间,只有两类shell供人们选择,Bourne shell用来编程,C shell用来交互。为了改变这种状况,AT&T的bell实验室David Korn开发了Korn shell。ksh结合了所有的C shell的交互式特性,并融入了Bourne shell的语法。因此,Korn shell广受用户的欢迎。它还新增了数学计算,进程协作(coprocess)、行内编辑(inline editing)等功能。Korn Shell 是一个交互式的命令解释器和命令编程语言.它符合POSIX——一个操作系统的国际标准.POSIX不是一个操作系统,而是一个目标在于应用程序的移植性的标准——在源程序一级跨越多种平台。

    Bourne Again Shell (bash)
    bash是GNU计划的一部分,用来替代Bourne shell。它用于基于GNU的系统如Linux.大多数的Linux(Red Hat, Slackware, Caldera)都以bash作为缺省的shell,并且运行sh时,其实调用的是bash。

    POSIX Shell
    POSIX shell 是Korn shell的一个变种. 当前提供POSIX shell的最大卖主是Hewlett-Packard。在HP-UX 11.0 , POSIX shell 就是/bin/sh,而bsh是/usr/old/bin/sh.

    各主要操作系统下缺省的shell:
    AIX 下是Korn Shell.
    Solaris和FreeBSD缺省的是Bourne shell.
    HP-UX缺省的是POSIX shell.
    Linux是Bourne Again shell.

    【TIP】
    #!/usr/bin/sh的用途
    shell scrīpt的第一行一般都是#!/usr/bin/sh或#!/usr/bin/ksh等,它的用途就是指出本脚本是用的哪种shell写的,执行时系统应该用哪种shell来解释执行它。

    附:LINUX系统的shell原理

      Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言的统称。

      shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。   shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用。用户在提示符下输入的命令都由shell先解释然后传给Linux核心。

      有一些命令,比如改变工作目录命令cd,是包含在shell内部的。还有一些命令,例如拷贝命令cp和移动命令rm,是存在于文件系统中某个目录下的单独的程序。对用户而言,不必关心一个命令是建立在shell内部还是一个单独的程序。

      shell首先检查命令是否是内部命令,若不是再检查是否是一个应用程序(这里的应用程序可以是Linux本身的实用程序,如ls和rm,也可以是购买的商业程序,如xv,或者是自由软件,如emacs)。然后shell在搜索路径里寻找这些应用程序(搜索路径就是一个能找到可执行程序的目录列表)。如果键入的命令不是一个内部命令并且在路径里没有找到这个可执行文件,将会显示一条错误信息。如果能够成功找到命令,该内部命令或应用程序将被分解为系统调用并传给Linux内核。

      shell的另一个重要特性是它自身就是一个解释型的程序设计语言,shell程序设计语言支持绝大多数在高级语言中能见到的程序元素,如函数、变量、数组和程序控制结构。shell编程语言简单易学,任何在提示符中能键入的命令都能放到一个可执行的shell程序中。

      当普通用户成功登录,系统将执行一个称为shell的程序。正是shell进程提供了命令行提示符。作为默认值(TurboLinux系统默认的shell是BASH),对普通用户用“$”作提示符,对超级用户(root)用“#”作提示符。

      一旦出现了shell提示符,就可以键入命令名称及命令所需要的参数。shell将执行这些命令。如果一条命令花费了很长的时间来运行,或者在屏幕上产生了大量的输出,可以从键盘上按ctrl+c发出中断信号来中断它(在正常结束之前,中止它的执行)。

      当用户准备结束登录对话进程时,可以键入logout命令、exit命令或文件结束符(EOF)(按ctrl+d实现),结束登录。

      我们来实习一下shell是如何工作的。

      $ make work

      make:***No rule to make target ‘work’. Stop.

      $

      注释:make是系统中一个命令的名字,后面跟着命令参数。在接收到这个命令后,shell便执行它。本例中,由于输入的命令参数不正确,系统返回信息后停止该命令的执行。

      在例子中,shell会寻找名为make的程序,并以work为参数执行它。make是一个经常被用来编译大程序的程序,它以参数作为目标来进行编译。在“make work”中,make编译的目标是work。因为make找不到以work为名字的目标,它便给出错误信息表示运行失败,用户又回到系统提示符下。

      另外,用户键入有关命令行后,如果shell找不到以其中的命令名为名字的程序,就会给出错误信息。例如,如果用户键入:

      $ myprog

      bash:myprog:command not found

      $

      可以看到,用户得到了一个没有找到该命令的错误信息。用户敲错命令后,系统一般会给出这样的错误信息.
  • Oracle SQL 性能优化技巧

    zengyi2008 发布于 2007-04-28 13:06:46

    选用适合的ORACLE优化器
    ORACLE
    的优化器共有3

    A
    RULE (基于规则) bCOST (基于成本) cCHOOSE (选择性)

       
    设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULECOSTCHOOSEALL_ROWSFIRST_ROWS 你当然也在SQL句级或是会话(session)级对其进行覆盖。

       
    为了使用基于成本的优化器(CBO Cost-Based Optimizer) 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性。

       
    如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的优化器模式将和是否运行过analyze命令有关。 如果table已经被analyze过, 优化器模式将自动成为CBO 反之,数据库将采用RULE形式的优化器。

       
    在缺省情况下,ORACLE采用CHOOSE优化器, 为了避免那些不必要的全表扫描(full table scan) 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器。


    2.
    访问Table的方式
    ORACLE
    采用两种访问表中记录的方式:

    A
    全表扫描

    全表扫描就是顺序地访问表中每条记录。ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描。

    B
    通过ROWID访问表

       
    你可以采用基于ROWID的访问方式情况,提高访问表的效率, ROWID包含了表中记录的物理位置信息。ORACLE采用索引(INDEX)实现了数据和存放数据的物理位置(ROWID)之间的联系。通常索引提供了快速访问ROWID的方法,因此那些基于索引列的查询就可以得到性能上的提高。


    3.
    共享SQL语句
       
    为了不重复解析相同的SQL语句,在第一次解析之后,ORACLESQL语句存放在内存中。这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享。 因此,当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的执行路径。ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用。

       
    可惜的是ORACLE只对简单的表提供高速缓冲(cache buffering),这个功能并不适用于多表连接查询。

       
    数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了。

       
    当你向ORACLE提交一个SQL语句,ORACLE会首先在这块内存中查找相同的语句。这里需要注明的是,ORACLE对两者采取的是一种严格匹配,要达成共享,SQL语句必须完全相同(包括空格,换行等)

       
    数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了。

    共享的语句必须满足三个条件:

    A
    字符级的比较: 当前被执行的语句和共享池中的语句必须完全相同。

    B
    两个语句所指的对象必须完全相同:

    C
    两个SQL语句中必须使用相同的名字的绑定变量(bind variables)


    4.
    选择最有效率的表名顺序(只在基于规则的优化器中有效)
        ORACLE
    的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理。在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。当ORACLE处理多个表时, 会运用排序及合并的方式连接它们。首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并。

       
    如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表。


    5.WHERE
    子句中的连接顺序
        ORACLE
    采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。


    6.SELECT
    子句中避免使用 ' * '
       
    当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 '*' 是一个方便的方法。不幸的是,这是一个非常低效的方法。实际上,ORACLE在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间。


    7.
    减少访问数据库的次数
       
    当执行每条SQL语句时,ORACLE在内部执行了许多工作:解析SQL语句,估算索引的利用率,绑定变量,读数据块等等。由此可见,减少访问数据库的次数,就能实际上减少ORACLE的工作量。


    8.
    使用DECODE函数来减少处理时间
       
    使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。


    9.
    整合简单,无关联的数据库访问
       
    如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)


    10.
    删除重复记录

    11.
    TRUNCATE替代DELETE
       
    当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息。 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况)

       
    而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息。当命令运行后,数据不能被恢复。因此很少的资源被调用,执行时间也会很短。


    12.
    尽量多使用COMMIT
       
    只要有可能,在程序中尽量多使用COMMIT,这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少

    COMMIT
    所释放的资源:

    A
    回滚段上用于恢复数据的信息。

    B
    、被程序语句获得的锁。

    C
    redo log buffer 中的空间。

    D
    ORACLE为管理上述3种资源中的内部花费。


    13.
    计算记录条数
       
    和一般的观点相反,count(*) count(1)稍快,当然如果可以通过索引检索,对索引列的计数仍旧是最快的。例如 COUNT(EMPNO)


    14.
    Where子句替换HAVING子句
       
    避免使用HAVING子句,HAVING 只会在检索出所有记录之后才对结果集进行过滤。 这个处理需要排序,总计等操作。如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销。


    15.
    减少对表的查询
       
    在含有子查询的SQL语句中,要特别注意减少对表的查询。


    16.
    通过内部函数提高SQL效率。

    17.
    使用表的别名(Alias)
       
    当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上。这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。


    18.
    EXISTS替代IN
       
    在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下,使用EXISTS(NOT EXISTS)通常将提高查询的效率。


    19.
    NOT EXISTS替代NOT IN
       
    在子查询中,NOT IN子句将执行一个内部的排序和合并。 无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历)。为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)NOT EXISTS


    20.
    用表连接替换EXISTS
       
    通常来说,采用表连接的方式比EXISTS更有效率


    21.
    EXISTS替换DISTINCT
       
    当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT 一般可以考虑用EXIST替换

  • C#命名规则和开发习惯

    zengyi2008 发布于 2007-04-28 13:18:39

     

    一、命名

     

    1.pascal规则来命名方法和类型.

    public class TextBox

    {

        public void DataBind() 

        {

        }

    }

     

    2.camel规则来命名局部变量和方法的参数.

    string userName;

    public AddUser(string userId, byte[] password);

     

    3.所有的成员变量前加前缀 m_

    public class Database

    {

        public string m_connectionString;

    }

     

    4.接口的名称加前缀 I.

    interface ICompare

    {

        int compare();

    }

     

    5.自定义的属性以Attribute结尾

    public class AuthorAttribute : Attribute

    {

    }

     

    6.自定义的异常以Exception结尾

    public class AppException : Exception

    {

    }

     

    7.方法的命名.一般将其命名为动宾短语.

    ShowDialog()

    CreateFile()

    GetPath()

     

    8.代码的缩进.要用Tab,而不要用space.

     

    9.局部变量的名称要有意义.不要用xyz等等.

    string userName

     

    10.所有的成员变量声明在类的顶端,用一个换行把它和方法分开.

     

    11.用有意义的名字命名namespace,如:产品名、公司名.

     

    12.建议局部变量在最接近使用它时再声明.

     

    13.使用某个控件的值时,尽量命名局部变量.

     

    14.把引用的系统的namespace和自定义或第三方的分开.

     

    15.文件名要能反应类的内容,最好是和类同名,一个文件中一个类.

     

    16.目录结构中要反应出namespace的层次.

     

    17.大括号"{"要新起一行.

    public class AuthorAttribute : Attribute

    {

    }

     

    二、编码习惯.

    1.C#预定义的类名,而不要用别名.

    string userName;   而不是 System.String userName;

    int number;            而不是 System.Int32;

     

    2.一行不要超过80个字符.

     

    3.尽量不要手工更改机器生成的代码,若必须更改,一定要改成和机器生成的代码风格一样.

     

    4.关键的语句(包括声明关键的变量)必须要写注释.

     

    5.文字常量和数字常量不要硬编码,应该用常量类或枚举代替.

     

    6.不要用goto系列语句.

     

    7.不要声明publicprotected的成员变量,应用property.

    8.不要声明publicevent,应用事件访问器.

    public class Source

    {

        private EventHandler m_NumberChangeEvent;

       

        public event EventHandler NumberChangeEvent

        {

            add

            {

                m_NumberChangeEvent += value;

            }

           

            remove

            {

                m_NumberChangeEvent -= value;

            }

        }

    }

     

    9.类型转换的使用规则.

    Animal animal = new Dog();

    Dog dog = animal as Dog;

    if (dog != null)

    {

    }

     

    10.生成和构建一个长的字符串时,一定要使用StringBuilder,而不用string.</P< p>

     

    11.始终使用"{  }"包含if下的语句,即使只有一条语句.

     

    12.switch语句一定要有default来处理意外情况.

     

    13.尽量不要使用三目运算符 ? : ,而要使用if语句.

     

    14.尽量不用使用this引用,除非是要调用类中的另一个Constructor.

    public class Person

    {

        public Person(string name)

        {

        }

       

        public Person() : this("Jim")

        {

        }

    }

     

    .net控件命名规则

    1 、命名方法
    控件名简写+英文描述,英文描述首字母大写
    2
    、主要控件名简写对照表
    控件名                          简写            控件名                        简写

    Label                              lbl             TextBox                            txt

    Button                            btn            LinkButton                      lnkbtn

    ImageButton                imgbtn         DropDownList                  ddl

    ListBox                           lst            DataGrid            &a

  • 转载之报表测试

    zengyi2008 发布于 2007-04-30 09:09:19

     

    本文适合有过MIS系统报表测试经验,或者有关进销存系统测试经验的朋友参考。

    报表功能的基本要求,就是通过查询/统计/分析,提供用户所需的准确的数据。如果无法实现这个基本功能,则报表完全失去意义。

    对于用户来说,报表可以直接影响到他们的决策,例如可能因为报表对销售和库存情况反映的不准确,导致错误的大量进货;或者因为报表对应收应付金额计算的不准确,而导致企业对资金占用情况做出错误的估计,

    从而导致错误的决策,最终造成用户在经营上的损失。诸如此类,相信只要大家留心,还可以找出很多这样的例子。

    进销存系统中的报表多如牛毛,而且各种不同行业的进销存系统中的业务有区别,报表也有些区别,因此不太可能对各种报表逐个讲解,而主要是把一些报表测试的经验总结成了十几条可以在各种行业的报表测试中应用的“最佳实践”,来跟大家一起分享。希望下面的这十几条像一招招简单实用的“擒拿手”,可以供正在进行报表测试或者准备开始作报表测试的朋友随手拈来,见招拆招,轻松应对这项工作

    <!--[if !supportLists]-->(1)       提高对业务的熟悉程度<!--[endif]-->

        其实对任何一个软件进行测试,都必须要熟悉它的业务,包括业务流程和业务规则。但是报表同一般的业务功能还是有些区别的。例如对于单据的增、删、改,通过对界面的浏览和探索性的操作,大概都可以弄明白它的业务流程和业务规则,因为这些内容比较直观,而且在不同的行业中也差不了太多。但是在报表中,是很难直观的看到我们所需要了解的内容的。例如报表中的某个数据项,它的算法或者说数据来源,恐怕是比较难看出来的——即使是很类似的一个数据项,在不同行业的实际业务中,它的算法和数据来源也可以能完全不同的。

    所以对于报表业务的熟悉,主要是两个方面:数据项的算法和数据来源,也就是说要明白一个数据项同具体的业务有什么关系,单据的增、删、改或者状态的变化,对报表中各个数据项的计算会产生什么不同的影响。如果不知道到这些,那么就无法验证报表中的数据是否准确,也无法通过报表去检查业务系统的正确与否。

    <!--[if !supportLists]-->(2)       覆盖所有可能的查询统计方式,而不是以自己的使用习惯为准<!--[endif]-->

        对于报表的使用者来说——一般是企业的中层或高层领导,他们对于报表的要求可能会是多方面的,例如在进销存系统中,可能需要按不同商品进行分类统计,也可能是按供应商分类统计,这些都是由用户在实际工作中的需要来决定的,所以假如一个报表提供了多种查询统计的方法,那么在测试时,只要时间充分,就应该覆盖这些所有可能被用到的查询统计方法,而不是以自己的使用习惯为测试的依据。

    <!--[if !supportLists]-->(3)       使用或构造受控的数据环境<!--[endif]-->

        数据对于报表测试来说是一个非常非常重要的问题。因为上面说到,报表的基本功能就是通过各种查询统计分析的方法,为用户提供准确的数据,帮助用户做出决策。那么那些用来进行测试的数据从哪里来呢?

        首先,应该保证准备足够多的有效的数据。前面一条也提到了,在实际测试报表时,应当尽可能的覆盖到报表所提供的各种查询统计方法,因此至少应该保证每一种查询统计方法都应该有对应的数据,得到的结果都不会是0,否则等于没有覆盖到这个被测的查询统计算法。当然数据也不是越多越好,能保证全部覆盖,并且刚好够用就可以了,因为数据的准备和生成也是很花时间的。

        其次,要保证数据的可控。数据并不是随意生成的,如果使用通过自动化工具或者通过业务测试时随意的输入的数据来进行报表测试,一般来说是不太可能的。因为如果无法控制数据来源,那么即使知道报表中每个数据项的算法,也无法最终验证报表的查询统计结果是否正确。例如,系统的会有不同类型的单据,每种单据又会有不同的状态,某个报表的统计中,可能会涉及到多种类型和状态的单据,那么在准备数据时,就要充分考虑到这一点,准备各种不同的单据来满足测试的要求。又比如,如果整个系统中只有一个供应商,一个商品,那么测试按供应商分类统计或者按商品分类统计的报表时,意义也就不大了。

        所以如果希望高有效、更高质量的完成报表的测试,那么就要重视并增加对于数据准备工作的关注:用于验证报表功能的数据,一定是专门为报表准备的,并且是经过精心设计,要分析影响数据项算法的各种因素,以及每个因素可能出现的不同变化,这样才有可能覆盖各种查询统计方法;同时,才能保证无论使用哪个数据项的算法进行计算,其结果都是可以预知的——因为数据来源已经被我们控制了。

        特别是对于算法比较复杂,又提供了多种查询统计方式的报表,如果想完整的测试,就需要准备大量的数据。而如果想高效、高质量的完成这项功能,就一定要理解数据准备工作的重要性。

        经过精心设计的数据还有一个好处,就是当在进行业务功能的测试时,不再需要使用一些随意的数据,而是可以通过业务测试的过程,把报表测试所需要的数据输入到系统中。并根据报表对单据类型和状态的需要,进行相应的操作。

        如果留心,你也会发现报表测试同其他业务功能测试的有个区别。业务功能(例如单据的新增、审核等)的测试用例设计,通常需要考虑的是对各种正常的、异常的业务流程和业务规则的组合的遍历或覆盖;而对于报表功能,虽然没有太复杂的业务流程和规则,但是算法更加复杂,同时报表功能本身就是一种对数据的加工处理,因此会更偏重于对于各种数据来源和算法的遍历或覆盖,也就是要准备各种正常的、异常的数据,来验证报表是否取到的该取的数据、没有取不该取的数据,并且最后计算出了正确的结果。

    <!--[if !supportLists]-->(4)       特征性数据的准备<!--[endif]-->

        这又是一个同数据准备有关的问题,也是一个解决实际问题的经验。如果由多人同时对一个系统进行测试,虽然大家各自使用的数据都是经过精心设计的,但是在实际进行报表测试时,还是很难保证其他人的数据不会对自己的测试结果产生影响,最明显的一个问题就是原来自己对结果是可以预知的——因为数据是经过精心设计的,是可控的,但是现在掺杂了别人的数据,就需要花时间去区分这种“假”的错误和真的错误。

    有一个经验是可以借鉴的,就是在初期,团队内对数据的准备达成一直,使数据中的某一项具有特征性,例如分别使用不同的供应商,或者使用不同的商品。最后测试报表时,通过限定选取的数据来源,来保证相互之间尽可能的没有影响。

    <!--[if !supportLists]-->(5)       做好数据环境的备份和维护<!--[endif]-->

    虽然数据是经过精心准备的,但是难免在操作过程中因为误操作导致环境的变化,例如不小心把一张单据变成了另外一种状态,或者某个类型的单据多做了一张。对于这种情况,一个简单的方法就是去维护你的数据文档——一般我们都可以用EXCEL表来保存我们事先准备的数据,可以一个文件保存一个类型的单据,例如采购单、入库单、出库单等等,文件中的每张表用来保存不同状态的单据,例如已经审核过的入库单,没有审核过的入库单,全部入库的入库单和部分入库的入库单,等等。假如你一不小心,把一张本来准备入一半的入库单全入了,那也不要惊慌,去重新调整一下你的数据文档,在相应的类型相应的状态的单据列表中新增一张就行了。

    而如果想减少回归测试的工作量,那么应该考虑在一些关键的“点”上备份测试数据。例如所有的基础单据已经输入完成,但是还都没有开始审核或者出入库,那么可以备份一下,下次再测的时候可以直接在数据库中恢复这部分原始数据。

    <!--[if !supportLists]-->(6)       在业务功能测试通过之后才开始<!--[endif]-->

    这一点相信应该不难理解,如果业务功能本身存在缺陷,导致的数据不准,那么最后进行报表测试也就没有什么意义了。所以,应该在保证各项同报表有关的业务的功能测试通过之后,才开始考虑对报表进行测试。

    <!--[if !supportLists]-->(7)       寻求开发人员的协助<!--[endif]-->

        在报表测试中很常见的一个问题,是需求文档中可能没有定义报表的各个数据项的算法,这时候你需要找开发人员帮忙,向他们了解准确的算法和相应的公式。

    <!--[if !supportLists]-->(8)       多个报表相互对照<!--[endif]-->

    这是一项“高级”的报表测试技能,需要对整个系统中的各种业务的熟悉程度达到一种炉火纯青的地步。除了可以准确的说出各个业务的处理过程对每张报表的影响之外,还能够进行横向的联系,知道不同报表之间存在的关系。例如,一个简单的例子,库存报表中,你可以看到商品的出入库情况,而在销售报表中,你可以看到商品的销售金额和销售成本金额,在应收应付报表中,你又可以看到不同供应商或客商之间的应收应付金额。那么这几张报表之间,是否存在一些关联呢?是否会存在一些可以相互验证的地方呢?这个问题,留给大家来思考 ^_^

    <!--[if !supportLists]-->(9)       着重对那些算法复杂、与业务功能关联较多的报表的测试<!--[endif]-->

        如果只是简单的把某个日期范围内的所有入库情况统计出来,可能不会出错;但是如果还要考虑按照供应商或商品汇总,同时要选取特定的类型或状态的单据,再进行一些响应的计算,恐怕就很难保证开发人员永远不会出错了。这就像业务功能的测试一样,越是复杂的业务,越有可能出错。

    <!--[if !supportLists]-->(10)   留意四舍五入对报表数据的影响<!--[endif]-->

    从这一条开始,后面的内容可以说也是一些在实际测试时要注意的事项。

    这也是一个常见的问题。在一般的进销存系统中,都会存在这种情况,无论小数点后保留几位,总是难以避免明细和汇总之间的差别。原因可能是因为采购和销售的包装不一致,因为拆零引起的,例如10/30*3010;或者由于毛利率、税率等因素导致的不一致。我们曾经试过在保留4位小数的情况下还是无法避免这种情况。

    <!--[if !supportLists]-->(11)   留意进//销时使用不同单位对报表数据的影响<!--[endif]-->

    例如采购时是5箱,每箱有100盒,而销售单位是盒,入库之后,可能会要求按照销售单位来统计,这时要注意开发人员是否会选择了错误的单位,把500盒弄成5盒。

    <!--[if !supportLists]-->(12)   留意业务单据中存在多个日期字段时对报表数据的影响<!--[endif]-->

        一般来说,一张单据上都会有多个日期字段,比如采购单就有采购日期、单据日期、审核日期,而入库单也会有单据日期、入库日期,诸如此类。那么在测试时,一定要留意,开发人员是否按照要求选择了正确的日期,包括日期选取的一致性——是否存在这边取采购日期,那边取审核日期的情况。

    <!--[if !supportLists]-->(13)   留意是否存在遗漏的单据类型<!--[endif]-->

        例如像出入库的报表,入库方向的,除了最主要的采购入库外,可能还会包括退货入库、盘盈入库、报溢入库;出库方向的,除了最常见的销售出库,还会包括盘亏出库、报损出库。那么在具体测试时,一定要准备充分这些相应类型的单据,并且要留意开发人员是否遗漏了相应的单据类型。

    <!--[if !supportLists]-->(14)   留意不同状态的单据对报表数据的影响<!--[endif]-->

    例如采购单,当采购单发出后,供应商会开始送货,可能第一批之送来了一半的商品,那么这时采购单的收货状态是“未完成” ;当供应商把商品送齐了以后,采购数量=收货数量,则采购单的收货状态变为“已完成”。那这时留意,开发人员在采购报表中,是包含所需要的状态的单据,还是只包含了一部分?

    <!--[if !supportLists]-->(15)   留意那些被当做默认规则的因素<!--[endif]-->

    有些规则——例如单据类型或者单据状态——是作为默认规则写死在SQL语句或者数据库的存储过程里面,这些规则不会体现在界面,也不会由用户选择决定。但是这些规则恰恰是最容易被忽略的部分。所以,一定要同开发人员反复确认,保证自己已经了解了同报表各数据项计算有关的各个因素。

    <!--[if !supportLists]-->(16)   保证测试人员可以通过UI 找到自己所需的所有原始数据<!--[endif]-->

    在进行系统测试时,无论是报表,还是一般的业务功能测试,都不要去直接通过SQL语句查询数据库中的内容,而是通过UI来输入,再通过UI体现处理的结果进行验证——因为这是系统测试,不是集成测试,将来用户是决不会去直接查数据库的。因此,如果需要对报表的结果进行验证,应该通过其他的功能模块,去查询业务单据,或者其他报表,根据UI体现的结果,来进行确认。

    <!--[if !supportLists]-->(17)   检查大数据量对报表的影响<!--[endif]-->

        报表测试也会涉及到性能测试,主要是在大数据量查询统计的测试。大数据量一是说原始数据多,二是被操作、计算的数据多,三是某个数据项被是经过多次计算得出的。特别是对于一些算法比较复杂的报表,10万条数据和100万条数据时的响应时间将表现出巨大的差别。

    <!--[if !supportLists]-->(18)   不要遗漏权限控制和访问安全性的测试<!--[endif]-->

    这里说的权限控制不是谁可以访问某个模块,谁不可以访问某个模块,而且数据的计算也没有直接的关系,而是侧重于报表设计的测试。我们都知道不同的报表是设计给不同的人看的,例如出入库报表是给仓库管理人员看的,里面不会包含商品的价格,而只会包含数量;而财务报表中,只会包含采购、销售的金额,而不会包含数量,这样才能保证可以相互对照,不会出现营私舞弊的行为。那么在测试时,应当考虑报表是否泄漏了不该泄漏的信息。当然,这里对业务的熟悉程度就是更高的要求了。

    又如,不同的业务员只能看到同自己有关的业务,但是领导可以看到所有业务员的业务——例如不同的业务员分管不同的客户或者地域,他们之间的销售情况是互相保密的。

    还有一种情况,系统的用户可能会为他的供应商提供一个专门的程序或者Web页面,供其对其供应的商品的销售、库存情况进行查看。那么对于这种情况,一方面是要保证某个供应商只能看到他所供应的商品的销售、库存情况,如果某个商品由多个供应商同时提供,那么其中一个供应商应该只能看到他提供的那部分,而看不到其他供应商提供的同一商品的情况。当然,这种功能一般都是通过外网(internet)来访问的,所以也还要考虑相应的访问安全性测试,以免泄漏重要的商业信息。

Open Toolbar