【读后总结】程序员修炼之道---从小工到专家

[TOC]c++

【读后总结】程序员修炼之道---从小工到专家

一,我的读后总结

本书相对比较基础,不是那种大规模程序设计、高并发设计等等,主要是针对程序员的一些基本素质和一些基本常规编程设计作一些梳理和规范,对于初入职的程序员,养成这些良好素质是很是有必要的;对于已经入职多年的程序员,回顾一下本书,而后结合自身状况看看是否可以基本达到本书中的一些素养也是有必要的。程序员

总体而言,有必定的经验性总结,相对来讲比较基础,对开发者也有必定的做用;对我我的而言,里面不少的素养、设计规范之类都有必定了解,不过可能平时作的不够完全,所以看完以后,仍是有必定的收获,至少有了这样的文档性的总结,方便后续快速检阅查看。算法

二,程序、架构设计方面

1,避免重复,进行复用

复用能够减小代码臃肿,也能够下降改动风险(一个改动,要改动多处,容易遗漏),增长开发效率。以下几个状况可能会使得有重复的代码,须要注意尽可能避免:数据库

  • 代码模块功能相似
  • 不一样语言要实现同一功能
  • 不一样开发者实现同一个相似功能

2,灵活的设计、隔离性

项目开发中,常常会遇到某个功能需求改变,或者某个底层资源改变,或者数据结构的改变,要作到撤销的最小代价,注意项目永远没有最终最肯定的抉择编程

代码架构的设计要保持灵活性、隔离性、可替代性;如某种负载均衡算法的替换,如istio数据平面的替换等。后端

这个架构设计须要:微信

  • 解耦数据结构

  • 接口抽象多线程

    • 抽象出各类不一样接口,如虚基类、纯虚基类、接口和实现
  • 隐藏细节架构

    • 接口暴露的方式,须要隐藏一些私有的细节处理,对外暴露统一的外部方法
  • 隔离

    • 如何保证互不影响,互无论理
  • 元数据方式

3,解耦合【正交性】

划分出细粒度的模块,而后各个模块之间解耦合,好比有一个函数的得墨忒耳法则.得墨忒耳定律也叫作“最少了解原理”,是一种软件设计原理,尤为是应用到面向对象的程序设计中,基本原理为:

  • 每一个对象对其余对象只能有最少的了解:只有整体才能接近个别对象;
  • 每一个对象只能和本身的朋友对话:不要和陌生人说话;
  • 只和本身最亲密的朋友对话。

必定尽可能不要开发设计出强耦合的系统,要划分模块、分层设计,这样能够提升效率,也能下降风险,不然,会牵一发而动全身。最简单的如MVC架构模型,上层应该能够支持多种形态,改动一个模块应该只影响另一个模块的调用而不是影响全局

每一个模块的设计须要有暴露给外部的,同时也会须要有私有的。解耦合的设计的理念就是:

  • 分层
  • 分模块
  • 抽象

4,分层架构设计

程序架构要分层,分而治之,划分不一样功能的子模块;划分模块以后,就要考虑模块(子服务)之间如何通讯问题,经常使用的方案如:

  • pub/sub:发布订阅模式

    • 只对感兴趣事件进行订阅
  • MVC模式

    • Model-View-Controller

5,元数据的设计

用元数据(metadata)描述应用的配置选项、参数、用户偏好等,不少程序设计中都用到了元数据,尤为是一些开源的大型项目中,那么元数据究竟是啥?元数据是指数据的数据,广义上就是任何对应用描述的数据。如数据库schema或数据词典。schema含有名称、存储长度等属性进行描述的属性,咱们应该要能够访问和操做这些信息,就像对数据库中任何其余数据同样。

典型状况系,元数据应该在运行时而不是编译时被访问和使用。优雅的方式是使用元数据进行数据配置和驱动应用,达到这样的目标:声明式思考,也便是规定要作什么而不是怎么作,并建立高度灵活的程序。核心设计思想就是将抽象放进代码,细节放进元数据,这样的优点在于:

  • 设计必需要解耦合,这样会更灵活

  • 须要建立更健壮、更抽象的设计;细节的处理推迟到程序以外

    • 这个,我尚未理解明白
  • 可定制,如插件化,无需修改程序

6,软件程序的并发和次序

时间是软件架构的一个常常被忽略的方面,这里的时间指的是程序自身的时间因素:

  • 并发:同一时间发生多个事件
  • 次序:事件在时间中的相对位置

尤为是互联网的开发设计中,并发是一个不可忽视的因子,设计之初就必需要考虑进来;如何防止并发冲突?如何保证高并发?

防止并发冲突,改善并发性,一个可能的原则就是分析工做流,能够经过UML活动图去分析。

另外,并发方面的编程,要考虑到多进程、多线程、多协程;服务端架构设计还要考虑高并发,如何扩缩容等

7,原型->基础框架->逐渐填充

当需求并不明朗的时候,或者当须要从0到1的时候,能够先快速搭建一个基础框架,实现一个最简单的诉求,固然须要划分模块、分层等基础设计,不用太过复杂,先实现效果,而后逐渐填充和丰富,小版本重构和优化,最终造成一个大的项目

前期必定须要原型的配合,先构建原型出来,而后再逐步迭代优化,须要注意:

  • 正确性
  • 完整性
  • 健壮性
  • 风格

原型设计中须要考虑:

  • 组件的定义和责任划分是否清晰
  • 耦合是否最小、是否细粒度
  • 接口定义、约束是否知足诉求

8,进行预估和评审

任何项目都须要进行预估,预估一下总体时间、风险点、项目大小等;预估完了以后,进行初步设计,设计了以后须要再进行评审:

  • 拆分组件、拆分模块
  • 细粒度组件、子模块的预估
  • 项目进度的预估
  • 项目风险的预估
  • 需求的评审
  • 项目的评审
  • 架构设计的评审

三,程序编码方面

要不断批判全部代码,包括本身的和别人的!!!

1,理解代码的工做原理

  • 不要盲目的写代码,要先理清原理、需求、设计等等,最后才是编码

  • 要制定阶段性的规划

  • 思考全部可能的边界并处理好全部边界条件,不要靠猜

  • 每一行代码都要清楚含义,确保本身写的代码就是本身要表述的流程,对代码白盒化

  • 严格的测试用例、正常条件、异常条件

  • copy原有代码的时候,想一想,是否可以优化?原有代码是否合适?

2,理清系统性能

要时刻估算程序的运行状况,QPS=10w如何,QPS=100W如何? QPS=1000W的时候又当如何?由于随着变化,大多数状况下都不是线性变化的。估算的范围包括但不限于:系统的处理时间、占用内存、CPU、磁盘io等

那如何估算?除了已有知识和经验可以帮助估算外,还能够进行建模估算:

  • 循环
  • 嵌套循环
  • 二分法
  • 分而治之
  • 组合

3,代码随时重构

架构须要优化,代码也随时须要优化,前期的代码总会有优化之处

当代码出现重复、过期的知识、性能问题、耦合性太强的时候就必需要进行重构;并且咱们须要常常性的重构而且要早早的开始重构,不然越到后面,历史包袱越大;每次回归本身的代码,都要考虑,可否重构,能否更优?

若是后面一个项目copy或者沿用前一个项目,那么后面的项目,必定要比前面的项目架构要更优,必定要作出改变,不然就不会有成长。

重构的时候须要注意一些技巧如:重构的时候不要新增功能,重构以前须要有较为全面的单元测试用例,重构完了以后须要全面测试

4,编写易于测试的代码和丰富的测试用例

单元测试、集成测试

小模块的测试

丰富的测试用例

示例代码

5,按合约设计(DBC)

人不可能写出十分完美的软件,不符合预期的程序、接口时有发生,咱们须要防卫性的编码,所以就是对方的都不可信任,好比输入参数。

按合约设计的思想在于充分利用前置条件、后置条件、类不变项。其实意思就是一切要按照事先约定的合约进行,如何保证呢?那么必须在设计的时候考虑:输入域的范围、边界条件是如何、输出数据是怎样、能够输出什么不能够输出什么。

一些好的姿式包括:断言、预处理、提早返回错误和崩溃。关于提早返回错误和崩溃的意义在于对于输入的检测上,要保证最初输入的异常就返回而不用等到程序开始计算运行以后才返回

6,程序发生奔溃的处理

程序发生错误、奔溃是没法避免的,可是咱们须要知道,若是错误已经发生,那么表明程序必定在某些地方存在问题,尤为是一些没法必现的问题,那么就须要咱们在错误发生以后可以有足够的信息去分析它并fix它。检查每个可能的错误,尤为是意料以外的错误是一种良好的实践。

若是程序发生一些极端错误以后,若是没有终止程序,颇有可能致使后端数据产生脏数据或者后端请求出现批量异常等等。所以须要及早抛出异常

经过断言来检测输入参数,在c、c++中是经常使用的优雅姿式,可是不要用断言去处理真正的错误流程

处理好错误流程和异常处理流程、捕获异常并进行处理,可是须要区分什么状况下才是真正的异常,这个可能须要根据实际状况去分析

7,解决疑难杂症问题的思路

要知道,任何问题都有解决方案,只是你暂时没有找到,或者没有找到合适的。排查问题的方法:梳理出全部可能的路径,先不要排除任何东西,而后逐一检查并排除。

对于疑难杂症的重要的思考点:

  • 这个问题是思路是否正确?注意力在这上面是否正确?
  • 是否有更容易的方法?
  • 为何如此难以解决?
  • 必须是这种方式解决吗 ?
  • 这个为何是一个问题 ?
  • 真的必须解决吗 ?

四,项目管理相关

1,需求相关

项目是否可以成功?项目的各类需求?

业务项目而言,会有产品经理提需求;基础项目而言,须要咱们开发人员本身挖掘需求、搜集需求,其中最重要就是挖掘需求

一个典型例子:

  • 只有指定人员才能查看档案【good】
    • 这样的需求过来,开发人员会设计一套权限管理系统,方便后续扩展
  • 只有领导和人事部门才能查看档案【bad】
    • 这样的需求过来,开发人员可能只是作一个简单的配置,进行前置静态检测
    • 只要需求改变,就可能没法知足,甚至须要修改代码

由于这就告诉咱们几点:

  • 需求颇有多是常常变更的,需求是否合理,如何知足日益变化的需求
  • 需求的陈述表达
  • 设计的时候必定要考虑后续的兼容性和扩展性
  • 抽象很重要

2,思考清楚再开始启动项目

若是有疑惑,必定要反复思考清楚,等一块儿都思考清楚,准备就绪后再开始编码、项目设计。

由于一旦没有思考清楚,极可能致使返工,或者是无用功,就怕就是折腾一两个月后发现前面都作错了!

3,程序的规范

程序须要有必定的规范,尤为是多人协做的程序

4,自动化工做流程

工做流程自动化、项目自动化,构建、编译、部署等;这个在咱们目前现有系统和工做中基本已经都是自动化了,如CI、CD等

5,各类类型的测试

自动化测试,早测试、常测试,测试占编码很大一部分;项目须要单元测试、集成测试;须要有必定的覆盖度。主要测试种类包括:

  • 单元测试
  • 集成测试
  • 验证和校验
  • 性能测试
  • 可用性测试
  • 资源耗尽、错误和恢复

6,文档和注释

关于文档方面,很重要,可是常常会发现文档跟不上代码节奏,能够将代码生成文档。另外就是代码注释,注释也常常跟不上代码节奏。所以须要注意文档和注释的编写、及时更新等

五,其余零散经验

  • 对象属性的读写不要直接暴露字段,应该用方法封装,方便将来调整,也可以保持一致性

  • 检查每个可能的错误,尤为是意料以外的错误是一种良好的实践。

  • 经过断言来检测输入参数,在c、c++中是经常使用的优雅姿式,可是不要用断言去处理真正的错误流程

  • 元数据的设计

【"欢迎关注个人微信公众号:Linux 服务端系统研发,后面会大力经过微信公众号发送优质文章"】

个人微信公众号
相关文章
相关标签/搜索