Problem solving nuggets

I have been a software engineer for about 10 years now. Even after all these years, I still feel somewhat apprehensive whenever I start on a new project. I can’t exactly put my finger on it, and it doesn’t matter how many times I’ve done it before, there’s always some unknown element associated with every project.

Whenever I’m in a situation that seem daunting like starting a new project, I always apply a set of problem solving techniques. Some of you may think these are obvious, but personally, I’ve found them immensely useful especially when faced with complex problems and I’m stressed out.

I hope you can benefit from my listing them here. If nothing else, bookmark this article for future reference. Here are 13 problem solving nuggets I apply constantly:

1. Start with a positive outlook. The first thing you should do when faced with a difficult problem is to start with a positive outlook. Sometimes our first reaction is to fear the unknown. That’s pretty natural. However, I’ve realised over the years that it is the unknown that has given us, as individuals and as the human race, the curiosity to try new things and aim for the stars. Don’t fear the problem itself. Look at it as an opportunity.

2. Understand the problem well by asking questions. I distinctly remember my days in University where an entire classroom of would-be engineers have sat there having not understood an important point the lecturer had made two months ago. Yet nobody had asked a single question. Why is that? A lot of it has to do with the fear of looking stupid. Most of the time, I find people do have the same questions as I do, but for some reason are too afraid to ask them. Regardless, before you can solve a problem, you must first understand it. If there’s something you don’t understand, ask as many questions as you need to. There are no stupid questions, only those you do not yet have an answer for.

3. Approach the problem with an open mind. An old saying goes, “If the only tool you have is a hammer, everything becomes a nail”. What this means: The way you have done things in the past may not always work for all situations. In life, I find there are often many solutions to a given problem. Some are more effective than others. Some are more appropriate than others. When faced with a difficult problem, do not assume you know the answer at the start. Stop for a second and take the time to understand what the problem is truly about before applying a solution. Be open to all possibilities. Do not presume everything is a nail.

4. Look at the problem from the helicopter view. Sometimes the problem we are trying to solve isn’t the real problem at all. In order to solve a problem, we may need to take a helicopter view of the situation. From a different vantage point, we may discover that the problem we have focused on is in fact part of a bigger problem – one which would require a completely different solution. So, before attempting to put a solution in place, first seek out the “real” problem. Once you have understood the problem in its entirety and context, only then can you determine the best course of action.

5. Define the problem thoroughly. Take a minute or two to actually define the problem. In doing so, identify what the problem is about and what it isn’t about. When you understand the problem thoroughly, you may already know what tools you need to apply or what solutions to avoid because they are not appropriate. Sometimes, when given a problem, we can naturally assume it is something it is not and so can implement the wrong solution. It is often more effective to ensure you understand the problem, its symptoms and causes before proceeding. Ask what, where, why, how and whom. Write the problem down, draw diagrams, create plans etc.

6. Dissect the problem into bite sized chunks. Would you eat a whole apple in one mouthful? Probably not. In a similar fashion, some problems are simply too big to chew all at once. A useful technique for solving complex problems is drilling-down into the detail and continuing until each puzzle piece becomes manageable. Once you have a set of manageable pieces, solve each individually. When a given problem is broken into bite sized chunks, sometimes it is easier to see the patterns, tools to apply and the actions that need to take place.

7. Think through the issues logically. Simple problems don’t often require a plan of attack. However, given a complex problem or one which involves an extended time frame, having an actionable plan identifying what needs to be done is crucial. The plan is a good reminder for yourself of what and when things need happen as well as a communication tool for all the people involved. Creating a plan requires that you think through all the issues logically and identify all the relevant issues and constrains.

8. Look for similarities with other problems. Whenever you are faced with a problem, ask yourself whether this problem shares the same characteristics as something else you may have solved. Often, problems mask themselves within their context but the root issue is the same. If you find you have a problem which shares the same characteristics as something else, you may be able to leverage the solution you have applied to that other problem. I find this is most useful in conjunction with the previous tip. When a problem is broken down into its constituent parts, you’ll find some of these parts occur frequently in other places.

9. Don’t be discouraged by mistakes. Problem solving and making mistakes often go hand-in-hand. Sometimes in order to find the best solution to a given problem, we have to go through a hundred bad solutions first. The most important thing here is to remember that mistakes are ok. Don’t get discouraged. Don’t get frustrated. Use the mistakes as stepping stones to get to the desired solution. If you have gone through a hundred options to no avail, you have found a hundred ways not to do something rather than one hundred failures.

10. Don’t let your emotions get in the way. Emotions or stress can sometimes affect our thinking and judgement. Do not let these cloud your mind. In most cases, problems are best dealt with logically. Try adopting a rational mindset and let your mind govern your actions. Go through in your mind what the problem is, then identify the steps which are required to resolve the situation before taking action. If you find you are too emotionally charged, pause for a moment and let yourself calm down first.

11. Focus on the end state. Problem solving is about getting from one state to another state. This is known as traversing the solution path. Sometimes getting from the start state to the end state is not as immediately obvious as seeing how the end state can come from the start state. In many ways, this is like navigating using a map – we can either trace a path from where we are to where we want to go or we can start from the destination and work backwards. In many cases, I find it is useful to focus on the end state and then plan backwards until I get to familiar territory.

12. Take notes and record your progress. When a problem is open ended and you’re working in uncharted space, be vigilant with your note taking and record your progress. You may find months later an off handed note you made can be the breakthrough you are looking for. It may not be immediately obvious at the time, so record your progress and ensure you can trace back to the things you have tried and what the results were.

13. Check your answers and challenge your assumptions. As you progress, be mindful of the answers you have obtained and assumptions you have made. Ensure they are logically consistent and “makes sense”. Mistakes do happen, so check, recheck and then check again. You do not want to build your solution upon incorrect answers and assumptions. When you are satisfied with your solution, don’t forget to test it under various conditions, not just the most likely scenario, but also the edge cases. Only with rigorous testing can you be sure your solution meets the initial requirements.

Good luck! Remember these nuggets and apply any and all to the problems you are struggling with.

Related Posts

Given a task, there are essentially two ways we can approach it. Either, we can work as hard as we can until it is “done” or we can fix the amount of time we have available and do the “best” we can. The latter approach is known as “Time boxing“.

Time boxing is a very simple technique we often use in software development. It is an effective technique for tracking progress and simply getting things done. From a planning perspective, time boxing is useful, especially when things appear complex or daunting initially and we are unsure of how to begin.

From a personal management perspective, I’ve found that time boxing can greatly improve our productivity and effectiveness. Because it’s simple, anyone can do it – including you. I use it when working on open ended tasks, like writing, where neither the scope or the quality is well defined.

This article briefly discusses how we can apply time boxing to our daily lives and get things done.

What is time boxing?

Time boxing is about fixing the time we have available to work on a given task and then doing the best we can within that time frame. So instead working on something until it is “done” in one sitting, we only work on it for say 30 mins. It is either marked as done at the end of this period or we commit to another 30 mins at a later time or another day.

In software development, an agile team releases new versions of a product to the customer for testing in fixed length iterations, say weekly. The customer and the development team work together to identify the features to be included in each release based on the relative priority and complexity of each task.

What’s special about Time boxing?

There are always several things competing for our time. At any moment, each of us could have hundreds of outstanding things to do. This question immediately become important – How can we ensure we get as much done as possible?

I believe time boxing is special for four reasons. Firstly, by consciously being aware of time, it allows us to focus on doing the things that matter most. Secondly, it serves as a reality check on how much time we spend working on open ended tasks. Thirdly, because of the fixed time constraints, it can be an effective tool against procrastination. Finally, it allows us to work on things during the free gaps we have between our commitments and appointments.

Focus on doing the things that matter most

If the time available we have is limited, a rational person should immediately think about prioritising their outstanding tasks based on what’s important and urgent.

By using time boxing and ranking our outstanding tasks, we make ourselves consciously aware of how much time we have available. This allows us to focus our energies towards things that matter most. In this way, we get things that matter most done first.

There are many techniques for ranking tasks and I won’t go into them in this post. However, it’s worth mentioning “Quality Function Deployment” – which is a technique we use in software development and engineering to translate customer requirements into engineering specifications. In the simplest sense, for each feature, we multiply a number representing a customer’s perception of its importance by another number representing an engineer’s estimation of the complexity. The final result is ranked and the relative ordering gives us an indication of what we should implement given a certain time constraint.

Limiting the time spent on open ended tasks

Do you know people who are perfectionists? Those who are constantly tweaking things to make them incrementally better or just different? To a certain extend, I suffer from a perfectionist personality which is why I find working on open ended tasks difficult. I’ll use some examples relating to my writing to illustrate: Should this sentence be structured in a passive voice? Does this paragraph look ok here? Are there enough anecdotes in this article?

Because by their nature there is no distinction between done and not done, an arbitrary open ended task can take anywhere between 1 min and 3 weeks. Time boxing is particularly useful as a reality check when working on open ended tasks. By limiting the time we spend on a given task, as long as it is complete though not perfect, we can objectively decide when something is done. This frees us up to work on the next task.

Effective tool against procrastination

In my experience, people procrastinate for two reasons – firstly, when faced with a complex task they are unsure of how to start and secondly, the prospect of having to do something they’re not particularly interested in doing.

  • As a tool against complex tasks: Time boxing is useful here because it allows us to work on complex tasks over several iterations or in bite sized chunks. For example, writing a good article is a complex task for me and it is rare to be able to find one block of time in which I can write an article from start to finish. For me, it is more effective to write as best as I can within a fixed period, constantly refining and repeating this process until I finish.
  • As a tool against uninteresting things: Time boxing is useful here because it allows us to commit to an undesirable task for only a limited amount of time. It’s a lot easier to start working on something we don’t like if we knew we only need to work on it for the next 30 mins. For example, if you have to clean a messy house, instead of trying to get through the entire house in one go, try only doing as much as you can for 30 mins. When you have another 30 mins to spare another day and feel so inclined, you can continue.

Using free gaps between commitments

The composition of a day from person to person and day to day is different. For some of us, our calendars are completely filled with appointments and meetings. For others, our days are relatively unstructured. Irrespective of our calendars, we often have what I call “null” time. That is, gaps between commitments in which we are either waiting for something or have free brain cycles.

Examples of “null” times are: At the station minutes before the train comes. In the car on a winter morning whilst waiting for the engine to warm up. At the desk, after you have kicked off a full compile on a complex codebase.

Time boxing can be immensely useful during these “null” times. If you knew the train will come soon, the car will warm up in moments or the code will compile in a few mins, you can choose to use that time effectively and work on a relatively simple task you know can be done within that short “null” time.

In conclusion

Time boxing is an effective way for getting things done. By fixing the amount of time we spend on a given set of tasks, we can focus on doing the things that matter, give us motivation to start, prevent overruns and use our “null” times effectively. In contrast, if we worked on things until completion in one sitting, we’re less likely to start on complex tasks, more likely to overrun on open ended tasks and leaves us with less time and motivation to work on the next set of tasks.

If you are interested in finding out more about time boxing, you may find these links useful:

Related Posts

I’m not sure how many of you have heard of the phrase “Broken window broken house” otherwise known as the “Broken Windows Theory”. As a Software Engineer, this phrase holds special meaning because it describes software entropy – a condition we try to avoid. However, I have also found the meaning of this phrase is applicable to our daily lives, especially regarding how habits and patterns can influence our productivity and effectiveness.

Let me begin by giving you a bit of a background behind this phrase. Its origin can be traced back to an article written by James Wilson and George Kelling which was later turned into a book Kelling wrote with Catherine Coles. The book was titled “Fixing broken windows: Restoring order and reducing crime in our communities”. It addresses the question why some buildings in an inner city are beautiful and clean whilst others are run down, dilapidated and derelict. They write:

“Consider a building with a few broken windows. If the windows are not repaired, the tendency is for vandals to break a few more windows. Eventually, they may even break into the building, and if it’s unoccupied, perhaps become squatters or light fires inside.”

“Or consider a sidewalk. Some litter accumulates. Soon, more litter accumulates. Eventually, people even start leaving bags of trash from take-out restaurants there or breaking into cars.”

These examples describe how a single broken window, if left unrepaired for an extended period of time, can cause the inhabitants to lose respect, pride and care in their surroundings. When one window is broken, another will follow, and another. In time, vandalism takes place, crime levels rise and eventually the effort and cost to fix the condition becomes insurmountable.

For software, the “Broken Windows Theory” describes how rapidly a piece of software can degrade into entropy or “spaghetti code”. When a developer sees poor design or writes bad code and doesn’t fix the problem immediately, it sets a precedence for more poor design and bad code. Given enough poor design and bad code, the effort and cost required to address the problem become too big and it is simply easier to continue perpetuating the problem rather than fixing it.

For example, a developer seeing a software component someone else has written does not have comments might think comments aren’t important, required or necessary for this project. So they don’t write any. After all, if nobody is doing it, why should they? This is a natural reaction. However, soon you’ll have a system with thousands upon thousands lines of code which do not have comments or documentation.

In another example, a developer while attempting to write a software component, searches for other components in the system to use as reference but sees they have been written poorly. Fixing these requires too much work, so instead the developer exacerbates the problem by copy and pasting bad code to complete their task.

The book continues by describing the strategy for avoiding the decay and entropy is to solve the problems when they are small. When a window is broken, fix it immediately. In software, if a developer sees poor design or bad code, they should address it immediately.

I’ve found the “Broken Windows Theory” applies to our personal lives just as well. It isn’t constrained to solving crime and software engineering. Consider the following:

If I left some paper on my desk instead of filing it away at the beginning of the week, I find by the end of the week, I have a messy desk. If I left my clothes on the floor instead of the closet or the dirty laundry basket, soon I have a messy room with clothes everywhere. If I procrastinated on a task today, say paying the electricity bill, I find I don’t ever get to it until the day it is due and all my other bills don’t get paid either. If I left a single plate after dinner unwashed in the sink, soon there’s a sink full of unwashed dishes!

Do you see the pattern here? Instead of filing the paper away, putting clothes in the right place, paying bills the moment they come up or washing the dishes when required, procrastination can cause us, even if only at a sub-conscious level, to lose respect, pride and care in our surroundings. One piece of paper not filed, leads to more. One clothing item on the floor, is followed by another. Heck, there’s already 10 dirty dishes in the sink, what’s one more?

To avoid this slippery spiralling decay and disorder in our personal lives, I find that developing good habits and sticking to positive patterns are essential. Fix the problems and address the issues as they arise. Don’t leave that paper unfiled. Put it away immediately. Instead of dropping the clothes on the floor, put in a little bit of effort now and place them in the laundry basket. If there are dirty dishes, wash them immediately.

This applies to our personal and professional goals in life as well. Whatever your goals are, be committed to it. Do not approach them half-heartedly. I know this takes discipline, but if that’s what it takes, then you’ve got to do it. For example, I have committed to waking up early and consistently and I do so everyday. Not just on weekdays, but weekends too. Sleeping in just once, sets a precedence for future sleep ins. So try to eliminate thoughts like “I’ve already slept in 4 times this week, what’s another time?”.

If leaving a single window broken leads to more broken windows, then not fixing a window sends a message that vandalism is tolerated. In summary, the moral of this story is “Don’t live with broken windows”. If there is something that needs to be done or fixed, do so as soon as possible. Don’t let the problem escalate to a point it becomes too difficult or costly to fix. When that happens, it just doesn’t get done.

For more information about the “Broken Windows Theory”, you may find the following resources helpful:

Related Posts