Advance your career by losing hope

This week I finally decided to take the plunge: I started working on my résumé. That's right! After six years I have finally decided that it's time to get my career moving and so I have officially entered the job market.

Ah, job hunting! It's quite the experience, isn't it? I'd almost forgotten what it was like. There really is nothing like a good job search to make you feel like a useless, incompetent sack of crap!

I don't know about other industries, but this is definitely the case in the IT world. If you've ever looked for a job in software development, you know what I'm talking about. For every reasonable job listing you see, there are twelve that absolutely require a 10 years using laundry-list of excruciatingly specific technologies, strong interpersonal skills, a Mensa membership, and a strong track record of miraculous healing. And that's for an entry-level position. With a typical career path, if you start early, you should be ready for their grunt-work jobs by about the time your kids are graduating from college and moving back in with you.

The listings that have really been killing me, though, are the absurdly specialized ones. Not the ones that require 5 years experience with ASP.NET, C#, Java, Oracle, SQL Server, SAP, Netware, Active Directory, LDAP, UNIX, SONY, Twix, and iPod - they're just asking for the kitchen sink and hoping they get lucky. I'm talking about listings like the one I saw that required advanced training in computer science, a doctorate in medical imaging, and 10 years of experience developing imaging software. Or, perhaps, all those listings for a particular defense contractor that required experience with technologies I had never even heard of. I mean, I couldn't even begin to guess what these abbreviations were supposed to stand for, and I'm pretty up on my technology! When you come across a lot of listings like that at once, it can be a little depressing. "How am I ever going to find a job? I don't even know about grombulating with FR/ZQ5 and Fizzizle Crapulence GammaVY5477 or how to do basic testing of quantum microcircuits using radiation harmonics with frequency-oscillating nano-tubes on a neural net. Every idiot understands that!"

But the real killer for me is location. I'm in the southern tier of New York state, which is not exactly a hotbed of tech startups. I like the area and don't really want to move, but there's practically nothing here in terms of software development. The best possibility I found was a local consulting company 10 minutes form home. However, when I sent them a résumé, I got a message back saying that they were currently unable to add new positions due to the fact that they were going out of business. I've applied for a couple of other semi-local positions, but of all the possibilities I've found, the closest is about 50 miles from my house. Workable, but not a situation I'm crazy about.

I'm now starting to think seriously about relocating. I don't really want to move to the west coast, both because of the cost of living and on general principle, so I'm thinking of looking either downstate (i.e. New York City) or south to the Washington, D.C. or Atlanta metropolitan areas. All three of those seem to have a fair number of positions in software development.

However, I'm faced with something of a moral dilemma. You see, having been born and raised in upstate New York, it is my patriotic duty to hate New York City. But as a New Yorker, it is also my patriotic duty to look down on the South and New Jersey. That leaves me wondering whether I'm forced in to choosing Washington, or whether it counts as "the South" too and I'm just out of luck.

In the end, I guess I'm just not that patriotic. All three of those cities sound good to me. But New Jersey is another story.

The anti-agile

I think I've put my finger on the reason that, despite being a rookie in it's practice, I'm so enamoured of Test-Driven Development. It's because TDD, despite being an "agile" programming practice, is the very inverse of agile methods. It's good, old-fashioned design. The only difference is that it's dressed up to look like programming.

At least that's what I get from reading Dave Astel's thoughts on TDD. He's an advocate of Behavior-Driven Development. This is an evolution of Test-Driven Development where the emphasis is shifted from testing units of code to describing the desired behaviour of the system. The idea is that rather than concentrate on writing a test for each class method, you figure out what the system should do and design your test cases around that rather than around the program structure. (Apologies if I mangled that explanation - I only learned about BDD today.)

This is somewhat similar to the other expansion of the initialism "TDD" that I discovered early in my research - Test-Driven Design. Note that the emphasis here is on using the unit tests as a design tool, i.e. specifying the behavior of the system. In other words, the unit tests are not written to do testing per se, but rather as a vehicle for expressing the low-level system specification.

Having studied formal development methods, it seems to me that, at a fundamental level, practitioners of TDD and formal methods are really doing pretty much the same thing. They're both trying to describe how a program is supposed to function. The TDD people do it by creating a test suite that asserts what the program should and shouldn't do. The formal methods people do it by writing Z specifications and SPARK verification conditions. Both are creating artifacts that describe how the system is supposed to work. The formal methods people do it with verifiable mathematical models, while the TDD people do it with executable test. They're just two different ways of trying to get to the same place.

In a way, this seems to be the opposite of what agile methods promote. Most of the agile propoganda I've read advocates doing away with specifications and documentaiton to the maximum extent possible. In fact, I've even read some statements that the amount of non-code output in a project should approach zero. And yet TDD can be viewed primarily as a design activity of the type that, using a different notation, would generate reams of paper. The only thing that saves it is the technicallity that the design language is also a programming language. It just seems a little ironic to me.

I suppose that's really the genius of TDD. It's the type of specification activity programmers are always told they should do, but repackaged into a code-based format that's palatable to them. It's sort of a compromise between traditional "heavy-weight" design methods and the more common "make it up as we go" design. I don't want to say it's the best of both worlds, but it's certainly better than the undisciplined, half-assed approach to design that's so common in our industry.

More on TDD

I think I may have to break down and buy a book on test-driven development. Maybe Kent Beck's Test Driven Development By Example. I usually don't like to pay for programming books because they tend to be expensive, have low re-read value, and you can often get the information online. However, this is more a methodology topic than a technology topic, so that's not so true. Plus they don't have anything on TDD in the local Barnes & Noble, so I can't read it without shelling out. Rats!

I really just need to do some more reading and get a little more practice. There are still some aspects that I'm not quite getting. Then again, it's been less than a month since I started looking at TDD and I haven't had as much coding time as I would have liked.

The problem seems to be two-fold. The first is that I'm not yet certain how to write really good unit tests. Second, and the reason I was looking at Beck's book, is because I haven't seen any really good examples yet.

Most of the articles I've read suffer from the same pedagogical flaws as tutorials on object-oriented programming: they're too simple to be useful. An article doesn't provide enough space to work up to a good example. You either end up jumping right in on the deep end, which makes it useless for beginners, or you do something small, manageable, and not especially useful in real life.

Another problem I'm having is working with mock object frameworks like NMock. At this point I'm still working on where the line is between adding mock objects to my unit tests and refactoring things so that it's not an issue. I suspect this is because I have yet to internalize the line between unit and functional tests. Hence the need for a more extensive treatment.

It's only a matter of time and practice. Just my little experience with TDD so far make me feel that I've made significant progress as a developer. Which actually feels both good and bad. It's good to learn new techniques and improve. But on the other hand, I feel like kind of a schmuck for taking so long to get to the party. But at least I'm not the last one....

Metabar and weird templates

Konqueror with small Metabar panelThe other day I was playing with the Konqueror Metabar. The metabar is a handy little sidebar panel that gives you information on the selected file or directory, provides quick access links to the KDE "open with" and "actions" menus, file previews, and some other features. However, the default metabar theme in Kubuntu is kind of annoying in that, as this screen shot shows, when the panel is too small, long lines wrap over other lines and make the text basically unreadable.

So I tried building my own theme. Since the theme system is based on KHTML, you can build a theme using HTML, CSS, and JavaScript. It's just that it's weird HTML. Here's a sample of what the code for the "open with" panel looks like:
<div class="frame">
<div class="head"><a i18n image="run" class="title" onClick="this.blur();" hr
ef="function://toggle/open">Open With</a></div>
<li id="open" expanded="true" style="height:0px">
</li>
</div>

Note that the README for the Metabar code said not to change this markup.

My initial reaction to this was, naturally, "What the hell is this?!" Not only is this non-semantic, not only is it invalid, but it doesn't even make sense! Why the lone LI hanging out in the middle of the DIV? It's obviously where Metabar is injecting the KDE "open with" items, but why is it an LI? I would have thought a UL or another DIV would make more sense. What is Metabar injecting anyway?

I never did get a good layout. I couldn't seem to get the panels to correctly resize. All I really wanted was for them to expand to fit their contents. It should have been as simple as a "height: auto", but for some reason, it just didn't work. I'm not sure why - there didn't seem to be anything in the stylesheet that would interfere with that. Though it's hard to be sure without knowing exactly what the application is adding to the markup.

It might possibly have been something built-in to the binary. The default theme certainly seemed to be. The application's theme directory only contained one theme, and it wasn't the Kubuntu one. I guess I'll have to go to the source to figure out that one. Presumably Metabar is in one of the KDE add-on packages. I just have to figure out which one.

Tools I can't do without: VMware

We all have those few programs we can't do without. For the non-technical user, the list might include Internet Explorer and Outlook Express. For the hard-core geek, it might be Vim/Emacs, GCC, and GDB. As for me, lately I've found that VMware is way up on that list.

VMware Player running Kubuntu 6.10 under Kubuntu 7.04This is particularly the case when it comes to testing and evaluating software. If it's anything even remotely "big," such as Microsoft Office, or if it's something I'm doing for work or casual research and am not planning to keep installed, I'll just break out a VM, install the software, and then blow the VM away when I'm done. In fact, I keep a directory full of compressed VM images of various pre-configured test setups for just this purpose. When I need to try something out, I decompress one of the images, do my thing, and then delete it when I'm all done. It's kind of like the old-fashioned "take a disk image" approach, only way, way faster. Honestly, VMware makes things so easy, it baffles me that people still bother with physical test machines for testing applications. It's so...1990's.

But VMware is great for regular work too. The performance is quite good, so if you have even a middle of the road system, you can run medium to heavy-wieght applications in a VM without too much pain. This is especially useful if you happen to be stuck running Windows, because some things are just so much easier to do in Linux, such as getting the tools you need. Of course, virtualization can't beat running natively, but flipping back and forth between your regular desktop and a VM is a lot less cumbersome than dual-booting or having two computers.

Of course, my whole-hearted adoption of virtualization is not without its price. This week I found myself looking up prices on new RAM sticks for my desktop and laptop. The main benefit I envisioned? I could comfortably run more than one instance of VMware! It's the perfect answer to, "What could you possibly do with 4GB of memory?"

If you've never used any virtualization software, you really need to check it out. It's a godsend. I use VMware Player because it's free and available on both Windows and Linux. QEMU is also a fairly nice cross-platform solution. And for the Windows-only crowd, there's always Virtual PC. They might take a little getting used to, but it's well worth the effort.