存档: 作者存档:

farewell

1条评论 2010年1月27日

阿福离职了。

这是我在这个博客的最后一篇文章。

我会继续在http://nimoforresty.spaces.live.com写文章的。

大家保重。

加油。

好产品往往是用很烂的代码写出来的

10 条评论 2009年12月2日

“好产品往往是用很烂的代码写出来的”

忘记最早是在哪里看到的这句话的,最近深有感悟。

在开发的过程中,我们总是无可避免地会遇到需要在“代码质量”和“产品质量”之间做权衡的时候。作为一个程序员,我们往往会追求代码本身的美感,而忘记这个程序能够产生的价值。从用户的角度来说,除非他脑子进水了或者是一个geek,不然用户永远不会管你服务器用的是Linux系统还是万恶的Windows,服务器端的代码用的是php还是高贵的RoR,你是用Ctrl+C & Ctrl+V从网上到处抄来的代码,复用了别人已经开发好的系统,还是用尽了各种设计模式和PEAA中学来的各种架构模式、绞尽脑汁严格控制代码中空格和tab的区别以及行末是否有多余空格等亲手一行一行敲出代码来。

用户关注的是你这个产品能不能满足他的需求,是不是有很好的用户体验。

这让我想起了Chrome里处理ed2k链接的方式。Chrome现在是我最喜欢的浏览器,但是每次我要到verycd.com上面去找一张专辑或者一部电影(我承认我侵犯版权了,我忏悔……),我都会很不爽。

为什么?因为在找到一个资源之后,我要么需要在页面空白位置点击右键,然后查看源代码或者“检视页面元素”,手动找到这个链接,复制这个链接,填到eMule里;或者我要打开我万不得已才打开的IE,或者我要打开我臃肿的做开发的时候才用到的Firefox。在这个支付宝和建行都已经支持Chrome的年代,这种事情实在让我很难以接受。

为什么?因为Chrome不认ed2k的链接。

为什么?很明显,ed2k的链接对待”|”这个符号不太符合标准,由于Chrome的代码用一种通用并且优雅的方式对待所有URL Scheme,而正好ed2k链接是一个比较尴尬的特例,于是它的“|”符号被转义了。

去读那个issue里面的用户评论吧,我基本上笑死了:)有用户在问这不就是一个if语句么,而马上开发者就说这样很脏,开始讨论是不是有一种通用的方式去对待这一类特殊的URL Scheme。然后有人说貌似只有ed2k链接比较变态啊,不存在一类特殊的URL Scheme,而是只有一个。这下尴尬了,不存在从代码角度来说很“优雅”的解决方案,至少短时间内找不到。而这时一个看起来比较senior的开发者就出来讲了一大堆Chrome内部对URL的处理方式,试图解释为什么这个bug还没有被修掉。后来又有用户出来说了:

Comment by NoamNelke, Oct 30, 2009

I'm all against special-casing in general, but at least until a better solution
is found or agreed upon - please, just do it...
 

Google code上的Chromium项目已经有了超过29000个Issue,这个Issue的Id是160,是一个在Chrome 0.2时代就存在的bug。

这个Issue在Google code上的chromium项目里的优先级是P3,就算Chrome的用户只有极少数会像我这样去点击ed2k链接,但是

至于么?不就是一条if语句么?

看来Google的APM/PM还不够多呀。

———————————————————–

另外一件事情是,Windows里有一个名字叫abc的数据结构 ,而且还是一个API。

我就想,负责这块代码的工程师们得有多大的毅力和自制力去维护它,并且在MSDN上搞出这么专业的文档。

虽然我很想笑,但是我真的要向你们致敬。

———————————————————–

说到这里,大家应该满清楚了。其实问题就在于,我们写代码是为了满足别人的真实存在的需求,还是自己内心充满寂寞的成就感。

在我精神分裂了一年之后,我不太灵光的脑子终于把这个问题想清楚了:)

当然,这不是意味着,在饿了么产品质量是P1,代码质量是P2。在饿了么,代码质量绝对是P1,而产品质量则是P0。你可以先用dirty hack的方式满足产品的需求,但是回头还是得尽快用重构的方式,避免给将来带来太大的麻烦。

当然,饿了么这个产品现在还远远没有达到及格线的标准。如果满分是100分,现在最多只有30分。

不过幸好目前许多工作正在幕后默默地进行着,预计近期能够越过这条线:)

———————————————————–

Raymond童鞋加入之后,我代码写得越来越少,也逐渐有了许多时间处理各种其他事情,和进行思考。在经历了身兼PM+dev lead,磕磕碰碰惹下无数麻烦,带来无数问题,体质变差精神分裂的一年之后,我终于逐渐开始洗手不写代码了。希望从此大家能重拾对我的信心:)

作为一个*nix programmer(虽然SC和PW童鞋还不赞同),我最近很信奉Unix的一条哲学:do one thing and do it well. 或许真的有人可以很好的身兼PM和Dev Lead的角色,但是我还是太嫩了,并且或许这辈子都不可能做到。

但是这未必就不是一件好事,赫赫。

写了这么多,回头看看自己的网站还是那么的不尽如人意,实在是丢脸啊。我做不成一个好PM+dev,那我就努力至少成为一个好PM吧。

(图片来源:http://www.slipperybrick.com/tag/imac/

新民晚报报道饿了么

3 条评论 2009年11月2日

DSCF0191_600x800

2009年11月2日 《新民晚报》B9就业导航版:)

百度更懂中文的证据

1条评论 2009年10月27日

image

image

image

阿猫 阿狗 和 foosball

没有评论 2009年9月27日

我住的南洋博士新居楼下有一只黄色大肥猫,每次我经过它的时候它总是眯着眼睛看着我,貌似很大牌的样子。有一天我试着去摸摸它的头,它居然很温顺地低头不动了。

————————–

今天早上出门的时候,天上下着蒙蒙细雨。刚上车没多久,一只超可爱的黄色小狗跟在我自行车后面跑,屁颠屁颠地几次差点撞到我的后轮胎。我怕撞伤它,赶快停了下来,结果它马上开始舔我穿着拖鞋的脚= =

看来这条狗没有人养的样子,正考虑要不要抱回去养着,结果阿康骑着电瓶车过来了,它马上就把我抛弃了屁颠屁颠地跟着阿康跑了……

————————–

ELEME DevDiv Office V3基本完工,灰常感谢阿康和他的富婆。今天早上我们一帮人把foosball桌子装了起来,玩得巨high,右手臂现在有点酸。

傍富婆真好。

————————–

Project Pearl Wave 1 (codename Arsenal) 于今天正式开始了。希望一切顺利:)

饿了么产品组招聘软件开发工程师

3 条评论 2009年9月21日
饿了么产品组招聘软件开发工程师,全职也可,兼职也可,“实习”也成。要求很高,待遇不差:)
饿了么是什么?
饿了么创办于2008年9月,目标是帮助中国餐饮业提供信息化解决方案,完成整体产业升级。目前为交大闵行校区,紫竹科学园区和周边住宅区提供网上订餐和代购业务,运营状况健康,发展势头迅猛,预计将在半年内扩张到周边区域,一年内业务遍布全上海。现今因短时间内业务快速扩张的需要,产品部门需要新鲜血液加入。
饿了么的创始人均为上海交大校友,其中两人已经休学,一人已在今年本科毕业后全职加入。产品组办公地点在地铁剑川路站附近,距离交大北门10分钟自行车车程。
不就是个订餐网站么……
对,从用户的角度来看,的确是这样。从某种意义上来说,iPod也就是一个mp3播放器,kindle也不过是一个电子书阅览器而已。我们不想成为一个只会吸引用户注意力,浪费用户宝贵时间的网站,我们希望能够做出一个真正有价值的工具,一个真正能够给用户带来便利,给餐厅提高效率,带来收益的工具。日本的出前馆做出了这样的一个工具,美国的OpenTable做出了这样的一个工具,他们都上市了。淘宝、阿里巴巴、百度和Google从某种意义上来说,也都只是工具而已。
我们正在着力打造的是:
一个针对用户的足够简单足够强大的订餐工具;
一个针对餐厅的真正提高效率带来收益的软件即服务(SAAS)产品;
一个基业长青,百年不倒的伟大公司。
为什么我要选择饿了么?
在这里,你将获得和大型软件公司完全不同的体验:你面对的不会是业界最难的问题,你也不会困死在长达一年的项目周期里。有的只是敏捷开发,敏捷项目管理。你要关注的是getting things done.
你将体验大多数人一辈子都无法经历的最刺激的创业过程,你将感受和整个公司一起飞速成长的快感。在饿了么,每天都有新变化。在饿了么,我们互相学习,共同成长。在饿了么,我们 work hard, play harder.
我需要具备怎么样的能力?
我们需要真正卓越的人才,至少,你要有追求卓越的决心和毅力。
我们希望你有扎实的技术功底,踏实的作风。
最重要的,是有快速学习的能力,和学习的热情。Smart and get things done.
至于你具体会什么技术,不会什么技术都完全没有关系,我们相信只要你够聪明并且喜欢解决各种难题,你总会在团队里找到自己的位置。
我们目前用到的各种技术有(仅列出部分):
C(餐厅出单机驱动),CSS/XHTML/Javascript/JSON(网站前端),PHP(网站后端),shell脚本(各种自动化脚本),python(Google App Engine脚本),Java(数据挖掘和机器学习)和Linux自定义发行版(餐厅终端机所用的系统)。
同时,我们有完善的版本控制,逐步进入正轨的项目管理和产品发布机制。
看,饿了么不仅仅是一个简单的订餐网站吧?:)
我来了能做什么?
参与网站的开发,参与网站的测试,参与网站的设计,参与网站的运作。只有想不到,没有做不到。
饿了么能给我提供什么?
绝对有竞争力的待遇,绝对有竞争力的学习机会,绝对有竞争力的表现自己的舞台,最刺激的创业体验。
工作地点在哪里?
地铁剑川路站附近,距离交大北门10分钟自行车车程。
时间上有什么要求么?
为了保证有效的沟通,所以每周能够过来的时间越多越好,毕竟团队还很小,我们承担不起太高的沟通成本。原则上工作时间不少于每周3天,不过这个时间你可以比较灵活地进行安排。
如何加入?
发邮件给阿福 forrest dot ye at ele dot me,请附上简历。
我们不是最有经验的,但是我们是最有热情的。相信我,加入饿了么并且用心去做,这份经历会成为你这辈子最宝贵的财富之一。
Stay hungry, stay foolish. 你饿了么?

饿了么产品组招聘软件开发工程师,全职也可,兼职也可,“实习”也成。要求很高,待遇不差:)

饿了么是什么?

饿了么创办于2008年9月,目标是帮助中国餐饮业提供信息化解决方案,完成整体产业升级。目前为交大闵行校区,紫竹科学园区和周边住宅区提供网上订餐和代购业务,运营状况健康,发展势头迅猛,预计将在半年内扩张到周边区域,一年内业务遍布全上海。现今因短时间内业务快速扩张的需要,产品部门需要新鲜血液加入。

饿了么的创始人均为上海交大校友,其中两人已经休学,一人已在今年本科毕业后全职加入。产品组办公地点在地铁剑川路站附近,距离交大北门10分钟自行车车程。

不就是个订餐网站么……

对,从用户的角度来看,的确是这样。从某种意义上来说,iPod也就是一个mp3播放器,kindle也不过是一个电子书阅览器而已。我们不想成为一个只会吸引用户注意力,浪费用户宝贵时间的网站,我们希望能够做出一个真正有价值的工具,一个真正能够给用户带来便利,给餐厅提高效率,带来收益的工具。日本的出前馆做出了这样的一个工具,美国的OpenTable做出了这样的一个工具,他们都上市了。淘宝、阿里巴巴、百度和Google从某种意义上来说,也都只是工具而已。

我们正在着力打造的是:

  • 一个针对用户的足够简单足够强大的订餐工具;
  • 一个针对餐厅的真正提高效率带来收益的软件即服务(SAAS)产品;
  • 一个基业长青,百年不倒的伟大公司。

为什么我要选择饿了么?

在这里,你将获得和大型软件公司完全不同的体验:你面对的不会是业界最难的问题,你也不会困死在长达一年的项目周期里。有的只是敏捷开发,敏捷项目管理。你要关注的是getting things done.

你将体验大多数人一辈子都无法经历的最刺激的创业过程,你将感受和整个公司一起飞速成长的快感。在饿了么,每天都有新变化。在饿了么,我们互相学习,共同成长。在饿了么,我们 work hard, play harder.

我需要具备怎么样的能力?

我们需要真正卓越的人才,至少,你要有追求卓越的决心和毅力。

我们希望你有扎实的技术功底,踏实的作风。

最重要的,是有快速学习的能力,和学习的热情。Smart and get things done.

至于你具体会什么技术,不会什么技术都完全没有关系,我们相信只要你够聪明并且喜欢解决各种难题,你总会在团队里找到自己的位置。

我们目前用到的各种技术有(仅列出部分):

C(餐厅出单机驱动),CSS/XHTML/Javascript/JSON(网站前端),PHP(网站后端),shell脚本(各种自动化脚本),python(Google App Engine脚本),Java(数据挖掘和机器学习)和Linux自定义发行版(餐厅终端机所用的系统)。

同时,我们有完善的版本控制,逐步进入正轨的项目管理和产品发布机制。

看,饿了么不仅仅是一个简单的订餐网站吧?:)

我来了能做什么?

参与网站的开发,参与网站的测试,参与网站的设计,参与网站的运作。只有想不到,没有做不到。

饿了么能给我提供什么?

绝对有竞争力的待遇,绝对有竞争力的学习机会,绝对有竞争力的表现自己的舞台,最刺激的创业体验。

工作地点在哪里?

地铁剑川路站附近,距离交大北门10分钟自行车车程。

时间上有什么要求么?

为了保证有效的沟通,所以每周能够过来的时间越多越好,毕竟团队还很小,我们承担不起太高的沟通成本。原则上工作时间不少于每周3天,不过这个时间你可以比较灵活地进行安排。

如何加入?

发邮件给阿福 forrest dot ye at ele dot me,请附上简历。

我们不是最有经验的,但是我们是最有热情的。相信我,加入饿了么并且用心去做,这份经历会成为你这辈子最宝贵的财富之一。

Stay hungry, stay foolish. 你饿了么?

DevDiv头脑风暴后的产物

1条评论 2009年8月8日

brainstorm_masked

[译文] symfony 参考指南 – 配置文件原则

没有评论 2009年8月4日

原文:the symfony Reference Book, http://www.symfony-project.org/reference/1_2/en/03-Configuration-Files-Principles
翻译:ELEME Dev Team

symfony 所有的的配置文件都基于一套共同的原则,并使用一些公共属性。本节将详细地介绍这些原则和属性,并且可为后面几个关于YAML配置文件的章节提供参考。

缓存

symfony 的配置处理类会将所有的配置文件缓存为 PHP 文件。当 is_debug 属性设置为 false 时 (例如在 prod 环境中,即生产环境),symfony 仅会在首次请求中对配置文件进行缓存处理,而在这之后的所有请求都将访问相应的 PHP 缓存文件。对 YAML 文件的解析是一个较“重”的处理过程,缓存机制使得这个过程只执行一次。

dev 环境(即开发环境)下, is_debug 属性默认设置为 true,symfony 将在每一次配置变化后重新分析处理缓存(symfony 会检查文件的修改时间)。

可以通过 config_handler.yml 文件来配置解析和处理配置文件所需的配置处理类(configuration handler class)。

在以下各节中,我们称 symfony 将 YAML 文件转化为 PHP 文件并存储在缓存中的这一过程为“编译”。

要强制清空配置缓存可以使用 cache:clear 命令:

$ php symfony cache:clear --type=config

常量

配置文件core_compile.ymlfactories.ymlgenerator.ymldatabases.ymlfilters.ymlview.ymlautoload.yml

一些配置文件允许使用预先定义的常量。symfony 通过占位符来使用常量,即在大写的常量名两侧加上“%”符号,类似于“%XXX%”。当配置文件被编译时,symfony 会用常量的实值去替换掉所有相应的占位符。

使用配置文件中的常量

settings.yml 中定义的任何设置都可以作为常量来使用。其占位符为大写的设置名称并在开头加上 SF_

logging: %SF_LOGGING_ENABLED%

当 symfony 编译配置文件时,它会从 settings.yml 文件中读取常量的值并替换掉占位符。在上面的例子中,symfony 会在 settings.yml 中查找 logging_enabled 这一设置,并用其值来替换占位符 SF_LOGGING_ENABLED

使用应用程序设置文件中的常量

与使用 settings.yml 文件中的常量类似,可以通过添加 APP_ 的前缀来使用 app.yml 中的设置。

特殊常量

默认情况下, symfony 根据当前的前端控制器定义了四个常量:

常量 描述 配置方法
SF_APP 当前应用程序名称 getApplication()
SF_ENVIRONMENT 当前环境名称 getEnvironment()
SF_DEBUG 是否启用调试 isDebug()
SF_SYMFONY_LIB_DIR symfony 库目录 getSymfonyLibDir()

文件和目录

当你需要引用一个文件或目录地址时,使用常量而不是硬编码是个很不错的主意。symfony 已经为一些公共目录定义了对应的常量。

SF_ROOT_DIR 对应于 symfony 目录树中的根目录,其余所有目录变量都通过这一变量产生。

项目目录结构的常量定义如下:

常量 默认值
SF_APPS_DIR SF_ROOT_DIR/apps
SF_CONFIG_DIR SF_ROOT_DIR/config
SF_CACHE_DIR SF_ROOT_DIR/cache
SF_DATA_DIR SF_ROOT_DIR/data
SF_DOC_DIR SF_ROOT_DIR/doc
SF_LIB_DIR SF_ROOT_DIR/lib
SF_LOG_DIR SF_ROOT_DIR/log
SF_PLUGINS_DIR SF_ROOT_DIR/plugins
SF_TEST_DIR SF_ROOT_DIR/test
SF_WEB_DIR SF_ROOT_DIR/web
SF_UPLOAD_DIR SF_WEB_DIR/uploads

应用程序目录结构是根据 SF_APPS_DIR/APP_NAME 所定义的:

常量 默认值
SF_APP_CONFIG_DIR SF_APP_DIR/config
SF_APP_LIB_DIR SF_APP_DIR/lib
SF_APP_MODULE_DIR SF_APP_DIR/modules
SF_APP_TEMPLATE_DIR SF_APP_DIR/templates
SF_APP_I18N_DIR SF_APP_DIR/i18n

最后,应用程序的缓存目录结构定义如下:

常量 默认值
SF_APP_BASE_CACHE_DIR SF_CACHE_DIR/APP_NAME
SF_APP_CACHE_DIR SF_CACHE_DIR/APP_NAME/ENV_NAME
SF_TEMPLATE_CACHE_DIR SF_APP_CACHE_DIR/template
SF_I18N_CACHE_DIR SF_APP_CACHE_DIR/i18n
SF_CONFIG_CACHE_DIR SF_APP_CACHE_DIR/config
SF_TEST_CACHE_DIR SF_APP_CACHE_DIR/test
SF_MODULE_CACHE_DIR SF_APP_CACHE_DIR/modules

环境

配置文件settings.ymlfactories.ymldatabases.ymlapp.yml

某些配置文件与 symfony 的当前环境有关。这些文件通过划分不同的区段,为每个环境设置不同的配置。当创建一个新的应用时,symfony 会创建三个默认的环境:prod(生产环境),test(测试环境),和 dev(开发环境):

prod:
  # `prod` 环境的配置

test:
  # `test` 环境的配置

dev:
  # `dev` 环境的配置

all:
  # 所有环境公用的默认配置

all 区段为所有的环境提供默认设置。当 symfony 从配置文件中读取一个设置时,它会优先使用相应环境区段中的配置,若当前环境区段中没有提供该设置,则 symfony 会在 all 区段去寻找它。

配置的级联

配置文件core_compile.ymlautoload.ymlsettings.ymlfactories.ymldatabases.ymlsecurity.ymlcache.ymlapp.ymlfilters.ymlview.yml

有时候,同一个配置文件可以在几个不同的 config 目录多次出现,symfony 会按照目录结构合并它们。

symfony 在编译配置文件的时候,会根据以下顺序先后合并多个文件中的配置信息:

  • 模块配置( PROJECT_ROOT_DIR/apps/APP_NAME/modules/MODULE_NAME/config/XXX.yml
  • 应用程序配置( PROJECT_ROOT_DIR/apps/APP_NAME/config/XXX.yml
  • 项目配置( PROJECT_ROOT_DIR/config/XXX.yml
  • 插件配置( PROJECT_ROOT_DIR/plugins/*/config/XXX.yml
  • symfony 库配置( SF_LIB_DIR/config/XXX.yml

例如,在一个应用程序目录中定义的 settings.yml 将默认继承这个应用程序所在项目的 config 目录中 settings.yml 的配置信息,而项目的 settings.yml 又是继承自 symfony 框架的默认 settings.yml 配置文件中的配置信息(lib/config/config/settings.yml)。

当一个配置文件与环境相关,并在多个目录中,那么则按照下面给出的优先级来合并配置:

  1. 模块
  2. 应用程序
  3. 项目
  4. 特定环境
  5. 所有环境
  6. 默认值

上周ELEME Dev Team工作总结

没有评论 2009年7月14日

经过一周的辛勤工作,我们很开心地发布了一个新版本,主要包含以下内容:

1. 做了许多工作,大大提高了网站的安全性

具体细节不谈:)

2. 修改密码功能完成(终于……)

在登录后的页面右上方,可以看到一个修改密码的链接:

修改密码

点击此链接即跳转到修改密码页面

修改密码

3. 更改密码时需要输入原始密码,那么如果忘记密码了怎么办?找回密码!

找回密码

输入注册时候的邮箱,饿了么会自动给您发送一封找回密码的邮件

找回密码

找回密码的邮件

重设密码

为了您的安全考虑,您在饿了么的密码是经过单向哈希处理的,所以我们也不知道您的原始密码是什么。不过你可以重设密码:)

4. 可以用注册时候使用的Email登录饿了么了!

大家可能已经发现,刚刚这个图上有一点不一样的地方:

使用邮箱登陆

有时候,阿福经常会忘记自己在一个网站上的用户名是什么,所以有些网站在有找回密码功能的同时,还需要另一个功能,叫找回用户名……

所以,为了大家更方便地使用饿了么,现在你也可以用Email地址登录饿了么啦:)很简单,填入Email地址,填入密码,提交!

5. 咦,我刚刚下的订单哪里去了?

饿了么是支持不注册不登录直接下匿名订单的,但是之前存在一个这样的一个情况:

你下了一个匿名订单,然后在订单中心看到了这个订单。然后你注册,然后登录,然后到订单中心,发现订单不见了……

不用担心,现在这个问题已经没有了:)现在,在你登录之后,饿了么会帮你之前下的匿名订单转化成你的订单,再也不用担心订单不见的问题了!

guest_order_center

这是刚刚下的匿名订单

retrieve_guest_order1

成功认领匿名订单!

6. 更多……

还有,我们修复了灰常多的bug,做了灰常多的代码优化。饿了么每天都在成长:)

饿了么大大扫除

5 条评论 2009年6月18日

昨天,我们进行了一场大大大大扫除,整理出一个房间,饿了么DevDiv(Developer Division)终于有独立办公室了:)

废话不多说,上图:

浏览更多,请到

http://www.flickr.com/photos/forresty/sets/72157619862472826/

或者阿福校内:

http://photo.xiaonei.com/getalbum.do?id=309803401&owner=229030294&ref=minifeed

或者

http://cid-6fa2b93b87c3068f.skydrive.live.com/browse.aspx/2009-06-17%20ELEME%20DevDiv%20Office%20V2