メンバーのスキルアップ、どうしてる? − java...
Post on 06-Jan-2017
4.173 Views
Preview:
TRANSCRIPT
メンバーのスキルアップ、どうしてる?
-Java 100本ノックで新加入メンバーを鍛えてみた-
JJUG CCC Fall 20162016/12/03
#jjug_ccc#ccc_f3#Java100
自己紹介
• 株式会社ジャストシステム 福嶋 航• Twitter @fukushiw• Java歴約20年、JavaでWebサービス作っています• #Java100 本ノックの人https://github.com/JustSystems/java-100practices
株式会社ジャストシステム
• 創業37年、売上182億円、社員平均年収884万円
• Javaのプロダクト採用は1.0から。一太郎Ark:1996年開発着手。
• 1999年、2005年、2006年にはJavaOne Conferenceに出展
JavaOne画像引用:@IT 「JavaOneで阿波踊りを踊るジャストシステム」http://www.atmarkit.co.jp/news/200506/30/just.html
株式会社ジャストシステム現在、いくつものWebサービスをJavaで作っています。
などなど・・・
今日お話しすること
1.Java 100本ノックを 用いたトレーニング実例
2.ソフトウェア開発 アンチパターン7つ
1
Java 100本ノックを用いたトレーニング実例
Java100本ノックとは?プログラミング言語 Java に関するスキル向上を目的とした問題集です。 具体的には、運用環境で安定稼働でき、かつ、保守性・拡張性に優れたコードがより多く生産できるようになることを目指しています。
Javaを初めて使う方から中級者までをメインターゲットにしています。
Java100本ノック 目次
001-010:はじめの一歩011-040:言語仕様041-060:コアAPI061-080:複合・Java EE081-090:ライブラリ091-099:フレームワーク100 :Webアプリケーションの作成
Java100本ノック例えばこんなの(1)
Java100本ノック例えばこんなの(1)解答例
jar cfe ${JARFILE} Answer010 -C ${CLASSES} Answer010.class
Java100本ノック例えばこんなの(2)
Java100本ノック例えばこんなの(2)解答例
medals.forEach(System.out::println);
Java100本ノック例えばこんなの(3)
Java100本ノック例えばこんなの(3)解答例
「等価なオブジェクトは等価なハッシュ・コードを保持する必要がある」というhashCodeメソッドの汎用規約に従う必要があるため
java.lang.Object#equals()java.lang.Object#hashCode()
のAPIドキュメント参照
ある日
新メンバーがあらわれた!
たたかう じゅもん ▶どうぐ にげる
みんな がんばれ
ふくしまは Java100本ノックを つかった!
トレーニング内容• 被験者
• Java歴数ヶ月のエンジニア(20代前半)• 課題
• Java100本ノックを001番から順番に実施• 期間
• 1ヶ月• サイクル
• 帰る前にその日できた分をPull Request• 翌朝Pull Requestの内容について対面レビュー• 指摘反映&再レビュー→新規課題取り組み
トレーニング結果• 期間
• 19営業日• 課題進捗
• 001~074のうち、019(JNI)を除く73問を完了• スキル向上度合い(受講者の感想)
• 参考書を見ながらコーディングできるレベル ↓Javaを「なんとなく」ではなく、理解しながら実装することができるようになった! と同時に実装することが楽しいとまで感じられるようになった!
トレーニング結果• 期間
• 19営業日• 課題進捗
• 001~074のうち、019(JNI)を除く73問を完了• スキル向上度合い(受講者の感想)
• 参考書を見ながらコーディングできるレベル ↓Javaを「なんとなく」ではなく、理解しながら実装することができるようになった! と同時に実装することが楽しいとまで感じられるようになった!特にnullチェックなどの引数や例外をチェックするクセが身についた
新メンバーは レベルが あがった!
進捗
0
10
20
30
40
50
60
70
80
1日目
2日目
3日目
4日目
5日目
6日目
7日目
8日目
9日目
10日目
11日目
12日目
13日目
14日目
15日目
16日目
17日目
18日目
19日目
0
2
4
6
8
10
12
14
16
完了累計
(左軸)
完了
(右軸)
Java100本ノックの進め方
• (再掲)• 帰る前にその日できた分をPull Request• 翌朝Pull Requestの内容について対面レビュー• 指摘反映&再レビュー→新規課題取り組み
Java100本ノックの進め方
• (再掲)• 帰る前にその日できた分をPull Request• 翌朝Pull Requestの内容について対面レビュー• 指摘反映&再レビュー→新規課題取り組み
力をつけるにはレビューが大事1行ずつ、1文字ずつ意味がある
Java100本ノックを受けてみた感想• 参考書でJavaの知識を網羅したと思い込んでいたことに恐怖
を感じた• Java API リファレンスを見る癖が付いた• Eclipseの補完機能に頼らず実装できるようになった• 単純に問に対する答えが分からないから難しいのではなく、 使
用するコマンド・クラス・APIなどを正しく理解した上で、 正しく使用しなければ解けない問題が多いため難しい。
• 問題が難しい分、解けた時には、なるほどといった爽快感があった。
• 今までJavaを学習してきた中で、100本ノックのような問題集にもっと早く出会えていたら、Javaの理解スピードは遙かに違っていただろうと思った。
※個人の感想です
Java100本ノックを受けてみた感想• 参考書でJavaの知識を網羅したと思い込んでいたことに恐怖
を感じた• Java API リファレンスを見る癖が付いた• Eclipseの補完機能に頼らず実装できるようになった• 単純に問に対する答えが分からないから難しいのではなく、 使
用するコマンド・クラス・APIなどを正しく理解した上で、 正しく使用しなければ解けない問題が多いため難しい。
• 問題が難しい分、解けた時には、なるほどといった爽快感があった。
• 今までJavaを学習してきた中で、100本ノックのような問題集にもっと早く出会えていたら、Javaの理解スピードは遙かに違っていただろうと思った。
ヨイショォオォォォォ!!
※個人の感想です
どのように活用すべきか• 基本
• 回答→Pull Request→レビューのサイクル• オンデマンドで被験者の相談に乗る
• レビューで鍛える• レビューの場=スキルアップの場• 教える側も本質を正しく理解していないといけない• 指摘だけではなく、よくできたところを伝える
• 「コメントがよく書けた!」• 「1メソッドが短くていいね!」• 「この命名はわかりやすいね!」
Java100本ノックは基礎を学ぶもの
• 次は実践• 実践では何に気をつけるべきか
2
ソフトウェア開発アンチパターン7つ
社内の複数のプロジェクトに関わってきたら、気づいてしまった
ひとつ関われば自分がわかる
ひとつ関われば自分がわかる
ふたつ関われば全てが見える
ひとつ関われば自分がわかる
ふたつ関われば全てが見える
みっつ関われば…アンチパターンが見える
ひとつ関われば自分がわかる
ふたつ関われば全てが見える
みっつ関われば…アンチパターンが見える
見える見えるー嵌まる様
アンチパターンを作るきっかけ• 複数のプロジェクトに関わるうちに「あそこがイクナイ」
「ここがイクナイ」という事例がたまってきていて、これをバネに各開発チームのスキルアップが必要と感じていた。
• そんな折、「SQLアンチパターン」の社内読書会に @t_wada さんにお越し頂く機会があり、そこで、
アンチパターンには名前をつけるとよいです
というお言葉を頂戴した。
アンチパターンを作るきっかけ• 複数のプロジェクトに関わるうちに「あそこがイクナイ」
「ここがイクナイ」という事例がたまってきていて、これをバネに各開発チームのスキルアップが必要と感じていた。
• そんな折、「SQLアンチパターン」の社内読書会に @t_wada さんにお越し頂く機会があり、そこで、
アンチパターンには名前をつけるとよいです
というお言葉を頂戴した。
これ、使えるんじゃないだろうか?
社内のQiita:Teamで共有してみた
今日お話しする部分
1
シャイ・メッセージ
何が起きたかは生ログで
シャイ・メッセージ(何が起きたかは生ログで)
本当にあった怖い話
ログ監視システムからアラートメールが到着。肝心のメッセージ部分には
java.lang.NullPointerException: null
とだけ書かれている
!?ユーザーへの影響は?
何が起きているのかサッパリ分からん・・・
シャイ・メッセージ(何が起きたかは生ログで)
本当にあった怖い話
ログ監視システムからアラートメールが到着。肝心のメッセージ部分には
java.lang.NullPointerException: null
とだけ書かれている
!?ユーザーへの影響は?
何が起きているのかサッパリ分からん・・・運用環境に乗り込んでログを確認・・・(初動調査に遅れ)
シャイ・メッセージ(何が起きたかは生ログで)
解決策:例外スロー時・ログ出力時のそれぞれで、 何が起きて何ができなかったかを記載する
例外をスローするときは何が起きたかをメッセージに入れるthrow new ApiException("api server did not respond for " + retryCount + " times");
ログ出力時にどこで何の処理ができなかったかを記述するLOGGER.error("Failed to retrieve the score from database.", e);
2
リ・インベンティング・ザ・ホイール無駄な独自ロジック
リ・インベンティング・ザ・ホイール(無駄な独自ロジック)
本当にあった怖い話
渡された日付の前日が所属する年月を求めて欲しい
OK
できたよ
・・・2016/01/01入れると2016年0月ってなるんだけど・・・
リ・インベンティング・ザ・ホイール(無駄な独自ロジック)
本当にあった怖い話
渡された日付の前日が所属する年月を求めて欲しい
OK
できたよ
・・・2016/01/01入れると2016年0月ってなるんだけど・・・
String newMonth = Integer.parseInt(inputString.substring(3,5)) - 1;return newYear + "年" + newMonth + "月";
リ・インベンティング・ザ・ホイール(無駄な独自ロジック)
本当にあった怖い話
渡された日付の前日が所属する年月を求めて欲しい
OK
できたよ
・・・2016/01/01入れると2016年0月ってなるんだけど・・・
String newMonth = Integer.parseInt(inputString.substring(3,5)) - 1;return newYear + "年" + newMonth + "月";ロジック作っちゃってる・・・!
リ・インベンティング・ザ・ホイール(無駄な独自ロジック)
補足:Date and Time API を使えば以下の通り(※例外未考慮)return LocalDate.parse( inputString, DateTimeFormatter.ofPattern("yyyy/MM/dd")).plusMonths(-1L).format( DateTimeFormatter.ofPattern("yyyy年MM月"));
解決策:標準SDKやよく使われているライブラリを使用する今回の場合、標準SDKであるSimpleDateFormatクラスやCalendarクラスを使えばなんのことはなくできる処理です。標準SDK以外のライブラリを使うまでもありません。標準SDKが第1の選択肢です。ちまたのユーティリティライブラリが第2の選択肢です。後者の場合、使用の前にライセンスの確認が必要です。
3
リーゾンレス・トラスト
nullチェックしない
リーゾンレス・トラスト(nullチェックしない)
本当にある普通の話
実は、現場で起きている例外で一番多いのが、
NullPointerException
リーゾンレス・トラスト(nullチェックしない)
本当にある普通の話
実は、現場で起きている例外で一番多いのが、
NullPointerException
リーゾンレス・トラスト(nullチェックしない)
The Checker Framework の @NonNull や Kotlin を使うという解決策もあります。
解決策:nullチェックを入れる
nullチェックを入れない代わりに、nullチェックをしなくてよい理由をコメントしてもよいです。にするのがよいです。
4
デコイ・コード
ソースコードのコピペ
デコイ・コード(ソースコードのコピペ)
本当にある普通の話
機能追加、今あるものに影響が出ないよう、元のコードをコピーして改変せよ
了解しました
あ、ここにバグがあるや、修正しよう
あれ? 直したはずがまだバグコードがあるぞ?
デコイ・コード(ソースコードのコピペ)
本当にある普通の話
機能追加、今あるものに影響が出ないよう、元のコードをコピーして改変せよ
了解しました
あ、ここにバグがあるや、修正しよう
あれ? 直したはずがまだバグコードがあるぞ?
バグA を たおした!バグA の かげから バグB が あらわれた!
デコイ・コード(ソースコードのコピペ)
本当にある普通の話
機能追加、今あるものに影響が出ないよう、元のコードをコピーして改変せよ
了解しました
あ、ここにバグがあるや、修正しよう
あれ? 直したはずがまだバグコードがあるぞ?
バグAをたおした!バグAのかげからバグBがあらわれた!
メンテナンスコスト ∝ ロジックコピペ回数
デコイ・コード(ソースコードのコピペ)
解決策:Once And Only Once
コードの重複をしないように工夫します。例えば、旧ロジックと新ロジックの共通部分をスーパークラスで実装し、サブクラスで違う部分だけを実装するようにします。
当然、リファクタリング前にテストコードを書いてデグレ防止対策をする必要があります。
5
ナム・トゥ・イエロー
警告無視
ナム・トゥ・イエロー(警告無視)本当にある普通の話
• @SupressWarningsがクラスについてる• 警告は普通に無視。もしくは気づかない。
Eclipseだと黄色になるだけで実行できるし痛くもかゆくもない。
ナム・トゥ・イエロー(警告無視)本当にある普通の話
• @SupressWarningsがクラスについてる• 警告は普通に無視。もしくは気づかない。
Eclipseだと黄色になるだけで実行できるし痛くもかゆくもない。でもいざDeprecatedのものが消えたりするとそのとき大騒ぎ
ナム・トゥ・イエロー(警告無視)解決策:コンパイラが出す警告は全て解消する
ビルドのログを見て警告が出ていないことを毎回必ず確認するようにします。一杯たまると大変なので、ちょっとずつビルドして、警告が出たらすかさずつぶすようにするのがよいです。
6
エングリッシュ
奇妙な英語
エングリッシュ(奇妙な英語)本当にあった怖い話
• public void regist(User user)
• public boolean isExist(User user)
A:「registでしょ?」B:「えっ?」A:「えっ?」
エングリッシュ(奇妙な英語)本当にあった怖い話
• public void regist(User user)
• public boolean isExist(User user)
A:「registでしょ?」B:「えっ?」A:「えっ?」
「キラキラ変数名」とかいう言葉も世の中にはあるようで・・・ (ノД̀)
エングリッシュ(奇妙な英語)便利なツール
• codichttps://codic.jp/ PascalCase, camelCase, snake_caseなど かゆいところに手が届いているところがニクい
• IDE例:Android Studio →
エングリッシュ(奇妙な英語)便利なツール
• codichttps://codic.jp/ PascalCase, camelCase, snake_caseなど かゆいところに手が届いているところがニクい
• IDE例:Android Studio →
• ATOK日本語入力してF4
7
ミミック
おかしいコードの増殖
ミミック(おかしいコードの増殖)本当にあった怖い話
リーダー「前担当のソースを参考にしてみて」メンバー:コピーして必要なところだけ修正
~レビューにて~リーダー「なんでthrowするのがRuntimeException?」
メンバー「だって前のコードを参考にしろという指示だったし、そもそも何やってるのかわからないところはそのままにし
ています」
ミミック(おかしいコードの増殖)本当にあった怖い話
リーダー「前担当のソースを参考にしてみて」メンバー:コピーして必要なところだけ修正
~レビューにて~リーダー「なんでthrowするのがRuntimeException?」
メンバー「だって前のコードを参考にしろという指示だったし、そもそも何やってるのかわからないところはそのままにし
ています」あなたが書いたコードはコピペであってもあなたのものですから!
ミミック(おかしいコードの増殖)解決策:最善なコードを生産する
前任者から引き継いだコードがひどいシロモノだった、というのはよくある話です。ひどいコードスタイルをそのまま受け継ぐと負の遺産が増えるばかりです。自分がコードを書くところは自分の責任ですから、自分が最善と思えるコードを書き、新しく作るところだけでも清らかにしていくことが重要です。
まとめ
本日お話ししたこと
メンバーのスキルアップ、どうしてる?
本日お話ししたこと
1.Java 100本ノックを 用いたトレーニング実例
2.ソフトウェア開発 アンチパターン7つ
We are Hiring!!
top related