台場 2016-08-27

趁着台风来之前做点ingress任务,选择了台場。

查路线的时候鬼使神差地选了一个到现在为止我还读着拗口的「ゆりかもめ」电车,然后选择在「お台場海浜公園」下车。自然而然的我就开始做那个18个「お台場公園めぐり」连续任务了。

刚开始一两个我觉得还没什么,还觉得那两个不同颜色的缠在一起的管子挺好玩的。

任务一开始会往「お台場第三公園」方向走,那个公园人很少,从地图上看是一个正方向的公园,三面环海,中间有个盆地。

(more…)

2016年8月25日

好久没有写博客了。但是VPS的钱还是要交,于是想着继续写点东西吧。

之前博客放置不写,有一个原因是没法升级到最新WP,今天查了下,感觉可能是服务器的防火墙的问题,增加了可以访问外部HTTPS网站之后就可以了。

小结就是iptables功力不够。

今天另外做的一件事情是换了主题,这样感觉就和以前不一样了。

暂时就这些。

同步IO与异步IO(NIO)

只是一点小感想,仅供参考。
同步IO是比较传统的IO处理方式,等待IO完成继续接下来的处理。NIO相反,等待IO处理完成的时候可以处理其他的事情。典型的例子如node.js, nginx, redis等等。这些都是比较热门,甚至被认为是标杆的项目。一时间传统IO被丢弃,服务观开发可以用node.js了,其他语言都是垃圾,redis/memcache必须用redis,memcache是旧事物了等等。乍一看,似乎NIO就像New IO一样,但事实上不过是Non-blocking IO而已。
就像很多人发现redis在处理单个大请求时同样会阻塞之后其他所有请求一样,Non-blocking IO只是在IO处理上不会阻塞,在内部的任务处理上仍然会因为计算原因而被阻塞。换句话说,NIO适合通讯层面的处理,基于NIO的库比如Netty对于构建高并发的系统来说很有帮助。但是认为NIO可以代替一切了,这只是错觉。对于CPU密集的任务来说,仍旧需要类似传统IO+线程池的技术来提高CPU利用率和吞吐量。
小结一下,根据场景选择方案,NIO不是银弹。

ruby

使用Rails后的一点想法,关于模块化等等

好久没有写博客了,最近老是在周末写公司的代码,自己平时的学习有点拉下了,需要一点改变。

使用Rails和Ruby开发也有半年多,最近渐渐对Rails的风格有点自己的理解了,想通过博客记录下来。

“Rails是一个很特立独行的Web MVC框架”,有点不记得这句话从哪里听到的了,但是现在觉得说的很在点上。

Ruby与Rails不同,使用Ruby开发并不没有很特立独行的感觉,老老实实开发,就和用Python开发一样。

Ruby的框架比较出名的有Rails。除了比较底层或者不太适合Web开发的语言,各种程序语言都有各自的Web开发框架。有一些Web开发框架是参照Rails来设计的。Rails的特点是“约定优于配置”,简化了Web开发,特供了全栈式的开发体验。对于初始项目来说这几点很有利,可以快速做出产品原型。但是个人在开发一段时间后,觉得A肯定优于B不是绝对的,A和B有各自的pros and cons。自由配置切换对于长期维护的项目,项目逐步扩大时候的flexibility是很重要的一点。

以上是我个人的一些想法,不过我觉得肯定会有人跳出来反驳。就像有人写了“几年后再看创业初期的技术选择,不会再选择Rails,列举出Rails/Ruby存在的缺陷“的文章之后,会有人跳出来反驳一样。自己Google如何在Rails中应用DI(依赖注入),出来的第一篇是反对第二篇DHH(Rails的作者)说Rails不需要DI的文章,顺便说一句,DHH的言论感觉很多的时候都是“斩钉截铁”的原则一样被Rails社区接受。包括各种Rails的书籍,“The Rails Way“,用Rails的方式来开发等等有点”教条主义“倾向的书籍,所谓的”特立独行“就是指这样一种围绕Rails的氛围吧。

即使是特立独行,相信也有会拥护的人,当时也有不喜欢这种排外的氛围的人。各种语言之间,各种框架的争论从他们被创造出来时就已经开始了,Rails不过是其中的一个例子而已。为了工作,该学的还是学,即使是Rails论坛上有倾向性的问答。每个人因为背景,因为资历,强加自己的喜好到别人的身上大部分时间不会有太好的结果。

言归正传,个人其实不喜欢Rails的shinny controller, fat model风格。没有实践shinny controller的项目,controller中非常多的DAO代码,就是多次调用或者调用多个模型。项目发展到一定程度,想要对数据项目部分修改时,由于涉及的代码太过分散,维护困难的事情并不难以想象。所以很多人推崇shinny controller。但是我个人并不认为单层模型可以处理所有的事情。换句话说,把所有业务逻辑下沉到模型层只是把混乱的部分放到另外的地方而已,维护和理解难度并没有太大的改观。首先大部分人眼中的模型只是数据库表对应的映射,这会极大地限制业务逻辑的表达能力。比如表单内容并不是某个表的映射的时候,数据库表并不和模型完全一致时(默认的ActiveRecord只支持单表继承(STI),JOIN TABLE继承只能自己做),涉及多个表的虚拟模型等等。当然,眼光敏锐的人肯定知道追加新的非数据库表映射的模型应对各种情况。但是在保持MVC的前提下用模型应对各种情况就足够了么?我个人觉得还有疑问。

OOP的一大特点是封装,还有类似多态等高级功能。实践中还有开闭原则等等辅助设计参考。各种设计模块描述下在某些情况下该怎么设计类,满足维护性的要求。如何在实现业务逻辑的时候,安排各种模型,满足各种设计原则,避免后期维护困难,我觉得这不是简单地参照“The Rails Way“就可以完成的。业界在长期的经营中提出了各种方法,包括TDD(可以用测试来反馈设计不足),DDD(域模型驱动,域模型是核心模型,有些时候并不能简单地映射到表,需要虚拟层或者映射层),还有就是不知道为何很多人都想避免的各种企业开发模式。

我觉得衡量一个软件的扩展性,从它自身的拓展性方面入手可以有所了解。Rails提供一些中间件的注册方法,有RailsEngine等等。Rails并不是非常难以修改的系统。Rails之外的Ruby也有大家喜欢在一个命名空间下开发出一些插件,用插件名当做模块来操作的案例。但是个人感觉以Rails为基础的开发总是有一种难以放开手脚干的感觉,估计是各种Rails论坛上“频繁变化的最佳实践和风格”,一不小心跟不上就会发现之后就没法好好开发了。

比如个人对于使用分层,模块化和DI一直很犹豫。软件分层一直是被认为是一种非常有效的协同开发模式,有助于系统的安定的隔离。典型的MVC软件只有三层,如果是shinny controller的话,其实只有单层M,怎么想都对于开发来说层次太过单一。在面对复杂的软件开发时个人并没有看到或者理解出来有什么好的地方。为什么要导入多个层次,比如依赖外部服务时,你不应该把外部服务嵌入你的代码中,至少要留一层wrapper,比如XXXClient。这个XXXClient并不完全是为了随时应对外部服务的参数或者接口变化,同时在分析代码依赖时有很好的起点。这种XXXClient不一定是按照RESTful形式设计,你也没法要求外部服务按照这个规则设计,在性能与设计上,外部服务往往会选择性能。如果你想尽办法把服务设计成模型式的,之后因为接口修改导致你的模型失效,个人觉得得不偿失,所以在这类设计上,其实是按照层来处理的,属于底层依赖的服务,往往不会按照典型模型来设计。举这个例子,个人是想说明软件分层的必要性。感觉Rails并不推行层次,而是认为模型可以解决一切?特别是app/services层次这种。当然,什么是分层,什么是模型,还有什么是模块,意义上有重合的地方,所以结论上可能有所分歧。

第二个个人认为不可思议的地方是,模块化与DI。所谓的模块化,个人理解在Ruby中是聚合相关功能的一个入口类。这个入口类可能采用class variable,class instance variable或者thread/fiber variable来存储相关配置或者实例,用于之后的调用。在Rails中还有一种方法是initilazers中初始化,以常量的方式被其他类使用。实践中,类似DI的,由依赖组装成入口类实例的方式也可以存在,但是貌似DHH觉得DI对于测试比较有效,然而Ruby是开放类,所以没必要使用DI,修改模块入口的行为同样可以达到DI最大的目的。就像Google第一篇Rails DI的文章一样,个人不赞同DI没有用的言论。在依赖多个外部模块/服务时,你的测试代码会很复杂,比如依赖外部HTTP服务,本地文件读写,这些是一定要对代码的行为有所修改的,在测试服务器上往往无法执行成功。如果一律按照整合测试,那么开发会变得很被动,不灵活,很难关注代码自身的逻辑而不被各种预期行为修改而分心。特别是模块,你修改了全局模块的行为,你必须在测试之后修改回去,这其实是一个很大的缺点,如果你因为测试速度原因,尝试同时执行你的测试用例,你就会发现你的代码出现各种奇怪的行为,这也是为什么不推荐使用全局变量的首要原因。用模块级别的开放修改,其实等价于全局变量的值修改,理论上这是一种很危险的行为。其次,资源ownership,C++中最重要的思想是资源属于谁管理,那就由谁来释放。虽然Ruby有GC不用太关心资源的释放,但是Rails中每次XXXBusinessObject.new(parameters…).foo是一种很“别扭”的设计。当然我并没有说这种代码不应该存在,类似的代码从设计模型上来说,是Command模型。主要缺点在于没有上下文变量,比如你这个Command在执行的时候,依赖于某些配置,你肯定不希望让调用方关注这些信息,因为这不是他的资源管理范围。你也不应该让Command自身管理这类信息,这种往往是多个Command通用的数据。典型方法是在Command#execute(context)的上下文中添加,这个context往往存在一个类似CommandFactory之类的Class中。如果只是典型的MVC,极端的Rails的fat model的话,估计只会把配置放在某个全局变量(模块的Class variable/Class instance variable等价于全局变量),然后让Command执行。全局变量还是DI相信各位自己有自己的想法,不要觉得换了一种形式,甚至带上模块化了(Resque无法初始化两个),就可以不用考虑依赖关系随意使用了,这往往就是Rails项目中不加限制之后依赖关系混乱的原因之一。相反的,如果你把各种资源合理的放到各个类层次上,会让你对于类层次设计,资源归属管理有更好的理解。以前看到过一句话,“Rails把程序员“惯坏了””,个人觉得不管是全局变量还是各种DAO的使用上,Rails并没有真正让程序员感觉到自己有必要理解系统的构成而不是上手就写,当然这也是魅力,也是毒药。

不知不觉写了好多,也算是把最近自己对于Rails的想法记录了下来。Ruby其实并没有那么强烈的风格倾向,但是Rails个人觉得过于特立独行,而且在大项目上如果一开始就没有按照某种有先见性,指导性的原则开发的话,非常容易变成一个依赖关系混乱,到处都是全局变量的难以维护的代码库。对于这点,请理解Rails只是一个MVC框架,并不是唯一的标准。该封装的时候封装,该分离的时候分离,Web/软件开发是一门需要经验的艺术,而不是随便什么人画画就以为可以把抽象画卖出去的那种非常低门槛的开发。最后,Rails如果你好好理解它的不足,理解它的优势,理解它的内部,不认为Rails可以做一切,不认为Rails什么都不能做,相信你可以更好地使用它。

来日本一周年了

去年的今天,一个人固执的来到了日本,开始了新的生活。

离开父母,去陌生的城市陌生的国家,讲陌生的语言。
在这之前我从来不敢想象。
以便至今都没有任何的真实感。
每天上下班,看着帷子川里流动的水,就会想,为什么我在这里,我真的在这里吗?

今天和我妈谈到时间,她说,人年纪越大就会觉得时间过得越快。
看来我已经是老了。

还记得一年前的那个晚上,刚搬进Share house时房间里空空荡荡的,隔壁烧烤店和楼下卡拉OK的声音交杂着传入耳里,关了灯裹在公司给的廉价的被褥里,不停的问自己是不是在做梦。

在Share house里生活到了去年3月底,经历了很多事,认识了很多人。
一边学着日语,一边习惯生活,一边忙着工作。
一边想着,为什么我会在这里。

樱花盛开的晚上一个人扛着大包小包的家具用品走在去新公寓的路上。
累了就在树下坐会儿,拍拍樱花,看着路灯洒在河里的光和月亮的倒影交织在一起。

新公寓不大,就一个房间,加上阁楼也就9平米。
在那个工作也忙得像狗一样的四月里,还得跑家具城为了那蜗居购置家具布置房间。
人生第一次,拥有自己的一套家具。

一切安顿下来后的初夏,开始了登山。
人总是怕闲,或者说是怕寂寞。
从高尾山、日ノ出山、金時山、尾濑高原,到富士山顶,一个人,说是体验人生什么的都是假的。
爬山的时候,很少会去想东西,身边一个人都没有,往往走了一个小时却看不到人影。
即便如此,也不会去思考什么。
只是走,不停的向前走。

就这么一个人安安静静的过着日子,转眼到了九月份,身边多了一个吵吵嚷嚷的家伙。
吵吵嚷嚷的过上了当初约定的两个人的「小日子」。
偶尔晚上一个人还醒着的时候,还是会怀念一个人住的那段光景。

于是,一年过去了。

8月24日随笔

时间一晃已经到了24日,距离辞职已经两周多了。这段时间除了处理事情之外就是休息了,现在记录一些这些天的小事。

口吃

在原公司头两年我是没口吃的,但是三四年的时候我发现自己在说话时会很高几率口吃。原因我大致知道,长时间工作没有和他人谈话。两点一线,在家也很少谈话。解决方法理论上很简单就是平时和别人多说话。不过造成这样情况不得不说原来小组的氛围太压抑,工作分配不合理等等。
现在几个星期后,感觉自己好多了,基本没有那种症状了,主要可以轻松休息,做自己喜欢的事情。这也算是这段时间的工作状态恢复吧。

twitter

月初对twitter很上心,因为好久没用了。不过最近发现时间线上的内容好没有营养,越是生活推越是有固定的圈子;而且年龄层次不同谈的内容感觉也不同,好多学生;在职的稍微好点,几个现实中就有接触的自然没什么问题,其他的感觉难谈拢。唉,还是当做信息窗口吧。

(more…)

坐出租车和uber

昨天突发奇想去了一次西湖,路上高铁等按下不表,单就坐了两次uber写点对于杭州出租车的想法。

拒载,选择性载客是一种恶化打车环境的行为。从司机角度来说,碰到一个扬招的人,问了去处,太近不去,太远也不去,其中部分原因是觉得不实惠。比如堵车,堵车费也不高。还有原因是太远回来路上基本是空车。个人觉得从司机利益角度来说无可厚非,但是导致打车人等待时间变长,打车体验大幅降低。本来出租车作为公交的一种更加自由,但是现在看来司机也有自己的小算盘,不愿意完全为你做事。我觉得这个和出租车行业长期以来一种“垄断”性质,收入低,不明不白份子钱,运载力不足等等脱不了干系。期盼相关部门解决这个问题?不太可能,他们只向钱看齐。

解决行业痛点的一个是之前快的打车,滴滴打车之类的工具,问题的原因没法直接解决,但是通过提前告知去处,然后司机选择是否接单,这样就可以避免扬招时的尴尬。个人觉得是一个很好的通过协调打车人和司机之前的方案,间接提升了体验。但一个副作用就是扬招的人更难打到车了。另外在车比较少的地方仍旧很难打到车,去得比较远没有人不愿意接单也没办法,虽然比你连续扬招几辆被拒绝要好。其背后的一个问题还是出租车运能不足。个人觉得这其实还是行业的恶性循环造成的,包括准入机制,垄断性质,万恶的份子钱制度等等。

运能不足不能期待出租车行业整体反思,”人民拼车“其实是一个很好的切入点,通过大众的车辆来弥补这个不足,类似嘀嗒拼车,uber都是不错的工具。uber其实还更进了一步,不使用国内那种司机选单方式,而是自动调度,这里其实杜绝了选择性接单这种恶化体验的行为。从使用上来说,不管到哪里,让系统帮你选择接单一方面公平,另一方面也帮你选择了路线,降低了运营的难度,实在是对司机和搭车人都很不错的使用方法。

当然,这对于传统的出租车行业是一个很大的威胁,也看到过各种闹腾。对于搭车人来说,最重要的还是方便快捷。地铁站常看到出租车、黑车甚至还有摩托车,出租车拒载很常见,于是只能黑车,那些叫嚣打击非法营运车辆的人理由充分,然后呢维护的只是出租车的利益,难道半小时路程你让我走回去?现在太多这种只看表面不考虑真正解决的事情。

我其实也不会预计之后这个行业的发展,出租车现有的制度只会劣币驱逐良币,打车体验很一般甚至很差。专车虽然可能不专业,但是满足了很多人需求。撇开价格来说,两者可能会达到某种平衡,在不同层次各自覆盖。

最后说一句,我一直深信的出租车下午4点换班的说法,后来才知道只是大部分出租车司机不愿意做下午4点后堵车比较多的生意,于是昨天下午吃好晚饭后直接用uber,再也没考虑出租车。