软工实践寒假作业(2/2)
作业基本信息
这个作业属于哪个课程 | 2021春软件工程实践|S班 (福州大学) |
---|---|
这个作业要求在哪里 | 软工实践寒假作业(2/2) |
这个作业的目标 |
|
作业正文 | 作业正文 |
其他参考文献 |
CSDN
, GitHub |
part1:阅读《构建之法》并提问
敏捷开发的各个阶段所占时间比例是怎么分配的呢?
我在书中和网上了解到敏捷开发的原则和流程,例如如果可用的软件和完备的文档只能选其一,那么按照敏捷开发的做法,可用的软件更加重要,但我对于敏捷开发具体的时间分配还不清晰,时间的分配有成熟的标准吗,还是根据实际情况具体分析?
《构建之法》中说到单元测试必须由最熟悉代码的人来写,我觉得很有道理,但有没有这样一种可能,如果写代码的人员本身在思维上有一些误区,而代码正是由他来写,那么这些错误会一直被保留到最后而不容易被发现?
所以除了写代码的人之外,是否还需要其他人站在更客观的角度测试呢?
如何根据项目情况,选择合适的团队模式呢?
什么样的项目适合敏捷开发?敏捷开发适合所有的项目吗?
现阶段测试人员需要具备什么样的技能?对测试人员的要求和对开发人员的要求有什么不同吗?
测试人员是否不需要具备代码能力,对于测试人员来说比较重要的技能是哪方面的呢?
附加题
为什么键盘不是按照字母顺序排列的?
大家都知道,现在我们通用的键盘是按照英文字母QWERTY排列的。可是很多人却不知道,这样的字母布局最初并不是为了让打字速度更快,而是为了让打字速度慢下来。这个反智的发明是一个叫Scholes的美国人的创举。早期机械打字机依靠按键驱动后方的字锤进行操作,如果输入过快,前一个字母的字锤还未完全弹起,后面一个字母的字锤就已经落下,相邻键杆就会撞在一起而发生卡壳。于是,Scholes把常用字母安排在了不顺手的地方,这样就能减慢打字员的速度,击节连杆也就不会卡住了。有趣的是:据说设计的时候特意把打字机Typewriter的字母全放在顶排,所以销售展示的时候可以用极快的速度打出Typewriter而不卡机。
part2:WordCount编程
Github项目地址
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
30 | 30 | ||
Development | 开发 | 960 | 1425 |
60 | 45 | ||
30 | 30 | ||
30 | 50 | ||
60 | 100 | ||
60 | 90 | ||
300 | 450 | ||
180 | 300 | ||
240 | 360 | ||
Reporting | 报告 | 90 | 100 |
30 | 30 | ||
30 | 30 | ||
30 | 40 | ||
合计 | 1080 | 1555 |
解题思路描述
- 分模块实现基本功能
- 考虑细节问题
- 正确性验证
- 性能优化
- 代码简洁美观
代码规范制定链接
设计与实现过程
统计文件的字符数
//统计文件的字符数
int countChar(FILE *fp,char *argv){
int others=0;
char ch;
int cntChar=0;
while((ch=fgetc(fp))!=EOF){
if(isascii(ch))
cntChar++;
else {
others++;
}
}
if(others>0){
printf("文本含非ASCII字符\n");
}
//统计文件的字符数
ofstream output(argv, ios::app);
output<<"字符个数为"<<cntChar<<std::endl;
// printf("字符个数为%d\n",cntChar);
return cntChar;
}
//判断是否为ASCII字符
int isascii(char ch){
return(ch>=0 && ch<=127);
}
统计文件的有效行数
//统计文件的有效行数
//任何包含非空白字符的行,都需要统计
int countRow(FILE *fp,char *argv){
int row=0;
char ch;
int cntChar=0;
while((ch=fgetc(fp))!=EOF){
if(!isspace(ch)) {
cntChar++;
}
if(ch=='\n' && cntChar!=0){
row++;
cntChar=0;
}
}
if(cntChar!=0){
row++;
cntChar=0;
}
//统计文件的有效行数
ofstream output(argv, ios::app);
output<<"有效行数为"<<row<<std::endl;
// printf("有效行数为%d\n",row);
return row;
}
统计文件的单词总数
//统计文件的单词总数
int countWord(FILE *fp,char *argv){
char ch;
//单词总数、字母总数、数字总数
int cntWord,cntAlpha,cntNum;
cntWord=cntAlpha=cntNum=0;
//标志cntWord是否已经加一
int increase=0;
while((ch=fgetc(fp))!=EOF){
if(isalnum(ch)){
if(isdigit(ch)){
cntNum++;
//出现数字,则将cntAlpha清零
cntAlpha=0;
}
else if(isalpha(ch)){
cntAlpha++;
if(isWord(cntAlpha,cntNum,increase)) {
cntWord++;
increase=1;
}
}
}
//遇到非字母数字的字符,将cntNum,cntAlpha清零
else{
cntNum=cntAlpha=increase=0;
}
}
//统计文件的单词总数
ofstream output(argv, ios::app);
output<<"单词总数为"<<cntWord<<std::endl;
// printf("单词总数为%d\n",cntWord);
return cntWord;
}
//判断是否为单词
int isWord(int cntAlpha,int cntNum,int increase){
//字母连续出现4次,前面没有数字且此单词尚未计入总数
return(cntAlpha>=4 && cntNum==0 && increase==0);
}
统计文件中各单词的出现次数
//统计文件中各单词出现的次数
void top10(FILE *fp,FILE *fp1,char *argv){
//按频次排序
map<int,string>mapSorted;
//按字典序排序
map<string,int>mapCmp;
//...
}
性能改进
- 使用C++标准容器Map
- 删除冗余代码,避免重复计算
单元测试
异常处理说明
- 区分了ASCII字符与其他字符,以便于统计字符数目。
- 对行末换行符及其他特殊字符做了处理。
心路历程与收获
- 这次作业花费了很多时间来完成,但收获颇丰,也算是对快遗忘的知识点的巩固。
- 经过这样一次完整的作业,才能明白有压力才会有动力。
- 了解单元测试和回归测试,感受到单元测试的作用以及必要性。