I will tell you everything I have learned about problem-solving during my more than ten years of work experience in software engineering.
This guide follows the universal problem-solving framework. That is why this can also be helpful for people who aren't software engineers.
Here is a shortened list of points of the problem-solving framework.
- Define the problem
- Generate potential solutions and choose one solution
- Implement and follow up
Let's dive into the points and implement the framework for the software engineering domain.
This is the most important step. If we do not define the problem correctly, we won't be able to solve it. Often, we don't formulate the problem correctly from the outset, or we don't have enough data to know what the real problem is. Not having a well-defined problem from the beginning is an issue, but, as we will see in this article, some of our steps will help us to do it.
Maybe you are using an old version of a software or library.
The combination of different hardware, operating systems, software, and different versions of the above will make each setup unique.
The uniqueness of each setup is one of the reasons that many software vendors ask you to send your system information when you create a bug report or report an issue on an open-source project.
When defining the problem, you need to consider the specifics of your system.
You need to isolate the problem. This way, you can find the root cause of the problem.
If you have a tricky issue and you think that your system contributes to the problem, try to reproduce the issue on:
Any software can be run in an isolated environment. Here are some examples.
If you are working on a desktop application, you can run the setup in a docker container.
If you're doing system development, you can boot the operating system in safe mode.
If you're doing browser extension development, you can disable other browser extensions.
In general, if you're working with a source code, you can isolate a feature logic or component from the rest of the system.
You might want to use previous (stable) versions of the software and see if the issue reproduces.
To ask the right question is already half the solution to a problem. – Carl Gustav Jung
You have reduced the scope of the issue and have a great candidate for the root cause. Great! Now is the time to find the solution to the problem.
One of the fastest ways to find solutions to software problems is a Google search.
Sometimes, we find the solutions pretty quickly. But, if the issue is not common, we need some more work.
Here we need some searching skills.
First of all, we need to find the language needed to describe the issue. Many times Google will give hints on the language used by more advanced users.
Let's consider a trivial example. Imagine that we are learning frontend development, and we want to design our new website in a way that will look beautiful on all screen sizes and will be easy to use on all devices. We will go to Google and type something like this: "change website structure based on screen sizes"
Quickly looking onto the search results page, specifically onto the search results page's titles and the "Related searches" section, we can find that the type of websites we are looking for is called responsive websites.
So if our initial query didn't have the industry term, we can use the term "responsive design" in the subsequent queries.
This is the industry jargon. Using industry jargon in your search queries is important. Many articles, videos, and posts on the Q&A websites use industry jargon. You will certainly find great resources when you use industry jargon in your searches.
Our initial query: "change website structure based on screen sizes", returned a lot of beginner-friendly articles. Some of these articles didn't use jargon in their titles. You might think it is okay to use simple words and avoid jargon, but that's not the best idea. Industry jargon will help you find solutions to non-trivial issues because they are written for professionals and advanced-level users.
We've seen a nice feature of the Google search. Being a total newbie in the problem area, we discovered terms used by professionals. Similarly, we can further improve our query step by step.
If we didn't find the answer with a simple search, we could use Google Search operators.
One of the most-used operators that will help us during the search is the text in double quotes like this: "problem solving in software engineering".
This will tell Google to fetch the pages only if they have the "problem solving in software engineering" phrase exactly as it is written (exact match). Variations and partial queries like "problem solving" will not be considered. For example, exact match search is helpful if you want to search with the exact error message.
Another helpful operator is the website name. If you want to search only inside stackoverflow.com website, you can add site:stackoverflow.com before or after the search query. For example:
You might think you can do the same if you search for the answer on the StackOverflow website.
You can do this, but keep in mind that this is a completely different search engine. This is Stackoverflow's internal search engine.
In general, Google is superior to internal search engines because of the PageRank and RankBrain algorithms and because, obviously, Google possesses more data and advanced search algorithms.
Keep in mind that some articles might not be available on Google's search engine. For example, a search on StackOverflow might provide results you might not find in Google's search results. This can happen if an article is new and Google hasn't yet added it to its index.
If I have lost you there, don't worry. If you check how Google search works, you will improve your search game.
Now that we have defined the problem, it's time to generate potential solutions.
We did the steps before and eventually found the root cause of the problem. The initial root cause can turn out not to be the actual one. We might find that out if we start applying the potential solutions.
In practice, potential-solution generation consists of two phases.
The rapid phase: We search for the solution on the internet, and we apply the suggested solutions. In a nutshell, we check if the problem has occurred to other people. Many issues are common, and the solution is already provided on the internet. We don't want to reinvent the wheel or stay longer with the problem, so it's wise to look for a solution on the internet as the first step.
The strategic phase: We accept that the problem is not simple and we give ourselves time to solve it. We take the problem apart and do deeper research.
Here we formulate hypotheses, isolate them, check the isolated hypotheses, and prove them wrong or right. We can start fixing the problem as soon we have found the reason.
Let's talk about the rapid solution-seeking process.
If we have a coding problem, it's not a secret that many of the answers will come from the Stackoverflow website. If there is an accepted answer, chances are high that the proposed solution will work.
Note that the process is similar for all other helpful Q&A websites, even in different industries and domains. Most of them have a notion of an accepted/recommended solution and upvoted answers.
If the accepted answer doesn't work, we tend to try out the other solutions that have been given positive usefulness points (upvotes).
If popular Q&A websites do not have the answers we are looking for, we can check the other pages in the search results. In many cases, there are great blog posts addressing the issue with detailed explanations, sometimes going into the fundamentals. They may help us to find the solution.
Remember one thing, though. Everything on the internet does not come with the highest quality. If an article for the solution to your problem ranks on the first page of Google, that does not necessarily mean that the article is the best among the peers and that the solution will work.
So, the answer wasn't on the community forum websites or even in the blogs. That's bad. That means you have a tricky problem. Either it is a weird case, or the software or library you are using is not that popular. Now, it is time to start the deep research phase.
It may be a good idea to read the docs now. I would start with the topics around the issue. If that is not enough and you have enough time, you can read more and more about the library or software. Note that the information in the docs should be up to date. If it turns out that that's not the case, then you can report an issue.
This is a crucial step. Whether your colleagues will be able to give you an answer depends on the question. The problem that you are facing today may be a well-known problem for your colleagues. Your team might forget to tell you about well-known problems or shortcomings of the system. Even if it's not a well-known problem, you might have a colleague who has deeper knowledge in the domain of the issue and can help you find the fix quickly.
You need to be shameless here. Not asking questions can be counterproductive. If your colleagues can help you solve the problem in a couple of minutes, but you spend more time figuring it out yourself without asking the question, then you're wasting time. That means you are not working efficiently.
If the rapid phase didn't help us to find the solution, we must give ourselves time and change tactics. This and the following steps show how we can do it.
We visited community Q&A websites in the previous steps. If nobody asked a question about the problem we are facing on the Q&A websites like Stackoverflow and the community and support forums, we can do it ourselves and ask the question.
Here's a way to maximize the chances of getting answers in the shortest possible time. Official vendor websites point out recommended places for community support. Many times you can find them in the "Contact us" section. There, you can find vendors' recommended Q/A websites for asking questions.
When a company indicates recommended places to ask questions, that usually means that their employees or the most active community members are regularly checking the questions there, which means there's a great chance to get quick and reliable answers to your questions.
You can see the React.js framework's "Where To Get Support" page below.
In any case, it won't hurt to ask questions on generic Q&A websites stackoverflow.com or on another related website of the Stack Exchange network in addition to the vendor forums.
Reading the documents as was stated in the previous steps would help us formulate the question in a way that would be easy for the community to answer it.
Additionally, Stackoverflow and other websites suggest including minimal code snippets and environment details so that people can quickly reproduce the issue and check their answers before posting them. This means that you would help people to help you! The isolated hypothesis checking process discussed above might help us to generate a minimal isolated snippet and attach it to the question.
You did the previous steps as fast as possible, and you posted the question on the community forums. You probably never took a break while doing all the steps discussed above. You may have been in such a rush that you didn't even notice how time passed.
But the whole world is not that interested in the problem you are solving! Community members are living their lives and aren't impatiently waiting for questions. Though, in some cases, you might be lucky and get a fast answer.
Now that you posted the question in the community forum, it's time to take a break!
The break would help in the following ways:
You can have coffee or refreshments, take a walk, or speak with colleagues. You can do other non-work-related stuff planned for the day, etcetera.
Sometimes you need to slow down to understand the problem. As surprising as this might sound, you might not have thought enough about the problem while doing the previous steps.
I remember a day when a colleague of mine was honest and said he had tried to solve a problem without thinking about it. He then realized that the problem was not trivial and that he needed to understand it to solve it. The reason he "confessed" was he wanted to tell us that the problem was tricky and that we needed to allocate a lot more time for it and avoid entering autopilot mode.
The order of the steps can be different for different people. For example, some people love to check the source code even before they check the documentation.
The source code provides the most accurate documentation.
Documentation can be incorrect or obsolete, but the source code cannot lie.
Note that you need to make sure you are checking the source code of the correct version of the software.
Obviously, the source code needs to be readily available.
Fortunately, the majority of popular software development tools are open source. That means that you can easily find their source code on the internet.
If the software is not open source, it's still possible to analyze its source code. Here's how.
If the software is on your machine and is written in scripting and interpreting languages like Python or Bash, then you already have the source on your machine. Easy.
If it's written in Java or another bytecode language, you can use bytecode decompilers to recover the code from the bytecode.
Here's what you can do if the software is hosted on the cloud or it's a software as a service (SaaS).
The backend behind the API, unfortunately, is a black box. You can't see the code that runs the backend behind the API. However, sometimes, you can get an idea of what's happening there.
Now that you have looked at the source code, you can debug the code in your mind. Many experienced software engineers can debug and run many lines of code in their minds.
You can use debuggers to debug it if the issue is in the software code you are working on.
If the issue happens on the library code, debugging is harder. It will take quite some time to set up a debugger on the library's source code. In most cases, this is unnecessary because you are not one of the library developers.
This step can be skipped by many of us. Your company might have dedicated support channels with software and library vendors. If this is the case, you already guessed it: Ping them.
When we were hosting a non-trivial setup on Amazon Web Services (AWS), sometimes we needed to go deep into the documentation to check how to configure some tasks.
We were spending considerable time on this until a colleague checked and found that our company had dedicated support from Amazon. This is not common, and it makes sense for big accounts.
Instead of spending time figuring out how to do the next advanced config, our colleague would fire an email to the support center.
The colleague didn't stop there. Turned out that there was phone support as well. Email support usually takes longer than phone support, right? So instead of sending emails, our colleague would immediately pick up the phone and call them.
I think the support team at Amazon Web Services hated him, but we loved him!
It is important to note that people working in support centers must know the documentation very well, and the chances are higher that they will give you great advice in a much shorter amount of time.
Moreover, support teams have access to powerful tools that are not meant to be shared with clients. Remember — with great power comes great responsibility. That's one of the reasons that companies don't give the public access to these sensitive tools.
For example, the Amazon Web Services support team sometimes did the configuration for us instead of telling us how to do it. They even made changes that wouldn't have been possible with the public user interface.
So, you've spent a lot of time on the issue, and it still isn't resolved? Well, there's a "weapon" in this case: Call it a day.
If it is time to go home, you can go home. Staying overtime to solve the problem during the day may be counterproductive for several reasons:
You have now stayed too long with the problem. You have some crystalized ideas about how the problem should be solved. It's difficult to come up with different approaches if you don't take a break.
Secondly, you might be tired. It is the end of the day, and you have spent much more energy solving a difficult problem than you would spend on a regular day. With a tired brain and body, you can't perform efficiently.
You will need full energy tomorrow, so you need a good rest. If you get high-quality sleep, you can even go to work earlier than usual. You will not be disturbed much when you work early in the morning, and you will have a mind.
So it's a good idea to move the overtime hours to the next morning. As a bonus, since you will come earlier than usual the next morning, you can leave sooner that day.
The solution, or even several possible solutions, may come to you while you're resting during the night. As you might know, this happens.
I listed some reasons you need to call it a day.
What if it's not the time to go home?
If it's around 4 p.m., you might also want to call it a day and work on a routine task that you have to do anyway.
No matter what process we use when generating solutions, we will have one or many solutions. We need to implement the solution that is the most efficient, maintainable, and doesn't change our existing system too much.
Sometimes, the decision is evident, and we can implement the solution.
Other times, the solution might require significant or risky changes. If that is the case, it's a good idea to talk with the team and together decide which path to take to solve the problem.
I've already talked about defining the problem, seeking the solution, and choosing the best one. The listed items are a critical part of problem-solving. The way a solution is implemented, however, is crucial as well.
In an ideal case, the implementation would be reliable, fundamental, fitting in the design flow, and clean.
There are situations when the best solution cannot be implemented because of shortcomings in our setup. In this case, we need to adjust the solution to the system or implement a suboptimal solution. Remember that something that works today is better than something perfect that would work sometime in the future.
Note that sometimes we might be unable to apply the best solution, not because of our system's shortcomings but because third-party software and services are the blockers.
Viola: You have solved the problem by finding the root cause, evaluating the solutions, picking one of them, and implementing it in our system.
We need to revert the fixes that didn't work.
When we stay longer with the issue, we tend to apply many changes, even the ones that do not affect the system in any way or worse than that, the changes may have a side effect on other system functions. We need to clean up the code that didn't help. Though, it will help a lot when the cleanup is done during the evaluation process - when the solutions are tried.
After the cleanup, we can do the delivery process. We need to After the cleanup, we can start working on the delivery process. We must ensure that we have thoroughly tested the change and that the code follows the accepted standards.
If everything is in place, we can send the code to be reviewed so that team members can evaluate the final solution.
If everything is fine, the solution can be delivered to end users. Since the delivery process is different depending on the type of software, I will not go into the details.
You just have solved a problem. You might have learned important lessons. You can document what you've learned because writing notes about the solution will crystalize the solution for you. Since you might forget the solution after a year, noting down the solution will help you if the problem occurs anywhere else.
I have a great advice for you that I have learned from one of my colleagues. It's a good idea to start doing this if you aren't doing it already.
One day we were pair programming with a senior colleague of mine. We were sitting in front of his computer. I saw a file that day that would change the way I work.
What was inside this magic file?
It was a simple text file containing server URLs, usernames, workarounds, fixes to common problems, and everything you might need to look up regularly. I could not believe my eyes. How could I have been in the industry for five years and have not come up with such a brilliant idea?
Quickly after, I created my version of the file.
I use this kind of file for each company and project. If you want to create the file, I suggest making it an offline plain text file. The file should be as simple as possible and, ideally, accessible with just one click.
You may want to add the solution to the problem you just solved to the file.
In Addition, if you posted a question in the Q&A forums, it would be great if you would provide the answer that worked for you. You would help the community.
Software engineers solve problems every day. Many of the issues that we see are new. This is because:
Software changes fast. With version updates, a piece of software can change drastically.
Software and libraries come and go, and a different set of software combined with different project requirements often creates unseen-before problems.
If we notice patterns in these problems and use a well-defined process to solve them, we will become great problem solvers in software engineering.
This guide introduced a framework for problem-solving and an implementation of the framework, with detailed sequential steps. Hope that you liked it!
You can find my publications on my LinkedIn profile page.
Please feel free to add additional steps you use when solving problems in the comments below.