[{"categories":["技术笔记"],"collections":null,"content":"软件工程基础","date":"2026-08-20","objectID":"/posts/software-engineering/","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/"},{"categories":["技术笔记"],"collections":null,"content":"软件： 概念：是计算机系统中与硬件相互依存的另一部分，包括程序、数据及其相关文档的完整集合 数据：是使程序能够适当处理信息的数据结构 程序：是能够完成预定功能和性能的可执行指令序列 文档：是开发、使用和维护过程中程序所需要的图文资料 ## 软件危机： 概念：在计算机软件开发和维护过程中所遇到的一系列严重问题，主要包括开发和维护。 表现： 对软件开发成本和进度估算不准确。 软件质量不可靠。 软件不可维护。 没有适当的文档资料。 软件成本在计算机系统中所占比例逐年上升。 软件开发生产率低。 原因： 忽视需求分析 轻视软件维护 没有认识到程序只是软件的一部分（很多人的共性问题） 没有认识到软件开发只是软件漫长生命周期中一个比较次要的阶段 越到后期如果引入变动则代价越高 软件是逻辑实体，具有不可见性，所以管理和控制较为困难 软件不会磨损，维护意味着需要修改原来的设计，维护困难 软件规模庞大，程序复杂性随规模增加而增加 解决方法： 对计算机软件应该有正确的认识 要吸取和借鉴人类长期从事各种工程项目积累的原理、概念、技术和方法 积极开发和使用计算机辅助开发软件 探索更好更有效的管理措施和手段对开发过程进行控制和管理 ## 软件工程： 概念： 采用工程的概念、原理、技术和方法来开发与维护软件，把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来，经济的开发出高质量的软件并维护它 原则： 按软件生存期分阶段制定计划并认真实施 坚持进行阶段评审 坚持严格的产品控制 使用现代程序设计技术 结果能够得到清楚的审查 用人少而精 承认不断改进软件工程实践的必要性 ### 软件工程方法学： 把在软件生命周期全过程中使用的一整套技术方法的集合称之为方法学，也称为泛型。软件工程方法学包含三个要素：方法、工具、过程 方法：完成软件开发各项任务的技术方法，回答\u0026quot;怎么做\u0026quot;的问题 工具：为运用方法提供的自动或半自动软件工程支撑环境 过程：是为了获得高质量软件所需要完成的一系列任务框架，回答\u0026quot;何时做\u0026quot;的问题 ### 传统方法学： 采用结构化技术完成软件开发各项任务 把软件生命周期的全过程依次划分为若干阶段 每个阶段开始和结束都有严格标准 每个阶段结束后要有严格审查 ### 面向对象方法学： 把对象作为融合了数据及在数据上的操作行为的统一的软件构件 把所有对象划分为类 按照父类与子类的关系，把若干类组成层次结构的系统 对象彼此间仅能通过发送消息互相联系 ## 软件生命周期： ### 定义： 角色：系统分析员 问题定义：弄清用户要解决什么问题，需要得到用户确认。关于问题性质、工程目标和工程规模的书面报告。 可行性研究：系统分析和设计过程。研究问题的范围，探索这个问题是否值得去解，是否有可行的解决办法。 需求分析：为了解决这个问题，系统需要具备怎样的功能。软件需求规格说明书(SRS)。 ### 开发： 总体设计：设计软件结构，确定程序由哪些模块组成以及模块间的关系。设计程序的体系结构，可以应用设计模式。 详细设计：针对每个模块，设计详细规格说明，确定算法和数据结构，可以应用设计模式。 编码：将详细设计内容用语言实现。 单元测试：测试每个单一模块。 综合测试：通过各种类型测试使软件达到预定要求。 ### 维护： 改正性维护：即诊断和改正在使用过程中发现的软件错误; 适应性维护：即修改软件以适应环境的变化; 完善性维护：即根据用户的要求改进或扩充软件使它更完善; 预防性维护：即修改软件，为将来的维护活动预先做准备。 ## 软件生命周期模型： 软件过程：是为了获得高质量软件所需要完成的一系列任务框架，它规定了完成任务的工作步骤。通常用软件生命周期模型来描述软件过程。 模型 核心特点 适用场景 瀑布模型 线性串行，阶段依次执行，变更成本高 需求固定、合规要求高的军工传统项目 V 模型 开发与测试阶段一一对应，测试提前规划 嵌入式、安全关键类软件 增量模型 先定整体架构，分模块分批交付 大型复杂系统 迭代模型 多轮迭代循环，逐步完善产品，接纳需求变化 需求不明确，需要持续打磨的产品 螺旋模型 风险驱动，循环迭代结合原型 大型高风险、需求不确定项目 快速原型模型 搭建原型确认需求，抛弃原型后正式开发 需求模糊、交互界面复杂的中小型项目 Scrum 敏捷 Sprint 短迭代，持续交付，快速响应需求变更 互联网产品，需求频繁变化项目 ","date":"2026-08-20","objectID":"/posts/software-engineering/:1:0","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#软件"},{"categories":["技术笔记"],"collections":null,"content":"瀑布模型（大型复杂） 阶段串行，上一阶段完成才进入下一阶段，需求前期确定，变更代价大。 flowchart LR A[需求分析] --\u0026gt; B[软件设计] B --\u0026gt; C[编码实现] C --\u0026gt; D[软件测试] D --\u0026gt; E[部署维护] V模型（瀑布扩展） 开发阶段左侧，对应右侧测试，强调测试尽早规划，多用于安全关键系统。 flowchart TD subgraph 开发阶段 A[需求分析] B[概要设计] C[详细设计] D[编码] end subgraph 测试阶段 A1[验收测试] B1[系统测试] C1[集成测试] D1[单元测试] end A -.对应.-\u0026gt;A1 B -.对应.-\u0026gt;B1 C -.对应.-\u0026gt;C1 D -.对应.-\u0026gt;D1 A --\u0026gt; B --\u0026gt; C --\u0026gt; D ","date":"2026-08-20","objectID":"/posts/software-engineering/:1:1","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#瀑布模型大型复杂"},{"categories":["技术笔记"],"collections":null,"content":"增量模型 整体架构先定，分多个增量包逐个开发，每完成一个增量就交付一部分功能给客户 flowchart LR 总架构[整体架构设计] subgraph 增量1 I1A[分析]--\u0026gt;I1D[设计]--\u0026gt;I1C[编码]--\u0026gt;I1T[测试]--\u0026gt;I1OUT[交付客户] end subgraph 增量2 I2A[分析]--\u0026gt;I2D[设计]--\u0026gt;I2C[编码]--\u0026gt;I2T[测试]--\u0026gt;I2OUT[交付客户] end subgraph 增量N INA[分析]--\u0026gt;IND[设计]--\u0026gt;INC[编码]--\u0026gt;INT[测试]--\u0026gt;INOUT[交付客户] end 总架构 --\u0026gt; I1A 总架构 --\u0026gt; I2A 总架构 --\u0026gt; INA ","date":"2026-08-20","objectID":"/posts/software-engineering/:1:2","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#增量模型"},{"categories":["技术笔记"],"collections":null,"content":"迭代模型 完整做一轮完整流程（需求‑设计‑编码‑测试），多轮迭代，每轮迭代完善全部功能，不是只做一部分模块 flowchart TD ITER[迭代开始] --\u0026gt; R[需求调整] R --\u0026gt; D[设计] D --\u0026gt; C[编码] C --\u0026gt; T[测试评审] T --\u0026gt;|未完成| ITER T --\u0026gt;|完成| END[正式发布] ","date":"2026-08-20","objectID":"/posts/software-engineering/:1:3","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#迭代模型"},{"categories":["技术笔记"],"collections":null,"content":"螺旋模型 flowchart TD S[开始] subgraph 一轮螺旋循环 P[制定计划] RISK[风险分析评估] DEV[开发\u0026amp;验证原型] EVAL[客户评审评估] end S --\u0026gt; P P --\u0026gt; RISK RISK --\u0026gt; DEV DEV --\u0026gt; EVAL EVAL --\u0026gt;|风险未消除，继续下一圈| P EVAL --\u0026gt;|风险可控，正式交付| FIN[产品发布] ","date":"2026-08-20","objectID":"/posts/software-engineering/:1:4","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#螺旋模型"},{"categories":["技术笔记"],"collections":null,"content":"快速原型模型 需求模糊、用户说不清完整需求的场景，快速搭建一个可运行的简易原型，给用户体验、收集反馈，反复迭代打磨需求；需求确认后，再开发正式产品。 flowchart LR A[快速需求分析] --\u0026gt; B[构建简易原型] B --\u0026gt; C[用户试用评估原型] C --\u0026gt; D{需求确定?} D -- 否，收集反馈 --\u0026gt; B D -- 是 --\u0026gt; E[抛弃原型，正式开发] E --\u0026gt; F[测试部署交付] ","date":"2026-08-20","objectID":"/posts/software-engineering/:1:5","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#快速原型模型"},{"categories":["技术笔记"],"collections":null,"content":"敏捷开发（主流） 概念：是一套软件开发价值观，来源于《敏捷宣言》，核心：拥抱变化、小步交付、重视人、客户持续反馈，可工作的软件 \u0026gt; 完备的文档，个体和交互 \u0026gt; 过程和工具 工具：白板、在线文档、PingCode、Jira 基于迭代增量模型，除了scrum还有看板、SAFe等模型 #### Scrum 主要负责项目管理 **Sprint（时间盒迭代）**为核心，迭代周期一般 2‑4 周，一个 Sprint 产出可工作、可评审的软件版本。 设施：Product Backlog（全部需求池）、Sprint Backlog（当前Sprint需求池） 角色：产品负责人 PO（排需求优先级）、Scrum Master（保障 Scrum 流程正常运行，协助坚持Scrum 原则）、开发团队（开发、测试） 事件：Sprint 规划会（生成 Sprint 待办）、站会（昨天做了什么、今天做什么、遇到什么阻碍）、Sprint 执行（团队开发测试）、Sprint 评审会（向PO、客户演示软件效果收集反馈）、Sprint 回顾会（复盘总结本次迭代，准备改进措施） flowchart TD A[Product Backlog\u0026lt;br/\u0026gt;产品待办] --\u0026gt; B[Sprint规划会] B --\u0026gt; C[Sprint迭代2‑4周\u0026lt;br/\u0026gt;每日站会] C --\u0026gt; D[Sprint评审会\u0026lt;br/\u0026gt;演示可工作增量] D --\u0026gt; E[Sprint回顾会\u0026lt;br/\u0026gt;复盘改进] E --\u0026gt;|更新需求，开启下一轮迭代| A 图表：看板、燃尽图 看板：任务（需求）状态，包括责任人，时间，进度【待办、进行中、已完成】 燃尽图：折线图，Sprint 迭代周期内，剩余工作量随时间下降的趋势 #### 极限编程XP 主要负责代码开发质量 主要是规定一系列在实际开发和测试中的原则 TDD 测试驱动开发：先写测试用例，再写业务代码，测试先行。 结对编程：两人一台机器，一人写代码，一人实时评审，角色轮换。 重构：不改变外部行为，优化内部代码结构 简单设计：只实现当前需要的功能，拒绝过度设计。 小版本频繁发布 现场客户：客户深度参与，随时澄清需求。 #### DevOps 保证可靠快速的构建、测试、部署、上线运维 CI 持续集成：自动编译，自动测试，频繁合并代码到主干 CD 持续交付：自动把软件构建成可执行文件 CD 持续部署：完全自动部署到生产环境，无需人工审批 容器：把应用和环境打包成镜像解决环境不一致问题 容器管理：批量管理容器，扩容缩容、滚动更新、故障自愈 配置设施：批量配置服务器，用代码管理云服务器 制品仓库：存储Docker镜像、产品软件包 DevOps一般流程包括：代码管理（git）-CI（GitHub Actions）-代码安全（GitHub Actions、SonarQube）-容器（Docker、Kubernetes(K8s)）-配置设施（Ansible）-制品仓库（Harbor）-CD（GitHub Actions、ArgoCD）-监控告警（Prometheus + Grafana、Elasticsearch+Logstash+Kibana） # 可行性研究： 目的：用最小的代价在最小的时间内确定问题是否可以被解决。 任务： 分析和澄清问题的定义 导出系统的逻辑模型 根据逻辑模型探索若干种可供选择的解法 研究每种解法的可行性 经济可行性：经济效益是否大于开发成本 技术可行性：现有技术能够实现 操作可行性：系统操作方式是否可行 其它可行性：法律、社会效益 过程： 复查系统规模和目标 研究目前正在使用的系统 导出新系统的高层逻辑模型 进一步定义问题 导出和评价供选择的解法（经济、技术、操作、其他可行性） 推荐行动方针 草拟开发计划 书写文档提交审查 ### 数据流图DFD 概念：结构化分析工具，只表达数据流动，不表达控制逻辑（分支、循环） 可以分层绘制，0 层顶层图描述整体，子图逐层细化加工 数据字典描述具体的数据结构，现在一般用数据库表设计文档替代 基础构件： 实例： 银行计算机储蓄系统的工作过程大致如下：储户填写的存款单或取款单由业务员键入系统，如果是存款则系统记录存款人姓名、住址(或电话号码)、身份证号码、存款类型、存款日期、到期日期、利率及密码(可选)等信息，并印出存单给储户；如果是取款而且存款时留有密码，则系统首先核对储户密码，若密码正确或存款时未留密码，则系统计算利息并印出利息清单给储户 # 需求分析： 原则： 必须理解并描述问题的信息域，根据这条准则应该建立数据模型（E-R图） 必须定义软件应完成的功能，这条准则要求建立功能模型（数据流图） 必须描述作为外部事件结果的软件行为，这条准则要求建立行为模型（状态转换图） 必须对描述信息、功能和行为的模型进行分解，用层次的方式展示细节 内容： 确定对系统的综合要求： 功能要求：系统必须提供的服务功能 性能要求：系统必须满足的约束条件（如响应速度、安全性等） 可靠性和可用性需求：可靠性定量、可用性量化 出错处理需求： 错误响应机制，说明系统对环境错误应该如何响应 接口需求： 用户接口需求 硬件接口需求 软件接口需求 通信接口需求 约束： 用户或环境强加的限制条件（如工具、语言等） 逆向需求： 系统不应该做什么 将来可能提出要求： 将来可能需要实现的需求 分析系统的数据要求： 建立数据模型： 层次方框图、warnier图 导出系统的逻辑模型： 数据流图、数据字典、实体联系图、状态转换图 修正系统开发计划 ## 层次方框图 ## Warnier图 ⊕：异或，二选一 (a,b)：重复次数a-b ## IPO图 ## E-R图 用于数据库结构设计，描述现实中的实体、实体属性、实体间关系 实体：客观存在、可以区分的事物，比如学生、图书。 属性：实体的特征，比如学号、书名。 联系：实体与实体之间的关联。 一对一 1:1：A 一个实例对应 B 一个实例，例如：学生‑身份证 一对多 1:N：A 一个对应 B 多个；B 一个只对应 A 一个。例如：班级‑学生 多对多 M:N：两边都可以对应多条。例如：学生‑课程（一个学生选多门课，一门课多个学生选） 基础构件： 实例： 一个学生可选修多门课，一门课有若干学生选修;一个教师可讲授多门课，一门课只有一个教师讲授;学生选修一门课，产生成绩;学生的属性有学号、姓名等;教师的属性有教师编号，教师姓名等;课程的属性有课程号、课程名等。请画出该系统E-R图 ## 状态转换图 见UML状态图： ## 需求验证 一致性：所有需求必须是一致的，任何一条需求不能和其他需求互相矛盾 完整性：需求必须是完整的，规格说明书应该包括用户需要的每一个功能或性能 现实性：指定的需求应该能用现有的硬件和软件技术可以实现 有效性：必须证明需求是正确有效的，确实能解决用户面对的问题 验证方法： 一致性：软件工具 现实性：开发经验 完整性、有效性：软件原型 PSL/PSA系统 PSL（问题陈述语言）：是用来描述系统的形式语言 PSA（问题陈述分析程序）：是处理PSL描述的分析程序 用PSL描述的系统属性放在一个数据库中。一旦建立起数据库之后即可增加信息、删除信息或修改信息，并且保持信息的一致性。PSA对数据库进行处理以产生各种报告，测试不一致性或遗漏，并且生成文档资料。 # 概要设计： ## 概要设计 系统设计阶段： 设想供选择的方案：设想把数据流图中处理分组的各种可能的方法 选取合理的方案：低成本、中等成本和高成本的3种方案，系统流程图、物理元素清单、成本/效益分析、进度计划 推荐最佳方案 结构设计阶段： 功能分解 设计软件结构（层次图、结构图） 设计数据库 制定测试计划 书写文档（系统说明、用户手册、测试计划、详细实现计划、数据库设计结果） 审查和复查 ## 设计原理（高内聚、低耦合）： 模块：模块是由边界元素限定的相邻程序元素的序列,而且有一个总体标识符代表它。模块是构成程序的基本构件。过程、函数、子程序和宏等，都可作为模块。面向对象方法学中的对象是模块，对象内的方法也是模块。 模块化：模块化就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体，可以完成指定的功能满足用户的需求。模块化是为了使一个复杂的大型程序能被人的智力所管理，是软件应该具备的唯一属性。 抽象：抽出事物的本质特性而暂时不考虑它们的细节。 逐步求精：逐步求精是软件工程技术的基础，为了能集中精力解决主要问题而尽量推迟对问题细节的考虑。 MIller法则：注意力集中在(7 ± 2)个事物上。 信息隐藏：指一个模块内包含的信息对于不需要这些信息的模块来说是不能访问的，主要是指模块的实现细节 局部化：指把一些关系密切的软件元素物理地放得彼此接近，有助于实现信息隐藏 模块独立：开发具有独立功能而且和其他模块之间没有过多的相互作用的模块，就可以做到模块独立。使得每个模块完成一个相对独立的特定子功能，并且和其他模块之间的关系很简单。模块独立的概念是模块化、抽象、信息隐藏和局部化概念的直接结果。其质量标准是耦合和内聚 耦合：是对一个软件结构内不同模块间互连程序的度量。耦合强度取决于模块接口的复杂程度、通过接口的数据等。耦合度越高，模块独立性越弱，以下耦合从低到高 完全独立：如果两个模块中的每一个都能独立地工作而不需要另一个模块的存在 数据耦合：如果两个模块彼此间通过参数交换信息，而且交换的信息仅仅是数据 特征耦合：如果整个数据结构作为参数传递而被调用的模块只需要使用","date":"2026-08-20","objectID":"/posts/software-engineering/:1:6","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#敏捷开发主流"},{"categories":["技术笔记"],"collections":null,"content":"基础： 对象（Object）： 类：\u0026ldquo;类\u0026quot;是对具有相同数据和相同操作的一组相似对象的定义,即类是对具有相同属性和行为的一个或多个对象的描述，包括对怎样创建该类的新对象的说明。类是支持继承的抽象数据类型，而对象就是类的实例 实例：实例就是由某个特定的类所描述的一个具体的对象。 消息：消息就是要求某个对象执行在定义它的那个类中所定义的某个操作的规格说明。 方法：方法就是对象所能执行的操作，也就是类中所定义的服务。 属性：属性就是类中所定义的数据。 封装：封装是把数据和实现操作的代码集中起来放在对象内部。 继承：继承是指能够直接获得已有的性质和特征，而不必重复定义它们。 多态：不同层次中的每个类各自按自己的需要来实现这个行为。 重载：在同一作用域，若干个参数特征不同的函数可以使用相同的函数名。运算符重载：同一个运算符可以施加于不同类型的操作数上面 ### 方法学： 面向对象方法学的出发点和基本原则，是尽可能模拟人类习惯的思维方式，使开发软件的方法与过程尽可能接近人类认识世界解决问题的方法与过程，使描述问题的问题空间(问题域)与实现解法的解空间(求解域)在结构上尽可能一致。 要点： 对象：面向对象的软件系统是由对象组成的，软件中的任何元素都是对象，复杂的软件对象由比较简单的对象组合而成。用对象分解取代了传统方法的功能分解。 类：把所有对象都划分成各种对象类,每个对象类都定义了一组数据和一组方法。 继承：按子类与父类的关系，把若干个对象类组成一个层次结构的系统。子类自动具有和上层的父类相同的数据和方法。 封装：对象彼此之间仅能通过传递消息互相联系。对象是进行处理的主体，必须发消息请求它执行它的某个操作，处理它的私有数据，而不能从外界直接对它的私有数据进行操作。 优点： 与人类习惯的思维方法一致 稳定性好 可重用性 较易开发大型软件产品 可维护性好 #### 面向对象分析 抽取和整理用户需求并建立问题域精确模型的过程，包括5个层次：主题、类、结构、属性和服务，建立三个模型对象模型、动态模型、功能模型 描述用户的需求而不是提出解决问题的方法 哪些是系统必要的性质，哪些是任选的性质 不描述系统的内部结构 描述系统性能及系统与外界环境交互协议 描述采用的软件工程标准、模块构造准则、将来的扩充以及可维护性要求等方面 ##### 对象模型-UML类图 表示静态的、结构化的系统的数据性质。它是对模拟客观世界实体的对象以及对象彼此间的关系的映射，描述了系统的静态结构。对象模型为建立动态模型和功能模型，提供了实质性的框架。 软件开发过程就是一个多次反复修改、逐步完善的过程。仅仅经过一次建模过程很难得到完全正确的对象模型。 划分主题： 按问题领域而不是用功能分解方法来确定主题 按照使不同主题内的对象相互间依赖和交互最少的原则来确定主题 建模步骤： 确定对象类和关联(对于大型复杂问题还要进一步划分出若干个主题); 给类和关联增添属性，以进一步描述它们; 使用适当的继承关系进一步合并和组织类 关联类间关系 常见对象： 可感知的物理实体; 人或组织的角色; 应该记忆的事件; 两个或多个对象的相互作用; 类的方法： 设计实现服务的算法（算法复杂度、容易理解与容易实现、易修改） 选择数据结构 算法与数据结构的关系 定义内部类和内部操作 类的关联： 单向关联：简单指针属性实现。 双向关联： ##### 动态模型-UML状态图/时序图 动态模型表示瞬时的、行为化的系统的控制性质，它规定了对象模型中的对象的合法变化序列。 建模步骤： 抽象现实中的交互行为，用UML时序图编写典型交互行为的脚本 从脚本中提取出事件，确定触发每个事件的动作对象以及接受事件的目标对象 排列事件发生的次序，确定每个对象的状态及状态间的转换关系，用状态图描绘 比较各个对象的状态图，确保事件之间的匹配 ##### 功能模型-UML用例图/DFD图 功能模型表示变化的系统的功能性质，它指明了系统应该做什么，因此更直接地反映了用户对目标系统的需求。 ##### 三种模型的关联 针对每个类建立的动态模型，描述了类实例的生命周期或运行周期 状态转换驱使行为发生，这些行为在数据流图中被映射成处理，在用例图中被映射成用例，它们同- 时与类图中的服务相对应 功能模型中的处理对应于对象模型中的类所提供的服务 数据流图中的数据存储，以及数据的源点/终点，通常是对象模型中的对象 数据流图中的数据流，往往是对象模型中对象的属性值，也可能是整个对象 用例图中的行为者，可能是对象模型中的对象 功能模型中的处理可能产生动态模型中的事件 对象模型描述了数据流图中的数据流、数据存储以及数据源点/终点的结构 #### 设计模式 原则：模块化、抽象、封装、低耦合、高内聚、可重用 实现：参见设计模式 启发规则： 设计结果应该清晰易懂 一般一特殊结构的深度适当 设计简单的类 使用简单的协议 使用简单的服务 把设计变动减至最小 软件重用： 代码重用 实例重用 继承重用 多态重用 设计结果重用 分析结果重用 重用成本： 领域分析与建模的成本 设计领域体系结构的成本 为方便重用而增加的文档的成本 维护和完善可重用的软件成分的成本 为从外部获取构件所付出的版税和许可证费用 创建及运行重用库的费用 对设计和实现可重用构件的人员的培训费用 ","date":"2026-08-20","objectID":"/posts/software-engineering/:1:7","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#基础"},{"categories":["技术笔记"],"collections":null,"content":"分解面向对象设计模型： 子系统间关系： 客户-供应商关系 平等伙伴关系 子系统方案： 层次组织 块状组织 层次和块状的结合 拓扑结构（管道形、树形、星形） ##### 人机交互子系统： 分类用户 描述用户 设计命令层次 设计人机交互类 ##### 问题域子系统： 调整需求 重用已有的类 把问题域类组合在一起 增添一般化类以建立协议 调整继承层次 ##### 任务管理子系统（重要）： 分析并发性 确定事件驱动型任务 确定时钟驱动型任务 确定优先任务 确定关键任务 确定协调任务 尽量减少任务数 确定系统资源需求 ##### 数据管理子系统（重要）： 文件管理系统 关系数据库管理系统 面向对象数据库管理系统 设计数据格式 文件系统： 定义第一范式表:列出每个类的属性表;把属性表规范成第一范式， 从而得到第一范式表的定义 为每个第一范式表定义一个文件 测量性能和需要的存储容量 修改原设计的第一范式，以满足性能和存储需求 关系数据库管理系统： 定义第三范式表：列出每个类的属性表;把属性表规范成第三范式，从而得出第三范式表的定义 为每个第三范式表定义一个数据库表 测量性能和需要的存储容量 修改先前设计的第三范式，以满足性能和存储需求 面向对象数据库管理系统： 扩展的关系数据库途径：使用与关系数据库管理系统相同的方法 扩展的面向对象程序设计语言途径：不需要规范化属性的步骤 设计相应的服务 文件系统： 被存储的对象需要知道打开哪个文件，怎样把文件定位到正确的记录上，怎样检索出旧值，以及怎样用现有值更新它们 定义一个 ObjectServer类，并创建它的实例 关系数据库管理系统： 被存储的对象，应该知道访问哪些数据库表，怎样访问所需要的行，怎样检索出旧值，以及怎样用现有值更新它们 定义一个 ObjectServer类，并声明它的对象 面向对象数据库管理系统： 扩展的关系数据库途径：使用与关系数据库管理系统相同的方法 扩展的面向对象程序设计语言途径：无须增加服务，只需给长期保存的对象加个标记，然后由面向对象数据库管理系统负责存储和恢复这类对象 ### 程序设计风格： 可重用性： 提高方法的内聚 减小方法的规模 保持方法的一致性 把策略与实现分开 全面覆盖 尽量不使用全局信息 利用继承机制 可扩充性： 封装实现策略 不要用一个方法遍历多条关联链 避免使用多分支语句 精心确定公有方法 健壮性： 预防用户的错误操作 检查参数的合法性 不要预先确定限制条件 先测试后优化 ## UML建模语言： 用例图：从用户角度描述系统功能。 类图：描述系统中类的静态结构。 对象图：系统中的多个对象在某一时刻的状态。 状态图：是描述状态到状态控制流，常用于动态特性建模 活动图：描述了业务实现用例的工作流程 时序图：对象之间的动态合作关系，强调对象发送消息的顺序，同时显示对象之间的交互 协作图：描述对象之间的协助关系 构件图：一种特殊的UML图来描述系统的静态实现视图 部署图：定义系统中软硬件的物理体系结构 包图：对构成系统的模型元素进行分组整理的图 组合结构图：表示类或者构建内部结构的图 交互概览图：用活动图来表示多个交互之间的控制关系的图 ### UML用例图 阶段：需求分析 构件： 参与者 (Actor)：与系统交互的外部角色，小人图标，可以是人、外部系统。 用例 (Use Case)：椭圆，代表系统提供的一项功能。 系统边界：矩形框，框住全部用例，表示待开发系统范围。 关联：实线，参与者和用例之间连线。 包含 (\u0026lt;\u0026lt;include\u0026gt;\u0026gt;)：基用例一定会调用被包含用例；箭头指向被包含用例。 扩展 (\u0026lt;\u0026lt;extend\u0026gt;\u0026gt;)：条件满足才会扩展原有用例；箭头指向基用例。 泛化：空心三角箭头，子参与者 / 子用例继承父。 实例： ","date":"2026-08-20","objectID":"/posts/software-engineering/:2:0","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#分解面向对象设计模型"},{"categories":["技术笔记"],"collections":null,"content":"UML活动图 阶段：需求分析/详细设计 描述流程、步骤逻辑，侧重业务 / 算法执行流程，类似流程图。 构件： 初始节点：实心小黑圆，流程起点。 活动动作：圆角矩形，代表一个执行步骤、操作。 转移箭头：实线箭头，流程走向。 判定分支：菱形，if‑else 分支，写监护条件。 合并节点：菱形，多个分支汇合到一处。 分叉（并发 fork）：粗黑竖线，一条流入，多条流出，开启并行执行。 汇合（join）：粗黑竖线，多条流入，一条流出，等待全部并行分支完成才往下走。 终止节点：同心圆，流程结束。 实例： flowchart TD A[*] --\u0026gt; B[校验用户信息] B --\u0026gt; C{用户合法?} C --\u0026gt;|不合法| D[返回错误提示] D --\u0026gt; Z([*]) C --\u0026gt;|合法| E[创建订单] %% fork并发分叉 E --\u0026gt; F((fork)) F --\u0026gt; G[扣减商品库存] F --\u0026gt; H[生成订单操作日志] %% join汇合，两个都完成才继续 G --\u0026gt; J((join)) H --\u0026gt; J J --\u0026gt; K[发起支付请求] K --\u0026gt; Z([*]) ","date":"2026-08-20","objectID":"/posts/software-engineering/:2:1","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#uml活动图"},{"categories":["技术笔记"],"collections":null,"content":"UML组件图 阶段：概要设计 描述软件的模块 / 组件，组件对外提供接口、需要依赖别的组件，表达模块之间依赖关系。 构件： 组件：带小方框标记的矩形，代表独立软件模块。 提供接口：组件对外暴露的服务（棒棒糖符号）。 需要接口：组件需要外部提供的接口（凹槽符号）。 依赖：虚线箭头，A 组件依赖 B 组件。 实例： %%{init: { \u0026#39;theme\u0026#39;: \u0026#39;base\u0026#39; } }%% flowchart LR subgraph Web前端组件 WEB[WebUI] end subgraph 业务层组件 OrderComp[订单组件] UserComp[用户组件] PayComp[支付组件] end subgraph 数据层组件 DBComp[数据库组件] end WEB -.-\u0026gt;|依赖| OrderComp OrderComp -.-\u0026gt;|依赖| UserComp OrderComp -.-\u0026gt;|依赖| PayComp OrderComp -.-\u0026gt;|依赖| DBComp PayComp -.-\u0026gt;|依赖| DBComp UserComp -.-\u0026gt;|依赖| DBComp ","date":"2026-08-20","objectID":"/posts/software-engineering/:2:2","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#uml组件图"},{"categories":["技术笔记"],"collections":null,"content":"UML类图 阶段：概要/详细设计 Mermaid代码可以直接渲染成UML类图 构件： 包： 类： 组成： 第一层：类名 第二层：属性（成员变量），格式：可见性 名称 : 类型 第三层：方法（成员函数），格式：可见性 名称(参数:类型) : 返回值类型 可见性： + public 公开 - private 私有 # protected 保护 特性： virtual：方法尾部{virtual}标记，纯虚函数尾部{abstract}标记或斜体，抽象类标注\u0026lt;\u0026lt;abstract\u0026gt;\u0026gt; static：变量和方法下划线 const：变量属性名大写，格式 可见性 名称:类型 = 值，方法尾部加{const}标记 接口： 标注\u0026lt;\u0026lt;interface\u0026gt;\u0026gt; 没有属性 所有方法全部斜体 关系： 常用的是泛化、实现、关联，次之是组合、依赖 泛化（继承）：is a，空心三角实线，三角指向父类。子类 \u0026mdash;-▷ 父类。 实现（接口实现）：implement of，空心三角虚线，三角指向接口。实现类 - - -▷ 接口。 关联：普通实线；对象之间存在联系，可以当作has a，可以标注多重度 (1、0..* 等)。 聚合：空心菱形实线，菱形指向整体；has a，整体包含部分，部分可脱离整体独立存在。 组合：实心菱形实线，菱形指向整体；contains a，整体包含部分，部分生命周期跟随整体，整体销毁则部分销毁。 依赖：虚线普通箭头；use a，一个类临时使用另一个类（函数参数、局部变量）。 实例： classDiagram class User{ -userId : long -userName : string } class Order{ -orderId : long -createTime : time +addItem() : void +getTotalPrice() : double } class OrderItem{ -goodsName : string -count : int } class PayInterface{ \u0026lt;\u0026lt;interface\u0026gt;\u0026gt; +pay(money:double) : bool } class AliPay{ +pay(money:double) : bool } Order *-- OrderItem : 组合 Order -- User : 关联 AliPay ..|\u0026gt; PayInterface : 实现 ","date":"2026-08-20","objectID":"/posts/software-engineering/:2:3","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#uml类图"},{"categories":["技术笔记"],"collections":null,"content":"UML时序图 阶段：详细设计 按照时间从上到下顺序，描述多个对象之间消息调用的先后顺序。 构件： 角色：时序图最上方，代表外部系统 / 人，属于参与者 对象：矩形框，格式 对象名:类名，放在图最上方；:前面为空代表匿名对象。 生命线：对象下方垂直虚线，代表对象存活时间。 执行条：生命线上面的细长矩形，表示对象正在执行。 同步发送：实心箭头实线，调用方等待对方执行完成。 返回消息：虚线箭头，从被调用方返回调用方，携带返回结果。 异步发送：空心箭头实线，发送之后不等待，继续往下执行。 组合片段：alt分支判断、loop循环、opt可选执行、par并行执行等等，用来表达分支循环逻辑。 实例： %%{init: { \u0026#39;theme\u0026#39;: \u0026#39;base\u0026#39; } }%% sequenceDiagram actor user as user:用户 participant orderService as orderService:订单服务 participant stockService as stockService:库存服务 participant payService as payService:支付服务 user-\u0026gt;\u0026gt;orderService: createOrder(goodsId) activate orderService loop 最多重试3次 orderService-\u0026gt;\u0026gt;stockService: deductStock(goodsId) activate stockService stockService--\u0026gt;\u0026gt;orderService: stockResult deactivate stockService alt 库存充足 orderService-\u0026gt;\u0026gt;payService: doPay(money) activate payService payService--\u0026gt;\u0026gt;orderService: payOk deactivate payService note over orderService:下单完成，跳出循环 else 库存不足 note over orderService:继续循环重试 end end alt 下单成功 orderService--\u0026gt;\u0026gt;user: success(订单ID) else 重试全部失败 orderService--\u0026gt;\u0026gt;user: fail(库存不足) end deactivate orderService ","date":"2026-08-20","objectID":"/posts/software-engineering/:2:4","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#uml时序图"},{"categories":["技术笔记"],"collections":null,"content":"UML状态图 阶段：需求分析、详细设计 只针对单个对象，描述一个对象在生命周期内的各种状态、状态之间的转移、触发事件、监护条件、动作。 构件： 初始伪状态：实心小黑圆，对象起点。 终止状态：实心圆外面套一个空心圆环，对象生命周期结束。 状态：圆角矩形，内部写状态名称；可写 entry /do/exit 动作。 复合状态：大圆角矩形，内部嵌套子状态，包含多个内部子状态。 转移：带箭头实线，从源状态指向目标状态，语法事件 [监护条件] / 动作 状态内部： entry / 行为：进入该状态的时候执行 do / 行为：处于该状态期间持续执行 exit / 行为：离开该状态的时候执行 转移语法： 事件：触发状态切换发生的事情 监护条件：方括号，布尔判断，满足才允许跳转 动作：跳转发生时执行的行为 stateDiagram-v2 [*] --\u0026gt; 待支付 : 创建订单 待支付 --\u0026gt; 已支付 : 用户支付 [金额正确] / 生成支付记录 待支付 --\u0026gt; 已取消 : 超时 / 自动关闭订单 已支付 --\u0026gt; 已发货 : 发货 已发货 --\u0026gt; 已完成 : 用户确认收货 已完成 --\u0026gt; [*] 已取消 --\u0026gt; [*] ","date":"2026-08-20","objectID":"/posts/software-engineering/:2:5","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#uml状态图"},{"categories":["技术笔记"],"collections":null,"content":"UML部署图 阶段：部署方案 描述物理硬件节点 + 运行在节点上的软件组件，表达软件部署位置、服务器之间通信链路 构件： 节点 Node：立体方框，硬件 / 服务器 / 设备（应用服务器、DB 服务器、手机客户端）。 构件 Artifact：运行在节点内部的软件包、程序、组件。 关联连线：实线，节点之间网络通信，标注协议 HTTP/TCP。 # 软件项目管理： 估算软件规模：估算实现一个功能所需要的源代码行数、以功能点（FP）为单位度量软件规模 工作量估算：工作量的单位通常是人月(pm) 静态单变量模型（基本的COCOMO模型） 静态多变量模型（COCOMO2模型） 动态多变量模型（putnam模型） 进度计划：甘特图(Cantt图) 人员组织： 民主制程序员组 主程序员组 现代程序员组 质量保证： 基于非执行测试（复审或评审） 基于执行测试（软件测试） 程序正确性的证明（数学方法） 软件配置管理： 基线：通过了正式复审的软件配置项，可以作为进一步开发的基础，只有通过正式的变化控制过程才能改变它 标识对象 版本控制 变化控制 配置审计 状态报告 能力成熟度模型： 初始级 可重复级 已定义级 已管理级 优化级 # 个人项目应用： ### 大型项目 生命周期模型：瀑布流模型 可行性研究： 文档：软件开发任务书 工具：PowerDesigner 图表：数据流图DFD、数据字典 需求分析： 文档：软件需求规格说明书 工具：PowerDesigner 图表：E-R图、层次方框图、数据流图DFD、状态转换图 概要设计： 图表：层次图 详细设计： 图表：PAD图 复杂度：McCabe方法计算环形复杂度。 测试： 单元测试：代码审计 集成测试：自顶向下深度优先渐增式集成测试 验收测试：Alpha版本和Beta版本 面向对象： 分析阶段：UML类图-\u0026gt;UML时序图-\u0026gt;UML状态图-\u0026gt;数据流图DFD-\u0026gt;完善UML类图 设计阶段：根据设计模式重新设计UML类图 ### 小型项目 生命周期模型：敏捷编程（scrum） ","date":"2026-08-20","objectID":"/posts/software-engineering/:2:6","tags":["项目开发","软件工程","c++"],"title":"软件工程","uri":"/posts/software-engineering/#uml部署图"},{"categories":["测试"],"collections":null,"content":"hugo 博客测试","date":"2026-08-14","objectID":"/posts/myfirstpost/","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/"},{"categories":["测试"],"collections":null,"content":"本篇用于博客测试，日常工作流如下 # 新建文章 hugo new posts/xxx.md # 本地热更新预览 rm -rf public resources .hugo_build.lock hugo server -D --disableFastRender # 在文章中取消草稿模式 draft = false # 写完提交推送，Actions自动构建发布 git add . git commit -m \u0026#34;add article\u0026#34; git push ","date":"2026-08-14","objectID":"/posts/myfirstpost/:0:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#本篇用于博客测试日常工作流如下"},{"categories":["测试"],"collections":null,"content":"Hugo 常用命令 前提：进入项目根目录执行所有命令 ","date":"2026-08-14","objectID":"/posts/myfirstpost/:0:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#hugo-常用命令"},{"categories":["测试"],"collections":null,"content":"一、基础运行 # 启动本地开发服务器（最常用） hugo server # 启动并自动打开浏览器；草稿内容也渲染 hugo server -D # 指定端口（默认1313） hugo server -p 1314 # 关闭实时刷新 hugo server --noLiveReload 访问地址：http://localhost:1313 ","date":"2026-08-14","objectID":"/posts/myfirstpost/:1:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#一基础运行"},{"categories":["测试"],"collections":null,"content":"二、创建内容 # 创建文章，自动根据archetype模板生成md文件 hugo new posts/my-first-post.md # 创建草稿（默认草稿不会被正式构建，需 -D 预览） hugo new posts/draft-article.md 文件路径：content/posts/my-first-post.md Front Matter常用标识： title = \u0026#34;标题\u0026#34; date = 2026-08-14T12:00:00+08:00 draft = true # true=草稿，构建默认忽略 tags = [\u0026#34;标签\u0026#34;] categories = [\u0026#34;分类\u0026#34;] ","date":"2026-08-14","objectID":"/posts/myfirstpost/:2:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#二创建内容"},{"categories":["测试"],"collections":null,"content":"三、构建静态站点（部署用） # 生成静态文件到 public/ 文件夹 hugo # 构建同时包含草稿 hugo -D # 生产环境构建（压缩、优化资源） hugo --minify 输出目录：public/，直接丢到 GitHub Pages / Vercel / Netlify ","date":"2026-08-14","objectID":"/posts/myfirstpost/:3:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#三构建静态站点部署用"},{"categories":["测试"],"collections":null,"content":"四、主题相关操作 ","date":"2026-08-14","objectID":"/posts/myfirstpost/:4:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#四主题相关操作"},{"categories":["测试"],"collections":null,"content":"1. 添加主题（Git Submodule 方式，推荐） # 示例PaperMod主题，按需替换仓库地址 git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod # 后续拉取主题更新 git submodule update --remote themes/PaperMod 然后在 hugo.toml / config.toml 设置 theme = \u0026#34;PaperMod\u0026#34; ","date":"2026-08-14","objectID":"/posts/myfirstpost/:4:1","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#1-添加主题git-submodule-方式推荐"},{"categories":["测试"],"collections":null,"content":"五、配置文件 hugo 支持三种格式，任选其一： hugo.toml（新版推荐） config.toml config.yaml / config.json ","date":"2026-08-14","objectID":"/posts/myfirstpost/:5:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#五配置文件"},{"categories":["测试"],"collections":null,"content":"六、实用进阶命令 # 列出所有页面信息 hugo list all # 列出草稿 hugo list drafts # 列出未来定时文章（future） hugo list future # 清理 public 缓存 rm -rf public resources # Windows Remove-Item public, resources -Recurse -Force ","date":"2026-08-14","objectID":"/posts/myfirstpost/:6:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#六实用进阶命令"},{"categories":["测试"],"collections":null,"content":"七、部署简易流程（GitHub Pages 思路） 本地写完文章，hugo server -D 预览 修改 frontmatter draft=false 执行 hugo --minify 将 public 内静态文件推送到 pages 分支 自动化方案：GitHub Action 直接仓库源码构建，不用本地生成 public ","date":"2026-08-14","objectID":"/posts/myfirstpost/:7:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#七部署简易流程github-pages-思路"},{"categories":["测试"],"collections":null,"content":"八、高频踩坑 修改配置文件后，重启 hugo server 才生效 draft=true 的文章，不加 -D 看不到 图片路径：优先使用 static/ 存放全局资源；页面内资源放页面同名文件夹（Page Bundle） 主题更新不要直接改 themes 内源码，使用 layouts/ 目录覆写模板 ","date":"2026-08-14","objectID":"/posts/myfirstpost/:8:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#八高频踩坑"},{"categories":["测试"],"collections":null,"content":"九、Page Bundle（常用组织方式） content/posts/article/ ├── index.md # 文章正文 ├── pic1.jpg # 当前文章专用图片 在 md 中直接引用 ![](./pic1.jpg) ","date":"2026-08-14","objectID":"/posts/myfirstpost/:9:0","tags":["测试标签"],"title":"第一篇文章","uri":"/posts/myfirstpost/#九page-bundle常用组织方式"},{"categories":null,"collections":null,"content":"👋 你好，我是grassro0t 后端开发，自由摄影创作者。 本博客主要用来记录编程学习笔记、踩坑记录，偶尔分享部分摄影相关心得和一些日常心得体会。 笔记以个人复习为目的，内容难免疏漏，欢迎交流指正。 ","date":"0001-01-01","objectID":"/about/:1:0","tags":null,"title":"关于我们","uri":"/about/#-你好我是grassro0t"},{"categories":null,"collections":null,"content":"🛠 技术方向 C++ 现代开发，游戏后端，设计模式 ","date":"0001-01-01","objectID":"/about/:1:1","tags":null,"title":"关于我们","uri":"/about/#-技术方向"},{"categories":null,"collections":null,"content":"📷 个人爱好 摄影、力量训练、电吉他。 ","date":"0001-01-01","objectID":"/about/:1:2","tags":null,"title":"关于我们","uri":"/about/#-个人爱好"},{"categories":null,"collections":null,"content":"✍ 博客说明 站点由 Hugo + FixIt 主题驱动。 若无特殊说明，所有内容为原创。 转载请标注原文链接，禁止商用。 ","date":"0001-01-01","objectID":"/about/:1:3","tags":null,"title":"关于我们","uri":"/about/#-博客说明"},{"categories":null,"collections":null,"content":"📮 联系 GitHub：https://github.com/grassro0t Email：julian.song.work@outlook.com ","date":"0001-01-01","objectID":"/about/:1:4","tags":null,"title":"关于我们","uri":"/about/#-联系"}]