行者无疆 始于足下 - 行走,思考,在路上

Announcing oh-my-emacs v0.1

去年偷闲的时候,挖了好多大坑(这里这里这里),怎奈挖坑容易填坑难……客观原因自然是“认真的写作有如雕刻”云云,主观上嘛,“懒”大概是逃不脱的一个字吧。

Wait,是谁说过,“懒惰是程序员的美德”来着。秉承这种美德,耗了将近两个月的业余时间,尝试了不下50个el-get package,并且认真读了不下10个package的manual,遂成 oh-my-emacs.

一切缘起于两个月前的某一天,我忽然心血来潮,想要整理下那一坨"just works"的.emacd.d。我几乎尝试了所有github上比较流行的.emacs.d,但是没有一个满足我的需求。“因为所以,科学道理”, Reinventing the wheelNot invented here 大概是每个程序员必修的一课吧。索性不管那么多了,代码写的不好,又不输房子不输地,坑 挖的不好,大不了留着自己用就是。

Oh-my-emacs着重解决的问题是(引用自oh-my-emacs的README):

  • Better default settings with various eye candy, powerline, scrollbar, color-theme, fonts, etc.
  • Adopt el-get as the default package manager for Emacs, instead of the default builtin package.el, say goodbay to ./configure; make; make install and explicitly mananully management of load-path. el-get also provides automatic documentation management, customizable user's recipe support, etc.
  • Self-adapted, only install necessary packages when it satisfy the prerequisities. You need to install clang for auto-complete-clang, for example.
  • Modular, only load necessary packages as you need.
  • Literate, each package have comprehensive documentation or even a tiny tutorial with it, together with necessary web links. Say goodbye to old, out-dated emacs lisp code from Google.
  • Work as expected, completion every where when possible, semantic code completion through auto-complete with various ac backend, helm for minibuffer completion, etc.
  • Full-blown, oh-my-emacs is not another starter kit, it is hacker kit.

这其中,补全、文档、自适应性,是我特别看重的三点。补全自不必说,作为上古大牛也 许是不需要补全的,但是对于我这样21st Century成长起来、尝试过Visual Studio强大补全甜头的程序员来讲,补全是最为迫切的需求。而Emacs/Vim作为General Purpose Editor, 其最大的使用不便就是没有代码的语义补全(semantic completion)。Emacs有一个内置的 Semantic, 来源于Emacs社区鼎鼎大名,目标远大的CEDET, 但是Semantic的使用和配置 都很复杂(参考emacser.com的文章),而且很慢,有时会让Emacs卡住。究其原因,我认为 Semantic 的思路是不对的。用性能本就不怎么好的Elisp去实现复杂如C++这类语言的 Parser,其本身就是浩大的工作量。正确的思路是,对于不同的语言,依赖于不同的 backend,然后用Elisp写相应补全的interface。所以我认为, auto-complete 的思路是正确的。oh-my-emacs利用已有的各种auto-complete的backend(如 ac-slime, auto-complete-clang 等)基本上实现了对C/C++,Python,ELisp/Common Lisp/Clojure的语义补全。

第二点是文档,Emacs的世界从来不会缺乏选择, el-get-list-packages ,2500个 package,其中有很多package要么是已经过时,要么是年久失修,要么是语焉不详,看上去 一片繁华的Emacs世界,实则荆棘密布。如果你没有一点Elisp的功底,想开箱即用,那几乎是不可能的。单拿Python来说,Emacs和Python社区就有两套不同的 python.el ,这给很多Python和Emacs的初学者造成了困惑。Google: Python Emacs,其首页的几套解决方案,采用的是不同的 python.el ……你说对于一个好容易学会翻墙,开始习惯用Google搜索技术文档的计算机初学者而言,看完这些文章,不晕菜才怪呢。稍微复杂一些的配置,比如 TeXLive,在比如Common Lisp的各种实现和SLIME,想要得到一个比较舒适的环境,不但要配置好Emacs,还要配置好系统环境,这又是一大难题。oh-my-emacs借助org-mode Babel, 采用Literate的方式1, 将文档和代码写在一起,在文档中尽量给出每个模块所需要的系 统环境;对于有多个选择的情况,文档中尽量给出为什么选用package A而不是package B的理由和权衡过程。有一部分文档甚至可以当作Tutorial来看。Literate方式最大的好处是保 持文档和代码的同步,这样,oh-my-emacs即可以用作是“开箱即用”的.emacs.d,也可以当作是手把手的Emacs配置教程 (统计下来,oh-my-emacs中文档和代码的LOC 比例约为3:1左 右)。另外,操作系统的环境千差万别2, 因此oh-my-emacs基本上在每个相关模块的文档里面都指明了使用这个模块所需的系统环境,这也可以看做是我为了填去年的坑所做的一点努力吧。

第三点是自适应性。这又是一个很宽泛的话题。什么叫自适应性?是支持多个操作系统吗? 不是的,至少我没有打算让oh-my-emacs很好的支持Windows,一方面是因为Windows没有一个好的类似于apt-get这种类型的package manager3,oh-my-emacs依赖的很多底层软件如ssh,gcc/clang,TeXLive等在Windows上配置起来都很麻烦,远不如 apt-get/yum/pacman/homebrew这种一条命令来的方便。我这里讲的自适应性,主要包括:

  • 采用el-get, 自动化管理load-path,以及info文档等,say goodbay to git submodule
  • 如果系统环境不满足某个package的要求,就不要安装这个package,免得装完了不能用。 比如 auto-complete-clang 依赖于 clang, 如果系统中没有安装clang,那么oh-my-emacs在启动的时候就不会安装 auto-complete-clang。反之,如果你意识到这个问题并安装了clang,那么可要重启Emacs, auto-complete-clang就应该可用了。
  • 尽量借助工具和代码获取相关配置,而不是在代码中写死。比如,oh-my-emacs大量使用Elisp中的 executable-find ,这需要依赖于操作系统的package manager设置好相关的 $PATH , 这样带来的好处就是oh-my-emacs能够无缝的适应很多环境。
    • 比如 AUCTeX需要PDF阅读器作为LaTeX文档的Viewer, oh-my-emacs采取的策略是优先采用 Okular, 其次是 Evince, 如果操作系统上即没有装Okular也没有装Evince, 那么oh-my-emacs会fallback到 xdg-open, 这样可以用可移植的代码获得最大限度的灵活性和自适应性[4]。
    • 再比如 SLIME 支持多种Common Lisp Implementation, oh-my-emacs采取的策略是同时支持 SBCL/Clozure CL/CLisp ,也就是说,只要你安装了SBCL/Clozure CL/CLisp其中的一个,oh-my-emacs的Common Lisp设置就应该是可以工作的。
    • 针对auto-complete-clang, oh-my-emacs可以利用 pkg-config 检测并设置正确的 ac-clang-flags , 可以对系统中可用的任意C/C++ lib提供语义补全。比如,你可 以用 M-x ome-pkg-config-enable-clang-flag "QtGui" RET 来获得QtGui库的补全 支持,效果可以参考这里

Oh-my-emacs目前已经包含了对C/C++/Python/Common Lisp/Clojure的支持,基本上都提供了较好的语义补全。其他方面,设置了更友好的字体,powerline,color-theme。启用了 一些比较好的内置mode,诸如recentf/savespace/uniquify。对\LaTeX编辑提供了完整的支持,默认采用XeTeX。

Oh-my-emacs的名字来源于 oh-my-zsh, 用意嘛,自然是希望能将oh-my-emacs打造成oh-my-zsh那样。大话止于此,看行动。

最后放张图,更多美照在 这里 。Enjoy emacs, and, your life.

oh-my-emacs

--

Footnotes:

4 这个PDF阅读器的例子主要是在Linux下面测试的,我手头没有Mac的环境,so, patches are always welcome.

1 Literate programming 的 概念来源于祖师爷 Donald Knuth。没记错的话,大名鼎鼎的 \TeX 早期也是用literate的 方式写成的。 Org-babel提供了所谓的"active code in Org-mode",还有专门的Paper论 述Org-babel的workflow。 oh-my-emacs这方面的灵感主要来自于 emacs24-starter-kit

2 也许正是如此,puppet/chef这类工具才会大行其道吧。

3 chocolatey 也许是个不错的选择,但是我没有用过。

 

OpenStack开发杂谈

去年12月份的时候我曾经给自己写了一份"OpenStack开发基础知识"书单,贴在墙上,书单大概如下:

读书进度=书名中划线部分的长度/书名的长度。之所以有这份书单,是因为在前面几个月的开发中,我发现自己的基础知识薄弱,远远不能满足OpenStack开发的需要。虽然自己已经能够按照公司的基本要求,照猫画虎地开发出几个能用的所谓Feature,但是我内心明白,自己的能力上尚不足以透彻理解OpenStack代码1

我认为自己还算是一个比较努力的人,并且自认为对自己目前所从事的行业还是有着满心的热爱和期待,期待自己能做出一些有用的产品,留下一些真正有用的能改善人们生活的东西。这个宏大的愿望映射到眼前,就是努力使自己成为一个合格的Full-Stack类型的Web开发工程师。而进一步将眼前目标付诸行动,就是上面的书单了。我原本定的时间是3-5个月左右,不过现在看来还是太狂妄太浮躁了。客观上是自己要工作,时间不完全都是自己的;主观上则是自己“深度优先,随性而为”的阅读习惯常常会不自主的打乱原本订好的读书计划。比方说我在读"Pro Python"的时候为了搞清楚细节会去读"Python源码剖析",会去尝试理解Python的整个历史;在读"HTTP"的时候为了理解ReST,会去读"REST in Practice"; 而我在尝试理解Python TDD的时候会把Ruby中关于Cubumber的书加入阅读计划。这或许不是一个良好的阅读习惯,但这能保持我的兴趣,这就够了。

我不是一个Top的工程师,至少目前不是——Top的工程师不会像我一样还在费力的学习理解ReST/TDD这些概念性的东西。我知道Top的工程师在哪里 2。这类人天赋异禀,并且在很早的时候就接触计算机。在你还在骑着自行车围着院子绕圈的时候他们已经开始理解算法和数据结构,在你刚刚写出"hello world"的时候他们已经能写出成型的软件作品,在你毕业之际为找工作焦头烂额的时候,他们已经受过了1万小时的训练,有更好的机会和最聪明的人合作更快的提高自己。这个博客基本上忠实记录了我正式开始认真学习计算机的全部历程。四年来我几乎做过各种各样的东西,Windows手机开发,Java SSH(已经忘光光),OpenGL程序,Hadoop,Python/FFmpeg写的转码系统等等,很杂,也很浅。但我一直坚持一个方向,就是拥抱开源,先是尝试学习基础知识,用好Linux/Emacs这类基本工具,毕业工作后开始去尝试读一些开源代码,提一些无关痛痒的patch试图接近开源,这一年来又开始尝试理解OpenStack,并真正的提交了一些patch。我不敢评价OpenStack的设计是否优秀,事实上我还没有这个能力去完全理解它,更妄论评价了。但是OpenStack的开发确实让我学到了很多东西,我开始理解了TDD,开始逐理解了ReST和Web Service,开始逐渐理解作为工程语言而不是脚本语言的Python,开始理解Message Queue。而我也通过自己的努力,让基于jenkins/gerrit的自动化测试部署的全套流程在公司运转了起来。

两年前信心满满刚来北京的时候,我从未想过自己会那么快的离开百度3,一年前开始寻找新的工作机会的时候,我完全没有听过OpenStack这个词。当初一心坚持离开学校是为了远离校园里学习的束缚,现在走向工作岗位又会感慨感叹时间的宝贵和校园里相对的自由。说白了,我是一个贪心的实用主义者,胸无大志,从来不会想五年以后的事情,学校里面不想听无聊的课程,就天南海北山山水水的疯跑,哪怕一学期挂科五门依然无所畏惧不懂屈服;工作以后顶撞上司就来个偷得浮生半年闲,躲进小楼成一统,管他春夏与秋冬,云卷云舒花开花落——但为了生活还是要出来找工作。

貌似扯的有些远了……最后回到本文的正题吧,OpenStack的开发。上个星期做了两个东西,第一是做了个OpenStack代码的国内镜像,方便教育网内学生党4,地址是:

第二是基于Vagrant做了个OpenStack的开发环境,地址是:

好了,吹牛到此结束,各位好梦晚安。

--

Footnotes:

1 比如我至今依旧没完彻底理解OpenStack中基于sqlalchemy ORM的数据模型,基于iptable/openvswitch等的底层网络原理,更妄想理解kvm/xen/内核这类CS工程领域真正“高富帅”的东西了。事实上,如果没有扎实的数据库/网络/操作系统知识,要彻底理解这些东西是很难的。

2 比如这里这里这里

3 也从未想到过自己的一篇文章能引起那么大的争议。

4 顺便吐槽下北大的校园网,30元/80小时,50元/160小时,90元不限时包月,超时流量1元/MB,这价格都快赶上北京正常的联通宽带了。而且速度那么慢(github clone 20k/s),北京联通现在可是号称20M光纤入户的。这就是世界一流大学的校园网,可笑。

 

轻松一刻:电影条形码转换脚本

大概是从去年年初开始认真的写作。怎奈认真的写作有如雕刻,每次写作少则四五个小时,多则十几个小时,极耗体力,因此再不敢轻易提笔。两周前的一篇文章,更是在机缘巧合之下将鄙人推向了舆论的风口浪尖,至今想起来依然心有余悸。写的人累,想必读的人应该也不会太轻松。值此新春佳节,特奉上一篇“技术小品文”,奢望读者百忙之中施舍一笑^~

想象一下,如果把一整部电影压缩成一张图片,那会是怎样壮观的场景?有点迫不急待?看看这里,梯子在这里

是不是想动手尝试下了?可是有这样的软件吗?我没找到。于是唯一的办法就是自己动手,丰衣足食了。代码在这里,依赖Linux/ffmpeg/bc/graphicsmagick。运行过程中需要保证5G以上的可用磁盘空间。转换耗时约30分钟,视电影时长而定。

#!/usr/bin/env bash

################################################################################
# Usage:    A script to convert a movie to a movebarcode
# Author:   Xiao Hanyu
# Depends:
#   ffmpeg:     get basic info of a movie and convert it to a series of images
#   graphicsmagick:
#               convert, mogrify, blur images
#   bc:         shell calculator
################################################################################

function get_duration
{
    ## [0-9]{2}:[0-9]{2}:[0-9]{2}(|\.[0-9]{1,2}) matches:
    ##      hh:mm:ss.ms
    ##      hh:mm:ss
    duration=$(ffmpeg -i $1 2>&1 | grep 'Duration' | grep -E -o "[0-9]{2}:[0-9]{2}:[0-9]{2}(|\.[0-9]{1,2})")
    duration_h=$(echo $duration | awk -F: '{print $1}')
    duration_m=$(echo $duration | awk -F: '{print $2}')
    duration_s=$(echo $duration | awk -F: '{print $3}')
    movie_seconds=$(echo "$duration_h * 3600 + $duration_m * 60 + $duration_s" | bc)
}

function get_fps
{
    fps=$(ffmpeg -i $1 2>&1 | grep -E -o "[0-9]{2}\.[0-9]{2}\ fps" | grep -E -o "[0-9]{2}\.[0-9]{2}")
}

movie=$1

get_fps $movie
get_duration $movie

## use multi-cores of cpu to improve the speed of ffmpeg, see ffmpeg man page
cpu_cores=$(cat /proc/cpuinfo | grep processor | wc -l)

time ffmpeg -i $1 -r 1 -threads $cpu_cores image%d.png
time gm mogrify -resize 0.5%x100% *png
time gm convert $(for i in `seq 1 $movie_seconds`; do ls -l image$i.png; done | awk '{print $9}') +append result1.png
time gm convert result1.png -blur 50 result2.png

# resize result2.png with a proper size
# I set new width to 2000, while keep the height intact
new_width=2000
new_geometry=$(gm identify  result2.png | awk '{print $3}' | awk -F+ '{print $1}' | sed 's/[0-9]*x/2000x/g' | sed 's/$/!/g')
gm convert -resize $new_geometry result2.png result3.png

rm image*png

if [ -e $(which xdg-open) ]; then
    xdg-open result3.png
fi

代码逻辑很少,先是通过ffmpeg进行截图,然后用graphicsmagick进行图片的接合、缩放和模糊处理,最后清扫战场,删除一些临时文件,就这么简单。最后,奉上《迁徙的鸟》和《阿甘正传》的条形码,博君一笑。
迁徙的鸟_条形码

阿甘正传_条形码

慎言多思

世界很小,互联网很大。昨夜随手写的一篇文章,不知受到了哪位仁兄的抬爱,被转到了百度运维的Hi群里,搞得我险些被请去“喝茶”……半夜5点发的文章,早晨9点左右,由于豆瓣九点的推荐,访问量开始突增,到了正午,豆瓣九点上已经有了近五十条推荐……而我的个人豆瓣“粉丝”也激增了20+(增幅达20%),博客也多了很多订阅者。更奇怪的是,这篇文章到了下午5点左右的时间,豆瓣九点上的链接已经莫名失效了1。我又尝试去微博上搜索了下,只搜到了3-4条,最下面是“根据相关法律法规和政策,部分搜索结果未予显示。”

从各种渠道收集的反馈,多数人的看法是诸如“文章比较犀利”,“有同感”之类,还有一位仁兄说这是“loser的文章,看看即可”,一位与我素未谋面的仁兄说“我知道这位刺头是谁……淘宝有怎样怎样的问题……腾讯有怎样怎样的问题……”,还有的说“文章里有个人情绪,但也有原因分析,只是分析的不够深入”等等。午饭后一位百度的朋友QQ上告诉我说“你的文章火了,有人转到百度运维官方群了”,我心想“完了完了,这下没准要被请去喝茶了……”,然后又接到了几个朋友的电话,跟我说明下说文章的内容有不实之处和个人情绪在,我说我会再做斟酌,酌情修改。

文章大概7000字,写了8个小时左右。最开始只是睡不着觉,然后就琢磨着想写一写关于狼性的看法,后来越写越多,也就不自主的加入了一些个人的情绪在里面。”不识庐山真面目,只缘身在此山中“,我只是一个小小的OP,可能看不到那么高,也看不到那么远,因此文章的各种内容观点均出自个人,与别人无关,我会为我的言论负责。

首先我诚恳地向kain同志道歉。因为我的疏忽对你做出了错误的评价。坦白地讲,我对kain同志并没有深入的了解,对北大青鸟也没有深入的了解,甚至带有很深的下意识的个人偏见。我以前并不知道kain同志并非科班出身而是化学专业出身,靠着自己的兴趣和努力走上了计算机这条路,并且通过自己的努力进入了百度,我应该对此表示恭贺。我欣赏有想法、有主见、有自己个人兴趣并按照自己计划不断提高自身的人。事实上我觉的我也是这样的人2。碰巧我在大学之前也是学习化学竞赛的,几乎不会使用电脑,大学前两年忙于户外社团,对计算机的系统学习是大三以后的事情。你说的对,一个人的出身并不能代表什么,而别人的偏见在短时间内又难于消解,总会无意间就碰上有心无心看扁你的人。对此我在此表示诚恳的抱歉,也感谢你让我对我自身的缺陷有了进一步的认知。同时我也觉得,无论别人怎么看轻自己评价自己,自己才是自己最后的裁判。一个心怀优秀信念并不断努力的自己,即便碰上一些挫折,误解,只要自己对自己怀有信心,那么别人的评价再多,也“尽可当他是清风拂山,明月映江,虽能加于我身,却不能有丝毫损伤。”

其次,关于Hadoop开源方面,由于我并不是Hadoop的RD,因此关于“几乎没有对Hadoop社区的开源回馈”这句话是不准确的。Hadoop的一个C++框架HCE是百度自己独立开发的,测试显示其效率高于传统的Hadoop程序,并且已经开源。Hadoop之外,其他的开源项目,我了解的有一个UEditor,百度前端团队有一些开源的项目,参考https://github.com/BaiduFE,剩下的我所知有限。

以上两点我已经在原有文章中做了更正。至于各条怪现状,由于上篇文章掺杂着个人的情感和经历在内,因此难免有“吐糟”,“百度黑”的嫌疑。回过头来我也想过,如果将我个人的经历和情感去掉,那么文章本身是否会变得更客观理性更具有参考价值一些。挑几条再简单阐述下吧。

关于洗脑,我认为这个也没有什么不对,因为这是员工熟悉公司文化、制度、理念的一个很好的手段。但是有两点我认为需要改进,一是学习方式上,可以讨论,但是我认为“毛主席语录“式的学习方式是不可取的,应该要允许部分”异类“的存在,你倡导“快速迭代,越变越美”,但也要允许“慢工出细活”,“一炮打响”的存在;二是要与时俱进,我记得书里面好像有关于有啊的故事,但是有啊后来失败了,却没有一个地方对有啊的失败做个总结和反思,这就难免会让人对公司所灌输的理念产生怀疑。

关于开源,这方面我强烈建议百度拥抱开源,不要死守着老观念不放。没有自上而下的推动,没有公司气氛的烘托,光靠几个有心的底层RD敲敲打打是成不了大气候的。至于为什么要拥抱开源,这个就不再多做讨论了。

关于KPI驱动,这点尤其需要改变。我坚持认为“上下异心”是百度当前最大的发展阻力。但是这种局面的改变需要自上而下,而不是自下而上。要让底层技术人员放开手脚去做、去闯、去创新,也要让中层的管理者们转变KPI报表为王的管理策略,真真正正的去抓一些实际的东西。作为一个一流的互联网公司,用wiki的方式手工维护记录可用机器列表,用人肉的方式每周去copy/paste数据到固定的模板里生成报表周报,这种行为可以视为科技公司的一种耻辱。要大力推行工具文化,自动化不是一句口号,是一点一滴。

关于会议沟通,这个大概是大公司的通病了。我认为很大一部分原因还是工具不到位,自动化的东西做得不够好,所以不得不通过人力反复沟通确认来完成事情。在Hadoop组搞机器预算的时候,每次都是人肉Excel,反复打电话确认。而这些不必要的沟通很大程度上是可以通过开发一个成熟的预算系统来解决的。后来也确实有人做出了预算系统的原型,Lisp写的,我接手的时候还修复了几个bug,可惜这么个原型系统毕竟只是个人的业余工作,加上沟通电话实在太多,没有精力完善,上面也不重视,最后也就不了了之了。

关于自由上班,这个就仁者见仁智者见智了。中国很多企业的通病就是员工一迟到就扣钱批评,但员工加班晚归却视而不见。百度当然没有这样,并且百度的工作时间,以及加班补贴和调休制度都还算比较完善。所以归根结底还是要减少不必要的会议沟通,提高白天的工作效率。

关于Geek,我不认为用Linux/Mac就是Geek的一种表现,但是作为一个互联网公司,其入职预装的系统依旧是10年前的Windows XP,难免很让某些人(诸如我这样的)大倒胃口。Geek不是一个操作系统,也不是一个手机一个平板,Geek更多的是一种对待工作的态度——倾向于用机器来代替人,DRY,对代码的洁癖,对工作效率的追求,对文档排版这类美感细节的敏感。不要小看这类细节,细节代表着专业性,比如说技术博客一个最基本的要求就是排版规范,简洁,同时要有合理的代码高亮。但是百度很多“官方”的技术博客并没有做到基本的整洁规范,比如这里这里这里。多余的话不多说,如果你认为这些所谓文档排版,代码洁癖无所谓的话,我也无话可说。

关于有啊。其实这个事情我了解的并不多,我入职的时候有啊基本上已经散了。但是正因为了解不多所以我才在这里提出,因为我从未看到过公司层面上对自己做的任何失败的产品有过任何的反思。还是那句话,员工犯错可以批评可以扣KPI,但是如果公司犯错了呢?如果由于高管的失误造成公司的损失和员工职业发展的挫折,又该如何呢?再进一步,如果Robin犯错了呢?我觉得百度的高管应该认真反思下这个事情,要勇于面对自己的不足,敢于拉下面子做自我批评,不要总是高高在上,犯了错都是员工的,做好都是自己的。

最后的最后,还是再允许我多絮叨几句吧。首先我不是一个百度黑,我在百度长了很多见识,学到了很多书本上无法学到的东西,也有幸和部分真正的牛人有过一面之缘,管中窥豹,了解下他们的工作,给自己树立个目标。我所指出的这些问题,我相信至少还是有一部分是许多百度同学的共识,只是迫于各种各样的原因无法像我这种离职的员工更加方便的开口讲述。我希望百度能够更多地倾听底层技术人员的声音,不要总是脱离群众去制定自己辉煌的战略路线。我希望百度发展的更好,但我也明白知易行难的道理,作为曾经的百度人,我所能做的也只有这些了。其次是每个公司都或多或少有自己的不足,百度如此,腾讯如此,淘宝也是如此,毕竟时间并无完美之物,而人生之不如意又十之八九,我觉得多数情况下可以变通,但也不要被生活磨平了棱角。其三,我想说的是,个人的职业发展,8小时之外的功夫也许有时比8小时之内的功夫更加重要。所以我也提醒各位和我一样初入职场的同学,与其天天扑在工作上,能否多花些精力在工作外,然后反过来提升工作的效率,从而给自己的工作、生活和学习都留下更多的自由空间呢?

至于我个人的经历结果,我并没有太多的遗憾甚至抱怨,或许是我运气不好,又或许是我能力真的有限而我没有意识到。事情已经过去,多说无益,只求各位看官也千万不要把我看成一个高级文艺的“百度黑”。感谢一直关心我的朋友,我现在过得很好,住在北大附近,离未名湖五分钟的路程;工作不是太忙,用Linux+Emacs+Git+Python做着我喜欢做的事情,OpenStack教给了我很多;每天晚上归家奢侈地享受4个小时的阅读(悦读);间或周末去北大看场电影;赚得钱够家用,也能随心所欲的买书;沉浸在lambda的程序世界里;有个关心我的妞在身边。总之,一切都很好。

谨以此文,纪念我那九个月“不合格”的百度岁月。

--

Footnotes:

1 以前也出现过这样的情况,这应该是九点的bug,一篇文章如果被九点抓取过来后又修改过,那么九点的链接就会失效。但是这次文章发表之后直到工作下班我没有对文章本身做过任何修改,所以很奇怪……

2 我认为,一个人对他人的欣赏无外乎两种情况,一种是互补性欣赏,也就是在他人身上找到了自己身上没有的但值得学习的东西,另一种是印证性欣赏,也就是找到了和自己“臭味相投”的人。

 

李彦宏的“罪己诏”

1 离开

离开百度已经一年多了。

间或有人问我为什么要离开百度。找工作的时候问,工作了几个月后还是会有人问。我怎么回答这个问题呢?说A)试用期没通过不得不卷铺盖走人?还是说B)自己工作不爽主动离职?事实上我多数情况下会选择说B。被炒鱿鱼这种事当然是不光彩的,只是有的时候懒得解释,也就随便撒个小慌,一笑而过。我会跟人家说,他娘的我也想炒掉那个操蛋老板,只是我没有那个权利,被暗算了吗?

间或也有百度的同事打来电话,跟我抱怨说工作上如何束手束脚无法施展。两个月前,Robin一封狼性邮件,将百度推向了舆论的风口浪尖。可是通篇读下来,我只看到了两个字——“吃人”。

2 狼性

中国的领导似乎都有一个毛病,那就是总以为自己高高在上1,神圣不可侵犯。事情做好了,功劳都是自己的,心情好了赏仨瓜俩枣给手底下辛苦干活的员工;事情搞砸了,就开始埋怨员工不好好干活,没有“奉献自己100%的热血和青春”。

10年初Google退出中国后,百度已然躺在印钞机上数了两年的钱,其员工规模也从不到五千人膨胀到了接近两万人。不过,在电子商务、云计算和移动互联网的大潮下,这艘航母似乎还没有找到自己的航向,在通往未来的路上越走越偏……

无可否认,在中国互联网的发展历史中,百度占有举足轻重的地位(废话一),创造了多个中国第一(废话二),即便在百度略显疲惫衰落的今天,它依然是中国互联网界当之无愧的三大巨头之一(废话三)。这里有(一些)中国顶尖的工程师,(比较)海量的数据,(比较)庞大的机器规模以及许许多多在很多公司、高校和实验室都无法找到的学习工作环境(废话四,你能指望学校的实验室搭建千台规模的集群供你把玩吗?)可是我们也异常遗憾的看到,凤巢以后:

  • 百度已经很久没有推出令人耳目一新的产品了(典型的如03-06年的知道、百科和贴吧)。
  • 百度迄今为止所有的国际化努力都是失败的。
  • 在电子商务、移动互联网和云计算方面,相比较其余互联网公司,百度毫无建树。

一个手握百亿现金流,掌握中国互联网生杀大权的公司,竟然几年之内拿不出响当当的产品,Robin首先想到的是员工不够拼命,因此任何“有良好背景,流利英语,稳定的收入,信奉工作只是人生的一部分,不思进取,追求个人生活的舒适才是全部”的人,都是小资,都是要被淘汰的。可是我不明白的是,“信奉工作只是人生的一部分”,“追求个人生活的舒适”,这个有错吗?绝大多数的人死之前,想到的不是工作,而是家庭、朋友、亲情。人之所以成为人而不是一部工作机器,正是因为人生中有比工作更为重要的东西。我热爱我的家庭朋友,也享受下班归来灯下漫笔读书的时光,这个有错吗?

没错,作为老板,你当然可以挥舞着狼牙大棒叫你的员工一边加班一边喊爽,但这种所谓狼性是由上而下的,不会长久。我认为,百度当今最大的问题在于上下异心。上层想要业绩要改变要漂亮的报表,中层欺上瞒下只看KPI,每天想着怎样弄份漂亮的报表好生存下去越爬越高,而底层技术人员确实想做一些技术上的事情,但被中层经理压制,有心无力。技术上不去,一切都是空谈,所谓的业绩报表,除了欺上瞒下,就是自欺自娱。房地产企业的土地房子可以升值,但互联网企业的代码机器却会腐朽。

3 岁月

即便算上实习,我在百度待的时间也只有九个月,不到一年。从最初的新鲜兴奋,到最后悲剧性的离开,这期间各种人事变动、技术思考,我几乎从未在博客上写过。今日趁着记忆尚存,偏又莫名辗转难眠,权且将自己在百度的经历,以及自己对工作的一些思考记录下来,希望对后来人有些帮助。其中陈述可能有失公允,欢迎讨论和指正。

以下逐条列出百度之“怪现状”

3.1 百度论语的洗脑文化

当代企业最爱做的事情就是给新员工洗脑,洗脑的内容也无非就那么几项,一是你现在的公司多么多么好,二是你现在的老板多么多么圣明,三是你现在的工作对公司多么多么重要(对,后勤工作对公司也很重要,搞卫生扫厕所的就更不用提了),四是即使你当前的工作不怎么重要不怎么有趣不怎么符合你的预期只要你好好工作那么多年媳妇熬成婆你总会有出头之日的。洗脑本来无可厚非,特别是在天朝这种神奇的国度里。只是百度也搞这一套,倒真是让刚刚实习入职的我大跌眼镜。我记得那个时候刚刚入职实习的时候发了一本《百度论语》,然后每周开例会的时候,一组人做一圈,每周学习一条,轮流说心得报告,总共29条,可以学习半年了。事实上这本书也不是什么不好的书,但这种学习的方式总让我想起七十年代人手一本《毛泽东语录》的场景。书中Robin被写的近乎完美神化,可是我却从来没有看到过百度内部哪里有关于失败产品(典型的比如百度Hi、有啊)的总结。

3.2 封闭的技术开发

中国的互联网企业都有一个毛病,那就是没有开源共享的精神,对开源社区索取大于回馈,百度也是如此。这些企业总是以为自己的技术高人一等,又不想做那些”琐碎“的基础工作,将开源的项目拿过来修修补补贴点牛皮藓后就开始到处吹牛逼说什么世界领先国内一流。比如我在的时候,百度宣称自己的Hadoop集群在规模、负载和利用率上是世界前三的。可是这又有什么用呢?第一,Hadoop不是百度开发的,百度只是打了点补丁做了些定制而已;第二,百度的Hadoop集群数量只有10+个,远远比不上Google 100+个GFS集群这样的规模,其整体的自动化运维水平也差了一个世代;第三,百度所做的所有“改进”很少回馈过开源社区。

其实在Hadoop之前,百度也曾想过开发自己的GFS+MapReduce+BigTable,没错,百度想要开发的系统就是基于Google那三篇著名的论文的2。这个系统叫做Pyramid,其领衔人是王选的高徒阳振坤博士。Pyramid大约开发了2-3年,最终以失败告终,据说最后与Hadoop PK的时候完败下来,阳振坤也在其后离职加盟淘宝3。我不知道Google开发GFS+MapReduce+BigTable用了多久,但是GFS的论文是03年,MapReduce论文是04年,BigTable应该是07年,想来Google应该也是开发了4-6年左右的时间。Pyramid的失败直接导致了Hadoop在百度的崛起,不到两年,Hadoop的机器数量从无到有,很快就突破了万台的规模,并且机房也从北京开始像长三角扩展,百度也终于迈出了跨数据中心的步子,尽管这个步伐似乎比Google慢了5-8年4

不过百度虽然自己用Hadoop用得很High,负载什么的,报表都弄得不错,集群规模也上了国内少有的3000+台,但是却很少对Hadoop社区进行开源回馈。其内部Hadoop是基于Hadoop 0.19-0.20改进的。这样做的好处就是快,一方面依赖社区拿到已有的代码基,整合测试就可上线,同时也不用管什么伦理道德奉献回馈的鸟事,但其缺点就是内部的Hadoop和官方的Hadoop会逐渐越走越远,上游的Patch和改进越到后来会越难引进合并。这样做的结果就是和社区分离,用自己一人之力对抗全球智慧,最终只能自讨苦吃5

我记得有一次内部年会上,有位工程师跳起来问,“公司可不可以做一些开源的产品呢?很多东西本来就是从外边拿过来的。”我只记得当时台上的两位高管,其中一位女高管脸色稍变,过了一会又开始讲什么“做开源需要时间精力;好的东西才好意思开源出去,否则会丢脸”什么什么的。我想,一个IT公司有没有勇气拥抱开源,是一个公司是否对自己的技术有足够自信的一个表现。在这方面,百度乏陈可善,不但没有代码,连论文也很少。而淘宝在章文嵩的带领下,其开源已经做的如火如荼,算是国内IT企业中开源做的最好的一个。

3.3 世界上最优秀的工程师?

百度的内部邮件中不止一次的提到“世界上最优秀的工程师”这个字眼,可惜作为这封邮件的收件人,连我们自己都不相信自己是世界上最优秀的工程师。09-11年高速扩张的两年,百度的招人标准降低了很多。这也是无可奈何的事情,毕竟中国的人才储备有限,有时候即便你想花钱,也不一定能招到足够的人。

你当然无法否认,百度内部有很多牛人,可是大凡拿得上台面的公司,那个手里没有一些牛人呢?重要的是保证整体人才的平均质量,而不是树立几个典型,然后就自吹自擂说自己的工程师是世界上最优秀的。

3.4 KPI为王

我在Hadoop运维组做到第4个月的时候,一手创立Hadoop运维的经理走了,空降了一位新来的经理。当然,这位经理是不懂Hadoop的,加上他又实在繁忙,所能做的就是从报表入手。比如说每周几千台机器几百条小报警有没有都处理掉,预算做的怎么样,总之都是报表性的东西。至于技术上的,监控怎么做,如何才能更好的自动化,怎样统一归约化的整合集群的各个系统,从来就不是他关心的重点。我辛苦两周做出来一个小的监控系统,可以自动的检测各个集群的一些指标参数,并且支持自定义插件,自动化的生成监测报告发送到邮箱中,他给的评价是“这算啥,T2的工程师都能做”。我当时特别火也特别委屈,心里想“T2的工程师都能做,可是为什么一直没有人做呢?站着说话不腰疼”。

再比如我们每周都要写Hadoop集群运维周报,内容无非是去几个监控系统上鼠标copy/paste一些数据到一个模板里。其实这样的东西完全可以稍微花些人力写点程序抓点网页完成,可是一直没有人做这个事情,大家就这样一周一周的写下来。反正经理要的就是这个,谁管你怎么得来的呢。

当一家技术公司由技术驱动变成KPI驱动的时候,也就意味着这家公司发展到了一个瓶颈期。不断有前同事跟我聊,说自己想做一些事情,但是经理不让。为什么呢?比如说一个4、5年的产品代码,由于人员的交替加上技术的封闭,必然是有很多丑陋的代码的,这个时候后来接手的人如果是个有责任心又有代码洁癖的人的话,自然就想对代码做些重构和改进。这就带来了一个问题:万一由于这种额外的改动造成产品出现事故,怪谁?经理是不想承担这样的责任的,因为百度的经理不写代码,多一事不如少一事。这样一个技术人员的积极进取心就这样被压制了。还有的经理说,”做,可以做,如果一个星期之内可以完成,就去做”。可是有多少伟大的产品是一个星期内完成的呢?GFS不是,MapReduce也不是。可是经理才不会管这些,他关心的是他的KPI,是报表。一个东西,如果短期内无法出成果,就不要做。

所以像Puppet这样的工具是不可能出自百度之手的。即便是工程师在平时的工作之中有一些思考,但也很少能有时间形成系统化的,并且能够走出百度被业界认可的东西的。

3.5 会议,还是会议;总结,还是总结;沟通,还是沟通

百度的会议之多,总结之烦,沟通之杂简直是令人闻风丧胆。我在百度的时候,每周至少开3个会,每个会不少于1个小时;每天发送查看邮件不少于40封;每天花在Hi上交流的时间不少于3个小时。有人会问,这么多的沟通会议时间,还有时间干正事嘛?怎么会需要这么多时间沟通交流呢?首先是百度非常看中邮件文化,所有事无论大小都要有个邮件性的总结,学会设定邮件规则是每个百度人的第一课;其次就是百度的部门极其多,据统计整个公司大概有500多个部门和组,工种单一,想要完成一个Project需要跨越很多部门。这就导致了百度内部的沟通成本一直居高不下,会议室都要提前一周甚至两周才能订上。很多rd都是上午过来处理邮件,下午开会,然后晚饭后写代码6

3.6 自由上班?Shit

百度号称自由上班,但这个所谓的自由上班,每天8小时只多不少7

3.7 部门隔离

没错,百度虽然号称“简单可依赖”,“不唯上”,平等,无“公司政治”的企业文化,但是由于部门繁多,流程繁杂,真的想做一件事情,如果没有自上而下的推动,光预算、排期、开会就要耗掉几周甚至几个月的时间。

另一方面,如果你去仔细观察百度的产品,你会发现百度的产品风格差异极大。无论是网页产品还是客户端产品,其UI方面从来都没有给人一种非常明朗统一的感觉,能够让人一看就知道这是百度的东西。这方面,苹果做的最好,Google次之,百度毫无章法。

3.8 Geek在哪里?

百度并不是一个Geek公司。Facebook是,Google是,但百度不是。大多数工程师还在用着10年前的XP系统,用着盗版的Office和SecureCRT软件登录SSH写着各种文档和代码。百度的工程师没有追求美感的习惯,这种美感包括但不限于代码风格、文档排版、产品设计等。据我所知,Google的所有代码在提交之间都会经过一系列的检查,但百度至今没有如此完善的流程。至少在我们组,代码写了一年多,才想到要重新整理,规整风格。百度内部的wiki、代码审查,项目管理系统从来也是破破烂烂,没有类似于Facebook phabricator这样的系统。

3.9 有啊

百度历史上有很多失败的产品,但是从来没有一个产品,如有啊这般惨烈悲壮8。这样的人,这样的团队,这样的条件下这样的时间内做出了这样的牺牲和这样的业绩,但最终依然无法摆脱失败的命运。有的时候,我真的怀疑,当你怀着“我坚信让我一往无前的唯一力量就是我热爱我所做的一切”这样的信念去努力去拼搏的时候,你的老板能够看到并且认可你的付出吗?有啊的惨败,百度的高管可曾做过认真的反省?这究竟是公司战略上的问题还是员工的问题?员工犯错可以扣钱扣绩效,但如果是公司犯错呢?公司做过这样的检讨吗?

4 无他

最终导致我离职(或者被炒掉)的事件是因为一次不快的沟通。那次沟通中经理对我做出了“好高骛远”的评价,并且不认可我平时业余时间KPI之外的工作成果,说我的东西“连T2的工程师都可以做”。而我当然不认可这种评价,当面顶撞了他,说“不认可这种评价”。这可能直接导致经理认为我是个刺头,无法约束,干脆开掉为好。于是在我转正前一周我接到通知让我滚蛋走人。我将此事告知了我前面三个月的导师,他表示非常震惊。HR也特别奇怪,说一个人怎么前面三个月好好的,到了快要转正的时候突然就被开掉了。

回家之后,我跟妞说,“不以物喜,不以己悲”,《偷得浮生半年闲》。

5 箴言

一个人工作的价值(狭义上讲是薪水)正比于这个人的不可替代性。

“谢谢你们曾经看轻我”。

“即使缤纷落尽,繁华消亡,青春绝版,也不要被生活磨平了棱角”。

--

Footnotes:

1 和菜头:放开那些员工和菜头:得罪得罪

2 所以你千万不要相信百度说自己和Google在竞争,事实上如果没有GFW“贸易保护”的话,百度根本没有和Google竞争的技术实力。你要相信,无论是从技术、人才、基础设施和营收上来比,百度和Google都不是一个级别上的公司。

3 关于这个项目更多细节,可以参考内部人士尚未写完的Pyramid传奇系列,我接手Hadoop运维的时候,Pyramid已经下线了,只在Wiki上看到过只言片语。

4 Oh,5-8年,IT的一个朝代都过去了。

5 国内IT企业对待开源大多如此,但是有些企业已经开始觉醒,比如新浪之于OpenStack

6 参考:一个前百度工程师看百度的狼性

7 参考:工作这些年

8 参考:东宝:为了即将忘却的记忆

----------

这篇文章发表半天后,由于某位不知名的百度仁兄的抬爱,忽然的就火了起来,也吓了我一跳。我写了另外一篇小文作为补充说明:《慎言多思》。如有任何建议指正,欢迎多多指教,xiaohanyu1988@gmail.com。

另,很多人提到说题目有些“驴唇不对马嘴”,我这里稍微解释下。首先我是明白“罪己诏”这三个字的含义的,取这三个字为题也是有意为之;其次是写这篇文章的初衷是为了“批判”下Robin的那封狼性邮件,因为我觉得百度出现的很多问题是公司层面的而非员工层面,绝不是为了博眼球。想来想去还是觉得这个题目比较好,加上引号,算一点修正,剩余不再修改。谢谢诸位提醒。




Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee