Kotlin Quiz @ Kotlin Festの正解発表

punchdrunker

Kotlin Fest2018のスポンサーブースの企画で、ミクシィからはKotolin Quizを実施しました。最終的には115件の回答を頂き、なかなか好評だったように思えます。問題は全7問でオリジナル問題は無く、全て https://kotlinquiz.com/https://github.com/angryziber/kotlin-puzzlers から選びました。

当日、ブースには3台のiPadを並べてGoogle Formで解答してもらう簡素な仕組みでした。回答はリアルタイムで採点できるので、最後に名前だけ教えてもらえれば点数がわかるようになっています。3問以上正解で景品を差し上げる、という企画でした。

ブース全景
主催のたろうさんにも回答してもらいました

難易度のレベルはちょっと高めで最高得点は6点の方が5名。得点の中央値が3点でした。

当日16時過ぎに現地で解答発表したのですが、改めて解説付きで公表したいと思います。

問題

問題のあとにすぐ正解を書くと、初めて見た人は楽しめないと思うので、正解は最後に記載します。

Q1.次のコードを実行するとどうなるでしょうか?

val a: String? = null
val b: String = “kotlin”
println(a==b)

  1. NullPointerException
  2. true
  3. false
  4. コンパイルできない

(https://kotlinquiz.com/ より出題)

Q2.次のうち、 data classが提供しない機能はどれでしょう?

  1. JSONとの相互変換
  2. toString() を自動生成
  3. copy() でコピーインスタンスを作ることができる
  4. hashCode() と equals() を自動生成

(https://kotlinquiz.com/ より出題)

Q3.次のコードを実行するとどうなるでしょうか?

foo()()

  1. 2次元配列を生成する
  2. foo() を非同期に実行する
  3. コンパイルに失敗する
  4. foo() が返す関数を実行する

(https://kotlinquiz.com/ より出題)

Q4.次のコードを実行するとどうなるでしょうか?

val s: String? = null
if (s?.isEmpty()) println(“true”)

  1. 何も出力されない
  2. true
  3. NullPointerException
  4. コンパイルできない

(https://github.com/angryziber/kotlin-puzzlers より出題)

Q5.次のコードを実行するとどうなるでしょうか?

val x: Int? = 2
val y: Int = 3

val sum = x?:0 + y

  1. 3
  2. 5
  3. 2
  4. 0

(https://github.com/angryziber/kotlin-puzzlers より出題)

Q6.次のコードを実行するとどうなるでしょうか?

open class A(val x: Any?)

object B : A(C)
object C : A(B)

println(B.x)
println(C.x)

  1. null; null;
  2. C@1544bf85; null
  3. ExceptionInInitializerError
  4. コンパイルできない

(https://github.com/angryziber/kotlin-puzzlers より出題)

Q7.次のコードを実行するとどうなるでしょうか?

fun oops() {
return throw throw return
}
print(oops())

  1. kotlin.Nothing
  2. kotlin.Any
  3. kotlin.Unit
  4. コンパイルできない

(https://github.com/angryziber/kotlin-puzzlers より出題)


正解

A1.

3が正解です。falseがプリントされます。一見簡単そうに見えますが、解説するとなるとちょっと難易度が高いです。

a==bは内部的には a?.equals(b) ?: (b===null) と変換されます。今回の場合、bがnullではないので、falseがプリントされるという事になります。

A2.

1のJSONとの相互変換が正解です。data classはそれ以外の機能を全て提供してくれます。

A3.

4が正解です。Kotlinは高階関数をサポートしていて、foo()()はfoo()が返す関数を即時実行します。

A4.

正解は4。コンパイルできません。IDEがあれば悩む事もありませんね。

Kotlinのif文 はBooleanは受け付けますがBoolean?は受け付けないので、Boolean?となるs?.isEmpty()を使う事は出来ません。

A5.

正解は3で、sumには2が代入されます。今回正解率が24%と、一番低かった問題です。

多くの人は5と回答していました。
なぜ2が代入されるかというと、

x?: 0 + y

x ?: (0 + y)

として解釈されます。
つまり、xがnullならば(0 + y)を返しますが、xはnullではないので、xの値がそのままsumに代入されます。

A6.

C@1544bf85; null が正解です。
Kotlinではシングルトンオブジェクトはトポロジカルソートにより決定された順番で初期化されます。

今回のように循環した初期化が行われるケースではトポロジカルソートでの決定が出来なくなります。
そのため、循環に巻き込まれたオブジェクトがnullとして扱われてしまうという仕様があり、今回の問題はその仕様書で使われた例文です。

http://jetbrains.github.io/kotlin-spec/#_singleton_objects

A7.

正解はUnitです。
throw や returnはNothingとして評価されますが、Nothingはそれ以外の型のsubtypeなので、他のクラスのsubtypeとして扱う事もできます。

この問題で一番ひっかかる点として、throw return はコンパイルできるのか?という疑問があります。

throwは引き数として、Throwableを取りますが、NothingはThrowableのsubtypeとしても評価可能なので、コンパイルできるようです。

というわけで

return throw throw return

という式は、一番右側のreturn が最初に実行され、oops()からfunctionのデフォルトの型であるUnitが返ってくるという事になります。

より詳しい解説は http://natpryce.com/articles/000818.html をご覧ください。


以上、Kotlin Quiz の正解発表でした。

mixi developers

ミクシィグループのエンジニアやデザイナーによるブログです。

    punchdrunker

    Written by

    Programmer in Tokyo. I am writing an article for the study of English.

    mixi developers

    ミクシィグループのエンジニアやデザイナーによるブログです。

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade