メルペイの Backend Engineer's meetup SIer に参加してきました
私は5年ほど前から大手のSIerの中で、フリーランスとして常駐してます。
その中見つけたメルペイさんのイベント、「Backend Engineer's meetup SIer経験者が語る自社サービス開発の魅力」。
ダメもとで応募して抽選待ちしてましたが、まさかの当選しました。
自分の経験と重ね合わせて、記録していきます。
イベント概要
SIer出身のメルペイの社員の方4名が、SIerとメルペイでの違いを個人の経験をもとに述べていきます。
パネルディスカッション後はQ&Aを行い、参加者が聞きたいことをぶつけることができます。
最後はお酒と軽食をつまみながら、メルペイの社員の方とざっくばらんに会話をする機会が用意されています。
パネルディスカッション
開発プロセスの違い
開発プロセスと聞いて、すぐ出てくるのは、ウォータフォールとアジャイル。
メルペイではアジャイルで行っています。
SIerの時はウォータフォールで開発をしていたから、そこが違いに感じられたようです。
ちなみに確かにSIerはウォータフォールが多いイメージですが、なぜか自分はアジャイル開発が多いです。
先行開発部隊に入る確率が高いため、プロトを短い単位でお客さんに見せたいという要望が多く、そうなっているのだと思います。
あと意見が分かれてたのは、レビューの密度。
SIer系の時の方が雑だったという意見もあれば、むしろSIerの時の方が細かくレビューしていたという意見もありました。
会社で求められていることや、お客さんが求めていることによって、レビューの密度は変わるので、意見が異なるのは納得します。
ともかく品質は良いから、スピード重視でというお客さんの時と、
品質を大切にしてくれ、というお客さんの時とでは、レビューの仕方が変わります。
ではメルペイではレビューはどのように行っているのか?
メルペイでは当然自分で作ったものが、自社サービスとして動きます。
つまり甘いレビューでバグを残してしまっては、自社にそのツケが戻ってくることになります。
だからこそGithubのプルリクを使って、密にレビューを行っているそうです。
このレビューが通らなければ、世にサービスが出回らないわけです。
あとWeb系ということもあり、リファクタリングを多いそうです。
Sier時代の経験でいかせていること
SIerの時にレビューを紙ベースで、赤ペンで行っていたなんて経験があるなんて昔話をメルペイの方が話してくれました。
だからコピー機の使い方がうまくなったことが、活かせているらしい・・・(笑)
というのは置いておき、
- スケジュールの逆引き
- お客さんとのコミュニケーションスキル
- ドキュメントスキル
が活かされているとのことでした。
メルペイでは、本番運用とかリリース時期の意識が、SIer時代と比べ、皆薄かった気がしたとのことでした。
後になって駆け込みで、あれが足りないこれが足りないって言ったところがらしい・・・
これ私のチームでやったら、上層部から怒られて他のチームに飛ばされかねないです。
確かになって思ったのは、コミュニケーションスキルやドキュメントスキル。
SIerはお客さんの要望やレベル感で、コミュニケーションの仕方や、書き残すドキュメントのレベルが変わってきます。
一生懸命システムを細かく書いた資料を、非システム部門の方渡しても意味がありません。
お客さんの中では、システムはあくまでも業務の補助でしかないので、主体をお客さんの業務にした資料を作らなければならない。
などなど考えていると、確かにSIerでの経験は役に立つのだなって思いました。
求められるスキルセットの違い
SIerでは、与えられた案件を一直線にやっていくことが多かった。
対して、メルペイでは自走する力が必要となる。
自社のサービスなので、自発的な行動ができる自由さがあるのだ、とおっしゃっていました。
またWeb系はコードの品質に関して、
- デザインパターンは意識しているか
- 言語の特性は理解しているか
- 言語の慣習は理解しているか
を聞かれることが多いといいます。
SIer系だと、どんな案件が回ってくるかわかりませんよね。
自分も、全く知らない言語や分野の先行開発とかよくあります。
そうしているうちに、調査能力が身についたり、マルチにプログラミングができるようになります。
それが良いと取るか、悪いと取るかは人それぞれだと思います。
メルペイでは自社開発なのでそういった感じではなく、どちらかというと自社に関連した技術に特化していくイメージ。
深く深く掘り下げ、また最新技術が有用だと思えば、取り込んでやっていく感じがしました。
メルカリ・メルペイと、他の自社開発の違い
自社サービスだからこそ、PMに対して、自分の意志が反映しやすいというところがあります。
例えばデザインとか、反映されやすいのではとのこと。
逆にSIerだとデザインを修正するより、業務ロジックの修正を求められることが多いです。
背景としては、デザインはKPIなど定量的に表すのは難しく、それを見積もって金額が高くなったら、後回しにされます。
この経験は自分もよく経験しています。
当然ではありますが、お客さんは費用に対しての効果を求めてきます。
デザイン変えたら、どうなるんだとか、
最新技術に置き換えて、意味があるかなど。
決定権は常にお客さんにあるので、経験上デザインに関しては後回しにされることが多かったです。
納品がない自社サービスについて
「バス運行している会社と、個人タクシーの違いに似ている」
バスは時刻表通りに到着しなければならないので、時間が決まっている。
個人タクシーは時間通りである必要はないので、自分の裁量で多く働いたり、短めに働いたりできる。
SIerだってメルペイだって、システムを開発するというのは同じ。
だがそのアプローチの自由度というのは、メルペイの方が明らかに大きく感じられるとのことでした。
自由というのはその分、責任があります。
SIerは割とリリースしたら「はい!終わり」なんてケースが多いかと思います。
もちろん保守し続けるところもあるので、一概には言えませんが。
自社サービスでやっている分、自分で書いた失敗が、そのまま数年後に帰ってくることがあります。
そことが違いとして感じられたそうです。
自社開発に転職した時のキャリアアップ
SIerの時は、いつもコードを書いているわけではなく別作業を行っていたことが多かったらしいです。
メルペイでは、ほぼ毎日コードを書いていて、技術が身についているとのこと。
なお勉強方法は皆それぞれでした。
独学でやられている方もいれば、Gopher道場で技術を身につけた方もいました。
また技術だけでなくマインドの部分も変わったといいます。
自分たちの作ったものが、自分に返ってくるという意識が強くなった。
そのおかげで、より良いものを作る意識が強くなったとのこと。
チーム内の雰囲気
開発チームによって違い、多国籍で少人数のチームもあれば、大人数のチームがある。
会社的に英語を身に付けてほしい、という意思があるようで、英語の勉強会や宿題などがあるようです。
Slackでは英語でやり取りをするようにしたり、コードのコメントを英語で行うようにしています。
また仕事に飲みに行ったりするチームもあるみたいですが、
既婚者が多いチームだと、夜は厳しいので、ランチに良いものを食べに行くことが多いところもあるみたいです。
自分も子供がいて、なかなか今の現場チームの人と飲みに行ったりできないのですが、こういった気遣いがあるチームはうらやましい。
ちなみにメルペイでは、チームビルディング制度があって、飲み代を会社に請求するとそれが返ってくるそうです。
人事評価
クォータごとの人事評価があります。
人事評価2回分、つまり年2回給与変わるみたいです。
評価方法は、指標としてはOKRをベースに、どのぐらい目標を達成できたかをみます。
またOKRで評価できない部分も、しっかり評価するようです。
マネージャと1on1でメンバーと話したりするそうで、その人の能力に紐づくものとする試みが感じられました。
感想
率直にエンジニアとして、非常にそそられる会社だなって思いました。
自由に開発ができる感じ、個人を大切にしている感じがありました。
常に前を向いて進んでいるのも、いいですよね。
また飲みの席で社員の方と話していても、自分の技術力でも役に立てると感じました。
Go言語を学んでいく 第3弾:配列、スライス、マップ
Go言語の基礎を学んでいくシリーズ。
Go言語を学んでいく 第1弾:基礎 - PC依存エンジニアのブログ
Go言語を学んでいく 第2弾:基本的なステートメント - PC依存エンジニアのブログ
第3弾は配列、スライス、マップを見ていきます。
配列
宣言方法
以下のパターンがあります。
- var 変数名 [Length]型
- var 変数名 [Length]型 = [Length]型 {初期値}
- 変数名 := [...]型 {初期値}
- 変数名 := new([length]型)
3つ目の[...]の部分は、初期値に合わせて自動的に長さをカウントしてくれることを指します。
またインデックスは0から始まる点に注意です。
サンプルコードは以下のようになります。
package main import ( "fmt" ) func main() { var a [3]int var b [3]int = [3]int{1, 2, 3} c := [...]int{1, 2, 3} d := new([3]int) fmt.Println(a) fmt.Println(b) fmt.Println(c) fmt.Println(d) }
長さ
配列の長さは
len(変数名)
で取得することができます。
package main import ( "fmt" ) func main() { c := [...]int{1, 2, 3} fmt.Println(len(c)) }
スライス
他言語では、あまり聞かないと思います。
スライスは、配列内の要素への参照です。
スライス型は、このスライスを集合を表しています。
宣言方法
以下のパターンがあります。
- var 変数名 []型
- var 変数名 型 = 型 {初期値}
- 変数名 := []型 {初期値}
- 変数名 := 配列[開始インデックス:終了インデックス]
- 変数名 := make([]型, length, capacity)
- 変数名 := new([length]型)[開始インデックス:終了インデックス]
ほとんど配列の宣言と同じですが、長さを指定することはありません。
package main import ( "fmt" ) func main() { array := [...]int{1, 2, 3} var a []int var b []int = []int{1, 2, 3} c := []int{1, 2, 3} d := array[0:2] e := make([]int, 3, 3) f := new([3]int)[0:2] fmt.Println(a) fmt.Println(b) fmt.Println(c) fmt.Println(d) fmt.Println(e) fmt.Println(f) }
要素の追加
append関数を使用することで、簡単に要素を追加することができます。
append(変数名, 値)
ただし、新しいスライスが返ってくるので注意が必要です。
package main import ( "fmt" ) func main() { a := []int{1, 2, 3} b := append(a, 4) fmt.Println(a) fmt.Println(b) }
メモリの共有
スライスは配列の参照ですので、配列の値が変更されると、スライスが示す値も変更されます。
逆にスライス経由で値を変更すれば、参照先の配列の値も変更されます。
package main import ( "fmt" ) func main() { array := [...]int{1, 2, 3} a := array[0:] fmt.Println(array, a) array[0] = 4 fmt.Println(array, a) a[0] = 1 fmt.Println(array, a) }
マップ
JavaとかならHashMap、C#やpythonならDictionaryに相当する部分です。
ユニークになるキーと、値を管理しています。
なお要素の順序は持っていません。
宣言方法
以下のパターンがあります。
- make(map[キーの型]値の型)
- make(map[キーの型]値の型, 容量の初期値)
- map[キーの型]値の型 {初期値}
容量の初期値は省略可能です。
package main import ( "fmt" ) func main() { a := make(map[int]string) b := make(map[int]string, 2) c := map[int]string{1: "one", 2: "two"} fmt.Println(a) fmt.Println(b) fmt.Println(c) }
補足になりますが、make関数で容量の初期値を指定しても、その容量以上登録できないわけではありません。
上の例であれば、変数bに2個以上要素を登録できます。
容量オーバになったら、自動で容量を拡張してくれるわけです。
だったら初期値を設定する意味ないじゃんとなりそうですが、
容量の初期値を設定するメリットは、処理を高速にするためです。
map容量を拡張するとき、元データのコピーと再ハッシュが行われます。
つまり容量を確保していない場合、毎回元データのコピーと再ハッシュが行われてしまい、処理負担が大きくなります。
だったら最初からある程度の容量を確保しておいた方が、処理の高速化につながります。
だからといって容量をとりすぎるのはダメですよ。。
要素の挿入、更新
挿入と更新は、キーと値を指定して、登録します。
この時すでにキーが登録されていれば、更新となり、
キーが未登録であれば、挿入となります。
変数名[key] = 値
package main import ( "fmt" ) func main() { a := map[int]string{1: "one", 2: "two"} fmt.Println(a) a[3] = "Three" fmt.Println(a) a[1] = "iti" fmt.Println(a) }
要素の取得
キーを指定して、取得できます。
変数名[key]
なお存在しないキーを指定され場合、デフォルト値が返却されますので注意が必要です。
package main import ( "fmt" ) func main() { a := map[int]string{1: "one", 2: "two"} fmt.Println(a[1]) fmt.Println(a[10] == "") }
要素の削除
要素の削除はdelete関数で行います。
delete(変数名, key)
package main import ( "fmt" ) func main() { a := map[int]string{1: "one", 2: "two"} fmt.Println(a) delete(a, 2) fmt.Println(a) }
次回
第4弾ではポインタと構造体を見ていきます。
VS CodeとCloud Codeを使って、GKE上で動かして見る
Google Cloud Next ’19 に参加してきました。
その中でVisual Studio Codeの拡張機能で使用できるCloud Codeの話題があったので、早速使ってみました。
Cloud Codeとは
IDEからクラスタの管理やクラウドへのデプロイ、デバッグを行うことができます。
cloud.google.com
今までKubernetesを使った開発を行う場合、以下のデメリットがありました。
- Painful Development Cycle
変更するたびに繰り返し同じ作業が必要
- Context Switch
DE使ったり、ターミナルを使ったり、ブラウザ使ったりとコンテキストスイッチによる生産性の低下
- High Learning Cost
Kubernetes関連ツールをすべて覚えるのは困難
情報を把握し、どのツールを使うのかの判断が大変
チームに参画した人へのサポートが大変
そこでCloud Codeを利用することで、一つのIDEで統合的かつ簡単に管理することができます。
これにより開発者はよりコードに集中する環境ができるようになります。
Cloud Codeは
の拡張機能として使うことができます。
前置きはこれぐらいにして、早速Hello Worldを表示するまでやってみます。
Cloud Codeを動かす
今回はVisual Studio Codeで、Cloud Codeを動かします。
Hello Worldを表示するページを出すだけのプロジェクトを、新規に作成します。
新規アプリケーション
VS Codeで、⌘⇧Pでコマンドパレットを開きます。
「cloud code: new」と入力し、「Cloud Code: New Application」を選択し、新しいアプリケーションを作成します。
hello-world用のプロジェクトが言語ごとにあると思いますが、今回はGo言語を指定します。
プロジェクト名を入力して、作成します。
作成に成功すると、hello world用のテンプレートが作成されます。
新規クラスタ
GKEクラスタを新規に作成します。
VS Codeで、⌘⇧Pでコマンドパレットを開きます。
「cloud code create」と入力すると、「Cloud Code: Create GKE Cluster」を選択し、新しいクラスタを作成します。
そうするとクラスタを作成するための、設定画面が開きます。
各項目を入力して、「Create Cluster」ボタンからクラスタを作成してください。
※ Compute Engine APIを有効にしないと、設定ができません。
クラスタの作成が成功すると、「GOOGLE KUBERNATES ENGINE EXPLORER」のなかにクラスタ情報が表示されます。
クラスタを右クリックして、「Set as Active Cluster」でクラスタを有効化しましょう。
デプロイ
GCP上でビルドして、imageファイルを作成し、クラスタ上でプロジェクトを動かしましょう。
VS Codeで、⌘⇧Pでコマンドパレットを開きます。
「cloud code deploy」と入力すると、
- Deploy
- Continuous Deploy
があります。
前者は一度のみのデプロイ、
後者は初回デプロイした後、変更を検知し、自動でデプロイします。
今回はContinuous Deployします。
続いてビルド方法は
- default
- cloud build
があります。
defaultは、ローカル環境でビルドします。
cloudbuildは、Cloud Build環境でビルドをします。
今回はcloudbuildを選択します。
※Cloud Build APIを有効にしないと、ビルド権限がないとエラーが返ってきます。
続いてイメージの登録先を指定すると、デプロイが開始されます。
イメージの確認
Container Registryのページから、イメージファイルが作成されていることが、確認できます。
まとめ
Cloud Codeがなかったら、たったこれだけのことでも画面をあっちこっち切り替えて、設定する必要があります。
これをCloud Codeを使用することで、インフラ出身でない自分でも簡単に設定することができました。
まだまだ細かい設定ができそうなので、引き続き使って行きたいと思います。
Go言語を学んでいく 第2弾:基本的なステートメント
第1弾ではGo言語の基礎的なところをやってきました。
iristech.hatenablog.com
今回はGo言語の基本的なステートメントについて学んでいきましょう。
ifステートメント
他の言語と同じように、シンプルに書くことができます。
package main import ( "fmt" ) func main() { x := "rainy" if x == "sunny" { fmt.Println("Happy day.") }else if x == "cloudy" { fmt.Println("Not bad.") }else if x == "rainy" { fmt.Println("Bad day.") } }
さらにGo言語では条件式の直前に実行する、簡易ステートメントを記述できます。
つまり x := "rainy"の部分を、if文の中に埋め込めます。
ただし変数はスコープはif文内のみとなりますので、外側では使用できません。
package main import ( "fmt" ) func main() { if x := "rainy"; x == "sunny" { fmt.Println("Happy day.") } else if x == "cloudy" { fmt.Println("Not bad.") } else if x == "rainy" { fmt.Println("Bad day.") } // xはスコープ外になる // fmt.Println(x) ⇒ NG }
switchステートメント
式switch
JavaやC#と異なり、breakを記述せずとも、case節が終わると次のcase節に行かず、そのままswitch文は終了します。
もし次のcase節に行ってほしい場合は、fallthroughステートメントを使用します。
package main import ( "fmt" ) func main() { x := "rainy" switch x { case "sunny": fmt.Println("Happy day.") case "cloudy": fmt.Println("Not bad.") case "rainy": fallthrough default: fmt.Println("Bad day.") } }
こちらもif文同様に、簡易ステートメントを記述することが可能です。
package main import ( "fmt" ) func main() { switch x := "rainy"; x { case "sunny": fmt.Println("Happy day.") case "cloudy": fmt.Println("Not bad.") case "rainy": fallthrough default: fmt.Println("Bad day.") } }
またswitch式が空の場合は、trueと記述した場合と同じ扱いになります。
package main import ( "fmt" ) func main() { x := "rainy" switch { case x == "sunny": fmt.Println("Happy day.") case x == "cloudy": fmt.Println("Not bad.") case x == "rainy": fallthrough default: fmt.Println("Bad day.") } }
型switch
式switchでは値の比較を行っていました。
型switchでは型の比較を行って、条件分岐していきます。
package main import ( "fmt" ) func main() { var x interface{} = "rainy" switch x.(type) { case nil: fmt.Println("This is nil.") case int: fmt.Println("This is int.") case string: fmt.Println("This is string.") default: fmt.Println("Other type.") } }
※インターフェースに関しては、第5回で解説します。
forステートメント
forステートメントに関しては、他言語とそこまで違いはありません。
package main import ( "fmt" ) func main() { for i := 0; i < 10; i++ { fmt.Println(i) } }
条件部分以外は省略可能なので、以下のように書き換えることもできます。
package main import ( "fmt" ) func main() { i := 0 for i < 10 { fmt.Println(i) i += 1 } }
続いて
を見てみましょう。
package main import ( "fmt" ) func main() { for i := 0; i < 10; i++ { if i == 6 { break } if i%2 == 1 { continue } fmt.Println(i) } }
ちなみに他言語にあるwhileやuntilなどは、forステートメントで記載できるので、Go言語に存在しません。
gotoステートメント
そこまで頻出するステートメントではありませんが、覚えておいた方がいいgotoステートメント。
gotoステートメントは指定したラベルへジャンプすることができます。
下記の例ではラベルL1にジャンプしています。
package main import ( "fmt" ) func main() { weather := "sunny" if weather == "sunny" { goto L1 } fmt.Println("bad weather but ") L1: fmt.Println("happy days") }
gotoで使えるのは2重ループの時などで、ループを脱出したいときです。
breakステートメントは、最も近いループの脱出しかできないため、2重ループの場合、2回breakを書かなければなりません。
package main import ( "fmt" ) func main() { doBreak := false for i := 0; i < 10; i++ { for j := 10; j > 0; j-- { if i == j { doBreak = true break } fmt.Println(i, j) } if doBreak { break } } fmt.Println("END") }
対してgotoだと簡単に脱出できます。
余計なdoBreak変数も使わずに済みます。
package main import ( "fmt" ) func main() { for i := 0; i < 10; i++ { for j := 10; j > 0; j-- { if i == j { goto L1 } fmt.Println(i, j) } } L1: fmt.Println("END") }
次回
Go言語の配列、スライス、マップについて学んでいきます。
Bonfire Backend #3 に参加②(メルペイ、PayPay)
今日も引き続き、Bonfire Backendの続きを記録します。
再び唐揚げドーン!
第2弾は、メルペイとPayPayです。
メルペイ
よくCMでも見かけるので、言わずも知れていますが、MPM式の決済サービスです。
www.merpay.com
サーバサイド
メルペイではGCP上で、Go言語でマイクロサービスを構築しています。
メルカリって言ったらGo言語っていう勝手なイメージがあります。
よくGo言語のイベントがありますからね。(一度も抽選通ったことありませんが。。)
EMV規格にそうように、go-my-codeライブラリを使用しています。
github.com
マイクロサービスアーキテクチャ
決済のアーキテクチャーに関して、メルカリさんのブログで公開されていますので、こちらは非常にわかりやすくて参考になります。
tech.mercari.com
リクエストに対してAPI Gatewayが受け付けます。
その後StaticMPM ServiceでQRコード解析、セッショントークン管理、決済処理を行います。
決済処理に関してはさらに、別のマイクロサービスに委託することで、さらなる独立性を実現しています。
不整合対策
マイクロサービスにしていることで、機能は分散されますが、その分マイクロサービス間の整合性は確保しなければなりません。
その対策として以下を挙げておりました。
冪等性
二重決済などされないようにするため、クライアントからのリクエストの内容にidempotency keyを持たせるようにしています。
その結果同じリクエストに対して、同じ結果が返せるようになっています。
Write repair
マイクロサービス間で障害があった場合、リトライして不整合を修復するようにしている。
その際のライブラリとして、retryを使用しています。
http:// https://godoc.org/github.com/grpc-ecosystem/go-grpc-middleware/retry
Asynchronous repair
Write repairで修復できなかった場合、非同期にチェックして、修復するようにする。
課題
課題として挙がったのは、
- 上記内容を各マイクロサービスに実装するのが大変
- 擬似的に障害を起こして、テストするのが難しい
といった点がありました。
これから
Envoyを使用して、流行りのサービスメッシュを導入してみたい
PayPay
こちらも多々CMで見かけますね。
なんと900万顧客、70万店舗で利用されているらしいです。すごい規模!
さらに常に40~50のキャンペーンが動いているみたいです。
paypay.ne.jp
開発スタイル
アジャイル型で週1スプリントで進める。
10ヶ月間で50回以上のリリースをしているそうです。
外国籍のエンジニアが40%以上います。
サーバサイド
AWS上で動作し、マイクロサービスをJavaのSpring Frameworkで構築されています。
60以上のマイクロサービスがあるそうです。
マイクロサービスにした理由として、
- 開発とリリースも早くなる
- 決済に影響させずに、関係ない部分の製造ができる
- ビジネスコンテキストが増えたら、マイクロサービスを増やせばいい
などがありました。
またWriteとReadでDBが分離されています。
マイクロサービスアーキテクチャー
Kafkaを使用して、イベント駆動の非同期サービスを実現しています。
つまりKafkaにPublishされたイベントを、興味があるサービスだけが取り出して、処理を行うようになっています。
またAkka StreamsをScalaで構築することで、分散・並列のストリーミング処理を実現しています。
利点
このアーキテクチャーでの利点として、
- 一部イベントだけ別環境に流し、テストしてそのまま移行も可能
- サービス依存が少ない
- Amazon RDS からAmazon Auroraへのマイグレーションをメンテナンスなく進められる
課題
こちらでもマイクロサービスの整合性の担保の難しさが挙がっていました。
またAkka内部が見えないので、可視化する必要があると言った点もありました。
参加した感想
今までバックエンドエンジニアとして、マイクロサービスの製造は関わってきましたが、インフラ周りは専門ではありませんでした。
なので今回、たくさん初めて知った技術を聞くことができたした。
今後はもっと初めて知った技術を掘り下げていき、掲載できれば載せていきたいと思います。
それとこう言った、最新技術を触れる環境が非常に羨ましく思えました。
エンジニアにとっては、非常に充実した会でした。
また参加したいと思います。
Bonfire Backend #3 に参加①(Origami Pay、Kyash)
Bonfire Backend #3 に参加してきました。
マイクロサービスの製造や、ECサイトのバックエンド側の製造をやってはいましたが、
流行りのCPMやMPMでの決済は関わったことはなかったので非常に楽しかったです。
それにこの唐揚げの山
唐揚げがBonfireしてました!
メモをとったらかなりの量になったので、抜粋して2回に分けて記載していきます。
第1弾は、Origami Pay、Kyashです。
Origami Pay
MPM式でのQRコード決済ができます。
詳細はHP
https://origami.com/origami-pay/
Origami Pay の仕組み
手順としてはこのようになります。
①加盟店で金額を入力してもらい、お支払いコードを発行
②お客様が支払いコードを自分の端末に入力
ところで入力方法は以下の方法があります。
①手入力(カメラが使えないときにも使用できる)
②iBeacon(すでに廃止)
③QRコード
iBeaconは初めて聞いたので調べてみました。
iBeacon
Appleが開発しており、BLE規格で非接触型の決済ができる
Android端末でも使用することができます。
BLE規格は、Bluetooth Low Energyの略語で、
極めて省電力で動作する無線通信の技術。通信速度は低速だが、省電力なので長持ちしやすい
といった特徴を持っております。
ただしデメリットがあって、
・電波を使用して通信を行っている分、受信状況が悪くなりがちで、決済に失敗しやすかった
・受信状況が悪いと、失敗したかどうかの判断をすることが困難になることが多かった
・端末によっては、電波の発信場所が異なるため、店員さんやお客さんにとっても負担があった
といった問題があります。
iBeaconと比べると、QRコードであれば、受信状況の影響もなくなるし、端末による戸惑いも少なくなります。
さらにエラーの判断もしやすいため、Origami Payでは徐々にQRコードに移行し、iBeaconは廃止されていきました。
余談ではありますが、
卓越してくると、肉眼でiBeaconの電波が見えてくるらしいです。
ぜひ見たい方はiBeaconを見えるまで使ってみたください。
Kyash
プリペイド式のVisaカードで、チャージやスマホでリアルタイムで管理したり、
現在開発中(Kyash Direct)だが、企業向けにAPIを開放して、パートナー企業がカード発行や決済などを行うことができるようにしている。
kyash.co
サーバサイド
AWS上で動作し、マイクロサービスをGo言語で実装しています。
マイクロサービス間の通信は同期で行っています。
スマホアプリからの通信と、VisaNetからのリクエストを、AWSのEC2インスタンス経由で受け取って処理を行う形になっています。
Visa決済の仕組み
普段カード会社がやるべき処理を内製して作っています。
例えば仮売り上げ処理や売り上げ確定処理などです。
ちなみにこのメッセージのやり取りはvisa特有の電文で行うそうですが、英語で1000ページはあるそうで、毎日眠気との戦いとおっしゃっていました。
内省したことによる利点
本来なら他社に処理を委託するところを、内製してますので、リアルタイム性が実現できます。
また自動でチャージすることも利点として挙げておりました。
対策
履歴の作成処理の負荷に対してのアプローチ
- CQRSでシステム全体を更新系と参照系で処理を分散する
- それぞれの処理は各サービスで処理し、履歴の検索は参照系の責務にする
といったことがあげられました。
用語
簡単に用語をまとめておきます。
いつかまた記事で掘り下げていきたいと思っております。
CQRS
Command and Query Responsibility Segregation(コマンド クエリ責務分離)の略語です。
コマンド側(更新系)とクエリ側(参照系)で完全に機能を分けてしまい、処理分散を図ってしまおうと。
そもそもコマンド側とクエリ側で求められる要件が異なるので、各々に沿ったアーキテクチャで製造することができます。
Choreography
それぞれのサービスが自立して動作し、あらかじめ定められた他のサービスを呼び出す方式です。
ちなみにそれぞれ自立してますので、結果を返すという概念はありません。
補足
builders con tokyo 2019で詳細な説明をしていただけるそうです。
ちなみに自分は行ってみようかと思っています。(嫁が許せば・・・)
builderscon.io
Go言語を学んでいく 第1弾:基礎
最近Go言語を使ってますので、その記録をしていきます。
早速じゃんじゃん行きましょう。
対象者
Go言語を学ぶ意思がある
他言語でのプログラミング経験がある方
簡単な標準出力
いきなりコードから・・・
package main import ( "fmt" ) func main() { fmt.Println("Golang is good.") }
packageやimportあたりは、「Go言語を学んでいく 第6弾:パッケージ」の投稿でしっかり説明します。
ざっくり説明すると
標準出力するためには、"fmt"という部品(パッケージ)が必要ですので、import文で部品を取り込んであげます。
プログラムを起動したら、main関数(func main()の中)を実行してほしいので、package文でmainを指定します。
標準出力させている部分は、
fmt.Println("Golang is good.")
これで実行すると、
Golang is good.
と出力されているはずです。
標準出力の詳しい説明は、後々投稿いたします。
コメントの書き方
コメントは//での行コメントと、/* */でのブロックコメントが使用できます。
JavaやC#とかと同じですね。
package main import ( "fmt" ) func main() { // This is the output code. fmt.Println("Golang is good.") /* Golang is good. Is it output? */ }
定数
const文で定義することで、コンパイル時に定数が作成されます。
定義の仕方には数パターンあります。
型を省略することもできますが、その際、型は自動で決定します。
①const <定数名> [型] = 値
package main import ( "fmt" ) const ConstNum1 int32 = 10 const ConstNum2 = 10 func main() { fmt.Println(ConstNum1) fmt.Println(ConstNum2) }
また複数の定数をまとめて定義することもできます。
package main import ( "fmt" ) const ConstNum1, ConstNum2 int32 = 1, 2 const ConstNum3, ConstStr1 = 1, "string" func main() { fmt.Println(ConstNum1) fmt.Println(ConstNum2) fmt.Println(ConstNum3) fmt.Println(ConstStr1) }
②const (列挙)
列挙で定義することもできます。
iotaは列挙内で0,1,2,3...とインクリメントしてくれます。
今回最初の0は必要ないので、無視するようにしています。
package main import ( "fmt" ) const ( _ = iota ConstNum1 ConstNum2 ConstNum3 ) func main() { fmt.Println(ConstNum1) fmt.Println(ConstNum2) fmt.Println(ConstNum3) }
※注意として、定数になるのは数値、文字列、論理値だけです。
また定数を関数で定義することはできません。
const ConstArray = [1, 2, 3] ⇒ NG const ConstAdd = add(1, 2) ⇒ NG
変数
定数と同じように初期化できますが、プログラム実行時に評価されます。
①var <変数名> [型]
package main import ( "fmt" ) func main() { var i int fmt.Println(i) }
複数の変数を一気に定義することもできます。
package main import ( "fmt" ) func main() { var i1, i2, i3 int fmt.Println(i1, i2, i3) }
②var <変数名> [型] = <初期値>
package main import ( "fmt" ) func main() { var i int = 1 fmt.Println(i) }
こちらも複数一気に定義することもできます。
package main import ( "fmt" ) func main() { var i1, i2, i3 int = 1, 2, 3 fmt.Println(i1, i2, i3) }
③var (列挙)
列挙で一気に定義することができます。
package main import ( "fmt" ) func main() { var ( i1, i2, i3 int = 1, 2, 3 s1, s2 string = "s1", "s2" ) fmt.Println(i1, i2, i3) fmt.Println(s1, s2) }
④<変数名> := <値>
型の指定を行わず、省略した形の記述方法です。
package main import ( "fmt" ) func main() { f := 3.14 fmt.Println(f) }
次回
Go言語のステートメントについて学んでいきます。
応用情報処理技術者試験 合格までの勉強法など
個人的な報告ですが、平成31年4月の応用情報処理技術者試験に合格しました。
せっかく平成最後に合格したし、令和に受ける方たちのために、やってきたことを記載します。
- そもそも応用情報技術者とは
- 自分もともとスペック
- なんで受けたか
- 勉強期間
- 勉強スケジュール
- 午前の勉強方法
- 午後の勉強方法
- 試験会場ついたら
- 午前試験の戦い方
- 午後試験の戦い方
- 試験が終わったら
- 感想
- 今後
そもそも応用情報技術者とは
情報処理推進機構(IPA)が主催とする、ITの国家試験の1つで、毎回合格率20%とまぁまぁ難易度の高い試験です。
問われるのは、2進数の計算などの基礎や、ネットワークの構成や製造物責任法などの法律関係まで、ともかく範囲は広いです。
午前と午後の2部制で、午前は選択問題、午後は筆記試験です。
それぞれ150分で、どちらも60点以上で合格です。
自分もともとスペック
バックエンドエンジニアとして7年ほどやってます。
なのでデータベースとアルゴリズム系はもともと知識はありましたが、それ以外は全くありません。
20歳で基本情報は合格してましたが、もうほぼ忘れています・・・
なんで受けたか
何となく漠然と、技術のことを基礎から見直したいと思ってやりました。
目的は合格することではなく、知識を得ることでした。
なので落ちたら落ちたで、再試験する気はありませんでした。
勉強期間
1~4月の4か月間です。
平日は仕事後に1時間半ほどと、電車内(20分)を飲み会が無ければやってました。
休日は3時間ほどですね。
勉強スケジュール
1月 午前教材勉強・復習
2月 午前教材勉強・復習
3月 午前・午後過去問・復習
4月 午後過去問・復習
午前の勉強方法
基本暗記。多々計算問題がありますので、教材に沿って自分も紙に計算式を書いていて、内容を把握します。
テキストを読み、知らないワードはGoogleドキュメントに表形式で記録していきました。
ただ読むだけだと眠くなるし頭に入らないので、手を動かすことが大切だと思います。
Googleドキュメントにまとめる際は、教材の転記ではなく、自分の言葉でまとめていくのが大切!
そうすることで、脳が刺激されて、記憶になります。
それで電車の中では基本iPhoneでGoogleドキュメントに記録した内容の復習。
復習が午前合格のカギとなります。
過去問は過去問道場を使用しました。
過去3年分を間違えなくなるまでやり続けました。
もちろん過去問の中で知らないワードがあったら、Googleドキュメントに記録します。
過去3年以上前の問題をやっても良いですが、それをやるなら午後の過去問に回した方がいいです。
午後の勉強方法
午後は
情報セキュリティは必須で、以下の中から4つを選択して回答します。
①経営戦略
②プログラミング
③システムアーキテクチャ
④ネットワーク
⑤データベース
⑥組込みシステム開発
⑦情報システム開発
⑧プロジェクトマネジメント
⑨サービスマネジメント
⑩システム監査
勉強するなら、絞ってやった方がいいです。
時間があるなら、全分野やっても良いのですが、効率的にやるんだったら絞りましょう。
ちなみに自分は午後の選択は、
プログラミング・ネットワーク・データベース・組込みシステム開発
にしました。
プログラマの方は、この選択が一番やりやすいと思いますよ。
ちなみに保険として、システムアーキテクチャも勉強してましたが、出番はなかったです。
午後は文章問題なので、過去問を通して文章に慣れる必要があります。
重点対策を使用して、間違えなくなるまで繰り返しました。
最初は文章の多さに精神的にやられましたが、繰り返してやることで慣れていきました。
試験会場ついたら
お手洗い済ませたら、黙想しましょう。
昔からの自分のやり方ですが、試験当日は勉強しません。
無駄なことに頭使いたくありませんから。
それにギリギリまで勉強しなきゃ受からないようなスケジュール管理では、社会に出て苦労します。
突発的なタスクではなく、前もって試験日はわかっているのだから、しっかり余裕をもって計画を立てましょう。
ちなみに私は試験前日も全く勉強しません。
午前試験の戦い方
150分で80問ですので、1問あたり約1分50秒。
割と時間余りますので、焦らずじっくり攻めていきましょう。
特に計算ミスとかには気を付けてください。
1周して解き終えたら、2周目で凡ミスはないか確認して、途中退室しました。
退室したときは、残り60分ぐらいあったので、90分で終わってますね。
どうでもいいけど、この年の最後の問題は、社畜を問う問題で面白かったですね。
午後試験の戦い方
ちょうど試験会場が自宅から近かったので、家でお昼を食って再度試験会場へ。
お昼を食べた後の文章問題は眠気を誘うので、コーヒーを飲んで参戦しました。
150分で5分野ですので、1分野あたり30分。
午後は割と時間を食うので、しっかり時間管理します。
確認の時間が欲しいので25分過ぎそうであったら、途中でやめて次の分野に気分転換します。
余った残り時間で、終わっていない問いに挑みましょう。
高確率で、どこかで時間がかかってしまう問題があります。
私は得意としていたデータベースで時間をとられました。
なので、あ~これは時間取られる割に正解できなそうだ、と感じたので問題を飛ばして分かるものから解いていきました。
午後も途中退室でしたが、残時間は20分ほどだったので、130分ぐらいかかってます。
試験が終わったら
試験のことなんて忘れて、すぐさまランニングして、酒買って帰って、終わった余韻に酔いしれる。
これが勉強頑張った技術者のロマンってやつです。
合格したか気になる方は、合格発表に2か月以上かかって待ち遠しいと思います。
というか情報試験だったら、採点を自動化して高速に処理できないものかと思ってしまいます。
自分は合格発表までに子供が産まれて、すっかり忘れてた頃に合格通知が届きました。
感想
会社にやらされている・先生にやれと言われたという受動的スタンスでは合格するのは難しいかと思います。
簡単な試験ではありませんから。
能動的だとしても、これで技術力が上がるというわけではないです。
だったら民間の技術に特化した資格の方がいいかと思います。
技術の幅広い基礎的な知識を得たい方には、おすすめの試験です。
別の分野の技術者と会話するときも、知識があるので、結構会話として成り立ります。
今後
ここから上の技術者試験は基本的に文章問題の毛色が強くなります。
技術の知識を得たいだけの私は、応用情報までが適正だと思いますので、これ以上は目指しません。
技術者としてなら応用情報までで十分なのでは、と思います。
Go言語 Visual Studio Code開発環境構築
最近Go言語の開発を始めました。
少々つまづいたところもあったので、開発環境の構築を記録していきます。
なお執筆時点は2019年7月です。
環境はWindows 7 64bitなので、環境に応じて異なる個所がある可能性があります。
Go言語のインストール
以下のサイトから各OSに応じたインストーラをダウンロードします。
golang.org
インストーラの指示に従って、インストールしてください。
以下のように完了したメッセージが表示されたら、「Finish」ボタンをクリックして終了してください。
コマンドプロンプトを開き、コマンドを実行して動くことを確認します。
go version
Visual Studio Codeのインストール
以下のサイトからインストーラをダウンロードします。
code.visualstudio.com
こちらもインストーラの指示に従って、インストールしてください。
インストール完了後、コマンドプロンプト上で以下のコマンドを実行して、動くことを確認します。
code
拡張機能のインストール
Visual Studio Codeをに拡張機能をインストールします。
Go言語を実行するだけなら、この手順は必要ありませんが、開発するなら必須なのでやってください。
※私の環境は英語ですが、気にしないでください。(日本語パッケージが嫌いなため・・)
Visual Studio Codeの左のサイドパネルから、拡張機能をクリックして、検索欄にGoと検索してください。
そうするとおそらくトップに、Microsoft社が出しているGo言語用の拡張機能が表示されます。
こいつを「インストール」ボタンをクリックして実行してください。
依存パッケージのインストール
拡張機能から参照されるパッケージをインストールしていきます。
コマンドプロンプトで以下のコマンドを実行してください。
go get -u -v github.com/nsf/gocode go get -u -v github.com/rogpeppe/godef go get -u -v github.com/zmb3/gogetdoc go get -u -v github.com/golang/lint/golint go get -u -v github.com/lukehoban/go-outline go get -u -v sourcegraph.com/sqs/goreturns go get -u -v golang.org/x/tools/cmd/gorename go get -u -v github.com/tpng/gopkgs go get -u -v github.com/newhook/go-symbols go get -u -v golang.org/x/tools/cmd/guru go get -u -v github.com/cweill/gotests/... go get github.com/derekparker/delve/cmd/dlv
インストール後、Visual Studio Codeを再起動してください。
サンプルプログラム
Visual Studio Codeの左のサイドパネルから、エクスプローラをクリック。
まだフォルダーを開いてない方は、どこか好きなところにフォルダを作成して、選択してあげてください。
エクスプローラパネルに、ファイル作成用アイコンがありますので、クリックしてファイルを作成します。
ファイル名は適当にGoPractice.goにしました。
コードは以下。
package main import "fmt" func main() { fmt.Println("Hello World!") }
実行
Visual Studio CodeでCtrl+@でターミナルを開きましょう。
以下のように実行結果が返ってくれば成功です。
C:\Users\VSCode\GoPractice>go run GoPractice.go Hello World!
MERCI TALKに参加してきました
「ITエンジニア×スポーツ」MERCI TALK〜スポーツを仕事にしたい人のためのイベント〜に参加しました。
connpass.com
個人的な感想を織り交ぜつつ、ずらずら書いていきます。
概要
スポーツ業界に対して、ITでサポートを行っている方々に様々な角度から意見をしてもらう。
また製作したゲームやアプリを紹介していただき、最新のスポーツへの取り組みを紹介していただきました。
セッション
HADO
ARを使って、自分の手から波動を出して、プレイや自ら身体を使って戦うゲーム。
映像見たけど無茶苦茶かっこいい。
正直これは衝撃的で、面白そう。
「人が想像できることは、必ず人が実現できる」
なんてどこかのCMでありましたけど、かめはめ波を出すことが、ついに実現できる感じがしました。
製造した株式会社meleapリードシニアエンジニアの増田様は、これからのスポーツ業界には、
「テクノロジーを駆使した、新しいゲームがどんどんやってくるだろう。」と述べられていましたが、本当にその時代が近いうちに来るでしょう。
以前から気にはなっていましたが、HololensやArglassなどを使ったVR・AR・MRの世界は今後も伸びる非常に面白みのある世界だと思います。
Hololensなんてそうですが、なかなか個人レベルで簡単に買える価格ではないので、なかなか開発を試すことができませんが、値下げしてきたら購入して、このブログでも紹介できたらなんて思っています。
TeamHub
こちらはリクリエーションレベルのユーザに向けて、スポーツ関連のサポートをするもの。
例えば、スケジュール調整や試合結果などの記録、チーム内の情報共有などができる。
自分はいくつかのランニングチームに所属している身でもあるので、このアプリを使えたらいいなと思いました。
こういったレクリエーションレベルの方向けに、テクノロジーを作ってくださるのは大変ありがたいです。
アプリ自体は流行りのReactNativeを使われているそう。
良いなと思ったのが、製造した株式会社Link Sportsの濱本様が
「社員がこの技術を使いたいと思ったら、世の中では別の技術を使うのが普通だとしても、その社員の要望を大切にしたい」
とおっしゃっていたことです。
良いこと言ってますね。やけに古い技術にこだわって、そのままずっと使い続けて、意地でも新しい技術を取り込もうとしない現場や技術者はいますからね。
そんな人たちは、新しい技術を使うのはギャンブルかのように言い、お金もバグも起こらない既存技術で押し通そうとします。(まぁ実際はバグもお金もかかっていますが・・)
まぁそれはそれで安全?だからいいのでしょうけど。
私はアプリのエンジニアではないですが、今後Link Sportsさんがどのように発展していくのか、楽しみにしています。
自分のこと、ブログのこと
ブログの目的
このブログでは、自分自身が現場で遭遇した技術や勉強中の技術、その他IT業界関連を中心に情報を発信していきます。
また自分の中で反芻する意味でも、記録しております。
たまにそれた話題もありますが、そこはご容赦ください。
自己紹介
バックエンドと組み込み開発を主軸に、7年間社員として従事。
その後フリーランスエンジニアとして独立いたしました。
とは言え、仕事内容は社員の時からお世話になっている常駐先に、現在もお世話になっております。
エンジニアらしいエンジニアで、新しい技術が大好きです。
フリーになってから、様々な技術のお話を聞く機会が増えて、非常に楽しくやってます。
好きな開発言語は
C# Python Java Go
です。
趣味でランニングをしていて、マラソンも何度か完走することができました。
どうしても開発していると、身体も心も鈍っていくので、運動は定期的にするようにしています。
今後考えていること
しばらくはフリーランスとして働き続けるのもありかと思ってますが、より技術に貪欲でレベルの高い集団の中で開発したい欲の方が強いです。
特に客先常駐で成り立つ会社より、自社サービスを強みにしている会社の方が、魅力的に感じます。
もちろん働くとなると、子供もいるので、ワークライフバランスと給料を考慮してとなりますが、もしこんな技術屋さんと仕事をしたいって方がおりましたら、コメントください。
その他
日中は仕事、帰宅すれば娘が大騒ぎで慌しく、記事の更新が遅くなりますが、継続して続けていきたいと思います。
もし記事に不備があったり、情報が古かったりした場合、コメントいただけると幸いです。
また技術好きな人、これから技術を学びたい人、走るのが好きな人などなど、お気軽にコメントいただけたら励みになります。