VSCode
- vscode 快捷键
- ctrl/win + O —— 打开文件夹
- ctrl/win + N —— 新建文件
- ctrl/win + W —— 关闭文件
- ctrl/win + K + W —— 关闭所有文件
- ctrl/win + K + U —— 关闭已保存的文件
- ctrl/win + S —— 保存文件
- ctrl + / —— 单行注释
- ctrl + shift + A —— 块注释
- ctrl + shift + E —— 资源管理器
- ctrl + shift + F —— 跨文件搜索
- ctrl + shift + G —— 源代码管理
- ctrl + shift + D —— 启动与调试
- ctrl + shift + X —— 管理扩展
- ctrl + shift + M —— 显示错误和警告
- ctrl + shift + P —— 查找并运行所有命令
- ctrl + ` —— 切换集成终端
- LSP(Language Server Protocol)协议
- 节制的设计
- 最重要的概念动作和位置即“在指定位置执行规定动作”,抽象为请求、回复并规定其规格。
- 基于文本、基于JSON、基于JSONRPC
- 合理的抽象
- 周全的细节
- 节制的设计
- DAP(Debug Adapter Protocol)协议
- VSCRD(Remote Devement)
- 可以在远程环境(比如虚机、容器)里开一个 VS Code 工作区,然后用本地的 VS Code 连上去工作
- 所有的交互都在本地 UI 内完成,响应迅速
- UI运行在本地,遵从所有本地设置
- 传输是操作请求和响应,开销与命令行相仿
- 第三方插件的功能依然可用
- 远程文件系统被完整映射到本地
- Extension Host
- VS Code 统管所有用户界面交互,制定用户界面交互的标准,所有用户的操作被转化为各种请求发送给插件进程,插件能做的就是响应这些请求,插件进程只能专注于业务逻辑处理,从而做到UI界面渲染与业务逻辑隔离,一致的用户体验。
Git
- 命令
- —— 在目录下创建版本库
- —— 查看当前工作区(workspace)状态
- —— 将文件添加至暂存区(index)
- —— 将暂存区(index)里的文件提交至仓库
- —— 查看HEAD前提交的记录,便于回到过去
- —— 查看HEAD之后提交的记录,便于回到未来
- —— 回退到某次提交的版本
- 默认 重置暂存区和上次保持一致,工作区文件内容不变
- 回退到某个版本
- 撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交
- —— 将远程库下载到本地库
- —— clone远程库并在本地创建版本库
- —— 合并两个或多个开发历史记录
- —— 从其他存储库或分支抓取并合并到当前存储库的当前分支 (= git fetch + merge)
- 区别
- 无需初始化本地仓库,和则需要
- 下来的项目可直接,、的项目则需要后才能
- 区别
- —— 将本地库相关数据对象更新至远程库
- —— 切换分支
- —— 创建并切换分支
- —— 查看分支
- —— 创建分支(并不切换)
- —— 另一个分支基础之上重新应用,用于把一个分支的修改合并到当前分支。
- 和的区别
- —— 合并当前分支的多个commit记录
- 团队合作项目标准流程
- 克隆或同步最新的代码到本地存储库;
- 为自己的工作创建一个分支,该分支应该只负责单一功能模块或代码模块的版本控制;
- 在该分支上完成某单一功能模块或代码模块的开发工作;
- 将该分支合并到主分支。
- 合并建议非快进式合并(–no-ff)
- git merge –no-ff 可以保存你之前的分支历史。能够更好的查看 merge历史,以及branch 状态。
- git merge 则不会显示 feature,只保留单条分支记录。
- 合并建议非快进式合并(–no-ff)
- 向别人仓库里贡献代码流程
- 先 fork(分叉) 别人的仓库,相当于拷贝一份;
- 做一些 bug fix或其他的代码贡献;
- 发起 Pull request 给原仓库;
- 原仓库的所有者 review Pull request,如果没有问题的话,就会 merge Pull request 到原仓库中。
Regular Expression
- 表达式
- —— 或
- —— 匹配任意一个字符
- —— 匹配出现一次或多次的字符(前一个字符)
- —— 匹配出现零次或多次的字符(前一个字符)
- —— 匹配出现零次或一次的字符(前一个字符)
- —— 匹配出现上限到下限次的字符
- —— 匹配一组希望的字符
- —— 定义要匹配的字符范围,如匹配从a-z的字符
- —— 定义不要匹配的字符,如匹配元音以外的字符
- —— 表示字符串开头
- —— 表示字符串结尾
- —— 即
- —— 即
- —— 即
- —— 即
- —— 即捕获组
- exp. 匹配 —— 其中即代表捕获组
- 贪婪匹配&懒惰匹配
- 默认greedy即贪婪匹配找到符合正则表达式模式的字符串的最长可能部分,并将其作为匹配返回。
- 可用开启lazy即找到符合正则表达式模式的字符串的最小可能部分。
- exp: titanic
- t[a-z]*i -> titani
- t[a-z]*-> ti
编写高质量代码的基本方法
- 通过控制结构简化代码(条件、循环、递归)
- 通过数据结构简化代码
- 一定要有错误处理
- 注意性能优先背后隐藏的代价
- 将更多精力放在提高工作效率、质量保证、代码的可读性、可扩展性等方面
- 拒绝修修补补要不断重构代码
模块化软件设计
- 模块化基本原理 —— 关注点分离
- 模块化是在软件系统设计时保持系统内各部分相对独立,以便每一个部分可以被独立地进行设计和开发。
- 模块化衡量指标
- 耦合度 —— 软件模块之间的依赖程度
- 紧密耦合(Tightly Coupled)
- 松散耦合(Loosely Coupled)(追求)
- 无耦合(Uncoupled)
- 内聚度 —— 软件模块内部各种元素之间互相依赖的紧密程度
- 功能内聚 (理想追求),也就是一个软件模块只做一件事,只完成一个主要功能点或者一个软件特性
- 耦合度 —— 软件模块之间的依赖程度
- 软件设计中的基本方法
- KISS(Keep It Simple & Stupid)
- 一行代码只做一件事
- 一个块代码只做一件事
- 一个函数只做一件事
- 一个软件模块只做一件事
- 使用本地化外部接口来提高代码的适应能力 —— 代理模式
- 先写伪代码的代码结构更好一些
- 因为伪代码不需要考虑异常处理等一些编程细节,最大限度地保留了设计上的框架结构,使得设计上的逻辑结构在伪代码上体现出来。从伪代码到实现代码的过程就是反复重构的过程,这样避免了顺序翻译转换所造成的结构性损失。
- KISS(Keep It Simple & Stupid)
可重用软件设计
- 消费者重用及生产者重用
- 消费者重用 —— 重用已有的软件模块代码
- 该软件模块能否满足项目所要求的功能
- 该软件模块代码是否比从头构建一个需要更少的工作量
- 该软件模块是否有完善的文档说明;
- 该软件模块是否有完整的测试及修订记录;
- 生产者重用 —— 生产可以重用的软件模块
- 通用的模块才有更多重用的机会;
- 给软件模块设计通用的接口,并对接口进行清晰完善的定义描述;
- 记录下发现的缺陷及修订缺陷的情况;
- 使用清晰一致的命名规则;
- 对用到的数据结构和算法要给出清晰的文档描述;
- 与外部的参数传递及错误处理部分要单独存放易于修改;
- 消费者重用 —— 重用已有的软件模块代码
- 接口基本概念
- 接口具体定义了软件模块对系统的其他部分提供了怎样的服务,以及系统的其他部分如何访问所提供的服务
- 接口基本要素
- 接口的目的;
- 接口使用前所需要满足的条件,一般称为前置条件或假定条件;
- 使用接口的双方遵守的协议规范;
- 接口使用之后的效果,一般称为后置条件;
- 接口所隐含的质量属性。
- 本地化外部接口
- 使用本地化外部接口来提高代码的适应能力, 将我们的代码接口分离出来,写成本地化的外部接口,能更好的帮助我们分离业务之间的关联性,使得代码开发更加高效。
- 软件架构模式
- 传统单集中式
- 适应大型机、小型机单体服务器环境
- 微服务 —— 一系列独立的微服务共同组成软件系统
- 各微服务分布式管理
- 系统通过前端应用或API 关来聚合各微服务
- 适应PC服务器的大规模集群及基于虚拟化技术和分布式计算的云计算环境
- 传统单集中式
- RESTful API
- GET用来获取资源;
- POST用来新建资源(也可以用于更新资源);
- PUT用来更新资源;
- DELETE用来删除资源。
- call-back/call-in函数
- call-in
- call-back
- call-in
- 耦合方式
- 公共耦合
- 共享数据区或变量名的软件模块之间即是公共耦合,他们隐式的共享了共享了数据区或变量名。
- 数据耦合
- 软件模块之间仅通过显式的调用传递基本数据类型
- 标记耦合
- 软件模块之间仅通过显式的调用传递复杂的数据结构(结构化数据)
- 公共耦合 > 标记耦合度 > 数据耦合
- 公共耦合
- 通用接口定义的基本方法
- 参数化上下文
- 通过参数来传递上下文的信息,而不是隐含依赖上下文环境
- 移除前置条件
- 简化后置条件
- 参数化上下文
可重入函数与线程安全
- 线程概念
- 操作系统能够进行运算调度的最小单位
- 每个线程拥有独自的调用栈,线程之间共享其他资源如全局变量
- 线程安全
- 如果同一段代码每次多线程运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
- 线程安全问题都是由全局变量及静态变量引起的
- 只读无写 ——> 一般线程安全
- 需写 ——> 考虑线程同步
- 可重入(reentrant)与不可重入(non-reentrant)
- 可重入(reentrant)可以由多于一个任务并发使用,而不必担心数据错误。
- 不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信 量,或者在代码的关键部分禁用中断)。
- 可重入的函数不一定是线程安全的
- 相同的可重入的函数在多个线程中并发使用时是线程安全的
- 不同的可重入函数(共享全局变量及静态变量)在多个线程中并发使用时会有线程安全问题
- 不可重入的函数一定不是线程安全的。
- Makefile
- $@ 表示目标文件
- $^ 表示所有的依赖文件
- $< 表示第一个依赖文件
需求
- 需求分析
- 需求分析就是需求分析师对用户期望的软件行为进行表述,并进一步用对象或实体的状态、属性和行为来定义需求。
- 需求类型
- 功能需求:根据所需的活动描述所需的行为
- 质量需求或非功能需求:描述软件必须具备的一些质量特性
- 设计约束(设计约束): 设计决策,例如选择平台或接口组件
- 过程约束(过程约束): 对可用于构建系统的技术或资源的限制
- 高质量需求
- 需求可测试
- 为每个副词和形容词指定定量描述
- 用实体的特定名称替换代词
- 确保每个名词都在需求文档中有定义
- 解决冲突
- 需求满足优先次序
- 必要的:绝对必须满足
- 可取的:非常可取但不是必需的
- 可选:可能但可以消除
- 需求很有特点
- 正确的 Correct
- 持续的 Consistent
- 毫不含糊 Unambigious
- 完全的 Complete
- 可行的 Feasible
- 相关的 Relevant
- 可测试 Testable
- 可追溯 Traceable
- 需求可测试
- 需求分析的两类基本方法
- 原型化方法(Prototyping)
- 原型化方法可以很好地整理出用户接口方式(UI,User Interface),比如界面布局和交互操作过程。
- 建模的方法(Modeling)
- 建模的方法可以快速给出有关事件发生顺序或活动同步约束的问题,能够在逻辑上形成模型来整顿繁杂的需求细节。
- 原型化方法(Prototyping)
用例
- 用例概念及要素
- 概念
- 用例的实质是经过逻辑整理抽象出来的一个业务过程,即完成特定业务任务的一系列活动。
- 要素(必要条件)
- 是一个业务过程
- 由业务领域内某个参与者(Actor)触发
- 为特定参与者完成特定业务
- 终止于某个特定参与者(Actor)
- 概念
- 用例三个抽象层级
- 抽象用例
- 动名词短语,就可以非常精简地指明一个用例;
- 高层用例
- 需要给用例的范围划定一个边界
- 扩展用例
- 所有交互步骤的详细描述(一般表格描述)
- 抽象用例
- 提取用例的基本办法
- 从需求中寻找业务领域相关的动名词和动名词短语(抽象用例)
- 验证这些业务领域相关的动名词和动名词短语到底是不是用例(满足四个必要条件)
- 在需求中识别出参与者、系统或子系统
- 业务领域建模基本步骤
- 收集应用业务领域的信息
- 头脑风暴
- 概念分类
- 画出UML
- 对象交互建模基本步骤
- 在扩展用例中右侧一列中找出关键步骤(关键步骤是那些需要在背后进行业务过程处理的步骤,而不是仅仅在表现层与参与者进行用户接口层面交互的琐碎步骤)
- 对于每一个关键步骤完成剧情描述
- 将剧情描述(scenario)进一步转换成剧情描述表
- 将剧情描述(scenario)或剧情描述表(scenario table)转换成序列图
软件开发模型
- 瀑布模型
- 需求 ——> 设计 ——> 编码 ——> 测试 ——> 部署
- 统一过程
- 核心要义
- 用例驱动 —— 用例建模得到的用例作为驱动软件开发的目标
- 以架构为中心 —— 保持软件架构相对稳定,减小软件架构层面的重构造成的混乱
- 增量且迭代
- 核心要义
- 敏捷统一过程
- 概念
- 将软件过程中每一次迭代过程划分为计划阶段和增量阶段
- 关键步骤
- 确定需求
- 通过用例的方式来满足这些需求
- 分配这些用例到各增量阶段
- 用例建模
- 业务领域建模
- 对象交互建模
- 形成设计类图
- 编码实现和应用部署
- 具体完成各增量阶段所计划的任务
- 概念
编程语言
- 闭包
- 异步调用
- lambda
没有银弹
- 软件中的根本困难,即软件概念结构(conceptual structure)的复杂性,无法达成软件概念的完整性和一致性,自然无法从根本上解决软件危机带来的困境。
三种系统
- S系统 —— 有规范定义,可从规范派生
- 矩阵操纵矩阵运算
- P系统 —— 需求基于问题的近似解,但现实世界保持稳定
- 象棋程序
- E系统 —— 嵌入现实世界并随着世界的变化而变化
- 预测经济运行方式的软件(但经济尚未被完全理解)
- 软件具有复杂性和易变性,从而难以达成概念的完整性与一致性。
设计模式
- 设计模式概念
- 设计模式的本质是面向对象设计原则的实际运用总结出的经验模型。
- 目的是包容变化,即通过使用设计模式和多态等特殊机制,将变化的部分和不变的部分进行适当隔离。
- 设计模式优点
- 提高程序员的思维、编程和设计能力
- 使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。
- 程序设计标准化,代码编制工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
- 设计模式组成
- 名称
- 目的,即该设计模式要解决什么样的问题;
- 解决方案
- 约束和限制条件
- 设计模式分类
- 按类与对象划分
- 类模式
- 处理类与子类之间的关系(继承),静态
- 模板方法模式
- 对象模式
- 处理对象之间的关系(组合聚合),动态
- 多数设计模式
- 类模式
- 任务类型划分
- 创建型模式
- 比如单例模式、原型模式、建造者模式等
- 结构型模式
- 比如代理模式、适配器模式、桥接模式、装饰模式、外观模式、享元模式、组合模式等
- 行为型模式
- 比如模板方法模式、策略模式、命令模式、职责链模式、观察者模式等
- 创建型模式
- 按类与对象划分
- 设计模式原则
- 开闭原则(Open Closed Principle,OCP)
- 软件应当对扩展开放,对修改关闭
- Liskov替换原则(Liskov Substitution Principle,LSP)
- 子类可以扩展父类的功能,但不能改变父类原有的功能
- 依赖倒置原则(Dependence Inversion Principle,DIP)
- 要面向接口编程,不要面向实现编程
- 应用于:模块化设计
- 单一职责原则(Single Responsibility Principle,SRP)
- 一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分
- 迪米特法则(Law of Demeter,LoD)
- 如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。
- 合成复用原则(Composite Reuse Principle,CRP)
- 软件复用优先考虑组合或聚合、其次考虑继承
- 开闭原则(Open Closed Principle,OCP)
- 常用设计模式
- 单例(Singleton)模式
- 原型(Prototype)模式
- 建造者(Builder)模式
- 代理(Proxy)模式
- 适配器(Adapter)模式
- 装饰(Decorator)模式
- 外观(Facade)模式
- 享元(Flyweight)模式
- 策略(Strategy)模式
- 命令(Command)模式
- 模板方法(TemplateMethod)模式
- 职责链(Chain of Responsibility)模式
- 中介者(Mediator)模式
- 观察者(Observer)模式
- MVC模式
- Model(模型)代表一个存取数据的对象及其数据模型。
- View(视图)代表模型包含的数据的表达方式,一般表达为可视化的界面接口。
- Controller(控制器)作用于模型和视图上,控制数据流向模型对象,并在数据变化时更新视图。控制器可以使视图与模型分离开解耦合。
- MVVM
- 优点
- 低耦合
- 可重用
- 独立开发
- 可测试
- 优点
- MVC与MVVM 的区别
- MVC中,用户对于M的操作是通过C传递的,然后C将改变传给V并且M将在发生变化时通知V,然后V通过C获取变化
- MVVM中,用户直接与V交互,通过VM将变化传递给M,然后M变之后通过VM将数据传递给V,从而实现解耦
- MVC中C承担数据解析,而MVVM中VM承担解析。
- MVC架构为什么更灵活以及MVVM架构为什么更智能
- MVC: 为了包容需求上的变化而导致的用户界面的修改不会响软件的核心功能代码,可以采用将模型(Model)、视(View)和控制器(Controller)相分离的思想
- MVVM: View和Model之间没有联系,通过ViewModel进行互,而且Model和ViewModel之间的交互是双向的,因此视图数据的变化会同时修改数据源,而数据源数据的变化也会立即应到View上。
- 软件角度分析MVC到MVVM的发展
- 随着前端页面越来越复杂,用户对于交互性要求也越来越高,jQuery是远远不够的,于是MVVM被引入到Javascript前端开发中。前端有了MVVM的设计思想后,终于实现了前后端工程及数据的彻底分离
软件架构复用
- 复用方法
- 克隆(Cloning) —— 完整地借鉴相似项目,只需简单修改
- 重构(Refactoring) —— 在参考已有的软件架构模型的基础上逐步形成系统软件架构
- 分解方法
- 面向功能
- 面向特征
- 面向数据
- 面向并发
- 面向事件
- 面向对象
- 架构描述方法
- 分解视图 Decomposition View
- 分解视图用软件模块勾划出系统结构,通过不同抽象层级的软件模块形成层次化的结构。
- 依赖视图 Dependencies View
- 展现了软件模块之间的依赖关系
- 泛化视图 Generalization View
- 展现软件模块之间的一般化或具体化的关系(例如继承)
- 执行视图 Execution View
- 展示了系统运行时的时序结构特点,比如流程图、时序图等。
- 实现视图 Implementation View
- 描述软件架构与源文件之间的映射关系。
- 部署视图 Deployment View
- 将执行实体和计算机资源建立映射关系
- 工作任务分配视图 Work-assignment View
- 将系统分解成可独立完成的工作任务,以便分配给各项目团队和成员
- 分解视图 Decomposition View
软件质量
- 软件质量定义
- 一个系统、组件或过程符合指定要求的程度,或者满足客户或用户期望的程度。
- McCall软件质量模型
- 产品修订(改变的能力)
- 产品过渡(对新环境的适应性)
- 产品运营(基本运营特征)
- 从以上三个角度总结出11个质量要素(外部视角——客户用户)和23个质量标准(内部视角——开发人员)
- CMM/CMMI软件质量模型
- 初始级 —— 目标及努力明确,目标可实行
- 管理级 —— 对项目有一系列管理程序
- 已定义级 —— 这套管理体系与流程予以制度化
- 量化管理级 —— 项目管理实现了数字化
- 持续优化级 —— 可能出现的问题予以预防,实现流程优化
- 软件质量属性
- 易于修改维护(Modifiability)
- 良好的性能表现(Performance)
- 安全性(Security)
- 可靠性(Reliability)
- 健壮性(Robustness)
- 易用性(Usability)
- 商业目标(Business goals)
软件过程模型
- 软件生命周期
- 分析、设计、实现、交付和维护
- 分析阶段的任务是需求分析和定义,形成业务概念原型
- 设计阶段分为软件架构设计和软件详细设计
- 实现阶段分为编码和测试(单元、集成、系统测试)
- 交付阶段主要是部署、交付测试和用户培训等
- 维护阶段一般持续时间最长且可能会形成单独的项目,再次循环
- 瀑布模型
- 过程活动的顺序结构,没有任何迭代,因为其假定需求不会发生任何变化
- V模型
- 在瀑布模型的基础上发展而来,因为测试是为了验证设计、确认需求,所以通过将瀑布模型前后两端的过程活动结合起来,可以提高过程活动的内聚度,从而改善软件开发效率。
- 生死相依原则——开始一个特定过程活动和评估该特定过程的过程活动成对出现
- 分阶段开发模型
- 增量开发
- 从一个功能子系统开始交付,每次交付会增加一些功能,这样逐步扩展功能最终完成整个系统功能的开发
- 迭代开发
- 首先完成一个完整的系统或者完整系统的框架,然后每次交付会升级其中的某个功能子系统,这样反复迭代逐步细化最终完成系统开发
- 增量开发
- 螺旋模型
- 兼顾了快速原型的迭代的特征以及瀑布模型的系统化与严格监控,并引入风险管理,使软件在无法排除重大风险时有机会停止,以减小损失。
- 计划 —— 确定目标、备选方案和限制条件 —— 评估替代方案和风险 —— 开发测试
- 个人软件过程PSP
- 团队软件过程TSP
- 团队基本要素
- 规模
- 凝聚力
- 协作的基本条件
- 团队强度和项目特点的关系
- 项目失败最根本的原因是团队问题(缺乏有效的领导和管理、不能做出妥协、安排或不善于合作、缺少参与、拖拉与缺乏信息、质量低劣、功能多余、无效的组员互评)
- 如何建设高效团队
- 建设具有凝聚力的团队
- 设定有挑战性的目标
- 反馈
- 共同遵守的工作流程和框架
- 团队基本要素
敏捷开发
-
宗旨
- 以人为本
- 目标导向
- 客户为先
- 拥抱变化
-
敏捷宣言
- 个体和互动 高于 流程和工具
- 工作的软件 高于 详尽的文档
- 客户合作 高于 合同谈判
- 响应变化 高于 遵循计划
- 尽管右项有其价值,我们更重视左项的价值
-
开发流程
- 找出完成产品需要做的事情 — Product Backlog
- 决定当前的冲刺(Sprint)需要解决的事情 — Sprint Backlog
- 冲刺(Sprint)。团队按照backlog任务执行。
- 得到软件的一个增量版本,冲刺评审会议,发布给用户。
- 在此基础上又进一步计划增量的新功能和改进。
-
总结
- 全员规划,分块并行
- 文档为纲,当面交流
- 迭代开发,分块检查,持续交付
- 优先开发,讲究实效
DevOps
- DevOps概念
- 一组过程、方法与系统的统称,用于促进软件开发、技术运营和质量保障(QA)部门之间的沟通、协作与整合。
- 精益原则
- 精益生产
- 在需要的时候、按需要的量、生产所需的产品
- 精益创业
- 先在市场中投入一个极简的原型产品,然后通过有价值的用户反馈不断改进,对产品进行快速迭代优化,以期适应市场。
- 最小可行产品
- 把产品最核心的功能用最小的成本实现出来(或者描绘出来),然后快速征求用户意见获得反馈进行改进优化。
- 精益生产
参考资料 代码中的软件工程
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!