BUAA 2020 软件工程 提问回顾与个人总结
Author: 17373051 郭骏
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 2020春季计算机学院软件工程(罗杰 任健) |
这个作业的要求在哪里 | 提问回顾与个人总结 |
我在这个课程的目标是 | 学习软件工程的开发知识,培养工程化开发能力 |
这个作业在哪个具体方面帮助我实现目标 | 反思学习课程之前的问题,在自我回答中进步 |
提问博客链接 | BUAA 2020 软件工程 个人博客作业 |
- BUAA 2020 软件工程 提问回顾与个人总结
- 一、对自己提出的问题进行解答
- 二、还不明白的问题
- 三、产生的新问题
- 四、学到的知识点
- 五、理解和心得
一、对自己提出的问题进行解答
问题2
书本原文
4.5.2 为什么要结对编程
在结对编程中,因为有随时的复审和交流,程序各方面的质量取决于一对程序员中各方面水平较高的那一位,这样,程序中的错误就会少得多,程序的初始质量会高很多,这样会省下很多以后修改、测试的时间。
问题原文
虽然我没有尝试过真正的结对编程,但是我尝试过按照书中的“结对”做过很多事情。关于书中所提到的结对编程理由,我感到疑惑。既然程序的质量“取决于各方面水平较高的那一位”,那结对编程和让那个水平较高的人单独编程,真的有很大的区别吗?同样的,如果两个人的水平几乎相同,那结对编程和两个人分别自己写,又真的有很大的区别吗?
如果两个人各有所长,而且长处不尽相交,或许这样的行为成果比单独编程更加显著。但是,如果一个程序可以被拆分成两个不尽相交的领域,使得两个人都可以发挥,那为什么不让这两个人分开写两个模块呢?
上面我只是提到了结对编程好处不明显,这样的论证还不足以让我提出疑问。在我的个人经历中,我更多会看到结对的弊端,而这个弊端在结对编程中同样不可避免。
- 假设两位同学同解一道数学题,假设两人水平差距比较大,其中一个人已经想到了解法,并且开始指导另一个人做题,向另一个人介绍想法,但另一个人往往跟不上前人的思路。因为数学水平较高的人,解题思路和运算速度都超过另一个人,另一个人需要花费额外的时间开销去理解、消化前人的思路。在消化之前,这道题目无法继续进行求解。这种情况下,结对成了一种拖延时间的负担。编程也是如此。很有可能思路慢的同学需要花费额外的时间去理解算法和代码背后的意义,如果不花时间去理解,那这次编程经历就不叫“结对编程”。
- 还是这两位同学解一道数学题。其中一个人想到了一步运算帮助解题,例如直线的斜率k=(y2-y1)/(x2-x1)。另一个同学就会想“有道理”或者“我也有这方面的想法”,然后两人一拍即合,直接把式子写到纸上,开始下一步计算。可惜他们忘了,x2-x1可以等于0,此时直线垂直于x轴,需要分情况进行讨论。这种事情在一个人解题,另一个人特意找茬的时候,错误更容易被发现。但两个人一起解题,其中一人提出一个表面看起来成立的思路时,另一个人容易被迅速带进沟里。编程也是如此。很有可能两人思路同步之后,没有能看出对方提出的算法/代码的缺陷,导致程序出现Bug。而这种Bug的出现,或许在一般的编程+复审的流程中,更容易被找出来。
因而,在我眼中,书中所提到的结对编程的“好处”可能没那么好,而弊端却更加显而易见,而且我深有体会。当我和别人结对解题的时候,也只是聪明人主导稍笨一点的人在解题而已,因而我提出疑问,结对编程的意义真的大吗?是不是我们的合作方法不对?又或许是解题和编程有重大的区别?
不过也不用着急,我会在接下来的结对编程作业中,寻找属于自己的答案。
在上完了这门课,经历过结对编程和团队开发之后,我能够对这个问题有更深刻的回答了。
在提问时我所担心过的,结对编程的弊端确实存在。我和队友在结对编程的过程中,也往往会有一个人的思维主导另一个人,以及双方的思维难以同步的情况。我想这应该是许多结对编程的人必须经历的一道坎。而且,加上本次结对编程没法面对面编程,队友的网络状态又不好,导致无论是用什么方式结对编程,总会出现一定程度的交流障碍,给我们的结对编程带来了不好的体验。
但总的下来,当我们最终做出程序的时候,我们的结果是好的。尤其是在看见自己的个人项目翻车的时候,我更加确信了这次结对编程的重要性。在一人驾驶,一人领航的情况下,我们确实做到了随时的复审和交流,也帮助我找到了很多个人结对项目中存在的问题。可能我们在结对编程上所花费的时间较多,而且体验也未必那么良好,但是结对编程这样一种工作方式,确确实实的帮助我们找到了很多很多的问题,也让我们的程序在正确性和效率上更上一层楼。我和队友可以实时讨论,考虑如何优化代码;可以随时复审,帮助找到代码中所缺少的部分和条件。虽然也有我们两人同时疏忽的东西,但是两人的工作所犯的错,总会比一个人工作少得多。
在团队开发过程中,我们认为良好的代码复审起到了一定的结对编程的作用,即交流和改错。所有程序员都会犯错,而实时的代码复审能够帮助我们减少开发阶段的问题。结对编程则是将代码复审的实时性拉到最高的一种开发模式。我认为这种开发模式有非常重要的意义。
问题3
书本原文
8.4 竞争性需求分析的框架
大家可以参考NABCD模型。
N:Need,需求
A:Approach,做法
B:Benefit,好处
C:Competitors,竞争
D:Delivery,推广
问题原文
看到这个模型,我不由得开始思考,NABCD模型中,到底哪一项因素更重要?这里的“重要”是指,哪一项因素可以使得用户更多、用户粘性更大?
现在市面上有这样几款软件,真的非常奇怪。它们使用的人口基数大,用户粘性高,而它们的核心用户却并不会给这款软件好评。官方论坛上,或是意见箱中,高度统一的诟病非常多,但大家还是用。这样甚至给了软件公司一种印象:用户只是会耍耍嘴皮子,一旦要用的时候还是乖乖送上门。但这不代表用户没有这个需求(Need)。最经典的例子比如微信。微信是全中国使用基数最大的聊天通讯软件,甚至已经超过了他的前辈QQ。许多人使用微信办公、聊天、付款,但许多人并不觉得微信能够满足他们的需求。比如微信群管理混乱、没有永久群文件功能、消息记录同步功能差、多端同步功能差……微信产品经理张小龙有句名言:每天都有一亿人教我如何做产品。言下之意是什么呢?即便有一亿人对我指点江山,我也未必会改。
我不愿意承认微信是一款值得好评的产品,但它却是一款成功的产品。因为它的用户基数大,用户粘性高,谁都离不开微信。但微信成功的原因,却未必在注重了NAB这三点上。首先,微信没有足够强力的竞品(Competitors)。国内的聊天软件质量参差不齐,本身就不足以和微信竞争。就比如微信的小程序功能,此类技术依旧掌握在腾讯手中,哪怕用户量大如微博这种软件,也没有这种功能与其竞争。在微信的定位点上,它更像是书中的图所展示的定位。
前面说到竞品虽少,但也不是没有。就比如小米曾经试图发展聊天软件“米聊”,更不要忘记,微信最大的竞品正是与其师出同门的老前辈QQ。之前我提到了一些微信的弊端,有许多明显QQ都做到了的功能,微信却迟迟不肯上线。同时,微信所有的功能,QQ正在一步步全部实现,例如QQ钱包、QQ小程序、QQ公众号等。当然,QQ有它本身的问题,比如无用功能过多。但是,微信依然还是最大的聊天软件,起码在一段时间内是。原因在于,微信的推广(Delivery)超越大部分同门。微信凭借着腾讯旗下的用户渠道吸引了一大波原始用户,当然不可否认,之所以能够吸引到,也是因为微信最初的定位和QQ不同,对用户有不同的好处(Benefit)。微信以其界面的简洁吸引了一大批中老年人,并且更有人有意将自己的娱乐放在QQ上,而工作放在微信中,将两者割裂开。但现在,微信已经用其庞大的用户群体织好了这片社会网,哪怕大家都意识到微信不便,任何一个人却都无法独善其身。因为单独的脱离意味着与群体的割裂,所以微信依然能,并且在很长一段时间内将持续主宰社交网络。我更愿意称其为推广上的营销捆绑。
微信的NAB三项,放在以前或许是革命性的,但放在现在,以这么大的用户群体为基础,满足如此多的功能需求,已经是非常单薄。微信之所以能稳步提升地位,坐实中国社交软件老大哥的地位,更多是CD方面的捆绑。游戏行业也有说法,只要是腾讯推广的游戏,无论是什么臭鱼烂虾,都会有不低的知名度和用户量。这就是我的疑惑点,软件的成功,好像不那么看重需求,而更多的与资本和营销绑定在一起?
我当时提出的想法是,一款软件是否成功,很大程度上取决于大力的推广和竞品的缺乏,而对用户的需求未必需要那么精准的把握。
在我提出这个问题之后,经历团队开发的过程中,也确实遇到了这方面的挑战。我们的项目——航胥:北航教务助手,是考虑到了竞争产品少,我们有足够的优势,才选择这个项目。真正的在需求方面,我们在设定计划之前,没有调研的很清楚。我们真正下功夫的地方,依然是错开竞品和广泛推广。最后的结果,我认为相对符合我们的预期。我们Alpha阶段制作的功能“课程中心DDL”与软软软组的“DDLKiller”完美撞车,在Beta阶段我们立马转向了别的方向开发,并不试图将广受好评的DDL功能作为主打功能开发。推广方面,我们依靠口口相传,拜托身边认识的人向更广阔的范围宣传,以求获得更大的用户基数和课程评价群体。就结果而言,我们的用户数和用户口碑都不错,而这一切都建立在对需求的分析没有那么详细之上。我们也确实因为需求问题导致用户增长缓慢,但是我们广泛的推广依然起到了成效。
而对于我当时提出的问题而言,我现在的想法是,无法去评价一款成功的产品是需求分析做得更好,还是推广和竞争做得更好。产品能成功,永远是NABCD五项的综合。因为微信的社交圈子太广泛,所以我们才嫌弃微信的需求分析做的不好,这只是其一方面的光辉太过耀眼,使得本来做的不错的需求分析也黯然失色。我认为,一款产品只需要在NABCD五项的综合上,得到一个“综合排名第一”的成绩,就算是成功了,何必去谈论软件是否“偏科”呢?
问题4
12.1.5 不让用户犯简单的错误
一个叫西乔的同学为微软学术搜索UI提出了建议,将submit和cancel按钮采用不同的样式,降低用户丢失操作的可能性。
这种建议非常有必要。但同时,我不得不回想起一些软件,他们的设计思路是想让用户犯简单的错误。比如,特意把“取消”和“确定”按钮交换左右位置,让用户故意选择错误的选项。亦或是卸载某一软件时,将卸载按钮藏在最深处,需要折腾很久,导致用户难以卸载……说白了,这些软件利用了用户的习惯,让他们根据自己的习惯进行选择,从而犯下错误。我的问题在于,如果大部分软件都遵循同一个使用习惯(例如确定在左,取消在右),那这种故意想让用户犯错的软件不就更加有机可乘了吗?
进一步思考,我们是否需要有标准甚至法律来规定软件在此方面的设计,从而防止出现这种“故意引导”式的错误呢?这种错误的产生,追根溯源就是软件开发者的共识和习惯导致用户也养成了这样的思维惯性。那么,我们何不将其以标准的形式公布,让市面上软件都强制性这样做呢?尤其是那些涉及安全隐私和个人财产的软件,这种方面的设计更是应该限制,不能让他们利用用户的习惯进行“惯性诈骗”。
在进行团队开发的过程中,我们也遇到了一些习惯方面的问题。比如我们有一位前端设计者有“左右滑动进行功能翻页”的习惯,导致7天的课表必须浓缩在一块不能左右滑动的窄屏幕里。然而我们的其他安卓用户并没有这种习惯。在其他方面上,我们也在一些需要为用户提供“怎样的方便”设计上纠结。这种选择还是相对自由的,毕竟有和没有这种习惯的人占一半一半。但是,有一些达成共识的东西,我们依然遵循最基础的习惯和共识来开发。
这些东西如果按我说的,形成一种规范和标准,略显矫枉过正。但是,遵循一种标准的设计去开发,应当成为软件设计者的职业素养,就像代码风格一样,需要在开发者的圈子中形成一种长期的约束。
二、还不明白的问题
问题1
书本原文
2.4.1 从Hello World开始
下面的联系可以用来锻炼学生的编程基本功。
全部用命令行工具和Notepad编辑器,不用Visual Studio等集成编辑环境,每人手工创建并编译一个C的命令行程序。
问题原文
我阅读了这段文字,其实未必是对文字中的内容有很大疑问,只是想到,在科技日新月异,各种全能IDE层出不穷的情况下,程序员真的有必要去返璞归真,从命令行和Notepad开始去学习编程吗?如今,几乎所有公司的软件开发岗位全部都使用IDE进行编程开发,哪怕是书上也要求我们使用Visual Studio进行开发和测试。使用命令行和记事本,又能在什么地方真正的帮助到程序员呢?这些掌握到的“帮助”,例如不使用关键词补全就能写上函数名,是否真的有实战意义呢?
我在学习操作系统课程设计这门课的时候,被要求使用原生无插件的Vim进行操作系统开发。同样的,编译运行也是完全使用命令行界面。这样的行为,首先无疑降低了我这种没有Vim使用经验的人的编程效率,甚至到结课我都未能掌握Vim的效率编程。此外,我们无法用各种单元测试等工具来评估自己的小操作系统的运行效率,出现Bug也十分难找,甚至可能是语法错误导致无法通过编译。这些问题在当今的IDE中大多可以避免,甚至Visual Studio Code由于其强大的插件支持能力,已被誉为“除了不能生孩子什么都行”。或许不使用IDE,是一种极端而复古的开发学习,确实能体会上一辈人初学编程的感受,可我依然困惑,是否在当今的时代,还需要紧抱Notepad去编程锻炼呢?
软工课程完全没有能够帮助我回答这个问题,并且一直在鼓励和强调我们使用更现代化、更自动化的开发工具,我个人也是一个喜爱拥抱新技术的人。不过无论何时何地,这种底层、原始和封装、现代化的碰撞永远都会存在。总有人钟爱Vim,也有人钟爱VS Code。我想,或许我们应该尊重每个人的开发习惯,Notepad编程应当是一种体验和尝试,而不应当有这种强制性的锻炼?
问题5
16.1.5 迷思之五:要成为领域的专家,才能创新
另一个例子是索尼公司的“单放机”(Walkman)。公司的专家们认为随身听没有市场,他们还做了多次市场调查,来证明大众不会喜欢“只能放音乐,不能录音乐的小玩意”。盛田昭夫基于自己对电子消费品的趋势洞察和对未来的直觉,坚持推动研发。Walkman最终吸引了众多的消费者,这是许多专家当初想不到的。
这个例子让我感觉和前面的例子有点不同。专家们不是简单地有想法认为随身听没有市场,而是尝试用市场调查去证明他们的观点。而盛田昭夫只是用直觉来力排众议,最终取得了成功。这个例子说明了什么呢?
- 专家们的证明可能很不靠谱,亦或是专家不如外行人更了解市场?
- 用这个例子鼓励实践在内行眼里不可思议的想法,鼓励直觉主导?
- 这是一个成功的案例,而这种案例大多是成功还是失败呢?
这种创新更像是一种冒险,未必是内行想不到,而是内行在经过市场调查后选择了放弃。但盛田昭夫还是要推行。虽然他成功了,我们在此对其予以赞扬,可万一这是一款失败的产品呢?我们只会批评他“思维怪异,特立独行”,一点都不懂消费者,就像是之前案例中提到的铱星手机。事后诸葛亮大家都会当,可是我们真的应该把创新交由直觉吗?
内行人也不喜欢乔布斯对手机的执拗,可是他的苹果手机设计最终成功,所以我们认为乔布斯是伟大的开创者。但是这种创新就一定伟大、一定成功吗?反观国内的各种创新产品,例如上层是巴士,下层可走车的“巴铁”,还有用水分解的氢氧作燃料的“水电池新能源汽车”,都获得了政府投资,可事后证明,这就是骗投资的产品,圈了钱就跑。或许大公司可以接受失败,去一定程度上尝试创新,可初创的小公司是否有能力去这样做?成功和失败听上去是个轻如鸿毛的概率问题,可落到任何一个人头上都重如泰山。可能所有人都有对外行的点子,但不是所有人都有尝试的资本。
这个问题略显市场化和社会化,是一个更加复杂的社会学问题。软工课程实在没有办法帮助我对这个问题进行解答。我想这个问题,需要我有更丰富的社会阅历,在更高级的公司中体会种种商业竞争之后,才能够给出一个相对完善的解答吧。
三、产生的新问题
本次软件工程的体验和往年不一样,一个重要的区别就是我们在线上进行开发。我感觉,线上的工作和研究并没有那么大的阻碍,只要每个人家里的网络通畅,几乎可以起到和面对面一样的效果。将来是否有可能,程序员的线上工作成为一种常态?这又会给软件工程这门课程带来什么样的改变和冲击呢?
四、学到的知识点
-
需求
用户对于一款纯白没有框架的软件,能提出的需求也是笼统的。我们需要进行一定的开发之后,让用户提出更加具体的需求意见。
-
设计
设计方面需要注意设计的粒度,不能太详细也不能太笼统,且需要给设计的计划做应急预案,若某项功能无法实现需要有代替方案。
-
实现
实现时无论是问题还是进度都需要及时沟通报告,以防出现冲突,以及与设计相背等问题。
-
测试
测试时可以给项目外的人进行小规模的分发来对软件功能进行测试,可以获得一些不同角度的测试用例和使用感受。
-
发布
发布一定需要找准用户群体和发布时间,好的发布必然具备天时地利人和。
-
维护
维护需要实时跟进,需要设置专门的窗口接受用户反馈和错误信息,并且及时通知到开发人员进行修复处理。这是一款软件能够长久生存的立身之本。
五、理解和心得
-
个人项目
就我个人的体验而言,个人项目的开发过程绝对是痛苦且不愿再来的,且并没有觉得自己真正学到了什么东西。或许其中存在着一些感情上的主观因素,但是我依然想对此提出一点批判性意见。
个人项目的选题是“计算几何”,一个能干掉ACMer的类型。比起一道软件工程的题目,这更像是某种算法竞赛题,正确性和效率上都有无数的难点。
正确性上,由于计算机对浮点数本身就无法精确储存,需要设置误差项epsilon才能够尽量减小误差。而想要使得结果更精确、正确性更高,必然需要采用更复杂的结构,比如存储分子分母等,这样会带来效率的降低,很有可能超时,且解出来依然可能是错的。
效率上,我想对于大多数同学来说,该怎么对这道题目进行优化是完全没有思路的。大家无非只能做出一些常数项较大的\(O(n^2)\)做法,且正确性也得不到保证。之后给出的扫描线算法实用性也较低,想要将其运用到我们的题目上,也需要很大的改动。
我认为,作为一个一周的作业,个人项目显然是要求过高了。更多的人在正确性上翻车,应该是没想到助教出了这样一道大部分人没有能力去优化的题目,放了许多精力在优化上,导致正确性也没拿到分。
无论这道题目和我们北航大学生的能力是否匹配,无论在以后的生产工作中会不会遇到更难的问题,无论我们是否有资格去揣摩和评价出题者的心思,我依然认为这道题作为一个一周的课程考核项目来说,是失败的。这道题的区分度体现在很奇怪的地方,奖励的人真的是那些所谓的“高能力者”吗?
或许对这个项目的碎碎念太多,都让我忘了我到底学到了什么,有了什么理解和心得。也或许,在这个项目上,我除了一地鸡毛,什么也没有收获。
-
结对项目
结对项目是个人项目的改版,在这道题上依然没有很良好的体验。不过做完个人项目知道出题者的手段之后,结对项目对效率啥的追求完全没有了。能对就行。当然可能最后也没有做对。
结对编程确实能够帮助我们开发者增加程序的正确性和效率,不过不代表会增加开发效率。结对编程的开发时间一般大于一个人单独开发的时间,也一般小于两个人独立开发所有功能的时间之和。这多余的时间,就放在了复审、探讨、优化和改进上。就这点而言,对于这道需要细心和全面思考的题目来说,结对编程确实能够帮助我们纠正许多错误。
也正是通过结对编程,我收获到了从未有过的开发体验。和两个人一起交流开发代码不再是以前课程里明令禁止的“抄袭”和“违规”,而是变成了一种提升程序质量的办法,体验非常神奇。
有点不太理解的是为什么要写个GUI,在之后的团队开发中,临时学会的技术也没有起到什么作用。
-
团队项目
在Alpha阶段和Beta阶段,我作为团队的PM在监督开发。虽然前端的代码一行都没有写过,对后端的代码也主要是停留在复审阶段,不过我感觉到PM的职责还是很重要的,
起码博客基本是我写的。PM是团队的监督者,是团队磨合还不够成熟时,最重要的话语者和拍板者。在Alpha阶段开发时,团队中遇到各种各样的问题,也手忙脚乱,
不过我经常很勤快的push大家,尽到PM的职责。最终Alpha阶段发布时,和计划阶段的样子区别还是比较大,多了许多辅助功能,帮助我们的软件做到更好。在Beta阶段,团队的磨合更上一层楼,进入创造阶段之后,PM的工作就非常少了。虽然还是要代码复审和监督,但是哪怕没有PM,团队也能以一种微妙的形式进行开发活动。此时PM的工作则是对一些事情拍板定论,时刻监督团队人员的开发进度。在Beta阶段我们遇到了一些困难导致部分功能没有制作,但最后依然拿出了具有核心功能的产品。
最终回顾我们的产品,想起我们从零开始学习搭建起软件的体验,我感到非常充实和喜悦。在这次团队开发的过程中,我学到了技术,也学到了沟通、计划、推广、随机应变,受益匪浅。
-
总结
个人项目的选题很迷,体验并不良好。不理解为什么要整个(这样的)个人项目。
结对编程和团队开发给我带来的收获是重大的,将成为我程序员路上的一份重要的经验。