Planet of Woodpecker.org.cn for CPUG

August 14, 2017

@khsing

Nginx 的流量镜像模块

Nginx 发布了1.13.4版本,并且包含了一个流量镜像的模块 ngx_http_mirror_module

这对于线上系统就很好了,比如可以镜像部分流量来做测试、debug之类的

例子也很简单:

location / {
    mirror /mirror;
    proxy_pass http://backend;
}

location /mirror {
    internal;
    proxy_pass http://test_backend$request_uri;
}

by khsing at August 14, 2017 07:01 AM

August 13, 2017

@khsing

软件的收费模式

Ulysses 发了一篇blog: Ulysses Switches to Subscription 就唰喇喇的把自己的售卖模式从卖 License 换到了卖时间了。

曾几何时,还在指责 Mac App Store 不支持升级的收费策略的时候,这些应用开发商却把自己的收费模式先换成了订阅。我承认软件开发商在卖 License 的模式下面临着很多的生存困境,比如一个 App 很好,但是为了持续的获得收入只能走两条路:

  1. 发展新客户,每年都把东西卖给陌生人,这个过程其实是挺难的。
  2. 向老客户收钱,每年总有那么几个改版本号骗钱的App奸商,比如臭名昭著的Parallels Desktop。

开发商能怎么办,也很无奈啊,程序员嗷嗷待哺,不弄点钱,新版本怎么开发,总不能卸了磨就杀驴吧。所以这模式得改,要说这改的快的还是几个大厂,以Adobe为首的先把自己的 Creative 套件给转到订阅了,Microsoft把也提供了365的订阅模式,订阅模式确实对厂商来说是非常的好,收入有了保障,日子也可以过的有滋味了。

用户当然是希望App能稳定的好好工作,别罢工,积极解决遇到的问题,持续更新。最讨厌的就是付费更新,最最讨厌的就是不付费更新在新版OS里就不能好好工作的那种,比如Parallels Desktop。

用户付费买的是什么?是软件的使用权还是有效时间的使用权?

如果是一个有效时间的使用权,应该适用于专业用户,专业用户能够频繁的使用这个软件,这样你才能对得起你的服务和售价。普通用户买来就不合算了,比如工具软件,普通用户一年也就用上几次,只是希望安安静静的工作就行了,所以普通用户修图片应该买 Pixelmator 而不是 Photoshop。

如果是使用权,那就是一个稳定的OS版本下,可以一直使用这个软件,比如我10年前买一个软件,只要我的操作系统没有换,其他环境没有换,这个版本就应该可以一直使用下去。

有些软件的某个版本写的太好了,以至于新版本没有什么吸引力让我去升级,比如我常用的那个Dash 和 Alfred,Dash 4 和 Alfred 3都出来很久了,提醒更新也很久了,但是他们现在的这个版本太好了以至于我完全没有什么动力去升级,厂商当然就挣不到钱喽(心疼1s),所以从某种程度上也可以理解 TextMator 和 Sublime Text 为啥后来更新乏力了,该买的早就买了,不买的也不会再买了。

所以说产品定位很重要,针对专业用户的尽管走订阅模式,因为用你的工具用户能挣回来更多的钱。如果你只是一个针对普通用户的工具,还是卖License吧,以量取胜,增加边际收益,而且工具不是你的长期事业,能分化出专业用户还是得走订阅模式来稳定收益,更长期服务下去。

当然订阅模式也存在 @bfishadow 说的那个问题,即便你一年啥事儿都不干,还是得给你付费才能使用,这确实是很操蛋的事情了,所以我觉的 Sketch 的订阅模式很好,好的是他订阅的是你升级的权利,并不是使用的权利,所以你的订阅过期了,软件依然可以使用,只是不能升级到最新版了而已,所以我之前使用的日记软件Day One是不会升级到新版去的。

by khsing at August 13, 2017 08:56 AM

August 12, 2017

@khsing

体验是优化出来的

从直觉上都认为 Apple Pay 的支付体验是优于微信支付的,直到头几天 Apple Pay 和银联一起搞了一个5折之类的促销活动,刺激了很多人去用 Apple Pay,包括星巴克,7-11。从集中的使用了一段时间来看,Apple Pay在国内的体验是不敌微信支付的。

主要就从速度来说,Apple Pay的支付速度远不及微信支付,举一个我在7-11的例子吧:

  • Apple Pay: 排队 -> 告诉店员使用Apple Pay -> 店员拿起 POS 机设置金额 -> 贴上去支付 -> 完成
  • 微信支付:排队 -> 准备好支付界面-> 告诉店员使用微信支付 -> 直接贴在扫码机上面 -> 完成

所谓的需要打开App再支付的步骤,排队的时候就干完了,而且就现在情况来说,打开个App和掏个手机基本不差。

从技术方案上,从安全性来说Apple Pay都要比微信支付好,但是从部署难以程度,从体验的优化上,微信支付已经在国内大幅的超越了Apple Pay,下一步 iPhone 的 NFC 接口开放之后会不会对微信支付的体验上带来优势呢?也许结合小程序和RDIF在零售领域玩出新花样也不好说。

项目 微信支付 Apple Pay
绑定银行卡 需要 需要
需要POS机 不需要 需要
POS操作难易 易(甚至不需要)
需要网络 不需要 不需要
店员培训
适用范围 iPhone 5S + 有摄像头的手机

可见这部署成本以及市场教育的结果,再加上市场优化的结果,微信支付的体验某种程度上也来自于这些服务于商铺的服务商的优化。

by khsing at August 12, 2017 09:07 AM

June 06, 2017

@khsing

十条无我编程的戒律

下面是译自Jeff Atwood的The Ten Commandments of Egoless Programming

========我是华丽的分割线========

这十条无我编程的戒律,源自Jerry Weinberg的《程序开发心理学》一书。

  1. 理解并接受你所犯的错。这是说尽早的在产品发布之前发现这些错误。幸好我们不是在JPL(隶属NASA的喷气推进实验室)开发火箭制导软件的一小撮人,在我们的行业中很难出现致命错误,所以我们可以也必须从错误中学习、开怀并且继续前行。
  2. 你并不等于你的代码。记住审查的目的是为了找到问题,而且问题一定会被找到。不要为一个没有发现的问题而自责。
  3. 你知道多少不重要,总有人知道的比你多。如果你问一个人他总能告诉你一些新鲜的玩意。寻找并且从其他人那里接受输入,尤其是你觉的你不需要的时候。
  4. 没有商讨就不要重写代码。在修复代码和重写代码之间总有一条不错的界线,知晓其中的不同,并在代码审查的框架中追查文法上的变化,而不是孤僻的强迫症。
  5. 用耐心和尊敬善待那些知道的比你少的人。非技术人员在和开发打交道时普遍持有偏见,好一些情况下认为我们是一群自负的怪人,坏一些的情况下认为我们是一群玻璃心。不要用愤怒和不耐烦加深这种偏见。
  6. 在这个世界上持续存在的只有变化。用微笑和开放的心态去接受变化。把每一个需求、平台或是工具上的变化视作新的挑战,而不是严重的不利因素去抵触。
  7. 真正的权威来自于知识,并不是职位。知识带来权威,权威带来尊敬,所以你如果想要在一个自大的环境中受尊敬,增加知识吧。
  8. 为你的信仰而战,但也要勇于承担。要知道有时候你的想法会被批驳。即便最终你是对的,也不要报复或者说“我早就说了”这样的话,也不要作出一副为你的想法惋惜或者哭诉的模样。
  9. 不要成为屋子里的人。不要成为长期处在阴暗角落且打水的时候才出现的码农,屋子里的人与世隔绝、淡出人们视线、失控且在开放协作的环境中无立锥之地。
  10. 批评代码而不是批评人——善待码农,而不是代码。尽可能的让你的评论都是积极的而且目的是促进代码质量。评论要和标准,编程规范,优化性能等内容相关。

软件的人性化的准则真是不过时的。这本《程序开发心理学》成书于1971年,而一年后我才出生。

========我是华丽的分割线========

Guixing 翻译于 2017-06-06

by khsing at June 06, 2017 07:40 AM

June 01, 2017

@khsing

黑客帝国的Neo和围棋世界的柯洁

黑客帝国(The Matrix, 1999)一直是我非常喜欢的一部科幻片,其中世界设定值得深思,不时的就会质疑自己是不是一块电池。Neo作为电影的主角有洞悉虚拟世界的能力,也被称之为救世主,在电影的3部曲结束之后,Neo战败,Matrix清除了Agent Smith,达成了人类和机器的和平。

自从 AlphaGo 去年4/5大败李世石之后,人类的围棋世界其实就已经崩塌了,无法战胜 AlphaGo 已经是必然。 今年柯洁和 AlphaGo 的对决以3:0落败,也成了 AlphaGo 的收官之作,从此退役,独孤求败。而柯洁也和 Deepmind 达成共同研究 AlphaGo,让其辅助人类研究围棋。

Neo和柯洁某种程度上何其相似,在 Matrix 即将摧毁人类最后的据点 Zion 之时,Matrix 打败了 Neo,获取了 Agent 的代码,完善了自己。柯洁最后大败给 AlphaGo,但柯洁也开始帮助 AlphaGo 进一步完善。

AI的一直是科幻界的主题,那部以人工智能(2001)命名的电影,人工智能把自己都给骗了,David努力在寻找自己不是人造的(Artificial)的证据,并且一直在寻找变成真正小孩的方法,最后发现自己并没有唯一性也不能变成真小孩,但是奇幻的一点也是他还是有唯一性,所以人工智能从情感上已经无法分辨了。

人类发明AI是科技发展的必然,机器仿生技术的进步必然会促进生活水平的提高。现在很多人还在纠结同性恋,变性人,out了,下一步该怀疑一下和你恋爱的是不是一个AI了。(这个题材也有了,《她》(2013),[捂脸])

AI和机器人的发展,一方面会让财富快速的向掌握AI和机器的人聚拢,另一方面人类会成为机器豢养的宠物。

by khsing at June 01, 2017 01:56 AM

May 09, 2017

@khsing

我所依赖的科技公司

使用了很多科技产品,如果这家公司和他们的产品突然消失,也许生活会很不方便,那么究竟有哪些是我生活中不可或缺的公司和产品呢?

  1. Apple,苹果公司的产品应该是我几乎无法替代的,他家的软件服务产品都不值一提,唯独iPhone和Mac是我工作生活不可缺少的,让我替换起来成本很高。
  2. Google,搜索产品基本是最最最不能缺少的东西了,缺了他我都不会上网了,Gmail和Contact都还可以替换,至于Chrome我只是开发的时候会用。
  3. 淘宝,万能的淘宝,基本上没有买不到的东西和服务,合法的哈。

上面这些是基本需求了,作为一个码农,下面两个服务也是不能缺少的

  1. Github,太多的开源项目在上面了。
  2. StackOverflow,离了他我都不会写代码了。

以上满足了基本需求。

by khsing at May 09, 2017 05:37 AM

April 26, 2017

@khsing

Uber被苹果请喝茶

这两天还发生了一件事,Uber CEO Travis Kalanick被Apple CEO Tim Cook叫去喝了茶,主要是Uber在代码中嵌入了追踪用户手机的指纹技术,甚至用户清理手机之后,也一样可以追踪的到,而且设置了地理围栏(Geofence)来躲避苹果的审核人员。

这事儿挺有意思的,对用户做标记是广告和推荐系统中必须要做的一件事,从最早iOS可以在App中直接读取Mac地址到后来这个接口变成私有API,以及苹果提供了iAd的一套标记用户方法,等等这些都是为了知道屏幕背后的那条狗。从这个角度来说Uber做的这个技术其实是很通用的,只要是做广告和推荐的都这么干。不同之处应该是Uber调用了私有API,从而可以永久标记一个用户,如果只是使用了iAd的标记,用户可以在iOS设置->通用->隐私->广告中重置。

司如其人,Uber的CEO按常理来说就是一个混蛋,只要没有被抓到,什么事情都可以干的出来。

by khsing at April 26, 2017 03:11 AM

Apple Pay、内购(IAP)和微信支付的体验

昨天说到应用内购买和微信支付体验问题,早上开车想了一下,Apple Pay,IAP和微信支付还真不是一码事,而且还各有各的特点。

先说IAP,应该说这是这三个产品中最早的一个,应用内购买是苹果在2009年推出的。解决应用内虚拟物品的购买,消费通过App Store绑定的信用卡、借记卡、或者余额来购买。便捷性上呢,在没有Touch ID之前,需要输入一次Apple ID用户名和密码进行消费,现在内购基本上就是弹出一个确认购买,TouchID,购买成功或者失败。

其次是微信支付,是微信提供的一套支付体系。微信借着滴滴打车和红包砍下了国内移动支付1/3以上的市场份额,生生把二维码支付和抢红包发展成了全国民运动。分场景来说,在微信内的支付很方便,无论是打赏还是微商城一类的支付都是很方便的,但是在其他App中使用微信支付是需要跳转到微信支付完成之后再跳转回去,这个过程就不是那么的原生和自然,但是依然是很不错的体验。

最后是Apple Pay,在国外开展的算是顺利,但是在国内却几乎是一败涂地,被二维码打的可以说是连牙都没找到。除去Apple Pay的POS机部署成本、国人信用卡持卡率等问题不说,仅教育用户这一项,Apple比微信和支付宝来说基本就是没有投入,只有在升级完之后的一个添加银行卡的引导过程,这是远远不够的,中国的移动支付市场是腾讯和阿里两家用补贴和红包砸出来的。就支付体验来说,分线上和线下两个场景来说,Apple Pay的体验都是很不错的,线上来说,无需跳转到另外的App,Touch ID就直接支付,很轻松,线下就更不用说了,轻触一下就完成了。但是,凡事总是有但是,Apple Pay在国内使用的时候,店员不知道、不会操作、设备不支持等等的问题比起微信二维码来说,那就是复杂太多了,店员不耐烦的时候甚至会说:你还是微信支付宝吧。

这时候再来看用户体验的问题,Apple Pay和微信支付的场景都基本上是支付,而IAP还有不同的地方在于支付完成后还要记录用户的支付记录,有些App的功能开启还需要恢复购买这样的功能,所以从功能上来说IAP的业务逻辑要复杂于Apple Pay和微信支付,这也造成了IAP用户体验差,尤其国内还有长城的存在,IAP的接口都在国外,这中间的网络通信就导致IAP支付过程很慢,甚至会失败。Apple Pay的体验优于IAP主要是无须网络连接照样完成支付,逻辑简单。

微信支付的体验好于IAP的主要原因是访问的服务都在国内,如果是店家扫描二维码支付甚至无须客户手机联网,这一点和Apple Pay是同等级的,只是没有Apple Pay那种系统级别行云流水般的顺滑而已。

所以,要微信把赞赏切换到IAP的话,是有一些损伤体验的,但是切换到Apple Pay的话,应该不存在体验损伤的问题,只看用户是不是使用了Apple Pay,这个大前提就喝退了很多人。

by khsing at April 26, 2017 03:10 AM

April 24, 2017

@khsing

微信和苹果的一次交锋

已经好几天的热点了,苹果从结果上逼微信干掉了iOS版文章打赏功能,理由是违反了苹果的App准入规定3.1.1的条款,即解锁程序内功能时必须使用IAP(内购),苹果举了个例子是:订阅,游戏货币,游戏等级,访问高级内容,或者解锁完全版本等,而且不可以引导用户跳过IAP使用其它支付。

先下结论,这次事件从目前的结果来看,微信的付费阅读产品可能会延期,至少会在iOS端会缺席。

再来想想这次事件的几个问题:

首先,微信的打赏究竟在不在苹果的这个规定范围内?

打赏虽然没有解锁一个新的功能,但是实际上这本身就是一个新的功能,我认为归类到订阅、访问高级内容这样的服务中也合乎情理。

其次,苹果的这个规定合理么?

根据我的地盘我做主的原则,这事儿其实也没的说,就腾讯来说他自己也干过很多我的地盘我做主的事情,比如干掉淘宝(虽然是淘宝先动手的),干掉优步,可以说微信也是乏善可陈。

最后,这些决定对用户的影响是什么?

苹果是敦促微信回到他的规则上来,乖乖的交虚拟产品的苹果税,微信的做法是用二维码代替按钮(之后也被要求撤下),耍了小聪明,猜测6小时后下线二维码也是在苹果的勒令之下撤下了二维码。其实,微信完全可以继续保留功能,打赏走IAP。但是我也听说,这是为了保持微信支付的优秀体验,好吧,微信的支付体验比Apple Pay要好?

要知道现在的做法是有损公众号的内容提供者的,也就是说微信为了自己的产品体验,强行损害了自媒体的利益,腾讯,干的真是漂亮!

微信的公众号域名是http://mp.weixin.qq.com,一直有对这个mp缩写的猜测,我倾向于这是Media Platform的缩写,媒体平台。如果你是一个内容创业者,或者是一个收入依赖于微信的媒体运营者,长点心吧,这次的事情已经说明,你们的利益是被腾讯这个平台裹挟的,是他可以作为筹码和其他公司打架的武器。

在拥抱微信获取流量的同时也要把灵魂交给撒旦!

再来说Apple的规则是不是真的就那么的神圣?

其实今天微信遇到的问题,不是微信一家遇到的问题,而是所有进入App Store平台的App一起面临的问题,比如Kindle作为一个电子书应用,不能在iOS版App内买书,为啥呢?因为这是虚拟产品,要交30%的苹果税,图书利润很薄还要和作者分成,除非iOS版购买比其他版本购买多30%,但是这个逻辑是不是很诡异呢?打开微博、爱奇艺要续费一个会员,也必须走IAP,为什么呢?因为3.1.1条款。这确确实实是一条霸王条款!

既然这个问题是行业内一样面临的问题,苹果有没有可能去改善?答案是可能会有改善。君不见喊了一万年的App支付订阅模式在去年就有所改进,很多的App也跟进了,比如我常用的Podcasting应用Overcast就在苹果支持订阅模式之后就推出了订阅付费的模式。

苹果占据了移动市场食物链顶端,而且目前的地位别人还无法撼动,所以他的规矩就是规矩,想要Apple作出改变,要么告他,要么退出App Store市场。很多Mac上的App就因为不满App Store的分成和苹果的霸道退出了App Store,比如Sketch, Sip等应用,但是Mac端好歹还是有其他途径安装App的,而iOS安装App的合法路径只有一条————App Store。

强大就封闭,弱小就开放。这就是一个很现实的生存环境,没有什么道义可言,只有商业利益赤裸裸的摆在这里。

至于苹果是不是惧怕微信的小程序而故意修理呢?也许有吧,但是小程序真的就能取代App么?

by khsing at April 24, 2017 12:04 PM

April 21, 2017

@khsing

2016款Macbook Pro的分辨率

入手2016款Macbook Pro有一小段时间了,一个小的细节是显示器的默认分辨率从1440×900变成了1680×1050,但是显示屏的物理分辨率还是2880×1800,而且那里也不现实Best for Retina了,但是这样的改变让屏幕可显示区域变大了,鸡贼了苹果。

对于一个轻度OCD患者来说,这太不科学了,改回来,必须是Best for Retina.

by khsing at April 21, 2017 02:26 AM

April 20, 2017

@khsing

升级Homebrew中的PostgreSQL

最后还是入手了新版的MBP,开发环境都是重新设置的,用PostgreSQL的时候,启动提醒版本不兼容

FATAL:  database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 9.5, which is not compatible with this version 9.6.2.

所以要升级一下原来的库,作弊条开始

  • brew services stop postgresql
  • brew install postgresql@9.5
  • initdb /usr/local/var/postgres9.6 -E utf8
  • 开始升级数据库
pg_upgrade \
  -d /usr/local/var/postgres \
  -D /usr/local/var/postgres9.6 \
  -b /usr/local/Cellar/postgresql@9.5/9.5.6/bin \
  -B /usr/local/Cellar/postgresql/9.6.2/bin/ \
  -v
  • mv /usr/local/var/postgres /usr/local/var/postgres9.5
  • mv /usr/local/var/postgres9.6 /usr/local/var/postgres
  • brew services start postgresql

完成

by khsing at April 20, 2017 04:13 AM

云服务和数据自由

最近发生了一个事情,我之前为了方便就把一些流程图都放在了ProcessOn的云服务上,我很容易的能把这个内容发给朋友,而且也可以邀请朋友同事一起来改,但是在我想导出一个思维导图的时候,发现只能导出成图片、私有的pos文件或者pdf,这个时候我就是很懵逼的情况。按理说,这个数据是我的,我应该有数据迁移的自由。

数据自由交换是一种权利,比如我记录的笔记之类的内容,这是我的创作内容,应该可以很容易的导出成一个容易迁移的格式,说的就是Evernote和OneNote。大概从2年前开始,我买了Office 365服务,理所应当的被送了一些空间,OneNote正好可以使用这些空间,我就打算把之前使用Evernote的内容都前一过来,但是当我发现OneNote只能一个Note一个Note的导出成PDF的时候,我彻底的放弃了这个产品,就更不要提他经常不知所以的同步状态,继续乖乖的付费使用Evernote。

从这些云服务的情况来看,我对他们的担心主要是三个问题

  1. 数据的属主问题。在云服务不能提供良好的数据导出时,这个数据并不能完全意义上属于我。
  2. 数据的交换问题。以文档类数据为例,ProcessOn 没有提供导出Mindmap为Freemind等其他软件格式就是一个数据不能自由交换的例子,这和1意义上相同。
  3. 服务的持续性问题。如果不在1,2的问题,那么第三个问题就是很严重的问题,作为一个云服务公司,如果数据既不能自由导出流转,那服务的期限最好就是永久,否则就是数据的丢失就是不可避免的了。

我并不排斥使用云服务,而且我司也是做云服务的,只是我觉的一些通用的产品数据应该被自由流通和编辑。举几个例子:

  • 文档,应该可以导出成为txt, rtf, word格式
  • 表格,应该可以导出成为csv, excel格式
  • 思维导图,应该可以导出成为,freemind, xmind, mindmanager格式

数据才是正真的自己拥有。

by khsing at April 20, 2017 04:01 AM

March 28, 2017

@khsing

思考和书写

人活着除了生理上的存活状态,最主要的还是思考在继续。我们看见周围的事和物都会去思考一系列的问题,比如:这是什么?为什么会发生?等等。

互联网的出现极大的拓展了我们获取知识的能力和范围,而移动互联网的出现则彻底的把我们的时间变的碎片化。在大量碎片信息的冲刷之下,我们的独立思考变的弥足珍贵。

现实生活和工作中面临的问题有小有大,大部分的问题凭着我们的经验和直觉就解决了。而有些问题是值得仔细思考的,甚至是需要长时间的理性思考的。这似乎与我们现在的移动互联网生活是冲突的,刷微博和朋友圈,接收着大量的碎片化信息,是无法完成深度思考的。有些时候我们的直觉会欺骗我们,看到一件事或物,经过简单的分析和思考就认为这件事情掌握了,了解了,然而这只是一个假象。在时间碎片化的今天,这一情况更为普遍。

一个接受和没接受教育的人的最本质的能力区别是阅读和写作,阅读是一种输入技能,经过思考之后书写出来就是输出了。这一点很像写了一个数据处理函数。

思考和写出来是有很大区别的,一个你觉的已经思考过的内容,要写出来的时候就变成了梳理的过程,这时候就会发现自己在脑海中浅思考的错误,所以写出来的内容往往比自己想的内容更加缜密。

如果一件事,经历之后,再经过思考梳理,形成文字材料才是真的消化,想通透了。所以技术人员要多思考,多实践,多分享。

by khsing at March 28, 2017 10:26 AM

March 12, 2017

@khsing

写给SaaS创业公司的安全基础知识

头两天看到了写给SaaS创业公司的安全101,内容涵盖了不少,非常值得一读,其实不光是给SaaS企业了,其他公司一样适用。

我摘了几个贴在这里

  • 密码共享和密码管理,所有系统都有一个终极的Admin账户,这个账户是共享的,防止这个人的单点故障,同时一旦共享了,那么密码是需要加密共享的,所以要有密码管理。
  • 全盘加密,Mac/Windows都有很好的加密方法了,几乎一键加密。
  • 买3个以上域名,第一个用于公开的品牌和企业的邮箱。第二个用于自己的SaaS服务,比如googleapis.com之类的。第三个域名用于内部的后勤支持,比如公司vpn等基础设施等等,而且这个域名最好匿名,这样别人就难以猜测了。营销邮件应该使用独立的域名,以防反垃圾系统标记后影响公司业务邮件来往。
  • 所有地方都使用HTTPS
  • API密钥,每一个客户都应该拥有不同的API钥匙对。
  • 物理安全:
    • 使用屏保,并且从屏保恢复需要输入密码。
    • 不要使用U盘,这是入侵的最方便最直接的方法了。
  • 企业内部沟通用Slack,客户间沟通用邮件,国内可以适用企业内部用BearyChat,客户沟通用邮件+微信。
  • 认证服务支持SSO和OAuth
  • 备份
    • 冷备/热备/异地容灾
    • 自动化备份
    • 定期恢复演练
    • 备份加密
  • 防火墙和访问权限
    • 服务访问需要认证,比如ElasticSearch, MongoDB, MySQL等
    • Review防火墙设置,只能允许必要的服务和端口开放。
    • 自动扫描。

可以照这个列一个checklist,看看自己公司都做到了哪些?

by khsing at March 12, 2017 05:12 AM

you-get下载视频

网络资源虽然很方便了,但是我依然喜欢把东西下载下来,尤其是喜欢的YouTube视频,因为版权等一系列的原因,这些东西在互联网可能只是短暂的停留。

you-get简直是一个神器,下载视频刚刚的。而且可以制定下载格式,连字幕都下载好了。比如指定下载mp4格式

you-get --itag=18 https://www.youtube.com/watch?v=ud4qy1EHRKQ

by khsing at March 12, 2017 03:43 AM

March 02, 2017

@khsing

消除Outlook的安装后反复欢迎提醒和Update无法更新的问题

Outlook for Mac 2016实在是太慢了,写个邮件都要卡顿半天,重新装了2011版来用,导出导入olm文件很是方便,这也是这几年来我一直使用outlook的一个主要原因。

遇到的问题是无法更新和欢迎界面每次都弹出。

其实就是一个权限的问题,我也懒的去找哪一个文件了,直接执行

find ~/Library -type f -user root -exec sudo chown `whoami` {} \;

问题解决!

by khsing at March 02, 2017 06:30 AM

March 01, 2017

@khsing

伟大长城带来的痛苦

上个礼拜,全球最大的开源社区仓库Github被认证,带来的不便就不说了。

最近用了一个项目,大量的使用了Git Submodule,如果在CI服务器上来做这件事儿,就是问题多多。没有办法,我只能clone一个下来再把内容放到自己的git repo里去,把依赖于github的submodule都给去掉。

苦不堪言!

by khsing at March 01, 2017 08:27 AM

February 27, 2017

@khsing

一毛钱股份

就算老公一毛钱股份都没拿到,在我心里,他依然是最牛逼的创业者 的文章上个礼拜被炒的火热,当事人很快就被扒出来了,最后陈CEO也出来解释了;

这事儿最重要的一点就是CEO老陈有没有给老韩承诺给股份?不管是口头的还是书面的,甚至比例都不重要,只是确定这个饼是不是存在。

如果没有,老韩媳妇现在要股份是理亏,最终是吃亏。

如果有,但是比例没有定,那么一个股份制公司运行了7年之久还没有确定的股份比例,我只能说老陈这个CEO不是蠢就是坏!

  1. 至于老韩人家家里过什么样的生活和股份的获得没有任何关系!甚至有说老韩你7年买房、买车、结婚生子,日子已经过的不错了。呵呵,圣人不死大盗不止!这7年人家日子过的好坏,买了豪车别墅也和凭承诺拿股份没有任何的关系;这就好比是一个公司在创业初期,比尔盖茨投了钱或者精力,比尔盖茨过的生活也和能否获得这个公司股份是没有关系的,如果这公司有承诺比尔盖茨股份,那就按承诺来,如果没有那比尔盖茨也得吃瘪,还是和他个人的生活没有关系。同理,公司现在的经营情况,获利情况依然和老韩拿股份这事儿没关系,只和当时的承诺有关,与其他事都无关;
  • 至于公司后面的发展老韩无法带队或者工作状态低迷,而且就老陈CEO的回复来看,是给发了200万分红之后出现的;这个情况还是和老韩获取股份没有关系,如果老韩入伙时没有承诺,老陈CEO就该早做决断,而不是把这个问题一拖再拖,而且是从2013年拖到了2017年。有承诺,即便是消极怠工也一样得给股份,请参考聚美优品陈欧在新加坡的公司一事;

  • 发200万和发100万也和股份获得没有关系。注意,这个文章是老韩老婆发的,也许老韩只和老婆说了100万,也许公司只发了100万。这笔钱并不是老韩退出股份的报酬,所以该是多少股份还是得给多少股份。

  • 说一千道一万,最重要的还是承诺;老陈没有承诺,老韩给公司干了7年,终了白干,这是老陈CEO辜负了老韩的信任;老陈给了承诺,终了没有兑现,这是老陈CEO的失信,甚至可以对簿公堂;老韩后期消极怠工,这是老韩不义;面对老韩消极怠工不做处理,这是老陈CEO失职;

    结论:拖延症害死人啊!

    那到底该不该给老韩股份呢?

    有句话叫吃水不忘挖井人,老陈在最需要的时候,老韩跟他一起干,完成了公司的冷启动,你说他该不该拿股份?

    再说了,老韩和老陈一起干的时候是降薪,经济学有个概念叫机会成本,老韩也许没有直接投入金钱,但是投入这家公司的机会成本是值得他拿这个股份的!

    by khsing at February 27, 2017 03:23 PM

    February 23, 2017

    @khsing

    继续留在Mac OS X

    macOS 10.12 发布之后我升级过了两次,但是体验都不是很好,本身系统的变化不大,但是带来的问题并不小,对我最大的影响是外接显示器之后的风扇狂转不止。甚至让我产生了它们要修复系统在老机器上运行过于流畅的bug了。

    本身我自己的MBP也已经用了4年之久了,是应该更新一下了,然而对于新版MBP的失望,配件的短缺,看来我的MBP还要继续服役1年以上,等配件比较齐全的时候再下手了,希望到时候macOS能稳定一些。

    我常读的Joel On Software主角,Joel Spolsky也表达了同样的

    @spolsky: Sorry Apple. After 10 years loyalty, this latest MBPro with useless touchbar and unreliable keyboard was last straw. Switched to Dell XPS13👋

    tweets

    by khsing at February 23, 2017 04:10 AM

    January 08, 2017

    @khsing

    在阿里云ubuntu 16.04 lts上安装gitlab-ce

    需要安装一个gitlab-ce给大家用,最近把操作系统都换到ubuntu来了,这个ubuntu是阿里云定制过的。

    清华大学又一个gitlab的镜像,但是阿里云无法连通,超时,但是单独curl又是好的,结果呢是阿里定制了/etc/apt/apt.conf文件,修改如下即可

    Acquire::http::Proxy "http://mirrors.aliyun.com/";
    

    内部用一个proxy连接的trick,添加一行即可使用清华的镜像了

    Acquire::http::Proxy::mirrors.tuna.tsinghua.edu.cn "DIRECT";
    

    by khsing at January 08, 2017 04:00 PM

    November 17, 2016

    @khsing

    Trump elected to be next president

    做为一个中国人没什么太多资格去讨论一个外国元首,但是他作为一个影响全球的世界元首,对其他国家或多或少还是有影响的,从最近汇市和股市的尿性就可以看出来了,就这还没有上任呢。

    至于Trump为啥能被选上呢?鬼知道,现在来看大家都归结于社交媒体的胜利。不无道理,以我之见,很多人选Trump的主要原因是想看到一些改变,而不是希拉里作为一个成熟政客的4年表演,她的表演和观海同志一样,who want repeat 4 years again? 而Trump能不能做到他说的make American great again, 未必吧,潜台词是American is not great anymore,但是即便是如此大家也愿意看到一些不太确定的变化吧,更何况Trump说的一些事情也是很多人想做的,比如限制非法移民和废除Obama~~Don’t~~Care之类的。

    至于现在的民族主义、孤立主义抬头,全世界的新潮流吧,从英国脱欧开始到现在的美国有可能转向保守主义等等,都有表明这个世界正在起变化。全球化进程是不是就此开始衰退,我倒没有太担心,从发达国家已经流出的工作岗位是不会再流回的,他们只是很有可能被另外一种更新的技术来取代。

    今天这是卖白菜的操了卖白粉的心,多虑了,洗洗睡觉!

    by khsing at November 17, 2016 12:58 AM

    November 16, 2016

    @khsing

    selenium wait 和 iframe

    还是从朋友那个小事儿做的时候弄出来的问题

    1. selenium 如何切换driver到一个ID设置为中文iframe?
    2. 遇到alert了怎么处理?
    3. 检查某个元素是不是出现了?

    不要问我为啥id会用中文,说多了都是泪,总之这是一个一言难尽的问题,一句话,国有企业你懂的。

    1. 切换到特定的iframe/frame
    driver.switch_to_frame(driver.find_element_by_id('some_id'))
    

    这样就可以在这个frame/iframe里做相应的find element操作了,但是要记住操作完了要切换回来

    driver.switch_to_default_content()
    

    多层嵌套的iframe也没有问题,只要一步一步的切换进去就好了

    1. 接受alert

    一个简单的方法就是预计有alert的地方,写上接受就好了

    driver.switch_to.alert.accept()
    

    这样很粗暴,但是也很有效,精细一些的做法看文档,比如:

    • 确认或者取消
    from selenium.webdriver.common.alert import Alert
    Alert(driver).accept()
    Alert(driver).dismiss()
    
    • 读取alert的文字内容
    Alert(driver).text
    
    • 认证的用户名和密码
    driver.switch_to.alert.authenticate(username,password)
    
    • 输入内容
    name_prompt = Alert(driver) name_prompt.send_keys(“Willian Shakesphere”) 
    name_prompt.accept()
    
    1. 检查某个元素是否出现

    以前的一个很粗暴的做法是time.sleep(N),但是这种情况下非常粗旷,selenium 提供了更精细的一些控制方法

    • 等待某个元素出现以后获取这个元素
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    wait = WebDriverWait(driver, 10) #10秒,超过这个时间就会raise Exception
    element = wait.until(EC.element_to_be_clickable((By.ID,'someid')))
    
    • 这里的expected_conditions可以是下面的这些条件
      • title_is
      • title_contains
      • presence_of_element_located #元素可以找到
      • visibility_of_element_located #元素可见
      • visibility_of
      • presence_of_all_elements_located #所有元素可以被找到
      • text_to_be_present_in_element #元素中包含text
      • text_to_be_present_in_element_value #元素的value值包含text
      • frame_to_be_available_and_switch_to_it #iframe可以切换
      • invisibility_of_element_located #不可见元素被找到
      • element_to_be_clickable #不但可见,而且可点
      • staleness_of
      • element_to_be_selected #元素被选中
      • element_located_to_be_selected #
      • element_selection_state_to_be
      • element_located_selection_state_to_be
      • alert_is_present #弹框出现

    这些基本覆盖了常见的情况了,足够用了,记得处理异常,否则就挂了。

    by khsing at November 16, 2016 11:22 PM

    macOS 的ssh-add -K

    macOS 10.12 开始ssh-add并不是默认将你的ssh-key添加进去了,所以需要额外配置一下

    打开自己的ssh配置文件~/.ssh/config,加入如下内容

    Host *
        UserKnownHostsFile /dev/null #这一句还好吧
        StrictHostKeyChecking no #这一句非常危险,结合上一句再加上dns劫持的话,再加上密码认证就很有泄漏密码的可能性
        ForwardAgent yes
        TCPKeepAlive yes
        IdentityFile ~/.ssh/id_rsa
        AddKeysToAgent yes
    

    by khsing at November 16, 2016 03:09 AM

    November 08, 2016

    @khsing

    再说 vendor 目录进不进版本控制

    先说结论:不进

    官方的指导是不进,如果非要进有如下四个方法

    1. 尽可能使用已经发布的包,这样可以使用tarball的方式来更新。
    2. composer.json中指定preferred-installdist或者更新的时候带上--prefer-dist参数
    3. 在提交git/svn之前,删除掉所有.git目录
    4. 在项目的.gitignore中加上/vendor/**/.git

    为什么我又来发这个了呢,因为我踩到坑了啊,由于使用了private package在composer.json中加了repositories,结果vendor下这些内容都成了submodule,但是远端的并不会更新,所以这是一个很严重的问题。

    至于以后的部署问题,我还要再梳理一下。

    by khsing at November 08, 2016 10:34 AM

    November 07, 2016

    @khsing

    Selenium 连接一个已有的连接

    帮朋友弄个东西,需要先登录,有一个不复杂的验证码,但是上OCR也太重,所以就先起一个driver,然后手工登录之后再连过来进行操作.

    • 先启动一个Driver和Session,并且打印出连接的URL和Session
    url = driver.command_executor._url       #"http://127.0.0.1:60622/hub"
    session_id = driver.session_id            #'4e167f26-dc1d-4f51-a207-f761eaf73c31'
    
    • 然后再连接过去
    driver = webdriver.Remote(command_executor=url,desired_capabilities={})
    driver.session_id = session_id
    
    

    REF:
    Stackoverflow: Connect to an already running instance of chrome using selenium in python

    by khsing at November 07, 2016 08:38 AM

    对新的 Macbook Pro 有点失望

    新的 Macbook Pro 发布已经有一小段时间了,接口都统一成了USB-C的样式,新增了一个Touch Bar的功能,外形上基本没有变化。

    我现在使用的是Macbook Pro的2012年中版,平时的情况基本满足需求,对我来说目前就是内存和SSD硬盘都有一些吃紧,Touch Bar什么的其实我并不Care,所以要我升级来说主要就是升级内存和SSD,如果说外观上能有一个升级的话,这是加分项。

    But,这一次的升级除了Touch Bar之外乏善可陈(Touch Bar其实最有用的是TouchID),而且Touch Bar还去掉了ESC,这对于一个程序员来说是个悲剧,就更不要提那个蝴蝶结构的键盘了。其次就是那个令人诟病的接口了,机身只有4个USB-C,充电、数据传输、外接显示器都得靠这4个全新的接口,所以买回来的第一件事应该是买USB-C相关的各种转接头,这简直就是个悲剧,更悲剧的是Apple这次涨价了。

    这样以来对于我来说今年要想更新Macbook Pro就不是一件明智的事情了,要么让我的老Macbook Pro挺一年,要不就是买一个2015款的16/32G内存的版本。我有点希望一个本子有ThinkPad的键盘+Macbook Pro的触摸板和ThinkPad的丰富的接口的机器,起码我不用带一堆配件或者辫子。

    记Apple一次失望的Macbook Pro更新,而且饭盒和垃圾桶都没有更新了。我有点离不开的是macOS,虽然它越来越烂了,也需要重启才能解决kernel_task占用过多内存的问题之类的,但是依然是目前能用到的最好的操作系统了。

    by khsing at November 07, 2016 03:20 AM

    November 03, 2016

    @khsing

    还是不要全局 .gitignore 了

    昨天踩了一个小坑,使用bower安装了一堆的组件进来,我这里是好的,但是同事去构建的时候就不对了。

    发现我git commit的时候,jQuery包里的dist目录没有添加进去,进而发现实际是我在很久以前在~/.gitignore里添加了一个dist导致彻底忽略了。

    索性就把这个家目录下的.gitignore给删除了,反正都是跟着项目走的,新建git repo的之后添加一个.gitignore就好了。

    by khsing at November 03, 2016 03:14 AM

    November 02, 2016

    @khsing

    在Mac上设置一套好用的PHP开发环境

    在Mac上工作多年,近1年多写PHP比较多,所以也总结了一点在Mac安装一套好用的PHP开发环境的套路。写出来丢在了Github上,更新了几次,这次给team更换开发环境到Mac的时候也是让大家照这一套来做的,自觉用起来非常顺手,主要的特点是:

    • 全部使用了HomebrewHomebrew Services来管理软件和服务
    • 环境是 Nginx + PHP-FPM + MySQL,如果有用到Redis和Memcached的地方使用brew install就好了。
    • 新增项目无需修改nginx配置文件
    • 尤其适合Laravel框架

    详见Setup Mac Development Envrionment

    by khsing at November 02, 2016 02:16 AM

    November 01, 2016

    @khsing

    我的 Macbook Pro 可能要挂了

    新的Macbook Pro发布了,看着一堆的TB3和配件,我觉的我的Macbook Pro还能挺一年。

    但是最近我的MBP的耳机插口坏了,这就尴尬了。

    于是我把音频输出走了TB到了Dell的显示器上,但是更尴尬的是显示器没有音量控制。

    于是我又接了一个功放在显示器上,好惨!

    by khsing at November 01, 2016 04:14 AM

    October 26, 2016

    @khsing

    解 git submodule 无映射路径的问题

    我们在使用Git submodule 的过程中我遇到的一个问题是执行git submodule update之后会出一个错误

    fatal: no submodule mapping found in .gitmodules for path 'vendor/predis/predis'
    

    这个问题就是你发现有一个不在.gitmodule文件中的submodule在更新,解决办法就是

    git ls-files --stage | grep 160000
    

    这可以看到你所有的Submodule文件,然后

    git rm --cached PATH
    

    Problem solved.

    REF:

    by khsing at October 26, 2016 04:01 PM

    October 17, 2016

    @khsing

    更换了iPhone 6 Plus 的电池,又换回去了

    上周我某宝买了一个飞毛腿iPhone 6 Plus的电池,主要是原来的那个电池只要天一冷就关机,最严重的一次是在电量70%的情况下,手机关机了,我很是焦虑,所以入手一个新电池准备过冬。

    盼星星盼月亮,终于把电池给盼来了,换上了,图片已经收入Flickr。但是悲剧发生了,换完之后充不进去电,坑爹啊!

    我又把iPhone的原装电池换了回去,飞毛腿退货,差评,换一个牌子继续折腾。

    btw.

    在手撕那个胶条的时候一定要慢,一定要慢,一定要慢,重要的事情说三遍!

    by khsing at October 17, 2016 09:42 AM

    阿里云的证书被吊销了?

    上周的我要登陆阿里云的时候发现他家的证书被吊销了,我发了个微博,阿里云的客服就立马回复过来了是:

    亲,经核实,SSL 证书管理机构及提供商GlobalSign的部分证书由于OCSP服务异常导致证书出现错误,会导致 macOS Sierra 系统部分用户使用 Chrome 或者 Safari 等浏览器时访问受限。GlobalSign反馈问题已经修复,新用户不受影响,但是由于证书体系的缓存性质,有一部分用户可能还会受到影响。
    

    但是今天还是无法使用Chrome打开,而Safari和Firefox都已经正常了。

    update: 2016-10-17

    重装Chrome之后正常了

    by khsing at October 17, 2016 06:16 AM

    September 25, 2016

    @khsing

    oh-my-zsh 总是很慢

    csh切换到zsh已经很久了,但是有时候他会很慢,甚至是在ctrl+c的时候,看了一下,主要的时间都是去检查git状态了,反正这个功能不是特别需要,就关掉好了。

    git config --add oh-my-zsh.hide-status 1
    

    Ref: oh-my-zsh slow, but only for certain Git repo

    by khsing at September 25, 2016 04:04 AM

    Safari 10 Released

    Safari 10发布了,除了在浏览器中支持Apple Pay之类的新特性之外,还支持了CSP(Content Security Policy) 2.0,这让好多 UserScript 就无法使用了。

    by khsing at September 25, 2016 03:51 AM

    September 23, 2016

    @khsing

    开始使用MWeb

    知道MWeb这个App已经很久了,也使用Markdown很久了,头段时间MWeb打折就下单了,而且也把blog从MovableType换到了Wordpress,所以也就结合用起来了。

    MWeb支持上传图片到Google Photos和七牛,但是我还没有尝试,所以就先这样吧,以后再设置前来玩。

    从朋友那里借了一个HHKB Pro 2 Type S,发现键位真是不太适应,刚刚适应一点,去别人那里总是按错键,也是小醉。

    ps. 本文编辑自MWeb

    by khsing at September 23, 2016 08:08 AM

    September 17, 2016

    @khsing

    再说阿里月饼事件

    之前我写了一篇《阿里价值观卖的是什么馅的月饼?》 说了一下我的看法,在那之后,事情有了新的进展,阿里集团把5人全部开除了,我也陆续看了一些相关和其他人的意见,就再说一次。

    先说阿里巴巴的最终决定,这基本上就是用一个错误去掩盖前一个错误的决定。他们讨论了4个小时,参与人包含了马云、逍遥子等人,基本就是阿里巴巴高管悉数出动了,而第一个决定只用了2个小时,参与人也就是HR、行政和这4个人的直接领导,另一个据说是阿里云的安全老人叶敏,在其领导道哥的周旋下虽然躲过了第一个决定,但是因此事把阿里巴巴放在公众风暴眼的情况下,几个大佬就做了一个简单但是他们却艰难的决定,叶敏也开除,从此阿里黑(阿里云除外,原话)。

    我在Eric 这一篇阿里月饼事件: My Concurring Opinion里注意到一个细节是此事之前有规定只能预定1个订单,最多3盒,单就这一点,从结果看这5个人都超出了规定数量,都违反了规定;到这里我也不否认这5名同学违反活动规定,采用技术手段影响了秒杀月饼这个活动的公平性(也仅仅是相比较其他没有使用技术工具的同学而言);

    真正值得争议的部分是阿里对此事的处置办法,在2个小时内让涉及此事的4名同学走人,罪名状是:违反阿里核心价值观——诚信原则。且先不论阿里价值观中是否有这一条,先说说这几位同学是否因此事可以确认他们就不诚信呢?诚信,诚实守信。这几名同学在发现预定月饼远超自己想要的数量后是主动向行政部门报告了此事,而且坦白说明使用了脚本来模拟点击秒杀月饼,这不是诚实这是什么呢?守信,单从此事我并看不出他们有失信于谁的行为。

    要说错,他们唯一的错在于抢的太多,影响活动公平性的问题也来自于此,要是他们脚本只抢1单或者系统只允许抢1单(没想到可以连续秒杀,换成真人去点也一样),我相信这个问题便不存在了。凡是认为他们使用脚本进行秒杀本身就是动机不对,此诛心之论,要是这样来说,凡是使用工具抢火车票的都是动机不对,理应枪毙;

    单从抢月饼一事我看不出这5名阿里员工有何违背诚信的地方。

    关于微博上 @吴军博士言论 , 我非常认同贺师俊的回答

    同时我也看到有人在知乎问 如果月饼事件(或类似的事)发生在 Google、微软或者 Facebook 这种公司,它们会如何处理? ,回答都很不错。

    喜事办成丧事,这也是阿里HR的本事。

    by khsing at September 17, 2016 04:36 PM

    May 03, 2016

    @shell909090

    唐僧被吃了

    唐僧被吃了。

    本来不应该发生这样的事的。

    正常来说,悟空会随时在师傅身边保护。要逃过悟空的眼睛,几无可能。因此唐僧的安全可以说是固若金汤。但是事有凑巧,今天是悟空回天庭报道的日子。由于悟空当年大闹天宫,被压在五行山下。今日戴罪立功,属于假释。所以按照天庭假释管理办法,需要每个月向天庭报道一次。当然,正常来说这种事情也就是走个过场。天上一日地上一年,每月报道一次是按地上时间计算的,所以在天上就是每个时辰出现一次,日夜不休。天庭监狱管理委员会的工作人员也受不了这个繁琐,所以文书手续,验明正身一概抽查。正常而言只要猴头出现,就算过关。

    但是今日,玉帝闲来无事,要去隔壁礼部视察。礼部主事和刑部尚书关系交好,于是偷偷通知了刑部尚书。万一玉帝没事干,出了礼部进刑部,那就是天大的麻烦。所以各种见不得光的事情都要收起来。因此悟空这几个月的报道格外麻烦。

    为此,悟空特意驾筋斗云前后看了一圈。附近地界太平,没有什么妖孽。又召出土地来问过,再三确认安全。于是向二师兄三师兄好好叮嘱了一番,这才上天庭报道去的。

    然后唐僧就死了。

    如来很生气,后果很严重。悟空队还没排到,就被监狱管理委员会的人扣下。西天联合天庭,成立天庭取经事故联合调查委员会,由迦叶尊者任首席调查官,主持调查工作。太白金星出任首席行政官,代表天庭协调双方工作。

    委员会成立后,首先对事情的经过进行了初步的调查,基本排除了悟空伙同外人作案的可能性。于是委托太白金星对悟空进行谈话,说服其配合委员会的工作。在这次谈话中,悟空才初次知道师父去世的细节。

    据天庭取经事故联合调查委员会的初步查证,事故是这样发生的。唐僧师徒行路到一半,看到个牌子,上面写着,大雷音寺,左转向前,还有28公里。于是唐僧师徒毫不怀疑的左转。结果前方并不是大雷音寺,而是小雷音寺。唐僧师徒住下后,唐僧在沐浴时不慎撞到头,昏倒在池内。童子问水是否够热无人回应,误以为客人喜欢热水。于是添足柴火,三个时辰过去,唐僧师父被煮成一锅老汤。。。

    太白金星话还没说完,就被悟空飞起一脚踢倒。还没站起身,就被悟空楸住领子:老官,你扯的什么鬼话。哪里有人会呆呆被烧一点动静都没有的,我师父又不是木头。这种鬼话就是骗童子都不够,你真当俺老孙呆子不成!

    太白金星连忙求饶:大圣,大圣,听我一言。当初调查委员会的人也是不信,可是小雷音寺的人说,西方有科卡罗斯煮死米诺陶斯,那米诺陶斯又不是呆子。为什么唐师傅的事就不可能是意外呢?

    悟空冷笑一声:就算是意外好了。他们装成大雷音寺,骗我师父入住,这才能不动声色煮死我师父。这冒充大雷音寺的罪过,总不是意外了吧。

    太白金星又说:这个我们也调查过了。对方拿出一份西天颁发的“关于鼓励信众自行传教的规定”,其中第一百七十三条第五款规定,为了传播西天教义,允许采取各种形式。因此小雷音寺的信众们就采用模仿大雷音寺的方式,向民众宣传大雷音寺的尊严。

    大圣顿时哑口:这种事难道教务办不管么?

    太白金星道:教务办哪里有空一个个检查信众自行传教的细节,最多也就是出了岔子找出首恶而已。实在乱子搞大了,了不起再出一个“关于禁止信众自行传教的规定”也就是了。

    悟空咬咬牙,再道:就算小雷音寺无事,那乱插路标,诱我师父前去之人呢?

    太白金星拨开悟空手指:大圣,小雷音寺的人对我们都拿的出“关于鼓励信众自行传教的规定”,对着人家自然也是拿出规定,说为了弘法,故此需要改标线路就是了。

    悟空双手抱胸坐下,翘起二郎腿冷笑:天下哪里有为了弘法,把正法指向邪路的道理。必是此人见钱眼开,没细细核对文件之故。

    太白金星道:悟空,你又何必固执。他又不是吃你师父的首恶,你何必和他过不去。要说细细核对文件,你前几次的假释报道,似乎也是核对不全吧。

    悟空轻叹口气:师父也许呆,俺老孙却不傻。小雷音寺敢仿大雷音寺而无事,显然是背后有人不希望我师徒前去西天。因此调查报告里鬼话连篇,就是不敢指摘背后之人的不是。我待罪之身,哪里能左右这些。俺老孙唯一能左右的,便是此为虎作伥之人。若不是他从中作梗,哪里来这许多事。周围乡邻,难免也为其所骗,拜错菩萨。难道你认为他无罪?

    太白金星微微一笑:非也非也,大圣你这么想是再好不过。

    悟空微微一愣:怎讲?

    太白金星道:既然小雷音寺众人无罪,这桩事总也需要个了结。你是观音菩萨保举,若说是你玩忽职守,大家面上不好看。西天的意思是,此人擅做主张,引诱唐僧师父到小雷音寺,以至招待不周,发生意外。此人负有不可推卸的责任。大圣你再做污点证人,说他当初也为你指路,并无什么不妥。以至于未曾察觉。

    悟空怒道:合着你们就是找我坑替罪羊来了?

    太白金星道:大圣,大圣。你不刚刚还主张要严惩此人?如今随了你心意,你又要怎样?

    悟空呆若木鸡,不知如何自处。

    PS:其实昨天就写完了,拿给霍叔叔看。霍叔叔说,你这类比太绕了。我说好,我想办法改改。结果还没等我改,取经事故联合调查委员会已经宣布了调查结果。再等下去怕是连西游记都要被查禁。所以赶紧出一版,大家凑合看看吧。

    by shell909090 at May 03, 2016 03:58 AM

    April 11, 2016

    @shell909090

    三亚潜水体验

    最近去三亚玩了,我就说潜水吧。

    水况

    潜水地点是在分界州,水不算太好。水下景点一般在深度5-15米范围内,有两艘沉船,一个飞机残骸。小沉船离岸比较近比较浅,水深不超过10米。大沉船需要再游一刻钟,深度15-18米左右。飞机残骸也差不多深度,不过只看到一点。水下危险生物包括狮子鱼石头鱼棘冠海星(魔鬼海星),水母。这次潜导在水下就被水母蜇了,被蛰的还很神奇。他下水就戴了面镜,升上水面就开始痛了,还被蛰在眼皮上。到底水母是怎么进去的就鬼知道了。不过问题也不严重,痛了一会就没事了。

    能见度分别比较大。在10米左右有一个明显的分界面。在分界面上,能见度大约是10米左右,下面只有3-5米。从上面明显能看到下面像一潭池塘一样。水底温度21-22度。我去的时候是四月上旬,所以只能代表这个时间点的情况。据说6月前后的时候能见度会好很多,水温也会比较高。亚龙湾和蜈支州的情况据说要好点,不过从我看到的水色来说,估计好不了太多。

    洋流情况还好,0.5m/s以下,一般都不构成问题。那天浪在0.5m左右,水面上有点晕。周围潜水环境还行,只是偶尔有人炸鱼,可能有巨响。另外水面上有摩托艇在开,和潜导分开的话,没有SMB上浮会比较危险。

    潜店

    这次潜水是走的中仁潜水的持证fun dive,价格是880两支气瓶。价格包括接送,上岛费用,一顿午饭。还包括了海豚表演门票。但是fun dive来说,根本没时间去看。

    BCD,fin,regulator是潜店提供的,他们问了我的身高体重来配fin和防寒衣。不过防寒衣是岛上提供的。我的体型比较大,所以穿了他们最大的防寒服。5mm的,比较适合水况,也很新,估计是穿的人不多的缘故。本来还问了我是否有度数,不过我的面镜和呼吸管是自带的,所以用不到。我还自带了3mm的手套,考虑到这里的水下危险生物,这个举措其实非常明智。

    岛上有免费的更衣和冲凉,但是寄包要20元。气瓶是中潜自己打的,一般都超过200bar。但是配重是公用的,比较烂。

    我们潜FD是岸潜,水面游动100-200米。DSD有一个平台,跳下去就行。平台那里比较浅,据说在5米左右。

    三亚潜水

    除了分界州外,我还去了一趟亚龙湾。在那里,我碰上了三亚名产——体验潜水。

    下车之后我就看到有人在做潜水培训。仔细看了一下,是一个潜水体验旅游的报名点。名义价格是400左右。我仔细观察了一下,整个点没有任何标志。没有PADI或者CMAS的标。

    在我吃饭的时候有人过来拉生意,鼓动我们潜水。我直接说我是PADI的持证潜水员,然后他就消失了。

    不做任何评论,大家自己分析。

    注意,在三亚海滩上是有打着PADI标志的潜店的,在PADI上也可以查到这家。不要以为我说的是他们。我其实在他们店里休息过一会,听了他们和客户的一些对话,觉得他们做生意还基本不过分吧。

    by shell909090 at April 11, 2016 04:33 AM

    March 25, 2016

    @shell909090

    潜水的一些简单解说

    潜水的乐趣

    潜水好不好玩?不好说。这得看你是不是喜欢潜水。不同的人在潜水中获得不同的乐趣。有人喜欢看鱼看珊瑚看沉船,有人喜欢水下漂浮的感觉,有人甚至只是泡妹子/帅哥。是的,潜水者里帅哥/美女的比例极高。因为潜水很要求体力,所以大部分人身材都很好,像我这种胖子绝对是少数(不过在学校里我看到了另外一个胖子,比我还夸张,衣服都是自带的)。我甚至看到一个学着学着潜水泡上了教练的妹子。。。

    是否适合潜水

    潜水的一般性要求是10岁以上,没有心血管疾病,癫痫什么的。细节可以去PADI网站上看一下。通常对于休闲潜水而言,大部分人都应该是没问题的。这里只说几个上面没有的问题。

    不会游泳能不能潜水?

    咳咳,我就不会游泳。

    潜水对游泳的要求是,能在水面上游动200米,或者在水面停留10分钟(我记得是这两个值)。这基本和会游泳没什么区别——除了通过条件。考核这项的时候,是允许你穿着防寒衣在海水里考的。这等于让你穿件救生衣问你会不会游泳一样,我想大多数旱鸭子的水性还不至于糟糕到这种地步。糟糕到这种地步的,坐船都要额外买保险了。

    但是会游泳还是非常有帮助的。如果会游泳的话,在水下移动的时候会很有优势。所以建议还是去学一下游泳。当然,你可以学以潜水为目标的游泳——主要就是不用换气。不求游多少距离,没气了站起来喘完了再游也行。

    潜水的另一个要求是胆大心细,遇事冷静。在水下碰到状况,很多都只能靠自己。所以胆子要大,但是遇事要冷静。

    当然,冷静谁也说不好。有的人平时也挺冷静,碰到大事了就突然反应不过来。大多数人都是这样,也不用不好意思。至于胆量,有个很简单的测试。找一个游泳池(当然,是淡水),3米以上,脚够不到底的地方。不穿救生衣,从岸上往下跳(注意,很多泳池禁止你这么做,请首先咨询管理员取得许可),跳下去之后游回岸边。捏着鼻子插筷子也好,摒气也好,随便你。看你的胆子和游泳技巧是否能够做到。如果做不到,例如不敢跳,或者跳下去根本不会游上来,那就不要费劲了。你跳下去不是潜水,是去找死的。

    技术解说

    携带呼吸装置潜水其实只有一个要点,就是呼吸。除此之外的东西都只能算是技术,学了肯定能会的那种。例如怎么组装备,规范动作怎么做什么的。智商没什么太大问题都很容易。

    可能很多人会首先说耳朵的问题。耳压平衡是潜水基础中的基础,一上来就会讲的。在水下做了平衡就不应该耳朵痛了。像三亚名产,不做平衡告知就丢下水,10分钟后耳朵痛就升水,那是道德问题,不是技术问题。如果学了耳压平衡但是做不到,那平时坐飞机都应该有问题,你需要检查内耳疾病。

    呼吸之所以重要,是因为呼吸关系到浮力。会游泳的应该有体会,浮在水面的时候,吐气就会下沉。潜水的时候也是一样,吸气上浮,吐气下沉。听起来很简单,但是水里需要呼吸不停,而且由于游动,呼吸量还不小。这种情况下如何保持稳定,就是一个非常有技巧的事情了。技术上说,这叫中性浮力。好的潜水员甚至可以靠呼吸停留在沙滩上十公分处,既不接触,也不浮上去。

    潜水的时候,身上的气瓶是负浮力。防寒衣虽然是正浮力,但是不足以平衡气瓶。如果只穿这两件的话,就必须不断踢水,停止踢水就会下沉。所以身上会背一个充气背心,来抵消气瓶的浮力。这样通过向背心内充放气,可以将全身的浮力和重力抵消到1公斤以内。人的一次呼吸一般潮气量在3000左右,换算成浮力有三公斤左右的波动,这样就可以通过呼吸来控制上升下降。一般操作上还会额外配一些配重,然后通过背心的浮力抵消配重。这样一方面在下潜的时候允许通过放气变的更重,可以有更大的余地。另一方面,在遇到紧急情况的时候,也可以通过快速脱下配重浮出水面(警告,这样很危险,容易产生减压病或肺部过度扩张)。

    浮力的难点在于,呼吸对浮力的影响是瞬时的,但是你很难感知现在是正浮力还是负浮力。你能发现的只有浮力对深度的影响,现在是往上飘了还是往下沉了。这就像顶杆子一样。你不能感觉到力,只能感觉到位置变化,不断调控。而呼吸要影响到深度,至少需要1-2秒的延迟。而且等你发现的时候,往往像火箭一样,停不下来了。好比上浮,吸一点气,我擦没反应啊。再吸一点?哎呦沃草升天啦。赶快吐气,我擦快停下,快TM升水了。好了好了。。。等等,我擦怎么变砖头了?再来。。。等你折腾一会,教练会让你看一眼压力。靠,没气了,升水吧。

    理论上说,要找保持悬浮,需要找准平衡气量,在这个范围内小幅呼吸。但是在不同深度下,充气背心的浮力是会发生变化的。潜水到后面,气瓶里空气不足,也会产生额外的浮力。你需要不停用经验发现现在的平衡气量是多少,围绕着小口呼吸,甚至有的时候需要充放气来重新平衡一下。

    中性浮力是很多东西的基础。例如在水下摄影,如果浮力一塌糊涂,一呼吸相机都抖成中风了,潜水又禁止憋气。那还照个P啊。从珊瑚上游过也是,如果浮力控制不好,要么离很远,要么你就会直接在珊瑚上砸出一个人型的坑。

    PADI的技术路线

    PADI的入门课程从小孩开始(骗钱从娃娃抓起啊),我们这里只说大人的。

    最低的是SCUBA Diver执照。一次体验潜水,然后做泳池课程和基础训练,再潜两次就能拿到。这个执照能潜12米深度。

    大部分人应该没听说过SCUBA Diver执照。因为只要再多两潜,几乎不需要额外课程,就可以拿到OpenWater执照(简称OW)。大部分人会直接潜水五次,拿OW执照。潜水深度从12米提高到18米,这样就可以去大部分地方潜水玩了。

    OW再往上是Advenced OpenWater(简称AOW)。AOW在拿照方式上和OW有本质性区别。OW是固定课程,你想不想,五节课都要过才能拿证。AOW是一堆专长,两项必修的,其他再选三项,就能通过。总计来说需要潜水五次,两次超过18米深度。完成AOW执照后,可以潜30米深度。

    上面这些深度什么概念呢?例如某次我们潜的Greenrock,一块大石头,三个顶部。最高的地方7米左右,最低30米没到(印象里的资料,可能不一定准)。SCUBA Diver的话就只能看三个顶部。OW的话就能绕着大石头一圈看岩壁和缓坡。AOW的话可以在石头底下绕一圈——正好有个班戟鱼的窝。所以很多点其实大部分执照都能下(甚至包括体验潜水),但是不一样的执照看到的东西会有差。除非你打算只去深度非常小的地方,否则执照当然是越深越好玩。当然,以休闲潜水来说,40米的深度还有很多地方去不了。但是安全起见(也是为钱包的安全),暂时就这样满足了吧。

    然后就是AOW的一堆专长。例如我修了一个鱼类辨识(看着很扯淡,其实就是看鱼玩),一个深潜,一个水底导航,一个沉船,一个顶尖中性浮力。其实大同小异(骗钱也是不手软哦)。除了告诉你一些技巧外,主要就是在不同环境下潜水。等潜水次数多了,自然就熟练和有信心了。

    AOW和AOW以下的执照,加大部分的专长执照,其实都不难拿。有钱,有闲,也就差不多了。甚至都不必须考。例如我需要去夜潜了,现场找潜店把钱交掉,题做掉。然后就可以带着去了,回来就拿到证了。无非也就是哪里拿的证和多少钱的问题。

    注意我说大部分。AOW有个专长叫潜水摄影,是问的最多的专长。尴尬的是,这货的难度非常高,我不知道为什么这货会进AOW专长课的。考这玩意一般需要学上几个礼拜,比DM都简单不了多少。当然,买的下潜水相机的人而言,倒是不会缺钱的。

    其中还有一个特别的执照,Nitrox,高氧潜水。高氧主要是用于长时间潜水,减少残氮量的。这玩意不是长时间潜水几乎不会用到。高氧的特别之处就在于,一,高氧潜水有额外风险,二,你可以拿高氧去潜深潜,从而一次性多拿一张执照。

    特别重复说明一点,并不是说氧气含量高了就能潜的深。恰恰相反,氧气浓度越高,潜水深度越低。纯氧在水下六米处吸了就有很大可能会挂掉,反倒是EANx32(氧含量32%)的氧气能允许你潜深33米。高氧的唯一目地就是减少残氮量,从而增加你的免停留潜水时间。这方面详细情况,我会写一篇关于高压空气的话题。

    要不要修哦?如果你可能会单次重复潜水,次数很多的,深度很深的,可以考虑。因为气比免停留时间还长。如果是一天两潜,深度又不高的。免停留时间本身就够,你要高氧干什么呢?急救?

    AOW再往上,潜到20左右,可以去出一张RESCUE的证。这张还要配修EFR的,贵的要死,不过基本没啥用。RESCUE是你能救别人,不是别人能救你。但是尴尬的是,又不是因为你有RESCUE执照就能带人潜水了——恰恰相反,你自己潜水还是需要人带的。而万一出了问题,正常来说带你的那个人急救资格都比你高(也肯定比你熟练)。那这张证能干嘛呢?在带你的那个人不在的场合下——例如不在潜水的时候——救人。

    你妹,不如说让我TM学游泳救人算了,还用的上点。

    潜够40,可以开始考DiveMaster(潜水长)的执照了。这个执照非常难,一般都要70潜以上才考出来。因为AOW和DM的差别就是业余和专业的差别了。在过了DM之后,你潜水就不需要人带,可以自己约潜伴了。

    我暂时还没搞明白,DM是不是能带AOW或者OW去潜,还是AOW或者OW必须由OWSI带。反正我碰到所有的DM都拿到了OWSI。

    DM再往下是专业线了,我记得不是很清楚,自己看吧。反正拿到这个证的,课程都远比这点发展线路复杂了。

    潜点选择,交通和成本

    每个潜点都有一些特点。例如珊瑚(珊瑚周围往往有大量热带鱼),石缝里的鳐鱼,海鳗,天然形成的洞穴,沉船等等。这些特点往往会对应不同深度。有的时候证不够就没什么必要去某个潜点——好比koh tao的Sattaukt这个点。沉船的位置在水下24-30米,没有AOW的证根本去不了,只能在上面远远看着。还去干嘛呢?不如去隔壁的Whiterock钻洞。还有一些点,会在特定的时间形成特色——例如鱼类季节性孵化和成长的时候。这些也需要提前搞明白。

    所以要到一个潜点前,需要查潜点地图,搞明白每个潜点的特色,需要什么证书,并且提前约好潜店和潜伴。不同潜店不同时间会去不同的点,有的潜店甚至需要提前预约才行,否则当前是没有船去的。至于约朋友——要知道,潜水行程意外太多,凑不齐人不奇怪,凑齐了才是意外。要潜店约一堆人容易,自己约朋友就纯看运气了。就算平安无事到了地方,万一碰到感冒就只能扫兴而归了(我不大建议吃通鼻子的药去潜水)。所以要珍惜每个和你一起潜水的朋友,能碰上是多大的缘分啊。

    每个潜点也会受到交通方式的影响。近海的潜点可以船潜或者从岸上下水,但是稍微远一点的,十有八九都要船潜,甚至需要船宿。这时候需要考虑自己是否受得了船宿的晃动和晕船。

    还有,来返潜点的交通方式往往用飞机。但是潜水18小时内是禁止坐飞机的。所以假期短的话,会耗费大量时间在潜水以外的时间上。这会使潜水成本大幅上升。建议能准备一些不潜水也能玩的地方来填充时间段,同时尽量准备长一些的假期。

    装备

    作为入门,一般你不需要买任何装备。大部分潜店都会租装备给你。大多数情况下,自带装备的运输费用(和劳动量)会比租装备还贵。唯一例外的是有戴眼镜的人的潜水面镜。潜水不能戴眼镜(废话)。为了安全起见,也不建议戴隐形(做过全面镜脱着的应该知道为什么)。所以建议你买一副潜水镜(注意,要罩住鼻子),然后凭你现在的眼镜度数去配光学玻璃装上去。

    如果体型特别巨大(脸好疼),可以考虑买自己的防寒衣或者全身式潜水衣。以免你想借却借不到的尴尬。水鞋没啥必要,反正一般常潜的脚底都应该够厚了,不常潜的买了你也用不上。

    如果经常潜水,例如一年五潜以上,可以考虑买一支自己的潜水电脑表。入门的也就千把块。自己的潜水表可以记录自己潜水的精确数据,潜店的装备里一般不会包含电脑表(除非租高氧气瓶),而压力表上连的那个二货往往功能有限不说(例如无法设定高氧),你也不能连着调节器一起拿走啊——那还不如直接买电脑表呢。

    值得初学者考虑的装备还有能在水下写字的板子和笔,水下的哨子(或其他声响设备),潜水手电。水下不能说话,通讯全靠手势。万一碰到手势搞不定的问题,不想升水只有用白板了。不过这种例子一般不多见,反正我潜了十多回就碰到一次,还是在水下考鱼类辨识。哨子非常有用,方便通知别人让他们看你手势。但是这玩意常规也不大用,一般只有DM叫人的时候用。如果有上过夜潜课的话,潜水手电也可以考虑入一个,大不了平时当普通手电用。

    一般好像很少有人会自带BCD的。我见过一起潜水刷瓶子打算考DM的一个妹子自己有一个背飞的BCD,但是实话说没感觉哪里必要。先不说价格,每次潜水回去的时候把BCD洗好收起来都是个大麻烦,更不提带来带去的重量。调节器也没见有人自备的,一般拿船上的就行。自己的还要定期找人检修维护,万一哪个岩石卡一下又要心疼半天。倒是O-ring可以自备几个,以免气瓶还在,O-ring没了。

    倒是很多不在装备清单里的东西很值得备一个。例如防水包。在船潜的时候,潜水日志啦,眼镜什么的要找地方放,还要防水。有个防水包会非常方便,还能放放衣服。还有,如果晕船的话,最好准备一些不嗜睡的晕船药。有的潜店会准备,但是有的潜店就不会管这个了。别以为自己不会晕船,你试试多潜几次再说。

    by shell909090 at March 25, 2016 05:16 AM

    March 06, 2016

    @xupeng

    团结紧张,严肃活泼

    今天,3 月 6 日,是豆瓣 11 岁生日,我做梦一样游了 798,看到大蔡司,还以为蔡司在这里开店了呢,

    后来才发现污龙了,

    然后莫名其妙来到中二街,

    稀里糊涂和自由女神合了个影,

    受到了严重警告,

    突然醒悟虽然圆外那么大,但可能眼界之内都是荒草。


    说完正经的,接下来是不正经的。

    我基本上是一个严肃的人,尤其是前些年工作中讨论或者解决技术问题的时候,这倒也符合其他角色对工程师的一贯印象,想起来大概是 08 年的时候,在前东家做 Intacct 的一个项目,Intacct 的 CTO Aaron Harris 对我的其他评价我现在已经记不清了,但是 “Poker face” 我至今都还记得很清楚,形容得相当精准,翻译成中文的话,我想最接近的应该是「面瘫」。

    去年参加了几次培训,遇到了一群全都不是工程师的人,第一天的时候我如坐针毡脸上自然也是 Poker 状,当然后面几天也没比第一天好到哪儿去,回来之后,有位同学看到我时不时在朋友圈里讲冷笑话,说:「哦,原来你不是我想象中的那种工程师。」

    其实,工作和生活中都有很多很好玩儿的事情,谐音、双关、翻译、重复、断句、曲解、自黑,处处都是脑洞,我还能记起来最早亲历的冷笑话,比我被称作 Poker face 还要更早一些,是同事们教老外 BA 学汉语时说,立春,意思就是 Standing Spring,他们还把公司的中文名字「华美汉盛」翻译成 “China Beauty Handsome”,正是这些好玩儿的事情,让我时刻不能放松学习的工作和生活更多了些趣味。

    最近我快三岁的女儿开始尝试自行解释一些她可能还不明白的词,比如因为大人长的大的所以叫大人,长的高就叫高人,长的小就叫小人,妈妈扫地扫的好所以叫扫地师,好像也很有道理的样子;再比如妈妈比较喜庆所以叫喜羊羊,爸爸走的慢所以叫慢羊羊,她自己很美所以叫美羊羊。

    我也自行解释一下我搞不明白的一个词:严肃活泼,那就是一本正经讲笑话,嘻嘻哈哈过难关,劳逸结合把事儿办。

    说起来汗颜,我前几天才刚刚读过一遍周爱民老师的《大道至简》,好书就是这种清清楚楚地把我已经知道、甚至已经在实践的事情再简洁地解释一遍,把我虽然有体悟但还有点模糊的道理一针见血地指出来,比如谈到到士气「三鼓而竭」这个话题,他说不认可甚至否定「积极、主动、敏锐、勇敢、主见」这些良好品质,是大多数公司无效率无创新的根源,「想法好不好」是技术问题,但态度是要认可的。恰好在几个月前,我觉得某个同事的想法太超脱实际而不认可他的那些主意,但同时也在无意中打击了背后的良好品质,读到这里,我真是直冒冷汗,这关乎中二,关乎眼界,关乎眼界太窄导致了中二。

    最近两年多我个人最大的一个变化是,我在工作和生活中可以越来越坦然地承认和面对自己过往的错误,并在自黑中纠正,但在更早的时候,害怕犯错、害怕面对已经发生了的错误的确给我带来过很大的压力,要我说,以玩笑的态度的去释放压力,在这个过程中给了我最大的帮助。

    March 06, 2016 09:22 PM

    @khsing

    油猴脚本加载微信公众号的图片

    微信公众号的文章图片使用了 Lazy Load 模式,导致使用 Evernote Clip 剪贴的时候就没有图片,这里有一个 Weixin Image PreloadUserScripts。Safari上需要安装一个 NinjiaKit的扩展。

    by khsing at March 06, 2016 09:14 AM

    February 27, 2016

    @xupeng

    最容易被忽视的,是常识

    同事最近在拆分数据库和清理数据,这当中有一些趣事,比如在拆分一个叫 luz 的集群时,新拆出的集群被命名为了 lua,可以从至少两个角度来理解这个名字,最显而易见的它是一门语言,除此之外它还代表从 z 到 a 的新一轮轮回;再比如拆分另一个叫 eag 的集群时,新集群被命名为 eager,不过它诞生时的含义其实是「eag 的 er 砸」。

    也有一些哭笑不得的问题,比如发现有些应用的数据清理 cron 曾经有日子没被成功执行,导致数据文件的体积相比它应有的大小暴涨了一个数量级;还有比如发现 Sentrynodestore_node 表涨到了几百 GB,检查的时候看到 nodestore 的 schema:

    1
    2
    3
    4
    5
    6
    7
    
    CREATE TABLE `nodestore_node` (
        `id` varchar(40) NOT NULL,
        `data` longtext NOT NULL,
        `timestamp` datetime NOT NULL,
        PRIMARY KEY (`id`),
        KEY `nodestore_node_d80b9c9a` (`timestamp`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    它都有哪些问题呢?

    脱离业务场景,孤立地看这个 schema,除了这三点可疑之处外其实并没有太多值得挑剔的:

    1. Primary key 比较长(40 个字符),通常是一个不当设计的预警信号。
    2. 写入纪录的顺序和主键索引序可能不同,潜在的问题是影响写入性能,并可能导致数据页碎片化进一步影响读性能。
    3. timestamp 字段使用了 MySQL 的关键字。

    那么再了解一点点业务,通过阅读 Sentry 这部分的代码可以了解到这些:

    1. id 要存储的原始数据是 UUID version 4,16 字节,但在存储之前用 base64 编码为可打印字符串,编码后的长度为 24 字节。
    2. data 所存储的数据是把结构化数据序列化,之后用 zlib 压缩,再把压缩之后的数据使用 base64 编码为可打印字符串。
    3. timestamp 字段是数据写入时的时间,这个字段的索引用于按时间删除旧数据。

    考虑业务的需要,这个 schema 还有哪些问题呢? id 字段使用了 utf8 编码(在 MySQL 中是 1-3 字节长度的变长编码),最大长度是 40 字符,id 字段是主键,在索引中以最大宽度对齐,再加上 varchar 类型最大长度标示 2 字节,也就是 40 * 3 + 2 = 122 字节,不仅在主键中如此,在二级索引 nodestore_node_d80b9c9a 中也是如此。

    那么怎么改进呢?

    1. 由于业务上 id 是 16 字节 的 UUID version 4,但编码为 24 字节的可打印字符串,因此在不修改业务代码的前提下,可以对业务透明地把 id 列的定义修改为 id char(24) CHARACTER SET latin1 NOT NULL,这样在索引中的宽度就可以从 122 字节减小为 24 字节。
    2. 如果对业务代码做小幅重构,可以使用 binary(16) 来存储 UUID version 4,可以进一步减小为 16 字节。
    3. data 字段所存储数据的长度大多分布在几 KB 到几十 KB 之间,以 20KB(20480) 为例,base64 编码之后的长度为 27308,比未编码数据增长了 33+%,如果可以牺牲对人类的可读性(实际上人类也直读不了 base64 编码的字符串),直接存储 zlib 压缩之后的二进制数据,就可以省掉这 33% 的空间浪费,这一部分的浪费在整个系统中所占的比重相当可观。
    4. 在 Sentry 的场景下,nodestore 是典型的写多读少,如果再加入一列自增列作为 primary key,把 id 改为有唯一性约束的二级索引,可以提升写入性能、减轻数据页的碎片化,同时还能进一步节省空间。
    5. 使用自增列(记作 dummy_id)作为 primary key 之后,在这个场景下 timestamp 字段实际上和 dummy_id 同序,按时间删除旧数据的需求就可以不必借助 timestamp 字段的索引,使用笨笨的二分法找到需要的时间边界,然后按对应的 dummy_id 作为条件来删除即可,每行纪录可以节省 24 字节。

    做到这些有多难呢?

    回顾一下上面所提到的问题和相应的优化手段,可以发现所需要的只是在理解业务的基础上,对数据库的工作方式也有基本的理解,但更实际的情况是,大量的产品开发者在编写 Model 代码时随手就会写下 max_length=255,完全没有意识到产生的列定义会是 varchar(255),或者压根儿没有意识到这么做会有什么影响,几年前我自己在做产品开发的工作时也是这样的习惯。相对来说,我愿意相信这里写了 max_length=40 而不是 max_length=255 是一个经过深思熟虑了的决定。

    要做到对数据库和索引的工作方式有基本的理解,难吗?很多同学会觉得不就是读一读文档吗没有什么技术含量啊,事实也正是如此,只要能阅读和理解文档,加上必要的动手实践,都能有超越类似场景要求的理解,比掌握一门语言要简单太多,既不需要高于普通人的智商,也不需要加班加点地埋头苦干,所需要的仅仅是踏实的态度和一点耐心,再加上一点思考。

    再举个例子

    这是随手从某著名产品中摘出的 schema,就不在这里做更多的问题分析了,不过我相信仅仅依靠上面提到的几点常识,就能看到很多问题,这多多少少能进一步说明,优秀的产品一样会有糟糕的实现,但是,这些产品不都好好的是吗?是不是应该再思考一下技术的价值,以及技术和产品的关系呢?😂

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    
    CREATE TABLE `storage_blobs` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `oid` varchar(255) NOT NULL,
        `size` bigint(20) DEFAULT NULL,
        `created_at` datetime NOT NULL,
        PRIMARY KEY (`id`),
        UNIQUE KEY `index_storage_blobs_on_oid` (`oid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2580 DEFAULT CHARSET=utf8;
    
    CREATE TABLE `users` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `login` varchar(255) NOT NULL,
        `crypted_password` varchar(40) DEFAULT NULL,
        `salt` varchar(40) DEFAULT NULL,
        `created_at` datetime DEFAULT NULL,
        `updated_at` datetime DEFAULT NULL,
        `remember_token` varchar(255) DEFAULT NULL,
        `remember_token_expires_at` datetime DEFAULT NULL,
        `wants_email` tinyint(1) DEFAULT '1',
        `disabled` tinyint(1) DEFAULT '0',
        `plan` varchar(255) DEFAULT NULL,
        `billed_on` date DEFAULT NULL,
        `auth_token` varchar(255) DEFAULT NULL,
        `upgrade_ignore` varchar(255) DEFAULT NULL,
        `upgrade_accept` int(11) DEFAULT NULL,
        `role` varchar(255) DEFAULT NULL,
        `billing_attempts` int(11) DEFAULT '0',
        `spammy` tinyint(1) DEFAULT '0',
        `last_ip` varchar(255) DEFAULT NULL,
        `plan_duration` varchar(255) DEFAULT NULL,
        `bouncing_email` tinyint(1) DEFAULT NULL,
        `billing_extra` text,
        `gift` tinyint(1) DEFAULT NULL,
        `type` varchar(255) DEFAULT 'User',
        `last_read_broadcast_id` int(11) DEFAULT NULL,
        `raw_data` blob,
        `referral_code` varchar(255) DEFAULT NULL,
        `billing_type` varchar(255) DEFAULT 'card',
        `braintree_customer_id` int(11) DEFAULT NULL,
        `bcrypt_auth_token` varchar(255) DEFAULT NULL,
        `suspended_at` datetime DEFAULT NULL,
        `organization_billing_email` varchar(255) DEFAULT NULL,
        `gravatar_email` varchar(255) DEFAULT NULL,
        `time_zone_name` varchar(255) DEFAULT NULL,
        `session_fingerprint` varchar(255) DEFAULT NULL,
        `token_secret` varchar(40) DEFAULT NULL,
        `require_2fa` tinyint(1) DEFAULT NULL,
        `restrict_oauth_applications` tinyint(1) DEFAULT NULL,
        `spammy_reason` varchar(255) DEFAULT NULL,
        `seats` int(11) NOT NULL DEFAULT '0',
        `split_diff_preferred` tinyint(1) NOT NULL DEFAULT '0',
        `custom_volume_discount` int(11) NOT NULL DEFAULT '0',
        `tenant_id` int(11) NOT NULL DEFAULT '1',
        PRIMARY KEY (`id`),
        UNIQUE KEY `unique_index_users_on_login` (`login`),
        UNIQUE KEY `unique_index_users_on_login_and_tenant_id` (`login`,`tenant_id`),
        KEY `index_users_on_billed_on` (`billed_on`),
        KEY `index_users_on_type` (`type`),
        KEY `index_users_on_referral_id` (`referral_code`),
        KEY `index_users_on_last_ip` (`last_ip`),
        KEY `index_users_on_plan_and_billing_type_and_type` (`plan`,`billing_type`,`type`),
        KEY `index_users_on_updated_at` (`updated_at`),
        KEY `index_users_on_spammy` (`spammy`),
        KEY `index_users_on_braintree_customer_id` (`braintree_customer_id`),
        KEY `index_users_on_suspended_at` (`suspended_at`),
        KEY `by_billing_email` (`organization_billing_email`),
        KEY `by_gravatar_email` (`gravatar_email`),
        KEY `index_users_on_role` (`role`),
        KEY `index_users_on_created_at` (`created_at`),
        KEY `index_users_on_tenant_id` (`tenant_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=198 DEFAULT CHARSET=utf8;
    

    我昨天由这个问题吐槽了一下 Sentry,引来了一些讨论和建议,比如大句哥哥和 XTAo 说 Sentry 官方推荐用 PostgreSQL,不过就这个具体的问题来说,如此设计恐怕在 PostgreSQL 下也不是好的实践,更重要的不在于用什么,而是怎么用好它,话说回来,要把 Sentry 用好,也得对 Sentry 有更多的了解和理解才行。

    最后,推荐几则不错的文档和书

    February 27, 2016 01:40 PM

    February 25, 2016

    @shell909090

    一个有趣的问题

    前面给公司出了一个有趣的问题,似乎没采用。所以现在放出来大家看着玩玩。

    以下代码在python2中适用。python3请看尾部注释。

    import os, time
    data = range(10000000)
    pid = os.fork()
    if pid < 0:
        print 'error:', pid
        os.exit(pid)
    if pid > 0:
        os.wait()
        os.exit(0)
    sum(data)
    

    在第2行执行的前后,使用ps和free观察内存使用情况,可以看到进程使用了320M内存,系统被占用了320M内存。在3行执行后再观察,有两个进程分别占用320M内存,系统总计被占用了320M内存。 问1,为什么两个进程分别占用320M左右内存,系统总计占用数并没有翻倍?这种现象叫做什么?

    在10行执行后再观察,有两个进程分别占用320M内存,系统总计被占用了560M内存。 问2,为什么sum增加了系统内存占用,解释其开销。

    问3,推测出python整数对象长度和当前CPU字长。(python自身的内存开销忽略)

    答1. 这种现象叫做COW,copy on write。在fork后,两个进程会共享内存表项,一致的部分会仅使用一个页面。

    答2. 每个进程的内存占用都没有上升,但总内存占用量上升了,这必然是发生了页面写时复制的结果。页面写时复制必须写入内存,因此推测python使用引用计数 手段控制对象生命周期。当sum时,每个对象都要被读取。在读取前,系统会增加其引用计数。在这个过程中会发生页面写时复制,导致系统内存占用上升。

    注:内存复制必须发生在写时刻,说读取导致内存复制的统统不得分。答出引用计数四个字即可得全分。

    答3. 在写时复制时,数字对象会增加引用计数,而数组对象不会(准确的说,数组对象本身引用计数会增加,但只有一页会发生复制)。发生复制增加的内存有 240M,因此整数对象长度24字节。未倍增内存有80M。对象有10M个。因此推断指针长度为8字节,当前CPU字长64位。

    注:python3里有几个不同。首先,range返回了一个生成器,所以需要改为data = list(range(10000000))。其次,python3中,int长度为28,pointer长度为9。因此下面的数据会需要调整,而且并不很容易解释。

    by shell909090 at February 25, 2016 07:19 AM

    February 19, 2016

    @shell909090

    一次升级故障的排查

    问题描述

    前两天,我收到了USN-2900-1通知,glibc上有个严重漏洞,可导致DoS或(可能性的)执行任意代码。这个USN对应的CVE是CVE-2015-7547,我相信很多人应该听说过这个漏洞,或者应该已经修复了。我也不例外,很快的推进修复了这个漏洞。收到消息6-7小时后,已经看到了POC

    OK,我们本次不是讨论这个漏洞本身的。在漏洞修复后,有一台设备报错,无法安装程序,wget都无法执行。很有可能是漏洞修补补丁导致的。由于这个机器很关键,目前很难迁移,所以我需要找到原因。另一方面说,如果无法明确原因,已经执行补丁的机器群将无法确定可靠性。因此无论如何,必须要研究一下原因。

    出问题的机器是一台ubuntu12.04,修补的版本号为2.15-0ubuntu10.13。

    处理过程

    首先,CVE的说明表明这个漏洞来自于getaddrinfo调用。因此首先确定问题和这个调用的关系。使用python,import socket,然后执行任意一个socket.getaddrinfo。python崩溃了。这就说明问题很可能来自本次修补。当然,同时的测试中表明wget也会崩溃,但是dig没事。所以dig很可能并没有产生getaddrinfo调用。

    而后,我使用strace和tcpdump追踪了一下程序。tcpdump表明一切正常,并没有人正在攻击系统,因而可以排除修补不妥当加正在被攻击导致的崩溃。strace中断在ioctl调用后,除了进一步明确当时正在进行DNS查询外,并没有给出太多有效的信息。

    常规来说,下一步应该是gdb。但是由于apt无法执行,所以gdb装不上去。因此我跳过gdb,先翻了一下USN-2900-1补丁的细节。这个补丁里包含了所有ubuntu自己打上去的补丁,因而有点大。但是仔细看之后可以分离出CVE-2015-7547补丁的位置:debian/patches/any/CVE-2015-7547.diff(还有pre1和pre2)。仔细阅读修补代码,尽管对逻辑并非十分清楚,但是并没有看到什么奇怪的错误。结合剩下的机器并没有问题,我基本认为这个补丁是没问题的。

    后面很幸运的,向才发现虽然apt-get update不行,但是apt-get install却没问题。不知什么原因,总之我们有了一个能用的gdb系统。通过gdb,我确定了出问题的代码行号。我本来想省点事,从补丁上直接读出出问题的行(eglibc-2.15/resolv/res_send.c:1303)。但是很遗憾,出问题的行本身似乎没有什么问题。(*ansp2_malloced = 1;)虽然可以看出是ansp2_malloced跑飞导致了SEGFAULT,但是并没有提示为什么。所以还是得需要完整的源码。

    然后就是debian包维护的基本功夫。首先用apt-get source libc6下载源码。再用dpkg-source -x解开文件。进入目录里,用quilt push -a应用全部补丁(细节看这里)。这样就得到了和线上一致的完整源码。我本来想将整个过程在目标机上完成,但是目标机上却无法安装quilt(根本找不到这个包,由于apt-get update无法执行,我也无法修正这个问题)。所以最后源码的补丁是在我本地的workstation完成的。

    无论如何,我按照gdb的bt输出,仔细核对了出问题的代码。问题确实是出在了ansp2_malloced,这个值为0。但是这个值是逐层传递的参数,传递的最后几行表明这个值都是0,而在前面,这个值是有有效值的。可是吊诡的是,在有效变为无效的过程中,指针并没有修改过。

    这个值是在__libc_res_nsearch(resolv/res_query.c:331)里发生变化的。在这个函数里,这个指针叫做answerp2_malloced。根据gdb的bt,在函数入口上,这个数值不为0。但是到了第421行,调用__libc_res_nquerydomain的时候,就变为了0。而从函数入口开始按照顺序搜索answerp2_malloced,都是对指针的值的修改,并没有对指针本身修改。函数也是传递指针,而不是双重指针。也就是说,answerp2_malloced在一个并不可能改变的代码段中被改变了。

    读到这里的朋友,有兴趣的话可以先不要往下看,先猜猜原因。这个神秘的现象直到我看到结果,才反推出来为什么。

    原因

    我在这里被卡了很久。后来在无聊中,往下看了一下bt。留心到其中某个函数并没有调试信息,因为这个函数所在的so文件位置不对。仔细一看,这是一个glibc的库,但是却在/usr/local/lib下面。

    我X。是哪个孙子把系统库的部分拷贝到了其他位置,还改变了LD路径。。。拿一个版本的glibc和另一个版本的glibc库混用,不出问题才见鬼咧。把这个so文件改名后,问题立刻解决。

    复盘

    事后根据复盘。这个参数其实是为了修补问题,新加的。原本__libc_res_nquerydomain函数并没有这个参数。然后为啥能跑?这涉及到linux下C的入栈顺序。这里不讲细节,如果你有兴趣,先看这个。再往下看复盘。

    根据调用规则,调用者首先会对现场压栈。他会将需要保留的寄存器入栈,以防子程序改变他们。然后他会根据C规则或pascal规则入栈参数。最后call指令会将当前IP入栈,并且转跳到指定地址上。以这里的情况看,应该是默认的C规则。

    C规则的好处在于被调用者获得的是栈顶相对位置,其余参数向栈底依次展开(注意下面用的全部是栈底/栈顶,由于对口,实际内存分布一般是反过来的)。使用BP+8,BP+12这种规则来访问。因此调用者可以传递变长参数。无论你在实际参数之前入栈了多少个数据,只要调用者最后记得把这些数据出栈,就不会对执行构成影响。而pascal规则则不然,为了获得参数位置,被调用者必须知道传入了多少个参数。例如访问第一个参数,就需要用BP+4*N+4来访问(当然在编译时这个数字会被静态的算出来)。如果你在实际参数之前入栈了数据,那么被调用者就需要用-1这种方法去访问这些数据了。而如果在实际参数之后入栈数据,整个参数位置都会错乱掉。因此pascal规则一般被认为是不能传递可变参数的。

    但是C规则的这个优势,在这里变成了问题。调用者的代码还是打补丁之前的版本,而被调用者的代码则是打补丁之后的了。因此__libc_res_nsearch将参数入栈前入栈的最后一个元素认做了最后一个参数。这个元素,可能是需要保存的现场,也可能是局部变量。

    如果__libc_res_nsearch将现场当作了最后一个元素的话,将无法解释这个值为什么在后面发生了变化——被保存的现场一般来说是用于未来的恢复的,他们不应当发生变化。而如果是局部变量则相反,局部变量的指针经常被当作参数传递给子函数——这也是经典的C多值返回方法。

    如果__libc_res_nsearch确实接受了局部变量的地址作为参数,他可能会向这个地址写入任何东西——例如0。这就造成了这个地址在调用时有值,但是在使用时值被清零,又找不到任何地方修改这个值的缘故。

    当然,这里也有很多疑惑。例如局部变量顶上一般会保存被调用者需要保存的现场。无论如何,参数和局部变量之间一点现场都不隔,是件很奇怪的事情。而现场一般是不变的。对于这点,我没时间去反向源码并分析栈的实际情况,谁知道可以告诉我。

    这是一个调用者(caller)的原型认知比被调用者(callee)少一个参数的结果。如果事实反过来,调用者的原型认知比被调用者对一个参数,那么代码执行将不会有任何麻烦。

    事后分析

    这个故障最主要的原因是有人将系统库复制到了/usr/local,并修改了LD顺序。

    glibc确实是一个几乎没有改动的库,但是这不表示他不会改动。根据我这里的记录,在过去的一年半时间里,他改变了八次。有趣的是,最早一次改动也是因为getaddrinfo的漏洞做修补(USN-2306-1)。也许是运气好,前几次改动中并没有调整参数,或者对参数的意义做变更。因此老代码和新代码的混合调用并没有出现问题。然而本次修补就过不去了。

    这并不是ABI的错——ABI承诺的是“向外暴露接口”,而libc中的内部互相访问显然不在其中——谁会承诺自己内部结构的ABI兼容性呢?那会让稍微复杂点的重构都无法进行。

    根本的问题在于,为什么有将glibc中的一部分提取出来,放在/usr/local中固化的需求呢?(或者对glibc的实现做调整)而且从操作上,即使我们需要对glibc动手脚,最好将整个编译结果放在/usr/local中,完整替换全部的glibc库。当然,这个行为会使得glibc的修补补丁彻底失效。根据运行时错误好过逻辑错误的理论,这是一件比崩溃更糟糕的事。

    更糟糕的问题并不在glibc上,而是这台机器的维护状态,还好这是一台开发用机,而不是在线机器。如果有人知道这台机器的LD被做过手脚,应该很容易能够想到这个问题的原因。但是在复盘中我询问多个人,都不知道这台机器被如此设定的理由,甚至没人知道如何维护这台机器。实际上这台机器的维护曾多次易手,其中有些人根本已经离职。即使尚未离职,也未必记得自己到底做过哪些事。而我也找不到任何相关文档表明这台机器被如何的维护了。这也是为什么这台机器不好迁移的原因——在机器上有太多明的暗的诡异的workthrough,要将其迁移到另一台机器上是件耗费人工的事。我维护的很多机器(帮朋友维护)也处于类似的状态。维护时间太长,经手人多次转手,上面很多设定完全黑化,要迁移需要付出相当代价,等等。。。

    docker能解决这个问题么?

    不好说,这个问题有点复杂。

    从本质上说,docker解决不了这个问题。因为一个workthrough,存在于整个系统中,还是存在于一片dockerfile的海洋中,其实没太大区别。如果我会跑上去就看dockerfile,然后从一大堆过程中一眼看出问题,那我也会在这次解决中先去看LD设定。最低限度,看bt的时候根本不用参考源码,往下看两行就知道原因了。而即便知道原因,这句cp存在于里面的原因仍然未知。我不知道为什么会把这个文件cp到/usr/local,无论是机器上实际存在的复制,还是dockerfile中的cp语句。最后实际有帮助的,还是在这句cp上注释的信息,或者机器上留存的维护文档。

    但是docker是有帮助的。首先使用了docker起码好迁移了。当然,这不是他最大的帮助。

    docker最大的帮助帮助并不是来自于能够帮助我简化寻找流程,或者知道原因。而是来自于减小系统规模,甚至可以将系统规模降低到需要的最小规模。在一个复杂系统中,寻找一个workthrough,或者知道为什么是困难的。但是在简洁系统就容易很多,非常多。

    当然,将复杂系统拆分为简洁系统是有代价的,并不那么容易的。在这点上,我比较信奉熵增原则。在增大系统规模的时候,系统的熵永远是增加的。如果要降低熵,就需要对这个系统做功,无论从哪个方面。随着手段不同,做功只有大小差别,而没有一颗“一次解决”的银弹。从这个意义上说,docker并不能解决这个问题,他只是能降低你需要做的功。

    而如果对某个系统做功并不产生实际效用(而只是为了将来可能性的维护便利)时,这部分开销就可能被砍掉。反正解决了问题并保持一段时间,相关人员可能就不再继续维护,或者高升,或者离职,或者根本转行。于是系统中(包括代码和维护)会不断产生各种workthrough,“将来要修”的承诺,和随着不断的人员变更不再有人记得的暗创。最后系统就会变成遗留系统,没人知道为什么,没人敢动,也不敢停。静静的在那里,吞噬一批又一批IT从业人员的青春,同时也产生更大的熵。

    by shell909090 at February 19, 2016 09:39 AM

    January 11, 2016

    @khsing

    Django中使用多数据库和裸SQL

    有时候一个项目可能会使用多个数据库,而且数据来源可能不同,在Django中支持多数据库,同时不用ORM的情况下直接执行SQL的方法如下,做个笔记

    from django.db import connections, connection
    cursor = connection.cursor() # 这是settings.py中定义的default数据库
    cursor2 = connections['mysql'].cursor() # 这是settings.py中定义的mysql数据库
    

    剩下的操作主要靠 PEP 249 的规范

    by khsing at January 11, 2016 04:20 PM

    @shell909090

    关于程序员和产品经理两大世界体系的对话——论快播庭审

    最近快播的段子都快传疯了。很多网友也在那里分析快播有没有罪,辩护有没有问题之类的。其实结果对我来说一点都不重要。快播有没有罪,这个留给法庭审判。我今天要说的是庭审所暴露出来的一些问题,一些我日常中经常看到的问题。

    我们先看两个段子(其实基本是庭审里的事实):

    审判长问:文件加了密,你为什么不解密呢?

    张克东:如果达不到一定的码率,快播软件就会启动缓存服务器开始加速,达到了码率,就会自动断开。
    法官:软件它为什么会知道?它是机器人么?

    也许有些人看到段子1,会喷国家审查啊什么的。其实这不是审查,而是无知。审查一定是懂行的,无知才会要人解密。至于段子2,也有类似的问题——码率的衡量问题在大多数程序员,甚至包括懂一点技术的用户那里都不是秘密。问“软件为什么知道”,实际上非常无知。

    甚至同样的问题,也存在于某些网友的评论中。例如这篇。我引用这个评论段落:

    我看到不少网友以此取笑法官如何外行。其实法官非常聪明,不管张克东如何回复,都回避不开“软件如何知道”,也就是系统如何识别片源问题,只要这个回答了,你快播就摆脱不了你”清楚”播放哪些视频的问题。

    如果懂一点技术的话,应该明白一点。对软件而言,码率一定是知道的。而内容,则未必。或者换个对不了解技术的同学们更友好一点说法。对浏览器而言,网页上的图片的大小,格式,都是知道的对吧?浏览器也可以用来浏览黄色网站对吧?那问题也一样,软件它为什么会知道?

    红衣主教,是不是该轮到你出庭聊一聊了?

    同样,所有聚焦点在“软件应当可以监管浏览内容”的人,同时也面临这么个问题,浏览器是否可以监管黄色网页?作为处理数据流的软件,肯定是了解被处理数据的格式,大小,码率等参数的。那么处理软件是否应当对被处理的数据的内容合法性负责呢?如果是的话,那毫无疑问,所有黄色信息都必然经过了Intel和AMD两家生产的CPU,而且绝大多数也经过了Windows。

    实际上,整个庭审中通篇都是法官和公诉人各种技术外行。例如用IP地址标识服务器,硬盘大小标识硬盘等等。如果在国外正常庭审,这证据其实就算废掉了。因为被告可以当场演示给你看改IP地址,你连服务器是不是他的都无法证明,还怎么构成证据链呢?当然,在中国来说,最后是否取信还是合议庭说了算的。

    对于程序员来说,这个故事是不是很熟悉?是不是觉得和产品经理打交道很像?一样是对技术一无所知,却对一无所知不以为耻。我碰到过一个产品经理,自以为提了一个很犀利的需求——为什么我们不通过软件自动算出地址,还要客户自己填?

    我听到这个问题的时候,估计表情和听到“为什么不解密”时的表情是一样的。心里一万头草泥马奔腾而过——合着不是你实现啊。尼马我怎么算?IP地址只能知道大致地区,还不一定准。GPS当时还不是每个浏览器都支持,就算支持也只能算出坐标,算不出地址。

    很多时候,产品上的一点小小的改变,往往是技术上的翻天覆地。不信你考虑一个论坛系统,如果做到像腾讯那么大流量的时候会是什么样一个样子?再考虑一个交易系统,在同样一个量下是什么样子?前者应该还能做,后者应该已经没法弄了吧。为什么同样是个网站,同样的量,一个没事,一个挂了?

    因为论坛系统是典型的无事务低写高读系统,因此可以使用分库分表,多层缓存的方法来增强性能。而交易系统是典型的事务,没法用这个手段。所以交易系统在海量压力下的技术难度,和论坛系统在海量压力下的技术难度,其水平和重点根本不是一类的。从这个意义上说,淘宝双11,很不容易。

    而这种技术难度,产品经理是不知道的。所以他搞不好会给一个超大流量论坛提出一个很实在的需求——咱们弄一个内部交易系统吧,应该会变成不错的盈利点。呵呵。这个系统要么做出来会有各种各样的事务问题,要不然这个系统大量使用的时候,整个系统(做的好的话应该不会波及论坛)就会慢到无法接受。

    当然,现实中一般是没有这么大论坛的。京东实打实在事务性能上吃过亏没错,但是那时候京东已经多大体量了?一个论坛,要引流过去那么大体量,自身得多大?但是这个例子本身说明技术难题的非直观性和在下判断时的必要性。如果你不了解这个技术本身会引发什么问题,你就无法得到合理的结论。

    作为产品经理,或者要和技术打交道的一切人士。不懂技术并不可耻,可耻的是不懂技术又无视技术。既不去学,也不去问。装作技术不会对他产生影响,装作不懂技术并不影响他决策的权威性。

    与此形成对比的,是微软垄断诉讼案中法官的表现。那个案子里,微软律师强调的是IE内核和windows系统的严密整合,导致两者几乎无法拆分。从软件架构角度来说,这没错。但是法官很明白里面的门槛——保留IE内核不代表保留IE。鼠标一点,IE直接从系统中干掉。虽然内核还在系统上,但是不额外安装IE的话,无法使用浏览器。如果没有后来的一些事的话,估计微软就难逃一劫了。

    话题拉回到快播庭审的事情上来。快播有没有问题?排除色情非罪化(我支持内容分级审查和色情非罪化),我觉得是有的。就好像我们说**的时候,一般都会想到约炮。(由于某些因素,我不能写出这两个字来。但是如果你这两个字和我想的不一样,那你的问题就大了)如果快播没有放任色情传播的话,是很难做到这么大的,更不可能做到我们一说找XX内容就想到快播。这不能说因为检方派了几个猪队友,所以快播干净了。

    但是这个问题是不是罪?这不好说。定罪这个事情是个专业性很强的活,我的法律知识不足以下这个判断。但是个人意见,我觉得应该无罪,至少不能拿缓存服务器上的色情信息来定罪。如果缓存服务器上有色情内容就可以定罪的话,那铁通小区宽带就可以直接去转型了。因为他们为了减少对电信的依赖,降低流量结算费。在小区里都是装了缓存服务器的,而且是强制透明缓存,想不做都不行。小区里有没有人看色情网站?他们为什么不人工看?

    看,这又是一个不懂技术就不知道我在说什么的问题。对用户来说,可能铁通的感觉就是“不好用”。技术人员才知道,电信和铁通的流量结算价格问题,还有铁通(以及各种小ISP)的透明代理的存在。知道这个透明代理和快播的缓存是不是在技术上是等效的。

    还有解密,可行不可行?对于快播来说,要解密应该是可以的。但是对于百度网盘来说,连解密都不行。我把我的一堆生活照在百度网盘上备了个份。为求安全,我用GPG做了加密,然后再用SHA256。我自己倒是问心无愧,但是对百度来说,里面到底是不是色情内容?我觉得百度要是还能解开,不妨把技术卖给CIA。

    by shell909090 at January 11, 2016 05:00 AM

    January 04, 2016

    @khsing

    科学使用Android

    在兲朝科学使用Android,到了Android 6.0重置之后恢复应用的功能终于可以和Apple iOS相提并论了,然而在兲朝还是不太行;步骤如下
    1. 开Debug模式,adb 安装 ShadowsockBarcode Scanner
    2. 我使用了12vpn的SS服务,扫描二维码添加配置
    3. 开启SS后等待自行恢复
    4. 登陆一些需要重新登录的App(大部分需要,还是不如iOS)

    by khsing at January 04, 2016 04:37 PM

    December 18, 2015

    @shell909090

    云计算的成本计算

    成本构成和计算基准

    一般来说,云计算的综合成本会分为三块。硬件,机房(包括机房内网络设施),运维。当然,其实还有IP费用和流量费用。但是那个在云计算的费用中一般也是分开列的,所以可以和以上三项分开算。我们先算出去掉IP和流量的费用,然后再来独立讨论这两项的效应。

    在云计算中,CPU是可以超卖的,但是内存一般不超卖。所以我们计算的基准是内存。准确的说,是“带上其他硬件设备的内存”的单位价格。单位是人民币每G每年,缩写为/Gyr。在整个计算中,硬件费用都是来自dell美国的报价计算器,汇率恒定在6.5,折旧速率是5年。存储系统的折旧速度会比整机更快。存储盘3年折旧,SSD1.5年折旧。

    存储是硬件成本中比较特殊的一项,因为每个虚拟机都带有存储,也可以额外配置。所以我们单独为其估价,再在整体费用中将其加回去。这样在估算价格时可以计算光板系统。

    硬件成本

    在这个计算中,我随意挑了一款2U机器——R530。这是一台最低型号的2U机器,不知道有没有人在实际生产中用他,总之我们就先随便算。这台机器极限能插8条32G的内存,总内存量可以高达256G,还是挺适合虚拟化的。因为机器总体有成本,单机内存数越高,原理上说越省钱。

    撇开存储,撇开网络,内存升到极限,其实我们能选的就是一颗CPU。而且一般来说,CPU和内存需要成比例搭配。一般会选择1:4的搭配比,256G内存需要64颗核心。整个CPU搭配表上就没这么牛X的CPU。。。

    好吧,退而求其次,看看稍微差一点的CPU如何。由于整机搭配的内存和CPU越高,整体价格越便宜。所以我们搭配一颗最牛X的核心——E5-2695 * 2。整个系统瞬间升到56颗核心。和64核也相差无几,我们就选他了。

    相对的,整个机器既然配置了这么牛的系统,那么网卡就不能用默认的千兆网卡了。我选了两个双口光纤万兆模块,再加上一个1+1冗余电源。其他都用默认选配。计算下来,每G成本为56.2/Gyr。这差不多就是一个光板机器的最低价格了,里面不带任何其他费用。

    另外,为了参考,我们计算一组CPU配足的机型E5-2670 * 2。这颗CPU是24T的,所以要配合192G内存。平均成本为60.47/Gyr。

    IO密度问题

    上面假定一台机器尽力往里插内存,但是实际上不能这么做。因为存储模型的问题。

    我把虚拟化分为两种——单台机器故障的情况下数据不丢失,可以立刻在其他系统上开始启动系统的。和单台故障的情况下无法立刻恢复系统,甚至数据完整性都不能保证的。前者敢叫云计算,后者只能叫VPS。

    为了达到后者,一般我们会把写入存放在多台机器上。而为了效率考虑,EC编码之类的方案几乎不能考虑。所以综合下来,唯一的方法就是将数据写入同步到另外两台机器上(三副本)。如果这个复制动作通过网络进行,那么写入速度就受到网络瓶颈。

    例如上面的256G机器。虽然我选了两个双口万兆模块,总吞吐量高达40G。但是实际上你得假定可能有一根线故障,可用速率只有30G(如果是一个模块故障,更会降低到20G,幸好这不常见)。30G速率均分给256G内存,平均分给每G的吞吐只有120Mbps/G。折算出来就是15MB/s每G。这个速率要通过两份数据,分别传输给两台机器。如果用户不幸而选择了1G的内存,搞不好写入速度只有7.5M/s。要达到普通系统60M/s的写入速率,至少需要8G内存。这还没有计算机器到机器间通讯速率。

    那么解决方案是什么?其中之一就是降低机器上的内存数。当然增加网卡也是一个方案,但是这会严重影响接入系统的效率——我们本来已经出了4根纤了,你想把服务器搞成八爪鱼不成?

    如果内存数降低,那么单位内存上的吞吐速率就能提升。192G的吞吐是160Mbps/G,每G写入可达10M/s。内存降到128G的话,平均吞吐率就会升高到240Mbps/G,每G的写入速率可以提高到15M/s。如果降到64G,每G写入速率还会提升到30M/s。不过IO问题是个峰值问题。如果全系统都有大量写入,例如大部分实例都装了数据库,那么很不妙。不过如果全系统都是纯密集计算,那写入速度其实影响并不很大。为了对比,我同样计算了128G和64G的情况。但是这并不表示在实际搭建集群的时候需要使用低内存的机器。

    有趣的是,在其他保持不变的情况下,128G的平均成本为59.44/Gyr,和256G的版本相差无几,比192G的版本还便宜些。64G却快速上升到94.25。这说明在一定内存数量以上,硬件平均成本受到内存密度的影响并不大,但是低于某个限制后,则快速受到影响。

    另一个方案则是在服务器上采用40G网卡,4块40G网卡也能解决问题。但是网络会非常难做。因为上手就用了普通汇聚层的速率,所以如果要不大影响收敛比的情况下,汇聚和核心的速率要求会进一步提升。这种模型下,单位价格为62.55/Gyr。

    当然,还有另一个方案。我们使用独立存储系统,例如盘柜。这样会带来两个好处。首先盘柜的光纤独立,因此会极大的提升网络系统的效率。其次盘柜的多份复制是自行完成的,因此并不需要在吐出光纤上传送两份数据。当然,我对这种方案不熟,所以下面没做深入计算。哪天可以把这个方案的成本模型算出来再写一篇。

    下面我总结一遍上面方案的配比和成本:

    • 256G + 10G * 4: 56.20/Gyr
    • 192G + 10G * 4: 60.47/Gyr
    • 128G + 10G * 4: 59.44/Gyr
    • 64G + 10G * 4: 94.25/Gyr
    • 256G + 40G * 4: 62.55/Gyr

    注1:其实192G的版本用R730还会更便宜一些,低到54.40/Gyr。但是我们的目标是同类对比。为了减少环境变量,所以不讨论这种情况。

    注2:其实128G的版本由于CPU比较节能,所以整机大约可以节约100W的电力。这部分在下面并没有被考虑,否则可能涉及机柜里会多或者少一台机器,计算会非常复杂。

    机房成本

    机房成本包括两块,网络设备费用和柜子费用。

    网络费用很容易算,一个柜子一般是42U/10A/20A电力。撑死放5-10台服务器。一个服务器两口,也就是10-20口左右的交换机。选个不大夸张的机器,也就是1W差不多了。就算电力翻倍,机器翻倍,交换机价格差不多也是翻倍的。所以平均成本还是基本不变。

    核心那里难算一点,一套核心要上百万,摊给全机房用。而且如果机器太多,可能两层交换量不够,还会用三层交换。那还有汇聚层的钱要算,大概又是上百万。

    柜子的价格最难算。视地点不同,每个月从几k到十几k不等。每个柜子能放的机器,随电力状况和CPU功耗,从5台到15台(35A)不等。而且很多时候,公司的体量大小和谈判能力也会严重的影响到价格。

    所以,为了简化上述计算,我直接硬把机柜价格指定为60k/yr[1]。300个柜子,每个柜子5台设备,1500台机器。核心加汇聚加接入,总数大约600W,每个柜子20k。至于为什么是这个数?不为什么,就是后面好算。

    于是很容易就算出来,每机柜每年成本64k/yr。128G下是100/Gyr,192G下是66.67/Gyr,256G下是50/Gyr。40G光纤比10G光纤原则上要贵,因为起手就要用汇聚交换机,而不是接入级的。但是具体贵多少——很遗憾我根本找不到数据。推测是贵了至少5倍。

    实际上,由于机房各种配比不一定能够达到最优状况,所以接入模型配比往往会比预期的高上非常多。而且机房成本也不一定能够控制在60k/yr的水平上。所以如果从业界实际角度考虑,这个费用的精确度大约会有20%的上下浮动。

    1. 参考这篇文档,有的地方能租到这么便宜的柜子,有的地方不行。

    运维

    一套云计算平台,需要多少个人运维?

    不知道,这得看是什么平台了。假定不需要研发(openstack出局),不需要license费(vmware出局),纯维护管理。最小单位需要1-2个SA,1-2个网络工程师,一个程序员,一个经理,五六个值班监控。。。大约10人团队。如果再加上研发,那就没底了。

    目前每个人的公司侧成本(不计办公费用,计公司税费),至少要30W一年。这批人就是300W一年的开销。如果摊到1500台256G的机器上,那就是7.812/Gyr。如果是192,那就是10.42/Gyr。如果是128G,那就是15.625/Gyr。当然,加上公司运营因素和各种杂项,要翻倍比较合适。

    资金成本

    大家别忘了,资金也是有成本的呐。不是说1W摊5年,每年摊2k就完事了。如果1W放五年理财,也得有个25%的收益了。从企业运营的角度讲,如果资金收益率小于10%,那还不如让别人来干。省下钱来干点别的更赚钱的业务。

    所以以上各项成本,在累加后还要乘以至少1.1。

    成本部分结论

    上面数项,除掉存储,价格总计为:

    1. 256G + 10G*4: (56.2 + 50 + 15.62) * 1.1 = 134.0/Gyr
    2. 192G + 10G*4: (60.47 + 66.67 + 20.83) * 1.1 = 162.77/Gyr
    3. 128G + 10G*4: (59.44 + 100 + 31.25) * 1.1 = 209.76/Gyr
    4. 64G + 10G*4: (94.25 + 200 + 62.50) * 1.1 = 392.42/Gyr
    5. 256G + 40G*4: (62.55 + 62.5 + 15.62) * 1.1 = 154.74/Gyr

    里面我们可以得到一些结论。

    1. 云计算的成本,基本是硬件和机柜对半分。最贵的不一定是硬件,很可能是机柜,尤其在内存密度不足时。

    2. 大内存最显著的意义并不是降低硬件平均费用,而是增加机柜密度。机柜密度大就节约租金和运维开销,因为一般运维不会因为维护的机器内存更大就更花人工。当然,由于上面并没有反应出高密度机器CPU功率会高的事实,所以更高的机柜密度就意味着更低的成本。如果将这部分纳入,高功率可能导致少放一台机器,从而产生其他影响。

    3. 影响机柜密度的最主要因素不是空间不足,而是电力不足。机柜租金中也有相当大比例来自电费(和制冷电费)。因此电费便宜,环境冷的地方的机房,成本肯定低。

    4. 从硬件侧说,整台机器的主要电力花销和成本都来自CPU。大数额内存的功率花销几乎可以忽略,成本基本都是32G/500$,合大约20/Gyr。主要电功率开销和浮动成本都来自CPU,所以选择低功耗低成本比CPU可以有效降低成本。而一般来说,核数越多,平均功耗是几乎肯定降低的,平均价格会略有波动。

    5. 但是如上面所说,增加CPU核心密度来提升机柜密度有其缺陷——外部通讯系统瓶颈。是否要解决这个问题,就见仁见智了。

    6. 在这几个模式里,我个人比较喜欢2和5。两个都相对不算贵。2的IO比1好,而且CPU足。5的成本更低,但是CPU不足,而且这个模式下的稳定性如何,网络如何支撑,没有大量实践。

    存储

    我们下面要估算的是裸存储价格,即光板存储的单位价格。在配置RAID,或者做冗余的时候,需要相应的折损。

    裸存储价格也分为三类——低速盘,高速盘,SSD。一般来说,速度越低,IOPS越低,越适合做数据仓库。速度越高,成本越高,越适合做高速读写。

    低速盘最大8T,单价7k。折算下来,0.289/Gyr。一般能跑100-200IOPS,平均0.025IOPS/G。

    高速盘最大600G,单价4k。折算下来,2.254/Gyr。一般能跑500IOPS,平均0.833IOPS/G。

    SSD先选最大一块1.92T那块,单价14k,折算下来,4.972/Gyr。这块是读优化的,有数据说能到100k IOPS,平均52IOPS/G。如果是写入,只有18k IOPS,平均9.375IOPS/G。阿里云的宣称数据是30IOPS/G,这块是支撑不起来的。要能支持30IOPS/G,需要选用800G那块,写优化的。单价13.04/Gyr,据说写入能达到28k IOPS,平均35IOPS/G。

    可以看到,SSD的成本要比存储盘远高。按照单价而言,甚至远远高于硬件成本。如果我们给一台虚拟机增配20G裸存储SSD的话,每台就要增加280.8/yr的费用。更糟糕的是,虚拟机存储费用是裸存储的3倍(三副本)。一般来说为了节约成本,没有厂家会在这里用SSD来支撑系统镜像,最多高速盘。也就是135.24/yr的成本。

    吞吐的成本如此高,也难怪IO是衡量虚拟机性能的重要指标。

    注:有些厂家可能在高速盘集群上搭配了SSD的cache,作为读写缓冲,并自动分层管理缓存。这种模式对IO优化很好,成本也很低廉。我们在这里对这种模式不做深入。

    计算存储成本

    如果以4G内存搭配20G高速盘来计算存储附加,成本增加为:

    3 * 2.254 * 20 / 4 * 1.1 = 37.19/Gyr

    1. 256G + 10G*4: 134.0 + 37.19 = 171.19/Gyr
    2. 192G + 10G*4: 162.77 + 37.19 = 199.96/Gyr
    3. 128G + 10G*4: 209.76 + 37.19 = 246.95/Gyr
    4. 64G + 10G*4: 392.42 + 37.19 = 429.61/Gyr
    5. 256G + 40G*4: 154.74 + 37.19 = 191.93/Gyr

    云计算费用

    OK,在经过上面罗哩罗嗦的计算后,我们终于讲到重头戏了——云计算费用。

    在配置硬件的时候,在搭配中1T会配4G内存。但是CPU超卖情况下,1T是绝对不会卖4G以上内存的。因为这会让部分CPU永远不被用到。(想不通的朋友可以考虑,如果1T配8G内存,那256G内存最多分配32T,56T里面会空出24T无法分配)因此2核心可以搭配1G-8G内存,却不能搭配以上。如果只搭配2G内存,那么2G/2核心,按平均却只能占有半个核心,却实际能占据两个核心。

    这就是虚拟化成本计算模型中最大的问题——CPU超卖。

    我们如何计算呢?很简单。取每家最大核心的情况下,内存最大的一个套餐,计算为每G成本。因为这个搭配基本和这家的每个计算单元的物理状况趋向一致。而这家的其他套餐,费用一定会高于这个套餐。多出来的钱就是CPU超卖利润。

    当然,超卖比例越高(例如全都是2G内存搭配4核心),虽然利润越高。但是如果这家不约束这种行为,会很快导致计算力不足而被客户骂死。一旦约束这种行为,实际上就需要将内存空着不卖出去。导致每G内存收取费用上升。本质上还是会回归到差不多的价格。

    作为用户来说,其实小内存大核心在密集运算的价格上会占点便宜。但是由于一般网站计算的特性,应当合理的搭配核心和内存。也没可能为了多占核心而特意配一个小内存大核心的机器。1:2到1:4的内存比是比较恰当的。

    青云:国内665.82/Gyr,亚太节点921.00/Gyr。

    阿里云:国内(除青岛)447.0/Gyr,香港节点525.94/Gyr。

    腾讯云:375/Gyr。腾讯云的特殊之处在于有1核心超越4G内存的搭配,看来硬件配比应该比较特殊。而且香港机房并没有显著贵。

    ucloud:国内454.84/Gyr,亚太节点518.28/Gyr。

    GCE:美国531.44/Gyr,亚太节点584.58/Gyr。

    AWS(EC2):美国516.18/Gyr,美国(北加州)711.46/Gyr,日本683.55/Gyr。

    linode:780/Gyr。所有节点统一价格,还包了流量费用。简直神奇。

    结论

    1. 别忘了上面的价格可都是零售价格,大客户还能打折。再加上一般机房里不可能全部资源都正好卖光,都会空着部分资源。上面的价格乘以0.7-0.8差不多是实际运营商每G能赚到的钱。

    2. 大部分云计算厂商的价格都在500/Gyr上下波动。linode的特别贵,但是那个包含了很高的流量费用,扣掉之后反而是最便宜的。但是要记得,linode是vps,而不是云。腾讯云的特别便宜,而且香港机房也没有提价,原因不确定。

    3. 机房对总成本的影响非常大,这点非常符合成本预期。下面实际计算出来光成本差就有0(腾讯云),50/Gyr(GCE/ucloud),200/Gyr(青云/AWS),这么几种级别。

    4. 以阿里云,0.8销售比和128G节点来计算的话。阿里云的折算后收益大约是360,节点成本是250。考虑其他费用(包括市场/售前/售后/财务/人事,etc)的情况下,其实match的很不错。

    5. 假设用户有xG的需求,每个都是理想状态,自建服务器和采购云平台哪个更合算?

    我们只计算256G版本,192G版本和128G版本,其他请自己类推。

    256G版本:
    (56.2 + 50 + 2*3000000/x + 135.24/4) * 1.1 = 500 * 0.8
    求出来得到x = 26830.5G。

    192G版本:
    (60.47 + 66.67 + 2*3000000/x + 135.24/4) * 1.1 = 500 * 0.8
    求出来得到x = 29602.4G。

    128G版本:
    (59.44 + 100 + 2*3000000/x + 135.24/4) * 1.1 = 500 * 0.8
    求出来得到x = 35214.1G。

    所以,要自建机房,至少得有30T内存需求以上,甚至要到35T。用256G内存来算,这大约是120台。192G下是160台。128G下是300台。

    一个基本结论是,所用的内存越大,越容易低成本的自建云存储。这很容易理解,因为大内存机机柜密度高,租金低,用小团队就可以管理。考虑到各种其他开销。如果总内存需求量上了30T,不妨可以考虑一下。当然,你可别忘了上面的假定是“10个人团队能hold住整个系统”。很多IT公司的管理和选型下,这点是做不到的。

    考虑到自己开销的波动(例如促销),公有云比自建机房更方便抵消这部分波动。从这里来说,大部分情况下自建机房都不合算。如果基础系统开销已经超过了临界点,不妨考虑将波动部分扔到云上,通过VPN和自建平台对接(例如AWS Direct Connect)。

    带宽价格

    上面我们都在说机房,而没有提到带宽。主要问题是国内带宽情况非常混乱。电信卖给竞争对手的价格高达1000/Mbps,而阿里CDN的价格只有22.8/Mbps(所以才有流量穿透问题啊,同学们,万恶的资本主义。。。)。这说明在阿里的边缘节点上,他们的带宽价格不会比22.8/Mbps更贵,至少不会普遍更贵。

    那么带宽价格如何对照?我觉得比较有意义的是各CDN厂商的价格。CDN厂商的主要成本都是来自边缘节点的出向流量费用。由于缓存作用,他们的入向流量应该显著不足。当然,传统CDN厂商也像各大运营商一样,定价非常浮动。不过aliyun之类的厂商定价还是比较透明的。我们可以以他们作为标杆。

    说明

    首先特别说明一点。这个计算中不包括任何七牛的线上配置,产品,价格之类的数据。对比中也特意略去了七牛。

    对于我来说,这些算是公司机密,因为很多我都接触到了。当然,大家可以自行将上面的算法应用在七牛上。。。那就和我没关系了。

    其次要注意,成本那部分并不很准。首先用的是DELL海外官方价格。相信任何一家云计算去采购的时候都会面对不一样的供货价格,然后再谈判一个折扣。那个价格只能参考。其次很多地方也采用了近似估计的方法(例如机房)。只能仅供参考。

    by shell909090 at December 18, 2015 08:14 AM

    December 17, 2015

    @khsing

    证书换到Let’s Encrypt了

    今天把证书换到Let’s Encrypt了,Super Easy.
    1. git clone https://github.com/letsencrypt/letsencrypt
    2. ./letsencrypt-auto certonly -d domain.tld,然后提醒写一个常用email就好了
    3. 配置一下Nginx
    下面是Nginx配置中的证书部分
    ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;

    by khsing at December 17, 2015 10:03 AM

    November 12, 2015

    @khsing

    tips: 记 Windows 下计划任务执行 bat 复制网络映射文件

    设置了一个计划任务从来就没有正常执行过,而手动运行又都是好的;终于解决了这个问题,主要是卡在输入用户名密码上了,首先 bat 中做网络影射
    IF NOT EXIST z:. net use z: \\SERVERIP\Folder /PERSISTENT:YES
    就是执行到这里是需要密码的,进入控制面板 > 用户管理 > 管理你的凭据 > 增加一个 Windows 的凭据;就可以了。
    用完了可以断开映射
    IF EXIST z:. net use z: /delete

    by khsing at November 12, 2015 10:24 AM

    October 28, 2015

    @khsing

    vendor 目录究竟应不应该进 VCS

    很多项目现在都有组件式的包管理,比如 `composer` 管理的第三方组件都存放在 `vendor` 目录下,那么究竟这个目录应不应该放到 git 之类的版本管理里去,之前我的做法是不放,但是后来发现了一个问题,当多台机器面临更新第三方组件的时候,会出现版本不一致的问题,而且本身 Laravel 的 `config/app.php` 中启用了第三方组件,但是 `vendor` 目录中还需要 `composer update` 更新的时候就会报错;
    所以,`vendor` 作为整个项目的一部分,应该放进版本控制系统(VCS);在部署打包的时候也是一份子,编译打包进入 Docker 之类的容器,进行整体的部署,也才能够保障每个服务器上运行的代码是一致的;

    by khsing at October 28, 2015 03:03 AM

    October 23, 2015

    @khsing

    HP 关闭 Public Cloud 服务

    [HP Public Cloud](http://www.hpcloud.com) 宣布到明年1月底就关闭服务了,公有云这个市场有 [AWS](https://aws.amazon.com) 这样的先行者和巨无霸,其它产品只能是边边角角像 [Linode](https://www.linode.com) 和 [Digtal Ocean](https://www.digitalocean.com) 这样填补便宜的 VPS 市场;
    国内的竞争还不明朗,没有什么太多的数据,阿里云应该是国内最大了吧,腾讯云借着强绑定应该也有不少用户,剩下的就是 UCloud 和 金山云了,也主要靠游戏;其它的云厂商都是提供部分 AWS 的服务;

    by khsing at October 23, 2015 01:11 AM

    October 22, 2015

    @shell909090

    说说密码和安全设计

    趁着某站密码泄漏,我review了一下整个密码和安全系统。下面总结一下要点,大家可以参考一下。但是我觉得多数人无法照抄。

    基础

    假定

    1. **会随时找我谈话。(不要以为不现实,想想我得分最高的项目)
    2. 手机是会丢的。但是窃贼不会攻击经济无关帐号。

    设计

    1. 尽量使得问题只出现于局部,不会波及全部系统。
    2. 在不严重的情况下,尽量简化使用,而不是增加复杂性。
    3. 在“大部分情况下更严密,小部分情况更糟糕”和“平均化”的选择中。只要小部分发生概率不高,选择大部分情况更严密,并尽力避免小部分情况。

    帐号体系

    • 能用Oauth自动登录的尽量绑自动登录。能不自己管认证体系的尽量别自己管。
    • 境外关键服务,应绑定邮箱,不可绑定手机。其余服务应绑定手机和邮箱。如果没有假定1,能绑啥绑啥。
    • 集中绑定能减少帐号系统复杂性。其代价就是当基础手机/邮箱出问题时,后果会很严重。因此需要设计对应措施。
    • 重要服务(尤其涉及钱)只能有一个绑定寻回,切忌绑了邮箱绑手机,还都能寻回。一个出问题,帐号很危险。
    • 基础手机/邮箱之间严禁互相绑定,以防一个出问题全部出问题。
    • 多个身份间不要串帐号。一个帐号体系和另一个帐号体系之间可以发生来往,但是不能发生混同。想一下妹子用自己手机号帮多个男的登记开房的事。。。
    • 基础邮箱/手机的信任问题不是信任问题,是信仰问题。对应措施无法对应基础系统自身的问题,例如供应商恶意作恶,或者供应商出了问题。所以选择谁是个信仰问题,要仔细选择信仰。

    OTP管理

    • 能开OTP的统统开起来。把emergency token抄纸条上丟家里。
    • 可以使用OTP的列表
    • 上面的补充:Microsoft, CloudFlare,Slack,Vultr,Tumblr,Ifttt,Eveonline,阿里云, DigitalOcean,dnspod,btc-e。
    • ms家会让你装他自己的app。请在手机系统的选项里选other,这样他就乖乖出一个QR让你扫了。
    • OTP的保存时间和系统安全性有关。可信系统上可以保存一个月,不可信系统上尽量在一天以内。太长时间可以登录不需要输入OTP等于没有OTP。

    密码管理

    • 使用密码数据库保存数据。
    • 密码数据库管理程序应彻底开源。
    • 使用同步网盘保存和同步密码数据库(加密后的)。
    • 要注意防护整个系统突然失效。从出现概率分析,系统失效概率比被盗概率要高。而一旦发生失效,你的大多数帐号就全都失控了。
    • 手机上不应同步密码库,而应手工复制更新。以防同步系统出错清了所有副本。
    • 可以定期将基础密码(主要是邮箱)抄出来,放在家里的角落里。万一不得已,可以对所有系统做密码寻回。
    • 密码维护建议在同一个环境上进行(例如全是windows),以防两种不同版本的软件冲突导致数据丢失。
    • 不应在不可信系统上输入主密码。否则主密码和密码文件都会丢失,等于所有密码丢失。所以不要在不安全系统上使用密码管理系统做任何操作。
    • 要谨慎使用粘帖板管理程序。保存粘帖板历史的程序不要开。
    • 搞一个足够安全的系统随身。推论可知,系统越多,出问题可能性越高。搞一个足够安全的系统随身,可以避免万一的情况下被迫要在不安全的系统上输密码。
    • 这基本就是需要你有一只足够安全的手机。

    手机

    • 如果手机有root,不算安全系统,不能使用密码管理系统。
    • 注意手机上的“可以收取短信”和“可以访问剪贴板”权限。如果一个应用可以访问这两个,基本就可以访问大半密码数据库,并收取验证码。也就是可以在无察觉的情况下把某个帐号偷跑。
    • 手机上保存的帐号尽量不使用手机寻回帐号,尤其是涉及钱的。如果帐号保存在手机上,而且可以用手机寻回。一旦手机丢失,拿到的人就可以长驱直入了。按照假定2,这很危险。

    • 银行卡升级到高密卡。低密卡的安全性问题就不说了。
    • 目前高密卡还是可以按照低密使用的,这其实仍然不安全,因为复制后还是可以偷钱。增强卡安全需要全部系统强制废弃低密卡。
    • 经济相关帐号需要一个“防止手机丢失”的手段,否则不应在里面长期放大量资金(可视为这笔钱会随手机丢失)。
    • 支付宝的设计是“手机高于一切”。所以在“手机会丢”的假定下,直接出局。微信的设计也类似,所以也出局。
    • 银行帐号,其密码无法通过手机寻回的,可视为安全。
    • 如果能通过手机寻回密码的,有转出限额(无法通过手机更改)也可以接受。

    吐槽

    • QQ现在要求我用申诉的方法才能改密。但是申诉需要三个以前好友的帮助。我TM从98年开始用的,连同学都没几个还在上了。你让我去找麻花藤来申诉啊。。。
    • 支付宝本来还支持字母支付密码,后来直接改成了6位数字。手机应用本来还需要解锁,现在只在特定情况下需要输入手势锁。本来还有宝令,现在已经没有了。总体来说,支付宝的安全性是越做越差的。
    • 在整个密码体系里,就属支付宝和微信的安全性最差,就属他们涉及的钱最多。

    by shell909090 at October 22, 2015 08:47 AM

    October 17, 2015

    @delphij

    假设 3721 = x * y,其中x, y 均为整数,则 x+y 最大是多少?

    翻了个船,记一笔。题目如题。

    已知 x、y 为整数,由于 3721 是正整数,因此 x、y 符号相同且均不为0。又,题目所求是 x+y 的最大值,故只需考虑 x、y 的正整数解情形。

    由 x * y = 3721,令 y = 3721 / x,则 x + y = x + 3721/x。由于 x > 0 且为整数,可知所求为符合条件的 max(x2 + 3721),或 max(x)。

    将 3721 开方得到正整数 61。由此可知 x = y = 61 是 xy=3721 的一个整数解。61 是质数,于是很想当然地得到了错误答案 = 61+61 = 122。掉到这个坑里的主要原因是想太多了,实际上题目最终要求的是 x 的最大正整数解,换言之,此类问题:已知C为正整数,C = x*y,求 max(x+y) 的结果应该是 (C+1),不需要任何超出小学算术的计算。本题中的正确答案为3722。

    by Xin LI at October 17, 2015 01:20 AM

    October 16, 2015

    @shell909090

    从青蒿素得奖说现代医学里的方法论

    最近青蒿素比较火,首先恭喜我们终于有一个拿得出手的nobel奖了。

    然而,很多人对青蒿素获奖的事情传播不准确,各种争论。例如,中医获奖了。实际上在青蒿素的获奖中,没中医太多事。要明白这点,我们首先就得明白,什么是现代医学,现代医学中有哪些基础的方法论。

    双盲实验

    双盲实验法是整个近代医学基础中的基础,说是基石也不为过。可能很多人被双盲法的名字搞糊涂了,整个双盲法的思考基础其实非常的简单直观而且科学。可以说,如果听了双盲法的概念后,表示不可以理解和接受的,都得算伪科学。。。

    让我们从一个简单的问题开始。我们怎么判断一个算命的是不是有真本事?

    最简单的方法,当然是让他算一下,然后我们找人去验证他算的对不对,进而得出一个正确比例来。这个方法固然简单,但是多少才算是“对”呢?这又陷入了另一个困难。

    作为解决方法之一,在算命的算玩后,找完全不会的人胡扯一些算命结果,作为对比去验证。如果算命师的命中比例比瞎猜明显高,那就是真的算命师傅。如果和瞎猜差不多,那就是水货。如果扔出各种理由告诉你不能这么做,那么就是不可知。

    这个方法很简单吧?通过足够多的实验,我们可以清楚的知道,哪些算命师是真货。

    但是有个问题。算命结果的解读,是需要人进行的。而人会受到心理暗示的强烈影响。例如,你知道自己正在解读某位大师的算命结果,他是否吻合呢?有的时候往往模棱两可,你可能就认为其实是命中的。所以一般性情况下我们会让你对正在解读的是真的还是假的保持未知。类似,近代医学已经证明,如果你认为自己在接受治疗,那么你的病情有的时候会出人意料的好转,哪怕实际上你并没有接受治疗。这叫做安慰剂效应。因此,在医学实验的时候,被试者必须对自己是否真的在接受治疗一无所知。这叫做单盲实验。

    而更进一步的,当实验的组织者了解哪组是真组的时候,出于利益因素他可能进行干扰。即便他本人并不进行干扰,有可能在日常的接触中给予了过高的期望,从而影响了实验的效果或者解读。这种现象在现代心理学中叫做皮格马利翁效应。如果你给予某个组过多的期望,那么他们就会表现的更好。为了防止这种现象,我们会让专门的人进行真假对照组分配,而对实验进行管理的实验者,在结论完成前对真假都是未知的。这叫做双盲(实验者,被实验者)。

    可以说,双盲法并不否定算命。双盲法不假定你要做什么,也不需要理解其工作原理。相反,双盲法试图用一般人能理解的角度,来验证你行为的有效性。双盲法就是一个更严谨版本的“让我来试试效果”。

    为什么要进行双盲实验

    很多人会说,中医已经经过了几千年的检验,是对人体,尤其是中国人体的非常高的认识。所以不需要双盲检验。其实从青蒿素得奖的报道中我们恰恰可以看到,这种说法是完全错误的。大家可以找一下青蒿素研究的相关报道,青蒿并不是治疗疟疾的第一线用药,大多数用法和用料也全是错误的。相关课题组从中医中,收集了几百个可能的药方,而其中能够成为药物的,只有青蒿素这么一个。那么剩下的几百个药方是什么?对人体的全面总结?这就好比你去医院,问医生说,搞不搞的定啊。医生拿出600多种药来,告诉你,一样样试过来,你的病就有救了——

    ——尼玛你的病才没救了呢。600多种药,当饭吃都要吃上几天。更不说多种药物之间还会互相反应冲突。这哪里是治病,分明是致命。

    也有人说,中医需要根据情况,复方辩证,药物配伍,才能治病。所以双盲法不能起作用。其实这也简单。找个白胡子老头,就是电视广告里经常有“祖传配方”的那种形象,也跟一批患者面前一戳。找点树皮草根去熬,完了也给丫灌进去。要是你的治愈率比不过这个,实话说,我们真用不着您的祖传药物,直接在民间里筛演员就成。还能做一档节目,就叫中国好中医。广告商都好找的很,凉茶商们分分钟扔出一堆钱。。。

    还有人说,中医有几千年历史,近代医学才几百年。为什么要用一个几百年历史的东西,去证明一个几千年历史的东西呢?

    如果你信服这个观点,你就需要考虑。马车有超过千年的历史,汽车历史不超过200年。按照同一理论,我们不能用汽车的理论去规范马车(例如靠停,让行,撞击安全标准等),还得让他们在一起跑。不知道你春运的时候,会不会驾驶一架马车上高速(如果上的去的话)。

    有些人就是这么奇怪。穿化学制品,汽油机车出行,住钢筋水泥,还用洋人们发明的一种叫CPU的玩意上一种叫ineternet的网(抱歉,有些地方叫innernet)。偏偏轮到中医头上就不能用现代的标准衡量。你知道早年某国也有一群人,大喊着大师兄速速显灵,戴上面具自以为刀枪不入出发去捣毁洋鬼子们的教堂。该国还给自己的军队起名叫“虎神营”。其结果我就不多说了。。。

    其实对真正有信心的中医大师而言,双盲法不是打脸,而是机遇。双盲法能够以近代科学方式,令人信服的检验一种疗法是“有效”的,还是“无效”的。这为后面的一系列研究打下了基础。而且通过双盲法测试后,治疗方法的有效性就会被现代医学所接纳和研究,从而使中医在未来有更广阔的发展。如果对中医真正有信心的话,我无法想象为什么会拒绝双盲法检验。最基本的,一家馆子好不好吃还允许客人尝尝味道再评价呢。一个疗法有没有效,居然不允许别人试试再评论,搬出各种理由必须无条件的相信。我也是没话说了。。。

    记载和公开验证

    我还看到某篇报道,通篇长篇大论论述“黄青蒿也是青蒿”。这更是扯淡。一种植物到底是不是药物,药典居然并不能很明确的分辨明晰。那么你吃的药有没有效,我想医生也并不能很明确的分辨明晰。数百年的中医口口相传,每个中医是不是都能掌握正确的治疗方法呢?也未必。鲁迅先生就记载过一味药:败鼓皮丸。有没有效?我不知道。治法虽看似儿戏,但是不能因为看似儿戏就断定无用。传统医学种种方法,很多有效的疗法就藏在看似儿戏的行为里,例如嚼树皮。但是我至少能说一点——这记载很有问题。

    破旧铜鼓皮一张——什么样的铜鼓?用的什么动物的皮?

    以陈烧酒和糯米粉糊丸——是不是要哪里的陈烧酒和糯米粉?

    这些都不明确,确实只能靠中医的口口相传,秘而不宣。别的不说,我至少可以说一点——鲁迅先生当年就没遇到传对了的医生。

    完全存在可能,某种特定动物的皮,在经过很长时间后,恰好能够治愈文中所描述的症状。但是这种动物能治,换种动物行不行?时间短点行不行?这些都很模糊。其结果就是这个药方的效果不“稳定”,有时有效,有时没有。有的人有效,有的人没有。

    然而在验证上,这个事就有点扯皮了。上面的一堆组合中(各种动物,放置时间长短),假设有一种组合是有效的。那么能说这个方子有效么?无效?这方子明明可以用。有效?大部分的医生,大部分的时间里都无法治愈你。这就像青蒿素的悖论一样。虽然治疗方法都摆在那里,但是在中国历史上的几百年间,愣是拿疟疾没辙。证据就是,自古以来中国视南方瘴疬之地为畏途。可从没听说哪个医生带了一车青蒿大摇大摆的走了进去,对瘴气是若无物的。另一方面,如果中国长期以来,主流治疗方法都是正确的,有效的。那上个世纪搞那么大规模的疟疾治疗研究是干嘛呢?为什么不直接用成方呢?屠女士是怎么获的奖呢?国家领导都是白痴么?

    近代医学体系的基础,是清晰的,公开的记录,和公开的第三方验证。只有将发现记载清晰,才能够公开,由其他人独立重复实验。只有公开,才能允许第三方验证。而只有第三方验证,才能对整个实验中是否存在潜在问题,做出一个独立的研究。这整个体系,是现代医学得以存在和发展的基础。

    讽刺的是,这也同样是中医发展的基础。本草纲目之所以伟大,正是因为其公开而完善的记载。如果本草纲目是一本家传古籍,当然更值钱,然而中医也无从发展了。

    近代医学中,也有记载不清楚的地方(或者记载者自己并不知道记载不完善)。但是消除记载不明确的地方是常识,将这种不明确秘而不宣才是异常。例如反应停事件,人们以为记载了药物的分子式就结了,没想到药物还有手性问题。其中的R构型有疗效,而S构型会致畸。通过对Thalidomide的深度研究,科学界明确了药物的作用机理,风险,和控制方法。现在,Thalidomide被作为一种麻风性结节性红斑的药物使用。通过分离手性分子,可以将副作用降低到最低。

    这个事件,和“黄青蒿是否为青蒿”的纠结,可做一对比。

    临床试验

    双盲法测试有效不是故事的终结。恰恰相反,双盲法认定了这是一种有效疗法,这才是故事的开始。一种疗法(尤其是其副作用)被现代医学透彻的研究之前,是不会被广泛应用的,尤其是中药。因为中医在近代医学上扮演过极不光彩的角色。

    在上世纪,其实老外们很迷中药的。后来在92年前后吧,比利时有很多人染上了奇怪的肾病。经过医学研究,明确将病因指向含有马兜铃酸的中药。此后,在2000年的时候,FDA正式下令,禁止含有马兜铃酸的草药和制品流入美国。整个事件可以看wikipedia的马兜铃酸事件

    其实我的意见,吵架双方完全没争论到点上。当我们讨论毒物的时候,剂量是一个很重要的因素。马兜铃酸在各种剂量和配伍下,引发肾衰竭的可能性如何?至今为止没有人给出解答。似乎中医中药的赞同者们,从来没从近代医学的角度考量过问题。(这里可参考上面的“为什么要进行双盲实验”)

    化学药品固然也有导致肾衰竭或者肝衰竭的可能性,但是在使用的时候,多大剂量,可能造成多严重后果,这些数据是基本可查的(我记得这货应该叫循证医学?)。医生在开药的时候,可以根据服药的后果可不服药的后果,来衡量使用一种药物的价值。

    然而马兜铃酸的毒理性数据(尤其是中医们宣称的,群臣佐使情况下的毒理数据)缺乏(在可靠测量方式下缺乏),使得传统医学中很大一部分药物根本无法被现代医学使用。因此我们只能看到中医界反复宣传,中医安全,可靠,不会引起副作用。但是现代医学界却始终无法接受。最后就完全变成了信仰之争。

    我相信中医中还有大量的有效的疗法(和更大量的,传出了问题的疗法)。但是哪些疗法有效,哪些疗法无效,哪些疗法有多大效果,有多大副作用,尚没有一个明确结论前。实话说,虽心向往,不敢用之。

    作用机理

    近代医学比传统医学更进一步的,是明确了“药物为何会起作用”的机理。这个机理是明确的,公开的,可重复的,可证伪的,而不是以阴阳五行或者太阳月亮在天空中的位置,来指导治疗。

    我查过,关于青蒿素,就有好几篇“青蒿素类药物的作用机制”。我目前还不清楚其作用机理是否已经完全被解析明了。但是人类是有好奇心的,一定会有人好奇为什么这种药物能起作用,从而持续的研究他。

    更深一步,近代医学对药物机理和毒性的研究,甚至能够改善药物的效果,减少毒性。例如上面提到的反应停手性问题。对药物作用机理的研究,甚至还能指导药物设计。例如奥司他韦

    当然,作用机理研究不清,也是不妨碍用药的。现代医学没有那种必须搞清楚才用的怪癖。

    中医,西医,现代医学

    假定你感冒了。给你板蓝根的,是中医。给你柳树皮嚼的,是西医。给你对乙酰氨基酚的,是现代医学。我们在说西医西医的时候,其实也是巫医,是传统医学。只有当近代,医学结合了科学的方法论,才脱离原始蒙昧的阶段,正式成为现代医学。

    by shell909090 at October 16, 2015 08:19 AM

    October 15, 2015

    @shell909090

    印度游记-4

    有人反馈说,印度和巴基斯坦是世仇,因此有恐怖袭击风险。尤其是Taj Mahal酒店,是2008年孟买连环恐怖袭击的袭击对象(不过那次是孟买)。事后得知,真是一身冷汗。

    中国不是没有,而是主要集中在西部。其他地方,有点风险的人还没下大巴呢,就先叫去谈话了。。。

    建议来印度玩的,把你常用的地点都在gmap上戳一圈。这样很多事情会很方便。

    HOHO bus千万不要坐,老婆更是傻傻的买了两天的套餐,说第二天才多20%的价。结果咧,完全没有用到。

    HOHO bus非常扯,开着开着,冷气没了。然后老外就和他们争论。本来让我们等下一班的,结果就是来人修车,同时尽快派一班过来。

    气场啊,气场。

    实际修复的结果,差不多搞了30分钟,只能说略快而已。

    这才是医院的日常。

    不建议去玩。不过看到好多学生来观光。老婆跟我说,印度的妹子小时候真漂亮。

    非常不建议坐。各种意外,各种不靠谱。

    这条推是批量发的,次序有错乱。

    有兴趣的朋友可以去看看。对宗教没兴趣的就不用进去了,你会觉得很无聊的。

    印度那里有一些小摊,弹子汽水瓶子上摆个柠檬的那种。可以买一种饮料。柠檬榨汁,加点糖水,加苏打水。第一次喝味道很赞,第二次就难喝。对自己的胃和运气有信心的人可以试试。

    上海地铁好好学学。

    瑞典的朋友说,瑞典有法律。如果你的母语不是瑞典语,小学会安排老师进行一周一次的母语学习。。。

    img

    事后补的,时间有跳脱

    感觉在偷,骗,抢上,我们就是印度的祖宗。印度的骗子那是啥水平?拉去旅行社骗你去个差点的旅馆的水平,这也就我们上世纪末的手法。我们的骗子啥水平?在大城市里,拉去传销,警察还怎么抓都抓不找。印度的小偷啥水平?居然偷到插在口袋里的手上。我们的小偷啥水平?拿着手机,插着耳机,听着歌。突然歌声断了,低头一看。耳机还在,手机没了。回个头,大家都离你好远,都不知道是谁干的。以前觉得日本黑社会碰到中国黑社会会报警是个笑话,今天觉得,他们的警察要是可以也会报警的。。。

    不知道为啥,进这家店的人都在抽水烟。

    查了一下,片子是这部: Singh Is Bliing

    img

    在印度也看到有人用筷子,用的还不错。

    lamic简直是the taste of evil,可是老婆超爱喝怎么办?

    至于医院配的电解质补充盐,味道非常不错。

    和人对了一下,比北京轻点。

    img

    img

    念的经文里面,其实很多都有中文音译的,例如“南无”。

    其实整个delhi,就印度国家博物馆里面值得看看。

    后面有人评论说,中国有地方洗澡完毕后有递内裤的。。。

    img

    我问过上海的出租司机,不算油钱的话他们出工费也是600一天(我觉得浮动很大),不过那是24小时。上海的出租行业其实很变态。一方面出工算时间都是24小时整计算的,所以司机必须全天运营,要么就浪费夜间租金。所以晚上出租爆多,很多司机晚上没得选,只能去机场趴着。常规来说出租数量应当是白天多夜间少的。另一方面则是把出租当作公共交通来运营,导致准入门槛(和高昂的管理费),另一方面质量则和公交车同一档次管理和计算。你没法通过消协来投诉和维权的,只能通过城建,而城建的人又只会转给公司处理,其他根本不作为。所以上海打车有“挑牌子”的讲究。就是因为有些出租公司管理比较严格,有些公司的管理就呵呵了。

    by shell909090 at October 15, 2015 07:18 AM

    October 14, 2015

    @shell909090

    印度游记-3

    img

    img

    img

    事后发的,时间跳脱。

    这就是我说的,基础设施造成的重大影响。印度这地方不像中国,政府说弄个电线,分分钟就搞定了。你先得考虑对环境的影响,对古迹的影响,再问问居民答应不答应。等所有事情都谈好,中国人已经把活干完了。。。

    小哥说中国啥都便宜,就是羊毛特别贵。中印外贸交流其实机会挺多。我觉得也是。只是基础设施可能会造成很大问题。不过这也不是什么大事,我们援非建设都搞了多少了,在印度搞个什么工程还不是手到擒来。只要能先把各方面问题先谈妥。。。

    不知为何,好多印度人会说中文。中国人就别指望印地语了,但起码英语不要太差啊。。。

    这是我最意外的一点,印象中印度很多教徒因为吃什么肉的问题经常起冲突。不同的宗教,在教义执行上会有不同麻烦。为此我还特意去了解了很多宗教和禁忌。不过我个人的意见,教义是用来约束自己的,不是约束别人的。不应当因为别人触犯教规而感到被冒犯。

    建议大家晚上去看看。主持人会用印地语和三式英语报一遍,能听懂多少就看个人了。不过我觉得听懂听不懂其实不重要。

    当然,是烤鸡。

    感觉中国还是挺干净的,起码我到处乱摸和吃手指都没有造成腹泻(不然我也拉肚子多少年了)。印度就不一定行了。可能无意识中随手咬了一下手指,腹泻。。。

    这里有评论说,不同地方还不一样。例如上海和武汉就不一样。所以不是“印度物价只有中国的一半”,而是“udaipur物价只有上海的一半”。而武汉的物价基本也是上海的一半。所以大致上感觉上海出去到这两个地方都可以装土豪了。

    下面有人问为什么印度人不喜欢英语。我不大了解,但是这里有个wiki页面: 印度官方语言列表,里面提到

    大体上,英语已经在1965年终止了它唯一官方语言(或与印地语相同的)的地位,但依旧保留了它“第二附加官方语言”的地位,直到一个被指定(负责该事宜)的委员会在经过周期性考察后决定(将官方语言)全面转换到印地语。无论如何,因为有来自许多如泰米尔纳德邦等印地语使用率很低的地区的抗议,这种“双语言”系统仍然在流行。由于印度全国正在快速工业化,以及受到国际经济交流的影响,英语仍然非常流行并且在日常商业活动和政府交流中发挥重大作用,以至于试图取代其地位的努力功效不张。

    总体来说,语言对经济一体化的影响非常大。中国全地区通行普通话,实际上为跨地区经济交流和合作提供了基础。而印度通行英语,其实这是个非常大的优势。

    不知道是不是语言问题,三哥不用计算器的话算数字很慢。我碰到大部分中国人算数字都是秒出的,三哥出数字就不好说了。但是语言天赋真不是吹的。在jagdish temple前面的街上走着,一路上听到了中文,英文,日文,韩文,和印地语五种语言的招呼。。。而且有些人甚至不是会一句两句,而是能和你坐下扯上好一会。

    印度咖喱的变化其实非常丰富。但是作为一个非印度人,我最多只能吃出红咖喱黄咖喱,还有里面用了什么主料。所以瞬间咖喱的选择就变成了羊肉,鸡肉,蘑菇,素咖喱这么几种。加上一般饭店你也没法和他说,给我来份羊肉红咖喱,重辣,要哪几种香料。这在中国也是熟客待遇。一般饭店最多有几种咖喱(不同咖喱名字是不一样的,不都叫curry)和主料组合,点的时候有辣和不辣的选择。对于游客而言,辣的选择一般也可以无视了。所以就结论来说,印度庞大的咖喱变化就变成了不超过10种的咖喱。

    另外吐个槽。从中国飞过去的航班上,咖喱那叫一个难吃。回来的是同一家航空同一班的返程,餐食由印度地面供应。咖喱顿时好吃了一个数量级。

    另外烤鸡烤鱼味道很不错,但是和中国的夜市比,也就那样。也许是我吃惯了中国的食品。

    事后回顾,这次过机场简直简单的难以置信。在delhi过机场的时候,光是柜台排队就排了好久。然后又是好久的海关。反正三哥也不着急,慢慢弄。该做的事情,还是很严谨的做完的。就是排的这一溜人实在是。。。

    另外delhi机场的安检,比udaipur就乱多了(当然人也多多了)。而且那边安检很有趣。过了安检的包,都会单独给个牌子。最后凭牌子带包上飞机。我不知道这有什么意义。因为,如果我能带进一个有问题的包裹的话,我可以带一个没问题的包裹。然后把牌子换上去,再把没问题的包裹丢垃圾箱里。安检防御,要么就是把有害物品挡在安检外,要么就是通过其他手段联动。这种把安检记录交给用户保存的手法,除了折腾人之外,基本一无是处。

    img

    img

    事后补的,时间有跳脱

    这点是我们运气比较好。我们在shivaji stadium下了机场快线,出门找tutu。这里离前两天去过的connaught circus很近。当地人可能60-80能搞定,我们叫价应该在100以上。开始一个人叫价200,老婆觉得太贵了,没上。然后骗子叫价50,有一个黑三哥一起跳上来跑。我以为这哥们也是顺路,所以能便宜点,就没在意。结果他上来就扯哪里哪里可以租他的车。我想这也是tutu标准待遇啊,也没管,有的没的的聊着。他问我是不是第一次来印度,我说是的(注意他没问delhi,算是他的失误)。还有要在印度呆几天啦之类的问题,很多tutu司机都会问,也算正常。聊着聊着看到前几天看到过的景色,顿时就觉得不对了。因为我事先看过地图,都很熟。shivaji stadium到connaught circus很近,不会开了很久还在这边。而且从路线来说,走connaught circus会绕远路。所以我就伸手开GPS。刚开,丫就开始说,印度有很多Taj Mahal Hotel,所以你要给我你的准确地址,我在office里查查。

    嘿嘿,这招唬新手差不多。我和老婆都不是傻瓜,才50的车,绕大远路,又要在office里查查,能是什么好东西了?再说,当初连我去哪都不知道就敢叫价50?虽然我不知道这后面是什么把戏,但是我可以肯定的贴个骗子标签不会冤枉人了。

    我就直接和他说,虽然我是第一次到印度,但是这是第二次到delhi,我们已经在印度绕了一大圈了,这地方我五天前来说。顿时丫的表情就变得很精彩。老婆更直接,u are westing my time。扔他五十,我们就直接跑了。

    虽然跑了,但是车还是不好找。这地方过去的司机可能都是接我们这种跑掉的客人的,开价都是200。有不少出租司机在旁边歇着,和我们说。他们的车(指出租)太贵了,不建议我们坐出租。tutu司机开价200太宰人了,建议我们叫个便宜点的tutu。还有挺热心帮我们叫的,最后真帮我们叫到了一辆。

    刚被这么搞过一轮,我也怕啊。所以我开着GPS一路看过去。我开始一看说,路径错了。司机说你放心好了,我知道路,我信教,不会像他们那样骗你的。我心说,在中国,信不信教的都说自己信教呢。不过还不错,司机后面的路都是对的。最后还真是100把我们拉到了地方。可见当初帮我们叫车的出租司机真是诚心想帮我们的。

    印度这地方大概就是这样。有骗子,也有好人。有人会把你拉过去宰,也有会帮你叫个同行便宜点送回去的。有会给你乱指路的,也有不小心指错了路还专门找我们来道歉的。我觉得这样的社会也不错,挺有趣,不寂寞。当然,也可能是我没被骗到的缘故。

    后来想了半天。其实在印度吃猪肉没有太大风险,吃牛肉才有风险。穆斯林虽然不吃猪肉,但是并不禁忌其他人吃猪肉。

    这个新天地搞得真惨。。。

    by shell909090 at October 14, 2015 09:14 AM

    October 12, 2015

    @shell909090

    印度游记-2

    根据后面的计算,德里的平均小时工资大约就是150。jaipur这里带燃料和折旧才这个价格,估计工资会更低一些。

    价格的计算模式是,1500八小时,因为有上下两个上下山(琥珀堡和老虎堡),所以有200的额外燃料费。超过的2小时一小时150,总计起来就是2000上下。最后有些额外的时间什么的,会多一点钱。

    琥珀堡很古老,很有古堡探险的味道。据司机的说法,其历史甚至比jaipur还长。但是,可能是我们的期望太高了,琥珀堡里面除了镜之宫外,并没有什么太值得看的东西。

    司机还不错,不会总带我们去买东西。我们后面自己说要去买点当地衣服,他带去了一个工厂店,估计能赚一点。衣服也是不错的,老婆回来后还一直穿。

    img

    img

    img

    img

    img

    ‏@lichray评论: 美国也有,我很喜欢。

    ‏@cashplk评论: 尼泊尔也看到过类似的,他们叫Daba。

    img

    应该是“阿三黑暗料理”。号称中国炒面,其实和炒面一毛钱关系都没有,感觉上是炒的细米粉。炒过面的应该知道,炒面会比较油。印度这里放的油比较少,面更软,更像是粉的感觉。而且口味也严重的本地化了。

    jaipur其实有点乏善可陈,一天都嫌多。早上去一下城市宫殿和星相台,下午去一下琥珀堡(不去也成),晚上在老虎堡看个日落。回来的时候拍一下风之宫殿,结了。其实从下午开始出门就够了,中午可以睡个觉。

    具体可以看“世界遗产”,“斋浦尔的天体观测设备”。

    上火车之前,找了半天站台。有个三哥给我们指了路,指错了。我们犹豫半天决定往回走,就看那个三哥跑来找我们,说不好意思他搞错了。你们的车是这个站台。正说着,站台信息又变化了,我们要去了隔壁站台。

    你们人真是太好了。我上次给一个老外指错了路,地铁一发车,我可是追都没得追了。

    另外,老婆去买水的时候,被一大圈印度妹子拍照调戏了。

    亲眼目睹三哥开挂。

    我们当时听说的情况是,从jaipur到udaipur的车,只有一节ac,其余都是普卧。有个坐过卧铺的哥们还说,一楼有老鼠。而且普卧比空调还冷,因为风大不恒温。我和人说笑说,100迈的时候手伸出去张开就是D罩杯的感觉?我现在感觉被一堆大胸包围了起来。。。我曾在甘肃坐过绿皮车,三哥的卧铺比绿皮车还恐怖。

    对了,说到这个奇葩哥们。我们在umaid坐着等火车的时候,进来个妹子,开口问,do you have rose? 我当时就在猜,这是谁过生日这么大面子,让妹子到旅馆里来买玫瑰。三哥也一脸疑惑的摇头。然后妹子往外喊,他们没房间啦。。。

    我擦!我当时没忍住,就直接接了一句,do you have rooms? 三哥就一脸明白的点头,yeah yeah。

    然后进来三个人,两女一男。其中一个妹子和另两个不是一路的,坐那里等沟通。另外一对的那个英语真是。。。我这种烂水准的人居然都能找回自信,我真感慨他们居然能在印度活到现在。。。

    妹子让我帮忙问问,他们房间多少钱。然后小哥计算器上按了一个数。妹子和我说,我其实有订一间房的,但是我不想让他知道这个事。。。

    我擦。。。。我沉吟半天,幽幽的说,那我就当没听到你这句话好了。。。隔壁老婆和另一个妹子笑的满地打滚,小哥一脸疑惑。(这三个中国人到底说了什么?)

    再然后,开始帮他们沟通房间啦,车票啦的问题。问题是那个妹子又特别事多。也不能算事多吧,就是希望选择比较多,事先又没做够功课。例如这边酒店网上什么价格,现在什么价格啦。隔壁酒店是不是会便宜啦。三张床是分开的还是2+1的啦。几号的火车有几点的车啦,几号的火车要几点出发啦。问题是她这个英语水平,事还不抓关键的问。和印度人沟通的时候费劲不费劲啊。。。

    最后我猜测了一下三个人的情况。明显三个人是认识的,不然不会有两个女性和一个男性敢住一间房的选项(否则的话,也有另一个角度的“认识”)。英语很烂的那两个可能是一对,拉上一个很熟的电灯泡出来玩,在jaipur下面可能要分开走了。

    三哥的卧铺真是鼠笼待遇。层高1米左右,不能坐起身。整个卧铺是一张活页板,外侧有两条铁链吊起来支撑重量。因此也不能从侧面进入。我只能从脚底的位置,采用毛毛虫一样蠕动的方法进去。因为进出极其不便,所以一晚上都僵直着没怎么活动身体。没有毯子没有枕头,用书包垫了一下。

    另外,我事后得知,我楼上三层那么小的地方,侧身睡了两个人。我一个人也顶两个人的重量。因此那两根承重的铁链,至少承受了设计重量的一倍。三哥的东西做工还真是不错。

    老婆说,晚上有个三哥在那里走来走去,走一会就喊“dai”。我说,他后面要是加一句“孽畜还不速速现出原形”,是不是就协调多了?

    老婆锤我。尼玛你睡的倒是好,我一晚上听着呆呆的没睡着。。。

    结果老婆自己冻感冒了,一路上都在骂我。到回来还在感冒,飞机上还压耳了。

    ‏@jeuxee: 其实忘了和你说,迪卡侬那种快干大毛巾很好用,非常轻薄叠起来不占地方,可兼当浴巾毯子,湿了随便挂一下很快就干。

    再去印度的可以考虑入一个。

    感觉还是中国人太聪明了。三哥这里的偷骗行贿,到我们这里就变成不入流了。只是这种聪明反而会害了自己。

    img

    img

    img

    img

    img

    img

    老婆去和三哥讲了半天的价(厉害吧,英语能和三哥讲价),最后给我们一个“据说很不错的价格”(其实就是还价失败)。然后他们听说我感冒了,还推荐我用特制的油推拿,会好一些。

    推拿的时候是男女分开的,然后基本脱光。剩下的就基本是在抹油,没有什么穴道啊手法的玩意。最后他们拿来一盆水一样的玩意,给我洗了个头。我还觉得有点冷。不过出门的时候倒是觉得好多了。

    img

    真不愧是艺术之都,随便一个路边都这么文艺。

    img

    img

    评论里求助万能的推油们,怎么描述腹绞痛,胀气,有呕吐感。感谢大家的答复。推测是大肠杆菌感染。

    ‏@ayanamist: 兲朝社区一般性挂个水不会超过100,超过了就是宰人,就回到我前两天和你说的那个“太聪明”的问题上了

    @ayanamist: 腹泻有两种治疗方法,一种保守挂盐水治疗,国外出于控制抗生素滥用的考虑都选用此法;一种激进抗生素治疗,国内出于种种原因都选用此法。价格差异就出来了

    基本来说,国内挂水是很便宜,但是是纯“挂水”。如果使抗生素,那大概就是上千的架势。三哥这可是私人医院直接给的抗生素,而且是两种强力广谱抗生素混合治疗,再口服六种药。这个价格和国内挂水差不多,价格差异可想而知。但是如果挂个水医院不收那么贵的药费,反而收个几百的医护诊疗费,我不知道大家是不是能接受。

    @HexCube: 我有个同事在印度创业两年,后来天天拉肚子受不了就回美国了

    再次感谢旅馆的小哥,不是你的帮忙,我就跪了。

    不知为啥,给他吊过针后,那个手背到今天都还是有点疼痛。估计是针头没戳太准引发了一些问题。印度的小哥很耐心没错,可是论练习量,还是比不上我大天朝忙的满头包的护士小姐们。

    三哥不卖药啊。我们吃的药,有一种三天三顿九颗的,医院那里一版只有八颗,丫硬是用订书机订了一颗上去,不整个卖你。反倒是整个过程中的管子啊,针头啊,监控仪器用的一次性胶皮啊,给我们帐算的很清楚。

    感谢大家的安慰。有个朋友说他同事也是在火车站喝了瓶水就不好了。还有个说在印度拉到受不了,申请外派回来。到了中国,喝了瓶印度带回来的水,又进去了。。。

    中文名字是“左氧氟沙星”和“甲硝唑”,天朝人应该都知道吧。这个在其他国家一般都是三线药品,在中国和印度都是上手就开。中国是尽力卖药的原因,而且都是整包卖。三哥则是细菌污染太普遍,不给强力抗生素,等不到换药搞不好就挂了。当然,也有可能是因为我们是游客,不可能看看没效果再换一种药。但是在客观上,这种用药方法都会产生很严重的细菌耐药问题。

    朋友评价,能开对抗生素和剂量就不错了,这两种抗生素显示医药水平也不错。你得谢天谢地了。要是印度小地方医疗水准不行,你痛个两天他束手无策也是有可能的。

    img

    这里有人评论设备不错。墙上电源接口很丰富,有心跳血压监视,还有氧气接口。印度那里是护士给你上监控,然后把一些基础问题问了,然后医生过来读数据和问问题就好。整个医院好像就一个医生,其余时间都是护士在忙前忙后。

    护士妹子很漂亮,长长的波浪形头发。三哥护士小哥都很俊俏。大家神情都不算紧张。

    有个朋友评论说,想看现实,应该三点左右去公立医院看看,这是私人医院。顿时反应过来了。楼下小哥都说小贵了,人哪会多。大部分病人应该都去了公立医院。

    by shell909090 at October 12, 2015 08:48 AM

    October 11, 2015

    @khsing

    Safari Bookmarklet的快捷键

    我很喜欢以前 Safari 的 Bookmark 的快捷键 `CMD + NUM`,但是 Safari 8 以后这个快捷键被调整成了 Tab 切换,新的 Bookmarklet 快捷键是 `CMD + Option + NUM`。

    by khsing at October 11, 2015 03:04 AM

    @shell909090

    印度游记-1

    注意,由于是回国后整理,因此以下时间都转换到了东八区时间。印度是东5区半,所以当地时需要倒退2.5小时。

    img

    img

    正解应当是parathas,一种绿豆做的小煎饼。

    准确的说,印度有三个national days,其中10-02是甘地的生日。细节在Public holidays in India。在这天,我们看到的大部分门面商店都是不开门营业的。但是很多私人的小店照做生意不误。这点和中国有很大不同,去印度旅游的同学一定要恰当的避开节日(除非为了赶庆典)。

    另外,印度的kfc做的鸡腿相当不错,我很喜欢。

    感觉上印度的kfc之类的地方是情侣常去约会的地方。我们在kfc里面经常能看到一对对情侣。老婆在kfc门口站了一会等我,上来两拨搭讪的(你们几个意思)。

    img

    印度的莎丽,很漂亮的衣服,大家去印度可以买买看。我们这块是700,加搭配的裤子什么的一堆,最后砍价到1000rs。不过穿法比较麻烦,不大熟悉的话会走走路就开了。然后走几步调整一下,很花时间。

    我们穿着这个在街上走的时候,回头率相当高。后来我发现印度人对我们中国去的好像很好奇,好多围观拍照的。老婆的这个穿着更奇怪,后面杯子指出来了,缺头饰。所以回头率超高,连欧美老外都连连回头。

    img

    这家下午茶店就在我们住的简易酒店隔壁。这家酒店用的还是英式电梯(就是那种拉手门,好像建筑工地一样的那种)。床很有特色,双人房两张床是上下两张,就像我们大学里的那种。中庭有很漂亮的天井,躺椅和阳伞,看上去像是英式庭院。

    印度的物价超便宜,德里介于武汉和上海之间,其他小城市比武汉还便宜。中国人去了都是土豪。我们这天去的是一家路边摊(黑暗料理),大概相当于上海路边的小店。可是那也不是62人民币能搞定的地方。。。

    印度的咖喱变化非常复杂,但是对游客而言,你最多只能吃出主料是什么,红咖喱还是黄咖喱。基本来说只有素咖喱,鱼,鸡,羊,蘑菇这么几种变化,我建议在不同的店可以错开变化吃吃,而且中间最好间隔着几顿别吃咖喱。以免发生惨案。。。

    img

    img

    这个时间是乱序的,是第二天网好的时候补的。

    henna是一种印度的天然颜料。印度人拿来在手上画花纹,就会出现纹身一样的效果。一般消退时间随原料而定,一周到一个月都有。也可以拿来染头发,据说比较天然,不会有化学品的困扰。

    印度的henna,一般是100-200rs一只手,随大小价格会有变化。连肩膀带背部都画上也不过是几百而已。1500rs单手的价格显然是在宰客了。

    后面我们发现,印度的无线信号覆盖基本是,大城市偶尔3g,小城市基本2g,偏一点信号就基本没有。即便有2g,速度也是慢的要吐血。在印度,我们连像样的LBS都找不到,更不提其他的互联网基本服务。不过倒是有很多店在用tripadvisor。我们这点发现的太晚了,时间已经不允许测试一下tripadvisor的效果。下次有朋友去的话可以试试。

    咖喱真的是非常给力的,一晚上烧肚子,后面大便干燥了好几天。后面好几天,我上厕所的时候都是血流如注。这也是为什么我建议不要顿顿连续咖喱,太挑战人生了。。。

    后面有朋友问,环境是不是脏乱差。我觉得基本和我们的城中村差不多吧(德里老城区)。但是三哥交通真是逆天。我们这里违规行为是乱穿马路,跨道行驶等。他们干脆就无视了所有交通指示,只有满街的质点在运动。更神奇的是,这里不会发生碰撞,所以不会产生布朗运动,戳在路中间最多只会来个交警问你是不是OK。究其原因,大概是大家对这种状况已经习惯了。知道前面随时会出现人,速度一定要控制好,精神要集中,出现人要立刻闪开,闪不开可以扒车上。。。

    先说我们的票。都是在官网上定了,直接打印出信息。不需要特别的防伪,车上也没人检票,只有一个列车员拿了这张纸登记一下你来了就行。

    三哥这里有个习惯。很多人在等车的时候,拿出随身携带的毯子往地上一铺,就直接躺下睡了。不怕脏也不怕冷,上了地铁还能拿来盖。而且哪怕是在机场光滑的大理石地板上,也是如此。一群群人直接在机场前面躺成一堆,军队(真是军队)也不管。而且大部分靠柱子的地方,都没什么人吐痰的痕迹。反倒是靠墙的地方很脏,怀疑不知道是什么的污迹。。。

    后来发现,三哥的火车管理很糟糕,但是又要准点发车。因此往往会在始发站提前半小时就把车开上站台,让所有人慢慢上车。在上海,提前15分钟开始检票是正常流程。听上去是差不多,可是三哥是不检票的。你到了火车站,把行李过一下安检,完了就可以直接上车了。不检票不查票,站台距离极近,有个两分钟就能进站上车。这种情况下车硬是在站台上停半小时。而且在此期间,火车上卫生间继续开放。。。

    不是我说,三哥的火车站管理是要好好改改了。就不说上海火车站那种高效的候车管理,起码有个人检票引导一下吧。我们进站台前,看不到列车信息。来了个人,不能确认身份,说我们这趟车买的有问题。我们怀疑是骗子,想找官方柜台问问,没找着。后来他拿着我们的票,说这是卖给印度人的,所以你没法填地址。然后给我们填了个地址——1站台。这也行?反正后面没人说不行。

    进了站台后,我们找不到自己列车的信息,倒是找到了不少中国人,和我们一样迷茫。这时候国铁(印度国铁!不是铁道部!)网站立功了。国铁网站说一站台,反正我们也没别的信息源,干脆就等在一站台吧。然后开来辆车,车身上有我们的车次号。我们就互相说,就是这辆,就是这辆。开始找车厢。到此时为止,站台上还没有任何有效提示信息。

    后来发现,印度的国铁网站有时会无反应,怀疑是被刷死了(12306?)。但是上面真的有非常多的有效信息,包括列车运行情况,现在是不是晚点什么的。超级赞!去印度玩的一定要用。地址是http://enquiry.indianrail.gov.in/mntes/,点spot your train,输入车次和车站,显示运行状况。

    提示一下。以三哥的效率,从你到火车站,到你上车,有个10分钟其实就够了。三哥的车都是基本准点的。但是,你得留出找站台的时间。。。

    另外,很多人提到了一个梗。银河系搭车指南里的。grab a towel, don’t panic。

    三哥的车,每个两排座位左右都有一个插座,分布在车窗的两边。隔壁的三哥是个pm,带着一台很厚的dell。他直接在插座上接了个转换头,一头扔给dell,一头放了一个usb充电器。充电器的输出又分三路,给家里三个人的手机充电用。整个一坨就和我们看到的印度大部分地方的乱接线一样。

    img

    三哥这里空调车是送配餐的。

    刚说没两天,就亲眼目睹了三哥开挂的场景。

    后面确定下来,那个地方叫做bengaluru(南印的一个地方,中文叫做班加罗尔)。三哥说那里也很漂亮,有空去玩。有一个kung fu master在那里。我说从中国去的么?他说不是,是去了中国的。我想了想——达摩!

    后面有人说,尼泊尔也是这样。据说是当口香糖用,清新口气的。

    杯子问我们这种也敢上?实话说,三哥的管理真没法减少太多犯罪,大多数情况下你都得靠自己。不过也还好,大部分三哥都挺热情友好,对中国人感觉是好奇多于敌意(可能也是去的中国人不多的原因)。偶尔碰到骗子小偷,呵呵,实话说,我们在这方面可比他们领先多了。这叫贼碰到贼祖宗么。。。

    taj mahal是为数不多既不好玩但是我又必然会推荐你去的地方。这就好像中国的故宫。人多,又贵,麻烦的很,好玩有限。可是真的不去看看么?

    一个人25,一个相机25的门票在我们来看足够笑掉大牙。故宫好几年前就已经120了,还不带珍宝馆。但是跟导游跳排队这招在我们这里是不行的。倒不是他们不想干,而是这么明目张胆,一天之内就会捅上报纸,然后全国哗然,就像青岛大虾一样。到时候火都扑不完。

    我以为75是五景点联票,其实不是的。在红堡还是要买票,只是有打折,而且打的很厉害。印度买票很有趣,当地人一个队,外国人分开一个队。前者窗口多,但是还是堵死。外国人的队基本全是空着的。但是外国人的价格比当地人贵了10倍左右。

    至于为什么香烟,巧克力不得入内。我觉得可能和某种穆斯林习俗有关,其他地方也就随随便便了(我们在胡马雍陵是穿着鞋进的陵寝,照理不该如此吧)。安检不检炸弹反而检巧克力也是有趣。不过印度最大的仇家就是巴基斯坦,他们炸谁都不会炸一个穆斯林的陵墓吧。

    img

    像素大战里被炸了的就是这玩意。但是我真不觉得有人能在周围一个人都没有的情况下掏戒指求婚。

    其实感觉上也是某种的讨钱行为,好像在印度,这种行为并不值得羞耻。不过也完全是自愿,没有必须要给不然就生气的情况。而且就算要这么讨钱,也很有技术含量啊。

    img

    img

    taj mahal周围的污染严重到什么地步呢?如果今天,沙贾汗被扔去红堡,他能看到一大坨的白色的珍珠——见过隔着毛玻璃看东西么。。。

    泰姬陵最让人觉得震撼的,就是他用纯白的线条,展示了非常密集而丰富的空间构型。这就好像一张纯白的纸,在上面折出复杂的图案,再重新摊开。虽然还是一张白纸,上面一个字都没有,然而随着光影,你能看出无数复杂的线条在上面舞动。

    @txyyss评论: 新加坡的表示这边虽然不烧野火,但架不住邻国印尼烧,于是污染也是很严重……

    发出去后,有网友反馈,这个就是手指饼干。

    img

    img

    时间是乱序的,下火车后补的。

    ‏@uSuede评论: 欢迎去瑞士glacier express体验他们的三道式午餐,价格和味道简直感人。

    img

    img

    时间是乱序的,下火车后补的。

    印度这里的信号质量并不好,导致很多地方wifi用不起来。我们10天用了700多m流量。wifi是租的,10天340多点。大家可以自己估量一下。

    但是我强烈建议大家去印度后一定要有信号,如果没信号,很多时候很不方便。例如查火车,分辨骗子等等。你有网了,查一下,开个GPS,他们就很没办法。

    有网友在这里问了印度的财富情况,这导致了我们下面的一些调查和推算。

    img

    img

    img

    时间是乱序的,下火车后补的。

    看看就好。。。

    img

    时间是乱序的,下火车后补的。

    这条评论比较多。大部分都建议是,干脆全手机接入算了。因为信号可以搞无线,电力传输可没办法。在地区电力负载能力有限的情况下,低功耗电器是唯一的选择。我们后面在udaipur就碰上了大停电的问题,店主反应说这都是常见现象了。同时,线路接入也极乱。在楼下喝果汁的时候,老板使用的榨汁机和多个设备接在了一个大接线板上,接线板的插头被剪掉,和其他几个接线板一起,用裸线插进了一个底座里。露天,整个设施没有做过防水,也没有看到保险。。。

    但是无线网络的话,以印度的人口密度,3G很可能都不够使了。事后测试的反馈是,印度大部分地区勉强有2G(无法确认是GPRS还是EDGE,因为显示都是R,漫游),有时2G都没有。3G普及看来都需要很长时间,4G就更长。而如果使用wifi类信号接入,先不说在乱糟糟的地区怎么拉线,wifi信号密度和串扰也是个比较头痛的问题。

    同时,有人也提到,中国农村也有类似问题。小一辈的基本都有智能机,但是房子里都没有电脑。大部分都是比较差的杂牌安卓机,移动4G有覆盖,但是一样,屋子里信号就不好。

    看来全世界的电脑普及还大有可为,更多人拥有和使用终端,就会产生更多的通讯需求,进一步改变生活模式,甚至社会结构。这也难怪google将发展定位到印度。印度有非常大的人口基数,发展空间广阔,而且不像中国那样不友好。但是,教育和基础设施极差,会严重制约发展。google要么祭出黑科技,要么就要干铺路修桥的活了。

    感觉上,对大终端量的点对点通讯设备,直接吊在气球上扔上天是个比较省力的办法。

    事后大概查了一下位置,大约在bamanpura到dausa的这个位置,发推的时间大概已经到了jaipur。大部分小楼都是六层以上的,和前面那种两层三层的建筑一下就拉开了级别。

    img

    据说是以前有钱人的家,后面改造的。

    by shell909090 at October 11, 2015 02:55 AM