The art of code(一)

2022-07-06  本文已影响0人  冰菓_

一. 软件工程能力

为什么要重视工程能力

由于行业内竞争加剧,成本上涨和产业升级等形势的变化,工程能力收到越来越高的重视
工程能力首先会影响"打得准不准".如果从业者不能做好需求识别和分析,缺乏产品方面的意识,那么研发出的软件就没有市场和用户
工程能力还影响"是否能打赢".工程能力会影响软件研发的效率,质量和成本,一个低效,低质量和成本高的软件项目是没有市场竞争力的

什么是工程能力

提升工程能力不等于写好代码,工程能力反应的是团队的综合素质.在软件研发中,很多从业者的大量时间其实并没有用在琢磨技术上,而是用在了其他方面(沟通,项目协调,错误设计导致的返工),这些方面的时间消耗往往也没有得到大家的关注

工程能力的定义

在百度内部材料中,将工程能力定义为:使用系统化的方法,在保证质量的前提下,更高效率地为客户/用户持续交付有价值的软件或服务的能力

质量第一:无论如何定义质量,客户都不会容忍低质量的产品.质量必须被量化,并建立可落地实施的机制,以促进和激励质量目标的达成
实现价值持续交付:软件/服务的价值提供是长周期的,从业者做好长期维护,长期服务,持续改进优化的思想准备

怎样提升工程能力

工程能力的素质要求
  1. 公司能力素质
    规范和指南,工具,平台,开源协作,知识管理,人力资源机制
  2. 团队能力素质
    研发过程管理,研发效率,成本意识,教育培养
  3. 个人能力素质
    需求把握,系统设计,编码能力,项目管理,运维能力,产品意识,客户服务意识,安全意识,质量意识,沟通能力
人是工程能力的根本

伟大的系统和产品一定来自优秀的人和团队.在人没有改变的情况下,团队规模的增加,劳动时间的延长,都无法从根本上改变软件的品质.无论是对于组织还是个人,都应该在培养人方面投入更多的资源

工程能力提升源自自我驱动

作者一直秉持的一个观点就是:如果一个人知道什么是高效而正确的方法,那么他一定不会继续使用低效且错误的方法相对于依赖指标考核,不如通过教育和培训让工程师了解什么才是正确的方法

个人能力的素质要求

写好代码(对应编码能力),写好文档(对应需求把握和系统设计),做好项目管理

  1. 没有好的管理,再好的技术也是没有用的
  2. 好的代码,首先来自好的设计
  3. 需求分析先于系统设计

二. 代码的艺术

背景和初衷

在尽量早的时候,形成正确的意识,对一名软件工程师的快速成长是非常关键的

代码和艺术

代码也能成为艺术品
软件工程师和码农

一个软件工程师要具备非常高的综合素质,具体包含一下几个方面:

  1. 专业知识
    软件工程师需要掌握的专业知识包含数据结构,算法,编码方法,还包括系统结构,操作系统,计算机网络,分布式系统
  2. 产品
    软件工程师还需要具有产品方面的思维,要对业务有深刻的理解,为了提供良好的用户体验,软件工程师需要学习交互设计,这是一个非常专业的学科方向;还需要学习产品数据,会基于这些数据来优化产品;更需要学习产品/业务运营,这对很多运营型的产品来说是非常重要的
  3. 项目管理
    做软件项目不是一个人的工作,要做好软件项目需要懂得管理.有很大比例的软件工程师不懂项目管理,忽视项目管理对软件项目成功的巨大作用
  4. 研究和创新
    有一些项目具有很强的研究和创新属性,这就要求软件工程师要具备研究的能力
来自艺术的启发
写代码并非易事

写代码并不是容易的事情,具体的原因如下:

  1. 写代码是从无序变为有序的过程,计算机中所运行的程序时按照严格的逻辑来执行的,而现实世界纷繁复杂,其中的秩序并不是一眼可以辨识的,需要我们把他整理为有序的结构
  2. 写代码将现实世界中的问题转化为数字世界中的模型.程序是数字世界的一种映射.其中涉及对现实世界的抽象和建模
  3. 写代码是一个认识的过程.在写代码的过程中,原来所未知的问题,在代码完成后变为已知.对于一项新业务,在开始时我们可能并不了解,但通过逐步分析,逐渐有了更深入的理解,在这个认识的基础上可能开发出对应的软件

好代码和坏代码

好代码的特性
  1. 鲁棒
  2. 高效
  3. 简洁
  4. 简短
  5. 可测试
  6. 共享
  7. 可移植
  8. 可观测/可监控
  9. 可运维
  10. 可扩展
坏代码的例子
  1. 不好的函数名称
  2. 不好的变量名称
  3. 没有注释
  4. 不好的排版
  5. 无法测试

好的代码从哪里来

好代码不止编码
  1. 在编码前,需要做好需求分析和系统设计.而这两项工作是经常被大量软件工程师忽略或轻视的环节
  2. 在编码时,需要编写代码和编写单元测试
  3. 在编码后,要做集成测试,上线,以及持续运营/迭代改进,这几件事情都是要花费不少精力,比如上线,不仅仅要做程序部署,而且要考虑程序是如何被监控的
需求分析和系统分析
  1. 几种常见的错误现象
  2. 研发前期多投入,收益更大
  3. 修改代码和修改文档,哪个成本更高
  4. 需求分析和系统设计之间的差别
    需求分析:定义系统/软件的黑盒的行为,它是从外部看到的,在说明是什么
    系统设计:设计系统/软件的白盒的机制,它是从内部看到的,要说明怎么做和为什么

如何做好需求分析

如何描述需求👍

在描述需求时,我们要考虑的是:如何用寥寥数语勾勒出一个系统的功能,以GFS(谷歌文件系统)为例:GFS的设计目的是:基于商用邮件组成的大型集群,为其提供有效和可靠的数据访问机制. 在获取需求信息后,我们需要更加详细的信息,而且在需求描述中,需要使用精确的数字来刻画需求.对于很多指标来说,量变会导致质变

对需求分析的误解

误解1. 需求分析和软件工程师没有关系(沟通)
误解2. 做需求分析时需要考虑实现细节(防止"实现决定需求")

需求分析的重要性

导航模块

如何做好系统设计

什么是系统设计

系统设计是定义系统的架构,模块,接口和数据以满足特定需求的过程
另外,这个定义没有提到下面两点,一个是系统中使用的关键算法,对于某些系统来说,算法是比较复杂的,需要花费不少精力来设计.另一个就是系统设计思路,当前的系统设计并不是终点,未来也会有优化或重构,对于未来从事这些工作的同事来说,系统设计中所留下的设计思路是非常有价值的

设计文档的分类👍
  1. 总体设计文档:描述系统的总体构成和运行机制
  2. 子系统设计文档:描述构成系统的某个子系统的组成和运行机制
  3. 接口定义文档:描述系统对外提供的接口
  4. 关键算法说明文档:描述系统中的关键算法
  5. 数据表设计文档:描述系统使用的数据表的设计,可能是数据库的设计,也可能是其他存储设备的设计

将不同类型的设计文档独立存放的原因在于:第一点是便于读者阅读,每个文档都有特定的读者,比较经典的是接口定义文档,这个文档是提供给系统的外部使用者的.第二点是便于编写文档的人进行修改和维护,进行切分文档后,在做修改维护时冲突的可能性会大大降低,同时也降低了设计文档成为"巨型文档"的可能性,对短小的文档进行阅读和维护的难度都更低

什么是系统架构

系统架构是概念模型,定义了系统的结构,行为和更多的视图

  1. 静:首先,从静止的角度,描述系统如何组成,以及系统的功能在这些组成部分之间是如何划分的,这就是系统的结构.一般要描述的是:系统包含哪些子系统,每个子系统有什么功能.在做这些描述时,应感觉自己是一名导游,带着游客在系统的各子系统间参观
  2. 动:然后,从动态的角度,描述各子系统之间是如何联动的,它们是如何相互配合完成系统预定的任务或流程的,这就是系统的行为,在做这个描述时,应感觉自己时一名电影导演,将系统的各种运行情况通过一个个短片展现出来
  3. 细:最后,在以上两种描述的基础上,从不同的角度,更详尽地刻画系统的细节和全貌,这就是更多视图
系统设计的原则和方法
  1. 单一目的
  2. 对外关系清晰
  3. 重视资源约束
  4. 根据需求做决策
  5. 基于模型思考

作者说,数据结构这门课可以用一下两句话来概括

  1. 如何用空间换时间,从链表到哈希表,再到二叉树,通过使用更多的存储空间,不断降低查找等操作的复杂度
  2. 如何在读复杂和写复杂间做权衡,对很多数据结构来说,读和写是一对矛盾的操作,在很多时候,我们会假设读的频率远高于写,于是在优化中更偏向于牺牲写的性能,从而提高读的性能
重视对外接口
  1. 对外接口比系统内部实现更重要
    第一点.对外接口定义了系统对外所提供的功能.如果功能不正确,系统就不会产生价值,而我们编写软件的最终目的是提高价值.第二点,对外接口决定了系统的外部关系
  2. 对外接口的形态
  3. 设计和修改对外接口的注意事项

如何写好代码

代码的沟通价值
  1. 50%以上的时间是用于沟通的
  2. 写代码也是一种沟通方式
  3. 代码为人而写
  4. 表达能力很重要
模块的设计方法
  1. 程序的构成
    程序由多个模块构成,每个模块内包含数据的定义,函数的实现和类的实现
  2. 模块的形态
  3. 模块划分的重要性
  4. 模块设计的方法
划分模块的方法
  1. 数据类的模块
  2. 过程类的模块
  3. 以BFE开源项目为例
函数的设计方法
  1. 类和函数
  2. 函数划分
  3. 函数描述三要素
    第一个是功能,描述这个函数是做什么的,一个函数的功能尽量能用一句话表述清楚,最好在函数的开头就将函数的功能用注释的方式写下来
    第二个是传入参数,各个参数的含义和限制条件,对于函数中的每个参数,其含义应该有明确的说明,对于参数的限制条件也应该给出说明
    第三个是返回值:返回值的各种可能性.返回值并不是只靠一个数据类型就可以看懂,而是需要将返回值的各种可能性都写清楚
  4. 控制函数的规模
  5. 函数的返回值
  6. 单入口单出口
代码块的编写注意事项
  1. 案例对比
  2. 代码段落区分清楚
  3. Donnot make me think
  4. 注释不是补出来的
    作者推荐写注释的方法是:先写注释,再写代码
软件开发中的命名
  1. 命名很重要
  2. 命名中出现的一些问题
  3. 命名不是一件容易的事情

如何支持系统运营

可检测性的重要性

成为优秀软件工程师的三条路径

学习 -- 思考 -- 实践
知识 -- 方法 -- 精神
基础乃是治学之根本

三. 代码评审

代码评审的常见误区

为什么要做好代码评审

代码评审的重要意义
  1. 代码评审的目的是改进代码质量.代码可以运行,但是并不意味着它一定正确.在软件开发中越早发现问题,修复的成本就越低
  2. 高质量的代码能够节省成本,虽然当前代码评审会花费时间,但是从长期来看这是值得的
  3. 仅从知识传递这一点考虑,代码评审也值得做.每个人不应该仅仅知道代码是怎么修改的,更应该知道设计决策背后的原因.代码评审给了开发者一个解释它们设计的机会.在代码评审中,开发者之间可以相互学习
  4. 在辅导他人编码方面,代码评审是最好的方法
  5. 代码评审使团队对顶级开发者更有吸引力
没有做好代码评审的后果
为什么要提升代码质量
为什么要提升编码能力

作者说:很多工作多年的软件工程师在编码方面任然处于业余水平,写出来的代码,既不符合基本的编码规范,也缺乏设计思想,这样的人很容易在35岁左右出现职业危机

如何做好代码评审

代码评审的常见问题
  1. 各种拼写错误
  2. 未优化的代码实现
  3. 不必要的复杂代码
  4. 重复实现已经存在的代码逻辑
  5. 缺少必要的注释
  6. 缺少必要的单元测试
    .....
代码评审的正确态度
代码评审的推荐步骤
对坏代码的简单判断
代码评审的注意事项
上一篇下一篇

猜你喜欢

热点阅读