Kotlin | Вопросы собесов
2.57K subscribers
28 photos
960 links
Download Telegram
🤔 Расскажи про коллизии в 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
🤔 В чем разница между LinkedList и ArrayList?

`ArrayList` хранит элементы в виде массива и обеспечивает быстрый доступ по индексу, но медленно вставляет и удаляет элементы в середине списка, так как элементы нужно сдвигать. `LinkedList` основан на узлах, где каждый узел ссылается на следующий, что делает вставку и удаление быстрыми операциями, но доступ к элементам по индексу медленнее, так как нужно пройти через каждый узел. `ArrayList` лучше подходит для доступа к данным, а `LinkedList` — для частого изменения структуры данных.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥8
🤔 В чем разница между работой с list и работой с sequence ?

🚩Основные структуры работы с коллекциями

🟠List
Является жадной коллекцией, что означает, что все операции над элементами выполняются немедленно и целиком. Когда вы применяете функции к списку, такие как map, filter и т.д., все элементы проходят через каждую функцию сразу же. В данном примере все элементы списка numbers сначала умножаются на 2, затем фильтруются. Вся работа выполняется сразу для каждого элемента.
val numbers = listOf(1, 2, 3, 4, 5)
val result = numbers
.map { it * 2 }
.filter { it > 5 }
println(result) // Output: [6, 8, 10]


🟠Sequence
Является ленивой коллекцией. Это означает, что элементы обрабатываются по мере необходимости. Функции, применяемые к последовательности, создают цепочку операций, которая выполняется только при обращении к элементам. В этом примере numbers сначала преобразуется в Sequence. Операции map и filter создают цепочку, которая выполняется только при преобразовании обратно в List с помощью toList(). Это позволяет избежать лишних операций и обрабатывать элементы по мере необходимости.
val numbers = listOf(1, 2, 3, 4, 5)
val result = numbers.asSequence()
.map { it * 2 }
.filter { it > 5 }
.toList()
println(result) // Output: [6, 8, 10]


🚩Различия

🟠Жадность против ленивости
List: Все элементы обрабатываются сразу при вызове функций.
Sequence: Элементы обрабатываются по мере необходимости, что может повысить эффективность.

🟠Производительность
List: Подходит для небольших коллекций, где выполнение всех операций сразу не критично.
Sequence: Эффективен для больших коллекций или длинных цепочек операций, так как уменьшает количество промежуточных коллекций.

🟠Использование памяти
List: Может использовать больше памяти из-за создания промежуточных коллекций.
Sequence: Уменьшает использование памяти, обрабатывая элементы по одному.

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

`BroadcastReceiver` — это компонент Android, который позволяет приложениям принимать и обрабатывать широковещательные сообщения (broadcasts) от системы или других приложений. Примеры системных сообщений включают изменения состояния сети, получение SMS или завершение загрузки устройства. Приложения могут регистрировать BroadcastReceiver статически в манифесте или динамически в коде. BroadcastReceiver помогает реагировать на важные события, происходящие в системе.

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

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

🟠Фоновые задачи
Сервисы выполняют задачи в фоновом режиме, что позволяет не прерывать работу пользовательского интерфейса.

🟠Отсутствие UI
Сервисы не имеют пользовательского интерфейса. Они работают независимо от активности, которая может завершиться или быть приостановлена.

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

🚩Типы сервисов

🟠Started Service (Запущенный сервис)
Запускается с помощью метода startService(). Выполняет свою задачу независимо и завершает работу сам, вызвав stopSelf(), или его можно остановить извне, вызвав stopService(). Загрузка файла в фоне.
// Запуск сервиса
Intent intent = new Intent(this, MyService.class);
startService(intent);

// Остановка сервиса
stopService(intent);


🟠Bound Service (Связанный сервис)
Предоставляет интерфейс клиентам для взаимодействия с сервисом с помощью bindService(). Связывается с компонентом приложения (например, Activity), и работает до тех пор, пока компонент не завершится. Сервис для взаимодействия с удаленной базой данных.
// Привязка к сервису
Intent intent = new Intent(this, MyService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

// Отключение от сервиса
unbindService(serviceConnection);


Пример привязки к Bound Service в Activity:
public class MainActivity extends AppCompatActivity {
MyBoundService myService;
boolean isBound = false;

private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyBoundService.LocalBinder binder = (MyBoundService.LocalBinder) service;
myService = binder.getService();
isBound = true;
}

@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
}
};

@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, MyBoundService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
super.onStop();
if (isBound) {
unbindService(serviceConnection);
isBound = false;
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🤔 Что такое sealed классы и зачем они нужны?

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

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

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

🚩Особенности типа

🟠Подтип любого типа
Nothing является подтипом любого другого типа в Kotlin. Это означает, что значение типа Nothing можно присвоить переменной любого типа.

🟠Отсутствие значения
Тип Nothing не имеет значений. Любая функция, которая возвращает Nothing, либо выбрасывает исключение, либо не завершает выполнение (например, бесконечный цикл).

🚩Применение

🟠Функции, которые не возвращают значение
Функции, которые всегда выбрасывают исключение, могут быть объявлены с возвращаемым типом Nothing.
fun fail(message: String): Nothing {
throw IllegalArgumentException(message)
}


🟠Указание невозможности завершения
Тип Nothing используется для обозначения точек кода, которые не могут быть достигнуты. Например, после выбрасывания исключения выполнение кода не продолжается.
val result: Int = fail("Error occurred") // Тип Nothing может быть присвоен переменной типа Int


🟠Использование в выражениях
Nothing может быть использован в выражениях, где требуется любой тип. Это позволяет писать более выразительный и безопасный код.
fun process(value: Any?) {
val result = value ?: fail("Value is null") // fail возвращает Nothing, который совместим с любым типом
}


🟠Обработка ошибок
В некоторых случаях Nothing используется в библиотеках для обработки ошибок или в случаях, когда выполнение программы не может продолжаться.
sealed class Result<out T>
class Success<out T>(val data: T) : Result<T>()
class Error(val exception: Throwable) : Result<Nothing>() // Error использует Nothing


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

Функция, выбрасывающая исключение
fun terminate(): Nothing {
throw RuntimeException("This function never returns")
}

fun main() {
val x: Int = terminate() // Можно присвоить переменной типа Int
}


Использование Nothing в условных выражениях:
fun checkNotNull(value: String?): String {
return value ?: fail("Value is null") // Если value null, вызовется fail, возвращающий Nothing
}

fun main() {
val name: String = checkNotNull(null) // Ошибка: Value is null
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
🤔 Чем data class отличается от обычного класса?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥31
🤔 Какие коллекции знаешь?

Имеется богатый набор коллекций, которые предоставляют различные способы хранения и управления данными. Коллекции в Kotlin можно разделить на две основные категории: неизменяемые (immutable) и изменяемые (mutable). В рамках этих категорий есть несколько типов коллекций, таких как списки, множества и карты.

🚩Неизменяемые коллекции

🟠List
Неизменяемый список, который позволяет хранить элементы в определенном порядке и допускает дублирование элементов.
val immutableList: List<String> = listOf("Apple", "Banana", "Cherry")


🟠Set
Неизменяемое множество, которое не допускает дублирования элементов и не гарантирует сохранение порядка.
val immutableSet: Set<String> = setOf("Apple", "Banana", "Cherry")


🟠Map
Неизменяемая карта, которая хранит пары ключ-значение. Ключи должны быть уникальными.
val immutableMap: Map<String, Int> = mapOf("Apple" to 1, "Banana" to 2, "Cherry" to 3)


🚩Изменяемые коллекции

🟠MutableList
Изменяемый список, который позволяет добавлять, удалять и изменять элементы.
val mutableList: MutableList<String> = mutableListOf("Apple", "Banana", "Cherry")
mutableList.add("Date")


🟠MutableSet
Изменяемое множество, которое позволяет добавлять и удалять элементы.
val mutableSet: MutableSet<String> = mutableSetOf("Apple", "Banana", "Cherry")
mutableSet.add("Date")


🟠MutableMap
Изменяемая карта, которая позволяет добавлять, удалять и изменять пары ключ-значение.
val mutableMap: MutableMap<String, Int> = mutableMapOf("Apple" to 1, "Banana" to 2, "Cherry" to 3)
mutableMap["Date"] = 4


🚩Специализированные коллекции

🟠ArrayList
Изменяемый список, основанный на массиве. Обеспечивает быстрый доступ по индексу.
val arrayList: ArrayList<String> = arrayListOf("Apple", "Banana", "Cherry")


🟠HashSet
Изменяемое множество, основанное на хэш-таблице. Обеспечивает быструю проверку принадлежности.
val hashSet: HashSet<String> = hashSetOf("Apple", "Banana", "Cherry")


🟠HashMap
Изменяемая карта, основанная на хэш-таблице. Обеспечивает быстрый доступ к значениям по ключу.
val hashMap: HashMap<String, Int> = hashMapOf("Apple" to 1, "Banana" to 2, "Cherry" to 3)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍111
🤔 Что такое сборщик мусора?

Сборщик мусора (Garbage Collector) — это механизм управления памятью, который автоматически освобождает неиспользуемую память, занятую объектами, к которым больше нет ссылок. В Kotlin, как и в Java, сборщик мусора работает в фоновом режиме, устраняя необходимость вручную освобождать память. Это помогает предотвратить утечки памяти и делает управление памятью более безопасным и простым. Сборщик мусора улучшает производительность, автоматически управляя жизненным циклом объектов.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥2🎉1
🤔 На что следует обращать внимание, чтобы оптимизировать большой список?

🟠Правильное использование ViewHolder в RecyclerView
Причина: Создание новых объектов при каждом скролле приводит к значительным задержкам.
Решение: Используйте ViewHolder для повторного использования представлений.
class MyAdapter(private val myDataset: Array<String>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

class MyViewHolder(v: View) : RecyclerView.ViewHolder(v) {
val textView: TextView = v.findViewById(R.id.textView)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val v = LayoutInflater.from(parent.context)
.inflate(R.layout.my_text_view, parent, false)
return MyViewHolder(v)
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.textView.text = myDataset[position]
}

override fun getItemCount(): Int {
return myDataset.size
}
}


🟠Выполнение тяжелых операций в фоне
Причина: Выполнение тяжелых операций в главном потоке приводит к блокировке пользовательского интерфейса.
Решение: Переносите тяжелые операции в асинхронные задачи или используйте библиотеки для асинхронной загрузки.
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.textView.text = myDataset[position]
Glide.with(holder.imageView.context)
.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"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:contentDescription="@string/image_desc" />

<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/imageView"
android:text="@string/sample_text" />
</androidx.constraintlayout.widget.ConstraintLayout>


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

SOLID — это пять принципов объектно-ориентированного программирования, направленных на создание гибкого, поддерживаемого и расширяемого кода. Эти принципы включают: Single Responsibility (единственная ответственность), Open/Closed (открытость для расширения, закрытость для изменений), Liskov Substitution (замена Барбары Лисков), Interface Segregation (разделение интерфейсов) и Dependency Inversion (инверсия зависимостей). Применение SOLID помогает улучшить архитектуру приложений и уменьшить сложность кода.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8
🤔 Какие есть главные функции у стека?

🚩Главные функции стека включают основные операции для добавления, удаления и просмотра элементов.

🟠push()
Добавляет элемент на вершину стека. Эта операция вставляет новый элемент в стек и делает его верхним элементом.
val stack = Stack<Int>()
stack.push(10) // Стек: [10]
stack.push(20) // Стек: [10, 20]


🟠pop()
Удаляет и возвращает верхний элемент стека. Эта операция удаляет элемент, который находится на вершине стека, и возвращает его. Если стек пуст, обычно выбрасывается исключение (например, EmptyStackException).
val top = stack.pop() // top = 20, Стек: [10]


🟠peek()
Возвращает верхний элемент стека без его удаления. Эта операция позволяет просмотреть верхний элемент стека без его удаления. Если стек пуст, обычно выбрасывается исключение.
val top = stack.peek() // top = 10, Стек: [10]


🚩Дополнительные функции

🟠search(Object o)
Ищет элемент в стеке и возвращает его позицию относительно вершины стека. Если элемент не найден, возвращает -1.
val position = stack.search(10) // position = 1


Пример использования стека
import java.util.Stack;

public class StackExample {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();

// Добавление элементов (push)
stack.push(10);
stack.push(20);
stack.push(30);

// Просмотр верхнего элемента (peek)
System.out.println("Верхний элемент: " + stack.peek()); // Вывод: 30

// Удаление верхнего элемента (pop)
System.out.println("Удален элемент: " + stack.pop()); // Вывод: 30
System.out.println("Новый верхний элемент: " + stack.peek()); // Вывод: 20

// Проверка, пуст ли стек (isEmpty)
System.out.println("Стек пустой? " + stack.isEmpty()); // Вывод: false

// Размер стека (size)
System.out.println("Размер стека: " + stack.size()); // Вывод: 2
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
🤔 Что такое Activity и для чего это используется?

`Activity` в Android — это компонент приложения, который представляет один экран пользовательского интерфейса и отвечает за взаимодействие с пользователем. Каждое приложение может содержать несколько Activity, и они управляются системой Android в рамках жизненного цикла. Activity управляет пользовательским вводом, отображением данных и переходами между экранами. Это основной блок для создания интерактивных приложений на Android.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥31
🤔 Вставка значения быстрее в Linked list или в Array list?

🚩Вставка в `ArrayList`

ArrayList реализован на основе массива.

🟠Вставка в конец
Амортизированное O(1). Если массив не заполнен, элемент добавляется в конец списка. В случае, если массив заполнен, требуется выделение нового массива и копирование элементов, что занимает O(n) времени.
val arrayList = ArrayList<Int>()
arrayList.add(1) // Быстрая вставка в конец


🟠Вставка в начало или середину
O(n). Необходимо сдвинуть все элементы, начиная с позиции вставки, чтобы освободить место для нового элемента. Это требует времени, пропорционального количеству элементов после позиции вставки.
arrayList.add(0, 2) // Медленная вставка в начало
arrayList.add(1, 3) // Медленная вставка в середину


🚩Вставка в LinkedList

LinkedList реализован на основе узлов, где каждый узел содержит ссылку на следующий и/или предыдущий узел (в случае двусвязного списка).

🟠Вставка в начало: O(1). Для добавления элемента в начало достаточно изменить ссылки первого узла и нового узла.
val linkedList = LinkedList<Int>()
linkedList.addFirst(1) // Быстрая вставка в начало


🟠Вставка в конец
O(1) (если есть ссылка на последний узел) или O(n) (если необходимо пройти весь список). Если список двусвязный и хранится ссылка на последний элемент, вставка в конец осуществляется за O(1). В противном случае, требуется пройти весь список до конца.
linkedList.addLast(2) // Быстрая вставка в конец, если есть ссылка на последний узел


🟠Вставка в середину
O(n). Необходимо пройти список до нужной позиции и изменить ссылки узлов.
linkedList.add(1, 3) // Медленная вставка в середину


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

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
🤔 Что такое layout, какие их виды бывают и когда их использовать?

Это способ определения пользовательского интерфейса (UI) приложения, который описывает, как элементы интерфейса (виджеты) располагаются на экране. Макеты задаются с помощью XML-файлов или программно в коде.

🚩Виды

🟠LinearLayout
Располагает дочерние элементы в виде одной строки или столбца (вертикально или горизонтально). Подходит для простых интерфейсов, где элементы должны быть расположены один за другим.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, World!" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me" />
</LinearLayout>


🟠RelativeLayout
Располагает дочерние элементы относительно друг друга или относительно родительского контейнера. Подходит для более сложных интерфейсов, где элементы должны быть выровнены относительно других элементов
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, World!" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
android:layout_below="@id/textView" />
</RelativeLayout>


🟠ConstraintLayout
Предоставляет гибкую систему ограничения для размещения элементов относительно друг друга и границ контейнера. Это мощный и эффективный макет, который заменяет сложные вложенные макеты. Подходит для сложных интерфейсов, где требуется точное позиционирование и выравнивание элементов.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, World!"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
app:layout_constraintTop_toBottomOf="@id/textView"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>


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

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2