C and GO
Table of Contents
diff Linux OpenBSD
Q: 下記は go env を LinuxとBSDで実行した時のdiffの差分を列挙した結果です。
幾つかの疑問が有ります。 1. goは独自のコンパイラー系を使うと理解してたけど、unix系の利用は どんな場面ですか? 2. GOGCCFLAGSはCCを利用する時の設定? ですよね。-fPICが付いてるって事は C言語のコードを何とかしてgoに取り込む工夫? 3. GOTOOLCHAINのautoってのはlinuxの場合、gcc/clangとかCCで指定可能? vm$ diff -u linux BSD|egrep '^(\-|\+)' --- linux Mon Feb 16 06:46:03 2026 +++ BSD Mon Feb 16 06:57:24 2026 -CC='gcc' +CC='cc' -CXX='g++' +CXX='c++' -GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build333965881=/tmp/go-build -gno-record-gcc-switches' +GOGCCFLAGS='-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2120427002=/tmp/go-build -gno-record-gcc-switches' -GOHOSTOS='linux' +GOHOSTOS='openbsd' -GOOS='linux' +GOOS='openbsd' -GOTOOLCHAIN='auto' -GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64' +GOTOOLCHAIN='local' +GOTOOLDIR='/usr/local/go/pkg/tool/openbsd_amd64' -GOVERSION='go1.25.3' +GOVERSION='go1.25.1'
A: とても良い観察ですね。差分から Go の内部構造がかなり見えてきています。
順番に整理して説明します。
## 1. Goは独自コンパイラなのに、Unix系CCはいつ使われる?
はい、Goは基本的に独自コンパイラ(=cmd/compile=)と独自リンカ(=cmd/link=)を使います。 いわゆる gcc や clang は通常の Go コードのコンパイルには使いません。
しかし、/以下の場合にCコンパイラ(CC)が使われます。/
### ① cgo を使うとき
import "C"
を使うコードでは、Cコンパイラが必要になります。
このときの流れは:
- GoコードをGoコンパイラでコンパイル
- Cコード部分を CC (gcc/clang/cc) でコンパイル
- Goリンカが両方をまとめる
つまり、
「純粋Go」→ CC不要 「cgoあり」→ CC必要
です。
### ② internal linking が使えない場合
Goは通常「internal linker」を使いますが、 以下のようなケースでは external linker(ld)を使います:
- cgoを使っている
- -buildmode=shared
- OSの制約で外部リンカが必要な場合
このとき CC がドライバとして呼ばれます。
### ③ runtimeの一部
一部のアーキテクチャやOS依存部分では、ビルド時にCコンパイラを使うことがあります(特に非Linux系で顕著)。
OpenBSD で CC'cc'= になっているのは、システム標準が clang ベースの cc だからですね。
## 2. GOGCCFLAGSとは? -fPICが付いている理由
はい、その理解はほぼ正しいです。
GOGCCFLAGS は:
Goが cgo 経由で Cコンパイラを呼ぶときに付与するデフォルトフラグ
です。
### -fPIC が付いている理由
-fPIC は Position Independent Code を生成するオプションです。
なぜ必要か?
- Goのランタイムは動的リンクや共有ライブラリ的な扱いになることがある
- cgo経由のCコードも同様に安全にリンクできる必要がある
特に:
- -buildmode=shared
- -buildmode=c-shared
- -buildmode=plugin
では必須になります。
つまり、
「CコードをGoに取り込むための工夫」
というよりは
「Goのリンクモデルに適合させるための安全策」
です。
### OpenBSD側で増えているフラグ
-fno-caret-diagnostics -Qunused-arguments
これは clang 系特有のオプションです。
OpenBSDはclangベースなので、Linux(gcc想定)との差が出ています。
## 3. GOTOOLCHAIN='auto' とは?
これは gccやclangの話ではありません。
ここで言う toolchain は:
Goツールチェーン(goコマンド + compile + link)
のことです。
### GOTOOLCHAIN の意味
Go 1.21以降に導入された機能で、
GOTOOLCHAIN=auto
の場合:
必要なら自動で別バージョンのGoをダウンロードして使う
という動作になります。
例えば:
- go.mod に
go 1.26と書いてある - 手元は go1.25
→ 自動で1.26を取得して使う(autoの場合)
### local との違い
GOTOOLCHAIN='local'
は:
インストール済みのGoだけ使う。自動取得しない。
OpenBSDで local になっているのは、 パッケージ版Goがこの設定でビルドされている可能性が高いです。
## 差分から見える面白い点
### Linux
GOTOOLCHAIN='auto' GOVERSION='go1.25.3'
### OpenBSD
GOTOOLCHAIN='local' GOVERSION='go1.25.1'
これは:
- Linuxは手動インストール(公式バイナリ?)
- OpenBSDは ports/packages 版
の可能性が高いですね。
OpenBSDのportsは自動ダウンロード機構を嫌うことがあります。
## まとめ
### Q1
Goは基本独自コンパイラだが、 cgoやexternal linking時にCCを使う。
### Q2
GOGCCFLAGSは cgo用のデフォルトフラグ。 -fPICはGoのリンクモデルに合わせるため。
### Q3
GOTOOLCHAINはgcc/clangの話ではなく、 Go自体のバージョン管理機構。
もし興味があれば、次は:
- internal linking と external linking の実際の違い
- OpenBSDでのGoのリンクモデル
- go build -x で実際にCCが呼ばれる様子を追跡
あたりはかなり面白いテーマです。
どこを深掘りしますか?
Q: internal linking と external linking の実際の違い を お願 します。
それからgoはシングルバイナリーが売りと思ってましたけど、状況によっては それが破れる場合も有るって事ですか?
A: 非常に良いところに目を付けていますね。 ここは Go の「思想」と「現実のOS事情」が交差する面白い部分です。
## ◆ internal linking とは
Go純正リンカ(=cmd/link=)だけで最終バイナリを生成する方式。
流れ:
Go source ↓ cmd/compile ↓ .o (Go object) ↓ cmd/link ← Goのリンカ ↓ 実行バイナリ
特徴:
- Cコンパイラ不要
- ldも不要
- ほぼ完全に自己完結
- 静的リンクが基本
- 「Goらしい」ビルド
Linuxで純粋Goコードならこれになります。
## ◆ external linking とは
最終リンクをシステムのリンカ(ld)に任せる方式。
流れ:
Go source ↓ cmd/compile ↓ .o ↓ cmd/link(中間生成物) ↓ CC (gcc/clang) ↓ ld ↓ 実行バイナリ
ここで CC がドライバとして使われます。
## ◆ いつ external linking になるのか?
主な条件:
### ① cgo を使うとき
import "C"
→ Cオブジェクトが混ざる → Goリンカ単独では完結できない → external linking
### ② -buildmode=c-shared / plugin / shared
共有ライブラリ生成時は external linking が使われます。
### ③ OSが internal linking を十分サポートしていない場合
OpenBSDはLinuxより external linking が使われやすいです。
## internal linking の場合
Goリンカは:
- ELFヘッダを自前生成
- relocation解決
- シンボル解決
- セクション配置
- runtime挿入
全部自分でやります。
つまり:
Goが「簡易ld」を持っている
ということです。
## external linking の場合
Goリンカは:
- Go固有部分だけ処理
- 最終ELF生成はシステムldへ委譲
になります。
そのため:
- glibc や libc に依存
- 動的リンクが発生する可能性あり
ここが重要です。
答え:
純粋Goならほぼ常にシングルバイナリ cgoを使うと破れる可能性がある
## ◆ 純粋Goの場合
例:
package main
func main(){}
Linux:
ldd ./a.out → not a dynamic executable
完全静的。
## ◆ cgo使用時
例えば:
import "C"
すると:
ldd ./a.out
libc.so.6 => ...
となる場合があります。
つまり:
- glibcに依存
- 動的リンク発生
- 別環境に持っていくと動かない可能性
## ◆ 例外:静的リンク強制
Linuxでは:
CGO_ENABLED=1 go build -ldflags "-linkmode external -extldflags -static"
とすると静的リンクも可能。
ただし:
- glibcは完全静的リンクが難しい
- muslなら比較的容易
OpenBSDは:
- libcとの結合が強い
- system callの扱いがLinuxと違う
ため、external linking が使われやすいです。
つまり:
OpenBSDの方が「完全自己完結Goバイナリ」はやや崩れやすい
| 状況 | internal | external |
| ------- | -------- | -------- |
| 純粋Go | ✓ | ✗ |
| cgo使用 | ✗ | ✓ |
| 共有ライブラリ | ✗ | ✓ |
| 完全静的 | 可能 | 条件付き |
Goの思想は:
「ビルド環境に依存しないデプロイ」
ですが、
OSの現実(libc, ELF, relocation, ABI)との境界で
100%の自己完結は保証できない
ということになります。
もし興味があれば、次は:
- 実際に
go build -xで internal/external の違いを見る - readelf / objdump でELFを比較
- OpenBSD特有のリンク事情
どれを掘りますか?
Q: 実際に go build -x で internal/external の違いを見る これって、gcc hoge.c -v 相当?
A: いい質問ですね。結論から言うと:
かなり近いですが、完全に同じではありません。
gcc -v が「コンパイラ+リンカの内部呼び出しを表示する」のに対して、
go build -x は goコマンドが実行している全サブコマンドを表示する ものです。
例えば:
gcc -v hello.c
は内部的に:
- cpp
- cc1
- as
- ld
などの呼び出しを全部表示します。
一方:
go build -x
は:
- compile
- asm
- pack
- link
- (必要なら)gcc / clang
の実行ログをすべて出します。
つまり:
「Go版の -v 相当」 ただし表示レイヤーが少し違う
という感じです。
純粋Goコードで実行すると:
go build -x
の最後の方にこんな行が出ます:
/usr/local/go/pkg/tool/linux_amd64/link ...
ここで終わります。
gccやccは呼ばれません。
つまり:
compile → link(Go純正)
で完結しています。
cgoを含むコードで:
go build -x
すると途中に:
gcc ...
や
cc ...
が出てきます。
そして最後のリンクで:
gcc -o a.out ...
のような呼び出しが出ます。
これが external linking の証拠です。
強制的に指定できます。
### internal を強制
go build -ldflags "-linkmode internal" -x
### external を強制
go build -ldflags "-linkmode external" -x
するとログの違いがはっきり出ます。
external linking 時に:
go build -x -ldflags "-extldflags=-v"
とすると、
最終的に呼ばれる gcc が -v 付きになり、
ld まで全部見えます。
つまり:
go build -x
↓
gcc -v
↓
ld ...
という多層構造になります。
あなたの環境では:
CC='cc' GOHOSTOS='openbsd'
なので、
external linking 時は:
cc ...
が出てくるはずです。
Linuxでは:
gcc ...
になる可能性が高い。
ここを比較するとかなり面白いです。
| コマンド | 見える範囲 |
| ---------------------- | -------------- |
| gcc -v | Cコンパイル内部 |
| go build -x | Goツールチェーン全体 |
| go build -x + external | Go + gcc/ld 全部 |
あなたのように:
- 仮想環境比較
- カーネルビルド時間測定
- toolchain挙動観察
をやっている方なら、
go build -work -x
もおすすめです。
-work を付けると一時ディレクトリが削除されないので、
生成された .o や中間ファイルを直接読めます。
かなり面白いですよ。
もし良ければ次は:
- 実際の
go build -xログを一部貼ってくれれば一緒に解析 - internal linker がやっている ELF 処理の中身
- OpenBSD での PIE / WX とGoの関係
どこまで深掘りますか?
cgo
package main
/*
#include <stdio.h>
#include <stdlib.h>
void hello(char* str) {
printf("C says: %s\n", str);
}
*/
import "C"
import "unsafe"
import "fmt"
func main() {
s := C.CString("Hello from Go!")
defer C.free(unsafe.Pointer(s))
C.hello(s)
fmt.Println("Hello GO world")
}
C側のヘッダーとかライブラリィー指定は、
/* #cgo CFLAGS: -I./include #cgo LDFLAGS: -L./lib -lmylib #include "mylib.h" */
ブロック・コメントの中がC言語の世界らしい。
ad$ ./a.out
C says: Hello from Go!
Hello GO world
ad$ file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1
ad$ ldd a.out
a.out:
Start End Type Open Ref GrpRef Name
0000000000200000 00000000003da000 exe 2 0 0 a.out
000000025a8a8000 000000025a8b5000 rlib 0 1 0 /usr/lib/libpthread.so.27.1
0000000265696000 000000026579d000 rlib 0 1 0 /usr/lib/libc.so.100.3
0000000295099000 0000000295099000 ld.so 0 1 0 /usr/libexec/ld.so
まあ動いたけれど、シングルバイナリーが完全に破れている。混ぜるな危険って ことにしておこう。どうしてもってなったら、rubyで体験してopen3なライブラリィ 相当がきっと有るだろう。
A: その通りです — あなたのビルド結果は “純粋なシングルバイナリ”ではない という現実を示しています。
cgo を使うと libc や libpthread への依存が発生し、結果として 動的リンクされたバイナリになる ことが普通です。
## ✅ なぜあなたのバイナリは動的リンクになるのか
あなたのコードはこうなっています:
import "C"
これにより:
- Cコンパイラが呼ばれる(ここでは clang/gcc)
- Cライブラリ関数(printf, free など)への参照が生まれる
- Goリンカは Go内部リンカでは処理しきれず
- external linking へフォールバックする
その結果:
ldd a.out
libc.so.100.3
libpthread.so.27.1
というように標準 C ランタイムを動的リンクしています。
## ❓ Goはシングルバイナリをうたっているのに矛盾じゃないか?
これはよくある誤解です。
### 正確に言うと:
“純粋な Go コードなら(cgo を使わなければ)、 単一実行ファイルで自己完結するバイナリが生成される”
という意味です。
つまり:
import "C"
という時点で、Goの思想である “シングルバイナリ = 自己完結” は崩れる可能性があります。
## ❗ Go で 100% 静的リンクするには?
Linux では次のように外部リンカに静的リンクを指示すれば可能なこともあります。
例:
CGO_ENABLED=1 go build -ldflags "-linkmode external -extldflags '-static'"
ただし…
- glibc は完全な静的リンクが推奨されない設計
- musl libc を使う方が静的リンクしやすい
- OpenBSD では libc が強く環境依存なので 静的リンクは現実的でない場合が多い
このため クロスプラットフォームな “完全静的” は難易度が高い です。
## 💡 だったら別プロセスで疎結合にしようという発想
あなたの考えのとおり:
外部プロセスとして C プログラムを実行してやりとりする
というのはよくある設計パターンです。
Go には 標準でプロセス起動 / パイプ付き通信機構 があるので、 Ruby でいうところの Open3 に相当するものはちゃんと用意されています。
## ✔ Go の外部コマンド実行
標準パッケージにあります:
### ① 基本
cmd := exec.Command("hoge", "arg1", "arg2")
out, err := cmd.Output()
### ② 標準入出力も扱う
cmd := exec.Command("hoge")
stdin, _ := cmd.StdinPipe()
stdout, _ := cmd.StdoutPipe()
stderr, _ := cmd.StderrPipe()
cmd.Start()
// ここで stdin.Write / stdout.Read 等を使う
cmd.Wait()
これは Ruby の Open3 とだいたい同じです。
### ③ 例: 複数チャネル付き
cmd := exec.Command("hoge")
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
err := cmd.Run()
## 📌 cgoを使わずにCと連携するパターン
| パターン | 特徴 |
| ------ | ---------------------- |
| cgo | 同一プロセスでCコードを呼べるが依存増 |
| プロセス分離 | Goは純粋、Cは外部プロセス |
| RPC | gRPCや stdin/stdout で協調 |
| ソケット | ネットワーク越しに疎結合 |
あなたが言っているように:
Ruby の Open3 相当を使って疎結合にする
というアイデアは Goでも自然 にできます。
## 🎯 だから結論として
✔ cgo を使うと Go の “自己完結バイナリ” は壊れる ✔ Goの強みは 純粋Goコードでのシングルバイナリ ✔ Cと併用したいなら 別プロセスで疎結合 が安全 ✔ Go標準で Open3 っぽい機構はしっかりある
debug for go
Delve is a debugger for the Go programming language.
go言語のデバッガ(delveとgdb)とcore dump
go-dlv for emacs なんてのが有るけど、徳する事は無かったぞ。
sakae@lu:cmtfmt$ dlv debug main.go -- test.go z.go b main.main c
Q: 残念ながらOpenBSDでは dlv をサポートしていない。 そこで、見様見真似で go build -o a.out -gcflags=all="-N -l" main.go
gdbする時は、ポインター類が短かいi386環境が最適。
ob$ gdb -q a.out
Reading symbols from a.out...
Loading Go Runtime support.
(gdb) b write
Breakpoint 1 at 0x57d940
(gdb) r
Starting program: /home/sakae/go/src/work/a.out
[New thread 314019 of process 34783]
[New thread 565006 of process 34783]
[New thread 156560 of process 34783]
[New thread 462638 of process 34783]
Thread 1 hit Breakpoint 1, __i386_read_tcb (offset=0)
at /usr/include/machine/tcb.h:41
41 __asm__ ("movl %%gs:(%1),%0" : "=r" (val) : "r" (offset));
(gdb) info threads
Id Target Id Frame
* 1 thread 139680 of process 34783 __i386_read_tcb (offset=0)
at /usr/include/machine/tcb.h:41
2 thread 314019 of process 34783 _thread_sys_nanosleep () at /tmp/-:2
3 thread 565006 of process 34783 _thread_sys___thrsleep () at /tmp/-:2
4 thread 156560 of process 34783 _thread_sys___thrwakeup () at /tmp/-:2
5 thread 462638 of process 34783 __tfork_thread ()
at /usr/src/lib/libc/arch/i386/sys/tfork_thread.S:67
(gdb) bt
#0 __i386_read_tcb (offset=0) at /usr/include/machine/tcb.h:41
#1 _libc_write_cancel (fd=1, buf=0x5c58a000, nbytes=23)
at /usr/src/lib/libc/sys/w_write.c:26
#2 0x06337a3f in __swrite (cookie=0x262bf480 <__stdout>,
buf=0x5c58a000 "C says: Hello from Go!\n", n=23)
at /usr/src/lib/libc/stdio/stdio.c:65
#3 0x062fc2c8 in __sflush (fp=0x262bf480 <__stdout>)
at /usr/src/lib/libc/stdio/fflush.c:77
#4 0x0636441a in __sfvwrite (fp=0x262bf480 <__stdout>, uio=0xcf7e99ac)
at /usr/src/lib/libc/stdio/fvwrite.c:199
#5 0x0633157c in __sprint (fp=0x262bf480 <__stdout>, uio=<optimized out>)
at /usr/src/lib/libc/stdio/vfprintf.c:112
#6 __vfprintf (fp=0x262bf480 <__stdout>, fmt0=0x432dd1 "C says: %s\n",
ap=0xcf7ea054 "l\177Df") at /usr/src/lib/libc/stdio/vfprintf.c:1074
#7 0x0632ec64 in _libc_vfprintf (fp=0x262bf480 <__stdout>,
fmt0=0x432dd1 "C says: %s\n", ap=0xcf7ea050 "\300s\242Hl\177Df")
at /usr/src/lib/libc/stdio/vfprintf.c:275
#8 0x063432a7 in _libc_printf (fmt=0x432dd1 "C says: %s\n")
at /usr/src/lib/libc/stdio/printf.c:44
#9 0x0057d125 in hello (str=<optimized out>)
at /home/sakae/go/src/work/main.go:8
#10 _cgo_387e112766b2_Cfunc_hello (v=0x66447f6c) at cgo-gcc-prolog:63
#11 0x0052f95c in runtime.asmcgocall ()
at /usr/local/go/src/runtime/asm_386.s:689
#12 0x66447f6c in ?? ()
(gdb) c
Continuing.
C says: Hello from Go!
Thread 1 hit Breakpoint 1, __i386_read_tcb (offset=0)
at /usr/include/machine/tcb.h:41
41 __asm__ ("movl %%gs:(%1),%0" : "=r" (val) : "r" (offset));
(gdb) bt
#0 __i386_read_tcb (offset=0) at /usr/include/machine/tcb.h:41
#1 _libc_write_cancel (fd=1, buf=0x680140c0, nbytes=15)
at /usr/src/lib/libc/sys/w_write.c:26
#2 0x00530d42 in runtime.syscall ()
at /usr/local/go/src/runtime/sys_openbsd_386.s:645
#3 0x680140c0 in ?? ()
#4 0x0052f95c in runtime.asmcgocall ()
at /usr/local/go/src/runtime/asm_386.s:689
#5 0x68047c94 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) c
Continuing.
Hello GO world
上記のBT中、frame 3,5 のソースがポイントされていないけど、動的に作成されて いる為、察知できないのかな? go build -x -work の結果でも、自動作成って 名乗るコードが出てきてましたから。
A: 素晴らしい観察です。 これは cgo + OpenBSD + i386 + gdb という、かなり深いところに入っています。
結論から言うと:
はい、その frame は「cgo が自動生成したコード」なので gdb が通常のソースに対応付けできないことがあります。
順番に整理します。
### 最初の停止点(C側 printf)
#9 hello #10 _cgo_xxx_Cfunc_hello (cgo-gcc-prolog) #11 runtime.asmcgocall
これは完璧に正しい流れです。
Go main ↓ runtime.asmcgocall ↓ _cgo_xxx_Cfunc_hello ← cgo生成 ↓ hello (C) ↓ printf ↓ libc
#3 0x680140c0 in ?? () #5 0x68047c94 in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?)
これは:
スタックが壊れているのではなく GoのスタックとCのスタックが切り替わっている
ためです。
Goは普通:
- goroutine stack(小さい)
- 分割可能
- grow/shrinkする
を使っています。
しかしCを呼ぶとき:
goroutine stack ↓ asmcgocall ↓ 切り替え ↓ OS thread stack ↓ C実行
という スタック切り替え が発生します。
この橋渡しが:
runtime.asmcgocall
です。
理由は3つあります。
## ① cgo生成コードは一時ファイル
go build -work -x をすると出てくる:
_cgo_gotypes.go _cgo_export.c _cgo_main.c cgo-gcc-prolog
これらは:
- ビルド時に生成
- コンパイル後削除
- デバッグ情報が簡略
なので gdb が完全に追えない場合があります。
## ② GoはDWARFを独自生成
GoコンパイラはDWARFを出力しますが:
- CとGoのABIが違う
- フレームポインタを使わない場合がある
- スタックマップがGo独自
なので:
Backtrace stopped: previous frame inner to this frame
がよく出ます。
## ③ i386特有の事情
i386では:
- TLSアクセス(gsレジスタ)
- TCB読み出し
- OpenBSD特有のスレッドモデル
が絡みます。
あなたが最初に止まった:
__i386_read_tcb
は TLS(Thread Control Block)読み出しです。
つまり:
gdbはlibc側のTLS処理を追って止まっている
0x680140c0 0x68047c94
これは:
- Goランタイム内部
- goroutineトランポリン
- スタック境界マーカー
の可能性が高いです。
i386では特に:
- フレームポインタ最適化
- asmcgocall の特殊スタック操作
のせいで崩れやすいです。
あなたのビルド:
-gcflags=all="-N -l"
は正しいです。
さらに改善するなら:
go build -gcflags=all="-N -l" -ldflags="-linkmode external"
そして gdb で:
set disassemble-next-line on set print asm-demangle on
さらに:
info frame
を使うと少しマシになります。
あなたの観察:
「動的に作成されている為、察知できないのかな?」
は半分正解で、半分違います。
正確には:
✔ 自動生成コード ✔ Go独自ABI ✔ スタック切り替え ✔ DWARF制限
の複合要因です。
あなたのBTのここ:
#11 runtime.asmcgocall ()
これが
Go → C への境界
です。
そして次に:
runtime.syscall
が出ていますね。
これは
C → Go runtime → syscall wrapper
への戻り境界です。
つまりあなたは今、
Goランタイムの境界層を完全に踏んでいます。
これはかなり深い解析レベルです。
あなたの興味的には、たぶんここが面白い:
- runtime.asmcgocall の実装(=asm386.s=)
- Goのスタック切り替え方法
- gdbでgoroutineを追う方法
- OpenBSDのTLSとGo runtimeの関係
どこまで行きますか?
正直、今かなりカーネル寄りの世界に入っています。
また、長くなってきたので、to be continue ….
README
数多ある数理モデルを一堂に集積した本。
例えば、巡回セールスマン問題なんてのがある。すべての地点を巡る 最短経路モデルって事だ。今迄はそういうのが有るって事は知ってたけど 身近な問題として考えた事がなかった。
こういうのに対して応用例が説明されてる。京都に旅行します。見たい寺 とかを6箇所要望されました。どういう経路で巡ったら最短時間になるで しょうか? 1日乗車券とかを利用するだろうから、移動時間が問題。 まさに、時は金なりって事ですな。 俄然、目の色を替えて取り組む問題ですねぇ。
地図は何色あったら塗りけられるでしょうか、ってのを一般化すると、グラフ 彩色問題になるそうな。これも、一部の好事家の頭の体操とばかり思っていた。 応用例が出てた。携帯基地局の周波数割り当てに応用されるとな。近隣の 局が同一周波数を利用すると混信しちゃうので、それを避けたい。 頂点を無線局、エッジを通信範囲、色を周波数に置き替えて問題を解決する そうな。周波数は有限な公共資源だから、無闇矢鱈に増やす事は、御法度だ。
100x100の画像から個人の顔を認識して特定したい。そんな時は、平均顔の 画像を用意して、引き算するらしい。そうすると個人の特徴が鮮明になる そうな。そしてそれを主成分分析して、特徴ベクトルを作成。この時に 行列の固有値が大活躍するとか。無味乾燥な数学よりは、よっぽどか興味が 沸くな。
The Go Programming Language (book)
これ、あの人が著者に名を連ねていて良さそうなんだけど、絶賛絶版中らしい。 せめて、ソースだけでも眺めてみるか。