Алгоритмы не важны

83a50bbfea97b9cad5af2d95ae6241ff

Прошу простить заранее за несколько кликбейтный заголовок)
Не так давно писал в соцсетях хейт-пост по поводу «алгоритмических секций» при приёме на работу в Яндекс.
Да и многие другие софтверные компании это практикуют и считают навыки написания алгоритмов — чуть ли не самым важным навыком для программистов.
И ставят данной компетенции очень высокий приоритет при приёме на работу.

Попробую сегодня развить эту мысль и объяснить почему ставить навыки написания алгоритмов на первый план — не правильно, этот критерий не релевантен и не отражает реальной ценности / уровня / потенциальной пользы от данного программиста.

Для этого проведу параллель между программистами и другими видами инженеров.
Для простоты и наглядности — пусть это будут инженеры-водопроводчики.
Буду использовать простой язык без заумных терминов и объяснять «на пальцах», чтобы было понятно.

Так вот, глобально всех инженеров (а также вообще всех высококвалифицированных технических специалистов) можно разделить на две больших категории:

  1. Те, кто создают технологии или технологически-сложные узлы / агрегаты. Например, инженеры, создающие новые двигатели внутреннего сгорания, реактивные двигатели, ракетные двигатели. В нашем примере с водоснабжением пусть это будут инженеры, создающие новые насосы для воды. Назовём их — технологические инженеры.

  2. Те, кто с помощью уже имеющихся технологий или узлов / агрегатов создают конкретное решение или продукт для конечного потребителя или продукт на широкий круг потребителей. В нашем примере про водоснабжение — это инженеры, которые создадут (и реализуют) проект по водоснабжению / отоплению конкретного загородного дома. Назовём их — инженеры, создающие решения.

Так вот, число первых, то есть «технологических» инженеров — сильно меньше, чем вторых. Их квалификация на порядок выше, чем вторых, и необходимость в них на несколько порядков меньше, чем вторых. По понятным причинам — создавать технически-сложные элементы «конструктора» сложнее, чем строить потом из конструктора конкретные решения. Да основных моделей водяных насосов, которые нужны в частных домах — может быть сотни, а самих домов, в которых надо обустраивать водоснабжение — сотни миллионов.

Так вот, квалификация первых, «технологических» инженеров должна быть сильно выше.
Например, конструкторы авиационных двигателей должны прекрасно разбираться в газодинамике и «сопромате», уметь рассчитывать прочность конструкции с помощью «метода конечных элементов», рассчитывать нюансы охлаждения, сгорания топлива и т.п. Они должны быть прекрасно подкованы в физике и решать порой новаторские задачи — то, что до них вообще никто никогда не делал.

Инженеры, проектирующие насосы для воды должны как минимум хорошо разбираться в гидродинамике, чтобы эффективность / КПД их насоса была выше конкурентов, а также прекрасно разбираться в тех же материалах и конструктивных решениях, чтобы насос был более надёжный / живучий, менее шумный и т.п.

При этом, инженер, который проектирует (и возможно сам реализует) водоснабжение конкретного дома — ему не нужно разбираться ни в гидродинамике, ни в сопромате.

За него уже подумали заранее другие квалифицированные инженеры и предоставили подробные спецификации того, какие узлы и агрегаты (трубы, краны, задвижки, автоматику, насосы и т.п.) можно и нужно использовать в тех или иных ситуациях.

Ему нужно исходя из конкретной ситуации и запросов клиента понять: сколько нужно труб и каких, чтобы всё развести куда нужно: чтобы хватило давления / объёма воды, при этом чтобы иметь некий запас надёжности / прочности / толщины труб, но при этом не переплачивать за заведомо избыточные характеристики, сколько нужно кранов и каких, где какая нужна автоматика, какие требования нужно соблюсти по каким-то нормам / ГОСТам / стандартам и т.п.

Наш «инженер-реализатор» определённо должен обладать немалой квалификацией, чтобы учесть все эти вводные и предложить оптимальное / сбалансированное решение, которое решает задачу, при этом надёжно, при этом отвечает нормам безопасности, и чтобы при этом не переплачивать за ненужное.

Он инженер-реализатор, должен быть отнюдь не дебил, чтобы грамотно справиться с этой задачей и, по хорошему, ему нужно учиться / набираться опыта несколько лет, чтобы брать сложные заказы.
Но вот, какие знания для него точно избыточны и не нужны в работе — это, к примеру, та же гидродинамика. Ему попросту негде применить эти знания.
Если бы он проектировал новую модель насоса (был бы «технологическим» инженером) — ему было бы это однозначно нужно.

Даже если ты инженер-проектировщик какого-нибудь специализированного электрического грузового автомобиля для конкретного заказчика в некоем прекрасном будущем, когда на рынке готовых компонентов уже представлена широкая номенклатура узлов — есть уже готовые всевозможные электромоторы и аккумуляторы на любой «вкус и цвет» — тебе не нужно разбираться в нюансах органической или неорганической химии — ты просто берёшь уже готовые аккумуляторные ячейки, которые тебе подходят, и просто их используешь в своём электромобиле. В каком-то смысле это проектирование превращается в рутину — тебе просто нужно знать основы / принципы проектирования конкретных видов продуктов, грамотно подобрать компоненты, которые подойдут по характеристикам, соединить всё вместе, покрасить в нужный цвет, и вуаля — автомобиль поехал.

Теперь вернёмся к программированию…
Тут действует то же самое разделение труда, что и во всех прочих инженерных областях.
**Есть «технологи», создающие новые движки / технологии / технически-сложные библиотеки / инструменты**.
Например, те, кто создают новые СУБД (которые быстрее / эффективнее конкурентов), новые поисковые движки, движки для работы с нейросетями, языки программирования и т.п.
Им, определённо, нужны хорошие знания алгоритмов, чтобы создавать высоко-конкурентные «узлы» и «детали».
Если твоя СУБД недостаточно или твой движок нейросетей недостаточно быстрые или потребляют слишком много памяти в сравнении с конкурентами — другие инженеры / программисты просто не будут их использовать. Конкуренция тут достаточно жёсткая и требования очень высокие и жёсткие.

Однако, примерно 98% программистов — не создают технологии или движки.
Они создают продукты или конкретные решения од конкретных заказчиков.
Их задача — взять адекватный набор из уже готовых технологий / движков / библиотек и сделать конкретное решение.
Это может быть весьма непростая задача и всё вышесказанное не означает, что эту задачу могут успешно решать программисты с отсутствующим мозгом (хотя бывает и такое).
Для успешной реализации продуктов / решений нужна немалая квалификация и немалый опыт. Однако, ряд вещей, которые просто обязаны хорошо знать «программисты-технологи», для них избыточны. В первую очередь это пресловутые алгоритмы.

Если какой-нибудь условный интернет-магазин, написанный под конкретного заказчика, будет в полтора раза медленнее (или потреблять в полтора раза больше памяти) от теоретически/технологически-достижимого предела, скажем, отвечать на запросы за 0.15 секунд вместо 0.1 секунды — этого никто не заметит. В конце концов, можно докупить больше серверов или поставить немного больше памяти — и это будет гораздо более экономически оправданны решением, нежели тратить годы на разработку «оптимальнейшего» решения. Я не говорю, что, скажем, перечисленные параметры: скорость и потребление памяти не важны — важны. Важны.
Но чаще всего для обеспечения этих характеристик куда важнее правильно подобрать стек технологий и «правильно» спроектировать само решение из конструктора кубиков-технологий, нежели пресловутое умение «оптимизировать пузырьковую сортировку» и производить те или иные операции над списками «за один проход».

Точно также как инженеру-водопроводчику не обязательно знать гидродинамику — ему просто негде применить эти знания, поскольку жидкость в трубах течёт с гораздо меньшей скоростью, нежели та, когда все эти гидродинамические эффекты начинают иметь значение.
К счастью, инженеру-водопроводчику не нужно заморачиваться, к примеру, с эффективными закруглениями труб, которые бы меньше препятствовали потоку воды, и он может сосредоточиться на других аспектах, в том числе удобстве обслуживания системы водоснабжения и эстетике его решения.

За 20 лет работы программистом я очень ограниченное / считанное число раз встречался с ситуациями, когда приходилось бы решать условно «алгоритмические» задачи, при том, что проектировал / участвовал в проектировании распределёных систем большой сложности, работающих на десятках серверов.
В реальности же нужны совершенно другие компетенции.
Перечислять их тут нет смысла. В числе прочего, это умение писать понятный поддерживаемый код.

Во этой ситуации ставить главным / основным критерием при приёме на работу для обычных (в том смысле, что принадлежащим к тем самым 98% разработчиков, которые делают РЕШЕНИЯ, а не ТЕХНОЛОГИИ) программистов — это, считаю, большая ошибка.

В результате получим нерелевантный отбор — отбираем по тем компетенциям, которые скорее всего не пригодятся и игнорируем компетенции, которые скорее всего будут нужны.

PS: Равно как я очень скептически отношусь ко всякому «спортивному программированию», где на скорость люди решают какие-то полуматематические задачи — поскольку это совсем не те навыки, которые нужны программистам в реальной жизни и в реальной работе. Это какая-то «параллельная вселенная».

Это как «танец с саблями» имеет отдалённое отношение к реальному бою на саблях.
Люди, которые хотят устроится в компании с подобными требованиями, специально прокачивают свои «алгоритмические» скилы на всяких leetcode.com.
А потом, после похождения собеседований, успешно их забывают.

Почему эти «алгоритмические задачки» вообще так популярны на собеседованиях и почему руководство верит, что так они смогут отобрать хороших программистов — вопрос открытый.
Как будто бы работа программиста только и заключается в том, что надо каждый день перепридумывать алгоритм быстрой сортировки или алгоритм сжатия без потерь.
(К тому же, вообще этим должны заниматься скорее математики, а не инженеры…)

© Habrahabr.ru