Javaの単一ファイル実行を試してみる #Java

概要

みんなの Java 読んでいたら、Java の単一ファイル実行試してみたくなったのでやってみた。

環境

Mac で試した。

Java のバージョンは12。

$ java -version
openjdk version "12.0.1" 2019-04-16
OpenJDK Runtime Environment (build 12.0.1+12)
OpenJDK 64-Bit Server VM (build 12.0.1+12, mixed mode, sharing)

単一ファイルで実行してみる

下記のようなファイルを App.java という名前で用意する

package myapp;

public class App {
    public static void main(String... args) {
        System.out.println("Hello");
    }
}

実行してみる。

$ java App.java
Hello

すごい。。感動する。

Shebang として実行する

手順は下記の通り

  1. 先頭に Shebang を書く
  2. ファイル拡張子を外す
  3. ファイルに実行権限をつける
#!/usr/bin/env java --source 12
package myapp;

public class App {
    public static void main(String... args) {
        System.out.println("Hello shebang Java!");
    }
}

Shebang--sourceJava のバージョンの指定が必要らしい。

$ mv App.java app # 拡張子を外す
$ chmod +x app    # 実行権限をつける

実行してみる。

$ ./app 
Hello shebang Java!

すごい!

小さなプログラムも Java で書きやすくなった!

Localstack の SQS を使ってみる #AWS

概要

AWS サービスの Mock ツール、LocalStack で Amazon SQS を使ってみました。

かんたんに扱えるので、ローカル環境での開発等に重宝しそうです。

github.com

Localstack の構築

いろんなやり方があるようですが、 docker-compose でやるのが楽そうです。

本家の docker-compose.yml を適当なディレクトリに配置して起動します。

https://github.com/localstack/localstack/blob/master/docker-compose.yml

TMPDIR=/private$TMPDIR docker-compose up -d

Mac で起動する場合、 $TMPDIRシンボリックリンクが含まれており、 Docker でマウントできないため、書き換えて起動します。

起動に成功すると、ブラウザからリソースが確認できるようになります。

http://localhost:8080/

awscli-local の導入

localstack を操作しやすいように awscli-local を導入します。

github.com

awscli だけでも使えるんですが、 --endpoint-url をいちいち指定する必要がなくなります

pip install awscli-local

キューの作成

SQS に local-sqs-sandbox という名前でキューを作成してみます。

awslocal sqs create-queue \
  --queue-name local-sqs-sandbox

キューを作成するとブラウザからも確認できるようになっているはずです。

f:id:su-kun1899:20200426212920p:plain
こんな感じ

メッセージの登録

作成したキューにメッセージを登録してみます。

awslocal sqs send-message \
    --queue-url http://localhost:4576/queue/local-sqs-sandbox \
    --message-body "test localstack sqs"

登録後、取得してみるとメッセージが取得できます。

awslocal sqs receive-message \
    --queue-url http://localhost:4576/queue/local-sqs-sandbox

もちろん削除もできます。 (ReceiptHandle は recieve すると分かります)

awslocal sqs delete-message \
    --queue-url http://localhost:4576/queue/local-sqs-sandbox \
    --receipt-handle "{ReceiptHandle}"

補足

  • docker-compose.yml環境変数をいじることで、起動するサービスを制限したり、Portを変更したりできます
  • Localstack は一部サービスを除いて永続化に対応していないため、基本的に停止したらリソースはいなくなります

「テスト駆動開発」を読んだ

テスト駆動開発

テスト駆動開発

  • 作者:Kent Beck
  • 発売日: 2017/10/14
  • メディア: 単行本(ソフトカバー)

自分程度のキャリアでも、テストを取り巻く環境は大きく変わったと思う。

テストコードは多くの場所で当たり前になった。

それでも、日々のプログラミング(テストコードに限らない)で「こういった場合はどう書くのがよいだろう」と考えるとき、この本の内容が今でも大きな助けになる。

t-wada さんによる訳者解説も面白くて役に立つ。

「みんなでアジャイル」を読んだ

みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた

みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた

  • 作者:Matt LeMay
  • 発売日: 2020/03/19
  • メディア: 単行本(ソフトカバー)

同僚の何人かが読んでいたので手にとってみた。

アジャイル」という言葉は「単なる方法論」あるいは「宗教のような何か」と誤解されがち。

そんな「アジャイル」の根本的な価値観を職種問わずわかり易い言葉で説明している。

またそれを実現する組織にするためのヒントが散りばめられていた。

アジャイルマニフェストの成り立ちにまで言及しているところにとても好感がもてる。

ページ数もそんなになくてサクッと読めた。

その代償なのだろうけど、エンジニアリングと絡むような(技術的な)側面への言及はほとんどない。

コンウェイの法則的な話もあるけど、こういった組織論を語るときに一緒にテーブルに乗っていないと、個人的には何か片手落ちな気がしてしまうのであった。

この本で特によいなぁと思ったのは、組織構造の問題点に触れているところ。

構造の観点が最近自分の中でもホットなので、読んだタイミングがよかったのかもしれない。

「そう振る舞うことが自然」という構造にすることが、組織づくりにおいてとても大切な気がする。

みんなでアジャイル読書メモ · GitHub

SQL アンチパターンを読んだ

SQLアンチパターン

SQLアンチパターン

  • 作者:Bill Karwin
  • 発売日: 2013/01/26
  • メディア: 大型本

ちょこちょこつまみ読みはしていたけれど、改めて通しで読んでみた。

そこそこキャリアのある人であれば、どこかで見かけ、そして苦しめられたパターンがいくつかあると思う。

この本がとてもいいなぁと思ったのは、アンチパターンがなぜよくないか、どういうデメリットがあるかということを言語化してくれているということ。

「当然これはやらない方がよい」と考えたことでも、それを明確に論理立て、かつ具体的に人に伝えるというのはすごく難しい。

この本があることで、少なくとも議論の前提が揃えられるというのは大きいと思った。

SQLアンチパターン読書メモ · GitHub

1365. How Many Numbers Are Smaller Than the Current Number

LeetCode の挑戦ログ

Problem

https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/

  • 数字の配列が与えられる
  • それぞれの値より少ない値がいくつ含まれているか数える
  • その数を同じ index の配列にして返す

Solution

class Solution {
    public int[] smallerNumbersThanCurrent(int[] nums) {
        return Arrays.stream(nums)
                .map(base -> (int) Arrays.stream(nums).filter(num -> num < base).count())
                .toArray();
    }
}

Impressions

  • count に詰め替えているところは可読性を考えると関数に切り出してもいいかも
  • 結局コードの考え方としては総当たりに近いのでもうちょっといいアプローチがありそう

1342. Number of Steps to Reduce a Number to Zero

LeetCode の挑戦ログ

Problem

https://leetcode.com/problems/number-of-steps-to-reduce-a-number-to-zero/

  • 正の整数が渡される
  • 偶数なら 2 で割る、奇数なら 1 を引く
  • 0 になるまでの回数を数える

Solution

class Solution {
    public int numberOfSteps(int num) {
        return countSteps(num);
    }

    private int countSteps(int num) {
        int steps = 0;
        while (num != 0) {
            num = reduce(num);
            steps += 1;
        }

        return steps;
    }

    private int reduce(int num) {
        return num % 2 == 0 ? (num / 2) : (num - 1);
    }
}

Impressions

  • 最初は再起で書いたけど、ループに書き直した
  • Java には言語での末尾再帰最適化はないらしい
  • Kotlin の tailrec は便利だな

再起で書いたやつ

class Solution {
    public int numberOfSteps(int num) {
        return countSteps(num, 0);
    }

    private int countSteps(int num, int steps) {
        num = reduce(num);
        steps += 1;

        if (num == 0) {
            return steps;
        }

        return countSteps(num, steps);
    }

    private int reduce(int num) {
        return num % 2 == 0 ? (num / 2) : (num - 1);
    }
}