How to solve any programming problem

Original author: Justin Fuller
  • Transfer
Hello to all!

Today, we offer you a translation in its own irreplaceable article that will help you to approach even the most insidious and nontrivial TK, which you do not understand at first glance. The main thing - do not give up and sensibly formulate questions. Mr. Justin Fuller from Bank of America kindly describes how this is done correctly.

Enjoy reading!

So this day has come. Maybe this is your first working day, or maybe you have been working at this place for ten years now - it doesn't matter. It happens to everyone: you finally got a task that you just don’t understand.

What to do? Just get down and hope that everything will work by itself? Or confess to the boss that you can’t do this because you don’t understand?

I think you guessed that the correct answer is neither one nor the other!

I noticed that in programming, as in any other profession, it is almost impossible to live a working week (and sometimes a working day) without facing an absolutely incomprehensible task.

But do not worry! There is great news. Not only can you solve this problem - in addition, it can also benefit you.

After all, at the same time you will have to expand your knowledge and skills in comparison with everything that you did and knew before.

Next, I will tell you how to bridge the gap between the demands you have put on you and the knowledge you need to complete the task.

About the "requirements"

As you have already noticed, I use the word "requirements". Depending on where you work, this word may have one or another connotation.

In my experience, in large companies, they love requirements, and in small ones, they sometimes "do not make demands." I think that's what we need to talk about here.

The fact is that, ultimately, all programmers do the same thing: they solve problems.
You can get an exhaustive hundred page TK on how to solve this problem (I once visited an hour-long meeting about the text on a button). Or maybe this is the case: the CEO goes past your desk and as if inadvertently asks - “can you cope with this task by Friday?”
In both cases, the task has been set before you, and you must be sure that you fully understand it; only in this way can you approach it properly!

About stages

Not all the steps listed below will be required to solve any problem. Only the most complex tasks may require careful execution of all the steps that will be discussed in this article.

It is possible that many questions cannot be answered, based only on voiced demands or because of the insufficiency of your personal experience.

You may need to consult other developers, a team leader, a product owner, a business analyst, or even a grandmother! And maybe with each of them, before the task can be solved!

However, this is normal. This means that you will collect the scattered knowledge and bring it together - and so you will be able to achieve the best possible result!

Finally, a final warning: do not overdo it with formalization! The most important thing here is to quickly understand the task. No artificial barriers and red ribbons needed! We need only a systematic plan for solving a problem that you currently do not understand.

Step one: analyze the problem

At this stage we are trying to understand what you have been asked to do. While we are not trying to decide how we will do it!

It is important to catch this difference. It can be dangerous to go straight to the realization, without thinking of all the consequences or, even worse, without fully understanding what you were asked to do.

We classify a task.

Classifying a task means determining what work will have to be done to solve it. Here are some examples of task types:

  • Bug fix
  • New feature
  • New application
  • Research assignment
  • Performance optimization

Remember that this list of options is not exhausted.

In this case, we need to decide what kind of work you are expected to do. This is important because it will directly affect what kind of work you will do.

This stage is especially important in case of fuzzy requirements, for example: "We need a way to somehow clear our client caches after updating the site."

Here are some possible interpretations of this requirement.

  1. You must quickly implement a certain cache clearing mechanism, such that customers always receive the most current updates.
  2. It is necessary to examine all the ways of storing these client caches and determine the best (e) option (s) for getting rid of these caches after each site update.
  3. Client caches should have already been cleared, and you are required to find and fix a bug that prevents it.

At this stage, if you are not absolutely sure what treatment was meant - you need to ask for clarification, and only then continue to work.

Formulate the essence of the problem in the form of one or two simple statements.

Summarize a complex requirement, as if answering the question “what are you working on today?” Maybe it will not be so easy, but you should try and reduce the essence of the task to one or two sentences.

To summarize a task in this way fails, it may mean that it should be divided into several subtasks. In principle, this step turns into a litmus test, signaling whether you were able to organize your tasks in the form of rather small fragments.

Here is a good example of such a summary: “When updating the site, we attach a unique number to the files, so the browser understands that it should use the newest version of the code.”
This task passed the “litmus test” for simplicity and, perhaps, does not break it into smaller fragments. required.

But a bad example: “When updating the site, we attach a unique number to the files, so the browser understands that it must use the latest version of the code. We must also send a message to our CDN network, thus notifying it of the need to update the files. You will also need to provide for applications for IOS and Android to send an update to the application market. More ... ”

In this case, the test is definitely failed. A lot of work is required, and, perhaps, each task needs to be defined and tracked separately.

Highlight the most important details.

Now you must (in a free form, the most convenient for you) make a list of the main things that need to be done.

This, again, must be very simple pressing of each of the main stages.

This is not about step-by-step or detailed troubleshooting guides.

Remember that while you continue the analysis of the task set before you. At this stage, I recommend to make written notes. I personally use Notes for this.

Our caching task is very simple and, quite possibly, it is not necessary to describe it in this way. Let us in this case consider a more complex example.

Our next task is to implement a new feature: “Address advertising of our internal product should be displayed to each user. This ad should be adapted to the needs of the user, based on the data we collected. ”

To isolate the main elements of this task, we must clearly understand what needs to be done to implement each element.

  • The advertisements we have will need to be distributed in such a way that they correlate with some specific user parameter.
  • For our marketing department, you need to provide a way to relate new advertisements to one or more pieces of user data (and marketers do not have to program anything!)
  • The system will need to aggregate such user parameters that are relevant in the context of our advertising.
  • Finally, you need to create some kind of system that will receive a user ID and display advertising.

The beauty of such lists is that they can be quickly coordinated with the team or boss! So, in this example, you could show this list to your team leader, and he decided that another, very important item was missing from the list:

  • Users should be able to tell us that they no longer want to see certain ads.

After all, in the end, the least we want to annoy our favorite users! Having spent time and having thought over a task of only a couple of extra minutes, we will avoid hours and days of trouble later. So, it is important how to formulate and plan an important task, and only then proceed to the code.

Before moving on, I would like to respond to your possible criticism.

Perhaps you think: “In a normally set-up business, this kind of work should be done even before the demands are laid on the table to the developer” - and I strongly agree with you!

However, sadly, our world is not perfect. Sometimes the requirements that fall to the developer are not laid out on the shelves. Therefore, we must make every effort to properly assess the requirements before starting development.

Identify the problem (s) you are trying to solve.

Answer the question: “why would anyone have to use it?” Or “what is the real or perceived problem that I am trying to fix in this case?”

I hope the answer is obvious. In our first example, here, the answer is: "users will always see the latest updates." In the second case, with advertisements, “users will always see relevant notifications, and not those that do not interest them.”

The proc of both of these answers should be obvious! By understanding more deeply the task and its goals, you will be able to make smarter decisions and make an implementation that will suit your business goals. If you can identify bad solutions and meaningless tasks, then you can not waste your time and effort searching, which by definition will not help solve the problem.

Stage Two: Interpret and Assess Requirements

At this stage, you should already be aware of what you are to do and why.
Next, you need to understand the details of what you are going to do, how you are going to do it and why you will do it that way.
Clarify important terms related to your task.

This step is probably more important for a novice developer as part of a team, or if you work for a large company. In both such situations, it is highly likely that you will come across unfamiliar terms in the requirements.

These may be concepts from the business field, such as the names of products, customers, or processes. There may be terms related to development — for example, the names of tools, applications, models, services, or libraries.

You need to make sure that all important terms are clearly understood, so that you can be sure that you are accomplishing the task correctly.

Perhaps you already understand that you need to invent a way to access aggregated user information, but do you understand what it means to add it to dao?
You probably understand that you should format advertising data, but can you imagine what “MADF” is (markup of advertising news feeds)?

I do not understand either one or the other.

That is why you need to isolate and define all the important terms. To get lost in definitions is a sure way to solve the problem incorrectly.

Decide how the task should be done.

At this stage, you should already figure out how the task will be carried out. The details of this process can vary greatly depending on where you work and what specific task you are assigned.

In some teams, no one will explain to you exactly how to implement the requirements, they will simply say what functionality should come out.

In others, your every step will be described in detail.

Most likely, you happen to be in some intermediate situation.

If the team did not provide you with instructions, then at this stage you will hardly be able to do anything. If you received instructions - then start to get acquainted with the stages that you have to go.

This step seems completely natural, but it is important to pay attention to exactly in what order we proceed to it.

Naturally, we would like to plunge into all the details of the task at once and study them until the goal is clear to us.

However, since the above you have already spent time to understand the task, now you need to be more clearly aware of the whole task, assessing the steps that need to be taken on the way to achieve it.

Determine whether assigned tasks

At this stage, the stages of analysis and interpretation merge together. At the analysis stage, you focus on a holistic picture and large-scale goals - what we do and why.

At the interpretation stage, focus on the details - how we do it.

The second stage is called “interpretation and evaluation”, because now you can relate “how” and “what and why”. You interpret the details based on the overall picture. You evaluate the details and determine whether the original problem was solved.

Ask yourself: will the steps that I have been instructed to do lead to a result that was designated as the ultimate goal of the task? Does the planned result really solve the original problem?

If you are sure that all problems are solved, and the details are meaningful, then you can get to work! Otherwise, it is necessary to proceed to the third stage in order to resolve all conflicts.

Stage three: we approach the problem critically

At this stage you must be able to confidently assert that you understand both the problem and the solution. It only remains to be sure that this is the right decision.

To create the highest quality product, we all must be able to take responsibility and speak out if some things are obviously wrong.

On the other hand, we are not going to make inappropriate claims. One cannot say that something is wrong, because “it seems so” or simply “it doesn't like it”. It is necessary to put forward concrete and well-thought-out arguments.

So, we set out the basic rules of competent disagreement

Know when to disagree

  • Disagreement is unacceptable, until I figured out the problem thoroughly.
    To say “this is not true” can only be made with absolute certainty that you understand exactly what you do not agree with /
    If you cannot confidently formulate the problem and the planned solution, then it is impossible to disagree. If you are not convinced that you understand everything correctly - you can not disagree. Just being sure that you understand the problem to the smallest detail, you can afford to disagree.
    If you feel that you do not have all the necessary information, then perhaps it is time to stop and reconsider all the completed stages, before claiming that the requirements are erroneous.
  • One cannot but agree for subjective reasons. Pay attention to genuine potential problems.
    “I do not like how this is done” - a subjective judgment. “This will lead to performance problems, since so many operations are involved” - an objective reason. Examples of other subjective reasons: “And on another project, we did it differently” or “I would have implemented this decision a little differently, but this, of course, is a matter of taste.”
  • You should have in place well-thought-out explanations that support your claims.
    If you cannot explain why something is wrong, can you be sure that you are really right? I advise you to write down the reasons why the decision seems to be wrong for you, and to formulate how it can be corrected.

If you cannot offer such a solution, tell it clearly from the very beginning.

Be careful when expressing disagreement with others. We need to spend a lot of time to listen to everyone and understand everything - and only then can we disagree.

If up to this point you have carefully adhered to all the steps described, then it is very likely that you have understood everything well. However, try very hard not to lock yourself in your calculations - because you might have missed something!

I like to start the discussion with the words: “Not that I disagree with you, I just do not understand yet.” Later, if necessary, we can express strong disagreement, but first of all, sort it out.

Be able to disagree correctly

To ensure that our disagreement is objective, we will take a series of measures that will help us understand whether our arguments are valid.

Objective disagreement allows you to demonstrate at least one of the following facts:

  • The decision is not sufficiently informed.
  • The decision is wrong informed
  • Problem or solution is illogical
  • The solution is incomplete

The lack of awareness is not a cause for offense; it simply means that when creating the solution, you proceeded from incomplete data. Perhaps the compilers of TK did not know about the already existing system, capable of performing the necessary actions.

Being wrong informed means creating a solution based on incorrect information.

This is a case when, in the opinion of the compilers of the TK, the existing system can do something, but in reality this possibility is not provided in it. For example, the SEO team asked you to ensure that Google indexed a page with a user account in your application. Google can not do this. This means that your SEOs misinterpret the functions of the Google search robot.

An illogical task or an illogical solution is simply meaningless. A typical example (from the point of view of the developer) is to implement a feature that will bring down some other feature. Such a requirement can be considered illogical, since it hurts rather than helps.

The solution is incomplete, and sometimes it is done intentionally. In software development, we often try to create an MVP (minimally viable product) to begin with. This means that in the first operation you can deliberately postpone the implementation of the functional, which is not absolutely necessary.

In fact, an incomplete solution can be considered only if it does not solve the task itself, or if the steps listed above are not enough to create a workable product or a full-fledged opportunity.

Also popular now: