Kotlin | Вопросы собесов
2.56K subscribers
27 photos
956 links
Download Telegram
📌 Как работает hashmap ?

💬 Спрашивают в 33% собеседований

HashMap — это структура данных, которая использует хеш-таблицу для хранения пар "ключ-значение". Она позволяет выполнять операции вставки, удаления и поиска элементов с почти постоянным временем выполнения, что делает её очень эффективной для определённых задач. Вот как она работает:

🤔 Основы работы

1️⃣ Хеширование ключей: Каждый раз, когда добавляется новая пара "ключ-значение", HashMap использует хеш-функцию для вычисления хеш-кода ключа. Хеш-код затем используется для определения индекса в массиве, где будет храниться значение. Это позволяет быстро находить значения по ключам.

2️⃣ Разрешение коллизий: Два разных ключа могут иметь одинаковый хеш-код или хеш-коды, которые приводят к одному и тому же индексу в массиве (это называется коллизией). HashMap разрешает такие коллизии, сохраняя эти элементы в одной "корзине" или "ячейке" в виде списка (до Java 8 использовались связанные списки, начиная с Java 8 — сбалансированные деревья при большом количестве коллизий в одной корзине).

3️⃣ Вставка и поиск: При вставке нового элемента HashMap вычисляет индекс корзины для ключа и помещает значение в эту корзину. При поиске значения по ключу HashMap снова вычисляет индекс, находит соответствующую корзину и затем перебирает элементы в ней, чтобы найти нужное значение.

4️⃣ Масштабирование: Когда количество элементов в HashMap достигает определённого порога заполнения (загрузки), размер массива увеличивается, и все существующие элементы перераспределяются в новом массиве. Это необходимо для поддержания эффективности операций вставки и поиска.

Представьте, что у вас есть HashMap, где ключи — это имена пользователей, а значения — это их email. Когда вы добавляете новую пару "ключ-значение" ("John Doe", "[email protected]"), HashMap выполняет следующие действия:

1️⃣Вычисляет хеш-код для "John Doe".
2️⃣Использует хеш-код, чтобы найти индекс корзины, где должен быть сохранён email.
3️⃣Добавляет "[email protected]" в корзину этого индекса.

Когда вы пытаетесь найти email по имени "John Doe", HashMap снова вычисляет хеш-код для "John Doe", находит соответствующую корзину и возвращает сохранённый в ней email.

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31
🤔 Сколько значений будет возвращено из функции, если используется ключевое слово suspend?
Anonymous Quiz
10%
0
38%
1
8%
Множественные
44%
Зависит от контекста
🤔4👍1
📌 Что известно про типы any, unit, nothing в Kotlin ?

💬 Спрашивают в 33% собеседований

Существуют специальные типы Any, Unit и Nothing, которые имеют уникальные цели и применения в языке программирования:

🤔 Any

Является корневым типом для всех ненулевых типов в Kotlin, аналогичным Object. Любой объект, за исключением null, наследуется от Any. Этот тип обычно используется там, где требуется представление любого возможного значения, за исключением null. Any определяет несколько базовых методов, таких как equals(), hashCode() и toString(), которые могут быть переопределены.
fun printAnyObject(obj: Any) {
println(obj.toString())
}


🤔 Unit

Аналогичен void, но в отличие от void, он является полноценным объектом. Функции в Kotlin, которые не возвращают значимый результат, на самом деле возвращают Unit. Этот тип обычно используется для указания, что функция выполняет действие, но не возвращает значение. Хотя возвращаемый тип Unit обычно опускается, его можно указать явно.
fun printHello(): Unit {
println("Hello, World!")
}


🤔 Nothing

Это тип, который не имеет значений. Он используется для обозначения "невозможности", то есть ситуаций, когда функция никогда корректно не завершает своё выполнение. Например, функция может вечно зацикливаться или всегда выбрасывать исключение. Его указание в качестве возвращаемого типа функции помогает понять, что эта точка кода недостижима.
fun failWithErrorMessage(message: String): Nothing {
throw IllegalArgumentException(message)
}


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

Any — это базовый тип для всех объектов в Kotlin, кроме null.
Unit указывает, что функция не возвращает полезное значение, аналогично void в других языках программирования, но является объектом.
Nothing используется для обозначения "невозможности" выполнения кода после определённой точки, например, после выброса исключения.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🤔 Какое ключевое слово используется для создания сопрограмм в Kotlin?
Anonymous Quiz
18%
async
3%
await
67%
suspend
12%
coroutine
😁2🤯2👾1
📌 Зачем нужен класс nothing ?

💬 Спрашивают в 33% собеседований

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

1️⃣ Обозначение "недостижимого" кода

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

2️⃣ Помощь в статическом анализе кода

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

3️⃣ Улучшение читабельности и понимания кода

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

Рассмотрим функцию, которая используется для обработки ошибок и всегда выбрасывает исключение:
fun throwError(message: String): Nothing {
throw IllegalArgumentException(message)
}


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

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
🤔 Как в Kotlin называется функция, которая вызывается на объекте для преобразования его в другой тип?
Anonymous Quiz
12%
convert
15%
transform
58%
map
16%
cast
🤯2
📌Что такое сериализация?

💬 Спрашивают в 7% собеседований

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

🤔 Почему это нужно?
Когда мы работаем с объектами в приложении, они находятся в оперативной памяти. Но, если нужно сохранить состояние объекта между запусками программы или передать его через сеть, нам нужно как-то его "упаковать". Вот тут и приходит на помощь сериализация. Например, вы можете сериализовать объект, сохранить его в файл, а потом прочитать этот файл и десериализовать объект обратно.

🤔 Как это используется?

В Android для сериализации часто используется интерфейс Serializable или Parcelable. Вот пример использования Serializable:
import java.io.Serializable;

public class User implements Serializable {
private String name;
private int age;

public User(String name, int age) {
this.name = name;
this.age = age;
}

// геттеры и сеттеры
}


Чтобы сериализовать объект User и сохранить его в файл, можно сделать так:
User user = new User("John", 30);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"))) {
oos.writeObject(user);
} catch (IOException e) {
e.printStackTrace();
}


Для десериализации объекта из файла:
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"))) {
User user = (User) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}


🤔 Пример использования `Parcelable` в Android:

Parcelable предпочтительнее в Android, так как он быстрее работает по сравнению с Serializable.
import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable {
private String name;
private int age;

public User(String name, int age) {
this.name = name;
this.age = age;
}

protected User(Parcel in) {
name = in.readString();
age = in.readInt();
}

public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}

@Override
public User[] newArray(int size) {
return new User[size];
}
};

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}

// геттеры и сеттеры
}


Теперь можно передавать объект User между активити:
Intent intent = new Intent(this, AnotherActivity.class);
User user = new User("John", 30);
intent.putExtra("user", user);
startActivity(intent);


И получить его в AnotherActivity:
User user = getIntent().getParcelableExtra("user");


🤔 Кратко:
Сериализация – это способ сохранения или передачи объектов, преобразовывая их в поток байтов. В Android можно использовать Serializable или Parcelable для этих целей.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
🤔 Какой модификатор позволяет создать приватный конструктор для класса в Kotlin?
Anonymous Quiz
70%
private constructor
8%
private init
16%
private class
6%
private fun
📌 Как подключить BroadcastReceiver, чтобы он смог получать сообщения?

💬 Спрашивают в 7% собеседований

Подключение BroadcastReceiver в Android состоит из двух основных шагов: создание самого ресивера и его регистрация. Ресивер можно зарегистрировать как статически в манифесте, так и динамически в коде.

1️⃣ Создание 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();
}
}


2️⃣ Регистрация ресивера

2️⃣🔤1️⃣ Статическая регистрация в манифесте

Можно зарегистрировать ресивер в файле AndroidManifest.xml. Это удобно, когда вы хотите, чтобы ресивер всегда был активен и слушал определённые системные события, например, перезагрузку устройства или получение SMS.
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.myapp">

<application
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>

</application>

</manifest>


2️⃣🔤2️⃣ Динамическая регистрация в коде

Иногда нужно регистрировать ресивер только на время выполнения определённой активности или службы. В этом случае лучше использовать динамическую регистрацию.
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);
}
}


В этом примере ресивер регистрируется в методе onStart() и отписывается в методе onStop(). Это позволяет ресиверу быть активным только тогда, когда активность видима.

🤔 Кратко:

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥4
🤔 Какой из приведенных типов нельзя использовать в when выражении без аргумента?
Anonymous Quiz
5%
Int
28%
String
53%
Boolean
14%
Long
🤯3
📌 Какие типы хранилищ существуют в Android-приложениях?

💬 Спрашивают в 7% собеседований

В Android-приложениях существует несколько типов хранилищ данных, каждый из которых подходит для различных сценариев и требований к данным. Основные типы хранилищ данных в Android включают:

1️⃣ SharedPreferences:
Описание: Используется для хранения пар "ключ-значение".
Применение: Идеально подходит для хранения небольших данных, таких как настройки пользователя, предпочтения и конфигурации.

2️⃣ Internal Storage:
Описание: Хранение данных внутри внутренней памяти устройства.
Применение: Подходит для хранения приватных данных, которые должны быть доступны только внутри приложения.
Пример:

      String filename = "myfile";
String fileContents = "Hello, World!";
FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(fileContents.getBytes());
fos.close();

// Чтение данных
FileInputStream fis = openFileInput(filename);
int c;
StringBuilder temp = new StringBuilder();
while( (c = fis.read()) != -1) {
temp.append((char)c);
}
fis.close();


3️⃣ External Storage:
Описание: Хранение данных на внешней памяти устройства (SD-карта или внешняя память устройства).
Применение: Используется для хранения данных, которые должны быть доступны за пределами приложения, например, мультимедийные файлы (фотографии, видео).
Пример:

      String filename = "myfile.txt";
String fileContents = "Hello, World!";
File file = new File(getExternalFilesDir(null), filename);
FileOutputStream fos = new FileOutputStream(file);
fos.write(fileContents.getBytes());
fos.close();

// Чтение данных
FileInputStream fis = new FileInputStream(file);
int c;
StringBuilder temp = new StringBuilder();
while( (c = fis.read()) != -1) {
temp.append((char)c);
}
fis.close();


4️⃣ SQLite Database:
Описание: Полноценная реляционная база данных, встроенная в Android.
Применение: Идеально подходит для хранения структурированных данных с отношениями, запросами и транзакциями.

5️⃣Content Providers:
Описание: Механизм для обмена данными между приложениями.
Применение: Используется для предоставления доступа к данным одного приложения другим приложениям. Часто используется для доступа к системным данным, таким как контакты, изображения и видео.
Пример (получение контактов):

      Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
cursor.close();


🤔 Кратко:

1️⃣SharedPreferences: Для хранения небольших настроек и данных пользователя.
2️⃣ Internal Storage: Для хранения приватных данных приложения.
3️⃣ External Storage: Для хранения данных, доступных вне приложения.
4️⃣ SQLite Database: Для хранения структурированных данных.
5️⃣ Content Providers: Для обмена данными между приложениями.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Какое ключевое слово используется для определения метода, который должен быть переопределен в подклассе?
Anonymous Quiz
50%
abstract
19%
open
31%
override
0%
final
📌 Для чего нужен StateFlow?

💬 Спрашивают в 7% собеседований

StateFlow – это специальный тип потока данных, используемый в Kotlin и библиотеке Kotlin Coroutines. Он предназначен для управления состоянием и передачи данных в реальном времени в реактивных приложениях. StateFlow основан на концепции потоков данных, аналогичной LiveData в Android, но с улучшенной поддержкой сопрограмм.

🤔 Основные особенности `StateFlow`

1️⃣ Горячий поток: StateFlow всегда активен и хранит последнее значение состояния. Подписчики получают текущее состояние немедленно после подписки.
2️⃣ Поддержка сопрограмм: Полностью интегрирован с Kotlin Coroutines, что позволяет легко использовать его в асинхронном коде.
3️⃣ Изменяемое состояние: StateFlow поддерживает изменение состояния через методы value или emit.

🤔 Почему нужен `StateFlow`

1️⃣ Реактивное программирование: StateFlow помогает создавать реактивные и асинхронные приложения, где состояние может изменяться динамически и пользователи получают обновления в реальном времени.
2️⃣ Предсказуемое состояние: В отличие от LiveData, StateFlow требует начальное состояние, что делает его состояние всегда предсказуемым и никогда не null.
3️⃣ Сопрограммы: Лучшая интеграция с Kotlin Coroutines по сравнению с LiveData.

🤔 Как использовать `StateFlow`

Создание `StateFlow`

Для создания StateFlow используется MutableStateFlow, который позволяет изменять его значение:
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

class MyViewModel : ViewModel() {
private val _state = MutableStateFlow("Initial State")
val state: StateFlow<String> get() = _state

fun updateState(newState: String) {
_state.value = newState
}
}


🤔 Пример: Подписка на StateFlow в Activity

import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

class CounterActivity : AppCompatActivity() {

private val viewModel: CounterViewModel by viewModels()

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

// Подписка на StateFlow
lifecycleScope.launch {
viewModel.count.collect { count ->
// Обновляем UI
textView.text = count.toString()
}
}

// Пример использования методов инкремента и декремента
incrementButton.setOnClickListener {
viewModel.increment()
}

decrementButton.setOnClickListener {
viewModel.decrement()
}
}
}

🤔 Кратко:
StateFlow – это поток данных для управления состоянием в Kotlin, который всегда содержит последнее состояние и работает с сопрограммами. Он используется для реактивного программирования, обеспечивая предсказуемое и синхронизированное обновление состояния в приложении.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👀1
🤔 Что произойдет при вызове функции с параметром по умолчанию, если параметр не указан?
Anonymous Quiz
14%
Ошибка компиляции
3%
Ошибка выполнения
6%
Параметр принимает значение null
77%
Используется значение по умолчанию
📌 Что используется для работы с сетью в Android?

💬 Спрашивают в 7% собеседований

Для работы с сетью в Android используются различные библиотеки и инструменты, обеспечивающие выполнение сетевых запросов, обработку ответов, и управление асинхронными операциями. Наиболее популярные и широко используемые инструменты включают:

1️⃣ HttpURLConnection:
Описание: Встроенный в Android класс для выполнения HTTP-запросов.
Применение: Подходит для простых сетевых операций без необходимости использования сторонних библиотек.
Пример:

      new Thread(() -> {
try {
URL url = new URL("https://api.example.com/data");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
// Обработка ответа
} finally {
urlConnection.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();


2️⃣OkHttp:
Описание: Мощная и популярная сторонняя библиотека для выполнения HTTP-запросов.
Применение: Предоставляет удобный API для работы с сетью, поддерживает кеширование, перехватчики, а также WebSocket.
Пример:

      OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
.url("https://api.example.com/data")
.build();

client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String responseData = response.body().string();
// Обработка ответа
}
}
});


3️⃣ Retrofit:
Описание: Сетевая библиотека, созданная на основе OkHttp, для упрощения взаимодействия с RESTful API.
Применение: Использует аннотации для описания HTTP-запросов и преобразует API в интерфейс, поддерживает конвертеры (например, JSON в POJO с использованием Gson или Moshi).

4️⃣ Volley:
Описание: Библиотека от Google для выполнения сетевых запросов с фокусом на простоте использования и производительности.
Применение: Поддерживает кеширование и управление очередями запросов.

5️⃣Ktor:
Описание: Асинхронный HTTP-клиент, написанный на Kotlin, подходит для выполнения HTTP-запросов в мультиплатформенных проектах.
Применение: Предоставляет удобный DSL для конфигурации запросов и обработки ответов.

🤔 Кратко:

Для работы с сетью в Android можно использовать HttpURLConnection для простых задач, а также сторонние библиотеки, такие как OkHttp, Retrofit, Volley и Ktor, для более сложных и мощных сетевых операций. Эти инструменты помогают управлять HTTP-запросами, обрабатывать ответы и поддерживать асинхронные операции.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Какой из следующих модификаторов используется для задания свойства, которое можно переопределить?
Anonymous Quiz
52%
open
23%
override
0%
final
25%
abstract
📌 Как делать сетевые запросы с помощью retrofit?

💬 Спрашивают в 7% собеседований

Чтобы делать сетевые запросы с помощью Retrofit, следуйте этим шагам:

1️⃣ Добавление зависимости Retrofit

Сначала добавьте зависимости для Retrofit и конвертера JSON в файл build.gradle вашего проекта:

dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}


2️⃣ Создание модели данных

Создайте класс, который будет представлять данные, полученные от API. Например, если ваш API возвращает информацию о пользователях, создайте класс User:
public class User {
private String name;
private String email;

// Геттеры и сеттеры
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}


3️⃣ Определение API-интерфейса

Создайте интерфейс, который описывает HTTP-запросы. Используйте аннотации Retrofit для указания типа запроса и конечной точки:
import retrofit2.Call;
import retrofit2.http.GET;

import java.util.List;

public interface ApiService {
@GET("users")
Call<List<User>> getUsers();
}


4️⃣ Настройка Retrofit

Создайте экземпляр Retrofit в вашем приложении. Обычно это делается в классе Application или в отдельном синглтоне:
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {
private static final String BASE_URL = "https://api.example.com/";
private static Retrofit retrofit = null;

public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}


5️⃣ Выполнение запроса

Теперь вы можете использовать созданный ApiService для выполнения сетевых запросов. Это обычно делается в активити или во ViewModel:
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import java.util.List;

public class MainActivity extends AppCompatActivity {
private ApiService apiService;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

apiService = ApiClient.getClient().create(ApiService.class);

fetchUsers();
}

private void fetchUsers() {
Call<List<User>> call = apiService.getUsers();
call.enqueue(new Callback<List<User>>() {
@Override
public void onResponse(Call<List<User>> call, Response<List<User>> response) {
if (response.isSuccessful()) {
List<User> users = response.body();
// Обработка полученных данных
for (User user : users) {
Toast.makeText(MainActivity.this, "User: " + user.getName(), Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(MainActivity.this, "Response Error " + response.code(), Toast.LENGTH_SHORT).show();
}
}

@Override
public void onFailure(Call<List<User>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Network Error: " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}


🤔 Кратко:

1️⃣Добавьте зависимости Retrofit в `build.gradle`.
2️⃣ Создайте модель данных, например, класс `User`.
3️⃣Определите интерфейс API с аннотациями Retrofit для запросов.
4️⃣ Настройте экземпляр Retrofit с помощью базового URL и конвертера JSON.
5️⃣ Используйте созданный `ApiService` для выполнения сетевых запросов и обработки результатов.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
🤔 Какой тип сборщика мусора используется в Kotlin/JVM?
Anonymous Quiz
52%
G1
21%
CMS
9%
Serial
18%
ZGC
👀8
📌 За что отвечает runtime?

💬 Спрашивают в 7% собеседований

🤔 Что такое Runtime в контексте Android?

Runtime (время выполнения) в контексте Android — это среда, в которой исполняется приложение. Она отвечает за выполнение кода, управление памятью и взаимодействие с операционной системой. В Android runtime включает такие компоненты, как:

1️⃣ Android Runtime (ART) или Dalvik Virtual Machine (DVM):
ART (начиная с Android 5.0) заменил DVM, который использовался в предыдущих версиях Android. ART и DVM — это виртуальные машины, которые выполняют байт-код, сгенерированный из Java-кода.
ART использует компиляцию Ahead-of-Time (AOT), что улучшает производительность приложений и снижает их потребление энергии по сравнению с Dalvik, который использует Just-In-Time (JIT) компиляцию.
Основные функции ART/DVM включают:
Загрузка классов: Загружает классы из скомпилированных .dex файлов.
Управление памятью: Управляет выделением и освобождением памяти для объектов.
Исполнение кода: Интерпретирует байт-код или выполняет его с использованием компиляции.

🤔 Основные функции и задачи Runtime

1️⃣Исполнение кода:
Runtime отвечает за выполнение кода приложения. ART/DVM интерпретирует и исполняет байт-код, сгенерированный из исходного кода.

2️⃣Управление памятью:
Управление памятью включает выделение памяти для новых объектов и освобождение памяти, которая больше не используется (сборка мусора).
ART имеет улучшенную систему управления памятью по сравнению с DVM, что способствует более эффективному использованию памяти и уменьшению пауз при сборке мусора.

3️⃣ Загрузка классов:
Runtime загружает классы по мере их необходимости. Это позволяет приложениям динамически загружать классы и модули.

4️⃣ Безопасность и управление разрешениями:
Runtime обеспечивает выполнение кода в изолированной среде, что предотвращает несанкционированный доступ к памяти и ресурсам устройства.
Управляет разрешениями, предоставленными пользователем для каждого приложения, и следит за тем, чтобы приложения соблюдали эти разрешения.

5️⃣ Обработка исключений:
Runtime обрабатывает исключения, возникающие во время выполнения программы, и позволяет приложениям реагировать на ошибки и сбои.

🤔 Пример работы Runtime

Рассмотрим простой пример создания и использования объекта в Java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Создание нового объекта
Person person = new Person("John", 30);

// Вызов метода объекта
String details = person.getDetails();
Log.d("MainActivity", details);
}
}

class Person {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getDetails() {
return "Name: " + name + ", Age: " + age;
}
}


В этом примере:

1️⃣ Загрузка классов: ART/DVM загружает классы MainActivity и Person.
2️⃣ Исполнение кода: Runtime выполняет код в методе onCreate, создавая объект Person и вызывая его метод getDetails.
3️⃣ Управление памятью: ART выделяет память для нового объекта Person и освобождает её, когда объект больше не нужен (например, при завершении активности или сборке мусора).
4️⃣ Обработка исключений: Если бы возникло исключение (например, NullPointerException), Runtime обработал бы его и вызвал соответствующий обработчик исключений.

🤔 Кратко:

Runtime в Android отвечает за выполнение кода приложения, управление памятью, загрузку классов, обеспечение безопасности и обработку исключений. ART (Android Runtime) является текущей реализацией runtime в Android и предлагает улучшенную производительность и управление памятью по сравнению с предыдущей версией (Dalvik).

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Какой интерфейс позволяет преобразовать suspend функцию в callback?
Anonymous Quiz
28%
CoroutineDispatcher
13%
ContinuationInterceptor
47%
Continuation
13%
SuspendFunction