Гроза собеседований: Задача FizzBuzz
Есть известное высказывание:
Меня немного удручает тот факт, что 199 из 200 соискателей программистских вакансий не умеют программировать. Повторю: они не умеют писать код. Вообще.
Речь здесь идет об известной задаче FizzBuzz, которую придумали еще в 2007 году.
Смысл ее такой:
Напишите программу, которая выводит на экран числа от 1 до 100. При этом вместо чисел, кратных трем, программа должна выводить слово «Fizz», а вместо чисел, кратных пяти — слово «Buzz». Если число кратно и 3, и 5, то программа должна выводить слово «FizzBuzz».
Появилась эта задача из-за того, что на технических интервью даже Senior Developer-ы не могли решать простейшие задачки на бумаге. Чтобы решить задачу FizzBuzz, у многих уходило более 15 минут, хотя должно занять не более пары минут.
Сейчас эта (и подобные) задачи стали уже классикой собеседований - их активно используют, чтобы выявить «недопрограммистов».
Дэн Кигель описал свои мысли по этому поводу так:
Поверьте, если вы можете написать цикл от 1 до 10 на всех языках, указанных в вашем резюме, если вы можете решить в уме несложный арифметический пример и если вы знаете, как применить рекурсию в несложной (но взятой из реальной жизни) задаче — то вы уже на голову выше большей части людей, вращающихся в нашей индустрии.
Так в чем же здесь сложность? Почему эта задача вызывает такой ступор? Давайте попробуем решить эту задачу с помощью языка Python.
Попытка 1
Первое, что приходит в голову - в цикле проверять выполнение каждого условия и в зависимости от результата выводить число, Fizz или Buzz.
Вот так выглядит код в первой итерации:
Однако, тут сразу можно дать несколько рекомендаций. Некоторые в коде уже учтены, а некоторые просто нужно принять к сведению.
- Лучше проверять делимость на 15, а не на 3 и 5 по-отдельности. Причина проста - одно вычисление быстрее, чем 2.
- Проверять делимость лучше с помощью оператора %, а не с помощью функций. Оператор работает быстрей.
Можно еще придумать ряд правил. Главное, понимать, что задача не просто на «умение написать код». С помощью этой задачи также проверяется, насколько Вы умеете код оптимизировать. Чем «экономней» будет Ваш цикл, тем лучше.
В интернете Вы найдете огромное количество реализаций этого алгоритма. Какие из них правильные?... Сложно сказать. Скорее всего, правильным кодом будет тот, который сидит у Вашего интервьюера в голове :) Так что не пытайтесь найти «секретный ключ» - просто сравните большое количество вариантов, найдите разницу между ними и выберите самый эффективный с точки зрения производительности и сложности алгоритма.
Попытка 2
Давайте рассмотрим еще несколько реализаций. Например, здесь с помощью строк мы уменьшаем количество условных блоков на 1.
Вот еще пример - в одну строку.
А вообще, не зря говорят, что преждевременная оптимизация - источник зла. Пытаться что-то оптимизировать в отрыве от контекста - не всегда умная (и приносящая пользу) задача. Вы можете намудрить со структурами данных или сделать еще что-то великое, но если остальная программа использует другие структуры, то толку от этого не будет.
По этому поводу есть даже одно интересное замечание:
Если думать о производительности, то вообще надо предварительно вычисленные значения использовать.
Например, как-то так:
Разобрались?
Тогда закрепите знания на практике - попробуйте решить задачу FizzBuzz самостоятельно!Эпилог
Мы с Вами разобрали популярную задачу FizzBuzz и даже рассмотрели несколько вариантов решений. Надо понимать, что часто условие задачи немного меняют, поэтому не стоит привязываться к конкретной формулировке. Лучше разберите как можно больше вариантов заранее, чтобы Вы могли быстро сориентироваться на любом техническом собеседовании.
И не бойтесь рассуждать. Напишите первый, черновой, вариант решения, а потом постепенно его улучшайте. Ваш собеседник это оценит, я Вас уверяю. В конце концов, не забывайте высказывание Дэна Кигеля, которое мы приводили в начале статьи.