Thoughts on Doing Contract Work as a Software Developer

As I was recently looking for new employment I spent quite a bit of time deciding wether I might enjoy doing contract work full-time. I enjoy working on different projects and learning new things but there is one major roadblock to becoming a full-time contract developer. My personality doesn’t let me write software that is anything less than my best.

WARNING: Gross generalizations and simplifications below. I’m not trying to offend anyone, just describe my experiences.

Most of the contract work I’ve done has been for people who are not technically savvy. They come to me with a very vague idea of the software they want. They expect me to tell them how much it will cost before we’ve discussed specific requirements. When the requirements are incomplete or incorrect they expect that I’ll just fix it without additional cost to them.

Not all of my contract experience has been negative. In fact, most of it has worked out quite well. Usually both my client and myself are pleased with the software and the cost of building it. But I’ve had enough negative experiences to be careful when considering a new job.

Part of the problem is that it is nearly impossible for anyone to completely define the scope of a project. There is always some miscommunication or misunderstanding, there is always some unforseen problem.

“You want me to setup a blog for your company? No problem, I can get WordPress setup for you in an hour.”

“Wait, I didn’t realize that by ‘blog’ you meant store front application that can accept payments, handle accounts payable, accounts receivable and inventory tracking. That will take slightly more than an hour.”

That kind of situation actually isn’t bothersome to me. As a contractor it is part of my job to understand what you want before making a bid. If a potential client obviously doesn’t know what they want, I can either decline to bid on that job or I can adjust my bid to account for a large amount of unknown. I don’t love it, but that type of risk is manageable.

The part of contract work that I dislike is being forced to compromise quality. When I’m working on a fixed cost contract, it is in my best interest to deliver exactly what is specified, as quickly as possible. As long as my client is reasonably happy with the deliverable, I am going to get paid $20k regardless of whether it took two days, two weeks or two months to create. I don’t get additional money for clean code. I don’t get extra for having good test coverage.

When I complete a project more quickly than I had anticipated there is no problem. I can spend time verifying that the code is tight and that everything is working as expected. But if I am running behind schedule, it becomes more difficult to care about testing the code or fixing “little” bugs.

There may be a bug in the code where order totals aren’t calculated correctly, but what are the odds that my client will notice the bug before he signs off on the project? If he does find the problem and I correct it, will he think to test for that same bug in every release?

This is the dilemma that makes contract work difficult for me. If I see a bug in my code, I’m going to fix it. If I’m writing a tricky or important calculation (like calculating totals), I’m going to write a test. I need to have confidence that my code is doing what I expect. I’ve never shipped any software that didn’t have a list of known bugs but I have also never shipped any software in which I didn’t have a high level of confidence that it was working correctly.

For me, doing the bare minimum isn’t an option for two reasons:

  1. Quality is extremely important to me. I can’t just hack something together that meets the contract requirements. When I write software, I want to deliver my personal best.
  2. Most of the time, the fast/crappy way of implementing something simply doesn’t occur to me.

I understand a company’s need to understand cost before approving custom softare. But if you want me to do contract work, pay me on an hourly basis. I’ll give you a projected timeline for project completion.

With an hourly rate, you only pay me for the time I actually spend working. With an hourly rate I know that I won’t lose money just because I insist on high-quality code. We’ll both be happier in the long run.

I’m not an idiot… I promise!

I hate new jobs. I like getting to work on new projects, I like learning new things and I like meeting new people, but I hate the actual “new job” stuff. I don’t like looking for jobs, I don’t like interviewing, I don’t like being the new guy who doesn’t know anything. Due to circumstances related to the recent economic turmoil, I decided that regardless of my aversion, it would be a good idea to start searching for new employment.

I started looking and, on one of my first phone interviews, was asked, “What is an interface?”

I know what an interface is. I’ve written new interfaces; I can create a class that implements IComparable, IDisposable and IMakeMillionsFromCrazyIdeas without breaking a sweat. I can talk at length about why multiple-inheritance is pure evil and how single-inheritance, combined with interfaces, will solve every problem known to man. If you would prefer, I can argue the inverse. But, when asked, “What is an interface?” I babble like an idiot:

Oh, an interface is a thing that classes have and they start with an ‘I’ in C# anyway but it’s by convention not a requirement and they come after the class name and a colon and they help us to do things so that when other classes want to do something they know that our class can be used to do that thing because our class implements the interface.

I’s a rel gud programur. I got teh 1337 h@X0r skillz. yeah…

I knew the answer, but on the spot, I couldn’t figure out how to intelligently convey that knowledge. I hadn’t been asked to verbalize that knowledge for a long time. Since I don’t like feeling like an idiot, I spent some time googling “interview questions.” I don’t remember which site recommended the book, but I ended up buying Programming Interviews Exposed: Secrets to Landing Your Next Job, 2nd Edition.

Programming Interviews Exposed was a good purchase. If you you’re not already familiar with some basic concepts of computer science I doubt this book would be very useful. But for me it was a great refresher on concepts I use regularly, but hadn’t consciously thought about for a while. Who thinks about the nuts and bolts of programming when you’re in the zone, and it’s just flowing?

As you would expect from a job hunting book, there are chapters on the basics of job hunting: how to decide what companies you want to work for, how to find job opportunities, how to work with headhunters, how to negotiate offers, etc. I wouldn’t necessarily consider myself an interview-pro but, many of these tips just seemed like common sense.

The book describes methods for solving riddles and how to answer questions. It doesn’t just provide a bunch answers to memorize but discusses ways to convey your knowledge and experience to the interviewer (hint: keep talking and explain what you are thinking). The chapters that I found most useful were the computer science topics: linked lists, trees and graphs, arrays and strings, concurrency, etc. The book gives questions that might be presented in an interview then explains the answers.

To date, I haven’t been asked any of the questions presented in Programming Interviews Exposed. Reading examples of various ways to traverse trees and reverse strings was useful. The interviewer does not want return new string (Array.Reverse ("xyzzy".ToCharArray()));. It was useful enough that, when asked to calculate the weight of tree nodes and return a specific node in O(n) time, I felt confident in my answer.

Programming Interviews Exposed will most likely benefit those who are already familiar with basic computer science concepts. It’s a quick read and quite effective. Good luck with your next interview!