и посмотреть медиа
Kotlin Preguntas de Entrevista
и посмотреть медиа
Preguntas de entrevista para desarrolladores de Kotlin con respuestas.
Preguntas de entrevista para desarrolladores de Kotlin con respuestas.
bot de IA para clonar texto a voz y voz en Telegram. Cree audio utilizando la red neuronal de forma rápida y fácil.
Preguntas de entrevista Kotlin: extensiones, coroutenos, colecciones. Con ejemplos de código y explicaciones para Android y backend.
🤔 В чём отличие обычного метода от extension метода в Kotlin? Extension-функция выглядит как будто добавлена в класс, но на самом деле это статическая функция, которой не требуется менять сам класс. Она даёт синтаксический сахар, не добавляя нового в байткод класса. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
Открыть канал и посмотреть медиа🤔 Как определить изменение скорости работы программы после наших действий? 🟠Profile GPU Rendering Этот инструмент показывает время, затраченное на отрисовку каждого кадра. Использование этого инструмента позволяет выявить "тяжелые" кадры и измерить улучшения после оптимизации. 1⃣Включите режим разработчика на устройстве. 2⃣Перейдите в "Настройки" -> "Для разработчиков". 3⃣Включите опцию "Profile GPU Rendering" и выберите "On screen as bars". 4⃣Запустите ваше приложение и наблюдайте за графиками. Зеленые линии указывают на время отрисовки, и ваша цель - оставаться ниже 16 мс (для 60 кадров в секунду). 🟠Android Profiler Предоставляет набор инструментов для анализа производительности приложения. 1⃣ Откройте Android Studio и запустите ваше приложение. 2⃣Перейдите в "View" -> "Tool Windows" -> "Profiler". 3⃣Выберите ваше устройство и запущенное приложение. 4⃣Используйте вкладки CPU, Memory, Network и Energy для анализа различных аспектов производительности. 5⃣Сравните данные до и после оптимизации. 🟠Benchmarking Создание и использование тестов производительности помогает количественно оценить улучшения. Вы можете использовать библиотеку Jetpack Benchmark для создания и выполнения тестов производительности. 🚩Пример использования Jetpack Benchmark: 1⃣Добавьте зависимости в build.gradle: dependencies { androidTestImplementation "androidx.benchmark:benchmark-junit4:1.1.0" androidTestImplementation "androidx.test:runner:1.3.0" androidTestImplementation "androidx.test:rules:1.3.0" } 2⃣Создайте класс теста: import androidx.benchmark.junit4.BenchmarkRule import androidx.test.ext.junit.runners.AndroidJUnit4 import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class ExampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun myFunctionBenchmark() { benchmarkRule.measureRepeated { // Вызов вашей функции или кода для тестирования производительности myFunction() } } } 🟠Logcat Используйте журналирование для измерения времени выполнения определенных операций. val startTime = System.currentTimeMillis() // Ваш код val endTime = System.currentTimeMillis() Log.d("Performance", "Время выполнения: ${endTime - startTime} мс") 🟠StrictMode StrictMode помогает обнаружить операции, которые могут замедлить работу приложения, такие как работа с сетью или базой данных в главном потоке. if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy( StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .build() ) StrictMode.setVmPolicy( StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() .build() ) } 🟠Systrace Systrace позволяет собирать и анализировать трассировки производительности системы, предоставляя детализированные данные о времени выполнения различных операций. 1⃣Включите режим разработчика на устройстве. 2⃣В "Настройки" -> "Для разработчиков" включите "Enable GPU Debug Layers". 3⃣Запустите команду adb shell am broadcast -a com.android.systemui.screenshot.ScreenshotService.ACTION_SYSTRACE. Ставь 👍 и забирай 📚 Базу знаний
Открыть канал и посмотреть медиа🤔 Что такое сущность Observable? Это объект, который может производить данные (события) и передавать их подписчикам (Observer). Он используется для работы с асинхронными потоками данных. Основные возможности: 1. Генерация данных. 2. Обработка данных через операторы. 3. Управление подпиской и отпиской. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
Открыть канал и посмотреть медиа🤔 Что такое утечки памяти? Это ситуация, когда приложение выделяет память для каких-либо объектов, но затем не освобождает её, даже когда эти объекты больше не нужны. Это приводит к тому, что используемая память накапливается, что может со временем замедлить работу приложения и привести к его аварийному завершению (крашу) из-за нехватки доступной памяти. 🚩Почему происходят утечки памяти в Android? В Android утечки памяти могут возникнуть из-за особенностей работы виртуальной машины (ART или Dalvik), а также из-за того, что сборщик мусора (Garbage Collector, GC) не может освободить память для объектов, на которые по-прежнему существуют ссылки. Это происходит в следующих случаях: 🟠Долгоживущие ссылки Если объект ссылается на другой объект, который больше не нужен, последний не может быть освобождён GC. Например: Статические ссылки, которые продолжают "удерживать" объект. Замыкания (closures), которые хранят ссылки на контекст активности. 🟠Неявные ссылки Некоторые объекты системы Android, такие как Context, View, Handler, хранят ссылки на компоненты приложения (например, Activity), из-за чего их нельзя освободить. 🟠Неправильное использование API Ошибки, такие как регистрация слушателей (listeners) без последующей отписки, использование таймеров, которые продолжают работать даже после уничтожения активности, и так далее. 🚩Пример утечки памяти public class MyActivity extends AppCompatActivity { private static TextView myTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myTextView = findViewById(R.id.my_text_view); myTextView.setText("Hello, Memory Leak!"); } } Исправленный код public class MyActivity extends AppCompatActivity { private TextView myTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myTextView = findViewById(R.id.my_text_view); myTextView.setText("Hello, World!"); } } 🚩Как избежать утечек памяти? 🟠Избегайте долгоживущих ссылок на объекты активности или контекста Не используйте static для объектов, ссылающихся на Context или Activity. Используйте WeakReference, если нужно сохранить ссылку, которая не должна блокировать сборщик мусора. 🟠Отключайте слушателей и callback-методы Если вы регистрируете слушателей (например, через setOnClickListener), обязательно удаляйте их в методах жизненного цикла, например, в onDestroy(). 🟠Осторожно используйте анонимные классы и лямбда-выражения Анонимные классы (например, Runnable, Handler) могут неявно хранить ссылки на внешние классы, что может привести к утечке памяти. 🟠Используйте инструменты для выявления утечек памяти Android Profiler: встроенный инструмент Android Studio для мониторинга использования памяти. LeakCanary: библиотека, которая автоматически обнаруживает утечки памяти в вашем приложении. Ставь 👍 и забирай 📚 Базу знаний
Открыть канал и посмотреть медиа🤔 Как сделать метод потокобезопасным? Использовать ключевое слово synchronized — оно не даёт методу быть вызванным из двух потоков одновременно. Можно также использовать блокировки (Lock) или атомарные типы (AtomicInteger). Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
Открыть канал и посмотреть медиа🤔 Как подключить BroadcastReceiver, чтобы он смог получать сообщения? Подключение BroadcastReceiver в Android состоит из двух основных шагов: создание самого ресивера и его регистрация. Ресивер можно зарегистрировать как статически в манифесте, так и динамически в коде. 🚩Создание BroadcastReceiver Создадим простой BroadcastReceiver, который будет реагировать на определённое событие, например, на получение SMS. import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Сообщение получено!", Toast.LENGTH_SHORT).show(); } } 🚩Регистрация ресивера 🟠Статическая регистрация в манифесте Можно зарегистрировать ресивер в файле AndroidManifest.xml. Это удобно, когда вы хотите, чтобы ресивер всегда был активен и слушал определённые системные события, например, перезагрузку устройства или получение SMS. 🟠Динамическая регистрация в коде Иногда нужно регистрировать ресивер только на время выполнения определённой активности или службы. В этом случае лучше использовать динамическую регистрацию. import android.content.IntentFilter; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private MyBroadcastReceiver myBroadcastReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myBroadcastReceiver = new MyBroadcastReceiver(); } @Override protected void onStart() { super.onStart(); IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); registerReceiver(myBroadcastReceiver, filter); } @Override protected void onStop() { super.onStop(); unregisterReceiver(myBroadcastReceiver); } } Ставь 👍 и забирай 📚 Базу знаний
Открыть канал и посмотреть медиа🤔 Какие есть реализации коллекций? - ArrayList, LinkedList, - HashSet, TreeSet, LinkedHashSet, - HashMap, TreeMap, LinkedHashMap, - PriorityQueue, ArrayDeque. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
Открыть канал и посмотреть медиа🤔 Зачем нужен DiffUtil? DiffUtil — это утилита для быстрого обновления списков в RecyclerView. Она сравнивает старый и новый список и находит различия, чтобы обновлять только изменённые элементы, а не весь список. 🚩Проблема без `DiffUtil` Обычное обновление списка без DiffUtil перерисовывает всё, даже если изменился один элемент. adapter.notifyDataSetChanged() // Полностью обновляет список ❌ 🟠Решение с `DiffUtil` DiffUtil находит различия между старым и новым списком и обновляет только изменённые элементы. class MyDiffUtilCallback( private val oldList: List, private val newList: List ) : DiffUtil.Callback() { override fun getOldListSize() = oldList.size override fun getNewListSize() = newList.size override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition].id == newList[newItemPosition].id } override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition] == newList[newItemPosition] // Используем data class (авто `equals()`) } } 🚩Как использовать `DiffUtil` в `RecyclerView.Adapter`? После создания DiffUtil.Callback, вызываем DiffUtil.calculateDiff() и передаём результат в adapter. fun updateList(newList: List) { val diffCallback = MyDiffUtilCallback(userList, newList) val diffResult = DiffUtil.calculateDiff(diffCallback) userList = newList // Обновляем старый список diffResult.dispatchUpdatesTo(this) // Обновляем только изменённые элементы } 🟠`ListAdapter` – ещё проще! Если используем ListAdapter, DiffUtil уже встроен. class UserAdapter : ListAdapter(DIFF_CALLBACK) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_user, parent, false) return UserViewHolder(view) } override fun onBindViewHolder(holder: UserViewHolder, position: Int) { holder.bind(getItem(position)) // `getItem()` уже работает с `ListAdapter` } companion object { private val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { override fun areItemsTheSame(oldItem: User, newItem: User): Boolean = oldItem.id == newItem.id override fun areContentsTheSame(oldItem: User, newItem: User): Boolean = oldItem == newItem } } } Обновление списка в ListAdapter adapter.submitList(newList) // DiffUtil работает внутри 🚀 Ставь 👍 и забирай 📚 Базу знаний
Открыть канал и посмотреть медиа🤔 Как эффективно изменить данные в списке, состоящем из большого количества View? Для списков с большим количеством View лучше использовать DiffUtil, который вычисляет разницу между старым и новым списками. Это позволяет обновить только те элементы, которые изменились, без перерисовки всего списка, что значительно повышает производительность. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний
Открыть канал и посмотреть медиаSolo los usuarios registrados pueden compartir su opinión.
¡Sé el primero en compartir tu experiencia con este recurso!