Java11をインストールしてください。
IDEを使う場合は、gradle projectをインポートしてください。また、lombokを使用していますので、お使いのIDEでlombokが使えるように設定してください。
gradleでbootRunタスクを実行してください。http://localhost:8080 でアクセスできます。 IDEを使って実行しても構いません。
SkillCheckResource.javaで定義されているデータについて、全件取得する、または条件を指定して絞り込めるAPIを持ったサーバーアプリケーションです。
Q1〜Q4の回答はREADME.mdに記載し、Q5はプログラムを修正、Q6、Q7は新規にクラスを作成し、別途申し上げる方法で回答してください。
Q1: 本アプリケーションで定義されているAPIのパス、パラメーター名と型を記載してください。
A1:
※ A1〜A4 は Q5〜Q7 の実装前(元のソース)の状態についての回答です。実装後の最終的なAPI仕様は末尾の「Q5〜Q7 実装後のAPI仕様」を参照してください。
| 項目 | 内容 |
|---|---|
| パス | /skillCheck |
| HTTPメソッド | GET |
| レスポンス形式 | application/json(SkillCheckResource の配列) |
| パラメーター名 | 型 | 必須 | 説明 |
|---|---|---|---|
name |
String | 任意 | 名称の部分一致(String.contains) |
age |
Integer | 任意 | 指定値以上の年齢(age >= 指定値) |
いずれも Optional で受け取っているため未指定可。未指定の場合はその条件を適用しない(両方未指定なら全件取得)。
なお hasSkill は SkillCheckResourceCriteria にフィールドとしては存在するが、SkillCheckController の @RequestParam には定義されていないため、現状はAPIパラメーターとしては機能しない(Q4参照)。
Q2: Q1のAPIによりデータを取得した場合のレスポンス(一例)を記載してください。
A2:
GET /skillCheck(パラメーター未指定・全件取得)のレスポンス:
[
{
"name": "taro yamada",
"age": 28,
"hasSkill": true,
"skills": [
{ "id": 1, "name": "Java" },
{ "id": 2, "name": "Kotlin" }
]
},
{
"name": "shiori yamada",
"age": 24,
"hasSkill": true,
"skills": [
{ "id": 3, "name": "JavaScript" },
{ "id": 4, "name": "TypeScript" }
]
},
{
"name": "sho yamada",
"age": 38,
"hasSkill": false,
"skills": []
},
{
"name": "kazumasa yamada",
"age": 44,
"hasSkill": false,
"skills": []
},
{
"name": "yasufumi yamada",
"age": 35,
"hasSkill": true,
"skills": [
{ "id": 1, "name": "Java" },
{ "id": 4, "name": "TypeScript" }
]
}
]絞り込みを行う例として GET /skillCheck?name=taro&age=20 は以下を返す。
[
{
"name": "taro yamada",
"age": 28,
"hasSkill": true,
"skills": [
{ "id": 1, "name": "Java" },
{ "id": 2, "name": "Kotlin" }
]
}
]Q3: 本アプリケーションで例外が発生するパターンのAPIのパス、パラメーター名と値を記載してください。
A3:
| パス | パラメーター名 | 値 |
|---|---|---|
/skillCheck |
age |
90 以上の整数(例: 90, 91) |
SkillCheckService の判定は「name と age の両方が指定されている場合」「age のみ指定されている場合」「name のみ指定されている場合」の順に分岐しており、上限チェック(90歳以上)は age のみが指定された分岐にしか存在しない。
そのため GET /skillCheck?age=90 は RuntimeException("90歳以上は検索対象外です") となり HTTP 500 が返る。
{
"timestamp": "2026-08-27T04:52:27.907+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/skillCheck"
}一方 GET /skillCheck?name=taro&age=90 は2条件指定の分岐に入り上限チェックを通らないため、例外は発生せず HTTP 200 で空配列 [] が返る。
name に空文字を渡した GET /skillCheck?name=&age=90 も同様で、name が null ではなく空文字として扱われるため2条件分岐に入り、例外は発生しない。
| パス | パラメーター名 | 値 |
|---|---|---|
/skillCheck |
age |
整数に変換できない文字列(例: abc, 28.5) |
Optional<Integer> へのバインドに失敗し MethodArgumentTypeMismatchException が発生、HTTP 400 が返る。
{
"timestamp": "2026-08-27T04:52:28.067+00:00",
"status": 400,
"error": "Bad Request",
"path": "/skillCheck"
}なお GET /skillCheck?age=(値が空)は空文字が null に変換され Optional.empty() となるため、エラーにはならず全件取得となる。
Q4: Q1のAPIでhasSkill=trueを指定した際にどういうレスポンスになるか記載してください。
A4:
hasSkill は SkillCheckController.search の引数に @RequestParam として定義されていない。
Spring MVC はハンドラーメソッドの引数に定義されていないクエリパラメーターを単に無視する(未知のパラメーターに対するエラーは発生しない)ため、hasSkill=true は検索条件として一切使われない。
結果として GET /skillCheck?hasSkill=true は パラメーターを何も付けない GET /skillCheck と同じレスポンス(hasSkill が false の sho yamada / kazumasa yamada を含む全5件)になる。
SkillCheckResourceCriteria には hasSkill フィールド自体は存在するものの、Controller から値が渡されないため常に boolean の初期値 false のままであり、さらに SkillCheckService の Predicate が hasSkill を参照していないため、いずれにせよ絞り込みには影響しない。
Q5: Q1のAPIで、SkillCheckResource.hasSKillの値を条件として検索できるように、パラメーター(名称: hasSkill, 型: Boolean)を追加してください。その際、SkillCheckService.java内のコメントに記載された条件を維持するようにしてください。
Q6: Q1のAPIに、複数のキー(年齢・名前など)でソートできる機能を追加してください。 どのようなパラメーター設計・受け取り方・バリデーションにするかも含めて、ControllerクラスとServiceクラスを修正してください。
【要件】
- Q1のAPIに、複数のソート条件を指定できる機能を追加すること。
- パラメーター設計・受け取り方・バリデーションは自分で考えて実装すること。形式は自由に設計してよい。
- 指定可能なキーは name, age とすること。不正な値の場合はRuntimeExceptionを発生させること。
- Comparatorの連結やStream APIの活用が望ましい。
- SkillCheckServiceで複数キーによるソート処理を実装し、SkillCheckControllerから呼び出すこと。
- 必要に応じてenumやバリデーション用クラスを作成してもよい。
Q7: 以下の要件を満たすように、ControllerクラスとServiceクラスを新規に作成してください。 すでに実装されているSkillCheckControllerクラスとSkillCheckServiceクラスを参考にして構いません。
【要件】
- SkillCategoryの一覧を取得するAPI(GET /skillCategories)を実装すること。
- Serviceクラスには、SkillCategoryの一覧取得のロジックを実装すること。
- SkillCategoryは「id(Long型)」「name(String型)」の2つのプロパティを持つものとする。
- APIのリクエストパラメータとして「name(部分一致)」による絞り込みを可能にすること。
- nameパラメータが未指定またはnull、空文字列の場合は全件取得とすること。
- nameパラメータが50文字を超える場合はRuntimeExceptionを発生させること。
- Q1-Q4: 30分(コードリーディング)
- Q5: 30分(機能追加)
- Q6: 60-90分(設計+実装)
- Q7: 60分(新規実装)
- 合計: 約3時間
- コードの正確性(40%)
- 設計の適切性(30%)
- コードの保守性・可読性(20%)
- ドキュメント・コメント(10%)
- 修正後のソースコード一式
- README.mdの回答(Q1-Q4)
- 本課題は個人で取り組んでください。
- AIツールは利用しても構いませんが、提出物の内容については自身で理解して説明できるようにしてください。面接時に設計意図や実装方針を確認します。 例:なぜそのパラメーター設計にしたか、バリデーションや例外処理の方針、拡張性の工夫など
A1〜A4 は実装前の状態についての回答のため、実装後の最終的なAPI仕様をここに記載する。
| パス | パラメーター名 | 型 | 必須 | 説明 |
|---|---|---|---|---|
GET /skillCheck |
name |
String | 任意 | 名称の部分一致 |
GET /skillCheck |
age |
Integer | 任意 | 指定値以上の年齢 |
GET /skillCheck |
hasSkill |
Boolean | 任意 | スキル保有有無の完全一致(Q5で追加) |
GET /skillCheck |
sort |
String(繰り返し指定可) | 任意 | ソート条件。キー:並び順 形式(Q6で追加) |
GET /skillCategories |
name |
String | 任意 | 名称の部分一致(Q7で追加) |
- 検索条件は指定されたものだけをAND連結して判定し、1つも指定がなければ全件取得となる。
hasSkillは「未指定」と「false指定」を区別するため、検索条件クラスではBooleanで保持している。- 元の仕様どおり、年齢条件のみが指定されている場合は90歳以上で
RuntimeExceptionとなる。2条件以上指定されている場合は上限チェックを行わない(例:?age=90は例外、?age=90&hasSkill=trueは例外なし)。 sortは記述順がソートの優先順位となる(例:?sort=age:desc&sort=name:asc)。キーはname/age、並び順はasc/desc(大文字小文字は区別せず、並び順の省略時はasc)。未指定の場合は元の順序を維持する。不正なキー・並び順・形式はRuntimeExceptionとなる。/skillCategoriesのnameは未指定・null・空文字・空白のみの場合は全件取得、50文字を超える場合はRuntimeExceptionとなる。