Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+1 198новых вакансий за сутки·81 048вакансий открыто сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании6 803
РезюмеAIПодготовкаСтатьи
BoostТарифыBoost
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 400 кандидатов открыты к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python15 317
  • Облачные технологии11 512
  • QA вакансии3 347
  • Backend вакансии1 829
  • Инженер данных1 397
  • Продакт-менеджер842

Разработка

  • Android1 758
  • iOS1 639
  • AI вакансии875
  • Fullstack вакансии727
  • Frontend вакансии631
  • Mobile вакансии31

По стеку

  • Go8 413
  • Java5 383
  • Node.js1 730
  • Kotlin1 427
  • Rust1 387
  • .NET1 303
  • PHP554
  • C++394
  • C#373

DevOps и инфраструктура

  • Kubernetes6 474
  • DevOps вакансии4 845
  • Linux-инфраструктура4 834
  • Terraform / IaC3 590
  • Мониторинг и Observability1 636
  • CI/CD1 557
  • SRE504
  • Кибербезопасность245

Аналитика и данные

  • Data Scientist769
  • Аналитик данных748
  • Бизнес-аналитик722
  • Системный аналитик94

Другие направления

  • Проджект-менеджер338
  • UI/UX дизайн105
  • Ручное тестирование14

По регионам

  • Вакансии в США40 526
  • Вакансии в Европе16 981
  • Вакансии в Канаде3 889
  • Работа в России3 872

По формату

  • Удалённые вакансии64 846
  • Релокация в США40 528
  • Гибридная работа9 711
  • Офисная работа6 760

По уровню

  • Senior вакансии36 345
  • Middle вакансии17 248
  • Junior вакансии5 866

Сейчас нанимают

Все компании
  • Wise193 вакансии
  • Rakuten189 вакансий
  • ASML164 вакансии
  • Grab134 вакансии
  • Celonis45 вакансий
  • Spotify37 вакансий
  • Adyen29 вакансий
  • Infobip28 вакансий
  • Monzo19 вакансий
  • Darktrace17 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме KotlinВсе вопросы
KotlinMiddleТеория

Что такое inline functions в Kotlin и когда их стоит использовать?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

inline вставляет тело функции и лямбд прямо в место вызова, устраняя создание объектов-функций. Применяется для HOF в горячих путях и для reified-параметров, позволяющих обойти JVM type erasure.

Зачем нужен inline

Каждая лямбда в JVM — это экземпляр анонимного класса. При частых вызовах (например, в цикле) это создаёт давление на GC. С inline компилятор копирует байткод функции и лямбды прямо в вызывающий код:

// Без inline: создаётся объект Function1 на каждый вызов
fun repeat(times: Int, action: (Int) -> Unit) {
    for (i in 0 until times) action(i)
}

// С inline: лямбда встраивается в вызывающий код
inline fun repeatInlined(times: Int, action: (Int) -> Unit) {
    for (i in 0 until times) action(i)
}

fun main() {
    // Этот вызов компилируется так, будто вы написали for-цикл напрямую
    repeatInlined(1_000_000) { i ->
        println(i)
    }
}

Inline functions в Kotlin

Модификатор inline указывает компилятору вставить тело функции (и тела переданных лямбд) непосредственно в место вызова вместо создания объектов-функций и вызова через виртуальную диспетчеризацию. Это устраняет накладные расходы, связанные с лямбдами как объектами.

Non-local returns

Одно из важных свойств inline-функций: лямбды, переданные в них, могут использовать return для выхода из внешней функции (non-local return). В обычных функциях это запрещено.

inline fun findFirst(list: List<Int>, predicate: (Int) -> Boolean): Int? {
    for (item in list) {
        if (predicate(item)) return item // возврат из findFirst
    }
    return null
}

fun searchInList(): Int? {
    val numbers = listOf(1, 5, 3, 8, 2)
    // return выходит из searchInList целиком (non-local return)
    return findFirst(numbers) { it > 4 }
}

println(searchInList()) // 5

noinline и crossinline

Если функция inline, но конкретный лямбда-параметр не нужно встраивать (например, его передают дальше как объект), используется noinline. crossinline запрещает non-local return для конкретной лямбды, оставляя её встраиваемой.

inline fun process(
    data: String,
    noinline onComplete: () -> Unit, // не встраивается, можно сохранить в переменную
    crossinline transform: (String) -> String // встраивается, но без non-local return
) {
    val result = transform(data)
    scheduleCallback(onComplete) // onComplete передаётся как объект
    println(result)
}

fun scheduleCallback(cb: () -> Unit) { cb() }

Reified type parameters

Только inline-функции могут иметь параметры типа с reified — это позволяет использовать тип как реальный объект во время выполнения, обходя JVM type erasure:

inline fun <reified T> List<*>.filterByType(): List<T> {
    return filterIsInstance<T>()
}

inline fun <reified T> parseJson(json: String): T {
    // можно использовать T::class, T::class.java
    return jacksonObjectMapper().readValue(json, T::class.java)
}

fun main() {
    val mixed = listOf(1, "hello", 2.0, "world", 3)
    val strings = mixed.filterByType<String>()
    println(strings) // [hello, world]
}

Когда применять inline

  • Функции высшего порядка, вызываемые часто (в циклах, в методах коллекций).
  • Когда нужен reified тип-параметр.
  • Утилитарные функции-обёртки (try/catch wrappers, логирование времени и т.д.).
  • DSL-строители с lambda with receiver.
// Пример: измерение времени выполнения
inline fun <T> measureMs(block: () -> T): Pair<T, Long> {
    val start = System.currentTimeMillis()
    val result = block()
    val elapsed = System.currentTimeMillis() - start
    return result to elapsed
}

val (result, time) = measureMs {
    (1..1_000_000).sum()
}
println("Результат: $result, время: ${time}мс")

Подводные камни

  • Раздувание байткода (code bloat). Каждый вызов inline-функции копирует её тело. Если функция большая и вызывается в 100 местах, итоговый .class значительно увеличится.
  • Нельзя хранить noinline-параметры внутри inline-функций. Встроенная лямбда не существует как объект — попытка сохранить её в поле класса не скомпилируется без noinline.
  • Non-local return может быть неожиданным. Коллеги, использующие вашу inline-функцию, могут не ожидать, что return в лямбде выйдет из их функции.
  • inline не всегда даёт прирост. Для крупных функций или функций с малым числом вызовов встраивание не ускоряет код. JIT JVM сам оптимизирует частые вызовы.
  • Рекурсивные inline-функции запрещены. Компилятор не позволит inline-функции вызывать саму себя — это привело бы к бесконечному раскрытию кода.
  • reified не работает с обычными функциями. Попытка использовать reified без inline вызывает ошибку компиляции.
  • Видимость приватных членов. Встроенный код может обращаться к private-членам вызывающего класса, что нарушает инкапсуляцию — компилятор предупреждает об этом.

Частые вопросы на собеседовании

  • Что такое structured concurrency в Kotlin?
  • Для каких задач Kotlin является сильным выбором, а где лучше честно выбрать другой язык?
  • В чём разница между val и var в Kotlin?
  • В чём разница между List и MutableList в Kotlin?

Типичные ошибки

  • Объяснять «inline functions» только как синтаксис и не описывать поведение runtime/compiler.
  • Игнорировать важный риск: Чрезмерный inline раздувает bytecode и ухудшает читаемость stack traces.
  • Давать пример без edge case: отмены, null, recomposition, platform boundary или ошибки.

Что проверяет интервьюер

  • Формулирует суть темы «inline functions» своими словами и связывает ее с кодом.
  • Называет механизм: Особенно полезно для маленьких higher-order helpers, reified generics и DSL; noinline/crossinline ограничивают поведение lambda.
  • Видит production-последствие: Чрезмерный inline раздувает bytecode и ухудшает читаемость stack traces.

Как вы знаете этот вопрос?

Проверить себя по теме Kotlin →

Источники

  • https://kotlinlang.org/docs/inline-functions.html

Связанные темы

Kotlininline-functions-reasoningkotlin-language