软工实践寒假作业(2/2)
这个作业属于哪个课程 | 福大20春软工S班 |
---|---|
这个作业要求在哪里 | 软工实践寒假作业(2/2) |
这个作业的目标 | 新型冠状病毒疫情统计 |
作业正文 | 221701117余嘉宸作业(2/2) |
其他参考文献 | 《Java程序设计》 |
1. Github仓库
个人代码见Github仓库:仓库地址
2. PSP表格
PSP是卡耐基梅隆大学(CMU)的专家们针对软件工程师所提出的一套模型:Personal Software Process (PSP, 个人开发流程,或称个体软件过程)。
看了《构建之法》第二章PSP的描述,看到了软件工程师和普通大学学生在表格上的不同。工程师在“需求分析”和“测试”方面下的功夫较多,但在写程序上花的时间比大学生少,说明一个优秀的程序员提升能力的表现在于,花更少的时间完成代码,花更多的时间测试代码和需求分析。
同时PSP和代码是无关的,不能说你用java一定会比c语言的程序开发工程师会慢,这是完全错误的想法。PSP依赖数据,通过记录各项活动的时间,来追求更高更好的编程习惯和方法。
PSP有三个因素衡量软件开发的工作量和质量:项目大小、花费时间、交付代码的质量。通过对比这几种元素就可以衡量某次软件开发是否成功了。
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 2h | 1.5h |
Estimate | 估计这个任务需要多少时间 | 2h | 1.5h |
Development | 开发 | 55h | 58h |
Analysis | 需求分析 (包括学习新技术) | 2h | 2.5h |
Design Spec | 生成设计文档 | 1h | 1h |
Design Review | 设计复审 | 1.5h | 2h |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 2h | 3h |
Design | 具体设计 | 8h | 5.5h |
Coding | 具体编码 | 20h | 25h |
Code Review | 代码复审 | 10h | 12h |
Test | 测试(自我测试,修改代码,提交修改) | 12.5h | 9h |
Reporting | 报告 | 15h | 16h |
Test Repor | 测试报告 | 2h | 5h |
Size Measurement | 计算工作量 | 1h | 1.5h |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 12h | 9.5h |
合计 | 72h | 75.5h |
3. 解题思路描述
根据作业要求,是要读取日志文件统计疫情情况。首先根据选项,输入需要程序输出的要求,可以获取相应输出的文档。
- 程序语言选择Java实现。
- 在输入的args中,判断字符串,根据不同选项划分不同功能。
- 创建新类,保存省份疫情信息。
- 获取日志文件,按行获取日志内容。
- 分割字符串,通过判断字符串,处理数据增减疫情人数信息。
- 根据选项,筛选输出内容。
- 保存到相应文件中。
- 实现过程中忘记的java语法,我将查找别人的博客,或者查看相应的书籍,再者也可以询问老师同学。
4. 设计实现过程
根据思路解决相应的功能。
5. 关键代码与思路
- 处理命令行参数
private static void dealParameter(Vector<String> vector) {
// TODO Auto-generated method stub
int pos=0;
if(vector.get(0).equals("list"))
{
for(int i = 0;i < vector.size();i ++ )
{
if(vector.get(i).charAt(0) == '-') {
if(vector.get(i).equals("-log"))
{
//System.out.print("-log:");
//System.out.print("interval.elementAt(pos):"+interval.elementAt(pos));
//System.out.print("(pos):"+pos);
for(int j = 0;j < interval.elementAt(pos);j ++ )
{
//System.out.print(vector.get(i+j+1));
inputAddress = vector.get(i+j+1);
}
//System.out.println();
i += interval.elementAt(pos);
pos ++ ;
continue;
}
.....
.equals函数判断字符串,实现相应要求。首先判断“list”,再判断“-”开头的字符串,再计算不定参数的个数。
- 不定输入参数
private static void initialVector() {
// TODO Auto-generated method stub
for(int i = 0;i < vector.size();i ++ )
{
if(vector.get(i).charAt(0) == '-')
{
posVec.add(i);
}
if(vector.get(i).equals("全国")) //如果有全国,则省份个数减一个
{
isOutCountry = true;
countryPos = i;
}
}
if(isOutCountry) //如果有全国,则省份个数减一个
{
posVec.add(vector.size()-1);
}
else
{
posVec.add(vector.size());
}
for(int i = 1;i < posVec.size();i ++)
{
interval.add(posVec.elementAt(i)-posVec.elementAt(i-1)-1);
//System.out.println(posVec.elementAt(i)-posVec.elementAt(i-1)-1);
}
}
处理省份的时候,如果出现要求输出全国的疫情信息的时候,有一个方法可新建一个数组再重新排序,把“全国”放在第一位,这时候后面的下标就需都+1;也可唯独判断“全国”,节省空间。
- 处理日期
try {
dBegin = sdf.parse("2019-12-31");
dEnd = sdf.parse(inputEndDate);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//设置Calendar时间
Calendar calBegin = Calendar.getInstance();
calBegin.setTime(dBegin);
Calendar calEnd = Calendar.getInstance();
calEnd.setTime(dEnd);
//在选择的日期内循环。
while(dEnd.after(calBegin.getTime()))
{
calBegin.add(Calendar.DAY_OF_MONTH, 1);
......
}
根据输入的日期,处理2019-12-31日至输入日期的日志文件,calendar实现日期+1功能。
- 文本按行分割
public static ArrayList<String> FileReadLine(String name)//txt文件按行分割
{
//System.out.println(name);
ArrayList<String> arrayList = new ArrayList<>();
try {
File file = new File(name);
InputStreamReader inputReader = new InputStreamReader(new FileInputStream(file));
BufferedReader bf = new BufferedReader(inputReader);
// 按行读取字符串
String str;
while ((str = bf.readLine()) != null) {
arrayList.add(str);
}
bf.close();
inputReader.close();
} catch (IOException e) {
e.printStackTrace();
}
return arrayList;
}
创建ArrayList数据结构,存储行信息。
6. 单元测试截图和描述
Junit单元测试
所谓单元测试:是测试应用程序的功能是否能够按需要正常运行。单元测试是一个对单一实体(类或方法)的测试。单元测试是每个软件公司提高产品质量、满足客户需求的重要环节。JUnit 是一个 Java 编程语言的单元测试框架。JUnit 在测试驱动的开发方面有很重要的发展,是起源于 JUnit 的一个统称为 xUnit 的单元测试框架之一。JUnit 促进了“先测试后编码”的理念,强调建立测试数据的一段代码,可以先测试,然后再应用。这个方法就好比“测试一点,编码一点,测试一点,编码一点……”,增加了程序员的产量和程序的稳定性,可以减少程序员的压力和花费在排错上的时间。
注意:编写测试类的原则:
(1)测试方法上必须使用@Test进行修饰
(2)测试方法必须使用public void 进行修饰,不能带任何的参数
(3)新建一个源代码目录来存放我们的测试代码,即将测试代码和项目业务代码分开
(4)测试类所在的包名应该和被测试类所在的包名保持一致
(5)测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖
(6)测试类使用Test作为类名的后缀(不是必须)
(7)测试方法使用test作为方法名的前缀(不是必须)
(1)测试ListOut1.txt
测试result文件ListOut1.txt中的命令,将结果拷贝到Vector
/*
输入:list -log G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\ out G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt -date 2020-01-22 -province 福建 河北
输出:
全国 感染患者15人 疑似患者22人 治愈2人 死亡1人
福建 感染患者5人 疑似患者7人 治愈0人 死亡0人
湖北 感染患者10人 疑似患者15人 治愈2人 死亡1人
// 该文档并非真实数据,仅供测试使用
*/
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-date","2020-01-22"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("全国 感染患者15人 疑似患者22人 治愈2人 死亡1人\n");
temp.add("福建 感染患者5人 疑似患者7人 治愈0人 死亡0人\n");
temp.add("湖北 感染患者10人 疑似患者15人 治愈2人 死亡1人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(2)测试ListOut2.txt
测试result文件ListOut2.txt中的命令,将结果拷贝到Vector
/*
输入:list -log G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\ out G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt -date 2020-01-22 -province 福建 河北
输出:
福建 感染患者5人 疑似患者7人 治愈0人 死亡0人
河北 感染患者0人 疑似患者0人 治愈0人 死亡0人
// 该文档并非真实数据,仅供测试使用
*/
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-date","2020-01-22","-province","福建","河北"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("福建 感染患者5人 疑似患者7人 治愈0人 死亡0人\n");
temp.add("河北 感染患者0人 疑似患者0人 治愈0人 死亡0人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(3)测试ListOut3.txt
测试result文件ListOut3.txt中的命令,将结果拷贝到Vector
/*
输入:list -log G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\ out G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt -date 2020-01-23 -type cure dead ip -province 全国 浙江 福建
输出:
全国 治愈4人 死亡3人 感染患者42人
福建 治愈1人 死亡0人 感染患者9人
浙江 治愈0人 死亡0人 感染患者0人
// 该文档并非真实数据,仅供测试使用
*/
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-date","2020-01-23","-type","cure",
"dead","ip","-province","全国","浙江","福建"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("全国 治愈4人 死亡3人 感染患者42人\n");
temp.add("福建 治愈1人 死亡0人 感染患者9人\n");
temp.add("浙江 治愈0人 死亡0人 感染患者0人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(4)测试默认日期、省份、类型
默认不存在province、type、date选项的输出结果。
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("全国 感染患者147人 疑似患者317人 治愈27人 死亡21人\n");
temp.add("福建 感染患者22人 疑似患者38人 治愈3人 死亡0人\n");
temp.add("湖北 感染患者125人 疑似患者279人 治愈24人 死亡21人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(5)测试超出最晚日志日期
要求输入的date必须要在最新的log的日期及之前。
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-date","2020-01-28"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("-date参数错误:日期应在日志最晚日期及之前!");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(6)测试日期不存在
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-date","2020-01-25.7"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("-date参数错误:日期应在日志最晚日期及之前!");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(7)测试只会列出指定选项:全国,浙江,福建
有指定province时,列出指定的省份。
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-province","全国","浙江","福建"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("全国 感染患者147人 疑似患者317人 治愈27人 死亡21人\n");
temp.add("福建 感染患者22人 疑似患者38人 治愈3人 死亡0人\n");
temp.add("浙江 感染患者0人 疑似患者0人 治愈0人 死亡0人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(8)测试重庆多音字问题
之前中文排序的时候遇到了重庆这个多音字到底年chong还是zhong困扰。
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-province","全国","重庆","福建"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("全国 感染患者147人 疑似患者317人 治愈27人 死亡21人\n");
temp.add("重庆 感染患者0人 疑似患者0人 治愈0人 死亡0人\n");
temp.add("福建 感染患者22人 疑似患者38人 治愈3人 死亡0人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(9)测试不列出全国,只会列出重庆,福建
测试不列出全国会不会出错呢?
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-province","重庆","福建"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("重庆 感染患者0人 疑似患者0人 治愈0人 死亡0人\n");
temp.add("福建 感染患者22人 疑似患者38人 治愈3人 死亡0人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(10)测试默认类型的输出顺序
type选项默认时的输出循序是否正确呢?
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt",
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("全国 感染患者147人 疑似患者317人 治愈27人 死亡21人\n");
temp.add("福建 感染患者22人 疑似患者38人 治愈3人 死亡0人\n");
temp.add("湖北 感染患者125人 疑似患者279人 治愈24人 死亡21人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(11)测试指定类型的输出顺序
type选项指定时的输出循序是否正确呢?
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-type","dead","cure"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("全国 死亡21人 治愈27人\n");
temp.add("福建 死亡0人 治愈3人\n");
temp.add("湖北 死亡21人 治愈24人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
(12)测试边界问题:刚好是最晚日期
考虑日期边界问题
String[] args = {
"list","-log","G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\infectstatistic_yjchen\\","-out",
"G:\\java\\eclipse\\eclipse-workspace\\hw2_2\\src\\1\\output.txt","-date","2020-01-27"
};
for(int i = 0;i < InfectStatistic.listType.length;i++)
{
InfectStatistic.listType[i] = 0;
}
temp.add("全国 感染患者147人 疑似患者317人 治愈27人 死亡21人\n");
temp.add("福建 感染患者22人 疑似患者38人 治愈3人 死亡0人\n");
temp.add("湖北 感染患者125人 疑似患者279人 治愈24人 死亡21人\n");
temp.add("// 该文档并非真实数据,仅供测试使用");
try {
new InfectStatistic();
assertEquals(temp, InfectStatistic.main(args));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
7. 单元测试覆盖率优化和性能测试
覆盖率
* Coverage:代码测试覆盖率 * Covered Instructions:覆盖到的指令行 * Missed Instructions:没覆盖的指令行 * Total Instructions:总指令行数性能测试
本次作业采用Jprofiler来测试程序性能。
JProfiler是用于分析J2EE软件性能瓶颈并能准确定位到Java类或者方法有效解决性能问题的主流工具,它通常需要与性能测试工具如:LoadRunner配合使用,因为往往只有当系统处于压力状态下才能反映出性能问题。
1.内存使用情况 Memory profiler
JProfiler的内存视图部分可以提供动态的内存使用状况更新视图和显示关于内存分配状况信息的视图。所有的视图都有几个聚集层并且能够显示现有存在的对象和作为垃圾回收的对象。
点击窗体上面的绿色图标Run GC可以通知JVM进行垃圾回收的动作。即点击Run GC后明显观察到,下图中内存大小减小(垃圾回收不是强制立即执行,只是提醒系统尽快执行)。
堆内存跟踪 Heap walker
2.CPU视图 CPU Views
JProfiler 提供不同的方法来记录访问树以优化性能和细节。线程或者线程组以及线程状况可以被所有的视图选择。所有的视图都可以聚集到方法、类、包或J2EE组件等不同层上。
- 访问树 Call Tree
显示一个积累的自顶向下的树,树中包含所有在JVM中已记录的访问队列。JDBC,JMS和JNDI服务请求都被注释在请求树中。请求树可以根据Servlet和JSP对URL的不同需要进行拆分。 - 热点 Hot Spots
显示消耗时间最多的方法的列表。对每个热点都能够显示回溯树。该热点可以按照方法请求,JDBC,JMS和JNDI服务请求以及按照URL请求来进行计算。 - 访问图 Call Graph
显示一个从已选方法、类、包或J2EE组件开始的访问队列的图。 - 方法统计 Method Statistis
显示一段时间内记录的方法的调用时间细节。.
3.线程视图 Thread Views
JProfiler通过对线程历史的监控判断其运行状态,并监控是否有线程阻塞产生,还能将一个线程所管理的方法以树状形式呈现。
优化
由于覆盖率和输入有关,所以覆盖率只能尽可能的达到高水平,关键就是修改无用的代码,提升覆盖率。同时,覆盖率也不能绝得判断代码的好坏。
检查代码的时候,发现这两个判断语句恒假,故可以删去,可提高覆盖率。
对于排序问题,之前考虑的排序算法,后来考虑到直接排好序就好了hhh。并且已知vector效率低,空间每次都是提前设置两倍,浪费空间,修改vector也提高了程序运行效率。
8. 代码规范
个人代码规范见Github仓库:codestyle.md
9. 心路历程与收获
就如《构建之法》书中描述的的那样,一个程序,刚开始可能只是完成他的功能即可,到后面,程序还要对数据进行操作,这些数据可能是静态的(提示信息,软件图标),有可能是动态的(随机数,网路上下载的数据,用户输入等)。一个复杂的软件还要有合理软件架构、软件设计与实现,还有各个程序文件之间的依赖关系等,还要考虑不同的操作系统,配置管理,还要经过软件测试、软件维护等过程,还要考虑服务器承受能力等等。如此之多需要我们细心考虑的地方,学习这本书就是学习软件的构建过程。
软件工程包括下列领域:软件需求分析、软件设计、软件构建、软件测试和软件维护。其中,一个好的软件通过用户满意度、可靠性、软件流程质量和可维护性衡量。软件工程的三点目标:研发出符合用户需求的软件说明:要通过实际的工作收集、推导、提炼需求,并在软件发布后通过实际数据验证需求的确被满足了;通过一定的软件流程,在预计的时间内发布“足够好”的软件说明:这个软件不是期末前两天由两三个同学熬通宵赶出来的急就章,而是经历了一定的软件流程,通过全体团队成员的努力,在一个学期内逐步完成的;并通过数据和其他方式展现所开发的软件是可以维护和继续发展的说明:例如,对用户需求有详细的分析,包括对将来这类软件发展的趋势的分析。
《构建之法》谈到了如何从初级软件工程师一步步成长:积累软件开发相关的知识,提升技术技能(如对具体技术的掌握,动手能力)、积累问题领域的知识和经验(例如:对医疗或金融行业的了解)、对通用的软件设计思想和软件工程思想的理解、提升职业技能(区别于技术技能,例如说自我管理的能力,表达和交流的能力,与人合作的能力,按质按量完成任务的执行力,这些能力在IT行业和其他行业都很重要)。掌握了这些技巧,这样才能步步高升,稳中求胜。
还有一项特别重要,就是合作,也就是结对编程。
一入学老师就教导我们,软件开发不是鹤立鸡群而是携手并进。 结对编程是个渐进的过程——有效率的结对编程不是一天就能做到的。结对编程是一个相互学习、相互磨合的渐进过程。开发人员需要时间来适应这种新的开发模式。一开始,结对编程很可能不比单独开发效率更高,但是在度过了学习阶段后,结对编程小组的开发质量、开发时间通常比两人单独开发有明显的改善。
代码规范在个人编程,以及团队编程中启到很重要的步骤,优雅的代码会让别人对你赞不绝口,丑陋的代码会让别人很难看懂,甚至自己也很难看懂。不利于维护,而且也会被上司骂。所以要形成自己的代码规范,并且遵循他。
代码复审,第一次接触这个词。代码复审的正确定义:看代码是否在“代码规范”的框架内正确地解决了问题。复审在于找出错误,也就是找bug,无论是自我复审还是团队复审,都要有一种复审机制,免得容易考虑不具体,bug众多。
敏捷编程。
什么是“敏捷编程”?“敏捷流程”是一系列价值观和方法论的集合。步骤大概就是,找项目,分配任务,每日例会报告目标和完成的任务,和自己遇到的问题。
MSF是微软解决方案框架。MSF过程模型是从传统的软件开发瀑布模型和螺旋模型发展而来的。MSF过程模型的基本元素是阶段和里程碑。所谓“阶段”,就是在这一段时间里团队集中精力做某一类事情,每个阶段的结束都代表了项目的进展和团队工作重心的变化。 比如在“开发阶段”结束后,团队就不再允许设计/实现新的功能,除非有理由充分的“变更请求”。
10. 技术路线图相关的5个仓库
(1)仓库1:Servlet
名称 | servlet3-showcase(servlet3示例) |
---|---|
链接 | 仓库链接 |
简介:通过JavaEE 7,其中包含Servlet3.1规范,通过本例学习JavaEE的知识点。其中包括了web模块化,可以将一个项目分成N个模块,然后装配。通过Maven,简单介绍了一些Maven基础知识。 |
(2)仓库2:Django
名称 | DjangoBlog(基于Django的博客系统) |
---|---|
链接 | 仓库链接 |
简介:基于python 3.6和Django 2.1实现的博客系统,能实现简单文章、页面、标签目录的增删改查,完善的评论功能,邮件提醒,缓存自动刷新,标签云,图床功能等。 |
(3)仓库3:Ruby
名称 | ruby(The Ruby Programming Language [mirror]) |
---|---|
链接 | 仓库链接 |
简介:介绍Ruby语言。开源的,类似服务器端语言python,可以嵌入到超文本标记语言HTML,语法简单,可扩展性强,大程序易于维护,支持GUI工具,有丰富的内置函数。 |
(4)仓库4:Vue
名称 | vue2-manage(基于 vue + element-ui 的后台管理系统) |
---|---|
链接 | 仓库链接 |
简介:Vue.js是一套构建用户界面的渐进式框架,与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,方便与第三方库或既有项目整合。该项目是 vue + element-ui 构建的后台管理系统,是后台项目node-elm 的管理系统,所有的数据都是从服务器实时获取的真实数据,具有真实的注册、登陆、管理数据、权限验证等功能。 |
(5)仓库5:go语言
名称 | Go-Blog-In-Action(Go语言博客实践) |
---|---|
链接 | 仓库链接 |
简介:Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。该仓库主要是以书的形式,来进行博客实践教学。 |