2009年6月30日星期二

张可兴:股票投资的难与易

通过股票投资赚钱到底是容易还是困难?看似一个简单的问题,但实际却比较复杂。
一方面,上证指数从1990年100点起步到现在的2800多点,深证从1991年988点起步并在当年创下397点的历史最低后到现在的11000多点,似乎每个参与股市的投资者长期下来,都是应该赚钱的。特别是从个股看,上市三五年以上的股票,除极少数退市的企业,绝大多数股票如今的复权价都高于当初的上市价,有很多股票的涨幅都在10倍以上。而另一方面的现实却是大多数股民总是亏损的,市场不断重复8亏1平1赚的股市28原则。在绝大多数股票都在上涨的现实下,大多数股民反而是亏钱的,这就值得每位投资者深思了。
从价值投资的角度
上讲,股票投资赚钱的道理非常简单,概括起来就四个字"低估"、"成长",也就是说股票估值低了,企业成长了都会造成股价未来的上涨。中国股市的每一次的
牛熊交替就是不断的重复股价从低估到高估的过程,而经过多次股市低估、高估轮回,股市长期依然不断上涨,又正是在中国经济高速发展的过程中,大多数上市公
司不断成长带动的。只要你具备一定长远的眼光,去把握股市低估到高估的过程,去把握企业成长的过程,赚钱并不难。
判断股市估值的高低,其实也并不困难,有很多方法和标准,比如根据股市整体平均PE和PB,在中国19年的证券史上,市场平均PE在20倍以下、PB在2倍以下,市场就处于低估区域,PE在50倍以上、PB在5倍
以上时,市场就处于严重高估区域。另外,还有一些更简单的常识可以辅助判断估值的高低,一般熊市的后期估值是比较低的,而牛市的后期估值是比较高的,而判
断牛熊市有很多常识性的现象,比如券商营业部交易大厅的冷清与火爆,你身边的大多数股民是亏损累累,谈股变色,还是人人都大赚特赚,连邻居的老大妈都成了
股神,向你推荐股票等。我们在别人贪婪的时候恐惧,在别人恐惧的时候贪婪,从本质上就是在讲在股市低估的时候买进,在高估的时候卖出,因为当大多数人恐惧
的时候,往往是熊市的后期股市处于低估阶段,而大多数人贪婪的时候也往往是牛市的后期股市处于高估阶段。李嘉诚曾经告诫很多企业家的成功心得,"当大街上
遍地都是鲜血的时候,就是你最好的投资时机。"

判断企业的成长,并不是普通股民能够轻易做到的,这里面需要对商业、企业及企业所在行业发展趋势、竞争态势等的深刻理解。这既与整个国家乃至全球的经济环
境、企业及行业发展的客观规律有关,也受投资者本人的知识水平、经验阅历所限制。但这里面有些普遍的规律和常识,又是投资者能够把握的,比如,在一个国家
经济腾飞,人民生活不断富裕的过程中,金融、地产等支柱产业,消费品,服务业等与百姓生活息息相关的行业,都会得到长足的发展,而其中具备竞争优势的优秀
企业成长是确定性很高的事件。另外,虽然每个人的能力圈不同,但总有一些日常的生活常识能辅助你选择企业,比如茅台的不断提价和供不应求,小肥羊的新店扩
张,腾讯QQ的付费用户和盈利点越来越多,哪家银行、地产公司服务更好或更具竞争力等等,都会为你选择企业提供帮助。总之,你对企业的未来把握的越清楚越准确,你投资赚钱会越容易。

阅中国股市的历史,其实股民要想长期赚钱,永不亏损,比起国际成熟市场还要容易的多,甚至只要把握好牛熊规律就够了,因为中国股票的稀缺性特点和市场参与
者的不成熟,一个从熊市到牛市的过程中,几乎什么股票都会上涨,你只要在一个熊市的后期买入几只股票,持有的牛市的后期卖出股票,即使你的选股能力差些,
几乎也是保赚不赔的。你也许赚不到上一轮牛市中苏宁、万科等成长企业的几十倍收益,但只要你在08年底前后买入了股票,在将来合适时候卖出了股票,赚上几倍并不难。

么,为什么大多数股民最终依然亏损累累呢?这是因为股票投资中也有困难的地方。一是,想买在底部,卖在顶部是困难的;二是判断一只股票短期内涨跌是困难
的;三是做到在股票已经低估,但市场继续低估,承受账面亏损,巍然不动甚至继续加仓是困难的;第四,在股票已经严重高估卖出后,看着股票继续上涨,持有现
金,等在下一次低估的到来过程是困难的。
市场中多数人在股市不断上涨的大趋势下,不断亏钱,正是因为舍易求难,不断的想买了就涨;不断的试图去抓每月、甚至每周的10%;
不断的在看到大家都赚了钱的高估区间开始买股票,在严重亏损的低估区间卖出;不去买自己能够研究明白的优秀企业,而去追寻自己根本不了解的所谓黑马;不断
的频繁交易,试图每一天都战胜市场,结果把自己的大部分资产都为国家贡献了税收、为券商贡献了利润。反而对低估区间买入成长企业,这种每个牛熊周期都能创
造数倍收益,几乎无任何风险的简单投资方法熟视无睹。
最后,建议投资者与其把精力花在复杂繁琐的技术分析和盯盘上,不如花在同样困难些的企业价值研究分析和正确的投资理念及理性的操作纪律培养上。一样是付出辛勤的劳动,但二者的收获最终会是天壤之别的,走错了方向,只能南辕北辙。走对了,即使走得慢些,也会离目标越来越近。

2009年6月29日星期一

我心中的两位股市大师

价值投资,不是"傻根投资"。理想的结果与实现的过程是两码事。"价值投资"根本不是一种投资理念,而是一种投资能力。
  进入2007年,中国股市进入相对"高位",几乎每天都有大量的投资者进入市场。相对于年末沪市收盘的2675点,指数近期涨幅并不大。但据业内统计,现在盘中已经有数百只股票见到历史新高,其中最为活跃的120只股票今年以来的绝对涨幅超过100%;此外,沪深两市目前已经没有了"资产净值"以下的股票。
  与此同时,股票型基金的业绩,却在高位徘徊,几乎完全复制指数的涨幅,看来,如果今年全年市场最终只是箱体震荡,那么选择"长线持股"的投资策略就有可能跟着股指上上下下地"坐电梯",至少收益率不会很高。
  比较一下两位华尔街的名人,他们代表短线与长线的不同的投资理念。这就是巴菲特与彼得・林奇,这两人都是市场大师,都是我们的偶像。但是在一个多元化的市场,经常比较一下他们的差异,还是很有必要的。
  首先,是关于资产规模的比较。从1956年做到1965年,巴菲特的投资基金年均增长率达30%,规模做到2600万美元;而彼得・林奇的投资基金,从1976年到1989年的13年间,年均增长率29%,虽然与巴菲特管理的投资合伙公司水平相当,但资产规模的扩张要快得多,13年的时间即由2000万美元增长到130亿美元。
  其次,是关于投资难易风格的比较。彼得・林奇最为擅长的是"短线",以便能够追随市场的波动。他相信,只要资金的规模足够大,你买到哪只股票,哪只股票必涨无疑。但是如此操作也具有相当的难度。彼得・林奇是在46岁的时候就宣布退休,因为压力太大,身体受损,这就是炒短线最大的坏处。但"从来不看电脑股票行情"的巴菲特的行业寿命,却一直持续到了今天。
  不过要讲投资,集中投资与分散投资,并不意味着前者一定强于后者。彼得・林奇在其职业生涯之中,轮番持有过1400多只股票,远远超过同一时期的巴菲特。
  其三,是关于投资成本的比较。让巴菲特做短线,行还是不行?可以说"肯定不行",这是因为巴菲特所控股的核心企业就是"美国地方政府"的保险公司,该公司可以为巴菲特提供大量的低成本现金,但不允许他进行短线套利交易。正因如此,所以巴菲特被迫当了几十年的"股市傻根",事实的真相是,"傻根"没赢,他只是把所有的风险都转嫁给了"华仔",包括"奶茶"。
  其四,关于机会成本,尽管巴菲特的"机会成本"为零,但在他的投资生涯之中,同样难免失手,这就是所谓投资无必胜。譬如巴菲特曾经投资于美国航空,彼得・林奇也曾经重仓美国航空这只股票,但后者是获利出局,而巴老先生却没有他那么幸运。1989年7月,巴菲特投资3.58亿美元购入美国航空的股票,当时美国航空普通股每股股价是50美元,此前的1981年至1988年,美国航空一直是令投资者印象深刻的蓝筹股,它的股东权益报酬率平均达14%,税前纯收益率在8%―12%。这样的股票,完全符合巴菲特的选股条件。而且航空业进入门槛高,属于寡头垄断,巴菲特坚信美国航空的普通股应该会有不错的表现。然而结果却事与愿违。航空公司经营的恶化,始于廉价航空公司和破产航空公司纷纷采取自杀性的低价战略,以及相对强势的航空工人工会具备极强的议价能力,致使工资成本高居不下。美国航空居然发生巨额亏损,股价从此一年不如一年。
  该次投资应是巴菲特为数不多的失败案例之一,以此看来,"天下无贼"毕竟只是传说,关键中的关键在于,这回巴菲特当的是"华仔",而不是运气好得要命的"傻根"。
  巴菲特喜欢低市盈率,但低市盈率并不总是好事,低市盈率有时仅仅表明这只股票(或这个市场)的买家极其稀少,股价极不活跃,或者就存在着你所不知道的"系统风险"。
  其五,关于可复制的难易程度的比较。这个已经不用我说,在当今世界,每10个股民中就有9个自认为可以效法巴菲特,以为巴菲特他老人家只是攥着几只好股票,然后"熬年头",一直熬成股神的。但事实上,巴菲特并非一般人可以复制的,想复制他的成功,比复制彼得・林奇更难,因为他对于看中的股票采用绝对控股的办法,他买下的是公司,而非公司的股票。在今天的美国,至少有30万人可以这样说,"我在巴菲特先生的公司里工作"。以此观之,彼得・林奇缝的是"被窝儿",但巴菲特把自己也"缝"进去了,你根本分不出哪一块是"被窝儿",哪一块是巴菲特他自己。
  对此,我们完全可以得出一个结论:价值投资,绝不是"傻根投资",理想的结果与实现的过程是两码事,恐怕不能相提并论。很多今年新入市的投资者并不晓得,一般而言,"价值投资"根本不是一种投资理念,而是一种投资能力。
1老巴不喜欢快速的成长。认为过快的成长会伤害公司股东利益。而林奇喜欢快速的成长,因为这里10倍股较多。
2老巴不喜欢零售业,因为零售业竞争太激烈,这个行业太危险,林奇喜欢,因为他喜欢零售连锁企业的高速扩张。
3老巴不喜欢转困型的股票,因为坏学生永远会是坏学生。林奇喜欢,因为他认为,好学生遭遇临时困难,度过危机后,还是好学生,
4老巴不喜欢价值被低估的股票,虽然他年轻的时候很喜欢,后来他把这种股票投资叫吸烟屁股,只能抽一口没什么意思。有经验后改成低估85%+成长15%,必须前提是持续成长,然后低价买入,二者缺一不可。而林奇喜欢,低价买入,等股价回升到其价值的三分之一时就抛掉。
5:老巴喜欢稳定移动的大象,林奇不喜欢,主要原因两个人管理的钱不一样。投资风格不一样。
6:老巴喜欢集中投资。长期持有,林奇喜欢分散投资,短期持有。
7:老巴不喜欢周期繁荣的股票,所以一生都是追求确定性高的垄断消费品行业,而林奇喜欢周期股,喜欢那种爆涨爆跌的预期游戏。
相同点:
1:老巴和林奇都以价值投资为基础,分析企业和行业能力超一流
2:老巴和林奇都不喜欢高科技股,因为看不利润,也看不到稳定性
3:都相信,从长期来看股价和企业业绩100%相关。
4:都相信,市场的愚蠢可以让我们挣大钱
5:都相信,长线是金
最后老巴被人叫成股神,林奇被叫做股圣

上证综指和我的“进化”

1992年涉足证券投资时,上证综指刚发布不久。股票的魔力激发了我无尽的求知欲。各种投资流派都加以学习、尝试,来者不拒。
经过一段时间的学习和实践,我归纳了证券投资的致胜金字塔、四项原则和八大课题。看似系统全面,本质上就是目前颇为流行的基本面选股、技术面选时,投资和投机相结合的方法。
这一阶段,上证综指在我的投资决策中起到重要的"风向标"作用。原因有二:一是我当时的投资系统中,在基本面选股的基础上,注重把握涨跌趋势,以技术指标的低、高档作为买卖股票的主要依据。二是当时绝大多数股票出现齐涨齐跌的局面,一切行动都听上证综指的"指挥"。
正当我自以为已经找到投资秘籍、准备大干一场的时候,"十月革命一声炮响送来了社会主义"。1995年底,我在在上海证券报《财经闲话》专栏阅读了孙涤教授介绍格雷厄姆、巴菲特思想的系列文章,"安全边际"、"买卖股票如同经营企业"的核心思想如露入心、醍醐灌顶,使我投资方式和人生轨迹都发生了重大转折。上证综指在我投资系统的作用也相应地发生了变化。
接受巴菲特思想后,我投资系统的进化过程,实际上就是不断的"去投机化"的过程,从脚踏投资、投机两条船,逐步过渡到两只脚都踏进价值投资一条船上。因为我认识到,以市场价格波动趋势为主要操作依据的买卖行为,应归类为"投机"。投机者A,长期试图判断 B、C、D,而B、C、D反过来也做着同样判断,这种博弈行为必然导致"囚徒困境",在不自觉中形成难以摆脱的"投机陷阱"。而且就投机者的整体而言,因为交易磨损成本的存在,其失败是先天的、必然的。
格雷厄姆、巴菲特的投资方法有两大基础优势:一是安全边际使投资者有犯错的空间,避免损失;二是这种方法深深地植根于对心理学的了解,具有巨大的心理优势,不会因为情绪波动而导致决策失误。相反,技术分析等投机的模式只看重价格趋势,忽视公司质地、价值评估,经常如"高空走钢丝"或一直在悬崖边上行走,缺乏安全边际的保护,唯一的救命方式是停损,但碰到"黑天鹅"等突发事件,停损根本无法执行,存在 "一失足成千古恨"而前功尽弃的致命风险。而且技术分析等投机方法,缺乏心理学的支持,心理因素对投机者的成功构成强烈的威胁。如果把技术分析等投机方法引进价值投资,将使价值投资的心理优势荡然无存,这无疑是一种引狼入室的行为。
我进化的过程并非一帆风顺,中间伴随着困惑、摇摆和试错。经过对巴菲特思想的长期学习、思考和实践,直到2002年,我的投资系统才基本定型,变得纯粹、专注起来。
在这个进化过程中,我对宏观经济和股市趋势的分析不断淡化,逐步专注于公司长期竞争优势的分析。因为我认识到,宏观经济和股票市场是庞大的复杂适应性系统,没有任何模型能准确预测。格雷厄姆在《证券分析》中指出:"人们不可能对处在人类自身控制之下的经济事件作出科学预测。这种预测的"可靠性"将使人们采取相应的行动,而这种行动反过来推翻当初的预测"
所以,上证综指的短期趋势是不可知的,也不重要。对上证综指趋势的正确态度是判断、调整、适应,重在应对而不是预测。只有在少数极端的情形下,分析家才能对上证综指的中长期走向发出权威的声音,其他大部分时间的预言都是苍白无力的。
而且股票市场和宏观经济之间的关系也相当复杂,并非像教科书上所说的"股市是宏观经济的晴雨表"那么简单。
2001年11月10日,美国《财富》杂志发表了《巴菲特谈股市》一文。文中巴菲特重申了股市整体表现长期来说与美国经济整体增长性相关。过度高估或过度低估的股价长期而言肯定会回归其内在价值。但是,巴菲特还以翔实的历史数据说明了1899年―1998年的100年间,美国股市整体走势与GNP走势相背离的现象。指出影响股市走向有三个关键因素:利率、人们对未来投资报酬率的预期和心理因素。
有"德国巴菲特"之称的安德烈・科斯托兰尼曾讲述了一个"男人和狗"的寓言:有一个男人带着狗在街上散步,像所有的狗一样,这狗先跑到前面,再回到主人身边。接着,又跑到前面,看到自己跑得太远,又再折回来。整个过程里,狗就这样反反复复。最后,他俩同时抵达终点,男子悠闲地走了1公里,而狗跑来跑去,走了4公里――在这个寓言里,男子就是经济,狗则是股市。"长远看来,经济和证券市场的发展方向相同,但在过程中,却有可能选择完全相反的方向。"
居于以上认识,上证综指在我投资决策中的作用也相应从"风向标"逐步演变成了"温度计",从"老师"变成了"朋友"。通过评估上证综指所处区域的估值水平,判断市场是否处于过热或过冷阶段,有助于对股市的长期趋势作出判断,对投资决策和资产配置会起到一定的参考作用。此外,我还把上证综指作为长期投资业绩的评价标准,每五年拿自己投资业绩和上证综指相比较,检讨得与失。
本杰明・富兰克林说过:"回忆生命并把它记录下来,无异于重获新生。这样,它就能够长时间流传下来,历久弥新。"回顾我近18年的投资生涯,上证综指先是我的"严师",后是我的"益友",一直伴随着我的成长。

新人入行指导

每个项目都有遇到新人进入团队后的指导工作,公司只是在大的层面上指导,更多的还是靠新人自己去摸索。这里转贴,有很好的参考价值,希望对大家有用。
从2003年加入现在的公司,已经有了快6个年头,自己也从一个计算机软件开发方面的新兵变成了老人。在公司里也做过几个不同的项目,有一些新的同事加
入项目组,会有这样那样的疑惑和问题。在这里想简单说说,一个新人如何能快速的融入一个新的开发组,让其他同事能够接受自己。
首先是读文档。计算机方面有个著名的黑话叫做RTFM,什么意思呢?按字面翻译就去"去读他妈的文档",这是在新闻组或者论坛里可能常见的回复,一些人
娇滴滴的说"我是妹妹,能指导一下这个问题么"或者贱兮兮的"跪求某某问题答案"。当然,同事之间不可能搞这些,不过也经常碰到有人问一些感觉非常简单
问题,这些问题实际上都在项目文档或者软件规范里就明白写着。
一个新人加入某个项目,或者转换到一个新项目,都会感觉到手足无措,就像老虎吃刺猬不知如何下嘴。领导不会让这样的新人去完成一些复杂模块的开发或者修改一些相对困难的bug,基本上都是先分一些界面上的小改动,或者是让他开发耦合程度低一些、相对独立一些的功能作为练手,这个时候作为一个新人就要尽快的掌握整个项目的大概,然后泛读一下项目的重要文档。如果要开发某个业内标准的实现软件,那这个标准的相关文档至少要通读一遍,不需要投入很长时间,可以快速掌握一下大概,做做简单的笔记,不懂的地方先记下来以后有空再说。读文档不要作为一个整体任务完成,可以用一些零碎时间来读,以免很长时间没有
什么进展,领导看了还以为在磨洋工呢。
**注意事项一,尽管有这样那样的软件支持,一支笔一个本子仍然是最方便最快速最实用的学习工具,我几乎每年都要写掉八九个大笔记本,里面写着项目开发
的心得、文档书籍的感受、领导指示的一些开发问题等等,不需要有什么文章格式,先写下来就可以了。
如果是第一次进入公司,项目组长会分一个任务作为对新人水平的考察,就好比网游中的新手任务。我们公司大多数的新手任务都是半个月一个月左右的时间,注意要尽量赶在期限结束前完成所有的编码和单元测试,而且最好完成代码清理和代码注释工作,注意命名规则,这样看起来比较专业一些。
**注意事项二,接到一个项目第一个要问的就是这个项目结束期限(dead
line)是什么,这样心里比较容易对进度有个估计,免得最后无法完成任务。领导可能会反过来咨询老程序员对分到的项目难度估计。一般来说,估计一个大概的编码时间,然后把估计时间乘二,留出一定余量比较好。
读文档不要作为一个整体任务完成,可以用一些零碎时间来读。实际上接手一个新任务,必须要做的就是理解需求。一个开发人员如何不理解他想做什么,基本上这个任务一定会失败。我们高考时候都会写一篇大作文,对题目的理解非常重要,偏题跑题就没法拿到高分,开发也是如此。对需求的理解需要反复的进行,定期和项目组领导或者客户进行沟通,以免自己做了无用功。但是沟通之前一定要注意,自己先掌握一定的背景知识,比如前面提到的规范文档,或者是读一读已经有的代码,跑一跑成型的产品,免得问的都是不必要的问题。
搜索一下可以找到一篇题为"提问的智慧"的文章,里面介绍如何在网上问问题。其实项目组内沟通也是如此,要注意问有意义的问题。打个比方说,有时候自己会有一种感觉,跑到别人面前,把问题说了一遍,还没等人回答,突然拍着脑袋说"啊我明白了",也许是反应挺快,可是还是耽误了别人的功夫,像这样的问题,自己组织组织语言或者写出来,答案就很容易发现。另外也有的人,总是这是怎么回事那是怎么回事,其实到搜索引擎一搜或者是把动手做做就知道结果,但是非要张嘴问,这样的人说得难听点就是问题不经过大脑,其实一思考就能得到答案了。问问题之前也可以试着理清一下思路,看看前因后果,简化一下问题模型,也许经过这些方式,自己就能找到答案。有同组的同事问问题,很多时间我反问几句,把思路理清,他自己就知道答案是什么了。忘记在哪有看到一个轶事,在某个著名软件公司里,开发组的桌上会放着一只小熊,大家互相问问题之前,先对着小熊把问题说一遍,看能不能把问题描述的清晰,基本上说的比较有条理以后,答案也就随之而来了,大家可以试试这个办法。
**注意事项三,提问之前,自己先试图看看能不能找到答案,我建议的寻找顺序是文档、google,最后才是张嘴问,问之前最好已经积累了一些材料,比如关于这个问题自己做了什么研究,搜索了什么关键字等等,这样问的有诚意,回答才能有诚意。
另外,对于一个新人,需要多跟老同事沟通,了解项目的关键点是什么,比如开发一个通讯程序,用了什么协议,哪个网站比较有用,哪个文档需要精读,都是非常有意义的问题,这些问题可以少走一些弯路。早上到了公司,第一件事是接收业务邮件,然后记下一些需要回复或者要做的工作。邮件阅读以后,可以跟项目组长做个简单的沟通,了解一下哪个任务或者功能需要快一点完成,交流一下自己的想法,时间花费不多但是可以把一天的任务明确下来。
如果比较努力而且有一定的开发能力,两三个月以后应该开始接触到项目比较核心的东西了,这个时候需要做的工作就是读代码。一个项目最重要的东西就是代
码,至于文档、注释、测试,其实都是保证代码质量以及代码可维护型的一种辅助手段,作为一个开发人员,不熟悉代码就是致命的错误。
读代码我这里有一些简单的体会。
读代码要注意的第一条是从界面开始,深入到功能。打个比方说,一个桌面软件,其中有个格式转换功能,可以从菜单选择"格式转换"进行操作(注意,所谓格式转换就是一个例子,没有实际意义),那么就可以搜索菜单里的"格式转换",找到相对应的界面函数,这就是一个相对独立的功能入口点了。然后从这个入口点顺藤摸瓜,就可以搞清楚格式转换这个功能需要的一系列界面函数以及逻辑实现函数。
读代码的时候注意要随时做笔记,可以用word或者是powerpoint这样的软件做记录,搭配一个抓屏软件抓取界面变化、程序运行栈或者是一些关键
数据就更好了。
一个相对独立的功能基本上是由几个数据类或者数据结构,加上几个比较重要的逻辑函数实现的,抓住了这些关键就抓住了这个功能的核心。比如说一个通讯软
件,重要的就是通讯数据格式和通讯协议实现。经过我的体验,这个小窍门还是很有用的。一般经常出现问题的也就是这些相对来说复杂一些的函数。
阅读代码的同时还要经常问自己一些问题,比如这个地方为何这样实现,有没有其他的方案,哪个方案更好一些等等。这些问题可以让自己更好的理解当时开发人员的一些想法思路,另外也是将来代码进行重构的一个铺垫。
**注意事项四,作为一个开发人员,多思考是非常必要的一个特质。
一个新人,经过这些阶段,基本上可以成为项目组的中坚力量了,希望每个入行的新人都能成功晋级成为老手。

使用TCP协议的NAT穿透技术-原理及实现

本文来自:http://blog.csdn.net/ssihc0/archive/2008/10/10/3053395.aspx
其实很早我就已经实现了使用TCP协议穿透NAT了,但是苦于一直没有时间,所以没有写出来,现在终于放假有一点空闲,于是写出来共享之。
一直以来,说起NAT穿透,很多人都会被告知使用UDP打孔这个技术,基本上没有人会告诉你如何使用TCP协议去穿透(甚至有的人会直接告诉你TCP协议
是无法实现穿透的)。但是,众所周知的是,UDP是一个无连接的数据报协议,使用它就必须自己维护收发数据包的完整性,这常常会大大增加程序的复杂度,而
且一些程序由于某些原因,必须使用TCP协议,这样就常常令一些开发TCP网络程序的人员"谈穿透色变"。那么,使用TCP协议是不是就不能实现穿透呢?
答案当然是否定的:TCP协议不仅能实现NAT穿透,而且实现起来比UDP穿透甚至还简单一些。
要了解如何使用TCP穿透NAT,就要首先看看如何使用UDP穿透NAT。
我们假设在两个不同的局域网后面分别有2台客户机A和
B,AB所在的局域网都分别通过一个路由器接入互联网。互联网上有一台服务器S。
现在AB是无法直接和对方发送信息的,AB都不知道对方在互联网上真正的IP和端口,
AB所在的局域网的路由器只允许内部向外主动发送的信息通过。对于B直接发送给A的路由器的消息,路由会认为其"不被信任"而直接丢弃。
要实现
AB直接的通讯,就必须进行以下3步:A首先连接互联网上的服务器S并发送一条消息(对于UDP这种无连接的协议其实直接初始会话发送消息即可),这样S
就获取了A在互联网上的实际终端(发送消息的IP和端口号)。接着
B也进行同样的步骤,S就知道了AB在互联网上的终端(这就是"打洞")。接着S分别告诉A和B对方客户端在互联网上的实际终端,也即S告诉A客户B的会
话终端,S告诉B客户A的会话终端。这样,在AB都知道了对方的实际终端之后,就可以直接通过实际终端发送消息了(因为先前双方都向外发送过消息,路由上
已经有允许数据进出的消息通道)。
用UDP来实现以上3步不存在什么理论上的问题,因为UDP是无连接的协议,它允许socket进行"多对一"的通讯(即几个具有不同IP和端口号的
socket向一个接收socket发送消息)。但是使用TCP就出现了问题:在一般情况下,TCP
socket不允许在已经建立连接的端口上再进行监听和使用该本地端口。换句话说,当AB连接上服务器S后,S将AB的实际终端告诉对方,下一步本该是
AB利用对方的实际终端进行直连,但这时你会发现对方的实际终端已经被占用了(就是各自连接到服务器S的会话占用了终端),无法同时listen和
connect。于是很多人得出结论:TCP无法实现NAT穿透。
于是问题的关键变成了如何复用一个TCP连接的本地终端,这其实不是协议的问题,而是一个API的问题。幸运的是,所有主流操作系统都支持一个特定的
TCP套接字选项——SO_REUSEADDR。这个选项允许将多个socket绑定到同一个本地终端。我们建立socket的时候只要加上这么一行:
setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &flag, len) ; //C++就这么做
_Client.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, True) '这是vb.net 更加简单
知道上面的知识就很好办了,下面我来说说TCP协议的穿透流程:
机器布局还是和上面使用UDP的一样。现在假设客户A想和客户B建立TCP连接。
首 先还是
AB分别和服务器S分别建立连接,S记录AB的互联网实际终端。然后S分别向AB发送对方的实际终端。接着,从A和B向S连接时使用的端口,AB都异步调
用connect函数连接对方的实际终端(就是S告诉的终端),同时,AB双方都在同一个本地端口监听到来的连接(也可以先监听,再connect更
好)。由于双方都向对方发送了connect请求(假设各自的SYN封包已经穿过了自己的NAT),因此在对方connect请求到达本地的监听端口时,
路由器会认为这个请求是刚刚那个connect会话的一部分,是已经被许可的,本地监听端口就会用SYN-ACK响应,同意连接。这样,TCP穿透NAT
的点对点连接就成功了。
下面是示例代码下载,VB.NET代码,演示如何用TCP协议穿透NAT实现文件传送,请用vs2005打开解决方案
http://dl2.csdn.net/down4/20070724/24133943521.rar
代码中有一个我自己封装的模仿vb6
winsock的控件ZXMSocket,这个socket可以让你设置是否使用SO_REUSEADDR参数,socket是事件驱动的。
如果你要测试代码,需要使用一个bat来启动发送和接收程序(文件格式请参照bin/Debug文件夹
下的run.bat文件),这个bat的功能是以命令行的方式告诉程序登录服务器缩使用的用户名,对于服务器来说,这个用户名必须是唯一的,当然,这可能
有点不科学,但是这毕竟只是一个demo。

P2P之UDP穿透NAT的原理与实现

本文来自:http://hi.baidu.com/wangzhe1945/blog/item/3e72fffe47fc2f365d60080c.html
源码下载: http://www.ppcn.net/upload/2005_08/05080112299104.rar
参考: http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt
文章说明:
关于UDP穿透NAT的中文资料在网络上是很少的,仅有<<P2P之UDP穿透NAT的原理与实现(shootingstars)>>这篇文章有实际的参考价值。本人近两年来也一直从事P2P方面的开发工作,比较有代表性的是个人开发的BitTorrent下载软件
- FlashBT(变态快车).
对P2P下载或者P2P的开发感兴趣的朋友可以访问软件的官方主页:
http://www.hwysoft.com/chs/
下载看看,说不定有收获。写这篇文章的主要目的是懒的再每次单独回答一些网友的提问,
一次性写下来,
即节省了自己的时间,也方便了对于P2P的UDP穿透感兴趣的网友阅读和理解。对此有兴趣和经验的朋友可以给我发邮件或者访问我的个人Blog留言:
http://hwycheng.blogchina.com. 您可以自由转载此篇文章,但是请保留此说明。
再次感谢shootingstars网友的早期贡献. 表示谢意。
NAT(The IP Network Address Translator) 的概念和意义是什么?
NAT, 中文翻译为网络地址转换。具体的详细信息可以访问RFC 1631 -
http://www.faqs.org/rfcs/rfc1631.html,
这是对于NAT的定义和解释的最权威的描述。网络术语都是很抽象和艰涩的,除非是专业人士,否则很难从字面中来准确理解NAT的含义。
要想完全明白NAT
的作用,我们必须理解IP地址的两大分类,一类是私有IP地址,在这里我们称作内网IP地址。一类是非私有的IP地址,在这里我们称作公网IP地址。关于IP地址的概念和作用的介绍参见我的另一篇文章:
http://hwycheng.blogchina.com/2402121.html
内网IP地址: 是指使用A/B/C类中的私有地址,
分配的IP地址在全球不惧有唯一性,也因此无法被其它外网主机直接访问。公网IP地址:
是指具有全球唯一的IP地址,能够直接被其它主机访问的。
NAT
最初的目的是为使用内网IP地址的计算机提供通过少数几台具有公网的IP地址的计算机访问外部网络的功能。NAT
负责将某些内网IP地址的计算机向外部网络发出的IP数据包的源IP地址转换为NAT自己的公网的IP地址,目的IP地址不变,
并将IP数据包转发给路由器,最终到达外部的计算机。同时负责将外部的计算机返回的IP数据包的目的IP地址转换为内网的IP地址,源IP地址不变,并最终送达到内网中的计算机。
图一: NAT 实现了私有IP的计算机分享几个公网IP地址访问Internet的功能。
随着网络的普及,IPv4的局限性暴露出来。公网IP地址成为一种稀缺的资源,此时NAT
的功能局限也暴露出来,同一个公网的IP地址,某个时间只能由一台私有IP地址的计算机使用。于是NAPT(The
IP Network Address/Port
Translator)应运而生,NAPT实现了多台私有IP地址的计算机可以同时通过一个公网IP地址来访问Internet的功能。这在很大程度上暂时缓解了IPv4地址资源的紧张。
NAPT
负责将某些内网IP地址的计算机向外部网络发出的TCP/UDP数据包的源IP地址转换为NAPT自己的公网的IP地址,源端口转为NAPT自己的一个端口。目的IP地址和端口不变,
并将IP数据包发给路由器,最终到达外部的计算机。同时负责将外部的计算机返回的IP数据包的目的IP地址转换内网的IP地址,目的端口转为内网计算机的端口,源IP地址和源端口不变,并最终送达到内网中的计算机。
图二: NAPT 实现了私有IP的计算机分享一个公网IP地址访问Internet的功能。
在我们的工作和生活中,
NAPT的作用随处可见,绝大部分公司的网络架构,都是通过1至N台支持NAPT的路由器来实现公司的所有计算机连接外部的Internet网络的。包括本人在写这篇文章的时候,也是在家中使用一台IBM笔记本通过一台宽带连接的台式机来访问Internet的。我们本篇文章主要讨论的NAPT的问题。
NAPT(The IP Network Address/Port Translator) 为何阻碍了P2P软件的应用?
通过NAPT
上网的特点决定了只能由NAPT内的计算机主动向NAPT外部的主机发起连接,外部的主机想直接和NAPT内的计算机直接建立连接是不被允许的。IM(即时通讯)而言,这意味着由于NAPT内的计算机和NAPT外的计算机只能通过服务器中转数据来进行通讯。对于P2P方式的下载程序而言,意味着NAPT内的计算机不能接收到NAPT外部的连接,导致连接数用过少,下载速度很难上去。因此P2P软件必须要解决的一个问题就是要能够在一定的程度上解决NAPT内的计算机不能被外部连接的问题。
NAT(The IP Network Address Translator) 进行UDP穿透的原理是什么?
TCP/IP传输时主要用到TCP和UDP协议。TCP协议是可靠的,面向连接的传输协议。UDP是不可靠的,无连接的协议。根据TCP和UDP协议的实现原理,对于NAPT来进行穿透,主要是指的UDP协议。TCP协议也有可能,但是可行性非常小,要求更高,我们此处不作讨论,如果感兴趣可以到Google上搜索,有些文章对这个问题做了探讨性的描述。下面我们来看看利用UDP协议来穿透NAPT的原理是什么:
图三: NAPT 是如何将私有IP地址的UDP数据包与公网主机进行透明传输的。
UDP协议包经NAPT透明传输的说明:
NAPT为每一个Session分配一个NAPT自己的端口号,依据此端口号来判断将收到的公网IP主机返回的TCP/IP数据包转发给那台内网IP地址的计算机。在这里Session是虚拟的,UDP通讯并不需要建立连接,但是对于NAPT而言,的确要有一个Session的概念存在。NAPT对于UDP协议
包的透明传输面临的一个重要的问题就是如何处理这个虚拟的Session。我们都知道TCP连接的Session以SYN包开始,以FIN包结束,NAPT可以很容易的获取到TCP
Session的生命周期,并进行处理。但是对于UDP而言,就麻烦了,NAPT并不知道转发出去的UDP协议包是否到达了目的主机,也没有办法知道。而且鉴于UDP协议的特点,可靠很差,因此NAPT必须强制维持Session的存在,以便等待将外部送回来的数据并转发给曾经发起请求的内网IP地址的计算机。NAPT具体如何处理UDP
Session的超时呢?不同的厂商提供的设备对于NAPT的实现不近相同,也许几分钟,也许几个小时,些NAPT的实现还会根据设备的忙碌状态进行智能计算超时时间的长短。
图四: NAPT 将内部发出的UDP协议包的源地址和源端口改变传输给公网IP主机。
图五: NAPT
将收到的公网IP主机返回的UDP协议包的目的地址和目的端口改变传输给内网IP计算机现在我们大概明白了NAPT如何实现内网计算机和外网主机间的透明通讯。现在来看一下我们最关心的问题,就是NAPT是依据什么策略来判断是否要为一个请求发出的UDP数据包建立Session的呢?主要有一下几个策略:
A. 源地址(内网IP地址)不同,忽略其它因素, 在NAPT上肯定对应不同的Session B.
源地址(内网IP地址)相同,源端口不同,忽略其它的因素,则在NAPT上也肯定对应不同的Session
C.
源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)相同,目的端口不同,则在NAPT上肯定对应同一个Session
D.
源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)不同,忽略目的端口,则在NAPT上是如何处理Session的呢?
D的情况正式我们关心和要讨论的问题。依据目的地址(公网IP地址)对于Session的建立的决定方式我们将NAPT设备划分为两大类:
Symmetric NAPT: 对于到同一个IP地址,任意端口的连接分配使用同一个Session;
对于到不同的IP地址, 任意端口的连接使用不同的Session. 我们称此种NAPT为
Symmetric NAPT. 也就是只要本地绑定的UDP端口相同,
发出的目的IP地址不同,则会建立不同的Session.
图六: Symmetric 的英文意思是对称。多个端口对应多个主机,平行的,对称的!
Cone NAPT: 对于到同一个IP地址,任意端口的连接分配使用同一个Session;
对于到不同的IP地址,任意端口的连接也使用同一个Session. 我们称此种NAPT为
Cone NAPT. 也就是只要本地绑定的UDP端口相同, 发出的目的地址不管是否相同,
都使用同一个Session.
图七: Cone 的英文意思是锥。一个端口对应多个主机,是不是像个锥子?
现在绝大多数的NAPT属于后者,即Cone
NAT。本人在测试的过程中,只好使用了一台日本的Symmetric
NAT。还好不是自己的买的,我从不买日货,
希望看这篇文章的朋友也自觉的不要购买日本的东西。Win9x/2K/XP/2003系统自带的NAPT也是属于
Cone NAT的。这是值的庆幸的,因为我们要做的UDP穿透只能在Cone
NAT间进行,只要有一台不是Cone
NAT,对不起,UDP穿透没有希望了,服务器转发吧。后面会做详细分析!
下面我们再来分析一下NAPT
工作时的一些数据结构,在这里我们将真正说明UDP可以穿透Cone
NAT的依据。这里描述的数据结构只是为了说明原理,不具有实际参考价值,真正感兴趣可以阅读Linux的中关于NAT实现部分的源码。真正的NAT实现也没有利用数据库的,呵呵,为了速度!
Symmetric NAPT 工作时的端口映射数据结构如下:
内网信息表:
[NAPT 分配端口] [ 内网IP地址 ] [ 内网端口 ] [ 外网IP地址 ] [ SessionTime
开始时间 ]
PRIMARY KEY( [NAPT 分配端口] ) -> 表示依据[NAPT
分配端口]建立主键,必须唯一且建立索引,加快查找. UNIQUE( [ 内网IP地址 ], [
内网端口 ] ) -> 表示这两个字段联合起来不能重复. UNIQUE( [ 内网IP地址 ], [
内网端口 ], [ 外网IP地址 ] ) -> 表示这三个字段联合起来不能重复.
映射表:
[NAPT 分配端口] [ 外网端口 ]
UNIQUE( [NAPT 分配端口], [ 外网端口 ] ) -> 表示这两个字段联合起来不能重复.
Cone NAPT 工作时的端口映射数据结构如下:
内网信息表:
[NAPT 分配端口] [ 内网IP地址 ] [ 内网端口 ] [ SessionTime 开始时间 ]
PRIMARY KEY( [NAPT 分配端口] ) -> 表示依据[NAPT
分配端口]建立主键,必须唯一且建立索引,加快查找. UNIQUE( [ 内网IP地址 ], [
内网端口 ] ) -> 表示这两个字段联合起来不能重复.
外网信息表:
[ wid 主键标识 ] [ 外网IP地址 ] [ 外网端口 ]
PRIMARY KEY( [ wid 主键标识 ] ) -> 表示依据[ wid 主键标识
]建立主键,必须唯一且建立索引,加快查找. UNIQUE( [ 外网IP地址 ], [
外网端口 ] ) -> 表示这两个字段联合起来不能重复.
映射表: 实现一对多,的
[NAPT 分配端口] [ wid 主键标识 ]
UNIQUE( [NAPT 分配端口], [ wid 主键标识 ] ) ->
表示这两个字段联合起来不能重复. UNIQUE( [ wid 主键标识 ] ) ->
标识此字段不能重复.
看完了上面的数据结构是更明白了还是更晕了? 呵呵!
多想一会儿就会明白了。通过NAT,内网计算机计算机向外连结是很容易的,NAPT会自动处理,我们的应用程序根本不必关心它是如何处理的。那么外部的计算机想访问内网中的计算机如何实现呢?我们来看一下下面的流程:
c 是一台在NAPT后面的内网计算机,s是一台有外网IP地址的计算机。c 主动向 s
发起连接请求,NAPT依据上面描述的规则在自己的数据结构中记录下来,建立一个Session.
然后 c 和 s 之间就可以实现双向的透明的数据传输了。如下面所示:
c[192.168.0.6:1827] <-> [priv ip:
192.168.0.1]NAPT[pub ip: 61.51.99.86:9881] <-> s[61.51.76.102:8098]
由此可见,一台外网IP地址的计算机想和NAPT后面的内网计算机通讯的条件就是要求NAPT后面的内网计算机主动向外网IP地址的计算机发起一个UDP数据包。外网IP地址的计算机利用收到的UDP数据包获取到NAPT的外网IP地址和映射的端口,以后就可以和内网IP的计算机透明的进行通讯了。
现在我们再来分析一下我们最关心的两个NAPT后面的内网计算机如何实现直接通讯呢?
两者都无法主动发出连接请求,谁也不知道对方的NAPT的公网IP地址和NAPT上面映射的端口号。所以我们要靠一个公网IP地址的服务器帮助两者来建立连接。当两个NAPT后面的内网计算机分别连接了公网IP地址的服务器后,服务器可以从收到的UDP数据包中获取到这两个NAPT设备的公网IP地址和这两个连接建立的Session的映射端口。两个内网计算机可以从服务器上获取到对方的NAPT设备公网IP地址和映射的端口了。
我们假设两个内网计算机分别为A和B,对应的NAPT分别为AN和 BN,
如果A在获取到B对应的BN的IP地址和映射的端口后,迫不急待的向这个IP
地址和映射的端口发送了个UDP数据包,会有什么情况发生呢?依据上面的原理和数据结构我们会知道,AN会在自己的数据结构中生成一条记录,标识一个新Session的存在。BN在收到数据包后,从自己的数据结构中查询,没有找到相关记录,因此将包丢弃。B是个慢性子,此时才慢吞吞的向着AN的IP地址和映射的端口发送了一个UDP数据包,结果如何呢?当然是我们期望的结构了,AN在收到数据包后,从自己的数据结构中查找到了记录,所以将数据包进行处理发送给了A。A
再次向B发送数据包时,一切都时畅通无阻了。OK, 大工告成!且慢,这时对于Cone
NAPT而言,对于Symmetric NAPT呢?呵呵,自己分析一下吧...
NAPT(The IP Network Address/Port Translator) 进行UDP穿透的具体情况分析!
首先明确的将NAPT设备按照上面的说明分为: Symmetric NAPT 和 Cone NAPT, Cone
NAPT 是我们需要的。Win9x/2K/XP/2003 自带的NAPT也为Cone NAPT。
第一种情况, 双方都是Symmetric NAPT:
此情况应给不存在什么问题,肯定是不支持UDP穿透。
第二种情况, 双方都是Cone NAPT:
此情况是我们需要的,可以进行UDP穿透。
第三种情况, 一个是Symmetric NAPT, 一个是Cone NAPT:
此情况比较复杂,但我们按照上面的描述和数据机构进行一下分析也很容易就会明白了,
分析如下,
假设: A -> Symmetric NAT, B -> Cone NAT
1. A 想连接 B, A 从服务器那儿获取到 B 的NAT地址和映射端口, A
通知服务器,服务器告知 B A的NAT地址和映射端口, B 向 A 发起连接,A
肯定无法接收到。此时 A 向 B 发起连接, A
对应的NAT建立了一个新的Session,分配了一个新的映射端口, B 的 NAT
接收到UDP包后,在自己的映射表中查询,无法找到映射项,因此将包丢弃了。
2. B 想连接 A, B 从服务器那儿获取到 A 的NAT地址和映射端口, B 通知服务器,
服务器告知 A B的NAT地址和映射端口,A 向 B 发起连接, A
对应的NAT建立了一个新的Session,分配了一个新的映射端口B肯定无法接收到。此时
B 向 A 发起连接, 由于 B 无法获取 A
建立的新的Session的映射端口,仍是使用服务器上获取的映射端口进行连接, 因此
A 的NAT在接收到UDP包后,在自己的映射表中查询,无法找到映射项,
因此将包丢弃了。
根据以上分析,只有当连接的两端的NAT都为Cone
NAT的情况下,才能进行UDP的内网穿透互联。
NAPT(The IP Network Address/Port Translator)
进行UDP穿透如何进行现实的验证和分析!
需要的网络结构如下:
三个NAT后面的内网机器,两个外网服务器。其中两台Cone NAPT,一台 Symmetric
NAPT。
验证方法:
可以使用本程序提供的源码,编译,然后分别运行服务器程序和客户端。修改过后的源码增加了客户端之间直接通过IP地址和端口发送消息的命令,利用此命令,你可以手动的验证NAPT的穿透情况。为了方便操作,推荐你使用一个远程登陆软件,可以直接在一台机器上操作所有的相关的计算机,这样很方便,一个人就可以完成所有的工作了。呵呵,本人就是这么完成的。欢迎有兴趣和经验的朋友来信批评指正,共同进步。

2009年6月28日星期日

编码转换 iconv

一、利用iconv函数族进行编码转换
在LINUX上进行编码转换时,既可以利用iconv函数族编程实现,也可以利用iconv命令来实现,只不过后者是针对文件的,即将指定文件从一种编码转换为另一种编码。
iconv函数族的头文件是iconv.h,使用前需包含之。
#include <iconv.h>
iconv函数族有三个函数,原型如下:
(1) iconv_t iconv_open(const char *tocode, const char *fromcode);
此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。
(2) size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char
**outbuf,size_t *outbytesleft);
此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。
(3) int iconv_close(iconv_t cd);
此函数用于关闭转换句柄,释放资源。
例子1: 用C语言实现的转换示例程序
/* f.c : 代码转换示例C程序 */
#include <iconv.h>
#define OUTLEN 255
main()
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安装";
char out[OUTLEN];
//unicode码转为gb2312码
rc = u2g(in_utf8,strlen(in_utf8),out,OUTLEN);
printf("unicode-->gb2312 out=%sn",out);
//gb2312码转为unicode码
rc = g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN);
printf("gb2312-->unicode out=%sn",out);
}
//代码转换:从一种编码转为另一种编码
int code_convert(char *from_charset,char *to_charset,char *inbuf,int
inlen,char *outbuf,int outlen)
{
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;
cd = iconv_open(to_charset,from_charset);
if (cd==0) return -1;
memset(outbuf,0,outlen);
if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1;
iconv_close(cd);
return 0;
}
//UNICODE码转为GB2312码
int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
//GB2312码转为UNICODE码
int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen);
}
例子2: 用C++语言实现的转换示例程序
/* f.cpp : 代码转换示例C++程序 */
#include <iconv.h>
#include <iostream>
#define OUTLEN 255
using namespace std;
// 代码转换操作类
class CodeConverter {
private:
iconv_t cd;
public:
// 构造
CodeConverter(const char *from_charset,const char *to_charset) {
cd = iconv_open(to_charset,from_charset);
}
// 析构
~CodeConverter() {
iconv_close(cd);
}
// 转换输出
int convert(char *inbuf,int inlen,char *outbuf,int outlen) {
char **pin = &inbuf;
char **pout = &outbuf;
memset(outbuf,0,outlen);
return iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
}
};
int main(int argc, char **argv)
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安装";
char out[OUTLEN];
// utf-8-->gb2312
CodeConverter cc = CodeConverter("utf-8","gb2312");
cc.convert(in_utf8,strlen(in_utf8),out,OUTLEN);
cout << "utf-8-->gb2312 in=" << in_utf8 << ",out=" << out << endl;
// gb2312-->utf-8
CodeConverter cc2 = CodeConverter("gb2312","utf-8");
cc2.convert(in_gb2312,strlen(in_gb2312),out,OUTLEN);
cout << "gb2312-->utf-8 in=" << in_gb2312 << ",out=" << out << endl;
}
二、利用iconv命令进行编码转换
在LINUX上进行编码转换时,既可以利用iconv函数族编程实现,也可以利用iconv命令来实现,只不过后者是针对文件的,即将指定文件从一种编码转换为另一种编码。
iconv命令用于转换指定文件的编码,默认输出到标准输出设备,亦可指定输出文件。
用法: iconv [选项...] [文件...]
有如下选项可用:
输入/输出格式规范:
-f, --from-code=名称 原始文本编码
-t, --to-code=名称 输出编码
信息:
-l, --list 列举所有已知的字符集
输出控制:
-c 从输出中忽略无效的字符
-o, --output=FILE 输出文件
-s, --silent 关闭警告
--verbose 打印进度信息
-?, --help 给出该系统求助列表
--usage 给出简要的用法信息
-V, --version 打印程序版本号
例子:
iconv -f utf-8 -t gb2312 aaa.txt >bbb.txt
这个命令读取aaa.txt文件,从utf-8编码转换为gb2312编码,其输出定向到bbb.txt文件。
小结: LINUX为我们提供了强大的编码转换工具,给我们带来了方便。
glibc带了一套转码函数iconv,使用方便,可识别的码很多,如果程序需要涉及到编码之间的转换,可考虑用它。
iconv命令的用法。
$ iconv --list # 显示可识别的编码名称
$ iconv -f GB2312 -t UTF-8 a.html > b.html #
转换GB2312编码的文件a.html为UTF-8编码,存入b.html
$ iconv -f GB2312 -t BIG5 a.html > b.html #
转换GB2312编码的文件a.html为BIG5编码,存入b.html
iconv编程涉及到以下glibc库的调用:
#include <iconv.h>
iconv_t iconv_open(const char *tocode, const char *fromcode);
int iconv_close(iconv_t cd);
size_t iconv(iconv_t cd,
char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);
在使用iconv转码的时候,首先用iconv_open获取转码句柄,然后调用iconv转码,转完了后调用iconv_close关闭句柄。
iconv函数中:
参数cd是用iconv_open调用返回的转码句柄;
参数inbuf指向需要转码的缓冲区;
参数inbytesleft是inbuf所保存的需要转码的字节数;
参数outbuf存放转码结果;
参数outbytesleft存放outbuf空间的大小。
如果调用成功,iconv返回转换的字节数(不可逆转调用的字节数,可逆转调用的字节数不包括在内)。否则返回-1,并设置相应的errno。
iconv逐步扫描inbuf,每转换一个字符,就增加inbuf,减少inbytesleft,并将结果存入outbuf,结果字节数存入outbytesleft。遇到下列情况将停止扫描并返回:
1. 多字节序列无效,这时候errno为EILSEQ,*inbuf指向第一个无效的字符;
2. 有字节留在inbuf尚未转换,errno为EINVAL;
3. outbuf空间不够,errno为E2BIG;
4. 正常转换完备。
对于iconv函数,还有两种调用情况:
1.
inbuf或者*inbuf为NULL,outbuf和*outbuf不为NULL,iconv会设置转换状态为初始状态,并保存转换序列到*outbuf。如果outbuf空间不足,errno会设置为E2BIG,返回(size_t)(-1);
2.
inbuf或者*inbuf为NULL,outbuf或者*outbuf也为NULL,iconv设置转换状态为初始状态。
iconv命令的使用固然方便,可是如果转换过程中如果遇到问题则会停止转换,有时候我们希望跳过不能转换的字节序列继续转换。以下的一段程序能实现这种功能。
/**
* siconv.cpp - A simple way to demostrate the usage of iconv calling
*
* Report bugs to marchday2004@yahoo.com.cn
* July 15th, 2006
*/
#include <iconv.h>
#include <stdio.h>
#include <string>
#include <stdarg.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#ifdef DEBUG
#define TRACE(fmt, args...) fprintf(stderr, "%s:%s:%d:"fmt, \
__FILE__, __FUNCTION__, __LINE__, ##args)
#else
#define TRACE(fmt, args...)

printf()格式化输出详解

printf的格式控制的完整格式:
% - 0 m.n l或h 格式字符
下面对组成格式说明的各项加以说明:
①%:表示格式说明的起始符号,不可缺少。
②-:有-表示左对齐输出,如省略表示右对齐输出。
③0:有0表示指定空位填0,如省略表示指定空位不填。
④m.n:m指域宽,即对应的输出项在输出设备上所占的字符数。N指精度。用于说明输出的实型数的小数位数。对数值型的来说,未指定n时,隐含的精度为n=6位。
⑤l或h:l对整型指long型,对实型指double型。h用于将整型的格式字符修正为short型。
---------------------------------------
格式字符
格式字符用以指定输出项的数据类型和输出格式。
①d格式:用来输出十进制整数。有以下几种用法:
%d:按整型数据的实际长度输出。
%md:m为指定的输出字段的宽度。如果数据的位数小于m,则左端补以空格,若大于m,则按实际位数输出。
%ld:输出长整型数据。
②o格式:以无符号八进制形式输出整数。对长整型可以用"%lo"格式输出。同样也可以指定字段宽度用"%mo"格式输出。
例:
main()
{ int a = -1;
printf("%d, %o", a, a);
}
运行结果:-1,177777
程序解析:-1在内存单元中(以补码形式存放)为(1111111111111111)2,转换为八进制数为(177777)8。
③x格式:以无符号十六进制形式输出整数。对长整型可以用"%lx"格式输出。同样也可以指定字段宽度用"%mx"格式输出。
④u格式:以无符号十进制形式输出整数。对长整型可以用"%lu"格式输出。同样也可以指定字段宽度用"%mu"格式输出。
⑤c格式:输出一个字符。
⑥s格式:用来输出一个串。有几中用法
%s:例如:printf("%s", "CHINA")输出"CHINA"字符串(不包括双引号)。
%ms:输出的字符串占m列,如字符串本身长度大于m,则突破获m的限制,将字符串全部输出。若串长小于m,则左补空格。
%-ms:如果串长小于m,则在m列范围内,字符串向左靠,右补空格。
%m.ns:输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的右侧,左补空格,注意:如果n未指定,默认为0。
%-m.ns:其中m、n含义同上,n个字符输出在m列范围的左侧,右补空格。如果n>m,则自动取n值,即保证n个字符正常输出,注意:如果n未指定,默认为0。
如果是sprintf(desc, "%m.ns", sour); 如果desc空间够的话,会在%m.ns 串
的结尾自动补null字符,不同于strncpy。
例如 :sprintf(desc, "%.3s", "123456");
desc如果空间>=4字节的话,第4个字节将是null字符。
⑦f格式:用来输出实数(包括单、双精度),以小数形式输出。有以下几种用法:
%f:不指定宽度,整数部分全部输出并输出6位小数。
%m.nf:输出共占m列,其中有n位小数,如数值宽度小于m左端补空格。
%-m.nf:输出共占n列,其中有n位小数,如数值宽度小于m右端补空格。
⑧e格式:以指数形式输出实数。可用以下形式:
%e:数字部分(又称尾数)输出6位小数,指数部分占5位或4位。
%m.ne和%-m.ne:m、n和"-"字符含义与前相同。此处n指数据的数字部分的小数位数,m表示整个输出数据所占的宽度。
⑨g格式:自动选f格式或e格式中较短的一种输出,且不输出无意义的零。
---------------------------------------
关于printf函数的进一步说明:
如果想输出字符"%",则应该在"格式控制"字符串中用连续两个%表示,如:
printf("%f%%", 1.0/3);
输出0.333333%。
---------------------------------------
对于单精度数,使用%f格式符输出时,仅前7位是有效数字,小数6位.
对于双精度数,使用%lf格式符输出时,前16位是有效数字,小数6位.
----------------------------------------------------------------------------------------------------------------------
printf()函数是格式输出函数,请求printf()打印变量的指令取决与变量的类型.例如,在打印整数是使用%d符号,在打印字符是
用%c
符号.这些符号被称为转换说明.因为它们指定了如何不数据转换成可显示的形式.下列列出的是ANSI C标准peintf()提供的各种转换说明.
转换说明及作为结果的打印输出
%a 浮点数、十六进制数字和p-记数法(C99)
%A    浮点数、十六进制数字和p-记法(C99)
%c    一个字符 
%d    有符号十进制整数 
%e    浮点数、e-记数法
%E    浮点数、E-记数法
%f    浮点数、十进制记数法  
%g    根据数值不同自动选择%f或%e.
%G    根据数值不同自动选择%f或%e.
%i 有符号十进制数(与%d相同)
%o    无符号八进制整数
%p    指针    
%s    字符串
%u    无符号十进制整数
%x    使用十六进制数字0f的无符号十六进制整数 
%X    使用十六进制数字0f的无符号十六进制整数
%%    打印一个百分号
//还有一个特殊的格式%*.*
,这两个星号的值分别由第二个和第三个参数的值指定
printf("%.*s \n", 8, "abcdefgggggg");
printf("%*.*f \n", 3,3, 1.25456f);
使用printf ()函数
 printf()的基本形式: printf("格式控制字符串",变量列表);
#include<cstdio>
int main()
{
//for int
int i=30122121;
long i2=309095024l;
short i3=30;
unsigned i4=2123453;
printf("%d,%o,%x,%X,%ld,%hd,%u\n",i,i,i,i,i2,i3,i4);//如果是:%l,%h,则输不出结果
printf("%d,%ld\n",i,i2);//试验不出%ld和%d之间的差别,因为long是4bytes
printf("%hd,%hd\n\n\n",i,i3);//试验了%hd和%d之间的差别,因为short是2bytes
//for string and char
char ch1='d';
unsigned char ch2=160;
char *str="Hello everyone!";
printf("%c,%u,%s\n\n\n",ch1,ch2,str);//unsigned
char超过128的没有字符对应
//for float and double,unsigned and signed can not be used with double
and float
float fl=2.566545445F;//or 2.566545445f
double dl=265.5651445;
long double dl2=2.5654441454;
//%g没有e格式,默认6位包括小数点前面的数,
//%f没有e格式,默认6位仅只小数点后面包含6位
//%e采用e格式,默认6位为转化后的小数点后面的6位
printf("%f,%e,%g,%.7f\n",fl,dl,dl,dl);
printf("%f,%E,%G,%f\n",fl,dl,dl,dl);//%F is wrong
printf("%.8f,%.10e\n",fl,dl);
printf("%.8e,%.10f\n\n\n",fl,dl);
//for point
int *iP=&i;
char *iP1=new char;
void *iP2;//dangerous!
printf("%p,%p,%p\n\n\n",iP,iP1,iP2);
//其他知识:负号,表示左对齐(默认是右对齐);%6.3,6表示宽度,3表示精度
char *s="Hello world!";
printf(":%s: \n:%10s: \n:%.10s: \n:%-10s: \n:%.15s: \n:%-15s:
\n:%15.10s: \n:%-15.10s:\n\n\n",
s,s,s,s,s,s,s,s);
double ddd=563.908556444;
printf(":%g: \n:%10g: \n:%.10g: \n:%-10g: \n:%.15g: \n:%-15g:
\n:%15.10g: \n:%-15.10g:\n\n\n",
ddd,ddd,ddd,ddd,ddd,ddd,ddd,ddd);
//还有一个特殊的格式%*.*
,这两个星号的值分别由第二个和第三个参数的值指定
printf("%.*s \n", 8, "abcdefgggggg");
printf("%*.*f \n", 3,3, 1.25456f);
return 0;
}

静态库和共享库库的定位搜索路径(编译时和运行时)

库文件在连接(静态库和共享
库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的。一般
Linux 系统把 /lib 和 /usr/lib
两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到
库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:
在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。
在 /etc/ld.so.conf 文件中添加库的搜索路径。
将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择
添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:
/usr/X11R6/lib
/usr/local/lib
/opt/lib
需要注意的是:第二种搜索路径的设置方式对于程序连接时的库(包括共享库和静态库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是
因为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所以是直接读取库列表文件
/etc/ld.so.cache 从中进行搜索的。/etc/ld.so.cache
是一个非文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf
中设置的搜索路径由 /sbin/ldconfig
命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令要以 root
权限执行)。
因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf
中进行了库搜索路径的设置之后,还必须要运行 /sbin/ldconfig 命令更新
/etc/ld.so.cache 文件之后才可以。ldconfig
,简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache
以供使用。因此当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增加新的库路径后,需要运行一下
/sbin/ldconfig使所有的库文件都被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使用
的,结果编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂computer蠢猪一个。
在程序连接时,对于库文件(静态库和共享库)的搜索路径,除了上面的设置方式之外,还可以通过
-L 参数显式指定。因为用 -L
设置的路径将被优先搜索,所以在连接的时候通常都会以这种方式直接指定要连接的库的路径。
前面已经说明过了,库搜索路径的设置有两种方式:
在环境变量 LD_LIBRARY_PATH 中设置
在 /etc/ld.so.conf 文件中设置。
其中,第二种设置方式需要 root 权限,以改变 /etc/ld.so.conf 文件并执行
/sbin/ldconfig 命令。而且,当系统重新启动后,所有的基于 GTK2
的程序在运行时都将使用新安装的 GTK+ 库。不幸的是,由于 GTK+
版本的改变,这有时会给应用程序带来兼容性的问题,造成某些程序运行不正常。为了避免出现上面的这些情况,在
GTK+
及其依赖库的安装过程中对于库的搜索路径的设置将采用第一种方式进行。这种设置方式不需要
root 权限,设置也简单:
$ export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH
可以用下面的命令查看 LD_LIBRAY_PATH 的设置内容:
$ echo $LD_LIBRARY_PATH
至此,库的两种设置就完成了。
交叉编译时候如何配置连接库的搜索路径
交叉编译的时候不能使用本地(i686机器,即PC机器,研发机器)机器上的库,但是在做编译链接的时候默认的是使用本地库,即/usr/lib,/lib两个目录。因此,在交叉编译的时候,要采取一些方法使得在编译链接的时候找到需要的库。
首先,要知道:编译的时候只需要头文档,真正实际的库文档在链接的时候用到。
(这是我的理解,假如有不对的地方,敬请网上各位大侠指教)
然后,讲讲如何在交叉编译链接的时候找到需要的库。
(1)、交叉编译时候直接使用-L和-I参数指定搜索非标准的库文档和头文档的路径。例如:
arm-linux-gcc test.c -L/usr/local/arm/2.95.3/arm-linux/lib
-I/usr/local/arm/2.95.3/arm-linux/include
(2)、使用ld.so.conf文档,将用到的库所在文档目录添加到此文档中,然后使用ldconfig命令刷新缓存。
(3)、使用如下命令:
$ export
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/2.95.3/arm-linux-lib
参见《ld.so.conf 文档和PKG_CONFIG_PATH变量》这篇文章。
通过环境变量LD_LIBRARY_PATH指定动态库搜索路径(!)。
通过设定环境变量LD_LIBRARY_PATH也可以指定动态库搜索路径。当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔。
不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LD_LIBRARY_PATH
的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》
)。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路
径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。
(4)、交叉编译时使用软件的configure参数。例如我编译minigui-1.3.3,使用如下配置:
#!/bin/bash
rm -f config.cache config.status
./configure --build=i686-linux --host=arm-linux --target=arm-linux \
CFLAGS=-I/usr/local/arm/2.95.3/arm-linux/include \
LDFLAGS=-L/usr/local/arm/2.95.3/arm-linux/lib \
--prefix=/usr/local/arm/2.95.3/arm-linux \
--enable-lite \
--disable-galqvfb \
--disable-qvfbial \
--disable-vbfsupport \
--disable-ttfsupport \
--disable-type1support \
--disable-imegb2312py \
--enable-extfullgif \
--enable-extskin \
--disable-videoqvfb \
--disable-videoecoslcd
这里我配置了CFLAGS和LDFLAGS参数,这样一来,我就不用去修改每个Makefile里-L和-I参数了,也不用再去配置LD_LIBRARY_PATH或改写ld.so.conf文档了。
Linux下动态库使用小结
1. 静态库和动态库的基本概念
静态库,是在可执行程序连接时就已经加入到执行码中,在物理上成为执行程序的一部分;使用静态库编译的程序运行时无需该库文件支持,哪里都可以用,但是生
成的可执行文件较大。动态库,是在可执行程序启动时加载到执行程序中,可以被多个可执行程序共享使用。使用动态库编译生成的程序相对较小,但运行时需要库
文件支持,如果机器里没有这些库文件就不能运行。
2. 如何使用动态库
如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。linux的可执行程序在执行的时候默认是先搜索/lib和/usr/lib这
两个目录,然后按照/etc/ld.so.conf里面的配置搜索绝对路径。同时,Linux也提供了环境变量LD_LIBRARY_PATH供用户选择
使用,用户可以通过设定它来查找除默认路径之外的其他路径,如查找/work/lib路径,你可以在/etc/rc.d/rc.local或其他系统启动
后即可执行到的脚本添加如下语句:LD_LIBRARY_PATH
=/work/lib:$(LD_LIBRARY_PATH)。并且LD_LIBRARY_PATH路径优先于系统默认路径之前查找(详细参考《使用
LD_LIBRARY_PATH》)。
不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LD_LIBRARY_PATH
的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》
)。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路
径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。
3.库的链接时路径和运行时路径
现代连接器在处理动态库时将链接时路径(Link-time
path)和运行时路径(Run-time
path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提高了库应用的灵活性。比如我们做嵌入式
移植时#arm-linux-gcc $(CFLAGS) –o target –L/work/lib/zlib/ -llibz-1.2.3
(work/lib/zlib下是交叉编译好的zlib库),将target编译好后我们只要把zlib库拷贝到开发板的系统默认路径下即可。或者通过-
rpath(或-R )、LD_LIBRARY_PATH指定查找路径。
小问题:
1.编译时的-L选项是否影响LD_LIBRARY_PATH的值?
举一个实例:
当前文件夹结构如下:
test.c tools/
tool下有tool.c tool.h my_err.h 以及由此生成的libtool.so
tool下编译生成库文件
gcc -Wall -g -shared -o tool.so tool.c
在当前文件夹引用:
gcc -Wall -g –o test.c -Ltools -ltool
编译不报错,但是运行加载的时候就出现cannot open shared object file。
如果将该库文件拷贝到/usr/lib下就没有错误,正常运行。
说明编译时的-L选项并不影响环境变量LD_LIBRARY_PATH,-L只是指定了程序编译连接时库的路径,并不影响程序执行时库的路径,系统还是会到默认路径下查找该程序所需要的库。
有关动态链接库需要注意的相关事项
1.有关动态链接库需要注意的相关事项。
如果碰到有GTK 的程序中 有 <gtk\gtk.h>
那么需要加入动态链接库的参数
$ gcc test_a.c test_b.c iptbox.c -fPIC -shared -o iptbox.so `pkg-config
--cflags --libs gtk+-2.0
生成出来的.so 动态链接库 需要放在usr/lib 目录下
cp libipt.so /usr/lib
2、在运行AP时出现错误,可以使用下列方式来查找问题:
strace ./test
3、查找文件夹下路径:
find /usr/lib -name libipt.so
4、解压缩命令:
tar -zxvf 文件名
5、解RPM包的方式:
#rpm -ivh scim-1.4.7.4-1benX.src.rpm
#cd /usr/src/dorado/SPECS
#rpmbuild -bb scim.spec
6、目录权限打开:
chmod 777 root(目录名称)
7、linux 下安装软件三步骤:
a. ./configure
b. make
c. make install
8、更新库引用:
ldconfig
9、查找是否有安装该AP.
# whereis scim-ppenglish

多线程编程之重点--使用DSP/BIOS时选择线程类型的参考方法

了解以下这些,对在DSP/BIOS上设计多线程应用程序就是轻而易举的事件。
DSP/BIOS支持多种类型线程,每种类型线程且有不同执行及抢先点,下图表(点击可见大图)列出了这些线程的一些特点。

线程选择的一些原则
对线程选择基于对下面这个问题的回答:在应用程序中,这个线程是否具有实时性(线程必须在严格的时间段内结束,以及不允许被抢先)?该线程的执行时间相对其它部分来说是否少很多?
1. 严格的实时性
如果线程的执行需要严格的实时性,而线程执行需要的时间又很少时,可以使用硬件中断或时钟函数来完成。CLK时钟函数也是在硬件中断中执行的。
DSP芯片一般都有一个或多个片上定时器外设,并能产生周期性的等间隔硬件中断。DSP/BIOS内核通常会使用其中的一个定时器作为自己的系统时钟。在大多数TMS320系列的DSP中,DSP/BIOS内核的CLK模块都可以提供接近一个机器周期的时钟。CLK函数将由片上的定时器中断触发,并在该中断的中断服务子程序(ISR)中调用执行。
硬件中断线程由外部的同步事件(或AD转换器的中断信号)触发而执行。HWI函数或中断服务子程序(ISR)将在中断发生后执行。由于硬件中断具有最高优先级,所以HWI函数具有严格的实时性。在DSP/BIOS的应用程序中,HWI中断函数能够处理频率为200KHZ的中断(具体瑾因工作频率不同或ISR的复杂度而可能有差异)。所以当处理时间间隔在2-5US之间时,可以使用硬件中断线程。还有一个原因,就是硬件中断线程有极小的中断潜伏期。所谓中断潜伏期,指的是从中断触发到中断服务子程序的第一条指令开始执行之间的时间。当然,中断潜伏期越长,表示中断的响应越不及时,这一点对处理的实时性来讲相当重要。硬件中断线程只可以用汇编语言或C语言和汇编语言的混合体,但通常我推荐使用汇编语言。
在硬件中断处理函数中,可以将SWI软件中断对象,或TSK任务对象放到执行队列中,但它们必须等到所有的硬件中断线程结束后才能允许。所以,应该尽量减小HWI硬件中断函数,以便中断服务序尽快结束。另外,DSP在响应硬件中断后会自动屏蔽所有的中断,因此可以通过设置调用HWI_enter的参数开放一些中断,允许这些中断抢先执行。在系统存在多个硬件中断线程,而其中一个的中断服务程序稍长时,这种方法非常有效。
当硬件中断函数调用某些PIP管道模块的API函数时,如PIP_alloc,PIP_free,PIP_get,PIP_put等,读写通知函数也将在中断响应中调用执行。
2.部分实时性
有时会遇到这种情况,只有一部分线程的执行要求有严格的实时性,其余部分执行时间较长而且对处理时间没有太多的要求。显然,这时仅仅使用硬件中断线程是不理想的。
一般情况下,要求严格实时性的处理都是由硬件中断触发,所以我们显然会使用硬件中断服务程序来响应这个中断,以便满足对实时性的要求。更为能用的做法是,可以增加SWI软件中断或TSK任务线程来完成一些非实时性的处理任务。这样可以减少中断的潜伏期,提高响应实时性请求的能力。
所以,将代码分为多个线程,只要求有严格实时性的任务放到HWI硬件中断中完成,而其余处理都放到优先级较低的SWI或TSK中完成。这些SWI或TSK线程有如下两个特点:
* 能完成实时处理任务,但允许处理时间相对较长;
* 允许被其他线程抢先。
那么这些处理函数究竟该选择使用SWI软件中断线程还是TSK任务线程呢?请先看下面的几种情况:
* 处理函数需要等待某些资源(例如数据、上位机的信号等),以便继续运行。
* 处理函数与其他线程之间有复杂的联系或数据共享要求。
* 希望处理函数有自己的堆栈空间而不是系统共用的堆栈空间。
* 处理函数中用到LCK,MBX或SEM这几个内核模块。
* 希望在线程创建、删除、退出、就绪、切换时调用钩子函数。
当上面的情况有任何一种存在时,建议使用TSK任务线程;相反,当没有上面的一种情况出现时,建议选用SWI软件中断。任务线程与软件中断线程有以下几点区别:
* 任务在执行时可以被挂起(suspended,可以理解为暂停),直到必需的条件(如数据准备好、信号同步等)得到满足,才可以继续运行。在任务被挂起时,即任务处于暂停或阻塞(blocked)状态,其他任务或线程得以执行,而软件中断做不到这点。
* DSP/BIOS内核提供了一组用于任务之间通信和同步的数据结构,包括旗语、邮箱和锁。这些数据结构无法用于软件中断之间的通信和同步。
* 每个任务都有自己的堆栈区,而软件中断使用共享的系统堆栈。
* 当任务被创建、删除、退出或切换时,都可以调用特殊函数(钩子函数)。这些钩子函数可以用于保存任务的环境面不仅仅是CPU的寄存器。
* 任务线程的优先级比软件中断线程低,而比后台IDL线程高。任务线程内部又被划分为16个优先等级。用户任务的优先级可以是从1-15级,最低的0级内核保留给LOOP循环使用。
软件中断线程往往伴随着硬件中断的发生。每当有硬件中断发生时,会触发HWI硬件中断服务函数,而软件中断的触发是靠SWI软件中断API函数调用实现的。例如,在硬件中断服务函数中调用SWI_post函数,可以触发一个SWI软件中断。
软件中断线程适合于处理一些发生速率较低的任务,或对实时性要求不苛刻的任务。SWI软件中断可以帮助硬件中断函数将一些非严格实时性的处理放到低优先级的线程中,以减少硬件中断的响应时间。这点非常重要,因为在硬件中断响应过程中往往处于关中断状态。
与硬件中断线程一样,软件中断线程总会一直执行下去,直到结束。当程序将软件中断放到CPU的执行队列中排队等待时,软件中断函数需要的所有数据应该是准备好了的。SWI软件中断对象中的邮箱提供了一种判断资源准备情况的方法。在其他线程运行时,一个软件中断线程不能够等待资源变为有效。
软件中断的优先级比任务线程高,但比硬件中断低。软件中断线程比任务线程使用更少的存储器,因为所有的软件中断线程都使用系统的堆栈空间。任务线程提供了额外的能力,如暂停(阻塞)和切换,而软件中断线程不支持这些。
3.周期性的服务
虽然有时线程的执行有实时性限制,但是处理任务却有足够长的时间执行而且能够允许其他线程抢先,即被其他线程中断去处理更紧急的任务。这种情况可以参照上面处理部分实时性线程的原则进行处理。但其中有一个较特殊的应用,就是需要周期性地或在固定的时间间隔内完成处理任务,而一般情况下,时间间隔比处理任务所需的时间要长得多。对于这种要求,我建议使用DSP/BIOS内核提供的PRD周期性函数来完成。
周期函数以系统时钟为基础,默认情况下,系统时钟由片上定时器驱动,也可以配置为其他事件来驱动,如IO事件等。周期性函数属于SWI软件中断中的PRD_swi对象,通常该对象的优先级较低,可以通过DSP/BIOS的配置工具提高它的优先级。
所有的PRD周期函数具有同样的SWI软件中断优先级,因此一个周期函数是不能抢先其他周期函数的。当存在一些处理时间较长的其他SWI或TSK线程时,为了保证所有PRD周期函数正常执行,除了尽量缩短周期函数本身的处理时间外,还需要提高整个PRD周期函数的优先级,以保证周期函数被允许在系统时钟触发时能够抢先那些低优先级的线程。
如果多个周期函数被同一个系统时钟触发,它们将按照创建时的顺序执行。另外,若周期函数需要被挂起或暂停时,应该使用TSK线程来完成同样的服务。
4.不需要实时性
有时线程只需要在后台进行一些无关紧要的处理,比如收集统计数据、与自己交换检测数据等。这时,我们建议使用IDL线程。
IDL等待循环是DSP/BIOS内核中最低优先级的线程。当应用程序的主函数返回后,DSP/BIOS内核调用该应用程序所用到的DSP/BIOS模块的初始化启动代码。在这些启动代码结束后,便进入这个IDL等待循环。该循环是一个无限循环,它不停地调用IDL后台对象中的所有函数。每个函数在前一个函数结束后依次运行。这些IDL函数不断被运行,直到被更高优先级的线程抢先。由于IDL函数的优先级最低,运行的时间得不到保证,所以IDL函数不适合于有实时性要求的任何处理任务。它通常用在一些不需要中断(当然也不能有中断)的非实时设备查询中,或用于监视系统状态,或其他一些后台活动。
DSP目标系统与主机的DSP/BIOS分析工具之间的通信是在后台IDL循环中完成的。这可以保证DSP/BIOS的分析工具不会干扰应用程序的运行。如果目标板上的DSP太忙,以致无法运行后台IDL线程时,DSP/BIOS分析工具会停止接收目标板信息。所以我们经常会看到,当目标板DSP的处理任务太繁重或因错误落入一个死循环时,CCS的所有操作都会变得迟缓起来。

只放一只羊!

"阿尔迪"超市的所有者,是德国80多岁的阿尔布莱希特兄弟,它是全世界公认的零售
业航母,目前的身价已达400亿欧元。在美国,阿尔迪的年销售额现已达到48亿美元,它计划
今后每年开40家分店,到2010年把总量扩展到1000家。同时,阿尔迪还在北美收购了那些被
沃尔玛挤兑而破产的零售商。
  尽管年销售额达2000亿欧元的美国"沃尔玛"公司,销售额是阿尔迪的6倍,但阿尔迪每
年经销的单件商品的总价值却超过4000万欧元,竟是沃尔玛的30倍。因阿尔迪只销售不超过
1000种商品,比沃尔玛少15万种。
  德国人给阿尔迪起了一个通俗的名字——"穷人店"。二战后,阿尔布莱希特兄弟从盟
军战俘营回到家乡,开办了一家食品零售店。因为当时人们只想用最低的价格购买生活必需
品,所以兄弟俩把价格定得很低。他们说:"我们的业务发展基础只有一个:最低的价格!
"
  阿尔迪能从一个三流小店发展成为世界上最成功的零售商,人们曾有无数个猜想,认为
它一定有非常机密的营销方案,而且也会把它严严实实地隐藏起来。但出乎人们意料,它的
制胜法宝只有两个字:"简单"!就是"简单"这两个字,令许多企业始终无法模仿。
  它简单到什么程度,从以下几个方面就可以看出:
  不做广告
  阿尔迪所有的商场,只有每周一期八开的《阿尔迪信息报》放在超市入口,对下周的新
上柜货品作个介绍,由顾客随意自取浏览,便于顾客按照自己的意愿选择喜欢的商品。除此
之外,绝不做其他任何形式的商品宣传。
  商品单调
  商场里只放着简单的600~700种商品。货品装在纸箱里堆在光秃秃的货架板上,价目表悬
在头顶,而不是贴在商品包装上;瓶装芦笋和沙丁鱼罐头挤破了纸箱,手纸只有两种牌子,
腌菜只有一种,每种商品只提供一种选择,即同类商品之中最好的品牌,每一种商品都只有
一种规格的包装。商品都是能够迅速带出店铺的,包括罐头食品、纸袋包装食品、快餐食品
、一些新鲜果蔬和冰冻食品等。除少量日用品、食品设有货架、冷柜外,其他商品均由店员
打开纸箱包装,任顾客自取。
  员工人数少
  每一家阿尔迪超市的雇员都少于10名,他们都身兼数职。商场里没有现代化超市设备,
没有使用条形码扫描仪和读卡机等现代化设备,坚持使用最简单的收款机,而且只收现金。
没有人员为顾客提供装袋的服务,店员对商品价格倒背如流,他们心算和录入速度令人惊叹
,整个顾客交款的过程非常快捷。
 不收尾数钱
  在阿尔迪,商品价格的尾数都是0或5。他们开始时经过测试,发现营业员找零钱的时间
会影响销售,如果将找零钱的时间去掉,可以减少营业员数量,又可以多卖出为数不少的商
品。于是阿尔迪决定,尾数0.05~0.09马克的商品,按0.05马克收款;而尾数0~0.04马克的
商品,按0收款。这样做,既提高了商店员工的工作效率,又降价吸引了更多的顾客。
  
  不举债经营
  阿尔迪从不举债经营,扩张都是用已产生的利润来进行,因此风险很低。曾是阿尔迪的
管理人员迪特?布兰德斯说:"阿尔迪的一个原则是:不仓促展开业务,而是先打好牢固的基
础。基础一旦有了,它会行动得很快。"
  员工执行力强
  阿尔迪的用人原则是能力+高薪,非常注重员工队伍的精干和年轻化。与其他零售企业相
比,阿尔迪的薪水要高出10%~20%。工作出色的员工有很多升迁机会,升任超市经理的即
配给公车,升任部门主任的年薪可达到20万马克。因此,阿尔迪吸引了大批年轻的优秀人才
加盟。
  有人这样形象地总结了阿尔迪成功的秘诀:只放一只羊!因为,无数个想放一群羊的人
,到了最后,却一只羊也没剩下,原因就是他们被无尽的贪欲挤垮,而最后失掉了一群羊。
所以,不管你做什么工作,在做事前,还是先衡量一下自己的能力,看看你到底适合放几只
羊?

货币政策奠定中长期底部——金学伟

在硬通货时代,每隔一段时间就会发生一次经济衰退和萧条。那是真正的衰退,不是今天我们通常所说的经济增长率下降,而是国民生产总值实实在在的减少。这种由国民生产总值周期性的正增长和负增长交替的经济波动,被称为古典式波动。与此相反,近几十年来的经济波动主要体现为增长率的高低起伏,由此产生的波动称为增长型波动。
产生古典式波动的原因很多。其中最主要的原因之一出在货币供应量上。货币作为商品价值尺度、财富储存手段、商品流通媒介与支付手段,它的总量必需和经济总量相匹配:有多大的经济总量就需要有多大的货币总量,否则整个经济运行就会失序,正常的循环就会中断。而在硬通货时代,货币就是金、银、铜,它的增长受到矿山开采、冶炼等生产环节的制约,这些环节的年均增长率决定了货币的年均增长率。当经济的发展过于迅猛,或货币生产的环节出现梗阻时,整个社会就会产生钱不够的问题,正常的商品流通与循环也就无法进行下去。最终的结果只能是经济总量降下来,以适应货币总量。
我国北宋年间曾发生过两次经济危机,其原因都在货币短缺。北宋时曾短暂出现过的"交子"——世界上最早的纸币形式,就是应这一需要产生的。明朝末年张献忠窜入四川,建立大西国。这个农民天真地以为有了银子就有一切,把整个大西国的银子搜刮一空,使四川经济陷入万劫不复的深渊,最后连张献忠本人想举办一次"国宴",也空有一大堆银子,却买不到所需的肉。清朝的康熙、雍正年间也发生过一次钱不够的问题,不过当时缺的主要是铜钱,国家拿不出那么多铜来铸造铜钱,以满足商品流通的需要。为此朝廷争论了好多年,直到雍正上台,这位务实皇帝拍板:不怕人家说大清朝铜钱不纯,不要担心因此损害大清朝面子,以60%的铜加40%的锡铸成铜钱,才解决了这个问题。
在纸币时代,上述问题已不存在,只要需要,货币可随时印刷。但由此产生的新的问题就是货币发行量的过剩,以及由此带来的长期通货膨胀。当今世界,一年的通胀率也许就超过了以往100年。
通胀发生于现在,它的根源却在过去。以我国为例,从1986年到2006年的20年间,我国GDP总量的年均复合增长率为16.26%,而货币供应量(M2)的年均复合增长率为22.84%。如果说,经济总量增长1%,货币总量也增长1%属于正常所需,那么,这一数字表明在过去20年里,我国货币供应量平均每年要超过正常所需6.58个百分点。如以近10年来看,则从1996年到2006年,GDP的年均增长率为11.39%,而货币总量的年均增长率为16.72%,平均每年超过正常所需5.33个百分点。当今的通货膨胀实际上就是长期积累的货币超量发行结果。2002年,笔者曾发表文章,针对当时众多经济学家要求政府加大货币发行量,以解决所谓退货紧缩问题,根据货币总量和经济总量以及流通中现金的运行态势预测:从2003年起,我国就将进入新一轮通胀,在此之前,任何加大货币发行量的建议,都会加剧日后治理通胀的难度。当前的通胀,实际上就是过去10多年间超量发行货币的总爆发或集中体现。这样的通胀,任何一个国家和政府都无法从根本上消除它,因为时间不能倒退,我们无法回到过去再重新来过。只有当社会经济总量、资产总量与货币总量在新的物价基础上达到新的平衡,通胀才能基本消除。在此之前,唯一的办法就是通过一定手段,延长平衡的时间,以放慢通胀速度,也就是以延长通胀时间的方法,来防止因平衡速度过快而导致恶性通胀的出现。如果我们不能清楚地认识到这一点,如果把控制通胀提到太高的高度,如果为反通胀而过度收缩银根,以致货币发行量不能和现有的经济总量相匹配,满足不了经济运转的需要,那么很可能会出现通胀没有下去,而GDP总量却下去了,最终反而导致通胀率的居高不下,甚至猛升。
笔者以为,近两年我国央行的货币政策已出现了相关苗头:2007年,我国名义GDP总量增长了17.76%,而当年货币供应量只增长了16.9%;今年上半年,名义GDP的同比增长率为22.33%,货币供应量的同比增长率只有17.4%。货币供应量的增长率已经连续1年半低于经济总量的增长率。这样的货币政策已无法维持下去。
 如果说在硬通货时代,经济总量的周期性下降是不可避免的;那么,在纸币时代,周期性的通货膨胀同样也是不可避免的,能够避免的只有恶性通胀以及经济总量的衰退。如果说在硬通货时代,通胀比衰退更可怕,因为通胀会加剧衰退;那么在纸币时代,衰退比通胀更可怕,因为衰退可加剧通胀。这已被越来越多的人所认识。
( 作者为上海智晟投资管理有限公司首席经济顾问)

办公族五个坏习惯让身体长石头

肾结石一跃成为全民最为关注的疾病之一。但是要预防结石病,仅仅关注奶粉或者牛奶的食用安全远远不够,而需要被关怀的也绝不仅止于婴幼儿群体。相关资料显示,近年来结石的发病率逐年升高,发病群体涵盖所有年龄层,并有年轻化的趋势,其中办公室白领占据相当大的比例。
  结石为何盯上办公族?有关专家指出,这与办公族工作繁忙、工作节奏紧张等客观因素有关,更与其不良的生活习惯紧密相连,其中五个坏习惯,是致病的罪魁祸首。
  不吃早餐
  不吃早餐的办公族不在少数,有的是因为早上赶着上班,来不及吃,有的是为了减肥,不愿意吃。这一看似寻常的生活习惯却是导致结石病的重要原因。据健康863网的保健专家介绍,不吃早餐诱发结石病的几率相当大。这是因为人体在经过夜晚的长时间睡眠后,需要在早晨摄入食物来补充能量,胆作为消化系统的一部分,会在早上分泌胆汁,做好消化食物的准备。人如果不吃早餐,胆就没有食物可消化,胆汁就会长时间停留在胆囊,长此以往,胆汁会淤积在胆囊或肠道,胆固醇自胆汁中析出就易形成结石。
  防石计:不要给自己任何借口不吃早餐。吃早餐耽搁不了太多时间,也不会让你长胖。即使是简单的喝点牛奶、吃片面包,也能起到预防作用。
  不爱喝水
  不少办公族因为工作节奏快,喝水的时间相应较少,还有为数不少的人即使有时间喝水,量也不够大,而这正是诱发结石病的另一重要原因。专家表示,喝水少会减少人体尿液,并会使尿液过度浓缩,尿中盐类的浓度增高,沉淀增多,就容易形成肾结石或尿路结石。
  防石计:多喝水可以增加排尿量,稀释尿液,降低尿内晶体浓度,冲洗尿路,有利于预防结石形成及促使结石排出,所以即便不口渴,个人每天也应喝水2000毫升以上,并最好选择清水。
  不喜欢运动
  运动量少也会导致结石的产生。而办公族的工作性质注定了坐的时间非常长,运动的机会少,下班后很多人也不爱运动。专家指出,人如果很少运动,一方面不利于钙质吸收,会增加尿液中的钙盐成分,产生肾结石或尿路结石;另一方面人体腹壁会松弛,引致内脏下垂,压迫胆管,使胆汁排泄不畅而淤积,从而形成胆结石。

  防石计:加强运动,不要"坐等"结石的形成。在办公室工作两个小时左右,就应站起来做些简单的放松运动,业余也应保证一定的运动量,每天的运动时间应在30分钟以上。
  吃得太油
  办公族因为工作繁忙,应酬较多等原因,在外就餐的机会较多,吃大鱼大肉的频率较高,并容易暴饮暴食,尤其是男性,往往吃得过于油腻,而这正是结石病的重要诱因。因为高脂肪、高蛋白食物会增高胆汁中的胆固醇含量,形成结石;动物内脏、肉类代谢也会产生尿酸,导致结石。
  防石计:管住嘴,限制食物中胆固醇的含量,少吃或忌吃富含胆固醇的食物,如肥肉、动物内脏、鱼籽、蟹黄、蛋黄等。多吃新鲜瓜果和蔬菜以及大蒜、洋葱、香菇、黑木耳等具有降低胆固醇作用的保护性食物。
  吃得太素
  吃得太油腻容易得结石,吃得太素同样容易长石头。办公室MM大多热衷减肥,不少人信奉素食主义,以蔬菜为主食。专家提醒,虽然蔬菜富含维生素、矿物质和膳食纤维,但是,菠菜、芹菜、番茄、竹笋等蔬菜中同时还富含草酸,过量食用可能从尿中析出而形成结石,其与豆制品或者钙片中的钙结合后,也容易形成结石。
  防石计:含草酸盐较多的蔬菜在吃之前应先焯一下,然后再过一遍水,以减少草酸摄入量;可多吃碱性蔬菜和苹果,综合酸碱度;宜适量摄入高脂肪、高蛋白食物,均衡饮食结构,减小结石风险。

2009年6月27日星期六

sh一在建楼盘轰然倒塌

事情发生在早上5:40分左右。

行人车辆请注意,飞机就要开过来了!

请在拦木外等候,不要抢行,不要翻栏杆!

Linux代码淬火工具

介绍用来提高Linux应用程序安全性和可靠性的开源工具和代码追踪技术。
一、源代码检查工具
在软件开发过程中,我们可以利用源码检查工具来找出常见的编程错误以及安全漏洞。这些工具用起来并不复杂,下面介绍splint和flawfinder这两款源码检查工具的使用方法。
splint是一款静态源代码检查工具,能对源代码进行全面的分析。对于没有注释的源代码,可以使用-weak选项:
splint -weak *.c -I./inc
其中,./inc是头文件所在的子目录。此外,Splint还支持标准检查模式(选项-standard),若要进行中等强度检查则使用选项-checks,若使用选项-strict则进行最严格的检查。
flawfinder也是一款用来寻找源代码错误的静态分析工具。通过该工具提供错误消息,开发人员可以更快的找到错误所在。请看下面的例子:
$ flawfinder test.c
test.c:11: [2] (buffer) char:
Statically-sized arrays can be overflowed. Perform bounds
checking, use functions that limit length, or ensure that
the size is larger than the maximum possible length.
$
本例中,flawfinder给出了一个提示,指出静态尺寸的数组可能被恶意利用的潜在危险。
除了上面介绍的splint和flawfinder这两款工具外,还有RATS(一款安全审计工具)以及ITS4(静态漏洞扫描工具)等工具可用。但需要
注意的是,虽然这些工具能够分担一部分工作,但却无法完全替代人类。因为工具在发现漏洞的同时,也可能遗漏安全漏洞。

二、代码跟踪技术
我们知道,strace工具通常是用来追踪系统调用的,实际上,它还可以作为间接的源代码审计工具。从系统调用的角度来跟踪应用程序的执行,可以让我们了解到Linux应用程序的底层操作,借助这些低层操作我们可以更好的理解我们的源代码。
在下面的例子中,有多处违反了我们前面讨论的代码淬火原则,现在我们展示如何利用strace来进行调试。
#include <unistd.h>
#include <fcntl.h>
#define MAX_BUF 128
int main()
{
int fd;
char buf[MAX_BUF+1];
fd = open( "myfile.txt", O_RDONLY );
read( fd, buf, MAX_BUF );
printf( "read %s\n", buf );
close( fd );
}
我们注意到,上面的代码的第11行,即:fd = open( "myfile.txt", O_RDONLY
);
试图打开一个称为myfile.txt的文件,但事前并没有检查该文件是否业已存在。在这种情况下执行该程序的话,会导致无法预测的结果:
$ gcc -o bad bad.c
$ ./bad
read @?8Z@
$
看看,这样的结果是你没料到的吧。所以,先让我们利用strace来看看到底发生了什么。注意,下面的输出已经作了删减,但重要的信息都保留下来了:
$ strace ./bad
execve("./bad", ["./bad"], [/* 20 vars */]) = 0
uname({sys="Linux", node="camus", ...}) = 0
...
open("myfile.txt", O_RDONLY) = -1 ENOENT ( No such file or
directory)
read(-1, 0xbfffef20, 128) = -1 EBADF (Bad file descriptor)
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0x40017000
write(1, "read \300\357\377\2778Z\1@\n", 14read /à???8z@
) = 14
close(-1) = -1 EBADF (Bad file descriptor)
munmap(0x40017000, 4096) = 0
exit_group(-1) = ?
$
执行程序后,我们看到用来启动该程序的系统调用是execve();不久又调用了open(),该系统调用对应于代码中的第11行。并且我们看到系统调用
open()的右边的返回值是-1,并指出错误"ENOENT ( No such file or
directory)",即不存在这个文件或目录。换句话说,这是在告诉我们需要先建立文件。此外,系统调用read()也以失败而告终,它的错误是非法
的文件描述符,因为open调用失败了。
strace工具不仅用来帮助理解有源代码的程序的行为,而且也对于没有源代码的程序也同样有效。因为,透过对系统调用的观察,我们能够在二进制级别来理解程序的行为。

三、小结
古人云,工欲善其事,必先利其器。借助于上文介绍的代码淬火方面的编码知识,用来提高Linux应用程序安全性和可靠性的调试工具,相信读者能够更快更好开发出安全可靠的高品质软件来。

编程利器——splint工具

到底需不需要编译器之外的独立的静态代码检查工具呢?这个问题'仁者见仁,智者见智'。但是有一个结论我想大家都会认可,那就是越是在开发周期早期发现的
Bug,修复它所付出的代价就越小。而像lint这样的静态代码检查程序恰恰是让Bug在早期阶段'显露原型'的绝佳工具,而追求'lint-
clean'[注1]境界的代码也向来是专家级程序员的嗜好。别忘了在'C专家编程'一书中曾经提到Sun
OS的内核一直是保持'lint-clean'状态的,这就是榜样!还等什么?赶快学呀!^_^

有人抱怨'不敢用lint工具,
太多的Warnings把快屏幕都淹没了!',不过高手一般不这么想,他会细心琢磨这些Warnings背后的'暗示',并和lint工具沟通,利用
lint工具提供的交互方法屏蔽掉一些经过分析认为不能成为错误的Warnings。久而久之,高手本身就成了一个lint程序,就能够很快的用肉眼发现
代码中的问题,并指出问题所在,如何解决!他还能告知如何嵌入一些Annotations从而避免让lint程序产生不必要的Warnings,这时这位
高手对语言和程序的理解就又提高了一个档次了。其实使用ling工具不仅仅是为了提早发现程序中的Bug,其使用过程有助于你加深对程序的认识和理解。的
确事实就是这样。

Splint就是一款强大而且应用广泛的开源lint工具。它的强大的代码检查能力固
然让人称道,但是让我更欣赏的却是它提供的'Annotations'机制。
Splint可以让程序员在自己的代码中嵌入相应的Anotations,这些Anotations作为Splint分析代码时的输入以帮助Splint
产生对程序员更有用的信息。下面是一些Splint的使用入门,更多详细信息请查看'Splint
manual'。

1、最简单的Splint使用方法
>> splint *.c

2、Splint输出Warnings的基本格式
<file>:<line>[,<column>]: message
[hint]
<file>:<line>,<column>: extra location information, if appropriate
我们可以使用'+/-<flags>'来自定义其输出格式,如'splint -showcol
*c',则Splint不会在输出信息中显示'列'信息。

3、使用flags控制splint的检查范围和输出格式
'+<flag>' -- 表明某个flag处于打开状态,如'+unixlib';
'-<flag>' -- 表明某个flag处于关闭状态,如'-weak';

4、使用.splintrc环境文件
如果不想每次使用splint的时候都手工输入一堆'+/-<flags>',那么你可以把这些'+/-<flags>'预先写
到.splintrc文件中,当splint执行的时候它会自动加上这些flags的。默认的flags设置在'~/splintrc'文件中,但是如果
一旦splint的当前工作路径下也有.splintrc文件,那么这个.splintrc文件中的flag设置会覆盖'~/splintrc'中的
flags设置,但是命令行中的flags设置是具备最高优先级的,它会覆盖前面提到的任何一个文件中的flags设置。

5、使用Annotations
对于'Annotations'的作用,Java程序员并不陌生,但是C程序员则对这个不是那么了解。C代码中的Annotations用来指导Splint生成恰当的代码检查报告。下面这个例子对比使用和不使用Annotations,Splint的输出的差别:
/* testlint.c */
void foo1() {
/*@unused@*/int *p = NULL;
}

void foo2() {
int *p = NULL;
}

splint testlint.c
Splint 3.1.1 --- 28 Apr 2003

testlint.c: (in function foo2)
testlint.c:6:7: Variable p declared but not used
A variable is declared but never used. Use /*@unused@*/ in front of
declaration to suppress message. (Use -varuse to inhibit warning)

Finished checking --- 1 code warning

可以看出没使用Annotation的函数foo2被给出Warning了。Splint的Annotations繁多,我们在平时做lint时可以多多接触。

'早用lint,勤用lint',这是C专家给我们的建议。'lint-clean'也许离你并不遥远。

[注1]
'lint-clean' -- 程序能够顺利通过lint程序的检查。

2009年6月25日星期四

Socket send函数和recv函数详解

1.send 函数
int send( SOCKET s, const char FAR *buf, int len, int flags );
不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。
该函数的第一个参数指定发送端套接字描述符;
第二个参数指明一个存放应用程序要发送数据的缓冲区;
第三个参数指明实际要发送的数据的字节数;
第四个参数一般置0。
这里只描述同步Socket的send函数的执行流程。当调用该函数时,
(1)send先比较待发送数据的长度len和套接字s的发送缓冲的长度,
如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;
(2)如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么send就比较s的发送缓冲区的剩余空间和len
(3)如果len大于剩余空间大小,send就一直等待协议把s的发送缓冲中的数据发送完
(4)如果len小于剩余
空间大小,send就仅仅把buf中的数据copy到剩余空间里(注意并不是send把s的发送缓冲中的数据传到连接的另一端的,而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里)。
如果send函数copy数据成功,就返回实际copy的字节数,如果send在copy数据时出现错误,那么send就返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话,那么send函数也返回SOCKET_ERROR。
要注意send函数把buf中的数据成功copy到s的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。如果协议在后续的传送过程中出现网络错误的话,那么下一个Socket函数就会返回SOCKET_ERROR。(每一个除send外的Socket函数在执
行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,如果在等待时出现网络错误,那么该Socket函数就返回
SOCKET_ERROR)
注意:在Unix系统下,如果send在等待协议传送数据时网络断开的话,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。
通过测试发现,异步socket的send函数在网络刚刚断开时还能发送返回相应的字节数,同时使用select检测也是可写的,但是过几秒钟之后,再send就会出错了,返回-1。select也不能检测出可写了。
2. recv函数
int recv( SOCKET s, char FAR *buf, int len, int flags);
不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。该函数的第一个参数指定接收端套接字描述符;
第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
第三个参数指明buf的长度;
第四个参数一般置0。
这里只描述同步Socket的recv函数的执行流程。当应用程序调用recv函数时,
(1)recv先等待s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR,
(2)如果s的发送缓冲中没有数据或者数据被协议成功发送完毕后,recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据,那么recv就一直等待,直到协议把数据接收完毕。当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以
在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的),
recv函数返回其实际copy的字节数。如果recv在copy时出错,那么它返回SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0。
注意:在Unix系统下,如果recv函数在等待协议接收数据时网络断开了,那么调用recv的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。

VIM显示十六进制出错

在linux下用vim打开jpg文件,使用%!xxd进行16进制显示时,文件头显示为"3f3f
3f3f 0011 0804"文件尾端显示为 "3f3f
0a";而同样的操作在windows下,就显示为"ffd8 ffc0 0011 0804"和 "ffd9
0a",这才是正确的jpeg文件头和文件尾标志。
很蹊跷 !
初时,我以为是jpeg在windows和linux下是不同的文件头,后来把jpg后缀去掉,就一个纯文件,现象依旧。考虑可能不是操作系统的差异了。
重新使用ghex打开jpeg数据查看,发现显示正常,为"ffd8 ffc0 0011
0804"和 "ffd9 0a",正确。
估计应该是vim的问题了。
3f的ascii码是?,那表示vim对文件头、尾没有正常解析,是不是和vim解析文件时用的编码格式有关系呢?
打开.vimrc配置项,屏蔽掉下面这句话:
set fileencodings=utf-8,gb2312,gbk,gb18030,ucs-bom
再用vim打开jpeg文件,显示"ffd8 ffc0 0011 0804"和 "ffd9 0a",
显示正确。
原来,为了支持识别和显示中文,我规定了vim的fileencodings,
当vim打开文件时,会使用规定的编码格式对数据进行解析,可惜jpeg的文件头FFD8、尾FFD9
不是任何一个中文的编码,vim找不到对应的中文字,就显示为??,即:3f3f。
至此,困惑全部打开。

2009年6月24日星期三

一个农夫给世界带来的变化

福莱明,一个很平常、还十分穷苦的苏格兰农夫。
有一天,正在地里干活的他,忽然听到附近的泥沼里有人发出求救的哭喊声。他赶紧放下手中的家什,飞跑着来到泥沼边――天哪!是一个小孩掉进了粪池里。于是,福莱明镇定、迅速地采取措施,立即把这个小孩从死亡边缘给救了回来。
第二天上午,有一辆崭新的、颇是气派的马车停在农夫家门口,从车中走出一位优雅的绅士。他进了农夫的茅屋,首先自我介绍是那个被救小孩的父亲,然后很诚恳地对农夫说:"此刻,我不知该和您说什么,我真的非常感谢您……您救了我孩子的生命,我一定得报答您!"农夫憨厚地笑着说:"不!先生。我不能因为救了您的小孩而接受报答。"
就在这时,农夫的儿子从外面走进屋来,绅士朝农夫问道:"那是您的儿子吗?"农夫显得很自豪地说:"是!他是我的儿子。"绅士沉思一会,继而严肃地对农夫说:"我们签定个协议,让我带他走,我要让他接受良好的教育。假如这孩子能象他父亲一样,我相信,他将来一定会成为一个更令您感骄傲的人。"农夫这次毫不犹豫地答应了。
就是这个农夫的孩子,后来从圣玛利亚医学院毕业,并成为举世闻名的福莱明・亚历山大爵士――盘尼西林的发明者。他在1944年受封骑士爵位,并在同年荣获诺贝尔奖。
几年后,那个绅士的儿子染上肺炎,是谁救活了他?盘尼西林。那绅士是谁?上议院议员丘吉尔。绅士的儿子是谁?英国最伟大的政治家――丘吉尔。
一个小小农夫的不算太大的善良举措,竟然给世界带来如此重大的变化,真是善莫大焉。

巴菲特:通胀时期该如何投资

  本文首次于1977 年5 月发表于《财富》杂志,在目前环境中,随着人们对未来通胀预期的升温,重读此文,重温巴菲特思想的火花,相信当代投资者仍将能从中受益。
  巴菲特认为,就经济本质而言,股票和债券事实上非常相似,股票不过是穿着股票的外衣来到华尔街化装舞会的"股本债券"。由于股票的本质与债券非常相似,股票受通胀的影响也非常大。通胀转移富裕股东的收入来改善工人福利的潜力并不大。要想产生更多的经济福利,就需要大幅增加实际资本,并且投资在现代生产设施中。此外,通胀影响实际资本积累,部分企业派息后业务扩张资金所剩无几,企业在派息与增发新股之间游戏,最终受伤的还是投资者。通胀对企业回报率的影响有普遍性,但需要大量有形资产支出来维持经营的企业往往会受通胀伤害较大;需要较少有形资产支出的企业受伤害程度较小;经济商誉高的企业受到的伤害也较小……
  股票和债券类似,在通胀的环境中表现不佳,这早已不是什么秘密。过去十年中(六七十年代),我们大多数时间都处在通胀环境中,对股票而言,这也是一个困难重重的时期。
  但是,人们对这段时期内股市问题原因的认识尚不够充分。通胀时期债券持有人面临的问题并不难理解。当美元价值逐月恶化,以美元计算收益和本金的证券将不会成为大赢家。
  人们长期以来认为股票与债券不同。许多年来,人们普遍认为股票可以对冲通胀风险。产生这一认识的根源是,股票代表的不是债权,而是具有生产设施的公司的所有权。投资者认为,不管政府如何印钱,公司的生产设施将能保留其实际价值。
  但是,为何事与愿违呢?我认为主要原因是,就经济本质而言,股票和债券事实上非常相似。
  我知道,对许多投资者而言,这一观点听起来有些奇怪,他们会迅速反驳道,债券的回报是固定的,股权投资的回报率每年起伏较大。但是,如果仔细考察公司在二战后的总回报,你会发现一个惊人的现象:股权回报率事实上变化不大。
  股票的息票是固定的
  二战后第一个十年中(1946-1955),道琼斯工业指数平均每年回报率为12.8%。接下来的十年中,这一数字是10.1%。其后的十年中,回报率为10.9%。但是,多年总体而言,账面价值回报率趋向于12%。在通胀年份里,没有迹象显示回报率大幅超过这一水平,在物价稳定的年份里也同样如此。现在,我们把这些公司看作生产企业,而非上市股票。假设企业的所有者按净值购买股票。那么,他们自己的回报也将是大约12%。因为这一回报率前后一致性相当高,我们可以合理地将它假设为"股本息票"。
  当然,在现实世界里,股票投资者不单单是买入并长期持有。相反,投资者为了在所投资公司的利润分配中分得更大一杯羹,相互之间争勇斗智。很明显,整体而言,这种纷纷扰扰徒劳无功,对股本息票无任何影响,只不过是降低了投资者应当分得的部分,因为频繁交易产生大量的摩擦成本,如咨询费、经纪佣金。活跃期权市场的存在导致摩擦成本进一步上升,这一赌场般的市场丝毫不能提高美国企业的生产率,但却需要数千人在此劳作。
  股票是永久性的
  另一个事实是,现实世界中股票投资者通常不是以账面价值买入股票的。有时他们能够以低于账面价值的价格购买,不过大多数时候买入价高于账面价值,这种情况发生时,12%的回报率面临的压力就更大了。随着通胀率上升,股本资本的回报并未上升。从本质上讲,买入股票得到的是具有内在固定回报率的证券,这和买入债券是一样的。
  当然,债券和股票的形式有重大差别。首先,债券终将到期,也许投资者需要长期等待,但是最终投资者将能够重新协定合约条款。如果目前或预期通胀率使得他过去的息票不足,他可以拒绝进一步游戏,除非现在供应的息票能重新激起他的兴趣。类似情形最近几年时有发生。
  但是,股票是永久性的。股票的到期日无限远。股票投资者锁定了美国企业所能挣得的收益,不管有多少。如果美国企业的回报率注定是12%,那么投资者必须接受这一回报率。股票投资者整体而言既不能退出,也不能重新商议契约条款。个别公司可能被出售或清算,公司可能回购股份。不过,总体而言,新股发行以及留存收益确保公司系统中的股本资本将增加。
  所以,我们给债券形式打一分。债券息票最终将被重新商议,股本"息票"不能。当然,我们要承认,长期来看回报率为12%的息票似乎并不需要大量修改。
  穿"股本债券"外衣的股票
  我们的股票不过是穿着股票的外衣来到华尔街化装舞会的"股本债券"(equity bond)。
  普通债券和上述回报率为12%的"股本债券"之间还有另外一个重大差别。通常情况下,债券投资人以现金形式收到全部息票,可以自由地进行再投资。相比之下,股票投资者的股本息票部分被公司留存,其再投资的回报率只能是公司的回报率。换句话说,公司每年12%的回报率部分派息,剩余部分被投资到公司中,再产生12%的回报率。
  高通胀、高利率时代――股票风光不再、投资者纷纷退出
  回过头来看,1946-1966 年间的投资者可以认为自己着实分得了满满的三大杯羹。第一,他们受益于当时远高于利率的公司股本回报率。第二,公司将股本回报的一大部分进行再投资并获得高回报率,通过其他途径是很难获得这么高的回报率的。第三,随着人们普遍认识到前两个优势,股票投资者还受益于股本资本的升值。这一点意味着,除了最基本的大约12%的公司股本资本回报外,投资者还获得了红利,这部分红利来自于道指的市净率从1946年的1.33 倍涨到1966 年的2.20 倍所带来的收益。估值上升的过程中,投资者暂时获得了超过其所投资企业内在盈利能力的回报率。
  到60 年代中期,大型投资机构终于发现了这一投资的"人间天堂"。但是,就在这些金融巨头开始争相买入股票时,我们进入了通胀加速上升、利率升高的年代。估值上升的过程开始反转,这一点也相当符合逻辑。利率上涨无情地降低了所有现有固定息票投资标的的价值。随着长期公司债券利率开始上升(最终升至10%左右),股票的12%股本回报率和再投资特权都显得黯然失色。
  人们认为股票比债券风险大,这一点无可厚非。虽然股本息票长期来看大致固定,但每年的确有波动。投资者对未来的态度受每年波动的影响相当大,虽然这种影响经常是错误的。股票风险大的另外一个因素是它们的到期日无限长。由于这层额外风险,投资者自然的反应是期望股本回报稳稳高于债券回报,比如说,如果债券的回报为10%,那么同一类型公司发行的股票12%的股本回报率就不能算作"稳稳"。随着差价缩减,股票投资者开始寻求退出。
  但是,股票投资者作为一个整体不能退出。他们所能做的是大量换手,产生大量摩擦成本,随后估值水平大幅下降,因为12%的股本息票在通胀环境中吸引力下降。过去10 年中,债券投资者经历了一系列的冲击,在这一过程中,他们发现任何息票水平――不管是6%、8%或10%――都并非是注定的,债券的价格也是会崩溃的。大部分股票投资者没有认识到他们也有一个"息票",对此,他们现在还处于认识过程中。
  企业提高赢利的五种方法在通胀环境中难以凑效
  我们是否必须认为12%的股本息票是一成不变的呢?是否有什么规律说公司的股本资本回报率在通胀率持续攀升的环境中不能向上调整呢?
  当然没有这样的规律。不过,另一方面,美国也不能随心所欲或通过制定法律来提高公司赢利。要提高股本回报,公司需要至少做到以下一点:(1)提高周转率,即销量与企业使用总资产的比率;(2)使用更便宜的杠杆;(3)使用更多杠杆;(4)降低所得税;(5)增加经营利润率。
  除了以上这些,增加普通股回报率恐怕别无他法。这些方法在通胀时期究竟能不能提高公司的股本资本回报率呢?下面我们将仔细阐述。
  第一,提高周转率。关于此,我们需要考虑三个主要资产类别:应收账款、存货、固定资产。
  应收账款增长与销量成比例增长,不管销售额增长是靠销量增长、还是靠价格上涨驱动。这一点没有提高空间。
  至于存货,情况就没这么简单了。长期来看,单位存货的趋势追随单位销量的趋势。但是,短期内,存货周转率可能因预期成本或瓶颈等因素的影响而上下波动。
  使用"后进先出"的存货估值方法在通胀时期有利于提高报告的周转率。当销售额因通胀而上升时,使用"后进先出"存货估值方法的公司的存货水平要么维持不变,要么跟随销量增长。但无论如何,金额周转率上升。
  20 世纪70 年代早期,公司使用"后进先出"的会计方法的潮流兴起,其结果是降低了公司报告的收益和应缴税额。这一趋势目前似乎放缓。然而,许多使用"后进先出"会计方法公司的存在以及其他公司跟随潮流的可能性将导致公司报告库存周转率进一步上升。
  通胀带来周转率上涨的幅度不大
  就固定资产而言,通胀率只要上升,其首先的结果便是提高周转率。这是因为销量会立即反映新的价格水平,而固定资产账上只能缓慢反映变化,也就是说,随着现有资产退役并且以新价格重置时,才能反映变化。很明显,公司的重置过程越缓慢,周转率上涨越多。但是,当公司的重置周期完成后,周转率将不再因此上涨。假设通胀率稳定,销量和固定资产将开始与通胀率等速一起上涨。
  总的来说,通胀能带来周转率一定程度的上升。其中一部分上升是肯定的,因为使用"后进先出"的会计方法;如果通胀加速,另一部分上升是可能的,因为销量上升快于固定资产上升。但是,通胀带来周转率的上升是有限的,其幅度不足以导致股本资本回报率的大幅上升。
  那么,使用便宜的杠杆是否能带来股本资本回报率增加呢?不大可能。高通胀率通常导致借贷成本增加,而非减少。通胀率飚升导致资本需求飚升,由于出借人对长期贷款合同的担忧日渐加深,贷款条件也越来越苛刻。但是,即使利率不会进一步上升,杠杆也会变得更贵,因为公司账面上债务的平均成本小于替代成本。现有债务到期后,需要被替代。整体而言,杠杆成本未来的变化对股本回报可能产生轻微的抑制作用。
  出借人是否愿意大量放贷?
  在通胀引起融资需求方面,具有讽刺意味的是,利润率高的公司需要相对较少的债务资本;但是利润率低的公司对举债似乎欲壑难填。出借人现在对这一问题的认识比以前清楚多了,因此也不大愿意出借资金给那些资本需求大、利润率低的公司让他们大幅增加杠杆。
  然而,在通胀环境中,许多公司未来似乎定会通过增加杠杆来提高股本回报率。管理层会这样做,因为他们需要大量的资本,他们希望不需削减派息或发行新股便能够获得大量资本,因为在通胀环境下发新股的吸引力并不大。因此,他们自然的反应便是不计成本地大举借债。
  但是,以目前利率增加贷款对提升股本回报率的作用与60 年代早期利率为4%的贷款所起的作用相去甚远。更糟糕的是,负债率上升还会导致信贷评级被下调,导致利率成本进一步上升。
  因此,除了前文所阐述的,上述原因也会导致杠杆成本上升。总的来说,杠杆成本上升的弊处可能抵消杠杆增加的益处。
  此外,美国公司系统的债务远高于传统资产负债表上显示的水平。许多公司有巨大的养老金义务,其数量与公司现任员工退休时的工资水平相挂钩。在1955-1965 年间低利率环境中,来自这些养老金计划的债务是可以合理预测的。如今,没有人能说得清楚公司最终义务有多少。
  当然,公司每年报表上都有一项关于未履行的养老金债务的精确数据。如果这一数据真实可靠,那么公司可以预先支付这一数目的金额,将其加入现有的养老金资产,将养老金资产全部交给一家保险公司,让它来承担公司现在所有的养老金债务。唉,可惜在现实世界里恐怕根本找不到一家愿意听一听这笔交易的保险公司。
  美国几乎每家公司的会计想到发行"生活费用"债券时都会忍不住要退缩。但是,通过由私营领域负担养老金的制度,美国的公司事实上已经背负起等同于该债券的数量惊人的债务。
  股东应当带着挑剔的眼光看待杠杆的增加,不管是传统债务,还是不入账的与物价挂钩的"养老金债务"。企业在不负债的情况下获得12%的回报率要远远好于债台高筑的企业获得同样的回报率。这意味着,如今公司12%的股本回报的价值要远低于20 年前12%的回报率的价值。
  降低所得税不大可行
  降低公司所得税似乎也不大可能提高股本资本回报率。美国公司的投资者所持有的股票只能算作D 类,A、B、C 类分别被联邦政府、州政府和市政府持有,代表的是他们征收所得税的权利。虽然这些"投资者"不会占有公司资产,但是他们在公司收益中分得一大部分,包括留存收益导致股本增加所产生的收益,留存收益本该归属D 类股东。
  这些A、B、C 类股票的另一迷人特点是,只要任何一类"股东"进行单边投票,那么他们在公司收益中占有的份额将会立即大幅增加,而且不需付款,比如,对A 类股票持有人(联邦政府)而言,只要国会采取行动即可。更有趣的是,有时其中一类股票持有人会投票追溯提高其占有企业的份额,纽约的公司1975 年就很沮丧地发现了这种情况。每当A、B、C 类"股东"投票提高他们在企业中占有的份额时,剩余归属D 类股东――普通投资者――的部分就将下降。
  展望未来,长期来看,认为A、B、C 类股票控制人会投票降低他们的份额是不明智的。D 类股票持有人可能将不得不努力维持他们自己的份额。
  FTC 统计显示通胀上升经营利润率下降
  上面我们提到的五种增加股本回报率的方法中,最后一种是提高经营利润率。一些乐观的人希望可以通过这种方法大幅提高股本回报。没有证据显示他们错了。但是,1 美元的销售额中只有100 美分,在我们得到剩余价值、税前利润前,这1 美元的销售额中还要扣除多项支出,主要项目包括劳动力、原材料、能源和各种除所得税外的其他税种。在通胀时期,这些成本的相对重要性似乎很难下降。
  而且,最近统计证据也不支持上述认为通胀时期利润率扩大的说法。在1956-1965 这段通胀水平相对较低的时期,联邦贸易委员会(FTC)每季度报告的制造业公司平均每年税前销售利润率为8.6%。1966-1975 年间,平均利润率是8%。换句话说,尽管通胀率大幅上升,公司利润率还是下降了。
  如果企业能够按照重置成本定价,利润率在通胀时期将扩大。但是,一个简单的事实是,尽管大多数大型企业的市场影响力得到人们普遍信任,但是他们未能做到按重置成本定价。重置成本会计方法几乎总是显示过去十年中公司利润大幅下滑。如果像石油、钢铁和铝等主要行业的垄断能力名副其实,那么我们只能认为他们的定价政策备受制约。
  上面可能提高公司普通股回报的五个因素都分析完了。在我看来,在通胀时期,这些方法的效果都不大。也许你在分析完之后更加乐观,但请记住,12%左右的回报率已经伴随我们多年了。
  未来收益三因子:账面价值和市场价值的关系、税率和通胀率
  也许你同意上述12%左右的股本回报率多多少少是固定的,尽管如此你仍希望在未来岁月中取得良好的回报。这一点也无可厚非,毕竟,很长时间以来,很多投资者的收益都不错。但是,你未来的收益将取决于三个变量:账面价值和市场价值的关系、税率和通胀率。
  我们先来简单地算一算账面价值和市场价值。当股票价格一直等于账面价值时,一切都非常简单。如果股票的账面价值是100 美元,平均市场价值也是100 美元,企业12%的收益将为投资者带来12%的回报。如果派息率是50%,投资者将获得6 美元的股息、并且从企业账面价值增加中获得另外6 美元,这6 美元自然会反映在该投资者所持股份的市场价值中。
  如果该股票的价格是账面价值的150%,整个情况就变了。投资者同样将收到6 美元的现金股息,但是其回报率只有成本的4%。企业的账面价值同样也将上升6%至106 美元,该投资者所持股票的市场价值类似地也上升6%至159 美元。但是,投资者的总回报――包括股票升值和股息――只有10%,低于企业原本12%的回报率。
  当投资者以低于账面价值的价格买入股票时,这一过程正好反过来了。比如,如果股票价格是账面价值的80%,假设收益和派息率和上例相同,那么股息收益率将为7.6%(6/80),股票升值6%,总回报为13.5%。换句话说,折价买股的回报率要高于溢价买股,这是常识。
  "二战"后,道琼斯工业指数的市场价值1974 年最低,仅为账面价值的84%,1965年最高,是账面价值的232%,大多数时间,这一比率高于100%。假设未来这一比率接近100%,这意味着股票投资者将获得企业全部12%的回报率,至少他们含通胀、含税收益率为12%。
  通胀是一种税,扣除后的收益有多少?
  通胀是一种比我们立法机构制定的任何税的破坏性都更大的税种。通胀税有吞噬资本的奇妙功能。
  如果我的通胀率假设接近正确,那么即使市场上涨,结果仍然令人失望。上月道指大约为920 点,相对于10 年前上涨了55 点。但是,经通胀调整后,道指下跌大约345 点――从865 点跌至520 点。即使是为了得到这一结果,道指成分公司中已经有大约一半的收益未派发给所有者,而是进行再投资。
  未来十年中,单单算上12%的股本息票、40%的派息率和目前110%的市净率,道指就将翻番。考虑到7%的通胀率,在1800 点出售股票的投资者在支付资本利得税后的实际状况要比现在贫穷的多。
  说到这里,我几乎可以听得见投资者对我的悲观预测的反应了。他们可能会认为,不管未来投资环境中面临什么样的困难,他们总会努力为自己交上一份优异的投资答卷。他们成功的可能并不大,当然,投资者整体而言,是不可能成功的。如果你认为你可以随心所欲买进卖出一只证券,并且收益超过通胀率,我倒愿意做你的经纪人,但不是合伙人。
  即使所谓的免税投资者――养老金、大学捐赠基金――也逃脱不了通胀税。如果我假设的7%的通胀率是正确的,那么大学会计应当把每年收益的前7%仅仅视作对购买力的补充。捐赠基金的回报率如果低于7%,他们实际上什么也没挣得。如果通胀率为7%、整体投资回报率为8%,那么,这些自认为免税的机构实际上支付了87.5%的"所得税"。
  通胀影响实际资本积累,派息后业务扩张资金所剩无几
  为了理解通胀对实际资本积累的影响,需要稍微计算一下。我们暂时回到前面提到的12%的股本资本回报,这一盈利水平扣除了折旧,应该允许现有产能的重置。
  我们假设一半的盈利以股息形式派发出去,剩余6%作为未来增长的股本资本。如果通胀率低,公司增长的很大一部分是实物产出的真实增长。因为在这种情况下,为了复制今年的实物产出,第二年投入到应收账款、库存和固定资产的资金必须增加2%,这样只剩下4%投资于实物产出的增量部分。也就是说,2%为虚幻金额增长提供资金,反映的是通胀;剩余4%为真实增长提供资金。如果人口增长1%,那么实际产出增加4%带来人均净收入增长3%。过去我们经济体的人均净收入增长基本上就在这个水平。
  现在我们来做另一个运算。如果通胀率是7%、派息政策和杠杆率保持不变,那么考虑通胀成分后,剩下的实际增长为零。12%的盈利中一半用于派息,剩下的6%全部用于为维持去年的业务量而增加的资金。许多公司在正常派息后实际上没有留存盈利为业务扩张提供资金,他们开始问,我们如何才能降低分红同时又不会惹怒股东?我给他们带来一个好消息,现在已经有这样的方案了。
  近年来,发电行业分红能力甚微,甚至没有。或者换句话说,如果投资者同意购买他们的股票,他们就有能力派息。1975 年,电力行业支付普通股股息33 亿美元,要求投资者返还34 亿美元。当然,他们略施小计,拆东墙补西墙,这样得以避免重蹈Con Ed 公司的覆辙。1974 年,Con Ed 公司非常干脆地告诉投资者无力派发股息。这家公司坦率但不明智的做法在资本市场上换来的是灾难。
  精明一点的公用事业类公司维持甚至增加季度派息水平,然后要求新老股东把钱汇过来。换句话说,公司发了新股。这种做法将巨额的资本送给税务部门和承销商。但是,似乎每个人都兴致高昂,特别是承销商。
  或许政府是解铃人
  随着企业努力应对实际资本积累问题,预计这种削减派息的方法将会被更广泛地使用。但是,控制股东并不能完全解决这一问题。7%的通胀率和12%的回报率导致用来满足公司未来真实增长所需的现金流减少。
  因此,随着传统的私人资本积累方法在通胀面前变得岌岌可危,我们的政府将越来越多地试图影响行业的资本流入,他们也许会像英国那样失败,或者像日本那样取得成功。美国不具备日本式的、政府、企业和劳工密切合作所需要的文化土壤和历史背景。如果幸运,我们或许能避免步英国后尘,在英国,各个集团围绕如何分配蛋糕而非协力做大蛋糕争斗不休。
  总之,随着时间推移,我们可能会听到更多关于投资不足、滞胀以及私人领域不能满足需求的故事。
  附:通胀环境中有望表现较好的公司
  既然通胀对企业盈利影响具有普遍性,那么哪些公司受伤害较小?在1983 年致股东信中,巴菲特指出,虽然长期以来人们认为那些自然资源、厂房、机器或其它有形资产丰富的企业最能提供通胀保护,但情况并非如此。任何需要有形资产净支出进行运营的无杠杆企业均将受到通胀伤害。需要很少有形资产支出的企业受通胀伤害最小。重资产企业通常回报率低,其回报率通常不足以满足通胀带来的企业现有业务运营的资金需求,没有剩余资金来支持真实增长、向股东分配股息、获得新业务。相比之下,在通胀岁月中积累的大量财富中,那些对有形资产需求较小、拥有持久价值的无形资产的企业占比较大。在通胀时期,经济商誉(而非会计商誉)能够持续创造价值,因为真实经济商誉的名义价值通常与通胀成比例增长。
  在1981 年致股东信中,巴菲特提到,其旗下伯克希尔哈撒韦公司收购的两类公司结果非常亮丽,其中一类恰好是能够很好地适应通胀环境的企业。这类企业必须有两个特点:(1)有能力在无需担心市场份额和单位产量大幅下降的情况下轻易地提价(即使当产品需求平稳、产能未得到充分利用时也能如此),(2)有能力将企业产出额大幅增加(更多是归因于通胀而非真实增长)与较少的额外资本投资需求协调好。

盖茨父子分享最佳人生建议:尝试自己不擅长的事

导读:比尔・盖茨(Bill Gates)与父亲老比尔・盖茨(Bill Gates Sr.)6月21日父亲节一同在巴黎接受了《财富》杂志的专访,两人就家庭关系、成长历程和共事经历畅所欲言。盖茨眼中的父亲形象伟大,父亲眼中的儿子优秀可贵。
  以下为文章全文:
  这对父子关系显然不一般。儿子曾创造出史上最大的财富奇迹之一,而今成为慈善家,父亲则在这家全球最大的慈善机构――拥有275亿美元资产的盖茨基金会――担任联合主席。其实对父子两人而言,这均为人生的第二份工作。现年53岁的盖茨去年6月退出微软日常事务管理,而现年83岁的父亲老盖茨也于1998年从西雅图著名的Preston Gates & Ellis事务所(现名K&L Gates)退休。近年父子二人互为顾问,但数年来父亲都对儿子谆谆教诲。近日记者在巴黎协和广场气隆酒店著名的伯恩斯坦套房拜访了这对神奇父子,并询问了两人人生获得的最佳建议。
  记者(以下简称"记"):比尔,我想知道,父亲给你的最佳建议是什么?
  比尔・盖茨(以下简称"子"):小时候,父母常鼓励我尝试自己不擅长的事情,让我参加许多运动,比如游泳、橄榄球和足球,当时我并不明白为什么。那时我觉得这样没意义,但后来它的确给了我许多展现领导才能的机会,并且让我懂得很多事情我并不拿手,而不是让我什么拿手就只做什么。这段经历很棒,而且有些运动我现在也很喜欢。父母当时必须这样敦促我,因为我经常退缩,不过这个建议非常宝贵。
  记:盖茨先生,你记得当时是刻意给孩子提出建议,还是出于父母的本能?
  老比尔・盖茨(以下简称"父"):我想在某种程度上,比尔的母亲和我是特意强调这一点的,但大部分时间都是本能地施教。我们的确认为他应该出去、加入社区的垒球队之类。我们觉得这样对他有好处而且他会喜欢,事实证明这个建议是正确的。
  子:尽管我当时很不擅长垒球。
  父:你打得不错。
  记:你这话听来简单,但所有身为父母的人都知道经营一个家有时并非如此。在新书中你提到周日共进晚餐和(圣诞节)穿同样的睡衣。盖茨先生,这些办法真有用吗?
  父:我想就我个人家庭的经历而言,我可以肯定地说有用。
  记:比尔,你觉得呢?
  子:我觉得家庭聚会聊天的传统的确帮助很大,比如一起出游,永远在饭桌上分享观点。从父母那儿我们了解到他们从事的东西,无论是United Way(注:美国一家慈善基金会,盖茨的母亲是该基金会的主席)还是志愿活动,或者是商业。后来我与成年人聊天时非常自如,因为父母就是这样与我们分享对事物的观点的。
  记:你们俩的关系并非一直这么好。像其他父子一样,你们也有过摩擦,对吗?
  子:没错。我觉得把这说出口并不容易。我曾经对我想做的事情精力充沛且十分固执。我高中最后一年时得到一份工作,可能因此中断学业。当时让我惊讶的是,父亲跟校长见过面、了解完所有情况后说:"这是你能做而且该做的事情。"之前我们有不少矛盾,我那时很迷惑,也想通过与父母对抗证明自己。父母特意让我拜访了一位专家,他告诉我与父母对抗并无好处。现实世界中净是纷争与战斗,父母则是真正站在我这边的。这话说得太好了。它改变了我的心态。那时我才十二、三岁。我觉得从那时起跟父母的关系就好起来了。
  记:许多十二、三岁的孩子都被劝告过,父母不是敌人,但他们往往是左耳进右耳出。但你却能真正听进去,并且从此跟父母越来越亲近?
  子:没错。我开办微软那会儿,周日常去父母家和他们聊自己遇到的挑战,并听取他们的建议,把麻烦事儿发泄一通。我记得微软上市时,我曾说其中可能存在一些弊端,然后我们一同讨论如何避免它们。所以我们好比同一个战壕里的战友。尽管这个行业还略显神秘,但父母非常支持我。机会之大无法想象。
  记:你们在工作上合作默契,家庭关系也十分亲密。你认为其中的秘诀是什么?
  父:我获得过的(最佳人生建议)之一便与你方才的问题有关,也就是如何与孩子相处并适当地鼓励他们。比尔的母亲和我早年曾在教堂接受父母效力训练。在那里人们教导我们并强调的至关重要的一点就是,不要贬低孩子。一旦你意识到这点的重要性,你与孩子的关系便有了良好的开端。我是儿子的忠实粉丝。我认为他是一个了不起的公民和商人,我们有机会共事的时候我就会把这个想法表露出来。
  子:我想这是因为我们角色分工明确。我很有干劲,是总问"为什么我们还没做完?"的那种人,父亲则代表着一股智慧。比如我们开会讨论日程问题或是开支问题等等,他的发言会让所有人停下来思考。你知道,我们缺乏这种看事情的角度。他全天候上岗,为基金会塑造了良好的价值观。基金会开会时,人们会起立鼓掌,因为他的确给公司带来了改变。在繁忙的工作中设立家族基金会,还要保证基金会内部价值观正确向上,这一切必须归功于我父亲。
  记:你的儿子并非事事采纳你的建议吧,盖茨先生?我是说,当他告诉你计划从哈佛辍学时,你是怎么对他说的?
  父:他第一次说起要离开一阵子再回校时,强调的还是,他会回去。第二次,他确实回校之后,他又感到必须前往阿尔布开克,也就是公司所在地,并且花更多的时间在那儿工作。第二次我们就对此事关心多了。公司变得业务繁忙,保罗・艾伦(Paul Allen)一人在阿尔布开克,比尔必须去帮他。
  记:比尔,我想了解下你另一个人生导师沃伦・巴菲特(Warren Buffet),你从他那儿获取的最佳建议是什么?
  子:沃伦给了我很多宝贵建议。最有趣的可能就是他如何简化事情。翻开他的日程表,你会发现上面十分简单。你跟他讨论一桩商业前景诱人的生意,他只了解少量基础数字和事实。(如果)还可以简单些,他就会感觉应该选择它进行投资。他根据现有的模型进行选择,这个模型有预知性,并且将长期有效。所以他有能力进行高度概括、专注于最重要的事情、思考基础问题,这些都很了不起。这是一种特殊的才华。
  记:如果你的日程表有一大堆复杂的事务,你真的会停下来思考,换作巴菲特,他会怎么做吗?
  子:当然。我会想,巴菲特对所有人都很好,他拒绝别人时会怎么说?他是怎么排定事务优先次序、并且保持头脑清晰?他回绝了不计其数的事情,却让所有人都感觉良好。他与人交往的风度惊人,比如他说:"你可能比我在这方面懂得多,你看我刚接手就弄得一团糟。"你知道,这是一种特殊的本领,我有时候的确会思考,巴菲特会用怎样的礼仪表达这件事呢?年度大会上曾发生过一件事,有人问他是否应该出售价格上涨的股票而保留没上涨的,他回答说:"不,你应该看它的商业价值。"查理(Charlie Munger,伯克希尔-哈撒韦公司副董事长)在一旁补充:"他是在告诉你,你的基本概念大错特错。"其实巴菲特的答复正如此,只不过他只字未提"喂,傻瓜……"
  记:比尔,说说你的成长过程?高中或哈佛的老师?在那里有没有什么经历让你获益匪浅,恍然大悟?
  子:我父母很好,把我送进了一所优秀的高中。那是一家私立高中。许多老师都在数学与科学科目上对我大加鼓励,并把自己喜欢的教材赠与我,让我提前阅读。而我对计算机的熟悉,也来自于Lakeside中学的先见。老师真的很棒,他们发现计算机操作复杂后,让学生代为接管。我猜大多数学校在这种情况下都会直接关闭了事。而我们竟然自行接管了起来,我们甚至开始使用计算机选择班级见面时间,我和一个朋友负责此事。所以说,他们很放心。有不少老师我都十分感激,他们让我们随心所欲地行动、梦想。
  记:你还记得他们的名字吗?
  子:记得。弗莱德・莱特(Fred Wright)是数学部的主要负责人,我要把最多的感谢送给他。物理老师加里・马斯特瑞迪(Gary Maestretti)很鼓励我。即便我在8年级,各项国家级测试中都成绩突出时,一个叫保罗・斯托克林姆(Paul Stocklim)的人还是对我说:你应该更自信些。你真的很擅长这些东西。这些鼓励对我帮助极大,也给了我一个极其优越的环境。所有老师都很体贴。我觉得他们尤其偏爱我,因为我对尖端领域非常感兴趣。也正由于此,他们总是把新事务扔给我处理。
  记:那么盖茨先生,是什么原因促使你决定写作此书?这本书里写有大量建议与知识,显然你感到很有必要拿出来分享一二。那么促使你这么做的原因是什么呢?
  父:起初我打算写一本回忆录,后来我的同事玛丽・安・麦金(Mary Ann Mackin)鼓励我把它写成一本书,而不是仅仅送给亲友阅读的回忆录,她的名字就在本书的封皮上。坦白说,起初我很犹豫,但是她坚持让我考虑,最后我说,好吧好吧,那就这么做吧。现在我很高兴当初的决定。这个过程十分有意思。我是说我之前对书籍出版业一无所知,出书让我大饱眼福并且享受到无穷乐趣。
  记:你认识了很多儿子的同事与伙伴,最后这些人成了你自己的同事你是否很惊讶?你有没有设想过事情会这样发展?
  父:完全没有。你不可能设想这样的事情发生。你说得很对,这的确让我惊讶。我从来没想过,我的人生会以这样的方式发展。
  记:你儿子的同事或伙伴中,哪些人在你看来对你的学习过程有所帮助?
  父:有很多。当然,他的两个主要同事,保罗・艾伦和史蒂夫・鲍尔默(Steve Ballmer)肯定在列。他们是非常聪明、有洞察力、有思想的人。
  子:我会说可能还有帕蒂・斯通塞弗(Patty Stonesifer,盖茨基金会总裁兼联席董事)。
  父:没错。
  子:帕蒂跟我父亲一起创立了基金会以及整个方案和价值观。她正直谦逊。他俩全面考虑了许多事情,因此等我有时间全职工作时,基金会已经开始解决一系列有趣而复杂的问题。所以我很幸运,由我接管基金会时,它早已不在萌芽阶段,而已经与许多了不起的人物发展业务。父亲的价值观很好地引导了基金会的发展方向。
  父:顺便说道,另一个对我帮助很大的人当属梅琳达・盖茨(Melinda Gates),她不单是我的儿媳,更是朋友,会提出非常有智慧的建议。
  记:比尔,当你从微软走进基金会的世界,从计算机科学走进自然科学乃至更远的天地时,你有没有从新共事的人身上获取什么建议、学到什么新东西呢?
  子:有,这是一个全然不同的世界,而且我希望能从自己毕生奉献的商业环境和工程技术领域里,去粕取精,并且万无一失。
  记:你在壮大微软的过程中从安迪・格鲁夫(Andy Grove)或是IBM人身上学到了什么吗?
  子:我们在质量监控方面学到了很多,尤其是从IBM日本公司身上。我们的日本用户在整体上对质量和精确度都有严格要求,这很好,因为我们在早期与他们有大量合作。我们跟英特尔几乎是同步成长。安迪有时候非常友好,会给我们提出建议,有时候又非常严格。但无论怎样我们都裨益良多。我是说,他很睿智。他帮助我们用全新的角度思考问题。苹果是我们的竞争对手,但为保证苹果机面向大众消费者销售,微软拥有所有的早期软件,因此是他们的核心合作伙伴。这个学习过程非常有趣,与史蒂夫・乔布斯(Steven Jobs) 共事让人激动,而且时有惊喜意外,不过他很有才华,也在很多方面赋予我们灵感。
  记:这些年来,你从乔布斯身上学到了什么特别的东西吗?
  子:史蒂夫是个会痴迷于某些东西的人,而且我认为狂热这个特征没有得到公道的评价。我对领导技术团队及保证技术质量非常狂热。史蒂夫对用户体验和产品设计十分狂热,这显然为苹果带来了巨大改变,史蒂夫说必须整体一致,不是像委员会那样罗列清单,而要有一个整体观。这一见解很深刻。
  记:你们庆祝父亲节吗?怎么庆祝?
  父:生日之类的我们会办得很隆重,但是父亲节就是偶尔一道吃个晚饭。
  子:是的,父亲节的时候经常通电话。
  父:没错,是这样。
  子:我们的风俗习惯更多是围绕感恩节、生日、独立日和圣诞节进行。不过父亲节是个很好的机会,我会借机通过电话告诉父亲,他树立了一个优秀的楷模形象,是个了不起的父亲。

新能源泡沫须小心――翟敬勇

从去年年底开始的新能源热让我也花了不少精力去研究琢磨.拜访了不少PE/vc的朋友,也看了不少研究员的文章,也去了解了一些新能源的公司.刚好昨天晚上看了中央二台的节目,谈什么新能源的,正好有一家我们深入了解过的一家公司.
一个非常有名的vc公司的朋友跟我说了一句话:"我真搞不懂做二级市场的人,只要一条生产线开始投产了,股票就会呼呼的涨,好象只要投产就可以赚钱了."他们拿着的企业是不能抛售的,所以需要观察\了解成本与收入的关系.而二级市场的人可能比较容易卖掉,就人骗人了,反正有傻瓜接盘.
我了解一家公司的光伏发电成本为五块,当地政府补贴四块,发一度电还亏一块.中央二台做节目的这位李总还在说,准备再亏五年.还是这家公司,开年度股东会告诉我们不再搞太阳能项目,可我们前脚刚走,后面新的太阳能多晶硅项目公司就成立了.因为投资了这家公司,一帮朋友给公司找大量数据指出不能投资烧钱,也许是上天帮助我们,公司的一个项目失火了,一把火把管理层烧清醒了,之后终止了多晶硅项目.五月份再开股东会时,我去了,公司高管向我们讲了把新能源公司结束了.(从成立到结束一个月,虽然公司说感谢流通股东的支持,我个人认为是这把大火的功劳)
对于多晶硅的价格:去年还在300美金/公斤----目前60-70美金/公斤;比亚迪宣布可以做到13美金/公斤.我真不知道那些口口声声投资新能源的人如何睡得着觉.最近多方了解,就算比亚迪做到13美金/公斤,还是亏钱,最重要的原因是无法大规模商用,不能大规模商用就无法产生经济效益,不能产生经济效益,那不就只能亏钱了.比亚迪的电动汽车政府补贴,更是一个美丽的虚幻大饼,一辆车补贴6万,一万辆车就是6个亿,哪个地方政府肯拿钱.比亚迪烧钱还有资本,电子零部件和传统的油车,能够支持其太阳能电池和电动车烧钱.国内的其他公司有这个实力烧钱的好象没有.
至于所谓的风电,听起来现在更好笑,国家的五大电力集团要投资多少建设,这是典型的拿着国家的钱在烧.我去过一家风电企业了解过,综合成本在六毛以上,政府补贴才不亏钱.更重要的是,他们发的电,电网公司还不要.
现在为什么新能源项目都是美丽的烧钱花呢,主要是我们的电网落后.电网就向高速公路一样,没有形成新的改造之前,所谓的新能源根本没有办法投入商用.就拿风电来说,风力不稳定导致电流输送不稳定,一旦规模形成将对现有的传统电网产生巨大的伤害.这也就是电网公司为什么不敢要风力发的电的主要原因.太阳能也是如此.
解决的问题唯一的办法就是智能电网,可是,大规模的电网改造,涉及的面非常广,不能轻易的做实验.今年国家才刚刚提出规划,从目前来看,智能电网的改造,预计需要5-10年以上的时间.换个角度考虑就是,现在的新能源企业可能要烧5-10年的钱,谁能烧下去,谁就能活下去.
从国家的重点投资转向来看,今明两年还集中在高速铁路的建设中,两年以后电网改造才有可能进入议事日程,从比较现实的角度来看,跟电网改造相关的一些企业或许存在一些投资机遇.
新能源本属于PE/VC干的活,缺被忽悠到了二级市场.这些美丽的概念变成实实在在利润还需要一个漫长的过程,其间重大的不确定因素还在等待这这些企业.投资不确定的东西确实需要一些胆量.只有那些不需要为投入的钱负责任的人才敢大胆的冲进去.
翟敬勇
2009年6月23日

2009年6月23日星期二

冷笑话大集合

如果有一辆车,司机是王子,乘客是公主,请问这辆车是谁的呢?--如果的
金木水火土,谁的腿长?————火腿肠
眼睛蛇和大象约会,寒暄一番后说:"来就来吧,还牵这么大头猪,客气了。" 
我想,只要我再稍微具有一些谦虚的品质,我就是个完美的人了。
有一天,绿豆跟女朋友分手了。他很难过,于是他不停地哭呀哭呀,哭呀哭
呀......结果......发芽了。~~~
pol.ice:"说,你叫什么~?" 犯人:"我叫成龙。"
pol.ice:"你怎么不叫陈真,给我把态度放端正了~好好说你叫什么~?"
犯人:"我叫陈真。"
两只水母在海边相撞在一起, 水母甲:「搞甚么嘛!你游泳不长眼睛啊!」
水母乙:「甚么是眼睛啊?」
水母甲:「我也不知道,上次和别人撞到的时候他这样骂我的。」
水母乙:「喔!是这样喔!」
小学自然课,老师告诉我们膝盖那里轻击的话会有膝跳反射。我回家后拿个锤子在我爸膝盖那里锤了一下,结果我爸站起踢了我一腿。结果证明老师说得没错!
假如有一天我变成流氓,请记得告诉我我曾经清纯过。
人生的第一句谎话是从小学写作文开始的,而真心话是从写情书开始的
格林兄弟在写《白雪公主》时很有预见性,里面最后拯救了白雪公主并和她一起幸福生活的男人名叫"白马王子"。而现在的女同胞们都想找到心目中的那个白马王子,为什么捏?因为白马王子的拼音简写就是——BMW,还是Z系。
一男要跳楼,其妻大喊道:"亲爱的别冲动,我们的路还长着呢!"男子听后,嗖地一声跳了下去。pol.ice说:"你真不该这样威胁他!
大便跟小便是好兄弟,有一天大便过马路被车撞死了,小便就说:我好想大便啊…
小明:"妈妈,同学都说我头好大。"妈妈:"瞎说,他们都是坏孩子不理他们。去,帮妈妈买栗子去。"小明:"用什么装?"妈妈:"用你的帽子啊。"
先在脑子里想一个数,乘以二,再加上五,然后减去最初你想到的那个数,再乘以八,减去五,然后闭上眼睛,什么都看不见了,对不对?
某同学暗恋一位每天放学都会遇到的PLMM,但苦于没有机会接近。一日跟踪MM到一家拉面馆,终于鼓起勇气跟她说话:"同学..............你叫什麽?"
MM:"牛肉面。"................................................
有一人走着走着摔倒了,他爬起来继续走又摔倒了.于是他说;早知道,我刚才就不爬起来了
细雨落到小河上 小河便起了一层鸡皮疙瘩
什么卡通人物最专情?回答: 美人鱼(因为她不会劈腿)
小明呢,明天就要考试,但晚上却在看电视
小明妈妈就担心地问:书都看完了吗?明天要考试啊
小明就爽快地回答:妈,我看完了。
小明妈妈就很开心的赞扬小明:乖,那明天你一定考得很好呢
小明哭着说:妈,我是说,'妈,我看,完了'。
小A对小B说: 挖塞 ....外面下雨了也!! 看到没
小B很兴奋:是啊 我看到了 你呢
小明上完厕所回到教室跟老师说:
厕所有好多蚂蚁,
老师忽然想到蚂蚁的英文ant这个单词,于是测试小明:蚂蚁怎么说?
小明一脸茫然.......说:
蚂蚁他…………什么也没说…
一天,三只小猪为了躲避大灰狼的追赶,而建造了三个小屋。大灰狼不费劲的吹毁了草屋、木屋、砖屋,三只小猪们拼命的跑,但是还是被大灰狼追上了。
三只小猪绝望地说:你看着办吧。我们放弃了,随你怎样。
此时,大灰狼*笑着,流着口水说:那快告诉我小红帽在哪里?

猪八戒正在月亮上和嫦娥亲热,突然一条黑影掠过,猪八戒急忙提着钉耙
追出去,过了一会回来了,说:妈的,杨利伟......

一天在公共汽车上,一个女人为了买票离开座位,等她回来的时候发现,自己的座位被另外一个女人占了,于是很不甘心,大声说了一句:下蛋不行,占窝倒挺快。坐在座位上的女人听见了,连忙站起来,面带微笑的说:不好意思啊,耽误您下蛋了!

一个人养了一只鹦鹉,非常厉害,和它关在一起的其他鸟都被它打死了。
后来主人弄回来一只鹰和它搁在了一块,等主人在来看,笼子外面挂着鹦鹉的毛。
主人说:"这回不****了吧。"
可在仔细一看,是鹰死了,鹦鹉光着个身子说:"这孙子真厉害,不脱光膀子还真打不过丫挺的。"

一司机开着一辆装满母鸡的货车,边开车边逗他的鹦鹉,一美女搭车,司机便将鹦鹉放到货箱与母鸡在一起,请美女坐在驾驶室。开了一会儿,司机试探着问美女:"亲一下行吗?"美女非常害羞地摇了摇头,说:"不行。"等了一会儿,司机契而不舍地又问:"抱一下行吗?"美女仍然摇头说:"不行。"司机气愤地说:"不行就下去。"开了一会儿,司机感到自己地做法很不绅士,于是返回去又请美女上了车,可开了一会儿,司机不死心地又问:"亲一下行吗?"美女仍然摇了摇头,"抱一下行吗?"美女还是摇头,"不行就下去。"如此反复了三次,终于到了鸡场,司机打开车箱,见母鸡已缪缪无几,只见鹦鹉提起一只母鸡问道:"美女亲一下行吗?"母鸡拼命地摇头,鹦鹉又问:"美女抱一下行吗?"母鸡仍然摇头。鹦鹉说:"不行就下去。"母鸡被抛出车外......

小白兔在森林里散步,遇到大灰狼迎面走过来,上来"啪啪"给了小白兔两个大耳贴子,说"我让你不戴帽子"。小白兔很委屈的撤了。
第二天,她戴着帽子蹦蹦跳跳的走出家门,又遇到大灰狼,他走上来"啪啪"又给了小白兔两个大嘴巴,说"我让你戴帽子。"
兔兔郁闷了。思量了许久,最终决定去找森林之王老虎投诉。
说明了情况后,老虎说"好了,我知道了,这件事我会处理的,要相信组织哦"。当天,老虎就找来自己的哥们儿大灰狼。"你这样做不妥啊,让老子我很难办嘛。"说罢抹了抹桌上飘落的烟灰:"你看这样行不行哈?你可以说,兔兔过来,给我找块儿肉去!她找来肥的,你说你要瘦的。她找来瘦的,你说你要肥的。这样不就可以揍她了嘛。当然,你也可以这样说。兔兔过来,给我找个女人去。她找来丰满的,你说你喜欢苗条的。她找来苗条的,你说你喜欢丰满的。可以揍她揍的有理有力有节"。大灰狼频频点头,拍手称快,对老虎的崇敬再次冲向新的颠峰。不料以上指导工作,被正在窗外给老虎家除草的小白兔听到了。心里这个恨啊。
次日,小白兔又出门了,怎么那么巧,迎面走来的还是大灰狼。大灰狼说:"兔兔,过来,给我找块儿肉去。"兔兔说:"那,你是要肥的,还是要瘦的呢?"大灰狼听罢,心里一沉,又一喜,心说,幸好还有B方案。他又说:"兔兔,麻利儿给我找个女人来。"兔兔问:"那,你是喜欢丰满的,还是喜欢苗条的呢?"大灰狼沉默了2秒钟,抬手更狠的给了兔兔两个大耳帖子。"靠,我让你不戴帽子。"

小白兔蹦蹦跳跳到面包房,问:"老板,你们有没有一百个小面包啊?"
老板:"啊,真抱歉,没有那么多"
"这样啊。。。"小白兔垂头丧气地走了。
第二天,小白兔蹦蹦跳跳到面包房,"老板,有没有一百个小面包啊?"
老板:"对不起,还是没有啊"
"这样啊。。。"小白兔又垂头丧气地走了。
第三天,小白兔蹦蹦跳跳到面包房,"老板,有没有一百个小面包 啊?"
老板高兴的说:"有了,有了,今天我们有一百个小面包了!!"
小白兔掏出钱:"太好了,我买两个!"

犯人被执行枪决,由于子弹质量不好,第一枪没响,接着又开了第二枪。。。第三枪。。。这时犯人哭了,抱着法警的大腿说:大哥你掐死我把!太他妈吓人了.....
一小学生,向暗恋已久的老师表白,老师说这样不对,可他不听。最后,老师受不了,说:我不想要小孩子。小学生说:我会小心的!"。

某精神病院听说领导要来医院视察情况,于是,院长召集所的病人开会在会上,
院长讲道:"今天下午,有很重要的领导要来参观,所有的人都要去门口欢迎。在欢
迎的时候,所有病人站在医院大门口两边,要站整齐,当我咳嗽的时候,大家一起鼓
掌,越热烈越好;我跺脚的时候必须全部停止,不能有一个出错。要大家都做好了,
今天晚上可以给大家吃肉包子,只要有一个人弄砸了,所有的人都没有包子吃,记住
了吗?"台下病人一起喊道:"记住了!"
这天下午,领导准时到来,当他步入大门的时候,欢迎的病人已在门口站好了这
时,随着院 长一声咳嗽,所有的病人一起鼓掌欢迎,气氛十分热烈。来参观的领导
受到热烈气氛的感染,面带笑容,和大家一起鼓掌步入医院。见领导已经走进了医
院,院长一跺脚,所的掌声都停止了,非常整齐。只有这位领导还在面带笑容一边鼓
掌一前行,院长感到非常满意。忽然,从欢迎的人群里窜出来一个壮如施瓦辛格的病
人,大步冲到领导面前,抡圆了给了他一个大耳光,气愤异常地吼道——"你丫不想吃包子了?!!!"
有三个人,在一起比试枪法,由一个黑人顶着某样东西做为靶子。
第一个人在黑人的头上放了一个苹果,然后在距离10米远的位置,抬手一枪就将苹果打碎了,他吹了一下枪口说:I'm
佐罗!
第二个人在黑人的头上放了一个樱桃,然后在距离50米远的地方,抬手一枪就把樱桃打碎了,他吹了一下枪口说:I'm007
第三个人在黑人的头上放了一粒芝麻,然后在距离100米远的地方,抬手一枪就把那个黑人的头打碎了,他也吹了一下枪口说:I'm
sorry……
一家有仨人,分别叫强盗,菜刀,麻烦
一天,麻烦失踪.强盗带着菜刀来到公安局,对警察说:"您好,我是强盗,我带着菜刀来找麻烦."
嘻嘻和哈哈是一对好朋友,非常要好的朋友.
有一天,哈哈死了.嘻嘻很难过,他走到哈哈的坟前说:"哈哈,你死了."
一天,一头大象在森林里散步,不小心碰了一蚂蚁窝满身是蚂蚁,它就把身上的蚂蚁抖了下来,可是还剩一只在大象的脖子上,这时地上的蚂蚁就对上面的蚂蚁大叫:掐死它.....掐死它......
三只老鼠在吹牛。一只说:"我把老鼠药当糖果吃,一天不吃心里不舒坦。"另一只说:"我每天都爱上街溜达两遍不然睡不安稳。"第三只老鼠说:"天晚了,回家抱猫睡咯。"
夫妻离婚争孩子,老婆理直气壮说:"孩子从我肚子里出来的,当然归我!"老公说:"笑话!简直是胡说八道。取款机里取出来的钱能归取款机吗?还不是谁插卡归谁!?
属相
中国民俗十二生肖属相,也是西方人极感兴趣的话题,每个人都想查清楚自己是属什么动物的。不幸的是,"属"和"属于"海明威常常混淆。
一天他对秘书姑娘兴奋地说:"你是属于猪的。"
中文里用"雌性"或"雄性"来形容动物性别,这对海明威来说未免太难为他了,因在英语里无论形容人或动物都可通用male(男性)或female(女性)。
一天晚上海明威在街上牵着她的爱犬散步,见到我后,得意地向我介绍"这是我的女狗。"
安全帽
海明威除了开小车,平常爱骑摩托车,说是方便。我说路上车太多,要小心。他接了一句:没关系,我会戴安全套的。他本来想说的是"安全帽"(头盔)。
量词
中文里的量词,也令海明威大为头痛。一次他自我标榜是"一条好汉",问他何意?他说:"一条好汉,意思就是一个瘦而高、相貌好看的男人。"他解释"一条"自然是长而直的意思,至于"好汉"理所当然应该是模样好看的男人。
还有一次他告诉我,他在公路上看到了"一张小狗"。我立即纠正应该是一只小狗,他却表情认真地反驳说,千真万确是一张小狗,因为小狗已经被汽车轧死了,压扁了的小狗理所当然变成为一张小狗,就如同一张纸、一张相片一样。
除此之外,诸如什么"一对裤子",海明威振振有辞地辩解,因为裤子都有两条裤腿,两条即一对,因此没错。甚至处找中国人辩论,坚持称应当是"一套屁股"才符合逻辑,听来甚为滑稽。
各种各样的"汁"
有一次,考考海明威的成语能力:"绞尽___汁"。
结果是:
"绞尽墨汁","绞尽乳汁","绞尽果汁","绞尽汤汁"。
哈!"你真是'绞尽脑汁'也没想出'绞尽脑汁'
有个妈妈对小女孩说:「如果有人对你性骚扰,摸上面就说"不要",摸下面就说"停"!」
隔天,小女孩被性骚扰了,哭着回来向妈妈说,妈妈听完小女孩的话后,很生气的说:「你有拒绝那个人吗?」
小女孩用很无辜的眼神看着妈妈,点点头说:「那个人上下一起摸,所以我说"不要~~停"!!」
葛亮是个精通奇门八术的人,其中有一项特长就是口技。却说这一日诸葛亮正与刘备在帐中议事,诸葛亮突然想放屁,
又怕被刘备听见,不好意思。他灵机一动,道:"主公,为了调节一下气氛,我学啄木鸟叫给你听怎么样?"刘备点点头。
诸葛亮模仿啄木鸟叫了两声,趁机把屁给放了。然后问道:"怎么样主公?我学的象不象?"刘备道:"你再学一次吧,刚才你放屁的声音太大,我没听见。"
一小学生第一次参加学校的朗诵比赛,特别紧张,老师鼓励了老半天,手心还是冒汗。终于轮到她了。
小学生一咬牙,几步走到了台中央:"老师们,同学们,我朗诵的题目是:红叶疯(枫)了......"~~·#¥**......
还是一小学生,看到被老师点到念作文的同学,特别羡慕,总盼着老师也能让自己念一回。机会终于来了。
"某某,把你的作文给大家念一下!"
小学生"腾"地一下站起来:"《我的老师》。老师,我多象你的妈妈......":(
这回是一个歌舞团的学艺不精的主持人。
一次演出,之前没好好准备就匆忙登台了。
演出依次进行。
轮到她报幕了:"观众朋友们,下面请听犊(独)子笛奏......"(注:"犊子"在东北方言里有骂人意)
观众倾倒一片·#¥-
我家里在冬天经常把大葱栽在盆子里,以保持它的鲜嫩。
我妹妹过年回家看到了,欣喜地对我妈说:"哎!妈,这粗真葱......"
我和我妈皆笑倒。
有个我叫"大姑"的邻居,每天骑自行车上班。
一早,在门口碰到她,我微笑着客气了一句:"上姑啊,大班......"
呸!......我当时恨不得把自己的舌头咬下来。
某女同学,一天顾影自怜,忽转头对后面的人说:"我的胸毛美不美?"
吓人一跳,又说:"噢,我是想问我的眉毛凶不凶。"
全体起立!奏国旗,升国歌...
我带儿子去喂鸭子。他一边给鸭子撒面包屑一边追鸭子到处跑,我拿着他的苹果在后面追他(他不爱吃,我只能在他精神分散的时候伺机塞给他几口)。他不停地跑,我不停地喊他:"过来吃一口苹果再追鸭子!"总是重复这一句,我终于大声喊出了口:"过来吃一口鸭子......"然后很聪明地刹住了闸。
记得上小学的时候,有片课文叫瀑布的,中间说到作者转过一座山见到一条瀑布垂在山间,我的一个女同学朗读的时候也是声情并茂的念:转过这座山,我惊呆了,一条破布挂在山上。。。
全班同学都惊呆了。
还有一个从俄罗斯作家的小说摘来的课文里有一句是:这里的房子都是老爷(指有钱人)们的。
结果我的一个男同学朗读道:这里的房子都是老爷们儿的。话音一落,我们语文老师就疑惑地问他:那老娘们儿都住哪儿?
电器用品举办讲笑话大赛,规定每个电器都要讲一个笑话,而且让现场的每一位观众都哈哈大笑,否则要被抓去阿鲁巴。
首先上场的是洗衣机,他笑话一讲完,全场哈哈大笑。
突然听到电饭锅说:"好冷哦~~~"
所以洗衣机就被抓去阿鲁巴了。
接下来上场的是最聪明的计算机,他的笑话一讲完,所有的家电全部笑翻了。
又听到电饭锅说:"好冷哦~~~"
所以! 计算机也被抓去阿鲁巴了。
第三位是最幽默的台灯。台灯很有自信的讲完笑话,大家全部笑到在地上打滚。
电饭锅又说:"好冷哦~~~"
正当台灯要被抓去阿鲁巴时,电饭锅很生气的站起来,转过头对坐在他后面的冰箱说:"我受够了,你笑就笑,嘴巴不要张那么大,很冷唉!"

电器用品举办讲笑话大赛,规定每个电器都要讲一个笑话,而且让现场的每一位观众都哈哈大笑,否则要被抓去阿鲁巴。
首先上场的是洗衣机,他笑话一讲完,全场哈哈大笑。
突然听到电饭锅说:"好冷哦~~~"
所以洗衣机就被抓去阿鲁巴了。
接下来上场的是最聪明的计算机,他的笑话一讲完,所有的家电全部笑翻了。
又听到电饭锅说:"好冷哦~~~"
所以! 计算机也被抓去阿鲁巴了。
第三位是最幽默的台灯。台灯很有自信的讲完笑话,大家全部笑到在地上打滚。
电饭锅又说:"好冷哦~~~"
正当台灯要被抓去阿鲁巴时,电饭锅很生气的站起来,转过头对坐在他后面的冰箱说:"我受够了,你笑就笑,嘴巴不要张那么大,很冷唉!"
丑孩子
一名妇女抱着一个孩子坐上公共汽车。司机看了一眼孩子,突然说道:"我一辈子都没见过这么丑的孩子!"
气愤的妇女走到最后一排,坐下后,对旁边的一名男子说:"这个司机刚才侮辱了我!"
那人答道:"您赶紧去找他算帐,我来替您抱这个丑猴子!……"
讲不好普通话的笑话
1、卖鱼的扯着嗓子一个劲地叫喊着:"鱼啦,鱼啦。"旁边一个卖枣的也不甘示弱,紧接着嚷:"糟(枣)啦,糟(枣)啦。""鱼啦。""糟啦。""鱼啦。""糟拉。"卖鱼的越听越不对劲,觉得卖枣的好像有意跟他作对,于是两人吵了起来。
2、某乡镇企业的厂长将要到日本神户考察,他连普通话都讲不了,平常只说方言。于是他让下属去找个翻译,下属回来报告说:"日语翻译没有一个能听懂厂长土话的"。厂长说:"这好办,我们就再带个本镇的老师,到时叫他把咱的土话先翻成普通话。"下属说:"还不行啊,到了日本还得请个人把日本的'普通话'翻译成神户的土话。"
3、一个方言土音很重的外地人,在市区迷了路,见一个斯文的小姐走过来,便迎上去问:"兔子(同志),亲吻(请问)一下......"话还没说完,小姐便气得满脸通红。
4、一南方人来到北京一家小吃店,对女服务员说:"睡觉一晚(水饺一碗)多少钱?"服务员一听,神色大变,尖声道:"流氓!"南方人一听,说:"才六毛,便宜,来一晚(碗)。"
5、有一对农民兄妹用板车拉着小麦到市场去卖,一个南方人来到他们兄妹跟前,问:"大哥,你的小妹(小麦)怎么卖呀?"大哥气得额头上青筋暴突。
6、牛老伯在大声叫卖:"卖月饼了,四块钱十个。"很多人都围上去买这"便宜"月饼,到付钱时,才明白老伯的月饼是十块钱四个。
7、敬老院的老人们在中秋之夜举行晚会,主持人王老太说:"各位,表演该死(开始)了,大家请安静。"
8、一个北方人在广州某公园打听"缆车"在哪儿,按回答寻去,找到的是"男厕"。
9、一对新人结婚后第一天清晨,一家人起床洗脸,新娘恭恭敬敬地对婆婆说:"婆婆,请您先死(洗)。"说完,新娘又对新郎说:"婆婆死了,你死好吗?"停了停又说:"婆婆和你都死了,最后我死。"婆婆听后,脸色铁青,一句话也说不出。新娘又说:"婆婆,您怎么还不死呢?"
10、一个莆田老太在路边卖甘蔗,一辆客车停下来,车上一位外地人来到老太摊前买甘蔗,刚称好甘蔗,还没付钱,车子发动了。老太催促道:"快点,你钱给我,我嫁(蔗)给你。"外地人吓得连甘蔗也没拿,飞快地上了车。
11、一乡下姑娘来到超市,服务员热情地招呼:"小姐,您要什么?"姑娘说:"我要你的命(面),猪孙(竹笋)。"
12、春花遇见一个朋友带着儿子逛街,忙上前打招呼,并赞道:"这个小狼孩(男孩)长得真可爱。"
13、一所乡村小学上课了,老师走进教室:"站(上)课。"学生们齐声道:"老死(师)好!"老师说:"吐血(同学)们,早死(上)好!"
14、两个乡下姑娘进城回来,天色晚了,见一辆卡车开来,便向卡车招手,司机探出头来,一个姑娘说:"同志,我俩可以做(坐)你的妻(车)子吗?"司机没好气地说:"谁要你们做我妻子。"另一个姑娘赶紧说:"不要紧啦,我们很亲(轻)。"司机气得把车开走了,心想:"谁和你们亲去。"
15、村长在村民会议上说:"兔子们,虾米们,咸菜太贵,不要酱瓜,要猪蹄。"把他的方言译成普通话是:同志们,乡亲们,现在开会,不要讲话,要注意。
我和朋友刚搬家的时候,家里没有电视机,两个人很无聊。我们就假装桌子上有电视机,然后两个假装手里有遥控器,还能换台。这个王八蛋不停的换台,我说他,他还不听,后来我们就打了起来。
老师在课堂上对小明提问,小明站起来却一声不吭。
老师:小明?
老师:小明??
老师:小明!你怎么回事啊?你到底知不知道答案啊?好歹吱一声啊!
小明:吱~
三只小兔拉便便
第一只是长条的 。
第二只是圆球的。
第三只居然是三角形的 。
问,它答:我用手捏的。
牛给羊打电话,
羊问:"你谁?"
牛说:"我cow"
羊问:靠,你谁啊?
牛:靠,我cow

犯人被执行枪决,由于子弹质量不好,第一枪没响,接着又开了第二枪。。。第三枪。。。这时犯人哭了,抱着法警的大腿说:大哥你掐死我把!太他妈吓人了.....

"有没有听过大猪说有,小猪说没有的"笑话 一般人都会回答没有的

2009年6月22日星期一

10 大颇具智慧的毕业典礼演讲

导读:美国知名科技博客今天撰文,列举了最具智慧的 10 次毕业典礼演讲,其中包括苹果 CEO 乔布斯的"求知若饥,虚心若愚"(Stay Hungry. Stay Foolish)等著名片段。
1. 苹果 CEO 史蒂夫〃乔布斯(Steve Jobs),2005 年,斯坦福大学
精彩语录:当我十七岁的时候,我读到了一句话:"如果你把每一天都当作生命中最后一天去生活的话,那么有一天你会发现你是正确的。"这句话给我留下了深刻的印象。从那时起的 33 年内,我在每天早晨都会对着镜子问自己:"如果今天是我生命中的最后一天,你会不会完成你今天想做的事情呢?"当答案连续多次都是"不"的时候,我知道自己需要改变某些事情了。
"记住你即将死去"是我一生中遇到的最重要箴言,它帮我指明了生命中重要的选择。因为几乎所有的事情,包括所有的荣誉、所有的骄傲、所有对难堪和失败的恐惧,都会在死亡面前消失。
没有人愿意死,即使人们想上天堂,人们也不会为了去那里而死。但是死亡是我们每个人共同的终点,从来没有人能够逃脱它。……因为死亡就是生命中最好的一个发明。
你们的时间很有限,所以不要将它们浪费在重复其他人的生活上。不要被教条束缚,那意味着你和其他人思考的结果一起生活。不要被其他人喧嚣的观点掩盖你真正的内心的声音。最重要的是,你要有勇气去听从你直觉和心灵的指示――它们在某种程度上知道你想要成为什么样子,所有其他的事情都是次要的。
求知若饥,虚心若愚。
2. 亚马逊 CEO 杰夫〃贝索斯((Jeff Bezos),2008 年,卡耐基〃梅隆大学
精彩语录:成功人士关注他们所喜欢的事情,并等待这个世界呈现在他们面前,而另外一种做法,即追逐当时的热点则是一条艰难之旅。在 1999 年互联网淘金热时,我看到许多人对电脑、技术并没有真正的兴趣,对真正的商业利益和安心挖掘互联网的价值没有真正的兴趣。你会发现自己与一批有着更多激情的人同场竞技非常危险。
3. 全球最富有的作家、《哈利波特》作者 J〃K〃罗琳,2008 年,哈佛大学
精彩语录:你们可能从未象我这样经历过如此多的失败,但生命中必然存在失败。没有人可以永远成功,除非你象根本没有活着一样地小心生活――而这根本就是一种彻头彻尾的失败。
4. 微软创始人兼董事长比尔〃盖茨(Bill Gates),2007 年,哈佛大学
精彩语录:人类最大的进步并不是表现在科技的发现和发明上,而是表现在如何用它来消除不平等。
5. 谷歌创始人拉里〃佩奇(Larry Page),2009 年,密歇根大学
精彩语录:我们中的许多人都很幸运地举家前来这里,我们中有些人有亲密的朋友和家人,也许你们当中的一些人就像露茜(Lucy)和我一样,正在梦想着建立自己未来的家庭。和我一样,你的家庭将你们带到这里,你将你的家庭带到这里。请关心你的家人,同时记住:他们才是生命中真正重要的。
6. 谷歌 CEO 埃里克〃施密特(Eric Schmidt),2009 年,宾夕法尼亚大学
精彩语录:我们的目标是让你们尽可能地与与电脑连接在一起,但也要知道哪里可以关闭电脑。你可能在电脑中打发时间,但生命在于你周围的人。这些工具有着巨大的影响力,使用它们,然后关闭它们,多和周围的人交流。
7. 维亚康姆董事长雷石东(Sumner Redstone),2002 年,凯洛格商学院
精彩语录:如果你在 28 岁时悲叹命运的不幸,你应该听从下面这三条来自一位在过去 50 年中从来没有悲叹过的人的忠告:
- 机会从来不会主动敲门;
- 追逐梦想,但立足现实
- 这与财富无关,而是与成功有关
8. 谷歌全球销售高级副总裁奥米德〃柯德斯塔尼(Omid Kordestani),2007年,圣何塞州立大学
精彩语录:为了保持我的敏锐,我必须象移民一样思考和行动,他们的乐观和动力让我受益匪浅。移民是天生的梦想家和斗士。
9. 1999-2005 年惠普 CEO 卡莉〃菲奥莉娜(Carly Fiorina),2004 年,加州理工学院
精彩语录:什么才能称得上你们这一代的伟大之处?我认为是使用你们在这里所学的知识,不仅仅是找到与计算机连接的方式,而且找到与人的连接方式;不仅仅是架设桥梁填补技术间的鸿沟,更是架设文化间的桥梁;不仅仅是使用数字和公式创造,更是使用语言去引领。在这个过程中,填补愚昧与智慧间的差距。
10. 通用电气 CEO 杰夫〃伊梅尔特(Jeff Immelt),2007 年,圣母大学
精彩语录:通过你的决心让自己脱颖而出,努力锻炼自己的能力,为生活设定一个目的,你将定义你自己的目标。努力工作并实现你的梦想。

弹性――巴菲特、李嘉诚成功的共同秘诀

今天下午听了朗咸平在上海经济论坛的一个演讲。他在当中提到,李嘉诚成功的最大秘诀是保有最大的弹性。即平时持有大量的现金,保持很低的负债比例,20%左右,关键时刻往上冲,提高负债比例,增加企业的资金,一下子把竞争对手打败。他一生最大的两次投资是港灯和和记黄埔。他有今天的成就,主要靠这两次成功的收购,否则现在只能在北京某个高校读EMBA。
一次是港灯的收购,当时负债20%不到,竞争对手的负债已经达到90%,李嘉诚把负债从20%上冲到90%,把对手打败;收购成功后,又慢慢把负债降到20%以内,保持充足的弹性。另一次是收购和记黄埔,也是如此。
回顾巴菲特的成功,保有充足的弹性也是重要秘诀。
在1973经济危机前几年,巴菲特就结束了合伙企业,积累了大量的现金,在1973年的危机中以内在价值四分之一的低价成为华盛顿邮报的大股东。
在1987年的金融危机前,巴菲特除了首都/美国广播公司、盖可保险和华盛顿邮报三家公司的股票宣布永久持有外,其他大部分股票都已经清仓,积累了充足的弹药。危机爆发后,在1988和1989年得以趁机投巨资成为可口可乐的第一大股东。
在本次全球金融危机前,巴菲特也通过伯克希尔的保险事业和其他子公司,积累了上千亿美元的现金等价物和固定收益证券,维持了直布罗陀般的财务状况,拥有巨量超额的流动性、很低短期债务和多元化的收益及现金来源,弹性十足。2008年危机深化后,在大多数金融机构现金匮乏、摇摇欲坠的危局下,扮演拯救者的角色,从容出手,抓住了条件优厚的高盛、通用的可转换优先股等巨大投资机会。
和李嘉诚相比,巴菲特的弹性更强,更安全,成功率更高。李嘉诚的弹性靠的是平时积累现金、降低负债,关键时刻加大负债比例来实现"蛇吞象"。李嘉诚当时靠长实集团6.93亿资产控制了65亿的和记黄埔,是典型的"蛇吞象"的手法,一旦出现意外情况或消化不良,还是有全盘失败的可能。而巴菲特靠的是巨量低成本保险浮存和多元化的收益及现金来源来保有充足的弹性,无论投资、收购前后,负债比例都维持在很低的水平,即是出现意外和消化不良,也可以从容化解,不会危及全局,安全边际更大。
简而言之,股市泡沫、经济繁荣时,注意积累现金,降低负债,保有弹性,耐心等待,是应对危机、抓住机遇、取得成功的法宝。

读懂公司财务的4要4不要 ---秦荣生

年报要看上市公司有什么样的资产、什么样的利润、什么样的现金流和股东权益。
  中国上市公司的财务会计问题,伴随着新会计准则体系的实施和2008年全球金融危机的冲击,变得越来越难以捉摸,考验着新会计准则的生命力和投资者的理解力。
  考虑对上市公司影响深远的相关因素,要读懂年报,主要体现在以下几个方面:
  看公司拥有什么样的资产,而不是利润的高低
  分析企业盈利能力和股东财富的变化时,报表使用者更多地关注利润表,而关注资产负债表较少。会计利润的大小容易被公司管理者操纵,因为许多会计技巧的使用都可轻而易举地改变会计利润,使利润数字本身的价值受到贬损。
  所以,不论是分析企业的财务状况,还是考核企业业绩,报表使用者都需要更多地关注资产负债表各项目的构成和变动。如果上市公司一方面有较高的利润,另 一方面却呈现存货,特别是产成品、半成品增加,应收账款余额大量增加趋势,表明虚高的利润是以出现大量的不良资产为代价。存货太多,应收账款回收过慢,导 致公司不得不通过借贷、委托理财、变卖资产等方式来增加日常运营所需资金,公司持续发展能力存在问题。
  看公司拥有什么样的利润,而不是利润总额
  上市公司应有明确的主营业务,其营业收入和利润应主要来自于主营业务,而不是主要来自于非经常性损益和合并财务报表范围以外的投资收益。
  在现行会计核算体系下,上市公司持有的金融资产无论是否售出,都必须按照公允价值计量。这样,对于已售的金融资产确认投资收益,对于未销售的金融资产,按照公允价值确认当期利润或损失。所以,现行利润的概念是企业的全面收益,营业利润仅仅是其中的一部分。
  2008年因受全球金融危机的冲击,一些上市公司为维护自己的市场形象,在年报中利用短期投资收益、股权转让收益、营业外收入与营业外支出、债务重 组、资产重组等非经常性损益填充业绩,从2008年年报中不难发现他们操纵的痕迹,其扭亏"工作",也是八仙过海,各显神通,这主要是因为我国的证券市场 机制尚不健全,监管不到位,亏损公司只有"制造"出非经常性损益来进行盈余管理,以达到其预期目标。
  看公司拥有什么样的现金流,而不是现金流总额
  阅读年报,看懂现金流量结构十分重要,总量相同的现金流量在经营活动、投资活动、筹资活动之间分布不同,则意味着不同的财务状况。一般情况下:
  1、当经营活动现金净流量为负数,投资活动现金净流量为负数,筹资活动现金净流量为正数时,表明该上市公司处于产品初创期。这个阶段上市公司需投入大量资金形成生产能力,开拓市场,其资金来源只有举债、融资等筹资活动。
  2、当经营活动现金净流量为正数,投资活动现金净流量为负数,筹资活动现金净流量为正数时,可以判断企业处于高速发展期。这时产品迅速占领市场,表现 为经营活动中大量货币资金回笼,同时为了扩大市场份额,企业仍需要大量追加投资,而仅靠经营活动现金流量净额可能无法满足所需投资,必须筹集必要的外部资 金作为补充。
  3、当经营活动现金净流量为正数,投资活动现金净流量为正数,筹资活动现金净流量为负数时,表明企业进入产品成熟期。在这个阶段产品销售市场稳定,已进入投资回收期,但很多外部资金需要偿还,以保持企业良好的资信程度。
  4、当经营活动现金净流量为负数,投资活动现金净流量为正数,筹资活动现金净流量为负数时,可以认为企业处于衰退期。其特征是:产品销售市场占有率下降,经营活动现金流入小于流出,同时企业为了应付债务不得不大规模收回投资以弥补现金不足。
  因此,在对年报进行分析时必须关注上市公司现金流量,了解上市公司利润中的收现成份,以及在投资过程、筹资过程中现金收入和使用的情况,以此来判断企 业真正的收益能力,进行投资决策;规避因企业盈余管理及选用不同会计政策,而造成的每股收益比同行上市公司高所带来的误导投资风险。
  看公司拥有什么样的股东权益,而不是权益总额
  股东权益是一个很重要的财务指标。当总资产小于负债时,公司就陷入了资不抵债的境地,这时,公司的股东权益便消失殆尽。如果实施破产清算,股东将一无所得。相反,股东权益金额越大,该公司的实力就越雄厚。
  在新会计准则实施后,由于公允价值概念全面引入,财务报表中股东权益的数据在很多时候都不能很好地反映股东投入这一基本范畴,从而使财务指标偏离了常规意义上的经济内涵。
  据有关规定,上市公司法定资产重估增值按法定程序可办理增资并增加股东权益。但由于目前我国的评估标准政出多门不统一,确认重估价值弹性大,有些上市 公司便乘机将法定资产重估,不切实际地夸大资产价值,然后把增值的"水分"转增股东权益。因此,如果上市公司中大量资本公积是由于法定资产重估增值所形成 的,那么就客观存在着股东权益的虚假现象。

财报新思维:三切入点和自由现金流量 ---黄世忠

从利润表、资产负债表、现金流量表分析盈利质量、资产质量、现金流,
  我在浙大EMBA的课堂上,曾经为学员们反复强调着一个概念"现金为王"。到底怎么来分析这四个字,我在这里结合本轮席卷全球的金融危机,谈谈我的财务报表分析的一些新思维,我们先从三大切入点入手。
   财务报表分析的三大逻辑切入点
   盈利质量、资产质量、现金流,是财务报表分析的三大逻辑切入点。
   ・从利润表入手,分析盈利质量
  通过销售收入及利润的成长性和波动性,体现主营业务收入创造现金流量的能力、市场份额增长情况以及创造现金流量的稳定性。毛利率也是盈利质量分析的重要方面,因为它表明管理层可用于研究开发、广告促销从而提高企业品牌和知名度,保证企业可持续增长的能力。
   ・从资产负债表入手,分析资产质量
  企业破产的大部分原因是资产出了问题,资产质量分析一方面通过考察流动资产和固定资产占资产总额的比重,来考察企业的财务弹性。
  如果固定资产的比重较高,而且较多的是专用设备,在行业竞争加剧的情况下,企业将面临较高的退出壁垒。另一方面要检查资产的"含金量","真金白银"和陈年老账、变价存货占资产的比重,可体现企业发生潜在损失的风险。
   ・从现金流量表着手
   对自由现金流量进行分析。这是报表分析三大逻辑切入点中最重要的一个环节,这也是本文的重点。
   现金流动速度是企业运行的风向标
  大部分发达国家的统计数据显示,每五家破产倒闭企业,有四家是盈利的,只有一家是亏损的。可见,企业主要是因为缺乏现金而倒闭,而不是因为盈利不足而消亡。
  例如,1975年美国最大的商业企业之一W.T.Grant宣告破产,而在其破产前一年,其营业净利润近1000万美元,经营活动提供营运资金 2000多万元,银行贷款达6亿美元,1973年公司股票价格仍按其收益20倍的价格出售。该企业破产的原因就在于公司早在破产前五年的现金流量净额已经 出现了负数,虽然有高额的利润,公司的现金不能支付巨额的生产性支出与债务费用,最后导致"成长性破产"。
   因此现金流量分析对企业具有举足轻重的作用。在全球金融危机的大环境下,谁手中拥有"现金"谁就能在这场危机中活下来。
  以往在对企业的发展能力来做评价时,两大指标是利润和收入。但由于利润的计量方法可以被人为地操纵,再加上有些企业为了增加利润,会相应减少产品开发研究费用,这些费用的削减只会影响企业的长远利益。
  现金流量则弥补了这些不足。在全球不景气的大环境下,现金的流动性就是决定企业运行速度的最重要的因素。而通过现金流量的管理,就可以使企业保持良好的现金流动性,提高现金的使用效率,从而将企业的资金及时地转化为生产力,提高企业的竞争力。
   自由现金流量非常重要
  当前,财务分析的教科书大多关注的是经营活动产生的现金流量,而经营活动产生的现金流量固然重要,并不代表企业可自由支配的现金流,因为企业首先要保 证自己为持续经营而进行必要投资的前提下,才能把钱用于还本付息、为股东派发股利。我的看法是,自由现金流量有被忽视的重大意义。
  自由现金流量则可反映企业总体支付能力,股权现金流量可以真实反映企业实际支付能力。两个指标综合反映了企业自身的支付能力及给予企业利益相关者的回报能力,是企业发展潜力的综合体现。因此,中国联通在其2003年计划工作会议上,就已经明确将企业自由现金流量作为对分公司发展进行考核的重要指标。
  对经营规模变动不大,而且是资本密集型的企业而言,自由现金流的最简单计算公式是经营活动产生的现金流量减去企业用于更新、改造固定资产所需投入的现金流量。

2009年6月21日星期日

交银施罗德:投资时钟下股票是2009年最好的投资品种

2007年房价涨幅就远远超过股票市场,包括很多有色金属和其他大宗商品是2007年最赚钱的投资品种。
  2008年,最好的投资品种变成债券。
  2009年,大家感觉好像又轮回到股票市场,实际上是不是这样呢?按照美林证券的投资时钟原理,经济复苏期是比较好的股票投资机会。我们国家经济处于复苏阶段,比较好的投资品种是股票。
  股票可能是目前最好的投资品种
  美林证券从100多年历史总结出来的投资时钟规律,从来没有失准过。它把经济分为四个象限,包括复苏、过热、滞涨、衰退,不同阶段有不同重点投资品种。在复苏阶段应投资股票,过热的阶段投资大宗商品,衰退的阶段要投资债券。
  看经济处于哪个阶段,主要依赖两个指标――通胀和经济增长速度。低通胀,高增长是复苏;高通胀,高增长是过热;高通胀,低增长是滞涨;低通胀,低增长是衰退。我国目前应该是低通胀的阶段,经济要么处在衰退,要么处于复苏。至于是哪个阶段就要看经济增长水平。也就是说,我们的投资要么继续是债券,要么可以开始选择股票。
  美国经济情况处于比较差的阶段,美国经济数据可能有见底的迹象,但不排除是一个短期波动的情况,复苏的过程可能会比较长。这轮经济危机中新兴市场国家受影响不大,会比美国先复苏。我国的通胀被认为是处于比较低的位置,那宏观经济要么是衰退,要么是复苏。而只要内需没有问题,经济复苏的情况应该是比较乐观的。
  因此,我国经济是处于复苏阶段,低通胀,经济增长开始复苏。这时股票是最好的投资品种。
  流动性正推升资产泡沫
  交银施罗德去年9月份第一次开始股票基金的加仓,主要原因就是判断经济可能见底。当时流动性开始放出,虽然名义GDP还是往下,但是由于货币政策放得很松,货币供应量开始增加,很多钱会流入到资本市场而推升股票市场反弹。而目前宽松的货币政策还在持续,只要政策不改变,流动性推升股市的局面不会改变。
  因此在IPO没有重启的情况下,股票价格是应该上升的。如果IPO重启之后,只要货币供应量的速度能跟上IPO的速度,股票价格还是能往上走的。

2009年6月19日星期五

获利百倍的价值投资 [读书笔记]

价值投资(Investor),而非投机(Trade)。不是利用市场不同时期估值差异产生的市盈率不同来交易获利,而是以公司成长性为出发点,逢低买进资产,注重安全边际,坚持长线投资,让优秀企业为股东赚钱。
用公司表示为:价值投资=(安全边际+成长)×时间,安全边际、成长性和持股时间为价值投资三要素;以坚忍的毅力为中心,以合理安全边际和高成长为两个基本点,坚持一手抓安全边际,一手抓成长,两手都要抓,两手都要硬。
价值投资区别于别的投资流派在于坚持以下几个出发点:
(1)、投资人是不理性的,他们常常深受股票可能下跌的恐惧和期望股票价格上扬的贪婪所影响。
(2)、市场不是有效率的,愿意学习研究的投资人完全有可能打败市场。
(3)、风险并非源自于价格波动,而是由企业本身的内在价值决定的。
(4)、最好的投资策略是把资金重押在少数获利前景最高的价值投资组合上。

价值投资目标:不为未来只能上涨一点点的原因而买进,而是要为未来两年内可能上涨50%,5年上涨100%,15年能涨10倍或20倍买进股票。费雪在他的《怎样选择成长股》中写道:"找到真正杰出的公司,抱牢它们的股票,度过市场的波动起伏,不为所动,也远远比买低卖高的做法赚得多。"
价值投资要求:价值投资,知易行难,需要一种信念,甚至说是一种信仰。需要忍耐孤独、寂寞,抑制诱惑;"手中有股,心中无股,心中有企业"为其最高境界。不要求会技术分析,不需要波段操作技能,不进行短线投机这种零和游戏。
价值投资的六项法则(摘于网络):
第一法则:竞争优势原则
好公司才有好股票:那些业务清晰易懂,业绩持续优秀并且由一批能力非凡的、能够为股东利益着想的管理层经营的大公司就是好公司。
最正确的公司分析角度-----如果你是公司的唯一所有者。
最关键的投资分析----企业的竞争优势及可持续性。
最佳竞争优势----游着鳄鱼的很宽的护城河保护下的企业经济城堡。
最佳竞争优势衡量标准----超出产业平均水平的股东权益报酬率。
经济特许权-----超级明星企业的超级利润之源。
选股如同选老婆----价格好不如公司好。
选股如同选老公:神秘感不如安全感
第二法则:现金流量原则
新建一家制药厂与收购一家制药厂的价值比较。
价值评估既是艺术,又是科学。
估值就是估老公:越赚钱越值钱
估值就是估老婆:越保守越可靠
巴菲特主要采用股东权益报酬率、帐面价值增长率来分析未来可持续盈利能力的。
估值就是估爱情:越简单越正确
第三法则:"市场先生"原则
在别人恐惧时贪婪,在别人贪婪时恐惧
市场中的价值规律:短期经常无效但长期趋于有效。
第四法则:安全边际原则
安全边际就是"买保险":保险越多,亏损的可能性越小。
安全边际就是"猛砍价":买价越低,盈利可能性越大。
安全边际就是"钓大鱼":人越少,钓大鱼的可能性越高。
第五法则:集中投资原则
集中投资就是一夫一妻制:最优秀、最了解、最小风险。
集中投资就是计划生育:股票越少,组合业绩越好。
集中投资就是赌博:当赢的概率高时下大赌注。
第六法则:长期持有原则
长期持有就是龟兔赛跑:长期内复利可以战胜一切。
长期持有就是海誓山盟:与喜欢的公司终生相伴。
长期持有就是白头偕老:专情比多情幸福10000倍。
选股原则:
(1)、产业原则。公司业务要单纯,易于理解;有持续增长的营运记录;有长期的发展潜力。
(2)、经营原则。经营者理念要合理;对股东要坦白诚信。
(3)、财务原则。重视股东报酬率而非每股盈余;毛利率高,确定公司一元的保留盈余,最少要能创造一元的市值。
价值投资操作:买进后不轻易买出,不动股,坚持到底,个股的基本面没有出现问题就坚持持股,经济出现问题影响到个股不是卖出股票的理由。一旦经济变好了,那这股票就更加强大了,经济危机只会使平庸企业倒了。
价值投资手段:买进3-10只长期获利高于市场水平的绩优股、小盘成长股、然后耐心地持有5年、10年甚至20年,再关注它们。
价值投资格言:
消费的钱能少,投资的钱一分都不能动;
人生就像滚雪球,最重要之事是发现足够湿的雪和长长的坡。
今天的做法,决定了你十年以后的活法!