SlideShare a Scribd company logo
1 of 37
Download to read offline
YARVINTRODUCTION
WAKASUGI HIROFUMI
DECEMBER 20, 2015
Rubyプログラムが動く仕組みの中で、
中心的な役割の1つを占めるYARVを
簡単に紹介します。
YARVINTRODUCTION
YARV
(Yet Another Ruby VM)
• 現在のMRI (CRuby) の処理系
• Rubyコードを実行するための仮想マシン (VM)
• Ruby 1.9でMRIに取り込まれた
• 開発者は笹田耕一氏
YARVINTRODUCTION
仮想マシンとは?
YARVINTRODUCTION
ソフトウェアが動作する構造
ハードウェア
OS
ソフトウェア コンピューターでは、
ソフトウェアは左記の
ようなレイヤー構造で
動く仕組みとなってい
る
YARVINTRODUCTION
ソフトウェアが動作する構造
ハードウェア
OS
ソフトウェア
ソフトウェアはOSのAPIを利用
OSのカーネルがハードウェアを制御
ソフトウェアはOSによって「仮想化」されたハードウェア資源を活用する。
このように、間に仮想化機構を挟むことでギャップを埋め扱いやすくなる。
YARVINTRODUCTION
一般的に「仮想マシン」と聞いて思い浮かぶもの
ハードウェア
OS (※)
OS
あるOSの上に仮想化されたマシンを構築
し、別のOSなどを動かせるもの
ただ、YARVのような、プログラミング言
語における仮想マシンを考えるときには、
この仮想マシンのイメージに捉われすぎ
ない方がいいかも
※実際にはほとんどオリジナルのOSはスルーして直接ハード
ウェアを操作できることが多い
仮想マシン (VirtualBoxなど)
ソフトウェア
YARVINTRODUCTION
プログラミング言語処理系としての
「仮想マシン」
ハードウェア
OS
プログラミング言語 プログラミング言語は仮想マシン
が解釈できる命令に変換され、仮
想マシンがその命令をOSなどより
低い層に伝える
さっきのソフトウェアが動作する
ための仮想化機構と考え方は同じ
仮想マシン
YARVINTRODUCTION
VM VM VM
プログラミング言語処理系としての
「仮想マシン」
OS
プログラミング言語
VM
YARVINTRODUCTION
OS OS OS
HW HW HW HW
このように、プログラミング言語自体を
マルチ環境に対応できるよう設計するの
は非常に難しいが、仮想マシンを間に挟
むことで対応や最適化が容易になる
言語は仮想マシンが解釈できる命令を吐ければOK
仮想マシンのマルチ環境対応は比較的容易
仮想マシンが解釈するもの
=> バイトコード
YARVINTRODUCTION
プログラミング言語 バイトコード
仮想マシンが解釈
できる命令列
コンパイル
仮想マシン
命令
プログラム実行…
代表的な仮想マシン
YARVINTRODUCTION
Java JVM
• おなじみ「Write Once, Run Anywhere」
• Javaはもちろん、Scala、Clojureなど多数がこの処理系で動作する
.NET Framework
• MS製だがOSSとして公開されており、本来プラットフォームは問わない
• VB.NET、C#、F#などの言語がこの処理系で動作する
代表的な仮想マシン
YARVINTRODUCTION
Java
• おなじみ「Write Once, Run Anywhere
• Javaはもちろん、Scala、Clojure
.NET Framework
• MS製だがOSS
• VB.NET、C#、F#
LLVMもLLVM IRという中間表現を利用す
るなど仮想マシンに近いところはあるが、
厳密にはコンパイラ基盤なので
ちょっとジャンルが違う
仮想マシンのメリットまとめ
YARVINTRODUCTION
• マルチ環境への対応が容易になる
• 各環境への最適化がしやすく高速化が期待できる
• 別のプログラミング言語の開発もしやすい
仮想マシンという仲介役を用意し、プログラミング言語を
仮想マシンへの命令列にコンパイルする仕組みによって、
YARVINTRODUCTION
YARV
Overview
YARVINTRODUCTION
OS
Rubyコード
YARV
OS OS OS
HW HW HW HW
YARV YARV YARV
C C C C
① RubyコードはYARV命令列のバイトコードにコ
ンパイルされる
② 各環境に対応したYARVが、共通のYARV命令
列を解釈しCプログラムを生成して実行
•MRIはC言語実装なので、YARVを介してCの
プログラムとして実行される
•ネイティブコードに変換されるJVMなどとは
この点で異なるが、仮想化の構造的には同じ
YARV命令列とは?
YARVINTRODUCTION
def hello(name)
"Hello " + name
end
puts hello("Tom")
YARVINTRODUCTION
このRubyコードをコンパイルすると…?
YARVINTRODUCTION
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>===============
0000 trace 1 ( 1)
0002 putspecialobject 1
0004 putspecialobject 2
0006 putobject :hello
0008 putiseq hello
0010 opt_send_without_block <callinfo!mid:core#define_method, argc:3, ARGS_SIMPLE>
0012 pop
0013 trace 1 ( 5)
0015 putself
0016 putself
0017 putstring "Tom"
0019 opt_send_without_block <callinfo!mid:hello, argc:1, FCALL|ARGS_SIMPLE>
0021 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
0023 leave
== disasm: <RubyVM::InstructionSequence:hello@<compiled>>===============
local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] name<Arg>
0000 trace 8 ( 1)
0002 trace 1 ( 2)
0004 putstring "Hello "
0006 getlocal_OP__WC__0 2
0008 opt_plus <callinfo!mid:+, argc:1, ARGS_SIMPLE>
0010 trace 16 ( 3)
0012 leave ( 2)
こんなYARV命令列になる
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>===============
0000 trace 1 ( 1)
0002 putspecialobject 1
0004 putspecialobject 2
0006 putobject :hello
0008 putiseq hello
0010 opt_send_without_block <callinfo!mid:core#define_method, argc:3, ARGS_SIMPLE>
0012 pop
0013 trace 1 ( 5)
0015 putself
0016 putself
0017 putstring "Tom"
0019 opt_send_without_block <callinfo!mid:hello, argc:1, FCALL|ARGS_SIMPLE>
0021 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
0023 leave
== disasm: <RubyVM::InstructionSequence:hello@<compiled>>===============
local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1,
kwrest: -1])
[ 2] name<Arg>
0000 trace 8 ( 1)
0002 trace 1 ( 2)
0004 putstring "Hello "
0006 getlocal_OP__WC__0 2
0008 opt_plus <callinfo!mid:+, argc:1, ARGS_SIMPLE>
0010 trace 16 ( 3)
0012 leave ( 2)
?
YARVINTRODUCTION
YARVINTRODUCTION
puts 2 + 3
字句解析
構文解析
The Long and Winding Road to YARV Instructions
Rubyコード
コンパイル
YARV命令列
YARVINTRODUCTION
字句解析
Rubyコードを1文字ずつ読み込み解析する
10.times do |n|
puts n
end
YARVINTRODUCTION
字句解析
Rubyコードを1文字ずつ読み込み解析する
1 0 . t i m e s d o ¦ n ¦
10.times do |n|
puts n
end
YARVINTRODUCTION
字句解析
Rubyコードを1文字ずつ読み込み解析する
1 0 . t i m e s d o ¦ n ¦
10.times do |n|
puts n
end
tINTEGER
10
.
tIDENTIFIER
times
keyword_do ¦
tIDENTIFIER
n
¦
YARVINTRODUCTION
字句解析
Rubyコードを1文字ずつ読み込み解析する
1 0 . t i m e s d o ¦ n ¦
10.times do |n|
puts n
end
tINTEGER
10
.
tIDENTIFIER
times
keyword_do ¦
tIDENTIFIER
n
¦
トークン列
YARVINTRODUCTION
puts 2 + 3
字句解析
構文解析
The Long and Winding Road to YARV Instructions
Rubyコード
コンパイル
YARV命令列
コードをトークン列に分解
YARVINTRODUCTION
構文解析
tINTEGER
10
.
tIDENTIFIER
times
keyword_do ¦
tIDENTIFIER
n
¦
method_call: ... | primary_value '.' operation2 | ...
文法規則にマッチ
パーサが文法規則に基づいてトークン列の解析を行う
省略…
YARVINTRODUCTION
構文解析
program
method

add block
call
integer
10
period
identifier
times
do block
構文解析によってAST (抽象構文木) が生成される
YARVINTRODUCTION
構文解析
Ripperを使うと実際にASTを確認できる
require 'ripper'
require 'pp'
code = <<EOS
10.times do |n|
puts n
end
EOS
pp Ripper.sexp(code)
[:program,
[[:method_add_block,
[:call, [:@int, "10", [1, 0]], :".", [:@ident, "times", [1, 3]]],
[:do_block,
[:block_var,
[:params, [[:@ident, "n", [1, 13]]], nil, nil, nil, nil, nil, nil],
false],
[[:command,
[:@ident, "puts", [2, 2]],
[:args_add_block, [[:var_ref, [:@ident, "n", [2, 7]]]], false]]]]]]]
S式!
YARVINTRODUCTION
puts 2 + 3
字句解析
構文解析
The Long and Winding Road to YARV Instructions
Rubyコード
コンパイル
YARV命令列
コードをトークン列に分解
トークン列からASTを生成
YARVINTRODUCTION
YARV命令列へのコンパイル
より単純なRubyコードを元に説明
puts 2 + 3
Rubyコード
NODE_SCOPE
NODE_FCALL
method_id: puts
NODE_CALL
method_id: +
NODE_LIT
2
NODE_LIT
3
レシーバ 引数
ASTノード
putself
putobject 2
putobject 3
send <callinfo!mid:+, argc:1, …
send <callinfo!mid:puts, argc:1, ...
YARVINTRODUCTION
YARV命令列へのコンパイル
AST構造を りながら
YARV命令列スタックにプッシュしていく
NODE_FCALL
method_id: puts
NODE_CALL
method_id: +
YARV命令列
NODE_LIT
2
NODE_LIT
3
putself
putobject 2
putobject 3
opt_plus
opt_send_simple <callinfo!mid:puts, argc:1, ...
YARVINTRODUCTION
YARV命令列へのコンパイル
YARV命令列は最適化される
NODE_FCALL
method_id: puts
NODE_CALL
method_id: +
YARV命令列
NODE_LIT
2
NODE_LIT
3
更に最適化を行い、
最適化した命令に置き換える
YARVINTRODUCTION
puts 2 + 3
字句解析
構文解析
The Long and Winding Road to YARV Instructions
Rubyコード
コンパイル
YARV命令列
コードをトークン列に分解
トークン列からASTを生成
ASTから最適化された
YARV命令列 (バイトコード)
を生成
YARVINTRODUCTION
YARVが命令に従いCプログラムを実行
このようにしてRubyプログラムは実行される
$ cat example.rb
puts 2 + 3
$ ruby example.rb
5
字句解析、
構文解析、
YARV命令列へのコンパイル、
Cプログラムの実行
YARVINTRODUCTION
まとめ
Rubyのしくみを知ると
RubyKaigiをもっと楽しめる!
YARVINTRODUCTION
参考
★ YARV Maniacs
• http://magazine.rubyist.net/?0006-YarvManiacs
★ Rubyのしくみ Ruby Under a Microscope
• https://estore.ohmsha.co.jp/titles/978427405065P
以下の記事や書籍を思いっきり参考にしました
よちよち.rb
回オメデトウ

More Related Content

What's hot

Mruby jitプレゼン
Mruby jitプレゼンMruby jitプレゼン
Mruby jitプレゼンmiura1729
 
Osc tokyo2010 fall_zfs
Osc tokyo2010 fall_zfsOsc tokyo2010 fall_zfs
Osc tokyo2010 fall_zfs悟 宮崎
 
JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」
JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」
JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」y torazuka
 
リテラルと型の続きの話 #__swift__
リテラルと型の続きの話 #__swift__リテラルと型の続きの話 #__swift__
リテラルと型の続きの話 #__swift__Tomohiro Kumagai
 
JVMの中身を可視化してみた
JVMの中身を可視化してみたJVMの中身を可視化してみた
JVMの中身を可視化してみたKengo Toda
 
覚醒JavaScript -ES6で作るIsomophicアプリケーション-
覚醒JavaScript  -ES6で作るIsomophicアプリケーション-覚醒JavaScript  -ES6で作るIsomophicアプリケーション-
覚醒JavaScript -ES6で作るIsomophicアプリケーション-Oonishi Keitarou
 
XSSフィルターを利用したXSS攻撃 by Masato Kinugawa
XSSフィルターを利用したXSS攻撃 by Masato KinugawaXSSフィルターを利用したXSS攻撃 by Masato Kinugawa
XSSフィルターを利用したXSS攻撃 by Masato KinugawaCODE BLUE
 
JavaScript基礎勉強会
JavaScript基礎勉強会JavaScript基礎勉強会
JavaScript基礎勉強会大樹 小倉
 
DTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめDTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめMikiya Okuno
 
JavaのStreamで学ぶ遅延処理実装パターン
JavaのStreamで学ぶ遅延処理実装パターンJavaのStreamで学ぶ遅延処理実装パターン
JavaのStreamで学ぶ遅延処理実装パターンShinya Mochida
 

What's hot (11)

Mruby jitプレゼン
Mruby jitプレゼンMruby jitプレゼン
Mruby jitプレゼン
 
Osc tokyo2010 fall_zfs
Osc tokyo2010 fall_zfsOsc tokyo2010 fall_zfs
Osc tokyo2010 fall_zfs
 
覚醒!JavaScript
覚醒!JavaScript覚醒!JavaScript
覚醒!JavaScript
 
JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」
JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」
JJUG CCC 2013 Fall「JVMコードリーディング入門-JVMのOS抽象化レイヤーについて-」
 
リテラルと型の続きの話 #__swift__
リテラルと型の続きの話 #__swift__リテラルと型の続きの話 #__swift__
リテラルと型の続きの話 #__swift__
 
JVMの中身を可視化してみた
JVMの中身を可視化してみたJVMの中身を可視化してみた
JVMの中身を可視化してみた
 
覚醒JavaScript -ES6で作るIsomophicアプリケーション-
覚醒JavaScript  -ES6で作るIsomophicアプリケーション-覚醒JavaScript  -ES6で作るIsomophicアプリケーション-
覚醒JavaScript -ES6で作るIsomophicアプリケーション-
 
XSSフィルターを利用したXSS攻撃 by Masato Kinugawa
XSSフィルターを利用したXSS攻撃 by Masato KinugawaXSSフィルターを利用したXSS攻撃 by Masato Kinugawa
XSSフィルターを利用したXSS攻撃 by Masato Kinugawa
 
JavaScript基礎勉強会
JavaScript基礎勉強会JavaScript基礎勉強会
JavaScript基礎勉強会
 
DTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめDTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめ
 
JavaのStreamで学ぶ遅延処理実装パターン
JavaのStreamで学ぶ遅延処理実装パターンJavaのStreamで学ぶ遅延処理実装パターン
JavaのStreamで学ぶ遅延処理実装パターン
 

Similar to YARV INTRODUCTION

Web技術勉強会 第33回
Web技術勉強会 第33回Web技術勉強会 第33回
Web技術勉強会 第33回龍一 田中
 
OpenCVをAndroidで動かしてみた
OpenCVをAndroidで動かしてみたOpenCVをAndroidで動かしてみた
OpenCVをAndroidで動かしてみた徹 上野山
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPUTakuro Iizuka
 
【17-E-2】Ruby PaaS「MOGOK」 ~ ソフトウェアエンジニアのためのクラウドサービス ~ 藤原秀一氏
【17-E-2】Ruby PaaS「MOGOK」 ~ ソフトウェアエンジニアのためのクラウドサービス ~ 藤原秀一氏【17-E-2】Ruby PaaS「MOGOK」 ~ ソフトウェアエンジニアのためのクラウドサービス ~ 藤原秀一氏
【17-E-2】Ruby PaaS「MOGOK」 ~ ソフトウェアエンジニアのためのクラウドサービス ~ 藤原秀一氏Developers Summit
 
Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)
Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)
Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)axsh co., LTD.
 
Azure Application Insights + Angular5+ - Global azure boot camp 2019@sapporo LT
Azure Application Insights + Angular5+ - Global azure boot camp 2019@sapporo LTAzure Application Insights + Angular5+ - Global azure boot camp 2019@sapporo LT
Azure Application Insights + Angular5+ - Global azure boot camp 2019@sapporo LTJun-ichi Sakamoto
 
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方Yoshifumi Kawai
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
20091119_sinatraを使ってみた
20091119_sinatraを使ってみた20091119_sinatraを使ってみた
20091119_sinatraを使ってみたngi group.
 
マイクラ自動化枠第1回資料
マイクラ自動化枠第1回資料マイクラ自動化枠第1回資料
マイクラ自動化枠第1回資料Ryo Fujita
 
ET2014資料: mruby プログラム言語Rubyによる組込みソト開発
ET2014資料: mruby プログラム言語Rubyによる組込みソト開発ET2014資料: mruby プログラム言語Rubyによる組込みソト開発
ET2014資料: mruby プログラム言語Rubyによる組込みソト開発Kazuaki Tanaka
 
Node.js基礎の基礎 - Miyazaki.js vol.2
Node.js基礎の基礎 - Miyazaki.js vol.2Node.js基礎の基礎 - Miyazaki.js vol.2
Node.js基礎の基礎 - Miyazaki.js vol.2Nobuhiro Nakashima
 
Scalatronで楽しく学ぶ関数型プログラミング
Scalatronで楽しく学ぶ関数型プログラミングScalatronで楽しく学ぶ関数型プログラミング
Scalatronで楽しく学ぶ関数型プログラミングJun Saito
 
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Taisuke Oe
 
巨大ポータルを支えるプライベート・クラウド構築事例から学べ!~攻める情シスのためのインフラ構築、その極意とは?~
巨大ポータルを支えるプライベート・クラウド構築事例から学べ!~攻める情シスのためのインフラ構築、その極意とは?~巨大ポータルを支えるプライベート・クラウド構築事例から学べ!~攻める情シスのためのインフラ構築、その極意とは?~
巨大ポータルを支えるプライベート・クラウド構築事例から学べ!~攻める情シスのためのインフラ構築、その極意とは?~Brocade
 

Similar to YARV INTRODUCTION (20)

MlnagoyaRx
MlnagoyaRxMlnagoyaRx
MlnagoyaRx
 
Web技術勉強会 第33回
Web技術勉強会 第33回Web技術勉強会 第33回
Web技術勉強会 第33回
 
RxSwift
RxSwiftRxSwift
RxSwift
 
OpenCVをAndroidで動かしてみた
OpenCVをAndroidで動かしてみたOpenCVをAndroidで動かしてみた
OpenCVをAndroidで動かしてみた
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU
 
【17-E-2】Ruby PaaS「MOGOK」 ~ ソフトウェアエンジニアのためのクラウドサービス ~ 藤原秀一氏
【17-E-2】Ruby PaaS「MOGOK」 ~ ソフトウェアエンジニアのためのクラウドサービス ~ 藤原秀一氏【17-E-2】Ruby PaaS「MOGOK」 ~ ソフトウェアエンジニアのためのクラウドサービス ~ 藤原秀一氏
【17-E-2】Ruby PaaS「MOGOK」 ~ ソフトウェアエンジニアのためのクラウドサービス ~ 藤原秀一氏
 
Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)
Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)
Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)
 
Azure Application Insights + Angular5+ - Global azure boot camp 2019@sapporo LT
Azure Application Insights + Angular5+ - Global azure boot camp 2019@sapporo LTAzure Application Insights + Angular5+ - Global azure boot camp 2019@sapporo LT
Azure Application Insights + Angular5+ - Global azure boot camp 2019@sapporo LT
 
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
20091119_sinatraを使ってみた
20091119_sinatraを使ってみた20091119_sinatraを使ってみた
20091119_sinatraを使ってみた
 
マイクラ自動化枠第1回資料
マイクラ自動化枠第1回資料マイクラ自動化枠第1回資料
マイクラ自動化枠第1回資料
 
Real world rails
Real world railsReal world rails
Real world rails
 
ET2014資料: mruby プログラム言語Rubyによる組込みソト開発
ET2014資料: mruby プログラム言語Rubyによる組込みソト開発ET2014資料: mruby プログラム言語Rubyによる組込みソト開発
ET2014資料: mruby プログラム言語Rubyによる組込みソト開発
 
Node.js基礎の基礎 - Miyazaki.js vol.2
Node.js基礎の基礎 - Miyazaki.js vol.2Node.js基礎の基礎 - Miyazaki.js vol.2
Node.js基礎の基礎 - Miyazaki.js vol.2
 
Scalatronで楽しく学ぶ関数型プログラミング
Scalatronで楽しく学ぶ関数型プログラミングScalatronで楽しく学ぶ関数型プログラミング
Scalatronで楽しく学ぶ関数型プログラミング
 
JRuby on Rails
JRuby on RailsJRuby on Rails
JRuby on Rails
 
Java on Azure 2019
Java on Azure 2019Java on Azure 2019
Java on Azure 2019
 
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Real World Android Akka - 日本語版
Real World Android Akka - 日本語版
 
巨大ポータルを支えるプライベート・クラウド構築事例から学べ!~攻める情シスのためのインフラ構築、その極意とは?~
巨大ポータルを支えるプライベート・クラウド構築事例から学べ!~攻める情シスのためのインフラ構築、その極意とは?~巨大ポータルを支えるプライベート・クラウド構築事例から学べ!~攻める情シスのためのインフラ構築、その極意とは?~
巨大ポータルを支えるプライベート・クラウド構築事例から学べ!~攻める情シスのためのインフラ構築、その極意とは?~
 

YARV INTRODUCTION