生活在于有力度和信心,无论怎样的过程都是我们生命中的一个经历,认真对待它们,就是认真对待我们自己的人生!正视它们就是正视我们的生活,不会颓废,不会气馁!充满阳光和美好的气氛永远在你的身边!

发布新日志

  • TCPDUMP简介及测试中的应用

    2008-08-25 11:23:21Top 3 Digest 2

        在传统的网络分析和测试技术中,嗅探器(sniffer)是最常见,也是最重要的技术之一。sniffer工具首先是为网络管理员和网络程序员进行网络分析而设计的。对于网络管理人员来说,使用嗅探器可以随时掌握网络的实际情况,在网络性能急剧下降的时候,可以通过sniffer工具来分析原因,找出造成网络阻塞的来源。对于网络程序员来说,通过sniffer工具来调试程序。

    用过windows平台上的sniffer工具(例如,netxray和sniffer pro软件)的朋友可能都知道,在共享式的局域网中,采用sniffer工具简直可以对网络中的所有流量一览无余!Sniffer工具实际上就是一个网络上的抓包工具,同时还可以对抓到的包进行分析。由于在共享式的网络中,信息包是会广播到网络中所有主机的网络接口,只不过在没有使用sniffer工具之前,主机的网络设备会判断该信息包是否应该接收,这样它就会抛弃不应该接收的信息包,sniffer工具却使主机的网络设备接收所有到达的信息包,这样就达到了网络监听的效果。

    Linux作为网络服务器,特别是作为路由器和网关时,数据的采集和分析是必不可少的。所以,今天我们就来看看Linux中强大的网络数据采集分析工具——TcpDump。

    用简单的话来定义tcpdump,就是:dump the traffice on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。

    作为互联网上经典的的系统管理员必备工具,tcpdump以其强大的功能,灵活的截取策略,成为每个高级的系统管理员分析网络,排查问题等所必备的东东之一。

    顾名思义,TcpDump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。

    tcpdump提供了源代码,公开了接口,因此具备很强的可扩展性,对于网络维护和入侵者都是非常有用的工具。tcpdump存在于基本的FreeBSD系统中,由于它需要将网络界面设置为混杂模式,普通用户不能正常执行,但具备root权限的用户可以直接执行它来获取网络上的信息。因此系统中存在网络分析工具主要不是对本机安全的威胁,而是对网络上的其他计算机的安全存在威胁。

    普通情况下,直接启动tcpdump将监视第一个网络界面上所有流过的数据包。
    -----------------------
    bash-2.02# tcpdump
    tcpdump: listening on eth0
    11:58:47.873028 202.102.245.40.netbios-ns > 202.102.245.127.netbios-ns: udp 50
    11:58:47.974331 0:10:7b:8:3a:56 > 1:80:c2:0:0:0 802.1d ui/C len=43
    0000 0000 0080 0000 1007 cf08 0900 0000
    0e80 0000 902b 4695 0980 8701 0014 0002
    000f 0000 902b 4695 0008 00
    11:58:48.373134 0:0:e8:5b:6d:85 > Broadcast sap e0 ui/C len=97
    ffff 0060 0004 ffff ffff ffff ffff ffff
    0452 ffff ffff 0000 e85b 6d85 4008 0002
    0640 4d41 5354 4552 5f57 4542 0000 0000
    0000 00
    ^C
    ------------------------

    首先我们注意一下,从上面的输出结果上可以看出来,基本上tcpdump总的的输出格式为:系统时间 来源主机.端口 > 目标主机.端口 数据包参数

    TcpDump的参数化支持

    tcpdump支持相当多的不同参数,如使用-i参数指定tcpdump监听的网络界面,这在计算机具有多个网络界面时非常有用,使用-c参数指定要监听的数据包数量,使用-w参数指定将监听到的数据包写入文件中保存,等等。

    然而更复杂的tcpdump参数是用于过滤目的,这是因为网络中流量很大,如果不加分辨将所有的数据包都截留下来,数据量太大,反而不容易发现需要的数据包。使用这些参数定义的过滤规则可以截留特定的数据包,以缩小目标,才能更好的分析网络中存在的问题。tcpdump使用参数指定要监视数据包的类型、地址、端口等,根据具体的网络问题,充分利用这些过滤规则就能达到迅速定位故障的目的。请使用man tcpdump查看这些过滤规则的具体用法。

    显然为了安全起见,不用作网络管理用途的计算机上不应该运行这一类的网络分析软件,为了屏蔽它们,可以屏蔽内核中的bpfilter伪设备。一般情况下网络硬件和TCP/IP堆栈不支持接收或发送与本计算机无关的数据包,为了接收这些数据包,就必须使用网卡的混杂模式,并绕过标准的TCP/IP堆栈才行。在FreeBSD下,这就需要内核支持伪设备bpfilter。因此,在内核中取消bpfilter支持,就能屏蔽tcpdump之类的网络分析工具。

    并且当网卡被设置为混杂模式时,系统会在控制台和日志文件中留下记录,提醒管理员留意这台系统是否被用作攻击同网络的其他计算机的跳板。

    May 15 16:27:20 host1 /kernel: fxp0: promiscuous mode enabled

    虽然网络分析工具能将网络中传送的数据记录下来,但是网络中的数据流量相当大,如何对这些数据进行分析、分类统计、发现并报告错误却是更关键的问题。网络中的数据包属于不同的协议,而不同协议数据包的格式也不同。因此对捕获的数据进行解码,将包中的信息尽可能的展示出来,对于协议分析工具来讲更为重要。昂贵的商业分析工具的优势就在于它们能支持很多种类的应用层协议,而不仅仅只支持tcp、udp等低层协议。

    从上面tcpdump的输出可以看出,tcpdump对截获的数据并没有进行彻底解码,数据包内的大部分内容是使用十六进制的形式直接打印输出的。显然这不利于分析网络故障,通常的解决办法是先使用带-w参数的tcpdump 截获数据并保存到文件中,然后再使用其他程序进行解码分析。当然也应该定义过滤规则,以避免捕获的数据包填满整个硬盘。

    TCP功能

    数据过滤

    不带任何参数的TcpDump将搜索系统中所有的网络接口,并显示它截获的所有数据,这些数据对我们不一定全都需要,而且数据太多不利于分析。所以,我们应当先想好需要哪些数据,TcpDump提供以下参数供我们选择数据:

    -b 在数据-链路层上选择协议,包括ip、arp、rarp、ipx都是这一层的。

    例如:tcpdump -b arp 将只显示网络中的arp即地址转换协议信息。

    -i 选择过滤的网络接口,如果是作为路由器至少有两个网络接口,通过这个选项,就可以只过滤指定的接口上通过的数据。例如:

    tcpdump -i eth0 只显示通过eth0接口上的所有报头。

    src、dst、port、host、net、ether、gateway这几个选项又分别包含src、dst 、port、host、net、ehost等附加选项。他们用来分辨数据包的来源和去向,src host 192.168.0.1指定源主机IP地址是192.168.0.1,dst net 192.168.0.0/24指定目标是网络192.168.0.0。以此类推,host是与其指定主机相关无论它是源还是目的,net是与其指定网络相关的,ether后面跟的不是IP地址而是物理地址,而gateway则用于网关主机。可能有点复杂,看下面例子就知道了:

    tcpdump src host 192.168.0.1 and dst net 192.168.0.0/24

    过滤的是源主机为192.168.0.1与目的网络为192.168.0.0的报头。

    tcpdump ether src 00:50:04:BA:9B and dst……

    过滤源主机物理地址为XXX的报头(为什么ether src后面没有host或者net?物理地址当然不可能有网络喽)。

    Tcpdump src host 192.168.0.1 and dst port not telnet

    过滤源主机192.168.0.1和目的端口不是telnet的报头。

    ip icmp arp rarp 和 tcp、udp、icmp这些选项等都要放到第一个参数的位置,用来过滤数据报的类型。
    例如:

    tcpdump ip src……

    只过滤数据-链路层上的IP报头。

    tcpdump udp and src host 192.168.0.1

    只过滤源主机192.168.0.1的所有udp报头。

    数据显示/输入输出

    TcpDump提供了足够的参数来让我们选择如何处理得到的数据,如下所示:

    -l 可以将数据重定向。

    如tcpdump -l >tcpcap.txt将得到的数据存入tcpcap.txt文件中。

    -n 不进行IP地址到主机名的转换。

    如果不使用这一项,当系统中存在某一主机的主机名时,TcpDump会把IP地址转换为主机名显示,就像这样:eth0 < ntc9.1165> router.domain.net.telnet,使用-n后变成了:eth0 < 192.168.0.9.1165 > 192.168.0.1.telnet。

    -nn 不进行端口名称的转换。

    上面这条信息使用-nn后就变成了:eth0 < ntc9.1165 > router.domain.net.23。

    -N 不打印出默认的域名。

    还是这条信息-N 后就是:eth0 < ntc9.1165 > router.telnet。

    -O 不进行匹配代码的优化。
    -t 不打印UNIX时间戳,也就是不显示时间。
    -tt 打印原始的、未格式化过的时间。
    -v 详细的输出,也就比普通的多了个TTL和服务类型。


    TCPDUMP的安装

    在linux下tcpdump的安装十分简单,一般由两种安装方式。一种是以rpm包的形式来进行安装。另外一种是以源程序的形式安装。
    1. rpm包的形式安装
    #rpm -ivh tcpdump-3_4a5.rpm
    这样tcpdump就顺利地安装到你的linux系统中。怎么样,很简单吧。
    2. 源程序的安装
    #tar xvfz tcpdump-3_4a5.tar.Z
    rpm的包可以使用如下命令安装:
    #rpm -ivh tcpdump-3_4a5.src.rpm
    这样就把tcpdump的源代码解压到/usr/src/redhat/SOURCES目录下.

    第二步 做好编译源程序前的准备活动

    在编译源程序之前,最好已经确定库文件libpcap已经安装完毕,这个库文件是tcpdump软件所需的库文件 。同样,你同时还要有一个标准的c语言编译器。在linux下标准的c 语言编译器一般是gcc。 在tcpdump的源程序目录中。有一个文件是Makefile.in,configure命令就是从Makefile.in文件中自动产生Makefile文件。在Makefile.in文件中,可以根据系统的配置来修改BINDEST 和 MANDEST 这两个宏定义,缺省值是
    BINDEST = @sbindir@
    MANDEST = @mandir@

    第一个宏值表明安装tcpdump的二进制文件的路径名,第二个表明tcpdump的man 帮助页的路径名,你可以修改它们来满足系统的需求。

    第三步 编译源程序

    使用源程序目录中的configure脚本,它从系统中读出各种所需的属性。并且根据Makefile.in文件自动生成Makefile文件,以便编译使用.make 命令则根据Makefile文件中的规则编译tcpdump的源程序。使用make install命令安装编译好的tcpdump的二进制文件。

    总结一下就是:

    # tar xvfz tcpdump-3_4a5.tar.Z
    # vi Makefile.in
    # . /configure
    # make
    # make install

    关于tcpdump更详细的信息,请查看Man tcpdump。

     

    tcpdump在服务器维护方面的使用

    在表达式中一般如下几种类型的关键字:

       第一种是关于类型的关键字,主要包括host,net,port

       例如  host 210.27.48.2, 指明 210.27.48.2是一台主机

       net 202.0.0.0,指明202.0.0.0是一个网络地址

       port 23 指明端口号是23。如果没有指定类型,缺省的类型是host。

       第二种是确定传输方向的关键字,主要包括src,dst,dst or src,dst and src,这些关键字指明了传输的方向。

       举例说明,src 210.27.48.2 ,指明ip包中源地址是 210.27.48.2 , dst net 202.0.0.0 指明目的网络地址是202.0.0.0。

       第三种是协议的关键字,主要包括fddi,ip,arp,rarp,tcp,udp等类型。

       还有三种逻辑运算,取非运算是not,!  ;与运算是and,&& ;或运算是or ,||

       example:

         1. tcpdump port 23 and \( host 192.168.1.101 \) :    过滤主机192.168.1.101(不管src还是dst)且端口为23的包

         2. tcpdump host 192.168.1.1:    截获所有192.168.1.1主机收到的和发出的所有的包

         3. tcpdump ip host 210.27.48.1 and ! 210.27.48.2:    获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包

         4. tcpdump host 210.27.48.1 and \(210.27.48.2 or 210.27.48.3 \):    截获主机210.27.48.1 和主机210.27.48.2或210.27.48.3的通信

         5. 先 tcpdump 一看,信息太多。 想了想我要做的是什么,主要是想看看,局域网中访问internet那些东西,跟那些机器有连接,而且要探测不明链接。从而可以发现是否有木马,病毒一些在作怪! tcpdump dst net not 192.168.123.0/24 不监视跟网内机子的链接,过滤很多信息。迅速进入主题, 不想看发邮件的情况,一般的80网页访问,domain访问,还有要排除网内已有服务器的一些端口。

  • TCL——Tool Command Language 扫盲

    2008-08-20 23:24:57Top 2

    Tcl编程简介(一)

    关键词tcl                                          

      Tcl是一种很通用的脚本语言,它几乎在所有的平台上都可以解释运行,功能强大。是tool command language的缩写,发音为 "tickle”, 实际上包含了两个部分:一个语言和一个库。

      首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一 些互交程序如文本编辑器、调试器和shell。它有一个简单的语法 和很强可扩充性,Tcl可以创建新的过程以增强其内建命令的能力。

      其次,Tcl是一个库包,可以被嵌入应用程序,Tcl的库包含了一个分析器、用于执行内建命令的例程和可以使你扩充(定义新的 过程)的库函数。应用程序可以产生Tcl命令并执行,命令可以由用户产生,也可以从用户接口的一个输入中读取(按钮或菜单等)。 但Tcl库收到命令后将它分解并执行内建的命令,经常会产生递归的调用。

      下面简单介绍以下txl的语法规则:

    解释器

      在Tcl的数据结构中的核心是Tcl_Interp.一个解释器包含了一套命令,一组变量和一些用于描述状态的东西。每一个 Tcl命令是 在特定的Tcl_Interp中运行的,基于Tcl的应用程序可以同时拥有几个Tcl_Interp。Tcl_Interp是一个轻量级的结构,可以快速的新建和删除。

    数据类型

      Tcl只支持一种数据结构:字符串(string)。所有的命令,命令的所有的参数,命令的结果,所有的变量都是字符串。请牢记这一点,所有的东西都是字符串。 这是它比较有特点的方面字符串有三种形式:命令(command), 表达式(expresion)和表(list)。

    Basic Command Syntax 基本语法

      Tcl有类似于shell和lisp的语法,当然也有许多的不同。一 条Tcl的命令串包含了一条或多条命令用换行符或分号来隔开,而每一条命令包含了一个域(field)的集合,域使用空白分开的,第一个域是一个命令的名字,其它的是作为参数来传给它。

      例如:

      set a 22 //相当于C中的 a=22 a是一个变量这条命令分为三个域:1: set 2: a 3: 22 set使用于设置变量的值的命令,a、20 作为参数来传给它,a使它要操作的变量名,22是要付给的a值。

      Tcl的命令名可以是内置的命令也可以是用户建的新命令,如果是用户用户建的新命令应用程序中用函数Tcl_CreateCommand来创建。所有的参数作为字符串来传递,命令自己会按其所需来解释的参数的。命令的名字必须被打全,但 Tcl解释器找不到一同名的命令时会用 unknown命令来代替。

      在很多场合下,unknown 会在库目录中搜寻,找到一个的话,会自动生成一个Tcl命令并调用它。unknown经常完成缩略的命令名的执行。但最好不要使用。

    注释

      和shell很象,第一个字母是"#"的Tcl字符串是注释。

    其他细节规则

      Grouping arguments with double-quotes 用双引号来集群参数,目的在于使用有空白的参数。

      例如:

    set a "this string contains whitespace" 

      如够一个参数一双引号来开始,该参数会一直到下一个双引号才结束。其中可以有换行符和分号。

      Variable substitution with $ 用美元符进行变量替换说白了就是引用该变量。

      如:

    
    set a hello 
    set b $a // b = "hello" 实际上传给set命令的参数 
    //是b,"hello" 
    set c a // b = "a" 
    

      Command substitution with brackets 命令子替换(用方括号)

      例如:

    set a [set b "hello"] 

      实现执行 set b "hello" 并用其结果来替换源命令 中的方括号部分,产生一条新命令

      set a "hello" //"hello" 为 set b "hello" 的返回值

      最终的结果是b="hello" a="hello"

      当命令的一个子域以方括号开始以方括号结束,表示要进行一个命令子替换。并执行该子命令,用其结果来替换原命令中的方括号部分。方括号中的部分都被视为Tcl命令。

      如下一个复杂一点的例子:

    
    set a xyz[set b "abc"].[set c "def"] 
    //return xyzabcdef 
    

      Backslash substitution 转移符替换

      转移符时间不可打印字符或由它数意义的字符插入进来。这一概念与C语言中的一样。

    
     Backspace (0x8). 
    f Form feed (0xc). 
    
     Newline (0xa). 
    
     Carriage-return (0xd). 
     Tab (0x9). 
    v Vertical tab (0xb). 
    { Left brace (`{"). 
    } Right brace (`}"). 
    [ Open bracket (`["). 
    ] Close bracket (`]"). 
    $ Dollar sign (`$"). 
    sp Space (` "): does not terminate argument. 
    ; Semicolon: does not terminate command. 
    " Double-quote. 
    

      Grouping arguments with braces 用花扩括号来集群参数

      用花扩括号来集群参数与用双引号来集群参数的区别在于:用花扩括号来集群参数其中的三种上述的子替换不被执行。而且可以嵌套。

      例如:

    
    set a {xyz a {b c d}}//set收到俩个参数 a "xyz a {b c d}" 
    eval { 
    set a 22 
    set b 33 
    }//eval收到一个参数 "set a 22
    set b 33" 
    

    命令综述

      1.一个命令就是一个字符串(string)。

      2.命令是用换行符或分号来分隔的。

      3.一个命令由许多的域组成。第一个于是命令名,其它的域作为参数来传递。

      4.域通常是有空白(Tab横向制表健 Space空格)来分开的。

      5.双引号可以使一个参数包括换行符或分号。三种子替换仍然发生。

      6.花括号类似于双引号,只是不进行三总体换。

      7.系统只进行一层子替换,机制替换的结果不会再去做子替换。而且子替换可以在任何一个域进行。

      8.如果第一个非控字符是`#", 这一行的所有东西都是注释。

    表达式

      对字符串的一种解释是表达式。几个命令将其参数按表达式处理,如:expr、for 和 if,并调用Tcl表达式处理器(Tcl_ExprLong, Tcl_ExprBoolean等)来处理它们。其中的运算符与C语言的很相似。

    ! 

      逻辑非

    
    * / % + - 
    << >> 
    

      左移 右移 只能用于整数。

    < > <= >= == != 

      逻辑比较

    & ^ | 

      位运算 和 异或 或

    &&'  '
  • 如何写好概要设计

    2008-08-20 14:17:41Top 2

        在需求明确、准备开始编码之前,要做概要设计,而详细设计可能大部分公司没有做,有做的也大部分是和编码同步进行,或者在编码之后。因此,对大部分的公司来说,概要设计文档是唯一的设计文档,对后面的开发、测试、实施、维护工作起到关键性的影响。

      一、问题的提出

      概要设计写什么?概要设计怎么做?

      如何判断设计的模块是完整的?

      为什么说设计阶段过于重视业务流程是个误区?

      以需求分析文档还是以概要设计文档来评估开发工作量、指导开发计划准确?

      结构化好还是面向对象好?

      以上问题的答案请在文章中找。

      二、概要设计的目的

      将软件系统需求转换为未来系统的设计;

      逐步开发强壮的系统构架;

      使设计适合于实施环境,为提高性能而进行设计;

      结构应该被分解为模块和库。

      三、概要设计的任务

       制定规范:代码体系、接口规约、命名规则。这是项目小组今后共同作战的基础,有了开发规范和程序模块之间和项目成员彼此之间的接口规则、方式方法,大家就有了共同的工作语言、共同的工作平台,使整个软件开发工作可以协调有序地进行。

      总体结构设计:

      功能(加工)->模块:每个功能用那些模块实现,保证每个功能都有相应的模块来实现;

      模块层次结构:某个角度的软件框架视图;

      模块间的调用关系:模块间的接口的总体描述;

      模块间的接口:传递的信息及其结构;

      处理方式设计:满足功能和性能的算法

      用户界面设计;

      数据结构设计:

      详细的数据结构:表、索引、文件;

      算法相关逻辑数据结构及其操作;

      上述操作的程序模块说明(在前台?在后台?用视图?用过程?······)

      接口控制表的数据结构和使用规则

      其他性能设计。

      四、概要设计写什么

      结构化软件设计说明书结构(因篇幅有限和过时嫌疑,在此不作过多解释)

      任务:目标、环境、需求、局限;

      总体设计:处理流程、总体结构与模块、功能与模块的关系;

      接口设计:总体说明外部用户、软、硬件接口;内部模块间接口(注:接口≈系统界面)

      数据结构:逻辑结构、物理结构,与程序结构的关系;

      模块设计:每个模块“做什么”、简要说明“怎么做”(输入、输出、处理逻辑、与其它模块的接口,与其它系统或硬件的接口),处在什么逻辑位置、物理位置;

      运行设计:运行模块组合、控制、时间;

      出错设计:出错信息、处错处理;

      其他设计:保密、维护;

      OO软件设计说明书结构

      1 概述

      系统简述、软件设计目标、参考资料、修订版本记录

      这部分论述整个系统的设计目标,明确地说明哪些功能是系统决定实现而哪些时不准备实现的。同时,对于非功能性的需求例如性能、可用性等,亦需提及。需求规格说明书对于这部分的内容来说是很重要的参考,看看其中明确了的功能性以及非功能性的需求。

    这部分必须说清楚设计的全貌如何,务必使读者看后知道将实现的系统有什么特点和功能。在随后的文档部分,将解释设计是怎么来实现这些的。

      2 术语表

      对本文档中所使用的各种术语进行说明。如果一些术语在需求规格说明书中已经说明过了,此处不用再重复,可以指引读者参考需求说明。

      3 用例

      此处要求系统用用例图表述(UML),对每个用例(正常处理的情况)要有中文叙述。

      4 设计概述

      4.1 简述

      这部分要求突出整个设计所采用的方法(是面向对象设计还是结构化设计)、系统的体系结构(例如客户/服务器结构)以及使用到的相应技术和工具(例如OMT、Rose)

      4.2 系统结构设计

      这部分要求提供高层系统结构(顶层系统结构、各子系统结构)的描述,使用方框图来显示主要的组件及组件间的交互。最好是把逻辑结构同物理结构分离,对前者进行描述。别忘了说明图中用到的俗语和符号。

      4.3 系统界面

      各种提供给用户的界面以及外部系统在此处要予以说明。如果在需求规格说明书中已经对用户界面有了叙述,此处不用再重复,可以指引读者参考需求说明。如果系统提供了对其它系统的接口,比如说从其它软件系统导入/导出数据,必须在此说明。

      4.4 约束和假定

      描述系统设计中最主要的约束,这些是由客户强制要求并在需求说明书写明的。说明系统是如何来适应这些约束的。

      另外如果本系统跟其它外部系统交互或者依赖其它外部系统提供一些功能辅助,那么系统可能还受到其它的约束。这种情况下,要求清楚地描述与本系统有交互的软件类型以及这样导致的约束。

      实现的语言和平台也会对系统有约束,同样在此予以说明。

      对于因选择具体的设计实现而导致对系统的约束,简要地描述你的想法思路,经过怎么样的权衡,为什么要采取这样的设计等等。

      5 对象模型

      提供整个系统的对象模型,如果模型过大,按照可行的标准把它划分成小块,例如可以把客户端和服务器端的对象模型分开成两个图表述。在其中应该包含所有的系统对象。这些对象都是从理解需求后得到的。要明确哪些应该、哪些不应该被放进图中。所有对象之间的关联必须被确定并且必须指明联系的基数。聚合和继承关系必须清楚地确定下来。每个图必须附有简单的说明。

      6 对象描述

      在这个部分叙述每个对象的细节,它的属性、它的方法。在这之前必须从逻辑上对对象进行组织。你可能需要用结构图把对象按子系统划分好。

      为每个对象做一个条目。在系统对象模型中简要的描述它的用途、约束(如只能有一个实例),列出它的属性和方法。如果对象是存储在持久的数据容器中,标明它是持久对象,否则说明它是个临时对象(transient object)。

      对每个对象的每个属性详细说明:名字、类型,如果属性不是很直观或者有约束(例如,每个对象的该属性必须有一个唯一的值或者值域是有限正整数等)。

      对每个对象的每个方法详细说明:方法名,返回类型,返回值,参数,用途以及使用的算法的简要说明(如果不是特别简单的话)。如果对变量或者返回值由什么假定的话,Pre-conditions和 Post-conditions必须在此说明。列出它或者被它调用的方法需要访问或者修改的属性。最后,提供可以验证实现方法的测试案例。

      7 动态模型

      这部分的作用是描述系统如何响应各种事件。一般使用顺序图和状态图。

      确定不同的场景(Scenario)是第一步,不需要确定所有可能的场景,但是必须至少要覆盖典型的系统用例。不要自己去想当然地创造场景,通常的策略是描述那些客户可以感受得到的场景。

      7.1 场景(Scenarios)

      对每个场景做一则条目,包括以下内容:

      场景名:给它一个可以望文生义的名字

      场景描述:简要叙述场景是干什么的以及发生的动作的顺序。

      顺序图:描述各种事件及事件发生的相对时间顺序。

      7.2 状态图

      这部分的内容包括系统动态模型重要的部分的状态图。可能你想为每个对象画一个状态图,但事实上会导致太多不期望的细节信息,只需要确定系统中一些重要的对象并为之提供状态图即可。

      8 非功能性需求

      五、概要设计怎么做

      结构化软件设计方法:

      详细阅读需求规格说明书,理解系统建设目标、业务现状、现有系统、客户需求的各功能说明;

      分析数据流图,弄清数据流加工的过程;

      根据数据流图决定数据处理问题的类型(变换型、事务型、其他型);

      通过以上分析,推导出系统的初始结构图;

      对初始结构图进行改进完善:所有的加工都要能对应到相应模块(模块的完整性在于他们完成了需求中的所有加工),消除完全相似或局部相似的重复功能(智者察同),理清模块间的层次、控制关系,减少高扇出结构,随着深度增大扇入,平衡模块大小。

      由对数据字典的修改补充完善,导出逻辑数据结构,导出每种数据结构上的操作,这些操作应当属于某个模块。

      确定系统包含哪些应用服务系统、客户端、数据库管理系统;

      确定每个模块放在哪个应用服务器或客户端的哪个目录、哪个文件(库),或是在数据库内部建立的对象。

      对每个筛选后的模块进行列表说明。

      对逻辑数据结构进行列表说明。

      根据结构化软件设计说明书结构对其他需要说明的问题进行补充说明,形成概要设计说明书。

      OO软件设计方法:

      在OOA基础上设计对象与类:在问题领域分析(业务建模和需求分析)之后,开始建立系统构架。

      第一步是抽取建立领域的概念模型,在UML中表现为建立对象类图、活动图和交互图。对象类就是从对象中经过“察同”找出某组对象之间的共同特征而形成类:

      对象与类的属性:数据结构;

      对象与类的服务操作:操作的实现算法;

      对象与类的各外部联系的实现结构;

      设计策略:充分利用现有的类;

      方法:继承、复用、演化;

      活动图用于定义工作流,主要说明工作流的5W(Do What、Who Do、When Do、Where Do、Why Do)等问题,交互图把人员和业务联系在一起是为了理解交互过程,发现业务工作流中相互交互的各种角色。

      第二步是构建完善系统结构:对系统进行分解,将大系统分解为若干子系统,子系统分解为若干软件组件,并说明子系统之间的静态和动态接口,每个子系统可以由用例模型、分析模型、设计模型、测试模型表示。软件系统结构的两种方式:层次、块状

      层次结构:系统、子系统、模块、组件(同一层之间具有独立性);

      块状结构:相互之间弱耦合

      系统的组成部分:

      问题论域:业务相关类和对象(OOA的重点);

      人机界面:窗口、菜单、按钮、命令等等;

      数据管理:数据管理方法、逻辑物理结构、操作对象类;

      任务管理:任务协调和管理进程;

      第三步是利用“4+1”视图描述系统架构:用例视图及剧本;说明体系结构的设计视图;以模块形式组成包和层包含概要实现模型的实现视图;说明进程与线程及其架构、分配和相互交互关系的过程视图;说明系统在操作平台上的物理节点和其上的任务分配的配置视图。在RUP中还有可选的数据视图。

      第四步是性能优化(速度、资源、内存)、模型清晰化、简单化(简单就是享受)。

      六、概要设计的原则

      总体原则和方法:由粗到细的原则,互相结合的原则,定性分析和定量分析相结合的方法,分解和协调的方法和模型化方法。

      要系统考虑系统的一般性、关联性、整体性和层次性。

      分解协调:目的是为了创造更好的系统。系统分解是指将一个复杂的系统分解为若干个子系统,系统协调一是系统内协调,即根据系统的总结构、总功能、总任务和总目标的要求,使各个子系统之间互相协调配合,在各个子系统局部优化基础上,通过内部平衡的协调控制,实现系统的整体优化;

      屏蔽抽象:从简单的框架开始,隐含细节;

      一致性:统一的规范、统一的标准、统一的文件模式;

      每个模块应当有一个统一命名的容易理解的名字;

      编码:由外向内(界面->核心);

      面向用户:概要设计是对于按钮按下后系统“怎么做”的简要说明;

      模块、组件的充分独立性、封闭性;

      同时考虑静态结构与动态运行;

      每个逻辑对象都应当说明其所处物理对象(非一一对应);

      每个物理对象都有合适的开发人员,并且利于分工与组装。(详细说明见本人另一篇文章:系统构架设计应考虑的因素);

      确立每个构架视图的整体结构:视图的详细组织结构、元素的分组以及这些主要分组之间的接口;

      软件构架与使用的技术平台密切相关,目前常用的平台有J2EE、.NET、CORBA等等,因此具体的软件构架人员应当具备使用这些平台的软件开发经验;

      通过需求功能与设计模块之间的列表对应,检查每个需求功能是否都有相应的模块来实现,保证需求功能的可追溯性和需求实现(模块)的完整性,同时可以检查重复和不必要的模块。

      在需求调研分析过程中对业务处理过程了解的完整性和准确性非常重要。调查了解清楚所有的业务流程才能设计出适合各流程业务节点用户业务特点和习惯的软件,使开发出来的软件更受欢迎。当然在进行软件概要设计时,要尽量排除业务流程的制约,即把流程中的各项业务结点工作作为独立的对象,设计成独立的模块,充分考虑他们与其他各种业务对象模块的接口,在流程之间通过业务对象模块的相互调用实现各种业务,这样,在业务流程发生有限的变化时(每个业务模块本身的业务逻辑没有变的情况下),就能够比较方便地修改系统程序模块间的调用关系而实现新的需求。如果这种调用关系被设计成存储在配置库的数据字典里,则连程序代码都不用修改,只需修改数据字典里的模块调用规则即可。

      七、概要设计的重要输出

      编码规范:信息形式、接口规约、命名规则;

      物理模型:组件图、配置图;

      不同角度的构架视图:用例视图、逻辑视图、进程视图、部署视图、实施视图、数据视图(可选);

      系统总体布局:哪些部分组成、各部分在物理上、逻辑上的相互关系;

      两个不可忽视的输出:

      与需求功能的关系:对于需求中的每一个功能,用哪一层、哪个模块、哪个类、哪个对象来实现(一对多关系);反过来,应当说明将要创建的系统每一层、每个模块、每个对象、每一个类“做什么”,他们是为了帮助实现哪些功能(一对多关系)。(需求的颗粒度在一开始往往是比较粗的,因此根据功能点对于整体项目规模的估计或得到项目WBS其误差范围也是比较大的。更为重要的原因是,需求往往不是编码工作分解的准确依据,因为一个需求的功能点可能对应多个代码模块,而多个需求的功能点也可能只对应一个或少数代码模块,同时还有软件复用等因素要考虑,因此只有在概要设计完成以后才能准确地得到详细设计或编码阶段的二次WBS,并估计较为准确的整体项目规模。)

      逻辑与物理位置:每个对象在逻辑上分别落在哪一层、哪个模块、哪个类;在物理上每个模块、每个对象、每一个类放在哪个应用服务器或客户端的哪个目录、哪个文件(库),或者是建立在数据库管理系统中的什么东东(过程、函数、视图、触发器等等)。

      八、结构化与面向对象方法特点比较

      1. 从概念方面看,结构化软件是功能的集合,通过模块以及模块和模块之间的分层调用关系实现;面向对象软件是事物的集合,通过对象以及对象和对象之间的通讯联系实现;

      2. 从构成方面看,结构化软件=过程+数据,以过程为中心;面向对象软件=(数据+相应操作)的封装,以数据为中心;

      3. 从运行控制方面看,结构化软件采用顺序处理方式,由过程驱动控制;面向对象软件采用交互式、并行处理方式,由消息驱动控制;

      4. 从开发方面看,结构化方法的工作重点是设计;面向对象方法的工作重点是分析;但是,在结构化方法中,分析阶段和设计阶段采用了不相吻合的表达方式,需要把在分析阶段采用的具有网络特征的数据流图转换为设计阶段采用的具有分层特征的结构图,在面向对象方法中则不存在这一问题。

      5. 从应用方面看,相对而言,结构化方法更加适合数据类型比较简单的数值计算和数据统计管理软件的开发;面向对象方法更加适合大型复杂的人机交互式软件和数据统计管理软件的开发;

      参考文献:

      《实用软件工程》第二版,郑人杰、殷人昆、陶永雷等著

      《微软项目:求生法则》Steve McConnell著,余孟学译

      《软件工程:实践者的研究方法》(第5版)Roger S.Pressman著

      《软件构架实践》SEI软件工程译丛,林·巴斯著

      《RUP2000》电子版;

      《UML与系统分析设计》张龙祥著;

      《面向对象的分析与设计》杨正甫著;

  • Tcl编程简介(二)

    2008-08-22 00:21:05Top 1 Digest 1

    列表


      字符串的另一种解释为列表。一个列表是类似于结果的一个字 符串包含了用空白分开的很多域。例如 "Al Sue Anne John" 是 一个有四个元素的例表,在列表中换行父被视为分隔符。例如:


      b c {d e {f g h}} 是一个有三个元素的列表 b 、c 和 {d e {f g h}}。


      Tcl的命令 concat, foreach, lappend, lindex, linsert,list, llength, lrange,lreplace, lsearch, 和 lsort 可以使你对列表操作。


    正则表达式


      Tcl 提供了两个用于正则表达式的命令 regexp 和 regsub。 这里的正则表导师实际上是扩展的正则表达式,与 egrep 相一致。


      支持 ^ $ . + ? > < () | []


    命令结果


      每一条命令有俩个结果:一个退出值和一个字符串。退出值标志着命令是否正确执行,字符串给出附加信息。有效的返回制定议在`tcl.h", 如下:


    TCL_OK


      命令正确执行,字符串给出了命令的返回值。


    TCL_ERROR


      表示有一个错误发生,字符串给出了错误的描述。全局变量 errorInfo 包含了人类可读的错误描述,全局变量errorCode 机器使用的错误信息。


    TCL_RETURN


      表示 return 命令被调用,当前的命令(通常是一个函数)必须立刻返回,字符串包含了返回值。


    TCL_BREAK


      表示break已经被调用,最近的巡环必须立刻返回并跳出。字符串应该是空的。


    TCL_CONTINUE


      表示continue已经被调用,最近的巡环必须立刻返回不跳出。字符串应该是空的。


      Tcl编程者一般需要关心退出值。当Tcl解释器发现错误发生后会立刻停止执行。


    Procedures 函数


      Tcl 允许你通过proc命令来扩充命令(定义新的命令),定义之后可以向其它的内建命令一样使用。


      例如:



    proc pf {str} {
    puts $str
    }
    pf "hello world"
    这里有一个初学者不注意的地方,上述的定义一定要写成那样子。而不能向下面那样写:
    proc pf {str}
    {
    puts $str
    }




      因为proc实际上也只不过是一条命令,是一换行符或分号来结束的,用集群参数来传递函数体。proc的定义如下:



    proc name args tclcommand
    Variables: scalars and arrays



      变量:标量和向量(即数组)


      向量就是数组,而标量是没有下表的变量。


      我们用C来类比:



    int i; // i 是标量
    int j[10]; // j 是向量



      变量不需要定义,使用的时候会自动的被创建。Tcl支持两种


      变量:标量和向量


      举个例子来说明吧,



    set i 100
    set j(0) 10
    set k(1,3) 20



      i是标量,j是向量。


      引用的时候:



    $i
    $j(0)
    $k(1,3)

  • 全面介绍单元测试

    2008-08-20 00:24:23Top 1 Digest 1

    一 单元测试概述
      工厂在组装一台电视机之前,会对每个元件都进行测试,这,就是单元测试。
      其实我们每天都在做单元测试。你写了一个函数,除了极简单的外,总是要执行一下,看看功能是否正常,有时还要想办法输出些数据,如弹出信息窗口什么的,这,也是单元测试,老纳把这种单元测试称为临时单元测试。只进行了临时单元测试的软件,针对代码的测试很不完整,代码覆盖率要超过70%都很困难,未覆盖的代码可能遗留大量的细小的错误,这些错误还会互相影响,当BUG暴露出来的时候难于调试,大幅度提高后期测试和维护成本,也降低了开发商的竞争力。可以说,进行充分的单元测试,是提高软件质量,降低开发成本的必由之路。
      对于程序员来说,如果养成了对自己写的代码进行单元测试的习惯,不但可以写出高质量的代码,而且还能提高编程水平。
      要进行充分的单元测试,应专门编写测试代码,并与产品代码隔离。老纳认为,比较简单的办法是为产品工程建立对应的测试工程,为每个类建立对应的测试类,为每个函数(很简单的除外)建立测试函数。首先就几个概念谈谈老纳的看法。
      一般认为,在结构化程序时代,单元测试所说的单元是指函数,在当今的面向对象时代,单元测试所说的单元是指类。以老纳的实践来看,以类作为测试单位,复杂度高,可操作性较差,因此仍然主张以函数作为单元测试的测试单位,但可以用一个测试类来组织某个类的所有测试函数。单元测试不应过分强调面向对象,因为局部代码依然是结构化的。单元测试的工作量较大,简单实用高效才是硬道理。
      有一种看法是,只测试类的接口(公有函数),不测试其他函数,从面向对象角度来看,确实有其道理,但是,测试的目的是找错并最终排错,因此,只要是包含错误的可能性较大的函数都要测试,跟函数是否私有没有关系。对于C++来说,可以用一种简单的方法区隔需测试的函数:简单的函数如数据读写函数的实现在头文件中编写(inline函数),所有在源文件编写实现的函数都要进行测试(构造函数和析构函数除外)。
      什么时候测试?单元测试越早越好,早到什么程度?XP开发理论讲究TDD,即测试驱动开发,先编写测试代码,再进行开发。在实际的工作中,可以不必过分强调先什么后什么,重要的是高效和感觉舒适。从老纳的经验来看,先编写产品函数的框架,然后编写测试函数,针对产品函数的功能编写测试用例,然后编写产品函数的代码,每写一个功能点都运行测试,随时补充测试用例。所谓先编写产品函数的框架,是指先编写函数空的实现,有返回值的随便返回一个值,编译通过后再编写测试代码,这时,函数名、参数表、返回类型都应该确定下来了,所编写的测试代码以后需修改的可能性比较小。
      由谁测试?单元测试与其他测试不同,单元测试可看作是编码工作的一部分,应该由程序员完成,也就是说,经过了单元测试的代码才是已完成的代码,提交产品代码时也要同时提交测试代码。测试部门可以作一定程度的审核。
      关于桩代码,老纳认为,单元测试应避免编写桩代码。桩代码就是用来代替某些代码的代码,例如,产品函数或测试函数调用了一个未编写的函数,可以编写桩函数来代替该被调用的函数,桩代码也用于实现测试隔离。采用由底向上的方式进行开发,底层的代码先开发并先测试,可以避免编写桩代码,这样做的好处有:减少了工作量;测试上层函数时,也是对下层函数的间接测试;当下层函数修改时,通过回归测试可以确认修改是否导致上层函数产生错误。

    二 测试代码编写
      多数讲述单元测试的文章都是以Java为例,本文以C++为例,后半部分所介绍的单元测试工具也只介绍C++单元测试工具。下面的示例代码的开发环境是VC6.0。

    产品类:
    class CMyClass
    {
    public:
        int Add(int i, int j);
        CMyClass();
        virtual ~CMyClass();

    private:
        int mAge;      //年龄
        CString mPhase; //年龄阶段,如"少年","青年"
    };

    建立对应的测试类CMyClassTester,为了节约编幅,只列出源文件的代码:
    void CMyClassTester::CaseBegin()
    {
        //pObj是CMyClassTester类的成员变量,是被测试类的对象的指针,
        //为求简单,所有的测试类都可以用pObj命名被测试对象的指针。
        pObj = new CMyClass();
    }

    void CMyClassTester::CaseEnd()
    {
        delete pObj;
    }
    测试类的函数CaseBegin()和CaseEnd()建立和销毁被测试对象,每个测试用例的开头都要调用CaseBegin(),结尾都要调用CaseEnd()。

    接下来,我们建立示例的产品函数:
    int CMyClass::Add(int i, int j)
    {
        return i+j;
    }
    和对应的测试函数:
    void CMyClassTester::Add_int_int()
    {
    }
    把参数表作为函数名的一部分,这样当出现重载的被测试函数时,测试函数不会产生命名冲突。下面添加测试用例:
    void CMyClassTester::Add_int_int()
    {
        //第一个测试用例
        CaseBegin();{              //1
        int i = 0;                //2
        int j = 0;                //3
        int ret = pObj->Add(i, j); //4
        ASSERT(ret == 0);          //5
        }CaseEnd();                //6
    }
    第1和第6行建立和销毁被测试对象,所加的{}是为了让每个测试用例的代码有一个独立的域,以便多个测试用例使用相同的变量名。
    第2和第3行是定义输入数据,第4行是调用被测试函数,这些容易理解,不作进一步解释。第5行是预期输出,它的特点是当实际输出与预期输出不同时自动报错,ASSERT是VC的断言宏,也可以使用其他类似功能的宏,使用测试工具进行单元测试时,可以使用该工具定义的断言宏。

      示例中的格式显得很不简洁,2、3、4、5行可以合写为一行:ASSERT(pObj->Add(0, 0) == 0);但这种不简洁的格式却是老纳极力推荐的,因为它一目了然,易于建立多个测试用例,并且具有很好的适应性,同时,也是极佳的代码文档,总之,老纳建议:输入数据和预期输出要自成一块。
      建立了第一个测试用例后,应编译并运行测试,以排除语法错误,然后,使用拷贝/修改的办法建立其他测试用例。由于各个测试用例之间的差别往往很小,通常只需修改一两个数据,拷贝/修改是建立多个测试用例的最快捷办法。

    三 测试用例
      下面说说测试用例、输入数据及预期输出。输入数据是测试用例的核心,老纳对输入数据的定义是:被测试函数所读取的外部数据及这些数据的初始值。外部数据是对于被测试函数来说的,实际上就是除了局部变量以外的其他数据,老纳把这些数据分为几类:参数、成员变量、全局变量、IO媒体。IO媒体是指文件、数据库或其他储存或传输数据的媒体,例如,被测试函数要从文件或数据库读取数据,那么,文件或数据库中的原始数据也属于输入数据。一个函数无论多复杂,都无非是对这几类数据的读取、计算和写入。预期输出是指:返回值及被测试函数所写入的外部数据的结果值。返回值就不用说了,被测试函数进行了写操作的参数(输出参数)、成员变量、全局变量、IO媒体,它们的预期的结果值都是预期输出。一个测试用例,就是设定输入数据,运行被测试函数,然后判断实际输出是否符合预期。下面举一个与成员变量有关的例子:
    产品函数:
    void CMyClass::Grow(int years)
    {
        mAge += years;

        if(mAge < 10)
            mPhase = "儿童";
        else if(mAge <20)
            mPhase = "少年";
        else if(mAge <45)
            mPhase = "青年";
        else if(mAge <60)
            mPhase = "中年";
        else
            mPhase = "老年";
    }

    测试函数中的一个测试用例:
        CaseBegin();{
        int years = 1;
        pObj->mAge = 8;
        pObj->Grow(years);
        ASSERT( pObj->mAge == 9 );
        ASSERT( pObj->mPhase == "儿童" );
        }CaseEnd();
    在输入数据中对被测试类的成员变量mAge进行赋值,在预期输出中断言成员变量的值。现在可以看到老纳所推荐的格式的好处了吧,这种格式可以适应很复杂的测试。在输入数据部分还可以调用其他成员函数,例如:执行被测试函数前可能需要读取文件中的数据保存到成员变量,或需要连接数据库,老纳把这些操作称为初始化操作。例如,上例中 ASSERT( ...)之前可以加pObj->OpenFile();。为了访问私有成员,可以将测试类定义为产品类的友元类。例如,定义一个宏:
    #define UNIT_TEST(cls) friend class cls##Tester;
    然后在产品类声明中加一行代码:UNIT_TEST(ClassName)。

      下面谈谈测试用例设计。前面已经说了,测试用例的核心是输入数据。预期输出是依据输入数据和程序功能来确定的,也就是说,对于某一程序,输入数据确定了,预期输出也就可以确定了,至于生成/销毁被测试对象和运行测试的语句,是所有测试用例都大同小异的,因此,我们讨论测试用例时,只讨论输入数据。
      前面说过,输入数据包括四类:参数、成员变量、全局变量、IO媒体,这四类数据中,只要所测试的程序需要执行读操作的,就要设定其初始值,其中,前两类比较常用,后两类较少用。显然,把输入数据的所有可能取值都进行测试,是不可能也是无意义的,我们应该用一定的规则选择有代表性的数据作为输入数据,主要有三种:正常输入,边界输入,非法输入,每种输入还可以分类,也就是平常说的等价类法,每类取一个数据作为输入数据,如果测试通过,可以肯定同类的其他输入也是可以通过的。下面举例说明:
      正常输入
      例如字符串的Trim函数,功能是将字符串前后的空格去除,那么正常的输入可以有四类:前面有空格;后面有空格;前后均有空格;前后均无空格。
      边界输入
      上例中空字符串可以看作是边界输入。
      再如一个表示年龄的参数,它的有效范围是0-100,那么边界输入有两个:0和100。
      非法输入
      非法输入是正常取值范围以外的数据,或使代码不能完成正常功能的输入,如上例中表示年龄的参数,小于0或大于100都是非法输入,再如一个进行文件操作的函数,非法输入有这么几类:文件不存在;目录不存在;文件正在被其他程序打开;权限错误。
      如果函数使用了外部数据,则正常输入是肯定会有的,而边界输入和非法输入不是所有函数都有。一般情况下,即使没有设计文档,考虑以上三种输入也可以找出函数的基本功能点。实际上,单元测试与代码编写是“一体两面”的关系,编码时对上述三种输入都是必须考虑的,否则代码的健壮性就会成问题。

    四 白盒覆盖
      上面所说的测试数据都是针对程序的功能来设计的,就是所谓的黑盒测试。单元测试还需要从另一个角度来设计测试数据,即针对程序的逻辑结构来设计测试用例,就是所谓的白盒测试。在老纳看来,如果黑盒测试是足够充分的,那么白盒测试就没有必要,可惜“足够充分”只是一种理想状态,例如:真的是所有功能点都测试了吗?程序的功能点是人为的定义,常常是不全面的;各个输入数据之间,有些组合可能会产生问题,怎样保证这些组合都经过了测试?难于衡量测试的完整性是黑盒测试的主要缺陷,而白盒测试恰恰具有易于衡量测试完整性的优点,两者之间具有极好的互补性,例如:完成功能测试后统计语句覆盖率,如果语句覆盖未完成,很可能是未覆盖的语句所对应的功能点未测试。
      白盒测试针对程序的逻辑结构设计测试用例,用逻辑覆盖率来衡量测试的完整性。逻辑单位主要有:语句、分支、条件、条件值、条件值组合,路径。语句覆盖就是覆盖所有的语句,其他类推。另外还有一种判定条件覆盖,其实是分支覆盖与条件覆盖的组合,在此不作讨论。跟条件有关的覆盖就有三种,解释一下:条件覆盖是指覆盖所有的条件表达式,即所有的条件表达式都至少计算一次,不考虑计算结果;条件值覆盖是指覆盖条件的所有可能取值,即每个条件的取真值和取假值都要至少计算一次;条件值组合覆盖是指覆盖所有条件取值的所有可能组合。老纳做过一些粗浅的研究,发现与条件直接有关的错误主要是逻辑操作符错误,例如:||写成&&,漏了写!什么的,采用分支覆盖与条件覆盖的组合,基本上可以发现这些错误,另一方面,条件值覆盖与条件值组合覆盖往往需要大量的测试用例,因此,在老纳看来,条件值覆盖和条件值组合覆盖的效费比偏低。老纳认为效费比较高且完整性也足够的测试要求是这样的:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖。做过单元测试的朋友恐怕会对老纳提出的测试要求给予一个字的评价:晕!或者两个字的评价:狂晕!因为这似乎是不可能的要求,要达到这种测试完整性,其测试成本是不可想象的,不过,出家人不打逛语,老纳之所以提出这种测试要求,是因为利用一些工具,可以在较低的成本下达到这种测试要求,后面将会作进一步介绍。
      关于白盒测试用例的设计,程序测试领域的书籍一般都有讲述,普通方法是画出程序的逻辑结构图如程序流程图或控制流图,根据逻辑结构图设计测试用例,这些是纯粹的白盒测试,不是老纳想推荐的方式。老纳所推荐的方法是:先完成黑盒测试,然后统计白盒覆盖率,针对未覆盖的逻辑单位设计测试用例覆盖它,例如,先检查是否有语句未覆盖,有的话设计测试用例覆盖它,然后用同样方法完成条件覆盖、分支覆盖和路径覆盖,这样的话,既检验了黑盒测试的完整性,又避免了重复的工作,用较少的时间成本达到非常高的测试完整性。不过,这些工作可不是手工能完成的,必须借助于工具,后面会介绍可以完成这些工作的测试工具。

    五 单元测试工具
      现在开始介绍单元测试工具,老纳只介绍三种,都是用于C++语言的。
      首先是CppUnit,这是C++单元测试工具的鼻祖,免费的开源的单元测试框架。由于已有一众高人写了不少关于CppUnit的很好的文章,老纳就不现丑了,想了解CppUnit的朋友,建议读一下Cpluser 所作的《CppUnit测试框架入门》,网址是:
    http://blog.csdn.net/cpluser/archive/2004/09/21/111522.aspx。该文也提供了CppUnit的下载地址。
      然后介绍C++Test,这是Parasoft公司的产品。[C++Test是一个功能强大的自动化C/C++单元级测试工具,可以自动测试任何C/C++函数、类,自动生成测试用例、测试驱动函数或桩函数,在自动化的环境下极其容易快速的将单元级的测试覆盖率达到100%]。[]内的文字引自
    http://www.superst.com.cn/softwares_testing_c_cpptest.htm,这是华唐公司的网页。老纳想写些介绍C++Test的文字,但发现无法超越华唐公司的网页上的介绍,所以也就省点事了,想了解C++Test的朋友,建议访问该公司的网站。华唐公司代理C++Test,想要购买或索取报价、试用版都可以找他们。老纳帮华唐公司做广告,不知道会不会得点什么好处?
      最后介绍Visual Unit,简称VU,这是国产的单元测试工具,据说申请了多项专利,拥有一批创新的技术,不过老纳只关心是不是有用和好用。[自动生成测试代码 快速建立功能测试用例 程序行为一目了然 极高的测试完整性 高效完成白盒覆盖 快速排错 高效调试 详尽的测试报告]。[]内的文字是VU开发商的网页上摘录的,网址是:
    http://www.unitware.cn。前面所述测试要求:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖,用VU可以轻松实现,还有一点值得一提:使用VU还能提高编码的效率,总体来说,在完成单元测试的同时,编码调试的时间还能大幅度缩短。算了,不想再讲了,老纳显摆理论、介绍经验还是有兴趣的,因为可以满足老纳好为人师的虚荣心,但介绍工具就觉得索然无味了,毕竟工具好不好用,合不合用,要试过才知道,还是自己去开发商的网站看吧,可以下载演示版,还有演示课件。
    这是一篇全面介绍单元测试的经典之作,对理解单元测试和Visual Unit很有帮助,作者老纳,收录时作了少量修改]

    一 单元测试概述
      工厂在组装一台电视机之前,会对每个元件都进行测试,这,就是单元测试。
      其实我们每天都在做单元测试。你写了一个函数,除了极简单的外,总是要执行一下,看看功能是否正常,有时还要想办法输出些数据,如弹出信息窗口什么的,这,也是单元测试,老纳把这种单元测试称为临时单元测试。只进行了临时单元测试的软件,针对代码的测试很不完整,代码覆盖率要超过70%都很困难,未覆盖的代码可能遗留大量的细小的错误,这些错误还会互相影响,当BUG暴露出来的时候难于调试,大幅度提高后期测试和维护成本,也降低了开发商的竞争力。可以说,进行充分的单元测试,是提高软件质量,降低开发成本的必由之路。
      对于程序员来说,如果养成了对自己写的代码进行单元测试的习惯,不但可以写出高质量的代码,而且还能提高编程水平。
      要进行充分的单元测试,应专门编写测试代码,并与产品代码隔离。老纳认为,比较简单的办法是为产品工程建立对应的测试工程,为每个类建立对应的测试类,为每个函数(很简单的除外)建立测试函数。首先就几个概念谈谈老纳的看法。
      一般认为,在结构化程序时代,单元测试所说的单元是指函数,在当今的面向对象时代,单元测试所说的单元是指类。以老纳的实践来看,以类作为测试单位,复杂度高,可操作性较差,因此仍然主张以函数作为单元测试的测试单位,但可以用一个测试类来组织某个类的所有测试函数。单元测试不应过分强调面向对象,因为局部代码依然是结构化的。单元测试的工作量较大,简单实用高效才是硬道理。
      有一种看法是,只测试类的接口(公有函数),不测试其他函数,从面向对象角度来看,确实有其道理,但是,测试的目的是找错并最终排错,因此,只要是包含错误的可能性较大的函数都要测试,跟函数是否私有没有关系。对于C++来说,可以用一种简单的方法区隔需测试的函数:简单的函数如数据读写函数的实现在头文件中编写(inline函数),所有在源文件编写实现的函数都要进行测试(构造函数和析构函数除外)。
      什么时候测试?单元测试越早越好,早到什么程度?XP开发理论讲究TDD,即测试驱动开发,先编写测试代码,再进行开发。在实际的工作中,可以不必过分强调先什么后什么,重要的是高效和感觉舒适。从老纳的经验来看,先编写产品函数的框架,然后编写测试函数,针对产品函数的功能编写测试用例,然后编写产品函数的代码,每写一个功能点都运行测试,随时补充测试用例。所谓先编写产品函数的框架,是指先编写函数空的实现,有返回值的随便返回一个值,编译通过后再编写测试代码,这时,函数名、参数表、返回类型都应该确定下来了,所编写的测试代码以后需修改的可能性比较小。
      由谁测试?单元测试与其他测试不同,单元测试可看作是编码工作的一部分,应该由程序员完成,也就是说,经过了单元测试的代码才是已完成的代码,提交产品代码时也要同时提交测试代码。测试部门可以作一定程度的审核。
      关于桩代码,老纳认为,单元测试应避免编写桩代码。桩代码就是用来代替某些代码的代码,例如,产品函数或测试函数调用了一个未编写的函数,可以编写桩函数来代替该被调用的函数,桩代码也用于实现测试隔离。采用由底向上的方式进行开发,底层的代码先开发并先测试,可以避免编写桩代码,这样做的好处有:减少了工作量;测试上层函数时,也是对下层函数的间接测试;当下层函数修改时,通过回归测试可以确认修改是否导致上层函数产生错误。

    二 测试代码编写
      多数讲述单元测试的文章都是以Java为例,本文以C++为例,后半部分所介绍的单元测试工具也只介绍C++单元测试工具。下面的示例代码的开发环境是VC6.0。

    产品类:
    class CMyClass
    {
    public:
        int Add(int i, int j);
        CMyClass();
        virtual ~CMyClass();

    private:
        int mAge;      //年龄
        CString mPhase; //年龄阶段,如"少年","青年"
    };

    建立对应的测试类CMyClassTester,为了节约编幅,只列出源文件的代码:
    void CMyClassTester::CaseBegin()
    {
        //pObj是CMyClassTester类的成员变量,是被测试类的对象的指针,
        //为求简单,所有的测试类都可以用pObj命名被测试对象的指针。
        pObj = new CMyClass();
    }

    void CMyClassTester::CaseEnd()
    {
        delete pObj;
    }
    测试类的函数CaseBegin()和CaseEnd()建立和销毁被测试对象,每个测试用例的开头都要调用CaseBegin(),结尾都要调用CaseEnd()。

    接下来,我们建立示例的产品函数:
    int CMyClass::Add(int i, int j)
    {
        return i+j;
    }
    和对应的测试函数:
    void CMyClassTester::Add_int_int()
    {
    }
    把参数表作为函数名的一部分,这样当出现重载的被测试函数时,测试函数不会产生命名冲突。下面添加测试用例:
    void CMyClassTester::Add_int_int()
    {
        //第一个测试用例
        CaseBegin();{              //1
        int i = 0;                //2
        int j = 0;                //3
        int ret = pObj->Add(i, j); //4
        ASSERT(ret == 0);          //5
        }CaseEnd();                //6
    }
    第1和第6行建立和销毁被测试对象,所加的{}是为了让每个测试用例的代码有一个独立的域,以便多个测试用例使用相同的变量名。
    第2和第3行是定义输入数据,第4行是调用被测试函数,这些容易理解,不作进一步解释。第5行是预期输出,它的特点是当实际输出与预期输出不同时自动报错,ASSERT是VC的断言宏,也可以使用其他类似功能的宏,使用测试工具进行单元测试时,可以使用该工具定义的断言宏。

      示例中的格式显得很不简洁,2、3、4、5行可以合写为一行:ASSERT(pObj->Add(0, 0) == 0);但这种不简洁的格式却是老纳极力推荐的,因为它一目了然,易于建立多个测试用例,并且具有很好的适应性,同时,也是极佳的代码文档,总之,老纳建议:输入数据和预期输出要自成一块。
      建立了第一个测试用例后,应编译并运行测试,以排除语法错误,然后,使用拷贝/修改的办法建立其他测试用例。由于各个测试用例之间的差别往往很小,通常只需修改一两个数据,拷贝/修改是建立多个测试用例的最快捷办法。

    三 测试用例
      下面说说测试用例、输入数据及预期输出。输入数据是测试用例的核心,老纳对输入数据的定义是:被测试函数所读取的外部数据及这些数据的初始值。外部数据是对于被测试函数来说的,实际上就是除了局部变量以外的其他数据,老纳把这些数据分为几类:参数、成员变量、全局变量、IO媒体。IO媒体是指文件、数据库或其他储存或传输数据的媒体,例如,被测试函数要从文件或数据库读取数据,那么,文件或数据库中的原始数据也属于输入数据。一个函数无论多复杂,都无非是对这几类数据的读取、计算和写入。预期输出是指:返回值及被测试函数所写入的外部数据的结果值。返回值就不用说了,被测试函数进行了写操作的参数(输出参数)、成员变量、全局变量、IO媒体,它们的预期的结果值都是预期输出。一个测试用例,就是设定输入数据,运行被测试函数,然后判断实际输出是否符合预期。下面举一个与成员变量有关的例子:
    产品函数:
    void CMyClass::Grow(int years)
    {
        mAge += years;

        if(mAge < 10)
            mPhase = "儿童";
        else if(mAge <20)
            mPhase = "少年";
        else if(mAge <45)
            mPhase = "青年";
        else if(mAge <60)
            mPhase = "中年";
        else
            mPhase = "老年";
    }

    测试函数中的一个测试用例:
        CaseBegin();{
        int years = 1;
        pObj->mAge = 8;
        pObj->Grow(years);
        ASSERT( pObj->mAge == 9 );
        ASSERT( pObj->mPhase == "儿童" );
        }CaseEnd();
    在输入数据中对被测试类的成员变量mAge进行赋值,在预期输出中断言成员变量的值。现在可以看到老纳所推荐的格式的好处了吧,这种格式可以适应很复杂的测试。在输入数据部分还可以调用其他成员函数,例如:执行被测试函数前可能需要读取文件中的数据保存到成员变量,或需要连接数据库,老纳把这些操作称为初始化操作。例如,上例中 ASSERT( ...)之前可以加pObj->OpenFile();。为了访问私有成员,可以将测试类定义为产品类的友元类。例如,定义一个宏:
    #define UNIT_TEST(cls) friend class cls##Tester;
    然后在产品类声明中加一行代码:UNIT_TEST(ClassName)。

      下面谈谈测试用例设计。前面已经说了,测试用例的核心是输入数据。预期输出是依据输入数据和程序功能来确定的,也就是说,对于某一程序,输入数据确定了,预期输出也就可以确定了,至于生成/销毁被测试对象和运行测试的语句,是所有测试用例都大同小异的,因此,我们讨论测试用例时,只讨论输入数据。
      前面说过,输入数据包括四类:参数、成员变量、全局变量、IO媒体,这四类数据中,只要所测试的程序需要执行读操作的,就要设定其初始值,其中,前两类比较常用,后两类较少用。显然,把输入数据的所有可能取值都进行测试,是不可能也是无意义的,我们应该用一定的规则选择有代表性的数据作为输入数据,主要有三种:正常输入,边界输入,非法输入,每种输入还可以分类,也就是平常说的等价类法,每类取一个数据作为输入数据,如果测试通过,可以肯定同类的其他输入也是可以通过的。下面举例说明:
      正常输入
      例如字符串的Trim函数,功能是将字符串前后的空格去除,那么正常的输入可以有四类:前面有空格;后面有空格;前后均有空格;前后均无空格。
      边界输入
      上例中空字符串可以看作是边界输入。
      再如一个表示年龄的参数,它的有效范围是0-100,那么边界输入有两个:0和100。
      非法输入
      非法输入是正常取值范围以外的数据,或使代码不能完成正常功能的输入,如上例中表示年龄的参数,小于0或大于100都是非法输入,再如一个进行文件操作的函数,非法输入有这么几类:文件不存在;目录不存在;文件正在被其他程序打开;权限错误。
      如果函数使用了外部数据,则正常输入是肯定会有的,而边界输入和非法输入不是所有函数都有。一般情况下,即使没有设计文档,考虑以上三种输入也可以找出函数的基本功能点。实际上,单元测试与代码编写是“一体两面”的关系,编码时对上述三种输入都是必须考虑的,否则代码的健壮性就会成问题。

    四 白盒覆盖
      上面所说的测试数据都是针对程序的功能来设计的,就是所谓的黑盒测试。单元测试还需要从另一个角度来设计测试数据,即针对程序的逻辑结构来设计测试用例,就是所谓的白盒测试。在老纳看来,如果黑盒测试是足够充分的,那么白盒测试就没有必要,可惜“足够充分”只是一种理想状态,例如:真的是所有功能点都测试了吗?程序的功能点是人为的定义,常常是不全面的;各个输入数据之间,有些组合可能会产生问题,怎样保证这些组合都经过了测试?难于衡量测试的完整性是黑盒测试的主要缺陷,而白盒测试恰恰具有易于衡量测试完整性的优点,两者之间具有极好的互补性,例如:完成功能测试后统计语句覆盖率,如果语句覆盖未完成,很可能是未覆盖的语句所对应的功能点未测试。
      白盒测试针对程序的逻辑结构设计测试用例,用逻辑覆盖率来衡量测试的完整性。逻辑单位主要有:语句、分支、条件、条件值、条件值组合,路径。语句覆盖就是覆盖所有的语句,其他类推。另外还有一种判定条件覆盖,其实是分支覆盖与条件覆盖的组合,在此不作讨论。跟条件有关的覆盖就有三种,解释一下:条件覆盖是指覆盖所有的条件表达式,即所有的条件表达式都至少计算一次,不考虑计算结果;条件值覆盖是指覆盖条件的所有可能取值,即每个条件的取真值和取假值都要至少计算一次;条件值组合覆盖是指覆盖所有条件取值的所有可能组合。老纳做过一些粗浅的研究,发现与条件直接有关的错误主要是逻辑操作符错误,例如:||写成&&,漏了写!什么的,采用分支覆盖与条件覆盖的组合,基本上可以发现这些错误,另一方面,条件值覆盖与条件值组合覆盖往往需要大量的测试用例,因此,在老纳看来,条件值覆盖和条件值组合覆盖的效费比偏低。老纳认为效费比较高且完整性也足够的测试要求是这样的:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖。做过单元测试的朋友恐怕会对老纳提出的测试要求给予一个字的评价:晕!或者两个字的评价:狂晕!因为这似乎是不可能的要求,要达到这种测试完整性,其测试成本是不可想象的,不过,出家人不打逛语,老纳之所以提出这种测试要求,是因为利用一些工具,可以在较低的成本下达到这种测试要求,后面将会作进一步介绍。
      关于白盒测试用例的设计,程序测试领域的书籍一般都有讲述,普通方法是画出程序的逻辑结构图如程序流程图或控制流图,根据逻辑结构图设计测试用例,这些是纯粹的白盒测试,不是老纳想推荐的方式。老纳所推荐的方法是:先完成黑盒测试,然后统计白盒覆盖率,针对未覆盖的逻辑单位设计测试用例覆盖它,例如,先检查是否有语句未覆盖,有的话设计测试用例覆盖它,然后用同样方法完成条件覆盖、分支覆盖和路径覆盖,这样的话,既检验了黑盒测试的完整性,又避免了重复的工作,用较少的时间成本达到非常高的测试完整性。不过,这些工作可不是手工能完成的,必须借助于工具,后面会介绍可以完成这些工作的测试工具。

    五 单元测试工具
      现在开始介绍单元测试工具,老纳只介绍三种,都是用于C++语言的。
      首先是CppUnit,这是C++单元测试工具的鼻祖,免费的开源的单元测试框架。由于已有一众高人写了不少关于CppUnit的很好的文章,老纳就不现丑了,想了解CppUnit的朋友,建议读一下Cpluser 所作的《CppUnit测试框架入门》,网址是:
    http://blog.csdn.net/cpluser/archive/2004/09/21/111522.aspx。该文也提供了CppUnit的下载地址。
      然后介绍C++Test,这是Parasoft公司的产品。[C++Test是一个功能强大的自动化C/C++单元级测试工具,可以自动测试任何C/C++函数、类,自动生成测试用例、测试驱动函数或桩函数,在自动化的环境下极其容易快速的将单元级的测试覆盖率达到100%]。[]内的文字引自
    http://www.superst.com.cn/softwares_testing_c_cpptest.htm,这是华唐公司的网页。老纳想写些介绍C++Test的文字,但发现无法超越华唐公司的网页上的介绍,所以也就省点事了,想了解C++Test的朋友,建议访问该公司的网站。华唐公司代理C++Test,想要购买或索取报价、试用版都可以找他们。老纳帮华唐公司做广告,不知道会不会得点什么好处?
      最后介绍Visual Unit,简称VU,这是国产的单元测试工具,据说申请了多项专利,拥有一批创新的技术,不过老纳只关心是不是有用和好用。[自动生成测试代码 快速建立功能测试用例 程序行为一目了然 极高的测试完整性 高效完成白盒覆盖 快速排错 高效调试 详尽的测试报告]。[]内的文字是VU开发商的网页上摘录的,网址是:
    http://www.unitware.cn。前面所述测试要求:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖,用VU可以轻松实现,还有一点值得一提:使用VU还能提高编码的效率,总体来说,在完成单元测试的同时,编码调试的时间还能大幅度缩短。算了,不想再讲了,老纳显摆理论、介绍经验还是有兴趣的,因为可以满足老纳好为人师的虚荣心,但介绍工具就觉得索然无味了,毕竟工具好不好用,合不合用,要试过才知道,还是自己去开发商的网站看吧,可以下载演示版,还有演示课件。
  • LoadRunner

    2008-09-01 17:05:12

    工具介绍
     LoadRunner: LoadRunner是一种预测系统行为和性能的工业标准级负载测试工具。通过模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题。
     10字真言:虚拟的用户,真实的负载
     VuGen: 脚本录制工具
     Controller:场景控制器
     Analysis: 结果分析工具

    经验总结
     1.测试需求及目标
      a.性能测试的第一步工作就是要“明确客户的需求“,这一阶段我称之为命题作文。作文如果跑题了即使长篇大论也无济于事。
      b.这一阶段的参与者包括需求提出人员和测试人员,由于性能测试一般没有需求变更的情况,要求需求人员一定是比较权威。
      c.一般来说,项目级性能测试客户自身会根据系统使用者范围(总用户数或在线用户数),系统使用环境(集中或分布),高峰作业量(并发用户)提出明确的要求,测试人员也可以提出一些供参考的经验值作为预期的目标。
      d.如果系统测试属于产品测试,那么除了经验值目标外还应包含产品比对,这也是很多产品性能测试采用的一般模式。
      e.性能测试的需求的大致分为两种:
       一种是压力需求,要求××场景××并发用户下平均响应时间小于可接受值;
       另一种是负载需求,要求××场景响应时间在××内支持××用户数。
       二种测试的方法略有不同,但都能够通过测试工具简单操作完成切换。


     2.测试设计
      a.测试设计的原则:从简单到复杂
      b.测试设计主要是测试人员根据测试目标准备测试方案和选取案例。
      c.对于项目级测试,在测试需求中一般都会进行相关的说明,大多数情况下是将系统中关键业务处理场景作为性能测试案例,
      d.考虑到减少测试的复杂性,可以对业务场景中的测试案例进行进一步加工,比如实际场景中可能在一次请求中包含多次子操作(既查询,又修改),那么可以将这些操作拆分,这样更有利于分析结果数据,同时可以抛开业务操作功能之外的消耗(比如有些复杂页面包含很多查询结果,可以拆开分别进行测试,或者页面中包含较多的图片或flash也可以剥离出去,当然也可以利用测试工具中功能达到类似效果)


     3.测试环境
      a.测试环境=硬件环境+软件环境
      b.测试环境在整个性能测试中是一个非常重要的工作。因为在测试报告中测试环境是最客观的指标,同时也是整个性能测试结果的基础
      c.测试环境包括网络环境、硬件环境和软件环境。测试的服务器最好在同一个网段,硬软件最好和真实环境一致。说起来简单做起来难,在搭建环境的过程中一定要自己检查,尤其是软件环境涉及操作系统、应用服务器、数据服务器,更要做到完全一致,因为性能测试的数据都是上万级,结果数据往往相差都是毫秒级,一个小小的索引都会导致极大的差异。


     4.脚本录制和测试工具
      a.环境搭建好之后,可以开始录制脚本,录制脚本使用LoadRunner Virtual User Genorator工具,具体使用的方法网上有很多介绍,我的体会还是很容易上手,下面介绍一些经验和体会
      b.事务设置
       由于实际业务可能包括多个子操作,新增、查询、修改、删除。可以考虑使用事务分别进行监控,事务的使用也很简单,loadrunner的菜单栏提供加入事务功能。
      c.参数变量和函数的使用
       在测试中,我们可能需要录入一个随机数据或者一个枚举的顺序数据,比如业务场景中的数据主键可能一个日期+唯一序列码,同时业务场景中主键是由系统程序(java代码)而不是数据库生成,这时候可以使用LoadRunner提供的参数来实现,参数被定义来自一个文件、一个随机数或者是一个顺序枚举,我仅尝试了后两种。(实际操作中定义参数后可以使用函数将参数和日期拼接成主键值)
      d.Loadrunner提供一系列脚本函数,我使用其中的一部分,感觉还是很好用的。包括日志输出、数据转换、页面交互(以Web_***开头的),尤其是在作删除事务的时候,由于需要取得新增数据的主键,可以考虑在新增数据后把主键值保存在页面,loadrunner会在请求的时候从返回数据中得到这个主键值并保存在脚本变量中,删除的时候可以使用这个变量来进行删除工作。使用web_reg_save_param可以达到这个目的,比如web_reg_save_param(”userid”,”LB=ABC”,”RB=EFG”,LAST)就是把返回页面中的正则匹配ABC***EFG中的***保存在userid变量中,”LB”标志数据的左边界,同时”RB”标志数据的右边界,使用时同时要注意,这个函数相当于一个过滤器filter,所以一定要把它放在发出请求的事务前面。如果页面返回的数据比较多可以设置buffer值来增大返回数据的容量。
      e.所有函数的用法都可以在工具提供的帮助文件中找到,个人体会比使用Google要好。
      f.即使是测试本地系统,录制脚本的目标URL不要设置为http://localhost:7073/*.do或者http://127.0.0.1:7073/*.do,而应该使用真实的本地ip。
      g.运行结束后,LoadRunner会弹出一个测试结果窗口,同时运行时的页面还可以通过在LoadRimmer User Generator中切换察看树形视图进行检查。
      h.通过检查数据库可以确认脚本是否按照预期进行了正确的数据操作。
      i.在做关联的时候,应该从数据第一次出现的位置之前做关联,否则就会出现找不到数据的情况


     5.测试计划及测试工具
      a.脚本调试完毕,我们进入正式的测试工作,开始使用LoadRunner的控制台进行详细的测试计划编排和设置
      b.关于如何使用控制台大家可以找到很多参考,我这里仅列出几点体会:
       i  .运行测试之前一定要先进行脚本验证,保证在无并发用户的情况下脚本能正确执行。
       ii .运行测试一般设置测试运行的duration即可,但是为了对测试所执行的数据监控,也可以采取设置运行次数RunLogic来达到目的,比如并发用户10个,每个用户运行10次,那么如果每个用户执行一次插入数据动作,最终应该产生100条数据。
       iii.取消浏览器模拟browser emulation可以阻止测试中页面非测试数据的下载进而让测试结果更干净。
       iv .no thinktime模式服务器压力比较大,如果是稳定性测试可以在事务间加入适当的thinktime,因为稳定性测试并不是压力测试。
       v  .并发用户较大时应该采用逐步增加用户的方式来执行计划(比如每隔15秒增加10个用户),执行计划时间一定要达到足够产生稳定的数据。(通过测试监控观察,可以在测试运行中随时增加新的用户来延长测试时间)


     6.测试结果分析
      a.测试分析是性能测试的最后一关,如果前面的工作没有失误的话,应该是水到渠成,可是大多数情况下我们还是需要对结果进行进一步分析,并调整我们的测试策略(包括环境、案例及脚本)
      b.Loadrunner提供强大的测试分析工具-analysis,可以将测试数据提取出来进行事后分析。
      c.其中最重要的是响应时间response time和吞吐量(hps),顾名思义,响应时间越小越好,吞吐量越高越好。当然资源消耗(CPU,MEMORY)越少越好。但是其实并不完全,对于一个系统来说,也要讲和谐,也既是所有的资源使用应该使用率应该保持一致。如果测试显示应用服务器CPU特别高,数据服务器特别低,那么系统运行肯定不正常,这时候需要检查是否网络正常,数据服务器是否有死锁等。
      d.一般我们可以对测试结果做一点处理让数据更准确,比如设置过滤器去除不稳定数据,可以设置时间段截取稳定运行时间内的数据作为标本数据。
      e.一旦分析完毕,可以将结果导出到网页作为测试报告

    注:本文为转载,希望作者能来认领,呵呵

  • 华为笔试面试题目

    2008-08-20 01:20:04

     1、语音信号数字化过程中,采用的是的量化方法是非均匀量化。

    2、PCM30/32路系统中,每个码的时间间隔是488ns 。

    3、PCM30/32路系统中,TS0用于传送帧同步信号,TS16用于传送话路信令。

    4、PCM30/32路系统中,复帧的重复频率为500HZ,周期为2ms。

    5、程控交换机的硬件可分为话路系统和中央控制系统两部分,整个交换机的控制软件都放在控制系统的存储器中。

    6、一般二氧化硅光纤的零色散波长在1310nm左右,而损耗最小点在1550nm波长左右。

    7、G.652光纤是零色散波长在1310nm的单模光纤。

    8、光缆的基本结构由缆芯、加强元件和护套组成。

    9、常用的光缆结构形式有层绞式光缆、束管式光缆、骨架式光缆和带状式光缆。

    10、在网状网的拓扑结构中,N个节点完全互连需要N(N-1)/2 条传输线路。

    11、在星型网的拓扑结构中,N个节点完全互连需要N-1 条传输线路。

    12、ATM技术是电路交换技术和分组交换技术的结合。

    13、根据98年发布的《自动交换电话(数字)网技术体制》,我国电话网分为三级。

    14、根据新的电话网体制,我国长途电话网分为二级。

    15、当电话网全网为三级时,两端局之间最大的串接电路段数为5段,串接交换中心最多为6个。

    16、新体制中一级长途交换中心(DC1)为省(自治区、直辖市)长途交换中心,其职能主要是汇接所在省(自治区、直辖市)的省际长途来去话务和一级交换中心所在地的长途终端话务。

    17、一级长途交换中心(DC1)之间以基干路由网状相连。

    18、根据话务流量流向,二级长途交换中心(DC2)也可与非从属的一级长途交换中心DC1建立直达电路群。

    19、一级长途交换中心DC1可以具有二级长途交换中心的职能。

    20、本地网路由的选择顺序为:直达路由、迂回路由、最终路由。

    21、数字本地网中,原则上端至端的最大串接电路数不超过3段。

    22、根据CCITT的建议,国内有效号码的长度不超过12位,国际有效号码长度不超过15位。

    23、我国电话网目前采用的编号方式为不等位编号。

    24、No.7信令中,消息传递部分由低到高依次包括信令数据链路、信令链路功能和信令网功能三个功能级。

    25、国内No.7信令网采用由HSTP、LSTP和SP组成的三级信令网。

    26、常见的同步基准信号有2048Kbits/s 和2048KHz。

    27、我国的No.7信令网为三级网络结构。

    28、我国No.7信令网中,第一级HSTP间采用A、B平面连接方式,A、B平面内部各个HSTP网状相连,A和B平面成对的HSTP相连。

    29、每个LSTP通过信令链至少要分别连接至A、B平面内成对的HSTP。

    30、LSTP至A、B平面两个HSTP的信令链路组之间采用负荷分担方式工作

    31、每个SP至少连至两个STP。

    32、SP至两个STP的信令链路应采用负荷分担方式工作。

    33、两个信令点间的话务群足够大时,可设置直达信令链,采用直联方式。

    34、我国信令网分为33个主信令区。

    35、我国国内的信令点编码为24位。

    36、直拨PABX应分配给信令点编码。

    37、信令数据链路的传输速率为2048Kbits/s。

    38、STP设备的基本进网要求规定,独立型STP信令链路数量不小于512条链路。

    39、STP设备的基本进网要求规定,独立型STP信令处理能力不小于80000MSU/s。

    40、STP设备的基本进网要求规定,独立型STP信令链路组数量不小于256。

    41、STP设备的基本进网要求规定,独立型STP路由区不小于1024。

    42、STP设备的基本进网要求规定,综合型STP信令处理能力不小于10000MSU/s ,最大信令链路数量不小于128。

    43、信令路由的选择规则是首先选择正常路由,当正常路由故障不能使用时,再选择替换路由。

    44、高效直达电路群上的话务可溢出到其他电路群上去,低呼损直达电路群上的话务不允许溢出到其他电路群上去。

    45、本地网为网状网结构时,所有端局与长途局间必须设置基干电路群,所有端局间必须设置低呼损直达电路群。

    46、本地网为集中汇接方式时,所有端局与长途局间必须设置基干电路群,所有端局和汇接局之间必须设置低呼损直达电路群。话务量大的两端局之间可设置直达电路(高效或低呼损)。汇接局和长途局之间可设置低呼损直达电路群。

    47、根据交换设备总技术规范书,我国电话用户的话务负荷分为两档:0.05-0.10Erl/用户、0.10-0.15Erl/用户。

    48、根据交换设备总技术规范书,交换设备来话中继话务负荷按0.7Erl/线计算。

    49、在中国1号信令的后向A组信号中,A1:发下一位,A2:由第一位发起,A3:转KB信号,A4:机键拥塞,A5:空号,A6:发KA和主叫用户号码。

    50、我国交换机本地通信的计费方式为:由主叫用户所在的发端本地局负责计费,对PSTN用户采用复式记次方式,对ISDN用户采用详细记录(LAMA)方式。

    51、我国交换机国内长途通信的计费方式为:原则上由发端长途局进行计费,采用详细计费记录(CAMA)方式。

    52、根据交换设备总技术规范书,交换设备用户侧接口有:二线模拟接口Z、数字接口V和U。中继侧接口只使用数字接口A(2048Kbps/s)

    53、根据交换设备总技术规范书的规定,交换机采用主从同步方式。

    54、最基本的光传输系统由电/光变换器(E/O)、光/电变换器(O/E)和光纤组成。

    55、要将交流220V电源转换成稳定的-48V直流电源输出,一般需经过变压、整流、滤波和稳压四个步骤。

    56、同步网中时钟有四种工作状态: 快捕、 跟踪、 保持和自由运行。

    57、信令网是由信令点SP、信令转接点STP以及连接它们的信令链路LINK组成。

    58、ATM采用53字节的定长信元,其中5 字节为信元头,48字节为信息字段。

    59、在PCM传输线上传输的码型是HDB3码,在交换设备内采用的码型是NRZ码。

    60、我国数字移动通信网(GSM)采用3 级结构,分别是TMSC1、TMSC2和MSC。

    61、OSI参考模型中的七层由低到高分别为物理层、数据链路层、网络层、传送层、会话层、表示层和应用层。

    62、TCP/IP中的TCP指传输控制协议,IP是指网际协议,IPX/SPX中的IPX指互联网信息包交换协议,SPX是指顺序信息交换包协议。

    63、通信网的基本结构形式有五种,分别是网型、星型、复合型、环型、总线型。

    64、数字交换网络所用的时分接线器有 时间接线器 和 空间接线器 两种。

    65、我国目前使用的随路信令为中国一号信令系统,具体分为 线路 信令和 记发器 信令。

    66、语音数字化处理在PCM系统的发端需包括采样、量化、编码个基本部分;而在收端包括再生、解码 、滤波三个部分。

    67、数字用户交换机的用户电路具有七种功能,通常简称为“BORSCHT”功能。即馈电、过压保护、振铃、监视、编译码、混合和测试

    68、10BASE2同轴细缆网线采用BNC、每一区段最大传送距离是185米,10BaseT无屏蔽双绞网线采用RJ45接头、每一区段最大传送距离是100米。

    69、No.7信令方式的基本功能结构是由 消息传递部分MTP 和 用户部分UP 组成。其中 用户部分UP 可以是 电话用户 部分、 数据用户DUP 部分或 ISDN用户 部分等。

    70、Erl的计算方法:单位时间内通话时间所占的百分比。 BHCA的计算方法:忙时最大试呼次数。

    71、七号信令电路,国标规定了两种选线方式:大小/小大、主控/非主控,优先使用主控/非主控方式。

    72、DPC为 目的信令点编码 ,OPC为 源信令点编码 ,CIC为 电路识别码,其中CIC的最低5位表示分配给话路的实际时隙号, 其余7位 表示起源点和目的点的PCM系统识别码。

    73、数据通信用户设备按功能可分成 数据终端设备(DTE)和数据电路终接设备 (DCE) 。

    74、TCP协议和IP协议分别是在OSI模型中第四层(传送层)和第三层(网络层)上实现的。

    75、HDLC是高速数据链路控制规程的缩写,HDSL是高比特率数字用户电路的缩写,ADSL是异步数字用户电路的缩写,SDSL是同步数字用户电路的缩写。

    76、电路交换方式分为时分电路交换方式和空分电路交换方式,存储交换方式分为报文交换方式和分组交换方式。

    77、进行时隙交换采用T接线器,T接线器有输入控制和输出控制 两种方式,T接线器由 语音存储器 和控制存储器 两部分组成。

    78、电话网组成部分包括传输线路、交换机 和 用户终端。

    79、在NO.7信号中,IAM表示初始地址信息 ,IAI表示带附加信息的初始地址信息 ,ANC表示应答计费 ,GRQ表示 一般请求信号 ,GSM表示 一般前向建立信号,ACM表示 地址全信息 , 前向拆线信号为 CLF ,释放监护信号为 RLG 。

    80、NO.7信令单元有 消息信令单元 、 链路状态单元和填充单元等三种信号单元。

    81、NO.7信令网的工作方式,根据通话电路和信号链路的关系, 一般可分为 直连工作方式和 准直连工作方式。

    82、接入网有三类主要接口用户网络接口(UNI)、 业务节点接口(SNI) 、Q3管理接口.

    83、TMN提供 性能管理,故障管理,配置管理,帐务管理,安全管理 五个管理功能域.

    84、SDH帧结构分为 段开销SOH,信息净负荷PAYLOAD,管理单元指针AU PTR 和三部分。3个TU-12构成 1个TUG-2, 7个TUG-2构成一个TUG-3,3个TUG-3构成一个VC-4。

    85、 FTTC意思是光纤到路边 、FTTB意思是光纤到楼 、FTTO意思是光纤到办公室、FTTH意思是光纤到户。

    86、有两种基本的ISDN服务类型:基本速率接口BRI和基群速率接口PRI。


    填空题

    我国和欧洲采用的PCM非均匀量化方式实现方法为(A律13折线压扩),共分(128)个量化级,而日本和北美采用的非均匀量化方法是(u律压扩)。
    石英光纤的零色散波长在(1.31)um左右,损耗最小点在(1.55)um左右。
    中国长途No.7信令网采用(三)级结构,第一级为(高级信令转接点HSTP),第二级为(低级信令转接点LSTP),第三级为(信令点SP)。大、中城市的本地网采用(二)级信令网。
    根据我国的信令网组织原则,每个信令链路组中至少应包括(2)条信令链路。
    信令路由可分为正常路由和(迂回路由)
    No.7信令方式中,OPC指(源信令点编码),DPC指(目的信令点编码),CIC指(电路识别码),SLC指(信令链路编码)。
    No.7信令方式的基本功能结构是由(消息传递部分(MTP))和(用户部分( UP))组成的。
    No.7信令方式的信令单元可分为(MSU)、(LSSU)和(FISU)三种。
    No.7信令系统的工作方式有直连工作方式、(准直连工作方式)和(全分离工作方式)三种。数字信令链路的速率为(64)KBPS
    1数字同步网的同步方式可分为(准同步)、主从同步和(相互同步)等三种方式,其中主从同步方式又可分为(主时钟控制同步方式)和(等级时钟同步方式)
    我国国内No.7信令网的信令点编码由(主信令区编码)、(分信令区编码)和(信令点编码)组成。
    光纤按传输总模数可分为(单模光纤)和(多模光纤)
    目前我国的移动通信网(GSM)采用的频段为(900M)Hz和(1800M)Hz。
    我国数字移动通信网(GSM)采用(三)级结构,分别是(TMSC1、TMSC2和MSC)
    数字移动通信系统中,A接口是(MSC)和(BSC)之间的接口,接口速率为(2M)bps,Abits接口是(BSC)和(BTS)间的接口。
    OSI参考模型中的七层由低到高分别为(物理层)、(数据链路层)、(网络层)、(传送层)、(会话层)、(表示层)和(应用层)。
    TCP/IP中的TCP指(传输控制协议),IP是指网际协议,IPX/SPX中的IPX指(互联网信息包交换协议),SPX是指(顺序信息交换包协议)。
    V5.2接口上的每一条2048kbit/s链路上的 TS16 和 TS31 均可用作物理C通路;凡不用作C通路的其它时隙,除 TS0 外,均可作为承载通路。
    综合型STP由于都采用2Mb/s接口,因而综合型STP配备的时钟等级应由该STP在信令网中的等 级决定,HSTP 应采用第二级A类时钟,LSTP 若设在C3级中心时,应采用第二级B类时钟,LSTP 若设在汇接局时,应采用第三级时钟。
    电信建筑防雷接地装置的冲击接地电阻不应大于10W。室外的电缆、金属管道等在进入建筑物之前,应进行接地,室外架空线直接引入室内时在入口处应加避雷器。
    交换机机房内设计要满足 国家二 级防火标准。
    每瓦电能变成热能的换算系数是0.86 。
    交换机是靠定时器来实现监视和话路强迫释放,国标规定摘机久不拨号等待时长:10s ,号间久不拨号等待时长20s ,应答监视长途呼叫90s 。
    国标规定SDH设备应至少配备有 2 个外同步时钟输入接口和 1 个外同步的时钟输出接口,各接口应符合 ITU-T建议 G.703 。
    一个交换设备对一个目标局可选择的最大路由数为 5 个。
    华为公司的用户电缆中芯对编排所采用的五种色码线序为 粉橙绿蓝灰 。
    对于基站的固定天线,在工作频率范围内,无线端口的VSWR应不大于 1.5。
    GSM的空中物理信道是一个频宽200KHZ,时长为0.577ms的物理实体。
    移动用户至公用通信网接口处的净衰耗标称值为4.5dB 14、根据97年我国新的电话交换设备总技术规范书,对开放非ISDN业务的用户线话务量可分两档取定:(0.05-0.1)Erl/线和 (0.1-0.15)Erl/线; 中继线的话务量可按(0.7)Erl/线取定。
    我国目前电信网管系统分为(全国中心)、(省中心)和(本地网中心)三级 。
    在SDH中,STM-1的速率为(155.520M)bps,STM-4的速率为(622.080M)bps,STM-16的速率为(2488.240M)Bps.
    信令在多段路由上的传送方式可分为(端到端)和(逐段转发)两种,No.7信令采用的传送方式是(逐段转发)。
    目前我国电话网的计费方式有(CAMA)、(LAMA)和(PAMA)三种,
    根据C &C08交换机的安装规范要求,机房净高(梁下或风管下)不得小于(3.0)m。
    C&C08交换机第一排机架距墙应不少于(1.2-1.5)m,前后两排机架正面的间距一般应设计为(1.4-1.5)m,最小不得小于(1.2)m;机架侧面与墙的距离不小于(0.8)m,机架背面距墙不应小于(1)M。
    C&C08交换机的直流输入电压范围为(-41V-- -57V)。
    C&C08交换机安装规范要求地板承重应不小于(450Kg)。
    BITS提供的时钟信号可分为两种,一种是(2MHZ)信号,一种是(2Mbit)信号。
    2B+D ISDN数字用户线总的传输速率是(160Kbps),一帧有(20)比特。
    阻抗为50欧姆的同轴细缆网线,单网段最大传输距离限制为(185)m,无屏蔽双绞网线的最大传输距离为(100)M。
    机房内通信设备及其供电设备(正常不带电的金属部分),(进局电缆的保护装置接地端),(以及电缆的金属护套)均应作保护接地。
    大楼顶的微波天线及其支架应与(避雷接地线)就近连通。天馈线的(上端)和进入机房入口处均应就近接地。
    电力室的直流电源接地线必须从(接地总汇集线)上引入。其他机房的直流电源接地线亦可从(分汇集线上)引入。
    机房的直流电源接地垂直引线长度超过(30米)时,从(30米)开始,应每向上隔一层与接地端子连接一次。
    局内射频同轴布线电缆(外导体)和屏蔽电缆的(屏蔽层两端),均应与所连接设备的金属机壳的外表面保持良好的电气接触。
    各类通信设备保护地线的截面积,应根据最大故障电流值确定,一般宜选用(35-95)平方毫米(相互故障电流为25-350A)的(多股)铜线。
    综合通信大楼的接地电阻值不宜大于(1)欧姆。
    电源系统是由(交流供电系统)、(直流供电系统)和相应的(接地系统)组成。(集中供电)、(分散供电)、(混合供电)为3种比较典型的系统组成方式。
    直流供电系统由(整流设备)、(蓄电池组)和(直流配电设备)组成。
    48V直流放电回路全程压降不应大于(3.2)V。
    同步的含义使通信网上的数字设备工作在一个相同的(平均速率)上。发送设备快于接收设备的时钟速率,会产生(漏读)滑动,反之会产生(重读)滑动。
    同步网的同步是数字网中(所有设备时钟)之间的同步。“同步”包括(比特定时)和(帧定时)两层含义。
    同步方式分为(全同步)、(全准同步)、(混合同步)三类。
    同步方法分为(主从同步法)和(互同步法)。
    同步系统定时基准的传递方式有以下三种:(PDH 2048kbit/s专线)、(SDH STM-N 线路信号)、(PDH 2048kbit/s业务电路)。
    同步网络有(2048khz)、(2048kbit/s)、(STM-N)三种接口。
    选择题


    1、通信网的基本结构形式有五种,以下正确的说法是(C)

    A、网型、星型、树型、环型、总线型;
    B、网型、星型、线型、复合型、环型;
    C、网型、星型、复合型、环型、总线型;
    D、网型、环型、线型、复合型、树型。
    2、N个节点完全互联的网型网需要的传输电路数为(D)

    A、N(N-1) B、N
    C、N-1 D、1/2N(N-1)
    3、衡量数字通信系统传输质量的指标是(A)

    A、误码率 B、信噪比 C、噪声功率 D、话音清晰度
    4、以下关于各种类型路由特点的说法,哪些是不正确的(B)

    A、选路顺序是先选直达路由、其次迂回路由、再次基干路由;
    B、高效直达路由的呼损不能超过1%,该路由允许有话务溢出到其它路由;
    C、低呼损直达路由不允许话务量溢出到其它路由;
    D、一个局向可设置多个路由。
    5、消息传递部分为三个功能级,正确的叙述是(D)

    A、第一级为数据链路功能级,第二级是信令网功能级,第三级是信令链路功能级;
    B、第一级为信令链路功能级,第二级是数据链路功能级,第三级是信令网功能级;
    C、第一级为信令网功能级,第二级是数据链路功能级,第三级是信令链路功能级;
    D、第一级为数据链路功能级,第二级是信令链路功能级,第三级是信令网功能级;
    6、以下关于各种类型路由特点的说法,哪些是不正确的(B)

    A、选路顺序是先选直达路由、其次迂回路由、再次基干路由;
    B、高效直达路由的呼损不能超过1%,该路由允许有话务溢出到其它路由;
    C、低呼损直达路由不允许话务量溢出到其它路由;
    D、一个局向可设置多个路由。
    7、分组交换网的网间互联信令规程是(B)

    A、X.21 B、X.25 C、X.28 D、X.75
    8、以下属于可接入N-ISDN的业务终端有:(A、B、C、D、F)

    A、数字电话 B、高速数据传真
    C、384K桌面视像系统 D、会议电视
    E、高清晰度电视 F、计算机通信
    9、下列属于采用虚电路连接的系统是(A、C、D)

    A、分组交换 B、DDN C、帧中继 D、ATM E、SDH
    10、我国对独立型STP设备要求其信令链路数不得小于(C)

    A、128;B、256;C、512;D、1024
    11、我国对独立型STP设备要求其信令链路数不得小于(B)

    A、7000MSU/s;B、10000MSU/s;C、14000MSU/s;D、20000MSU/s
    12、ATM信元的交换方式为(C)

    A、电路交换; B、分组交换; C、电路交换和分组交换的组合;
    D、与电路交换和分组交换方式毫无关系。
    13、GSM的多址方式为(D)

    A、FDMA; B、TDMA; C、CDMA; D、FDMA-TDMA混合技术
    14、GSM系统中,每个载频可包括(A)个信道

    A、8; B、6; C、4; D、2
    15、以下属于被叫控制的特服业务是(B)

    A、110、119、112、180 B、110、119、120、122
    C、110、114、117、168 D、110、119、166、185
    16、 以下哪种技术属于高速计算机网络技术(B、D)

    A、10BASE-T; B、ATM;
    C、EDI(电子数据交换); D、FDDI
    17、下列属于计算机网络协议的有(A、C)

    A、TCP/IP ; B、MAP; C、IPX/SPX; D、V.24
    18、通过使用下列哪种命令可以获得本机的IP地址(B、D)

    A、ping B、winipcfg C、tracert D、ipconfig
    19、以下哪些IP地址可以分配给一台计算机(D)

    A、256.3.2.1; B、197.9.4.0; C、199.100.331.78; D、11.15.33.235
    20、下列属于网络互联设备的有(A、B、D、F)

    A、路由器;B、中继器;C、防火墙;D、网络交换机;
    E、普通HUB ;F、网关
    21、当机房处在相对湿度较低的地区环境时,特别是当相对湿度处在 B 以下时,应采用抗静 电地面,加强抗静电措施 。

    A、10% B、20%

    C 、30% D、40%

    22、我国要求局用程控交换机的系统中断时间为平均每年不超过 B 。

    A、1小时 B、3分钟

    C、24小时 D、一周

    23、我国长途自动电话计费方式一般采用 C 计费方式,对本地ISDN用户采用 A 。

    A、LAMA B、PAMA

    C、CAMA D、BULK

    24、我国常用的用户信号音如拨号音、忙音、回铃音均采用 B

    A、 540HZ B、 450HZ

    C、双频 D、 1980HZ

    25、国标规定SDH设备在光缆线路出现下列情况下应即倒换 B

    A、 链路故障 B、 帧丢失(LOF)

    C、传输出现告警 D、其他

    26、国标规定接入网的维护管理接口应符合 C 接口标准

    A、Z B、DTE/DCE

    C、Q3 D、2B1Q

    27、国标规定用户线间绝缘电阻要大于 C 欧姆,馈电电流应不小于 E MA

    A.5000 B.10000 C.20000

    D.12 E.18 F.20 G.26

    28、国标规定交换机中具备CID功能的用户电路的配置比例暂定为 C 。

    A、5%~10% B、10%~20%

    C、10%~30% D、10%~40%

    29、省信令网管理中心中的信令网管理系统最终应通过 B 传送对LSTP和C3信令链路的管 理信息

    A、PSDN B、数据通信网 C、 信令网 D、 N-ISDN(D通道)

    30、长途自动接续中对信号音的发送地点有统一规定,对于忙音的发送地点为 C 。

    A、长途局 B、本地汇接局

    C 、发端本地局 D、终端本地局

    31、在规定的电源电压和温湿度范围内,450MHZ系统的发射频率误差不得超过 B , 900MHZ系 统的发射频率误差不得超过 C 。

    A、10×10-6 B、5×10-6 C、3×10-6 D、1×10-6

    32、发射机的载频功率小于25W时,任何离散频率的杂散辐射功率不超过 C ,大于25W 时,应低于发射载频功率 B 。

    A、55dB B、70dB C、2.5uW D、5uW

    33、我们移动通信的体制规定,公众移动电话网的移动用户与市话、长话用户通话时,移动通 信网内音频带内的信噪比大于或等于 C dB。

    A、12 B、24 C、29 D、32

    34. 以下哪种技术属于高速计算机网络技术(B、D)

    A、10BASE-T; B、ATM;
    C、EDI(电子数据交换); D、FDDI
    35. 下列属于计算机网络协议的有(A、C)

    A、TCP/IP ; B、MAP; C、IPX/SPX; D、V.24
    36. 防范CIH病毒的主要措施有(A、B)

    A、更改计算机系统时钟 ; B、经常使用有效的杀毒软件清除病毒;
    C、修改磁盘分区; D、修改BIOS设置;
    E、更换硬盘
    37. 下列能提供E1接口的路由器是(D)

    A、CISCO 2501; B、Quidway 2501;
    C、CISCO 2522; D、CISCO 4500
    38. 通过使用下列哪种命令可以获得本机的IP地址(B、D)

    A、ping B、winipcfg C、tracert D、ipconfig
    39. 下列需要重新启动计算机的操作有(A、D、E)

    A、更改计算机名称; B、增加打印机; C、更改显示器属性中的桌面区域;
    D、硬盘分区; E、安装完AUTOCAD R14
    40. 以下属于网络操作系统的是(A、B、D、E、G )

    A、Unix; B、Linux; C、WIN98; D、WINDOWS NT ;
    E、NETWARE 4.11; F、OS/2 ; G、LAN MANGER 4.0
    41. 以下哪些IP地址可以分配给一台计算机(D)

    A、256.3.2.1; B、197.9.4.0; C、199.100.331.78; D、11.15.33.235
    42. AUTOCAD R14中,若增加一种仿宋字体,则字库文件(.ttf形式)应放在(B)

    A、CAD自身的FONTS子目录下;
    B、WINDOWS的FONTS子目录下;
    C、以上两种均可;
    D、硬盘上任意一个子目录下
    43.下列属于网络互联设备的有(A、B、D、F)

    A、路由器;B、中继器;C、防火墙;D、网络交换机;
    E、普通HUB ;F、网关
    44、TELLIN智能网中SAU与SSP之间的连接是(B)

    A、单纯的话路连接

    B、单纯的信令链路连接

    C、既有话路连接,又有信令链路连接

    D、计算机网络连接

    45、TELLIN智能网中SAU与SCP处理机之间的连接是(D)

    A、串口通信连接

    B、并口通信连接

    C、信令链路连接

    D、计算机网络连接

    46、TELLIN智能网中 SMAP与SSP之间(A)

    A、无连接

    B、串口通信连接

    C、信令链路连接

    D、计算机网络连接

    47、以下有关TELLIN智能网的正确描述是:(D)

    A、一套智能网设备中,SMP是可选设备,SCP和SCE是必选设备。

    B、SCE的功能是业务处理和控制,它是智能网的核心设备。

    C、IP和SSP必须分离设置,不能合为一个整体。

    D、SAU是SCP的一个组成部分。


    简答题

    1、根据新国标,简述我国电话网新的等级结构

    我国电话网由五级逐步演变为三级,新的等级结构为:长途两级,一级交换中心DC1和二级交换中心DC2;本地两级,汇接交换中心DTm和终端交换中心DL。


    2、简述适合于特大和大城市的本地网的网路组织

    采用分区双汇接局结构。将本地网划分成若干个汇接区,每个汇接区内设置两个大容量的汇接局,覆盖区内的每个端局;当汇接局均为端/汇合一局(用DTm/DL)时,全网的所有汇接局间为个个相连的网状网;当某一个汇接区内的两个汇接局均为纯汇接局时,这两个汇接局之间不需相连。


    3、简述适合于中等城市的本地网的网路组织

    采用汇接局全覆盖结构。在全网设置2~3汇接局,对全网的端局全覆盖,汇接局一般设置在本地网的中心城市,并且相互之间采用网状网结构。


    4、简述适合于较小本地网的网路组织

    采用一级(无汇接局)网状网结构。


    5、按照新国标规定的电话网等级结构,简述信令网和电话网的对应连接关系。

    HSTP-DC1,LSTP-DC2、DTm、DL,在DC1兼作DC2时,LSTP-DC1。


    6、简述电话接续转接次数和转接段数的限值

    根据新国标规定的长途网与本地网的关系,在全国长途电话通信中,两端局间的最大串接电路段数为5段,串接交换中心数最多为6个。

    7、简述ISDN用户在网路接口处的接入通路的类型(只要求掌握名称及速率)
    ISDN用户网路接口处的‘接入通路’表示接口的信息荷载能力。

    ▲B通路:具有定时的64Kbit/s通路,用于传递广泛的各种用户信息流,不传递ISDN电路交换的信令信息。

    ▲D通路:主要用于传递ISDN电路交换的信令信息,也可以传递遥信信息和分组交换数 据。D通路可以有不同的比特率,

    ▲H通路:H通路有以下几种传输速率:

    H0通路:384Kbit/s

    H11通路:1536 Kbit/s

    H12通路:1920 Kbit/s

    H通路用于传递各种用户信息流,例如高速传真、电视影像、高质量音频或声音节目、高速数据、分组交换信息等,不传递ISDN电路交换的信令信息。

    8、简述ISDN用户-网络接口中“T”“S”“R”接口的含义

    “T”:用户与网络的分界点

    “S”:单个ISDN终端入网的接口

    “R”:提供所有非ISDN标准的终端入网接口


    9、简述ISDN用户-网络接口及终端设备的类型及功能

    NT1:用户传输线路终端装置,等效于物理层。

    NT2:即含物理层功能,又含高层业务功能,一般用于NT1与终端间。

    TE1:ISDN的标准终端

    TE2:非ISDN的标准终端

    TA:使TE2接入ISDN的标准接口

    10、简要绘制SDH传送网分层摸型


    11、TCP/IP分层模型是怎样的,各有什么作用?

    应用层:向用户提供一组常用的应用程序


    传输层:提供应用程序间的通信


    网间网层:负责相邻计算机之间的通信


    网络接口

    硬件 :负责IP 数据报的接收和发送

  • 日志新篇

    2008-08-20 00:16:21

      迷茫的学习了一个半月,总是感觉自己在努力,在努力的奋斗!今晚才发现自己还没没有给自己一个明确的目标,如果如此的下去会成为什么样的呢?估计是什么都会一点什么都不精或者是达不到想去公司的要求!那样最近的学习生活又是一个失败!

       确立自己的目标,软件行业分支太多,我们要给自己一个发展的趋势和学习的目标,有利于我们以后的工作和我从事的行业分支。

       

数据统计

  • 访问量: 7782
  • 日志数: 8
  • 文件数: 1
  • 建立时间: 2008-08-19
  • 更新时间: 2008-11-12

RSS订阅

Open Toolbar