一.项目地址
https://git.coding.net/chenxin1998/Arithmetic.git
https://git.coding.net/maleping/Amerithic.git
二.预计完成项目时间(PSP)
PSP2.1 |
任务内容 |
计划共完成需要的时间(h) |
实际完成需要的时间(h) |
Planning |
计划 |
15 |
17 |
· Estimate |
· 估计这个任务需要多少时间,并规划大致工作步骤 |
18 |
20 |
Development |
开发 |
98 |
100 |
·· Analysis |
需求分析 (包括学习新技术) |
52 |
54 |
· Design Spec |
· 生成设计文档 |
22 |
24 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
18 |
20 |
· Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
12 |
16 |
· Design |
具体设计 |
26 |
28 |
· Coding |
具体编码 |
48 |
56 |
· Code Review |
· 代码复审 |
7 |
9 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
18 |
24 |
Reporting |
报告 |
9 |
6 |
·· Test Report |
· 测试报告 |
3 |
2 |
· Size Measurement |
计算工作量 |
2 |
1 |
· Postmortem & Process Improvement Plan |
· 事后总结 ,并提出过程改进计划 |
3 |
3 |
三. 如何进行接口设计*
接口是提供给其他模块或者系统使用的一种约定或者规范。因此接口必须要保证足够的稳定性和易用性。这是设计接口的基本要求。
信息隐藏的意思是让模块仅仅公开必须要让 外界知道的东西,而隐藏其他一切内容。在模块设计的接口设计中,就充分体现了信息隐藏这一原则——接口是模块的外部特征,应当公开;而数据结构、算法、实现体等则是模块的内部特征,应当隐藏。一个模块仅提供有限的接口,接口是模块与外界交互的惟一途径。
耦合是模块之间依赖程度的度量。低耦合意味着模块之间的独立性更好,改变一个模块不会影响其它模块。所以在程序设计中我们采用前后端分离的模式,将出题模块、计算模块、运算符判断模块等均封装到不同的方法中,从而降低程序的耦合度。
四. 计算模块接口的设计与实现过程*
在计算模块中算法的关键是中缀表达式转后追表达式和根据中缀表达式计算结果,其思路大致为从左到右遍历中缀表达式的每一个数字和运算符,如果是数字就输出(即存入后缀表达式),如果是右括号,则弹出左括号之前的运算符,如果优先级低于栈顶运算符,则弹出栈顶运算符加入后缀表达式,并将当前运算符加入后缀表达式,遍历结束后,将栈则剩余运算符弹出。根据中缀表达式计算结果的过程大致是从左到右遍历后缀表达式,遇到数字就进栈,遇到符号,就将栈顶的两个数字出栈运算,运算结果进栈,直到获得最终结果。
五. 计算模块接口部分的性能改进
|
用时 |
使用JProfiler工具分析调试 |
3(h) |
查找影响性能的程序模块 |
3(h) |
性能改进 |
6(h) |
我们在性能分析的过程中花费了比较多的时间。
性能优化涉及面很广。一般而言,性能优化指降低响应时间和提高系统吞吐量两个方面,但在流量高峰时候,性能问题往往会表现为服务可用性下降,所以性能优化也可以包括提高服务可用性。在某些情况下,降低响应时间、提高系统吞吐量和提高服务可用性三者相互矛盾,不可兼得。
一开始的时候,我们用了比较多的正则表达式,发现:正则表达式给人的印象是快捷简便。但是在 N.O.P.E 分支中使用正则表达式将是最糟糕的决定。如果万不得已非要在计算密集型代码中使用正则表达式的话,至少要将Pattern缓存下来,避免反复编译Pattern。最好还是用普通的 char[] 数组或者是基于索引的操作。还有就是使用了大量的泛型,导致的结果是使用了 byte、 short、 int 和 long 的包装类,当我们处于 N.O.P.E. 分支的深处时,应该极力避免使用包装类。这样做的坏处是给GC带来了很大的压力。GC将会为清除包装类生成的对象而忙得不可开交。所以最后优化方法是使用基本数据类型、定长数组,并用一系列分割变量来标识对象在数组中所处的位置。
以下是一些JAVA性能优化的办法:http://www.importnew.com/16181.html
性能分析图:
六. 计算模块部分单元测试展示
部分单元测试代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class AirthmeticwebappseApplicationTests { @Test public void contextLoads() { } }
单元测试覆盖率:
七. 计算模块部分异常处理说明
部分代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.bravedawn.airthmeticwebappse; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class AirthmeticwebappseApplicationTests { @Test public void contextLoads() { } }
八. 界面模块的详细设计过程*
- 生成主页面包括可选择的语言
- 点击start now进入出题界面,跳转到随机生成的题目
- 在出题界面包括时间提示,写答案,以及答案正确错误提示
- 做完题目后可点击提交按钮
- 主页面前端代码展示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Four arithmetic applets</title> <link rel="stylesheet" href="/static/css/style.css"> <script src="/static/js/jquery-3.1.1.js"></script> </head> <body> <!--head part--> <div class="nav"> <p id="flag" th:text="${flag}" hidden></p> <h1 class="head-title">Four arithmetic applets</h1> <select class="lan-select"> <option value ="volvo">English</option> <option value ="saab">简体中文</option> <option value="opel">繁体中文</option> </select> </div> <!--body part--> <div class="content"> <h1 class="ready vertical-center">Are you ready?</h1> <a href="/answer.html"><button class="btn-start vertical-center">Start Now!</button></a> <a href="javascript:void(0);"><button class="btn-start-two vertical-center">See Past Performance!</button></a> </div> <script type="text/javascript"> $(function () { $(".btn-start-two").click(function () { var flag = $("#flag").text(); if (flag === "1"){ location.href = "/result.html" } else{ alert("You did not participate in the test 24 hours ago!"); } }) }) </script> </body> </html>
九. 界面模块与计算模块的对接*
本次结对项目我们做的是web项目。
前端计时部分代码展示:
function formatSeconds(value) { var secondTime = parseInt(value);// 秒 var minuteTime = 0;// 分 var hourTime = 0;// 小时 if (secondTime > 60) {//如果秒数大于60,将秒数转换成整数 //获取分钟,除以60取整数,得到整数分钟 minuteTime = parseInt(secondTime / 60); //获取秒数,秒数取佘,得到整数秒数 secondTime = parseInt(secondTime % 60); //如果分钟大于60,将分钟转换成小时 if (minuteTime > 60) { //获取小时,获取分钟除以60,得到整数小时 hourTime = parseInt(minuteTime / 60); //获取小时后取佘的分,获取分钟除以60取佘的分 minuteTime = parseInt(minuteTime % 60); } } var result = "" + parseInt(secondTime) + "秒"; if (minuteTime > 0) { result = "" + parseInt(minuteTime) + "分" + result; } if (hourTime > 0) { result = "" + parseInt(hourTime) + "小时" + result; } return result; }
网页页面展示
十. 结对照片
十一. 结对编程的优点和缺点
通过这次结对项目,我们觉得结对编程能够带来1+1>2的效果。
结对编程有以下优点:
1.之前一个人做的时候,遇到不懂得问题时,就会陷入迷茫。当两个人一起编程时,有不懂的可以一起讨论,说出自己的意见,也为整个编程过程节约了时间。
2.除此之外,两个人一起合作时就会产生更多更好的想法,可以更好的优化整个项目的设计,遇到问题时可以相互帮助解决问题,效率也比较高。
3.两个人合作还可以发现多方身上的优点,找出自己身上的不足,并能相互监督让彼此变得更好,还可以彼此分享好的学习经验。综上所述,我们认为两个人合作的效率远远大于一个人。
要说结对编程的缺点:
1.我觉得主要在完成项目的过程中,会产生分歧。每个人有每个人自己的想法,如果不能及时解决分歧,达成一致,很有可能演化成矛盾,进而使合作关系破裂,无法完成项目。
2.对于一个有经验的编程人员来说,更习惯于一个人编程。毕竟,在编程的过程中有别人在看的感觉有些奇怪。
小组成员互评:
马乐平:优点:认真细心,勤奋好问,善于思考; 缺点:理解能力欠佳,不善沟通
陈逸璇:优点:对学习充满热情,不怕困难,善于沟通; 缺点:技术还有待提高
十二.实际完成项目时间(PSP)
PSP2.1 |
任务内容 |
计划共完成需要的时间(h) |
实际完成需要的时间(h) |
Planning |
计划 |
15 |
17 |
· Estimate |
· 估计这个任务需要多少时间,并规划大致工作步骤 |
18 |
20 |
Development |
开发 |
98 |
100 |
·· Analysis |
需求分析 (包括学习新技术) |
52 |
54 |
· Design Spec |
· 生成设计文档 |
22 |
24 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
18 |
20 |
· Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
12 |
16 |
· Design |
具体设计 |
26 |
28 |
· Coding |
具体编码 |
48 |
56 |
· Code Review |
· 代码复审 |
7 |
9 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
18 |
24 |
Reporting |
报告 |
9 |
6 |
·· Test Report |
· 测试报告 |
3 |
2 |
· Size Measurement |
计算工作量 |
2 |
1 |
· Postmortem & Process Improvement Plan |
· 事后总结 ,并提出过程改进计划 |
3 |
3 |