个人作业-阅读和提问
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 2023 年北航敏捷软件工程 |
这个作业的要求在哪里 | 个人作业-阅读和提问 |
我在这个课程的目标是 | 学习并实践软件工程,实现从「程序」到「软件」的进展。 |
这个作业在哪个具体方面帮助我实现目标 | 阅读《构建之法:现代软件工程》,快速了解软件工程的基本知识,锻炼泛读和提问的能力。 |
问题一 :为什么一般不推荐在单元测试中使用随机数增加测试的真实性?
原文出自《构建之法》第 2 章 2.1.2 —— 好的单元测试标准
问:如果用随机数以增加测试的真实性,好么?
答:一般情况下不好,如果某个随机数导致程序出错,但是下一次运行又不能重复这一错误,则于事无补。我们还是要用随机数等办法「增加测试的真实性」,但不是在单元测试中。单元测试不能解决所有问题,不必期望它会发现所有的缺陷。
我认可作者的后一半观点,即单元测试只需要覆盖所有代码,测试程序是否基本符合逻辑。没必要引入随机数来期望它会发现所有的缺陷。但我不太认可作者的前一半观点。
随机数是由随机数种子seed生成的,我们可以在每次单元测试开始时,记录生成随机数的种子seed。当某个数据导致程序出错时,我们只需要通过追踪seed即可复原完整的输入。
此外我还有一些补充的观点。我认为随机最大的问题不在于不可复现,而在于其输出也是随机的。对于预先给定的几个单元测试输入,我们可以根据模块的功能定义,分别手工构造其相应的输出。但对于随机的输入数据,我们只能通过另一个程序来模拟运行的情况并给出理论上正确的输出。但这样一来,如何确保模拟程序本身是绝对正确的呢?我认为这才是在单元测试中使用随机数的最大问题。
在网上搜索后,我也发现了和我类似的观点
https://softwareengineering.stackexchange.com/questions/147134/how-should-i-test-randomness
I don’t think unit tests are the right tool for testing randomness. A unit test should call a method and test the returned value (or object state) against an expected value. The problem with testing randomness is that there isn’t an expected value for most of the things you’d like to test. You can test with a given seed, but that only tests repeatability. It doesn’t give you any way to measure how random the distribution is, or if it’s even random at all.
问题二: 对于一名工程师而言,究竟应该是更”专“一点好,还是更”广“一点好呢?
原文出自《构建之法》第 3 章 软件工程师的成长 —— 软件工程师的职业发展
专和精的关系
有人说一个人就可以快速成长成为一名全栈工程师,这让我想起街头卖艺的单人乐队(Oneman-band),他们什么都会一些,可以很快地演奏一些曲子。
与之对立的,是只研习某一乐器的乐手,你愿意花钱听哪种演奏呢?当一个小孩说长大了要做音乐家,你会让他走上单人乐队的道路么?
一个作曲家在写一首交响乐的时候,他可以写各个乐器的乐谱,充分发挥不同乐器的特点,这说明他对各个乐器是非常了解的。然而在演奏这首交响乐的时候,不会是一个演奏家满场奔走,一会儿拉小提琴,一会儿吹单簧管,不会是一个人来演奏各个乐器。
当我们谈论**“全栈工程师”的时候,我们说的究竟是“交响乐作曲家**写各个乐器的乐谱”,还是 “演奏家满场奔走,操作各种乐器”呢?当工程师设计软件的时候,工程师的设计、修改错误等活动大致等同于交响乐的谱写完善阶段,两个职业都假设一旦程序/乐谱写好,它们就会被正确地执行。当一个运维工程师在维护一套系统的时候,运维团队要了解各个模块的作用、维护知识,以及和硬件、商业模式相关的各种事件的需求。如果这大部分运维工作都是由一个运维工程师来完成,那么这位工程师的确是“全栈”。
我认为这是一个很有价值的问题。在不同的人生阶段,处于不同的团队中时,我们都需要思考和回答这个问题。我在这个团队中处于什么样的位置,这个团队需要我发挥什么样的功能。由于我之后的规划是投身科研领域,我也从科研的角度来回答。在初进入一个综合而复杂的团队时,这个团队中有来自各个领域的专业研究人员。我在这个团队中的价值在于把我的本职工作做好,把我这个专业的技能充分应用到团队项目中来,这时“专”一点更好。而当项目发展到一定阶段后,我需要和其他领域的人员进行对接,这时就也需要适当地“广”一点。最后当我经历了多个项目的锻炼,成为一个综合性项目的主要负责人后,我就需要从全局角度协调这个项目下各个领域的工作,需要对各个领域都有一定知识基础,这时“广”就比“专”更重要。
上述回答在软件工程师这个领域也适用。“专”还是“广”,取决于你的角色,“专”与“广”本身也是相对的。但我比较困惑的是,如何平衡好专与广的关系。我认为理想的情况应当是,当专/广发展到一定阶段达到相对饱和时,就需要切换到另一种模式。但显然,这种结论过于模糊,缺乏对实践的指导意义。因此我希望能通过一学期的软件工程实践,让我在期末能更好地回答这个问题。
问题三:如何预估任务的时间?
原文出自《构建之法》第 8 章 8.6 —— 计划和估计
软件项目计划的一个重要环节就是估计项目各类工作(特别是各种功能)所需的时间。
软件项目的难度还体现在另一个方面,软件工程师的【能力】没有合适的衡量单位,而且大部分依赖于估计值。例如,如果移山公司的程序员果冻一天能写一千行C++代码,那他10天就 能写好一万行代码?!而且什么叫写好一万行代码?如果你估计一个项目的代码量是10万行, 难道10个像果冻这样的人10天就能做完?
正如书中所说,由于软件项目本身叠加了太多不可量化的因素,精确的估计一个项目所需的时间十分困难。针对这个问题,书中给出的解决方法有:参考前人经验(有些项目的难度有一定客观规律,谁来做都要花一定时间)、快速原型法(用一个小型demo快速试水、从而估计整个项目的时间)、Wideband Delphi方法(所有人在每一轮提出一个估计时间和解释说明,相互说服,最终在多轮迭代中达成统一意见)、经验公式法( Y = X ± X ÷ N Y=X±X\div N Y=X±X÷N )
作为一个喜欢计划的人,如何高效预估一个任务所需的时间,一直是我在思考的问题。比如,我在看到软工第一周作业——阅读和提问后,我并没有一开始就去空想我读一本400多页的书+提5-10个问题要花多少时间,而是先尝试尽可能快地去阅读,并提一两个问题。在完成上述工作后,我对整个任务所需的时间就有了个大致的估计,之后就可以不紧不慢地安排空闲的碎片时间来完成整个任务。事后复盘时我才发现,这和书中提到的快速原型法如出一辙。
但我认为上述方法还是有很多不完善的地方。快速原型法基于时间成本与任务量成线性关系的假设,但这在大规模工程中显然不一定适用。例如,对于一个由多个小项目组合而成的大项目,除了考虑每个小项目本身的时间成本外,还需要考虑将小项目组合成大项目的时间成本。此外,有些项目的技术还有学习成本,这上面的时间估计也具有很强的不确定性。
综上,在如何预估任务的时间上,虽然书中给出了较多的方法,但我仍然觉得难以上手。希望在经过一学期的软件工程实践后,我能在这方面有所提升。
问题四:软件服务是否有权始终记住用户的选择?
原文出自《构建之法》第 12 章 12.1.3 —— 软件服务始终都要记住用户的选择
但是我已经用这个软件在同一台电脑上写了十几篇博客,我常用的就是两三种英文字体和两三种中文字体。为什么这个软件记不住, 我每次都得从长长的下拉框中选择已经选过N次的字体?
作者在这里举了一个例子,认为软件应当记录用户的每一次选择,从而增强用户的体验感。我认为在科技与法律都日益成熟的当下,这种观点过于片面。
在小程序的快速发展下,用户的每一次点击、搜索等行为都被商家收集并用于立体化用户画像。用户画像可以被用来完善用户的使用体验,也可用来挖掘用户的商业价值。我自己就有过类似的经历。有一次我在微信聊天中无意间提到了“雅思”这个词,第二天我的微信朋友圈中就出现了多条有关“英语培训机构”和“出国机构”的广告。这让我有一种被程序监视的感觉。
诚然,如果我们不记录用户的选择,就无法让软件去适应用户的使用习惯,无法为用户提供更好的服务。因此我的困惑是,该如何平衡软件收集用户隐私的限度?
问题五:作为学生如何在敏捷软工课中进行创新?
原文出自《构建之法》第 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),这个方法在当时表现并不亮眼。
先行者具有先发优势,若充分把握机会,便能先人一步占领市场,成为这个领域的开山鼻祖。而后起者可以利用后发优势,对先行者的经验进行取长补短,通过自身其他优势,在短时间内追上并超越先行者。
然而,作为需要兼顾多门课程、需要兼顾科研实习的大三学生,我们似乎既不像先行者那样,可以通过敏锐的洞察力和丰富的社会经验发现新的需求点;也不像后起者那样,可以通过强大的资源优势和雄厚的积淀来快速超越已有的产品。我很好奇,作为学生如何在敏捷软工课中进行创新?