Що питають на співбесіді Android Developer? У кожної продуктової ІТ-компанії свій сценарій технічного інтервʼю, який залежить від вимог та культури компанії. Цього разу досвідом проведення співбесід ділиться компанія Lift, бізнес з екосистеми Genesis, що розробляє однойменний застосунок для фото- та відеоредагування. Що з Computer Science має обовʼязково знати Android Developer, та як має готуватися інтервʼюер? Яких кандидатів шукають у компанії, та яких помилок припускаються спеціалісти, відповідаючи на питання? Олесь Никитюк, Senior Android Developer у Lift, поділився питаннями, кейсами та порадами, як підготуватися до співбесіди.
> Як проходить співбесіда в Lift
> Що питають на співбесіді Android Developer
> Red flags
> Перелік питань на співбесіду для Android Developer (Junior, Middle, Senior)
Як проходить співбесіда в Lift
Технічне інтервʼю в компанії Lift складається з трьох частин. Спершу ми розповідаємо про компанію та продукт, цікавимося, чи кандидат зміг подивитися застосунок, чи користувався, що він про нього думає, чи є зауваження. Відповіді на першому етапі можуть багато сказати про його мотивацію працювати у нас.
Далі розмовляємо з кандидатом про його досвід. На цьому етапі оцінюємо софт-скіли. Запитуємо, що його мотивує в роботі, чим він хоче займатися у майбутньому, у якому напрямку розвиватися. З якими викликами та проблемами стикався на попередніх проєктах, як їх вирішував. Останнє питання багато говорить про кандидата: він схильний аналізувати та виправляти помилки, або ж розчаровується та уникає цих проблем.
За нею йде частина, де ми спілкуємося з кандидатом про його досвід в технічних питаннях, і наскільки це відповідає нашим очікуванням. Сюди входять питання з Computer Science, Android SDK ta Kotlin, архітектури тощо. Додатковий блок — наша специфіка, а саме робота з низькорівневою графікою та медіа. Якщо у кандидата був такий досвід, то ми про це спілкуємося. Це не обов'язково, але буде великою перевагою.
Коли компанія відкриває нову позицію, я готую вимоги до кандидата та планую, які завдання він закриватиме в перші місяці роботи. Перед кожною співбесідою вивчаю CV, переглядаю відповіді на питання з прескринінгу, який провів рекрутер. Ця інформація дає можливість зробити певні висновки про потенційні сильні та слабкі сторони кандидата, які я стараюся перевірити на самій співбесіді.
Що питають на співбесіді Android Developer
Computer Science
У першу чергу ми ставимо питання з теорії Computer Science. Ці знання відіграють ключову роль в оптимізації швидкості роботи застосунків, коду, ефективної роботи з даними та використанням ресурсів. Зокрема алгоритми та структури даних — це база для розуміння основних принципів та концепцій розробки.
В Android-ком'юніті поширене твердження, що алгоритми вивчають в університетах і одразу забувають, адже ці знання нерелевантні. За моїми спостереженнями, більшість кандидатів розуміє цю тему лише на рівні популярних методів сортування, таких як Bubble Sort. Нам важливо, щоби кандидат усвідомлював, для чого взагалі потрібні алгоритми, як оцінювати їхню складність, як порівняти між собою та обрати той, що підходить для конкретного завдання. Більшість алгоритмів вже реалізовані у стандартній бібліотеці, і загалом їх не потрібно писати з нуля. Проте розуміти — критично важливо.
Така ж ситуація зі знаннями про структури даних. Більшість кандидатів використовує 2-3 найбільш популярні типи. Хоч вони й ефективні, але підходять не для всіх завдань. На співбесідах питаю, чи працював кандидат з чимось іншим, за яким принципом обрав, чи розуміє, які переваги. Часто по цій темі кандидати мають суттєві прогалини. Наприклад, є задача спроєктувати свій стек. Це доволі проста структура даних, але багато кандидатів навіть не можуть нормально пояснити, як працює стек.
Kotlin, Android SDK
Наступна тема стосується Kotlin, Android SDK, зокрема Concurrency та Coroutine. Це можуть бути загальні питання, як взагалі працює система Android, як вона взаємодіє з застосунком, або щодо оновлень. Зокрема, Android Jetpack Compose – це майбутнє, і треба знати, чи кандидат розуміє, як з ним працювати. Досвід з Compose буде великим плюсом. Також цінується вміння працювати з мультипоточним кодом, розуміння Concurrency тощо. Часом кандидати не дуже обізнані в оновленнях. Наприклад, в Kotlin давно з'явилися value-класи, але досить рідко зустрічаю тих, хто з ними працював, розуміє механіку та переваги.
Питання про ООП, принципи SOLID та патерни ми не ставимо. По-перше, вони дуже «заїжджені» на співбесідах, і всі на них очікують. По-друге, якщо у кандидата є прогалини у цих знаннях, це точно буде видно в ході співбесіди. Натомість я стараюся оцінити аналітичні здібності кандидата, побачити, як добре він розуміє тему, чи заглиблювався в неї.
Наприклад, якщо ми говоримо про корутини, які всі зазвичай люблять і бачать лише переваги, я питаю, коли їх не варто використовувати. Відповідь покаже, чи добре кандидат розуміє принципи, за якими вони працюють, та аналізує, для чого вони потрібні. Спілкуючись про Concurrency, можна спитати, коли доцільно використовувати декілька потоків, а коли краще обійтись одним. Це теми для розмов зі спеціалістами рівнів мідл та сеньйор.
У джуніорів варто перевірити розуміння extension функцій. Їх також усі люблять та використовують, але чи знає кандидат, коли краще використовувати extension функцію, а коли написати звичайну функцію в класі?
Архітектура
Наступний блок — питання з архітектури. Як краще спланувати архітектуру для UI та обрати один з підходів (MVP, MVVM, MVI)? Який з них краще підходить для Compose? Коли доцільно виносити проєкт на модулі? Як їх правильно структурувати? Також питаємо по Gradle, чи кандидат знає, як збирається проєкт, як його можна оптимізувати у збірку? Для чого там використовується ProGuard і які його плюси?
Робота з медіа
В застосунку Lift ми працюємо з низькорівневою графікою та медіа: декодуємо, перетворюємо та створюємо відео. Це доволі вузька ніша, яка потребує специфічних знань. Якщо у кандидата є відповідна експертиза, ми спілкуємось на цю тему.
Практичні задачі
В ході співбесіди я даю також декілька практичних завдань. Зазвичай вони стосуються потенційних робочих проблем або тих завдань, з якими кандидат працюватиме у цій ролі. Усі вони усні, їх можна вирішити доволі швидко.
Наприклад, я пропоную спроєктувати кешування зображень. Коли кандидат обміркує, як це зробити та видасть якісь результати, я додаю певні вимоги, що змінилися. Наприклад, тепер нам потрібно видавати зображення за іншим критерієм або попередньо обробляти їх. Це завдання дає зрозуміти, на скільки рішення, що пропонує кандидат, гнучкі. Адже робота в стартап-команді передбачає динамічне середовище, в якому відбуваються постійні зміни.
Тестового завдання в Lift немає. Водночас іноді після технічної співбесіди ми можемо дати додаткове завдання, коли є сумніви. Зазвичай це якась задача, з якою кандидат стикнеться в перші тижні роботи.
Софт-скіли
Найголовніші скіли для джуніора — бажання вчитися, мотивація. Якщо є база з Computer Science, він може швидко опанувати будь-які технології. Для мідла важлива самостійність, щоби він не приходив розбирати кожне питання та дрібне завдання, як джун. Мідл має справлятися з більшістю завдань самостійно. Сеньйор має вміти вирішувати будь-який тип задачі та хотіти працювати в цьому напрямі. Спеціалісти цього грейду часто починають втомлюватися та замислюватися про світчинг до іншого напряму розробки. Важливо, щоби сеньйору щиро подобалося те, чим він займається, а також, щоби він міг бути ментором для інших грейдів.
Перелічені теми і питання загалом підходять для всіх грейдів. Різниця тільки в тому, з яких питань я починаю та їхньої глибини. Наприклад, якщо джуніор добре відповідає на прості питання, я переходжу до складніших і намагаюся визначити його рівень. Якщо це сіньор, я не буду починати із простих питань, а братиму складніші і буду заглиблюватися в них.
Загалом співбесіда для різних грейдів проходить на схожим сценарієм, відрізняється по софтовій частині. Наприклад, у Джуна ми більше питаємо, як він навчається, звідки бере інформацію, що йому цікаво і так далі. У сеньора ми більше питаємо його плани на розвиток, його досвід, наскільки він мотивований, наскільки йому цікаво буде працювати з тим, чим ми займаємося, з тими технологіями, які у нас.
Red flags
1. Мати прогалини в Computer Science
Знання алгоритмів та структур даних — це база, без якої розробнику неможливо розвиватися далі. Важливо не просто «погуглити» ці теми перед співбесідою, щоби назвати інтервʼюеру якомога більшу кількість методів та типів, а саме зрозуміти, як вони працюють, які переваги мають, як їх оцінювати, як обрати серед них потрібний. У відкритому доступі є безліч матеріалів з Computer Science, тож раджу кандидатам підтягнути цю тему.
2. Не слідкувати за оновленнями
Kotlin — головний інструмент Android Developer. Як мова програмування, так і бібліотеки постійно розвиваються, тому за цим варто слідкувати. Команда Lift використовує сучасний технологічний стек (Android Jetpack, Jetpack Compose, Room, DataStore, Media3, Ktor, Hilt). Якщо кандидат на попередньому місці роботи працював із застарілими бібліотеками та інструментами, то ми очікуємо, щоби він як мінімум цікавився оновленнями та знайомився з ними на пет-проєктах.
3. Не вміти працювати з документацією
Вивчаючи технологію, важливо читати документацію. Це звучить очевидно, але чимало кандидатів вивчають Android SDK та Kotlin за прикладами та відео в ютубі. Краще мати терпіння та читати першоджерела. До того ж документація до цих технологій, зокрема Kotlin-бібліотек, корутин, — чудово описана, і читати її — приємно і ненудно.
4. Слабкі софт-скіли
Сильні «мʼякі навички» кандидата можуть нівелювати прогалини по технічній частині. Мотивований спеціаліст, який швидко вчиться і має бажання розвиватися, зможе надолужити брак досвіду з певними технологіями, і команда допоможе йому в цьому. І навпаки — якими б потужними не були технічні навички, якщо з людиною некомфортно спілкуватися, він навряд отримає офер.
У нас були кейси, коли кандидат був не готовий брати участь у регулярних daily, адже в цей час ходить в зал, або мав власне бачення на архітектуру і непохитну позицію щодо цього. Людина має добре вписатися в команду, щоби разом досягати амбітних цілей, і без софт-скілів досягти цього неможливо.
5. Відсутність мотивації
Іноді по кандидату видно, що він вигорів на попередній роботі та не має мотивації розвиватися. Для нас важливо, щоби спеціаліст хотів працювати саме на цій ролі та позиції, любив Android-розробку і щиро цікавився цим напрямом. Наприклад, на співбесіди приходили кандидати, які на питання про подальші плани казали, що хочуть вивчати iOS. Така позиція не надихає найняти саме його.
Перелік питань на співбесіду для Android Developer (Junior, Middle, Senior)
Computer Science
1. Що таке алгоритм сортування? Назвіть кілька різних алгоритмів сортування та поясніть, чому вони ефективні.
2. Як працює BFS та DFS? Як ці алгоритми можуть бути застосовані в розробці?
3. Що таке рекурсивна функція? Наведіть приклади, коли її доцільно використовувати?
4. Як ви розумієте поняття складності алгоритмів? Які методи визначення складності ви знаєте?
5. Які відмінності Heap та Stack памʼяті в Android-застосунках?
6. Що таке компіляція та інтерпретація? Чим вони відрізняються?
7. Як працюють механізми обробки винятків в Android-застосунках?
8. Як визначити та керувати залежностями між компонентами? Які інструменти використати для цього?
Структури даних
9. Які структури даних ви використовуєте? Чи є серед них не стандартні (ArrayList, HashMap)? В чому їхня перевага?
10. Чому так часто використовується HashMap? Яка складність операцій? Коли краще використати іншу структуру даних?
11. У чому відмінність між HashMap, ArrayMap та SparseArray? Наведіть приклади, коли краще кожну з них використовувати?
12. Як працює Stack? В чому відмінність від черги (Queue)?
13. Як працює ArrayDeque? Коли він ефективніше ніж ArrayList?
Kotlin
14. Чим система типів в Kotlin відрізняється від Java?
15. Що таке autoboxing і як він впливає на продуктивність?
16. Для чого потрібне ключове слово const?
17. Які переваги дає sealed interface/class?
18. Що таке ключове слово object, як відбувається ініціалізація? Який його життєвий цикл?
19. Як можна додати свій оператор до класу? Наприклад, оператор +.
20. Коли використовувати extension function, а коли member function? Яка відмінність?
21. В яких випадках краще використовувати extension function для розширення функціонала свого класу/інтерфейсу?
22. Як працюють inline функції? Які нові можливості вони дають?
23. В чому особливість value class?
24. Як досягається імутабельність колекцій в стандартній бібліотеці Kotlin?
25. В чому перевага Sequence, коли їх краще використовувати? Як це впливає на швидкодію?
26. В чому проблема інтерфейсів List, Map, Set в контексті імутабельності? Чи можна завжди очікувати що ці структури даних будуть незмінними?
27. Практичне завдання: реалізувати клас DataSize (KB MB GB), що описує розмір даних.
Concurrency
28. В чому різниця між процесом та потоком?
29. До якої памʼяті має доступ потік? Які проблеми це створює?
30. Для чого потрібна синхронізація потоків?
31. Які ви знаєте способи синхронізації?
32. Яка поведінка у synchronized?
33. Скільки потоків можуть виконуватись в одному synchronized блоці? Який порядок входу в цей блок?
34. В чому різниця між Atomic та Volatile? В які гарантії дає кожен з них? Що таке CAS?
35. Як працює Lock? В чому особливість ReadWriteLock?
36. Практичне завдання: є Executor, на якому паралельно виконуються задачі. Задача може завершитись успішно, або з помилкою. Як можна рахувати кількість успішних і неуспішних задач?
Coroutines
37. В чому переваги корутин?
38. Для яких задач недоцільно використовувати Kotlin Coroutines?
39. Як можна створити корутину?
40. Який життєвий цикл корутини?
41. Що відбувається з корутиною, якщо в ній кинути Exception?
42. Від чого залежить ця поведінка?
43. Для чого потрібен CoroutineScope?
44. Як він повʼязаний з CoroutineContext?
45. Що з себе представляє CoroutineContext?
46. Чи можна додати свій тип в CoroutineContext?
47. Як працює CoroutineDispatcher?
48. Як можна створити свій CoroutineDispatcher?
49. Практичне завдання: є CoroutineDispatcher який використовує лише 1 потік. Як можна на ньому виконувати декілька задач, які в циклі while(true) виконують роботу?
50. Які є способи синхронізації корутин?
51. Для яких задач краще підходить Mutex, а яких Channel?
52. Що з себе представляє Flow? Чим він відрізняється від SharedFlow та StateFlow?
53. Яка різниця між операціями flatMapConcat, flatMapMerge, flatMapLatest?
54. Чи є переваги у Flow, SharedFlow та StateFlow над Channel?
Android SDK
55. Які є способи взаємодії між застосунками в Android?
56. В чому різниця між Implicit та Explicit Intent?
57. Чому в Android використовується Bundle? В чому його обмеження? З чим це повʼязано?
58. Як працює Main потік?
59. Поясни взаємодію Looper та Handler?
60. Чи можна створити свій потік з Looper?
61. Які є способи збереження даних в Android?
62. Що таке SurfaceView як він працює? Для яких задач його можна використовувати?
63. Чим відрізняється TextureView від SurfaceView?
64. Що таке WorkManager і в яких випадках його доцільно використовувати?
Compose
65. Чим Jetpack Compose відрізняється від View системи? Які його переваги?
66. Що таке рекомпозиція?
67. Як Composable function знає, коли робити рекомпозицію?
68. Як можна зберігати стан між рекомпозиціями?
69. Які є вимоги до аргументів функції, щоби вона була skippable?
70. Для чого використовується анотація @Immutable та @Stable?
71. Що таке State Holder?
72. Як можна виконати side effect в Compose?
73. Що буде, якщо виконувати side effect безпосередньо в тілі composable функції?
74. Як задаються та передаються стилі?
Media
75. Як відбувається кодування/декодування зображень в Android? Як це можна оптимізувати?
76. Як можна відтворити аудіо не використовуючи MediaPlayer чи ExoPlayer?
77. Як відбувається декодування відео? Як працює MediaCodec?
78. Для чого використовується MediaMuxer?
79. Як можна транскодувати відео інструментами з Android SDK?
OpenGL
80. Що таке шейдер? Які типи шейдерів є? Як вони працюють?
81. Що таке GPU і як він працює? В чому переваги GPU над центральним процесором?
82. Як можна щось намалювати за допомогою GPU?
83. Які особливості використання OpenGL в Android?
84. Які основні компоненти архітектури графічного процесора?
85. Які ви знаєте основні типи шейдерів? Як вони використовуються у програмуванні графічних процесорів?
Architecture
86. Якому підходу надаєте перевагу для роботи з UI? (MVP, MVVM, MVI, etc)
87. Який підхід буде краще працювати з Compose?
88. Як ви бачите структуру проєкту загалом?
89. Коли проєкт доцільно ділити на модулі? Як ви будете це робити?
90. Як можна зменшити розмір APK?
91. Для чого використовується R8?