I made a mistake. While implementing a feature, I got stuck and spent a little bit too long spinning in circles before I figured out my problem.
While I was scrutinizing the front end, the mistake was (of course) hidden in the furthest possible back-end location. When I finally discovered the error, I felt silly and a bit stupid, and I couldn’t believe it had taken me that long. I immediately took a step back and thought about how I’ve approached being stuck in the past and what I could do differently next time, both before starting the feature and while working on it.
1. Predict Potential Errors in Advance
This piece of the puzzle comes into play before any code is written for the feature. Take a look at the state of the story board and the most recent commits. Identify what recent changes are in the code you plan on working with. When you’re thinking about how a feature will be implemented, identifying the areas of highest complexity and risk will give you a heads up on things that might cause confusion later. It’s a lot easier to see now than it will be once you’re deep into the specific piece of code that’s causing problems.
2. Approach the Unknown With a Plan
My professional career has taught me the importance of taking a clean methodical approach to problem solving. Agile development and test-driven development are two methodical approaches that are invaluable for creating strong code in bite size chunks. For debugging or adding new technologies to an application, time boxing by dedicating 30 minutes at a time to finding the answer is another plan that can reduce risk and increase productivity by creating a better awareness of amount of time being spent on a particular task. Having a plan keeps me from chasing my tail and helps me make small concrete steps towards finding a solution.
3. Carefully Analyze the Issue
It’s so easy to think we know what’s going on and not look any further. It’s important to remember to take a step back and analyzing the behavior of the issue. Some questions I like to ask myself are:
- Under what conditions does the issue appear?
- Can I add anything to my unit tests to increase my confidence that the systems I’m using are working as expected?
- How would I explain the problem to a non technical person?
- Can I create a white board diagram that draws out all of the different layers of code that are a part of this issue?
4. Focus Debugging Time on Learning the Technology
When debugging, it’s better to add value to the project by spending time learning more about the technologies involved using rather than aimlessly internet searching. Time spent looking over the documentation about how the technology works is much more valuable than time spent trying to copy and paste in code from the results of a google search. An understanding of how the tools you are using are working for you is useful for problem solving now and in the future of your project. Who knows, maybe you’ll discover a more efficient approach you didn’t see before.
5. Ask for Help
The beauty of pair programming is that often times asking for help is not necessary, since help is already right next to you. It’s so much easier to think things out with someone else’s ideas and criticism to work off of. When not pairing or when both pairs are stuck, however, it’s important to ask for help. Teamwork and knowledge sharing are a huge part of our culture, and you never know who is going to have the idea that will set you back on course.
When all else fails, I like to context switch away from the problem and come back to it.
How about you — what strategies do you employ when you get stuck?