zoukankan      html  css  js  c++  java
  • 编程杂谈:从人类与软件系统的根本矛盾说起

    在纷繁复杂的概念满天飞舞的软件编程领域,希望能分享自己整理的一些观点,帮助大家穿透迷雾,看清问题以及解决方案的本质。

    人类认知能力上限

    有一个说法:人的短时记忆广度平均数为7,即大多数人一次最多只能记忆7个独立的块(Magic number 7)。

    有另外一个说法:当需要根据短时记忆进行信息加工时,一个成年人能处理的块的个数是4左右(Working memory)。

    这些说法不一定完全正确,但我们可以肯定的是,人类处理信息、加工信息的能力是有上限的。

    软件系统的复杂性

    然而要完成一个有实际意义的软件业务系统,绝对不是处理4个变量或者7个变量就能完成的,完整的业务其所需处理的数据要大几个量级。

    由此软件系统的复杂性与人类认知能力存在上限形成了一个矛盾。当复杂度超过人类可控制的范围时,我们就可以认为其失控了。

    我们要怎么避免软件系统失控?或者说如何正确可控地完成一个软件系统呢?大家可以先思考10秒。

    既然矛盾是两个方面的事情,那解决矛盾也可以从两个方面入手:

    • 一个是分而治之,将问题分解成人类可控的范围大小

    • 一个是从软件复杂度方面出发,控制总体复杂度

    分而治之

    要进行分治的话,有也两个问题要解决

    • 按什么逻辑分组

    • 每个问题的规模大小

    对于第一个问题的答案就是我们经常听到的

    高内聚,低耦合

    上述指导原则,能让紧密耦合的逻辑、数据归集到一起,能更少牵制(接口、协议)地进行内部演进。

    而存在的 接口、协议 能让我们可以以更高维度的抽象来组织我们的逻辑。

    就像我们组装电脑时,只要主板与CPU、硬盘、显卡等等的接口协议确定了,那么主板就可以不管各类组件的具体品牌,型号地组织不同部件的工作,而各个组件都可以在接口的控制下各自独立改进。

    对于第二个问题,则是:

    子问题规模应为单个人认知极限规模的70%左右

    如上图,问题可以分解成不同的层级。上图把问题及解决方案分解成了3层,核心问题、子问题、孙问题。

    之所以有层级的存在,是因为子问题的解若数量太多的话,一个人也是无法整合处理的,因此要处理的子问题解数量必须在一个人的可控范围内。但数量控制了,子问题的规模可能很大,并非一个人能求得,因此需要继续划分孙问题。

    从上一段的文字我们也可以得出一个结论,子问题并非越小越好,而是尽可能的大,如此才能减少问题的层级,也减少了整合子问题而产生的消耗(也就是说微服务不是越小越好),而问题规模为个人处理极限的70%则是为了应对后续变化,需要预留一定的buffer。

    总体复杂度控制

    总体复杂度存在一个极限最小值,其由问题域的本质复杂度决定。

    然而我们的解决方案会在本质复杂度的基础上,有意无意地引入其他很多额外的复杂度:

    • 由于人类认知极限而进行子问题分解、整合而产生的复杂度

    • 由于未透彻理解问题本质而引入的额外复杂度,如错误的设计而形成畸形的、绕了远路的解决方案

    • 由于错误判断问题的演化方向而引入了额外的复杂度,这个可以理解为过度设计

    • 由于一些问题域外的其他需求引入的额外复杂度,如为了监控、排查问题等等而引入的复杂度

    • 由于代码腐化导致的复杂度,如复制代码块,补丁式代码等等

    • 由于性能问题引入的复杂度

    • ......

    可以说,引入复杂度的原因有千万种。而我们能做的,只有一件事情——每次引入复杂度时都认真思考其是否必要,是否利大于弊。

    然而我们不能指望于每个人都有能力以及觉悟去审视这个问题,因此自上而下的设计以及监督是必须的,否则代码的整体复杂度就会不断提升,与热力学第二定律有点类似

    孤立系统的熵(混乱程度)永不自动减少,熵在可逆过程中不变,在不可逆过程中增加。

    一个良好设计的系统,在后续没有经过上层设计以及监督(外部系统做功)的软件系统的混乱程度会不断增加,直到系统的混乱程度变得与编码的程序员思维混乱程度一致(当然或许编码程序员的思维并不混乱,对代码也有自己的要求,这样系统或许会不再腐化,甚至进化,但我们没办法做到每个程序员都有这样的水平)。

    小结

    本文的内容只是写好代码的序章,但由于规模引起的问题最终解决方向都会落到上面提到的 分而治之 以及 总体复杂度控制 上,这个是根源。

    分而治之及总量控制不仅仅能在软件领域上应用,我们可以从 公司人事组织架构、天体系统研究等等方面都可以看到应用。

    后续文章我会尝试在上面两个方向上继续细化,将 封装、抽象、多态、分层、DDD 等等思想 以及 面向对象语言、微服务、中台等等外功 关联起来。

    若本文能给你带来帮助,请点击右下角在看,若本文存在谬误,请帮忙批评斧正,谢谢!

     

    作者简介

    多年金融行业经验,现为某Top2互联网银行高级搬砖工,曾在两家TOP3股份制商业银行及一家互金创业公司工作(架构、核心业务主程),EasyTransaction作者,欢迎关注个人公众号,在这里我会分享日常工作、生活中对于架构、编码和业务的思考

     

  • 相关阅读:
    react-native运行iOS真机、模拟器命令
    如何在RN插件iOS部分添加framework文件
    fatal error: module map file '/Users/z/Library/Developer/Xcode/DerivedData/sometest-cnjreghvqrsixrehofwrnercfpei/Build/Products/Debug-iphoneos/YogaKit/YogaKit.modulemap' not found 1 error generated.
    ERROR | attributes: Missing required attribute `homepage`.
    数据交互一
    JSP__第1章 动态网页开发基础
    第9章 表单校验
    第8章 使用JQuery操作DOM
    第7章 jQuery中的事件与动画
    第6章 jQuery选择器
  • 原文地址:https://www.cnblogs.com/skyesx/p/11262013.html
Copyright © 2011-2022 走看看