初窥软件工程 2020BUAA软件工程\(\cdot\)个人博客作业
一、作业要求简介
本文是北京航空航天大学计算机学院软件工程课程的个人博客作业。本次作业的主要目标在于,通过通读教材《构建之法》,形成对软件工程这门学问的初步理解,对于不理解的地方,提出困惑之处,在之后这门课程的学习中,通过实践反复印证与体会书中方法,找到问题的答案。
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 博客园班级链接 |
这个作业的要求在哪里 | 个人博客作业 |
我在这个课程的目标是 | 获得成为一名软件工程师的能力 |
这个作业在哪个具体方面帮助我实现目标 | 形成对软件工程的初步理解 |
二、正文
(一) 快速看完整部教材,列出你仍然不懂的5到10个问题
问题1. 单元测试时如何有效拆分单元?输入数据和输出数据如何构造?
书中第二章介绍了单元测试的方法,我在面向对象课程中也使用过java的单元测试,不过仅仅流于形式,象征性完成课程的目标。在做编译课设的时候,也想过没写完一个模块都要做单元测试。但是我发现了一个难点,有时只有最开头的输入数据好构造(甚至可以构造),那么如何对中间一个单元做单元测试?
比如在测试编译器的第一个模块词法分析的时候,构造数据输入就特别容易,因为是第一个模块,直接输入字符串就可以了。但是从第二个模块语法分析开始就麻烦了,它的输入时词法分析的输出,这个输出是我定义的一个Class的实例,只有在跑完词法分析之后才能得到。如果我要对语法分析做单元测试,单元测试代码里就必须先跑词法分析得到输入,这跟直接测试整个程序就一样了,还叫单元测试吗?
除了输入以外,输出也是问题,有些时候,程序的运行结果人脑很难算出来甚至算不出来,我写程序的目的其实就是想把他算出来,那么我怎么能得到正确的输出来测试我的程序呢?比如写编译器时,中间的某些结果靠人脑就要花很长时间的推演。我们通常是靠和其它同学对拍来做测试,但是实际生产中,可能这一个模块只有一个人写,就没法对拍,这种情况下如何方便地得到测试标准结果呢?
还有一个问题就是单元测试要拆分到什么程度?代码短的单元没有测的必要,代码长的单元定位又不精准。我是以函数/方法为单元来测,还是以一个功能块为单元测,尺度如何把握?
问题2. 即使用了源代码管理工具,也很容易忘记某个版本究竟是干什么的,如何更好地通过message提示自己?
书中在讲代码管理的时候,提到要尽可能多的提交当前的修改,哪怕是只改了一个小bug,也要及时提交。我在使用git管理代码的时候,经常遇到这样的情况,在写git commit -m ""的message信息时,总不知道应该写什么,愣了半天写了一句“fix some bugs“或者之类的话。但是这种做法在需要版本回退的时候是非常痛苦的,真的不知道当时修了什么bug,如果去挨个diff分析自己改了什么又很低效。
所以这个message至关重要,但是对我而言有时写message又真的很难用语言表达我所做的修改,有没有什么技巧能够简洁清楚地描述修改了什么、目的是什么从而让版本回退时一目了然?
问题3. 怎么在源代码管理工具中更优雅地改bug?
这个问题是我之前写代码时遇到的,在读书中代码管理时提炼了出来。描述如下:
比如要开发两个连续流程A、B、C、D,顺序开发完ABCD,并commit。在开发完D并commit后,发现A中有bug,此时应该怎么做?是直接在D中改了,不管之前的A的正确性了?还是回退到A,改bug,commit到新的A‘,之后merge A’ 和D保证D的正确性?
分析一下,这两者都不太合理,首先第一种,如果我之后想版本回退,ABC版本都包含这个bug,那时候可能已经忘了这个bug了。第二种只能保证回退到A'是正确的,BC都没法正确回退。那么如果把BC也都改了呢?一个问题的是提交的message怎么写,"B1:B fixed bug xxx"? 假如之后再发现别的bug呢?用B1、B2这么编号好吗?另一个更难搞的是假如AD之间不只有BC,而是有几十个commit咋办?git的管理机制似乎没提供在之前某个提交的版本上修改,后面的提交自动改的方法(或者我不知道hh,git太难了)。事实上按照git的机制我们根本不能修改某次提交,最多是像从A分出一个改过bug的A‘。最终这个commit树就变成这样了,很是蛋疼。
希望通过之后对git的进一步理解,能够更优雅地解决这个问题。
问题4. 多人合作时,如何解决push冲突问题,如书中11.5.4所述
当Apull下来解决merge冲突,并测试无误之后,想要push,发现又有人push过了,这就还得再pull下来,解决冲突,并测试。这个无疑很浪费时间,但是似乎也没办法,书中提到了用一些宽和严的制度来规定这个处理方法。我之前没经历过多人合作开发,实际遇到这个问题时我们应该怎么办呢?
问题5. 如何解决开发基础差的问题?软工课上如何解决?
在11.6的讨论中,如果有队员的基础差怎么办,比如大家要用C#开发,但我不会C#,得现学现用,导致开发效率低,且容易出bug。软工课上要怎么解决这个问题呢?让基础差的同学做PM或者测试吗?他们不愿意怎么办?
问题6. 初创公司如何找到技术创新与营销经营的平衡点?
在阅读第16章创新的时候,书中有这样一个论断,当一个产品要发布的时候,通常都留有一些已知的bug而不去改。一方面原因是产品要即使发布才能有盈利,另一个原因是为下一阶段的产品迭代留有余地,团队会更有干劲。
这里涉及到一个把握平衡的问题,如果你还没有解决一些问题就发布,这个产品可能无法得到用户认可;但是如果一味追求解决所有技术问题,永无止境地做技术创新和技术改进,而不去经营营销,这样又没法盈利。所以现在有不少由技术出身的人办的初创公司面临着这个平衡的问题。有些公司一味地追求改进技术,忽略了经营营销的重要性,这样也是不可取的。那么如何找到这个平衡点呢?希望软件工程课能给我一些体会。
问题7. 软件工程有没有什么解决不了的问题?软件工程的痛点在哪?
读完了整本书,涵盖的内容十分繁杂,设计的领域也非常多,包括计算机,软件,经济,管理,方法论等等。也针对很多特定的问题给出了软件工程的解决方案。那么,有没有软件工程没法解决的问题呢?有没有人类使用了软件工程方法也没法实现出的软件?软件行业目前面临的痛点在哪?软件工程应该针对这些痛点提出什么新的方法呢?...
这些问题可能用一辈子的软件开发经历都不能完全回答,但是我希望通过软件工程这门课,加之今后软件开发的经历,能够认真思考这个问题,争取为软件工程的发展进步提出自己的见解。
(二) 请问 “软件” 和 “软件工程” 这些词汇是如何出现的 - 何时、何地、何人?
软件(Software)
术语"软件"(Software)的最早发表记录是在1958年John Wilder Tukey发表的论文"The Teaching of Concrete Mathematics"中。然而没有证据能证明是Tukey发明了"Software"这个词,其最早发明时间可能更早,在1953年Richard R. Carhart曾在engineering context中使用过这个词,是目前最早的"Software"术语的使用记录。
Tukey(1915-2000)是美国的数学家,其最知名的成就是发明了快速傅里叶变换(FFT)和箱型图(box plot)。1947年,在贝尔实验室工作的Tukey发明了术语"bit",而且还有诸多术语都是以Tukey命名的,如Tukey's range test, Tukey lambda distribution, Tukey's test of additivity, Tukey's lemma, 和 Tukey window
软件工程(Software Engineering)
术语"软件工程"(Software Engineering)被认为是在1968-1969年与NATO组织的会议上提出的。在60年代,由于大的复杂的系统开发困难,人类面临"软件危机"(Software Crisis)。因此人们提出引入工程化方法指导软件开发,从而降低软件开发的成本,提升开发效率。
在NATO会议正式提出"软件工程''术语之前,就曾有多次提出此术语的尝试,早在50年代 Douglas T. Ross 在MIT的讲座中就曾提到软件工程这个词,之后 Margaret H. Hamilton正式命名了这个术语。
Hamilton是著名的美国女性计算机科学家,系统工程师和企业家。她最重要的贡献就是曾担任MIT仪器实验室软件工程部主管,帮助开发阿波罗计划中航天器搭载的飞行软件。其编写的程序都以最大程度防止崩溃为目的,从而防止了阿波罗11号登月计划中缀。
(三) 请问软件工程发展的过程中有什么你觉得有趣的冷知识和故事?
微软2001年推出WindowsXP系统时,好不容易想好了广告语“prepare to fly”,911事件发生了。没办法,微软只好把“带你飞”,临时换成“你能行”。这一换,前期砸进去的两亿美元宣传费,就正式打水漂了。
控告之路,1994年苹果公司把微软告上法庭,理由是侵权。对此比尔盖茨是这么说的“我们有一个富邻居——施乐,他家有一台电视。当我们想偷的时候,发现早就被乔布斯偷走了,可他却说我们是小偷。”什么意思呢?EyeOpener简单“翻译”下,就是“你也是偷别人(施乐)的,好意思出来告我?”。在微软被告时,施乐以相似的理由把苹果也告了,当然最后的结果是:原告们都输了官司。
(四) 调查一下目前流行的源程序版本管理软件和项目管理软件都有哪些, 各有什么优缺点?
-
- GitHub是通过Git进行版本控制的软件源代码托管服务平台
- 优点:使用用户众多,最大的开源代码仓库。pull request和issue功能是亮点
- 缺点:由于使用广泛,其安全性近些年颇有讨论。曾突然*某些国家地区的使用,对其造成影响。而且上面反华*严重。
-
- 微软的团队代码管理服务平台Team Foundation Server,是微软开发的项目管理工具。
- 优点:与Visual Studio无缝结合,方便开发者进行源代码管理,支持代码审阅与讨论,支持邮件通知,支持Web访问与管理,支持工作项以及BUG等管理,不会上传.NET开发时生成的垃圾文件,自带版本合并以及比较工具,支持数据库版本管理,自带很多管理工具(测试管理器、反馈客户端、界面设计工具等等)
- 缺点:能应用起来的团队、公司的数量极少。(参考)
-
- Mercurial是跨平台的分布式版本控制软件,主要由Python语言实现,但也包含用C语言实现的二进制比较工具。Mercurial一开始的主要运行平台是Linux,现在Mercurial已经移植到Windows、Mac OS X和大多数的类Unix系统中。Mercurial主要由命令行程序组成,现在也有了图形用户界面。对Mercurial的所有操作都由用不同的关键字作为参数调用程序“hg”来实现,Hg是参考水银的化学符号而取的名字。
- 优点:命令行简单、容易上手。
- 缺点:功能不够强大。没有命名空间,多人合作时易出现重名问题。改写历史版本很麻烦。分支模型的设计有缺点(参考)
-
Bitbucket是Atlassian公司提供的一个基于web的版本库托管服务,支持Mercurial和Git版本控制系统。Bitbucket既提供免费帐号,也提供商业付费方案。Bitbucket提供的服务类似于GitHub(仅支持Git)。BitBucket的目标用户是开发专有软件的专业开发者,在2010年它被Atlassian收购后此定位更加明确。
优点:支持Hg同时支持Git。
缺点:GitHub私有仓库不再收费后市场减少。
-
- Trac是Edgewall公司开发并维护的开放源码网页界面项目管理、缺陷追踪软件。Trac的灵感来自于CVSTrac,因为能够与Subversion接口,所以最初叫做svntrac。
- 优点:非常灵活,可以随心所欲控制可以和SVN集成
- 缺点:功能不是很强大(参考)
-
是一款用于软件缺陷的追踪管理网络程序,由Mozilla计划开发和应用。1998年,网景公司开放其源代码后,以Mozilla公共许可证协议许可。有许多组织采用其作为旗下软件(特别是*软件)的产品缺陷追踪系统。
优点:是bug管理工具,比较出名的开源软件。
缺点:只能管理缺陷,界面效果差。
-
- 优点:采用迭代式开发模式,以降低项目风险;专注于构架,开发出更有弹性的系统,以迅速适应不断变化的业务需求。
- 缺点:对于个人用户的功能开发远不如github方便
-
- Xcode是苹果公司向开发人员提供的集成开发环境,用于开发macOS、iOS、WatchOS和tvOS的应用程序。
- 优点:功能强大的苹果软件IDE,也是苹果官方出品。其上集成了强大的代码管理工具。可以自动创建分类图表。自动提供撤消、重做和保存功能,无需编写任何编码。
- 缺点:功能太多,上手较慢,作为一名苹果用户至今没敢触碰的IDE。。。
请按照最近一两年使用人数的多少, 从多到少排序并说明各自有多少用户
Name | User |
---|---|
GitHub | 31,000,000 |
Bitbucket | 5,000,000 |
Launchpad | 3,965,288 |
SourceForge | 3,700,000 |
GitLab | 100,000 |
GNU Savannah | 93,346 |
OSDN | 54,826 |
Ourproject.org | 6,353 |
(五)源代码管理工具使用
- git 教程参考
目前用户量最大的源代码管理工具,我使用的比较多,上图是从github上clone了一个仓库,然后再本地切换分支,修改并提交。
- Mercurial 教程参考
Mercurial 也是一款常用的代码管理软件,利用conda或pip就可以安装,方便易用。
如图所示,clone了一个远端的仓库到本地,修改,并通过add和commit的操作进行提交。
可以看出Mercurial的用法和git很像,但是由于使用范围没有git广,所以我并没有深入研究它。