Wednesday, July 30, 2008
Monday, July 28, 2008
You've got to find what you love_Steve Jobs
'You've got to find what you love,' Jobs says
Printable Version
This is the text of the Commencement address by Steve Jobs, CEO of Apple Computer and of Pixar Animation Studios, delivered on June 12, 2005.
I am honored to be with you today at your commencement from one of the finest universities in the world. I never graduated from college. Truth be told, this is the closest I've ever gotten to a college graduation. Today I want to tell you three stories from my life. That's it. No big deal. Just three stories.
The first story is about connecting the dots.
I dropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why did I drop out?
It started before I was born. My biological mother was a young, unwed college graduate student, and she decided to put me up for adoption. She felt very strongly that I should be adopted by college graduates, so everything was all set for me to be adopted at birth by a lawyer and his wife. Except that when I popped out they decided at the last minute that they really wanted a girl. So my parents, who were on a waiting list, got a call in the middle of the night asking: "We have an unexpected baby boy; do you want him?" They said: "Of course." My biological mother later found out that my mother had never graduated from college and that my father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents promised that I would someday go to college.
And 17 years later I did go to college. But I naively chose a college that was almost as expensive as Stanford, and all of my working-class parents' savings were being spent on my college tuition. After six months, I couldn't see the value in it. I had no idea what I wanted to do with my life and no idea how college was going to help me figure it out. And here I was spending all of the money my parents had saved their entire life. So I decided to drop out and trust that it would all work out OK. It was pretty scary at the time, but looking back it was one of the best decisions I ever made. The minute I dropped out I could stop taking the required classes that didn't interest me, and begin dropping in on the ones that looked interesting.
It wasn't all romantic. I didn't have a dorm room, so I slept on the floor in friends' rooms, I returned coke bottles for the 5¢ deposits to buy food with, and I would walk the 7 miles across town every Sunday night to get one good meal a week at the Hare Krishna temple. I loved it. And much of what I stumbled into by following my curiosity and intuition turned out to be priceless later on. Let me give you one example:
Reed College at that time offered perhaps the best calligraphy instruction in the country. Throughout the campus every poster, every label on every drawer, was beautifully hand calligraphed. Because I had dropped out and didn't have to take the normal classes, I decided to take a calligraphy class to learn how to do this. I learned about serif and san serif typefaces, about varying the amount of space between different letter combinations, about what makes great typography great. It was beautiful, historical, artistically subtle in a way that science can't capture, and I found it fascinating.
None of this had even a hope of any practical application in my life. But ten years later, when we were designing the first Macintosh computer, it all came back to me. And we designed it all into the Mac. It was the first computer with beautiful typography. If I had never dropped in on that single course in college, the Mac would have never had multiple typefaces or proportionally spaced fonts. And since Windows just copied the Mac, its likely that no personal computer would have them. If I had never dropped out, I would have never dropped in on this calligraphy class, and personal computers might not have the wonderful typography that they do. Of course it was impossible to connect the dots looking forward when I was in college. But it was very, very clear looking backwards ten years later.
Again, you can't connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something — your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.
My second story is about love and loss.
I was lucky — I found what I loved to do early in life. Woz and I started Apple in my parents garage when I was 20. We worked hard, and in 10 years Apple had grown from just the two of us in a garage into a $2 billion company with over 4000 employees. We had just released our finest creation — the Macintosh — a year earlier, and I had just turned 30. And then I got fired. How can you get fired from a company you started? Well, as Apple grew we hired someone who I thought was very talented to run the company with me, and for the first year or so things went well. But then our visions of the future began to diverge and eventually we had a falling out. When we did, our Board of Directors sided with him. So at 30 I was out. And very publicly out. What had been the focus of my entire adult life was gone, and it was devastating.
I really didn't know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down - that I had dropped the baton as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and I even thought about running away from the valley. But something slowly began to dawn on me — I still loved what I did. The turn of events at Apple had not changed that one bit. I had been rejected, but I was still in love. And so I decided to start over.
I didn't see it then, but it turned out that getting fired from Apple was the best thing that could have ever happened to me. The heaviness of being successful was replaced by the lightness of being a beginner again, less sure about everything. It freed me to enter one of the most creative periods of my life.
During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I returned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.
I'm pretty sure none of this would have happened if I hadn't been fired from Apple. It was awful tasting medicine, but I guess the patient needed it. Sometimes life hits you in the head with a brick. Don't lose faith. I'm convinced that the only thing that kept me going was that I loved what I did. You've got to find what you love. And that is as true for your work as it is for your lovers. Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven't found it yet, keep looking. Don't settle. As with all matters of the heart, you'll know when you find it. And, like any great relationship, it just gets better and better as the years roll on. So keep looking until you find it. Don't settle.
My third story is about death.
When I was 17, I read a quote that went something like: "If you live each day as if it was your last, someday you'll most certainly be right." It made an impression on me, and since then, for the past 33 years, I have looked in the mirror every morning and asked myself: "If today were the last day of my life, would I want to do what I am about to do today?" And whenever the answer has been "No" for too many days in a row, I know I need to change something.
Remembering that I'll be dead soon is the most important tool I've ever encountered to help me make the big choices in life. Because almost everything — all external expectations, all pride, all fear of embarrassment or failure - these things just fall away in the face of death, leaving only what is truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are already naked. There is no reason not to follow your heart.
About a year ago I was diagnosed with cancer. I had a scan at 7:30 in the morning, and it clearly showed a tumor on my pancreas. I didn't even know what a pancreas was. The doctors told me this was almost certainly a type of cancer that is incurable, and that I should expect to live no longer than three to six months. My doctor advised me to go home and get my affairs in order, which is doctor's code for prepare to die. It means to try to tell your kids everything you thought you'd have the next 10 years to tell them in just a few months. It means to make sure everything is buttoned up so that it will be as easy as possible for your family. It means to say your goodbyes.
I lived with that diagnosis all day. Later that evening I had a biopsy, where they stuck an endoscope down my throat, through my stomach and into my intestines, put a needle into my pancreas and got a few cells from the tumor. I was sedated, but my wife, who was there, told me that when they viewed the cells under a microscope the doctors started crying because it turned out to be a very rare form of pancreatic cancer that is curable with surgery. I had the surgery and I'm fine now.
This was the closest I've been to facing death, and I hope its the closest I get for a few more decades. Having lived through it, I can now say this to you with a bit more certainty than when death was a useful but purely intellectual concept:
No one wants to die. Even people who want to go to heaven don't want to die to get there. And yet death is the destination we all share. No one has ever escaped it. And that is as it should be, because Death is very likely the single best invention of Life. It is Life's change agent. It clears out the old to make way for the new. Right now the new is you, but someday not too long from now, you will gradually become the old and be cleared away. Sorry to be so dramatic, but it is quite true.
Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma — which is living with the results of other people's thinking. Don't let the noise of others' opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.
When I was young, there was an amazing publication called The Whole Earth Catalog, which was one of the bibles of my generation. It was created by a fellow named Stewart Brand not far from here in Menlo Park, and he brought it to life with his poetic touch. This was in the late 1960's, before personal computers and desktop publishing, so it was all made with typewriters, scissors, and polaroid cameras. It was sort of like Google in paperback form, 35 years before Google came along: it was idealistic, and overflowing with neat tools and great notions.
Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find yourself hitchhiking on if you were so adventurous. Beneath it were the words: "Stay Hungry. Stay Foolish." It was their farewell message as they signed off. Stay Hungry. Stay Foolish. And I have always wished that for myself. And now, as you graduate to begin anew, I wish that for you.Publish Post
Stay Hungry. Stay Foolish.
Thank you all very much.
今天,有荣幸来到各位从世界上最好的学校之一毕业的毕业典礼上。
我从来没从大学毕业。说实话,这是我离大学毕业最近的一刻。
今天,我只说三个故事,不谈大道理,三个故事就好。
第一个故事,是关于人生中的点点滴滴怎么串连在一起。
我在里德学院(Reedcollege)待了六个月就办休学了。到我退学前,一共休学了十八个月。那么,我为什么休学?
这 得从我出生前讲起。我的亲生母亲当时是个研究生,年轻未婚妈妈,她决定让别人收养我。她强烈觉得应该让有大学毕业的人收养我,所以我出生时,她就准备让我 被一对律师夫妇收养。但是这对夫妻到了最后一刻反悔了,他们想收养女孩。所以在等待收养名单上的一对夫妻,我的养父母,在一天半夜里接到一通电话,问他们 「有一名意外出生的男孩,你们要认养他吗?」而他们的回答是「当然要」。后来,我的生母发现,我现在的妈妈从来没有大学毕业,我现在的爸爸则连高中毕业也 没有。她拒绝在认养文件上做最后签字。直到几个月后,我的养父母同意将来一定会让我上大学,她才软化态度。
十七年后,我上大学了。但是当时我无知选了一所学费几乎跟史丹佛一样贵的大学,我那工人阶级的父母所有积蓄都花在我的学费上。六个月后,我看不出念这个书的价值何在。那时候,我不知道这辈子要乾什么,也不知道念大学能对我有什么帮助,而且我为了念这个书,
花 光了我父母这辈子的所有积蓄,所以我决定休学,相信船到桥头自然直。当时这个决定看来相当可怕,可是现在看来,那是我这辈子做过最好的决定之一。当我休学 之后,我再也不用上我没兴趣的必修课,把时间拿去听那些我有兴趣的课。这一点也不浪漫。我没有宿舍,所以我睡在友人家里的地板上,靠着回收可乐空罐的五先 令退费买吃的,每个星期天晚上得走七哩的路绕过大半个镇去印度教的Hare Krishna 神庙吃顿好料。我喜欢HareKrishna神庙的好料。追寻我的好奇与直觉,我所驻足的大部分事物,后来看来都成了无价之宝。
举例来说:
当 时里德学院有着大概是全国最好的书法指导。在整个校园内的每一张海报上,每个抽屉的标签上,都是美丽的手写字。因为我休学了,可以不照正常选课程序来,所 以我跑去学书法。我学了serif 与san serif 字体,学到在不同字母组合间变更字间距,学到活版印刷伟大的地方。书法的美好、历史感与艺术感是科学所无法捕捉的,我觉得那很迷人。我没预期过学的这些东 西能在我生活中起些什么实际作用,不过十年后,当我在设计第一台麦金塔时,我想起了当时所学的东西,所以把这些东西都设计进了麦金塔里,这是第一台能印刷 出漂亮东西的计算机。如果我没沉溺于那样一门课里,麦金塔可能就不会有多重字体跟变间距字体了。又因为Windows抄袭了麦金塔的使 用方式,如果当年我没这样做,大概世界上所有的个人计算机都不会有这些东西,印不出现在我们看到的漂亮的字来了。当然,当我还在大学里时,不可能把这些点 点滴滴预先串在一起,但是这在十年后回顾,就显得非常清楚。我再说一次,你不能预先把点点滴滴串在一起;唯有未来回顾时,你才会明白那些点点滴滴是如何串 在一起的。
所以你得相信,你现在所体会的东西,将来多少会连接在一块。你得信任某个东西,直觉也好,命运也好,生命也好,或者业力。这种作法从来没让我失望,也让我的人生整个不同起来。
我的第二个故事,有关爱与失去。
我 好运-年轻时就发现自己爱做什么事。我二十岁时,跟Steve Wozniak在我爸妈的车库里开始了苹果计算机的事业。我们拼命工作,苹果计算机在十年间从一间车库里的两个小伙子扩展成了一家员工超过四千人、市价二 十亿美金的公司,在那之前一年推出了我们最棒的作品-麦金塔,而我才刚迈入人生的第三十个年头,然后被炒鱿鱼。
要怎么让自己创办的公司炒自己鱿鱼?
好 吧,当苹果计算机成长后,我请了一个我以为他在经营公司上很有才乾的家伙来,他在头几年也确实乾得不错。可是我们对未来的愿景不同,最后只好分道扬镳,董 事会站在他那边,炒了我鱿鱼,公开把我请了出去。曾经是我整个成年生活重心的东西不见了,令我不知所措。有几个月,我实在不知道要乾什么好。我觉得我令企 业界的前辈们失望-我把他们交给我的接力棒弄丢了。我见了创办HP的David Packard跟创办Intel的Bob Noyce,跟他们说我很抱歉把事情搞砸得很厉害了。我成了公众的非常负面示范,我甚至想要离开硅谷。但是渐渐的,我发现,我还是喜爱着我做过的事情,在 苹果的日子经历的事件没有丝毫改变我爱做的事。我被否定了,可是我还是爱做那些事情,所以我决定从头来过。
当时我没发现,但是现在看来, 被苹果计算机开除,是我所经历过最好的事情。成功的沉重被从头来过的轻松所取代,每件事情都不那么确定,让我自由进入这辈子最有创意的年代。接下来五年, 我开了一家叫做 NeXT的公司,又开一家叫做Pixar的公司,也跟后来的老婆谈起了恋爱。Pixar接着制作了世界上第一部全计算机动画电影,玩具总动员,现在是世界 上 最成功的动画制作公司。然后,苹果计算机买下了NeXT,我回到了苹果,我们在NeXT发展的技术成了苹果计算机后来复兴的核心。我也有了个美妙的家庭。
我 很确定,如果当年苹果计算机没开除我,就不会发生这些事情。这帖药很苦口,可是我想苹果计算机这个病人需要这帖药。有时候,人生会用砖头打你的头。不要丧 失信心。我确信,我爱我所做的事情,这就是这些年来让我继续走下去的唯一理由。你得找出你爱的,工作上是如此,对情人也是如此。
你的工作将填满你的一大块人生,唯一获得真正满足的方法就是做你相信是伟大的工作,而唯一做伟大工作的方法是爱你所做的事。如果你还没找到这些事,继续找,别停顿。尽你全心全力,你知道你一定会找到。而且,如同任何伟大的关系,事情只会随着时间愈来愈好。
所以,在你找到之前,继续找,别停顿。
我的第三个故事,关于死亡。
当 我十七岁时,我读到一则格言,好像是「把每一天都当成生命中的最后一天,你就会轻松自在。」这对我影响深远,在过去33年里,我每天早上都会照镜子,自 问:「如果今天是此生最后一日,我今天要乾些什么?」每当我连续太多天都得到一个「没事做」的答案时,我就知道我必须有所变革了。提醒自己快死了,是我在 人生中下重大决定时,所用过最重要的工具。因为几乎每件事-所有外界期望、所有名誉、所有对困窘或失败的恐惧-在面对死亡时,都消失了,只有最重要的东西 才会留下。提醒自己快死了,是我所知避免掉入自己有东西要失去了的陷阱里最好的方法。
人生不带来,死不带去,没什么道理不顺心而为。
一 年前,我被诊断出癌症。我在早上七点半作断层扫描,在胰脏清楚出现一个肿瘤,我连胰脏是什么都不知道。医生告诉我,那几乎可以确定是一种不治之症,我大概 活不到三到六个月了。医生建议我回家,好好跟亲人们聚一聚,这是医生对临终病人的标准建议。那代表你得试着在几个月内把你将来十年想跟小孩讲的话讲完。那 代表你得把每件事情搞定,家人才会尽量轻松。那代表你得跟人说再见了。我整天想着那个诊断结果,那天晚上做了一次切片,从喉咙伸入一个内视镜,从胃进肠 子,插了根针进胰脏,取了一些肿瘤细胞出来。我打了镇静剂,不醒人事,但是我老婆在场。她后来跟我说,当医生们用显微镜看过那些细胞后,他们都哭了,因为 那是非常少见的一种胰脏癌,可以用手术治好。所以我接受了手术,康复了。
这是我最接近死亡的时候,我希望那会继续是未来几十年内最接近的一次。经历此事后,我可以比之前死亡只是抽象概念时要更肯定告诉你们下面这些:
没 有人想死。即使那些想上天堂的人,也想活着上天堂。但是死亡是我们共有的目的地,没有人逃得过。这是注定的,因为死亡简直就是生命中最棒的发明,是生命变 化的媒介,送走老人们,给新生代留下空间。现在你们是新生代,但是不久的将来,你们也会逐渐变老,被送出人生的舞台。抱歉讲得这么戏剧化,但是这是真的。
你们的时间有限,所以不要浪费时间活在别人的生活里。不要被信条所惑-盲从信条就是活在别人思考结果里。不要让别人的意见淹没了你内在的心声。最重要的,拥有跟随内心与直觉的勇气,你的内心与直觉多少已经知道你真正想要成为什么样的人。任何其它事物都是次要的。
在 我年轻时,有本神奇的杂志叫做 Whole Earth Catalog,当年我们很迷这本杂志。那是一位住在离这不远的Menlo Park的Stewart Brand发行的,他把杂志办得很有诗意。那是1960年代末期,个人计算机跟桌上出版还没发明,所有内容都是打字机、剪刀跟拍立得相机做出来的。
杂 志内容有点像印在纸上的Google,在Google出现之前35年就有了:理想化,充满新奇工具与神奇的注记。Stewart跟他的出版团队出了好几 期Whole Earth Catalog,然后出了停刊号。当时是1970年代中期,我正是你们现在这个年龄的时候。在停刊号的封底,有张早晨乡间小路的照片,那种你去爬山时会经 过的乡间小路。
在照片下有行小字:
求知若饥,虚心若愚。
那是他们亲笔写下的告别讯息,我总是以此自许。
当你们毕业,展开新生活,我也以此期许你们。
求知若饥,虚心若愚。
非常谢谢大家。
Thursday, July 24, 2008
IO Benchmark
Bonnie++ - NEW!
Greatly improved disk I/O benchmark based on the code for Bonnie by Tim Bray. Bonnie++, rewritten in C++ by Russell Coker (russell@coker.com.au), adds the facility to test more than 2Gb of storage on 32-bit machines, and tests for file creat(), stat(), unlink() operations.
Bonnie v.2.0.6
One of the best "open systems" benchmarks available. It can be compiled under different UNIX flavors. We have successfully run it under SCO UNIX, Linux, Solaris, and BSDI. It should also compile with minimal changes under other UNIXes.
IOzone - UPDATED
Another great benchmark, in our opinion. The benchmark generates and measures a variety of file operations. IOzone is useful for performing broad filesystem analysis of a vendor's computer platform. It can also be used for NFS performance testing and the latest version now supports cluster testing as well. IOzone had been ported to numerous UNIX OSes and Windows NT. Read more about it and download the source by clicking on the link above.
Xbench - NEW!
Xbench is a a comprehensive benchmarking solution for Mac OS X. In addition to various system component benchmarks, it provides performance testing capabilities for sequential and random uncached disk I/O performance.
IOstone v. C/II
IOstone is a multi-platform disk, file I/O and buffer cache efficiencies benchmark program. This benchmark was originally created for UNIX and later ported to OS/2 and DOS. Included in this archive are the OS/2 and DOS executables with source code.
Disktest
Disktest allows any direct access device (and some sequential devices) to be tested while UNIX is still available to other users. Care should be taken to make the device which is to be tested unavailable to other system users.
IOBENCH
Excellent I/O throughput and fixed workload benchmark for UNIX. There are two versions of IOBENCH contained in sub-directories of this directory. These two versions contain the same source files and differ only in the scripts that drive the benchmark. Directory 073.iobench contains the throughput variant; directory 084.iobenchpf contains the fixed workload variant. This is the SPEC 2.6 distribution of IOBENCH.
IOCALL
IOCALL measures OS performance, in fact that is nearly all it measures. It also concentrates on system call interface efficiency, and especially read() system call performance, the most used system call on most systems. IOCALL is intended for UNIX systems only.
RawIO - NEW
Low-level raw device benchmarking program written by Greg Lehey, the author of the book "The Complete FreeBSD", published by Walnut Creek. This benchmark will only compile under BSD as it uses BSD specific mmap() call. Port to Linux is currently in progress.
A new benchmark to measure performance of e-mail, netnews, and e-commerce classes of applications. PostMark was created to simulate heavy small-file system loads with a minimal amount of software and configuration effort and to provide complete reproducibility. It can be compiled under Solaris, Digital Unix, and Win32 environments. Learn more about the PostMark and download the source code by following the link above.
Nbench
A very nice little benchmarking program for Windows NT. Nbench reports the following components of performance:
- CPU speed: integer and floating operations/sec
- L1 and L2 cache speeds: MB/sec
- main memory speed: MB/sec
- disk read and write speeds: MB/sec
NTiogen 1.03 - UPDATED
NTiogen benchmark was written by Symbios Logic. It's Windows NT port of their popular UNIX benchmark IOGEN. NTIOGEN is the parent processes that spawns the specified number of IOGEN processes that actually do the I/O.
The program will display as output the number of processes, the average response time, the number of I/O operations per second, and the number of KBytes per second.
IOmeter - UPDATED
This benchmark was originally written by Intel. Intel has discontinued the development and released the source code into public domain. SOURCEFORGE.NET is currently hosting this project. IOMETER is a disk I/O subsystem measurement and characterization tool for single and clustered systems. Iometer does for a computer's I/O subsystem what a dynamometer does for an engine: it measures performance under a controlled load. It is now available for Windows 2000, Linux, and Solaris.
Bench32
A very comprehensive benchmark that measures overall system performance under Windows NT or Windows 95. Unfortunately, the company that wrote this benchmarking program seems to have gone out of business. You can find a local copy of Bench32 v.1.21 here.
ThreadMark
A very popular benchmark written by Adaptec. Adaptec's decided that they cannot support it anymore and thus they have removed this benchmark from their web site. Click on the link to download ThreadMark from our server.
Shareware/commercial disk I/O benchmark. HD Tach is a physical performance hard drive test for Windows 95/98 and Windows NT. In Windows 95/98 it uses a special kernel mode VXD to get maximum accuracy by bypassing the file system. A similar mechanism is used in Windows NT. HD Tach reads from areas all over the hard drive and reports its average speed. It also logs the read speeds to a text file that you can load into a spreadsheet and graph to visually read the results of the test.
SCSITool - NEW
A very comprehensive diagnostics and benchmarking tool for SCSI storage devices. Currently supported device types are: harddisk, tape, cd-rom, optical and removable disks. Learn more about the SCSITool and download the program by following the link above.
RAIDmark
The only benchmark we have found that was specifically created to measure the performance of RAID arrays. RAIDmark benchmarking program by DynaTek Automation Systems Inc., measures cache size, system overhead, and application-level performance. Includes MS-DOS and Novell versions. Unfortunately, the source code is not included. As far as we know, this was the last release of RAIDmark; DynaTek no longer supports or does any development of this benchmarking program.
Qbench
DOS hard disk benchmark from Quantum Corporation which measures data access time and data transfer rate. Just a nice little benchmark for quick results. No source code included.
DOS disk benchmarking program created by CORE International. CORE Disk Performance Benchmark is distributed as a DOS binary, no source code included.
Wednesday, July 23, 2008
Tuesday, July 22, 2008
Random
int bigrand() // a 30 bits random variable
{
return RAND_MAX * rand() + rand();
}
return a random number from the range l to u
int rand(int l, int u)
{
return l + bigrand() % (u-l+1);
}
---------------------------
select with probability 2/5
bigrand() % 5 <>;
select m out of n number:
select = m
remaining = n
for i = [0, n)
******if (bigrand() % remaining ) < select
***********print i
***********select--
******remaining--
Q: Write m sorted integers random from 0...n-1
Solution-1: randomly select one number from 0 to n-1 for m times, and then sort this m element array.
Solution-2: "Shuffle card".
for i = [0, n-1)
{
swap(i, randint(i, n-1));
}
Q: read a text file and output each line randomly on the fly
always select the first line, select the second line with probability one half, the third line with probability one third and so on.
Monday, July 14, 2008
Namespace
2. Scope operators can also be used to refer to members of the global namespace. Global namespace does not have a name. ::name_in_the_globalspace
3. A nested namespace is a nested scope within the namespace that contains it. And during name resolution, nested namespace behave similarly to nested blocks. An entity declared in an enclosing namespace is hidden by an entity of the same name declared in a nested namespace. Silmiarly, an entity declared in a namespace is hidden by an entity declared in local scope.
4. Unnamed namespace is used to declare an entity locale to a file and never spans multiple text files. It is not necessary to use scope operator to refer to members of unnamed namespaces. In C, a global static is invisible outside of the file in which it is declared.
5. Namespace aliases
namespace IBM_1 = International_Business_Machines
namespace IBM_2 = International_Business_Machines
6. A name introduced by a using declaration has these characteristics:
6.1. It must be unique in its scope
6.2. It hides the same name introduced by a declaration in an enclosing scope
6.3. It is hidden by a declaration of the same name in a nested scope
Friday, July 11, 2008
Effective C++
copy constructor is used to initialize a new created object and assignment is used to initialize an already existing object.
Tricky: if you do not want others to use copy constructor and assignment operator, then just declare the functions but do not define them at all. Generally those two are enabled/disabled together.
Item 27: Explicitly disallow use of implicitly generated member functions you don't want.
Just make the functions private may not be enough, member and friend functions still can call them. But if we just declare them without definition, we will get link-time error when we try to invoke any of them.
Item 44: Say what you mean; understand what you're saying
public inheritance = isa
nonvirtual member function means invariance over specialization.
Item 45: Know what functions C++ silently writes and calls
class Empty {} is equal to
class Empty
{
Empty();
~Empty();
Empty(const Empty& rhs); //copy constructor
Empty& operator=(const Empty &); //assignment operator
Empty* operator&();
const Empty* operator&() const;
};
The compiler generated destructor is nonvirtual unless it's for a class inheriting from a base class that itself declares a virtual destructor.
c++ will refuse to generate the assignment operator for you if your class contain reference or const members. (if you think of the behaviors of assignment operator, you will see the reason)
Also c++ will refuse to generate the assignment operator for derived classes that inherit from base classes declaring the standard assignment operator private.
Item 14: Make sure base classes have virtual destructors
When you try to delete a derived class object through a base class pointer and the base class has a nonvirtual destructor, the results are undefined.
If a class does not contain any virtual functions, that is often an indication that it is not mean to be used as a base class. When a class is not intended to be used as a base class, making the destructor virtual is usually a bad idea.
One rule is declaring a virtual destructor in a class if and only if that class contains at least one virtual function. Also declare a pure virtual destructor in the class you want to be abstract. One twist: you must provide a definition for the pure virtual destructor, because this virtual destructor will definitely be called by the derived class's destructor.
Item 15: Have operator= return a reference to *this
C& C::operator=(const C &);
The return type of operator= must be acceptable as an input to the function itself, otherwise, it will prevent chains of assignments.
If we remove the const qualifier, it will prevent implicit type conversion. const-correctness: it's never legal to pass a const object to a function that fails to declare the corresponding parameter const.
Item16: Assign to all data members in operator=
Derived& Derived::operator=(const Derived & rhs)
{
if (this == &rhs) return * this;
Base::operator=(rhs); //make an explicit call to base class assignment operator= function
//*this will be still be the implicit left-hand object, just like calls to member functions within //other member functions.
y = rhs.y; // assign to data members defined in derived class
return *this;
}
One nastiest bugs in all c++-dom: it fails to copy the base class part when a derived object is copy constructed. To avoid this problem, derived's copy constructor must make sure that the Base's copy constructor is invoked instead of Base's default constructor. Just be sure to specify an initializer value for Base in the member initialization list of derived's copy constructor.
class Derived: public Base
{
//Base(rhs) will invoke base copy constructor
Derived(const Derived & rhs): Base(rhs), y(rhs.y) { }
}
Item17: Check for assignment to self in operator=
Aliasing: having two or more names for the same underlying object.
Object identity: 1) if the objects have the same value or 2) if the objects have the same address in memory or 3) write your own identity function and provide operator==.
Anytime you write a function in which aliasing could conceivably be present, you must take that possibility into account when you write the code.
Item 19: Understand the origin of temporary objects
True temporary objects in C++ are invisible and arise whenever a non-heap object is created but not named. Unnamed objects arise in one of the two situations: 1) when functions return objects and 2) when implicit type conversions are applied to make function calls succeed, these conversions occurs only when passing objects by value or when passing to a reference-to-const parameter.
Learn to look for such constructs, and your insight into the cost of "behind the scenes" compiler actions will markedly improve.
Item 20: Avoid data members in the public interface
Hide all your data members behind a wall of functional abstraction. If you implement access to a data member through a function, you can later replace the data member with a computation, and nobody using your class will be any the wiser.
Item 21: Use const whenever possible
1. Outside of classes, use it for global or namespace constants
const A * c = new A();
A* e = c;
This is wrong
A* const c = new A();
A* e = c;
This is right
2. Outside of classes, use it for static objects (local to a file or a block)
3. Inside of classes, use it for both static and nonstatic data members
const nonstatic data members are const to each independent class objects. If you want to have const data for the class, use enum. enum will not take objects' space and replaced during compilation time.
const members may only be initialized and must be initialized via initializer list, NEVER assigned. Also all the consturctors should initialize the const data members in their initializer list!
But how about const static?
4. For pointers, const char * const p = "hello";
5. Within a function declaration, const can refer to the function's return value, to individual parameters.
const int & foo (const int para) { }
6. For member functions, to the function as a whole.
6.1) Member functions differ only in their constness can be overloaded. The class object's constness decides which function will be invoked. const is part of the function signature, which mean you have to put const both in the class declaration and function definition if the definition is out of class body.
6.2) const member function can ONLY be called by const class object
6.3) constructor and destructor are exceptions and const class object could call constructor/destructor even they are not const.
6.4) a class object is constant after constructor and before destructor.
7. Mutable
bitwise constness vs conceptual constness (which shows constness only to the clients)
When applied to nonstatic data members, mutable frees those members from the constraints of bitwise constness. Mutable data members can NEVER be const, even the data members are in a const class object. Mutable data members can ALWAYS be updated, even in the const member function.
8. volatile
objects may be modified out of compiler's control, such as I/O interface data structure. Similar to const, volatile object can only invoke volatile member function, constructor and destructor.
Item 12: Prefer initialization to assignment in constructors
Construction of objects proceeds in two phases:
1. Initialization of data members
2. Execution of the body of the constructor that was called
Initialization is more efficient. We only need to call copy constructor for the data members if we use initialization list. But we have to call both default constructor and assignment operator= for the data member if we use assignment in constructors.
const and reference member can ONLY be initialized, NEVER assigned. So if we stick to initialization, we don't need to change initialization code if we later change some members to const or reference.
Item 13: List members in an initialization list in the order in which they are declared.
Rule: class members are initialized in the order of their declaration in the class. destructors for the members of an object are always called in the inverse order of their constructors. So in this way, compiler does not to keep track of the order in which the members were intialized for each object.
Only nonstatic data members are initialized according to the rule. Static data members act like global and namespace objects, so they are intialized only once.
Item 6: Use delete on pointer members in destructors
Adding a pointer member almost always requires each of the following:
1. Initialization of the pointer in EACH of the constructors. If no memory is to be allocated to the pointer in a particular constructor, the pointer should be initialized to 0.
2. Deletion of the existing memory and assignment of new memory in the assignment operator
3. Deletion of the pointer in the destructor
Item 22: Prefer pass-by-reference to pass-by-value
Pass by value: Function parameters are initialized with COPIES of the actual arguments, and function callers get back a COPY of the value returned by the function.
The meaning of passing an object by value is defined by the copy constructor of that object's class.
Pass-by-reference also avoids what is called the "slicing problem". When a derived class object is passed as a base class object, all the specialized features that make it behave like a derived class are "sliced" off, and you're left with a simple base class object, and you are left with a simple base class.
Item 23: Don't try to return a reference when you must return an object
const Rational operator*(const Rational & lhs, const Rational &rhs) { }
We can NOT return reference for the above function.
A function can only create a new object in only two ways: on the stack or on the heap. A reference is just a name, a name for some existing object.
Rational w, a, b, c;
w = a*b*c; //if we return references (to object created inside the function), memory leak
Item 29: Avoid returning "handles" to internal data
The lifetime of the temporary object returned from function will be until the end of the expression containing the call.
For const member functions, returning handles is ill-advised, because it violates abstraction. Even for non-const member functions, however, returning handles can lead to trouble, especially when temporary objects get involved. We should avoid dangling handles as we avoid dangling pointers.
Item 28: Partition the global namespace
A namespace is just a fancy way of letting you use the prefixes you know and love without making people look at them all the time.
Access symbols in namespace in any of the three ways:
1. importing all the symbols in a namespace into a scope: using namespace std;
2. importing individual symbols into a scope: using std::cout;
3. explicitly qualifying a symbol for one-time use: std::cout << "hello world!"; One of the nicest things about namespace is that potential ambiguity is not an error, provided you never refer to the conflict symbols.
Item 26: Guard again potential ambiguity
C++ Philosophy: potential ambiguity is not an error.
Access restrictions are not taken into account when disambiguating references to multiply inherited members. Becuase changing the accessibility of a class member should never change the meaning of a program.
Item 30: Avoid member functions that return non-const pointers or references to members less accessible than themselves.
You won't want to sacrifice the access restrictions that private and protected afford you. Use const whenever possible.
Item 31: Never return a reference to a local object or to a dereferenced pointer initialized by new within the function.
1. reference to non-existing object, which is undefined.
2. cause memory leak
Item 32: Postpone variable definitions as long as possible
In this way, you avoid not only constructing and destructing unneeded objects, you also avoid pointless default constructions. Define and initialize via copy constructor will make the meaning more clear.
Item 38: Never redefine an inherited default parameter value
Virtual functions are dynamically bound, but default parameter values are statically bound.
An object's static type is the type you declare it to have in the program text. An ojbect's dynamic type is determined by the type of the object to which it currently refers.
Item 37: Never redefine an inherited nonvirtual function
Nonvirtual functions are statically bound. Which nonvirtual function to call is decided by the declared type of the pointer.
class B { void f(); }
class D: public B {void f();}
B b;
D d;
B * pB = &b;
pB-> f();//call B::f()
pB = &d;
pB->f(); //call B::f()
Item 24: Choose carefully between function overloading and parameter defaulting
In general, if you can choose a reasonable default value and you want to employ only a single algorithm, you'll use default parameters.
You have to use overloaded functions if the algorithms depend on the input.
Using overloaded functions that call a common underlying function for some of their work to avoid code duplication.
Item 19: Differentiate among member functions, non-member functions, and friend functions
Virtual functions must be members. Non-member function can NOT be virtual. And if a function has to be dynamically bound, you've got to use a virtual function, a member of some class.
Operator >> and operator << style="font-weight: bold;">parameter list, never for the object on which a member function is invoked. In addition, if the function needs to access non-public members, make it a friend.
Everything else should be a member function.
Item 33: Use inlining judiciously
Inline is a hint, not a command.
Initially, don't inline anything, or at least limit your inlining to those functions that are truly trivial.
80-20, a typical program spends 80 percent of its time executing only 20 percent of its code. It's an important rule, because it reminds you that your goal as a software developer is to identify the 20 percent of your code that is actually capable of increasing your program's overall performance.
It's all wasted effort unless you're focusing on the right functions.
Item 39: Avoid casts down the inheritance hierarchy
Try to use virtual functions instead of if-then-else style of programmings that downcast objects.
copy constructor
When copies of objects are made
A copy constructor is called whenever a new variable is created from an object. This happens in the following cases (but not in assignment).
- A variable is declared which is initialized from another object, eg,
Person q("Mickey"); // constructor is used to build q.
Person r(p); // copy constructor is used to build r.
Person p = q; // copy constructor is used to initialize in declaration.
p = q; // Assignment operator, no constructor or copy constructor. - A value parameter is initialized from its corresponding argument.
f(p); // copy constructor initializes formal value parameter.
- An object is returned by a function.
C++ calls a copy constructor to make a copy of an object in each of the above cases. If there is no copy constructor defined for the class, C++ uses the default copy constructor which copies each field, ie, makes a shallow copy.
Don't write a copy constructor if shallow copies are ok
If the object has no pointers to dynamically allocated memory, a shallow copy is probably sufficient. Therefore the default copy constructor, default assignment operator, and default destructor are ok and you don't need to write your own.
If you need a copy constructor, you also need a destructor and operator=
If you need a copy constructor, it's because you need something like a deep copy, or some other management of resources. Thus is is almost certain that you will need a destructor and override the assignment operator.
Copy constructor syntax
The copy constructor takes a reference to a const
parameter. It is const
to guarantee that the copy constructor doesn't change it, and it is a reference because a value parameter would require making a copy, which would invoke the copy constructor, which would make a copy of its parameter, which would invoke the copy constructor, which ...
Here is an example of a copy constructor for the Point class, which doesn't really need one because the default copy constructor's action of copying fields would work fine, but it shows how it works.
//=== file Point.h =============================================
class Point {
public:
. . .
Point(const Point& p); // copy constructor
. . .
//=== file Point.cpp ==========================================
. . .
Point::Point(const Point& p) {
x = p.x;
y = p.y;
}
. . .
//=== file my_program.cpp ====================================
. . .
Point p; // calls default constructor
Point s = p; // calls copy constructor.
p = s; // assignment, not copy constructor.
Difference between copy constructor and assignment
A copy constructor is used to initialize a newly declared variable from an existing variable. This makes a deep copy like assignment, but it is somewhat simpler:
- There is no need to test to see if it is being initialized from itself.
- There is no need to clean up (eg, delete) an existing value (there is none).
- A reference to itself is not returned.
Thursday, July 10, 2008
Wednesday, July 9, 2008
Deep Copy and Shallow Copy
class A
{
string s;
};
A a;
A b;
a=b; //deep copy
When assigning b to a, the compiler-generated assignment operator of class A first invokes the assignment operator of class std::string. Thus, a.s and b.s are well-defined, and they are probably not binary-identical. On the other hand, a shallow copy (also called "bitwise copy") simply copies chunks of memory from one location to another. A memcpy() operation is an example of a shallow copy. Because memcpy() does not respect object semantics, it will not invoke the copy constructor of an object. Therefore, you should never use memcpy() to copy objects. Use it only when copying POD (Plain Old Data) types: ints, floating point numbers, and dumb structs.
-------------
A shallow copy of an object copies all of the member field values. This works well if the fields are values, but may not be what you want for fields that point to dynamically allocated memory. The pointer will be copied. but the memory it points to will not be copied -- the field in both the original object and the copy will then point to the same dynamically allocated memory, which is not usually what you want. The default copy constructor and assignment operator make shallow copies.
A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. To make a deep copy, you must write a copy constructor and overload the assignment operator, otherwise the copy will point to the original, with disasterous consequences.
NOTE:
there is no const qualifier in the passed parameter of the copy constructor and overloaded assignment operator.
Stack unwinding
Stack unwinding (C++ only)
When an exception is thrown and control passes from a try block to a handler, the C++ run time calls destructors for all automatic objects constructed since the beginning of the try block. This process is called stack unwinding. The automatic objects are destroyed in reverse order of their construction. (Automatic objects are local objects that have been declared auto or register, or not declared static or extern. An automatic object x is deleted whenever the program exits the block in which x is declared.)
If an exception is thrown during construction of an object consisting of subobjects or array elements, destructors are only called for those subobjects or array elements successfully constructed before the exception was thrown. A destructor for a local static object will only be called if the object was successfully constructed.
If during stack unwinding a destructor throws an exception and that exception is not handled, the terminate() function is called. The following example demonstrates this:
#include
using namespace std;
struct E {
const char* message;
E(const char* arg) : message(arg) { }
};
void my_terminate() {
cout << "Call to my_terminate" << endl;
};
struct A {
A() { cout << "In constructor of A" << endl; }
~A() {
cout << "In destructor of A" << endl;
throw E("Exception thrown in ~A()");
}
};
struct B {
B() { cout << "In constructor of B" << endl; }
~B() { cout << "In destructor of B" << endl; }
};
int main() {
set_terminate(my_terminate);
try {
cout << "In try block" << endl;
A a;
B b;
throw("Exception thrown in try block of main()");
}
catch (const char* e) {
cout << "Exception: " << e << endl;
}
catch (...) {
cout << "Some exception caught in main()" << endl;
}
cout << "Resume execution of main()" << endl;
}
The following is the output of the above example:
In try block
In constructor of A
In constructor of B
In destructor of B
In destructor of A
Call to my_terminate
In the try block, two automatic objects are created: a and b. The try block throws an exception of type const char*. The handler catch (const char* e) catches this exception. The C++ run time unwinds the stack, calling the destructors for a and b in reverse order of their construction. The destructor for a throws an exception. Since there is no handler in the program that can handle this exception, the C++ run time calls terminate(). (The function terminate() calls the function specified as the argument to set_terminate(). In this example, terminate() has been specified to call my_terminate().)
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/cplr155.htmTuesday, July 8, 2008
Thursday, July 3, 2008
下载流媒体的四种小技巧
第二、要是在线播放流媒体信息时,系统自动调出Windows媒体播放器时,你可以用鼠标右键单击播放窗口,执行快捷菜单中的“属性”命令,打开该属性界面中的“文件”标签页面,在对应的页面中,我们就能清楚地看到流媒体文件的真实下载地址了,此时将该地址粘贴到专用下载工具中就可以了。
第三、用鼠标右键单击网页中的某个流媒体链接地址时,也许你会在随后打开的右键菜单中,看到“目标另存为”这样的命令,执行该命令后,你就能将该流媒体链接地址保存为HTML文件,用记事本打开该html文件,你就能方便地找到流媒体文件的真实下载地址了。
第四、要是单击某个网页中的流媒体下载链接时,IE浏览器能很快地将百十兆左右的流媒体文件,下载下来,但发现下载获得的文件大小只有几十KB,那么这个文件很有可能是RAM、ASF、WMA或ASX格式的;其实该文件,只是起导航作用,此时你可以用记事本将它们打开,也许真实的下载地址就“躺”在其中呢。
两款探查真实下载地址的软件-Project URL Snooper和Asp2url最新版 (下载高手之必备之利器)
Project URL Snooper 是一个网络信息侦测(嗅探)软件, 能够实时跟踪通过你电脑中(经过网卡,调制解调器等)的数据信息,并分析出里面的各种类型的URL地址.一些电影点播网站对于影片的地址往往隐藏的很好,但是这个软件能够很容易的将这些地址轻易展现在你的眼前。是用来配合Streambox VCR, ASFR ,SDP 等一些流行的流媒体下载软件很好的助手。
Project URL Snooper (free URL Snooper software download)
Project URL Snooper (Freeware/Windows)
Many links to streaming audio and video that you come across on the web are hidden behind JavaScript, Macromedia Flash, ActiveX. Because of this, it is sometimes very difficult to figure out the actual urls that correspond to the streams being played.
Project URL Snooper was written to help users locate the urls of audio and video files so that they can be recorded.
The goal of Project URL Snooper is to provide a one-stop easy solution to finding the URLs for all streams. It does this by watching network traffic and identifying potential urls, especially streaming media urls.
Platform: Windows 9x/2K/XP.
New Features in Project URL Snooper version 2:
- Totally revamped and cleaner user interface.
- Smart packet spanning - rebuilds packet streams to eliminate split-urls.
- Improved identification of protocols, duplicates, and url arguments.
- New dynamic url filtering keywords.
- Improved context menu support, drag and drop file searching.
- Includes recording hints and website links.
- User customizable browser selection and favorites menu.
To find the hidden url for a streaming audio/video file:
- Open your browser and go to the page containing the stream you are interested in.
- Start Project Url Snooper and click on "Sniff Network."
- Go to the browser and start the stream playing.
- Hopefully you will soon see the stream URLs appear in the Results List.
- After the stream begins playing, you may stop it.
- Drag URLs to targets, or right-click to copy to clipboard or launch 3rd party apps.
Tuesday, July 1, 2008
Binary Search
loop
if l > u
p = -1; break
m = (l+u)/2
case
x[m] < t: l=m+1
x[m] == t: p=m; break
x[m] > t: u = m-1