对比的力量

本文地址:http://blog.hoppinglife.com/?p=24 

韩磊的演唱,简直是『欲扬先抑』的范本。

从『慢』开始,从『弱』开始,一点点的加快,变强,换音色,一点点撩拨你的情绪,当你试图抓住它的时候,又悄悄的逃开,回归平静,哪怕是第一遍副歌,留着余地,留着空间,浅尝辄止.

终于,你被撩拨的心痒难耐,满身的情绪只期待一个出口的时候。他轻轻的按下开关。足够了。

 

 

如何掌握观众,如何点燃观众,是一门值得好好学习的学问。

Mac OS X不是unix

本文地址:http://blog.hoppinglife.com/?p=19

警告:这是一篇高度个人化的文章,不适者请跳过。

这篇文章不是要探讨OS X的可用性或者设计优劣:尽管那个题目很热闹。我要讲的话是:『Mac OS X不是unix』。

从字面角度上,这句话不太正确:OS X通过了SUSv3,这使得它成为地球上不超过十个可以自称自己是『UNIX』的操作系统之一。其他的成员包括AIX, HP-UX, Solaris等等。

但是Linux和BSD都不是这个家族的成员,而它们加起来占了Unix服务器的绝大部分,所以让我略加修改APUE的名言:

On the other hand, if it does not look like a duck, does not walk like a duck, and does not quack like a duck, then it’s probably not a duck.

所以我们来看看Mac OS X是不是unix:Again,这无关某个动物或者鸭子是好还是坏,我只想说明某只特定的动物是不是鸭子。

一 内核

『Mac的底层是Darwin,Darwin是BSD』大概是最常听到的关于Mac和BSD的关系的描述。但事实上不是这回事。

事实上这个内核的核心还是mach:内存管理、进程管理都由mach负责,而mach不管从历史还是特征上都更像NT内核。部分Darwin kernel的源代码来自4.4BSD – 和Berkeley有关的最后一个版本。但是这部分代码运行在Mach的上层,几乎只负责提供SUS/POSIX子系统的API,而且被大规模的修改过. 除此以外,Darwin kernel拥有自己的Driver API和I/O Kit,(面向对象的),从这个角度上来说,与其说Darwin kernel像unix, 还不如说它像VMS/Windows。

二 API

让我从一个问题开始:『装着cygwin的Windows』是unix吗?

OS X的感觉与这个类似:你确实可以使用POSIX的API,但大多数OS X的GUI会基于闭源的cocoa,会使用特有的thread API,会使用launching API来运行daemon,会使用GCD来做消息处理,会使用不一样的动态链接库。

简而言之,除了使用了Posix的API,OS X和BSD/Linux并不share太多的共同点。你可能会使用一些POSIX的API,但你几乎同样必须使用Apple专有的API。

与其说你在开发unix软件,不如说你在开发OS X软件。

三 Look’n’Feel

OK,回到使用上,Mac OS X到底有多unix-y呢?

事实上,Apple在努力隐藏这个系统的unix部分:Apple有自己的路径规则和文件系统。用户使用Applescript来做自动化。时至今日,安装软件很多时候还是运行一个installer或者把文件copy到Application folder。App Store里找不到wget或者macvim,你可以清晰的区分出两类程序——一类装在/usr下面,一类装在/Applications里。

你的用户感受是『Mac OS』,不是『unix』。与其说Mac OS X像unix,不如说它更像Mac OS 9。

四 哲学

“Keep it simple and stupid”

“Do not reinvent the wheel”

“Write prog1rams that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.”

unix的最核心的价值之一,在于它提供的模式:充分利用已有的成果,给最终用户以选择的机会,系统高度透明和模块化,高度可配置。

Mac OS X不是这样的一个系统。Apple搭建了一个自有的平台,通过限制功能和封闭来达到稳定性,通过复杂的封装来达到可用性。macports和homebrew能够很好的反映这一点:你要么选择冗余(重新安装所有文件),要么选择匮乏(被系统工具的版本限制).

五 

如果从内核,API,操作方式到哲学,Mac OS X都更像Mac OS 9而非unix的话,为什么我们还要叫它unix呢?

我对Mac OS X没有什么意见——出于个人的偏爱,我不会用它,但我相信它是一个出色的系统。

但我不喜欢Apple用Unix当商标来推广Mac OS X,unix不仅仅是一个『好用的shell』而已,它的价值,也在于『类似的系统路径和配置方式』,更重要的,在于『高度透明和可配置』,在于『充分利用既有的社区成果而非重新发明轮子』。对这些哲学的坚持,是unix社区成功的要素之一。

但OS X是一个和unix社区从理念到实践都相差甚远的OS。它有着特有的操作方式和配置规则,有着比Windows还厚的封装,重新发明了比Ubuntu还多的轮子。

它只是碰巧能兼容一部分BSD程序而已。认为『Mac OS X有Unix认证所以是unix』和认为『Windows + cygwin是POSIX兼容的所以是unix』没有什么本质不同。就算猩猩和老鼠99%的基因相同,猩猩也不是老鼠。

你可以喜欢unix,也可以讨厌它,但是希望你喜欢或讨厌unix的原因,不是因为你喜欢或者讨厌Mac OS X。

Several Thoughts

本文地址:http://blog.hoppinglife.com/?p=13

最近有好几个小朋友跑来问我有关学习啊前途啊推荐导师方向啊的问题,我猜我的答案不是很让你们满意。正好,今天又看到一篇『ACM大牛太厉害怎么办』式的文章,有感而发,写一点我此刻的感触。个人意见,水平有限,仅供参考。

一 轨迹和距离

要讲的,大概就是乔布斯『dot』那个演讲的意思。你从来不知道自己的现在会以怎么样的方式影响未来。恩,这个话题很俗,但是在此时此刻,我希望我更早一些懂得这个道理。

我在大学里有几个领域不愿意碰:不喜欢数学,不喜欢Machine Learning,不喜欢并行编程。

结果是代数和概率没学好,Boss的一个很有趣的题目不敢接。前不久项目要用到基本的机器学习和MPI,翻出教材重看了好几天;课上讲到CUDA自己浅尝辄止,现在天天抱着Nvidia的资料啃。

专业课程的设置终究有它的原因,你永远都不知道,你不喜欢的那件事,在什么时候会挡住你的路。如果运气不好,说不定连是什么挡住了你的路都不知道。

二 游戏与现实

有一个很有名的段子,医学院的学生找老师去划重点,老师说,你打算跟将来的患者说,不好意思,这个病不是重点?

课堂、考试和大作业,终究是一种『游戏』。它不能太难以至于大多数人阵亡,它不能耗时太长以至于很多人饿死,它也不能太无趣,以至于大家觉得它很无聊。

但是教材那么厚,还有那么多参考书终究是有原因的,实践中的问题不会顾及你是否曾经对这个问题详加练习;不等式的难度是否超过了你算法课的习题;或者问题的规模是不是超出了你习惯的问题。

更何况,太多的问题书本上没有答案。C++书上,不太会讲到实践中tuple奇奇怪怪的用法或者是decay_copy对线程安全的意义,也不会讲到什么样的代码能内联什么样的代码不会被优化;算法课上,也不太会讨论B+树的节点插入的时候可以rebalance或者实践中B树的性能到底跟什么有关。

『考试内容』和『书本知识』天差地别,『书本内容』和『工程实践』又隔着鸿沟,想真正掌握一门学科,课堂讲义和教科书远远不够。

三 天赋与先发优势

最常听到的问题,是『成绩还行,编码不好怎么办』。

我就笑,因为我觉得,如果真的用心去『学』了相关的课而不是仅仅应付考试,编码应该有所提高才对:c++大作业让写链表的时候,有没有去翻翻std::list的实现?OS课上让写shell,有没有去翻翻类似的代码?做算法大作业的时候,有没有去查查工程实践中的代码是什么样的?做编译大作业的时候,有没有让自己的code尽量clean?学软工的时候,有没有仔细看看设计模式?

或许有人天生擅长coding,或许有人通过ACM的锻炼coding提高;但这绝非唯一的提高之途。作为一个工程师,对『先例』的熟悉和『自身经验』的累积,是远比天赋更宝贵的财富。

顺便说一句,在我ACM水平最高的时候,代码是变量乱飞作用域稀里糊涂的。很多ACMer编码水平高,是因为他们对待代码(和其他知识)比我认真。

四 结果与目的

别人看你的学生生涯,会有很多『评价因子』:成绩如何,奖学金和荣誉,科研,课外活动。加权平均一下,给你的学生生涯打个分数。

所以挺多小朋友从进大学开始,就开始奔着这个方向去努力:GPA,GT,进实验室。而当问起『你的兴趣是什么?』『你擅长什么?』的时候,往往很茫然:『其实我也没有什么特别的兴趣啦』。

但这些都是『结果』,不是『原因』。它们终究是衡量一个人的专业水平和综合素养的工具,而后者,才是大学应该给予你的东西。学数学也好,学编程也好,都是为了,当有一天用这些创造什么的机会摆在面前的时候,你可以把那份工作干得更漂亮,让自己更满意,幸运的话,惠及更多的人。

大学四年的意义,不仅仅是『换个敲门砖』,你可以做的多得多:认真寻找到一个自己擅长和感兴趣的领域;把基础知识认认真真学扎实;培养良好严谨的工程习惯;积累一些初步的经验。做好这些,那些你所在意的『敲门砖』,自然会水到渠成。

相信我,你今后不会有太多的机会做这些事的。

 

 

 

交互设计这件事

本文地址:http://blog.hoppinglife.com/?p=9

最近有两个客户端让我很闹心。

Android上的Twitter客户端Carbon更新了,新的Carbon有一个很漂亮的界面。(图片摘自Google Play)

问题?——我找不到我想要的功能在哪。

按Menu键没有反应,按返回键会退出程序,按那个加号是发新推。设定呢?帮助呢?为什么点twitter里的链接没有反应?

经过一段时间的研究,我发现打开菜单要点右下角你自己的头像——是的,那个加号和右边的头像不是一个按钮。是的,想要搜索、设定或者查看教程(教程藏在设定里面,如果你能找到教程,基本上你已经会用这个app了),你得猛击自己的头部——我的头很圆吗?和搜索功能有什么关系?

想要查看twitter的List,从边缘的右向左滑,但是要小心,如果你从中间滑,那你会来到conversation页面。用两个指头向上滑会跳到最新的tweet,但是要小心,如果你不小心用两个指头点中了一条twitter,那你会触发retweet功能。想要点击twitter里面的人名和链接?你要先点一下twitter,但不要点最左边发推人的图片——那会访问那个人的profile。——要想看到全部的对话,你要再点击一个按钮。

另外一个类似的应用是BeyondPod – 这是个podcast播放软件。在这个软件升级了新的版本之后我有两周都找不到怎么调整播放进度——没有提示,没有按钮;直到今天我不小心滑动了一下,发现『Now Playing』页面藏在播放列表右边。

这些软件坚定了我的判断——今天的app设计者,越来越把『酷』看得比『易用』来得重要。手势的滥用,就是最明显的例子。

其实,在我看来,今天的『手势』,其实和『命令行』没有什么不同:

-在GNU Screen的界面下,按<C-a><C-n>可以切换到下一个窗口
– 在Carbon主页的边缘从右向左滑动,可以调出list功能
-在FreeBSD下,ps aux会列出所有进程,包括它们是由谁调用的

有很大的区别吗?手势滑动看上去比命令行来得简单,但是它们同样要求用户记忆——哪个屏幕,哪个功能应该怎么调用。区别是,我愿意花时间学习shell来工作,我不想花时间学习怎么快速发推。而且在命令行下,我起码还有man page和–help可以救急。

我至今还记得第一次在展会上看到Windows 95——当时7岁的我只花了60s找到『扫雷』。除了『好看』,GUI的最大优点在于『易用』。这就是我们为什么愿意忍受繁多的菜单和按钮——当我需要一个功能的时候,我不用查阅500页的manpage就能找到它。

今天的交互设计师似乎早就忘了这件事——他们喜欢『最小化』和『直觉式』的设计,换个说法,他们喜欢把所有界面的功能都藏起来,让用户用第六感来找到它们。不幸的是,我的第六感和它们从来步调都没一致过。拜托,我的第六感有个名字,叫做Android Design

最后,对于有耐心看到这里的朋友,弱弱的问一句,Spotify新版里,怎么随机播放一个歌手所有的歌曲?

场外因素

本文地址:http://blog.hoppinglife.com/?p=4

(新网站缓慢建设中,尚无具体时间表。)

想了很久第一篇新Blog要写什么,现在想想就从天天在用的软件说起吧。

和很多同龄人一样,我开始接触编程的时候使用的是Turbo/Free Pascal/Lazarus的IDE, 后来转向C的时候用Dev C++/Code::Blocks, 接触Linux之后开始使用Emacs,用过一段时间的Eclipse写C/C++/Python/Java, 再后来开始长期使用vim/IDEA进行开发 – Java/前端代码用IDEA写,后端代码用vim写。

Coder总会不可避免的陷入圣战的泥潭 。 一开始是vim vs Emacs vs VS, 后来是Eclipse vs IDEA,再后来是vim vs sublime text, 总之有coder的地方就有江湖,有江湖的地方就有圣战。——这还只是文本编辑器。

不知道有没有像我一样的人,曾经觉得*nix下面没有一个出色的C/C++ IDE有那么一点奇怪(虽然Windows下大概也Visual Studio+Visual Assist X还活的比较好)。——几年之前最流行的组合包括vim/omni-complete和emacs/CEDET,用起来多少都有点奇怪,远远没有VS初上手来得正常。

大家似乎都这么想: 平均每3天我就会在不同场合看到论证Vim设计得很糟糕的文章。——反人类的设计,三十年前的键盘映射,糟糕的插件管理和界面,只是用来装X, 快点用acme/textmate/sublime什么的代替它吧。

但是大家还是在用vim/Emacs:如果有人问我做Linux下的C/C++开发用什么IDE, 我还是会说vim/emacs,十年之前是这样,十年之后还是这样。甚至今天的我,会费力把每个我会写字的地方都改成vim key-binding。

是的,我知道vim是很糟糕的设计,我知道配置它很麻烦(实际上有了vundle/janus/spf13之后并不复杂),我知道它的语法识别并不出色,但我还是会用vim, 哪怕我要专门写个脚本来生成我的.vimrc.

因为这个世界上,『最优秀产品』评选,有很多『场外因素』。

  • 通用
    有机器的地方就有vim——不管windows/Linux/BSD,不管是server还是树莓派,不管是android还是ios, 我都可以轻松的找到一个vim(至少是vi)来用。更重要的是,让这些vim长得用着都一样,并不花太多力气。
  • 社区大小
    成百上千的coder这么写代码——不管是配置、工具链都已经非常成熟了。毫不夸张的说,只要你想到的idea, 就有人或多或少的实现在vim里。每当想做一件什么事的时候,搜搜vim tips wiki就找到解决方法了:庞大的社区,能够相当程度的减低学习的难度,也能够轻易的让你体会到社区的最新成果。
  • 路径依赖
    是的,当你已经适应了一种工作方式了之后,你会懒得更改到另一种工作方式。
    毕竟,在ssh下工作,选择几乎只有vim/Emacs.
  • 免费/轻量
    是的,不用支付额外的费用,可以直接在ssh上工作,节省屏幕空间——大家都挺穷的。
  • It just works.
    大家已经这样写代码写了很多年了,至少说明它没有大问题,何必花精力改它——发掘一个更好用的toolchain的时间,很可能超出你的想象。

这并不是说vim/Emacs不优秀——实际上它们优秀到超乎想象,那部分内容和本文无关;但我相信如果今天再去设计vim/Emacs, 肯定不会长成它们现在这样子。但是这无关紧要。那些『场外因素』,已经或者弥补,或者让我们忽略了它们的缺点;也让我们离不开这些老家伙的『特性』。

 

同样的道理也适用于C/C++/Java/Unix/make/tex:如果今天重新设计这些东西,它们很可能会长成Go/Rust/D/Dart/Plan9/Scon/texmacs的样子。但是绝大多数情况下,这种关公战秦琼式的比较毫无意义:后者的优点和这些『场外因素』比起来,并不重要。更何况,让前者变得方便使用,比让后者变得成熟,要简单太多。

所以我从来不是很买『那个设计不好所以应该换』的帐。用户从来不傻:站在巨人的肩膀上或许不难,但是真正成为巨人远没有那么简单。