KT Kotlin  ·  30 вопросов  ·  ~85 мин  ·  ⏱ Таймер 25:00  ·  Сложный  · 

Архитектура Kotlin-приложения

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

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. На 30 вопросов отведено 85 минут. В каждом задании верен только один вариант. После завершения будут показаны общий результат и 6 тематических шкал.
Вопрос 1 из 30
Какой архитектурный выигрыш у такой модели?
KotlinДоменные модели · Инварианты Account
// Проследите фактическое выполнение без изменения кода.
@JvmInline value class AccountId(val value: String)

data class Account private constructor(val id: AccountId, val balance: Money) {
    companion object {
        fun open(id: AccountId): Account = Account(id, Money.ZERO)
    }
    fun debit(amount: Money): Account {
        require(amount > Money.ZERO && amount <= balance)
        return copy(balance = balance - amount)
    }
}
Вопрос 2 из 30
Какое объяснение результата «Доменный порт и internal adapter» выдерживает проверку соседними случаями?
KotlinГраницы модулей · Доменный порт и internal adapter
// На ревью требуется объяснить причину поведения.
// domain module
data class Order(val id: String)
interface OrderRepository { suspend fun save(order: Order) }

// infrastructure module
internal interface Database { suspend fun insert(order: Order) }
internal class SqlOrderRepository(
    private val database: Database
) : OrderRepository {
    override suspend fun save(order: Order) = database.insert(order)
}
Вопрос 3 из 30
Какая правка устраняет причину риска в «Атомарное обновление StateFlow», а не только его проявление?
KotlinПотоки состояния · Атомарное обновление StateFlow
// Сохраните назначение фрагмента, но укрепите его контракт.
import kotlinx.coroutines.flow.*
class Store(initial: AppState) {
    private val _state = MutableStateFlow(initial)
    val state: StateFlow<AppState> = _state.asStateFlow()
    fun dispatch(action: Action) { _state.update { reduce(it, action) } }
}
Вопрос 4 из 30
Какой сценарий выявит скрытое ограничение «Контекст запроса в корутине»?
Вопрос 5 из 30
Какой побочный эффект существеннее остальных после правки «Автоматическая проверка зависимостей»: Формулировать несколько значимых правил с понятным сообщением, а спорные решения документировать ADR и проверять интеграционными сценариями?
Вопрос 6 из 30
Какой принцип выражен в `AppRuntime`?
KotlinАрхитектура и конкурентность · Владелец фонового lifecycle
// Проследите фактическое выполнение без изменения кода.
import kotlinx.coroutines.*
class AppRuntime(
    private val scope: CoroutineScope,
    private val jobs: List<BackgroundService>
) {
    fun start() = jobs.map { it.start(scope) }
    suspend fun stop() { scope.cancel(); scope.coroutineContext[Job]?.join() }
}
Вопрос 7 из 30
Какой рефакторинг делает поведение «Доменный порт и internal adapter» предсказуемее?
KotlinГраницы модулей · Доменный порт и internal adapter
// Сохраните назначение фрагмента, но укрепите его контракт.
// domain module
data class Order(val id: String)
interface OrderRepository { suspend fun save(order: Order) }

// infrastructure module
internal interface Database { suspend fun insert(order: Order) }
internal class SqlOrderRepository(
    private val database: Database
) : OrderRepository {
    override suspend fun save(order: Order) = database.insert(order)
}
Вопрос 8 из 30
Какой редкий случай способен сломать наивную трактовку «Атомарное обновление StateFlow»?
Вопрос 9 из 30
Какой риск не исчезает после правки «Контекст запроса в корутине»: Редактировать чувствительные поля, логировать решение один раз на границе и добавить SLO-метрики/спаны для зависимостей?
Вопрос 10 из 30
Что произойдёт при запуске примера «Автоматическая проверка зависимостей»?
KotlinТестирование и инструменты · Автоматическая проверка зависимостей
// Проследите фактическое выполнение без изменения кода.
@Test fun architecture_rules() {
    classes().that().resideInAPackage("..domain..")
        .should().onlyDependOnClassesThat(resideIn("..domain..", "kotlin.."))
        .check(importedClasses)
}
Вопрос 11 из 30
Какой контракт снимает спор о причине поведения «Владелец фонового lifecycle»?
KotlinАрхитектура и конкурентность · Владелец фонового lifecycle
// На ревью требуется объяснить причину поведения.
import kotlinx.coroutines.*
class AppRuntime(
    private val scope: CoroutineScope,
    private val jobs: List<BackgroundService>
) {
    fun start() = jobs.map { it.start(scope) }
    suspend fun stop() { scope.cancel(); scope.coroutineContext[Job]?.join() }
}
Вопрос 12 из 30
Какой контракт определяет наблюдаемый результат «Инварианты Account»?
KotlinДоменные модели · Инварианты Account
// На ревью требуется объяснить причину поведения.
@JvmInline value class AccountId(val value: String)

data class Account private constructor(val id: AccountId, val balance: Money) {
    companion object {
        fun open(id: AccountId): Account = Account(id, Money.ZERO)
    }
    fun debit(amount: Money): Account {
        require(amount > Money.ZERO && amount <= balance)
        return copy(balance = balance - amount)
    }
}
Вопрос 13 из 30
Что может усложниться в сопровождении после изменения «Атомарное обновление StateFlow»: Сериализовать side effects отдельно, не выполнять сеть внутри update и публиковать immutable AppState?
Вопрос 14 из 30
Чего не хватает для полноценного расследования редких сбоев?
KotlinДиагностика аварии · Контекст запроса в корутине
// Проследите фактическое выполнение без изменения кода.
import kotlinx.coroutines.*
suspend fun handle(request: Request): Response = withContext(MDCContext()) {
    logger.info { "start id=${request.id}" }
    service.execute(request)
}
Вопрос 15 из 30
Что точнее описывает механику фрагмента «Автоматическая проверка зависимостей»?
KotlinТестирование и инструменты · Автоматическая проверка зависимостей
// На ревью требуется объяснить причину поведения.
@Test fun architecture_rules() {
    classes().that().resideInAPackage("..domain..")
        .should().onlyDependOnClassesThat(resideIn("..domain..", "kotlin.."))
        .check(importedClasses)
}
Вопрос 16 из 30
Что стоит исправить в «Владелец фонового lifecycle» перед слиянием?
KotlinАрхитектура и конкурентность · Владелец фонового lifecycle
// Сохраните назначение фрагмента, но укрепите его контракт.
import kotlinx.coroutines.*
class AppRuntime(
    private val scope: CoroutineScope,
    private val jobs: List<BackgroundService>
) {
    fun start() = jobs.map { it.start(scope) }
    suspend fun stop() { scope.cancel(); scope.coroutineContext[Job]?.join() }
}
Вопрос 17 из 30
Какую правку выбрать, чтобы сохранить назначение «Инварианты Account» и убрать хрупкость?
KotlinДоменные модели · Инварианты Account
// Сохраните назначение фрагмента, но укрепите его контракт.
@JvmInline value class AccountId(val value: String)

data class Account private constructor(val id: AccountId, val balance: Money) {
    companion object {
        fun open(id: AccountId): Account = Account(id, Money.ZERO)
    }
    fun debit(amount: Money): Account {
        require(amount > Money.ZERO && amount <= balance)
        return copy(balance = balance - amount)
    }
}
Вопрос 18 из 30
Какой редкий случай способен сломать наивную трактовку «Доменный порт и internal adapter»?
Вопрос 19 из 30
Почему пример «Контекст запроса в корутине» даёт именно такой результат?
KotlinДиагностика аварии · Контекст запроса в корутине
// На ревью требуется объяснить причину поведения.
import kotlinx.coroutines.*
suspend fun handle(request: Request): Response = withContext(MDCContext()) {
    logger.info { "start id=${request.id}" }
    service.execute(request)
}
Вопрос 20 из 30
Какую правку выбрать, чтобы сохранить назначение «Автоматическая проверка зависимостей» и убрать хрупкость?
KotlinТестирование и инструменты · Автоматическая проверка зависимостей
// Сохраните назначение фрагмента, но укрепите его контракт.
@Test fun architecture_rules() {
    classes().that().resideInAPackage("..domain..")
        .should().onlyDependOnClassesThat(resideIn("..domain..", "kotlin.."))
        .check(importedClasses)
}
Вопрос 21 из 30
Что добавить в регрессионный набор для «Владелец фонового lifecycle»?
Вопрос 22 из 30
Какой контрпример точнее всего показывает границу «Инварианты Account»?
Вопрос 23 из 30
Что может усложниться в сопровождении после изменения «Доменный порт и internal adapter»: Проверять архитектурными тестами запрещённые imports и не создавать интерфейс без реальной границы/вариативности?
Вопрос 24 из 30
Почему `update` предпочтительнее `state.value = reduce(state.value, action)` при конкуренции?
KotlinПотоки состояния · Атомарное обновление StateFlow
// Проследите фактическое выполнение без изменения кода.
import kotlinx.coroutines.flow.*
class Store(initial: AppState) {
    private val _state = MutableStateFlow(initial)
    val state: StateFlow<AppState> = _state.asStateFlow()
    fun dispatch(action: Action) { _state.update { reduce(it, action) } }
}
Вопрос 25 из 30
Какой сценарий выявит скрытое ограничение «Автоматическая проверка зависимостей»?
Вопрос 26 из 30
Какое ограничение сохранится после правки «Владелец фонового lifecycle»: Использовать SupervisorJob при независимости сервисов, хранить дочерние Jobs, задавать порядок stop/close и ограниченный graceful timeout?
Вопрос 27 из 30
В «Инварианты Account» выбрали решение: Возвращать доменный результат для ожидаемого отказа, отделить Money currency и покрыть переходы property-based тестами. Какова его реальная цена?
Вопрос 28 из 30
Что защищает такая зависимость?
KotlinГраницы модулей · Доменный порт и internal adapter
// Проследите фактическое выполнение без изменения кода.
// domain module
data class Order(val id: String)
interface OrderRepository { suspend fun save(order: Order) }

// infrastructure module
internal interface Database { suspend fun insert(order: Order) }
internal class SqlOrderRepository(
    private val database: Database
) : OrderRepository {
    override suspend fun save(order: Order) = database.insert(order)
}
Вопрос 29 из 30
Какое правило определяет поведение фрагмента «Атомарное обновление StateFlow»?
KotlinПотоки состояния · Атомарное обновление StateFlow
// На ревью требуется объяснить причину поведения.
import kotlinx.coroutines.flow.*
class Store(initial: AppState) {
    private val _state = MutableStateFlow(initial)
    val state: StateFlow<AppState> = _state.asStateFlow()
    fun dispatch(action: Action) { _state.update { reduce(it, action) } }
}
Вопрос 30 из 30
Как укрепить «Контекст запроса в корутине», не переписывая соседние модули?
KotlinДиагностика аварии · Контекст запроса в корутине
// Сохраните назначение фрагмента, но укрепите его контракт.
import kotlinx.coroutines.*
suspend fun handle(request: Request): Response = withContext(MDCContext()) {
    logger.info { "start id=${request.id}" }
    service.execute(request)
}

Ответьте на все 30 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу