本文来自本人独立博客,为获得更佳阅读体验,请点击 原文

----------------------------------------------------------------------------------------------------

「从粗放式的程序小子到精益化的编程大师。」

最近一直在思考,怎么算是有效地编程,个人该怎么做,一个开发团队又该如何? 这里的前提是假定需求的有效性,不考虑需求的无效导致的无谓的编程。 需求的有效性这是另外一个主题了,不在本文讨论。

我所在的开发团队,近三年前大部分都是刚毕业的学生,整个团队的开发风格就是粗放式的。 这里提到的 “粗放式” 是如何定义的,软件开发这个行业比较年轻,没有确切的定义,但在传统行业里提到的 “粗放经营” 可以用作类比,引用百度词条的定义如下:

粗放经营(Extensive Management),泛指技术和管理水平不高,生产要素利用效率低,产品粗制滥造, 物质和劳动消耗高的生产经营方式。

把上面这段话里面的经营二字改成编程,就很精确地表达我想说的粗放式编程的含义。

三年前大概就是上面说的粗放式编程的样子,那么三年后了现在是什么样呢?悲剧,还是粗放式的。 这不禁引发我思考粗放式编程的下一阶段是什么,路在何方? 然后就想到 “粗放” 的反义词 “精益”,然后又从传统行业里找到了关于 “精益生产” 的定义:

精益生产,简言之,就是一种以满足用户需求为目标、力求降低成本、提高产品的质量、不断创新的资源节约型的生产方式。

对的,把上面的生产换成编程就是我想要的 “精益编程”。感觉自己灵光一现找到了道路,看见了黎明的曙光。 再一查原来精益软件开发的思想早在 2003 年初就被 Mary Poppendieck 提出,并还写了本书专门来阐述 (Lean Software Development: An Agile Toolkit)。 好吧,2003 年我还在学校刚开始学习编程呢,自然很难切身体会精益编程的思想,不过一路走来最后发现英雄所见略同, 也就更有信心了,这真是黎明的曙光,不是海市蜃楼。

这下找到了方向,就是从粗放式向精益化的转变,那么这两者之间是否存在一个边界,就像历史上从东德到西德, 只要翻过了柏林墙世界就大变样了?我是否就是要找到这堵柏林墙把它推倒然后就从粗放式转变到了精益化? 仔细这么一思考,还真没这么明显的一堵墙。

拿着放大镜看看粗放式的编程是怎么的干活,一个需求到达开发后,开搞,搞完,上线,上完客户说 O 了,然后就没有然后了。 上面这个过程重复 500 遍,然后我们得到了一个提供 500 个不同业务服务的大型应用,然后问题来了。 加新功能开始变慢,再加第 501 个需求时,前面好几个功能突然就不正常了,代码量激增,维护困难。 这大概就是粗放式编程的第一阶段。

然后开始拆分业务功能,按小功能集打包成服务,服务独立部署,降低开发耦合付出的代价是提高了部署和运维的复杂度和难度。 新名词诞生了,面向服务架构(SOA)或者更新的微服务架构。 粗放式编程进入了第二阶段。

上面我们使用了最新最潮的服务架构,为什么还是粗放式的?因为我们还仅仅是在关注业务功能需求, 拆分服务也仅仅是降低了业务的耦合度,理顺业务服务之间的关系。 业务代码的开发是冰山露在海面上的部分,而海面下则是非功能性需求的支持,包括:可维护性、可扩展性、性能等。 今天受益于开源代码的流行,很多基础库代码的复用节省了大量的冰山下的开发维护成本, 但针对上面说的三个方面依然与业务代码开发息息相关。只是在粗放式的早期阶段我们能完成好功能已经不错, 回想下刚毕业时能让自己开发的系统顺利跑起来,完成客户的需求已经很开心了。

服务拆分是从整体上提升了系统的可维护性、扩展性和性能。但落在每个单个服务上,这三点取决于该服务的开发人员 的经验和水平,该服务的开发人员若还属于粗放式第一阶的话,可能就考虑不了那么多了。 精益编程的原则能帮助您通过迭代趋向完美:将软件开发看成一个不断探索的过程。 就整体系统而言,每轮迭代可能关注的重点不同,粗放阶段停留在完成功能,而进入精益阶段则关注非功能属性, 其目的是最低成本,最高质量的提供服务,最大化客户价值。

系统架构师关注系统服务整体拆分和部署的合理性,统观全局,这是关注整体系统的非功能属性。 架构师还需要关注每个核心服务的关键细节,以避免瓶颈效应影响整体系统的表现。 而每个服务的开发者则更需要具体关注服务的非功能属性,选择优化的实现方式。 这样算是迈入了精益化编程阶段。

具体开发服务时该如何关注非功能属性,应该没有统一方式,这里就我个人经验理解简单说说。

可维护性

  1. 单一服务提供的功能简单,职责唯一。
    简单更易维护。
  2. 服务之间功能正交。
    正交减少重复。
  3. 考虑新版本服务替换旧版服务时的并行性。
    意味着多考虑数据结构的稳定性,Linus 说的好程序员关注数据结构是有道理的。
  4. 提供不过时的文档说明。
    像维护代码一样维护文档,像写代码一样写文档,注重明确、清晰。
  5. 考虑可读性,命名,排版,一致性。
    像写文档一样写代码,注重可理解。

可扩展性

  1. 无状态更优。
    易于水平扩展,随时启停。
  2. 最小化共享资源的依赖。
    能不依赖更好,扩展到一定阶段的瓶颈可能就是共享资源。
  3. 基础服务多考虑提供 SPI 扩展接口,业务服务看情况。
    业务服务通常通过替换升级,而基础服务经常通过 SPI 扩展升级。

性能

  1. I/O 是英镑,内存是 RMB。
    访问 I/O 花的是英镑,访问内存花的是 RMB,能不花就不花,一次内存访问都是好几百个 CPU 时钟周期,要像花钱一样心痛。
  2. 碰到性能问题先从自己的代码上找原因。
    Java 程序员说起性能调优,总喜欢谈 JVM 调优,其实大部分性能问题都不是 JVM 的。
  3. 优化的前提是当前性能不能满足需求,提供性能数据证明。
    服务除了提供功能,还要性能指标说明,支持的 TPS,单次调用时长等,优化后也要提供数据对比。
  4. 性能回归自动测试,避免服务升级性能退化。
    其实现在能做好功能回归的都不多,性能花的功夫更少,继续努力。
  5. 更少的代码,更好地性能。

从粗放式到精益化编程相关推荐

  1. 漫谈粗放与精益:编程的两种思路与方式

    本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等 几年前,我给团队负责的整个系统写过一些公共库,有一次同事发现这个库里存在一个Bug,并告诉了我出错的现象.然后我便去修复这个 ...

  2. linux无锁化编程--__sync_fetch_and_add系列原子操作函数

    linux支持的哪些操作是具有原子特性的?知道这些东西是理解和设计无锁化编程算法的基础. 下面的东西整理自网络.先感谢大家的分享! __sync_fetch_and_add系列的命令,发现这个系列命令 ...

  3. java组件化的优势_组件化编程开发如何判断组件的优劣性

    随着互联网的不断发展,越来越多的程序员都在学习不同的编程开发方式,而组件化编程开发就是其中的一个常用开发方法.今天我们就一起来了解一下,组件化开发中关于组件的优劣性应该如何判断. 认识组件 随着近些年 ...

  4. Stanford UFLDL教程 矢量化编程

    矢量化编程 当使用学习算法时,一段更快的代码通常意味着项目进展更快.例如,如果你的学习算法需要花费20分钟运行完成,这意味着你每个小时能"尝试"3个新主意.但是假如你的程序需要20 ...

  5. c++以代理的方式来实现接口化编程

    假如你项目代码本身已经实现了很多的实体类,但并未采用接口,可以考虑以这种方式来实现接口化编程 struct ITest {virtual void Test()=0; };class CTest { ...

  6. matlab 矢量化编程(二)—— 使用 meshgrid

    matlab 矩阵矢量化编程 使用 meshgrid 使用 meshgrid 避免二重循环. patchSize = 17;pixel_weights = zeros(patchSize); mid ...

  7. leo-editor 关于 flutter 企业级路由 fluro 官方例子文学化编程分析

    fluro 是 flutter 企业级路由插件,在学习官方例子时有一些难度. fluro官方例子 下面是官方例子运行图 下面使用 leo-editor 对此例子进行文学化编程分析,按照从顶至底的顺序, ...

  8. Vue2基础、组件化编程、脚手架、Vuex、Vue路由、UI组件库

    尚硅谷张天禹老师讲课 学习视频 1.Vue简介 Vue2中文官网 1.1 Vue 介绍 一套用于构建用户界面的渐进式JavaScript框架 构建用户界面:把数据通过某种办法变成用户界面 渐进式:可以 ...

  9. 纷享销客高燕:回归第一性原理,B2B企业如何向精益化要增长

    什么是第一性原理?这个名词的火爆主要得益于"钢铁侠"埃隆·马斯克.他曾在采访中提到自己长期推崇的"第一性原理"思考法则:"通过第一性原理,我会回归事物 ...

最新文章

  1. iOS Sharing #02 | 2019-03-30
  2. vue之axios 登陆验证及数据获取
  3. java jframe 设置背景图片_JFrame如何设置背景图片
  4. usb设备由生产到使用 java 114979888
  5. go redis 序列化_求求你不要手写Redis缓存
  6. 不可能解开的谜题 (程序员修炼之道,评注者序)
  7. python 数据分析 电信_实例 | 教你用Python写一个电信客户流失预测模型
  8. 如何在OTN网站下载Grid方法(Oracle RAC)
  9. python方法怎么调用_python函数怎么调用自身?
  10. 网站域名被拦截,网站被流量劫持,服务器攻击,网站被跨区恶意点击,问题的定义与解答
  11. mysql neq什么意思_【知识科普】标准中的Eqv、Idt和Neq分别代表什么?
  12. 中国十大电子商务网站排名揭晓
  13. 银行卡格式化(每四位空格,删除添加,更变等)
  14. YoloV4论文学习
  15. 文档矫正(计算机视觉实验)
  16. msi笔记本u盘装linux,微星msi电脑重装系统_微星笔记本一键U盘重装系统教程图解...
  17. 以三维视频融合为核心的[点卯.增强虚拟全景平台]免费版,在智慧城市和安防监控行业中的应用
  18. 运行kaldi中遇到的问题总结
  19. 154 万 AI 开发者用数据告诉你,中国 AI 如何才能弯道超车?
  20. Android源码分析 - Framework层的Binder(客户端篇)

热门文章

  1. gem意思_GEM什么意思
  2. html怎么用chrome测试,html5 – 如何测试触摸事件现在Chrome无法进行标准测试?
  3. ip反查域名脚本实现
  4. realmeq2可以刷鸿蒙系统吗,realmeQ2Pro有NFC功能吗?可以用realmeQ2Pro刷公交和地铁吗...
  5. 动软代码生成器之 模板功能介绍
  6. 软件构造博客之工厂模式
  7. 移动web-版心容器
  8. [SDIO]Read Wait 读等待机制
  9. 从3元/条的个人信息买卖看企业数据安全建设
  10. lqc_使用SNAT、DNAT策略实现网关应用