October 16, 2019

Интервью с разработчиками. Студия Surf

Сегодня хочу представить вам не одного разработчика, а сразу нескольких.

Это Android-разработчики из команды Surf:

Евгений Сатуров — Android Teamlead;

Максим Туев — руководитель Android отдела.

Расскажите немного о компании

Расскажите немного о компании: чем занимается компания? Сколько людей работает в ней?

Макс:

Surf существует уже 8 лет. Основное направление деятельности — разработка мобильных приложений для крупных российских клиентов. Есть также ML и Backend направления. Большая часть мобильной разработки — нативная, недавно начали разрабатывать приложения на Flutter и будем дальше развивать это направление. В компании больше 100 человек, основной офис в Воронеже, около 40% сотрудников работают удаленно.

Расскажите в двух словах: кто вы? Чем занимаетесь в команде? Сколько лет работаете в компании?

Макс:

В Surf я выполняю роль Технического директора. Основную часть времени трачу на руководство Android отделом. В компании я 5 лет, начинал свою карьеру здесь со стажера. На тот момент в Surf было в 4 раза меньше сотрудников и было интересно наблюдать за ее развитием и, особенно, прикладывать к этому и свою руку.

Женя:

Сегодня я технический евангелист в компании, помогаю внедрять новейшие подходы и технологии, рассказываю об этом нашим клиентам, сообществу и соискателям. Кроме того руковожу командой разработки Android и Flutter приложений. За спиной 4,5 года в Android.

Какой у вас опыт разработки? Почему разработка Android?

Макс:

Я в программировании больше 5 лет. Android выбрал из-за любви к Java и перспективности этого направления.

Женя:

Перепробовав, будучи студентом, пожалуй, все возможные направления я пришёл в мобильную разработку и… уже не смог никуда уйти. Я люблю красивые, функциональные вещи и программирование. Мобильные приложения — как раз про это. Именно в этой сфере я смог сделать свой вклад в создание продуктов, которые действительно нужны людям.

В написании каких приложений вы поучаствовали?

Макс:

Участвовал в более чем 10 проектах. Среди которых Литрес Слушай, Лабиринт, Спрашивай.ру, PSB и др.

Женя

Аналогично, более 10 проектов. В некоторых приходилось фиксить баги и разбираться в чужой “легаси” архитектуре, последние годы — это серьёзные долгосрочные проекты, поднимаемые нашей командой с нуля. Особенно, горжусь Лабиринтом, над которым я проработал дольше всего. И ещё двумя проектами, про которые нельзя говорить. NDA :(

Поговорим про разработку

Какая у вас архитектура? Каких паттернов придерживаетесь при разработке?

Макс:

Пожалуй, здесь ничего глобально специфичного: основной стек у нас сейчас CleanArchitecture + MVVM. Но дьявол как всегда кроется в деталях, все базовые классы мы пишем сами и у нас местами для распространенных задач не самые типичные решения, например, навигация, пагинация и др. Вообще мы подходим к своим решениям со стороны удобства разработки и поддержки, а не со стороны соответствия каноничным паттернам. Еще на текущий момент экспериментируем с MVI, а точнее даже некоторым симбиозом MVVM и MVI, где вместо одного объекта стейта — может быть несколько аналогов LiveData.

Какие библиотеки и фреймворки используете? Какие считаете надежными?

Макс:

Из основных: RxJava, Dagger, Retrofit, OkHttp, Gson, Glide, Room. Библиотеки для ui слоя практически не используем, предпочитаем все писать самим, за исключением специфичных и узких компонентов, таких как маска поля ввода, построение графиков, нетипичные View. Из непопулярных и некачественных библиотек мы подключаем только инструменты для отладки, так как они не пойдут в продакшен. Кстати, реляционную базу мы у себя редко в проектах используем, обычно достаточно простого url кеша или объектного хранилища, и для этого у нас есть свои библиотеки.

Расскажи о тестировании. Как оно происходит? При помощи каких библиотек и подходов?

Макс:

Мы используем 3 вида тестирования:

  1. Unit тесты на голом JUnit. Обычно ими покрываем специфичную бизнес логику. Полного покрытия тестами не делаем, потому что зачастую большая часть приложения — это тонкий клиент и большинство клиентов не готовы оплачивать эту работу. Эти тесты запускаются на каждый Pull Request и при каждой сборке перед тестированием QA инженерами на CI.
  2. Интеграционные тесты на API сервера. Используются для проверки API во время реализации запросов в приложении, а также отслеживания состояния сервера. Тесты гоняются на CI несколько раз в день. Они используют наш ApiTestRunner. Этот runner имеет несколько полезных фич, в частности, если пометить метод с тестом аннотацией @WaitApi, результат теста будет инвертирован. Это позволяет определять те методы API, которые реализовали на сервере.
  3. UI тесты на Calabash + Cucumber. Их пишут QA инженеры. Особенность этого стека в том, что одни и те же тесты пишутся на Android и iOS, и тесты являются простым текстом, на человеческом языке, написанным в форме истории (сценария). Они также запускаются на CI периодически.

Как вы вводите новые библиотеки в проект?

Макс:

Все зависит от степени зависимости приложения от библиотеки, если библиотека небольшая и решает узкоспециализированную задачу, то решение об ее использовании принимает TeamLead. Иначе подключение этой библиотеки согласовывается с руководителем отдела, при этом, естественно, необходимо обосновать ее использование. Если мы встречаем задачу, с которой раньше не встречались обязательно выделяется время на исследование и поиск оптимальных библиотек.

Как у вас организована сборка билдов, CI и их выкладка в prod?

Макс:

В качестве CI используем Jenkins (с плагином BlueOcean) и собственный небольшой фреймворк на основе scripted pipelines, который подключается к Jenkins как библиотека. Сам фреймворк написан на Groovy (скриптовое расширение Java) и содержит набор утилит для распространенных задач, а также готовые pipeline для всех типов заданий и платформ, которые используют в Surf. Сами скрипты для ci конкретного проекта находятся в репозитории проекта, содержат несколько строк с подключением библиотеки и запуском пайплайна из нее. Благодаря использованию библиотеки, мы можем централизованно изменять логику работы ci для всех проектов. Кроме того, базовые пайплайны написаны таким образом, что позволяют изменять/добавлять любой шаг, подправлять любую команду под конкретные нужды проекта.

Для проекта у нас есть 4 типа pipeline:

  1. PR — запускается при создании и каждом изменении Pull Request (пр). Запрещено мержить PR, если build не проходит. Не считая стандартных шагов (build, test, оповещение в чат и установка статусов сборки обратно в репозиторий), есть несколько интересных доработок в частности:
    • локальный merge с целевой веткой перед сборкой;
    • триггер сборки на изменение целевой ветки;
    • экспериментально сейчас применяем автоформатирование кода.
  2. TAG — запускается при добавлении тега в репозиторий. Добавление тега означает необходимость создания сборки для тестирования или релиза. Сборка на тестирование передается с помощью Fabric Beta в конце пайплайна. Релизы в GooglePlay у нас обычно происходят руками, так как релизы не слишком частые, хотя на некоторых проектах и была настроена автоматическая выгрузка apk в GP. Также есть некоторые специфичные решения — вроде установки версии приложения равной имени тега в репо и автоинкремент версии кода.
  3. UI_TEST — этот job прогоняет ui тесты и полностью интергирован с Jira, а вернее с плагином XRay тестировщиков. Пример интеграции: тестировщик объединяет набор тестов (сущности Jira) в TestExecution и переводит его в статус InProgress. Дженкинс сам запускает нужный job, выполняет нужные тесты, выгружает результаты тестов обратно в Jira и передвигает TestExecution в соответствующий статус.
  4. API_TEST — запускается периодически и прогоняет интеграционные тесты на API.

Есть еще некоторые особенности в нашей организации сборки билдов:

  1. Кроме стандартных Debug и Release сборок у нас есть Qa сборки, которые и проверяют тестировщики, их основное отличие от Release сборок — тестовая подпись и установленный флаг debuggable. Для дебаг сборок мы также используем ту же тестовую подпись — это позволяет легко накатывать обновления на уже установленное приложение. При помощи этого, можно уменьшить затраты времени на исправление дефектов. Кстати, на QA сборках также включен Proguard, что позволяет находить связанные с ним проблемы в процессе их появления, а не перед релизом.
  2. Для ci и локальных сборок используем централизованный Gradle Build Cache. Вместе с многомодульной структурой проекта это дает существенное ускорение сборки.
  3. В названии apk средствами Gradle добавляем версию приложения и версию кода. Также в иконках приложений Qa и Debug сборок есть специальная метка с версией приложения — это сделано с помощью плагина gradle-android-ribbonizer-plugin.

Как пришла идея попробовать Flutter? Какие были сложности при его использовании?
Женя:
Скажем так, Flutter — наша инвестиция в будущее. Не хочется быть сторонним наблюдателем расцвета перспективной технологии. Для нас уже очевидно, что у Flutter есть все шансы завоевать рынок.
Заинтересовались мы им ещё до публичного релиза, хотя до этого студия 7 лет занималась исключительно нативной разработкой. Ни одно существующее на тот момент кроссплатформенное решение не вызывало у нас доверия. Тем не менее, мы прекрасно понимаем проблемы бизнеса и дороговизну нативной разработки. Не все проекты объективно “рождены” быть нативными, поэтому, копнув глубже во Flutter, мы решили: “Вот оно!”.
Очень качественно задизайненный фреймворк, декларативный UI, низкий порог вхождения и огромное сообщество, которое успело сформироваться за неполный год после выхода технологии в релиз — всё это сделало нашу встречу с Flutter неизбежной.
Сложности сопровождают интеграцию любой незнакомой технологии: слишком высоки риски и велика ответственность. Первому коммерческому проекту предшествовали полгода ресёрча. Важно было продумать архитектуру, выработать лучшие практики, наконец, нанять или переквалифицировать разработчиков.
Кстати, практически без изменений удалось портировать на Flutter архитектуру, которой мы следуем в Android. Это здорово упростило и ускорило процесс разработки.

Насколько сейчас востребован Flutter?
Женя:
Интерес к технологии лавинообразный. Ещё вчера никто не воспринимал его всерьёз, сегодня даже далёкие от технологий клиенты интересуются нашей Flutter-экспертизой. Вполне вероятно, скоро вы услышите об интересных кейсах использования фреймворка не только в аутсорсе, но и в крупных продуктовых компаниях. К сожалению, не могу раскрывать подробности.
Есть интерес и среди разработчиков. Не редкость, когда на собеседование приходит человек с большим опытом в React Native или в веб-разработке. А наши Flutter-митапы, которые мы периодически проводим, стабильно собирают аншлаги.

Расскажите немного про искусственный интеллект в проектах: что помогает решить? Как он связан с Android-разработкой? Какие проекты реализовывали при помощи него?
Женя:
Хороший вопрос! Правда в том, что ИИ хорошо решает определённый набор задач и справляется с ними тем лучше, чем больше мы имеем качественных данных для обучения нейросети. В этом плане отличный пример — визуальный поиск в приложении “Лабиринт”. Вы можете навести видоискатель камеры на обложку книги и в считанные секунды найти её в каталоге магазина.
Особый интерес и техническую сложность представляют собой именно “on-device” решения, когда нейросеть находится непосредственно на устройстве, а для получения результата не обязательно наличие подключения к интернету. В качестве главного инструмента используем TensorFlow Lite.
И ещё один совет: если вашу задачу решает сторонний сервис — рекомендую делать выбор в его пользу. Чаще всего в долгосрочной перспективе такое решение окупается. На этом поле сейчас у Google Cloud нет конкурентов. За последние годы они создали целое семейство AI Powered сервисов.

Как возникла идея создать свой репозиторий и сделать его доступным для всех?
Макс:
Изначально было желание не изобретать велосипеды в каждом проекте и сгладить некоторые “неровности” Android Framework. Началось все года 3 назад с небольшой библиотеки Ferro, которая постепенно стала обрастать дополнительной логикой, в какой то момент у нас появился отдельный пакет со всеми этими классами, который мы переносили из проекта в проект, затем отдельный модуль. Встала проблема синхронизации изменений этих классов между проектами, к этому времени эти классы стали уже достаточно стабильными, и естественным решением стало поставлять их в виде библиотеки. Мы понимали, что у нас немало интересных решений, которыми можем поделиться с сообществом, поэтому постепенно стали готовить репо к открытию, разрезали всю кодовую базу на модули, добавляли семплы и документацию, модернизировали ci. Параллельно с этим также развивали текущие модули, дописывали новые. Это продолжалось примерно полгода и к моменту бета релиза у нас было уже несколько десятков модулей. В бета статусе репозиторий находится до текущего момента и сейчас заканчиваем работы по выводу части его в полноценный open source.

Основная сложность с которой мы столкнулись при открытии репозитория — разные, иногда даже диаметрально противоположные, требования для open source кода и кода, являющегося частью живого развивающегося проекта. В частности, любое изменение публичной библиотеки должно проходить максимальное число проверок, а изменение части проекта должно быть очень быстрым и удобным, потому что “завтра демо клиенту”. Другая проблема — версионирование, открытые независимые библиотеки должны иметь разные версии и их изменение должно подчиняться определенным общепринятым правилам, а для внутреннего использования самым удобным является подключение набора библиотек с единой версией.
Многие из этих проблем мы решили с помощью уникальной build системы и ci. Основную идею, которую мы держали в голове при ее разработке — изменение AndroidStandard должно быть максимально удобным для проектных команд и с помощью автоматизации свести к минимуму количество дефектов в open source версии AndroidStandard. В итоге, все пайплайны ci AndroidStandard суммарно содержат более 60 шагов (для обычного проекта около 15). К примеру, один из этих шагов проверяет изменение release notes для каждого PullRequest.

Если бы вам сегодня надо было выбрать стэк для нового Android-приложения, то какой бы вы выбрали?
Макс:
Мы бы выбрали стек AndroidStandard :-) ну и в дополнение к нему Kotlin, Dagger, RxJava, Retrofit, Room; архитектура MVVM или MVI c CleanArchitecture и многомодульностью, в общем, ничего специфичного.

Была ли в последнее время технология или библиотека, которая вызвала “вау-эффект”? Возможно, интересный доклад или статья, которая вызвала такой эффект.
Женя:
Flutter! Но чтобы разбавить концентрацию содержания этого слова в нашей беседе, хочу упомянуть несколько решений, которые лично мне кажутся интересными, но они пока не входят в наш технологический стэк.
Первая — Jetpack Navigation. На удивление интересная реализация, которая скрывает сложность стандартной “андроидной” навигации и упрощает работу с анимациями переходов, передачей данных между экранами. Смущает две вещи: кодогенерация и возможные проблемы с масштабированием. На маленький проект точно зайдёт хорошо.
Вторая перспективная библиотека — Jetpack Compose. Пока ещё слишком рано оценивать реализацию, она объективно не готова к использованию в продакшне. Но уверен, что за декларативным UI будущее.
Что касается последних веяний в удивительном мире вёрстки — ConstraintLayout используем не часто, преимущественно для очень простых экранов, но MotionLayout бесконечно прекрасен. Радует, что с каждым годом реализация анимаций в Android становится всё проще и удобнее.
Отдельно хочу сказать спасибо команде разработки за последний релиз Android Studio 3.5. Долгие годы AS была источником ежедневных страданий мобильных разработчиков, но теперь ситуация меняется.

Поговорим про команду

Сколько человек у вас в команде?
Женя:
По-разному. Обычно от двух до восьми. Наши команды очень гибкие, благодаря единым требованиям к подходам и код-стайлу. Чужой код иногда трудно отличить от собственного. В моей текущей команде 4 разработчика.


Как осуществляется взаимодействие внутри команды? Методология работы.
Женя:
В команде есть иерархия. Тимлид — это руководитель. Он отвечает за результат и имеет право решающего голоса. Также он может влиять на бонусы и зарплаты членов своей команды.
Мы работаем по скраму, но без фанатизма. Проект бьётся на спринты, каждый разработчик пишет ввереный ему скоуп задач. Основная коммуникация идёт на этапе проектирования, когда мы можем часто обсуждать друг с другом собственное видение реализуемых фич.
Далеко не все инициативы исходят “сверху”, от лида. Мы ценим рациональные предложения от каждого члена команды и воспитываем культуру проактивности. Большая часть идей, реализованных в нашем AndroidStandard, принадлежит рядовым разработчикам. Да, мы аутсорс-студия, но работа над общей кодовой базой построена по принципам продуктовой разработки. И это помогает разработчикам отвлечься от рутины на проекте.
Изредка практикуем парное программирование. Парный багфикс вообще всегда экономит массу времени. Часто, зарывшись в отладку с головой, перестаёшь замечать очевидные ошибки. Свежий взгляд соратника по команде в таком случае очень помогает.
Каждый спринт обязательно завершается ретроспективой, которая проходит в несколько этапов: сначала внутри команды разработки, затем 1:1 тимлида с руководителем отдела, а завершается общей большой ретроспективой с участием всех, кто работал над проектом.


Как осуществляется общение в команде удаленно? Какие программы вы при этом используете?
Женя:
В нашем штате примерно 40% разработчиков — удалённые сотрудники и это может стать проблемой, если не уделять должного внимания качеству коммуникаций. У каждого сотрудника, который работает не в офисе, обязательно должна быть веб-камера, которая необходима для созвонов. Социализация и визуализация членов команды друг для друга крайне важна. Только так можно сформировать атмосферу доверия в коллективе.
Мы никак не контролируем рабочее время коллег, у нас у всех гибкий график. По-умолчанию считаем разработчика сознательным ответственным человеком, и крайне редко разочаровываемся. Если у разработчика резко падает производительность труда — это очень быстро становится заметно.
Для созвонов держим целый парк софта: Slack, Meet, Skype, Zoom. Видимо, в зависимости от лунных фаз, некоторые инструменты периодически перестают нормально работать.
Очень важно, чтобы у всех удалённых сотрудников были качественные гарнитуры или микрофоны. Стараемся обеспечивать техникой тех, у кого такой аппаратуры нет. Трудно проявить большее неуважение к коллегам, чем пытаться объяснять сложные нюансы технической реализации в “палочку” за 80 рублей. Поймите, вас очень плохо слышно. На моём столе для этих целей — Blue Yeti.

Какие инструменты/сервисы используются для работы удаленно? Где заводятся задачи, в каком виде? Например, в офисе легко можно подойти к менеджеру и уточнить требования, но на удаленке так быстро это не происходит.
Женя:
“Джентльменский” набор — софт для видеозвонков, Slack для переписки (наличие актуального статуса обязательно!), G-Suit с полным комплектом сервисов для рутины (почта, диск, документы).
Мы очень плотно сидим на продуктах от Atlassian, используем почти всю линейку: Jira, Confluence, Bitbucket. Все задачи заводятся только на доске в Jira. Никаких договорённостей в чате, по-минимуму не зафиксированных разговоров на кухне. Всё должно быть “на бумаге”. Нельзя переоценить важность наличия истории переписки. Если у вас бесплатный Slack без истории — концов в случае чего не найдёте. Лучше выбрать менее функциональный софт, но без “амнезии” в бесплатном режиме.
От себя добавлю, что продукты Atlassian своеобразны. К ним сложно привыкнуть и научиться эффективно использовать их тоже требует усилий. Но стоит подогнать всё под процессы вашего производства, установить необходимые плагины, настроить автоматизацию и интеграцию между сервисами, и вы не сможете понять, как жили без всего этого раньше.

Есть мнение, что ежедневные созвоны непродуктивны. Как вы к этому относитесь? Как у вас организуются онлайн-созвоны?
Женя:
Для меня ежедневный созвон — это пинг: “Да, я жив, я работаю, всё в порядке”. Если в команде есть удалённые сотрудники, эта формальность действительно сильно влияет на понимание происходящего на проекте. Не раз и не два, коллеги теряли контекст и “закапывались” в задачах, многократно превышая оценки. Такие вещи очень успешно отлавливаются именно на ежедневных созвонах.
Идеальный созвон не занимает более 10 минут. Старайтесь не скатываться в диалог с каким-то определённым разработчиком. Не обсуждайте личных и специфичных вопросов, которые никому кроме вас и собеседника не интересны. Запишите вопрос в свой личный планнер и позвоните коллеге сразу после общего созвона. Уважайте время остальных членов своей команды.
Проводя такие созвоны, вы должны чётко понимать, для чего это делаете. Созваниваться для галочки, действительно, смысла не имеет.

Общаются ли коллеги между собой оффлайн? Есть ли какие-то семинары/тренинги/обмен знаниями в команде? Как это устроено на удаленке?
Макс:
Не считая запланированных корпоративов, у нас бывают спонтанные посиделки в барах, некоторые проектные команды собираются чуть ли не по расписанию. Кроме того есть разные группы по интересам, футбол, просмотр фильмов и тд.
Для обмена опытом проводим собрания Android разработчиков практически каждую неделю. Обычно на этих собраниях одна из проектных команд рассказывает об интересных моментах в своих последних итерациях. Также могут презентоваться новые модули AndroidStandard, разбираться важные моменты с Google IO, изменения в стратегии отдела и др. Есть чат в Slack, где постоянно ребята помогают друг другу. Для лидов тоже есть отдельные еженедельные собрания, где они также обмениваются опытом и решают наболевшие проблемы.
Собрания проводятся в переговорной комнате, удаленных сотрудников при этом подключаем через видеозвонок.

Как у вас налажен тайм-менеджмент? Есть ли обязательные часы присутствия на связи? Требования к часовому поясу?
Макс:
В большинстве случаев сотрудник должен находится на связи с 11 до 17 по MSK, если по какой то причине он не может этого сделать в конкретный день, оповещает об этом команду. У нас работают люди из часовых поясов европейской части России, опыта с другими часовыми поясами практически не было, не считая зарубежных заказчиков, но коммуникация с ними всё-таки не такая частая, как внутри команды. Время логгируем в Jira, никаких средств слежения за сотрудниками не используем.

Как у вас “улавливается” психологическое состояние коллег? Например, в офисе видно, что у человека не очень хорошее состояние или есть конфликт с другими сотрудниками, а на удаленке это не видно. Есть ли 1-1?
Макс:
За психологическим состоянием сотрудников следит тимлид, как руководитель группы разработчиков. Я не замечал, что распознавать психологическое состояние удаленщиков и конфликты намного сложнее. В любом случае, это влияет на производительность и отражается, как минимум, на артефактах работы. Ежедневные митинги помогают держать руку на пульсе.
Регламентированные 1-1 проводятся раз в 4-6 мес. с лидом и руководителем отдела. С руководителем могут быть и внеплановые, например, из-за крутых успехов или наоборот, каких-либо проблем. Лид отдельно и намного чаще проводит небольшие 1-1, но это не строго регламентировано.

Как попасть к вам в команду? Какой уровень знаний нужен, чтобы у вас работать?
Макс:
Обычно мы набираем людей уровня либо Stajor, либо Middle-Senior.
На первую позицию чаще всего берем подающих надежды студентов с небольшим опытом Android разработки, и обычно в офис. Большую часть берем после наших летних школ. Стажера на удаленку тоже можем взять, но только если у него есть талант к программированию и он его активно развивает.
На вторую позицию, чаще всего берем удаленных сотрудников с опытом в серьезном продакшене от полутора лет, хорошими знаниями языков и фреймворка, пониманием сути программирования, умением думать.
С одной из сторон мы позиционируем себя как команда специалистов, которая любит свою работу и делает ее хорошо. Поэтому немаловажным для всех кандидатов являются софт скилы. Особенно, они важны для удаленных сотрудников. Без софт скилов не получится стать частью нашей команды.

Может быть есть что-то, отличающее вас от других компаний: бонусы, встречи, посещения каких-то мест. Можете рассказать об этом?
Женя:
Мы в этом не уникальны, но Surf действительно помогает своим сотрудникам. Помимо предоставления рабочей техники, которая всё же остаётся в собственности компании, существует опция беспроцентной рассрочки: техника останется вам навсегда, а выплаты можно разбить на мелкие неощутимые суммы.
В этом году Surf помог мне съездить на Google I/O в Калифорнию, покрыв стоимость билета на конференцию и весомую долю расходов на переезд и проживание.
В прошлом году едва ли не пол-офиса уехали на черноморский курорт, сняв там большую виллу, и две недели работали оттуда. Ни один проект при этом не пострадал :)
Регулярно происходят вылазки на байдарках по Воронежской области, поездки на горнолыжные курорты, Должанскую косу и в другие интересные места. Не успеваю сам за всем следить!
Но даже чаще, чем на корпоративах, мы видимся с нашими удалёнными сотрудниками на больших профессиональных конференциях типа Mobius. Недешёвый билет также предоставляется студией каждому, кто действительно понимает, что он хочет получить от мероприятия помимо толстой пачки стикеров и нескольких брендированных худи от партнёров. Конференции вдохновляют!

Огромное спасибо ребятам за такие подробные ответы и интервью!

Если у вас еще остались вопросы к ребятам, а также вы хотите узнать немного больше о команде Surf, то вы можете сделать это в чате.

Ссылка на репозиторий команды, который упоминался в интервью тут.

И, если вы еще не сделали это, то подписывайтесь на канал AndroidLive в Telegram, где периодически появляются новости и статьи из мира Android-разработки.