The Perfect Language

如果有一种语言是完美的,那它应该是什么样子的?谈谈我的看法。

防止用户用石头砸自己的脚

C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.

这句话出自Bjarne Stroustrup。即便C++让搬起石头砸自己的脚看起来更难一点,但并没有从根本上阻止用户这么干。根本问题在于用户是靠不住的,他可能不知道哪些行为是危险的。C++里面有不少这种一不小心就砸到自己的特性。比如指针和引用,每个程序员应该都有被C++的指针和引用伤害过,用的姿势不对就会引发灾难。所以写C++程序一定要小心翼翼,虽然我已经写了很多年了,但还是保持着“敬畏之心”,每次不确定某个写法的时候都要查资料反复确认。还有一些本来就可有可无的特性,引入之后反而让事情变得更复杂,但是又没有带来任何收益。比如i++++i,写个i = i + 1能又多难呢?这都是导致程序员脱发的元凶啊,生活本来可以更简单的。

那应该如何防止用户干这种事情呢?在指针和引用的问题上,Rust的处理方案是非常优秀的,通过ownership和borrow checker完美的解决了这类问题。只要用的姿势不对,编译都过不了。虽然代码写地略痛苦,但是和上线之后才发现问题相比,这点痛苦完全可以忽略不计了。

有问题就应该在编译阶段就解决,运行时再发现已经太迟了。

Maybe, Option, Optional

如果有一个整数型的变量,如何判断它是否有值呢?下面是一种常见的做法。

int write_x();

int read_x(int x) {
    if (x == 0) {
        do_something_without_x();
    } else {
        do_something_with_x();
    }

    return 0;
}

read_x能否正常运行,取决于write_x的实现。如果write_x也一样认为0就是没有的意思,那就万事大吉,否则就会出翔了。假如由两个团队分别维护read_xwrite_x两个函数,出现问题的机率更大。即使某个时刻双方达成了约定,无法通过系统进行约束,约定就是废纸一张。当然可以尝试通过其他途径进行封装,比如protobuf的has_x(),或者是将x的访问统一封装成函数库。只要有机会可以直接操作x,都无法彻底的避免。如果在语言层面支持,结果就非常不同了。

这里需要的是一种类型,可以完美的描述某个东西不存在的场景。这个类型,就是Haskell的Maybe,Scala和Rust中的Option,Swift的Optional。如果用Scala的话,上面的代码应该是这样的。

  def readX(optionX: Option[Int]): Unit = {
    optionX match {
      case Some(x) =>
        doSomethingWithX()
      case None =>
        doSomethingWithoutX()
    }
  }

通过Pattern Match,如果忘记了匹配case None,编译器会提醒你。如果不使用pattern match,而是通过optionX.get获取,当x不存在的时候会抛异常,虽然问题发现的晚,但是可以保证不会执行一段奇怪的逻辑。

Option实际上是一种代数类型(Algebraic data type),借助ADT可以实现各种复杂的类型,详细解释可以参考Haskell的wiki

技术不能改变世界

由餐厅想到的

看着路边的网红餐厅一个比一个火,想到一个问题。对餐饮行业来说,厨子重要吗?厨师毕竟决定了菜好不好吃,应该算重要的吧?但是回头想想,这些餐厅的炒的菜真的那么好吃么?好像也没有。只要厨子做的不是太差,基本上餐馆就不会倒闭了。但是餐馆如何扩大盈利规模,这就不是厨子能决定的了。还在于其他的方方面面,比如如何搞定市场?如何提升食客的体验?包括心理上的体验。对于这些事情,厨子是无能为力的。

如果站在厨师的角度,可能看法就完全不一样了,觉得自己特别牛逼。“这是一门艺术!”。不得不承认,能够把菜做好确实需要能力和经验,也具有一定的挑战。牛逼的厨师当然也有,但这本身就是凤毛麟角了。对餐厅来说,厨师不是短板,这个厨师不行,完全可以换其他的,反正也差不到哪里去。这也就意味着,厨子没法向老板要求更高的薪水。

厨子如果只知道闷头炒菜,一定是没有前途的。

程序员与厨子的共同点

程序员和厨子其实差不多。区别在于,相比炒菜而言,写代码有一定的门槛,需要一定的知识。但是说实在的,门槛高不到哪里去。不要看大家吹水的时候都是讨论各种牛逼的算法牛逼的语言,其实大家都很水。想想自己平时工作所贡献的代码,真的没有什么技术难度。在这个行业里面,往往都是面试的时候要求造火箭,上班之后拧螺丝。计算机因为是最近几十年才开始发展,所以现在还有一定的门槛。但这个工作早晚会变得像厨师、司机等等职位一样平凡,只是时间长短的问题。

有个很重要的问题,工作本身的难度就比较低,程序员的能力并不能得到很好的发挥,价值也就无法体现。如果工作的难度只有60分,对老板而言,一个60分的程序员和80分、100分的几乎没什么区别。虽然你可以造火箭,但是我这里只需要一个拧螺丝的,所以我只能付给你拧螺丝的薪水。

技术优越感

相比厨师而言,程序员更容易产生“技术优越感”。什么叫技术优越感?

一是盲目地认为技术可以解决一切的问题。就像厨子不知天高地厚,认为自己才是餐厅的财神爷,高估了自己在整个链条中的影响力。只把精力放在炒菜上,认为其他的一切都不重要。因为已经在这里累计了一定的优势,所以寄希望于通过自己最擅长的能力解决问题。做事情的时候,往往只关注技术方面,比如写博客,文章可能写不了几篇,但是框架换的非常勤。

二是瞧不起其他的方方面面。写代码这件事,当然有它的难度。完全可以朝着造火箭的方向去努力。因为存在难度,有门槛,有挑战,当掌握了这些“高端”技能的时候,反而忽略了其他的基本技能,非常抵触去做这些“低端”的事情,觉得自己做这些事情完全是大材小用太浪费了。也因为有了这些,勉强可以通过拧螺丝钉来解决温饱问题,根本不会考虑去做些不一样的事情。

100分的程序员更容易产生技术优越感。为什么呢?能做到100分,必然克服了无数的困难,一路上披荆斩棘。自以为Hard模式都已经通关了,还有什么做不成的?另外一方面,一定得是对技术有巨大的兴趣,才能自我驱动,这也就意味这是他们的舒适区。相反的,60分的程序员更容易有“全局观”,不至于在一棵树上吊死,逼自己做不擅长的事情是很痛苦的。

当厨师离开平台的时候,才会发现,“啊,原来我除了炒菜啥都不会”。这下生存都成问题了。

技术更应该作为一种优势,而不是赖以生存的唯一能力。作为厨师,当然可以花心思研究怎么炒出100分的菜。但是只有炒菜100分,其他都是0分,风险是很高的,发展终究要受限。假如各方面的能力都能均衡发展,岂不是更好?炒菜80分,其他的能力60分,这才是比较健康的状态。

题图来自Unsplash,作者Michael Browning。

面向未来思考

我不是一个善于规划的人,更确切的说,我非常讨厌做规划。总觉得“计划赶不上变化”,规划是一件非常虚无缥缈的东西。回顾一下过去,我所能思考到的未来大概也就是一周左右吧,“鼠目寸光”。最近思考一番,发现这是一个非常严重的思维缺陷,虽然内心非常不愿意承认。一个国家都需要五年十年一百年的长期规划,个人难道不应该做思考么?三年之后,我希望变成什么样,五年十年呢?从来没想过。

这就好像一辆车在路上行驶,只挑眼下最容易走的路,但是并不考虑目的地在哪。虽然好像走的很爽,但是走偏了。总结下原因,大概有这三个:

  1. 学生时代并没有养成这种习惯,这个阶段的人生基本上都已经被长辈被社会规划好了,不外乎中考、高考、大学毕业找工作,结婚生子。自己只要朝着这些方向努力就行了,根本用不着自己考虑。我想这应该也是大多数人的情况,天赋异禀的神童除外。
  2. 少不更事的年纪盲目听信了微博上技术大牛的“毒鸡汤”,主张“追求技术的同时顺便把钱挣了”。我信你个鬼,糟老头子坏的很。
  3. 工作事务繁忙。大脑的“带宽”被疯狂的挤压,视野只能停留在具体的事情上,想着尽快把当下的事情解决掉,无暇顾及将来。

工作多年,一直把提升技术实力,解决技术难题作为自己的目标。持续学习,花了不少时间在研究各种技术上面,遇到过很多困难,但是也算过得开心,起码时间投资是值了。坚信职位和待遇这些只是能力的附属品,能力上去了,这些自然都会有。自己从来没有反思过,这种想法到底对不对。最近有点疲倦,发现好像这些事情对自己吸引力没有那么大了。所以开始反思,做了这么多努力,为何现状与自己的预期有这么大差别?

追求这些东西对个人发展有益吗?当然有益。但是就工作本身来看,这些绝对是错误的目标。犯了“用战术上的勤奋掩盖战略上的懒惰”的错误。在公司工作,目标是什么?当然是升职加薪,做成打工皇帝啊。很直白的道理对不对?这些和技术能力有关系吗?有一定的关系,但绝不是决定性的。更为准确地说,关系非常有限。如果工作之初就能看到五年十年之后的话,一定不会有这些天真的想法了,在经历的很多事情上,也一定会做出不一样的选择。

仅关注眼前的事情,还会有个弊端,就是会把短期内的事情看的非常重,不自觉地放大这些事情的难度。但是回头想想,当时觉得是困难的事情,其实什么都算不上。跟未来的挑战相比,这些都是小菜一碟。

在公司工作,那就一定要好好的“混”,朝着那个目标而去。在技术上钻研,写博客,玩摄影,那就要争取在各个圈子里面产生一定的影响力,而不仅仅是沉浸在自己的世界里。看的要远,目标一定要明确,这是对自己的新要求。

题图来自Unsplash的Johannes Plenio。

新加坡见闻

亚洲的城市中,香港和新加坡可以称得上是风光摄影师的天堂。香港离深圳比较近,拍过很多次。去新加坡拍风景则是我的梦想。对于新加坡的所有印象,都来自于一位新加坡的摄影师 wonglp。他同样也是M43用户,所以我一直把他的照片作为标杆。我个人的摄影风格也受到他潜移默化的影响。他所拍摄的城市风光,让人感觉新加坡是一座来自未来的城市,所以很期待有朝一日也去新加坡拍一次。

五一小长假由于没有提前规划,就在深圳度过,感觉浪费了一个假期。所以五一过后就马上开始准备去新加坡。开始以为需要花很多时间准备攻略,后来研究了一下地图,发现根本不需要,新加坡本身非常小,几个景点地理位置上都比较近,而且公共交通非常发达,基本不需要操心了。出发之前在YouTube上看了一些视频,特别推荐cctv4的远方的家系列节目(远方的家一带一路038-048新加坡),简直就是旅游界的“舌尖上的中国”。

对一个国家的第一印象,一定来自于机场的体验。樟宜机场的用户体验真的可以用吊炸天来形容了,连续七年蝉联Skytrax“全球最佳机场”的称号。不夸张的说,单单这个机场就值得花一天的时间在里面。今年4月份星耀樟宜(Jewel Changi Airport)开业后,机场的可玩性更高了,最著名的应该就是这个网红室内瀑布。不过人真的很多,很多商店都要排队进入,比如SHAKESHACK、POKÉMON(实在搞不懂买个玩具也要排队)。

从机场到酒店的路上,让我一度产生了走在滨海大道上的错觉,路的旁边也是海,很像深圳湾公园,区别只是树的种类不同。其实新加坡与深圳在城市环境上有非常多的相似之处。气候接近,都是又热又湿。城市的管理者都比较注重绿化。深圳被Lonely Planet评为2019年度最佳旅行城市第二名,新加坡则是2015年最佳旅行国家第一名。

在建筑风格上,新加坡则要丰富的多,融合了东方与西方,古典与现代。这点也很容易理解,新加坡的历史比深圳可要久的多了,倒是和香港比较类似。

金沙酒店作为滨海湾的地标建筑,其优势在于楼顶的无边际泳池和空中花园。泳池一定是住客才可以进去的,空中花园可以买门票上去。从舒适的角度来讲,金沙并不是最佳的选择。大堂人来人往非常的拥挤,服务态度也非常一般。本次行程金沙住了一晚,其他几天都是在Ritz-Carlton。相比之下Ritz-Carlton就非常安静了,并且态度真的让人感觉很舒服。更意外的是,印度裔的工作人员汉语居然说的非常6。

第二天早早醒来,看到窗外下过雨之后的天空非常魔幻,于是独自出门走到Helix Bridge这里拍照,从这个角度看Singapore Flyer还是挺特别的。

Blame Oriented Programming

面向对象编程大家都知道,之前还听过面向“离职”的编程,意思就是写代码的时候要假设自己马上要离职了,考虑的接手同事的感受,应该把代码写的简单明了,多做注释,多写文档。今天给大家介绍“面向锅的编程思维”。

作为后台开发人员,自己的后台服务通常都会调用其他人的模块。在系统设计的时候,面临服务之间调用的异常,有两种做法。

  1. 根本不考虑异常情况,调用失败也不处理。假装所有接口都一定会成功。
  2. 考虑异常,但是觉得服务是对方的,挂了的话责任应该是对方的。所以只做简单的重试。

第一种做法必然不可取,一般也只有刚工作的程序员才会如此奔放。大多数人可能选择第二种做法,但是服务上线有问题后很可能锅就落到自己头上了。为什么?因为对老板来说,他并不关心具体原因,只知道这个功能有问题,你俩都要挨板子。这个时候很可能就说不清楚了。比如对方说,我的服务就是需要由调用方保证成功的,或者说我的服务不保证100%的成功率,如果你要求100%那就不应该用我的服务。这样一来,主要责任反而会落到自己头上。

那应该怎么做?对于每个可能失败的地方,都要做好以下思考。

  1. 可能失败的地方是否关键路径,失败了影响大不大?会不会影响升职加薪?
  2. 能否进行重试,如何进行重试?特别需要明确的是,重试的考虑,是有可能超过主流程的工作量的,因此这也是评估整体工作量的非常重要的一个因素。
  3. 如果重试不成功,那应该如何处理?如果最终没有解决方案,那至关重要的一点是让各方都知晓此处存在的风险,由整个团队来进行评估,不要自己一个人做决定。

这些其实是我自己的痛点。一开始没有考虑好,最终要花费很长的时间去修复这种问题。更别提这些问题已经造成的后果了。如果早一点意识到这些,那该多好。

2018过去了

又到了一年一度年终总结的时候。

技能树

Scala

2018年最大的进步,莫过于点亮Scala这个技能了。

Kafka分布式消息队列有一些非常厉害的特性,一直以来都想看看Kafka的源码,了解其实现原理,但是因为对Scala一窍不通,最终还是放弃了。Scala是属于Java阵营的,作为一名C++阵营的程序员,始终有点排斥Scala。2018年初,工作上需要使用spark,又多了一个学习scala的理由,那就干脆就好好学一下吧。虽然我没有任何的Java基础,但是学习Scala基本上没有什么障碍。反而很愉快的发现,因为有Haskell的基础,很多概念一点就通。

Scala最吸引我的地方,在于它很好的结合了函数式编程和实际应用场景。在函数式编程上,Haskell一定是最牛逼的。但是作为一门偏向学术派的语言,很难找到实际应用场景。在Haskell中是完全写不出imperative范式的程序的,入门的门槛非常高,导致Haskell的用户很少,可以用凤毛麟角来形容。Scala则完全不同,既能支持Functional范式也能支持Imperative范式。这决定了它的用户要比Haskell多的多,也就意味着一定能在实际业务中使用。

Haskell之所以难以掌握,就是因为学了也没有地方用,过一段时间就忘了。没有实际应用,也很难理解Functional Programming的好处。更有深远意义的是,Scala让我在学习Functional Programming上花的时间有了回报。

写Scala代码是种非常愉悦的体验,以至于我宁愿少写点C++多写点Scala。使用Emacs编辑器,安装Ensime插件,就可以非常完美地实现代码跳转,文档查询,代码自动补全等等这些功能。作为Emacs的老用户,我从未有过这样完美的体验。之所以能实现这么完美的功能,都是因为Java的功劳,所依赖的jar包都在本地,相关的类、函数、接口都一清二楚。

对于Scala,不同的人写出的代码是可以完全不一样的。不仅仅是指风格上的不同,而是范式上的不同。当把一些非常繁琐的逻辑,使用functional programming的范式表达出来的时候,内心是非常骄傲的。这也是Scala愉悦体验的一部分。

对于具体的技术而言,生命周期一定是有限的。现在热门的技术很可能过几年就消亡了,比如Flash。眼下解决某些问题非常完美的解决方案,在几年后可能就无法应对新的挑战,比如Mysql在分布式场景下的困境。但是, 更高维度的科学和技术,一定会对整个产业持续地产生深远的影响 。比如算法,无论硬件多么发达,在面临更复杂的问题时,必然存在性能上的瓶颈,为了提高效率,不得不设计更高效的算法。Functional Programming也在此列。在这些方向上投资,我觉得是更有价值的。

如何学习?

2018年总结出几个关于“如何学习”的经验。

自顶向下优于自底向上 。对于某个具体的问题,之前的习惯是直接搜答案。因为同样的问题可能很多人都遇到过,搜下解决方案,可能是最快的方法。今年发现效果其实并不好,反思之前的经历,这反而是弊大于利的做法。

  • 某个具体的点,可能知道答案了,但是缺乏体系的认识。
  • 虽然解决了眼下的问题,但是下次遇到其他有关的问题,依然束手无策。
  • 知道怎么做,但是不知道为什么。
  • 具体的点解决的越多,自己越是迷惑。
  • 搜到的这些答案也不一定正确。

这种从具体的点出发,进而掌握全部的方法,我把它称作“自底向上”。与之相反的则是“自顶向下”。对于一个特定的问题,先去仔细阅读一遍官方文档,把概念理清楚,搞明白“是什么”和“为什么”。然后再来考虑如何解决具体的问题,而不是直接搜答案。虽然看起来会非常的缓慢,但就我个人经验来说,总体效率上,这绝对比自底向上的方法快得多。开始阶段花的时间是n倍的,但是花这些时间所获得的知识,在解决其他的问题上是有巨大的帮助的。甚至,原来认为是问题的,都变成“显而易见”了。

借助于“自顶向下”的方法,我甚至搞明白了很多困扰已久的问题。所以我强烈推荐这种方法。

成长和进步,一定是痛苦的 。是的,就这么简单的道理,2018年才真正明白。成长的路上,一定会面临重重困难,如果一直抱着“学习使人快乐”这样的想法,那一定是不能坚持下去的。但是给自己no pain no gain的心理暗示之后,反而心态更加坦然。有人说,你看我就没遇到什么困难,机器学习都学会了。我想说的是,“学会”和“知道名词和概念”,是完全不同的两码事。不经历那些痛苦,没有一路上披荆斩棘,没有日日夜夜的奋斗,没有怀疑自我怀疑人生,很难说“学会了”。意识到这一点之后,在重重困难面前更容易坚持下去了。

书有必要看两遍 。成年人时间都有限,拿到书希望一遍看完就行了。简单的书,完全没问题,但是对于fp in scala这种虐心的书,一遍看完非常不现实。过程中非常容易陷入细节,而忽略了全局。起初可能是一两个问题无法解决,偶尔跳过也还好。但是问题越积越多,对于我这种有“完美主义”心态的人,后面的挫败感就非常强烈,这时候基本就会放弃了。更为致命的是,因为只着眼于细节,甚至都无法理解作者的意图,这些问题和整本书要解决的问题有什么关系?

后来我“妥协”了。问题解决不了没关系,就放在那里,继续看。先把作者的意图搞明白,为什么这里会有这样的问题?这一章的核心内容是什么?有了“全局观”之后,再看第二遍,解决那些绊脚石问题。效果比之前好太多,最起码的,终于可以看到书的最后一页了,这在之前简直就是不可能完成的任务。

今年看了几本非技术类的书。

原则。 这本书是2018年比较热门的书籍了,作者是桥水基金的Ray Dalio。他在书中总结了很多关于生活和工作的原则,这些原则都能给人以指引。但是对我来说,最受益的并不是书里的原则,而是授人以鱼不如授人以渔。它教会我一定要记录自己的“原则”,每个人的经历都不一样,只有自己最了解所面临的问题,也只有自己能给出最好的解决方法。

另外今年看了几本创业方面的书,创业维艰四步创业法。 本来是想对创业这件事再有个更进一步的了解,但是读完创业维艰,感觉基本就是被劝退了。当然这也是好事,作者起码把真实的一面表现出来了,而不是忽悠大家都去创业。

稀缺。 2018年上半年时间非常的紧张,每天都像打仗一样度过,所以就思考,我为什么会这么忙?刚好看到这本书,那就来读一下,看有没有破局的办法。全书看完,只记住一点:稀缺会让人的智力下降,产生“管窥”心态。这个可以很好的解释,为什么工作越忙越容易出bug。但是其他的详细内容已经记不清了,最后也没有给出具体的解决方法。

之前基本不看这类“畅销”书籍,因为总觉得这些书标榜的东西,是无法通过看书学会的。总不能说把四步创业法看完了,我就可以创业了吧?后来想想还是“兼听则明”,花一点时间看看也无妨。事实证明,帮助还是有的。另外需要特别注意的是,这类书的作者都有个非常牛逼的技巧,就是把一句非常简单的道理,前前后后重复说很多次,废话特别多,本来一页纸可以讲完的,非要弄成一个章节。所以在看这种书的时候,千万不要一字一句的仔细看,大体看一遍就行了。比如,对于原则这本书,我的建议是只看第二部分结尾和第三部分开头,这里有完整的原则列表。对于那些特别感兴趣的原则,可以翻到对应章节细读。第一部分是作者的自传,这部分基本没有废话,可以好好看看。

摄影

2018年对于摄影的认识发生了根本的变化。之前的我喜欢拍摄cityscape题材,总觉得这些才能体现摄影师的“能力”。一次偶然的机会看到几年前随手拍的工位的照片,桌面上乱七八糟,没有任何构图,光线也非常差。这张照片在当时我的眼里,一定是一张废片。但是今天看来,确实非常有价值的。过去的时光已经不在,看到这张照片,便回想起来当时的种种经历。

什么样的照片是有价值的?体现“能力”的城市风光照,不一定是有价值的。这样的照片今天可以拍,明天也可以拍,甚至若干年之后拍的更好,因为城市在不断的发展,风景必然会越来越好。风光照也未必能体现能力。可能运气好,碰到了好的天气,也可能时间上比较自由。

摄影的价值在于捕捉以后不可复现的瞬间。 我们去到国外旅游,随随便便拍的街道照片都会觉得非常好,因为这些地方是完全陌生的场景,以后再次回来拍摄的机会也非常少,所以这些照片更加珍贵。女儿一天天长大,每天都会有新的变化,把她的成长记录下来,这是非常有价值的。对于我们自己,“岁月是把猪饲料”,每天都在变老,把当下自己的状态记录下来,也是有价值的。

2018年的年度最佳照片,就是下面这两张。

PA064694

20190126-P1266973

新的开始

终于赶在春节回家之前把这篇博客写完,这大概是我有史以来写的最认真的一篇年度总结。对于2019年,内心其实有非常多的期待,但是我就不在这里立flag了。以免到2020年才能把2018年底许的2019年愿望实现。总之,2019年是一个全新的开始,希望在2019年能把心里的这些flag都实现。

新年快乐!

Posthaven to Hugo

前不久博客刚刚从wordpress迁移到Posthaven,在使用了两个月之后,还是从Posthaven流失了。

Posthaven的问题

起初没太注意文章的url,有一次写完发布之后,发现url居然是文章标题的拼音。对于英文内容来说,这样的url没问题,但是对中文来说,这样一大串不知所云的url,简直是个灾难。有个办法可以解决,就是发布的时候把期望的url作为文章标题,等发布之后再来把标题更新成中文。

Posthaven的页面引入了twitter和facebook的js,由于一些众所周知的原因,会导致博客无法顺利的打开。如果要去掉的话,需要修改主题。但是Posthaven的主题是用的liquid模版。修改的话有一定的门槛,至少要学会liquid。

类似的还有不少小问题,这些问题都有一些奇技淫巧可以解决。但是作为用户有没有必要这样折腾呢?如果还是要自己操心,那为什么不选择wordpress这些?

另外,Posthaven所标榜的“Last forever”或许只是个不切实际的幻想。一方面公司并不能保证永久运行下去。另一方面,万一哪天posthaven被屏蔽了,也就完蛋了。

需求很简单

我只需要一个minimal viable product:

  • 能够支持markdown,如果能原生支持org-mode最好了。如果不行的话,支持html也凑合,emacs可以很方便的把org-mode转成html。
  • 能够支持代码高亮,码农必备。
  • 不让用户操心,不需要做太多的定制,拿来就可以开始写。如果需要少量的折腾,那我至少希望这个折腾是值得的,经验是有其他的用武之地的。
  • 提供稳定的服务,页面打开速度有保证。

一直有个想法,既然这些都不能很好的满足需求,那为何不自己造个轮子?现在web framework都已经非常成熟了,实现起来应该也不会太难。org-mode的问题可以用scala写个parser解决。但是,自己造轮子要占用大量的时间。现阶段的时间这么紧张,把宝贵的时间花在这上面是不是值得?

那除了wordpress,还有什么选择?Jekyll, Hexo, Hugo。Jekyll的编译速度太慢,Hexo是nodejs的框架,学习成本略高,而且hexo的主题洋溢着一种qq空间的感觉。那就只有Hugo了。

Hugo也不完美

Hugo, Jekyll和Hexo这类博客最大的优点在于生成的是静态页面,如果博客部署的机器跪了,重新换台机器部署一下就行了,迁移起来非常方便。Hugo可以在本地渲染,而且支持live reload,写完保存文件在浏览器里就可以看到了。这一点是之前从未有过的体验。

虽然基本体验OK,但是Hugo也存在不少问题。

如果某篇文章太长,不希望在首页全部展示的时候,WordPress和Posthaven都支持插入Read More标签,这样在首页就可以只展示标签之前的部分。Hugo对于这个功能的支持,在markdown格式里面是完美的,如果用org-mode或者html,就比较令人蛋疼了。对于org-mode,文档里面写的是要用 #more ,但实际上还是要用markdown的方法。对于html,我是压根儿就没找到支持的方法。

Hugo的文档比较奇怪,给人的感觉是放着一些通俗易懂的说法不用,而是故意用了一些看起来更高深的词汇,但是对用户来说不够友好。比如taxomony,slug这些概念。

虽然Hugo支持org-mode,但是支持的并不够完善。很多标准的org-mode写法,都不能用。比如需要直接输出html,却不能用org-mode的 #+BEGIN_HTML#+END_HTML 。代码高亮需要使用hugo的short code,在org-mode里面一个简单的 #+BEGIN_SRC 不就可以搞定了么。

目前来看,hugo已经是能用的唯一方案了。就这样吧,后面如果实在忍不了的话,还是得自己造轮子。

业余摄影师的Olympus M.Zuiko 7-14mm F2.8 Pro使用体验

PB045277

本文是一篇迟到了大概3年的评测。刚入手7-14的时候,其实很想写一篇评测,但是总觉得自己都没怎么用过,也没拍出什么拿得出手的照片,没有资格来评论。现在3年过去了,我已经花了足够的时间去使用这枚镜头,可以称得上是重度用户了吧,那么今天就来谈一谈。

看镜头评测的读者最关心的是什么?从我的角度而言,应该是“如果我买了这枚镜头,能拍出什么样的照片?”。但是大多数都没有讲到这个读者真正想看的地方,仅仅是简单地阐述镜头的各项性能指标。要么就是各个光圈拍一张照片再放大看细节,为了寻找镜头的sweet spot。同时样片拍得也非常烂,让人怀疑这帮做评测的人到底会不会拍照。

Talk is cheap, show me the photo! 所以在这里,我尽量少说废话,多贴照片。

为什么选择7-14

刚开始接触摄影的时候,用的是RX100这款相机。一直沉迷于500px上的风光建筑类照片,但是RX100镜头广角端的等效焦距只有28mm,对风光题材实在无能为力,因此觉得必须入一个超广角了。

当时对各个厂家的系统都不太熟悉,只认得价格。我记得当时A7应该是刚发布没多久,机身的价格就已经非常感人,而且好像也没有什么牛逼的超广角。对比一圈下来,发现m43系统的价格非常适合我这种穷光蛋。刚好赶上了奥林巴斯7-14mm超广角镜头发布,看了很多的新闻和评测,都对这颗镜头赞赏有加。所以就和E-M5 Mark II一起入手了。

现在来看m43算是一个非常非常小众的选择了。再加上松下和徕卡适马成立了L卡口联盟,看起来好像松下老大哥要离M43远去了,只剩奥巴在坚守,m43要灭亡的声音也越来越响。但是,同时也有很多专业摄影师从full frame转到了M43阵营。

画质

作为业余摄影师,照片只是发发Flickr和instagram,对画质的要求不是非常严格。但是最基本的追求还是有的。从照片来看,7-14已经远远超出我的预期,让我拍到了很多非常满意的作品。

P5033274-2

↑ 深圳湾大桥的暮光。f/8.0的光圈,星芒很好看。

PB035212

↑ 建筑内景。

P9150989

↑ 夜景长曝光。

20180526-P5262907

↑ 深圳湾超级总部基地。

万里长征的第一步

之前的博客是自己搭建wordpress,大概维护了有六七年的时间,不过从14年开始基本不怎么写博客了。前段时间上去看,忽然发现被挂马了,点击链接有一定几率会跳转到一些垃圾网站。也尝试过去解决问题,但是主机都已经沦陷了,再怎么清理可能还是会有后门,因此干脆点把主机删掉了。

博客还是要继续。那就再搭一个wordpress吧,反正也轻车熟路了。买个阿里云的主机,再走个备案流程,这样国内也可以顺畅的访问了,看起来是个不错的方案。于是一边备案,一边搞wordpress。找主题,修改css,装乱七八糟的插件。备案的流程也有点麻烦。在这个过程中,兴趣被一点一点的被磨掉了。就是不想写东西。

博客,最重要的是内容,应该先考虑写什么怎么写的问题。wordpress让我分心的东西太多,精力无法集中在写博客这件事上。所以,即便有那么多的插件那么多的主题,也不想选择wordpress了。一个偶然的机会,看到了Sam Altman的博客,是托管在posthaven这个平台的。详细了解了一下发现正是我想要的,5$一个月,永久保存博客,承诺公司不会被出售。就这个了!只需要考虑一件事,那就是写,世界清净了很多。

为什么不选择公众号?在公众号上写东西,有两个非常强烈的感受。一是写出来的东西都不属于我,二是公众号只是微信体系内的一个应用,写出来的东西只是给微信用户看的。我想要的是一个独立的博客。还有另外一个原因,公众号文章里的图片,被压缩之后的质量实在太低了。而且不管作者上传的图片有多小,都再来压缩一次。如果说为了节省带宽考虑,我可以理解。但是为什么不把缩小图片的权利交给作者呢?尽管微信的压缩算法很牛逼,但这种不考虑作者感受的做法还是让人难以接受,尤其是对于喜欢摄影的我来说。

平台有了,接下来就看自己了,但愿能维持一个比较高的产量。不然又要回来打自己的脸了。

谈程序员的学习(二)

今天的主题是“专注”。

张无忌掉下悬崖之后,山谷里只有一本九阳真经,所以他也没得选择,只能把精力放在这上面。但是我们所处的世界不同于那个山谷,充满了各种“诱惑”,这段时间我对“九阳神功”确实比较关注,但是过几天我又听别人说“降龙十八掌”也很厉害,想尝试下。怎么办?

我们一般都认为,像张无忌在山谷里那样集中精力只做一件事情,效果一定是最好的。在短时间内,确实需要保持专注。比如一小时,一天,一周。如果不能集中精力在一件事情上,就会导致大脑频繁地进行“上下文切换”。今天我想学学scala的fastparse,但是又想写写博客,另外还想再继续看sedgewick的算法。最终结果是哪一件都做不好。

但是在长的时间范围上,反而不能太专注。从我的个人经验来看,学习效率最高的时候,往往是最开始接触一项技术的时候。因为面对的是一个全新的领域,自己会在好奇心的驱使下去学习,而不是自己逼着自己前进。

刚接触Haskell的时候,很多functional programming的概念都是第一次听说,就像是打开了通往新世界的大门,学习的欲望是非常强烈的。但是后来持续了两个月之后,慢慢地放弃了。起初看Learn you a haskell for great good这本书的时候,基本的概念还比较容易理解,但是越往后难度越大,再往后基本看不懂了。过了两年之后,看到了陈天的一些文章,重新燃起了对Haskell的热情。再去看Learn you a haskell for great good,原来看不懂的地方居然全明白了,有种大彻大悟的感觉。

在其他的领域上,也有过几次非常类似的经历。仔细想想,真的是自己的智商不够用吗?不,本质的问题不是Haskell太难,而是在第一次学习Haskell的后期,已经失去了对Haskell的热情,只是逼着自己去看书而已。第二次之所以能“大彻大悟”,完全是自己的兴趣使然。

不妨思考一下,养猪场的种猪,为什么每天都能保持高昂的战斗力?因为每天来的母猪都不同。适当的新鲜感,才能让自己持续输出高额的伤害。

“专注”的前提是自己有比较强烈的兴趣。在张无忌所处的环境下,中了寒毒,不练九阳神功就要挂了,保持专注当然是好的。对于我们现代人来说,如果已经不是发自内心地想继续下去的话,要么激励自己,重新点燃兴趣。要么就尽快的pivot,把精力放在其他更感兴趣的事情上。