首页 > 代码库 > 第一、二章作业

第一、二章作业

第一章作业:

1.四则运算生成器(python)

__author__ = ‘Doris‘

 

from random import *

 

def createAnExpression():

    beginNum = 0

    endNum = 100

    a = randint(beginNum, endNum)

    b = randint(beginNum, endNum)

    c = randint(beginNum, endNum)

    d = randint(beginNum, endNum)

 

    opChoice = (" + ", " - ", " * ", " / ")

    op1 = choice(opChoice)

    op2 = choice(opChoice)

    op3 = choice(opChoice)

 

    exp = str(a) + op1 + str(b) + op2 + str(c) + op3 + str(d)

    return exp

 

 

 

if __name__ == "__main__":

    num = 50

    for i in range(0, 50):

        print createAnExpression()

 

 

 

2.软件的“特殊”现象:

         a. 闪退现象:在使用一些游戏软件时,因为内存不足会出现闪退现象,在没有提醒的情况下用户体验较差。

         b. 卡机现象:在部分软件发布新版本时,会出现机器卡死现象,如百度浏览器等,被大家所诟病。出现原因可能为新版本功能紊乱,没有做到很好的测试。

         c. 濒死现象:软件只有最初一个版本,反馈Bug也没有下一步修复,可能原因是开发者不再进行维护,常出现在学校项目中。

        

3.目前流行的源程序版本管理软件有 Microsoft TFS, GitHub, SVN, Hg/Mercurial

 

TFS:由微软提供的团队协作开发工具,集中式

Git:开源的版本控制工具,分散式控制

SVN:集中式控制

Hg:分布式控制

 

 

优点

缺点

TFS

  1. 功能多,除版本管理外,拥有需求管理、Bug管理、部署管理等
  2. 拥有Lock功能,适合大型项目,避免代码提交和改动的冲突
  3. 只从版本管理来说,太过冗杂
  4. 在线式代码管理
  5. 牺牲了个人使用上的效率
 

Git

  1. 速度快
  2. 支持上下游的协同开发
  3. 本地提交+代码库提交
  4. 托管服务器多
  5. 命令参数多,入门较难
  6. 没有较为完善的访问权限控制
  7. 不能单独迁出子树
  8. 版本号太难记
 

SVN

  1. 统一的版本号,
  2. 支持中继资料管理
  3. 自动监测文件系统
  4. 可以checkout单个子树
  5. 操作简单
  6. 上游软件出现新版本,很难迁移
  7. 速度较慢
 

Hg/Mercurial

  1. 线性增长的数字版本号
  2. 操作简单
  3. 速度快
  4. 不支持分支
  5. 速度太慢没有提示
 

 

项目管理软件:

Trac:开源的应用平台,包含wiki和问题跟踪。以面向进度模型为项目管理模型,以里程碑方式进行项目管理。使用python开发,需要环境支持。

Bugzilla:为Unix定制的追踪系统的软件,可以管理软件开发中缺陷的提交、修复、关闭等整个生命周期。

Apple XCode:苹果公司向开发人员提供的集成开发环境,用于建立iOS X和iOS应用。拥有统一的用户界面设计、编码、测试、调试都在一个简单的窗口内完成,编译速度极快。

 

4.软件工程并不是教不会写程序的人开发软件,而是提供一种科学的、有效的开发思想、开发理念、开发模式和开发流程,使得开发团队更有效地工作,提供更可靠的、更优秀的产品。

 

5.天津大学开设有软件工程和计算机科学两个专业:

计算机科学专业侧重于科学,也就是学术,侧重于数学和计算机的具体方向,如图论、图形图像、并行计算等,也有硬件开发等。

软件工程专业侧重于软件开发,如语言类课程、设计模式、操作系统、需求分析、软件体系结构、UML建模语言、软件项目管理等。

两者的主要区别在于软件工程是涉及人类活动的,考虑这个软件做什么,怎么组织团队,怎么完成软件,怎么更好地开发等;而计算机科学则更多地从理论的角度出发,并不直接考虑工程方面的问题。

一句玩笑话是“软工出来的,都是码农;计科出来的,90%码农,10%电工”。

 

6.这种做法是不合适的,并不符合道德规范,不在“软件工程”的研究范围内。

软件工程是有着明确的职业道德要求的,只有当软件在安全、符合规范、通过测试、不降低生活质量、不侵犯隐私、不对环境造成伤害时,我们才认可这个软件,不能以牺牲他人利益来谋求自身利益。程序或者软件本身是没有伦理和道德约束的,但是企业或者程序员是要有自身职业道德要求与素养的,无规矩不成方圆,程序员不能无所控制。

 

7.“中文编程”并不是提升编程效率的武器。首先目前并没有成熟的编译环境;第二、反复切换中英文输入容易引起不易察觉的Bug;第三,英语作为目前编程的公认语言,被大家广泛使用,使用中文编程后,大量的开源项目都难以维持,造成交流上的障碍;第四,中文语言歧义较多,需要定制一系列的规定才能真正应用起来。

 

 

8.已经创建。

 

9.问题:两人结对编程在时间操作中的可行性

敏捷流程相比于增量开发,对于成员个人能力要求太高,是否是主流的开发方法

在目前开发中,尽量避免过多的文档,TFS功能是否太过复杂

目前编程人员频繁跳槽的处理方法

在公司实际开发过程中,使用完整的软件工程思想开发,时间、经济上能否承受

 

10.a.已经完成

  b.“移动物联系统”:项目使用手机等移动设备控制家用电器,作为竞赛项目,成果较好,但是没有推向市场。在竞赛结束后没有进行后期的开发和维护。项目源代码和文档仍有存档,但是由于代码没有备注、文档过于简单,所以再次开发成本较高。

经验和教训:对于较好的软件要进行市场推广;在开发过程中留有较为详细的文档说明和必要的备注,以便于移交给其他人进行继续开发。

对于学好软件工程的建议是:多关注业界信息,了解新的软件工程思想;理论结合实践,在实际开发中,尽量使用软件工程的观念进行开发。

 

11.“software”:1958年,Tukey的论文”The Teaching of Concrete Mathematics”中首次使用software的概念。1953年Richard R.Carhart在备忘录中使用software一词

“software engineering”:1968年在第一个软件工程大会上,NATO首次提出software engineering的概念。

第二章作业:

 

1.(1)

 

 

1(2) MaxSum:

#include <iostream>

 

using namespace std;

 

intarrayMaxSum(int* arr, int n)

{

int sum = arr[0];

inttmp = 0;

 

for(inti=0; i<n; i++)

    {

if(tmp< 0)

tmp = arr[i];

else

tmp += arr[i];

if (sum <tmp)

sum = tmp;

 

    }

return sum;

}

 

int main()

{

intmyArr[100] = {1, -2, 3, 5, -1};

intnum = 5;

intrlt = arrayMaxSum(myArr, num);

cout<<rlt;

return 0;

}

 

1.(3) Reverse Word:

#include <iostream>

#include <cstring>

 

using namespace std;

 

voidswapChar(char &a, char &b)

{

chartmp = b;

    b = a;

    a = tmp;

}

 

voidsentenceSwap(char* str, intsBegin, intsEnd)

{

int low = sBegin;

int high = sEnd;

 

while (low < high)

    {

swapChar(str[low], str[high]);

low++;

high--;

    }

}

 

voidreverseWord(char str[])

{

intlen = strlen(str);

 

sentenceSwap(str, 0, len-1);

 

int s = 0;

int e = 0;

 

for (inti=0; i<len; i++)

    {

        e = i;

if (str[e] == ‘ ‘)

        {

sentenceSwap(str, s, e-1);

            s = e + 1;

        }

if (e == len-1)

        {

sentenceSwap(str, s, e);

        }

    }

}

 

int main()

{

charstr[] = "hosw are you";

reverseWord(str);

cout<<str<<endl;

return 0;

}

 

 

 

1.(4) 鼠标拖动hello world:

Form1.cs:

 

using System;

usingSystem.Collections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Threading.Tasks;

usingSystem.Windows.Forms;

 

namespaceDragLabel

{

publicpartialclassForm1 : Form

    {

public Form1()

        {

InitializeComponent();

        }

 

privatePointmouseOffset;

 

 

privatevoid label1_MouseUp(object sender, MouseEventArgs e)

        {

if (e.Button == MouseButtons.Left)

            {

PointmousePos = Control.MousePosition;

mousePos.Offset(mouseOffset.X, mouseOffset.Y);

                ((Control)sender).Location = ((Control)sender).Parent.PointToClient(mousePos);

            }

        }

 

privatevoid label1_MouseDown(object sender, MouseEventArgs e)

        {

mouseOffset = newPoint(-e.X, -e.Y);

        }

    }

}

 

namespaceDragLabel

{

partialclassForm1

    {

///<summary>

///必需的设计器变量。

///</summary>

privateSystem.ComponentModel.IContainer components = null;

 

///<summary>

///清理所有正在使用的资源。

///</summary>

///<param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>

protectedoverridevoid Dispose(bool disposing)

        {

if (disposing && (components != null))

            {

components.Dispose();

            }

base.Dispose(disposing);

        }

 

        #region Windows 窗体设计器生成的代码

 

///<summary>

///设计器支持所需的方法 - 不要

///使用代码编辑器修改此方法的内容。

///</summary>

privatevoidInitializeComponent()

        {

this.label1 = newSystem.Windows.Forms.Label();

this.SuspendLayout();

//

// label1

//

this.label1.AutoSize = true;

this.label1.Location = newSystem.Drawing.Point(12, 26);

this.label1.Name = "label1";

this.label1.Size = newSystem.Drawing.Size(77, 12);

this.label1.TabIndex = 0;

this.label1.Text = "Hello World!";

this.label1.MouseDown += newSystem.Windows.Forms.MouseEventHandler(label1_MouseDown);

this.label1.MouseUp += newSystem.Windows.Forms.MouseEventHandler(label1_MouseUp);

 

//

// Form1

//

this.AutoScaleDimensions = newSystem.Drawing.SizeF(6F, 12F);

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

this.ClientSize = newSystem.Drawing.Size(284, 261);

this.Controls.Add(this.label1);

this.Name = "Form1";

this.Text = "Form1";

this.ResumeLayout(false);

this.PerformLayout();

 

        }

 

        #endregion

 

privateSystem.Windows.Forms.Label label1;

 

    }

}

 

 

 

 

 

1.(5). 解读成成

         (1) 程序要找的数为:寻找不能被数组中rg[k]和rg[k+1] 整除,但是可以被其他所有数整除的数。

         (2) 首先分析rg的特征:

当n <=15时,n *2 也在数组中,所以n>15.

                       剩下的数字可以分解为16=2*8, 18 = 2*9, 20 = 4*5, 22 = 2*11, 24 = 3*8, 26 = 2*13, 28 = 4*7, 30 = 2*15, 但是因为16=2*8中2是8的因子,所以16去除。

              这样可以筛选出rg[ k ] 和rg[ k+1]为16和17。

       接下来就是求不能被16 和17 整除,但是能整除其余所有数的数字。

       2到31中去除16和17的所有素数为:2 3 5 7 11 13 19 23 29 31

非素数可由素数作为因子相乘得到,其中8=2*2*2, 25=5*5, 27=3*3*3, 为例外情况。

       所以,最小的数为 2^3 * 3^3 * 5^2 * 7 * 11 * 13 *19 * 23 * 29 * 31 =

              2123581660200

(3)  估计时间:

该程序主要包括一个取模和一个判断,如果进入if语句的话,还包括1次加法操作,1~2次判断和一次赋值操作。

加法、判断等操作在几个时钟周期内,除法、取模操作在几十个时钟周期,另外,对64位整数的除法要慢于32位整数。

我们可以假设一次操作需要100个时钟周期。因此4GHz的CPU在1秒内能跑4*10^9 / 100 = 4*10^7 即6.4亿次原子操作,大约是0.03s。

接下来操作的次数:外层循环跑了2123581660200次,内层循环取决于i的情况,当i为奇数的时候,内层最多跑5次即可结束;当i为偶数的时候,大约平均在10次,总的操作执行了2*10^13次。

所以需要 2*10^13 / (4*10^7)* 0.03 = 6000秒,约为100min。

(4)  可以使用CUDA进行GPU加速,将对数组的每个元素的除法分开计算。

 

2. 效能分析的讨论

程序设计大作业大概是3周时间,每天4小时,15* 4 = 60小时。

程序量为1000 ~ 1500 LOC.

本科大作业多为个人项目,所以使用源代码管理的同学较少,一些习惯较好的同学会使用Git管理代码。

完全独立的学生在3-5人左右。

说明了同学们在遇到困难的时候更倾向于”拿来主义”,而不是请求帮助,自己完成;其次,在时间规划上并不好,经常是前面很长时间没有好好写,到了DDL,时间紧迫也就”心安理得”地用他人的作业。

3. 使用List替代ArrayList, 因为ArrayListz在存储或检索值类型时通常发生装箱和取消装箱操作,带来很大的性能耗损。

可以使用性能分析工具Performance analysis tool来观察程序中每一句的时间开销,从而优化程序。

第一、二章作业