Android开发高频面试题之——kotlin篇

发布于:2024-09-19 ⋅ 阅读:(14) ⋅ 点赞:(0)

Android开发高频面试题之——kotlin篇

Android开发高频面试题之——Java基础篇
Android开发高频面试题之——Kotlin基础篇
Android开发高频面试题之——Android基础篇

1. Kotlin如何实现空安全的?

  • Kotlin 将变量划分为可空和不可空,通过查看字节码可知,声明不可空的变量会加 @NonNull注解,会告诉编译器检查变量是否可空。声明可空的变量会加 @Nullable注解
  • Kotlin 提供了空安全操作符 ?相当于实现了非空判断,当对象不为空时才执行操作,否则不执行。保证了空安全
//场景1,m1方法接收一个不可能为null的字符串
//在其方法体中我们获取了传入字符串的长度
fun m1(str: String) {
   
    str.length
}
//场景2,m2方法接收一个可能为null的字符串
//在其方法体中我们采用了安全调用操作符 ?. 来获取传入字符串的长度
fun m2(str: String?) {
   
    str?.length
}
//场景3,m3方法接收一个可能为null的字符串
//在其方法体中我们采用了 !!  来获取传入字符串的长度
fun m3(str: String?) {
   
    str!!.length
}

  public final static m1(Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   L0
    ALOAD 0
    LDC "str"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
   L1
    LINENUMBER 6 L1
    ALOAD 0
    INVOKEVIRTUAL java/lang/String.length ()I
    POP
   L2
    LINENUMBER 7 L2
    RETURN
   L3
    LOCALVARIABLE str Ljava/lang/String; L0 L3 0
    MAXSTACK = 2
    MAXLOCALS = 1

// access flags 0x19
  public final static m2(Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
   L0
    LINENUMBER 10 L0
    ALOAD 0
    DUP
    IFNULL L1
    INVOKEVIRTUAL java/lang/String.length ()I
    POP
    GOTO L2
   L1
    POP
   L2
   L3
    LINENUMBER 11 L3
    RETURN
   L4
    LOCALVARIABLE str Ljava/lang/String; L0 L4 0
    MAXSTACK = 2
    MAXLOCALS = 1

 public final static m3(Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
   L0
    LINENUMBER 15 L0
    ALOAD 0
    DUP
    IFNONNULL L1
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.throwNpe ()V
   L1
    INVOKEVIRTUAL java/lang/String.length ()I
    POP
   L2
    LINENUMBER 16 L2
    RETURN
   L3
    LOCALVARIABLE str Ljava/lang/String; L0 L3 0
    MAXSTACK = 3
    MAXLOCALS = 1

2. 谈谈你对协程的理解

协程可以看做是官方封装的轻量级线程框架。线程是由系统调度的,线程切换或线程阻塞的开销都比较大。而协程依赖于线程,但是协程挂起时不需要阻塞线程,几乎是无代价的,协程是由开发者控制的。所以协程也像用户态的线程,非常轻量级,一个线程中可以创建任意个协程。

  • 协程与线程有什么区别:
    ·Kotlin协程,不是操作系统级别的概念,无需操作系统支持,线程是操作系统级别的概念,我们开发者通过编程语言(Thread,java)创建的线程,本质还是操作系统内核线程的映射。
  • Kotlin协程,是用户态的(userleve),内核对协程无感知;一般情况下,我们说的线程,都是内核线程,线程之间的切换,调
    度,都由操作系统负责。
  • Kotlin协程,是协作式的,由开发者管理,不需要操作系统进行调度和切换,也没有抢占式的消耗,因比它更加高效;线程,是
    抢占式的,它们之间能共享内存资源。
  • Kotlin协程,它底层基于状态机实现,多协程之间共用一个实例,资源开销极小,因比它更加轻量;线程会消耗操作系统资源。
  • Kotlin协程,本质还是运行于线程之上,它通过协程调度器,可以运行到不同的线程上
    优点:
  • 轻量和高效:协程可以在一个线程中开启1000个协程,也不会有什么影响。
  • 简单好用:其实轻量和高效并不是协程的核心竞争力,最主要的还是简化异步并发任务,代码中可以已同步的方式替换异步,去除java中回调地狱问题。

3. 了解密封类(Sealed Classes)吗

可以理解成是Enum枚举类的加强版

  • Sealed class(密封类) 是一个有特定数量子类的类,看上去和枚举有点类似,所不同的是,在枚举中,我们每个类型只有一个对象(实例);而在密封类中,同一个类可以拥有几个对象。
  • Sealed class(密封类)的所有子类都必须与密封类在同一文件中
  • Sealed class(密封类)的子类的子类可以定义在任何地方,并不需要和密封类定义在同一个文件中
  • Sealed class(密封类)没有构造函数,不可以直接实例化,只能实例化内部的子类
sealed class SealedClass{
   
    class SealedClass1():SealedClass()
    class SealedClass2():SealedClass()
    fun hello(){
   
        println("Hello World ... ")
    }
}
fun main(args:Array<String>){
   
    var sc:SealedClass = SealedClass()//这里直接编译报错
}
fun main(args:Array<String>){
   
    var sc:SealedClass = SealedClass.SealedClass1()//只能通过密封类内部的子类实例化对象,这时就可以执行里面的方法了
    sc.hello()
}

使用场景:与when表达式搭配

// Result.kt
sealed class Result<out T : Any> {
   
   data class Success<out T : Any>(val data: T) : Result<T>()
   data class Error(val exception: Exception) : Result<Nothing>()
}

    when(result) {
   
        is Result.Success -> {
    }
        is Result.Error -> {
    

网站公告

今日签到

点亮在社区的每一天
去签到