2019年振り返り

2019年の抱負に対して

一年前の振り返り記事を見返すと、2019年は以下目標にしていたらしい。

  1. 子供に色んな体験をさせる
  2. 技術的なアウトプットを増やす
  3. Goやる
  4. 英語

子供に色んな体験をさせる

4月から保育園に入ることができた。申請先の保育園は、住居区の昨年と一昨年のデータを基に、妻と色々検討し、結果ベストな選択ができた。
保育園入ってからは、自分たちが教えていないことをどんどん表現するようになって、すごく成長を感じるし、共働きという状況を度外視しても保育園に入れれることが出来て本当によかったと感じている。
ただ、土日にどこか出かけるとかはあまり出来ず、アンパンマンミュージアム、ディズニーランドは2020年持ち越しになってしまった。ただハワイには行ったw

技術的なアウトプットを増やす

足りなかった。4月からtech leadのポジションを引き継いだのもあって、中々ひたすら技術ばかりやってるということが難しくなってしまったのもあり、満足出来る結果にはならなかった。
ここはプライベートの時間も含めて、もう少し時間の使い方や集中と選択を戦略的に進める必要がありそう。。

Goやる

本業で本格的にGoをやることになった。まだインフラ含め基盤作りをしている段階だが2020年の早いタイミングでガッツリコード書くフェーズが来そう。

英語

週末ちまちまやってる程度。本当はもっと時間とお金使いたいが、結局仕事で使わん限り中々優先度的にアクセルを踏むことはなさそう。2020年も多分週末ちまちまやる。TOEICくらい受けてみようかな。

2019年振り返り

イベント

1月:妻が年末の帰省から一ヶ月実家から戻ってこなかったので一人暮らししてた
4月:Tech Leadになった
   娘が保育園に入園したため、毎日自転車で送ってから出勤することになった
5月:令和が始まった。令和最初の飯は地元の来来亭だった
6月:初めて目白田中屋行った
   吉本の闇営業問題が話題になった
7月:免許証を更新した
   自宅近くに常に1時間くらい待つラーメン屋が出来たので初めて行った
8月:所属企業にリモートワークが導入された
9月:ウイスキー検定3級受験した
   義弟の結婚式でハワイへ行った
10月:ウイスキー検定3級合格した
   娘がガストデビューした
11月:インタビュー記事が公開された
12月:PS4買った
   娘と初二人外食(もちろんガスト)した

読書

2019年はは40冊読んだ。2018年より3冊多かったみたい。以下読んだリスト。

技術書

自己啓発・ビジネス・一般書

小説

ノンフィクション・エッセイ

趣味・娯楽

競馬

昨年は馬連一点買いで黒字達成したので、引き続き同じ買い方で一年勝負した。

回収率 的中率 本命馬成績 本命馬
勝率
本命馬
連対率
本命馬
複勝
購入馬券
2017年 63.0% 8.6% [19.18.16.75] 14.8% 28.9% 41.4% 馬単一点
2018年 123.5% 11.5% [17.22.14.78] 13.0% 29.8% 40.5% 馬連一点
2019年 73.4% 3.1% [15.10.9.95] 11.6% 19.4% 26.4% 馬連一点

今年と昨年の違いは、本命馬を割と無謀に近い穴馬を中心にしたこと。結果からもわかるように本命馬が馬券圏外になることが増えた。当たれば一気に黒字を目論んだ手法だったが、的中したレースの配当もそこまで馬鹿でかいわけじゃなく、回収率もかなり下がってしまった。
本命馬が1着にきた15レース中、11レースで印をつけていた馬が2,3着にくるという結果が振り返ってわかった。もしその買い方でやっていたらとてつもない回収率を叩き出してたことが判明。来年は本命馬1着固定の3〜6頭流しの三連単で1年やってみたいと思う。

ウイスキー

計13本飲んだ。以下飲んだ順。

サッカー

またまたまたユーベはCL獲れなかった。
セリエは9連覇。今季監督がアッレグリからサッリに代わり、インテルがコンテ招集で、そろそろセリエ連覇も止まるかなと予想しているが、この一騎打ちのデッドヒートはかなりセリエを面白くしている。
CLは1位通過して初戦がリヨンなのでいいとこまで行って欲しいが、内容見ている限りCL獲るイメージはない。

以下18-19個人的ベストイレブン

18-19見てる限り、二年連続個人的ベストイレブンに入る可能性があるのはアリソン、ファンダイク、マルセロ、サラー、メッシあたりかな。

昨年の発言。マルセロ以外は当たった。(自分で選んでるので当たるもくそもないがw)
リバプールの好調さがわかる。
CBはセルヒオ・ラモスからアルデルヴァイレルトに変わった。レアルマドリージダン解任後あの頃の強さに陰りが見えた影響もあり、誰も選出しなかった。スパーズはCLの快進撃もあり、クリバリと悩んだがビッグマッチでクリーンシートも多かったスパーズのアルデルヴァイレルトにした。

右SBはキミッヒ→カンセロ。いやーカンセロはまじでよかったのにシティに行ってしまった。。代わりにダニーロだから戦力はかなりダウン。

左SBはマルセロ→ジョルディ・アルバ。ここは完全に消去法。割と人材難な感じが。今季見てる感じベルナトやロバートソンあたりが良いかなぁ。

中盤はデ・ブライネ、エリクセン、アラン→ギュンドアンラキティッチピャニッチと一新。デ・ブライネは怪我もあり、エリクセンも17-18ほどの活躍でもなかった。アランはよかった気がする。
ギュンドアンはシティでも完全にレギュラーとまではいかないのかもだけど、出てる試合はまじでよかった。ラキティッチは今季色々言われているが、やっぱこの選手うまいわ。ピャニッチはもうユーベに欠かせない選手に。

アタッカーはドウグラスコスタ→スターリング。コスタはシステム変更や怪我でまだ本領発揮できていない感じ。それでもドリブルとバズーカ砲はまじでチート。スターリングはまじですごかった。ドリブル、決定力共に同じポジションのサネを圧倒したと思う。(サネもかなりのレベルやけど)

2020年の抱負

アンパンマンミュージアムとディズニーランドには絶対に娘を連れて行く。できれば国内旅行もしたい。
仕事面では新規事業やサービスの言語リプレイス・インフラリプレイスを控えているので中々濃厚な感じになりそう。
あとそろそろ登壇する機会を増やしたい。

ということで、よいお年を。来年もよろしくお願い致します。

Github actionsからslackへ投稿する

Github actionsからSlackへ投稿するための連携手順です。

Slack側の設定

Slack APIへアクセス。
「Create New App」をクリック。

f:id:alex0715:20191204172224p:plain

モーダル画面の「App Name」に任意の名前(画像では「GitHub Action」)を入力。
「Development Slack Workspace」に連携させたいワークスペースを選択し「Create App」をクリック。

f:id:alex0715:20191204173534p:plain

サイドバーから「Bot Users」を選択し、「Display name」と「Default username」に任意の名前を入力。

f:id:alex0715:20191204174051p:plain

サイドバーから「Basic Information」を選択し、「Display Information」で好きなアイコンを設定。
ちなみにここでフリーで提供されています。

f:id:alex0715:20191204180818p:plain

「Basic Information」画面上部の「Install your app to your workspace」から「Install App to Workspace」をクリック。

f:id:alex0715:20191204181036p:plain

サイドバーの「OAuth & Permissions」から「Bot User OAuth Access Token」を確認する。(github actionの設定で使うので)

f:id:alex0715:20191204182107p:plain

Github Actionの設定

対象のリポジトリにいって、「Actions」タブをクリック。

f:id:alex0715:20191204185153p:plain

「New workflow」をクリックして、画面遷移後の「Set up a workflow yourself」をクリック。

f:id:alex0715:20191204185443p:plain

適当な名前でymlを作成。

name: Notify slack

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - name: Notify slack
        env:
          SLACK_BOT_TOKEN: xoxb-XXXXXXXX-XXXXXXXXX-XXXXXXXXX
        uses: pullreminders/slack-action@master
        with:
          args: '{\"channel\":\"C123456789\",\"text\":\"Hello world\"}'

pushされたタイミングで連携したslackのworkspaceのチャンネル(C123456789)に対して、「Hello world」と投稿する例です。

画面右上の「Start commit」をクリックし、直接デフォルトブランチにcommitするのか、新しくブランチを作成してcommitするのか選べます。

その後すぐにSlackに投稿されます。 f:id:alex0715:20191204221216p:plain

参考

github.com

go-grpc-middleware/recoveryを利用してpanicから回復する

goでgRPCサーバ実装する際に、panic起きた際に落ちずに回復させる方法です。 go-grpc-middlewaregrpc_recoveryを利用します。

事前準備

protoとgo-grpc-middlewareのインストール

$ go get github.com/golang/protobuf/proto
$ go get github.com/grpc-ecosystem/go-grpc-middleware

grpc_recoveryを使わない場合

こちらをご利用ください。

$ git clone https://github.com/ybalexdp/sample-grpc
$ cd schema
$ protoc --go_out=plugins=grpc:../pb sample.proto

panicを起こす処理を追記

service/service_sample.go

func (s *SampleService) GetSample(ctx context.Context, message *pb.GetSampleRequest) (*pb.SampleResponse, error) {
    if message.Name == "panic" {
        panic("failed")
        return nil, grpc.Errorf(codes.Internal, "Unexpected error")
    }
    return &pb.SampleResponse{
        Message: "Hello :" + message.Name,
    }, nil
}

サーバ起動

$ cd ..
$ go run main.go

panicを起こしてみる

$ evans --path schema --port 2007 sample.proto

  ______
 |  ____|
 | |__    __   __   __ _   _ __    ___
 |  __|   \ \ / /  / _. | | '_ \  / __|
 | |____   \ V /  | (_| | | | | | \__ \
 |______|   \_/    \__,_| |_| |_| |___/

 more expressive universal gRPC client


pb.Sample@127.0.0.1:2007> call GetSample
name (TYPE_STRING) => panic
command call: failed to send a request: rpc error: code = Unavailable desc = transport is closing

エラーです。
その後再度API叩いてみると、サーバが落ちていることが確認できます。

pb.Sample@127.0.0.1:2007> call GetSample
name (TYPE_STRING) => test
command call: failed to send a request: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:2007: connect: connection refused"

サーバ側

下記のように落ちています。

$ go run main.go                                                                                                                                        (git)-[master]
panic: failed

goroutine 4 [running]:
github.com/ybalexdp/sample-grpc/service.(*SampleService).GetSample(0x1843840, 0x15263a0, 0xc0001681b0, 0xc0001681e0, 0x1843840, 0xc000168150, 0x142b5e0)
    /Users/ybalexdp/go/src/github.com/ybalexdp/sample-grpc/service/service_sample.go:16 +0xf0
github.com/ybalexdp/sample-grpc/pb._Sample_GetSample_Handler(0x14224a0, 0x1843840, 0x15263a0, 0xc0001681b0, 0xc000164300, 0x0, 0x0, 0x0, 0xc000026128, 0x7)
    /Users/ybalexdp/go/src/github.com/ybalexdp/sample-grpc/pb/sample.pb.go:180 +0x23e
google.golang.org/grpc.(*Server).processUnaryRPC(0xc000084900, 0x1528160, 0xc000084d80, 0xc00018e000, 0xc0000a3e30, 0x1816e90, 0x0, 0x0, 0x0)
    /Users/ybalexdp/go/src/google.golang.org/grpc/server.go:1007 +0x485
google.golang.org/grpc.(*Server).handleStream(0xc000084900, 0x1528160, 0xc000084d80, 0xc00018e000, 0x0)
    /Users/ybalexdp/go/src/google.golang.org/grpc/server.go:1287 +0xdf9
google.golang.org/grpc.(*Server).serveStreams.func1.1(0xc0000a8890, 0xc000084900, 0x1528160, 0xc000084d80, 0xc00018e000)
    /Users/ybalexdp/go/src/google.golang.org/grpc/server.go:722 +0x9f
created by google.golang.org/grpc.(*Server).serveStreams.func1
    /Users/ybalexdp/go/src/google.golang.org/grpc/server.go:720 +0xa1
exit status 2

grpc_recoveryを使ってサーバを落とさせない

ソースもあげておきます。
go run main.goでgRPCのサーバが立ち上がります。

grpc_recoveryを実装する

main.go

package main

import (
    "fmt"
    "log"
    "net"

    grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
    grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
    "github.com/ybalexdp/sample-grpc_recovery/pb"
    "github.com/ybalexdp/sample-grpc_recovery/service"

    "google.golang.org/grpc"
    "google.golang.org/grpc/codes"
)

func main() {

    opts := []grpc_recovery.Option{
        grpc_recovery.WithRecoveryHandler(recoveryFunc),
    }

    server := grpc.NewServer(
        grpc_middleware.WithUnaryServerChain(
            grpc_recovery.UnaryServerInterceptor(opts...),
        ),
    )

    listenPort, err := net.Listen("tcp", ":2007")
    if err != nil {
        log.Fatalln(err)
    }
    sampleService := &service.SampleService{}
    pb.RegisterSampleServer(server, sampleService)
    server.Serve(listenPort)
}

func recoveryFunc(p interface{}) error {
    fmt.Printf("p: %+v\n", p)
    return grpc.Errorf(codes.Internal, "Unexpected error")
}

サーバ起動

$ cd ..
$ go run main.go

panicを起こした後、再度APIを実行する

pb.Sample@127.0.0.1:2007> call GetSample
name (TYPE_STRING) => panic
command call: failed to send a request: rpc error: code = Internal desc = Unexpected error

pb.Sample@127.0.0.1:2007> call GetSample
name (TYPE_STRING) => ybalexdp
{
  "message": "Hello :ybalexdp"
}

サーバが落ちていないことが確認できました。

サーバ側

実装したエラー出力のみで、サーバは落ちていないことが確認できます。

$ go run main.go
p: failed

参考

GoDoc

go-grpc-middlewareを一通り試してみる - Qiita

GoのgRPC ServerのInterceptor(recovery/auth/zap/prometheus) - sambaiz-net

GoでgRPCサーバたててevansで実行するまで

goでgRPCサーバたてて、evansで叩くまでの備忘録です。

gRPCサーバ実装

一応ソースあげておきました。

grpcのインストール

go get -u google.golang.org/grpc

protoファイル作成

schema/sample.proto

syntax = "proto3";
service Sample {
  rpc GetSample (GetSampleRequest) returns (SampleResponse) {}
}
message GetSampleRequest {
  string sample_txt = 1;
}
message SampleResponse {
  string sample_message = 1;
}

コード生成

mkdir pb

cd schema

protoc --go_out=plugins=grpc:../pb sample.proto

ここまででpb配下にsample.pb.goが生成されていると思います。

serviceレイヤ実装

service/sample.go

package service

import (
    "context"

    "github.com/ybalexdp/sample-grpc/pb"
)

type SampleService struct {
}

func (s *SampleService) GetSample(ctx context.Context, message *pb.GetSampleRequest) (*pb.SampleResponse, error) {
    return &pb.SampleResponse{
        Message: "Hello :" + message.Name,
    }, nil
}

main実装

main.go

package main

import (
    "log"
    "net"

    "github.com/ybalexdp/sample-grpc/pb"
    "github.com/ybalexdp/sample-grpc/service"

    "google.golang.org/grpc"
)

func main() {
    listenPort, err := net.Listen("tcp", ":2007")
    if err != nil {
        log.Fatalln(err)
    }
    server := grpc.NewServer()
    sampleService := &service.SampleService{}
    pb.RegisterSampleServer(server, sampleService)
    server.Serve(listenPort)
}

あとは

go run main.go

するだけ。

evans導入&実行

evansインストール(mac)

brew tap ktr0731/evans

brew install evans

evans起動&API実行

evans --path schema --port 2007 sample.proto

  ______
 |  ____|
 | |__    __   __   __ _   _ __    ___
 |  __|   \ \ / /  / _. | | '_ \  / __|
 | |____   \ V /  | (_| | | | | | \__ \
 |______|   \_/    \__,_| |_| |_| |___/

 more expressive universal gRPC client


pb.Sample@127.0.0.1:2007>call GetSample
name (TYPE_STRING) => test
{
  "message": "Hello :test"
}

pb.Sample@127.0.0.1:2007>

MySQLのバイナリログとレプリケーションとserver-idの関係

バイナリログに関して色々勉強しようと思い、まずは手元の環境(Mac)のbinlogを有効にして起動したところ以下のエラーが出た。

$ mysql.server start
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/ybalexdp.local.pid).

my.cnf

[mysqld]
log-bin=mysql-bin

原因調査と解決までのメモを書く。

環境

OS:Mac OS X 10.13.6
MySQL:5.7.17

server idが無い

エラー内容でググるとpidファイルを作成するとか、権限周りによる原因とか、最悪再インストールとか色々出てきたが、今回はmy.cnfの編集内容に起因しているので、ちょっと違った。

/usr/local/var/mysql/ybalexdp.local.errを確認すると下記のようなエラーログが確認できた。

[ERROR] You have enabled the binary log, but you haven't provided the mandatory server-id. Please refer to the proper server start-up parameters documentation

どうやらバイナリログを有効にする際に、server-idってのが必要でしかも必須らしいと。。

server-idを追記

試しにserver-idmy.cnfに追記してみる。

my.cnf

[mysqld]
log-bin=mysql-bin
server-id=1

で、起動すると立ち上がった。

server-idとは

複数のサーバ間でMySQLレプリケーションを行う場合、それぞれのサーバに対し、一意のIDを付与する必要があり、このserver-idにそのIDを指定する。
レプリケーションする際に必要なのはわかる。よぉくわかる。だがよぉ、、なんでバイナリログを有効にするだけなのに必須なんだ!  

レプリケーションとバイナリログ

このバイナリログ、レプリケーションで使われており、マスタが吐いたバイナリログをもとにスレーブ側で同じ状態に保ってる。
なのでレプリケーションをする際にはバイナリログの有効化が必須、かつserver-idも必要なためバイナリログ有効化にはserver-idも必須という構成なのか。
ただ、レプリケーションは組まず、でもポイントインタイムリカバリを実施したい、とかでも必須にしないといけない。
いや、普通レプリケーションくらい組むでしょ、っていうのはまぁその通りなんだろうけど。

まとめ

バイナリログを有効化にするにはserver-idは必須

docker-composeでgin+reactの開発環境を作る

ずっとバックエンドAPIにGoを使った開発がしたくて、趣味で作ってたRailアプリを作り直そうと思いまずは開発環境を作ってみた。
フロントに関しては別にこだわりはなかったんだけど、仕事はインフラ+バックエンドがメインでフロントはそこまでスキルがないので担当しているプロダクトにあわせて勉強がてらといういう意味でReactにしてみた。

構成

docker-compose.yml
|-- api(ginのソースコード格納)
|-- react(フロントのソースコード格納)
`-- docker
    |-- api
    |     |-- Dockerfile
    |     |-- Gopkg.toml(※)
    |     `-- main.go(※)
    |-- nginx
    |     |-- Dockerfile
    |     `-- nginx.conf
    `-- node
          `-- Dockerfile

docker/api 配下にある Gopkg.tomlmain.go だが、後述する docker-compose.yml内でapiコンテナにマウントさせている./api配下のものに上書きされる。
ここにわざわざ配置しているのは、apiコンテナ作成時にdep ensureによるパッケージインストールを実施したいため、両ファイル必要なのだが、マウントのタイミングがこのdep ensureより後に実施されてしまうため事前にDockerfile内でCOPYしてやる必要があったため。
本当はdocker/api 配下ではなくapi配下にあるファイルを置きたかったが、DockerfileのCOPYで指定するファイルがDockerfileより上位のディレクトリは指定できないようなので仕方なくこのような形にした。
ちなみにdocker/api/main.goは空ファイルでもよい。

docker-compose.yml

作ったdocker-compose.ymlはこんな感じ

version: "3"
services:
  node:
    build: ./docker/node
    volumes:
      - ./react:/var/www/html/
    working_dir: /var/www/html/horsebase
    command: yarn start
    ports:
      - "3000:3000"
  db:
    image: mysql:5.7.22
    environment:
      MYSQL_ROOT_PASSWORD: [password]
      MYSQL_PASSWORD: [password]
      MYSQL_DATABASE: [database]
    volumes:
      - ./mysql:/var/lib/mysql
    ports:
      - "3306:3306"
  api:
    build: ./docker/api
    volumes:
      - ./api:/go/src/project
  nginx:
    build: ./docker/nginx
    ports:
      - "1234:1234"

ginはサーバサイドレンダリングはせずにAPI提供のみとして構成している。

各Dockerfile

node

FROM node:8.9.4-alpine

WORKDIR /var/www/html/
RUN npm install -g create-react-app

api

FROM golang:1.10.2-alpine3.7

COPY Gopkg.toml /go/src/horsebase-prophet/
COPY main.go /go/src/horsebase-prophet/

WORKDIR /go/src/horsebase-prophet/

RUN apk update \
  && apk add --no-cache git \
  && go get -u github.com/codegangsta/gin \
  && go get -u github.com/gin-gonic/gin \ 
  && go get -u github.com/golang/dep/cmd/dep \
  && dep ensure

CMD gin -i run

nginx

FROM nginx:latest

RUN rm -rf /etc/nginx/conf.d/default.conf
COPY ./nginx.conf /etc/nginx/conf.d/default.conf

CORS(Cross-Origin Resource Sharing)問題

Reactのaxiosを使って直接ginのAPIを叩いてもCORSのため、通信できない。
gin側のレスポンスヘッダにAccess-Control-Allow-Originを設定することで通信可能になるという情報もあったが、Chromeだとうまくいかなかった。
Chromeの場合は起動オプションを指定する必要があるらしい。
(参考)
開発時にCORSを無視するGoogleChromeの起動オプション - Qiita

今回はnginxをproxyとして利用し、react→nginx→ginのようにアクセスするようにした。

nginx.conf(抜粋)(これだけでも動く)

server {
    listen       1234;
    server_name  localhost;

    location / {
        proxy_pass  http://api:9000;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

react/project/src/App.js

import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      message: ""
    };
    this.getData = this.getData.bind(this);
  }

  getData() {
    axios
      .get('http://localhost:1234/api/greeting')
      .then(results => {
        const data = results.data;
        this.setState({
          message: data['message']
        });
      });
  }
 
  render() {
    return (
      <div>
        <button onClick={this.getData}>getData</button>
        <p>{this.state.message}</p>
    </div>
    );
  }
}
export default App;

APIへのアクセスはnginxで待ち受けている1234ポートに投げる。
nginxはnginx.confproxy_passで定義したapiコンテナ内でginが待ち受けているポートへ。

api/main.go

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()

    r.GET("/api/greeting", func(c *gin.Context) {
        c.Writer.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")

        c.JSON(200, gin.H{
            "message": "hello, world",
        })
    })
    r.Run(":9000")
}

レスポンスヘッダのAccess-Control-Allow-Originにアクセス元のURLをセットする。
これをセットしないとCORSではじかれる。

まとめ

まとめというか、以下なんとかならんかな

  • 同じcompose配下のコンテナならCORS意識しなくていい仕組みほしい
  • volumesで指定したマウントのタイミングDockerfile内で定義したCMDやdocker-compose.yml内で定義したcommandのタイミングをコントロールしたい

2018年振り返り

もう2019年になってしまったどころか一週間くらい経ってしまったけど振り返ってみる。

本当は色々技術的なアウトプット用に開設したものの結局ほとんど何もせずに放置してしまったので、これをキッカケにちょくちょく何かしら書けたらいいなぁと。

イベント

2月:甥っ子が産まれた。

3月:妻が里帰り出産を終え、東京に娘と一緒に戻ってきた。3人暮らしが始まった。

5月:食器棚を購入した。

6月:サッカーW杯を見まくった。家族で上野動物園へ行った。シャンシャン見た。

7月:転職した。引き続きW杯見た。誕生日の前日に友達の結婚式で名古屋へ行った。

8月:ジョイン先のチームが独立して新しい企業として設立したのでそっちに移った。一ヶ月間神田のレンタルオフィスで働いた。

9月:新オフィスへ移った。(日本橋、水天宮、人形町近辺)

10月:ジョジョ展@六本木へ行ってきた。

12月:娘が一歳になった。

読書

昨年は37冊読んだ。ここ数年では割と少ない方だった。子供ができて自分の時間が減ったことが起因しているのかしら。以下読んだリスト。

技術書

自己啓発・ビジネス・一般書

小説

ノンフィクション・エッセイ

趣味・娯楽 他

競馬

昨年も全重賞を購入した。昨年は馬連一点買いのみで買い続けてみた。

以下結果(二年分)。ちなみにたまーに重賞以外も遊び馬券を購入してたけどちゃんと予想してない&馬連一点買いじゃないため特にデータ残してないので対象外。 

  回収率 的中率 本命馬成績 本命馬勝率 本命馬連対率 本命馬複勝 購入馬券
2017年 63.0% 8.6% [19.18.16.75] 14.8% 28.9% 41.4% 馬単一点
2018年 123.5% 11.5% [17.22.14.78] 13.0% 29.8% 40.5% 馬連一点

という感じで回収率がほぼ倍になった。

的中率が上がったのは馬単から馬連に変えたのでそりゃ上がる訳だが、単純に2倍とはいかなかった。

本命馬の成績はそこまで大差無いので昨年は裏目を割と踏んでいたんだろうな。

今年も継続して馬連一点買い縛りでやってみる。

ウイスキー

計15本飲んだ。以下飲んだ順。

サッカー

またまたユーベはCL獲れなかった。

W杯は予想通りフランスだった。四年後は再生したアズーリが見れるかしら。その前にユーロ。てか再生しかけているのはオランダの方やけど。

以下17-18個人的ベストイレブン

18-19見てる限り、二年連続個人的ベストイレブンに入る可能性があるのはアリソン、ファンダイク、マルセロ、サラー、メッシあたりかな。

ドウグラスコスタはほんま昨シーズンはバケモノだったけど、今シーズンは唾吐きによるしょーもない出場停止に加えてロナウド加入に伴うシステム変更もあってまだ本領発揮できてないな。

あとスカパーがついにCLの放映権をとらなかった(とれなかった?)。のでDAZNに加入した。スカパーの実況・解説陣のクオリテイが高かったので非常に残念だったが、開けてビックリほとんどの試合で同じ実況・解説陣だった。あと格安。画質等も問題無しで満足していた矢先にまさかまさかのスカパーがセリエAの独占放映権を一部とりやがったせいでDAZNセリエAユベントスの試合のみがほぼ見れない状況に追い込まれた。しかもセリエAのみの契約ができず無駄にJリーグとかその他見ないリーグと合わせたくそ高いパックのみで一気に悪質企業として認知することになった。

スカパー多少高くても14年ほど契約し続けてて非常に感謝の気持ちがあったけどこういうサッカーファンを置き去りにするような姿勢は許容できない。

が、ユベンティーノとしてさすがに年間通してリーグ戦見れないのは辛すぎるので泣く泣く加入した。

お仕事

7月に転職した。

MyReferという会社で主にバックエンドとインフラやってます。人少ないのでたまにフロントも。初めてReactとかやったけど、やっぱフロント苦手。

エンジニア採用にも携わってます。

興味ある方は是非!

myrefer.co.jp

2019年の抱負

娘が一歳になって少しずつコミュニケーションがとれるようになってきた。まだ結果は出てないけど4月から保育園に入園できる可能性もあるので、色々な成長が見れると思う。ということで色んな体験をさせてあげたい。

お仕事的には転職したばっかりで、ようやく色々とやりたいこととか動き出せる感じになってきたので、できれば個人的なアウトプット含めて色々外に出していくもの作りたい。できればGoをもっと使っていきたいが、業務では現状社内ツールとかくらいなので基本個人開発でやることになりそう。

それと英語勉強したい。そんな真剣に考えている訳では無いけど、個人的な興味に加えて娘の教育という観点で脱日本も良さそうかなとたまに思ったりするので、移住なんて大げさだけどそれくらいの気持ちで勉強すれば少しはまともに使えるようになるかも、と。