欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Android?Kotlin高頻面試題解析

 更新時間:2023年07月04日 09:49:52   作者:星邪Ara  
這篇文章主要為大家介紹了基于Android?Kotlin高頻面試題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

1.1 請簡述一下什么是 Kotlin?它有哪些特性?

kotlin和java一樣也是一門jvm語言最后的編譯結(jié)果都是.class文件,并且可以通過kotlin的.class文件反編譯回去java代碼,并且封裝了許多語法糖,其中我在項目中常用的特性有

  • 擴展,(使用非集成的方式 擴張一個類的方法和變量):比方說 px和dp之間的轉(zhuǎn)換 之前可能需要寫個Util現(xiàn)在,通過擴展Float的變量 最后調(diào)用的時候僅僅是 123.dp 這樣px轉(zhuǎn)成dp了
  • lamdba表達式,函數(shù)式編程. lamdba表達式并不是kotlin的專利,java中也有,但是有限制, 像setOnClickListener一樣,接口方法只有一個的情況才能調(diào)用, 而在kotlin中對接口的lambda也是如此,有這樣的限制,但是他更推薦你使用閉包的方式而不是實現(xiàn)匿名接口的方式去實現(xiàn)這樣的功能,閉包對lambda沒有接口這么多的限制,另外就是函數(shù)式編程 在java8中提供了streamApi 對集合進行map sort reduce等等操作,但是對android api有限制,為了兼容低版本,幾乎不可能使用streamApi
  • 判空語法 省略了許多if xxx==null 的寫法 也避免了空指針異常aaa?.toString ?: "空空如也" 當aaa為空的時候 它的值被"空空如也"替代
aaa?.let{
    it.bbb
}

當aaa不為空時 執(zhí)行括號內(nèi)的方法

  • 省略了findViewById ,使用kotlin 就可以直接用xml中定義的id 作為變量獲取到這個控件,有了這個 butterknife就可以淘汰了,使用databinding也能做到,但是,非常遺憾,databinding的支持非常不好,每次修改視圖,都不能及時生成,經(jīng)常要rebulid才能生成.
  • 默認參數(shù) 減少方法重載 fun funName(a :Int ,b:Int = 123)通過如上寫法 實際在java中要定義兩個寫法 funName(a)和funName(a,b)
  • kotlin無疑是android將來語言的趨勢,我已經(jīng)使用kotlin一年了,不僅App工程中使用,而且封裝的組件庫也是用kotlin,另外說明,kotlin會是apk大小在混淆后增加幾百k.但對于更舒適的代碼來說這又算的了什么呢

1.2 Kotlin 中注解 @JvmOverloads 的作用?

@JvmOverloads注解的作用就是:在有默認參數(shù)值的方法加上@JvmOverloads注解,則Kotlin就會暴露多個重載方法??梢詼p少寫構(gòu)造方法。
例如:沒有加注解,默認參數(shù)沒有起到任何作用。

fun f(a: String, b: Int = 0, c: String="abc"){
    ...
}
那相當于在java中:
void f(String a, int b, String c){
}
如果加上注解@JvmOverloads ,默認參數(shù)起到作用
@JvmOverloads
fun f(a: String, b: Int = 0, c: String="abc"){
    ...
}
相當于Java中:
三個構(gòu)造方法,
void f(String a)
void f(String a, int b)
void f(String a, int b, String c)

1.3 Kotlin中List與MutableList的區(qū)別?

List 返回的是EmptyList,MutableList 返回的是一個ArrayList,查看EmptyList的源碼就知道了,根本就沒有提供 add 方法。

internal object EmptyList : List, Serializable, RandomAccess {
private const val serialVersionUID: Long = -7390468764508069838L
override fun equals(other: Any?): Boolean = other is List<*> && other.isEmpty()
override fun hashCode(): Int = 1
override fun toString(): String = "[]"
override val size: Int get() = 0
override fun isEmpty(): Boolean = true
override fun contains(element: Nothing):
Boolean = false
override fun containsAll(elements: Collection<Nothing>): Boolean = elements.isEmpty()
override fun get(index: Int): Nothing = throw IndexOutOfBoundsException("Empty list doesn't contain element at index $index.")
override fun indexOf(element: Nothing): Int = -1
override fun lastIndexOf(element: Nothing): Int = -1
override fun iterator(): Iterator<Nothing> = EmptyIterator
override fun listIterator(): ListIterator<Nothing> = EmptyIterator
override fun listIterator(index: Int): ListIterator<Nothing> {
    if (index != 0) throw IndexOutOfBoundsException("Index: $index")
        return EmptyIterator
}
override fun subList(fromIndex: Int, toIndex: Int): List<Nothing> {
    if (fromIndex == 0 && toIndex == 0) return this
    throw IndexOutOfBoundsException("fromIndex: $fromIndex, toIndex: $toIndex")
}
private fun readResolve(): Any = EmptyList

1.4 Kotlin中實現(xiàn)單例的幾種常見方式?

餓漢式:

object StateManagementHelper {
    fun init() {
        //do some initialization works
    }
}

懶漢式:

class StateManagementHelper private constructor() {
    companion object {
        private var instance: StateManagementHelper? = null
            @Synchronized get() {
                if (field == null) field = StateManagementHelper()
                return field
            }
    }
    fun init() {
        //do some initialization works
    }
}

雙重檢測:

class StateManagementHelper private constructor() {
    companion object {
        val instance: StateManagementHelper by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            StateManagementHelper()
        }
    }
    fun init() {
        //do some initialization works
    }
}

靜態(tài)內(nèi)部類:

class StateManagementHelper private constructor() {
    companion object {
        val INSTANCE = StateHelperHolder.holder
    }
    private object StateHelperHolder {
        val holder = StateManagementHelper()
    }
    fun init() {
        //do some initialization works
    }
}

1.5 談?wù)勀銓otlin中的 data 關(guān)鍵字的理解?相比于普通類有哪些特點?

在kotlin中數(shù)據(jù)類通過data關(guān)鍵字來修飾。

數(shù)據(jù)類需滿足的條件

  • 主構(gòu)造器必須至少有一個參數(shù)
  • 主構(gòu)造器中的參數(shù)需要用var/val聲明為屬性
  • 數(shù)據(jù)類不能用abstract、open、sealed修飾,也不能定義成內(nèi)部類
  • 數(shù)據(jù)類可以實現(xiàn)接口也可以繼承其他類

系統(tǒng)自動為數(shù)據(jù)類生成哪些內(nèi)容

  • 生成equals/hashCode的方法。
  • 自動重寫toString方法返回形如:”User(name=guojingbu,age=18)“的字符串
  • 為每個屬性生成operator修飾的componentN()方法,來支持解構(gòu)。
  • 生成copy()方法,方便完成對象復(fù)制。

示例代碼

系統(tǒng)生成方法代碼驗證
數(shù)據(jù)類代碼如下:

data class Result(var code:Int,val msg:String)

反編譯后java代碼如下:

   private int code;
   @NotNull
   private final String msg;
    //...省略setter和getter方法
   public Result(int code, @NotNull String msg) {
      Intrinsics.checkNotNullParameter(msg, "msg");
      super();
      this.code = code;
      this.msg = msg;
   }
   public final int component1() {
      return this.code;
   }
   @NotNull
   public final String component2() {
      return this.msg;
   }
   @NotNull
   public final Result copy(int code, @NotNull String msg) {
      Intrinsics.checkNotNullParameter(msg, "msg");
      return new Result(code, msg);
   }
   @NotNull
   public String toString() {
      return "Result(code=" + this.code + ", msg=" + this.msg + ")";
   }
   public int hashCode() {
      int var10000 = this.code * 31;
      String var10001 = this.msg;
      return var10000 + (var10001 != null ? var10001.hashCode() : 0);
   }
   public boolean equals(@Nullable Object var1) {
      if (this != var1) {
         if (var1 instanceof Result) {
            Result var2 = (Result)var1;
            if (this.code == var2.code && Intrinsics.areEqual(this.msg, var2.msg)) {
               return true;
            }
         }
         return false;
      } else {
         return true;
      }
   }

數(shù)據(jù)類可以繼承其他類代碼驗證

open class Sup{}
interface Base{}
data class Result(var code:Int,val msg:String): Sup(),Base{}

如果想讓JVM為數(shù)據(jù)類生成一個無參構(gòu)造,那么數(shù)據(jù)類的主構(gòu)造中的參數(shù)必須都有默認值,示例代碼如下:
數(shù)據(jù)類代碼:

data class Result(var code:Int=0,val msg:String=""){}

反編譯后生成的java代碼:

public final class Result {
    ...省略一些getter和setter方法
   public Result(int code, @NotNull String msg) {
      Intrinsics.checkNotNullParameter(msg, "msg");
      super();
      this.code = code;
      this.msg = msg;
   }
   // $FF: synthetic method
   public Result(int var1, String var2, int var3, DefaultConstructorMarker var4) {
      if ((var3 & 1) != 0) {
         var1 = 0;
      }
      if ((var3 & 2) != 0) {
         var2 = "";
      }
      this(var1, var2);
   }
   public Result() {
      this(0, (String)null, 3, (DefaultConstructorMarker)null);
   }
    ...省略不相關(guān)代碼
}

可以看到上的代碼JVM會為數(shù)據(jù)類生成一個沒有參數(shù)的構(gòu)造器。

1.6 什么是委托屬性?請簡要說說其使用場景和原理?

屬性委托

有些常見的屬性操作,我們可以通過委托方式,讓它實現(xiàn),例如:

  • lazy 延遲屬性:值只在第一次訪問的時候計算
  • observable 可觀察屬性:屬性發(fā)生改變時通知
  • map 集合:將屬性存在一個map集合里面

類委托

  • 可以通過類委托來減少 extend
  • 類委托的時,編譯器會優(yōu)先使用自身重寫的函數(shù),而不是委托對象的函數(shù)
interface Base{
    fun print()
}
class BaseImpl(var x: Int):Base{
    override fun print(){
        print(x)
    }
}
// Derived 的 print 實現(xiàn)會通過構(gòu)造函數(shù)的b對象來完成
class Derived(b: Base): Base by b

1.7 請舉例說明Kotlin中with與apply函數(shù)的應(yīng)用場景和區(qū)別?

  • with 不怎么使用,因為它確實不防空
  • 經(jīng)常使用的是 runapply
  • run 閉包返回結(jié)果是閉包的執(zhí)行結(jié)果;apply 返回的是調(diào)用者本身。
  • 使用上的差別:run 更傾向于做一些其他復(fù)雜邏輯操作,而 apply 更多的是對調(diào)用者自身配置。
  • 大部分情況下,如果不是對調(diào)用者本身進行設(shè)置,我會使用 run。

1.8 Kotlin中 Unit 類型的作用以及與Java中Void 的區(qū)別?

Unit : Kotlin 中Any的子類, 方法的返回類型為Unit時,可以省略;
Void:Java中的方法無法回類型時使用,但是不能省略;
Nothing:任何類型的子類,編譯器對其有優(yōu)化,有一定的推導(dǎo)能力,另外其常常和拋出異常一起使用;

1.9 Kotlin 中 infix 關(guān)鍵字的原理和使用場景?

使用場景是用來修飾函數(shù),使用了 infix 關(guān)鍵字的函數(shù)稱為中綴函數(shù),使用時可以省略 點表達式和括號。讓代碼看起來更加優(yōu)雅,更加語義化。
原理不過是編譯器在語法層面給與了支持,編譯為 Java 代碼后可以看到就是普通的函數(shù)調(diào)用。
kotlin 的很多特性都是在語法和編譯器上的優(yōu)化。

1.10 Kotlin中的可見性修飾符有哪些?相比于Java有什么區(qū)別?

kotlin存在四種可見性修飾符,默認是public。 private、protected、internal、public

  • private、protected、public是和java中的一樣的。
  • 不同的是java中默認是default修飾符(包可見),而kotlin存在internal修飾符(模塊內(nèi)部可見)。
  • kotlin可以直接在文件頂級聲明方法、變量等。其中protected不能用來修飾在文件頂級聲明的類、方法、變量等。

構(gòu)造方法默認是public修飾,可以使用可見性修飾符修飾constructor關(guān)鍵字來改變構(gòu)造方法的可見性。

1.11 你覺得Kotlin與Java混合開發(fā)時需要注意哪些問題?

kotlin調(diào)用java的時候 如果java返回值可能為 null 那就必須加上@nullable 否則kotlin無法識別,也就不會強制你做非空處理,一旦java返回了 null 那么必定會出現(xiàn)null指針異常,加上@nullable 注解之后kotlin就能識別到j(luò)ava方法可能會返回null,編譯器就能會知道,并且強制你做非null處理,這也就是kotlin的空安全

1.12 在Kotlin中,何為解構(gòu)?該如何使用?

給一個包含N個組件函數(shù)(component)的對象分解為替換等于N個變量的功能,而實現(xiàn)這樣功能只需要一個表達式就可以了。

例如
有時把一個對象 解構(gòu) 成很多變量會很方便,例如:

val (name, age) = person

這種語法稱為 解構(gòu)聲明 。一個解構(gòu)聲明同時創(chuàng)建多個變量。 我們已經(jīng)聲明了兩個新變量: name 和 age,并且可以獨立使用它們:

println(name)
println(age)

一個解構(gòu)聲明會被編譯成以下代碼:

val name = person.component1()
val age = person.component2()

1.13 在Kotlin中,什么是內(nèi)聯(lián)函數(shù)?有什么作用?

Kotlin里使用關(guān)鍵 inline 來表示內(nèi)聯(lián)函數(shù),那么到底什么是內(nèi)聯(lián)函數(shù)呢,內(nèi)聯(lián)函數(shù)有什么好處呢?

什么是內(nèi)聯(lián)inline?

在 Java 里是沒有內(nèi)聯(lián)這個概念的,所有的函數(shù)調(diào)用都是普通方法調(diào)用,如果了解 Java 虛擬機原理的,可以知道Java 方法執(zhí)行的內(nèi)存模型是基于 Java 虛擬機棧的:每個方法被執(zhí)行的時候都會創(chuàng)建一個棧幀(Stack Frame),用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。每一個方法被調(diào)用直至執(zhí)行完成的過程,就對應(yīng)著一個棧幀入棧、出棧的過程。

也就是說每調(diào)用一個方法,都會對應(yīng)一個棧幀的入棧出棧過程,如果你有一個工具類方法,在某個循環(huán)里調(diào)用很多次,那就會對應(yīng)很多次的棧幀入棧、出棧過程。這里首先要記住的一點是,棧幀的創(chuàng)建及入棧、出棧都是有性能損耗的。

下面以一個例子來說明,看段代碼片段:

fun test() {
    //多次調(diào)用 sum() 方法進行求和運算
    println(sum(1, 2, 3))
    println(sum(100, 200, 300))
    println(sum(12, 34))
    //....可能還有若干次
}
/**
 *求和計算
 */
fun sum(vararg ints: Int): Int {
    var sum = 0
    for (i in ints) {
        sum += i
    }
    return sum
}

在測試方法 test() 里,我們多次調(diào)用了 sum() 方法。為了避免多次調(diào)用 sum() 方法帶來的性能損耗,我們期望的代碼類似這樣子的:

fun test() {
    var sum = 0
    for (i in arrayOf(1, 2, 3)) {
        sum += i
    }
    println(sum)
    sum = 0
    for (i in arrayOf(100, 200, 300)) {
        sum += i
    }
    println(sum)
    sum = 0
    for (i in arrayOf(12, 34)) {
        sum += i
    }
    println(sum)
}

3次數(shù)據(jù)求和操作,都是在 test() 方法里執(zhí)行的,沒有之前的 sum() 方法調(diào)用,最后的結(jié)果依然是一樣的,但是由于減少了方法調(diào)用,雖然代碼量增加了,但是性能確提升了。那么怎么實現(xiàn)這種情況呢,一般工具類有很多公共方法,我總不能在需要調(diào)用這些公共方法的地方,把代碼復(fù)制一遍吧,內(nèi)聯(lián)就是為了解決這一問題。

定義內(nèi)聯(lián)函數(shù):

inline fun sum(vararg ints: Int): Int {
    var sum = 0
    for (i in ints) {
        sum += i
    }
    return sum
}

如上所示,用關(guān)鍵字 inline 標記函數(shù),該函數(shù)就是一個內(nèi)聯(lián)函數(shù)。還是原來的 test() 方法,編譯器在編譯的時候,會自動把內(nèi)聯(lián)函數(shù) sum() 方法體內(nèi)的代碼,替換到調(diào)用該方法的地方。查看編譯后的字節(jié)碼,會發(fā)現(xiàn) test() 方法里已經(jīng)沒了對 sum() 方法的調(diào)用,凡是原來代碼里出現(xiàn)sum() 方法調(diào)用的地方,出現(xiàn)的都是 sum() 方法體內(nèi)的字節(jié)碼了。

noinline

如果一個內(nèi)聯(lián)函數(shù)的參數(shù)里包含 lambda表達式,也就是函數(shù)參數(shù),那么該形參也是 inline 的,舉個例子:

inline fun test(inlined: () -> Unit) {...}

這里有個問題需要注意,如果在內(nèi)聯(lián)函數(shù)的內(nèi)部,函數(shù)參數(shù)被其他非內(nèi)聯(lián)函數(shù)調(diào)用,就會報錯,如下所示:

//內(nèi)聯(lián)函數(shù)
inline fun test(inlined: () -> Unit) {
    //這里會報錯
    otherNoinlineMethod(inlined)
}
//非內(nèi)聯(lián)函數(shù)
fun otherNoinlineMethod(oninline: () -> Unit) {}

要解決這個問題,必須為內(nèi)聯(lián)函數(shù)的參數(shù)加上 noinline 修飾,表示禁止內(nèi)聯(lián),保留原有函數(shù)的特性,所以 test() 方法正確的寫法應(yīng)該是:

inline fun test(noinline inlined: () -> Unit) {
    otherNoinlineMethod(inlined)
}

crossinline

首先來理解一個概念:非局部返回。我們來舉個栗子:

fun test() {
    innerFun {
        //return 這樣寫會報錯,非局部返回,直接退出 test() 函數(shù)。
        return@innerFun //局部返回,退出 innerFun() 函數(shù),這里必須明確退出哪個函數(shù),寫成 return@test 則會退出 test() 函數(shù)
    }
    //以下代碼依舊會執(zhí)行
    println("test...")
}
fun innerFun(a: () -> Unit) {
    a()
}

非局部返回我的理解就是返回到頂層函數(shù),如上面代碼中所示,默認情況下是不能直接 return 的,但是內(nèi)聯(lián)函數(shù)確是可以的。所以改成下面這個樣子:

fun test() {
    innerFun {
        return //非局部返回,直接退出 test() 函數(shù)。
    }
    //以下代碼不會執(zhí)行
    println("test...")
    inline fun innerFun(a: () -> Unit) {
        a()
    }
}

也就是說內(nèi)聯(lián)函數(shù)的函數(shù)參數(shù)在調(diào)用時,可以非局部返回,如上所示。那么 crossinline 修飾的 lambda 參數(shù),可以禁止內(nèi)聯(lián)函數(shù)調(diào)用時非局部返回。

fun test() {
    innerFun {
        return //這里這樣會報錯,只能 return@innerFun
    }
    //以下代碼不會執(zhí)行
    println("test...")
    inline fun innerFun(crossinline a: () -> Unit) {
        a()
    }
}
  • 具體化的類型參數(shù) reified
    這個特性我覺得特別牛逼,有了它可以少寫好多代碼。在Java 中是不能直接使用泛型的類型,但是在 Kotlin 中確可以。舉個栗子:
inline fun startActivity() {
    startActivity(Intent(this, T::class.java))
}

使用時直接傳入泛型即可,代碼簡潔明了:

startActivity()

1.14 談?wù)刱otlin中的構(gòu)造方法?有哪些注意事項?

概要簡述

  • kotlin中構(gòu)造函數(shù)分為主構(gòu)造和次級構(gòu)造兩類
  • 使用關(guān)鍵詞constructor標記構(gòu)造函數(shù),部分情況可省略
  • init關(guān)鍵詞用于初始化代碼塊,注意與構(gòu)造函數(shù)的執(zhí)行順序,類成員的初始化順序
  • 繼承,擴展時候的構(gòu)造函數(shù)調(diào)用邏輯
  • 特殊的類如data class、object/componain object、sealed class等構(gòu)造函數(shù)情況與繼承問題
  • 構(gòu)造函數(shù)中的形參聲明情況

主/次 構(gòu)造函數(shù)

  • kotlin中任何class(包括object/data class/sealed class)都有一個默認的無參構(gòu)造函數(shù)
  • 如果顯式的聲明了構(gòu)造函數(shù),默認的無參構(gòu)造函數(shù)就失效了。
  • 主構(gòu)造函數(shù)寫在class聲明處,可以有訪問權(quán)限修飾符private,public等,且可以省略constructor關(guān)鍵字。
  • 若顯式的在class內(nèi)聲明了次級構(gòu)造函數(shù),就需要委托調(diào)用主構(gòu)造函數(shù)。
  • 若在class內(nèi)顯式的聲明處所有構(gòu)造函數(shù)(也就是沒有了所謂的默認主構(gòu)造),這時候可以不用依次調(diào)用主構(gòu)造函數(shù)。例如繼承View實現(xiàn)自定義控件時,三四個構(gòu)造函數(shù)同時顯示聲明。

init初始化代碼塊

kotlin中若存在主構(gòu)造函數(shù),其不能有代碼塊執(zhí)行,init起到類似作用,在類初始化時侯執(zhí)行相關(guān)
的代碼塊。

  • init代碼塊優(yōu)先于次級構(gòu)造函數(shù)中的代碼塊執(zhí)行。
  • 即使在類的繼承體系中,各自的init也是優(yōu)先于構(gòu)造函數(shù)執(zhí)行。
  • 在主構(gòu)造函數(shù)中,形參加有var/val,那么就變成了成員屬性的聲明。這些屬性聲明是早于init代碼塊的。

特殊類

  • object/companion object是對象示例,作為單例類或者伴生對象,沒有構(gòu)造函數(shù)。
  • data class要求必須有一個含有至少一個成員屬性的主構(gòu)造函數(shù),其余方面和普通類相同。
  • sealed class只是聲明類似抽象類一般,可以有主構(gòu)造函數(shù),含參無參以及次級構(gòu)造等。

1.15 談?wù)凨otlin中的Sequence,為什么它處理集合操作更加高效?

處理集合時性能損耗的最大原因是循環(huán)。集合元素迭代的次數(shù)越少性能越好。
我們寫個例子:

list.map { it ++ }
.filter { it % 2 == 0 }
.count { it< 3 }

反編譯一下,你會發(fā)現(xiàn):Kotlin編譯器會創(chuàng)建三個while循環(huán)。
Sequences 減少了循環(huán)次數(shù)
Sequences提高性能的秘密在于這三個操作可以共享同一個迭代器(iterator),只需要一次循環(huán)即可完成。
Sequences允許 map 轉(zhuǎn)換一個元素后,立馬將這個元素傳遞給 filter操作 ,而不是像集合(lists) 那樣,等待所有的元素都循環(huán)完成了map操作后,用一個新的集合存儲起來,然后又遍歷循環(huán)從新的集合取出元素完成filter操作。

Sequences 是懶惰的
上面的代碼示例,map、filter、count 都是屬于中間操作,只有等待到一個終端操作,如打印、sum()、average()、first()時才會開始工作,不信?你跑下下面的代碼?

val list = listOf(1, 2, 3, 4, 5, 6)
val result = list.asSequence()
    .map { println("--map"); it * 2 }
    .filter { println("--filter");it % 3 == 0 }
println("go~")
println(result.average())

擴展:Java8 的 Stream(流) 怎么樣呢?

list.asSequence()
.filter { it < 0 }
.map { it++ }
.average()
list.stream()
.filter { it < 0 }
.map { it++ }
.average()

stream的處理效率幾乎和Sequences一樣高。它們也都是基于惰性求值的原理并且在最后(終端)處理集合。

1.16 請談?wù)凨otlin中的Coroutines,它與線程有什么區(qū)別?有哪些優(yōu)點?

說一下個人理解吧。先列出協(xié)程幾個特點:

  • 在單個進程內(nèi),多個協(xié)程串行執(zhí)行,只掛起不阻塞
  • 協(xié)程最終的執(zhí)行還是在各個線程之中

優(yōu)點:

  • 由于不阻塞線程,異步任務(wù)是編譯器主動交到線程池中執(zhí)行。因此,在異步任務(wù)執(zhí)行上,切換和消耗的資源都較少。
  • 由于協(xié)程是跨多個線程,并且能夠保持串行執(zhí)行;因此,在處理多并發(fā)的情況上,能夠比鎖更輕量級。通過狀態(tài)量實現(xiàn)

1.17 Kotlin中該如何安全地處理可空類型?

對于方法傳入的參數(shù)直接通過if判斷,例如:

fun a(tag: String?, type: String) {
    if (tag != null && type != null) {
        // do something
    }
}

還有就是

a?.let{}
a?.also{}
a?.run{}
a?.apply{}

然后接著有一個疑問,假如同時判斷兩個變量,寫成:

a?.let{
    b?.let {
        //do something
    }
}

1.18 說說Kotlin中的Any與Java中的Object有何異同?

同:都是頂級父類
異:成員方法不同

Any只聲明了toString()、hashCode()和equals()作為成員方法。

我們思考下,為什么 Kotlin 設(shè)計了一個 Any ?

當我們需要和 Java 互操作的時候,Kotlin 把 Java 方法參數(shù)和返回類型中用到的 Object 類型看作 Any,這個 Any 的設(shè)計是 Kotlin 兼容 Java 時的一種權(quán)衡設(shè)計。

所有 Java 引用類型在 Kotlin 中都表現(xiàn)為平臺類型。當在Kotlin 中處理平臺類型的值的時候,它既可以被當做可空類型來處理,也可以被當做非空類型來操作。

試想下,如果所有來自 Java 的值都被看成非空,那么就容易寫出比較危險的代碼。反之,如果 Java 值都強制當做可空,則會導(dǎo)致大量的 null 檢查。綜合考量,平臺類型是一種折中的設(shè)計方案。

1.19 Kotlin中的數(shù)據(jù)類型有隱式轉(zhuǎn)換嗎?為什么?

不可隱式轉(zhuǎn)換
在Java中從小到大,可以隱式轉(zhuǎn)換,數(shù)據(jù)類型將自動提升。下面以int為例
這么寫是ok的

int a = 2312;
long b = a;
//那么在Kotlin中
//隱式轉(zhuǎn)換,編譯器會報錯
val anInt: Int = 5
val ccLong: Long = anInt
//需要去顯式的轉(zhuǎn)換,下面這個才是正確的
val ddLong: Long = anInt.toLong()

1.20 Kotlin中集合遍歷有哪幾種方式?

對于如下集合

val list = mutableListOf("a", "b", "c", "d", "e", "f", "g")
// kotlin中集合的遍歷方式有下面幾種
// 1、 通過解構(gòu)的方式,可以方便的獲取index和value
for ((index, value) in list.withIndex()){
    println("index = $index , value = $value")
}
// 2、 … 左閉右閉 [,]
for (i in 0 .. list.size - 1){
    println("index = $i , value = ${list[i]}")
}
// 3、 until 左閉右開 [,)
for (i in 0 until list.size){
    println("index = $i , value = ${list[i]}")
}
// 4、 downTo 遞減的循環(huán)方式 左閉右閉 [,]
for (i in list.size - 1 downTo 0){
    println("index = $i , value = ${list[i]}")
}
// 5、帶步長的循環(huán)step可以和其他循環(huán)搭配使用
for (i in 0 until list.size step 2){
    println("index = $i , value = ${list[i]}")
}
// 6、指定循環(huán)次數(shù) it就代表了當前循環(huán)的計數(shù),從0開始下面的語句循環(huán)了10次 每次的計數(shù)分別是 0,1…9
repeat(10){
    println(it)
}
// 7、不需要數(shù)據(jù)的下標,直接for循環(huán)list中的每個item
for (item in list){
    println(item)
}

以上就是基于Android Kotlin高頻面試題解析的詳細內(nèi)容,更多關(guān)于Android Kotlin面試題的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android小程序?qū)崿F(xiàn)簡易QQ界面

    Android小程序?qū)崿F(xiàn)簡易QQ界面

    這篇文章主要為大家詳細介紹了Android小程序?qū)崿F(xiàn)簡易QQ界面,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • 解決android studio 3.0 加載項目過慢問題--maven倉庫選擇

    解決android studio 3.0 加載項目過慢問題--maven倉庫選擇

    這篇文章主要介紹了android studio 3.0 加載項目過慢問題解決方案---maven倉庫選擇,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-11-11
  • Flutter?Ping檢查服務(wù)器通訊信號強度實現(xiàn)步驟

    Flutter?Ping檢查服務(wù)器通訊信號強度實現(xiàn)步驟

    這篇文章主要為大家介紹了Flutter?Ping檢查服務(wù)器通訊信號強度實現(xiàn)步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • gradle配置國內(nèi)鏡像的實現(xiàn)

    gradle配置國內(nèi)鏡像的實現(xiàn)

    這篇文章主要介紹了gradle配置國內(nèi)鏡像的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Android實現(xiàn)RecyclerView下拉刷新效果

    Android實現(xiàn)RecyclerView下拉刷新效果

    這篇文章主要為大家詳細介紹了Android實現(xiàn)RecyclerView下拉刷新效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android如何繪制發(fā)光效果詳解

    Android如何繪制發(fā)光效果詳解

    這篇文章主要給大家介紹了關(guān)于Android如何繪制發(fā)光效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Android4.4 WebAPI實現(xiàn)拍照上傳功能

    Android4.4 WebAPI實現(xiàn)拍照上傳功能

    這篇文章主要介紹了Android4.4 WebAPI實現(xiàn)拍照上傳功能,本文給出4.4版本后拍照上傳的具體實現(xiàn)方法,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Android開發(fā)之ClipboardManager剪貼板功能示例

    Android開發(fā)之ClipboardManager剪貼板功能示例

    這篇文章主要介紹了Android開發(fā)之ClipboardManager剪貼板功能,結(jié)合簡單實例形式分析了Android使用ClipboardManager實現(xiàn)剪貼板功能的相關(guān)操作技巧,需要的朋友可以參考下
    2017-03-03
  • Android中Spinner控件之鍵值對用法實例分析

    Android中Spinner控件之鍵值對用法實例分析

    這篇文章主要介紹了Android中Spinner控件之鍵值對用法,實例分析了Spinner控件控件的鍵值對實用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • Android TextView實現(xiàn)多文本折疊、展開效果

    Android TextView實現(xiàn)多文本折疊、展開效果

    這篇文章主要為大家詳細介紹了Android TextView實現(xiàn)多文本折疊、展開效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05

最新評論