一、《软件工程》之需求获取
需求是人们要解决的某个问题或达到某种目的的需要,是系统或其组成部分为满足某种书面规定(合同,标准,规范等)所要具备的能力,需求说明书将作为系统开发,测试,验收,提交的正式文档依据。
-
描述需求的三种思维
软件工程师的思维方式:会做出尽可能简化问题复杂度的假设 ;
计算机科学家思维方式:要找出不失一般性的解决方法 ;
数学家思维方式:追求对问题描述的精确性。 -
需求工程师(Requirements Engineer)
能力的要求:分析问题和解决问题的能力 、人际沟通及交流能力、软件工程知识和技能 、应用领域有关知识 、书面语言组织和表达能力。
工作的目标: • 识别错误假设 • 确保一致性 • 提升依从性 • 减少彼此误解 • 提高支持速度和效率 • 提升客户满意度 • 撰写优质需求文档。
应该尽量避免:干扰、沉默、过度规约、矛盾含糊、向前引用、不切实际与一厢情愿。 -
“需求管理” 有三项任务:
• 学习 ——需求获取
• 剪枝 ——需求优选
• 文档化 ——撰写需求规格说明书 (需求规格说明(Software Requirements Speciafication, SRS,架起现实应用与人造系统的桥梁)
-
好的需求是项目成功的必要条件:
• 单个需求项的质量 :
准确(Concise)、 正确(Correct)、明确(Non-ambiguous)、可行(Feasible)、可证(Verifiable)
• 整个需求集合的质量:现实(Realistic)、精确(Concise)、 全面(Complete)、一致(Consistent) -
需求分类:
-
业务需求:是指那些可以帮助企业达成组织目标的需求项
• 是关于企业业务的陈述,与需求如何被实现无关,无论是手动的还是通过系统来完成。
• 业务需求被叫做业务目标
• 例如:携程旅行的业务需求是卖⻜飞机票,公司的目标是成为当人们想买⻜飞机票时⾸首先想到的公司 。 -
系统需求:满足使得系统实现预期的功能,它从用户的角度描述系统在做什么, 与系统是由什么硬件和软件实现无关。
企业选择实现系统的首要条件是:系统需求满足组织的业务需求
例如 :
• 订票系统需要和⽤用户数据库交互
• 新的软件会使得汽车的启动速度加倍
• 我们新产品制造的低成本将会让我们有更高的市场份额并满⾜足销售目标 -
软件需求:指系统中软件部分的需求,它的满足帮助实现系统需求
举例:
• 订票系统软件通过标准的网络服务接⼝口和航班信息交互
• 用户接口需要设置关于用户偏好的颜色和字体大小
• 系统的API需要同时支持C++和Java来让程序员访问系统服务 -
系统的用户需求:指其满足会影响系统的用户接受程度的需求,有时也称“用户接口需求”。
举例 :
• 订票系统的用户接口需要提供和系统交互的选项,通过控制命令或者WIMP 接⼝口
• 客户希望照相机背后有一个液晶屏幕,这样在拍照之后可以马上看到照片 -
系统的功能性需求:是指满足系统需求需要提供的功能。也被称为“行为需求”
举例 :
• 订票系统需要提供一个在任何航班上预留座位的功能
• 订票系统需要提供⼀个通过信⽤用卡付费的功能 -
非功能性需求:软件系统以及软件开发过程为满足系统功能需求,要满足的其他约束条件。
-
质量需求:描述软件系统正常工作时需要满⾜足的额外的、与质量相关的要求
• 在软件⼯程⽂献中,也称之为“质量属性”。
• 它应答的是关于 “提供的服务好到何种程度”的问题 (即How well)
例如:
• 订票系统的⽤用户界面要满⾜用户选择出发和终到站的过程不能超过四次按键
• 订票系统的订票请求响应时间要小于1分钟
• 图书馆的⿊名单应随时响应馆员的查询操作
• 列⻋加速控制软件的平均⽆故障时间是109小时 -
依从性需求:描述软件对国家法律、国际公约、社交法则、文化与政治习惯、标准等环境约束的要求
例如:
• 两列⽕⻋车间的最⼩间距应满足国际铁路运输安全规范中的最坏情况停车距离
• 会议调度系统在缺省情况下,要排除目标市场所在地区的公众假期 -
体系结构设计需求:定义系统环境对待设计系统在结构上的约束
分布式约束:要求软件系统组件满足目标组织由于地理自然分布导致的对系统设备节点的分布要求,以及数据的分布式存储与处理要求。
例如:
会议调度系统应与分布在世界各地的参会者的邮件服务系统和电子日程管理系统协同工作。 -
安装约束:要求软件系统能够在目标实现环境下正常运行。
例如:
会议调度系统应在微软Window 8 和 Mac OS 10.10上
6.需求工程的涉及到的过程活动:需求抽取、分析、规约、管理、验证
二、《编译原理》之 编译过程总框架
科研领域的三种重要思维方法,享有推进人类进步的三大手段美称,包括:逻辑思维,以数学学科为代表,重视条件、假设、推理;实证思维,以物理学为代表,特点由观察、归纳出自然科学规律;计算思维,以计算科学为代表,核心思想是抽象、自动。
- 编译理论与其他课程的关系
其中,自动机和形式语言是数学领域的知识。 - 编译与翻译
翻译程序:其输入是某种语言的一系列语句,而其输出则是另一种语言的一系列语句(目标语言程序)。
编译程序(Compiler):把用高级语言写的源程序作为数据接收,经过翻译转换,产生面向机器的代码作为输出。
概括一下:编译就是输入与输出有限制的翻译。 - 编译过程的组成
编译过程包含至少包含以下5个部分:
- 词法分析:依据构词规则和自动机理论断词,即通过逐个扫描分解,将源程序字符串转换为单词符号,识别出一个个单词(一共有五类的词性:定义符、标识符、运算符、界符、常数)
- 语法分析:在词法分析基础上,将单词符号串转化为语法单位(类似英文的短语、子句、句子、程序段、程序),并确定整个输入串是否构成语法上正确的程序。此时:单词符号转化为语法单位。基于语法规则和上下文无关文法。
- 中间代码生成:对语法分析所识别出的各类语法范畴,分析其含义,并进行初步翻译(产生中间代码)
- 代码优化:性能与应用的发展不成比例。优化仍有意义。对于代码(主要是中间代码)进行加工变换,以期能够产生更为高效(省时间和空间)的目标代码。优化的前提是结果一样。
- 目标代码生成:将中间代码变换成特定机器上的低级语言代码。中间代码到目标代码。
绝对指令、可重定位指令、汇编指令。依据硬件体系结构、指令系统。 - 编译程序的总框架
编译各阶段均须维持表格并进行表格管理,以及对语法语义的出错的处理,所以编译程序的总框架如下:
三、OJ基础
- 算法训练营第一周
- T1 数组实现栈:pop()返回字符串之后+c_str():
(1)c_str()函数:返回一个指向正规C字符串的指针, 内容与本string串相同。
注:为实现与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string对象转换成c中的字符串样式。
- T2 数组实现队列:
与实现栈不同的是,队列的首部会随着元素出队而改变。 - T3数组实现二叉树先序遍历和后序遍历算法:https://dsa.cs.tsinghua.edu.cn/oj/problem.shtml?id=2113
(1)push_back():是向量的操作,将一个新的元素加到vector的最后面,位置为当前最后一个元素的下一个元素。 push():用于stack::push();//在栈顶增加元素;queue::push();//将x 接到队列的末端。
(2)二叉树结构体的构造:
//结构体 struct node{ int val,l,r; } t[N]; int root,cnt; //插入操作 int insert(int v,int x){ if(x == 0){ x = ++cnt; t[x].val = v; t[x].l = 0; t[x].r = 0; return x; } //递归插入左右子树 if(t[x].val > v) t[x].l = insert(v,t[x].l); else t[x].r = insert(v,t[x].r); return x; }
- T4 数字盒子:
实质上是数组+链表构造散列表,在散列表上进行插入、查询、删除等操作;
(1)链表或数组的替换删除方法:
//检查有无重复元素 bool check(int op, ll x){int h = Hash(x); //从前往后遍历散列表的某个位置 vector<ll>::iterator ptr = table[h].end();//the type of iterator is the element which he will visit for(vector<ll>::iterator it = table[h].begin();it != table[h].end();++it){ if( *(it) == x){//if find x,give the pointer to x ptr = it; break; } } //没有找到目标元素,则添加进入散列表 if(op==1){ if(ptr == table[h].end()){ table[h].push_back(x); return 1; } return 0; }//找到了目标元素,先与尾元素交换,是赋值操作,再删除尾元素,避免了大量移动 else{ if(ptr != table[h].end()){ *ptr = table[h].back(); table[h].pop_back(); return 1; } return 0; } }
- T5 栈排序:
类似插入排序,已排序栈需要不断的退栈以找到合适的排序位置。 - T6 成绩排序:
将各科成绩、总成绩等每种数据都用一个数组存储,用了最简单的bubblesort,好在渐进意义下,多个数组的同一个操作不影响时间复杂度。总之,很简单,就是数组+排序。 - T7 并查集检查等式是否合法:
开一个长长的数组,遇到一个元素就用find()检查是否属于同一个集合,只有不同集合时,元素合并才有效。
(1)Unionfind的find():
int find(int x){ if (x == Father[x]) {return x;} Father[x] = find(Father[x]); return Father[x]; //一直找到二叉树的root,再检查是否一致 return Father[x] == x ? x : Father[x] = find(Father[x]); }
- T8 道路升级:
简述这是一道并查集的应用题。检查题中,道路的花费与道路编号成正比,所以先对道路编号顺序排序,由小到大逐个合并升级道路的集合,合并过程中,用并查集检查是否有回路。
(1)向量倒排方法:reverse(ans.begin(),ans.end());