Kotlin | Вопросы собесов
2.57K subscribers
28 photos
960 links
Download Telegram
🤔 Для чего нужен data class?

Data class в Kotlin используется для создания классов, предназначенных для хранения данных. Такие классы автоматически генерируют полезные методы, такие как `equals()`, `hashCode()`, `toString()`, и `copy()`, что упрощает работу с объектами. Data классы минимизируют количество шаблонного кода, необходимого для определения моделей данных. Это делает их идеальными для создания простых контейнеров данных, таких как модели в приложениях.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥1
🤔 Как на экране одновременно отобразить два одинаковых фрагмента?

Чтобы одновременно отобразить два одинаковых фрагмента на одном экране в Android-приложении, вам нужно добавить два экземпляра фрагмента в разные контейнеры в макете активности. В этом случае каждый фрагмент будет работать независимо, даже если они используют один и тот же класс.

1⃣Создайте макет для активности
Который будет содержать два контейнера для фрагментов. Обычно это делается с помощью FrameLayout или LinearLayout.
<!-- res/layout/activity_main.xml -->
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<FrameLayout
android:id="@+id/fragment_container_1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />

<FrameLayout
android:id="@+id/fragment_container_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>


2⃣Создайте класс фрагмента
Класс фрагмента, который будет использоваться для отображения обоих экземпляров.
class MyFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Замените fragment_my на свой макет фрагмента
return inflater.inflate(R.layout.fragment_my, container, false)
}

companion object {
fun newInstance(): MyFragment {
return MyFragment()
}
}
}


3⃣Добавьте фрагменты в активность
Теперь добавьте два экземпляра фрагмента в вашу активность.
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container_1, MyFragment.newInstance())
.commit()

supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container_2, MyFragment.newInstance())
.commit()
}
}
}


4⃣Создайте макет для фрагмента
Это может быть любой макет, который вы хотите использовать.
<!-- res/layout/fragment_my.xml -->
<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- Здесь добавьте элементы вашего фрагмента -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a fragment!"
android:layout_gravity="center" />
</FrameLayout>


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 В чем преимущество Kotlin для разработки под android?

Kotlin предоставляет более лаконичный и безопасный синтаксис по сравнению с Java, что уменьшает количество шаблонного кода. Он встроен в экосистему Android и полностью совместим с существующими Java-библиотеками. Kotlin поддерживает функции, такие как null-безопасность, корутины для асинхронного программирования и расширяемость, что повышает производительность разработки. Кроме того, Kotlin позволяет писать код быстрее и с меньшим количеством ошибок.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай
📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥1
🤔 В каких случаях не рекомендуется использовать корутины и RxJava?

Корутины и RxJava не стоит использовать, если асинхронность не даёт преимуществ, а код становится сложнее, например, для простых и быстрых задач или в проектах с ограниченными ресурсами.

🚩Когда не рекомендуется использовать корутины:

🟠Простые задачи:
Если задача достаточно проста и не требует сложного асинхронного управления, использование корутин может добавить ненужную сложность. Простое чтение файла или выполнение небольшого сетевого запроса.
🟠Высокая сложность и неопытность:
Если команда разработчиков не имеет достаточного опыта работы с корутинами, это может привести к ошибкам и трудностям в отладке. Новая команда, которая только начинает изучать корутины.
🟠Низкоуровневые задачи:
Для задач, которые требуют низкоуровневого управления потоками или высокопроизводительных вычислений, корутины могут не подходить. Реализация собственного планировщика потоков или системы для управления реальными временными задачами.

🚩Когда не рекомендуется использовать RxJava:

🟠Избыточная сложность:
RxJava добавляет уровень абстракции, который может быть избыточным для простых задач. Обработка одного или двух простых асинхронных событий.

🟠Проблемы с производительностью:
RxJava может добавлять накладные расходы на производительность из-за создания большого количества объектов и обработки событий. Высокочастотные события, такие как обработка пользовательского ввода в реальном времени.

🟠Сложность отладки и сопровождения:
RxJava может быть трудно отлаживать и сопровождать из-за сложности потоков данных и операторов. Сложные цепочки операторов, которые трудно тестировать и отслеживать.

🟠Малая команда разработчиков:
Если команда небольшая и не имеет достаточного опыта работы с функциональным программированием, использование RxJava может привести к проблемам в поддержке кода. Стартап с небольшой командой, где нет возможности инвестировать много времени в изучение RxJava.

🟠Когда корутины могут быть нецелесообразны:
Предположим, что у вас есть простое приложение, которое выполняет один сетевой запрос при запуске и показывает результат на экране. Использование корутин здесь может добавить ненужную сложность.
fun fetchData() {
// Простой сетевой запрос без использования корутин
val result = simpleNetworkRequest()
displayResult(result)
}


🟠Когда RxJava может быть нецелесообразен:
Предположим, что у вас есть простое приложение, которое просто считывает данные из базы данных и отображает их. Использование RxJava здесь может быть избыточным.
public void loadData() {
// Простой запрос к базе данных без использования RxJava
List<Data> data = database.queryData();
displayData(data);
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔5👍31🤯1
🤔 Для чего нужны фрагменты, если есть Activity?

Фрагменты используются для создания многоразовых компонентов пользовательского интерфейса, которые могут быть встроены в различные Activity. Они позволяют более гибко управлять интерфейсом и разделять его на отдельные части, что улучшает модульность приложения. Фрагменты могут быть динамически добавлены или удалены во время выполнения, что упрощает адаптацию интерфейса под разные устройства. В отличие от Activity, фрагменты могут совместно использовать ресурсы внутри одного экрана.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍1🤯1
🤔 Какие есть преимущества у корутин перед RxJava?

🟠Простота и читабельность кода:
Корутины позволяют писать асинхронный код, который выглядит и читается как синхронный. Это упрощает понимание и сопровождение кода.
suspend fun fetchData(): String {
val data = networkRequest() // Выглядит как обычный синхронный вызов
return processData(data)
}

fun main() = runBlocking {
val result = fetchData()
println(result)
}

Observable<String> fetchData() {
return networkRequest()
.map(data -> processData(data));
}

fetchData()
.subscribe(result -> System.out.println(result));


🟠Управление состоянием и контекстом:
Корутины интегрированы с контекстами (например, Dispatchers), что позволяет легко переключаться между потоками и управлять жизненным циклом.
withContext(Dispatchers.IO) {
val data = networkRequest()
withContext(Dispatchers.Main) {
updateUI(data)
}
}

networkRequest()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(data -> updateUI(data));


🟠Легкость отмены:
Корутины предоставляют простой и мощный механизм для отмены выполнения, что делает их удобными для задач, которые могут быть прерваны.
val job = launch {
val data = networkRequest()
updateUI(data)
}

// Отмена выполнения
job.cancel()

Disposable disposable = networkRequest()
.subscribe(data -> updateUI(data));

// Отмена выполнения
disposable.dispose()


🟠Меньшие накладные расходы:
Корутины, как правило, имеют меньше накладных расходов по сравнению с RxJava, поскольку они не создают объекты для каждого оператора и события.

🟠Поддержка синтаксиса языка:
Корутины являются встроенной функцией языка Kotlin, что обеспечивает лучшую интеграцию и поддержку на уровне компилятора.

🟠Потокобезопасность:
Корутины обеспечивают встроенные механизмы для работы с потоками, такие как Mutex, Channel и Flow, что упрощает написание потокобезопасного кода.
val mutex = Mutex()

suspend fun safeUpdate() {
mutex.withLock {
// Критическая секция
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍111
🤔 Для чего нужны сервисы?

Сервисы в Android используются для выполнения длительных фоновых задач, которые не требуют взаимодействия с пользователем. Они продолжают работать даже после сворачивания приложения или его завершения. Сервисы могут быть как привязанными (работают в контексте приложения), так и независимыми (работают в фоновом режиме). Их основной задачей является выполнение операций, таких как загрузка данных, воспроизведение музыки или синхронизация.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥5
🤔 Что такое Intent?

Intent – это механизм в Android, который используется для связи между компонентами приложения (Activity, Service, BroadcastReceiver) или для связи между различными приложениями. Он позволяет запускать новые активности, сервисы, отправлять широковещательные сообщения и передавать данные между компонентами.

🚩Почему Intent необходим

🟠Связь между компонентами
Intent используется для запуска новых экранов (Activity), фоновых процессов (Service) и широковещательных сообщений (BroadcastReceiver).
🟠Передача данных
Intent позволяет передавать данные между компонентами, что упрощает обмен информацией.
🟠Взаимодействие между приложениями
С помощью Intent можно запускать активности и сервисы других приложений, что позволяет интегрировать функционал различных приложений.

🚩Типы Intent

🟠Явный (Explicit Intent)
Используется для запуска конкретного компонента внутри приложения. Здесь явно указывается компонент, который должен быть запущен.
Intent intent = new Intent(this, TargetActivity.class);
startActivity(intent);


🟠Неявный (Implicit Intent)
Используется для выполнения действий, которые могут быть выполнены несколькими приложениями. В данном случае система Android определяет, какое приложение лучше всего подходит для выполнения действия.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.example.com"));
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}


🚩Примеры использования Intent

Запуск новой Activity:
Intent intent = new Intent(this, NewActivity.class);
startActivity(intent);


Запуск Service:
Intent intent = new Intent(this, MyService.class);
startService(intent);


Отправка данных:
Intent intent = new Intent(this, TargetActivity.class);
intent.putExtra("KEY_NAME", "value");
startActivity(intent);


Отправка широковещательного сообщения:
Intent intent = new Intent("com.example.CUSTOM_INTENT");
sendBroadcast(intent);


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
🤔 Как передавать данные из одного фрагмента в другой?

Для передачи данных между фрагментами в Android можно использовать `Bundle`, передавая данные через методы `setArguments()` и `getArguments()`. Также можно использовать интерфейсы или ViewModel, чтобы организовать взаимодействие между фрагментами через Activity. ViewModel обеспечивает безопасное и эффективное управление состоянием, особенно при работе с жизненным циклом фрагментов. Это позволяет фрагментам оставаться независимыми и легко управлять данными между ними.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2
🤔 Какие у подходa Single Activity этого подхода + и - ?

Подход Single Activity означает использование одной основной активности (Activity) на весь жизненный цикл приложения, в рамках которой все пользовательские интерфейсы представлены фрагментами (Fragment). Этот подход отличается от более традиционного подхода с использованием множества активностей, где каждый экран приложения представлен отдельной активностью.

🚩Плюсы:

Улучшенная производительность и управление памятью:
Меньшее количество активностей означает меньше затрат на циклы жизни активностей и смену контекстов, что может улучшить производительность приложения и управление памятью.

Упрощенная архитектура приложения:
Управление всеми фрагментами в рамках одной активности может упростить коммуникацию между различными частями пользовательского интерфейса и сделать архитектуру приложения более простой и понятной.

Лучшая поддержка глубоких ссылок и навигации:
Навигация между экранами становится более контролируемой и удобной, особенно при использовании NavController из Android Jetpack, который оптимизирован для работы в рамках Single Activity.

Улучшенное управление состоянием:
Сохранение и восстановление состояния приложения может быть более управляемым, так как вся информация о состоянии хранится и обрабатывается в одном месте.

🚩Минусы:

Сложность управления фрагментами:
Управление множеством фрагментов, их стеками и переходами может стать более сложным и запутанным, особенно в больших и сложных приложениях.

Проблемы с производительностью:
Хотя уменьшение количества активностей может повысить производительность, управление большим количеством фрагментов и их состояниями может, напротив, ухудшить производительность, если это не контролируется должным образом.

Усложнение тестирования:
Тестирование приложения, где все фрагменты управляются одной активностью, может быть более сложным, так как каждый тестовый сценарий должен учитывать состояние всей активности и всех активных фрагментов.

Проблемы с жизненным циклом и управлением ресурсами:
Фрагменты должны тщательно управлять своими жизненными циклами в контексте родительской активности, что может привести к ошибкам в управлении ресурсами, если они не обрабатываются правильно.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🤔 Что такое inline функции?

Inline функции в Kotlin позволяют встраивать код функции в место её вызова, чтобы избежать накладных расходов на вызов функции, особенно в случае лямбд. Это полезно для небольших функций, которые часто вызываются и могут негативно сказаться на производительности при вызове через стек. Встраивание кода позволяет сократить расходы на создание объектов для лямбд и ускорить выполнение программы. Использование inline функций делает код более оптимизированным.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥4
🤔 В чем концептуальное отличие корутинов от потоков в Java?

🟠Легковесность
Тяжелые, требуют много ресурсов ОС. Легковесные, могут существовать в большом количестве без значительных затрат.

🟠Управление выполнением
Управляются ОС, переключение контекста дорогостоящее. Управляются на уровне языка, переключение быстрое и дешевое.

🟠Модель многозадачности
Параллельное выполнение. Кооперативная многозадачность, задачи добровольно уступают управление.

🟠Обработка блокировок
Могут блокироваться на длительное время. Приостанавливаются и возобновляются, эффективны при операциях ввода-вывода.

🟠Сложность управления
Требуют сложного управления и синхронизации. Код проще и читаемее.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🤔 Для чего нужен Manifest?

Файл AndroidManifest.xml необходим для определения ключевых компонентов приложения, таких как Activity, Service, BroadcastReceiver и ContentProvider. В манифесте указываются разрешения, необходимые приложению для выполнения определённых действий (например, доступ к интернету или файловой системе). Также он используется для определения метаданных приложения, таких как иконка, имя, версии и тема. Manifest обеспечивает взаимодействие системы Android с приложением и управляет его жизненным циклом.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥4🤔1
🤔 Чем отличаются двойное равно в Java и Kotlin?

🚩В Java:

Оператор == используется для сравнения двух переменных на равенство. Это означает, что == проверяет, указывают ли две переменные на один и тот же объект в памяти (сравнение ссылок).
String str1 = new String("hello");
String str2 = new String("hello");

if (str1 == str2) {
System.out.println("References are equal");
} else {
System.out.println("References are not equal");
}

// Output: References are not equal


В данном примере str1 == str2 вернет false, потому что str1 и str2 указывают на разные объекты в памяти, даже если их значения совпадают. Для сравнения значений строк в Java нужно использовать метод equals().
if (str1.equals(str2)) {
System.out.println("Values are equal");
} else {
System.out.println("Values are not equal");
}

// Output: Values are equal


🚩В Kotlin:

Оператор == используется для сравнения значений, а не ссылок. Это аналог метода equals() в Java. Для сравнения ссылок в Kotlin используется оператор ===. В данном примере str1 == str2 вернет true, потому что оператор == в Kotlin сравнивает значения строк. Если нужно сравнить ссылки в Kotlin, используется оператор ===.
val str1 = "hello"
val str2 = "hello"

if (str1 == str2) {
println("Values are equal")
} else {
println("Values are not equal")
}

// Output: Values are equal


Здесь obj1 === obj2 вернет false, потому что obj1 и obj2 указывают на разные объекты в памяти.
val obj1 = Any()
val obj2 = Any()

if (obj1 === obj2) {
println("References are equal")
} else {
println("References are not equal")
}

// Output: References are not equal


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥1
🤔 Как работает HashMap?

HashMap в Kotlin хранит пары ключ-значение и использует хеширование для быстрого поиска и вставки элементов. Каждый ключ хешируется, и результат хеш-функции определяет, где в таблице будет храниться соответствующее значение. В случае коллизий (когда два ключа имеют одинаковый хеш) HashMap использует цепочки или другие методы для хранения нескольких значений в одной корзине. Это обеспечивает доступ к элементам за среднее время O(1).

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥5👀1
🤔 Что делать, если надо исправить долгий запуск приложения в legacy проекте?

1⃣Анализ и сбор данных
Использую инструменты профилирования (например, Android Profiler в Android Studio) для сбора данных о времени выполнения различных частей кода при запуске приложения. Проанализирую логи, чтобы найти узкие места и определить, какие операции занимают больше всего времени. Проверю все зависимости и библиотеки, используемые в проекте, чтобы понять, не вызывают ли они задержки.

2⃣Идентификация проблемных зон
Проверю, какие объекты инициализируются при старте, и оценю, действительно ли все они необходимы на этом этапе. Выясню, не происходят ли тяжелые сетевые запросы или операции с базой данных во время запуска. Проверю, не загружаются ли большие ресурсы (изображения, файлы) в момент старта.

3⃣Оптимизация кода
Перенесу инициализацию объектов, которые не нужны сразу, на более поздние этапы работы приложения. Использую асинхронные операции (например, с помощью Coroutines в Kotlin или AsyncTask в Java) для выполнения тяжелых задач в фоне. Оптимизирую сетевые запросы и запросы к базе данных, чтобы они выполнялись быстрее и потребляли меньше ресурсов.

4⃣Использование архитектурных подходов
Внедрение зависимостей с использованием Dagger/Hilt, что позволяет более гибко управлять инициализацией объектов. Перенос тяжелой логики из стартовой активности в фоновые сервисы или ViewModel, чтобы основной поток оставался свободным.

5⃣Кэширование данных
Использую кэширование данных, которые не нужно запрашивать каждый раз при запуске (например, данные, полученные из сети или базы данных).

6⃣Оптимизация ресурсов
Оптимизирую изображения и другие ресурсы, чтобы уменьшить их размер и, следовательно, время загрузки. Вместо тяжелых анимаций использую Lottie для уменьшения нагрузки на систему.

7⃣Регулярное тестирование и мониторинг
Внедряю автоматические тесты для регулярного тестирования производительности. Настраиваю инструменты мониторинга (например, Firebase Performance Monitoring) для отслеживания производительности приложения в реальном времени.
// Вместо выполнения сетевого запроса на главном потоке, перенесем его в IO поток
fun fetchData() {
CoroutineScope(Dispatchers.Main).launch {
val data = withContext(Dispatchers.IO) {
// Долгий сетевой запрос
apiService.getData()
}
updateUI(data)
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81🔥1
🤔 Зачем нужен класс Nothing?

Класс `Nothing` в Kotlin представляет тип, который не имеет значения и используется для обозначения невозможного кода, например, в функциях, которые всегда выбрасывают исключение или никогда не завершаются. Это полезно для обозначения точек кода, которые не должны быть достигнуты. `Nothing` позволяет более точно описывать типы функций и улучшает читаемость и безопасность кода. Он используется как "конечный" тип, который не возвращает значений.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥6
🤔 Расскажи про коллизии в HashMap?

Возникают, когда два или более ключей имеют одинаковое значение хэш-кода. Это неизбежно, так как возможное количество ключей значительно превышает возможное количество хэш-кодов, что ведет к ситуации, когда разные ключи мапируются в одно и то же место (бакет) в таблице.

🚩Как работает

1⃣Хэширование ключей
При добавлении пары ключ-значение в HashMap, сначала вызывается метод hashCode() для ключа, чтобы получить его хэш-код.
2⃣Определение индекса бакета
Затем хэш-код используется для определения индекса бакета в массиве таблицы, где должна храниться эта пара.
3⃣Сравнение ключей
В бакете, который представляет собой связный список или дерево, проверяются все ключи с тем же индексом бакета, чтобы найти совпадение с помощью метода equals().

🚩Коллизии

🟠Связный список
В случае коллизии пара добавляется в связный список внутри соответствующего бакета.
Процесс добавления: Если бакет пустой, новая пара просто добавляется. Если нет, то пара добавляется в конец списка или обновляется, если ключ уже существует.
Процесс поиска: Когда требуется доступ к элементу, хэш-код снова используется для определения бакета, затем перебираются все элементы в списке и сравниваются ключи с помощью equals().

🟠Двоичное дерево (Java 8 и выше)
Когда количество элементов в одном бакете превышает определенный порог (обычно 8), связный список преобразуется в сбалансированное двоичное дерево, что улучшает производительность поиска и вставки.
Процесс добавления: Если количество коллизий превысило порог, связный список заменяется на дерево. Новые пары добавляются в дерево.
Процесс поиска: При доступе к элементам в дереве используется логарифмическое время поиска.

Пример, демонстрирующий коллизию в HashMap:
import java.util.HashMap;

public class HashMapCollisionExample {
public static void main(String[] args) {
HashMap<Key, String> map = new HashMap<>();

// Два ключа с одинаковым хэш-кодом
Key key1 = new Key("A1", 42);
Key key2 = new Key("B1", 42);

// Добавляем ключи в карту
map.put(key1, "Value1");
map.put(key2, "Value2");

// Получение значений
System.out.println(map.get(key1)); // Output: Value1
System.out.println(map.get(key2)); // Output: Value2
}
}

class Key {
private String name;
private int id;

public Key(String name, int id) {
this.name = name;
this.id = id;
}

@Override
public int hashCode() {
return id; // Искусственно создаем коллизии
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Key key = (Key) obj;
return id == key.id && name.equals(key.name);
}
}


🚩Как избежать и минимизировать

🟠Хорошая функция хэширования
Важно, чтобы метод hashCode() равномерно распределял значения, чтобы минимизировать вероятность коллизий.
🟠Расширение таблицы (Rehashing):
При превышении определенного порога заполненности (load factor), размер таблицы удваивается, и все элементы перераспределяются (rehashing).
🟠Использование подходящих структур данных
Современные реализации HashMap используют деревья вместо списков для бакетов с большим количеством элементов, что улучшает производительность при коллизиях.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
🤔 Как определяется приоритет приложений перед системой?

Приоритет приложений в Android определяется в зависимости от состояния активности приложения (например, foreground, background) и использования системных ресурсов. Приложения, работающие в фоновом режиме, имеют более низкий приоритет по сравнению с активными, и могут быть завершены системой для освобождения ресурсов. Система также учитывает важность компонентов приложения, таких как сервисы или фоновая обработка данных. Высший приоритет получают приложения, взаимодействующие с пользователем в текущий момент.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍1
🤔 Почему при скролле может тормозить список?

🟠Неправильное использование ViewHolder в RecyclerView
Создание новых объектов при каждом скролле. Правильное использование ViewHolder для повторного использования представлений.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public MyViewHolder(View v) {
super(v);
textView = v.findViewById(R.id.textView);
}
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
return new MyViewHolder(v);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textView.setText(myDataset[position]);
}

@Override
public int getItemCount() {
return myDataset.length;
}
}


🟠Тяжелые операции в onBindViewHolder
Загрузка изображений или обработка данных. Использование асинхронных задач и библиотек для загрузки изображений.
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textView.setText(myDataset[position]);
Glide.with(holder.imageView.getContext())
.load(imageUrls[position])
.into(holder.imageView);
}


🟠Неправильная обработка изображений
Загрузка больших изображений без сжатия. Использование библиотек Glide или Picasso.
Glide.with(context)
.load(url)
.into(imageView);


🟠Неоптимизированные макеты
Сложные иерархии макетов. Использование простых макетов и ViewStub для отложенной загрузки.
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@string/image_desc" />
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/sample_text" />
</androidx.constraintlayout.widget.ConstraintLayout>


🟠Частые вызовы notifyDataSetChanged
Перерисовка всего списка. Использование notifyItemInserted, notifyItemRemoved, notifyItemChanged для частичных обновлений.
adapter.notifyItemInserted(position);
adapter.notifyItemRemoved(position);


🟠Отсутствие кэширования данных
Повторная загрузка данных при каждом скролле. Кэширование данных с помощью LiveData.
LiveData<List<Item>> items = viewModel.getItems();
items.observe(this, new Observer<List<Item>>() {
@Override
public void onChanged(List<Item> items) {
adapter.setItems(items);
}
});


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4