Problem Solving: 7 факторов для определения и правильного анализа проблемы
A problem: a difference between the actual situation and the desired situation.
Думаю, многим попадался друг или коллега, который или которая может всё. К ним можно прийти с любой проблемой — и они найдут решение. Причем часто такое, о котором ты не подозревал, хотя изучил уже все вдоль и поперек. Мне они всегда казались суперлюдьми. И есть определенные способы, которыми эти суперлюди пользуются.
Хотя «problem solving» переводится как «решение задач», я оставлю термин «проблема» вместо более узкого — «задача».
Фактически все, что мы делаем каждый день на работе, это problem solving. Большую часть времени у нас традиционно занимает решение: мы любим свои решения, оптимизируем их, долго обдумываем. Мы рады, когда придумываем решение, и нам нравится приводить его в жизнь шаг за шагом. Для программиста это может быть алгоритм, для менеджера — стратегия, для рекрутера — план действий. Мы так увлекаемся решением, что часто забываем, какую проблему оно решает.
Проблема, которой мы заняты, может казаться очевидной, но часто, когда появляется контекст или мнение стейкхолдеров, выясняется, что мы решали проблему, которую больше никто не видел, или наше решение работает только для «сферического коня».
Я хочу поделиться простым фреймворком анализа проблем, который помогает идентифицировать нужную проблему и найти ее оптимальное решение.
Рисунок автора
Анализ проблемы
Для определения проблемы и вдохновения идеями нужно иметь полный контекст ситуации, куда входит:
- Что решаете?
- Почему возникает проблема? (т. н. root cause, используйте 5 whys при необходимости)
- Зачем это нужно?
- Для кого решаете?
- Как часто возникает проблема?
- При каких условиях?
- Какой бюджет/срок на решение?
Не все из этих семи параметров каждый раз будут одинаково помогать выявить настоящую проблему: иногда это один параметр, иногда — пять, и сложно отсортировать их по приоритету. Фреймворк не строгий. Но отталкивайтесь от реальной задачи, которую хотите решить.
Со стороны менеджмента важно объективно описать проблему, а команде нужно убедиться, что она поняла ее верно. Если что-то из контекста неясно или не хватает информации, спрашивайте. Можете этими вопросами поставить менеджмент в неловкое положение, и им тоже придется задуматься и раздобыть вам данные.
Частая ошибка: сфокусироваться на самом описании проблемы, сделать ее абстрактной и проработать универсальное решение в противовес конкретному.
Ограниченность ресурсов
Многие из нас перфекционисты, и мы хотим, чтобы наше решение было самым прочным, самым надежным и вообще идеальным по своей красоте. Но решения, красивые в реализации и учитывающие всевозможное количество деталей, обычно очень долгие и дорогие. Поэтому решение, которое мы предлагаем, должно быть good enough, чтобы решить именно ту проблему, которая уже стоит перед нами, а не еще потенциальные десять.
У любого бизнеса ресурсы ограничены, это часть контекста, которую нужно иметь в виду.
Так в чем проблема
Мой любимый пример — об аэропорте Хьюстона, который часто разбирают на семинарах с тематикой «Чего хочет кастомер?». Пассажиры начали жаловаться, что очень долго ждут багаж. Они прилетели, прошли паспортный контроль, пришли к багажным лентам и долго ждут. Выяснили, что время ожидания — в среднем 10 минут, например. Аэропорт выделил бюджет на то, чтобы ускорить доставку багажа, и после нескольких месяцев оптимизации удалось сократить время ожидания с 10 до 8 минут. Жалобы не пропали.
Тогда было принято решение изменить маршрут пассажиров и сделать его на 8 минут длиннее, чтобы, когда они приходили к багажным лентам, багаж уже был там. Жалобы прекратились. То есть изначально компания взялась решать не ту проблему, и для второй проблемы было более простое и дешевое решение — пустить пассажиров через более длинный коридор.
Проанализируем контекст с помощью нашего фреймворка:
Вопрос | ✅ | ❌ |
Что решаете? | Уменьшить количество жалоб от клиентов | Низкая скорость доставки багажа |
Почему возникает проблема? |
| Машине с багажом нужно сделать объезд |
Зачем это нужно? | Улучшить имидж компании и снизить нагрузку на саппорт | Ускорить доставку багажа на ленту |
Для кого решаете? | Все пассажиры внутренних рейсов (этот вопрос важен, чтобы понять процент затронутых кастомеров) | |
Как часто возникает проблема? | Каждый раз (этот вопрос важен, чтобы понять частоту возникновения проблемы) | |
При каких условиях? | При любых (тут важно понять, обычные это условия или экзотические, а также получить любые данные, которые помогут дебаггингу) | |
Бюджет/срок | 2 недели | 3 месяца |
Видно, что вместо того, чтобы сосредоточиться на уровне возникновения проблемы, то есть кастомерских жалобах, сосредоточились уровнем ниже, на одном из возможных решений.
Основные сложности
Самая большая ошибка, конечно — не анализировать проблему вообще. Но даже когда беремся за анализ, мы везде сталкиваемся со сложностями.
При определении, что решаете |
|
При определении root cause |
|
При определении, зачем нужно решение |
|
При определении, для кого нужно решение |
|
При определении частоты возникновения проблемы |
|
При определении условий возникновения проблемы |
|
При определении стоимости решения |
|
Примеры анализа
Давайте разберем еще несколько проблем с помощью этого фреймворка и ошибки в их анализе.
Определение сегмента
Пишет кастомер в саппорт, что не может загрузить свой CSV. При рассмотрении файла выясняется, что формат немного отличается от того, который поддерживает система. Какое решение кажется очевидным? Проапдейтить систему и начать поддерживать и этот формат. Но добавим контекст:
Вопрос | ✅ | ❌ |
Что решаете? | Невозможность загрузить файл определенного формата | |
Почему возникает проблема? |
| |
Зачем это нужно? | Новый кастомер хочет попробовать продукт, для этого ему нужно свои данные загрузить из CSV | Поддерживать файлы, сгенерированные в старой версии |
Для кого решаете? | Конкретно для этого человека, больше таких просьб не было | Для всех, кто генерирует файлы старой версии |
Как часто возникает проблема? | Данные нужно загрузить только один раз, для того чтобы дальше пользоваться фичей | При каждой загрузке |
Когда видим контекст, появляется другое решение — сконвертировать своими силами кастомерский файл в один из поддерживаемых форматов и загрузить его вручную. Это даст возможность кастомеру сразу же попробовать продукт. Конечно, это решение не масштабируемое (если завтра будет 50 таких запросов, мы не справимся), не абстрактное (работает только для этого файла, а не для всех такого формата) и совсем неизящное с точки зрения инженерии. Но оно быстрое, не усложняет систему и решает реальную проблему, а не ту, что может возникнуть завтра.
Другой пример: на сервис пошла повышенная нагрузка, и все процессы начинают падать, потому что им не хватает памяти. Произошло это потому, что пришел один кастомер, который добавил очень много данных на обработку. Вариант решения: оптимизация производительности. Займет неделю и предотвратит повторение, если придет еще один такой кастомер (в чем уверенности нет). Возвращаясь к проблеме, вариант второй — ограничить количество памяти, которое один процесс может себе забрать. Это замедлит скорость обработки данных для всех кастомеров, но решение моментальное, возвращает работоспособность сервису, и «тяжелый» кастомер получит свой результат уже через сутки.
Вопрос | ✅ | ❌ |
Что решаете? | Процессы падают | Текущая имплементация ест много ресурсов |
Почему возникает проблема? |
| Все задачи сразу добавляются в память |
Зачем это нужно? | Чтобы все процессы всех кастомеров корректно отработали | Чтобы сложные заказы быстро обрабатывались |
Для кого решаете? | Для всех кастомеров | Для любого кастомера, который добавит много задач |
Как часто возникает проблема? | Случай единичный | Каждый раз |
При каких условиях? | Если кто-то добавил много задач |
Фокусирование на одном решении
Кастомер жалуется, что у него подвисает интерфейс. Интуитивное решение — оптимизация производительности. Если таких кастомеров мало, а бюджет небольшой, то добавление лоадеров решит проблему. Часто в таких случаях проблема не в скорости, а в том, что интерфейс не отвечает, и пользователь не понимает, что происходит. В таком случае теряется ощущение контроля над ситуацией и появляется дискомфорт. При наличии лоадера кастомер будет знать, что надо подождать; система становится для него предсказуемой.
Вопрос | ✅ | ❌ |
Что решаете? | Жалоба от клиента на повисший интерфейс | Тормоза на фронтенде |
Почему возникает проблема? |
| |
Зачем это нужно? | Сохранить клиента | Улучшить производительность |
Для кого решаете? | Пользователи FF, у которых включена определенная фича и есть более 20 записей | |
Как часто возникает проблема? | Каждый раз при открытии фичи | |
При каких условиях? | FF, доступ к фиче, более 20 записей |
Или, к примеру, программисту нужно получить SSH-доступ к серверу, для того чтобы выполнить определенную команду, а у хостера этого доступа из коробки нет. Можно пойти по пути чтения документации, углубиться в нее на день, ничего не найти и отчитаться о том, что документация прочитана. Какую проблему решили? Ознакомления с документацией. Менеджмент такую задачу вернет назад, потому что изначальная проблема не решена. Если документация не помогла, можно написать в саппорт или спросить в community.
Вопрос | ✅ | ❌ |
Что решаете? | Выполнить команду на сервере | Получить SSH-доступ к серверу |
Решение, не взвешенное по стоимости
В систему каждый месяц нужно добавлять 200 IP, полученных из третьего источника. Для этого их нужно сконвертировать в подходящий формат и скопировать в специальную форму, удалив предварительно предыдущие 200 IP. Можно это автоматизировать? Да. Уйдет два дня (16 часов), чтобы запрограммировать, протестировать и задеплоить. Копи-пейст вручную с исправлением формата на нужный занимает 10 минут каждый месяц, то есть 2 часа в год. За 8 лет стоимость автоматизации сравняется со стоимостью ручной работы. Чтобы автоматизация стала выгодней ручного решения, нужно, чтобы продукт и эта фича просуществовали более 8 лет. Если вы в этом не уверены, то не стоит вкладываться в автоматизацию.
Вопрос | ✅ | ❌ |
Как часто возникает проблема? | 1 раз в месяц | Каждый раз |
Какой бюджет/срок на решение? | 10 минут | 16 часов |
Другое решение при том же бюджете
Нужно найти фуллстек-разработчика на проект. Рекрутер с ног сбился — никого нет. Фуллстек нужен, чтобы делать работу по фронту и бэку. Зная бюджет (10 000) и предполагаемую загрузку, можно открыть две вакансии (по 5 000): на фронт и на бэк, возможно, парт-тайм.
Вопрос | ✅ | ❌ |
Что решаете? | Найти людей для деливери проекта | Найти фуллстека |
Какой бюджет/срок на решение? | 10 000 | 10 000 |
Некорректная цель
Есть параллельно запущенные процессы, и каждому перед стартом надо взять прокси из фиксированного списка. Бизнес хочет посмотреть, как поменяются возвращаемые результаты, если процессы будут ходить под прокси.
Базовое решение понятно, но в процессе к нему добавляется фича балансировки и ротации проксей; то есть, если одну прокси использовали 10 раз, а вторую — 5, в следующий раз нужно брать ту, которую использовали меньше, то есть вторую. Очень красивое решение, если есть проблемы с баном или необходимостью равномерно распределять трафик. Фактически оно решает проблему, которой нет.
Вопрос | ✅ | ❌ |
Что решаете? | Получить более точные результаты с использованием прокси | Равномерное распределение нагрузки между проксями |
Почему возникает проблема? | При использовании одного и того же IP сервис по своим причинам отдавал неверные данные | Базовая реализация берет первую попавшуюся прокси |
Зачем это нужно? | Проверить, готовы ли кастомеры платить за данные такой точности | Равномерно распределить трафик и минимизировать вероятность бана |
Граница между проблемой и решением
Так теоретически можно разделить сферы, где заканчивается проблема и начинается решение. И чем дольше мы засиживаемся в области решения, тем меньше у нас остается ресурсов на область проблемы.
Можно представить ситуацию и так: всегда оставаясь в problem space, перебрать, взвесить и найти лучшее solution.
Есть отличная городская легенда, которую на митапах любят использовать как вступление к теме overengineering. Надо было разработать решение, чем писать в условиях космоса. И пока одна группа инженеров решала, как адаптировать шариковую ручку к условиям невесомости (шаги с разработкой чернил и поршня), вторая группа предложила использовать карандаш.
Чем дальше мы углубляемся в детали нашей реализации, тем дальше мы от самой проблемы. Поэтому на момент выбора решения нужно убедиться, что мы точно понимаем проблему и перебрали все возможные решения.
Неправильное направление: никто не счастлив в конце
Если изначально взялись решать не ту проблему или куда-то сильно отклонились в процессе решения, в результате не будет доволен никто. Бизнес не получит, что хотел, менеджмент будет считать убытки, а инженерам никто не скажет спасибо.
Не все проблемы — проблемы
Почему еще важно иметь решение «в точку» и самое быстрое? Потому что не все проблемы оказываются проблемами, и чем быстрее это станет ясно, тем выгодней. Мне нравится история, как аргентинская компания запускала свое приложение в Бразилии. Во многих ресторанах есть живая очередь, то есть ты приходишь, просишь столик на двоих и тебя просят 40 минут подождать. Компания решила сделать бронирование через приложение: тебе дается список ресторанов, ты выбираешь, какой, во сколько, и приходишь без очереди. Отличная идея. Аппку долго полировали, заключали контракты с ресторанами, и в итоге идея провалилась. Как выяснилось, для бразильцев стояние в очереди не было проблемой ¯\_(ツ)_/¯
Выполнение инструкций — это не решение проблем
Детально расписанные требования, иногда вплоть до if-else, редко приводят к хорошему результату. Следование таким инструкциям — это не решение проблем. Получается, что человек, которые такие требования просит/получает, не хочет/не может видеть, что же он решает на самом деле. Отсюда берутся и воркэраунды для corner cases, которые никогда в реальной жизни не произойдут, закладывается фундамент для потенциальных фичей, которых никогда не будет и оптимизируется то, что никто не оценит. В моей практике лучшие решения получались, когда максимально описывали контекст и то, что решаем. Тогда команда создает лучшее решение, потому что это как раз их компетенция.
Следующие шаги
Ну и после того, как мы правильно определили решаемую проблему, дело остается за решением и коммуникацией:
- Определите проблему и интересы всех сторон.
- Перечислите возможные решения.
- Оцените варианты.
- Выберите вариант.
- Задокументируйте соглашение о выбранном варианте.
- Договоритесь, как мониторить и оценить результат и что делать в случае непредвиденных обстоятельств.
В завершение
Тема решения проблем очень сложная, и затрагивает она далеко не только IT. Сегодня нет общего фреймворка и даже какого-то общего подхода из-за уникальности проблем, с которыми мы сталкиваемся. Я думаю, это та сфера, куда ИИ доберется в последнюю очередь, потому что в процессе анализа затрагивается слишком много ассоциативных связей. Но я знаю, что в нашей индустрии мы уже очень хорошо справляемся с решениями, и хотелось бы, чтобы мы стали лучше в определении того, зачем мы это делаем.