写点什么

撇开代码不说,谈谈我对架构的 6 个冷思考

2016 年 9 月 21 日

计算机是个复杂的机器,相比普通的机器(比如小家电、汽车),它可以在使用过程中对其「工作行为」进行「再定义和场景适配」,以解决不同场景下的人的需求和问题,这种「定义的结果」,对于机器的最终用户来说,是「应用 / Application」。

对于非计算机相关的普通人而言,即便是有诸多对于职位头衔的描述:「程序员」、「软件工程师」、「架构师」、「首席技术官」,也离不开一个潜意识的印象:「做网站的」或者是「修电脑的」。

很多「架构师」,都是从「软件工程师」开始,不知不觉的变成了一个「架构师」。对于我个人而言,当我还是一个实习生,被「升」为一个部门架构师带领一些正式员工干活的时候,对「架构师」这个概念居然是一片空白,甚至于不知道这是个「好消息」,还是个「坏消息」,当然也不知道「架构师」是干嘛的。

所以,我一直以最简单的方式对架构进行定义:架构是一种用计算机解决问题的综合能力,与头衔无关。下面我将结合自己的工作经验,谈谈这些年来,我对结构的理解。

1、架构源于对实践的总结

架构能力并不是与生俱来的,而是和具体经历强相关的,丰富的经验是形成架构能力的基础。

很多时候我们强调「系统性思考」对于架构设计的重要性,希望从方法论上能够对正在从事或者即将从事架构工作的程序员在专业能力上进行提升。教条式、填鸭式的培训,是教不出架构能力的。理论的价值是能够帮助应用理论的人少走一部分的弯路,但不能够解决眼前的现实问题。

在企业里,架构是一个实践结合非常紧密的领域,一切以解决实际问题为目标。由于问题是多种多样的,导致解决的方法也是多种多样的。踩过的雷,填过的坑,都需要进行总结和抽象,才能提升到架构层的高度,防止重蹈覆辙。

2、架构是一个建模的过程

对于一个复杂问题,通常会对复杂问题按照能力领域进行分解,其目的是能够找到与现有能力相匹配的映射。这个映射,就是解决方案。它,离不开人的「知识型劳动」,主要分解为三个方面:

  1. 对于已知问题的抽象和建模
  2. 对于已知能力的抽象和建模
  3. 对于解决方案和工具的设计

其中前两个方面,都提到了「建模」。建模本身是对客观事物的一种抽象,客观事物越复杂,那建模的结果变成「盲人摸象」的概率就越高。

然而,「盲人摸象」在 IT 领域其实不能算是个「贬义词」,因为这个现象十分的常见。究其原因,解决实际问题信息系统,更多程度是面向于「典型」应用场景,而不是「任意」应用场景的。

场景即是对客观事物的认知视角,信息系统做不到、也不需要对一个完整的客观事物进行全面(360°无死角)建模。

举个具体的例子:对于人这个客观事物,银行系统里,可能会关心这个人财务指标,例如「收入」、「支出」和「存款余额」,但在医院的重症监护病房里,可能就会关心这个人的生命指标,例如「血压」、「心跳」。

从例子里可以看出,一个面向具体问题的场景化应用系统,都是对一个客体进行「片面的」场景化建模。

说到底,建模是一种抽象能力,具体的说,是人对客观事物认知结果的理性提炼和总结,不可否认感性的部分太难以刻画和描述。很符合「庄子·天道」中所述:「意之所随者,不可以言传也」。

如果要拿数学语言进行描述「建模的能力」,就是找到一组尽可能少的「特征向量」去表述这个空间,而找这组「特征向量」的能力,就是建模的能力。

3、架构工作的核心是设计

没有软件的计算机,是「无法使用」的,因为没有办法帮助我们解决任何问题。计算机原本很「生硬」,无法很「柔软」的去直接适配所需要解决的问题。

架构的核心工作是「设计」,设计计算机如何按照预期进行工作。

架构设计中,建模的结果,是模型,它有着结构化、棱角分明的特质,因为这是计算机进行计算的最高效的方式:严格的告诉我们——两个数是相等还是不相等,及其衍生。正由于严格匹配,所以在很长的一段时间里,解决方案的制定和后续系统的交付运行,都围绕着如何严格按照实际场景进行模拟和落地。 很少以「按概率成功」对系统的业务功能进行设计和实现,一切都必须「绝对正确」。因为绝大部分的计算机系统,无法理解自然语意。只能根据人为设计的结构化信息,「按部就班」地完成重复性劳动。

人工智能、机器学习,在解决自动化建模领域的成熟度还是远远达不到人的能力,如果达到了,那么软件就不需要人进行「架构设计」了。简单的从架构设计的结果(当然也是结构化的),生成代码,这方面目前的计算机还是有能力胜任的。

任何不符合实际场景的计算结果,用户都认为是「缺陷 」,而在系统中产生此类异常结果,往往需要「程序员」为此承担相应的责任。呐,回想一下,在没计算机的时代,反而往往都是店小二算错了帐自己赔,没有人会去责怪算盘。这是为什么,因为算盘足够简单,简单到不需要做任何的监控系统、不需要记录任何的日志,连「三下五除二」这样的操作规则,都已经被社会化学习消除了使用成本。最终,一切出错的原因只有一个:用键盘的人。

是的,计算机系统生来就是是不可靠的,它不可能像「算盘」一样在运行期不依赖任何的自然资源。断电了,会引发故障;光纤断了,会引发故障;磁盘满了,会引发故障。。。一系列的不确定因素,导致「分布式系统」架构设计比「主机系统」的架构设计复杂的多,原本不需要操心的事情,都需要从更上层的软件层加以解决了。

所以,当前架构工作的很大一块,都随着分布式系统规模的增大而加大了比重。也许,导致世界上最聪明的一伙人都去解决计算机的问题了。

4、架构需要作出一系列非技术选择

架构既然是个解决方案,自然有很多可以自由选择的领域,有很多受限的前提条件。这些外围因素,往往还系统背后的个人、团队、企业的价值观、以及非 IT 能力有关,这是一个很容易被忽视的点。

与人和团队的关系

架构往往是与个人或者团队的能力有关的,因为架构前一部分是设计工作,后一部分是代码框架的落地工作。可以没有一个十全十美、满足各方需求的方案,架构过程中有很多都是妥协的结果,有的是向需求妥协,有的是向运维妥协,有的是向个人英雄主义妥协。另外,绝大部分的选择都是人作出的,这导致了和人、团队的水平形成了很大的耦合关系。

早在 1895 年,法国心理学家勒庞在他的心理学名著「乌合之众(The Crowd)」就早已经说过:一群精英所作出的群体决定,很有可能是最愚蠢的决定。有时候,技术团队不能太强调民主;有时候,技术团队中的强强产生的效果是「1 + 1 \< 1」。一个良好的、强弱结合的组织结构,才有可能孵化出优秀的工具,再进阶为一个优秀的产品,也有利于成员梯队的培养。

团队越大,一个优秀的架构设计方案被严格执行下去的可能性越小。第一,制定方案的人和落地方案的人大多数情况下都有脱节,很多设计精巧的方案细节到了执行者的手里,会被忽视。第二,为了统一一个团队的认识结构、设计理念,这部分的培训成本往往都是各个雇主不愿意付出的。第三,方案的描述本省是「不精确」的,还很容易存在文档过期的情况,在软件及交付的各个环节,任何参与者都有机会以自己的知识背景作为出发点进行理解,并自豪地加上自己的「杰作」。

与企业的价值观相关

企业的价值观,最直接的体现,就是企业的投资组合。

在大型的企业里,软件产品的采购往往会受制于「采购部」,也会受制于不懂 IT 的公司级领导所下达的行政干预,有些理由好像听上去也「很有道理」:采购过为什么还要采购,要「保护投资」。往往到了这个层面,程序员、架构师都纷纷表达了无奈。

软件,包含代码和数据。它不是一个简单的能够按照「固定资产折旧」进行的固定资产。它透射的是使用者对客观世界的认识,也需要随着对客观世界认知的变化而变化,因此版本对于软件来说就是一个时刻认知的快照沉淀。

行业的快速发展,企业的快速发展,势必推动企业信息系统的快速发展。对于企业而言,其价值是能够找到感知行业、感知产品、感知用户、感知企业内部运营的触角,每个社会中的实体不管是个人,还是产品都能够在系统中找到它的影子。

对企业主而言,IT 是一个长期的投资行为。陈旧的、不符合时代背景的软件,是会变成降低企业生产力的绊脚石。

5、代码是架构设计的落地实现

现今任何的计算机高级编程语言,例如 Java/C/C++,或者更高层的 DSL,都是人与计算机之间的「单向语言」。这些「单向语言」,并非自然语言,大多数由程序员编写,再交由计算机进行执行,在很长的一段时间内,信息系统都是以这种方式与人进行交互。 (当然,也可以慢慢的等待「Siri」之类的助手长大成人,成为一名架构师,也许那个时候,广大架构师需要转行了。)

代码是架构实现的核心,通过代码可以完成对现实世界的「虚拟化」:

  • 概念的虚拟化
  • 能力的虚拟化
  • 实体的虚拟化
  • 记忆的虚拟化
  • 协作的虚拟化

通过一些例子,有助于理解:

  • 概念的虚拟化:一个业务概念的类定义
  • 能力的虚拟化:一个方法对多个输入数据进行加工并返回结果
  • 实体的虚拟化:一个类的实例,即具体的数据
  • 记忆的虚拟化:一条关系型数据库的行记录
  • 协作的虚拟化:远程方法调用

是的,代码是计算机的指挥者,代码是把人类智慧「赋能」给计算机的一种语言。

代码到不到位,写的好不好,对设计的落地实现会产生很大的影响。

6、其实,架构是一种用计算机解决问题的综合能力

很多时候我们看到的「系统架构图」,其实是针对目标问题所设计的「计算机领域的解决方案」,是一种设计图纸。

可以说,「架构工作」不仅要能够交付「设计图纸」,还要能够「建地基、搭房梁」。

  • 宏观层面:对特定问题,进行解决方案的设计
  • 微观层面:对后续的编码工作,形成与解决方案核心相一致的代码框架

做好「架构工作」有很多非技术的「软实力」,比如:

  • 对于团队中成员职能的正确定位,知道他们真正擅长什么
  • 深挖至本质的问题分析
  • 多视角、符合人性的换位思考
  • 舍弃一些力所能及,但影响专注的「杂事」,合理的说「不」
  • 具备一定的投资意识,从更高、更长远的视角,看待投入与产出

其他的发散性思考 在互联网公司出现之前,有没有「互联网公司」呢?他们和现如今的互联网公司的差别是什么?

其实是有的,例如「电网」、「电信运营商」、「股份制商业银行」、「快递物流公司」。在人类社会中最基本的两个元素,就是「实体」和「连接」,一切和连接有关的行业,都可以认为是「互联」,只不过信息系统在企业中的价值是由「生产关系」决定了其价值。

机器学习能够帮助架构设计吗?

机器学习很长一段时间之内都停留在参数调优上,而不具备对于一般事物进行建模的能力。前文也阐述过「概念的虚拟化」和「实体虚拟化」之间的关系,实体虚拟化就是数据,而数据本身已经是类的实例了,

互联网公司大谈「大数据」以及「数据驱动 DT」的原因是什么?

前面提到,数据是对客观实体的虚拟化,客观实体并不是无中生有的,他们是自然世界的产物,数据驱动的本质是客观事物驱动,退一步讲,本质仍然是「业务驱动」。当然,打通多个场景化的数据,对客体进行 360°的建模,是「大数据」真正价值所在。

需要注意的是,剑总是双刃的,当在计算机系统这个虚拟世界里,找到了 360°、包含衣食住行的你,生活是便利了,因为可以预测你的需求,不过你的隐私还存在多少?

对开源软件实施「拿来主义」是否可行?

很多开源软件,直接的「拿来主义」,会导致「后患无穷」。很大程度上,开源代码是一个个人、一个团队整体能力的映射,并且和运行这些代码所需要的环境息息相关。开源代码也是挑人、挑环境的,在一个团队没有想匹配的能力进行正确的使用之前,很多时候都是一匹「天生野马」,在驯服之后才会变成自己的「血汗宝马」,驯服的过程其实就是和自己团队以及周边环境相适配、磨合的过程。

重复造轮子真的是浪费吗?

一个健康的 IT 团队,应当建立起一套评估「现有轮子」是否产生实际效益的体系,比如能够监控代码在生产环境的实际使用率、故障率,适时的下线一些「低效益」的代码。不要简单的否定和阻止「重新造轮子」,这是与企业内部人的能力对齐、外部大环境对齐的过程,更是企业不断新陈代谢的「投资型基因」。

结构化的数据到底意味着什么?

所谓结构化,其实是面向数据的下游处理者,可以与其内置的概念(数据模型)进行映射和处理。结构是一种「元信息」。

举个具体的例子,一张 bitmap 图片,它本身是有结构的。bitmap 的图片是标明了每个像素点上的 RGB 颜色值具体是多少,这个数据结构,对于图片浏览器来说,是可以识别和解析成为一张人眼能够识别的图片的,而浏览器本身只负责每个像素点上的颜色还原。倘若这张图片里是一张「用户」写实头像,那么图片浏览器并不能够分析出这张头像具体是哪个自然人,也无法将这张图片作为一个 API 的入参,联合其他该用户的入参,进行内部业务逻辑的处理。

嘉宾介绍

王延炯,密码学博士,现任普元信息软件产品部主任架构师,微博帐号 @SINeWang。毕业于北京邮电大学网络与交换技术国家重点实验室网络安全中心。曾先后任职于西门子(中国)研究院、普元信息、垂直行业互联网公司。带领团队交付了移动、金融、电信、广电、移动互联网等多个行业、众多 IT 系统的咨询、设计、研发、实施、维护、优化工作。对分布式架构,企业架构,以及企业 IT 平台化运营有深入的研究和理解。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016 年 9 月 21 日 17:413385

评论

发布
暂无评论
发现更多内容

花了19998买的学习教程!2021年Android技术下半场在哪?震撼来袭免费下载!

欢喜学安卓

android 程序员 面试 移动开发

计算机专业必看!难道Android真的凉了?大厂内部资料

欢喜学安卓

android 程序员 面试 移动开发

OpenKruise 2021 规划曝光:More than workloads

阿里巴巴云原生

阿里云 开源 容器 云原生 调度器

架构师训练营 - 大作业一

Pudding

架构训练营 - 第 13 周课后作业 - 学习总结

Pudding

架构训练营 - 第12周课后作业 - 学习总结

Pudding

这些常用ETL任务调度框架组件,你都知道几个?

会飞的鱼

大数据处理 kettle 海豚调度 调度引擎 调度式分布

Java并发编程:AQS的公平性

码农架构

Java Java 分布式 java 并发

滴普技术荟-云原生基座OpenKube开放容器实践(一):如何理解Linux network namespace ?

滴普科技2048实验室

Linux

测开之函数进阶· 第7篇《装饰器装饰类,通用装饰器,有啥区别呢?》

清菡

测试

架构师训练营 - 大作业二

Pudding

IT2.0:中台构建还应从企业业务实际出发

华为云开发者社区

区块链 分布式 安全 数据 身份安全

架构师训练营 - 第 13周课后作业(1 期)

Pudding

Appium的安装及简单的使用介绍

行者AI

人工智能

云原生2.0时代,华为云DevOps立体运维实践

华为云开发者社区

DevOps 运维 云原生 华为云

如果腾讯、阿里是弱生态,那么谁是强生态?

ToB行业头条

分布式身份:重新定义你的“身份”管理

华为云开发者社区

区块链 数据 隐私保护 分布式身份标识

从根上理解高性能、高并发(三):深入操作系统,彻底理解I/O多路复用

JackJiang

网络编程 高并发 高性能 即时通讯

深圳区块链交易所开发、数字货币交易平台开发

W13902449729

深圳区块链交易所开发 数字货币交易平台开发

万字长文聊缓存(下)- 应用级缓存

Silently9527

缓存 缓存击穿 Caffeine 缓存架构

软件测试--中间件介绍

测试人生路

软件测试 中间件

细节拉满!美团首推“百万级”Redis进阶笔记究竟有什么魅力

程序员小毕

数据库 nosql redis 分布式 性能

案例展示自定义C函数的实现过程

华为云开发者社区

数据库 数据 C语言 字符串

抽象照进现实

型火🔥

抽象 视觉化

Linux的进程pid编号极限

程序员架构进阶

Linux 进程

2020 — iOS 面试败北感悟

iOSer

ios iOS Document 大厂面试 iOS面试 底层知识

四年三次获奖,PostgreSQL再度荣获“年度数据库”桂冠!

PostgreSQLChina

数据库 postgresql 开源

如何防止短信验证码接口被恶意调用攻击?

香芋味的猫丶

短信 短信防刷 接口安全 验证码

anyRTC 2020年12月SDK更新

anyRTC开发者

uni-app android 音视频 WebRTC sdk

Vue 3 组件开发:搭建基于SpreadJS的表格编辑系统(环境搭建)

Geek_Willie

Vue SpreadJS vite

全网最全原理讲解!如何试出一个Android开发者真正的水平?已开源

欢喜学安卓

android 程序员 面试 移动开发

演讲经验交流会|ArchSummit 上海站

演讲经验交流会|ArchSummit 上海站

撇开代码不说,谈谈我对架构的6个冷思考-InfoQ