Kotlin | Вопросы собесов
Открыть в Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv
Больше2 444
Подписчики
Нет данных24 часа
-187 дней
-2730 дней
Загрузка данных...
Похожие каналы
Облако тегов
Входящие и исходящие упоминания
---
---
---
---
---
---
Привлечение подписчиков
сентябрь '26
сентябрь '26
+4
в 0 каналах
август '26
+25
в 0 каналах
Get PRO
июль '26
+27
в 0 каналах
Get PRO
июнь '26
+23
в 1 каналах
Get PRO
май '26
+20
в 0 каналах
Get PRO
апрель '26
+30
в 0 каналах
Get PRO
март '26
+32
в 0 каналах
Get PRO
февраль '26
+46
в 0 каналах
Get PRO
январь '26
+54
в 0 каналах
Get PRO
декабрь '25
+23
в 0 каналах
Get PRO
ноябрь '25
+42
в 0 каналах
Get PRO
октябрь '25
+38
в 0 каналах
Get PRO
сентябрь '25
+44
в 0 каналах
Get PRO
август '25
+47
в 0 каналах
Get PRO
июль '25
+35
в 0 каналах
Get PRO
июнь '25
+46
в 0 каналах
Get PRO
май '25
+55
в 0 каналах
Get PRO
апрель '25
+57
в 0 каналах
Get PRO
март '25
+110
в 1 каналах
Get PRO
февраль '25
+105
в 2 каналах
Get PRO
январь '25
+159
в 53 каналах
Get PRO
декабрь '24
+59
в 0 каналах
Get PRO
ноябрь '24
+70
в 0 каналах
Get PRO
октябрь '24
+210
в 42 каналах
Get PRO
сентябрь '24
+608
в 251 каналах
Get PRO
август '24
+147
в 0 каналах
Get PRO
июль '24
+203
в 54 каналах
Get PRO
июнь '24
+492
в 244 каналах
Get PRO
май '24
+563
в 189 каналах
Get PRO
апрель '24
+461
в 23 каналах
| Дата | Привлечение подписчиков | Упоминания | Каналы | |
| 04 сентября | 0 | |||
| 03 сентября | +1 | |||
| 02 сентября | +3 | |||
| 01 сентября | 0 |
Посты канала
🤔 Сколько типов инстансов у nothing?
Nothing — это специальный bottom type (нижний тип), который означает:
Функция никогда не возвращает результат (throw, error()).
Код после Nothing недостижим.
fun fail(): Nothing {
throw IllegalStateException("Ошибка!") // Никогда не возвращает значение
}
🚩Почему `Nothing` не имеет инстансов?
Все классы в Kotlin могут иметь инстансы (объекты), кроме Nothing.
Nothing нельзя создать (instantiate), потому что он не имеет конструктора.
Любая переменная типа Nothing просто не существует.
val x: Nothing = Nothing() // ❌ Ошибка: у Nothing нет конструктора
🚩Где используется `Nothing`?
Используется в throw
fun fail(): Nothing = throw IllegalArgumentException("Ошибка")
Используется в TODO()
fun getData(): String {
TODO("Функция ещё не реализована")
}
Используется в if-else, где один вариант throw
fun getValue(x: Int): String {
return if (x > 0) "Позитивное число" else throw IllegalArgumentException("Отрицательное!")
}
Ставь 👍 и забирай 📚 Базу знаний| 2 | 🤔 В чём отличие обычного метода от extension метода в Kotlin?
Extension-функция выглядит как будто добавлена в класс, но на самом деле это статическая функция, которой не требуется менять сам класс. Она даёт синтаксический сахар, не добавляя нового в байткод класса.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний | 173 |
| 3 | 🤔 Как определить изменение скорости работы программы после наших действий?
🟠Profile GPU Rendering
Этот инструмент показывает время, затраченное на отрисовку каждого кадра. Использование этого инструмента позволяет выявить "тяжелые" кадры и измерить улучшения после оптимизации.
1⃣Включите режим разработчика на устройстве.
2⃣Перейдите в "Настройки" -> "Для разработчиков".
3⃣Включите опцию "Profile GPU Rendering" и выберите "On screen as bars".
4⃣Запустите ваше приложение и наблюдайте за графиками. Зеленые линии указывают на время отрисовки, и ваша цель - оставаться ниже 16 мс (для 60 кадров в секунду).
🟠Android Profiler
Предоставляет набор инструментов для анализа производительности приложения.
1⃣ Откройте Android Studio и запустите ваше приложение.
2⃣Перейдите в "View" -> "Tool Windows" -> "Profiler".
3⃣Выберите ваше устройство и запущенное приложение.
4⃣Используйте вкладки CPU, Memory, Network и Energy для анализа различных аспектов производительности.
5⃣Сравните данные до и после оптимизации.
🟠Benchmarking
Создание и использование тестов производительности помогает количественно оценить улучшения. Вы можете использовать библиотеку Jetpack Benchmark для создания и выполнения тестов производительности.
🚩Пример использования Jetpack Benchmark:
1⃣Добавьте зависимости в build.gradle:
dependencies {
androidTestImplementation "androidx.benchmark:benchmark-junit4:1.1.0"
androidTestImplementation "androidx.test:runner:1.3.0"
androidTestImplementation "androidx.test:rules:1.3.0"
}
2⃣Создайте класс теста:
import androidx.benchmark.junit4.BenchmarkRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ExampleBenchmark {
@get:Rule
val benchmarkRule = BenchmarkRule()
@Test
fun myFunctionBenchmark() {
benchmarkRule.measureRepeated {
// Вызов вашей функции или кода для тестирования производительности
myFunction()
}
}
}
🟠Logcat
Используйте журналирование для измерения времени выполнения определенных операций.
val startTime = System.currentTimeMillis()
// Ваш код
val endTime = System.currentTimeMillis()
Log.d("Performance", "Время выполнения: ${endTime - startTime} мс")
🟠StrictMode
StrictMode помогает обнаружить операции, которые могут замедлить работу приложения, такие как работа с сетью или базой данных в главном потоке.
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build()
)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build()
)
}
🟠Systrace
Systrace позволяет собирать и анализировать трассировки производительности системы, предоставляя детализированные данные о времени выполнения различных операций.
1⃣Включите режим разработчика на устройстве.
2⃣В "Настройки" -> "Для разработчиков" включите "Enable GPU Debug Layers".
3⃣Запустите команду adb shell am broadcast -a com.android.systemui.screenshot.ScreenshotService.ACTION_SYSTRACE.
Ставь 👍 и забирай 📚 Базу знаний | 183 |
| 4 | 🤔 Что такое сущность Observable?
Это объект, который может производить данные (события) и передавать их подписчикам (Observer). Он используется для работы с асинхронными потоками данных. Основные возможности:
1. Генерация данных.
2. Обработка данных через операторы.
3. Управление подпиской и отпиской.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний | 216 |
| 5 | 🤔 Что такое утечки памяти?
Это ситуация, когда приложение выделяет память для каких-либо объектов, но затем не освобождает её, даже когда эти объекты больше не нужны. Это приводит к тому, что используемая память накапливается, что может со временем замедлить работу приложения и привести к его аварийному завершению (крашу) из-за нехватки доступной памяти.
🚩Почему происходят утечки памяти в Android?
В Android утечки памяти могут возникнуть из-за особенностей работы виртуальной машины (ART или Dalvik), а также из-за того, что сборщик мусора (Garbage Collector, GC) не может освободить память для объектов, на которые по-прежнему существуют ссылки. Это происходит в следующих случаях:
🟠Долгоживущие ссылки
Если объект ссылается на другой объект, который больше не нужен, последний не может быть освобождён GC. Например:
Статические ссылки, которые продолжают "удерживать" объект.
Замыкания (closures), которые хранят ссылки на контекст активности.
🟠Неявные ссылки
Некоторые объекты системы Android, такие как Context, View, Handler, хранят ссылки на компоненты приложения (например, Activity), из-за чего их нельзя освободить.
🟠Неправильное использование API
Ошибки, такие как регистрация слушателей (listeners) без последующей отписки, использование таймеров, которые продолжают работать даже после уничтожения активности, и так далее.
🚩Пример утечки памяти
public class MyActivity extends AppCompatActivity {
private static TextView myTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTextView = findViewById(R.id.my_text_view);
myTextView.setText("Hello, Memory Leak!");
}
}
Исправленный код
public class MyActivity extends AppCompatActivity {
private TextView myTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTextView = findViewById(R.id.my_text_view);
myTextView.setText("Hello, World!");
}
}
🚩Как избежать утечек памяти?
🟠Избегайте долгоживущих ссылок на объекты активности или контекста
Не используйте static для объектов, ссылающихся на Context или Activity. Используйте WeakReference, если нужно сохранить ссылку, которая не должна блокировать сборщик мусора.
🟠Отключайте слушателей и callback-методы
Если вы регистрируете слушателей (например, через setOnClickListener), обязательно удаляйте их в методах жизненного цикла, например, в onDestroy().
🟠Осторожно используйте анонимные классы и лямбда-выражения
Анонимные классы (например, Runnable, Handler) могут неявно хранить ссылки на внешние классы, что может привести к утечке памяти.
🟠Используйте инструменты для выявления утечек памяти
Android Profiler: встроенный инструмент Android Studio для мониторинга использования памяти. LeakCanary: библиотека, которая автоматически обнаруживает утечки памяти в вашем приложении.
Ставь 👍 и забирай 📚 Базу знаний | 226 |
| 6 | 🚨60 минут
Пожизненный PRO-доступ на easyoffer (подготовка к IT-собесам + поиск оффера) по цене одного года закрывается прямо сейчас. Один платёж — доступ навсегда.
Последнее напоминание 👇
👉 https://easyoffer.ru/pro | 39 |
| 7 | ⚠️ 3 часа до конца акции.
Последний шанс забрать пожизненный PRO на easyoffer по цене одного года. Это полный доступ к подготовке к собесам и инструментам поиска работы (вопросы с реальных интервью, ответы сеньоров, автоотклики, тренажёры) — один раз и навсегда, вместо ежегодной оплаты.
В полночь цена возвращается к обычной.
👉 https://easyoffer.ru/pro | 88 |
| 8 | 🤔 Как сделать метод потокобезопасным?
Использовать ключевое слово synchronized — оно не даёт методу быть вызванным из двух потоков одновременно. Можно также использовать блокировки (Lock) или атомарные типы (AtomicInteger).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний | 271 |
| 9 | 🤔 Как подключить BroadcastReceiver, чтобы он смог получать сообщения?
Подключение BroadcastReceiver в Android состоит из двух основных шагов: создание самого ресивера и его регистрация. Ресивер можно зарегистрировать как статически в манифесте, так и динамически в коде.
🚩Создание BroadcastReceiver
Создадим простой BroadcastReceiver, который будет реагировать на определённое событие, например, на получение SMS.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Сообщение получено!", Toast.LENGTH_SHORT).show();
}
}
🚩Регистрация ресивера
🟠Статическая регистрация в манифесте
Можно зарегистрировать ресивер в файле AndroidManifest.xml. Это удобно, когда вы хотите, чтобы ресивер всегда был активен и слушал определённые системные события, например, перезагрузку устройства или получение SMS.
<manifest xmlns:android="http://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>
🟠Динамическая регистрация в коде
Иногда нужно регистрировать ресивер только на время выполнения определённой активности или службы. В этом случае лучше использовать динамическую регистрацию.
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);
}
}
Ставь 👍 и забирай 📚 Базу знаний | 265 |
| 10 | ⏳ Ребята, сегодня заканчивается акция, о которой стоит знать, если вы в поиске работы или планируете сменить её в ближайший год.
easyoffer — это платформа для подготовки к IT-собесам и поиска оффера. Внутри:
– база реальных вопросов и live-coding задач с собесов (с частотой их встречаемости)
– эталонные ответы от Senior-разработчиков
– 1100+ записей настоящих интервью (Сбер, Яндекс, Авито, WB, OZON, МТС)
– автоотклики на hh, генератор резюме под вакансию, тренажёры собеседований
Сегодня пожизненный PRO-доступ продаётся по цене одного года — платишь один раз и пользуешься всем этим всю жизнь, включая будущие фичи. С завтрашнего дня — только обычная годовая подписка.
👉 https://easyoffer.ru/pro | 155 |
| 11 | 🤔 Какие есть реализации коллекций?
- ArrayList, LinkedList,
- HashSet, TreeSet, LinkedHashSet,
- HashMap, TreeMap, LinkedHashMap,
- PriorityQueue, ArrayDeque.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний | 263 |
| 12 | 🤔 Зачем нужен DiffUtil?
DiffUtil — это утилита для быстрого обновления списков в RecyclerView. Она сравнивает старый и новый список и находит различия, чтобы обновлять только изменённые элементы, а не весь список.
🚩Проблема без `DiffUtil`
Обычное обновление списка без DiffUtil перерисовывает всё, даже если изменился один элемент.
adapter.notifyDataSetChanged() // Полностью обновляет список ❌
🟠Решение с `DiffUtil`
DiffUtil находит различия между старым и новым списком и обновляет только изменённые элементы.
class MyDiffUtilCallback(
private val oldList: List<User>,
private val newList: List<User>
) : DiffUtil.Callback() {
override fun getOldListSize() = oldList.size
override fun getNewListSize() = newList.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].id == newList[newItemPosition].id
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition] == newList[newItemPosition] // Используем data class (авто `equals()`)
}
}
🚩Как использовать `DiffUtil` в `RecyclerView.Adapter`?
После создания DiffUtil.Callback, вызываем DiffUtil.calculateDiff() и передаём результат в adapter.
fun updateList(newList: List<User>) {
val diffCallback = MyDiffUtilCallback(userList, newList)
val diffResult = DiffUtil.calculateDiff(diffCallback)
userList = newList // Обновляем старый список
diffResult.dispatchUpdatesTo(this) // Обновляем только изменённые элементы
}
🟠`ListAdapter` – ещё проще!
Если используем ListAdapter, DiffUtil уже встроен.
class UserAdapter : ListAdapter<User, UserViewHolder>(DIFF_CALLBACK) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_user, parent, false)
return UserViewHolder(view)
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
holder.bind(getItem(position)) // `getItem()` уже работает с `ListAdapter`
}
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<User>() {
override fun areItemsTheSame(oldItem: User, newItem: User): Boolean =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: User, newItem: User): Boolean =
oldItem == newItem
}
}
}
Обновление списка в ListAdapter
adapter.submitList(newList) // DiffUtil работает внутри 🚀
Ставь 👍 и забирай 📚 Базу знаний | 274 |
| 13 | Пожизненный PRO — по цене одного года.
Покупаешь один раз — пользуешься всю жизнь:
👉 https://easyoffer.ru/pro
🚀 PRO-доступ закроет 99% проблем на пути к офферу:
1. 1100+ записей реальных собеседований (включая топы: Сбер, Авито, Яндекс, WB, OZON, МТС). Видите всё изнутри: как спрашивают, как отвечают сильные кандидаты и на каких ошибках проваливаются 80%.
2. База live-coding задач и вопросов с реальных собесов — с уникальной системой вероятности их встречи. Готовитесь не вслепую, а точечно по темам, которые спрашивают чаще всего.
3. Эталонные ответы от Senior-разработчиков. Никакой воды и догадок — только чёткие структурированные решения, за которые дают «зелёный свет» к офферу.
4. Полный доступ ко всем грейдам и профессиям. Junior вы или Senior, тестировщик, разработчик или проджект — вы получаете ВСЕ материалы easyoffer без ограничений. Безлимитно, Все, Навсегда.
5. База 400+ тестовых заданий. Прокачивайте навыки на реальных задачах — тех самых, что дают перед собесом.
6. Автоотклики на hh.ru — пока вы спите, резюме уходит рекрутерам автоматически. Экономия сотен часов ручного кликанья.
7. Аналитика ТОП-требований из вакансий. Парсим рынок и показываем, какие скиллы сейчас в цене. Апгрейдите резюме точечно и проходите ATS-фильтры (они отсеивают до 75% резюме ещё до рекрутера).
8. Генератор резюме и CV под каждую вакансию. Забудьте про «универсальное» резюме — нейросеть адаптирует ваш опыт под конкретную позицию за минуту и повышает шансы на приглашение в разы.
9. Тренажёры подготовки к собеседованию:
«Реальное собеседование» — сценарий вопросов из настоящих интервью. «Проработка вопросов» — флеш-карточки по методике интервальных повторений (как Anki)
10. 🔥 Самое важное: все будущие фичи
Вы платите один раз, а продукт растёт всю жизнь. Каждое обновление, каждый новый инструмент, каждая фича, которая появится за все годы проекта, автоматически падает вам в подписку без доплат. Вы фиксируете цену года, а получаете продукт, который через пару лет будет стоить в разы дороже
⭐️ Это уникальная акция пока сайт в режиме Beta.
Успей ей воспользоваться⏳ Завтра последний день.
👉 https://easyoffer.ru/pro | 181 |
| 14 | 🤔 Как эффективно изменить данные в списке, состоящем из большого количества View?
Для списков с большим количеством View лучше использовать DiffUtil, который вычисляет разницу между старым и новым списками. Это позволяет обновить только те элементы, которые изменились, без перерисовки всего списка, что значительно повышает производительность.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний | 264 |
| 15 | 🔥 Осталось 3 дня!
Пожизненный easyoffer PRO по цене одного года. Покупаешь один раз – пользуешься всю жизнь.
Что входит в PRO:
– Вопросы и задачи с реальных собеседований в конкретных компаниях
– Лучшие ответы и видео-примеры от middle/senior специалистов
– Записи реальных собеседований
– Обход фильтров ATS с топ-30 ключевых слов в резюме
– Автоотклики на hh
– Тренажёры и симуляторы для идеальной подготовки к интервью
⏳ Акция действует только до 2 сентября 23:59 по МСК
👉 Забрать PRO со скидкой 70%: https://easyoffer.ru/pro | 222 |
| 16 | 🤔 Какие знаешь особенности системы типов в Kotlin ?
🟠Null Safety (Безопасность null)
Переменные по умолчанию не могут быть null, что предотвращает NullPointerException.
var a: String = "abc"
var b: String? = "abc"
b = null // Допустимо
🟠Коллекции (Collections)
Разделение на изменяемые и неизменяемые коллекции.
val list: List<String> = listOf("a", "b", "c") // Неизменяемый список
val mutableList: MutableList<String> = mutableListOf("a", "b", "c") // Изменяемый список
🟠Data Classes (Классы данных)
Автоматическое создание методов equals(), hashCode(), и toString().
data class User(val name: String, val age: Int)
🟠Smart Casts (Умные приведения типов)
Автоматическое приведение типа после проверки с помощью is.
fun demo(x: Any) {
if (x is String) {
println(x.length)
}
}
🟠Sealed Classes (Запечатанные классы)
Упрощают обработку ограниченных иерархий классов.
sealed class Expr
data class Const(val number: Double) : Expr()
🟠Выведение типов (Type Inference)
Kotlin автоматически определяет тип переменной.
val x = 10 // Int
Ставь 👍 и забирай 📚 Базу знаний | 287 |
| 17 | Ты ищешь только по верхушке айсберга 🧊
Вбиваешь «Android разработчик» и думаешь, что видел всё. А под водой скрывается ещё 80% вакансий, которые называются иначе: «мобильный разработчик», «Kotlin engineer», «SDK developer» и так далее.
Рекрутеры не договариваются между собой о названиях. Поэтому те, кто ищут по одному запросу, просто сливают лучшие предложения.
В свежем посте на канале я собрал полный список из 15 рабочих запросов для разных площадок + список самих площадок, где эти вакансии реально публикуют.
Забирай список и перестань терять вакансии 👇
Android Оффер | 209 |
| 18 | 🤔 Какая особенность у Data Class относительно других Kotlin Classes?
Data Class автоматически генерирует equals, hashCode, toString, copy, и componentN функции. Они удобны для хранения данных и значительно упрощают работу с неизменяемыми структурами.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний | 288 |
| 19 | 🤔 Расскажи о контрактах equals и hashCode
Методы equals() и hashCode() используются для сравнения объектов и их корректной работы в коллекциях (Set, Map).
🚩Контракт `equals()`
Метод equals() должен:
Рефлексивность: a.equals(a) → true (объект равен самому себе).
Симметричность: a.equals(b) == b.equals(a).
Транзитивность: если a == b и b == c, то a == c.
Согласованность: если a == b, то a.equals(b) всегда возвращает одно и то же, пока объект не изменится.
Сравнение с null всегда даёт false: a.equals(null) == false.
class User(val name: String, val age: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true // Проверка на ссылочное равенство
if (other !is User) return false // Проверка типа
return name == other.name && age == other.age // Сравнение полей
}
}
val user1 = User("Alice", 25)
val user2 = User("Alice", 25)
println(user1 == user2) // true (потому что переопределён equals)
🚩Контракт `hashCode()`
Метод hashCode() должен:
Согласованность с equals(): если a == b, то a.hashCode() == b.hashCode().
Но обратное не обязательно: два разных объекта могут иметь одинаковый hashCode().
Хеш-код не должен меняться, если объект не изменился.
class User(val name: String, val age: Int) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is User) return false
return name == other.name && age == other.age
}
override fun hashCode(): Int {
return name.hashCode() * 31 + age // 31 - стандартный коэффициент
}
}
val userSet = HashSet<User>()
userSet.add(User("Alice", 25))
println(userSet.contains(User("Alice", 25))) // true
🚩Автоматическая генерация в Kotlin
Чтобы не писать equals() и hashCode() вручную, можно использовать data class:
data class User(val name: String, val age: Int)
data class автоматически создаёт equals(), hashCode(), а также copy() и toString().
val user1 = User("Alice", 25)
val user2 = User("Alice", 25)
println(user1 == user2) // true (equals)
println(user1.hashCode() == user2.hashCode()) // true
Ставь 👍 и забирай 📚 Базу знаний | 305 |
| 20 | 🤔 Как работает async/await?
async запускает асинхронную корутину, возвращающую Deferred, аналог Future.
await приостанавливает выполнение до получения результата. Это позволяет параллельно выполнять задачи и синхронно работать с результатом.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний | 330 |
