oracle Java SE 8 ProgrammerⅡ(Gold)に合格した勉強方法と試験で注意したポイント
oracle Java SE のGoldを受験して合格しました。
他のよくあるブログみたいに「一発合格しました!!!」とかではないです(笑)
1回目不合格で2回目に合格しました。
勉強時間:1ヶ月半くらいで平日2時間、休日4時間くらい
1回目:不合格 合格ライン65%に対して正解率57%
2回目:合格 合格ライン92%に対して正解率92%
1回目と2回目の間は2週間でした。
oracleで再受験無料キャンペーン期間中だったので、2回目は無料で受けることができました。
再受験無料だったり、受験料の値下げだったりとキャンペーンがあるのでその時に受けるとお得かもしれません。
勉強方法と1回目と2回目でつまづいたポイントを載せます。
勉強方法:受験1回目まで
いわゆる黒本で勉強しました。これしか使ってません。
1日に、
1章分の理解
前1章分の復習
前々1章分の解きなおし
という感じでやっていました。
まず問題に取り組んでみて、その後解答ページで確認していくという感じです。
やっぱり最初は答え合わせするとボロボロなのですけれど、
次の日にもう一度同じ場所を解いて不正解の解答解説を確認、
またその次の日に同じ場所を解く。
という感じで3日かけて同じ場所を解くとさすがに分かります。(答えの順番すら覚えてくる)
それを2週間くらいかけて10章までやってました。(毎日じゃなくてサボったりもしてました・・・( ^ω^))
残りの1週間でやったことは・・・
11章の総仕上げ問題をやりました。85問1日で解くのはしんどかったので1日40問ほどに分割して・・・
Webで黒本の総仕上げ問題がもう一つ配布されているので、それもDLして解きました。こちらの方が難しい印象。
https://book.impress.co.jp/books/1116101039
下にスクロールしていくと「特典」という項目があるのでそこからDLできます。
そして満を持して受験・・・!無事不合格となりました。
勉強方法:受験2回目まで
記憶がある間がいい!!ということで再受験無料キャンペーンで再受験できる最速の2週間後に受験を予約しました。
最初の1週間は黒本の10章までの解きなおし。1回目のやり方と同じです。
次の1週間で総仕上げ問題2本分の解きなおし+oracleでサンプル問題が公開されていたのでそれも解きました。(もっと早く気づけておけば・・・)
http://www.oracle.com/jp/education/certification/java-campaign-3254824-ja.html
あとはJavaDocのメソッドを眺めていました。特に戻り値とメソッドの内容を注視しつつ。
例えばStream<T>とIntStreamのメソッドの違いとか、Optionalの内容とか
とにかく「あれ?このメソッド何だっけ・・?」という感じのものがあったらすぐにJavaDocを見て確認してました。
そして試験当日、無事合格することが出来ました。
2回目ならそりゃ当たり前だろ~!と思うかもしれないですけれど、
1回目でどこがいけなかったのかということや不足していた点などを分析して2回目までに照準を合わせて軌道を修正していくというのは中々大事なことで、2回目でしっかり目標の達成まで持っていけるというのはとても重要な事だと思っています。(自画自賛)
つまづいたポイント
黒本でカバーしきれない部分とか。
裏を返せばこいつらは試験で高確率で出題されるということ。心して見るべし。
Deque
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Deque.html
DequeはQueueとStackのハイブリッドみたいな存在。故に理解が面倒。
特にQueueとStackのメソッドがどちらも使えるため、この二つのクラスのメソッドを使われた場合、先頭と末尾どちらに対しての動作だよ!という感じで混乱してくる。
以下の事を理解していれば大丈夫。
Queue
add(e)・・・Dequeで言うaddLast(e)
remove()・・・Dequeで言うremoveFirst()
Stack
push(e)・・・Dequeで言うaddFirst(e)
pop()・・・Dequeで言うremoveFirst()
超明快な図で理解した。この時自分は天才かと思った。(多分N番煎じ)
まずQueueとStackの基本イメージ
からのQueueを反転して足すと・・・
Deque(両端キュー)の完成
Outer・Innerクラス
Outer.Inner inner = new Outer. new Inner();
という問題系。staticが入ってくると余計にややこしくなってくる。
実際にソース書いて確認してみた。
package class_makeDiff; public class ClassMakeDiff { public static void main(String[] args) { // A ClassMakeDiff.A a = new ClassMakeDiff().new A(); System.out.println(a.str); // B ClassMakeDiff.B b = new ClassMakeDiff.B(); System.out.println(b.str); // C //実質 C.new C2() ClassMakeDiff.C.C2 c = new ClassMakeDiff.C().new C2(); System.out.println(c.str); // D //実質 D.D2 ClassMakeDiff.D.D2 d = new ClassMakeDiff.D.D2(); System.out.println(d.str); } /** * Outer...public class</br> * Inner...public class */ public class A { String str = "nonStatic_nonStatic"; } /** * Outer...public class</br> * Inner...public static class */ public static class B { String str = "nonStatic_static"; } /** * Outer...public static class</br> * Inner...public class */ public static class C { public class C2 { String str = "staic_nonStatic"; } } /** * Outer...public static class</br> * Inner...public static class */ public static class D { public static class D2 { String str = "static_static"; } } }
実行結果
nonStatic_nonStatic nonStatic_static staic_nonStatic static_static
Optional
黒本ではOptionalについての説明は微々たるものしか書いていない。もはや記載していないに等しい。
けど試験だと結構でる。
JavaDocを見るのが一番いい。
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Optional.html
特に
of(T value)
ofNullable(T value)
orElse(T other)
orElseGet(Supplier<? extends T> other)
ifPresent(Consumer<? super T> consumer)
は戻り値も含めて覚えた方がいい。完全に暗記もの。
Optional型はget()を使わないと中の値が取れないというのも注意。
IntStream型で計算したあとただintに格納するとかでよく引っかかる。
get()を使わないとint型に格納できないとか。
夏時間
黒本では一切説明されない内容。けど試験では出る。
夏時間(サマータイム)とは、特定の期間だけ UTC のオフセットが1時間多くなること。
太陽の出ている時間に合わせることで、色々メリットがあるらしい。
サマータイムとは
表示上1時間のずれが発生するだけで、現実時間は変わらない。
ので、時間の長さの計算は現実時間のまま(1時間足したり引いたりとかしない)
時間を出力する時だけ夏時間の計算が入る(1時間足したり引いたり)
.reverse()
streamの.sorted()メソッドの引数、Comparator.comparingの並び替えメソッドのどこに.reversed()が入るかによって昇順と降順がかわる。
途中に入るとそれまでが逆に、最後に入ると全てが逆になる。
//AのName昇順、Title昇順 .sorted(Comparator.comparing(A::getName).thenComparing(A::getTitle)); //AのName降順、Title昇順 .sorted(Comparator.comparing(A::getName).reversed().thenComparing(A::getTitle)); //AのName昇順、Title降順 .sorted(Comparator.comparing(A::getName).reversed().thenComparing(A::getTitle).reversed()); //AのName降順、Title降順 .sorted(Comparator.comparing(A::getName).thenComparing(A::getTitle).reversed());
ストリームの戻り値
引っ掛け問題でかなり出てくる。
Stream<T>で戻り値IntStreamのメソッド使用してるとか、
Int型に戻り値IntStream型格納してるとか・・・
JavaDoc見るしかない。
ExecuterServiceとForkJoinPool
実装されているメソッドと対応する型を混同しないように注意
ExecuterService
execute・・・戻り値無しの非同期(CallableまたはRunnable)
submit・・・戻り値有りの非同期(CallableまたはRunnable)
ForkJoinPool
execute・・・戻り値無しの非同期(ForkJoinTaskまたはForkJoinAction)
invork・・・戻り値有りの同期(ForkJoinTaskまたはForkJoinAction)
submit・・・戻り値有りの非同期(ForkJoinTaskまたはForkJoinAction)
Compare
sortの話。
compartorのcompare(sortTarget o1, sortTarget o2)メソッドで内部処理に
compareToを使った時に昇順と降順どっちだっけ?というのを忘れるのはよくある話。
基本は
o2-o1・・・降順
o1-o2・・・昇順
の考え方でOK
package sorted_compareTo; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class compareTo { public static void main(String[] args) { compareTo parent = new compareTo(); List<sortTarget> list = Arrays.asList( parent.new sortTarget("a", 1), parent.new sortTarget("b", 2), parent.new sortTarget("c", 3), parent.new sortTarget("d", 4), parent.new sortTarget("e", 5)); System.out.println("★sort1★"); Collections.sort(list, parent.new sort1()); for (sortTarget target : list) { System.out.println(target.getName()); } System.out.println(); System.out.println("★sort2★"); Collections.sort(list, parent.new sort2()); list.stream().map(sortTarget::getName).forEach(System.out::println); System.out.println(); System.out.println("★sort3★"); Collections.sort(list, parent.new sort3()); for (sortTarget target : list) { System.out.println(target.getName()); } System.out.println(); System.out.println("★sort4★"); Collections.sort(list, parent.new sort4()); for (sortTarget target : list) { System.out.println(target.getName()); } } public class sortTarget { private String name; private int key; public sortTarget() { } public sortTarget(String name, int key) { this.name = name; this.key = key; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getKey() { return key; } public void setKey(int key) { this.key = key; } } public class sort1 implements Comparator<sortTarget> { @Override public int compare(sortTarget o1, sortTarget o2) { return o1.getName().compareTo(o2.getName()); } } public class sort2 implements Comparator<sortTarget> { @Override public int compare(sortTarget o1, sortTarget o2) { return o2.getName().compareTo(o1.getName()); } } public class sort3 implements Comparator<sortTarget> { @Override public int compare(sortTarget o1, sortTarget o2) { return o1.getKey() - o2.getKey(); } } public class sort4 implements Comparator<sortTarget> { @Override public int compare(sortTarget o1, sortTarget o2) { return o2.getKey() - o1.getKey(); } } }
sort2の出力文だけStreamにしてみた。
実行結果
★sort1★ a b c d e ★sort2★ e d c b a ★sort3★ a b c d e ★sort4★ e d c b a