Грокаем алгоритмы. Иллюстрированное пособие для программистов и любопытствующих от Бхаргава А. Эта книга рекомендована Яндекс Практикум при подготовке к алгоритмическому собеседованию. Сам автор указывает, что книга для самоучек, студентов, выпускников и тех, у кого программирование не является основным профилем.

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

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

Вернемся к Яндекс Практикум и их рекомендации. Если алгоритмы так важны, то почему именно эта книга? Есть масса других, где и алгоритмов больше и разобраны они так, что бери да пользуй. Например, классический труд Д. Э. Кнута Искусство программирования. Да, рисунки в детском стиле в Грокаем алгоритмы забавны. Но иллюстрации в Искусство программирования полезны для понимания. Разве это не важнее, если уж кандидата посылают на алгоритмическое собеседование?

Если алгоритмы так важны с точки зрения Яндекс Практикум, то почему они советуют именно Грокаем алгоритмы, где приведены далеко не самые эффективные реализации? К примеру, сортировка выбором (в ГА) создает новый массив, который, к тому же, динамически растет. У Кнута приведен алгоритм сортировки выбором с обменом (5.2.3), не требующий дополнительной памяти ни на копию, ни на копию копии при динамическом росте.

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

А ведь это база для рекурсивных алгоритмов. Про то, что стек может быть конечного и даже малого размера в ГА не сказано. Лишь упомянуто вскользь, что могут быть высокие затраты памяти. А ведь, как правильно указано в 1м томе "Информатика. Основополагающее введение" от Манфреда Броя, при каскадной рекурсии "вызовы лавинообразно ведут к экспоненциальному нарастанию возникающих рекурсивных вызовов ("каскад вызовов")". И именно такой вариант быстрой сортировки расщеплением приведен в ГА. Также автор не стесняется склеивать три массива на каждой итерации. Если важна эффективность, как уверяет Яндекс Практикум, то быструю сортировку надо смотреть не в ГА, а снова у Кнута, где алгоритм обменной сортировки с разделением (5.2.2) не требует ни дополнительной памяти, ни склеивания половин.

Не менее интересно в ГА разобраны хеш-таблицы и хеш-функции, о которых нам "никогда не придется беспокоиться" ибо об этом уже побеспокоились "пожилые бородатые умники, сидящие в полутемных комнатах" (цитата из книги). Ладно, если бы это было просто безобидно, но автор рекомендует использовать SHA при реализации своих хеш-таблиц. И где будет эффективность, о которой говорит Яндекс Практикум? Для сравнения, если просто почитать 6.4 в т.3 Кнута, то станет по крайней мере понятно почему до Java 7 стандартный шаблон сгенерированного hashCode() выглядел следующим образом:

public int hashCode() {
    int result = target.hashCode();
    result = 31 * result + (optimal ? 1 : 0);
    result = 31 * result + parent.hashCode();
    return result;
}

Поиска в ширину и жадных алгоритмов в первых трех томах Кнута нет. Но их описание в ГА можно сравнить с описанием в "Искусственный интеллект. Стратегии и методы решения сложных проблем" от Джорджа Ф. Люгер. В ГА более длинно и более разжёвано, а потому и более понятно.

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

Вместо объяснения как он пришел к данной "формуле" или в чем ее физический смысл, дабы читатель мог использовать схожий подход в своей практике, автор успокаивает: "Если у вас голова идет кругом, не огорчайтесь. Это сложный материал". И по алгоритму Дейкстры, и по динамическому программированию я бы рекомендовал дополнительно почитать https://ru.algorithmica.org. Так оно будет гораздо понятнее, чем только после прочтения ГА.

На методе K ближайших соседей автор ГА либо устал, либо сам толком метод не освоил. Об этом можно судить и по корню в Евклидовой метрике, и по отсутствию нормализации. Если у нас миллионы точек в многомерном пространстве, то найти по запросу таким образом 5 соседей на практике вряд ли получится, особенно, если запросы приходят в параллель. Книга не упоминает, что все это очень дорого и по памяти, и по времени. А ведь Яндекс Практикум говорит именно об эффективности. Чтобы более полно ознакомиться с методом K ближайших соседей и понять аспекты его практического применения, вариации и альтернативы, я бы рекомендовал описание в онлайн-учебнике по машинному обучению от Школы анализа данных.

Все, что идет в книге далее, несерьезно рассматривать более чем как see also.

Что можно сказать резюмируя? В принципе, выполнение упражнений полезно (как минимум, я снова убедился, что писать на Java проще, чем на C++). Также опытный разработчик может встретить какие-то новые вещи - это тоже всегда полезно. Не программисты и начинающие разработчики наверняка найдут книгу легкой в чтении и увлекательной. И это хорошо. Но вообще хотелось бы каталога алгоритмов наподобие GoFEIPSoftware Architecture Patterns and Designing Distributed Systems.

Примеры выполнения упражнений

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


  1. HotkeyM
    05.05.2022 00:21
    +10

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

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


    1. wrqqq
      05.05.2022 00:37

      А что бы вы посоветовали?


      1. HotkeyM
        05.05.2022 01:01
        +3

        Как учебник - Algorithm Design (John Kleinberg, Éva Tardos), для подготовки к интервью - Elements of Programming Interviews, как справочник - Кормена.


      1. SibProgrammer
        05.05.2022 05:12
        +5

        • Algorithms от Sedgewick'а (с вполне практичными примерами на Java)

        • Classic Computer Science Problems in Python (тоже практичней некуда, еще и владение Python'ом подкачаете)

        • Algorithms Design Manual от Skiena (имхо, одна из самых популярных рекомендаций в FAANG'ах)


    1. nikolaysmartynov Автор
      05.05.2022 11:35
      +3

      и этот псевдокод еще очень странный и далёкий от современного программирования

      Да эти примеры кода далеки от того, что каждый из нас увидит в коде коллеги или напишет сам. Но есть у такого подхода и преимущество. Во-первых, он позволяет точнее оценить стоимость алгоритма и, например, сравнить два алгоритма с одинаковой асимптотикой. У Кнута много таких примеров, где изначальный алгоритм оптимизируется и показывается за счет чего и на сколько именно получен выигрыш. Такая возможность появляется как раз благодаря тому, что код написан на машинном языке и хорошо видно сколько чего выполняется. Во-вторых, при таком подходе невозможна магия. Рукава закатаны и все прекрасно видно. Никаких допущений, что язык или библиотека, что-то сделали, а ты об этом не рассказал. Два примера. В том же ГА при описании быстрой сортировки приведен вот такой код:

      return quicksort(less) + [pivot] + quicksort(greater)

      Код работает правильно, все понятно, все приближено к современной реальности. Но за этой простотой и понятностью скрываются циклы и копирования. Эффективность такой реализации сомнительна. Второй пример: в Алгоритмике при объяснении метода двух указателей на примере сортировки слиянием можно увидеть вот такой код:

      merge(v.begin() + l, v.begin() + mid, v.begin() + mid, v.begin() + r, c.begin());

      Не изучавшему STL будет сложно понять, что это std::merge из C++ и что тут на самом деле цикл и внутри него if, копирование и инкремент одного из двух указателей. Код короткий и хорошо понятный опытному C++ разработчику. Но для всех других такая высокоуровневость скорее помешает понять алгоритм.

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

      Но я соглашусь. Текст тяжелый, половина книг - упражнения и решения к ним. Это совсем не тоже, что каталог для практиков как у GoF.


    1. risentveber
      05.05.2022 13:44

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


  1. danilovmy
    05.05.2022 01:50
    +2

    Уже обсуждалась эта книга неоднократно на хабре. Мнения 50/50. Я бы не назвал это "Профессиональной литературой". Подтвержу слова статьи, что во второй половине книги автор перестает "грокать" и начинает "плавать". Это наводит на мысль, что глубоко изучать сложные алгоритмы все равно придется по другой литературе.

    @nikolaysmartynovты пишешь "хотелось бы каталога алгоритмов". На мой взгляд монография  Donald E. Knuth "The Art of Computer Programming" остается наилучшим вариантом. Другой вопрос, что это не публицистика, а научный труд, который читать - труд не меньший :)

    В своем комментарии https://habr.com/ru/post/439576/comments/#comment_19802200 я отмечал, что иначально Grokking Algorithms была выпущена с большим количеством ошибок, и перевод ситуацию только ухудшил. Некоторые исправления автор разместил тут: https://adit.io/errata.html , я нашел еще несколько ошибок, сообщил автору, но в errata правки пока не появились.


    1. nikolaysmartynov Автор
      05.05.2022 10:48

      ты пишешь "хотелось бы каталога алгоритмов". На мой взгляд монография  Donald E. Knuth "The Art of Computer Programming" остается наилучшим вариантом.

      К сожалению на русском можно купить только первые три тома. Четвертый том не найти. Остальные и вовсе не переводились. А похоже именно там комбинаторика, статистические методы, NP-полные задачи и т.п. По крайней мере этого нет в первых трех томах. Можно конечно и в электронном, и на английском почитать, но это не совсем то.


      1. PsihXMak
        05.05.2022 11:13

        Еще стоит упомянуть, что за эти три тома придётся выложить пол зарплаты....


      1. risentveber
        05.05.2022 13:40

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


      1. wibbtwo
        05.05.2022 14:07

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


  1. T1murgar88
    05.05.2022 09:09

    А в скиллбоксе не знаешь какие книги рекомендуют? В списке литературы для поступления в шад, не видел такой книги.


    1. nikolaysmartynov Автор
      05.05.2022 11:47

      Не могу сказать, ибо не знаю. Но видимо, там рекомендуют какую-то более серьезную литературу. Возможно, что-то что перечислил HotkeyM или SibProgrammer.


      1. T1murgar88
        05.05.2022 11:53

        Это был сарказм, просто яп это же просто курсы для свитчеров, и относится к таким курсам , как к авторитетному источнику я бы не стал.


  1. Samummm
    05.05.2022 09:10
    +3

    Книжка "Грокаем алгоритмы" - точно не учебник. Простоватая, мне не зашла. Как-то все скользко, мутно. Все книги про алгоритмы делятся на 2-е части или заумные вроде Кнута, например, где ты с 20 страницы понимаешь, что ты ничего не понимаешь или простые до нельзя, вот как эта, что-то типа алгоритмы в комиксах, где вроде бы все понятно, но ничего не ясно. А вот "золотой середины" по книгам здесь очень мало.

    Я бы порекомендовал Ананий Левитин "Алгоритмы: введение в разработку и анализ" мне очень понравилась. Просто о сложном. Я бы даже бумажный экземпляр купил, может кто подскажет где?


    1. nikolaysmartynov Автор
      05.05.2022 11:48

      Похоже только с рук или в букинистике.


  1. Kadzikage
    05.05.2022 16:20
    +1

    Jon Kleinberg, Eva Tardos Algorithm design

    Роберт Седжвик, фундаментальные алгоритмы на c++

    Обе есть на русском , читабельные , понятные


  1. Roman_Cherkasov
    05.05.2022 20:10
    +1

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


  1. Woodroof
    06.05.2022 06:14

    Если английский — не проблема, то у Introduction to algorithms недавно вышло 4 издание. На русский переведено пока только третье, но кардинальных отличий нет. Динамическое программирование там есть :)


  1. tsurugi-no_ken
    06.05.2022 07:00

    Хорошая идея создать такую книжку для первоначального ознакомления с алгоритмами!


  1. lidefo
    06.05.2022 16:29

    ГА хороша именно что для первичного ознакомления с алгоритмами


  1. Dasfex
    07.05.2022 01:35

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

    Если вы в районе нуля, это хорошая отправная точка. Хотя бы понять зачем это и как.