程序开发——结对编程

结对组合

学号1:211606367 姓名:林恩       学号2:211606445 姓名:肖志豪

一、预估与实际

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 10 10
• Estimate • 估计这个任务需要多少时间 10 10
Development 开发 420 750
• Analysis • 需求分析 (包括学习新技术) 30 20
• Design Spec • 生成设计文档 60 20
• Design Review • 设计复审 10 10
• Coding Standard • 代码规范 (为目前的开发制定合适的规范) 10 10
• Design • 具体设计 60 60
• Coding • 具体编码 200 250
• Code Review • 代码复审 20 30
• Test • 测试(自我测试,修改代码,提交修改) 30 350
Reporting 报告 60 50
• Test Repor • 测试报告 40 30
• Size Measurement • 计算工作量 10 10
• Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 10 10
合计 490 810

二、需求分析

我通过网上查询的方式了解到:

(1)小学一年级数学有如下的几个特点:

  • 特点1:掌握100以内加减法

  • 特点2:未学习小数和负数

    经过分析,我认为,这个程序应当:

  • 加法和减法使用的数字小于100(加法计算结果也不能超出)

  • 小学还未学习负数(减法计算结果也不能出现负数)

  • 小学一年级尚未学习乘除,所以四则运算暂时不做乘除运算。

(2)小学二年级数学新增如下的几个特点:

  • 特点1:掌握乘法口诀表

  • 特点2:10以内的除法

    经过分析,我认为,这个程序更新后应当:

  • 加法和减法使用的数字小于100(加法计算结果也不能超出)

  • 小学还未学习负数(减法计算结果也不能出现负数)

  • 乘法和除法使用的数字小于10(乘法计算结果可以超出)

(3)小学三年级数学新增如下的几个特点:

  • 特点1:加减乘除四则混合运算

  • 特点2:乘除运算拓展为100以内的乘除

  • 特点3:四则运算中除法不能有余数

  • 特点4:学习了小括号的使用

经过分析,我认为,这个程序再次更新后应当:

  • 一二年级的功能保留

  • 四则混合运算中运算符在 2~4 个

  • 四则混合运算中可以加括号

  • 除法运算除数不能为0,不能有余数

  • 括号须有意义,并不能是无意义括号

  • 运算结果不超过10000

三、设计

1. 设计思路

这个程序就一个类,九个函数,其中4个为公共的函数,5个为私有函数。main函数接收输入的信息,之后调用check函数检查输入的信息是否有误(其中分别去调用checkFormat函数和checkData函数分别检查输入的信息在格式和数据上是否有误),有误给出提示,无误则继续调用create函数创建out.txt输出文件。最后调用work函数出题和给出答案(调用answer函数)。类图:

流程图:

2. 实现方案

  • 准备工作:先在Github上创建仓库,克隆到本地,在eclipse上编写代码。

  • 技术关键点:梳理一下设计思路,可能遇到哪些技术关键点

    • 命令行参数输入

    • 参数正则匹配

    • 重定向输出到文件

    • 生成四则混合运算式

    • 求解四则混合运算式

  • 算法:调度场算法与逆波兰表达式。

    • 学习參考:逆波兰表达式

    • 有篇博客整理得很好

    • 这里有分步演示调度场算法

    • 在这里我就用思维导图更直观的展示下调度场算法的过程

四、编码

1. 调试日志

首先,在写answer函数遍历题目字符串过程中,为了防止23这类数字被拆成2和3,我用一个字符串保存,当下个不为数字时,再把这字符串压入栈中。这里问题就是当最后以数字结尾的题目,最后一个数字下个已经没有符号了,在一次次的debug下发现了这个问题,所以我就加了一个判断是否已经扫描到最后的if语句解决了这个问题。

其次,在生成题目的过程中,对于括号的随机生成不好把握,但是由于运算符最多4个(这里我把括号也算成运算符)所以有括号的题目是固定的。即 (a op b)op c 和 a op(b op c)两种情况,这样会简单很多。

最后,在判定题目生成是否符合规范中,思路是不符合规范就退出循环重新生成,在运行事老是出错,在和搭档谈论和debug后发现原来有的判定是要跳出外层循环。在上网学习了通过标记循环来控制跳出的地方后,这问题也就解决啦。

2. 关键代码

/*** 出题函数 * 根据输入的年级和题数生成对应题目,并打印题目和最后答案*/
public static void work() {int num1, num2, answer, op;Random rand = new Random();// src:题目字符串。 result:答案字符串。lineBreak:换行字符串。String src = "";String result = "";String lineBreak = "\r\n";// 标记为为外层循坏,以便continue退出。outerLoop: for (int i = 1; i <= n; i++) {if (grade == 1) {num1 = rand.nextInt(101);num2 = rand.nextInt(101);// 一年级只有加减,所以运算符随机生成数为0和1op = rand.nextInt(2);// 符合条件则计算答案if (op == 0 && num1 + num2 <= 100) {answer = num1 + num2;} else if (op == 1 && num1 - num2 > 0) {answer = num1 - num2;} else {// 不符合条件则退出本次循环,并i--重新生成这一题i--;continue;}// 将题目添加到题目字符串,答案添加到答案字符串中src += "(" + i + ") " + num1 + operator[op] + num2 + lineBreak;result += "(" + i + ") " + num1 + operator[op] + num2 + " = " + answer + lineBreak;} else if (grade == 2) {// 二年级涉及乘除,所以运算符随机生成数为0到3op = rand.nextInt(4);if (op < 2) {// 加减为百以内的加减num1 = rand.nextInt(101);num2 = rand.nextInt(101);} else {// 乘除为表内乘除,所以取值范围是0到10num1 = rand.nextInt(11);num2 = rand.nextInt(11);}// 符合条件则计算答案if (op == 0 && num1 + num2 <= 100) {answer = num1 + num2;} else if (op == 1 && num1 - num2 >= 0) {answer = num1 - num2;} else if (op == 2 && num1 * num2 <= 100) {answer = num1 * num2;} else if (op == 3 && num2 != 0) {answer = num1 / num2;} else {// 不符合条件则退出本次循环,并i--重新生成这一题i--;continue;}// 将题目添加到题目字符串中src += "(" + i + ") " + num1 + operator[op] + num2 + lineBreak;// 将答案添加到答案字符串中,如果是除法要考虑是否有余数if (op != 3)result += "(" + i + ") " + num1 + operator[op] + num2 + " = " + answer + lineBreak;else {if (num1 % num2 != 0)result += "(" + i + ") " + num1 + operator[op] + num2 + " = " + answer + "..." + (num1 % num2)+ lineBreak;elseresult += "(" + i + ") " + num1 + operator[op] + num2 + " = " + answer + lineBreak;}} else {// 三年级,新增功能num1 = rand.nextInt(101);// 这里answer变量不是用来存储结果,而是用来存储上一轮的第二个随机生成数。answer = num1;// isBracket随机生成数0和1,用来存储是否有括号,0没有括号,1有括号。int isBracket = rand.nextInt(2);if (isBracket == 0) {// opNum随机生成数2到4,用来存储运算符个数int opNum = rand.nextInt(3) + 2;// 定义一个字符串,用来存储这一题的题目生成,初始化为第一个随机生成数String str = num1 + "";// 标记为为内层循坏,以便continue退出。innerLoop: for (int j = 1; j <= opNum; j++) {op = rand.nextInt(4);num2 = rand.nextInt(101);// 不符合题目生成规则则退出本次循环,并j--重新生成运算符和第二个随机生成数if (op == 0) {if (num1 + num2 >= 1000) {j--;continue innerLoop;}} else if (op == 1) {if (num1 - num2 < 0) {j--;continue innerLoop;}} else if (op == 2) {if (answer * num2 > 1000) {j--;continue innerLoop;}} else if (op == 3) {if (num2 == 0 || answer % num2 != 0) {j--;continue innerLoop;}}// 符合题目生成条件,先计算这步结果,如果这步结果是负数或者超出小学生三年级范围,退到外层循环,并i--重新生成这题String s = str + operator[op] + num2;num1 = Integer.parseInt(answer(s));if (num1 < 0 || num1 > 10000) {i--;continue outerLoop;}// 结果也符合,将这步添加到题目str += operator[op] + num2;answer = num2;}// 最后将生成的题目添加到题目字符串和答案字符串中src += "(" + i + ") " + str + lineBreak;result += "(" + i + ") " + str + " = " + answer(str.substring(str.indexOf(')') + 1)) + lineBreak;} else {// 最多四个运算符,有括号的情況有:// (a op b)op c 和 a op(b op c)// 所以从括号的位置可以分为 在前和在后,随机生成括号位置site,0在前,1在后int site = rand.nextInt(2);if (site == 0) {// 定义一个字符串,用来存储这一题的题目生成,初始化为 "("+第一个随机生成数String str = "( " + num1;// 由于括号在前,括号内的运算符只需加减即可,乘除加括号没有意义(都需从左到右计算)op = rand.nextInt(2);num2 = rand.nextInt(101);// 同理,不符合题目生成规则则退出循环,并i--重新生成题目if (op == 0) {if (num1 + num2 >= 1000) {i--;continue outerLoop;}} else {if (num1 - num2 < 0) {i--;continue outerLoop;}}// 符合就添加到str中str += operator[op] + num2 + " )";num1 = Integer.parseInt(answer(str));// 括号外边的运算符为乘除,否则括号加了没有意义op = rand.nextInt(2) + 2;// 同理,判断是否符合题目生成规则if (op == 2) {if (num1 * num2 > 1000) {i--;continue outerLoop;}} else {if (num2 == 0 || num1 % num2 != 0) {i--;continue outerLoop;}}str += operator[op] + num2;num1 = Integer.parseInt(answer(str));if (num1 < 0 || num1 > 10000) {i--;continue outerLoop;}// 将题目和答案分别添加到题目字符串和答案字符串中src += "(" + i + ") " + str + lineBreak;result += "(" + i + ") " + str + " = " + answer(str) + lineBreak;} else {// 括号在后,逻辑和括号在前类似op = rand.nextInt(2);num2 = rand.nextInt(101);if (op == 0) {if (num1 + num2 >= 1000) {i--;continue outerLoop;}} else {if (num1 - num2 < 0) {i--;continue outerLoop;}}String str = "( " + num1 + operator[op] + num2 + " )";num2 = Integer.parseInt(answer(str));op = rand.nextInt(2) + 2;num1 = rand.nextInt(101);if (op == 2) {if (num1 * num2 > 1000) {i--;continue outerLoop;}} else {if (num2 == 0 || num1 % num2 != 0) {i--;continue outerLoop;}}str = num1 + operator[op] + str;num1 = Integer.parseInt(answer(str));if (num1 < 0 || num1 > 10000) {i--;continue outerLoop;}src += "(" + i + ") " + str + lineBreak;result += "(" + i + ") " + str + " = " + answer(str) + lineBreak;}}}}System.out.println(src);System.out.print(result);
}/*** 解题函数* 根据给出的题目通过调度场算法和逆波兰表达式的思路得出计算结果* @param src 参数是带求解的题目字符串* @return 返回值是一个字符串:最后结果*/
private static String answer(String src) {// 定义两个栈,用来存储数字和运算符,即输出栈和符号栈Stack<String> print = new Stack<String>();Stack<String> operator = new Stack<String>();// 去掉题目中的空格String str = src.replace(" ", "");// 定义一个number字符串,用来存储数字,不会将数字拆分,例如23不会拆成2和3String number = "";// 遍历字符串str,是数字添加到输出栈,是符号就和符号栈栈顶元素比较优先级for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);if (c >= '0' && c <= '9') {number += c + "";// 如果到达最后,将number入栈(输出栈),同时将number清空if (i + 1 >= str.length()) {print.push(number);number = "";}} else {// 如果number里有数字,将number入栈(输出栈),同时将number清空if (!number.isEmpty()) {print.push(number);number = "";}// 如果当前符号(1)是左括号或者(2)符号栈为空或者(3)当前符号优先级>栈顶符号优先级,直接入栈if (c == '(' || operator.isEmpty() || comparePriority(c + "", operator.peek()) == 1) {operator.push(c + "");} else if (c == ')') {// 如果当前符号为右括号,需要出栈直到遇到第一个左括号为止。String stackTop = operator.pop();while (!stackTop.equals("(")) {// 出栈的时候,同时进行逆波兰表达式的计算,取出输出栈的前两个数int number1 = Integer.parseInt(print.pop());int number2 = Integer.parseInt(print.pop());int number3;// 按出栈的符号计算得出结果number3if (stackTop.equals("+")) {number3 = number2 + number1;} else if (stackTop.equals("-")) {number3 = number2 - number1;} else if (stackTop.equals("×")) {number3 = number2 * number1;} else {number3 = number2 / number1;}// 并将结果入栈(输出栈)print.push(number3 + "");stackTop = operator.pop();}} else if (comparePriority(c + "", operator.peek()) != 1) {// 如果当前符号优先级<=栈顶符号优先级,需要出栈直到当前符号优先级>栈顶符号优先级为止while (!operator.empty() && comparePriority(c + "", operator.peek()) < 1) {// 同理,出栈的时候,同时进行逆波兰表达式的计算,取出输出栈的前两个数int number1 = Integer.parseInt(print.pop());int number2 = Integer.parseInt(print.pop());int number3;// 按出栈的符号计算得出结果number3String stackTop = operator.peek();if (stackTop.equals("+")) {number3 = number2 + number1;} else if (stackTop.equals("-")) {number3 = number2 - number1;} else if (stackTop.equals("×")) {number3 = number2 * number1;} else {number3 = number2 / number1;}// 并将结果入栈(输出栈)print.push(number3 + "");stackTop = operator.pop();}// 最后将当前符号入栈(符号栈)operator.push(c + "");}}}// 最后需要将符号栈中的符号依次出栈,同时进行逆波兰表达式计算while (!operator.empty()) {String stackTop = operator.pop();int number1 = Integer.parseInt(print.pop());int number2 = Integer.parseInt(print.pop());int number3;if (stackTop.equals("+")) {number3 = number2 + number1;} else if (stackTop.equals("-")) {number3 = number2 - number1;} else if (stackTop.equals("×")) {number3 = number2 * number1;} else {number3 = number2 / number1;}print.push(number3 + "");}return print.peek();
}/*** 比较运算符优先级方法* @param a 此参数为其中一个运算符* @param b 此参数为另一个运算符* @return  如果第一个运算符的优先级大于第二个运算符的优先级,返回 1。 *          如果第一个运算符的优先级等于第二个运算符的优先级,返回 0。*          如果第一个运算符的优先级小于第二个运算符的优先级,返回 -1。*/
private static int comparePriority(String a, String b) {if (a.equals(b)) {return 0;} else if (Priority(a) > Priority(b)) {return 1;} else if (Priority(a) < Priority(b)) {return -1;} else {return 0;}
}/*** 查询运算符优先级方法* @param op 参数为待查询的运算符* @return 返回运算符的优先级*/
private static int Priority(String op) {if (op.equals("×") || op.equals("÷")) {return 2;} else if (op.equals("+") || op.equals("-")) {return 1;} else {return 0;}
}/*** 检查函数 检查输入的参数是否符合标准* @param s 参数是 输入的字符串* @return 如果输入的参数符合标准,返回true;否则返回false。*/
public static boolean check(String[] s) {if (checkFormat(s)) {if (s[0].equals("-n"))return checkData(s[1], s[3]);elsereturn checkData(s[3], s[1]);} else {System.out.println("亲,输入格式错误哦");return false;}
}/*** 检查数据函数 由check检查函数调用,在检查中起到检查数据的作用。* @param strN 此参数待检查的题数* @param strGrade 此参数为待检查的年级* @return 如果题数和年级都符合标准,返回true;否则返回false。*/
private static boolean checkData(String strN, String strGrade) {if (!strN.matches("\\d*")) {if (strN.matches("-\\d*")) {System.out.println("输入一个正确的数字哦,不能为负");return false;} else {System.out.println("输入的题数必须是数字!");return false;}} else {n = Integer.parseInt(strN);if (n > 100) {System.out.println("输入的题数过大,体谅下小学生哦");return false;} else if (n == 0) {System.out.println("输入的题数为零,那我还要不要出题呀");return false;}}if (!strGrade.matches("[1-3]")) {System.out.println("对不起,亲,目前只有1到3年级哦");return false;} else {grade = Integer.parseInt(strGrade);}return true;
}/*** 检查格式函数 由check检查函数调用,在检查中起到检查格式的作用。* @param s 参数为待检查的字符串数组* @return 如果输入的字符串数组的格式符合标准,返回true;否则返回false。*/
private static boolean checkFormat(String[] s) {if ((s[0].matches("-n") && s[2].matches("-grade")) || (s[0].matches("-grade") && s[2].matches("-n"))) {return true;} else {return false;}
}

3. 代码规范

请给出本次实验使用的代码规范:

  • 第一条:代码中的命名均不能以下划线或美元符号开始,也不能一下划线或美元符号结束。

  • 第二条:代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。

  • 第三条:注释的双斜线与注释内容之间有且仅有一个空格。

  • 第四条:方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵循驼峰形式。

  • 第五条:杜绝完全不规范的缩写,避免忘文不知义。

  • 第六条:不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。

  • 第七条:大括号的使用约定。如果是大括号内为空,则简介地写成{}即可,不需要换行;如果是非空代码块则:左大括号前不换行。左大括号后换行。右大括号前换行。右大括号后还有 else 等代码则不换行;表示终止的右大括号后必须换行。

  • 第八条:左小括号和字符之间不出现空格;同样的,有小括号和字符之间也不出现空格。详见第5条下面正例提示。

  • 第九条:循环体内,字符串的连接方法,使用StringBuilder的append方法进行扩展。
    并人工检查代码是否符合规范

五、测试

测试用例 预期结果 实际结果
java MathExam6445 - n 100 - gr a de 1 亲,输入格式错误哦 同预期结果
java MathExam6445 -n -grade 100 1 亲,输入格式错误哦 同预期结果
java MathExam6445 -grade -n 1 100 亲,输入格式错误哦 同预期结果
java MathExam6445 -n 100 1 -grade 亲,输入格式错误哦 同预期结果
java MathExam6445 -grade 1 100 -n 亲,输入格式错误哦 同预期结果
java MathExam6445 -n 100000 -grade 1 输入的题数过大,体谅下小学生哦 同预期结果
java MathExam6445 -n -100 -grade 1 输入一个正确的数字哦,不能为负 同预期结果
java MathExam6445 -n 0 -grade 1 输入的题数为零,那我还要不要出题呀 同预期结果
java MathExam6445 -n xzh -grade 1 输入的题数必须是数字! 同预期结果
java MathExam6445 -n 00000000 -grade 1 输入的题数为零,那我还要不要出题呀 同预期结果
java MathExam6445 -n 00000001 -grade 1 通过检查 同预期结果
java MathExam6445 -grade 1 -n 100000 输入的题数过大,体谅下小学生哦 同预期结果
java MathExam6445 -grade 1 -n -100 输入一个正确的数字哦,不能为负 同预期结果
java MathExam6445 -grade 1 -n 0 输入的题数为零,那我还要不要出题呀 同预期结果
java MathExam6445 -grade 1 -n xzh 输入的题数必须是数字! 同预期结果
java MathExam6445 -grade 1 -n 00000000 输入的题数为零,那我还要不要出题呀 同预期结果
java MathExam6445 -grade 1 -n 00000001 通过检查 同预期结果
java MathExam6445 -n 100 -grade -1 对不起,亲,目前只有1到3年级哦 同预期结果
java MathExam6445 -n 100 -grade 0 对不起,亲,目前只有1到3年级哦 同预期结果
java MathExam6445 -n 100 -grade 1 通过检查 同预期结果
java MathExam6445 -n 100 -grade 2 通过检查 同预期结果
java MathExam6445 -n 100 -grade 3 通过检查 同预期结果
java MathExam6445 -n 100 -grade 4 对不起,亲,目前只有1到3年级哦 同预期结果
java MathExam6445 -n 100 -grade xzh 对不起,亲,目前只有1到3年级哦 同预期结果
java MathExam6445 -grade -1 -n 100 对不起,亲,目前只有1到3年级哦 同预期结果
java MathExam6445 -grade 0 -n 100 对不起,亲,目前只有1到3年级哦 同预期结果
java MathExam6445 -grade 1 -n 100 通过检查 同预期结果
java MathExam6445 -grade 2 -n 100 通过检查 同预期结果
java MathExam6445 -grade 3 -n 100 通过检查 同预期结果
java MathExam6445 -grade 4 -n 100 对不起,亲,目前只有1到3年级哦 同预期结果
java MathExam6445 -grade xzh -n 100 对不起,亲,目前只有1到3年级哦 同预期结果

六、总结

这次结对编程有了初次程序开发的经历,各个流程的步骤清晰许多,也能更好的下手,不会像上次那样茫然无措。

总的来说,这次作业带来的问题还是很多的,感触也很深,程序开发的开始,我的斗志还是很高的,毕竟我喜欢沉浸在程序开发过程中,看着自己的作品不断的完善更新,那是有很大的成就感的。一开始,我就和我的搭档开了一个小会(哪怕小会的时间不到5分钟),在小会上经过讨论,分配任务,我的任务是解题,他的任务是出题。解题需要用到调度场算法和逆波兰表达式,这两个高大上的玩意对我来说那是闻所未闻啊,所以,在我逛了许多博客和亲自动手在纸上演算后大致上懂得了其中的思路。剩下的就剩下思路变代码啦。

不得不说,我的搭档的实力还是杠杠的,在我还没打完解题的代码时,他和我说他都打完了(包括我的解题部分),那时我是相当的无语(说好了我负责呢。。。),在我写完解题后,时间还充裕,所以决定开始写出题部分。

出题部分那是相当恶心啊,那比解题难的不是一星半点,数字是随机的,运算符也是随机的,运算符个数也是随机的,是否要加括号括号还是随机的,括号要加在哪里还还还是随机的,随机过后,还要判断是否符合规则。在有了思路尝试变成代码后,那bug一个一个来,debug的过程是一个枯燥乏味的过程,而且当找不到bug是容易焦躁。记得有个广告这么说:“充电五分钟,通话两小时”。我的感觉是:“代码五分钟,调试两小时”。虽然有些夸张,但我的感觉就是调试比代码更耗时更需要耐心。

这里给大家一些个人意见,当你调试一直找不出bug的时候,可以停止调试,放松下,比如听听歌什么的,因为在继续下去还是找不到bug的话,那心情会相当糟糕,甚至会对编程感到厌恶;当你没有思路的时候,可以逛逛博客找些思路,最好不要一开始就看他人的代码,我个人感觉一开始看他人的代码会限制你的代码随着他人的代码走,没有自己的创新。如果看了别人的思路,自己能够实现成代码,那就是你自己的学到东西了。

转载于:https://www.cnblogs.com/xzh0717/p/9672365.html

程序开发——结对编程相关推荐

  1. 项目管理---敏捷开发--结对编程

    首先接触这个词是从师哥的博客中学习到了(看博客的好处啊),由于在人事系统优化过程中一直在敏捷开发的思想下指导开发,学习到了很多新的理念.开发方法.指导思想等等,都是值得在项目的开发中深刻的去体会和运用 ...

  2. Java面向对象程序开发——网络编程入门知识

    目录 七.网络编程入门知识 软件结构 网络通信协议 协议分类 网络编程三要素 TCP通信程序 概述 Socket类 构造方法 成员方法 ServerSocket类 构造方法 成员方法 简单的TCP网络 ...

  3. python编程基础张勇答案_Python程序开发、编程基础阶段试题及答案

    1. 下面关于 pycharm 描述错误的是 (B) A . pycharm 用于我们开发 python 程序的集成工具 B. pycharm 不可以打开已有的项目代码 C. 使用 pycharm 运 ...

  4. JAVA程序开发----网络编程

    1.简述TCP/IP的参考模型层次结构. 一共有4层,分别是物理+数据链路层.网络层.传输层和应用层. 2.举例说说你对IP地址和端口号的理解. 如果把程序当做人,把计算机网络当做类似邮递员的角色,当 ...

  5. 结对编程作业——四则运算GUI程序

    毛忠庆 201421122088 赵嘉楠 201421122065 源代码存放位置:https://gitee.com/ouwen0819/SiZeYunSuan.git 题目描述 使用 -n 参数控 ...

  6. 敏捷软件开发之结对编程

    2019独角兽企业重金招聘Python工程师标准>>> 说明 [作为推荐的最佳实践,结对编程早已为人们熟知,并且也是所有XP实践中争议最大的一个] 结对编程技术是一个非常简单和直观的 ...

  7. 敏捷开发与中医理论系列之二:古法教学(软件教育,松结对编程,师徒制度)...

    由来 中国古代的很多技术或艺术,都是没有学校教授的,譬如中医,戏曲,民间艺术,食品,酿酒--但却不乏流传千古的名家和作品,唯一问题就是流传缓慢,传内不传外,传男不传女--.现在终于有了大学,流传速度应 ...

  8. 程序员curd编程是什么_为什么许多程序员讨厌结对编程?

    结对编程是国外非常盛行的一种敏捷开发方式,今天 Google 最顶级的两位程序员 Jeff Dean 和 Sanjay Ghemawat 就是结对编程世界让人颇为津津乐道的人物.不过,有人喜欢有人讨厌 ...

  9. 敏捷开发“松结对编程”系列之七:问题集之一

    本文是"松结对编程"系列的第七篇.(之一,之二,之三,之四,之五,之六,之七,之八) 刚刚参加完MPD 2011深圳站,在演讲中间及后来媒体采访,被问到了一些问题,也给出了答案,这 ...

  10. 敏捷开发绩效管理之三:个体动力之源——同行压力(松结对编程,师徒制度,跨职能团队,绩效考核)...

    这是敏捷开发绩效管理的第三篇.(之一,之二,之三,之四,之五,之六,之七) 如果有10个程序员,笔者相信至少有9个是勤奋的.但是如果有一个10人的程序员团队,其中1个人不是勤奋的,而且仍然拿到与其他人 ...

最新文章

  1. 说说悲观锁、乐观锁、分布式锁
  2. Mybatis中的collection、association来处理结果映射
  3. 既生瑜何生亮 access_token VS refresh_token
  4. html动画用css还是js,javascript与css3动画结合使用小结
  5. nginx 监听非标准端口80,重定向端口丢失问题解决
  6. java日志系统简介: 从tomcat大量打印debug日志说起
  7. 树莓派入门教程 - 0 - 准备篇 - 0.4 树莓派安装FTP服务器
  8. java apache.poi_Java利用apache的POI操作Excel
  9. CSS hack:区分IE6,IE7,firefox
  10. svn管理ad元件库_AD元器件库服务器管理指南
  11. 微型计算机系统教案,微型计算机硬件系统教案
  12. Windows 资源保护找到了损坏文件,但其中有一些文件无法修复
  13. 从通信的角度理解现场总线
  14. minus 如何实现不去重效果
  15. 关于软件测试未来发展趋势分析与总结
  16. PHP 垃圾回收机制
  17. 用计算机表白我不喜欢你了,绝对看不懂的表白公式(用古文暗示我喜欢你的方式)...
  18. 京东云 - 增值税发票识别
  19. android手机可以设置屏幕锁定,Android手机屏幕锁定设置方法(九个点图案)
  20. Android——adapter解读

热门文章

  1. [NOIP2015] 运输计划(第二弹)
  2. HAproxy的安装配置及动静分离
  3. 根据文件大小搜索电脑文件
  4. IOS音频1:之采用四种方式播放音频文件(一)AudioToolbox AVFoundation OpenAL AUDIO QUEUE...
  5. PHP执行超时的那些事
  6. web测试 结果存储类型为“Database”,但尚未指定结果储存库连接字符串
  7. Xcode连接git@osc
  8. postman本地访问https
  9. Python工程师面试题目
  10. python3.5和python3.6关于json模块的区别