Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
1410 lines (1068 sloc) 99.7 KB
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="">
<title><![CDATA[Steven Yang's Blog | 杨晨昀]]></title>
<link href="" rel="self"/>
<link href=""/>
<name><![CDATA[Steven Yang]]></name>
<generator uri="">Octopress</generator>
<title type="html"><![CDATA[Guidelines for Learning Anything from Scratch]]></title>
<link href=""/>
<content type="html"><![CDATA[<ul id="markdown-toc">
<li><a href="#keep-yourself-motivated-all-the-time">Keep Yourself Motivated All the Time</a> <ul>
<li><a href="#realize-the-difficulties-and-set-proper-expectation">Realize the Difficulties and Set Proper Expectation</a></li>
<li><a href="#seek-motivation-deliberately">Seek Motivation Deliberately</a></li>
<li><a href="#focus-on-steps-one-at-a-time">Focus on Steps, One at a Time</a></li>
<li><a href="#choose-the-direction-to-make-effort">Choose the Direction to Make Effort</a> <ul>
<li><a href="#start-from-the-basics">Start from the Basics</a></li>
<li><a href="#when-in-doubt-make-instinct-decision">When in Doubt, Make Instinct Decision</a></li>
<li><a href="#follow-the-uncomfortable-zone">Follow the Uncomfortable Zone</a></li>
<li><a href="#conclusion">Conclusion</a></li>
<p>October 28th, 2010 is the day I started to learn programming from scratch all by myself. I built my first website in 6 months, got a programming job in 8 months, and begin to lead the development in a startup in 18 months and now I am still making progress and exploring new fields everyday.</p>
<p>This self-educating experience is both challenging and rewarding. To conquer obstacles and make the learning process effective, I’ve learned, tested and applied some principles of learning to my own studies.</p>
<p>Despite their effectiveness, these principles are often misunderstood or ignored by most people, even by education institutions. Thus I am sorting them out here and hope it might be helpful for you to apply some in your own studies.</p>
<h2 id="keep-yourself-motivated-all-the-time">Keep Yourself Motivated All the Time</h2>
<p>Motivation matters. </p>
<p>Continuous effort is required to build skills and it is hard to commit that effort without being motivated <strong>during the whole learning process</strong>. People tend to give up shortly after they decided to start something new, even those who are highly motivated at the beginning.</p>
<p>Given any book series, the first volume always outsells later sequences; among curriculum provided by schools, introductory courses are more popular than advanced ones; in gym business, registered members are much more than regular ones. People tend to initialize something on a hunch but few will succeed to develop it into a hobby, fewer into a profession. </p>
<p>These phenomena are common because motivation doesn’t arrive naturally, deliberate effort is required to obtain that.</p>
<h3 id="realize-the-difficulties-and-set-proper-expectation">Realize the Difficulties and Set Proper Expectation</h3>
<p>When people decide to initialize a learning process, they rarely vision the resulting tedious details, boring exercises and uncomfortable stretches. To learn a foreign language, memorizing the basic vocabulary, grammar and pronunciation is required before any serious reading and writing; to learn a music instrument, scale exercise is required to let the body play seamlessly with an instrument; to learn programming, basic syntaxes and tedious rules are required to work with computers.</p>
<p>The starting process is particularly difficult because it usually takes quite a long period before a beginner realizes the outcome of the effort. It might take several months to compose a paragraph in a foreign language, play one complete song or write a practical program. The beginning phase of learning is like the ‘death valley’ - dry, harsh and seems forever. </p>
<p>Frustration comes up when the initial expectation mismatches the reality. The illusion of an easy start and fancy progress vanishes shortly after the learning starts. When people realise learning as tedious and boring exercises with little progress, they easily become disappointed, self-doubting and later give up.</p>
<p>A prepared mind for those difficulties will avoid the frustration. When the tedious and boring exercise is within the initial expectaion, less frustration will occur when encounter them in reality. </p>
<p>When the learning has initialized, it is time to learn how to keep motivation along the way.</p>
<h3 id="seek-motivation-deliberately">Seek Motivation Deliberately</h3>
<p>Motivation could be collected from external source. You could deliberately look for materials which inspire you and it doesn’t need to be directly related to the fields you are studying. When I was learning programming, I collected short inspiring quotes deliberately and turn this collection into a <a href="">site</a> which I set as default home page in the browser. Those quotes fed me inspiration on a daily basis to move forward.</p>
<p>Motivation could be cultivated internally as well. The hunch which drives you to learning is a good place to start. Ask yourself why you want to acquire those skills in the first place. It’s okay the motivation doesn’t sound noble but it must matter to yourself. Once you dig out the motivation, keep reminding yourself of it - write down on paper, paste on the wall or set as screen saver etc. </p>
<h3 id="focus-on-steps-one-at-a-time">Focus on Steps, One at a Time</h3>
<p>A clear goal helps keep motivation high but narrowing yourself to that goal is counter-productive.</p>
<p>It is a good start to have a clear goal - speak Spanish with Latin friends, learn to cover your famous guitar song, write a program to crawl a website etc. . But if you only keep your eyes on the goals, the necessary exercises and effort become painful and unpleasant obstacles in order to reach that destination. <strong>The process itself becomes frustrating.</strong></p>
<p>However, if you think on a broader scale, <strong>the destination doesn’t exist</strong>. Even for professionals, there is always space to improve. How would you tell that one writer has reached the “destination” of writing, or one musician has developed all the skills to perform music. Any endeavour is serious enough to commit a lifelong effort so that there is no destination but an endless journey with seemingly repetitive but rewarding daily activities.</p>
<p>Instead of feeling obliged and restricted about the boring and tedious exercises, it is better to embrace and enjoy this experience because this experience together with the resulting progress is the everything about learning.</p>
<p>Then focus on individual steps and pay attention to however tiny progress made every day. Be proud of how you’ve learned to pronounce a new word, how you could play the scale little faster, how you have grasped the meaning of a new syntax.</p>
<p>When focusing on the individual steps, positive feedback will be accumulating along the way, which will collectively serve as a greater momentum to move you forward.</p>
<h2 id="choose-the-direction-to-make-effort">Choose the Direction to Make Effort</h2>
<p>Once you have learned to keep your motivation high, you are ready to invest your efforts in your studies. </p>
<p>For a beginner in one field, there are a lot of choices needed to be made. These choices certainly determine how much progress you might make along the way. </p>
<h3 id="start-from-the-basics">Start from the Basics</h3>
<p>In any fields, there are several levels of concepts which might be exposed to you. Some are the basics. In learning a language, vocabulary, grammar and spelling are the basic; in programming, syntax, data structure, clauses are the basics; in guitar playing, chord switches, playing scales, picking and strumming are the basics.</p>
<p>There are also high level concepts. In learning a language, they include tones, choices of words, idioms; in programming, design pattern, abstraction, architecture; in guitar playing, musicality, negative spaces and dynamics.</p>
<p>These two kinds of concepts are usually exposed to a beginner simultaneously, but the higher concepts could not be fully understood without a comprehensive understanding of the lower ones. It is impossible to write a well-structured articles in one language if the author still struggles with the meaning and spelling of most of the vocabulary, same for a programmer to write an application when he is still confused by the syntaxes.</p>
<p>Despite the dependencies, beginners are inclined to learn the high-level concepts instead of low-level ones. This is reasonable tendency. Learning the basics usually requires plain, tedious, repeated exercises. Memorize vocabulary, do repetitive exercises, read dry documentation. These basics seem to have no relationship with the work carried out by experts. It is easily get bored practicing those basics. On the other hand, the ambiguity of high-level concepts makes them easily to be understood ‘in general’. This ‘general understanding’ creates an illusion in the beginners to believe they have grasped this concept by being able to talk about these concepts. </p>
<p>The attractiveness of high-level concepts will misguide the beginners to skip practicing the basics and jump to the high-level ones. This will in fact slow down the actual progress they could potentially make.</p>
<p>Slow is fast. For a beginner, it is more important to focus on the basics. Practice those basics until they become natural to the brain and the high level concepts will be built on top of those.</p>
<h3 id="when-in-doubt-make-instinct-decision">When in Doubt, Make Instinct Decision</h3>
<p>Besides the choices between low-level ones and high-level ones, there are still a lot of detailed choices to be made for a beginner. Which dictionary should I purchase when learning Spanish? Which guitar should I play? Acoustic or electric? Which language should I use to start programming? Python, Ruby or C? </p>
<p>The answer is <strong>any one</strong> which you find most accessible and inspiring. These detailed choices don’t matter that much comparing with the effort to move forward. If you master the acoustic guitar, it won’t be hard to switch to an electric one; if you master Ruby, it only takes days to work with Python.</p>
<p>And those really important choices will reveal themselves to you later in the future when you are mature enough to distinguish the difference then.</p>
<p>So when you are in doubt, just follow the instinct and move forward.</p>
<h3 id="follow-the-uncomfortable-zone">Follow the Uncomfortable Zone</h3>
<p>The starting experience is usually unpleasant. It might be hard to reason out a very simple sentence when studying a foreign language, hard to play the simplest scales, hard to write a small piece of program that doesn’t generate an error.</p>
<p>This hardness usually leads to frustration which stops beginners making progress. But why not see it as a sign of where breakthroughs can be made?</p>
<p>If you find some words very hard to understand, look up dictionaries to learn more examples about it; if you feel certain scales are hard to play, practice more on them and let the muscle memory get used to that; if you constantly make certain type of errors when programming, look up the documentation for more details.</p>
<p>This short term goals will also feed you motivation. With continuous effort, you will notice improvement on that particular spot quickly, this generates feeling of accomplishment and help to keep the morale high.</p>
<h2 id="conclusion">Conclusion</h2>
<p>These are the principles that I have gleaned from my own learning experience and which, I believe, underlies what will really help you survive the ‘death valley of giving up’. To get through the hard beginning phase, you need to focus on small steps and put efforts on the basics. Do not worry about the choices you make, worry about the actions you are not about to make. You should live with the stretches and let the uncomfortable stretches guide you through the journey of learning.</p>
<p>Connect these principles with your successful learning experience and apply them into your next learning attempt. Happy Learning.</p>
<p>Thanks for <a href="">Chenjie Ding</a> for reading draft of this.</p>
<title type="html"><![CDATA[A Plan to Read the Ruby Standard Library]]></title>
<link href=""/>
<content type="html"><![CDATA[<ul id="markdown-toc">
<li><a href="#why-bother-reading-the-source-code">Why Bother Reading the Source Code?</a></li>
<li><a href="#resources">Resources</a></li>
<li><a href="#work-of-load">Work of Load</a></li>
<li><a href="#goals-and-plans">Goals and Plans</a></li>
<li><a href="#track-of-my-studies">Track of My Studies</a></li>
<h2 id="why-bother-reading-the-source-code">Why Bother Reading the Source Code?</h2>
<p>For the past two years, I’ve built the skill to craft software with various frameworks and tools. To move forward, I need to have more control over the system, the language and the libraries I work with. Merely reading the documentation doesn’t fulfil this requirement.</p>
<p>For any craftmanship, learning from the masterpiece is always a good way to improve one’s skills. Writers make improvement by reading other writers’ work, so should us - coders.</p>
<p>Inspired by <a href="">this</a> <a href="">two</a> articles, I decided to read all the source code of ruby standard libraries in the next four months.</p>
<p>It might be hard to begin with - lots of unknown idioms, unknown concepts and large code bases - but if I survive, I will improve the ability to dive into the source code directly and make sense out of it. This skill will help me become a better programmer in the future.</p>
<h2 id="resources">Resources</h2>
<p>Most of the studies will take place in the <a href=""><code>ruby 1.9.3</code></a> source code. I decided to read 1.9.3 instead of 2.0 because most of my work still runs in 1.9.3 that and it would be living for a while. It would be good I could adapt what I’ve learned into my work quickly.</p>
<p>I decided to leave out some of the <a href="">‘default gems’</a> in the ruby trunk as they have either an indenpedent or a large code base and deserve dedicate attention in the future. So are some domain-specific parser or gui libraries such as <code>syck</code>, <code>psych</code>, <code>rexml</code>, <code>rss</code>, <code>tk</code> and <code>tkextlib</code>.</p>
<p>Along the way, <a href=""><code>ruby-spec</code></a> and <a href="">Programming Ruby</a> will be the guide book to help me dive in the source code.</p>
<h2 id="work-of-load">Work of Load</h2>
<p>Leaving out the complex libraries or gems, there are <strong>92 libraries</strong> I need to study in. </p>
<p>I calculated the total lines of code I needed to go through…</p>
<pre><code>cloc --not-match-f='^(tk|psych).+' --exclude-dir=psych,rake,rubygems,rdoc,rexml,tk,tkextlib,rss .
<p>…and get 287 files, 51770 locs, 15160 effective lines of code(loc).</p>
<pre><code>287 text files.
287 unique files.
731 files ignored. v 1.56 T=2.0 s (141.5 files/s, 44190.0 lines/s)
Language files blank comment code
Ruby 283 9649 26961 51770
SUM: 283 9649 26961 51770
<p>To be more specific, I want to know every files I also listed all the files I needed to go through with:</p>
<pre><code>tree -I 'x86_64-darwin12.3.0|psych*|rake|rubygems|rdoc|rexml|tk*|rss' --prune
<p>…and it come out with <a href="#track-of-my-studies">this list</a>.</p>
<h2 id="goals-and-plans">Goals and Plans</h2>
<p>I want to finish this study in 120 days, from <code>Fri, 03 May 2013</code> - <code>Sat, 31 Aug 2013</code>. That means I need to go through around 450 locs every day, might take me 1 to 2 hours to finish this work.</p>
<p>Reading is also about quality and understanding, so for each library I will:</p>
<li>write some example code to use this library</li>
<li>do researches about unique techniques I found within the source code</li>
<p>All learning progress will be recorded here. <code>[x]</code> is finished file, <code>[-]</code> is skipped file.</p>
<h2 id="track-of-my-studies">Track of My Studies</h2>
<pre><code>[x] ├── English.rb
[x] ├── abbrev.rb
[ ] ├── base64.rb
[ ] ├── benchmark.rb
[x] ├── bigdecimal
[x] │   ├── jacobian.rb
[x] │   ├── ludcmp.rb
[x] │   ├── math.rb
[x] │   ├── newton.rb
[x] │   └── util.rb
[ ] ├── cgi
[ ] │   ├── cookie.rb
[ ] │   ├── core.rb
[ ] │   ├── html.rb
[ ] │   ├── session
[ ] │   │   └── pstore.rb
[ ] │   ├── session.rb
[ ] │   └── util.rb
[ ] ├── cgi.rb
[ ] ├── cmath.rb
[ ] ├── complex.rb
[ ] ├── csv.rb
[ ] ├── date
[ ] │   └── format.rb
[ ] ├── date.rb
[ ] ├── debug.rb
[x] ├── delegate.rb
[ ] ├── digest
[ ] │   ├── hmac.rb
[ ] │   └── sha2.rb
[ ] ├── digest.rb
[ ] ├── dl
[ ] │   ├── callback.rb
[ ] │   ├── cparser.rb
[ ] │   ├── func.rb
[ ] │   ├── import.rb
[ ] │   ├── pack.rb
[ ] │   ├── stack.rb
[ ] │   ├── struct.rb
[ ] │   ├── types.rb
[ ] │   └── value.rb
[ ] ├── dl.rb
[ ] ├── drb
[ ] │   ├── acl.rb
[ ] │   ├── drb.rb
[ ] │   ├── eq.rb
[ ] │   ├── extserv.rb
[ ] │   ├── extservm.rb
[ ] │   ├── gw.rb
[ ] │   ├── invokemethod.rb
[ ] │   ├── observer.rb
[ ] │   ├── ssl.rb
[ ] │   ├── timeridconv.rb
[ ] │   └── unix.rb
[ ] ├── drb.rb
[ ] ├── e2mmap.rb
[x] ├── erb.rb
[ ] ├── expect.rb
[ ] ├── fiddle
[ ] │   ├── closure.rb
[ ] │   └── function.rb
[ ] ├── fiddle.rb
[ ] ├── fileutils.rb
[ ] ├── find.rb
[x] ├── forwardable.rb
[ ] ├── getoptlong.rb
[ ] ├── gserver.rb
[ ] ├── io
[ ] │   └── console
[ ] │   └── size.rb
[ ] ├── ipaddr.rb
[ ] ├── irb
[ ] │   ├── cmd
[ ] │   │   ├── chws.rb
[ ] │   │   ├── fork.rb
[ ] │   │   ├── help.rb
[ ] │   │   ├── load.rb
[ ] │   │   ├── nop.rb
[ ] │   │   ├── pushws.rb
[ ] │   │   └── subirb.rb
[ ] │   ├── completion.rb
[ ] │   ├── context.rb
[ ] │   ├── ext
[ ] │   │   ├── change-ws.rb
[ ] │   │   ├── history.rb
[ ] │   │   ├── loader.rb
[ ] │   │   ├── math-mode.rb
[ ] │   │   ├── multi-irb.rb
[ ] │   │   ├── save-history.rb
[ ] │   │   ├── tracer.rb
[ ] │   │   ├── use-loader.rb
[ ] │   │   └── workspaces.rb
[ ] │   ├── extend-command.rb
[ ] │   ├── frame.rb
[ ] │   ├── help.rb
[ ] │   ├── init.rb
[ ] │   ├── input-method.rb
[ ] │   ├── inspector.rb
[ ] │   ├── lc
[ ] │   │   ├── error.rb
[ ] │   │   ├── help-message
[ ] │   │   └── ja
[ ] │   │   ├── encoding_aliases.rb
[ ] │   │   ├── error.rb
[ ] │   │   └── help-message
[ ] │   ├── locale.rb
[ ] │   ├── magic-file.rb
[ ] │   ├── notifier.rb
[ ] │   ├── output-method.rb
[ ] │   ├── ruby-lex.rb
[ ] │   ├── ruby-token.rb
[ ] │   ├── slex.rb
[ ] │   ├── src_encoding.rb
[ ] │   ├── version.rb
[ ] │   ├── workspace.rb
[ ] │   ├── ws-for-case-2.rb
[ ] │   └── xmp.rb
[ ] ├── irb.rb
[ ] ├── json
[ ] │   ├── add
[ ] │   │   ├── complex.rb
[ ] │   │   ├── core.rb
[ ] │   │   └── rational.rb
[ ] │   ├── common.rb
[ ] │   ├── ext.rb
[ ] │   └── version.rb
[ ] ├── json.rb
[ ] ├── kconv.rb
[x] ├── logger.rb
[ ] ├── mathn.rb
[ ] ├── matrix
[ ] │   ├── eigenvalue_decomposition.rb
[ ] │   └── lup_decomposition.rb
[ ] ├── matrix.rb
[ ] ├── minitest
[ ] │   ├── autorun.rb
[ ] │   ├── benchmark.rb
[ ] │   ├── mock.rb
[ ] │   ├── pride.rb
[ ] │   ├── spec.rb
[ ] │   └── unit.rb
[-] ├── mkmf.rb
[ ] ├── monitor.rb
[ ] ├── multi-tk.rb
[ ] ├── mutex_m.rb
[ ] ├── net
[ ] │   ├── ftp.rb
[ ] │   ├── http.rb
[ ] │   ├── https.rb
[ ] │   ├── imap.rb
[ ] │   ├── pop.rb
[ ] │   ├── protocol.rb
[ ] │   ├── smtp.rb
[ ] │   └── telnet.rb
[ ] ├── observer.rb
[ ] ├── open-uri.rb
[ ] ├── open3.rb
[ ] ├── openssl
[ ] │   ├── bn.rb
[ ] │   ├── buffering.rb
[ ] │   ├── cipher.rb
[ ] │   ├── config.rb
[ ] │   ├── digest.rb
[ ] │   ├── ssl-internal.rb
[ ] │   ├── ssl.rb
[ ] │   ├── x509-internal.rb
[ ] │   └── x509.rb
[ ] ├── openssl.rb
[ ] ├── optparse
[ ] │   ├── date.rb
[ ] │   ├── shellwords.rb
[ ] │   ├── time.rb
[ ] │   ├── uri.rb
[ ] │   └── version.rb
[ ] ├── optparse.rb
[ ] ├── ostruct.rb
[ ] ├── pathname.rb
[ ] ├── pp.rb
[ ] ├── prettyprint.rb
[ ] ├── prime.rb
[ ] ├── profile.rb
[ ] ├── profiler.rb
[x] ├── pstore.rb
[ ] ├── racc
[ ] │   └── parser.rb
[ ] ├── rake.rb
[ ] ├── rational.rb
[x] ├── rbconfig
[x] │   ├── datadir.rb
[x] │   └── obsolete.rb
[ ] ├── rdoc.rb
[ ] ├── remote-tk.rb
[ ] ├── resolv-replace.rb
[ ] ├── resolv.rb
[ ] ├── rinda
[ ] │   ├── rinda.rb
[ ] │   ├── ring.rb
[ ] │   └── tuplespace.rb
[ ] ├── ripper
[ ] │   ├── core.rb
[ ] │   ├── filter.rb
[ ] │   ├── lexer.rb
[ ] │   └── sexp.rb
[ ] ├── ripper.rb
[ ] ├── rss.rb
[ ] ├── rubygems.rb
[ ] ├── scanf.rb
[ ] ├── securerandom.rb
[x] ├── set.rb
[ ] ├── shell
[ ] │   ├── builtin-command.rb
[ ] │   ├── command-processor.rb
[ ] │   ├── error.rb
[ ] │   ├── filter.rb
[ ] │   ├── process-controller.rb
[ ] │   ├── system-command.rb
[ ] │   └── version.rb
[ ] ├── shell.rb
[x] ├── shellwords.rb
[ ] ├── singleton.rb
[ ] ├── socket.rb
[ ] ├── sync.rb
[ ] ├── tcltk.rb
[ ] ├── tempfile.rb
[ ] ├── test
[ ] │   ├── unit
[ ] │   │   ├── assertions.rb
[ ] │   │   ├── parallel.rb
[ ] │   │   └── testcase.rb
[ ] │   └── unit.rb
[ ] ├── thread.rb
[ ] ├── thwait.rb
[ ] ├── time.rb
[ ] ├── timeout.rb
[ ] ├── tmpdir.rb
[ ] ├── tracer.rb
[ ] ├── tsort.rb
[ ] ├── ubygems.rb
[ ] ├── un.rb
[ ] ├── uri
[ ] │   ├── common.rb
[ ] │   ├── ftp.rb
[ ] │   ├── generic.rb
[ ] │   ├── http.rb
[ ] │   ├── https.rb
[ ] │   ├── ldap.rb
[ ] │   ├── ldaps.rb
[ ] │   └── mailto.rb
[ ] ├── uri.rb
[ ] ├── weakref.rb
[ ] ├── webrick
[ ] │   ├── accesslog.rb
[ ] │   ├── cgi.rb
[ ] │   ├── compat.rb
[ ] │   ├── config.rb
[ ] │   ├── cookie.rb
[ ] │   ├── htmlutils.rb
[ ] │   ├── httpauth
[ ] │   │   ├── authenticator.rb
[ ] │   │   ├── basicauth.rb
[ ] │   │   ├── digestauth.rb
[ ] │   │   ├── htdigest.rb
[ ] │   │   ├── htgroup.rb
[ ] │   │   ├── htpasswd.rb
[ ] │   │   └── userdb.rb
[ ] │   ├── httpauth.rb
[ ] │   ├── httpproxy.rb
[ ] │   ├── httprequest.rb
[ ] │   ├── httpresponse.rb
[ ] │   ├── https.rb
[ ] │   ├── httpserver.rb
[ ] │   ├── httpservlet
[ ] │   │   ├── abstract.rb
[ ] │   │   ├── cgi_runner.rb
[ ] │   │   ├── cgihandler.rb
[ ] │   │   ├── erbhandler.rb
[ ] │   │   ├── filehandler.rb
[ ] │   │   └── prochandler.rb
[ ] │   ├── httpservlet.rb
[ ] │   ├── httpstatus.rb
[ ] │   ├── httputils.rb
[ ] │   ├── httpversion.rb
[ ] │   ├── log.rb
[ ] │   ├── server.rb
[ ] │   ├── ssl.rb
[ ] │   ├── utils.rb
[ ] │   └── version.rb
[ ] ├── webrick.rb
[ ] ├── xmlrpc
[ ] │   ├── base64.rb
[ ] │   ├── client.rb
[ ] │   ├── config.rb
[ ] │   ├── create.rb
[ ] │   ├── datetime.rb
[ ] │   ├── httpserver.rb
[ ] │   ├── marshal.rb
[ ] │   ├── parser.rb
[ ] │   ├── server.rb
[ ] │   └── utils.rb
[x] ├── yaml
[-] │   ├── dbm.rb
[x] │   └── store.rb
[x] └── yaml.rb
<title type="html"><![CDATA[How I Finished the DBClass from Stanford with Full Score]]></title>
<link href=""/>
<content type="html"><![CDATA[<ul id="markdown-toc">
<li><a href="#the-summary-of-material">The Summary of Material</a></li>
<li><a href="#how-i-approach-the-course-differently">How I Approach the Course Differently</a> <ul>
<li><a href="#more-reading-and-practice">More Reading and Practice</a></li>
<li><a href="#tune-the-tools">Tune the Tools</a></li>
<li><a href="#whats-next">What’s next?</a></li>
<p>For the past ten weeks, I’ve been working the <a href="">DBClass</a> offered by Standord. With 40 hours’ study I achieved <a href="">distinguished statement with full score</a> on all exercises and both exams. </p>
<p>In this course, I’ve acquired a solid knowledge about the algebra used behind the SQL language, learned advanced usage of database system and also get to know the basics to work with XML.</p>
<h2 id="the-summary-of-material">The Summary of Material</h2>
<p>You might checkout <a href="">all the exercise code</a> I’ve written for the course and some mindmaps I summarized for the reviews: <a href="">assertions and triggers</a>, <a href="">constrains</a>, <a href="">transactions</a>, <a href="">XML</a>.</p>
<p>Besides following the class instruction, I added some materials for learning and set up a more convenient development environment. The great learning experience is certainly brought by these improvements which I would like to share.</p>
<h2 id="how-i-approach-the-course-differently">How I Approach the Course Differently</h2>
<p>I have approached the course differently in three aspects:</p>
<li>I read all related chapters in text book.</li>
<li>I studied and wrote real-world examples.</li>
<li>I made deliberate effort to setup development environment to ease practice and test.</li>
<h3 id="more-reading-and-practice">More Reading and Practice</h3>
<p>I followed the text book <a href="">The Database System - The Complete Book</a> along the course schedule. This is the text book used in former Stanford database courses and it is what the course’s material origined. I read related chapters in the text book after watching the videos. Reading would reveal some points I’ve missed in the video and help build up a systemetic view over the topic.</p>
<p>As I work as a programmer, I applied the knowledge I learned in this course directly to several relational database based projects. </p>
<p>I wrote a lot of <a href="">raw SQLs</a> to fetch analytic data against our production database, it helped me to understand subqueries, natural joins and aggregations in the real world. </p>
<p>I substituted the backend with <code>sqlite</code> for <a href="">one command line tool</a> I was building at local hackthon.</p>
<p>To understand the advanced usage of triggers and constrains, I also read the source code of <a href="">squash</a>, an open source tool we use internally for bug tracking.</p>
<h3 id="tune-the-tools">Tune the Tools</h3>
<p>Another improvment I made is the development environment. I wanted to make it as easy and quick as possible to test out codes. This is the principal rule I’ve learned from former programming experience. Thus I made some deliberate effort to tune up the development environment.</p>
<p>As my major editor is <code>vim</code>, I use the database plugin <a href=""><code>dbext</code></a> to play with SQL. <code>dbext</code> enables me to execute SQLs and get the result back in my editor. Instead of editing the SQL, doing copy-and-paste, printing the result out, I could write, run, edit, run, cleanup, run with one simple key binding. This convenience was very helpful when solving complex problems. I could start with some instinct ideas and tested them out right away and improved based on the result I got back. This fast cycle of feedback s helped to evolve one idea to one correct solution.</p>
<p><img src="" alt="dbext image" /></p>
<p>Later, when I was working with XQuery, I missed the convenience I got from <code>dbext</code>. So I decided to implement it myself. Together with some <a href="">bash script</a> and a <a href="">vim function</a>, I built the same experience for XQuery editing. One key binding would fire the XQuery expression against the xml file and return the result right in the editor.</p>
<p><img src="" alt="xquery image" /></p>
<p>There is also simple <a href="">bash script</a> to make working with relational algebra compiler <code>ra</code> and xslt compiler easier.</p>
<h2 id="whats-next">What’s next?</h2>
<p>The <a href="">extra problems</a> included in the DBClass is well designed and is aimed to test more practical skills. I will finish them within this week.</p>
<p>DBclass has covered a wide range of topics in such a short period, but it also omits some concepts such as schemes, procedures, functions which are also widely used in modern databases. I will refer to the book and database system documentations to fill the gap.</p>
<p>Thanks for all the class2go team and Professor Jennifer Widom to carry out such an excellent course.</p>
<title type="html"><![CDATA[Annual Review for 2012]]></title>
<link href=""/>
<content type="html"><![CDATA[<p><img src="" alt="img for 2012 review" class="center" /> <sup id="fnref:4"><a href="#fn:4" rel="footnote">1</a></sup></p>
<ul id="markdown-toc">
<li><a href="#highlights">Highlights</a></li>
<li><a href="#achievement-in-hacking">Achievement in Hacking</a> <ul>
<li><a href="#system-administration">System Administration</a></li>
<li><a href="#programming-and-web-development">Programming and Web Development</a></li>
<li><a href="#main-failure">Main Failure</a> <ul>
<li><a href="#communication-failure-with-scentlibrary">Communication Failure with Scentlibrary</a></li>
<li><a href="#break-of-personal-reviewing-habit">Break of Personal Reviewing Habit</a></li>
<li><a href="#other-part-of-2012">Other Part of 2012</a> <ul>
<li><a href="#physical-training">Physical Training</a></li>
<li><a href="#design-blog-and-travel">Design, Blog and Travel</a></li>
<li><a href="#summary">Summary</a></li>
<li><a href="#footnote">Footnote</a></li>
<h2 id="highlights">Highlights</h2>
<p>In the very early 2012, I went to Beijing and joined in ScentLibrary (气味图书馆) to help build the tech department. Thanks to this opportunity, I set up the whole network architecture from scratch - from the topology design, routing rules, DNS/DHCP setup, NAT/firewall rules to several supporting services. This experience provided me a solid experience when I started up my own company later this year.</p>
<p>I peaked <a href="">Mt.Haba (5396m)</a> in May. It is the first snow mountain in my life. I had been preparing it since the start of this year. The 14-hour continuous ascending was both challenging and exciting.</p>
<p>Late in May, by the invitation of <a href="">Peter</a>, I went back to Shanghai and initiated the <a href="">endeavor</a> to bring our shared dream to reality. The ideas we are trying out includes <a href="">this</a>. </p>
<p>In November, we launched <a href="">Huali</a>(花里花店) after one month’s prototyping and preparation. Since then this project has drawn support from a passionate and young team and is being cultivated by us now.</p>
<h2 id="achievement-in-hacking">Achievement in Hacking</h2>
<p>The main achievements in 2012 are mostly in the fields of programming. Comparing with last year, there are progress in three fields :</p>
<li>More programming output. In the 2nd half year, I was more active in writing programs due to the familiarity with programming environment and fluency in programming language.</li>
<li>Wider range of knowledge about computers. The programs I crafted this year varied a lot, they range from command line tool, web page parser, chat robot, automation script, API wrapper and web applications.</li>
<li>Wise choice of tools. Last year, I could only follow the choices of the herd by blind but now I could weigh the options I have at hands and choose between them accordingly. </li>
<h3 id="system-administration">System Administration</h3>
<p>In 2012, I have completed the following projects related with system administration:</p>
<li>Set up a corporate Ethernet infrastructure in ScentLibrary using a Linux box as gateway, DNS and DHCP server.</li>
<li>Accomplished the Stanford open course “An Introduction to Computer Networks” with a score of 880/960. <sup id="fnref:1"><a href="#fn:1" rel="footnote">2</a></sup></li>
<li>Summarized the knowledge about building an environment ready for application deployment with <a href=""><code>capistrano-zen</code></a> and open-sourced it.</li>
<p>As all the endeavors was worked out on Linux, I became more familiar with it. I studied one of the best invention on Unix - the pipeline. I also touched the surface of the book <a href="">“The Art of Unix Programming”</a> to know more about the programming styles of Unix.</p>
<p>Among all the tool, <code>git</code> has changed the way I work and study. After learning the internals of <code>git</code> and I integrated it into my daily work flow. <code>git</code> has also become the tool to check the team member’s work, do code reviews and exchange opinions with other people at At the end of year, I installed an internal git hosting application with <code>gitolite</code> and <code>gitlab</code>, it provides our team more control over the development process.</p>
<p>I also got to know the basis of network infrastructure of the Internet. I dived into this field with no experience, I struggled for a while - reading academic books about computer network, reading manuals for implementations, trying out new tools. Fortunately, with the help of two friends - <a href="">Adieu</a> and <a href="">Zhanzhong</a>, I completed the infrastructure at last. Within the process, I learned all the internal workings such as DHCP, NAT, Routing tables the hard way. Then after I finished the <a href="intro-cn-site">Stanford course</a> about computer network, I linked all the knowledge together and formed a basic knowledge about how the Internet works from bottom up. </p>
<h3 id="programming-and-web-development">Programming and Web Development</h3>
<p>Here is the website, web application or programs I wrote in 2012:</p>
<li>Made three static sites: <a href="">zenhacks</a>, <a href="">manzuo</a>, <a href="">wazo</a>. All open-sourced. <sup id="fnref:2"><a href="#fn:2" rel="footnote">3</a></sup></li>
<li>Accomplished the UC Berkley open course “Software Engineering for Software as a Service” with a score of 1975/2126. <sup id="fnref:3"><a href="#fn:3" rel="footnote">4</a></sup></li>
<li>Crafted a prototype of <a href="">manzuoapp</a> with <code>nodeJS</code>, <code>MongoDB</code> and <code>Redis</code>.</li>
<li>Crafted an e-commerce web application for <a href="">huali</a> with <code>Rails</code>.</li>
<li>Wrote a small tool <a href="">ask</a> one day at a hackthon with my roomate Kuno, it helps you accumulate your knowledge about commandline tools.</li>
<li>Wrote a simple Ruby wrapper <a href="">foxit</a> for <a href="">gitlab</a> API v2.</li>
<li>Created a bot to parse the and mirror it privately with <code>express</code>. The source code is <a href="">here</a>.</li>
<li>I learned and improved the tool I am using for programming and became more effective with them. Checkout my <a href=""><code>vim</code> config files</a> and <a href=""><code>fish</code> config files</a>.</li>
<p>Through the working with various web application, I gained an in-depth understanding over HTTP - a communication protocol between two processes across the Internet just as any RPC service. I’ve worked with beautifully designed APIs such as Github’s and also have designed APIs for manzuoapp and built wrapper around exist API. Through the process, I was more aware of the RESTful design principle.</p>
<p>I adapted the ideas in the <a href="">12 factor app</a> when design the architecture for the Rails application. I broke down the application into difference Unix processes - web apps, background workers and http workers. This separation helps the application to allocate different responsibility to different processes. </p>
<p>Last but not least, I finally adopted <code>Ruby</code> and <code>Rails</code> into production work. I finished reading on <a href="">Programming Ruby</a> and began to use <code>Ruby</code> to write day-to-day scripts. I also used <code>Rails</code> to build and all other personal stuff. I am happy to survive with these new tools and look for more fluent usage in the coming new year.</p>
<p>Besides the accomplishment in 2012, I had two main failures in 2012.</p>
<h2 id="main-failure">Main Failure</h2>
<h3 id="communication-failure-with-scentlibrary">Communication Failure with Scentlibrary</h3>
<p>The main failure at work is the failed communication with ScentLibrary. I, as the only tech person within the team, didn’t communicate with the board well. This corporation ended nastily. They ended up with a infrastructure without maintenance, I financial lose and extra reallocation cost.</p>
<p>I was quite furious when they cancelled the oral contract without notice and compensation. But when I settled down in Shanghai and talked this issue with some senior friends at TZG, I realized my own responsibility for that failure. I was too self-centered and overconfident when dealing with disagreement and conflicts, I didn’t sit in their seats to make communication happen. The ignorance of their needs make further corporation unreachable. </p>
<h3 id="break-of-personal-reviewing-habit">Break of Personal Reviewing Habit</h3>
<p>Another failure is the break of my planning and reviewing discipline. It resulted in the gap between the goals set in <a href="">the 2012 plan</a> and the final accomplishment. I sadly found I failed myself in all fields other than programming. The personal management system I established in 2011 helped me stay focused, fight against distraction and concentration on long term goals which really matters. However, after moving to Shanghai, I stopped this discipline and never resumed it. For the second half year I was busy but not focused. In the last two months, when the new company started up, the errands chewed up the time which I should have put into long term goals. </p>
<p>Now I might look the other part of my 2012.</p>
<h2 id="other-part-of-2012">Other Part of 2012</h2>
<h3 id="physical-training">Physical Training</h3>
<p>Speaking of physical exercise, I kept my weekly schedule the first half year. I ran 10-20km per week and did some push-ups everyday. However, the exercise stopped when I got back to Shanghai. I didn’t do any physical training for the second half year. There might be two reasons for this: </p>
<li>Lack of long-term motivation. I kept the exercise schedule in Beijing because I was preparing for the snow mountain climbing. Once it was achieved, motivation disappeared.</li>
<li>Lack of community support. I ran with a bunch of friends in Beijing, this support from friends helped to keep motivation high.</li>
<p>As a result, my health declined. My back and shoulder pain became more severe. Once in a while, I would feel the back pain every morning when I got up. My sleeping patterns also went worse - I could not sleep before 3/4am and hardly woke up before 10am.</p>
<p>To ease the back pain, I switched to a <a href="">standing desk</a> in October and it helped to ease the pain in shoulder and back. I will continue this practice.</p>
<p>Next year, re-establishing the exercise routine will be the main goal.</p>
<h3 id="design-blog-and-travel">Design, Blog and Travel</h3>
<p>I didn’t make any progress in design in 2012. Scheduled time is all squeezed out by programming activities. I attempted to learn drawing from <a href="">this excellent illustrator</a> I met in ScentLibrary, but I left Beijing too quickly to have a chance to draw more than a basic cubic. </p>
<p>I also fell short of the articles I should have written. I ended up with four articles. I also drafted about <code>capistrano</code> internal workings, <code>xmonad</code> setups but didn’t have a chance to polish them up and make them publishable. Less of focus has impaired the deliberate effort which is necessary to cultivate an idea into article.</p>
<p>For the traveling plan, I didn’t get the chance to Southern-Asia and Russia because the unscheduled work changes in the middle of the year. But I did accomplish peaking Mt.Haba. I had been preparing it physically for more than half year and thanks to the mild weather and the help from our guide, I didn’t encounter any fatal setbacks. The 1700km daily ascending was challenging but the views and the final peaking experience was worth all the effort. Check out the photos <a href="">here</a>.</p>
<p>The reading routine beyond programming also fell short of planning. But I did encountered some unexpected good books: </p>
<li><a href="">The Intention Experiment</a> explains power of thought with scientific methods, </li>
<li><a href="">The Soul of the Firm</a> demonstrates the values of people in any successful long-lived company.</li>
<li><a href="">The Ten Faces of Innovation</a> provides a clue to detect creative people and form a creative team.</li>
<p>In the aspect of social activity, I seemed more active comparing with last year due to living locations. I attended several tech gatherings in Shanghai such as HuJS and RubyConf China. I attended Hobby Project Day twice and topped <a href="">both</a> <a href="">times</a>. I also co-hosted <a href="">Wazo Box</a> and made a speech about Chinese color there.</p>
<h2 id="summary">Summary</h2>
<p>In summary, 2012 was an unbalanced year for me, all my time and effort has been put into hacking and programming (as I really enjoyed it!). But this unbalanced life also hurt: my health condition declined severely, design and art practice had no progress, exploration was halted etc. Balancing programming and other parts of life will be a challenge for me in 2013. </p>
<h2 id="footnote">Footnote</h2>
<div class="footnotes">
<li id="fn:4">
<p>The photo is credited to <a href="">wtl</a>.<a href="#fnref:4" rel="reference">&#8617;</a></p>
<li id="fn:1">
<p>Here is the <a href="">statement of accomplishment</a> for <a href="">An Introduction to Computer Networks</a>.<a href="#fnref:1" rel="reference">&#8617;</a></p>
<li id="fn:2">
<p>The source code could be found at <a href="">zenhacks</a>, <a href="">manzuo</a> and <a href="">wazo</a>.<a href="#fnref:2" rel="reference">&#8617;</a></p>
<li id="fn:3">
<p>Here is the <a href="">statement of accomplishment</a> for <a href="">Software Engineering for Software as a Service</a>.<a href="#fnref:3" rel="reference">&#8617;</a></p>
<title type="html"><![CDATA[Ack - a better way to search in files]]></title>
<link href=""/>
<content type="html"><![CDATA[<p>Recently, <a href="">ack</a> became the replacement for <code>grep</code> when I need to spot editing point in my code bases. It wins over <code>grep</code> in terms of:</p>
<li>A better pattern match syntax with <a href="">Perl regular expressions</a></li>
<li>Smarter to limit searches in directories or certain file types</li>
<li>Much prettier display of result</li>
<li>Config files to make customization permanent</li>
<p>These advantages will be introduced in the the following sections and after reading it I hope you will be comfortable with it.</p>
<p>Let’s start by installing <code>ack</code>:</p>
<p>Mac OS X with homebrew:</p>
<pre><code>brew install ack
<pre><code>sudo apt-get install ack-grep; sudo ln -s $(which ack-grep) /usr/local/bin/ack
<p>Then <code>git clone</code> to get the directory used in following examples.</p>
<ul id="markdown-toc">
<li><a href="#search-with-modern-regexp-pattern">Search with Modern Regexp Pattern</a></li>
<li><a href="#limit-where-the-search-happens">Limit Where the Search Happens</a></li>
<li><a href="#add-files-to-be-searched">Add Files to be Searched</a></li>
<li><a href="#make-configuration-sticky">Make Configuration Sticky</a></li>
<li><a href="#more-magic-and-conclusion">More Magic and Conclusion</a></li>
<h2 id="search-with-modern-regexp-pattern">Search with Modern Regexp Pattern</h2>
<p>Let’s start with a simple search <code>ack diff</code>.</p>
<p>It prints out all the files whose lines contain the string <code>'diff'</code> within the current working directory.</p>
<p>In fact <code>'diff'</code> could be any valid Perl Regular Expression include the <a href="">advanced regular expression syntax</a>, if you are familiar with regular expression in Ruby, Python, javaScript or Perl, you will be far more at home with the syntax than GNU Basic Regular Expression.</p>
<p>For example, we could use <code>ack 'diff\(.+\)'</code> to detect a string as a function call such as <code>'diff(o, n)''</code> .</p>
<p>It will be common that we will be more interested in <code>'diff'</code> as a word than a portion of string. In this case, we could use <code>ack '\bdiff\b'</code> but there is a handy option <code>-w</code> which force a pattern to match a complete word. So we could send our search result as <code>ack -w diff</code>.</p>
<p>As in any regular expression flavors, to match character such as <code>$</code> or <code>.</code>, we need to escape them in the pattern as <code>'\$\.proxy'</code>. In this case, <code>ack</code> also comes with a handy way to treat the pattern as string literal. Use <code>ack -Q $.proxy</code> to match text against liternal <code>'$.proxy'</code>. It is useful to match IP addresses in log file such as <code>ack access.log -Q</code>.</p>
<h2 id="limit-where-the-search-happens">Limit Where the Search Happens</h2>
<p>You might have already noticed that in the above example, <code>ack</code> automatically search under your current working directory.</p>
<p>In order to alter this behavior, you could specify the file or directory to be searched in. <code>ack href js/bootstrap-alert.js</code> will only match pattern in the <code>js/bootstrap-alert.js</code> file. Similarly, if you specify a directory name as <code>ack proxy docs</code>, it will search in the <code>'docs'</code> directory recursively.</p>
<p>To cancel the recursive behavior, pass in <code>-n</code> or <code>--no-recurce</code>. For example <code>ack post docs -n</code> will only match pattern in the <code>'docs'</code> directory but not its subdirectories.</p>
<p>You can also ignore directory with <code>--ignore-dir=name</code> option, <code>ack post --ignore-dir=docs</code> will seek <code>'post'</code> in all directories other than <code>'docs'</code>.</p>
<p>Sometimes the constrain is complicated, then the option <code>-f</code> will be helpful as it will print the files to be searched before performing the search. For example <code>ack --ignore-dir=docs -f</code> will print all the files <code>ack</code> will search in.</p>
<p>Besides reading from arguments for files, <code>ack</code> could also reads from STDIN. This makes <code>ack</code> a nice candidate in unix pipeline. We could chain multiple <code>ack</code> together to zero in on what the text you really care about. For example <code>ack postError js | ack message</code> <strong>first</strong> find matches for <code>'postError'</code> in all <code>'js'</code> directory and <strong>within the result</strong> it find matches for <code>'message'</code>.</p>
<h2 id="add-files-to-be-searched">Add Files to be Searched</h2>
<p>Try <code>ack background less</code> to search files in the <code>less</code> directory. It doesn’t return the result we are looking for, the <code>.less</code> files are ignored by <code>ack</code>. There must be something wrong with <code>ack</code>, right?</p>
<p>However, this behavior is not an error but is by design by its author Andy Lester:</p>
<p>… Most codebases have a lot files in them which aren’t source files, and grep wastes a lot of time searching through all of those as well and returning matches from those files. </p>
<p>That’s why ack’s behavior of not searching things it doesn’t recognize is one of its greatest strengths: the speed you get from only searching the things that you want to be looking at.</p>
<p><code>ack</code> is designed to only search in file types it knows. The file types known by <code>ack</code> could be seen with <code>ack --help-types</code>. Through <code>ack --help-types | ack less</code> we found that, <code>*.less</code> is not known by <code>ack</code> and that’s the reason why they are ignored.</p>
<p>To add more file types we use <code>--type-set</code> and <code>--type-add</code>. With <code>ack background less --type-set less=.less</code>, we succeeded in searching in the <code>*.less</code> files. </p>
<p>Sometimes, we don’t care about file type and just want search in all files in the directory, in these cases, we use <code>--all-types</code> or <code>-a</code>. It will search in all files regardless of its type with one exception - the CVS directory such as <code>.git</code> or <code>.svn</code> is excluded. If we want to count them in, use the ultimate <code>--unrestricted</code> or <code>-u</code> options to search <strong>everything</strong> within a directory.</p>
<h2 id="make-configuration-sticky">Make Configuration Sticky</h2>
<p>In most cases, we want to limit our searches to certain types, then it will be tedious to type <code>--type-set</code> or <code>--type-add</code> every time we want to search beyond build-in file types. <code>~/.ackrc</code> comes into play in these case. This is the configuration file which will be loaded by <code>ack</code>. All the options we introduced above could be written to it to make it permanent.</p>
<p>Take my configuration as an example:</p>
<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="code"><pre><code class="bash"><span class="line"><span class="c"># ~/.ackrc ack configuration file</span>
</span><span class="line">
</span><span class="line"><span class="c"># Sort files by default</span>
</span><span class="line">--sort-files
</span><span class="line">
</span><span class="line"><span class="c"># Use smart-case by default</span>
</span><span class="line">--smart-case
</span><span class="line">
</span><span class="line"><span class="c"># Extended File Types</span>
</span><span class="line">--type-add<span class="o">=</span><span class="nv">css</span><span class="o">=</span>.less,.scss,.sass
</span><span class="line">--type-add<span class="o">=</span><span class="nv">ruby</span><span class="o">=</span>.haml
</span><span class="line">--type-set<span class="o">=</span><span class="nv">coffee</span><span class="o">=</span>.coffee
</span><span class="line">--type-set<span class="o">=</span><span class="nv">markdown</span><span class="o">=</span>.md,.markdown
</span><span class="line">--type-set<span class="o">=</span><span class="nv">json</span><span class="o">=</span>.json
<p>One thing to be noticed, instead of use whitespace in <code>--type-add less=.less</code> use <code>=</code>. Also, line begins with <code>#</code> is ignored.</p>
<p>After adding our own file types, we could use <code>--type less</code> / <code>--less</code> to limit searches in certain file types or <code>--type noless</code> or <code>--noless</code> to exclude them. </p>
<h2 id="more-magic-and-conclusion">More Magic and Conclusion</h2>
<p><code>ack</code> comes a lot options for the format of output, you could use <code>--pager=less -r</code> to use <code>less</code> as pager with color support, or use <code>-C</code> to display the lines above/below the matched line as well. For more information, check out <code>man ack</code>.</p>
<p>This handy tool is smarter and faster than <code>grep</code> and I have been using it heavily in my workflow. Moreover, the coming <a href="">ack2.0</a> is more powerful in terms of file type filtering and multiple config file support.</p>
<p>Hope this introduction makes you comfortable with <code>ack</code>.</p>
<p>Do you know other “improved” substitute for daily unix utility?</p>
<title type="html"><![CDATA[How to Measure and Monitor Network Performance]]></title>
<link href=""/>
<content type="html"><![CDATA[<p>When a network is set up it is also necessary to measure the real performance. Does the real WAN bandwidth match ISP’s promise? What’s the real bandwidth of the 1Gbit ethernet LAN? When is the busiest hours of the network? How the traffic is distributed across different IPs and hosts?</p>
<p>In this article, I will introduce the usage of three different programs to solve above problems.</p>
<p><code>iperf</code> is a easy tool to calculate the raw bandwidth between two machines. <code>vnstat</code> could track traffic with a low resource cost. For more detailed information about network usage, <code>ntop</code> plays its role well.</p>
<ul id="markdown-toc">
<li><a href="#measure-the-effective-bandwidth-with-iperf">Measure the Effective Bandwidth with iperf</a> <ul>
<li><a href="#installation">Installation</a></li>
<li><a href="#two-commands-one-test">Two Commands, One Test</a></li>
<li><a href="#more-options">More Options</a></li>
<li><a href="#monitor-bandwith-usage-with-vnstat">Monitor Bandwith Usage with vnstat</a> <ul>
<li><a href="#install-vnstat">Install Vnstat</a></li>
<li><a href="#setup-scheduled-update">Setup Scheduled Update</a></li>
<li><a href="#simple-usage">Simple Usage</a></li>
<li><a href="#detailed-configuration">Detailed Configuration</a></li>
<li><a href="#dump-the-data-for-scripting">Dump the Data for Scripting</a></li>
<li><a href="#monitor-detailed-network-traffic-with-ntop">Monitor Detailed Network Traffic with ntop</a></li>
<h2 id="measure-the-effective-bandwidth-with-iperf">Measure the Effective Bandwidth with iperf</h2>
<p><code>iperf</code> is a program used to perform network throughput tests. It will <strong>move as much data as possible</strong> using available connections established between two computers.</p>
<h3 id="installation">Installation</h3>
<p><img src="" alt="Iperf Install" title="install iperf on both machines" /></p>
<p>On Linux, you do:</p>
<pre><code>sudo aptitude install iperf
<p>On Mac OS X, you could install it with <a href="" title="Home Brew - Package Manager on Mac" target="blank">homebrew</a>.</p>
<pre><code>brew install iperf
<p>On windows, you could download the executables from <a href="" title="Iperf Executables for Windows"></a>.</p>
<h3 id="two-commands-one-test">Two Commands, One Test</h3>
<p><img src="" alt="Iperf mode" title="iperf mode image" /></p>
<p>You need to have <strong>at least</strong> one pair of <code>iperf</code> client and server to perform the test.
To run <code>iperf</code> as server:</p>
<pre><code>iperf -s
<p>To run <code>iperf</code> as client:</p>
<pre><code>iperf -c
<p>This is the result table from client’s terminal:</p>
Client connecting to, TCP port 5001
TCP window size: 65.0 KByte (default)
[ 4] local port 56752 connected with port 5001
[ ID] Interval Transfer Bandwidth
[ 4] 0.0-10.0 sec 128 MBytes 107 Mbits/sec
<p>By default, <code>iperf</code> will establish TCP connection on 5001 port and transfer as much data as possble in 10 seconds.</p>
<h3 id="more-options">More Options</h3>
<p>The format of bandwidth could be specified by <code>-f</code>, the time to transmit could be specified in <code>-t</code> and the interval to send data could be set with <code>-i</code>.
For example, to report tests with 10 seconds intervals in 50 seconds under the format of MBytes could be written as:</p>
<pre><code>iperf -c -t 50 -i 10 -f M
<p>The result likes:</p>
Client connecting to, TCP port 5001
TCP window size: 0.06 MByte (default)
[ 4] local port 56924 connected with port 5001
[ ID] Interval Transfer Bandwidth
[ 4] 0.0-10.0 sec 126 MBytes 12.6 MBytes/sec
[ 4] 10.0-20.0 sec 133 MBytes 13.3 MBytes/sec
[ 4] 20.0-30.0 sec 135 MBytes 13.5 MBytes/sec
[ 4] 30.0-40.0 sec 138 MBytes 13.8 MBytes/sec
[ 4] 40.0-50.0 sec 135 MBytes 13.5 MBytes/sec
[ 4] 0.0-50.0 sec 667 MBytes 13.3 MBytes/sec
<p>Sometimes it is also necessary to measure two-way transmission. You could use <code>-d</code> to do bidirectional test at the same time or use <code>-r</code> to do each transmission individually.</p>
<p><img src="" alt="Iperf mode" title="iperf mode in d image" /></p>
<p><img src="" alt="Iperf mode" title="iperf mode in r image" /></p>
<pre><code>iperf -c -d
iperf -c -r
<p>If you want to use run <code>iperf</code> as a daemon on the server, you could use <code>-D</code></p>
<pre><code>iperf -s -D
<p>To specify the port through which the client and server communicate use <code>-p</code></p>
<pre><code>iperf -s -p 9393
iperf -c -p 9393
<p>You could find more practical examples <a href="" title="iperf detailed usage">here</a>.</p>
<h2 id="monitor-bandwith-usage-with-vnstat">Monitor Bandwith Usage with vnstat</h2>
<p><code>vnstat</code> use a <strong>database file to keep a log of network traffic</strong> through certain interfaces. It provide hourly/daily/weekly/monthly traffic information. And as it doesn’t sniffing packets, it is very efficient.</p>
<p>To use <code>vnstat</code> there are two things needed to be done:
1. Install the program;
2. Update the databases regularly.</p>
<h3 id="install-vnstat">Install Vnstat</h3>
<p>Install <code>vnstat</code> with these commands:</p>
<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="code"><pre><code class="bash"><span class="line"><span class="c"># Linux</span>
</span><span class="line">sudo aptitude install vnstat
</span><span class="line"><span class="c"># Mac OS</span>
</span><span class="line">brew install vnstat
<h3 id="setup-scheduled-update">Setup Scheduled Update</h3>
<p>Now add a scheduled task with <code>crontab -e</code> to update the database every five minutes.</p>
<pre><code># /etc/cron.d/vnstat: crontab entries for the vnstat package
0-55/5 * * * * root if [ -x /usr/bin/vnstat ] &amp;&amp; [ `ls /var/lib/vnstat/ | wc -l` -ge 1 ]; then /usr/bin/vnstat -u; fi
<p>If you run <code>vnstatd</code> daemon instead of <code>vnstat</code>, there is no need to create the crontab as it will read the <a href="#detailed-configuration">configuration file</a> and handle the updates accordingly.</p>
<h3 id="simple-usage">Simple Usage</h3>
<p>Now wait a while for the database to be updated and you could see a traffic summary for one interface through:</p>
<pre><code>vnstat -i eth0
Database updated: Sat Feb 18 16:30:01 2012
eth0 since 02/17/2012
rx: 1.75 GiB tx: 4.45 GiB total: 6.20 GiB
rx | tx | total | avg. rate
Feb '12 1.75 GiB | 4.45 GiB | 6.20 GiB | 34.04 kbit/s
estimated 2.86 GiB | 7.30 GiB | 10.17 GiB |
rx | tx | total | avg. rate
yesterday 1.69 GiB | 4.22 GiB | 5.91 GiB | 573.44 kbit/s
today 60.19 MiB | 242.29 MiB | 302.48 MiB | 41.71 kbit/s
estimated 87 MiB | 352 MiB | 439 MiB |
<p>You could also specify the intervals with <code>--hours</code>, <code>--days</code>, <code>--weeks</code>, <code>--months</code>.</p>
<pre><code>vnstat -i eth0 --days
<p>There is even a live mode triggered by <code>--live</code> to display current transfer rate.</p>
<pre><code>vnstat -i eth0 -l
<h3 id="detailed-configuration">Detailed Configuration</h3>
<p><code>vnstat</code> use <code>$HOME/.vnstatrc</code> for user specific configuration and use <code>/etc/vnstat.conf</code> for default configuration.</p>
<p>You could specify the interfaces to use by default, intervals to update data and update the database file etc.</p>
<p>The configuration file is quite self-explained:</p>
<pre><code>sudo vim /etc/vnstat.conf
<h3 id="dump-the-data-for-scripting">Dump the Data for Scripting</h3>
<p><code>vnstat</code> also provides formated output of the database.</p>
<p>If you want a xml formatted database, use <code>vnstat --xml</code>.</p>
<p>There is also a parseable format with <code>vnstat --dumpdb</code>. The detailed explanation of the output format could be found at <code>man vnstat</code>. You could also use this format for traffic summary with <code>vnstat --oneline</code>.</p>
<p>You could find more about <code>vnstat</code> on <a href="" title="vnstat official site">its official site</a>.</p>
<h2 id="monitor-detailed-network-traffic-with-ntop">Monitor Detailed Network Traffic with ntop</h2>
<p><code>vnstat</code> measures the overall traffic of interfaces but it fails to keep track of individual communications. For more detailed information, <code>ntop</code> comes into places.</p>
<p><code>ntop</code> is a <strong>traffic probe</strong> and use a <strong>web interface</strong> to display certain information. It could show traffic distribution across protocols, IPs, hosts and more.</p>
<p>You could install <code>ntop</code> with:</p>
<pre><code>sudo aptitude install ntop
<p>To initial <code>ntop</code> the first time run</p>
<pre><code>sudo ntop
<p>Now the ntop could be accessed through 3000 port from HTTP request, you could use it through a browser.</p>
<p>Along with the detailed information <code>ntop</code> collects, it uses much more system resources than <code>vnstat</code>.</p>
<p>I am just a beginner of webmaster work, I’d love to hear what’s in your toolbox to measure network performance.</p>
<title type="html"><![CDATA[Annual Plan 2012 - One Step Further]]></title>
<link href=""/>
<content type="html"><![CDATA[<p><img src="" alt="img for 2012 plannings" class="center" /></p>
<p>My 2012 annual plan is finally finished after the decision making about moving to Beijing and joining in <a href="" title="ScentLibrary" target="_blank">ScentLibrary</a>.</p>
<h2 id="the-purpose-of-2012">The Purpose of 2012</h2>
<p>From the <a href="" title="2011 Annual Reviews" target="_blank">changes</a> I made in 2011, I will expand my skills to the full-web development stack from LAN setup, web services configuration, backend development and agile development with Rails. Besides, I will start practicing the very basics of design - drawing while dust off my photograph skills. I would also explore new fields such as branding, scents in daily life, innovation and story-telling. On the physical side, I would recover my backbone aches through exercise routines which will also prepare myself for the snow mountain climbing and cycling in countries of southern Asia.</p>
<p>The detailed plan could be downloaded <a href="" title="2012 Annual Plans" target="_blank">here</a>. And the spreadsheets I used to do this practice is <a href="" title="personal management toolkit">here</a>.</p>
<h2 id="outcome-of-2012">Outcome of 2012</h2>
<p>The main goals of accomplishment includes:</p>
<h3 id="internal-development">Internal Development</h3>
<li>More patience about my work.</li>
<li>Take record of 3000 hours.</li>
<li>Increase productive hours (pomodoros) to 5.5 hours per day.</li>
<h3 id="computer-science">Computer Science</h3>
<li>HTML5/CSS3 powered branding website for ScentLibrary.</li>
<li>A e-commerce web app based on agile development using Rails.</li>
<li>Setup web services on Linux (DNS/HTTP/SFTP/VPN etc.)</li>
<li>Two cutting-edge experiments with HTML5/CSS3/JS.</li>
<li>Reach a rank of annual top 10% at <a href="http://" title="StackOverflow" target="_blank"></a></li>
<li>Contribute to one open-source project.</li>
<li>Write 20 tutorials about web development.</li>
<h3 id="design">Design</h3>
<li>Finish one drawing curriculum.</li>
<li>Conduct two graphic design projects.</li>
<li>Make one short video about natural scenes.</li>
<h3 id="misc">Misc</h3>
<li>Exercise 285 hours.</li>
<li>Run 10km in 50’, swim 50m in 60’’ and 500m in 15’.</li>
<li>Make four public presentations.</li>
<li>Climbed one snow mountain.</li>
<p>Footnote: The photo is credited to <a href="">frank-k_</a>.</p>
<title type="html"><![CDATA[Annual Review 2011 - A Turning in Life]]></title>
<link href=""/>
<content type="html"><![CDATA[<p>2011 is a turning corner of my life. Straying away from my Economics background, I started learning web design and development from scratch and ended up with a result better than my expectation.</p>
<ul id="markdown-toc">
<li><a href="#highlights">Highlights</a></li>
<li><a href="#excerpt-of-2011">Excerpt of 2011</a></li>
<li><a href="#a-more-close-look-at-2011">A More Close Look at 2011</a> <ul>
<li><a href="#english-writing">English Writing</a></li>
<li><a href="#web-design-and-computer-science">Web Design and Computer Science</a></li>
<li><a href="#travel">Travel</a></li>
<li><a href="#physical-training-and-habit">Physical Training and Habit</a> <ul>
<li><a href="#personal-management-system">Personal Management System</a></li>
<li><a href="#physical-training-and-health">Physical Training and Health</a></li>
<h2 id="highlights">Highlights</h2>
<p>On March 14th, I made a <a href="" title="Presentation about what hinders adult from learning" target="_blank">presentation</a> at Barcamp Shanghai talking about what hinders adult learning and I met Peter and later the whole TEDxFiveStarSquare(TEDxFSS) team.</p>
<p>On May 15th, I created <a href="" target="_blank">the site of TEDxFSS</a> and designed the banner, poster and screen for this event. This solidates my confidence to deliver work of design and development.</p>
<p>On June 7th, I started the <a href="" title="Link to Eleme Napos" target="_blank">Napos</a> project at <a href="" target="_blank">Eleme</a> and later I joined the team and took charge of UI design and frontend development.</p>
<p>On August 21th, I made a <a href="" target="_blank">speech</a> at TEDxYouth Westlake about making a change in your life.</p>
<h2 id="excerpt-of-2011">Excerpt of 2011</h2>
<p><img src="" alt="TEDxFiveStarSquare Logo" class="left" />
I expected one year preparation before I could deliver qualified projects. But the first website was accomplished after five months of learning. I built <a href="" target="_blank">the website of TEDxFSS</a> and later contributed to the design of the whole event. With the help of a great team, we pull off the only one <a href="" title="TEDxFSS Event" target="_blank">TEDx Event</a> this year in Shanghai.</p>
<p>After that, I joined in a start-up company and created a <a href="" title="Link to Eleme Napos" target="_blank">webapp</a> for restaurants and contributed to the <a href="" target="_blank">new website</a> redesign and later led the frontend development.</p>
<p>Thanks to the people I worked with, I also have fallen in love with Unix and learned to setup various backend service. A summary on technology learned will cover this geeky issue.</p>
<p>The progress is mostly due to the <a href="" title="section of personal management system">personal management system</a> I have developed to manage my times and goals. In 2011, I <strong>recorded 7.58 hours</strong> and worked with focus for <strong>4.18 hours everyday</strong>.</p>
<p>However in other aspects, things haven’t worked out as expected. Due to my work in the second half year, English learning have been paused and travel plan to Southern Asia was canceled. Besides I have been suffering from anxieties from time to time and getting up early still eludes me.</p>
<p>From the ups and downs of 2011, I learned a lot <a href="" title="Lesson I have learned" target="_blank">lessons</a> and I am thinking about moving forward.</p>
<h2 id="a-more-close-look-at-2011">A More Close Look at 2011</h2>
<h3 id="english-writing">English Writing</h3>
<p>The biggest achievement for English study is that I have developed a memorizing system with <a href="" title="Supermemo methods" target="_blank">Supermemo</a> methodology for learning. I collected sentences and words from my reading and quoted the detailed explanation in that context from dictionaries. Later this collection was transformed into Supermemo items (with the format of xml) through a script. The Supermemo software then took care of the repetition plans.</p>
<p>Through out the year, I have remembered <strong>2151</strong> sentences, <strong>1412</strong> Nouns, <strong>441</strong> oral phrases and <strong>2477</strong> words spelling.</p>
<p>The repetition plans are calculated according to the supermemo algorithm which makes sure I will remember what I have learned. The learning effort becomes accumulative.</p>
<p>Although working out well, the performance still fell short of the goals as I had paused learning new words in the 2nd half year due to my work. A initial habit breaking in June finally led to a permanent stop. In November, I had more than 3000 drills need to be caught up with.</p>
<p>For the same reason, I also missed the goals for English reading and writing.</p>
<p>I planned to write 15 publishable articles (20,000 words) but I only ended up in only <a href="" title="Presentation about what hinders adult from learning" target="_blank">one</a> and some drafts. I also missed the goal to finish 10 non-tech English books. There were about ten books I have opened this year but I didn’t finish all of them.</p>
<li>Hermann Hesse - Siddhartha, listened several times with audio version.</li>
<li>Rilke - Letters To A Young Poet, read through once.</li>
<li>Ernest Hemingway - The Old Man and the Sea, read through several times and recited the first 20% of the book.</li>
<li>Carson McCullers - The Heart is a Lonely Hunter, finished Part one</li>
<li>Malcolm Gladwell - Outliers -The Story Of Success, listened the audiobook.</li>
<li>Malcolm Gladwell - Blink, listened with the audiobook.</li>
<li>Mihaly Csikszentmihalyi - Flow, read through once</li>
<li>Anne Lamott - Bird by Bird, read 50% of all chapters</li>
<p>The biggest achievement is that I have accustomized myself to reading electronic books. I built myself an search-able library and I also customize the <a href="" title="PDF-XChange Viewer" target="_blank">great PDF reader</a> with an highlight system to mark while reading. With the notes and comments, I could archive the same reading experience as reading a paper book while gain the ability to search with convenience.</p>
<h3 id="web-design-and-computer-science">Web Design and Computer Science</h3>
<p>I wanted myself to be a “qualified web designer” in the beginning of the year and thanks to my full-time work in the second half year I have exceeded this goal by all means.</p>
<p>I have acquired all the core skills I planned to master - <code>HTML5</code>, <code>CSS</code>, <code>javaScript</code> and created five sites. Besides, I also have switched my workspace to Unix (MacOS and Ubuntu), learned to setup servers (HTTP, SSH etc.), learned basic <code>Ruby</code> scripting and also contributed <a href="" title="Stackoverflow Profile" target="_blank">a little back to the community</a>.</p>
<p>Beyond the details of various technology, I began to form a big picture about the whole “web stack” - how a browser renders to a user based on HTTP response processed by the server. This guide map now provides me a clear clue about what I need to learn in the future.</p>
<p>The part that fell short is the financial income. I began to get incomes in June but I didn’t reach my goals for saving. The reason is that I compromised my salary for expected options. As I left the team, those promise won’t be cashed in. I was also quite inactive on the business side. I didn’t make any effort to negotiate my incomes or look for contract projects.</p>
<h3 id="travel">Travel</h3>
<p>Although I have processed material and booked three tickets to Malaysia, Indonesia and Thailand, I canceled the itinerary because of work in the second half year.</p>
<p>I set travel the highest priority in the planning, but along the time, I found becoming a good developer and designer motivates me much more than travel. Near the end of year <a href="" title="Nancy's Speech" target="_blank">Nancy from ScentLibrary</a> also asked me “Why are you travel?”. It makes me powder my motivation underneath - exploration is just a process not a goal, so what is my ultimate goal of living?</p>
<p>This stunning question provides a clue I need to follow.</p>
<h3 id="physical-training-and-habit">Physical Training and Habit</h3>
<h4 id="personal-management-system">Personal Management System</h4>
<p>The corner stone for all my growth is the time management system I invented by combining the methods of GTD, <a href="" title="Pomodoro Methods" target="_blank">Pomodoro</a> and <a href="" title="Lyubishchev's Methods" target="_blank">Lyubishchev</a>. I used GTD method to setup top-down goals and break them down to single tasks. Everyday I cleared my task stack one by one. At last, I recorded and audited my time spending to detect spaces for improvement. I edited the sheet created by <a href="" title="aonc site" target="_blank">Chris@ANOC</a> and I invented my own sheet for weekly and daily planning. You could find the whole toolkit <a href="" title="personal management toolkit" target="_blank">here</a>.</p>
<p>I also did some improvement to this system while I am using it:</p>
<li>I add the feature-week and feature-day to ramp up energy for starting some new projects;</li>
<li>I separates the hours of working and learning;</li>
<li>I wrote down everyday tasks in the beginning of the week;</li>
<li>I would use several pomodoros in a row to handle big tasks;</li>
<li>I also record normal time spendings.</li>
<p>The lesson learned with this system is:</p>
<li><strong>Always</strong> start your week with a plan.
When you postponed the planning, I have whiled away my time in 78 days.</li>
<li>Plan loosely, work hard.
In the first several weeks, I packed too much tasks into a week. It overwhelmingly exceeded my capacity and resulted in anxiety and frustration.</li>
<li>Leave flexible time with planning.
I find there are always some inevitable sporadic events I need to handle.</li>
<li>Always motivate yourself.
I recorded 1742 hours in the first 30 weeks and only recorded 433 in the later 22. This happens because when I am at work, I cut the time for inspiration. This huge productivity decline is caused by lack of motivation.</li>
<h4 id="physical-training-and-health">Physical Training and Health</h4>
<p>I did a bad job in health and training. From January to June, I would swim twice every week and from March I would do 100 push-ups everyday. However the exercise time was still less than the 30 min everyday. This situation was worse in the second half year.</p>
<p>As a result, I began to suffer from aches at shoulder and low backbone. In the end of the year, the pain could even last the whole day and make sitting an discomfortable position.</p>
<p>Another setback in health is my biological clock. The habit of getting up early still eluded me. I was still quite exciting after midnight and I used to work later than 12:00pm since May. The situation got worse when I went to work where I slept later than 2:00am in average. With the shift in sleeping hours, I also have shifted the time I get up - usually 8 hours after I went to bed.</p>
<p>This shift in sleeping hours dispairs my sleeping quality and I felt a decline in endurance and time of focus when I am working.</p>
<title type="html"><![CDATA[Lesson Learned]]></title>
<link href=""/>
<content type="html"><![CDATA[<p>The experience I had in 2011 is invaluable. It extends my perception of work and achievement. Some lessons are learned through trial-and-error and some are learned from costly mistakes.</p>
<ul id="markdown-toc">
<li><a href="#lesson-1-know-how-to-sustain-yourself">Lesson 1: Know How to Sustain Yourself</a> <ul>
<li><a href="#a-frustrating-start">A Frustrating Start</a></li>
<li><a href="#always-choose-to-take-action">Always Choose to Take Action</a></li>
<li><a href="#lesson-2-dont-avoid-the-boring-work">Lesson 2: Don’t avoid the boring work</a></li>
<li><a href="#lesson-3-guard-against-distraction">Lesson 3: Guard Against Distraction</a></li>
<li><a href="#lesson-4-walk-at-your-own-pace">Lesson 4: Walk at Your Own Pace</a></li>
<li><a href="#lesson-5-identify-the-opportunity">Lesson 5: Identify the “Opportunity”</a></li>
<h2 id="lesson-1-know-how-to-sustain-yourself">Lesson 1: Know How to Sustain Yourself</h2>
<h3 id="a-frustrating-start">A Frustrating Start</h3>
<p>Nobody, as long as he moves about among the chaotic currents of life, is without trouble. - Carl Jung</p>
<p>After the first thrilling weeks since I dived into computer science, things turned out to be much more daunting than I thought before. Without preparation I walked into an obscure reign with a ‘map’ full of mystical symbols. Soon I realized that there were more areas I needed to explore, the ‘map’ I had was just an entrance to a much bigger world. In that world, I would encounter stunning web products on a daily basis. The more products I saw, the eager I wanted to be able to create and the more frustration I ended up with - I didn’t even know how to make a single web page.</p>
<p>Besides frustration, self-doubt is another setback. I constantly doubted myself because I had no experience in computer science. Did I choose the right technology to learn? Was I learning too slowly? Did I miss something important? How long would it take to reach the next stage? There was no place to find the answers. To comfort myself I had to choose to ignore them.</p>
<p><img src="" alt="My yelling self" class="right" />
Ignoring didn’t solve the problem. As the excitement and confidence subsided, the accumulating fear and doubt finally dominated. I was worn out. There comes the time when I found myself utterly useless:</p>
<p>A 24-year-old who just start learning web design and development alone without the ability to feed his own living.</p>
<p>What a bum.</p>
<h3 id="always-choose-to-take-action">Always Choose to Take Action</h3>
<p>Time to give up?</p>
<p>I thought about it honestly. However, I reasoned out that if I gave up and started in another field I had to experience the same frustration again. If this <strong>pattern of problem</strong> couldn’t be overcome, I could go nowhere further than where I was. I had to sustain myself and keep on walking.</p>
<p>If this <strong>pattern of problem</strong> couldn’t be overcome, I could go nowhere further than where I was.</p>
<p>Having no choice to fall back on, I needed to <strong>protect my motivation</strong> in order to deal with the fear and doubt. Thus I developed <a href="" title="My Quotes" target="_blank">Qotto</a> - a collection of quotes I like. I set it as my default browser tab and feed me inspiration when I feel disheartened.</p>
<p>I also decided <strong>always choose to take action</strong> when I feel frustrated. Whenever I feel overwhelmed by self-doubt, I force myself to do something - anything from reading one or two pages of a book to making several lines of code work. The actions I took always provide me with positive feedback. I learned one or two tips to use a language, make a small piece of code work under my will. However small they were, it convinced me that I was moving forward. And moving forward is the one most important action to overcome the frustration.</p>
<h2 id="lesson-2-dont-avoid-the-boring-work">Lesson 2: Don’t avoid the boring work</h2>
<p>After working on some personal projects and later in a start-up company, I learned that getting the boring work done is necessary to deliver great work.</p>
<p>For every creative work, the process to form and express an idea is often thrilling and inspiring, be it in way of writing, drawing, coding etc. It is then followed by a long and boring process to fix things and polish them up. This sort of work seems not as creative as the previous one. However it is <strong>this boring process determines the quality of the creation</strong>.</p>
<p>Take writing as an example, the first several hours of writing are always thrilling. With several rough points of view in mind, it is easy to pull together several ideas into paragraphs quickly. But then there comes the boring part. The right words need to be found and weighed in order to express the ideas with accuracy. The whole structure needs to be balanced - excessive part need be compressed or removed, confusing one will be rewritten, weak arguments need to be strengthened. Then mistakes in spelling and grammar need to be spotted and fixed. For me, the polishing up work will often take almost twice the time of writing itself.</p>
<p>The same rule applies to coding. An elegant solution isn’t found in the from the outset. After thinking about a problem, doing some research and weighing several choices, I would rough out a solution to work with. When this creative part of work is done, I need to sketch the idea out from writing the first piece of code, making it work, adding another part, making them work together and so on so forth. When the whole pieces are working as expected, I will rewrite it towards a modularized structure and improve its performance and legibility.</p>
<p>…it is often this boring parts of work separate professionals from amateurs.</p>
<p>This repetitive and humdrum process is shared in all kinds of work. <strong>It is often this boring work separates professionals from amateurs.</strong> We could only take care of one aspect of creation at one time. When pulling ideas out of our head, we want it to flow smoothly, one after another, and often result in a mess. When an idea is roughed out, refinement process is needed to fix the part that doesn’t work and polish the whole thing up in all aspects. Although boring and daunting, without this refinement, a messed-up products based on even brilliant idea won’t work.</p>
<h2 id="lesson-3-guard-against-distraction">Lesson 3: Guard Against Distraction</h2>
<p>It takes time to realize even one idea and there are so many of them. Thus it is important to guard myself against distraction.</p>
<p>In 2011, I recorded 130 new ideas and took actions on 43 of them. Some were improvement on what I had been doing but some were only sporadic impulses to try something out. The projects driven by these impulses were often canceled or abandoned within one month. This failed attempts cover:</p>
<li>Learning Drovak keyboard layout</li>
<li>Attend 54 air companies’ frequent miles program to earn travel tickets</li>
<li>Try to recite <the old="" man="" and="" sea="" /></li>
<li>To learn the ins and outs of <code>Wordpress</code></li>
<li>Learning <code>Django</code></li>
<li>Worked on several projects with friends</li>
<p>The time spent on those projects was wasted. This wasted time is the <strong>cost of distraction</strong>. If I was able to turn down all of them but focus my work on one, at least I could make one difference in my current situation.</p>
<p>It takes time to realize even one idea and there are so many of them I <em>could</em> take action on. Thus it is important to guard myself against distraction and only focus on the most important stuff. I need to <strong>detect those distraction</strong> and <strong>prevent myself taking actions</strong>.</p>
<p>To detect distraction, the <strong>minimal viable rule</strong> works well. When I get thrilled by one idea, I will check it against the question ‘is it necessary or better than my current methods to approach my goal?’. If the answer is not an absolutely ‘yes’, it is a distraction.</p>
<p>To prevent taking action, I will ask another question against it - ‘will you be doing it one month later? six month later? one year later?’ It the answer is no, I will drop it because I don’t even have enough determination in the beginning. Without the resolution, I won’t be able to sustain myself through the tough process to pull an idea off.</p>
<h2 id="lesson-4-walk-at-your-own-pace">Lesson 4: Walk at Your Own Pace</h2>
<p>Being slow is in fact being fast. It is natural to begin slowly because there are skills to learn, knowledge to acquire and obstacles to overcome.</p>
<p>In the first few weeks, I always crammed too much stuff into one single week - I wanted to read several chapters of a book, write an article, practice programming and design skills. A goal to accomplish all these tasks was, obviously, unreachable.</p>
<p>After several rushing but frustrating weeks, I gradually discovered my own pace for <strong>each</strong> task. When reading, I need 8 pages/hour to follow a technology book, 12 pages/hour for familiar topics, 2-3 pages/hour to follow a literature book. When writing, I need 8 hours to produce an article. When doing design work, I need 15-20 hours to find the right tone of the whole project and I need 4-5 hours for each individual page/poster design.</p>
<p>Whenever I rush a task I will inevitably miss something. If I rush at technology learning, I wouldn’t have time to exercise. Thus I will end up with only acquaintance with the technology but not practical experience. If I rush a literature book, I would miss the subtle nuance of meaning and end up with a fuzzy story outline. If I rush the coding, I would copy and paste snippets from others without a fully understanding. Thus my skill isn’t improved and the following maintenance work will be a pain.</p>
<p>Being slow is in fact being fast. It is natural to begin slowly because there are skills to learn, knowledge to acquire and obstacles to overcome. Being a beginner in a novel field, I couldn’t predict the situation with accuracy. I need to learn crawling before I could walk and run. Only after required practices at a slow pace, I could get myself accustomed to crawling and it is the time I could get my hands off the ground and start learning walking and then running. Being slow is the necessary process before being fast. Rushing up in the beginning would only trip me up.</p>
<h2 id="lesson-5-identify-the-opportunity">Lesson 5: Identify the “Opportunity”</h2>
<p>Opportunity is a very personal thing. Another people’s opportunity isn’t necessarily mine as we might have very difference goals.</p>
<p>In my second half year, most of my goals are not archived (English learning, design, backend technology and financial goals), productivity drops and unhappiness arrives. After I join in a company, my original direction is diverted to another route. This setback is caused by the fault to mistake “one possible way” for my opportunity.</p>
<p>Opportunity is a very personal thing. Another people’s opportunity isn’t necessarily mine as we might have very difference goals. <strong>Opportunity is like the highway which leads to <em>my</em> destination</strong>. There are lots of entrances to different highways. Driving into the wrong ones won’t get me further.</p>
<p>To choose the right one, it is essential to have one confirmed destination. I made a mistake in August when joining the company because I was not determined to stick to mine. I was convinced that “being a core member of a successful company will be a huge boost for my personal development”. It turned out to be a bad choice as working with the company whose values aren’t congruent with mine is a miserable experience. When I left the team, both sides suffered from some loss.</p>
<p>This is a costly lesson learned. In 2012, I will lay down the most important goals in the annual plan and use them to prevent the same mistake happening again.</p>
<title type="html"><![CDATA[Speech at TEDxYouth West Lake]]></title>
<link href=""/>
<content type="html"><![CDATA[<h2 id="what-holds-us-back-from-changes">What Holds Us Back from Changes</h2>
<p><img src="" alt="TEDxWestlake Logo" class="right" />
This is the a talk I delivered at <a href="" title="TEDxYouth Details">TEDxYouth Wesk Lake</a> on August 21th 2011.</p>
<p>I talked about lessons learned from my experience to change career path from an background of Economics to web designer and developer in 301 days.</p>
<embed class="" src="" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="opaque" width="480" height="360" />
<div style="width:480px; margin:0 auto;" id="__ss_10760600"><object id="__sse10760600" width="480" height="404"><param name="movie" value=";stripped_title=what-holds-us-back-from-changes&amp;userName=yangchenyun" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="wmode" value="transparent" /><embed name="__sse10760600" src=";stripped_title=what-holds-us-back-from-changes&amp;userName=yangchenyun" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" width="480" height="404" /></object></div>
<p>The related files could be found <a href="" title="Presentation Files of my TEDxYouth Talk">here</a>.</p>
<p>Thanks for all the lovely organizers to pull this event off.</p>