The key mantra my computer science professors worked hard to drill into us at college was always “Computer science is about solving problems, computers are simply a tool we use to do it.” As fun as it is to meme about the technical interview vs. the actual job, the reality is that we actually do have to figure out how to implement things that make the business money from time to time. When that happens, the ability to work through problems is what separates the successful developers from the code monkeys who can implement pseudo-code off a user story. And given some of the technical interviews I’ve sat in, it’s not necessarily a skill that’s developed when teaching people how to code.
“Asking the duck” is a classic problem-solving technique. Even if you don’t have a dedicated bath toy to talk to, simply defining the problem out loud and talking through the steps needed to solve it has done a lot to help me understand all the moving pieces involved, find questions that aren’t answered in the user story, and identify possible failures that’ll need to be handled. While it hasn’t given me the “Eureka” moments that the original blog post described, it has helped me identify approaches that weren’t going to work as well as re-frame what I’m trying to do in ways that started me down the path that ultimately solved my problem.
I’ve been working from home full-time since 2020, so talking to one’s self isn’t as frowned-upon in my “office” as it may be in 1 of those stupid open office floor plans. That’s why it doesn’t hurt to convert talking through your approach to an outline in a TODO comment:
/* * TODO: * 1. Read the file and map the line to my POJOs * 1a. If that parsing fails, grab the error message and line number, and write those (along with the offending line) to the error report file * 2. Add the POJO to my list of items to add to the database. * 3. Add a method to take this list of items to add to the database, and save them all in a single transaction block * 3a. If the method fails, send an error notification to the user * 3b. If the method finishes successfully, send a confirmation method with the number of rows saved to the user. */
It doesn’t force all the details out of me the way asking the proverbial duck would, but it does force me to organize my thoughts and sequence them. Plus it’s easy to add something if I forgot a bit, and I can delete lines as I complete bits and pieces of the implementation.
Speaking of writing things down, I’ve also had a lot of success working through how things should work on a dry erase board. I don’t know if it’s the association of putting how something works on white boards with professors explaining concepts in college creating a placebo-like boost of confidence, or simply the marker fumes, but the ease of jotting down anything (not just writing out sentences, like in the TODO example above, but also sketching out flow and relationships) and being able to easily erase something and try again helps visualize what I’m working on. Sadly it’s been over a decade since I’ve had a dedicated white board in my work space, but I still oftentimes do the same thing with a pencil and paper. That helps too, but just doesn’t feel the same.
Another tactic that’s helped me put something into focus is stepping away and doing something else. Specifically, “something else” that’s unrelated enough to what I’m working on that I have to come back to it fresh, and mindless enough that I can do it on auto-pilot, which lets my mind wander around the problem while I’m doing it. In college, it would be going for a run, playing a video game I’ve done on single-player 1,000 times, or even running out and grabbing a snack from somewhere. Sadly, that’s frowned upon in the full-time workplace these days (even working from home), but you can still always get up and move about the office to check the break room (you likely won’t find anything, but at least you’re walking away from the problem for a couple of minutes), or go to the farthest water fountain/bathroom from your desk. For anyone who wants to point out how it’s important for developers to be in a flow state – that’s only useful when you have a good understanding of what to do and are actively making progress towards the solution. This tactic is for people who are stuck in a rut trying to work something out.
Along the same lines of “walking away and forcing yourself to come back fresh,” I’ve noticed I can be surprisingly effective on days where I have a lot of known interruptions to work (meetings that aren’t directly related to what I’m working on, having to run out and do something during a lunch break, followed by having to pick up the kids later, etc.). Notice I’m not trying to argue “I work best under pressure” (those people are procrastinators with a history of getting lucky), but rather “I have short, non-continuous bouts of work today.” It’s not as good as getting in the zone (see #8) and really cranking stuff out, but I’ve found that on tasks I’ve been lost in the weeds on, going in and out of something forces me to focus both on the basics, and on keeping things as simple. That can sometimes do a great job of clearing mental cruft and getting me far enough along that understanding and processing edge cases is a lot easier.
When it comes to solving problems and working things out, it seems like nothing beats stopping and either documenting the problem and proposed solution, or walking away and coming back anew. The former works for understanding and validating both problem scope and implementation details, the latter works best of coming up with those implementation details in the first place. Timeboxing yourself can do a great job of focusing your initial implementation, instead of getting so bogged down in minor details that you end up with something hard to understand and thus hard to maintain. Granted, none of this is actually novel or original, but they are simple steps that help focus on, understand, and start solving problems, which is what we’re paid to do.