It can be difficult to create a mental model around the act of problem-solving. Having a full understanding of what steps are necessary to solving a problem goes a long way to becoming an efficient and effective problem solver. I will attempt to map out some of the steps that I've identified as a useful rubric for me.
- 1. The first step is to make sure that you fully understand what the problem is.
Identifiying what attributes this problem has, what the effects of the problem are, and who are the people suffering because of it. These are all important questions that should be answered. Thankfully, most of them are easy to answer!
Quick note: in the context of building software, a problem doesn't necessarily mean that there's a bug in the software. It could also mean that there's a feature that needs to be built.
Do you know what is missing because of the problem's existence? What change will be enacted by changing the code and altering how this specific code works?
If you're an engineer, do you know what benefit stakeholders will appreciate when the problem is solved? What is the motivation, both internal and external, that is causing stakeholders to ask for this problem to be solved?
These are questions that need to be extremely solid and firm in your
understanding. Once you know how to identify the problem, you now need to understand what it would mean for the problem to be considered "solved".
- 2. The second step is figuring out what the goal is.
The inverse of understanding what the problem is causing is called "Acceptance Criteria". What needs to be true in order for this problem to be considered solved? What is the end result that is being looked for by the people asking for this problem to be solved?
What can you point to and say, "This problem is solved, because X and Y and Z are all true." This is different for every problem, and I won't attempt to give you a standard, but this is ascertained by communication, understanding the problem, and knowing what tools you have available to solve the problem.
This then moves into understanding what constraints are in place stopping you from solving the problem right now. Why does the problem exist in the first place?
- 3. You need to identify what needs to be different for this problem to be correctly solved.
This is slightly different than #2. This isn't referencing what actual condition needs to be met for the problem to be considered solved, it refers to the makeup of the problems specifics that block you from meeting that condition.
It's possible that there are no actual blockages to solving the problem. If the answer to that question is "Nothing", that's great! This will possibly be easier to do.
- 4. Map out all possible ways to solve the problem.
I like to write down the possible solutions to the problem and eliminate any non-viable solutions. You won't know every
possible way to solve a problem, as that comes with time! This is where the expression "pattern matching" comes into play. As one gains experience, you can attempt to (correctly) apply successfully applied solutions from past problems to this new but similar issue. Figure out what you do know, and see if you can gather up any additional possibilities that you don't know about yet.
- 5. Attempt to identify viability or non-viability.
Once you have written down in a mind-map, or a list, (or less formally, not written, I just find that easier) - follow the steps needed to actually implement that solution, and see if there are any unsolved issues or constraints to that solution that you didn't foresee. This can be by actually writing code, or just thinking through the steps if they are simple. I like to bounce them off other people, but a rubber duck helps too.
Occasionally, that will render a possible solution non-viable. That's ok!
That's just more information you can use to solve the problem.
Eventually, it will also help you communicate upwards to the stakeholders who are awaiting more information about this specific problem.
- 6. Gather information
Once you have your list, depending on the critical-ness of the
problem/difficulty of possible solutions you've gathered, it's now time to consult with peers, and crowd-source any possible solutions you may have missed.
Very often, someone will mention something you didn't know or present a thought that didn't seem relevant earlier but will lead you to a new way to solve the problem!
Next step, implement the solution!
Recently at work, we needed to switch email providers that our transactional emails were being sent through.
The problem was: We were spending too much money using our old provider, our user information was fragmented and needed to be consolidated, and our marketing team was less effective because of our current email provider.
The acceptance criteria: In order for this problem to be considered solved, the emails needed to be sent by the marketing automation tools we were currently using, without any change to the current functionality of the way we send emails. This would mean that marketing would have their emails in the right place, Finance was spending less money overall, and everyone would be happy.
The constraints: The target platform requires that a user have an external_id which they can then identify the user with, and then send the email internally.
This requires us to save state, and somehow make sure that the (new) user was in their system before sending out the email.
With this understanding, I knew that changing our current system was the only possibility.
In addition, it had recently become a lower priority.
As a result, I had actually delegated it as a learning task to a different engineer.
End result? We now have this blog post. Let me know if I missed anything.
Comments and questions always welcome!