As software engineers our jobs are mostly breaking down abstract problem statements into code that computers can understand.
I think the biggest challenge here is to simply figure out what to do. How do you convert an abstract problem statement with complex objects, asynchronous data flow, multiple stake holders and complex logic into low level code that a machine can understand?
Break down the problem into smaller steps is common advice that is seen everywhere when talking about problem solving.
But how exactly? Where to start?
I think the best way to go about simplifying a problem is to write it down.
Simply write down the problem in your own words. Writing things down helps your mind to offload some of the information onto the screen or paper. Our brains are built for making connections, not remembering things.
While tasked with an abstract problem statement think about the following and write down:
- Why is solving this problem important? What is the impact? Who benefits from the solution for this problem?
- What are the different inputs and ideal output or finish state?
- How is the input taken in for processing? Through an API, event, database or any other data source? Does this raw input need any processing?
- What is the output format? Do you have to store it somewhere? Push an event? Or simply display it? Or maybe there is no output — maybe you are designing something?
- What areas of the code base would be affected by your solution? What areas need to be modified? Which teams need to know about this? Are there any teams/people that can help you out?
Once you have answers to these general questions, you should have a better idea on how to approach this problem. Talking to the people who are impacted by what you are about to solve really helps in getting a deeper understanding and might reveal some hidden insights that you might want to consider.
Right now the abstract problem statement has been simplified to a more definite form, that resembles an engineering problem with inputs, outputs and their desired formats.
Next you need to figure out the steps to be taken, things to build, functions to write, objects to build, services to run etc.. to take the input to its output form. Maybe you are designing/architecting something, in that case there is no clear output — the plan itself is the output.
Avoid writing paragraphs describing engineering problems or solutions. Write everything in bullets — this automatically adds some structure, and breaks it down into steps.
Do your research. Are there any tools out there that can partially or fully solve your problem? What are the tools that you are going to use to help you solve this problem? Are there any alternatives that maybe more suitable for your use case?
Gather as much information as you can about tools you could potentially use. While deciding what tools to finally use, do not just pick a tool because it seems better. Have a reason to pick it. Also have reasons not to pick the other tools you rejected.
Almost always you will find that what you are trying to do has already been fully or partially done before. If you cannot use the same thing to solve your problem, you can still refer to these solutions. You can look for inspiration, patterns, things to do, not to do etc.. from it.
By the end of this phase, you should have a clear plan about what needs to be done to get to your solution.
Now you know your inputs, what processing is to be done on it, the tools you are going to use and the final output format. Write down the final plan in bullet points.
Write down the all options you considered including the reasons for choices, alternate approaches you could think of and links to everything you referred to and could be useful.
Something my manager recently taught me is to always use an example when describing complex things. Take an example input, run it through you plan and see if you are getting to the desired output.
This especially works where you are building services, designing APIs or data structures. The specifications are not enough, work it out using an example.
Finally get a second opinion before you implement it or hand it over. A fresh pair of eyes can always spot things you overlooked or missed.
I think real talent lies in breaking down abstract problems into bite sized chunks that you can easily implement and explain.
If someone could tell you what exactly to do, what tools to use, design objects, what functions to write, where to write them and all the edge cases to consider, then anybody can solve it.
A lot of people can write code without errors in multiple languages, but a few people can simplify abstract problems and know exactly what to write or build. I think it is this skill of simplifying and breaking down problems that differentiates engineers from programmers and coders.
These are just a few things that I have learned from my managers and seniors over the last few years that I find useful. If you have any more ideas or improvements, feel free to share it in the comments or email me at firstname.lastname@example.org.
I also started a newsletter recently called Better Engineering, where I share engineering concepts, stuff I am working on and my journey of becoming a better engineer. Do subscribe to it if you love all things software engineering!