Kotlin | Вопросы собесов
2.57K subscribers
28 photos
965 links
Download Telegram
🤔 Вставка значения быстрее в 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
👍6🤔1
🤔 Что положить в state для отображения первоначального списка?

Для отображения первоначального списка в state можно положить пустой массив, если данные загружаются асинхронно, или заранее подготовленный статический список, если данные известны на момент загрузки приложения. Например, если список продуктов подгружается из API, начальное состояние будет пустым массивом, который заполняется после загрузки. Это позволяет избежать ошибок рендеринга до загрузки данных.

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

В Android при нажатии пользователя на экран вызывается событие ACTION_DOWN.

🚩Разбор работы событий касания

Android использует систему обработки касаний через MotionEvent. Когда пользователь касается экрана, система генерирует разные типы событий:
ACTION_DOWN – вызывается в момент первого касания.
ACTION_MOVE – вызывается, когда пользователь двигает палец по экрану.
ACTION_UP – вызывается, когда пользователь убирает палец с экрана.
ACTION_CANCEL – вызывается, если система прерывает касание (например, из-за входящего звонка).

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

Для обработки событий касания нужно переопределить метод onTouchEvent() в View или использовать setOnTouchListener().
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("TouchEvent", "Палец коснулся экрана")
return true
}
MotionEvent.ACTION_UP -> {
Log.d("TouchEvent", "Палец отпущен")
}
}
return super.onTouchEvent(event)
}


Можно также назначить слушатель
view.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
Log.d("TouchEvent", "Нажатие зафиксировано")
true
} else {
false
}
}


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

Данные из разных источников нужно объединить, преобразовать в единый формат и отфильтровать, чтобы привести их к структуре, удобной для отображения. Например, если данные о продуктах поступают из API и локальной базы данных, их нужно объединить, исключить дублирующиеся записи и сохранить в state. Это делается для обеспечения консистентности и удобства использования в UI.


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

В Kotlin инициализаторы используются для выполнения кода при создании экземпляра класса.
Первичный (primary) конструктор
Вторичные (secondary) конструкторы
Инициализационный блок (init)

🟠Первичный конструктор
Это основной способ инициализации класса в Kotlin. Он объявляется в заголовке класса.
class User(val name: String, val age: Int)


Если нужно выполнить дополнительную логику во время создания объекта, используют блок init:
class User(val name: String, val age: Int) {
init {
println("Создан пользователь: $name, возраст: $age")
}
}


🟠Вторичные конструкторы
Они объявляются с помощью constructor и нужны, если:
Нужно несколько способов создания объекта.
Надо вызвать другой конструктор (this(...)).
class User {
var name: String
var age: Int

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

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


Можно создать объект так
val user1 = User("Алекс")   // возраст будет 18  
val user2 = User("Иван", 25)


Если есть первичный конструктор, вторичный должен его вызывать через this(...)
class User(val name: String, val age: Int) {
constructor(name: String) : this(name, 18)
}


🟠`init` vs вторичный конструктор
init выполняется всегда при вызове первичного конструктора.
Вторичный конструктор создаёт альтернативный способ создания объекта.
class User(val name: String, val age: Int) {
init {
println("Создан пользователь: $name, возраст: $age")
}

constructor(name: String) : this(name, 18) {
println("Вызван вторичный конструктор")
}
}


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

Можно использовать такие механизмы, как RxJava, Kotlin Coroutines, или встроенные функции маппинга, например, map, filter, reduce. Эти инструменты позволяют асинхронно преобразовывать данные, соединять их в единую структуру и подготавливать для использования в интерфейсе. Например, объединение данных с помощью combine в Coroutines позволяет синхронизировать несколько потоков данных.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
🤔 Можешь привести пример, когда android фреймворк использует паттерн Factory?

Да, Android Framework активно использует паттерн Factory в различных API. Один из самых известных примеров — LayoutInflater.

🚩Пример: `LayoutInflater` (Фабричный метод)

В Android для создания (инстанцирования) UI-компонентов из XML используется LayoutInflater, который реализует паттерн Factory Method. Вместо того чтобы вручную создавать объекты View, система предоставляет фабричный метод inflate(), который "производит" экземпляры View.

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

В XML описан интерфейс.
LayoutInflater загружает XML и создает соответствующие объекты View.
Это абстрагирует создание UI-компонентов от разработчика.
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.custom_layout, parent, false)


🚩Другие примеры использования Factory в Android

🟠`MediaPlayer.create()`
Вместо MediaPlayer() напрямую используется MediaPlayer.create(context, R.raw.sound), который автоматически создаёт и настраивает объект.

🟠`PreferenceManager.getDefaultSharedPreferences()`
Позволяет получить SharedPreferences без необходимости вручную создавать экземпляр.

🟠`Fragment.instantiate()`
Фабричный метод для создания Fragment без явного вызова конструктора.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 По результатам нужно отобразить Snackbar или Toast, как это сделаешь?

Для отображения Toast можно использовать Toast.makeText(context, "Message", LENGTH).show(), а для Snackbar – Snackbar.make(view, "Message", LENGTH).show(). Toast чаще используется для кратких уведомлений, а Snackbar – для сообщений с действиями, например, кнопкой "Отменить". Snackbar также требует привязки к определённому view.


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

При пересоздании Activity (например, при повороте экрана) состояние ScrollView или RecyclerView сбрасывается. Чтобы этого избежать, можно сохранить и восстановить позицию скролла.

🟠Использование `onSaveInstanceState()`
Android позволяет сохранять данные в Bundle перед уничтожением Activity, а затем восстанавливать их.
class MainActivity : AppCompatActivity() {
private lateinit var scrollView: ScrollView

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

scrollView = findViewById(R.id.scrollView)

// Восстанавливаем позицию скролла
savedInstanceState?.let {
val scrollY = it.getInt("scroll_position", 0)
scrollView.post { scrollView.scrollTo(0, scrollY) }
}
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("scroll_position", scrollView.scrollY)
}
}


🟠Для `RecyclerView`
У RecyclerView уже есть встроенный механизм сохранения состояния через LinearLayoutManager.
class MainActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var layoutManager: LinearLayoutManager

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

layoutManager = LinearLayoutManager(this)
recyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = MyAdapter()

// Восстанавливаем позицию скролла
savedInstanceState?.let {
val scrollPosition = it.getInt("recycler_position", 0)
recyclerView.post { layoutManager.scrollToPosition(scrollPosition) }
}
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("recycler_position", layoutManager.findFirstVisibleItemPosition())
}
}


🟠Использование `android:freezesText` для `EditText`
Если EditText находится внутри ScrollView, можно включить android:freezesText="true", чтобы автоматически сохранять данные.
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:freezesText="true"/>


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

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

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

Map – это коллекция пар ключ-значение. Каждый ключ уникален, а значения могут повторяться. В Kotlin Map не наследуется от Collection, но является частью стандартных коллекций.

🟠Виды `Map` в Kotlin
В Kotlin есть два основных типа Map:
Map (неизменяемая) – нельзя добавлять/удалять элементы после создания.
MutableMap (изменяемая) – можно добавлять, удалять и изменять элементы.

Создаётся с помощью mapOf()
val users = mapOf(1 to "Alice", 2 to "Bob", 3 to "Charlie")
println(users[1]) // Выведет: Alice


Создаётся с помощью mutableMapOf()
val users = mutableMapOf(1 to "Alice", 2 to "Bob")
users[3] = "Charlie" // Добавляем элемент
users[1] = "Alex" // Изменяем значение по ключу
users.remove(2) // Удаляем элемент
println(users) // {1=Alex, 3=Charlie}


🟠Основные операции с `Map`
map[key] – получить значение (или null, если ключа нет).
map.getValue(key) – получить значение (или исключение, если ключа нет).
map.getOrDefault(key, defaultValue) – вернуть значение или defaultValue, если ключа нет.
map.getOrElse(key) { default } – если ключа нет, выполнить лямбда-выражение.
val users = mapOf(1 to "Alice", 2 to "Bob")
println(users[1]) // Alice
println(users.getOrDefault(3, "Unknown")) // Unknown


🟠Проверка наличия ключей и значений
map.containsKey(key) – есть ли ключ?
map.containsValue(value) – есть ли значение?
println(users.containsKey(2))  // true
println(users.containsValue("Charlie")) // false


Перебор элементов
for ((key, value) in users) {
println("ID: $key, Name: $value")
}


Фильтрация Map
val filtered = users.filter { (key, value) -> key % 2 == 0 }
println(filtered) // {2=Bob}


🚩Особенности `Map` в Kotlin

🟠Порядок элементов
mapOf() – не гарантирует порядок. linkedMapOf() – сохраняет порядок добавления.
🟠Производительность
Обычный HashMap (mutableMapOf()) – O(1) для поиска по ключу. TreeMapO(log n), но поддерживает сортировку по ключам.

val sortedUsers = sortedMapOf(3 to "Charlie", 1 to "Alice", 2 to "Bob")
println(sortedUsers) // {1=Alice, 2=Bob, 3=Charlie}


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

Переход со списков на детализацию реализуется с помощью навигационных инструментов: Intent (в Android), NavController (в Jetpack Navigation), роутеров во фреймворках, таких как React Router. Данные об элементе передаются через Bundle или параметры, чтобы на экране детализации отобразить всю информацию об объекте.

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

В Kotlin для работы с многопоточностью можно использовать atomic переменные или synchronized блоки. Они помогают избежать гонок данных (race conditions), когда несколько потоков одновременно изменяют одну и ту же переменную.

🚩Когда использовать `atomic` переменные?

Atomic переменные (AtomicInteger, AtomicLong, AtomicReference и др.) используются, когда нужно быстро и безопасно обновлять одно значение без блокировки потока.
Высокая производительность – атомарные операции работают быстрее, чем synchronized.
Потокобезопасность – операции выполняются без блокировок (lock-free).
Удобство – простые методы incrementAndGet(), compareAndSet() и т. д.
Работает только с одним значением – не подходит для сложных операций.
Не подходит для зависимых изменений (например, если изменение одной переменной зависит от другой).

import java.util.concurrent.atomic.AtomicInteger

val counter = AtomicInteger(0)

fun increment() {
counter.incrementAndGet() // Увеличиваем значение безопасно
}


🟠Когда использовать `synchronized`?
Используется, когда нужно защитить сразу несколько связанных операций от одновременного выполнения в нескольких потоках.
Подходит для сложных операций с несколькими переменными.
Работает с любыми типами данных.
Снижает производительность – потоки ждут, пока один поток закончит работу.
Может вызывать deadlock (взаимную блокировку).
val lock = Any()
var count = 0

fun increment() {
synchronized(lock) {
count++ // Только один поток может изменять `count` одновременно
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤯1🎉1
🤔 Какая разница между диалогом и фрагментом?

Это небольшое окно для взаимодействия с пользователем (например, подтверждение действия), которое закрывается после выполнения задачи. Фрагмент – это независимый компонент интерфейса, который может содержать сложные элементы и использоваться для создания динамических экранов, заменяя их в активности.


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

В Kotlin есть множество удобных функций для получения одного элемента или списка элементов из коллекций (List, Set, Map). Какую функцию использовать — зависит от задачи.

🚩Получение одного элемента

🟠`get(index)` и `getOrNull(index)`
получение по индексу
Если индекс может выйти за границы массива, лучше использовать getOrNull().
val list = listOf("A", "B", "C")

println(list[1]) // "B"
println(list.getOrNull(5)) // null


🟠`first()` и `last()`
первый и последний элементы
println(list.first())  // "A"
println(list.last()) // "C"

Используйте firstOrNull() или lastOrNull(), если список может быть пустым
println(emptyList<String>().firstOrNull())  // null


🟠`find {}` и `findLast {}`
поиск по условию Возвращает первый или последний элемент, удовлетворяющий условию.
val numbers = listOf(10, 20, 30, 40)

println(numbers.find { it > 15 }) // 20
println(numbers.findLast { it > 15 }) // 40
println(numbers.find { it > 50 }) // null


🟠`single()` и `singleOrNull()`
если ожидается только один элемент
val oneElementList = listOf(42)
println(oneElementList.single()) // 42
println(oneElementList.singleOrNull()) // 42

val emptyList = emptyList<Int>()
println(emptyList.singleOrNull()) // null

single() бросает исключение, если элементов нет или их больше одного.

🚩Получение нескольких элементов (списка)

filter {} – фильтрация элементов по условию
val numbers = listOf(1, 2, 3, 4, 5)
val evenNumbers = numbers.filter { it % 2 == 0 }
println(evenNumbers) // [2, 4]


take(n) и takeLast(n) – первые/последние n элементов
val items = listOf("a", "b", "c", "d", "e")

println(items.take(3)) // [a, b, c]
println(items.takeLast(2)) // [d, e]


slice(indices) – получение элементов по индексам
val sliced = items.slice(listOf(0, 2, 4))
println(sliced) // [a, c, e]


map {} – преобразование списка
val squared = numbers.map { it * it }
println(squared) // [1, 4, 9, 16, 25]


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41
Forwarded from easyoffer
💡 В EasyOffer 2.0 появится фильтрация вопросов по грейдам и типам интервью!

📊 Например, вот вероятности ТОП-30 вопросов, которые задают на HR-скрининге Python-разработчику уровня Middle/Senior. Данные основаны на 53 реальных интервью.

97% Какие у тебя зарплатные ожидания
73% Какие у тебя есть вопросы
44% Какие критерии при выборе будущей работы
41% Расскажи о себе
38% Почему ищешь работу
35% Расскажи про свой опыт
35% Расскажи про проект на предыдущей работе
32% Почему уволился с предыдущей работы
29% Где территориально сейчас живешь/находишься
23% Есть ли другие предложения по работе
17% Есть ли военный билет
17% Почему хочешь сменить работу
17% Как проводишь свободное время
17% Расскажи про задачи на предыдущей работе
17% Сколько коммерческого опыта работы с Python
17% С какими БД работал
14% Находишься ли в активном поиске работы
14% С каким стеком работаешь
14% Почему решил откликнуться на нашу вакансию
14% Какой текущий статус поиска работы
11% Почему решил стать программистом
11% С какими фреймворками работал
11% Какую зарплату получал на предыдущей работе
11% Работаешь ли в настоящий момент
11% На какой грейд себя оцениваешь
11% Как быстро можешь приступить к работе после получения офера
11% Расскажи про свои pet-проекты
8% Какие знаешь типы данных в Python
8% Что такое декоратор в Python
8% Что ищешь на новой работе

🚀 Скоро стартует краудфандинговая кампания, которая поможет ускорить разработку EasyOffer 2.0.
Первые спонсоры получат уникальные лимитированные награды!

📢 Если вам это интересно, подписывайтесь на канал 👉 этот телеграм канал
🤔 Какую стратегию использовать для метода present state?

Для управления состоянием следует использовать стратегию unidirectional data flow (однонаправленный поток данных), как в Redux или MVI. Это гарантирует, что состояние представлено одним источником истины и изменяется только через заранее определённые действия, обеспечивая предсказуемость и простоту отладки.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
🤔 Расскажи о контрактах 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


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

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

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

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

🚩Лямбда-выражения

Были введены в Java 8 и являются частью усилий по добавлению функциональных возможностей в язык. Лямбды в Java чаще всего используются с функциональными интерфейсами, которые являются интерфейсами с одним абстрактным методом.
(parameters) -> expression


или
(parameters) -> { statements; }


🚩Лямбда-выражения

Поддерживает более гибкие и выразительные лямбды по сравнению с Java. Лямбды могут использоваться как с функциональными интерфейсами, так и в качестве части синтаксиса языка, благодаря чему Kotlin особенно удобен для функционального программирования.
{ parameters -> code body }


🚩Примеры

Лямбда без параметров
{ println("Hello, World!") }  


Лямбда с одним параметром
{ a: Int -> a * a }   


Лямбда с несколькими параметрами
{ a: Int, b: Int -> a + b }   


Лямбда с телом, содержащим несколько выражений
      { s: String ->
println(s)
s.length
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Три основных проблемы в многопоточности?

1. Состояние гонки: возникает, когда несколько потоков одновременно изменяют общий ресурс, вызывая непредсказуемое поведение.
2. Дедлок: блокировка потоков, когда каждый поток ждёт ресурсы, занятые другим потоком.
3. Утечки памяти: при неправильной синхронизации объектов или их несвоевременном освобождении.


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