如何通过 Kotlin 面试:热门问题详解与示例
Kotlin 已稳固确立为 Android 开发和 JVM 后端的现代语言。如果你正在准备技术面试,不仅需要了解语法,更重要的是理解这门语言的设计哲学:安全性、简洁性以及与 Java 的兼容性。本文将结合实际代码示例,解析 Kotlin 面试中最常问的关键问题。
1. 空安全:Kotlin 如何解决 null 问题
Kotlin 的主要卖点之一是其内置的针对 NullPointerException 的保护机制。在面试中,你一定会被问到可空类型和非空类型。
问题:String? 和 String 有什么区别?如何安全地处理可空类型?
答案:String 类型保证变量永远不会为 null。String? 允许为 null。安全访问时,会使用操作符 ?.、?:(Elvis 操作符)和 !!(仅在你 100% 确定时使用)。
fun main() { val name: String? = null // 安全调用 println(name?.length) // null // 默认值 val length = name?.length ?: 0 println(length) // 0 // 强制解包(有 NPE 风险) // println(name!!.length) // 错误!}附加问题:lateinit 和 lazy 是什么?
lateinit— 用于稍后初始化的变量(仅var)。lazy— 用于委托初始化(仅val)。
class User { lateinit var email: String val config by lazy { loadConfig() } fun init() { email = "test@example.com" }}2. 协程:无痛异步
协程是现代 Kotlin 的必备知识。面试官会考察你对 suspend、launch、async 以及调度器的理解。
问题:launch 和 async 有什么区别?
答案:launch 启动一个协程并返回一个 Job(无结果)。async 返回一个 Deferred,你可以通过 await() 从中获取结果。
suspend fun fetchData(): String { delay(1000) return "数据已加载"}
fun main() = runBlocking { // launch:无需结果 val job = launch { println("任务 1 完成") } // async:需要结果 val deferred = async { fetchData() } println(deferred.await()) // "数据已加载" job.join()}问题:你知道哪些调度器 (Dispatchers)?
Dispatchers.Main— 用于 UI (Android)。Dispatchers.IO— 用于输入/输出、网络请求。Dispatchers.Default— 用于 CPU 密集型任务。Dispatchers.Unconfined— 不绑定特定线程(很少使用)。
3. 扩展函数与密封类:扩展能力
Kotlin 允许在不使用继承的情况下向现有类添加新函数。这在架构相关的上下文中经常被问到。
问题:什么是扩展函数?请举例说明。
答案:扩展函数是在类外部声明,但作为该类方法调用的函数。它们不修改类本身,只是增加了语法糖。
// 为 String 定义扩展函数fun String.isEmail(): Boolean { return this.contains("@") && this.contains(".")}
fun main() { val email = "user@example.com" println(email.