海外求人のコーディングによるスクリーニングテストで惨敗したので対策を考える

あらすじ

海外の求人に飛びついてみたら、4次面接まであった。その内の2次面接がコーディングによるスクリーニングテストだった。

少なからぬ自信があったけど、結果は惨敗だった。ので、対策を考えた。

スクリーニングテスト?

いわゆる面接官の前で解く、というタイプではない。自宅から所定の問題を解いて提出して、自動的にスコアが算出されるというもの。

僕が受けたテストはcodilityというサイト上でのものだった。

スクリーンは以下の通り。

左に問題があり、右にエディタと実行結果画面がある。また、左下のcreate test casesを使用すると、自分でテストケースを作成することができる。(上記の問題は一般に公開されているもので、面接で使用したものではありません)

今回のスクリーニングテストでは、3問用意されており回答時間は90分。途中でpauseすることは不可。

今回の問題

クレデンシャルの観点から具体的には書けないけど、問題自体は決して難しいものではなかった。

  • 与えられた配列の中で、A1~Ap = A(p+1) ~Anを満たすような均衡点pを見つけよ。
  • 与えられた配列について、A1 + A2 + … + An = A(i+1) + A(i+2) + … + A(j) = A(j+1) + A(j+2) + … + A(k)となるような組み合わせはあるかどうか調べよ。

このような感じ。競技プログラミングでは定番の問題と言えるかもしれない。ただし、実際の問題ではこのように直接的に書かれているわけではなく、何を求めれば良いのかを自分で抽象化しなければいけない。

そして、結果は300点中60点しかスコアできなかった。求められていたスコアが120点だから半分しか到達できなかったことになる。

自分のプログラミング回答歴

ここで自分のプログラミング問題の回答歴について書いておくと、AtCoderというサイトにしばしばお世話になっている。

これは前職のスーパーエンジニアさんから教えていただいたサイトで、僕は今でも利用している。

コンテストの種類が複数あるんだけど、僕は初心者向けのビギナーズコンテストを解いている。そして回答コードは一応githubに上げてある。

何が問題だったのか

では、そんな競技プログラミング歴のある自分が、なぜ実際のスクリーニングテストではダメだったのか。原因を考えてみる。

英語の問題文

今回のスクリーニングテストでは、問題文を英語か中国語でしか表示することができなかった。僕が普段AtCoderで問題を解く時、日本語モードを選択している。

英語による問題文は、意味を汲み取ることはできるけど、慣れていない分時間がかかってしまった。エッセンスを汲み取ると「ああ、そういうことね」と分かるのに、英語になると定番の問題でも新鮮に見えてしまった。

まずこれが1つ目の問題。

慣れていない制限時間

自分が普段AtCoderで問題を解く時、過去問を解く。そして、これは良くないなあと思いつつ、制限時間を設けていない。時間がかかってもいいから問題を解けるようになろうという姿勢だったので、制限時間はまだかけなくていいかなと考えていた。

なので、スクリーニングテストでの分刻みで減っていくタイマーによって、不要な緊張が生まれてしまった。

エッジケースを考えられていない

スクリーニングテストでは、一応動くコードは書けた。例題を満たすことができたし、配列要素が無かった場合や、数値が0だった場合みたいな例外的なケースもクリアしていたはず。

それでも、それぞれの問題のTotal Scoreは50%にも満たなかった。自分の想定していなかったケースがあまりにありすぎた。

AtCoderでは、そういう場合はあまり無い。コードが間違っていて全部のケースで失敗するか、正しいコードなので全てのケースをパスするかの2通りであることがほとんど。

だから、Codilityの方がケースが多いのかもしれない。

抽象からコードを書けない

正直な所、未だに数式に苦手意識がある。

こんな問題があるとする。

A1 ~ Anの配列が与えられる。A1 + A2 + … Ai = A(i+1) + A(i +2) + … + An であるようなiを求めよ(1 < i < n)

これは簡単な例だけど。それでも、初見で「うっ…」と思ってしまう。

だけど、AtCoderや今回利用したCodilityには具体例がある。

例1.
[4, 2, -10, -4] の場合、i = 3なら、4 + 2 + (-10) == (-4)となるので、回答は3となる。

この時初めて、そういう問題なのかと理解できる。そしてコードを書き始めて、他の例題にも当てはまるかどうか考える。

つまり自分のコーディングは具体からしか導けていないんだなと感じる。

他のプログラマさんがどうかは分からない。抽象的な数式だけを見て、スラスラとコードを書けてしまうのか。具体例をどれほど参考にするのか。基準が分からない。

けど、自分の場合はあまりに抽象的な数式から目を背けてしまっているように感じる。Σで表される数式を見た時に、どのような数の和を表しているのか、具体例を見ずともパッと思い浮かべられるようにしたい。…って、理系のプログラマさんからすれば、引かれてしまうようなレベルだけど。

難度のバラツキがある問題群にしか慣れていない

AtCoderのビギナーズコンテストでは、簡単なA問題から難しいD問題まで、4つの問題がある。だから、まあ順当にA問題から解いていけば良い。しかし今回のCodilityの問題では、3つの問題すべてが同じ難度だった。

どれから解いていいか迷ったし、時間配分を失敗してしまったかもしれない。

問題点をまとめると

ここまでをまとめると、「ぬるかった」という一言に尽きる気がする。

AtCoderでは英語での表示を選択することができるし、そもそも時間制限を設けていないのは一部の人からは「意味ないじゃん」と言われてしまうかもしれない。

それにいつまでもビギナーズコンテストに留まっているのではなく、ワンランク上のレギュラーコンテストにも参加するべきだ。

つまるところ、プログラミングの上達とか言う名目でヌルく競技プログラミングを解いていた気がする。コンテストとして本格的に向き合っていれば、今回のスクリーニングテストはもっとスコアできたはず。

対策

問題点の裏返しになってしまうけど、対策は以下の通り。

  • 英語モードを選択する。
  • 厳格に時間制限を設ける。
  • ビギナーズコンテストからレギュラーコンテストに移行する。
  • Codilityの一般公開されている問題を解く。(よりエッジケースが多そうだから)
  • 定石をしっかりと抑える。

最後の定石だけど、こちらのスライドを参考にした。

今まで場当たり的に問題を解いてきたけど、たしかに最近は定石のようなものが見えてきた。自分の中でしっかりとパターンを言語化して理解して、都度迅速に対応できるようにしようと思う。

というわけで買いました。

最後に

スクリーニングテストの記事というより、自分のシンプルな至らなさの記事になってしまったけど、誰かのお役に立てれば幸いです。

追記

テストの結果を受けてHuman Resourceの方からメールが来ました。

あなたは所定のスコアを満たしてはいないけど、テストに対する所感やその他のアピールをすることで、次の選考へ進める可能性もあります。

一応回答結果は見てくれるらしい。Codilityでは時間経過毎のコードの遷移も記録されるので、そこからコーディングのススメ方は見られてしまう。

正直どうしようか迷ったけど、何かしらの返信をすることに。

Show your support

Clapping shows how much you appreciated chuck’s story.