Нужно ли программисту уметь считать?
Мой знакомый сейчас находится в поиске работы и за последнее время побывал на многих интервью. На одном из них уже после всех возможных вопросов про API и HTTP, его озадачили, а не знает ли он, сколько аптек в Петербурге.
«Что за глупый вопрос,» — подумал он.
Даже если сперва вопрос поставил его в ступор, виду он не подал. «Наверно, тысячи две,» — ответил соискатель. «А почему именно столько?» — уточнил интервьюер. «Ну одна тысяча мне показалось слишком мало. Пять слишком много, и я решил, что где-то посередине,» — был ответ. На этом интервьюер остановился.
После этой встречи мы обсуждали с приятелем список вопросов. «Ну что за дичь,» — сокрушался знакомый, — «Опять эти пинг-понговые шарики, которые вышли из моды, наверно, лет сто назад.» Сказать по правде, раньше я и тоже так считал. Но вновь столкнувшись с таким вопросом, я вдруг подумал. Ведь это же, на самом деле, великолепная задача.
Отвлекусь и поделюсь другой задачей, на этот раз рабочей, которую пришлось решать на моем проекте не так давно. Наш бизнес растет, и мы приближаемся к тому, что принято называть хайлоад, когда простое горизонтальное масштабирование в существующей архитектуре не помогает так, как хотелось бы. Именно поэтому мы решили вводить новый компонент и строить его на базе событийной архитектуры (event-driven architecture). В основном наш опыт строился на теории из конспектов microservices.io и книги Алекса Сю, но никакой практики построения с нуля не было. Зная, как верхнеуровнево это всё работает, мы стали подбирать инструмент, который бы помог решить нашу проблему.
На входе в нас были метрики, описывающие текущую нагрузку, прошлую (для расчета прогнозируемого роста), и объем данных (вплоть до размера передаваемого сообщения), который мы хотим через этот компонент пропускать. Требовалось рассчитать, сколько бы стоило внедрение такой системы сейчас и через пару лет с учётом роста и переиспользования архитектуры, сколько бы составляли все издержки при достижении заданных показателей надежности. Посидев с таблицами, мы высчитали, что нам необходимо, чтобы система могла перемалывать такое-то количество сообщений, общий поток составит столько-то ГБ в среднем и столько-то в пике, нам потребуется столько-то ГБ для хранения всего этого дела, и за всю подсистему мы должны будем заплатить столько-то денег. В итоге мы проанализировали четыре решения, сделали сводную таблицу и выбрали одно.
Чем эта задача отличается от вопроса про аптеки? Кроме абстрактной формулировки — ничем. В обоих случаях нам нужно вычислить, пусть даже весьма условно, некую метрику (количество или стоимость). Ни о какой точности речь идти идёт, допущения сильны, погрешности велики, но это и не важно.
Мы не смогли до цента оценить стоимость выбранного решения, но зато сравнили несколько вариантов между собой, ведь мы везде использовали одинаковую методику расчетов. Сам по себе расчет в вакууме бесполезен, и должен использоваться как один из факторов при принятии решения.
Более того, обе задачи используют одни и те же инструменты: сбор известных метрик, элементарные математические формулы (при желании можно подключить статистику или матанализ) и выражение искомых метрик через известные метрики и формулы.
Рассчет стоимости внедрения всем интуитивно понятен. Мы знаем текущее состояние, аппроксимируем рост пропускной способности и потребности к хранению, умножаем на цену, получаем общую стоимость. Как же подступиться к задаче про аптеки? Что для меня было бы приемлемым ответом на такой вопрос?
Ответ пальцем в небо иногда может быть хорошей стратегией, когда не от чего отталкиваться. Но что до данной задачи, это худший ответ из всех возможных.
Другой простой ответ в лоб это воспользоваться справочником или поисковой системой. Поиск доступной информации в разных источниках это тоже аналитика, и потому такой ответ уже лучше
Более сложный вариант, попробовать рассчитать самостоятельно. Для этого нам нужно выделить метрики, которыми мы обладаем. Придется побрейнштормить и накидать несколько, хоть и не все могут нам пригодится. Например, население города (4 млн) ни к чему нас не приведёт, так как иначе нам потребовалась плотность аптек к населению, что вычислить сразу весьма проблематично.
Решение, которое я выдал при обсуждении со знакомым, заключалось в следующем. Я знаю, что город окружён КАД, и откуда-то я знаю его примерную длину (150 км, метрика из личного опыта). Сделаем допущение, и представим, что эта кольцевая дорога действительно выглядит как круг (на самом деле нет), тогда мы можем посчитать площадь, заключённую внутри. Город занимает примерно половину, так как остальная площадь это залив, и по расчетам это примерно 570 кв. км. Отмечу, что предыдущие шаги можно было опустить, если бы я изначально знал площадь города, но в этом и суть упражнения: выразить неизвестные через известные. Далее я рассуждал так: я живу где-то в городе, и вокруг меня в пятиминутной шаговой доступности есть 6 аптек, и именно этой доступностью я покрываю один квадратный километр при средней скорости ходьбы 6 км/ч. Воспользовавшись пропорцией получаем 3400 аптек.
Как видно, расчеты весьма приблизительные, принято очень допущений, но самое главное, мы определили порядки. У меня в шаговой доступности 6 аптек, у кого-то могло бы быть 3, а у кого-то 8. Разброс большой, но и к большой точности мы не стремимся. Для её увеличения можно было бы воспользоваться методом Монте-Карло, и получить количество аптек в шаговой доступности в нескольких точках города. В своих выкладках я использовал только одно измерение.
В качестве бонуса, вычислив все метрики выше, я смогу прикинуть количество аптек в любом городе, сделав допущение, что их плотность в расчете на население примерно одинакова. Расширив пространство известных нам метрик мы можем «покуситься» на ещё более неизвестные, именно поэтому данный подход так прекрасен.
Идеальным ответом на вопрос об аптеках в рамках собеседования было бы упоминание всех трёх методов с указанием их применимости. Это показывает не только способности к аналитике, но и ещё и мета уровень: анализ того, какой именно уровень аналитики уместен.
И возвращаясь к ответу в заголовке. Уметь считать, конечно же надо. Возможно, на начинающих позициях способность к аналитике и не так важна, она приходит с опытом. Перво-наперво нужно научиться обращаться с инструментом, а уже потом искать возможные нестандартные способы его применения. Элементарные формулы — инструмент, а увидеть их применение в нестандартных задачах — мастерство, которое приходит далеко не сразу. Но чем выше уровень разработчика, тем более критичны навыки аналитики. И если для начинающих разработчиков этот вопрос просто смешен, то, по моему мнению, для профессионалов, просто необходим, но, может быть и не в такой формулировке.
Кстати, более-менее точный ответ на вопрос: 3260 (получен с использованием справочника).