見出し画像

Tech Note - Technical Interviewとは?

みなさん、こんにちは。お久しぶりです。元気にお過ごしでしょうか?

「大手のテック会社のインタビューを受けてみた!」と言うような動画を一度は目にしたことがあるのではないでしょうか?パズルとか規則性を見つけて解くような問題や、「スクールバスの中にゴルフボールは何個入るの?」みたいな問題を解いている印象が強いと思います。

これを書くに至った経緯

大学の就活の際面接した会社を数個あげると、Bank of America, Amazon, Microsoft, Cisco, Citrix, Yahoo, Google, Chase Bank, Facebookなどで、全て最終段階までは進めました。自分の経験上からいいますが、はっきり言ってソフトウェアエンジニアのインタビューで一つ目のパズルのような問題は見たことがありません。同じ会社で他の役職についてる方々にも聞いたことがあるのですが、やはりパズルみたいな問題を出されたと言う方は見つかりませんでした。2つ目の様な問題は一ヶ所だけで、類題をコーディング問題のプラスアルファとして出されました。でもやはり稀であると思います。

今日は自分の経験に基づいてTechnical Interview: Codingの進め方を書いていきたいと思います。興味がありましたら是非!大分テクニカルだと思うので、「こんなの興味ないやい〜」と思う方がいらっしゃいましたら、他にも記事ありますので是非😁

Technical Interviewの基本

ソフトウェアエンジニアを希望する場合は基本的にいくつかのコーディングインタビューが必要です。会社によって様々ですが、殆どは一回の電話面接またはオンラインアセスメント、そして4, 5回の現地面接があります。

問題の種類はざっくり分けて二種類あり、実用的なタイプの問題と、ピュアなアルゴリズムの問題があります。実用的な方の問題例としては、「スーパーマーケットのレジシステムを作れ」などがこのタイプに当てはまります。ピュアなアルゴリズムの問題としては「いつこんなの使うんだよ」みたいな問題が出されます。

ここでは、ピュアなアルゴリズムの問題を使って、インタビューの流れとexpectationを説明していきたいと思います。

Technical Interviewの流れ

自己紹介と履歴書

まず初めは、約5分間お互いの自己紹介とちょっとした履歴書をベースとした質問をされる場合が多いです。基本的には履歴書に書いてあるプロジェクトについてどの様な工夫をしたかなど聞かれます。この時間は、基本的に就活生をリラックスさせるために使われる時間です。

問題提示

ここからが本番。
今日例題として使いたいのは"Two Sum"と言う超簡単な問題です。これが実際にテクニカルインタビューで出るなら、他にもう一題問題があるか、この問題だけなら超ラッキーと思ってもらっていいでしょう。

問題:
数字の配列とターゲット値が与えられた時、和がターゲット値になるような、配列内の二つの数字のインデックスの組を求めよ。
例:
   [1, 3, 2, 4, 5]   target:8
 index: 0  1  2  3  4
この場合8になるのは3と5を足した場合なので、それらのインデックス1と4を出せば正解です。

質問コーナー

問題をいきなり解く前に質問をすることが重要です。基本的に面接官が出す問題はわざと条件を明確にしていない場合が多いため、質問をして正しく問題を理解しているか確かめる必要があります。
この問題の場合の質問例としては:

Q: もし配列内に和がターゲット値となる2つの数字の組が存在しない場合はどうするべきですか?
A: [-1, -1]を戻り値にしてください。

Q: int型のOverflowを配慮する必要がありますか?
A: 二つの数字を足し合わせてOverflowをするケースは考えなくても良い。

Q: 数字の組は重複が許されますか?
A: ダメです。

などです。

ディスカッション

ここから面接官にアイディアを言っていき、面接官が納得するまではコードをあまり書かない方がいいです。なぜなら遅いアルゴリズムを書いても時間の無駄ですし、合格は基本的にもらえないからです。

ここで自分が考えたこの問題の解き方を二つ紹介していきたいと思います。

public int[] twoSum(int[] array, int target) {
    if (array == null || array.length < 2) {
        return new int[]{-1, -1};
    }
    for (int i = 0; i < array.length; i++) {
        for (int j = i + 1; j < array.length; j++) {
            if (array[i] + array[j] == target) {
                return new int[]{i, j};
            }
        }
    }
    return new int[]{-1, -1};
}

このやり方は一番基礎的な書き方で、Speed Complexity(処理速度)はO(n^2)です。このやり方では強引に二つの数をひたすら足して行き、ターゲット値になるまでひたすら繰り返します。

public int[] twoSum(int[] array, int target) {
    if (array == null || array.length < 2) {
        return new int[]{-1, -1};
    }
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < array.length; i++) {
        if (map.containsKey(target - array[i])) {
            return new int[]{map.get(target - array[i]), i};
        }
        map.put(array[i], i);
    }
    return new int[]{-1, -1};
}

一方この方法ではMapと言うデータ構造を用いて、Speed ComplexityをO(n)まで下げています。(解説難しいからわかる人だけってことでかたじけない)

この様に簡単な問題でも解き方はいくつもあり、書き方も人それぞれです。面接の時間は45分から1時間と限られた時間ですので、いかに時間を無駄にせずに、Speed Complexityがいい解き方を見つけ出せるかが鍵となっています。

最後に

テクニカルインタビューでは基本的には面接官を同僚としてみることが大事だと思います。質問をするのを恐れてはいけません、飽くまでも一緒にアイデアを出し合って問題を解いていると思い込むことが重要です。一人でコードを書く時とは大分違って、考えてることをどんな些細なことでも口にだして伝えなければなりません。それを基に考え方を訂正してくれたり、「その線でもうちょっと考えてみて」などと言われるのです。

まぁもちろん、ヒントばかりに頼ってしまうと落とされますけどね(笑)
なので、適度に面接官にアイデアを言っていき一番Speed Complexityがいい方法を見つけることが合格へのカギです!

この記事が気に入ったらサポートをしてみませんか?