ホワイトボード面接で「いきなりコードを書き始めてしまい、途中で行き詰まった」という経験はないでしょうか。頭の中ではなんとなく解法が浮かんでいるのに、それをいきなりPythonやJavaの文法で表現しようとすると手が止まってしまう。そんな苦い思い出を持つエンジニアは決して少なくありません。
実は、この問題を解決する強力な武器が疑似コードです。疑似コードとは、プログラミング言語の厳密な文法に縛られることなく、アルゴリズムのロジックを人間が読みやすい形で記述する手法のことです。特定の言語に依存しないからこそ、思考の流れをそのまま書き出すことができます。ホワイトボード面接では、この疑似コードを効果的に使いこなせるかどうかが、合否を分ける重要なポイントになることがあります。
この記事では、ホワイトボード面接で疑似コードをどのように書き、どのように活用すれば面接官に好印象を与えられるのかを具体的に解説していきます。疑似コードの基本から応用まで、実践的なテクニックを幅広くカバーしていますので、面接を控えている方はぜひ参考にしてみてください。
疑似コードを書く意味と面接官の視点
ホワイトボード面接で疑似コードを書くのは、単にコーディング前のメモ書きではありません。面接官の立場から見ると、疑似コードを書く行為そのものが、候補者の思考力とコミュニケーション能力を測る指標になっているのです。問題を聞いた瞬間にコードを書き始める候補者と、まず疑似コードでロジックを整理してから実装に移る候補者がいたら、後者のほうが「計画性のあるエンジニア」として評価されるのは自然なことでしょう。
ところで、疑似コードを書くことのメリットは面接官へのアピールだけではありません。自分自身の頭を整理するうえでも、疑似コードは非常に有効なツールです。特に時間制限のあるホワイトボード面接では、考えがまとまらないまま書き始めると途中で大幅な修正が必要になり、貴重な時間を浪費してしまいます。疑似コードの段階でロジックの穴を見つけておければ、実装段階での手戻りを大幅に減らすことが可能です。
そういえば、多くの面接官が口を揃えて言うことがあります。「完璧なコードが書けなくても、正しいアプローチで疑似コードが書けている候補者は高く評価する」と。これは、実務では細かい文法はIDEが補助してくれるのに対し、ロジックを正しく組み立てる能力はツールでは補えないという現実を反映しています。疑似コードで論理的な思考を見せることは、それだけで大きなアドバンテージになるのです。
疑似コードの基本的な書き方
疑似コードに「これが正しい書き方」という唯一の正解はありません。しかし、ホワイトボード面接で効果的に使うためには、押さえておくべきポイントがいくつかあります。重要なのは、面接官が読んでパッと理解できる程度の明快さを保ちつつ、アルゴリズムの骨格がしっかり伝わるレベルの詳細さを持たせることです。
疑似コードで使う表現は、自然言語とプログラミング言語のちょうど中間くらいを意識するのがよいでしょう。たとえば「配列を左から順に見ていく」と完全に日本語で書くのは抽象的すぎますし、逆にfor文をCやJavaの文法で厳密に書くのはもう実装コードです。「for each element in array」くらいの粒度が、疑似コードとしてはちょうどよいバランスになります。
実は、疑似コードの書き方で面接官が特に注目しているのは、制御フロー(条件分岐やループ)の表現です。if-else の分岐が何を判定しているのか、ループが何回まわるのか、そして終了条件は何なのか。これらが明確に読み取れる疑似コードは、その後の実装への移行もスムーズにいきます。逆に、分岐やループの構造がぼんやりしている疑似コードは、そのまま曖昧な実装につながりがちです。
ホワイトボードに疑似コードを書くとき、インデント(字下げ)を意識するだけで読みやすさは劇的に変わります。ネストが深くなるごとに一段下げるという、コーディングでは当たり前の習慣を疑似コードにも適用するのです。ホワイトボードのスペースは限られていますから、インデント幅はスペース2つ分くらいで十分です。重要なのは、論理的な階層構造が視覚的にわかることです。
関数の境界も明確にしておきたいポイントです。疑似コードの中で別の関数を呼び出す場合は、その関数名をCALLやINVOKEのように目立つキーワードで書くか、あるいは関数の定義を別の場所に書いて参照する形にすると、ロジックの全体像がつかみやすくなります。面接官は「この候補者はモジュール化の意識がある」と感じてくれるでしょう。
疑似コードにコメントを付けるかどうかは判断が分かれるところですが、要所にはつけておくことをおすすめします。特に「なぜこの分岐が必要なのか」「このループの目的は何か」といった意図を短く書き添えておくと、面接官があなたの思考をトレースしやすくなります。ただし、すべての行にコメントを書くのはやりすぎです。疑似コード自体がコードの説明なのですから、コメントのコメントのようになってしまっては本末転倒です。
抽象度の調整テクニック
疑似コードを書くうえで最も難しく、かつ最も重要なのが「抽象度の調整」です。抽象度が高すぎると、面接官に「この人は具体的な実装イメージが湧いていないのでは」と思われてしまいます。逆に抽象度が低すぎる、つまり実装コードに近すぎると、疑似コードを書く意味そのものが薄れてしまうのです。
理想的な抽象度は、問題の複雑さと面接の段階によって変わります。最初に疑似コードを書くときは、アルゴリズムの大枠を捉えるために高めの抽象度で書き始めるのがよいでしょう。「入力を受け取る」「条件を満たす要素を探す」「結果を返す」といった粗いステップから始めて、面接官とのやりとりの中で徐々に詳細化していくのが自然な流れです。
そういえば、この「段階的詳細化」というアプローチは、ソフトウェア設計のトップダウン手法と同じ考え方です。最初から細部にこだわるのではなく、全体の構造を固めてから部分を詰めていく。この進め方を面接の場で見せられると、面接官は「設計思考ができる人だ」という印象を持ちます。疑似コードはアルゴリズムの記述にとどまらず、あなたの設計スキルをアピールする手段にもなり得るのです。
問題を初めて聞いたとき、すぐに細かいロジックを考え始めるのではなく、まずはハイレベルな疑似コードで全体の方針を示しましょう。たとえば「最短経路を見つける」という問題であれば、「1. グラフを構築する」「2. 始点から探索を開始する」「3. 終点までの最短距離を返す」というレベルで十分です。この段階で面接官に方針を確認し、正しい方向に進んでいるかフィードバックをもらうのが賢い戦略です。
面接官が「いいですね、では詳しく書いてみてください」と言ったら、そこから一段階ずつ詳細化していきます。「グラフを構築する」を「隣接リストとして入力をパースする」に展開し、「探索を開始する」を「BFSでキューを使って層ごとに探索する」に展開するといった具合です。この段階的な展開を見せること自体が、あなたの問題解決プロセスのデモンストレーションになっています。
ハイレベルから詳細化した疑似コードは、実装コードに非常に近い形になります。この段階では、変数名やデータ構造の選択も具体的に書くのが望ましいでしょう。「visited集合を用意する」「キューに始点を入れる」「キューが空になるまでループ」といった表現は、そのままコードに翻訳できるレベルの詳細さです。
ところで、ローレベルの疑似コードを書くときに気をつけたいのは、エッジケースへの言及です。「入力が空の場合はどうするか」「グラフが非連結の場合はどうするか」といった例外的な状況を疑似コードの段階で書き込んでおくと、面接官は「細部まで考えが及んでいる」と評価します。エッジケースの処理を後回しにする候補者は多いのですが、疑似コードの段階で触れておくだけで、印象は大きく変わります。
疑似コードから実装コードへの変換テクニック
疑似コードを書いたら、いよいよ実装コードに変換するステップです。ここでのコツは、疑似コードの各行を機械的にコードに変換していくことです。疑似コードの段階でロジックがしっかり固まっていれば、コードへの変換は翻訳作業に近い作業になります。考えることよりも書くことに集中できるので、文法ミスも減らせるという利点があります。
変換の際に意識したいのは、疑似コードの構造をできるだけ保つことです。疑似コードで3つのステップに分けたなら、コードでもその3つの区切りがわかるように書きましょう。疑似コードとコードの対応関係が明確であれば、面接官がコードを読むときの負担が大幅に軽減されます。「疑似コードの2番目のステップがこのコードブロックに対応しています」と指し示せるのは、大きな強みです。
実は、変換で最もつまずきやすいのは、疑似コードでは省略していた初期化処理や型宣言の部分です。Pythonのような動的型付け言語ではあまり問題になりませんが、JavaやC++を使う場合は、変数の型や初期値を明示する必要があります。疑似コードを書く段階で「ここは後で初期化コードが入る」とメモしておくと、変換時の漏れを防げます。
面接中に疑似コードから実装に移る過程で、疑似コードの論理にミスがあることに気づく場合があります。このとき、慌てて疑似コードを書き直す必要はありません。面接官に「実装に移る中でここのロジックに改善点を見つけました」と説明しながら、疑似コードに修正を加えればよいのです。
むしろ、自分のミスに気づいて修正できる能力は、面接官が高く評価するポイントのひとつです。実務でもコードレビューやデバッグで自分の過ちに気づく場面は日常的にあります。重要なのは、間違えないことではなく、間違いに気づいてリカバリーできることなのです。疑似コードの修正をためらう必要はまったくありません。
面接官に好印象を与える疑似コードの活用法
疑似コードは書くだけでは不十分です。面接官とのコミュニケーションツールとして積極的に活用してこそ、その真価を発揮します。書いた疑似コードを面接官に見せながら「この方針で進めてよいでしょうか」と確認を取る行為は、実務における設計レビューやコードレビューのシミュレーションとも言えます。
面接官と疑似コードについて議論する際、自分のアプローチの時間計算量と空間計算量に言及できると、さらに評価が上がります。「この疑似コードではソート済み配列に対して二分探索を使うのでO(log n)になります」のように、疑似コードの各部分の計算量を説明できれば、面接官は安心してコーディングに進むよう促してくれるでしょう。
ところで、疑似コードを使った面接のもうひとつのメリットは、面接官からヒントをもらいやすくなることです。いきなりコードを書いている段階で行き詰まると、ヒントの出しようがありません。しかし疑似コードの段階であれば、面接官は「ここの部分はハッシュテーブルを使うとどうなりますか?」のように、ロジックレベルでのヒントを自然に提供できます。疑似コードは候補者と面接官の間の共通言語として機能するのです。
余裕がある場合は、ひとつの問題に対して複数のアプローチを疑似コードレベルで書き出し、トレードオフを議論するという方法も非常に効果的です。「アプローチAは時間計算量O(n^2)ですが実装が簡単です。アプローチBは時間計算量O(n log n)ですがソートが必要です」のように比較検討できると、面接官はシニアレベルの判断力を持つ候補者として見てくれます。
この比較を疑似コードで行うメリットは、実装コードを2つ書く時間がなくても議論できるという点にあります。疑似コードなら数行で本質的な違いを表現できるので、限られた面接時間を有効に使えます。面接官も「この候補者は常にベストなアプローチを探す姿勢がある」と感じるでしょう。
典型的な問題パターン別の疑似コード例
ここからは、ホワイトボード面接でよく出題される問題パターンごとに、疑似コードの書き方を見ていきましょう。パターンを知っておくと、初見の問題でも「このパターンに近いな」と当てはめることができ、疑似コードを書くスピードが格段に上がります。
配列の走査やフィルタリングに関する問題では、入力配列、出力の形、そしてフィルタ条件の3つを明確にした疑似コードが効果的です。「配列の各要素について、条件Xを満たすなら結果に追加する」という骨格が書ければ、あとは条件Xの部分を問題に合わせて埋めるだけです。このテンプレート的な思考法は、面接でのスピードを大幅に向上させてくれます。
再帰的な問題の場合、疑似コードではベースケースと再帰ケースを分離して書くことが極めて重要です。「ベースケース:入力が空なら空を返す」「再帰ケース:先頭要素を処理して、残りに対して再帰呼び出し」という構造を明示しておくと、再帰の終了条件を見落とすミスを防げます。実は、再帰の問題で行き詰まる原因のほとんどは、ベースケースの定義が曖昧なことに起因しています。
グラフやツリーの問題では、探索の種類(BFS/DFS)、訪問済みノードの管理方法、そして各ノードで行う処理の3点を疑似コードで明記しておくのが定石です。これらが明確に書かれていれば、実装コードへの変換で迷うことはほぼなくなります。グラフ問題は実装が複雑になりがちですが、疑似コードで骨格を固めてあれば、コーディングは格段に楽になるはずです。
ツリーの問題に特有なのは、左部分木と右部分木の再帰呼び出しです。疑似コードでは「左に対して再帰」「右に対して再帰」「結果を統合」という3ステップを明確に分けて書くと、前順・中順・後順のどの走査方法を使っているかが一目でわかります。面接官に走査の種類を問われたとき、疑似コードを指し示しながら答えられるのは大きな利点です。
動的計画法の問題では、状態の定義、遷移式、ベースケースの3つを疑似コードで書き出すことが最も重要です。「dp[i]は○○を表す」「dp[i] = max(dp[i-1], dp[i-2] + value[i])」「dp[0] = 0, dp[1] = value[1]」のように、これら3要素が明確に記述されていれば、面接官はあなたが動的計画法の本質を理解していると確信するでしょう。
そういえば、動的計画法の疑似コードを書くとき、メモ化再帰(トップダウン)とテーブル充填(ボトムアップ)の両方のアプローチを示せると、さらに高い評価を得られます。メモ化再帰は再帰的な疑似コードに「既に計算済みなら保存値を返す」という一行を加えるだけなので、追加の記述コストは小さいものの、面接官への印象は大きくプラスに働きます。
疑似コードを書くときによくある失敗とその対処
ホワイトボード面接で疑似コードを書く際に、多くの候補者が陥りやすい失敗パターンがいくつかあります。これらを事前に知っておくだけで、本番での致命的なミスを避けられるでしょう。
最も多い失敗は、疑似コードが長くなりすぎることです。ホワイトボードのスペースは有限ですし、面接官が読むのにも時間がかかります。疑似コードが20行を超えるようなら、関数に分割するか、抽象度を上げて圧縮する必要があります。目安としては、ひとつの関数の疑似コードは10行以内に収めるのが理想的です。
もうひとつありがちなのが、疑似コードを書いたまま放置してしまうことです。せっかくよい疑似コードが書けても、面接官に説明せずにいきなり実装コードに移ってしまうと、疑似コードを書いた意味が半減します。疑似コードを書き終えたら、必ず面接官に向き直って「このアプローチでよいか確認させてください」と一声かけましょう。この一言があるかないかで、コミュニケーション力の印象は大きく変わります。
実は、もうひとつ見落とされがちな失敗が、疑似コードと実装コードのスタイルを混在させてしまうことです。疑似コードの中に突然arr.lengthのような言語依存の表現が出てきたり、自然言語の文とif文のコードが同じ行に混ざっていたりすると、読み手は混乱します。一貫したスタイルで書くことを心がけてください。
疑似コードの練習方法
疑似コードを上手に書けるようになるには、やはり練習が欠かせません。ただし、疑似コードの練習はコーディングの練習とは少しアプローチが違います。コーディングでは「動くコードを書く」ことがゴールですが、疑似コードの練習では「読んだ人がアルゴリズムを理解できるか」がゴールなのです。
おすすめの練習方法は、LeetCodeなどの問題を解く際に、まず疑似コードだけをノートに書き、それを翌日の自分が読んで理解できるかどうかをチェックすることです。一晩寝て文脈を忘れた状態でも読める疑似コードは、面接官にも伝わる疑似コードです。逆に、翌日読み返して「これ何のことだっけ」と思ったなら、抽象度や表現方法を改善する余地があるということです。
友人同士でホワイトボード面接のモックを行うのも非常に効果的な練習方法です。面接官役の人に疑似コードを読んでもらい、「ここの部分がよくわからない」と指摘してもらうことで、自分では気づかなかった表現の曖昧さを発見できます。面接本番で初めて第三者に見せるよりも、事前にフィードバックを受けておくほうがはるかに安心して臨めるはずです。
まとめ
疑似コードは、ホワイトボード面接において思考を整理し、面接官とコミュニケーションを取るための強力なツールです。適切な抽象度で書かれた疑似コードは、あなたの問題解決能力と設計思考を面接官に直接伝えてくれます。
疑似コードを書いてから実装に移るという一手間を加えるだけで、コーディングの精度と速度が向上し、面接の合格率も上がります。日頃の問題演習から疑似コードを書く習慣を身につけて、ホワイトボード面接を自信を持って乗り越えてください。