Меня зовут Кирилл Мокевнин, я CEO и сооснователь онлайн-школы программирования Хекслет. Мы помогаем людям с самым разным бэкграундом стать разработчиками уже 10 лет. За это время я не раз замечал, что зачастую студенты плохо представляют себе профессию. Вещи, не относящиеся напрямую к технической составляющей программирования, но имеющие огромное значение для успеха в будущей специальности, становятся для них сюрпризами еще во время обучения. В этой статье я поделюсь открытиями, которые ожидают студентов и начинающих программистов, решивших посвятить себя разработке. Студенты представляют себе разработку так: существует заказчик, который приходит к программисту и дает техническое задание, где описано все, что нужно сделать, и как нужно сделать. От программиста требуется только написать код. В действительности же, техническое задание даже если и есть, то далеко не полное. И это нормально: никто не может заранее сказать, окажется ли новая возможность удобной, пока пользователи не начнут жаловаться: «Дуров верни стену!». Не существует человека, который точно знает, как нужно делать. Любая заранее продуманная логика разбивается о реальность. Именно поэтому в разработке так популярны гибкие методологии, когда продукт делается не по ТЗ от начала до конца. С их помощью продукт разрабатывается небольшими порциями, которые постоянно отдают пользователям, чтобы убедиться в верности принятых решениях и направлении развития. Программный продукт — живой организм, который постоянно развивается на основе экспериментов и обратной связи. Все продукты, которые вы знаете, разрабатываются непрерывно. Иногда программирование сравнивают со строительством, но это сравнение не очень корректно. В случае со стройкой все планируется заранее, а разработчик всегда находится в состоянии неопределенности — он не знает, куда точно будет развиваться проект. Задачи, которые ставят программистам, обычно описываются с точки зрения поведения обычных пользователей: «Добавить подтверждение входа по смс». В целом — все понятно, но возникает множество вопросов по условиям работы и технической реализации. В каких ситуациях нужно подтверждение? Можно ли его отключить? А если это абонент другой страны? А если человек потерял телефон? А через какой сервис отправить смс? Часть этих вопросов будет раскрыта в техническом задании, но далеко не все. И это делается не специально. Только программист понимает всю сложность, которая скрыта за такими задачами. Это его прямая обязанность — указать на моменты, про которые забыли или которые будут сложны в реализации. В результате задача может значительно измениться в сторону упрощения, так как исходный вариант займет значительное время на разработку, которое стоит дорого. Все это требует переговоров, копания в документации, взаимодействия с людьми из внешних продуктов и других частей системы. Чем опытнее разработчик, тем чаще он этим занимается. А код? Код пишется в конце, когда выясняются все нужные детали. Написание 20 строчек кода может сопровождаться днями обсуждений. Настоящий заказчик разработки — пользователь продукта, именно о его удобстве должен думать в первую очередь программист, приступая к задаче. Задача появляется у разработчика потому, что у клиента есть какая-то проблема, которую нужно решить. Поэтому, в идеальной ситуации, разработчик либо общается с пользователем, либо, с теми, кто общается с пользователями. В любом случае у разработчика должно быть четкое понимание, как клиент взаимодействует с продуктом. Именно поэтому во многих компаниях использование сотрудниками продуктов бренда — обязательное условие при приеме на работу. В других компаниях, разработчики время от времени переходят в отдел поддержки, чтобы знать потребности и боли клиентов. Если программист этого не знает, он может легко заняться строительством воздушных замков там, где нужны простые и понятные решения. Начинающие разработчики боятся совершать ошибки и пытаются сразу все сделать правильно. Однако если вы решили стать программистом, о перфекционизме придется забыть. Хотите с первого раза написать рабочий код? Увы, не выйдет. В процессе выяснится множество деталей, о которых забыли подумать, либо они проявляются в рабочем коде только у части пользователей. В разработке ошибки — неотъемлемая часть жизни приложения. Более того, значительную часть своего времени разработчики тратят именно на исправление чужих и собственных ошибок. Опытные разработчики делают ошибок немногим меньше, чем начинающие, но они быстрее их исправляют. В этом им помогают насмотренность и автоматизированные тесты, которые постоянно проверяют код. Распространенная проблема в разработке — «овер-инжиниринг», когда создаются решения, которые учитывают все возможные сценарии, даже те, которые еще не используются. Или многие любят делать код быстрым, в надежде на большую нагрузку, которая наступает лишь у некоторых проектов. В действительности же начинать следует с самого простого, «деревянного» ответа на проблему пользователя — с решения, которое можно осуществить в короткий срок. При этом неважно, насколько это решение хорошее или плохое. Дальше анализируются преимущества и недостатки выбранного подхода, к решению добавляется что-то, усложняющее его и одновременно делающее лучше. И так шаг за шагом. На выходе мы получаем не одно решение, а несколько, каждое со своими плюсами и минусами. И только после этого стоит принимать решение, что из этого реализовывать. Если же программист видит только один способ реализовать свою задачу, то он ее не понимает. Кажется, самый парадоксальный факт из всех описанных: хороший разработчик  —  не тот, который больше всех кодит. Опытный разработчик может решать задачи, не написав ни строчки кода. Любой код приходится поддерживать, за ним надо следить. В разработке каждое решение тебя связывает: код ограничивает в выборе последующих решений, потому что в программировании все последующие решения зависят от предыдущих. За годы работы продукта накапливается огромное количество архитектурных решений, от которых невозможно отойти ни вправо, ни влево. И чем больше кода пишется, тем шире эта ловушка. Если можно не писать код — его не надо писать. При появлении задачи опытный программист всегда выяснит, на что способна уже существующая система, и не будет ее усложнять, если в этом нет необходимости. Например, иногда решить задачу можно удалив код, а не создавая его. Пример. На сайте школы Хекслет есть рейтинг учеников. Он считался динамически, поэтому через определенное время все начинало тормозить на 20 странице. Мы пришли с проблемой к разработчикам. Что сделает в этом случае неопытный программист? Вероятно, предложит добавить кеширование или периодический расчет рейтинга. Что сделали наши программисты? Предложили обрезать рейтинг до сотого номера, справедливо предположив, что никто не будет листать до 20-й страницы в принципе. Теперь у нас сайте есть рейтинг топ-100. Проблема была решена через продуктовое решение и удаление кода.  Кстати, как бы удивительно это ни звучало, благодаря такому решению у студентов появилось больше стимула к успешной учебе: им интересно попасть в список лучших. Многие начали бороться за попадание в этот рейтинг.