NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

注目のタグ

    新人の部内研修でJava100本ノックのレビュアーをやった話 〜 AI時代に、なぜあえてJava100本ノックを回すのか 〜

    本記事は  【Advent Calendar 2025】  24日目②の記事です。
    🌟🎄  24日目①  ▶▶ 本記事 ▶▶  25日目①  🎅🎁

    はじめに

    はじめまして、最近はAI支援(Claude Code等)を前提に開発することが増えてきた 松本和樹 です。

    今年、新人部内研修で「Java100本ノック」のレビュアーを担当しました。 AIで実装そのものは加速する一方で、運用や前提合わせ、文脈共有は自動で良くなりません。だからこそ「レビュー付きでPRを回す」設計には今も価値がある、というのがこの記事の結論です。

    研修の中でうまくいったことと反省点が想像以上に出たので、備忘も兼ねてまとめます。

    経緯

    所属部署では、新人研修としてここ数年「Java100本ノック」を継続しています。 ただ、今年からこれまで主にレビューを担っていた熟練メンバーがほぼいなくなり、「今年は誰がどう見る?」を決める必要が出てきました。

    そこで、去年の受講者を少しだけ見ていた流れもあって、今年は私がレビュアー役をやることになりました。 ついでに、過去に熟練者がどんな観点でレビューしていたのかを把握したかった、というのも理由のひとつになります。

    そもそもJava100本ノックとはなにか

    Java100本ノックは、株式会社ジャストシステムが GitHub 上で公開している Java の問題集で、目的として「運用環境で安定稼働でき、保守性・拡張性に優れたコードをより多く生産できるようになること」を掲げています。

    github.com

    特徴として、序盤から JDK 標準コマンドを使う作業(コンパイル・jar 作成など) が入っている点があります。 IDE に慣れ切った状態だと見えにくい “裏側の手順” を、一度ちゃんと踏めるのがとても良い教材だと言えます。

    一方で、この教材自体は公開から年数が経っているという問題点もあります。 当時は一般的だった前提(Java バージョン、周辺ツール、定番ライブラリ、作法など)がそのまま残っているので、解答例をそのまま手本にすると いまの推奨とズレる箇所が混ざってしまいます

    もちろん全部が悪いわけではないのですが、「そのまま真似る前提」で回すには少し危なく、こちら側で前提を補正しながら運用する必要があり、そこを指摘するのもレビュアーの責務となります。

    目的の設定

    「Java100本ノック」と聞くと、目的は色々思い浮かびます。

    • Java 言語仕様の理解
    • オブジェクト指向の理解
    • Spring 等のフレームワーク理解
    • Java 17 以降のモダンな書き方への慣れ

    もちろんこれらも目的としてやるのが望ましいのですが、今回の研修で私が特に重視したのは次の2つになります。

    1. Git の扱いを通して、チーム開発の進め方を覚えること (PR / レビュー / 差分の読み方 / コミット粒度 / 履歴の残し方)
    2. 「読みやすい/直しやすい」を前提に書く癖をつけ、保守性を理解すること (命名 / 責務分離 / 例外設計 / テスト / 変更容易性)

    理由はシンプルで、Javaの知識そのものは今後AIを含む支援で補える場面が増える一方、チーム開発の作法保守性の感覚 は実コードの往復でしか身につきにくいからです。

    また、学生時代は個人開発や小規模で完結しやすく、「保守する前提」で設計・実装する経験が薄いことも多いものです。 業務だとそこが前提になるので、本研修では 「チーム開発の作法」と「保守性の感覚」 の2点を主目的として設定しました。

    研修設定

    期間

    他の研修と並行して2ヶ月実施しました。

    体制

    研修の体制は以下。

    • 新人1人に対して、インストラクター1人が 1次レビュー
    • 全員のPRに対して私が 2次レビュー(最終的な品質と観点の統一)

    環境

    環境は基本的に配属先に寄せました。

    • IDE: IntelliJ IDEA(ただし注意点あり。後述)
    • Java: Amazon Corretto JDK 21
    • ビルド: Maven

    進め方

    • Git-flow(develop起点のfeature運用)で進める

      • 10問ごとに feature/* ブランチを作成
      • 10問が終わったら MR(PR)を作成してレビューに回す
      • レビュー対応が終わったら developにマージして次の feature/* に進む
    • レビューは2段階(観点の統一のため)

      • 1次レビュー:インストラクター
      • 2次レビュー:松本

    実施しない問題

    No. 実施しない理由
    4 Java 自体のアップデート等に関する問題のため
    91~93 アプリケーション開発(アプリケーション開発研修と内容重複のため)
    97~99 今後利用する可能性の低いフレームワーク(PlayFramework)の問題のため
    100 アプリケーション開発(アプリケーション開発研修と内容重複のため)

    ディレクトリ構成

    プロジェクトはシンプルな構成に寄せました。(XXには受講者名を入れています)

    java-100-knock_XX(project root)
    ├── Answer001/
    ├── Answer002/
    …
    └─Answer100/

    ルールとして以下を設定しています。

    • 余計なファイルは入れない(解答は自身の解答ソースのみ)
    • どの形式でもいいので問題文は入れる

    README

    今まで上記で記述していたルールをプロジェクト直下のREADME.mdに入れることで、ルールの周知を行いました。

    上はブログ向けに要約した内容で、実際に配布・運用していた原文が以下です。

    # Java100本ノック_{受講者名}
    
    ### 目的
    - Java 言語で基礎的なコーディングを行い、標準的なコーディング作法を身につける
    - ソースコード管理ツール(git)や IDE の使い方を身につける
    - ソフトウェアがどのように実行されているのかを身につける
    - 第三者のレビューをうけ、指摘修正するまでの一連のフローを理解する
    
    ### 目標
    - Java100 本ノックの課題のうち実施する問題を全て実施する
    - 一般的な Java コーディング規約を理解し、規約に則った記述ができるようになる
    - git を使用したバージョン管理を理解し、複数人での共同作業を行うことができる
    - レビューの指摘内容を理解し、指摘内容に従った適切な修正を行うことができるようになる。また同じ指摘を受けないようになる。
    
    ### 実施内容
    - [Java100 本ノック](https://github.com/JustSystems/java-100practices)を行う
      - GitLabの自身のリポジトリ上で作業ブランチを作成した上で、マージリクエストを行い、インストラクターにマージしてもらう。
      - 一部の問題は実施しない
      - インストラクター と 松本 にコードレビューをうける
          - 1次レビュー:インストラクター
          - 2次レビュー:松本
    - 利用する Java のバージョンは JDK21とする。
    - 利用するビルドツールはMavenとする。
    - gitに慣れてもらうため、10問ずつでfeatureブランチを切って作業し、完了したらマージリクエストを作成するようにしてください。
    
    | No.   | 実施しない理由 | 
    | :---- | :--------------- | 
    | 4     | Java 自体のアップデート等に関する問題のため| 
    | 91~93 | アプリケーション開発(アプリケーション開発研修と内容重複のため) | 
    | 97~99 | 今後利用する可能性の低いフレームワーク(PlayFramework)の問題のため | 
    | 100   | アプリケーション開発(アプリケーション開発研修と内容重複のため) | 
    
    ### プロジェクト構成
    java-100-knock_XX(project root)
    ├── Answer001/
    ├── Answer002/
    …
    └─Answer100/  
    
    * 余計なファイルは入れない。(解答は自身の解答ソースのみを入れる)
    * どの形式でもいいので問題文は入れる。

    実施ノウハウ

    全体的に、指摘する前に説明しておいた方がいい点

    レビューで指摘する前に、最初に前提をそろえておくと後半がラクになります。

    • ブランチ運用(Git-flow / GitHub Flow)の説明

      • この研修では Git-flow を採用したが、GitHub Flowでもよい。大事なのは「運用ルールがある状態でPRを回す」経験である。
    • ビルドツール(Mavenなど)の説明

      • 後半から必要になるので、早めに「何をしているか」だけでも触れると詰まりにくい。意外とどの書籍もこの知識は前提とされていて説明をあまりしてくれない。
    • フォーマッタを必ずかけさせる(理由もセットで)

      • “揃える” はチーム開発の基本。
    • 見ればわかるコメントは禁止(コメントはWhyNot)

      • コードを読めば分かることはコードに寄せる。コメントは意図・背景を書く。
    • 成果物(classファイル等)をコミットしない(.gitignoreの徹底)

      • 2次生成物は差分がノイズになってレビュー効率を落とし、環境差で中身も変わる。リポジトリは「ソースと設定」を正として扱うため、.gitignore で遮断する。
    • 認証情報をpushしない注意喚起 + git-secret導入

      • 「事故らない」ための習慣づけ。

    新人だけでは解決しづらい“罠”になりがちな問題

    詰まりポイントが「Javaの理解」ではなく「環境差分」や「時代の差分」になりやすいです。 以下の問題はインストラクターが伴走することをおすすめします。それら以外は基本的にJava初心者でも解けるようになっています。

    • 009:その他のコマンド(2)

      • 解答例にある native2ascii は JDK 9 で削除済み。現行バージョンに沿った手順が必要。
    • 019:JNI

      • gcc を利用するためにツール導入とパス設定が必要。
    • 059:コアAPI:java.net(1)

    • 079:複合(19)
    • 085:ライブラリ:OkHttp

      • 認証プロキシ配下だと追加対応が必要。
    • 080:Java EE:javax.servlet

      • javax.* のため Tomcat 10 以降だとそのまま動かない。
      • さらに IntelliJ IDEA Community だと Smart Tomcat 等のプラグインが必要になるケースがある。
    • 082:ライブラリ:JPA, Ebean

      • DBが必要。Docker で環境用意するとスムーズ。

    失敗と学び

    研修の主導権を握らなかった

    これが一番の失敗でした。 年次が上のインストラクターが旗を振るのが自然だし、私もやりすぎるのは違うかと思い、説明やタスク確認は任せてしまいました。

    結果として、最初の「前提のすり合わせ」が不足し、小さなズレが連鎖して運営コストが膨らみました。 過去に同じ研修を回した経験がある以上、本来は私が地固めをして、進行をスムーズにするべきだったと反省しています。

    • 利用しているJavaのバージョンが違った

      • 途中で Java 24 を使っているのが発覚。最初に環境が「揃っているか」を確認すべきだった。
    • ディレクトリ構成がぐちゃぐちゃ

      • 見る側の負荷が跳ねる。ネストを浅くする方針、IDEにどう紐づけるかも含めて最初に決めたかった。
    • 期限感がなく、ぐだぐだになった

      • 最後は写経じみたペアプロをせざるを得なくなり、自分の負荷も上がった。
    • リモートリポジトリがPJ依存のGitLabになってしまった

      • 有識者に見てもらいにくいし、知見共有の範囲が狭くなる。研修は“見せられる場所”に置いた方がよい。

    ペアプロがほぼ写経になってしまった

    後半は時間がなく、なるだけ公式を見せながら説明はしたが、「新人が考えるターン」が薄くなってしまいました。 答えを教えるより、考えさせる時間を先に確保するべきでした。

    レビューしすぎた

    熟練レビュアーがいなくなった穴を埋めようとして張り切りすぎました。 1PRで28指摘はさすがに多い。新人には申し訳なかった。 「今週はこれだけ直せばOK」という優先順位(Must / Should / Could)を明確にするべきでした。

    不要な問題(JNIなど)を研修対象から弾かなかった

    Java100本ノックには、現場ではあまり使わない(または環境依存が強い)問題もあります。 今年はそれを残してしまいました。

    ただ、残したのには理由。。。というより意図があります。 私が新卒のころ、このJNIで盛大に詰まったことがあります。 javah を叩いて「そんなコマンドはない」と言われ、先に進めなくなり途方にくれてました。
    実際は javah は JDK 10 で削除され、代わりに javac -h <dir> が正解でした。(しかもこれは JDK 8 時点で javac に入っている)。 docs.oracle.com

    このとき刺さったのが「困ったときは公式(一次情報)を見るのが結局いちばん早い」ということでした。 検索では欲しい情報が出ない中、公式ドキュメントに“答えそのもの”が普通に書いてあって、公式の重要性を体で覚えた記憶があります。

    なので新人にも「まず公式を見る」を一回は体で覚えてほしい、という狙いはあったのですが。。。

    今はAIに聞けば大体即答が返ってきます。なので「公式を読んで辿り着いた」体験がこの時代では発生しにくいですね。

    AIくんには、その体験を(あとメモリも)返してほしい。

    だからこそ、現場でほぼ使わない問題は外してよい、という結論になりました。

    今後Java100本ノックの問題で個人的に改善していきたいこと

    • Java8前提の作りなので、モダン系の問題が少ない

      • Optional など、なんとなくで使われがちなところは補強したい。
    • テスト実装系の問題が少ない(ほぼ1つ)

      • 現場ではテストを書くことが多いので、問題を追加したい。
    • 現場で使うフレームワーク系の問題が少ない

      • Spring Security など、実務に寄った題材が欲しい。

    現場で利用されていない問題、時代に合っていない問題の代わりに上記3つを中心に問題を追加していきたいところ。

    まとめ

    今年のJava100本ノックは、教材としての良さはそのままに、「年数が経った教材を現代の前提で回す難しさ」も強く感じた研修でした。解答例や環境前提にズレがあり、こちらが補正しながら回す場面も多かったです。

    ただその一方で、新人が「Javaが書ける」だけでなく、「チームで開発できる」を早い段階で体得できるようにはできたかなと思います。 PRを回し、差分で会話し、「読みやすい/直しやすい」を前提に整える練習には今も価値があると考えています。

    なお、今年の新人3人はレビューの打ち返しも含めて、最終的には全員完了までやり切ってくれました。正直、最後まで走り切るのは簡単ではないはずなので、率直に言って強いと思いました。

    来年は今年の反省をちゃんと仕組みに落としていきたいところでしたが、私は部署異動してしまったので、今後は後輩が現代の前提に合わせてブラッシュアップしてくれることを願っています。

    執筆者 : 松本和樹 バックエンドエンジニア/フロントエンドエンジニア。時々インフラエンジニア。学生の時のあだ名はゴリラ