Холодный старт (Cold Start) и как не заставлять пользователя ждать.
🕓 Правило 3 секунд: Почему ваше приложение удаляют сразу после установки
Знаете ли вы, что 53% пользователей закрывают и удаляют приложение, если оно грузится дольше 3 секунд?
Новички часто совершают одну и ту же ошибку: «Напихаю-ка я инициализацию всей аналитики, рекламы, базы данных и сетевых клиентов в самый старт, чтобы потом всё было готово».
В итоге пользователь видит белый экран или зависшее лого на 5 секунд. Это Холодный старт (Cold Start) - момент, когда система создает процесс вашего приложения с нуля.
🛑 Главные убийцы скорости:
1. Тяжелый
Если вы инициализируете 15 библиотек в главном потоке (Main Thread) до того, как покажется первый экран - вы тормозите запуск.
2. Фейковые Сплэш-экраны.
Никогда (слышите, никогда!) не делайте
🚀 Как ускорить запуск (Чек-лист Мидла):
✅ Ленивая загрузка (Lazy Init):
Инициализируйте тяжелые библиотеки (например, чаты поддержки или карты) только тогда, когда пользователь реально открывает нужный экран, а не при старте.
✅ Фоновые потоки:
Если библиотеку нужно загрузить сразу, делайте это в
✅ Правильный Splash Screen:
🔵 🤖 Android: Используйте официальный
🔵 🍎 iOS: Сделайте
🛠 Как измерить:
Не считайте «на глаз»!
🔵 Android: В логах (Logcat) ищите строку
🔵 iOS: В Xcode зайдите в Product -> Profile -> App Launch. Instruments покажут каждый миллисекунду задержки.
А вы следите за временем запуска или надеетесь на мощные смартфоны пользователей? 👇
#performance #optimization #android #ios #coldstart #middle
👉 @developer_mobila
🕓 Правило 3 секунд: Почему ваше приложение удаляют сразу после установки
Знаете ли вы, что 53% пользователей закрывают и удаляют приложение, если оно грузится дольше 3 секунд?
Новички часто совершают одну и ту же ошибку: «Напихаю-ка я инициализацию всей аналитики, рекламы, базы данных и сетевых клиентов в самый старт, чтобы потом всё было готово».
В итоге пользователь видит белый экран или зависшее лого на 5 секунд. Это Холодный старт (Cold Start) - момент, когда система создает процесс вашего приложения с нуля.
🛑 Главные убийцы скорости:
1. Тяжелый
Application.onCreate (Android) / didFinishLaunching (iOS).Если вы инициализируете 15 библиотек в главном потоке (Main Thread) до того, как покажется первый экран - вы тормозите запуск.
2. Фейковые Сплэш-экраны.
Никогда (слышите, никогда!) не делайте
Thread.sleep(2000) или таймер на стартовом экране, «чтобы пользователь успел разглядеть логотип». Это бесит.🚀 Как ускорить запуск (Чек-лист Мидла):
✅ Ленивая загрузка (Lazy Init):
Инициализируйте тяжелые библиотеки (например, чаты поддержки или карты) только тогда, когда пользователь реально открывает нужный экран, а не при старте.
✅ Фоновые потоки:
Если библиотеку нужно загрузить сразу, делайте это в
Coroutines (Dispatchers.IO) или DispatchQueue.global(). Главный поток должен заниматься только отрисовкой UI.✅ Правильный Splash Screen:
androidx.core:core-splashscreen. Он нативен, красив и работает мгновенно, пока грузится ваш процесс.LaunchScreen.storyboard максимально легким. Никакого кода, только статика.🛠 Как измерить:
Не считайте «на глаз»!
Displayed. Там система сама пишет: ActivityManager: Displayed com.app/.StartActivity: +850ms.А вы следите за временем запуска или надеетесь на мощные смартфоны пользователей? 👇
#performance #optimization #android #ios #coldstart #middle
👉 @developer_mobila
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
💉 Dependency Injection: Зачем усложнять, если можно просто написать
Когда новичок видит код с кучей аннотаций
❌ Код Джуна (Hard dependency):
В чем проблема?
Представьте, что вы строите дом. Этот код как если бы вы вмуровали кофемашину прямо в стену кухни.
1. Хотите заменить кофемашину на новую? Придется ломать стену (переписывать код класса).
2. Хотите протестировать кухню, не варя кофе? Не получится, машина там намертво.
✅ Код Мидла (Dependency Injection):
В чем суть?
Вы говорите: "Мне для работы нужна база данных. Дайте мне её, я не хочу сам её создавать".
Это как розетка. Вы не вмуровываете технику в стену, вы просто втыкаете вилку. Сегодня это дешевый чайник (тестовая база), завтра мощная кофемашина (реальный сервер).
🛠 Инструменты (Что учить):
🤖 Android:
• Hilt (Dagger): Стандарт от Google. Мощный, проверяет ошибки при компиляции, но сложный в настройке.
• Koin: Service Locator (технически не совсем DI, но решает те же задачи). Простой, пишется на чистом Kotlin, но ошибки могут вылезти в рантайме. Идеально для старта.
🍏 iOS:
• Swinject: Классика DI контейнеров.
• Swift Native: В современных проектах часто используют просто Factory Pattern или передачу зависимостей через
💡 Совет:
На собеседовании на вопрос "Что такое DI?" не начинайте рассказывать про даггер.
Скажите просто: "Это принцип, когда объекты не создают свои зависимости сами, а получают их извне. Это нужно для тестируемости и гибкости кода". Это ответ уровня Senior.
А что используете вы в своих проектах? 👇
#architecture #di #hilt #koin #ios #android #middle #patterns
👉 @developer_mobila
new?Когда новичок видит код с кучей аннотаций
@Inject или модулей, у него возникает вопрос: "Зачем всё это? Я же могу просто создать объект внутри класса!"❌ Код Джуна (Hard dependency):
class UserRepository {
// Мы "приварили" конкретную базу данных к репозиторию
private val database = SQLiteDatabase()
fun getUser() { ... }
}
В чем проблема?
Представьте, что вы строите дом. Этот код как если бы вы вмуровали кофемашину прямо в стену кухни.
1. Хотите заменить кофемашину на новую? Придется ломать стену (переписывать код класса).
2. Хотите протестировать кухню, не варя кофе? Не получится, машина там намертво.
✅ Код Мидла (Dependency Injection):
class UserRepository(private val database: Database) {
// Мы просим дать нам ЛЮБУЮ базу данных через конструктор
}
В чем суть?
Вы говорите: "Мне для работы нужна база данных. Дайте мне её, я не хочу сам её создавать".
Это как розетка. Вы не вмуровываете технику в стену, вы просто втыкаете вилку. Сегодня это дешевый чайник (тестовая база), завтра мощная кофемашина (реальный сервер).
🛠 Инструменты (Что учить):
🤖 Android:
• Hilt (Dagger): Стандарт от Google. Мощный, проверяет ошибки при компиляции, но сложный в настройке.
• Koin: Service Locator (технически не совсем DI, но решает те же задачи). Простой, пишется на чистом Kotlin, но ошибки могут вылезти в рантайме. Идеально для старта.
🍏 iOS:
• Swinject: Классика DI контейнеров.
• Swift Native: В современных проектах часто используют просто Factory Pattern или передачу зависимостей через
init, без сторонних библиотек. Это самый чистый путь.💡 Совет:
На собеседовании на вопрос "Что такое DI?" не начинайте рассказывать про даггер.
Скажите просто: "Это принцип, когда объекты не создают свои зависимости сами, а получают их извне. Это нужно для тестируемости и гибкости кода". Это ответ уровня Senior.
А что используете вы в своих проектах? 👇
#architecture #di #hilt #koin #ios #android #middle #patterns
👉 @developer_mobila
👍6
🏎 Гонка потоков: Баг, который исчезает, когда вы пытаетесь его найти
Представьте ситуацию: у вас на банковском счете 100$. Вы и ваша жена одновременно (в одну миллисекунду) пытаетесь снять 10$ через разные банкоматы.
В теории должно остаться 80$.
На практике, из-за Race Condition, может остаться 90$. Банк потерял деньги. 💸
Почему так происходит?
Даже простая операция
1. Считать текущее значение (100).
2. Прибавить единицу (101).
3. Записать новое значение (101).
Если два потока начнут выполнять шаг 1 одновременно, они оба "увидят" 100. Оба прибавят 1 и запишут 101. Одно действие потеряется навсегда.
🐛 Heisenbug (Гейзенбаг):
Самое страшное в гонках то, что они часто исчезают, когда вы начинаете дебажить (добавляете
🛡 Как защититься (Инструменты Мидла):
🤖 Android (Kotlin):
🔵 Atomic-типы: Для простых счетчиков используйте
🔵 Mutex (для Coroutines): Это "светофор" для корутин.
• StateFlow: Позволяет безопасно обновлять состояние UI, избегая гонок.
🍏 iOS (Swift):
• Actors (Swift 5.5+): В 2026 году это стандарт. Акторы автоматически защищают свое изменяемое состояние. Вам не нужны ручные блокировки.
• Serial Queues (GCD): Старая добрая очередь, где задачи выполняются строго по одной.
💡 Совет: Если у вас в приложении есть переменная
Сталкивались с багами, которые невозможно повторить на устройстве разработчика? 👇
#concurrency #multithreading #android #ios #kotlin #swift #bugs
👉 @developer_mobila
Представьте ситуацию: у вас на банковском счете 100$. Вы и ваша жена одновременно (в одну миллисекунду) пытаетесь снять 10$ через разные банкоматы.
В теории должно остаться 80$.
На практике, из-за Race Condition, может остаться 90$. Банк потерял деньги. 💸
Почему так происходит?
Даже простая операция
count++ (увеличение счетчика) для процессора - это три действия:1. Считать текущее значение (100).
2. Прибавить единицу (101).
3. Записать новое значение (101).
Если два потока начнут выполнять шаг 1 одновременно, они оба "увидят" 100. Оба прибавят 1 и запишут 101. Одно действие потеряется навсегда.
🐛 Heisenbug (Гейзенбаг):
Самое страшное в гонках то, что они часто исчезают, когда вы начинаете дебажить (добавляете
print или брейкпоинты), так как это меняет тайминги выполнения потоков.🛡 Как защититься (Инструменты Мидла):
🤖 Android (Kotlin):
AtomicInteger или AtomicBoolean. Они гарантируют атомарность операций.
val mutex = Mutex()
mutex.withLock {
// Код здесь выполняется только одним потоком за раз
count++
}
• StateFlow: Позволяет безопасно обновлять состояние UI, избегая гонок.
🍏 iOS (Swift):
• Actors (Swift 5.5+): В 2026 году это стандарт. Акторы автоматически защищают свое изменяемое состояние. Вам не нужны ручные блокировки.
actor BankAccount {
var balance = 100
func withdraw(amount: Int) { balance -= amount }
}
• Serial Queues (GCD): Старая добрая очередь, где задачи выполняются строго по одной.
💡 Совет: Если у вас в приложении есть переменная
var, которую меняют из разных фоновых потоков, это бомба замедленного действия. Заверните её в Atomic, Mutex или Actor.Сталкивались с багами, которые невозможно повторить на устройстве разработчика? 👇
#concurrency #multithreading #android #ios #kotlin #swift #bugs
👉 @developer_mobila
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤖 Хватит быть «человеком-компилятором» на Code Review
Вам знакомо это чувство, когда вы открываете Pull Request коллеги, и вместо того, чтобы проверять логику, пишете:
🔵 «Тут лишний пробел»
🔵 «Название функции с большой буквы?»
🔵 «Удали неиспользуемый импорт»
Это трата дорогого времени разработчика. Эти споры (Tab vs Space, где ставить фигурную скобку) должны решать роботы, а не люди.
В 2026 году стыдно не иметь настроенный Linter (Линтер) в проекте.
🛠 Что подключить прямо сейчас:
🤖 Android (Kotlin):
1. Ktlint: Следит за стилем кода (официальный Kotlin Style Guide). Умеет сам форматировать файл по команде (
2. Detekt: Это уже тяжелая артиллерия. Он ищет не просто кривые отступы, а потенциальные баги: слишком сложные функции, магические числа, пустые блоки
🍏 iOS (Swift):
1. SwiftLint: Стандарт индустрии. Настраивается через
🔵 Пример правила:
🚀 Уровень Pro (Git Hooks):
Настройте Pre-commit hook.
Это скрипт, который запускает линтер до того, как коммит вообще создастся.
Если линтер найдет ошибку - Git просто не даст сделать коммит.
Итог: В репозиторий физически невозможно запушить «грязный» код.
💡 Договоритесь с командой о правилах один раз, запишите их в конфиг линтера и забудьте. Code Review должен быть про архитектуру и надежность, а не про красоту текста.
У вас в проекте стоит жесткий запрет на варнинги (Treat warnings as errors) или «пусть висят»? 👇
#ci #quality #detekt #swiftlint #ktlint #automation #middle
👉 @developer_mobila
Вам знакомо это чувство, когда вы открываете Pull Request коллеги, и вместо того, чтобы проверять логику, пишете:
Это трата дорогого времени разработчика. Эти споры (Tab vs Space, где ставить фигурную скобку) должны решать роботы, а не люди.
В 2026 году стыдно не иметь настроенный Linter (Линтер) в проекте.
🛠 Что подключить прямо сейчас:
🤖 Android (Kotlin):
1. Ktlint: Следит за стилем кода (официальный Kotlin Style Guide). Умеет сам форматировать файл по команде (
./gradlew ktlintFormat). Больше никаких споров о пробелах.2. Detekt: Это уже тяжелая артиллерия. Он ищет не просто кривые отступы, а потенциальные баги: слишком сложные функции, магические числа, пустые блоки
catch.🍏 iOS (Swift):
1. SwiftLint: Стандарт индустрии. Настраивается через
.swiftlint.yml. Может кидать Warning (желтое) или Error (красное), если код не соответствует правилам команды.force_cast (запрет на использование as!), line_length (длина строки).🚀 Уровень Pro (Git Hooks):
Настройте Pre-commit hook.
Это скрипт, который запускает линтер до того, как коммит вообще создастся.
Если линтер найдет ошибку - Git просто не даст сделать коммит.
Итог: В репозиторий физически невозможно запушить «грязный» код.
У вас в проекте стоит жесткий запрет на варнинги (Treat warnings as errors) или «пусть висят»? 👇
#ci #quality #detekt #swiftlint #ktlint #automation #middle
👉 @developer_mobila
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
🎨 Почему простой список лагает: Скрытый враг FPS (Overdraw)
Бывало такое? Вы сверстали красивый экран, но при скролле он идет рывками, а телефон в руках начинает нагреваться. Вы смотрите в код адаптера, там всё чисто.
Проблема не в коде. Проблема в Overdraw (Перерисовке).
Это когда система вынуждена закрашивать один и тот же пиксель на экране 3-4 раза за один кадр.
Пример: У вас есть белый фон у
GPU делает 4 лишних действия, хотя пользователь видит только картинку.
🛠 Как увидеть это своими глазами:
🤖 Android:
Это встроенная суперсила, о которой забывают.
1. Идем в Настройки разработчика (Developer Options).
2. Ищем пункт «Отладка наложения GPU» (Debug GPU overdraw).
3. Выбираем «Показывать зоны наложения».
Ваш экран станет психоделически цветным:
• 💙 Синий: 1 слой (Идеал).
• 💚 Зеленый: 2 слоя (Норма).
• 🩷 Розовый: 3 слоя (Стоит обратить внимание).
• ❤️ Красный: 4+ слоя (Плохо! Тут тормозит).
🍏 iOS: В Xcode:
1. Запустите приложение на устройстве.
2. В меню Xcode: Debug -> View Debugging -> Rendering -> Color Blended Layers.
3. Красные зоны покажут места, где смешиваются прозрачные слои (это самое дорогое для GPU).
🚀 Как лечить:
1. Удаляйте лишние фоны (
2. Избегайте прозрачности (alpha). Для GPU просчитать полупрозрачность сложнее, чем просто сплошной цвет.
3. В списках (RecyclerView/LazyColumn) следите, чтобы элементы не рисовали фон там, где его перекрывает картинка.
💡 Задание: Включите этот режим на телефоне и зайдите в популярные приложения (Telegram, YouTube). Посмотрите, как качественно (или нет) они оптимизированы. А потом зайдите в своё. 😉
Знали про эту настройку или всё это время гадали, почему падает FPS? 👇
#performance #ui #fps #android #ios #optimization #middle
👉 @developer_mobila
Бывало такое? Вы сверстали красивый экран, но при скролле он идет рывками, а телефон в руках начинает нагреваться. Вы смотрите в код адаптера, там всё чисто.
Проблема не в коде. Проблема в Overdraw (Перерисовке).
Это когда система вынуждена закрашивать один и тот же пиксель на экране 3-4 раза за один кадр.
Пример: У вас есть белый фон у
Activity -> сверху белый фон у Fragment -> сверху белый фон у карточки товара -> сверху картинка.GPU делает 4 лишних действия, хотя пользователь видит только картинку.
🛠 Как увидеть это своими глазами:
🤖 Android:
Это встроенная суперсила, о которой забывают.
1. Идем в Настройки разработчика (Developer Options).
2. Ищем пункт «Отладка наложения GPU» (Debug GPU overdraw).
3. Выбираем «Показывать зоны наложения».
Ваш экран станет психоделически цветным:
• 💙 Синий: 1 слой (Идеал).
• 💚 Зеленый: 2 слоя (Норма).
• 🩷 Розовый: 3 слоя (Стоит обратить внимание).
• ❤️ Красный: 4+ слоя (Плохо! Тут тормозит).
🍏 iOS: В Xcode:
1. Запустите приложение на устройстве.
2. В меню Xcode: Debug -> View Debugging -> Rendering -> Color Blended Layers.
3. Красные зоны покажут места, где смешиваются прозрачные слои (это самое дорогое для GPU).
🚀 Как лечить:
1. Удаляйте лишние фоны (
background). Если у контейнера уже есть белый фон, не нужно ставить такой же белый фон вложенному TextView2. Избегайте прозрачности (alpha). Для GPU просчитать полупрозрачность сложнее, чем просто сплошной цвет.
3. В списках (RecyclerView/LazyColumn) следите, чтобы элементы не рисовали фон там, где его перекрывает картинка.
💡 Задание: Включите этот режим на телефоне и зайдите в популярные приложения (Telegram, YouTube). Посмотрите, как качественно (или нет) они оптимизированы. А потом зайдите в своё. 😉
Знали про эту настройку или всё это время гадали, почему падает FPS? 👇
#performance #ui #fps #android #ios #optimization #middle
👉 @developer_mobila
👍3👏1
🗣 «У меня не работает»: Почему сеньоры игнорируют ваши сообщения
Классическая ситуация:
Джун пишет в командный чат: «Парни, тут 500-я ошибка при логине, что делать?» и прикладывает скриншот логов.
В ответ - тишина. Или сухое: «Смотри бэкенд».
Почему так? Потому что вопрос сформулирован как «Решите проблему за меня». Это раздражает.
Опытного разработчика отличает умение ценить чужое время. Если вы хотите быстрый и качественный ответ, используйте алгоритм идеального вопроса:
1. Контекст: Что именно ты пытался сделать?
2. Ожидание vs Реальность: Что должно было произойти и что произошло на самом деле?
3. Самое важное - что ты уже попробовал
❌ Плохо: «Я ничего не трогал, оно само».
✅ Хорошо: «Я погуглил ошибку, проверил токен в хедере (он есть) и перезагрузил сервер. Не помогло».
⏳ Правило 15 минут:
Прежде чем дергать коллегу, потратьте ровно 15 минут на самостоятельный поиск решения.
🔵 Если спросили раньше - вы ленивый и не хотите думать.
🔵 Если залипли на 3 часа и молчите - вы тратите деньги компании впустую. Найдите баланс.
🦆 Метод Утенка (Rubber Duck Debugging):
Перед тем как написать вопрос, проговорите его вслух (или напишите в «Избранное» самому себе).
Магия в том, что пока вы структурируете проблему словами, вы в 90% случаев сами находите решение, даже не отправив сообщение.
💡 Совет: Никогда не присылайте код скриншотами! Скриншот нельзя скопировать, чтобы запустить или погуглить. Используйте сниппеты или Gist.
А у вас в команде есть человек, который задает вопросы лучше всех? 👇
#softskills #career #communication #teamwork #middle #tips
👉 @developer_mobila
Классическая ситуация:
Джун пишет в командный чат: «Парни, тут 500-я ошибка при логине, что делать?» и прикладывает скриншот логов.
В ответ - тишина. Или сухое: «Смотри бэкенд».
Почему так? Потому что вопрос сформулирован как «Решите проблему за меня». Это раздражает.
Опытного разработчика отличает умение ценить чужое время. Если вы хотите быстрый и качественный ответ, используйте алгоритм идеального вопроса:
1. Контекст: Что именно ты пытался сделать?
2. Ожидание vs Реальность: Что должно было произойти и что произошло на самом деле?
3. Самое важное - что ты уже попробовал
❌ Плохо: «Я ничего не трогал, оно само».
✅ Хорошо: «Я погуглил ошибку, проверил токен в хедере (он есть) и перезагрузил сервер. Не помогло».
⏳ Правило 15 минут:
Прежде чем дергать коллегу, потратьте ровно 15 минут на самостоятельный поиск решения.
🦆 Метод Утенка (Rubber Duck Debugging):
Перед тем как написать вопрос, проговорите его вслух (или напишите в «Избранное» самому себе).
Магия в том, что пока вы структурируете проблему словами, вы в 90% случаев сами находите решение, даже не отправив сообщение.
💡 Совет: Никогда не присылайте код скриншотами! Скриншот нельзя скопировать, чтобы запустить или погуглить. Используйте сниппеты или Gist.
А у вас в команде есть человек, который задает вопросы лучше всех? 👇
#softskills #career #communication #teamwork #middle #tips
👉 @developer_mobila
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🧟♂️ Зомби в вашем коде: Почему приложение «пухнет» со временем
Бывало такое? Вы открыли экран, закрыли его, а память не освободилась. Сделали так 10 раз и приложение упало.
Поздравляю, у вас Memory Leak (Утечка памяти).
Это происходит, когда объект (например, тяжелая
Главные причины утечек (Checklist):
🛑 Android:
1. Static Context: Никогда не сохраняйте
• Плохо:
2. Забытые слушатели: Если вы подписались на синглтон (
3. Внутренние классы: Анонимные классы (например,
🛑 iOS:
1. Retain Cycles (Циклы сильных ссылок):
Объект А держит Б, а Б держит А. Они никогда не удалятся.
• Классика: Вы передали
• Лечение: Всегда используйте
🛠 Инструменты для поиска (Без них вы слепы):
🐤 Android - LeakCanary:
Библиотека от Square. Must-have в любом debug-билде.
Она автоматически следит за Activity/Fragment. Если происходит утечка, она присылает уведомление (буквально кричит), дампит память и показывает красивое дерево ссылок: кто именно держит ваш объект.
📊 iOS - Memory Graph Debugger:
В Xcode есть встроенная кнопка (три шарика, соединенных линиями) в нижней панели дебага.
Нажимаете её во время работы приложения - и Xcode показывает граф всех объектов в памяти. Ищите фиолетовые восклицательные знаки (⚠️) - это утечки.
💡 Совет: Утечки памяти коварны тем, что на мощном телефоне разработчика они незаметны. А у пользователя на старом Android с 3 ГБ RAM приложение вылетит через 5 минут. Проверяйте память хотя бы раз в спринт.
А вы используете
#memory #performance #leaks #leakcanary #ios #android #middle #optimization
👉 @developer_mobila
Бывало такое? Вы открыли экран, закрыли его, а память не освободилась. Сделали так 10 раз и приложение упало.
Поздравляю, у вас Memory Leak (Утечка памяти).
Это происходит, когда объект (например, тяжелая
Activity или ViewController) уже не нужен пользователю, но сборщик мусора (GC) не может его удалить, потому что кто-то другой всё еще держит на него ссылку.Главные причины утечек (Checklist):
🛑 Android:
1. Static Context: Никогда не сохраняйте
Context или View в статические переменные!• Плохо:
companion object { var myView: TextView? = null } - это удержит всю Activity в памяти навсегда.2. Забытые слушатели: Если вы подписались на синглтон (
LocationManager.addListener(this)), но забыли отписаться в onDestroy - Activity останется жить вечно.3. Внутренние классы: Анонимные классы (например,
Handler или AsyncTask) неявно хранят ссылку на внешний класс.🛑 iOS:
1. Retain Cycles (Циклы сильных ссылок):
Объект А держит Б, а Б держит А. Они никогда не удалятся.
• Классика: Вы передали
self внутрь замыкания (closure), которое сохранено в свойстве этого же класса.• Лечение: Всегда используйте
[weak self] внутри клоужеров, если есть риск цикла.🛠 Инструменты для поиска (Без них вы слепы):
🐤 Android - LeakCanary:
Библиотека от Square. Must-have в любом debug-билде.
Она автоматически следит за Activity/Fragment. Если происходит утечка, она присылает уведомление (буквально кричит), дампит память и показывает красивое дерево ссылок: кто именно держит ваш объект.
📊 iOS - Memory Graph Debugger:
В Xcode есть встроенная кнопка (три шарика, соединенных линиями) в нижней панели дебага.
Нажимаете её во время работы приложения - и Xcode показывает граф всех объектов в памяти. Ищите фиолетовые восклицательные знаки (⚠️) - это утечки.
💡 Совет: Утечки памяти коварны тем, что на мощном телефоне разработчика они незаметны. А у пользователя на старом Android с 3 ГБ RAM приложение вылетит через 5 минут. Проверяйте память хотя бы раз в спринт.
А вы используете
[weak self] везде «на всякий случай» или только там, где нужно? 👇#memory #performance #leaks #leakcanary #ios #android #middle #optimization
👉 @developer_mobila
👍4❤1
🎭 Искусство обмана: Зачем нужны Mock-объекты (и почему без них тесты - мусор)
Представьте: вы пишете тест для экрана Логина.
Вы нажимаете «Войти» в коде теста -> идет запрос на реальный сервер -> сервер отвечает 200 OK -> тест проходит.
На следующий день у вас пропал интернет. Или бэкенд упал. Или Вася с бэкенда поменял JSON.
Ваш тест упал 🔴.
Но ваш код Логина не менялся и работает правильно!
Это Flaky Test (Хрупкий тест). Он проверяет не вашу логику, а погоду на Марсе (доступность сервера).
🛡 Решение: Mocking (Мокирование)
В Unit-тестах мы должны тестировать классы в изоляции.
Ваш
Как это работает (на пальцах):
1. У вас есть интерфейс
2. В реальном приложении вы используете
3. В тесте вы создаете Mock этого репозитория.
Что умеет Mock:
Вы говорите ему: "Слушай, когда у тебя вызовут метод
🛠 Инструменты Мидла:
🤖 Android (Kotlin):
Забудьте про Mockito (он из мира Java). Используйте MockK.
🍏 iOS (Swift):
В Swift часто пишут моки вручную (создают класс
Либо используют генераторы: Sourcery или Cuckoo.
Суть та же:
💡 Главная мысль:
Unit-тесты должны работать без интернета, без эмулятора и выполняться за миллисекунды. Если ваш тест идет 5 секунд - это не Unit-тест.
А какой процент покрытия кода тестами (Code Coverage) в вашем проекте? (Если 0% - не стесняйтесь, ставьте 🌚) 👇
#testing #unit #mockk #android #ios #quality #middle
👉 @developer_mobila
Представьте: вы пишете тест для экрана Логина.
Вы нажимаете «Войти» в коде теста -> идет запрос на реальный сервер -> сервер отвечает 200 OK -> тест проходит.
На следующий день у вас пропал интернет. Или бэкенд упал. Или Вася с бэкенда поменял JSON.
Ваш тест упал 🔴.
Но ваш код Логина не менялся и работает правильно!
Это Flaky Test (Хрупкий тест). Он проверяет не вашу логику, а погоду на Марсе (доступность сервера).
🛡 Решение: Mocking (Мокирование)
В Unit-тестах мы должны тестировать классы в изоляции.
Ваш
ViewModel / Presenter не должен знать, что существует настоящий сервер или база данных. Ему нужно подсунуть «куклу» (Mock).Как это работает (на пальцах):
1. У вас есть интерфейс
AuthRepository.2. В реальном приложении вы используете
NetworkAuthRepository (который ходит в сеть).3. В тесте вы создаете Mock этого репозитория.
Что умеет Mock:
Вы говорите ему: "Слушай, когда у тебя вызовут метод
login("admin", "123"), не ходи ни в какую сеть. Просто верни мне Success мгновенно" (или Error, если хотите проверить обработку ошибок).🛠 Инструменты Мидла:
🤖 Android (Kotlin):
Забудьте про Mockito (он из мира Java). Используйте MockK.
// Создаем мок
val repository = mockk<AuthRepository>()
// Обучаем его (Stubbing)
coEvery { repository.login(any(), any()) } returns Result.Success(User("Max"))
// Тестируем ViewModel
viewModel.onLoginClicked()
// Проверяем, что метод был вызван (Verification)
coVerify { repository.login("admin", "pass") }
🍏 iOS (Swift):
В Swift часто пишут моки вручную (создают класс
MockAuthRepo, реализующий протокол), так как рефлексия ограничена.Либо используют генераторы: Sourcery или Cuckoo.
Суть та же:
class MockAuthRepo: AuthRepository {
var loginResult: Result<User, Error>?
func login(...) {
return loginResult! // Возвращаем то, что настроили заранее
}
}
💡 Главная мысль:
Unit-тесты должны работать без интернета, без эмулятора и выполняться за миллисекунды. Если ваш тест идет 5 секунд - это не Unit-тест.
А какой процент покрытия кода тестами (Code Coverage) в вашем проекте? (Если 0% - не стесняйтесь, ставьте 🌚) 👇
#testing #unit #mockk #android #ios #quality #middle
👉 @developer_mobila
👍1
⚡️ Kotlin — современный мощный инструмент с простым синтаксисом. Он подходит как для бэкенд, так и фронтенд-разработки, к тому же на нем разрабатывают приложения под Android. Присматриваетесь к Kotlin, но еще нет навыков программирования? В OTUS стартовал набор на онлайн-курс «Kotlin Developer. Basic».
Всего через 4 месяца вы:
✔Освоите принципы программирования и алгоритмов
✔Узнаете о возможностях языка Kotlin на практике
✔Научитесь использовать популярные структуры данных
✔Опробуете Kotlin в качестве языка бэкенд- и фронтенд-разработки
И все это на живых вебинарах с ведущими разработчиками и на практике, где вы разработаете собственный проект для портфолио. Пройдите вступительный тест и успейте занять место со скидкой:
https://vk.cc/cUxQm5
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Всего через 4 месяца вы:
✔Освоите принципы программирования и алгоритмов
✔Узнаете о возможностях языка Kotlin на практике
✔Научитесь использовать популярные структуры данных
✔Опробуете Kotlin в качестве языка бэкенд- и фронтенд-разработки
И все это на живых вебинарах с ведущими разработчиками и на практике, где вы разработаете собственный проект для портфолио. Пройдите вступительный тест и успейте занять место со скидкой:
https://vk.cc/cUxQm5
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Подводные камни миграции на Swift 6, о которых стоит знать
Swift 6 вводит более строгие проверки изоляции конкурентности и поддерживает поэтапную миграцию, модуль за модулем. Хотя рекомендуемая Apple стратегия выглядит мягкой, на практике вы можете столкнуться со скрытыми сбоями во время выполнения, особенно когда в проекте одновременно сосуществуют модули на Swift 5 и Swift 6.
В этой статье разберем два реальных кейса, на которых команды регулярно спотыкаются при поэтапной миграции на Swift 6. Мы свяжем их с исходниками Swift Runtime, объясним задумку и триггеры падений, и завершим практическими мерами по снижению рисков и рекомендациями по обновлению.
https://www.hughlee.page/en/posts/swift-6-migration-pitfalls/
#ios
👉 @developer_mobila
Swift 6 вводит более строгие проверки изоляции конкурентности и поддерживает поэтапную миграцию, модуль за модулем. Хотя рекомендуемая Apple стратегия выглядит мягкой, на практике вы можете столкнуться со скрытыми сбоями во время выполнения, особенно когда в проекте одновременно сосуществуют модули на Swift 5 и Swift 6.
В этой статье разберем два реальных кейса, на которых команды регулярно спотыкаются при поэтапной миграции на Swift 6. Мы свяжем их с исходниками Swift Runtime, объясним задумку и триггеры падений, и завершим практическими мерами по снижению рисков и рекомендациями по обновлению.
https://www.hughlee.page/en/posts/swift-6-migration-pitfalls/
#ios
👉 @developer_mobila
👍1
🚀 Хватит собирать билды руками: Введение в CI/CD
Знакомая боль: вы закончили крутую фичу, и QA просит тестовую сборку. Вы переключаете ветку, жмете "Build APK" (или "Archive" в Xcode) и... идете гулять на 20 минут. Ноутбук гудит как турбина самолета, интерфейс тормозит, работать невозможно.
А потом тестировщик пишет: "Слушай, а ты версию (versionCode) забыл поднять, оно не ставится поверх старого". 🤦♂️
Сборка релизов руками со своего компьютера - это огромная трата времени и источник человеческих ошибок (забыли сменить конфиг с Debug на Release, выбрали не тот сертификат).
Взрослые команды используют CI/CD (Continuous Integration / Continuous Deployment).
⚙️ Как это выглядит у Мидлов:
Вы просто делаете
Дальше начинается магия:
1. В облаке просыпается виртуальный сервер.
2. Он скачивает свежий код.
3. Запускает линтеры и Unit-тесты (о которых мы говорили раньше). Если они упали - сборка отменяется, а вам в Slack/Telegram прилетает по шапке.
4. Если всё зелено — сервер сам увеличивает номер версии, собирает приложение и подписывает его нужным ключом.
5. Готовый файл (APK/IPA) автоматически улетает в Firebase App Distribution, TestFlight или прямо в чатик QA.
🛠 Что нужно знать мобильному разработчику (Инструменты):
• Fastlane: Это абсолютный мастхэв индустрии (работает и для iOS, и для Android). Это инструмент, который превращает клики мышкой по настройкам в простой код. Он умеет всё: от сборки до автоматического создания скриншотов для App Store / Google Play.
• GitHub Actions / GitLab CI / Bitrise: Это те самые «облачные серверы» (Runner'ы), которые будут выполнять ваши команды из Fastlane каждый раз, когда вы пушите код.
💡 Правило чистой среды:
Главный плюс CI/CD - код собирается на «чистой» машине. Это навсегда убивает отмазку -А у меня локально всё собирается и работает!". Если код не собрался на CI - значит, он сломан.
#cicd #automation #fastlane #android #ios #middle #githubactions
👉 @developer_mobila
Знакомая боль: вы закончили крутую фичу, и QA просит тестовую сборку. Вы переключаете ветку, жмете "Build APK" (или "Archive" в Xcode) и... идете гулять на 20 минут. Ноутбук гудит как турбина самолета, интерфейс тормозит, работать невозможно.
А потом тестировщик пишет: "Слушай, а ты версию (versionCode) забыл поднять, оно не ставится поверх старого". 🤦♂️
Сборка релизов руками со своего компьютера - это огромная трата времени и источник человеческих ошибок (забыли сменить конфиг с Debug на Release, выбрали не тот сертификат).
Взрослые команды используют CI/CD (Continuous Integration / Continuous Deployment).
⚙️ Как это выглядит у Мидлов:
Вы просто делаете
git push или сливаете Pull Request в ветку develop. ВСЁ. Ваша работа закончена.Дальше начинается магия:
1. В облаке просыпается виртуальный сервер.
2. Он скачивает свежий код.
3. Запускает линтеры и Unit-тесты (о которых мы говорили раньше). Если они упали - сборка отменяется, а вам в Slack/Telegram прилетает по шапке.
4. Если всё зелено — сервер сам увеличивает номер версии, собирает приложение и подписывает его нужным ключом.
5. Готовый файл (APK/IPA) автоматически улетает в Firebase App Distribution, TestFlight или прямо в чатик QA.
🛠 Что нужно знать мобильному разработчику (Инструменты):
• Fastlane: Это абсолютный мастхэв индустрии (работает и для iOS, и для Android). Это инструмент, который превращает клики мышкой по настройкам в простой код. Он умеет всё: от сборки до автоматического создания скриншотов для App Store / Google Play.
• GitHub Actions / GitLab CI / Bitrise: Это те самые «облачные серверы» (Runner'ы), которые будут выполнять ваши команды из Fastlane каждый раз, когда вы пушите код.
💡 Правило чистой среды:
Главный плюс CI/CD - код собирается на «чистой» машине. Это навсегда убивает отмазку -А у меня локально всё собирается и работает!". Если код не собрался на CI - значит, он сломан.
#cicd #automation #fastlane #android #ios #middle #githubactions
👉 @developer_mobila
👍1