MST

星途 面试题库

面试题:Kotlin高阶函数的复杂应用场景

假设你正在开发一个游戏框架,其中有一系列的游戏任务。每个任务都有一个执行逻辑,并且任务之间可能存在依赖关系。请使用Kotlin高阶函数和Lambda表达式设计一个任务调度系统,能够根据任务的依赖关系正确执行任务,并且在任务执行前和执行后可以执行一些通用的逻辑(如记录日志)。
45.9万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试
class Task(
    val name: String,
    val dependencies: List<String>,
    val execute: () -> Unit
)

class TaskScheduler {
    private val tasks = mutableMapOf<String, Task>()
    private val taskExecutionOrder = mutableListOf<String>()

    fun registerTask(task: Task) {
        tasks[task.name] = task
    }

    fun scheduleTasks() {
        val visited = mutableSetOf<String>()
        fun dfs(taskName: String) {
            if (taskName in visited) return
            visited.add(taskName)
            val task = tasks[taskName]?: return
            task.dependencies.forEach { dfs(it) }
            taskExecutionOrder.add(taskName)
        }

        tasks.keys.forEach { dfs(it) }
    }

    fun executeTasks() {
        taskExecutionOrder.forEach { taskName ->
            val task = tasks[taskName]?: return
            logBeforeExecution(taskName)
            task.execute()
            logAfterExecution(taskName)
        }
    }

    private fun logBeforeExecution(taskName: String) {
        println("Before executing task: $taskName")
    }

    private fun logAfterExecution(taskName: String) {
        println("After executing task: $taskName")
    }
}

fun main() {
    val scheduler = TaskScheduler()

    scheduler.registerTask(Task("TaskA", emptyList()) {
        println("Executing TaskA")
    })

    scheduler.registerTask(Task("TaskB", listOf("TaskA")) {
        println("Executing TaskB")
    })

    scheduler.registerTask(Task("TaskC", listOf("TaskB")) {
        println("Executing TaskC")
    })

    scheduler.scheduleTasks()
    scheduler.executeTasks()
}
  1. Task
    • 用于表示一个任务,包含任务名称name,依赖的任务名称列表dependencies,以及实际执行任务的Lambda表达式execute
  2. TaskScheduler
    • tasks:用于存储所有注册的任务,以任务名称为键。
    • taskExecutionOrder:用于存储任务的执行顺序。
    • registerTask方法:用于注册任务到任务调度器中。
    • scheduleTasks方法:使用深度优先搜索(DFS)来确定任务的执行顺序,避免循环依赖。
    • executeTasks方法:按照确定的执行顺序执行任务,并且在每个任务执行前和执行后调用相应的日志记录方法。
    • logBeforeExecutionlogAfterExecution方法:用于记录任务执行前和执行后的日志。
  3. main函数
    • 创建一个TaskScheduler实例。
    • 注册三个任务,TaskA没有依赖,TaskB依赖TaskATaskC依赖TaskB
    • 调度任务并执行任务,观察输出结果。