326
0
0
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
Назад

Лучший алгоритм сортировки, или задачка с подвохом

Время чтения 1 минута
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
326
0
0
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники

Всем алоха. Меня зовут Сергей Голицын, и я ведущий инженер-программист с девятью годами опыта. Умею проектировать, внедрять и разворачивать крупномасштабные облачные проекты с низкой задержкой более чем для 1 миллиона пользователей по всему миру. Я руковожу и наставляю команду из 14 инженеров. Кроме того, я основал ютуб-канал FaangTalk, подкаст и программу коучинга для программистов. За свою карьеру я прошел огромное количество собеседований. Естественно, большая часть из них была посвящена алгоритмам. Поэтому сегодня я хочу поговорить об алгоритмах сортировки на интервью.

Лучший алгоритм сортировки, или задачка с подвохом

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

Какой алгоритм лучше всего подходит для сортировки?

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

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

  • Что мы знаем о данных? Они уже полностью или по большей части отсортированы? Насколько большим может быть набор данных? Могут ли там присутствовать повторяющиеся ключевые значения?
  • Каковы требования к сортировке? Нужна ли оптимизация производительности для лучшего, худшего или среднего случая? Должна ли сортировка быть устойчивой?
  • Что мы знаем о системе? Как самый большой объем данных соотносится с доступной памятью — меньше ее, имеет аналогичный объем или превосходит ее по объему?

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

  • Сортировка пузырьком. Хорошо подходит для небольших массивов или когда массив уже частично отсортирован.
  • Сортировка вставками. Эффективна для небольших или частично отсортированных массивов, а также для онлайн-сортировки, когда данные поступают постепенно.
  • Быстрая сортировка (QuickSort). Часто используется для сортировки больших массивов, особенно если известно, что данные распределены равномерно.
  • Сортировка слиянием (MergeSort). Хорошо подходит для сортировки связанных списков или когда требуется устойчивая сортировка.
  • Сортировка выбором (SelectionSort). Простой и понятный алгоритм, который может быть полезен для небольших массивов или в случае, когда количество операций записи важнее, чем время выполнения.

Сказ о провальном интервью в FAANG

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

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

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

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

В Timsort мы используем дополнительную память. Например, если файл помещается в память и занимает 20 ГБ, то для Timsort нам нужно минимум 40 ГБ. Кроме того, нужна память на старт JVM, указатели и прочие расходы. Поэтому трюк с такой сортировкой не пройдет. Все это я уже узнал после того, как провалил интервью, в беседе с интервьюером.

Что делать, если нет идей?

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

Но как быть, если в задаче указан бесконечный поток данных? Здесь стоит уточнить у интервьюера, что именно будет результатом. Это будет текущее среднее значение, или значение на определенный момент времени, или… можно придумать еще несколько кейсов.

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

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

Если у вас были подобные ситуации или есть другие варианты решения, то, пожалуйста, поделитесь, я буду рад обсудить.

Комментарии0
Тоже интересно
Комментировать
Поделиться
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники