アルゴリズムを使ったエンジニア面接でのテスト

# アルゴリズムを使ったエンジニア面接でのテスト

### 自己紹介

初めまして。私は株式会社アドベンチャーで、フロントエンド開発を担当しています朴（パク）と申します。
今回はフロントエンドエンジニア面接で使えるツールとして「アルゴリズム」をご紹介したいと思います。

## クリエイティブ職の採用

デザイナーやエンジニアなど、クリエイティブ職の採用としたら、面接官の裁量（主観）が大きく作用すると思いがちです。
しかし、会社としては採用の結果として明示的な目標の達成を目指しています。
そのため、最近は単純に「感」による面接より、会社の状況とポジションに適合する客観的な検証プロセスを導入する場合が増えています。

デザイナーの面接だったら、以前の制作物やポートフォリオなどをチェック項目として使う場合が多いですが、問題はエンジニアです。

## エンジニア採用での問題点

エンジニアの面接目的を「会社が求める人材の採用」と想定して話を進めます。

まず、エンジニアの結果物は、表に出ない場合が多いです。
「バックエンドを2人で」「Rubyで30%」など、定量的で一見わかりやすいようにみえますが、ふわっとしているので参考の意味にしかなりません。

「大きな会社で勤務した経験」「チームやプロジェクトをマネジメントした経験」など定性的なことで面接を進めても、採用してからは期待通りになってない場合もあります。

もちろんその人材に問題があるとは限りませんが、口頭の面接だけになるとエンジニアの採用目的に適合かどうかの検証ができない可能性が高いのも事実です。

## なので、テスト

最近は少なくない企業のエンジニア面接の場面でテストが行われます。

例えば、
- 課題をパソコン上でコーディングして提出
- 問題集を解く
- 課題を手書きでコーディングして提出

など形式は色々あります。

客観的に判断ができる事、判定に時間が長くかからない事、実際のコーディング能力がわかることなどで便利な道具ではありますが、どういうテストを出すか、どこまで深く出すか、どれくらいの量で出すかなど考えるべき事が多いです。
さらに、テストの方向が間違っていたら、優秀な人材を見逃す危険性も高くなります。

- 基本ができているかどうかを判断したい。
- あるくらい公認されたテストを行いたい。
- テストの時間を短くしたい。
- テストを出す時間を節約したい。

そういう観点から、「アルゴリズム」のテストをお勧めします。

## アルゴリズムの例

では、基本的なアルゴリズムの例をいくつか見てみましょう。
Javascriptをメインに記載しましたが、同アルゴリズム名で検索すると他言語のアルゴリズムも多く確認できます。

#### Fizz Buzz

並んだ数字の中から特定条件にあっている数字が現れる場合だけFizz、またはBuzzを出力します。例えば、1から30の数字がある場合3の倍数ならFizz、５の倍数ならBuzz、3と5の倍数ならFizzBuzzが出力されます。

```javascript
function fizzBuzz(num) {  
  for (var i = 1; i <= num; i++) {  
    if (i % 15 === 0 ) console.log('FizzBuzz');  
    else if (i % 3 === 0) console.log('Fizz');  
    else if (i % 5 === 0) console.log('Buzz');  
    else console.log(i)  
  }  
}
// 実行
fizzBuzz(30);
```

#### 前から読んでも、後ろから読んでも同じ

特定の文字列を前から読んでも、後ろから読んでも同じ文字かを確認します。「madam」が良い例になります。正規表現を使って不要な文字や余白を除去します。

```javascript
function isTextSame(text) {  
  if (text === undefined) return false;  
  var left = 0;  
  var right = text.length - 1;  
  while (left < right) {  
    if (text[left++] !== text[right--]) return false;  
  }  
  return true;  
}

function isPhraseSame(text) {  
  var chars = text.replace(/[^a-zA-Z]/g, '').toLowerCase();  
  return isTextSame(chars);  
}
// 実行
isPhraseSame("Madam, I'm Adam");
```

#### 真ん中の文字を持ってくる

単語の真ん中の文字を返す関数です。単語の長さが偶数なら２文字を返します。

```javascript
function solution(s) {  
  var answer = '';  
  var string = s;  
  var stringLength = string.length;  
  var stringHalf = Math.floor(stringLength/2);  
  var stringStart = '';  
  var stringEnd = stringHalf + 1;  
      
  if (stringLength%2 === 0) {  
    stringStart = stringHalf - 1;  
    answer = string.substring(stringStart, stringEnd);  
  } else if (stringLength%2 === 1) {  
    stringStart = stringHalf;  
    answer = string.substring(stringStart, stringEnd);  
  }  
      
  return answer;  
}
```

#### 文字列内のaとbの数

大文字と小文字で構成されている文字列sの「a」の数と「b」の数を比べて同じだったらTrue、違ってたらFalseを返す関数です。

```javascript
function solution(s) {  
  var data = s.toLowerCase().split('');
  var initialValue = {};
  var answer = true;
  
  data.reduce(function(accu, val) {
    if (accu.hasOwnProperty(val)) accu[val] = accu[val] + 1;
    else accu[val] = 1;
    return accu;
  }, initialValue);
  
  if(initialValue.a !== initialValue.b) answer = false;
  return answer;
}
```

#### Factorial数列

指定した数までの掛け算を行う関数です。

```javascript
function factorial(number) {
  var result = 1;
  for (i = 2; i <= number; i += 1) {
    result *= i;
  }
  return result;
}
```

１行にしたらこんな感じになります。

```javascript
function factorial(number) {
  return number > 1 ? number * factorial(number - 1) : 1;
}
```

#### Fibonacci数列

０から足していく数列で、前の二つの数字の合計が次の数字になる関数です。0、1、1、2、3、5、8、13、21、34、55、89。。。な感じです。

```javascript
function fibonacciNth(n) {
  var currentValue = 1;
  var previousValue = 0;
  if (n === 1) return 1;
  var iterationsCounter = n - 1;

  while (iterationsCounter) {
    currentValue += previousValue;
    previousValue = currentValue - previousValue;
    iterationsCounter -= 1;
  }

  return currentValue;
}
```

## テストの実行

#### アルゴリズムと一緒に行えるテスト項目

ここまでみられた方に印象を聞いたら、多分次の反応ではないでしょうか。
- これだけ覚えておくやついそう。
- 実務と関係ないじゃん。
- ググって出るものは避けたいな。

確かに。
なので、アルゴリズムだけを使うよりは、下記の項目も一緒に使うことをお勧めします。
- 基本的な単語の定義を答えてもらう
- エラーの対応策を答えてもらう
- プログラム実行後の期待値を答えてもらう
- コード上の不備を見つけてもらう

#### アルゴリズムテストのバリエーション

そして、アルゴリズムのテストを行う場合も
- 条件を満たすアルゴリズムを答えてもらう
- アルゴリズムの一部を省いて、埋めてもらう
- アルゴリズムだけ見て期待値を答えてもらう
- アルゴリズムを要請に合わせて修正してもらう
- アルゴリズムでエラーの原因になる部分を見つけてもらう
- アルゴリズムから予想されるエラーを見つけてもらう
- ex) Javascript：ES5で書いてあるコードをES6またはTypescriptに変換してもらう
- ex) Javascript：jQueryで書いてあるコードをReactやVue.jsのコンポネントに変換してもらう

などのバリエーションで行えます。

#### フィードバック

そして、テスト結果のフィードバックも大事です。

テストはあくまでも道具です。テストの結果で採用を決めるのではなく、テストの結果以外の事項も評価の対象です。

ここまでしたら、エンジニア採用での不安はある程度解消できると思います。

## 結論

仕事の同僚、会社の宝物を探す作業は気軽にすべきではない大事なこと。各社にぴったりの人材と出会えるように、この記事が一役立てたらと思います。

### おまけ

弊社では、旅行業界をリードしていくフロントエンドエンジニアを積極的に募集中です。

- フロントエンドエンジニア（旅行事業）

[アッ！と思わせる旅行サイトへグロースさせるフロントエンジニアを真剣募集！](https://www.green-japan.com/job/43286)

- フロントエンドエンジニア（新規事業/EC）

[前年比189％成長の上場企業で、一緒に新規事業を立ち上げましょう！](https://www.green-japan.com/job/72699)

ご興味のある方、ぜひ一度ご覧になってください！