个人作业-提问回顾与个人总结

项目内容
这个作业属于哪个课程2023 年北航软件工程
这个作业的要求在哪里个人作业-提问回顾与个人总结
我在这个课程的目标是学习并实践软件工程,实现从「程序」到「软件」的进展。
这个作业在哪个具体方面帮助我实现目标对本学期课堂上所学与实践中所获得的体会进行总结反思

问题回顾

问题在这里

问题一 :为什么一般不推荐在单元测试中使用随机数增加测试的真实性?

原文出自《构建之法》第 2 章 2.1.2 —— 好的单元测试标准

问:如果用随机数以增加测试的真实性,好么?

答:一般情况下不好,如果某个随机数导致程序出错,但是下一次运行又不能重复这一错误,则于事无补。我们还是要用随机数等办法「增加测试的真实性」,但不是在单元测试中。单元测试不能解决所有问题,不必期望它会发现所有的缺陷。

在结对编程中,我和队友使用了包含随机数的单元测试用例。正如我在学期开始分析的那样,随机数是由随机数种子seed生成的,我们可以在每次单元测试开始时,记录生成随机数的种子seed。当某个数据导致程序出错时,我们只需要通过追踪seed即可复原完整的输入。

此外,在学期开始时我还有如下观点:

我认为随机最大的问题不在于不可复现,而在于其输出也是随机的。对于预先给定的几个单元测试输入,我们可以根据模块的功能定义,分别手工构造其相应的输出。但对于随机的输入数据,我们只能通过另一个程序来模拟运行的情况并给出理论上正确的输出。但这样一来,如何确保模拟程序本身是绝对正确的呢?我认为这才是在单元测试中使用随机数的最大问题。

在结对编程中,我的待测试程序本身使用了状压DP、剪枝等多种优化。因此我另外实现了一个朴素的DP方法,来保证对拍测试的正确性。

问题二: 对于一名工程师而言,究竟应该是更”专“一点好,还是更”广“一点好呢?

原文出自《构建之法》第 3 章 软件工程师的成长 —— 软件工程师的职业发展

专和精的关系

有人说一个人就可以快速成长成为一名全栈工程师,这让我想起街头卖艺的单人乐队(Oneman-band),他们什么都会一些,可以很快地演奏一些曲子。

与之对立的,是只研习某一乐器的乐手,你愿意花钱听哪种演奏呢?当一个小孩说长大了要做音乐家,你会让他走上单人乐队的道路么?

一个作曲家在写一首交响乐的时候,他可以写各个乐器的乐谱,充分发挥不同乐器的特点,这说明他对各个乐器是非常了解的。然而在演奏这首交响乐的时候,不会是一个演奏家满场奔走,一会儿拉小提琴,一会儿吹单簧管,不会是一个人来演奏各个乐器。

当我们谈论**“全栈工程师”的时候,我们说的究竟是“交响乐作曲家**写各个乐器的乐谱”,还是 “演奏家满场奔走,操作各种乐器”呢?当工程师设计软件的时候,工程师的设计、修改错误等活动大致等同于交响乐的谱写完善阶段,两个职业都假设一旦程序/乐谱写好,它们就会被正确地执行。当一个运维工程师在维护一套系统的时候,运维团队要了解各个模块的作用、维护知识,以及和硬件、商业模式相关的各种事件的需求。如果这大部分运维工作都是由一个运维工程师来完成,那么这位工程师的确是“全栈”。

学期开始时,我的观点如下

我认为这是一个很有价值的问题。在不同的人生阶段,处于不同的团队中时,我们都需要思考和回答这个问题。我在这个团队中处于什么样的位置,这个团队需要我发挥什么样的功能。由于我之后的规划是投身科研领域,我也从科研的角度来回答。在初进入一个综合而复杂的团队时,这个团队中有来自各个领域的专业研究人员。我在这个团队中的价值在于把我的本职工作做好,把我这个专业的技能充分应用到团队项目中来,这时“专”一点更好。而当项目发展到一定阶段后,我需要和其他领域的人员进行对接,这时就也需要适当地“广”一点。最后当我经历了多个项目的锻炼,成为一个综合性项目的主要负责人后,我就需要从全局角度协调这个项目下各个领域的工作,需要对各个领域都有一定知识基础,这时“广”就比“专”更重要。

上述回答在软件工程师这个领域也适用。“专”还是“广”,取决于你的角色,“专”与“广”本身也是相对的。但我比较困惑的是,如何平衡好专与广的关系。我认为理想的情况应当是,当专/广发展到一定阶段达到相对饱和时,就需要切换到另一种模式。但显然,这种结论过于模糊,缺乏对实践的指导意义。因此我希望能通过一学期的软件工程实践,让我在期末能更好地回答这个问题。

经过了一学期的实践,我对这个问题有了新的理解和体会。

在alpha阶段,我更加偏向“专”,将精力集中在前后端的对接上。一方面,我需要详细分析前端所有需求,对后端提出API接口;另一方面,我也需要对后端数据库的设计有一定的了解,在提出需求时尽可能考虑后端实现的难易程度和性能。而在beta阶段,由于在alpha阶段我的角色使我对每个成员所做的工作有了一定了解,我可以由“专”拓展为“广”,从一个更全局的角度来参与整个团队的项目。例如,由于我对每个页面都有参与,我可以从全局一致性的角度,对美工和用户体验等方面提出修改建议;此外,在涉及前置后置关系的两个子任务时,由于我对每个任务都有一定的了解和参与,我可以从中进行协调和对接,以确保项目的顺利交付。

综上,我认为由专到广是入门一个领域较好的模式。

问题三:如何预估任务的时间?

原文出自《构建之法》第 8 章 8.6 —— 计划和估计

软件项目计划的一个重要环节就是估计项目各类工作(特别是各种功能)所需的时间。

软件项目的难度还体现在另一个方面,软件工程师的【能力】没有合适的衡量单位,而且大部分依赖于估计值。例如,如果移山公司的程序员果冻一天能写一千行C++代码,那他10天就 能写好一万行代码?!而且什么叫写好一万行代码?如果你估计一个项目的代码量是10万行, 难道10个像果冻这样的人10天就能做完?

在学期之初,我有如下观点:

正如书中所说,由于软件项目本身叠加了太多不可量化的因素,精确的估计一个项目所需的时间十分困难。针对这个问题,书中给出的解决方法有:参考前人经验(有些项目的难度有一定客观规律,谁来做都要花一定时间)、快速原型法(用一个小型demo快速试水、从而估计整个项目的时间)、Wideband Delphi方法(所有人在每一轮提出一个估计时间和解释说明,相互说服,最终在多轮迭代中达成统一意见)、经验公式法(Y = X ± X ÷ N Y=X±X\div NY=X±X÷N )

作为一个喜欢计划的人,如何高效预估一个任务所需的时间,一直是我在思考的问题。比如,我在看到软工第一周作业——阅读和提问后,我并没有一开始就去空想我读一本400多页的书+提5-10个问题要花多少时间,而是先尝试尽可能快地去阅读,并提一两个问题。在完成上述工作后,我对整个任务所需的时间就有了个大致的估计,之后就可以不紧不慢地安排空闲的碎片时间来完成整个任务。事后复盘时我才发现,这和书中提到的快速原型法如出一辙。

但我认为上述方法还是有很多不完善的地方。快速原型法基于时间成本与任务量成线性关系的假设,但这在大规模工程中显然不一定适用。例如,对于一个由多个小项目组合而成的大项目,除了考虑每个小项目本身的时间成本外,还需要考虑将小项目组合成大项目的时间成本。此外,有些项目的技术还有学习成本,这上面的时间估计也具有很强的不确定性。

综上,在如何预估任务的时间上,虽然书中给出了较多的方法,但我仍然觉得难以上手。希望在经过一学期的软件工程实践后,我能在这方面有所提升。

经过了一学期的实践,我有如下体会:

在结对编程任务中,由于我们的题目和往年的题目有较高的相似性,我采用了“前人经验法”来预估任务花费的时间。在实际执行后,我发现“前人经验法”的一个重要问题是,每个前人本身的技能树差异较大,最终实现的软件质量也参差不齐,因此“前人经验”本身的方差就很大。更加合理的方式是根据前人经验先得到一个统计学结果,再结合自己的技能树来做一定偏差估计。

在团队项目中,我们并没有具体估计每个任务需要花费多少时间,而是采用了每一到两天分配一个有明确验收标准的子任务的方式。在分配任务时,我们本身也留了一定的冗余天数,因此如果某个任务在原本分配的期限内未全部完成,我们可以根据反馈及时做出调整,例如分配更多的资源到这个任务上。

问题四:软件服务是否有权始终记住用户的选择?

原文出自《构建之法》第 12 章 12.1.3 —— 软件服务始终都要记住用户的选择

但是我已经用这个软件在同一台电脑上写了十几篇博客,我常用的就是两三种英文字体和两三种中文字体。为什么这个软件记不住, 我每次都得从长长的下拉框中选择已经选过N次的字体?

在学期之初,我有如下观点:

作者在这里举了一个例子,认为软件应当记录用户的每一次选择,从而增强用户的体验感。我认为在科技与法律都日益成熟的当下,这种观点过于片面。

在小程序的快速发展下,用户的每一次点击、搜索等行为都被商家收集并用于立体化用户画像。用户画像可以被用来完善用户的使用体验,也可用来挖掘用户的商业价值。我自己就有过类似的经历。有一次我在微信聊天中无意间提到了“雅思”这个词,第二天我的微信朋友圈中就出现了多条有关“英语培训机构”和“出国机构”的广告。这让我有一种被程序监视的感觉。

诚然,如果我们不记录用户的选择,就无法让软件去适应用户的使用习惯,无法为用户提供更好的服务。因此我的困惑是,该如何平衡软件收集用户隐私的限度?

在团队项目中,我们在beta阶段加入了统计功能,可以详细统计特定API的调用情况(记录每次调用时的调用者、调用时间等信息)。这样做的目的一个是为了更好了解用户的使用偏好,另一个是为了便于从全局角度掌握平台的使用情况。为了避免给用户一种隐私侵犯的感觉,我们并没有直接使用用户的个人信息进行推荐预测,而是根据所有用户的使用偏好定制了推荐问题列表。在实现管理端统计图功能时,我们也没有直接统计单个用户的使用情况,而是对符合筛选条件的所有用户进行统计。

问题五:作为学生如何在敏捷软工课中进行创新?

原文出自《构建之法》第 16 章 16.1.4 —— 迷思之四:创新者都是一马当先

其实,大部分成功的创新者都不是先行者,例如搜索引擎,Google是很晚才进入这个领域的。又如Apple的音乐播放器iPod,发布于2001年10月23日,在它之前市面上已经有很多同类产品了

另外,Gmail、Google Calendar都不是第一个产品,Gmail发布时,世界上大部分使用E-mail服务的用户都至少有两个免费的E-mail/日历服务了(Yahoo Mail、Hotmail),谁还会需要第三个免费的账户?但是,作为后来者的Gmail却在很短的时间内赶上并超越了先行者。

在学期之初,我有如下观点:

这点我也有一些感触。之前在读CLIP这篇论文时,作者提到NLP向CV的zero-shot迁移学习在2017年就已经有类似工作了。但由于当时既没有transformer,也没有CLIP这么大规模高质量的数据集和强大的算力(money is all you need),这个方法在当时表现并不亮眼。

先行者具有先发优势,若充分把握机会,便能先人一步占领市场,成为这个领域的开山鼻祖。而后起者可以利用后发优势,对先行者的经验进行取长补短,通过自身其他优势,在短时间内追上并超越先行者。

然而,作为需要兼顾多门课程、需要兼顾科研实习的大三学生,我们似乎既不像先行者那样,可以通过敏锐的洞察力和丰富的社会经验发现新的需求点;也不像后起者那样,可以通过强大的资源优势和雄厚的积淀来快速超越已有的产品。我很好奇,作为学生如何在敏捷软工课中进行创新?

作为大三学生,我们的优势在于我们有丰富真是且本土化的校园生活经历。我们团队项目是给学校的“士疑解惑”活动开发问答平台。提出该选题时,我的灵感就来自我亲身参与该活动的经历。作为该活动的参与者,我能切身感受到它有很多需求痛点可以解决,且解决这些痛点所需要的技术完全在我们的能力范围内。在开发过程中,由于我们团队大部分成员都有参加“士疑解惑”活动的经历,我们可以对用户的反馈给出设身处地的答复。

综上,我认为在创新时,我们应当尽可能结合自己的长处和优势,结合团队成员的经历和能力特点进行创新。

新的问题

我在学期之初提出的问题都有一定程度的解答,没有产生新的问题。

知识点总结

请问你们在项目的 需求/设计/实现/测试/发布/维护阶段(一共6 个阶段)中都学到了什么“知识点”,每个阶段只要说明一个知识点即可。

需求

在需求分析过程中,我使用了 NABCD 分析法。NABCD 分析法从 N (Need,需求)、A (Approach,做法)、B (Benefit,好处)、C (Competitors,竞争)、D (Delivery,推广) 五个角度对需求进行分析。对于一个没有先例可以参考的产品,使用 NABCD 分析进行用户调研,可以更有说服力地说明一个产品可以满足用户需求。

设计

在设计阶段,我学习了MVVM 架构。MVVM(Model–view–viewmodel)是一种软件架构模式,有助于将图形用户界面的开发与业务逻辑或后端逻辑(数据模型)的开发分离开来。

依靠 MVVM 架构,前端在设计阶段可以统一确定每个页面的全部功能,之后由负责视图层的成员专注于静态界面的设计、实现和美化,由负责模型层的成员专注于js逻辑的实现和 API 的对接。

实现

在实现阶段,我进一步学习了 Vue2 框架,更加熟练地掌握了 git 的使用,学习了团队开发的规范。

测试

在测试阶段,我学习了单元测试。单元测试可以针对单个模块进行最基本的测试,一定程度上可以保证模块最基本功能的正确性。但单元测试也有较多的局限性,通过分析分支覆盖率可以发现,不少异常情况需要多个模块联合才能触发。因此需要多种测试模式相互结合使用。

发布

在发布阶段,我对 CI/CD 有了更深刻的理解。CI/CD是指持续集成(Continuous Integration) 和持续交付(Continuous Delivery)。经过前期 PM 对服务器 CI/CD 的搭建,我们可以随时且自动化地完成发布,以实现软件的快速迭代。

维护

在维护阶段,我对项目可持续性有了更深刻的理解。为了让平台能顺利传承到下一届,我们需要有完整的入门文档,以便新加入的开发者能快速了解这个项目的框架,知道在遇到问题时该去查阅哪个文档。

心得与理解

结合自己在个人项目/结对编程/团队项目的经历,谈谈自己的理解或心得

个人项目

个人项目中让我较有体会的是个人阅读作业。在这个作业中,我学习并实践了如何快速入门一个领域。在科研实习过程中,我也常常面临这种情况。师兄师姐给了几个比较新的关键词(在本课程中就是《构建之法》、敏捷开发等),希望我在一定期限内(在本课程中是1周)达到某种效果(在本课程中就是提出至少5个问题)。

我挺喜欢这种可以给人新鲜感的挑战。在阅读构建之法时,我会带着快速了解软件工程的基本知识、提出5个值得思考的问题的目的,每读完一定篇幅后,思考我上一个阶段做的事情对我的目的有什么帮助,我下一个阶段应当做怎样的调整(例如如果觉得这一章对我没什么启发,可以直接跳过;如果觉得这一章很有启发,可以快速写一个总结笔记)。

结对编程

在结对编程中,我深刻体会到了与具有不同特长的人合作的好处。

我个人之前有ACM经历,因此对算法有一定的了解。在结对编程中主要负责算法实现和数据构造。而我的队友对性能分析和程序实现的底层原理有较深的理解,非常熟悉工程化开发规范。在结对编程中,他教会了我工程化的开发流程,让我明白了很多之前算法题中的c++写法会产生很多性能问题和安全性问题(如内存泄漏)。

和与自己技能树不同的人合作,在开发过程中实现优势互补,同时也能够通过合作开发学习对方的优点,拓展自己的眼界。

团队项目

在团队开发中,我将之前积累的软件工程理论付诸实践,实现了从「程序」到「软件」的进展。在团队合作中,我深刻感受到每个人都有自己的长处,并通过磨合逐渐在团队中找到合适自己的位置,发挥出自己的长处。有的成员很擅长组织管理和表达展示,我学习到了如何协调项目进度、如何与甲方/用户进行有效沟通、如何在答辩中高情商地回答评委的质疑。有的成员对工程化开发有较深的理解,我学习了如何从工程角度对软件进行分析、如何通过工程化方法保证软件的质量,体会到工程化的重要性。有的成员对安全有较深的理解,可以从很多角度启发我对软件安全性的思考。

最后,感谢团队和杰对项目中队友的无私帮助,感谢老师和助教一学期的辛苦付出!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值