[I.1] 个人作业:阅读和提问

项目 内容
这个作业属于哪个课程 课程社区首页
这个作业的要求在哪里 作业要求
我在这个课程的目标是 系统学习现代软件工程的开发流程、方法与规范,在实践中提升个人工程能力,并深入体验团队合作开发的过程。
这个作业在哪个具体方面帮助我实现目标 通过阅读《构建之法》并结合作业要求,我对软件开发的整体流程、团队协作方式和工程化实践有了更具体的认识,为后续深入体验团队开发和规范开展软件工程实践打下了基础。

AIGC 使用说明

本文在完成过程中使用了 GPT-5.4 进行辅助,具体使用点如下:

  • 辅助查询与本作业相关的公开资料,用于补充对书中观点和相关方法的理解。
  • 作为讨论对象,围绕《构建之法》中的部分观点进行交流,帮助我梳理问题背景与思路。
  • 在我完成主要内容后,对文字表达进行语言润色与表述优化。

本文中的问题提出、观点判断、内容取舍与最终整理由我本人完成,AIGC 仅作为辅助工具使用。

软件工程中的“度量”真的能准确反映一个人的贡献吗?

这个问题主要来自《构建之法》第3.1节关于软件工程师能力评估与度量的讨论。书中提到,在软件最终发布时,可以用缺陷数量除以项目大小来衡量质量,例如Bugs/KLOC;也有人尝试用re-work来表示质量,例如一段代码在开发到发布过程中一共被修改了多少行·次。书中随后指出,re-work更多表明的是开发过程中花费的时间,它和最终质量并不一定成正比,因为软件开发在很大程度上本来就是探索和实验的过程,适当的反复修改有助于尽早交付原型、发现难点并找到更优方案。与此同时,书中还以两个程序员交付任务的例子说明:相比单纯看平均完成时间,交付时间的稳定性和标准方差也很重要,因为团队更需要稳定、可预期的成员。

我之所以对这一部分产生疑问,是因为它让我意识到:软件工程里很多评价标准虽然看上去很客观,但未必真的能准确反映一个工程师的实际贡献。比如缺陷率、返工次数、平均交付时间、交付时间方差,这些指标都能反映某一方面的问题,但它们似乎都只能描述结果的一部分,而不能完整描述一个人到底做得好不好。

以re-work为例,返工次数多,并不一定意味着质量差。有些任务本来就包含大量探索,例如需求并不明确、技术路线尚未确定、或者需要快速试错验证方案。在这些情况下,re-work反而可能意味着工程师在主动发现问题、修正思路,而不是低水平重复劳动。如果只把改动少简单理解为质量高,我觉得会忽略软件开发本身具有探索性的特点。

再比如交付时间。书中用平均值和标准方差比较两个程序员,我觉得这个视角很有启发性,因为团队协作确实需要稳定和可预测的交付。但与此同时,我也会怀疑:如果一个工程师总是在处理最困难、最模糊、最具不确定性的任务,那么他的交付时间天然就更不稳定。相反,另一个工程师如果主要负责边界清晰、重复性较高的任务,他的数据往往会更好看。在这种情况下,只看度量结果,会不会反而低估了前者的真实贡献?

结合自己的理解,我目前的观点是:软件工程中的度量当然有价值,因为团队管理不能完全依赖主观印象,必须借助一些可观察、可比较的数据。但问题在于,很多真正重要的贡献其实并不容易被直接量化,例如理解模糊需求、推动团队达成共识、提前发现风险、做出关键设计取舍、帮助别人解决复杂问题。这些工作未必能体现在 bug 数、代码行数、返工次数或者交付方差里,但它们对项目成败往往很关键。

如果软件工程必须依赖度量来管理团队,那么我们该如何避免只看容易统计的数据,却忽视那些更重要但更难量化的贡献?也就是说,度量到底应该被当作评价工程师能力的核心依据,还是只能作为一种有限的辅助参考?

在 coding agent 能力日渐强大的今天,传统的结对编程是否还有必要?

这个问题来自《构建之法》第 4.5.2 节“为什么要结对编程”。书中提到,结对编程是两位程序员肩并肩在同一台机器前协作开发,一人担任驾驶员(Driver),一人担任领航员(Navigator),两人一起分析、设计、编码、测试和写文档。教材认为,结对编程的主要价值在于:

  • 提高设计质量和代码质量
  • 两人合作解决问题的能力更强
  • 能实时交流、相互激励、相互复审

我之所以产生这个问题,是因为现在很多编程场景里,在一位合格的软件工程师的使用下,AI工具已经能承担很大一部分原本需要“第二个人”完成的工作。例如:

  • 能根据注释、需求描述自动生成函数或模块代码
  • 能对代码进行静态分析,指出潜在 bug、边界条件和重构机会
  • 能在程序员编写代码时提供实时补全、错误修正和测试建议
  • 能解释陌生代码、总结思路,甚至参与需求拆分和任务规划

这些能力和教材中领航员负责提醒、检查、补充思路的角色已经出现了明显重叠。

同时,程序员群体里常说一句话:“Talk is cheap, show me the code.”
从这个角度看,单个程序员可以快速的和AI交流自己的设计、测试与编码并快速产出,个人生产力的解放冲击了传统结对编程的必要性。

从我自己的体验来看,一个人写代码时如果配合AI工具,确实能明显减少查文档、写样板代码和定位低级错误所花的时间。很多原本需要请同学帮忙看一眼的问题,现在先让AI解释或检查一下,就能更快推进。

但另一方面,我也感觉AI和真正的人类搭档并不完全一样。比如:

  • AI能生成代码,但未必真正理解团队约定、项目背景和业务目标
  • AI能提出建议,但未必能像经验丰富的同伴那样主动质疑需求本身是否合理
  • 人和人结对时,除了找 bug,还有知识传递、工作节奏互相约束、共同决策这些作用
  • 有些复杂设计问题并不是代码写出来就解决了,很多时候和另一位工程师的交流会产生更有价值的设计思路。

我并不完全认为AI会直接让结对编程失去意义,但我也很难完全接受教材中对结对编程价值的论述在今天仍然可以不加变化地成立。

敏捷强调“拥抱变化”,那项目还需要多大程度上的前期计划?

我看了《构建之法》中敏捷流程的这一章,这一章强调:软件开发和传统工程不同,需求往往不是一开始就完全明确的,因此团队不能指望靠一次性的详细计划解决所有问题,而应该通过短周期迭代、持续反馈和不断调整来推进项目。书中这种写法让我感觉,敏捷开发更重视根据变化及时修正,而不是先把未来全部设计好再开始做。

如果敏捷开发强调拥抱变化,那一个项目到底还需要多大程度上的前期计划?如果前期计划做得太细,后面需求一变,之前的很多安排可能就失去意义;但如果前期计划做得太少,团队又可能一开始就没有清晰目标,开发过程中反复返工,甚至连每轮迭代到底要解决什么问题都说不清楚。这样看来,敏捷似乎并不是不要计划,而是不要那种试图一次性确定一切的计划,但这个边界到底在哪里,我并不是很明白。

我查了资料后,发现一些说法和我的理解既一致又不完全一致。比如Agile Manifesto明确提到,团队应该“welcome changing requirements, even late in development”,也就是即使在开发后期,也欢迎需求变化,因为变化可能为客户带来竞争优势。这说明敏捷确实把变化看作正常现象,而不是异常情况。另一方面,Scrum Guide又强调Scrum是围绕Product Goal(产品目标)、Sprint Planning(冲刺计划)和Sprint Goal(冲刺目标)来组织工作的,也就是说,敏捷流程并不是完全没有计划,而是仍然需要明确目标,并在较短周期内进行计划和调整。查完这些资料后,我的感觉是:敏捷反对的并不是计划,而是那种试图在项目最开始就把所有细节永久固定下来的计划。

根据我的实践,平时做课程作业或者小项目时,如果一开始完全不规划,只想着边做边改,往往很快就会遇到问题:有人不知道先做什么,有人做到一半才发现理解不一致,甚至写出来的模块接口都对不上,最后返工很多。相反,如果一开始就把界面、功能、数据库、技术细节全部定死,后面一旦发现需求理解错了,或者实现成本比预期高,就会觉得前面的计划反而成了负担。所以从我的经验来看,项目早期确实需要计划,但这个计划更像是先把目标、优先级和大方向说清楚,而不是把所有实现细节都提前锁死。

我的困惑是:敏捷开发到底要求团队在项目开始前计划到什么程度,才既不会因为计划过多而失去灵活性,也不会因为计划过少而导致混乱?进一步说,哪些内容应该在前期尽量明确,比如产品目标、核心需求、任务优先级;哪些内容又应该留到迭代过程中再根据反馈逐步决定?我觉得书中拥抱变化的原则是对的,但真正困难的不是接受这个原则,而是在真实项目中判断计划和变化各自应该占多大比重。

需求分析真的能在项目早期说清楚吗?

这个问题来自第8章需求分析的相关内容。书中强调,需求分析是软件工程中非常重要的一步,团队需要尽可能弄清楚用户到底需要什么,明确项目的目标、用户群体、使用场景和产品价值。书中还介绍了如 NABCD 等方法,帮助开发者更清晰地描述需求、分析用户痛点,并从需求出发推动后续的设计与实现。

书中的叙述给我的感觉是:只要团队足够重视需求分析、采用合适的方法,就能够在项目早期把需求比较清楚地整理出来。但结合我自己的经验,我觉得很多时候问题恰恰在于:用户自己在项目早期也未必知道自己真正想要什么。

在很多实际场景中,用户最开始提出的往往只是一个模糊的想法,而不是一个清晰、稳定、可直接实现的需求。比如用户可能会说“我想做一个方便大家交流的平台”“我想做一个智能化的管理系统”,但这些描述往往过于宽泛。只有在真的做出一些原型、交互界面甚至初步版本之后,用户才会逐渐意识到自己真正关心的是什么,也会不断修改原有想法。也就是说,需求很多时候并不是在一开始就摆在那里等着我们去分析,而是在项目推进过程中被逐步发现、澄清和修正的。

我查阅了一些资料后,也发现不少软件工程实践都强调需求具有变化性。尤其是在互联网产品和创新型项目中,需求变更几乎是常态。敏捷开发之所以强调迭代和反馈,本身就说明软件开发未必能够在一开始把所有需求完整定义清楚。如果需求本身还在变化,那么前期把需求说清楚这件事,是否本来就只能做到一个相对有限的程度?

结合这些想法,需求分析当然重要,但它的作用可能并不是在项目一开始就彻底说清楚需求,而是帮助团队在当前阶段形成一个尽可能清晰的共识,并为后续的验证、迭代和修正打下基础。换句话说,我觉得需求分析更像是一个持续进行的过程,而不只是项目开始时的一次性工作。

因此,我真正的困惑是:教材在强调需求分析的重要性时,是否默认了需求是可以较早被明确的前提?如果面对的是探索性较强、用户自己也并不清楚真实需求的项目,那么需求分析的方法和目标是否也应该随之变化?

书中强调创新要考虑兼容大众习惯和已有系统,那真正颠覆式创新怎么办?

这个问题主要来自《构建之法》第16.1.3节“迷思之三:好的想法会赢”。书中提到,一个创新想法要想被接受,不能只看它本身是否先进,还要考虑很多现实条件,例如是否能让利益相关者看到好处、是否有相对优势、以及它和目前大众习惯、已有系统是否兼容。教材还用 QWERTY 键盘和 Dvorak 键盘的例子说明:即使一个方案在理论上更高效,如果它和既有使用习惯不兼容,推广起来也会非常困难。

这个判断对于渐进式创新当然很有说服力,但如果一项创新本身就是要改变用户习惯、打破旧系统的限制,那它一开始往往就不可能兼容。如果把兼容大众习惯和已有系统看得太重要,会不会导致创新只能是在原有框架里的优化,而很难产生真正有突破性的变化?

我之所以会有这个困惑,是因为我觉得兼容性确实能降低推广成本,但它也可能在无形中限制创新的方向。很多真正有影响力的新事物,在刚出现时都不是为了迎合旧习惯,而是为了改变旧习惯。如果当时只因为不兼容就否定它们,那很多后来被证明有价值的创新,可能一开始就不会被认真对待。所以我会怀疑书中的这条建议,到底是在说明好创新应该尽量不改变用户,还是只是在说明创新要想成功落地,必须考虑现实阻力?

结合第16.2节“创新的时机”再看,我对这个问题的理解又发生了一点变化。书里用黄金点游戏说明,一个群体的共识通常不会一下子跳到最激进的位置,成功的创新往往只是比大众平均认知先走一小步。教材还提到,很多技术并不是因为不够先进而失败,而是因为推出得太早,市场和用户还没有准备好接受它。这样看下来,我觉得第16.2节其实在某种程度上补充了第16.1.3节:书里强调兼容性,未必是在反对颠覆式创新本身,而是在提醒我们,再好的创新也要面对社会接受的节奏。

但我的疑问并没有完全消失。因为如果按照这个思路理解,书中的建议更像是在讨论如何让创新更容易被大众接受,而不是在讨论什么样的创新更有突破性。也就是说,一个创新完全可能在方向上是颠覆性的,但在落地方式上必须表现得相对兼容、相对克制,先让用户接受第一步,再逐渐改变习惯。我比较认同这种解释,但也正因为如此,我会进一步追问:当教材说创新要兼容大众习惯和已有系统时,它强调的到底是创新内容本身不要太激进,还是创新进入市场的路径不能太激进?这两者其实不是一回事。

因此,我真正想问的是:如果一项创新的价值,恰恰在于改变旧习惯、突破旧系统,那么我们应该把兼容性理解为创新必须满足的原则,还是只把它理解为创新在特定阶段、特定市场条件下的一种策略?如果只是策略,那么它适用的边界在哪里?什么时候我们应该为了推广而向现实妥协,什么时候又应该坚持那些暂时不兼容但可能更有长期价值的方向?

posted @ 2026-03-09 20:53  juuuuuu  阅读(10)  评论(0)    收藏  举报