SlideShare a Scribd company logo
1 of 56
Download to read offline
The Go gopher was designed by Renée French.
The gopher stickers was made by Takuya Ueda.
Licensed under the Creative Commons 3.0 Attributions license.
マスター・オブ・goパッケージ
@会津大Go言語+仮想通貨勉強会
2017年12月10日
1
※ この資料はGolangUK 2017の発表資料を改良したものです
自己紹介
上田拓也
@tenntenn
所属
コミュニティ活動
&
Go ビギナーズ
Go Conference
上田拓也
@tenntenn
2
ソウゾウ エキスパートチーム
技術をアウトプットするところに技術は集まる
■ エキスパートチームとは?
● 50%以上の時間を技術コミュニティへの貢献に充てる
■ エキスパートチームの役割
● 社内に新しい技術を取り取り込む
● 社外のコミュニティなどを通じて社会へ還元する
■ エキスパートチームの活動
● カンファレンス・勉強会の開催/運営
● 対外的な講演活動
● 執筆、雑誌への寄稿、インタビュー
● 社内外での担当技術の普及推進
@tenntenn
担当:Go・GCP
@mhidaka
担当:Android
メンバー
3
アジェンダ
■ Gopherを探せ!
■ 静的解析
■ Goにおける静的解析
■ 静的解析の製品開発への応用
4
Gopherを探せ!
みつけてね
Powered by https://gopherize.me
5
Gopherを探せ!
みつけてね
Powered by https://gopherize.me
6
"Gopher"を探せ!
type Gopher struct { Gopher string `json:"gopher"` }
func main() {
const gopher = "GOPHER"
gogopher := GOPHER()
gogopher.Gopher = gopher
fmt.Println(gogopher)
}
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{ Gopher: "gopher" }
return
}
7
みんな大好きgrep
$ grep Gopher main.go
type Gopher struct { Gopher string `json:"gopher"` }
gogopher.Gopher = gopher
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{ Gopher: "gopher" }
grepで"Gopher"を探す
8
"Gopher" 型を探せ!
type Gopher struct { Gopher string `json:"gopher"` }
func main() {
const gopher = "GOPHER"
gogopher := GOPHER()
gogopher.Gopher = gopher
fmt.Println(gogopher)
}
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{ Gopher: "gopher" }
return
}
9
"Gopher"型を探すには?
■ grep だと文字列としてしか検索できない
■ 文字列ではなくGoのソースコードとして
理解しないといけない
■ そこで静的解析を使う!
10
静的解析
11
静的解析と動的解析
■ 静的解析
● プログラムを実行せずに解析すること
● ソースコードを解析する
● 例:lint、コード補完、 コードフォーマッタ
■ 動的解析
● プログラムを実行して解析すること
● 実行時 変数 状態や関数 実行順などを検証
● 例:レースコンディション
12
リフレクション
■ リフレクション
● 実行時に型や値 情報を解析する
■ Goにおけるリフレクション
● reflectパッケージを使う
● 実行時にstructタグにアクセスする唯一の方法
● 出力引数としてポインタを貰ってきた場合に値を入れるために使用
● JSONやXMLなどのエンコードに使用
13
Goの静的解析ツール
■ Goには多くの静的解析ツールが存在する
gofmt/goimports コードフォーマッタ
go vet/golint コードチェッカー、リンター
guru 静的解析
gocode コード補完
errcheck エラー処理のチェック
gorename/gomvpkg リファクタリング
14
Goと静的解析
■ 静的解析しやすいように設計されている
● 静的型付け
● 文法がシンプル
● 型推論
● 暗黙の型変換がない
● 標準パッケージで静的解析の機能を提供
静的解析では多くの情報を取得できる
15
go パッケージ
go/ast 抽象構文木(AST)を提供
go/build パッケージに関する情報を集める
go/constant 定数に関する型を提供
go/doc ドキュメントをASTから取り出す
go/format コードフォーマッタ機能を提供
go/importer コンパイラに適したImporterを提供
go/parser 構文解析 機能を提供
go/printer AST 表示機能を提供
go/scanner 字句解析 機能を提供
go/token トークンに関する型を提供
go/types 型チェックに関する機能を提供
16
Goにおける静的解析
17
静的解析の流れ
ソースコード
トークン
抽象構文木
(AST)
型情報
構文解析
字句解析
型チェック
go/scanner
go/token
go/parser
go/ast
go/types
go/constant
18
■ 入力された文字列をトークンとして分解
字句解析- go/scanner,go/token
IDENT ADD INT
トークン
ソースコード: v + 1
19
構文解析 - go/parser,go/ast
■ トークンを抽象構文木(AST)に変換
v + 1
IDENT ADD INT
ソースコード:
+
v 1
BinaryExpr
Ident BasicLit
トークン:
抽象構文(AST):
20
"Hello, World"の抽象構文木
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
Run on Playground
*ast.File
[]ast.Decl
*ast.GenDecl *ast.FuncDecl
21
型チェック - go/types,go/constant
■ 型情報を抽象構文木から抽出
● 識別子の解決
● 型の推論
● 定数の評価
n := 100 + 200
m := n + 300
定数の評価
= 300
型の推論
-> int
識別子の解決
22
ソースコードから抽象構文木の取得
■ parser.Parse* 系の関数を使う
● ParseExpr,ParseExprFrom
○ 式をパースする
○ ParseExpr は ParseExprFrom のシンプルバージョン
● ParseFile
○ ファイルをパースする
● ParseDir
○ ディレクトリ単位でパースする
○ 内部で ParseFile を呼んでいる
23
式の抽象構文木を取得する
expr, err := parser.ParseExpr(`v + 1`)
if err != nil {
/* handling the error */
}
/* use expr */
■ 式単位でパースする
24
ファイル単位で抽象構文木を取得
const src = `
package main
var v = 100
func main() {
fmt.Println(v+1)
}`
fs := token.NewFileSet()
f, err := parser.ParseFile(fs, "my.go", src, 0)
if err != nil {
/* handling the error */
}
/* use f */
srcがnilの場合だと
ファイル名を元にファイルが開かれる
ソースコード
パースモード
25
token.FileSet
■ ファイル中の位置情報を記録する為の型
● token.Posは数値として記録
● 複数ファイル間で共通の値が使われる
● token.FileSet は各ファイルのオフセットを記録
● オフセットはパース時に記録される
● token.FileSet はparser.Parse*系の関数に出力引数として渡される
type Pos int
26
デモ 1: 構文解析と抽象構文木の出力
27
https://youtu.be/lM1Pj6xYxZs
Demo Code: https://gist.github.com/tenntenn/833207ce1715089da23936b5dfaebea5
抽象構文木の探索- ast.Inspect
■ Using ast.Inspect
expr, _ := parser.ParseExpr(`v + 1`)
ast.Inspect(expr, func(n ast.Node) bool {
if n != nil { fmt.Printf("%Tn", n) }
return true
})
抽象構文木の探索
*ast.BinaryExpr
*ast.Ident
*ast.BasicLit
Playgroundで実行
ast.Walk はもっと複雑な処理ができる
+
v 1
BinaryExpr
Ident BasicLit
28
抽象構文木の探索 - 再帰
func traverse(n ast.Node) {
switch n := n.(type) {
case *ast.Ident:
fmt.Println(n.Name)
case *ast.BinaryExpr:
traverse(n.X)
traverse(n.Y)
case *ast.UnaryExpr:
traverse(n.X)
default:
fmt.Println(n)
}
}
識別子:識別子名を出力
2項演算式:各項について再帰的に探索
型で処理を分岐
Playgroundで実行
単項演算式:項を再帰的に探索
29
デモ 2: 識別子の探索
30
https://youtu.be/mpUgaaASvHo
Demo Code: https://gist.github.com/tenntenn/299c226c540fccd8386b7148f55f0884
型チェック
/* 型チェックのためのConfigを初期化 */
cfg := &types.Config{Importer: importer.Default()}
info := &types.Info{
/* TODO: 結果を保持するためのmapを初期化 */
}
pkg, err := cfg.Check("main", fs, []*ast.File{f}, info)
if err != nil {
/* エラー処理 */
}
/* TODO: pkgやinfoを使う処理 */
■ (*types.Config).Check で型チェックを行う
31
types.Info で型チェックの結果を保持する
type Info struct {
// Types maps expressions to their types, and for constant
// expressions, also their values.
Types map[ast.Expr]TypeAndValue
// Defs maps identifiers to the objects they define.
Defs map[*ast.Ident]Object
// Uses maps identifiers to the objects they denote.
Uses map[*ast.Ident]Object
// Implicits maps nodes to their implicitly declared objects, if any.
Implicits map[ast.Node]Object
// Selections maps selector expressions (excluding qualified identifiers)
// to their corresponding selections.
Selections map[*ast.SelectorExpr]*Selection
// Scopes maps ast.Nodes to the scopes they define.
Scopes map[ast.Node]*Scope
// InitOrder is the list of package-level initializers in the order in which
// they must be executed.
InitOrder []*Initializer
}
32
デモ 3: Gopher型の探索
33
https://youtu.be/AuSDtmiMaXI
Demo Code: https://gist.github.com/tenntenn/134d6965f75efe5eb6f6edf7b0ebe509
抽象構文木の変更
34
■ 抽象構文木を探索&条件マッチするノードの置き換え
● 2項演算式中の第2項だけを変更する
● 1ノードだけみるast.Inspectやast.Walkでは難しい!
○ go/ast: provide AST Rewrite functionality (ast.Walk is not good enough)
+
X Y
BinaryExpr
Ident
+
X 2
BasicLit
astutil.Apply関数
■ 抽象構文木を変更するための関数
● golang.org/x/tools/go/ast/astutilパッケージで提供
● preとpostというノードに適用する関数を渡す
○ pre: 子ノードを処理する前に呼ばれる関数
○ post: 子ノードを処理した後に呼ばれる関数
● 変更した結果をresultとして返す
○ ルートが変更された場合はrootとresultが変わる
35
参考:astutil.Applyで抽象構文木を置き換える
func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node)
ApplyFunc型とCursor型
■ ApplyFunc型
● astutil.Apply関数に各ノードに再帰的に適用される関数
■ Cursor型
● 現在注目しているノードに関する情報を保持する型
● ノードの情報を取得するメソッド
○ Node、Index、Parent、Name
● ノードの操作を行うメソッド
○ Replace、Delete、InsertBefore、InsertAfter
36
type ApplyFunc func(*Cursor) bool
ノードの情報を取得するメソッド
■ Node() ast.Node
● 現在注目のノード取得する
■ Parent() ast.Node
● 注目ノードの親ノードを取得
■ Name() string
● 親ノードにどういう名前でノードを管理されているか
○ 例:BinaryExprの場合、2つの項はXとY
■ Index() int
● 親ノードでスライスとして管理していた場合にそのインデックス
○ 例:関数の引数など
● Nameメソッドだけで区別できない場合に使う
37
ノードを変更するメソッド
■ Replace(n ast.Node)
● 現在注目のノードを指定したノードで入れ替える
■ InsertBefore(n ast.Node)
● スライスで管理されているノードが対象
● 現在注目のノードの前にノードを追加する
■ InsertAfter(n ast.Node)
● 現在注目のノードの後ろにノードを追加する
■ Delete()
● 現在注目のノードを削除する
38
ノードの更新の例
39
expr, err := parser.ParseExpr(`x+y`)
if err != nil { log.Fatal(err) }
n := astutil.Apply(expr, func(cr *astutil.Cursor) bool {
if _, ok := cr.Parent().(*ast.BinaryExpr); !ok { return true }
if cr.Name() == "Y" {
cr.Replace(&ast.BasicLit{Kind:token.INT, Value:"2"})
}
return true
}, nil)
if err := format.Node(os.Stdout, token.NewFileSet(), n); err != nil {
log.Fatalln("Error:", err)
}
fmt.Println()
ノードを操作する際の注意点
■ ノードの操作は破壊的に行われる
● コピーが作られるわけではない
● Apply関数の戻り値はちゃんと受け取る
■ ノードの操作は即時反映される
● preとpostは実行された瞬間にそのノードに適用される
40
ノードの削除の例(失敗例)
41
■ 第1引数だけを削除したい
expr, err := parser.ParseExpr(`func(x, y int){}(10, 20)`)
if err != nil { log.Fatal(err) }
n := astutil.Apply(expr, func(cr *astutil.Cursor) bool {
if cr.Name() == "Args" && cr.Index() == 0 {
cr.Delete()
}
return true
}, nil)
if err := format.Node(os.Stdout, token.NewFileSet(), n); err != nil {
log.Fatalln("Error:", err)
}
fmt.Println()
ノードの削除の例(修正版)
42
■ 第1引数を一度だけ削除する
expr, err := parser.ParseExpr(`func(x, y int){}(10, 20)`)
if err != nil { log.Fatal(err) }
var once sync.Once
n := astutil.Apply(expr, func(cr *astutil.Cursor) bool {
if cr.Name() == "Args" && cr.Index() == 0 {
once.Do(cr.Delete)
}
return true
}, nil)
if err := format.Node(os.Stdout, token.NewFileSet(), n); err != nil {
log.Fatalln("Error:", err)
}
fmt.Println()
静的解析の製品開発への応用
ケース 1: gpath,go-httpdoc
43
go.mercari.io/go-httpdoc
■ HTTPハンドラのテストからAPIドキュメントを生成
● 単にHTTPハンドラのテストを書くだけで良い
● gRPCとJSON RPCにも対応している
44
主にdeeeetさん作
リクエストとレスポンスのテスト
■ リクエストのテストからドキュメントを生成
● Request Bodyをリフレクションでテストしている
● 構造体の任意のフィールドを指定できる
validator.RequestBody(t, []httpdoc.TestCase{
{"Name", "tenntenn", "User Name"},
{"Attribute.Email", "tenntenn@example.com", "e-mail address"},
}, &createUserRequest{})
45
参考:go-httpdocのexample
github.com/tenntenn/gpath
■ 構造体の任意のフィールドにアクセスできる
● 複雑なリフレクションが簡単に書ける
● Goの式で記述できる
● スライスやマップにも対応している
type Bar struct { N []int }
type Foo struct { Bar *Bar }
f := &Foo{ Bar: &Bar{ N: []int{100} }}
v, _ := At(f, `Bar.N[0]`)
fmt.Println(v)
$ go run main.go
100
46
開発ツールへ静的解析を使う
■ 自作開発ツールでレビューコストを下げる
● 自動化できることは自動化する(カラクリ)
○ 自分のプロジェクト用にカスタマイズされたリンターを作る
○ よくあるバグを検出するツールを作る
● レビューの時間はもっと重要なことに使う
○ アルゴリズムの検証
○ 設計
○ パフォーマンス
47
静的解析の製品開発への応用
ケース 2: バナーツール
48
デモ:https://goo.gl/HzHTm6
バナーツール
■ アプリ内バナーを管理するツール
アプリ内バナー
メルカリ アッテのタイムライン
49
主にtenntenn作
バナーツール
■ アプリ内バナーを管理するツール
バナーツール
● 配信条件式
● レスポンス
バナーの取得
OS, API バージョン
配信可能バナーのリストを返却
画像URL, 遷移先URLなど
Apps
50
配信条件式の評価
バナーの取得
GET /banner/?os=1
String(os) == "1"
バナー画像URLなど
配信条件式:
バナーツール
"1" == "1"
true
束縛
評価
■ 配信条件をGoの式に似た形式で記述する
● go パッケージを使って式を評価する
● 型つき変数として関数呼び出しの記述方式を利用
51
静的解析の製品開発への応用
ケース 3: Datastore Wrapper
52
参考:ぼくが かんがえた さいきょうの でーたすとあ らっぱー
go.mercari.io/datastore
53
■ Datastoreとは
● 主にGoogle App Engine(GAE)で使われるキーバリューストア
■ Datastore Wrapper
● Datastoreのライブラリの使いにくいところを改善
● GAEガチ勢のノウハウを凝縮したライブラリ
● DatastoreのRPCのコールの回数を減らすバッチ処理など
vvakameさん作
移行ツールの作成
■ 既存のプロジェクトでDatastore Wrapperを使う
● 既存のコードの置き換えが大変
● import文の変更などは自動化できる
● カスタマイズされたものを作る方が利便性が高い
■ astutil.Apply関数の利用
● 複雑な置き換えが可能
● 条件式にマッチしたものを置き換えれる
54
まとめ
■ Goで静的解析を行うのは簡単
● 静的型付け、シンプルな文法、goパッケージ
■ goパッケージで簡単に静的解析を行える
● 字句解析、構文解析、型チェック
■ 製品開発での静的解析の利用
● 自作の静的解析ツール (例:gpath, go-httpdoc)
● Webアプリ(例: Banner Tool)
● マイグレーションツール(例:Datastore Wrapper)
55
Thank you!
twitter: @tenntenn
Qiita: tenntenn
connpass: tenntenn
56

More Related Content

What's hot

インタフェースの実装パターン
インタフェースの実装パターンインタフェースの実装パターン
インタフェースの実装パターン
Takuya Ueda
 
Goで言語処理系(の途中まで)を作ろう
Goで言語処理系(の途中まで)を作ろうGoで言語処理系(の途中まで)を作ろう
Goで言語処理系(の途中まで)を作ろう
Esehara Shigeo
 
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Takuya Ueda
 
今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋
Takuya Ueda
 

What's hot (20)

Goとテスト
GoとテストGoとテスト
Goとテスト
 
マスター・オブ・Reflectパッケージ
マスター・オブ・Reflectパッケージマスター・オブ・Reflectパッケージ
マスター・オブ・Reflectパッケージ
 
GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門
 
インタフェースの実装パターン
インタフェースの実装パターンインタフェースの実装パターン
インタフェースの実装パターン
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化
 
Goで言語処理系(の途中まで)を作ろう
Goで言語処理系(の途中まで)を作ろうGoで言語処理系(の途中まで)を作ろう
Goで言語処理系(の途中まで)を作ろう
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
 
GAE/Goとsyncパッケージ
GAE/GoとsyncパッケージGAE/Goとsyncパッケージ
GAE/Goとsyncパッケージ
 
今日から始める Go言語 と appengine
今日から始める Go言語 と appengine今日から始める Go言語 と appengine
今日から始める Go言語 と appengine
 
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
 
エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法
 
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
 
Goroutineと channelから はじめるgo言語
Goroutineと channelから はじめるgo言語Goroutineと channelから はじめるgo言語
Goroutineと channelから はじめるgo言語
 
今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋
 
Goでwebアプリを開発してみよう
Goでwebアプリを開発してみようGoでwebアプリを開発してみよう
Goでwebアプリを開発してみよう
 
Pynyumon03 LT
Pynyumon03 LTPynyumon03 LT
Pynyumon03 LT
 
GoでMinecraftっぽいの作る
GoでMinecraftっぽいの作るGoでMinecraftっぽいの作る
GoでMinecraftっぽいの作る
 
tse - Pythonによるテキスト整形ユーティリティ
tse - Pythonによるテキスト整形ユーティリティtse - Pythonによるテキスト整形ユーティリティ
tse - Pythonによるテキスト整形ユーティリティ
 
今年使ってみて良かった、Pythonモジュール、パッケージ、ツール
今年使ってみて良かった、Pythonモジュール、パッケージ、ツール今年使ってみて良かった、Pythonモジュール、パッケージ、ツール
今年使ってみて良かった、Pythonモジュール、パッケージ、ツール
 
Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)
 

Similar to マスター・オブ・goパッケージ

関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013
Esehara Shigeo
 
今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて
Takuto Matsuu
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0
Kiwamu Okabe
 
Play meetup-2-dev-best-practices
Play meetup-2-dev-best-practicesPlay meetup-2-dev-best-practices
Play meetup-2-dev-best-practices
k4200
 

Similar to マスター・オブ・goパッケージ (20)

Boost Fusion Library
Boost Fusion LibraryBoost Fusion Library
Boost Fusion Library
 
20170131 python3 6 PEP526
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526
 
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
 
ECMAScript没proposal追悼式
ECMAScript没proposal追悼式ECMAScript没proposal追悼式
ECMAScript没proposal追悼式
 
関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013
 
ひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指すひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指す
 
Mesh tensorflow
Mesh tensorflowMesh tensorflow
Mesh tensorflow
 
プログラマのための文書推薦入門
プログラマのための文書推薦入門プログラマのための文書推薦入門
プログラマのための文書推薦入門
 
2017-12-04 Linuxの基本構造とBashでの扱い方
2017-12-04 Linuxの基本構造とBashでの扱い方2017-12-04 Linuxの基本構造とBashでの扱い方
2017-12-04 Linuxの基本構造とBashでの扱い方
 
今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて
 
20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説
20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説
20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
 
LLdeade Python Language Update
LLdeade Python Language UpdateLLdeade Python Language Update
LLdeade Python Language Update
 
Subprocess no susume
Subprocess no susumeSubprocess no susume
Subprocess no susume
 
Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0
 
Play meetup-2-dev-best-practices
Play meetup-2-dev-best-practicesPlay meetup-2-dev-best-practices
Play meetup-2-dev-best-practices
 

More from Takuya Ueda

More from Takuya Ueda (18)

Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −
 
WebAssembly with Go
WebAssembly with GoWebAssembly with Go
WebAssembly with Go
 
そうだ、Goを始めよう
そうだ、Goを始めようそうだ、Goを始めよう
そうだ、Goを始めよう
 
メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新
 
Go Friday 傑作選
Go Friday 傑作選Go Friday 傑作選
Go Friday 傑作選
 
GoによるiOSアプリの開発
GoによるiOSアプリの開発GoによるiOSアプリの開発
GoによるiOSアプリの開発
 
Static Analysis in Go
Static Analysis in GoStatic Analysis in Go
Static Analysis in Go
 
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
 
オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選
 
Gopher Fest 2017参加レポート
Gopher Fest 2017参加レポートGopher Fest 2017参加レポート
Gopher Fest 2017参加レポート
 
Google Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめGoogle Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめ
 
Cloud functionsの紹介
Cloud functionsの紹介Cloud functionsの紹介
Cloud functionsの紹介
 
goパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するgoパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現する
 
Cloud Functionsの紹介
Cloud Functionsの紹介Cloud Functionsの紹介
Cloud Functionsの紹介
 
Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践
 
Mobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingMobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse Binding
 
粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法
 
GAE/GoでLINE Messaging API を使う
GAE/GoでLINE Messaging API を使うGAE/GoでLINE Messaging API を使う
GAE/GoでLINE Messaging API を使う
 

Recently uploaded

Recently uploaded (11)

Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 

マスター・オブ・goパッケージ