Java文字列反転の面接で迷わない答え方を解説。StringBuilder、immutability、計算量、Unicode、StringBufferの違いまで整理し、追加質問にも強くなれます。
Java の文字列反転の面接問題でつまずく候補者の多くは、コードでつまずいているわけではありません。説明でつまずいています。動くコードは書けたのに、面接官に「なぜ別の方法ではなくそのアプローチを選んだのですか?」と聞かれた瞬間に黙ってしまうのです。java の string reverse 面接問題は、要するに、正しい道具を選び、フラッシュカードを読んでいるように聞こえずに、その理由を 30 秒で言えるかどうかを試す問題です。
このガイドでは、まず最初に答えるべき定番の回答、1 分以内で話せる説明スクリプト、そして immutability、計算量、Unicode、StringBuffer といった、練習した人と準備した人を分ける追加質問の落とし穴まで取り上げます。
面接官が本当に聞きたい Java の最初の答えから始める
最初に言うのは StringBuilder。派手だからではなく、いちばん素直なデフォルトだからです
Java で文字列を反転する正当な方法は少なくとも 4 つあります。手動で末尾から先頭へ走査する方法、char[] の入れ替え、スタック、そして StringBuilder.reverse() です。どれも理屈は通ります。ただし面接では、最初に何を言うかが、単なるパズルではなく本番コードをどう考えるかを示します。char[] の入れ替えはメモリ理解を示し、手動ループはアルゴリズム理解を示し、スタックは LIFO の理解を示します。どれも有用ですが、まずは定番の答えを押さえていることを示した上での話です。
StringBuilder.reverse() が最初の答えとして適切なのは、短く、正しく、説明しやすいからです。これは Java 標準ライブラリ の一部で、バッファ管理を任せられ、シニアエンジニアならこうレビューするだろうという書き方になっています。見せびらかしているのではありません。判断力を示しているのです。
実際にはこう見えます
コードの骨組みと、それに対応する口頭説明は次のとおりです。
そして、60 秒以内でこう口に出します。
"まずは StringBuilder.reverse() を使います。入力文字列から新しい StringBuilder を作って、組み込みの reverse メソッドを呼び、最後に String に戻します。時間計算量は O(n)、空間計算量も O(n) です。builder が文字列の可変コピーを保持するためです。実務ではこれを選びます。読みやすく、JDK で検証されており、可変バッファの扱いも任せられるからです。必要であれば、手動ループでも説明できますし、Unicode 文字でどう振る舞うかも説明できます。"
最後の一文が重要です。面接官に聞かれる前に次の論点を提示することで、論点を知っていることが伝わります。コーチングの現場では、この一文を加えた候補者は、追加質問を罠ではなく会話として受けられることが一貫して多いです。
文字列の immutability を、Java を本当に理解している人のように説明する
String をその場で反転できない理由
Java の文字列反転面接で最も多い概念的なミスは、アルゴリズムを間違えることではありません。String を可変バッファのように扱ってしまうことです。候補者は、文字列をその場で書き換えているように見えるコードを書きますが、実際には参照を新しいオブジェクトに再代入しているだけです。Java の String クラスは 設計上 immutable です。String オブジェクトが生成されたあと、その内部の文字配列を変更することはできません。連結、置換、substring など、一見 String を変更しているように見える操作はすべて、新しい String オブジェクトを返します。
つまり、Java で String をインプレースで反転することは、難しいのではなく、String 型では構造的に不可能です。
実際にはこう見えます
例えば次のコードを考えてみます。
変数 `s` は、まったく新しい String オブジェクトを指すようになります。元の `"java"` オブジェクトは、ガベージコレクションされるまで、変更されないままメモリ上に残ります。これを StringBuilder と比べてみましょう。
StringBuilder は内部バッファを直接変更します。反転処理そのものでは新しいオブジェクトは作られません。これが本質的な機械的な違いです。面接でこれを明確に言えると、Java の文法だけでなくメモリモデルまで理解していることが伝わります。
面接向きに聞こえる一言
こう言えば十分です。"Java の String は immutable なので、反転には新しいオブジェクトが必要です。そのため、可変な char[] を内部に持つ StringBuilder が自然な選択になります。"
この一文で、理由、仕組み、結果のすべてをカバーできます。15 語ほどで、Java の文字列反転問題の背後にある暗黙の問いに答えています。
手動ループは、必要になってから見せれば十分です
末尾から先頭へ走査するループは、基礎を見たいときの素直な代替案です
面接官が「組み込みメソッドを使わずにできますか?」と言うことがあります。これは罠ではなく、reverse() が実際に何をしているのか理解しているかを見る、正当な確認です。最も素直な手動実装は、最後のインデックスから先頭へ向かって走査し、各文字を新しい StringBuilder に append する方法です。
これが、Java で文字列を反転する際の説明可能な手動解です。明示的で、重複したオブジェクト生成を避けるために StringBuilder を使っており、ホワイトボードでも追いやすいです。
実際にはこう見えます
入力 `"java"` を考えます。インデックス 3 で `'a'` を読み、append します。インデックス 2 で `'v'` を読み、append します。インデックス 1 で `'a'` を読み、append します。インデックス 0 で `'j'` を読み、append します。結果は `"avaj"` です。これをホワイトボードで声に出して追えば、数式を暗唱するのではなく、見えている動きを説明しているだけなので、機械的に聞こえません。
先頭に足していくテクニックや、文字列連結の繰り返しが罠になる理由
罠のコードはこうです。
これは、`+=` のたびに新しいオブジェクトが割り当てられ、以前の文字列全体がコピーされるため、時間計算量は O(n²) になります。10 文字の文字列では目立ちませんが、1 万文字になると性能が急激に悪化します。手動ループを求める面接官は、この罠を知っていて、引っかかるかどうかを見ています。軽くでもそれを口にすることは、Java の文字列連結の実装レベルの挙動を理解しているサインです。
計算量を飛ばさないでください。面接官が見ているのは判断力です
時間計算量は簡単ですが、空間計算量でごまかす人が多いです
よくある反転方法――StringBuilder、手動ループ、char[] の入れ替え――はいずれも時間計算量は O(n) です。ここは言いやすく、確認もしやすいです。点数を落としやすいのは空間計算量です。候補者は「O(n) です」とだけ言って終わりにしがちですが、面接官はその空間を何が使っているのか、その理由は何かを聞いています。
StringBuilder なら、内部の可変バッファに O(n) の空間が必要です。char[] の入れ替えなら、配列コピーに O(n) の空間が必要です(String は immutable なので、まず char[] に変換する必要があります)。スタックなら、スタック自体に O(n) の空間が必要です。3 つともパターンは同じですが、n 個の文字を保持している具体的な構造を名指しすると、単に計算量記法を唱えているのではなく、メモリを考えていることが伝わります。
実際にはこう見えます
面接でそのまま使える、Java の計算量説明スクリプトは次のとおりです。
- StringBuilder.reverse(): 時間 O(n)、空間 O(n) — 内部の char バッファ。
- StringBuilder を使う手動ループ: 時間 O(n)、空間 O(n) — 理由は同じです。
- char[] の入れ替え: 時間 O(n)、空間 O(n) — 変換先の char 配列。
- スタックベース: 時間 O(n)、空間 O(n) — スタック自体。
面接ではこう言えば十分です。"一般的な方法はどれも時間計算量が O(n) です。空間計算量もすべて O(n) です。StringBuilder のバッファでも、char 配列でも、スタックでも、n 個の文字を入れる場所が必要だからです。"
追加質問で答えが変わる場合
面接官がストリーミング的な方法や最小メモリを求めるなら、答えは変わります。String では真のインプレース反転は不可能ですが、char[] が与えられれば両端から中央に向かって入れ替えることで、追加空間 O(1) を達成できます。「String ではなく char[] を渡してくれれば、追加空間 O(1) でできます」と条件を明言すると、デフォルト解だけでなく問題の境界を理解していることが伝わります。
短いコーチングメモとして覚えておく価値があるのは、`"O(n) です"` だけで終わって構造を名指ししなかった候補者は、必ずといっていいほど追加質問で穴を突かれたということです。バッファや配列を名指しした候補者は、うなずかれて次へ進みました。差は一言でした。
StringBuffer は必要なときだけ触れ、その理由も知っておきましょう
ここでは同期化が不要なので、デフォルトは StringBuilder です
StringBuilder と StringBuffer の違い は、Java の面接トピックの中でも、実際以上に重要そうに見えるものの一つです。StringBuffer はスレッドセーフです。メソッドが synchronized されているため、複数スレッドから呼ばれても状態が壊れません。StringBuilder は synchronized されておらず、その分、単一スレッドの文脈では速いです。
文字列反転の面接問題で複数スレッドが関わることは、ほとんどありません。1 つの文字列を 1 回のメソッド呼び出しで反転しているだけです。この場面で StringBuffer を選ぶのは慎重だからではなく、ルールを、そのルールが適用される場面を理解せずに当てはめているだけです。
実際にはこう見えます
面接官がスレッドセーフティに触れないなら、StringBuilder を使い、StringBuffer については何も言わなくて構いません。もし「なぜ StringBuffer ではなく StringBuilder なのですか?」と聞かれたら、こう答えます。"StringBuffer は synchronized されているため、その分のオーバーヘッドがあります。ここでは不要です。これは単一スレッドの処理なので、StringBuilder が適切です。"
これで答えは終わりです。1 文で、正しく、完了です。コードレビューの場では、最初に StringBuffer を挙げる候補者が、なぜと聞かれたときに後退することがよくありました。クラス名だけ学んで、トレードオフを学んでいなかったからです。そういう候補者にならないでください。
Unicode は、扱われる前にこちらから対処しましょう
char 単位の答えは、絵文字が出た瞬間に破綻します
Java の char 型は 16 ビットのコードユニットです。一般的な文字の多くは 1 つの char に収まりますが、絵文字、多くの東アジア文字、各種記号はそうではありません。1 つの Unicode コードポイントを表すのに 2 つの char が必要で、これをサロゲートペアと呼びます。charAt() や char[] のループで文字単位に反転すると、コードポイントではなくコードユニットを反転することになります。`[high, low]` だったサロゲートペアが `[low, high]` になり、それは有効な文字ではありません。見た目は反転しても、意味的には壊れています。
これは単純な反転で見落とされる失敗モードであり、実際のユーザー入力を扱うアプリケーションで現れる種類の問題です。
実際にはこう見えます
例えば、ひとつの絵文字を含む `"hi😀"` を考えます。Java の内部表現では、その絵文字は 2 つの char としてエンコードされています。ナイーブな char 単位の反転では `[low surrogate][high surrogate]hi` になり、絵文字が不正になります。Unicode を正しく扱う反転では、コードポイント 単位で処理します。
空文字列で試すと空文字列が返ります。問題ありません。1 文字の文字列ではそのまま返ります。問題ありません。絵文字を含む文字列では、反転後も絵文字が先頭に intact のまま残ります。正しい挙動です。これなら IDE 上で 1 分もあれば違いが見えます。
Unicode 委員会に見せるつもりでなく、鋭く聞こえる程度に言えば十分です
Unicode の正規化まで講義する必要はありません。面接での一言はこれです。"基本的な反転は ASCII や多くのラテン文字では問題ありません。ただし、絵文字や Basic Multilingual Plane 外の文字を含む可能性があるなら、char ではなく code point 単位で反復する必要があります。ナイーブな反転ではサロゲートペアが分断されるからです。"
エッジケースを聞かれたらこの一言を使ってください。そうでなければ、付け足しとして 1 文で十分です。「Unicode 安全性が必要なら、絵文字やサロゲートペアを考慮して code point 単位の反転にすべきです。」これで、本当に本番コードを考えたことがある人に聞こえます。
スタックの答えは、最初の一手ではなく予備として使いましょう
スタックが機能するのは、反転が LIFO の言い換えだからです
スタックベースの反転は概念的に美しいです。各文字をスタックに push し、その後 pop していきます。スタックは Last In, First Out なので、最後に push した文字が最初に pop されます。これはまさに反転の動作です。データ構造の選択がアルゴリズムの論理をそのまま表している、よい例です。
ただし、Java の文字列反転面接で最初に出す答えではありません。実際の動作は StringBuilder より遅く、ボイラープレートも増え、面接官がデータ構造の知識を特に試していない限り、分かりやすさも増しません。
実際にはこう見えます
`"java"` を追ってみます。j, a, v, a を push します。pop すると a, v, a, j になります。結果は `"avaj"` です。LIFO 特性が自動的に反転を実現しています。模擬面接では、この方法をうまく使えた候補者は、まず StringBuilder を挙げ、そのうえで「LIFO の性質を示したければ、スタック版も説明できます」と言えた人でした。その言い方をすると、スタックの答えは混乱した第一選択ではなく、深さを示すデモになります。ここで使っている標準的なスタック操作については、Java の Deque ドキュメント を参照してください。
よくある質問
Q: 面接で文字列を反転する最も簡単で正しい Java 解は何ですか?
`new StringBuilder(s).reverse().toString()` です。1 行で、時間 O(n)、空間 O(n)、しかも JDK で検証された実装を使っています。まずこれを答え、その後で求められたら別解を説明しましょう。
Q: String が immutable で、それがここでなぜ重要なのか、どう説明しますか?
String の内部文字配列は final であり、生成後に変更できません。String を変更しているように見える操作はすべて、新しいオブジェクトを返します。つまり、インプレース反転は構造的に不可能で、反転した文字を保持するには StringBuilder のような可変構造が常に必要です。
Q: char[] の入れ替え、StringBuilder、手動ループのうち、最初に挙げるべき Java の方法はどれですか?
StringBuilder です。慣用的で簡潔で、標準ライブラリで直接サポートされています。char[] の入れ替えや手動ループは、面接官が低レベル実装を明示的に求めたときの良い追加回答です。
Q: 面接官に好まれる形で時間計算量と空間計算量をどう説明しますか?
一般的な方法はどれも時間 O(n) だと述べ、その後で O(n) の空間を使う具体的な構造――StringBuilder のバッファ、char 配列、スタック――を名指しします。「O(n) 空間です」とだけ言うのではなく、どの構造がその空間を使うのかを言うことが、面接官が見ているサインです。
Q: この問題では、StringBuilder と StringBuffer のどちらがよいですか?
ほとんどの場合は StringBuilder です。StringBuffer の同期化は、単一スレッドの反転では役に立たないオーバーヘッドを増やすだけです。デフォルトでは StringBuilder を使い、スレッドセーフティが話題になったときだけ StringBuffer に触れれば十分です。
Q: 空文字列や 1 文字の文字列など、どんなエッジケースに触れるべきですか?
簡潔に触れれば十分です。空文字列は空文字列を返し、1 文字の文字列はそのまま返ります。StringBuilder.reverse() は特別な分岐なしで両方を正しく処理します。先回りしてエッジケースを挙げると、境界条件を考えていることが伝わります。
Q: Java の文字列反転は、Unicode や絵文字で壊れることがありますか?
はい。Java の char は 16 ビットのコードユニットです。絵文字や Basic Multilingual Plane 外の文字はサロゲートペア、つまり 1 文字を 2 つの char で表します。ナイーブな char 単位の反転はサロゲートペアを分断し、無効な出力になります。対策は、`s.codePoints()` と `sb.appendCodePoint()` を使って code point 単位で反復することです。
Verve AI で Java の文字列反転コーディング面接を突破する方法
Java の文字列反転面接で最も難しいのはコードを書くことではありません。ライブの圧力の中で説明をしながら、面接官の追加質問に追従することです。これは実演スキルであり、決まったプロンプトではなく、あなたの発言に実際に反応できるシステム相手に繰り返すことでしか上達しません。Verve AI Coding Copilot はまさにそのために作られています。LeetCode、HackerRank、CodeSignal で問題を解いている最中の画面を 読み取り、一般的な問題に対する汎用ヒントではなく、実際に書いた内容に基づく文脈依存の提案を出します。説明の途中で面接官が「絵文字を含む場合はどうしますか?」と方向転換しても、Verve AI Coding Copilot が Unicode の code point アプローチをリアルタイムで促してくれるので、追加質問で不意を突かれません。Secondary Copilot モードは、文脈の切り替えを避けて 1 つの問題に集中し続けられるため、StringBuilder の説明、計算量スクリプト、StringBuffer のトレードオフを同時に頭に置いておく必要がある場面で特に有効です。ここで紹介した 1 分スクリプトを、自分の言葉として自然に言えるまで練習し、そのうえで Verve AI Coding Copilot を使って、実際につまずきやすい追加質問に対してストレステストしてください。
結論
Java の文字列反転面接問題を通過するのに、巧妙なトリックは必要ありません。必要なのは、最初の答えとして StringBuilder.reverse() を選び、なぜそれが妥当かを落ち着いて 30 秒で説明することです。String は immutable なので可変バッファが必要であり、StringBuilder が Java らしい選択だからです。それ以外――手動ループ、スタック、StringBuffer の違い、Unicode のエッジケース――はすべて追加質問であって、最初の一手ではありません。
1 分のスクリプトを暗記してください。immutability の一文を、自然に言えるまで声に出して練習してください。そして Unicode の注意点は手元に置いておきましょう。面接官がエッジケースを深掘りし始めたら、「ナイーブな char 単位の反転ではサロゲートペアが分断される」という一言が、単なるアルゴリズムではなく本番コードを考えていることの証拠になります。
Verve AI
アーカイブ
