WebAssemblyにコンパイルしたRustコードにJavaインタフェースをマッピングする

Chicoryを使ってRustをコンパイルしたwasmをJavaから呼び出してみました。
JVMでWebAssemblyにコンパイルしたRustのコードを動かす - きしだのHatena

ただ、結構呼び出しがめんどいので、Javaインタフェースを定義したらなんかメソッド呼び出しで使える、というよく見かけるやつを作ってみます。

Rustのコードはこう。

#[no_mangle]
pub fn add(left: i32, right: i32) -> i32 {
    left + right
}

#[no_mangle]
pub fn sub(left: i32, right: i32) -> i32 {
    left - right
}

#[no_mangle]
pub fn mul(left: i32, right: i32) -> i64 {
    (left as i64) * (right as i64)
}

こんなJavaインタフェースで呼び出せるようにしたい。

interface RustFuncs {
    int add(int left, int right);
    int sub(int left, int right);
    long mul(int left, int right);
}

ということで、こんな感じでProxyを作る。

static <T> T bind(String name, Class<T> type) {
    var wasm = CallWasm.class.getClassLoader().getResourceAsStream(name);
    var module = Module.builder(wasm).build();
    var instance = module.instantiate();

    T obj = (T) Proxy.newProxyInstance(type.getClassLoader(), new Class<?>[]{type}, 
            (p, m, a) -> methodHandler(instance, type, p, m, a));
    return obj;
}

static Object methodHandler(Instance ins, Class type,
        Object proxy, Method method, Object[] args) throws Throwable {
    var m = ins.export(method.getName()); // todo:use annotation name
    List<Value> values = new ArrayList<>();
    for (int i = 0; i < args.length; ++i) {
        values.add(switch (args[i]) {
            case Integer n -> Value.i32(n);
            case Long l -> Value.i64(l);
            default ->throw new RuntimeException("unknown type " + method.getParameterTypes()[i]);
        });
    }
    var result = m.apply(values.toArray(Value[]::new))[0];
    var rt = method.getReturnType();
    if(rt == long.class || rt == Long.class) {
        return result.asLong();
    } else if (rt == int.class || rt == int.class) {
        return result.asInt();
    } else {
        throw new RuntimeException("unknown ret type " + rt);
    }
}

こうやって呼び出せるようになりました!やったね!

public static void main(String[] args) throws IOException {
    var rf = bind("hello_wasm.wasm", RustFuncs.class);
    System.out.println(rf.add(12, 34));
    System.out.println(rf.sub(34, 12));
    System.out.println(rf.mul(100_000_000, 100_000_000));
}

文字列とかはwasmでは定義されてなくて結構めんどいので、そのあたりはもう少し考えてみます。
使い物になりそうだったらasmかJavassistバイトコード生成を。

ITが面白い時代はすでに終わっているし変化も遅くなった

ITはもう面白くなくなってますね。
技術が面白いときには、いろいろ新しいものが出て性能あがったりできることが増えたりします。調べたらどんどん新しいものが出てくるし、新しいものもたくさん作るし、面白い。ですが、IT技術は一通り出そろって、成熟期に入っています。そうすると新しい技術に出会うことも新しいものを作ることも減っていきます。その結果、いままでの変化のあった状況を知っていれば、つまらんってなりますね。

※2024/8/24 追記 言いたいことをまとめると、IT素振りのネタ探しに苦労するようになったよねってことです。

結局のところITというのは新しいハードをどう動かして社会に実装していくかというものなので、新しいハードが出ないとどうしようもないのです。けれどもだいたい飽和してしまった。

雑にいえば、これまで1980年くらいにBASIC搭載8bitパソコンが普及するとBASICプログラミングが流行り、1990年くらいにパソコンが32bit化するとGUIシステムが使い物になるようになってWindowsやそのうえで動くソフトの開発が流行り、2000年くらいから常時接続インターネットが広まり始めたりiモードなどモバイルインターネットが可能になってネットワークサービスの開発が流行りブログや2chのような文字ベースのサービスが広まって、2005年くらいからマルチコアのプロセッサが広まると仮想化やらクラウドの流れが本格化してmixiのようなSNSが大規模化して、2010年くらいにスマホが広まって4Gでモバイル通信も速くなって動画サービスが当たり前になり、2017年のTikTokくらいでゴール、みたいな感じですね。

その流れから、使われる技術も対応して進化しつつ、プログラミング言語も2014年のSwift以降は広く使われるようなものは出てきていないし、実行基盤も同じ年に出てきたKubernetesで、だいたいの技術は出そろったという感じになっています。

ライブラリやツールも、欲しいものはだいたいすでにあるという状況。オープンソースにコミットしようにもすでに巨大になりすぎてさわれない。

さすがにメシの種がなくなったということで、VRとかブロックチェーンとか5Gとかに目をつけてWeb3として注目されたものの、そこまで流行らなかったですね。

サービス開発の裏で、いつの間にか超並列プロセッサになっていたGPUを使って科学計算しようぜーというのが2007年のCUDAで流行りだして、2011年にディープラーニングがいわれるようになって、見えないところで写真をきれいにしてくれたりラーメン次郎を識別してくれたりというのが発展しつつ、2022年にさっそうと現れたChatGPTによってAIバブルが発生し、つい先日はじけました。

ChatGPTは期待され初速こそ2ヵ月で1億ユーザーを獲得したと話題になりましたが、教育か開発で使われるサービスという感じに落ち着いて、日常生活を変えるかというとそこまで変わらない。
それを使って勉強なり開発なりした人が「新しいサービス」を作らないと世界が変わらない、GitHubに近い位置づけに思います。

もちろん、開発のやりかたとかへの影響は大きいとは思うのだけど、結局「じゃあそれでなにを作るの?」というところが面白くならなければ、「作業のやりかたの話ばかりになってつまらん」というのは変わらない気がする。

ちなみにAIまわりのオープンソースはちょっとさわるとすぐ治せるバグが見つかるし便利機能も実装しやすいのでコミットしやすく最後の楽園っぽさはありますが、それゆえ参加者が多すぎてすぐ食い尽くされそう。

あと、ITでお金を稼ぐには広告一択、にもなってますね。つまり、IT自体ではお金を稼ぐ能力が弱くて、物理サービスの売上を広告で助け、そこで稼がれたお金をもらって成り立つ業界です。

その結果で、面白いことといえば既存産業をITで強くするというDXのようなものが流行り、新しいサービスというのも車がやってきたり料理がやってきたりスキマ時間に働けたり、物理サービスをより最適化するような、どちらかというとITは裏方になったものが多くなってきてますね。

なので、新しいものが出て楽しいというのはもう終わって、IT自体を楽しまないといけない時代、もしくはビジネスを楽しまないといけない時代になっていると思います。

※追記 何人かやりとりして思ったのだけど、ITがようやく道具として使い物になってきたということなのかもな。

JTCは英語の「正しい」語順としてもJTCじゃないんだろうか

JTC、つまりJapanese Traditional Companiesのことですが、英文法チェッカーが「Traditional Japanese Companiesでは?」みたいな指摘をしてきたり、TJCのほうが正しいという話がありますね。

英語の文章でどのような語順で出てくることが多いか数えてTJCのほうがいいのではとしているブログもありました。

けれども、ここでJTCというのは、次の日経記事にあるよう「上意下達の企業文化や硬直的な組織運営を皮肉る際に使われます」という言葉です。
JTC(Japanese Traditional Company)とは? 古い企業体質、変革を模索 - 日本経済新聞

英語でTraditional Japanese Companiesが正しいというには、それが古い企業体質を皮肉る文脈で使われている必要があります。けれどもそんな文脈はほとんどないんじゃないかと。

JTCって、西暦578年創業の金剛組とか西暦1707年創業の赤福とかの話をしたいわけじゃないです。金剛組赤福を言いたいのであれば、Traditional Japanese Companiesでいいと思います。

JTCは「伝統的な日本企業」ではなく「日本のよくある古い企業」を指しているので、Japanese Traditional Companyでいいんじゃないかと思います。少なくとも、「英語でよくつかわれるのはTraditional Japanese CompaniesだからTJCが正しい」というのは根拠にならないんではないかと。

JVMでWebAssemblyにコンパイルしたRustのコードを動かす

Chicoryを使うとJVM上でWebAssemblyを動かせるということで、RustからWebAssemblyにコンパイルしたコードを動かしてみます。

このときはRustをLLVMビットコードにしてGraalVMで動かしていましたね。
GraalVMでRust動かしたりレイトレをネイティブコンパイルしたり - きしだのHatena

Rustからwasmを作成

まずはRustのプロジェクトを作成。

>cargo new --lib hello-wasm
    Creating library `hello-wasm` package

lib.rsというファイルが作成されてadd関数が定義されているので、no_mangleをつけてu64をi32にします。

#[no_mangle]
pub fn add(left: i32, right: i32) -> i32 {
    left + right
}

そしたらビルド

hello-wasm>cargo build --target=wasm32-unknown-unknown --release
   Compiling hello-wasm v0.1.0 (C:\Users\naoki\Desktop\hello-wasm)
    Finished `release` profile [optimized] target(s) in 0.44s

ブラウザで試す

とりあえずブラウザで動かしてみます。こんなJS入りHTMLを書く。

<html>
<head>
 <title>Hello wasm</title>
 <script>
   const wasm = "./target/wasm32-unknown-unknown/release/hello_wasm.wasm"
   fetch(wasm)
    .then(res => res.arrayBuffer())
    .then(b => WebAssembly.instantiate(b, {}))
    .then(res => {
      alert(res.instance.exports.add(2, 3))
    })
  </script>
</head>
</html>

さて、fetchでwasmを読み込んでいるけど、これはファイルシステム経由での読み込みができないので、Webサーバーが必要です。

ここでJava 18で導入されたjwebserver。 https://openjdk.org/jeps/408

ただ、Windowsで起動すると文字化けるです。

hello-wasm>jwebserver
繝・ヵ繧ゥ繝ォ繝医〒繝ォ繝シ繝励ヰ繝・け縺ォ繝舌う繝ウ繝峨@縺セ縺吶ゅ☆縺ケ縺ヲ縺ョ繧、繝ウ繧ソ繝輔ぉ繝シ繧ケ縺ァ"-b 0.0.0.0"縺セ縺溘・"-b ::"繧剃スソ逕ィ縺励∪縺吶・
C:\Users\naoki\Desktop\hello-wasm縺翫h縺ウ繧オ繝悶ョ繧」繝ャ繧ッ繝医Μ繧・27.0.0.1繝昴・繝・000縺ァ菴ソ逕ィ縺励∪縺・URL http://127.0.0.1:8000/

別にコンソールなので文字化けさせておけばいいのだけど、気になるのでchcpコマンドでUTF-8にしておきましょう。

hello-wasm>chcp 65001

気を取り直してjwebserverの起動。

hello-wasm>jwebserver
デフォルトでループバックにバインドします。すべてのインタフェースで"-b 0.0.0.0"または"-b ::"を使用します。
C:\Users\naoki\Desktop\hello-wasmおよびサブディレクトリを127.0.0.1ポート8000で使用します
URL http://127.0.0.1:8000/

http://localhost:8000/hello.htmlにアクセスすると、なんかWebAssemblyが動いてるっぽい。

Chicoryの導入

では、JVMでWebAssemblyを動かすChicoryを導入します。
https://github.com/dylibso/chicory

readmeに従ってdependencyを追加します。

<dependency>
  <groupId>com.dylibso.chicory</groupId>
  <artifactId>runtime</artifactId>
  <version>0.0.12</version>
</dependency>

Javaコードで動かす

では、試しに動かしてみましょう。targetの下の方にhello_wasm.wasmができているので、src/main/resourcesにコピーしておきます。

そして次のコードを。ちなみに、現状のChicoryのreadmeに書いてあるParser.parseを使ったサンプルは、まだ配布バイナリに反映されていません。古い書き方で書く必要があります。

import com.dylibso.chicory.wasm.types.Value;
import com.dylibso.chicory.runtime.Module;
import java.io.IOException;

public class CallWasm {
    public static void main(String[] args) throws IOException {
        var wasm = CallWasm.class.getClassLoader().getResourceAsStream("hello_wasm.wasm");
        var module = Module.builder(wasm).build();
        var instance = module.instantiate();
        var add = instance.export("add");
        
        var result = add.apply(Value.i32(3), Value.i32(2));
        System.out.println(result[0].asInt());
    }
}

実行すると5が表示されて、なにか動いてそう。

まとめ

この記事ではSQLiteをwasmにコンパイルして動かすということもやってます。Cで書かれたコードをJavaで動かしやすくなりそうで、なかなかよさそうですね。
https://www.infoq.com/articles/sqlite-java-integration-webassembly/

ただ、パフォーマンスが必要ならおとなしくネイティブバイナリ使いましょうということになると思うので、テスト用とかですかね。

ソフトウェアの「詳細設計書」とはなんなのか

「設計書」というのは、作るものの構造を抽象的に表現したものと言うことができます。
ただ、ソフトウェアの抽象化の仕組みはプログラミングコード自体に備わっているので、ソフトウェア生成可能な抽象的表現というのはコード表現ができるはずですね。コードで表現しておくと、整合性のチェックとかも行いやすいです。
でも、コードではない「詳細設計書」というものが一部業界には必要とされているので、その「詳細設計書」というのは実際はなんなのか考えてみます。
※ 最初はタイトルは「設計書」としてましたが、話を限定するため「詳細設計書」に変更しました。
追記:納品物に関する記述を追加しました。

表現を変えたコーディング

ソフトウェア生成可能な抽象的表現というのはコード表現ができるわけですが、文字で表記する必要もなく、ダイアグラムで表現することもできますね。

代表的なのがER図やクラス図で、これは文字表現との相互変換が可能です。クラス図はclass定義から生成したほうが楽だったり、DB定義は図でやるほうが楽だったりします。
処理については、フローチャートやScratchがありますね。
画面仕様も、最初から画面デザイナでやっておけばーという気持ちになったりします。

その点では、このような文書を作る「設計」の作業は、プログラミング作業を表記を変えて前倒しでやっているとも言えます。
実装可能性を高めれば高めるほど、プログラミングに近づきます。実装力が低いプログラマを想定するときは、一度実装したものを書き起こす、みたいな話を聞いたりもしますね。

机上プロトタイプ

設計書が表現を変えたコーディングであるなら、その検証作業は机上での実行シミュレーションになりますね。ということは、設計書というのは、机上プロトタイプであるとも言えます。
それであれば、最初からソフトウェアとしてプロトタイプを作ればいいのではという気もしますが、ソフトウェア実装しようとすると、つい作りこんでしまいがちなので、ちゃんと動かない環境でやるのも大事だったりします。
設計作業と言われるものは、ペーパープロトタイピングに近いかもしれません。
ペーパープロトタイピング 最適なユーザインタフェースを効率よくデザインする

分析資料

ハードウェアを作るときに状態遷移の設計が必要というやりとりをしたことがあります。
現実世界との接点になるソフトウェアでは現実世界とのやりとりの状態を管理する必要があるので、状態遷移が大事になります。

ただ、そういった資料を作るときの作業は、「どう作るか」を考える設計作業というより、「どうなっているか」を考える分析作業としたほうがいいんじゃないかと思います。そのため、その過程ででる「設計書」は分析資料に近くなるように思います。

この場合は、設計というよりは、仕様や定義としたほうが適切な場合も多そうです。

保守資料

「設計書」の必要性について触れると「メンテナンスのときに必要」という話がたびたびでてきますね。納品物になるときに期待されるのも、メンテナンス資料という位置づけが多いと思います。
でもまあ、メンテナンスのための保守資料なら事前に作る必要はなく、事前につくると開発作業中に同期をとるのが面倒ということを考えれば、完成が近づいたころか完成したあとに作るほうがいいと思います。

1992年にC++ Jounalに載った「What Is Software Design?」というエッセイは、「コーディングは設計」というようなことが書いてありますが、「設計ドキュメントをコードの前ではなく後に書くとはるかに正確なドキュメントが作成されるということを、全てのプログラマが知っています」と書かれていますね。
https://www.developerdotstar.com/mag/articles/reeves_design.html

コードとの同期を考えるとコメントを書いて自動生成がいいんではないかと。概要がわからないならChatGPTにコード全部なげて聞きましょう。
保守を考えるなら、こういった資料をがんばるよりは、プロダクトコードについての質問に答えてくれる、クローズドに使えるサービスのほうが大切になりそう。

作業指示書

SESで行われる「SE」と「PG」が分かれた水平分業では、コードを書く人への作業指示が必要になりますね。
「詳細設計書」にまつわる話は、基本的に水平分業由来であることが多く、ソフトウェアの性質から来るものというよりSESという業務形態で必要なビジネス文書であるように思います。

契約資料

多重下請け構造だと、「SE」と「PG」は別会社になるので、そうすると上記の作業指示書は会社をまたがった契約資料にもなります。納品物になるときには、問題が起きたときに責任を後から追跡できる資料にもなりうるという点では、契約資料としての納品という面もあるかも。
「PG」が勝手に設計を変えてはいけない、変えるにしろ確認が必要、という話には、トラブルが起きたときの責任という話がついてきて、つまり「設計書」が契約資料でもあるからですね。
「詳細設計書」について「ソフトウェア開発作業として、なんか変なこと言ってるなぁ」と思うときには、だいたいこの契約資料としての性質によるものな気がしています。

ところでこの本、Jackson法をベースにデータフロー->モジュール化->ふるまい定義と、かなりいい感じにまとまってるのだけど、ここで書いたような「設計書」の書きかたを求める人の需要は満たせなかったようで評価低い。

プログラミングが設計作業であるという話

いわゆる「ソフトウェア設計書」が設計ではなく、ソースコードが設計であるという話。
随筆です。考えマトメ中なので、ツッコミはそのあたり踏まえていただければ。

追記:ブコメに「設計の定義は?」とあったので末尾に追加しています。

追記(2024/8/15):設計書ってなんだろう?というのも書いておきました。
ソフトウェアの「設計書」とはなんなのか - きしだのHatena

このエントリで書いたのですけど、もうすこしちゃんと。
建築では多重下請けでやれてるのに業務システムでだめなのはなぜ? - きしだのHatena

このエントリでは次のように書いています。まあ、これで全てではあるのだけど。

「建築などの施工図面に相当するのはソースコードで、建築現場で多重下請けでやってる作業は、ソフトウェアだと(でも?)ビルドです」

あと「継続的デリバリーのソフトウェア工学」からの抜粋。

「継続的デリバリーのソフトウェア工学」では、「ソフトウェア開発を選んだ私たちがバカでない限り、私たちにとっての製造とは、ビルドボタンのクリックです」とあります

ところでほんと、売るために「継続的デリバリーの」をつけたことで売れなくなってるんじゃないかという気がするが、それは余談。

まあ、言いたいのは、ソフトウェア作成作業というのは、ハードウェア上で手続きを動かすことが最終成果であって、ソースコードや実行バイナリを作るのが目的ではないのですよ、ということ。
(「ソフトウェア作成というのは~」と書くと「いや、企業が利益を出すことが~」みたいなツッコミがたぶん来るので、「ソフトウェア作成作業」としてます)

10年前に「ソフトウェア工学は失敗している」と書いたときに思いのほか異論が出ていなかったのだけど、「継続的デリバリーのソフトウェア工学」でも「ソフトウェア工学は、重々しいくせにソフトウェア開発のプロセスに大した付加価値を与えてくれるわけではありませんでした」と書いてたり、やはりうまくいってなかった模様
ソフトウェア工学は失敗している - きしだのHatena

これは、ソフトウェア開発の目的を、暗に実行バイナリを作るところまでのようにとらえていたからじゃないかという気がします。2022年改訂の「ソフトウェア工学の基礎 改訂新版」でも、目次は次のようになっていて、一旦完成したあとの変更作業は「保守・進化」のように付加的な位置づけになっています。ソフトウェア工学の本の標準的な目次です。

第1章 ソフトウェアとソフトウェア工学
第2章 ソフトウェアプロセス
第3章 要求工学
第4章 モデル化技法とUML
第5章 データと制御の流れモデル
第6章 動的振舞いモデル
第7章 オブジェクト指向モデル
第8章 形式手法
第9章 設計技法
第10章 検証技術
第11章 ソフトウェアの保守・進化
第12章 開発環境とツール
第13章 安全・安心な社会のためのソフトウェア
第14章 プロジェクト管理

これは、受託開発やパッケージを想定して作られているともいえますが、ソフトウェアが比較的小規模で単純であったときには成り立っても、いまはもうあてはまりにくくなっています。

実際には、GitHubでプルリクをベースにCI / CDをまわして常時クラウドにデプロイしつつ、メトリクスをとり、負荷に合わせてサーバーを伸長縮退しながら動かし、コードを常に変更していくというのは、もはや開発作業の主要部分になっています。

要求工学やモデル化や設計技法が必要なフェーズはその「開発作業」の最初、むしろその開発作業に入る前に必要な事前作業ではないかという感じがします。

と書くと、「いや業務システムでは~」みたいなツッコミ入りそうですが、そこで決めるのは業務プロセスだったりして、ソフトウェアと密接ではあるものの、ソフトウェア一般の話ではなかったりもする。

まあ、ソフトウェア開発の技術というのは複雑さに立ち向かう技術でもあるので、業務プロセスの構築にも役に立つというか、業務プロセス構築とソフトウェア開発の区別はつきにくい、というのはさておき。

そして、CI/CDまわしてメトリクスとってといったことは、「ソフトウェア工学」ではあってもオマケ程度で、ほとんど触れられていません。

ともかくとして、先ほどサーバーを伸長縮退しながら動かすということを書いたけど、これも手作業でやっては間に合わないので設定なりなんなりコード化するわけですね。手続きの指定はもちろんコードで書きます。

そして、そういったコードは、書いてみるまでわからない、書くことでわかる、動かしてみてわかるということも多いです。

テスト駆動開発では、テストと共にコードを書くことで正しい設計に近づくということがコンセプトですが、テスト駆動ではないにしろ、コードを書かないことには正しい設計には近づかないのは確かではないかと。

そうすると、そういったコードそのものが設計であって、そのコードを書くプログラミングが設計作業なのではないかと思います。

-- -- ここからは追記 -- --
追記:ブコメにあって思い出したのだけど、設計という言葉には構造やアーキテクチャという意味と、その構造やアーキテクチャを事前に決めたものという意味があるのだけど、ここでは前者です。あと、よく言われるコーディングを伴わない事前作業としてのソフトウェア設計は、構造やアーキテクチャを決めきれておらず、その意味での「設計」になってないんじゃないかというのもありますね。大体は作ることを決める仕様決めの作業になってる。
つまりここでの「設計」は「どう作るか」「どのように作られているか」をあらわすもののはずで「何を作るか」ではなく、プログラムがどのように作られているか示すのはコードであるという感じですね。

追記:「設計書」もコードもどちらも設計では?っていうコメントあるけど、確かにその面もあって、「設計」ってコーディングの一部を表記変えてやってる面もある。クラス図とかはclassに変換可能で、なんならclassって書いたあと自動生成して「設計書で~す」ってやったりする。

追記:脱線ではあるけど、この文脈を作曲いいかえるとしても、「作曲は音源を作ることが最終成果で譜面を作るのが目的ではない、譜面は設計である」みたいになるように思います。実際、いまの音楽はほとんどが譜面記載できない音の塊で、演奏してナンボみたいなところがあると思います。
追記の追記:
音楽が商業にのるようになった時期は録音技術もなく楽譜を売ることが目的だったので、楽譜が最終成果だったわけですが、今どきの作曲は他者による再演は想定されてなく、ミックスまで含めた録音こそが最終成果になってますね。DTMでも。

追記: 建築でも現場でいろいろ変えるという指摘があるけど、柱の位置を変えたり増減するような構造部分の変更はせず、フィッティングの調整のような感じなんじゃないかと思います。その点では、コンパイル時の最適化に相当するんではないかと。コンパイラの自由度はかなりあって、コンパイラコンパイルオプションによって性能やバイナリサイズに差が出たりしますね。

追記(2024/8/15):ソースコードが設計であるという話は1992年にC++ Journalに載ったエッセイが古いものとしては有名です。
「コーディングは設計であり、テストとデバッグは設計の一部であり、私たちが通常ソフトウェア設計と呼ぶものもやはり設計の一部」
「設計ドキュメントをコードの前ではなく後に書くとはるかに正確なドキュメントが作成されるということを、全てのプログラマが知っています」
https://www.developerdotstar.com/mag/articles/reeves_design.html

「プロになるJava」補足記事まとめ

プロになるJava」の補足記事のまとめです。

練習問題の答え

「プロになるJava」 第2部「Javaの基本」の練習問題解答 - きしだのHatena
「プロになるJava」 第3部「Javaの文法」の練習問題解答 - きしだのHatena
「プロになるJava」 第4部「高度なプログラミング」の練習問題解答 - きしだのHatena

GitHub Codespacesでの手順

環境設定
GitHub CodespacesでJava開発を始める - きしだのHatena

Spring Boot
GitHub CodespacesでSpring Bootの開発を始める - きしだのHatena

API

日付時刻の処理
Java Date Time APIでの和暦の扱い、ロケール、タイムゾーン - 「プロになるJava」 ボツ原稿 - きしだのHatena

条件分岐

論理演算と論理思考(not ロジカルシンキング)
プログラミングは論理的思考の訓練になるか - 「プロになるJava」ボツ原稿 - きしだのHatena

繰り返し

do-whileなどの補足
do whileやwhileなど繰り返しの補足 - 「プロになるJava」ボツ原稿 - きしだのHatena

データ構造の処理

値の処理の集合のパターンに2つ記事を追加
データ構造の処理のパターンとStream - きしだのHatena

難しい処理

カッコが対応しているかどうか判定する
カッコが対応しているかどうか判定する - 「プロになるJava」ボツ原稿 - きしだのHatena

移動平均とスライディングウィンドウ
移動平均とスライディングウィンドウ - 「プロになるJava」ボツ原稿 - きしだのHatena

アルゴリズムや計算量について
アルゴリズムと計算量 - 「プロになるJava」ボツ原稿 - きしだのHatena

Maven

外部ライブラリの使い方として、JacksonとRetrofitを使う例
JacksonとRetrofitで郵便番号APIを呼び出す - きしだのHatena

データベース

JOINやGROUP BY、ORDER BYの解説
SQLのJOINとGROUP BYを試す - きしだのHatena