代码中的软件工程复习

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

  • 通过控制结构简化代码
  • 通过数据结构简化代码
  • 一定要有错误处理
  • 注意性能优先的代价
  • 拒绝修修补补不断重构代码

性能优先策略带来的隐藏代价

  • 软件工程师的人力成本远 大于所消耗的 计算资源成本时, 提高代码编写的工作效率将更有价值;
  • 质量保证的人力成本和质量保证的成效也比所消耗的 计算资源成本更有价值;
  • 性能优先的策略往往会让代码很难理解,结果需要消耗更多的工时;
  • 面向机器的代码修改起来更困难,可扩展性差,同样会消耗更多工时。

模块化的基本原理

模块化是在软件系统设计时保持系统内各部分相对独立,以便每一部分可以独立的设计和开发。基本原理是关注点的分离。通过”分而治之”,将复杂问题分解成一个个简单问题,减少出错的情形。

我们一般使用耦合度和内聚度来衡量软件模块化的程度。内聚度是一个软件模块内部各个元素的紧密程度,耦合度是软件模块之间依赖程度。

为什么追求高内聚低耦合?

内聚度越高,模块内只做一件事,只完成一个主要的功能点。这使得每一个模块都易于开发和理解。

在软件设计中,我们更追求松散耦合。这样,整个系统更容易定位软件bug,因为每一个bug都局限在一两个模块内。整个系统也更好维护,扩展时只需要变更少量的模块。

软件设计中的一些基本方法

KISS原则:一行代码只做一件事,一个块代码只做一件事,一个函数只做一件事,一个软件模块只做一件事。

使用本地化外部接口来提高代码的适应能力,即将外部代码进行二次封装,写成本地接口,能更好的帮助我们分离业务之间的关联性,降低模之间的耦合度,使得代码开发更加高效。——”不要和陌生人说话”

先使用伪代码写出代码结构,一是可以提供一个框架,避免代码无序生长;二是不需要考虑异常处理等变成细节,避免了编码带来的结构性损失。

消费者重用

软件开发者在项目中重用已有的软件模块。一般要重点考虑以下四点:

  • 该模块是否能满足项目所要求的功能
  • 重构该模块是否比从头构建一个软件模块工作量少
  • 该模块是否有完整的文档说明
  • 该模块是否有完整的测试和修订记录

生产者重用

生产者重用即生产可以重用的软件模块。一般要考虑以下几点:

  • 通用模块才有重用的机会
  • 对设计的 接口要有完善的 描述
  • 进行测试并且有 修订记录
  • 一致的 命名规则
  • 对用到的 数据结构要有完整的 *说明

接口的基本概念

接口是互相联系的双方共同遵守的一种协议规范。

在软件模块内部,一般是通过一组函数API来约定软件模块间的沟通方式。

对于面向过程编程,是通过一些数据结构和操作这些数据结构的方法来定义接口。对于面向对象的编程,一般是用对象对外暴露的属性和方法来定义接口。

接口的五个基本要素

接口的目的

接口的前置条件(如参数在什么时候才有意义)

接口双方遵守的协议规范(如互相联系双方的传入参数都必须是某种数据结构)

接口的后置条件(如 返回值)

接口所隐含的质量属性

为什么使用微服务而不是单体集中式架构

通过模块化的思想垂直划分业务功能,由一系列微服务共同组成软件系统的一种架构模式。

每个微服务独立部署,跑在自己的进程中,有自己独立的堆栈。每一个微服务可以分解成最小的产品,达到功能内聚。微服务之间无耦合或者有极为松散的耦合,系统通过前端应用来聚合微服务达到业务功能。

微服务架构的出现是由于传统的单体服务器转变为基于虚拟化技术和分布式云计算技术的PC服务器的大规模集群。

接口与耦合度之间的关系

公共耦合:即两个软件模块之间的接口定义不是通过显式调用,而是通过隐式共享数据区或变量名。

数据耦合:仅通过显式调用传递基本数据类型。

标记耦合:通过显式调用结构化数据,此时数据的结构称为软件模块之间的隐含规定,因此耦合度比数据耦合高。但比公共耦合这种没有显式调用的数据传递方式要低。

通用接口定义的基本方法

参数化上下文

移除前置条件

简化后置条件

可重入函数

可重入函数即可以又多个并发任务使用,而又不用担心错误。可重入函数只使用自己栈帧的数据,可以在任何时候中断。

如果要使用全局变量或者static,一定要注意保护自己的数据(如关中断、信号量)。可重入函数不能调用malloc和free这样的不可重入函数,不返回指向静态数据的指针。

什么是线程安全

如果所在的进程中有多个线程,当且仅当多个并发线程反复调用这段代码且结果总是正确,就说这段代码是线程安全的。

线程安全问题是由于全局变量和静态变量引起的。如果只对全局变量或者static变量进行读操作,一般来说是安全的,但是如果多个线程执行写操作,就需要考虑同步和互斥的问题。

可重入函数是线程安全函数的子集,因此可重入函数一定是线程安全的。而线程安全不一定是可重入的。

RESTful API

表现层状态转化,有表现层一定有背后的信息实体,信息实体就是URI代表的资源,状态转换是通过HTTP里定义的四种操作方式:

  • GET用来获取资源
  • POST用来新建资源
  • PUT用来更新资源
  • DELETE用来删除资源

为什么要有分支合并

每一个版本都是上一个版本的增量补丁,将 要合并的分支里的BDF几个增量补丁 合并到当前的工作区,解决冲突后提交为版本H,这就是合并。

代码中的软件工程复习

如果多人都同时向远程master提交代码,一是可能会有冲突,二是git log排列在一条时间线上,不利于查看或者回退代码。 可以使用git merge –no-ff,让一段连续的工作在commit日志时间线呈现出一条条支线。

git merge和git merge –no-ff的区别

git merge –-no-ff 可以保存你之前的分支历史。能够更好的查看 merge历史,以及branch 状态。

git merge 则不会显示 feature,只保留单条分支记录。

代码中的软件工程复习

团队项目的开发者的工作流程

  1. 克隆或同步最新的代码到本地存储库(git clone ——克隆远程库到当前目录下/ git pull——从其他库或分支抓取并合并到当前分支)
  2. 为自己创建一个分支,只负责单一模块的版本控制(git checkout -b mybranch——创建新分支/git branch ——切换分支)
  3. 在该分支上完成代码开发工作,多次进行如下操作(git add FILE——把文件添加到暂存区/ git commit -m “log”把暂存区文件提交到仓库)
  4. 先切换回master(git checkout master),再将远程master同步拉取到本地存储库(git pull),再合并分支到master(git merge –no-ff mybranch),最后推送到远程master(git push)。

git rebase

可以对某一段线性提交历史进行编辑、删除、复制、粘贴;因此,合理使用rebase命令可以使我们的提交历史干净、简洁!但是通过rebase对任何已经提交到公共仓库的commit进行修改!

vim命令和通配符

u复原前一个命令

ctrl r重做上一个动作

“*”表示前一个字符出现 0 次、1 次或多次;”+”表示前一个字符出现一次或多次

Original: https://www.cnblogs.com/Grong/p/15776795.html
Author: 乌有先生ii
Title: 代码中的软件工程复习

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/585741/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 事务与事务隔离级别详解

    事务基本概念 一组要么同时执行成功,要么同时执行失败的SQL 语句。是数据库操作的一个执行单元。 事务开始于: 连接到数据库上,并执行一条DML 语句in sert 、update…

    Linux 2023年6月14日
    095
  • Shell脚本编程初体验

    通常,当人们提到”shell脚本语言”时,浮现在他们脑海中是bash,ksh,sh或者其它相类似的linux/unix脚本语言。脚本语言是与计算机交流的另外…

    Linux 2023年5月28日
    096
  • Shell 脚本大全之检测两台服务器指定目录下的文件一致性

    Shell 脚本大全之检测两台服务器指定目录下的文件一致性 bash;gutter:true;</p> <h1>!/bin/bash</h1> …

    Linux 2023年5月28日
    0100
  • Redis 基础

    Redis 基础 Redis 定位 – 特性 关系型数据库 特性 非关系型数据库 特性 Redis 特性 Redis 安装 – 启动 – 使用 …

    Linux 2023年6月13日
    0137
  • Docker 安装 MySQL、Redis

    1 Docker 中安装 Redis 1.1 创建目录 在硬盘上创建 redis 的数据目录: mkdir -p /Users/yygnb/dockerMe/redis/data …

    Linux 2023年6月7日
    099
  • 代码上传Github后乱码解决方案

    阅文时长 | 0.23分钟字数统计 | 384字符主要内容 | 1、引言&背景 2、解决方案 3、声明与参考资料『代码上传Github后乱码解决方案』 编写人 | SCsc…

    Linux 2023年6月14日
    0174
  • [极客大挑战 2019]Secret File

    0x01 寻找做题信息 打开环境,查看源代码,发现可疑链接,/Archive_room.php,action.php打开action.php会发生302跳转,查找302跳转无果,百…

    Linux 2023年6月8日
    091
  • 位图实现

    位图就是用每个字节中的bit位代表一组资源的映射。 例如:一个字节有8位,在操作系统中可以用一个bit位代表一个4K的页,那一个字节就可以代表8页32K内存。 可以利用位图进行资源…

    Linux 2023年6月7日
    077
  • [20220228]enq TX

    [20220228]enq TX – allocate ITL entry的测试3.txt –//上个星期的测试有点乱,重新规划测试. 1.环境:SCOTT…

    Linux 2023年6月13日
    087
  • 一篇文章学会shell脚本

    一、Shell传递参数 运行: 二、Shell数组 运行: 三、Shell运算符 1、算术运算符 注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的…

    Linux 2023年5月28日
    086
  • 记一次从源码泄露到getshell(一)

    0x00 前言 此次渗透中的所有修改已经复原,且漏洞已经提交至cnvd平台 0x01 源码泄露 在一个月黑风高的夜晚,闲来无事的我又开着脚本利用hunter进行互联网站点源码的扫描…

    Linux 2023年5月28日
    0108
  • Python中import外部模块全局变量修改规则及踩坑

    最近碰到一个import外部文件全局变量修改后未符合预期效果的问题,简要描述如下: 有env.py, test.py, dal.py三个文件,env.py 中定义了DEBUG=Fa…

    Linux 2023年6月6日
    065
  • 函数指针的重要用途——回调函数

    什么是回调函数? 粗暴的说,如果一个函数作为另一个函数的参数传入,这种函数就可以称为回调函数(这句话并不严谨,但为了说明问题可以这么理解)。C语言里面,一般就是一个函数的参数列表中…

    Linux 2023年6月8日
    093
  • MySQL注入流程

    确认注入点 信息收集 数据获取 提权 写个MySQL注入流程的大纲,类似一份全局地图,能指导下一步工作。MySQL注入流程分为四步: 确认注入点 信息收集 数据获取 提权 确认注入…

    Linux 2023年6月6日
    0111
  • Python递归遍历目录下所有文件

    递归遍历目录下所有文件 方法一 import os def gci(filepath): #遍历filepath下所有文件,包括子目录 files = os.listdir(fil…

    Linux 2023年6月13日
    0108
  • 整理常用的 vim 命令

    vim 是一款功能强大的文本编辑器,它是Linux下常用的编辑器之一,对于熟练掌握了 vim 的人来说,用它编辑文件,方便又快捷,能极大的提高工作效率 vim 功能强大,对应的命令…

    Linux 2023年6月13日
    0101
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球