kotlin面试题看这一篇就行了

最近有换工作打算,能用kotlin做项目和能回答面试官关于kotlin的问题是两回事, 于是就在网上搜了搜相关面试题,发现内容千篇一律且少的可怜。于是就用英语在谷歌上搜了搜看,发现国内文章也是翻译国外的。 你翻译归翻译,为什么就不能全面一点。内容丰富一点。果然找资料搜问题还是得用英文。。。。。

原文

希望这篇文章能够帮助大家:

  1. 什么是kotlin
    Kotlin 是一个运行在JVM上的静态类型的程序语言。它可以使用Java源码或者LLVM编译器编译
  1. kotlin的开发者是谁?
    JetBrains.

  2. 为什么要从java转换到kotlin
    相对于java,kotlin语言更简单。能减少代码的冗余以及一些Java不支持的特性。

  3. 使用kotlin三个最重要的优势
    1.易学,语法与java相似
    2.基于jvm的函数式语言,移除了很多样板代码。
    3.让代码更易读,更易理解

  4. 解释扩展函数的使用
    扩展函数有助于扩展类而不需要继承类

  5. 空安全在kotlin意味着什么?
    空安全特性让kotlin移除了实时出现的空指针异常的风险。区分空引用和非空引用也是可能的。

  6. 为什么kotlin和java是可交互的
    因为它也使用jvm字节码。把它直接编译成字节码有助于实现更快的编译时间且对于jvm而言和java无差异

  7. Kotlin中是否有像java那样的三元操作符
    没有

  8. Kotlin中如何声明变量
    var my_var:Int

  9. Kotlin中有多少有效构造函数
    两类构造函数 1.主要构造函数 2.次级构造函数

  10. Kotlin支持哪几种编程类型
    1.面向过程 2.面向对象

  11. Kotlin提供java.io.File的扩展函数的名字
    1.bufferedReader():用于读取一个文件到BufferedReader
    2.readBytes():用于读取文件内容到字节数组
    3.readText():用于读取文件内容到单个字符串
    4.forEachLine():用于一行一行的读取一个文件 5.readLines():用于读取文件中的行到List中

  12. kotlin如何处理空指针异常?
    Elvis操作符用于处理空指针异常 val l: Int = if (b != null) b.length else -1 可替换为:val l = b?.length ?: -1

  13. kotlin有而java没有的特性
    1.空指针安全
    2.操作符重载
    3.协程
    4.Range 表达式
    5.智能转换
    6.伴随体

  14. kotlin中数据类的使用
    数据类型持有基础数据类型,不包含任何功能

  15. 我们能把代码从java迁移到kotlin 么?
    可以,IDEA提供一个 内置的工具来进行迁移

  16. Kotlin支持宏指令么?
    不支持

  17. Kotlin类的默认行为?
    Kotlin中所有的类默认为final.
    Kotlin支持多继承,Open class比final class造成更多开销

  18. Kotlin是否支持原始数据类型?

  19. 什么是ranges操作符?
    Ranges操作符帮助遍历一个范围。操作符形式 是(…),例如: for (i in 1..15)

  20. Kotlin能为标准java包或类提供额外的函数
    (kotlin程序能像其他java代码那样在jvm上运行。且允许jvm把任何程序编译成字节码。使用java虚拟机是可访问的,因此,kotlin跟java相似。此外,Kotlin应用能用部分java代码构建)能

  21. 声明一个volatile 变量
    Volatile var x: Long? = null

  22. Abstraction在kotlin中的用处?
    抽象是oop中最重要的概念。 在kotlin, 抽象类当你知道一个类应该有什么功能。但是你不清楚功能怎么实现或者功能能用不同方法实现。

  23. 如何比较两个字符串?
    1.== 操作符
    2.compoareTo()扩展函数

  24. 这段代码干了什么?

bar {
System.out.println("Guru99!")
}

该代码传入了一个lambda表达式函数给函数 bar(),这个函数打印 “”Guru99!”。

  1. kotlin的目标平台是什么?
    为什么kotlin-java的交互是可能的 JVM是ktolin的目标平台。Kotlin百分百可与java交互,因为两者都编译生成字节码。 因此Kotlin能把Java调用,反之亦然。

  2. 如何声明变量,且与java有何不同。
    Kotlin 以val, var 开头,跟可选类型,ktolin用类型引用自动推断类型。

  3. 声明的val 和var有何不同
    val变量不可变,于java中final修饰符类似。 Var 可再被赋值,且必须为同类型。

  4. 什么是空安全和可空类型,什么是Elvis操作符
    kotlin非常重视空安全。 通过使用可空类型(String?, Int?, Float?等)来阻止空指针异常。 Elvis操作符 newStr = str?: "Default Value" , 右边的值将被使用如果str为空

  5. 什么是 const? 和val有什么区别?
    Val是在运行时被 设置, 加一个const 修饰符在val上将会变成编译时常量。 Const不能修饰var,不能用于局部变量

  6. Kotlin的入口
    main函数

  7. !!操作符 和?.操作符 在打开可空变量时有什么区别? 是否有其他方式安全的打开可空类型。
    !!操作符强行打开可空类型。如何返回值是Null,可导致运行时崩溃。 因此!!只用于你确定这个值不会为空。 ?.是一个Elvis操作符可是安全的调用。 我们可以用lambda表达式 let来安全的调用

  8. 函数如何声明? 为什么kotlin函数被称为顶级函数 ?
    fun sumOf(a:int, b:Int):Int{ return a+b}
    kotlin中的函数能在kotlin根文件中声明

  9. == 和=== 的区别?
    ==比较双方的值是否相等, ===比较双方引用是否相等。

  10. 列举出kotlin的可见修饰符, 什么是默认的可见修饰符?
    Public, internal, protected, private public是默认的修饰符

  11. 如下的集成结构能否编译?
    Class A{} classB:A(){} 不能,ktolin的默认类是final的,你需要加Open修饰符

  12. Kotlin构造函数类型? 区别是什么?如何在类中定义?
    首要构造函数-在类头中定义,不能持有任何逻辑,每个类只有一个首要构造函数。 次要构造函数-定义于类体中。如何存在必须代理给首要构造函数,可以有逻辑。且可有多于一个次要构造函数。

  13. 什么是kotlin init代码块
    init是Kotlin初始化器,它在首要构造函数实例化后被调用。Init 块的代码在次级构造函数调用之前调用。即使没有主要构造函数,该函数将被隐性调用。

  14. 字符串插入在Kotlin中怎么工作。 用一个代码块解释。
    val name = "Journaldev.com" val desc = "$name now has Kotlin Interview Questions too. ${name.length}" 用$在字符串中增加变量,用美元符号+{}来计算表达式 (美元符号会转义,所以部分用中文代替)

  15. 构造函数中的参数类型是?
    默认为val, 除非明确设置成var

  16. Kotlin中是否有new关键字?
    如何实例化一个类对象 没有, var a = A()

  17. Kotlin switch关键字的替换是什么? 有和区别?
    When, default 用else来替换 var num = 10 when (num) { 0..4 -> print("value is 0") 5 -> print("value is 5") else -> { print("value is in neither of the above.") } }

  18. Kotlin中数据类是什么? 什么使它如此有用? 如何定义?
    在java中,创建一个数据类存贮数据,你需要设置变量,getter和setter,重写toString, hash() 和copy()函数。 在kotlin中,只需要在类头增加data关键字,上述所有都被自动生成。

19.Kotlin中的解构声明是什么? 用个例子来解释
解构声明是一种从objects/arrays 灵活的给多个变量赋予值的方式

1.png

  1. Inline函数和Infix函数的区别? 每个给个例子。
    内联函数通过组织对象给匿名函数/lambda表达式调用分配空间来节省内存。 相反,它提供在运行时调用它的函数提供函数体。 这可能轻微的增加字节码但是节省一些内存。 插入函数 用于调用没有括号和方括号的函数。这样做代码看起来更像自然语言。


    2.png
  1. Lazy和layinit的区别
    两者都延迟属性的初始化 lateinit 是用于var的修饰符, 可以用于 晚点来进行赋值。 Lazy更像一个方法或者一个lambda表达式。只用于val。 在需要时被创建。

  2. 如何创建单例。
    可用object关键字。 Object不能有构造函数,但可以使用init 块

  3. Kotlin有没有static 关键字? 如何创建static函数?
    没有,创建静态函数我们可以用伴随体

  4. 如下数组是什么类型?
    val arr = arrayOf(1, 2, 3);
    Array

25.如何在Kotlin中带值初始化数组?
val numbers: IntArray = intArrayOf(10, 20, 30, 40, 50)

26.Fold和reduce的基本区别? 且分别什么时候使用他们?
Fold接收一个初始值 listOf(1,2,3).fold(0){ sum, element -> sum + element }
第一次调用lambda将会是 0+1
Reduce不接收初始值,相反从集合的第一个元素开始

  1. Kotlin中的数据类型
    首要构造函数至少一个参数,所有的构造函数参数必须标记为var 或者val 。 数据类不能为abstract, open, sealed 或者inner

  2. Kotlin中伴随体的目的?
    不支持static成员,所以用伴随体来放静态成员函数和变量及常量

29.什么是lateinit 和什么时候使用它?**

如不想在构造函数初始化一个变量且你能保证在使用它之前初始化,可以声明为lateinit 变量。 Lateinit不支持原始类型 例如 Int,Long

一些及其实用的案例:

1. Andorid在声明周期实例化的变量

2. 用Dagger 去依赖注入

3. 单元测试的装配, 在@Before函数中初始化的变量

4. Spring Boot注解(@Autowired)

  1. 什么时候使用lateinit而不是lazy initialization

1. 属性是可变的 , 如果不是只初始化一次

  1. 什么是Kotlin !!操作符

非空断言, 把任何值转换成一个非空类型,如果值为空, 抛出KotlinNullPointerException

30.什么是协程?

轻量级线程,创建协程不需要分配新的线程,相反,它使用已经定义好的线程池,智能调度。此外,协程可以挂起和恢复。

31.Suspending和blocking的区别?
Blocking 意味着在同一线程暂停本函数的调用。此外,如果你在主线程调用阻塞函数,将暂停UI直到阻塞函数执行完。不建议这么做。*

Suspending 不需要阻塞本函数的调用。

31.与switch相比,when的优势?

更灵活:如下:支持数字,字符串,对象,以及range

· fun describe(obj: Any): String =

· when (obj) {

· 1 -> "One"

· "Hello" -> "Greeting"

· is Long -> "Long"

· !is String -> "Not a string"

· else -> "Unknown"

· }

32.对比java,kotlin的优势

数据类型 toString, hashcode, equals 。 不需要自己写。 Setter 和getter不需要自己写
Kotlin支持扩展函数
空指针安全
自带单例(object)

Kotlin的缺点

没有明显意义的关键字, internal, crossinline, expect, reified, sealed, open. 生成很多不一定需要的代码。
java有的而kotlin没有的 ,检查异常 , 原始类型, 静态成员, 非私有字段, 通配符类型, 三元操作符。

33.List和Array类型区别

最主要不同是Array固定大小, (Mutable)List可以动态调整大小。 此外,Array是可变的,List不可变。

  1. IntArray 和Array 可以相互交换么?

不能, Array = Integer[] IntArray = int[] , 中间要经过装箱拆箱。

35.函数返回Unit的目的? 为什么是这个值? 值是什么?

目的与c和java相同。 只有Unit是一个合适的类型,所以可作为泛型参数传递

36.如何在Kotlin中实现 建造者模式?

private constructor(builder: Builder) : this(builder.model, builder.year)

class Builder {
    var model: String? = null
        private set

    var year: Int = 0
        private set

    fun model(model: String) = apply { this.model = model }

    fun year(year: Int) = apply { this.year = year }

    fun build() = Car(this)
}

37.Apply函数如何在Kotlin中使用?

创建一个对象且对这个对象进行初始化。

38.什么是kotlin中域函数?

Let

Run

With

Apply

also

  1. 为什么kotlin中没有static keyword?

Kotlin的理念是一切皆对象, static由伴随体取代。 伴随体且支持继承,实现接口。

40.提供一个内联类有用的实际例子

主要用于类型封装, 减少风险,给你简单的,安全的封装器而不引入额外的堆内存分配。

inline fun inlined(block: () -> Unit) {
    println("before")
    block()
    println("after")
}

inlined {
    println("do something here")
}

// No Function object instance will be created, instead, the code around the 
// invocation of block inside the inlined function will be copied 
// to the call site
System.out.println("before");
System.out.println("do something here");
System.out.println("after");

41.Kotlin 支持field 用于干什么?

Kotlin中的类没有字段, 然而,使用自定义访问器的有些时候需要用到支持字段:如下

var selectedColor:  Int  = someDefaultValue

 get() = field

 set(value) {

 field = value

 }

42.怎么为默认数据类重写getter

data class Test(val value: Int)

我该怎么重写它 让它返回0 如果值是负的

1.不要使用数据类型,用普通类

class  Test(value:  Int) {

  val value:  Int  = value

 get() =  if (field <  0) 0  else field

  override  fun  equals(other:  Any?):  Boolean {

  if (this  === other) return  true

  if (other !is  Test) return  false

  return  true

 }

  override  fun  hashCode():  Int {

  return javaClass.hashCode()

 }

}

2.创造一个安全的属性

data  class  Test(val value:  Int) {

  val safeValue:  Int

 get() =  if (value <  0) 0  else value

}

42.SAM 转换是什么?

SAM 表示 单个抽象函数。 SAM-type 指的是像Runnable,Callable的接口。当从kotlin中调用java函数,只要传入的满足单一的非默认函数的接口,可以转换成lambda表达式

43.Kotlin让类的默认可见修饰符为final的动机是什么? 你是否同意?

1. kotlin支持多继承,默认定义为final可以节省开销

2. 类设计原则中,更推荐用合成组合来取代继承。Kotlin用final来默认修饰类。强制使用的人在使用继承时进行进一步的考虑。 是否能用其他方式实现。

44.Reified 关键字如何在kotlin 中工作?

Reified关键字主要用在泛型当中

45.什么时候用kotlin内联函数,什么时候不要用?

传入函数类型参数且函数相对来说比较短时,推荐使用内联函数。 当函数比较长且没有使用内联函数。

46.Launch/join 和 async/await 在kotlin协程中的区别是什么?

Launch 和启动线程相似,当有异常从该线程抛出。处理方式与线程中未捕获的异常相似。在stderr打印出错误且让应用程序崩溃。 Join用于等待执行的协程完成,它不传递异常。 然而,一个崩溃的子协程将会取消它的父协程。

Async 用于执行一个协程且可获得一个Deferred 实例。你可以调用await来得到协程的执行结果。 未捕获的异常被存在Deferred的结果当中。

47.为什么协程比RxKotlin/RxJava好

1. Kotlin比 Rx系列易于理解 subscribeOn ObserveOn 是让人迷惑的。

2. 灵活,且更多控制 。 例如:对于给定计算,你可以控制优先级,是否平行计算,是否锁定资源。

3. 被压处理上,kotlin比Rxjava更容易

48.在Kotlin泛型中,*和Any的区别

List<*> 更够包含任何类型,但只有该擦除后的类型

List可以包含任何类型。

49.如何创建空构造函数

第一种放方式 构造函数的默认参数

另一种方式 次要构造函数

50.什么是协程域(Coroutine Scope), 且和协程上下文(Coroutine Context)区别是什么?

1. 协程总是在一些上下文中执行。 协程上下文 是一系列元素的集合。最主要的是协程的job

2. 写成语 没有它自己的数据,它只拥有一个协程上下文(CoroutineContext)

你可能感兴趣的:(kotlin面试题看这一篇就行了)