
⚡️ Заказывайте в AI-каталоге — получайте скидку!
5% скидка на размещения в каналах, которые подобрал AI. Промокод: TELEGA-AI
Подробнее

РегистрацияВойтиВойти
Скидка 3,5% на первые три заказа
Получите скидку на первые три заказа!
Зарегистрируйтесь и получите скидку 3,5% на первые рекламные кампании — промокод активен 7 дней.
5.7

Kotlin | Вопросы собесов
Поделиться
В избранное
Купить рекламу в этом канале
Формат:
keyboard_arrow_down
- 1/24
- 2/48
1 час в топе / 24 часа в ленте
Количество:
keyboard_arrow_down
- 1
- 2
- 3
- 4
- 5
- 8
- 10
- 15
Стоимость публикации:
local_activity
3 776.22₽3 776.22₽local_mall
0.0%
Осталось по этой цене:0
Последние посты канала
🤔 Как по объекту понять, что он не используется?
Сильная ссылка - это ссылка, которая напрямую указывает на объект и предотвращает его сборку сборщиком мусора.
🚩Основные подходы
🟠WeakReference
Использование слабых ссылок (
WeakReference
) позволяет определить, был ли объект освобожден сборщиком мусора.
🟠ObjectWatcher (в LeakCanary)
LeakCanary использует ObjectWatcher
для отслеживания объектов. Если объект не освобожден, ObjectWatcher
уведомляет об утечке.
import java.lang.ref.WeakReference;
public class MemoryLeakExample {
public static void main(String[] args) {
// Создание объекта
MyObject myObject = new MyObject();
// Создание слабой ссылки на объект
WeakReference<MyObject> weakRef = new WeakReference<>(myObject);
// Удаление сильной ссылки
myObject = null;
// Вызов сборщика мусора
System.gc();
// Проверка, была ли слабая ссылка освобождена
if (weakRef.get() == null) {
System.out.println("Object has been garbage collected");
} else {
System.out.println("Object is still alive");
}
}
static class MyObject {
// Некоторая логика класса
}
}{}
🚩Понимание, что объект не используется
🟠Нет сильных ссылок
Убедитесь, что на объект нет сильных ссылок. Только слабые, мягкие или фантомные ссылки не предотвращают сборку объекта.
🟠Сборка мусора
Если объект становится недоступным через сильные ссылки, сборщик мусора может его освободить.
🟠Проверка с помощью WeakReference
Слабые ссылки могут быть использованы для проверки того, был ли объект освобожден.
Ставь 👍 и забирай 📚 Базу знаний478
12:05
26.07.2025
🤔 Какие есть реализации коллекций?
- ArrayList, LinkedList,
- HashSet, TreeSet, LinkedHashSet,
- HashMap, TreeMap, LinkedHashMap,
- PriorityQueue, ArrayDeque.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
461
19:10
26.07.2025
🤔 Как правильно передать большой объем данных, например, картинку на Activity?
Передача больших данных (например, изображений, видео, JSON) между
Activity
требует оптимального подхода, потому что:
Intent.putExtra()
имеет ограничение по размеру (~1MB).
Передача Bitmap
в Intent
может вызвать TransactionTooLargeException
.
Большие данные лучше передавать через Uri
, БД или FileProvider
.
Неправильный способ (НЕ ДЕЛАТЬ!) – Bitmap
через Intent
val bitmap: Bitmap = getBitmap()
val intent = Intent(this, ImageActivity::class.java)
intent.putExtra("image", bitmap) // ❌ ОПАСНО! Может вызвать Exception
startActivity(intent){}
🚩Лучший способ – передача через `Uri` (`FileProvider`)
Сохраняем изображение во File
и получаем Uri
fun saveBitmapToFile(context: Context, bitmap: Bitmap): Uri {
val file = File(context.cacheDir, "image.png")
file.outputStream().use {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, it)
}
return FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
}{}
Передаём Uri
через Intent
val uri = saveBitmapToFile(this, bitmap)
val intent = Intent(this, ImageActivity::class.java).apply {
putExtra("image_uri", uri.toString())
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // Даем доступ другому Activity
}
startActivity(intent){}
Получаем Uri
в ImageActivity
и загружаем изображение
val uriString = intent.getStringExtra("image_uri")
val uri = Uri.parse(uriString)
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(uri))
imageView.setImageBitmap(bitmap){}
🚩Альтернативный способ – через Базу Данных (`Room`)
Если изображение уже хранится в базе данных (Room
), передаём ID записи, а не сам файл.
val intent = Intent(this, ImageActivity::class.java)
intent.putExtra("image_id", imageId) // Передаём только ID
startActivity(intent){}
🚩Альтернативный способ – через `SharedPreferences` (только путь к файлу!)
Сохраняем путь
val filePath = saveBitmapToFile(this, bitmap).toString()
getSharedPreferences("app_prefs", MODE_PRIVATE).edit()
.putString("last_image", filePath)
.apply(){}
Читаем путь в Activity
val filePath = getSharedPreferences("app_prefs", MODE_PRIVATE)
.getString("last_image", null)
val bitmap = BitmapFactory.decodeFile(filePath)
imageView.setImageBitmap(bitmap){}
Ставь 👍 и забирай 📚 Базу знаний465
12:05
27.07.2025
🤔 Как можно уменьшить количество рекомпозиций помимо side-эффектов?
Использовать remember, derivedStateOf, key и мемоизацию функций. Также важно следить, чтобы State не обновлялся без необходимости, а структура UI не пересоздавалась без причины.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
426
19:10
27.07.2025
🤔 Если профайлер показывает тебе что какой-нибудь фрейм занял 120 миллисекунд, что это значит?
Если профайлер показывает, что рендеринг какого-либо фрейма занял 120 миллисекунд, это означает, что этот фрейм выполнялся слишком долго, что приводит к фризам и лагам в пользовательском интерфейсе.
🚩Разбор проблемы
🟠Что значит "фрейм" в этом контексте?
В Android интерфейс обновляется 60 раз в секунду (частота 60 FPS). Это значит, что каждый кадр (фрейм) должен рендериться не дольше 16,67 мс (1000 мс / 60 FPS).
🟠Почему 120 мс — это плохо?
Если рендеринг кадра занимает 120 мс, то за это время устройство должно было бы нарисовать 7 кадров (120 / 16,67 ≈ 7). Однако оно успело обработать только один, что приводит к заметному подтормаживанию.
🟠Что может вызывать такие задержки?
Тяжёлые вычисления в основном потоке (UI Thread) – например, сложные математические операции, работа с JSON, парсинг файлов.
Долгие операции с рендерингом – сложные векторные изображения, перегруженные
Canvas.draw()
или анимации.
Синхронные вызовы I/O (чтение файлов, базы данных, сети) – если, например, в onDraw()
идёт обращение к диску или базе данных.
Неоптимальный layout – глубокая иерархия ViewGroup
, частые перерасчёты макетов (measure/layout
).
🚩Как исправить?
🟠Перенести тяжёлые вычисления в фоновый поток
Coroutines
, Executors
, WorkManager
🟠Использовать профайлер Android Studio
для поиска "узких мест".
🟠Оптимизировать рендеринг
избегать сложных onDraw()
, использовать ViewStub
, RecyclerView
.
🟠Пересмотреть макет
убрать ненужные ViewGroup
, использовать ConstraintLayout
.
Ставь 👍 и забирай 📚 Базу знаний421
12:05
28.07.2025
🤔 Что нужно сделать в Android-проекте, чтобы начать рисовать UI на экране?
Минимальные шаги:
1. Создать Activity — она является точкой входа для UI.
2. Установить content view — это может быть XML или программно созданный View.
3. Убедиться, что в манифесте указана MainActivity как LAUNCHER.
4. При запуске устройства система вызывает onCreate(), и в этот момент UI "привязывается" к экрану.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
407
19:10
28.07.2025
🤔 Как называется лейаут в котором объекты могут наслаиваться друг на друга?
В Android для наложения (перекрытия) элементов друг на друга используется FrameLayout или Box (в Jetpack Compose).
🚩FrameLayout (в XML и View)
FrameLayout — это контейнер, в котором все вложенные элементы располагаются в левом верхнем углу, но при этом могут накладываться друг на друга.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/background" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Наложенный текст"
android:textSize="24sp"
android:textColor="#FFFFFF"
android:layout_gravity="center"/>
</FrameLayout>{}
🚩Box (в Jetpack Compose)
В Jetpack Compose аналогом FrameLayout
является Box
. Он также позволяет располагать элементы друг над другом.
Box(
modifier = Modifier.fillMaxSize()
) {
Image(
painter = painterResource(id = R.drawable.background),
contentDescription = "Фон",
modifier = Modifier.fillMaxSize()
)
Text(
text = "Наложенный текст",
fontSize = 24.sp,
color = Color.White,
modifier = Modifier.align(Alignment.Center)
)
}{}
Ставь 👍 и забирай 📚 Базу знаний405
12:05
29.07.2025
🤔 Как в runtime делать динамические экраны, которые не были предусмотрены?
– Загружать конфигурацию с сервера (JSON, XML),
– Использовать Fragment/View-фабрики,
– Генерировать UI из описания,
– Использовать Jetpack Compose или RecyclerView с различными ViewType.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
374
19:10
29.07.2025
🤔 Как сборщик мусора понимает что обьект можно уничтожить?
Сборщик мусора (Garbage Collector, GC) в Android (и в JVM) использует анализ ссылок для определения, можно ли уничтожить объект.
🚩Объект считается "мёртвым", если на него нет доступных ссылок
GC работает по принципу "сборки мусора с поиском корней" (Tracing Garbage Collection).
GC ищет "корневые" объекты (Root Objects) – это объекты, к которым точно есть ссылка (например, статические переменные, локальные переменные текущего потока, объекты в стеке).
GC обходит все объекты, к которым есть ссылки (прямые или косвенные).
Если объект не связан с корневыми объектами, он считается "мусором" и удаляется.
fun main() {
var user: User? = User("Alice") // Создаём объект
user = null // Теперь на объект нет ссылок, GC его удалит
}{}
🚩Сборщик мусора использует "Mark & Sweep"
Метод Mark & Sweep – основной алгоритм работы GC.
Mark (Пометка) – GC помечает все достижимые объекты (к которым есть ссылки).
Sweep (Очистка) – GC удаляет непомеченные объекты (на которые нет ссылок).
Root → A → B
→ C{}
Недостижимые объекты (GC их удаляет)
Root → A → B (C больше недоступен)
C (GC удалит!){}
🚩"Сборка поколений" (Generational GC)
Объекты делятся на молодые (Young) и старые (Old)
Young Generation – новые объекты (большинство умирает быстро).
Old Generation – "долго живущие" объекты (Activity, Singleton).
🚩Что GC НЕ удаляет? (Memory Leaks)
Утечки памяти (Memory Leaks) происходят, если на объект осталась ссылка, но он больше не нужен.
class Activity {
var button: Button? = null
}
var activity: Activity? = Activity() // Создаём объект
activity?.button = Button() // `Button` ссылается на `Activity`
activity = null // Activity нельзя удалить из-за ссылки на кнопку!{}
Ставь 👍 и забирай 📚 Базу знаний325
12:05
30.07.2025
🤔В чём отличие Android 5 и 6?
Android 6 (Marshmallow) привнёс:
- Runtime permissions — запрашиваются во время использования, а не при установке.
- Doze mode — экономия батареи при бездействии.
- Поддержка Fingerprint API.
- Поддержка USB Type-C.
- Новый менеджер памяти (Adoptable Storage).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
272
19:10
30.07.2025
close
С этим каналом часто покупают
Отзывы канала
Отзывов нет
Новинки в тематике
Лучшие в тематике
Статистика канала
Рейтинг
5.7
Оценка отзывов
0.0
Выполнено заявок
1
Подписчики:
2.6K
Просмотры на пост:
lock_outline
ER:
15.0%
Публикаций в день:
4.0
CPV
lock_outlineВыбрано
0
каналов на сумму:0.00₽
Подписчики:
0
Просмотры:
lock_outline
Перейти в корзинуКупить за:0.00₽
Комментарий