5、Koltin相关面试题

kotlin面试题_码农乐园的博客-CSDN博客_kotlin面试题 

Kotlin协程是个什么东西? - 掘金

Kotlin 如何在 Android 上运行?

就像 Java 一样,Kotlin 代码也被编译成 Java 字节码,并在运行时由 Java 虚拟机即 JVM 执行。当一个名为 Kotlin 的文件Main.kt被编译后,它最终会变成一个类,然后生成该类的字节码。字节码文件的名称将是MainKt.class,并且该文件将由 JVM 执行。

 用val和const声明变量有什么区别?

声明的变量本质val上const都是不可变的。但是const变量的值必须在编译时知道,而val变量的值也可以在运行时分配。

安全调用(?.)和空值检查(!!)有什么区别?

安全调用运算符 ie?.用于检查变量的值是否为空。如果为 null 则返回 null ,否则返回所需的值。

var name: String? = "码农乐园"
println(name?.length) // 8
name = null
println(name?.length) // null


如果要在变量值为 null 时抛出 NullPointerException,则可以使用 null 检查或!!运算符。

var name: String? = "码农乐园"
println(name?.length) // 8
name = null
println(name!!.length) // KotlinNullPointerException

Kotlin 中是否有像 java 一样的三元运算符?

 Kotlin 中没有三元运算符,但可以通过 if-else 或 Elvis 运算符来使用三元运算符的功能。

 Kotlin 中的 Elvis 运算符是什么?

在 Kotlin 中,您可以使用 null 安全属性将 null 值分配给变量。要检查一个值是否具有空值,那么您可以使用 if-else 或可以使用 Elvis 运算符?:,例如:

var name:String? = "码农乐园"
val nameLength = name?.length ?: -1
println(nameLength)

上面使用的 Elvis 运算符(?:)将返回 name 的长度,如果 value 不为 null,否则如果 value 为 null,则返回-1。

如何将 Kotlin 源文件转换为 Java 源文件?

将 Kotlin 源文件转换为 Java 源文件的步骤:

在 IntelliJ IDEA / Android Studio 中打开您的 Kotlin 项目。

然后导航到工具 > Kotlin > 显示 Kotlin 字节码。

现在单击反编译按钮以从字节码中获取您的 Java 代码。

@JvmStatic、@JvmOverloads、@JvmFiled 在 Kotlin 中有什么用?

@JvmStatic:这个注解用来告诉编译器该方法是静态方法,可以在Java代码中使用。

@JvmOverloads:要在 Java 代码中使用 Kotlin 代码中作为参数传递的默认值,我们需要使用@JvmOverloads注解。

@JvmField:要在不使用任何 getter 和 setter 的情况下从 Java 代码访问 Kotlin 类的字段,我们需要@JvmField在 Kotlin 代码中使用。

Kotlin 中什么时候使用 lateinit 关键字?

lateinit是后期初始化。

通常,声明为非空类型的属性必须在构造函数中初始化。然而,这通常并不方便。

例如,可以通过依赖注入来初始化属性,或者在单元测试的 setup 方法中初始化属性。在这种情况下,您不能在构造函数中提供非 null 初始化程序,但您仍然希望在引用类主体内的属性时避免 null 检查。要处理这种情况,您可以使用 lateinit 修饰符标记该属性。

如何检查一个lateinit变量是否已经初始化?

您可以在方法的帮助下使用它之前检查 lateinit 变量是否已初始化isInitialized。如果 lateinit 属性已初始化,则此方法将返回 true,否则将返回 false。例如:

class Person {
        lateinit var name: String
        fun initializeName() {
                 println(this::name.isInitialized)
                 name = "MindOrks" // initializing name
                 println(this::name.isInitialized)
         }
}
fun main(args: Array) {
           Person().initializeName()
}


Kotlin 中的 lateinit 和 lazy 有什么区别?

lazy 只能用于 val 属性,而 lateinit 只能用于 var,因为它不能编译为 final 字段,因此不能保证不变性。

如果您希望您的属性以一种事先可能未知的方式从外部初始化,请使用 lateinit。
 

构造函数
kotlin中构造函数分为主构造函数和次构造函数。

主构造函数
主构造函数没有函数体,直接定义在类名后。每个类都会默认带一个不带参数的构造函数,也可以直接定义参数,如果需要在构造函数中进行初始化工作,可以用init关键字:

class Student {}

class Student(var name: String) {    

       init {        Log.e(TAG,"name=$name")    }

}

class Student constructor(var name: String) {  

       init {        Log.e(TAG,"name=$name")    }

}


次构造函数
除了类名后这种主构造函数,其他的构造函数方法就是通过constructor关键字来定义次构造函数,一个类可以定义多个次构造函数。如果主构造函数和次构造函数同时存在的时候,次构造函数必须调用主构造函数。

class Student{    

        private val username: String    

        constructor(username: String){        this.username = username    }

}

class Student(username: String) {    

        private var username: String    

        private var age: Int    

        init {        this.username = username        this.age = 10    }    

        constructor(username: String, age: Int) : this(username) {        this.age = age    }

}


协程
Kotlin协程是对线程的一种封装,同样是用来解决并发任务(异步任务)的方案,可以理解为一种线程框架,特点是挂起时不需要阻塞线程,更好的解决了线程切换,魔鬼调用的问题。

简单举个例子,具体的说明大家可以翻翻以前的文章——协程三问。

GlobalScope.launch(Dispatchers.Main) {    

        var name = ioTask()    

        updateUI(name)    

        var name1 = ioTask()    

        updateUI(name1)    

        var name2 = ioTask()    

        updateUI(name2)

}

private suspend fun ioTask(): String {    

        var name = ""  

         withContext(Dispatchers.IO) {     //耗时操作,比如网络接口访问        name = "jimu"    }  

         return name

}

GlobalScope.launch        去开启一个协程
Dispatchers.Main         表示运行在主线程
suspend        关键字用于标记挂起函数的关键字
withContext        函数用来构建一个协程作用域,可以标明作用线程,比如这里的Dispatchers.IO。这个函数必须在挂起函数或者协程中执行 

你可能感兴趣的:(Adroid面试题,android)