包含标签 技术 的文章

『每个架构师都应该研究下康威定律』

InfoQ 中国在 2016 年,发表过一篇文章,杨波的《每个架构师都应该研究下康威定律》。这篇文章对当时的我,触动是非常深刻的。一些说不清道不明的经验,被别人用浅显易懂的道理,讲得一清二楚。 康威定律是很早就听说过的,后来陆续又有一些接触,每次时隔一段时间再做了解,就会有非常深的触动。我理解,原因无他,因为它聚焦在组织架构和系统设计的关系上,而这两者,一个是架构师目标,一个是架构师的手段/工具。文中用很简短的一句话,讲清楚了这中间的关系。 系统架构的目标是解决利益相关者的关注点。 这句话简直太重要,太精妙了。 1. 架构师的目标,是各个利益相关者的关注点 很多人对架构师的误解,都以为是架构师是技术执行,是 top-level coder,对 coding 的结果负责。这就犯了以表象取人的问题。为什么?我后面再提。 架构师首先应该关注的,是项目中,各个角色,各个利益相关者,他们的利益诉求,他们在项目中的焦点。根据这些焦点,得到一个权衡的方案,并取得最大限度的支持。 2. 架构是权衡的艺术 权衡的英文表述比较准确一些。trade-off 。利益交易和平衡。 权衡的方法是博弈,无论是纳什均衡还是帕累托最优,权衡目标是达成一个相对稳定的博弈结果。这个结果,就是架构的目标需求。 所以你看,脱离实际场景谈『架构』,本来就是虚空的。 3. 架构首先是业务架构,其次才是技术架构 道理很简单,业务架构往往涉及最直接的利益分配,从市场到产品到后勤保障,通常都对业务指标虎视眈眈。产品技术指标他们并不关心。 从工作流程上来讲,业务架构决定产品设计,产品设计决定技术设计。说业务架构是技术架构的前置步骤,一点不为过。 唯一的例外,可能就是大厂里面做平台产品研发的案例了。从无到有形成一个平台,比如阿里 IaaS 云。商业模式不清晰,业务架构反而受制于技术架构。不过这种机会今后出现的可能性,越来越小。 4. 技术架构是工具/手段 确定了各个 stakeholder 的 key points,剩下就是怎么做的事情了。技术手段、技术架构,不过是实现平衡的工具而已。通过技术架构,将权衡的方案,表达出来,这是一个称职的架构师,秀于外的工作。 我个人对架构师的定义是,以权衡项目中各个利益相关方的利益关注点为目标,以技术设计为工具和手段,以持续的产品技术服务为交付物的产品研发决策者。 所以回过头去看,架构师的工作中,技术架构的部分,优先级排不到前列,称得上是最基础、最『本分』的技能。技术好,技术设计灵活,不是一名架构师值得炫耀的资本。架构师值得炫耀的,是他能够在复杂纷扰的环境中,仍然可以理出线头,正确判断形势,做出合理的架构设计。 比方说,一名做 ToB 业务的 SaaS 平台架构师,既往工作中,以项目经理/甲方的利益诉求为主,以己方销售的利益诉求为辅,养成了习惯。一个需求做不做,怎么做,第一问己方销售/甲方,其次问项目经理,总可以得到答案。有一天,他去到一家做 toC 产品的公司任架构师,他面临的 stakeholders 发生了翻天覆地的变化,『甲方』成了成千上万的个体,怎么去问每个个体,他们的 key points 是什么?所以这位架构师的转变是,以直接上级的利益诉求为主,以产品经理的利益诉求为辅。那么,这个架构师,很明显就犯了最低级的失职。即便他的技术实力再强,首先目标就错了,谈何取得胜利? 雷军讲的,以战术上的勤奋,掩盖战略上的懒惰,大概也是说这个意思。 啰嗦一句。无论是 toC 产品还是 toB 产品,架构师首先应该予以重视的 stakeholder,都应该是财务上销项对应的一方。也就是为公司提供入账的一方。有人可能会觉得奇怪,toC 产品不应该是用户为首要的 stakeholder 吗?真不一定。如果是付费用户,那么他们是公司账上销项对应的一方,他们算首要的 stackholder。如果用户是免费使用公司服务,那么应该把他们看做产品/服务的一部分,把他们看做产品/服务的资源,而不是 stackholder。既然是资源,能为己所用就可以;既然是产品的一部分,只要产品不散就可以。不需要过多考虑免费用户的诉求和偏好。 有些免费产品讲情怀,前提是他们活着不成问题。没干爹可抱的企业,先把自己的财务账算清楚,努力维持公司现金流为正,先有资本活下去,才是正道。别人在山顶为踏足云顶做赋,那是情怀,你在山底谈云,那是浮云。 5. 架构不止『偏技术』,不是每一名架构师都需要『偏管理』的搭档 架构师的责任,是交付能够让至少大多数 stakeholder 满意的架构方案,并且落地执行,交付一个 predictable 的结果。……

阅读全文

Mac 下 VirtualBox 系统扩展不兼容的错误修复

Mac 上升级 VirtualBox 6.0.8,遇到一个报错,一直搞不定。大意是 system extension incompatible。提示框不是 warning 或者 error 图标,就是普通的 performance 图标,而且只出现一次,再安装,不会出现。 网络上没有结论,大多是说在 Performance 里面做安全授权。然后我遇到的并不是这个问题,Performance 里面没有授权提示。于是自己试着用降级的办法,安装 5.2.30,还是不行,同样的错误。再降级,到 5.2.28,终于行了,安装成功。 打开 5.2.28,发现有个提示,说有磁盘镜像失效,打开管理工具,发现是之前装的 Nox,在 VirtualBox 的配置中写入了 Nox 自己的镜像。卸载 Nox 的时候,Nox 没有从 VirtualBox 的配置中删除 Nox 的磁盘镜像。于是手动确认删除 Nox 相关的两个镜像。再进入 VirtualBox 就好了。 今天忽然想起来,也许就是因为失效镜像,导致升级失败呢。于是再安装 VirtualBox 试试。果然,就行了。 结论 对 VirtualBox 的失效镜像,一定要自行观察,手动清除,不能听之任之,容易造成潜在的问题。有一些模拟器啥的,安装的时候容易,卸载的时候麻烦,只能靠自己多留个心眼。……

阅读全文

hexo 又成了技术流的玩具

其实写这篇文章,心情不太痛快。hexo 是我找了好久才确定下来,能用 markdown 写 blog 的系统。之前试过的如 jekyll 太复杂,而且定制化程度太低,不灵活。刚开始用 hexo 的时候发现它简直是尤物,轻便简洁,扩展性还不错,官方收录了很多 plugins,足够码农用了。 结果没过几年,hexo 也快成了技术流的玩具。 问题一。npm 依赖存在缺陷 首先是 "hexo@3.8.0" 某个依赖 "hexo-fs@0.2.2",后者依赖 "chokidar@1.2.7",而 chokidar 又依赖 "fsevents@1.1.3"。好了,最后这个 "fsevents@1.1.3" 是被 deprecated 的版本,包含原生库,已经不存在 binary 下载,从源码编译也会报错。错误的大意是跟 node 的版本不兼容。 下面我把这个关系链重新理一下。 graph LR; A["hexo@3.8.0"]-->B["hexo-fs@0.2.2"]; B-->C["chokidar@1.2.7"]; C-->D["fsevents@1.1.3"]; D-->E["(HELL)"]; 除了上面的问题以外,大量已经停更的 plugins 依赖的 "hexo-cli@1.0.3" 等旧库,也多对 "fsevents@1.1.3" 存在间接依赖。 用一句话来说后果,在 MacOS 下,用 hexo-cli new + npm i 的方式,根本安装不上 hexo。 问题二。插件的停更、老化 像上面提到的,停更的插件,其间接依赖的第三方库若是被废弃,插件本身也就不可用了。这是一种情况。 第二种情况,hexo 本身在发展,某些停更的第三方插件没有跟着做适配,结果是 hexo 的使用体验受到了影响。 第三种情况,最常见的。哪怕是官网列表中的插件,质量也是有高有低,对那些技术不灵光的用户实在麻烦。 解决方法 针对安装不上的问题。我也不知道怎么解决 :( 我用撞大运的办法,hexo-cli new 一个项目以后,手动修改 package.……

阅读全文

不过时的技术

最近两天被极客时间的新课刷群刷屏。刷屏的标题大多是“学了这么多年 Java,却连 singleton 都不会用”、“面试总被问高并发,你真的会么”这一类标题党。内容千篇一律是推荐极客时间打新的课程,《Java 并发编程实战》。 高并发哥又不是没做过,随手找了一下,发现陈皓在 2009 年的一篇文章就提到了正确的解法,以及背后的原因。《深入浅出单实例 SINGLETON 设计模式》。 文中给出几种功能上正确的 singleton 写法。 // version 1.4 public class Singleton { private volatile static Singleton singleton = null; private Singleton() {} public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton== null) { singleton= new Singleton(); } } } return singleton; } } 请留意私有变量的描述词 volatile,目的是不让编译器对指令进行重排序优化。 // version 1.5 public class Singleton { private volatile static Singleton singleton = new Singleton(); private Singleton() {} public static Singleton getInstance() { return singleton; } } 这是自动加载版本。每次加载类的时候,实例就生成了。所以加载类的过程可能会很慢(特别是有很多继承、引用的情况)。……

阅读全文

固态硬盘和优盘不是稳健的数据存储介质

说到固态硬盘(SSD)和优盘,恐怕很多人心里面有个潜在的印象,就是数据放在这里面,很安全,比在机械硬盘里面安全。最近两个朋友找我,帮找恢复数据的解决方案。两位都是数据放优盘或移动硬盘里面,遇到存储芯片故障。 其实长期不用的数据,放在固态硬盘里面,真的不一定是安全的。固态硬盘的存储原理是往浮栅晶体管上加/放电子,使晶体管的通电性能发生变化,形成通路/闭路,对应数字 1/0,从而达到记录数据的目的。这里就有个问题,浮栅中的电子会存在泄漏的情况,也就是说,记录的数据会丢失。通常,这种数据的丢失受电压(包括静电)、环境温度、以及存储时间的影响。希捷曾经有工程师在报告中讲,温度每上升 5 摄氏度,数据存储的时间就短一半。不通电不读写的情况下,保存在 Nand Flash(SSD、SD Card、TF Card、U Disk……)介质中的数据最多也就两年的存储寿命。最糟糕的情况是像移动硬盘、优盘这样的设备,插入电脑 USB 口的一瞬间,假如遇到静电,Nand Flash 芯片被瞬间高电压击穿,那不管当时环境温度多少、你有没有经常使用,你的数据都完蛋了。 记住,要保存数据,一定用机械硬盘。这是目前最稳妥的方法了。机械硬盘丢数据的风险,都是可以人为规避的。保存得当,存里面的数据,保存十年二十年没问题。不要再傻傻被 SSD、优盘骗了。等到数据都恢复不回来,再后悔。……

阅读全文

MacOS 下安装 flutter 遇到的一个依赖问题

最近在 MacOSX 上安装 flutter 也遇到一些问题。不是 MacOS Mojave 的问题,而是 flutter 依赖的一个开源库,它的依赖树出现版本不兼容问题。 运行 flutter doctor 出现如下提示。 [!] iOS toolchain - develop for iOS devices (Xcode 10.0) ✗ libimobiledevice and ideviceinstaller are not installed. To install, run: brew install –HEAD libimobiledevice brew install ideviceinstaller ✗ ios-deploy not installed. To install: brew install ios-deploy ✗ CocoaPods not installed. CocoaPods is used to retrieve the iOS platform side’s plugin code that responds to your plugin usage on the Dart side.……

阅读全文

CentOS7 下安装 DNF 的方法

NOTE(simon): 讲啰嗦一点,方便搜索引擎收录关键字。需要解决方案的同学,可以直接拖到后半部分。 旧办法不灵 不知道什么原因,CentOS 7 下面安装 dnf 总是要出错,各种各样的问题与不兼容。CentOS 直到现在,还没有正式支持 dnf。相反,Fedora 22 开始就已经正式支持 dnf 作为默认的包管理工具了。差距啊。 之前试过用一个半官方的 dnf repo(rpmsoftwaremanagement/dnf-nightly Copr) 在 CentOS 7 下面安装 dnf,一直都是可以的。也可以正常升级。以前通过这个办法安装过 dnf 的系统,已经升级到 2.8.5。用起来很顺。 但是不知道为什么,最近用这个库,在全新的 CentOS 7 下面安装 dnf,遇到一个麻烦,就是包版本有冲突。类似的错误信息如下。 # yum install -y dnf-2.8.5-0.101g0f20917d.el7.centos Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: mirrors.shu.edu.cn * epel: mirrors.yun-idc.com * extras: mirrors.163.com * updates: mirrors.163.com Resolving Dependencies --> Running transaction check ---> Package dnf.noarch 0:2.8.5-0.101g0f20917d.el7.centos will be installed --> Processing Dependency: python2-dnf = 2.……

阅读全文

MacOS 下 flutter run 遇到墙的问题

最近调研 flutter,甚是大爱。 虽然 flutter 非常友好提供了针对中国用户的镜像(Using Flutter in China · flutter/flutter Wiki · GitHub),解决了一些不可说的难题,但偶尔还是会遇到类似的问题。比如我今天就遇到了,在 VS Code 调试编译的时候,遇到 “Download Failed” 的问题。Could not resolve all files for configuration ':image_picker:lintClassPath'. 具体原因是 Connect to d29vzk4ow07wi7.cloudfront.net:443 [d29vzk4ow07wi7.cloudfront.net/13.33.69.104, d29vzk4ow07wi7.cloudfront.net/13.33.69.3, d29vzk4ow07wi7.cloudfront.net/13.33.69.38, d29vzk4ow07wi7.cloudfront.net/13.33.69.111] failed: Read timed out 。 原来是碰上了墙外面的老朋友,CDN 服务商 cloudflare 的域名。 中间还是比较曲折,最后解决的办法是用 proxychain4 解决问题。 brew install proxychains-ng sed -i '.bak' 's@^\(socks4.*\)@#\1@g' /usr/local/etc/proxychains.conf echo -e "socks5\t127.0.0.1 1080" >> /usr/local/etc/proxychains.conf proxychains4 curl ip.gs 等等,好像不对,IP 是本市的。 $ proxychains4 curl ip.gs [proxychains] config file found: /usr/local/etc/proxychains.……

阅读全文

CoreDNS - 轻量级高性能的 DNS 服务在 MacOS 下的安装部署

DNS 的原理相信大家都了解。树形结构,根服务器,递归溯源,UDP 协议(现在也有 TCP 协议甚至 http 协议的)。搭建一台自己的 DNS 也是稀松平常的事情。 我遇到的场景是这样的。 公司有内网机房,研发用,研发环境和测试环境都在内网机房; 公司的域名是『company.com』,在公司内网有专门的 DNS(bind 搭建)做解析; 研发/测试环境的服务器也用顶级域名指向,例如:test1.mod-a.company.com。这类解析都是通过 bind 实现的。公司外网解析不到这个地址; 我自己需要一个安全的 DNS 环境,对 DNS 服务器溯源这个细节,优选 TCP 协议; 对『company.com』顶级域名的解析还是走公司内部的 DNS 服务器,即 bind; 之前用 ss 的 chinadns,可以实现第 4 条,但是无法实现第 5 条。 找了一圈,发现 CoreDNS 挺好的。推荐之。 一、安装 CoreDNS 是 golang 写的,所以只需要下载对应操作系统的二进制文件,到处拷贝,就可以运行了。 下面统统以 MacOS 为例作讲解。 cd ~/Downloads curl -LO "https://github.com/coredns/coredns/releases/download/v1.1.2/coredns_1.1.2_darwin_amd64.tgz" && \ tar zxf coredns_1.1.2_darwin_amd64.tgz && \ mv ./coredns /usr/local/bin/ 这里补充一句,CoreDNS 的二进制版本已经安装了所有的插件(plugins),不需要你自己编译。推荐下载二进制版本。 二、配置 要深入了解 CoreDNS,请查看其文档,及 plugins 的介绍。……

阅读全文