分类 观点 下的文章

是什么造就了一个优秀的程序员?首先问问你自己吧,这会是个有趣的问题。它让你反思自己的软件开发技术。这个问题也适合问问你的同事们。它可以带来一些关于如何协同工作的有趣讨论。下面是我认为成为一个优秀程序员必备的五个重要技能。

1. 分解问题

编程是为了解决问题,但在你开始写代码前,需要明白如何解决问题。优秀程序员的一项技能是把大的问题逐层分解成一个个更小的部分,直到每一部分都可以很容易解决。但找到解决问题的方式往往并没有那么简单。优秀程序员能找到方法去建立问题模型,这种方法使得输出结果的程序容易解释、实现和测试。

我写过的某些最复杂的程序在局部上都是难懂的,因为代码实现并不能很好地匹配这个问题,也就导致了编写的代码难以理解。当问题很好地建模的时候,我赞同伯尼·科赛尔所说的话(取自著名的程序员在工作中的访谈记录):

“……很少有本质上很难的程序。如果你盯着某一块代码,它看起来确实很难;如果你无法理解这段代码应该产生什么结果,这基本上就是暗示它很难被理解了。在这个时候,你不应该卷起袖子,尝试修复代码;你需要只是往回一步,再仔细考虑清楚。当你已经深思熟虑后,你会发现问题变得很简单”。

2. 场景分析

优秀开发者能考虑到如何使程序适合多种不同的场景。这项能力既适用于处理程序本身的逻辑,又适用于处理可能会发生的外部和内部事件。为了考虑逻辑上的不同思路,他们问自己这样的问题:如果这个参数为空会发生什么?如果所有条件都为假呢?这个方法在线程上是安全的吗?为了发现软件需要处理的各种类型的事件,他们问自己这样的问题:如果队列占满了会怎样?如果请求收不到响应会怎样?如果在这台服务器重启的同时另外一台服务器也重启了会怎样?

优秀程序员问他们自己:如何发现程序的缺陷?换句话说,他们有能力像测试人员一样思考。相反,缺少经验的程序员通常只考虑正确的路径——在一切都按照预期进行时正常的控制流(当然这也是程序在大部分时候的情况)。当然,异常不可避免要发生,所以需要程序能处理这些情况。

3. 命名

编程由大量的命名对象组成:类、方法和变量。当编码完成得很好时,程序也具备了自我描述的能力,也就是说通过阅读源代码可以清楚地明白程序中函数的含义。自描述代码的一个好处就是很自然地产生许多更短的命名方法,而不是少数更长的方法,因为你有更多空间去放置有意义的名字(还有其它原因解释为什么短小方法更好)。

想出好的名字比它听起来更困难一些。我喜欢这段引用(来自菲尔·卡尔顿):“在计算机科学领域只有两件困难的事情:缓存失效和命名对象。”命名在一定程度上很困难是因为你需要清楚地明白每一个名字究竟要代表什么。有时候命名不是一下子就清晰明了,只有随着软件开发进展才会慢慢显现。因此,重命名和命名一样重要。

命名对象也包含提出要用的概念和这些概念该如何称呼。通过深思熟虑,清楚命名所使用的惯用概念(在程序中和与程序员、非程序员讨论时使用),这使得编写程序变得更加容易。

4. 一致性

也许编程中最大的挑战是管理复杂性。保持一致性是处理复杂性的一种方法。它通过允许我们看到对象命名、使用和处理所采用的模式和推理来降低了某些复杂性。有了一致性,我们就无需用脑去记住异常和随机变量。取而代之,我们可以更关注程序本身的复杂性,而不是偶然产生的复杂性

保持一致性从整体看来是很重要的。它应用在变量名字和分组、方法命名、模块划分、目录结构、GUI、错误处理、日志输出和文档等很多方面。比如,如果某些变量是的相关,并一起出现(在声明、方法调用或数据库中的列),而且总是以相同的顺序使用它们。那么当其中一个消失或者整体被打乱时,你就会很容易发现。对于一个操作,如果在一个地方叫delete,就不要在另一个地方叫remove:务必使用相同的名字。史蒂夫·麦克奈尔在代码大全中对于使用相反命名有相同的建议。比如,begin和end是相反的,就如同start和stop一样。当使用相反对时不要混用不同对的名字(比如使用begin和stop)。

当修改一段程序时可能会引入非一致性。粗心大意的程序员不会注意到他们添加的代码是否和已有的代码保持一致。优秀程序员会严苛地确保在这些看似很小的细节上都要做到精益求精。他们知道保持一致性对于在软件开发的整个过程中处理复杂性是多么的重要。

5. 学习能力

作为一名软件开发者,你需要持续学习。在为软件添加一项新功能前,你必须明白为什么要这么做。在给一个已有程序添加代码前,你通常必须知道已有代码在做什么,以便合适地嵌入新功能。你还需要学习相关系统,以便正确地与它们交互。因此,快速学习的能力使你成为一名更加高效的开发者。

而且,因为软件工程领域的开发速度是如此的快速,所以新的编程语言、工具、技术和框架需要学习层出不穷。这是好还是坏,就看你怎么看。佛瑞德·布鲁克斯把学习能力列为技能的快乐之一,对此我深表赞同。学习新事物本身就是令人心满意足的,它也意味着开发者的生活从不无聊。

总结

上面所有的技能都是通用的——它们中没有一项是针对某种语言、某个框架或某种技术。如果你拥有它们,你就能快速学习一门新的语言或工具,在新的环境下写出优秀的软件。而且,因为它们在本质上是通用的,所以不会在若干年以后过时。

是什么造就了一个优秀的程序员?以上便是我的观点。你认为造就一个优秀程序员的因素有哪些?在评论里告诉我吧。


via: http://henrikwarne.com/2014/06/30/what-makes-a-good-programmer/

作者:Henrik Warne 译者:KayGuoWhu 校对:Caroline

本文由 LCTT 原创翻译,Linux中国 荣誉推出

安卓0.9显示着横屏的主屏幕——后续一些版本无法实现的一个特性。

安卓 0.9 显示着横屏的主屏幕——后续一些版本无法实现的一个特性 [Ron Amadeo供图]

尽管从功能上很难将模拟器和操作系统区分开,但安卓 0.9 是第一个支持横屏显示的版本。更让人惊讶的是,几乎所有东西都支持横屏模式,在某些方面安卓 0.9 甚至做的比 KitKat 更好。在 Kiakat 中,主屏幕和拨号被锁定为竖向并且无法旋转。但在安卓 0.9 这里,对任何一个应用横向显示都不是问题。(有谁知道怎么把 Nexus 5 从 Kitkat 升/降级到安卓 0.9 吗?)

截图同样显示了安卓 0.9 中的新的音量显示设计。它抛弃了在 Milestone 3 中初次登场的旧铃铛式控制界面。那是一个巨大的,充满屏幕的界面。实际上,安卓 4.0 的重新设计中让它变得更小了,但它仍然是个问题。(你想增加音量却因此没法看到视频了这种情况特别烦人。)

新通知面板,抛弃了应用快捷方式并添加了顶部部分。

新通知面板,抛弃了应用快捷方式并添加了顶部部分 [Ron Amadeo供图]

几乎每个安卓版本中的通知面板都有一定的调整,安卓 0.9 也不例外。电池电量图标进行了重绘,变成了黑底绿色图标,其它的状态栏图标变为黑色,白色以及灰色。状态栏左侧部分明智地选择在通知面板打开的时候显示日期。

通知面板加入了一个新的顶部部分,它能够显示运营商名称(在模拟器里显示“安卓”),以及一个巨大的写着“清除通知”的按钮,它能够让你不用打开应用而彻底清除通知。应用程序图标被取消了,替换为通知到达的时间,“最新事件”文字被更换为简单的“通知”。面板的空白部分现在是灰色的而不是之前的白色,底部的滑动条也进行了重新设计。上面两张图片的底部看起来并没有对齐,但这是因为 Milestone 5 的通知面板在面板底部有一圈空白。安卓 0.9 的通知面板是完全直达底部边缘的。

安卓0.9和0.5的浏览器,展现出新的无色彩菜单。

安卓 0.9 和 0.5 的浏览器,展现出新的无色彩菜单 [Ron Amadeo供图]

浏览器主页现在是加载一个真正的网站,而不是像 Milestone 5 中那样的本地存储的假 Google 页面。Webkit 的版本升至 525.10,但是看起来它似乎没法正确渲染更现代的 Google.com 搜索按钮。纵观安卓 0.9,Milestone 5 中的菜单设计已经被抛弃,取而代之的是重新设计的灰色图标。这些截图的区别十分的明显,因为所有的颜色都被去除了。

“更趋向于”列表式的菜单变得更高了一点,并且只是一个没有图标的列表而已。安卓 0.9 已经获得了其它搜索方式,这次是在浏览器菜单里。和主屏幕小部件,主屏幕菜单按钮,以及浏览器主页,它们共同组成了四个搜索框。谷歌从未隐藏它的主要业务是什么,就连在它的操作系统中也是这样。

从左到右:安卓0.9的浏览器缩放控件,页面内搜索界面,浏览器窗口,以及设置。

从左到右:安卓 0.9 的浏览器缩放控件,页面内搜索界面,浏览器窗口,以及设置 [Ron Amadeo供图]

安卓 0.9 带来了许多浏览器改进。谢天谢地缩放控件又能正常使用了,而且从疯狂的垂直控制变成了简单的加减按钮。谷歌做了个符合常识的决定,将缩放控制从屏幕中间移到了屏幕底部。在这些缩放控件中,安卓在一致性方面的努力显而易见。这些看起来是系统中唯一的圆形按钮。

安卓 0.9 中的新特性“页面内查找”会高亮显示页面内的关键词。但总的来说,UI 还是十分粗糙的——文本框比它应有的高度高了许多,“完成”按钮带的勾选框对这个页面来说只是一种图标而已。“完成”基本上是个“关闭”按钮,这意味着它也许应该是个右对齐的“X”按钮。

这个版本的系统没有设置界面,但是浏览器最终还是有了自己的设置界面。它会有个桌面式选项的弹窗,Javascript,隐私和 cookie,保存的密码以及表单数据。甚至还有 Google Gears 整合(还记得 Google Gears 吗?)。

拨号盘以及打开菜单的正在通话界面。

拨号盘以及打开菜单的正在通话界面 [Ron Amadeo供图]

拨号和联系人在安卓0.9中实际上是同一个应用——两个图标只是打开不同的标签而已。将联系人像这样附到拨号盘表明了智能手机联系人的第一目的还是通话,不是短信,电子邮件,即时通讯或查找地址。最终谷歌还是会完全接受非传统的智能手机沟通,将联系人和拨号分为两个独立的应用程序。

Milestone 5中大多数拨号盘的缺陷在安卓0.9中得到了修复。“最小化”标签被一组正常的亮/暗标签替代。对话气泡式的退格键被替换为正常的退格图标并集成到了拨号数字显示界面。数字键变成了圆形,尽管这个系统的其它东西是圆角矩形的(至少这次文本是垂直对齐的)。谷歌还修复了Milestone 5中“-”键,“*”键和“#”键不平衡的问题。

在安卓0.9中点击显示的号码会开始一个通话。这是十分重要的,因为这是摆脱安卓设备硬件实体“拨号”和“结束”键的一大步。另一方面,来电界面却走的是完全相反的道路,去除了在安卓0.5中显示于屏幕之上的“接听”和“拒绝”按键。谷歌会花上接下来几个版本的时间去摸索在特定的显示之下是否需要硬件实体拨号键。但是直到安卓2.0和摩托罗拉Droid面世,实体拨号按钮才最终变成了可选选项。

来电界面的所有选项隐藏在目录按钮之后。Milestone 5不支持距离传感器,所以它采取了简单粗暴的路线,在通话过程中禁用触摸屏。安卓0.9为G1开发,它有个距离传感器。最终谷歌没有在通话的时候禁用触摸传感器。

安卓0.9和0.5中独立的联系人界面和联系人编缉界面。

安卓 0.9 和 0.5 中独立的联系人界面和联系人编缉界面 [Ron Amadeo供图]

Milestone 5 的一些联系人信息有令人困惑的标签,像电子邮件只被打上“主要的”标签而不是“主电子邮箱”标签。安卓 0.9 用各部分的水平标题纠正了这个错误。而且现在左侧的每个联系人类型都有了 手形图标 Action icons

编缉联系人界面如今是个更加繁忙的地方。每个输入框都有删除按钮,特定联系人铃声,一个显示在屏幕上的“更多信息”按钮用来添加输入框,一个是否将通话直接发送到语音信箱的复选框,以及在列表底部的“保存”和“放弃修改”按钮。从功能上来说,相对于旧版本这是个巨大的进步,但它看起来仍然很混乱。


Ron Amadeo / Ron 是Ars Technica的评论编缉,专注于安卓系统和谷歌产品。他总是在追寻新鲜事物,还喜欢拆解事物看看它们到底是怎么运作的。@RonAmadeo


via: http://arstechnica.com/gadgets/2014/06/building-android-a-40000-word-history-of-googles-mobile-os/4/

译者:alim0x 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

Systemd 是目前为止在Linux平台上最有争议的项目之一。它到底有多大的争议?它的争议大到systemd的开发者之一Lennart Poettering 声称有人使用比特币雇佣职业杀手要干掉他。但是还是有比较理智的做法的,有一个抵制systemd网站在技术角度上提出了抵制systemd的原因。

如此强烈的抵制也反映了systemd的成功。它已经被或将要被Fedroa、OpenSUSE、Ubuntu、Debian、Arch Linux等众多发行版采用。随着时间推移,GNOME越来越依赖它,Debian回归GNOME的原因之一就是它采用了systemd。systemd无处不在!

那么如此激烈的争论到底是关于什么呢?让我们近距离观察这场战争。

Systemd是一个全新的init

Systemd的核心是取代老旧的SysV init。init用来初始化你的操作系统,当你启动系统时,init负责加载需要的驱动,激活你的网络链接,启动众多的系统服务,最后进入图形登陆界面。而SysV init 是一个老旧的系统,它基本上仅运行/etc/init.d目录下的一些脚本。

Systemd是一个现代技术,用以取代老旧以及粗糙的SysV init。它可以在接收到事件响应时启动相关服务;比如,当你接入了一个USB打印机,systemd可以在接收到设备接入响应时启动打印服务。当它接收到某个网络端口的连接请求时,它可以启动在此端口上监听的服务并且传递这个连接。

获取更多关于SysV init 与 systemd的信息,可以参考Jorgen Schäfer的 “Why systemd?

但是systemd远不止此

systemd的反对者之中也有部分人认为SysV太老了,应该被取代掉。但是批评systemd的人发现Systemd是一个巨大的项目,其中包括了很多其他的功能。它是一个软件套件,而不仅仅是一个init。

An illustration of systemd's structure.

维基共享资源 systemd 结构图解

Systemd包括用于管理用户登陆的守护进程logind,还包括journald,并且journald 颇有争议的使用了二进制形式保存系统日志而不是以文本形式。systemd也采用了udev的思想及代码,它对/dev/目录下的虚拟设备文件进行管理,并且处理设备接入或推出时所产生的事件。除了这些还有很多其他的,如:systemd还包括了cron风格的任务调度器与网络守护进程networkd等等。

抨击者认为systemd不是类UNIX风格

多数的抱怨源于人们认为systemd项目太大以至于超出了它的工作范围,并且它从Linux系统接管的部分太多了。不要感到惊奇,systemd的抵制活动是以下面的抱怨开始的:

"systemd文件是一大堆的复杂的高度耦合的二进制组成的,这违反了UNIX哲学:‘做一件事情,并把它做好’。它超出了一个init程序的职责范围,因为它还有电源管理,设备管理,挂载管理,cron(定时执行工具),磁盘加密,socket接口/inetd,syslog,网络配置,登陆/会话管理,文件预读,GPT分区发现,容器注册,hostname/locale/time管理,mDNS/DNS-SD等功能,它将Linux控制台以及其他的一些功能都包装在一个程序里面。

那么,systemd是好是坏?

到这里,我判断一下,到底谁是正确的。

systemd最初的想法是非常好的。Linux需要一个新的东西来替换老的 SysV init 和沉重的 SysV init 脚本,这个新的程序应该是灵活的,现代化的系统守护进程,它可以响应更多类型,并且智能化的管理众多的守护进程。然而,事实上systemd好像成为了一个仅依赖Linux核心的完全统一的系统层

但是,尽管Linux是一个社区开发项目,但它不是为PC世界的专栏作家或者是一群网络评论者提供的,这些人都不能决定它的进化与发展。只有那些亲手贡献代码以及全身心投入的人才有这个资格。巧的是,Linux发行版以及那些参与者好像大部分都倾向与systemd。

'我对于systemd本身并没有很强烈的个人看法。我与核心开发人员争论过它的bug与兼容性,并且我认为它的一些设计是愚蠢的(比如二进制的日志),但这只是细节,不是大问题。

如果 Linus Torvalds 对于systemd的设计没有什么反对意见,那么说明它可能还是不错的。如果你想平静的看下为什么Linux发行版要使用systemd的话,我推荐这篇文章,Debian's systemd discussion document

你是如何看systemd的,可以在评论回复!但是请文明讨论。

更新这篇文章以澄清之前的错误的消息,ubuntu 桌面版将在下一个版本中纳入systemd。之前我们错误的认为ubuntu已经使用了systemd


via: http://www.pcworld.com/article/2841873/meet-systemd-the-controversial-project-taking-over-a-linux-distro-near-you.html

作者:Chris Hoffman 译者:SPccman 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

Ubuntu Kylin也许能在中国用来替代Windows

Windows操作系统将退出中国的前门,而它的位置将由一个Linux发行版替代,用于官方和政府部门。问题是目前还没有一个真正的可替代系统,尽管还是有一款操作系统也许已经准备接下这个任务,它就是Ubuntu Kylin。

至少可以这么说,中国政府和微软目前的关系很紧张。就像新闻里说的,一个用Linux类似系统在全国逐步替换Windows的计划已经在准备了。还不清楚具体会采用哪个系统,因为情况很复杂而且这是一个非常大的国家。

通常,这种问题没有一个普适的解决方案,而且中国的行动确实看起来有点呆板。不管怎样,这为Ubuntu Keylin打开了一扇巨大的机会之窗,它是一个基于Ubuntu由中国开发者和Canonical共同开发的发行版。它已经稳定一段时间了,而且已经发布了几个连续版本。

Ubuntu Kylin在敲Windows的大门

有趣的是,在这个关于中国意图的新闻冒出来的同一天里,发布了一篇对国防科技大学(NUDT)副教授Dr. Jonas Zhang的采访,关于最新的14.10分支开发计划

“在这次的14.10版本中,有许多很好的功能。比如,新手也可以轻松地通过Ubuntu Kylin软件中心找到Windows软件的替代;用户可以使用Ubuntu Kylin的SSO(Ubuntu Kylin的单一登录系统,我们叫它UKID)来登录到Ubuntu Kylin的软件和社区;Sogou输入法(一款世界知名的中文输入法,上个月已经在苹果的应用市场上线了)减少了40%的CPU和内存占用。”

“来自CSIP(中国政府的一个部门),超过50个 Canonical 和 NUDT(国防科技大学)的项目经理、工程师和社区管理员在为 Ubuntu Kylin 工作。大部分全职工程师来自NUDT。许多来自Ubuntu,Debian和其他社区的开发者也参与到Ubuntu Kylin的开发中了。”Dr. Jonas Zhang

中国政府也许自己也正想办法搭建另一个Linux发行版(不是第一次尝试了),但是目前看来已经有一个很好的用来替代Windows的候选者了。这对于Canonical也是很好的商机,至少从被承认这个角度看。

如果Ubuntu,通过它和Kylin的联系,想在像中国这样的大国里取代Windows,对这家公司将会是个巨大的促进。让我们拭目以待,看看开发者们让Ubuntu Kylin变成一个有竞争力的操作系统所花费的努力是不是白费力气。


via: http://news.softpedia.com/news/Ubuntu-Could-Give-a-Fatal-Blow-to-Windows-in-China-463500.shtml

作者:Silviu Stahie 译者:zpl1025 校对:Caroline

本文由 LCTT 原创翻译,Linux中国 荣誉推出

DockerAnsible 的技术社区内存在着很多好玩的东西,我希望在你阅读完这篇文章后也能像我们一样热爱它们。当然,你也会收获一些实践知识,那就是如何通过部署 Ansible 和 Docker 来为 Rails 应用搭建一个完整的服务器环境。

也许有人会问:你怎么不去用 Heroku?首先,我可以在任何供应商提供的主机上运行 Docker 和 Ansible;其次,相比于方便性,我更偏向于喜欢灵活性。我可以在这种组合中运行任何程序,而不仅仅是 web 应用。最后,我骨子里是一个工匠,我非常了解如何把零件拼凑在一起工作。Heroku 的基础模块是 Linux Container,而 Docker 表现出来的多功能性也是基于这种技术。事实上,Docker 的其中一个座右铭是:容器化是新虚拟化技术。

为什么使用 Ansible?

我重度使用 Chef 已经有4年了(LCTT:Chef 是与 puppet 类似的配置管理工具),基础设施即代码的观念让我觉得非常无聊。我花费大量时间来管理代码,而不是管理基础设施本身。不论多小的改变,都需要相当大的努力来实现它。使用 Ansible,你可以一手掌握拥有可描述性数据的基础架构,另一只手掌握不同组件之间的交互作用。这种更简单的操作模式让我把精力集中在如何将我的技术设施私有化,提高了我的工作效率。与 Unix 的模式一样,Ansible 提供大量功能简单的模块,我们可以组合这些模块,达到不同的工作要求。

除了 Python 和 SSH,Ansible 不再依赖其他软件,在它的远端主机上不需要部署代理,也不会留下任何运行痕迹。更厉害的是,它提供一套内建的、可扩展的模块库文件,通过它你可以控制所有的一切:包管理器、云服务供应商、数据库等等等等。

为什么要使用 Docker?

Docker 的定位是:提供最可靠、最方便的方式来部署服务。这些服务可以是 mysqld,可以是 redis,可以是 Rails 应用。先聊聊 git 吧,它的快照功能让它可以以最有效的方式发布代码,Docker 的处理方法与它类似。它保证应用可以无视主机环境,随心所欲地跑起来。

一种最普遍的误解是人们总是把 Docker 容器看成是一个虚拟机,当然,我表示理解你们的误解。Docker 满足单一功能原则,在一个容器里面只跑一个进程,所以一次修改只会影响一个进程,而这些进程可以被重用。这种模型参考了 Unix 的哲学思想,当前还处于试验阶段,并且正变得越来越稳定。

设置选项

不需要离开终端,我就可以使用 Ansible 来在这些云平台中生成实例:Amazon Web Services,Linode,Rackspace 以及 DigitalOcean。如果想要更详细的信息,我于1分25秒内在位于阿姆斯特丹的2号数据中心上创建了一个 2GB 的 DigitalOcean 虚拟机。另外的1分50秒用于系统配置,包括设置 Docker 和其他个人选项。当我完成这些基本设定后,就可以部署我的应用了。值得一提的是这个过程中我没有配置任何数据库或程序开发语言,Docker 已经帮我把应用所需要的事情都安排好了。

Ansible 通过 SSH 为远端主机发送命令。我保存在本地 ssh 代理上面的 SSH 密钥会通过 Ansible 提供的 SSH 会话分享到远端主机。当我把应用代码从远端 clone 下来,或者上传到远端时,我就不再需要提供 git 所需的证书了,我的 ssh 代理会帮我通过 git 主机的身份验证程序的。

Docker 和应用的依赖性

我发现有一点挺有意思的:大部分开发者非常了解他们的应用需要什么版本的编程语言,这些语言依赖关系有多种形式:Python 的包、Ruby 的打包系统 gems、node.js 的模块等等,但与数据库或消息队列这种重要的概念相比起来,这些语言就处于很随便的境地了——随便给我个编程语言环境,我都能把数据库和消息队列系统跑起来。我认为这是 DevOps 运动(它旨在促进开发与运维团队的和谐相处)的动机之一,开发者负责搭建应用所需要的环境。Docker 使这个任务变得简单明了直截了当,它为现有环境加了实用的一层配置。

我的应用依赖于 MySQL 5.5和 Redis 2.8,依赖关系放在“.dockercontainerdependencies”文件里面:

gerhard/mysql:5.5
gerhard/redis:2.8

Ansible 会查看这个文件,并且通知 Docker 加载正确的镜像,然后在容器中启动。它还会把这些服务容器链接到应用容器。如果你想知道 Docker 容器的链接功能是怎么工作的,可以参考Docker 0.6.5 发布通知.

我的应用包括一个 Dockerfile,它详细指定了 Ruby Docker 镜像的信息,这里面的步骤能够保证把正确的 Ruby 版本加载到镜像中。

FROM howareyou/ruby:2.0.0-p353

ADD ./ /terrabox

RUN \
  . /.profile ;\
  rm -fr /terrabox/.git ;\
  cd /terrabox ;\
  bundle install --local ;\
  echo '. /.profile && cd /terrabox && RAILS_ENV=test bundle exec rake db:create db:migrate && bundle exec rspec' > /test-terrabox ;\
  echo '. /.profile && cd /terrabox && export RAILS_ENV=production && rake db:create db:migrate && bundle exec unicorn -c config/unicorn.rails.conf.rb' > /run-terrabox ;\
# END RUN

ENTRYPOINT ["/bin/bash"]
CMD ["/run-terrabox"]

EXPOSE 3000

第一步是复制应用的所有代码到 Docker 镜像,加载上一个镜像的全局环境变量。这个例子中的 Ruby Docker 镜像会加载 PATH 配置,这个配置能确保镜像加载正确的 Ruby 版本。

接下来,删除 git 历史,Docker 容器不需要它们。我安装了所有 Ruby 的 gems,创建一个名为“/test-terrabox”的命令,这个命令会被名为“test-only”的容器执行。这个步骤的目的是能正确解决应用和它的依赖关系,让 Docker 容器正确链接起来,保证在真正的应用容器启动前能通过所有测试项目。

CMD 这个步骤是在新的 web 应用容器启动后执行的。在测试环节结束后马上就执行/run-terrabox命令进行编译。

最后,Dockerfile 为应用指定了一个端口号,将容器内部端口号为3000的端口映射到主机(运行着 Docker 的机器)的一个随机分配的端口上。当 Docker 容器里面的应用需要响应来自外界的请求时,这个端口可用于反向代理或负载均衡。

Docker 容器内运行 Rails 应用

没有本地 Docker 镜像,从零开始部署一个中级规模的 Rails 应用大概需要100个 gems,进行100次整体测试,在使用2个核心实例和2GB内存的情况下,这些操作需要花费8分16秒。装上 Ruby、MySQL 和 Redis Docker 镜像后,部署应用花费了4分45秒。另外,如果从一个已存在的主应用镜像编译出一个新的 Docker 应用镜像出来,只需花费2分23秒。综上所述,部署一套新的 Rails 应用,解决其所有依赖关系(包括 MySQL 和 Redis),只需花我2分钟多一点的时间就够了。

需要指出的一点是,我的应用上运行着一套完全测试套件,跑完测试需要花费额外1分钟时间。尽管是无意的,Docker 可以变成一套简单的持续集成环境,当测试失败后,Docker 会把“test-only”这个容器保留下来,用于分析出错原因。我可以在1分钟之内和我的客户一起验证新代码,保证不同版本的应用之间是完全隔离的,同操作系统也是隔离的。传统虚拟机启动系统时需要花费好几分钟,Docker 容器只花几秒。另外,一旦一个 Dockedr 镜像编译出来,并且针对我的某个版本的应用的测试都被通过,我就可以把这个镜像提交到一个私有的 Docker Registry 上,可以被其他 Docker 主机下载下来并启动一个新的 Docker 容器,而这不过需要几秒钟时间。

总结

Ansible 让我重新看到管理基础设施的乐趣。Docker 让我有充分的信心能稳定处理应用部署过程中最重要的步骤——交付环节。双剑合璧,威力无穷。

从无到有搭建一个完整的 Rails 应用可以在12分钟内完成,这种速度放在任何场合都是令人印象深刻的。能获得一个免费的持续集成环境,可以查看不同版本的应用之间的区别,不会影响到同主机上已经在运行的应用,这些功能强大到难以置信,让我感到很兴奋。在文章的最后,我只希望你能感受到我的兴奋!

我在2014年1月伦敦 Docker 会议上讲过这个主题,已经分享到 Speakerdeck了。

如果想获得更多的关于 Ansible 和 Docker 的内容,请订阅 changlog 周报,它会在每周六推送一周最有价值的关于这两个主题的新闻链接。

如果你想为我们的 Changlog 写一篇文章,请使用 Draft repo,他们会帮到你的。

下次见,Gerhard


via: http://thechangelog.com/ansible-docker/

作者:Gerhard Lazu 译者:bazz2 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

从左到右:安卓0.9的主屏幕,添加的应用抽屉,以及快捷方式删除界面。

从左到右:安卓 0.9 的主屏幕,添加的应用抽屉,以及快捷方式删除界面 [Ron Amadeo供图]

Android 0.9, Beta——嘿,这看起来很眼熟!

Milestone 5 发布后六个月,2008 年 8 月, 安卓 0.9 发布。尽管安卓 0.5 milestone 版看起来“很早期”,而此时距离 1.0 发布也只有两个月时间了。因此,安卓 0.9 被打上了“beta”的标签。在移动操作系统之路的另一边,苹果在一个月前已经发布了iPhone 的第二代产品——iPhone 3G。第二代的 iPhone 搭载了第二代 iPhone OS。苹果同样发布了 App Store 应用商店并且已经开始接受应用提交。谷歌在追赶的道路上还有很多事情要做。

谷歌抛弃了很多在 Milestone 5 中引入的 UI 设计。所有设计都回炉重造,采用全彩设计,白色方形图标背景被抛弃。尽管 0.9 还是一个模拟器版本,相比与安卓发布版来说看起来还是有点熟悉。安卓 0.9 有一个可用的桌面式主屏幕,一个特有的应用抽屉,多主屏,更多的应用程序,以及全功能(仅是它自身的)小部件。

Milestone 5 中似乎没有计划支持安装 21 个以上的应用,但在安卓 0.9 中有一个垂直滚动的应用抽屉,可以通过屏幕底部的灰色标签打开。那时候,应用抽屉真的只是个抽屉。除了作为一个按钮使用,灰色标签还可以跟随你的手指被向上拉起,就像通知面板被拉下来那样。还额外添加了一些应用,像闹钟,计算器,图片,信息,以及照相机。

这是第一个可以完全自定义主屏幕的版本。长按应用或小部件可以拖动它们。你可以把应用从抽屉中拖出到主屏幕快捷方式,或长按一个已经存在的主屏幕快捷方式来移动它。

安卓 0.9 提醒我们谷歌那时候并不像今天这样擅长设计。实际上,当时安卓的部分设计工作外包给了其它公司。你可以从时钟小插件看出一点端倪,它包含了“MALMO”字样,它是设计公司 The Astonishing Tribe 的所在地。

安卓0.9的“添加到主屏幕”对话框。

安卓 0.9 的“添加到主屏幕”对话框 [Ron Amadeo供图]

安卓 0.9 中只有三个小部件:时钟,相框和搜索。搜索小部件在列表中甚至没有一个自己的图标——它用的是图片的图标。也许这里面最有趣的选项是壁纸选项中的“购买的图片”——一个“在非智能机时购买铃声是个普遍的现象”的遗留产物。谷歌要么准备出售壁纸,要么在某时已经加入了一个运营商。不过这家公司最终从未实现这个计划。

小部件集合,打开的文件夹,重命名文件夹,以及一个复制/粘贴菜单。

小部件集合,打开的文件夹,重命名文件夹,以及一个复制/粘贴菜单 [Ron Amadeo供图]

在上面左侧的截图展示了谷歌搜索和图片小部件。除了给你一个框进行输入之外,搜索小部件做不了其它事情——它没有自动补全或是附加的 UI 界面。在框里输入并点击“Go”会启动浏览器。底部的一排图标显示了一些菜单中通过长按得到的“快捷方式”,它会创建图标并将应用启动到特定屏幕。独立的联系人,浏览器书签,以及音乐播放列表都是 0.9 中可以被添加到主屏幕上的快捷方式。

“文件夹”是快捷方式标题下的一个选项,尽管它并不是任何东西的快捷方式。一旦创建了一个空文件夹,图标就可以被移动进去并重新排列。不像今天,那时候的文件夹里有什么并不反映在文件夹图标上,它一直是一个简单的,白色的,看起来空空的文件夹图标。

0.9 同样是第一个拥有系统级别复制/粘贴支持的安卓版本。长按任意文本框会唤出一个对话框,从而让你保存或撤销剪贴板中的文本。iOS 直到近两年后才支持复制/粘贴,所以在一段时间内,这是安卓的特色之一——以及许多网络争议的源头。

从左到右:安卓0.9的新菜单,最近使用应用,电源选项,以及锁屏。

从左到右:安卓 0.9 的新菜单,最近使用应用,电源选项,以及锁屏 [Ron Amadeo供图]

安卓 0.9 真正地开始显示出了它的成熟。主屏幕有完整的菜单选项,包括设置(尽管它还不能正常运作)以及搜索按钮(谷歌肯定很喜欢你去搜索)。从那时起菜单的设计便已经最终成型,直到安卓 2.3 它转变成了黑色。

长按实体 Home 键会唤出一个 3x2 方格的“最近使用应用”的菜单,这是一个一直持续到安卓 3.0 的设计。“最近使用应用”菜单会将背景显示模糊化,但这个设计用在这里显得有些奇怪,在其它弹窗比如“添加到主屏幕”对话框或是主屏幕文件夹视图之中并没有用到该设计。电源菜单至少包含在了背景模糊设计组之中,它的图标经过了重新设计,并且功能的对应名称更改得更容易让人接受。不过电源菜单图标缺乏填充,显得有些拥挤和不雅观。

安卓 0.9 以其锁屏为特色,虽然是非常基础的样子。黑色和灰色的锁屏没有任何屏幕解锁的选项——你需要点击实体菜单键。


Ron Amadeo / Ron 是 Ars Technica 的评论编缉,专注于安卓系统和谷歌产品。他总是在追寻新鲜事物,还喜欢拆解事物看看它们到底是怎么运作的。@RonAmadeo


via: http://arstechnica.com/gadgets/2014/06/building-android-a-40000-word-history-of-googles-mobile-os/3/

译者:alim0x 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出