<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0cBSXk6cSp7ImA9Wx5QFE0.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846</id><updated>2010-09-01T22:24:18.719-07:00</updated><title>Xiao Ma's Blog</title><subtitle type="html">Let's talk about operating systems, software reliability, program analysis, computer architecture, ..., and the most important, building something that is useful.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.xiao-ma.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/xiao-ma-blog" /><feedburner:info uri="xiao-ma-blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CEMMQHwzfyp7ImA9WxFXFUQ.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-5166763701152814998</id><published>2010-05-22T16:25:00.000-07:00</published><updated>2010-05-22T22:28:01.287-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-22T22:28:01.287-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Facebook" /><title>Facebook acts just like any other monopoly</title><content type="html">Facebook started with a brilliant idea, just like any other monopoly.&lt;br /&gt;
&lt;br /&gt;
Although Facebook didn't invent social networking, it did a terrific job to execute the idea, grow insanely fast and beat its competitors, just like any other&amp;nbsp;monopoly.&lt;br /&gt;
&lt;br /&gt;
Since Facebook got to a great position, it started doing something, which usually early-age start-ups try hard to avoid - pissing off users, just like any other&amp;nbsp;monopoly. More specifically, as you already knew, it keeps ignoring users' privacy.&lt;br /&gt;
&lt;br /&gt;
One important thing that backs it up is its&amp;nbsp;business, social networking.&amp;nbsp;Social networking is one of those&amp;nbsp;businesses&amp;nbsp;that once you use it, it is way too complicated and expensive to switch to other alternatives. If you already have hundreds of friends on Facebook, how could you easily shutdown your account and create another network somewhere else (which is nowhere for now, unfortunately)? Another good example is Microsoft's territory in enterprise software. Most companies don't even want to get rid of IE6 due to the cost, let along Windows and Office.&lt;br /&gt;
&lt;br /&gt;
The whole philosophy behind Facebook's privacy policy changes is two folds, in my opinion.&lt;br /&gt;
&lt;br /&gt;
First, Facebook is betting that 90% of its users don't realize that they should check the policy, or they don't care. So it makes the &lt;a href="http://mattmckeon.com/facebook-privacy/"&gt;default setting to share as much as possible&lt;/a&gt;. 90% of the rest of users won't check the policy in detail if it is too complicated to understand. So it makes its policy implicit and complicated and makes policy setting interface extremely difficult.&lt;br /&gt;
&lt;br /&gt;
Second, with its dominant position, Facebook can experiment kicking off bad policies without worrying much of losing users. Think about it, even if the policy doesn't work out eventually, what's the worst thing that could happen? Facebook can just roll back the changes and apologize. It will still have its, I don't know exactly, hundreds of millions of users, even if &lt;a href="http://www.quitfacebookday.com/"&gt;tens of thousands of them are pissed off so badly and quit&lt;/a&gt;.&amp;nbsp;Again, this is just like any other&amp;nbsp;monopoly.&lt;br /&gt;
&lt;br /&gt;
Don't get me wrong. I don't completely hate Facebook. With no doubt, Facebook changed the way we share. On the day any of us created Facebook accounts, we admitted that we want to more or less share something.&amp;nbsp;I also really like a few ideas from Facebook, such as &lt;a href="http://blog.xiao-ma.com/2009/09/facebook-invites-everyone-to-be.html"&gt;Facebook Development APIs and Facebook Connect&lt;/a&gt;. I especially believe Open Graph is a great idea, if it is done right.&amp;nbsp;While Google is aggregating information from the web, Facebook is aggregating information from our lives and our minds. This is &lt;i&gt;HUGE&lt;/i&gt;. With this information, Facebook has big potential to really build better web to help people. For instance, I'm a big fan of &lt;a href="http://vark.com/"&gt;Aardvark&lt;/a&gt;, which I think is a perfect example with which Facebook could make huge difference based on its user base and information.&amp;nbsp;I'm actually surprised when Aardvark was bought by Google but Facebook, maybe Facebook has already started building its own.&lt;br /&gt;
&lt;br /&gt;
It's not very fair to&amp;nbsp;blame Facebook for everything. Its whole business model is based on the number of users and the amount of information users are willing to share, or are forced to share, or share without even being aware of it. Facebook wants to grow and it does what it is meant to do. It depends on the user to accept it or not. When there are no other options, Facebook wins. What Facebook really needs is competitors, good competitors, just like any other&amp;nbsp;monopoly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-5166763701152814998?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/WlJcKqvjomg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/5166763701152814998/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=5166763701152814998" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/5166763701152814998?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/5166763701152814998?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/WlJcKqvjomg/facebook-acts-just-like-any-other.html" title="Facebook acts just like any other monopoly" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2010/05/facebook-acts-just-like-any-other.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUECSXg7cSp7ImA9WxFTE0g.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-8278606303742158760</id><published>2010-04-03T21:53:00.000-07:00</published><updated>2010-04-03T22:07:48.609-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-03T22:07:48.609-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="iPad" /><category scheme="http://www.blogger.com/atom/ns#" term="Apple" /><title>Tough Waiting</title><content type="html">&lt;b&gt;Mar. 30th&lt;/b&gt; - Received the shipping notification from Apple.&lt;br /&gt;
&lt;div&gt;&lt;hr /&gt;&lt;div&gt;&lt;b&gt;Mar. 31st&lt;/b&gt; - Found the package left from Shenzhen, China.&lt;/div&gt;&lt;hr /&gt;&lt;div&gt;&lt;b&gt;Apr. 1st&lt;/b&gt; - The package arrived in the U.S.&lt;/div&gt;&lt;hr /&gt;&lt;div&gt;&lt;b&gt;Apr. 2nd&lt;/b&gt; -&amp;nbsp;&amp;nbsp;I do not want to ship it to my home, for some reason, so&amp;nbsp;package is shipped to the building where my office is. Since the building is closed on Saturdays, I called UPS several times to make sure it will be delivered. I asked if the delivery person can call me once he comes by the building, the answer is that they do not carry phones. I asked if I can pick it up in local customer center, the answer is "we made special deal with Apple, we cannot change anything before the first attempt of delivery". So I decided to wait at the door for the UPS delivery tomorrow.&lt;/div&gt;&lt;hr /&gt;&lt;div&gt;&lt;b&gt;Apr. 3rd 8:30 AM&lt;/b&gt; - Found on the UPS tracking page that the package arrived in Decatur at 5:45am, which is about one hour away from Urbana. Right on track!&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Apr. 3rd 8:50AM &lt;/b&gt;-&amp;nbsp;I went to the office and sit at the door of the building. It is nice that there is a power plug next to the door, so I can do some work while waiting.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;b&gt;Apr. 3rd 9:30 AM&lt;/b&gt; -&amp;nbsp;Called UPS to check again. There is a voice message about iPad delivery, which says that all pre-ordered iPad packages will arrive by the end of the day. I talked with a representative, she told me that the normal Saturday delivery schedule, packages are delivered before noon, does not apply to iPad deliveries today. She can not help me locate or contact the delivery person, but she's sorry that I need to wait at the door.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;b&gt;Apr. 3rd 9:53 AM&lt;/b&gt; - Refreshed the UPS tracking page again, found the package actually has arrived in Urbana at 8AM. Nice!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Apr. 3rd 11:09 AM&lt;/b&gt; - It stopped raining. I got some work done. A big goose dropped by.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Apr. 3rd 11:30 AM&lt;/b&gt; - The status of the package still hasn't changed into "Out For Delivery", so I called UPS again to double check if they deliver packages to business addresses on Saturdays. This time I was told that they do not. So I decided to have lunch first. If the status changes to&amp;nbsp;"Out For Delivery", &amp;nbsp;I will come back.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Apr. 3rd 11:50 AM&lt;/b&gt; - Left the office.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Apr. 3rd 12:50 PM&lt;/b&gt; - Found the status of the package became "12:03 AM -&amp;nbsp;&lt;i&gt;Exception:&amp;nbsp;THE RECEIVER'S LOCATION WAS CLOSED ON THE 1ST DELIVERY ATTEMPT. A 2ND DELIVERY ATTEMPT WILL BE MADE&lt;/i&gt;". So I called a supervisor in UPS. He promised to contact the local UPS center and make the second attempt today, in about 2 hours.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Apr. 3rd 1:10PM&lt;/b&gt; - Went back to the building and sit at the door.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Apr. 3rd 1:40 PM&lt;/b&gt; - Got the iPad.&lt;br /&gt;
&lt;br /&gt;
Although the waiting is not that pleasant, iPad is so awesome! She is so surprised.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_9g0CxX7-Ez4/S7gbJT6qpOI/AAAAAAAAAhg/kzq_2x8gvKc/s1600/iPad.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_9g0CxX7-Ez4/S7gbJT6qpOI/AAAAAAAAAhg/kzq_2x8gvKc/s320/iPad.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-8278606303742158760?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/GHah8LPNay0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/8278606303742158760/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=8278606303742158760" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/8278606303742158760?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/8278606303742158760?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/GHah8LPNay0/tough-waiting.html" title="Tough Waiting" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_9g0CxX7-Ez4/S7gbJT6qpOI/AAAAAAAAAhg/kzq_2x8gvKc/s72-c/iPad.JPG" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2010/04/tough-waiting.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IDR3g7eSp7ImA9WxBXGU0.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-9058390112955135656</id><published>2010-01-30T19:18:00.000-08:00</published><updated>2010-01-30T19:46:16.601-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-30T19:46:16.601-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="iPad" /><category scheme="http://www.blogger.com/atom/ns#" term="Apple" /><title>iPad is Not a Toy. You Do the Math</title><content type="html">&lt;a href="http://www.apple.com/ipad/"&gt;Apple released iPad&lt;/a&gt;. Not too much surprise. It is a tablet and it is a lot like what the rumors said. Did I &lt;a href="http://blog.xiao-ma.com/2010/01/what-to-expect-when-you-are-expecting.html#links"&gt;expect too much&lt;/a&gt;? Yes. Am I disappointed by iPad? Not really. Do I lose faith in iPad? Absolutely no! iPad is a great product. It is not just a big iPhone. It is not just a toy. It started changing how a computer should work for most of the things we use computers for.&lt;br /&gt;
&lt;br /&gt;
During &lt;a href="http://www.apple.com/quicktime/qtv/specialevent0110/"&gt;his presentation&lt;/a&gt;, Steve Jobs clearly defined the market of iPad - it is a "&lt;i&gt;third category&lt;/i&gt;" mobile device between smart phones and laptops. This definition again brings back the question that everybody asked before - why do we need a third category mobile device? As for Steve Jobs' answer, the reason is that we need to do "key things" in a "far better" way. I totally buy this rationale. We really need this "third category". It covers the most important tasks, including&amp;nbsp;reading emails, browsing the Web, listening to musics, watching videos, playing games and reading ebooks.&amp;nbsp;It also covers a lot of scenarios where the first two categories are not good enough. These scenarios add up to a significant amount of time of using a computer.&amp;nbsp;All these boil down to a&amp;nbsp;simple math problem:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/S2T0z8epTcI/AAAAAAAAAgA/OB4uYQbGyCg/s1600-h/apple-tablet-2.001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/S2T0z8epTcI/AAAAAAAAAgA/OB4uYQbGyCg/s400/apple-tablet-2.001.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
The reality is that "A" is becoming bigger and bigger and "C" is becoming smaller and smaller. Obviously, this leads to a more and more significant difference. So do the math, then you will realize that iPad is not just a toy, it is a serious and useful device for everybody.&lt;br /&gt;
&lt;br /&gt;
One could certainly argue that even if the difference becomes bigger, I can still use either a smart phone or a laptop to cover it. Yes, of course you can, but iPad just makes it far better than a smart phone or a laptop. It is fast. It is convenient. It has a new human-computer interface, which matters the most.&lt;br /&gt;
&lt;br /&gt;
The keyboard-mouse-monitor interface has not changed for decades. It has been working pretty well, but it is certainly not the ideal one. What iPad provides is a much better interface. In my opinion, the human-computer interface should be as similar as possible to what we do things in the real world, meanwhile leverage computing power to help us do things better. Take the photo app on iPad as an example. It makes photo piles and lets the user to spread/stack up a pile of photos. It is better than how iPhoto works. It is more natural and fun. In the meantime, it helps people share photos, make photo books, organize photos by tags, geographic information, faces and such, which traditional photo albums can not do. This is how a computer should work.&lt;br /&gt;
&lt;br /&gt;
Many people think iPad is a content consumer. I don't think it is true. It is &lt;i&gt;brilliant&lt;/i&gt; for Apple to port iWork to iPad, which makes iPad much more than a content consumer. iWork significantly enlarges the use case space of iPad. For example, think about high school students, or even college students. They can use iPad to take notes, read text books, write reports and make presentations. How cool is that?&lt;br /&gt;
&lt;br /&gt;
Is iPad good enough for everything? One can easily come up with thousands of things that iPad can not do. It's true. I can come up with thousands of things that a laptop, or even a desktop can not do as well. Does it prevent me from buying a laptop instead of a super computer? No. Because a laptop is good enough for most tasks.&amp;nbsp;The just unveiled iPad is not intended to replace everything. But for average computer users, it does most of their tasks in a much better way. As for the next generation, or the generation after... I think iPad will become the first thing to think about when somebody needs to buy a computer.&lt;br /&gt;
&lt;br /&gt;
Thirty years ago, nobody could imagine that a computer can be put on a desk, until Apple released Apple II and soon IBM released 5150.&amp;nbsp;Ten years ago, nobody believed that a laptop could be as powerful as a desktop. Today, most of my friends have only a laptop and a big monitor at home.&amp;nbsp;It is way too early to conclude that iPad, tablets in general, won't be the next &amp;nbsp;mainstream personal computing device. Give it time, things will change. iPad has no doubt just started this change now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-9058390112955135656?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/3LRANz0E0xk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/9058390112955135656/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=9058390112955135656" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/9058390112955135656?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/9058390112955135656?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/3LRANz0E0xk/ipad-is-not-toy-you-do-math.html" title="iPad is Not a Toy. You Do the Math" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_9g0CxX7-Ez4/S2T0z8epTcI/AAAAAAAAAgA/OB4uYQbGyCg/s72-c/apple-tablet-2.001.png" height="72" width="72" /><thr:total>11</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2010/01/ipad-is-not-toy-you-do-math.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UESHw7eSp7ImA9WxBQGEo.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-6210818440621030774</id><published>2010-01-16T16:04:00.000-08:00</published><updated>2010-01-18T21:33:29.201-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-18T21:33:29.201-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Apple" /><title>What To Expect When You Are Expecting - Apple Tablet</title><content type="html">As the rumored release date is coming, "Apple Tablet" (let's call it this for now) has stimulated heated discussion and a lot of speculation. It is just a lot of fun to think about what Apple will do.&lt;br /&gt;
&lt;br /&gt;
Just like many other products, two&amp;nbsp;fundamental&amp;nbsp;keys of Apple Tablet are the &lt;i&gt;price&lt;/i&gt; and the &lt;i&gt;market&lt;/i&gt;. The biggest market problem of Apple Tablet is that it more or less overlaps with existing Apple product lines. The first question people will ask themselves is that if I already have a desktop and a smartphone, maybe also a laptop, why should I buy a tablet? When and where will I use it? Will it be very useful or just sort of useful? What price would I accept to buy a widget that is "sort of useful" or even just a fancy expensive toy?&amp;nbsp;These are all valid questions. So&amp;nbsp;what should we expect from Apple Tablet?&amp;nbsp;Before we think about what to expect, let's start with what not to expect.&lt;br /&gt;
&lt;br /&gt;
Apple Tablet will not be a traditional &lt;i&gt;browser-only&lt;/i&gt; netbook. First of all, Apple's strength is not making Web browsers, although Safari is great. Apple's strength is design and user experience. So there must be awesome client applications besides a Web browser. Second of all, 99.99% of the current web sites are not touch-screen friendly. They are not designed for touch screens at all. Even in the future, I don't think websites can easily provide as good user experience as client applications can (note that I did not say desktop applications). I always prefer client applications even if most of the storage and computation is thrown to the cloud,&amp;nbsp;with only a few exceptions of Google's great products, namely Gmail and Google Reader.&lt;br /&gt;
&lt;br /&gt;
Apple Tablet&amp;nbsp;will not be an e-reader. This is not only because &lt;a href="http://bits.blogs.nytimes.com/2008/01/15/the-passion-of-steve-jobs/"&gt;Steve Jobs said "people don't read anymore"&lt;/a&gt;, it just does not make sense for Apple to make a dedicated reading device, because it will need to make another device to provide more later.&amp;nbsp;&amp;nbsp;Kindle is a great innovation and I have been hesitating between buy or not buy a kindle for a long long time. But what Kindle can do is just a small part of personal computing. Maybe Apple Tablet will not be as good as Kindle in terms of reading book, but it will be a reasonable e-reader plus a lot more.&lt;br /&gt;
&lt;br /&gt;
Apple Tablet will not be a Macbook with a touch screen. Apple Tablet will be smaller, lighter and may provide less computing power. It will be easier to carry around. Maybe not &lt;i&gt;much&lt;/i&gt; easier than Macbook, but let me give you one scenario for instance: using Macbook when you were in the restroom is awkward, but Apple Tablet will fit nicely. Apple Tablet will also be easier to use, and most importantly, thanks to new possibilities in interface design, it will be more fun!&lt;br /&gt;
&lt;br /&gt;
What should we expect then?&amp;nbsp;In my guess,&lt;b&gt;&amp;nbsp;Apple Tablet will be a revolution that changes the way how mainstream people use computers, including both desktops and laptops. &lt;/b&gt;Fortunately, Apple is a company that is capable to do such a thing.&lt;br /&gt;
&lt;br /&gt;
I drew a picture of four main products lines in Apple. iPhone is&amp;nbsp;irreplaceable, because it is the only one you can carry with you all the time. Apple Tablet is under "Fit In Pocket", together with Macbook and iMac, but it is way portable than iMac and better than Macbook. Apple Tablet is just cross the "Enough For Most User" line, which makes it capable to say no to both Macbook and iMac.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/S1Ue9IsNP_I/AAAAAAAAAfo/DVHODCj4flg/s1600-h/apple-tablet.001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/S1Ue9IsNP_I/AAAAAAAAAfo/DVHODCj4flg/s400/apple-tablet.001.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://daringfireball.net/"&gt;John Gruber&lt;/a&gt;&amp;nbsp;thought &lt;a href="http://daringfireball.net/2009/12/the_tablet"&gt;Apple Tablet will be a kind of a replacement of Macbook&lt;/a&gt;. When people want to by a portable device from Apple, they will consider either a Macbook or an Apple Tablet, but not likely to get both. I agree with him, but I think Apple Tablet is more&amp;nbsp;ambitious&amp;nbsp;than this - most people will only need an Apple Tablet, maybe plus an iPhone.&lt;br /&gt;
&lt;br /&gt;
First of all, why must we have a desktop &lt;i&gt;and&lt;/i&gt;&amp;nbsp;a laptop? For most people, the border between desktops and laptops is vague and there is no need to have both, because the mobile hardware is so advanced and more and more computation and storage is being moved to the cloud. You can store your documents on the cloud, your pictures, and even your musics and videos - remember that Apple has the best online streaming service for movies, TV shows and &lt;a href="http://www.techcrunch.com/2009/12/04/apple-acquires-lala/"&gt;it recently acquired Lala&lt;/a&gt; to stream musics. So in my opinion, the next generation of personal computing should be always portable, even in a house, I want to move my computer wherever I want. High-performance desktop will be only needed for people who want to edit a movie or something.&lt;br /&gt;
&lt;br /&gt;
Why must we use a keyboard and a mouse to talk with the computer? I feel sorry that my mom has to struggle&amp;nbsp;with typing when she starts using computers. There must be some ways that are more natural and easier to interact with computers. This is actually the most exciting thing I would expect from Apple Tablet - a&amp;nbsp;phenomenal&amp;nbsp;brand new user interface. Imagine you could dance your finger on the screen to organize your&amp;nbsp;pictures and emails. Imagine you&amp;nbsp;could&amp;nbsp;make a picture by "drawing" them with your hands. Imagine&amp;nbsp;when&amp;nbsp;you read a book, you&amp;nbsp;could&amp;nbsp;flip a page by sliding your figures on its corner, you&amp;nbsp;could&amp;nbsp;highlight/circle the interesting part by move your finger&amp;nbsp;across&amp;nbsp;them and you&amp;nbsp;could&amp;nbsp;write down your comments and even draw a&amp;nbsp;sketch. Now this comes to what Apple is good at. Trust me, it will change everything.&lt;br /&gt;
&lt;br /&gt;
Ok, talking the keyboard, a really big topic. Not sure if Apple Tablet will have a real keyboard, probably not. If there will be only an on-screen keyboard, I think Apple will make it&amp;nbsp;&lt;i&gt;resizable&lt;/i&gt;, so it can fit hands in different sizes. You can also move it to any place on the screen. Once you settle down at home, you can use a wireless keyboard or mouse if you want to.&amp;nbsp;I think this would be enough, except for people who needs to type a lot a lot, like programmers or writers.&lt;br /&gt;
&lt;br /&gt;
Talking about the screen. It will be multi-touch, no doubt. I hope it will be pressure-sensitive as well. In terms of size, 10 inches is the most accepted speculation. I don't care the size that much, since it won't fit into my pocket anyway. Kindle is too small to me. 10 inches is a nice size for reading, at least to me. One big question is how it will make reading books easier. People will definitely expect to use it for reading. I have tons of PDF books and I hate to read them on my laptop. &lt;a href="http://spectrum.ieee.org/computing/hardware/winner-pixel-qis-everywhere-display/0"&gt;Pixel Qi's multi-purpose screen&lt;/a&gt; seems to be a really good idea.&lt;br /&gt;
&lt;br /&gt;
As for network, will Apple Tablet have only WiFi or support 3G, iPhone-like 3G or Kindle-like 3G? If it &amp;nbsp;supports wireless data plan, it must be optional, and probably more expensive than the iPhone plan. I highly doubt it though. AT&amp;amp;T is already struggling to support iPhone users. With Apple Tablet, it's like Hulu@iPhone, I don't think any providers will want to run that risk.&amp;nbsp;How about peripherals? What if you really need a real keyboard and mouse, or a big screen monitor, or a printer? It's easy, you can plug the tablet into a station and most stuff won't even need a cable.&lt;br /&gt;
&lt;br /&gt;
Finally, the price. Price, to be more specific, low price, is very important if Apple wants massive success of the new device. This goes back to the two keys I mentioned in the beginning, market and price. I want to use the "vitamin v.s. pain killer" metaphor, which my&amp;nbsp;advisor&amp;nbsp;often uses to judge research papers. If the product is a "pain killer", high price may be acceptable. But if it is just "vitamin", well, I won't buy it if it is too expensive. Although I believe Apple Tablet will be capable let most people just have one device, the reality is that many people &lt;i&gt;already&lt;/i&gt; have laptops and/or desktops. To convince them to switch, the price should make them happy.&lt;br /&gt;
&lt;br /&gt;
Enough is enough. I vividly remember the &lt;a href="http://www.apple.com/quicktime/qtv/mwsf07/"&gt;Macworld 2007 Keynote by Steve Jobs where he introduced iPhone&lt;/a&gt;, which absolutely redefined the smartphone industry. Apple Tablet will redefine the game again: personal computing should be like this. I can't wait to see it, can you?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-large;"&gt;Updates:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Jan. 18th: &lt;a href="http://www.macrumors.com/2010/01/18/apple-issues-invitations-for-january-27th-media-event/"&gt;Apple issues invitation to a media event on the 27th&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://images.macrumors.com/article/2010/01/18/122548-appleinvite_500.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="233" src="http://images.macrumors.com/article/2010/01/18/122548-appleinvite_500.jpg" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Because of the colorful splatter paint in the post, people start thinking the new device will focus on art creating. Did I expect too much?&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-6210818440621030774?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/Tb067hQg2Ok" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/6210818440621030774/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=6210818440621030774" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/6210818440621030774?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/6210818440621030774?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/Tb067hQg2Ok/what-to-expect-when-you-are-expecting.html" title="What To Expect When You Are Expecting - Apple Tablet" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_9g0CxX7-Ez4/S1Ue9IsNP_I/AAAAAAAAAfo/DVHODCj4flg/s72-c/apple-tablet.001.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2010/01/what-to-expect-when-you-are-expecting.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08ARHc_eyp7ImA9WxBQFU8.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-8828571047210766107</id><published>2010-01-12T22:26:00.000-08:00</published><updated>2010-01-14T20:30:45.943-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-14T20:30:45.943-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="China" /><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><title>Google Leaves, Baidu Laughs, Users Suffer</title><content type="html">Triggered by cyber attacks from China, &lt;a href="http://googleblog.blogspot.com/2010/01/new-approach-to-china.html"&gt;Google started reviewing the feasibility of doing business in China&lt;/a&gt;. Google decides not to continue censoring search results any more. If Chinese government can not accept this, Google will stop running &lt;a href="http://google.cn/"&gt;Google.cn&lt;/a&gt; and may close the Chinese office as well.&lt;br /&gt;
&lt;br /&gt;
I am shocked that such a brilliant company is finally kicked out.&amp;nbsp;Giving up Chinese market must be a very tough decision for Google. All difficulties aside, China is a huge market. Google made such a decision, I think Google is finally fed up. I'm sorry for Google. Last year when &lt;a href="http://english.cctv.com/01/index.shtml"&gt;CCTV&lt;/a&gt;&amp;nbsp;(a television network speaking for the government) criticized Google.cn for suggesting pornographic&amp;nbsp;search queries. I thought that is just to send out a warning message to all websites. By the way, that was one of the &lt;i&gt;biggest&lt;/i&gt; jokes in 2009. Google's suggestion is nothing more than top content in other Chinese websites. If CCTV thinks the suggested queries are&amp;nbsp;pornographic, please just go ahead&amp;nbsp;find&amp;nbsp;those websites and quit making fake interviews to judge Google.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Kai-Fu_Lee"&gt;Kaifu Li&lt;/a&gt;&amp;nbsp;&lt;a href="http://cnreviews.com/business/companies/lee-kai-fu-resignation_20090904.html"&gt;left Google China last September&lt;/a&gt;. His timing couldn't be better. Imagine how people would think if he is still in Google China today. Did Kaifu already&amp;nbsp;foresee what will happen? Anyway, people may not blame him, since he did a great job before he left. He improved Google's market share in China from 16.1% to 31%. But it seems to be an impossible mission to make Google the market leader in China. But will he fight with Google executives to keep Google.cn if he is still with Google now? After Kaifu left, people started leaving too. If Google.cn is gone, even if Google wants to keep the Google China office, more people will leave I think.&lt;br /&gt;
&lt;br /&gt;
Let's think about what will happen in China if Google really leaves?&amp;nbsp;First&amp;nbsp;of all, it is a big shrink-back signal to companies that want to enter China. Well, this probably gives some people in China the time to copy good ideas from oversea companies, or &lt;a href="http://www.techcrunch.com/2008/04/30/chinese-facebook-clone-xiaonei-raises-a-staggering-430-million/"&gt;maybe even icons and source code&lt;/a&gt;? Baidu.com can finally celebrate on eliminating the biggest competitor to split the big Internet advertising cake in China. Remember, no competitors, no improvement. How about Internet users? They will have to use Baidu.com, a search engine that censors information,&amp;nbsp;is not capable to correct tiny English misspellings with errors in edit-distance of 1,&amp;nbsp;while still suggests "pornographic" search queries:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/S01jlMR0DOI/AAAAAAAAAfc/7wcdEK44XcY/s1600-h/Picture+1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/S01jlMR0DOI/AAAAAAAAAfc/7wcdEK44XcY/s400/Picture+1.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;(Search queries suggested by "Baidu.com" for the query "mm" ("beautiful girl" in Chinese), including "naked pictures of sexy girls in bed", "teenage girls sleeping naked" and such. The screenshot was taken when I published this post inspired by this &lt;a href="http://www.chinasmack.com/more/cctv-attacks-google-porn-links-fake-interview-exposed/"&gt;post&lt;/a&gt;.)&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
CCTV, will you criticize&amp;nbsp;Baidu and push it to the end-road as well, or just leave it alone because it is a local company, or politically friendly? The rule seems to be: as long as you do not&amp;nbsp;criticize&amp;nbsp;the authority, it is fine to provide "pornographic" content.&lt;br /&gt;
&lt;br /&gt;
Anyway, I feel sorry for Internet users in China, "happy" searching without Google.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-8828571047210766107?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/jrVNQwbI7YU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/8828571047210766107/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=8828571047210766107" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/8828571047210766107?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/8828571047210766107?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/jrVNQwbI7YU/google-leaves-baidu-laughs-users-suffer.html" title="Google Leaves, Baidu Laughs, Users Suffer" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_9g0CxX7-Ez4/S01jlMR0DOI/AAAAAAAAAfc/7wcdEK44XcY/s72-c/Picture+1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2010/01/google-leaves-baidu-laughs-users-suffer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QGR3o5cCp7ImA9WxBREk0.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-7915787434687652358</id><published>2009-12-30T12:20:00.001-08:00</published><updated>2009-12-30T12:35:26.428-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-30T12:35:26.428-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="iPhone" /><category scheme="http://www.blogger.com/atom/ns#" term="Apple" /><title>Turn An Original/3G iPhone To A Video Recorder</title><content type="html">Video recording is one of the most-wanted features of iPhone 3GS to me. My iPhone is still the 3G release and I don't plan on upgrading to 3GS, since I'm not qualified for a standard upgrade until next July. Before I will be able to upgrade to the rumored iPhone 4G, I think it would be cool to do some video recording with my current iPhone. Fortunately, there are several apps now doing this. I did some research and listed what I found here: &lt;br /&gt;
&lt;br /&gt;
&lt;div id="table-div"&gt;&lt;table id="app-table"&gt;&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;App&lt;br /&gt;
&lt;/th&gt;&lt;th&gt;Resolution&lt;br /&gt;
&lt;/th&gt;&lt;th&gt;Frame/Sec&lt;br /&gt;
&lt;/th&gt;&lt;th&gt;Max Length&lt;br /&gt;
&lt;/th&gt;&lt;th&gt;Features&lt;br /&gt;
&lt;/th&gt;&lt;th&gt;Price&lt;br /&gt;
&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt; &lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://labs.laan.com/blog/products/ivideocamera/"&gt;iVideoCamera &lt;/a&gt;&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;160x213&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;3&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;1 min&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;-&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;$0.99&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.kenditech.com/Applications/Entries/2009/12/14_Camcorder.html"&gt;Camcorder &lt;/a&gt;&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;320x426&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;3-7&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;No limit&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;-&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;$0.99&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://ividcam.com/"&gt;iVidCam&lt;/a&gt; (Free) &lt;br /&gt;
&lt;/td&gt;&lt;td&gt;280x360&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;3-7&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;No limit&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;-&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;$0.00&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a href="http://ividcam.com/"&gt;iVidCam &lt;/a&gt;&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;320x427&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;3-7&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;No limit&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;Encode queue, File transfer&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;$0.99&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;3GS :)&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;640x480&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;30&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;No limit&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;Fast encoding, more formats&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;$499.00&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt; &lt;/table&gt;&lt;/div&gt;&lt;br /&gt;
I bought iVidCam. It is pretty good. I especially like its encoding queue feature, with which you can encode videos later when you want to record the next one immediately, and file transfer feature, with which you can transfer videos to computers. The quality is not good, of course, due to both the low frame rate and the low resolution of the camera on 3G, but it is better than nothing.&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript"&gt;
YAHOO.util.Event.addListener(window, "load", function() {
YAHOO.example.EnhanceFromMarkup = new function() {
var myColumnDefs = [
{key:"app",label:"Apps",sortable:true},
{key:"resolution",label:"Resolution", sortable:true},
{key:"frame",label:"Frame/Sec",sortable:true},
{key:"max-length",label:"Max Length", sortable:true},
{key:"features",label:"Features", sortable:true},
{key:"price",label:"Price",formatter:YAHOO.widget.DataTable.formatCurrency,sortable:true}
];

this.parseNumberFromCurrency = function(sString) {
// Remove dollar sign and make it a float
return parseFloat(sString.substring(1));
};

this.myDataSource = new YAHOO.util.DataSource(YAHOO.util.Dom.get("app-table"));
this.myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
this.myDataSource.responseSchema = {
fields: [
{key:"app"},
{key:"resolution"},
{key:"frame"},
{key:"max-length"},
{key:"features"},
{key:"price", parser:this.parseNumberFromCurrency} // point to a custom parser
]
};

this.myDataTable = new YAHOO.widget.DataTable("table-div", myColumnDefs, this.myDataSource,
{caption:"Video capture Apps", sortedBy:{key:"app",dir:"asc"}}
);
};
});
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-7915787434687652358?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/AIbGH308mCI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/7915787434687652358/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=7915787434687652358" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7915787434687652358?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7915787434687652358?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/AIbGH308mCI/turn-original3g-iphone-to-video.html" title="Turn An Original/3G iPhone To A Video Recorder" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/12/turn-original3g-iphone-to-video.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04BR3YzeCp7ImA9WxBREEs.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-3665869061683181193</id><published>2009-12-27T15:42:00.000-08:00</published><updated>2009-12-28T22:59:16.880-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-28T22:59:16.880-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="English" /><title>Understanding English Mistakes Made By Native Chinese Speakers</title><content type="html">Everybody knows learning a new language is not easy. Learning English is especially hard for native Chinese speakers, because English and Chinese are so different in many ways. I think it might be an interesting idea to write down some common mistakes made by native Chinese speakers.&amp;nbsp;It may more or less help native English speakers understand their Chinese speaking friends better. Most of these mistakes make their English looks or sounds strange, while they can usually be understood with enough context. But some of them may cause misunderstanding and confuse the audience.&amp;nbsp;I make these mistakes all the time. I found it is hard to avoid them especially when I talk fast because my brain is not used to these language features. In the meantime, for the same reason, I tend to&amp;nbsp;tolerate&amp;nbsp;those mistakes. For example, I never pay attention to the speaker's using of "he" or "she". So even if the speaker uses the wrong pronouns, I can figure it out who the speaker refers to from the context. That is probably why Chinese people can easily understand each other even when they talk in English with these mistakes. &amp;nbsp;Many things could lead to language mistakes, but I will focus on mistakes related to the grammar differences between English and Chinese.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;b&gt;Using wrong gender of pronoun.&lt;/b&gt; This is the most common mistakes, because in Chinese, "she", "he" and "it" are&amp;nbsp;pronounced&amp;nbsp;in the exactly same way. The grammar&amp;nbsp;differentiates&amp;nbsp;"she", "he" and "it", but not very strict. So native Chinese speakers are not used to considering gender of pronouns, specially for "she" and "he". A few of my friends often complained to me that they got lost after I talk for a while, because I often randomly switch between "he" and "she" and they can not follow whom exactly I&amp;nbsp;refer to.&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Using wrong verb tense.&lt;/b&gt; I&lt;a href="http://en.wikipedia.org/wiki/Grammatical_tense"&gt;n Chinese, tense is not used.&lt;/a&gt; Instead, people rely on context or some adverbs to figure out the time when the action takes place. For example:&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span style="color: red;"&gt;吃&lt;/span&gt; (eat)&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span style="color: #274e13;"&gt;烤鸭&lt;/span&gt; (roast duck)&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span style="color: red;"&gt;吃&lt;/span&gt;&lt;span style="color: #274e13;"&gt;烤鸭&lt;/span&gt; (eat roast duck)&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span style="color: red;"&gt;吃&lt;/span&gt;完&lt;span style="color: #274e13;"&gt;烤鸭&lt;/span&gt;了 (ate roast duck)&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;要去&lt;span style="color: red;"&gt;吃&lt;/span&gt;&lt;span style="color: #274e13;"&gt;烤鸭&lt;/span&gt; (will eat roast duck)&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;正在&lt;span style="color: red;"&gt;吃&lt;/span&gt;&lt;span style="color: #274e13;"&gt;烤鸭&lt;/span&gt; (be eating roast duck)&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Misusing singular/plural forms of nouns and ignoring verb agreement.&lt;/b&gt;&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Grammatical_number#Formal_expression_of_number"&gt;Chinese does not have&amp;nbsp;grammatical number&lt;/a&gt;, which causes three common mistakes:&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Misusing singular/plural forms of nouns, like&amp;nbsp;&amp;nbsp;"I have a computer", " I have two computer" or "I have many computer".&lt;/li&gt;
&lt;li&gt;Using uncountable nouns as countable nouns, like "bought some waters".&lt;/li&gt;
&lt;li&gt;Ignoring verb agreement,&amp;nbsp;like "Mike drink milk", "there is apples on the table".&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;These mistakes could be very misleading when there is no enough context indicating the real quantity.&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Mixing definite and indefinite articles.&lt;/b&gt; This is another very common mistake even when native Chinese speakers write in English, because &lt;a href="http://en.wikipedia.org/wiki/Article_(grammar)#Variation_among_languages"&gt;in Chinese, we do not need to use articles&lt;/a&gt;. You may find native Chinese speakers tend to use "this", "these", "that" and "those" instead of articles, since these words are used in a similar way as articles in Chinese. The most common mistakes about articles are missing articles when they are needed or adding articles when they are not needed. I remember when I was in high school, a lot of questions in English exams are about articles. I would say most of them do not really help me understand how to use articles. This is an example:&lt;br /&gt;
&lt;/div&gt;&lt;blockquote&gt;Let’s go to ____ cinema-that’ll take your mind off the problem for ___ while.&lt;br /&gt;
&lt;br /&gt;
A. the;&amp;nbsp;the &lt;br /&gt;
B. the; a&lt;br /&gt;
C. a; the&lt;br /&gt;
D. a ; a&lt;br /&gt;
&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Not using subjunctive mood&lt;/b&gt;. Chinese grammar does not&amp;nbsp;differentiate the indicative and subjunctive mood, so native Chinese speakers often use the indicative mood when the subjunctive mood&amp;nbsp;should be used. This could be pretty confusing&amp;nbsp;especially&amp;nbsp;when the subjunctive mood should be used to express a hypothesis.&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Using wrong prepositions or missing prepositions.&lt;/b&gt; In Chinese, prepositions are not very critical in grammar. One preposition could be used in many&amp;nbsp;scenarios for different meanings. People often depend on the context and adverbs to decide the meaning of prepositions. For example, the preposition "在" can be used in these sentences:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;在&lt;/b&gt;墙上 (&lt;span style="color: #274e13;"&gt;&lt;b&gt;on&lt;/b&gt;&lt;/span&gt; the wall)&lt;br /&gt;
&lt;b&gt;在&lt;/b&gt;冰箱里 (&lt;b&gt;&lt;span style="color: #274e13;"&gt;in&lt;/span&gt;&lt;/b&gt; the&amp;nbsp;refrigerator)&lt;br /&gt;
&lt;b&gt;在&lt;/b&gt;床上 (&lt;b&gt;&lt;span style="color: #274e13;"&gt;in&lt;/span&gt;&lt;/b&gt; the bed)&lt;br /&gt;
&lt;b&gt;在&lt;/b&gt;那本书里 (&lt;b&gt;&lt;span style="color: #274e13;"&gt;in&lt;/span&gt;&lt;/b&gt; that book)&lt;br /&gt;
&lt;b&gt;在&lt;/b&gt;家 (&lt;b&gt;&lt;span style="color: #274e13;"&gt;at&lt;/span&gt;&lt;/b&gt; home)&lt;br /&gt;
&lt;b&gt;在&lt;/b&gt;桌子下 (&lt;b&gt;&lt;span style="color: #274e13;"&gt;under&lt;/span&gt;&lt;/b&gt; the desk)&lt;br /&gt;
&lt;b&gt;在&lt;/b&gt;北京 (&lt;b&gt;&lt;span style="color: #274e13;"&gt;in&lt;/span&gt;&lt;/b&gt; Beijing)&lt;br /&gt;
&lt;br /&gt;
Many English verbs work with certain prepositions, such as "go to", "shoot at", "single out" and so on. This is not common in Chinese either. In many cases. prepositions are just not needed.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.englishdaily626.com/c-mistakes.php?001"&gt;http://www.englishdaily626.com&lt;/a&gt;&amp;nbsp;has some excellent examples of Chinese-style misusing prepositions:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Chinese Style&lt;/i&gt;: The sun rises &lt;b&gt;&lt;span style="color: red;"&gt;from&lt;/span&gt;&lt;/b&gt; the East.&lt;br /&gt;
&lt;i&gt;American Style&lt;/i&gt;: The sun rises &lt;b&gt;&lt;span style="color: #274e13;"&gt;in&lt;/span&gt;&lt;/b&gt; the East.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Chinese Style&lt;/i&gt;: The thief got in &lt;b&gt;&lt;span style="color: red;"&gt;from&lt;/span&gt;&lt;/b&gt; the window.&lt;br /&gt;
&lt;i&gt;American Style&lt;/i&gt;: The thief got in &lt;b&gt;&lt;span style="color: #274e13;"&gt;through&lt;/span&gt;&lt;/b&gt; the window.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Chinese Style&lt;/i&gt;: Let's begin &lt;b&gt;&lt;span style="color: red;"&gt;from&lt;/span&gt;&lt;/b&gt; page 10.&lt;br /&gt;
&lt;i&gt;American Style&lt;/i&gt;: Let's begin &lt;b&gt;&lt;span style="color: #274e13;"&gt;at ( on )&lt;/span&gt;&lt;/b&gt; page 10.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Chinese Style&lt;/i&gt;: There is a limit &lt;b&gt;&lt;span style="color: red;"&gt;in&lt;/span&gt;&lt;/b&gt; my patience.&lt;br /&gt;
&lt;i&gt;American Style&lt;/i&gt;: There is a limit &lt;b&gt;&lt;span style="color: #274e13;"&gt;to&lt;/span&gt;&lt;/b&gt; my patience.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Chinese Style&lt;/i&gt;: Is your house insured &lt;b&gt;&lt;span style="color: red;"&gt;for&lt;/span&gt;&lt;/b&gt; fire ?&lt;br /&gt;
&lt;i&gt;American Style&lt;/i&gt;: Is your house insured &lt;b&gt;&lt;span style="color: #274e13;"&gt;against&lt;/span&gt;&lt;/b&gt; fire ?&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Chinese Style&lt;/i&gt;: This is the key &lt;b&gt;&lt;span style="color: red;"&gt;of&lt;/span&gt;&lt;/b&gt; my room.&lt;br /&gt;
&lt;i&gt;American Style&lt;/i&gt;: This is the key &lt;b&gt;&lt;span style="color: #274e13;"&gt;to&lt;/span&gt;&lt;/b&gt; my room.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Chinese Style&lt;/i&gt;: He is a student &lt;b&gt;&lt;span style="color: red;"&gt;of&lt;/span&gt;&lt;/b&gt; Harvard University.&lt;br /&gt;
&lt;i&gt;American Style&lt;/i&gt;: He is a student &lt;b&gt;&lt;span style="color: #274e13;"&gt;at&lt;/span&gt;&lt;/b&gt; Harvard University.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-3665869061683181193?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/OLy5ZAcvI0U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/3665869061683181193/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=3665869061683181193" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/3665869061683181193?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/3665869061683181193?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/OLy5ZAcvI0U/understanding-english-mistakes-made-by.html" title="Understanding English Mistakes Made By Native Chinese Speakers" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>6</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/12/understanding-english-mistakes-made-by.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMMQHg_eSp7ImA9WxBSFUk.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-7634110606729346292</id><published>2009-12-15T20:43:00.000-08:00</published><updated>2009-12-22T21:01:21.641-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-22T21:01:21.641-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Trip" /><category scheme="http://www.blogger.com/atom/ns#" term="Pattern Insight" /><title>Company Trip - Day #3</title><content type="html">We visited great scene spots around Lake Tahoe.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyqndU3iYsI/AAAAAAAAAdM/tcdrbgZHrbI/s1600-h/IMG_0717.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyqndU3iYsI/AAAAAAAAAdM/tcdrbgZHrbI/s320/IMG_0717.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyqngcxdqGI/AAAAAAAAAdU/U1bw1jKT33E/s1600-h/IMG_0720.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyqngcxdqGI/AAAAAAAAAdU/U1bw1jKT33E/s320/IMG_0720.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyqniUYBjeI/AAAAAAAAAdc/6JA117Cm3-A/s1600-h/IMG_0733.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyqniUYBjeI/AAAAAAAAAdc/6JA117Cm3-A/s320/IMG_0733.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyqnlZElsII/AAAAAAAAAdk/Nv-ynzbgEo8/s1600-h/IMG_0740.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyqnlZElsII/AAAAAAAAAdk/Nv-ynzbgEo8/s320/IMG_0740.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyqnntUY9eI/AAAAAAAAAds/L8_-7sjYQO4/s1600-h/IMG_0725.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyqnntUY9eI/AAAAAAAAAds/L8_-7sjYQO4/s320/IMG_0725.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
We had lunch in Keys Cafe. It is a small place, but their food is quite nice.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/Syqn6B5CBmI/AAAAAAAAAd0/WOry5HgCYq8/s1600-h/IMG_0750.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/Syqn6B5CBmI/AAAAAAAAAd0/WOry5HgCYq8/s320/IMG_0750.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_9g0CxX7-Ez4/Syqn9eMQOzI/AAAAAAAAAd8/ISHFDzZIXyA/s1600-h/IMG_0751.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_9g0CxX7-Ez4/Syqn9eMQOzI/AAAAAAAAAd8/ISHFDzZIXyA/s320/IMG_0751.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/Syq1GGrTs0I/AAAAAAAAAeE/lCo_gk0mP9U/s1600-h/IMG_0753.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/Syq1GGrTs0I/AAAAAAAAAeE/lCo_gk0mP9U/s320/IMG_0753.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;We saw this, so we bought coffee there :-)&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/Syq1IxYlfyI/AAAAAAAAAeM/LXv3bfCNa8o/s1600-h/IMG_0754.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/Syq1IxYlfyI/AAAAAAAAAeM/LXv3bfCNa8o/s320/IMG_0754.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;On the way back, &lt;a href="http://erikhinterbichler.com/"&gt;Erik&lt;/a&gt; got me addicted to a really cute iPhone game - &lt;a href="http://en.wikipedia.org/wiki/Doodle_Jump"&gt;Doodle Jump&lt;/a&gt;. That's my second favorite iPhone game now, after &lt;a href="http://www.firemint.com/flightcontrol/"&gt;Flight Control&lt;/a&gt;.&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SzGiroCtS5I/AAAAAAAAAeY/vdJC641v6R4/s1600-h/IMG_0281.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SzGiroCtS5I/AAAAAAAAAeY/vdJC641v6R4/s320/IMG_0281.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-7634110606729346292?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/ReBaffi31_c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/7634110606729346292/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=7634110606729346292" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7634110606729346292?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7634110606729346292?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/ReBaffi31_c/company-trip-day-3.html" title="Company Trip - Day #3" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyqndU3iYsI/AAAAAAAAAdM/tcdrbgZHrbI/s72-c/IMG_0717.JPG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/12/company-trip-day-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYARnoyeip7ImA9WxBTGU4.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-7823925409703988500</id><published>2009-12-14T16:42:00.000-08:00</published><updated>2009-12-15T18:22:27.492-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-15T18:22:27.492-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Trip" /><category scheme="http://www.blogger.com/atom/ns#" term="Pattern Insight" /><title>Company Trip - Day #2</title><content type="html">&lt;div style="text-align: left;"&gt;Today is a very beautiful day, perfect to have snow sports.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SybZqNr4ttI/AAAAAAAAAb8/goGzkJxQp18/s1600-h/IMG_0661.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SybZqNr4ttI/AAAAAAAAAb8/goGzkJxQp18/s320/IMG_0661.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SybZvqzOqoI/AAAAAAAAAcE/ZVKV5nlh7-U/s1600-h/IMG_0664.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SybZvqzOqoI/AAAAAAAAAcE/ZVKV5nlh7-U/s320/IMG_0664.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;We left our cabin around 9:45. Everybody was well armed and prepared for some fun.&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SybaLGlp6qI/AAAAAAAAAcM/FRxjB0hTxlo/s1600-h/IMG_0666.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SybaLGlp6qI/AAAAAAAAAcM/FRxjB0hTxlo/s320/IMG_0666.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The &lt;a href="http://www.skiheavenly.com/"&gt;Heavenly Mountain Resort&lt;/a&gt; is less than 1 mile away from our cabin. It looks great.&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SybazsdcIYI/AAAAAAAAAcU/LTUz5oTnd8s/s1600-h/IMG_0672.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SybazsdcIYI/AAAAAAAAAcU/LTUz5oTnd8s/s320/IMG_0672.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SybbZFksScI/AAAAAAAAAcc/oVK4Yg_0aPA/s1600-h/IMG_0678.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SybbZFksScI/AAAAAAAAAcc/oVK4Yg_0aPA/s320/IMG_0678.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;Two of us tried snowboarding and the rest went for skiing. It is so much fun!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SycOjxokYfI/AAAAAAAAAc0/9tko6rusOc8/s1600-h/IMG_0108.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SycOjxokYfI/AAAAAAAAAc0/9tko6rusOc8/s320/IMG_0108.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I will also like to feature two of the snow board players, Spiros and myself:&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SycO52CJKBI/AAAAAAAAAc8/eQXqZkZ39rc/s1600-h/IMG_0112.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SycO52CJKBI/AAAAAAAAAc8/eQXqZkZ39rc/s320/IMG_0112.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SycPGkoJ6-I/AAAAAAAAAdE/0aMFMlSIGfk/s1600-h/IMG_0087.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SycPGkoJ6-I/AAAAAAAAAdE/0aMFMlSIGfk/s320/IMG_0087.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Steak chili is a popular choice for lunch toady.&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SybdssMJztI/AAAAAAAAAcs/t2EIp784dxY/s1600-h/IMG_0676.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SybdssMJztI/AAAAAAAAAcs/t2EIp784dxY/s320/IMG_0676.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
At night, we played PISOP 2009 final table. Our CEO John Lovitt won the first PISOP bracelet!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-7823925409703988500?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/tkAWmsRLjgw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/7823925409703988500/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=7823925409703988500" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7823925409703988500?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7823925409703988500?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/tkAWmsRLjgw/company-trip-day-2.html" title="Company Trip - Day #2" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SybZqNr4ttI/AAAAAAAAAb8/goGzkJxQp18/s72-c/IMG_0661.JPG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/12/company-trip-day-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkYHQ3YycCp7ImA9WxBTF0U.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-3719218125776513535</id><published>2009-12-13T11:48:00.000-08:00</published><updated>2009-12-14T01:48:52.898-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-14T01:48:52.898-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Trip" /><category scheme="http://www.blogger.com/atom/ns#" term="Pattern Insight" /><title>Company Trip - Day #1</title><content type="html">Sameer and myself caught a very early flight from Chicago to San Jose to meet the rest of the team.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyVDyEgXfdI/AAAAAAAAAZU/e1sKgL_PwV0/s1600-h/IMG_0544.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyVDyEgXfdI/AAAAAAAAAZU/e1sKgL_PwV0/s320/IMG_0544.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
We arrived 20 minute earlier than the schedule. As a Silicon&amp;nbsp;Valley airport, San Jose airport offers free wifi access and computer operation tables with power plugs and USB power plugs. Pretty thoughtful, except that the USB plugs do not seem to work.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SyVEkUlRu5I/AAAAAAAAAZc/_YIVELQ0o0E/s1600-h/IMG_0548.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SyVEkUlRu5I/AAAAAAAAAZc/_YIVELQ0o0E/s320/IMG_0548.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
We had enough bad weather in Illinois, so San Jose stopped raining right after we arrived. What a warm welcome!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyVJEOofGSI/AAAAAAAAAZk/idvHRf2oAiI/s1600-h/IMG_0549.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyVJEOofGSI/AAAAAAAAAZk/idvHRf2oAiI/s320/IMG_0549.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
We got everybody together and had lunch at La Bamba, my favorite Mexican&amp;nbsp;restaurant.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyWip0Ro2SI/AAAAAAAAAZs/_jhWcX0SP_w/s1600-h/IMG_0557.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyWip0Ro2SI/AAAAAAAAAZs/_jhWcX0SP_w/s320/IMG_0557.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Although I already had lunch on the plane, I won't miss any chance I am here:&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SyWi3pIHO4I/AAAAAAAAAZ0/nY5s1eUMKWI/s1600-h/IMG_0555.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SyWi3pIHO4I/AAAAAAAAAZ0/nY5s1eUMKWI/s320/IMG_0555.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
We left from Mountain View around 1:15pm. This is one of the cars in our fleet:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyWjTaBep6I/AAAAAAAAAZ8/qqqIrX9Ix78/s1600-h/IMG_0562.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyWjTaBep6I/AAAAAAAAAZ8/qqqIrX9Ix78/s320/IMG_0562.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
On the way, we saw a beautiful rainbow across the highway I-50. It is the first time in my life I see a rainbow this close:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyX_VD_gitI/AAAAAAAAAac/lXn1_7oxJT4/s1600-h/IMG_0586.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyX_VD_gitI/AAAAAAAAAac/lXn1_7oxJT4/s320/IMG_0586.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyWjxAUA7ZI/AAAAAAAAAaM/iP9TwR4lubg/s1600-h/IMG_0593.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyWjxAUA7ZI/AAAAAAAAAaM/iP9TwR4lubg/s320/IMG_0593.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyWj3mR2IPI/AAAAAAAAAaU/ubgyE7PyG_0/s1600-h/IMG_0598.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyWj3mR2IPI/AAAAAAAAAaU/ubgyE7PyG_0/s320/IMG_0598.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Given that Pattern Insight have many coffee lovers, stopping by a coffee shop is&amp;nbsp;necessary&amp;nbsp;to make everybody happy.&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SyX_6hEndTI/AAAAAAAAAak/mhSusCO-q8c/s1600-h/IMG_0604.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SyX_6hEndTI/AAAAAAAAAak/mhSusCO-q8c/s320/IMG_0604.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;South Lake Tahoe, our destination, snows a lot today. When we were close by, the road condition became very very bad.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyYAuhPdl_I/AAAAAAAAAas/yjJ7IZ0zSvg/s1600-h/IMG_0620.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyYAuhPdl_I/AAAAAAAAAas/yjJ7IZ0zSvg/s320/IMG_0620.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SyYA8gPHk2I/AAAAAAAAAa0/WqhiRgKZQ4I/s1600-h/IMG_0628.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SyYA8gPHk2I/AAAAAAAAAa0/WqhiRgKZQ4I/s320/IMG_0628.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;Even the well-known fast driver, Spiros, drove with caution.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyYB22JENFI/AAAAAAAAAa8/PFFK4P0wE_A/s1600-h/IMG_0641.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyYB22JENFI/AAAAAAAAAa8/PFFK4P0wE_A/s320/IMG_0641.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;We finally safely arrived at our cabin. It is very nice house, spacial and&amp;nbsp;comfortable.&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SyYCcjN3VPI/AAAAAAAAAbE/e5lJ4cXdfAM/s1600-h/IMG_0652.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SyYCcjN3VPI/AAAAAAAAAbE/e5lJ4cXdfAM/s320/IMG_0652.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyYDMbZWkCI/AAAAAAAAAbc/Pcz6FYhd_OY/s1600-h/IMG_0649.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyYDMbZWkCI/AAAAAAAAAbc/Pcz6FYhd_OY/s320/IMG_0649.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyYDPoqtYQI/AAAAAAAAAbk/TDrKnb6Un1s/s1600-h/IMG_0644.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyYDPoqtYQI/AAAAAAAAAbk/TDrKnb6Un1s/s320/IMG_0644.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;We had a great dinner at &lt;a href="http://www.nepheles.com/"&gt;Nepheles&lt;/a&gt;. The only thing that made it&amp;nbsp;imperfect was that they do not have food for vegetarians, so Sameer did not have enough food. We went a&amp;nbsp;grocery store and Sameer made some pretty good food by himself afterwards.&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SyYDR1eKQxI/AAAAAAAAAbs/FZgecq9F0wI/s1600-h/IMG_0656.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_9g0CxX7-Ez4/SyYDR1eKQxI/AAAAAAAAAbs/FZgecq9F0wI/s320/IMG_0656.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;PISOP (Pattern Insight Series of Poker) 2009 warm-up event was hold in the cabin after the dinner. We will have PISOP 2009 main event tomorrow.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SyYDUdKrw8I/AAAAAAAAAb0/Ff99pzLa68c/s1600-h/IMG_0659.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SyYDUdKrw8I/AAAAAAAAAb0/Ff99pzLa68c/s320/IMG_0659.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: auto;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-3719218125776513535?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/PHhhg1JgXi4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/3719218125776513535/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=3719218125776513535" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/3719218125776513535?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/3719218125776513535?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/PHhhg1JgXi4/company-trip-day-1.html" title="Company Trip - Day #1" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_9g0CxX7-Ez4/SyVDyEgXfdI/AAAAAAAAAZU/e1sKgL_PwV0/s72-c/IMG_0544.JPG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/12/company-trip-day-1.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcCRHg6eSp7ImA9WxBTFE0.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-629268856029205357</id><published>2009-12-08T22:33:00.001-08:00</published><updated>2009-12-09T15:07:45.611-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-09T15:07:45.611-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Apple" /><title>Notify 2 - The best Gmail notifier on Mac</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/Sx9Jqti0ALI/AAAAAAAAAY8/wjk3guqF0E0/s1600-h/Picture+7.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/Sx9Jqti0ALI/AAAAAAAAAY8/wjk3guqF0E0/s200/Picture+7.png" width="150px" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;I have been struggling to look for a good Gmail notifier on Mac since forever. There are a lot of them, but no one was perfect. I used to use Google's official &lt;a href="http://toolbar.google.com/gmail-helper/notifier_mac.html"&gt;Gmail notifier&lt;/a&gt; on Mac. It is pretty good, but it only supports one account and it misses a few basic functionalities, such as letting the user decide how often to check emails. I asked&amp;nbsp;&lt;a href="http://erikhinterbichler.com/"&gt;Erik&lt;/a&gt;, who wrote &lt;a href="http://erikhinterbichler.com/software/herald/"&gt;Herald&lt;/a&gt;, to write a notifier for people who do not use Mail.App, but he did not have time.&lt;br /&gt;
&lt;br /&gt;
Today, finally, Vibealicious released &lt;a href="http://vibealicious.com/apps/notify/"&gt;Notify 2&lt;/a&gt; and I loved it! The previous version of Notify was not an option to me, because it did not support Google App accounts. But Notify 2 has almost everything I need:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Multiple account support.&lt;/li&gt;
&lt;li&gt;Google App support.&lt;/li&gt;
&lt;li&gt;Basic operations in the app, such as to delete a message, mark as read and such.&lt;/li&gt;
&lt;li&gt;Be able to open a browser window.&lt;/li&gt;
&lt;li&gt;Be able to set up how often to check.&lt;/li&gt;
&lt;/ul&gt;It can be further improved for a few things in my opinion:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The icon on the menu bar is not pretty.&lt;/li&gt;
&lt;li&gt;It should support single-click disable/enable.&lt;/li&gt;
&lt;li&gt;It should show labels, or even use labels to filter notification.&lt;/li&gt;
&lt;li&gt;It should allow different configuration for different accounts.&lt;/li&gt;
&lt;li&gt;It should support multi-selection of mails.&lt;/li&gt;
&lt;li&gt;The interface is good and clean, but I think it could be cooler :-)&lt;/li&gt;
&lt;/ul&gt;Notify 2 supports many other account types as well. If you want an email notifier on Mac, check it out.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Updates&lt;/i&gt;&lt;/b&gt;: Just found out that Notify uses &lt;a href="http://www.mronge.com/code/"&gt;MailCore&lt;/a&gt;, a framework to process emails via IMAP and SMTP,&amp;nbsp;developed&amp;nbsp;by my pal &lt;a href="http://www.mronge.com/"&gt;Matt Ronge&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyAtrvZrshI/AAAAAAAAAZM/3eaTykuGRKU/s1600-h/about.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/SyAtrvZrshI/AAAAAAAAAZM/3eaTykuGRKU/s320/about.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Great job, Matt!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-629268856029205357?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/ZaEk8gs2lS0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/629268856029205357/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=629268856029205357" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/629268856029205357?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/629268856029205357?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/ZaEk8gs2lS0/notify-2-best-gmail-notifier-on-mac.html" title="Notify 2 - The best Gmail notifier on Mac" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_9g0CxX7-Ez4/Sx9Jqti0ALI/AAAAAAAAAY8/wjk3guqF0E0/s72-c/Picture+7.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/12/notify-2-best-gmail-notifier-on-mac.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ICRH07cCp7ImA9WxNaGUk.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-7105369867774418166</id><published>2009-12-04T07:43:00.000-08:00</published><updated>2009-12-04T07:46:05.308-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-04T07:46:05.308-08:00</app:edited><title>Should I just stay here? :-)</title><content type="html">&lt;div style="text-align: center;"&gt;&lt;object height="295" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/cyqxyhccIBk&amp;hl=en_US&amp;fs=1&amp;color1=0x2b405b&amp;color2=0x6b8ab6"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/cyqxyhccIBk&amp;hl=en_US&amp;fs=1&amp;color1=0x2b405b&amp;color2=0x6b8ab6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-7105369867774418166?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/cLQwvki7DKk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/7105369867774418166/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=7105369867774418166" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7105369867774418166?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7105369867774418166?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/cLQwvki7DKk/should-i-just-stay-here.html" title="Should I just stay here? :-)" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/12/should-i-just-stay-here.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQESHw6fCp7ImA9WxBTF0U.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-8869666248651519433</id><published>2009-11-29T15:09:00.000-08:00</published><updated>2009-12-14T01:51:49.214-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-14T01:51:49.214-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Pattern Insight" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>You Must Do Code Review And Do It Right</title><content type="html">Our company started code review about one and half years ago. It is one of the smarted decisions we have made. It significantly improves the code quality and helps programmers learn from each other. Do code review, unless there is only one programmer in your company or you don't care about code quality. I just read a &lt;a href="http://smartbear.com/docs/BestPracticesForPeerCodeReview.pdf"&gt;white paper about code review&lt;/a&gt; from &lt;a href="http://smartbear.com/index.php"&gt;Smart Bear&lt;/a&gt;. It is a very interesting paper. I also have a few tips myself to share.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;First, stop sending patches through emails and pick the right tool for code review&lt;/i&gt;. As a start-up company, we always prefer free tools. We found&amp;nbsp;&lt;a href="http://www.reviewboard.org/"&gt;Review Board&lt;/a&gt;&amp;nbsp;really great. It was developed by a couple engineers in VMWare and used within VMWare originally. It makes the code review very convenient and efficient. We would not have started code review that early if there was no Review Board. With Review Board, all a submitter needs to do is to upload a diff. Review Board automatically pulls files from SCM systems, generates side-by-side diff view and highlights code differences and syntax. People can add conversations on any lines in the diff. Review Board works in an asynchronized way - you don't need to finish a complete review at once. You can do a review piece by piece at your own pace. Review Board also supports follow-up diff files, email notifications and many other cool features. Its interface has been improved significantly after the 1.0 release. If you are open to commercial tools, check out&amp;nbsp;&lt;a href="http://smartbear.com/codecollab.php"&gt;Code Collaborator&lt;/a&gt; from Smart Bear and&amp;nbsp;&lt;a href="http://www.atlassian.com/software/crucible/"&gt;Crucible&lt;/a&gt;&amp;nbsp;from &lt;a href="http://www.atlassian.com/"&gt;Atlassian&lt;/a&gt;. I'm not familiar with them.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Second, pick the right reviewer&lt;/i&gt;. The simple rule is to pick the people who know the background of your changes and have some time to do the review in the near future. Someone suggested to check the reviewer's schedule first, but I think it is too much for small companies. It would help if the review tool shows information about this. For example, the tool can show how many pending reviews the reviewer has right now and how large they are.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Third, submit reviews in the right size.&lt;/i&gt; According to the user study in CISCO, the white paper shows that &lt;i&gt;200-400&lt;/i&gt; line changes is the right size for one review. The longer a review is, the fewer defects can be found and the more boring the review process will be. I absolutely agree with this. The longest code review I have done is about 80 files with thousands of lines of changed code. I had 3 shots of espresso to finish it and I don't think I did a good job. When a review is about 200-400 lines of changes, I feel that I can finish it in 30-60 minutes, so I can be more focus and careful to read every detail.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Forth, respect your reviewers.&lt;/i&gt; Keep in mind that a code review is a big favor your reviewer does you, so try to make it as easy as possible. Prepare the code review well, don't just throw a diff and let your reviewer struggle to understand it. I often review frontend code from one of our engineers. He always attaches screenshots and draws figures to explain the layout and relationship of UI components, which makes the review much easier. I think there are a few things that the submitter should always do:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Explain the rationale behind the review and how it works&lt;/li&gt;
&lt;li&gt;Explain the reason why to change each of the files, which is usually not mentioned in comments in the code&lt;/li&gt;
&lt;li&gt;Guide the reviewer through the review, such as which files should be read first&lt;/li&gt;
&lt;li&gt;Attach additional documents if they help&lt;/li&gt;
&lt;/ul&gt;&lt;i&gt;Fifth, respect your submitters.&lt;/i&gt; When someone sends you a review, it shows that she trusts you. Do the review in a timely manner. If you can't do it in time, talk to the submitter and pass the review to others. More importantly, do the review with responsibility. Code review is the last step to find problems, assume that the submitter already fully tests the changes. After the review, the code will be committed to the repository. So try your best to find problems.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Sixth, a submitter should always address all comments and upload follow-up diffs&lt;/i&gt;. This is a ground rule in our company and it works really well. It makes sure that the submitter responds all problems and fixes them in the code. The reviewer won't give "Ship It!" until follow-up diffs are uploaded.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Seventh, code review is a good opportunity to check unit testing code.&lt;/i&gt; Submitters should submit unit testing code together with the functioning code and reviewers should be responsible to check if the unit testing code is good enough. Keep in mind that unit testing code is as important as functioning code, so it needs to be reviewed as well. Including unit testing code in code review has a few advantages:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Code review covers all new code - perfect coverage.&lt;/li&gt;
&lt;li&gt;The reviewer gets very familiar with the changed code after reading the code, its the best time to review the unit testing code as well.&lt;/li&gt;
&lt;li&gt;The only chance to enforce writing unit testing code. Some testing coverage tools can also do this, but they are inflexible and not be able to find missed unit testing code in finer granularity.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Unit testing code help the reviewer understand the changes.&lt;/li&gt;
&lt;/ul&gt;&lt;i&gt;Last but not the least, build a positive code review culture.&lt;/i&gt; The white paper also mentions this. I think it is very important. We never had culture problems in our company, but we may have it in the future as we grow. There are a few things I think people should do.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Everybody should realize code review is a win-win deal. Both reviewers and submitters learn something from it.&lt;/li&gt;
&lt;li&gt;As a reviewer, don't be harsh. Ask questions before make statements. Code review is not the stage where you show off.&lt;/li&gt;
&lt;li&gt;As a reviewer, don't force everybody else to write code in the &lt;i&gt;exact&lt;/i&gt; some way as you write code. So don't fixating on small things if there is disagreement.&lt;/li&gt;
&lt;li&gt;As a reviewer, inject compliment when you see some cool snippets.&lt;/li&gt;
&lt;li&gt;As a submitter, don't be self-defensive. Remember that the review is about the code, not about people who write the code.&lt;/li&gt;
&lt;li&gt;As a submitter, respond to every comment, nicely. Speak out your reasons if you think some comments are not correct.&lt;/li&gt;
&lt;/ul&gt;I'm happy to hear other good code review experiences.&lt;br /&gt;
&lt;br /&gt;
By the way, Smart Bear&amp;nbsp;also published a book, "Best Kept Secrets of Peer Code Review". I just requested for a free copy from &lt;a href="http://smartbear.com/codecollab-code-review-book.php"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Updates on Dec. 1, 2009&lt;/b&gt;&lt;/i&gt;: modified the description of how Review Board was developed, as pointed out by one of the authors of RB:&amp;nbsp;&lt;a href="http://www.chipx86.com/blog/"&gt;Christian Hammond&lt;/a&gt;. Thanks, Christian!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-8869666248651519433?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/uPjxeVB6VN0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/8869666248651519433/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=8869666248651519433" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/8869666248651519433?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/8869666248651519433?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/uPjxeVB6VN0/you-must-do-code-review-and-do-it-right.html" title="You Must Do Code Review And Do It Right" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>4</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/11/you-must-do-code-review-and-do-it-right.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUICRng7cCp7ImA9WxNaEks.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-8311528651458405400</id><published>2009-11-26T10:59:00.000-08:00</published><updated>2009-11-26T11:26:07.608-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-26T11:26:07.608-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="China" /><title>Peking University's New Tactic Will Not Work In Reality</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_9g0CxX7-Ez4/Sw7PseSq7nI/AAAAAAAAAYI/YBg658lZvig/s1600/peking-univ-new-way.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="268" src="http://4.bp.blogspot.com/_9g0CxX7-Ez4/Sw7PseSq7nI/AAAAAAAAAYI/YBg658lZvig/s320/peking-univ-new-way.jpg" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;(Picture is drawn by Xiaomo Tao. It is from &lt;a href="http://www.jyb.cn/gk/gksd/200911/t20091119_324830.html"&gt;www.jyb.cn&lt;span id="goog_1259260592825"&gt;&lt;/span&gt;&lt;span id="goog_1259260592826"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.blogger.com/"&gt;&lt;/a&gt;)&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
In China, since 1977 the&amp;nbsp;&lt;a href="http://zh.wikipedia.org/zh-cn/%E6%99%AE%E9%80%9A%E9%AB%98%E7%AD%89%E5%AD%A6%E6%A0%A1%E6%8B%9B%E7%94%9F%E5%85%A8%E5%9B%BD%E7%BB%9F%E4%B8%80%E8%80%83%E8%AF%95"&gt;college entrance exam&lt;/a&gt; has been the only way for universities to select students. Although it is just a 3-day exam once every year, it significantly affects tens of millions of people's lives. I'm not exaggerating at all. 10.2 million students took college entrance exams in 2009. When somebody prepares for it, that will be the only thing her whole family care about for about a year.&amp;nbsp;&amp;nbsp;I believe most of them are single-child, which make the number up to about 30 million.&amp;nbsp;This single-exam policy has been criticized for many years, however, nobody could come up with better solutions.&lt;br /&gt;
&lt;br /&gt;
One of the big changes is to give universities the power to select students, instead of depending on nation's Ministry of Education to do everything for everyone. This is good, because universities can use whatever they think is the best way to pick high school graduates. A few days ago, &lt;a href="http://en.pku.edu.cn/"&gt;Peking University&lt;/a&gt;, one of the best universities in China, proposed a brave and&amp;nbsp;&lt;a href="http://www.gotopku.cn/data/detail.php?id=4913"&gt;new tactic&lt;/a&gt;. It chose&amp;nbsp;&lt;a href="http://www.gotopku.cn/data/detail.php?id=4915"&gt;39 high school principals&lt;/a&gt;&amp;nbsp;and let each of them recommend 1-5 students. If these students can pass an additional interview, they will have 30 "free" scores in the college entrance exam next year.&amp;nbsp;This is a new attempt to change the current situation, but the question is - does it really work? Let's start with something I don't like about this plan.&lt;br /&gt;
&lt;br /&gt;
First, one of the key points of this new policy is that the names of these 39 high school principals are public. I don't know how you feel about this, but I feel it is kinda of funny. I'm not sure what it infers. Does it mean that if referees' names are not public, they will not be trusted?&lt;br /&gt;
&lt;br /&gt;
Second, it is not fair to pick certain high schools to recommend students. Does Peking University want to pick students, or another affiliated high school? On the other hand, this is probably a perfect commercial for those 39 high schools. It delivers this message: these 39 high schools are the best high schools in China, go there so you will have chance to be recommended to Peking University.&lt;br /&gt;
&lt;br /&gt;
Third, I think teachers know students better than principals, so they should recommend students. Back to when I was in high school, I only talked to the principal in my high school once or twice. Besides teachers and principals, people outside of schools should also be able to recommend students.&lt;br /&gt;
&lt;br /&gt;
Although I don't agree with all of above, I do understand why Peking University did it. They all boil down to one problem - people do not trust each other. If everybody is trustable, Peking University can simply take any recommendations into account. Unfortunately, they can only trust 39 people after letting everybody know their names. What they want to do is to make accountability very clear. If you have doubts on any of the recommended students, go ask those principals. This also enforces the supervise on referees, so they will not do bad things, such as taking bribes or recommending their friends or relatives.&lt;br /&gt;
&lt;br /&gt;
So, it looks like a good plan, doesn't it? Unfortunately, I don't think it will work in reality. The execution of this new policy will turn to be formalism. Most of those high school principals will probably just recommend students who have best scores in exams - the traditional, but controversial, way to define best students. That is obviously the safest way to do it. Everybody is watching, they don't want to be questioned for doing something "new", or I would say "better". For example, this&amp;nbsp;&lt;a href="http://news.sina.com.cn/c/2009-11-22/100116648593s.shtml"&gt;high school&lt;/a&gt; in Chongqing recommended three students who have the best scores in the recent four exams. These students can probably go to Peking University even without this so-called recommendation.&amp;nbsp;There is nothing wrong with doing this, but&amp;nbsp;if all of other 38 high schools do the same, this new policy does not make any sense, because its original goal is to give opportunities to students who are not usually considered as the best - those who do not have the best scores in exams.&amp;nbsp;I'm very curious what other high schools will do next.&lt;br /&gt;
&lt;br /&gt;
Just like many other problems related to education, how to pick students to colleges is a very hard problem. Having admission hinge on a single exam is definitely a bad idea, but it is probably the best way for now, given the realities in China. Things take time to change. If Peking University's new policy can more or less make a step further on the way, it is worth the effort.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-8311528651458405400?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/My7oTyBbatI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/8311528651458405400/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=8311528651458405400" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/8311528651458405400?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/8311528651458405400?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/My7oTyBbatI/peking-universitys-new-tactic-will-not.html" title="Peking University's New Tactic Will Not Work In Reality" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_9g0CxX7-Ez4/Sw7PseSq7nI/AAAAAAAAAYI/YBg658lZvig/s72-c/peking-univ-new-way.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/11/peking-universitys-new-tactic-will-not.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQMRXwzeCp7ImA9WxNaFEo.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-4593057439593182902</id><published>2009-11-12T22:45:00.000-08:00</published><updated>2009-11-28T23:06:24.280-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-28T23:06:24.280-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>Write Parallel Gomoku AI Programs With The Branch &amp; Bound Pattern</title><content type="html">In today's lecture, we learned the &lt;a href="http://parlab.eecs.berkeley.edu/wiki/patterns/backtrack_branch_and_bound"&gt;Branch &amp;amp; Bound Pattern&lt;/a&gt;. The main idea of this pattern is to explore huge search spaces with multiple threads/processes while applying bounding or pruning strategies to control the size of the search space. This is a very interesting pattern. It reminds me some fun time in high school. When I was in high school. a very popular game among computer geeks was to write programs to play &lt;a href="http://en.wikipedia.org/wiki/Five_in_a_Row_(game)"&gt;Gomoku&lt;/a&gt; (Also names Five-in-a-row). We let programs to compete with each other to see who wrote the smarted programs. The basic rule of Gomoku is straightforward: two people place black/white pieces on a 19x19 Go board in turns. Whoever make five of her colors in a row wins the game.&amp;nbsp;Branch &amp;amp; Bound Pattern is a perfect pattern to parallelize such gaming problems.&lt;br /&gt;
&lt;br /&gt;
The basic idea to make a move in Gomoku games is to go from the current state of the board, explore as many steps in the future as possible, and pick the move with the highest possibility to win finally. For example, after the first white piece is placed, the search graph is something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SxINYbF7IGI/AAAAAAAAAYw/7uWi40NnjeY/s1600/search-space.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="284" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SxINYbF7IGI/AAAAAAAAAYw/7uWi40NnjeY/s320/search-space.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
It's not hard to see that the search space can be huge. Let's think about the four operations in the Branch &amp;amp; Bound Pattern. We define a function &lt;i&gt;G(state)&lt;/i&gt; for each state. &lt;i&gt;G(state)&lt;/i&gt; indicates the chance for the program to win finally.&lt;br /&gt;
&lt;br /&gt;
As for branching, it is straightforward. When the program makes a move, it needs to calculate the &lt;i&gt;G(state)&lt;/i&gt; for each of the to-be states and pick the best choice. &lt;i&gt;G(state)&lt;/i&gt; is actually a recursive function of &lt;i&gt;G(state')&lt;/i&gt; where &lt;i&gt;state'&lt;/i&gt; is the subsequent states of &lt;i&gt;state&lt;/i&gt;. So we need to calculate all&amp;nbsp;&lt;i&gt;G(state')&lt;/i&gt; first.&lt;br /&gt;
&lt;br /&gt;
As for evaluating. &lt;i&gt;G(state)&lt;/i&gt; is used to evaluate states in the search.&lt;br /&gt;
&lt;br /&gt;
As for bounding, Gomoku game is not as trivial as SAT or integer linear programming mentioned in the pattern. It is very hard to efficiently calculate the bonding value of &lt;i&gt;G(state)&lt;/i&gt;. What we can do here is to come up with an estimated &lt;i&gt;Ge(state)&lt;/i&gt; according to the current state and/or &lt;i&gt;Ge(state)&lt;/i&gt; of its sub-states. There are many ideas to calculate &lt;i&gt;Ge(state)&lt;/i&gt;. For example, we can consider how many three-in-a-row &amp;nbsp;cases in each side. The more three-in-a-row cases one side has, the more likely that side will win. Usually we use several strategies and give each of them a weight. The final &lt;i&gt;Ge(state)&lt;/i&gt; is calculated as a function of all strategies.&lt;br /&gt;
&lt;br /&gt;
As for pruning, if a state has been evaluated in other branches or a state's &lt;i&gt;Ge(state)&lt;/i&gt; is worse than the current-best &lt;i&gt;G(state)&lt;/i&gt;, we can prune the branch started by this state. Of source, there can be many tricks to do smarter pruning than this.&lt;br /&gt;
&lt;br /&gt;
To parallelize the searching process, structure-based parallelization is the best fit for this problem. Because&amp;nbsp;all processors should process states in a single pool,&amp;nbsp;we can use either Synchronized-Single-Pool (SSP) or Asynchronized-Single-Pool (ASP) with shared current-best state and visited states. I think the best-state-first strategy may work better then the depth-first strategy. We need to carefully limit the maximum depth to search regardless which search ordering strategy we use.&lt;br /&gt;
&lt;br /&gt;
It is already close to the end of the class, otherwise I think it is a good idea to have a Parallelized Gomoky Program Contest in the class ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-4593057439593182902?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/q6FoBMRym-o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/4593057439593182902/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=4593057439593182902" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/4593057439593182902?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/4593057439593182902?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/q6FoBMRym-o/write-parallel-gomoku-ai-programs-with.html" title="Write Parallel Gomoku AI Programs With The Branch &amp; Bound Pattern" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SxINYbF7IGI/AAAAAAAAAYw/7uWi40NnjeY/s72-c/search-space.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/11/write-parallel-gomoku-ai-programs-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UAR3o_eCp7ImA9WxNaFEs.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-7788315289201276428</id><published>2009-11-07T15:24:00.000-08:00</published><updated>2009-11-28T18:20:46.440-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-28T18:20:46.440-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><category scheme="http://www.blogger.com/atom/ns#" term="OS Research" /><title>Given That Deterministic Replay is Still Slow, What Should We Do for Parallel Debugging?</title><content type="html">Debugging has been tough, and it becomes tougher these days. One of the reasons is that people write more parallel programs and introduce concurrency bugs. Concurrent bugs are especially hard to debug, because many of them do not always show up. There can be many things that make a bug hard to fix, not being reproduced is probably the worst one.&lt;br /&gt;
&lt;br /&gt;
What is the ideal way to debug a parallel program? In my mind, a parallel debugging framework should provide the following:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;In the production run, records the execution with zero or very low overhead.&lt;/li&gt;
&lt;li&gt;In the debugging phase, let people &lt;i&gt;deterministically&lt;/i&gt; replay what happened when the bug manifests. It is even better if the replay can go both forward and backward.&lt;/li&gt;
&lt;li&gt;Programmers can attach their favorite debuggers to the replay session.&lt;/li&gt;
&lt;/ul&gt;This even sounds tempting to sequential debuggers, doesn't it? However, the real world is not ideal. The main problem is that recording introduces huge overhead in the production run. A lot of research has been done to make it faster, but still, there is no very realistic solutions yet, especially for applications that run on multi-processors. In this years &lt;a href="http://www.sigops.org/sosp/sosp09"&gt;SOSP&lt;/a&gt;, there are two papers on this topic:&amp;nbsp;&lt;a href="http://www.sigops.org/sosp/sosp09/papers/park-sosp09.pdf"&gt;Do You Have to Reproduce the Bug at the First Replay Attempt? -- PRES: Probabilistic Replay with Execution Sketching on Multiprocessors&lt;/a&gt; and&amp;nbsp;&lt;a href="http://www.sigops.org/sosp/sosp09/papers/altekar-sosp09.pdf"&gt;ODR: Output-Deterministic Replay for Multicore Debugging&lt;/a&gt;. They both send out three interesting messages:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;They are both software-only solutions.&lt;/li&gt;
&lt;li&gt;They both make compromise - push the complexity from recording to replaying.&lt;/li&gt;
&lt;li&gt;They both work on multiprocessors.&lt;/li&gt;
&lt;/ul&gt;This trend shows that people become more realistic about this hard problem. First, software-only solutions are preferred, because they are easier to implement. Don't get me wrong. I'm not saying hardware-based or software-hardware-hybrid solutions are unrealistic, but they indeed take longer time to become real. Second, people compromise something that is less important to make more important things to be feasible. Third, multiprocessors are so common today, so a realistic solution should work with it.&lt;br /&gt;
&lt;br /&gt;
The idea of PRES is to sacrifice the efficiency of replay. Instead of reproducing the buggy execution at the first try, it requires more than one attempts to reproduce it. Meanwhile, the reward of this is that it only needs to record much less information in the production run. One could think of it as PRES drawing a "sketch" in the production run, instead of a "finished paint". Although it may need to try several times to recover the "finished paint", but "sketch" is fast and enough to catch a rough idea about what happened. If painters use this idea, why can't we? Very smart! During replaying, PRES uses both the sketch from the production run and feedbacks from previously failed attempts. The idea is that when PRES encounter a data race that has not been recorded in the production run, it makes a random guess. As soon as PRES finds out the execution does not match the sketch any more, or does not reproduce symptoms in the buggy execution, what it will do is to roll back a bit, flip some data races and give it another try.&amp;nbsp;This actually reminds me about another paper, &lt;a href="http://opera.ucsd.edu/paper/Rx-SOSP05.pdf"&gt;Rx&lt;/a&gt;, which is one of the system research papers that I like the most.&lt;br /&gt;
&lt;br /&gt;
The idea of ODR is to sacrifice the accuracy of replay. Instead of reproducing the buggy execution based on internal values, it tries to reproduce an execution that has the same output as the buggy one. Output includes segment fault, core dump, print out strings and such. The reproduced execution may be different from the buggy one, but the rationale behind this idea is that if it has the same output, it is very likely that the bug that appears in the buggy execution also manifests in the reproduced execution. If output-determinism is enough, why would we want value-determinism?&lt;br /&gt;
&lt;br /&gt;
There are many other good papers about deterministic replay for debugging parallel programs. If interested, you can find more from the references of these two papers.&lt;br /&gt;
&lt;br /&gt;
Besides academic research, VMWare's replay debugger is a production-class parallel debugger tool. Although it only works for single processor execution, it has almost everything an ideal parallel program debugger should have. I was really really impressed.&amp;nbsp;&lt;a href="http://www.elewis.net/"&gt;E Lewis&lt;/a&gt; gave talk in Google about it:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;object height="285" width="340"&gt;&lt;param name="movie" value="http://www.youtube.com/v/RvMlihjqlhY&amp;hl=en&amp;fs=1&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/RvMlihjqlhY&amp;hl=en&amp;fs=1&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="340" height="285"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-7788315289201276428?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/N6HKAZ_Z4Ak" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/7788315289201276428/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=7788315289201276428" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7788315289201276428?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/7788315289201276428?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/N6HKAZ_Z4Ak/deterministic-reply-is-still-slow-what.html" title="Given That Deterministic Replay is Still Slow, What Should We Do for Parallel Debugging?" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>5</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/11/deterministic-reply-is-still-slow-what.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UESHo6cSp7ImA9WxNaFEs.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-1283450840952872741</id><published>2009-10-31T21:46:00.000-07:00</published><updated>2009-11-28T18:20:09.419-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-28T18:20:09.419-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>Programming is not as easy as it sounds</title><content type="html">(After reading "&lt;a href="http://norvig.com/21-days.html"&gt;Teach Yourself Programming in Ten Years&lt;/a&gt;" by &lt;a href="http://norvig.com/"&gt;Peter Norvig&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
I found this article after I read &lt;a href="http://st-www.cs.illinois.edu/users/johnson/"&gt;Prof. Johnson&lt;/a&gt;'s &lt;a href="http://www.cincomsmalltalk.com/userblogs/ralph/blogView?showComments=true&amp;amp;printTitle=Teach_yourself_programming_in_ten_years&amp;amp;entry=3433826000"&gt;blog post&lt;/a&gt; about it. All the points from this article are so true and I think every programmer should read it.&lt;br /&gt;
&lt;br /&gt;
Back to when I was in college, many students in Computer Science major thought programming is easy and kind of boring. It only requires time but less skills. Many people who have been programming for years after school still think in the same way. I think the major reason is that as computer hardware, programming languages and development tools has been improving so fast in the past decades, writing runnable and reasonably fast programs requires lower and lower learning curve. Even if you know nothing about computers, you can probably write a piece of Python code to do quite something in one or two days. However, does it really mean that programming become no-brainer now? It certainly does not.&amp;nbsp;&amp;nbsp;The superficial simplicity prevents people from thinking more about it.&amp;nbsp;Just like Peter Norvig, I also have a few tips about how to teach yourself programming.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;First thing first, make yourself interested in programming&lt;/b&gt;&lt;/i&gt;. Maybe programming is not one of your dream jobs, but if it is what you do now, try to become interested in it. This helps you kill the pains and have more enjoyable programming time.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;If you did not know computers much, try to learn something about it.&lt;/b&gt;&lt;/i&gt; I strongly recommend a few books for basic concepts:&amp;nbsp;&lt;a href="http://www.amazon.com/Computer-Organization-Design-Fourth-Architecture/dp/0123744938/ref=dp_cp_ob_b_title_2"&gt;Computer Organization and Design: The Hardware/Software Interface&lt;/a&gt;,&amp;nbsp;&lt;a href="http://www.amazon.com/Computer-Architecture-Quantitative-Approach-4th/dp/0123704901/ref=pd_sim_b_1"&gt;Computer Architecture: A Quantitative Approach&lt;/a&gt;,&amp;nbsp;&amp;nbsp;&lt;a href="http://www.amazon.com/Modern-Operating-Systems-2nd-GOAL/dp/0130313580"&gt;Modern Operating Systems&lt;/a&gt;&amp;nbsp;and &lt;a href="http://www.amazon.com/Computer-Networks-Andrew-S-Tanenbaum/dp/0133499456"&gt;Computer Networks&lt;/a&gt;. These books are all very well written and teach you many things you should know when you write programs. Without this knowledge, you won't be able to understand many important aspects of programming, such as pointers, why buffered I/O streams are faster, how to use threads correctly to avoid concurrency bugs and so on. Additionally,&amp;nbsp;&lt;a href="http://research.google.com/people/jeff/index.html"&gt;Jeff Dean&lt;/a&gt;&amp;nbsp;has a list of numbers he believes everybody should know:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9g0CxX7-Ez4/Su0AxV2WGaI/AAAAAAAAAXk/g1_Rlob2xTE/s1600-h/Picture+9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_9g0CxX7-Ez4/Su0AxV2WGaI/AAAAAAAAAXk/g1_Rlob2xTE/s400/Picture+9.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;(from the slides of Jeff Dean's talk&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.cs.cornell.edu/projects/ladis2009/talks/dean-keynote-ladis2009.pdf"&gt;Designs, Lessons and Advice from Building Large Distributed Systems&lt;/a&gt;)&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Read the&amp;nbsp;&lt;/i&gt;&lt;/b&gt;&lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1257046302&amp;amp;sr=1-1"&gt;&lt;b&gt;&lt;i&gt;Design Patterns&lt;/i&gt;&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&lt;i&gt;&amp;nbsp;book once a year.&lt;/i&gt;&lt;/b&gt; I personally think this is the &lt;i&gt;best&lt;/i&gt; book about programming I have ever read. It opens a new door to think about programing. When you read this book, think more beyond patterns for OO programming. There are actually programming patterns everywhere and they are powerful weapons to conquer system design problems. The more patterns you know, the more choices and beautiful ideas you will have when you design a system.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Open your mind and learn more languages even if you do not need them for work&lt;/i&gt;&lt;/b&gt;. Learning a new language helps you re-think programming. For example, say you are a Java programmer originally, when you learn Python, the first thing you may think about is dynamic typing. It may make you feel uncomfortable at the beginning, because you are so afraid that you will make typing mistakes. But after a while, you may feel dynamic typing helps you write programs faster. OK, now what, is it good or bad after all?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Read other people's code.&lt;/i&gt;&lt;/b&gt; One of the best ways to learn is to learning by examples, either good examples or bad examples. You can read open source code or read code written by your colleagues. Remember it when you think their code is good and try to improve it when you think their code is not that good. Our company has very strict code review policy. I learned a lot by reviewing other people's code and letting them review my code.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Get familiar with software development tools&lt;/i&gt;&lt;/b&gt;. There is a Chinese epigram saying "sharpen your knife before you cut wood" (工欲善其事，必先利其器). Many great development tools can significantly improve efficiency and quality of software development. Take Java as an example. Java is famous for having many great tools. Just to name a few open-source tools:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;IDE: Eclipse, NetBeans&lt;/li&gt;
&lt;li&gt;Buidling: Ant, Maven&lt;/li&gt;
&lt;li&gt;Debugging: jdb, &lt;a href="http://java.sun.com/javase/6/docs/technotes/tools/share/jhat.html"&gt;jhat&lt;/a&gt; (heap analysis), &lt;a href="http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html"&gt;jconsole&lt;/a&gt; (monitoring), Eclipse integrated debugging features.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Profiling: &lt;a href="http://java.sun.com/developer/technicalArticles/Programming/HPROF.html"&gt;jprof&lt;/a&gt;, &lt;a href="http://profiler.netbeans.org/"&gt;NetBeans Profiler&lt;/a&gt; (I really like this)&lt;/li&gt;
&lt;li&gt;Static analysis tools: &lt;a href="http://findbugs.sourceforge.net/"&gt;FindBugs&lt;/a&gt;, &lt;a href="http://pmd.sourceforge.net/"&gt;PMD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Unit testing: &lt;a href="http://www.junit.org/"&gt;JUnit&lt;/a&gt; framework, &lt;a href="http://emma.sourceforge.net/"&gt;Emma&lt;/a&gt; (check unit testing coverage)&lt;/li&gt;
&lt;/ul&gt;&lt;i&gt;&lt;b&gt;Always keep in mind that testing rocks, debugging sucks. &lt;span style="font-style: normal;"&gt;&lt;span style="font-weight: normal;"&gt;I did not really realize this until I started working in the company. I would say making solid testing is one of the biggest lessons I learned in the real world. Good testing can totally change the quality of a program and "life quality" of programmers. Once you adopt test-driven development, you will never go back.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Think while you do.&lt;/i&gt;&lt;/b&gt;&amp;nbsp;This is more about attitude. Even if you are in charge of just a small component of a large system, don't always bind your mind to that particular component. Think about big pictures, such as how the whole system works, what are good and what are bad, how to improve it and so on. If you think more, you will find you can learn a lot even if you are working on something that you thought was boring before.&lt;br /&gt;
&lt;br /&gt;
Happy programming. :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-1283450840952872741?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/WLkgcIb6rDg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/1283450840952872741/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=1283450840952872741" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/1283450840952872741?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/1283450840952872741?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/WLkgcIb6rDg/programming-is-not-as-easy-as-it-sounds.html" title="Programming is not as easy as it sounds" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_9g0CxX7-Ez4/Su0AxV2WGaI/AAAAAAAAAXk/g1_Rlob2xTE/s72-c/Picture+9.png" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/10/programming-is-not-as-easy-as-it-sounds.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4MSXc9eyp7ImA9WxNUEEQ.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-4032351234220013241</id><published>2009-10-25T21:59:00.000-07:00</published><updated>2009-11-01T08:46:28.963-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-01T08:46:28.963-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Quote" /><title>When to learn a new language?</title><content type="html">&lt;span style="font-family: georgia, 'times new roman', times, serif; font-size: 15px; line-height: 22px;"&gt;"A language that doesn't affect the way you think about programming, is not worth knowing."&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: georgia, 'times new roman', times, serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 22px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: right;"&gt;&lt;span style="font-family: georgia, 'times new roman', times, serif; font-size: medium;"&gt;&lt;span style="font-size: 15px; line-height: 22px;"&gt;-- &lt;a href="http://en.wikipedia.org/wiki/Alan_Perlis"&gt;Alan Perlis&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
(&lt;a href="http://www-pu.informatik.uni-tuebingen.de/users/klaeren/epigrams.html"&gt;Epigrams on Programming&lt;/a&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;I like this epigram so much. How did the languages you have learned affect the way you think about programming?&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-4032351234220013241?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/yuaG_aVCiPc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/4032351234220013241/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=4032351234220013241" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/4032351234220013241?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/4032351234220013241?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/yuaG_aVCiPc/when-to-learn-new-language.html" title="When to learn a new language?" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/10/when-to-learn-new-language.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YCQHYzfip7ImA9WxNWGE8.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-2928688390065354209</id><published>2009-10-17T16:12:00.000-07:00</published><updated>2009-10-17T16:12:41.886-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-17T16:12:41.886-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Quote" /><category scheme="http://www.blogger.com/atom/ns#" term="Apple" /><title>What does Steve Jobs say about design?</title><content type="html">&lt;span class="Apple-style-span" style="font-family: georgia, 'times new roman', times, serif; font-size: 15px; line-height: 22px;"&gt;''People think it's this veneer -- that the designers are handed this box and told, 'Make it look good!' That's not what we think design is. It's not just what it looks like and feels like. Design is how it works.''&lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: right;"&gt;&lt;span style="font-family: georgia, 'times new roman', times, serif; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; line-height: 22px;"&gt;-- Steve Jobs&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-2928688390065354209?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/cVdkaY9bLPQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/2928688390065354209/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=2928688390065354209" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/2928688390065354209?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/2928688390065354209?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/cVdkaY9bLPQ/what-does-steve-jobs-say-about-design.html" title="What does Steve Jobs say about design?" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/10/what-does-steve-jobs-say-about-design.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UBRXozcSp7ImA9WxNaFEs.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-1255963387664473751</id><published>2009-10-14T10:40:00.000-07:00</published><updated>2009-11-28T18:20:54.489-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-28T18:20:54.489-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>"Stress Testing On Concurrent Problems - CHESS</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SxG0Y4da2zI/AAAAAAAAAYo/y9ZnA4iOL8w/s1600/ChessLogoWebpage.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SxG0Y4da2zI/AAAAAAAAAYo/y9ZnA4iOL8w/s320/ChessLogoWebpage.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;Testing concurrent problems, such as data races, deadlock and so on, could be very hard. This kind of problems only happen with certain input and highly depend on how threads/processes are scheduled. In order to have good coverage of threads/processes schedules, people need to run the same testing many times and keep their fingers crossed to run into concurrent problems if there is any. This doesn't work well for problems that happen very rarely. People sometimes also use stress testing, testing with very heavy workload, to find potential concurrent problems. But this doesn't work well either, because heavy workload may introduce more concurrent operations, but it does not mean to introduce the right concurrent operations/orders to trigger concurrent problems.&lt;br /&gt;
&lt;br /&gt;
The &lt;a href="http://research.microsoft.com/en-us/projects/chess/"&gt;CHESS project&lt;/a&gt; from Microsoft Research tried to solve this problem. CHESS uses model checking technologies to explore different concurrent schedules, more specifically - how threads interleaves with each other, to find the one with concurrent problem. Once the problematic schedule is found, CHESS is able to accurately reproduce it later and let programmers debug the program. As an example from their paper, CHESS reported a deadlock after executing &lt;i&gt;6,727&lt;/i&gt; different schedules in about 20 seconds. This is apparently is one of those tricky current bugs that take days to find.&lt;br /&gt;
&lt;br /&gt;
The most interesting part to me about CHESS is how it controls the state space. It is not hard to imagine that the number of different schedules of a multi-threading program can be huge. CHESS uses various technologies to shrink the search space. There are two major strategies. The first one is preemption bounding - to limit the number of preemptions and use them carefully. According their &lt;a href="http://research.microsoft.com/en-us/projects/chess/pldi07-iterativecontextbounding.pdf"&gt;previous paper&lt;/a&gt;, it shows that if the schedule desides a part of the preemptions, the rest of the schedule is determined automatically. Basically a problematic schedule only depends on a few preemptions to happen at the right places. The experience shows that having at most 2 preemptions is enough to find serious concurrency bugs. The other approach CHESS uses is to cache visited program states to prune redundant search. The questions is that what can be used as program state in terms of concurrent behaviors? CHESS uses happens-before graphs. The rationale is that "two executions that generate the same happens-before graph only differ in the order of independent synchro-nizations operations".&lt;br /&gt;
&lt;br /&gt;
Microsoft Research already integrated CHESS into Visual Studio 2008. It works for multi-threaded single-process application. If you are interested, &lt;a href="http://research.microsoft.com/en-us/projects/chess/download.aspx"&gt;download&lt;/a&gt; and give it a try. For latest updates about CHESS, check out its &lt;a href="http://blogs.msdn.com/chess/"&gt;blog&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-1255963387664473751?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/ldKqEnj6RGU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/1255963387664473751/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=1255963387664473751" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/1255963387664473751?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/1255963387664473751?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/ldKqEnj6RGU/stress-testing-on-concurrent-problems.html" title="&quot;Stress Testing On Concurrent Problems - CHESS" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_9g0CxX7-Ez4/SxG0Y4da2zI/AAAAAAAAAYo/y9ZnA4iOL8w/s72-c/ChessLogoWebpage.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/10/stress-testing-on-concurrent-problems.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYER307fip7ImA9WxNaFEo.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-2695319793459341774</id><published>2009-10-08T19:50:00.000-07:00</published><updated>2009-11-28T20:48:26.306-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-28T20:48:26.306-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>Refactor Java Loops With ParallelArray</title><content type="html">&lt;i&gt;(After reading "&lt;/i&gt;&lt;a href="https://netfiles.uiuc.edu/dig/papers/ReLooper.pdf"&gt;&lt;i&gt;ReLooper: Refactoring for Loop Parallelism&lt;/i&gt;&lt;/a&gt;&lt;i&gt;")&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
The ParallelArray Framework is a new feature in Java 7 &amp;nbsp;that provides parallel operations on an array. For example, the programmers can apply a modification on each element of an array, map each element of an array to element of another array, reduce a set of element of an array to a value and so on. These operations will be parallelized by with ParallelArray Framework automatically.&amp;nbsp;&lt;a href="https://netfiles.uiuc.edu/dig/RefactoringInfo/tools/ReLooper/"&gt;ReLooper&lt;/a&gt; is tool that helps programmer rewrite existing loops using ParallelArray to improve performance. It delivers 1.32-1.96x performance speedup on a 2-core machine.&lt;br /&gt;
&lt;br /&gt;
Rewriting a loop to a parallelized version with ParallelArray is not hard. The hard part is make sure the new loop behaves correctly as the originally loop. Relooper uses several static analysis technologies to analyze a loop to make sure it can be safely parallelized with ParallelArray. If Relooper finds any potential problems, it warns the user before start refactoring. There are mainly three constraints that may prevent a loop from being parallelized.&lt;br /&gt;
&lt;br /&gt;
First, the original loop should go through &lt;i&gt;all&lt;/i&gt; elements in the array in order and there is no inter-iteration dependency. If the original loop is a for-loop. Relooper should check if the iteration variable is used as the index of the array and if the iteration variable changes from 0 to the length of the array. Relooper also checks if any control flow statements, such as break, return and continue, skip some array operations.&lt;br /&gt;
&lt;br /&gt;
Second, Relooper checks if different iterations of the original loop access shared data. If there is any conflict accesses, the original loop can not be parallelized easily. This check if not trivial because of the complexity of memory reference analysis and method calls. Relooper develops an inter-procedure data-flow analysis to do the check.&lt;br /&gt;
&lt;br /&gt;
Third, the original loop should not have blocking I/O operations. Because ParallelArray uses Fork/Join Framework to parallelize operations, blocking I/O can significantly hurt the performance.&lt;br /&gt;
&lt;br /&gt;
These constraints make a lot of sense, but in my opinions, they do not completely kill the opportunity to parallelize a loop. It would be better if the paper can describe what should be done if any of them happen. Is there anything smart Relooper can do to still parallelize the code, or programmers have to be involved to make the decision or even adjust the code?&lt;br /&gt;
&lt;br /&gt;
Relooper is implemented as an Eclipse plug-in and you can download it from &lt;a href="https://netfiles.uiuc.edu/dig/RefactoringInfo/tools/ReLooper/"&gt;its website&lt;/a&gt;. I really appreciate the author's effort to make it real and usable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-2695319793459341774?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/dTJs5t2rGNo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/2695319793459341774/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=2695319793459341774" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/2695319793459341774?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/2695319793459341774?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/dTJs5t2rGNo/refactor-java-loops-with-parallelarray.html" title="Refactor Java Loops With ParallelArray" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/10/refactor-java-loops-with-parallelarray.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YCRX09cSp7ImA9WxNaFEs.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-4506504965739458913</id><published>2009-10-07T17:01:00.000-07:00</published><updated>2009-11-28T18:19:24.369-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-28T18:19:24.369-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>Refactor Java Programs To Take Advantage of Concurrency</title><content type="html">&lt;i&gt;(After reading "&lt;/i&gt;&lt;a href="http://portal.acm.org/citation.cfm?id=1555001.1555054&amp;amp;coll=ACM&amp;amp;dl=ACM&amp;amp;CFID=50133825&amp;amp;CFTOKEN=75787924"&gt;&lt;i&gt;Refactoring sequential Java code for concurrency via concurrent libraries&lt;/i&gt;&lt;/a&gt;&lt;i&gt;".)&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
There are more and more new libraries and language supports to help programmer write better concurrent code. They greatly benefit writing new code, but how about existing code? We probably need new code refactoring technologies to improve existing code. &amp;nbsp;This paper proposed a tool, &lt;a href="https://netfiles.uiuc.edu/dig/RefactoringInfo/tools/Concurrencer/"&gt;CONCURRENCER&lt;/a&gt;, which can refactor existing sequential Java programs to take advantage of the &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/package-summary.html"&gt;java.util.concurrent&lt;/a&gt; (j.u.c) library.&amp;nbsp;CONCURRENCER contains three main refactoring technologies.&lt;br /&gt;
&lt;br /&gt;
First, it can convert usages of an int field into &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html"&gt;AtomicInteger&lt;/a&gt;. This can make sure that access to this field become thread-safe. Besides AtomicInteger, the j.u.c library also provides a few other &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/atomic/package-summary.html"&gt;atomic data types&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Second, it can convert usage of HashMap into &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html"&gt;ConcurrentHashMap&lt;/a&gt;. The traditionally way to make a map thread-safe is to use lock to protect every operation on this map, which introduce unnecessary contention. &amp;nbsp;ConcurrentHashMap is a pretty cool class in the j.u.c library to solve this problem. It uses a smarter locking mechanism to allow concurrent retrieval operations and partial-concurrent update operations. It divides the hash table into chunks and each chunk has its own update lock. So different chunks can be updated concurrently.&lt;br /&gt;
&lt;br /&gt;
Third, the most complex, it can convert a recursive method to a new version based on the Fork/Join framework. To solve a divide-and-conquer problem, the Fork/Join Framework recursively solve one task by using multiple threads to solve its sub-tasks, wait all of them to finish and then aggregate the results for the original task. I &lt;a href="http://blog.xiao-ma.com/2009/09/from-threadjoin-to-invokeall-to.html"&gt;wrote about this framework&lt;/a&gt; before. According to the experiments, this refactoring strategy can improve the average performance of a sequential recursive method to 2.97x (on 4-core systems).&lt;br /&gt;
&lt;br /&gt;
I like this paper because I think it is practical. Each of these three refactoring ideas looks small, but if they can be correctly applied, they can much improve the code quality and performance of existing sequential programs. The authors also mentioned that they keep looking for refactoring opportunities to take advantage of other features in the j.u.c library.&lt;br /&gt;
&lt;br /&gt;
One problem of&amp;nbsp;CONCURRENCER is that it depends on the programmer to pick the code to refactor. It would be more helpful if it can collaborate with other static analysis tools to find this code automatically.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-4506504965739458913?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/aHshooD4trk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/4506504965739458913/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=4506504965739458913" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/4506504965739458913?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/4506504965739458913?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/aHshooD4trk/refactor-java-programs-to-take.html" title="Refactor Java Programs To Take Advantage of Concurrency" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/10/refactor-java-programs-to-take.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QFRXc6fip7ImA9WxNaFEs.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-9075052674991823680</id><published>2009-10-02T16:47:00.000-07:00</published><updated>2009-11-28T18:21:54.916-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-28T18:21:54.916-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Reading" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>"Creeping Featurism is a Strength" if it is done right.</title><content type="html">&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;i&gt;(Reading notes for Chapter 11 of "Beautiful Architecture" GNU Emacs: Creeping Featurism Is a Strength)&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;This chapter describes the software architecture of Emacs and discusses its creeping featurism "problem". Creeping featurism means that people tend to put more and more features into a system and eventually make it too complicated to manage. Many people think creeping featurism leads to no good, but if it can certainly become a strength if it is done right.&amp;nbsp;Software becomes very complicated these days and people expect more and more from software. So a closed system is very hard to be very successful. We can see this tendency from desktop applications, like &lt;a href="https://addons.mozilla.org/en-US/firefox/"&gt;Firefox&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/IPhoto#Plugins"&gt;iPhoto&lt;/a&gt; and so on, to enterprise software, like &lt;a href="http://www.splunk.com/apps?src=sb"&gt;SplunkBase&lt;/a&gt;, to web-based applications, like Facebook.&lt;br /&gt;
&lt;br /&gt;
Extension is especially important&amp;nbsp;for open source software which usually has a lot of uncentralized developers and users. &amp;nbsp;I will talk about a few thoughts on how to make a software system open to extensions but in the meantime prevent creeping featurism.&lt;br /&gt;
&lt;br /&gt;
Firstly, a system should have a fairly simple data model. The book chapter compares the data model of Emacs and the data model of Microsoft Word. I think this is a very good example. The simplicity of Emacs data model, strings of characters, makes it much easier to extend then MS Word, I'm not criticizing MS Word, after all, Emacs is an editor, not a word processor.&lt;br /&gt;
&lt;br /&gt;
Secondly, the interface between the core part of a system and its other rich features should be clear and well defined. Emacs'&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;MVC&lt;/a&gt; model is a good example again. Views are automatically updated once a relevant model change is detected. The core controller is written in C, but the controller code of most command we use is written in Emacs Lisp, which is also used as the major language to develop extensions. This design lets extensions integrated into the whole system naturally. Most extension code can be modified without recompiling the core Emacs, even without restarting Emacs.&lt;br /&gt;
&lt;br /&gt;
Thirdly, a system should have a good default set of features that fit common needs. Most Emacs users only use a small subset of its features, but a complete installation of Emacs is already pretty big, it takes time to start and occupies quite some system resource when running. This is actually one of the major attacks from Vi advocators. To find the balance between efficiency and reasonable set of features is hard. This &lt;a href="http://www.interaction-design.org/encyclopedia/featuritis_and_creeping_featurism.html"&gt;article&lt;/a&gt; presents one solution of having different sets of default features, like expert mode, normal mode, hardcore mode and such.&lt;br /&gt;
&lt;br /&gt;
Fourthly, to make it very easy to install an extension. If it takes hours to install an extension, I don't believe people will do it at all. Emacs extensions are not trivial to install. For most of them, you need to modify your ".emacs" configuration file and copy package files to the right place. For some of them, it even requires compiling and/or installing new stuff. Software like Eclipse and Firefox do a better job on this.&lt;br /&gt;
&lt;br /&gt;
Finally, to have a good platform for people to share and look for extensions is important. If a system is designed to be extend, extensions should be managed efficiently and provide good communication between people who write extensions and people to require new features.&lt;br /&gt;
&lt;br /&gt;
Making enterprise software extendable and control its feature scale is quite different from to do so to open source software. I will probably write another post about that.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-9075052674991823680?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/frAtHorJpOg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/9075052674991823680/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=9075052674991823680" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/9075052674991823680?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/9075052674991823680?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/frAtHorJpOg/creeping-featurism-is-strength-if-it-is.html" title="&quot;Creeping Featurism is a Strength&quot; if it is done right." /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/10/creeping-featurism-is-strength-if-it-is.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UDRH8-eip7ImA9WxNaFEs.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-9015065806479326794</id><published>2009-09-29T13:17:00.000-07:00</published><updated>2009-11-28T18:21:15.152-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-28T18:21:15.152-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>Why to implement a JVM in Java?</title><content type="html">&lt;i&gt;(Reading notes for Chapter 10 of "Beautiful Architecture" - The Strength of Metacircular Virtual Machine: Jikes RVM)&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
I heard about &lt;a href="http://jikesrvm.org/"&gt;Jikes RVM&lt;/a&gt; before as popular in the Java runtime environment research community, but I didn't think through what exactly implementing a JVM in Java benefits research in particular, or in general. I still held this question before I read this chapter.&lt;br /&gt;
&lt;br /&gt;
This chapter is pretty clear. I especially like the part talking about myths surrounding runtime environments. It would be better if the book can also compare Jikes with other&amp;nbsp;metacircular architectures, not necessary&amp;nbsp;JVMs.&amp;nbsp;Combining this chapter and some other articles, I think the advantages to implement a JVM in Java are two folds. First of all, it offers an opportunity to have better understanding of the language, especially how applications talk with run time environment and performance-critical features. So we can implement them in a better way. Secondly, in terms of performance, this implementation moves the Java/non-Java boundary crossing overhead below JVM instead of above JVM, which opens doors to more efficient implementation ideas and dynamic optimization opportunities. However, the question is that whether it is desirable to build a &lt;i&gt;production-class&lt;/i&gt; JVM in Java. I still doubt it.&lt;br /&gt;
&lt;br /&gt;
As a big system fan, I'm interested on how Jikes bootstraps itself and communicates with hardware/OS. I went through some research&amp;nbsp;literals&amp;nbsp;and found this paper,&amp;nbsp;&lt;a href="http://cs.anu.edu.au/~Steve.Blackburn/teaching/comp4700/resources/papers/jalapeno-oopsla-1999.pdf"&gt;Implementing Jalapeño in Java&lt;/a&gt;, is a must-read.&amp;nbsp;Jalapeño is the predecessor of Jikes. This paper describes the original motivation of the&amp;nbsp;Jalapeño&amp;nbsp;project in IBM Research and the challenges they encountered at the early age. Very interesting. You can find answers for these questions:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;How do they implement the first few essence components of a JVM, a not-very-efficient baseline compiler, a dynamic class loader, a simple memory manager and a debugger?&lt;/li&gt;
&lt;li&gt;How do they generate a boot-strap image of these components and load it to start&amp;nbsp;Jalapeño?&lt;/li&gt;
&lt;li&gt;How does&amp;nbsp;Jalapeño interface the hardware - through a special class MAGIC.&lt;/li&gt;
&lt;li&gt;How does&amp;nbsp;Jalapeño interface the operating system - via ~1000 line C code to invoke system calls through the standard C library.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
One thing that would have made this paper even more interesting is to talk more about the trade-offs between different implementation alternatives.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-9015065806479326794?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/4qc1vOuQsAE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/9015065806479326794/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=9015065806479326794" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/9015065806479326794?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/9015065806479326794?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/4qc1vOuQsAE/why-to-implement-jvm-by-java.html" title="Why to implement a JVM in Java?" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/09/why-to-implement-jvm-by-java.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08MSXc-eCp7ImA9WxBXFEU.&quot;"><id>tag:blogger.com,1999:blog-1176935114478477846.post-3036924104838667472</id><published>2009-09-27T22:01:00.000-07:00</published><updated>2010-01-25T22:04:48.950-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-25T22:04:48.950-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>From Thread.join(), to invokeAll(), to the Fork/join Framework</title><content type="html">Fork/join Framework (FJF) is new in Java 7. It was developed by &lt;a href="http://gee.cs.oswego.edu/dl/"&gt;Doug Lea&lt;/a&gt; based on his paper "&lt;a href="http://gee.cs.oswego.edu/dl/papers/fj.pdf"&gt;A Java Fork/Join Framework&lt;/a&gt;". Simply speaking, the Fork/join Framework helps parallelize &lt;a href="http://en.wikipedia.org/wiki/Divide_and_conquer_algorithm"&gt;divide-and-conquer&lt;/a&gt; algorithms by multi-threading. It divides a big chuck of work into smaller pieces, sends them to a set of threads to process, waits until all of them are done and aggregates the results.&lt;br /&gt;
&lt;br /&gt;
This idea seems to be simple and straightforward, but there are a lot of things to think about to make it work well. Without too much thinking deeper, this idea can be implemented by just what Java &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Thread.html"&gt;Thread&lt;/a&gt; class provides. For each task, if it is small enough, solve directly; otherwise create several threads and let each new thread handle a smaller chuck. Then call join() method on each new threads to wait until all of them finish. Finally merge results. There are a few problems of this approach. First of all, creating threads is expensive. When a task is fairly small, the time spent in creating more threads is even longer than the computing time spent in solving the task itself. Second, there will be a lot of threads created. These threads compete for CPU cycles which result in worse performance. Third, programmer needs to write specific code for each divide-and-conquer algorithm. It makes code harder to write, read and maintain.&lt;br /&gt;
&lt;br /&gt;
If you are familiar with the &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/package-summary.html"&gt;java.util.concurrency&lt;/a&gt; package introduced since Java 5, you may want to suggest to use a thread pool based executor and call&amp;nbsp;&lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html#invokeAll(java.util.Collection)"&gt;invokeAll()&lt;/a&gt;&amp;nbsp;to process divided tasks. This saves the overhead of creating threads and limits the number of threads - a big step ahead, but there is good odds that this idea will not work well either.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The tasks queue, most likely an unbounded &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html"&gt;blocking queue&lt;/a&gt;, that is &lt;i&gt;&lt;b&gt;shared&lt;/b&gt;&lt;/i&gt; by all threads in an executor could become a bottleneck, because every thread needs to lock the queue when it gets tasks from the queue or puts new sub-tasks into the queue.&lt;/li&gt;
&lt;li&gt;What should happen when a thread is done its job? It may not be able to process the next queued task because that task may still be waiting for join its sub-tasks. In this case, how could this thread pick another task to continue instead of being idle?&lt;/li&gt;
&lt;li&gt;Programmers still have to write a fairly big amount of code in addition to the code that runs the algorithm itself.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The Fork/join Framework solves these problems. Each worker thread maintains its own tasks scheduling queue. This prevent one single shared queue from being a bottleneck. What should a thread do when its own tasks queue becomes empty?&lt;br /&gt;
&lt;br /&gt;
Here comes the smartest trick in Fork/join Framework - the "work-stealing" strategy. A scheduling queue of each thread is a &lt;a href="http://en.wikipedia.org/wiki/Deque"&gt;double-end queue&lt;/a&gt;. When a task needs to be divided into smaller tasks, it sends all its sub-tasks to one worker thread. So as the time goes, the head of a queue contains bigger tasks and the tail of a queue contains smaller tasks. For each thread, it processes tasks from the &lt;i&gt;tail&lt;/i&gt; of its queue (FIFO fashion). This utilizes data locality and also tries to concentrate on all sub-tasks of one task as much as possible. When a worker thread finishes all its own tasks, it "steals" tasks from the &lt;i&gt;head&lt;/i&gt; of other threads' queues (LIFO fashion). There is a good chance that this thread will pick a big task and thus it can further divide this tasks without affecting other on-going work. It won't need to "steal" again in the near future. For each double-end queue, one thread works on one end and other threads may work on the other end, but not very often. This is very good to prevent contention on queues.&lt;br /&gt;
&lt;br /&gt;
Last but not the least, with the Fork/join Framework, programmers can focus on the code that tackles their own problems. The code could be much cleaner and easier to read.&lt;br /&gt;
&lt;br /&gt;
In his &lt;a href="http://gee.cs.oswego.edu/dl/papers/fj.pdf"&gt;paper&lt;/a&gt;, Doug also evaluates the Fork/join Framework by solving a few real problems. He mentioned that the performance can also be affected by garbage collection, memory locality and bandwidth, task synchronization and task locality. These aspects should be considered careful when design the algorithm to utilize the Fork/join Framework. I like this paper, it is a typical Doug-style paper and it is a lot of fun to read.&lt;br /&gt;
&lt;br /&gt;
The Fork/join Framework is a part of &lt;a href="http://jcp.org/en/jsr/detail?id=166"&gt;JSR-166&lt;/a&gt;. It can be downloaded from the &lt;a href="http://gee.cs.oswego.edu/dl/concurrency-interest/"&gt;JSR-166 interest site&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1176935114478477846-3036924104838667472?l=blog.xiao-ma.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/xiao-ma-blog/~4/jMhRRXk0D9o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.xiao-ma.com/feeds/3036924104838667472/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1176935114478477846&amp;postID=3036924104838667472" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/3036924104838667472?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1176935114478477846/posts/default/3036924104838667472?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/xiao-ma-blog/~3/jMhRRXk0D9o/from-threadjoin-to-invokeall-to.html" title="From Thread.join(), to invokeAll(), to the Fork/join Framework" /><author><name>Xiao Ma</name><uri>http://www.blogger.com/profile/03209516172392190490</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="16967663387129926257" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.xiao-ma.com/2009/09/from-threadjoin-to-invokeall-to.html</feedburner:origLink></entry></feed>
