<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Software Bloat &#187; general</title>
	<atom:link href="http://www.softwarebloat.com/category/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.softwarebloat.com</link>
	<description>Simple software project management.</description>
	<lastBuildDate>Sun, 14 Feb 2010 03:01:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using Yammer and Git with git2yammer</title>
		<link>http://www.softwarebloat.com/2009/03/09/using-yammer-and-git-with-git2yammer/</link>
		<comments>http://www.softwarebloat.com/2009/03/09/using-yammer-and-git-with-git2yammer/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 04:08:03 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[communication]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[engineering]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[yammer]]></category>

		<guid isPermaLink="false">http://www.softwarebloat.com/?p=215</guid>
		<description><![CDATA[Using the Yammer API we've been able to tie Git into the system so that notifications are sent out after each commit which contain the commiter, the commit message, and a hash tag which associates the Yammer message with the project.]]></description>
			<content:encoded><![CDATA[<p><em>The most important thing in communication is to hear what isn&#8217;t being said. &#8212; Peter Drucker</em></p>

<p><a href="http://www.yammer.com/">Yammer</a> is a web app that lets you &#8220;connect and share with the people in your company or organization&#8221;.  It&#8217;s basically <a href="http://www.twitter.com/">Twitter</a> for your intranet.</p>

<p>We use it to fire off quick messages about the progress we&#8217;ve made and the challenges we&#8217;re facing on our projects.  <strong>Using the Yammer API we&#8217;ve been able to tie <a href="http://git-scm.com/">Git</a> into the system so that notifications are sent out after each commit which contain the commiter, the commit message, and a hash tag associating the Yammer message with the git repository name.</strong><span id="more-215"></span></p>

<p><img src="http://www.softwarebloat.com/wp-content/uploads/2009/03/bc_shout-264x300.jpg" alt="bc_shout" title="bc_shout" width="264" height="300" class="alignnone size-medium wp-image-216" /></p>

<p>The idea of broadcasting status information like this is similar in concept to Alistair Cockburn&#8217;s idea of <a href="http://alistair.cockburn.us/Information+radiator">Information Radiators</a>.  From his page describing the concept:</p>

<p>[...] <strong>“information radiator” refers to a publicly posted display that shows people walking by what is going on. Information radiators are best when they are big, very easy to see (e.g. not online, generally), and change often enough to be worth revisiting</strong></p>

<p>My favorite example has always been <a href="http://pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/Devices/BubbleBubbleBuildsInTrouble.rdoc">using lava lamps to indicate build status</a>.</p>

<p>Anyway, the code has been made available on my github at <a href="http://github.com/rboyd/git2yammer/tree/master">http://github.com/rboyd/git2yammer/tree/master</a>.  Using git with yammer has been great for us so far and I hope you find it useful in your projects as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2009/03/09/using-yammer-and-git-with-git2yammer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Backup Blueprints: Automate Backups With Amazon S3</title>
		<link>http://www.softwarebloat.com/2009/02/16/backup-blueprints-automate-backups-with-amazon-s3/</link>
		<comments>http://www.softwarebloat.com/2009/02/16/backup-blueprints-automate-backups-with-amazon-s3/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 04:58:55 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[blueprints]]></category>
		<category><![CDATA[s3]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.softwarebloat.com/?p=183</guid>
		<description><![CDATA[Always in the back of your mind, that nagging thought -- <strong>what would happen if I lost all my data?</strong>]]></description>
			<content:encoded><![CDATA[<p><em>&#8220;A pint of sweat, saves a gallon of blood.&#8221; &#8212; George S. Patton</em></p>

<p>You know you should do it, but you still don&#8217;t.  It&#8217;s eating at you really.  Always in the back of your mind, that nagging thought &#8212; <strong>what would happen if I lost all my data?</strong></p>

<p>So here you go.  <strong>My recipe for taking nightly snapshots of mission critical data and backing up to <a href="http://aws.amazon.com/s3/">Amazon S3</a>.</strong><span id="more-183"></span>  Just replace the relevant directories, MySQL password, and S3 bucket name with your own.  You&#8217;ll also need to setup your AWS SSH keys before s3cmd will work.</p>

<p>Note: this script requires the program <strong>s3cmd</strong> which can be installed on debian-based systems (like Ubuntu) with <strong>apt-get -y install s3cmd</strong></p>

<p><pre name="code" class="bash:nogutter">
GIT_DIR="/srv/git"
HUDSON_DIR="/srv/hudson"
REDMINE_DIR="/mnt/redmine"
BACKUP_DIR="/root/backups"</p>

<p>DATE_TAG=$(date +%m_%d_%Y)</p>

<h1>backup key directories</h1>

<p>tar pczvf $BACKUP_DIR/git.$DATE_TAG.tgz $GIT_DIR
tar pczvf $BACKUP_DIR/hudson.$DATE_TAG.tgz $HUDSON_DIR
tar pczvf $BACKUP_DIR/redmine.$DATE_TAG.tgz $REDMINE_DIR</p>

<p>#</p>

<h1>backup databases</h1>

<p>mysqldump --password=your_pw_here --all-databases | gzip -c &gt; $BACKUP_DIR/mysql
.$DATE_TAG.gz</p>

<p>for f in $BACKUP_DIR/<em>$DATE_TAG</em>
do
    /usr/bin/s3cmd -c /root/.s3cfg put $f s3://your_bucket_here.com/$(basename $f) &gt;&gt; 
/root/backup.log 2&gt;&amp;1
done
</pre></p>

<p>Save that script to a file named <strong>backups</strong> and drop it in <strong>/etc/cron.daily</strong>.  Make sure it&#8217;s root-owned (<strong>chown root.root backups</strong>) and has the proper permissions (<strong>chmod 755 backups</strong>).</p>

<p>Keep in mind this will accumulate files in the backups directory in its current state, so you might want to add a line to remove the backups after storing to s3.  Personally I like to delete them manually after ensuring the backup was performed correctly.</p>

<p>I hope this saves somebody&#8217;s ass someday &#8212; it&#8217;s already saved mine.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2009/02/16/backup-blueprints-automate-backups-with-amazon-s3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Book Report: Reality Check</title>
		<link>http://www.softwarebloat.com/2009/02/15/book-report-reality-check/</link>
		<comments>http://www.softwarebloat.com/2009/02/15/book-report-reality-check/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 01:20:59 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[book reports]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[guy kawasaki]]></category>
		<category><![CDATA[reality check]]></category>

		<guid isPermaLink="false">http://www.softwarebloat.com/?p=165</guid>
		<description><![CDATA[“Many receive advice, only the wise profit from it.&#8221; &#8211;  Publilius Syrus

If I could choose a life coach for this stage of my life, it would be Guy Kawasaki. In his latest book Reality Check, Guy has done an awesome job of covering all the bases.

Having spent a few years there myself, I found his [...]]]></description>
			<content:encoded><![CDATA[<p><em>“Many receive advice, only the wise profit from it.&#8221; &#8211;  Publilius Syrus
</em><strong>
If I could choose a life coach for this stage of my life, it would be Guy Kawasaki.</strong> In his latest book Reality Check, Guy has done an awesome job of covering all the bases.<span id="more-165"></span></p>

<div id="attachment_166" class="wp-caption aligncenter" style="width: 209px"><img class="size-medium wp-image-166" src="http://www.softwarebloat.com/wp-content/uploads/2009/02/reality_check_cover-199x300.jpg" alt="Cover of Guy Kawasaki's book Reality Check." width="199" height="300" /><p class="wp-caption-text">Cover of Guy Kawasaki&#39;s book Reality Check.</p></div>

<p>Having spent a few years there myself, I found his portrayal of Silicon Valley both hilarious and accurate.  <strong>If I had a nickel for every company suffering from extreme amounts of wasteful spending or delusions of grandeur &#8212; well, I never would have banked on those stock options.</strong></p>

<p>My favorite thing about the book though has to be the way he presents the various personalities at play in startups and business.  He presents some of these roles in a list that would make David Letterman proud.  For example, from The Top Seventeen Lies of CEOs:</p>

<p><strong>&#8220;Working together, we&#8217;ve established our goals.&#8221;</strong> In other words, these are the goals that the CEO decided will make him look good.  Few managers believe that these goals are doable, and yet they are the ones who are going to have to accomplish them.  But that&#8217; what &#8220;working together&#8221; means: The CEO decides and the workers do.</p>

<p>(similar sections on lies told by VC, Entrepreneurs, Engineers, Lawyers and Partners)</p>

<p>Other sage wisdom in this book includes advice on effective communication techniques, especially emailing, demoing, and presenting.</p>

<p>There&#8217;s a hilarious chapter on handling the competition where he cites some pretty clever little tactics.  <strong>For example the new pizza store that offered customer discounts if they brought in the torn-out Yellow Pages of the competitors restaurants.  Or the hardware store owner that responded to a competing national chain opening up right next door by hanging a sign over his door that read &#8220;MAIN ENTRANCE&#8221;.</strong></p>

<p>Mr. Kawasaki left me with a &#8220;just go get it done&#8221; attitude after reading this book.  This is definitely one of my favorite books on business, startups and tech culture and it definitely deserves a place on your bookshelf.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2009/02/15/book-report-reality-check/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Intentional Programming: This Space Intentionally Left Blank</title>
		<link>http://www.softwarebloat.com/2008/12/23/intentional-programming-this-space-intentionally-left-blank/</link>
		<comments>http://www.softwarebloat.com/2008/12/23/intentional-programming-this-space-intentionally-left-blank/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 22:36:27 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[charles simonyi]]></category>
		<category><![CDATA[domain specific languages]]></category>
		<category><![CDATA[generative programming]]></category>
		<category><![CDATA[intentional programming]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://softwarebloat.com/?p=136</guid>
		<description><![CDATA[If you have spent any time developing Windows applications in the last decade you&#8217;ve probably used a silly naming convention called Hungarian Notation where you would prepend type information before a variable name (e.g. &#8220;szName&#8221; for a zero-terminated string).  We have Charles Simonyi to thank for this technique, which seems to have fallen by [...]]]></description>
			<content:encoded><![CDATA[<p>If you have spent any time developing Windows applications in the last decade you&#8217;ve probably used a silly naming convention called <a href="http://en.wikipedia.org/wiki/Hungarian_notation">Hungarian Notation</a> where you would prepend type information before a variable name (e.g. &#8220;szName&#8221; for a zero-terminated string).  We have <a href="http://en.wikipedia.org/wiki/Charles_Simonyi">Charles Simonyi</a> to thank for this technique, which seems to have fallen by the wayside in light of newer dynamically-typed languages.  Simonyi made over a billion dollars working with Gates at Microsoft and later made history by spending some of that money on launching himself into space and visiting the International Space Station as the world&#8217;s fifth space tourist.</p>

<p>Anyway, I was thinking about the future of software development and I remembered reading <a href="http://www.forbes.com/forbes/2002/1223/342.html">an interview with Dr. Simonyi</a> in Forbes circa 2002 about a technology he was developing called &#8220;<strong>Intentional Programming</strong>&#8220;.  Not much has been written about Intentional Programming but we do have a few resources on the subject.</p>

<ul>
    <li>US Patents: <a href="http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&amp;Sect2=HITOFF&amp;p=1&amp;u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&amp;r=5&amp;f=G&amp;l=50&amp;co1=AND&amp;d=PTXT&amp;s1=Simonyi.INNM.&amp;OS=IN/Simonyi&amp;RS=IN/Simonyi">6,966,054</a>, <a href="http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&amp;Sect2=HITOFF&amp;p=1&amp;u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&amp;r=4&amp;f=G&amp;l=50&amp;co1=AND&amp;d=PTXT&amp;s1=Simonyi.INNM.&amp;OS=IN/Simonyi&amp;RS=IN/Simonyi">7,051,279</a>, <a href="http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&amp;Sect2=HITOFF&amp;p=1&amp;u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&amp;r=3&amp;f=G&amp;l=50&amp;co1=AND&amp;d=PTXT&amp;s1=Simonyi.INNM.&amp;OS=IN/Simonyi&amp;RS=IN/Simonyi">7,165,238</a>, <a href="http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&amp;Sect2=HITOFF&amp;p=1&amp;u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&amp;r=1&amp;f=G&amp;l=50&amp;co1=AND&amp;d=PTXT&amp;s1=Simonyi.INNM.&amp;OS=IN/Simonyi&amp;RS=IN/Simonyi">7,237,226</a></li>
    <li>YouTube Videos: <a href="http://www.youtube.com/watch?v=tSnnfUj1XCQ">Intentional Programming demo (Part 1) &#8211; Editor</a>, <a href="http://www.youtube.com/watch?v=ZZDwB4-DPXE">Intentional Programming demo (Part 2) &#8211; Compiler</a></li>
    <li>One chapter in the book <a href="http://www.amazon.com/review/product/0201309777">Generative Programming: Methods, Tools, and Applications</a></li>
    <li>Interviews with Charles Simonyi (<a href="http://www.codegeneration.net/tiki-read_article.php?articleId=61">here</a>, <a href="http://www.edge.org/digerati/simonyi/simonyi_p1.html">here</a>, <a href="http://blogs.zdnet.com/BTL/index.php?p=1190">here</a>, and <a href="http://www.youtube.com/watch?v=R02GFdxvuqc">here</a>)</li>
</ul>

<p>Simonyi&#8217;s vision is in line with the theme of this blog: <strong>building good software should be easier</strong>.  His approach seems to resonate with similarities to other concepts such as domain specific languages and metaprogramming.  <strong>Intentional Programming calls for domain experts to capture their intentions of a program&#8217;s inner-workings in a tree structure which is versioned and databased and later translated into program code.</strong> This translation borrows from biology and the system responsible for this work is called an &#8220;enzyme&#8221; in Intentional Programming parlance.</p>

<p>Did Microsoft scrap the project?  Critics of Simonyi have spoken out against Intentional Programming by asserting that his method merely shifts the complexity from application development to the development of these new translation modules &#8212; and perhaps rightly so.  Also missing from materials on the Intentional approach is any mention of the debugging and testing processes.</p>

<p>Is Intentional Programming vaporware?  Perhaps.  Or perhaps Simonyi and his team are already quietly enjoying levels of productivity that the rest of us can only dream about.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2008/12/23/intentional-programming-this-space-intentionally-left-blank/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programmer Efficiency: Test Your Might!</title>
		<link>http://www.softwarebloat.com/2008/11/30/programmer-efficiency-test-your-might/</link>
		<comments>http://www.softwarebloat.com/2008/11/30/programmer-efficiency-test-your-might/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 20:54:08 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[codegolf]]></category>
		<category><![CDATA[efficiency]]></category>
		<category><![CDATA[fizzbuzz]]></category>
		<category><![CDATA[judo]]></category>
		<category><![CDATA[larry wall]]></category>
		<category><![CDATA[laziness]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[pragmatic programmer]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[virtues]]></category>

		<guid isPermaLink="false">http://softwarebloat.wordpress.com/?p=124</guid>
		<description><![CDATA[&#8220;We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris.&#8221; &#8212; Larry Wall

Good programmers are like Judo masters &#8212; they both practice the art of maximizing efficiency.


Larry Wall (the founder of Perl) defined laziness as:

&#8220;The quality that makes you go to great effort to reduce overall energy expenditure. [...]]]></description>
			<content:encoded><![CDATA[<p><em>&#8220;We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris.&#8221; &#8212; Larry Wall</em></p>

<a href="http://www.softwarebloat.com/2008/11/30/programmer-efficiency-test-your-might/"><p><em>Click here to view the embedded video.</em></p></a>

<p><strong>Good programmers are like Judo masters &#8212; they both practice the art of maximizing efficiency.
</strong></p>

<p>Larry Wall (the founder of Perl) defined laziness as:</p>

<p>&#8220;<strong>The quality that makes you go to great effort to reduce overall energy expenditure</strong>. It makes you write labor-saving programs that other people will find useful, and document what you wrote so you don&#8217;t have to answer so many questions about it. Hence, the first great virtue of a programmer.&#8221;</p>

<p><strong>He&#8217;s not talking about programmers with bad work ethic here.  No, he&#8217;s talking about expert programmers who know how to make every keystroke count.
</strong>
From <a href="http://en.wikipedia.org/wiki/Judo">Wikipedia&#8217;s article on Judo</a>:</p>

<p>&#8220;The word &#8220;judo&#8221; shares the same root ideogram as &#8220;jujutsu&#8221;: &#8220;jū&#8221; (柔, &#8220;jū&#8221;?), which may mean &#8220;gentleness&#8221;, &#8220;softness&#8221;, &#8220;suppleness&#8221;, and even &#8220;easy&#8221;, depending on its context. Such attempts to translate jū are deceptive, however. The use of jū in each of these words is an explicit reference to the martial arts principle of the &#8220;soft method&#8221; (柔法, jūhō?). The soft method is characterized by the indirect application of force to defeat an opponent. More specifically, it is the principle of using one&#8217;s opponent&#8217;s strength against him and adapting well to changing circumstances. For example, if the attacker was to push against his opponent he would find his opponent stepping to the side and allowing his momentum (often with the aid of a foot to trip him up) to throw him forwards (the inverse being true for pulling.) <strong>Kano saw jujutsu as a disconnected bag of tricks, and sought to unify it according to a principle, which he found in the notion of &#8220;maximum efficiency&#8221;</strong>. Jujutsu techniques that relied solely on superior strength were discarded or adapted in favour of those that involved redirecting the opponent&#8217;s force, off-balancing the opponent, or making use of superior leverage.</p>

<p><strong>Master software developers have a strong command over their tools.</strong>  One of the most <a href="http://www.pragprog.com/the-pragmatic-programmer/extracts/tips">important tips</a> from <a href="http://www.pragprog.com/titles/tpp/the-pragmatic-programmer">The Pragmatic Programmer</a> is to <strong>Use a Single Editor Well</strong>:</p>

<p><strong>&#8220;The editor should be an extension of your hand; make sure your editor is configurable, extensible, and programmable.&#8221;</strong></p>

<p>They&#8217;re also fluent in multiple programming languages and understand how to choose the best one for the job.  <strong>When more than one language may be appropriate, they choose the most expressive language available.
</strong>
Consider <a href="http://imranontech.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/">The FizzBuzz Problem</a> (a simple &#8220;weed-out&#8221; problem given to interview candidates) which has been stated as:</p>

<p>Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.</p>

<p>There are many general purpose programming languages that could be used to solve this problem.  Programmers have invented a game called <a href="http://codegolf.com/">Code Golf</a>.  The rules are simple &#8212; solve a problem with the shortest possible program.</p>

<p>Here&#8217;s a <a href="http://golf.shinh.org/p.rb?FizzBuzz#ranking">list of scores which demonstrates how various languages stack up to solve the FizzBuzz problem</a>.  We see Ruby and Python coming in at 56 characters each.  Compare that with C# (123) and Java (130) and you start to get the idea here.  <strong>If you were the policy carrier responsible for insuring these programmers against carpal-tunnel syndrome, who would you rather cover?</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2008/11/30/programmer-efficiency-test-your-might/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Book Report: Don&#8217;t Make Me Think</title>
		<link>http://www.softwarebloat.com/2008/11/29/book-report-dont-make-me-think/</link>
		<comments>http://www.softwarebloat.com/2008/11/29/book-report-dont-make-me-think/#comments</comments>
		<pubDate>Sat, 29 Nov 2008 01:24:27 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[accessibility]]></category>
		<category><![CDATA[bookreports]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[krug]]></category>
		<category><![CDATA[usability]]></category>
		<category><![CDATA[ux]]></category>
		<category><![CDATA[webdesign]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://softwarebloat.wordpress.com/?p=108</guid>
		<description><![CDATA[This book&#8217;s fitting subtitle is &#8220;a common sense approach to web usability&#8220;.  Steve Krug has done a fine job of presenting his expert-level experience with making good websites better.  The book is a very easy read that is chock full of useful information.



I have often visited a website or reviewed a proposal from [...]]]></description>
			<content:encoded><![CDATA[<p>This book&#8217;s fitting subtitle is &#8220;<strong>a common sense approach to web usability</strong>&#8220;.  Steve Krug has done a fine job of presenting his expert-level experience with making good websites better.  The book is a very easy read that is chock full of useful information.</p>

<p><a href="http://www.softwarebloat.com/wp-content/uploads/2008/11/dont_make_me_think_2nd.png"><img src="http://www.softwarebloat.com/wp-content/uploads/2008/11/dont_make_me_think_2nd.png?w=233" alt="" title="" width="233" height="300" class="aligncenter size-medium wp-image-109" /></a></p>

<p>I have often visited a website or reviewed a proposal from a designer and get the feeling that the design is inadequate &#8212; but <strong>until I read this book I didn&#8217;t have the tools to identify and outline specific problems in web design</strong>.  In the first few chapters the author describes a test for recognizing issues with areas such as: presentation, layout, navigation, search, and site identification.</p>

<p>One of the fundamental takeaways from this book is that your website should be a &#8220;<a href="http://en.wikipedia.org/wiki/Mensch">Mensch</a>&#8221; &#8212; a Yiddish term which roughly translates to &#8220;a stand-up guy&#8221;.  <strong>Make things easy on your users.</strong>  Don&#8217;t ask them to fill out information in forms until that information is absolutely needed.  Make your website accessible to users with disabilities.  The book follows it&#8217;s own advice and is written in a very friendly and down-to-earth language.  It is illustrated with comical illustrations and great quotes throughout.</p>

<p>The last few chapters describe the benefits of conducting usability testing on your website.  <strong>It calls for testing early and often, and it outlines a plan for doing it without destroying your budget.</strong></p>

<p>Krug offers the book and hands-on training workshops at his company&#8217;s website, <a href="http://www.sensible.com/">Advanced Common Sense</a>.  See for yourself, the entire text of <a href="http://www.sensible.com/chapter.html">Chapter 2 is available online</a>.  <strong>If you build websites by vocation or avocation, I highly recommend you do yourself a favor and get yourself a copy of this book.</strong></p>

<p>P.S. BTW, in keeping with the spirit of this site (that is, growing a community of people sharing ideas for building better software) I&#8217;m not linking to this book with any sort of affiliate code, nor will I ever do this in the future.  That&#8217;s just annoying.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2008/11/29/book-report-dont-make-me-think/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Continuous Integration Blueprints: How to Build an Army of Killer Robots With Hudson and Cucumber</title>
		<link>http://www.softwarebloat.com/2008/11/19/continuous-integration-blueprints-how-to-build-an-army-of-killer-robots-with-hudson-and-cucumber/</link>
		<comments>http://www.softwarebloat.com/2008/11/19/continuous-integration-blueprints-how-to-build-an-army-of-killer-robots-with-hudson-and-cucumber/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 18:09:17 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[blueprints]]></category>
		<category><![CDATA[continuousintegration]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gitosis]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://softwarebloat.wordpress.com/?p=52</guid>
		<description><![CDATA[With my &#8220;blueprints&#8221; posts, I&#8217;d like to share recipes for building better software.  In this first installment my goal is to introduce you to a continuous integration environment by walking you through the steps to set up your own.  While following along, use your best judgement in deviating from the tutorial.  For [...]]]></description>
			<content:encoded><![CDATA[<p>With my &#8220;blueprints&#8221; posts, <strong>I&#8217;d like to share recipes for building better software</strong>.  In this first installment my goal is to introduce you to a <a href="http://martinfowler.com/articles/continuousIntegration.html">continuous integration</a> environment by walking you through the steps to set up your own.  While following along, use your best judgement in deviating from the tutorial.  For example, if you&#8217;re using another language besides Ruby in your project you might want to seek out and incorporate the preferred unit-test framework for that language (although Cucumber can also be used to test .NET, Java and ActionScript/Flex code).  <strong>This exercise takes about 30 minutes to run through.</strong></p>

<p><strong>The players:
</strong>
<a href="https://hudson.dev.java.net/">Hudson</a> &#8211; An extensible continuous integration engine
<a href="http://git.or.cz/">Git</a> &#8211; Fast version control system
<a href="http://eagain.net/gitweb/?p=gitosis.git;a=blob;f=README.rst">Gitosis</a> &#8211; Easier and safer repository hosting
<a href="http://merbivore.com/">Merb</a> &#8211; Lean and mean Ruby web app framework
<a href="http://github.com/aslakhellesoy/cucumber/wikis">Cucumber</a> &#8211; Execute feature documentation (stories) in plain text
<strong>
The Setup:</strong></p>

<p>Fresh Ubuntu 8.10 server install.  I&#8217;m running mine on <a href="http://aws.amazon.com/ec2/">Amazon&#8217;s EC2</a> using Alestic&#8217;s public ami-7806e211, but you should be just fine following with a local server if you&#8217;re not on the cloud yet.</p>

<p><strong>Step 0: Pre-installation</strong></p>

<p>It&#8217;s a good idea to update our packages before getting started:</p>

<p><pre name="code" class="bash:nogutter">
apt-get -y update &amp;&amp; apt-get -y upgrade
</pre></p>

<p><strong>Step 1: Install Java, Apache and Tomcat</strong></p>

<p>Hudson is a Java web application that plays nicely with Apache 2.2 and Tomcat 6.  First we&#8217;ll install Java, here&#8217;s how to get it going:</p>

<p><pre name="code" class="bash:nogutter">
apt-get -y install sun-java6-jdk
</pre></p>

<p>You&#8217;ll have to accept Sun&#8217;s license agreement during the Java install, but it&#8217;s pretty painless.</p>

<p>Then we can just:</p>

<p><pre name="code" class="bash:nogutter">
apt-get -y install apache2 tomcat6
</pre></p>

<p>If you try to install all three packages at the same time, tomcat may not start properly.  YMMV.</p>

<p><strong>Step 2: Convince Tomcat that it wants to run behind Apache, and prepare it for Hudson</strong></p>

<p>Now we need to configure Apache and Tomcat to communicate with each other over Apache&#8217;s binary AJP protocol.  We also need to prepare Tomcat for our Hudson install.  This is pretty boring and labor-intensive stuff, so instead of walking you through the specifics, I&#8217;m going to just publish my config files and have you use wget to overwrite yours with them.  If you want to see what I&#8217;ve modified then you can always backup your copies and diff them against mine.</p>

<p><pre name="code" class="bash:nogutter">
wget http://pastie.org/pastes/315473/download -O /etc/tomcat6/context.xml
wget http://pastie.org/pastes/315475/download -O /etc/default/tomcat6
wget http://pastie.org/pastes/316125/download -O /etc/apache2/apache2.conf
wget http://pastie.org/pastes/318217/download -O /etc/init.d/tomcat6
</pre></p>

<p>Now let&#8217;s create a directory for hudson to live in and restart Tomcat.</p>

<p><pre name="code" class="bash:nogutter">
mkdir /srv/hudson
chown tomcat6.tomcat6 /srv/hudson
/etc/init.d/tomcat6 restart
/etc/init.d/apache2 restart
</pre></p>

<p><strong>Step 3: Install Hudson</strong></p>

<p>This step is pretty painless, we just grab the latest version of Hudson and move it to Tomcat&#8217;s web app directory.</p>

<p><pre name="code" class="bash:nogutter">
wget http://hudson.gotdns.com/latest/hudson.war
chown tomcat6.tomcat6 hudson.war
mv hudson.war /var/lib/tomcat6/webapps/
</pre></p>

<p>Don&#8217;t worry, Tomcat will load it and set it up automatically.  At this point you should be able to access Hudson&#8217;s control panel.  Aim your browser at http://<strong>yourhost</strong>/hudson/ and have a look around.</p>

<p><strong>Step 4: Install Git and Gitosis</strong></p>

<p>The Git version control system seems to be the hacker&#8217;s choice these days.  We&#8217;ll grab the Git toolset itself as well as Gitosis which will allow us to manage users and public or private repositories.</p>

<p><pre name="code" class="bash:nogutter">
apt-get -y install git-core python-setuptools
git clone git://eagain.net/gitosis.git
cd gitosis
python setup.py install
adduser --system --shell /bin/sh --gecos 'git user' --group --disabled-password --home /srv/git git
cd ..
</pre></p>

<p>Now we need to generate a SSH key to manage Gitosis with.  This way you can add the private key to your keychain and manage gitosis from any machine you like.  Use a passphrase, or don&#8217;t, it&#8217;s up to you.  Then let&#8217;s run ssh-agent and add the new key.</p>

<p><pre name="code" class="bash:nogutter">
ssh-keygen -t rsa</p>

<h1>...</h1>

<p>ssh-agent /bin/bash
ssh-add ~/.ssh/id_rsa
</pre></p>

<p>Finally, let&#8217;s initialize Gitosis now that we have our key:</p>

<p><pre name="code" class="bash:nogutter">
sudo -H -u git gitosis-init &lt;~/.ssh/id_rsa.pub
</pre></p>

<p>We also need to make sure the post-update script has the proper permissions to execute so that our changes to the configuration take effect after we push them.  Here&#8217;s how:</p>

<p><pre name="code" class="bash:nogutter">
chmod 755 /srv/git/repositories/gitosis-admin.git/hooks/post-update
</pre></p>

<p>While we&#8217;re on the subject, let&#8217;s add Tomcat&#8217;s user account (tomcat6) to the git group so that it can clone repositories off of the local filesystem.</p>

<p>[sourcecode language='php']
usermod -G git tomcat6
</pre></p>

<p><strong>Step 5: Install Merb</strong></p>

<p><pre name="code" class="bash:nogutter">
apt-get -y install ruby-full libsqlite3-dev libxml-ruby libxslt-dev libxslt-ruby
wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz
tar -zxvf rubygems-1.3.1.tgz
cd rubygems-1.3.1
ruby setup.rb
ln -s /usr/bin/gem1.8 /usr/bin/gem
cd ..
gem install merb
</pre></p>

<p><strong>Step 6: Start the project and manage it with Git</strong></p>

<p>Now the real fun begins.  <strong>The whole point of this exercise of course is to build our killer robots in the most efficient way possible.</strong> So let's generate a new Merb application and get it under version control.</p>

<p><pre name="code" class="bash:nogutter">
merb-gen app robot
cd robot
git init
git add .
git commit -a -m "Initial import."
cd ..
</pre></p>

<p>Now let's create a repository in Gitosis for it.  You can do this step on any machine, it doesn't need to be the server -- <strong>just make sure you've added your private key from Step 4 with ssh-add</strong> first.</p>

<p><pre name="code" class="bash:nogutter">
git clone git@yourhost:gitosis-admin.git
</pre></p>

<p>Now open <strong>gitosis-admin/gitosis.conf</strong> in your favorite editor and add a group and make a new repository writable for our project.  Here's what mine looks like:</p>

<p><pre name="code" class="bash:nogutter">
[gitosis]</p>

<p>[group gitosis-admin]
writable = gitosis-admin
members = rboyd@plato</p>

<p>[group robot-dev]
writable = robot
members = rboyd@plato
</pre></p>

<p>Now commit that, and push -- your new repository should be ready.  Run this from the gitosis-admin directory:</p>

<p><pre name="code" class="bash:nogutter">
git commit -a -m "Adding robot repository."
git push
</pre></p>

<p>Now let's get back into our robot directory and push our repository to Gitosis.</p>

<p><pre name="code" class="bash:nogutter">
git remote add origin git@localhost:robot.git
git push origin master:refs/heads/master
cd ..
</pre></p>

<p><strong>Step 7: Install Cucumber</strong></p>

<p><pre name="code" class="bash:nogutter">
gem install webrat  # dependency for cucumber
git clone git://github.com/david/merb_cucumber.git
cd merb_cucumber/
rake install
</pre></p>

<p>Now we can get Cucumber setup and working in our Merb app:</p>

<p><pre name="code" class="bash:nogutter">
cd robot
merb-gen cucumber
</pre></p>

<p><strong>As anyone who's tried to take over the world before knows, automation is key</strong>.  The most important part of building an army of killer robots is to make sure that your robots know how to self-assemble new killer robots.  Otherwise you'll be bogged down building them all by yourself.  Let's spec it out.  Create a file <strong>features/replicate.feature</strong> in your robot directory.  Make it look like this:</p>

<p><pre name="code" class="bash:nogutter"></p>

<h1>replicate.feature</h1>

<p>Feature: Replicate
In order to take over the world
Robots should be able to</p>

<p>find parts and self-replicate</p>

<p>Scenario: Find parts
Given that there are parts available
And that the Robot needs parts
Then it should take any that it needs</p>

<p>Scenario: Self-replicate
Given that the Robot has all of the needed parts
Then it should be able to build a new Robot
</pre></p>

<p>You can run your Cucumber stories with the command <strong>rake features</strong>.  We don't have these steps implemented yet though, so let's create them in <strong>features/steps/robot_steps.rb</strong>:</p>

<p><pre name="code" class="ruby:nogutter">
require 'spec'</p>

<p>class Robot
def initialize
@backpack = []
end
attr_accessor :backpack</p>

<p>def take_from!(parts)
parts.each { |p| backpack &lt;&lt; p }
end</p>

<p>def needs?(parts)
true
end</p>

<p>def can_replicate?
true
end</p>

<p>def build!
backpack = []
return Robot.new
end
end</p>

<p>Before do
@robot = Robot.new
end</p>

<p>Given /^that there are parts available$/ do
@available_parts = []
@available_parts &lt;&lt; {:type =&gt; :leg}
@available_parts &lt;&lt; {:type =&gt; :leg}
@available_parts &lt;&lt; {:type =&gt; :brain}
@available_parts &lt;&lt; {:type =&gt; :chainsaw}
end</p>

<p>Given /^that the Robot needs parts$/ do
@robot.needs?(@available_parts).should be_true
end</p>

<p>Then /^it should take any that it needs$/ do
before = @robot.backpack.length
@robot.take_from!(@available_parts)
@robot.backpack.length.should be &gt; before
end</p>

<p>Given /^that the Robot has all of the needed parts$/ do
@robot.can_replicate?.should be_true
end</p>

<p>Then /^it should be able to build a new Robot$/ do
@new_robot = @robot.build!
@new_robot.class.name.should == "Robot"
end
</pre></p>

<p>Now when you run <strong>rake features</strong> you get the results you'd expect.  All green!  Good.  Now we'll want to commit our changes to the repository, but before we do, let's get Hudson setup to kick off our tests as soon as it gets our latest changes.  <strong>This is what continuous integration is all about.</strong></p>

<p><strong>Step 8: Wire everything up</strong></p>

<p>First we need to add the Git plugin to Hudson.  Fire up the browser again and aim it at http://<strong>yourhost</strong>/hudson/pluginManager/available -- then click the checkbox next to the <strong>Git Plugin</strong>.  Let's add the <strong>Rake Plugin</strong> while we're at it.  Then click the Install button at the bottom of the page.</p>

<p>Hudson tells us "Once the installation is completed, Hudson needs to be restarted for changes to take effect." so let's do that again:</p>

<p><pre name="code" class="bash:nogutter">
/etc/init.d/tomcat6 restart
/etc/init.d/apache2 restart
</pre></p>

<p>Hudson likes to tag revisions from Git with its build number.  But it needs a <strong>.gitconfig</strong> with user and email settings before git will allow this.  So let's drop this file in <strong>/srv/hudson/.gitconfig</strong>:</p>

<p><pre name="code" class="bash:nogutter">
[user]
name = Hudson
email = hudson@yourhost
</pre></p>

<p>Ensure that it's owned by the proper user:</p>

<p><pre name="code" class="bash:nogutter">
chown tomcat6.tomcat6 /srv/hudson/.gitconfig
</pre></p>

<p>Now let's enable security for Hudson.  Click <strong>Manage Hudson</strong> then <strong>Configure System</strong>.  For now, make it look like this:</p>

<p><a href="http://www.softwarebloat.com/wp-content/uploads/2008/11/enable_security_full_anonymous.png"><img class="alignnone size-full wp-image-79" title="enable Hudson security" src="http://www.softwarebloat.com/wp-content/uploads/2008/11/enable_security_full_anonymous.png" alt="enable Hudson security" width="450" height="215" /></a></p>

<p>Now you should be able to create new users by clicking the <strong>sign up</strong> link in the top-right corner.  Create two, one for yourself (I'll call mine admin) and one for Gitosis (gitosis) to use to trigger builds automatically upon updates to the repository.  Once these user accounts are created, login and head back to <strong>Configure System</strong> switch over to Project-based Matrix Authorization Strategy and remove all privileges for Anonymous (this is a good idea because Hudson comes with a Groovy script interpreter on by default which is a potential security vulnerability), and add all privileges for your admin account.  Your gitosis account can get away with only Read and Build permissions.  Here's how it looks:</p>

<p><a href="http://www.softwarebloat.com/wp-content/uploads/2008/11/hudson_matrix_based.png"><img class="alignnone size-full wp-image-82" title="Project-based Matrix Authorization Strategy" src="http://www.softwarebloat.com/wp-content/uploads/2008/11/hudson_matrix_based.png" alt="Project-based Matrix Authorization Strategy" width="449" height="275" /></a></p>

<p>Now we're ready to crate a <strong>New Job</strong>.  Name it robot and select <strong>Build a free-style software project</strong>, then click <strong>OK</strong>.</p>

<p>On the project configuration page you tell Hudson how to fetch and execute any build steps for the project.  We'll configure it to grab the robot.git repository from the local filesystem (bypassing gitosis altogether).  We'll also enable the checkbox for <strong>Trigger builds remotely</strong>.</p>

<p><a href="http://www.softwarebloat.com/wp-content/uploads/2008/11/new_job_scm.png"><img class="alignnone size-full wp-image-84" title="SCM Configuration for Robot Job" src="http://www.softwarebloat.com/wp-content/uploads/2008/11/new_job_scm.png" alt="SCM Configuration for Robot Job" width="450" height="337" /></a></p>

<p>We're almost done, now we just need to tell Hudson to kick off a <strong>rake features</strong> after grabbing updates.  Click the <strong>Add build step</strong> drop-down menu and select <strong>Invoke Rake</strong> and just type <strong>features</strong> into the <strong>Tasks</strong> input box.</p>

<p><a href="http://www.softwarebloat.com/wp-content/uploads/2008/11/invoke_rake.png"><img class="alignnone size-full wp-image-88" title="Invoke Rake Build Step" src="http://www.softwarebloat.com/wp-content/uploads/2008/11/invoke_rake.png" alt="Invoke Rake Build Step" width="450" height="123" /></a></p>

<p>Now let's set Gitosis up to trigger your build upon code checkin.  Add this line to <strong>/srv/git/repositories/robot.git/hooks/post-receive</strong>, replace <strong>pass</strong> and <strong>secret</strong> with whatever you used for the gitosis user password and the build trigger token:</p>

<p><pre name="code" class="bash:nogutter">
/usr/bin/curl -u gitosis:pass http://localhost/hudson/job/robot/build?token=secret
</pre></p>

<p>Then set file permissions on <strong>post-receive</strong> and <strong>post-update</strong>:</p>

<p><pre name="code" class="bash:nogutter">
chmod 755 /srv/git/repositories/robot.git/hooks/post-update
chmod 755 /srv/git/repositories/robot.git/hooks/post-receive
</pre></p>

<p>That's it.  Now Gitosis and Hudson should play nicely together to automatically kick off builds and run your tests whenever you add new code to your project.</p>

<p><strong>Step 9: Check in your code</strong></p>

<p>Back in our robot project directory, we still have our Cucumber test code that we haven't added yet.  Run <strong>git status</strong> to see these new files.  Let's commit our changes and push it to Gitosis and watch Hudson run the build:</p>

<p><pre name="code" class="bash:nogutter">
git add .
git commit -a -m "Adding tests."
git push
</pre></p>

<p>Now just sit back and watch the build progress on the job page (maybe check out the console output) and prepare for world domination!</p>

<p><a href="http://www.softwarebloat.com/wp-content/uploads/2008/11/build_success.png"><img class="alignnone size-full wp-image-93" title="Build Successful" src="http://www.softwarebloat.com/wp-content/uploads/2008/11/build_success.png" alt="Build Successful" width="450" height="86" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2008/11/19/continuous-integration-blueprints-how-to-build-an-army-of-killer-robots-with-hudson-and-cucumber/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Cream of the Crop</title>
		<link>http://www.softwarebloat.com/2008/11/15/cream-of-the-crop/</link>
		<comments>http://www.softwarebloat.com/2008/11/15/cream-of-the-crop/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 18:37:54 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[collins]]></category>
		<category><![CDATA[graham]]></category>
		<category><![CDATA[interviews]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[spolsky]]></category>

		<guid isPermaLink="false">http://softwarebloat.wordpress.com/?p=37</guid>
		<description><![CDATA[In a book called Good to Great, Jim Collins and his team of researchers built a list of 1,435 companies and identified the top 11 to determine what makes them tick.  One of the principles of effective businesses is that they manage to get &#8220;the right people on the bus&#8221;.  I believe this [...]]]></description>
			<content:encoded><![CDATA[<p>In a book called <a href="http://www.amazon.com/Good-Great-Companies-Leap-Others/dp/0066620996">Good to Great</a>, <a href="http://jimcollins.com/">Jim Collins</a> and his team of researchers built a list of 1,435 companies and identified the top 11 to determine what makes them tick.  One of the principles of effective businesses is that they manage to get &#8220;the right people on the bus&#8221;.  I believe this is especially true in the software industry.</p>

<p><a href="http://paulgraham.com/">Paul Graham</a> had this to say about the variation in productivity between commoon programmers and truely spectacular ones in his essay <a href="http://paulgraham.com/gh.html">Great Hackers</a>:
<strong>
&#8220;Productivity varies in any field, but there are few in which it varies so much.  The variation between programmers is so great that it becomes a difference in kind.&#8221;</strong></p>

<p>So when you&#8217;re hiring, how do you identify a great programmer?  <a href="http://joelonsoftware.com/">Joel Spolsky</a> has written an article <a href="http://www.joelonsoftware.com/articles/fog0000000073.html">The Guerilla Guide to Interviewing</a> and it is a definitive contribution on this topic.  The book <a href="http://www.amazon.com/Programming-Interviews-Exposed-Secrets-Programmer/dp/047012167X">Programming Interviews Exposed</a> is another fantastic resource.  You should definitely read these and apply their wisdom.</p>

<p>I recently fielded a <a href="http://stackoverflow.com/questions/239185/what-is-the-best-way-to-tell-an-excellent-programmer-in-a-job-interview">question</a> on <a href="http://stackoverflow.com/">stackoverflow</a> (a software development Q&amp;A site) which related to this topic, so I&#8217;ve decided to republish my answer to this blog.  Here is my interview outline to help you craft specific questions to fire at your candidates.  I&#8217;ve tried to list these topics in order of importance.</p>

<p><strong>
General Intelligence (brain teasers/logic puzzles)</strong></p>

<ul>
    <li><a href="http://www.braingle.com/brainteasers/7824/100-closed-lockers.html">Counting toggled lockers</a></li>
    <li><a href="http://puzzlepage.blogspot.com/2008/02/crossing-bridge.html">Crossing bridges</a></li>
    <li><a href="http://www.redhotpawn.com/board/showthread.php?threadid=24129">Weighing marbles</a></li>
    <li><a href="http://brainden.com/forum/index.php?s=69929cfdecc74efee37a45cb942067f7&amp;showtopic=4801&amp;st=0">Burning fuses</a></li>
</ul>

<p><strong>Computer Science Knowledge</strong></p>

<ul>
    <li><a href="http://en.wikipedia.org/wiki/Data_structure">Data structures</a> (<a href="http://en.wikipedia.org/wiki/Stack_(data_structure)">stacks</a>, <a href="http://en.wikipedia.org/wiki/Queue_(data_structure)">queues</a>, <a href="http://en.wikipedia.org/wiki/Linked_list">lists</a>, <a href="http://en.wikipedia.org/wiki/Tree_data_structure">trees</a>)</li>
    <li><a href="http://en.wikipedia.org/wiki/Algorithm">Algorithm knowledge</a> (<a href="http://en.wikipedia.org/wiki/Sorting_algorithm">sorting</a>, <a href="http://en.wikipedia.org/wiki/Search_algorithm">search</a>, <a href="http://en.wikipedia.org/wiki/Shortest_path_problem">shortest path</a>, <a href="http://en.wikipedia.org/wiki/Euclidean_algorithm">Euclidean algorithm</a>, <a href="http://en.wikipedia.org/wiki/Hamiltonian_path">Hamiltonian cycle</a>, <a href="http://en.wikipedia.org/wiki/Data_compression">data compression</a>)</li>
    <li><a href="http://en.wikipedia.org/wiki/Analysis_of_algorithms">Algorithm analysis</a></li>
    <li><a href="http://en.wikipedia.org/wiki/Recursive_algorithm">Recursion</a>/Tail Recursion versus Iterative solutions</li>
    <li><a href="http://en.wikipedia.org/wiki/Model_of_computation">Models of computation</a>/<a href="http://en.wikipedia.org/wiki/Finite_state_machine">Finite state machines</a></li>
    <li><a href="http://en.wikipedia.org/wiki/String_searching_algorithm">String matching</a>/<a href="http://en.wikipedia.org/wiki/Regular_expression">Regular expressions</a></li>
    <li><a href="http://en.wikipedia.org/wiki/Backus-Naur_form">Backus-Naur Form</a></li>
</ul>

<p><strong>Programming Exercises</strong></p>

<ul>
    <li><a href="http://en.wikipedia.org/wiki/Greatest_common_divisor">GCD</a>, <a href="http://en.wikipedia.org/wiki/Factorial">Factorial</a>, <a href="http://en.wikipedia.org/wiki/Fibonacci_number">Fibonacci</a>, <a href="http://en.wikipedia.org/wiki/Tower_of_Hanoi">Towers of Hanoi</a></li>
    <li>String and list reversal</li>
    <li>Determine if a singly-linked list has a loop (can you do it with only two pointers?)</li>
    <li>Find the bug</li>
</ul>

<p><strong>Tools, Technique and Methodology</strong></p>

<ul>
    <li><a href="http://en.wikipedia.org/wiki/Debug">Debugging</a></li>
    <li><a href="http://en.wikipedia.org/wiki/Revision_control">Version Control</a></li>
    <li><a href="http://en.wikipedia.org/wiki/Agile_software_development">Agile Software Development</a></li>
    <li><a href="http://en.wikipedia.org/wiki/Object-oriented_analysis_and_design">Object-oriented analysis and design</a> / <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language">UML</a></li>
    <li><a href="http://en.wikipedia.org/wiki/Software_design_pattern">Design Patterns</a></li>
    <li><a href="http://en.wikipedia.org/wiki/Code_coverage">Coverage analysis</a></li>
    <li><a href="http://en.wikipedia.org/wiki/Continuous_Integration">Continuous integration</a></li>
</ul>

<p><strong>Security</strong></p>

<ul>
    <li><a href="http://en.wikipedia.org/wiki/Buffer_overflow">Buffer</a>/<a href="http://en.wikipedia.org/wiki/Heap_overflow">Heap overflow</a></li>
    <li><a href="http://en.wikipedia.org/wiki/SQL_injection">SQL injection</a></li>
    <li><a href="http://en.wikipedia.org/wiki/Cross-site_scripting">Cross-site scripting attacks</a></li>
</ul>

<p><strong>Basic Mathematics</strong></p>

<ul>
    <li><a href="http://en.wikipedia.org/wiki/Numeral_system">Numeral systems</a> (convert from one base to another)</li>
    <li><a href="http://en.wikipedia.org/wiki/Probability_theory">Probability Theory</a></li>
    <li>Distance between two points on Cartesian plane (Pythagorean theorem)</li>
    <li>Square root (Heron of Alexandria, successive approximation)</li>
</ul>

<p><strong><a href="http://en.wikipedia.org/wiki/Cryptography">Cryptography</a></strong></p>

<ul>
    <li>Public key cryptography</li>
    <li>Symmetric-key cryptography</li>
    <li>Hash functions</li>
    <li>Cryptographic protocols (secret sharing, zero-knowledge proofs)</li>
</ul>

<p><strong><a href="http://en.wikipedia.org/wiki/Discrete_mathematics">Discrete Mathematics</a></strong></p>

<ul>
    <li>Logic</li>
    <li>Set theory</li>
    <li>Graph theory</li>
    <li>Information theory</li>
    <li>Combinatorics</li>
    <li>Proofs (like existence of irrational numbers, infinite primes)</li>
</ul>

<p>Anyone has conducted a significant amount of interviews in this industry knows that the majority of potential recruits won&#8217;t last through the first 30 minutes of the interview, so much of this list will be unnecessary most of the time.  Before you dismiss my more complex topics as overkill, just <strong>keep in mind how expensive and emotionally taxing it can be to recognize that you made a poor hiring decision and to later correct it</strong>.  Good luck in building your team of awesome developers!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2008/11/15/cream-of-the-crop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Virtues of Version Control</title>
		<link>http://www.softwarebloat.com/2008/11/13/the-virtues-of-version-control/</link>
		<comments>http://www.softwarebloat.com/2008/11/13/the-virtues-of-version-control/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 20:08:10 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[continuousintegration]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[redmine]]></category>
		<category><![CDATA[revisioncontrol]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[versioncontrol]]></category>
		<category><![CDATA[versioning]]></category>

		<guid isPermaLink="false">http://softwarebloat.wordpress.com/?p=25</guid>
		<description><![CDATA[&#8220;History is the version of past events that people have decided to agree upon.&#8221; &#8212; Napolean Bonaparte

It&#8217;s always a good idea to maintain a network of colleagues that you can call on for advice when you need it.  Recently a friend and I were discussing our respective software projects, and I started asking him [...]]]></description>
			<content:encoded><![CDATA[<p><em>&#8220;History is the version of past events that people have decided to agree upon.&#8221; &#8212; Napolean Bonaparte</em></p>

<p>It&#8217;s always a good idea to maintain a network of colleagues that you can call on for advice when you need it.  Recently a friend and I were discussing our respective software projects, and I started asking him questions about his methodology.  I asked if he was making use of any continuous integration systems, like <a href="https://hudson.dev.java.net/">Hudson</a> or <a href="http://cruisecontrolrb.thoughtworks.com/">CruiseControl.rb</a>.  He wasn&#8217;t.  I asked him if he had used any tools for coverage analysis, like <a href="http://www.ncover.com/">rcov</a> or <a href="http://ncover.org/">NCover</a>.  Neither was he doing any similarity analysis (<a href="http://www.redhillconsulting.com.au/products/simian/">Simian</a>) to identify code violating the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> principle.  I asked him what he was using for <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a>/<a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">BDD</a> (check out <a href="http://github.com/aslakhellesoy/cucumber/wikis">Cucumber</a>), and he replied that he wasn&#8217;t doing any.</p>

<p>Many software teams I&#8217;ve encountered (or even been a part of) have ignored these tools.  This isn&#8217;t terribly uncommon.  Finally I ask him, &#8220;<strong>are you even doing any <a href="http://en.wikipedia.org/wiki/Revision_control">version control</a></strong>?&#8221;.  He was not.</p>

<p>I found this to be very surprising, because my buddy has been working on his project for the better part of a year.  He hopes to productize his software and take it to market.  It&#8217;s apparently a fairly mature code base, and yet it is not under the safe watch of any versioning system.  It&#8217;s shocking to me, because here we are in the year 2008.  <strong>Today&#8217;s software engineering tools are more powerful than ever before, but to a large extent they go unused.  Why is this?</strong></p>

<p>With regards to versioning, my friend has several options.  Traditionalists are still using <a href="http://www.nongnu.org/cvs/">CVS</a>, and <a href="http://subversion.tigris.org/">Subversion</a> is still quite popular.  Microsoft has its line in the water with <a href="http://msdn.microsoft.com/ssafe/">SourceSafe</a>, which I think has been integrated into TeamSystem, but I&#8217;m not quite sure.  Even some of the strongest open source advocates I know readily plop down cash for <a href="http://www.perforce.com/">Perforce</a>, they say it&#8217;s THAT good.  There&#8217;s new entrants to the arena all of the time, like <a href="http://www.ericsink.com/">Eric Sink</a>&#8217;s <a href="http://www.sourcegear.com/">SourceGear</a>.  Linus Torvalds uses <a href="http://git.or.cz/">git</a> to help manage the development of the Linux kernel.</p>

<p>My buddy&#8217;s reason for not using any of them? <strong> &#8220;I&#8217;m the only person working on the code.  Why would I need to version it?&#8221;</strong></p>

<p>I believe this is the most common reason for not using a versioning system &#8212; people just don&#8217;t know when the project is established enough to merit using one.  Many less experienced developers feel that the right time to start using version control is when there are multiple developers touching the codebase.  While this would certainly be a good reason (and<strong> I can&#8217;t imagine many successful teams of developers not using versioning</strong>), it&#8217;s flawed reasoning that the lone coder working in isolation doesn&#8217;t benefit from the virtues of version control.  <strong>My take on it is that you should be using version control as soon as you have code that you care about enough that you would be disappointed to lose it</strong>.  That&#8217;s when it&#8217;s important enough to version it.</p>

<p>All of this of course inspired me to climb up on my soapbox and preach about the many reasons for versioning your software.  So here are my <strong>Top 10 reasons for using a version control system</strong>:</p>

<ol>
    <li>Never again suffer from the confusion of juggling multiple versions of your codebase by hand.</li>
    <li>Provides a single source for backups.</li>
    <li>Multiple developers easily work against the same code base.</li>
    <li>Branches are easily managed with version control.  Sometimes you want to experiment and take the project in a whole new direction.</li>
    <li>Commits can reference ticket numbers or bug ids so that developers can easily answer the question &#8220;when did we fix that bug?&#8221;.</li>
    <li>Easily diff new versions against old ones to pinpoint changes.</li>
    <li>Easily integrate with a web tool like <a href="http://www.redmine.org/">Redmine</a> to provide project statistics at a glance.</li>
    <li>Plays a key role in continuous integration systems.</li>
    <li>No real software engineer or manager will take your project seriously unless it&#8217;s under version control.</li>
    <li>Develop with impunity.  With version control you&#8217;re like a trapeze artist flying worry-free over a safety net.</li>
 

For these reasons, I believe that just after the compiler/interpreter and debugger, <strong>a versioning system is the most useful weapon in the software engineer&#8217;s arsenal</strong>.  If your project isn&#8217;t under version control yet, what are you waiting for?  Here&#8217;s a nice <a href="http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html">tutorial</a> and a <a href="http://git.or.cz/gitwiki/GitCheatSheet">cheat sheet</a> for git to help you get started.  Once you&#8217;re up and running, you might want to check out <a href="http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way">Gitosis</a> (do it yourself) or <a href="http://github.com/">github</a> (managed hosting) to share your repository with the world.</ol>

<p></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2008/11/13/the-virtues-of-version-control/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Book Report: Tribes</title>
		<link>http://www.softwarebloat.com/2008/11/12/book-report-a-tribes-thing/</link>
		<comments>http://www.softwarebloat.com/2008/11/12/book-report-a-tribes-thing/#comments</comments>
		<pubDate>Wed, 12 Nov 2008 17:39:35 +0000</pubDate>
		<dc:creator>rboyd</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[bookreports]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[communities]]></category>
		<category><![CDATA[socialmedia]]></category>
		<category><![CDATA[socialweb]]></category>
		<category><![CDATA[tribes]]></category>

		<guid isPermaLink="false">http://softwarebloat.wordpress.com/?p=22</guid>
		<description><![CDATA[I recently finished reading Seth Godin&#8217;s Tribes.  It&#8217;s a great little book describing the effect that the internet and social media has had on empowering the individual.  We&#8217;ve seen this effect in business, technology, and entertainment.  It is now extremely easy for one person with a good idea to get it front [...]]]></description>
			<content:encoded><![CDATA[<p>I recently finished reading Seth Godin&#8217;s <a href="http://www.amazon.com/Tribes-We-Need-You-Lead/dp/1591842336">Tribes</a>.  It&#8217;s a great little book describing the effect that the internet and social media has had on empowering the individual.  We&#8217;ve seen this effect in business, technology, and entertainment.  It is now extremely easy for one person with a good idea to get it front of the community.  To get it the attention that it deserves.</p>

<div align="center">
<img class="size-medium wp-image-23" title="tribes_01" src="http://www.softwarebloat.com/wp-content/uploads/2008/11/tribes_01-210x300.jpg" alt="Tribes Book Cover" width="210" height="300" />
</div>

<p>This book really got me thinking.  What tribes do I belong to?  We&#8217;ve heard it said <strong>&#8220;Do what you love, and you&#8217;ll never work a day in your life&#8221;</strong> and <strong>&#8220;Follow your bliss&#8221;</strong>.  I love building elegant systems &#8212; especially software.  I want to hear from you if you share this passion.  I want to trade ideas with you about the best way to do that.  That&#8217;s our tribe.</p>

<p>Over the course of maintaining this blog, I expect most of my posts to relate to the following 4 assertions:</p>

<ul>
    <li><strong>Good software makes users lives better.</strong></li>
    <li><strong>Building good software is hard but it can be easier.</strong></li>
    <li><strong>Happy developers build good software.</strong></li>
    <li><strong>Happy developers use powerful tools.</strong></li>
</ul>

<p>What is your passion?  What is your tribe?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.softwarebloat.com/2008/11/12/book-report-a-tribes-thing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
