Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Most developers love to write code. Many of us code in our free time. This is where weâre most comfortable. Itâs what weâve been trained to do. When it comes to our jobs, itâs easy for us to see ourselves as coders. Itâs easy to believe that our job is to translate requirements into code.
Our job is not to write code. Our job is to solve problems.
Even if youâre not a professional, itâs still not enough for you to just codeââânot if you want to be good. Itâs not enough to know how to work with standard algorithms. Itâs not enough to memorize languages, design patterns, and best practices.
Good programmers know how to problem solve.
To move from coding to problem-solving, we need to change how we think and how we work. This begins with a change in perspective. Then, it involves understanding how to problem solve.
Problems, Problems
The first step in understanding how to solve problems is understanding problems themselves.
Most problems are more complicated than people realize. They have many facets. Like chopping off the head of a Hydra, if you get rid of one problem, many others can come to take its place. Problems have perspectives. A problem for one person may not be a problem for another. It may be a benefit!
Hereâs a âsimpleâ example. Consider a small town with one market. Customers of the market are complaining because the price of apples has gone up. Apples are a staple of the diet in this town. The market owner is refusing to lower the price of the applesâââeven though apples in the market of a neighboring town cost less.
What is the problem here?
On the surface level, you could say the problem is that the market is charging too much for its apples. But this simple analysis misses important things.
Perspective
To start with, there are several perspectives on what the problem is:
- From the customerâs point of view, the problem is that the price of apples has gone up.
- For the market owner, the problems are rising operating costs, short-term financial difficulties, and difficulty selling other fruits.
- For the marketâs fruit supplier, the problem is that the market isnât selling enough apples. They have a surplus of apples that will soon go to rot in storage.
- Some other businesses in town are actually pleased by the circumstances. For example, the local cafe has started selling apples at a lower price than the market. People are now coming to the cafe to buy apples. This has incidentally increased their sales of coffee, and sweets.
Knowing the perspectives of the different groups affected by the problem lets us know what outcomes they want. While this is helpful, it also creates a new set of problems:
- Which outcome do we decide to work forâââi.e., which groupâs problem do we decide to solve?
- Is it possible for us to meet the needs of more than one group? If so, how do we do that?
- Solving one groupâs problem could cause problems for another group. How are we going to handle those problems?
- What do we do about groups whose needs arenât met?
Understanding the Problem
Then, thereâs our perspective as problem solvers. What biases are we bringing to the situation? How much do our own needs, and our tendency to not see our contributions impact our ability to fully see the problem? How well do we really understand the problem? In a fast-paced world, where quick answers are often rewarded, itâs easy to take the stated problem at face value and rush to solutions.
However, if you canât think of at least three things that might be wrong with your understanding of the problemâââyou probably havenât spent enough time with it. As you can see from the simple example listed above, lots of things can be missing from a problem definition.
Itâs not just the problem definition that can be rushed. If you canât think of at least three solutions to the problemâââyou probably havenât spent enough time brainstorming.
Consider the problem of maintaining a specific level of water in a tub. What are our options? Many people will say: âThatâs simple! Fill the tub up with water to the level you need, then plug it with a stopper.â Is this the best option? Maybe. It depends. Why do we need to maintain this level of water in the tub, to begin with? What problem is that solution designed to solve?
Letâs assume, for now, that we do need to maintain the water level in the tub. Is plugging the tub the best solution? Itâs not the only solution. Here is another one:
- Start with a tub full of water. Open the drain, letting water out. When the tub is at the desired level, turn on the faucet so the rate of water flowing in is equal to that flowing out.(1)
Is this a better solution? It depends on the problem that maintaining the level of water in the tub was designed to solve.
Context
In addition to perspectives, problems have context. If we just look at the problem on a surface level, we may be missing important information. Letâs return to our problem of the market with the increased price of apples. What happens to your perception of the problem when you start asking a few background questions:
- Why did the market raise its prices?
- How long has the market been charging its current prices?
- Is the price increase temporary?
- How do those prices compare with the competition?
- What is the history between the market and its customers, suppliers, and the other businesses in town?
The answers to these, and many other questions, could change how we view the problem dramatically.
The Hydra
Letâs say that we came up with a âsolutionâ to our apple problem. We determined that the market needed to lower the cost of apples. This satisfied the customers. However, now we have new problems.
The market had to absorb the increased cost of apples. Therefore, it could no longer afford to sell oranges. This didnât have a significant impact on the townâs population. They didnât like oranges much. However, it did impact the marketâs relationship with their supplier. The supplier, now, is threatening to drop the market because itâs no longer meeting its minimum fruit order. Furthermore, if the supplier drops this market, it will drop all markets in the surrounding area, because there will no longer be enough markets for the supplier to continue to make a profit.
The town cafe, which was selling apples on the cheap to draw in customers, no longer has that draw. They are experiencing a downturn in business, for which they are not happy. So⊠now our poor market owner has all kinds of people furious at him!
Your Relationship to the Problem
As weâve discussed, every problem has a context. Itâs important to keep in mind that the problem solver is also a part of this context. Your relationship to the problem has an important impact on your ability to solve it well.
- A web apps developer in New York is probably not the best person to solve an apple pricing problem for a small German town. Best to let the townspeople solve the problem. It matters more to them, and they have to live with the solutions implemented.
- If you are emotionally involved in the problem, you have to be very careful because your judgment is likely to be clouded. You could, for example: stand to benefit from the problem, be very angry or sad about it, feel threatened or scared. Strong emotionsâââhappy or sadâââoften drive us to ignore important information and options.
- If you know the problem space very well, this can also be a limitation. Confidence or familiarity can drive you to blindness or default thinking. As Shunryu Suzuki has famously said: âIn the beginnerâs mind, there are many possibilities. In the expertâs mind, there are few.â
Summary
- Problems are almost always more complicated than we think they are. This can easily become apparent when we consider the problem from multiple perspectives.
- Itâs helpful for us to understand our perspective on the problem, and contrast it with other problem solvers.
- To really understand a problem, we need to know its context. This means that we must spend time with it and ask a lot of questions.
- Solving one problem often leads to the introduction of not one, but many other problems.
- Make sure youâre the right person/group to solve this problem. Ideally, the people who have to live with the solution should be involved in solving the problem.
- Be aware of your relationship to the problem, and how this can impact both your ability to understand it, and to solve it.
But wait, you may be saying, I solve problems all the time and I donât deal with all this craziness! Enter some of the most difficult factors in problem-solving: Time, Linearity, and Systems.
Time, Linearity, and Systems
Because of feedback delays within complex systems, by the time a problem becomes apparent, it may be unnecessarily difficult to solve.âââDonella Meadows
Time is one of the most complicated factors in understanding the impact of an action. When there is a time gap between an action and a consequence, humans have difficulty making causal connections. This fact is eagerly exploited by credit card companies who allow you to buy now and pay later.
The issue of time is compounded by the fact that, as engineers, we work withâââand withinâââsystems. In addition to this, we tend to think linearly in simple patterns of cause and effect. However, systems are more complex. They often have multiple things happening at the same time. Systems are jumbles of connections in many directions, simultaneously. A symptom in one place could be the result of several causal factors. Changing one of those factors can have unpredictable impacts.
If you have a situation where you seem to be stuck with long-term problemsâââyou may be dealing with feedback delays or patching symptoms. In these situations, it can be very difficult to see the systemic connections and relationships that are driving circumstances.
Problems are often more complicated than we seeâââespecially when time and complex systems are involved. It is easy to believe that a problem is solved, only to realize with time or new information that itâs notâââor that other problems have come to take its place.
Letâs Bring This Back to Code
At the beginning of this article, I said that just knowing how to code wasnât enough. You had to know how to problem solve. So far, all the examples weâve looked at havenât involved code. Surely, when weâre dealing with code, things are different⊠right? Nope.
Letâs look at an example of a simple, common interview task:
Write a function that counts the duplicates in an unsorted array of numbers.
That seems pretty straightforwardâââat first glance. But, weâre a bit wiser now than we were before. What could we be missing?
- What data types do we have to work with? This will matter if weâre writing the algorithm in C++, for exampleâââless so in JavaScript. We also might have to know how big the numbers are (16-bit, 32-bit, 64-bit).
- How big is the array?
- What happens in cases such as: Incorrect values, no values, or the wrong data type?
- Do I know anything about the expected number of unique values? If there are only a few unique values, this could impact the effectiveness of certain algorithms.
- Are there specific performance constraints?
- How will the function be used? Is it for use in a library? Is it a utility function? Is it local to a component?
What other questions would you ask?
This is another good example of how a seemingly simple problem statement is more complex than it appears. It is also, incidentally, a good example of how decay and complexity can enter a system. There are lots of algorithms just like this one in most applications. These functions start off simpleâââoften due to a simple understanding of the problem theyâre trying to solve. Then, they get refactored for various reasons. Those reasons are rarely documented. Sometimes, theyâre validated with unit testsâââif a unit test is appropriate. The impact of this multiplies over time, as the refactoring done for one scenario impacts the refactoring done for a previous scenario. With each refactoring, functionality can be subtly impacted, and information lostâââthus creating new problems that may only be discovered over time.
Summary
So, whatâs an engineer to do? Problem-solving is⊠a complicated problem! There are a lot of possible answers. Here are 10 things to keep in mind:
- Take more time to sit with your problems. Slow down. Donât jump to solutions. Flesh out the details of the problem. Ask questions. Talk with the people involved and get their perspectives.
- Problem solve with others. Different perspectives bring more information. Every problem faces issues of understanding. There are things we know, and things we donât know. When we seek feedback from others, they often bring us information we wouldnât otherwise have.
- Take time to consider multiple solutions. Find the option that best fits your problem, and creates the fewest number of collateral problems.
- Look for patterns over time. If you see recurring or re-appearing issues, look for problems with feedback mechanisms in your systemsâââtechnical or personal.
- Donât fall into the fallacy of the single cause. Look for multiple, influencing factors.
- Expect your solution to generate new problems. Try to anticipate what those problems might be.
- Make sure this is your problem, to begin with. If itâs not, youâre probably not the best person/group to solve it.
- Take documentation seriously. Yes, the code documents what the function currently does. No, thatâs not enough. If you donât have some form of documentation, you canât easily see the history or context of the function when you sit down to refactor it the next time.
- Make time to practice. Work with all kinds of problems, in all kinds of situations. The problem you work with doesnât have to be technical.
- Learn about problem-solving. A great resource I can recommend for this is Gause and Weinbergâs Are Your Lights On? I first learned about it from DHH. Many thanks for the referral.
Notes
- Another potential solution to the problem of keeping the tub half full is to freeze the water in it.
The Heart of an Engineer was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.