软件工程-理念与修习

『简约主义』

异教徒说:能在单脚站立期间讲完 Torah (旧约之首第 5 卷)所有内容,就改变信仰!

先知说:勿对别人做出连自己都憎恶之事,其它都是注释,你自己学习!

理解最本质的思想为接下来所有的细节提供了一个上下文关系,初始的动机(Basic Idea)最为核心。

理念篇

可维护的重要性

  • 面向维护设计
    • KISS原则+文档清晰

    • 系统的优化迭代与做新,会走到 $6 / 4$ 的比例上

  • 价值反馈提速
    • 商业模式/产品规划$\rightarrow$需求分析$\rightarrow$方案设计$\rightarrow$开发$\rightarrow$测试$\rightarrow$上线发布$\rightarrow$运营
    • 若软件生命周期是一个链路的话,过去 10 年软件行业在通过创新和实践在不断的加速反馈环。

软件工程直面的问题:复杂性

需求本身就是复杂的。编写优秀的软件要比做出可靠的设计更复杂(细节就是魔鬼)

功能需求+非功能需求+约束条件

  • 非功能需求:性能、吞吐能力、故障恢复、兼容性、弹性、可用性

  • 约束条件:技术熟悉度、容量「并发服务能力、系统存储量」、成本、失败容忍度

最大要对付的就是复杂性。面对复杂性做架构选择,有几个问题要先回答:

  • 熟悉的技术栈(我是谁)
  • 产品的发展阶段和规模带来的压力如何(我在哪)
  • 技术复杂度是首要问题了么?(我要干嘛)
    • 技术属性(搜索、视频)

回应好了这些问题,才能做出更匹配的架构设计,保证初级阶段的成功

复杂性的解药:拿来主义

  • 系统开发中常碰到险恶(Wicked)问题:只有通过解决或部分解决才能被明确的问题。

  • 分析你所能找到的所有类型系统、设计、代码

  • 经验表明:系统中 80%的部分应能找到参照系,能很大程度降低设计的难度和风险

全面分析是最棘手的 – 需求和技术上

面对重构同样是这样的原则:80%能工作,20%很烂,大部分改动奔着的目标是改进这 20%,却想推倒重来。控制住自己解决最核心的问题,比推倒重来要好。

高质量软件的目标:面向维护的设计

  • 最小的复杂度:避免聪明但不易理解的设计(KISS),才能经得起进化考验
  • 易于维护:软件的生命周期更多在维护阶段
  • 松散耦合
  • 可扩展性:面向未来设计(对变更进行隔离)
  • 可重用性:为团队积累做出贡献
  • 高扇入,低扇出:力求封装被最大需求,最小依赖
  • 层次性:力求在任意层次观察系统,层次间互相隔离
  • 标准技术:力求引入最少的新技术

做好设计有哪些要求

  • 事业开阔,避免造轮子
  • 难题解决能力
  • 行业经验带来的直觉和预见性
  • 庖丁解牛的切分和设计能力
    • 松耦合
    • 清晰并行
    • 不过度设计

高阶的要求是一步到位的能力或计划路线图

警惕过早的优化

发于 1974 年的《The Art of Computer Programming》: premature optimization is the root of all evil (or at least most of it) in programming.

we should forget about small efficiencies,say about 97% of the time: premature optimization is the root of all evil.Yet we should not pass up our opportunities in that critical 3%

The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times;

思维武器

  • 抽象:从概念提炼和概念学习中锻炼

    • 简化

    • 关注要素:要的是什么,子模块是什么

    • 隐藏细节

  • 分层:人类世界亦如此演化而来

  • 分治:Divide and Conquer,复杂问题的规模也来自于分形的组合,包括自然界的进化,也可以看作是分形和变异(大量无方向的并行开发试错)的结合。比大量的并行试错反馈环更好的机制,你能找到不?

  • 演化:尤其直面客户的互联网系统,三分设计,七分演化

  • 组织惯例与公共建设:干干净净也是组织惯例建设的一种

设计上的完美并不是没有东西可以加了,而是没东西可以减。

只有简单的体系,才能经得起进化

KISS 放宽到哲学领域就是奥卡姆剃刀

CTO 要求再进一步

  • 深刻的产品意识
  • 量化的技术意识
  • 精细的成本意识
  • 团队管理意识

这是对架构师的一种更高要求,因为纯做技术的人,是做不了CTO的。喜欢做技术且又能把技术做好做深,当然可以一直做技术喜欢技术的同时,又有很好的视野,格局和情商,可以涉足其它领域。

让正确的事情相继发生!

从熵的角度看软件生命周期

没有绝对的静止

  • 软件开发是减少混乱度(熵减)的过程
  • 软件维护是提高混乱度(熵增)的过程,是一个退化到非稳态的过程
  • 现实世界的混乱无序,投射到Cyber宇宙就是不断变换的需求
  • 架构设计如何适应(隔离)改变,是一个架构的关键特征

最熟练的维护工作,也是放缓系统退化到非稳态的过程热力学第二定律(熵增):随时间进行,一个孤立体系中的熵不会减小。

熵的乱炖与惊喜

热力学领域能被宏观观测的物理量非常有限,热量,压力,体积、温度。玩来玩去,都玩的差不多了,大家就开始务虚,进行理想实验,加减乘除,排列组合,只要单位合适,造出很多概念。一段时间内,统计物理横行,一大堆进行理想实验造出的参数被证实,熵这玩意跟系统的所有状态数是亲戚,且是相当直系的亲戚,log(所有状态数)。因为其统计解释的直观性,所以被推广到很多的领域,在信息论中,也是跨界的神作

信息熵

在数学上,负无穷和正无穷都是极限态,甚至接近一回事。信息熵的正无穷(说法太多,混乱)和负无穷(完全没资料)等同于差不多。

举个例子,资治通鉴记周朝某年,赵伐魏。

  • 这么一条消息,你编外星人在齐国横行霸道抢掠民女都没关系
  • 鲁国天天吃喝玩乐,花花世界,事情太多,版本多多,算了,不记也罢。

修习篇

重构

  • 丢弃代码中的坏味道,做到干干净净
  • 重构的第一步就是建立一个有效的测试机制,好的测试机制可帮助重构
  • 不仅代码要重构,文档一样要鲜活和进化跟上

设计模式

  • OO流行起来后,解决特定问题(创建型,结构型,行为型)较好的编程实践总结。OO之前,大家用宏也耍的飞起。目标是低耦合的情况下隔离变化。
    • OO使得封装理解起来更自然;继承使得关系看起来更自然;
    • 多态真正提供了应对变化的最强大能力
  • 它是一个 95 后(诞生于 1995 年)。与其同年的事物:Java和Javascript诞生,win95发布(干倒中文Dos系统),九五计划提出,64k专线接入美国,镭射录像厅爆发,PC躺在要脱鞋进入的空调间,新世纪福音战士播出,京九铁路全线贯通,提出计划经济往市场经济根本转变,粗放型向集约型转变。
    • Java一直在浪潮里,Applet,JavaEE, Android。语法进步缓慢,但Java平台生态非常好。且在大型软件所需的要素:确定的理念,强依赖管理,整洁的接口,抽象化,优秀的文档工具方面表现突出
  • 设计模式在国内开始有讨论,差不多在02年。为啥,加入世贸,国内还要用IT武装自己提升效率。当时国内的开发理念与国外有8-10年的差距,IT化水平差距更大
    • 好在我国人多码农多,追赶的特别快,除去基础能力,在互联网界的应用追赶到差不多只有一年差距的,部分超级应用已经赶超西方。
    • web开发当前疯狂攻城略地的时候,设计模式又没有那么热火朝天了

领域设计模式

  • 对特定领域问题进行抽象挖掘,形成解决方案套件
  • 积累领域经验

独孤四剑

  • partition everything:how do you eat an elephant
  • async everywhere : good things comes to those who wait
  • automate everything
  • remember everything fails: be prepared

精进:持续学习

  • 领域太过专业化,一段时间后,可能会发现自己的专业已经陈旧了
  • 除了把工作中用到的技术掌握好,还应学习其它的语言和平台
  • 至少要掌握两门以上的编程语言,才能相互印证,融汇贯通(现在单一编程语言几乎干不成任何事)
  • 追求卓越,让事情变得更好,而不是追求完美

生活的召唤,永远是我们前进中最好的原动力

视野扩宽非常有必要。每天就面对那么几个人,经理就是监工,客户就是傻叉,每个角色都被自己设定好了,就把自己的范围设窄了,这就不好突破了

结合自己的学习风格

弄清楚自己属于哪一类,与自己的学习风格配套努力,才能得到好的更好的效果

结语

泰山不拒细壤,故能成其高

江河不拒细流,故能成其深