1. 概要

このチュートリアルでは、Kotlinの通常の面接の質問について説明します。

理解しやすいように、質問を初級レベルと上級レベルに分類します。

2. 初心者レベルの質問

2.1. Kotlinとは何ですか? Javaとどのように相互運用可能ですか?

Kotlinは、JetBrainsによって設計および開発された汎用JVMベースのプログラミング言語です。 これは静的に型付けされたプログラミング言語であり、手続き型、機能型、およびオブジェクト指向プログラミングをサポートします。

Kotlinコンパイラは、Javaコンパイラによって生成されたバイトコードと100% e同等のバイトコードを生成します。 したがって、はJavaとシームレスに相互運用できます。

範囲式、拡張関数、nullセーフ、スマートキャストなどのいくつかの便利な機能により、KotlinはJavaよりも優れた代替手段になります。

さらに、GoogleはKotlinをAndroid開発の公用語として宣伝しています

2.2. Kotlinのさまざまなタイプの変数宣言とは何ですか?

Kotlinでは、 valまたはvarキーワードの後にオプションのデータ型を使用して、変数を宣言できます。

val userName: String = "John"
var age = 25

val キーワードは、初期化を1回だけ許可する最終的な不変変数を作成します。 ただし、 varは、複数の割り当てに適した可変の汎用変数を作成します

データ型なしで変数を宣言すると、Kotlinはスマートキャスト機能を使用して、値の割り当てに基づいてデータ型を決定します。

また、 constキーワードをvalと一緒に使用して、コンパイル時の定数を宣言できます

2.3. valconstの違いは何ですか?

The val キーワードは実行時に不変の変数を作成しますが、 const 一緒に valを使用すると、コンパイル時の不変変数(定数)を作成できます。

val welcomeMsg: String = "Hello $userName"
const val FILE_EXTENSION: String = ".jpg"

また、 val キーワードを使用して、グローバルまたはローカルの不変変数を宣言できます。これは、関数または任意のクラスコンストラクターに割り当てることができます。

ただし、Kotlinがコンパイル時に const 変数の値を決定するため、関数やクラスコンストラクターに割り当てることはできません。

2.4. Kotlinでコンストラクターを作成する方法は?

Kotlinで使用できるコンストラクターには、プライマリとセカンダリの2種類があります。 Kotlinクラスには、1つのプライマリコンストラクターと1つ以上のセカンダリコンストラクターを含めることができます。

Kotlinでは、クラスヘッダーのプライマリコンストラクターをvarまたはval変数宣言で初期化します。

class Person (var firstName: String, var lastName: String) {
    var age: Int = 0
}

var person = Person("John", "Smith");

ただし、セカンダリコンストラクター定義には、varおよびvalキーワードを使用した変数宣言を含めることはできません。

class Person (var firstName: String, var lastName: String) {
    var age: Int = 0

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

 var personWithAge = Person("John", 27);

また、セカンダリコンストラクタは、定義でプライマリコンストラクタを内部的に使用できます。

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

2.5. Kotlinで文字列補間を説明する

Kotlinは、文字列補間の2つの方法をサポートしています。$を使用した変数置換と${}を使用した式の補間です。 例えば:

var welcomeMsg = "Hello $userName";
var secondsInOneYear = "${60 * 60 * 24 * 365} seconds"

2.6. KotlinのNull-Safetyとは何ですか?

Kotlinのヌルの安全性は、オブジェクト参照がヌルまたはボイドの値を持たないことを保証します

デフォルトでは、Kotlinは変数がnull値を持つことを許可していません。 したがって、本番環境で悪名高いNullPointerExceptionに遭遇するリスクを排除します。

ただし、必要に応じて、データ型の後にを使用して、null参照で変数を定義できます。

var name : String?

2.7. Kotlinのデータクラスとは何ですか?

Kotlinは、ボイラープレートコードを減らすことで、コードの簡潔さを促進しています。 たとえば、データクラスは、簡潔で読み取り可能なPOJOを作成する方法を提供します。

これらは、ゲッター/セッター、パラメーター化されたコンストラクターを定義する必要をなくし、hashcodeequalsのようなメソッドをオーバーライドします。

Kotlin では、データキーワードをクラスに追加するだけで、これらすべてが可能になります。

data class Person(var firstName: String, var lastName: String)

さらに、 equals hashCode toStringなどの通常のPOJOメソッドとは別に、openなどの組み込み関数もいくつか作成します。およびcomponentN。

2.8. Kotlinでシングルトンクラスを作成するにはどうすればよいですか?

データクラスと同様に、Kotlinは、オブジェクトキーワードを使用して、シングルトンクラスを定義する際のボイラープレートコードを削減します。

object SimpleSingleton

Kotlinコンパイラは、スレッドセーフなレイジー初期化を使用してシングルトンクラスを内部的に実装します。

2.9. Kotlinのダブルバン演算子とは何ですか?

Kotlinのdoublebang(!!)演算子は、nullではないアサーション演算子です。 変数をnull以外の型に変換し、nullの場合はNullPointerExceptionをスローします。

したがって、開発者は、変数が null でないことが確実な場合は、この演算子を使用する必要があります。

2.10. Kotlinの範囲式とは何ですか?

範囲は、開始値と終了値によって定義される一連の値です。 Kotlin の範囲式は、範囲を反復処理するのに役立ちます。

Kotlinは、rangeを作成するためのrangeToおよびdownTo関数を提供します。 または、二重ドット(..)演算子を使用して値の範囲を定義することもできます。

たとえば、Kotlinでいくつかの範囲を定義しましょう。

(i in 1..10) // range from 1 to 10

(i in 1.rangeTo(10)) // range from 1 to 10

(i in 10.downTo(1)) // range from 10 down to 1

(ch in 'a'..'z') // range from a to z

(i in 1..10 step 2) // range from 1 to 10 with a step of 2 (1, 3, 5, 7, 9)

また、Kotlinでは、さまざまなユースケースの範囲式で reverse until first lastなどの便利な関数を使用できます。

2.11. Kotlinでwhenを説明する

Kotlinのwhenは、Javaのswitch-caseステートメントの高度なバージョンです

一致する式が見つかると、Kotlinは対応するコードを実行し、次のステートメントに移動します。

when (person.firstName) {
    "Mike" -> println("hello!")
    "John" -> println("howdy!")
    else -> println("hi!")
}

Javaとは異なり、Kotlinは各caseブロックの最後にbreakステートメントを必要としません。 さらに、Kotlinの when は、ステートメントとしても式としても役立ちます。

2.12. Kotlinで利用可能なすべてのアクセス修飾子を一覧表示します。 デフォルトで使用されるアクセス修飾子はどれですか?

Kotlin で使用可能な4つのアクセス修飾子があります– public private protected 、およびinternal

Javaと同様に、Kotlinの public 修飾子は、宣言にグローバルな可視性を提供します。 宣言されていない場合、これはKotlinのデフォルトの修飾子です。

同様に、 private 修飾子は、public修飾子の反対です。 したがって、ファイル内の宣言にアクセスできます。

ただし、 protected 宣言は保護されており、トップレベルの宣言では使用できません。

Javaとは異なり、 Kotlinには、モジュール内の任意の場所で宣言へのアクセスを提供する内部修飾子があります。

2.13. Kotlinでopenを定義する

デフォルトでクラスとメソッドを拡張できるJavaとは異なり、Kotlinは openキーワードを使用して、他のユーザーがそれらを継承できるようにします。 つまり、Javaの最後のキーワードの反対です。

Kotlinはすべてを最終的なものに保ち、 open キーワードを通じて、必要な場合を除いてクラスの拡張を制限するという哲学をサポートします。

3. 上級レベルの質問

3.1. Javaに対するKotlinの利点は何ですか?

JVMプログラミング言語であるKotlinは、Javaと相互運用可能な、簡潔で簡単で読みやすいコードを作成するためのツールを提供します。

さらに、これはAndriod開発用の公式プログラミング言語であり、OOP、手続き型、機能などの主要なプログラミングパラダイムをサポートします。

また、Kotlin は、Javaが持ついくつかのギャップ(nullの安全性、範囲式、文字列テンプレート、コルーチン、インライン–中置関数、スマートキャスト)を埋めます。

3.2. インラインおよびインフィックス関数を定義する

Kotlinのインライン関数を使用すると、コンパイラーは、関数が呼び出される場所(インライン)に本体を直接置き換えることができます。

inline fun isEven (number: Int): Boolean {
     return number % 2 == 0
}

val resultList = (1..10).filter { isEven(it) }

Kotlin コンパイラーは、フィルターでisEvenの本体を直接置き換えます。 したがって、関数またはラムダ式へのオブジェクトの割り当てを防ぎます。 例えば:

したがって、抽象化と効率を気にすることなく、inlineキーワードを使用してエレガントなラムダを記述できます。

ただし、Kotlininfix関数は、ピリオドと括弧を使用せずに呼び出すことができるいくつかの関数です。

var personDetailsMap = mapOf(
    "firtName" to "john",
    "lastName" to "smith",
    "age" to 25
  )

ここでは、 toメソッドがinfix関数として使用され、は、より自然言語に近いコードになります。読みやすく、理解しやすい

Kotlinは、または一致などのさまざまな中置関数を提供します。 また、必要に応じてカスタム中置関数を定義できます。

3.3. lazylateinitを定義します

lazylazy初期化を意味し、lateinitは遅延初期化を意味します。

Kotlinは、lazy変数を使用する前に初期化しません。 したがって、valでのみサポートされます。 lazy 変数は、単一の初期化のみをサポートします。

一方、Kotlinは lateinit 変数の初期化を遅らせますが、使用する前に変数が初期化されることを期待しています。 また、 Kotlinは UninitializedPropertyAccessException 例外 w 初期化なし。

var でサポートされており、複数の初期化が可能です。 ただし、プリミティブタイプにlateinitを使用することはできません。

lazy 変数は、初期化子ラムダからのみ初期化できます。 ただし、 lateinit 変数を使用すると、変数にアクセスできる場所ならどこからでも初期化できます。

3.4. foldおよびreduce関数を定義します

foldおよびreduce関数はコレクションをトラバースし、それぞれ初期値がある場合とない場合の特定の操作を適用します。

foldおよびreduce関数を使用した簡単な操作を見てみましょう。

var sum = (1..10).fold(10) { res, next -> res + next }
assertEquals(65, sum)

fold 関数を使用したコレクションの最初の反復では、最初に10(初期値)を使用します。 したがって、resnextの値はそれぞれ10と1です。

sum = (1..10).reduce { res, next -> res + next }
assertEquals(55, sum)

ただし、反復はreduce関数を使用して1と2から始まります。

また、 fold関数を使用すると、初期値のデータ型を定義して結果の型を変更できます。

3.5. Kotlinのコルーチンは何ですか?

コルーチンは、Kotlinで軽量のマルチスレッドプログラミングを提供します。 また、実行中のコルーチンの一時停止と再開を利用して非同期プログラムを作成することができます

Kotlin言語には、 kotlinx-coroutines と呼ばれる豊富なライブラリが付属しており、 core test debug などのモジュールがいくつかあります。 ]reactive複数の機能をサポートします。

3.6. Kotlinのコンパニオンオブジェクトとは何ですか?

Javaとは異なり、Kotlinには静的メンバーまたはメンバー関数がありません。 したがって、クラス内にコンパニオンオブジェクトを定義して、クラスインスタンスなしでメソッドを実行できます。

companion キーワードを使用して、コンパニオンオブジェクトを宣言できます。

class Person(var firstName: String, var lastName: String) {

    companion object {
        val defaultPerson = Person("Mike", "Shaw")
    }

    // ...
}

assertEquals("Mike", Person.defaultPerson.firstName)

ただし、Kotlinのコンパニオンオブジェクトは標準オブジェクトに似ていますが、開発を容易にするためのいくつかの追加機能があります。 たとえば、コンパニオンオブジェクトの名前はオプションであり、シングルトン実装を提供します。

3.7. Kotlinでのビット演算の説明

Javaと同様に、 Kotlinにも、またはおよび xor のようなビット演算があり、左右にシフトします。 ただし、演算子にはJavaよりも直感的に名前が付けられます。

たとえば、Kotlinビット演算子の名前はまたはおよび xor 、およびinvです。

assert(111 or 101 == 111) 
assert(111 and 101 == 101)
assert(111 xor 101 == 10)
assert(101.inv() == -102)

同様に、バイナリシフト演算子は shl –符号付き左シフト、 shr –符号付き右シフト、および ushr –符号なし右シフトです。

assert(3 shl 3 == 24)
assert(12 shr 2 == 3)
assert(-1 ushr 1 == Int.MAX_VALUE)

4. 結論

この記事では、初心者レベルと上級レベルに分類されたいくつかの典型的な面接の質問を行いました。

これらの質問とその簡単な回答は、Kotlinインタビューの準備をしている人に良いスタートを切ることができます。 ただし、詳細な概念を理解し、実践的な経験を積むのに十分な練習をすることもお勧めします。