fa
Feedback
Мобильная разработка #1

Мобильная разработка #1

رفتن به کانال در Telegram

Всё о создании приложений под Android и iOS в одном месте. 🔹 Инструменты, библиотеки и ресурсы для ускорения работы. 🔹 Статьи и гайды для разработчиков любого уровня. 🔹 Тренды мобильной разработки и новости индустрии. Реклама @evgenycarter

نمایش بیشتر
3 881
مشترکین
-324 ساعت
-27 روز
+130 روز
آرشیو پست ها
🧠 ИИ-ассистенты помогают писать код, но часто делают это неправильно. Подсказки могут ломать архитектуру проекта, предлагать
🧠 ИИ-ассистенты помогают писать код, но часто делают это неправильно. Подсказки могут ломать архитектуру проекта, предлагать неверные решения или генерировать код, который трудно поддерживать. 🗓 25 марта в 20:00 МСК разберём, почему ИИ-ассистенты ошибаются при генерации кода, как структура проекта влияет на качество подсказок и какие принципы помогают писать ИИ-дружелюбный код. Вы увидите сравнение неправильных и правильных подходов, узнаете, как архитектура, названия и комментарии влияют на работу ИИ и как ускорить разработку мобильных приложений. ➡️Открытый урок проходит в преддверии старта курса «Flutter-разработчик». Принять участие: https://vk.cc/cVBlt8 Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

TUIkit — UI-фреймворк для терминалов Фреймворк, похожий на SwiftUI, для создания пользовательских терминальных интерфейсов на
TUIkit — UI-фреймворк для терминалов Фреймворк, похожий на SwiftUI, для создания пользовательских терминальных интерфейсов на Swift: без ncurses, без зависимостей от C, только чистый Swift. TUIkit позволяет создавать приложения, используя тот же декларативный синтаксис, который вы уже знаете из SwiftUI. Определяйте свой пользовательский интерфейс с помощью View, создавайте представления с помощью VStack, HStack и ZStack, стилизуйте текст с помощью модификаторов, таких как .bold() и .foregroundColor(.red), и запускайте все это в терминале. https://github.com/phranck/TUIkit 👉 @developer_mobila

🍔 Приложение на диете: Как не заставлять пользователя удалять фото ради вашего кода Знакомая ситуация: вы сделали простенько
🍔 Приложение на диете: Как не заставлять пользователя удалять фото ради вашего кода Знакомая ситуация: вы сделали простенькое приложение со списком задач, собираете релиз, а маркетплейс показывает размер - 80 МБ. Пользователь, стоя на улице с мобильным интернетом, видит эту цифру и думает: "Да ну его, скачаю потом (никогда)". Почему приложения «толстеют»? Новички обожают тащить огромные библиотеки ради одной функции. Подключили гигантский фреймворк ради красивой анимации кнопки? Добавили 15 шрифтов и картинки в формате PNG без сжатия? Поздравляю, у вас ожирение. Взрослые проекты борются за каждый мегабайт. И главное оружие здесь - Minification & Shrinking (Минификация и удаление неиспользуемого). 🛠 Как худеют приложения: 🤖 Android (R8 / ProGuard): В файле build.gradle у сеньоров всегда написано:

buildTypes {
    release {
        minifyEnabled true // Включает обфускацию и удаление мертвого кода
        shrinkResources true // Удаляет неиспользуемые картинки и XML
    }
}
Что это делает? 1. Shrinking: R8 анализирует ваш код. Если вы импортировали огромную библиотеку, но используете из нее один метод - R8 просто вырежет остальные 99% библиотеки из финального APK. 2. Obfuscation (Обфускация): R8 переименовывает ваши красивые классы NetworkUserRepository в a.b.c. Это не только уменьшает вес файла, но и усложняет жизнь хакерам (Reverse Engineering). 💥 Обряд посвящения: Каждый разработчик хоть раз в жизни ловил краш на Релизе, потому что R8 переименовал классы для работы с сетью (JSON модели), и парсер сошел с ума. Решение: аннотация @Keep над data-классами. 🍏 iOS (App Thinning & Dead Code Stripping): Apple делает много магии под капотом: 1. Dead Code Stripping: Компилятор LLVM автоматически вырезает функции и классы, которые нигде не вызываются (включается в Build Settings). 2. App Slicing: Когда пользователь скачивает приложение, App Store отдает ему не весь ваш бинарник со всеми картинками мира, а только те ресурсы, которые нужны для его конкретного устройства (например, только картинки @3x для iPhone 15 Pro, вырезая старые @2x). Главное - хранить всё в Assets.xcassets. 💡 Золотое правило: Прогоняйте все растровые картинки через сервисы сжатия (TinyPNG), а лучше - переходите на вектор (SVG / PDF / ImageVectors). Вектор весит килобайты и идеально скейлится на любые экраны. #appsize #optimization #proguard #r8 #android #ios #middle #performance 👉 @developer_mobila

🚀 Подборка полезных IT каналов в Max Системное администрирование, DevOps 📌 https://max.ru/i_odmin Все для системного администратора https://max.ru/bash_srv Bash Советы https://max.ru/sysadminof Книги для админов, полезные материалы https://max.ru/i_odmin_book Библиотека Системного Администратора https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др. 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика GitHub Сообщество 📌 https://max.ru/githublib Интересное из GitHub Базы данных (Data Base) 📌 https://max.ru/database_info Все про базы данных Фронтенд разработка 📌 https://max.ru/frontend_1 Подборки для frontend разработчиков Библиотеки 📌 https://max.ru/programmist_of Книги по программированию https://max.ru/proglb Библиотека программиста https://max.ru/bfbook Книги для программистов Программирование 📌 https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻 Шутки программистов 📌 https://max.ru/itumor Шутки программистов Защита, взлом, безопасность 📌 https://max.ru/thehaking Канал о кибербезопасности https://max.ru/xakkep_1 Хакер Free Книги, статьи для дизайнеров 📌 https://max.ru/odesigners Статьи, книги для дизайнеров Математика 📌 https://max.ru/Pomatematike Канал по математике https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике Вакансии 📌 https://max.ru/progjob Вакансии в IT Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Бонус 📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы

🚀 Как прогнать 37 000 тестов за 12 минут вместо 3 часов? В крупных проектах unit-тесты со временем превращаются в «тыкву»: и
🚀 Как прогнать 37 000 тестов за 12 минут вместо 3 часов? В крупных проектах unit-тесты со временем превращаются в «тыкву»: их становится так много, что CI не выдерживает, а локальный запуск превращается в утопию. Ребята из Альфа-Банка столкнулись именно с этим в своем Android-приложении (800+ модулей) и поделились крутым кейсом оптимизации. В чем была проблема? 1. Инициализация моков. Оказалось, что mockk<Activity>() может занимать больше 1 секунды из-за генерации байт-кода на лету. Второго такого «золотого» вызова нет (кешируется), но... 2. Gradle и изоляция. Gradle запускает тесты каждого модуля в отдельном JVM-процессе. Итог: кеш байт-кода не шерится, и в каждом модуле мы снова и снова тратим секунды на тяжелые моки. 3. Утечки в MockK. Метод clearAllMocks() со временем работает всё медленнее из-за раздувания внутренней карты объектов. Что сделали:Отказались от стандартного распараллеливания Gradle по модулям. Вместо этого написали кастомную таску, которая собирает все тесты в единый classpath. ✅ Ручное дробление. Все тесты разбили на 10 чанков (по количеству ядер/воркеров) и запустили их в 10 долгоживущих JVM-процессах. ✅ Чистка рефлексией. Пофиксили деградацию MockK, принудительно очищая внутренние мапы библиотеки через рефлексию. Результат: Время прогона упало с 180 минут до 12 минут. На пулл-реквестах с учетом импакт-анализа тесты теперь пролетают вообще за минуту. Минусы подхода: Снижается изоляция. Если кто-то забыл сделать unmockkStatic, это может «отстрелить» в совершенно другом тесте, который попал в тот же процесс. Подробный разбор с примерами кода и ссылкой на черновики Gradle-плагина читайте в статье: https://habr.com/ru/companies/alfa/articles/993352/ #Android #Gradle #Testing #Performance #Architecture 👉 @developer_mobila

📶 Что видит пользователь, когда заходит в лифт? (Или почему ваш лоадер всех бесит) Представьте: пользователь едет в метро. И
📶 Что видит пользователь, когда заходит в лифт? (Или почему ваш лоадер всех бесит) Представьте: пользователь едет в метро. Интернет то появляется, то пропадает. Он открывает ваше приложение, чтобы почитать ленту. ❌ Подход Джуна (Прямая труба): Запрос в сеть -> Показ лоадера на весь экран -> Ошибка тайм-аута -> Пустой белый экран. А если пользователь случайно повернет телефон (сменит ориентацию) - лоадер появится снова, потому что Activity пересоздалась и запрос полетел заново. Это боль. ✅ Подход Мидла (Single Source of Truth - SSOT): Открыл приложение -> Мгновенно увидел вчерашние данные из кэша -> В фоне пошел незаметный запрос в сеть -> Лента плавно обновилась свежими данными. Как это работает (Паттерн SSOT): Запомните золотое правило: UI никогда не должен получать данные напрямую из сети! Единственным источником «правды» для экрана должна быть ваша локальная База Данных (БД). 1. Ваш ViewModel / Presenter просто подписывается на изменения в БД. 2. Когда нужно обновить данные, Repository идет в сеть. 3. Скачанные из сети данные сохраняются в Базу Данных. 4. База данных отправляет сигнал в UI: "Эй, у меня новые данные, перерисуйся!". 🛠 Чем пользуются профи: 🤖 Android: Связка Room + Flow (или LiveData). Вы пишете в DAO: fun getNews(): Flow<List<News>>. UI начинает слушать этот Flow. Как только метод из сети сделает insert(newItems) в базу, Room сам протолкнет новые данные в Flow, и UI обновится. Магия! 🍏 iOS: Современный SwiftData (или старая добрая CoreData) + макрос @Query (в SwiftUI) или Combine. Принцип тот же: UI биндится к хранилищу. Вы просто обновляете контекст базы, а списки на экране разъезжаются и анимируются сами. 💡 Совет: Такой подход не только спасает от отсутствия интернета, но и решает проблему пагинации, поиска и шаринга данных между разными экранами (ведь все они смотрят в одну базу). #architecture #offlinefirst #ssot #android #ios #middle #caching 👉 @developer_mobila

👩‍💻 Открытый урок «Знакомство с Kotlin: пишем первый код» 🗓 5 марта в 20:00 МСК 🆓 Бесплатно. Урок в рамках старта курса «
👩‍💻 Открытый урок «Знакомство с Kotlin: пишем первый код» 🗓 5 марта в 20:00 МСК 🆓 Бесплатно. Урок в рамках старта курса «Kotlin Developer. Basic» от Otus. Программа вебинара: ✔Разберем три ключевых преимущества Kotlin: безопасность null, лаконичность и совместимость. ✔Напишем небольшой, но полезный фрагмент, который решает понятную задачу. ✔Ответим на главный вопрос: почему Kotlin — это не просто «улучшенная Java», а другой подход к разработке. Вебинар будет полезен: Начинающим разработчикам, разработчикам на Java, которые хотят писать современный, более безопасный и лаконичный код. 🔗 Ссылка на регистрацию: https://vk.cc/cUZHBX Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

🚀 Подборка полезных IT каналов в Max Системное администрирование, DevOps 📌 https://max.ru/i_odmin Все для системного администратора https://max.ru/bash_srv Bash Советы https://max.ru/sysadminof Книги для админов, полезные материалы https://max.ru/i_odmin_book Библиотека Системного Администратора https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др. 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика GitHub Сообщество 📌 https://max.ru/githublib Интересное из GitHub Базы данных (Data Base) 📌 https://max.ru/database_info Все про базы данных Фронтенд разработка 📌 https://max.ru/frontend_1 Подборки для frontend разработчиков Библиотеки 📌 https://max.ru/programmist_of Книги по программированию https://max.ru/proglb Библиотека программиста https://max.ru/bfbook Книги для программистов Программирование 📌 https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻 Шутки программистов 📌 https://max.ru/itumor Шутки программистов Защита, взлом, безопасность 📌 https://max.ru/thehaking Канал о кибербезопасности https://max.ru/xakkep_1 Хакер Free Книги, статьи для дизайнеров 📌 https://max.ru/odesigners Статьи, книги для дизайнеров Математика 📌 https://max.ru/Pomatematike Канал по математике https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике Вакансии 📌 https://max.ru/progjob Вакансии в IT Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Бонус 📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы

🚀 Хватит собирать билды руками: Введение в CI/CD Знакомая боль: вы закончили крутую фичу, и 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

Подводные камни миграции на Swift 6, о которых стоит знать Swift 6 вводит более строгие проверки изоляции конкурентности и по
Подводные камни миграции на 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

⚡️ Kotlin — современный мощный инструмент с простым синтаксисом. Он подходит как для бэкенд, так и фронтенд-разработки, к том
⚡️ Kotlin — современный мощный инструмент с простым синтаксисом. Он подходит как для бэкенд, так и фронтенд-разработки, к тому же на нем разрабатывают приложения под Android. Присматриваетесь к Kotlin, но еще нет навыков программирования? В OTUS стартовал набор на онлайн-курс «Kotlin Developer. Basic». Всего через 4 месяца вы: ✔Освоите принципы программирования и алгоритмов ✔Узнаете о возможностях языка Kotlin на практике ✔Научитесь использовать популярные структуры данных ✔Опробуете Kotlin в качестве языка бэкенд- и фронтенд-разработки И все это на живых вебинарах с ведущими разработчиками и на практике, где вы разработаете собственный проект для портфолио. Пройдите вступительный тест и успейте занять место со скидкой: https://vk.cc/cUxQm5 Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

🎭 Искусство обмана: Зачем нужны Mock-объекты (и почему без них тесты - мусор) Представьте: вы пишете тест для экрана Логина.
🎭 Искусство обмана: Зачем нужны Mock-объекты (и почему без них тесты - мусор) Представьте: вы пишете тест для экрана Логина. Вы нажимаете «Войти» в коде теста -> идет запрос на реальный сервер -> сервер отвечает 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

🧟‍♂️ Зомби в вашем коде: Почему приложение «пухнет» со временем Бывало такое? Вы открыли экран, закрыли его, а память не осв
🧟‍♂️ Зомби в вашем коде: Почему приложение «пухнет» со временем Бывало такое? Вы открыли экран, закрыли его, а память не освободилась. Сделали так 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

🗣 «У меня не работает»: Почему сеньоры игнорируют ваши сообщения Классическая ситуация: Джун пишет в командный чат: «Парни,
🗣 «У меня не работает»: Почему сеньоры игнорируют ваши сообщения Классическая ситуация: Джун пишет в командный чат: «Парни, тут 500-я ошибка при логине, что делать?» и прикладывает скриншот логов. В ответ - тишина. Или сухое: «Смотри бэкенд». Почему так? Потому что вопрос сформулирован как «Решите проблему за меня». Это раздражает. Опытного разработчика отличает умение ценить чужое время. Если вы хотите быстрый и качественный ответ, используйте алгоритм идеального вопроса: 1. Контекст: Что именно ты пытался сделать? 2. Ожидание vs Реальность: Что должно было произойти и что произошло на самом деле? 3. Самое важное - что ты уже попробовал ❌ Плохо: «Я ничего не трогал, оно само». ✅ Хорошо: «Я погуглил ошибку, проверил токен в хедере (он есть) и перезагрузил сервер. Не помогло». ⏳ Правило 15 минут: Прежде чем дергать коллегу, потратьте ровно 15 минут на самостоятельный поиск решения. 🔵Если спросили раньше - вы ленивый и не хотите думать. 🔵Если залипли на 3 часа и молчите - вы тратите деньги компании впустую. Найдите баланс. 🦆 Метод Утенка (Rubber Duck Debugging): Перед тем как написать вопрос, проговорите его вслух (или напишите в «Избранное» самому себе). Магия в том, что пока вы структурируете проблему словами, вы в 90% случаев сами находите решение, даже не отправив сообщение. 💡 Совет: Никогда не присылайте код скриншотами! Скриншот нельзя скопировать, чтобы запустить или погуглить. Используйте сниппеты или Gist. А у вас в команде есть человек, который задает вопросы лучше всех? 👇 #softskills #career #communication #teamwork #middle #tips 👉 @developer_mobila

🎨 Почему простой список лагает: Скрытый враг FPS (Overdraw) Бывало такое? Вы сверстали красивый экран, но при скролле он иде
🎨 Почему простой список лагает: Скрытый враг FPS (Overdraw) Бывало такое? Вы сверстали красивый экран, но при скролле он идет рывками, а телефон в руках начинает нагреваться. Вы смотрите в код адаптера, там всё чисто. Проблема не в коде. Проблема в 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). Если у контейнера уже есть белый фон, не нужно ставить такой же белый фон вложенному TextView 2. Избегайте прозрачности (alpha). Для GPU просчитать полупрозрачность сложнее, чем просто сплошной цвет. 3. В списках (RecyclerView/LazyColumn) следите, чтобы элементы не рисовали фон там, где его перекрывает картинка. 💡 Задание: Включите этот режим на телефоне и зайдите в популярные приложения (Telegram, YouTube). Посмотрите, как качественно (или нет) они оптимизированы. А потом зайдите в своё. 😉 Знали про эту настройку или всё это время гадали, почему падает FPS? 👇 #performance #ui #fps #android #ios #optimization #middle 👉 @developer_mobila

🤖 Хватит быть «человеком-компилятором» на Code Review Вам знакомо это чувство, когда вы открываете Pull Request коллеги, и в
🤖 Хватит быть «человеком-компилятором» на Code Review Вам знакомо это чувство, когда вы открываете 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 просто не даст сделать коммит. Итог: В репозиторий физически невозможно запушить «грязный» код. 💡Договоритесь с командой о правилах один раз, запишите их в конфиг линтера и забудьте. Code Review должен быть про архитектуру и надежность, а не про красоту текста. У вас в проекте стоит жесткий запрет на варнинги (Treat warnings as errors) или «пусть висят»? 👇 #ci #quality #detekt #swiftlint #ktlint #automation #middle 👉 @developer_mobila

🏎 Гонка потоков: Баг, который исчезает, когда вы пытаетесь его найти Представьте ситуацию: у вас на банковском счете 100$. В
🏎 Гонка потоков: Баг, который исчезает, когда вы пытаетесь его найти Представьте ситуацию: у вас на банковском счете 100$. Вы и ваша жена одновременно (в одну миллисекунду) пытаетесь снять 10$ через разные банкоматы. В теории должно остаться 80$. На практике, из-за Race Condition, может остаться 90$. Банк потерял деньги. 💸 Почему так происходит? Даже простая операция count++ (увеличение счетчика) для процессора - это три действия: 1. Считать текущее значение (100). 2. Прибавить единицу (101). 3. Записать новое значение (101). Если два потока начнут выполнять шаг 1 одновременно, они оба "увидят" 100. Оба прибавят 1 и запишут 101. Одно действие потеряется навсегда. 🐛 Heisenbug (Гейзенбаг): Самое страшное в гонках то, что они часто исчезают, когда вы начинаете дебажить (добавляете print или брейкпоинты), так как это меняет тайминги выполнения потоков. 🛡 Как защититься (Инструменты Мидла): 🤖 Android (Kotlin): 🔵Atomic-типы: Для простых счетчиков используйте AtomicInteger или AtomicBoolean. Они гарантируют атомарность операций. 🔵Mutex (для Coroutines): Это "светофор" для корутин.

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

💉 Dependency Injection: Зачем усложнять, если можно просто написать new? Когда новичок видит код с кучей аннотаций @Inject и
💉 Dependency Injection: Зачем усложнять, если можно просто написать 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

Холодный старт (Cold Start) и как не заставлять пользователя ждать. 🕓 Правило 3 секунд: Почему ваше приложение удаляют сразу
Холодный старт (Cold Start) и как не заставлять пользователя ждать. 🕓 Правило 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: 🔵🤖 Android: Используйте официальный androidx.core:core-splashscreen. Он нативен, красив и работает мгновенно, пока грузится ваш процесс. 🔵🍎 iOS: Сделайте LaunchScreen.storyboard максимально легким. Никакого кода, только статика. 🛠 Как измерить: Не считайте «на глаз»! 🔵Android: В логах (Logcat) ищите строку Displayed. Там система сама пишет: ActivityManager: Displayed com.app/.StartActivity: +850ms. 🔵iOS: В Xcode зайдите в Product -> Profile -> App Launch. Instruments покажут каждый миллисекунду задержки. А вы следите за временем запуска или надеетесь на мощные смартфоны пользователей? 👇 #performance #optimization #android #ios #coldstart #middle 👉 @developer_mobila

🔐 Вы только что подарили хакерам доступ. Где НЕЛЬЗЯ хранить ключи Классическая история: вы пишете пет-проект, используете AP
🔐 Вы только что подарили хакерам доступ. Где НЕЛЬЗЯ хранить ключи Классическая история: вы пишете пет-проект, используете API (например, ChatGPT или Firebase), и пишете прямо в коде: val apiKey = "sk-proj-12345..." Потом git push, и вы идете спать. А утром ваш ключ заблокирован, или с карты списали деньги за чужой трафик. 🤖 Реальность: Боты сканируют публичные репозитории GitHub на наличие строк, похожих на ключи, за секунды после публикации. Удалить коммит не поможет, он уже в кеше у злоумышленников. Как делать правильно (Middle Way): Секреты никогда не должны попадать в систему контроля версий (Git). Они должны жить только локально на вашем компьютере. 🤖 Android: Используйте файл local.properties. Он по умолчанию добавлен в .gitignore. 1. Откройте local.properties и добавьте: MY_API_KEY="ваш_ключ". 2. В build.gradle (app) считайте его и прокиньте в код:

defaultConfig {
    buildConfigField("String", "API_KEY", gradleLocalProperties(rootDir).getProperty("MY_API_KEY"))
}

3. В коде используйте: BuildConfig.API_KEY. 🍏 iOS: Вариантов много, но самый простой для старта: 1. Создайте файл Secrets.xcconfig (или .plist). 2. Сразу же добавьте его в .gitignore. 3. Запишите ключ туда. 4. В настройках проекта (Build Settings) подключите этот конфиг или считывайте файл программно. 🛡 Золотое правило: Если вы клонируете свой проект на чистый ноутбук, он не должен собраться сразу. Он должен попросить вас создать локальный файл с ключами. Это не баг, это безопасность. Признавайтесь, случалось случайно комитить пароли или токены? 👇 #security #android #ios #git #tips #middle #safety 👉 @developer_mobila