软件项目管理学习笔记-从软件危机到敏捷与DevOps

软件项目管理这节课,我把笔记整理成了这篇(软件危机 → 敏捷 → DevOps → 测试)

一节课下来脑子有点满,回来照着笔记重新捋了一遍。这篇既是复习,也算给后面要考试、要写课程设计的同学留个参考。哪里理解偏了,欢迎评论区指正。


写在前面

今天这门课的信息量确实不小。老师在黑板上画了一堆箭头和框,从"软件到底是什么"一路扯到敏捷、Scrum、DevOps、微服务,最后落在测试和 CMMI 上。我当时记得手忙脚乱,有些地方只有几个关键词,下面这些是我按课上的逻辑把笔记补全、串起来之后的版本。

如果你也是刚接触软件项目管理,可以先记住一句话:这门课真正想教的不是"怎么把活干完",而是"怎么在需求一直变的情况下,还能把活按预期交出去"。


一、先问一个根本问题:软件为什么这么难管

老师一上来就抛了个问题:硬件年年翻倍地涨性能,软件为什么还是动不动就延期、出 Bug、超预算?

这就是我们常说的软件危机(Software Crisis)。这个说法不是随便起的,1968 年北约(NATO)在联邦德国办的一场学术会议上,正式提出了这个概念。那时候计算机硬件突飞猛进,软件开发却还停在"一个人闷头写代码、能跑就行"的作坊阶段,规模一大就全崩了。

课上列的表现,我归了一下,大概这么几类:

典型表现 说人话就是
进度和成本失控 预算一超再超,交付时间一拖再拖
质量不可靠 Bug 多、稳定性差,出错代价还挺大
维护困难 改一个 Bug 引出三个新 Bug
文档缺失 除了代码啥也没有,换个人接手等于重写
用户不满意 辛辛苦苦做出来,根本不是用户想要的

再往下想一层,为什么软件这么特殊?老师讲的几条我印象很深:

  • 软件是逻辑产品,不是物理部件,看不见摸不着,进度和质量都很难直观衡量;
  • 软件的复杂度随规模呈指数级上升,不是线性叠加;
  • 软件不会用坏,但会过时------需求一变,就得改,改起来又牵一发动全身。

想摆脱危机,靠"更努力地写代码"是没用的,得换一套工程化的打法。软件工程这门学科,就是这么被逼出来的。


二、软件工程三要素:方法、工具、过程

这三个词看着挺虚,用盖楼类比一下就清楚了。

要素 含义 盖楼类比
方法(Method) 告诉你"怎么做"的技术路线 施工图纸和工艺规范
工具(Tool) 支撑方法落地的环境和软件 脚手架、起重机
过程(Process) 规定什么时候做什么、产出什么 先打地基、再砌主体、最后装修

光有菜谱(方法)不会用锅(工具)不行,光有锅不知道先干啥(过程)也不行。三者得配合。

基于这套思路,一个项目的成功标准也就明确了:在给定成本、进度的前提下,做出满足用户需求的高质量软件。 注意这里的顺序------成本和进度是前提条件,不是可以随便突破的。


三、项目管理铁三角:范围、时间、成本(中间还坐着质量)

这是整节课我觉得最有用、也最容易被忽略的一个模型。

项目管理里公认的三重约束是范围、时间、成本:范围决定做多少东西,时间决定多久交付,成本决定投多少钱和人。这三条边是互相牵制的------扩大范围,通常就得加时间或加钱;要压缩工期,就得砍需求或加人手。
#mermaid-svg-dqwArHjidNTvga40{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dqwArHjidNTvga40 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dqwArHjidNTvga40 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dqwArHjidNTvga40 .error-icon{fill:#552222;}#mermaid-svg-dqwArHjidNTvga40 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dqwArHjidNTvga40 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dqwArHjidNTvga40 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dqwArHjidNTvga40 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dqwArHjidNTvga40 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dqwArHjidNTvga40 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dqwArHjidNTvga40 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dqwArHjidNTvga40 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dqwArHjidNTvga40 .marker.cross{stroke:#333333;}#mermaid-svg-dqwArHjidNTvga40 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dqwArHjidNTvga40 p{margin:0;}#mermaid-svg-dqwArHjidNTvga40 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-dqwArHjidNTvga40 .cluster-label text{fill:#333;}#mermaid-svg-dqwArHjidNTvga40 .cluster-label span{color:#333;}#mermaid-svg-dqwArHjidNTvga40 .cluster-label span p{background-color:transparent;}#mermaid-svg-dqwArHjidNTvga40 .label text,#mermaid-svg-dqwArHjidNTvga40 span{fill:#333;color:#333;}#mermaid-svg-dqwArHjidNTvga40 .node rect,#mermaid-svg-dqwArHjidNTvga40 .node circle,#mermaid-svg-dqwArHjidNTvga40 .node ellipse,#mermaid-svg-dqwArHjidNTvga40 .node polygon,#mermaid-svg-dqwArHjidNTvga40 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dqwArHjidNTvga40 .rough-node .label text,#mermaid-svg-dqwArHjidNTvga40 .node .label text,#mermaid-svg-dqwArHjidNTvga40 .image-shape .label,#mermaid-svg-dqwArHjidNTvga40 .icon-shape .label{text-anchor:middle;}#mermaid-svg-dqwArHjidNTvga40 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dqwArHjidNTvga40 .rough-node .label,#mermaid-svg-dqwArHjidNTvga40 .node .label,#mermaid-svg-dqwArHjidNTvga40 .image-shape .label,#mermaid-svg-dqwArHjidNTvga40 .icon-shape .label{text-align:center;}#mermaid-svg-dqwArHjidNTvga40 .node.clickable{cursor:pointer;}#mermaid-svg-dqwArHjidNTvga40 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dqwArHjidNTvga40 .arrowheadPath{fill:#333333;}#mermaid-svg-dqwArHjidNTvga40 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dqwArHjidNTvga40 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dqwArHjidNTvga40 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dqwArHjidNTvga40 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dqwArHjidNTvga40 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dqwArHjidNTvga40 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dqwArHjidNTvga40 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dqwArHjidNTvga40 .cluster text{fill:#333;}#mermaid-svg-dqwArHjidNTvga40 .cluster span{color:#333;}#mermaid-svg-dqwArHjidNTvga40 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dqwArHjidNTvga40 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dqwArHjidNTvga40 rect.text{fill:none;stroke-width:0;}#mermaid-svg-dqwArHjidNTvga40 .icon-shape,#mermaid-svg-dqwArHjidNTvga40 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dqwArHjidNTvga40 .icon-shape p,#mermaid-svg-dqwArHjidNTvga40 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dqwArHjidNTvga40 .icon-shape .label rect,#mermaid-svg-dqwArHjidNTvga40 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dqwArHjidNTvga40 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dqwArHjidNTvga40 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dqwArHjidNTvga40 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 范围 Scope

做什么
质量
时间 Time

多久
成本 Cost

多少钱
质量是底线

不能被挤爆

老师特别强调了一点,也可以用一句很扎心的话概括:

范围、时间、成本,你最多只能锁住两个。如果三个都要锁死,那塌掉的必然是质量。

现实里项目失控,十有八九是从范围蔓延(Scope Creep)开始的。需求一个接一个地"顺手加一下",每个单独看都不大,攒在一起就是灾难。所以范围管理最关键的动作不是写文档,而是建立变更规则------任何新增需求都要先回答三个问题:影响哪些任务、多花多少工作量、会不会挤压原有交付。这道门槛立住了,项目才不会被零碎变更拖垮。


四、需求:别把"用户说的"直接当成"要做的"

课上反复出现的一个词是用户需求,而且箭头最终指向的不是"功能",是"用户价值"。

需求管理大致是这么一条链:收集 → 分析 → 确认 → 变更控制。看起来简单,难的是两件事:

一是听清真实需求。用户说"我要一匹更快的马",背后其实是"我要更快到达目的地"。把原话直接翻译成功能,很容易做出一个没人用的东西。

二是管住变更。需求变是常态,敏捷甚至是欢迎变化的,但"欢迎变化"不等于"随便变"。每次变更都要评估它对范围、进度、成本的影响,走一遍审批,这才叫可控。


五、开发模式这条主线:从瀑布到敏捷

这是今天的大头。老师按时间线把几种模式串了一遍。

5.1 敏捷宣言:四条价值观 + 十二条原则

2001 年,17 位软件领域的大佬在美国犹他州雪鸟(Snowbird)滑雪场开了三天会,憋出了那份著名的《敏捷软件开发宣言》。四条价值观:

  1. 个体和互动 高于 流程和工具
  2. 可工作的软件 高于 详尽的文档
  3. 客户合作 高于 合同谈判
  4. 响应变化 高于 遵循计划

注意"高于"不是"否定右边",而是左边更被重视。在此基础上还有十二条原则,核心包括:持续尽早交付有价值的软件、拥抱需求变化、用短周期频繁交付、业务与开发每天在一起、以可工作软件衡量进度、保持可持续的开发节奏、追求技术卓越和良好设计、简洁为本、最好的架构出自自组织团队、团队定期反思改进等。

5.2 Scrum:记住"3-3-5"

Scrum 是敏捷里最常用的一套框架,我用课上的讲法拆成"3 个角色 + 3 个工件 + 5 个事件"来记:

  • 三个角色:产品负责人(PO,管需求优先级和产品价值)、Scrum Master(管流程是否被正确执行、帮团队扫清障碍)、开发团队(对交付负责,自组织);
  • 三个工件:产品待办列表(Product Backlog)、迭代待办列表(Sprint Backlog)、产品增量(Increment);
  • 五个事件:Sprint 本身、Sprint 计划会、每日站会、Sprint 评审会、Sprint 回顾会。

Sprint 一般 2--4 周,一旦开始就尽量不改目标、不降质量。每个 Sprint 结束必须产出一个"潜在可交付"的增量,这是硬要求。
#mermaid-svg-ahhVN7hwwHjGBuxL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ahhVN7hwwHjGBuxL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ahhVN7hwwHjGBuxL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ahhVN7hwwHjGBuxL .error-icon{fill:#552222;}#mermaid-svg-ahhVN7hwwHjGBuxL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ahhVN7hwwHjGBuxL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ahhVN7hwwHjGBuxL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ahhVN7hwwHjGBuxL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ahhVN7hwwHjGBuxL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ahhVN7hwwHjGBuxL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ahhVN7hwwHjGBuxL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ahhVN7hwwHjGBuxL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ahhVN7hwwHjGBuxL .marker.cross{stroke:#333333;}#mermaid-svg-ahhVN7hwwHjGBuxL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ahhVN7hwwHjGBuxL p{margin:0;}#mermaid-svg-ahhVN7hwwHjGBuxL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ahhVN7hwwHjGBuxL .cluster-label text{fill:#333;}#mermaid-svg-ahhVN7hwwHjGBuxL .cluster-label span{color:#333;}#mermaid-svg-ahhVN7hwwHjGBuxL .cluster-label span p{background-color:transparent;}#mermaid-svg-ahhVN7hwwHjGBuxL .label text,#mermaid-svg-ahhVN7hwwHjGBuxL span{fill:#333;color:#333;}#mermaid-svg-ahhVN7hwwHjGBuxL .node rect,#mermaid-svg-ahhVN7hwwHjGBuxL .node circle,#mermaid-svg-ahhVN7hwwHjGBuxL .node ellipse,#mermaid-svg-ahhVN7hwwHjGBuxL .node polygon,#mermaid-svg-ahhVN7hwwHjGBuxL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ahhVN7hwwHjGBuxL .rough-node .label text,#mermaid-svg-ahhVN7hwwHjGBuxL .node .label text,#mermaid-svg-ahhVN7hwwHjGBuxL .image-shape .label,#mermaid-svg-ahhVN7hwwHjGBuxL .icon-shape .label{text-anchor:middle;}#mermaid-svg-ahhVN7hwwHjGBuxL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ahhVN7hwwHjGBuxL .rough-node .label,#mermaid-svg-ahhVN7hwwHjGBuxL .node .label,#mermaid-svg-ahhVN7hwwHjGBuxL .image-shape .label,#mermaid-svg-ahhVN7hwwHjGBuxL .icon-shape .label{text-align:center;}#mermaid-svg-ahhVN7hwwHjGBuxL .node.clickable{cursor:pointer;}#mermaid-svg-ahhVN7hwwHjGBuxL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ahhVN7hwwHjGBuxL .arrowheadPath{fill:#333333;}#mermaid-svg-ahhVN7hwwHjGBuxL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ahhVN7hwwHjGBuxL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ahhVN7hwwHjGBuxL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ahhVN7hwwHjGBuxL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ahhVN7hwwHjGBuxL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ahhVN7hwwHjGBuxL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ahhVN7hwwHjGBuxL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ahhVN7hwwHjGBuxL .cluster text{fill:#333;}#mermaid-svg-ahhVN7hwwHjGBuxL .cluster span{color:#333;}#mermaid-svg-ahhVN7hwwHjGBuxL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ahhVN7hwwHjGBuxL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ahhVN7hwwHjGBuxL rect.text{fill:none;stroke-width:0;}#mermaid-svg-ahhVN7hwwHjGBuxL .icon-shape,#mermaid-svg-ahhVN7hwwHjGBuxL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ahhVN7hwwHjGBuxL .icon-shape p,#mermaid-svg-ahhVN7hwwHjGBuxL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ahhVN7hwwHjGBuxL .icon-shape .label rect,#mermaid-svg-ahhVN7hwwHjGBuxL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ahhVN7hwwHjGBuxL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ahhVN7hwwHjGBuxL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ahhVN7hwwHjGBuxL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 产品待办列表

按价值排序
Sprint 计划会
迭代待办列表
每日站会

开发中
Sprint 评审会

演示增量
回顾会

改进流程

5.3 极限编程 XP:把工程实践做到极致

如果说 Scrum 管的是"节奏和协作",XP 管的就是"代码质量"。它把几个好习惯推向了极端:

  • 测试驱动开发 TDD:先写会失败的测试(红)→ 用最简单的方式让它通过(绿)→ 重构(重构),也就是"红-绿-重构"循环;
  • 结对编程:两个人共用一台电脑,一个写、一个审,角色轮换;
  • 持续集成、重构、简单设计、集体代码所有权。

课上还提到 XP 的价值观:沟通、简单、反馈、勇气。个人觉得"简单"这条最反常识也最实用------YAGNI(You Aren't Gonna Need It),现在用不到的功能就别提前设计。

5.4 看板 vs Scrum:到底选哪个

这俩经常被拿来对比,其实不是谁更先进,而是解决不同的问题。我用一张表整理了一下:

维度 看板(Kanban) Scrum
交付节奏 持续流动,没有固定周期 固定迭代,一般 1--4 周
需求进入 按优先级随时拉动 按 Sprint 承诺纳入
变更弹性 高,随时能插单 较低,Sprint 内尽量冻结
管理重点 在制品(WIP)、流速、瓶颈 迭代目标、燃尽、交付承诺
适合场景 运维、缺陷处理、插单多的团队 目标明确、节奏稳定的产品研发

一句话记:想"少阻塞、快流转"选看板,想"定周期、强承诺"选 Scrum。 现实里很多团队其实是混合着用------看板管流动,再保留每日站会和定期回顾。


六、工程化落地:DevOps 与 CI/CD

敏捷解决的是"做什么、怎么排节奏",DevOps 解决的是"怎么让开发和运维不再互相甩锅"。

DevOps 不是某个工具,而是文化 + 方法论 + 工具链三位一体,核心目标是打通开发、测试、运维、安全,让交付变成一条自动化的流水线。

最核心的载体就是 CI/CD:

  • 持续集成(CI):开发频繁把代码合到主干,每次提交自动构建、自动跑测试,保证主干随时可用;
  • 持续交付/部署(CD):通过测试的代码自动部署到类生产环境甚至生产环境,配合蓝绿发布、金丝雀发布降低风险。

课上还顺着往下讲到了几个当前很热的词,我简单串一下它们的关系:

  • 云原生:以云为底座,讲究弹性、可扩展、高可用,声明式 API、不可变基础设施是关键词;
  • 微服务:按业务边界把单体应用拆成一组松耦合、能独立部署和扩缩容的小服务;配合容器(Docker)、编排(Kubernetes)、API 网关、服务网格一起用;
  • API 与集成:服务之间、系统之间靠 API 打通,"平台化 + 开放 API"是常见形态;
  • AI 大模型:这两年对研发流程的冲击很直接------代码生成、测试用例生成、缺陷定位、需求分析都在被重塑。

这里我想补一句,也是老师提到的趋势:AI 不会让铁三角的约束消失。效率工具能提效,但范围、时间、成本的张力还在,瓶颈正在从"执行层"往"决策层"转移------你得更清楚要做什么、什么先做。


七、质量与测试:越早发现 Bug 越省钱

这是笔记里圈圈最多的部分。核心结论就一句:

缺陷发现得越晚,修复成本越高。需求阶段是 1 倍,开发阶段约 10 倍,到了生产环境可能就是 100 倍。

7.1 测试的四个阶段

阶段 测什么 谁来做 目标
单元测试 最小代码单元(函数、方法) 开发 底层逻辑正确
集成测试 模块之间、接口之间的交互 开发为主,测试协助 模块拼起来能通
系统测试 完整系统 + 业务全流程 测试人员 整体功能与质量达标
验收测试 交付效果 客户/产品 满足业务需求,可上线

另外还有两个高频词别搞混:回归测试 是"改了代码之后重跑老用例,确认没改坏原来的功能";冒烟测试是"上线前快速过一遍主流程,看版本能不能进入正式测试"。

7.2 测试金字塔

这是指导测试投入比例的一个经典模型,由 Mike Cohn 提出:
#mermaid-svg-Uj5Ng7Km5odoFqmZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .error-icon{fill:#552222;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .marker.cross{stroke:#333333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Uj5Ng7Km5odoFqmZ p{margin:0;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .cluster-label text{fill:#333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .cluster-label span{color:#333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .cluster-label span p{background-color:transparent;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .label text,#mermaid-svg-Uj5Ng7Km5odoFqmZ span{fill:#333;color:#333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .node rect,#mermaid-svg-Uj5Ng7Km5odoFqmZ .node circle,#mermaid-svg-Uj5Ng7Km5odoFqmZ .node ellipse,#mermaid-svg-Uj5Ng7Km5odoFqmZ .node polygon,#mermaid-svg-Uj5Ng7Km5odoFqmZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .rough-node .label text,#mermaid-svg-Uj5Ng7Km5odoFqmZ .node .label text,#mermaid-svg-Uj5Ng7Km5odoFqmZ .image-shape .label,#mermaid-svg-Uj5Ng7Km5odoFqmZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .rough-node .label,#mermaid-svg-Uj5Ng7Km5odoFqmZ .node .label,#mermaid-svg-Uj5Ng7Km5odoFqmZ .image-shape .label,#mermaid-svg-Uj5Ng7Km5odoFqmZ .icon-shape .label{text-align:center;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .node.clickable{cursor:pointer;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .arrowheadPath{fill:#333333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Uj5Ng7Km5odoFqmZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Uj5Ng7Km5odoFqmZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Uj5Ng7Km5odoFqmZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .cluster text{fill:#333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .cluster span{color:#333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Uj5Ng7Km5odoFqmZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .icon-shape,#mermaid-svg-Uj5Ng7Km5odoFqmZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .icon-shape p,#mermaid-svg-Uj5Ng7Km5odoFqmZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .icon-shape .label rect,#mermaid-svg-Uj5Ng7Km5odoFqmZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Uj5Ng7Km5odoFqmZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Uj5Ng7Km5odoFqmZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Uj5Ng7Km5odoFqmZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} UI / 端到端测试 ------ 约 10%

慢、脆、维护成本高
集成测试 ------ 约 20%

验证模块间交互
单元测试 ------ 约 70%

快、稳、定位准

原则是底层多、上层少。单元测试跑得快、定位准,是质量的底座;端到端测试最接近真实用户,但运行慢、容易因页面一点改动就崩。很多团队的毛病是金字塔倒过来了------一堆 E2E,单元测试几乎为零,结果流水线又慢又脆。

7.3 除测试之外的质量手段

  • 代码评审(Code Review):提交前让人看一眼,成本最低的缺陷拦截;
  • 静态分析:不运行代码,靠工具扫出空指针、内存泄漏、代码坏味道;
  • 测试前移:测试人员提前参与需求评审,而不是等开发完了才进场。

顺带说一句,AI 正在改变测试的形态:自动生成用例、脚本自愈、缺陷根因分析,这些都有落地案例了。但"测什么、测多深、哪些必须修"这类判断,目前还得靠人。


八、过程成熟度:CMMI 的五级台阶

课上最后讲到怎么衡量一个组织"会不会做软件"。答案之一就是 CMMI(能力成熟度模型集成),它源自 1987 年卡内基梅隆大学软件工程研究所的 CMM,后来整合成一个统一框架。

等级 名称 特征
1 初始级 无序,成功靠个人英雄主义
2 已管理级 有基本的管理制度和规程
3 已定义级 过程标准化、文档化,全组织统一
4 量化管理级 用数据量化管理过程,可预测
5 优化级 持续改进,用创新和技术优化流程

一个提醒:CMMI 的价值在"持续改进",而不是拿一张证书。课上也提到了 MSF 这类过程模板,本质都是帮团队把过程规范起来。另外国内也有对应的推荐性国家标准(GB/T 45989---2025)在推软件过程能力成熟度。


九、一张图把今天串起来

#mermaid-svg-OvdmwlfPfQzB8ThS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OvdmwlfPfQzB8ThS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OvdmwlfPfQzB8ThS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OvdmwlfPfQzB8ThS .error-icon{fill:#552222;}#mermaid-svg-OvdmwlfPfQzB8ThS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OvdmwlfPfQzB8ThS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OvdmwlfPfQzB8ThS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OvdmwlfPfQzB8ThS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OvdmwlfPfQzB8ThS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OvdmwlfPfQzB8ThS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OvdmwlfPfQzB8ThS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OvdmwlfPfQzB8ThS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OvdmwlfPfQzB8ThS .marker.cross{stroke:#333333;}#mermaid-svg-OvdmwlfPfQzB8ThS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OvdmwlfPfQzB8ThS p{margin:0;}#mermaid-svg-OvdmwlfPfQzB8ThS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-OvdmwlfPfQzB8ThS .cluster-label text{fill:#333;}#mermaid-svg-OvdmwlfPfQzB8ThS .cluster-label span{color:#333;}#mermaid-svg-OvdmwlfPfQzB8ThS .cluster-label span p{background-color:transparent;}#mermaid-svg-OvdmwlfPfQzB8ThS .label text,#mermaid-svg-OvdmwlfPfQzB8ThS span{fill:#333;color:#333;}#mermaid-svg-OvdmwlfPfQzB8ThS .node rect,#mermaid-svg-OvdmwlfPfQzB8ThS .node circle,#mermaid-svg-OvdmwlfPfQzB8ThS .node ellipse,#mermaid-svg-OvdmwlfPfQzB8ThS .node polygon,#mermaid-svg-OvdmwlfPfQzB8ThS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OvdmwlfPfQzB8ThS .rough-node .label text,#mermaid-svg-OvdmwlfPfQzB8ThS .node .label text,#mermaid-svg-OvdmwlfPfQzB8ThS .image-shape .label,#mermaid-svg-OvdmwlfPfQzB8ThS .icon-shape .label{text-anchor:middle;}#mermaid-svg-OvdmwlfPfQzB8ThS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OvdmwlfPfQzB8ThS .rough-node .label,#mermaid-svg-OvdmwlfPfQzB8ThS .node .label,#mermaid-svg-OvdmwlfPfQzB8ThS .image-shape .label,#mermaid-svg-OvdmwlfPfQzB8ThS .icon-shape .label{text-align:center;}#mermaid-svg-OvdmwlfPfQzB8ThS .node.clickable{cursor:pointer;}#mermaid-svg-OvdmwlfPfQzB8ThS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OvdmwlfPfQzB8ThS .arrowheadPath{fill:#333333;}#mermaid-svg-OvdmwlfPfQzB8ThS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OvdmwlfPfQzB8ThS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OvdmwlfPfQzB8ThS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OvdmwlfPfQzB8ThS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OvdmwlfPfQzB8ThS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OvdmwlfPfQzB8ThS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OvdmwlfPfQzB8ThS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OvdmwlfPfQzB8ThS .cluster text{fill:#333;}#mermaid-svg-OvdmwlfPfQzB8ThS .cluster span{color:#333;}#mermaid-svg-OvdmwlfPfQzB8ThS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OvdmwlfPfQzB8ThS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OvdmwlfPfQzB8ThS rect.text{fill:none;stroke-width:0;}#mermaid-svg-OvdmwlfPfQzB8ThS .icon-shape,#mermaid-svg-OvdmwlfPfQzB8ThS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OvdmwlfPfQzB8ThS .icon-shape p,#mermaid-svg-OvdmwlfPfQzB8ThS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OvdmwlfPfQzB8ThS .icon-shape .label rect,#mermaid-svg-OvdmwlfPfQzB8ThS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OvdmwlfPfQzB8ThS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OvdmwlfPfQzB8ThS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OvdmwlfPfQzB8ThS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 软件危机

复杂度高、难衡量
软件工程

方法·工具·过程
项目管理铁三角

范围·时间·成本·质量
需求管理

对应用户价值
开发模式

瀑布 → 敏捷 Scrum/XP/看板
工程化

DevOps / CI-CD / 云原生 / 微服务
质量保障

测试分层 + 代码评审 + 静态分析
过程改进

CMMI 成熟度
最终目标

按预期交付可用的软件


十、写在最后:三句自己总结的话

  1. 管项目,先管范围。 需求可以不完美,但"本期承诺做什么"必须说清楚,变更必须走门槛。绝大多数项目不是死在技术上,是死在范围失控上。
  2. 敏捷不是"快点跑",是"小步走 + 快反馈"。 短迭代、持续集成、每日站会,本质都是在缩短反馈周期,让问题早点暴露------因为越早发现越便宜。
  3. 质量和测试不是最后一道工序,而是贯穿全程的习惯。 单元测试、代码评审、测试前移,这些看着"拖慢速度"的动作,长期反而最省时间。

这节课最大的收获,其实是意识到软件项目管理不是一堆表格和流程的堆砌,而是一套在约束里做取舍的方法论。范围、时间、成本、质量四者不可兼得,能做的就是守住底线、动态平衡。

如果这篇笔记对你有帮助,点个赞让更多同学看到;有讲得不对的地方也欢迎评论区一起交流。


关键词 / 标签:#软件项目管理 #敏捷开发 #Scrum #DevOps #CI/CD #软件测试 #测试金字塔 #CMMI #需求管理 #软件工程

参考方向:《敏捷软件开发宣言》、Scrum 指南(2020 版)、CMMI 能力成熟度模型、测试金字塔模型(Mike Cohn)、GB/T 45989---2025《软件过程能力成熟度模型》。

相关推荐
传奇开心果编程2 小时前
【SwiftUI入门练中学】第7课 动画与手势:让界面更灵动
学习·macos·ui·ios·swiftui·swift
效率工作实验室2 小时前
AI Agent 管理平台如何与现有 DevOps 和 ITSM 体系集成?
ai·agent·devops·集成·管理平台
幼儿园蛋小黄2 小时前
SPI 多点触摸屏学习嵌入式总结
学习
dadaobusi2 小时前
学习:顶点着色器输出后,三角形为什么是四个分量
学习
lengxuenong3 小时前
枚举及其优化学习手册
c++·学习·算法·青少年编程
M78佐菲4 小时前
ARM学习笔记(12)
linux·arm开发·笔记·嵌入式硬件·学习
奇思妙想聪明勤奋的小羊4 小时前
ai-agent-book第五章:Coding Agent 与通用 Agent 学习笔记
人工智能·笔记·学习
优化Henry4 小时前
BBU与RRU光链路详解:从双纤一收一发到单纤双向
网络·笔记·学习·5g·tdd
yi0114 小时前
DAY17: LeetCode 139|单词拆分:从“把单词删掉”到用 DP 记录合法切口
人工智能·笔记·python·算法·leetcode·动态规划