分类目录归档:百姓网

写代码这件事

晚上花了两个小时给丰兄和花花展示一次如何写代码,从第一个字符开始,用199行代码完成付费的如下功能:

  1. 权责发生制的记帐
  2. 置顶的产生和显示逻辑
  3. 类目置顶,筛选置顶,全省置顶,全国置顶,区县置顶
  4. 部分订单取消
  5. 置顶竞价,端口竞价
  6. 送天数逻辑,买100送20块这样真钱假钱逻辑

很累。

结论和大家分享:

1. 会代码不等于会逻辑

代码只是一种语言,一种更加精确的语言。会写代码仅仅是会写代码。一个汉语讲不明白话的人用英语也不见得讲明白。一个海明威要是学会了意大利语,估计小说也写得不错。代码仅仅是表达。一个代码写不明白的人,事情一定想不明白。事情想明白的人,就差一点点培训,就能写好的代码。

2. 边界

我们已经在停止学习了。停止学习是创业公司的死亡之日,也几乎是一个人的死亡之日。业务人员为什么不能看代码?我拉丰兄和花花(你没看错)来看代码,而且是看我一个字一个字敲出来,就是用一种残酷的方式打破大家对代码的恐惧。哪有那么复杂?就是一些数学表达式而已。

现在的状态让我感觉警察追小偷,一超过自己的区域,就嘎然而止,看着小偷扬长而去而不敢跨越雷池半步。我们不要讨论边界好不好,讨论一下小偷怎么还逍遥法外的问题好不好?不要骂对面地界的警察无能。骂自己无能,没办法走过去好不好?

3. 跨界

代码逻辑和业务逻辑本来就是在一起的,认为的分在两个人脑子里让谁都想不清。我们怎么可能在一点不知道财务怎么算帐的情况下把帐理清楚呢?怎么可能在不知道代码的情况下把付费逻辑理清楚呢?对不起,我不相信分工,我相信hacker精神,我相信聪明。

最后的底线是,不要告诉我不能做的原因,告诉我怎么可以做。代码理不清楚我来写。199行的代码虽然离上线还有距离,但距离已经不远了。我们的付费复杂吗?要得了两万多行的代码吗?两万行的代码解决问题倒也罢了,还没解决问题。。。。

我又想骂人了。就此打住。。

 

动手好奇反叛的Hacker精神

这两天正好赶上给办公室新的WIFI的SSID命名。我建议网络名叫hacker(还有一个可以覆盖到整个徐汇交大大草坪的热点,叫Free4Hacker。我花了点时间,写下了我对Hacker精神的理解,给大家瞅瞅。

Hacker不是仅仅在计算机领域才有。历史上的那些杰出的发明家,画家,建筑师,工程师,科学家,很多具有hacker的精神。

他们会发现这个世界里面让他们兴奋的问题,并且自己动手去寻求解决方案。

问题是什么?

Hacker解决的问题可能很大。比如人类想飞而不能飞的问题;比如马的力气不够大的问题;比如把消息尽快的传出去的问题,到在互联网上找不到东西的问题。看看世界上林林总总的解决方案,你会惊讶于莱特兄弟的方案,福特给出的方案,以及Tim-Berners-Lee等很多聪明人给出的方案。Hacker不是以做什么为导向的,他们以解决什么问题为导向。

他们是那些不满足现状的人,是那些长长的排队的队伍里面最想改变流程,让大家不再排队的人;是那些相信做任何事情都有更好的解决方案的人。

自己动手

当发现了问题,他们迫不及待的解决这些问题。如果没有解决方案,他们会自己动手建造解决方案,无论是写代码,还是刨木头,或者买砖头,他们开始干了起来;如果遇到不会干的,他们会学习。

他们没有边界,他们永远不把自己定位为一个程序员,一个建筑师,或者一个业务人员。他们为了解决问题可以带上任何需要的头衔!如果说他们到底身份是什么,他们的身份就是hacker,就是跨越所有边界解决问题的人。他们的好奇心带领着他们进入一个又一个领域,并且都做得很好。

好奇心

他们在做和学中间迅速游走,让其他还在自认为是某个职业的人惊讶的张大嘴巴。曼哈顿计划中的物理学家理查德·費曼就是这样一个人。它不仅物理很强(诺贝尔物理学奖获得者,原子弹的重要贡献者),他还是一个画家,鼓手,甚至在接到妹妹的中文信以后愣是自个儿学习中文,并用中文回了信。换句话讲,那些hacker都是成年了还保留着5岁孩子的好奇心的人,保持开放的心态去学习的人,那些不把自己关在一个地方的人。

反叛精神

Hacker还有特点,就是崇尚自由,打破常规,藐视权威。这或许是中文翻译中“黑客”一词的来源,人权运动和开源软件等运动和Hacker精神有很高的内在相似性,而他们和现代版权保护,政府,边界,平均主义等格格不入。

Hacker要的是解决问题,要的是更好的解决方案。为了这个方案,他们去除一切阻挡的因素。费曼教授最著名的趣事就是为了拿到数据破解了国防部的保险柜。他们反编译源代码,打开任何电子设备的机箱,解剖可以解剖的生物就是为了了解现有方案,了解这个世界是怎么工作的,从而给出更好的方案。所以当他们继续前行的时候一路必然伴随着越界。一个当众嘲笑CEO无知的程序员也常常是那些嘲笑现有的解决方案的程序员,更是那些对于“你做不出来这个东西”的判断最不屑一顾并且证明这个说法是错误的程序员。反抗是Hacker最宝贵的精神,也是现代公司制度中最不受欢迎的精神(虽然大家用更加文雅的词语来教育大家,说要有团队精神)。但我坚决保护这种反叛的种子。

为了把事情完成,他们不等待,他们自己动手,不会就自己做,当看到一点点蛛丝马迹他们会沿着它一路跟下去,在这个过程中不经意的翻了谁的墙,踩了谁的花,这些真的只是副作用而不是他们的本意,甚至有些连Hacker自己都没有注意到。但如果没有他们,我们很少能在技术前沿有所进步。

自己动手+好奇心 + 反叛,这是我能理解的Hacker的精神。我在周围有些人身上看到了这种精神。而我最期待的,就是和Hacker一起工作,并且把Hacker的精神散播出去,让大家成为“疯狂到相信能改变世界的人”,并“最终改变了世界”。

 

看代码的愤怒

刚才花时间看了些代码,怒了。

程序员是思考的人,象画家和作家一样,不是码农,不是通过体力完成功能的人,绝不是!看代码和看书一样,是能感觉到写代码的人的思想。看一篇优美的散文和诗歌,跟看报纸上干巴的公关稿,感觉就是不一样,跟看帐本更不一样。

我刚才看到大量的hardcode的东西,没有逻辑,没有层次,多次拷贝粘贴而成的东西,怒!虽然完成了功能,但根本就是垃圾的代码,是没有灵魂的代码,写这样的东西,真的只能叫码农,不能叫程序员。

代码是有灵气的东西。它是对与世界的抽象。之所以需要有灵气,是因为在复杂的需求和优美的实现中间有一个巨大的矛盾,这个矛盾的解决之道是程序员的能力。

千万不要抱怨现实的复杂。现实必然复杂!画人像的画家从来不应该抱怨模特的脸为什么不长成严格的正方体,好让自己画阴影的时候容易点。试图用正方体去画人像必然失败,会被骂。在现实的复杂和纸面上的优雅之间的巨大冲突,需要由画家的技巧来弥补。

不是复杂的世界一定会导致恶心的代码。精致的代码不见得出来的就是简化得现实。但两者兼得的确来之不易,需要能力!

怎么做到用精致得代码构造复杂的现实呢?

  1. 分层。
  2. 抽象。
  3. 迭代

首先是分层。

举个做菜的例子。中国菜馆的菜单动辄几十种,若是没有合适的分层,连原料存储都成了问题:总不能厨房里面放着几十个格子,每个格子里面放着一样菜的所有原料吧。分层,或许可以分为“配菜层”,“制作层”,“调料层”。

  1. “配菜层”又分成“肉”和“菜”并列的两类。肉里面有牛肉,羊肉,鸡肉等,菜里面几种蔬菜。
  2. “制作层”其实就只有炒,烧,蒸,爆,煮等有限的几种;
  3. “调料层”是放油,盐,辣椒,香菜等等。

分了层,几十种菜就变成可以掌控的几组选择的组合。不管什么菜的肉都放在冷冻箱里,不管什么菜都用有限的几种锅子就做得出来,不管什么菜都是一样的几种辣椒。分了层,就把复杂的东西简化了。好的厨师不是宣布我为了简化只做三种菜,也不会因为几十种菜而需要1000平米的厨房来存货,而是通过分层化繁为简,再由简至繁。

别跟我说复杂,说恶心。线团不缠在线轴上当然复杂,像猫一样在乱麻里面搅和当然很复杂。

第二就是抽象。

数据结构就那几种经典的,设计模式也这么多年没有发现新的了,控制逻辑更是几乎从代码生成到现在无外乎一只手数得过来的。如何在纷繁的世界里面看到后面的逻辑,从Listing页面看到后面可以抽象成collection,复杂的关系抽象出“图”,把相互关联抽象成“边”,把看似毫不相关的东西抽象成一样,把看起来几乎一模一样的东西看透必须是不同的类来表示,这些都是抽象能力。

不努力去抽象,就会平庸的大段拷贝粘贴代码,就只会顺序执行,再加一点 if { } else { },只会字符串拼接而形成HTML,只会无休止的写代码,就只能自己干体力活。不会写循环的程序员小明才会熬夜写:

print(“1”);

print(“2”);

print(“3”);

 print(“100”);

一行一行的写,写呀。。写呀。。写呀。。。写呀。。。写呀。。。!!!一边写还在抱怨:“为什么活儿真他妈的多,我真他妈的苦。”写出来的东西还老多的bug,修bug的时候还不服气:“要不是有这些bug拦着我,我早就写到1000了。。。” 实在是不动脑子加嘴硬的典型代表。

但想想,会了循环和用函数封装,你就比小明高级很多了吗?

最后是迭代。

文章是一点点改出来的,不是写一遍再重写一遍的,不要期待啥时候一个来一个新架构,新框架就能解决问题。前后端分离不是专门的工作,是一种思想,需要立刻操练起来,从自己的每一行新代码开始。

推倒重建在任何领域都不是好主意。因为推倒重建是一种习惯。如果解决问题的办法是大规模重建,在三个月后建成必然会有更多的理由再次推倒建成的,因为这是一种习惯。

也不要等待。程序员不能等待,因为程序是分层的,是可改动的,是可以在一层很乱的情况下封装好把上层做好,之后再更改下层的。工程中的脚手架在代码世界可以用得天衣无缝。必须学会在垃圾堆里建设一个茅屋,在茅屋堆里建大楼。因为除此以外的情形,是不现实的,是追求不到的。

程序会呼吸的。会变化的,会一点点的变好的。看看佛罗伦萨的那些古建筑,450年来,一些建筑里面从泥巴已经变成了不锈钢了,或者表面已经加了防氧化膜了,那个建筑已经不是那个建筑了,却依然美丽。你推倒重建一个大教堂就牛了吗?保持表面不变换结构,或者保持里面不变换外观,土木工程师在现实世界都能做得出来,代码这种思想的东西难道做不出来?

分层,抽象,迭代,就是这些。

希望大家好好看看程序,在自己能心平气和的写出自己觉得漂亮的程序之前别跟别人说自己是程序员了。

提正确的问题,用聪明的办法解决

刚才我们一起过了一下付费,抱歉,我又非常气愤。气愤在于大家的智慧没有发挥,而在一个乱麻中间搅和,完全是在浪费生命。我期望百姓网的程序员都是Hacker,如下是我的期望:

1. 要有追求。

程序员是非常神圣的职业,拥有和建筑师,作家,画家一样的魔力,可以构建一个不存在的世界,而比起那些职业,程序员的工具更多,世界更加绚丽。大家要有追求,成为一名hacker。Hacker的定义是非常聪明的,能够创造世界的程序员。Hacker绝不会有祥林嫂一样的被动的,只知道抱怨的倾向。Hacker会不惜一起代价解决一切问题,没有的回去写,不会的要去学,会像福尔摩斯一样拿到一个线索追问下去直到解决。这就是hacker喜欢开源的原因。我们所有的问题都可以找到根源解决。今天关于置顶的讨论,一个如此简单,4个小时应该就完美解决的东西,被搞成几个人几个月还纠缠不清的一个漩涡,就是因为不敢破,不敢去看搜索,不敢越界,把没有的界限当作自己的界限。Hacker会打破沙锅问到底,Hacker会创造。好的Hacker不会忍受空调过冷而没有行动,更何况是代码这个纯思想的世界。

2. 要问正确的问题。

问正确的问题比解决问题更重要。今天我看到大家问的问题都是如何在Ad上打标签,如何补一个有一个漏洞的问题。我问大家为什么需要在这里纪录,大家说是因为另一个设计。但有没有问如果不是这个设计会是怎样?可能会需要解决的问题更多,或者会更少。但不敢去质疑设计,把自己捆在一个地方,让我感觉到大家在思想的世界里面走动的速度好似一个80岁的老头在现实社会走动的速度,半年过去了还没有走出自己的院子。

3. 要聪明的解决。

大家都是聪明人。问问自己,你的解决办法聪明吗?我们不提代码的事情。代码是思考的一种记录而已。聪明,不是脑子好不好用,而是你是不是真的思考过了。什么叫思考过了?如果对于一个问题,你没有进入过面部没有表情,目光呆滞,梦游一样的在办公室里面踱步的状态,我真不觉得你曾经思考过。思考需要象拼图一样,一些清楚了,先放在那里不要动,去看另外一块,然后再半个小时以后把那个想清楚了,再和这一块拼起来(所以最好我还记得那一块,这就要求没有打断)这种快感是Hacker解决问题的方法。现在的做法不聪明。我看到了苦力的影子。我看到了码农在工作,没有看到思想。代码里面没有思想。告诉大家一个非常简单的判断依据:以百姓网现在的代码复杂度,如果你的大多数函数都超过7行,八成你从来没有思考过问题。

我对于百姓网的程序员抱有极大的期望,现在的代码让我及其失望。我愿意和大家一起花时间来理。

最后加一句:好的程序员需要大量的时间才能磨练出来,需要刻苦。我和小排有一个有趣的讨论,小排说,关于Graph API,我周末花了7个小时,为什么下层还没有理清楚,而你却把上层全写好了?我说:我周末写了8遍,40个小时。

就这么简单。

Graph架构图

 -----------------------------------------------------------
  |                       URL Routing                       |
  -----------------------------------------------------------
  -----------------------------------------------------------
  |                    Controller Routing                   |
  -----------------------------------------------------------  

  -----------------------------------------------------------
  |                       Controller                        |
  -----------------------------------------------------------
 -----------------------------------------------------------
  |                     View Dispatcher                     |
  -----------------------------------------------------------
  ---------  ---------  ----------  ------ -------- ---------
  |View Ad|  |Listing|  |Homepage|  |User| |Search| |Payment|
  |View   |  |View   |  |View    |  |View| |View  | |View   |
  ---------  ---------  ----------  ------ -------- ---------
  -----------------------------------------------------------
  |                    Template Engine                      |
  -----------------------------------------------------------
  -----------------------------------------------------------
  |                   Model (Data Binding)                  |
  -----------------------------------------------------------
  -----------------------------------------------------------
  |                  Model/Graph Integration                |
  -----------------------------------------------------------
 ------------------  -----------------  --------------------
  | HTTP Transport |  | PHP Transport |  | Socket Transport |
  ------------------  -----------------  --------------------
  -----------------------------------------------------------
  |         Security/Prettifier/Limit Control               | 
  -----------------------------------------------------------
 -----------------------------------------------------------
  |                      Graph () API                       |
  -----------------------------------------------------------
  -----------------------------------------------------------
  |                          Node                           |
  -----------------------------------------------------------
 -----------------------------------------------------------
  |                          Edges                          |
  -----------------------------------------------------------
  -----------------------------  ----------------------------
  |            ID             |  |        Connections       |
  -----------------------------  ----------------------------
 -----------------------------  ----------------------------
  |           Data            |  |   Algorithm Dispatcher   |
  -----------------------------  ----------------------------
  -----------------------------  --------- --------- --------
  |   Global/Local Namespace  |  |Listing| | Plain | | User |
  |           Conversion      |  |Logic  | | Logic | | Logic|
  -----------------------------  --------- --------- --------
 -----------------------------  ----------------------------
  |     Storage Dispatcher    |  |    Search Dispatcher     |
  -----------------------------  ----------------------------
  -------- --------  ----------  --------- -------- ---------
  |MySQL | |Mongo |  |External|  |Elastic| |Solr  | |MySQL  |
  |Driver| |Driver|  |Driver  |  |Search | |Search| |Search |
  -------- --------  ----------  --------- -------- ---------

Database Driver 完成所有与具体的数据库服务器之间的接口。 这一层以上不会再出现任何babel_topid,tpc_bak2, attributeData这样的字符串了。

Storage Dispatcher, Search Dispatcher根据对象类型分配driver.
这一层以上不应该有任何地方知道数据存在哪里,如何存储。

Global/Local Namespace Conversion层,保证之上所有的对象都是用GID访问。
这一层以上不应该有任何地方能够看到lid(Local ID),所有ID都是唯一的。
这一层一下不应该知道有global ID的存在

Data层,基础数据类,所有数据从它而来。完成Versioning等

Algorithm Dispatcher层,根据不同上下文选择合适的connection逻辑
这一层之上不应该知道任何业务逻辑(这里使用Strategy设计模式,并不产生混乱)

Listing Logic等层,提供置顶,排序,去除等各种listing业务逻辑

Search Dispatcher层,把Query分配给合适的Search提供者
这一层以上不应该知道搜索由谁提供
这一层以下不应该知道任何逻辑

Edges层,解析id,和id的各种连接。
这一层之上把conn就应该当作数据的一部分,不作区分。

Node层,Graph的基础数据层

Graph层,提供graph()函数调用,以及对于Graph的命令解析,提供斜线分割的语法。

Security层,保证API的调用安全性,访问次数,对象组装等最后包装工作

Transport层,提供各种连入Graph API的方法。

Transport层以上是示意图,并没有仔细推敲,大概描述使用Graph API的场景

我思考的百姓网类目用户模型

我把用户分类三大类,并使用如下态度

* 坚决保护熊猫用户

* 允许核心用户发展

* 收费限制污染用户

(骗子违法坚决打击,不在用户模型里面)

熊猫用户是我们想要的用户。

* 在二手里面,就是哪些处理东西的宅男,卖宝宝东西的妈妈等等;
* 在二手车里面,卖自家二手车的车主;
* 在工作类目,直招的50人以下的小企业;
* 在房屋类目,房东直接租房,卖房的用户;

实在找不到一个更好名字,来表达,姑且用熊猫来代指。他们是相对弱小的群体。

在未来,我们有可能会为了收入等压力转变我们专注的重点,我们现在就要想好去除这种可能性。

这些本地的,个人化,社区化的熊猫用户是我们的根基,服务他们是我们建立百姓网的原因。我们需要尽一切我们可能去保护他们,让他们享受到我们能够提供的最好的服务。这包括:

* 用户产品以这些用户为原型,为这些用户优化;
* 市场上把这些用户作为目标用户,获取和激活这样的用户;
* 销售原则上不需要打扰他们,通过在线自助完成;

另外一类是污染用户。这部分用户是会威胁到其他用户生存的那种类型。

* 在二手里面,就像回收,全国卖山寨电脑等商家意味非常浓的商家;
* 在二手车里面,是高危的黄牛(??需要确认)
* 在工作里面,是职介,这类高危
对于这部分用户,哪怕他们全都消失,我们问题不大(但没必要有洁癖和人家作战);他们如果过于繁荣,其他用户的生活空间将被污染。对于他们,我们将进行限制,并且大胆的,大力的收费,通过收费控制污染。

中间的核心用户层是仔细考虑过的。我们必须在清晰的内外两圈内设置足够大的一个缓冲区间,以避免非此即彼;如果没有这个区,就会出现只要确定不是我们要的熊猫,就一定污染这样的问题。核心用户是生态系统中必然存在的。我们不为他们优化,但必须允许他们生存。

* 二手车里面,他们是车商
* 工作里面,他们是中大型企业,连锁企业,派遣公司
* 房屋里面,他们是中介
对于核心用户,我们的态度是“允许核心用户发展”,但一定不是“专注核心用户”。我们所有的优化,应该以熊猫用户为主。

我们在用户和listing层面,不再做角色划分,不分为“个人,商家”,或者按入上三者分层。拿出一个用户辩论到底是三种情况的哪一种是没有意义的。我们实施的方法是按照每一类用户的喜好做产品,做市场,设计规则。比如按照熊猫用户的使用来限制总发帖数让他们正好很好用。就好像我们只管扔竹子,而不用区分下面的是狼还是熊猫。

这个层次对于各个组织的影响:

* 战略组:断分析市场情况,确认我们的三层各是哪些人,确认我们战略正确
* 市场组:获取和激活熊猫用户;吸引核心用户;忽略污染用户
* 产品组:为熊猫用户做产品
* 营收组:对污染用户重度收费;对于核心用户收费;对于熊猫用户,自助收费

百姓网对开发者的风水

经过一段时间观察,我发现百姓网的办公室对于开发者来说,风水不好,需要改变。

如果不信,问大家一个问题:如下两个场景更接近于你的工作状态

1)自己坐在竹林里的亭子里,小风在吹,我在写程序;

2)自己坐在人民广场地铁站里放了一张桌子写程序。

我觉得我们有变成第二种的倾向。如果一个开发者认为自己心神不宁,惶惶不可终日,就是开发的风水不好了。如下是我认为风水的问题:

1。会议。这个在《入境和入世》里面提到了。中途打断的会议一定要干掉。不仅仅是有形的,我们为了沟通把人放在一起,有的时候需要阶段性的把人分开。

2。上线。我忽然发现一个比会议更加吓人的打断大家工作的事情了,就是下午5点的合代码时间。到了接近下午5点的时候,大家就开始心神不宁了,因为即使和自己没有关系,5点的时候也要去看一下,看自己有没有被影响。我们必须把合case这个步骤干掉,用Git等持续集成的办法,没有集中的合代码操作。

3。邮件。我看到发到All@baixing.com,youqu@baixing.com,还有engineer@baixing.com的邮件大家回得都很及时。这是严重的分心的东西。以前在公司只有二十个人的时候,online的异步的沟通方式其实活不下来的,一周没有新帖子的论坛是没人看的,没人看的论坛更不会有新帖子的,所以用了邮件这种几乎是唯一可行的工作方式。现在是时候改动了。我们必须开始用相对更现代的沟通方式来做事情了。

4。开放的座位。同理,这个也是对于小公司合适,在人多的情况下就没法用了。原来听一耳朵的声音是信息,人多了就已经成为噪音;原来随便抓一个人是最有效的沟通方式,现在人多了,变成持续的抓人,且方向不同。不规律的不同方向的信号叫做噪音。重要的打断不仅仅是打断,雪上加霜的是因为人多导致的打断的不规律性。

5。工具。当工具不顺手的时候我们常常以为工具是不必要的。我们现在做很多东西不是最简单的,比如必须有bugfree才能上线等等,都是工具束缚了生产力。我们不然大家直接拿手抓吃的,但也不能给人家两个榔头让大家夹菜呀。工具是程序员风水很重要的部分。

让我们一点点的把这些风水改变。如下是我的解决方案:

1。对于工具组,一周正式会议必须不多于两次,工作方式灵活。
2。率先使用git,不参与上线。
3。设立公司内blog,用blog代替all
4。座位隔离,在1801办公
5. 工具组做足够好的工具,给大家用。

建硕

为什么大家都在加功能

小排问了我一个问题,为什么各个创业公司的产品都要拼命加功能。我当时还没有特别好的回答这个问题。现在我有了更完整的答案。
说到功能,我们先要从技术开始。技术就是做事情的方法。如果你找到了一种比大多数人更好地做事情的方法,你就有了更先进的社会生产力。比如1200年的佛罗伦萨,它的财富就是由发明了一整套的先进的纺织机开始的,作为一个城市,他们比欧洲全球任何国家都能够更便宜的织出更好的布;1500年的荷兰,开始仅仅因为发明一个小刀可以一刀切的剖开鲱鱼的肚子,去除内脏并且直接放到盐里保存;之后他们又发明了肚子大,甲板小,不带火炮的专用商船,把运输成本降低到英国人的一半,成为海上马车夫;更不要说1700年以后英国的以蒸汽机为代表的工业革命,以及以电气为代表的第二次工业革命,以及发端于美国的以计算机信息技术为代表的第三次工业革命。简而言之,科技不断发展,生产率逐渐提高,就是过去发生的事情。

但问题时,技术的前沿移动得非常快,非常非常快。在过去曾经让自己占据先机得技术,很快就会成为社会的平均生产力。现在有一台蒸汽机,或者大肚子商船仅仅是复古,而不是科技得象征。科技不断向前飞奔,这就要就大家都要努力向前跑,不断寻找现在最难的问题,应用最广泛的问题,去解决它。这个竞赛中,跑在最前面得一定是创业公司,不是因为他们小,是因为他们快。

在互联网领域,技术的前进更加明显。越来越多的高科技在几年里面就民用,现在一个iPhone的技术能力和存储空间几乎是互联网开始时候的一台服务器,以前公司起家的核心的技术,非常快的变成大家都能用的东西,比如搜索,比如数据库,比如BI,比如前端框架。

以存储为例。原来有一个数据库(FoxBase啥的),先进得不得了了,现在普通的MySQL,NoSQL存储已经司空见惯,连上T的存储都易如反掌了,我们必须努力去解决更难的问题,无论是更大还是更快,或者更方便。以分类为例。

作为中国第一家,建一个网站,让大家可以在网上自己交易已经远不是什么新的生产力了,大数据量的时候保证信息质量,同时又可以最简单的发布,这是难题,需要解决;我们不断的面临以前从来没有人解决过的问题。不持续解决这个问题,其实就是把科技前沿让出来给别人解决。

技术的前进,就是做事情的方法的提高是必然的,而这种必然常常以功能表现出来。有大量的提高时没有界面的功能,比如Google的搜索,百姓网的骗子比例减少,的;还有大量的更好的做事情的方法是有界面的功能,比如按地域产照等等。加功能后面,必须是更好的做法来给用户他们要的东西。

理解这点,我们需要做到:1)挑难的做。有两件事情可以做,一件相对容易,对用户的帮助也小一些;一件相对难很多,对用户的帮助也大很多。我们一般情况下应该挑更难的。难的常常就是技术发展的地方。2)加没界面的功能也是加功能。3)从这个角度来说,的确我们需要不断的添加功能。创业公司如果不往前冲,很快会远离生产力最高的前沿,离开了这个阵地,创业公司就没有什么活路了。毕竟,创业公司有些象荷兰的商船,或者动物界的蚊子,是放弃了所有的武装,为了更快的速度而选择没有任何自卫能力,如果速度也没有了,就什么也没有了。

开发者的办公环境

一个好的开发者的办公环境是什么样子的呢?

  1. 安静的。安静的要死的那种环境。我不介意要戴上耳机听听音乐,但背景一定要安静下来。
  2. 风水好。所谓风水里面让人心里安静的那些因素都需要有。背后最好有柱子,有屏风可以看不到别人,可以安静的自己呆着。最好的状态是一人有一个办公室,隔离起来,但如果达不到也要有独立的空间。用盆栽的小树把自己围起来是一个好主意。(Amy,我决定用9盆我旁边的那种小树把我的座位围起来。请帮忙)
  3. 一流的网络环境。网速要快,默认翻墙,稳定。
  4. 有饮水机,有沙发,可以发呆,可以睡觉。必须有窗户,但要有完全遮光的帘子,以遮挡外面的光线。同时走路10步以内必须有一个可以向远处眺望的地方,让自己的眼睛可以休息一下。
  5. 不规律的时间。一定要故意做出点不规律出来,不规律不是重点,重点是不要让规律阻挡思考的自发节奏。当自己在努力写一些东西的时候,应该让自己写完,而不管是不是午饭时间。如果自己在一个地方卡住的时候,不要等到下班再休息,就应该在沙发上躺一下。如果需要,晚上晚点走,早上晚点来也是好主意。
  6. 耳机。耳机是一个非常好的表达不要让大家打扰的办法。在工作的时候必须尊重戴耳机的人的选择,并且形成一个惯例。
  7. Herman Miller Aron椅子。这是必须的。必须的,不要试图争辩。
  8. 两个屏幕?这个我还不是很确信。在我变成的年月里面,从来没有用过两个屏幕,但是或许有人需要。硅谷三个屏幕似乎是标配。
  9. 可调节的大桌子。桌子的高度如果可以调节最好。毕竟在全世界那么多的参数中间,这个和自己的关系最为紧密。
  10. 台灯。这个可能会被忽略,但是在晚上非常有用。如果房间的灯光关上,把台灯打开,这是一种非常好的入静的状态。放心,对于正在写东西的developer来说,这个状态决不会睡着。
  11. 无数的插座。没有比临时找不到地方插一个新的充电器更浪费程序员时间的了。

最后,这个办公室必须至少比程序员的家里舒服。必须的。所以按照一个最舒服超越自己在家里办公的规格设计就好了。

Baixing Graph API 0.2 发布

各位Hacker们,

今天乐高时间,我们将要发布一个还没有成型,但是可以初步展示我们要做的东西。大家可以自己先玩一玩。在给大家尝试的地址之前,我先说一下背景。

程序员的工作其实是增加社会财富。

社会财富的增加 = “效率提高” x “杠杆”。

“效率提高”是指是不是有更好的方式解决问题;“杠杆”是指这个提高会被多少人使用。单纯的提高效率如果没有足够长的杠杆,就像自己把自己的自行车洗干净,并没有对社会产生太大的影响;而在百姓网写一段程序,劳动量和洗自己一辆自行车一样,但杠杆长得多。这个杠杆,就是百姓网工程师每一个改动会被成几千万人使用。我们的一个小时劳动会带来几千万人每人节省或者浪费一分钟,这是巨大得社会财富的增加或者浪费。

而还有一个杠杆,就是我们的程序员的工具。工具的每一点提高,就会带来二十几个开发人员的效率的提高,再乘以几千万人,这个杠杆非常的长,产生的影响非常大。这就是工具组的产生的原因。

工具组小排和Hax花了一周的时间,把我们的第一个产品,Graph API的Alpha版本推出。这就是让大家用更加容易的方式访问到百姓网的所有数据和所有功能,且开始尝试建造新的语言,让大家更快的表达要表达的东西。

说到表达,更大家分享一个有趣的例子。前天学会一个新单词:Gape。原文是”I stood there gaping for a few seconds”。 Gape啥意思呢?一查字典,意思是:Stare, with mouth widely open。其实,如果学过编程的话,你会发现这是一个函数定义,

function gape() {

Stare();

Mouth_Widely_Open()

}。

如果你继续查Stare这个函数,定义如下 :

function stare() {

return directly(fixedly(look());

}。

也就是说,语言本来就是不断的定义,产生新的语言。如果小学生,会说look,或者会说“look fixedly and directly”, 如果啰嗦一点的小学生或许会精确的描述为: “look fixedly and directly, with mouth widely open”。但会用gape这个已经定义好的语言,就比啰哩啰嗦的说一大堆是更高级的语言,更加高效的表达了意思(风险是语言版本比较低的人会在脑子里蹦出来undefined function错误)。你会发现当一个人开始用成语和典故的时候,他的表达能力在加强。刚才的例子,gape是比stare更高级的语言,stare高于look,而look高于更底层的,大家没有听说过的语言,叫gaze。

而我们现在的语言,每一个函数,之所以那么长,那么恶心,那么读不懂,就是因为我们只会用php给的那些语言,那些语言不足以让我们表达。我们需要不断的定义class,就像miniChaoge一样,而且要让其他人使用这些class,功能,工具,我们的效率才会提高,才会往高级语言方向前进。

工具组要做的事情就是造语言,造函数,造工具,让大家能用一个词表达,就不要用那么多的词。

好,下面开始讲Graph API.

造语言,一定从最简单却最常用,且最麻烦的地方开始。这就是我选择了数据。如果有统一的方法访问到百姓网所有数据,以及他们之间的联系,大家说话一定会简洁很多。Graph API的一个绰号叫“百姓网数据解放运动”。

在Graph的世界里面,任何对象都是平等的,有一个唯一的ID,叫做gid (Global ID),只要知道gid,就可以用如下两种方式访问:

PHP里面,用graph($gid);

在外面,用http://graph.baixing.com/gid (返回JSON格式)

返回的对象包括所有的属性,并且描述了这个对象的所有属性(包括程序定义的,和Meta里面定义的),以及这个属性的所有的连接(比如Ad就有user,category这样的指向另外一个对象的连接,也有comment,log这样的返回一个数组的连接)。

为了更好的理解Graph,你可以想像百姓网的任何一个对象都是一个八爪鱼,向四面八方伸出触角。这些触角写在connections里面。通过在id后面添加触角的名字,你就访问到了另外一个对象(或者一组对象),从那里又是一个起点,可以继续访问。。。

举一个例子,我们从一个广告开始,227812140。

graph(227812140)

返回这个广告所有的属性。它还有如下的edge:

user -> 连到一个用户对象。

category -> 连到category对象

area -> 连到area对象

ip -> 连到一个关于这个ip信息的对象上。

user, category, area, ip等大多数对象有一个ad连接,可以返回一个数组,包含所有的ad

category,area等树状结构有parent,children等连接,还有一个特殊的path,返回从根到自己的所有对象的一个数组,用户拼面包屑用。

未来,会支持百姓网所有的信息,比如

mobile会支持call,就是呼入call centre 的所有log,通化时长,以及接线员工号等。

ad会支持付费的log

user会支持过去7天内,14天内,一年内的pv,pv在各个类目的分布等等飞哥那里有的所有信息,甚至每一行的访问log

这些只需要一些配置和数据准备工作。

大家应该可以看到这个graph的潜力。我们要让所有百姓网有的数据,和互联网上的数据,用统一的方式访问。比如刚才的ip对象,数据是来自于淘宝的,不是我们自己的数据库。比如:wiki:上海,就指wikipedia上面的上海的文章。通过统一了数据,我们让百姓网的开发速度大幅增快。

好了, 现在大家就可以测试了,请从这里开始,随便点击任何的可以点击的连接,并且注意URL的变化。

http://graph.baixing.com

建议大家用Chrome的Json View来看。Graph API Explorer Has正在写。同时很快大家就可以在chaoge代码里面开始使用

来访问数据了。graph的数据比JSON的数据完整很多。

未来:

在这里一定要强调一下,就是这一层仅仅是整个技术架构中间最最底层的一层,叫做数据层。它仅仅代表数据,但是不代表业务逻辑,不代表前端的展示。还有很多这一层之上的东西。我们需要在这一层之上不断的建设新的层,供上层来用。

工具组会在接下来的一周把这个Alpha变成production级别,可以在线上使用。写操作设计数据一致性,会跟随业务重构一个对象一个对象的支持。

jianshuo