Я часто слышу о том, как важно уметь решать сложные алгоритмы в программировании. На собеседованиях могут спрашивать про алгоритмы с графами и т.д., которые в работе встречаются довольно редко.

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

Я говорю про часто встречающиеся проекты, которых большинство: личные кабинеты, CRM, системы учета, мобильные приложения, интернет-магазины, сайты, программы автоматизации и т.д. То есть то, что покрывает огромную часть разрабатываемого софта.

Сегментов, где нужны "олимпиадники" и сложные алгоритмы, очень мало. Гораздо больше проектов с обычным софтом.

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

Более того, можно написать свою нейронную сеть, не написав при этом ни одной математической формулы! Неожиданно. Просто используя готовую библиотеку на Python Keras.

На мой взгляд, важнее продукт, который должен получиться, для этого мы и пишем весь код, разве не так? Крайне важна скорость разработки, возможность ее легкой поддержки и расширяемости, а это совсем не про написание алгоритмов.

Подход

Я считаю, что наиболее важным является сам подход к задаче. То есть придумать каким методом, какими инструментами мы будем решать задачу. Где мы можем срезать углы.

Пример

На веб странице нужно сделать сортировку перетаскиванием мышкой. Нашли плагин, подключили. И новые отсортированные данные необходимо как-то передавать на сервер. Для этого нужен код на JavaScript. Начали искать в документации плагина, оказалось, что нет описания, как получить новое состояние сортированных плашек. Мы помучались около часа, написали в поддержку. Это прямой подход, и, по сути, верный, но так как ситуация тупиковая, я решил его изменить. Плагин меняет разметку HTML в форме. Мы можем подложить в каждую плашку скрытое поле input в виде элемента массива. И в форме данные летят именно в том порядке, в котором плагин выстроил в HTML после перетаскивания. Это решает нашу проблему, при этом в данном подходе ноль написанных нами строчек кода на JavaScript.

Итого поменяв подход, нам даже не пришлось вообще писать алгоритм. Понимаете?

Это сильно сэкономило время разработки и скорость работы программы.

Нужно быть аккуратным в выборе подхода и инструмента. Т.к. ошибка может оказаться болезненной: если будет много надстроек, сложно будет потом их просто убрать.

Другими словами, программист, который подберет хороший подход, выиграет у программиста с плохим подходом, но хорошим локальным алгоритмом.

Подход важнее алгоритма, но есть еще что-то важнее подхода.

Вроде очевидная вещь, но не всем почему-то.

Понимание

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

Если у программиста нет четкого понимания задачи, он уже не может правильно написать код. И ему не поможет ни подход, ни алгоритм.

Пример

При постановке задачи говорят, что в Экселе есть данные, нужно написать код на Python, что бы сделать сводные данные. Спрашиваем, как часто это нужно делать? Сказали что очень редко. Открываем Эксель и просто делаем сводную таблицу за 5 минут и отдаем обратно. Специалист, который не вникнул в задачу, просто возьмет и будет ее делать. Потратит кучу драгоценного времени программиста.

Еще пример

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

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

Итоги

Важные слои написания кода от самого важного, к менее важному:

  1. Понимание

  2. Подход

  3. Алгоритм

Часто бывает наоборот. Пишем алгоритм, что-то не получается. Понимаем, что подход не очень, меняем подход. А в итоге вышло, что на выходе от нас ждали вообще другого.

Пойми задачу. Найди подход решения. Пиши алгоритм.

Комментарии (38)


  1. username-ka
    24.11.2023 12:57
    +14

    Вывод из статьи - у Питонщиков свой мир (в принципе, подозревал, имея небольшой опыт работы в питонскими "инструментами"). Подключаем ML одной командой, но спотыкаемся и вынуждены придумывать алгоритм, когда нужно сделать ручную сортировку перетаскиванием. Вы всерьёз собирались писать в суппорт по этому поводу? Даже любопытно, сколько рабочих часов было потрачено на эту задачу.

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


    1. mc_nick Автор
      24.11.2023 12:57

      у Питонщиков свой мир

      ))))))

       сколько рабочих часов было потрачено на эту задачу.

      Не много, это просто как пример на самом деле. Не нужно искать прям смыслы.

      По факту - алгоритмы нужны так же, как нужно в школе изучать математику и русский язык, чтобы быть программистом. 

      Конечно, я согласен, когда вы изучаете язык. Или в начале пути. Алгоритмизация важный навык программиста.


      1. Lainhard
        24.11.2023 12:57

        Вот только язык изучается все время????

        Не изучается он только в одном случае - когда спишь, ну или делаешь что-то другое не связанное с LANGNAME


  1. AlexeichD
    24.11.2023 12:57
    +2

    Дано: миллион одних людей должны деньги миллиону других людей. Множество пересекается. Есть замкнутые цепочки, когда люди должны друг другу в круг. Требуется за секунду (желательно меньше) рассчитать оптимальный с точки зрения суммы набор цепочек для взаимного погашения долгов. Одна из типовых задач в клиринговых центрах. Жду готового решения с "примитивным алгоритмом" или ссылки на библиотеки.


    1. ioncorpse
      24.11.2023 12:57

      Это однонаправленный граф с весами. Берём либу, ищем лупы. Образно.
      Если же задача не абстрактная, то тут думать надо и в алгоритмы.


    1. SwetlanaF
      24.11.2023 12:57

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

      Не могли бы вы назвать алгоритм, которым можно это сделать за секунду? Очень любопытно))


      1. AlexeichD
        24.11.2023 12:57

        ну если совсем вкратце, то это старый добрый симлекс метод)) где матрица уравнений это сумма долга входящего равна сумме долга исходящего для каждого субъекта. Таким образом, можно отойти от истории с обходами графов, узлов, чего угодно. И решить через систему уравнений. Будет работать доли секунды на современных мощностях


  1. AlexeyPolunin
    24.11.2023 12:57
    +5

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


  1. GospodinKolhoznik
    24.11.2023 12:57
    +5

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

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


  1. pyrk2142
    24.11.2023 12:57
    +5

    Имхо, есть две крупных группы тех, кто не любит алгоритмы: те, кто понимает, как устроены алгоритмы, но не знает/забыл/не изучал детали, и те, кто не понимает, и поэтому не знает.

    К людям из первой группы особых вопросов нет: если надо, они прочитают описание, поймут принцип работы и напишут сами достаточно хорошо. Например, человек решил не тратить время на то, что ему не интересно, его право.

    А вот вторая группа вызывает очень много вопросов: почему человек не может понять принцип работы не очень сложных алгоритмов? С чем это связано? А какие ещё вещи из ИТ он не может понять? Недавно столкнулся с великолепной ситуацией: группа разработчиков не могла понять примерно два дня, что именно делает их код (который они частично написали сами, частично скопировали из разных источников). Верхнеуровнево все понятно, а вот что именно происходит в коде люди не могли понять. И их руководитель краснел от стыда и говорил, что ребята реально не понимают, что делает их код, хотя они же его и собрали.


    1. mc_nick Автор
      24.11.2023 12:57
      +3

      Конечно же программист, обязан понимать алгоритмы, как минимум простые точно. Написать их в жизни какую-то часть.

      Я просто хотел посмотреть немного под другим углом на разработку и как это бывает часто в жизни.

      Пример пахнет оверинжинирингом, отдельная боль. Когда накрутят код так, что потом и сами не могут разобрать. Многие задачи можно написать проще, меняя подход.

      Другое если тебе свалился чужой код, в нем хочешь не хочешь, а придется копаться.


      1. pyrk2142
        24.11.2023 12:57

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


    1. flancer
      24.11.2023 12:57

      ребята реально не понимают, что делает их код, хотя они же его и собрали.

      В большинстве случаев программы, которые мы пишем, берут какие-то данные, компонуют их с другими данными и отправляют куда-то там, после чего анализируют ответ с результатом отправки. Программы - это огромная паутина "проводов" (маршрутов) по которым бегают данные. В узлах этой паутины стоят переключатели "if-then-else". Вот и все алгоритмы. Перефразируя известную поговорку электриков, можно сказать, что в программировании есть всего два вида сбоев: "нужные данные не попадают туда, куда нужно" и "ненужные данные попадают туда, куда не нужно". А задача программиста для начала растянуть эту "паутину", а затем перестраивать её по мере надобности. Любой алгоритм можно запихнуть в библиотечную компоненту и использовать эту компоненту в узлах "сети" (программе), ну а топологию маршрутов движения данных нужно уметь вытаскивать из кода и втискивать в код. Это не сложно, это объёмно.


  1. Batalmv
    24.11.2023 12:57
    +2

    Мне кажется, стоит банально вспомнить, а что такое "алгоритм"! Это мне кажется логичным, перед там как писать нужны ли они, или когда они нужны. И окажется, что алгоритм - это просто последовательность шагов для решения задачи. И способ мышления, который опирается на представление процессов реального мира (или еще не разработанного приложения) на базовые блоки и способ их выстраивания в виде алгоритма для решения задачи.

    И попытка проверить "знание" алгоритмов нужна скорее не для проверки знания алгоритма решения конкретной задачи, а вообще - с целью проверки способности кандидата так мыслить. Понятно, есть и такие, которые могут спросить "знаешь сортировку пузырьком? Нет? - до свидания", но это какое-то маргинальное меншинство и предлагаю их в обсуждении этого вопроса игнорировать

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

    ----------------------

    1. Понимание

    2. Подход

    3. Алгоритм

    И в этом месте хочется спросить? А как вы поняли, если не прибегали к мышлению, основанном у на алгоритмах? Понятно, мыслить можно по разному. Но вот интересно, а как тогда? И стоит ли кандидата, который сначала задачу понимает "как-то", а потом переводит в алгоритм - воспринимать, как адекватного програмиста?

    И вот это уже реально вопрос :)


    1. mc_nick Автор
      24.11.2023 12:57
      +1

      "Если утро, то выпью кофе, если вечер и пятница, то бархатное, если ни чего не подошло, вода."

      Боюсь без алгоритмов сложно жить )


      1. Batalmv
        24.11.2023 12:57

        Ну давайте не сводить к двух крайностям, которые в реальной жизни никогда не встречаются. Понятно, последовательности действий, логически связанные между собой встречаются повсеместно. Ну, любой кулинарный рецепт, к примеру. И также очевидно, что на некотором базовом уровне такого рода "алгоритмическим" мышлением владеют все.

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

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

        К примеру, простое действие "зажечь огонь на плите спичкой". Чего там сложного? На бытовом уровне почти все это делали кучу раз (ну кроме тех, у кого электро). А теперь давайте напишем алгоритм действия робота, который делает тоже самое. И я вот думаю, что условная домохозяка такую задачу зафейлит на раз, а к успешному алгоритму придет на 100й, а может и тысячной итерации.

        И в этом разница, так как дорого платить плохому программисту за много итераций


  1. MrSung
    24.11.2023 12:57
    +2

    Успокойтесь, скоро придёт ии и ничего не будет нужно.


    1. mc_nick Автор
      24.11.2023 12:57
      +4

      Я и есть ИИ


    1. GospodinKolhoznik
      24.11.2023 12:57
      +3

      Ну что вы так пессиместично, ничего не нужно будет. Нужно будет, просто на собеседованиях будут другие вопросы задавать: Сколько кубатуры леса за сутки выдаёте? Или какие каналы вам доводилось копать?


  1. KirillBelovTest
    24.11.2023 12:57
    +1

    Я вообще думаю вы слишком мягко прошлись по этим алгоритмам. На мой взгляд в принципе все программисты не важны! Зачем они вообще? Чем занимаются? Только плодят баги и доставляют нам трудности! Без них жизнь была бы проще и собеседования легче проходить. Это я вам как QA говорю, мне можно верить.


  1. ALexKud
    24.11.2023 12:57
    +1

    Согласен, в 99% случаев достаточно этих трех составляющих. Понимание задачи наиболее упускаемый этап. Имею ввиду полное понимание, согласованное с пониманием заказчика. Часто бывает что понимание слабое, типа в процессе разберёмся, я уже делал подобное и т п. Здесь бы и моделирование интерфейса подключать. Отсюда вытекает правильная декомпозиция задач . Ну а алгоритмы они внутри задач сами выстраиваются.


  1. skovoroad
    24.11.2023 12:57

    "Программисту не надо знать алгоритмы, можно открыть Эксель и посчитать"

    Эмм, а Эксель кто пишет, не программисты?

    Можно ещё написать статью: инженерам автомобильной промышленности не надо изобретать автомобили: можно вызвать такси и поехать.


  1. titan_pc
    24.11.2023 12:57
    +1

    В современном мире, где есть ChatGPT, уже не важно знать наизусть все сложные алгоритмы. Достаточно иметь представление зачем тот или иной алгоритм существует и какие им можно решать задачи. Просто пишите чату "Покажи мне Алгоритм А на языке Б" и всё. Пару раз для успокоения души пройдитесь по коду отладчиком, напишите тестовое покрытие и готово.

    Но есть вещи, которые так не решаются. Когда вы например знаете кучу алгоритмов поверхностно но не понимаете, как ими решить кейс. Зреет разработка собственного алгоритма. Но это уже совсем другая история. Не так давно накидавшись кофем, я рекурсивно растянул json дерево в хронологическую линейную последовательность. Олимпиадник я - нет. Знаю ли я алгоритмы супер хорошо - нет. Но оно работает, оно живое и решает наши кейсы, rps всех устраивает.

    Как наиболее ценное в кандидатах, мы например, как средняя по размеру компания ценим именно способность творить новое. К пониманию старого относимся поверхностно.

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


    1. JekaMas
      24.11.2023 12:57

      Дам лишь одину цитату по своему общению с chatGPT, которую он мне выдал:
      "This is because the identity element for multiplication, 1, is not an odd integer."

      Пока верить в gpt рано. Только рутинные и тупые операции, которые затем проверяем подкованный человек.


  1. mondzucker
    24.11.2023 12:57

    Есть кейс.

    Команде нужно написать обвязку к логгеру/рэйтлимитер/миддлварь. Из 10 человек в команде у 7 подход к разработке "алгоритмы не нужны, надо знать фрэймворк". Нужное решение пишется и работает небольшое количество лет. Со временем нагрузка на сервисы увеличивается и следующее поколение разработчиков, занимаясь оптимизацией, попутно выясняет, что около 90% работы приходится на участки кода, написанные вот такими ребятами. В неожиданных местах находится кубическая сложность вместо линейной.

    Сейчас кто-нибудь бегло прочитает статью, а потом придёт на собеседование, где ему предложат простую алгоритмическую задачу и спросит: "задачи? Зачем?".

    Я согласен с некоторыми моментами. Олимпиадники часто оторваны от реальности. Но нужен какой-то баланс. Разработчик должен уметь не только "numpy go brrr"


    1. 1755
      24.11.2023 12:57

      Если предыдущее решение, судя по всему, успешно работало несколько лет, то значит оно подходящее. Скорее всего его было легко создать и не заняло много времени и те разработчики освободилась для новых задач.

      А сейчас, через несколько лет, нагрузка выросла (и скорее всего и бизнес) и узкие места стали проблемными. Но это нормально, что только сейчас их переписывают более оптимальным способом.


      1. randomsimplenumber
        24.11.2023 12:57
        +1

        Ребята сделали канализацию, а она зимой замерзла, надо переделывать. Это нормально, она ведь полгода успешно решала задачи бизнеса. И те разработчики освободилась для новых задач.


        1. polearnik
          24.11.2023 12:57
          +1

          если вам нужна канализация для частного дома на семью из 4 человек то глупо и расточительно ставить по проекту для микрорайона. Комментатор выше пытается донести до вас что преждевременная оптимизация зло и если в течении нескольких лет этот участок кода не доставлял проблем то значит задлача была решена правильно. как только ситуация изменилась то сразу этот код пошли переписывать


          1. 1755
            24.11.2023 12:57

            Спасибо, именно это я и имел в виду, что преждевременная оптимизация - корень всех зол.

            Одно дело, если бы решение нужно было бы переписывать сразу или же через пару месяцев после них, тогда да, как в примере комментария о трубах - решение не рабочее и не годится.

            Но вот если оно работало несколько лет и справлялось со своей задачей - то все нормально. Скорее всего справлялось бы и дальше, если бы не сменились требования.


  1. svz
    24.11.2023 12:57

    Не все задачи сводятся к перетаскиванию элементов ui мышкой. Многие задачи, имея только базовое понимание требуемого результата, эффективно решить невозможно.

    Реальный пример: сокращение времени обработки данных с 40 минут до 30 секунд на тех же мощностях исключительно за счёт правильной алгоритмизации.

    Если вы считаете, что алгоритмы не нужны, вы решаете слишком простые задачи.


    1. MyraJKee
      24.11.2023 12:57

      Зависит от того почему так медленно работает. Например для того чтобы понять что выборка/запись из репозитория в цикле - плохое решение, не нужны знания сложных алгоритмов.

      Сколько в последнее время делал задач по рефакторингу, обычно всё упирается в простые вещи.


    1. mc_nick Автор
      24.11.2023 12:57

      Нужно было написать менее провокационный заголовок. Я хотел другую важную мысль выразить. Но всех тригернуло на алгоритмах.


      1. lordgreem
        24.11.2023 12:57

        Кажется тут больше подошло бы "Почему знание реализаций алгоритмов наизусть не важно", это в большей степени вызывает проблемы, по крайней мере у меня. Мозг устроен так, что даже если я 10 раз прочитаю и выучу какой-то специфичный алгоритм, я его забуду, потому что не пишу его каждый день, у меня есть ссылка в голове, я знаю что такой алгоритм есть и смогу быстро освежить память в гугле, но постоянно держать его в голове у меня не получается и так со многими вещами.


  1. AnonimYYYs
    24.11.2023 12:57

    Как раз таки, разница между умением решать алгоритмы и решением алгоритмов. Понимание и подход это как раз таки части уменря решать оные, а просто решать можно и по шаблону вообще не вдупляя что происходит. Поэтому именно умение решать и важно, а не решение само по себе


  1. nameisBegemot
    24.11.2023 12:57

    Чтобы библиотека или фремворк работал, а программист при этом не знал алгоритмов, нужен программист, который создаст эту библиотеку или фремворк.

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

    На практике такие задачи могут решаться готовыми решениями. И все будет работать, пока устраивает это самое готовое решение. А если не устраивает, если нужно создавать свое решение?


    1. mc_nick Автор
      24.11.2023 12:57

      Да, есть задачи в которых придется попотеть над алгоритмами. Думаю приведенные примеры это отражают: свои библиотеки, фреймворки, игры, своя ОС, высоконагруженные системы и т.д.

      Но так же хочу заметить что очень много задач где особо сложных алгоритмов нет, например: веб разработка, веб приложения.


  1. xirustam
    24.11.2023 12:57

    Понимание алгоритмов можно воспринимать как побочный эффект высокого уровня способности логического мышления человека. Но такая способность требует большого количества энергии, затрачиваемого мозгом. Если же принять во внимание принцип Парето (80% результата достигается за 20% усилий), то не всегда высокий уровень логического мышления выдаёт быстрый результат. С другой стороны, парадоксально, что потребители могут чутко различать 80% и 100% качества, например, автомобили ВАЗ и Мерседес.


    1. mc_nick Автор
      24.11.2023 12:57

      "высокого уровня способности логического мышления человека"

      Моя мысль в другом, то что эта способность может быть бесполезна если человек не понимает бизнес задачу. Он может жестко оверинженирить, писать кучу кода ненужного, и потом кроме него ни кто это не разберет, я с таким встречался. Такие заумные принесут больше вреда чем пользы. Понятно что не все такие, хотелось бы что-то без крайностей, что-то среднее...

      На мой взгляд отличное знание сложных алгоритмов в разработке не достаточно, это не делает тебя автоматически хорошим программистом. Наверное это я хотел сказать.