<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-36663819</id><updated>2011-04-21T21:24:38.738-07:00</updated><category term='C#'/><category term='Vista'/><category term='WinFx'/><category term='Linux'/><category term='.Net'/><category term='AJAX'/><category term='CIL'/><category term='ASP.Net'/><category term='Windows'/><category term='JavaScript'/><category term='Java'/><category term='WPF'/><category term='Open Source'/><title type='text'>/dev/Brian</title><subtitle type='html'>cat /home/phb/requirements &gt; /dev/Brian</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-36663819.post-5362249587232095022</id><published>2007-10-11T10:18:00.000-07:00</published><updated>2007-10-11T10:52:55.973-07:00</updated><title type='text'>I'm geek-famous again!</title><content type='html'>So if I bribe Craig Shoemaker with $5 every time he posts an episode of &lt;a href="http://polymorphicpodcast.com/"&gt;Polymorphic Podcast&lt;/a&gt;, I get mentioned on the podcast, and even on &lt;a href="http://polymorphicpodcast.com/shows/architectextensibility2/"&gt;the blog&lt;/a&gt;.  Being a Tivo / Podcast evangelist (short version: thou shalt not listen to commercials) it's weird how your sense of "famous" completely changes.  In my weird little universe, Craig Shoemaker, &lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt;, and the &lt;a href="http://javaposse.com/"&gt;Java Posse&lt;/a&gt; are more famous than Matt Lauer or Hillary Duff.  (Oh, excellent!  I'm so unplugged that I didn't even get the name right... I was thinking Lindsay Lohan.)&lt;br /&gt;&lt;br /&gt;Anywho, so Craig interviewed Miguel Castro again, and among other things, they talked about the whole abstract base class vs. interface decision.  I am apparently in a minority here, but I prefer both.  In all cases, I pass around the least-specific interface or base class that I need.  (Does that parameter need to be List&lt;foo&gt;, or do you just need IEnumerable&lt;foo&gt;?)&lt;br /&gt;&lt;br /&gt;I always think in terms of avoiding option-limiting decisions.  So if I'm going to make a base class or interface for something, I want both.  I start with an interface and that is the type that I always pass around.  I make a base class that implements that interface, and that may even end up being the only thing in the world that ever implements that interface,  but I've left myself an out -- the option to change my mind without ripping the guts out of everything.&lt;br /&gt;&lt;br /&gt;When I start designing stuff this way, I get a lot of pushback, though.  And usually the argument involves the phrase "overengineering".  And then my response is usually that it won't feel overengineered if you see it everywhere and it just becomes the knee-jerk implementation that you always use.  And it's really not a big deal.  When you want to pull up some code into a base class, go ahead and do it.  Then just go one step further and pull those signatures up into an interface.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-5362249587232095022?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/5362249587232095022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=5362249587232095022&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/5362249587232095022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/5362249587232095022'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/10/im-geek-famous-again.html' title='I&apos;m geek-famous again!'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-1776207275778689004</id><published>2007-03-05T16:33:00.000-08:00</published><updated>2007-03-05T16:54:17.082-08:00</updated><title type='text'>Miguel de Icaza and Pixelmonkey talk Java, Mono, Windows, Linux</title><content type='html'>Andrew Montalenti, aka &lt;a href="http://www.pixelmonkey.org/"&gt;Pixelmonkey&lt;/a&gt;, started a lively debate with &lt;a href="http://tirania.org/blog/"&gt;Miguel&lt;/a&gt; over at Miguel's comment google group.  The thread is &lt;a href="http://groups.google.com/group/tiraniaorg-blog-comments/browse_thread/thread/e0797330090eb791"&gt;here&lt;/a&gt;, and Andrew's post on it is &lt;a href="http://www.pixelmonkey.org/2007/02/04/spirited-discussion-with-miguel-de-icaza-on-mono-and-microsoft/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.go-mono.org"&gt;Mono&lt;/a&gt; is my numero-uno interest as far as open source projects go.  And I've always gotten a kick out of Miguel's style.  Open source zealots seem often puzzled by Miguel's decision to dance with the devil, as they would see it.&lt;br /&gt;&lt;br /&gt;I'm not calling Andrew a zealot, just that he brought up a number of the points that I've seen made with far less tact and forethought by some of the more zealous.&lt;br /&gt;&lt;br /&gt;"Why would I choose mono when I have an open source java?"  I think that's the wrong question.  Most developers don't choose a language and/or platform.  They either only know one, or of the several they know, one is dictated to them by their job.  So why mono?  Because it provides a path to Linux and other platforms where C# was their non-choice.&lt;br /&gt;&lt;br /&gt;Along those lines, I'm planning on moving this blog to a mono-powered dasBlog engine on a linux host.  Just to see what it's like.  And to stop feeling like a *.blogspot.com poser.  :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-1776207275778689004?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/1776207275778689004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=1776207275778689004&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1776207275778689004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1776207275778689004'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/03/miguel-de-icaza-and-pixelmonkey-talk.html' title='Miguel de Icaza and Pixelmonkey talk Java, Mono, Windows, Linux'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-8112751443631319338</id><published>2007-02-25T14:34:00.000-08:00</published><updated>2007-02-25T14:51:10.614-08:00</updated><title type='text'>Almost there... Orcas better get this right.</title><content type='html'>It's a pretty old post... but it's a big internet and I haven't found the end yet.  :)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/davidebb/archive/2005/10/30/487160.aspx"&gt;David Ebbo&lt;/a&gt; explains how to distribute an ascx UserControl without having to distribute the actual ascx file.&lt;br /&gt;&lt;br /&gt;And then a litany of comments with people having trouble getting the secret sauce to work just right.&lt;br /&gt;&lt;br /&gt;To introduce this on my team, I need to be able to have an "ascx project" that fits into studio as a first-class member of the solution, and that produces an assembly that the other projects can refer to as a project reference.&lt;br /&gt;&lt;br /&gt;I need this to have build automation, and a project model that I can let beginner-intermediate developers go to town on without having to understand all the underlying twiddling.  It's just not quite there.  So we're still doing "reference this assembly and copy these ascx files into your /controls directory".  That blows, but the beginners can handle it.&lt;br /&gt;&lt;br /&gt;There must be a universe that I am not exposed to where you would be allowed and would actually want to edit a code-behind, aspx, or ascx file on a live, production server.  I can only imagine this scenario in a small business fiddling with their own little website.  Those people can have the ascx UserControl.  For bigger business development, we really just need and want resource-based full design-time support for a Web.Control.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-8112751443631319338?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/8112751443631319338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=8112751443631319338&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/8112751443631319338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/8112751443631319338'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/02/almost-there-orcas-better-get-this.html' title='Almost there... Orcas better get this right.'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-226625476451272352</id><published>2007-02-12T05:48:00.000-08:00</published><updated>2007-02-15T15:30:36.795-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Apache / IIS Flamebait</title><content type='html'>There's a &lt;a href="http://blogs.zdnet.com/threatchaos/wp-trackback.php?p=311"&gt;ZDNet blog posting&lt;/a&gt; by Richard Stiennon that shows two call graphs comparing the system calls that a Linux / Apache server makes to serve up a simple page versus the equivalent on Windows / IIS.&lt;br /&gt;&lt;br /&gt;Surprise, Apache makes fewer system calls. The argument is that this makes it easier to secure a Linux / Apache implementation. That might be true. My experience is that ignorant administration is an orders-of-magnitude greater threat than the inherent limitations of either platform.&lt;br /&gt;&lt;br /&gt;While it's sort of an interesting look... I've got a few big problems with the post:&lt;br /&gt;a) The graphs are unreadable, and therefore FUD. I'm sure it was just a bandwidth issue not to have a version of the graph with enough resolution to actually read the system calls being made. However, just showing two pictures with lots of lines and basing your conclusion on the fact that one picture has way more lines in it is a pretty shoddy argument. I'll give Stiennon the benefit of the doubt that he both analyzed the original graphs, and is qualified to understand what they say. If that's not the case, then shame on you for stirring up a pointless religious debate.&lt;br /&gt;b) Microsoft chose this implementation on purpose. You can make an intellectually honest argument that keeping most processing in user-space is inherently more secure, but that's just a (sensible) opinion, and not gospel fact. IIS7 moved most low-level processing into http.sys as a conscious decision in support of performance and stability. ASP.Net can blow chunks and IIS will restart it. IIS can blow chunks and http.sys will queue up the requests until the OS restarts IIS. You would be right in assuming that this puts the entire OS at the mercy of any holes in http.sys. But in closed-source land that means that http.sys is going to be something that they pay extra-special attention to, and also insulate from the feature-itis that ASP.Net (and thus IIS) are prone to.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Alright, that's enough defending Microsoft (like they need my help). In Linux-land, there's a fanatical devotion to moving as much code as possible out of kernel-space and into user-mode. Security is one of the concerns, but it also keeps the kernel simple and light (well, simple as far as kernels go). This is a design decision that gets repeated in lots of Linux projects, but it comes at a price, like all design decisions do. Until the code can cross the magic line where really almost everything is happening in user-mode, there's a not-irrelevant performance cost from the marshaling between memory spaces. Apache already crossed that line... it's a good decision. And really, under the open source model where defense-in-depth is even more important, it's usually a good decision for most projects.&lt;br /&gt;&lt;br /&gt;Of course, this is only a "decision" you get to make if you're hacking straight at the API. And if you're one of those people... you knew all this already. :)&lt;br /&gt;&lt;br /&gt;Oh, and thanks to &lt;a href="http://arnosoftwaredev.blogspot.com/2007/02/system-calls-on-http-request.html"&gt;Arno&lt;/a&gt; for pointing me at the post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-226625476451272352?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blogs.zdnet.com/threatchaos/wp-trackback.php?p=311' title='Apache / IIS Flamebait'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/226625476451272352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=226625476451272352&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/226625476451272352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/226625476451272352'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/02/apache-iis-flamebait.html' title='Apache / IIS Flamebait'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-6361554368063893039</id><published>2007-02-08T21:19:00.000-08:00</published><updated>2007-02-25T14:15:54.204-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CIL'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Yet weirder nuances with C# interfaces</title><content type='html'>&lt;a href="http://brennan.offwhite.net/blog"&gt;Brennan&lt;/a&gt; has a &lt;a href="http://brennan.offwhite.net/blog/2007/02/05/unexpected-nuance-with-c-interfaces/trackback/"&gt;post&lt;/a&gt; about the differences between implicitly and explicitly implementing an interface in C#. He's got screenshots and better code formatting than I've figured out how to do yet, so really just go look there. But in brief, if you have an interface like this:&lt;br /&gt;&lt;blockquote&gt;&lt;div class="cf"&gt;&lt;pre class="cl"&gt; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;interface&lt;/span&gt; &lt;span class="cb2"&gt;IDog&lt;/span&gt;  &lt;/pre&gt;&lt;pre class="cl"&gt; {  &lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb1"&gt;void&lt;/span&gt; Bark();  &lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb1"&gt;void&lt;/span&gt; Run();  &lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb1"&gt;void&lt;/span&gt; Catch();  &lt;/pre&gt;&lt;pre class="cl"&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;You have two ways you can implement it. Implicitly, which is what I'm used to seeing:&lt;br /&gt;&lt;style type="text/css"&gt;amily: courier new; font-size: 10pt; color: black; background: white; }.cl { margin: 0px; }.cb1 { color: blue; }.cb2 { color: teal; }.cb3 { color: green; &lt;/style&gt;&lt;br /&gt;&lt;div class="cf"&gt;&lt;pre class="cl"&gt;&lt;/pre&gt;&lt;blockquote&gt;&lt;pre class="cl"&gt; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;class&lt;/span&gt; &lt;span class="cb2"&gt;Bulldog&lt;/span&gt; : &lt;span class="cb2"&gt;IDog&lt;/span&gt;  &lt;/pre&gt;&lt;pre class="cl"&gt; {  &lt;/pre&gt;&lt;pre class="cl"&gt;&lt;span class="cb1"&gt;#region&lt;/span&gt; Implicit implementation of IDog&lt;/pre&gt;&lt;pre class="cl"&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb3"&gt;// Implicit &lt;/span&gt;&lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;void&lt;/span&gt; Bark()  &lt;/pre&gt;&lt;pre class="cl"&gt;     {  &lt;/pre&gt;&lt;pre class="cl"&gt;         &lt;span class="cb1"&gt;throw&lt;/span&gt; &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;NotImplementedException&lt;/span&gt;();  &lt;/pre&gt;&lt;pre class="cl"&gt;     }  &lt;/pre&gt;&lt;pre class="cl"&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;void&lt;/span&gt; Run()  &lt;/pre&gt;&lt;pre class="cl"&gt;     {  &lt;/pre&gt;&lt;pre class="cl"&gt;         &lt;span class="cb1"&gt;throw&lt;/span&gt; &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;NotImplementedException&lt;/span&gt;();  &lt;/pre&gt;&lt;pre class="cl"&gt;     }  &lt;/pre&gt;&lt;pre class="cl"&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;void&lt;/span&gt; Catch()  &lt;/pre&gt;&lt;pre class="cl"&gt;     {  &lt;/pre&gt;&lt;pre class="cl"&gt;         &lt;span class="cb1"&gt;throw&lt;/span&gt; &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;NotImplementedException&lt;/span&gt;();  &lt;/pre&gt;&lt;pre class="cl"&gt;     }  &lt;/pre&gt;&lt;pre class="cl"&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;&lt;span class="cb1"&gt;#endregion&lt;/span&gt;  &lt;/pre&gt;&lt;pre class="cl"&gt; } &lt;/pre&gt;&lt;/blockquote&gt;&lt;/div&gt;Or explicitly like this:&lt;br /&gt;&lt;style type="text/css"&gt;font-family: courier new; font-size: 10pt; color: black; background: white; }.cl { margin: 0px; }.cb1 { color: blue; }.cb2 { color: teal; &lt;/style&gt;&lt;br /&gt;&lt;div class="cf"&gt;&lt;blockquote&gt;&lt;pre class="cl"&gt; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;class&lt;/span&gt; &lt;span class="cb2"&gt;Terrier&lt;/span&gt; : &lt;span class="cb2"&gt;IDog&lt;/span&gt;  &lt;/pre&gt;&lt;pre class="cl"&gt; {  &lt;/pre&gt;&lt;pre class="cl"&gt;&lt;span class="cb1"&gt;#region&lt;/span&gt; Explicit implementation of IDog&lt;/pre&gt;&lt;pre class="cl"&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb1"&gt;void&lt;/span&gt; &lt;span class="cb2"&gt;IDog&lt;/span&gt;.Bark()  &lt;/pre&gt;&lt;pre class="cl"&gt;     {  &lt;/pre&gt;&lt;pre class="cl"&gt;         &lt;span class="cb1"&gt;throw&lt;/span&gt; &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;NotImplementedException&lt;/span&gt;();  &lt;/pre&gt;&lt;pre class="cl"&gt;     }  &lt;/pre&gt;&lt;pre class="cl"&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb1"&gt;void&lt;/span&gt; &lt;span class="cb2"&gt;IDog&lt;/span&gt;.Run()  &lt;/pre&gt;&lt;pre class="cl"&gt;     {  &lt;/pre&gt;&lt;pre class="cl"&gt;         &lt;span class="cb1"&gt;throw&lt;/span&gt; &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;NotImplementedException&lt;/span&gt;();  &lt;/pre&gt;&lt;pre class="cl"&gt;     }  &lt;/pre&gt;&lt;pre class="cl"&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;     &lt;span class="cb1"&gt;void&lt;/span&gt; &lt;span class="cb2"&gt;IDog&lt;/span&gt;.Catch()  &lt;/pre&gt;&lt;pre class="cl"&gt;     {  &lt;/pre&gt;&lt;pre class="cl"&gt;         &lt;span class="cb1"&gt;throw&lt;/span&gt; &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;NotImplementedException&lt;/span&gt;();  &lt;/pre&gt;&lt;pre class="cl"&gt;     }  &lt;/pre&gt;&lt;pre class="cl"&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;&lt;span class="cb1"&gt;#endregion&lt;/span&gt;  &lt;/pre&gt;&lt;pre class="cl"&gt; }  &lt;/pre&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;They both accomplish the same thing (sort of, here come the nuances). Brennan pointed out that the explicit implementation (Terrier) will not show intellisense for variables of type Terrier. But you can still pass it around to methods expecting an IDog. Bulldog behaves more like you would expect -- intellisense shows all the methods and you can still pass it anywhere you could pass an IDog.&lt;br /&gt;&lt;br /&gt;So lately I've been playing with &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt; more than is healthy for a person. It prompted me to go out and read the &lt;a href="http://msdn2.microsoft.com/en-us/netframework/aa569283.aspx"&gt;CIL specification&lt;/a&gt;. (Well, I'm almost done with Partition I at any rate. Yes, I've become that kind of geek.)&lt;br /&gt;&lt;br /&gt;So I compiled this little sample and dropped it into Reflector. Interesting. The "normal" implicit implementation in Bulldog.Bark:&lt;style type="text/css"&gt;.cf { font-family: courier new; font-size: 10pt; color: black; background: white; }.cl { margin: 0px; }.cb1 { color: blue;&lt;/style&gt;&lt;br /&gt;&lt;div class="cf"&gt;&lt;pre class="cl"&gt;&lt;/pre&gt;&lt;blockquote&gt;&lt;pre class="cl"&gt;.method &lt;span class="cb1"&gt;public&lt;/span&gt; hidebysig newslot &lt;span class="cb1"&gt;virtual&lt;/span&gt; final instance &lt;span class="cb1"&gt;void&lt;/span&gt; Bark() cil managed&lt;/pre&gt;&lt;pre class="cl"&gt;{&lt;/pre&gt;&lt;pre class="cl"&gt;      .&lt;br /&gt;maxstack 8&lt;/pre&gt;&lt;pre class="cl"&gt;      L_0000: nop &lt;/pre&gt;&lt;pre class="cl"&gt;      L_0001: newobj instance &lt;span class="cb1"&gt;void&lt;/span&gt; [mscorlib]System.NotImplementedException::.ctor()&lt;/pre&gt;&lt;pre class="cl"&gt;      L_0006: &lt;span class="cb1"&gt;throw&lt;/span&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;}&lt;/pre&gt;&lt;/blockquote&gt;&lt;pre class="cl"&gt;&lt;/pre&gt;&lt;/div&gt;And the explicit implementation:&lt;style type="text/css"&gt;nt-family: courier new; font-size: 10pt; color: black; background: white; }.cl { margin: 0px; }.cb1 { color: blue; }.cb2 { color: teal; }&lt;/style&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div class="cf"&gt;&lt;pre class="cl"&gt;.method &lt;span class="cb1"&gt;private&lt;/span&gt; hidebysig newslot &lt;span class="cb1"&gt;virtual&lt;/span&gt; final instance &lt;span class="cb1"&gt;void&lt;/span&gt; com.navelplace.&lt;span class="cb2"&gt;IDog&lt;/span&gt;.Bark() cil managed&lt;/pre&gt;&lt;pre class="cl"&gt;{&lt;/pre&gt;&lt;pre class="cl"&gt;      .&lt;span class="cb1"&gt;override&lt;/span&gt; com.navelplace.&lt;span class="cb2"&gt;IDog&lt;/span&gt;::Bark&lt;/pre&gt;&lt;pre class="cl"&gt;      .&lt;br /&gt;maxstack 8&lt;/pre&gt;&lt;pre class="cl"&gt;      L_0000: nop &lt;/pre&gt;&lt;pre class="cl"&gt;      L_0001: newobj instance &lt;span class="cb1"&gt;void&lt;/span&gt; [mscorlib]System.&lt;span class="cb2"&gt;NotImplementedException&lt;/span&gt;::.ctor()&lt;/pre&gt;&lt;pre class="cl"&gt;      L_0006: &lt;span class="cb1"&gt;throw&lt;/span&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;So everything after .maxstack 8 is identical, as you'd expect. That nop puzzles me. That's a CIL no-op (do nothing). I'm guessing it has to do with byte alignment. If I'm wrong I'd love somebody to explain that to me.&lt;br /&gt;&lt;br /&gt;Anywho... before you wig out about looking at IL... what are the differences? The explicit version declares itself as a .override, and not the implicit version. They're both "virtual final instance void". I'll break that down: virtual and final have the same meaning as they do in C#, virtual because all methods from an interface are virtual, final meaning you could not override Bark() in a subclass of Bulldog or Terrier. CIL is a lot more statically-oriented, so "instance" means "not static". And void meaning, umm, void.&lt;br /&gt;&lt;br /&gt;hidebysig and newslot are pretty obscure -- they have to do with overloading and overriding. I believe all .method's coming out of C# will be marked hidebysig, or at least I haven't stumbled across anything marked hidebyname yet. It means that foo() will hide base.foo() but not base.foo(int). With hidebyname, foo() would hide anything from base named foo, regardless of signature. Although "signature" includes more things than we're used to in C#.&lt;br /&gt;newslot comes into play for overriding. Implementing an interface requires a new slot on the type, but overriding a virtual method on a class would not specify newslot.&lt;br /&gt;&lt;br /&gt;But now the real difference, and the weird part. The explicit implementation is marked private, while the implicit implementation is marked public. This explains why the explicit implementation doesn't show up in intellisense -- it's a private member of the concrete class. But it's not just intellisense that thinks so. new Terrier().Bark() is a compile-time error. This would seem to violate the inheritance rules from the spec, since everything in an interface is public:&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;When a derived type overrides a virtual method, it can specify a new accessibility for the virtual method, but the accessibility in the derived class shall permit at least as much access as the access granted to the method it is overriding.&lt;/blockquote&gt;There would seem to be an exception made for interfaces. And notice the method that specifically says ".override" is the one apparently violating the accessibility rule. Haven't stumbled across the part of the spec that explains the reasoning. It doesn't violate the substitution principle, since anything expecting an IDog would get an implicit cast and the explicit implementations would become visible again. But it still seems weird.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-6361554368063893039?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://brennan.offwhite.net/blog/2007/02/05/unexpected-nuance-with-c-interfaces/trackback/' title='Yet weirder nuances with C# interfaces'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/6361554368063893039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=6361554368063893039&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/6361554368063893039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/6361554368063893039'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/02/yet-weirder-nuances-with-c-interfaces.html' title='Yet weirder nuances with C# interfaces'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-1346580200937500744</id><published>2007-02-02T17:19:00.000-08:00</published><updated>2007-02-07T17:34:40.136-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Concurrency and C-Omega</title><content type='html'>The old name was Polyphonic C#.  Both sound cool, but C-Omega is harder to type, but looks way cooler when you use the real symbol: C&lt;span style="font-family:Symbol;"&gt;w&lt;/span&gt; (that made blogger mad putting that in, and Firefox remains unimpressed with my font tag, so follow the link or read this in IE to see the symbol).  Apparently it is &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; C&lt;span style="font-family:Symbol;"&gt;W&lt;/span&gt; which would have looked cooler.&lt;br /&gt;Anyway, I totally stumbled across it while trolling the Microsoft Research site.  Concurrency stuff is becoming a lot more interesting to me -- from the geeky theory level just because of the increasing abundance of multi-core processors, but also because I'm running into these same issues at work. C&lt;span style="font-family:Symbol;"&gt;w&lt;/span&gt; dovetails a bunch of LINQ stuff into it too, but the concurrency stuff is what has me excited.&lt;br /&gt;We implemented a pretty naive attempt at SOA here, and ran into the classic performance bottleneck.  The extra network hop involved in talking to a web service caused all the same old kinds of performance issues that we used to run into with DCOM, just in new ways.  Consuming too many discreet services means you're making too many network roundtrips, so the server spends most of its time waiting around for responses from other servers.  And for us, it does all that waiting in a serial fashion.  Ouch.&lt;br /&gt;This is of course why all of .Net's auto-generated web service proxies have asynchronous equivalents to every call, but synchronizing all the callbacks in a way that isn't both confusing and brittle is pretty hard.  And then there's the whole issue of defending your code from slash-and-burn programmers that just don't get it.&lt;br /&gt;&lt;br /&gt;But check out their simple example (I made it simpler):&lt;br /&gt;&lt;!-- {\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20     \cf2 public\cf0  \cf2 class\cf0  \cf10 Buffer\par ??\cf0     \{\par ??        \cf2 public\cf0  async Put(\cf2 string\cf0  s);\par ??\par ??        \cf2 public\cf0  \cf2 string\cf0  Get() &amp; Put(\cf2 string\cf0  s)\par ??        \{\par ??            \cf2 return\cf0  s;\par ??        \}\par ??    \}\par ??} --&gt;&lt;br /&gt;&lt;div    style="background: white none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier New;font-size:10pt;color:black;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    1&lt;/span&gt;     &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:teal;"&gt;Buffer&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    2&lt;/span&gt;     {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    3&lt;/span&gt;         &lt;span style="color:blue;"&gt;public&lt;/span&gt; async Put(&lt;span style="color:blue;"&gt;string&lt;/span&gt; s);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    4&lt;/span&gt; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    5&lt;/span&gt;         &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; Get() &amp; Put(&lt;span style="color:blue;"&gt;string&lt;/span&gt; s)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    6&lt;/span&gt;         {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    7&lt;/span&gt;             &lt;span style="color:blue;"&gt;return&lt;/span&gt; s;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    8&lt;/span&gt;         }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    9&lt;/span&gt;     }&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The idea is that any call to Put just hands off the parameter and returns immediately (async implies a void return type).  A call to Get is synchronous like a regular method call, but has to be paired with a call to Put.  So if Put had already been called, the value s is waiting to be returned.  If Put has not been called, the call to Get blocks until some other thread calls Put.  Multiple calls to Put will stack up waiting to be consumed.&lt;br /&gt;This example hurt my brain to look at the first time:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;!-- {\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20     \cf2 public\cf0  \cf2 class\cf0  ReaderWriter\par ??    \{\par ??        \cf2 private\cf0  async idle();\par ??        \cf2 private\cf0  async s(\cf2 int\cf0  n);\par ??\par ??        \cf15 ///\cf11  \cf15 &lt;summary&gt;\par ??\cf0         \cf15 ///\cf11  We start out by dropping message to idle()\par ??\cf0         \cf15 ///\cf11  \cf15 &lt;/summary&gt;\par ??\cf0         \cf2 public\cf0  ReaderWriter()\par ??        \{\par ??            \cf11 //\par ??\cf0             idle();\par ??        \}\par ??\par ??        \cf15 ///\cf11  \cf15 &lt;summary&gt;\par ??\cf0         \cf15 ///\cf11  A call to Exclusive() will block unless or until\par ??\cf0         \cf15 ///\cf11  there is an idle() message dropped.  It consumes\par ??\cf0         \cf15 ///\cf11  the idle() message, so another call to Exclusive()\par ??\cf0         \cf15 ///\cf11  will have to wait for someone else to call idle().\par ??\cf0         \cf15 ///\cf11  \cf15 &lt;/summary&gt;\par ??\cf0         \cf2 public\cf0  \cf2 void\cf0  Exclusive() &amp; idle() \par ??        \{\par ??            \cf11 //We don't need to actually do anything.\par ??\cf0             \cf11 //Consuming the idle() message is enough.\par ??\cf0         \}\par ??\par ??        \cf2 public\cf0  \cf2 void\cf0  ReleaseExclusive()\par ??        \{\par ??            \cf11 //Makes us idle again.\par ??\cf0             idle();\par ??        \}\par ??\par ??        \cf15 ///\cf11  \cf15 &lt;summary&gt;\par ??\cf0         \cf15 ///\cf11  A call to Shared will block until there is a matching \par ??\cf0         \cf15 ///\cf11  message of either idle() or s(int).  You only have\par ??\cf0         \cf15 ///\cf11  to match on one of the asynchronous methods.  So a \par ??\cf0         \cf15 ///\cf11  call to Shared() will either match idle() or s(int),\par ??\cf0         \cf15 ///\cf11  but not both.  (The &amp; syntax makes that a little\par ??\cf0         \cf15 ///\cf11  confusing.  You might think Shared would wait for\par ??\cf0         \cf15 ///\cf11  both idle and s(int).)\par ??\cf0         \cf15 ///\cf11  \cf15 &lt;/summary&gt;\par ??\cf0         \cf2 public\cf0  \cf2 void\cf0  Shared() &amp; idle() \par ??        \{\par ??            \cf11 /*\par ??             * If we were idle, when somebody called Shared,\par ??             * then we go here, and drop a message that there\par ??             * is one reader.\par ??             */\par ??\cf0             s(1);\par ??        \}\par ??        &amp; s(\cf2 int\cf0  n) \par ??        \{\par ??            \cf11 /*\par ??             * If we were already in Shared mode and somebody\par ??             * called Shared again, then just bump up the counter.\par ??             */\par ??\cf0             s(n+1);\par ??        \}\par ??\par ??        \cf15 ///\cf11  \cf15 &lt;summary&gt;\par ??\cf0         \cf15 ///\cf11  This just needs to make the decision to either\par ??\cf0         \cf15 ///\cf11  decrement the shared counter or call idle.  Either\par ??\cf0         \cf15 ///\cf11  way, it will drop another asynchronous message.\par ??\cf0         \cf15 ///\cf11  And if you follow the logic, ReleaseShared() will\par ??\cf0         \cf15 ///\cf11  always find that there is a waiting s(int) message.\par ??\cf0         \cf15 ///\cf11  \cf15 &lt;/summary&gt;\par ??\cf0         \cf2 public\cf0  \cf2 void\cf0  ReleaseShared() &amp; s(\cf2 int\cf0  n) \par ??        \{\par ??            \cf2 if\cf0  (n == 1)\par ??                idle();\par ??            \cf2 else\par ??\cf0                 s(n - 1);\par ??        \}\par ??    \}} --&gt;&lt;br /&gt;&lt;div    style="background: white none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier New;font-size:10pt;color:black;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    1&lt;/span&gt;     &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; ReaderWriter&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    2&lt;/span&gt;     {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    3&lt;/span&gt;         &lt;span style="color:blue;"&gt;private&lt;/span&gt; async idle();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    4&lt;/span&gt;         &lt;span style="color:blue;"&gt;private&lt;/span&gt; async s(&lt;span style="color:blue;"&gt;int&lt;/span&gt; n);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    5&lt;/span&gt; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    6&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    7&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; We start out by dropping message to idle()&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    8&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    9&lt;/span&gt;         &lt;span style="color:blue;"&gt;public&lt;/span&gt; ReaderWriter()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   10&lt;/span&gt;         {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   11&lt;/span&gt;             &lt;span style="color:green;"&gt;//&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   12&lt;/span&gt;             idle();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   13&lt;/span&gt;         }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   14&lt;/span&gt; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   15&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   16&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; A call to Exclusive() will block unless or until&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   17&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; there is an idle() message dropped.  It consumes&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   18&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; the idle() message, so another call to Exclusive()&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   19&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; will have to wait for someone else to call idle().&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   20&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   21&lt;/span&gt;         &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Exclusive() &amp; idle() &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   22&lt;/span&gt;         {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   23&lt;/span&gt;             &lt;span style="color:green;"&gt;//We don't need to actually do anything.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   24&lt;/span&gt;             &lt;span style="color:green;"&gt;//Consuming the idle() message is enough.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   25&lt;/span&gt;         }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   26&lt;/span&gt; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   27&lt;/span&gt;         &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ReleaseExclusive()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   28&lt;/span&gt;         {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   29&lt;/span&gt;             &lt;span style="color:green;"&gt;//Makes us idle again.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   30&lt;/span&gt;             idle();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   31&lt;/span&gt;         }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   32&lt;/span&gt; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   33&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   34&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; A call to Shared will block until there is a matching &lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   35&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; message of either idle() or s(int).  You only have&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   36&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; to match on one of the asynchronous methods.  So a &lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   37&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; call to Shared() will either match idle() or s(int),&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   38&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; but not both.  (The &amp; syntax makes that a little&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   39&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; confusing.  You might think Shared would wait for&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   40&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; both idle and s(int).)&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   41&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   42&lt;/span&gt;         &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Shared() &amp; idle() &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   43&lt;/span&gt;         {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   44&lt;/span&gt;             &lt;span style="color:green;"&gt;/*&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   45&lt;/span&gt; &lt;span style="color:green;"&gt;             * If we were idle, when somebody called Shared,&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   46&lt;/span&gt; &lt;span style="color:green;"&gt;             * then we go here, and drop a message that there&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   47&lt;/span&gt; &lt;span style="color:green;"&gt;             * is one reader.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   48&lt;/span&gt; &lt;span style="color:green;"&gt;             */&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   49&lt;/span&gt;             s(1);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   50&lt;/span&gt;         }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   51&lt;/span&gt;         &amp; s(&lt;span style="color:blue;"&gt;int&lt;/span&gt; n) &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   52&lt;/span&gt;         {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   53&lt;/span&gt;             &lt;span style="color:green;"&gt;/*&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   54&lt;/span&gt; &lt;span style="color:green;"&gt;             * If we were already in Shared mode and somebody&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   55&lt;/span&gt; &lt;span style="color:green;"&gt;             * called Shared again, then just bump up the counter.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   56&lt;/span&gt; &lt;span style="color:green;"&gt;             */&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   57&lt;/span&gt;             s(n+1);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   58&lt;/span&gt;         }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   59&lt;/span&gt; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   60&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   61&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; This just needs to make the decision to either&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   62&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; decrement the shared counter or call idle.  Either&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   63&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; way, it will drop another asynchronous message.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   64&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; And if you follow the logic, ReleaseShared() will&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   65&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; always find that there is a waiting s(int) message.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   66&lt;/span&gt;         &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   67&lt;/span&gt;         &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ReleaseShared() &amp; s(&lt;span style="color:blue;"&gt;int&lt;/span&gt; n) &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   68&lt;/span&gt;         {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   69&lt;/span&gt;             &lt;span style="color:blue;"&gt;if&lt;/span&gt; (n == 1)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   70&lt;/span&gt;                 idle();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   71&lt;/span&gt;             &lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   72&lt;/span&gt;                 s(n - 1);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   73&lt;/span&gt;         }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   74&lt;/span&gt;     }&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It's a lot less painful once you grasp on to the fact that an asynchronous call is just dropping off a message.  (The contents of the message being the parameters.) The &amp;amp; token groups together method signatures (you can group two or more, but only one can be synchronous).  Together the grouped signatures form a chord, and the body will execute when a synchronous and an asynchronous call find a match.  I found the concept got simpler as I started thinking about it in a similar way to signature matching for overloaded methods.&lt;br /&gt;It is a little unsettling to see that state is being stored with no variables for you to look at.  But there's at least a baseline here for debugging tools to latch onto that would making debugging a multi-threaded app a lot less painful.&lt;br /&gt;And yah, this stuff is hard to wrap your brain around, but concurrency is hard to wrap your brain around.  This is a big step into abstracting away the non-essentials.&lt;br /&gt;&lt;br /&gt;There are some other equally-impressive things being baked into &lt;a href="http://research.microsoft.com/comega/"&gt;C&lt;span style="font-family:Symbol;"&gt;w&lt;/span&gt;&lt;/a&gt;, go check it out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-1346580200937500744?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://research.microsoft.com/comega/' title='Concurrency and C-Omega'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/1346580200937500744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=1346580200937500744&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1346580200937500744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1346580200937500744'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/02/concurrency-and-c-omega.html' title='Concurrency and C-Omega'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-2351751018318225881</id><published>2007-01-25T17:02:00.000-08:00</published><updated>2007-02-05T11:39:11.928-08:00</updated><title type='text'>Good intro to MSBuild</title><content type='html'>Brennan wrote a &lt;a href="http://brennan.offwhite.net/blog/2006/11/30/7-steps-to-msbuild/"&gt;nice little tutorial on MSBuild&lt;/a&gt; over on his blog. It'll be especially useful to you if you've never used ant or Nant before.  There's also some good quick starts over at the &lt;a href="http://channel9.msdn.com/wiki/default.aspx/MSBuild.HomePage"&gt;Channel 9 wiki&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I have a fetish for making build scripts.  Considering how plebeian the task is, I enjoy it way more than I ought to.  I ran into Brennan's post hunting around for good stuff on Foundation Server's build stuff.&lt;br /&gt;&lt;br /&gt;Foundation Server looks awesome.  I don't quite understand why Microsoft is trying to make money off of it, but they're being quite clever about it.  You can download a 90 day trial from &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=D5C12289-F4E4-49A9-9235-AB2F6D4CA097&amp;amp;displaylang=en"&gt;here&lt;/a&gt;.  And then you're just a checkbook away from turning your trial version into a production version.&lt;br /&gt;&lt;br /&gt;We are likely falling for it.  :)&lt;br /&gt;&lt;br /&gt;Strange things coming from Microsoft these days.  MSBuild (and Studio's total integration with MSBuild) is just a slam dunk, but very un-Microsoft of them.  And then trying to make money off of VSTS and Foundation Server (you can't download it as part of the not-so-universal-anymore MSDN subscription).  I would think the mindshare they'd own by giving it away would be worth more dollars than they're going to get for licensing.  Or maybe they're just so confident in their monopoly these days that they figure they might as well start charging for more stuff.  Hmm...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-2351751018318225881?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://brennan.offwhite.net/blog/2006/11/30/7-steps-to-msbuild/' title='Good intro to MSBuild'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/2351751018318225881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=2351751018318225881&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2351751018318225881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2351751018318225881'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/01/good-intro-to-msbuild.html' title='Good intro to MSBuild'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-1387470661839288216</id><published>2007-01-12T10:13:00.001-08:00</published><updated>2007-01-12T10:36:11.530-08:00</updated><title type='text'>Review: Working Effectively with Legacy Code</title><content type='html'>I originally posted this review to Amazon. Thought I'd repeat it here. The author, &lt;a href="http://www.artima.com/weblogs/index.jsp?blogger=mfeathers"&gt;Michael Feathers&lt;/a&gt;, is from &lt;a href="http://www.objectmentor.com"&gt;Object Mentor&lt;/a&gt;. Check out &lt;a href="http://blog.objectmentor.com/"&gt;their blogs&lt;/a&gt;, there's a lot of interesting noise being made over there. (They recently moved the blog from &lt;a href="http://butunclebob.com/"&gt;their old site&lt;/a&gt;, but the new site has a link to the old stuff.)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052"&gt;Here's a link directly to the book&lt;/a&gt; where you can read other reviews.  Oh, and I didn't mention it originally in my review, but another big plus to this book is that it's language-agnostic, which is a big deal when legacy code is your issue.&lt;br /&gt;&lt;br /&gt;Anywho, here's the review. The punchline is: READ THIS BOOK! It's really excellent.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;A more accurate title for this book would have been "Unit Testing and Refactoring is How To Work Effectively with Legacy Code" The book operates entirely from that premise, and only spends a little time trying to sell you on the concept. If you're still struggling with that debate, this book may rub you the wrong way. However, I found it to be intensely practical and found the author repeatedly speaking about scenarios that I run into quite often.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I would describe myself as someone who finds the whole fascination with design patterns a little optimistic and certainly hype-laden. Useful to be familiar with, but nothing to preach about. Feathers' treatment of patterns is exactly what they should be, however -- from the trenches, and goal-oriented. He describes the patterns he uses with the very immediate goal of how they will help you "get code under test" as he would put it, and slowly unwind the spaghetti we all run into.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Although the world didn't need yet another book about unit testing, refactoring, and patterns, there are few books that offer practical advice for the ugly side of software development. To get the most out of this book, you'll need to have slightly better than intermediate experience with object-oriented development, but this is not a hypothetical-scenario type book targeted at gurus. And most importantly, it acknowledges and embraces the fact that we have all inherited reams of code that has either abused and ignored OO principles, or wasn't even OO to begin with. It is quite readable and accessible, and doesn't overwhelm. I found a lot of valuable techniques in here that I have not found anywhere else.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I highly recommend this book, and I'm going to be shoving it down my coworkers' throats. :)&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-1387470661839288216?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/1387470661839288216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=1387470661839288216&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1387470661839288216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1387470661839288216'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/01/review-working-effectively-with-legacy.html' title='Review: Working Effectively with Legacy Code'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-4057739262804161261</id><published>2007-01-07T13:44:00.001-08:00</published><updated>2007-01-07T13:44:24.002-08:00</updated><title type='text'>Review: Saving Money and Time With Virtual Server (O'Reilly Shortcuts)</title><content type='html'>&lt;p&gt;If you haven't heard of &lt;a href="http://www.oreilly.com/store/series/sc.csp" target="_blank"&gt;O'Reilly's Shortcuts&lt;/a&gt; series, they are a fairly large collection of downloadable PDF articles, usually between 25-100 pages long, and priced between 6-10 dollars.&amp;nbsp; Or if you have a &lt;a href="http://safari.oreilly.com/" target="_blank"&gt;Safari&lt;/a&gt; account, they're all included with your subscription.&amp;nbsp; Well, that's enough of sounding like a commercial for O'Reilly.&amp;nbsp; But they did send me a free copy to review (thanks Marsee!) so I thought I'd at least plug them a little.&amp;nbsp; And considering that I'm about to give a lukewarm review of the article itself...&lt;/p&gt; &lt;p&gt;This is the first Shortcut I've read, and I hope it's not indicative of the series as a whole.&amp;nbsp; While the quality of the article was quite good and the information useful, it was definitely a commercial for Microsoft's Virtual Server 2005.&amp;nbsp;Granted, the article is clearly targetted as an introduction to Virtual Server, but any discussion of virtualization that does not also mention VMWare is clearly suspect.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The author, &lt;a href="http://www.chrissanders.org/" target="_blank"&gt;Chris Sanders&lt;/a&gt;, is not a paid shill for Microsoft, so it's a shame that his article comes across as&amp;nbsp;just another piece of evangelism.&amp;nbsp; Do check out his blog, though, he has quite a bit of useful tips and info for an IT admin, but that's just not my bag.&amp;nbsp; I'm the guy always making the IT guys nervous.&amp;nbsp; :)&lt;/p&gt; &lt;p&gt;In spite of my complaints, the article is a good introduction to Virtual Server to someone who has never used it before, and is even new to the idea of virtualization.&amp;nbsp; It has a quick introduction to the concept of virtualization, and then a basic how-to on setting up your first virtual machine.&amp;nbsp; The instructions were clear and easy to follow, and I had my little sample machine up and running with little trouble.&amp;nbsp; So good job there.&lt;/p&gt; &lt;p&gt;Not being an IT guy, I spent more time paying attention to how I could use it to run multiple development platforms, and didn't pay very close attention to the sections about security or&amp;nbsp;consolidation (running multiple VM's&amp;nbsp;on one beefy server).&amp;nbsp; But if you &lt;em&gt;are&lt;/em&gt; an IT guy, I imagine you'll want to pay attention to those sections.&amp;nbsp; &lt;/p&gt; &lt;p&gt;I'm still not up to speed enough on the ins and outs of either Virtual Server or VMWare, but they are very soon going to&amp;nbsp;end my adventures with Norton Ghost or dual booting.&amp;nbsp; Virtualization is one of the New Cool Things getting a lot of attention, and we're moving aggressively on it at my work.&amp;nbsp; If you're a newbie in this area like I am, you should put your ear to the ground.&lt;/p&gt; &lt;p&gt;But would I shell out $7.99 for this article?&amp;nbsp; Probably not.&amp;nbsp; Mostly because I'm a Cheap Bastard, but also because if I'm going to pay for someone's knowledge, I want an unbiased opinion.&amp;nbsp; This article isn't trying to be a reference source for Virtual Server.&amp;nbsp; So if I'm just being introduced to a product, I'd be really interested in hearing&amp;nbsp;its relative merits to its obvious competitor.&amp;nbsp; And there is literally not one single mention of VMWare in the whole article.&lt;/p&gt; &lt;p&gt;If this were an article&amp;nbsp;posted out on some IT forum, I would certainly point people to it and recommend they read it.&amp;nbsp; It's got good stuff.&amp;nbsp; But then I would recommend they &lt;a href="http://www.google.com/search?q=virtual+server+vs+vmware"&gt;google the comparisons&lt;/a&gt;.&amp;nbsp; If you've already got a Safari account, or if you're spending someone else's money, do download the article.&amp;nbsp; Amazon and O'Reilly do get lots of my money for technical books, but if I had just spent 8 bucks for this, I'd feel a little cheated.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-4057739262804161261?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/4057739262804161261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=4057739262804161261&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/4057739262804161261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/4057739262804161261'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/01/review-saving-money-and-time-with.html' title='Review: Saving Money and Time With Virtual Server (O&amp;#39;Reilly Shortcuts)'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-2109252897092301388</id><published>2007-01-05T11:35:00.000-08:00</published><updated>2007-01-05T11:45:12.294-08:00</updated><title type='text'>Horrifying thing I just overheard at work.</title><content type='html'>I'm being arrogant as all hell... but I'm posting it anyway.&lt;br /&gt;&lt;br /&gt;Dev1: "This is how they do multiple inheritance in C#.  Interfaces."&lt;br /&gt;Dev2: "Aaah."&lt;br /&gt;&lt;br /&gt;Apparently Dev1 and Dev2 are C++ guys.  And &lt;em&gt;only&lt;/em&gt; C++ guys.&lt;br /&gt;&lt;br /&gt;I have a rant in me about the importance of being multi-language and multi-platform literate.  And this is perfect grist for that mill, but it more makes me think about the social and non-technical difficulties of coming up with a good design when you're part of a team that isn't really at the level to understand, implement, or take advantage of that design.&lt;br /&gt;&lt;br /&gt;And I'm not talking about overly-elaborate designs that turn into frameworks that turn into solutions looking for a problem.  I can explain dependency injection to someone, for example, but if they don't &lt;em&gt;get it&lt;/em&gt; and understand &lt;em&gt;why&lt;/em&gt; and &lt;em&gt;when&lt;/em&gt; it is a good idea, then I'm pretty tied down in the kind of design I can put into our project.&lt;br /&gt;&lt;br /&gt;Hrm...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-2109252897092301388?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/2109252897092301388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=2109252897092301388&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2109252897092301388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2109252897092301388'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2007/01/horrifying-thing-i-just-overheard-at.html' title='Horrifying thing I just overheard at work.'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-2627099310228308915</id><published>2006-12-16T22:46:00.000-08:00</published><updated>2006-12-17T11:42:11.566-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='WinFx'/><title type='text'>What's in a name?</title><content type='html'>And as long as I'm rambling. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0" onclick="BLOG_clickHandler(this)"&gt;WinFx&lt;/span&gt;, Avalon, Atlas, and Indigo sounded a lot more hip and bleeding-edge than the stodgy names that are so long I don't even care to type them (okay, I really mean I don't care to look them up to make sure I get them right).&lt;br /&gt;&lt;br /&gt;And Atlas didn't even make the cut for inclusion in the otherwise technically irrelevant grouping of .Net 3.0. Can we dump the hype for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1" onclick="BLOG_clickHandler(this)"&gt;Workflow&lt;/span&gt; Foundation and swap in Atlas?&lt;br /&gt;&lt;br /&gt;Go read &lt;a href="http://en.wikipedia.org/wiki/No_Silver_Bullet"&gt;No Silver Bullet&lt;/a&gt; and then run screaming when your boss mentions &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2" onclick="BLOG_clickHandler(this)"&gt;Workflow&lt;/span&gt; Foundation. I am perhaps biased by the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3" onclick="BLOG_clickHandler(this)"&gt;multi&lt;/span&gt;-million, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4" onclick="BLOG_clickHandler(this)"&gt;multi&lt;/span&gt;-year boondoggle that my company chased with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5" onclick="BLOG_clickHandler(this)"&gt;BEA's&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6" onclick="BLOG_clickHandler(this)"&gt;Weblogic&lt;/span&gt; Integration 8.x. And the plural of "anecdote" is not "data". But neither is "unfounded opinion" the equivalent of "experience". Nor does a technology evangelist have your best interests at heart.&lt;br /&gt;&lt;br /&gt;My ego was in no little way stroked that I got to say "I told you so" when our &lt;a href="http://c2.com/cgi/wiki?ArchitectsDontCode"&gt;Architects&lt;/a&gt; eventually got chewed out for drinking &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7" onclick="BLOG_clickHandler(this)"&gt;BEA's&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8" onclick="BLOG_clickHandler(this)"&gt;Kool&lt;/span&gt;-Aid.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-2627099310228308915?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/2627099310228308915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=2627099310228308915&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2627099310228308915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2627099310228308915'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/12/whats-in-name.html' title='What&apos;s in a name?'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-2169917033720887106</id><published>2006-12-16T22:11:00.000-08:00</published><updated>2006-12-16T22:46:13.826-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Oh please let this be the start of the end of web-enabled everything.</title><content type='html'>I'm excited about Avalon... err Windows Presentation Foundation. The advent of Ajax has and will continue to go a long way toward deadening the pain of web-based interfaces, but I'm still clinging tenaciously to the opinion that there are way too many web apps out there that have no business being web apps.&lt;br /&gt;&lt;br /&gt;The New York Times has the perfect excuse for being a &lt;em&gt;web site, &lt;/em&gt;and they never really tried to be a web app, but they've done a beautiful thing with the &lt;a href="http://firstlook.nytimes.com/index.php?cat=4"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0" onclick="BLOG_clickHandler(this)"&gt;NYT&lt;/span&gt; Reader&lt;/a&gt;. Go check it out, even if you don't care for the paper. There need to be more apps like this. Good for you, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1" onclick="BLOG_clickHandler(this)"&gt;NYT&lt;/span&gt;. Sorry the bottom is falling out of your business model.&lt;br /&gt;&lt;br /&gt;And here's the beauty of the system. It requires "stuff" on your system to be installed for it to work. And it will handle it &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2" onclick="BLOG_clickHandler(this)"&gt;automagically&lt;/span&gt; and securely.&lt;br /&gt;&lt;br /&gt;(Okay, "stuff" is the dubiously-named .Net 3.0 framework. But grandma doesn't need to even know that "stuff" is required. It "just works".)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-2169917033720887106?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://firstlook.nytimes.com/index.php?cat=4' title='Oh please let this be the start of the end of web-enabled everything.'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/2169917033720887106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=2169917033720887106&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2169917033720887106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2169917033720887106'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/12/oh-please-let-this-be-start-of-end-of.html' title='Oh please let this be the start of the end of web-enabled everything.'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-9002017357812569087</id><published>2006-12-16T00:18:00.000-08:00</published><updated>2006-12-17T11:42:43.056-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Vista'/><title type='text'>Having less than a stellar experience with Vista 64</title><content type='html'>Haven't figured out what to call it yet. x64 Vista? 64-bit Vista? Vista 64? Eventually we'll just be calling it Windows, I suppose.&lt;br /&gt;&lt;br /&gt;Anywho, I'm actually getting instant cold restarts (twice so far, just had it installed for a few days). And many, many apps just don't run right.&lt;br /&gt;&lt;br /&gt;Sounds like this is going to be a slow, painful experience bringing the rest of the world up to 64 bits. I'm going to try reinstalling at 32 bits and see how many problems go away, or if it's just the hard-core security stuff built into Vista now. (I blame the cold boots on the 64-to-32 conversion it has to do, probably some device driver misbehaving....) But it seems that if the software wasn't written by Microsoft, it just doesn't behave right.&lt;br /&gt;&lt;br /&gt;Interesting too that by default they have me running the 32-bit version of IE. I can run the 64-bit version, but it doesn't appear that I can make that my default program for web pages.&lt;br /&gt;&lt;br /&gt;Quite the disappointing experience.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-9002017357812569087?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/9002017357812569087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=9002017357812569087&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/9002017357812569087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/9002017357812569087'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/12/having-less-than-stellar-experience.html' title='Having less than a stellar experience with Vista 64'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-1378199847492907220</id><published>2006-11-22T18:38:00.000-08:00</published><updated>2006-11-22T18:41:47.405-08:00</updated><title type='text'>Junfeng Zhang</title><content type='html'>&lt;a href="http://blogs.msdn.com/junfeng/default.aspx"&gt;Junfeng&lt;/a&gt; probably isn't going to win any prizes in literature, but his blog is just chock full of useful tech tips. The nitty gritty stuff that isn't documented (much).&lt;br /&gt;&lt;br /&gt;And he's quite the friendly chap. For that, he makes my blogroll.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-1378199847492907220?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blogs.msdn.com/junfeng/default.aspx' title='Junfeng Zhang'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/1378199847492907220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=1378199847492907220&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1378199847492907220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1378199847492907220'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/11/junfeng-zhang.html' title='Junfeng Zhang'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-1564553535502135685</id><published>2006-11-15T01:14:00.000-08:00</published><updated>2006-11-15T01:25:54.531-08:00</updated><title type='text'>Java vs. C# vs. C++</title><content type='html'>Arno posted a little duelling performance test for a sudoku solver &lt;a href="http://arnosoftwaredev.blogspot.com/2006/10/java-vs-net-vs-c-performance.html"&gt;here&lt;/a&gt;.  He has snobbily disabled comments on his blog (you hear me, Arno?)  :)&lt;br /&gt;&lt;br /&gt;So in hopes that he gets a trackback, I'd be really interested to see how much of a difference .Net 2.0 would make to his performance numbers, as well as java 1.5 and 1.6 (or against BEA's JDK).&lt;br /&gt;&lt;br /&gt;And also see how much more g++ might be able to squeeze out of his code if it were thoroughly twiddled for optimizations.&lt;br /&gt;&lt;br /&gt;I really need to hunt down the post I read long ago that argued that most application development these days is IO bound, and not processor bound, and that chasing these milliseconds doesn't really help us much.  This is largely the argument made in defense of interpreted languages like Python, Ruby, and Perl.  Your language choice doesn't change your bandwidth, your network latency, or the speed of your hard drives.&lt;br /&gt;&lt;br /&gt;Perl is an unfortunate crime of history.  But Python and Ruby are moving in directions we need to pay attention to.  Need to break out Iron Python and see how I like it.&lt;br /&gt;&lt;br /&gt;Of course, Arno posted his code and I could run it under those platforms, and even for fun port it to Python and Ruby (I need to get a little Ruby under my belt just to see what all the noise is about.)&lt;br /&gt;&lt;br /&gt;At some point I'll blog my thoughts about the difficulties of a multi-language environment when you're developing with a team.  Sometimes the best tool isn't the best tool when you're the only guy that knows it.  And apparently I'm in a significant, but not majority subset of developers that think it's fun to learn new languages and get them to play nice with each other.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-1564553535502135685?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://arnosoftwaredev.blogspot.com/2006/10/java-vs-net-vs-c-performance.html' title='Java vs. C# vs. C++'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/1564553535502135685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=1564553535502135685&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1564553535502135685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/1564553535502135685'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/11/java-vs-c-vs-c.html' title='Java vs. C# vs. C++'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-8412398363321002726</id><published>2006-11-13T10:29:00.000-08:00</published><updated>2006-12-17T11:43:41.436-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><title type='text'>W00t!  GPL Java!</title><content type='html'>With most (all?) of the "scary" viral components rendered non-issues for the average developer. And non-GPL'd versions will remain available to those still frightened off by the whole thing. (Sun retains the copyright/left, so is free to license it under multiple licensing models.)&lt;br /&gt;&lt;br /&gt;The semi-official announcement is &lt;a href="http://today.java.net/pub/a//today/2006/11/13/open-source-java-editorial.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I imagine this means that for Sun to accept contributions into their tree, you have to surrender the copyright to your contribution. Somebody correct me on that.&lt;br /&gt;&lt;br /&gt;Java has really benefited from the competition .Net brought to the game, and it's better off for it. There's been a lot more velocity in Java in the last five years. And this will just kick in the afterburners.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-8412398363321002726?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.javalobby.org/java/forums/t84244.html' title='W00t!  GPL Java!'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/8412398363321002726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=8412398363321002726&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/8412398363321002726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/8412398363321002726'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/11/w00t-gpl-java.html' title='W00t!  GPL Java!'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-6234044136878538828</id><published>2006-11-10T16:09:00.000-08:00</published><updated>2006-11-10T16:20:57.060-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>New Toy!  Script#</title><content type='html'>Looks like a really clean concept. I won't talk out of my butt about it, because I haven't played with it yet.&lt;br /&gt;&lt;br /&gt;Oh, and thanks to &lt;a href="http://brennan.offwhite.net/blog"&gt;Brennan&lt;/a&gt; for turning me on to this. Lot's of other nice stuff on his &lt;a href="http://brennan.offwhite.net/blog/2006/09/10/web-development-tools-for-the-power-developer/"&gt;Power Toys&lt;/a&gt; post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-6234044136878538828?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.nikhilk.net/ScriptSharpIntro.aspx' title='New Toy!  Script#'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/6234044136878538828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=6234044136878538828&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/6234044136878538828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/6234044136878538828'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/11/new-toy-script.html' title='New Toy!  Script#'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-2247310593007028750</id><published>2006-11-08T16:56:00.000-08:00</published><updated>2006-12-24T09:44:17.219-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><title type='text'>More reasons why a Web Application is a fundamentally unnatrual act.</title><content type='html'>Yes, more railing about the evils of browser-based "applications".&lt;br /&gt;&lt;br /&gt;Follow the link for an MSDN article about how you can put a progress bar on your web page when the server is going to take a long time to process your request.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The rub lies in the fact that the operation runs on the server and there's no way for a server-side environment to push information to a page displayed in a browser (unless the server holds the connection open to the client, rendered to the unfinished page, but that's not recommended). Basically, when a classic postback is taking place the client page is virtually frozen and no other client activity can occur.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The advice in the article is actually pretty good. A perfect job for AJAX. ("A sufficiently advanced technology is indistinguishable from a rigged demo.")&lt;br /&gt;&lt;br /&gt;But let's just not forget how much simpler it would be to accomplish the same goal in a thick client. Spin up a separate thread, and point it to a callback method that updates the progress bar. To be fair, it's a fundamentally difficult problem. You generally get fake progress bars when you'd have to pay a high cost for real progress information.&lt;br /&gt;&lt;br /&gt;But the mechanics to accomplish all of that is much harder in a web client environment. AJAX does at least bring some sanity to the situation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-2247310593007028750?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://msdn.microsoft.com/msdnmag/issues/06/09/CuttingEdge/default.aspx' title='More reasons why a Web Application is a fundamentally unnatrual act.'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/2247310593007028750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=2247310593007028750&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2247310593007028750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/2247310593007028750'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/11/more-reasons-why-web-application-is.html' title='More reasons why a Web Application is a fundamentally unnatrual act.'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-316372584467746432</id><published>2006-11-03T20:08:00.000-08:00</published><updated>2006-11-04T19:18:54.457-08:00</updated><title type='text'>Don't chain yourself to your install base.</title><content type='html'>When I worked at The Very Bad Place, we had an MFC application with an install base of several thousand users spread all over the U.S. It talked DCOM to our corporate servers to get its data. DCOM wasn't a completely insane decision at the time it was chosen -- there were far fewer remoting choices for Windows back then.&lt;br /&gt;&lt;br /&gt;What was insane, however, was the admins not knowing enough about DCOM and TCP ports so that the company had to leave the DCOM servers sitting outside the firewalls.&lt;br /&gt;&lt;br /&gt;I arrived at that scene back when SOAP was the new Golden Hammer. We probably could have handled most of their security issues with the SOAP-tunneled DCOM that COM+ offered, but that involved some strange inter-departmental politics, so the idea never took flight. They also had the IT departments from a lot of their customers planting the word SOAP in upper management's ears. Thus is the nature of Golden Hammers. So they hired me to put SOAP shims on the client and server so that most of the rest of the system still thought it was talking DCOM. It was all about Microsoft's SOAP toolkit back then.&lt;br /&gt;&lt;br /&gt;The basics of tiered design had been abandoned for so long, that not only was the client sending raw SQL straight up to the server, it was even providing the name of the server and the database instance that the SQL should be thrown at.&lt;br /&gt;&lt;br /&gt;So, basically, a horror show. But I get my SOAP shims implemented, we release a new version, thousands of clients install it, there was much rejoicing. Even a small performance boost because of a horrid on-server temp-file hack I was able to get rid of.&lt;br /&gt;&lt;br /&gt;So all better, yah? No. Because roughly 80% of the install base upgraded. Leaving 20% of the install base still talking DCOM. Meaning that DCOM servers still had to sit with their arses in the wind asking to be hacked at.&lt;br /&gt;&lt;br /&gt;And those SQL queries going across the line? It means we can't change our tables until every last client is gone. But we really &lt;em&gt;need&lt;/em&gt; to change our tables because they're basically a mirror of a COBOL database, most some 50 columns wide, and it takes 6 hours for the nightly population script to run.&lt;br /&gt;&lt;br /&gt;So these are the reasons most shops are so keen to go with web-based applications, and it certainly sounds like I just made a fine argument in favor of them. But we've been lost in this knee-jerk web-enablement world for so long, that I think most have forgotten how much easier it is to develop a thick client app. Besides the fact that they are a lot nicer. It's not the memory consumption anymore. Right now the two biggest memory consumers on my box are Firefox at 48MB, and IE at 40MB. (Sorry, Firefox, Task Manager doesn't lie, maybe it's all those silly plugins I installed.) Microsoft had to stop calling them thin clients. Right now Visual Studio is only taking up 36MB.&lt;br /&gt;&lt;br /&gt;But AOL figured out another solution a long time ago, and Microsoft a little (okay, a lot) later. Automatic Updates. And that whole concept is built right into .Net smart clients. Security sandboxes, code verification and signing -- everything you'd want out of a web app without sucking. Gmail is really impressive, but I'll take Outlook, thankyouverymuch. Or Thunderbird.&lt;br /&gt;&lt;br /&gt;If you're trying to reach a huge audience of previously anonymous customers, then a web app is obviously the right way to go. Amazon has to be a web app (and an impressive one it is at that, but if they wrote a thick client, I'd sure as hell give it a spin. You hear me, Amazon?). But what if you're just going to have a few thousand users? A few hundred? And they already have to register with you and write you a check? Do you think they enjoy waiting for the page to refresh?&lt;br /&gt;&lt;br /&gt;Obviously, there would be a tremendous increase in time spent testing installers, and the upgrade process, and OS version compatibility, and yadda yadda yadda. But development time would go down by just as much, I would think. And developers cost more than testers and admins.&lt;br /&gt;&lt;br /&gt;And .Net has done a lot for getting rid of the compatibility and library version issues that an MFC or VB app used to have.&lt;br /&gt;&lt;br /&gt;Of course, my Linux brethren are hissing at me right now. And I say -- &lt;a href="http://www.mono-project.com"&gt;Mono!&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-316372584467746432?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/316372584467746432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=316372584467746432&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/316372584467746432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/316372584467746432'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/10/dont-chain-yourself-to-your-install.html' title='Don&apos;t chain yourself to your install base.'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-7214644595757767807</id><published>2006-11-02T19:30:00.000-08:00</published><updated>2006-12-24T09:44:50.192-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><title type='text'>Bamboo Technology</title><content type='html'>I googled around a little bit, and apparently this expression is not as popular as I thought. And no, I'm not talking about the &lt;a href="http://dev.riseup.net/bamboo/"&gt;content management system&lt;/a&gt; by that name.&lt;br /&gt;&lt;br /&gt;Its inspiration is The Professor on Gilligan's Island. Well, I'll be darned, there's &lt;a href="http://en.wikipedia.org/wiki/Gilligan"&gt;a whole article about it on wikipedia&lt;/a&gt;. (I go there a lot to make sure I don't say something patently stupid on here.) The coconut Geiger counter is an all-time classic.&lt;br /&gt;&lt;br /&gt;Normally I use it as a negative, but it doesn't always have to be. I'm sure you all have your own bamboo technology you have to deal with -- you're just calling it something else. If I had to define it, I'd say it's stretching an old or limited technology well beyond its intended use. Usually you run across this in a bad way. Our accounting system runs on a "database" called Universe which is almost as old as I am, and you program it in Pick Basic. It calls itself a "multi-value database" which really means, "This group of flat files are fixed-width delimited, but sometimes inside a column you might see multiple values delimited by an unprintable character."&lt;br /&gt;&lt;br /&gt;I had heard of neither Universe nor Pick Basic until I got here. You hit the application with a terminal emulator. It has since been bought by IBM, who, clearly by magic, have written an XA JDBC driver for it that actually works. We update our Oracle back-end and the accounting system inside a distributed transaction. I can't begin to think how it actually accomplishes that. Hat's off to IBM for that -- I'll buy their coconut Geiger counter when it ships.&lt;br /&gt;&lt;br /&gt;I'd call AJAX an example of good bamboo technology. We've been stuck with javascript since before the dawn of time (assuming time dawned sometime after '95). And we'll continue to be stuck with it for the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;foreseeable&lt;/span&gt; future. AJAX is getting a big bang for the buck in a sensible way that makes the best out of what we have.&lt;br /&gt;&lt;br /&gt;But I should save that up for a rant about knee-jerk decisions to do everything as a web app.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-7214644595757767807?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/7214644595757767807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=7214644595757767807&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/7214644595757767807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/7214644595757767807'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/10/bamboo-technology.html' title='Bamboo Technology'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-8038664632162915863</id><published>2006-11-01T10:35:00.000-08:00</published><updated>2006-11-10T16:22:13.155-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>NStatic</title><content type='html'>(Until I figure out a more intuitive way to lay it out, the title of this post is the link to the article.)&lt;br /&gt;&lt;br /&gt;Wesner Moise is a former Microsoftian who is working on a group of super-top-secret apps using an AI engine he has developed and is still tweaking.&lt;br /&gt;&lt;br /&gt;He's using the AI engine as the back-end to a code analysis tool that he's calling NStatic. (N for .Net, Static for static analysis, which is the technical term for what it does. I believe the term static is used to distinguish this approach versus profiling.)&lt;br /&gt;&lt;br /&gt;Think FxCop with a brain behind it instead of a set of rules. It explores your code with all kinds of "what-if" scenarios and can show you where things might go wrong. Kind of like virtual profiling, if I understand correctly. It doesn't actually run your code, and you don't have to provide input. It just analyzes what your code &lt;em&gt;might&lt;/em&gt; do.&lt;br /&gt;&lt;br /&gt;The idea is that it would just be something running in the background, analyzing your code deeper and deeper the more time you give it, and popping up warnings about the things it finds as it finds them. Like much of AI, it's all about exploring nodes in a tree. I say that like I could just whip something like that up over the weekend.&lt;br /&gt;&lt;br /&gt;I would envision using it as part of a Continuous Integration process, so that you could have a dedicated machine digging really deep. He seems to be putting his focus on immediate feedback during development, though. Hmm, think I'll pop him a note.&lt;br /&gt;&lt;br /&gt;And he's big into usability, so his UI looks all whiz-bang. Check out the &lt;a href="http://wesnerm.blogs.com/net_undocumented/2006/11/effortless_ui_i.html"&gt;code markup&lt;/a&gt; he does to show execution flow. Definitely a toy I want to play with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-8038664632162915863?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://wesnerm.blogs.com/net_undocumented/nstatic/index.html' title='NStatic'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/8038664632162915863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=8038664632162915863&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/8038664632162915863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/8038664632162915863'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/11/nstatic.html' title='NStatic'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-8794567840691760312</id><published>2006-10-31T14:41:00.000-08:00</published><updated>2006-12-24T09:45:23.803-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Spec#</title><content type='html'>The first I heard of this was from &lt;a href="http://wesnerm.blogs.com/net_undocumented/2006/10/real_world_spec_2.html"&gt;Wesner Moise's Blog&lt;/a&gt; talking about the work he's doing on NStatic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-8794567840691760312?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://research.microsoft.com/specsharp/' title='Spec#'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/8794567840691760312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=8794567840691760312&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/8794567840691760312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/8794567840691760312'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/10/spec.html' title='Spec#'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-116223636395494691</id><published>2006-10-30T11:15:00.000-08:00</published><updated>2006-10-30T11:21:30.923-08:00</updated><title type='text'>I'm not this guy.</title><content type='html'>There's &lt;a href="http://en.wikipedia.org/wiki/Brian_Deacon"&gt;another Brian Deacon&lt;/a&gt; that is doing a fine job of helping me stay anonymous on the net, but it certainly doesn't make ego-surfing any fun. Although it was gratifying to see that at least my Amazon profile showed up at the very bottom of the first page of hits on google. (W00t! I made it to the first page!)&lt;br /&gt;&lt;br /&gt;But you can imagine my confusion one day when I got a VHS tape in the mail of a &lt;a href="http://en.wikipedia.org/wiki/Jesus_Film_Project"&gt;movie about Jesus&lt;/a&gt; and flipped it over to find that I played Jesus. I at first thought it was a very cleverly executed proselytizing gimmick, and that down the street was an identical copy of the tape, but with Joe Smith playing the role of Jesus.&lt;br /&gt;&lt;br /&gt;But the other guy is way over in England (that place is lousy with Deacons), and as far as I can tell, he has few opinions on software.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-116223636395494691?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://en.wikipedia.org/wiki/Brian_Deacon' title='I&apos;m not this guy.'/><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/116223636395494691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=116223636395494691&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/116223636395494691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/116223636395494691'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/10/im-not-this-guy.html' title='I&apos;m not this guy.'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36663819.post-116190791601520991</id><published>2006-10-26T16:45:00.000-07:00</published><updated>2006-10-30T11:21:30.778-08:00</updated><title type='text'>Welcome to the show...</title><content type='html'>Because I thought, really, the net needs Yet Another Software Blog where some opinionated geek explains to the rest of the geeks all the ways in which they are mistaken. Well, maybe not, but I thought it would at least spare my coworkers my-not-so-occassional harangues. And they're nice people and really don't deserve it.&lt;br /&gt;&lt;br /&gt;By the way, if you yourself are not a geek, then just smile and back away slowly. You won't find anything here even remotely interesting, and probably for the most part it will just sound like speaking in tongues.&lt;br /&gt;&lt;br /&gt;So, a little about me, as long as you're here. I'm an application developer in San Diego, California. I work for a company that I don't care to implicate, as I'd like to reserve the right to bitch about them at some later point. But mostly I have nothing but good things to say about them. They work very sincerely at creating a culture that respects the employees, with the transparent goal of not having to pay us as much. It seems to be working for them. Company culture is a big deal to me, and I'll probably blab about it some more down the road.&lt;br /&gt;&lt;br /&gt;As far as my geek credentials go, I am currently a double agent doing both .Net and Java development. I've been programming for about 10 years, or a little longer than that if you want to call what I was doing in those first couple years programming. But I suppose we all start out that way.&lt;br /&gt;&lt;br /&gt;I have been a number of flavors of developer over the years, but only recently have I been able to finally get paid for doing non-Windows programming. I was a C++ guy for a few years, mostly ATL but some MFC as well. But for a long time before that I was a Visual Basic hack. Oh, the horrible spaghetti I wrote in the early days!&lt;br /&gt;&lt;br /&gt;I made two bets early on for both VB and Java, and taught myself both. I even got certified in both. But the VB was so much more in demand at the time, that I got sort of sucked into the Microsoft world without ever deciding if I'd like to or not. Eventually I got an MCSD, and I'm in the middle of re-upping to an MCSD.Net. While at the same time chasing an SCEA. I don't personally put much stock in the value or meaning of technical certifications, but studying for an exam is a good way to round out the the corners of a particular tech that you might not otherwise get exposed to.&lt;br /&gt;&lt;br /&gt;Back in the build-up to the dot-com boom, though, when a pulse was all that was required to score a high-paying job, the MCSD thing seemed to impress a lot of people. It seems to ebb and flow in importance. Feels like people are paying more attention to certifications again.&lt;br /&gt;&lt;br /&gt;My reintroduction to the Java world seemed to coincide with a gaining interest in all things Agile. Although Agile seems to be a newer word -- it was all about XP at the time I got interested. At that time, and still today, the whole thing felt a little culty and unrealistic. But there were and are quite a lot of really valuable pieces to be picked out of it. I am not an advocate of any One True Process, but I have definitely become a Unit Test Zealot. And I'm probably just short of being a Continuous Integration Zealot. I've seen and believed in the value of the nightly build since about '99, but once I stumbled onto CruiseControl, I thought, "There is just no good enough excuse to not be using this."&lt;br /&gt;&lt;br /&gt;My previous soul-sucking job, which I now just refer to as "the very bad place" left me feeling no creative spark from the work I was doing, so I decided to teach myself Linux. I think getting a MythTV out of it was the original goal, but I was quickly distracted by all the other neat stuff to stick to my plan. Then I got quite bitten by the Linux bug, and some of that self-righteous OSS stuff has started to rub off on me. It doesn't help any that the open source stuff I use just keeps working. Stay tuned for a rant on the evils of Weblogic. There just aren't enough voices out there &lt;a href="http://jaredtech.blogspot.com/2005/05/hey-weblogic-is-not-piece-of-crap.html"&gt;badmouthing that POS tool for vendor lock-in&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm hoping my bet on Linux doesn't take as long to pay off as my bet on Java.  I would &lt;em&gt;love&lt;/em&gt; to be able to pilot a Linux box all day to do my development, but since I'm planted firmly in both camps, and Java &lt;em&gt;does&lt;/em&gt; play nice with Windows, my options remain limited.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36663819-116190791601520991?l=devdeacon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devdeacon.blogspot.com/feeds/116190791601520991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=36663819&amp;postID=116190791601520991&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/116190791601520991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36663819/posts/default/116190791601520991'/><link rel='alternate' type='text/html' href='http://devdeacon.blogspot.com/2006/10/welcome-to-show.html' title='Welcome to the show...'/><author><name>Brian Deacon</name><uri>http://www.blogger.com/profile/09865087260155604763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
