精华内容
下载资源
问答
  • Python金融数据分析入门到实战

    万人学习 2019-09-26 17:08:33
    由股票数据的获取、技术指标的实现,逐步进阶到策略的设计和回测,由浅入深、由技术到思维地为同学们讲解Python金融数据分析在股票量化交易中的应用。 以Python为编程语言 解锁3大主流数据分析工具 Python做金融具有...
  • PHP深入理解-PHP架构布局

    万次阅读 多人点赞 2018-12-16 15:40:10
    PHP内核的深入理解有助于我们PHP的整体认识,对于业务层初期发展我们可以只了解基本语言的逻辑就可以写出符合业务的代码,但是随着业务的发展我们通过分析源码,编写扩展,深入了解PHP内部机制,帮助我们理解PHP内部...

    本文基于《PHP 内核剖析》与 《PHP7底层设计与源码实现》所记笔记。
    对PHP内核的深入理解有助于我们对PHP的整体认识,对于业务层初期发展我们可以只了解基本语言的逻辑就可以写出符合业务的代码,但是随着业务的发展我们通过分析源码,编写扩展,深入了解PHP内部机制,帮助我们理解PHP内部实现逻辑,更好助力业务发展.

    执行流程

    解析为Token
    将语法转换为抽象语法树
    将语法树转换Opcodes
    Scanning
    Parsing
    Compilation
    Excution:执行Opcodes

    从上图中看出主要从解析PHPCode到执行主要经过了四个阶段.

    获取token可以通过Token_get_all('<?php echo "str";>')函数获取token信息.

    抽象语法树主要将解释器和编译器进行解耦.

    opcodes最终执行的指令,例如ZEND_ECHO:本质还是一个对应的C函数.

    架构结构

    PHP架构图
    Zend层为上层的PHP层提供一些基础的内存管理以及数据结构等.

    SAPI层为最上层和Server进行通信,封装了不同的通信类型,cgi,fast-cgi,cli等.

    目录结构

    sapi

    存放根据不同环境支持的上层API交互形式,实现了不同的输入输出形式.

    Zend

    存放PHP相关的核心代码,如前所述内存管理等.

    main

    负责与Zend层交互的入口,还有一些钩子函数.

    ext

    主要是扩展相关的目录.通过ext_skel命令生成自定的模块.会默认安装到这个目录.

    TSRM

    线程资源管理相关的目录,一般只有和Apache结合使用时会涉及到线程资源管理相关的代码.
    与Nginx相关的一般只会用到FastCGI协议不涉及到TSRM模块.

    展开全文
  • 架构设计本质

    千次阅读 2020-10-12 15:45:24
    简介:实际上架构只是系统设计里面的一个重要环节,除了架构还包含了商业诉求,业务建模,系统分析,系统设计等重要...架构设计本质是什么? 如何进行架构设计? 如何进行业务领域建模? 模型如何推导出架构设计? 架
    简介:实际上架构只是系统设计里面的一个重要环节,除了架构还包含了商业诉求,业务建模,系统分析,系统设计等重要领域。本文尝试从更高视角重新审视架构设计的工作,把架构设计的上升到系统设计的立体空间去探索,最终勾勒出系统设计的全域知识体系。

    1006头图.png

    作者 | 编程原理林振华

    【问题】

    • 什么是系统设计,系统设计的核心是什么?
    • 如何训练系统设计的思维模式?
    • 有什么方法来帮助我们理解复杂的系统?
    • 如何进行系统分析?
    • 架构设计的本质是什么?
    • 如何进行架构设计?
    • 如何进行业务领域建模?
    • 模型如何推导出架构设计?
    • 架构设计需要遵循哪些规范?

    【关键词】

    系统思维,系统分析,系统设计,架构元素,架构视图,架构模型,业务模型,概念模型,系统模型,分析模型,设计模型,用例驱动,领域驱动,物件,功能,物件结构,功能交互,利益,架构工具,决策选择,架构师,架构图

    全文概要

    软件从业人员的成长路线大体是在管理线和技术线上形成突破,当然也有结合起来相得益彰的。而技术上的追求,架构师则是一个重要的门槛,对于刚入行的程序员可能会认为架构师就是画架构图的,诚然架构师很重要的一个职责是绘制架构图,但这只是其中一个很小的环节而已。

    实际上架构也只是系统设计里面的一个重要环节,除了架构还包含了商业诉求,业务建模,系统分析,系统设计等重要领域。本文尝试从更高视角重新审视架构设计的工作,把架构设计的上升到系统设计的立体空间去探索,最终勾勒出系统设计的全域知识体系。

    思维分析

    1. 系统总览

    人类社会活动中的不管大大小小的,简单抑或复杂的事物,总要先出现在我们的脑海里,然后再投射到现实的物理空间来。我们总是在孜孜不倦地追求美好的事物,但现实存在的问题就是,首先我们的脑袋也理解不了太过复杂的东西,其次脑海里的想象有时候也很难真实无损的映射成现实的系统,再者由于总是资源有限的,我们并没有花不完的预算。

    归结起来设计一个系统,或者朴素的说,做一件事情,我们需要解决以下问题:

    1.jpg

    在解决以上提出的问题前,首先声明我们要实现的是一个系统,而不是随意混搭的一件物品,毕竟现在讨论的不是行为艺术。那么就需要先来了解系统的定义:

    系统是由一组实体和实体之间关系构成的集合,其功能大于各个实体功能之和。

    系统可以分为自然系统和人工系统,但是本文特指需要人类参与的人工系统。

    自然系统

    • 人体系统
    • 生态系统
    • 大气系统
    • 水源系统

    人工系统

    • 机械系统
    • 电子系统
    • 操作系统
    • 社会系统

    2. 系统演化

    上面谈到在系统设计流程主要是使用了分析思维和系统思维的结合,当然人类思维还有其他的运作模式,比如批判思维,创新思维和发散思维等,以此衍生的又是另外一套截然不同的方法论。下面我们主要分析系统设计过程中的思维活动。

    通常谈起架构师就会联想到各式各样的架构图,谈架构图就要搞清楚什么是架构设计,那么架构设计之前是什么呢?架构设计是整个系统建设的核心环节,犹如设计图纸之于建筑那么重要,那架构设计之上应该就是系统设计了。先搞清楚系统设计的定义:

    系统设计是根据系统分析的结果,运用系统科学的思想和方法,设计出能最大限度满足所要求的目标系统的过程。

    1)业务描述

    上节弄清楚系统的概念,也就是先把边界框定下来,那么我们要实现的无非就是以上类别的系统。自然系统是天然形成的,或者你愿意的话也可以认为是盘古开天辟地形成的,那也可以归为人为系统。我这么说的原因是尝试把视角从软件这个领域往更加宏观的方向提升,让我们暂时忘掉软件架构师这一根深蒂固的角色。

    假设现在我们想登上火星,言下之意是需要借助一套设备要把人类送到火星上,大胆一点,发挥仅存那点为数不多的物理知识储备,要设计出一套系统,能够把人类送到火星。这个时候老板就是愿意出资去火星豪华 7 日游的金主,那么需要一个负责人来实现这趟旅程,我们姑且把这个负责人就称为登火旅行系统架构师(叫总设计师也行,不需要在意这种细节)。那么这个系统架构师的工作,就是把登陆火星的一系列需求和目标转化成为足于支撑登陆火星庞大工程的系统架构。

    根据系统总览提到的问题,先一一作答。

    2.jpg

    由于人命关天,这项工作看起来是挺复杂的,初次接到这个单子时我内心是彷徨的。但是回答了以上问题后,感觉明朗了不少,我们在完成系统性质,受众,利益和目标的分析和解答后,才能进入到系统的架构阶段。

    首先对以上提到的需求,我们先用动画片里面的简单画面为基础来描绘我们的设计,然后大致根据能想到的过程完成初次业务流程的描述。

    业务流程画图元素:火箭,机舱,地球,火星,来回,基础功能(安全,舒适,成本)

    3.png

    通过以上的描述,基本涵盖了火星旅程的四个阶段:登机,航行,下机游玩,返程,这本质上跟我们平时搭个飞的去趟浪漫的土耳其也是差不多的。而在此之前我们脑海里可能还是一片混沌,沉溺在登陆火星这项浩瀚的工程而不知道从而入手。

    从混沌到开始有点头绪,其实无形中已经完成了一次建模,我们称为业务建模。翻回去查阅系统总览的表格,其实我们已经把需求这个维度大致列举出来了,把登陆火星的几大领域给分离开来了。那么接下来就是要把登陆火星这个项目的主线给说明清楚。

    2)概念抽象

    怎样把这件事的主线说明清楚?滔滔不绝的把一件事情讲完其实反而是很难讲明白,除非这件事情本身足够非常简单的。那么就需要抓重点的来说,这个时候就需要一个叫做“概念”的工具。

    概念是抽象的、普遍的想法,是充当指明实体、事件或关系的范畴或类的实体。

    简单来说,概念就是用简单的一个词汇,就可以让在坐的大家都能准确无误的理解这个词汇所表达的含义。这个是语言独特的魅力,可以说有个概念这个武器,才有了人类多次工业革命的文明大爆发。有了“概念”这个工具,再对概念进行组合,会爆发出无穷的生产力。

    这里穿插讲一下概念的应用,比“傅立叶级数”这个概念,我敢打赌有 80% 的人不知道所谓何物,但是没关系,我们并不是要来科普这个概念,先根据百度百科来看看这个概念的描述:

    4.jpg

    先不要怕,我这么说的目的不是为了让大家搞懂什么是傅立叶级数,这里我们可以看出即使这么鬼畜概念也是很普通的基础概念元素组成的,比如收敛公式,比如三角函数,比如 Σ 求和概念,甚至像 1,2,3 这些阿拉伯数字。这里不得不说学数学最核心的环节就是深刻理解概念,没有之一。

    说回来,这里的语境就是在大家都共同理解接受这些基础概念后,经过一系列复杂组合的高级概念,也依然能够清晰严谨的表达出来,下面傅里叶级数的产生过程的动图看看就好。

    5.gif

    好了,现在我们知道了概念这个工具的重要性和功能,前面我们已经列举了登陆火星要做的事情,那么现在就需要精确简洁的把这件事给说清楚了,这个是个困难的任务,因为如果主线没有梳理清晰,后面整个工程将万劫不复。

    在业务建模后就是概念建模,作为架构设计的输入,这个阶段就需要对核心业务的充分理解,同时在基础性和通用性方面的功能也需要同时考虑,这个阶段需要大量的业务专家和各个领域的科学家通力协作,保证对系统的理解没有偏差。经过一系列的概念抽象和组合,最终输出登陆火星工程的架构图,这里只是用于说明登陆火星项目同样遵循这业务-概念-架构-设计的流程,不要在意架构图本身合不合理。

    6.png

    3)系统落地

    当然这还远远不够,系统之所以复杂,就是我们对系统总有无数更多的要求,更多的功能,更好的性能,那么接下来就是对各个模块进行分析,细化,设计和实施。当然我们不会班门弄斧真的在这里去分析登陆火星的实际流程,以上这个例子虽然比较粗旷,但是基本也描绘了一个复杂系统建设的过程,也就是从需求,建模到架构的思维过程,是从最原始的登火需求一步步扩展的过程。

    其实我们还可以举个小一点的案例,比如一个有趣的需求“赚钱”,引申出来就是做一个能盈利商业项目架构,有兴趣的同学可以根据这个思维模式一步一步勾画出整个流程出来,相信这也是一个不错的方法,也许还真能解决些许困惑。下面演示的就是登月过程宏观层面落地的步骤。

    7.png

    3. 架构思维

    1)架构目标

    一直以来我听过很多人在讲架构,有些人在做架构,但是很难讨论出一个大家都满意的定义,什么是架构师,架构师需要做哪些工作?或者说很少有往深的去思考,只知道被称为架构师说明这个人很厉害。在我毕业的时候有个同学打趣的跟我说,你们做程序的无非就是增删改查,当时我竟无言以对,当时脑海里浮现的是一系列工具的应用技巧,比如 tomcat,nginx 的使用,还有对业务的翻译。

    随着对业务的贴近和对计算机技术的进一步认识,我重新审视“这世上的系统无非就是增删改查”,这句话说对也对也不对,这句话就跟计算机软件无非就是 0 和 1 的集合,也对也不对。特别是对刚入行的人可能觉得设计离自己比较远,因为习惯了打开 idea 才开始考虑业务,写代码才开始思考领域模型,这是非常不好的习惯,好像如果没有在 coding 状态下是无法进行建模思考,这个很难,需要持久的训练才能达成设计阶段进行思考。

    架构设计只是系统设计里面的一个阶段,而系统设计是应用建设里面的核心环节,有一些简单的应用建设是不需要系统设计的,当然有一些复杂的应用,在能力超强的工程师团队,有足够的默契后,也可以直接进行建设。

    软件架构之道最核心的问题是解决复杂性的问题,并且在解决问题的过程中找到最佳的平衡点,既要简单又能满足发展。描述系统设计的本质,就是实现纵向上的时间,横向上的空间进行考虑,规划出决策路径,最终拿到目标结果。

    架构师眼里第一件事不是多流行的技术,多高性能的框架,或者多完善的业务模型,而应该聚焦在利益之上。对,这个可能会颠覆一些认知,当我们真正把利益放在首位后,再去考虑接下来要完成的事情,我们的工作才能称得上架构。也就是说,架构师的天职就是最大限度地实现客户的利益,这里的客户可以是市场客户,也可以是协作团队,还可以是同一个团队的项目成员。

    再直白的说,架构师就是负责把老板画的饼给实现了,在相当长的一段时间内保证产物有足够的利益回报。有人会说那我们做的就是公益项目,就不考虑利益,我补充一下,这里说的利益不止是经济收益,还有系统带来的社会价值。那么又有人会说,架构是追求利益回报,那老板的目标就是炒股发大财,请架构师你给我选几支股票吧,那我会说其实优秀的基金经理也可以称为广义上的架构师。

    2)架构过程

    自然在增熵,而系统架构过程其实就是减熵的过程,一个架构的诞生始于目标的确立,然后是对需求的刻画,继而是落地方法的抉择。

    所谓条条大路通罗马,有的是一路平川而有的则是崎岖不平,那么架构过程就是不断归类合并同类项,力求最合适的决策选择来实现我们所要达成的愿望。在面对复杂业务的场景下,我们需要做出如下的思考:

    • 确定系统实体对象和预期功能
    • 抽象系统实体之间的关系,功能与实体的关系
    • 划定系统的边界和外部环境的关系
    • 预测系统带来的效果

    在架构过程中,很重要的一项任务就是识别系统的实体关系和功能关系,进而对系统效果进行预测,也就是在完成一系列的分析建模工作后推导出来的系统架构需要在预测上达到我们要的效果,那么系统预测通常有如下四种方式:

    • 经验
    • 实验
    • 建模
    • 推理

    3)系统思维

    系统思维不等于系统化思考,与系统思维并列的可以是批判思维,分析思维,创新思维,而我们追求的是元认知,也即是认识到自己处于何种思维模式。系统思维目标:

    • 理解系统是什么
    • 预测系统的走向
    • 为决策提供知识支持

    系统思维首先是高效地理解分析现存的系统,对系统重构做好理论指导基础。

    这一节介绍了设计一个系统需要经历哪些重要的环节,并且强调了谋求利益是系统设计的核心诉求。然后通过登陆火星这项任务把一个庞大的工程变成了可理解的独立步骤,并且还有模有样的画出了架构图,体现了对业务建模到架构输出的流程。下面章节我们将会展开来介绍一套核心的方法论,如何破局系统架构设计。

    系统分析

    上一节谈论了系统设计的心智模型和投射到物理世界的演化规律,但前提是建立在已经具备丰富系统设计经验基础上。而在进行系统架构之前,需要先对系统分析有一定的理解,好比我们制造发动机之前,得先把发动机拆下来好好研究一番,直接上来就要设计出发动机有点像空中楼阁。

    本节将提供一套基础的方法,来对现有系统进行分析,得出一些系统架构相关的推论。按照惯例需要先搞清楚系统分析的概念:

    系统分析,旨在研究特定系统结构中各部分的相互作用,系统的对外接口与界面,以及该系统整体的行为、功能和局限,从而为系统未来的变迁与有关决策提供参考和依据。系统分析的经常目标之一,在于改善决策过程及系统性能,以期达到系统的整体最优。

    大到银河系,小至原子粒子都有着特有的结构,何谓结构:

    结构是指在一个系统或者材料之中,互相关联的元素的排列、组织关系。

    而系统在物质世界里面当然也遵循这样的规则,分析系统跟分析银河系也一样,需要对它的组成元素和元素之间的关系进行分析。而对系统的分解也是讲究方法的,可以参考以下总结的一些方向:

    • 体系归纳
    • 层级分解
    • 逻辑关系
    • 自顶向下
    • 自底向上
    • 由外向内
    • 由内而外

    1. 实体分析

    实体指系统物理时空存在的单元,彼此通过一定的结构形成系统,那么在分析实体之前,我们可以带着下面的问题进行分析:

    • 系统是什么?
    • 构成系统的元素有哪些?
    • 系统元素之间的结构是什么?
    • 系统的边界在哪里?
    • 系统的使用场景是什么?

    实体是系统的一项基础属性,是系统的物理体现或信息体现。对功能的执行起工具性作用,而描述实体通常可以使用以下工具来表达:

    • 文字描述
    • 符号描述
    • 插图
    • 插画
    • 示意图
    • 三维图
    • 透视图

    实体之间的关系就是结构,分析结构时需要对实体进行分解,实体可以建模为对象及其之间的结构,进一步可以分解为小的实体,又可以聚合起来称为系统本身,对实体之间的各种结构分析则可以得出系统架构,即是把功能元素组合成物理块时所用的编排方式。

    1)分析实体

    • 对实体的载体进行抽象聚类,形成对象,体现出边界
    • 用适当的层次来分解架构的实体

    2)分析关系

    即是实体的结构,是对象之间存在稳定关系,有助于功能交互的执行系统实体有如下关系:

    • 空间拓扑关系
    • 连接性关系
    • 地址关系
    • 顺序关系
    • 成员关系
    • 所有权关系
    • 人际关系

    2. 功能分析

    上面一节我们了解了系统的物理基础,对组成系统的实体进行分解,分析,进而对实体的关系描述为结构,结构抽象是得出架构的基础步骤,而系统物理基础存在的理由是为了实现我们的诉求,也即是系统的功能。毕竟万物皆有因,存在即合理,系统构建最终也是要达成我们的意愿,完成这个诉求才算是合格的架构。分析形式相对来说毕竟简单,毕竟实体是有形的便于理解,而功能则是由实体组合涌现出来的属性,功能分析过程需要跟实体不断的交互穿插。

    关于系统功能其实可以朴素的认为就是动宾短语的集合,功能=动词+宾语,含义就是实体状态变化的过程,就是功能的体现,具体分析下文会详细展开。功能 = 主体 + 操作 + 操作对象,比如嘴巴有“吃饭”功能,飞机有“搭载乘客”功能,报表平台有“展示报表”功能。

    • 操作:对象经历的一种转换模式,过程设计操作数的状态变化;
    • 操作对象:操作数是一个对象,在某段时间内稳定且无条件存在,操作数不需要先于功能的执行而存在,操作数可能会由功能中的过程部分来创建,修改或消耗。

    总结起来,系统分析就是建立一套方法论,去分析复杂的系统,令系统不再那么难懂。

    系统设计

    经过了上几节的思维训练和系统逆向分析,我们也大概理解了系统设计的流程和系统架构的形成过程,本节将介绍系统设计,包括设计工具,需求分析,模型建立,架构推导,设计规范完整的系统设计流程。

    系统设计,即设计出一套良好的系统架构,就是构建一套具备必要复杂度又不难懂的系统。下面在介绍方法论的同时,同时会穿插一个数据平台的大致设计过程

    在进入本章节系统设计前,我们先要来学习学习一个架构 TOGAF:

    TOGAF:框架开放组体系结构框架(The Open Group Architecture Framework,缩写:TOGAF)是一个企业架构框架,它提供了一种设计,规划,实施和管理企业信息技术架构的方法。TOGAF 是一种高层设计方法。它通常被建模为四个级别:业务,应用程序,数据,和技术。

    在 TOGAF 中,任何一种企业能力的建设都需要对如下四种领域进行设计,包括针对这一可持续性架构实践建设:

    • 业务架构:突出了架构治理、架构流程、架构组织结构、架构信息需求以及架构产品等方面;
    • 数据架构:定义了组织中架构连续体和架构资源库的结构;
    • 应用架构:描述了用于支持此可持续架构实践的功能和服务;
    • 技术架构:描述了架构实践中用于支持各架构应用和企业连续体的基础设施需求和部署方式。

    TOGAF 架构框架是一组工具,可用于开发各种不同的架构:

    • 描述了一种用于根据一组构建块来定义信息系统的方法
    • 展示构建块如何组合在一起
    • 包含一组工具
    • 提供共同的词汇集合
    • 包括推荐标准列表
    • 包括可用于实现构建块的兼容产品列表

    企业可以通过应用企业架构开发方法(ADM)来建设各种业务能力,下面我们再来介绍另外一种系统设计的思路。

    1. 设计工具

    工欲善其事,必先利其器。前文讲到思维分析,不同思维模式决定不同的方法论,那么在分析思维层面,人类大脑其实很难理解太过复杂的东西,这个时候就需要借助一些工具来协助思维的活动。

    首先第一工具当然是语言,这个不用多说,没有语言作为基础将寸步难行,单个体的时候语言用于描述系统的诉求,而多个体的时候语言则扮演着沟通的角色,但是如果语言不互通的话可能就像鸡同鸭讲。即使是同一种语言,不同的表述都会形成很大的偏差,那么就需要一种普遍认可的统一语言,在系统分析审计领域,我们首推统一建模语言(英语:Unified Modeling Language,缩写 UML),当然还有其他比如 SYSML 或者 OPM,下面我们先大致介绍下 UML,列出 UML 的核心语言元素,视图,模型和过程。

    1)核心元素

    • 参与者
    • 用例
    • 边界
    • 业务实体
    • 分析类
    • 设计类
    • 关系
    • 组件
    • 节点

    2)核心视图

    静态图包括:

    • 用例图
    • 类图
    • 包图

    动态图包括:

    • 活动图
    • 状态图
    • 时序图
    • 协作图
    • 泳道图

    3)核心模型

    • 业务用例模型
    • 概念用例模型
    • 系统用例模型
    • 业务领域模型
    • 系统分析模型
    • 系统设计模型
    • 系统组件模型

    4)核心流程

    • 业务建模
    • 系统建模
    • 模型分析
    • 模型实施

    5)软件工具

    • draw.io
    • StarUML
    • Visual Paradigm

    2. 需求分析

    本节不打算讲需求分析师的工作流程,因为我们已经很熟悉需求分析师对需求的分析过程了,所以无需多言,在讲需求之前我们先来看看架构师需要完成的工作。

    架构师并不是全能的通才,无法了解所有细致的需求,所以架构师要做的就是简化系统的复杂度,消除业务歧义,致力于输出健壮兼容的系统架构。由于系统需求分析需要由架构师这个角色全程参与,深度理解业务,下面我们简单对架构师角色进行讨论。

    1)架构角色

    我们先看看传统系统设计两大核心角色的定义:

    系统架构师:是在信息系统研发中,负责依据需求来确定主要的技术选择、设计系统的主体框架结构,并负责搭建实施的人。

    系统分析师:是在信息系统研发中,负责通过需求分析确认系统的需求,并进而形成系统产品设计的人。通常他们也会涉及可行性评估、项目管理、开发前评估、需求验证等工作。

    传统意义的系统开发分为系统架构师和系统分析师两个角色,但是随着互联网的快速发展,如今系统建设越来越趋向于将两个角色结合起来,那么互联网时代架构师有如下职责:

    • 了解问题领域,消除歧义
    • 树立业务目标,抽象业务用例
    • 完成涉众分析,发现系统主要受益者
    • 划清系统边界,确立对外交互方式
    • 划分优先级别,聚焦系统核心诉求
    • 分析业务需求,输出业务模型
    • 抽象业务概念,输出概念模型
    • 推导系统架构,输出架构模型
    • 负责技术选型,完成系统落地

    架构师是软件开发活动中的众多角色之一,它可能是一个人、一个小组,也可能是一个团队,我们分析的是架构师这个角色,能胜任这个角色的才是架构师,那么在这个角色上能做得更加出色的就是好的架构师。

    以上架构师职责是整体上的描述,在细分领域有不同的分类。微软对架构师有一个分类参考,我们参考一下,他们把架构师分为 4 种:

    • 企业架构师 EA(Enterprise Architect)
    • 基础结构架构师 IA(Infrastructure Architect)
    • 特定技术架构 TSA(Technology-Specific Architect)
    • 解决方案架构师 SA (Solution Architect)

    既然对架构师角色有诸多要求,那么也可以来归纳一下架构师必备的一些技能,能力模型可以参考《职业成长的逻辑模型》一文中对能力模型的描述,架构师能力要求:

    • 现有资源评估盘点及资源编排能力
    • 消除歧义分清问题主次能力
    • 业务简化描述,用例抽象思维
    • 通用市场法务市场领域基础常识
    • 业务分析架构推导能力
    • 计算机基础理论知识体系
    • 通用技术栈原理认知
    • 工具使用熟练,排查定位问题能力
    • 技术深度广度
    • 分布式高并发性能调优技能
    • 产品思维

    2)利益分析

    首先当然是要确立好客户,所谓客户第一,听起来很简单,如果只是单一的服务好客户,那确实不算很难。难的是如果同时存在多个业务方向的客户,而且客户直接的利益产生交集,而且存在矛盾,怎么权衡好利益分配,区分客户利益优先级,才是困难的。

    8.png

    不忘初心这一点尤为难得,很多项目做着做着就偏离了当初的目标,这个过程我们一定要紧紧抓住系统最重要的受益者,梳理好系统众多涉众的利益分配。

    3)资源评估

    资源评估不仅仅是项目经理的事,而且还是对团队资源的评估和编排,比如某项业务技术团队中研发和数据人员的配比,决定了数据平台投入的资源范围,这要求架构师在做设计分析的时候需要充分考虑到资源的利用效率,包括人力资源和机器等资源。

    4)需求规范

    用户的诉求体现为需求的输出过程,不同层次分解需求得出了不同的复杂度,我们知道架构师的一项重要职责就是消除歧义,精准的把握需求来匹配用户的诉求。那么就需要一系列规范来保障需求采集的过程中不失真。

    下面列出了需求采集过程的一些指导原则:

    • 每个软件需求是否都有唯一的标识符?
    • 每个软件需求都可以验证吗?(如果可能,是否可正规化,量化)
    • 是否对每个软件要求进行了优先排序?
    • 所有不稳定的软件要求是否都已标明?
    • 软件需求是否完整?(涵盖了所有用户要求,考虑了所有相关的输入情况)
    • 软件要求是否一致?
    • 是否明确指出了软件需求之间的重叠交叉?
    • 是否明确规定了初始系统状态?
    • 软件需求是否表达了逻辑模型, 而不是实现形式?
    • 软件需求是否以结构化的方式表示为抽象层次?
    • 是否足够清楚,逻辑模型的结构
    • 软件要求是否已正式形式化?
    • 是否已证明软件需求的关键属性?
    • 所有形式化的图表材料是否都随附了充足解释性文字?
    • 是否针对项目团队缺乏经验的领域描述了探索性原型?

    5)需求描述

    在进行需求描述时,我们可以从多个角度来审视需求是否合理地表达出来:

    • 满足需求,能带来什么价值,符合什么利益诉求?
    • 需求无法满足时,会带来什么危害,有何潜在风险?
    • 需求是否紧迫,必须在什么时间段内完成?
    • 多个需求直接是否产生耦合,完成一个需求后是否带来了新的问题?
    • 是否能多个备选方案来完成需求?

    6)需求采集

    回到我们平台设计的案例上,经过用户访谈粗略的采集的需求:

    • 单项业务壁垒是个困局,本质上是功能缺陷,打通数据壁垒
    • 业务各个阶段的数据管理,要对数据底层进行管理
    • 需要对由相同特性的报表实现快捷地生成

    需求背后:

    • 可以一次性看更多的数据
    • 可以方便的切换数据
    • 可以更快的看到数据

    so,这个真的是客户想要的吗?整体上,用户想看什么数据?同时我也在思考下面的问题

    • 深入分析用户需求
    • 搞清楚我们的客户是谁?
    • 定义好问题,搞清楚问题的本质,分析问题矛盾之处,我们要解决什么问题?
    • 我们要在多大范围内去解决问题,要解决跨度多长时间可预计的问题?
    • 我们的边界在哪里?
    • 我们的使命是什么?有了使命后再谈我们自己,愿景是什么?

    3. 模型建立

    在系统设计这个阶段,我们已经介绍了如何运用工具,还有用户需求的管理,接下来就是要把需求“消化”成我们需要的架构。但是架构不是平白无故就产生的,前文我们用登陆火星的案例也大概描述了系统的建设过程,那么在推导出架构之前,把用户不那么清晰的诉求转化成严谨的业务概念模型就很有必要了。

    1)模型基础

    首先我们要搞清楚模型相关的概念:

    模型:是指用一个较为简单的东西来代表另一个东西。

    科学模型:是科学研究中对一类研究方法的通称,使用数学公式、电脑模拟或简单的图示来表示一个简化的自然界,透过分析这个模型,以期能够进一步了解科学,包括说明、验证假说、或分析资料。

    概念模型:是用一组概念来描述一个系统,或用任何代替的形式来描述一个概念,以期能进一步了解或说明事物的运作原理。具体的形式可能包括思想实验、数学模型、电脑模拟、示意图、比例模型等。

    业务建模:是以软件模型方式描述企业管理和业务所涉及的对象和要素、以及它们的属性、行为和彼此关系,业务建模强调以体系的方式来理解、设计和构架企业信息系统。

    2)建模目标

    即是说业务建模是一种建模方法的集合,目的是对业务进行建模。这方面的工作包括了对业务流程建模,对业务组织建模,改进业务流程,领域建模等方面。针对复杂难懂的系统,我们构造出一个比较简单的模型,来代表复杂的业务,这个是一种有效的办法,这也是我们需要建模的原因,随着计算机的飞速发展,或许以后计算机可以帮人类承当一部分的设计工作,而计算机是不怕复杂业务的,也许那个时候就不再需要这种特地适应人类思考的模型了。

    建立模型不是最终目的,而是把复杂的业务诉求构建成简单的业务概念,在软件开发团队沟通过程中能形成共识,消除歧义,而且信息传递不失真,为输出架构奠定基础

    3)模型分类

    在业务不同的阶段,通常会使用不用的模型来表达,一般情况下我们把模型分为:

    • 业务模型
    • 概念模型
    • 系统模型
    • 分析模型
    • 设计模型
    • 物理模型

    4)建模方法

    建模有很多种方法,对于同样的问题域使用不同的建模手段,得到的模型可能也不尽相同。建模是一种对现实事件的抽象,不同的心智会产生不同的模型,比如宗教,不同宗教就是对人生观世界观产生不同的模型,我们先介绍常用的建模方法:

    • 领域驱动(DDD)
    • 用例驱动(UDD)
    • 四色建模
    • CRC建模
    • CQRS建模

    下面我们以用例驱动和领域驱动为案例来介绍这两种思维方式的建模过程。

    5)用例驱动

    用例驱动是一种由外而内,先招式后内功的思想。我们先从涉众对系统的期望开始,定义出系统如何满足他们的愿望。这一过程是感性的、外在的、符合当前需求的。

    用例驱动的结果是我们的软件是以实现一个个场景为目的的,认为当一个系统的行为满足了所有涉众的期望之后,即满足了涉众使用系统的场景之后,该系统就是一个成功的系统。

    【建立用例】

    用例定义:工具—>过程—>操作数 (主 谓 宾)

    • 参与者:某些具有行为的事物,可以是人,计算机系统或组织;
    • 场景:参与者和系统之间的一系列特定的活动和交互;
    • 用例:一组相关的成功和失败的场景集合,用来描述参与者如何使用系统来实现目标。
    【用例规范】

    用例其实就是对一件独立事情的描述,这非常符合我们人类语言的表达过程,我们日常沟通很大部分是陈述一个观点,那就是以主谓宾的方式来表达,同样的编写用例也可以遵循这个结构。

    【建模过程】
    • 用例模型

    用例:每个用例提供了一个或多个场景,该场景说明了系统是如何和最终用户或其它系统互动,也就是谁可以用系统做什么,从而获得一个明确的业务目标。编写用例时要避免使用技术术语,而应该用最终用户或者领域专家的语言。

    用例模型:用例模型是系统既定功能及系统环境的模型,它可以作为客户和开发人员之间的契约。用例是贯穿整个系统开发的一条主线。同一个用例模型即为需求工作流程的结果,可当作分析设计工作流程以及测试工作流程的输入使用。

    用例有严格的规范,回顾上文系统分析里面,我们对系统功能分析给出一个公式:功能 = 主体 + 操作 + 操作对象。用例也是需要这样的结构,比如“我爱你”是完整的用例,能完整的描述一件事情,而“爱你”则不能称为一个用例。所以用例模型建立阶段就要力求把用户诉求都完整的以用例表达出来。

    • 业务模型

    业务模型:业务模型采用业务用例来绘制,表达业务的观点。

    我们在数据平台对用例模型进行抽象。

    分析师 为客户 制作 业务 报表

    9.png

    抽象起来就是分析师制作报表,这个是我们最朴素的模型,我们以这个最原始最核心的用例为立足点点开始发散。

    • 主语:分析师
    • 状语:客户
    • 谓语:制作
    • 定语:某一项业务
    • 宾语:报表

    经过我们对语言的分析,已经很清晰地呈现出我们的业务模型,就是分析师制作报表,加上状语和定语的修饰,我们知道是为客户这个主体创建的报表,而且是特定领域的报表,状语就是跟分析师强相关的。

    10.png

    • 概念模型

    概念模型:概念模型是一种或多或少的形式化描述,描述的内容包括建立软件组件时,所用到的算法、架构、假设与底层约束。这通常是对实际的简化描述,包括一定程度的抽象,显式或隐式地按照头脑中的确切使用方式进行构建。

    现在我们明确了业务模型后,接着就是细化用户,补充更多的细节:

    • 分析师 为 不同的客户  制作  不同业务的 报表
    • 分析师 为 不同的客户  制作  几款业务的 报表
    • 分析师 为 不同的客户  制作  一项业务不同区域的 报表
    • 两个分析师 为 某个群体用户  制作  业务线的 报表
    • 客户 授权 某个群体  查看  不同业务的 报表

    结合我们对业务的了解,可以丰富领域的属性,还有一个隐性的“权限”名词,我们需要独立出来,因为权限不属于任何一个领域。

    11.png

    通常我们需要角色概念来管理用户访问报表的权限。

    • 管理员 为 不同的客户  创建  一项业务不同区域的 角色
    • 管理员 为 不同的客户  分配  一项业务不同区域的 角色
    • 小二 为不同报表  创建  不同  权限
    • 系统模型

    系统模型:系统模型是一个系统某一方面本质属性的描述,它以某种确定的形式(如文字、符号、图表、实物、数学公式等)提供关于该系统的知识。

    丰富业务场景后,整体的用例如下图:

    • 分析师 为 不同的客户  制作  不同业务的 报表
    • 工程师 为制作 个性  报表
    • 小二 给不同业务创建报表模板 来生成报表
    • 小二创建权限 来 匹配报表
    • 客户创建角色
    • 客户分配角色
    • 客户筛选人群进行营销活动
    • 前置条件:业务告警?

    12.png

    6)领域驱动

    用例驱动是一种从局部到全体的思维方式,刚刚接触某一行业的人员从零开始来了解业务,复杂业务很难一开始就拥有上帝视角来分析业务。而领域驱动则是一开始就站在上帝视角来着手业务,领域驱动要求化整为零,它是一种由内而外,先内功后招式的思想。它要求团队里有资深的业务领域专家,该专家对业务领域极其了解,不但要了解其然,还要理解其所以然,或者是能够跟领域专业人员学习到足够的领域知识。

    在此条件下,团队将从业务领域里找出反映业务本质的那些事物、规则和结构,把它抽象化,描述业务运行的基本原理和业务交互的机制,识别出用户的首要利益。

    领域驱动需要领域专家深度参与,访谈专家,才可能得出领域模型,单靠技术人员本身很难得出完成得领域模型。语言就是承载思想或者想法的模型,不同的语言建模出不同的思想,中西语言差异造就思维差异,所以领域模型需要从语言谈起,用语言描述事物。领域模型本质上传递的是概念,是知识性的信息,语言正是让知识传递成为可能。

    对于软件开发的场景来说,把这些知识显式化,能快速对齐不同角色、不同参与方之间的概念,加速沟通,避免误解。

    【领域模型】

    我们先得搞清楚领域模型的概念,然后才有领域驱动。

    领域模型是采用业务对象建立起来的一种模型,我们把领域模型当中使用到的业务对象称为领域类。

    回顾我们学了很多年的面向对象变成设计,而实际上真正使用面向对象开发的思维却是比较稀少的,比如传统 MVC 架构下的 web 开发,基本是失血模型的对象,让我们很少真正使用面向对象来实现我们的业务。而正是因为缺少面向对象的业务实现的必要训练,让很人使用领域驱动时觉得困难重重,这就需要我们对领域模型有一些基本的认识,然后在训练中来深化对领域模型,面向对象的认识。

    领域模型的核心思想是对象,而领域驱动的核心是分层,需要对实现架构进行分层,不同的团队,不同业务可能会有相应不同的分层,但是整体上分层的思想就是解耦,把复杂的事情分解开来简单化处理。

    13.png

    传统架构挂着面向对象的名号,实际上干的全是面向过程的勾当,用户界面,数据库操作以及其他辅助性代码进程被写到业务对象里面,原因就是能让业务快速的跑起来,而领域驱动则打破了这个传统,给出了通用的架构解决方案,包含 4 个概念层:

    14.jpg

    将应用按层分离并且建立好约束的交互规则是很有必要的,代码如果没有被放在正确的位置上,则很快会发生混乱。领域层最核心的职责只应该关心领域方面的业务问题,基础设施则只需关心底层的数据交互和外界的数据通讯交换,而无需关注业务的实现。

    代码层面上各层的实现职责如下:

    • 接口层:该层包含与其他系统进行交互的接口与通信设施,在多数应用里,该层可能提供包括 Web Services、RMI 或 Rest 等在内的一种或多种通信接口,该层主要由 Facade、DTO 和 Assembler 三类组件构成;
    • 应用层:Application 层包含的组件就是 Service,在领域驱动设计的架构里,Service 的组织粒度和接口设计依据与传统 Transaction Script 风格的 Service 是一致的,但是两者的实现却有着质的区别,TransactionScript 风格的 Service 是实现业务逻辑的主要场所,因此往往非常厚重;而在领域驱动设计的架构里,Application 是非常“薄”的一层,所有的 Service 只负责协调并委派业务逻辑给领域对象进行处理,其本身不真正实现业务逻辑,绝大部分的业务逻辑都由领域对象承载和实现了,这是区别系统是 Transaction Script 架构还是 Domain Model 架构的重要标志;
    • 领域层:Domain 层是整个系统的核心层,该层维护一个使用面向对象技术实现的领域模型,几乎全部的业务逻辑会在该层实现,Domain 层包含 Entity(实体)、ValueObject(值对象)、Domain Event(领域事件)和 Repository(仓储)等多种重要的领域组件;
    • 基础设施层:作为基础设施层,Infrastructure 为 Interfaces、Application 和 Domain 三层提供支撑,所有与具体平台、框架相关的实现会在 Infrastructure 中提供,避免三层特别是 Domain 层掺杂进这些实现,从而“污染”领域模型,Infrastructure 中最常见的一类设施是对象持久化的具体实现。
    【建模过程】

    有了领域建模的基础知识后,下面我们介绍下领域建模的过程。

    • 用户访谈:充分贴合业务,基于现有人员资源能力;
    • 领域知识:首先我们分析项目在领域分层后的概念项目涉及到:

      • 名词:分析师,工程师,客户,小二
      • 报表,报表模板,权限,角色,告警,人群,活动,决策
      • 动词:登陆,创建权限,匹配权限,授权,建表,圈人,营销
      • 实体:报表,报表模板,权限,角色,人群,活动,决策
      • 值对象:告警
      • 服务:登陆,创建权限,报表匹配权限,授权给用户,创建报表,圈人,营销
      • 模块:报表域,权限域,洞察域,营销域
      • 聚合根:报表(报表模板,报表数据),权限(权限,角色),活动(人群,营销规则)
      • 工厂:报表模板工厂,人群工厂,决策工厂,权限工厂
      • 资源库:数据库,消息,外部接口
    • 领域模型:经过对领域知识的消化,就可以输出领域模型图。

    4. 架构推导

    经过了漫长的前戏--模型建立,本篇终于到了架构设计了,真的不容易啊。一开始我总是在纠结架构师应该输出什么架构图,什么才是标准的架构图,但是当我理解什么是架构,架构形成的过程后,我不再纠结了,架构存在每一个阶段,以不同的形态出现,业务,产品,技术,实施不同的阶段都需要一张提纲挈领的架构图来指导系统建设。

    系统架构这个词经常放在一起说,以至于我们觉得天经地义,经常混为一谈。系统指的是由一堆实体组成的一个具备某些功能的整体,而架构则是架和构,即是框架和结构,也就是具备稳定诉求而且是可以支撑整体的组件。系统可以没有架构,比如我们乱糟糟的系统。但是系统同时也是需要架构的,架构就像是系统的 DNA,架构决定了系统的走向和生命周期,好的架构可以支撑系统持久运行和更新迭代。

    1)架构定义

    我们先来对架构进行定义:

    架构:对系统中实体与实体之间的关系进行抽象的描述,用于指导软件系统各个方面的设计。

    2)架构分类

    随着互联网的发展,应用从单体到分布式,到如今基础设施的变革,我们迎来了云原生时代,系统的架构随着基础技术的突破也不断演化,单体应用最简单最常见的架构就是分层架构,比如我们熟悉的 MVC 架构,由于业务发展到一定层度后,需要对服务进行解耦,进而把一个单一的大系统按逻辑拆分成不同的子系统,通过服务接口来通讯,面向服务的设计模式,最终需要总线集成服务,而且大部分时候还共享数据库,出现单点故障的时候会导致总线层面的故障,更进一步可能会把数据库拖垮,所以才有了更加独立的设计方案的出现。

    随着分布式技术的成熟,微服务架构开始大行其道,在此基础上的边车服务和 servicemesh 也开始进入蓬勃发展期,整体上架构有如下分类:

    • 分层架构:MCV,六边形架构,洋葱架构
    • 事件驱动架构
    • 微核架构
    • 微服务架构
    • 云原生架构

    3)推导架构

    先问题,后定位,即:先使命后愿景,解决什么问题?先定义问题,何为问题,有矛盾即存在问题,专业的抽象和架构知识,以及背后的归纳和演绎的逻辑思考方法,加上丰富的业务用例,通过逻辑排列,形成业务架构,首先我们会用以下的表格来描述问题。

    15.jpg

    • 演绎

      • 将用例进行抽象分类成为业务模型
      • 将业务模型进行 IT 层面的思考,增加非功能性的组件形成系统模型
    • 归纳

      • 将用例以及问题进行分类聚合
      • 业务用例形成系统架构过程需要进行归纳
      • 对行为稳定性,性能考虑的总结,归纳为通用组件

    4)架构输出

    • 方案概述:对设计方案的概括性描述;
    • 设计约束:包括要遵循的标准或规范,技术上依赖的假设条件等;
    • 技术选型:包括系统运行的软硬件环境,研发、测试的软硬件环境,编程语言,现有或开源框架、平台、模块、基础库的重用策略;
    • 系统结构:包括系统的网络部署结构,子系统划分,推荐用 UML 部署图、包图描述;
    • 关键技术设计:每个系统关键点不一样,但一般都会有安全设计,一些算法的设计;
    • 接口设计:包括协议栈,子系统间的接口数据结构,子系统间的业务流程描述。业务流程推荐用 UML 序列图描述;
    • 数据设计:流动的数据已通过接口设计,这里描述要存储的数据,数据的组织形式不一样,比如 NoSQL,NewSQL,SQL 等不同类型,描述方式也会不一样,关系数据库推荐用 ER 模型描述顶层逻辑结构,字段表描述物理结构;
    • 质量预测:对遗留缺陷率、平均无故障运行时间等质量指标进行预测,提出可能出现的缺陷和问题。

    5)架构总结

    • 自底向上:由点及面,步步为营,通过用例堆积,分类,归纳,划分,内聚,逐步扩大范围,再通过剥离,复用,从业务架构到技术架构;
    • 自顶向下:洞察客户背后的本质需求,定义问题,分析问题,问题分类,优先级,升层思考,一上来自带上帝视角。

    实际应用,两者结合。

    5. 设计规范

    建立用例后,由于对用例分析的方法差异可能生成不同的领域模型。

    1)模型约束

    推导出模型过程中,需要参考业界沉淀出来的经验,比如 sold 原则,开闭原则等:

    • GRASP 设计原则(职责分配原则)
    • 信息专家原则(information)
    • 创造者原则(creator)
    • 低耦合原则(low coupling)
    • 高内聚原则(high cohesion)
    • 控制器原则(controller)
    • 多态原则(polymorphism)
    • 纯虚构(pure Fabrication)
    • 中介原则(indirect)
    • 受保护变量原则(protected Variations)

    2)设计原则

    GRASP 原则,设计原则有很多,我们进行架构设计的主导原则是 OCP(开闭原则),在类和代码的层级上有:SRP(单一职责原则)、LSP(里氏替换原则)、ISP(接口隔离原则)、DIP(依赖反转原则);在组件的层级上有:REP(复用、发布等同原则)、CCP(共同闭包原则)、CRP(共同复用原则),处理组件依赖问题的三原则:无依赖环原则、稳定依赖原则、稳定抽象原则。这些原则是前人大量的经验总结,比如设计模式的原则,SOLID 是几个重要编码原则的缩写:

    • 开闭原则(Open Close Principle):开闭原则就是说对扩展开放,对修改关闭,在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果;
    • 里氏代换原则(Liskov Substitution Principle):里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一;
    • 依赖倒转原则(Dependence Inversion Principle):这个是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体;
    • 接口隔离原则(Interface Segregation Principle):这个原则的意思是:使用多个隔离的接口,比使用单个接口要好,还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合;
    • 迪米特法则(最少知道原则)(Demeter Principle):为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立;
    • 合成复用原则(Composite Reuse Principle):该原则是尽量使用合成/聚合的方式,而不是使用继承。

    3)设计模式

    在编码过程中,前人抽象出来的 23 个设计模式也是很值得参考的:

    【创建型模式】
    • 简单工厂模式(Simple Factory)
    • 工厂方法模式(Factory Method)
    • 抽象工厂模式(Abstract Factory)
    • 创建者模式(Builder)
    • 原型模式(Prototype)
    • 单例模式(Singleton)
    【结构型模式】
    • 外观模式(Facade)
    • 适配器模式(Adapter)
    • 代理模式(Proxy)
    • 装饰模式(Decorator)
    • 桥模式(Bridge)
    • 组合模式(Composite)
    • 享元模式(Flyweight)
    【行为型模式】
    • 模板方法模式(Template Method)
    • 观察者模式(Observer)
    • 状态模式(State)
    • 策略模式(Strategy)
    • 职责链模式(Chain of Responsibility)
    • 命令模式(Command)
    • 访问者模式(Visitor)
    • 调停者模式(Mediator)
    • 备忘录模式(Memento)
    • 迭代器模式(Iterator)
    • 解释器模式(Interpreter)

    架构落地

    说了这么多,架构如何落地?相信这个是大家最关心的,前文我们已经从整体上建立了系统设计的方法论,再从 it 领域上升到通用商务领域的设计思维,在系统设计的层面又步步为营给出了工具和剖析模型建立架构推导的一步流程。

    其实到了这一步,架构设计已经到了柳暗花明的阶段了,因为我们已经已经把最核心的环节都弄通了,接下来无非对症下药,根据需求找到系统薄弱的地方,相应地使用适用的工具来发挥最大的作用。

    1. 行业架构

    目前大部分行业其实都已经有相对稳定成熟的应用架构,也形成了基本的套路,比如金融行业有传统的基于 IOE 的商业应用架构,也有新型互联网的去 IOE 基础上的架构,比如微服务化的流行,在即时通信的消息架构也是有成熟的解决方案。另外产业互联网各个传统行业的互联网化也可以应用边缘计算架构来实现。

    2. 技术架构

    行业下沉到技术架构层面,从微小企业到大型企业应用的解决方案,都逃不过网关设计,流量管理,服务治理,容错设计,监控告警,性能调优,数据管理等环节,而这方面的设计实现,业界也提供了成熟的开源解决方案,可以参考《分布式设计知识体系》一文,除了巨型企业需要自研外,多数开源的工具已经可以满足大部分需求,架构设计其实就是选择最适当的工具来解决我们的问题。

    总结

    系统设计犹如医生看病需要对症下药,医生需要博学多才精通药理,才能对症下药,就像架构师经验丰富,懂得各种软件工具(药)的利弊,各种设计原则和设计理论(药理)可以设计出架构图(药方),把软件工具精妙的组合在一起。

    学习的最佳方式是先进行比喻,其次是模仿,最后回归到概念的本质定义。一个好的软件架构师,同样可能成为很好的 hr 专家。本文共分为三个部分从思维讲起到系统逆向分析,到后面的正向设计。从“道,理,术”三个角度诠释了系统架构设计的全面知识体系。

    16.png

    阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”

    原文链接:https://developer.aliyun.com/article/775377?

    版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
    展开全文
  • 高级程序设计语言的基本理解

    千次阅读 2019-07-12 10:20:46
    我是在大学期间开始接触编程,但是学习的第一门程序设计语言是C语言,但是当时只是简单的学习,能用C语言写一些简单的控制台程序,所以当时对于程序设计来说只是一种玩票性质。 后来也进过实验室,玩过单片机,还...

    各位看官抱歉,因为域名备案出现了一点小插曲,原定计划Typora调教和七牛云图床的相关内容可能要拖到周末进行。

    我是在大学期间开始接触编程,但是学习的第一门程序设计语言是C语言,但是当时只是简单的学习,能用C语言写一些简单的控制台程序,所以当时对于程序设计来说只是一种玩票性质。

    后来也进过实验室,玩过单片机,还接触过汇编,但是最终都没有走下去。

    到大四下学期的时候由于毕业设计和工作的需要,开始接触JavaWeb,从此踏上了一条不归路,所以从这个意义上来说Java才是我在编程世界的母语。

    从刚开始懵懂地照着葫芦画瓢,到现在接触Java一年半左右的时间,对于一些高级程序设计语言中的基本概念有了一些理解,虽然不知道理解的是否正确,但是还是想记录下来,留待以后进行验证(目前我也在积极的学习JS相关的技术栈,而且计划明年年初的时候学习一下kotlin语言)。

    (想自学习编程的小伙伴请搜索圈T社区,更多行业相关资讯更有行业相关免费视频教程。完全免费哦!)

    我们编写的代码是什么

    我们平常使用高级程序设计语言编写的程序代码,其实就是一个文本文件,而每种程序设计语言的文本文件都有自己的扩展名,比如Java程序的源代码文件的扩展名是.java,JavaScript程序的源代码文件的扩展名是.js

    文件的扩展名是什么呢?文件是用来存储数据的,而数据要存储到计算机中肯定要进行编码,那么我们就可以把文件的扩展名理解成一种“协议”,如果一个文件采用某个扩展名,就相当于这个文件遵循了某个协议,就可以被支持这种数据协议的应用程序读取、解析并处理。当然用不支持这种协议的应用程序也能够打开这个文件,但是得到的往往是乱码。

    但是程序源代码还有所不同,高级程序设计语言的源代码其本质上还是一个纯文本文件,我们可以用任何一个编辑器打开并查看,而采用特定的扩展名其实是告诉这门高级程序设计语言的编译器,这个文件中的文本遵循了对应的程序设计语言的语法和规范,可以被编译器进行编译。

    关键字、标识符和字面量

    高级程序设计语言的源代码文件本质上是一个纯文本文件,而纯文本文件对于人类来说其实就是一个大字符串,而高级程序设计语言的编译器在对源代码进行编译的时候其实也是在处理一个大的字符串,它会根据特定的规则(主要依靠程序语言中定义的关键字)将源代码的文本映射成一棵抽象语法树(这里不做过多介绍,关键是本人还没有过多接触编译原理的相关知识),反正是一顿操作之后,代码就能运行了(认真脸)。

    而从人类信息文明的发展来看,从刚产生文字到现在为止,人类进行信息记录和传递的方式都是使用“字符串”,而计算机程序的运行是进行数据的处理,我们要向代码中传入数据,然后从代码中接收处理之后的数据;而数据的来源是人类,那么我们可以比较确定的说,计算机程序的最终来源是人类提供的字符串。

    就算是java中的Date这种对象的数据的最终来源也是一个代表了数字的字符串(时间戳)。

    高级程序设计语言的**源代码本身就是一个字符串,那我们怎么向一个字符串中传递数据呢?这就要依靠高级程序设计语言为我们提供的字面量机制了。**高级编程语言中通过使用界定符、特殊格式、关键字等手段为我们提供字面量机制。

    在程序设计语言中,字面量常常被分为三类:

    • 字符串,但是因为代码本身就是字符串,通常会使用界定符比如""来区分是字面量还是程序代码
      -数字,其实就是具有特定格式的字符串,因为其格式特殊,所以不需要界定符
    • 逻辑值,true或者false,大部分程序设计语言中都把true和false作为关键字。

    思考

    1. 标识符可以由字母、数字、下划线、$组成,其中数字不能打头。
    2. 标识符不能是java的关键字和保留字
    3. 标识符不能包含空格
    4. 标识符只能包含美元符号($),而不能包含诸如@、#等其他特殊符号(@、#等专门在java编译器自动生成的代码中使用,以进行区分)

    以上是摘自《疯狂java讲义》P48中的java标识符的命名规则,其实大部分的程序设计语言的标识符命名规则都是类似的,现在我们来讨论为什么标识符可以包含数字但是不能用数字打头。

    上面在介绍字面量的时候提到,数字字面量不需要界定符,也就是编译器在对代码进行编译的时候如果遇到纯数字字符串就认为这是一个数字,注意,数字字面量没有界定符,也就是说数字字面量是直接嵌入到代码中的,编译器对数字字面量的识别仅仅是“这是一个代表数字的字符串”。假如说,标识符的命名规则没有数字不能打头这一说,那么像a=1+b这句代码中,1是一个标识符还是一个数字字面量?同时就算是限定标识符不能是纯字符字符串也是行不通的,就拿java来说,123L这是一个数字字面量值,如果放开数字不能打头的限制,对于标识符的解析成本和难度将会大大增加,而对于一门高级程序设计语言来说,对标识符的解析是一个非常频繁的操作,而限制标识符不能以数字打头不会对我们的程序编写造成任何影响,所以标识符名称不能以数字打头无疑是最佳的解决方案。

    说到这里我又忍不住提到Java中的int和long的字面量,java中的整形字面量支持四种进制:

    • 二进制 以 0b 或者 0B 打头
    • 八进制 以 0 打头 这一点需要特别注意
    • 十进制 默认进制,但是需要注意不要以0打头
    • 十六进制 以 0x 或者 0X 打头

    发现了没有,各种进制还是以数字打头,也就是说在java中只要遇到以数字打头且没有界定符的“标识符”java就认为这是一个数字字面量。

    数据类型、操作符和变量

    数据类型、操作符和变量可以说是每一门高级程序设计语言的最基本的构件,而且我们日常的编码中很大一部分就是在跟这三者打交道,高级程序设计语言通过这三个基础构件让我们以比较接近自然语言的方式书写程序代码,例如a=b+c这样的代码相信每个开发人员都写过,不论你使用的是哪一门高级程序设计语言,这样的表达式都是非常常见的;这也使得高级程序设计语言的语义更加明确,代码更加易写。

    但是我们在使用高级程序设计语言给我们提供的这些数据类型、操作符和变量的时候,高级程序设计语言到底问我们做了什么事情呢。

    在我的理解中,数据类型、操作符以及变量其实就是高级程序设计语言为我们封装的一系列内存操作,比如在32位的计算机系统中,如果直接使用汇编我们需要自己对内存进行寻址,同时将数据加载到一个寄存器中,然后再用相应的汇编指令让CPU对我们加载到寄存器中的数据进行运算;而在高级程序设计语言中,这一系列的操作被一个简单的表达式a=b+c完成,其中的a、b、c在这里是变量(当然一个表达式中也可以存在字面量值)帮助我们完成了寻址的操作,同时变量所具有的数据类型规定操作的内存的大小和内存中数据的解释方式,操作符规定了对这些数据进行的操作。

    对以上的理解稍微总结一下,在高级程序设计语言中:

    • 变量其实是引用了一个内存地址,它帮助我们完成对内存的寻址操作。
    • 数据类型定义了对应的变量所要操作的内存的长度,以及对内存中数据的解释方式。
    • 操作符定义了要对对应的变量指向的内存地址中对应长度的数据进行的操作。

    这样,开发人员就从底层硬件中解脱了出来,让我们更加关注于程序的逻辑。

    当然,现在很多的程序设计语言是运行在某个平台(宿主环境,可以是操作系统,也可以是其他的应用程序,比如JavaScript是运行在浏览器中的;SQL是运行在数据库管理系统中的;Java是运行在JVM中的,而JVM又是运行在操作系统中的;etc…),而高级程序设计语言的发展又依赖于编译技术等底层技术的发展,这里不进行过多的介绍。

    以上的理解均是个人经验和理解,如有不同的看法欢迎留言进行讨论

    展开全文
  • 初次看到信息熵的公式有很多不理解的地方,只知道信息熵如何进行计算,却不懂得公式背后的原理,我通过查阅了一些资料,加深了信息熵的理解,现在将这些理解分享给大家。如有疑问欢迎评论,若你有帮助,麻烦点个...

    一、序言

        初次看到信息熵的公式有很多不理解的地方,只知道信息熵如何进行计算,却不懂得公式背后的原理,我通过查阅了一些资料,加深了对信息熵的理解,现在将这些理解分享给大家。如有疑问欢迎评论,若对你有帮助,麻烦点个赞。未经允许、请勿转载。(本文适合只知道信息熵的公式,但是不明白其中原理的人进行阅读)

    二、什么是信息熵

        正如我们想要衡量某个物体的质量引入了克这个单位、我们想衡量时间,我们设计一秒钟这么长。香农老人家想要量化一条消息中带有的“信息量”的大小,提出了信息熵。
    那么,首先明确一个问题,什么样的消息算作“信息量大”呢?什么样的消息又算作“信息量小呢”?举个例子昨天小明和我说:“今天罗志祥又和周扬青秀恩爱了!”,我就觉得这有啥的,他们天天秀恩爱。也就是说小明的这条消息并不能给我带来很大的信息量。
    BUT今天小明和我说:”周扬青怒锤罗志祥!!!罗志祥人设崩塌!!!“,我就会很惊讶,因为这条消息给我的信息量很大。(类似的信息量很大的消息还有:小明告诉我今天太阳会从西边升起)
    我们用信息熵来描述一个事件混乱程度的大小(一个事件我们一定知道结果,那么这个事件的混乱程度就是0;一个时间充满随机性,我们猜不到或者很难猜到结果,那么他的混乱度就很大)
    引用下面一个在箱子里面摸球的例子,我们来更具体的了解信息熵。
    (此例引自:Youtube的一个视频
    在这里插入图片描述
    图左侧中有一个装有四个球的封闭箱子(这个箱子里面有三个红球、一个蓝球),现在我们从箱子中随机取出一个球,记录它的颜色后再放回箱子中,重复四次操作。如果你依次取出的序列为右上角所示(第一次取到红色、第二次取到红色、第三次取到红色、第四次取到蓝色),则你可以获得奖金;否则你就输了。大家用初中数学来算一算,我赢得奖金的概率是
    P ( x ) = 3 4 ∗ 3 4 ∗ 3 4 ∗ 1 4 = 27 256 P(x)=\frac{3}{4}*\frac{3}{4}*\frac{3}{4}*\frac{1}{4}=\frac{27}{256} Px=43434341=25627
      现在明确了这个游戏的规则,那么我们分析一下如下几个箱子与赢得奖金的情况,分别计算一下获胜概率
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    (每个图的左边是这个箱子的红球与蓝球初始条件,右侧是获胜所要求的序列,大家自己算算这个概率和图上写的一样吗?)
    在这里插入图片描述
    我们来分析一下这三种状态的游戏,第一次由于箱子内全是红球、该箱子的随机性很弱,也就是说还没摸我就知道结果了。这种状态带来的信息量很小;第三个箱子随机性很强,也就是说,对于结果我们充满未知。这个状态的信息量很大。我们算出的这个概率越接近1时候,这个信息熵应该越接近0;算出的这个概率越小的时候,信息熵反而应该越大。我们需要找到这么一个公式来满足这一点。(暂停思考一下,有哪些公式可以满足)
    该可以很轻松的想到,用刚才P(winning)的概率取倒数可以吗? 答案是,只考虑刚才的问题,是可以的。但取倒数这个方式还是存在一些问题,比如第三个箱子取0.0625的倒数,算出来的这个信息量为16,如果这个P(winning)概率算出结果很小时,取倒数后就会变得非常大,所以我们认为这个乘法的规则并不是很好(换言之,我们希望曲线平滑一些)。香农发现log函数可以很好的解决这个问题。 因为log(a*b) = log(a)+log(b);而恰巧像抽箱子的独立事件P(AB) = P(A)*P(B)。【原因不止于此,后面我们还会再详细讨论】。
    所以香农取了一个-log(x)这么一个函数来表示某一状态的信息量大小,因为x是概率事件取[0,1],所以log(x)是一个递增的恒负的值,取一个负号,-log(x)是一个恒正、递减的函数,正好符合我们的预期。
    在这里插入图片描述

    表的第四列就是我们用log计算出的结果。而我们刚刚是依次计算的每一个球的结果,为了表示系统的平均信息量。我们除4得到最终的信息熵。
    在这里插入图片描述
    我们来将这个模型一般化,m个红球n个蓝球,信息熵表示如上图所示。
    我们可以再将模型一般化一些,如果这个箱子里有多种不同颜色的球,我们就公式变成了如下的样子:
    H ( x ) = − ∑ i = 1 n P ( x i ) ∗ l o g ( P ( x i ) )   H_{(x)}= -\sum_{i=1}^{n}P_{(x_i)}*log(P(x_i))\, H(x)=i=1nP(xi)log(P(xi))
    这就是信息熵。也就是说,我们规定拿出一枚硬币,随意投出后,他可能是正面也可能是反面,它的信息熵是单位1(用刚才的方法来算算是不是1)。就像我们在这节开始所提到的,我们知道一个物体是几千克。是因为我们有一个1kg的砝码作为参考。我们能感受到时间流逝了多少秒,是因为我们规定了秒的单位。

    三、为什么是log

     这章我们会再用一个例子来讲解,为什么是信息熵为什么要用log?还是以一个游戏为例。在这里插入图片描述
    在上述的8个字母中,任取一个字母(我们不知道取的是什么,但我们知道初始的8个字母是什么),现在让你来猜这个字母是什么。
    利用我们刚刚学过的信息熵,我们可以知道第一个序列的信息熵很低、第三个最高。我们可以计算出如下结果
    在这里插入图片描述
    (这个信息熵大家自己算一下,和上面计算的方式完全一样)
    重点来了: 下面我们用一种提问的方式,来解决这个问题。你可以像系统提问(比如:这个字符是A吗?),系统会给你回答,你根据回答继续进行提问,直到猜到结果为止。以第二个序列为例;系统选了D,让你来猜。你会这样提问:
    Q1:这个字符是A吗? Answer:不是
    你就知道,这个答案只能是B,C,D中的一个,你就会继续提问:
    Q2:这个字符是B吗? Answer:不是
    你就会继续问:
    Q3:这个字符是C吗?Answer:不是
    好了,你不会再继续问下去了,因为这个答案一定是D。
    也就是说通过这种方式,如果答案是A,你会猜1次,答案是B你会猜两次,答案是C或者D,你会猜三次。平均猜测次数为
    E ( x ) = 1 4 ∗ 1 + 1 4 ∗ 2 + 1 4 ∗ 3 + 1 4 ∗ 3 = 2.25 次 E(x)=\frac{1}{4}*1+\frac{1}{4}*2+\frac{1}{4}*3+\frac{1}{4}*3=2.25次 Ex=411+412+413+413=2.25
    显然,你可以选择一种更精妙的提问方式,来缩减平均猜测的次数
    你可以这样进行提问:
    Q1:这个字符是A或B吗? Answer:不是
    Q2:那么这个字符是C吗? Answer:不是
    好了,那么我知道这个字符是D了。也就是通过这种方式,我们不管是哪一个字符,我们只需要问两次就可以解决问题,我们用一种更直观的树来表示,如下图所示
    在这里插入图片描述
    恰巧,这种提问二选一的过程,恰巧是个抛硬币的过程。由于我们类似的等价于抛了两次硬币,我们可以知道,这个过程的信息熵是2。我们再用信息熵的公式试一试
    H ( x ) = 1 4 ∗ l o g ( 4 ) + 1 4 ∗ l o g ( 4 ) + 1 4 ∗ l o g ( 4 ) + 1 4 ∗ l o g ( 4 ) = 2 H(x)=\frac{1}{4}*log(4)+\frac{1}{4}*log(4)+\frac{1}{4}*log(4)+\frac{1}{4}*log(4)=2 Hx=41log(4)+41log(4)+41log(4)+41log(4)=2
    (这里我们把符号直接化进log中了)

    大家发现没有,log(x)是不是恰巧等于x需要询问的次数呢?!!!这也是这个公式的精妙所在,在离散数学中我们学过,一个树的高度等于log(节点数),这个log(x)恰巧是询问的高度,也就是投硬币的次数!这原来就是使用log的原因
    上面的例子中A,B,C,D都是等概率出现的;下面我们将这个过程一般化,看一看当每个随机变量不等概率时的运算过程
    在这里插入图片描述

    我们看如上的序列,其中A出现的概率要等于BCD之和。所以我们为了让我们的提问次数最小化,我们要尽力讲每次提问的YorN分成等概率,也就是我们要问的第一个问题是:
    Q1:这个字符是A吗?
    如果不是,我们知道是B,C,D但是B的概率等于C和D之和,我们就再问:
    Q2:这个字符是B吗?
    如果不是,这时候C和D等概率,我们随便问一个即可:
    Q3:这个字符是C吗?
    好了,现在得出了结论。
    问出A需要1次,B2次,C和D都是三次。
    我们用信息熵来计算一下。
    H ( x ) = 1 2 ∗ l o g ( 2 ) + 1 4 ∗ l o g ( 4 ) + 1 8 ∗ l o g ( 8 ) + 1 8 ∗ l o g ( 8 ) H(x)=\frac{1}{2}*log(2)+\frac{1}{4}*log(4)+\frac{1}{8}*log(8)+\frac{1}{8}*log(8) Hx=21log(2)+41log(4)+81log(8)+81log(8)
    每一个log(x)恰巧对应着他所在的叶子在树的第几层,也就是他需要询问的次数,前面乘上一个概率,是不是发现这个公式提出的非常巧妙!!

    同时,在二进制计算机中,一个比特为0或1,其实就代表了一个二元问题的回答。也就是说,在计算机中,对于这个事件进行编码,所需要的平均码长为H(x)个比特。

    三、结语

     通过上述过程,相信大家能清楚的理解信息熵。本文并没有一些数学上详细的证明,暂时留个坑以后填。如果大家有什么问题,欢迎在评论区交流,如果觉得有用麻烦点个赞~
    参考资料:
    [1]https://www.youtube.com/watch?v=ErfnhcEV1O8
    [2]https://blog.csdn.net/v_JULY_v/article/details/40508465

    展开全文
  • 彻底理解递归,从递归的本质说起!

    万次阅读 多人点赞 2018-05-12 14:28:35
    遍历二叉树,是学习树这种数据结构首先要理解的一种基本操作。比较简单地方式就是用递归去遍历,鉴于递归这种调用方法有一定的特殊性,今天还是想来讲讲怎么去理解递归遍历。本文针对想理解递归的过程的朋友,因为...
  • 浅谈我DDD领域驱动设计理解

    万次阅读 2017-11-29 09:25:46
    这哥这个问题解释得非常透彻,借此自己也学习一下。 从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决。 比如,我是一家企业,然后我觉得...
  • 软件设计本质论--面向对象,详细的讲解,容易理解
  • 理解socket的本质

    千次阅读 2016-08-03 14:33:52
    这些句柄,其实是代表了系统中的某些特定的对象,用于在各种函数中作为参数传入,以特定的对象进行操作--这其实是C语言的问题,在C++语言里,这个句柄其实就是this指针,实际就是对象指针啦。 现在我们知道, ...
  • 图像识别技术原理和神经网络的图像识别技术

    万次阅读 多人点赞 2019-03-03 19:44:58
    随着计算机技术的发展,人类图像识别技术的认识越来越深刻。图像识别技术的过程分为信息的获取、预处理、特征抽取和选择、分类器设计和分类决策。简单分析了图像识别技术的引入、其技术原理以及模式识别等,之后...
  • 研究生工程伦理课程答案整理

    万次阅读 2019-12-17 09:55:12
    1.多选(1/1分) “什么是好的、正当的行为方式?”这一问题的思考和争议由来已久,从而形成了不同的伦理学思想和伦理立场。大体上,可以把这些伦理立场概括为() 口功利论 口契约论 口义务论 口德性论 正确答案:功利...
  • 2019工程伦理慕课答案(2019秋)习题及期末答案

    万次阅读 多人点赞 2019-11-08 18:19:53
    第一章习题(下) 单选题 (1/1 point) 下列哪一项不是工程与技术的区别 内容和性质 目的 活动主体 任务、对象和思维方式 单选题 (1/1 point) 下列哪一项不是工程活动的... 设计 ...计划、设计、建造...
  • IOC和DI本质理解

    千次阅读 2016-08-04 13:29:50
    【4】迪米特法则(最少知识原则):不知道依赖的具体实现,只知道需要提供某类服务的对象(面向抽象编程),松散耦合,一个对象应当其他对象有尽可能少的了解,不和陌生人(实现)说话 【5】IoC是一种让服务消费...
  • 什么是设计设计本质是什么

    千次阅读 2014-01-30 00:05:25
    设计的首要 因素: 发现 存在问题 设计都带有缺陷 我刚进大学时,韩国教授问我们,为什么要做设计。那时候的我心里说「因为我喜欢设计」。教授说设计为了赚钱。那时候的我接受了这个想法。 后来,我越做...
  • Linux C/C++ 学习路线

    万次阅读 多人点赞 2019-07-04 20:41:56
    这三个是最核心的智能指针,理解清楚智能指针的本质是,内存的申请与释放全部交给了对象管理,以避免人为疏忽,造成内 存泄露。 何为c/c++Linux方向的深入学习,就是在掌握上述前提技术基础之上的进阶学习。 ...
  • 获得一组基本需求说明后,就快速地使其“实现”,通过原型反馈,加深系统的理解满足用户基本要求,使用户在试用后需求说明进行补充和精确化,从而获得合理完整、现实可行的需求说明 再把快速原型思想用到软件...
  • 如何理解反步法设计控制器?

    万次阅读 多人点赞 2019-04-13 19:37:16
    假设以二阶系统为例,被控对象的系统状态方程为: 基于反步控制的具体方法如下: 1.1步骤一 定义期望状态为xd,状态误差e1,为: ...因此设计的控制律为: 设计c>0,则: 满足Lyapunov的稳定性判定条件...
  • 面向对象的程序设计,我记得好像是上世纪70年代提出来的,具体时间不太记得了,那么到现在...其实,我个人觉得,不管是面向对象,还是结构化程序设计,从流程和逻辑来看,其本质都是一样的,不一样的是分析和实现的思
  • 模糊PID算法及其MATLAB仿真(1)

    万次阅读 多人点赞 2019-04-15 20:34:35
    这种方法本质上是PID控制,对于参数变化范围大的对象,要获得良好的相应性能,就需要PID参数进行在线调整,模糊自整定PID就是比较好的方法。 (3)还有一种我也是在参考文献 [1] 才见过的,文中提到这有点类似...
  • 用产品思维设计API(二)——数据解耦,才是前后分离的本质前言 最近公司内部在重构项目代码,包括API方向的重构,期间遇到了很多的问题,不由得让我重新思考了下。 - 一个优雅的API该如何设计? - 前后端分离...
  • 架构的本质

    千次阅读 2021-01-18 20:06:15
    1、架构的本质 物理学中有个很著名的“熵增定律”:一个封闭系统,都是从有序到无序,也就是它的熵 (即混乱程度)会不断地增加,最终系统会彻底变得无序。 这个理论放在软件系统的演化上,也是非常适用的。 一方面,...
  • 认知与设计理解UI设计准则

    热门讨论 2013-05-27 21:42:58
    从认知心理学出发,以理论的视角剖析UI设计,让你深入理解UI的本质
  • 编译原理 - 学习/实践

    千次阅读 2019-08-31 18:04:34
    1.介绍 TBD 2.应用背景 TBD 3.学习 课程目录 已更新 30 讲 / 共 38 讲 ... 01 | 理解代码:编译器的前端技术 02 | 正则文法和有限自动机:纯手工打造词法分析器 03 | 语...
  • python3_实现BP神经网络 + BP神经网络应用实例

    万次阅读 多人点赞 2018-07-29 22:10:28
    1.BP神经网络简介 BP神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照逆向传播算法训练的多层前馈神经网络,是目前应用最广泛的神经...从本质上讲,BP算法就是以网络误差平方目标函数...
  • 前端学习路线

    万次阅读 多人点赞 2015-10-28 11:22:47
    就像你在去理解别人的代码的时候一样,不要漏掉任何一行! 5.首先用简明的语言来写复杂的代码。这是一种锻炼! 6.定期定目标,每天都看看,想想,保持敏感、紧迫感、期待感。 7.记笔记: 学习过程中...
  • 4 实验结果 其实本质上就是在双闭环的基础上加了一个位置环,其实难度和结构都比较简单,但是要实现高的精度,还有很快的相应速度,如果纯PI需要特别理想的参数,或者就是增加前馈补偿,本次我只是尝试了调PI的方法...
  • 浅谈DDD领域驱动设计理解

    千次阅读 2017-09-30 11:20:51
    理解什么是领域驱动设计,首先要理解什么是领域,什么是设计,还有驱动是什么意思,什么驱动什么。 什么是领域(Domain)? 前面我们已经清楚的知道我们现在要做一个什么样的系统,这个系统需要解决什么问题...
  • 学习Spring系列,永远离不开的就是IOC控制反转和AOP面向切面编程,并且在其中充满了设计模式的魅力. 之前面试也被问到过,简单的理解过程是不够的,败在了理解源码上面,为了今后的学习,想用源码去理解一下到底什么...
  • 工作多年,我架构的一些理解

    千次阅读 多人点赞 2020-07-13 09:41:54
    每一个程序员都听过架构这个词,每一个程序员都有自己对此的理解和看法,本文分享我架构的理解。 什么是架构? 因为我是程序员,所以本文讨论的架构特指软件架构(Soft Architecture)。 我看过很多关于架构方面的书...
  • 理解递归的本质:递归与栈

    万次阅读 多人点赞 2018-04-11 09:34:08
    递归的基本思想所谓递归,就是有去有回。递归的基本思想,是把规模较大的一个问题,分解成规模较...或者可以这么理解:递归解决的是有依赖顺序关系的多个问题。我们假设一个抽象问题有两个时间点要素:开始处理,结...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 298,900
精华内容 119,560
关键字:

对设计本质的理解