<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Henrik Warne&#039;s blog</title>
	<atom:link href="http://henrikwarne.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://henrikwarne.com</link>
	<description>Thoughts on programming...</description>
	<lastBuildDate>Thu, 16 May 2013 18:14:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='henrikwarne.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Henrik Warne&#039;s blog</title>
		<link>http://henrikwarne.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://henrikwarne.com/osd.xml" title="Henrik Warne&#039;s blog" />
	<atom:link rel='hub' href='http://henrikwarne.com/?pushpress=hub'/>
		<item>
		<title>Great Programmers Write Debuggable Code</title>
		<link>http://henrikwarne.com/2013/05/05/great-programmers-write-debuggable-code/</link>
		<comments>http://henrikwarne.com/2013/05/05/great-programmers-write-debuggable-code/#comments</comments>
		<pubDate>Sun, 05 May 2013 19:32:17 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[trouble-shooting]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=763</guid>
		<description><![CDATA[All programs need some form of logging built in to them, so we can observe what it is doing. This is especially important when things go wrong. One of the differences between a great programmer and a bad programmer is &#8230; <a href="http://henrikwarne.com/2013/05/05/great-programmers-write-debuggable-code/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=763&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>All programs need some form of logging built in to them, so we can observe what it is doing. This is especially important when things go wrong. One of the differences between a great programmer and a bad programmer is that a great programmer adds logging and tools that make it easy to debug the program when things fail.</p>
<p>When the program works as expected, there is often no difference in the quality of the logging. However, as soon as the program fails, or you get the wrong result, you can almost immediately tell the good programmers from the bad.<span id="more-763"></span></p>
<h3>Example 1: &#8220;Let&#8217;s make a debug version&#8221;</h3>
<p>For example, a tester came to me with a call case that didn&#8217;t work. We looked at the logs, and saw that the problem seemed to be in a neighboring module. A call to the other module to get a list of values simply returned null. When we enabled logging in the neighboring module and re-ran the test case, there was no more information available. No clues to why null was returned &#8211; did we supply the wrong arguments, did some external system fail, was there an error in the neighboring module, or what?</p>
<p>When asking the developer responsible for the code, the answer we got was: &#8220;Oh, then we have to make a debug version to see what happens&#8221;. Fail! It must be possible to get some sense of where the problem is just from the logs. If this had been in a production system, adding a debug version would have been a lot of work. The code needs to include enough information in the log statements so you at least have some idea of why it fails.</p>
<h3>Example 2: Show Me How We Got Here</h3>
<p>One of our products at work finds the cheapest route for the delivery of SMS:s (text messages) to mobile phones. Depending on the current location of the phone, and the operator the destination subscriber belongs to, there are many possible routes to choose from, each with a given cost and other characteristics.  In addition, there can be exceptions that forbid some routes, and promote other routes. There are typically many thousands of routes defined. <span style="color:#444444;line-height:1.7;">The system finds the cheapest route in each case, given the constraints, and delivers the SMS.</span></p>
<p>Now, suppose a certain SMS gets delivered using route A, but we believe it should have used route B. Why was route A chosen? If there is no logging information (other than &#8220;route A was chosen&#8221;), we are left with hundreds of possible routes, their costs, the exceptions, and a complex algorithm. Good luck figuring out why A was chosen.</p>
<p>In our implementation, the log includes all potential routes, in cost order. As routes are eliminated due to different restrictions, the eliminated routes are listed in the log, together with the reason for elimination. With all the information on the input to the algorithm, as well as the steps taken, listed in the log, it is fairly easy to see why a certain route was picked.</p>
<h3>Why Not?</h3>
<p>So, why don&#8217;t all programmers write debuggable code? I can think of three reasons:</p>
<ol>
<li><span style="line-height:14px;">You have to be humble enough to realize that there will be cases when your code doesn&#8217;t work as expected. I believe many programmers have a hard time with this.</span></li>
<li>If you test your own code thoroughly, you will make sure it works (or fails gracefully) in a lot of different scenarios. For each scenario, it is natural to add logging. If you don&#8217;t test those cases, you are less likely to add logging there.</li>
<li>Many programmers don&#8217;t trouble-shoot their own code in production systems often enough. If you have a problem in a live system, and the logs tell you nothing about why there is a problem, you have a strong incentive to add logging that will actually help you the next time you are in a similar situation.</li>
</ol>
<h3>Is <em>Your</em> Code Debuggable?</h3>
<p>There are of course cases where even good logging messages don&#8217;t give you the full story on why something fails. You may still have to make that debug version. But your regular logging should at the very least give you some hints on what the problem might be<span style="color:#444444;line-height:1.7;">.</span></p>
<p>So, how well have you prepared? When your code fails, will the logs tell you what&#8217;s going on?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/763/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/763/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=763&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2013/05/05/great-programmers-write-debuggable-code/feed/</wfw:commentRss>
		<slash:comments>44</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>
	</item>
		<item>
		<title>SET Card Game Variation &#8211; Complementary Pairs</title>
		<link>http://henrikwarne.com/2013/04/07/set-card-game-variation-complementary-pairs/</link>
		<comments>http://henrikwarne.com/2013/04/07/set-card-game-variation-complementary-pairs/#comments</comments>
		<pubDate>Sun, 07 Apr 2013 14:15:40 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[probabilities]]></category>
		<category><![CDATA[SET game]]></category>
		<category><![CDATA[simulation]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=737</guid>
		<description><![CDATA[I recently got an e-mail from Michael Sherman, a teacher in New York. He had developed a variation of the card game Set called Complementary Pairs. This is how he described it: &#8220;We have Set competitions at the school where &#8230; <a href="http://henrikwarne.com/2013/04/07/set-card-game-variation-complementary-pairs/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=737&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I recently got an e-mail from Michael Sherman, a teacher in New York. He had developed a variation of the <a title="Set card game" href="http://en.wikipedia.org/wiki/Set_(game)">card game Set</a> called <em>Complementary Pairs</em>. This is how he described it:</p>
<p><em>&#8220;We have Set competitions at the school where I teach, both as individual time trials and as head-to-head matches. When many students at my school became capable of finding sets very quickly, I developed what I called C.P. Set (Complementary Pairs) to slow them down a bit and reduce the number of simultaneous calls in the head-to-head matches.  The idea is to find two pairs of cards that both require the same 3rd card to complete a Set. The completing card does not need to be on the board; only the four cards forming the complementary pairs are picked up.&#8221;<span id="more-737"></span></em></p>
<p>The picture below shows two pairs that have the same third card. The two cards to the left (pair 1) form a set with the top card. Likewise, the two cards to the right (pair 2) also form a set with the top card. Therefore, pair 1 and pair 2 are complementary.</p>
<p style="text-align:center;"><a href="http://henrikwarne1.files.wordpress.com/2013/04/dscf4598.jpg"><img class="aligncenter  wp-image-742" alt="DSCF4598" src="http://henrikwarne1.files.wordpress.com/2013/04/dscf4598-e1365339018719.jpg?w=480&#038;h=360" width="480" height="360" /></a></p>
<p>At Michael&#8217;s school, they started out playing Complementary Pairs Set with 12 cards on the table, but soon realized that they could also play with only 9 cards on the table. So if the four cards in the picture above (pair 1 and pair 2) were present anywhere among the 9 cards on the table, they could be removed as complementary pairs, and be replaced by four new ones. Note that the third card (the top card in the picture) doesn&#8217;t have to be present on the table.</p>
<p>Michael had read my first post on <a title="SET Probabilities Revisited" href="http://henrikwarne.com/2011/09/30/set-probabilities-revisited/">Set probabilities</a>, and was wondering what the chances are of not finding any complementary pairs when playing with 9 cards on the table. He asked if I could find the answer by modifying my simulator. With 9 cards on the table, there are 36 different possible pairs. For each pair, there is exactly one card that can form a set with it. So the question is: how often does it happen that all the 36 pairs require a different third card (of the possible 81 cards) to form a set?</p>
<p>It turns out that it is very rare that there are no complementary pairs present among 9 cards. When I simulated playing one million games, the odds of there not being any complementary pairs were around 12,000 to 1. Put another way, it only happened around 80 times out of a million. The odds were constant per round of play, which is not surprising, given that the third card doesn&#8217;t have to be present on the table. The Java program I used is available at <a title="SetComplementaryPairs" href="https://bitbucket.org/henrik_w/setcomplementarypairs/src/aa8e8fbb52e5c8eff97d00e11d148372f599ca40/SetGameCP.java">BitBucket</a>.</p>
<p>After Michael came up with the idea of complementary pairs, he found out that the same variation of Set had already been proposed, but under the name of <a title="Super Set" href="http://magliery.com/Set/SuperSet.html">Super Set</a>. However, I think complementary pairs is a more descriptive name, so I&#8217;ll stick to that.</p>
<p>If you haven&#8217;t yet tried Complementary Pairs Set, give it a try. And if you can&#8217;t find any complementary pairs, look harder &#8211; the odds of there not being any are 12000:1. Happy playing!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/737/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/737/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=737&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2013/04/07/set-card-game-variation-complementary-pairs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>

		<media:content url="http://henrikwarne1.files.wordpress.com/2013/04/dscf4598-e1365339018719.jpg?w=300" medium="image">
			<media:title type="html">DSCF4598</media:title>
		</media:content>
	</item>
		<item>
		<title>Programmer Productivity &#8211; Interruptions, Meetings and Working Remotely</title>
		<link>http://henrikwarne.com/2013/04/02/programmer-productivity-interruptions-meetings-and-working-remotely/</link>
		<comments>http://henrikwarne.com/2013/04/02/programmer-productivity-interruptions-meetings-and-working-remotely/#comments</comments>
		<pubDate>Tue, 02 Apr 2013 05:42:58 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[face to face]]></category>
		<category><![CDATA[interruption]]></category>
		<category><![CDATA[meeting]]></category>
		<category><![CDATA[office]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=702</guid>
		<description><![CDATA[In my previous post on what programmers want, I ranked working from home low on the list. Several commenters value working from home higher, and K (not his real name) added a link to a great TED talk given by &#8230; <a href="http://henrikwarne.com/2013/04/02/programmer-productivity-interruptions-meetings-and-working-remotely/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=702&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In my previous post on <a title="What Do Programmers Want?" href="http://henrikwarne.com/2013/03/26/what-do-programmers-want/">what programmers want</a>, I ranked working from home low on the list. Several commenters value working from home higher, and <a title="K" href="http://sv.gravatar.com/kirkbeard">K</a> (not his real name) added a link to a great TED talk given by <a title="Jason Fried on Twitter" href="https://twitter.com/jasonfried">Jason Fried</a> (of <a title="37signals" href="http://37signals.com/">37signals</a>) on <a title="Why Work Doesn't Happen At Work" href="http://www.ted.com/talks/jason_fried_why_work_doesn_t_happen_at_work.html">why it is hard to get any work done at work</a>. Jason starts with the observation that programmers need long stretches of uninterrupted time in order to get stuff done, and goes on to recommend avoiding meetings, and minimizing interruptions by using chat and e-mail instead of direct communication. While I agree with the meetings part, I think there is more to consider regarding interruptions. I also value face to face interactions more than he does.<span id="more-702"></span></p>
<h3>office Interactions</h3>
<p>The picture Jason paints of working at an office makes you wonder why we work at an office at all. Constant interruptions from bosses, colleagues and meetings make it hard to get anything substantial done. Why not have everybody work remotely all the time instead? For me, the main reason is that software development requires a lot of collaboration. Brain-storming, discussing, and refining ideas with other developers usually yield solutions much better than what you can come up with on your own. Furthermore, these kinds of interactions are much more effective in person, with a whiteboard handy (pretty much all discussions benefit from a few quick drawings). Remote collaboration tools try their best to recreate the face to face dynamics, but it is never the same as being in the same room with someone.</p>
<p>Jason recommends switching from active communication (face to face or phone call) to passive communication (e-mail or chat), to avoid interrupting people. This is good advice for avoiding interruptions. But after the initial request, the sooner you switch to talking, the better. Written communication works well for simple questions and answers. However, talking to someone is at least an order of magnitude more efficient when there is even a little bit of uncertainty or ambiguity . For example, if I get an e-mail with the question &#8220;Do we support feature XXX?&#8221;, most of the time the answer is not a simple yes or no. Perhaps it depends on which other features the customer has. Or we may have just developed the more capable feature YYY that they could use instead. Writing all this down takes time and effort &#8211; talking (in person or on the phone) lets you have the back and forth immediately, instead of spreading it out in writing.</p>
<h3>Good Interruptions</h3>
<p>While I totally agree with Jason that programmers need long stretches of uninterrupted time in order to be productive, there are cases when interruptions should be tolerated. If someone is working on a problem (a tester, a support engineer, or another developer), and has a question I know the answer to off the top of my head, I&#8217;m fine with being interrupted. Sure, my productivity takes a hit, but we should optimize for the company&#8217;s productivity, not only my productivity. If one (or several) other people in the company would be stalled, it&#8217;s better to ask me and get the answer in one minute, than to dig around for an answer in the code or in the documentation.</p>
<p>Another case where interruptions are acceptable is when there is a trouble report. In my team at work, we have virtually no trouble report back-log. We try to finish off trouble reports as soon as we get them. Getting back to the customer right away has several benefits: the problem is fresh in their minds, it&#8217;s easy to get additional information if needed, and the customer sees that we care about fixing the problem quickly.  The quick turn-around time means that no back-log of unanswered trouble reports builds up. It is also easy to stay on top of what the outstanding problems are at all times, since there are so few of them.</p>
<h3>Meetings &#8211; Inefficient use of time</h3>
<p>When it comes to meetings, I agree with Jason: the fewer the better. Having a meeting is often very poor use of time. When I worked at <a title="Ericsson" href="http://www.ericsson.com/">Ericsson</a>, we had a weekly status meeting for the whole R&amp;D department on Tuesdays at 10 o&#8217;clock. So at 9.30, you don&#8217;t feel like starting anything new, since you know you are going to be interrupted soon. Knowing that you will have to attend a meeting soon causes you to get less done. An unplanned interruption is much better &#8211; at least you don&#8217;t know about it beforehand. Another problem with those status meetings was that pretty much all information given could just as easily have been sent out in an e-mail.</p>
<p>Another reason meetings are inefficient is that often the people there aren&#8217;t needed for the whole meeting, so some of their time is wasted. At <a title="Symsoft" href="http://symsoft.com/">Symsoft</a>, I have very few meetings. Instead of calling a meeting, I&#8217;ll walk over to the people involved (all developers are a maximum of 5 offices away) and discuss the issue. No meeting, and only the people directly involved are interrupted. Way better than the overhead of a meeting.</p>
<h3>It&#8217;s not that hard</h3>
<p>The work place Jason describes in his talk is pretty bleak. But it doesn&#8217;t have to be that way. I have never worked for a manager that came around frequently for &#8220;status updates&#8221;, probably because they have all been programmers too, and know not to interrupt. I hardly have any meetings at all at Symsoft, and it was the same when I worked at <a title="Tilgin" href="http://www.tilgin.com/">Tilgin</a>. Creating a good environment for software developers isn&#8217;t that hard. I do get interrupted, but almost always for the right reasons. <em>I</em> become less productive, but <em>we</em> become more productive. And I still have plenty of quiet, uninterrupted time for developing new features and fixing bugs. How about you?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/702/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/702/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=702&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2013/04/02/programmer-productivity-interruptions-meetings-and-working-remotely/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>
	</item>
		<item>
		<title>What Do Programmers Want?</title>
		<link>http://henrikwarne.com/2013/03/26/what-do-programmers-want/</link>
		<comments>http://henrikwarne.com/2013/03/26/what-do-programmers-want/#comments</comments>
		<pubDate>Tue, 26 Mar 2013 08:40:30 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[hiring]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[programmer]]></category>
		<category><![CDATA[programming job]]></category>
		<category><![CDATA[recruiting]]></category>
		<category><![CDATA[working]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=672</guid>
		<description><![CDATA[I got an e-mail last week from three students at Halmstad University doing a three month project on what programmers want in a job, and how companies can attract talented programmers. Here are my answers to their questions, in order &#8230; <a href="http://henrikwarne.com/2013/03/26/what-do-programmers-want/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=672&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I got an e-mail last week from three students at <a title="Halmstad University" href="http://www.hh.se/english.5_en.html">Halmstad University</a> doing a three month project on what programmers want in a job, and how companies can attract talented programmers. Here are my answers to their questions, in order of importance. Obviously people have different preferences, so it would be interesting to hear what items you agree and disagree with, how you would rank them, and what you think is missing.<span id="more-672"></span></p>
<p><strong>The product is software.</strong> I like the programs I work on to be the main business of the company. This rules out working in an IT-department, since their job only supports the real business (whatever it is) indirectly. I also like to work on the central parts of the system &#8211; the more important it is, the better. If my parts stop working, it should immediately become an emergency issue. Finally, I don&#8217;t want to merely configure, adapt and glue together software from other companies &#8211; I want to write significant chunks of functionality myself.</p>
<p><strong>Great colleagues.</strong> It is very stimulating to work with smart programmers who are passionate about software development. Time and again I see how discussing a problem or a design with a colleague leads to a solution that is better than either of us would have come up with by ourselves. Not only does it lead to better code, the process itself is also very enjoyable.</p>
<p>How do you know if someone is a good programmer? A very good sign is if they keep learning and improving their skills, for example by reading books and blogs, taking courses, and going to conferences. It is not a necessary condition though; I&#8217;ve worked with plenty of really great developers that don&#8217;t. Finally, good developers tend to attract other good developers, because of the reasons above. The fact that a company has many great developers makes it easier to recruit more.</p>
<p><strong style="line-height:1.7;">Challenging problems.</strong><span style="color:#444444;line-height:1.7;"> Programmers like solving problems with code. There should be at least  some aspect of the product that requires clever solutions, be it requirements on low latency, many concurrent requests, or limited hardware resources. However, a lot of productions software consists of regular code without any particularly difficult parts. So you should not expect to only work on &#8220;hard problems&#8221; and shun everything else. Besides, it is a big challenge to organize even the boring code in a way that makes it easy to understand and maintain.</span></p>
<p><strong>Cool technology.</strong> This is mainly about using interesting programming languages (for example Clojure, Erlang or Go), but also includes frameworks and applications (for example Hadoop or Cassandra). This is one area where a company may have a problem. If their application is written in a certain language (say C++), it won&#8217;t change. So if you want to change to using some new language, you pretty much have to change jobs. For example, if you want to work with Erlang in Stockholm, you could try <a title="Klarna" href="https://klarna.com/jobs">Klarna</a> or <a title="Campanja" href="http://www.campanja.com/join-us/">Campanja</a>.</p>
<p><strong>Users.</strong> One of the <a title="Why I Love Coding" href="http://henrikwarne.com/2012/06/02/why-i-love-coding/">joys of coding</a> is making something that is useful to others. Making something that nobody uses is boring. Having users (the more the better) focuses the development effort and gives valuable feedback. The only exception would be a start-up, but then the overriding priority must be to get users as soon as possible.</p>
<p><strong>Good salary.</strong> Companies that have a lot of good developers know the value of great people. Since the variation between great and average programmers is big, it makes economic sense to pay for quality developers &#8211; the variation in productivity is much greater than the variation in salary. On the flip side, companies that don&#8217;t pay their programmers well tend to be the companies that view programmers as interchangeable &#8220;resources&#8221;. Those are the companies you want to avoid for other reasons as well, not just for the low salary.</p>
<p><strong>Good tools.</strong> This is almost self-evident. Having a fast computer and several monitors speeds up development &#8211; who&#8217;s against that? (OK, pointy-haired bosses that only see the cost, not the benefit, would be against).</p>
<p><strong>40 hours a week.</strong> If you constantly have to work overtime to ship, something is wrong in the organization. Besides, working long hours <a title="Bring back the 40-hour work week" href="http://www.salon.com/2012/03/14/bring_back_the_40_hour_work_week/">don&#8217;t equate with being productive</a>.</p>
<p><strong>Minimal bureaucracy.</strong> For the development process, this is more or less fixed with agile development methodologies, which seem almost universally adopted. General administrative overload is mostly a problem at larger companies in my experience.</p>
<p><strong>Working from home.</strong> It&#8217;s handy to be able to work from home sometimes, but it is not high on my list. I like being at the office and interacting with people. I&#8217;ve worked with a remote office using video conferencing, chat and e-mail, but it didn&#8217;t come close to the kind of productivity you get from being co-located.</p>
<p><strong>Short commute.</strong> Obviously hard to influence, but not spending hours each day in traffic is really great.</p>
<h3>Comments</h3>
<p>If you are a consultant, some things on the list change. I&#8217;ve always liked working for product companies, mostly because I prefer to really get to know a system deeply and seeing it evolve over time. So I don&#8217;t have any first-hand knowledge of working as a consultant, but my take is this. As a consultant, it is much easier to get exposed to cool new technology, since you have a chance to work with many different clients. However, even if you have great colleagues, you probably won&#8217;t work with them day to day, since you may be with different customers.</p>
<p>So this is the list, in order of importance, of what I look for in a company. In real life there are always some compromises, but the higher up something is on the list, the less willing I am to compromise on it. What are your priorities?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/672/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/672/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=672&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2013/03/26/what-do-programmers-want/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>
	</item>
		<item>
		<title>Coursera course review: Algorithms: Design and Analysis, Part 2</title>
		<link>http://henrikwarne.com/2013/02/18/coursera-algorithms-course-part2/</link>
		<comments>http://henrikwarne.com/2013/02/18/coursera-algorithms-course-part2/#comments</comments>
		<pubDate>Mon, 18 Feb 2013 21:01:51 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[coursera]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[on-line course]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=623</guid>
		<description><![CDATA[I recently finished the Coursera course Algorithms: Design and Analysis, Part 2 by Professor Tim Roughgarden of Stanford. I&#8217;ve already reviewed part 1, and here are my thoughts on the second part. The main theme of part 1 was the divide &#8230; <a href="http://henrikwarne.com/2013/02/18/coursera-algorithms-course-part2/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=623&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I recently finished the Coursera course <a title="Algorithms: Design and Analysis, Part 2" href="https://www.coursera.org/course/algo2">Algorithms: Design and Analysis, Part 2</a> by Professor Tim Roughgarden of Stanford. I&#8217;ve <a title="Coursera course review: Design and Analysis of Algorithms I" href="http://henrikwarne.com/2012/05/08/coursera-algorithms-course/">already reviewed part 1</a>, and here are my thoughts on the second part.</p>
<p><span style="color:#444444;line-height:1.7;">The main theme of part 1 was the divide and conquer paradigm. In the second part the main themes were greedy algorithms, dynamic programming and NP-Complete problems. The lectures were excellent, with clear and easy to follow algorithm development and proofs. At six weeks, it was one week longer than part 1, and I found it quite a bit harder than part 1. Here&#8217;s more on each part.<span id="more-623"></span></span></p>
<h3>Greedy Algorithms</h3>
<p>In the greedy paradigm, you iteratively make the best possible choice, and hope that in the end you have an optimal solution. Usually the algorithms are easy to come up with, and easy to analyze, but it is equally easy to come up with an incorrect algorithm. The greedy algorithms covered were:</p>
<ul>
<li><span style="color:#444444;line-height:1.7;">Job scheduling</span></li>
<li><span style="color:#444444;line-height:1.7;">Minimum spanning tree </span></li>
<li>Clustering</li>
<li>Huffman coding</li>
</ul>
<p>For job scheduling, a number of jobs, each with a weight and duration, are to be ordered so that the weighted sum of the completion times is as small as possible. The first programming assignment dealt with job scheduling. 10,000 jobs were to be scheduled in two different ways, and the answers were the sums of the completion times. Straight-forward, and the easiest of the programming assignments.</p>
<p>A minimum spanning tree (MST) connects all the nodes of a graph together as cheaply as possible. Two algorithms were covered: Prim&#8217;s, where you start with an arbitrary node, and expand with the cheapest available edge, and Kruskal&#8217;s, where you sort the edges in cost order, and keep using the cheapest ones (while avoiding cycles) until the minimum spanning tree is complete. For Kruskal&#8217;s algorithm, the Union Find data structure was introduced. It is needed to be able to quickly determine if a cycle would be created. It&#8217;s analogous to how Dijkstra&#8217;s shortest path algorithm uses a heap. I hadn&#8217;t seen the Union Find data structure before, but it is quite neat &#8211; both simple and easy to implement.</p>
<p>In clustering, the objective is to collect &#8220;related&#8221; nodes of a graph together in groups. This is a special case of Kruskal&#8217;s algorithm, but you stop before the clusters are merged into one big group. There were programming assignments to calculate the cost of the MST of a 500 nodes graph, and to calculate the maximum spacing of a 4-clustering of another graph. Both were straight-forward.</p>
<p>Huffman coding is a way of assigning binary code words to symbols of an alphabet, considering the probability of each symbol occurring, so that the resulting encoding is as short as possible. I learnt about Huffman coding when I went to university, and I still remember the idea, so I skipped this part.</p>
<h3>Dynamic Programming</h3>
<p>This was the most interesting part of the course for me. I had heard about dynamic programming before, but I had never really looked into it. If you can express the optimal solution in terms of the solution to smaller sub-problems, then dynamic programming may be suitable. The algorithms covered were:</p>
<ul>
<li><span style="color:#444444;line-height:1.7;">Independent set of maximum weight</span></li>
<li>Knapsack problem</li>
<li>Sequence alignment</li>
<li>Optimal binary search trees</li>
<li>Bellman-Ford single-source shortest path</li>
<li>Floyd-Warshall all pairs shortest path</li>
<li>Johnson&#8217;s all pairs shortest path</li>
</ul>
<p>The independent set problem was used to illustrate how dynamic programming works. Given a path of nodes with non-negative weights, pick a subset of non-adjacent nodes with the maximum total weight. For the simple 4-nodes example with weights 1, 4, 5 and 4 (with maximum weight 4 + 4 = 8), we saw how both a greedy approach and a divide and conquer approach failed.</p>
<p>Then the optimal solution is expressed in terms of two smaller paths (without the last one or two nodes respectively). A recursive solution would lead to an exponential number of sub-problems, but by caching the result of already solved sub-problems (&#8220;memoization&#8221;), the time-complexity becomes O(<em>n</em>). Finally the solution is reformulated as a bottom up solution, where a table is created where the solutions to the sub-problems is filled in. I thought this was a great introduction to dynamic programming &#8211; well-reasoned, clear and easy to follow.</p>
<p>Next was the classic knapsack problem (I knew about it, but had never attempted to solve it). Given <em>n</em> items, each with a value and a size, and a knapsack of size <em>W</em>, find a subset of items that can fit in the knapsack that maximizes the total value of the items. Programming assignment 3 deals with the knapsack problem. In the first part, there are 100 items, and the knapsack capacity is 10,000. This can be solved with the bottom up approach of filling in a 2-dimensional array with the solutions to the sub-problems. In the second part, there are 500 items, and the knapsack capacity is 2,000,000. In this case the table approach would take up too much memory. Instead it can be solved recursively with caching of intermediate results.</p>
<p>The next application of dynamic programming was the really cool algorithm for sequence alignment. Given two strings (for example DNA), how can we make them align so that we minimize the cost, where there is a cost for each inserted gap and mismatched letter. For example, the strings AGGGCT and AGGCA can be made to align by inserting a gap in the second string so it becomes AGG_CA. The cost in this case is one gap, and one mismatch (the T and A at the end). For long strings (thousands of letters), a brute force solution is staggeringly time consuming. Fortunately, with dynamic programming, it is possible to express the solution in terms of the solution to sub-problems, and the running time is O(<em>mn</em>), where <em>m</em> and <em>n</em> are the lengths of the two strings. Very cool!</p>
<p>For optimal binary search trees, given <em>n</em> items, each with a given probability of being selected, construct the binary search tree that will minimize the average search time for the items. This is similar to Huffman codes in that they both output a binary tree, and they both try to minimize the average depth. However, in Huffman codes, the items are only leaves in the tree, whereas here the items are both nodes and leaves. I didn&#8217;t find this algorithm that interesting, since if you have a balanced search tree (albeit not optimal), the performance will still be quite good.</p>
<p>Next were three different algorithms for finding shortest paths in directed graphs. The Bellman-Ford algorithm finds the shortest path from a source node to all other nodes in the graph, and is developed by using the dynamic programming idea of building the solution from the solution to sub-problems. In this case, the sub-problems consist of the shortest path using only a fixed number of edges. The algorithm works for negative edge weights, unlike Dijkstra&#8217;s algorithm (covered in part 1).</p>
<p>Floyd-Warshall&#8217;s algorithm computes all pairs shortest paths in a directed graph. The key trick in its development is to let the sub-problem consist of the shortest path limited to using a certain sub-set of the edges. In this way, the dynamic programming solution is found. It is built using a 3-dimentional array, where each axis has the number of nodes. In programming assignment 4, you had to find the shortest of all the shortest paths in three given 1000-node graphs. If there were any negative cycles in the graph, this had to be indicated. This assignment was a little bit trickier, since you have to make sure you don&#8217;t run out of memory (the 3-dimensional array contains a billion entries).</p>
<p>The final graph algorithm was Johnson&#8217;s algorithm for finding all pairs shortest paths. It uses a clever technique to re-weight the edges to make sure there are no negative edges, and then uses Dijkstra&#8217;s algorithm to find the shortest paths.</p>
<h3>NP-Complete Problems and Ways to Deal With Them</h3>
<p>We covered NP-complete problems when I went to university, so this wasn&#8217;t new to me, but it was good with a refresher. For a lot of problems, like the travelling salesman problem, there are no known algorithms that run in polynomial time. So we are stuck with solutions with exponential running time, meaning that only problems with very small input sizes can be solved optimally. However, all is not lost. Various ways to deal with NP-complete problems were covered.</p>
<p>The following topics, algorithms and techniques were covered:</p>
<ul>
<li>P, NP, and what they mean</li>
<li>Reductions between problems</li>
<li>NP-complete problems</li>
<li>The P vs. NP problem</li>
<li>Vertex cover</li>
<li>Travelling salesman</li>
<li>Approximate solutions to the knapsack problem</li>
<li>Local search</li>
<li>Papadimitriou&#8217;s 2SAT algorithm</li>
</ul>
<p>The first part of this section of the course defined the concepts of P, NP, NP-hard and NP-complete problems. Next, the reductions between NP-complete problems was covered, and the question of whether P = NP. After the theory had been established, various ways of dealing with NP-complete problems were presented.</p>
<p>It is still possible to solve the NP-complete problems for small inputs using brute force. It may also be possible to find special cases that are of interest and can be solved more quickly. Yet another way is to find algorithms that are better than brute force search, but still not polynomial. An example of this was an algorithm for the travelling salesman (more on this below). Otherwise we may have to turn to non-optimal solutions. An example algorithm was developed for the general knapsack problem, where it is possible to come within a given fraction of the optimal solution (the closer to the optimal solution, the longer the running time).</p>
<p>One meta-algorithm covered was local search. The idea is to start with a randomly generated solution that is most likely not optimal. Then we iteratively try to improve on that solution by making local changes until we can&#8217;t improve anymore. Then we start with a new random solution and repeat the process. There is obviously the risk of finding local maxima, while still not finding a global maximum.</p>
<p>For programming assignment 5, we had to find the shortest path for a travelling salesman problem with 25 cities to visit. This was the hardest of the programming problems. The algorithm that was developed in the lecture videos used dynamic programming to improve the running time from O(<em>n!</em>) to O(<em>n^2&#215;2^n</em>), so it is not polynomial. The algorithm, while reasonable easy to understand conceptually, takes quite a bit of work to implement correctly. However, the biggest problem with the solution wasn&#8217;t running time, but memory usage.<span style="color:#444444;line-height:1.7;"> I started out using the Java class BitSet to keep track of which cities to include. But I ran out of memory and changed to integers instead. I also changed from pre-calculating all integers with <em>x</em> number of bits set, and instead calculated them on the fly. With these memory optimizations, I was finally able to run the algorithm, but it took quite a bit of work.</span></p>
<p>The last algorithm covered in the class was a clever randomized local search algorithm for the 2SAT problem. In the 2SAT problem (which I had never heard of before, even though it is famous), the task is to find boolean values for <em>n</em> boolean variables used in clauses of the form (<em>x</em> or <em>y</em>). A number of these clauses are basically and:ed together, and the task is to determine if there is an assignment of true or false to all the variables that makes the whole expression true (there may not be such an assignment). The algorithm covered was Papadimitriou&#8217;s algorithm, which uses the idea of a random walk to try to find an assignment of the variables that makes the expression true. A clever idea, and a nice analysis of the properties of the algorithm.</p>
<p>The final programming problem was to solve the 2SAT problem. One way would have been to use Papadimitiou&#8217;s algorithm, but I chose to use the program I developed in part 1 of the course for finding strongly connected components (SCC) instead. By (again very cleverly) transforming the 2SAT expression to a graph, it was possible to check if it is solvable by checking if a given boolean variable and its negation are both present in the same SCC. If so, the 2SAT expression can not be solved. This programming problem was harder than the first ones, but not as hard as the travelling salesman one.</p>
<h3>Conclusion</h3>
<p>I really enjoyed this course. It started in the beginning of December, had a break over Christmas, and continued in January. Since I am always very busy around Christmas and New Year&#8217;s, I wasn&#8217;t able to start the course until the second week of January. This meant that I had to work quite hard to complete it in the time left. But even if that had not been the case, the course was still a lot harder than part 1 I thought. Especially the quizzes, but also the programming assignments. I skipped part 2 of programming assignment 2 (clustering in a bigger graph), but completed all the other programming assignments, all the quizzes, and the final exam. Since I started late, my score on the first three weeks&#8217; assignments was reduced by 50%. My final score was 67% (80% without reductions), and the cut-off for getting a statement of accomplishment was 70%, so no certificate for me this time.</p>
<p>Regardless of the score, I learnt a lot by taking this course. It took a lot of time and effort, by I have definitely improved my algorithm knowledge and skill. I can really recommend both parts of the course to anyone wanting to learn more about algorithms and problem solving.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/623/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=623&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2013/02/18/coursera-algorithms-course-part2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>
	</item>
		<item>
		<title>Blog stats for 2012 (by WordPress)</title>
		<link>http://henrikwarne.com/2012/12/31/blog-stats-for-2012-by-wordpress/</link>
		<comments>http://henrikwarne.com/2012/12/31/blog-stats-for-2012-by-wordpress/#comments</comments>
		<pubDate>Mon, 31 Dec 2012 15:37:04 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[statistics]]></category>
		<category><![CDATA[stats]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=615</guid>
		<description><![CDATA[The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog. Here&#8217;s an excerpt: About 55,000 tourists visit Liechtenstein every year. This blog was viewed about 170,000 times in 2012. If it were Liechtenstein, it would take about &#8230; <a href="http://henrikwarne.com/2012/12/31/blog-stats-for-2012-by-wordpress/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=615&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>The WordPress.com stats helper monkeys prepared a 2012 annual report for this blog.</p>
<p><a href="http://henrikwarne.com/2012/annual-report/"><img alt="" src="http://www.wordpress.com/wp-content/mu-plugins/annual-reports/img/2012-emailteaser.png" width="100%" /></a></p>
<p>Here&#8217;s an excerpt:</p>
<blockquote><p>About 55,000 tourists visit Liechtenstein every year. This blog was viewed about <strong>170,000</strong> times in 2012. If it were Liechtenstein, it would take about 3 years for that many people to see it. Your blog had more visits than a small country in Europe!</p></blockquote>
<p><a href="http://henrikwarne.com/2012/annual-report/">Click here to see the complete report.</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/615/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/615/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=615&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2012/12/31/blog-stats-for-2012-by-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>

		<media:content url="http://www.wordpress.com/wp-content/mu-plugins/annual-reports/img/2012-emailteaser.png" medium="image" />
	</item>
		<item>
		<title>Working as a Software Developer</title>
		<link>http://henrikwarne.com/2012/12/12/working-as-a-software-developer/</link>
		<comments>http://henrikwarne.com/2012/12/12/working-as-a-software-developer/#comments</comments>
		<pubDate>Wed, 12 Dec 2012 20:44:51 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[production software]]></category>
		<category><![CDATA[professional software development]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[programming course]]></category>
		<category><![CDATA[university]]></category>
		<category><![CDATA[working]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=549</guid>
		<description><![CDATA[I recently gave a presentation on what it is like to work as a software developer to first-year engineering students at KTH taking an introductory programming course. I wanted to give my view on the main differences between professional software &#8230; <a href="http://henrikwarne.com/2012/12/12/working-as-a-software-developer/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=549&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I recently gave a presentation on what it is like to work as a software developer to first-year engineering students at <a title="KTH Royal Institute of Technology" href="http://www.kth.se/en">KTH</a> taking an <a title="ID1004 Objectoriented Programming 7.5 credits" href="http://www.kth.se/student/kurser/kurs/ID1004?l=en">introductory programming course</a>. I wanted to give my view on the main differences between professional software development and programming for a university course.</p>
<p>First I talked about challenges with large-scale software development. Then I listed several development practices used to cope with these challenges. I went on to present ways to become a better programmer, and ended with some fun facts from work.</p>
<p><span id="more-549"></span></p>
<h3>Characteristics of Production Software</h3>
<p><strong>Programs are BIG</strong>. The main characteristic of software used in live systems is the size. For example, our main repository <a title="Symsoft" href="http://symsoft.com/">at work</a> contains 1.8 million lines of Java (I used the tool <a title="Count Lines of Code" href="http://cloc.sourceforge.net/">cloc</a> to find the number of lines). The sheer size of the programs complicates software development, and a lot of practices have been developed to deal with it.</p>
<p><strong>Software is never done.</strong> Software that is used keeps growing and evolving. The customers find more and more uses for it, and want more and more features. Software that is not used is discontinued, but successful software is developed continuously for many years. Several developers are almost always involved. For example, I checked the subversion log of one of the main classes in our SMS application. There were 150 check-ins over 7 years, by 8 different developers (2 of which don&#8217;t work at Symsoft anymore).</p>
<p><strong>Complexity from aggregation.</strong> Most features in production software are quite simple, but because there are so many of them, you get subtle (or not so subtle) interactions between them causing bugs. The complexity of the system comes from the aggregation of many simple parts, not from any complex parts.</p>
<p><strong>Reading code.</strong> A consequence of the characteristics mentioned above is that <em>reading</em> code is a very important skill. Before a program can be modified, you need to understand what it does, and how it does it. Only then can new functionality be added so it fits in with the existing structure, and without breaking anything.  Reading and understanding a program can be a major effort, and one sign of a well-designed program is that it is relatively straight-forward to modify it.</p>
<h3>How to Manage</h3>
<p>Many techniques have been developed to make developing and maintaining large programs easier. Here are the most important.</p>
<p><strong>Modularize.</strong> This is an obvious first step, and (I believe) universally used. The software is split into subsystems, layers or modules so that smaller chunks of functionality can be dealt with at a time.</p>
<p><strong>Iterate.</strong> Developing software bit by bit is as helpful for small 30-lines scripts as it is for systems with millions of lines of code. I like the following quote:</p>
<p><em>“A complex system that works is invariably found to have evolved from a simple system that worked.” &#8211; John Gall</em></p>
<p><strong>Self-documenting code.</strong> The naming of the classes, methods and variables is incredibly important. The names, when chosen well, let you understand what the program does just by reading them. They also greatly reduce the need for comments in the code.</p>
<p><strong>No duplication.</strong> Code-duplication causes a lot of problems when you come back to modify the program (happens all the time) &#8211; you may forget to make the intended change in all the duplicates. So instead of copy-pasting, combine the logic into one method. It makes the code more compact, and easier to modify in the future. There is an excellent article by Martin Fowler, <a title="Avoiding Repetition (pdf)" href="http://martinfowler.com/ieeeSoftware/repetition.pdf">Avoiding Repetition</a>, on this subject. Unfortunately, I have seen a lot of duplicated code in production software over the years.</p>
<p><strong>Unit testing</strong>. Unit testing (<a title="JUnit" href="https://github.com/kentbeck/junit/wiki">JUnit</a> etc.) is useful both in small-scale and large-scale development. It&#8217;s an easy way to ensure your smallest program parts work as expected, and you get repeatable tests that can be run again and again. Making sure your code can be unit-tested also automatically improves the structure of the code &#8211; it becomes less monolithic, more de-coupled.</p>
<p><strong>Version control.</strong> Using version control (like git or subversion) is a no-brainer, and as far as I can tell pretty much always used in professional software development. Version control systems are used both to keep track of different working versions of the software, and for knowing exactly what code is included in each release.</p>
<p>Version control is also useful on an individual level, for example for the programming assignments at a university course. Any program I spend more than 10 minutes writing, I stick in a local git repository. That way, I can always go back to previous (working) versions of my program.</p>
<p><strong>Write for people first, computer second.</strong> The code you write will be read many times in the future (by you, or another developer). The computer doesn&#8217;t care how the code is written, so make it as easy as possible to understand for the next person that has to read it. A corollary to this is: don&#8217;t be too clever. It&#8217;s better to be clear than to be clever. The following quote puts it another way:</p>
<p><em>“It’s OK to figure out murder mysteries, but you shouldn’t need to figure out code. You should be able to read it.” &#8211; Steve McConnell</em></p>
<p><strong>Plan for failure &#8211; logging and error handling.</strong> What do you do when the program doesn&#8217;t work as expected? You need some way of seeing what is going on. Usually this is in the form of tracing or logging. This will inevitably happen, so you might as well build in support for tracing and logging from the start (and make it possible to activate and deactivate while the program is running). It&#8217;s a similar story with error handling; put in place a unified way of handling errors in the program, because errors will happen.</p>
<p><strong>Issue tracking.</strong> For any real system, it is necessary to have a way to keep track of bug reports - e-mails don&#8217;t cut it. At work we use <a title="Jira" href="http://www.atlassian.com/software/jira">Jira</a>, but there are many products with similar capabilities. Often, the same system is also used to keep track of new features to be implemented.</p>
<h3>Becoming a better programmer</h3>
<p>There is almost no limit to what you can do to improve as a programmer. Here are some basic tips, appropriate if you are taking a software development course at university, but want to progress beyond learning the content of the course.</p>
<p><strong>Program!</strong> The best way to learn to program is to actually program. Reading a book or listening to a lecture can make it seem like you have learnt and understood the concepts, but it is not until you actually start writing your own programs that you really learn. This is why (in my opinion) the best programming courses have lots of programming assignments &#8211; that&#8217;s when you are forced to put the theory into practice.</p>
<p>But you don&#8217;t have to stop at just doing the assignments. Solve some other problems with programs as well. If you don&#8217;t know what to solve, you can look for good problems at <a title="Programming Praxis" href="http://programmingpraxis.com/">Programming Praxis</a>, <a title="Ruby Quiz" href="http://www.rubyquiz.com/">Ruby Quiz</a> (the problems don&#8217;t all have to be solved in Ruby), or <a title="Project Euler" href="http://projecteuler.net/problems">Project Euler</a> (quite mathematical).</p>
<p><strong>Learn a scripting language.</strong> Being able to write small scripts to automate tasks on the command line or to filter out information from a log file containing 100,000 lines is quite useful. Make sure to learn how to use regular expressions, and a language like Ruby, Python or Perl. All those languages are also used for &#8220;serious&#8221; applications, but even just using them for quick shell scripts is worthwhile.</p>
<p><strong>Learn an IDE and a text editor well.</strong> For Java development it&#8217;s really worthwhile to learn to use an Integrated Development Environment (IDE), such as IntelliJ IDEA or Eclipse, really well (as I have written <a title="Programmer Productivity: Emacs versus IntelliJ IDEA" href="http://henrikwarne.com/2012/06/17/programmer-productivity-emacs-versus-intellij-idea/">about before</a>). In addition, it is always useful to know a good text editor, for example Emacs or Vim. In both cases (IDE and editor), learn as many keyboard shortcuts as you can. The goal is to be able to go from thought to program as effectively as possible.</p>
<p><strong>Books.</strong> The number one book that every programmer should read is<a title="Code Complete" href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/"> Code Complete</a> by Steve McConnell. It&#8217;s always on top of every list of the best programming books, and for good reason (I&#8217;ve <a title="My review of Code Complete" href="http://www.amazon.com/review/R269BBARXH1V6R/">reviewed it on Amazon</a>). It has a lot to say about how to write code (in a language-neutral way). The next book to read is <a title="The Pragmatic Programmer" href="http://www.amazon.com/The-Pragmatic-Programmer-Journeyman-Master/dp/020161622X">The Pragmatic Programmer</a> by Andrew Hunt and David Thomas. It contains a lot of tips on how to develop software efficiently.</p>
<p><strong>Hacker News and Proggit.</strong> There are always interesting articles related to programming at both <a title="Hacker News" href="http://news.ycombinator.com/">Hacker News</a> and <a title="Proggit" href="http://www.reddit.com/r/programming">reddit/r/programming</a>. Just remember to not spend <em>too</em> much time there &#8211; program instead. But for inspiration these sites are great.</p>
<h3>Fun Facts</h3>
<p>I also added a few fun facts about how we develop software at Symsoft. All of these are not necessarily true everywhere, but I wanted to add in a few bits of trivia to give a better sense of what it can be like to work.</p>
<p><strong>HashMap and ArrayList. </strong>The two Java data structures we use the most in our code.</p>
<p><strong>English</strong>. We&#8217;re in Sweden, but everything is in English &#8211; the code, documentation, bug reports etc. No big surprise, I just wanted to make sure everybody knows.</p>
<p><strong>People interactions.</strong> Even if your job description is coding, there is quite a bit of interaction with other people. Mostly discussing designs and bugs with colleagues, but also contact with product management and sales, and with customers. There is no such thing as a solitary coder.</p>
<p><strong>Time for bug-fixing.</strong> We schedule around 30% of the developers&#8217; time for bug-fixing. This includes the time for investigating reported problems, fixing the bugs and testing the solution. It is worth noting that many reported problems aren&#8217;t actual bugs. Sometimes the system is not configured properly, sometimes the problem is in a surrounding system, and sometimes the bug report is actually a request for a new feature.</p>
<p><strong>No UML.</strong> We don&#8217;t use <a title="Unified Modeling Language" href="http://en.wikipedia.org/wiki/Unified_Modeling_Language">UML</a>, but there are lots of whiteboards around. We use them all the time when discussing a solution to a problem, and when describing how the system works.</p>
<p>The talk took about 45 minutes to deliver. It was interesting to prepare and fun to give. What is your opinion and experience on what it is like to work as a professional software developer? Let me know in the comments.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/549/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/549/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=549&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2012/12/12/working-as-a-software-developer/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>
	</item>
		<item>
		<title>4 Reasons Why Bugs Are Good For You</title>
		<link>http://henrikwarne.com/2012/10/21/4-reasons-why-bugs-are-good-for-you/</link>
		<comments>http://henrikwarne.com/2012/10/21/4-reasons-why-bugs-are-good-for-you/#comments</comments>
		<pubDate>Sun, 21 Oct 2012 09:01:16 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[debugging]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=495</guid>
		<description><![CDATA[Every once in a while I read something along the lines of: &#8220;most developers just want to write new features, they don&#8217;t want to work with maintenance and bug-fixing&#8221;. If that&#8217;s true, then most developers are missing out on the fun &#8230; <a href="http://henrikwarne.com/2012/10/21/4-reasons-why-bugs-are-good-for-you/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=495&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Every once in a while I read something along the lines of: &#8220;most developers just want to write new features, they don&#8217;t want to work with maintenance and bug-fixing&#8221;. If that&#8217;s true, then most developers are missing out on the fun and benefits of finding and fixing bugs.<span id="more-495"></span></p>
<h3>Each bug can teach you something</h3>
<p>Feedback is one key to developing better products. It&#8217;s one of the primary tenets of agile development. Unit testing and iterative development are both techniques to provide feedback faster. With unit testing you get feedback on whether the code works, and with each delivered release you can hear what the customer thinks of the new features. A bug report is another form of feedback on your code.</p>
<p>There can be many different causes of a bug. Some possibilities are: a simple coding mistake (like a nested if-statement where you end up in the wrong branch), or a faulty assumption on your part (maybe the incoming messages don&#8217;t always have certain fields present, so you got a null pointer exception), or there is a missing requirement (you should have answered the message in a different way if a given parameter is present), or the customer is using the software in an unanticipated (but correct) way, leading to bugs.</p>
<p>In each of these cases, you can learn something about how to code, about your product, or about the domain it operates in.</p>
<p>For example, when I developed VoIP products at <a title="Tilgin" href="http://www.tilgin.com/">Tilgin</a>, there was a case where we received a faulty message that caused our software to loop indefinitely. The messages contained elements encoded using tag-length-value (TLV) parameters, where the length value was the total length of the element. This way you can skip unused or unknown elements by jumping forward &#8220;length&#8221; number of bytes. In this case, the length value was zero, so after the skip we pointed to the same element we pointed to before the skip, causing an infinite loop.</p>
<p>Before this bug, my code carefully checked length values for too big values that would cause a read past the end of the message buffer. However, up until then, it had never occurred to me that a length of zero could be just as bad.</p>
<h3>Your Own Code Becomes Easier To Debug</h3>
<p>When you spend time trouble-shooting problems and fixing bugs, it doesn&#8217;t take long until you want to make your own code as easy as possible to debug. It is frustrating not having all available information presented.</p>
<p>One extremely common problem is exceptions that don&#8217;t include dynamic information. For example, suppose there is code that expects a value to be in the range 0 &#8211; 20. How many times have you seen an exception that just says &#8221;Illegal value&#8221;? That doesn&#8217;t tell you much if you are trying to find a bug. If for instance 21 was received, it should say something like &#8221;Illegal value: 21, not in range 0 &#8211; 20&#8243;.</p>
<p>It helps to include the allowed range, and it definitely helps to include the current value. The current value could be 21, or -128, or 65535. All of those could give you a clue as to what caused it, which you don&#8217;t get from a plain &#8221;Illegal value&#8221;.</p>
<p>Even Steve McConnell breaks this rule in some places in the excellent book <a title="Code Complete" href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/">Code Complete</a>. For example, in chapter 15 there is an example where an unexpected type of character is detected, but the error message doesn&#8217;t include the character in question.</p>
<p>Every time you find and fix a bug, you need to ask yourself: is there anything in my code I should do differently in order to eliminate bugs like this in the future? Is there anything I should be doing to make trouble-shooting this kind of bug easier in the future? This is very fertile ground for improvements.</p>
<h3>Both You And the Customer will be Happy</h3>
<p>As I mentioned in <a title="Why I Love Coding" href="http://henrikwarne.com/2012/06/02/why-i-love-coding/">Why I Love Coding</a>, one of the joys of programming is making something that is useful to other people. You get the same kind of kick out of fixing a bug, but on a different time scale. Delivering new features usually takes a while, but a bug-fix can be done in an hour. Each fixed bug makes you feel you are accomplishing something, and that&#8217;s a great feeling.</p>
<p>It&#8217;s a bit of a paradox that fixing a bug will make the customer happy. If there wasn&#8217;t a bug in the first place, there wouldn&#8217;t be a need to fix it, so why should they be happy? However, my experience is that they <em>are</em> happy to receive a bug-fix, especially if it is solved quickly. Everybody knows that there will always be bugs. What matters is that somebody is ready to fix them quickly when they are discovered.</p>
<h3>Solving Problems is Fun</h3>
<p>Many programmers enjoy solving problems, like mathematical puzzles, programming challenges, Sudoku or crosswords. Even reading murder mysteries feed into this: you look at the clues and try figure out how it happened.</p>
<p>Debugging and fixing bugs is the same. Each bug is a new mystery to figure out. Often your first reaction when seeing a new bug report is: that&#8217;s impossible? How could that happen? That&#8217;s when you start looking for clues. What do the logs say? Any error reports from the system? What else happened in the system at this time? Was anything changed recently &#8211; new software, configuration changes, traffic disturbances? Let the figuring-out begin!</p>
<p>These are four reasons I like debugging and bug-fixing so much. What is your experience?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/495/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/495/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=495&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2012/10/21/4-reasons-why-bugs-are-good-for-you/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>
	</item>
		<item>
		<title>Book Review: How Google Tests Software</title>
		<link>http://henrikwarne.com/2012/09/23/book-review-how-google-tests-software/</link>
		<comments>http://henrikwarne.com/2012/09/23/book-review-how-google-tests-software/#comments</comments>
		<pubDate>Sun, 23 Sep 2012 06:13:04 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=438</guid>
		<description><![CDATA[When I found out about the book &#8221;How Google Tests Software&#8220;, it didn&#8217;t take long until I had ordered a copy. I find it quite fascinating to read about how Google does things, whether it is about their development process, their &#8230; <a href="http://henrikwarne.com/2012/09/23/book-review-how-google-tests-software/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=438&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://henrikwarne1.files.wordpress.com/2012/09/dscf3998.jpg?w=225"><img class=" wp-image-471    alignright" title="How Google Tests Software" src="http://henrikwarne1.files.wordpress.com/2012/09/dscf3998.jpg?w=186&#038;h=247" alt="" width="186" height="247" /></a> When I found out about the book &#8221;<a title="How Google Tests Software" href="http://www.amazon.com/Google-Tests-Software-James-Whittaker/dp/0321803027">How Google Tests Software</a>&#8220;, it didn&#8217;t take long until I had ordered a copy. I find it quite fascinating to read about how Google does things, whether it is about their development process, their infrastructure, their hiring process, or, in this case, how they test their software. I am a developer at heart, but I have worked for a few years as a tester, so testing is also dear to me.</p>
<p>It&#8217;s quite an interesting book, and it makes some great points about the future of testing. However, despite the phrase &#8220;Help me test like Google&#8221; on the cover, it is not as useful as I had hoped when it comes to improving your own testing.<span id="more-438"></span>The book starts off by describing the key roles at Google: SWE (Software Engineer), SET (Software Engineer in Test) and TE (Test Engineer). Briefly, the SWE builds features for Google&#8217;s products, the SET develops testing infrastructure and larger-scale automatic tests, and the TE tests the products from a user&#8217;s perspective. After the introductory chapter, there is a chapter each on the SET and TE roles, and there is also a chapter on the TEM (Test Engineer Manager) role. The final chapter is about the future of testing at Google (and in general).</p>
<h4>Software Engineer in Test (SET)</h4>
<p>As the different roles are explained in the respective chapters, there is also quite a bit of detail on how the testing is done at Google. The most interesting part in the chapter on the SET role is the part about the infrastructure. There is (of course) extensive support for running tests automatically. There is common infrastructure for compilation, execution, analysis, storage and results reporting of tests. Tests are categorized as small, medium, large or enormous. Small tests are basically unit tests where everything external is mocked out, and they are expected to execute in less than 100 ms.</p>
<p>Medium tests involve external subsystems, and can use database access, but generally run on one machine (use no network services), and are expected to run in under a second. Large and enormous tests run a complete application, including all external systems needed. They can be nondeterministic because of the complexity, and they are expected to complete in 15 minutes and 1 hour respectively. A good way to summarize them is that small tests lead to code quality, and medium, large and enormous tests lead to product quality. The common test execution environment for running the tests has been developed over time, and has several nice features. It will automatically kill tests that take too long to run (thus the time limits mentioned above).</p>
<p>It has several features to facilitate running many different test concurrently on a machine &#8211; it&#8217;s possible to request an unused port to bind to (instead of a hardcoded port number that could clash with another test), writing to the file system can be done to a temporary location unique to the current test, and private database instance can be created and used to avoid cross talk from other tests. Further, their continuous integration system uses dependency analysis to run only tests affected by a certain change, thus being able to pinpoint exactly which change broke a certain test. This system has been developed by Google for many years, and has become quite capable and tailored to their way of working.</p>
<h4>Test Engineer (TE)</h4>
<p>The most interesting part in the TE chapter is the description of the process used for developing the test plan for a product. The test plan&#8217;s purpose is to map out what needs to be tested for the product, and when it is done it should be clear what test cases are needed. It can be a challenge to find the right level of detail for a test plan, but it seems like they have found a good balance at Google.</p>
<p>The Google process for coming up with the test plan is called ACC, which stands for Attribute, Component and Capability. Attributes are the qualities of the product, the key selling points that will get the people to use the product. The examples given for Chrome include fast, secure and stable. There won&#8217;t typically be that many attributes.</p>
<p>Next, the Components are the major subsystems of the product, around 10 seems to be a reasonable number to include. Finally there are the Capabilities, which are the actions the system can perform for the user. Whereas there are relatively few attributes and components, there can be quite a number of capabilities. The capabilities lie at the intersection of attributes and components. It is natural to create a matrix with attributes along one axis, and components along the other axis. Then each capability will fit in at the given coordinates. A key property for a capability is that it is testable, and each capability will lead to one or more test cases to verify its functionality. Thus the matrix is an aid in enumerating all the test cases that are needed.</p>
<p>The matrix allows you to look at what capabilities affect a certain module. If you look along the other dimension, you will see all capabilities supporting a certain attribute. The matrix is also useful in risk analysis, and when tracking testing progress.</p>
<p>In the same chapter, there is also a good story about a 10-minute test plan. James Whittaker did an experiment where he forced people to come up with a test plan for a product in 10 minutes. The idea was to boil it down to the absolute essentials, without any fluff, but still being useful. Because of the time constraint, most people just made lists or grids &#8211; no paragraphs of text. In his opinion (and I agree), this is the most useful level &#8211; it is quick to come up with and doesn&#8217;t need a lot of busy-work filling out sections in a document template, and still it&#8217;s a useful basis for coming up with test cases. The common theme in all cases was that people based the plan on capabilities that needed testing.</p>
<h4>Tools</h4>
<p>There are other interesting testing tools described in the book too. One such tool developed at Google is BITE &#8211; Browser Integrated Test Environment. When testing a browser-based app, like Google Maps, and something went wrong, there was a lot of information to extract and put into the bug report. For example, what actions lead up to the bug, what version of the software was running, how the bug manifest itself etc. The BITE browser extension keeps track of all the actions the tester made in the application, and supports filing a bug report by automatically including all the relevant information. It also has support for easily marking in a screen shot where the bug appeared.</p>
<p>Another interesting tool is Bots. It involves automatic tests where many different versions of Chrome fetch the top 500 webpages on the web. The resulting HTML is compared and detailed &#8220;diff&#8221;-reports are produced.</p>
<h4>Tips</h4>
<p>There was also a sprinkling of interesting ideas (that can definitely be of use in any test organization) throughout the book. Here are the ones that stuck in my head: When asking people to estimate a value for something (for example the frequency of a certain failure scenario), use an even number of values (e.g. rarely, seldom, occasionally, often). That way you can&#8217;t just pick the middle value &#8211; you&#8217;re forced to think about it more carefully.</p>
<p>Another example in the same area. If you want people&#8217;s opinion of how likely a certain failure scenario is, you could just ask them about it. But another technique is to assign a value yourself, and then ask what they think. Then you have given them something to argue against. Often, people have an easier time to say what something<em> isn&#8217;t</em>, then what it is.</p>
<p>There is also a quote from Larry Page that is referred to several times in the book (for example regarding the relatively few testers at Google) &#8220;Scarcity brings clarity&#8221;, and (later on), Scarcity is the precursor of optimization. Worth thinking about.</p>
<p>As well as describing how the testing is done, and which tools are used, there are also a number of interviews with various people in the test organization. The chapter on TEM (Test Engineer Manager) in particular consists almost entirely of interviews, 8 in total. Most interviews in the book were interesting to read, but many of them weren&#8217;t that useful in terms of tips or ideas to use in your own testing.</p>
<h4>The Future of Testing</h4>
<p>For me, the best chapter in the book was chapter 5, &#8220;Improving How Google Tests Software&#8221;. It is the last and shortest chapter, only 7 pages. In it, James Whittaker shares some profound insights about testing at Google, and testing in general. One of the flaws he sees with testing is that testers are&#8230; testers. They are not part of the product development team. Instead, they exist in their own organization, and this separation of testers and developers gives the impression that testing is not part of the product; it&#8217;s somebody else&#8217;s responsibility. Further, the focus of testing is often the testing activities and artifacts (the test cases, the bug reports etc.), not the product being tested. But customers don&#8217;t care about testing per se, they care about products.</p>
<p>Finally, a lot of the testing mindset we have today developed in a different era. When you released a product, that was it. There was no easy way to upgrade it, and users had to live with whatever bugs slipped through. However, these days so much of the software can be fixed and upgraded without a lot of fuss. In this environment, it makes less sense to have testers act as users and try to discover what bugs they might run into. Instead, you can release the software, and see what bugs the actual users encounter. Then you make sure these bugs are fixed and that the new release is pushed out quickly.</p>
<p>So his opinion is that testing should be the responsibility of all the developers working on the product. It should be their responsibility to test the product and to develop the appropriate tools (with some exceptions, for instance security testing). Whether you agree or disagree with this, it is definitely food for thought!</p>
<h4>Conclusion</h4>
<p>Initially, when I had just finished reading the book, I felt a little disappointed. It was interesting to read, but there didn&#8217;t seem to be that much to take away from it and apply to your own testing. Pretty much all of the techniques and tools are tailored for Google and their needs, which is just as it should be. But that means that they may not be applicable to your own situation.</p>
<p>However, as I am going through it again while writing this review, I realize that there are quite a few good ideas in it &#8211; they just have to be adapted to your specific situation. So while not directly applicable, the ideas in the book serve as inspirations for how testing can be organized and executed.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/438/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/438/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=438&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2012/09/23/book-review-how-google-tests-software/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>

		<media:content url="http://henrikwarne1.files.wordpress.com/2012/09/dscf3998.jpg?w=225" medium="image">
			<media:title type="html">How Google Tests Software</media:title>
		</media:content>
	</item>
		<item>
		<title>Top 5 Surprises When Starting Out as a Software Developer</title>
		<link>http://henrikwarne.com/2012/08/22/top-5-surprises-when-starting-out-as-a-software-developer/</link>
		<comments>http://henrikwarne.com/2012/08/22/top-5-surprises-when-starting-out-as-a-software-developer/#comments</comments>
		<pubDate>Wed, 22 Aug 2012 10:15:52 +0000</pubDate>
		<dc:creator>Henrik Warne</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[surprises]]></category>
		<category><![CDATA[university]]></category>
		<category><![CDATA[working]]></category>

		<guid isPermaLink="false">http://henrikwarne.com/?p=391</guid>
		<description><![CDATA[Even though more than 20 years have passed, I still remember wondering what it would be like to finish university and start working. Up until that point, I had pretty much spent my whole life in school, with only a &#8230; <a href="http://henrikwarne.com/2012/08/22/top-5-surprises-when-starting-out-as-a-software-developer/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=391&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Even though more than 20 years have passed, I still remember wondering what it would be like to finish university and start working. Up until that point, I had pretty much spent my whole life in school, with only a few, non-programming summer jobs thrown in. My expectations of what it would be like to work as a software developer were mostly correct, but there were a few surprises in the first few years, and here are the top five:<span id="more-391"></span></p>
<h5>5. People Interaction</h5>
<p>Programming seemed like quite a solitary job &#8211; a feature needs to be done, so you sit down at your computer and code it up. The truth is there is quite a lot of interaction with other people. You discuss your designs with your colleagues, you are in meetings reviewing new features, and you talk to the testers testing your code.</p>
<p>It really helps to be tactful and diplomatic during these interactions; if this doesn&#8217;t come naturally, learn how. One of the best books on the subject is <a title="How To Win Friends and Influence People" href="http://www.amazon.com/How-Win-Friends-Influence-People/dp/1439167346/">How To Win Friends and Influence People</a>by Dale Carnegie. If you haven&#8217;t read it, I really recommend that you do.</p>
<h5>4. Writing Matters</h5>
<p>It helps a lot to be able to write clearly in order to get your points across. To some extent, coding and writing are quite similar. In both cases you need to express your ideas clearly and unambiguously in a structured way. There are of course lots of e-mails that need to be written, but there is also documentation of the features you have developed, describing bugs in bug reports so that it is clear what the problem is, as well as writing good explanations for bugs you have fixed. There wasn&#8217;t much emphasis on writing at university, but being able to write well definitely is an asset at work.</p>
<h5>3. Software is Never Done</h5>
<p>Before I started working, I thought that you developed a feature, and then you were done with it. However, in reality you quite often come back to features. Maybe it was not exactly what the customer wanted, or you are adding more functionality to it, or similar funtionality so you want to combine it, or you are fixing a bug in it. One way or another, you often return to code you wrote before.</p>
<p>I didn&#8217;t really understand either that new features are almost always inserted into existing code. At university, we always developed programs from scratch, but that is almost never the case in the real world. Sure, you create new functionality, but it always has to fit in to what is already there. Therefore, a large part of creating a new feature is understanding the existing code in order for the new feature to fit in. This is something we never practiced at school.</p>
<h5>2. Few Clever Algorithms</h5>
<p>At university I did an M.Sc. in Computer Science and Engineering. I studied communication systems, which included signal processing, error correcting codes, queuing theory and so on. We also had core computer science courses like algorithms and data structures, and I loved all of it. I thought it was really cool to be taught all these clever algorithms and data structures, and I expected to see them in use at work.</p>
<p>My first job was as a software developer at Ericsson in Montreal, working with the mobile switching center that handles calls in a cellular network. There was a lot of code controlling call set-up, hand-offs, roaming etc, but I was pretty disappointed to see that it was all done with quite basic data structures and algorithms. The most interesting part I found was the code keeping track of roaming subscribers currently in the system. It consisted of one thousand binary trees, where the last three digits of the subscriber number determined which tree a given subscriber belonged to. To find a subscriber, you picked the tree based on the last three digits of the number, then traversed the tree to find the subscriber. Apart from that, it was pretty much only linked lists or simpler.</p>
<h5>1. Complexity from Aggregation</h5>
<p>So, given that there were no clever algorithms in use, and that the whole application was only using pretty basic data structures, it seemed at first that there wouldn&#8217;t be many challenges working on the system. Wrong! I quickly realized that the system is hugely complicated, not with complicated features, but in having lots and lots of simple features aggregated together. This is something I have seen in all systems I have worked with. Most features are dead simple, but because there are so many of them, you get subtle (or not so subtle) interactions between them causing bugs. The complexity of the system comes from the aggregation of many simple parts, not from any complex parts.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/henrikwarne1.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/henrikwarne1.wordpress.com/391/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=henrikwarne.com&#038;blog=27679227&#038;post=391&#038;subd=henrikwarne1&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://henrikwarne.com/2012/08/22/top-5-surprises-when-starting-out-as-a-software-developer/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/a96dd0afc13b56a4a965eca289973c8f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">henrikw1</media:title>
		</media:content>
	</item>
	</channel>
</rss>
