I have a confession to make. My reputation may get damaged, I might get fired, and my family may disown me, but it's high time the truth came out.
Programming does not come naturally to me. At all.
Of course, I love doing it. The process of programming is the ultimate brain teaser. It frees you from the normal, arbitrary nature of the universe because it's rooted in logic, in ones and zeros. If something goes wrong, it's not because the universe is unfair. It's because you messed something up, which is awesome because that means it's fixable. Conversely, if everything goes right, you've created a small part of the universe that's completely in your control. You're making the rules. You're god.
But just because I enjoy it does not mean that I'm good at it. It does not come intuitively to me in the slightest. When I learn anything new it's an agonizingly slow process, and there are a lot of people out there who are much, much quicker at it than me. And in this business, you have to teach yourself everything from the ground up. Once I've figured out something new, I can do it pretty well, but there are still a lot of people who could do it better in a heartbeat. I like to think my love/hate relationship with the process is characteristic of anyone who is passionate about anything, but that's just speculation.
What this translates to is a whole lot of late nights for me. I'm the officially the company's Senior Developer, but ask Evan or Logan and they'll tell you I'm the company's Senior Code Breaker. However, that also means I'm the company's Senior Code Fixer. While I may particularly versed in breaking things, anyone who has ever written code has had to go through the delightful process of fixing it. The night will come when you're grappling with a seemingly insurmountable error. When that night comes, take a few tips from me:
- Don't Panic
It doesn't matter how soon your deadline is. Even if you have to have the server running tomorrow morning, demo in an hour, or get your website back up as soon as humanly possible, fear is the mindkiller.
The act of writing code is a creative one. Like painting, theater, or writing poetry, it requires familiarity with your medium, spontaneity, and an artistic touch. However, the act of debugging is a methodical one. You have to be able to immerse yourself in the code, follow each line's train of thought, and find the penny on the track. You become the art critic, the deconstructionist. You have to watch the dance, but instead of getting swept up in its beat and beauty, catch every misstep of every dancer.
Panic works against you in this setting more than any other. You need your wits about you, so you can't afford to lose them.
- Create an Escape Plan
As soon as you realize your code is broken, don't make fixing it your first priority.
First figure out what you'll do if you can't fix it, no matter how small the error may seem at first. Evaluate what you can to do to buy yourself more time: hardcode a quick and dirty fix, create a placeholder on your website, set up a pretty page to display if something goes wrong rather than just output an error message. Something. Anything. Prepare that escape plan before you try and debug. If you fix the error before deadline, just comment that code out and keep it around in case it happens again. If you can't fix the error quickly, you'll have a solution to fall back upon when you run out of time.
After you have your escape plan ready, figure out how long it would take to implement. If it takes half an hour to put up your dirty fix and you have to demo at 8am tomorrow, you'll know you'll be able to stop stressing out about your null pointer error and call it quits at 7:30. This will help alleviate your panic and focus on the task at hand. Knowing your broken code won't cost you anything more than time is the best thing you can do for yourself.
- Bring a Ball of String
Well before you start writing code, prepare to break it. Before you embark into the labyrinth of logic that is the heart of any program, realize that you're going to have to bring a ball of string with you if you're going to find your way to the Minotaur. That way if you take a wrong turn somewhere, you know how to get back and take the right one.
If you've just broke your code, that means that it was working not long ago. If you're changing code you obviously are trying to make something work better, but it is far better to have something working poorly than not at all, so keep track of every change you make. If you're using Github, commit often. If you're trying to update the server, back up all of your configuration files and write down the version number of every program you're about to upgrade. If you're modifying a database, duplicate the schema. If you're using an IDE, see if you can change the default number of 'Undo' actions remembered to a much greater number. One day you'll need to use each and every 'Undo' afforded to you.
Even with all of these tools in place, when I develop I have half a dozen untitled text files open with snippets of code before I changed them, so I can keep precise track of my every motion. Uncertainty is for the Heisenbergs of the world. This came in handy when writing this article: a client who borrowed my computer closed all of the windows I had open, including the blog post page I've been composing this on, instead of just the tab he was working in. I had a handy copy of what I'd written, updated every paragraph, saved in TextEdit. I've changed the defaults of pretty much every application I have to accommodate: my Paint program keeps track of every pixel I lay down, my Calculator program remembers every calculation I run, and even my video games have every version of autosave enabled. Then it just becomes a matter of leaving these applications open as long as you intend to develop to undo any poor choices you might have made. An ounce of prevention is worth a pound of cure, but if you're clever you can increase that exchange rate substantially.
- Call for Air Support Early
The generals who call for air support last minute are forgotten. They die. The generals who call for air support five minutes before that get to go drinking with the ground troops when the war is over. The internet is a powerful playground of information, but it's way too large to get the answers you need quickly. You have to get help early, long before your deadline.
Open up the first dozen search results on Google before you look at even one. As you read through each one and realize that they have nothing at all to do with the error message you're getting, take the time to figure out why. Then if the first dozen results don't give you the answer you need, instead of going to the next page of search results, refine your search to exclude keywords characteristic of the irrelevant results. Consider using advanced search results to include valuable sources of information like .edu or stackoverflow.com, or hide the ones that consistently fail you like forumtopics.com (do this with -site:forumtopics.com in Google). Repeat.
If you're going to post a forum question about your error, do it as soon as you get the error, even if the problem is a complicated one and you're just beginning to unravel it. As you start to figure things out, just update the forum post, because waiting until you have a very specific error with an exact line number gains you nothing. You'll find that people who respond can steer you towards the heart of your error faster than you could find it yourself. This also gives you a lot more time to wade through the irrelevant or unhelpful answers that well-meaning people will inevitably offer well before your deadline hits.
- Broken Bones Heal Stronger
At the end of the day, it is quite possible that you are still going to have broken code when the time comes to show something. When you get put on the spot, don't fret, and don't apologize--too much.
Remember that while your job is to produce a product, it's in everyone's best interests to do it right. Both you and your client want a reputation of being responsible for awesome things, and that can never happen if you rush. As frustrating as broken code can be, learn to appreciate the opportunity offered by fixing the code, and communicate that value to the client instead of begging for forgiveness. Unless you've committed to a ridiculous deadline, chances are if you haven't been able to fix things at this point there was something fundamentally wrong in the way you were doing things previously.
Perhaps when you installed nginx on the server you passed a parameter incorrectly, and the first time you try and update something that depends on it, everything goes to hell. It's a good thing you found that out before you handed the entire project over to your client's sys admin. Perhaps the basic logic you were using to structure your controllers in Rails breaks when you add a nested resource. Well, your fix will be a much more scalable solution. Even if it's over the client's head, assure them that the holdup in the project is necessary for the best possible work you can provide, and sing the praise of the new solution.
Programming is a two-steps-forward, one-step-back kind of a dance. When you get caught taking a step back, don't undermine what you do by profusely excusing yourself. Just explain that it's all a part of the dance, and learn to love the back-and-forth, ebb-and-tide, love-and-hate struggle that is the art of programming.