Самый простой и логичный способ — поменять направление внутри компании. Мог так сделать дважды, но тогда бы и писать было не о чем. Буду рад, если кому-то мой опыт окажется полезным или интересным.

В рамках статьи сеньора обозначим как разработчика, который получает сеньорскую зарплату и стабильный положительный фидбек от руководителя и других разработчиков в команде более года. Шире определял в другой статье.

Содержание

Введение
Зачем менять стек?
Краткая история пути
Лирическое резюме со ссылками
Сложности в бэкенде, когда ты — мобильщик
- Основная идея — в бэкенде всё ненадежно
- Объем данных
- Распределенность системы
- Кошмарные релизы
Что в мобильной разработке нравилось
Вместо заключения: как чувствую себя сейчас

Зачем менять стек?

В 2019 году, работая над android-приложением Auto.ru, я часто думал, что надо что-то менять в карьере. Вот несколько тезисов:

  1. Стать CTO в будущем будет проще с опытом в бэкенде.

  2. Бэкендер может вырасти в архитектора. О мобильных архитекторах я не слышал.

  3. Мобильная разработка — это большая завязка на фреймворк. Мне иногда казалось, что я настройщик фреймворка — а-ля «мастер фотошопа».

  4. Вдохновившись книгой SICP, начал изучать Clojure. А на Clojure есть вакансии только на фронтенд (включая react native) и сервер.

  5. Многие задачи, связанные с UI и UI-тестами, казались рутинными. Вчера изучал RelativeLayout, сегодня в моде ConstraintLayout, завтра уже задеприкейтили MotionLayout (точнее MotionEditor).

  6. Бэкенд более многогранен и дает больше пространства для постоянного изучения нового.

Последний тезис хочется объяснить. Приятели-бэкендеры часто говорили, что подготовиться к собеседованию невозможно:
— Никто не знает всё, — говорил мой друг-бэкендер с 15+ годами опыта в серверной разработке. Книжки вроде «Designing Data-Intensive Applications» могут дать обзор базы, которую желательно понимать бэкендеру, и это ошеломляет.

С другой стороны, мобильная разработка ýже.

Берешь 100 вопросов на андроид-собеседование, недельку готовишься - ты гарантированно пройдешь в любую компанию. — Максим Сидоров, коллега из SberDevices.

С фразой согласен, делал так же и проходил везде, только вопросы готовил сам в Anki.

Краткая история пути

Путь получился витиеватым из-за частой смены фокуса. Зато было интересно в процессе.

Первый год

Уволился из Яндекса с позиции middle android developer. Начал одновременно изучать Clojure, Backend, Frontend, Emacs, Linux. Прочитал штук 6 книг по Clojure и бекенду, написал мультиплеерную игру (plusminus).

Спустя полгода отчаялся. Прогресс не ощущался, а работы на Clojure нет. Решил искать за рубежом. Подумал, что если уж на запад, то в FAANG. Посвятил 2 месяца решению алгоритмов.

Facebook, Apple, Netflix и Uber даже не ответили. Google отказался брать меня в бэкенд, а вот Amazon после первых собеседований соглашался брать в два региона — Ирландию и Кремниевую долину. С последней отказали из-за проблем с H1B визой (нужно было или 10+ лет опыта, или техническое образование). Пригласили очно ехать в Дублин на финал, но не захотел сам, потому что по-настоящему хорошо платят только в долине.

Решил еще раз податься в Google, пусть хоть в Android. Пошел на месяц повторять алгоритмы и базовую теорию по андроид. Собеседования провалил.

Второй год

Деньги заканчивались, надо было уже выходить на работу, поэтому решил вернуться в стек, в котором чувствовал себя увереннее всего, — в Android-разработку. Учитывая подготовку, особенно по части алгоритмов, получил в SberDevices доход в 3Х от того, что было в Yandex.

В свободное время начал писать приложение с бэкендом на Clojure, которое планировал зарелизить на СберДевайсах. MVP написал, но так и не зарелизил. Не хватило мотивации довести до конца.

Третий год

Под конец третьего года получилось написать небольшой проект на Clojure на работе — что-то вроде админки для загрузки и анализа логов девайсов. Проект маленький, разрабатывался недельку, но впервые удалось прикоснуться к Kubernetes. После увольнения, кстати, проект переписали на Java.

Тут можно было поменять команду и начать заниматься бэкендом девайсов без всяких потерь грейдов и зарплат. Но мне хотелось Clojure, а не Kotlin или Java. Просто было иррациональное желание, если не сказать «религиозное».

Четвертый год

Уволился и опять начал изучать Clojure. Написал несколько pet-проектов, поконтрибьютил (подробнее будет ниже) в популярные библиотеки. Подавал на все найденные вакансии, но только спустя полгода удалось выйти на работу. Зато на сеньорскую роль и сеньорское (для 2022 года с его «лэйоффами») вознаграждение. Двое знакомых с опытом в бэкенде под 10+ лет, в том числе на Clojure, собеседовались туда же и получили офферы на такую же сумму.

Лирическое резюме со ссылками

В чем сложность поиска работы на Clojure? Правильно, ее нет. Я живу в Москве недалеко от станции метро Дмитровская, и в радиусе 10км найдется с десяток вакансий в андроид-разработке. Сколько вакансий Clojure во всем мире, куда я смогу устроиться, не уезжая зарубеж? В тот момент, когда искал — середина 2022 года, — было около трех.

Чтобы не упасть духом на таком рынке, я пытался рассуждать так. У меня 7 лет опыта разработки, но нет промышленного опыта в бэкенде. Зато удалось написать небольшую утилитку для анализа логов, которую смог загрузить как веб-сервис в предыдущей компании. Значит, если написать резюме правильно, то опыт будет, но небольшой. Явно не тянет на сеньорский.

У меня нет коммерческого опыта на Clojure, но язык я любил и поэтому все, что мог, писал на нем: например, свой pet-project — мультиплеерную игру с бэкендом и фронтендом на Clojure и ClojureScript, которая оказалась совершенно никому не нужной, но дала опыт и возможность делиться ссылкой на Github.

Скрипты для своих нужд писал на Clojure, и в какой-то момент решил выделить общий код в библиотеку. Написанных на Clojure библиотек относительно мало и нет риска затеряться в толпе, как с JS. В свободное от работы время реализовал пару open source проектов-утилит, один из которых оказался полезным для community — переводчик с Dart на Clojure.

Занимаясь всем вышеописанным, использовал популярный линтер Clj-Kondo, который был настолько гибким и удобным, что я мог для изобретенного мной синтаксиса — да, такое легко делать на Clojure — добавлять свои ошибки (warnings). Разобравшись в линтере, я решил сделать несколько пулреквестов в интересные мне проекты (вроде ClojureDart, где был изобретенный синтаксис, и сам линтер Clj-Kondo). Таким образом, мог показать работодателю свое участие в open source разработке на Clojure.

В течение полугода я отправлял резюме во все проекты по всему миру, делал тестовые (делился в TG) для всех, кто был согласен со мной разговаривать, параллельно читая книжки по Clojure и по серверной разработке (перечитывал «Designing data-intensive applications»), и, наконец, нашел австралийскую компанию, которая согласилась взять меня на сеньорскую зарплату.

Сложности в бэкенде, когда ты — мобильщик

Ни в коем случае не претендую на всесторонний обзор, но лишь поделюсь тем, как и что вижу сам через призму личного и довольно ограниченного опыта.

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

Основная идея — в бэкенде всё ненадежно

Когда пишешь мобильное приложение, единственная ненадежность, с которой приходится сталкиваться — проблемы с сетью (Wi-Fi, GPS, Bluetooth, NFC, GSM/CDMA, и т.п.). Все остальные API, с которыми надо взаимодействовать — база данных, камера, файловая система, гироскоп, медиа-сессия — практически безотказны.

За разработчика уже всё продумали и остаётся только написать правильный код. Пример с андроидом: когда система решает убить приложение, есть callback, чтобы успеть сохранить стейт. Когда приложение «воссоздастся», запустится другой callback с этим стейтом.

Да, некоторые API требуют возни со специфичными ОС (привет, Самсунг). Часто приходится писать ветвления в зависимости от версий ОС или размеров экрана. Но это будет надежный код.

В бэкенде вопрос изначально ставится по-другому: как построить надежную систему из ненадежных компонентов?

Рассмотрим пример проблемы, о которой не думаешь в мобильной, embedded или фронтенд-разработке:

  1. Пришел запрос.

  2. Положили данные в базу.

  3. Делаем запрос в другой сервис. Запрос падает.

  4. Хотим убрать данные из базы. Но тут процесс сервиса убивают (например, из-за выкатки релиза или задержки по health-check).

На шаге «2» мы могли оставить транзакцию в базу открытой, но если сервис из пункта «3» отвечает долго, а у нас тысячи RPS, мы забьем коннекшены к базе, и всё упадет.

Что мы имеем: общение с клиентом ненадежно, общение с базой ненадежно, общение с другими сервисами ненадежно, и даже наше существование ненадежно (убьют без всяких callback вроде onSaveInstanceState).

Объем данных

К проблеме выше прибавляется необходимость заботиться о том, что каждый участок кода может вызываться много раз в секунду. Прям как onDraw. Android-разработчик понимает, что не стоит создавать объекты в onDraw, потому что это спровоцируетGC и в приложении появится лаг. В бэкенде так нужно априори относиться к каждой функции, но в первую очередь стоит беспокоиться не о создании объектов, а об IO-операциях. Например, не ходить в базу данных или в сеть в циклах.

Другие аспекты:

  • Когда-нибудь думали, разрабатывая мобильное приложение, как себя будет вести HashMap с миллионом ключей?

  • А если этот миллион ключей внезапно удвоится и перестанет помещаться в выделенный сервису RAM?

  • А если его держать на диске, а не в RAM?

Распределенность системы

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

Возьмем для примера обычный жизненный цикл Activity:

  • onCreate

  • onStart

  • onResume

  • onPause

  • onStop

  • onDestroy

Как андроид разработчик, вы знаете, что эти функции вызываются не то что на одном процессе, а на одном потоке. Например, на onStart вы можете «биндиться» к сервису, а на «onStop» — отвязываться от сервиса.

Представьте, насколько жизнь была бы сложнее, если бы ваше приложение состояло из сотни процессов, где одновременно могут запуститься ЖЦ сотни Activity. Пусть будет какой-то 4-хмерный юзер, который способен с ними взаимодействовать. Но только одна Activity должна «забиндиться» к сервису. Если эта Activity отвязывается от сервиса, другая должна занять ее место.

В backend-разработке попадаются задачи, когда надо координировать процессы. Сложность заключается еще и в том, что эти процессы могут работать на разных физических сервисах, связь между которыми может прерываться. Появляются проблемы, связанные с распределенными транзакциями и локами и конечно же с производительностью всего этого.

Кошмарные релизы

Когда я был мобильным разработчиком, я думал, что миграция базы данных — это неприятно и сложно. Надо и об обратной совместимости подумать, и проверить специально руками, что всё работает.

В бэкенде проблемы серьезнее. Представьте, что вам нужно обновить приложение, пока пользователь им пользуется, чтобы он не заметил. Возвращаясь к примеру с сотней Activity, запущенных одновременно. Представьте, что нужно обновить их так, чтобы 4-хмерный юзер не заметил, и чтобы стейт сервиса тоже сохранился, а сервис остался привязан к той же самой Activity.

И это еще не всё. Может понадобиться, чтобы 50 Activity были от старой версии, а 50 — обновились незаметно для пользователя, и чтобы пользователь ничего не заподозрил.

Да, не всегда получается такое решить, и тогда разработчики просто релизятся в 2 ночи или 6 утра с даунтаймом.

6:23 AM, а не PM
6:23 AM, а не PM

А в некоторых командах бывают дежурства, когда разработчику на выходные выдается пейджер.

База данных — квантовая система

Пока вы жили в мобильном мире, данные были локальны и детерминированы: записал в SQLite — сразу видишь результат. В базе данных на бэкенде всё иначе: состояние «и сохранено, и не сохранено» может существовать одновременно, пока транзакция не закоммитится и не «схлопнет волну вероятности».

Дебажить это дело сложно. Сперва у меня была иллюзия, что достаточно посмотреть Slow Queries, запустить Explain и разобраться в проблеме. На практике, просидев неделю, запуская EXPLAIN (ANALYZE, BUFFERS) на стенде, близкому к проду по данным, где я пытался симулировать похожую на прод активность, — я понял, что этого недостаточно. Боюсь развивать тему, т.к. она необъятна даже для книги, не говоря о статье. Гляньте только Рассказ про b-tree индексы для разработчиков приложений Ситникова.

Что помогало быть полезным с самого начала

Когда устроился на бэкенд-проект в Австралию, было критически сложно: общение на английском, новый ЯП в проде, динамическая типизация, бэкенд вместо мобилки, нестандартный график работы, откровенный говнокод из-за текучки. Тем не менее, удалось утилизировать имеющийся опыт:

  • Знание алгоритмов позволяли оптимизировать участки кода. Всегда можно самостоятельно создать задачку на себя и сделать маленький PR.

  • Опыт в мобильной разработке и фронтенде позволил делать некоторые задачи fullstack, экономя время на коммуникации.

  • Опыт с CI/CD и девтулами. Можно ускорить pipeline. Можно написать полезные для всех скрипты.

Ну и 12-часовой рабочий день тоже выручал, как и работа в выходные первые 3 месяца.

Что в мобильной разработке нравилось

За мои 10+ лет опыта прослеживалось, что качество кода у мобильных разработчиков значительно выше. С первых лет карьеры разработчика смотрел на код друзей в бэкенде и поражался грязи. Сначала объяснял это тем, что в бэкенде много всего и нет времени на сам код. Ведь помимо ЯП и паттернов проектирования есть база данных (в которую пишут тысячи транзакций в секунду), очереди, облачные сервисы, service mesh, распределённые транзакции, сага, файловые хранилища, шардинг, алгоритмы консенсуса. Другими словами, бесконечный зоопарк концепций, проблем и технологий, которые нужно обуздать.

С опытом понял, что уверенность в чем-то создаёт иллюзии, и всё-таки написание мобильного приложения — это объективно сложно, даже в плане описания бизнес-логики. Фреймворк вмешивается в работу на каждом шагу, вынуждая писать асинхронный код со стейтом. Навыки написания качественного кода — ответ на сложность.

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

Вместо заключения: как чувствую себя сейчас

Первый год жалел, что уплыл из тихой гавани мобильного разработчика в пучину боли и страданий. Много раз порывался вернуться за «халявными» деньгами. Книга «Designing Data-Intensive Applications» дала ощущение, что бэкенд — для гениев.

Во второй год было легче, а теперь доволен, что остался:

  • Стало так же комфортно, как было в мобильной разработке.

  • Задачи кажутся интереснее, горизонта и границ не прослеживается (как было в мобильной разработке).

  • Карьерных возможностей больше. Кто-то уже готов брать меня CTO (и опыт разработки под android идет плюсом).

  • Нет завязки на языки программирования, можно выбирать другой ЯП и переходить на другую работу. В бэкенде опыт бэкенда и баз данных намного ценнее языка.

Если было интересно, подписывайтесь на ТГ. Более короткие посты пишу там. Например, размышления:

Комментарии (6)


  1. onets
    22.10.2025 20:04

    Странный выбор Clojure. Можно же было загуглить статистику вакансий и выбрать что-то из более популярного, типа Go, Java, C#


    1. arturdumchev Автор
      22.10.2025 20:04

      Выбор был бы странным, если бы целью было любой ценой уйти в бекенд. Мне ничего не мешало сделать это в auto.ru, а потом и в SberDevices — можно было перейти в соседнюю команду на Kotlin/Java.

      Логично было выбрать Java. Я первый год под Android писал на Java. Читал Effective Java и Concurrency in Practice. Kotlin — это по сути сахар над Java + корутины.

      Зато благодаря иррациональному выбору сейчас у меня есть прочитанный и проработанный SICP, реализованные интерпретаторы (concatenative), переводчик c Dart на Clojure. Опыт в проде в бекенде на Clojure и Kotlin. Опыт на фронте на ClojureScript (пару месяцев в крипто-стартапе) и TypeScript (в той же Австралийской конторе, куда ушел писать бекенд). И всё время было интересно.

      Уйди я в бекенд на Java, не видел бы сейчас дальше своего носа, опыт был бы очень ограниченным по части того, как можно писать код. Да и скорее всего я бы без интереса не вывез, бросил и вернулся в Android.


  1. themen2
    22.10.2025 20:04

    Андройд говорите тихая гавань? Я перешёл в веб на фронт (Ангуляр) и вот думаю вернуться на бек на Го (когда то им занимался).

    Андройд - это лютое месиво из сырых технологий: java + xml, compose, room, mvvm, mvp, mvi, итд итп и конца и края не видно. И все ПОСТОЯННО устаревает. Гуглу вообще похеру на разработчиков, на их опыт. Они хотят взять из большого рынка monkey реакт разработчиков и посадить их за Conpost свой, ебучий. Как я это все дерьмо не навижу, горите в аду)).

    Работал с беком, кажется там более стабильные технологии: база, кеши, очереди, один язык, один фреймворк. Всё. И нет вендор лока на Гугол.

    Моё мнение - карьера Андройд разработчика - это тупик!!!!!!!


    1. arturdumchev Автор
      22.10.2025 20:04

      и вот думаю вернуться на бек на Го (когда то им занимался).

      Возвращайтесь на бек, конечно. Go — отличный язык, сам хочу на нём писать.

      В остальном что вы сказали — согласен. Но когда у меня было ~7 лет опыта разработки под Android, мне, разумеется, этот стек казался самым простым, понятным, я уже всё вдоль и поперек обошел на нем.


      1. themen2
        22.10.2025 20:04

        Какой последний стек на Андройд вы использовали? Просто интересно.

        Последнее, что я пробовал, это был Compose + Accompanist (костыли для Compose, которые туда не успели войти). Mvvm паттерн.

        Ну... верстать UI на Compose наверное проще чем на xml. Однако вся эта декларативная модель работы с данными и однонаправленные потоки данных мне кажется как то очень сложно реализованы на Андроиде... В итоге всегда было ощущение, что сидишь на кактусе... К тому же ты ещё должен знать и о gotchas которые могут вызвать лишние рекомпозиции. Ага, норм фрейм, где ты не только бизнес логику должен делать, но ещё и на рекомпозицией следить..


        1. arturdumchev Автор
          22.10.2025 20:04

          В проде только на xml писал, ConstraintLayout, MVVM c лайвдатой. Для себя потом на флаттер и КМП с compose писал, но не вникал в них особо.