Kotlin | Вопросы собесов
2.57K subscribers
28 photos
961 links
Download Telegram
🤔 Что такое принципы 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
🤔 Для чего служит component в data class ?

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

Здесь объявлен data class Person с двумя свойствами: name и age. Когда создается объект person этого класса, мы можем использовать синтаксис деструктуризации для извлечения значений этих свойств. Внутренне это работает благодаря componentN функциям, которые автоматически создаются компилятором для каждого свойства.
data class Person(val name: String, val age: Int)

fun main() {
val person = Person("Alice", 30)

// Использование componentN функций
val (name, age) = person
println("Name: $name, Age: $age")
}


component1 возвращает значение свойства name.
component2 возвращает значение свойства age.
Синтаксис деструктуризации (val (name, age) = person) позволяет присвоить значения этих свойств соответствующим переменным, как если бы мы вручную вызывали person.component1() и person.component2().

Вот как это могло бы выглядеть без синтаксиса деструктуризации:
И так, функции componentN служат для облегчения доступа к свойствам data class, особенно при использовании синтаксиса деструктуризации.
fun main() {
val person = Person("Alice", 30)

val name = person.component1()
val age = person.component2()

println("Name: $name, Age: $age")
}


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

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

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

🚩Требования и особенности

🟠Конструктор с параметрами
Data class должен иметь хотя бы один параметр в первичном конструкторе.
🟠Модификаторы параметров
Параметры первичного конструктора должны быть помечены как val или var, чтобы они становились свойствами класса.
🟠Функции-члены
Kotlin автоматически генерирует несколько функций для data class: equals(), hashCode(), toString(), copy(), и componentN функции для каждого свойства в порядке их объявления.
🟠Ограничения на наследование
Data class не может быть abstract, open, sealed или inner.
data class Person(val name: String, val age: Int)

🟠Конструктор с параметрами
Data class Person имеет первичный конструктор с двумя параметрами: name и age.
🟠Модификаторы параметров
Параметры name и age помечены как val, что делает их свойствами класса с доступом только для чтения.
🟠Функции-члены
Компилятор автоматически генерирует следующие функции для класса Person:
equals(): для проверки равенства объектов.
hashCode(): для вычисления хэш-кода.
toString(): для представления объекта в виде строки.
copy(): для создания копии объекта с возможностью изменения некоторых свойств.
componentN функции: для доступа к свойствам по порядку их объявления (например, component1 для name и component2 для age).
🟠Ограничения на наследование
Data class Person не может быть помечен как abstract, open, sealed или inner.

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

fun main() {
val person1 = Person("Alice", 30)
val person2 = person1.copy(age = 31)

println(person1) // Вывод: Person(name=Alice, age=30)
println(person2) // Вывод: Person(name=Alice, age=31)

val (name, age) = person1
println("Name: $name, Age: $age") // Вывод: Name: Alice, Age: 30
}


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

Жизненный цикл фрагментов напрямую связан с жизненным циклом Activity, в которой они находятся. Когда Activity создаётся, запускается или уничтожается, её фрагменты проходят те же стадии жизненного цикла. Фрагменты могут иметь свои уникальные методы жизненного цикла, такие как `onCreateView()` или `onDestroyView()`, но они всегда синхронизированы с жизненным циклом Activity. Это гарантирует правильное управление ресурсами и состоянием интерфейса пользователя.

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

🚩Первичный конструктор

Это конструктор, который объявляется вместе с объявлением класса. Он может принимать параметры и инициализировать свойства класса. Этот класс Person имеет первичный конструктор с двумя параметрами: name и age. Они одновременно являются свойствами класса.
class Person(val name: String, var age: Int)


Особенности первичного конструктора.
Параметры первичного конструктора могут быть объявлены как val или var, что делает их свойствами класса. Код инициализации может быть выполнен в блоке init.
class Person(val name: String, var age: Int) {
init {
println("Person initialized with name: $name and age: $age")
}
}


🚩Вторичные конструкторы

Это конструкторы, которые объявляются внутри класса с использованием ключевого слова constructor. Они используются для предоставления дополнительных способов инициализации класса.
class Person {
var name: String
var age: Int

constructor(name: String, age: Int) {
this.name = name
this.age = age
}

constructor(name: String) {
this.name = name
this.age = 0 // Значение по умолчанию
}
}


Этот класс Person имеет два вторичных конструктора:
Один принимает два параметра: name и age.
Другой принимает только параметр name и устанавливает age по умолчанию в 0.

Сочетание первичного и вторичных конструкторов
Класс может иметь как первичный, так и вторичные конструкторы. Если у класса есть первичный конструктор, вторичные конструкторы должны делегировать ему вызов с помощью ключевого слова this. В этом примере вторичный конструктор делегирует вызов первичному конструктору с значением age по умолчанию равным 0.
class Person(val name: String, var age: Int) {
constructor(name: String) : this(name, 0) {
println("Secondary constructor called")
}

init {
println("Primary constructor called")
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🤔 Что означает в Android-разработке подход Single Activity?

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

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

🚩Абстрактные классы

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

🚩Особенности абстрактных классов

🟠Абстрактный класс может содержать как абстрактные, так и не абстрактные (реализованные) методы.
🟠Абстрактные методы не имеют тела и должны быть реализованы в подклассах.
🟠Абстрактный класс может наследоваться любым количеством подклассов.
🟠Абстрактные классы используются, когда нужно создать базовый класс, который определяет общие свойства и методы для своих подклассов.
abstract class Animal {
abstract fun makeSound()

fun sleep() {
println("The animal is sleeping")
}
}

class Dog : Animal() {
override fun makeSound() {
println("Woof")
}
}

class Cat : Animal() {
override fun makeSound() {
println("Meow")
}
}


🚩Sealed классы

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

Особенности sealed классов
Sealed классы используются для ограничения иерархии классов. Все подклассы должны быть известны на этапе компиляции. Подклассы sealed класса могут быть абстрактными или конкретными (не абстрактными). Sealed классы часто используются в сочетании с when-выражениями для обеспечения исчерпывающей проверки вариантов.
sealed class Result {
data class Success(val data: String) : Result()
data class Error(val exception: Exception) : Result()
object Loading : Result()
}

fun handleResult(result: Result) {
when (result) {
is Result.Success -> println("Data: ${result.data}")
is Result.Error -> println("Error: ${result.exception.message}")
Result.Loading -> println("Loading...")
}
}


🚩Ключевые отличия

🟠Наследование
Абстрактный класс: может наследоваться любым количеством подклассов, которые могут находиться в разных файлах и модулях.
Sealed класс: ограничивает количество подклассов, которые могут его наследовать. Все подклассы должны быть объявлены в одном файле.

🟠Область применения
Абстрактный класс: используется для создания базовых классов с общей функциональностью, которая должна быть реализована в подклассах.
Sealed класс: используется для создания ограниченных иерархий классов, когда все возможные варианты известны и должны быть исчерпывающе обработаны (например, при работе с состояниями или результатами операций).

🟠Безопасность типов
Sealed класс: предоставляет более строгую проверку типов на этапе компиляции, что делает его удобным для использования в when-выражениях без необходимости добавления ветки else.

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

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

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

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

🚩Концепции

🟠Executor Interface
Базовый интерфейс, который имеет один метод execute(Runnable command), предназначенный для выполнения переданной задачи.

🟠ExecutorService Interface
Расширяет интерфейс Executor и добавляет методы для управления жизненным циклом исполнителя, такие как shutdown(), submit(), и другие. Он также предоставляет методы для выполнения задач, возвращающих результат (Callable).

🟠ThreadPoolExecutor
Одна из самых часто используемых реализаций ExecutorService, которая использует пул потоков для управления выполнением задач.

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

В этом примере создается Executor с использованием фабричного метода Executors.newSingleThreadExecutor(), который создает одиночный поток для выполнения задач. Метод execute принимает задачу в виде объекта Runnable и выполняет её в потоке.
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class Main {
public static void main(String[] args) {
Executor executor = Executors.newSingleThreadExecutor();

executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("Task executed");
}
});
}
}


Более сложный пример с использованием ExecutorService:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);

for (int i = 0; i < 5; i++) {
executorService.execute(new WorkerThread("Task " + i));
}

executorService.shutdown();

try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
}
}
}

class WorkerThread implements Runnable {
private String command;

public WorkerThread(String command) {
this.command = command;
}

@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Start. Command = " + command);
processCommand();
System.out.println(Thread.currentThread().getName() + " End.");
}

private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

🟠Создается ExecutorService с фиксированным пулом из 3 потоков.
🟠5 задач добавляются в очередь на выполнение.
🟠Метод shutdown инициирует упорядоченное завершение работы, при котором ранее отправленные задачи будут выполнены, но новые задачи приниматься не будут.
🟠Метод awaitTermination ожидает завершения всех задач в течение указанного времени, после чего вызывается shutdownNow для принудительного завершения всех задач.

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

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

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

🟠Минимизируйте использование статических переменных.
🟠Избегайте утечек памяти, правильно управляя ссылками на контексты и активности.
🟠Используйте слабые ссылки (WeakReference) для больших объектов.
🟠Избегайте внутренних классов в Activity, заменяя их статическими вложенными классами.
🟠Применяйте LruCache для кэширования данных в памяти.
🟠Профилируйте приложение с помощью Android Studio Profiler и LeakCanary.
🟠Используйте Glide или Picasso для загрузки и кэширования изображений.
🟠Управляйте крупными объектами и загружайте изображения оптимального размера.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🤔 Расскажи data классы и sealed классы.

Data классы в Kotlin предназначены для хранения данных и автоматически генерируют методы, такие как equals(), hashCode(), toString() и copy(). Они идеально подходят для создания POJO/POCO объектов.
Sealed классы используются для представления ограниченного набора типов, похожих на перечисления, но с возможностью иметь классы с разными свойствами и методами. Это помогает обеспечить безопасное использование при работе с типами во время компиляции, улучшая обработку ошибок и логику ветвления.

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

🟠`onCreate(Bundle savedInstanceState)`
Создание активности. Вызывается при создании активности. Здесь инициализируются основные компоненты (например, настройка пользовательского интерфейса).

🟠`onStart()`
Активность становится видимой для пользователя. Вызывается после onCreate и каждый раз, когда активность становится видимой.

🟠`onResume()`
Активность становится доступной для взаимодействия с пользователем. Вызывается после onStart и каждый раз, когда активность возвращается на передний план (например, после паузы).

🟠`onPause()`
Активность перестает быть доступной для взаимодействия. Вызывается, когда активность переходит в состояние паузы (например, при открытии новой активности или диалога).

🟠`onStop()`
Активность становится невидимой для пользователя. Вызывается, когда активность больше не видна (например, при переходе к другой активности).

🟠`onDestroy()`
Уничтожение активности. Вызывается перед окончательным уничтожением активности. Здесь освобождаются ресурсы.

🟠`onRestart()`
Активность снова становится активной после остановки. Вызывается после onStop, перед onStart.

🟠`onSaveInstanceState(Bundle outState)`
Сохранение состояния активности. Вызывается перед уничтожением активности для сохранения ее текущего состояния.

🟠`onRestoreInstanceState(Bundle savedInstanceState)`
Восстановление состояния активности. Вызывается после onStart, если активность была ранее уничтожена и существует сохраненное состояние.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🤔 Чем launch отличается от async/await?

Функция launch в Kotlin Coroutines используется для запуска новой сопрограммы, которая выполняется параллельно остальному коду, и не блокирует поток, в котором она была вызвана. Результатом launch является Job, который представляет собой ссылку на сопрограмму.
Async используется для запуска сопрограммы, которая возвращает Deferred — промис для результата. Await используется для получения этого результата, при этом ожидание результата suspend'ит (приостанавливает) текущую сопрограмму до его получения.

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