エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

2018/12/03週 気づきと振り返り

業務こなして思ったこと

Androidのパフォーマンス計測はどうすればいいのか?

Androidアプリをいじることになったのだが、パフォーマンス計測ってどうすればいいのか?

サーバサイドJavaなら分るんだけど、Androidは情報が全然無い。。。
Androidは、ウォームアップとか関係ないのかな?
Javaで動く以上、JVMの最適化からは抜けられない気がするのだが、どうなのだろう?

調べても分らなかったので、30回くらい動かして、それの中央値と散布図作って終えた。

MacSafariでAudioタグのcrossoriginが効かない

chromeは動いていたのに、なぜsafariはだめなのか?

動かしたときにCORSでエラー吐かれると、絶望感を覚える。
windowschromeでいじってたときも別の箇所でそれが出てきて、proxy用意したりするので、かなり四苦八苦した。。。

今回のやつは、どうやって回避したらいいんだ。。。
proxy作ったら、SSLの証明書が信頼できないって怒られて、絶望感しか沸かない。

safariでのWebAudioAPI

webkitAudioContextを使う。

雑記

佐賀行きてぇ。。。
老後は佐賀で過ごすかな?
来年の早いうちに佐賀に行きたい。

もうMac/Safariの対応で、ハゲそう。。。
手詰まり感がハンパない。。。

会社の飲み会って参加する意味あるんですかね?
つまんなすぎて、もう出ようとは思わない。
2時間壁と喋ってなきゃいけないんだぜ。。。
一人は苦ではないが、何もしないで時間だけ過ごすのは、苦痛。

来年は、Android-Javaの取得が目標かな?
今年の振り返りは、どっかでしたいが、JavaScriptが思うように使えるようになったのは、かなり大きい気がする。

思いついた名言

  • 子どもの夢を壊すのが大人の優しさ。

2018/11/26週 気づきと振り返り

業務こなして思ったこと

Object.assignの副作用

const a = { a: 1, b: 2, c: 3, f: 5 }

const b = { c: 4, e: 6 }

const assign = Object.assign(a, b);

console.log(assign);
console.log(a);
console.log(b);

例えば、上記を実行する。
俺としては、aの値は変わりなく { a: 1, b: 2, c: 3, f: 5 } なんだけど、実際には下記の通り。

{ a: 1, b: 2, c: 4, f: 5, e: 6 } // assign
{ a: 1, b: 2, c: 4, f: 5, e: 6 } // a
{ c: 4, e: 6 }  // b

第一引数の値が変わってしまっている。。。
だったら戻り値返すなやって思いました。
なので、やるとしたら、第一引数は空のオブジェクトか、副作用が起きても問題ないオブジェクトだけを入れるべきだと思う。

これを知らずに使ってしまったので、バグを生んでしまった。。。
不変性は大事。意図しないバグを生む。

ハンドリング複数は辞めるべき

EventEmitter使ってイベントハンドリングしている人は多いと思う。

ただ、同じイベントを別々にハンドリングするのは辞めるべき。

emitter.on("response", (value) => {
  if(XXXX) {
    // 処理A
  }
});

emitter.on("response", (value) => {
  if(XXXX) {
  // 処理B
  }
});

上記みたいに複数のイベントハンドリングしていると、どっちでバグが出たのか追いづらい。
やるなら、下記。

emitter.on("response", (value) => {
  if(XXXX) {
    // 処理A
  }

  if(XXXX) {
  // 処理B
  }
});

windowsIntelliJの参照先から戻るショートカット

ctrl + alt + ←

windowsは、画面が回転してしまうので、OS側のショートカットキーを無効にしてあげる必要がある。
windows8.1の話。ほかは知らない

やり方

  1. デスクトップで右クリック
  2. グラフィックオプション
  3. ホットキーを無効にする

三項演算子について考え直した

きっかけ

現場でああだこうだ言っていたので、自分の考えをまとめる。

思うんだけど、現場の人間と挨拶以外に話さない日が多い気がするんだが、これは普通のことだよね?

前提

Java10

三項演算子

class Test {
  public static void main(String args[]) {
    int a = 0;
    int answer = a == 0 ? 10 : 11;

    System.out.println(answer);
  }
}

当然、出力は 10

if文で書くとどうなるか?

class Test {
  public static void main(String args[]) {
    int a = 0;
    int answer;
    if (a == 0) {
      answer = 10;
    } else {
      answer = 11;
    }

    System.out.println(answer);
  }
}

冗長記述になる。
answerがまどろっこしいくらいに出てくる。

三項演算子のメリット

  • 冗長性を回避できる
  • 記述量を削減できる

三項演算子のデメリット

メリットあれば、当然デメリットもある。

複数項

三項で済めばいいけど、四項・五項になってくると、意味がわからなくなる。

class Test {
  public static void main(String args[]) {
    int a = 0;
    int answer = a == 1 ? 10 : a == 0 ? 11 : 12;

    System.out.println(answer);
  }
}

answerには 11 が設定されるのだが、 条件が複数になった時点で、人間の処理能力を越えると思う。

演算子の優先順位

class Test {
  public static void main(String args[]) {
    int a = 0;
    int answer = a++ == 1 ? 10 : a == 0 ? 11 : 12;

    System.out.println(answer);
  }
}

これは、 12 が正解だが、パット見、10と答えたくもなる。
三項演算子は、演算子が連続して記述される可能性が高くなるため、なるべく演算子を途中で利用するのは避けるべき

三項演算子でやっちゃいけないこと

  • 項が複数に成らないようにする
  • 演算子を混ぜない

上記のどれかに合致してしまう場合、使わない方がいい。

あと、下記の理由で使うのも辞めるべき

  • ワンライナーで書きたい。
  • 俺、頭いいでしょって見せびらかしたい。
  • 記述量を減らしたい

本来は、簡素な記述で分かりやすくあるべきもの。
本来の意図を見失って、自己陶酔に走ったりするのは、ナンセンス。
たまにワンライナー至上主義みたいなエンジニアがいるが、個人的な見解を言うと、頭おかしい人だから、あんまり真に受けないほうがいい。
ワンライナーで書いても問題ないところは、書くこと推奨だが、他者の理解を著しく妨げるものは、辞めたほうがいい。

三項演算子を使うべきパターン

class Test {
  public static void main(String args[]) {
    System.out.println(Test.isNegativeNumber(-1));
  }

  static String isNegativeNumber(int target) {
    return target < 0 ? "yes. it's negative!" : "no!";
  }
}

2パターンにしか成らない返り値の場合とかが最有力だと思う。
それ以外は、使用を控えるべき。
目的に沿って使うことが重要。
複数個を返す可能性があったりするものは、if文でやるほうが無難だと思う。

ちなみに、negativeってワードを選んだのには、他意はない。
整数だとintegerで紛らわしいから。だったらpositiveでいいじゃんってのは、作ったあとに思った。

気をつけること

ワンライナー教は、マジで厄介。
レビューで指摘すると反発してくることがよくある。
だけど、可読性を著しく下げるものは、許容できないので、根気強く説得するしかない。

2018/11/05週 気づきと振り返り

業務こなして思ったこと

順次実行はPromise

JavaScriptやるようになって半年。Typescript含めれば、1年。
順次実行したいものを実装したい場合は、自前でキューみたいなものを用意するより、Promiseで処理を積んだ方が、簡単に実装できる。

git log --decorate

ログ内容にHEAD、ブランチ名、タグ情報が付与される。

タグ付けしたさいの確認は、これを使ったほうがいい。

gitで未プッシュの差分を見る

git log origin/{ブランチ名}..{ブランチ名}

プッシュしたか分からないときに使う。 sourcetree使えばいいと、最初のときは思っていたが、細かいことをしたいってなると、コマンド打つしかなくなる。

だから、CLIには、なれたほうがいい。

今は、どっちも使っている。
ステージに上げるのは、差分見ながらやれるsourcetreeの方が良い。
CLIだと、何がなんだか分かりにくいんだよね。。。
差分をもっと簡単に表示させる方法はないのだろうか?
上下に出てると分からないから、左右で見比べられるようにできないだろうか?

個人的に思いついた名言

責任は果たすものじゃない。なすりつけるものだ。

汚い大人の社会は、だいたいこうです。
大手のSIerは、この考えで動く人が多い。

人の名前よりポケモンの名前を覚えるほうが楽。

現場の人間の名前は、ほとんど覚えてない。
仕事上、関係なければ覚える必要ないと思うんだよね。

JJUGナイトセミナー「JDK 11リリース記念:今知っておくべきJDK 11の重要ポイント 参加報告

公式サイト

【東京】JJUGナイトセミナー「JDK 11リリース記念:今知っておくべきJDK 11の重要ポイント」 - 日本Javaユーザーグループ/Japan Java User Group | Doorkeeper

まとめ・メモ

OracleJDK

  • ソース&バイナリをオラクルが提供
  • 用途によって有償

OpenJDK

- 無償

参考サイト

JDK 11リリース記念:今知っておくべきJDK 11の重要ポイントの個人メモ

JavaFX

同梱されなくなっただけ。
開発はされている。

JEP 330

JEP 330: Launch Single-File Source-Code Programs

javaコマンドだけでJavaファイルを実行可能。

制約

  • 1ファイルで完結している必要がある。
  • トップレベルクラスがmainを持っている必要がある。

仕組み

SourceLancherが起動してコンパイル実行している。

JEP 328

JEP 328: Flight Recorder

プロファイラ。情報収集を行うだけで、可視化は別途用意する必要がある。

JEP 181

JEP 181: Nest-Based Access Control

コンパイルされたときに、余計なクラスがなくなる。

JEP 320

JEP 320: Remove the Java EE and CORBA Modules

JavaEE/CORBAが削除された。

JEP 321

JEP 321: HTTP Client (Standard)

HTTPクライアントの実装。
HTTP2, Reactiveに対応。

sendAsync→非同期
send→同期

API追加

Null I/O

linux/dev/null と同じような動きをする。
何もしないクラス。

Rredicate.not

今までのラムダで書けなかった、条件の反転ができる。

感想

JEP 330のやつは、てっきりコンパイル&実行を勝手にしてくれているのだと思ったら、1個間に挟んでいるのか。。。
意外と制約が多かった。
普通に使うには気にならないと思うが。

Null I/Oは、テストで使うのかな?
それ以外の用途が全然分からない。

2018/10/01に覚えたこと Object.assign/責務分担/npm install

Object.assign

Object.assign() - JavaScript | MDN

他の人が書いたソースを見てて、何をやっているのか分からなかったから調べた。

やってくれることは、オブジェクトのマージ。

とりあえずサンプル

const object1 = {
  a: 1,
  b: 2,
  c: 3
};

const object2 = Object.assign({c: 4, d: 5}, object1);
console.log(object2);

実行結果
> Object { c: 3, d: 5, a: 1, b: 2 }

一番最初の引数に、上書きしていってくれるところ。
いいと思ったことは、Object1がnullだった場合でも、エラーになることなく処理を実行してくれること

const object2 = Object.assign({c: 4, d: 5}, null);

console.log(object2);
// > Object { c: 4, d: 5 }

一番最初の引数がnullだったらダメだけど、2番目以降は、null許容してくれる。
面倒くさいif文のnullチェックが不要になるのは、可読性も上がるし、いいと感じました。

他人のソース見てると、たまに発見があるから、なるべく見たほうが良い。
特に、自分より上位と思われるエンジニアが書いたソースは、要チェック。

責務分担

mainクラスは、ライブラリを使うだけにする。
機能の実装は、別クラスに追いやり、機能をつなぐだけにしておくと、全体像が見通せて、理解がしやすいはず。

気づかぬうちに、mainクラスになんでも突っ込んでしまうのが、いつものことなので、もうちょっと注意したい。

責務分担の定石って、どこかにまとまっていないものなのだろうか?

npm install

問題になったのは、linux環境でnpm installしたものをwindowsで動作させようとして動かなかったこと。

原因は、もちろん、npm installを別環境でしたから。
node_modules\.bin 配下にwindows用にコマンドを叩くためのcmdファイルがなかったため、npm startで使っていたがnpmモジュールが見つからなかったのが原因。
cmdファイルの中身を見たら、node.exe使って何かしようとしていたので、そうなんだろうなと推測。
公式ドキュメント見てないから、本当かどうかは、若干怪しいが。。。

何かの開発環境のときに、同じことしていたのを覚えていたので、気づくのが早かった。

結局、実行する環境でnpm install するに落ち着いた。

たぶん、別環境でnpm installしたものを持ってくるって人は、そうそう居ないので、ためになるかは微妙かも知れない。

Java11の新機能まとめと試し実行

公式サイト

JDK 11

JDK 11 GA Release

新機能まとめ

試してみる

環境は、win10、Javaは、もちろん、09/25リリースのJava11

手頃そうなものを、とりあえず試す。

ファイルからの即時Java実行

テスト用のJavaファイルの用意

まずは、実行するファイルの用意から。
恒例にしたがって、hello world の出力だけする簡単なもの

public class SampleJava11 {
    public static void main(String args[]) throws Exception{
        System.out.println("hello world");
    }
}

ファイル名は、SampleJava11.java で保存。

実行

コンパイルしたふぁいるを実行するときと同じように実行。

$ java SampleJava11.java
hello world

難なく実行できる。
学生時代は、コンパイルして実行を習ったが、今は手軽にできる。
たぶん、コンパイルは習うと思うけど、覚えたらただの手間だから、学習速度は向上しそう。
なんというか、スクリプト言語に近い感じで、即座に確認できるのがいいと思いました。

ラムダ式でも利用できるようになったvarによる型推論

テスト用ファイルの用意

import java.util.List;
public class SampleJava11 {
  public static void main(String args[]) throws Exception{
    List.of("はな", "さあや", "ほまれ", "エミル", "ルールー").stream().forEach((var s) -> {
        System.out.println(s);
    });
  }
}

趣味全開でサンプルを書いてみた。

実行

コンパイルが面倒くさいので、さっき覚えた即時Javaファイル実行で実行

$ java LambdaVar.java
はな
さあや
ほまれ
エミル
ルールー

動く。
Javaを最近使ってないからなんとも言えないが、型情報を書くのが面倒なときに使う感じだろうか?
特に、クラス名が長いのは、見てて苦痛だからね。

クラス名を書かなくて済むのなら、書かないほうが無難そう。
var自体は、Java10で入ったので、特に、大きな違和感なく受け入れられたし、事前学習はできている。
LTSだけ学習していればいいかとも思ったけど、最新バージョンを追っていたほうが、学習範囲が狭くて覚えやすい気がした。

HTTP Client API

今、node使った開発をしている。
提供されたAPIは、nodeで提供されているものがJavaっぽくなった感じの印象を受けた。

JSR & HTTP Client API doc

JEP 321: HTTP Client (Standard)

HttpClient (Java SE 11 & JDK 11 )

テストファイル

import java.net.http.*;
import java.net.URI;
public class SampleHttpClient {
  public static void main(String args[]) throws Exception{
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest getRequest = HttpRequest.newBuilder()
      .uri(URI.create("https://www.google.co.jp/"))
      .build();
    HttpResponse<String> response = client.send(getRequest, HttpResponse.BodyHandlers.ofString());
    System.out.println(response.statusCode());
    System.out.println(response.body());
  }
}

もっとも有名な、Googleさんにアクセスしてみる。

実行

もちろん、即時Javaファイル実行

$ java SampleHttpClient.java
200
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="世界中のあらゆる情報を検索するためのツールを提供しています。さまざまな検索機能を活用して、お探しの情報を見つけてください。" name="description">
・・・
;google.jsc && google.jsc.m(m);})();</script></div></body></html>

難なく取れる。

最初、URLをhttps://google.co.jp/ って書いてしまい、ステータスが301で帰ってきて、マジで焦った。。。
ブラウザでgoogle.co.jp って打ってもアクセスできる弊害がここに出てくるとは思わなかった。

手軽にWebAPI試したりできたりするのが、便利かな?
curlで済ましてしまいそうな気がしないでもないけど。
Apatch のHttp Clientからの移行が増えそうな気がする。

雑記

Typescript & Javascript + node で開発しているが、なんなく理解できた。

スクリプト言語の特徴が取り込まれつつある気がする。
今後、nodeで使われているようなAPIが増えていくのだろうか?
Promiseとかは、面白いと思う。
今だと、async-awaitかな?
Javaは、マルチスレッドだから必要ないかも知れないけどね。。。

参考サイト

Java 11の変更点を押さえよう! 標準機能になったHTTP Client API (1/3):CodeZine(コードジン)

Java 11正式版がリリース、本バージョンからOracle JDKのサポートは有償に。OpenJDKで無償の長期サポート提供は現時点で期待薄 - Publickey

Java 11正式版がリリース、本バージョンから「Oracle JDK」のサポートは有償に (1/4) - ITmedia エンタープライズ

Java 11正式版リリース、3年の長期サポート対応のLTSバージョンが4年半ぶりに更新 - GIGAZINE