第一章 计算机系统概论
计算机硬件基本组成
CPU
运算器也称算术逻辑单元(ALU),主要功能是在控制器的控制下完成各种算术运算和逻辑运算。
- 累加寄存器AC:通用寄存器,为运算器|算数逻辑单元(ALU)提供一个工作区,用来暂存数据;
- 程序计数器PC:存储下一条要执行指令的地方;
- 地址寄存器AR:用来保存当前CPU所访问的内存单元的地址;
存储器
随机存储器可以按照地址访问存储器的任一单元;
顺序存储器访问时按顺序查找目标地址,访问数据所需时间与数据存储位置相关;
直接存储器按照数据块所在位置访问,介于上述两者之间,磁道寻址随机,磁道内寻址顺序;
相联存储器:按内容访问的存储器,其工作原理就是把数据或数据的某一部分作为关键字,按顺序写入信息,读出时并行的将该关键字与存储器中的每一单元进行比较,找出存储器中所有与关键字相同的数据字,特别适合于信息的检索和更新。
中央处理单元CPU
平均执行周期数(CPI)是指CPU每执行一条指令所需时钟周期数。
CPU执行MOVRI,RO指令,CPU首先要完成的操作是从内存中读取该指令的指令操作码。取该指令的指令操作码,首先要做的就是将程序计数器的内容送到地址寄存器,即PC->AR。
计算机类与鼠标类的关系是聚合关系。
CPU是在一个总线周期结束时响应DMA请求的。
数据表示
原码:原码是最直观的二进制表示法,它直接根据整数的绝对值进行二进制转换,然后最高位(最左边的位)作为符号位,0表示正数,1表示负数。
5:0101 -5:1101
反码:反码是在原码的基础上,对除了符号位以外的所有位进行取反操作(即0变1,1变0),正数的反码与原码相同。
5:0101 -5:1010
补码:补码是在反码的基础上加1得到的。补码是目前计算机中最常用的表示有符号整数的方法,因为它可以方便地实现加法运算(包括减法,因为减法可以看作加上一个负数),正数的补码与原码相同。
5:0101 -5:1011
移码:通过偏移量将数值转换为非负数来表示,最适合表示浮点数阶码。
- 用原码表示带符号的整数0时,有-0和+0之分,其实就是符号位的变化,+0:0000 0000;-0:1000 0000;
因此用反码表示带符号的整数0时,也有-0和+0之分,分别是 +0反码是 0000 0000;-0反码是 1111 1111; - 而0补码是0000 0000;补码没有+0与-0之分
- 一个二进制数N可以表示为更一般的形式 N=2ExF,其中E称为阶码,F称为尾数。
用阶码和尾数表示的数称为浮点数,这种表示数的方法称为浮点表示法;
阶码越长的数,表示的数的范围越大;尾数约长的数,表示的精度越高。 - 浮点数加(减)法操作流程:对阶,求尾数和(差),结果规则化并判溢出,舍入处理,和溢出判别等步骤。
- 定点小数表示中,只有补码能表示 -1
校验码
海明码:通过在数据中添加冗余位(即校验位)来实现错误的检测和纠正,从而提高了数据传输和存储的可靠性。
例:使用海明码对长度为8位的数据进行检错和纠错时,若能纠正一位错,则校验位数至少为? :设校验位的位数为k,数据位的位数为n,海明码能纠正一位错应满足关系**2k>=n+k+1**,n=8,当k=4时,24>=8+4+1,所以校验位至少为4。
:::color4
采用模2运算进行校验码计算的是CRC码(循环冗余校验码)。
编码方式是在n个信息位后拼接k个校验位。
:::
:::color4
奇校验方法,用于判断接收的数据中1的位数是否为奇数;若有奇数个数据位出错,则可以检测出该错误但无法纠正错误。
:::
指令系统
顺序执行方式:执行完一条后再执行下一条;
流水线方式:完整流程(取指令只执行一次)+ (分析+执行)* 剩余指令数
立即寻址:操作数就包含在指令中。在形成指令的机器代码形式时,立即数就跟在指令操作码的后面,去除指令时即可得到操作数。
直接寻址:操作数放在内存单元中,指令中直接给出操作数所在存储单元的地址。
寄存器寻址:操作数存放在某一寄存器中,指令中给出存放操作数的寄存器名。
RISC(精简指令集计算机):采用硬布线逻辑实现
CISC(复杂指令集计算):采用微码实现,与主存直接交互,并由微程序控制。
存储系统
中断方式与DMA方式都可实现外设与CPU之间的并行工作
:::color1
I/O系统有5种不同的工作方式
程序控制方式:分为无条件查询和程序查询方式;
无条件传送方式:I/O端口总是准备好接受逐级的输出数据,或是总是准备好向主机输入数据,而CPU在需要时,随时直接利用I/O指令访问响应的I/O端口,实现与外设的数据交换,优点是软、硬件结构简单,缺点是对时序要求高,只适用于简单的I/O控制。
程序查询方式:也称程序轮询方式,该方式采用用户程序直接控制主机与外部设备之间输入、输出操作。CPU必须不停地循环测试I/O设备的状态端口,当发现设别处于准备好(Ready)状态时,CPU就可以与I/O设别进行数据存取操作。这种方式下的CPU与I/O设备是串行工作的。
中断方式:当I/O设备结束(完成、特殊或异常)时,就会向CPU发出中断请求信号,CPU收到信号就可以采用相应措施。当某个进程要启动某个设备时,CPU就向相应的设备控制器发出一条设备I/O启动指令,然后CPU又返回做原来的工作。CPU与I/O设备可以并行工作,与程序查询方式方式相比,大大提高了CPU的利用率,适合管理键盘等。
中断向量提供中断服务程序入口地址。
**DMA(直接内存存取)**方式:也称直接主存存取方式,其思想是:允许主存储器和I/O设备之间通过“DMA控制器(DMAC)”直接进行批量数据交换,除了在数据传输开始和结束时,整个过程无须CPU的干预。
通道控制方式:在一定的硬件基础上利用软件手段实现对I/O的控制和传送,更多的免去了CPU的接入,使主机和外设并行工作程度更高。
:::
I/O处理机:指专门负责输入/输出的处理机。可以有独立的存储器,运算部件和指令控制部件。
CPU对应的存储类别:寄存器
Cache对应的存储类别:缓存
主存对应的存储类别:DRAM
辅存对应的存储类别:硬盘、光盘等
RAID5实际容量 = (总盘块数-1)* 最小磁盘的容量。
虚拟存储器:页面如果很小,虚拟存储器中包含的页面个数就会过多,使得页表的体积过大,页表本身占据的存储空间过大,操作速度将变慢。
相联存取:是一种随机存取,但是选择某一单元进行读写是取决于其内容而不是其地址。Cache采用相联存取的方式。
输入输出
:::color4
BIOS保存在主板上的ROM
:::
总线
PCI总线是PC机常用总线,SCSI是软硬磁盘、光盘、扫描仪常用总线。都是并行总线。
片内总线是芯片内部的总线,如CPU内部的总线。
系统总线是CPU、主存、I/O设备各大部件之间的信息传输线。
通讯总线用于计算机系统之间或与其他系统之间的通信。
加密
:::color4
非对称加密算法:RSA、ECC
对称加密(共享密钥加密):MD5、DES、AES、RC-5、IDEA
信息摘要算法:SHA、MD5、HMAC
MD5:是信息摘要算法,把信息分为512比特的分组,并且创建一个128比特的摘要。
SHA-1:安全Hash算法也是基于MD5的,使用一个标准把信息分为512比特的分组,并且创建一个160比特的摘要。
:::
图
进程资源图
进程资源图是操作系统中用来表示进程与资源间的图形工具,主要用于检测和预防死锁。在这个图中,进程和资源被分别用不同类型的节点表示,而节点之间的边表示进程和资源之间的请求和分配关系。这种图形表示法可以帮助识别是否存在死锁的风险。
第二章 程序设计语言基础
程序设计语言基本概念
编译器的工作方式和特点是:先翻译后执行,用户程序运行效率高但可移植性差;
解释器的工作方式和特点是:边翻译边执行,用户程序运行效率底但可移植性好。
传值调用:形参取得是实参的值,形参的改变不会导致调用点所传的实参的值发生改变。
引用(传址)调用:形参取得是实参的地址,即相当于实参存储单元的地址引用,因此其值的改变同时就改变了实参的值。
编译程序中语法分析器接受以单词为单位的输入,并产生有关信息供以后各阶段使用。
算法优先法、LR分析法和递归下降法是几种常见的语法分析技术。
LR分析法主要有SLR(1)、LR(0)、LR(1)和LALR(1)等4种,其中LR(1)的分析能力最强,LR(0)的分析能力最弱。
静态检查 = 语义分析
符号表
- 是记录源程序中各个符号的必要信息,以辅助语义的正确性检查和代码生成,在编译过程中需要对符号表进行快速有效的查找、插入、修改和删除等操作;
- 符号表的建立可以始于词法分析阶段,也可以放到语法分析和语义分析阶段,但符号表的使用有时会延续到目标代码的运行阶段。
程序处理过程为:源代码、预处理、编译、优化、汇编、链接、可执行文件。
在运行时将调用和响应调用所需执行的代码加以结合的机制是动态绑定。
中间代码的作用是可使程序的结构在逻辑上更为简单明确,特别是可使目标代码的优化比较容易实现;有多种形式:逆波兰记号(后缀式)、四元式和三元式,共同特点是与具体的机器无关,不依赖与具体的计算机。
在编译过程中:词法分析、语法分析、语义分析、目标代码生成是必须的
:::color5
- 词法分析阶段:识别出一个个的单词,删掉无用的信息,报告分析时的错误
- 语法分析阶段:语法分析器以单词符号作为输入,分析单词符号是否形成符合语法规则的语法单位,如表达式、赋值、循环等,按照语法规则分析检查每条语句是否有正确的逻辑结构;语法分析构造一颗语法树。
- 语义分析阶段:主要检查源程序是否存在语义错误,并收集类型信息供后面的代码生成阶段使用;如:赋值语句的右端和左端的类型不匹配;表达式的出书是否为0等。
:::
第三章 操作系统
Apache默认的Web目录为“/home/httpd”
进程的通信
当有一个进程进入临界区且有另一个进程等待进入临界区时,S = -1。当S小于0时,其绝对值等于等待临界区的进程数。
临界区:指进程中用于访问临界资源的那段代码 。
至少需要资源数 = 并发进程数 *(每个进程所需资源数-1)+1
存储管理
虚拟存储管理系统的基础是程序的局部性理论。基本含义是:指程序执行时,往往会不均匀的访问内存储器,即有些存储区被频繁访问,有些则少有问津。
虚拟存储技术并非实际扩充内存、外存,而是采用相关技术相对地扩充主存。
虚拟存储器只能基于非连续分配技术。
工作集是指进程运行时被频繁访问的页面集合。
在win操作系统下,要获取某个网络开放端口所对应的应用程序信息,使用 netstat。
FAT文件系统用的基于文件的簇状链式结构文件管理结构。
用户A(所有者)的完全访问权限是7(4读+2写+1执行)
用户B(组)的只读和运行权限是5(4读+1执行)
用户C(其他用户)的运行权限是1(1执行)
第四章 网络与信息安全
网络分类
OSI(Open Systems Interconnection)是一个参考模型,由国际标准化组织(ISO)提出,用于指导不同厂商生产的计算机之间进行网络通信。它定义了网络通信的七层协议结构,每一层都实现了特定的功能,并提供了与其他层之间的接口。以下是OSI模型的七层及其简要描述:
:::info
- 物理层(Physical Layer)
- 主要功能:在物理媒体上传输原始的比特流(bit stream)。
- 涉及技术:各种物理传输媒介(如双绞线、光纤、无线等)和物理接口标准(如Ethernet、USB等)。
- 硬件设备:网线、集线器、中继器、调制解调器。
- 数据链路层(Data Link Layer)
- 主要功能:在相邻节点之间传输帧(frame),并进行错误检测和纠正。
- 涉及技术:MAC地址、以太网(Ethernet)、点对点协议(PPP)、帧中继(Frame Relay)等。
- 硬件设备:网桥、二层交换机、以太网交换机、网卡
- 网络层(Network Layer)
- 主要功能:提供路径选择和逻辑地址(如IP地址)管理,实现数据包(packet)的跨网络传输。
- 涉及技术:IP协议、ICMP协议、路由协议(如OSPF、BGP等)。
- 硬件设备:路由器、三层交换机
- 传输层(Transport Layer)
- 主要功能:提供端到端的通信服务,确保数据包的完整性和顺序,以及进行流量控制和错误恢复。
- 涉及技术:TCP(传输控制协议)、UDP(用户数据报协议)等。
- 硬件设备:四层交换机、四层路由器
- 会话层(Session Layer)
- 主要功能:建立、维护和终止会话(session),管理通信双方的对话过程。
- 涉及技术:RPC(远程过程调用)、SQL(结构化查询语言,用于数据库会话)等。
- 表示层(Presentation Layer)
- 主要功能:对数据进行格式化、加密和解密,以及进行数据压缩和解压缩,以确保数据在发送方和接收方之间以相同的格式呈现。
- 涉及技术:MIME(多用途互联网邮件扩展)、TLS(传输层安全协议,用于加密)等。
- 应用层(Application Layer)
- 主要功能:提供直接为用户和应用程序服务的功能,如电子邮件、文件传输、远程登录等。
- 涉及技术:HTTP(超文本传输协议)、FTP(文件传输协议)、SMTP(简单邮件传输协议)、SSH(安全外壳协议)等。
:::
TCP/IP
TCP的序号是以字节为单位进行编号的。
:::color1
TCP/IP协议的四层分别是网络接口层(有时也称为网络接入层或数据链路层)、网络层、传输层和应用层。以下是各层的详细介绍:
- 网络接口层(网络接入层/数据链路层)
- 主要功能:负责将数据帧从网络层传输到物理媒介(如以太网、Wi-Fi等),并处理数据在物理媒介上的传输。同时,它也负责从网络上接收物理帧,并抽取出IP数据报交给网络层处理。
- 关键技术:这一层涉及到物理媒介的管理,以及如何使用实际网络(如Ethernet、Serial Line等)来传送数据。地址解析协议(ARP)也工作在这一层。
- 网络层
- 主要功能:负责数据包在整个网络上的传输和路由选择。它使用IP地址来标识主机和路由器,并决定数据的最佳路径到达目的地。
- 关键技术:网络层包含多个协议,其中最重要的是IP协议。IP协议提供的是一个可靠、无连接的数据报传递服务。此外,还有互联网组管理协议(IGMP)和互联网控制报文协议(ICMP)等协议。
- 传输层
- 主要功能:为两台主机上的应用程序提供端到端的通信服务,保证数据包的顺序传送及数据的完整性。
- 关键技术:传输层定义了两个主要的协议:TCP(传输控制协议)和UDP(用户数据报协议)。TCP协议提供的是一种可靠的、通过“三次握手”来连接的数据传输服务;而UDP协议则提供的是不保证可靠的(但并不是不可靠)、无连接的数据传输服务。
- 应用层
- 主要功能:为用户提供所需要的各种网络服务,并处理应用程序的逻辑。
- 关键技术:应用层包含多个应用程序协议,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)以及域名系统(DNS)等。这些协议为用户提供了电子邮件、文件传输、远程登录和域名解析等网络服务。
:::
FTP协议占用两个标准端口号:20和21,20为数据口,21为控制口。
80:HTTP默认的端口号。
25:SMTP默认端口。
110:POP3默认端口,是TCP/IP协议中的一个,主要用于支持使用客户端远程管理在服务器上的电子邮件。
根据DHCP协议,如果主机设置为自动获得IP地址,而又没有可用的DHCP服务器,那么主机会自动生成一个169.254.X.X的IP地址,以与其他主机正常通信。
UDP协议:是一种简单、高效的传输层协议,适用于对实时性要求高、对可靠性要求不高的应用场景。
防火墙技术经历了包过滤、应用代理网关和状态监测技术三个发展阶段。
HTTPS:端口443,基于HTTP开发,用于在客户机和服务器交换信息;使用安全套接字层(SSL)进行信息交换,HTTP的安全版。
:::color1
HTTPS和HTTP的区别:
• https协议需要到ca申请证书,一般免费证书很少,需要交费。
• http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
• http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。
• http的连接很简单,是无状态的。
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
:::
第五章 数据库基础
数据的物理独立性是指用户的应用程序与存储在磁盘上的数据库中的数据是相互独立的。即,数据在磁盘上怎样存储是由DBMS管理,用户程序不需要了解,应用程序要处理的只是数据的逻辑结构,这样当数据的物理存储改变了,应用程序不用改变。
数据库的基本表对应概念视图;存储文件对应内部视图、视图对应用户视图。
SQL注入攻击的首要目标是获得数据库的权限。
ER图,根据转换规则,多对多的联系需要转换成独立的关系模式。
:::success
在结构化分析方法中,数据流图用于功能建模;E-R图用于数据建模;状态转换图用于行为建模。
:::
数据库设计
概念设计:用户角度、E-R图;
逻辑设计:E-R图转换成关系模式。
物理设计:物理存储方法、索引等。
多对多联系(m:n)转换为一个独立的关系模型R时,R的关键字为各实体关键字的集合。
完整性约束
数据的安全性:保护数据库,防止未经授权或不合法的使用造成的数据泄露、非法更改或破坏。
自然连接:要求两个关系中进行比较的分量必须是相同的属性组,并且在结果集中将重复的属性列去掉。自然连接要从关系的水平和垂直两个方向运算。
左外连接:是取出左侧关系中所有与右侧关系中任一元组都不匹配的元祖,用空值NULL充填所有来自右侧关系的属性,构成新的元组,将其加入自然连接的结果中。
右外连接:是取出右侧关系中所有与左侧关系中任一元组都不匹配的元组,用空值NULL充填所有来自左侧关系的属性,构成新的元组,将其加入自然连接的结果中。
全外连接:完成左外连接和右外连接。即填充左侧关系中与右侧关系中任一元组都不匹配的元祖,并填充右侧关系中所有与左侧关系中任一元组都不匹配的元组,将产生的新元组加入自然连接的结果中。
分布式数据库
- 逻辑透明性:最低层次的透明性,提供数据到局部数据库的映像,即用户不必关心局部DBMS支持那种数据模型,使用哪种数据操纵语言,都是系统自动完成。
- 位置透明性:用户不必关心数据的物理位置在何处。
- 分片透明性:不必关心数据如何分片(分块存储)
- 复制透明性:用户不需要关心数据库在网络中的各个节点的复制情况,数据的更新都是系统自动完成。
:::info
三层模式
视图–外模式
存储文件–内模式
基本表–模式
:::
第六章 软件工程
软件生存周期
:::success
统一过程模型:
- 起始阶段:起始阶段专注于项目的初创活动。
- 精化阶段:精化阶段在理解了最初的领域范围之后进行需求分析和架构演进。
- 构建阶段:构建阶段关注系统的构建,产生实现模型。
- 移交阶段:移交阶段关注于软件提交方面的工作,产生软件增量。
:::
软件开发模型
:::color2
瀑布模型将开发阶段描述为从一个阶段瀑布般地转换到另一个阶段的过程;常采用结构化生命周期方法。V模型是瀑布模型的变种。
- 优点:容易理解,管理成本低
- 缺点:缺乏灵活性,难以适应需求的变化,如果软件在后期出现需求变化,整个系统需要从头开始。
快速原型模型中,开发人员快速地构造整个系统或者系统的一部分以理解或澄清问题;不适用于大型软件系统的开发。
螺旋模型将开发活动和风险管理结合起来,以减小风险。
喷泉模型开发过程模型以用户需求为动力,以对象为驱动,适合于面向对象的开发方法。
:::
敏捷方法
:::color3
敏捷统一过程采用在大型上连续、在小型上迭代的原理来构建软件系统,提供了一系列活动,能够使团队为软件项目构想出一个全面的过程流。
极限编程:高效、低风险、测试先行(先写测试代码,在写程序)
并列争球法:迭代,30天为一个迭代周期,按需求优先级实现。
开放式编码:虚拟团队,开发成员分布各地。
水晶方法:不同项目,不同策略
功能驱动方法:开发人员分类,分为指挥者(首席程序员)、类程序员
自适应方法:预测-协作-学习
:::
系统设计
软件设计分为概要设计(软件结构设计)和详细设计。
- 概要设计的任务是确定软件系统的结构、进行模块划分、确定每个模块的功能、接口以及模块之间的调用关系。设计软件系统的结构,主要任务是确定模块间的组成关系。
面向数据结构的设计方法以数据结构作为设计的基础,根据输入/输出数据结构导出程序的结构。适用于规模不大的数据处理系统。
:::color4
模块化设计要求高内、低耦合。
- 模块的大小要适中,系统分解时要考虑模块的规模,过大的模块可能导致系统分解不充分,其内部可能包括不同类型的功能,需要进一步划分,尽量使各个模块功能单一;过小的模块将系统的负责度增加,模块之间的调用频繁,降低独立性。
- 模块的扇入扇出要合理
- 深度和宽度适当
:::
:::danger
耦合
非直接耦合:两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。
数据耦合:一个模块访问领一个模块时,彼此之间是通过简单数据参数(不是控制参数,公共数据结构或外部变量)来交换输入、输出信息的,耦合度较低。
标记耦合:一组模块通过参数表来传递记录信息,这个记录是某一数据结构的子结构,而不是简单变量;其实传递的是这个数据结构的地址。
控制耦合:一个模块通过传送开关、标志、名字等控制信息,明显地控制选择另一模块的功能。
外部耦合:一组模块都访问同一全局变量而不是同一全局数据结构,而不是通过参数表传递该全局变量的信息。
公共耦合:一组模块都访问一个公共数据环境(全局数据结构、共享通信区、内存的公共覆盖区)等。
内容耦合:一个模块直接访问另一个模块的内部数据;一个模块不通过正常入口转到另一模块内部;两个模块有一部分程序代码重叠;一个模块有多个入口
:::
系统测试与运行维护
系统可维护性包括:可理解性、可测试性、可修改性。
:::info
语句覆盖要求被测程序中的每一条语句至少执行一次,这种覆盖对程序执行逻辑的覆盖很低。
条件覆盖要求每一次判定语句中每个逻辑条件的各种可能的值至少满足一次。
判定/条件覆盖要求判定中每个条件的所有可能取值(真/假)至少出现一次,并使得每个判定本身的判定结果(真/假)也至少出现一次。
路径覆盖要求覆盖被测程序中所有可能的路径;覆盖准则最强。
:::
:::color5
对采用面向对象方法开发的系统进行测试时,通常从不同层次进行测试。
算法层:用于测试类中定义的每个方法,基本相当于传统软件测试中的单元测试。
类层:用于测试封装在同一个类中的所有方法与属性之间的相互作用。在面向对象软件中,类是基本模板,因此可认为这是面向对象测试中所特有的模块测试。
模板层:用于测试一组协同工作的类之间的相互作用。相当于传统软件测试中的继承测试。但这个也有面向对象的特点,如对象之间通过发送消息相互作用。
系统层:把各个子系统组织完成的面向对象的软件系统,在组装过程中进行测试。
:::
:::info
白盒测试原则:
- 程序模块中的所有独立路径至少执行一次
- 在所有的逻辑判断中,取“真”和取“假”的两种情况至少都能执行一次。
- 每个循环都应在边界条件和一般条件下各执行一次
- 测试程序内部数据结构的有效性等。
:::
系统测试的目的在于通过与系统的需求定义做比较,发现软件与系统定义不符合或与之矛盾的地方,以验证软件系统的功能和性能满足指定的要求。
项目管理
软件设计包括体系结构设计、接口设计、数据设计和过程设计。
项目估算一般考虑规模、工作量、成本等因素。
:::color5
甘特图是一种项目管理中常用的图表,用于规划和跟踪项目的进度。它以条形图的形式直观地展示了项目中的各个任务、活动或阶段的开始时间、持续时间和结束时间。通过这种可视化的方式,项目管理者可以轻松了解整个项目的进度情况,包括哪些任务已经完成、哪些正在进行以及哪些尚未开始。
甘特图通常包含几个关键元素:
- 任务列表:列出项目需要完成的所有主要任务。
- 时间轴:横跨图表顶部,表示项目的总时长。
- 条形图:每个任务对应一个条形,其长度代表了该任务预计所需的时间。
- 里程碑:用特殊的标记指出项目的关键节点,如重要决策点或阶段性成果达成时刻。
- 依赖关系:某些任务可能需要等待其他任务完成后才能开始,这些前置后置关系在甘特图上也会被标识出来。
使用甘特图的好处很多,比如帮助团队成员更好地理解自己的工作如何与他人协作;让项目经理能够更有效地分配资源;及时发现潜在的问题并调整计划等。随着技术的发展,现在有许多在线工具支持创建动态交互式的甘特图,使得项目管理和沟通变得更加高效便捷。
:::
软件质量
:::success
ISO/IEC软件质量模型定义了一系列用于评估软件产品质量的特性。
软件产品的质量特性主要包括但不限于以下几点:
- 功能性(Functionality):指软件提供的功能满足用户需求的程度,包括软件功能的完备性、准确性以及是否符合规定的要求。
- 可靠性(Reliability):衡量软件在特定条件下和一段时间内保持其性能水平的能力,涵盖错误率低、容错能力强等方面。
- 可用性(Usability):关注用户使用软件时的便利程度,如易学性、易操作性及界面友好度等,确保不同背景的用户都能轻松上手并有效利用软件。
- 效率(Efficiency):涉及资源消耗情况下的响应时间或处理速度,比如CPU利用率、内存占用量等指标,反映了软件执行任务时对计算资源的有效管理能力。
- 可维护性(Maintainability):指的是修改现有软件代码以纠正缺陷、改进功能或者适应环境变化所需努力的程度,良好的文档记录和清晰的设计有助于提高这一属性。
- 可移植性(Portability):表示软件从一个环境转移到另一个环境中运行的能力,包括硬件平台之间的迁移、操作系统版本升级等情况下的兼容性和适应性。
- 安全性(Security):保护信息免受未经授权访问、破坏或泄露的能力,通过实施适当的加密措施、身份验证机制等方式实现。
每个质量特性下还进一步细分为更具体的子特性,共同构成了一个完整的软件质量评估框架。企业和开发者可以根据项目的具体需求选择重点关注的质量属性,并据此制定相应的测试计划和改进策略,以保证最终交付给用户的软件产品具有较高的质量和满意度。
:::
软件度量
McCabe度量法是一种基于程序控制流的复杂性度量方法,复杂度=封闭空间的个数+1
概述
结构化方法属于面向数据流的开发方法,方法的特点是软件功能的分解和抽象。
Booch认为系统开发是一个螺旋上升的过程,每个周期包括4个步骤,分别是标识类和对象、确定类和对象的含义、表示关系、说明每个类的接口和实现。其开发模型包括静态模型和动态模型,动态模型包括状态图和顺序图,用来描述对象的状态变化和交互过程。
结构化分析
结构化分析方法采用自顶向下逐步分解的思想进行分析建模。
结构化分析方法在实施阶段强调的是分析对象的数据流。
数据流图用来描述系统的功能,进行功能建模。
结构化设计
结构化分析的输出是结构化设计的输入,设计活动依据分析结果进行。
7种内聚性由高到低分别为**功能内聚****、顺序内聚、通信内聚、过程内聚、时间内聚、逻辑内聚、偶然内聚**。
管道过滤器属于数据流架构风格,这种架构风格的特点就是数据交由系统后由系统中的构建进行处理,一个构建处理完毕后将数据交由后续构建继续处理,这个过程是顺序的不存在你来我往的“交互”。
面向对象基本概念
面向对象方法的多态性是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果;在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。
在面向对象方法中,对象是最根本的模块。
对象通常由对象名、属性和操作三部分组成。
:::info
类是一组具有相同属性和相同操作的对象的集合,类中的每个对象都是这个类的一个实例。
类之间共享属性与服务的机制称为继承。
一个对象通过发送消息来请求另一个对象为其服务。
对象具有以下特性:
- 清晰的边界
- 良好定义的行为
- 可扩展性
:::
:::color4
多态有四类,通用的多态有参数多态和包含多态,特定的多态有过载多态和强制多态。
**参数多态:**应用广泛、最纯的多态。
包含多态:同样的操作可用于一个类型及其子类型;一般需要进行运行时的类型检查。
过载多态:同一个名字在不同的上下文中所代表的含义不同。
**强制多态:**编译程序通过语义操作,把操作对象的类型强行加以变换,以符合函数或操作符的要求。
:::
面向对象分析
:::info
面向对象分析包含5个活动:
- 认定对象
- 组织对象
- 描述对象间的相互作用
- 确定对象的操作
- 定义对象的内部信息
:::
:::color3
面向对象的分析要建立三种模型:
- 功能模型:表达系统的详细需求,为软件的进一步分析和设计打下基础。在面向对象方法中,由用例图和场景描述组成。
- 对象模型:表示静态的、结构化的系统“数据”性质。描述现实世界中实体的对象以及它们之间的关系,表示目标系统的静态数据结构。类图是构建对象模型的核心工具。
- 动态模型:描述系统的动态结构和对象之间的交互,表示瞬时的、行为化的系统的“控制”特性。常用状态图、顺序图、合作图、活动图构建。
:::
:::info
构架用例模型(OOA)四个阶段:
- 确定参与者
- 确定需求用例
- 构造用例模型
- 记录需求用例描述
:::
面向对象设计
面向对象设计支持多重继承、单重继承和层次继承。
开闭原则:软件实体应该是可扩展的,即开放的。但是不可修改的,即封闭的。
接口分离原则:不应该强迫客户依赖于它们不用的方法,接口属于客户,不属于它所在的类层次结构,即:依赖于抽象,不要依赖于具体,同时在抽象级别不应该有对于细节的依赖,这样做的好处就在于可以最大限度地应对可能的变化。
里氏替换原则:子类可以替换父类。
迪米特原则(最少知道原则):一个对象应当对其他对象有尽可能少的了解。
依赖倒置原则:要依赖于抽象,不是具体实践;对接口进行编程,不要对实现编程。
共同重用原则:一个包中的所有类应该死共同重用的;如果重用了包中的一个类,那么就要重用包中的所有类。
无环依赖原则:在组件的依赖关系在途中不允许存在环。
:::info
类可以分为三种类型:
- 实体类:映射需求中的每个实体,实体保存需要存储在永久存储体中的信息;对用户来说最有意义的类;一个参与者一般对应实体类。
- 边界类:封装在用例内、外流动的信息或数据流。边界类是一种用于对系统外部环境与其内部运作之间的交互进行建模的类;将系统与其外部环境的变更隔离开,使这些变更不会对系统其他部分造成影响。
- 控制类:用于控制用例工作的类,一般是由董斌结构的短语转换来的名词;用于对一个或几个用例所特有的控制行为进行建模,控制对象通常控制其他对象,因此它们的行为具有协调性。
:::
:::color5
面向对象设计包含的主要活动是(区别于面向对象分析):
- 识别类及对象
- 定义属性
- 定义服务
- 识别关系
- 识别包
:::
UML
用例之间的关系主要有包含、扩展和泛化三类。
- 包含关系:当可以从两个或两个以上的用例中提取公共行为时,应该使用包含关系来表示它们。
- 扩展关系:如果一个用例明显的混合了两种或两种以上的不同场景,即根据情况可能发生多种分支,则可以将这个用例分为一个基本用例和一个多个扩展用例。
- 泛化关系:当多个用例共同拥有一种类似的结构和行为时,可以将他们的共性抽象成为父用例,其他的用例作为泛化关系中的子用例。
在UML中有4中事物:结构事物、行为事物、分组事物和注释事物。
- 结构事物:在模型中属于最静态的部分,代表概念上等或物理上的元素。
:::info
**用例图:**从用户的角度描述了系统的功能,并指出各个功能的执行者,强调用户的使用者,系统为执行者完成哪些功能。
类图:展现了一组对象、接口、协作和他们之间的关系。在面向对象系统的建模中,最常见的就是类图,它给出系统的静态设计视图。
对象图:描述的是参与交互的各个对象在交互过程中某一时刻的状态。对象图可以被看作是类图在某一时刻的实例。
组件图:展示了一组组件之间的组织和依赖。棒棒糖是组件图
通信图:是一种交互图,强调收发消息的对象或参与者的结构组织。
部署图:是用来对面向对象系统的物理方面的建模的方法,展现了运行时处理节点以及其中构建(制品)的配置。
顺序图:是一种交互图,交互图展现了一种交互,它由一组对象或参与者以及它们之间可能发送的消息构成;顺序图是强调消息的时间次序的交互图。
:::
设计模式
创建型
:::danger
生成器模式:创建型设计模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。适用于两种情况,当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时;当构建过程必须允许被构建的对象有不同的表示时。
适配器模式:将类的接口转换成客户希望的另一个接口。
工厂方法模式:
抽象工厂模式:提供一个接口,可以创建一系列相关或相互依赖的对象,而无须指定他们具体的类。
单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点。
建造者模式:
原型模式:可以封装生产代码后减少代码的编写。
:::
行为型
:::info
行为型
命令模式(Command):将一个请求封装成一个对象,从而使得用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。抽象出待执行的动作以参数化某对象。
策略模式:针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换;算法可以在不影响到客户端的情况下发生变化。
模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义算法的某些特定步骤。
观察者模式:定义对象间一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又无须暴漏该对象的内部表示。
责任链模式:避免请求发送者与接受者耦合在一起,让多个对象都有可能接受请求,讲这些对象连接成一条链,并且沿着这条链传递请求,知道有对象处理它为止。适用于:可处理一个请求的对象集合应该被动态指定;有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定;想在不明确指定接受者的情况下向多个对象中的一个提交一个请求。
备忘录模式:保存一个对象的某个状态,以便在适当的时候恢复对象。在不破坏封装性的前提下,捕捉一个对象的内部状态,并在该对象之外保存这个状态。
状态模式:将每一个条件分支放入一个独立的类中,这样就可以根据对象自身的情况将对象的装填作为一个对象,这一对象可以不依赖于其他对象而独立变化。
访问者模式:表示一个作用于某个对象结构中的各元素的操作,使得在不改变各元素的类的前提下定义作用于这些元素的新操作;适用于需要对一个对象结构中的对象进行很多不同的组合,并且不相关的操作时。
中介者模式:用一个中介对象来封装一系列的对象交互,使各对象不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变他们之间的交互。适用于:一组对象以定义良好但那是复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解;一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象;想定制一个分布在多个类中的行为,而又不想生成太多的子类。
解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
:::
结构型
:::color5
适配器模式:将一个类的接口转换成客户希望的另一个接口。使原本由于接口不兼容而不能一起工作的那些类可以一起工作。
装饰器模式:把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。
代理模式:通过提供与对象相同的接口来控制对这个对象的访问,以使得在确实需要这个对象时才对它进行创建和初始化。
外观模式:要求外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
桥接模式:将类的抽象部分和它的实现部分分离出来,使它们可以独立变化。
组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构,使得客户对单个对象和组合对象的使用具有一致性。
享元模式:
:::
第七章 数据结构
线性表 单链表
删除单链表的最后一个节点需置前节点的指针为null,需要从头开始以此遍历找到该前节点,需要O(n),与表长有关。
线性表:
链表:
栈
可以实现表达式中的括号匹配问题。
当扫描到左括号时,则将其压入栈中;当匹配到右括号时,从栈顶取出一个左括号。
当函数调用时,在栈顶创建并临时保留的一段存储空间即栈帧中,会存放调用函数时的返回地址、形参变量和局部变量。而全局变量存放在程序的静态存储区,位置是相对固定、独立的。
非静态局部变量存储在栈区。
队列
是一种常见的数据结构,遵循先进先出的原则。这意味着第一个被添加到队列中的元素将是第一个被移除的元素。
入队:将元素添加到队列的尾部。
出队:从队列的头部移除元素。
二维数组计算地址公式:LOC(i,j)=LOC(0,0)+(i*m+j)*L
矩阵
对稀疏矩阵的压缩方法有三种:
三元组顺序链表、十字链表、行逻辑连接的顺序表
有向图,各顶点的出度为矩阵行中1的个数。
无向图的邻接矩阵中,邻接大小为n2,非零元素个数为2e,所以零元素的个数是n2-2e。
树
度:有几个叶子结点
遍历方法:
先序:先访问根节点,然后从左到右遍历根节点的各棵子树;
后序:先从左到右遍历根节点的各棵子树,然后访问根节点;
层序:先访问处于第一层的节点,然后从左到右一次访问处于第2层、3层上的节点,即自上而下、自左至右逐层访问树各层上的节点。
中序:先访问左子树,然后访问当前节点,最后访问右子树。
大顶堆:一种特殊的完全二叉树结构,其中每个节点的值都大于或等于其子节点的值。在数组表示的大顶堆中,数组的下标可以用来表示树中的位置关系,使得堆的操作更加高效。
分支数等于树中各个节点的度之和。
哈夫曼树 在非空二叉树中,n0 = n2+1
霍夫曼编码将频繁出现的字符采用短编码,出现频率最低的字符采用长编码;基于贪心策略。
1、以每个字符的出现频率作为关键字构建最小优先级队列;
2、取出关键字最小的两个结点生成子树,根节点的关键字为孩子节点关键字之和,并将根节点插入到最小优先级队列中,直至得到一颗最优编码树。
一颗有n个节点的树的所有结点的度数和为 n-1
B+树:
所有的非叶子节点只存储索引信息,不存储实际数据。所有数据都存储在叶子节点中,这使得叶子节点可以形成一个有序链表,便于范围查询。
B+树的叶子结点之间通过指针相连,增加了区间访问性,可以使用范围查询等高级操作。
B+树的内部节点(非叶子节点)存储的是其子节点的最大值或最小值关键字,用于索引。
排序二叉树:
图
线性表:数据元素之间有线性关系,每个数据元素只有一个直接前驱和一个直接后继
树:数据元素之间有着明显的层次关系,并且每一层上的数据元素可能和下一层多个元素有关系,但只能和上一层中一个元素有关系
图:节点之间的关系可以是任意的,途中任一两个数据元素之间都可能有关系。
n个顶点的有向完全图中含有向边的数目最多为 n(n-1)
一个图的邻接矩阵表示唯一,邻接表表示不唯一;
邻接矩阵表示唯一是因为图中边的信息在矩阵中有确定的位置
邻接表不唯一是因为邻接表的建立取决于建立边的顺序和表中的插入算法。
邻接矩阵:是一种用来存储图G中顶点之间的关系的结构,它是由一个二维数组来表示的,数组中的每一行和每一列都代表一个顶点,而数组元素之间的值有一定含义,这些值代表了两个顶点之间是否存在连接,也就是说,只有存在边才能够表示值,否则以无穷大表示。
邻接表:采用的是链表的形式来存储顶点的相邻的结点的关系,也就是说,每个顶点都会有一个链表来存储它周围的结点。能够比较好的展示出图中各个顶点之间的关系,以及图中结点的孤立情况。
沟通路径公式:n*(n-1)/2
查找算法
:::color4
分治法:
动态规划法:
回溯法:
贪心法:总是做出在当前来说最好的选择,而并不从整体上加以考虑,所做的每一步都是当前步骤的局部最优选择,但从整体上来说不是最优选择;因此其耗费时间少,一般可以快速得到满意的解,但得不到最优解。
:::
稳定算法:冒泡排序、归并排序
快速排序
- 采用分治法策略来把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。
不适用于接近有序的情况。 - 时间复杂度:
- 平均 O(n log n)
- 最坏 O(n^2)
- 最好 O(n log n)
- 空间复杂度
- 原地排序 O(log n) (由于递归调用栈)
- 非原地排序 O(n) (由于需要额外的空间存储子数组)
直接插入排序
- 将待排序数组分为两个部分,已排好序部分和未排序部分
- 开始时,第一个元素在已排好序部分中,其余元素在未排序部分
- 然后依次从未排序部分去除第一个元素,从后向前与排好序部分的元素进行比较并将其插入到已排好序部分的正确位置,直到所有元素排好序。
- 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到对应位置并插入。
- 当序列基本有序时,直接插入排序过程中元素比较的次数较少,当序列为逆序时,元素的比较次数最多。
- 适用于少量数据的排序,或数据基本有序的情况。对于大量数据或完全无序的数据,性能可能不佳。
- 时间复杂度
- 最佳情况:O(n)(数组已排序,只需逐个插入)
- 最坏情况:O(n^2)(数组逆序,需进行大量元素移动)
- 平均情况:O(n^2)
- 空间复杂度
- O(1)(原地排序,无需额外存储空间)
堆排序:是一种基于堆数据结构实现的排序算法,选择排序。
- 将待排序的序列构造成一个大顶堆(升序)或小顶堆(降序),此时整个序列的最大值(或最小值)就是堆顶的根节点。
- 将堆顶元素(最大值或最小值)与末尾元素交换,并将堆的大小减一,然后对剩余部分重新进行堆的调整,以确保剩余部分仍然满足堆的性质。
- 重复上诉步骤,直到堆的大小减至1,此时序列已经完全排序。
- 时间复杂度:O(nlogn)
- 空间复杂度:O(1) (只涉及到元素之间的交换和移动)
冒泡排序:
- 通过重复比较要排序的数列,一次比较两个元素,如果它们的顺序错误就把他们交换过来。直到没有在需要交换的元素。
- 稳定性
- 时间复杂度:O(n^2)
- 空间复杂度:O(1) (只涉及到元素之间的交换和移动)
- 适用于小规模数据的排序
归并排序:
- 将待排序数组划分为子问题,对子问题求解,然后合并解
- 将数组分为两个相同规模的子数组,分别包含前n/2个元素和后n/2个元素;
- 递归地排序这两个子数组;
- 合并排好序的两个子数组,依次比较两个排好序的子数组的元素,得到整个数组的排好序的序列。
- 是一种建立在归并操作上的有效、稳定的排序算法,使用分治法策略
- 分解:将待排序的序列分成两个子序列,每个子序列包含n/2个元素
- 解决:递归地对这两个子序列进行排序。
- 合并:将排序好的两个子序列合并成一个有序序列。
- 稳定:相同元素的相对顺序在排序后不会改变。
- 时间复杂度:O(n log n) (能够提供一致的快速排序性能,不受输入数据初始顺序的影响)
- 空间复杂度:O(n) (需要与原始数组大小相同的额外空间来存储临时合并的数组)
- 适用性:适合处理大量数据、适合外部排序
基数排序
- 是一种非比较型的整数排序算法
- 将整数按位数切割成不同的数字,然后按每个位数分别比较
- 从最低有效位到最高有效位或从最高到最低进行排序
- 通常用于对数字或字符串进行排序
- 时间复杂度:基数排序的时间复杂度为O(d * (n + k)),其中d是最大数的位数,n是待排序数组的长度,k是计数排序中桶的数量(对于数字排序,k通常为10)。
- 空间复杂度:基数排序的空间复杂度为O(n + k),其中n是待排序数组的长度,k是计数排序中桶的数量
简单选择排序
- 首先在未排序的序列中找到最小(或最大)的元素,存放到排序序列的起始位置
- 然后再从剩余未排序的元素中继续寻找最小(或最大)的元素,放到已排序序列的末尾。以此类推,直到所有元素均排列完毕。
算法基本概念
- 算法是对问题求解过程的一种描述,是为解决一个或一类问题给出的一个确定的、有限长的操作序列。
- 原则:
- 首先算法必须是正确的
- 其次应有很好的可读性
- 必须具有健壮性
- 最后具有高效率与低存储量
第八章 知识产权
著作权
对于著作权,在没有合同约定清楚的情况下,著作权属于受委托方。
著作权自作品创作完成之日起产生。
专利权
发明专利权的期限为二十年。
实用新型专利权的期限为十年。
外观设计专利权的期限为十五年。
商标法
商标注册是按照资源注册与强制注册(烟草、人类药品)相结合的原则进行的。
商标专用权应当授予符合法定条件的申请人。
商标权的保护期是可以延长的。
用法律修改权、署名权、保护作品完整权受到永久保护。
发表权、使用权、获得报酬权保护期限为作者终身以及死后50年。
其他
结构化分析方法中,数据流图中的元素在数据字典中进行定义 。
数据字典中有4种类型的条目:数据流、数据存储、数据项和加工。
COCOMO 2 中,体系结构阶段模型基于源代码的行数进行估算。
用C/C++程序经过预处理、编译、汇编、链接后形成可执行程序。
递归调用使用栈实现的,这与栈的“后进先出"属性相符。
某模块的所有处理元素都在同一个数据结构上操作,则该模块的内聚类型为通信。
通信内聚指模块内的所有处理元素都在同一数据结构上操作,或者各处理使用相同的输入数据或产生相同的输出数据。
系统可靠性 = MTTF/(1+MTTF)
类图:一组对象、接口、协作和它们之间的关系。
用例图:一组用例、参与者以及它们2之间的关系。
对象图:某一时刻一组对象以及它们之间的关系
序列图:以时间顺序组织的对象之间的交互活动
在实体联系图中,属性冲突,是指属性值的类型,取值范围或取值集合不同。比如:“零 件号”有的定义为字符型,有的为数值型。
命名冲突,就是不同的意义对象名称相同。或者,相同的意义不同的名称。
结构冲突,是指同一对象在不同应用中具有不同的抽象。比如,“课程”在某一局部应 用中被当做实体,而在另一局部应用中被当做属性。
嵌入式操作系统的特点:
1、微型化
2、可定制
3、实时性
4、可靠性
5、易移植性
高质量文档包含以下主要特点:
- 针对性
- 无二义性
- 易读性
- 完整性
- 灵活性
- 可追溯性
:::danger
环路复杂度(Cyclomatic Complexity)是一种衡量软件程序复杂性的指标,由Thomas J. McCabe在1976年提出。它主要用来评估一个程序或函数内部结构的复杂程度,特别是控制流的复杂性。环路复杂度数值越高,表明程序越复杂,维护起来也就更加困难。此外,高环路复杂度还意味着可能存在更多的错误点。
计算方法上,环路复杂度可以通过几种不同的方式来确定:
- 通过分析程序中的线性独立路径数量来直接计算。一条从开始到结束不重复经过任何语句的路径被视为一条独立路径。
- 使用公式 V(G) = E - N + 2P 计算,其中 E 是图中边的数量,N 是节点数,P 是连接组件的数量(对于大多数情况下的单一功能代码块来说,P=1)。
- 或者使用更简单的形式 V(G) = P + 1,这里 P 表示决策点(比如 if 语句、while 循环等)的数量。
环路复杂度对于软件测试也很重要,因为它可以帮助确定需要多少个测试用例才能覆盖所有可能的执行路径。理想情况下,每个逻辑分支都应该至少被测试一次以确保其正确性。然而,在实际应用中,随着复杂度增加,完全覆盖变得越来越难以实现且成本高昂。
总之,监控和管理代码的环路复杂度是提高软件质量的一个关键方面,有助于开发团队创建出更容易理解、测试及维护的代码库。
:::