サイバーエージェントは、8月25日(土)に開催された「KotlinFest 2018」に協賛いたしました。

IMG_5312

弊社からはFRESH LIVEstormcat24さんが登壇し、Kotlinを使ったSpringBootやSpark FrameworkでのMicroservices構築、gRPCの活用やKubernetesでの運用のポイント等についてお話ししてきました。

↓当日のスライドはこちら↓

そして、何と発表当日はstormcat24さんの著書の発売日でもありました!

こちらもぜひご一読ください。

docker:kunernetes

 

また、サイバーエージェントのブースでは「Kotlin Puzzlers」を実施し、多くの方に参加いただきました。かなり盛り上がりを見せたのでブログでもご紹介したいと思います^^

IMG_3165

問題は計4問!まずは問題からご紹介します。

1問 <正解率は16%

am1

出展: Kotlin Puzzlers

2問<正解率は24%

am2

出展: @kkagurazaka

3問<正解率は41%で最も正解率が高かった問題です>

pm1

出展: Kotlin Puzzlers

4問 <正解率は5%で最も正解率が低かった問題です>

pm2

出展: @kkagurazaka

皆さんいかがですか??

ここからは@kkagurazakaさんによる解説をお届けします!

 

1問の正解は c) です。

java.util.List<E> は add , remove などを含むためKotlinでは MutableList として扱われます。

listOf() は java.util.Arrays$ArrayList<E> のインスタンスを返却しますが、これはもちろん java.util.List<E> を実装しているため、問題文中の is MutableList は true となります。

java.util.Arrays$ArrayList<E>#add の実装は親クラスである java.util.AbstractList<E> にて UnsupportedOperationException が送出されるようになっているため、 c) が正解となります。 

Kotlinの List<E> がimmutableなのはあくまでタイプとしての性質であって、インスタンスとしては (現時点では) mutableなものしか存在していない点に注意が必要です。

<追記>

参加者からご指摘いただ来ましたが、Kotlin-JS環境では正解が b) となるようです。

出題不備をお詫び申し上げます。

 

2問の正解は d) です。

launch で10個のcoroutinesを作成し、 joinAll で全ての完了を待っています。

これらのcoroutinesは2スレッドのスレッドプールを持つ context 上で実行されるため、2並列で 5000 ms かかるように思えますが、それは引っ掛けです。

ここでポイントとなるのは delay は呼び出し元スレッドをブロックしないsuspend関数であるという点です。

delay が呼び出されると呼び出し元のcoroutineは直ちに中断し、使っていたスレッドを空け渡します。

その結果、後続で控えていたcoroutineが実行され、そのcoroutineも delay が呼び出されるとスレッドを空け渡し・・・と連鎖していき、10個のcoroutinesが直ちに実行されることになります。

その後、大体 1000 ms 経つと全てのcoroutinesの実行が完了するため、正解は d) 1000 ms となります。

 

3問の正解は c) です。

3行目で plus を定義していますが、operator関数が被った場合は標準関数で定義されているほうが優先されるため、 -1 + 2 では自ら定義した plus は呼ばれず、そのまま 1 という答えになります。

ただし、標準関数で定義されている operator fun plus は infix 修飾子がついていないため、 -1 plus 2 の書き方では自分で定義した関数が呼び出されることになり、答えは -1 + 2 + 1 = 2 となります。

最後の -1.plus(2) についても標準関数のほうが呼び出されますが、単項演算子よりも関数呼び出しのほうが優先度が高いため -(1.plus(2)) と等価のコードになり、答えは -3 となります。

 

4問の正解は  c) です。

actorは Channel のラッパーのような存在ですが、 actor() が返すのは SendChannel のため、actorに値を送信することはできても、actorから値を受信することはできません。

actor() に渡すラムダ内でのみ Channel にアクセスすることができ、送信された値に応じて必要な処理を行うことができます。

actor() によるインスタンスの生成にはほとんど時間がかからないと考えてよいので、この問題ではactorに 0, 1, 2, 3, 4 の5つの数字を送り終えるまでの時間が答えになります。

まず、最初の0の send はactorの channel にまだ何も値が入っていないためそのまま成功します。

actorは channel に入った0を直ちに receive して delay(1000) を実行します。

次の1の send は、actorの channel に何も値が入っていないため、これまた成功します。

現在actorは0を receive したときの delay 中なので、 1 はまだactorによって receive されず、 channel に積まれたままになります。

そのため、2の send は channel が空くまで中断されます。

1000 ms ほど経つと、0を receive したときの delay が完了し、actorは channel から1を receive します。

ここで channel が空になったため、中断していた2の send が完了し、次の3の send は channel に空きがないので中断されます。

この流れが繰り返され、さらに 1000 ms 後に3の send が完了し、さらに 1000ms 後に4の send が完了することになるため、答えは c) 3000 ms となります。

 

Kotlin Puzzlersお楽しみ頂けたでしょうか!?

運営のみなさま、参加者のみなさま、お疲れさまでした^^