Самый простой и логичный способ — поменять направление внутри компании. Мог так сделать дважды, но тогда бы и писать было не о чем. Буду рад, если кому-то мой опыт окажется полезным или интересным.
В рамках статьи сеньора обозначим как разработчика, который получает сеньорскую зарплату и стабильный положительный фидбек от руководителя и других разработчиков в команде более года. Шире определял в другой статье.
Содержание
Введение
Зачем менять стек?
Краткая история пути
Лирическое резюме со ссылками
Сложности в бэкенде, когда ты — мобильщик
- Основная идея — в бэкенде всё ненадежно
- Объем данных
- Распределенность системы
- Кошмарные релизы
Что в мобильной разработке нравилось
Вместо заключения: как чувствую себя сейчас
Зачем менять стек?
В 2019 году, работая над android-приложением Auto.ru, я часто думал, что надо что-то менять в карьере. Вот несколько тезисов:
Стать CTO в будущем будет проще с опытом в бэкенде.
Бэкендер может вырасти в архитектора. О мобильных архитекторах я не слышал.
Мобильная разработка — это большая завязка на фреймворк. Мне иногда казалось, что я настройщик фреймворка — а-ля «мастер фотошопа».
Вдохновившись книгой SICP, начал изучать Clojure. А на Clojure есть вакансии только на фронтенд (включая react native) и сервер.
Многие задачи, связанные с UI и UI-тестами, казались рутинными. Вчера изучал RelativeLayout, сегодня в моде ConstraintLayout, завтра уже задеприкейтили MotionLayout (точнее MotionEditor).
Бэкенд более многогранен и дает больше пространства для постоянного изучения нового.
Последний тезис хочется объяснить. Приятели-бэкендеры часто говорили, что подготовиться к собеседованию невозможно:
— Никто не знает всё, — говорил мой друг-бэкендер с 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 или фронтенд-разработке:
Пришел запрос.
Положили данные в базу.
Делаем запрос в другой сервис. Запрос падает.
Хотим убрать данные из базы. Но тут процесс сервиса убивают (например, из-за выкатки релиза или задержки по health-check).
На шаге «2» мы могли оставить транзакцию в базу открытой, но если сервис из пункта «3» отвечает долго, а у нас тысячи RPS, мы забьем коннекшены к базе, и всё упадет.
Что мы имеем: общение с клиентом ненадежно, общение с базой ненадежно, общение с другими сервисами ненадежно, и даже наше существование ненадежно (убьют без всяких callback вроде onSaveInstanceState).
Объем данных
К проблеме выше прибавляется необходимость заботиться о том, что каждый участок кода может вызываться много раз в секунду. Прям как onDraw. Android-разработчик понимает, что не стоит создавать объекты в onDraw, потому что это спровоцируетGC и в приложении появится лаг. В бэкенде так нужно априори относиться к каждой функции, но в первую очередь стоит беспокоиться не о создании объектов, а об IO-операциях. Например, не ходить в базу данных или в сеть в циклах.
Другие аспекты:
Когда-нибудь думали, разрабатывая мобильное приложение, как себя будет вести HashMap с миллионом ключей?
А если этот миллион ключей внезапно удвоится и перестанет помещаться в выделенный сервису RAM?
А если его держать на диске, а не в RAM?
Распределенность системы
И мобильный разработчик, и фронтендер думают об одном процессе. Бэкендер же пишет код, который одновременно запускается на десятках, сотнях и даже тысячах машин.
Возьмем для примера обычный жизненный цикл Activity:
onCreateonStartonResumeonPauseonStoponDestroy
Как андроид разработчик, вы знаете, что эти функции вызываются не то что на одном процессе, а на одном потоке. Например, на onStart вы можете «биндиться» к сервису, а на «onStop» — отвязываться от сервиса.
Представьте, насколько жизнь была бы сложнее, если бы ваше приложение состояло из сотни процессов, где одновременно могут запуститься ЖЦ сотни Activity. Пусть будет какой-то 4-хмерный юзер, который способен с ними взаимодействовать. Но только одна Activity должна «забиндиться» к сервису. Если эта Activity отвязывается от сервиса, другая должна занять ее место.
В backend-разработке попадаются задачи, когда надо координировать процессы. Сложность заключается еще и в том, что эти процессы могут работать на разных физических сервисах, связь между которыми может прерываться. Появляются проблемы, связанные с распределенными транзакциями и локами и конечно же с производительностью всего этого.
Кошмарные релизы
Когда я был мобильным разработчиком, я думал, что миграция базы данных — это неприятно и сложно. Надо и об обратной совместимости подумать, и проверить специально руками, что всё работает.
В бэкенде проблемы серьезнее. Представьте, что вам нужно обновить приложение, пока пользователь им пользуется, чтобы он не заметил. Возвращаясь к примеру с сотней Activity, запущенных одновременно. Представьте, что нужно обновить их так, чтобы 4-хмерный юзер не заметил, и чтобы стейт сервиса тоже сохранился, а сервис остался привязан к той же самой Activity.
И это еще не всё. Может понадобиться, чтобы 50 Activity были от старой версии, а 50 — обновились незаметно для пользователя, и чтобы пользователь ничего не заподозрил.
Да, не всегда получается такое решить, и тогда разработчики просто релизятся в 2 ночи или 6 утра с даунтаймом.


А в некоторых командах бывают дежурства, когда разработчику на выходные выдается пейджер.
База данных — квантовая система
Пока вы жили в мобильном мире, данные были локальны и детерминированы: записал в 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)

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

arturdumchev Автор
22.10.2025 20:04и вот думаю вернуться на бек на Го (когда то им занимался).
Возвращайтесь на бек, конечно. Go — отличный язык, сам хочу на нём писать.
В остальном что вы сказали — согласен. Но когда у меня было ~7 лет опыта разработки под Android, мне, разумеется, этот стек казался самым простым, понятным, я уже всё вдоль и поперек обошел на нем.

themen2
22.10.2025 20:04Какой последний стек на Андройд вы использовали? Просто интересно.
Последнее, что я пробовал, это был Compose + Accompanist (костыли для Compose, которые туда не успели войти). Mvvm паттерн.
Ну... верстать UI на Compose наверное проще чем на xml. Однако вся эта декларативная модель работы с данными и однонаправленные потоки данных мне кажется как то очень сложно реализованы на Андроиде... В итоге всегда было ощущение, что сидишь на кактусе... К тому же ты ещё должен знать и о gotchas которые могут вызвать лишние рекомпозиции. Ага, норм фрейм, где ты не только бизнес логику должен делать, но ещё и на рекомпозицией следить..

arturdumchev Автор
22.10.2025 20:04В проде только на xml писал, ConstraintLayout, MVVM c лайвдатой. Для себя потом на флаттер и КМП с compose писал, но не вникал в них особо.
onets
Странный выбор Clojure. Можно же было загуглить статистику вакансий и выбрать что-то из более популярного, типа Go, Java, C#
arturdumchev Автор
Выбор был бы странным, если бы целью было любой ценой уйти в бекенд. Мне ничего не мешало сделать это в 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.