Как решить любую задачу: пособие для разработчика
Каждый разработчик рано или поздно получает задачу, которую просто не понимает. Разбираемся, как преодолеть пропасть между требованиями и знаниями.
Неважно, как долго вы работаете и как много у вас опыта. Даже разработчик с десятилетним стажем имеет все шансы встретиться с непонятной задачей. Как же быть? Просто начать и верить, что по ходу дела все станет яснее? Или немедленно сообщить начальнику, что вы не понимаете, что от вас хотят?
Оба ответа неправильные.
В разработке ПО (и любой другой профессии) подобные проблемы возникают постоянно. И это неплохо! Поверьте, вы способны не только решить их, но и извлечь из этого пользу, расширив свои знания и навыки.
О «требованиях»
В разных компаниях и проектах требования могут быть разными. Крупные компании обычно тщательно их прописывают, а маленькие могут иногда вообще не составлять.
В конечном счете наша цель как разработчиков – решать проблемы. Каким бы способом вы ни получили задачу, чтобы решить ее, вы должны ее понять.
О шагах
Ниже приведена последовательность шагов для решения сложных задач. Не всегда нужно выполнять каждый из них. Многое может пойти не по плану и вам придется искать ответы у коллег, аналитиков, руководителей, а возможно, и родственников. Этот процесс сбора и обобщения знаний из разных источников абсолютно нормален и поможет вам достигнуть лучшего результата.
И прежде чем мы перейдем к самим шагам, последнее предупреждение: не формализируйте их. Основная цель статьи – научить вас быстрее понимать проблему, а не создавать лишние барьеры и волокиту.
Первый шаг: анализ задачи
На этом шаге нужно попытаться осознать, что вам нужно сделать. Не как, а именно что.
Это важное уточнение. Иногда сразу переходить к воплощению, не продумав все последствия и не осознав конечную цель, может быть опасно.
Классифицируйте задачу
Определите, к какому типу относится работа, которую вам нужно выполнить. Это может быть:
- правка ошибок;
- внедрение новой функциональности;
- создание нового приложения;
- исследование проблемы;
- улучшение производительности.
Это не все возможные типы задач, но теперь вы понимаете, о чем идет речь.
Основная цель на этом этапе – определить вид работы. Это очень важно, поскольку будет напрямую влиять на ваши дальнейшие действия.
Особую важность имеет первый шаг в том случае, если требования составлены нечетко, вроде "нам нужен способ очистить кэш клиентов после обновления веб-сайта". Это можно интерпретировать по-разному:
- Необходимо немедленно реализовать некий механизм очистки кэша, чтобы пользователи всегда видели последние обновления.
- Нужно изучить все возможные способы хранения кэша и определить лучшие методы для его очистки после внедрения обновлений.
- Кэш пользователей уже должен был быть очищен, а вам требуется найти и исправить ошибку, которая этому препятствует.
Если вы не совсем уверены, что скрывается за этими требованиями, следует попросить разъяснений, прежде чем продолжать.
Сформулируйте задачу в паре простых фраз
Обобщите требования в одном или двух предложениях. Возможно, это будет не очень просто, но у вас обязательно получится.
Если вы не можете это сделать, значит, нужно разделить задачу. Таким образом, этот шаг является лакмусовой бумажкой для определения правильной организации рабочего процесса. Если задача слишком велика, нужно решать ее по частям.
Хороший пример обобщения: "при обновлении мы добавляем файлам уникальный идентификатор, чтобы браузер знал, что нужно использовать самый свежий код". Тест на простоту пройден, задача не нуждается в делении.
А пример плохой постановки задачи. "При обновлении мы добавляем файлам уникальный идентификатор, чтобы браузер знал, что нужно использовать самый свежий код. Также мы должны отправить сообщение об обновлении в CDN. Также следует обновить приложение в app store. Также…".
Это точно провал. Для решения этой задачи требуется слишком много действий, поэтому ее, вероятно, следует разделить и отслеживать каждую подзадачу отдельно.
Выделите основные части
Составьте список основных дел в любой удобной форме. Ограничьтесь очень простыми общими описаниями для каждого крупного этапа, а не составляйте подробное руководство. Лучше всего записать все ваши идеи.
Помните, что сейчас вы все еще анализируете задачу, а не решаете ее.
Пример с кэшированием слишком прост и не нуждается в схеме, поэтому мы введем более сложную задачу по созданию новой фичи: "Необходимо показывать целевое рекламное объявление, адаптированное для каждого пользователя на основании собранных данных".
Наметим основные части:
- Текущие объявления следует разделить так, чтобы они могли соотноситься с какой-то конкретной метрикой пользователя.
- Для маркетинговой команды нужен удобный способ сопоставить новые рекламные объявления с пользовательскими данными.
- Система должна агрегировать все показатели, которые имеют отношение к рекламе.
- Наконец, нужно каким-то образом получать идентификатор пользователя и выводить объявления.
Теперь этот список можно использовать для быстрого обсуждения с командой или руководителем, после которого могут быть внесены новые пункты, например:
- Нужно добавить для пользователя возможность сообщить о том, что он больше не хочет видеть конкретные объявления.Вы же не хотите раздражать ваших любимых клиентов!
Вот так, немного подумав над задачей и составив план, вы сэкономили часы или даже дни разработки и избежали множества проблем.
Возможно, вы считаете, что вся эта работа должна быть выполнена еще до того, как разработчик получит требования – и это на 100% верно!
Однако мы, к сожалению, не живем в идеальном мире, и требования не всегда полностью конкретизируются до того, как попадут к разработчику. Поэтому нужно сделать все возможное, чтобы правильно оценить задачу.
Определите проблему, которую вы пытаетесь решить
Определитесь, какую существующую или предполагаемую проблему реального мира вы пытаетесь решить.
В идеале ответ очевиден. Например, в задаче с кэшем цель состоит в том, чтобы пользователи всегда видели последние обновления. В примере с рекламой мы решаем проблему релевантности объявлений для пользователя.
Если вы не можете ответить на вопрос, вероятно, следует спросить кого-то, зачем вы решаете эту задачу. Либо вы получите более четкое представление, либо еще раз подумаете о том, что необходимо сделать.
Более глубокое понимание проблемы и цели позволит вам принять лучшие решения при реализации и избежать бесполезных усилий.
Второй шаг: разбор и оценка требований
Вы уже знаете, что и зачем вы должны сделать. На следующем шаге следует понять, каким способом решать задачу и почему им.
Уточните все термины, связанные с задачей
Вероятность встретить незнакомые понятия гораздо выше, если вы новичок или являетесь сотрудником большой компании.
Речь идет и о бизнес-терминах, например, продуктах, клиентах или процессах, и о понятиях разработки, таких как названия инструментов, приложений, служб или библиотек.
Возможно, вы знаете, что значит создать доступ к агрегированным данным о пользователе, а как насчет ее добавления в DAO? А имеете ли вы представление о том, что такое MADF в форматировании рекламных данных?
Если вы не понимаете важные термины, то общий смысл задачи может от вас ускользнуть и пострадает реализация.
Определите, как должна быть выполнена задача
Теперь можно начинать думать, как выполнить задачу. В зависимости от проекта этот этап может сильно различаться. Вам могут просто рассказать, какую функциональность нужно получить в итоге, или подробно описать каждый шаг, который следует сделать. Чаще всего встречается нечто среднее.
Если вы получили инструкции, то обязательно ознакомитесь с ними и оцените их. Это кажется очевидным, но обратите внимание, в какой именно момент мы переходим к этому шагу.
Вы могли бы погрузиться в технические детали реализации прежде, чем поняли суть и цель задачи. Но вы сделали все правильно и теперь можете объективно оценить каждую инструкцию.
Определите, решены ли проблемы
Именно на этом шаге происходит реальный анализ и интерпретация задачи. Здесь вы можете сосредоточиться на общей картине целей и результатов, подводя итог тому, что и зачем (анализ) и как (интерпретация) вы должны сделать.
Проделав всю подготовительную работу, вы видите более широкую картину. Взгляните на план действия и подумайте, приведет ли он вас к нужному результату и решит ли первоначальную задачу.
Если ответ положительный, начинайте работать. В ином случае для разрешения конфликтов необходимо перейти к третьему шагу.
Третий шаг: критическое мышление
Вы уже хорошо понимаете суть проблемы и знаете, как ее решить. Последний шаг поможет убедиться, что ваше решение правильное.
Чтобы создать самый лучший продукт, мы обязаны отсекать недостатки и бессмысленные вещи, но прежде чем сказать коллегам о том, что конкретный подход неправильный, нужно объяснить почему это так.
Сформулируем некоторые основные правила о разногласиях.
Когда не соглашаться
- Не возражайте, пока не поймете полностью.
Вы хорошо понимаете, с чем именно несогласны? Если у вас нет всех необходимых данных, самое время вернуться к предыдущим шагам.
- Не спорьте по субъективным вопросам. Сосредоточьтесь на реальных возможных проблемах.
"Мне не нравится" – это субъективно. “Большое количество операций плохо повлияет на производительность" – это объективно.
- Подготовьте аргументированное объяснение вашего несогласия.
Вы не способны объяснить, почему это неправильно? А вы уверены, что это действительно неправильно?
Прежде чем вы не согласитесь, внимательно выслушайте коллег и постарайтесь понять их аргументы. Может быть, вы что-то упускаете.
Как не соглашаться
Чтобы ваше несогласие было объективным, оно должно ясно демонстрировать, что принятое решение:
- основано на неполной информации, не учитывает существующих условий и данных;
- основано на ложной или ошибочной информации;
- нелогично или ломает существующую функциональность. Также нелогичной может быть сама исходная проблема;
- не решает проблему полностью. Иногда это именно то, что требуется. В разработке ПО мы часто начинаем с создания минимально жизнеспособного продукта, лишенного некоторой второстепенной функциональности. Но порой решение не дотягивает даже до этого уровня.
Подведем итоги
Запомните самое важное: не формализируйте этот процесс. На практике он гораздо быстрее и проще, чем в теории. Просто записывайте ваши мысли в заметки и при необходимости поговорите пару раз с коллегами, чтобы уточнить все тонкости задачи и реализации. Вот и все!
Вот упрощенный список шагов:
Шаг 1. Анализ
- Классификация задачи;
- Резюме в паре предложений;
- Выделение основных частей;
- Определение проблемы.
Шаг 2. Разбор и оценка
- Уточнение терминов;
- Составление общего плана реализации;
- Проверка, решает ли этот план проблему.
Шаг 3. Критическое мышление
- Знайте, когда не соглашаться;
- Знайте, как не соглашаться.
Используете ли вы эти приемы? А может быть, у вас есть своя система для понимания сложных задач? Расскажите о ней в комментариях.
Перевод статьи How to understand any programming task