Deadline:##

2018-9-17 22:00PM,以博客提交至班级博客时间为准

要求参考来自:https://www.cnblogs.com/xinz/archive/2011/11/27/2265425.html;

https://edu.cnblogs.com/campus/buaa/BUAASummerSETraining/homework/2013;

https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1816W/homework/2085

  1. 实现一个能够对文本文件中的单词词频进行统计的控制台程序。
  2. 进行单元测试、回归测试、效能测试,在实现上述程序的过程中使用相关的工具。
  3. 进行个人软件过程(PSP)的实践,逐步记录自己在每个软件工程环节花费的时间。
  4. 使用源代码管理系统 (码云)。

Task1:编码要求##

  1. Fork 码云项目 https://gitee.com/SE-net16/PersonalProject-C;

    https://gitee.com/SE-net16/PersonalProject-Java 到自己的仓库,在自己的码云仓库中新建一个学号命名的文件夹。
  2. 在开始实现程序之前,在PSP表格[附录1]记录下你估计在程序开发各个步骤上耗费的时间,在你实现程序之后,在PSP表格记录下你在程序的各个模块上实际花费的时间。
  3. 使用C++或者Java语言实现,C++请使用Visual Studio Community 2017进行开发,Java请使用,运行环境为64-bit Windows 10。
  4. 编写的代码遵守代码规范
  5. 使用码云来管理源代码和测试用例,代码有进展即签入码云。签入记录不合理的项目会被助教抽查询问项目细节。
  6. 使用单元测试对项目进行测试,并使用插件查看测试分支覆盖率等指标;并写出至少10个测试用例确保你的程序能够正确处理各种情况。
  7. 在完成个人项目后,请正确发起一个Pull Request,并确保自己的代码最终成功签入到 https://gitee.com/SE-net16/PersonalProject-C;

    https://gitee.com/SE-net16/PersonalProject-Java 中。(如果成功签入会在原始项目主页看到自己学号为名的文件夹)

Task2:博客要求##

  1. 在文章开头给出博客作业要求地址,码云项目地址。
  2. 给出个人的PSP表格。
  3. 解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。
  4. 设计实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?单元测试是怎么设计的?
  5. 代码说明。展示出项目关键代码,并解释思路与注释说明。
  6. 结合在构建之法中学习到的相关内容与个人项目的实践经历,撰写解决项目的心路历程与收获。

Task3:WordCount 项目要求##

实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。

第一步:基本功能要求###

输入文件名以命令行参数传入。例如我们在命令行窗口(cmd)中输入:

//C语言类
wordCount.exe input.txt
//Java语言
java wordCount input.txt

则会统计input.txt中的以下几个指标

  • 统计文件的字符数:

    - 只需要统计Ascii码,汉字不需考虑

    - 空格,水平制表符,换行符,均算字符

    - 统计文件的单词总数,单词:以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。

    - 英文字母:A-Za-z

    - 字母数字符号:A-Za-z0-9

    - 分割符:空格,非字母数字符号

    - 例:file123是一个单词,1file不是一个单词。fileFileFILE是同一个单词

  • 统计文件的有效行数:任何包含非空白字符的行,都需要统计。

  • 统计文件中各单词的出现次数,最终只输出频率最高的10个。频率相同的单词,优先输出字典序靠前的单词。

  • 按照字典序输出到文件result.txt:例如,windows95,windows98和windows2000同时出现时,则先输出windows2000

    • 输出的单词统一为小写格式
  • 输出的格式为

    characters: number
    words: number
    lines: number
    <word1>: number
    <word2>: number
    ...

第二步:接口封装###

在写了一些代码开胃之后,大家都完成了一份满足基本功能的代码。

大家的代码都各有特色,如果现在我们要把这个功能放到不同的环境中去(例如,命令行,Windows图形界面程序,网页程序,手机App),就会碰到困难:代码散落在各个函数中,很难剥离出来作为一个独立的模块运行以满足不同的需求。

同时我们也看到,不同的代码解决不同层面的问题:

  1. 有些是计算数据的(例如统计单词)
  2. 有些是控制输入的(例如scanf,cin,图形界面的输入字段)
  3. 有些是数据可视化的(例如printf,cout,println,DrawText)
  4. 有些则更为特殊,是架构相关的(例如main函数,并不是所有的程序都需要某个特定格式的main)

这些代码的种类不同,混杂在一起对于后期的维护扩展很不友好,所以它们的组织结构就需要精心的整理和优化。

我们希望把基本功能里的:

  1. 统计字符数
  2. 统计单词数
  3. 统计最多的10个单词及其词频

这三个功能独立出来,成为一个独立的模块(class library, DLL, 或其它),这样的话,命令行和GUI的程序都能使用同一份代码。为了方便起见,我们称之为计算核心"Core模块",这个模块至少可以在几个地方使用:

  1. 命令行测试程序使用
  2. 在单元测试框架下使用
  3. 与数据可视化部分结合使用

把计算核心在单元测试框架中做过完备的测试后,我们就可以在算法层级保证了这个模块的正确性。

但我们知道软件并非只有计算核心,实际的软件是交付给最终用户的软件,除了计算核心外,还需要有一定的界面和必要的辅助功能。

这个Core模块和使用它的其他模块之间则要通过一定的API来交流。

API应该怎么设计呢?

为了方便起见,我们可以从下面的最简单的接口开始(仅举例,你的代码里可能没有这个函数):

int countChar(File *file)

这个函数表示输出一个文件指针,返回这个文件的字符数。

假设我们用Core封装了这个接口,那么我们的测试程序可以是这样:

File *in = fopen("input.txt","r");
int count = 100;
Assert(countChar(in) == count);

当然,这样的测试程序并不充分,希望大家测试时不要像这样偷懒。

第三步:错误处理并设计单元测试###

现在我们封装了接口,我们要对我们的代码进行正确性验证。

另一方面我们都知道健壮性对于软件来说是非常必要的,请各位使用单元测试对项目进行测试,并使用插件查看测试分支覆盖率等指标;另外,请准备至少10个测试用例确保你的程序能够正确处理各种情况,并且不会崩溃。

对待错误的输入,能够尽可能精确报错(就像编译器一样)。

你可以有“容错性”的出错设计,但必须输出必要的提示或说明。

第四步:效能分析###

现在我们已经有了一个基础的词频统计软件,如果它通过了足够多的单元测试,那它可能也已经是一个比较完善的词频统计软件了。但是一个软件光正确了还不够,还需要有一定的性能。

那么,如何让软件又快又好地执行呢?那就需要我们找到执行消耗时间最久的模块,然后不断地优化改进它。那么,如何知道哪些语句是软件的时间瓶颈呢,这就需要用到效能分析。

使用 Visual Studio 进行 C++ 效能分析:https://docs.microsoft.com/en-us/visualstudio/profiling/beginners-guide-to-performance-profiling

使用 JProfiler 进行 Java 效能分析:https://www.cnblogs.com/AmilyWilly/p/7272160.html

关于效能分析的更多资料,可以查看:http://www.cnblogs.com/xinz/archive/2011/11/20/2255809.html

参照“效能测试、分析、改进,再效能测试”的流程,找出关键模块消耗最大的函数,然后分析一下:该如何改进这个程序?

值得注意的一点是,效能分析只在真正有性能问题时才会有显著结果。也就是说,学员在进行效能分析时,可能统计一个只有100行的文件并看不出来有什么差异,也看不出来哪里消耗最大。此时可以使用更大的参数试试,比如统计一个有1000,000行的文件,再使用效能分析工具测试消耗时间最多的模块,再进行改进。

Task4:测试须知##

组织目录###

助教在测试时,将运行自动测试程序编译源文件并运行,进行批量测试,因此请保证项目的组织目录符合要求.

Java####

对于使用Java语言的项目有以下两点要求:

【以学号为名的文件夹中】的目录下必须有src文件夹

  1. 在src目录下必须有名为Main.java文件,且Main.java中包含 public static void main(String[] args) 方法
  2. 一个Java项目的示例组织目录如下所示:
201621123000(文件夹名字为学号,这里以学号201621123000为例)
|- src
|- Main.java(主程序,可以从命令行接收参数)
|- lib.java(包含其它自定义函数,可以有多个,对名字不做要求)

C++####

对于使用C++语言的项目有以下两点要求:

【以学号为名的文件夹中】的目录下必须有src文件夹,在src文件夹中是可在VS2017下编译运行的解决方案,解决方案的名字必须为 WordCount,一个C++工程示例组织目录如下所示:

201621123000(文件夹名字为学号,这里以学号201621123000为例)
|- src
|- WordCount.sln
|- WordCount
|- stdafx.cpp
|- stdafx.h
|- WordCount.cpp
|- WordCount.vcxproj

评分基准##

博客评分###

本次博客作业总分 20分,由以下部分组成:

  1. 在文章开头给出自己的码云项目地址。(1')
  2. 在开始实现程序之前,在下述PSP表格记录下你估计将在程序的各个模块的开发上耗费的时间。(0.5')
  3. 计算模块接口的设计与实现过程。 设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处。(8')
  4. 计算模块接口部分的性能改进。 记录在改进计算模块性能上所花费的时间,描述你改进的思路。(3')
  5. 计算模块部分单元测试展示。 展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。并将单元测试得到的测试覆盖率截图,发表在博客中。(4')
  6. 计算模块部分异常处理说明。 在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。(3')
  7. 在你实现完程序之后,在附录提供的PSP表格记录下你在程序的各个模块上实际花费的时间。(0.5')

程序评分###

本次程序作业总分40分,由以下部分组成:

  1. 正确性(30')
  2. 性能(10')
  • 当程序的正确性评分大于25分时才可以参与性能评分环节,所以请各位同学务必保证自己程序的正确性。
  • 性能评分将采取档级评分制度,助教将根据同学们的程序跑同一数据耗费的时间长度将程序分为若干档,每一档的同学得到的分数为 10/档级数。

注:

  • 如能积极响应助教和老师的反馈并在评论2天内做出相应修改,会在已有评分上有一定加分,但原则上获得分数不超过本次作业总分。
  • 如对分数有意见,只给一次向助教申诉的机会
  • 迟交一周扣实际分数的一半
  • 迟交两周或以上,不给分
  • 抄袭倒扣分

【附录】##

附录1——PSP模板###

PSP模版表格如下,第3列和第4列分别对应第2列条目的估计时间和真实时间,模版表格里的时间只是示意。

PSP2.1 个人开发流程 预估耗费时间(分钟) 实际耗费时间(分钟)
Planning 计划 8 6
· Estimate 明确需求和其他相关因素,估计每个阶段的时间成本 8 6
Development 开发 82 88
· Analysis 需求分析 (包括学习新技术) 6 10
· Design Spec 生成设计文档 5 6
· Design Review 设计复审 4 6
· Coding Standard 代码规范 3 3
· Design 具体设计 10 12
· Coding 具体编码 36 21
· Code Review 代码复审 7 9
· Test 测试(自我测试,修改代码,提交修改) 13 21
Reporting 报告 9 6
· 测试报告 3 2
· 计算工作量 2 1
· 并提出过程改进计划 3 3

附录2——单元测试###

  1. 请根据自己以往积累的测试经验,在编码完成之后,提交产品之前,设计测试用例,并编写单元测试,对自己的项目进行测试。

    • 首先,至少应采用白盒测试用例设计方法来设计测试用例,其他测试方法不限。
    • 其次,要设计至少10个测试用例,确保你的程序能够正确处理各种情况。
    • 最后,结合测试评估的要求,对自己的测试设计进行评价,这些测试用例能满足该程序测试的要求吗?
  2. 另一个重要的措施是要把单元测试自动化,这样每个人都能很容易地运行它,并且可以使单元测试每天都运行。每个人都可以随时在自己的机器上运行。团队一般是在每日构建中运行单元测试的,这样每个单元测试的错误就能及时被发现并得到修改。
  3. 推荐阅读邹欣老师关于单元测试和回归测试
  4. 参考:

附录3——Git操作###

  1. Java培训文档
  2. C++培训文档

软工网络16个人作业2——WordCount的更多相关文章

  1. hel软工网络16个人作业1

    1Task1:注册个人博客账号 1Task2:注册码云账号 1Task3:提出问题 3.1问题一:软件工程是什么? 在第一章中我们可以从P8得到: 1.软件工程就是把系统的.有序的.可量化的方法应用到 ...

  2. 软工网络15个人作业4——alpha阶段个人总结

    软工网络15个人作业4--alpha阶段个人总结 一.个人总结 用自我评价表:http://www.cnblogs.com/xinz/p/3852177.html 总结Alpha冲刺过程. 由于直接用 ...

  3. 软工网络15团队作业4——Alpha阶段敏捷冲刺1.0

    软工网络15团队作业4--Alpha阶段敏捷冲刺1.0 1. 各个成员在 Alpha 阶段认领的任务,以及整个项目预期的任务量(使用整数表示,与项目预估的总工作小时数一致.比如项目A预估需120小时才 ...

  4. 软工网络15团队作业4——Alpha阶段敏捷冲刺2.0

    软工网络15团队作业4--Alpha阶段敏捷冲刺2.0 1.提供当天站立式会议照片一张. 2.每个人的工作 成员 昨天已完成 今天计划完成 郭炜埕 熟悉微信web开发者工具 完成新建话题界面的设计 郑 ...

  5. 软工网络15团队作业4——Alpha阶段敏捷冲刺3.0

    软工网络15团队作业4--Alpha阶段敏捷冲刺3.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 成员 昨天已完成 今天计划完成 郭炜埕 ...

  6. 软工网络15团队作业4——Alpha阶段敏捷冲刺4.0

    软工网络15团队作业4--Alpha阶段敏捷冲刺4.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 成员 昨天已完成 今天计划完成 郭炜埕 ...

  7. 软工网络15团队作业4——Alpha阶段敏捷冲刺6.0

    软工网络15团队作业4--Alpha阶段敏捷冲刺6.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 成员 昨天已完成 今天计划完成 郭炜埕 ...

  8. 软工网络15团队作业4——Alpha阶段敏捷冲刺8.0

    软工网络15团队作业4--Alpha阶段敏捷冲刺8.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 2.1 任务完成安排: 成员 昨日已完成 ...

  9. 软工网络15团队作业1——团队组队&展示

    一.团队展示 1.队名:想不出队名 2.队员学号(标记组长) 201521123064 郭炜埕 201521123066 郑晓丽 201521123067 廖怡洁 201521123068 包梦榕 2 ...

随机推荐

  1. MFC里面解析json文件格式

    CString strTemp; //CString ->string; string stringMsg = (LPCSTR)(CStringA)strTemp; //string -> ...

  2. VirtualBox 克隆后 IP 地址相同(DHCP 分配),如何变更MAC以获取不同的IP?

    由于需要做实验需要两个相同环境的虚拟机,在linux下使用virtualbox最小化安装centos6.0,并克隆了一个相同的,联网模式为桥接,修改配置文件之后重启网络发现二者的网络信息相同,所获取的 ...

  3. 3.在自己的bag上运行Cartographer ROS

    1.验证自己的bag cartographer ROS提供了一个工具cartographer_rosbag_validate来自动分析包中的数据.在尝试调试cartographer之前运行这个工具. ...

  4. Springboot+Mybatis 显示sql语句

    在application.properties里添加 logging.level.com.xxx.service=debug com.xxx.service为包路径,一般可以将service层全加上 ...

  5. Java集合:ConcurrentHashMap原理分析

    集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap).这篇文章主 ...

  6. explain 类型分析

    all 全表扫描 ☆ index 索引全扫描 ☆☆ range 索引范围扫描,常用语<,<=,>=,between等操作 ☆☆☆ ref 使用非唯一索引扫描或唯一索引前缀扫描,返回单 ...

  7. 做到让DBCP连接池不超时

    前些天部署了一个项目,但每次隔一段时间打开都会报如下所示的错误:  javax.servlet.ServletException: org.springframework.transaction.Ca ...

  8. Unity3D中的生命周期函数

    生命周期函数:需要继承 MonoBehaviour 类才能使用.生命周期函数全部都是由系统定义好的,系统会自动调用,且调用顺序和我们在代码里面的书写顺序无关. 常用的生命周期函数: Awake():唤 ...

  9. [au3]批量输入号码程序

    批量输入号码程序 这个文件可以随时产生一个剪贴板文字的文本文件,以供其他程序读取. 这个程序修改了许多次了,主要是针对网络延迟的问题. 最终找到了解决方案:探测输入的界面的反馈信息,也就是反馈的颜色. ...

  10. WPF学习笔记(6):DataSet更新后台数据库个别列失败的问题

    WPF窗体中建有一个DataGrid,运行后修改各行数据,通过Update方法更新后台数据库.发现在数据库中,其中一列FAcctID(文本型)每次都会变为0,还有一列FDebit(货币型)不能更新,其 ...