又见西雅图

1.

飞机降落在塔科马机场的时候,外面正下着瓢泼大雨。这样的大雨,在中国北方城市的冬季里,很少见到。

西雅图是个多雨的城市,而且雨季是在冬季。记得上大学的时候学英语,读到过一篇很有意思的文章。文章的作者说,他有一把伞,在西雅图多雨的天气里,这伞能带他去任何他想去的地方。更棒的是,这伞还带加热功能,在西雅图潮湿又寒冷的冬天里,能带给他温暖。我当时看了很惊讶,心想还有这么牛的雨伞。接着读下去,原来这伞就是作者的汽车,他卖了好大一个关子。

这篇文章给了我关于西雅图最早的印象之一。另一个关于西雅图的印象,是读了比尔盖茨的《未来之路》后,对他和他的公司充满了敬仰,知道了西雅图是微软总部所在地,那里住着许多富豪。

2.

我上次来西雅图,大概是两年多前。相比起那时,西雅图市区没有多少改变。Public market的小贩们还是那么开心,美心饼家还在,第一家星巴克门店还是有许多人排队,还是要照例去Crab Pot打卡。西雅图的街头也出现了共享单车的身影,中国的共享单车品牌ofo,和大概是本地品牌的Lime bike都能看到。但是在这多雨的天气里,没看到有人骑。

还有就是,鼎泰丰终于也开到西雅图市中心来了。

3.

在街角的Barns and Noble书店买了本《Fire and Fury》。这本书在书店打七折,在亚马逊上的折扣更高,但是亚马逊上标明的送货时间,是2到4个星期,来不及在我离开之前收到。

买这本书纯属猎奇,想看看作者到底写了些什么猛料,导致特朗普要威胁出版社不许出版,还要发律师信起诉作者。但是在特朗普以总统之尊,放狠话威胁之后,出版社和作者根本没加理会,书照出,还大卖,预售就登上了畅销书榜首。对比香港某书店老板和店员的经历,你甚至无法想象这样的事情会在中国发生。

不得不承认,这就是美国制度的伟大之处。这制度不能保证选出的总统各个优秀,但能保证烂总统也会被监督。

Web页面中的字体

我的blog荒废了很久,特别是2017年,基本没怎么管。最近觉着还是需要一个自己写字的地方,有一些时不时冒出来的想法,如果没记下来,没了也就没了。回看我很久之前写的一些文字,虽然不如何精彩,却也是一种个人记录。如果当时没写下来,那些人和事,只怕现在早已不记得了。所以又回来弄这个blog,想说把它弄得漂亮一点,至少自己看着也舒服。

我先是换了个theme。WordPress的主题目录里有太多的主题,看得人眼花缭乱,几乎选择困难症都要发作了。我最终选了这个gillian主题,觉着它比较适合我这样的个人blog,没有很多图片,也没有很多版式要求。在这个主题的基础上,我稍微改了改,主要是减少了标题背景的高度,留出更多空间给内容。

这个gillian主题是个英文主题,它的字体选择在iOS和Android上也还好,但是在Windows上就不那么好了。尤其是中文,会使用系统的默认中文字体,微软雅黑。虽然很多网页都是这么做的,但是我不太喜欢这款字体,于是改造了一下这款主题的字体选择。说实话,我之前对浏览器的fallback机制有大概的了解,但对字体没什么研究,搞不清楚衬线和非衬线的区别,和字型字重等等这些术语。为此,我跑去pluralsight听了一门名为Fundamentals of Typography的课程。算是对这些术语有了大概的了解。

原来,字体设计和使用是挺复杂又有趣的一件事情。以后有空,我会再多了解一些字体相关的知识。字体的选择需要考虑许多因素,但更多与设计师本身的审美有关。我对自己的审美没什么自信,所以最终选择了下面这样的字体搭配。

对于苹果平台的读者,如果有的话,使用苹果的系统字体就好了。使用别的字体,他们说不定反而会抱怨。对于其它平台,英文我选择了无衬线的Merriweather作为blog内容的字体,有衬线的Merriweather作为blog标题的字体。之所以这样选,是因为无衬线的Merriweather在大字号时,似乎有些字型有bug。更重要的中文字体,Windows上用等线体,Andriod上用Driod。等线体从Windows 8之后就默认安装在Windows里了,是我蛮喜欢的一款系统字体。Windows 7就用微软雅黑。其它情况就不考虑了。

此外,我还为这个blog加了个logo。没有什么设计感,不过在此过程中发现了一个看起来很厉害的设计网站Canva,logo就是用它设计的。在blog已经没人玩的当下,我决定试试google的AdSense,于是放了个广告在页面上,欢迎点击 🙂 。

电影 The Post

昨晚看了部电影,The Post,是一部讲述美国的新闻记者和媒体,维护新闻自由故事的电影。这部电影,演员和导演都是大牌,故事背景基于真实历史事件,主题又与现实的政治环境丝丝相扣,一时间在美国获得好评如潮。前几天,特朗普总统在twitter上公布“假新闻奖”,一度导致共和党网站宕机。在这样的氛围下,看这么部电影,真是应景。

1967年,美国正越来越深地陷入越战的泥淖,并看不到丝毫取胜的希望。时任美国国防部长麦克纳马拉,组织了一个研究项目,打算写一部百科全书式的越战历史。他后来声称,他希望通过这个项目,为后世的历史学家留下书面纪录,以及为将来的政府提供参考,希望他们日后能避免重蹈越战时期历任美国政府的错误政策和错误决策的覆辙。

这个项目小组最终写出了多达47卷的报告,其中包括3000多页历史记录分析和4000多页政府原始文件。重要的是,这个报告里记录了大量美国历任政府不为人知的机密行动和决策,涉及许多谎言,欺诈和权力的滥用。比如,美国总统约翰逊公开宣称,越战的目的是为了保护一个独立的,非共产的南越政府。但是报告中引述麦克纳马拉给约翰逊的备忘录,称越战的真正目的,不是为了帮助朋友,而是为了限制中国。再比如,报告披露,南越政府完全是由肯尼迪政府,为了对抗共产主义,出钱出枪,扶植建立的,等等。这份报告实在于美国政府的形象,以及进行中的越战,大大的不利。因此,这份报告从写成之日起,就被列为极为敏感的最高机密,普罗大众根本不知道它的存在。

1971年,一位斯诺登式的孤胆英雄出现了。这人名叫Daniel Ellsberg,是兰德公司的员工。他将这份五角大楼报告的一部分偷了出来,先是透露给纽约时报,后来又透过华盛顿邮报,进行发表。这份报告一经曝光,立即引起一系列连锁反应。先是尼克松政府以国家安全为名,限制媒体的报道,后来官司一路打到最高法院,最终美国政府败诉,媒体的新闻调查和报道自由得到了维护。这份报告即是著名的国防部文件(Pentagon Papers)

这份国防部文件,即是电影The Post的背景。电影故事展现华盛顿邮报的女老板Katharine Graham,总编Ben Bradlee和记者们,如何在巨大的挑战下,努力追求真相,坚持新闻出版自由,并最终让华盛顿邮报从一家地区小报,一举成为与纽约时报齐名的大报。

Meryl Streep主演的这位女老板Katharine Graham,也是一位传奇女性。她是史上第一位女性财富500强CEO,她更为人所知的,是其在之后的水门事件中,领导华盛顿邮报的表现。电影借由这位女老板,展现那个时代身为女性领导者的艰难。电影开始阶段,作为公司老板的Katharine,在面对她自己的董事会时,显得无力又懦弱。她的领导,备受董事会男成员的奚落。她的领导层中,除她之外全是男性。电影中有一幕,是她去华尔街为公司上市开幕。大门外的阶梯上,迎接她的是她的女性员工和朋友,大门推开,那些出现在开幕式上的,全部都是男性。但最终正是Katharine的坚持,华盛顿邮报才能顶住压力,坚持出版了那份报告。当Katharine冲着那个喋喋不休的董事会成员,说出那句“这不是我父亲的公司,也不是我丈夫的公司,这是我的公司”时,正展现了女性对自身权力的觉醒。Katharine决定发表国防部文件,某种程度上,是出于她对男权的反抗。

相比而言,Tom Hanks饰演的总编Ben Bradlee,则是一个相对单纯的角色。他不是公司老板,不需要为公司的运营负责。作为一名新闻出版业老兵,他能为了抢新闻,为了与纽约时报竞争,而不择手段。但在新闻自由受到威胁时,也能毫不犹豫的说出“他们输了,意味着我们也输了”。正是他和他的记者们对真相的追求和对新闻自由的坚持,给了Katherine做出艰难决定的勇气。

这部电影名列时代周刊2017年10佳电影首位,从剧情,拍摄,到演员的表演,都是上乘之作。稍有争议的地方,是关于史实的部分。实际上,在国防部文件事件中,纽约时报是主要的媒体报道者,以及与政府诉讼官司的主角。华盛顿邮报在此事件中的作用,并不如电影中那么重要。真正令华盛顿邮报名声大噪的,是之后的水门事件。不过这些小节于电影本身无伤大雅。

Creating API Management instances in Parallel with Automation Runbook

Provisioning an Azure API Management (APIM) service instance is a bit time-consuming task. It usually takes 20 to 30 minutes to get an instance created. In most of cases, it is fine because you usually don’t have the needs to create many APIM instances. For most customers, 2 or 3 instances are enough for their solutions. And provisioning APIM instances doesn’t seem to be a day to day work.

But recently I am preparing a lab environment for an APIM related lab session that I am going to deliver in an event. Given that provisioning an APIM instance would take 20 to 30 minutes, it is impracticable to let attendees create the instances during the lab session. I have to provision an APIM instance for each attendee before the lab session. As there could be more than 40 attendees, I have to do it with a script rather than manually clicking around in Azure portal.

APIM supports creating instances with PowerShell. It doesn’t support Azure CLI at the moment. The Cmdlet for instance creation is New-AzureRmApiManagement, and as mentioned in the document, this is a long running operation which could take up to 15 minutes. If I simply create a PowerShell script to run this operation sequentially, it would take tens of hours to get all APIM instances created. It is not acceptable. I have to run the operations in parallel.

I ended up creating a PowerShell Workflow runbook in Azure Automation to do the task. PowerShell Workflow has several ways to support parallel processing, and Azure Automation provides the enough computing resource to run all operations in parallel.

The following code snippet shows the key part of the workflow.

The code is quite straight forward. I need to include the Azure authorization code for each of the parallel operation because when operations are running in parallel, each operation runs in its own process. So each of them need to be authorized before they can access the Azure resource.

For the completed code, you can get it from here. To run this workflow runbook in Azure Automation, the AzureRM.ApiManagement module needs to be imported into Azure Automation. That’s all.

为什么Surface Book才是我心目中,PC的理想形态

上个月去美国旅行的时候,跑去微软商店买了一台Surface Book 2。几个星期用下来,我觉得它是我用过的,最好用的Windows 10 PC。它的这种混合了笔记本和平板的模式,是我觉得十分理想的PC形态。不知道微软怎么考虑的,Surface Book系列竟然只在少数几个国家卖。如果不是受限于微软的市场策略,和偏高的价格,它应该大卖才对。

Surface Book好在哪儿呢?

首先,它够强大,够powerful,又够轻。我之前用的是ThinkPad W540,i7+32GB内存,双显卡,非常强大,但是太重,单单它的充电器就比别人的整台机器还重了,不适合背着到处走。我的这台surface book,是13寸版本,i7+16GB内存,底座是带显卡的。跑Visual Studio,Docker等等,统统没问题。文明6玩起来也比W540感觉还强。重点是,不相上下的性能,surface book的重量连W540的一半都不到,也就刚刚比W540的充电器重了一点点吧,绝对有利于保护肩膀。

其次,surface book的底座更稳定,键盘手感更好。我之前还有一台surface pro 3。那时候是出门用surface pro,在家用W540。Surface pro的键盘手感不好还在其次。有一次去客户机房,服务器旁边没桌子,我只好坐在高脚椅上,然后把surface pro摊开放腿上。可是surface pro典型的头重脚轻,一不小心,它从我腿上掉下去了,我伸手只抓到了它的键盘。偏巧掉下去的角度不对,是一角先着地,屏幕就摔裂了,直接导致触屏玩完了。也导致我之后不得不背着W540出门。Surface book的屏幕和键盘重量比较均衡,链接铰链也比surface pro的安全多了。

第三点就是它对Windows 10的支持了。通过平板分离按键,可以在不断电的情况下,将平板部分卸下来。由于它有两块电池,平板部分的电池比较小,使得它端着比surface pro还轻。这点太方便了。有时候资料看到一半,不想坐在办公桌前看了,可以卸下平板,端着坐沙发上看,完全可以无缝切换。虽然离了底座,平板的电池大概只能支撑两三个小时,不过对轻度使用足够了。

总之surface book我用着蛮好的,希望微软能调整策略,让它大卖。

又是新的一年

2017年已经过去一个星期了。不知不觉之间,就过了一年,长了一岁。“人生天地之间,如白驹之过隙,忽然而已”,庄子的这句感叹,真是恰如其分。回望2017年,有些事情做的不错,小有成绩,有些事情就做得没什么结果。总的来说,小有成绩,没犯大错,算是平顺的一年。

2017年初的时候,我利用项目间的空档,学习了一下Docker容器相关的内容。又觉得应该掌握一门前端框架,就学习了React和Redux,这些竟然在后续的项目中都用到了。回想起来,如果当时那段空档时间荒废掉了,后面的项目估计会做得十分痛苦。

下半年的项目,是一个基于Azure的应用开发。项目里用到的Azure服务,在以前的项目里虽然也用,也和不同的客户讨论讲解过,但用的比较零散。这个项目才是我真正第一次,将这些涉及到的服务统合在一个solution中,并全面实践敏捷方法和DevOps,非常有收获。连带着项目总结,向Ready大会递交了两个content proposal,没想到都被接受了。其中一个被接受为Digital Ready的session,另一个是现场。这是我第一次被邀请为Ready的speaker,算是实现了一个小目标。从我提交content proposal的经验看,具体的产品和技术,Ready更倾向于选择产品组的内容。对于来自field的proposal,他们更看重的是所谓Lessons learned的内容,纯粹讲技术,他们不太会接受,毕竟field来的讲技术,是讲不过产品组的。

年底我们一家人去了一趟美东旅行。纽约,费城,华盛顿,尼亚加拉瀑布,波士顿,纽黑文,走了一大圈。虽然天气很冷,在波士顿遇到大雪,但没有遇到极端恶劣的天气,旅程出奇的顺利,我们都玩得很开心。我们在新年之前回到新加坡,新年之后的这几天,美东的天气变的极端糟糕,大量航班延误,交通受阻。我们不禁庆幸,老天爷算是给面子。

2018年已经开始,我心里也有些目标,要实现还是要努力才行。不过我想,如果能继续保持下面三条实践的话,还是有机会的。

  • 合理利用项目间的空闲时间,不断学习
  • 关注新技术的发展
  • 保持好奇心

比特币疯狂

1.
前两天看见朋友在朋友圈发了条高晓松讲的笑话,说他有个学长,当年在比特币只有几毛钱的时候,和人合伙买了两万个。俩人都怕对方背着自己买卖比特币,所以设计了一个巨复杂的密码,两人各持一半,要一起输入才能解密。结果那个合伙人去年车祸去世了,剩下那个学长望币兴叹。这当然是个笑话,不过我倒是想起了,几年前我也玩过比特币的。

2.
2010 – 2011年的时候,我偶然读到了一些关于比特币的文章,对它的原理十分好奇,同时又被中本聪的传奇吸引,混到了一个玩比特币的twitter圈子里潜水。那时候的比特币基本不值钱,我记得我上一个比特币论坛,里面的人为了推广比特币,会给回帖的新人送币。我的第一笔比特币交易,就是这么完成的,论坛里的人送了我0.2个,按照今天的市值,差不多几千美金吧。还有人兴奋的宣布,他成功用比特币买了一个披萨,大概花了三四枚的样子。按照今天的市值,那哥们大概花了几万美元吃了一个披萨,味道一定好到逆天了吧。

3.
2011年的时候,挖矿还比较容易。一台PC装上一块显卡,每8个小时,大概能挖到0.04 – 0.05枚BTC,有时候运气好的话,甚至可以到0.1BTC。现在挖矿的收益已经大减了,据说一台最powerful的矿机,跑一个月也只能挖到0.25BTC。不知道这能否够付电费的。所以很多文章都建议,如过想要比特币的话,拿投资矿机的钱和电费,去直接买,可能会有更高的收益。

4.
有人认为,比特币是史上最大的郁金香泡沫,也有人认为,数字加密货币是未来。到底是投机还是未来?我不知道。

今日比特币价格:$16982.85

避讳诸法

中国古人讲究避讳,遇到君王或尊长的名字,要回避以示尊敬。《礼记》中有“入境而问禁,入国而问俗,入家而问讳”之说,意思是到一个地方先要问清楚该地的禁忌,到一个国家先问清楚其国的习俗,到一户人家先问清楚人家的名讳,这样就不会一不小心犯了人家的忌讳,而失礼了。可见避讳这事,在中国已经几千年了。就像哈利波特和他的小伙伴们,对伏地魔不敢直呼其名,而要称之为you know who一样,古人对君王和尊长不但不能直呼其名,而且要想方设法回避用其名中之字,否则可能会犯下不敬之罪。唐朝有个诗人李贺,他父亲的名字叫“晋肃”。李贺要考进士,有人就说,李贺应该避他父亲的名讳,不能考进士。这说法惹恼了韩愈,他专门做了篇《讳辩》,来批驳这些人。但在这篇文章里,韩愈也不敢说不需要避讳,而只是辩解说,李贺考进士,并不触犯“二名律”和“嫌名律”,“父名晋肃,子不得举进士,若父名仁,子不得为人乎?”。可见避讳这件事对古人来说,还是兹事体大的。

为了避免犯罪,古人想出各种方法来避讳,比如最常见的方法就有,改字,空字和缺笔等。

改字法,就是遇到要避的字时,用另一个字代替。陆游在他的书里讲过一个故事说,一个叫田登的人去当州官,命令他的下属要避他的讳,否则就要责罚。于是该州为了避讳,就将灯(与登同音)这个字,用火字代替。到了上元节放灯的日子,州吏贴出告示说,“本州照例放火三日”。这个“只许州官放火,不许百姓点灯”的典故,就是用改字法避讳,闹出来的。

讳不只是人要避,动物也要避;不只是普通人要避,神仙也要避。野鸡这种动物,原来不叫野鸡的,人家原名是雉。只是汉代为了避吕后的讳,才改叫了野鸡,这比人家原来的名字听着土多了有没有。据说嫦娥原名叫做姮娥,为了避汉文帝刘恒的讳,才改名叫嫦娥的。这都属于用改字法避讳。

空字法,就是遇到要避的字时,不写这个字,而是空一格,画个方框或是注个讳字。比如唐初的徐懋功,本名叫徐世勣。唐高祖李渊赐他姓李,于是改名李世勣。到了唐太宗时,为了避李世民的讳,将世字去掉,改叫李勣。当皇帝的这么搞到是玩的开心,可你们有计算过徐懋功他爸爸的心理阴影面积吗?

最牛的空字避讳,大概要数观音菩萨了。传说观音菩萨法力无边,之前一直被尊称为观世音菩萨,到了唐太宗时,为了避讳,只得把世字去掉,改名叫观音菩萨了。也不知是真是假。

缺笔法,是将要避的字的笔画去掉一两笔,变成另外一个字,一般是去掉最后一笔。《康熙字典》里,就将康熙的名字,玄烨,个去掉了最后一笔的点和竖,变成了键盘上敲不出来的两个字。

想起避讳这件事,是因为最近我的两个答案,因为避讳不当,一个被删除,一个被政治敏感了。

中国在清朝之后,理论上就不再需要避讳了。可现实中,由于无法言说的原因,中国人还是需要不断地避讳的。实际上,我答题的时候就已经用改字法避讳了,比如使用庙号和英文来取代原来的字,可看起来改字法并好使。由于输入法的限制,缺笔法根本没法用。看起来唯一有效的方法,是空字法,即要么用方框(比如这个答案),要么彻底删除或避免提到那些讳字。

随着历史的车轮不断向前,中国人要避的讳字也会越来越多,避讳的方法也需要与时俱进才行啊。

[1]同步发在知乎专栏

Dockerfile实践

最近在玩OpenCV,顺手build了一个OpenCV 3.2.0的Docker image。这个image是基于Ubuntu 16.04和OpenCV 3.2.0的source code build的,顺带也build进了Python3的绑定。这个image比较适合用来作为开发和测试基于OpenCV的服务端程序环境的base image。由于包含了几乎全部的OpenCV组件,build的过程还是比较费时的,image的尺寸也比较
大,所以我将它push到了Docker Hub里。需要的话,可以用
docker pull chunliu/docker-opencv

把它拉下来使用。如果要精简组件,或build别的版本的OpenCV,可以修改Dockerfile,重新build。

实际上我以前并没有怎么用过Docker,只在虚机中安装过,顺着Docker官方的tutorial做过,并简单看过官方的几篇doc,仅此而已。大概明白Dockerfile是怎么回事,但没有写过很完整复杂的Dockerfile。事实证明,事非经过不知难,写这个Dockerfile还是有一些坑的。

首先,要写好这个Dockerfile,只靠记事本比较困难,使用辅助工具会容易一些。我用的是VS Code + Docker support,它能提供关键字着色和IntelliSense,也仅此而已。如果有工具能做语法检查就更好了,比如检查行尾是否少了一个续行符之类的。我开始几次都是跑build失败才发现,是某一行少了一个续行符。

另外,我没发现有什么好的方法,来debug和测试Dockfile。最开始,我是修改了Dockfile之后,就跑build,失败再找原因。但是这个build比较费时,这样不是很有效率。后来,我开始在一个container里,逐条跑Dockerfile里的命令,保证每条命令都没问题,再跑build。这样做的问题是,所有命令在一个bash session里跑成功了,并不能保证它们用RUN组织到Dockfile以后,build还能成功。

这就牵扯到Docker是怎么执行这个RUN的问题了。Docker的文档说,每一个RUN会是一个新的layer。我起初不太明白layer的含义,做过之后发现,所谓layer,就是一个中间状态的container。RUN后面的代码是在这个container里跑,跑完之后这个container被commit到image里,然后这个container被删除。后面的RUN,会基于新commit的image,起一个新的container。

所以,如果两段代码需要在一个bash session里跑的话,就需要在一个RUN里面才行。一个例子,比如build OpenCV的时候,会用下面的方式来make:

mkdir build
cd build
cmake ......
make ......

如果将cd,cmake和make分开到不同的RUN中,那cmake和make就有问题了,因为工作路径不对。实际上,RUN的工作目录是由WORKDIR设定的,每个RUN开始时都会使用它上面最靠近它的WORKDIR作为工作目录。所以如果非要将上面的代码分开到不同的RUN,也可以在RUN之间插入WORKDIR来指定路径,不过路径跳来跳去的,比较混乱。

细读Docker的两篇官方文档,对规避Dockerfile里的一些坑,是很有帮助的。

Reference

你好,2017

2016年就这么过去了。

回顾这一年,似乎和往年没有什么不同,依旧是在忙忙碌碌和似乎总也做不完的项目中度过。收获也有一些,但似乎又没有什么大书特书的必要。年初的new year resolution完成的七七八八,其中最重要的减肥目标,没能达成。这一年的体重状态,是不断的起伏。年初开始减,到6月去了趟台湾,被台湾的美食给打回了原型。下半年接着减,结果因为年底去澳洲旅行,又半途而废了。减肥这件事,看来是会继续留在2017年的new year resolution里了。除了坚持,谁知道旅行中有什么好方法控制体重?

进入2017年,我希望自己能将下面几件事情坚持做好做下去:

  • 跑步。从10月重新开始跑之后,目前坚持的不错。
  • 阅读。过去的一年里,我似乎只看完了两本书,其他时间都花在了网络上。2017年先定个小目标,希望自己能每月读完一本书。
  • 分享。“我的知乎2016”显示,我有200多天登录了知乎,不过只写了3个答案,Blog的更新频率也不高。只能自嘲,闲逛也是一种成就。其实我的草稿箱里,到是躺着许多未完成的答案,皆是因为懒,而没有完成的。希望在2017年里,能坚持分享和写作。
  • 增强执行力。程序员界有句名言,”Talk is cheap, show me the code.” 过去的一年中,我也遇到了许多好的不好的idea,但由于执行力不够,都没能实现出来。希望新的一年里,能够改善。其实,如果把这里列的事情做好了,执行力说不定就改善了呢。

你好,2017!

[1]: 题图来自 Unsplash, Annie Spratt