August 21, 2021
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:
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.