All Projects → fylmr → android-interview

fylmr / android-interview

Licence: other
Коллекция вопросов к собеседованию на позицию Android-разработчика на русском языке.

Projects that are alternatives of or similar to android-interview

React Ru Interview Questions
Здесь собраны самые популярные вопросы, задаваемые на русскоязычных собеседованиях разработчика React.js, и ответы на них. Тематика вопросов включает в себя как основы JavaScript и веб-технологий так и глубокое понимание работы React.js
Stars: ✭ 86 (+16.22%)
Mutual labels:  interview, russian
blog
✍️无他术,唯勤读书而多为之,自工。
Stars: ✭ 62 (-16.22%)
Mutual labels:  interview
FAANG-Coding-Interview-Questions
A curated List of Coding Questions Asked in FAANG Interviews
Stars: ✭ 1,195 (+1514.86%)
Mutual labels:  interview
android-interview
The comprehensive Android interview questions and study guide
Stars: ✭ 13 (-82.43%)
Mutual labels:  interview
CRACK JS INTERVIEWS
CRACK JS INTERVIEW
Stars: ✭ 33 (-55.41%)
Mutual labels:  interview
Web-Dev-Helper
Developer Helper where you can find all resources related to open source and software developer resources
Stars: ✭ 33 (-55.41%)
Mutual labels:  interview
career-resources
Some SWE/PM/Designer related career resources for students
Stars: ✭ 154 (+108.11%)
Mutual labels:  interview
coding-interview
Resources for preparing for your next coding interview
Stars: ✭ 27 (-63.51%)
Mutual labels:  interview
java-notes
自己的学习笔记。包含:个人秋招经历、🐂客面经问题按照频率总结、Java一系列知识、数据库、分布式、微服务、前端、技术面试、每日文章等(持续更新)
Stars: ✭ 1,560 (+2008.11%)
Mutual labels:  interview
phpunit-documentation-russian
Russian Documentation for PHPUnit
Stars: ✭ 16 (-78.38%)
Mutual labels:  russian
FCH-TTS
A fast Text-to-Speech (TTS) model. Work well for English, Mandarin/Chinese, Japanese, Korean, Russian and Tibetan (so far). 快速语音合成模型,适用于英语、普通话/中文、日语、韩语、俄语和藏语(当前已测试)。
Stars: ✭ 154 (+108.11%)
Mutual labels:  russian
ukrainian-typographic-layouts
Типографічні розкладки для української та російської мови / Типографские раскладки для украинского и русского языка
Stars: ✭ 69 (-6.76%)
Mutual labels:  russian
CodeTest
some source code for some online judge
Stars: ✭ 40 (-45.95%)
Mutual labels:  interview
algorithm
acwing, leetcode, kickstart, 算法模板, PAT 等等
Stars: ✭ 162 (+118.92%)
Mutual labels:  interview
CodingInterview
Leetcode解题、剑指offer第二版💪💪💪⛷😀
Stars: ✭ 28 (-62.16%)
Mutual labels:  interview
nerus
Large silver standart Russian corpus with NER, morphology and syntax markup
Stars: ✭ 47 (-36.49%)
Mutual labels:  russian
golang-interview
⁉️ Вопросы для собеседования по Go
Stars: ✭ 52 (-29.73%)
Mutual labels:  interview
flask-jobs
Flask-related job opportunities.
Stars: ✭ 74 (+0%)
Mutual labels:  interview
technical-interview
Technical interview questions for Alibaba Travels Co.
Stars: ✭ 306 (+313.51%)
Mutual labels:  interview
libmorph
libmorph rus/ukr - fast & accurate morphological analyzer/analyses for Russian and Ukrainian
Stars: ✭ 16 (-78.38%)
Mutual labels:  russian

Вопросы к собеседованию по Android

Java

  • Виды референсов: https://habr.com/ru/post/169883/

    1. SoftReference — если GC видит что объект доступен только через цепочку soft-ссылок, то он удалит его из памяти, если памяти будет не хватать. Удобно для кеширования.
    2. WeakReference — если GC видит что объект доступен только через цепочку weak-ссылок, то он удалит его из памяти. Применение: WeakHashMap. Это реализация Map<K,V> которая хранит ключ, используя weak-ссылку. И когда GC удаляет ключ с памяти, то удаляется вся запись с Map. Близкое к Андроиду применение в разделе WeakReference этой статьи.
    3. PhantomReference — если GC видит что объект доступен только через цепочку phantom-ссылок, то он его удалит из памяти. После нескольких запусков GC. Особенностей у этого типа ссылок две. Первая это то, что метод get() всегда возвращает null. Именно из-за этого PhantomReference имеет смысл использовать только вместе с ReferenceQueue. Вторая особенность – в отличие от SoftReference и WeakReference, GC добавит phantom-ссылку в ReferenceQueue после того как выполнится метод finalize(). То есть фактически, в отличии от SoftReference и WeakReference, объект еще есть в памяти.
  • Volatile/Atomic

    • volatile помечает объект как доступный для нескольких тредов. Ожидаемо работает только для атомарных операций. Например, операция инкремента не атомарна, из-за чего процесс будет сбоить.
    • Atomic-классы использут compare and swap алгоритм: обновляет значение, только если предыдущее совпадает с ожидаемым old value.
  • Описать Handler

    • Handler - это механизм, который позволяет работать с очередью сообщений между потоками. Он привязан к конкретному потоку и работает с его очередью. Handler умеет помещать сообщения в очередь. При этом он ставит самого себя в качестве получателя этого сообщения. И когда приходит время, система достает сообщение из очереди и отправляет его адресату (т.е. в Handler) на обработку.
  • Абстрактные классы против интерфейсов

    • Переменные в интерфейсе по умолчанию final
    • В абстрактном классе могут использоваться модификаторы доступа, в интерфейсе по умолчанию всё public
    • Можно наследовать несколько интерфейсов, но только один класс

Android

Activity

  • Жизненный цикл Activity

    • OnCreate() Создаётся view.
    • OnStart() Активити становится видно
    • OnResume() Активити становится доступным для ввода пользователя
    • OnPause() Активити видно, но недоступо для ввода пользователя (важно для многооконного режима)
    • OnStop() Активити больше не видно
    • OnDestroy() Активити уничтожается
    • OnRestart() Активити пересоздаётся, вызывается после уничтожения и перед созданием
  • Какие методы вызываются при переходе между активити

    • A: onCreate, onStart, onResume A: (переход) onPause B: onCreate, onStart, onResume A: onStop B: (обратный переход) onPause A: onRestart, onStart, onResume B: onStop, onDestroy иллюстрация процесса
  • Когда onDestroy() вызывается без onPause() и onStop()?

    • Если активити закрывается через метод finish() до начала onStart и onResume.
  • Почему setContentView() располагают в onCreate()

    • Это тяжёлая операция, и выгоднее производить её только единожды, при создании активити.
  • Launch modes

    • Standard При вызове, активити создаётся заново.
    • SingleTop Активити создаётся заново, только если она не вверху активити-стека.
    • SingleTask Стек стирается до момента, пока эта активити не окажется наверху стека.
    • SingleInstance Похож на SingleTask, но при создании активити, она уйдёт в новый таск.
  • Как очистить бэкстек при создании активити

    • Использовать флаг FLAG_ACTIVITY_CLEAR_TOP.
    • Использовать FLAG_ACTIVITY_CLEAR_TASK и FLAG_ACTIVITY_NEW_TASK вместе.
  • Разница между FLAG_ACTIVITY_CLEAR_TASK и FLAG_ACTIVITY_CLEAR_TOP

    • Первый очистит всё, что есть в таске, второй — только до той же активити, что и запускаемая.
  • Как при пересоздании активити сохранить некоторый объект (кроме onSaveInstanceState)

Fragments

  • Жизненный цикл Fragment

    • Жизненный цикл фрагмента
  • Отличия commit(), commitNow(), commitAllowingStateLoss() и commitNowAllowingStateLoss()

    • Если вызвать commit() после onSaveInstanceState(), система выкинет IllegalStateException (подробнее о причинах и процессе).
    • commitAllowingStateLoss() в этом случае не вызовет исключения, но состояние менеджера фрагментов может быть потеряно.
    • commit() помещает транзакцию для выполнения, когда главный поток будет свободен. Для синхронного выполнения висящих транзакций можно использовать метод executePendingTransactions(). Альтернатива этому — метод commitNow(), который исполнит транзакцию сразу, однако не сможет поместить её в backstack (подробнее).

Content provider

  • Зачем нужен Content Provider
    • Позволяет передавать данные между приложениями и процессами. Используется в связке с ContentResolver.

Services

  • Виды Service/IntentService

    • Часть приложения без UI
    • Foreground Выполняется в основном потоке. Во время исполнения показывает уведомление. Пример — аудиоплеер.
    • Background Выполняется в фоновом потоке. Начиная с API 26, приложения в фоне не могут создавать фоновые сервисы, решением в этом случае может быть WorkManager.
    • Bound Клиент-серверный подход: посылаем запросы, получаем результаты.
    • IntentService Создаёт и работает в собственном потоке, выполняет работу из метода onHandleIntent(), после чего останавливается. Операции в onHandleIntent() не могут быть прерваны, связь с основным потоком отсутствует.
  • Жизненный цикл сервисов иллюстрация

  • Метод startService()

    • startService не размножает экземпляры сервиса, а только создает очередь из заданий для него. И если IntentService просто выполнит все задания последовательно, одно за другим, то благодаря классу Service у нас появляется возможность запустить все задачи одновременно в независимых потоках. Достаточно в методе onStartCommand создавать новые потоки для каждой задачи.
  • Остановка сервиса

    • Сервис, создaнный с помощью одноименного класса, будет жить, пока его принудительно не остановят. Сделать это можно либо откуда-то снаружи методом stopService, с указанием интента, которым он был запущен, либо внутри самого сервиса методом stopSelf.
    • Как узнать, что сервис уже все сделал, особенно если мы поставили перед ним сразу несколько задач? В этом нам поможет параметр startId у метода onstartcommand — это порядковый номер каждого вызова сервиса, который увеличивается на единицу при каждом запуске.
    • Создав новый поток, разумно завeршать его методом stopSelf, указывая startId в качестве параметра. С таким параметром ОС не будет сразу завершать сервис, а сравнит переданный идентификатор с тем, который был выдан при последнем запуске onStartCommand. Если они не равны, значит, в очередь была добавлена новая задача и сервис остановлен не будет.
  • Перезапуск сервиса

    • Даже если ОС и внeштатно выгрузит сервис из памяти, есть возможность его запустить заново, кaк только появятся свободные ресурсы.
    • Метод onStartCommand возвращает переменную, указывaющую ОС, как следует поступить с сервисом, если он был принудительно остановлен. Существует три варианта того, как ОС может поступить с сервисом, если он был принудительно завершен:
      • START_NOT_STICKY — не будет перезапущен системой, и все останется так, как есть. Подходит для случая, когда он выпoлняет не самые важные задачи, и приложение может позже при необходимости самостоятельно его перезапустить.
      • START_STICKY — будет запущен заново, но в Intent, который ОС создаст для его запуска, не будет никаких параметров. Такой вариант работает с аудиоплеерами — он должен быть активным в фоне, но не обязательно при этом автоматически начинать проигрывать песни.
      • START_REDELIVER_INTENT — сервис будет запущен с теми же параметрами, которые были при его последнем старте. Это удобно, когда в фоне загружается большой файл и его загрузка была прервана.

Broadcasts

  • Как обновить UI-поток из фонового сервиса

    • Использовать Local Broadcast.
  • BroadcastReceiver в Android 8

    1. Apps that target Android 8.0 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. An implicit broadcast is a broadcast that does not target that app specifically. For example, ACTION_PACKAGE_REPLACED is an implicit broadcast, since it is sent to all registered listeners, letting them know that some package on the device was replaced. However, ACTION_MY_PACKAGE_REPLACED is not an implicit broadcast, since it is sent only to the app whose package was replaced, no matter how many other apps have registered listeners for that broadcast.
    2. Apps can continue to register for explicit broadcasts in their manifests.
    3. Apps can use Context.registerReceiver() at runtime to register a receiver for any broadcast, whether implicit or explicit.
    4. Broadcasts that require a signature permission are exempted from this restriction, since these broadcasts are only sent to apps that are signed with the same certificate, not to all the apps on the device.

Custom Views

ViewModel

  • Краткое устройство ViewModel (AndroidX, исходный код) Диаграмма классов
    • В активити мы получаем ссылку на ViewModel, используя
        ViewModelProvider(this).get(ViewModel::class.java);
    • ViewModelProvider создаёт вью-модель и сохраняет её во ViewModelStore.
    • Параметр, который мы передаём как this при получении ViewModelProvider имеет тип ViewModelStoreOwner, который как раз и хранит ViewModelStore. Если отследить, какие классы наследует наша активити, то видно, что она наследуется от ComponentActivity, которая реализует интерфейс ViewModelStoreOwner.
    • Когда активити пересоздаётся, она сохраняет текущий ViewModelStore, используя свои методы onRetainNonConfigurationInstance() и getLastCustomNonConfigurationInstance(), а также статический класс NonConfigurationInstances.
    • Также активити имеет LifecycleEventObserver, который слушает изменения жизненного цикла и, при уничтожении активити, вызывает getViewModelStore().clear().

Другое

  • Разница между Serializable и Parcelable

    • В первом используется рефлексия, довольно медленный процесс, однако разработчику нужно писать меньше кода. В Parcelable мы описываем только те вещи, которые нужно сериализовать, из-за чего кода становится больше.
  • Виды Intent-ов

    • Implicit (неявный) Вызываете системный интент: отправить СМС, позвонить, открыть карты и так далее
    • Explicit (явный) Вызов других активити внутри приложения
    • Sticky Интент, который остаётся после завершения бродкаста. Например, при подписке на ACTION_BATTERY_CHANGED, мы получим последний посланный интент. Поэтому, если нам нужно только текущее состояние батареи, слушать дальнейшие бродкасты не обязательно.
    • Pending Интент, который может быть исполнен в будущем на правах вашего приложения
  • Может ли приложение работать в разных процессах? Зачем это нужно? Как можно организовать межпроцессорное взаимодействие?

    • Может. Для частей приложения (активити, сервисы, бродкасты и контент провайдеры) надо указать флаг process.
    • +: Получаем больше памяти. Не всё приложение при недостатке памяти будет убито.
    • -: Поскольку каждый процесс живёт в отдельном инстансе Дальвика, делиться информацией сложно. Для этого используются AIDL, интенты, handler-ы, messenger-ы
  • Из-за чего возникает ошибка Application Not Responding (ANR)

    • Когда UI не отвечает несколько секунд. Случается обычно из-за блокированного главного треда.
  • Как обнаружить ANR?

class App : Application() {

    var tick = 0 % Integer.MAX_VALUE

    override fun onCreate() {
        super.onCreate()

        val handler = Handler(mainLooper)

        thread {
            while (true) {
                val lastTick = tick + 1
                handler.post { tick += 1 }
                TimeUnit.SECONDS.sleep(5)

                if (lastTick != tick)
                    Log.d("APP", "ANR")
            }
        }

    }
}

Kotlin

Inline-функции

  • Здесь и далее основано на статье ч.1, ч.2. Примеры кода смотреть в них.

  • Зачем в котлине ключевое слово inline

    • В Котлине функции рассматриваются как любые другие значения: они могут быть переданы в и возвращены из методов, сохранены в переменные или в структуры данных. Чтобы поддержать это, Котлин использует семейство функциональных типов. Тогда, чтобы работать с лямбдами, Котлин создаёт объекты, реализующие интерфейсы Function0, Function1 и так далее.
    • Когда в лямбде нет замыкания (грубо говоря: из лямбды не вызываются переменные и методы, которые не лежат внутри самой лямбды), для её реализации компялтор создаёт синглтон. Но для лямбды с замыканием компилятор вынужен создавать инстанс для каждого вызова лямбды. Если лямбда вызывается в цикле, это может даже привести к OOM (нехватке памяти).
    • В таком случае на помощь приходит ключевое слово inline: оно говорит компилятору, что содержимое лямбды нужно встроить в место её вызова, как будто мы написали код не внутри лямбды, а прямо в теле метода.
  • Для чего нужно ключевое слово reified

    • В Java существует такая концепция, как Type Erasure — стирание типов. Коротко говоря, это проблема, возникающая при работе с дженериками. Из-за неё, например, нельзя сделать проверку типа new ArrayList<String>() instanceof List<String>: в рантайме джава-машина не знает, какие конкретно типы лежат внутри дженерика.
    • Поскольку в Андроиде Котлин использует рантайм Джавы, проблема остаётся: мы не можем проверить, что arrayListOf<String>() is List<String>.
    • Но используя inline функции, мы можем избежать стирания типов с помощью применения модификатора reified к дженерику:
      inline fun <reified T> myGenericFunction(value: T): T {...}
  • crossinline и noinline

    • Поскольку мы встраиваем код лямбды на место вызова, return, написанный в лямбде, закончит выполнение не лямбды, а всей функции. Когда нам это не нужно, мы можем пометить лямбда-параметр функции как crossinline, что запретит нелокальные returnы.
      inline fun function(crossinline nonLocalReturnBlockedLambda: () -> Unit) {...}
    • Порой в inline функции нам нужно не вызвать лямбду на месте, а передать дальше, в другой метод. Тогда лямбда-параметр можно пометить как noinline, и он не будет встраиваться в место вызова.
      inline fun parameterPassedToOtherInlineFunction(lambda1: () -> Unit, noinline lambda2: () -> Boolean) {
          // эта лямбда встроится
          lambda1.invoke()
          // а эта останется лямбдой и будет передана в другой метод
          someNonInlinedLambdaConsumingFunction(lambda2)
      }

Архитектура

TBD

Библиотеки

Moxy

  • Moxy создаёт $$PresenterBinder, хранит хеш-мапы c биндерами в MoxyReflector

RxJava

  • Subjects

    • Publish Subject: Излучает(emit) все последующие элементы наблюдаемого источника в момент подписки.
    • Replay Subject: Излучает(emit все элементы источника наблюдаемого(Observable), независимо от того, когда подписчик(subscriber) подписывается.
    • Behavior Subject: Он излучает(emit) совсем недавно созданый элемент и все последующие элементы наблюдаемого источника, когда наблюдатель(observer) присоединяется к нему.
    • Async Subject: Он выдает только последнее значение наблюдаемого источника(и только последнее). Чтоб его подписчики получили содержание, на сабджекте нужно вызвать onComplete
  • flatMap / switchMap / concatMap / concatMapEager

    • flatMap не следит за порядком получаемых значений. Для каждого из передаваемых ему значений он создаёт свой observable и может прийти в любом порядке.
    • switchMap когда новый объект появлятся из observable выше, он отписывается от остальных — получает только последнее из значений.
    • concatMap похож на flatMap, но сохраняет порядок значений. Но есть и минус: concatMap ждёт заверешения каждого observable перед переходом к следующему
    • concatMapEager похож на concatMap, но выполняет код observable асинхронно. Его недостаток: требует больше памяти, чем остальные методы, поэтому для больших стримов использовать аккуратно
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].