2010年7月28日

android和twitter将改变世界

题目有点大了,我想说的是:android+twitter=智能终端,代表未来的发展方向。
我将计算机的历史分成3部分:PC集成计算设备、移动设备智能化、终端智能化。
由于计算机的迅速发展,普通PC已经能够完成传统大型计算设备的功能,在此基础上集成的多媒体等功能构成了当前计算机和互联网的基础。
而随着iPhone和Android的进一步普及,手机将在高级操作系统的基础上完成智能化,而拍照、录像、投影、多媒体、通话等功能将作为模块集成进去。
在可见的未来,终端设备将进一步智能化,至少Android和twitter已提供了实现的基础。
所谓终端,是网络的数据输入/输出模块。而网络,除了狭义的互联网和局域网外,还包含了物联网、通讯网、家庭网,以及水、电、煤气等基础设施网络。
在举例之前,我们先建立两个假设:
1、终端采用Android操作系统,这意味着数据传输能通过TCP网络进行。而终端的自有功能作为模块集成进去。
2、终端采用类似twitter的工具实现与服务器的数据交换。
如果剔除了多媒体文件、日志文件等非核心文件,大部分的数据可依据以下3条等效性假设进行处理:
1) 所有的数据都等同于一定格式的XML文件。
2) 所有的XML文件都可以分解成若干个小的XML文件。
3) 实时处理等同于间隔时间很小的非实时处理。
经过上述处理之后,我们就可以采用类似twitter的稳定消息处理机制来实现终端与服务器的数据传输。

下面我们举两个例子来说明这种可能性。
例一:智能电表。
采用智能操作系统的电表,将跨越电网、互联网、家庭网。
电表的数据以微博的方式定期发给到电力公司、用户。
电力公司在接收到电表数据后,将相关数据和结帐单发送给用户,然后用户进行在线支付和核对。
重要的是,由于数据实现了及时采集,电力公司可以及时了解到电力资源的消耗和分布情况,短期内可以调整高峰的电力消耗,长期可以估算电力的用户需求。

例二:生产控制。
在大型的制造企业,往往采用PLC(可编程逻辑控制器)实现对底层设备的控制和数据采集,而PLC是一种特有设备,需要借助OPC等中间层实现和企业核心系统的数据交换,成本高昂、维护困难。
假设有一种android设备,集成了底层控制的驱动接口,那么此终端可以直接在企业的局域网上进行数据的传输,数据的传输方式可以采用开源类twitter系统。
如果企业的生产数据非常多,可能需要专门设置一台消息服务器,终端通过消息服务器实现与企业核心网的数据交换。

智能终端作为发送端,包括以下功能模块:

业务处理(生成完整的业务数据)

套用模板(将业务数据转换成通用的数据文件)

拆分文件(将大的XML文件拆分,以方便传输)

发送文件

智能终端作为接收端,包括以下功能模块:

接收文件

组合文件(将若干小的XML文件组合成完整的XML文件)

套用模板(XML文件映射为具体的业务数据)

业务处理(分析数据,执行相应的指令)

要注意的是,终端要获得完整的业务数据,必须保证消息序列被严格地按照顺序执行。

作为消息服务器,也要包括以下功能模块:

-  接收/发送文件

-  组合/折合文件

-  套用模板

而对于业务的处理,则可以通过企业总线传递给具体的业务系统。

通过以上的等效性假设,我们发现,企业内的数据传递可通过微博系统完成通讯。智能终端的关键在于,数据传递完全通过标准TCP/IP完成,而设备的业务功能却作为一个功能模块集成到智能终端中。

电子书阅读器产品分析

目前流行的电子书阅读器是Kindle和iPad,但是它们无法在中国成为畅销的产品,原因是:中文支持不好、携带不方便、价格昂贵、电子书资源少。
下面是我对电子书阅读器产品的一些思考,希望对大家有所启发。
一、用户
电子书阅读器有以下的典型用户:学生、深度阅读者、上班族、宅居族,下面分别分析。
1、学生。如果阅读器能够包含课本和习题的大部分内容,那么可以有效减轻书包的重量。但是这会和传统教育图书的发行方造成利益冲突。
2、深度阅读者。目前的电子墨水技术和阅读器设计,还很难取代纸质书的阅读体验,但是电子书的价格优势还是有一定吸引力的。
3、上班族。上班路上的零碎时间,基本上花在了短信、电子书、电影、游戏上了。如果要争取他们,阅读器的便携性和易用性一定要认真考虑。
4、宅居族。用电脑看电子书,阅读体验相当糟糕。因此只要优于PC,就可吸引这部分的用户。

二、内容
电子书可包含以下内容。
1、书籍。主要是32开本的虚构类作品和各类畅销书。
2、杂志。主要是16开本的流行杂志。由于尺寸较大,如果要保留杂志的布局和大幅广告,那么对阅读器的尺寸造成重大影响。
3、报纸。由于内容太多,在制作成电子书时势必要重新排版。
4、多媒体。访谈、多媒体广告等,可以嵌入电子书。如果制作精良的广告作为多媒体嵌入电子书,则可以减少电子书的价格,从而吸引更多人下载。

三、阅读器
考虑到上述用户和内容的特点,阅读器应该体现以下设计特点:
1、便携性。方便携带,其尺寸应该小于32开纸书,可以塞入牛仔裤的裤兜里。
2、同时支持32开和16开,这样可以在不需要重新排版的情况下支持杂志的阅读。建议采用双屏设计,在单屏朝外时模拟32开书,在双屏朝里时模拟16开杂志。
3、为方便使用,只保留HOME、目录、上页、下页功能键,简化使用。其它操作全部用触摸屏完成。
4、硬件支持多媒体,制作时包含多媒体。

四、制作/管理软件
由于电子书阅读需要较多的时间,因此用户并不需要管理大量的电子书。
但正如ITUNES是IPOD成功的秘密一样,制作软件将是此阅读器背后的重要支持因素。
为了体现阅读器的特点,制作软件将包含以下重要功能:
1、单键将32开书保存成电子书,并保持原有的分页,阅读器可同时支持单屏和双屏阅读。
2、单键将16开杂志保存成电子书,将对应页码剪切后按双屏拼接。
3、方便地将报纸内容重新排版成电子书。
4、方便地插入多媒体内容。

五、版权方
版权方的收入来源主要是:
1、电子书的销售收入,由于简化了渠道,减少了制作、发行、库存的成本,定价可以大大低于纸书。
2、电子书的广告收入,象主要依靠广告收入的杂志和周报,广告是电子书的主要收入来源。

六、开发者
如果向开发者免费提供简化版的制作软件,那么开发者可以自己制作公有版本图书和博客等数字化内容,从而丰富电子书资源。

七、电子书市场
在制作软件的配合下,同时向版权方和开发者开放电子书市场,可以快速有效地增加电子书资源,并且方便用户检索。
用户通过触屏操作,进行电子书的搜索和下载。
阅读器集成WIFI/3G模块,可以直接连接电子书市场进行电子书的下载。
用户可以通过PC进行个人帐户的充值。

我认为,电子书阅读器仅仅是用户终端,要想获得巨大的成功,除了终端要给用户带来出色的阅读体验外,还要做好制作软件、电子书市场等配套工作,象iPod一样做成一个配套工程。

2010年7月26日

资源守恒定律

本文试图论述一个简单的经济学命题:在一定的时间范围和一定的流通空间里,资源的数量是守恒的。
这里的资源借用了经济学概念,既包含自然资源,也包含人力资源。

先以时间作为变量举一个例子。
股票,可以看成是对未来的投资。社会财富积累起来以后,主要流向是消费和投资,消费是将资源投入当下,投资是将资源投向未来。
考察一下股市泡沫的过程。假设大家都认为10年之后新能源受到追捧,因此数以千亿的钱流向新能源领域,那么这意味着什么呢?首先,大家压缩消费和其它领域的投资,因此当前的资源数量减少了。10年以后,如果新能源成功了,那么当前的投入加上新开采的资源,从而资源的总额大大提升,社会财富大大增加,进而股票得以升值。如果新能源失败了,那么没有带来新的社会财富,股票所购买的未来预期没有得到实现。
从某种角度来看,经济周期可以说是对未来资源预期的一个调整过程。在市场经济的模式下,资源的计划有一个提前量,商品在交易之前就进行生产,因而要事先估计未来的销售,从而根据对未来的判断而决定现在的资源投入。在经济繁荣的顶峰,在流通领域投入的资源数量大于未来一定时间内实际的需要,因而你在当前提前享用了未来的资源,在当前资源有盈余,而在未来资源有亏损,所谓的卯吃寅粮,后人还前人的债。
实际的例子是美国的次贷。大量的底层民众用华尔街的钱提前有能力买到了房子,然后用房子的升值能力作为抵押换银行的按揭,银行又将抵押卖给国外的基金。泡沫前后的资源平衡表里,美国开发了大量土地,民众享用了几年房子,基金损失了大量的钱,而华尔街得到了大部分的钱。

再以空间作为变量举一个例子。
全球化可以说是资源在全球流通的一个典型例子。假如一年之内全球的汽车销量是非常稳定的,那么美国企业可以选择在美国生产,也可以选择在中国生产。假如汽车厂为了降低人力成本选择在中国生产,那么有大量的美元投资和元器件采购也转移到中国,那么在全球的资源平衡表里,部分资源从美国转移到了中国。
从美国全局而言,占领金融、高新技术、农业等产业,可以实现核心竞争力,将制造外包可以实现全体资源的有效利用,这从经济上而言是正确的选择。但是就政治而言,制造产业工人是一支影响投票的政治力量,政治人物必须考虑他们的立场。因此资本家从经济角度选择制造外包,而产业工人和政客却从政治角度坚持本地生产。

最后举一个时间空间作为综合变量的例子:中国房地产。
中国的房地产是一个供求关系没有得到充分体现的市场,因为最大的资源-土地,是控制在政府手里的。
从时间的角度而言,作为城市化的一部分,房地产的需求不断上升,与此同时,土地供应的增长远远跟不上市场的需求,因此长期而言房价会不断地上涨,除非供求关系得到平衡。
那么为什么土地供应受到限制呢?这是因为从空间的角度出发,土地资源的数量是有限的,供应商品房的土地增加了,那么同时耕地的面积就减少。那么为了保住所谓的18亿亩耕地红线,商品房开发所需土地的供应必然受到限制。
当然有经济学家说了,粮食可以进口嘛。然而这就和上面分析的汽车例子一样,经济上正确的选择却是政治上不正确的选择。
由于我国选择了城市化(缩小农村,扩大城市)而不是城镇化(就地发展农村),事实上造成了这样的资源分布格局:农村的资源向城市汇集,小城市的资源向大城市汇集,最后由于全球化的作用,新兴经济体的资源向发达国家汇集。

2010年7月25日

边缘人

多年以前,我在杭州组织过一次碟友活动,大家一块买DVD、看电影。期间有两人刚开始并不说话,后来和我搭起话来就说个没完。后来老婆问我怎么回事,我说他们平时很少社交,所以一旦碰到谈得来的人就特别来劲了。
这种处在边缘状态的心理我是最熟悉不过了。
我自小生长在农村,5周岁就下地干活了,然而我一直对于干农活不上心,事情做不好,许多种田的常识都不知道,力气又小,所以常常被别人嘲笑。而我从小就是书呆子,书能够让我废寝忘食,所以一旦碰到同样喜欢书的人,就让我非常地高兴了。
大学里学理科,然而大多数时间都是坐在最后一排看文科的书,所以和周围的同学很少有学业上的话题,还好我兴趣广泛,足球、录像、台球等,所以有不少人一块玩。
我差不多有10年的网龄了,在网上我注意到一个现象,就是平时很少有社交的人,在网上却非常地活跃。
记得《约翰-克利斯朵夫》里讲,一位退休音乐教师,千里迢迢地过来,只为了和克利斯朵夫相聚,一起讨论共同关心的音乐话题。
3年以前,在做一个社交网站的时候,我认真地分析了传统社交圈和兴趣小组的区别。前者如家族、公司、学校,往往有利益的纽带在其中起作用,而后者往往是一种心理的需要。
我们每一个人,在社交圈里被贴上家族成员、同事的标签,然而一旦我们以内心深处的形象示人,则可能成为他人眼中的陌生人、边缘人。
随着社会的进一步分化,我们与别人的关系更加短暂,更加不稳定。
然而所谓的主流人群,也在经历一个不断被分化的过程。
当我们的祖先还依靠狩猎为生时,种植农业的部落就是边缘人。
当大清帝国被西方列强舰炮轰开大门时,我们仍视工业化的西方人为蛮夷之邦。
观测天象的古代科学家被市集上的人们嘲笑。
希望用音乐记录心声的莫扎特被宫廷音乐家捉弄。
电脑天才曾经被社会视为异类,然而计算机和互联网正在改变所有人的生活。
商人曾经被主流无数次地打击,然而现在商人却成为膜拜的偶像。
工业化、现代化、全球化,正在进一步分解传统文化和社会主义文化赖以生存的土壤,资本主义在带给我们自由的同时,也带给我们孤单。
边缘人和主流人群的界限有时会很模糊,因为主流人群也容易被政治力量、经济活动等边缘化,而边缘人有时反而能引导主流。
也许互联网是上帝给边缘人群最好的礼物,它取代了传统的信件交流等,能够很方便很廉价地帮助我们抱团取暖。

2010年7月21日

日常生活的幻觉

我生长在农村。奶奶、父母、邻居有时会讲起从前的事情,他们的讲述渐渐带给我一种印象,就是这世界是一成不变的,世界反复地轮回,春耕秋种是永远的规律,而人类的繁衍也近乎遵从与自然一样的规则。即便是巨大的变革如外族入侵、王朝更迭,他们也平淡地称之为变天,就好象难以预测的天气一样,尽管令人讨厌但不会改变自然的总体节奏。
长大以后读到过一位历史学家的心得,他认为文明就好比一条河流,平凡的人们生活在河的两岸,偶尔有干旱偶尔有洪水,但一旦恢复平静,人们又心安理得地按照惯常的节奏生活,因此古老的智慧永远能发挥作用。
后来我又读到过一份令人心惊的报告,说大多数现在英国的居民,都可以追溯到中世纪时的数百个祖先。也就是说,中世纪时的多数家族失去了繁衍的机会。
进化论很好地解释了很多令人吃惊的事实,但它与人们的直觉相违背。要理解进化论,要理解变化何以发生,就必须理解漫长的地质时间。而我们直觉地用我们的空间和时间尺度去丈量周围的世界。
当我们未成年时,我们用父母的世界观保护自己;随后的青春期我们勇敢地接受一切变化但力量有限;当人到中年掌握了大量的资源,然而此时他已害怕改变自己。
我们这个时代发生的诸多改变,让许多传统的智慧已经变得可笑,比如第一批按揭买房的人往往成为富翁,而老老实实存钱买房的人与自己的梦想越行越远。
我们的祖先依靠父辈相传的智慧就可以保平安传香火,而如今要保家人一生平安,你必须对今后数十年中国的经济政治发展要有一个清醒的认识。
在这个迅速变化的时代,假装日子只是日复一日地重复,假装自己的所学永远不会过时,这不过是一厢情愿的幻觉而已,尽管这幻觉带给你平静,然而一旦惊醒只会更加地痛苦。

2010年5月10日

我的GOOGLE READER订阅种子



我每天有超过4小时的时间上网,主浏览器是CHROME,主要网站是GMAIL/GOOGLE READER/TWITTER/DOUBAN/DOUBAN电台。
其中GOOGLE READER花费的时间可能最多了。
下面介绍一下我订阅的一些FEED,和大家交流一下。
我有两个TAG,是与电影相关的,一个是MEIJU,一个是MOVIE。
其中MEIJU这个TAG,下面放的是自己正在跟的美剧电驴资源,如24小时、迷失、未来闪影、生活大爆炸、太平洋战争、周六夜现场、荒野生存、神秘博士这些剧集在VERYCD发布页面的地址,这样就不会错过新的剧集了。
MOVIE这个TAG,主要是4类,最新放映电影、最新电视剧集、VERYCD更新、伊甸园论坛。最新电影是由MTIVE时光网提供的,通过有道输出FEED。最新电视剧集更新来自http://ezrss.it/feed/,每天都有大量更新,而且用户非常多。VERYCD提供搜索结果RSS,这样就产生了我关注的BDRIP和720P、BBC、NHK这4个FEED,而伊甸园论坛提供了我关心的24/LOST最新下载页和讨论贴,特别是24小时,由于每周定期发布,而且通常网友会迅速将资源传到国内的网盘上,速度比BT和电驴快得多,因而我一般是看到RSS更新后,再找到下载专用贴。
FRIENDS这个TAG主要是我的社交圈内朋友的博客和相册。
MUSTREAD主要是每天必看的博客,如译者、东西、可能吧、韩寒、HECAITOU、阮一峰、KESO、FENNG、月光。
BLOG主要是个人博客,一般个人博客更新不会很频繁,因而避免和群博放在一个TAG下,以免漏了好文章。
GROUP是群博,如天涯海阁、煎蛋、译言、玩聚、松鼠会。
PP标签放PPMEME机器人的TWEETS,以及一些推友在IMG.LY发布的照片。
ECO标签放一些经济学博客。
REF标签放一些牛人的TWITTER收藏,虽然这样有些不厚道,但是受益很多。
SLEEP标签放一些催眠佳片,主要是优酷的大师文艺片,通过专辑得到RSS。
最近活动放自己重要社交站点的RSS,然后通过GOOGLE READER输出,可以得到RSS小工具放在博客上。
FUN标签放一些好玩的视频。
NEWS放新闻站点FEED。
BBCVOA放英语听力音频FEED。
FML放段子、糗事。
VIVID放AV种子,主要是通过TWITTER收集的。
YOUKU放YOUKU上收藏的专辑。
YOUTUBE放YOUTUBE上收藏的频道。


2010年4月20日

过去一年中文推特圈的几件大事

1. #cn4iran
在09年,关于伊朗大选的标签#iranelection一直是TWITTER上的热门标签。
09年12月27日,在伊朗发生了大规模的流血冲突,越来越多的中国人开始在推特上关注伊朗的命运。现场的照片和视频越来越多,鲜血也使得更多人变得亢奋。
这时,著名网友安替@mranti建议推友统一使用#cn4iran标签跟进此话题,cn4iran的意思是China For Iran。
有网友说,中国政府和伊朗政府站在一边,而中国人民和伊朗人民站在一边。
越来越多的中国推友的关注,使得#cn4iran标签在当夜上了TWITTER热门榜的TOP10,和#iranelection标签比翼齐飞。
中国推友的关注,是因为这个事件太容易使人联想到89事件了。而中国政府向伊朗政府输出网络封锁技术,使得两国网民对网络封锁的体会感同身受。
后来,cn4iran.org网站及时地出现了,这个网站能够抓取TWITTER上#cn4iran的搜索结果,及时输出到网页,从而让墙内的网民也可以迅速得到相关的信息。并且此网站还在首页上放了TWITTER的墙内注册地址,帮助更多人的人能够使用TWITTER。
参考文章:FT中文网《Twitter上的国际主义》: http://www.ftchinese.com/story/001030513
RT @PKUbuzheteng 什么是国际主义?就是全世界的草泥马联合起来,就是推特上众人跑到人家伊朗的标签里面打酱油声援。
RT @bao3 重大消息:中国政府支持伊朗现政府,伊朗推友说:这不代表中国人民。
还有一句被广泛传播的伊朗诗歌:你可以摧毁花朵,但你不能阻止春天的到来。每一棵你揉碎的鲜花,我们将重新播种。

2. #GoogleCN
2010年1月12日,GOOGLE在官方博客发布声明,将停止谷歌中国的审查机制,并与中国政府重新进行谈判,参见:http://googleblog.blogspot.com/2010/01/new-approach-to-china.html
此声明说作此决定是因为谷歌中国的GMAIL服务受到有蓄谋的、针对人权活动家的恶意攻击。
消息一出,一片哗然。
众推友纷纷就此话题发言,以#GoogleCN作为标签,很快在全世界范围内受到广泛关注。
同时,有不少网友约定到北京谷歌中国的总部献花,却被清华科技园保安以“非法献花”为由受到干扰。
1月13日,百度首席产品设计师孙云丰发表博客《谷歌市侩,我感到恶心》。
2010年3月23日,在经过二个月的谈判后,谷歌声明将在大陆的服务器全部转移到香港,将GOOGLE.CN域名中转到GOOGLE.COM.HK:
http://www.google.com/press/new-approach-to-china/update.html
当天,#GoogleCN标签又受到广泛关注,网友自发组织给谷歌告别。
同一天,百度老总李彦宏在贴吧发贴《大家说,百度应该进军香港吗?》。
网友送给GOOGLE的雅号“骨哥纯爷们”。
参考可能吧文章:https://www.kenengba.com/post/2812.html
参考译者谷歌文集:http://docs.google.com/leaf?id=0B3C6I8b9sUt9ZDQ2ZGQ2OTUtN2E5My00NzVkLTg4ZTQtNDA4MmEzOGViNmFk&sort=name&layout=list&num=50

3. #netfreedom
2010年1月21日,在谷歌声明9天之后,美国国务卿希拉里发表题为“网络自由”的演讲,爱到中国推友的广泛关注,希拉里还特别邀请@mranti, @isaac等知名网友到现场聆听演讲,并在演讲之后与相关专家互动。
在国内的网友则通过CNN的在线直播观看。
同时,一个著名的翻译团队开始浮出水面。@xiaomi2020组织几个志愿者,对希拉里的演讲在推特上实时翻译。
这是美国国务院提供的官方译文:http://www.america.gov/st/democracyhr-chinese/2010/January/20100121212440eaifas0.9105341.html
这是译者团队整理的现场译文:http://docs.google.com/View?id=dgmrnk3b_13f7qzfxcc
外媒对译者团队的报导:http://www.technologyreview.com/web/25032/

4. #2015
#2015  年,我到和菜头家里做客,看到地板上的网线和正在闪烁的路由器,我大喜过望。“想不到你家里还能…!”此时菜头夫人在一旁说:“这是一毛不拔送的新款灯具,完全模拟有互联网的日子。”   via @wangpei
#2015 年,我到王佩家里做客,看到他正打开twiiter,我大喜过望。“想不到你家里还能…”此时王夫人在一旁说:“这是我们家的局域网,我们互Follow,完全模拟有twitter的日子”。 via @lianyue
#2015 年,我到连岳家做客,看到他正在写专栏,我大喜过望:“想不到你还在写啊……”此时连夫人在一旁说:“3年来他没收到过一封信,这是我写给他的,我当读者,他解答,完全模拟我爱问连岳的日子。”  via @beichen
以上3条推出现于2010年3月26日,之后,以#2015作为标签的黑色推开始汹涌地出现了。
可参考@songshinan的这篇博客:http://ssnly100.blog.163.com/blog/static/1156339201022623230296
据推测,@wangpei写此推,是受到两个因素的影响,一是王小波的小说《2015》(https://docs.google.com/Doc?docid=0AehxuQ1jJs7IZGczYmpuc2RfMjg0ZzZkazZ6Y3M&hl=zh_CN),二是前段时间风行的陈冠中小说《2013盛世中国》(https://docs.google.com/fileview?id=0B-hxuQ1jJs7IMjk3ZTU0NDktNTkzMi00MjkyLWJmYWMtYjZkYTBiNWNhMDVl&hl=zh_CN)。

5. @aoi_sola苍井空之夜
2010年4月11日晚,推友@StarKnight发布消息:“苍井空上推了。目前关注者2000多人,她说:‘目标是1万人’。我觉得这目标很容易达到”。
此推迅速在中文推特圈激起波澜,经过@hecaitou,@lianyun等中转后,立刻成为当天的热门话题,令众多男推友热血沸腾,令众多女推友内牛满面。
在短短数小时后,关注苍井空@aoi_sola的网友已突破1万大关。这一夜被@hecaitou称为苍井空之夜。
这位在中国拥有极大知名度的“童颜巨乳”AV女优被中国推友的热情吃惊了,她这样发推:谢谢。在中国我的球迷。 I use a translator in chinese. Thank you for my fans in China.
可以看出,为了方便与中国推友互动,她专门使用了机器翻译软件将日文推翻译成中文推。
此后,她还专门建了一个面向中国用户的简体中文的博客,如以下两篇文章在推特中文圈受到广泛传播:
http://aoisola.cocolog-nifty.com/si_ch/2010/04/post-2368.html
http://aoisola.cocolog-nifty.com/si_ch/2010/04/post-c9bf.html
另外,可参考东莞时报的报导:http://dgtime.timedg.com/html/2010-04/13/content_427081.htm
@hutianyi的博客:http://hutianyi.net/?p=1799
@songshinan的博客:http://ssnly100.blog.163.com/blog/static/115633920103168461287

补充资料:
知心大叔@xiaolai老师写的《Twitter非官方指南》:http://ow.ly/1AyYG
@rtmeme,中文推特机器人,专门转推热门推。
@lianyue,专栏作家。
@mranti,媒体圈达人。
@fenng,IT圈达人。
@wangshuo,老婆推创始人。
最后,请读者FOLLOW我@tallrain,谢谢!


2010年4月19日

房市随笔(九)


此为补遗之三。
前面几篇只讲经济行为,此篇补充政治分析,简单地写几条,不展开了。
一、房地产开发将土地货币化,开发环节相当于土地这一财富的重新分配过程。
二、政府官员、金融机构、开发商的合作,促进了权贵阶层的形成。
三、城市化和城市开发的推动,促进了资源进一步流向大城市,让城乡的差距进一步扩大,这是民粹主义的基础之一。
四、房价上涨远高于工资上涨,造成了大量房奴的存在,并削弱了中产阶级的力量,这是民粹主义的另一基础。
五、地方官员如果将开发城市作为自己家族获利的机会,那么会尽量维护高位房价。反之,如果地方官员更多从政治方面考量,打压房市可以获得民粹的支持。
六、由于社会日益断裂,权贵阶层和民粹主义者的矛盾将更加明显,在2012年的十八大中将得到体现。


使用GOOGLE BUZZ进行小圈子社交


使用TWITTER和BUZZ都有一段时间了,发现TWITTER比较适合消息的大范围传播,而BUZZ更适合小圈子的深入交流。
下面介绍一下如何使用GOOGLE BUZZ进行小圈子社交。
1. 邀请相关人员注册GMAIL。
2. 将相关人员加为好友,并且在GOOGLE CONTACTS里设置在同一个分组里。
3. 在BUZZ里相互FOLLOW。
4. 发布新讨论:在GMAIL里进入BUZZ标签,在消息框里输入内容,可包括文章链接和图片,选择消息不公开,并只显示给特定的小圈子。
5. 其它人在GMAIL的收件人和BUZZ中可以看到此消息,可以跟贴讨论。
要注意的是,BUZZ默认将所有消息都放到收件箱里,对正常的邮件接收造成干扰,以下说明将BUZZ与邮件分离的方法:
在GMAIL中点击"设置">"过滤器",选择搜索条件:包含字词:"label:buzz",下一步,跳过"收件箱",标记为已读,应用标签:(自己定义一个标签,如"buzz2")。设置完成之后,所有自己发布和关注的BUZZ将自动放到此标签中。


2010年4月15日

ORACLE PL/SQL随记



想到哪写到哪。
1. 典型的SQL结构
SELECT
 t1.f1,
 t1.f,
 t2.f3
FROM
 table1 t1,
 table2 t2
WHERE t1.f = t2.f -- 此为两表关联条件
AND t1.f4 > sysdate - 1 --此为数据筛选条件
ORDER BY
 t1.f1,
 t2.f3
-- 建议关键字大写,其它小写,每个表都定义别名,同时通过换行、空白等格式让代码易读。

2. 分组查询
以下分组查询关键字必须在SQL中包含GROUP BY,WHERE作为非分组字段的筛选条件写在GROUP BY之前,HAVING作为分组字段的筛选条件写在GROUP BY之后:
- COUNT()
- MIN()
- MAX()
- AVG()
- SUM()

3. 关联表的方式
- WHERE关联,这种写法方便理解完整的代码。
- JOIN关联,表之间用ON描述关系。
- INNER JOIN,强约束关联,返回值是两个表的交集。
- LEFT OUTER JOIN,左侧表所有的记录都返回,右侧匹配的记录返回,没有匹配的返回NULL,等同于WHERE t1.f = t2.f(+)。
- RIGHT OUTER JOIN, 右侧表的记录返回,左侧返回匹配的记录,没有匹配返回NULL,等同于WHERE t1.f(+) = t2.f。
- FULL OUTER JOIN,返回值是两个表的合集。

4. 合并查询结果
- 用UNION ALL合并多个查询结果集。

5. 限制查询结果集
- 用DISTINCT过滤重复记录。
- 用ROWNUM < N设定记录数。

6. 日期转换
- TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'),将日期转换成字符串,注意HH24表示24小时格式,MI表示分钟格式。
- TO_DATE('2010-04-14 10:14:23', 'YYYY-MM-DD HH24:MI:SS'),将字符串转换成日期。

7. DUAL
DUAL是系统内置的一个特殊表,此表有N多字段,但是只有一行记录,可以理解成一个特殊函数构造,如:
SELECT SYSDATE FROM DUAL; -- 查询系统日期
SELECT 1/3 FROM DUAL; -- 数值运算
SELECT USER FROM DUAL; -- 查询当前线程登录帐号

8. DECODE
使用此函数可以将字段直接进行处理,用法:DECODE(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)。
如DECODE(LISTSUBASSEMBLY, NULL, OPTIONPARTQUANTITY,  LISTSUBASSEMBLY),表示对于LISTSUBASSEMBLY字段,如果其值为NULL,则取OPTIONPARTQUANTITY值,否则取LISTSUBASSEMBLY值。

9. 代码注释
- 用--单行注释
- 用/* ...*/进行多行注释

10. 在查询SQL中可调用用户创造的函数

11. 在查询SQL中可调用的数据集:
- 表
- 视图
- 临时表
- 物化视图
- 远程数据库对象,用@连接远程数据库。

12. 物化视图
- 建议先创建表,包含所有的查询SQL,然而用物化视图引用此表。
- 建议用数据库JOB定期刷新表,对于重要数据,也可以用TRIGGER更新到物化视图。
- 物化视图是一个物理对象,有存储空间,可创建索引。

13. 表数据的备份
CREATE TABLE T2
AS
SELECT * FROM T1
注意创建的新表只包括结构和数据,但是索引和约束会丢失。

14. 用旧表创建新的空表结构
CREATE TABLE T2
AS
SELECT * FROM T1 WHERE 1 = 0 -- 此条件将返回0条记录

15. 用DBMS调试存储过程
- 在存储过程中包含dbms_output.put_line('P1='||P1); 其中P1是存储过程参数。
- 打开客户端的COMMAND WINDOW,SET SERVEROUTPUT ON;
- EXECUTE IMMEDIATE存储过程,DBMS的消息将显示到窗口中。

16. 最后,围观一坨300多行的单句查询SQL:
/*----------------------------------------------------------------------------------

Modified  by   : Tripti Mandal
Date               : 31st Mar 09
Organisation  : TCS
Purpose         : To get validation information for workorders on a particular the production line no
e.g
Option Part Mismatch( Item assembly configuration checks)
BOM Not Download

Modified  by   : Tripti Mandal
Date               : 23-Apr-09
Organisation  : TCS
Purpose         : To Fix PRDB_G00138326(Unable to download 
                           workorders from multiple lines at the same time)


Modified  by   : Rahul Sapar
Date           : 15-June-09
Organisation   : TCS
Purpose        : SubAssembly changes


Modified By : Amitava ( TCS )
Modified On : 9Jul07
PR : DB_G00142020

Modified By : Rahul Sapar ( TCS )
Modified On : 10Jul09
Purpose : Used Materialized View (COB_MV_DAILY_SCH_BOM) rather then mormal view (COB_V_DAILY_SCH_BOM_28001) to improve performance of SQL - PR : DB_G00142563



Modified By : Amitava ( TCS )
Modified On : 14Jul07
PR :  DB_G00142563

Modified By : Rahul Sapar ( TCS )
Modified On : 26Jul09
PR :  Changed MV from WO specific to WO and Date Specific

Modified By : Rahul Sapar ( TCS )
Modified On : 23Aug09
PR :  To Catch Multiple SubAssemblies

Modified By : Rahul Sapar ( TCS )
Modified On : 23Sept09
PR :  DB_G00146371

Modified By : Rahul Sapar ( TCS )
Modified On : 27Sept09
PR :  DB_G00146418 

Modified By : Rahul Sapar ( TCS )
Modified On : 12Oct09
PR :  DB_G00146418 

Modified By : Taoyun Zhang (BFCEC)
Modified On : 06 Oct 09
Purpose:       Check items discontinued in BOM but effective in IAC, 
Change BOM LEFT OUTER JOIN IAC, INTO FULL OUTER JOIN
DECODE PART FROM BOM OR IAC

--------------------------------------------------------------------------------------*/

SELECT   DSSG.WIPJOBNO AS LISTWORKORDERNO,
           DSSG.SONUMBER AS LISTSHOPORDER,
           TO_DATE (DSSG.BUILDSCHEDULEDATE, 'YYMMDD')
              AS LISTWORKORDERBUILDSCHDATE,
           TO_DATE (DSSG.CUSTOMERREQUESTDATE, 'YYMMDD')
              AS LISTWORKORDERCUSTOMERREQDATE,
           DSSG.CUSTOMERSPECIFICATION AS LISTWORKORDERCUSTOMERSPEC,
           DSSG.CUSTOMERNAME AS LISTWORKORDERCUSTOMERNAME,
           DSSG.STATUS AS LISTWORKORDERSTATUS,
           TO_DATE (DP.DP_BUILD_DATE, 'YYDDD') AS LISTDATAPLATEBUILDSCHDATE,
           OPTIONPARTQUANTITY AS LISTPARTMISSINGINFO,
           DSSG.HOTBUILDINDICATOR AS LISTHOTBUILDINDICATOR
    FROM         (

    SELECT   *
                    FROM   COB_T_DAILY_SO_SCHEDULE
                   WHERE   WIPJOBNO IN (@ListWorkOrderNo)) DSSG
              LEFT OUTER JOIN
                 COB_T_DATAPLATE DP
              ON DP.DP_SO_NO = DSSG.SONUMBER
                 AND TO_DATE (DP.DP_BUILD_DATE, 'YYDDD') =
                       TO_DATE (DSSG.BUILDSCHEDULEDATE, 'YYMMDD') --DSSG.BUILDSCHEDULEDATE
           LEFT OUTER JOIN
              (
           
              SELECT   NVL (WORKORDER, '') AS WORKORDER, -- ADDED BY RAHUL SAPAR
                        DECODE (
                           LISTSUBASSEMBLY,
                           NULL,
                           OPTIONPARTQUANTITY,
                           DECODE (OPTIONPARTQUANTITY,
                                   '0', LISTSUBASSEMBLY,
                                   NULL, LISTSUBASSEMBLY,
                                   OPTIONPARTQUANTITY)
                        )
                           AS OPTIONPARTQUANTITY
                 FROM      


-- A3 begin
(
--SELECT * FROM                 
-- A3 begin
--(
SELECT 

  A2.WORKORDER WORKORDER, --A2.P1, A2.P2, A2.ND,

                                       COB_F_TAB_TO_STRING (
                                          CAST (
                                             COLLECT(DECODE (
                                                        TO_CHAR (A2.P1),
                                                        NULL,
                                                        'BOM Not downloaded',
                                                        TO_CHAR (A2.P1) || '-->'
                                                        || TO_CHAR(A2.P2 || '-->'
                                                                   || TO_CHAR (
                                                                         A2.ND
                                                                      ))
                                                     )) AS COB_T_VARCHAR2_TAB
                                          ),
                                          ','
                                       )
                                          AS OPTIONPARTQUANTITY,
                                          a2.listsubassembly

FROM
-- A2 begin
(
SELECT
  *                                                                           
FROM  
(
SELECT * FROM
-- A begin                 
                 (  
                 SELECT *   
                 --WORKORDER,

                                FROM   

-- X begin                                         
                                (
                                
                                SELECT   BOMIAC.WORKORDER,
                                                 PARENTPART.PRODUCTNO P1,
                                                 CHILDPART.PRODUCTNO P2,
                                                 BOMIAC.quantity ND
                                          FROM   
                                          --(    
                                           
                                 
                                          --(
                                          
                                          
--SELECT * FROM
-- BOMIAC begin
(                                          

SELECT
  DECODE(workorder, null, workorder2, workorder) workorder,
  DECODE(parentproductid, null, parentproductid2, parentproductid) parentproductid,
  DECODE(parentproductno, null, parentproductno2, parentproductno) parentproductno,
  DECODE(productid, null, productid2, productid) productid,
  --DECODE(quantity, null, quantity2, quantity) quantity
  (NVL(quantity,0) - NVL(quantity2,0)) quantity
FROM
(
SELECT   
  --WORKORDER,
  --PARENTPRODUCTID,
  --PARENTPRODUCTNO,
  --PRODUCTID,
  --QUANTITY
  bom.WORKORDER,
  bom.PARENTPRODUCTID,
  bom.PARENTPRODUCTNO,
  bom.PRODUCTID,
  bom.QUANTITY,
  
  ctis.WORKORDER workorder2,
  ctis.PARENTPRODUCTID parentproductid2,
  ctis.PARENTPRODUCTNO parentproductno2,
  ctis.PRODUCTID productid2,
  ctis.QUANTITY quantity2   
  
FROM   
-- BOM begin
(
SELECT   
  DSS.WIPJOBNO AS WORKORDER,
  VBOM.PARENTPRODUCTID AS PARENTPRODUCTID,
  VBOM.PARENTPRODUCTNO -- Added by Rahul Sapar 23 Sept 2009
    AS PARENTPRODUCTNO,
  VBOM.PRODUCTID AS PRODUCTID,
  VBOM.QUANTITY AS QUANTITY
FROM      
  COB_MV_DAILY_SCH_BOM VBOM -- Modified by Rahul Sapar 10 July 2009
RIGHT OUTER JOIN
-- DSS begin
(
SELECT  
  WIPJOBNO,
  SONUMBER,
  STRUCTUREDATE
FROM
  COB_T_DAILY_SO_SCHEDULE
WHERE WIPJOBNO IN (@ListWorkOrderNo)
) DSS --ON DSS.WIPJOBNO = VBOM.WORKORDER
-- DSS end
ON DSS.SONUMBER = VBOM.SONUMBER
AND DSS.STRUCTUREDATE = VBOM.STRUCTUREDATE -- Added By Rahul Sapar 26 July - Made View Shop Order and Date specific rather than WO specific
)
--)
BOM
-- BOM end
-- LEFT OUTER JOIN -- change to full outer join, taoyun, 06 Oct 09
FULL OUTER JOIN
-- CTIS begin
(
SELECT
  WIPJOBNO AS WORKORDER,
  PARENTPRODUCTID,
  PARENTPRODUCTNO,
  PRODUCTID,
  QUANTITY AS QUANTITY -- Tripti 23-Apr-09 , Changed the sum
FROM   
(
SELECT   *
FROM   
  COB_V_DAILY_SCH_CTIS_28002
WHERE   WIPJOBNO IN (@ListWorkOrderNo)
AND ASSMPRODUCTIONLINENO IN (@ListProductionLineNo)
)
GROUP BY   
  WIPJOBNO,
  PARENTPRODUCTID,
  PARENTPRODUCTNO,
  PRODUCTID,
  QUANTITY -- Tripti 23-Apr-09
)
CTIS
-- CTIS end
ON CTIS.WORKORDER = BOM.WORKORDER
AND CTIS.PARENTPRODUCTID = BOM.PARENTPRODUCTID
AND CTIS.PARENTPRODUCTNO = BOM.PARENTPRODUCTNO
AND CTIS.PRODUCTID = BOM.PRODUCTID
)
WHERE (NVL(QUANTITY,0) - NVL(QUANTITY2,0) <> 0)
) BOMIAC
--) BOMIAC end

      

LEFT JOIN PRODUCT PARENTPART
ON PARENTPART.ID = BOMIAC.PARENTPRODUCTID
LEFT JOIN PRODUCT CHILDPART
ON CHILDPART.ID = BOMIAC.PRODUCTID
--)
--)
--WHERE   (NVL (BOM.QUANTITY, 0) - NVL (CTIS.QUANTITY, 0) <> 0) OR (BOM.PARENTPRODUCTID IS NULL))
GROUP BY   
  BOMIAC.WORKORDER,
  PARENTPART.PRODUCTNO,
  CHILDPART.PRODUCTNO,
  BOMIAC.quantity

) X
-- X end                                

--FULL OUTER JOIN
LEFT OUTER JOIN
-- Y begin
(  

SELECT   NVL (LISTSUBASSEMBLY, '') LISTSUBASSEMBLY, WIPJOBNO
               FROM                                            -- Add NVL here
                    (SELECT 

         'SUBASSMFAIL' AS LISTSUBASSEMBLY,DSS.WIPJOBNO as WIPJOBNO
    FROM 
    cob_t_daily_so_schedule dss 
    INNER JOIN product p ON P.PRODUCTNO = DSS.SONUMBER
         INNER JOIN cob_t_shop_order_detail sod ON p.productno = sod.productno
         INNER JOIN product_component pc ON pc.productid = p.id
         INNER JOIN component c
         ON (    c.ID = pc.componentid
             AND c.effectivedate <= TO_DATE (DSS.STRUCTUREDATE , 'YYMMDD')
             AND (   c.discontinuedate > TO_DATE (DSS.STRUCTUREDATE, 'YYMMDD')
                  OR c.discontinuedate IS NULL
                 )
            )            
         INNER JOIN product p1 ON p1.ID = c.productid
         INNER JOIN product_component pc2 ON pc2.productid = p1.ID
         INNER JOIN component c2
         ON (    c2.ID = pc2.componentid
             AND c2.effectivedate <= TO_DATE (DSS.STRUCTUREDATE, 'YYMMDD')
             AND (   c2.discontinuedate > TO_DATE (DSS.STRUCTUREDATE, 'YYMMDD')
                  OR c2.discontinuedate IS NULL
                 )
            )
         INNER JOIN product p2
         ON p2.ID = c2.productid AND p2.productinventorytype = 102
         left outer  JOIN cob_t_engine_build_var ebv
         ON ((    
         (ebv.level1option = p1.productno)              AND 
              (ebv.customer = sod.customer OR ebv.customer = 'ALL')
              AND (   ebv.enginefamily = sod.enginefamily
                   OR ebv.enginefamily = 'ALL'
                  )
              AND (ebv.enginetype = sod.enginetype OR ebv.enginetype = 'ALL'
                  )
              AND (   ebv.configuration = sod.configuration
                   OR ebv.configuration = 'ALL'
                  )
              AND (ebv.application = sod.application
                   OR ebv.application = 'ALL'
                  )
              AND (ebv.active = 1)
             )
            )
         INNER JOIN cob_t_item_assembly ctis
         ON (    ctis.parentproductid = p1.ID
         and CTIS.PRODUCTID = p2.id
             AND ctis.variationcode = NVL (ebv.variationcode, 0)
             AND ctis.effectivedate <= TO_DATE (DSS.STRUCTUREDATE, 'YYMMDD')
             AND (   ctis.discontinuedate >=
                                          TO_DATE (DSS.STRUCTUREDATE, 'YYMMDD')
                  OR ctis.discontinuedate IS NULL
                 )
             AND ctis.active = 1
             AND (   ctis.routingnumber IS NULL
                  OR ctis.routingnumber = 0
                  OR ctis.routingnumber = 1
                 )
             AND (ctis.deviatedpart = 0)      --Compare non deviated part only
             AND (ctis.assmworkstation IS NOT NULL)
             AND ctis.assmproductionlineno = DSS.PRODUCTIONLINENO
            )
   WHERE DSS.WIPJOBNO IN (@ListWorkOrderNo)
GROUP BY DSS.WIPJOBNO, ctis.assmworkstation,p2.PRODUCTNO,p2.productinventorytype
HAVING sum (c2.quantity) > 1
)
--)
) Y
-- Y end
                        ON X.WORKORDER = Y.WIPJOBNO
                        
                  
                        ) A
-- A end
--GROUP BY WORKORDER, P1, P2, ND                        
)
 
) A2 
-- A2 end
GROUP BY WORKORDER,listsubassembly
) A3
-- A3 end     
--)            
                 

)
           ON WORKORDER = DSSG.WIPJOBNO
ORDER BY   DSSG.WIPJOBNO