锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

高级软件工程学习总结

时间:2022-09-01 21:30:00 规格重载连接器

目录

1 码农的自我修养

1.1 定义软件工程

1.2 软件工程的本质特征

基本原理-toc" style="margin-left:40px;">1.3 软件工程的基本原理

1.4 课程教学目标

2 如果你想做好工作,你必须先利用其器械

2.1 Typing

2.2 Visual Studio Code

2.2.1 简介

2.2.2 vscode为什么能这么牛?

2.3 Git

2.3.1 Git与版本控制

2.3.2 Git基本操作逻辑

2.3.3 Git设计理念和时间线

2.4 Vi/Vim

2.4.1 简介

2.4.2 vi/vim的三种模式

2.5 正则表达式

2.5.1 简介

2.5.2 为什么使用正则表达式

3 实战工程编程

3.1 代码规范和代码风格

3.1.1 代码风格原则

3.1.2 代码风格的三重境界

3.1.3 代码风格规范中介

3.1.4 编写高质量代码的基本方法

3.2 模块化软件设计

3.2.1 模块化的基本原理

3.2.2 模块化代码的基本写法

3.3 可重用软件设计

3.3.1 消费者和生产者的重用

3.3.2 接口的基本概念

3.3.3 接口规格包括五个基本要素

3.3.4 微服务的概念

3.4 线程安全

3.4.1 线程的基本概念

3.4.2 可重新定义函数

3.4.3 可重入函数的基本要求

3.4.4 什么是线程安全

3.4.5 函数的可重入性与线程安全之间的关系

4. 从需求分析到软件设计

4.1 需求及需求分析

4.1.1 什么是需求

4.1.2 什么是需求分析

4.2 从需求进行分析与建模

4.2.1 需求分析的两类基本方法

4.2.2 什么是用例

4.2.3 用例的三个抽象层级

4.3 从需求分析到软件设计

4.3.1 瀑布模型

4.3.2 统一过程

4.3.3 敏捷统一过程的计划阶段

4.3.4 敏捷统一过程的四个关键步骤

4.3.4 敏捷统一过程的增量阶段

4.4 总结

5 软件科学基础概论

5.1 软件是什么

5.1.1 软件的基本构成元素

5.1.2 软件的基本结构

5.1.3 软件中的一些特殊机制        

5.2 软件设计模式初步

5.2.1 设计模式设计的基本概念

5.2.2 什么是设计模式

5.2.3 设计模式的优点

5.2.4 设计模式的分类

5.2.5 常用的设计模式

5.2.6 设计模式背后的设计原则

5.3 常见的软件架构

5.3.1 三层架构

5.3.2 MVC架构

5.3.3 MVVM架构

5.4 软件架构风格与策略

5.4.1 管道-过滤器

5.4.2 客户-服务

5.4.3 P2P

5.4.4 发布-订阅

5.4.5 CRUD

5.4.6 层次化

6 软件危机和软件过程

6.1 软件危机

6.1.1 产生背景

6.1.2 软件危机的展望

6.2 软件过程

6.2.1 软件的生命周期概述

6.2.2 软件的故障率曲线

6.2.3 瀑布模型

6.2.4 V模型

6.3 CMM/CMMI

6.3.1 简介

6.3.2 CMM/CMMI的5个等级

6.3.3 CMM/CMMI的作用

6.4 总结

7 课程总结


1 码农的自我修养

1.1 软件工程的定义

        根据1993年IEEE为软件工程赋予的规范定义:软件工程是把系统的、规范的、可度量的途径应用于软件开发、运行和维护过程,也就是把工程应用于软件。

1.2 软件工程的本质特征

(1)软件工程堆较大型的程序构造起着重要作用
(2)软件工程的研究中心是会程序复杂性的控制
(3)软件工程需要对软件进行经常化
(4)软件工程中软件的开发速度与质量至关重要
(5)开发软件是一件需要多方进行配合与合作的事情
(6)软件需要为其用户提供支持与存在感

1.3 软件工程的基本原理

(1)要对生命的周期做出有计划的分阶段专业管理
(2)要坚持进行阶段性的评析和审视
(3)对产品质量与走向进行严格控制
(4)不断采取和学习现代程序设计新技术
(5)对结果要有清晰明了的审查
(6)软件开发人员要重质量轻数量
(7)要不断的进行软件工程的实践探究

1.4 课程教学目标

        需求分析:分析现有软件, 归纳初步需求;基础差的同学学习技术
        设计阶段:用快速发布来证明设计是有效的,  能适应变化的
        实现阶段:用各种软件工程的衡量手段来证明大家实现的能力。
        稳定阶段:证明测试能否覆盖代码的大部分。
        发布阶段: 如期发布 , 用户量 用户评价
        维护阶段:网上的观众或下一个年级的同学能很愿意接手你们的软件。
        最后大部分同学们能说:  自己做了一个有人用,有生命的软件 然后下个学期,新的一批学生进来提高这一过程 … 

2 工欲善其事必先利其器

2.1 Typing

        通过 Learn Touch Typing Free - TypingClub学习标准指法,并测试打字速度。虽然码农的优秀与否与打字速度毫无关系,但其却是每个码农必备的且不可忽视的,要求打字速度>50WPM为优秀,>30WPM为及格。

2.2 Visual Studio Code

2.2.1 简介

        Visual Studio Code(以下简称vscode)是一个轻量且强大的代码编辑器,支持Windows,OS X和Linux。内置JavaScript、TypeScript和Node.js支持,而且拥有丰富的插件生态系统,可通过安装插件来支持C++、C#、Python、PHP等其他语言。

2.2.2 vscode为什么能这么牛

        简介而聚焦的产品定位,贯穿始终
        进程隔离的插件模型
        UI渲染与业务逻辑隔离,一致的用户体验
        代码理解和调试——LSP和DAP两大协议
        集大成的Remote Development

2.3 Git

2.3.1 Git与版本控制

        版本控制系统有很多:独立文件方式,比如另存为;补丁方式,不如diff;中心版本控制系统,比如Concurrent Version System/cvs和Subversion/svn。分布式版本控制系统,比如Git,是目前世界上最先进的版本控制系统(没有之一)。

2.3.2 Git的基本操作逻辑

        对于本地Repo,可能有多个branch,至少有一个叫master
        本地Repo,可能有多个branch,至少有一个叫master

2.3.3 Git的设计理念和时间线

2.4 Vi/Vim

2.4.1 简介

        几乎所有的Unix-Like系统一般都会预装vi文本编辑器,其他的文本剪辑器不一定预装。POSIX标准中就有vi命令。
        vim具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计。
        vim是vi发展出来的一个文本剪辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。
        简单的来说,vi仅仅是文本编辑器,不过功能已经很齐全了。vim则是程序开发者的一项很好用的工具。连vim的官方网站(http://www.vim.org)也说vim是一个程序开发工具而不仅是文本编辑器。

2.4.2 vi/vim的三种模式

        命令模式(Command mode),用户刚刚启动vi/vim,便进入了命令模式。此状态下敲击键盘动作会被vim识别为命令,而非输入字符。比如我们此时按下i,并不会输入一个字符,i被当作了一个命令。命令模式只有一些最基本的命令,因此仍要依靠底线命令模式输入更多命令。
        输入模式(Insert mode),在命令模式下按下i就进入了输入模式,按ESC退出输入模式,切换到命令模式。
        底线命令模式(Last line mode),在命令模式下按下:(英文冒号)就进入了底线命令模式。底线命令模式可以输入单个或多个字符的命令,可用的命令非常多。基本的命令有q(退出程序)、w(保存文件)等。按ESC键可随时退出底线命令模式。

2.5 正则表达式

2.5.1 简介

        正则表达式是对字符串操作的一种逻辑公式。
        正则表达式的应用范围非常之广泛,最初是由Unix普及开来的,后来在广泛运用于Scala、PHP、C#、Objective-c、Perl、Swift、VBScript、JavaScript、Ruby以及Python等等。
        学习正则表达式,实际上是在学习一种非常灵活的逻辑思维,通过简单快速的方法达到对于字符串的控制。
        正则表达式是程序员手中一把威力无比强大的武器!

2.5.2 为什么使用正则表达式

        测试字符串内的模式。例如,可以测试输入字符串,以查看字符串内是否出现电话号码模·式或信用卡号码模式。这称为数据验证。
        替换文本。可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
        基于模式匹配从字符串中提取子字符串。可以查找文档内或输入域内特定的文本。
        例如,您可能需要搜索整个网站,删除过时的材料,以及替换某些 HTML 格式标记。在这种情况下,可以使用正则表达式来确定在每个文件中是否出现该材料或该 HTML 格式标记。此过程将受影响的文件列表缩小到包含需要删除或更改的材料的那些文件。然后可以使用正则表达式来删除过时的材料。最后,可以使用正则表达式来搜索和替换标记。

3 工程化编程实战

3.1 代码规范和代码风格

3.1.1 代码风格原则

        代码风格的原则:简明、易读、无二义性
        一个项目代码的风格就如同一个人给人的印象,代码风格之所以那么重要,是因为它往往决定了代码是否规范、是否易于阅读。
        代码虽然最终是要给机器看的,但毕竟还是面向程序猿们的编程,程序猿们是要陪伴整个项目开发过程的。在编写代码的过程中,尤其是在协作开发的过程中,如果对方的代码杂乱无章,读起来都费劲,更别说还需要在此基础上进一步开发,这对程序员来说是个巨大的挑战。
        好的代码风格不仅易于代码的阅读和理解,还能在很大程度上减少一些不必要的语法错误,例如少了 "}" ,如果在编码的时候严格遵循了花括号的对齐规则,那此类错误将容易被避免

3.1.2 代码风格三重境界

        一是规范整洁。遵守常规语言规范,合理使用空格、空行、缩进、注释等;
        二是逻辑清晰。没有代码冗余、重复,让人清晰明了的命名规则。做到逻辑清晰不仅要求程序员的编程能力,更重要的是提高设计能力,选用合适的设计模式、软件架构风格可以有效改善代码的逻辑结构,会让代码简洁清晰;
        三是优雅。优雅的代码是设计的艺术,是编码的艺术,是编程的最高追求。
        一般来讲,我们对代码风格的基本原则要求是简明、易读、无二义性。

3.1.3 代码风格规范中介

        命名:合适的命名会大大增加代码的可读性;
        类名、函数名、变量名等的命名一定要与程序里的含义保持一致,以便于阅读理解;
        类型的成员变量通常用m_或者_来做前缀以示区别;
        一般变量名、对象名等使用LowerCamel风格,即第一个单词首字母小写,之后的单词        都首字母大写,第一个单词一般都表示变量类型,比如int型变量iCounter;
        类型、类、函数名等一般都用Pascal风格,即所有单词首字母大写;
        类型、类、变量一般用名词或者组合名词,如Member
        函数名一般使用动词或者动宾短语,如get/set,RenderPage 注释和版权信息:
        注释也要使用英文,不要使用中文或特殊字符,要保持源代码是ASCII字符格式文件;        
        不要解释程序是如何工作的,要解释程序做什么,为什么这么做,以及特别需要注意的地方;
        每个源文件头部应该有版权、作者、版本、描述等相关信息。

3.1.4 编写高质量代码的基本方法

        通过控制结构简化代码
        通过数据结构简化代码
        一定要有错误处理
        性能优先策略背后隐藏的代价
        拒绝修修补补要不断重构代码
        极限编程中不同的两类参与者的合作
        结合编程中同类参与者的合作

3.2 模块化软件设计

3.2.1 模块化的基本原理

        模块化(Modularity)是在软件系统设计时保持系统内各部分相对独立,以便每一个部分可以被独立地进行设计和开发。这个做法背后的基本原理是关注点的分离 (SoC, Separation of Concerns),是由软件工程领域的奠基性人物Edsger Wybe Dijkstra(1930~2002)在1974年提出,没错就是Dijkstra最短路径算法的作者。
        关注点的分离在软件工程领域是最重要的原则,我们习惯上称为模块化,翻译成我们中文的表述其实就是“分而治之”的方法。
        关注点的分离的思想背后的根源是由于人脑处理复杂问题时容易出错,把复杂问题分解成一个个简单问题,从而减少出错的情形。
        模块化软件设计的方法如果应用的比较好,最终每一个软件模块都将只有一个单一的功能目标,并相对独立于其他软件模块,使得每一个软件模块都容易理解容易开发。
        从而整个软件系统也更容易定位软件缺陷bug,因为每一个软件缺陷bug都局限在很少的一两个软件模块内。
        而且整个系统的变更和维护也更容易,因为一个软件模块内的变更只影响很少的几个软件模块。
        因此,软件设计中的模块化程度便成为了软件设计有多好的一个重要指标,一般我们使用耦合度(Coupling)和内聚度(Cohesion)来衡量软件模块化的程度。

3.2.2 模块化代码的基本写法

        命令行菜单在开源社区中常见的写法
        将数据结构和它的操作与菜单业务处理进行分离处理,尽管还是在同一个源代码文件中,但是已经在逻辑上做了切分,可以认为有了初步的模块化。
        进行了模块化设计之后我们往往将设计的模块与实现的源代码文件有个映射对应关系,因此我们需要将数据结构和它的操作独立放到单独的源代码文件中,这时就需要设计合适的接口,以便于模块之间互相调用。
        KISS(Keep It Simple & Stupid)原则
        使用本地化外部接口来提高代码的适应能力
        不要和陌生人说话原则
        先写伪代码的代码结构更好一些

3.3 可重用软件设计

3.3.1 消费者重用和生产者重用

Consumer Reuse
        消费者重用是指软件开发者在项目中重用已有的一些软件模块代码,以加快项目工作进度。软件开发者在重用已有的软件模块代码时一般会重点考虑如下四个关键因素:
该软件模块是否能满足项目所要求的功能;
        采用该软件模块代码是否比从头构建一个需要更少的工作量,包括构建软件模块和集成软件模块等相关的工作;
        该软件模块是否有完善的文档说明;
        该软件模块是否有完整的测试及修订记录;
        如上四个关键因素需要按照顺序依次评估。
Producer Reuse
        我们清楚了消费者重用时考虑的因素,那么生产者在进行可重用软件设计时需要重点考虑的因素也就清楚了,但是除此之外还有一些事项在进行可重用软件设计时牢记在心,我们简要列举如下:
        通用的模块才有更多重用的机会;
        给软件模块设计通用的接口,并对接口进行清晰完善的定义描述;
        记录下发现的缺陷及修订缺陷的情况;
        使用清晰一致的命名规则;
        对用到的数据结构和算法要给出清晰的文档描述;
        与外部的参数传递及错误处理部分要单独存放易于修改;

3.3.2 接口的基本概念

         接口就是互相联系的双方共同遵守的一种协议规范,在我们软件系统内部一般的接口方式是通过定义一组API函数来约定软件模块之间的沟通方式。换句话说,接口具体定义了软件模块对系统的其他部分提供了怎样的服务,以及系统的其他部分如何访问所提供的服务。
        在面向过程的编程中,接口一般定义了数据结构及操作这些数据结构的函数;而在面向对象的编程中,接口是对象对外开放(public)的一组属性和方法的集合。函数或方法具体包括名称、参数和返回值等。

3.3.3 接口规格包含五个基本要素

        接口规格是软件系统的开发者正确使用一个软件模块需要知道的所有信息,那么这个软件模块的接口规格定义就必须清晰明确地说明正确使用本软件模块的信息。一般来说,接口规格包含五个基本要素:
        接口的目的;
        接口使用前所需要满足的条件,一般称为前置条件或假定条件;
        使用接口的双方遵守的协议规范;
        接口使用之后的效果,一般称为后置条件;
        接口所隐含的质量属性。

3.3.4 微服务的概念

        由一系列独立的微服务共同组成软件系统的一种架构模式;
        每个微服务单独部署,跑在自己的进程中,也就是说每个微服务可以有一个自己独立的运行环境和软件堆栈;
        每个微服务为独立的业务功能开发,一般每个微服务应分解到最小可变产品(MVP),达到功能内聚的理想状态。微服务一般通过RESTful API接口方式进行封装
        系统中的各微服务是分布式管理的,各微服务之间非常强调隔离性,互相之间无耦合或者极为松散的耦合,系统通过前端应用或API网关来聚合各微服务完成整体系统的业务功能。        
        微服务架构的基本概念可以简单概括为通过模块化的思想垂直划分业务功能,传统单体集中式架构和微服务架构如下图示意

3.4 可重入函数与线程安全

3.4.1 线程的基本概念

        线程(thread)是操作系统能够进行运算调度的最小单位。它包含在进程之中,是进程中的实际运作单位。一个线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。一般默认一个进程中只包含一个线程。
        操作系统中的线程概念也被延伸到CPU硬件上,多线程CPU就是在一个CPU上支持同时运行多个指令流,而多核CPU就是在一块芯片上集成了多个CPU核,比如4核8线程CPU芯片就是在集成了4个CPU核,每个CPU核上支持2个线程。
        有了多核多线程CPU,操作系统就可以让不同进程运行在不同的CPU核的不同线程上,从而大大减少进程调度进程切换的资源消耗。传统上操作系统工作在单核单线程CPU上是通过分时共享CPU来模拟出多个指令执行流,从而实现多进程和多线程的。

3.4.2 可重入函数定义

        可重入(reentrant)函数可以由多于一个任务并发使用,而不必担心数据错误。相反,不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信号量,或者在代码的关键部分禁用中断)。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入函数要么使用局部变量,要么在使用全局变量时保护自己的数据

3.4.3 可重入函数的基本要求

        不为连续的调用持有静态数据;
        不返回指向静态数据的指针;
        所有数据都由函数的调用者提供;
        使用局部变量,或者通过制作全局数据的局部变量拷贝来保护全局数据;
        使用静态数据或全局变量时做周密的并行时序分析,通过临界区互斥避免临界区冲突;
        绝不调用任何不可重入函数。

3.4.4 什么是线程安全

        如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
        线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行读写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

3.4.5 函数的可重入性与线程安全之间的关系

        可重入的函数不一定是线程安全的,可能是线程安全的也可能不是线程安全的;可重入的函数在多个线程中并发使用时是线程安全的,但不同的可重入函数(共享全局变量及静态变量)在多个线程中并发使用时会有线程安全问题;
        不可重入的函数一定不是线程安全的。

4. 从需求分析到软件设计

4.1 需求及需求分析

4.1.1 什么是需求

        需求是期望行为的表述。这么说起来比较抽象,我们具体分析一下:
        期望是谁的期望?主要是用户的期望,当然也包括待开发软件其他利益相关者的期望;
        行为是谁的行为?自然是软件的行为,具体来说就是是待开发软件中的对象和实体的行为;
        表述是谁来表述?是软件开发者来表述,具体来说就是需求分析师来表述和定义需求。
        根据以上分析,我们可以进一步来得出:需求分析就是需求分析师对用户期望的软件行为进行表述,并进一步用对象或实体的状态、属性和行为来定义需求。

4.1.2 什么是需求分析

        需求就是对用户期望的软件行为的表述;
          获取需求就是需求分析师通过关注用户的期望和需要,从而获得用户期望的软件行为,然后对其进行表述的工作;
        需求分析是在获取需求的基础上进一步对软件涉及的对象或实体的状态、特征和行为进行准确描述或建模的工作。

4.2 从需求进行分析与建模

4.2.1 需求分析的两类基本方法

        原型化方法(Prototyping)和建模的方法(Modeling)是整理需求的两类基本方法。
        原型化方法可以很好地整理出用户接口方式(UI,User Interface),比如界面布局和交互操作过程
        建模的方法可以快速给出有关事件发生顺序或活动同步约束的问题,能够在逻辑上形成模型来整顿繁杂的需求细节。

4.2.2 什么是用例

        用例(Use Case)的核心概念中首先它是一个业务过程(business process),经过逻辑整理抽象出来的一个业务过程,这是用例的实质。什么是业务过程?在待开发软件所处的业务领域内完成特定业务任务(business task)的一系列活动就是业务过程
接下来我们具体看看用例的几个基本要素:
        A use case is initiated by (or begins with) an actor. 一个用例应该由业务领域内的某个参与者(Actor)所触发。
        A use case must accomplish a business task (for the actor).用例必须能为特定的参与者完成一个特定的业务任务。
        A use case must end with an actor. 一个用例必须终止于某个特定参与者,也就是特定参与者明确地或者隐含地得到了业务任务完成的结果。

4.2.3 用例的三个抽象层级

        在准确理解用例概念的基础上,我们可以进一步将用例划分为三个抽象层级:
        抽象用例(Abstract use case)。只要用一个干什么、做什么或完成什么业务任务的动名词短语,就可以非常精简地指明一个用例
         高层用例(High level use case)。 需要给用例的范围划定一个边界,也就是用例在什么时候什么地方开始,以及在什么时候什么地方结束
        扩展用例(Expanded use case)。需要将参与者和待开发软件系统为了完成用例所规定的业务任务的交互过程一步一步详细地描述出来,一般我们使用一个两列的表格将参与者和待开发软件系统之间从用例开始到用例结束的所有交互步骤都列举出来。

4.3 从需求分析到软件设计

4.3.1 瀑布模型

        在继续进行从需求分析到软件设计的后续部分之前,我们有必要从整体上探讨一下我们所遵循的软件过程——敏捷统一过程。为了理解敏捷统一过程,我们先从瀑布模型(Waterfall Process)说起
        瀑布模型是最基本的过程模型,它把整个软件过程按顺序划分成了需求、设计、编码、测试和部署五个阶段。瀑布模型的根本特点是按顺序划分阶段,至于是像我们这样划分成五阶段,还是划分三个阶段或八个阶段,并不是关键。这一点需要读者注意,以免在阅读其他资料时产生困惑。

4.3.2 统一过程

         统一过程(UP,Unified Process)的核心要义是用例驱动(Use case driven)、 以架构为中心(Architecture centric)、 增量且迭代(Incremental and Iterative)的过程。用例驱动就是我们前文中用例建模得到的用例作为驱动软件开发的目标;以架构为中心的架构是后续软件设计的结果,就是保持软件架构相对稳定,减小软件架构层面的重构造成的混乱;增量且迭代体现在下图中。  

4.3.3 敏捷统一过程的计划阶段

        在项目正式动手开工之前,敏捷统一过程要求进行精心周密的构思完成计划阶段。计划阶段要做的工作有如下几点:
     &
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章