/home/by-natures/dev*

データ界隈で働くエンジニアとしての技術的なメモと、たまに普通の日記。

2018/11/20 Amazon Corretto

そろそろ年末が近づいてきました。異動もあって歓送迎会があることもあり、11月末〜12月に掛けてお酒を飲む機会が増えそうです。ちなみに・・・お酒でいうと最近のお気に入りはこのクラフトジンです:

https://www.amazon.co.jp/%E3%83%8B%E3%83%83%E3%82%AB-01077J-%E3%82%AB%E3%83%95%E3%82%A7%E3%82%B8%E3%83%B3-%E7%93%B6-700ml/dp/B071KXTSWCwww.amazon.co.jp

和柑橘の爽やかな香りと山椒のスパイシーな香りが調和 とありますが、この山椒の香りが素晴らしいです。ちょっと値が張るのですが家の近くのバーで何度か飲んでいて、家に一本置いておくか迷っています。クラフトジンも、クラフトビールの流れから来ているのでしょうか?あまりバーなど行かないのですが、たまに行ってバーテンダーさんにオススメのものを教えてもらうと楽しいです。

Amazon Corretto

そういえば昨日 Oracle JDK の話をしたのですが、Amazon からも OpenJDK のディストリビューションが出るという話がありますね。

aws.amazon.com

aws.amazon.com

Amazon will provide security updates for Corretto 8 until at least June 2023. Updates are planned to be released quarterly. Corretto 11, corresponding to OpenJDK 11, will be available during the first half of 2019. Amazon will support Corretto 11 with quarterly updates until at least August 2024.

Corretto 8 は (少なくとも)2023年6月、Corretto 11 は2019年前半に出て、2024年8月までアップデートを予定しているようです。OracleJDK 8 は商用ユーザ向けには 2019年1月にアップデート終了とあるので、Corretto であれば4年半ほど長く Java8 が使い続けられそうです。

小さいシステムであれば Java の新機能が使えるメリットもあるので LTS 版の Java(8, 11, 16, ...) に合わせてアップデートするのも良い気がしますが、Corretto も発表されたばかりですし、しばらく動向をチェックしておくのが良さそうです。

2018/11/19 Oracle Code One 2018 報告会 ボランティアしてきました

先週末より部署異動がありまして、新しい部署での勤務が始まりました。家からちょっと遠くなったのと、乗り換えがどうも上手くいかないルートばかりで最適ルートが見つかっていないので、しばらく試行錯誤しながら通勤します。

先日土曜日、こちらのイベントの運営ボランティアをしました:

jjug.doorkeeper.jp

ボランティアメンバー間で交代して受付担当していたので、いくつかの発表しか聞けませんでしたが、最近の Java のトレンドを聞くことができてよかったです。Long-term support(LTS)は3年ごと、メジャーバージョンアップは半年ごとなので、Java11 が LTS になったあとは Java17, Java23 と LTS のバージョンは 6ずつ増えていくことになるようです。

Graal という他言語対応の VM というのがあるそうで、デモでは JavaScript, Java, Ruby, Python など様々な言語を呼び出していました。

GraalVM

Project Panama という、ベクトル演算を利用して Java の数値計算を高速化するプロジェクトについても紹介がありました。

OpenJDK: Panama

We are improving and enriching the connections between the Java TM virtual machine and well-defined but “foreign” (non-Java) APIs, including many interfaces commonly used by C programmers. と紹介されているので、ベクトル演算に特化したものではなくて、C 言語のインタフェースで提供されているものを使いやすくするといった感じなのでしょうか。Python が機械学習の分野で多く使われていますが、Python が様々な C のライブラリを便利に呼べるのが良くて、Python の実行速度自体は早くないという話もあったので、こういったプロジェクトによって Java でも機械学習系のプログラムが書きやすくなるのかもしれません。また折をみて調べようと思います。

Java での Map の初期化

いつも Guava で Map の初期化をしているのですが、そういえば double braces で初期化する方法もあったなぁと調べた時のメモです。

stackoverflow.com

http://wiki.c2.com/?DoubleBraceInitialization

double braces で初期化する場合、そのクラスのオブジェクトではなく、そのクラスを継承した匿名クラスのオブジェクトが生成される、というのがポイントです。上のリンクで紹介されている equal メソッドは、クラスを比較して同じクラスかどうかを判定していますが、double braces で生成するとクラスが元のクラスと一致しなくなります。(あまり Map に対してはそういうことしない気がしますが)

Java9 からは factory-methods というのが追加されていて、Map の初期化が簡単になっているようです。Java8 がそろそろサポート切れるので、バージョンアップしないといけないですね。。(factory-methods 使えない)

KSQL, ConfluentPlatform

こちらは完全に自分用メモです。KSQL, クエリでストリーミングが定義できるのはすごく便利そうですが…社内に詳しい人がいるので今度聞いてみよう。

qiita.com

www.confluent.io

Spring の ModelAttribute, SessionAttribute

便利そうではあるけれど、無理に使うとよく分からないことになる気もして今回は見送り

dzone.com

2018/11/14 正規表現でグループ化した文字列の取得

中国人の友達と日本語・中国語を教え合っているのですが、中国人にとっては中国語に近い熟語のほうが使いやすいようです。「それ錯誤です」と言われて気づきました。「間違う」は日本語としての変化があるので面倒だけれど、「錯誤」のような熟語なら音読みだけ覚えれば(中国語にその熟語が存在していれば)使えるので手っ取り早いみたいです。

もちろん違う点も多いので学ばないといけないですが、お互いの母国語にちょっとした共通点を見つけると面白くて、学ぶ意欲につながっています。

グループ化した文字列を取得する

Go言語でグループ化した文字列を取得したかったのですが、ちょっと探すのに手間取ったのでメモ代わりに。

nisenabe.hatenablog.com

FindSubmatch でグループ化した文字列が取得できます。ただ引数は []byte, 返り値は [][]byte なので少々面倒です。引数は []byte(string_var), 返り値は string() などで文字列に変換し直します。

stackoverflow.com

2018/11/08 SlackAPI, 三項演算子, goto文

飾り棚を少しずつ冬っぽくしようと、昨日夜飾り付けをしていました。マリボウルはクリアしか持っていないのですが、火をつけると雰囲気が華やかで良いですね。サルパネヴァプレートに写る様子もとてもきらびやか。

f:id:bynatures:20181108115653j:plain

Slack の API を呼ぶ

Slack の API を通じて、チャネルに通知を飛ばしたかったので調査。すごい簡単でした。昔 Twitter の API に投稿しようとして面倒だった記憶があったのですが、Slack は Webhook URL を取得したらほぼ完了です。あとは JSON を POST するだけでした。

crossbridge-lab.hatenablog.com

三項演算子がない

Go言語には三項演算子(tenary operator)がないので、プログラムが冗長になる場面が多いです。思想として、書きやすさよりも(他のプログラマに対して)読みやすさを重視しているから…ということなのですが。

stackoverflow.com

それでも三項演算子があれば

int index = val > 0 ? val : -val

と書けるはずが

var index int
if val > 0 {
    index = val
} else {
    index = -val
}

では冗長すぎないかということで上の StackOverflow の質問が投稿されていました。確かに上のプログラムだとかなり読みづらいですが、初期値を与えて else 節を消してしまえば読みやすくなると。

index := val
if val <= 0 {
    index = -val
}

確かにこれなら、どちらが主な値かを示すこともできるし読みやすいです。納得しつつ、でもプログラムを書いて、やっぱり三項演算子欲しいなぁと思うことを繰り返す昨今。。

goto 文を使ってみる

エラー値を受け取って if 文でリターンという処理が何度も続いたので、エラー処理をまとめるために goto 文を使ってみることにしました。ただ、ラベルを貼った移動先にスキップする行の中で、今まで出てきていない変数が新たに宣言されている(スコープに変数が新しく加わる)場合は構文エラーとなります。

cmd/compile: spurious "goto label jumps over declaration" - 2 · Issue #22101 · golang/go · GitHub

この X は goto とラベル宣言の間にいるのでエラーとなります:

package main
func main() {
    goto label
    X := 0
label:
}

変数スコープをややこくしないために、または実装上の都合かもしれませんが、エラー処理をまとめたいといった場合は少々面倒です。変数宣言を関数先頭にまとめてしまうか、新たにブロックを作って以下のようにすることで解決できました:

func main() {
    goto label
    {
        X := 0
        // X を使った処理...
        // もちろん中でも goto できる
    }
label:
}

2018/11/06[2] オブジェクト初期化の引数が多くなってきた時の対処法

オブジェクトのフィールドが増えると初期化する時の手間も増えてきてしまい、Java ならビルダパターンなどで必須パラメータと任意パラメータをうまく分けられたのですが、Go言語ではどうしているのか検索しました:

stackoverflow.com

ベストアンサーではないけれど UpVote が一番ついているものを見てみると、functional options というアイデアがあって、可変長引数でメソッドを渡して、その中で任意パラメータを処理する方法です。詳しくは以下のブログで紹介されています。

Functional options for friendly APIs | Dave Cheney

例えば id のみ必須パラメータであとは任意にしたい場合は以下のように書けます。最後の可変長引数はメソッドであれば何でも渡せてしまうので、そのオブジェクト(上なら Foo)のフィールドは外部パッケージからは非公開になるようにしておいた方がよさそうです。

func NewFoo(id string, options ...func(*Foo)) Foo {
        foo := Foo{id: id}
        for _, option := range options {
                option(&foo)
        }
        return foo
}

2018/11/06 日付処理

週末に TOEIC の S&W(Speaking and Writing)を受けてきました。2回目か3回目なのですが数年ぶりだったのと、対策する時間があまりなかったのでスピーキングがしどろもどろに。L&R は日々の勉強でよい点数が取れたのですが、スピーキングはやはり試験対策しないとダメそうです。ちょっと試験料が高いのでまたしばらく時間を空けて受けようと思います。

スピーキングは DMM 英会話で少しずつ勉強しています。この前やっと8000分を超えました。130時間ちょっとですかね。仕事中にあまり口を動かす職業ではないので、30分自分だけが主に喋る時間って楽しいですし精神的にも良いです。レッスンが終わるといつもすっきりした気分です。外国の先生なのでプライベートな相談をしても安心だし、世界各国の色々な話も聞けるのもよいです。語彙を増やすためにあえて普段興味を持たないトピックを選んだりして、知識の幅も広がっていると思います。

昔、言語を学ぶのって明確な目標がないといけないと思っていて、大学で3年フランス語を勉強したのですが途中でやめてしまいました。理系大学で3年も第二外国語をやる学生なんてほとんどおらず、周りはフランス語圏に留学したい人しか残っていなかったので、最初は楽しかったのにだんだんと肩身が狭くなってしまいました。でも就職してからは自分なりの方法を考えながら勉強できるので楽しいです。

話は変わりますが、TOEIC 900点並の翻訳機なんて話題が今日出てましたね:

www.asahi.com

翻訳機が便利なのは間違いないんですが、スマートフォンで Google が翻訳してくれるものでも十分便利だし、教師データを考えても Google には敵わない気もするので政府が予算を使ってまですることかというと疑問です。オリンピックについて言及されているので、日本国内での特定用途特化したデバイスを目指しているんでしょうか。

Go言語での時刻処理

stackoverflow.com

time パッケージがとても便利なのですが、オブジェクトに「分」を表す int フィールドがあって、その Duration オブジェクトを作りたいときに少し手間取りました。 intValue * time.Minute だと int Duration の間に乗算が定義されていないのでエラーになってしまうので、 time.Duration(intValue) * time.Minute として DurationDuration の乗算にすることで解決できました。

3 * time.Minute のような数字がリテラルの場合は変数型が決まっていない状態なのでコンパイルできるのですが、一度変数に入れてしまうと型が定まってしまうので、暗黙的な型変換になれていると戸惑います。

2018/11/01 クロスコンパイルとリリース

ハロウィンについてフィリピン人の英会話の先生と話をしていたら、フィリピンは世界でもっともクリスマスを長く祝う国?らしく、9月1日からクリスマスのデコレーションをするのだとか。ハロウィンもハロウィンで仮装して騒いで楽しむらしく、10月末はハロウィンとクリスマスが混在するようです。

11月からクリスマスなんて早いなぁと思っていましたが、それよりはるかに長い期間クリスマスを祝う国があると知っておどろきました。日本のお正月準備はクリスマスの後ばたばたと始まるので、フィリピンのようにイベントを重ねてやったらどうかなと一瞬考えましたが、和と洋で頭がおかしくなりそうなのでハロウィン・クリスマスほどは上手く行かなそうです。。

リリースの仕方

リリースの仕方について調べていたところ、以下のブログ記事がとても役に立ちました。

golang勉強会でGo製ツールの配布方法について話してきた | SOTA

Go言語ではクロスコンパイルしてさまざまなプラットフォーム向けのバイナリファイルを生成できるのですが、それをまとめて行える gox コマンド、そしてそれを GitHub へリリースする ghr コマンドなどが紹介されています。

speakerdeck.com

gox コマンドは -output オプションで出力ファイル名を指定できます。出力ディレクトリを指定するわけではないので、例えば以下のようにすると dist/ ディレクトリ以下に成果物が出力されます:

$ gox -os "linux" -output="dist/{{.Dir}}_{{.OS}}_{{.Arch}}" ./...

ghr コマンドはパブリックな GitHub を想定しており、GitHub EnterPrise(GHE) で利用する場合には環境変数を利用する必要がありました:

$ GITHUB_API=https://<GHEのドメイン>/api/v3/ GITHUB_TOKEN=<トークン> ghr <バージョン> <リリース対象ディレクトリ>

トークンは以下の公式ページで紹介されているやり方で、GUI からトークン生成可能です:

Creating a personal access token for the command line - User Documentation