В прошлом посте я подробно описал процесс поиска работы в Берлине. В течение этого процесса я сталкивался с вопросами, алгоритмическими задачками и Code challenge. В этом посте я распишу свой опыт в этом деле.
Вопросы
После каждого интервью я записывал вопросы, которые удалось вспомнить. Привожу полный список. Ответы не даю, потому что не знаю, правильно ли я отвечал.
Архитектура, паттерны
- Какие паттерны знаете?
- Считаете ли вы Singleton антипаттерном?
- Опишите принципы MVP. Какие еще есть похожие MV*, в чем разница между ними?
- Объясните принцип DI
- Объясните принципы SOLID
- Объясните принципы Clean Architecture
Android
- Как можно выявить проблемы в скорости UI и устранить их?
- Какие проблемы были с использованием Dagger?
- Приходилось ли использовать Guard?
- Что такое multidex?
- Приходилось ли сталкиваться с миграцией с Dalvik на новую технологию ART?
- Начиная с какой версии пишете под Android? Какие были сложности с разницей версий?
- Асинхронные механизмы загрузки в Android
- В чем отличие AsyncTask от Thread?
- Минусы AsyncTask
- Опишите, что такое Activity
- Чем Fagment отличается от Activity?
- Разница между Service и IntentService. Пример использования Service.
- Зачем нужен Headless fragment (без View и с setReatinInstance = true)? Приходилось ли использовать?
- Какие новшества были в последней версии Android?
- Как определяете, какой layout надо использовать для смартфона, а какой для планшета?
- Как в коде определите: планшет это или смартфон?
- Пример использования BroadcastReceiver
- Опишите LifeCycle Activity
- Отличия Serializable и Parcelable
Java
- Контракт hashcode и equals
- Виды коллекций в Java: List, Set, Queue, Stack
- Разница между ArrayList и LinkedList. В каком случае что лучше использовать?
- Принцип работы HashMap и HashSet
- Что такое Generic?
- Когда используем bounded type: "T extends Class" и "T super Class"? Каковы их ограничения.
- Отличия Abstract от Interface, когда какой лучше использовать?
Git
- Разница между pull и fetch
- Разница между merge and rebase
Прочее
- Минусы использования сторонних библиотек
- Что вы будете делать, если ваше решение не совпадает с решением коллег или лида?
- Какие свои качества работы в команде вы можете описать?
- Если бы вы могли вернуться на 3-4 года назад, что бы вы изучали?
- У вас есть команда, какие правила вы установите, чтобы писать тесты?
- Какую книгу вы можете посоветовать? Необязательно про программирование.
- Ваша жена не против релокации?
Алгоритмические задачки
В процессе интервью вам могут дать небольшие алгоритмические задачки, чтобы посмотреть на ваш уровень знания алгоритмов. Может быть и так, что все интервью состоит из одной или нескольких таких задач.
- Реализация merge сортировки из двух списков
- Реверс массива
- Из "abaaeba" получить (a: 4, b:2, e:1)
- Реализация Set с помощью List (методы int count, boolean add, boolean remove)
- Калькулятор, который парсит строки типа "1+2", "1 + 2 * 3 + 4" и возвращает вычисленное значение. Из операторов могут встречаться только + и *.
- Написать Reentrant блокировку
- Посмотреть код, где несколько потоков меняют одну Integer переменную. Сказать, какое значение получится в итоге. Предложить варианты исправления.
Code challenge
Задание, которое вы должны сделать, чтобы показать уровень своего кода и архитектурного мышления. Обычно вам присылают его по почте и дают несколько дней на выполнение.
Я убрал реальные адреса серверов из ссылок, чтобы не палить конторы.
1) Приложение, отображающее список сообщений
На сервере есть json файлы. До них можно добраться по ссылке: https://<server_name>/endpoint/{PAGE}.json, где PAGE - номер файла от 0 до какого-то произвольного числа, например, 15.
Каждый файл - это json массив из 50 сообщений. Сообщение содержит поля id, time и text.
Пример файла:
[ { "id": "7e3122f9-6d50-44bc-b217-44eb7ec5f4ae", "time": 1463451777180, "text": "mz4Snvvtqui3iuVhratnkTuDCejxme4AudtzifsyLszb8bpxmszigepWvgYgqybs8HAGluwcTUescikwapmjbppltvYboy9g" }, { "id": "a2c03a67-1942-456e-vc80-455b5f015af0", "time": 1463454782276, "text": "TRmxoqYyb0AgfrcxbbhjijcqXWkzkto5lGcb5vlp3dQusAgnvdk82N7kajfOsmdlnkhmL8dkdkv" }, … ]
Приложение должно загрузить сообщения с сервера и показать их в списке.
Юзер может удалить сообщение. Предпочтительно - свайпом, но можно и долгим нажатием.
При реализации можете добавлять фичи, чтобы показать свой уровень. Приветствуется чистый и тестируемый код.
Плюсом будет:
- постраничная подгрузка при скролле
- кэширование, чтобы приложение при старте показывало ранее загруженные сообщения
- некоторые сообщения в поле text вместо текста содержат ссылку на картинку, хорошо бы подгрузить и показать эту картинку
Срок выполнения - 5 дней. Про тесты ничего не сказано.
Я от себя добавил:
- action mode, чтобы удалять сообщения
- Retry кнопку, если была ошибка при загрузке данных
- отдельный экран для просмотра сообщения из списка. Переход на экран был с анимацией Activity Transition. Картинка показывалась сначала из кэша в плохом качестве (как в списке), а затем грузилась полная версия.
2) Приложение с картой и поиском
Приложение должно найти и показать на карте 5 объектов, ближайших к вашей текущей локации.
Пример запроса: https://<server_name>/places/search?at=52.5311%2C13.3847&q=restaurant
В at передаем координаты своего местоположения, а в q - поисковый запрос. Результат приходит в json формате.
Пример ответа:
{ "search" : { "context" : { "title" : "Paris", "location": { "position": [48.85692,2.34121], "address": { "city": "Paris", "country": "France", "text": "Paris<br/>France" }, "type" : "urn:nlp-types:place" } }, "results" : { "items" : [ { "position": [52.5031395, 13.3906403], "distance": 0, "title": "Wilhelm & Medne", "averageRating" : 5.0, "category": { "title": "Restaurant", "type": "urn:nlp-types:category", "href": "http://..." }, "icon": "http://...", "vicinity": "Hedemannstrasse 14<br/>10969 Berlin<br/>Germany", "href": "http://...", "type": "urn:nlp-types:place", "sponsored" : true, "id": "276u33d8-efb829f5b9464e5db8f286ff5fbf5643" }, { "position": [52.5046, 13.39087], "distance": 11, "title": "Speakers Corner", "averageRating" : 0.0, "category": { "title": "Restaurant", "type": "urn:nlp-types:category", "href": "http://..." }, "icon": "http://...", "vicinity": "Friedrichstrasse 31<br/>10969 Berlin<br/>Germany", "href": "http://...", "type": "urn:nlp-types:place", "id": "276u33d8-b08d10d141e4405fbfdabbf017571401" } ] } }
Результаты надо показать на карте. Можно использовать Google Maps. Но у этой компании было свое SDK для отображения карты, и я изучил и использовал его. Тем самым показал, что быстро могу разобраться в новом для себя SDK. При этом я заметил несколько вещей, которые можно было улучшить/исправить в SDK и на последующем собеседовании рассказал об этом.
Приоритет - качество. Про тесты ничего не сказано. Срок выполнения - неделя.
3) Приложение, отображающее список квартир.
По запросу на сервер приходит такой ответ:
{ "items": [ { "id": 1, "title": "Schöne Zweiraumwohnung direkt im Grünen", "price":500, "location":{ "address":"Bergmannstraße 33, 10961 Berlin", "latitude":52.488886876519175, "longitude":13.397688051882763 }, "images":[ { "id":1, "url":"https://pictureis24-a.akamaihd.net/pic/orig01/N/278/959/428/278959428-0.jpg/ORIG/resize/600x400/format/jpg" }, { "id":2, "url":"https://pictureis24-a.akamaihd.net/pic/orig01/N/278/959/436/278959436-0.jpg/ORIG/resize/600x400/format/jpg" }, { "id":3, "url":"https://pictureis24-a.akamaihd.net/pic/orig02/N/278/959/437/278959437-0.jpg/ORIG/resize/600x400/format/jpg" }, { "id":4, "url":"https://pictureis24-a.akamaihd.net/pic/orig04/N/278/959/419/278959419-0.jpg/ORIG/resize/600x400/format/jpg" } ] }, … ] }
items - список квартир. Для каждой квартиры указаны название, цена, локация, фото.
Необходимо в списке отобразить все полученные items. Каждая квартира должна показать первое из доступных фото, заголовок, цену и адрес. Примерный макет layout прилагался, но можно и что-то свое придумать.
Каждая квартира в списке может быть добавлена в избранное. Т.е. надо в layout квартиры добавить какую-то метку (например, звездочку), которая будет кликабельна и отобразит статус: в избранном или нет. Информация о том, что квартира добавлена в избранное, должна храниться локально. Т.е. после перезапуска приложения вы должны видеть, какие квартиры были отмечены
В приложении должен быть экран с картой, которая отображает локации всех квартир из списка.
Про тесты ничего не сказано. Срок выполнения - 5 дней.
Я все сделал и добавил несколько фич:
- поддержка альбомной ориентации. В этом случае слева отображался список, а справа - карта.
- нажатие на иконку в action bar покажет/скроет карту
- нажатие на квартиру в списке центрирует ее на карту
- и наоборот, нажатие на маркер квартиры на карте проскроллит список до этой квартиры
4) Выбор машины
Необходимо сделать что-то типа визарда для выбора автомобиля. На первом экране выбирается производитель (марка), на втором - модель, на третьем - год.
Соответственно, на сервере есть три метода, которые вам необходимо вызывать для получения этих данных.
- первый возвращает список производителей (id, name).
- второй принимает выбранный id из первого и возвращает список моделей этого производителя (name)
- третий метод принимает id из первого методы и name из второго и возвращает годы выпуска.
Первые два метода поддерживают постраничную подгрузку - у них есть параметры page и pageSize, и они возвращают totalPageCount.
Каждый экран должен отображать результаты выбора предыдущих экранов. Четвертый экран должен показать все, что в итоге было выбрано на предыдущих трех.
Требования:
- минимальный API - 16
- постраничная загрузка на первом и втором экранах. Размер страницы - 15
- идеально, если переход между экранами будет с анимацией
- сделайте разные layout для четных и нечетных строк списка
- поворот экрана должен работать без проблем
Опционально: на втором экране вместо постраничной загрузки грузите все сразу и добавьте текстовый фильтр по названию модели.
Вся работа по идее должна занять 5-6 часов, но они там понимают, что у вас есть дела/работа и вам дают неделю. Тесты писать необязательно, но если напишете, это будет большим плюсом.
5) Список разных данных
Надо собрать данные с двух разных API и отобразить их в одном списке.
1) Получить 50 репозиториев указанного юзера на github, используя GraphQL (https://developer.github.com/v4/)
2) Получить 50 фото с поиска Flickr. Там обычный json или xml (https://www.flickr.com/services/api/flickr.photos.search.html)
Вывести эти результаты в одном списке, чередуя друг с другом (репозиторий, картинка, репозиторий, картинка, ...).
Изначально экран не должен отображать данные. Есть только кнопка Load, по нажатию на которую начинается загрузка. Последующие нажатия на кнопку должны перезапускать загрузку.
Github данные должны отображаться просто как имя репозитория. Flickr данные должны отображаться как картинка. Нажатие на любой пункт списка должен перезапускать загрузку данных.
Можно писать на Kotlin. Про тесты ничего не сказано. Срок выполнения - 2 рабочих дня.
В этом задании для меня новым было GraphQL. Пришлось повозиться, пока нормально данные с гитхаба пошли. Времени на всякие плюшки в итоге не хватило.
Для всех этих заданий я делал тесты. В качестве архитектуры использовал MVP, а в двух последних еще и Clean Architecture. По возможности старался сделать чуть больше, чем надо, и добавлял какие-то навороты и удобства. Но уложиться в срок и сделать все качественно и красиво - всегда было приоритетом.
Присоединяйтесь к нам в Telegram:
- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance
- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня