AI
prepair.app
Пройти інтерв'ю →
EnglishУкраїнськаРусский
🤖

Junior Android (Kotlin)Питання на співбесіді Android розробника

Junior · без досвіду / до 1 року

Співбесіда Android-розробника крутиться навколо ідіом Kotlin, корутин і життєвого циклу платформи — більшість senior-питань насправді перевіряють, чи розумієте ви, що процес можуть убити будь-якої миті. Нижче — питання, які ставлять найчастіше, кожне з еталонною відповіддю. Junior: базова теорія, визначення та прості практичні кейси.

Теми для підготовки

Можливості мови Kotlin
Корутини та Flow
Життєвий цикл Android
Jetpack Compose
Архітектура і DI
Room, Retrofit і тести

9 питань рівня Junior з відповідями

1

Як працює null safety у Kotlin і чим небезпечні platform types?

Відповідь

Kotlin ділить кожен тип на nullable (String?) і non-nullable (String), і компілятор не дає звернутися до nullable-значення без перевірки, тому NullPointerException здебільшого зникає. Platform types зʼявляються на межі з Java: Kotlin не знає, чи може Java-метод повернути null, і довіряє вам. Саме звідти NPE і приходять — анотуйте Java-API або вважайте їхній результат nullable у місці виклику.

2

Що дають data class і sealed class?

Відповідь

Data class генерує equals, hashCode, toString, copy і деструктуризацію за первинним конструктором, тому це правильний інструмент для значень, які порівнюють і копіюють, — моделі API, стан UI. Sealed class обмежує набір нащадків відомим списком, тому when по ньому вичерпний і компілятор вкаже на забуту гілку. Разом вони чисто моделюють стан екрана: sealed-інтерфейс Loading, Content, Error, а дані несе data class.

3

Що таке структурна конкурентність у корутинах і навіщо потрібен scope?

Відповідь

Структурна конкурентність означає, що кожна корутина належить скоупу і батьківській задачі, тому скасування батька скасовує всіх дітей, а батько не завершиться, доки не завершаться вони. Саме це рятує від фонової роботи, що витекла, характерної для голих потоків. В Android viewModelScope скасовується при очищенні ViewModel, а lifecycleScope — при завершенні життєвого циклу, тож робота зупиняється, коли її результат уже нікуди застосувати.

4

Поясніть диспетчери і що для чого використовується.

Відповідь

Dispatchers.Main працює на UI-потоці, там торкаються вʼю. Dispatchers.IO — великий еластичний пул для блокуючої роботи: диск, мережа, база, — бо такі потоки здебільшого чекають. Dispatchers.Default розміром з кількість ядер і призначений для справжніх обчислень на кшталт парсингу чи сортування. Блокуючий виклик на Default виїдає пул — це найчастіша помилка з диспетчерами.

5

У чому різниця між Flow, StateFlow і LiveData?

Відповідь

Flow — холодний асинхронний потік: він починає видавати значення при підписці, і в кожного підписника своє виконання. StateFlow гарячий і завжди тримає рівно одне поточне значення, що робить його природним для стану UI — новий підписник одразу отримує актуальний стан. LiveData — старіший lifecycle-aware тримач; StateFlow разом із repeatOnLifecycle закриває ту саму задачу рештою інструментарію корутин, тому новий код зазвичай обирає його.

6

Чому зміна конфігурації перестворює Activity і як це пережити?

Відповідь

Поворот, темна тема, зміна мови й розміру вікна знищують і перестворюють Activity, щоб вона підвантажила ресурси під нову конфігурацію. Стан, який має вижити, живе у ViewModel — вона переживає перестворення. Стан, який має пережити ще й смерть процесу, іде в SavedStateHandle, бо систему ніхто не зобовʼязує тримати ваш процес у фоні. Перевірка цього шляху через «Не зберігати активності» відрізняє надійний застосунок від того, що втрачає введені користувачем дані.

7

Що спричиняє рекомпозицію в Jetpack Compose і через що вона гальмує?

Відповідь

Compose перезапускає composable, коли змінюється прочитаний ним State, і пропускає ті, у яких параметри рівні та стабільні. Гальмування йде від нестабільних параметрів — звичайний List або лямбда, що захопила змінюване значення, — вони ламають пропуск і перезапускають великі піддерева. Лікується підняттям стану до найближчого спільного власника, незмінними колекціями чи анотацією @Immutable, а також відкладеним читанням через лямбди, щоб перезапускалася лише фаза layout або draw.

8

Навіщо впровадження залежностей через Hilt замість прямого створення обʼєктів?

Відповідь

DI позбавляє клас знання про те, як зібрати свої залежності, що робить його тестованим і тримає проводку в одному місці замість розкиданих сінглтонів. Hilt генерує граф Dagger і привʼязує час життя компонентів до андроїдних: @Singleton живе із застосунком, @ViewModelScoped — з ViewModel. Практична вигода — підмінити справжній репозиторій фейком у тестах, не чіпаючи продакшен-код.

9

Як влаштований екран з точки зору чистої архітектури?

Відповідь

Шар UI тримає Compose або View плюс ViewModel, яка віддає незмінний стан і приймає події. Шар домену тримає юзкейси і чисті бізнес-правила без імпортів Android — саме тому він тестується звичайним JUnit. Шар даних тримає репозиторії, які обирають між Room і Retrofit та мапять DTO у доменні моделі. Важливий тут напрям залежностей: домен нічого не знає ні про дані, ні про UI.

🦎

Прочитати відповіді недостатньо

На співбесіді ти говориш вголос під тиском. Кем поставить ті самі питання, оцінить кожну відповідь і покаже, що саме підтягнути.

Пройти інтерв'ю Junior Android (Kotlin) →
Безкоштовно · 3 інтерв'ю на місяць

Інші рівні — Android (Kotlin)

Middle Android (Kotlin)Senior Android (Kotlin)Усі питання Android (Kotlin)

Інші спеціалізації

🔍Junior QA Manual🤖Junior QA AutomationJunior Java Backend🐍Junior Python Backend🐘Junior PHP Backend🦫Junior Go Backend🟢Junior Node.js Backend⚛️Junior React Frontend💚Junior Vue Frontend🅰️Junior Angular Frontend