SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Developers Summit 2023 セッションレポート(AD)

プロが求める実装スキルとは? コーディング試験の解答を実際にレビューしてみた

【10-C-5】ゆめみ流“技術面接”コードチェック実践方法 ~エンジニアによるエンジニアのための、最高の選考体験の作り方~

  • このエントリーをはてなブックマークに追加

 プログラマー採用や人材育成の一環として、コーディング能力をチェックするコーディングテストが広がっている。でも実際のところ、コーディングテストにはどのような問題が出て、その回答をどのように判定しているのだろうか。本講演では、エンジニア採用で行われているコーディングテストとそのレビュー内容を株式会社ゆめみのサーバサイドエンジニア・シニアアーキテクトでエンジニア採用を担当している仲川樽八氏、株式会社ギブリーの執行役員でコーディングテストツール「Track Test」「Track Job」の事業部長である山根淳平氏が詳しく解説した。

  • このエントリーをはてなブックマークに追加

なぜ、エンジニア採用にコードチェックを導入したのか?

 最初にファシリテータの山根氏が、エンジニア採用の現状とゆめみの取り組みについて簡単に紹介した。

 「最近は、技術者が人事部のミッションを持ちながら採用に関わることが増えています。どのようにしてエンジニアの仲間集めをしていくのか。候補者となるエンジニアの方には自分の技術力を正しくアピールしてもらって、最適なマッチングを図っていくのか。選考プロセスの中での最適化が重要になっています」

 ゆめみでは、コードチェックを実施して、丁寧にレビューした結果を合否に寄らず一人ひとりにフィードバックするという、候補者の技術力向上につながる育成的な選考プロセスを作っており、これに挑戦したい優秀な求職者の応募が年々増えている。

 続いて、ゆめみでエンジニア採用を担当している仲川氏が、「いろんな部門があり部門ごとに採用の方針は異なりますが、フロントエンドとAndroid・iOS・サーバーサイドの採用でコーディングテストを実施しています」と自社を紹介した。

 では、ゆめみではなぜコーディングテストを導入しているのだろうか。

 仲川氏は、5年以上前から新卒採用で、実際にしっかりコードが書けるかポテンシャルを見るためにコーディングテストを始めたと説明した。この段階では、コードを全く書けない人の足切りが目的だった。

 「ただ現在は会社のブランド力が向上して応募者が増えており、応募してくださる方のレベルがどんどん上がってきています。単純な足切りだと、ほとんどの方が満点に近い状態です」

 そのために、業務で必要となるコーディング力やグループ開発の経験値を見るためにコーディングテストを使っている。

コーディングテストでは、どの観点で見て何を重視するのか

 現在、ゆめみのサーバサイドエンジニア採用では次のような選考フローを採用している。コーディング試験は、カジュアル面接と書類審査のあとで実施しており、機械採点による足切りのあとエンジニアがコードレビューを実施している。このコーディングテストには、ギブリーのTrackを採用している。そして、エンジニアによる一次面接のあと、代表者による最終面接に進むというフローだ。

ゆめみの選考フロー
ゆめみの選考フロー

 一次面接のコストは大きい。その前にある程度絞り込みつつ、より優秀な人と面接できるようにするため、この位置にコーディングテストを入れている。コーディングテストでは、次図のポイントを重視している。

コーディングテストの評価観点:何を重視するのか
コーディングテストの評価観点:何を重視するのか

 これは企業によって異なると前置きした上で、ゆめみでは業務でよく扱う領域や、チーム開発や長期メンテナンスが必要になる経験などを意識していると説明した。

 「逆にそこまで重視してないのが、迅速に回答できることや特定のプログラミング言語やライブラリ・フレームワークを使えることです。効率的なアルゴリズムについても、ちょっとググったら出てきますし、ChatGPTのようなものが実用的になるかもしれません」

 では、こうした重視ポイントを具体的にどの観点で見るのだろうか。

 「大きく3つあって、可読性とデータ整合性・安全性、あと将来のメンテナンス性の観点で見ていきます。仕様を満たす実装力だけでなく、チーム開発や運用の経験を推し量りたいからです」

コーディングテストの評価観点:どの観点で見るか
コーディングテストの評価観点:どの観点で見るか

コーディング問題の難易度とレビューの粒度をどうそろえるか

 問題については、Trackが用意している700問以上の問題にほとんど目を通したうえで選んでいるそうだ。難易度は、コーディングテストを実施している他の会社よりも簡単になっている。問題が解けるかどうかではなく、ちゃんとリファクタリングしたコードや、自分はこういうポリシーで書いたというコードをみたいからだ。

 「難しい問題だと、どうしても書きかけのコードになりがちで、評価しにくいです。実際に動いたコード同士だと比較しやすいですが、『これはちゃんと動くはずだけど今のところ動いてない部品です』みたいなコードだと判断が難しくなります」

 そのために、プログラミング経験者であればイメージがつきやすい簡単な問題を用意している。力技でも書けるし、ちゃんと書くこともできるような問題だ。難しくて手が出ない問題だと応募する気にもならないが、腕に自信があるなら「応募してみようかな」というところを狙っているそうだ。

 「解答できるプログラミング言語は、弊社でレビュー可能なものを複数用意しています。学生に人気のあるPythonも入れてあります」

 こうして応募された解答は、機械的な採点で足切りをしたあと、複数のエンジニアによるレビューを実施している。面接官同士で、レビューの粒度をそろえるために次図のような工夫をしている。

面接官同士で、レビューの粒度をそろえるための工夫
面接官同士で、レビューの粒度をそろえるための工夫

 ゆめみでは、現在サーバーサイドのレビューを16人ほどで実施している。各プログラミング言語で模範解答と観点ごとに項目を分けた評価テンプレートを用意している。さらに必ず2名以上でレビューし、評価が難しい場合は3人目の評価を仰いでいる。

 「この解答は面白そうだとか、この書き方はよくないかなといった評価の分かれる解答は、オープンな評価会で検討・共有しています。これは、私たちを含めてかなり勉強になりました」

実践コードレビュー:サンプル問題の内容は

 ここでいよいよサンプル問題の解答について具体的なコードレビュー内容を解説した。問題は、サーバーサイドエンジニア応募者向けの模試である。サンプル問題は次の通り。

新卒・中途採用 サーバーサイドエンジニア応募社向けの模試
新卒・中途採用 サーバーサイドエンジニア応募社向けの模試

 「対象のプレイログは、肥大化して数千行を超えることがあります。上限は特に書いていないのでメモリのことを考慮する必要があります。プレイヤー総数は1万人を超えません。また、同点の平均スコアのプレイヤーが存在した場合、rankingに同じ数字が割り当てられます。この場合、10名以上のランキングが作られます」

 解答したコードは、ギブリーのビジネスサイドでプログラミングを学習しているメンバーが書いたものだという。準備しておいたテストパターンで解答を機械採点すると通過率100%となった。これで次のコードレビューに進むことになる。

サンプル問題:解答例
サンプル問題:解答例

実際にコードレビューしてみた

 「解答コードを見ると全部で55行くらいあり関数化もされていて、シンプルに書いてあったと思います。ただコメントが記述されていませんでした」

 実際の採点テンプレートとレビュー結果は次図の通り。

採点テンプレートとレビュー結果
採点テンプレートとレビュー結果

 本セッションでは、各評価項目について実際に詳しく解説したが、本レポートでは代表的な項目に限って紹介する。まず全体的に可読性の高いコードか調べるため、メインロジックの記述内容を見た。すると、csv_info変数があるが、一度も利用されていないことが分かった。また、scores変数とplayers変数・plyayer_score変数を唐突に利用していた。

コードレビュー > メインロジックを確認する
コードレビュー > メインロジックを確認する

 「コードをよく読むと、唐突に出てきた変数をすべて先頭行でグローバル変数として定義していました。この時点でグローバル変数に中身は入っていないので、各関数でこのグローバル変数を自由に読み書きしているようでした。おそらく最初は関数化せずに、頭から作っていって、それを処理のブロックごとに関数化したのではないかと考えました」

コードレビュー > 先頭行でグロ―バル変数を定義
コードレビュー > 先頭行でグロ―バル変数を定義

 これは、もちろんグローバル変数の汚染につながりやすい。あるべきコードとしては、グローバル変数をすべて削除し、main()関数のなかで各関数を呼び出して、その戻り値をmain()関数のスコープ内だけで利用する形にしたい。

コードレビュー > To Be グローバル変数の排除
コードレビュー > To Be グローバル変数の排除

 次は個別の関数を調べていった。ここでは、load_csv()関数の責務に注目した。すると、players変数とscores変数を返しており、それからjoin_list()関数で、この2つの値を連結したplayer_score変数を作成していた。

コードレビュー > load_csv()の責務に注目すると
コードレビュー > load_csv()の責務に注目すると

 「このデータをよく見みると、インデックス値は同じでplayers変数はプレイヤーIDだけ、scores変数はそのプレイヤーIDの人が取った得点をリストで含んだデータでした。インデックス値が同じだけど2つの別データは、扱いづらい不安定なものだと考えています。どちらか片方だけデータを挿入すると全部ずれてしまう。そういうものがバグを生み出しやすいと思います」

 load_csv()関数が辞書型でデータを返すようにすれば再度連結しなくても良くなる。次図の右下のように、プレイヤーIDに対するスコアのリストを保持するのだ。

コードレビュー > To Be 互いに相関のある不安定な変数の排除
コードレビュー > To Be 互いに相関のある不安定な変数の排除

 いずれも現場でコードを書くにあたって必要となる実践的なテクニックばかりだ。本セッションのコードレビューでは、この他にも「プログラムの処理の流れが適切な粒度で分離されているか」「関数名と変数名のリファクタリング」「唐突なマジックナンバーの使用と、問題に対応した数字の使用」「ファイルI/O周りの処理」「メモリとCPUの効率」など、多くのポイントについて詳しく解説した。

 ゆめみでは、このようやレビュー結果を、テキストでキレイにまとめてフィードバックするのは難しいので、評価でよかったところと改善ポイントをセットにして不合格になった応募者にも伝えているそうだ。

 「もしかすると応募者によってはピンとこないところがあるかもしれませんが、『我々はこのように見ました』という内容を改善ポイントとしてお伝えするようにしています」

 なお、講演後のAsk The Speakerで「合否関係なくレビューのコメントを応募者に伝えるのはなぜでしょうか?」という質問があった。

 これについて仲川氏は「不合格だった場合も6カ月とか一定の期間をおいて再チャレンジできる仕組みを用意している」と説明した。コードレビューの内容をちゃんと自分で理解して、もう一度チャレンジして、そこが改善されていたらそれを評価するというのだ。

 「あとは、学生さん全体への貢献といった側面もあり、こういうことをやっている会社だよと見ていただければと思います」

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加

提供:株式会社ギブリー

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/17452 2023/04/13 12:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング