日本語ブログ

Javaビット演算面接対策|頻出パターン完全解説

2026年5月10日5 分で読める
Javaビット演算面接対策|頻出パターン完全解説

Javaのビット演算子を面接で使いこなすためのパターン集。偶奇判定、XOR、マスク、シフトの落とし穴まで実例付きで整理。コーディング面接で差がつく要点を今すぐ確認してください。

`&` が何をするかを知っていること自体は問題ではありません。本当の問題は、コーディングラウンドで配列問題を前にして、面接官がプロンプトの奥深くに bit operator java interview のパターンをひっそり埋め込んでいることに気づけないまま固まってしまうことです。ビット操作の問題でつまずく候補者の多くは、すべての演算子を正しく言えます。しかし、再利用可能な少数のパターン — 偶奇判定、マスク、XOR のトリック、有符号シフトの罠 — が形を変えて何度も出てくることを、まだ身体に染み込ませていません。このガイドでは、演算子の豆知識は飛ばして、そうしたパターンをダイレクトに学べるようにします。暗算で再現できる Java コードと、実際に手を動かすドライラン付きです。

ラウンドが理論だけでは済まなくなったとき、なぜビットトリックが重要なのか

落とし穴は構文ではない — パターン認識だ

典型的なコーディングラウンドは、「`^` 演算子は何をしますか?」とは聞きません。代わりに「配列の中で、ほかの要素はすべて 2 回ずつ現れるとき、1 回だけ現れる数を見つけてください」と聞いてきます。問題文は配列問題に見えますが、実際には XOR 問題を隠したものです。ある数をそれ自身と XOR すると 0 になります。ある数を 0 と XOR すると、その数自身が返ります。したがって、配列全体を XOR で畳み込めば、重複は打ち消され、1 回だけの値が残ります。演算子は知っていても、このパターンを見たことがない候補者は、5 分かけてハッシュマップを作ろうとします。パターンを認識できる候補者は、3 行で解きます。

この差 — 構文を知っていることと、パターンを認識できることの差 — こそが、実際の bit operator java interview で問われているものです。演算子は語彙にすぎません。パターンは、それで意味のあることを言うための文法です。

実際にはこう見える

たとえば問題文がこうだとします。「整数が与えられたとき、剰余演算子を使わずに奇数か偶数かを判定してください。」弱い答えは `%` を挙げてから、ぎこちなく話を切り替えます。強い答えはこうです。「これは偶奇判定です。どんな整数でも最下位ビットが偶奇を表します。1 なら奇数、0 なら偶数です。なので数値と 1 を AND して、その結果を見ます。」そのあとでマスクを書き、17 を二進数でドライランし(`10001`)、最後に計算量は O(1) だと述べます。

私が見た模擬面接では、ある候補者が「1 回だけ現れる数を探せ」という問題で、即座に頻度マップを作り始めました。XOR の性質を考えるよう促すと、少し間を置いてから横に `a ^ a = 0` と書き、30 秒もしないうちに解法にたどり着きました。知識はありました。ただ、パターンを呼び出す引き金がなかったのです。このギャップを埋めるのが、このガイドです。

SHRM の技術採用に関する調査 によると、コーディングラウンドでパターンベースの問題が増えているのは、候補者が暗記した解法ではなく、根本原理を理解しているかを見分けやすいからです。

一度演算子を覚えたら、豆知識扱いするのはやめる

AND、OR、XOR、NOT はそれぞれ役割が違う — 面接では全部問われる

Java のビット演算子は、boolean の真理値表ではなく、整数値の個々のビットに対して働きます。この違いは重要です。なぜなら `&` と `&&` は別物だからです。`&&` は短絡評価を行い、boolean を返します。`&` は両辺を評価し、整数を返します。面接官はこの混同をまさに突いてきます。

  • `&`(AND): 両方の入力が 1 のときだけ、そのビットが 1 になります。特定のビットを抽出・判定するときに使います。
  • `|`(OR): 少なくともどちらか一方が 1 なら、そのビットが 1 になります。他のビットを壊さずにビットを立てるときに使います。
  • `^`(XOR): 入力が異なるとき、そのビットが 1 になります。トグルや打ち消しに使います。
  • `~`(NOT): すべてのビットを反転します。二の補数のせいで、これが意外に感じられます。

面接で最も時間を割かれるのは XOR です。なぜなら、XOR は逆演算が可能だからです。`a ^ b ^ b == a` です。この可逆性が「1 回だけ現れる数」を解くパターンを成立させ、XOR スワップも可能にします。

二の補数のせいで、 ~ が最初は妙に見える理由

Java の整数は、32 ビットの符号付き値として二の補数で格納されます。`~` を 5 に適用しても、-5 にはなりません。-6 になります。式は `~n = -(n + 1)` です。ビット単位の NOT を単純な符号反転のように考えている候補者は、ここで驚きます。

二の補数では、負数はすべてのビットを反転して 1 を足すことで表します。5 の二進数表現は `00000000 00000101` です。これを全部反転すると `11111111 11111010` になります。これは二の補数では -5 ではなく -6 です。面接官が「Java で `~5` は何を返しますか?」と聞くのは、よくある質問です。-5 と答えると、メンタルモデルに穴があることがすぐ分かります。

実際にはこう見える

面接前にこれを自分で実行してみる価値は、定義を読むよりずっとあります。`~a` の出力は、素朴な理解を壊す代表例です。`~12` から `-13` が出てくるのを一度見れば、二の補数のルールは頭に残ります。

Java Language Specification では、ビット演算子の意味と二の補数の整数表現が厳密に定義されています。面接官があなたの答えに異議を唱えたときの、最終的な根拠です。

1 ビットを使って、奇数・偶数を素早く判定する

なぜ n & 1 が冗長な書き方より優れているのか

Java のビット操作では、マスクの仕組みが分かれば偶奇判定は非常に簡単です。どんな整数にも最下位ビット(LSB)があります。LSB が 1 なら奇数、0 なら偶数です。`1` の二進数表現は `00000001` です。任意の数値と 1 を AND すると、LSB 以外のビットはすべて 0 になるため、結果は 0 か 1 のどちらかになります。

これは単なる小技ではありません。除算も剰余も不要で、戻り値以外に分岐もない O(1) の処理です。面接では、ただ使うだけでなく、そのマスクの意味を説明できるかどうかが、トリックを覚えただけの候補者と、理解している候補者を分けます。

実際にはこう見える

17 と 24 をドライランしてみます。

  • 17 の二進数: `10001`。`00001` と AND → `00001` → 結果は 1 → 奇数。
  • 24 の二進数: `11000`。`00001` と AND → `00000` → 結果は 0 → 偶数。

面接では、このメソッドをゼロから書けるようにしてください。マスクの意味を述べ、1 つ入力を二進数で追い、計算量を言う。それで答えは完成です。剰余は不要ですし、ビットトリックを使うことに引け目を感じる必要もありません。

パフォーマンスに関する一言だけ。単発の呼び出しなら、現代の JVM では `n & 1` が `n % 2` より実質的に速いとは限りません。このパターンを知る価値は、マイクロ最適化ではなく、パターン認識にあります。速度を過剰に主張しないでください。面接官に突っ込まれることがあります。

マスクを迷わず扱って、ビットを立てる・消す・反転する

本質は演算子ではなく、マスクだ

ビットマスキングの面接問題は、ほとんどが 3 つの操作に帰着します。ビットを 1 にする、ビットを 0 にする、ビットを反転する、です。使う演算子はそれぞれ違いますが、マスクの作り方は毎回同じです。`1 << i` で 1 を位置 `i` に移動させ、ちょうど 1 ビットだけ立ったマスクを作ります。

  • ビット i を立てる: `n | (1 << i)` — OR は現在の状態に関係なく、そのビットを 1 にします。
  • ビット i を消す: `n & ~(1 << i)` — NOT でマスクを反転し、ビット i を 0 にしたうえで、AND で他のビットを保持します。
  • ビット i を反転する: `n ^ (1 << i)` — XOR はビット i だけを反転します。

よくあるミスは、ビット位置とマスク値を混同することです。位置 2 ならマスクは `1 << 2 = 4` であって、`2` ではありません。ビット 2 を消したいのに `n & ~2` と書くと、ビット 1 を消してしまいます。これは静かに潜むバグで、面接官はそこを見ています。

実際にはこう見える

`n = 13`(二進数 `1101`)とビット位置 2 を考えます。

  • ビット 2 を立てる: `13 | (1 << 2)` → `1101 | 0100` → `1101` → 13(ビット 2 はすでに立っている)
  • ビット 2 を消す: `13 & ~(1 << 2)` → `1101 & 1011` → `1001` → 9
  • ビット 2 を反転する: `13 ^ (1 << 2)` → `1101 ^ 0100` → `1001` → 9

このドライランを示したあと、ほぼ必ず次に来る質問は「なぜ set には `|` を使って、`^` ではだめなのか?」です。XOR は反転だからです。すでにビットが 1 なら、XOR はそれを 0 にします。OR は常に 1 にします。この違いが答えです。

演算子の優先順位で、候補者は静かに点を落とす

`1 << i & n` のような混在式は罠です。Java では `&` の優先順位が `<<` より低いので、これは `1 << (i & n)` と評価されます。意図したものではありません。必ず `(1 << i) & n` のように括弧を付けてください。

Java の公式チュートリアルにある演算子の優先順位表 は、ブックマークしておくべき参照先です。`(1 << i)` と明示的に書くのは、単にコードがきれいになるだけではありません。優先順位を理解していて、それに頼り切っていないことを面接官に示せます。

XOR スワップを小技として語るのをやめ、なぜ動くのかを説明する

XOR スワップが有名なのは、賢く見えるからであって、常に有用だからではない

XOR スワップは、Java のシフト演算とビット操作の話題ではほぼ必ず出てきますが、多くの候補者はこれを見せびらかす小技として説明します。本当に重要なのは可逆性です。XOR は自分自身が逆演算です。`a ^ b ^ b == a` です。この性質がスワップを可能にし、同じ性質が「1 回だけ現れる数」を解くことも可能にします。可逆性を理解すると、この小技がより広いパターンにつながります。

本番のコードでは、XOR スワップはほとんど使いません。テンポラリ変数のほうが分かりやすく、JIT コンパイラも効率よく処理します。XOR スワップを聞く面接官が見ているのは、3 行を暗記しているかではなく、なぜ動くのかを理解しているかどうかです。

実際にはこう見える

各ステップを追ってください。1 行目のあと、`a` は 2 つの値の XOR を持ちます。2 行目で、もう一度 XOR することで元の `a` が `b` に戻ります。3 行目で、元の `b` が `a` に戻ります。XOR が可逆だからこそ成り立ちます。

1 つだけ壊れるケースがあります。`a` と `b` が同じ変数、つまり同じ値ではなく同じメモリアドレスを指している場合です。そのときは 3 回とも XOR の結果が 0 になり、値を完全に失います。面接ではこれも述べてください。単なる手順ではなく、仕組みを理解していることを示せます。

GeeksforGeeks のアルゴリズム参考資料 でも XOR スワップは定番の面接パターンとして紹介されていますが、実務では実用性に乏しいと注意されています。まさにその整理が正しいです。

面接官が本当に期待する形で、セットビット数を数える

素朴なループで十分 — ただし、もっと良くできると聞かれるまでは

ビット数を数えるビット操作の問題は、まず素朴な方法から始まり、そのあと発展させる流れがほとんどです。素朴なループは右シフトしながら毎回 LSB をチェックし、O(ビット数) で動きます。Java の `int` では O(32) なので実質 O(1) ですが、面接官に「もっと良くできる?」と言われると、少し物足りなく感じます。

より良い方法が Brian Kernighan のアルゴリズムです。`n & (n - 1)` を使うと、最下位の立っているビットが 1 回の操作で消えます。32 個のビット位置をすべてなめるのではなく、立っているビットだけを繰り返し処理します。セットビットが k 個ある数なら、ループはちょうど k 回回ります。

実際にはこう見える

`n = 29`、二進数 `11101` を考えます。立っているビットは 4 個です。

ドライラン:

  • `29 & 28` → `11101 & 11100` → `11100`(28)、count = 1
  • `28 & 27` → `11100 & 11011` → `11000`(24)、count = 2
  • `24 & 23` → `11000 & 10111` → `10000`(16)、count = 3
  • `16 & 15` → `10000 & 01111` → `00000`(0)、count = 4

ループ終了。4 個のセットビットに対して 4 回の反復です。

強い候補者が口に出して言うこと

不変条件を言語化してください。「`n & (n - 1)` は、1 を 1 つ引くと末尾の 0 が反転し、最下位の 1 が消えるので、常に最下位のセットビットだけを 1 つ消します。」計算量も述べます。「O(k) で、k はセットビット数です。Java の int では最大でも O(32) です。」組み込み API にも触れます。「Java には `Integer.bitCount(n)` もあります。名前を挙げる価値はありますが、面接官はたいてい手書き実装を見たがります。」こうした説明が、答えを知っているだけの候補者と、説明できる候補者を分けます。

Java の Integer クラスのドキュメント には `Integer.bitCount()` が載っています。面接官が標準ライブラリの代替案を聞いてきたときに便利です。

ビットマスクをフラグや権限として扱うべき理由、それがまさに正体だからだ

マスクは「これらのオプションがオンです」をコンパクトに表すだけ

フラグや権限を扱うビットマスキングの問題は、1 つの整数に状態を詰め込む発想を理解しているかを試します。Unix のファイル権限はその典型です。読み取り、書き込み、実行を 3 ビットに格納します。これは小技ではなく、システムコード、組み込み、メモリや通信帯域が重要な場所で実際に使われる設計パターンです。

面接官がこのパターンを好むのは、候補者がビットを単なる算術ではなく、意味のある状態として考えられるかを見たいからです。

実際にはこう見える

各定数は、ちょうど 1 ビットだけ立ったマスクです。これらを OR で組み合わせると権限セットになります。AND での判定は、特定のビットをチェックします。`& ~mask` で消すと、そのビットだけが落ちます。これは第 4 節で出てきた set/clear/toggle のパターンを、実世界のドメインに当てはめたものです。面接でこのつながりに気づけると、「強いシグナル」と見なされます。

シフトが役立つ場面と、Java が静かに意味を変えてしまう場面を見分ける

左シフトは通常「2 倍すること」だが、オーバーフローには注意

Java のシフト演算子では、`n << k` は `n` を `2^k` 倍するのと同じです。ただし、その結果が符号付き 32 ビット範囲に収まる場合に限ります。`8 << 1` は 16 です。`1 << 30` は 1,073,741,824 です。`1 << 31` は符号ビットを立てるため、-2,147,483,648 になります。「左シフトは 2 倍」と覚えるのは正しいのですが、値が符号付きオーバーフローの領域に入ると崩れます。エッジケースを気にする面接官は、そこを突いてきます。

Java には右シフトが 2 種類あり、負数ではとても重要になる

Java の技術面接で最もよく問われるシフトの違いです。

  • `>>`(算術右シフト): 符号ビットを保持します。負数を右にシフトすると、空いた上位ビットは 1 で埋まります。`-8 >> 1` は -4 です。
  • `>>>`(論理右シフト): 符号に関係なく、常に 0 で埋めます。`-8 >>> 1` は 2,147,483,644 で、大きな正数になります。符号ビットが 0 になるからです。

`>>` しか知らない候補者は、負数が出た瞬間に引っかかります。両方知っている候補者は、`>>>` がなぜ存在するのかも説明できます。符号付き型での unsigned 的な操作、ハッシュテーブル実装、特定のビットパッキング用途などです。

実際にはこう見える

`-8 >> 1` の二進数ドライランを見てみます。`-8` の二の補数表現は `11111111 11111111 11111111 11111000` です。1 ビット右に算術シフトすると、`11111111 11111111 11111111 11111100` になり、-4 です。次に `>>>` では、1 ビット右にシフトして上位を 0 で埋めるので、`01111111 11111111 11111111 11111100` となり、大きな正数になります。面接官は、まさにこの出力を説明してほしいのです。

Java Language Specification のシフト演算子に関する節 が決定版です。`>>` は算術シフト、`>>>` は論理シフトだと明記されています。面接官に仕様レベルの根拠を求められたときに使う説明です。

FAQ

Q: Java のビット演算子には何があり、論理演算子とどう違いますか?

Java のビット演算子 — `&`、`|`、`^`、`~`、`<<`、`>>`、`>>>` — は整数値の個々のビットに対して働き、両方のオペランドを必ず評価します。論理演算子 `&&` と `||` は boolean 値に対して働き、短絡評価を行います。`&&` は左辺が false なら右辺を評価せず、`||` は左辺が true なら右辺を評価しません。`&&` のつもりで `&` を使うと、左辺だけで結果が決まっても右辺が常に評価されるため、NullPointerException を引き起こすことがあります。

Q: Java で `&`、`|`、`^`、`~` は二進数値に対してどう動きますか?

AND (`&`) は、両方のビットが 1 のところだけ 1 を返します。特定のビットの抽出に便利です。OR (`|`) は、少なくともどちらかのビットが 1 のところで 1 を返します。ビットを立てるのに便利です。XOR (`^`) は、ビットが異なるところで 1 を返します。トグルや打ち消しに便利です。NOT (`~`) はすべてのビットを反転し、Java は二の補数なので `~n` は `-n` ではなく `-(n + 1)` になります。同じ 2 つの入力に対して 4 つ全部を一度ずつ試すのが、違いを身につける最短ルートです。

Q: Java で `>>` と `>>>` を使うと、負数はどうなりますか?

`>>` は算術右シフトです。空いた位置に符号ビットをコピーするので、負数は負数のままです。`-8 >> 1` は `-4` です。`>>>` は論理右シフトです。常に 0 で埋めるので、負数は大きな正整数になります。`-8 >>> 1` は 2,147,483,644 になります。この違いが重要なのは負数だけです。非負数では、両者の結果は同じです。

Q: 左シフト・右シフトは 2 の冪での乗算・除算とどう関係し、どこで破綻しますか?

`n << k` は `n * 2^k` に相当し、`n >> k` は `n / 2^k` に相当します(負数では負の無限大方向に丸められます)。このモデルは 2 つの場面で崩れます。左シフトは結果が `Integer.MAX_VALUE` を超えると符号付きオーバーフローを起こすこと、そして負数の右シフトは 0 方向ではなく負の無限大方向に丸められることです。面接前に、この 2 つのエッジケースを必ず押さえてください。

Q: 奇数・偶数判定やビット反転など、Java でよく出るビット演算の面接問題は何ですか?

繰り返し出るパターンは、`n & 1` を使った偶奇判定、`1 << i` をマスクにした set/clear/toggle、Brian Kernighan の `n & (n - 1)` ループによるセットビット数の計算、XOR を使った 1 回だけ現れる数の発見、そして負数に対する `>>` と `>>>` の違いです。Java のコーディングラウンドで出るビット操作問題の大半は、この 5 つでカバーできます。それぞれを、ドライラン付きでゼロから再構成できるなら、十分に準備できています。

Q: Java でビットマスクを使って特定のビットを立てる・消す・判定するにはどうしますか?

位置 `i` を狙うマスクは `1 << i` で作ります。立てる: `n | (1 << i)`。消す: `n & ~(1 << i)`。反転する: `n ^ (1 << i)`。判定する: `(n & (1 << i)) != 0`。`(1 << i)` は必ず明示的に括弧で囲んでください。Java の優先順位では `1 << i & n` は `1 << (i & n)` と解釈され、ほとんどの場合、意図とは違います。

Q: 面接で候補者がビット演算子を説明するときによくあるミスは何ですか?

繰り返し出るミスは 3 つです。1 つ目は、`~n` と `-n` を混同すること。二の補数では `~n = -(n+1)` です。2 つ目は、シフト式に括弧を付け忘れ、静かな優先順位バグを入れること。3 つ目は、`>>` と `>>>` を同じものとして扱うこと。正の数では同じですが、負数ではまったく違う結果になります。4 つ目のやや軽いミスは、演算子名だけを言って、マスクやビットのドライランを説明しないことです。その場合、面接官には本当に仕組みを理解しているのかが伝わりません。

Verve AI が、ビット演算子を使うコーディング面接の突破をどう助けるか

ビット操作のコーディングラウンドで最も難しいのはアルゴリズムそのものではありません。コードを書きながら、その場で思考を言語化することです。その二重の負荷で準備が崩れやすくなります。そしてまさにそのギャップを埋めるために、Verve AI Coding Copilot は作られています。

Verve AI Coding Copilot は、画面をリアルタイムで読み取り、LeetCode、HackerRank、CodeSignal、さらには本番の技術面接まで横断して、一般的なプロンプトではなく、実際に画面に映っている内容に反応します。「set bits を数える」問題で素朴なループを書いている途中でも、Verve AI Coding Copilot は面接官に言われる前に Brian Kernighan の最適化を提示できます。符号付きシフトのエッジケースを追っていて理解が揺らいだときも、目の前のコードに基づいて その場で回答候補を提案します。Secondary Copilot モードは、1 つの問題への集中を持続させるので、タブを切り替えたり文脈を失ったりすることがありません。同じセッションでビットマスクの問題が 5 回の追加質問に発展するような場面では、これが重要です。そして、その間もツールは目立たないまま動くので、面接官に見えるのは、問題を解いているあなた自身だけです。

結論

演算子そのものは難しくありません。`&`、`|`、`^`、`~`、`<<`、`>>`、`>>>` — これらは 1 日あれば覚えられます。時間がかかり、コーディングラウンドでの出来を本当に左右するのはパターン認識です。「1 回だけ現れる数」を見てすぐ XOR を思い出せること、マスク問題を見て、そのマスクにどの演算子を使うか考える前に `1 << i` を思い浮かべられることです。

次のコーディングラウンドの前に、必ずゼロから次の 3 つを練習してください。1 つは、手で二進数を追いながら行う偶奇判定。1 つは、明示的な括弧付きで特定の整数に対して set/clear/toggle を行う手順。1 つは、負数に対して `>>` と `>>>` を比較する符号付きシフト。Java を書き、ビットを追い、計算量を声に出して言う。それを 3 回やれば、パターンは「覚えているもの」ではなく「自動的に手が伸びるもの」になります。ライブのプレッシャーに耐える準備とは、結局そういうことです。

VA

Verve AI

アーカイブ