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

На работе, за компом
На работе, за компом

Немного истории...

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

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

Русский язык так устроен, что абсолютно всё, что можно написать или произнести - нужно сразу же приукрасить.

А именно - само слово АЛГОРИТМЫ в названиях книг, в статьях и других текстах.

Смотрите:

select * from (
	select 'Структуры данных' as word
	union 
	select 'Алгоритмы' as word) as word 
order by word desc

Мы сделали заготовку из двух слов на SQL на лету. Получили что-то типа:

|word            |
|----------------|
|Структуры данных|
|Алгоритмы       |

Как вывести "красиво"? По алфавиту и сконкатенировать. Поправим desc на asc и добавим

select STRING_AGG(cast(word as text), ' и ') as name from (
	select word from (
			select 'Структуры данных' as word
			union 
			select 'Алгоритмы' as word) as word 
	order by word asc
) as result

|result                      |
|----------------------------|
|Алгоритмы и Структуры данных|

Это простейшее упражнение на SQL в быту наш мозг выполняет автоматически, по привычке, не надо ничего изобретать - все готовые конструкции лежат у нас в голове в виде быстрого кеша с доступом o(1).

Поэтому названия книг "Классические алгоритмы программирования" и "Алгоритмы и структуры данных" так классно, лаконично и солидно выглядят.

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

Известная книга
Известная книга

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

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

Пример

Я специально написал "в нулевые годы", а не цифрами или синонимично.

Никто не говорит "в нолевые" годы - звучит коряво.

Но ноль, нуль и null по отдельности - вполне неплохо.

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

Кольца Ньютона. Наблюдаются в микроскопе - берешь глаз и смотришь!
Кольца Ньютона. Наблюдаются в микроскопе - берешь глаз и смотришь!

Вернемся к алгоритмам - слово потрясающее, начинается на А, содержит в себе столько загадочности, "неопределенности".

Действительно, alghoritms - это целая отрасль науки или даже общая область в других областях: алгоритмы оптимизации, нейро-сетевые алгоритмы и другие.

Но забывается одна важнейшая деталь.

Алгоритм сам по себе - БЕСПОЛЕЗЕН. В особенности без задачи и без сущностей, к которым он прилагается.

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

Функция из учебника по алгебре

Простая функция f(x)=4 из школы. Да хоть "ты тресни" применять к ней градиентный спуск или метод Ньютона для поиска минимума. Любому понятно, что при любых значениях x достигается и минимум, и максимум y=4.

Нам не нужны сложные алгоритмы оптимизации, чтобы найти экстремум. Здесь достаточно метода "пристального взора". А еще лучше сформулировать так: Соберите требования и изучите постановку задачи - тогда найдется простейшее решение.

Константная функция
Константная функция

В чем ценность примера? В простоте - не требуется умных слов для решения задачи.

Я клоню к тому, что за высокотехнологичными красивыми словами всегда кроется достаточно простая и элементарная логика решения достаточно легких тасок. И никакого пафоса.

Но наше человеческое сознание устроено так - не знаешь деталей (это ж надо напрягаться, разбираться) - не лезь!

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

Открываешь книгу по квантовой механике: "Ууу, нифига себе формулы, текст с непонятными словами, ну нафиг, это не для меня, пусть ботаны учат".

Особенно пользуются популярностью у людей "НА ОКОЛО" - СМИ, журналистов, блогеров, популяризаторов науки, болтунов.

Умеющие красиво говорить и преподносить информацию о той или иной сложности "Алгоритмов", преуспели здесь в разы.

Модный программист
Модный программист

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

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

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

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

Бывают случаи, когда казалось бы крутой алгоритм просто нифига не работает. А бывает, что идеально подходит к структуре.

Лирическое отступление закончили, вернемся к коду.

Реальная задача из жизни

Орешки.

Вводные:

  • Есть большой пакет 5кг арахиса

  • Лежит на кухне в шкафу

  • Компьютер с сериалом в другой комнате

Задание: Реализовать просмотр сериала с параллельным употреблением вкусностей

Есть 3 решения:

  • Взять весь пакет с собой в комнату. Сердито, неудобно, но сгодится

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

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

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

Пример, когда помогает неоптимальный алгоритм

Однажды много лет меня пригласили на дачу на шашлыки. Всё как обычно.

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

Входные данные:

- Гора тарелок в раковине на даче возле крана со шлангом

- Ледяная вода

- Помытую посуду надо относить в дом и ставить в шкаф

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

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

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

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

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

Реализация.

Сделал для разнообразия на Kotlin со Spring Boot

Кухня - это наша База Данных Postgres

interface NutsRepository : JpaRepository<Account, Long>, JpaSpecificationExecutor<Account> {

  //Порция орешков
  @Query(
      nativeQuery = true,
      value = "SELECT generate_series(1, :weightAll/:weightNut ) AS num, 2 AS weight LIMIT :portionWeight")
  fun getNutsPortion(weightAll: Long, weightNut: Long, portionWeight: Long): List<Nut>

  //По одному орешку
  @Query(
      nativeQuery = true,
      value = "SELECT generate_series(1, :weightAll/:weightNut ) AS num, 2 AS weight LIMIT 1 OFFSET :off"
  )
  fun getNut(weightAll: Long, weightNut: Long, off: Long): Nut
    
}

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

Значения для выборок

    // Вес ореха 2 грамма
    final val weightNut : Long = 2;

    //Вес пакета 5кг
    final val weightAll : Long = 5000;

    //Количество орехов всего штук в пакете
    val countNuts = weightAll / weightNut;

    //Вес порции орехов на тарелке для просмотра одной серии
    private final val portionWeightCount: Long = 100;

    val speed =  "Скорость съедания ${portionWeightCount * weightNut}г орехов: "

Проекция для DTO орешка

interface Nut {
    val num: Long
    val weight: Long
}

Методы реализации

//Нормальное решение - отсыпать орешков
fun solveNormal (): String {

      val nowSeconds = Instant.now().epochSecond;

      val nutsList: List<Nut> = nutsRepository.getNutsPortion(weightAll = weightAll, weightNut = weightNut, portionWeight = portionWeightCount)

      nutsList.forEach {
          logger.info("${it.num}, ${it.weight}")
          grawNut()
      }

      return speed + (Instant.now().epochSecond - nowSeconds) + " секунд"
  }

//Маргинальное - ходить за орешками по одному на кухню
fun solveMarginal(): String {

    val nowSeconds = Instant.now().epochSecond;

    for ( i in 0..< portionWeightCount) {

        moveToKitchen()

        nutsRepository.getNut(weightAll = weightAll, weightNut = weightNut, i).let {
            logger.info("${it.num}, ${it.weight}")

        }

        moveFromKitchen()

        grawNut()

    }

    return speed + (Instant.now().epochSecond - nowSeconds) + " секунд"
}

fun solveBigPacket (): String {
    TODO("Придумать эмуляцию решения с большим пакетом. Смысл тот же, что и с кухней, просто меньше интервалы взятия ореха в связи с неудобством")
    return speed;
}

И эмуляция задержек

    fun grawNut () {
        logger.info("Грызть орех");
        Thread.sleep(100);
        logger.info("Орех съеден");
    }


    fun moveToKitchen () {
        logger.info("Сходить на кухню");
        Thread.sleep(500);
    }

    fun moveFromKitchen () {
        logger.info("Вернуться из кухни");
        Thread.sleep(500);
    }

Смысл здесь абсолютно аналогичен классической задачей для джуна - вместо походов в БД с забором по одной записи, которые делаются медленно в цикле, сделать "одним ударом" забора всех данных с ограничениями. Жиза!

Возвращаемся к реалиям

Задача моего примера - это продемонстрировать отличие реальных простейших алгоритмов для решения задач от "алгоритмов" из СМИ и интернета.

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

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

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

А что толку от них, если ваш конкретный менеджер или аналитик плохо описывают задачу или вообще не описывают, не разбираются в предметной области?

Вы будете кормить ИИ плохие, кривые данные, вы будете тормозить при межсерверном взаимодействии, мучаться с выбором монолиты или микросервисы?

Проблема же далеко не в ИИ, если рассматривать его как черный ящик.

Приведу в заключение пару примеров из жизни, но ближе к IT.

Смартфон

Многие замечали, что телефон со временем начинает лагать, приходится покупать новый или периодически сбрасывать до заводских настроек, постоянно чистить приложения и прочее?

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

Происходит конкуренция за ресурсы, естественно, что плохо выбранные костыльные реализации curl'ов с огромным количеством if-else логики (а её немало, сколько всяких разных галочек и радио-кнопок) нагружают мобильник и он начинает фризить. Но зато у всех приложений появляется ИИ.

Видео-хостинги

Далеко ходить не надо - YouTube. При загрузке своих видео на канал нужно заполнять форму с самим файлом, заголовком, описанием и другими полями.

Присмотримся к двум важнейшим для публикации и ротации input'ам:

  • Да это видео для детей

  • Нет это видео не для детей

Связанный со вторым:

  • Это видео подходит для пользователей менее 18 лет

  • Нет, это видео не подходит для пользователей менее 18 лет

Popup загрузки нового видео на YouTube
Popup загрузки нового видео на YouTube

Присмотритесь.

Изначально, противоречивые radio button's, да еще и связанные между собой, да еще и захардкоженные if-else логикой на "гипотетический" возраст гугловой учетки, подаются в форме так, что единого понимания ожидаемого результата просто нет.

И всё, неверная комбинация параметров (а такое регулярно бывает) - и видео не показывается новым зрителям, не ротируется в трендах

Алгоритмы рекомендаций тут ни причем, алгоритм ВАЛИДАЦИИ с абсолютно неверно собранными требованиями реализован плохо.

А причем тут ИИ? Абсолютно ни при чем, просто ваш набор POST-данных не попадает в ... алгоритмы!

Выводы

Начинать разбираться в IT надо не с алгоритмов и трубить о них из всех оркестров.

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

Далее идут структуры данных. А только потом алгоритмы. Null's и подобные простейшие вещи как математический нуль, пустые списки и массивы, рациональные условия, а только потом алгоритмы.

Потому что нельзя сделать ИИ рекомендации из emptyList.

Правильная книга
Правильная книга

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


  1. axel_pervoliajnen
    13.01.2026 14:46

    Музыкант, прости меня сенжЖор ответьте пжлст зачем 4 монитора на картине первой? Ну я понимаю когда два. На первом код на втором вебсайт открытый. Но ещё плюс 2 экрана? Глаза то всего два (обычно)?


    1. S_gray
      13.01.2026 14:46

      На третьем лог, на четвертом - pdf с описанием стандарта какого-нибудь, на пятом - текущие письма в почтовом ящике, на шестом - пасьянс в качестве сорбэ. Про два глаза и два монитора - ну-ну...


  1. Akon32
    13.01.2026 14:46

    В тегах Java, но в статье от Java лишь многословность... Если её отбросить, с основной идеей сложно не согласиться.

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


    1. ShapitoS999 Автор
      13.01.2026 14:46

      Спасибо, учту, в следующей статье для разнообразия запилю микросервис на Java в одной экосистеме с Kotlin


  1. vybo
    13.01.2026 14:46

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


  1. muhachev
    13.01.2026 14:46

    Какой-то бессмысленный пафосно нравоучительный набор бредовых субъективных сентенций. Что за модель юзаете для генерации подобного низкопробного нейрослопа?


  1. HardlinePeak936
    13.01.2026 14:46

    По орешкам — есть ещё четвёртый метод: отнести компьютер на кухню к шкафу :)


    1. Anton_Timofeev
      13.01.2026 14:46

      Кажется, что "Сходить на кухню, и взять N орешков" - это вообще один и тот же алгоритм.