文章列表
 
2011-08-17 14:10

中央电视台2套节目这两天变成了“百度”频道,连篇累牍,滚动播出,”揭开百度推广背后的黑幕“,今晚还捎上了贴吧。明天不出意外可能还会继续这个专题,有些地方看过之后让人不吐不快,因此写了这篇软文。在此表示本文只表明个人观点,与任何组织机构无关。

央视头天的节目虽然有明显的偏向性,为了得到自己希望的结论,使用精心挑选的材料,并且使用自己擅长的钓鱼找托等手段曝光了一些凤巢系统的问题,但 是客观地说许多问题确实是存在的。可是这种报道的手法明显不是一家大型官媒应有的做派,更不是一个有社会公德心的媒体所应有的手段。我们都知道媒体喜欢放 大一些细节,因小见大,同时客观公正也是媒体应有的一个必须属性。但是央视在这里倾向性地选择材料,完全无视了百度推广帮助数十万家中小企业主找到了一个 廉价的推广渠道,优化了国内工业界生态圈的普遍事实(在这里暂时不提网页搜索对网民的贡献),片面地强调虚假广告的案例。但是我们知道广告界的虚假广告问 题是一直存在的,地方台各种乱七八糟的小广告和电话直销我们暂且不提,就说央视自己也曾经放过虚假广告(最大的一次就是曾经当过标王的“曲美”)。而在互 联网上的推广链接,它面对的是低门槛的中小企业主,广告链接过去的网站内容是不由媒体(百度)本身掌握的,而是随时可以由广告主自己改动的网页,本身在审 核上就有许多比传统媒体的审核更困难的地方。目前在这一方面,立法、监管、百度自身的审核技术和审核流程确实都有许多需要提升的地方,但是这些不能成为彻 底妖魔化百度的理由。看这个节目简直就是要做到把百度停业整顿,才能对得起互联网的良心。但是事实呢,真的考虑到百度对大部分中小企业主的贡献,对那些需 要在网上寻找所需商品和服务的网民的贡献,功过至少是9:1吧,如果算上百度对普通网民检索信息的贡献,这个1只会更小。

至于第二天的节目则基本上只剩下赤裸裸的攻击了,如果说第一天的节目央视还算是花了些功夫去调研百度相关的系统的话,第二天的一些结论让人感觉完全 是赶工的结果——太不专业,泼脏水都能不专业到让人愤怒……首先是请了cjm,我不知道cjm教授有没有上过论坛,一个论坛出现谩骂之类的言论是可以要求 斑竹删帖的,但是删帖后还要求整个论坛都关掉,合理吗?cjm之前做的事我不评价,但是既然是个教授和公众人物,提出这个提案就应该有这样的心理准备和觉 悟,另外现在天涯和猫扑上还有骂您的帖,需要把这两家论坛也关掉吗?至于掘金项目是什么,建议央视的工作人员自己去好好看看介绍,不要花多少时间。没想到他家居然拍脑门子断章取义,把精准推广的广告和贴吧广告混为一谈,真是让人笑掉大牙。搜狗做假药广告当年是央视曝光过的,怎么突然就这么一脸正义地出现在摄像机前?两家都有失忆症么?

我不想评价某些中小企业主的思想,如果百度推广真得如报道般不堪的话,现在是不会有几十万家广告主还在继续在百度上投放广告的。树大招风,这么多广 告主有1%的人不满,就够央视采访一年的了。我想对央视广告不满的广告主应该也不少,没有坚持一直在央视投放广告的肯定更多,我想新浪哪天是不是也可以去 挑出一两个来好好采访采访,保证爆出来的料不比这次的差。那个04年5元涨到11年15元的例子,稍微有点常识和智商的人都能看出04年到11年CPI的 涨幅是多少?中国的网民数翻了几倍?互联网广告市场又增长了多少?即使是身处发展缓慢的传统媒体广告业的央视自己,他家的广告收费这几年难道就都没涨 么?!

还有一个广告主说停止投放广告,网站就会被加入一个“黑盒子”,三个月不能上首页。首先,我从来没听过“黑盒子”这个名词,其次,真正了解百度搜索 机制的人都知道,这样的黑盒子在百度搜索现有的技术框架下是无法实现的。所有的百度rd都可以看到百度内部所有的代码,百度的离职率又不低,如果真有这个 东西,早就有人爆出来了。最后,哪怕不考虑技术细节,难道央视的编导认为一个小小的销售打个电话就能操纵本来完全由机器和算法控制的搜索结果了吗?他难道 以为百度内部是用人肉来给网站排序的?网站被封禁是有可能的,但是这个完全是自然搜索的封禁策略,和商务搜索无关,前方的销售更不可能接触到自然搜索的技 术人员,去人为干预这个结果。而网站被封最可能的原因正是那个广告主说的,他投入大量人力物力去搞SEO,而过分地SEO导致某次不小心触犯了某些规则, 而被百度的系统判定为作弊,从而被封禁,这点我想有SEO常识的人都会了解。这个广告主花了那么大的成本去投SEO,难道就一点都没关心过SEO也有 SEO的规则吗?

至于后面说的很多广告主抱怨百度推广价格昂贵,效果不好,我都懒得反驳。首先这是个完全自由竞争的市场,百度虽然目前有垄断的地位,但是并没有利用 垄断优势去压制搜搜、搜狗之类的竞争,如果范围更广点,在媒体广告领域百度更不具备任何优势,相比CCTV,百度只是只小虾而已。既然这些广告主觉得百度 推广物无所值,成本太高,他们完全可以去别的地方推广,去别的媒体投广告,或者干脆停止做广告。百度并没有拿着枪逼他们做善事。可是我们看到很多广告主一 边抱怨一边继续把“95%的利润”投到百度推广中,这是为什么?是不是说明如果停止了推广,他们连现在5%的钱都赚不到?如果不是的话,他们就应该早早停 止推广,否则这样的nc言论如何能出现在中国最大的官方媒体上?事实上在百度推广以前,中小企业的生意并没有现在这么好做,要想把摊子铺到全国,有几家中 小企业交得起传统媒体高昂的广告费(央视就不说了,就是地方电视台都比百度点击一下几块钱的收费贵得多得多)。可惜人心苦不知足,那些被采访的广告主似乎 希望最好有一些推广效果好,又几乎不用花钱的渠道,真是有点贪得无厌了。当然买方和卖方的矛盾总是存在的,但是在市场机制下,这并有没有谁对谁错的问题, 买家嫌贵,卖家还嫌便宜呢,至少百度没有自己定价,而是用了竞价,而且一个愿买一个愿卖,也没有搞央视那样的黄金时段投标和标王的噱头,至少还加入了质量 度,使得结果不是单纯的竞价。我不明白央视怎么就能义正辞严地一边炒作自己每年的广告标王,一边指责百度只认钱呢?

至于最后搬出来的当当和京东就更加搞笑,完全是赶工出来的断章取义,他们确实在三月份声称过要减少甚至是停止在百度的推广,但是之后当当的营业额直 线下降,不得不重新加大投入(这从侧面也看出百度推广的效果),而京东的老刘则更是直接在微博上对他之前的言论作出了道歉。还有那个搞笑的马云,阿里的公 关水平确实很好,但是阿里巴巴之前的诚信危机和淘宝一直以来猖獗的假货问题……真不知道央视是怎么挑人的,选谁来讲诚信我觉得都比这家合适些(我并没有怀 疑马云本人的人品,但是之前他自己在回应淘宝假货的时候说过淘宝无法监控这些假货,事实上现阶段的互联网还没有一个很好的机制来产生一个低成本低门槛的线 上工商局,大家都面临同样的问题,在这种时候央视把他搬出来实在没有道理)。

这次的节目到明天不知道还会不会有续集,或者央视会不会调转它的枪口。至于这次央视报道的目的,目前来看也可能有很多种的理由,旧媒体打压新媒体也 好,为加强互联网监控造势也好,收保护费也好,不管出于怎样的目的,用这样的手法都让人觉得不耻,不是一个公正客观的媒体人为达目的所该使的手段。写这篇 软文,我也只是觉得有些事需要澄清一下,不管出发点如何,央视这么做至少已经伤害了在公司内所有合法守纪、为加速互联网上信息流通、健全互联网生态环境而 努力的百度人的感情,拿一家公关孱弱的公司来祭旗,柿子挑软的捏,实在有失第一官媒的身份!

 
2011-07-30 23:53

1,PM首先是用户
2,站在用户角度看待问题
3,用户体验是一个完整的过程
4,追求效果,不做没用的东西
5,发现需求,而不是创造需求
6,决定不做什么,往往比决定做什么更重要
7,用户是很难被教育的,要迎合用户,而不是改变用户
8,关注最大多数用户,在关键点上超越竞争对手,快速上线,在实践中不断改进
9,给用户稳定的体验预期
10,如果不确定该怎么做,就先学别人是怎么做的
11,把用户当作傻瓜,不要让用户思考和选择,替用户预先想好
12,不要给用户不想要的东西,任何没用的东西对用户都是一种伤害

 
2011-04-01 9:28

向传奇的youa团队致敬!
===================================

原文:http://hi.baidu.com/dongbao/blog/item/4412b31b159d0a128618bfbd.html

  雨水淋过的泥土味道总是很浓厚的。在这样的氛围下,放一部老电影是最适合不过的了。2010年3月10日,有些事终于可以有个了结了,虽然结局对团队是不公平的,但,这也算是一种解放吧。

  2007年5月15日百度电子商务项目正式启动,不到10个人的团队,大家踌躇满志的集结在一起,为了一个远大的目标和愿景,愿意为提高中国网 民生活水平而努力做一些事情。那时的电子商务,正处于一个混沌时代,没有人关注用户,也没有人关注商户,电子商务市场的用户数增长远远落后于产业规模的增 长。

  2007年9月,电子商务事业部正式成立,自最开始7个人的产品团队开始,在最初三个月里就完成了早期20人的产品+技术的核心开发团队组建, 而就是这样一支团队,完成了几乎是百度有史以来规模最大、最复杂的产品设计和总体设计。什么概念呢?就是技术委员会评价有啊和百付宝系统后,认为其复杂程 度相当于10倍的贴吧和知道。

  百度电子商务平台,看上去植根于百度大公司,但可以说是白手起家:凭着当时的核心团队,完成了后续80多人的大团队,再到后来,就有上百人的规 模。而这其中,公司转入不到20%,自主招聘超过80%。20个RD、10个PM、10个QA、7个前端、4个UE,一半的应届生和实习生,80%的人加 入百度不足1年,6个月时间,编码带测试,6×12的强制工作强度,这些人做到了别人认为“不可能完成的任务”。

  从2008年中旬开始,我们开始了全国的巡讲。就像普罗米修斯一样,我们将电子商务希望的火种带到全国各个地方。凡所到之处,场面之火爆、反响之热烈实属始料未及。几乎所有的商户,把我们当成了电子商务的救星,但很遗憾,我们才刚刚起步。

  2008年中秋节,我们依旧在加班,产品即将上线,我们说:“keep walking”:一个小小的酿酒师Johnnie Walker用150年的执着专注,证明轩尼诗和芝华士和许许多多曾经风靡品牌的一统天下,不代表制酒业就容不下一个新的巨头,150年里的起起落落,坚 持到底、不断进步才是胜利。第一瓶酒不论酿的是好还是坏,至少这是迈出了第一步。

  同年9月25日,我们发布了商品和商店系统公测,当晚,数万商户几乎是同时涌进有啊测试平台。那天晚上,中国神舟七号发射成功,中国第一次载人航空飞行升天。

  10月底,经过36小时的上线后,凭借心中的那一线光亮,持续了6个月的高强度研发,我们正式发布了有啊商城、检索系统和百付宝交易平台,零事 故上线。我们在有啊的一个商户上订的蛋糕,被商户忠实的记录了下来。一年半不知疲倦的奋斗和努力,在那一晚上的泪水和笑声中,你就知道,什么都值了。

  上线后的第二天,记忆非常恍惚,高烧中。

  一个月后的11月,商品突破1000万件。有啊从0增长到10万商户、1000万商品,百度有啊只用了不到20天,发展速度是业内平均水平的500多倍。

  2009年1月年会,电子商务事业部荣获百度2008年度最高容易:总裁特别奖。

  市场是以结果为导向的,这是残酷的体现。业绩不行,必须有人负责,却无人为我们说话。事实的真相永远是被掌握话语权和媒体的人们——所谓的专家 所掩盖,团队和个人的尊严不见去除。越是到困难的时候、越需要有人帮你挺一把的时候,越能让人清楚的看到谁是朋友、谁心怀不轨。当我们面临每月仅数千元市 场推广费的无米之炊时,当我们发现互联网上淘宝以外的商品网页资源越来越少的时候,当我们发现公司又想马儿跑、又不给马儿吃草后,一切都变了。但负责人的 说,这样一支团队,这样群有梦想的人,却是比我看到过、听到过的那些为了市场业绩不择手段的所谓职业人要更加伟大、更加骄傲。如果当一个公司和内部的机制 不能为这样的团队的成功而铺平道路,或者说这样一个团队不能发挥其应有的价值和作用,那么一定不是这个团队的问题。

  历数一下我们对电子商务市场的贡献和创新吧,趁还能看到:

  首创了实物交易与虚拟交易分离的信用机制(已被所有的C2C交易平台所采用);

  大胆取消了折磨商户很久的“满意率”指标,首创了满意度打分的信用评价机制,并结合商户的认证资质证明等组成综合的信用认证体系;

  首创了电子商务标准库交易模式,先后上线了手机产品库、化妆品产品库,改变了传统的C2C购物流程,攻克了若干技术难度(现已被竞争对手学习);

  首创了智能订单聚合模式,能根据用户行为智能合并订单,并首次在C2C交易平台上以购物车+订单的模式提供给消费者(现已被竞争对手学习);

  首创了电子商务会员订阅中心的商户营销平台(现已被竞争对手学习);

  首创了搜索的按卖家聚合和新的搜索和筛选展现(现已被竞争对手学习)。

  ……

  俞敏洪曾说:如果将人生一分为二, 前半段人生哲学是「不犹豫」,后半段人生哲学是「不后悔」。我想,在未来某个时候或者某个场合,哪怕这些忘却的记忆被人们提起,哪怕做过的事情对其他的人 有那么一点帮助,拿这段记忆一定会在我们大家心中占有一个不会磨灭的记忆。最后,以明远对团队曾经的一段话作为结尾吧:

  “走过的路是为经历,其实过去的成败与否,对自己的价值其实是一样的,这个价值在于你是否真正的注意到了你之前所走过的路、每一次坎坷和上下坡 时,谁是值得信赖的旅伴,哪里该快步通过,哪里该停留沉思。人走路,不是驴拉磨,低头拉磨固然也是keep walking,但驴创造的价值永远只是磨磨豆腐,吃豆腐的人不会感激驴,而唯有让走过的路有价值,用心、用腿、知行合一、全身配合着走,才能少摔跟头、 少走错路,走过的路和最后的所到之处才算得上有价值、值得走。从这个角度,自信、专注、科学、坚持必须兼顾而不是独专,稳稳的走下去。”

  面北而望,泪已沾襟,不知所言。

  《别董大》

  (唐)高适

  千里黄云白日曛,

  北风吹雁雪纷纷。

  莫愁前路无知己,

  天下谁人不识君?

 
2011-02-17 14:06

地址无关代码,在64位下编译动态库的时候,经常会遇到下面的错误

/usr/bin/ld: /tmp/ccQ1dkqh.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

提示说需要-fPIC编译,然后在链接动态库的地方加上-fPIC的参数编译结果还是报错,需要把共享库所用到的所有静态库都采用-fPIC编译一边才可以成功的在64位环境下编译出动态库。

这里的-fPIC指的是地址无关代码

这里首先先说明一下装载时重定位的问题,一个程序如果没有用到任何动态库,那么由于已经知道了所有的代码,那么装载器在把程序载入内存的过程中就可 以直接安装静态库在链接的时候定好的代码段位置直接加载进内存中的对应位置就可以了。但是在面对动态的库的时候 ,这种方式就不行了。假设需要载入共享库A,但是在编译链接的时候使用的共享库和最后运行的不一定是同一个库,在编译期就没办法知道具体的库长度,在链接 的时候就没办法确定它或者其他动态库的具体位置。另一个方面动态库中也会用到一些全局的符号,这些符号可能是来自其他的动态库,这在编译器是没办法假设的 (如果可以假设那就全是静态库了)

基于上面的原因,就要求在载入动态库的时候对于使用到的符号地址实现重定位。在实现上在编译链接的时候不做重定位操作,地址都采用相对地址,一但到了需要载入的时候,根据相对地址的偏移计算出最后的绝对地址载入内存中。

但是这种采用装载时重定位的方式存在一个问题就是相同的库代码(不包括数据部分)不能在多个进程间共享(每个代码都放到了它自己的进程空间中),这个失去了动态库节省内存的优势。

为了解决这个问题,ELF中的做法是在数据段中建立一个指向那些需要被使用(内部的位置无关简单采用相对地址访问就可以实现)的地址列表(也被称为全局偏移表,Global offset table, GOT). 可以通过GOT相对应的位置进行间接引用.

对于我们的32位环境来说, 编译时是否加上-fPIC, 都不会对链接产生影响, 只是一份代码的在内存中有几个副本的问题(而且对于静态库而言结果都是一样的).但在64位的环境下装载时重定位的方式存在一个问题就是在我们的64位环 境下用来进行位置偏移定位的cpu指令只支持32位的偏移, 但实际中位置的偏移是完全可能超过64位的,所以在这种情况下编译器要求用户必须采用fPIC的方式进行编译的程序才可以在共享库中使用

从理论上来说-fPIC由于多一次内存取址的调用,在性能上会有所损失.不过从目前的一些测试中还无法明显的看出加上-fPIC后对库的性能有多大的损失,这个可能和我们现在使用的机器缓存以及大量寄存器的存在相关.

小提示

-fPIC与-fpic 上面的介绍可以看到,gcc要使用地址无关代码加上-fPIC即可,但是在gcc的手册中我们可以看到一个-fpic(区别在一个大写一个小写)的参数, 从功能上来说它们都是一样的。-fpic在一些特定的环境中(包括硬件环境)可以有针对性的进行优化,产生更小更快的代码, 但是由于受到平台的限制,像我们的编译环境,开发环境,运行环境都不完全统一的情况下面使用fpic有一定未知的风险,所有决大多数情况下我们使用 -fPIC来产生地址无关代码。共享内存效率

共享内存在只读的情况下性能和读普通内存是一样的(如果不算第一载入的消耗),而且由于是多个进程共享对cpu cache还显的相对友好。

同时存在静态库和动态库

前面提到编译动态库的时候有提到编译动态库可以像编译静态库那样采用-Lpath -lxx的方式进行, 但这里存在一个问题,如果在path目录下既有动态库又有静态库的时候的行为又是什么样地? 事实上在这种情下, 链接器优先选择采用动态库的方式进行编译.比如在同一目录下存在 libx.a 和 libx.so, 那么在链接的时候会优先选择libx.so进行链接. 这也是为什么在com组维护的第三方库(third, third-64)中绝大多数库的产出物中只有.a的存在, 主要就是为了避免在默认情况下使用到.so的库, 导致在上线的时候出现麻烦(特别是一些系统中存在,但又与我们需要使用的版本有出入的库).

为了能够控制动态库和静态库的编译, 有下面的几种方式

直接使用要编译的库 在前面也提到了在编译静态库的时候有三种方式 目标文件.o 直接使用静态库文件.a 直接编译采用 -L -l方式进行编译

编译的时候如果不采用-Lpath -lxx的方式进行编译, 而且直接写上 path/libx.a 或者 path/libx.so 进行编译,那么在链接的时候就是使用我们指定的 .a 或者 .so进行编译不会出现 所谓的动态库优先还是静态库优先的问题. 但这个方案需要知道编译库的路径,一些情况下并不适合使用。

--static参数

在gcc的编译的时候加上--static参数, 这样在编译的时候就会优先选择静态库进行编译,而不是按照默认的情况选择动态库进行编译.

不过使用--static参数会带来另外的问题,不推荐使用,主要会带来下面的问题

如果只有动态库,而不存在同名的静态库,链接的时候也不会报错,但在运行的时候可能会出现错误 /lib/ld64.so.1: bad ELF interpreter:由于我们程序本身在运行的需要系统中一些库的支持,在采用--static编译方式之后,链接的就是这些库的静态编译版本,等于使用的是 编译机上的库,但是我们的运行环境可能和编译机有所不同,glibc这些动态库的存在本身的目的就是为了能让在一台机器上编译好的库能够比较方便的移到另 外的机器上,程序本身只需要关注接口,至于从接口到底层的部分由每台机器上的.so来处理.不过这个问题也不是那么绝对,在一些特殊情况下(比如 glibc, gcc存在大版本差异的时候,主要是gcc2到gcc3有些地方没有做好,abi不兼容的问题比较突出,真遇到这些情况其实需要换编译器了)  --static编译反倒可以正常的运行.但是还是不推荐使用, 这些是可以采用其它方法规范在后面的第6点中有说明.另外就是glibc --static编译可能会产生下面的warning:warning: Using 'getservbyport_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking这个主要原因是由于getservbyport_r 这样的接口还是需要动态库的支持才可以运行,许多glibc的函数都存在这样的问题, 特别是网络编程的接口中是很常见的.对一些第三方工具不友好,类似valgrind检查内存泄露为了不在一些特殊的情况下误报, 它需要用动态库的方式替换glibc中的函数,如果静态编译那么valgrind就无法替换这些函数,产生误报甚至无法报错. tcmalloc在这种情况下也不能支持.64位环境中使用的pthread库,如果是使用的是动态库那么采用的是ntpl库,如果是静态库采用的linuxthread库,使用--static 会导致性能下降--static之后会导致代码大小变大,对cpu代码cache不友好,浪费内存空间,不过对于小代码问题也不大.

链接参数控制

链接器中提供了-dn -dy 参数来控制使用的是动态库还是静态库,-dn表示后面使用的是静态库,-dy表示使用的是动态库

例:

g++ -Lpath -Wl,-dn -lx -Wl,-dy -lpthread

这样如果在path路径下有libx.so和libx.a这个时候只会用到 libx.a.

注意在最后的地方如果没有-Wl,-dy 让后面的库都使用动态库,可能会报出 "cannot find -lgcc_s" 的错误,这是由于glibc的.a库和.so库名字不同,--static会自动处理,但是 -Wl,-dy却不会去识别这个问题.

小提示

如果使用--static, 由于-dy的使用导致后面的库都是共享库(dy强制屏蔽了静态库),这个时候编译出来的程序和只有动态库的情况下强制使用--static编译一样都会报错

运行报错 "undefined reference to `xxx()' "

对于动态链接库,实际的符号定位是在运行期进行的.在编译.so的时候,如果没有把它需要的库和他一起进行联编,比如libx.so 需要使用uldict, 但是忘记在编译libx.so的时候加上-luldict的话,在编译libx.so的时候不会报错,因为这个时候libx.so被认为是一个库,它里面 存在一些不知道具体实现的符号是合法的,是可以在运行期指定或者编译另外的二进制程序的时候指定.

如果是采用 g++ -Lpath -lx 的方式进行编译,链接器会发现所需要的uldict的符号表找不到从而报错,但是如果是程序采用dlopen的方式载入,由于是运行期,这个程序在这个地 方就直接运行报错了.另外还有一种情况就是一个对外的接口在动态库中已经声明定义了,但是忘记实现了,这个时候也会产生类似的错误.

如果在运行期报出这样的错误,就要注意是否是由于某些库没有链接进来或者某些接口没有实现的原因产生

=================================================

收集了一些与编译,链接相关的问题, 有问题随时欢迎提问.

纯C程序如何使用ullib这些用g++编译出来的库

上文已经介绍过了, 在g++的环境中直接编译的结果会导致符合表与gcc编译的结果不同导致不能混合编译.

gcc使用g++编译的库原则:

1. g++编译库的时候需要把被外界使用的接口按照纯C++可以接受的方式用extern "C" 包起来,并且加上__cplusplus宏的判断,可以参考public/mcpack, public/nshead中的写法. 对于一些特殊情况,比如已经是g++编译出来的库又不适合修改,比如ullib, 分词库等,可以自己写一个 xxx.cpp的程序,在xxx.cpp对需要使用的接口再做一次纯C接口的封装,同时用extern "C"把纯C接口导出使用.使用g++编译,并且在链接的时候加上ullib等库即可. 2. gcc编译g++库在我们的64位环境中需要在最后加上-lstdc++

gcc使用g++编译的库多见于需要将基础库与php扩展,apache mod进行联编;

g++使用gcc编译出来的库: 这个比较简单,只需要gcc编译的提供的头文件采用了extern "C"封装即可.

在同样的环境下用同样的方式编译出来的程序md5是否都一样

如果环境完全一样包括编译路径,环境变量等都是一样的,一般情况下确实是一样的,但是许多环境的情况我们很难做到一样,比如程序使用一些DATA这样与时间相关宏就会导致每次编译的结果都是不一样的,有时候甚至内存的多少也会影响编译的结果

链接和运行的时候,静态库和动态库路径的查找顺序都是什么?

链接的时候查找顺序:

-L 指定的路径, 从左到右依次查找由 环境变量 LIBRARY_PATH 指定的路径,使用":"分割从左到右依次查找/etc/ld.so.conf 指定的路径顺序/lib 和 /usr/lib (64位下是/lib64和/usr/lib64)

动态库调用的查找顺序:

ld的-rpath参数指定的路径, 这是写死在代码中的ld脚本指定的路径LD_LIBRARY_PATH 指定的路径/etc/ld.so.conf 指定的路径/lib和/usr/lib(64位下是/lib64和/usr/lib64)

一般情况链接的时候我们采用-L的方式指定查找路径, 调用动态链接库的时候采用LD_LIBRARY_PATH的方式指定链接路径.

另外注意一个问题,就是只要查找到第一个就会返回,后面的不会再查找. 比如-L./A -L./B -lx 在A中有libx.a B中有libx.a和libx.so, 这个时候会使用在./A的libx.a 而不会遵循动态库优先的原则,因为./A是先找到的,并且没有同名动态库存在.

哪些情况会出现 "undefined reference error" 的错误?

这里再总结一下这个问题可能出现的场景:

没有指定对应的库(.o/.a/.so) 使用了库中定义的实体,但没有指定库(-lXXX)或者没有指定库路径(-LYYY),会导致该错误,连接库参数的顺序不对 在默认情况下,对于-l 使用库的要求是越是基础的库越要写在后面,无论是静态还动态gcc/ld版本不匹配 gcc/ld的版本的兼容性问题,由于gcc2 到 gcc3大版本的兼容性存在问题(其实gcc3.2到3.4也一定程度上存在这样的问题) 当在高版本机器上使用低版本的机器就会导致这样的错误, 这个问题比较常见在32位的环境上, 另外就在32位环境不小心使用了64位的库或者反过来64位环境使用了32位的库.C/C++相互依赖和链接 gcc和g++编译结果的混用需要保证能够extern "C" 两边都可以使用的接口,在我们的64位环境中gcc链接g++的库还需要加上 -lstdc++,具体见前文对于混合编译的说明运行期报错 这个问题基本上是由于程序使用了dlopen方式载入.so, 但.so没有把所有需要的库都链接上,具体参加上文中对于静态库和动态库混合使用的说明可以把两个.o直接合并成一个.o文件吗?

可以,命令是 ld -r a.o b.o -o x.o, 不过不推荐这样做,这样做唯一的好处是静态库在链接的时候如果使用到了a.o中的符号也可以同时把b.o中的符号链接进来,可以避免--whole-archive的应用.

但是不推荐这样做,无形中增加了对源文件维护的麻烦

为什么使用inline,并没有把代码inline进程序?

首先加了inline的函数是否可以被inline这个是由编译器决定,很多时候即时是指定了inline但还是无法被inline

另外注意到gcc中,只有在使用-O以上的优化后inline才会起作用,没有-O, -O2, -O3这些优化手段,无论是否加上了-finline-functions gcc都是不会进行inline优化的,这个时候的inline相当于一个普通函数(其实还是有一点区别,在符号表中表示是不一样的).程序在编译的时候 加上了-finline-functions 但如果没有-OX(X>=1)的配合, -finline-functions其实是无效的,不会起作用也不会报错

gcc里面为了能够支持在不加-OX(X>=1)的情况下能够将函数inline, 提供了一个扩展always_inline, 将函数写成下面这样

__attribute__((always_inline)) int foo()
{
...
}

就可以在不加-OX(X>=1)的情况下把foo inline进程序,不过always_inline 这个扩展只在gcc3以后支持,32位环境中使用的2.96 gcc是不支持的.

64位机器上可以编译出32位程序吗?

理论上是可以的, 在64位机器上的64位gcc中提供了-m32的参数,可以指定进行32位的编译, 但是编译问题虽然解决链接问题却还是存在,在64位的机器上可以用进行链接的库主要有2个一个是供64位程序使用的,另外一个供gcc2.96编译程序在 64位机器上运行的,这两个库都不能给gcc -m32出来的结果提供链接环境(32位库不能连接64位库,给gcc2.96的库太老的不兼容), 所以在编译机器环境上是不能直接编译出可执行的32位程序(编译成.o文件还是可以的)

为什么编写的动态链接库不能直接运行?

在共享库的总结中介绍了如何实现共享库可以自己运行,但是有些时候会出现undefined reference error的错误导致共享库不能被运行。

这种情况产生的原因是:动态库中采用了类似 static int val = func(xxx);的写法, 其中val 是一个全局变量(或者静态全局变量)。 动态库被载入内存中使用的时候会直接先运行func这个函数,如果func是来自其他的库(比如一些情况下主程序使用-rdynamic编译,动态库使用 主程序的空间), 在编译动态链接的库的时候又没有被链接上, 这个时候就会出现这样的问题。

对于这样的问题主要考虑下面的解决方案:

1. 不要采用static int val = func(xxx);这种写法

将使用的静态库链接进共享库, 但这里要注意-rdynamic的影响,必要的时候需要保证和主程序使用的库版本是相同的。让共享库不可运行也是一种解决方案是否可以在main函数开始前就执行程序?

如果在main函数开始前执行代码,一般有下面的两种方法

采用 int val = func(xxx)的方式,在func(xxx)中执行声明一个class, 把需要运行的函数写在class. 并且定义一个全局(或者static)的类变量

在实现上,编译器把它们放到一个特殊的符号 _init 中,在程序被载入内存的时候被执行

但是这种方式我们不推荐使用,特别是在这些执行代码中存在库与库之间的依赖关系的时候, 比如下面的场景:

libA.cpp

class Aclass
{
public:
Aclass()
{
int * u = Bfunc(); //这是另外一个库libB中的函数
int c = u[0];
}

}

static Aclass s_test;

libB.cpp

staticint *s_test = test_init(); //初始化s_test

int *Bfunc()
{
return s_test;
}

上面的程序中有2个库,A库有一个static变量的构造函数依赖了 B库中的一个函数, B库中的这个函数又操作了一个由函数test_init初始化的static变量.

按照程序的要求我们必须要让test_init()这个函数在Aclass这个函数之前运行, 但是可惜的在某些情况我们很难做到这点, 这里涉及到链接器对库链接和初始化顺序的问题.

在默认情况下, test_init()和s_test的构造函数的执行顺序是按照链接的时候-l的顺序从右到左, 比如-lB -lA 那么Aclass的构造函数会在test_init()前执行,这个时候就会出现问题,需要保证-lA -lB的顺序才可以正常.

这里又涉及到另外一个问题, 就是 正常情况既然A依赖B, 那么在链接的时候肯定需要 保证 -lA在-lB. 但是这里我们只能说需要把越基础的库放在越后面,而不是必需放在最后面.还是上面的例子. 如果这个时候有一个test.cpp 使用了 A库, 并且在test中没有直接使用到B库中的东西, 这个时候如果-lB放在-lA前面,链接器会报错, 因为符号在从左往右展开的时候, 由于test没有使用到B的东西,所以没有做任何展开, 从这个角度而言在链接A的时候就找不到符号. 但是如果在test中有使用到B中和test_init相关联的函数,那么这个时候如果把-lB放在-lA的前面展开B函数的时候会把test_init 导出, 这样导致A会认为已经存在了test_init, 从而不报编译错误. 但是这样的结果就是test_init的初始化顺序被放到Aclass之后, 那么在程序运行的时候就可能导致错误.

对这种问题解决,主要有几种考虑

采用 单例模式, 采用类似 if (NULL == ptr) ptr = new xxx; return ptr的方式通过用户态的判断来控制,不过有些时候需要考虑些多线程问题,了解依赖关系, 把-lB放到-lA的后面不允许这种方式的存在.

在使用全局变量的时候 需要特别注意这种初始化的顺序问题.小提示:构造初始化等,是在_init中处理, 另一个方面_fini是存在在程序退出前的执行析构等操作

 
2011-01-02 14:57

千里之行,始于足下,无论你有多么的豪情万丈,总要从最基础的东西做起。

然而要做一个好的基层工作人员,并不是低头认认真真写好代码就可以的,其中可大有学问。


按照余世维所论,一个好的下属应该:

主动向上司汇报你的工作进度——让上司知道!
对上司的询问,有问必答,而且清楚——让上司放心!
充实自己,努力学习,才能了解上司的言语——让上司轻松!
接受批评,不犯两次过错——让上司省事!
不忙的时候,主动帮助他人——让上司有效!
毫无怨言的接受任务——让上司圆满!
对自己的业务,主动提出改善计划——让上司进步!

 

我也总结了如下几点,欢迎大家补充。

(1) 做得快还是做得好?

当前的项目管理中,多是强调结果的,号称结果导向或者结果驱动。

作为一个基层,做人重要,做事更重要,除了良好的沟通能力,能拿得出真金白银的成果,更是每个项目经理愿意看到的事情。

然而怎么叫好的结果呢?

一九五八年党的八大二次会议上,提出多快好省的建设社会主义。多快好省四个字即体现了前辈革命家的理想壮志,也成为后来中国管理者心中的梦。所以我们时常听到如下的话:"这些功能下个月一定要出来","代码质量要高,要有详细的注释,测试用例,code review","最好提前一周至少三天,可以准备demo","项目现在经费相对比较紧张,希望大家克服一下"。

然而现代的项目管理给我们画出了如下的三角形:

 

范围,预算,时间三者相互制约,牵一发而动全身。欲范围大(多),就应该增加项目预算(不省),如增加人手,增加资源,买第三方成品,或者应该延长时间(不快),如推迟release的时间等。欲按期完成(快),则可以增加预算(不省),或者减少功能(不多)。

然而现实中,老板可不这样想,预算是早就做好了的,时间也是确定了的,功能缺一不可,作为基层的程序员我们唯一可以影响的就是用加班换来更多的时间,当然还有中间的一个圆圈——项目的质量。

到底是尽快的做出一个实现基本功能但设计稍有缺陷,测试不太完备,有少量的Bug的版本出来然后慢慢改进呢,还是经过慢慢的精心设计,做出有完备的测试用例,经过严格测试少有Bug的版本呢?

这个问题如果你问程序员,大部分人会选择后者。尤其对于初涉职场,充满激情的程序员们,往往满脑设计模式,满口软件工程,几乎见不得注释中的错别字和没有覆盖到的测试边界,似乎一个不完美的方案就有辱于软件工程师的名号了,我们称之"技术洁癖"。

如果你问项目经理,也会告诉你后者,而且最好以后者的形式用前者的时间(多少有些多快好省的味道)。然而很少有项目经理会直接看你的代码,更不关心你用的何种设计模式,也不会一个个看你的测试用例来思考是否覆盖所有的边界,更不会看你写的注释了。

所以很不幸,除了少数精通技术,熟悉细节,了解程序员苦衷的项目经理外(这可是大多数程序员都翘首以待的领导啊),大部分喜欢前者。

因为精心的设计,良好的文档是需要大量的时间,完备的测试用例的代码量几倍于实现本身,功能测试,性能测试以及Bug的修改更是难以估计时间的,所以总的时间将几倍于前者的时间,在此过程中,你献给项目经理的,除了等待,还是等待。

人是不喜欢等待的,尤其是很少反馈的等待,当我们用windows的时候,往往会出现估计时间相当不准确的进度条,然而我们还是喜欢看着进度条一直走到底,同样项目经理也是。

总是能够很快的做出项目经理能够看到的版本,便容易给人一种能力很强的感觉,至少大部分人会这样认为。

也许你会说:我做的版本Bug很少,后期维护成本低,QA一测不就能够看出孰优孰劣来了吗?

仍然很不幸,在大多数人看来,你一个月做了一个稳定的版本被认为是做了一件事情,而别人两个星期做了一个不稳定的版本,后两个星期改了三个Bug是做了四件事情,而且其每次的会议总有进度可以说,成绩斐然。

而且一个人身上所挂着的Bug的个数,实在不是一件值得羞愧的事情,反而是一件令人感到荣耀的事情,这说明了你重担在身,举足轻重。

如果你做了一个模块,用了一个月,后来半年都不曾出过Bug,而另一个人做一个模块两个星期,出过多个Bug,并且后来兼任其他模块的时候还在改Bug,还是很不幸,你会被认为所做的模块相对简单,不容易出Bug,并随着项目的进行而被淡忘,会被这样提及:"他在半年前做过一个项目",而另一个人却会被认为所做的很复杂,有很多疑难杂症,而且后来会被认为身兼数职,会这样被提及:"随着能力的提升,同时维护并负责多个模块,有并行工作的能力,有很强的解决问题的能力"。

也许你觉得我说的太极端,那就举一个历史上的例子吧,有兴趣大家可以看李亚平的《前清秘史——入主中原之路》,其中是这样描写当时并称“南戚北李”的两位将军的:

李成梁屡立大功,受封为伯爵,跻身于帝国贵族行列。在当时,他的地位、名望等,很有可能已在戚继光之上。有一种看法,包括《明史》的作者们认为,恰恰因为戚继光威名太盛,坐镇蓟门十六年,使敌人从来不敢来犯(没有Bug啊),于是转道入侵辽东,才给了李成梁屡立战功的机会。张居正死后,新政被废,受到张居正支持重用的戚继光被迅速边缘化,在郁郁寡欢中死去(可能明朝认为蓟门这个模块不需要再维护了)。而李成梁,他同样受到过张居正的支持和倚重,然而,可能由于下面的三个原因:其一,远离京师,与张居正没有过多的私人交往;其二,赫赫战功给万历皇帝留下了深刻印象(每次总有进度可说);其三,动荡不安的辽东局势离不开这位骁将(辽东模块还需要维护啊)。从而,李成梁避免了池鱼之灾。

当前社会中,不是如此吗?是修了坚固的河堤的市长感动中国,还是和民众一起抗洪抢险的市长感动中国呢?是治理的地方路不拾遗的公安局长应该升职,还是让黑社会猖狂十年然后一举击溃的公安局长会升职呢?

如果你觉得你的项目经理英明过于历史甚至当朝首辅,那么恭喜你。

(2) 有问题要尽早喊

当一个模块或者一个任务交给你的时候,可能存在各种各样的困难,会出现各种各样的问题,需要各种各样的资源,这一切都应该慎重考虑后尽早提出。

问题的尽早提出,其实是风险控制的一种手段。

调配资源,排除干扰,风险控制是一个项目经理的重要责任之一,然而不要认为项目经理会英明神武到知道一切细节,也不要认为这是项目经理的事情,与你无关。其实一个模块,真正了解细节的是你。

所以对团队来讲,事先问题没有提出,到时候出现是你的甚至你的团队的责任,问题及早提出了,项目经理向相关人员请求资源,到时候没有解决就不是你的责任,甚至也不是你们团队的责任了。这个样子既帮助你的项目经理控制风险,又能够在外国人面前撇清责任,是每一个项目经理都欢迎的事情。

对你个人来讲,问题及早提出了,以后或有Bug,或有delay,都不会给人一种突然的感觉,也给项目经理一种对你,也对整个项目可控的感觉。

从心理学上来讲,人们多惯于先听坏消息,再听好消息,而不愿意先听好消息,再听坏消息,这就是我们常说的冷热水效应:一杯温水,保持温度不变,另有一杯冷水,一杯热水。当先将手放在冷水中,再放到温水中,会感到温水热;当先将手放在热水中,再放到温水中,会感到温水凉。

一个经常举得例子是:某汽车销售公司的老李,每月都能卖出30辆以上汽车,深得公司经理的赏识。由于种种原因,老李预计到这个月只能卖出10辆车。深懂人性奥妙的老李对经理说:“由于银根紧缩,市场萧条,我估计这个月顶多卖出5辆车。”经理点了点头,对他的看法表示赞成。没想到一个月过后,老李竟然卖了12辆汽车,公司经理对他大大夸奖一番。假若老李说本月可以卖15辆或者事先对此不说,结果只卖了12辆,公司经理会怎么认为呢?他会强烈地感受到老李失败了,不但不会夸奖,反而可能指责。在这个事例中,老李把最糟糕情况――顶多卖5辆车,报告给经理,使得经理心中的“秤砣”变小,因此当月绩出来以后,对老李的评价不但不会降低,反而提高了。

(3) 用Bug来说不

不知从何时开始《致加西亚的信》以及《没有任何借口》此类的书开始畅销,从而以执行力的名义把责任全部推到被领导的一方,用军队的方式来要求自己的员工,不讲条件,没有借口,从不说不,来完成领导所给的任务。真不知道资本家有什么资格这样要求自己的员工,作为军人为祖国献身后至少能够成为烈士,家人受到抚慰,而资本家在员工连跳九人的情况下却在论证这个数字其实低于全国平均自杀率的。

然而大多数的领导的的确确喜欢没有借口的下属,也不喜欢听到说不。所以当一个任务下达的时候,或者一种方案被指定的时候,不要直接说不。

领导毕竟是领导,能做到现在的位置,毕竟有强于你的地方;领导毕竟也是人,提出的方案也可能是拍脑袋拍出来的,也许会有不合理性。

然而需要记住的一点是:上情下达可以拍脑袋,下情上达则要用证据。

当你认为领导给的任务或者方案有问题的时候,除了上面提到的喊难在前之外,一定要加一句,"我试试看"。

当你经过实验测试,有数据或者日志足以证明你的结论的时候,可以尝试说,"我觉得可能有些问题"。

然而有时候简单的测试并不能够证明的时候,或者领导再次坚持的时候,那就上手做吧,只是别忘了做的有扩展性一些,能在多种方案之间较容易的切换,并将领导坚持的方案暴露出来。当测试人员发现问题的时候,将比你说不有效果的多。这时候领导关心的便是如何Bug进行修复,不在纠结到底应该采用你的方案还是他的方案了,当然此时你千万不要得意洋洋的指出领导原来方案的不合理性,你不指出,领导其实是从心里认可了你的方案的,并且为你记了一功,如果你指出来,就适得其反了,大部分领导绝不会表面承认自己的错误的,可能会再次坚持自己的方案的合理性,并把因此带来的项目失败或者delay记在你的头上。也许大家清晰的记得曹操不承认"鸡肋"的退兵禁令而杀杨修的故事吧。如果你觉得你的领导气度大于曹操,那么再次恭喜你。

也许你会说:这不是浪费了一个过程吗?其实不然,你先做了领导的方案,然后改Bug的时候应用了自己的方案,在领导眼中,你是一个好的下属,好的执行者,你是做了两件事情的。

如果你坚持做了自己的方案而没有优先用领导的方案,则会有以下风险:

你永远失去了证明你的方案优于领导的方案的机会 你会被认为固执,难于沟通,执行力差 一旦你的方案出现问题,你将单独的承担责任,甚至整个项目delay的责任。如果你优先采用了领导的方案出现问题的时候,一般合格的领导会勇于承担起责任,替你说好话:"我们采取的方案是相对较优的,也是经过测试的,Bug是难免的",相反,如果你固执己见,则没有人会替你说话,反而会说:"要是用原来的方案就不会出现这个问题" 。 领导的方案一般是由一定原理上合理性的,你的方案可能是比较符合你的实际需要,然而当时过境迁,context不在的时候,你百口难辨。

所以,毫无怨言的接受任务——让上司圆满,如果有问题,让Bug来说。

(4) 该干什么的时候干什么

在外企,一个常说的词叫"professional",何为职业化,一个通俗的说法就是,该干什么的时候就干什么,当然无论干什么,永远不要忘记,你是一个程序员,一个基层的程序员。

前面说过,除了写程序,外企的生活是丰富多彩的,健身,按摩,小食品,饮料,旅游,年会,各种协会等等不一而足,而且外企的氛围是相对宽松的,你可以在任何时间尽情享用,没有人会有意见,当然是在你完成了工作的基础之上的。

然而永远需要记住的是,写程序才是你的天职,而多彩的生活是公司对员工的福利,是一种施舍,说的不好听一点,公司花钱请你来是写软件的,不是让你来娱乐的,公司让你娱乐是给你脸,你总不能给脸不要脸吧。话说的难听一点,但细想想,话糙理不糙,试想如果项目经理每次来巡查的时候都看到你或大声的说笑,或尽情的饮食,或玩桌上足球的时候,其内心不会有上面的想法?只不过是一种优雅的方式表达出来罢了。比如走到你的面前,微笑着问:"你的feature做的如何了?","Bug XXX有没有结果?",顺便强调一下你所做的模块的难度和重要性:"你做的这部分比较有难度,是对你能力的挑战",并在最后来一句:"慢慢做,不着急"。你可知晓此彬彬有礼下面的深意?经理两次到你这里来说"不着急"的间隔越短,其实是说明这件事情越着急的。

所以说在办公室的大部分时间,你都应该低头写程序,谈话也要讨论技术问题,娱乐要适度,除非你想被人觉得工作量太少,不努力,或者你有足够的信心自己负责的模块不会出问题。

另外在开会的时候,你由于任务太多,总是盯着自己的笔记本默默写自己的代码吗?不要这样,这样会让组织会议的人感到不被尊重,会让领导觉得你对项目组不够关心,不够投入,甚至不够忠诚。开会的时候,就要像开会的样子。你可以提前阅读材料来准备几个问题;你可以支持,补充或建议组织者的方案;你可以在外国人面前举出证据来维护中国团队的利益;实在没招,你至少可以记会议记录,会后发meeting minutes。这样你给人的印象永远是你是有想法的,你是有贡献的,你是关心项目的,你是热爱团队的。

一个Team出去吃饭,或者出去旅游的时候,你是得意忘形的放开手脚去玩吗?甚至脱离团队和要好的朋友去逛吗?不要这个样子。余世维在《经理人常犯的11个错误》的演讲中曾经说过,出去Team building,对于员工来说是休息,而对于经理来说是工作。的确,你要清楚资本家为什么会出钱让员工去做这些和工作看起来无关的事情?为什么要大家一起出去而不是每人发钱自己去玩?当然是要增加团队的凝聚力和归属感,为共同合作奠定基础。既然对于经理来讲是工作,难道你不应该有责任辅助你的经理做好工作吗?在大家一起吃饭的时候,如果冷场,积极的起一个话题吧;在经理提出玩一个团队游戏的时候,率先支持,主动去做吧;在外出旅游的时候,帮助你的经理订餐馆,清点人数,摄影照相吧;当爬到山峰,或者年会表演节目的时候,喊出增加团队凝聚力和影响力的口号吧;在活动结束后,整理资料,相片,发出email来进一步增加活动的效果吧。这样你就是有组织能力的,辅助经理成功的,有良好影响力的,也是热爱团队的。

这里提到了团队聚餐中的话题问题,这里顺便提一下,当然根据不同的Team的氛围以及当时的情况而定,话题的优先级依次如下:

项目话题:如进度,难点,后面还会提到,学会喊累,喊忙,这是一个比较好的机会。当然此话题比较适合加班或者中午时的团队聚餐,不太适合旅游时候的团队聚餐。此话题可表明你对项目的关心。 技术话题:比如语言排名,那家公司被收购了,平台之间的差异等等。此话题可说明你对技术无限热爱。 员工生活话题:比如周末干什么了,介绍女朋友,结婚,孩子教育等,当然以当事人意愿为准,不要太当真。此话题可说明你关心同事。 娱乐话题:比如看什么电影,娱乐圈出来什么事情等,这是万能话题,也是最保险的话题。 员工敏感话题:比如非议其他Team,或者美国团队等,此类话题最好不要涉及,背后议人不太好。 公司敏感话题:如有的Team裁员,减薪,福利下降等,此话题千万不要提及,这是领导层想尽力遮盖的问题,甚至不在项目经理的权利范围之内。涉及此类话题将给人以你是一个不可托付大任的人。

最后,如果你在学校中是演艺明星或者体育明星,那么年会的表演以及团队之间的比赛也不是你表现英雄主义的地方,而是体现团队意识的地方,也是交流沟通的好机会。所以不妨在节目中介绍一下自己团队的产品;不妨在角色设定的时候劝说core team的人加入扮演一个牛人角色(欢乐可以一定程度上冲淡马屁味道);不妨申请印有团队logo的运动衣;不妨在运功过后和高层一同边走边聊(比平时冲到高层办公室里面好的多的机会);不妨去敬HR一杯酒,被她们多灌几杯(HR的办公室是个敏感区,平时很难交流感情啊);不妨去维护机房的团队那里敬酒以感谢他们的工作,去前台那里敬酒以夸赞她们的服装,发型等(他们对你来说真的很重要,想想几百人的团队,前台和运维都只有两三个人,还是那就话,当供需相差很大的时候,价格都会越来越高)。这将使你成为一个受欢迎的人。

(5) 适当的增加影响力

做一个好的基层程序员,除了完成自己的本职工作以外,也需不断增加自己的影响力,这既是你的品牌,也是日后加薪升职不可缺少的因素。

增加影响力主要有以下几种方式:

在工作中,如果完成了一定的功能,或者测试有了详细的报告,可发邮件给领导并cc整个Team,让领导知道你的付出,和同事分享你的喜悦,让众人知道你的亮点。邮件或者报告要在开头做精炼的总结,使得大部分人能够尽快的了解结果,具体细节可放在后面,供同模块的员工详细查阅。千万不要默认你的上司和其他人都显而易见的知道你完成了什么,这也可能是很多人觉得怀才不遇,难遇明主的原因吧。台湾作家黄明坚有一个形象的比喻:“做完蛋糕要记得裱花。有很多做好的蛋糕,因为看起来不够漂亮,所以卖不出去。但是在上面涂满奶油,裱上美丽的花朵,人们自然就会喜欢来买。” 在各类的会议中,如上面所说,事先准备问题,合理提出建议,适时提供证据,都是在同事,领导,以及外国人面前展现自己的机会。 有时候美国有或管理或技术的老大来中国,都会召开all hands,这是一个不可多得的在整个公司面前展现自己的机会。而在外企,程序员的竞争力大约包括对产品的把握,对技术的把握和对英语的把握等能力。all handls也是展现这三种能力的好地方。也许你会发现这样的事实,在all hands上英语流利的提问者们,提出问题的目的也许并不是为了想弄明白什么,而是为了展现什么。他们大多是这样问的:"As what you side A, but actually what we did in our project is B, so how/what/when C",你会发现,A和B会说的很具体,而C很抽象,显然A是为了展现产品把握能力(你讲的我都听懂了),B是为了展现技术把握的能力(我们采取了什么样的技术),整篇都用英语表达自然展现了英语的能力,最后问一个很Open的问题C,总不能问老大个很难的问题吧。 tech talk:当有了一定的技术积累,tech talk是一个很好的展现技术实力的平台,毕竟程序员是吃技术这碗饭的,所以良好的技术口碑对最初的升职至关重要。tech talk所讲的对象一般不是同项目的员工,因而难度要适当的把握,太简单则不足以体现你的技术实力,太难则大家会听的云里雾里,不能真正了解你的价值。在做tech talk的时候,最好一开始有一个整体的流程或者框架的介绍,以使得听众不会在途中迷路。一般有一个规律,就是在最前面几个slides的问题是最多的,大家总能够提出各种各样的问题,所以开始的几页,一定要是你最最熟悉的,最最有价值的,然而随着信息量的增大,后面就几乎提不出什么问题来了,到演讲最后,一般也就只能提出一些open question了,一般可以通过三个阶段轻松回答,其一,that is a good question,其二,it really depends,其三,I'd like to give an example。 demo:在很多施行迭代开发的项目管理的公司里,一个阶段是会有一个demo的。很多程序员重代码,而轻demo,明明实现的非常优雅的功能,却懒得花时间生动的demo出来,中国有句古话:六十四拜都拜了,就差最后一哆嗦,多对不起你前面没黑没夜的工作啊。demo是应该好好准备的,应该有一个详细的demo流程,先录入什么数据,然后如何操作,最后应该看到什么等等。然而demo是容易失败的,似乎成为一个难以规避的定律,即无论原来demo如何准备,临阵总会有意想不到的结果,大概因为看demo的人可能会提出奇怪的尝试需求,而可能正是程序员没有考虑过的边界。所以demo中,应该事先将良好的过程录制下来,以防止真实demo过程中有差错,造成功亏一篑,至少可以证明原来是好的。在demo中一定要用近似真实的数据,如输入人名,就用真实身边的员工姓名,输入日期就用当天的真实日期,千万不要用aaa, bbb, 123456此类的数据,既不美观,也容易出问题。而且在demo的过程中,应该严格按照已经准备好的流程走,当完全走完流程后,方才可以处理现场提出的各种尝试,可保证能够完成demo任务。 帮助他人:在不耽误自己工作的情况下帮助他人解决技术难题,是比tech talk和demo更能够体现技术实力的地方,并会积累下人脉,当众望所归的时候,你的升职也就仅仅是时间和名额问题了。举个相似的例子,tech talk好比是保健医生,只不过是给你宣扬养生之道,而解决技术难题就如同主治医师,可以使你药到病除。很显然,如果一个人如果能够很好的按照保健医生的养生之道去做,就很少会去找主治医师去看病了。然而主治医师却比保健医生更受欢迎,一方面因为相对重要的事情,人们多会更重视紧急的事情,一方面可能因为只有在逆境,出现问题的时候,人们才会虚心接受他人的意见。试想听tech talk的人们,就如同6000点的股市中的股民,多抱有"你懂,我可能比你还懂"的想法,而出现了问题的人们,便如跌至2000点股市的股民,才会虚心向专家请教,并对给出的方案五体投地了。而且此点满足,不忙的时候,主动帮助他人——让上司有效! 培训新人:有时候公司会招来一些学校来的实习生,一年一度也会招很多应届毕业生。当然一般公司都会有各种的培训,然而一旦进入团队的时候,如何更快的上手项目,仍然需要一个过程,如果能有老员工指导一二,将会轻松很多。在项目比较紧的情况下,很多老员工不愿意培训新人,万事开头难,起步总是相对缓慢的,害怕因此而耽误进度。当然,以耽误自己的工作换来对新人的培训我也是不赞成的,这也是后面所说的要给自己留buffer的原因所在。但我需要指出的是,给一个饥饿的人一个烧饼要比其成为千万富翁后给一百万更加让人感恩。人的眼光应该长远一些,无论如何都不要轻视一个年轻人,因为你不知道其将来会是什么样子。有的人,年纪大,level高,但是基本可以看出其一辈子的轨迹了,有的人年纪轻,level低,却可能前途无量,你永远不能把握将来谁会是你的贵人。

在增加的影响力的前面,我加了一个形容词——适当。要有和你的level相匹配的影响力,小心功高盖主啊。外国人有时候会强调leadership without authority,然而如果你果真这样做了,多半会招来同事的敌意(你凭什么指手画脚的啊),也可能会招来你的lead心中的隔阂(没有authority你都能够lead啦,给你authoriy还不反了天了,你lead,那我干嘛),所以还是不在其位,不谋其政的好。

(6) 给别人光环

当同事完成一项功能或修改完一个Bug的时候,你是否给过真诚的赞誉,帮其增加上述的影响力?

当同事帮助你解决了问题或者提出了优秀的方案,你是否公开表示感谢,让群众和领导都知晓?

当领导问及你做的模块的时候,你是否有意隐瞒了他人的功劳而突出自己的贡献?

当会议的时候,你是否会处心积虑的故意反对竞争对手的方案,虽然你觉得其实这真的是个好方案?

当发现其他人的Bug,Code reivew的时候发现他人的设计缺陷,你是否幸灾乐祸的大声疾呼,唯恐他人和领导不知?

你是否在同事,领导,HR的面前非议他人,嘲笑他人的设计,褒贬他人的缺陷,鄙视他人的技术,虽然的确你是此方面的大拿?

当你有幸获得一份荣誉的时候,你是否先谢国家(公司),再谢政府(团队),再谢领导,再谢同事?

给别人光环吧,别人也会给你光环。

一个只顾自己头上光环的人,以及一个别人给了光环而不知回报的人,最终都会孤立无援,难以开展工作,是涸泽而渔的做法。

我们必须承认的一点是,每个人都有自己的长处,也有自己的短处,每个模块都有优美的地方,也有不尽人意的地方,你有你擅长的技术,别人也有别人擅长的方向。如果大家互相向别人的头上套光环,则外人和领导看到的会多数是光环,从而大家精诚合作,团队蒸蒸日上。如果大家全部互相揭疮疤,则外人和领导则看到的会多数是负面的,从而大家互相猜忌,整个团队都没有希望。

历朝历代都有权臣,权臣之间必有党争,派别之间多知道对方的优势,也掌握了对方的把柄,如果派系之间相互合作,则大家都会壮大,皇帝则不会知道下面的暗流涌动,然而英明的皇帝多挑拨派系之间的关系,使他们互相揭露对方的把柄,从而下情上达,从中制衡。

我们也会经常看到,当一家公司的高管离开他的老东家而投奔新东家的时候,公开场合下,此高管多会十分赞誉在老东家中工作过的时光,赞誉工作过的团队,赞誉老东家的产品和项目,赞誉自己在老东家取得的进步,而老东家也多会给与此高管十分积极的评价,肯定其作出的贡献,其为公司带来的价值,其培养出的团队。其实如果两者之间如此的默契,如此的互相满意,就不会发生跳槽的事件了,既然选择分道扬镳,则其中必有隔阂,只不过互相心知肚明,各不言明罢了。这样无论对公司的发展,还是对此高管的职业生涯都有好处。试想,此高管必然是清清楚楚公司的优势劣势,公司也明明白白高管的功过是非,就像一对生活了很久的夫妻,既知道你能言善辩,也知道你鼾声震天,既知道你玉树临风,也知道你不爱洗澡,如果在公开场合互相指责,甚至谩骂,岂不家丑外扬?

(7) Daily report和weekly report很重要

很多程序员宁愿多写程序,也不愿意写report,觉得十分麻烦,而又无聊。

但是Daily report,weekly report真的非常的重要。

首先report可以帮助你管理自己的时间。在时间管理中,我们知道,人总是有重要而紧急的事情,重要而不紧急的事情,不重要而紧急的事情,不重要而不紧急的事情之分。你是否总结和思考过自己真的总是做了重要而紧急的事情么?人们总是忙啊忙,从早忙到晚,天天加班,其实每天都在处理各种各样的突发紧急的事件,使得计划一拖再拖,而忽略了对自己很重要的事情。试想想吧,你原来计划过要读的书有多少是真正去读了的?你在朋友面前畅谈的宏图大志有多少是真正实践过的?你还记得儿时的梦想吗?你是一直向着自己想要的方向在不断的进步吗?时间管理的原则告诉我们,每个人应该有一张思考的床,不要穷忙、瞎忙、无心的忙。写daily report和weekly report不完全是应付上司的,也是自己思考总结的过程啊。我还记得最初每周定计划的情况,当一周过去进行回顾的时候,我当时吓了自己一跳,我原以为自己一直过的非常的充实,却发现计划做得事情真的只做了大概三分之一,照此下去,如何进步啊。有兴趣大家可是试着制定一下计划,越详细越好,工作方面的可以写给上司看,学习,社交等方面的可以自己写给自己,有时候多少有些身在江湖,身不由己的感觉。

其二report可以帮助你总结自己的进步。当天做的事情一般人还是记得的,一个星期做的事情,大概就模糊了,半年前做的事情,则很多细节都忘记了。很多的时候,当我们每年对自己进行年终总结以期待明年加薪的时候,当我们想要跳槽来总结自己忙碌了几年的成果的时候,往往会发现,report到用时方恨少啊。面试的时候,对于有经验的人,往往会将项目经验问的很细很细,当时你为什么选择这种方案呢?系统的速度如何一步步改进提高的?你发现你可能说不清楚了。平时尽量多详细的记录一下自己每天的进步吧,这可是影响到你薪水的闪光点啊,对方的公司正等着一个牛人来提高他们的性能呢,你明明取得很不错的结果,只是忘记了自己做了哪些改进,岂不可惜啊。

其三report可以帮助你增加自己的影响力。如上面所述,report不但可以让自己知道自己做了什么,也可以让上司知道你完成了什么,如果写到wiki上,还能让更多的人知道你的成绩。

其四report可以作为维护权利的证据。这一点前面也说过,作为初入职场的基层,作为相对美国来说弱势的中方,证据是非常重要的。当项目delay的时候,你如何证明你是提前schedule完成的?当性能遇到瓶颈,你如何证明你曾经高效且没有做过改动?在写程序的时候,我们知道,当context不在的时候,唯一能够定位问题的,就是log了,report就是你工作的log。

其五report可以使你的上司对你放心。很多初入职场的基层,埋怨上司过多的干预自己的工作,总是有事没事的过来问,做的如何了?有什么困难?这段时间在做什么?有时候这种询问会打断你的思路,着实让人困扰。其实情有可原,你刚来,不放心是可以理解的。如何做到你办事,他放心是你的责任。当有阶段性成果的时候实时报告自己的状态,每天写daily report报告自己的进度都是让上司放心的办法。一个有意思的现象是,当你一天一封daily report向他汇报的时候,他却不怎么过来干预你的工作了,甚至到最后daily report他也不怎么看了。

做到此一点,方能主动向上司汇报你的工作进度——让上司知道,对上司的询问,有问必答,而且清楚——让上司放心!

(8) 给自己留buffer,学会喊累,学会喊忙

初入职场,激情高涨,多喜欢将自己满负荷运作,无论是需求来自领导还是来自同事,都不好意思拒绝,最后弄得自己疲于奔命,焦头烂额。

其实工作中,是应该给自己留有一定的buffer的,一方面,可以在项目有了突发事件的时候,不至于临阵慌乱,尚有调整和处理的时间,不至于第二天demo,当天晚上代码才完成。另一方面,要做好以上所述的事情,还都是需要buffer的,绝不能够低头干个不停。

另外,公司是要对项目负责的,而自己的职业前途,却只有自己负责。除了每天忙于项目之外,总要有一定的时间进行自我进步,从而提升自己的价值。前面也说过,有的人面试的时候,仅仅知道项目中用到的知识点,而相关的却很少知道,从而使自己的职业生涯既不广,也不深。所以日常工作中,留有一定的buffer来将知识点变成知识面是很重要的。

所以如果你真的很忙,真的很累,要勇于喊出来,而不要默默的承受着,当然这不是让你装忙装累,而是向周围散发出一种信息,就是你已经负荷较满了。这样你的领导在安排任务的时候,会综合考虑,你的同事在向你提出需求的时候,也拒绝的合情合理。当然你不能总是喊忙,总是不出成果,如第一点中所说,result永远是最重要的。而总是喊忙,总是能出成果,确是一种工作努力的表现。有的人认为,只有相互说话才叫沟通,其实不然,殊不知自言自语,凝重的表情,同样是沟通的手段。

也只有在有buffer的情况下,你才能做到充实自己,努力学习,才能了解上司的言语——让上司轻松,你才能够做到对自己的业务,主动提出改善计划——让上司进步。

 
2010-01-28 2:02
<?php  
  1. include_once(getenv('HOME').'/autoload.php');  
  2. $oDb = Db::get('account');  
  3. $oDb->query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');  
  4. //$oDb->query('SET TRANSACTION ISOLATION LEVEL REPEATABLE READ');  
  5. $queryRead = "select count(*) from test where name=1";  
  6. $query = "insert into test(name) values(1)";  
  7. try{  
  8.     $oDb->beginTransaction();  
  9.     $stmtRead = $oDb->prepare($queryRead);  
  10.     $stmtRead->execute();  
  11.     $r = $stmtRead->fetchColumn();  
  12.     var_dump($r);  
  13.     if(!$r){  
  14.     $stmt = $oDb->prepare($query);  
  15.     $stmt->execute();  
  16.     }  
  17.     sleep(10);  
  18.     $oDb->commit();  
  19. }catch(Exception $e){  
  20.     echo $e;  
  21.     $oDb->rollBack();  
  22. }  

其中sleep是为了模拟web环境的慢速操作。上述代码需要同时执行两个进程

上面是测试代码,这段代码的本意是,如果找到name=1的那条数据,那么就不再插入。mysql事务隔离有四个级别

1.READ UNCOMMITTED-读未提交

2.READ COMMITTE-读已提交

3.REPEATABLE READ -可重复读

4.SERIALIZABLE -串行

经过测试第一种和第四种即READ UNCOMMITED和SERIALIZABLE满足需求,其他级别下均会重复插入。

第一种情况,手册里说它是“脏读”。实验中发现它可以读取别的事务还没有提交的数据。如果第一个事务提交失败,那么整个业务不管同时被请求多少次, 都会执行失败。因为第二个事务已经读取了第一个事务的“脏数据”,所以,它不会再去执行插入的操作,而如果第一个事务执行失败,则整个业务等于没有被执 行。当然它也会造成在同一事务内读取的同一条数据不同的问题。

第二种,一直没弄明白,如果谁弄的很清楚了,请告诉我一声。

第三种,可重复读取,意思是在同一事务中两次读取同一条数据的结果是一样的。当然,在别的进程读取的也是原先的未被修改的数据。这是mysql默认的事务隔离级别。如果在这种级别下并发2个或者多个进程执行上述代码,不管有没有开启事务,读取的都是未提交之前的数据。

第四种,串行。我测试的结果是,如果同时两个进程执行上面的代码的话,第二个执行的必须等待,也就是在第一个进程没有完成之前,第二个进程不能读取,更别说操作了。但是,如果没有开启事务,则可以读取,但是读取的还是提交之前的数据。

最后附上事务的特性,和一些相关的问题。

事务的基本特性


l Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。

l Consistency(一致性):只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。

l Isolation(隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。

l Durability(持久性):事务结束后,事务处理的结果必须能够得到固化。


共享数据库可能出现的问题
l 更新丢失(Lost update):两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。

l 脏读取(Dirty Reads):一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险的,因为很可能所有的操作都被回滚。

l 不可重复读取(Non-repeatable Reads):一个事务对同一行数据重复读取两次,但是却得到了不同的结果。例如,在两次读取的中途,有另外一个事务对该行数据进行了修改,并提交。

l 两次更新问题(Second lost updates problem):无法重复读取的特例。有两个并发事务同时读取同一行数据,然后其中一个对它进行修改提交,而另一个也进行了修改提交。这就会造成第一次写操作失效。

l 虚读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。

|加上我这种重复记录的情况,这种情况只有使用最后一种才可以完全避免,当然这会对数据库的性能产生极大影响。所以,需要具有比较完善的架构。

当然,我觉得这既是值得的,也是可行的。在大部分的读取中,都可以读取缓存,当然事务中的读取除外。而把大部分的数据库都用来写。

数据库应该只作为一个存储的地方,而不应该还有过多的业务逻辑,因为始终sql这种是无法面向最终用户的,一般情况下,数据只有在程序的解释下才能有正确的含义。

 
2009-10-27 0:51
好文章先收藏啦, http://www.linuxsir.org/bbs/printthread.php?t=266890

介绍

如何使用dlopen API动态地加载C++函数和类,是Unix C++程序员经常碰到的问题。事实上,情况偶尔有些复杂,需要一些解释。这正是写这篇mini HOWTO的缘由。
理解这篇文档的前提是对C/C++语言中dlopen API有基本的了解。这篇HOWTO的维护链接是 http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/

  版权和许可证
这篇文档《C++ dlopen mini HOWTO》版权为Aaron Isotton所有(copyrighted (c) 2002-2006),任何人在遵守自由软件基金会制定的GPLv2许可证条款前提下可以自由拷贝、分发和修改这份文档。

  不承诺
本文不对文中的任何内容作可靠性承诺。您必须为您自己使用文中任何概念、示例和信息承担风险,因为其中可能存在错误和不准确的地方,或许会损坏您的系统──尽管几乎不可能发生此类事故,但您还是小心行事──作者不会为此负任何责任。

  贡献者
在这篇文档中,我欣然致谢(按字母顺序):
◆ Joy Y Goodreau <joyg (at) us.ibm.com> 她的编辑工作.
◆ D. Stimitis <stimitis (at) idcomm.com> 指出一些formatting和name mangling的问题, 还指出extern “C”的一些微妙之处。

  反馈
欢迎对本文档的反馈信息!请把您的补充、评论和批评发送到这个邮件地址:<aaron@isotton.com>。

  术语
dlopen API
关于dlclose、dlerror、dlopen和dlsym函数的描述可以在 dlopen(3) man手册页查到。
请注意,我们使用“dlopen”时,指的是dlopen函数,而使用“dlopen API”则是指整个API集合。
------------------------------------------------
问题所在
有时你想在运行时加载一个库(并使用其中的函数),这在你为你的程序写一些插件或模块架构的时候经常发生。
在C语言中,加载一个库轻而易举(调用dlopen、dlsym和dlclose就够了),但对C++来说,情况稍微复杂。动态加载一个C++库的困 难一部分是因为C++的name mangling(译者注:也有人把它翻译为“名字毁坏”,我觉得还是不翻译好),另一部分是因为dlopen API是用C语言实现的,因而没有提供一个合适的方式来装载类。
在解释如何装载C++库之前,最好再详细了解一下name mangling。我推荐您了解一下它,即使您对它不感兴趣。因为这有助于您理解问题是如何产生的,如何才能解决它们。

  Name Mangling
在每个C++程序(或库、目标文件)中,所有非静态(non-static)函数在二进制文件中都是以“符号(symbol)”形式出现的。这些符号都是唯一的字符串,从而把各个函数在程序、库、目标文件中区分开来。
在C中,符号名正是函数名:strcpy函数的符号名就是“strcpy”,等等。这可能是因为两个非静态函数的名字一定各不相同的缘故。
而C++允许重载(不同的函数有相同的名字但不同的参数),并且有很多C所没有的特性──比如类、成员函数、异常说明──几乎不可能直接用函数名作符 号名。为了解决这个问题,C++采用了所谓的name mangling。它把函数名和一些信息(如参数数量和大小)杂糅在一起,改造成奇形怪状,只有编译器才懂的符号名。例如,被mangle后的foo可能 看起来像foo@4%6^,或者,符号名里头甚至不包括“foo”。
其中一个问题是,C++标准(目前是[ISO14882])并没有定义名字必须如何被mangle,所以每个编译器都按自己的方式来进行name mangling。有些编译器甚至在不同版本间更换mangling算法(尤其是g++ 2.x和3.x)。即使您搞清楚了您的编译器到底怎么进行mangling的,从而可以用dlsym调用函数了,但可能仅仅限于您手头的这个编译器而已, 而无法在下一版编译器下工作。

  类
使用dlopen API的另一个问题是,它只支持加载函数。但在C++中,您可能要用到库中的一个类,而这需要创建该类的一个实例,这不容易做到。

解决方案

extern "C"
C++有个特定的关键字用来声明采用C binding的函数:extern "C" 。 用 extern "C"声明的函数将使用函数名作符号名,就像C函数一样。因此,只有非成员函数才能被声明为extern "C",并且不能被重载。尽管限制多多,extern "C"函数还是非常有用,因为它们可以象C函数一样被dlopen动态加载。冠以extern "C"限定符后,并不意味着函数中无法使用C++代码了,相反,它仍然是一个完全的C++函数,可以使用任何C++特性和各种类型的参数。

加载函数
在C++中,函数用dlsym加载,就像C中一样。不过,该函数要用extern "C"限定符声明以防止其符号名被mangle。

。。。
 
2009-09-20 23:33
今天和mm去看了卡地亚珍宝艺术展,太帅气了,法国人的手工真是精细,先上PP
























 
2009-08-21 14:31
在网上google,baidu了半天,居然没有找到相关的资料,最后没办法,去看了C的inet_aton函数的源码,最后一句 if (addr) addr->s_addr = htonl(val); ,在php里面实现htonl搞定,

htonl 将主机的无符号长整形数转换成网络字节顺序。
unpack("N",pack("L",$a)) 的效果和htonl相同
L unsigned long (always 32 bit, machine byte order)
N unsigned long (always 32 bit, big endian byte order)

Big-Endian 和 Little-Endian 字节排序
字节排序
含义
Big-Endian
一个Word中的高位的Byte放在内存中这个Word区域的低地址处。
Little-Endian
一个Word中的低位的Byte放在内存中这个Word区域的低地址处。
必须注意的是:表中一个Word的长度是16位,一个Byte的长度是8位。如果一个数超过一个Word的长度,必须先按Word分成若干部分,然后每一部分(即每个Word内部)按Big-Endian或Little-Endian的不同操作来处理字节。

所以,Big-Endian就是网络字节顺序

function inet_aton($ip){
$a = ip2long($ip);
$b = unpack("N",pack("L",$a));
return $b[1];
}
 
2009-06-07 23:51

“80后者,初从文,未及义务教育之免费,不逮高等学校之分配,适值扩招,过五关,斩六将,硕博相继,数年乃成,负债十万。觅生计,十年无休,披星 戴月,秉烛达旦,蓄十万。楼市暴涨,不足购房,遂投股市,翌年缩至万余,抑郁成疾。医保曰,不符大病之条例,拒赔。”这段描述80后的文字,调侃的背后有 一种深深的无奈。如果说这些无奈可以以自嘲的方式分享,而下面的这些寂寞却与谁说……

  1、独自在街道上游荡,看着街道上熙熙攘攘的人群,那些欢笑着的脸孔,那些都是不属于你的,你只是一个过客,什么也带不走,什么也留不下 ,再怎样的热闹,再怎样的繁华,却越发衬托你的形单影只 ,在人群中,你默然抬起头,却找不到一张熟悉的面孔……

      
2、一个人蜷缩在床上,无法入睡,脑子里想着莫名其妙的问题,黑暗犹如一张巨大的蛛网把你包裹在内,厚厚的棉被里,你感觉 好冷 ,从枕头下掏出手机,却发现你不知道该打给谁,于是,无奈的又塞回枕头中 ,你把头缩进被子里,轻轻的抱住自己的膝盖,像一个孩子把自己抱紧一点,那么,就不会冷了吧……

      
3、你恨一些人,一些事,甚至恨着这个世界 ,你总是在想,为什么是你 ,为什么承受一切痛苦的都必须是你 ,你只想做一个普普通通的小孩子,开心过完自己的童年,读书,找工作,恋爱……可是,这么普通的一切,对于你,却如此的难……你感觉背后似乎有一双眼睛, 带着讽刺的笑意看着你,然后,摇摇头,走开了……

      
4、面对着电脑发呆,身边的咖啡已经渐渐发凉,耳机里绵延出悠扬的音乐声,此时,已是凌晨,你也不知道是什么时候变成这样 的,像是一个穴居动物一般,躲在自己的窝里不想出来,什么时候,开始害怕外面的阳光,讨厌出门,面对着门外的那些人,你觉得他们甚至没有你那台冰冷的电脑 亲切,有时,虚拟世界,确实要比现实世界美丽……


5、你靠在窗边,透过蒙蒙细雨,静静的看着这个陌生的城市,你 不知道要在这里停留多久,你不知道你会遇见什么样的人,不也不知道你会留下怎样的回忆……点一支烟,烟雾缭绕中,你静静的咪上眼,享受这一刻的寂静,过去 的一切就让他这样过去吧,从今开始,你要学会认识陌生的人,做陌生的事,过陌生的生活……独在异乡为异客……


6、你习惯一个人在学校的走道上手插口袋漫步徜徉,没有目标,没有终点,你只是想这样一步一步的走下去,走到自己筋疲力尽为止,你学会在这种只属于一个人 的时间里,独自思考着解开一些问题,无论你的结论是对是错,都已经不重要了……你看着那热闹的操场,嘴角,轻轻上扬着一丝微笑,夕阳下,你的影子拉的好 长……


7、你在梦里看到她/他的离开,哭泣着从梦里醒来,看着空荡的房间,你静静的走到洗脸台前,看着镜子里,自己苍白而憔悴的脸,你一瞬间泪流满面……


8、你清晨起床,家中空无一人,你给自己泡了一杯牛奶,呵着暖暖的热气坐在阳台上的沙发里,随手翻开着旁边厚厚的书籍,冬日的阳光懒散而温暖的照在你身上 周围寂静而安详,不知不觉中,你再次睡着,轻声打着呼噜,如同一只懒猫。


9、你一直沉醉在回忆里,不愿意醒来,你想起以前和朋友在一起的场面,便会微微发笑,你想起以前的一些窘事,便会微微脸红,你想起以前的一些无奈,便会轻声长叹,你想起了她,便会死死的咬住下唇,你害怕……你会哭出声来……


10、你在酒吧里点一支啤酒,听着震耳欲聋的音乐,看着舞池里扭动着的人群,你漫无表情,冰冷的啤酒从食道一直凉到胃里,你轻声的呻吟…… 然后,随着眩目的灯光,脚轻轻的打着拍子,巴台上,你的背影像是一尊石像……


11、学会不再哭泣,学会不再透露自己的感情,他们说你冷血,你却只是在那里微笑,你知道,没有必要试图让别人了解你,知我者为我分忧,不知我者谓我何 求,眼泪解决不了任何问题,只会带来吵闹,很多的事情,我们可以感动,却不能流泪,因为一旦放任自己的感情,怕会让自己泣不成声。


12、参加一场聚会,喝很多酒,却一直没有醉倒,眯着一双眼睛看这个世界,光怪而陆离,告诉自己,你喜欢这种感觉,独自去洗脸台,泼了点冷水在脸上,然后看着镜子一个人傻笑,醉后……世界好美……


13、默默的喜欢上她/他,却不敢玷污这份感情,一直将它默默珍藏,无论她多么的骄横,无论她多么的不讲道理,无论她让你气上多少次,你都一直在让着 她,你明白你现在给不了她什么,你明白现实比爱情残酷,你明白,等你能够给她想要的东西时,你才配去爱她……最后,当你鼓起勇气去找她,去寻觅每一个她可 能在的角落,想跟她说明白一切时,却发现她的身边,已经有了一个能够让她幸福的人不爱她的理由有很多,爱她的理由……已经不存在了……

小评:80后们,最缺的就是沟通,因为怕伤害也怕被伤害。

总是把自己裹在密不通风的外套里。

也许,只有某一缕阳光能够救赎这本该属于我们的世界~

 
2009-05-24 11:19

作者 Stefan Tilkov 译者 苑永凯

不知你是否意识到,围绕着什么才是实现异构的应用到应用通信的“正确”方式,一场争论正进行的如火如荼:虽然当前主流的方式明显地集中在基于 SOAP、WSDL和WS-*规范的Web Services领域,但也有少数人用细小但洪亮的声音主张说更好的方式是REST,表述性状态转移(REpresentational State Transfer)的简称。在本文中,我不会涉及争论的话题,而是尝试对REST和RESTful HTTP应用集成做实用性的介绍。以我的经验,有些话题一旦触及就会引来众多的讨论,当涉及到这方面话题的时候,我会深入详细地阐述。

REST关键原则

大部分对REST的介绍是以其正式的定义和背景作为开场的。但这儿且先按下不表,我先提出一个简单扼要的定义:REST定义了应该如何正确地使用 (这和大多数人的实际使用方式有很大不同)Web标准,例如HTTP和URI。如果你在设计应用程序时能坚持REST原则,那就预示着你将会得到一个使用 了优质Web架构(这将让你受益)的系统。总之,五条关键原则列举如下:

  • 为所有“事物”定义ID
  • 将所有事物链接在一起
  • 使用标准方法
  • 资源多重表述
  • 无状态通信

下面让我们进一步审视这些原则。

为所有“事物”定义ID

在这里我使用了“事物”来代替更正式准确的术语“资源”,因为一条如此简单的原则,不应该被淹没在术语当中。思考一下人们构建的系统,通常会找到一 系列值得被标识的关键抽象。每个事物都应该是可标识的,都应该拥有一个明显的ID——在Web中,代表ID的统一概念是:URI。URI构成了一个全局命 名空间,使用URI标识你的关键资源意味着它们获得了一个唯一、全局的ID。

对事物使用一致的命名规则(naming scheme)最主要的好处就是你不需要提出自己的规则——而是依靠某个已被定义,在全球范围中几乎完美运行,并且能被绝大多数人所理解的规则。想一下你 构建的上一个应用(假设它不是采用RESTful方式构建的)中的任意一个高级对象(high-level object),那就很有可能看到许多从使用唯一标识中受益的用例。比如,如果你的应用中包含一个对顾客的抽象,那么我可以相当肯定,用户会希望将一个指 向某个顾客的链接,能通过电子邮件发送到同事那里,或者加入到浏览器的书签中,甚至写到纸上。更透彻地讲:如果在一个类似于Amazon.com的在线商 城中,没有用唯一的ID(一个URI)标识它的每一件商品,可想而知这将是多么可怕的业务决策。

当面对这个原则时,许多人惊讶于这是否意味着需要直接向外界暴露数据库记录(或者数据库记录ID)——自从多年以来面向对象的实践告诫我们,要将持 久化的信息作为实现细节隐藏起来之后,哪怕是刚有点想法都常会使人惊恐。但是这条原则与隐藏实现细节两者之间并没有任何冲突:通常,值得被URI标识的事 物——资源——要比数据库记录抽象的多。例如,一个定单资源可以由定单项、地址以及许多其它方面(可能不希望作为单独标识的资源暴露出来)组成。标识所有 值得标识的事物,领会这个观念可以进一步引导你创造出在传统的应用程序设计中不常见的资源:一个流程或者流程步骤、一次销售、一次谈判、一份报价请求—— 这都是应该被标识的事物的示例。同样,这也会导致创建比非RESTful设计更多的持久化实体。

下面是一些你可能想到的URI的例子:

http://example.com/customers/1234
http://example.com/orders/2007/10/776654
http://example.com/products/4554
http://example.com/processes/salary-increase-234

正如我选择了创建便于阅读的URI——这是个有用的观点,尽管不是RESTful设计所必须的——应该能十分容易地推测出URI的含义:它们明显地标识着单一“数据项”。但是再往下看:

http://example.com/orders/2007/11
http://example.com/products?color=green

首先,这两个URI看起来与之前的稍有不同——毕竟,它们不是对一件事物的标识,而是对一类事物集合的标识(假定第一个URI标识了所有在2007年11月份提交的定单,第二个则是绿颜色产品的集合)。但是这些集合自身也是事物(资源),也应该被标识。

注意,使用唯一、全局统一的命名规则的好处,既适用于浏览器中的Web应用,也适用于机对机(machine-to-machine,m2m)通信。

来对第一个原则做下总结:使用URI标识所有值得标识的事物,特别是应用中提供的所有“高级”资源,无论这些资源代表单一数据项、数据项集合、虚拟亦或实际的对象还是计算结果等。

将所有事物链接在一起

接下来要讨论的原则有一个有点令人害怕的正式描述:“超媒体被当作应用状态引擎(Hypermedia as the engine of application state)”,有时简写为HATEOAS。(严格地说,这不是我说的。)这个描述的核心是超媒体概念,换句话说:是链接的思想。链接是我们在HTML中常见的概念,但是它的用处绝不局限于此(用于人们网络浏览)。考虑一下下面这个虚构的XML片段:

 
23


如果你观察文档中product和customer的链接,就可以很容易地想象到,应用程序(已经检索过文档)如何“跟随”链接检索更多的信息。当然,如果使用一个遵守专用命名规范的简单“id”属性作为链接,也是可行的——但是仅限于应用环境之内。使用URI表示链接的优雅之处在于,链接可以指向由不同应用、不同服务器甚至位于另一个大陆上的不同公司提供的资源——因为URI命名规范是全球标准,构成Web的所有资源都可以互联互通。

超媒体原则还有一个更重要的方面——应用“状态”。简而言之,实际上服务器端(如果你愿意,也可以叫服务提供者)为客户端(服务消费者)提供一组链 接,使客户端能通过链接将应用从一个状态改变为另一个状态。稍后我们会在另一篇文章中探究这个方面的影响;目前,只需要记住:链接是构成动态应用的非常有 效的方式。

对此原则总结如下:任何可能的情况下,使用链接指引可以被标识的事物(资源)。也正是超链接造就了现在的Web。

使用标准方法

在前两个原则的讨论中暗含着一个假设:接收URI的应用程序可以通过URI明确地一些有意义的事情。如果你在公共汽车上看到一个URI,你可以将它输入浏览器的地址栏中并回车——但是你的浏览器如何知道需要对这个URI做些什么呢?

它知道如何去处理URI的原因在于所有的资源都支持同样的接口,一套同样的方法(只要你乐意,也可以称为操作)集合。在HTTP中这被叫做动词 (verb),除了两个大家熟知的(GET和POST)之外,标准方法集合中还包含PUT、DELETE、HEAD和OPTIONS。这些方法的含义连同 行为许诺都一起定义在HTTP规范之中。如果你是一名OO开发人员,就可以想象到RESTful HTTP方案中的所有资源都继承自类似于这样的一个类(采用类Java、C#的伪语法描述,请注意关键的方法):

class Resource {
Resource(URI u);
Response get();
Response post(Request r);
Response put(Request r);
Response delete();
}

由于所有资源使用了同样的接口,你可以依此使用GET方法检索一个表述(representation)——也 就是对资源的描述。因为规范中定义了GET的语义,所以可以肯定当你调用它的时候不需要对后果负责——这就是为什么可以“安全”地调用此方法。GET方法 支持非常高效、成熟的缓存,所以在很多情况下,你甚至不需要向服务器发送请求。还可以肯定的是,GET方法具有幂等性[译 注:指多个相同请求返回相同的结果]——如果你发送了一个GET请求没有得到结果,你可能不知道原因是请求未能到达目的地,还是响应在反馈的途中丢失了。 幂等性保证了你可以简单地再发送一次请求解决问题。幂等性同样适用于PUT(基本的含义是“更新资源数据,如果资源不存在的话,则根据此URI创建一个新 的资源”)和DELETE(你完全可以一遍又一遍地操作它,直到得出结论——删除不存在的东西没有任何问题)方法。POST方法,通常表示“创建一个新资 源”,也能被用于调用任过程,因而它既不安全也不具有幂等性。

如果你采用RESTful的方式暴露应用功能(如果你乐意,也可以称为服务功能),那这条原则和它的约束同样也适用于你。如果你已经习惯于另外的设计方式,则很难去接受这条原则——毕竟,你很可能认为你的应用包含了超出这些操作表达范围的逻辑。请允许我花费一些时间来让你相信不存在这样的情况。

来看下面这个简单的采购方案例子:

Sample Scenario

可以看到,例子中定义了两个服务程序(没有包含任何实现细节)。这些服务程序的接口都是为了完成任务(正是我们讨论的 OrderManagement和CustomerManagement服务)而定制的。如果客户端程序试图使用这些服务,那它必须针对这些特定接口进行 编码——不可能在这些接口定义之前,使用客户程序去有目的地和接口协作。这些接口定义了服务程序的应用协议(application protocol)。

在RESTful HTTP方式中,你将通过组成HTTP应用协议的通用接口访问服务程序。你可能会想出像这样的方式:

Sample Scenario, done RESTfully

可以看到,服务程序中的特定操作被映射成为标准的HTTP方法——为了消除歧义,我创建了一组全新的资源。“这是骗人的把戏”,我听见你叫嚷着。 不,这不是欺骗。标识一个顾客的URI上的GET方法正好相当于getCustomerDetails操作。有人用三角形形象化地说明了这一点:

Knobs one can turn

把三个顶点想象为你可以调节的按钮。可以看到在第一种方法中,你拥有许多操作,许多种类的数据以及固定数量的“实例”(本质上和你拥有的服务程序数 量一致)。在第二种方法中,你拥有固定数量的操作,许多种类的数据和许多调用固定方法的对象。它的意义在于,证明了通过这两种方式,你基本上可以表示任何 你喜欢的事情。

为什么使用标准方法如此重要?从根本上说,它使你的应用成为Web的一部分——应用程序为Web变成Internet上最成功的应用所做的贡献,与 它添加到Web中的资源数量成比例。采用RESTful方式,一个应用可能会向Web中添加数以百万计的客户URI;如果采用CORBA技术并维持应用的 原有设计方式,那它的贡献大抵只是一个“端点(endpoint)”——就好比一个非常小的门,仅仅允许有钥匙的人进入其中的资源域。

统一接口也使得所有理解HTTP应用协议的组件能与你的应用交互。通用客户程序(generic client)就是从中受益的组件的例子,例如curl、wget、代理、缓存、HTTP服务器、网关还有Google、Yahoo!、MSN等等。

总结如下:为使客户端程序能与你的资源相互协作,资源应该正确地实现默认的应用协议(HTTP),也就是使用标准的GET、PUT、POST和DELETE方法。

资源多重表述

到目前为止我们一直忽略了一个稍微复杂的问题:客户程序如何知道该怎样处理检索到的数据,比如作为GET或者POST请求的结果?原因是,HTTP 采取的方式是允许数据处理和操作调用之间关系分离的。换句话说,如果客户程序知道如何处理一种特定的数据格式,那就可以与所有提供这种表述格式的资源交 互。让我们再用一个例子来阐明这个观点。利用HTTP内容协商(content negotiation),客户程序可以请求一种特定格式的表述:

GET /customers/1234 HTTP/1.1
Host: example.com
Accept: application/vnd.mycompany.customer+xml

请求的结果可能是一些由公司专有的XML格式表述的客户信息。假设客户程序发送另外一个不同的请求,就如下面这样:

GET /customers/1234 HTTP/1.1
Host: example.com
Accept: text/x-vcard

结果则可能是VCard格式的客户地址。(在这里我没有展示响应的内容,在其HTTP Content-type头中应该包含着关于数据类型的元数据。)这说明为什么理想的情况下,资源表述应该采用标准格式——如果客户程序对HTTP应用协 议和一组数据格式都有所“了解”,那么它就可以用一种有意义的方式与世界上任意一个RESTful HTTP应用交互。 不幸的是,我们不可能拿到所有东西的标准格式,但是,或许我们可以想到在公司或者一些合作伙伴中使用标准格式来营造一个小环境。当然以上情况不仅适用于从 服务器端到客户端的数据,反之既然——倘若从客户端传来的数据符合应用协议,那么服务器端就可以使用特定的格式处理数据,而不去关心客户端的类型。

在实践中,资源多重表述还有着其它重要的好处:如果你为你的资源提供HTML和XML两种表述方式,那这些资源不仅可以被你的应用所用,还可以被任意标准Web浏览器所用——也就是说,你的应用信息可以被所有会使用Web的人获取到。

资源多重表述还有另外一种使用方式:你可以将应用的Web UI纳入到Web API中——毕竟,API的设计通常是由UI可以提供的功能驱动的,而UI也是通过API执行动作的。将这两个任务合二为一带来了令人惊讶的好处,这使得 使用者和调用程序都能得到更好的Web接口。

总结:针对不同的需求提供资源多重表述。

无状态通信

无状态通信是我要讲到的最后一个原则。首先,需要着重强调的是,虽然REST包含无状态性(statelessness)的观念,但这并不是说暴露功能的应用不能有状态——
事 实上,在大部分情况下这会导致整个做法没有任何用处。REST要求状态要么被放入资源状态中,要么保存在客户端上。或者换句话说,服务器端不能保持除了单 次请求之外的,任何与其通信的客户端的通信状态。这样做的最直接的理由就是可伸缩性—— 如果服务器需要保持客户端状态,那么大量的客户端交互会严重影响服务器的内存可用空间(footprint)。(注意,要做到无状态通信往往需要需要一些 重新设计——不能简单地将一些session状态绑缚在URI上,然后就宣称这个应用是RESTful。)

但除此以外,其它方面可能显得更为重要:无状态约束使服务器的变化对客户端是不可见的,因为在两次连续的请求中,客户端并不依赖于同一台服务器。一 个客户端从某台服务器上收到一份包含链接的文档,当它要做一些处理时,这台服务器宕掉了,可能是硬盘坏掉而被拿去修理,可能是软件需要升级重启——如果这 个客户端访问了从这台服务器接收的链接,它不会察觉到后台的服务器已经改变了。

理论上的REST

我承认:以上我所说的REST不是真正的REST,而且我可能有点过多地热衷于简单化。但因为我想有一个与众不同的开场,所以没有在一开始就介绍其正式的定义和背景。现在就让我们稍微简要地介绍一下这方面的内容。

首先,先前我并没有明确地区分HTTP、RESTful HTTP和REST。要理解这些不同方面之间的关系,我们要先来看看REST的历史。

Roy T. Fielding在他的博士学位论文(实际上你应该访问这个链接——至少对于一篇学术论文来说,它是相当易读的。此论文已被翻译成中文) 中定义了术语REST。Roy曾是许多基本Web协议的主要设计者,其中包括HTTP和URIs,并且他在论文中对这些协议提出了很多想法。(这篇论文被 誉为“REST圣经”,这是恰当的——毕竟,是作者发明了这个术语,所以在定义上,他写的任何内容都被认为是权威的。)在论文中,Roy首先定义一种方法 论来谈论架构风格——高级、抽象的模式,来表达架构方法背后的核心理念。每一个架构风格由一系列的约束(constraints)定义形成。架构风格的例子包括“没有风格”(根本没有任何约束)、管道和过滤器(pipe and filter)、客户端/服务器、分布式对象以及——你猜到它了——REST。

如果对你来说这些听起来都太抽象了,那就对了——REST在本质上是一个可以被许多不同技术实现的高层次的风格,而且可以被实例化——通过为它的抽 象特性赋上不同的值。比如,REST中包含资源和统一接口的概念——也就是说,所有资源都应该对这些相同的方法作出反应。但是REST并没有说明是哪些方 法,或者有多少方法。

REST风格的一个“化身”便是HTTP(以及一套相关的一套标准,比如URI),或者稍微抽象一些:Web架构自身。接着上面的例子,HTTP使 用HTTP动词作为REST统一接口的“实例”。由于Fielding是在Web已经(或者至少是大部分)“完善”了之后才定义的REST风格,有人可能 会争论两者是不是100%的匹配。但是无论如何,整体上来说Web、HTTP和URI仅仅是REST风格的一个主要实现。不过,由于Roy Fielding即是REST论文的作者,又对Web架构设计有过深远的影响,两者相似也在情理之中。

最后,我在前面一次又一次地使用着术语“RESTful HTTP”,原因很简单:许多使用HTTP的应用因为一些理由并没有遵循REST原则,有人会说使用HTTP而不遵循REST原则就等同于滥用HTTP。 当然这听起来有点狂热——事实上违反REST约束的原因通常是,仅仅因为每个约束带来的设计权衡可能不适合于一些特殊情况。但通常,违背REST约束的原 因可归咎于对其好处认知的缺乏。来看一个明显的反面案例:使用HTTP GET调用类似于删除对象的操作,这违反了REST的安全约束和一般性常识(客户程序不应为此负责,服务器端开发人员大概不是有意而为之)。但在随后的文 章中,我会提及更多这样或那样的对HTTP的滥用。

总结

本文试图对REST(Web架构)背后的概念提供快速的介绍。RESTful HTTP暴露功能的方式与RPC、分布式对象以及Web Services是不相同的;要真正理解这些不同是需要一些心态的转变。不管你构建的应用是仅仅想暴露Web UI还是想把API变成Web的一份子,了解下REST的原则还是有好处的。

Stefan Tilkov是InfoQ SOA社区的首席编辑,并且是位于德国和瑞士的innoQ公司的共同创始人、首席顾问和REST狂热分子首领。

查看英文原文A Brief Introduction to REST
 
2009-05-16 1:41
晚上研究了一小会,发现wget spider模式不太稳健,有的server屏蔽了header方法,在这个时候,只好用socket去连接服务器获取啦,
嘿嘿,file_get_contents居然支持,真是爽呀,
强大无比的curl中Range参数居然没用,有些失望~~~

/**
* @author: kevinchenkai[at]gmail.com
*/
function getResponseHeader($url){
    $aContext = array(
        'http' => array(
            'User-Agent' => 'Baiduspider+(+http://www.baidu.com/search/spider.htm)',
            'Accept-Encoding' => 'gzip,deflate',
            'Referer' => $url,
        ),
    );
    $cxContext = stream_context_create($aContext);
    $sFile = file_get_contents($url, False, $cxContext,0,0); // 不获取任何的数据
    return implode("\n",$http_response_header);
}

function wgetResponseHeader($url){
    $tmp = "/tmp/" . md5($url . date("YmdHis"));
    $cmd = "wget --spider --server-response --user-agent='Baiduspider+(+http://www.baidu.com/search/spider.htm)' -o {$tmp} {$url}";
    exec($cmd);
    $cnt = file_get_contents($tmp);
    unlink($tmp);
    return $cnt;
}

$url = "http://www.sina.com.cn";
$url = "http://hi.baidu.com/ismayday/rss";
echo wgetResponseHeader($url);
echo getResponseHeader($url);
 
2009-05-12 10:11

InnoDB做为MySQL目前最广泛的事务存储引擎,很多地方的设计和Oracle都是共通的。对于Oracle DBA来说,学习的时候可以多和Oracle的一些特性进行类比,当然也要明白二者之间的区别。

innodb_additional_mem_pool_size

用于缓存InnoDB数据字典及其他内部结构的内存池大小,类似于Oracle的library cache。这不是一个强制参数,可以被突破。

innodb_buffer_pool_size

内存缓冲池大小,用于缓存表和索引数据等。类似于Oracle的buffer cache,如果可能,尽可能的设置大一点。

innodb_log_buffer_size

日志缓冲区大小,类似于Oracle的log buffer

innodb_log_file_size

日志文件大小。默认会创建2个5M大小的名为ib_logfile0和ib_logfile1的文件。日志文件的数目由参数innodb_log_files_in_group指定。存放位置由innodb_log_group_home_dir指定。

innodb_data_file_path

指定InnoDB表空间数据文件名,大小以及其他属性。所有文件的加起来不能少于10M。多个数据文件之间以逗号分割,属性之间以冒号分割。默认创 建一个大小10MB名为ibdata1的可自动扩展的数据文件,一般在生产环境中都需要根据实际情况指定,由于往表空间中添加数据文件需要停机,尽量在规 划的时候做好准备,如果可以的话最好开启最后一个数据文件的自动增长属性。数据文件的个数在规划的时候还需要考虑另外一个innodb_open_files参数。

innodb_file_per_table

取值为ON或者OFF。是否为每个table使用单独的数据文件保存。如果系统中表的个数不多,并且没有超大表,使用该参数可以使得各个表之间的维护相对独立,有一定的好处。

innodb_autoextend_increment

当自动扩展表空间被填满之时,每次扩展空间的大小,默认值是8(单位MB)。该参数可以动态修改:

mysql> set global innodb_autoextend_increment=10;
Query OK, 0 rows affected (0.01 sec)

innodb_status_file

定期将show inndb status的结果输出保存到文件中,建议开启以便分析性能。

下面是windows上一个MySQL默认的参数查询结果:

mysql> show variables like ‘Innodb%’;
+———————————+————————+
| Variable_name | Value |
+———————————+————————+
| innodb_additional_mem_pool_size | 2097152 |
| innodb_autoextend_increment | 8 |
| innodb_buffer_pool_awe_mem_mb | 0 |
| innodb_buffer_pool_size | 8388608 |
| innodb_checksums | ON |
| innodb_commit_concurrency | 0 |
| innodb_concurrency_tickets | 500 |
| innodb_data_file_path | ibdata1:10M:autoextend |
| innodb_data_home_dir | |
| innodb_doublewrite | ON |
| innodb_fast_shutdown | 1 |
| innodb_file_io_threads | 4 |
| innodb_file_per_table | OFF |
| innodb_flush_log_at_trx_commit | 1 |
| innodb_flush_method | |
| innodb_force_recovery | 0 |
| innodb_lock_wait_timeout | 50 |
| innodb_locks_unsafe_for_binlog | OFF |
| innodb_log_arch_dir | |
| innodb_log_archive | OFF |
| innodb_log_buffer_size | 1048576 |
| innodb_log_file_size | 10485760 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | .\ |
| innodb_max_dirty_pages_pct | 90 |
| innodb_max_purge_lag | 0 |
| innodb_mirrored_log_groups | 1 |
| innodb_open_files | 300 |
| innodb_rollback_on_timeout | OFF |
| innodb_support_xa | ON |
| innodb_sync_spin_loops | 20 |
| innodb_table_locks | ON |
| innodb_thread_concurrency | 8 |
| innodb_thread_sleep_delay | 10000 |
+———————————+————————+

更多InnoDB参数,请参考官方文档

 
2009-05-12 10:08

#BEGIN CONFIG INFO
#DESCR: 4GB RAM, 只使用InnoDB, ACID, 少量的连接, 队列负载大
#TYPE: SYSTEM
#END CONFIG INFO

#
# 此mysql配置文件例子针对4G内存
# 主要使用INNODB
#处理复杂队列并且连接数量较少的mysql服务器
#
# 将此文件复制到/etc/my.cnf 作为全局设置,
# mysql-data-dir/my.cnf 作为服务器指定设置
# (@localstatedir@ for this installation) 或者放入
# ~/.my.cnf 作为用户设置.
#
# 在此配置文件中, 你可以使用所有程序支持的长选项.
# 如果想获悉程序支持的所有选项
# 请在程序后加上”–help”参数运行程序.
#
# 关于独立选项更多的细节信息可以在手册内找到
#

#
# 以下选项会被MySQL客户端应用读取.
# 注意只有MySQL附带的客户端应用程序保证可以读取这段内容.
# 如果你想你自己的MySQL应用程序获取这些值
# 需要在MySQL客户端库初始化的时候指定这些选项

#
[client]
#password = [your_password]
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@

# *** 应用定制选项 ***

#
# MySQL 服务端
#
[mysqld]

# 一般配置选项
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@

# back_log 是操作系统在监听队列中所能保持的连接数,
# 队列保存了在MySQL连接管理器线程处理之前的连接.
# 如果你有非常高的连接率并且出现”connection refused” 报错,
# 你就应该增加此处的值.
# 检查你的操作系统文档来获取这个变量的最大值.
# 如果将back_log设定到比你操作系统限制更高的值,将会没有效果
back_log = 50

# 不在TCP/IP端口上进行监听.
# 如果所有的进程都是在同一台服务器连接到本地的mysqld,
# 这样设置将是增强安全的方法
# 所有mysqld的连接都是通过Unix sockets 或者命名管道进行的.
# 注意在windows下如果没有打开命名管道选项而只是用此项
# (通过 “enable-named-pipe” 选项) 将会导致mysql服务没有任何作用!
#skip-networking

# MySQL 服务所允许的同时会话数的上限
# 其中一个连接将被SUPER权限保留作为管理员登录.
# 即便已经达到了连接数的上限.
max_connections = 100

# 每个客户端连接最大的错误允许数量,如果达到了此限制.
# 这个客户端将会被MySQL服务阻止直到执行了”FLUSH HOSTS” 或者服务重启
# 非法的密码以及其他在链接时的错误会增加此值.
# 查看 “Aborted_connects” 状态来获取全局计数器.
max_connect_errors = 10

# 所有线程所打开表的数量.
# 增加此值就增加了mysqld所需要的文件描述符的数量
# 这样你需要确认在[mysqld_safe]中 “open-files-limit” 变量设置打开文件数量允许至少4096
table_cache = 2048

# 允许外部文件级别的锁. 打开文件锁会对性能造成负面影响
# 所以只有在你在同样的文件上运行多个数据库实例时才使用此选项(注意仍会有其他约束!)
# 或者你在文件层面上使用了其他一些软件依赖来锁定MyISAM表
#external-locking

# 服务所能处理的请求包的最大大小以及服务所能处理的最大的请求大小(当与大的BLOB字段一起工作时相当必要)
# 每个连接独立的大小.大小动态增加
max_allowed_packet = 16M

# 在一个事务中binlog为了记录SQL状态所持有的cache大小
# 如果你经常使用大的,多声明的事务,你可以增加此值来获取更大的性能.
# 所有从事务来的状态都将被缓冲在binlog缓冲中然后在提交后一次性写入到binlog中
# 如果事务比此值大, 会使用磁盘上的临时文件来替代.
# 此缓冲在每个连接的事务第一次更新状态时被创建
binlog_cache_size = 1M

# 独立的内存表所允许的最大容量.
# 此选项为了防止意外创建一个超大的内存表导致永尽所有的内存资源.
max_heap_table_size = 64M

# 排序缓冲被用来处理类似ORDER BY以及GROUP BY队列所引起的排序
# 如果排序后的数据无法放入排序缓冲,
# 一个用来替代的基于磁盘的合并分类会被使用
# 查看 “Sort_merge_passes” 状态变量.
# 在排序发生时由每个线程分配
sort_buffer_size = 8M

# 此缓冲被使用来优化全联合(full JOINs 不带索引的联合).
# 类似的联合在极大多数情况下有非常糟糕的性能表现,
# 但是将此值设大能够减轻性能影响.
# 通过 “Select_full_join” 状态变量查看全联合的数量
# 当全联合发生时,在每个线程中分配
join_buffer_size = 8M

# 我们在cache中保留多少线程用于重用
# 当一个客户端断开连接后,如果cache中的线程还少于thread_cache_size,
# 则客户端线程被放入cache中.
# 这可以在你需要大量新连接的时候极大的减少线程创建的开销
# (一般来说如果你有好的线程模型的话,这不会有明显的性能提升.)
thread_cache_size = 8

# 此允许应用程序给予线程系统一个提示在同一时间给予渴望被运行的线程的数量.
# 此值只对于支持 thread_concurrency() 函数的系统有意义( 例如Sun Solaris).
# 你可可以尝试使用 [CPU数量]*(2..4) 来作为thread_concurrency的值
thread_concurrency = 8

# 查询缓冲常被用来缓冲 SELECT 的结果并且在下一次同样查询的时候不再执行直接返回结果.
# 打开查询缓冲可以极大的提高服务器速度, 如果你有大量的相同的查询并且很少修改表.
# 查看 “Qcache_lowmem_prunes” 状态变量来检查是否当前值对于你的负载来说是否足够高.
# 注意: 在你表经常变化的情况下或者如果你的查询原文每次都不同,
# 查询缓冲也许引起性能下降而不是性能提升.
query_cache_size = 64M

# 只有小于此设定值的结果才会被缓冲
# 此设置用来保护查询缓冲,防止一个极大的结果集将其他所有的查询结果都覆盖.
query_cache_limit = 2M

# 被全文检索索引的最小的字长.
# 你也许希望减少它,如果你需要搜索更短字的时候.
# 注意在你修改此值之后,
# 你需要重建你的 FULLTEXT 索引
ft_min_word_len = 4

# 如果你的系统支持 memlock() 函数,你也许希望打开此选项用以让运行中的mysql在在内存高度紧张的时候,数据在内存中保持锁定并且防止可能被swapping out
# 此选项对于性能有益
#memlock

# 当创建新表时作为默认使用的表类型,
# 如果在创建表示没有特别执行表类型,将会使用此值
default_table_type = MYISAM

# 线程使用的堆大小. 此容量的内存在每次连接时被预留.
# MySQL 本身常不会需要超过64K的内存
# 如果你使用你自己的需要大量堆的UDF函数
# 或者你的操作系统对于某些操作需要更多的堆,
# 你也许需要将其设置的更高一点.
thread_stack = 192K

# 设定默认的事务隔离级别.可用的级别如下:
# READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE
transaction_isolation = REPEATABLE-READ

# 内部(内存中)临时表的最大大小
# 如果一个表增长到比此值更大,将会自动转换为基于磁盘的表.
# 此限制是针对单个表的,而不是总和.
tmp_table_size = 64M

# 打开二进制日志功能.
# 在复制(replication)配置中,作为MASTER主服务器必须打开此项
# 如果你需要从你最后的备份中做基于时间点的恢复,你也同样需要二进制日志.
log-bin=mysql-bin

# 如果你在使用链式从服务器结构的复制模式 (A->B->C),
# 你需要在服务器B上打开此项.
# 此选项打开在从线程上重做过的更新的日志,
# 并将其写入从服务器的二进制日志.
#log_slave_updates

# 打开全查询日志. 所有的由服务器接收到的查询 (甚至对于一个错误语法的查询)
# 都会被记录下来. 这对于调试非常有用, 在生产环境中常常关闭此项.
#log

# 将警告打印输出到错误log文件. 如果你对于MySQL有任何问题
# 你应该打开警告log并且仔细审查错误日志,查出可能的原因.
#log_warnings

# 记录慢速查询. 慢速查询是指消耗了比 “long_query_time” 定义的更多时间的查询.
# 如果 log_long_format 被打开,那些没有使用索引的查询也会被记录.
# 如果你经常增加新查询到已有的系统内的话. 一般来说这是一个好主意,
log_slow_queries

# 所有的使用了比这个时间(以秒为单位)更多的查询会被认为是慢速查询.
# 不要在这里使用”1″, 否则会导致所有的查询,甚至非常快的查询页被记录下来(由于MySQL 目前时间的精确度只能达到秒的级别).
long_query_time = 2

# 在慢速日志中记录更多的信息.
# 一般此项最好打开.
# 打开此项会记录使得那些没有使用索引的查询也被作为到慢速查询附加到慢速日志里
log_long_format

# 此目录被MySQL用来保存临时文件.例如,
# 它被用来处理基于磁盘的大型排序,和内部排序一样.
# 以及简单的临时表.
# 如果你不创建非常大的临时文件,将其放置到 swapfs/tmpfs 文件系统上也许比较好
# 另一种选择是你也可以将其放置在独立的磁盘上.
# 你可以使用”;”来放置多个路径
# 他们会按照roud-robin方法被轮询使用.
#tmpdir = /tmp

# *** 复制有关的设置

# 唯一的服务辨识号,数值位于 1 到 2^32-1之间.
# 此值在master和slave上都需要设置.
# 如果 “master-host” 没有被设置,则默认为1, 但是如果忽略此选项,MySQL不会作为master生效.
server-id = 1

# 复制的Slave (去掉master段的注释来使其生效)
#
# 为了配置此主机作为复制的slave服务器,你可以选择两种方法:
#
# 1) 使用 CHANGE MASTER TO 命令 (在我们的手册中有完整描述) -
# 语法如下:
#
# CHANGE MASTER TO MASTER_HOST=, MASTER_PORT= ,
# MASTER_USER=, MASTER_PASSWORD= ;
#
# 你需要替换掉 , , 等被尖括号包围的字段以及使用master的端口号替换 (默认3306).
#
# 例子:
#
# CHANGE MASTER TO MASTER_HOST=’125.564.12.1′, MASTER_PORT=3306,
# MASTER_USER=’joe’, MASTER_PASSWORD=’secret’;
#
# 或者
#
# 2) 设置以下的变量. 不论如何, 在你选择这种方法的情况下, 然后第一次启动复制(甚至不成功的情况下,
# 例如如果你输入错密码在master-password字段并且slave无法连接),
# slave会创建一个 master.info 文件,并且之后任何对于包含在此文件内的参数的变化都会被忽略
# 并且由 master.info 文件内的内容覆盖, 除非你关闭slave服务, 删除 master.info 并且重启slave 服务.
# 由于这个原因,你也许不想碰一下的配置(注释掉的) 并且使用 CHANGE MASTER TO (查看上面) 来代替
#
# 所需要的唯一id号位于 2 和 2^32 - 1之间
# (并且和master不同)
# 如果master-host被设置了.则默认值是2
# 但是如果省略,则不会生效
#server-id = 2
#
# 复制结构中的master - 必须
#master-host =
#
# 当连接到master上时slave所用来认证的用户名 - 必须
#master-user =
#
# 当连接到master上时slave所用来认证的密码 - 必须
#master-password = #
# master监听的端口.
# 可选 - 默认是3306
#master-port =

# 使得slave只读.只有用户拥有SUPER权限和在上面的slave线程能够修改数据.
# 你可以使用此项去保证没有应用程序会意外的修改slave而不是master上的数据
#read_only

#*** MyISAM 相关选项

# 关键词缓冲的大小, 一般用来缓冲MyISAM表的索引块.
# 不要将其设置大于你可用内存的30%,
# 因为一部分内存同样被OS用来缓冲行数据
# 甚至在你并不使用MyISAM 表的情况下, 你也需要仍旧设置起 8-64M 内存由于它同样会被内部临时磁盘表使用.
key_buffer_size = 32M

# 用来做MyISAM表全表扫描的缓冲大小.
# 当全表扫描需要时,在对应线程中分配.
read_buffer_size = 2M

# 当在排序之后,从一个已经排序好的序列中读取行时,行数据将从这个缓冲中读取来防止磁盘寻道.
# 如果你增高此值,可以提高很多ORDER BY的性能.
# 当需要时由每个线程分配
read_rnd_buffer_size = 16M

# MyISAM 使用特殊的类似树的cache来使得突发插入
# (这些插入是,INSERT … SELECT, INSERT … VALUES (…), (…), …, 以及 LOAD DATA
# INFILE) 更快. 此变量限制每个进程中缓冲树的字节数.
# 设置为 0 会关闭此优化.
# 为了最优化不要将此值设置大于 “key_buffer_size”.
# 当突发插入被检测到时此缓冲将被分配.
bulk_insert_buffer_size = 64M

# 此缓冲当MySQL需要在 REPAIR, OPTIMIZE, ALTER 以及 LOAD DATA INFILE 到一个空表中引起重建索引时被分配.
# 这在每个线程中被分配.所以在设置大值时需要小心.
myisam_sort_buffer_size = 128M

# MySQL重建索引时所允许的最大临时文件的大小 (当 REPAIR, ALTER TABLE 或者 LOAD DATA INFILE).
# 如果文件大小比此值更大,索引会通过键值缓冲创建(更慢)
myisam_max_sort_file_size = 10G

# 如果被用来更快的索引创建索引所使用临时文件大于制定的值,那就使用键值缓冲方法.
# 这主要用来强制在大表中长字串键去使用慢速的键值缓冲方法来创建索引.
myisam_max_extra_sort_file_size = 10G

# 如果一个表拥有超过一个索引, MyISAM 可以通过并行排序使用超过一个线程去修复他们.
# 这对于拥有多个CPU以及大量内存情况的用户,是一个很好的选择.
myisam_repair_threads = 1

# 自动检查和修复没有适当关闭的 MyISAM 表.
myisam_recover

# 默认关闭 Federated
skip-federated

# *** BDB 相关选项 ***

# 如果你运行的MySQL服务有BDB支持但是你不准备使用的时候使用此选项. 这会节省内存并且可能加速一些事.
skip-bdb

# *** INNODB 相关选项 ***

# 如果你的MySQL服务包含InnoDB支持但是并不打算使用的话,
# 使用此选项会节省内存以及磁盘空间,并且加速某些部分
#skip-innodb

# 附加的内存池被InnoDB用来保存 metadata 信息
# 如果InnoDB为此目的需要更多的内存,它会开始从OS这里申请内存.
# 由于这个操作在大多数现代操作系统上已经足够快, 你一般不需要修改此值.
# SHOW INNODB STATUS 命令会显示当先使用的数量.
innodb_additional_mem_pool_size = 16M

# InnoDB使用一个缓冲池来保存索引和原始数据, 不像 MyISAM.
# 这里你设置越大,你在存取表里面数据时所需要的磁盘I/O越少.
# 在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的80%
# 不要设置过大,否则,由于物理内存的竞争可能导致操作系统的换页颠簸.
# 注意在32位系统上你每个进程可能被限制在 2-3.5G 用户层面内存限制,
# 所以不要设置的太高.
innodb_buffer_pool_size = 2G

# InnoDB 将数据保存在一个或者多个数据文件中成为表空间.
# 如果你只有单个逻辑驱动保存你的数据,一个单个的自增文件就足够好了.
# 其他情况下.每个设备一个文件一般都是个好的选择.
# 你也可以配置InnoDB来使用裸盘分区 - 请参考手册来获取更多相关内容
innodb_data_file_path = ibdata1:10M:autoextend

# 设置此选项如果你希望InnoDB表空间文件被保存在其他分区.
# 默认保存在MySQL的datadir中.
#innodb_data_home_dir =

# 用来同步IO操作的IO线程的数量. This value is
# 此值在Unix下被硬编码为4,但是在Windows磁盘I/O可能在一个大数值下表现的更好.
innodb_file_io_threads = 4

# 如果你发现InnoDB表空间损坏, 设置此值为一个非零值可能帮助你导出你的表.
# 从1开始并且增加此值知道你能够成功的导出表.
#innodb_force_recovery=1

# 在InnoDb核心内的允许线程数量.
# 最优值依赖于应用程序,硬件以及操作系统的调度方式.
# 过高的值可能导致线程的互斥颠簸.
innodb_thread_concurrency = 16

# 如果设置为1 ,InnoDB会在每次提交后刷新(fsync)事务日志到磁盘上,
# 这提供了完整的ACID行为.
# 如果你愿意对事务安全折衷, 并且你正在运行一个小的食物, 你可以设置此值到0或者2来减少由事务日志引起的磁盘I/O
# 0代表日志只大约每秒写入日志文件并且日志文件刷新到磁盘.
# 2代表日志写入日志文件在每次提交后,但是日志文件只有大约每秒才会刷新到磁盘上.
innodb_flush_log_at_trx_commit = 1

# 加速InnoDB的关闭. 这会阻止InnoDB在关闭时做全清除以及插入缓冲合并.
# 这可能极大增加关机时间, 但是取而代之的是InnoDB可能在下次启动时做这些操作.
#innodb_fast_shutdown

# 用来缓冲日志数据的缓冲区的大小.
# 当此值快满时, InnoDB将必须刷新数据到磁盘上.
# 由于基本上每秒都会刷新一次,所以没有必要将此值设置的太大(甚至对于长事务而言)

innodb_log_buffer_size = 8M

# 在日志组中每个日志文件的大小.
# 你应该设置日志文件总合大小到你缓冲池大小的25%~100%
# 来避免在日志文件覆写上不必要的缓冲池刷新行为.
# 不论如何, 请注意一个大的日志文件大小会增加恢复进程所需要的时间.
innodb_log_file_size = 256M

# 在日志组中的文件总数.
# 通常来说2~3是比较好的.
innodb_log_files_in_group = 3

# InnoDB的日志文件所在位置. 默认是MySQL的datadir.
# 你可以将其指定到一个独立的硬盘上或者一个RAID1卷上来提高其性能
#innodb_log_group_home_dir

# 在InnoDB缓冲池中最大允许的脏页面的比例.
# 如果达到限额, InnoDB会开始刷新他们防止他们妨碍到干净数据页面.
# 这是一个软限制,不被保证绝对执行.
innodb_max_dirty_pages_pct = 90

# InnoDB用来刷新日志的方法.
# 表空间总是使用双重写入刷新方法
# 默认值是 “fdatasync”, 另一个是 “O_DSYNC”.
#innodb_flush_method=O_DSYNC

# 在被回滚前,一个InnoDB的事务应该等待一个锁被批准多久.
# InnoDB在其拥有的锁表中自动检测事务死锁并且回滚事务.
# 如果你使用 LOCK TABLES 指令, 或者在同样事务中使用除了InnoDB以外的其他事务安全的存储引擎
# 那么一个死锁可能发生而InnoDB无法注意到.
# 这种情况下这个timeout值对于解决这种问题就非常有帮助.
innodb_lock_wait_timeout = 120

[mysqldump]
# 不要在将内存中的整个结果写入磁盘之前缓存. 在导出非常巨大的表时需要此项
quick

max_allowed_packet = 16M

[mysql]
no-auto-rehash

# 仅仅允许使用键值的 UPDATEs 和 DELETEs .
#safe-updates

[isamchk]
key_buffer = 512M
sort_buffer_size = 512M
read_buffer = 8M
write_buffer = 8M

[myisamchk]
key_buffer = 512M
sort_buffer_size = 512M
read_buffer = 8M
write_buffer = 8M

[mysqlhotcopy]
interactive-timeout

[mysqld_safe]
# 增加每个进程的可打开文件数量.
# 警告: 确认你已经将全系统限制设定的足够高!
# 打开大量表需要将此值设高
open-files-limit = 8192

 
2009-05-11 1:33

杭州,什么人的天堂?


其实,整个事件已经不是一起车祸那么简单了,如果说争论的焦点是对肇事人的处理上,不如说是整个社会想看看这个国家对待这件事的态度。
先来看看这个事件里的各种利益集团:
谭卓——草根出身,用了一条最普通的方法脱离的贫困:考大学,上大学。知识阶级的代表范例,也可以说是社会精英阶级。
胡斌——富家子弟,说实话,胡斌构不成一个利益集团,只能算是个寄生阶级。
声援谭卓的人——这部分人的组成很复杂:
第一类,谭卓的亲友,感情因素是他们不断声讨的主要动力。
第二类,社会正义力量,他们可能是普通的杭州市民,他们可能是千里之外的普通网友,他们可能很多人在这起车祸以前根本就认识谭卓,只是出于对社会公平,道德良知的考量。
第三类,广大的社会精英阶层,这部分人和谭卓拥有相同的社会出身,他们大多也是出身寒门,通过自身努力跻身知识阶层行列,但暂时还没有到达中产阶级的水平,他们考的是最好的大学,上的是最高精尖的专业,是推动这个社会进步的最重要力量,只是他们目前收入肯定没有他们的老板高。

保护胡斌的人——这部分人的组成就很单纯了:
第一类,胡斌的父母,没有解释,亲情使然。胡斌的父母非常有钱,属于整个社会中,社会财富的享受阶级,他们自身并没有什么文化(通过对子女的教育就可以看出来),但是因为各种各样的原因却享受着现成的财富,属于既得利益者。
第二类,胡斌父母发动的人,这部分人就不明说了,有那三家按着新闻不发的媒体们,有那个说“只有70码”的交警们,还有那些隐藏在事情背后的人,等待着一个合适的“价格”才会出手的人。
双方在5月7号以后就一直在交手,声援谭卓的人一直在用一种最简单,也是最无奈的办法对国家机器施加着压力——无声的抗议,用杭州文二西路的蜡烛 抗议,用天涯上一个个愤怒的字眼在抗议,其实手握正义的人们一直在等待着,看看这个标榜公平,公正的国家机器到底会怎么处理这件事。
保护胡斌的人的动作就远比声援谭卓的人要来的直接和有效率了,他们首先压抑媒体力量,他们深深地懂得舆论的可怕,舆论可以把本来就很愤怒的人群一 下点燃,所以,他们马上利用自己手上的资源封锁了杭州的三家媒体(这种媒体基本上也就失去了社会舆论的功能,一张受控制的嘴),其次,利用人脉,让交警们 做出最有利于胡斌的发言,不要小看这一步,一个看上去很官方的借口也许就能救了一条命。其他的事情我们就看不到了,我们的身份让我们接触不到跟高层的东 西,但我们可以猜的出来那是什么……
读到这里你应该了解到我要写什么了,大家对这起“简单的车祸”的愤怒实际上就是全社会对社会财富享受阶级的愤怒,也就是对“有钱人”的愤怒。
说实话,这不是简单的“仇富心理”,而是对有钱人的不满。
第一、 对他们财富来源的愤怒
我不知道胡斌父母的财富是怎么获得,此处我不做评价,但你能说山西小煤窑的矿主的财富来的光彩;但你能说温州炒房团投机倒把来的财富光彩;但你能说三鹿奶粉用三聚氰胺勾兑来的财富光彩,但你能说上市公司用虚假报表套来的财富来的光彩……
他们是“有钱人”,但是,他们是侵占了我们的东西,甚至靠伤害了我们才获得了财富,这样的一群人,反而在我们面前耀武扬威,反而在我们家门口的文二路上飙 车时,我们愤怒了。文西二路是我们上班下班走的路,是我们的孩子上课放学走的路。“有钱人”,为什么连我们路也要占。
第二、 对他们的行为愤怒
从来都是“有钱人”欺负“穷人”,没有“穷人”欺负“有钱人”的,5000年了,中国人的“有钱人”欺负“穷人”欺负惯了,你要是被欺负了5000年,能不恨吗?
第三、 社会精英阶层开始对“有钱人”愤怒
这个事情现在并不是一个简单的社会公平问题了,草根出身的谭卓用了最直接办法脱离了贫穷,渐渐往社会精英阶层走的过程中,死了,被“有钱人”撞死了,且还 有“白死”的危险,这样无情的事实让其他还处在贫穷中,为了进入社会精英阶层而考大学的人们怎么面对?这些人寒了心,这个国家还有希望吗?
这让那些已经进入社会精英阶层的人怎么看?他们受过高等教育,有着稳定的收入,并且是社会的中坚力量(有钱的人,并不是最推动社会发展的人,也并 不是社会里最必不可少的人),最重要的是,随着时代的进步,这些人对民主与公平的渴望会愈发的强烈,他们对社会的既得利益者也会越来越不满。很简单,我为 这个社会做出了最重要的贡献,而我却得不到最丰厚的回报,甚至连“死亡”都得不到尊重。这怎么能接受?
真正是哪些人推动这个国家进步?是谭卓还是胡斌的有钱父母?
请国家机器一定要秉公处理胡斌撞人事件,不能让社会精英阶层寒了心,这些人一旦寒心就会离开这个国家,一旦他们对这个国家产生压抑感,他们就会出国,一旦他们出国,这个国家就没有了进步的可能,这才是最危险的。
一个谭卓走了,不能让其他的谭卓们的心寒了!
北大和清华的留学回国率一直不高,仅仅就是外国的物质条件好吗?
本身就留不住最好的人才,何必再往外推呢?
 
   
 
 
文章分类
 
   
 
文章存档
 
     
 
最新文章评论
  

晚上打车回来,听到说在日本,几乎没有在网络上搜不到盗版,更极少有免费的mp3下载,
 

好文
 

顶凯哥
 

这12条里面哪一个的反馈周期是最短的? 好像第三条的时间最长。
 

回复苗苗_2009: 星星之火,即使不去燎原,也可以在某一角落各分秋色。
   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu