kotlin

大家好,这一期呢,我们谈一下kotlin的面试题。

第1题,什么是kotlin?

kotlin是静态类型的编程语言,运行于jvm之上。

第2题, 是谁开发了kotlin?

kotlin是由jetbrains开发的。

第3题, 为什么我们应该从Java转到kotlin?

首先,kotlin比Java要简单。它去除了很多Java里面的冗余代码。kotlin提供了很多Java不具有的特性。

第4题, 说一下使用kotlin的三大好处。

kotlin比较容易学,因为它跟Java很接近。

kotlin是功能性编程语言,是基于jvm上的。

kotlin的代码更易读,更容易理解。

第5题, 解释一下extension函数。

extension函数用来对class的扩展,而不需要从class进行派生。

第6题, kotlin中的null safety是什么意思?

null safety的特性是为了去除null pointer exception在实时运行中的出现风险。它也用来区分空引用和非空引用。

第7题, 为什么kotlin跟Java具有互相的操作性?

因为这两门语言,对于jvm来说没有区别。它们都是编译成byte code, 然后在jvm上运行的。

第8题,在kotlin中是否存在三元条件操作符?

不存在, 在kotlin中没有三元条件操作符。

第9题, 在kotlin中如何声明一个变量?

val xyz: String

第10题,在kotlin中有多少构造函数?

有两种,一种是primary构造函数,一种是secondary构造函数。

第11题, kotlin支持哪种编程类型?

一种是procedural编程, 另一种是面向对象的编程。

第12题,说一下kotlin中对Java.io.file的的扩展方法。

bufferedReader.

readBytes.

readText

forEachLine

readLines

第13题, 在kotlin中如何处理null异常?

使用elvis操作符来处理null异常。

第14题,有哪些特点, kotlin有,但是Java没有?

null safety.

Operator overloading.

Coroutines.

Range expressions.

Smart casts.

Companion objects.

第15题, 解释一下kotlin中数据类的作用。

数据类包含基本的数据类型, 它不包含任何功能函数。

第16题, 我们能把Java代码转成kotlin代码吗?

是的,我们可以用jetbrains ide把Java代码转成kotlin,也可以用Android studio转。

第17题, kotlin允许macros吗?

不允许。kotlin不支持宏。

第18题,说一下kotlin类的缺省行为。

kotlin类缺省是final的。因为kotlin支持多重类继承。开放类代价要比final类高很多。

第19题, kotlin是否支持原始数据类型?

不支持,kotlin不支持原始数据类型。

第20题, 什么是range操作符?

Range操作符用来遍历一个范围。用两个点来表示的。

for(i in 1..15)

print(i)

第21题, kotlin对标准的Java库和类提供额外的功能吗?

kotlin程序是跑在标准的Java虚拟机上的。所以kotlin跟Java在这一层级几乎没有区别。Java代码还可以直接在kotlin程序中使用。

第22题, 在kotlin中定义一个volatile变量。

Volatile var x:Long?=null

第23题, kotlin中的抽象有什么作用?

抽象是面向对象编程中最重要的概念。抽象类的特点是,你知道这个类会有什么功能,但是你不知道它具体如何实现这些功能和实现哪些功能。

第24题,在kotlin中如何比较两个字符串?

第1种方法你可以用双等号来比较两个字符串。

第2种方法用String.compareTo,这个扩展函数来比较两个字符串。

第25题, 下面这段代码是干什么用的?

bar{
System.out.println("haha")

}

bar作为一个函数,正在接收一个表达式为参数,这个表达式用来打印一行字符串。

Android:Kotlin详细入门学习指南-基础语法(一)

本人也是在初学Kotlin,如有错误,请帮忙指出,持续更新
Kotlin被Google官方认为是Android开发的一级编程语言
自 2019 年 Google I/O 以来,Kotlin 就成为了 Android 移动开发的首选。
首先来看看Kotlin的基础语法

Kotlin是什么

Kotlin是Android开发的一级编程语言(Google官方认证)
由JetBrains公司在2010年推出 & 开源,与Java语言互通 & 具备多种Java尚不支持的新特性
Android Studio3.0后的版本支持Kotlin

优点

码更少、可读性更强 - 花更少的时间来编写代码与理解他人的代码
成熟的语言与环境 - 自 2011 年创建以来,Kotlin 不仅通过语言而且通过强大的工具在整个生态系统中不断发展。 现在,它已无缝集成到 Android Studio 中, 并被许多公司积极用于开发 Android 应用程序。
Android Jetpack 与其他库中的 Kotlin 支持 - KTX 扩展 为现有的 Android 库添加了 Kotlin 语言特性,如协程、扩展函数、lambdas 与命名参数。
与 Java 的互操作性 - 可以在应用程序中将 Kotlin 与 Java 编程语言一起使用, 而无需将所有代码迁移到 Kotlin。
支持多平台开发 - 不仅可以使用 Kotlin 开发 Android,还可以开发 iOS、后端与 Web 应用程序。 享受在平台之间共享公共代码的好处。
代码安全 - 更少的代码与更好的可读性导致更少的错误。Kotlin 编译器检测这些剩余的错误,从而使代码安全。
易学易用 - Kotlin 非常易于学习,尤其是对于 Java 开发人员而言。
大社区 - Kotlin 得到了社区的大力支持与许多贡献,该社区在全世界范围内都在增长。 根据 Google 的说法,Play 商店前 1000 个应用中有 60% 以上使用 Kotlin。

使用

1、点击Android Studio settings -> Plugins -> 搜索Kotlin Languages插件
2、在根目录的build.gradle中加入

buildscript {
    ext.kotlin_version = '1.3.61'
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

3、在app/build.gradle中引入

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

buildscript {
    ext.kotlin_version = '1.3.61'
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

基本语法
定义包名 - 在源文件的开头定义包名:包名不必和文件夹路径一致:源文件可以放在任意位置。

package my.demo 
import java.util.
  • //...
    定义函数:定义一个函数接受两个 int 型参数,返回值为 int
fun sum(a: Int , b: Int) : Int{ 
    return a + b 
}

fun main(args: Array) {
    print("sum of 3 and 5 is ")
    println(sum(3, 5)) 
  }

该函数只有一个表达式函数体以及一个自推导型的返回值:

fun sum(a: Int, b: Int) = a + b 
fun main(args: Array) {
    println("sum of 19 and 23 is ${sum(19, 23)}") 
 }

返回一个没有意义的值:
Unit 的返回类型可以省略

fun printSum(a: Int, b: Int): Unit { 
    println("sum of $a and $b is ${a + b}")
     }
fun main(args: Array) { 
printSum(-1, 8)
     }

定义局部变量
声明常量:

fun main(args: Array) {
     val a: Int = 1 // 立即初始化 
     val b = 2 // 推导出Int型 
     val c: Int // 当没有初始化值时必须声明类型 
     c = 3 // 赋值 
     println("a = $a, b = $b, c = $c")
  }

变量:

fun main(args: Array) {
     var x = 5 // 推导出Int类型 
     x += 1 println("x = $x")
 }

注释:
与 java 和 javaScript 一样,Kotlin 支持单行注释和块注释。

// 单行注释
/* 哈哈哈哈 这是块注释 */
与 java 不同的是 Kotlin 的 块注释可以级联。
使用字符串模板

fun main(args: Array) {
     var a = 1 // 使用变量名作为模板: 
     val s1 = "a is $a" a = 2 // 使用表达式作为模板:
     val s2 = "${s1.replace("is", "was")}, but now is $a" println(s2)
 }

使用条件表达式

fun maxOf(a: Int, b: Int): Int { 
    if (a > b) {
     return a 
     } else { 
     return b
      } 
 }
 fun main(args: Array) { 
    println("max of 0 and 42 is ${maxOf(0, 42)}") 
 }

把if当表达式:

fun maxOf(a: Int, b: Int) = if (a > b) a else b
fun main(args: Array) {
    println("max of 0 and 42 is ${maxOf(0, 42)}")
}

使用可空变量以及空值检查
当空值可能出现时应该明确指出该引用可空。
下面的函数是当 str 中不包含整数时返回空:

fun parseInt(str : String): Int?{ //... }
使用值检查并自动转换
使用 is 操作符检查一个表达式是否是某个类型的实例。如果对不可变的局部变量或 属性进行过了类型检查,就没有必要明确转换:

fun getStringLength(obj: Any): Int? {
 if (obj is String) { 
 // obj 将会在这个分支中自动转换为 String 类型 return obj.length }
 // obj 在种类检查外仍然是 Any 类型 return null
 }

使用循环

fun main(args: Array) {
     val items = listOf("apple", "banana", "kiwi") 
     for (item in items) {
      println(item) 
      }
}

或者这样:

fun main(args: Array) { 
    val items = listOf("apple", "banana", "kiwi") 
    for (index in items.indices) {
     println("item at $index is ${items[index]}") 
     } 
 }

使用 while 循环

fun main(args: Array) { 
     val items = listOf("apple", "banana", "kiwi")
     var index = 0 while (index < items.size) { 
     println("item at $index is ${items[index]}")
      index++
      }
}

使用 when 表达式

fun describe(obj: Any): String = 
    when (obj) {
     1 -> "One" 
     "Hello" ->"Greeting" 
      is Long -> "Long" 
      !is String -> "Not a string" 
      else -> "Unknown" 
  }
  fun main(args: Array) {
         println(describe(1)) println(describe("Hello"))
         println(describe(1000L))
         println(describe(2)) 
         println(describe("other"))
 }

使用ranges
使用 in 操作符检查数值是否在某个范围内:

fun main(args: Array) { 
    val x = 10 
    val y = 9
     if (x in 1..y+1) {
      println("fits in range") 
      } 
 }

检查数值是否在范围外:

if (-1 !in 0..list.lastIndex) { 
    println("-1 is out of range") 
}

使用步进

for (x in 1..10 step 2)
for (x in 9 downTo 0 step 3)

使用集合
对一个集合进行迭代

fun main(args: Array) { 
    val items = listOf("apple", "banana", "kiwi") 
    for (item in items) {
     println(item) 
     } 
 }

使用 in 操作符检查集合中是否包含某个对象

fun main(args: Array) { 
    val items = setOf("apple", "banana", "kiwi") 
    when { 
    "orange" in items -> println("juicy") 
    "apple" in items -> println("apple is fine too") 
    } 
}

使用lambda表达式过滤和映射集合

fun main(args: Array) { 
    val fruits = listOf("banana", "avocado", "apple", "kiwi") 
    fruits 
    .filter { it.startsWith("a") } 
    .sortedBy { it } 
    .map { it.toUpperCase() } 
    .forEach { println(it) 
} 

习惯用语
创建DTOs(POJOs/POCOs) 数据类
相当于java的Bean,

data class Customer(val name: String, val email: String)
给 Customer 类提供如下方法
-为所有属性添加 getters ,如果为 var 类型同时添加 setters -- equals() - - haseCode() -- toString() -- copy()

函数默认值

fun foo(a: Int = 0, b: String = "") {...}
过滤 list

val positives = list.filter { x -> x >0 }
或者更短:

val positives = list.filter { it > 0 }
字符串插值

println("Name $name")
实例检查

when (x) { 
    is Foo -> ... 
    is Bar -> ... 
    else -> ... 
}

遍历 map/list

for ((k, v) in map) {
     print("$k -> $v") 
}

k,v 可以随便命名
使用 ranges

for (i in 1..100) { ... } // 闭区间: 包括100 
for (i in 1 until 100) { ... } // 半开区间: 不包括100 
for (x in 2..10 step 2) { ... } 
for (x in 10 downTo 1) { ... } 
if (x in 1..10) { ... } 
for (i in 1..100) { ... } 
for (i in 2..10) { ... }

只读 list

val list = listOf("a", "b", "c")
只读map

val map = mapOf("a" to 1, "b" to 2, "c" to 3)
访问 map

println(map["key"])
map["key"] = value
懒属性(延迟加载)

val p: String by lazy { // 生成string的值 }
扩展函数

fun String.spcaceToCamelCase() { ... }
"Convert this to camelcase".spcaceToCamelCase()
创建单例模式

object Resource {
val name = "Name"
}
如果不为空则... 的简写

val files = File("Test").listFiles()
println(files?.size)
如果不为空...否则... 的简写

val files = File("test").listFiles()
println(files?.size ?: "empty")
如果声明为空执行某操作

val data = ...
val email = data["email"] ?: throw IllegalStateException("Email is missing!")
如果不为空执行某操作

val date = ...
data?.let{ ...//如果不为空执行该语句块 }
返回 when 判断

fun transform(color: String): Int {
     return when(color) { 
     "Red" -> 0 "Green" -> 1 
     "Blue" -> 2 
     else -> throw IllegalArgumentException("Invalid color pa ram value")
      } 
}

try-catch 表达式

f```un test() {
val result = try {
count()
}catch (e: ArithmeticException) {
throw IllegaStateException(e)
}//处理 result
}

if 表达式

fun foo(param: Int){
val result = if (param == 1) {
"one"
} else if (param == 2) {
"two"
} else {
"three"
}
}

需要泛型信息的泛型函数的方便形式

// public final class Gson {
// ...
// public T fromJson(JsonElement json, Class classOfT ) throws JsonSyntaxException {
// ... inline
fun Gson.fromJson(json): T = this.fromJs on(json, T::class.java)

命名风格
如有疑惑,默认为Java编码约定,比如:
使用骆

驼命名法(在命名中避免下划线)
类型名称首字母大写
方法和属性首字母小写
缩进用四个空格
public 方法要写说明文档,这样它就可以出现在 Kotllin Doc 中
冒号
在冒号区分类型和父类型中要有空格,在实例和类型之间是没有空格的:

interface Foo : Bar {
fun foo(a: Int): T
}

Lambdas
在 Lambdas 表达式中,大括号与表达式间要有空格,箭头与参数和函数体间要有 空格。尽可能的把 lambda 放在括号外面传入

list.filter { it > 10 }.map { element -> element * 2 }
在使用简短而非嵌套的lambda中,建议使用 it 而不是显式地声明参数。在使用 参数的嵌套lambda中,参数应该总是显式声明

类声明格式
参数比较少的类可以用一行表示:

class Person(id: Int, name: String)
具有较多的参数的类应该格式化成每个构造函数的参数都位于与缩进的单独行中。 此外,结束括号应该在新行上。如果我们使用继承,那么超类构造函数调用或实现 的接口列表应该位于与括号相同的行中

class Person(
id: Int,
name: String,
surname: String
) : Human(id, name) {
// ...
}

对于多个接口,应该首先定位超类构造函数调用,然后每个接口应该位于不同的行 中

class Person(
id: Int,
name: String,
surname: String
) : Human(id, name),
KotlinMaker { // ...
}

构造函数参数可以使用常规缩进或连续缩进(双倍正常缩进)。

Unit
如果函数返回 Unit ,返回类型应该省略:

fun foo() { // ": Unit"被省略了 }
函数 vs 属性
在某些情况下,没有参数的函数可以与只读属性互换。尽管语义是相似的,但是有 一些风格上的约定在什么时候更偏向于另一个。
在下面的情况下,更偏向于属性而不是一个函数:

不需要抛出异常 -- 拥有O(1)复杂度 -- 低消耗的计算(或首次运行结果会被缓 存) -- 返回与调用相同的结果

你可能感兴趣的:(kotlin)