Development rules in Yandex. Health

    Many people think that Yandex is a large monolithic corporation with tightly regulated processes, but this is not so. We are constantly looking for new directions, starting new projects and trying new markets. The service for online consultations with the doctor " Yandex . Health " is one of the classic internal startups.

    I came to lead the development of Health at the time when the service was still a page with a brief on the internal wiki. In this post I want to share the approaches to development that have been formed in our more than two years of work on the service.

    Disclaimer:
    A startup has its own characteristics. Our main task is to do the maximum number of experiments per unit of time and issue food features as fast as possible. At the same time, we must keep the quality of the product at such a level that it is not a shame for it. [A place for a flame about a conscience lacking in some] . I note that the high speed of delivery of features implies including the maintenance of a sufficiently high quality code. Otherwise, the product sooner or later chokes in bugs.

    All the points below are somehow suffered, practically everybody has a case from real life.



    Code quality and architecture


    • We minimize the time to bring features to production while maintaining acceptable quality.
    • Any task involves two solutions: fast and correct. For any feature, we think of both options so that we can upgrade the quick solution to the correct one, making the minimum unnecessary work “for emission”. Rolling out a quick solution, for some time we look and understand whether the right one is needed.
    • Critical. Often, the difference in time between “solving the first available method, scoring a crutch” and “solving nicely and accurately” is ten minutes. Therefore, we always think before writing.
    • If there is a choice between minor optimization and readability / architecture, we choose the second. Two milliseconds will not solve anything, but with this code we still have to live and maintain.
    • We think about the future. The near future is more important than long-term prospects. If the decision can be made difficult (read “long”) and flexible, or simple, but nailed, you should nail it and then refactor as necessary. It is better to spend the day on a simple solution now and a month for a possible refactoring in a year than two weeks now (yes, this is what is called technical debt). It is important that such decisions are worth discussing with the team. Alone, you can incorrectly estimate the probability of expanding this feature in the near future.

    New technologies


    New technologies are cool, let's use them. But our product is not a testing ground. If you want to apply a new algorithm or technology, this can be done under the following conditions:

    • the technology carries a tangible profit (optimization, quality of architecture, code, scalability, and all this really should be necessary, and not far-fetched);
      the technology fits normally into the current stack (no need to write some services on Go, if all the code is written in Python);
    • the technology does not degrade the quality of the architecture and the readability of the code (this is subjective, therefore it is discussed with the team);
    • it takes no more time to implement and support a new technology (including a search for new developers) than to work under the current technology. Again, it all depends on the expected profit and is discussed with the team;
    • Any new technology is discussed with the team: if it is cool, then it’s right to use it with everyone, if not very much, then a group discussion allows you to understand it faster;
      no need to independently implement algorithms already implemented in ready-made libraries (except when it is a small piece of a huge framework and it does not make sense for the sake of one solution to drag it all).
    • if you have done something cool and convenient - share your solution with the team (or better, inside Yandex).

    Communication


    • We discuss the decision together. The more complex and critical the functionality, the more important such a discussion. If someone does not like the decision, we persuade each other until agreement is reached. Or the discussion time will not exceed a reasonable time.
    • If you could not agree - the last word for the head. We have a reasonable democracy, not the Polish Diet of the XVII century . At the same time, the manager receives a big minus in karma and must experience moral suffering. And certainly not use this right often.
    • After we have decided - we do as agreed. Even if I categorically disagreed. No “I know better than all these productologists how to do service, so I’ll do what I consider necessary”
    • "Not for sale - not done." Everyone monitors their tasks. If the feature is ready for testing, you need to take care that it rolls out into testing. If it is ready for release, you need to make sure that it gets into the prod as early as possible. The people responsible for the formation of the release, do not always remember about each feature. Do not hesitate to remind about it. [Place for the flame about the distribution of responsibility between roles in the team.] .
    • It is necessary to turn on the head. If the task seems strange, incomprehensible or too long, then it is necessary to speak clearly and loudly to the responsible manager. And do it until a clear understanding of why everything should be like that. It happens that the right questions asked at the right time save development weeks.

    Time management


    • If the task does not fit within a reasonable time, you need to speak loudly about it. You should not sit for several months and cut the task with an estimate of three days. If it is strongly delayed, then something goes wrong. Perhaps there is a misunderstanding in the statement or we underestimated the amount of work. In any case, such tasks need to be re-discussed (and as a result, sometimes postponed or even bury).
    • Emerging problems should be solved independently. But if it is clear that the process is delayed, be sure to talk about them and ask for help from colleagues. Sticking for a few days in a state of “I must do everything myself and not distract my comrades” is very bad.
    • No one looks at what time each of us comes and goes as long as we have time, and our regime does not begin to interfere with the work of the team. But to sit at night just because you do not have time to do something is not necessary. If this turns into a habit, then the problem is deeper - in planning, reassessing one's own capabilities, etc. While the developer is overtime at night (and as a result, everything is in time), the chances that someone will see and solve this problem are greatly reduced.
    • It happens that we need to necessarily launch an important feature by the agreed date (or just as soon as possible). In this case, we go to work in overtime. In this case, the manager receives a big minus in karma and must suffer morally. And certainly do not use this opportunity often. Such overtime is compensated. [Place for overtime and compensation flame] .

    Mortal sins


    This is a separate section. Here I tried to list what I consider wrong and harmful when working in a team. Each item has its own weight. Some talk about very big problems, others are not so critical. So, what should be avoided by all means:

    • Work, not including the head: "I was told to do - I did." Each team member must understand the essence of the features that he makes and its impact on the product.
    • Throw features not rolled out in the product with the words "I did everything." What we do should work in production. While the feature is not in sale, it is not ready.
    • Agree to do it in one way, and then quietly do it your way. Above it was about "I know better than anyone what is best." But once again recall that this is bad, it does not hurt.
    • Tighten important features, burrowing in the discussion of rare and unrealistic, but potentially possible problems. If it is not possible to figure out in a reasonable time how to circumvent a minor and rarely reproducible problem, we simply agree on how to live with it.
    • Do not voice problems in time, trying to solve everything on your own (usually at night). Such heroism leads only to the failure of terms, fatigue and feeling of underestimation: “I accomplish feats here, but I am also criticized for slow work!”
    • It is painful to respond to the criticism of the code and go to clarify the relationship. Even if a colleague says that the coprolit code is so-so (“let's rewrite everything!”), Treat this with understanding and discuss why he thinks so. For you personally, this is no less useful than for the service as a whole.
    • Become personal. When criticizing a code or solution, we criticize only the code or solution, but in no case the one who wrote or offered it. Given the previous paragraph, do not be afraid to criticize. Better a reasonable time to argue with colleagues than to send in an unsuccessful solution.

    Total


    Here you can write more about a million things. But the shorter the post, the easier it is to read it to the end , but I really hope so. And yes, I do not perceive the criticism painfully (with the condition that you do not get personal;). So let's discuss!

    Also popular now: