💡 Инструкция: Выберите один ответ из пяти. На 20 вопросов отведено 55 минут. В каждом задании верен только один вариант. После завершения будут показаны общий результат и 4 тематических шкал.
Вопрос 7 из 20
Что стоит исправить в «Общее состояние замыканий» перед слиянием?
Kotlin Захват значений · Общее состояние замыканий Копировать
// Сохраните назначение фрагмента, но укрепите его контракт.
fun counters(): List<() -> Int> {
var n = 0
return List(3) { { ++n } }
}
fun main() = println(counters().map { it() })
Ограничиться поясняющим комментарием о том, что будет выведен `[3, 3, 3]`, так как инкремент выполняется при создании списка.
Сохранить API и считать достаточным условие: Будет выведен `[1, 1, 1]`, потому что каждая лямбда получает копию n.
Перенести проверку в вызывающий код, исходя из того, что возникнет `ConcurrentModificationException` при последовательных вызовах.
Сделать состояние явным объектом или создать отдельную локальную переменную на итерацию, если счётчики должны быть независимыми.
Спрятать участок за вспомогательной функцией, сохранив предположение: Код не компилируется: лямбда не может менять захваченную `var`.
Вопрос 10 из 20
На каком входе или состоянии граница «Общее состояние замыканий» становится заметной?
Параллельные вызовы лямбд с общим `var` создают гонку: захват не добавляет атомарности или синхронизации.
Проверить, сохраняется ли контракт, когда возникнет `ConcurrentModificationException` при последовательных вызовах.
Добавить регрессию на гипотезу: Будет выведен `[1, 1, 1]`, потому что каждая лямбда получает копию n.
Зафиксировать сценарий, где ожидается: Код не компилируется: лямбда не может менять захваченную `var`.
Проверить крайний ввод, при котором будет выведен `[3, 3, 3]`, так как инкремент выполняется при создании списка.
Вопрос 13 из 20
Решение для «Общее состояние замыканий»: Сделать состояние явным объектом или создать отдельную локальную переменную на итерацию, если счётчики должны быть независимыми. Что в нём остаётся не бесплатным?
Замыкание удобно для небольшого состояния, но скрытое совместное владение ухудшает тестируемость и конкурентную безопасность.
Сопровождение усложнится, если окажется, что код не компилируется: лямбда не может менять захваченную `var`.
После правки останется ограничение: Возникнет `ConcurrentModificationException` при последовательных вызовах.
Решение оправдано лишь при условии: Будет выведен `[1, 1, 1]`, потому что каждая лямбда получает копию n.
Обратная сторона изменения состоит в том, что будет выведен `[3, 3, 3]`, так как инкремент выполняется при создании списка.
Вопрос 15 из 20
Что изменить в «Лямбда после круглых скобок», чтобы скрытое допущение стало явным контрактом?
Kotlin Завершающая лямбда · Лямбда после круглых скобок Копировать
// Сохраните назначение фрагмента, но укрепите его контракт.
fun collect(prefix: String, block: (Int) -> String): String =
(1..3).joinToString(prefix = prefix, transform = block)
fun main() = println(collect("[") { n -> "$n]" })
Оставить структуру прежней, документировав утверждение: Будет напечатано `1], 2], 3]`, поскольку prefix теряется после вынесения лямбды.
Перенести проверку в вызывающий код, исходя из того, что будет напечатано `[1][2][3]`, потому что prefix применяется к каждому элементу.
Вынести участок в отдельный метод, считая верным следующее: Код не компилируется: trailing lambda разрешена только без других аргументов.
Использовать trailing lambda, когда она представляет исходное действие вызова; параметры конфигурации оставлять явно названными.
Обернуть операцию проверкой и не менять основной контракт: Возникнет ошибка из-за отсутствующего separator.
Вопрос 17 из 20
Как укрепить «Функция как значение», не переписывая соседние модули?
Kotlin Функциональные типы · Функция как значение Копировать
// Сохраните назначение фрагмента, но укрепите его контракт.
fun applyTwice(x: Int, f: (Int) -> Int) = f(f(x))
fun main() = println(applyTwice(3) { it + 2 })
Добавить защитную проверку перед фрагментом, поскольку будет выведено `5`, потому что результат первого вызова не передаётся во второй.
Называть функциональный параметр по роли и при сложном контракте заменить голую сигнатуру на `fun interface`.
Перенести проверку в вызывающий код, исходя из того, что будет выведено `12`, поскольку лямбда умножается на число вызовов.
Оставить реализацию без изменений и закрепить тестом предположение: Код не компилируется без явного типа параметра `it`.
Оставить структуру прежней, документировав утверждение: Возникнет ошибка, так как функцию нельзя вызвать больше одного раза.