<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>The Inquisitive Coder - Davy Brion's Blog</title> <link>http://davybrion.com/blog</link> <description>inquisitive: adjective. given to inquiry, research, or asking questions; eager for knowledge; intellectually curious</description> <lastBuildDate>Sun, 29 Jan 2012 10:48:12 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/davybrion" /><feedburner:info uri="davybrion" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>davybrion</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><title>(Ab)Using Conventions To Enforce Good Practices</title><link>http://feedproxy.google.com/~r/davybrion/~3/flTvNIlkmus/</link> <comments>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/#comments</comments> <pubDate>Thu, 26 Jan 2012 19:15:29 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3886</guid> <description><![CDATA[I always tell people to explicitly specify the lengths of their string properties in their NHibernate mappings for performance reasons. If you don't specify them, the ADO.NET parameter lengths of those strings will always be set to the length of the actual string value that's been assigned to the parameter. This is a problem for [...]]]></description> <content:encoded><![CDATA[<p>I always tell people to explicitly specify the lengths of their string properties in their NHibernate mappings for performance reasons. If you don't specify them, the ADO.NET parameter lengths of those strings will always be set to the length of the actual string value that's been assigned to the parameter. This is a problem for SQL Server, because it can't cache those statements as efficiently as it would if the parameter lengths were always the same for a given statement. Simply put, if you don't specify the lengths, SQL Server's statement cache gets polluted with a bunch of statements that are often the same, but they're considered to be different simply because of the lengths of those string parameters. And this can really hurt the performance of your application.</p><p>Of course, not everyone remembers to set those lengths, so I thought it'd be great if I could force people to do this. With a little creative use of Fluent NHibernate's conventions, it's quite easy to enforce this:</p><div><pre class="brush: csharp; title: ; notranslate">
public class StringsMustHaveLengthConvention: IPropertyConvention, IPropertyConventionAcceptance
{
    public void Apply(IPropertyInstance instance)
    {
        var msg = string.Format(&quot;The string property '{0}' of type '{1}' does not have a length value specified, &quot; +
            &quot;which is required for performance reasons. Add something like this to your mapping override:\r\n&quot; + 
            &quot;\tmapping.Map(e =&gt; e.{0}).Length(50); // with an appropriate length for this property&quot;,
            instance.Property.Name, instance.EntityType.Name);

        throw new MappingException(msg);
    }

    public void Accept(IAcceptanceCriteria&lt;IPropertyInspector&gt; criteria)
    {
        criteria.Expect(x =&gt; x.Type == typeof(string)).Expect(x =&gt; x.Length == 0);
    }
}
</pre></div><p>With that convention in place, you won't even be able to run your code until you've specified the string lengths <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=flTvNIlkmus:vbJ3YxaBVC4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=flTvNIlkmus:vbJ3YxaBVC4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=flTvNIlkmus:vbJ3YxaBVC4:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/flTvNIlkmus" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/feed/</wfw:commentRss> <slash:comments>12</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/</feedburner:origLink></item> <item><title>Stop Storing Passwords Already!</title><link>http://feedproxy.google.com/~r/davybrion/~3/bskd34YcIcg/</link> <comments>http://davybrion.com/blog/2012/01/stop-storing-passwords-already/#comments</comments> <pubDate>Mon, 23 Jan 2012 20:53:51 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[security]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3882</guid> <description><![CDATA[This is largely common sense already, but I still frequently run into people who don't know how dangerous this is or how to properly store user credentials. The many Anonymous hacks in the past year that resulted in the leaking of users' passwords also show that many sites still store passwords in either clear-text or [...]]]></description> <content:encoded><![CDATA[<p>This is largely common sense already, but I still frequently run into people who don't know how dangerous this is or how to properly store user credentials. The many Anonymous hacks in the past year that resulted in the leaking of users' passwords also show that many sites still store passwords in either clear-text or encrypted form. It's actually quite simple to store credentials safely, so here's a quick recap and example.</p><p>The biggest issue with storing passwords is that you have to assume that it's always possible that someone can get access to your database. Yes, even if it's not directly exposed to the outside world, which it <strong>never</strong> should be. Whatever security measures you've put in place to protect your database, it's a good idea to assume that sooner or later, someone will be able to punch a hole through your security measures and be able to read the data. So obviously, you really don't want to store clear-text passwords. You also don't want to store encrypted passwords because encrypted data can always be decrypted. And if people get access to those encrypted passwords even if they weren't supposed to, it'd be wise to assume that they also know how to decrypt them, or that it won't take them long to figure it out.</p><p>A much better approach is to store a hashed representation of the password instead, using a strong one-way cryptographic algorithm and a <strong>unique</strong> salt value per password. If the cryptographic algorithm is one-way, it means you can't apply another algorithm to get the original source value again. The only way to compare passwords is to apply the cryptographic algorithm on a given password using the originally used salt value, and then compare the resulting hash with the one you've stored. If they are identical, the given password is the same as the one that was used originally. If they differ, the password is invalid.</p><p>Attackers can still employ <a
href="http://en.wikipedia.org/wiki/Rainbow_table">rainbow tables</a> to try to find password values that generate the same hashes as the ones in your database. Luckily, generating rainbow tables takes time and plenty of space as well so it makes it much harder for attackers to find the passwords. This is why it's so important to use a unique salt value per password. It effectively means that a rainbow table would have to be generated for every single salt value that you've used, making it practically infeasible to find the original password values.</p><p>Let's demonstrate this with a simple example. The example is from a Node.js application, but this technique can be applied with whatever technology stack you're using.</p><p>This is my User model:</p><div><pre class="brush: jscript; title: ; notranslate">
var mongoose = require('mongoose'),
    crypto = require('crypto'),
    uuid = require('node-uuid'),
    Schema = mongoose.Schema,
    ObjectId = Schema.ObjectId;

var userSchema = new Schema({
    name: { type: String, required: true, unique: true },
    email: { type: String, required: true },
    salt: { type: String, required: true, default: uuid.v1 },
    passwdHash: { type: String, required: true }
});

var hash = function(passwd, salt) {
    return crypto.createHmac('sha256', salt).update(passwd).digest('hex');
};

userSchema.methods.setPassword = function(passwordString) {
    this.passwdHash = hash(passwordString, this.salt);
};

userSchema.methods.isValidPassword = function(passwordString) {
    return this.passwdHash === hash(passwordString, this.salt);
};

mongoose.model('User', userSchema);
module.exports = mongoose.model('User');
</pre></div><p>Notice that the salt property of my User type has its default value set to 'uuid.v1'. In this case, uuid.v1 is a function which will be invoked by Mongoose whenever a new User instance is created. Every User instance will thus have a UUID value stored in its salt property. You can also see that I'm not storing the given passwordString in the setPassword function, but that I calculate the hash value based on the passwordString and the UUID salt value.</p><p>Suppose I create a user with the following code:</p><div><pre class="brush: jscript; title: ; notranslate">
var user = new User({
    name: 'test_user',
    email: 'blah'
});
user.setPassword('test');

user.save(function(err, result) {
    if (err) throw err;
}); 
</pre></div><p>Its database representation will look like this:</p><div><pre class="brush: jscript; title: ; notranslate">
{ 
    &quot;passwdHash&quot; : &quot;b604367796274cf64177eec345532fc6ca66c6f0501906f82bb03f7916265e9d&quot;, 
    &quot;name&quot; : &quot;test_user&quot;, 
    &quot;email&quot; : &quot;blah&quot;, 
    &quot;_id&quot; : ObjectId(&quot;4f1dbb2cfa6157b118000001&quot;), 
    &quot;salt&quot; : &quot;304a33f0-45fc-11e1-80d2-43c594a44fa0&quot; 
}
</pre></div><p>If an attacker would get access to this, he'd have to generate a rainbow table using the salt value, which takes time, and even then he has no guarantee that the rainbow table will actually contain the correct password. Again, this is why it's so important to use a unique salt for every password. Also, you can use whatever value you want as the salt value so if you can determine it based on some other fields or by using a specific formula you don't need to store the actual salt value. It's recommended to use a long salt value though. Theoretically speaking, it's safer if the salt value isn't stored so clearly as I'm doing here, but even with the salt value clearly visible to a possible attacker, it would still be practically infeasible for him to generate all those rainbow tables.</p><p>And of course, my actual authentication function is still very simple as well:</p><div><pre class="brush: jscript; title: ; notranslate">
var authenticate = function(username, password, callback) {
    User.findOne({ name: username }, function(err, user) {
        if (err) return callback(new Error('User not found'));
        if (user.isValidPassword(password)) return callback(null, user);
        return callback(new Error('Invalid password'));
    });
};
</pre></div><p>So as you can see, there's nothing hard or complicated about storing credentials in a secure manner. It's quite easy to do so and there are no downsides to doing this.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=bskd34YcIcg:SBOcMlCO2Xo:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=bskd34YcIcg:SBOcMlCO2Xo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=bskd34YcIcg:SBOcMlCO2Xo:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/bskd34YcIcg" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/stop-storing-passwords-already/feed/</wfw:commentRss> <slash:comments>16</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/01/stop-storing-passwords-already/</feedburner:origLink></item> <item><title>How Do You Pick Open Source Libraries?</title><link>http://feedproxy.google.com/~r/davybrion/~3/4BpBYXj8pYY/</link> <comments>http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/#comments</comments> <pubDate>Mon, 16 Jan 2012 21:15:40 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[Software Development]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3875</guid> <description><![CDATA[I'm currently looking into which library I'm going to use to handle authentication in a breakable toy project. Now, despite it being just a breakable toy, I want to do it with as few constraints on technical quality as possible because I want to maximize the learning experience I'm going to get from it. That [...]]]></description> <content:encoded><![CDATA[<p>I'm currently looking into which library I'm going to use to handle authentication in a breakable toy project. Now, despite it being just a breakable toy, I want to do it with as few constraints on technical quality as possible because I want to maximize the learning experience I'm going to get from it. That means I don't just want to quickly put something together that just works. I want something that works, but that would also hold up in real world scenarios, even though the project will at best only be used by myself. Which means that I'm going to be picky about any libraries that I take a dependency on, just as I would if this were a project that I'd be getting paid to work on.</p><p>So as I was browsing through a few possible alternatives for my authentication needs, I started thinking about my thought process when evaluating libraries/frameworks to use. I generally base my decision on the following items, listed in order of importance (to me):</p><ul><li><strong>How well does it work for my scenario?</strong> If a library satisfies all other items on this list, that certainly doesn't mean it's an automatic lock. How it works and the impact it has on my code is definitely the most important factor.</li><li><strong>Popularity</strong>. I've noticed that I let the number of watchers/forks on sites like Github influence my opinion. If a project has many watchers and many forks, odds are high that there's a relatively large group of happy users as well as people involved with the project. It also increases the odds that the project will be around for a while. Of course, inactive Open Source projects often remain available as well but if nobody's working on it, I'm not exactly tempted to take a dependency on it. Log4net is a notable exception to this, obviously. But when a project has a lot of people interested in it, or better yet, contributing to it, it's a good sign that you'll easily get help if needed, it's only going to get better in the long run and that it might get forked should the original developers stop working on it. As the author of an Open Source project that doesn't have a lot of watchers/forks (<a
href="https://github.com/davybrion/Agatha">Agatha</a>), I'm aware that my point of view on this is rather hypocritical but hey, it is what it is.</li><li><strong>Code quality</strong>. I don't have the time to do an in-depth review of the code as I'm sure most of us don't do either. But I do like to glance over the code to get a general feel of the quality of the code. I focus mostly on the clarity of the code and also keep an eye open for sloppiness or downright WTF's. I guess the questions I'm mostly trying to answer when doing this are: "is this code I'd like to try to improve or fix if I need to?" and "how easy would it be to debug this when I need to troubleshoot some non-obvious issues?".</li><li><strong>Location of code and issue tracker</strong>. A lot of people will probably take issue with this, but I consider it to be a major plus if the project is on Github. Not just because of my personal preference of Github, but because they truly encourage people to collaborate and contribute to projects and they make it very easy to do so. Also, the site is fast! I cringe when I have to look over issues of projects on Codeplex because it's just terribly slow. And the UI doesn't come close to that of Github either. I've heard that Bitbucket is pretty similar to Github, but I've never even looked for projects there. In any case: I want to be able to download the <em>latest</em> version of the code at any time, or of a particular branch if I need to, as easily as possible. I also prefer an issue tracker which is fast, responsive and easy to search. It doesn't have to be Github, but those 2 requirements are important to me.</li><li><strong>License</strong>. If it's GPL, I don't use it. Also, I check whether or not a commercial license needs to be purchased when you want to use the library/framework in production. Pay attention to dual-licensed projects because that Open Source license might not apply to commercial/production use!</li></ul><p>I'd love to hear your thoughts on this. Did I miss any important factors? I just quickly put this post together so it's likely that I missed some good ones <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=4BpBYXj8pYY:lkkPo1JSHCM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=4BpBYXj8pYY:lkkPo1JSHCM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=4BpBYXj8pYY:lkkPo1JSHCM:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/4BpBYXj8pYY" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/feed/</wfw:commentRss> <slash:comments>22</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/</feedburner:origLink></item> <item><title>Hosting A Node.js Site Through Apache</title><link>http://feedproxy.google.com/~r/davybrion/~3/r3DqhWiU0Qc/</link> <comments>http://davybrion.com/blog/2012/01/hosting-a-node-js-site-through-apache/#comments</comments> <pubDate>Sun, 15 Jan 2012 14:23:09 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[node.js]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3869</guid> <description><![CDATA[I recently lost some time trying to figure out how to host a Node.js site through Apache, so I figured I might as well write a post about how I got it working. Of course, this approach only makes sense if you already have a server that's running Apache and you want to add your [...]]]></description> <content:encoded><![CDATA[<p>I recently lost some time trying to figure out how to host a Node.js site through Apache, so I figured I might as well write a post about how I got it working. Of course, this approach only makes sense if you already have a server that's running Apache and you want to add your Node.js site with minimal impact/changes on your server. If you're not using Apache already but just want to publish a Node.js site, you're better off using Node.js to host it directly, or to put Nginx in front of it since it's more lightweight than Apache. But anyways, here's how you get it working with Apache.</p><p>First of all, you need a way to start your Node.js process automatically when your system boots, and to shut it down when the system is shut down. This will depend on the type of server you're running on. In my case, it's a Debian server so I just went with the <a
href="https://github.com/nicokaiser/node-monit/tree/master/init.d" target="_blank">sysv init script from Nico Kaiser</a>. Another popular alternative is the upstart utility, which is already preinstalled if you're using Ubuntu. Once you have a start|stop|restart script in place, you'll want something to monitor the Node.js process to restart it in case it goes down. An easy to use tool for this is <a
href="http://mmonit.com/monit/" target="_blank">monit</a>. Nico Kaiser again has a good example script available for Node.js on <a
href="https://github.com/nicokaiser/node-monit/tree/master/monit/conf.d" target="_blank">Github</a>.</p><p>Once you have your sysv init or upstart script in place, as well as monit, your Node.js process can stay running on your server. Of course, you probably have it set to listen to connections on some other port than port 80 because that's what your Apache server is listening on. So now, the only thing you have to do is configure Apache to proxy all requests coming in on port 80 through the URL of your Node.js site to your local Node.js process. You'll first need to install <a
href="http://httpd.apache.org/docs/2.1/mod/mod_proxy.html" target="_blank">mod_proxy</a> and <a
href="http://httpd.apache.org/docs/2.0/mod/mod_proxy_http.html" target="_blank">mod_proxy_http</a>. After that, the configuration to make it work is quite easy:</p><div><pre class="brush: xml; title: ; notranslate">
&lt;VirtualHost 109.74.199.47:80&gt;
    ServerAdmin davy.brion@thatextramile.be
    ServerName thatextramile.be
    ServerAlias www.thatextramile.be

    ProxyRequests off

    &lt;Proxy *&gt;
        Order deny,allow
        Allow from all
    &lt;/Proxy&gt;

    &lt;Location /&gt;
        ProxyPass http://localhost:3000/
        ProxyPassReverse http://localhost:3000/
    &lt;/Location&gt;
&lt;/VirtualHost&gt;
</pre></div><p>And that's it. Every request coming in at http://thatextramile.be or http://www.thatextramile.be will be forwarded to http://localhost:3000 where Node.js is listening. Note that the ProxyPassReverse is required to make sure that all HTTP response headers will contain the proxied URL instead of the real one (localhost).</p><p>If you need the raw throughput that Node.js offers, this solution is far from optimal. Every request that comes in through Apache will cause an Apache thread to wait/block until the response is returned from your Node.js process. This is essentially the same as when hosting PHP or Ruby through Apache, so it's not a problem, but it does take away one of the benefits of using Node.js. Again, this approach only makes sense if you're already using Apache to host other sites and you just want to add a Node.js site with minimal impact to your server.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r3DqhWiU0Qc:NjNpppKhXMI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r3DqhWiU0Qc:NjNpppKhXMI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r3DqhWiU0Qc:NjNpppKhXMI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/r3DqhWiU0Qc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/hosting-a-node-js-site-through-apache/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/01/hosting-a-node-js-site-through-apache/</feedburner:origLink></item> <item><title>Company Website Finally Online</title><link>http://feedproxy.google.com/~r/davybrion/~3/r-HQC-l9-nk/</link> <comments>http://davybrion.com/blog/2012/01/company-website-finally-online/#comments</comments> <pubDate>Sun, 15 Jan 2012 09:39:19 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Off Topic]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3852</guid> <description><![CDATA[I finally got around to putting my new company website online. I originally planned to do this sometime last year, but it just kept getting postponed for a variety of reasons. I'm pretty bad at graphic/web design so I had the design done by Ken Bekaert since I thought he had already done a great [...]]]></description> <content:encoded><![CDATA[<p>I finally got around to putting my new <a
href="http://thatextramile.be" target="_blank">company website</a> online. I originally planned to do this sometime last year, but it just kept getting postponed for a variety of reasons. I'm pretty bad at graphic/web design so I had the design done by <a
href="http://frozenyogurt.be/" target="_blank">Ken Bekaert</a> since I thought he had already done a great job on my <a
href="http://twitpic.com/5zgm99" target="_blank">logo and business cards</a>. Next up was the slicing of the design to HTML and CSS. I could theoretically do that myself, but it would've taken me way too long and I would not have enjoyed it one bit, so I preferred to have it done by some old <a
href="http://nivario.be/" target="_blank">friends who know what they're doing</a>. After that, it was finally my turn to play around with it <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>So of course, I couldn't resist doing the site with Express/Node.js. And I'm pretty happy with the result too: about <a
href="https://github.com/davybrion/companysite/tree/master/lib" target="_blank">130 lines of server-side code</a> that allows me to write the content of the site in Markdown (including caching and automatically updating the cache if the Markdown files are updated) and my <a
href="http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/" target="_blank">preferred solution to displaying feed items</a>. Does a simple site like this call for Express/Node.js? Of course not. But I knew it would be simple and fun, so that's why I used it.</p><p>The hardest part was actually writing the content of the site. Apparently, writing content for a company website is a lot harder than churning out a few blog posts occasionally, and I definitely underestimated that. Not because there's a lot of content (there's very little actually), but because you want to <em>avoid</em> ending up with a lot of content. It has to be concise and yet still contain everything you want it to say. After many revisions, it says everything I want it to say, and unlike on this blog I actually managed to keep it short <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>An extra benefit of doing it with Express/Node.js is that it reminded me how much fun I have working with that stack, so I'm going to get back to work on my <a
href="https://github.com/davybrion/therabbithole" target="_blank">breakable toy</a> which I've been neglecting for too long. I suppose this will lead to a few future posts as well <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r-HQC-l9-nk:LXDSSiTB9kI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r-HQC-l9-nk:LXDSSiTB9kI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r-HQC-l9-nk:LXDSSiTB9kI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/r-HQC-l9-nk" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/company-website-finally-online/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/01/company-website-finally-online/</feedburner:origLink></item> <item><title>Looking Back On 2011</title><link>http://feedproxy.google.com/~r/davybrion/~3/kthPy9_wMg0/</link> <comments>http://davybrion.com/blog/2011/12/looking-back-on-2011/#comments</comments> <pubDate>Mon, 26 Dec 2011 19:43:09 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Off Topic]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3848</guid> <description><![CDATA[This was my first year working as an independent, and it's been quite a year. Things have gone very well, and I'm amazed at how quickly it all went by. This time last year, I was looking forward to start working for my first client though I didn't quite know what to expect. I hoped [...]]]></description> <content:encoded><![CDATA[<p>This was my first year working as an independent, and it's been quite a year. Things have gone very well, and I'm amazed at how quickly it all went by. This time last year, I was looking forward to start working for my first client though I didn't quite know what to expect. I hoped it would be interesting, and it certainly has been. I've been able to work with interesting technologies, with the kind of technical variety that I've come to really enjoy. I wrote more code in JavaScript than in C# this year, and I've also been able to do quite a bit of Ruby as well. I certainly didn't expect that going into this contract, so that was a major bonus. Even better than the technologies I've been able to work with this year are the people I've worked with. The team I've worked with has a fantastic mix of experience, knowledge and talent and it feels like all of us continuously learn new things from each other which is a situation I can only recommend to every developer.</p><p>Another great part about being independent is that you're free to do extra things on the side as well. I'm very happy with the responses that I've gotten from the people who've taken my <a
href="http://thatextramile.be/training/nhibernate">NHibernate course</a>, and I'm going to continue to offer it in 2012. I initially thought it would be something I'd do once or twice, but I was able to do the course 4 times this year: 1 public and 3 private ones. I've got another private one scheduled in February and will organize another public course in 2012, though this time I'm taking care of the whole thing myself instead of working with another company to organize it.</p><p>The most important thing I've learned from this first year is that it's important not to try to do too much. The first 6 months of 2011 were way too busy and hectic, and I only spent one full day doing absolutely nothing work-related. I've been taking things much slower since July and I'm spending much more time enjoying other things in life outside of work. For 2012, my biggest priority is pacing myself much better and spreading things out more. I always seem to alternate between months where I'm always working on something, followed by months of doing as little as possible outside of the 40 hours a week I do for my client. Hopefully, I can finally find a maintainable balance between those two extremes in 2012 <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>On the blogging front, 2011 was a different year than the previous ones on this blog. In the previous years, I averaged about 150 posts a year but this year I only published 71 posts. And I'm actually happy about that. In fact, I hope to get that number down to 50 next year. I still like writing posts, but I no longer feel the need to like I did in the past while I was trying to build a bit of an audience. That often meant pushing myself to keep publishing new posts. Nowadays, I'll only write a post if I really feel like it, which in the long run is much more sustainable anyway. As far as topics covered this year, things have changed quite a bit as well. Some of my views, opinions and technical preferences have changed this year, which naturally reflects in the content I've published. I'm sure I've lost some readers this year because of it, but I also seem to have gained a lot more readers than I've lost. I don't know yet what I'll be writing about in 2012, but I will continue to push people to learn new things (or old things that people seem to forget about) and do better like I always have on this blog, in my own unique way of course <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>I hope you all enjoyed Christmas, and I wish you all a happy 2012. If it does turn out to be our last year on this planet, we might as well make it count.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=kthPy9_wMg0:graD7mYys-A:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=kthPy9_wMg0:graD7mYys-A:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=kthPy9_wMg0:graD7mYys-A:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/kthPy9_wMg0" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/looking-back-on-2011/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/12/looking-back-on-2011/</feedburner:origLink></item> <item><title>Displaying Feed Items On A Web Page: My Solution</title><link>http://feedproxy.google.com/~r/davybrion/~3/YOg6tZlA7JI/</link> <comments>http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/#comments</comments> <pubDate>Tue, 20 Dec 2011 07:00:55 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[express.js]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[node.js]]></category> <category><![CDATA[Performance]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3830</guid> <description><![CDATA[A couple of days ago I asked you how you'd implement showing links from an RSS feed on a web page (in this case: my new company web site). These are my requirements for this: It needs to be fast The fewer requests that are impacted by retrieving the feed data, the better If I [...]]]></description> <content:encoded><![CDATA[<p>A couple of days ago I <a
href="http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/">asked you</a> how you'd implement showing links from an RSS feed on a web page (in this case: my new company web site). These are my requirements for this:</p><ul><li>It needs to be <strong>fast</strong></li><li>The fewer requests that are impacted by retrieving the feed data, the better</li><li>If I publish a post, the links on the company website should contain the new link within 30 minutes</li><li>The simpler the solution, the better</li></ul><p>I came up with a very simple solution, which satisfies these requirements better than any other solution I could think of, or heard of from other people. It is extremely fast, doesn't delay any requests, and doesn't require me to deploy anything but the company website. I'm building the site with <a
href="http://expressjs.com/">Express</a> on <a
href="http://nodejs.org/">Node.js</a>, which means I can take full advantage of the asynchronous nature of Node.js to implement this.</p><p>Let's go over the code... in the script that starts the express server, I have the following code:</p><div><pre class="brush: jscript; title: ; notranslate">
var express = require('express'),
    app = module.exports = express.createServer(),
    NodePie = require('nodepie'),
    request = require('request'),
    recentFeedItems = null;

app.dynamicHelpers({
    getRecentFeedItems: function() {
        return recentFeedItems;
    }
});

// ... some extra configuration of Express that isn't relevant to this post

var processFeed = function(callback) {
    request('http://feeds.feedburner.com/davybrion', function(err, response, body) {
        if (!err &amp;&amp; response.statusCode == 200) {
            var feed = new NodePie(body);
            feed.init();
            recentFeedItems = feed.getItems(0, 5);
            if (callback) callback();
        };
    }); 
};

setInterval(processFeed, 1800000); // process feed items every 30 minutes

processFeed(function() {
    app.listen(3000);
    console.log('Express started on port 3000');    
});
</pre></div><p>I'll discuss the code in just a moment, but first I want to show the view code that renders the links:</p><div><pre class="brush: xml; title: ; notranslate">
&lt;ul&gt;
&lt;% getRecentFeedItems.forEach(function(item) { %&gt;
    &lt;li&gt;&lt;time class=&quot;date&quot;&gt;&lt;%= item.getDate().getDate() + '/' + (item.getDate().getMonth() + 1) %&gt;&lt;/time&gt;&lt;a href=&quot;&lt;%= item.getPermalink() %&gt;&quot;&gt;&lt;%= item.getTitle() %&gt;&lt;/a&gt;&lt;/li&gt;
&lt;% }); %&gt;
&lt;/ul&gt;
</pre></div><p>And that's all. This is the solution in its entirety!</p><p>If you're new to Node, this code probably requires some explanation. Let's start with this part:</p><div><pre class="brush: jscript; title: ; notranslate">
app.dynamicHelpers({
    getRecentFeedItems: function() {
        return recentFeedItems;
    }
});
</pre></div><p>Here I'm adding a dynamic helper to the Express application. It basically means that my views have access to the getRecentFeedItems function, which returns the value of the recentFeedItems variable. It's important to know that the getRecentFeedItems function creates a closure on the recentFeedItems variable created above it. That means that if the value of the recentFeedItems variable changes at any point in time, the getRecentFeedItems function will return that new value.</p><div><pre class="brush: jscript; title: ; notranslate">
var processFeed = function(callback) {
    request('http://feeds.feedburner.com/davybrion', function(err, response, body) {
        if (!err &amp;&amp; response.statusCode == 200) {
            var feed = new NodePie(body);
            feed.init();
            recentFeedItems = feed.getItems(0, 5);
            if (callback) callback();
        };
    }); 
};
</pre></div><p>This just creates a function that we can use later on. It retrieves the feed asynchronously, and when the result is retrieved, we parse the feed using the NodePie library and we get the 5 most recent items which we store in the recentFeedItems variable. Again, this creates a closure on the recentFeedItems variable which means that every time we assign a value to this variable, any subsequent call to the getRecentFeedItems function will return the value we just assigned to it because both functions point to the same memory thanks to the magic of closures. Finally, if a callback is provided as a parameter, the callback will be invoked.</p><div><pre class="brush: jscript; title: ; notranslate">
setInterval(processFeed, 1800000); // process feed items every 30 minutes

processFeed(function() {
    app.listen(3000);
    console.log('Express started on port 3000');    
});
</pre></div><p>The call to setInterval makes sure that the processFeed function is called every 30 minutes. After that, we call the processFeed function manually, and we pass in a callback where we start the Express server. This guarantees that the feed items will be in memory before the server starts processing requests.</p><p>What makes this solution so great is that we take full advantage of some of Node's benefits. Whenever we retrieve the RSS feed, Node.JS will retrieve that data asynchronously. As soon as it has fired the request to get the RSS feed, it just goes to the next event in its eventloop so no request is kept waiting while we wait for the data to be downloaded. Until the data from the RSS feed is returned, each request will just use the items that are stored in the recentFeedItems variable. Once the data has been returned, our callback is executed which overwrites the value of the recentFeedItems variable. We don't need to do any locking here because the Node.JS eventloop is single-threaded: while our callback is running, no other code that has access to the recentFeedItems variable can be executed anyway. And the actual parsing of the RSS feed is done by NodePie, which uses <a
href="http://expat.sourceforge.net/">expat</a> behind the scenes, which is supposedly the fastest C XML parser available.</p><p>Looking back on my initial requirements, I think this solution matches very well.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=YOg6tZlA7JI:EHTJxGRSvX8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=YOg6tZlA7JI:EHTJxGRSvX8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=YOg6tZlA7JI:EHTJxGRSvX8:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/YOg6tZlA7JI" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/feed/</wfw:commentRss> <slash:comments>7</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/</feedburner:origLink></item> <item><title>Node.js For Dummies</title><link>http://feedproxy.google.com/~r/davybrion/~3/AsPaZvBN6HA/</link> <comments>http://davybrion.com/blog/2011/12/node-js-for-dummies/#comments</comments> <pubDate>Sun, 18 Dec 2011 17:40:39 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[node.js]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3838</guid> <description><![CDATA[I'm sure you've all heard of Node.js by now. Its popularity is increasing rapidly, which means it's a good idea to be aware of what Node.js is and especially how it differs from more traditional technology stacks. In this post, I'll try to give an easy-to-understand overview of what makes Node.js different and make it [...]]]></description> <content:encoded><![CDATA[<p>I'm sure you've all heard of Node.js by now. Its popularity is increasing rapidly, which means it's a good idea to be aware of what Node.js is and especially how it differs from more traditional technology stacks. In this post, I'll try to give an easy-to-understand overview of what makes Node.js different and make it clear that it's more than just server-side JavaScript. Note that this overview is highly simplified and only meant to help people understand how Node.js works. This is definitely not a completely accurate description of the lower-level details of Node.js.</p><h2>Evented/Asynchronous I/O</h2><p>In most technology stacks, API calls for I/O operations are synchronous. As in, the thread that executes the operation is blocked for the duration of the I/O operation until that operation has completed. Once completed, execution of your code proceeds. Of course, a lot of technology stacks have asynchronous variants of those operations available as well, but generally speaking, they aren't used as often as the synchronous variants. In Node.js, it's the other way around. All I/O operations are asynchronous and there are only a few synchronous implementations available (and you're generally discouraged from using them).</p><p>This means that whenever you do an I/O operation (file manipulation, network requests, database operations, etc…), Node.js initiates the I/O operation through a lower-level C/C++ layer which will perform the operation asynchronously. Once the operation has completed, Node.js will execute your callback function that you passed as a parameter to the I/O operation's function call. The important thing here is that while the I/O operation is being executed, Node.js doesn't have to wait for the operation to complete, and is able to focus entirely on processing other events. And those events can be anything: incoming network requests, executing callbacks from other operations that have completed, or invoking whatever function that is assigned to a particular event.</p><h2>Eventloop</h2><p>The Node.js eventloop is what makes Node.js so interesting and powerful. Node.js basically just keeps reading from an event queue until that queue is empty. As it loops through the events to be processed, it invokes the JavaScript functions that have been assigned for those events. If any of those functions performs an I/O operation, Node.js will initiate the operation and then immediately move to the next event in the event queue. Once the I/O operation has completed, an event will be added to the event queue with a reference to your original callback. Once all preceding events have been processed, Node.js will get to the newly added event and invoke your callback. Because all I/O operations are asynchronous, this enables Node.js to maximize its efficiency as it processes events because it doesn't need to wait for slow I/O operations to complete.</p><h2>Single-threaded</h2><p>One thing that people don't always realize is that the Node.js eventloop is single-threaded. This has some nice benefits but there's a huge drawback as well. The biggest benefit is that you don't need to worry about concurrent access to shared state. After all, there is never more than 1 thread executing your JavaScript functions. This means you don't have to write any locking code to protect shared state. The drawback to the single-threaded eventloop is that you need to be careful not to block the event loop. If you're planning on doing heavy synchronous processing in your JavaScript code, you need to realize that no other events can be processed by Node.js until that synchronous block of code has completed. Obviously, since there's only one thread going through the eventloop, any delay you cause in your code can be very costly to overall throughput and performance. For now, it's best to execute synchronous processing routines as a child process, possibly even in a language that is more suitable for this than JavaScript. But it seems that future Node.js versions will provide a more integrated way to deal with this.</p><h2>Why JavaScript?</h2><p>JavaScript's support of closures and it treating functions as first class objects means it's ideally suited for the evented programming model that Node.js offers. Many people still think of JavaScript as a joke or a toy language, but it's a lot more powerful than many people think it is. Yes, it certainly has problems as well, but it's definitely worth learning. I do hope that this post has made it clear that there's a lot more to Node.js than simply being server-side JavaScript. What makes Node.js so interesting are the principles that I've tried to explain in this post. Those principles can be implemented with other languages as well, and could be made to work just as great as, or perhaps even greater than Node.js itself. But you'd be hard-pressed to find a language that's so ubiquitous, yet completely devoid of a pre-existing synchronous I/O infrastructure.</p><p>Anyways, I hope I succeeded at making it somewhat clear how Node.js works and why it's so different from most other technology stacks.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=AsPaZvBN6HA:0t_GLmgkIK8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=AsPaZvBN6HA:0t_GLmgkIK8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=AsPaZvBN6HA:0t_GLmgkIK8:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/AsPaZvBN6HA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/node-js-for-dummies/feed/</wfw:commentRss> <slash:comments>14</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/12/node-js-for-dummies/</feedburner:origLink></item> <item><title>Challenge: Displaying Feed Items On A Web Page</title><link>http://feedproxy.google.com/~r/davybrion/~3/Awt1njA8rQU/</link> <comments>http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/#comments</comments> <pubDate>Sat, 17 Dec 2011 15:17:41 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3822</guid> <description><![CDATA[I'm finally getting around to implementing the website for my company, and there's one small part of it that's quite interesting from an implementation point of view. The website will have a footer on each page which displays links to my 5 most recent blog posts: Of course, I don't want to update those links [...]]]></description> <content:encoded><![CDATA[<p>I'm finally getting around to implementing the website for my company, and there's one small part of it that's quite interesting from an implementation point of view. The website will have a footer on each page which displays links to my 5 most recent blog posts:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2011/12/feed_items.png" rel="prettyPhoto[3822]"><img
src="http://davybrion.com/blog/wp-content/uploads/2011/12/feed_items.png" alt="" title="feed_items" width="683" height="402" class="aligncenter size-full wp-image-3823" /></a></p><p>Of course, I don't want to update those links manually whenever I publish a new post, so they need to be retrieved from my blog's RSS feed, which is published by Feedburner. I was hoping to be able to retrieve only the metadata from the posts (date, title and URL is all I need) because my feed always contains the last 20 posts and its total size is usually above 100KB. I haven't found a way to do that, so getting the information I need has to be retrieved through the full feed. Sure, 100KB isn't much but keep in mind that you need to retrieve it and parse it and that I absolutely want to minimize the time each request takes and that I'd rather not see any visual delays on the page either.</p><p>I'm interested in hearing how you would implement this. You have total freedom to pick the technologies you'd like to use and no limits on how you'd use them. My only requirements are these:</p><ul><li>It needs to be <strong>fast</strong></li><li>The fewer requests that are impacted by retrieving the feed data, the better</li><li>If I publish a post, the links on the company website should contain the new link within 30 minutes</li><li>The simpler the solution, the better</li></ul><p>My solution can be found <a
href="http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/">here</a>.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Awt1njA8rQU:7Gti5R8zH_4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Awt1njA8rQU:7Gti5R8zH_4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Awt1njA8rQU:7Gti5R8zH_4:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/Awt1njA8rQU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/feed/</wfw:commentRss> <slash:comments>16</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/</feedburner:origLink></item> <item><title>Blue Pill vs Red Pill</title><link>http://feedproxy.google.com/~r/davybrion/~3/GuuPBMEfmJo/</link> <comments>http://davybrion.com/blog/2011/12/blue-pill-vs-red-pill/#comments</comments> <pubDate>Thu, 15 Dec 2011 20:44:40 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3816</guid> <description><![CDATA[I've been somewhat critical of certain 'hot' MS technologies on Twitter this week. Particularly: Azure, Nuget and Entity Framework, and I didn't even bother to complain about the troubles I've had with the differences between 32-bit and 64-bit Powershell today. And I've noticed that whenever I voice a negative opinion on a Microsoft technology that [...]]]></description> <content:encoded><![CDATA[<p>I've been somewhat critical of certain 'hot' MS technologies on Twitter this week. Particularly: Azure, Nuget and Entity Framework, and I didn't even bother to complain about the troubles I've had with the differences between 32-bit and 64-bit Powershell today. And I've noticed that whenever I voice a negative opinion on a Microsoft technology that is considered cool or great, I lose a few Twitter followers. My reaction to that is: good riddance. I prefer losing a few followers because of it, than having to deal with the responses from certain fanboys who either haven't stepped outside of the MSDN world, or are just trying to impress others with a devotion that they're hoping will increase their status within their organization or within the Microsoft developer community in general.</p><p>A lot of people think that I'm anti-Microsoft. And I'm really not. I'm not anti-anything. I <em>am</em> pro-quality. I have high standards because I've seen and experienced high quality solutions elsewhere and when I have to deal with lower quality alternatives to those solutions, I tend to compare them, which is only natural. If Microsoft releases good stuff, I'm more than happy to use it. I even considered creating an Entity Framework training course, similar to my NHibernate training course, because I was hearing many good things about it. But after trying to deal with a certain Entity Framework problem that came up this week in the one project at work that uses Entity Framework, I couldn't help but think "I don't want this mess in my life, no matter how much money I could make with it". I sincerely <em>want</em> to use good Microsoft technology, but too often it just disappoints me. And that in itself, isn't much of a problem since there are plenty of good Open Source alternatives around. What I do consider to be a problem is the reaction that many people have when you're critical of Microsoft technology.</p><p>I've often compared it to living in The Matrix. A lot of us are living in a world where they are being pushed into believing something that just isn't true. And some of us at some point get to choose between taking the blue pill or the red pill. The blue pill symbolizes blissful ignorance of illusion, while the red pill symbolizes the sometimes painful truth of reality. A lot of developers in the Microsoft world choose to keep their eyes closed and blindly believe whatever Microsoft tells them to believe. They'll run into a variety of problems with the technologies they've been told to use but a lot of people just accept it for what it is because they don't know any better, or because they're scared of the seemingly harsh world that awaits them should they choose to ignore Microsoft's guidance and venture out into a world that is more chaotic, yet offers more possibilities and flexibility. If you take the red pill, you learn a lot about what's really possible yet you face the added burden of having to deal with the people who've picked the blue pill and even worse, the technology that comes with it. Because that truly is the only bad part about taking the red pill. You'll start taking some things for granted, and when faced with technologies that don't quite match up to what you've recently become used to, you will get frustrated because of it. After all, you know things can be done much better with less friction, yet here you are, dealing with problems that have been solved by other libraries/frameworks already. That is the only sour taste you'll experience after having swallowed the red pill.</p><p>The choice between the blue pill or the red pill is one that everyone has to make for themselves. And honestly, I can't be bothered anymore to try to convince people to take the red pill instead of the blue pill. I've learned to adopt a "whatever floats your boat without sinking mine is fine with me" attitude, but sometimes, I can't help but wish for a world were people would try to think just a little bit more for themselves instead of blindly following what a dominant entity is telling them to do or use. Look around, see what other people and communities are doing and honestly ask yourself "are they doing things better than I am?". And if they are, put in the effort to figure out why and how they're doing what they're doing. The worst thing that could possibly happen is a temporarily sour taste, and there are many ways to wash that away.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=GuuPBMEfmJo:HOH0QnBmCbA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=GuuPBMEfmJo:HOH0QnBmCbA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=GuuPBMEfmJo:HOH0QnBmCbA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=GuuPBMEfmJo:HOH0QnBmCbA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=GuuPBMEfmJo:HOH0QnBmCbA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=GuuPBMEfmJo:HOH0QnBmCbA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=GuuPBMEfmJo:HOH0QnBmCbA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=GuuPBMEfmJo:HOH0QnBmCbA:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/GuuPBMEfmJo" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/blue-pill-vs-red-pill/feed/</wfw:commentRss> <slash:comments>36</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/12/blue-pill-vs-red-pill/</feedburner:origLink></item> <item><title>Does Certification Have Any Value?</title><link>http://feedproxy.google.com/~r/davybrion/~3/Cka6yFWxeFQ/</link> <comments>http://davybrion.com/blog/2011/11/does-certification-have-any-value/#comments</comments> <pubDate>Tue, 29 Nov 2011 21:30:21 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3811</guid> <description><![CDATA[Someone asked which certificate would be the better choice on Twitter today: Microsoft Certified Professional or Certified Scrum Master. My answer was very simple: neither because they're both utterly worthless. I've been very skeptical about any kind of software development certification for a couple of years now. More precisely, ever since I passed the ASP.NET [...]]]></description> <content:encoded><![CDATA[<p>Someone asked which certificate would be the better choice on Twitter today: Microsoft Certified Professional or Certified Scrum Master. My answer was very simple: neither because they're both utterly worthless. I've been very skeptical about any kind of software development certification for a couple of years now. More precisely, ever since I passed the ASP.NET WebForms exam with a 90% score even though I hadn't actually done <em>anything</em> with ASP.NET WebForms yet. I hadn't even bothered to do any exercises while preparing for the exam because I knew it just wasn't necessary. All you have to do is read the API documentation, memorize the details that you'd normally Google for and weed out the way-too-obvious bad choices in the multiple choice questioning of the test and that's it: you're certified, congratulations! Of course, you'll forget most of the details that you've memorized and you will not have learned anything really substantial that will serve you well for a long time. You'll certainly not learn anything important about how to develop high quality software or writing high quality code. And that should be rather important to you, no?</p><p>Of course, that doesn't mean that you have to approach it like that as well. You can indeed learn a lot about a certain technology while preparing for a certification exam, but the whole thing is completely devalued by the incredibly large group of people who <em>do</em> game the system and are only in it to add the certificates to their CV, or to demand a higher salary or rates because they are after all <em>certified professionals</em>. Never mind the fact that many of them never even bother to focus on learning fundamental principles that would benefit their careers as well as increasing the value they bring to clients/employers far more than intimate (temporary) knowledge of a specific technology that's probably going to be replaced by something new in about 4 years anyway. To those of you who've taken exams on WPF: how's that working out for you? Still debugging memory leaks I'm sure <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><p>Even though a lot of people know this all too well, they'll still come up with arguments like "but it really helps when clients ask for certificates" or "certificates give me a leg up when clients need to go over tons of CVs". Sorry, but I'm not buying it. Well, I do know that some companies indeed consider certificates a benefit when evaluating candidates but I prefer to look at it from a slightly different angle: those kind of companies often employ people who got their certificates by gaming the system at a much higher rate than companies who don't care about certificates and prefer to focus on real experience and solid knowledge of important fundamentals instead. Simply put: if you choose to work for companies that value certificates, odds are very high that you'll be working with certified idiots.</p><p>If you're wondering whether you should invest time in getting certified, I'd advise a different approach. Don't bother with certifications and spend your time and energy on attaining knowledge that will last you far longer, and will even improve your abilities of quickly picking up new technologies. And the way to do that is pretty simple. Work on hobby projects. Experiment with multiple technologies. Study code from established projects and developers. And read books. Lot's of them even! If you don't know which ones, I've got a good list available <a
href="http://davybrion.com/blog/recommended-books/">here</a> and you might notice that the majority of those books are technology-independent. They focus on fundamental principles and common knowledge that you'll be able to reuse no matter what technology you're using now or will end up using later on.</p><p>Of course, all of this does take more effort than simply showing up for a 2-day course where <em>everybody</em> gets a meaningless piece of paper or spending a weekend cramming API details that you don't actually need to remember to be productive at your job. But hey, if your goal is to improve your value, and not just your perceived status, it's worth it, right?</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=Cka6yFWxeFQ:MxLWkXW9WU8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Cka6yFWxeFQ:MxLWkXW9WU8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Cka6yFWxeFQ:MxLWkXW9WU8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Cka6yFWxeFQ:MxLWkXW9WU8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Cka6yFWxeFQ:MxLWkXW9WU8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Cka6yFWxeFQ:MxLWkXW9WU8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Cka6yFWxeFQ:MxLWkXW9WU8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Cka6yFWxeFQ:MxLWkXW9WU8:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/Cka6yFWxeFQ" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/11/does-certification-have-any-value/feed/</wfw:commentRss> <slash:comments>11</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/11/does-certification-have-any-value/</feedburner:origLink></item> <item><title>Silverlight’s Broken Promise</title><link>http://feedproxy.google.com/~r/davybrion/~3/HKpGyIOPiCE/</link> <comments>http://davybrion.com/blog/2011/11/silverlights-broken-promise/#comments</comments> <pubDate>Sun, 20 Nov 2011 17:31:42 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[Silverlight]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3808</guid> <description><![CDATA[By now, I'm sure you've all read about the rumors that the upcoming Silverlight 5 might be the last release of Silverlight. Of course, people who've been paying attention to the Silverlight news coming out of Microsoft and the blogosphere in the past year shouldn't be surprised at this. But for those of you who [...]]]></description> <content:encoded><![CDATA[<p>By now, I'm sure you've all read about the rumors that the upcoming Silverlight 5 might be the last release of Silverlight. Of course, people who've been paying attention to the Silverlight news coming out of Microsoft and the blogosphere in the past year shouldn't be surprised at this. But for those of you who are still in the "oh please, it's just a rumor" camp, you might want to keep in mind that every negative rumor about Silverlight of the past year has turned out to be true. As a result, I fully expect the upcoming Silverlight 5 release to indeed be the last stop along a troubled line.</p><p>Plenty of Silverlight developers were concerned that their investment in the technology would end up being worthless. I never really understood that since I've always believed that good developers focus on skills that are transferable to multiple technologies instead of betting it all on a single technology. Nevertheless, many Silverlight developers were up in arms, but their worries and fears seem to have been calmed by the news that Windows 8 will make extensive use of XAML. Silverlight developers will be able to transfer their XAML skills to building Metro apps and of course, WP7 apps. And there's no reason to assume that Microsoft intends to change its smartphone platform in a way that would diminish the importance of XAML. So, Silverlight developers who were worried that their skills will be worthless don't really have anything to worry about and I'm sure many of them are quite relieved by that. After all, many Silverlight projects will be able to run as native apps on Windows 8 with relatively minor modifications.</p><p>Of course, that doesn't quite offer a solution to the thorny little issue about all the Silverlight projects that have been developed because of some of the benefits that Silverlight promised: cross platform and browser-independent availability of the plugin. The promise was that you could develop projects that would be available to users no matter what platform or browser that they were using (believers of this promise would even mention Moonlight, which has never really offered a truly compatible version), and with no deployment-related issues. After all, users only needed to have the Silverlight plugin installed to run your software. And that promise has been broken. Yes, you can migrate your Silverlight projects to Windows 8. Yes, people will be able to keep running existing Silverlight projects as long as they have the upcoming Silverlight 5 runtime installed. But we also already know that the Metro version of IE10 will <em>not</em> run the Silverlight plugin and that running the plugin in the 'desktop' version of IE10 will require users to install it themselves. For enterprise software, that's not much of an issue but you do have to ask yourself: how long are you willing to hang on to a plugin that Microsoft itself is no longer interested in improving in the long run?</p><p>The reality of the matter is that your Silverlight products only have a future if you convert them to WinRT so they can run on Metro natively. Which means you've lost the ability to reach users on multiple platforms and devices. The very same technology you picked because of its cross-browser and cross-platform benefits has forced you on a path where in the future, you can only target users on the Windows platform meaning either Windows 8 or WP7. Sure, you can hang on to the fact that the plugin will be available for a few more years, but that also is a limiting choice since an ever increasing number of users will be running iOS and Android, and there's no reason whatsoever to expect the plugin to actually run on those platforms. Hell, WP7 doesn't even have the Silverlight plugin for its browser. My previous employer pretty much bet it all on Silverlight, mostly because they didn't want to deal with HTML/JavaScript, but also because they thought it would eventually be available on all devices. Which essentially means they're stuck with a couple of products that only really have a long-term future on Windows 8 or WP7, and its subsequent versions. Unless of course, current promises about said platforms are broken again. Yet another reason to start taking open standards and technologies that have multiple stakeholders seriously, I suppose.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=HKpGyIOPiCE:7yQOaDMhC9w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=HKpGyIOPiCE:7yQOaDMhC9w:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=HKpGyIOPiCE:7yQOaDMhC9w:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=HKpGyIOPiCE:7yQOaDMhC9w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=HKpGyIOPiCE:7yQOaDMhC9w:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=HKpGyIOPiCE:7yQOaDMhC9w:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=HKpGyIOPiCE:7yQOaDMhC9w:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=HKpGyIOPiCE:7yQOaDMhC9w:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/HKpGyIOPiCE" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/11/silverlights-broken-promise/feed/</wfw:commentRss> <slash:comments>14</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/11/silverlights-broken-promise/</feedburner:origLink></item> <item><title>Faster Hardware? Not On Our Budget!</title><link>http://feedproxy.google.com/~r/davybrion/~3/eOFCZsYl3gs/</link> <comments>http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/#comments</comments> <pubDate>Tue, 08 Nov 2011 22:16:09 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category> <category><![CDATA[work/career]]></category><guid isPermaLink="false">http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/</guid> <description><![CDATA[A lot of developers working in enterprise environments are used to not getting the right hardware that would make them more productive. You know how it goes: Operations likes to 'standardize' the hardware that gets rolled out and in too many cases, no exceptions are made for developers. Which is a shame, really. The simplest, [...]]]></description> <content:encoded><![CDATA[<p>A lot of developers working in enterprise environments are used to not getting the right hardware that would make them more productive. You know how it goes: Operations likes to 'standardize' the hardware that gets rolled out and in too many cases, no exceptions are made for developers. Which is a shame, really.</p><p>The simplest, and probably most effective example is that of giving developers SSD's instead of regular disks. I'm willing to bet that using an SSD instead of a regular disk could save an hour of lost time per day, per developer on average. Suppose the hourly cost of a developer is 80€. Now suppose you have 30 developers in total. That would be waste of 2400€ a day. Now suppose you have to buy 30 SSD's at 300€ each, which would set the company back 9000€.</p><p>That 9000€ investment will have paid itself back after 112,5 man-days, which is only 5 calendar days if you have 30 devs. After those 5 calendar days, the investment starts reducing development costs with 2400€ a day (on average), which for a full year (using 220 working days) could result in a yearly saving of 528000€ for the company.</p><p>Of course, Operations is usually a separate division from those that are responsible for development, which means that they have a separate budget sanctioned for what they need to do. Now suppose that Operations has to spend about 5000€ per year to replace failed SSD's. And lets assume that the yearly support cost for those SSD's is 20000€. I pulled that number out of my ass, which unless I'm mistaken is standard operating procedure whenever an Operations division gives you an estimate of support costs. Anyway, it would mean that on top of the 9000€ investment, a yearly recurrent cost of 25000€ would need to budgetted. And for what? The Operations division can't demonstrate a single benefit for <em>their</em> division to justify the cost.</p><p>Nevermind the fact that the company would save about 500000€ a year...</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=eOFCZsYl3gs:mB5xA96qtfc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=eOFCZsYl3gs:mB5xA96qtfc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=eOFCZsYl3gs:mB5xA96qtfc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=eOFCZsYl3gs:mB5xA96qtfc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=eOFCZsYl3gs:mB5xA96qtfc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=eOFCZsYl3gs:mB5xA96qtfc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=eOFCZsYl3gs:mB5xA96qtfc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=eOFCZsYl3gs:mB5xA96qtfc:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/eOFCZsYl3gs" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/feed/</wfw:commentRss> <slash:comments>9</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/</feedburner:origLink></item> <item><title>This Is Not How You Port Java Code To .NET</title><link>http://feedproxy.google.com/~r/davybrion/~3/T34mBzf0HUU/</link> <comments>http://davybrion.com/blog/2011/11/this-is-not-how-you-port-java-code-to-net/#comments</comments> <pubDate>Wed, 02 Nov 2011 13:06:41 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[What's Wrong With This Picture]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3800</guid> <description /> <content:encoded><![CDATA[<p><a
href="http://davybrion.com/blog/wp-content/uploads/2011/11/porting_java.png" rel="prettyPhoto[3800]"><img
src="http://davybrion.com/blog/wp-content/uploads/2011/11/porting_java.png" alt="" title="porting_java" width="700" height="650" class="aligncenter size-full wp-image-3801" /></a></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=T34mBzf0HUU:_N6DEJzQNHg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=T34mBzf0HUU:_N6DEJzQNHg:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=T34mBzf0HUU:_N6DEJzQNHg:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=T34mBzf0HUU:_N6DEJzQNHg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=T34mBzf0HUU:_N6DEJzQNHg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=T34mBzf0HUU:_N6DEJzQNHg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=T34mBzf0HUU:_N6DEJzQNHg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=T34mBzf0HUU:_N6DEJzQNHg:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/T34mBzf0HUU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/11/this-is-not-how-you-port-java-code-to-net/feed/</wfw:commentRss> <slash:comments>12</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/11/this-is-not-how-you-port-java-code-to-net/</feedburner:origLink></item> <item><title>Thoughts On Steve Jobs, The Book And The Man</title><link>http://feedproxy.google.com/~r/davybrion/~3/EIrgaA1ek_U/</link> <comments>http://davybrion.com/blog/2011/11/thoughts-on-steve-jobs-the-book-and-the-man/#comments</comments> <pubDate>Tue, 01 Nov 2011 17:54:02 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3795</guid> <description><![CDATA[In the tech world, most people have an opinion on Steve Jobs. And in the past couple of years, quite a few people outside of the tech world have learned about Steve Jobs as well due to the success Apple has enjoyed in the consumer space. A lot of those people have formed opinions on [...]]]></description> <content:encoded><![CDATA[<p>In the tech world, most people have an opinion on Steve Jobs. And in the past couple of years, quite a few people outside of the tech world have learned about Steve Jobs as well due to the success Apple has enjoyed in the consumer space. A lot of those people have formed opinions on him as well. And I don't think I'm exaggerating when I say that most people either love him or hate him. He's just been <em>that</em> polarizing over the years. Some people hate him because of his <a
href="http://en.wikipedia.org/wiki/Reality_distortion_field">Reality Distortion Field</a>, his arrogance, his attitude or because of his belief in a closed system where he has full control. Some people love him for the products he's delivered, his vision, his showmanship and well, his Reality Distortion Field.</p><p>Whether you love or hate Steve Jobs, Walter Isaacson's <a
href="http://www.amazon.com/Steve-Jobs-Walter-Isaacson/dp/1451648537/ref=sr_1_1?ie=UTF8&amp;qid=1320165027&amp;sr=8-1">biography on the man</a> is well worth reading. I found it to be a fascinating read, and quite funny at times as well. I was expecting it to have a somewhat balanced view on Job's personality, but the author went way beyond that. He doesn't waste many opportunities to point out a negative reaction by Jobs, which is good. There's no glorification of Jobs, just a balanced and honest view. Another important thing that I highly appreciate is that you often get both sides of the story. You get Jobs' recollections and opinions, as well as those of the people who were involved in the many situations that are covered. And again, differences between those recollections are not ignored.</p><p>Most things are covered in chronological order, from Steve being put up for adoption, to his time in college, to dropping out of college and going to India, to starting Apple, to getting ousted at Apple and starting Next and buying Pixar, to returning to Apple and returning it to prominence, to him getting cancer and eventually resigning from Apple because of it. There are also parts about his personal life and his family, though the majority of the book covers his successes and failures in his professional life.</p><p>For a long time, I thought Steve Jobs was the perfect salesman for what the various teams at Apple were cooking up. I knew he was involved with the product design, but I had no idea he was as involved as he really turned out to be. He was very hands-on in the way he worked with the various product teams, and in many cases he led them based on his vision for what a product should be. But it would be false to say that he originally thought of every successful product Apple has put out, though he apparently had no problems claiming other people's ideas as his own. Stories about his temper and the awful way he treated his employees have been around for a long time, and there are plenty of examples in the book.</p><p>What I did find surprising though, is that a lot of people he worked with claim that Jobs pushed them into achieving things they never considered possible and that they loved making such an impact with their work, despite their complaints of his outbursts and the way he treated people. I also found Jobs' take on it interesting. It was his way of making sure that Apple would have as many A players as possible, and to get rid of as many B players (or bozos, as he called them) as possible. He felt that A players only want to work with A players, and that mixing them with B players would reduce their value. You have to admit it's hard to disagree with the results of his approach.</p><p>As for his approach to being a CEO in the latter years of his career, the most interesting part to me was that he refused to split his company into divisions where each division had its own Profit &amp; Loss balance. Instead, you just had many teams and the only Profit &amp; Loss balance that they looked at was the company-wide one. Jobs forced them to work together instead of competing with each other (which is the complete opposite of what the young Jobs did in his first stint with Apple) and when people didn't work together, he'd get rid of them. He made sure everyone was on the same page and that there was no confusion about the priorities of the company. He made sure Apple only focused on a few products so they could do them as well as possible, instead of trying to do as much as possible.
It's pretty much the exact opposite of how Microsoft is being managed by Ballmer, and that contrast seems to reflect in both companies' success over the last couple of years.</p><p>The way he dealt with people, both in his personal as well as his professional life, wasn't as impressive though. It must have been hard to know him personally, and there are 2 stories of his behavior in the book that are downright shameful. In many of the stories of the book, he comes across as a total dick and a cry baby. You can take that literally even: there are countless moments in the book where it's mentioned that Jobs began crying when he didn't get his way. Saying that he had a complex personality is quite the understatement. But he was very good at knowing what people wanted and what they didn't want, even if they didn't know it yet, as he often said. Of course, it's exactly that arrogance that many of the people who don't like Apple products hate. Different strokes for different folks I guess, though I wouldn't be surprised if Jobs turns out to be right in most cases when it comes to <em>most people</em>, or non-techies in particular.</p><p>Despite his financial success, I do believe he was driven by building great products, and not just money. Had money been his primary motivation, I think he would've ended up with a lot more of it. The money issues that sometimes come up in the book seem to be more about respect than pure monetary gain, with the exception of one case, when he screwed one of his longtime friends during Apple's initial IPO. In that particular case, the author should've have dug deeper to find out Jobs' motivation. But again, from reading the book it's hard not to believe in Jobs' drive to create things that were truly great. I enjoy many of Apple's products, so in my opinion he's clearly succeeded at that. Though many of the Jobs-haters would probably disagree. Despite what you may think of the man or the products he's introduced, he's had a profound impact on many of the ways in which you and a lot of people you know interact with technology and media. And for that, I am glad he was the man that he was, regardless of his faults.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=EIrgaA1ek_U:T6E9pZMOYfQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=EIrgaA1ek_U:T6E9pZMOYfQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=EIrgaA1ek_U:T6E9pZMOYfQ:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=EIrgaA1ek_U:T6E9pZMOYfQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=EIrgaA1ek_U:T6E9pZMOYfQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=EIrgaA1ek_U:T6E9pZMOYfQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=EIrgaA1ek_U:T6E9pZMOYfQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=EIrgaA1ek_U:T6E9pZMOYfQ:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/EIrgaA1ek_U" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/11/thoughts-on-steve-jobs-the-book-and-the-man/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/11/thoughts-on-steve-jobs-the-book-and-the-man/</feedburner:origLink></item> <item><title>The Non-Typical .NET Job</title><link>http://feedproxy.google.com/~r/davybrion/~3/YSsRQsCyB0o/</link> <comments>http://davybrion.com/blog/2011/10/the-non-typical-net-job/#comments</comments> <pubDate>Sun, 23 Oct 2011 22:00:33 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[ALT.NET]]></category> <category><![CDATA[Code Quality]]></category> <category><![CDATA[Opinions]]></category> <category><![CDATA[Patterns]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[work/career]]></category><guid isPermaLink="false">http://davybrion.com/blog/2011/10/the-non-typical-net-job/</guid> <description><![CDATA[I recently referred to an interesting .NET job as a 'non-typical .NET job'. I hadn't used that term yet up until that point, so I thought that was rather interesting. But what exactly do I mean with 'non-typical .NET job'? It's pretty simple really: a job where you're using .NET technology without blindly following the [...]]]></description> <content:encoded><![CDATA[<p>I recently referred to an interesting .NET job as a 'non-typical .NET job'. I hadn't used that term yet up until that point, so I thought that was rather interesting. But what exactly do I mean with 'non-typical .NET job'? It's pretty simple really: a job where you're using .NET technology without blindly following the guidelines, recommendations and software from Microsoft on how to develop software on the .NET platform. It basically means that you'll use <em>whatever</em> you think is most appropriate for what you're trying to do.</p><p>The biggest problem in the .NET world is that most companies that do .NET development just stick to what Microsoft tells them to use and how to use it. Many .NET developers largely focus on that, because they know all too well that it increases their odds of getting hired. And let's face it: Microsoft has a solution for practically everything. The only problem is that those solutions are rarely the best in what they're trying to solve. But hey, no manager gets fired for going with Microsoft, right?</p><p>The result is that there are too many companies and too many developers that focus only on what Microsoft offers. But there's a lot more to software development than what Microsoft offers, or even knows about. There are countless examples of Microsoft being late to whatever technical party is interesting at the time. And when they show up, they certainly don't always make a good impression.</p><p>If you're the kind of developer that likes to learn from what other software development communities are doing, odds are high that you're screwed. There is an interesting OSS community within the .NET world, and they frequently produce great solutions, quite often based on succes stories coming from other development communities. The problem is not that .NET developers don't have great solutions available to them. The problem is that the majority of them simply don't know about them only because there hasn't been any Microsoft hype about it, or that the devs who do know about it aren't allowed to use it because their managers are sceptical about it, most likely also because there's no Microsoft backing for the technology or architectural style that is being proposed.</p><p>I'm not advocating the avoidance of Microsoft products or solutions. By all means, use Microsoft products if they are indeed the best solution to your problem. But do be aware of the things that are getting attention outside of the Microsoft sphere and use them when it makes more sense to use them. That's the essence of the 'non-typical .NET job' and that's exactly what makes it interesting: using the right tool for the right job.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=YSsRQsCyB0o:aakMIzbwVx0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YSsRQsCyB0o:aakMIzbwVx0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=YSsRQsCyB0o:aakMIzbwVx0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YSsRQsCyB0o:aakMIzbwVx0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=YSsRQsCyB0o:aakMIzbwVx0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YSsRQsCyB0o:aakMIzbwVx0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YSsRQsCyB0o:aakMIzbwVx0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=YSsRQsCyB0o:aakMIzbwVx0:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/YSsRQsCyB0o" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/10/the-non-typical-net-job/feed/</wfw:commentRss> <slash:comments>17</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/10/the-non-typical-net-job/</feedburner:origLink></item> <item><title>Developers Need To Keep Challenging Themselves</title><link>http://feedproxy.google.com/~r/davybrion/~3/FQ62wz6RSbY/</link> <comments>http://davybrion.com/blog/2011/10/developers-need-to-keep-challenging-themselves/#comments</comments> <pubDate>Sun, 23 Oct 2011 19:09:22 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[work/career]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3789</guid> <description><![CDATA[I read a very interesting article about a study on why some people learn faster than others. It's a very interesting read which I highly recommend, but in case you're short on time I'll summarize the most important parts because they're relevant to the subject I want to cover with this post. The study claims [...]]]></description> <content:encoded><![CDATA[<p>I read a very interesting <a
href="http://www.wired.com/wiredscience/2011/10/why-do-some-people-learn-faster-2/">article</a> about a study on why some people learn faster than others. It's a very interesting read which I highly recommend, but in case you're short on time I'll summarize the most important parts because they're relevant to the subject I want to cover with this post. The study claims that there are 2 types of mindset when it comes to learning:</p><ul><li>The <em>fixed mindset</em>: People who have this, think that we have a certain amount of intelligence and can't do much to change it. To them, a mistake is a failure, a sign that their capabilities aren't up to the task.</li><li>The <em>growth mindset</em>: People who have this believe that they can get better at almost everything, as long as they can invest the necessary time and energy. They see mistakes as an essential precursor to knowledge, the engine of education.</li></ul><p>Needless to say, people with a growth mindset turned out to be significantly better at learning from their mistakes. The article also covers a very interesting experiment involving school children. The children were given a test, and half of them were told "You must be smart at this". The other half was told "You must have worked really hard". After that, they could choose between 2 new tests. The first one was more difficult, but came with a mention that the students would learn a lot from them. The other test was similar to the test they had just taken.</p><p>And here's where it gets really interesting: of the kids that were praised for their effort instead of their intelligence (I'm going to refer to this group as the effort-kids from now on), <strong>90%</strong> of them chose the harder test. Of the kids that were praised for their intelligence (I'm going to refer to this group as the intelligence-kids from now on), the majority chose the test that was similar to the one they had just taken. Presumably, to avoid risking a low score after having already been praised for their intelligence. After the second test, all of the kids took the same third test, which was the hardest one so far. The effort-kids worked hard at figuring out the puzzles, while the intelligence-kids were easily discouraged by their mistakes. After the third test, the kids were given the choice to look at the exams of kids that did better than them, or the exams of kids that did worse. The effort-kids generally wanted to look at the exams of the people who did better. The intelligence-kids mostly picked the exams of those who did worse. The final test had the same difficulty level as the initial test. The effort-kids raised their average score by 30%, whereas the intelligence-kids saw their average score drop by 20%.</p><p>I find that kinda stuff fascinating. It also kinda confirms what I've seen from fellow developers ever since I graduated and started working. Every good developer I've met isn't afraid to make mistakes and sees mistakes as learning opportunities. These people routinely challenge themselves by learning something new. They also keep an eye on what other people are doing to get better and they actively try to learn from people they consider to be better than them.</p><p>One guy I used to work with was considered to be a great developer a few years ago. Now this was the kind of guy who was not only used to being praised for his 'intelligence', but his self-confidence was largely based on it. He once told me his favorite class in high-school was math because the other people in his class thought it was hard, while it was easy for him. He actually said it like that. When other people started getting more attention for their technical skills and knowledge, he began to move away from coding and started focusing more on writing functional analysis documents. He wasn't bad at it, but it wasn't great either. Now he does a little bit of everything from what I've heard. I'm pretty sure that if his self-confidence wasn't based on the praise he gets, he could've been much better at whatever he wanted to do.</p><p>That's just one story but I've seen similar things with other people who seemed to be more interested in what other people thought of what they could do as opposed to actually trying to improve on what they can do on a continuous basis. If they start thinking rather highly of themselves because of the praise they get, they often start thinking it's just not necessary anymore to keep working on improving their skills.</p><p>Keep challenging yourself. If you think you're pretty good at what you do (and there's nothing wrong with that), make sure you keep searching for new and better ways to do what you do. And when people praise you for being good at what you do, don't let it get to your head because before you know it, you won't be getting much praise at all anymore.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=FQ62wz6RSbY:zLajuVOuJZw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=FQ62wz6RSbY:zLajuVOuJZw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=FQ62wz6RSbY:zLajuVOuJZw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=FQ62wz6RSbY:zLajuVOuJZw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=FQ62wz6RSbY:zLajuVOuJZw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=FQ62wz6RSbY:zLajuVOuJZw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=FQ62wz6RSbY:zLajuVOuJZw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=FQ62wz6RSbY:zLajuVOuJZw:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/FQ62wz6RSbY" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/10/developers-need-to-keep-challenging-themselves/feed/</wfw:commentRss> <slash:comments>7</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/10/developers-need-to-keep-challenging-themselves/</feedburner:origLink></item> <item><title>You Need Your Time Off</title><link>http://feedproxy.google.com/~r/davybrion/~3/Y3AZzE1oc6Y/</link> <comments>http://davybrion.com/blog/2011/10/you-need-your-time-off/#comments</comments> <pubDate>Mon, 03 Oct 2011 19:29:31 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[life]]></category> <category><![CDATA[work/career]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3786</guid> <description><![CDATA[One of the hardest parts about being a good developer is trying to keep up with all of the new stuff that comes out. Let's be honest: we all have a list of things that we'd love to learn more about, but we just can't get around to it, right? I'm talking about programming languages, [...]]]></description> <content:encoded><![CDATA[<p>One of the hardest parts about being a good developer is trying to keep up with all of the new stuff that comes out. Let's be honest: we all have a list of things that we'd love to learn more about, but we just can't get around to it, right? I'm talking about programming languages, frameworks or libraries, new techniques, new kinds of data storage, architectural styles, or maybe just certain tools like specific editors or whatever. Well, I'm sure you get the point. I have a list like that. And so do you.</p><p>Another difficult part is always having a list of things you want to do, or need to do. Implementing that pet project you've had on your mind for a while now. Contributing to some Open Source projects that you're fond of. Accepting pull requests. Writing a blog post about something. There's always something, and you never quite manage to cross off every item on that list. I have a list like that. And so do you.</p><p>And you know what? That's ok. You have to accept the fact that between your job and your personal life, there is a limited amount of spare time available to you. And you just can't spend all of it on learning new stuff all the time or working on things that you think are important. Sure, learning is important. And so is taking the time to work on things that matter to you. But what's equally important is giving yourself enough time off to sit back, relax and maybe even do <em>nothing</em>.</p><p>I spend about 80 minutes each day on the train. Sometimes I'll read. Sometimes I'll code. And sometimes I just listen to some tunes while I stare out the window, either thinking about nothing or thinking about whatever comes to mind. It's a conscious decision. That's me saying "I just wanna relax right now". Which means I don't even want to think about software development stuff, or blogging, or anything else that I'm <em>supposed</em> to do. On some free evenings I think "damn, I really should do something useful". And on some of those nights, I will. But I'll also consciously choose not to do anything useful from time to time as well. It all kinda depends on how busy I've been in the days leading up to that free evening.</p><p>Your brain is like a semi-intelligent battery. It has a limited amount of energy and it can only do so much between charges. It's smart enough to scale down its activity when it's starting to run low, but most of us are too stupid to realize it and we just try to keep going. The result is that whatever we're trying to do, we're not going to do it as well as we think we are. You will have trouble learning new things when you're running low. You certainly won't do your best work when you're running low. In fact, you're likely to do a half-assed job which ironically only increases your workload.</p><p>Take care of that battery. Recharge it regularly, and don't think you can get by with minimum recharging. If it doesn't work for your phone, it won't work for you either.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=Y3AZzE1oc6Y:nybrynQgtTI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Y3AZzE1oc6Y:nybrynQgtTI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Y3AZzE1oc6Y:nybrynQgtTI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Y3AZzE1oc6Y:nybrynQgtTI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Y3AZzE1oc6Y:nybrynQgtTI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Y3AZzE1oc6Y:nybrynQgtTI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Y3AZzE1oc6Y:nybrynQgtTI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Y3AZzE1oc6Y:nybrynQgtTI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/Y3AZzE1oc6Y" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/10/you-need-your-time-off/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/10/you-need-your-time-off/</feedburner:origLink></item> <item><title>The Competition-Innovation Relationship We All Benefit From</title><link>http://feedproxy.google.com/~r/davybrion/~3/A7dKvp_Sm7g/</link> <comments>http://davybrion.com/blog/2011/10/the-competition-innovation-relationship-we-all-benefit-from/#comments</comments> <pubDate>Sun, 02 Oct 2011 15:34:15 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[gadgets]]></category> <category><![CDATA[Technology (general)]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3780</guid> <description><![CDATA[The other day, a friend of mine made an interesting observation that got me thinking. Here's what she said: It's weird how much change we've seen in the technology and websites we use in the past 3 years or so, compared to how little change there was in the 5 years before that. She's not [...]]]></description> <content:encoded><![CDATA[<p>The other day, a friend of mine made an interesting observation that got me thinking. Here's what she said:</p><blockquote><p>It's weird how much change we've seen in the technology and websites we use in the past 3 years or so, compared to how little change there was in the 5 years before that.</p></blockquote><p>She's not a techie. She's just a normal person who doesn't care about news from the technology world. But she is interested in devices and sites that make her life easier and better. We've all noticed that in an ever increasing way among non-techies in the past few years. If you think about it, it's a pretty big jump from where we were 5 years ago. Back then, the only technology innovations that people heard about were faster CPU's, bigger hard-drives and more memory. And most people didn't really care. The primary reason they bought new technology was because their computers 'got slow' doing the same tasks they once completed fast enough. With the notable exception of Napster (and its derivatives after that), there was nothing really that changed the way people consumed information and media. We didn't like the clunky mobile devices that were available. And while social networks already existed, they weren't as ubiquitous as they are now. For a few years, it seemed like there was hardly any progress in technology apart from the things that only geeks got excited about.</p><p>Back then, there was really only one tech-giant that mattered when it came to the consumer market: Microsoft. They were dominant and had little competition in their core markets. They then started to put a lot of resources into entering other markets, which meant they were basically building the same things that other companies were already offering. There were minor innovations, typically limited to small features and integration with other services/products that competing products didn't have. But nothing really substantial, they didn't introduce any game-changers. You could argue that hardware improvements at the time weren't coming along fast enough to create game-changing products, but I'd argue that such improvements largely come from companies that push for the required advancements in order to create the products they've envisioned. I like to compare it to how we were able to put a man on the moon 40 years ago because the space race pushed us ahead, yet we can't even match that feat (let alone exceed it) nowadays because nobody is pushing for it.</p><p>Luckily for us, we now live in a time where we're back to multiple tech-giants that matter to consumers. Apple, Google, Amazon, Facebook, Samsung, … they're all creating things that change the way we do things or consume things. They're all competing heavily and as a result, innovating because they simply have to. If they don't innovate, they quickly become irrelevant and that impedes their ability to compete. And if they no longer need to compete, it becomes less important for them to innovate. They'd only need to provide just enough innovation to get their customer base to upgrade regularly. And we, the consumers, would be back to where we were 5 years ago. Getting minor upgrades that slightly improve what we're <em>already doing</em>.</p><p>Despite any preferences you may have, you really ought to hope that none of the new tech-giants become as dominant in the areas they're active in as Microsoft used to be. If you're an Apple fan, you should be happy that Google and Samsung are fighting them so hard in the mobile space. If you're a Google fan, you should be happy that Facebook has them worried. If you're a Facebook fan, you should be happy about the changes that Google+ has inspired them to make already. If you're a Microsoft fan, you… well, that probably means your income is dependent on Microsoft's relevance. With the exception of Kinect and XBox, the only people that seem to get excited about Microsoft products are .NET developers, Windows sysadmins and tech journalists that cater to either of the first 2 groups. But the good news is that even Microsoft is being forced to innovate if they want people to buy their products. They can't leverage their Windows monopoly into automatic success in other markets anymore.</p><p>As long as none of the tech-giants can get comfortable in their position, we're going to keep benefiting from the competition and the resulting innovations. Just something to keep in mind for fanbois on all sides <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=A7dKvp_Sm7g:G9SmD-b2Y3I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=A7dKvp_Sm7g:G9SmD-b2Y3I:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=A7dKvp_Sm7g:G9SmD-b2Y3I:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=A7dKvp_Sm7g:G9SmD-b2Y3I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=A7dKvp_Sm7g:G9SmD-b2Y3I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=A7dKvp_Sm7g:G9SmD-b2Y3I:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=A7dKvp_Sm7g:G9SmD-b2Y3I:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=A7dKvp_Sm7g:G9SmD-b2Y3I:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/A7dKvp_Sm7g" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/10/the-competition-innovation-relationship-we-all-benefit-from/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/10/the-competition-innovation-relationship-we-all-benefit-from/</feedburner:origLink></item> <item><title>The Worst Code I Ever Wrote, And Why I’m Still Happy About It</title><link>http://feedproxy.google.com/~r/davybrion/~3/O7GSR_SQosY/</link> <comments>http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/#comments</comments> <pubDate>Sun, 18 Sep 2011 12:03:54 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Code Quality]]></category> <category><![CDATA[Software Development]]></category><guid isPermaLink="false">http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/</guid> <description><![CDATA[My last 2 years in high school, I was lucky enough to have 13 hours of programming-related classes every week. Those classes covered a few languages, but the most of it was spent on C/C++ (and nothing advanced either… mostly basic stuff) and Visual Basic. We thought we learned a lot, and I guess from [...]]]></description> <content:encoded><![CDATA[<p>My last 2 years in high school, I was lucky enough to have 13 hours of programming-related classes every week. Those classes covered a few languages, but the most of it was spent on C/C++ (and nothing advanced either… mostly basic stuff) and Visual Basic. We thought we learned a lot, and I guess from a purely syntactical point of view that may have indeed been true. But we didn't really learn a lot about the differences between good code and bad code.</p><p>We mostly cared about getting our assignments working. When you completed an assignment, you moved on to the next one and none of the code of the previous assignment really mattered anymore. Maintainability or even readability were things that never even occurred to us. Maybe a few of the teachers tried to tell us about it at some point, but it certainly didn't stick.</p><p>In the final year, we could pick a project to work on for the majority of the year. There were no limits on the assignment, so most people picked something that interested them. I was pretty interested in manager/simulation games, so I figured I'd just build my own Formula 1 manager game. The player would get full control over a F1 team, which in my game meant:</p><ul><li>picking the suppliers for tires, fuel and engines, all of which had varying levels of quality and costs associated with it</li><li>hiring a chief-designer, chief-mechanic and drivers, all of which had a specified talent level and negotiations took the results of the team's previous year into account, as well as the results of the potential hire's previous team, which influenced prices and negotiation tactics.</li><li>landing sponsors, some of which were more than happy to sponsor your team depending on last year's results, or wouldn't even answer your calls and they all had varying budgets as well</li></ul><p>I came up with a pretty good formula to simulate realistic race results based on all these factors as well as a dose of luck, or bad luck. If you played for a few seasons, the decisions you made all added up nicely, and gradually. When the project was due, it all worked. Since I loved playing those kind of games, I tested it very extensively by playing it regularly. When issues came up, I'd fix them. When I thought of improvements, I implemented them. I delivered something that worked, and that was large enough in scope and complexity to be impressive for a school project.</p><p>But the codebase was truly atrocious. I wasn't using proper structures for either data or behavior and I ended up with a shitload of extensive multi-dimensional arrays. All of my types were in those arrays, as I just didn't know yet that they should've been types of their own. Of course, I listed all of the indices on pieces of paper so I'd know which data properties corresponded with each index. Behavior was all implemented in the UI layer. I was using VB5 at the time, which didn't really encourage me to seek out nicer ways to structure my code. I copy/pasted large gobs of code whenever I needed to reuse something. And of course, whenever I had to make a change, I needed to do it in multiple places. Quite a few places in most cases even. I was using flat files to store data, so I didn't have the opportunity to make a horrendous mess out of a SQL-based data layer but if I had used a database, my usage of it would've surely been epic.</p><p>I got a very good grade for the project, and while I was happy to see that all of my hard work was rewarded, it did kinda scare me that a codebase that was so brittle and so painful could actually work, and work well even. It was my first encounter with what is by far the biggest problem with software development to this day: <em>if you keep adding code, sooner or later it might actually work</em>. Luckily, this was just a school project. But can you imagine if this were a project done by a professional company? That codebase would've cost money to develop, and the company would actually have a working project, no matter how expensive it would've been to keep working on it. At the time, I couldn't imagine a company in such a situation that would say: "ah, it sucks… we need to start over". And I think we all know that very few companies would actually do that.</p><p>I love that horrendous codebase for the lessons it taught me so early on. I learned a lot about what you shouldn't do when you're developing something that's supposed to stick around for a while, and I'm glad I learned it without it costing a lot of money. Of course, that doesn't mean that every single thing I've written since is all roses and peaches, but it put me on the path of trying to continuously improve as a developer, not only in what I was able to do with code, but also as to how clear I could make it to others.</p><p>Note: I no longer have that codebase unfortunately. Really wish I did, if only because it'd be pretty funny going through it after all these years.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=O7GSR_SQosY:XXEVd_C6T8M:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=O7GSR_SQosY:XXEVd_C6T8M:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=O7GSR_SQosY:XXEVd_C6T8M:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=O7GSR_SQosY:XXEVd_C6T8M:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=O7GSR_SQosY:XXEVd_C6T8M:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=O7GSR_SQosY:XXEVd_C6T8M:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=O7GSR_SQosY:XXEVd_C6T8M:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=O7GSR_SQosY:XXEVd_C6T8M:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/O7GSR_SQosY" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/feed/</wfw:commentRss> <slash:comments>11</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/</feedburner:origLink></item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/63 queries in 0.036 seconds using disk: basic
Object Caching 1304/1439 objects using disk: basic
Content Delivery Network via Amazon Web Services: CloudFront: d18sni7re4ly7f.cloudfront.net

Served from: davybrion.com @ 2012-01-29 11:48:33 -->

