memo
とりあえずこれ使った
https://github.com/rust-lang/mdBook
センキュー
https://www.bioerrorlog.work/entry/mdbook-github-pages-cd
メモ書きに使っていこうかな…
git
前略、git使ってますか?初歩的なポイントとよく使うコマンドを覚えてしまいましょう。
はじめに
- 初心者向けです
- あまり使ったことがない
- tortoise Git とかでやってる
- commit pull push をよくわからないが使っている
みたいな人向けです。
基本的なところ
git はローカルリポジトリと、外部のリポジトリであるリモートリポジトリの二つに分けられる。
例えば、このドキュメントを管理しているローカルリポジトリは.git
だし、リモートリポジトリは下記で確認できる。
➜ git remote -v
origin https://github.com/nichijo/nichijo.github.io.git (fetch)
origin https://github.com/nichijo/nichijo.github.io.git (push)
gitは、ローカルリポジトリだけで動作できる。
svnはサーバ上で生きていく存在だが、gitはただ、任意のディレクトリでgit init
とコマンドを打てばリポジトリが生成され、管理できる。
生まれたばかりのローカルリポジトリに、任意のファイルを管理させるには下記のようにする。
git add ./anyfiles.txt
git commit -m "commit message."
この時点でコミットログは下記の通りとなる。
gitGraph
commit id: "HEAD" type: HIGHLIGHT
再度任意のファイルを変更/追加してコミットするとこうなる
gitGraph
commit
commit id: "HEAD" type: HIGHLIGHT
add + commit
add
は、任意のファイルをコミット対象とするかどうかを決める。
例えば、前回のコミットから、ローカルファイルに以下のファイルの変更があったとする。
- book.toml
- src/SUMMARY.md
- mermaid-init.js
- mermaid.min.js
- src/2023-04-07.md
どう変化しているかは git status
コマンドで確認できる
➜ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: book.toml
modified: src/SUMMARY.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
mermaid-init.js
mermaid.min.js
src/2023-04-07.md
no changes added to commit (use "git add" and/or "git commit -a")
以下は、以前のコミットから変更があったようだ
- book.toml
- src/SUMMARY.md
こちらは、新規のファイルのようだ
- mermaid-init.js
- mermaid.min.js
- src/2023-04-07.md
git add
を使うと、この中から一部だけコミットすることができる
➜ git add .\book.toml .\mermaid-init.js .\mermaid.min.js
➜ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: book.toml
new file: mermaid-init.js
new file: mermaid.min.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: src/SUMMARY.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
src/2023-04-07.md
➜ git commit -m "add mermaid support"
[main 2339875] add mermaid support
3 files changed, 1289 insertions(+)
create mode 100644 mermaid-init.js
create mode 100644 mermaid.min.js
かくしてコミットログは下記のようになった
gitGraph
commit id: "0-00a7a51"
commit id: "1-0769b79"
commit id: "HEAD" type: HIGHLIGHT
branch
gitにはブランチ
という機能があり…あるコミットから、ソースコードの独立性を維持しながら複数の開発を進めることができる。
svnのブランチよりも気軽に扱えるため、gitを使う上では欠かせない機能といえる。
現在のコミットログはこう。現在位置はHEAD
gitGraph
commit id: "0-00a7a51"
commit id: "1-0769b79"
commit id: "HEAD" type: HIGHLIGHT
あなたは上司から、2件のアプリケーションの改修依頼を受けたとしよう。
一つめの改修では ViewA
と GodClass
が。
二つ目の改修では ViewB
と GodClass
の改修が必要だ!
classDiagram
class GodClass
class ViewA
class ViewB
GodClass <.. ViewA : use
GodClass <.. ViewB : use
こういう場合、作業ごとにブランチを切ったほうが、作業が混沌としないで済む
git branch work1
git branch work2
gitGraph
commit id: "0-00a7a51"
commit id: "1-0769b79"
commit id: "HEAD"
branch work1
作業1を進める。ある程度の作業ごとでコミットすると良いだろう
gitGraph
commit id: "0-00a7a51"
commit id: "1-0769b79"
commit
branch work1
commit id:"view1fix" type: HIGHLIGHT
commit id:"godclass fix" type: HIGHLIGHT
ブランチの切り替えには checkout
を使う。例えば下記は work1 で作業中の状態。
gitGraph
commit id: "0-00a7a51"
commit id: "1-0769b79"
commit
branch work1
commit
commit id:"HEAD" type: HIGHLIGHT
チェックアウトをすると、ブランチのHEADへ移動する 移動すると、ファイルの状態もコミットの状態に戻る。
git checkout master
gitGraph
commit id: "0-00a7a51"
commit id: "1-0769b79"
commit id: "HEAD" type: HIGHLIGHT tag: "ココに移動"
branch work1
commit
commit
合間合間に作業2を進めても良い
gitGraph
commit id: "0-00a7a51"
commit id: "1-0769b79"
commit
branch work1
branch work2
checkout work1
commit
checkout work2
commit
checkout work1
commit
checkout work2
commit type: HIGHLIGHT tag:"ココで作業"
仮に途中で作業が不要になったりしたらば、ブランチを消せばよい
git branch -D work2
通常 git branch -d
で消すが、mainブランチにマージしていないとエラーが出て怒られる。
なので git branch -D
として強制的に削除する。
Java
だいたいコピペです
2023-03-24 java20
言語機能 / switch式のパターンマッチング強化 / 2nd preview
// 型によるマッチング
Object obj = 123L;
String formatted = switch (obj) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> obj.toString();
};
// ガード節
static void test(Object obj) {
switch (obj) {
case String s when s.length() == 1 -> ...
case String s -> ...
...
}
}
// null もできる
String s = null;
switch (s) {
case "test" -> "テスト";
case null -> "ぬるぽ";
default -> "hello";
}
言語機能 / レコード パターン / 4th preview
static void printSum(Object obj) {
if (obj instanceof Point p) {
int x = p.x();
int y = p.y();
System.out.println(x+y);
}
}
record Point(int x, int y) {}
void printSum(Object obj) {
if (obj instanceof Point(int x, int y)) {
System.out.println(x+y);
}
}
API / Scoped Values (new! / Incubator)
// 同一スレッド内で値を共有したいとき
// これまでは ThreadLocal を使っていたが
// これは遅かったらしい
final ThreadLocal<String> STR = new ThreadLocal<>();
void start() {
STR.set("test");
proc1();
}
void proc1() {
System.out.println(STR.get());
proc2();
}
void proc2() {
System.out.println(STR.get());
}
// これは早いらしい、よくわからないが
final ScopedValue<String> STR = new ScopedValue<>();
void start() {
// where内でセットした値が run内部の STR 変数にセットされるような感じぽい
ScopedValue.where(STR, "test")
.run(() -> proc1());
}
void proc1() {
System.out.println(STR.get());
proc2();
}
void proc2() {
System.out.println(STR.get());
}
API / Virtual Threads / 2nd Preview
// Java19から変化なし
// これまでのスレッドは java.lang.Thread で OSのスレッドを使っていた
// これは重く、呼び出しなどのボトルネックで作って捨てるような小さい処理ではあまり早くならなかった
// そのため、JDKによって提供されるスレッドの軽量実装を作ったのだった(Goのゴルーチンみたいなね)
// Thread.Builder
// Thread.ofVirtual()
// Thread.ofPlatform()
// が追加されたんだってよ
Thread t = Thread.ofPlatform().unstarted(() -> System.out.println("hello")); // VirtualThread[#000000]/new
t.start(); // hello
Thread t2 = Thread.ofVirtual().unstarted(() -> System.out.println("hello")); //VirtualThread[#000001]/new
t.start(); // hello
// 1件の処理時間が短く、数が多い処理は virtual threadが有利らしいっす
API / Structured Concurrency (2nd Incubator)
異なるスレッドで実行される複数のタスクを1つの作業単位として扱うことでエラーハンドリングやキャンセル処理などを簡素化でき、プログラムの信頼性や可観測性を強化できます。 らしい。複数のタスクをのうち、いずれかで例外が出たときに、一部だけでも成功していれば良しとする。とか、一部がNGだったら他も中断しちゃうとか。なんかそんな雰囲気を感じる。
Response handle() throws ExecutionException, InterruptedException {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<String> user = scope.fork(() -> findUser());
Future<Integer> order = scope.fork(() -> fetchOrder());
scope.join(); // Join both forks
scope.throwIfFailed(); // ... and propagate errors
// Here, both forks have succeeded, so compose their results
return new Response(user.resultNow(), order.resultNow());
}
}
API / Foreign Function & Memory API (2nd Preview)
わからん、ヒープ外のメモリを直接扱うAPIらしいっす。
// 1. Find foreign function on the C library path
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MethodHandle radixsort = linker.downcallHandle(stdlib.find("radixsort"), ...);
// 2. Allocate on-heap memory to store four strings
String[] javaStrings = { "mouse", "cat", "dog", "car" };
// 3. Use try-with-resources to manage the lifetime of off-heap memory
try (Arena offHeap = Arena.openConfined()) {
// 4. Allocate a region of off-heap memory to store four pointers
MemorySegment pointers = offHeap.allocateArray(ValueLayout.ADDRESS, javaStrings.length);
// 5. Copy the strings from on-heap to off-heap
for (int i = 0; i < javaStrings.length; i++) {
MemorySegment cString = offHeap.allocateUtf8String(javaStrings[i]);
pointers.setAtIndex(ValueLayout.ADDRESS, i, cString);
}
// 6. Sort the off-heap data by calling the foreign function
radixsort.invoke(pointers, javaStrings.length, MemorySegment.NULL, '\0');
// 7. Copy the (reordered) strings from off-heap to on-heap
for (int i = 0; i < javaStrings.length; i++) {
MemorySegment cString = pointers.getAtIndex(ValueLayout.ADDRESS, i);
javaStrings[i] = cString.getUtf8String(0);
}
} // 8. All off-heap memory is deallocated here
assert Arrays.equals(javaStrings, new String[] {"car", "cat", "dog", "mouse"}); // true
API / Vector API (6th Incubator)
わからんが、普通に数学的なベクタとかなんかそんな感じのやつじゃない?(適当)
import jdk.Incubator.vector.*;
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_256;
void vectorComputation(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i += SPECIES.length()) { // SPECIES.length() = 256bit / 32bit -> 8
VectorMask<Float> m = SPECIES.indexInRange(i, a.length); // 端数がマスクされる
// a.lengthが11でiが8のとき最初の3つしか要素がないので [TTT.....]
// FloatVector va, vb, vc;
FloatVector va = FloatVector.fromArray(SPECIES, a, i, m);
FloatVector vb = FloatVector.fromArray(SPECIES, b, i, m);
FloatVector vc = va.mul(va).
add(vb.mul(vb)).
neg();
vc.intoArray(c, i, m);
}
}