海外の採用面接で、持ち帰りテストを受けた体験記（概要・設計編）

![.NET Core 3.1](https://img.shields.io/badge/.NET Core-3.1-brightgreen) ![Node JS 14.x](https://img.shields.io/badge/Node JS-14.x-brightgreen) ![NPM 14.x](https://img.shields.io/badge/NPM-6.14.x-brightgreen)

海外でソフトウェア開発系の仕事を探すと、採用面接の1つとして簡単なコーディングテストが行われるのが一般的です。特に GAFA(Google/Apple/Facebook/Amazon)では、[Codility](https://www.codility.com/
)のようなサイトで、パズルのような課題を制限時間内に解くというテストが当たり前。

ただ、中には **Take-Home Coding Test という少し珍しいタイプの試験**もあります。

現在、僕が働いているデンマークのデジタルマーケティング会社でもこのTake-Home Coding Testがあり、なかなか面白かったので体験をまとめてみました。

#Take-Home Coding Testとは

一般的なコーディングテストでは、パズルみたいな問題をオンライン上で制限時間内に解くものが多く、どちらかというとアルゴリズムやデータ構造の知識をテストするものが多いかと思います。

一方で、Take-Home Coding Test はパズルではなく、**業務内容に近いテーマの課題**が出され、自宅で好きな時間に取り組みます。制限時間が設定されることもありますが目安なことが多いので、**設計・実装の自由度はかなり高い**ことが特徴です。最終的には、完成したものを**デモしながらコードレビュー**してもらい、評価されるという形です。

採用される側の負担が大きいのがデメリットですが、コードの正確性やパフォーマンスしか評価しないオンラインテストと異なり、

- 課題認識力
- ロジカルシンキング
- 設計の考え方・設計センス
- 開発環境・ツールの使いこなし度
- プレゼン・コミュニケーションスキル

などの**実務経験やスキルをアピールしやすいというメリット**があります。


#課題内容

僕の場合は、1次面接でなんとなく良い雰囲気になったところで、面接をしてくれたCTOから簡単なTake-Home Coding Testをしたいと伝えられました。

オッケーと回答した後に、メールで送られた課題は↓の内容でした。

>  **Make a web app that searches twitter for a search keywords and get results back in the browser.**

> **Task #1**
>Using C# - be able to search Twitter API for search keywords. Result get stored in memory.

> **Task #2**
>Using Javascript (ReactJS preferred) - present the search result in the browser (how you present is up to you)

> **Task #3**
>Create an option to search “only results with images” and display the results with images.


要約すると、**「Twitter APIを使い、ツイート検索するウェブアプリを作る」**という課題。

補足的なTask #1~3を解釈すると、**バックエンドはC#で、フロントエンドはReactJSで作る**。

ついでに**画像付きのツイートだけを検索するオプションをつける**というのがポイントでした。

デモ＆コードレビューは1週間後に設定され、目安として半日から1日程度で開発できるぐらいのレベルのもので十分だよとのこと。

また、デモとコードレビューは僕のPCで行うので、ローカル環境で動けばOKとのことでした。

# 開発する前に方針を考える

今回の最終的な目的は採用に漕ぎ着けることなので「相手を感心させる」ための方針を明確化しておくことに。

そのため、求められている職種・会社の特徴・自分の強みを踏まえて、アピールすべきこと、アピールしたいことを整理して、3つの方針を作りました。

<dl>
  <dt>方針(1)</dt>
  <dd>幅広い知識が求められる「フルスタックエンジニア」の募集なので、できるだけ色々な事(手法・書き方・ツール・ライブラリ)を知っていることをさりげなくアピールする。</dd>
  <dt>方針(2)</dt>
  <dd>自分の強みとして「シンプルだけど拡張性あるアーキテクチャを考えられる設計力」をアピールする。</dd>
  <dt>方針(3)</dt>
  <dd>ユーザーエクスペリエンスやデザインを重視しているデジタルマーケティングの会社なので、UIにはそれなりに「モダンな機能を盛り込む」。</dd>
</dl>

求められている課題をただ実装するだけではなく、きちんと自分の強みや期待されているスキルを持っていることをアピールできるように考えたところがポイントかなと思います。


# ざっくりとした全体設計

さて、作るウェブアプリの名前は、受けている会社の名前をもじって「HeySearch」という名前にすることにしました。そして方針(1)と(2)を踏まえつつ、ざっくりとした全体像を書いてみました。

![HeySearchDesign_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656463/4c8282ba-d90c-e972-5246-5adf35b0137b.png)


設計上のポイントは2つ。

### 設計ポイント①

まず、Frontend-Backend間はREST API/JSONでやりとりできるようにしています。（下図 ポイント①）**REST APIにすることで、バックエンドはTwitter APIを使ってJSONデータを生成することに集中でき、UIを意識する必要がありません。** 逆にフロントエンドはUIだけに専念できるようにしています。

こうすることで、まずバックエンドをしっかり作った後に、フロントエンドのUIデザインの作り込みに専念する、という開発の流れを作っています。

今回は1人での開発ですが、大規模なプロジェクトなら、フロントエンドとバックエンドで開発チームを分けて、並行開発することも可能です。

### 設計ポイント②

そしてバックエンド側では、インターフェースと共通データ構造を定義しました（下図 ポイント②）この定義を作ることで、**Twitter以外のSNS(FacebookやInstagramなど)にも対応しやすくなります。**

今回はTwitter検索だけを作れば良いので、SocialNetworkSearchインターフェースを継承するTwitterServiceだけを実装します。ちなみに TwitterService の役割は、

1. Twitter APIを使ってツイート検索をかける
2. Twitter APIで得た検索結果をJSONデータを受け取り、TwitterModelオブジェクトに変換する
3. TwitterModelオブジェクトを使って、共通データ構造のSearchResultオブジェクトに変換する

最終的にバックエンドは、TwitterServiceが作った SearchResult オブジェクトをJSONデータにしてフロントエンドに返すことで一連の処理が完了します。

![HeySearchDesign_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656463/f12c7249-6b71-f5f6-efe0-c165458cd0af.png)

# フロントエンドデザインと工夫

フロントエンドのUIはできるだけシンプルなものにすることにしたので、ざっくりスケッチしてこんな感じにすることにしました。

![HeySearchDesign_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656463/c36cad9a-acaa-2d5b-fe53-bcef20638b37.png)

また、方針(3)で書いたように、今回の会社はデザインやユーザーエクスペリエンスを重視しているそうなので、フロントエンドにはできるだけモダンな機能を盛り込むことにします。

ざっと列挙すると↓のような感じ

- ツイッター検索中など、バックエンド処理を待っている最中の Loading アニメーション表示
- ツイートの検索結果が多い場合、ブラウザを下にスクロールしたら自動的に次の検索結果を追加する Infinit Scroll機能
- スマホなどの小さい画面に対応したレスポンシブUI (幅広いブラウザでは表形式で検索結果を表示し、小さい画面はリスト形式で表示する)
- 旧世代のブラウザ（IE10/IE11など）のサポート

# あえて省くことにした機能

HeySearchにはあえてユーザー認証を入れないことにしました。なぜなら、ログイン機能は求められていないですし、ユーザー認証を入れると難易度が上がってしまい、半日〜1日程度の開発ではなくなってしまうからです。

# 完成品と採用結果

そして、最終的に作ったものは↓のようになりました〜。（かなりシンプル・・・）

![HeySearchDesign_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656463/e2509a24-f67c-153b-97bf-8578acd401cf.png)


一応、レスポンシブになっているので、スマホなどの小さい画面で見ると、検索結果が表ではなくリスト表示になります。

![HeySearchDesign_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656463/0ec962b1-b532-e0c4-c216-e8bac8229b60.png)

実装している間に、Twitter APIはリツイートや引用ツイートも返してくることがわかったので、当初予定していなかった "Include retweets" というオプションも追加しました。このオプションが付いていると、リツイートも検索結果に含まれるようになります。


### ソースコードはgithubで公開中

バックエンド、フロントエンドの実装紹介は別途記事にする予定ですが、最終的なソースコードは  [github](https://github.com/higuhi/HeySearch#readme) で参照できます。

https://github.com/higuhi/HeySearch#readme 


下記の手順で実行環境が構築できるはずなのでぜひお試しを！
（Twitter API用のBearerトークンが必要なので、事前にTwitter Developer Accountの登録が必要です）

```
# git からコードを入手
git clone https://github.com/higuhi/HeySearch.git

# フロントエンド用のパッケージを入手
cd HeySearch/ClientApp
npm install 
cd ..

# バックエンドが使用する Twitter API のBearer Tokenを環境変数に設定（.NET Secret Managerを使います）
dotnet user-secrets init
dotnet user-secrets set "HeySearch:Twitter:BearerToken" "<Twitterアプリ用のBearerトークンの文字列>"

#サーバー実行 （起動後にブラウザで https://localhost:5001/ を開いてください）
dotnet run 
```


### 肝心の採用結果は・・・

さて、肝心な面接結果ですが、この HeySearch をデモ＆コードレビューをしたところ、**CTOから "I love it!" とかなり褒められました！** わーい ✌️

ただし、最初にデモを動かしたら、いきなりエラーメッセージが表示されてビビるというアクシデントも😭　会社のミーティングルームだったので、僕のパソコンがインターネットにつながっていなかっただけでしたがちょっと焦りますね💦 

ゲスト用のWiFiのパスワードを教えてもらい、ネットにつないだらちゃんと動作のでほっと安心。ついでに、冗談半分で「エラー処理がちゃんとされていることを見せれて良かった。えへっ」と伝えたら笑ってくれました。

そんなことで、今はその会社で働いています。

次回は、実装内容をより詳細に紹介する記事を書こうと思います。