Java Silverを受験しての所感

## はじめに
Java Silverに合格したので、合格までの道のりを記録として残します。(正答率89%で合格したので、わりと効率的な学習方法ではないかと思っています)
アウトプットする機会が少ないので、それに危機感を感じて記事にしてみることとしました。
最後に試験直前に確認していた確認リストも公開するので、ぜひ参考にしてみてください！

## この記事の内容
1. Java Silverとは
2. 受験のきっかけ
3. スケジュール感
4. 学習方法
5. 受験しての感想
6. 直前に確認していた内容
7. 最後に

## Java Silverとは
Java Silverとは、プログラミング言語Javaの技術レベルをOracle社が認定する資格で、正式には「Oracle Certified Java Programmer, Silver SE SE 11」と言います。

Javaアプリケーション開発のためのプログラミング知識や、さまざまな状況への対応能力を有していることを証明される、開発初心者を対象とした資格です。

## 受験のきっかけ
転職を考えるようになったのですが、その際に何か自分の技術力を証明するものが欲しいと感じました。
ただ、持っている資格としては、新卒時代に取得したITパスポートぐらいしかありませんでした。。(お恥ずかしながら...)
ですので、現場の業務で多く扱っているJavaについて、一定の技術力を持っていることを証明できるようにしようと考え、受験するに至りました。

## スケジュール感
11月頭から学習を開始し、1月末に受験しました。
学習期間としては**3ヶ月**。総学習時間は**90時間**程度。
仕事をしながらでしたので、主に業務後や休日を使って学習時間を確保しました。

## 学習方法
### 最初の1ヶ月
Youtubeを使い、Javaの基礎について学習を進めました。
Youtubeの学習は以下の動画を見てました(くそお世話になりました!!!)

1. **せかチャンの【JavaSilver対策】おすすめ動画集**

https://www.youtube.com/playlist?list=PLru8-xuz0YvwoVRzBTX5jUcavM4Q8gZi9

2. **黒本著者が教える やさしくない!? Java のOCJ-P Silver受験者向け動画**

https://www.youtube.com/@java9521/featured

### 後半の2ヶ月
基本的には黒本と呼ばれる **「徹底攻略Java SE 11 Silver問題集[1Z0-815]対応」** を3周解きました。
具体的には以下の流れで進めました。

1. とりあえず全ての問題を1周する(間違えた問題はチェックを入れておく)
2. もう一周全て問題を一通り解く(こちらも間違えた問題はチェックを入れておく)
※チェックが二つ入った問題にピンクの付箋を、1つの問題に青の付箋を貼っておく(色は任意です)
※解説で重要と思った箇所にも別の色の付箋を貼るようにする
3. 3周目は付箋の貼ってある問題が2回連続で正解するまで解くようにする
4. 3と並行して、付箋の貼ってある解説を繰り返し読み込む
5. なかなか頭に入らない内容はメモにまとめ、直前1週間で確認できるようにしておく

## 受験しての感想
### 学習期間中
- 現場で5年近くJavaを使ってきたが、思ったより知らないルールや考え方が存在し、愕然とした
- 最初に先人がどのようなツールで学習を進めていたのかを確認してから、自分の学習スケジュールを立てたのが良かった
- 黒本で間違えた問題に関しては、何故その回答になるのかをわかるまで調べて理解することが大切

### 受験当日
- テストセンターで受験したが、予約はかなり早く埋まってしまうので、2ヶ月前に会場を予約しておくのが良さそう(1ヶ月前に予約したが、かなり日が埋まってしまっていました ><)
- 持ち物は身分証明書が必要なので、何を持っていくのか事前に確認すること
- テストセンター近くには1時間前に到着しておくと安心(自分はカフェで時間潰しました)
- 受験時間は3時間あるので、途中でトイレに行きたくなることも。。行きたくなったらスタッフを呼び出していくことができるので、遠慮せずに行ったほうが良い(ただ時間はその間も経過してしまいます)
- 試験終了後はすぐに画面に結果が出ます(結果を見る直前はめちゃめちゃ緊張しました笑)

## 直前に確認していた内容
自分用に作成したものなので、間違っている部分もあるかとは思いますが、直前の見直し等の参考にしていただけると幸いですmm
## 1章 簡単なJavaプログラミングの作成
```
・java.langパッケージや同一パッケージに属するクラスのimport宣言は省略可能
・コンパイルの際に、javacコマンドで-dオプションを省略すると、ソースファイルと同じ場所にクラスファイルが作られる
・エントリーポイントは複数記述しても問題なし(オーバーロード)
  →ただ、呼び出されるのはStringの配列型のみ
◆JDK
  ・アプリケーションを作るための開発環境
  ・各OS用の物が用意されている
  ・JDKにはJREも含まれている
  ・IDEをインストールしても自動的にJDKがインストールされるわけではない
◆JDK, JRE, JVMについて
　JDKはJava開発者がJavaアプリケーションを開発するためのツールとリソースを提供し、
　JREはJavaアプリケーションを実行するためのランタイム環境を提供します。
　JVMはJavaアプリケーションを実際に実行するための仮想マシン
　→予め決められた形式でしかコードを読み込めない
```

### 2章　Javaの基本データ型と文字列配列
```
・整数リテラル
  「_」は先頭と末尾には記述できない
  記号(ドット、L、F、0b、0x)の前後には記述できない
・varはローカル変数の宣言にしか使用できない
・StringBuilderは保持している文字列+16文字分のバッファを持っている
・substringメソッドは間に線を引いて数える
```

### 3章　演算子と判定構造
```
・byte -128 ~ 127
・short -32768 ~ 32767
・&& や || はショートサーキット演算子と呼ばれ、左オペランドの結果によっては右を評価しない
・equalsメソッドは、nullが渡された時は常にfalseを戻さなければならない
・internメソッドについて、メモリ上に複数の同じ文字列を持つStringインスタンスがあっても、戻す参照は一つだけ
・switch文の条件式に戻せる型
  int以下の整数型とそのラッパークラス
  文字と文字列
  列挙型
・switch文の条件式にnullを戻すとnullポとなる
◆キャスト
・小さな型から大きな型へ型変換が行われる場合は、自動で型変換が行われる
・大きな型から小さな型へ型変換は明示的にキャスト式を記載する必要がある
　↓下記は自動で型変換が行われる
　変更元	   | 変更先
　byte     | short,int,long,float,double
　short	   | int,long.float,double
　int	   | long,float,double
　long     | float,double
　float    | double
　double   | --
　char     | int,long,float,double
  ※byteとshortはcharより小さい型にあたる
・基本データ型から参照型への変換は基本的には行えない。
　ただし、一部のプリミティブ型に対しては対応するラッパークラスが存在し、それを介して変換可能
```

### 4章 制御構造
```
・do-while文で中括弧を省略した場合、doとwhileの間には1文のみを記述できる。
　2文以上記述した場合にはコンパイルエラーとなる
・for文で初期化文に複数の変数を記述する場合、変数の型は同じでなければならない
```

### 5章 配列の操作
```
・newと初期化子を同時に使った場合、大括弧のなかにインデックスは記載できない
・Item[] items = new Item[3]; は、配列のインスタンスを生成しただけで、
Itemのインスタンスを生成したわけではない→items[0].prize等にアクセスするとnullポとなる
・初期化子は変数宣言と同時にしか使えない
　→変数宣言と配列インスタンス生成は分けて2行に記述できない
　ただ、明示的に次元数を記述すれば問題なし
　例)
　int[][] array;
　array = new int[][]{};
・「無名配列」は通常、「匿名配列」とも呼ばれ、配列の宣言と同時に要素を初期化して名前を付けずに作成する方法
・cloneメソッドは新しい配列を作り、その配列に同じ要素への参照をコピーする
　→2次元配列の場合、1次元目がクローン(別のインスタンス)、2次元めはコピーされないため同じ要素を参照
 ```

### 6章 インスタンスとメソッド
```
◆static
　・staticなフィールドへのアクセスは、クラス名.フィールド名だけでなく
    インスタンス生成し、その参照を使ってもアクセスできる
◆コンストラクタ
  ・メソッド名はクラス名と同じ
  ・戻り値型は記述できない
  ・インスタンス生成時以外は呼び出しができない
  ・アクセス修飾子は自由
  ・デフォルトコンストラクタは明示的にコンストラクタを記述しなかった場合に追加される
  ・コンストラクタでオーバーロードされた別のコンストラクタを呼び出す際は、
  thisで呼び出すコードは最初に記述しなければならない
  ・finalで修飾されたフィールドはコンストラクタ内で初期化されなければコンパイルエラーとなる
◆初期化子
  ・全てのコンストラクタで共通する前処理を記述するために使用
  ・コンストラクタ実行前に実行
  ・インスタンス生成時以外は呼び出しができない
  ・複数定義が可能で、上から順に実行
◆static初期化子
  ・静的メンバー変数(クラス変数)を初期化したい時に使用
  ・インスタンスを生成しなくても呼び出される
  ・複数定義が可能で、上から順に実行
◆オーバーロード
  ・戻り値の型はオーバーロードに影響しない
  ・オーバーロードされたメソッドで、引数がデータ型かそのラッパークラスの場合、オートボクシングしなくて済む
  データ型引数の方が選択される
◆ローカル変数
　・初期化されていないローカル変数を参照するとコンパイルエラーとなる
◆その他
・参照型の引数では、呼び出し元から値の参照が呼び出し先に渡される
→値が変更された場合、元の値も変更される
・プリミティブ型の引数では、呼び出し元から値のコピーが呼び出し先に渡される
→値が変更された場合、元の値も変更されない
・可変長引数は必ず最後の引数でなければならない
・インスタンス変数やクラス変数は同じクラス内に同名のものは複数定義できないが、
　同名のローカル変数は定義可能
・メソッドの実行時に、戻り値を格納する変数を設定していない場合でも、メソッド自体は実行される
```

### 7章 クラスの継承、インターフェース、抽象クラス
```
◆継承
・継承しても引き継げないものは以下
  コンストラクタ
  privateなフィールドやメソッド
・オーバーライドのルール
  シグニチャが同じ
  戻り値の型は同じ型か、サブクラス型
  アクセス修飾子は同じかより緩く
  ジェネリクスの型は同じでなければならない
  privateなメソッドはオーバーライドできない
  →@Overrideをつけるとコンパイルエラー
・継承元と継承先で同名のフィールドがある場合、フィールドは変数の型で宣言された方を使う
・キャスト式を記述して明示的に型変換すると、コンパイルは成功するが、型同士に互換性がない場合には
　実行時に例外がスローされる
・継承関係にある二つのクラス(A,B)にオーバーライドしたメソッドSampleがある場合、
　MainメソッドでA型でBクラスをインスタンス化した場合はBクラスに定義したSmapleメソッドが呼び出される
・菱形継承問題とはインターフェースを多重継承した場合にデフォルトメソッドが重複してしまう問題のこと
　→コンパイルエラーを解消するためには、.superの前にクラス名を記述する
・オーバーライドしたメソッドのジェネリクスの型パラメータは完全一致
◆インターフェース
・インターフェースに記述されている抽象メソッドは、記述がなくても全てpublic
・インターフェースに記述できるフィールド
  finalを使って動的に値が変更できないこと（定数）
  staticを使って、インスタンスが生成できなくても使えること
・インターフェースの継承にはクラスと同様にextendsを使う
  ※インターフェースの実装にはimplimentsを使う
・java.lang.Objectクラスに定義されているメソッドは、インターフェースでデフォルトメソッドとして
オーバーライドできない(コンパイルエラー)
・抽象メソッドを実装する場合には、同じシグニチャでなければオーバーライドではなくオーバーロードとなってしまう
・インターフェースが持つデフォルトメソッドは、インターフェース名.super.メソッド名()で呼び出せる
・インターフェース間の継承においては、必ずしもメソッドをオーバーライドする必要はない
　→インターフェースを実装したクラスではオーバーライドは必須
・インターフェースにはデフォルトメソッド、staticメソッドとこれらのメソッドから呼ばれるprivateメソッドしか
　具象メソッドを宣言できない

◆抽象クラス
・抽象クラスとインターフェースはインスタンス化できない(インスタンス化しようとするとコンパイルエラー)
・抽象クラスにはフィールドが定義できる
◆インナークラス
・クラスの中に作られるクラスのこと
・インナークラスはアクセス修飾子の制限がない
```

### 8章 関係型インターフェース、ラムダ式
```
◆ラムダ式
  ラムダ式で中括弧を省略した場合、処理は一文のみ記述可能でreturnは記述できない
  中括弧を記述した場合、returnは必ず記述しなければならない
  ラムダ式を記述しているブロックで宣言したローカル変数と同じ名前の変数は、ラムダ式内に宣言できない
  ラムダ式内からは、実質的にfinalなローカル変数として扱える変数にだけアクセスできる
  ラムダ式内でメソッドを参照する場合、()はつけない
◆関係型インターフェース
  Consumer<T>：引数を受け取って結果を戻さない。メソッドはvoid accept(T)
  Supplier<T>：何も受け取らず結果だけ返す。メソッドはT get()
  Predicate<T>：引数を受け取ってそれを評価する。メソッドはboolean test(T)
  Function<T>：引数を受け取って、指定された型の結果を返す。メソッドはR apply(T)
  ```

### 9章 API
```
・Comparatorインターフェースのcompareメソッド compare(Sample a, Sample b)
  与えられた二つの引数のうち、第一引数の順番が前なら-1,第二引数の順番が前なら1,
  並び順を変更しないなら0を戻す
・java.time.LocalDateクラスはimmutable(不変)である
◆java.util.ArrayList
  ・ArrayListのremoveメソッドは、条件に合致する最初の要素のみを削除する
    removeメソッドで要素を削除した場合、後ろの要素が繰り上がる
  ・ArrayListは動的配列でスレッドセーフではない
　 ArrayListから値を読み出している最中に要素を削除しようとすると例外がスローされる
  ・固定長のリストを作る方法
    ArraysクラスのasListメソッド
    Listインターフェースのofメソッド
◆java.util.Arrays
  ・asList：配列からリストのインスタンスを生成
  ・compare：二つの配列を辞書順に並べた時の並び順を比較。
          等しい場合は0,第一引数の方が先なら負の値,第二引数の方が先なら正の値
  ・mismatch：引数で渡された二つの配列の要素を先頭から順番に比較し、一致しない要素の添字を戻す
◆java.util.Map
  ・バリューの重複は許容し、キーの重複は許容しない
  ・HashMapはキーとバリューどちらもnullを許容する
  ・キーを取り出すにはkeySetメソッド(Set型)、バリューを取り出すにはvaluesメソッド(Collection型)を使う
◆java.util.List
  ・ofメソッドは変更できないコレクションを作る
  →変更の操作があった場合はUnsupportedOperationExceptionがスローされる
```

### 10章 例外処理
```
・try-catch-finallyはこの順番を変更できない
・finallyブロックは例外発生の有無にかかわらず実行される
　→これはcatchブロック内でreturnされた場合も同じ。
・catch内のreturnはfinallyが実行されてから戻される
・returnの変数は、メソッド内の変数とは異なる
　→catchのreturn変数をfinallyで変更しても値は変更されない
・tryとfinallyを複数記述した場合、コンパイルエラーとなる
・try-with-resourcesのtryブロックで宣言した変数の有効範囲はtryブロック内のみ
・try-with-resourcesの処理順は以下の通り
　1.closeメソッドによるリソース解放
　2.catchブロックの処理
　3.finallyブロックの事後処理
・非検査例外(RuntimeExceptionとそのサブクラス)はtry-catchを強制されず、throw句も宣言しなくて良い
・IndexOutOfBoundsExceptionはRuntimeExceptionのサブクラス(非検査例外)
・IndexOutOfBoundsExceptionのサブクラスがStringIndexOutOfBoundsExceptionとArrayIndexOutOfBoundsException
・StackOverflowErrorはErrorなので、ExceptionやRunTimeExceptionではcatchできない
```

### 11章 モジュールシステム
```
・モジュール化するにはmodule-info.javaとソースファイルをコンパイル
　例）java -d mods/hello src/hello/module-info.java src/hello/com/sample/main.Java
・モジュールクラスの実行
　例）java --module-path mods -m hello/com.sample.main
・複数モジュールを一つのファイルにまとめる
　例）jar --create --file=mlib/hello.jar --main-class=com.sample.Main -C mods/hello
・module2が必要とするモジュール設定をmodule1に伝播するにはmodule2のmodule-info.javaにtransive
　をつけたrequiresを記述する
・モジュールの情報を確認するコマンド
　1.javaコマンドの--describe-moduleオプション
　2.jmodコマンドのdescribeモード
・jdepsはモジュール等の依存関係を調べる
・利用するアプリケーションの使うJREモジュールを含めると、Javaがインストールされていないプラットフォームでもその
　アプリケーションが実行できる
・パッケージ単位での情報隠蔽が可能
```
## 最後に
Java Silverを受験したことで、自信がつき、もっと技術力をつけていきたいと感じるようになりました。資格としては次は応用情報を取ろうと考えてます。
以下の記事は自分が受験するにあたり参考にした記事です。
自分の記事より綺麗にまとまっておりますので、是非見に行ってみてください！

https://qiita.com/rikako_hira/items/ae208590d02a3bb91789

https://qiita.com/yoshinori_hisakawa/items/cc094bef1caa011cb739

https://qiita.com/liguofeng29/items/16d6dbec471bc5269f0e