xml地图|网站地图|网站标签 [设为首页] [加入收藏]
不可变基础设施,Google新logo是如何缩减13000字节
分类:web前端

图片 1

图片 2

本文出自:JamesonQuave.com,作者:Jameson Quave,译文出自:SwiftGG,译者:mmoaay在Objective-C中我们经常会用到指针,有些方法也需要直接去操作指针,今天我们就来看看如何在Swift中使用指针。在Swift中读C指针下面这个Objective-C方法会返回一个int指针,或者说C术语里面的(int *):

原文链接:Quora 译者:杰微刊—程慧编者按:有人在Quora上提问:Google的新logo是如何做到只有305字节的?旧logo的大小有14000字节之多。来自多伦多的UI设计师Ilya Yakubovich的回答1万+的投票。以下是杰微刊对其回答的完整译文。 之前的logo采用的是较为复杂的serif字体,它只能通过贝塞尔曲线来构建。这样的话总共会有100个锚点,结果产生的就是一个6KB的文件。而压缩之后能达到2KB。新logo是一个简化的版本,也就是说,几乎可以完全通过圆形和矩形来构建。整个logo包含:① 10个圆形② 5个矩形③ 1个由7个锚点构成的形状 虽然Google尚未发布新版本的305字节的logo,也不太可能在网上出现,但是我相信他们的logo会如预期一般,降至305字节。为了验证这一点,我采用SVG格式试着创建了第一个字母G,结果产生的是一个302字节的文件,压缩之后是195字节。下面是整个未压缩版的绘图过程,包括两个圆形和两个矩形:

同一套软件系统在部署与运行过程中,常常会因为依赖组件版本、运行时间及人工干预等多种因素引发运行结果差异,造成不必要的损失。要消除这种影响,其中之一就是推行“不可变基础设施”保证其一致性。什么是不可变基础设施在开始本文之前,先介绍下什么是不可变基础设施。不可变基础设施是由Chad Fowler于2013年提出的一个很有前瞻性的构想:在这种模式中,任何基础设施的实例一旦创建之后便成为一种只读状态,不可对其进行任何更改。如果需要修改或升级某些实例,唯一的方式就是创建一批新的实例以替换。这种思想与不可变对象的概念是完全相同的。当然在很多年以前这个概念是得不到技术支持的,我们很难在不同的物理机上实现软件的不可变。不过随着虚拟化技术以及云计算的发展,现在这已经变得可能了。我们更多的时候,面对的不是一台台的物理主机,更多的是云主机实例。安装一个操作系统也不需要几小时,而只需要鼠标点几下,等上两三分钟即可。重装系统这个概念已经不存在,删掉一个主机实例我们也不会心疼。实现这种模式的好处是显而易见的,这意味着配置工作可实现重复性,减少了配置管理工作的负担,让持续集成与持续部署过程变得更流畅。同时它也更易于应对部署环境间的差异及版本管理,包括在部署出错时可进行快速回滚 —— 只要旧版本的镜像文件还有备份,就可以快速地生成旧版本的实例进行替换。否则的话,就只能老老实实地重新构建旧版本的实例,并且祈祷能够赶在老板掀桌之前完成回滚。不可变基础设施令人兴奋的事情之一是:它让我们有机会重新审视一些旧的方式,并改进它们。其中之一是“漂移”——不同机器间的差异。造成这一问题主因有两个:延迟配置与更新。二者都会随着时间加剧。不同机器被设置的时间越久、存在的越久,就越有可能碰到漂移的问题。让我们依次来看看这些问题。为什么漂移是个问题?首先要回答的是:为什么漂移自身是个问题?或者换个说法:为什么拥有一模一样的机器很重要?在软件系统中,减少风险的主要方式之一是测试。手工和自动测试都依赖于相同的三个步骤:将系统置于一个已知状态执行一个动作将结果与预期做比较将系统置于一个已知状态不仅适用于数据,也适用于所有安装的软件组件版本。一旦系统被正确设置,测试将验证X版本代码运行于Y版本平台且具有Z版本库的正确性。所有其他组合都是未知的,必须单独验证。也就是说,无法保证同一版本代码与旧版或新版平台和库组合时能同样工作,因为旧版本可能存在BUG,而新版本可能有回归或细微的变化。为了让测试中的投入有所价值,必须保证系统及所有组件版本处于已知状态,以便能简单且安全地在机器和环境间复制。简单而言,要保证东西能工作,必须在生产环境中运行在测试环境中所测试的东西。这同样适用于单一环境。如果在负载均衡器后有多台机器为客户端提供服务,要保持工作正常,这些机器必须完全一致。延迟配置的问题你可能会觉得这很容易通过使用一些可靠的配置机制来解决。不管你喜欢什么脚本或配置管理工具,这并没有看起来那么容易。问题在于包管理器的常见使用模式及中央仓库的更新时机。当你使用类似这样的命令时,问题就出现了:

@interface PointerBridge : NSObject { int count;}- (int *) getCountPtr;@end @implementation PointerBridge- (instancetype) init { self = [super init]; if(self) { count = 23; } return self;}- (int *) getCountPtr { return count;}@end
svgxmlns=""circle r="100" cy="100" cx="100" fill="#4885ed"/circle r="70" cy="100" cx="100" fill="#ffffff"/rect transform="rotate(-40 166,67)" height="78" width="99" y="27" x="117" fill="#ffffff"/rect height="30" width="88" y="87" x="111" fill="#4885ed"//svg
 sudo apt-get install mypkg

上面的代码定义了一个PointerBridge类,它包含getCountPtr方法,这个方法返回一个值为23的int型内存地址。 这个Int其实是count的实例,它在构造方法init中被赋值为23。我把这段代码放在一个Objective-C的头文件中,然后把这个头文件import到我的桥接头文件中,这样就可以在Swift中使用。然后我在Swift中创建一个名为bridge的PointerBridge实例,然后获得getCountPtr() 方法的返回值…

这样就产生了下面右边的图形:另外有一位用户指出,还有一种途径可以创建出新的logo,它是采用笔画的方式来完成,而非填充的方式。这也是之前的老logo没法实现的,这种方法甚至可以带来更小的文件。整个logo的代码共290字节:

为了更好的展示为什么这是个问题,请看这个简单的例子:三台机器在不同时间使用同一配置脚本进行设置:正如你所见,虽然所有机器都安装了A和B包,配置时间的不同造成了同一脚本将同一个包的不同版本拉取到不同机器上。系统的稳定性与中心仓库里每个包的更新计划密切相关!镜像是解决之道解决这个问题的办法之一是将所有包及其依赖项固定到一个特定版本上。虽然这让你得以重新控制系统的更新计划,也带来了高昂的维护成本。一个更简单、更可靠的办法是听从真言:只做一次构建。要消除环境间的差异,构建的产物应在尽可能低的层次上捕获应用及其依赖项。在虚拟基础设施中,尽可能低的层次可以简单的是整个机器的镜像。然后,你就能创建出你所需要的完全一致的实例:镜像使得创建相同主机变得简单,但并没有解决所有问题。一旦有机会登录,你就失去了这些主机不随时间发散的保证:这些主机存在的越久,东西被修改的可能性就越高,也就越难被完全的重建。这在很大程度上消减了其带来的益处。强制不可变性那么,如何弥补这点?那就是禁止登录。这不仅解决了漂移问题,还能减少受攻击面从而提高安全性。在此之上,它还强制你遵循一个干净的以镜像为基础的工作流,杜绝后门。欢迎加入拒绝SSH的运动来推广所有这些优势:现在,你的基础设施已经不可变了。所有的修改都要求通过常规的自动化构建与部署管道来重新构建新的镜像。作为回报,系统的简单性和可靠性将大幅提升。非常值得一试。结论漂移通过侵蚀测试中得到的保证,降低了系统的可靠性。而这点在依赖传统配置工具时非常容易发生。迁移到能在尽可能低层次捕获应用及其依赖的构建与部署管道上,你将重获这种信心。在处理虚拟硬件时,达成这点最好的方式是产出整个系统的镜像。要保证这个过程的可靠性,你需要消除SSH和登录能力。镜像和基础设施不再可变。所有的修改都会触发新镜像的产生,且针对所有环境只构建一次。原文链接:Immutable Infrastructure: No SSH

let bridge = PointerBridge()let theInt = bridge.getCountPtr()print(theInt)print(theInt.memory)
svgxmlns="SVG namespace" width="600" height="250"g stroke-width="16" fill="none" path d="M173 102a51 51 0 1 1-13-30m20 37h-53" stroke="#4a87ee"/ circle cx="227" cy="128" r="32" stroke="#d83038"/ circle cx="313" cy="128" r="32" stroke="#f4c022"/ path d="M401 160a31 31 0 1 1 0-61m-4 0a24 29 0 1 1 0 61m26-67v79m-1-12a20 20 0 1 1-52 17" stroke="#4a87ee"/ path stroke="#4ab95a" d="M449 51v115"/ path d="M529 118a30 30 0 1 0-2 24m5-32l-62 28" stroke="#d83038"//g/svg

在Xcode中按住Option键点击theInt检查它的类型,你会发现他的Swift类型是UnsafeMutablePointerInt32。这是指向Int型的指针,和Int型不一样,它仅仅是指向它的指针。如果运行这个程序然后执行这段Swift代码,我们会发现theInt在命令行中输出类似0x00007f8bdb508ef8这样的内存地址,然后,然后我们会看到memory成员变量输出的值23 。访问指针指向的内存通常返回其底层指向的对象,在这个例子中就是原来的32位int。现在让Objective-C类支持设置count的值。

通过这种方法,整个logo用两个圆圈和四条路径就可以绘制完成。

@interface PointerBridge : NSObject { int count;}- (int *) getCountPtr;- (void) setCount:(int)newCount;@end @implementation PointerBridge- (instancetype) init { self = [super init]; if(self) { count = 23; } return self;}- (int *) getCountPtr { return count;}- (void) setCount:(int)newCount { count = newCount;}@end

我们可以调用setCount()方法来修改count的值。因为theInt是一个指针,所以通过setCount修改count也会更新theInt.memory。别忘了内存地址是不会变的,变的是值。也就是说,下面的代码会在命令行中打印数字23, 然后打印数字1000。

本文由澳门新葡亰手机版发布于web前端,转载请注明出处:不可变基础设施,Google新logo是如何缩减13000字节

上一篇:干什么自个儿着迷于动作效果设计,品质周围F 下一篇:没有了
猜你喜欢
热门排行
精彩图文