dev talks
January 7, 2021

dev talks #1

Сегодня мы поговорим о том, как устроена мобильная разработка крупных российских продуктов. У нас в гостях тимлид iOS команды разработки Cardsmobile – Богдан Маншилин.

Да, все верно, тимлид iOS разработки в Cardsmobile, мы разрабатываем приложение "Кошелёк".

Давай для начала попробуем разобраться с понятийным аппаратом. Что ты считаешь крупным продуктом, и что – российским?

Хороший вопрос. Я считаю крупным продуктом такой продукт, которым пользуется хотя бы 1.000.000 человек в месяц.

Объясни, почему именно миллион человек в месяц?

Потому что, как мне кажется, эта метрика максимально влияет и на те задачи, которые стоят перед разработчиком, и на те уровни проблем, на которые мы обращаем внимание. Мы можем не обращать внимания на какие-то мелкие баги/крэши в маленьких приложениях, которыми пользуется мало людей. Но если это, допустим, 1% от 1.000.000 пользователей, то это уже большая сумма.

А что по поводу российских продуктов?

Я считаю российскими те продукты, которые были сделаны в России. На примерах, из моего опыта разработки, крупные российские компании это:

  • Ultimate Guitar, компания, базирующаяся в Калининграде, то есть полностью вся разработка в Калининграде и head офис в Калининграде, однако продукт в первую очередь используется в США;
  • Lamoda и Яндекс.Еда, максимально российские продукты, как по тому, кто их использует, так и по разработчикам;
  • Cardsmobile – там, где я сейчас работаю, мы разрабатываем приложение, которое используется в России. Хотя мы сейчас нацелены на Европу, однако когда мы туда выйдем, мы все равно останемся российским продуктом.

Хорошо, вот те приложения, которые ты назвал. Ты над ними работал?

Да, все верно. Работал конечно на разных позициях. В Ultimate Guitar я начинал работать как джуниор-разработчик, и там уже дорос до нормального разработчика. На самом деле сложно говорить о грейдах в Ultimate Guitar, поскольку их там просто не было. По крайней мере на тот момент компания шла по пути "холакратии", то есть не было никаких лычек "мидл", "сеньор" или еще кто-то. Вся структура была максимально плоской, за исключением того, что был один руководитель. По своим личным ощущениям, за время работы в Ultimate Guitar я стал хорошим таким мидлом.

Дальше была Яндекс.Еда, куда я пришел на позицию старшего разработчика, но в какой-то момент я перестал работать над проектом и стал лидом, таким образом перестал писать код вообще. В Ламоде я тоже был немного разработчиком, немного лидом. Сейчас я в принципе не разрабатываю вообще, поскольку мне не хватает времени для того, чтобы писать код. Я руковожу отделом iOS разработки, он у нас довольно большой (сейчас это 10 человек), и мы планируем расти ещё больше.

Расскажи, почему покинул Яндекс.Еду и перешел в Ламоду?

Наверное, отчасти из-за карьерного роста. Хотя, если признаться честно, я пошел за своим руководителем. У нас был руководитель мобильной разработки в Яндекс.Еде, он из Ламоды и по своим причинам вернулся обратно. Какое-то время я пытался развиваться внутри Яндекс.Еды, у меня не получилось. Я не смог понять, какие же у меня там направления развития: бывало так, что я приходил на работу и не знал, чем мне заниматься, и в общем-то от такого отсутствия чётко поставленной цели я уже потянулся за своим прошлым руководителем, с которым мне нравилось работать.

Делал приложение под кофейни, где ставят печати на карточку. Как стартапер я прогорел.

Так, а как ты в Cardsmobile тогда оказался?

О, это очень интересная история. Параллельно с работой я разрабатывал еще и пет-проекты, одним из таких проектов было приложение "кофри". Идея была такая: я очень хотел сделать приложение, которое полностью бы заменило кошелек, то есть все дисконтные карты перенесло бы из моего кармана в это приложение. Я начал его разрабатывать, но в какой-то момент понял, что это приложение уже существует (это и есть приложение "Кошелек").

Я решил не отказываться от идеи, а сделал приложение исключительно под кофейни, наверное, знаешь такое, где печать ставят на карточку. В Кошельке такого не было, и я подумал: отлично, вот открытая ниша, пойду туда. Как стартапер-бизнесмен я прогорел, хотя у нас был готовый продукт, мы достаточно быстро его запилили и работал он хорошо. Однако продать мы его никому не смогли, и я сильно от этого фрустрировал, потому что очень хотелось сделать хороший продукт, но, к сожалению, не получилось.

То самое приложение с кофейнями

В какой-то момент я увидел на своей почте письмо от HR из Кошелька. О Кошельке я, естественно, уже давно знал, как о своём личном конкуренте. На тот момент я не рассматривал предложения о работе, меня всё устраивало в Ламоде. Но с ребятами я решил пообщаться и узнать, как у них в принципе идёт бизнес. Бизнес у них шел очень интересно: они выходили на европейские рынки, имели стратегического партнера в лице huawei, происходил рост в команде до десятков человек. Собственно, очень большие перспективы, каких не было в Ламоде. Я обсудил это со своим руководителем и понял, что интереснее было бы развиваться вместе с Кошельком.

Расскажи, на чём были написаны все те приложения, с которыми ты работал. Нативная разработка или кросс-платформа? Swift или Objective-C? React-Native или Flutter?

Всего по чуть-чуть. Я всегда был нативным разработчиком и всегда писал либо на Swift, либо на Obj-C. Первое приложение (Ultimate Guitar) было нативным, однако, когда я уходил, стратегия немного поменялась. Кстати, это, наверное, было одной из причин моего ухода – приложения стали кроссплатформенными. И я каюсь, на самом деле я приложил к этому руку. Первый прототип приложения Ultimate Guitar на React-Native разрабатывал я с ещё одним фронтенд-разработчиком, который хорошо разбирался в реакте. Это приложение очень сильно понравилось менеджерам AppStore из раздела Музыка, и в Ultimate Guitar решили разрабатывать всё на React-Native.

Это был долгий путь, к тому моменту я уже ушёл из компании, ребята набрали команду под реакт, переписали всё приложение, и у них получилось. Было много связанных с этим проблем, но они их решили. Теперь у них приложение полностью на React-Native, но кроме одной части. По сути, Ultimate Guitar – это приложение, которое отображает гитарные табулатуры, аккорды, вот это все. И экран с отображением этих табулатур довольно сложный, на React-Native всё это работало очень медленно. Поэтому ребята решили, что эту часть они напишут... нет, не нативно, а на Qt (Qt – это кроссплатформенная библиотека, написанная на С++).

А что с Ламодой и Яндекс.Едой? Они используют кроссплатформу или что-то нативное?

Оба приложения сейчас нативные. В Ламоде поговаривали о Flutter, но, к счастью, дальше разговоров дело не зашло. Как ты понял, я не большой сторонник кроссплатформенных решений. В Еде, насколько я знаю, какая-то часть (вроде бы Яндекс.Лавка) не нативная, по-моему, она на Flutter, но гарантировать я этого не могу, потому что именно эту часть делали уже после моего ухода.

Видишь ли ты какие-то преимущества нативной разработки над кроссплатформой или наоборот?

В первую очередь это, конечно, UX. Несмотря на то, что какие-то вещи в React-Native или Flutter пытаются сделать нативными (тот же React-Native берет нативные вьюхи и их отрисовывает, но сначала он создает виртуальный интерфейс, поверх которого уже рисуется нативный), у них есть проблемы с реюзабельными коллекциями (TableView), их там не было. То есть все отображённые ячейки висели в памяти приложения, из-за чего оно могло подлагивать.

Если говорить о Flutter, то, по сути, это технология, которая говорит, что мы самостоятельно перерисовываем весь интерфейс, то есть у нас свой UIKit, который похож на то, как это выглядит нативно. Однако тут мы понимаем, что, если у нас есть какой-то UIKit, который копирует нативное решение, то он копирует либо android либо iOS. То есть есть какая-то общая, базовая часть элементов, но всё таки есть UIKit например называется кажется купертино и обычный, и это два разных кита. И если ты хочешь разработать приложение, которое на iOS не выглядит, как приложение от Гугла, а хочешь, чтобы оно выглядело нативно, то так или иначе тебе всё равно придется пилить два разных интерфейса.

Однако преимуществ от этого я больших не вижу, поскольку проблемы продолжаются и дальше. Кроме всяких нативных вьюх (которые, по сути, не являются нативными, а только на них отчасти похожи), есть ещё и такие штуки, которые не напишешь на кроссплатформе. Например, виджеты. Сейчас они на SwiftUI. На Flutter их попросту нет. Когда я писал на React-Native, была проблема с отсутствием плагина для force touch. Сейчас, конечно, force touch уже нет, но тогда пришлось самому писать этот плагин, чтобы полностью воспроизвести ту функциональность, которая уже была в приложении. Да и в принципе, даже если кроссплатформа рано или поздно начинает поддерживать новые возможности платформы, она всё равно находится в отстающей позиции. Выходит новая фича на iOS или android, и в кроссплатформе её ещё нет. А если мы хотим всё сделать быстро, ввести эту новую фичу, и чтобы нас зафичерили в AppStore, то кроссплатформа попросту не позволит этого сделать.

Что можешь сказать по поводу скорости разработки?

Это очень тонкий вопрос, мне будет сложно на него ответить однозначно, потому что я больше разрабатывал нативно и только чуть чуть пробовал кроссплатформу в Ultimate Guitar. Но должен сказать, что быстрее у меня разрабатывать на React-Native не вышло... Были какие-то вещи, которые нужно было подпиливать под android. Хотя мы делали приложение только под iOS, мы понимали, что, если будем сейчас делать и под android, то нужно бы сделать ещё вот это, вот это и вот это, дофига всего. И собственно пришлось бы делать второй интерфейс. Это первое. А второе – время от времени ты затыкаешься на том моменте, что кроссплатформа этого не поддерживает. Я частенько вижу реквесты на Flutter или React-Native, что такой-то фреймворк там не прокинут и не поддерживается до кроссплатформенного sdk, то есть нужно написать плагин, или еще что-то сделать. В общем-то, честно я не могу привести какие то метрики. По ощущениям, сильно быстрее не будет. Конечно, если мы хотим соответствовать качеству нативного приложения.

Если мы можем подзабить на качество и где-то недокрутить тот же force touch (которого уже нет), ну или виджеты, или забить на то, что где-то вьюшка некрасиво скачет, вот, например, я смотрю сейчас с точки зрения пользователя на Яндекс.Лавку и она выглядит как будто веб-вьюха, вот если мы к этому готовы, тогда на Flutter будет быстрее. Если мы хотим сделать максимально плавно, нативно и красиво, то может оказаться, что кроссплатформенно разрабатывать будет даже дольше.

То есть большие компании всё-таки выбирают именно нативный путь?

Ну, не совсем. Вот та же Яндекс.Лавка – это Flutter. Хотя тоже большая компания. Наверное, тут дело не в том, большая это компания или маленькая, а в том, в каких компаниях или проектах важен UX, а где им можно пренебречь. Яндекс.Лавка считается экспериментальным проектом, и там ребята экспериментируют с Flutter и что с этим получится. Будем ждать статью от Яндекса, где они перешли с Flutter обратно на натив, как в своё время AirBnb перешли с React-Native на нативную разработку.

Вечный хакатон vs скрамбан

Расскажи о том, какие команды работают над всеми этими продуктами? Большие или маленькие? Как устроена структура этих команд и каких процессов они придерживаются?

Довольно обширный вопрос, давай по каждой команде пройдёмся отдельно. Давай возьмем Ultimate Guitar, но я буду говорить о ней образца 2015-2016 года, когда я там работал, поскольку Ultimate Guitar всегда изменяется. Тогда это была команда из 50-60 человек (вообще всех сотрудников), и это была полная холакратия, то есть не было вообще руководителей (кроме одного), и не было процессов. Процесс назывался "вечный хакатон". Когда ты приходишь на какой-нибудь курс по процессам, тебе говорят, что процесс – это на самом деле препятствие.

Что мы делаем: у нас есть какая-то задача, мы отдаем ее разработчику, разработчик её делает, не отвлекаясь ни на что, в итоге отдает результат. А все эти ваши скрамы, код ревью, тестирование, это всё разработку замедляет. Идеальный разработчик пишет такой код, который не нуждается ни в код ревью, ни в тестировании, а сразу готов к продакшену. Ultimate Guitar конкретно в то время придерживался именно этого подхода. Никаких лишних процессов не было. Не было ни код ревью, ни тестирования, ни скрамов. К тебе просто приходит какой-нибудь заказчик, то есть, по сути, даже не заказчик, поскольку там заказчиками всех фичей были сами разработчики.

Процесс был построен таким образом, что когда ты попадаешь в эту команду, твоя задача не только разрабатывать или рисовать дизайны, твоя задача предлагать идеи, питчить их. Ну и, образно говоря, каждый вторник, ну или раз в две недели, сотрудники компании приходили и рассказывали свои идеи. Фаундер смотрит и говорит: это фигня, а это звучит интересно, давайте сделаем. Таким образом, человек, который предложил идею, становится её заказчиком. Он берет эту идею и доводит её до продакшена. Никакого процесса тут нет, он сам находит ресурсы, обращается к разработчикам, сам её планирует. Как на хакатоне, ты придумал идею, собрал несколько человек. Сели и запилили за две ночи, примерно вот так. Очень интересно, но со своими минусами. Человек, который запитчил, должен довести всё до конца сам. Если он не самостоятельный, значит, проект сделан не будет.

Более классические примеры процессов были в Яндекс.Еде и Ламоде, они были довольно похожие. В Яндекс.Еде iOS разработчиков было примерно 5 штук, а всего в команде – более 100 человек (на всю Яндекс.Еду). Работали мы по методологии скрам, хотя я бы, наверное, назвал это скрамбан.

Scrumban – это методология, включающая в себя элементы scrum и kanban, однако Богдан называет скрамбаном любую химеру, которую придумывают менеджеры в попытке вобрать лучшее из канбана и скрама.

Это был недетерминированный процесс. В конечном итоге за основу мы взяли все-таки канбан. У нас была бесконечная борда, где в первой колонке находятся задачи в виде такого бесконечного списка.

Пример скрамбановской борды

Мы туда вкидывали эти задачи, и они там каким-то образом оценивались. В конечном итоге мы пришли к выводу, что лучше всего для этого подходит грумминг. Но на первых порах это могло быть по-разному, например кто-то из разработчиков, или тимлид самостоятельно оценивал задачу. Мы, собственно, вкидывали всё это в первую колонку, и дальше продакт платформы приоритизировал задачи. Банально он просто кидал задачу в самый верх колонки. Разработчик, заканчивая заниматься своей задачей, смотрит, что лежит в самом верху ToDo, и забирает задачу. Такой простой процесс.

Были уже и код ревью нормальные, и QA, причём мы работали по git flow. То есть, когда мы берем какую-то фичу, мы уходим в свою ветку. Пока работаем с фичой, находимся в этой ветке, здесь же был и код ревью, и происходило тестирование. Только потом заливаем это все уже в develop (название ветки). Еще у нас были спринты, ориентированные на проекты. То есть, они были регулярные – раз в 2 недели – но с упором на законченные задачи.

Обычное ретро, привязанное к спринтам, как происходит? Закрываем спринт, садимся все вместе и говорим, что в спринте было хорошо, а что плохо. В Яндекс.Еде, что интересно, мы поступали не так. Мы брали все задачи, которые к этому моменту успевали завершить (которые уже уехали в релиз), и проходились по ним. Эта задача проехала хорошо, есть по ней комментарии? Если комментариев нет, значит все окей, прилепили стикер на физическую доску и сказали что по ней комментариев нет. Если по задаче есть комментарии (не обязательно плохие), то их обсуждаем, записываем. В идеале, выписываем какие-либо поинты и тд. Это такой, в общем, процесс у нас был в Яндекс.Еде.

В Ламоде были спринты (то есть не было канбана), эти спринты мы планировали и в дальнейшем оценивали в сторипоинтах, в Еде это было в часах. То есть это был обычный скрам, без всяких интересностей. Всё как по книге. То есть, у нас есть грумминги, планинги, ретро. И все это более-менее работает. Всегда пытались посчитать велосити нашего спринта, чтобы его уметь планировать. Но это обычно не удавалось, и каждый раз мы чуть-чуть выезжали. Сложно было с планированием спринтов, хотя в целом всё работало хорошо. Больших отличий от Еды нет, кроме того, что появились спринты.

В команде на разных этапах было 7-9 человек, и она была разделена на две части. То есть было две команды по двум продуктовым направлениям. Одни занимаются конвершеном, вторые ретеншеном. Условно это два бизнесовых направления, у каждого есть продакт, за продактом закреплены разработчики (то есть те ресурсы, которые есть у продакта). Таким образом, проект был один, но задачи разные. Работали все в рамках одного проекта. Не было никаких зон ответственности, все отвечали за один проект. Где-то в момент моего ухода из Ламоды эту команду слили обратно в одну.

Нам нужно выйти на европейские рынки. Сделайте с этим что-нибудь.

Что можешь сказать по поводу разработки в Cardsmobile? Это было ближе к хакатонам или к традиционным процессам, таким как скрам, спринты?

По поводу разработки в Cardsmobile. Команд у нас много, в отличие от той же Ламоды, в которой было несколько команд по направлениям. У нас сейчас тоже есть команды по направлениям, как гораздо большие, так и гораздо меньшие (чем в Ламода). У каждой команды есть своя зона ответственности. В каждой из команд есть свои процессы. В общем, конечно, у нас скрам. Допустим, кор команда оценивает задачи в часах, другая команда может оценивать в том, в чём ей нравится, например, в сторипоинтах. Это, собственно, не совсем обычный скрам. Пока что я могу рассказать только про кор команду, потому что в кор команде я являюсь, условно говоря, заказчиком. То есть, у нас нет продакта, как такового, нам прилетают задачи на уровне "нам нужно выйти на европейские рынки, сделайте с этим что-нибудь". Мы уже тут сидим и придумываем, что же можно сделать, чтобы туда выйти. В связи с этим и процессы строим как нам удобно. Процессы выглядят таким образом: у нас есть спринты, оцениваемся мы в часах. Я, если честно, не вижу разницы между часами и сторипоинтами, даже когда мы оцениваем в часах, я считаю, что это какая-то относительная единица работы. Потому что даже если мы оценили задачу в 4 либо 40 часов, это совершенно не означает, что мы будем её делать 4 или 40 часов. Это просто-напросто подтверждается практикой.

Все равно наша велосити, в чем бы мы её не считали, в часах или поинтах, это статистически погрешная величина.

У нас пока нет ретро. Но, возможно, оно будет. Каким оно будет, проектным или ориентированным на спринты, пока непонятно. Мы хотим не просто ввести ретро, потому что, мол, так в скраме написано, а понять, какую цель он решает, чтобы максимально правильным способом его проводить. А возможно, он и не нужен нам вовсе. Как самые яркие тимлиды на конференции Подлодка рассказывали, что ретро не нужны. Конечно, это очень смелый подход, но заставляет задуматься, для чего же они всё-таки нужны.

У нас есть грумминги. Опять-таки, все эти процессы сейчас скорее находятся на этапе построения во всех наших командах. Говорить о том, как сейчас, наверное, нет большого смысла, потому что через месяц всё будет по-другому. Это единственное, что я могу гарантировать. Я лично над этим работаю.


Послесловие

У Cardsmobile, кстати, есть канал. Подписывайтесь, там много всего интересного! А также, в будущем, будет и вторая часть статьи, где мы обсудим, как попасть в крупную техническую компанию, какие у этих компаний проблемы и многое другое.


Статья подготовлена для канала Hello World.