Complex Problem Solving

Complex Problem Solving

People often struggle when trying to solve complicated problems. This may be while preparing a plan for a large project, in analyzing software bugs, or even in something like deciding which house to buy. In all these situations people may feel overwhelmed, not know where to start, get stuck or go round in circles. The causes often boil down to these behaviors:

  1. Trying to solve the entire problem at once
  2. Working in an unstructured way

In this article, I would like to explain a way of approaching these kinds of problems making them easier to solve.

Example 1: Struggling to create a project plan

Suppose you need to prepare a project plan to build a complicated feature. Motivated to do a good job, you consider as much as possible: different technical design options, some scope that is still open for questioning, time to market, your development capacity, the user experience...

So you set off to try to find a solution that satisfies all parameters. But faced with so many of them, soon you no longer see the forest through the trees. The problem has become too big to handle and has led to gridlock. To get out of that, we can do the following:

Create bite-size steps. Make the problem smaller so it does become manageable. Solve those bite-size pieces one after the other, each time ignoring any uncertainties that should be answered in later steps. Then execute those steps in a structured way and make every step count

So here's a possible structured approach to creating a project plan:

No alt text provided for this image

In this framework, you can see that we have defined some steps that we can do independent of any later steps. Probably, there are dozens of things you feel you can't say with certainty without working out some later steps, but you should ignore those and trust that you will find an answer later. For now, if necessary, simply make some assumptions, go for your ideal, or maybe just describe a few options that you will work out individually later.

For example, you may be unsure about one of your user journeys because you may fear that you won't find a design for it, or that it will be too expensive to develop. When this happens, fight the temptation to try to also pin down the design right now. Instead, make an assumption. E.g. you could decide to go for your ideal user journey for now. You can always come back to this step and reevaluate your user journey if it was too expensive. But by going through this process, you will end up with a concrete yes or no with much less uncertainty remaining.

People often struggle with this "trust" part, especially people who are intimately familiar with the details (software developers mostly are). This is counter-intuitive for many because in normal circumstances they are expected to know and deal with those details. Not solving something now to get to a solution quicker feels unintuitive and uncomfortable, but is necessary nonetheless. If you don't, you will remain in the situation that you have to consider too many parameters.

Later, it may turn out that your assumptions were wrong and that you've ended up in an unsolvable situation. Then you simply go back to a previous step, make the necessary changes and move forward again. For the framework to work efficiently and effectively, you should not skip any steps moving forward and always execute them in order. Maybe you will only have to reconsider some steps for a minute before moving on but make sure to revisit all subsequent steps because they may have been impacted.

If you're stuck, you're probably not respecting your bite-size pieces. You may be trying to create the design while figuring out the milestones for example. When you notice this is happening, stop what you're doing and force yourself to focus on this step alone.

Example 2: Investigating a complicated software problem

Suppose we are tasked to analyze a particularly pesky problem in our software, but we have no idea whatsoever what could be causing it nor do we have any idea where to start.

When this happens, people often just randomly start to check things. They won't deliberately waste time, but because they have no idea where to start, they randomly start shooting at things hoping to find something. The problem with this approach is that we are gathering information without really understanding where we're going and more importantly: this information will often not allow us to eliminate any options nor make any real progress in the analysis.

Again, let's apply our solutions (using bite-sized steps, executed in a structured way) and see where this leads us to. We could, for example, use the following framework to investigate software problems:

No alt text provided for this image

Start with "Understand the problem". Make sure that you know which problem to solve. Very often, people think they understand what the problem is, only to realize after several hours that this wasn't the problem after all.

Next, "understand your ecosystem". In this case, this means that you should understand the architectural design and the technologies involved. Without this understanding, how will you assess whether a 3GB memory footprint is normal or not? How will you asses whether an operation that takes 250 milliseconds should be considered a problem or not?

Then, come up with some potential causes. This is a crucial step and a good test to see if you understand the problem, architecture, and technologies enough. If you can't come up with any cause, you probably don't. Go back to the previous step and do that first. If you don't have the resources (documentation...) to truly understand the design, then you can't do your job effectively; force the team owning the feature to provide that documentation.

Even though this step should be obvious, people often don't start their analysis this way. Especially if they haven't developed the code themselves (e.g. support people or developers from another team). They may not have a cause or a wrong cause in mind simply because they misunderstood the design. This can lead to a lot of time being spent on gathering information that may not be of any value.

Then come up with a test that allows you to narrow down to your causes. This test can either confirm or eliminate one or more potential causes. If your test doesn't allow you to narrow down to any of your causes, or you can't draw any conclusions from it, don't bother with it; it's a waste of time. These considerations are represented with the back-arrows in the framework above. They are vital and there to help to ensure you only do things that matter.

Keep in mind that every step needs to allow you to make some progress in your analysis, to progress in the flowchart you have in mind. If it doesn't, this isn't a step worth taking.

Example 3: Career change

So far, I have used two examples that are related to the software industry, but these principles can help in many other areas. Here is a completely different example.

Suppose you're up for a career change but don't know what you want to do, and you are concerned about the implications on your personal life or family. Some jobs may require you to work weekends, some may require you to travel more, others may mean you earn less money... All these things can have a significant impact on your life. This can quickly make this problem too big to handle. So, like with the project plan, dividing the problem into bite-sized pieces may help. Here's a diagram showing what these pieces could be for this example:

No alt text provided for this image

As with the previous examples, the solution is to create bite-size steps where we ignore things that we will figure out in later steps. Then we will execute these steps in order, each time making sure that every step counts.

Summarized

  • If a problem is too big to handle because it has too many dependencies, questions, uncertainties or possibilities, divide it into smaller steps that you can handle. More importantly, force yourself to ignore any uncertainties that should be answered in a later step.
  • If you are going in circles trying to solve a problem, approach the problem in a structured way and make every step count towards your goal. If a step doesn't get you closer to your goal, don't do it.

要查看或添加评论,请登录

Michael Vanhoutte的更多文章

  • Reconciling an Agile Plan with a Long-Term Roadmap

    Reconciling an Agile Plan with a Long-Term Roadmap

    An agile plan is not the same as a waterfall plan, just like an agile roadmap is not the same as a traditional roadmap.…

    15 条评论
  • Creating Effective Presentations

    Creating Effective Presentations

    We often struggle to present information to other people who don't have the same knowledge as we do or don't see the…

  • Transitioning from on-premise to SAAS

    Transitioning from on-premise to SAAS

    Transitioning an on-premise deployed application to a (potentially multi-tenant) SAAS application running in the cloud…

    1 条评论
  • Understanding Quantum Computing for Software Developers

    Understanding Quantum Computing for Software Developers

    Quantum computers are a new generation of computers based on the principles of quantum mechanics. It is a technology…

    6 条评论
  • Don't let imposter syndrome choke you

    Don't let imposter syndrome choke you

    Here's a little secret. I suffer from imposter syndrome.

    3 条评论
  • Creating a Test Plan

    Creating a Test Plan

    Does this sound familiar? As a developer in a dev-team Have you ever wondered if you've created sufficient test cases?…

    2 条评论
  • Becoming a Technical Leader

    Becoming a Technical Leader

    This article is for software developers who aspire to take up more of a leading role within their organization. It…

    4 条评论
  • The merits of Design Diagrams

    The merits of Design Diagrams

    You’ll find many articles online describing how to create very detailed design documents covering things like business…

    11 条评论

社区洞察

其他会员也浏览了