Текст книги "Карьера продакт-менеджера. Все что нужно знать для успешной работы в технологической компании"
Автор книги: Гэйл Лакман Макдауэлл
Жанр: Управление и подбор персонала, Бизнес-Книги
Возрастные ограничения: +16
сообщить о неприемлемом содержимом
Текущая страница: 10 (всего у книги 56 страниц) [доступный отрывок для чтения: 18 страниц]
УЗНАЙТЕ МНЕНИЕ РУКОВОДИТЕЛЯ И ИНЖЕНЕРОВ
Количество и тип технических навыков, которые востребованы и ценятся в работе, варьируются в зависимости от должности и компании.
Поэтому целесообразно проконсультироваться с руководителем и инженерами по поводу того, что, по их мнению, может быть полезным. Они скажут, нужно ли пройти курс по написанию кода и какой язык выбрать. Возможно, вместо кода они предложат вам всего лишь ознакомиться с конкретными технологиями, которые команда использует в работе, или вообще не акцентировать внимание на технических навыках и уделить время чему-то другому.
УЧИТЕСЬ ИНТУИТИВНО ОЦЕНИВАТЬ ЗАТРАТЫ
В начале карьеры вы будете осторожничать и стараться избегать оценки затрат на инженерные разработки. Инженеры очень обижаются, когда PM сам решает, что ту или иную задачу можно выполнить быстрее, поэтому лучше не предполагать, а спросить напрямую.
Как только вы завоюете доверие инженеров и выстроите с ними прочные взаимоотношения, вы получите массу преимуществ, научившись понимать затраты на инжиниринг и самостоятельно рассчитывать приблизительные сроки работ.
Прежде чем идти дальше, я еще раз хочу повторить:
Вы всегда можете приблизительно оценить сроки и использовать их для личных целей, но никогда не устанавливайте их как обязательные для своей команды. Для этого можно брать только те расчеты, которые предоставили инженеры.
Итак, что вы можете сделать со своими собственными прогнозами? Предлагаем несколько вариантов:
• Отфильтруйте все возможные решения, чтобы выявить, какие из них, скорее всего, будут затратными, а какие нет. Хорошо, если вы работаете в паре с дизайнером или другим участником проекта, потому что так вы можете быстрее отметить более дорогостоящие идеи и сразу предложить альтернативные варианты. Быстрая обратная связь может избавить от многих ненужных итераций. Если вам нравится такой подход, рекомендуем на более позднем этапе перепроверить стоимость первоначальной идеи с инженером, чтобы быть уверенным, что отказ от нее не был преждевременным.
• Выявляйте недоразумения или недостаток информации на ранней стадии. Если, по вашему мнению, на внесение какого-либо изменения нужно несколько часов, а инженер считает, что на это уйдет пара недель, значит, кто-то из вас знает то, что другому неизвестно. Возможно, вы знаете о готовом компоненте или предварительных расчетах, которые можно использовать повторно. Часто бывает, что PM обладает информацией, способной ускорить процесс технической разработки. Он приобретает ее с опытом работы в компании или приносит какие-то сведения из реализованных ранее проектов.
• Первое, что вы должны сделать, это расставить приоритеты (в более мелком масштабе) и проработать roadmap (в более крупном масштабе). Приоритизация и составление roadmap всегда связаны с соотношением расходов и получаемой выгоды. Поэтому чем лучше вы спрогнозируете затраты, тем точнее будет ваш первый черновой план. Показывая свой черновик инженерам, включите в него смету затрат с маленьким/средним/большим уровнем детализации (метод размеров футболок). Обязательно спросите у них, не ошиблись ли вы в какой-то оценке.
Как развить интуицию в отношении оценки затрат
• Прежде всего вы должны понять, как будет разбита работа над составными компонентами продукта, и затем сопоставить это с тем, сколько времени ушло на проработку подобных компонентов в прошлом. При этом сравнивать нужно проекты, реализованные в одной компании, потому что сроки могут сильно зависеть от таких вещей, как инфраструктура, принципы тестирования и график развертывания программ.
На стоимость обычно влияют два главных фактора:
• Какую часть продукта можно использовать повторно, а какую придется создавать с нуля. Представьте, что вы добавляете новую форму в диалоговое окно и хотите, чтобы в ней была возможность выбора даты и цвета. Если в вашем продукте подобные инструменты уже используются, то создание формы, скорее всего, обойдется вам недорого. В противном случае работа займет больше времени и будет стоить дороже.
• Производительность. Если какой-то компонент задействует в своей работе большой объем данных (например, подсчет миллионов записей), для его создания нельзя использовать дешевые и заурядные способы, иначе он будет работать очень медленно. Он даже может вызвать проблемы устойчивости продукта в целом. То же самое относится и к решениям, которые используют последовательный поиск по большому объему данных, например поиск задействованных в фильме актеров и всех фильмов, в которых они снимались. Существуют инженерные средства и методы, позволяющие создавать такие решения, но процесс занимает больше времени и обходится дороже.
Концепции и фреймворкиТЕХНИЧЕСКИЕ ТЕРМИНЫ И ПОНЯТИЯ
Нам вряд ли удастся научить вас всему, что вы должны знать о технологиях, но мы можем предложить вам небольшой экспресс-курс по этой теме. Понимание терминологии очень поможет вам в общении с инженерами.
API
API (Application Programming Interface) – интерфейс программирования приложений. Это эквивалент UI для взаимодействующих друг с другом компьютеров.
Существуют внутренние API, с помощью которых разные продукты и системы внутри компании «общаются» между собой, и внешние API, которые могут использоваться внешними разработчиками для подключения к вашему продукту или проектирования на его основе. Так же как пользователь ограничен UI (например, мобильная версия приложения не обладает той же функциональностью, что и веб-версия), компьютеры ограничены доступными API.
Компании с широким ассортиментом продуктов часто переходят к сервис-ориентированной архитектуре, когда компоненты и части инфраструктуры разделены на изолированные сервисы, которые взаимодействуют через API, а не являются взаимосвязанной частью остального кода.
Внедрение API-интерфейсов
Когда речь заходит об API, вы можете услышать слово CRUD, что означает создание, чтение, модификацию и удаление (Create, Read, Update, Delete) – четыре основные функции, используемые при работе с данными. Например, применение CRUD API в Twitter для твитов позволило бы создать новый твит, считать его текст (если вы знаете числовой идентификатор твита), отредактировать или удалить твит[52]52
Да, я знаю, что на самом деле вы не можете редактировать твиты. Это всего лишь пример.
[Закрыть]. Обычно именно CRUD API первым делом предоставляется с продуктом, а уже позже добавляются более специализированные API, например для закрепления твита в профиле.
Многие API-интерфейсы используют XML или JSON (нотация объектов JavaScript) для форматирования передаваемой информации. Оба языка имеют текстовый формат, легко анализируются и считываются компьютером. Когда кто-то упоминает объекты JSON или большой двоичный объект JSON (JSON Blob), имеется в виду фрагмент данных, которые были соответствующим образом отформатированы, чтобы их легче было читать и обмениваться ими.
Для аутентификации (authentication, auth) API обычно используют маркеры доступа (access tokens) вместо отправки имени пользователя и пароля при каждом запросе. Они как печати, которые вам ставят на руку в музее, после того как вы покажете входной билет.
Клиент (или фронтенд) и сервер (бэкенд)
Клиент – это часть продукта, запускаемая на устройстве пользователя, например мобильное приложение или веб-сайт, который вы видите при загрузке страницы. Сервер – это часть продукта, которая запускается на компьютерах компании или в облачных сервисах, таких как Amazon Web Services (AWS). Любые данные, к которым вы можете получить доступ с разных устройств, хранятся на сервере, а клиент получает только их временную копию.
На стороне клиента могут выполняться только мгновенные действия. А то, что требует полного цикла приема и обработки запросов от клиентов на сервере (round trip to the server) – клиент отправляет серверу сообщение о том, что он хочет, а сервер отвечает, – часто выполняется с заметной задержкой в четверть секунды или более.
Мобильные и веб-приложения
Клиентская часть мобильного приложения часто содержит много контента, поэтому на его загрузку уходит какое-то время, и пользователю периодически нужно это приложение обновлять. Загрузка изображений и особенно видео длится долго, а вот тексты грузятся достаточно быстро. После запуска приложения иногда можно увидеть медленно заполняющуюся полоску с надписью «Загрузка нового контента». Если вы используете приложение в авиарежиме, обращение к серверу не выполняется. После исправления бага в мобильном приложении его необходимо перезалить в магазин, чтобы пользователи могли скачать обновление.
В случае с веб-приложениями клиентский код загружается с сервера каждый раз, когда вы перезагружаете страницу. Именно поэтому обновлять веб-приложения не требуется. Любую пользовательскую проблему в веб-приложении можно устранить в течение нескольких минут.
Оптимизация
Нужно, чтобы все работало быстрее? Вот несколько общепринятых подходов:
• На сервере часто выполняются фоновые задачи или cron-задачи (отложенные). Задача в данном контексте – это независимая часть кода, которая выполняется отдельно от остальной части серверного кода, а не в качестве прямой реакции на запрос клиента. Cron-задача выполняется регулярно по заданному графику (например, каждые десять минут или каждую ночь) и может применяться, например, для ежедневной рассылки сводок по электронной почте. Выполнение задач в фоновом режиме – это, по сути, асинхронное выполнение каких-то медленных действий, ожидание которых было бы слишком долгим для пользователя. Фоновыми могут быть как задачи пользователя (например, создание большого экспортируемого файла), так и системы (например, когда распространение нового имени профиля внутри системы занимает несколько минут).
• Где-то в системе создается кэш или несколько кэшей. Одна из популярных систем кэширования называется memcache. Кэш ускоряет работу, сохраняя результаты дорогостоящих вычислений. Это здорово, но иногда кэши приводят к багам и могут быстро увеличить определенные серверные затраты.
• Отложенная загрузка – это шаблон проектирования, который откладывает дорогостоящие вычисления до тех пор, пока они не понадобятся. Представим, что ваш продукт существует уже несколько лет, и теперь вы решили удалить всю бранную лексику из пользовательского контента. Вместо того чтобы запускать фоновую задачу по обновлению всего содержимого (что может занять месяцы), вы можете сделать так, чтобы ругательства удалялись только тогда, когда кто-то будет пытаться просмотреть содержимое.
Дополнительно об оптимизации работы с базами данных читайте на с. 117.
Развертывание и разработка, тестирование, индексирование, бета-версии и рабочие серверы
Инженеры целый день заняты написанием кода, но он не отправляется пользователям сразу же после создания. Сперва его тестируют в нескольких изолированных средах разработки, чтобы убедиться в том, что он работает как задумано, правильно функционирует со всеми последними изменениями, которые могли внести другие инженеры, и использует реальные данные. Развертывание (deployment) – это подготовка нового кода к реальному использованию.
Инженеры начинают с локальной «песочницы», также называемой сервером разработки (development server) или dev, разворачиваемой на персональных компьютерах[53]53
«Песочницей» также называют изолированную среду, в которой пользователь может «поиграть» с продуктом и протестировать его.
[Закрыть]. Эта изолированная среда может серьезно отличаться от реальной (например, иметь только небольшое количество фиктивных данных), но помогает очень быстро понять, как работает код, и запустить итерации с ним. У каждого инженера есть своя собственная «песочница», так что все могут писать код одновременно. После набора текста кода инженеру, возможно, придется выполнить сборку кода или компилировать его, и это может занять определенное время в зависимости от используемого языка и архитектуры кодовой базы. Ускорение времени компиляции может существенно повлиять на скорость проектирования, поскольку позволяет разработчикам быстрее тестировать свой код.
Создание кода включает в себя также написание новых тестов, которые будут проверять, работает ли код, как ожидалось. Если команда использует разработку на основе тестирования (test-driven development, TDD), тогда каждый тест создают до написания соответствующего кода, так как тесты в данном случае служат своего рода условиями или критериями приемлемости. В большинстве остальных случаев основная цель написания новых тестов – не обнаружить ошибки, а помешать будущему коду случайно нарушить существующий код.
Управление кодом
Когда инженеры пишут код, они используют систему управления версиями, например git или github, чтобы фиксировать свои изменения и получать новый код, написанный другими разработчиками. Централизованная копия кода называется основной ветвью разработки (master branch).
У каждого инженера есть локальный репозиторий, или копия всего кода на локальном компьютере. Для того чтобы начать работу над новой функцией, создается так называемая функциональная ветвь. У каждой из них имеются свои изменения и собственная история версий. Разделение на ветви очень полезно – например, когда инженера просят исправить какой-то баг, в то время когда он занят созданием новой функции, он может просто перейти на новую ветвь, сохранив при этом всю проделанную работу на другой.
Коммит кода
В ходе работы инженер выполняет коммиты, то есть сохраняет изменения в системе управления версиями и обновляет историю версий. Как только все готово, он объединяет свою ветвь с основной веткой кода, создает запрос на включение изменений, или пул-реквест (pull request, PR), иначе называемый список изменений. PR подсвечивает все diffs, то есть изменения (добавленные, удаленные или измененные строки кода). Иногда в него полезно заглянуть, если вы умеете читать код, например чтобы узнать, какое имя присвоено тому или иному событию в журнале.
Теперь PR можно представлять для код-ревью, который заключается в том, что другой разработчик просматривает код на предмет программных или стилистических ошибок. Многие компании требуют проводить код-ревью перед его загрузкой. Если подобная практика в вашей команде пока не используется, советуем к ней присмотреться. Это хороший способ выявить баги, обеспечить применение хороших практик разработки ПО, обучить новых людей, а также помочь каждому участнику команды лучше разобраться в кодовой базе.
Как только запрос на включение изменений будет принят, все изменения в основной ветви, внесенные другими разработчиками, сливаются в локальную ветвь. То есть если все редактировали разные строки кода, в объединенный код автоматически будут добавлены все изменения. Если два человека попытаются отредактировать одну и ту же строку, это приведет к конфликту слияния (merge conflict) – и инженеру потребуется исправить проблему вручную.
Проверка кода перед развертыванием
На следующем этапе запрос на включение изменений пу́шится (передается, от англ. push) на тестовый сервер для проведения тестов. Все инженеры используют один тестовый сервер, поэтому в случае одновременной отправки кода тестирование может занять длительное время.
Тестовый сервер обычно выполняет модульные (unit tests) и интеграционные тесты (integration tests). Модульные тесты – это небольшие изолированные тесты, которые автоматически запускают все функции компонента и проверяют правильность полученных результатов. На самом деле смысл этих тестов заключается не в проверке правильности только что написанного кода; скорее, они нужны для того, чтобы убедиться, что чужие изменения не смогут нарушить ваш код. Интеграционные тесты масштабнее, они применяются к потокам и нужны для полной проверки срабатывания вариантов использования продукта.
Если компания применяет непрерывное развертывание (continuous deployment), после автоматического прохождения тестов код объединяется с общей основной ветвью и развертывается на следующем сервере. Это может быть рабочий сервер (production server, prod), используемый реальными клиентами, бета-сервер для внутренних сотрудников или небольшого процента клиентов либо промежуточный сервер (staging server). Последний представляет собой точную копию производственного и используется для выполнения нагрузочных тестов (load tests). У каждой компании есть свой набор правил, которые определяют, когда код готов для перехода на следующий сервер (например, через несколько часов или тогда, когда скажет разработчик).
Когда код завершен
Если из-за отправки кода останавливается компиляция основной ветви разработки, происходит прерывание сборки (breaking the build). Обычно это случается, когда инженер пропускает этапы тестирования в попытке сэкономить время. Никто не может отправлять новый код, до тех пор пока сборка не будет исправлена.
Запуск кода не всегда означает, что пользователи сразу же видят новую функциональность. Изменения или новые опции могут быть скрыты за флагом функции, который представляет собой параметр настройки (он включает или выключает ту или иную функцию). Флаги часто используют в рамках A/B-тестирования, когда в произвольном порядке у каждого пользователя та или иная функция включена или выключена. Код прописывает использование флагов просто: «Если флаг включен, запустить такой код; если флаг выключен, запустить другой код».
Иногда компании используют запрет изменения кода (code freeze). В этом случае автоматического развертывания кода на следующем сервере не происходит. Это делается, чтобы предотвратить появление багов в сложный период, например на время отсутствия большинства сотрудников из-за отпусков или во время крупного запуска продукции. В случае запрета изменений кода отдельные коммиты можно развернуть вручную (cherry-pick), например исправить какой-то отдельный баг.
Аналитика и ведение журнала событий
Современные приложения оснащены эффективными инструментами продуктовой аналитики и регистрируют, или журналируют (log), практически каждое действие пользователя.
Регистрируемые действия (например, открытие приложения, наведение курсора на кнопку поиска, клик по ней или по результату поиска) называются событиями. Они не регистрируются автоматически; для каждого действия инженеры должны прописать код или, другими словами, провести инструментирование.
При регистрации событий может быть зафиксировано большое количество различной информации, например имя и время события, идентификатор вызвавшего его пользователя, тип устройства, на котором оно произошло, и любые другие метаданные, анализ которых может понадобиться. Например, когда кто-то нажимает кнопку поиска, можно также зафиксировать число слов, введенных в поисковую строку.
После регистрации события должны пройти обработку, прежде чем вы сможете их просмотреть. Обычно она проводится ночью (с помощью cron-задачи), поэтому, придя на работу утром, вы можете просмотреть данные за предыдущий день. Просмотр необработанных журналов событий затрагивает вопросы конфиденциальности, поэтому обычно для просмотра данные предоставляются обезличенными и в агрегированном формате.
SQL и базы данных
Базы данных (БД) – это системы хранения данных, похожие на сложные многоуровневые электронные таблицы[54]54
Вы также можете услышать термин «хранилище данных». Это более широкий термин, относящийся к любой системе хранения данных. Хранилище данных может представлять собой файловое хранилище или другую систему хранения информации, не связанную с базами данных. База данных – это один из видов хранилища.
[Закрыть]. Существует несколько типов баз данных, предназначенных для разных целей.
Вероятно, ваш продукт будет использовать БД общего назначения, например MySQL, Postgres или MongoDB, для хранения таких данных, как информация о пользователе и пользовательский контент.
Для журналов событий и бизнес-аналитики ваша компания также может использовать специальное хранилище данных (data warehouse), например Redshift. Журналы перемещаются в хранилище данных с помощью процесса, называемого ETL (Extract, Transform, Load – извлечение, преобразование, загрузка).
Если в продукте имеется функция поиска, можно также использовать ElasticSearch.
SQL
SQL – сокращение от Structured Query Language (язык структурированных запросов). Это язык программирования, используемый для добавления, редактирования и извлечения данных из большинства БД. Как пользователь, вы можете применять SQL для прямого взаимодействия с базами данных, но, как правило, только с базами данных журналов, но не с рабочими базами. Для работы с последними код сервера генерирует SQL-запрос и отправляет его в базу.
В целом с кодом SQL работать намного быстрее, чем с серверным кодом, однако SQL умеет далеко не все.
Оптимизация баз данных
Чтобы избежать дублирования, информация в базе данных обычно разбита на несколько таблиц, и для просмотра нужных сведений она должна быть повторно обработана. Например, в базе, хранящей публикации и комментарии к ним, одна таблица может содержать комментарии с кодом родительского сообщения, в то время как в другой хранятся фактические публикации. Чтобы показать, сколько комментариев было добавлено к публикации 1234, программе потребуется выполнить довольно медленную операцию подсчета всех комментариев, привязанных к сообщению 1234.
Для ускорения процесса можно использовать денормализованную копию таблицы предварительно рассчитанного количества комментариев к каждой публикации и попытаться синхронизировать ее с реальным подсчетом. Денормализация повышает скорость чтения (время, необходимое для просмотра данных) за счет более низкой скорости записи (времени на добавление или обновление данных). Этот способ достаточно популярен, хотя и может привести к появлению багов и увеличению времени разработки.
Алгоритмы и структуры данных
Хеш-таблица, или хеш-карта, – это широко используемый метод кодирования (структура данных), который позволяет очень быстро сопоставить ключ (любое уникальное число, слово или фразу) со значением. Инженеры знают всевозможные хитроумные способы использования хеш-таблиц для решения проблем. Например, на ваш вопрос, не будет ли ваше решение слишком медленным, инженер может ответить: «Никаких проблем. Я могу использовать хеш-таблицу». Однако не стоит самому предлагать такой вариант, если вы не знаете, что он означает, – это прозвучит глупо.
Время выполнения, или нотация «О-большое», – это описание эффективности алгоритма (по отношению к объему данных). Оно не дает точного времени; это, скорее, математическая функция, описывающая, насколько медленнее становится алгоритм при увеличении объема данных. Например, если удвоить количество контактов в адресной книге, будет ли алгоритм фильтрации работать с той же скоростью? Или он займет в два раза больше времени? Или еще больше? Наиболее распространенными считаются следующие варианты[55]55
Мы дали несколько упрощенное описание. Представьте себе алгоритм, выполнение которого на n фрагментах данных занимает (100 + n) секунд. С пятью фрагментами алгоритм занимает 105 секунд. На десяти – 110 секунд. Мы видим, что время не удвоилось, несмотря на то что размер данных увеличился вдвое. Однако наклон функции является линейным. При значительном увеличении n удвоение данных может практически удвоить и время.
[Закрыть]:
• O(1) (постоянное время): скорость выполнения алгоритма в целом остается неизменной независимо от количества данных.
• O(log n) (логарифмическое время): выполнение алгоритма замедляется по мере увеличения объема данных, но даже их удвоение мало что меняет. Например, десятикратное увеличение набора данных может удвоить время выполнения алгоритма.
• O(n) (линейное время): скорость выполнения алгоритма увеличивается пропорционально размеру набора данных. Таким образом, если набор данных увеличится в 10 раз, время выполнения алгоритма также может увеличиться в 10 раз.
• O(n log n) (линейно-логарифмическое время): алгоритм такой сложности немного хуже линейного. Увеличение набора данных в 10 раз может, например, повысить время выполнения алгоритма в 11 раз. Это допустимо для решения практических задач и обычно совпадает с реальным временем сортировки данных.
• O(n^2) (квадратичное время): алгоритм такой сложности значительно хуже линейного. Если набор данных возрастет в 10 раз, время выполнения алгоритма может увеличиться в 100 раз. Обычно такой алгоритм применяется, только если заранее известно, что ПО будет работать с небольшим объемом данных.
• O(2^n) (экспоненциальное время): кошмар. Алгоритм такой сложности гораздо хуже линейного; возрастание объема данных в 10 раз может привести к увеличению времени выполнения в 1000 раз. А увеличение в 20 раз означает повышение скорости алгоритма в 1 000 000 раз. Видите проблему? Подобный алгоритм крайне редко используется в расчетном ПО. Он слишком медленный.
O(n) быстрее, чем O(n^2)? Трудно сказать. Если объем данных невелик, то, возможно, и нет. Но если он значительно увеличивается, то определенно да. При этом один алгоритм O(n) может быть намного быстрее другого алгоритма O(n). Математикам это вряд ли понравится, но вы можете представлять нотацию «О-большое» как упрощенное объяснение того, как медленно будет выполняться алгоритм при больших объемах данных. Алгоритмы O(1) и O(log N) считаются лучшими, O(n) и O(n log n) – обычно приемлемы. O(n^2) или более медленные, как правило, непригодны. Но все зависит от того, какую задачу вы решаете![56]56
Обратите внимание на слово «обычно». Как думаете, вас устроит потратить на поиск нужного контакта O(log N) времени? Если вы будете искать нужного вам человека в списке контактов телефона за O(log N) времени [где N – число ваших контактов], скорее всего, все будет нормально. Но если поиск будет вестись по всему интернету [здесь N равно количеству страниц в интернете], вам придется ждать долго.
[Закрыть]
На графике видно, что для небольшого объема данных время практически одинаково. Но когда данных действительно много, скорость выполнения алгоритма становится очень, очень медленной.
Еще несколько терминов
• Поскольку клиенты и серверы могут находиться в любой точке мира, из-за разницы часовых поясов может возникнуть путаница во времени и датах. Чтобы этого не было, в коде, в том числе для расчетов, обычно используется время в формате UTC (Coordinated Universal Time – всемирное координированное время), которое переводится в местное для отображения пользователю. Время UTC почти совпадает со средним временем по Гринвичу (GMT, часовой пояс Лондона, Англия), но не учитывает переход на летнее время.
• Swag расшифровывается как Scientific Wild-Ass Guess – «метод научного тыка» – и используется для описания оценки затрат. Это слово передает, что оценка не точная, а предположительная. Используя этот метод при составлении графиков, стоит умножать свои оценки на два или даже на четыре, чтобы учесть неточность подсчетов и затраты на выполнение ежедневной рутины, например код-ревью или написание тестов.
• UUID или GUID означает универсальный уникальный ID (Universally Unique Identifier) или глобальный уникальный ID (Globally Unique Identifier). Это очень длинные, случайно сгенерированные строки (например, «712f58d0-0208-4fc4-b80f-fc4e960bfac2»), которые обычно используются в качестве ID объекта в базе данных. Они удобны, поскольку могут считаться уникальными и не требуют фактической проверки того, использовался этот ID раньше или нет. (Почему проверять не нужно? Потому что такой случай крайне маловероятен.)
• Технический долг. Это понятие используется для обозначения багов, которые появляются из-за пренебрежительного выполнения текущих задач и приводят к увеличению временных затрат или необходимости дополнительной разработки в будущем. Когда вы берете взаймы деньги – влезаете в финансовые долги, – вы получаете возможность купить что-то сейчас, но вы должны вернуть то, что вы потратите (с процентами!) в будущем. Технический долг работает так же: вы можете произвести запуск продукта сегодня, но позднее вам придется за это заплатить. Как и в случае с денежным долгом, технический долг возникает в определенных ситуациях. И чтобы с ним не сталкиваться, нужно действовать осторожно.
ЧТО ОЗНАЧАЕТ ФРАЗА «ЭТО СЛИШКОМ СЛОЖНО»?
На разных этапах карьеры вы можете услышать от разработчика, что реализовать вашу идею слишком сложно. Не заканчивайте разговор на этом. Постарайтесь докопаться, что он имеет в виду на самом деле. Спросите, почему он так думает и что конкретно делает вашу идею невыполнимой.
Существует три распространенных ответа: высокие затраты, низкая производительность/масштабируемость и увеличение технического долга.
Разработка будет слишком затратной
Говоря «сложно», инженеры часто имеют в виду, что разработка займет слишком много времени.
• Например, у разработчиков есть готовый компонент, но он не поддерживает нужную вам функциональность, и им придется создавать новый компонент с нуля, чтобы внедрить вашу идею.
• Возможно, вы недооцениваете объем работ, необходимый для воплощения вашей идеи.
• Это может означать, что инженерам придется затронуть часть кода, с которой они незнакомы, и для выхода на рабочий темп уйдет дополнительное время.
• Возможно, потребуется миграция данных, которая займет недели.
Как только вы разберетесь, какие действия особенно затратны, вы сможете найти более выгодные альтернативы. Можно использовать компонент с несколько отличающимся, но приемлемым функционалом. Или исключить какие-то элементы из своего решения. Возможно, вы найдете разработчика, знакомого с кодовой базой, который согласится помочь. Или вы решите, что без миграции данных можно обойтись.
Еще один полезный в подобных ситуациях вопрос звучит так: «Как долго, по вашему мнению, это займет?» Если работа важная, вы можете принять решение потратить на нее дополнительное время или попросить других инженеров из вашей команды подключиться к этой задаче.
Производительность будет низкой, а масштабируемость решения слишком слабой
Иногда «сложно» означает, что для создания функции требуются длительные расчеты или значительные компьютерные ресурсы. Например, у вас есть список из миллионов элементов, и вы хотите подсчитать их подмножество. Или в вашем списке несколько тысяч позиций, которые нужно сравнить между собой.
Существует несколько способов решения вопросов производительности:
• Установите ограничения. Например, можно показывать значение «99+», если количество элементов превышает 99.
• Измените продукт так чтобы за один раз требовалось производить меньше расчетов. Например, проводить сравнение только с одной позицией в списке.
• Потратьте больше времени на разработку системы, которая быстрее выдает результаты. Например, вы можете денормализовать (с. 117) или кешировать (с. 113) информацию либо произвести предварительные вычисления.
Производительность очень важна, поэтому, если вы не сможете найти альтернативное решение, вам придется отказаться от медленной функции.
Это приведет к возникновению технического долга, из-за которого реализация будущих проектов займет больше времени
Бывает, что под словом «сложно» имеется в виду, что решение окажется трудоемким, нестабильным или ненадежным. Например, это может означать отказ от стандартных компонентов, внедрение новых серверных систем или возникновение граничного случая (corner case), который необходимо запомнить на будущее.
Действовать в условиях технического долга затруднительно. Он усложняет работу вашего инженера и замедляет дальнейшую разработку. Спор на эту тему не имеет смысла и вряд ли найдет у кого-то положительный отклик. Поэтому важно не просто узнать, что может увеличить долг, а разобраться в сути ответа, чтобы суметь сформулировать возможные альтернативы.
Как и прежде, вы можете спросить у инженеров, могут ли они разработать альтернативное решение, которое не повлечет за собой увеличение долга. Если они разбираются в предметной области, они смогут придумать что-то выдающееся.
Правообладателям!
Данное произведение размещено по согласованию с ООО "ЛитРес" (20% исходного текста). Если размещение книги нарушает чьи-либо права, то сообщите об этом.Читателям!
Оплатили, но не знаете что делать дальше?