软工实践寒假作业(2/2)
软工实践寒假作业(2/2)
这个作业属于哪个课程 | 2021春软件工程实践S班 |
---|---|
这个作业要求在哪里 | 软工实践寒假作业(2/2) |
这个作业的目标 | 1.对《构建之法》有更深的理解 2.学习使用git以及github,指定属于自己的代码规范 |
作业正文 | 作业正文 |
其他参考文献 | 《阅读之法》 |
目录
《构建之法》的深入提问
Q1:
文字引用 | 王村的程序员果冻邀请邻村的姑娘小丽去听音乐会,但是果冻却迟到了,针对不同的层次,小丽会给出不同的反馈。 最外层:行为和结果 果冻你迟到了,让我很着急,我们现在进不了会场,错过了精彩的第一幕表演。 中间层:习惯和动机 果冻你又放我鸽子,你总是不重视我,让我等在外面,让我丢人! 最内层:本质和固有属性 果冻 你太自私了,心理都没有别人!你们男人没有一个好东西! |
---|---|
提出问题 | 虽然这个例子很生动形象地解释了评价别人的三种层次,但如果面对多样化反馈应该怎么处理呢? 比如我在玩的一种游戏会定期返厂一些限时物品,但当返厂物品很丑时,大多数玩家会表示不满. 他们的反馈很简单,就是想要好看的。当然也有喜欢这些物品的玩家,那我应该怎么根据这些反馈调整我的返厂计划呢 |
引用说法 | 在技术团队中,我们的反馈还是要着重于行为和结果,不要贸然深入到习惯和动机、本质。 除非情况非常严峻,需要触动别人内心深处,让别人悬崖勒马。 |
所得经验 | 可以从多个层次分析反馈,通过对反馈的分析改进 |
Q2:
文字引用 | 三明治有两块面包一块肉。 在表达观点时,先使用第一片面包:强调双方的共同点。团队共同的愿景,让对方处于一个安全的环境。 接着把建设性的意见加工成肉片:强调过去你做的不够,不过以后可以做的更好。 最后再来一片面包,呼应开头,鼓励对方把工作做好。 |
---|---|
提出问题 | 三明治反馈法是向别人反馈,表达自己的观点,但我对这个方法的理解是, 它应该用于上级对下级,或者合作伙伴之间的方法,我想知道我的理解是否正确 |
引用说法 | |
所得经验 | 可以在与同学,同事之间使用这种反馈方法,即不失礼又能起到很好的反馈效果。 |
Q3:
文字引用 | 初级软件工程师如何成长? 1、积累软件开发相关知识,提升技术技能(如对具体技术的掌握,动手能力)。 如:Java、C/C++、诊断/提高效能的技术,对某一开发平台的掌握等。 2、积累问题领域的知识和经验(例如:对游戏、医疗或金融行业的了解) |
---|---|
提出问题 | 第2点我不是很理解,这个的意思是需要多了解这些行业中的一些与软件相关的知识吗, 但这不是应该取决于我的工作方向吗,确定了工作方向我才能更多的去了解相关行业 |
引用说法 | |
所得经验 | 其他的建议相当有效,当然这需要在不断的学习和实践中成长 |
Q4:
文字引用 | 现在明白了需要有职业道德和职业规划,但是不知道具体该如何进行规划呢? 1、考级之路(计算机职业资格认证考试和计算机程序设计能力考试) 2、大公司会为软件工程师的职业发展提供完备的规划和支持,参照着给自己制定计划即可。 3、邹欣老师也总结了一些好工程师的自我评价清单,可以根据这个清单进行自我评价,及时补充提高。 |
---|---|
提出问题 | 有没有转行的选项,目前在我的理解中,软件工程师其实工作压力很大,我不确定等三十五岁之后还会不会选择这个行业,我只能在过程中选择是否考级等,选择是否放弃,这么想会不会太没有斗志了 |
引用说法 | |
所得经验 | 会根据自我评价清单考虑未来发展方向 |
Q5:
文字引用 | 通过不断的练习,把低层次的问题都解决了,变成不用经过大脑的自动操作,然后才有时间和脑力解决较高层次的问题。 |
---|---|
提出问题 | 还是不太理解层次的划分,但相信通过之后的学习可以理解 |
引用说法 | |
所得经验 |
WordCount编程
Github项目地址
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
• Estimate | • 估计这个任务需要多少时间 | 5 | 5 |
Development | 开发 | ||
• Analysis | • 需求分析 (包括学习新技术) | 120 | 100 |
• Design Spec | • 生成设计文档 | 10 | 20 |
• Design Review | • 设计复审 | 10 | 15 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
• Design | • 具体设计 | 100 | 110 |
• Coding | • 具体编码 | 300 | 400 |
• Code Review | • 代码复审 | 40 | 60 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 90 |
Reporting | 报告 | ||
• Test Repor | • 测试报告 | 15 | 30 |
• Size Measurement | • 计算工作量 | 20 | 30 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 40 |
合计 | 740 | 930 |
解题思路描述
- 了解所需要掌握的新知识
- github desktop的下载和学习使用
- fork项目
- commit
- Pull Request
- 分析基本需求
- 输入
- 输入文件和输出文件以命令行参数传入。
- 统计文件的字符数(对应输出第一行)
- 只需要统计Ascii码,汉字不需考虑
- 空格,水平制表符,换行符,均算字符
- 统计文件的单词总数(对应输出第二行)
- 至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。
- 统计文件的有效行数(对应输出第三行)
- 任何包含非空白字符的行,都需要统计。
- 统计文件中各单词的出现次数(对应输出接下来10行)
- 最终只输出频率最高的10个。
- 频率相同的单词,优先输出字典序靠前的单词。
- 输出的单词统一为小写格式
- 统计结果输出到output.txt
- 换行使用'\n',编码统一使用UTF-8。
characters: number words: number lines: number word1: number word2: number ...
- 定义函数方法
输出字符数:void countChar(String fileName)
输出单词数:void countWord(String fileName)
输出有效行数:void countLine(String fileName)
输出最多的10个单词及其词频: void countWordFrequency(String fileName)
代码规范制定链接
设计与实现过程
- 实现功能统计字符
一开始在判断汉字时候纠结了很久,后面阅读作业要求发现,输入文件皆为ASCII字码,只需要返回文件字符数就行。 - 实现功能空白行计数
在读取行时进行不为空判断,不为空行数加一
//readLine()方法, 用于读取一行,只要读取内容不为空就一直执行
while ((str = in.readLine())!= null)
{
//每行字符数相加
count_char += str.length();
//当不为空行时,行数加一
if(!str.matches(regxSpace))
count_line++;
- 实现功能单词数
- 先完成了空格分隔,在对分隔后的单词通过正则进行判断是否为四个字母开头
- 判断为单词后,用map对单词数进行统计
- 实现hashmap的不区分大小写统计
//统计单词数并统计单词出现次数
String[]ss = str.split("\\s+|\\W");//表示空格、空行或者非数字字母的正则进行分隔
for(String s:ss)
{
if(s.matches("[a-z,A-Z]{4,}.*")) //判断分割后的字符串是否是四个字母开头的单词
{//map统计这些单词
if(map.containsKey(s.toLowerCase())) //toLowerCase忽视大小写
map.put(s.toLowerCase(), map.get(s.toLowerCase())+1);
else
map.put(s.toLowerCase(), 1);
}
}
- 实现hashmap的优先value排序,value相同时按key字母排序
- 实现词频最大的十个单词的输出
List<String> result = new ArrayList<>();
List<Map.Entry<String,Integer>> list = new ArrayList<>();
list.addAll(map.entrySet());
Collections.sort(list,new Comparator<Map.Entry<String,Integer>>()
{ //对两个value进行比较
public int compare(Map.Entry<String,Integer>e1,Map.Entry<String,Integer>e2)
{
int re = e2.getValue().compareTo(e1.getValue());
if(re!=0)
return re;
else
return e1.getKey().compareTo(e2.getKey());
}
});
//将比较后的结构加入result中
for(int i=0;i<map.size();i++)
result.add(list.get(i).getKey());
- 输出
让以上输出按格式输出
//将所有所需数据输出到文件中
File file = new File("C:\\Users\\ling\\Desktop\\1.txt");
try (PrintWriter output = new PrintWriter(file);) {
output.println("characters:"+count_char);
output.println("words:"+count_word);
output.println("line:"+count_line);
for(int i=0;i<count_Word_Frequency;i++)
output.println(list.get(i).getKey()+":"+list.get(i).getValue());
}
- 规范
将代码规整划分,并进行完整注释
性能改进
本来将统计功能分为字符、行数、单词数、词频等四个函数,但发现分开之后需要进行参数传递和文件重新读入,更繁琐且浪费时间。
改进后将词频列为单独函数容易修改,其他功能不分开节约时间。
单元测试
异常处理说明
在hashmap根据值排序时,List<Entry<String,Integer>>报错,在多次百度求助并尝试后,发现Entry需要添加为Map.Entry。
List<String> result = new ArrayList<>();
List<Map.Entry<String,Integer>> list = new ArrayList<>();
list.addAll(map.entrySet());
心路历程与收获
教训是开始的太晚,没有在作业一布置就开始准备,而是一拖再拖,导致作业的完成相当仓促。过程中遇到的问题也不少,好在可以通过百度和不断尝试中解决问题。
之前有学过git和GitHub的使用,但是没有用过GitHub desktop,使用感觉很好,这让我意识到我应该多去了解一些实用的代码工具。尽管不一定会用到,但当需要使用时,好的工具将会节约大量时间,避免因为工具问题耽误作业工作学习的完成。
这次作业因为想修改单元测试,所以没有及时提交,因小失大,但迟交是我不可推卸的责任。所以我只能调整心态,在迟交的期限里尽量完善我的作业,多拿几分是几分。这次迟交完全是我自己的责任,后悔肯定是有的,但我尽量不沉迷于懊悔的情绪中,要为自己的行为买单,且尽可能地补救。当然,有了这次教训,我会在之后的作业中认真完成,不拖延,用心对待。
同时因为这次作业,对map的使用有了更深的了解,尤其是学习到了优先根据值排序,再对值相同按照key字母排序。当然还有其它一些之前没有完全掌握的知识,也在这次作业中巩固了。
实践的机会有很多,但像软工实践这种有许多优秀老师指导点评的机会不多,我会珍惜这些机会,在下一次的作业中进行更充分的准备。