「世界一のプロゲーマーがやっている 努力2.0」を読んだ感想
世界一のプロゲーマーがやっている 努力2.0が面白かったので雑にメモを書く。
- 「75点」取れたら次に行く
- 自分が無理をしていないか、常にモニターする
- 体力
- 基本の完成度
- ルーティン
- 自分を変えるな、環境を変えろ
- アウトソーシング
- ちょっとしたことを「やめる」訓練
- 「努力したい」と思える場所
「75点」取れたら次に行く
他人より格段にうまくなろうとか、100点を目指そうと意気込む必要はありません。まずは人並みでいい。そのくらい軽い気持ちでかまいません。そしてそこから少しずつできることを伸ばしていく。問題はそれをどこまで、「その環境で」伸ばしていくかです。僕は感覚的に75点からせいぜい80点で打ち切ります。80点とは、その集団では上位20%に入るくらいです。打ち切ってどうするのか。次のレベルの環境へ移ります。
ときど. 世界一のプロゲーマーがやっている 努力2.0 (Japanese Edition) (Kindle の位置No.635-641). Kindle 版.
- これは共感できる。根拠を問われると経験的にそう思うとしか言えないけれど...
自分が無理をしていないか、常にモニターする
自分のことをモニターするために、僕は1冊のノートを使っています。毎朝、昨日1日の自分の状態を記録する、いわば「自分の通信簿」です。
ときど. 世界一のプロゲーマーがやっている 努力2.0 (Japanese Edition) (Kindle の位置No.827-828). Kindle 版.
- 心のエネルギーは有限リソースなので、無理をしていないかを常にモニタリングしているとのこと。
- いかにもプロっぽい、ストイックな習慣で素直に凄いなと思った。
- 具体的には睡眠時間、食事回数、脈拍、幸せ度etc...を段階評価しているらしい。
- 自分はあまり項目が多いと続かなそうだからある程度厳選した上でやってみたい
体力
移動だけで疲労しているようでは、それだけで実力を発揮することはできなくなってしまう。強烈な危機感から、僕は2015年ごろから、筋トレを始めました。
ときど. 世界一のプロゲーマーがやっている 努力2.0 (Japanese Edition) (Kindle の位置No.889-890). Kindle 版.
- 自分が筋トレをする目的の1つはこれ。結局、現実的に何かを成し遂げるために必要なのは体力なんじゃないかと思っている。
- 人間の努力・経験・思考力・記憶力etcなんて他の人とは(大抵は)大差なくて、多くの場面で最後に差がつくのは意思と体力なのかなあと。もちろん例外はあるとは思うが。
基本の完成度
気をつけないといけないのは、70%くらいの完成度になっていると、練習レベルでは99%の人と差があまりないと錯覚してしまうこと。さらに、基本の技でミスをして負けても、単なるケアレスミスと勘違いしてしまうことです。プレッシャーのかかる場面や複雑な場面になると、基本の完成度の差が現れるのはよくあることで、これは「必然のミス」です。不意に九九を聞かれて答えられないようでは、数学のどんな試験でも使い物にはならないですよね。それと同じことです。「平凡だ」と感じるまで仕上げるとは、どんな大舞台、どんな非日常の場面でも、何も考えず技が出せるくらいの完成度に仕上げることをいいます。
ときど. 世界一のプロゲーマーがやっている 努力2.0 (Japanese Edition) (Kindle の位置No.1113-1115). Kindle 版.
- これもストイックなお話で、数学の例もめちゃくちゃよく分かる。九九ではないけど受験/試験で嫌というほど味わったな...
- プログラミングの場合だと、コーディングの素早さ・品質の高さなんかに現れてきそう
- 基本的な言語仕様、構文、標準ライブラリを頭で理解しているだけでなく、"どんな大舞台、どんな非日常の場面でも、何も考えず技が出せるくらいの完成度に仕上げ"ているか
- 迷いなく手を動かしてコードを書けるかみたいな感じ? 競プロだと基本的なアルゴリズムについても同じことが言えそう。
- とはいえ、自分はコーディングに関しては意図して反復練習するよりも、繰り返し書いていたら身に付いていた、という感じの方が自然で楽しいんじゃないかなとも思っている
- 受験数学は確かに間違った問題を3~5回ぐらい解くのを自分もやっていたが、そういうストイックさは今の自分にはもうない気がしている...
- また、業務を進めるだけなら、そこまで1つの言語に全力で向き合う必要もないんじゃないかという思いもあり複雑
- 基本的な言語仕様、構文、標準ライブラリを頭で理解しているだけでなく、"どんな大舞台、どんな非日常の場面でも、何も考えず技が出せるくらいの完成度に仕上げ"ているか
ルーティン
ルーティンを設定するのは大事だが、縛られないようにする。予想外のことが起きてもイライラしないで柔軟に対応する。ただし1番大事なポイントは抑える。それだけは何が起きても優先させる。
Kindleの引用上限に達したので以下引用ではなく要約。
- ルーティン設定あるあると、その対処法
- 自分の場合だと起床してから出社までのルーティンを確立したい気もするが、結構気分や体調で変わるのであんまり意味なさそう
自分を変えるな、環境を変えろ
- 例えば、ときど氏は部屋にベッド以外何も置かないことで練習やジムに行きやすくしているらしい。
- こういう話好きだけど、自分に適用できるかというとあまり思いつかない。姿勢を良くするよりアーロンチェアを買うとかそんな感じかな
アウトソーシング
- ときど氏は、目的と関係ない部分は全てアウトソーシングしているとのこと
- 例えば東大受験の例だと、合格することが目的なので、受験対策の研究・勉強の進め方は全部予備校に任せて、自分は勉強することだけに集中して時間を節約した
- 自分も筋トレは同じことを考えていて、パーソナルトレーナーに完全依存している。自分で筋トレの仕方を研究するモチベーションはない。
- 多分もっとアウトソーシングできることありそうな気もするが、そこまで時間を節約して自分は何がしたいのか?というところが実は曖昧だったりもする。
ちょっとしたことを「やめる」訓練
- ときど氏は、ゲームの練習・ジム等の大事な毎日の習慣でも、あえて2週間休むこともあり、長期的にはその決断が有効に働いているとのこと
- 義務感・根性で1日も欠かさず続けることよりも、「嫌ならやめる」ことで結果につなげる
- これはめちゃくちゃ分かる
- 趣味でコードを書くのも基本的には自分のモチベーションを大事にしている。無理に生産的なことをしよう・”しなければならない”と思うようになったら危険信号だと思う
- 「嫌だからやめる」がずっと続く場合はきっと自分に向いていないので自分がやらない方が良いことだということも分かる。その分別のことに時間を使えばいいと思う
「努力したい」と思える場所
TypeScriptで「ヒーリングっど・プリキュア」を実装してnpmパッケージとして公開した
作ったもの
モチベーション
- TypeScriptで何か作りたかった
- プリキュアの各言語での実装まとめ - Qiitaを見ていて、TypeScript実装がなかったので一応作った(最新のプリキュアのみ対応)
- npmパッケージを公開したことがなかったので試してみたかった
以下感想
クラス設計(モデリング)の難しさ
- やっぱりOOPのクラス設計は悩む
- 最初はプリキュア毎にクラスを作ったが何か違う感があった(例えばCureFontaineクラス, CureGraceクラス...)
new CureFontaine()
でインスタンスを作るが、キュアフォンテーヌは1人しかいないはず(シングルトンにしてもいいけど...)何か違う
- というわけで、ここでは状態をモデリングするのが多分妥当だろうと結論付けた
Stateパターンによるタイプコードの置き換え
- 状態のモデリングの着想はここから得た
- プリキュアは変身前後で2つの状態を持ち、状態に依存して振る舞いが変わる(名前や技、変身の可否等)
- インスタンスに状態を示す変数を持たせて、メソッド内で状態に応じて分岐させることもできる(例えば
isTransformed
を定義して、if文で分けて...等)- しかし、状態や状態固有のロジック等が追加されていくと辛くなる(例えば2段階変身が追加されたり、感情が追加されて振る舞いが変わるとか)
クソコード動画「switch文」 #ooc_2020 pic.twitter.com/USTrFcRCAS
— ミノ駆動 (@MinoDriven) 2020年2月16日
- Java言語で学ぶリファクタリング入門で
State/Strategyによるタイプコードの置き換え
というパターンが紹介されていることを思い出したので適用してみたらけっこう良い感じになった - 状態が増えても固有の振る舞いが追加されても非常に見通しが良い
npmパッケージを公開
- npmのアカウントさえあれば本当にすぐ出来る
- ローカルでは
$npm pack
して生成したtarを$npm install path/to/tar
して動作検証可能
TypeScriptの言語仕様
- クラス定義周りの言語仕様で、Javaと同じだと勝手に思っていたというか「そういえばそうなんだな」という発見があった
- Reactのコンポーネントクラスの実装と0からのクラス設計では使う言語機能が違うからかもしれないし、単にTypeScriptを書く量が不足しているのかもしれない
- 例えば
- enum classは定義できない
- innner classは定義できない
- クラス内でthisは省略できない(Javaのサンプルコードを読んでいて、そういえばとなった。TypeScriptはやはりJavaScript)
HerokuでDocker, Go, Postgresを使ってAPIサーバを動かしてみた感想
環境
- mac OS 10.14.6
- Go 1.12.4
モチベーション
- データのCRUDを伴うWebAPI(とDB)をサクッと作って公開したい
どうやったか
- ローカルはAPIとDB共にDockerで環境構築
- APIはそのDockerfileを使ってHerokuにデプロイ
- DBはHeroku addonsのPostgresを使用
- APIの実装はgin, gormを使って楽をした
- スキーマのmigrationはgoose(下の記事で使われてたのでそのまま使った)
できたもの
https://infinite-hollows-34092.herokuapp.com/api/ping
GETリクエストすると現在日時を格納する。これまでに格納された現在日時を全て返す。
手順
以下の手順に従って進めた。上記のコードはほぼ以下の記事のコードの写経に近い。フロントエンドがないのとgormを使っている点が違うだけ。
以下、感想を書きます。
Heroku addonsのPostgresについて
今まで使ったことなかったけど、コマンド1つでクラウド上にDBを作成できてここまで色々できるの凄いなと思った。
Dataclips
data.herokuのDataclipsを使うとブラウザからPostgresを参照できる。参照系のクエリを書くのでViewみたいな感じ。 このViewに対するURLを発行することもできて外部連携も可能な模様。
pgsql
ターミナルからpg:psqlで接続することも可能。
❯ heroku pg:psql --> Connecting to postgresql-rectangular-83658 psql (12.1) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. infinite-hollows-34092::DATABASE=> delete from ping_timestamp where id = 4; DELETE 1 infinite-hollows-34092::DATABASE=> select * from ping_timestamp; id | occurred ----+------------------------------- 1 | 2020-02-22 06:06:15.302206+00 2 | 2020-02-22 06:06:26.004438+00 3 | 2020-02-22 06:06:33.051055+00 (3 rows) infinite-hollows-34092::DATABASE=> \q
Dockerを利用したHeroku デプロイについて
Dockerfileを使ってHerokuにデプロイするためにheroku.yml
を書く。例えば今回は以下になる。
build: docker: web: Dockerfile worker: dockerfile: Dockerfile target: builder release: image: worker command: - ./migrate.sh
ちょっとイメージしにくかったのがreleaseフェーズで使用されるworkerの部分
- このDockerfileではmulti stage buildをしていて、Goのモジュールのビルドと実行を分離している
- releaseフェーズではPostgresに対してmigrationを実行するだけだが、その実行環境をworkerとしてbuildフェーズで事前にビルドしている
- なので同一のDockerfileを元に2つのイメージを作成している。webの方はGoのビルドと実行までで、workerはGoのビルドまで。
これは実際に$ git push heroku master
してHerokuが出力してくれるログを眺めると何をしているのかが分かって良かった
その他
- Netlify, Heroku, Firebase等、遊びで何かを作って公開するのが楽な時代になった
- 業務のサービス開発にいつも使えるとは限らないけど、選択肢として持っておくべきと思う
- 仮説検証的・速度重視の開発や、パフォーマンスを求められない単機能なWebAPIの開発など?
docker rmiで image is referenced in multiple repositoriesが発生した
環境
- macOS 10.14.6
- Docker version 19.03.5, build 633a0ea
Dockerの掃除をしていたら
- docker images を全削除するを参考に、イメージとコンテナの掃除をしていた
- その中になぜか削除できないイメージがいた
~/.ghq/github.com/pokuwagata/go-gin-gorm-heroku-example master* 11s ❯ docker images REPOSITORY TAG IMAGE ID CREATED SIZE portfolio-go-mysql-docker-webapp_nginx latest 8a2fb25a19f5 10 months ago 16MB nginx 1.14-alpine 8a2fb25a19f5 10 months ago 16MB ~/.ghq/github.com/pokuwagata/go-gin-gorm-heroku-example master* ❯ docker images -aq | xargs docker rmi Error response from daemon: conflict: unable to delete 8a2fb25a19f5 (must be forced) - image is referenced in multiple repositories Error response from daemon: conflict: unable to delete 8a2fb25a19f5 (must be forced) - image is referenced in multiple repositories
- macos - Can not remove images even though no container is running - Stack Overflowによると、複数のリポジトリで使用されているイメージはidでは削除できないらしい
- 確かにIMAGE IDは同一になっている
- そもそもdocker imagesコマンドは同じイメージも繰り返し表示する場合があるのか...と思ったら確かにそういう説明があった
An image will be listed more than once if it has multiple repository names or tags. This single image (identifiable by its matching IMAGE ID) uses up the SIZE listed only once.
docker images | Docker Documentation
- そういうわけで、idではなく、リポジトリ(とタグ)を指定して
docker rmi
すれば削除できる
❯ docker rmi portfolio-go-mysql-docker-webapp_nginx
結果
スッキリ
~/.ghq/github.com/pokuwagata/go-gin-gorm-heroku-example master* ❯ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ~/.ghq/github.com/pokuwagata/go-gin-gorm-heroku-example master* ❯ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
定期的に掃除していきましょう
urfave / cliを使ってGoでCLIアプリを作ってみた
環境
作ったもの
何だこれは
苺ましまろという作品に登場するキャラクターの台詞を出力するだけのアプリ。 台詞は3パターンしか登録していない。アナちゃんと茉莉ちゃんは未対応。
モチベーション
- 久しぶりにGo言語書きたかった
- cliアプリ用のライブラリを使ってみたかった
- これ試してみたかった:Go で書いた CLI ツールのリリースは GoReleaser と GitHub Actions で個人的には決まり
感想
- Go言語のcliアプリ作成支援系のライブラリとしてはspf13/cobraもあり、あまり大きな違いはなさそうなので名前でcliの方を選んだ(コブラは何か怖い)
- そもそもGoでcliアプリ作るなら、ライブラリ使わなくても十分実装できるだろうなという思いもあったが、とりあえず最初はライブラリ使ってみた
- Github Actionsを初めて使った。tagをpushするだけで各環境向けのビルドが完了してrelesesページで公開されるの凄い
- Go言語で書いているとGithubからgo getでインストール完了するので楽。皆、
ichigo-cli
をgo getしましょう。
ハマりどころ
Github Actionsとローカルでgo.sumに差異が発生してビルドに失敗した。原因はローカルがGo 1.12なのに対しActionsは1.13だったから。 ローカルのバージョン上げないと...と思いつつ一旦は1.12に合わせて、
$ go mod tidy
して解決した。台詞をランダムに表示するために、
math.rand
を使用して乱数を取得しようとしたら乱数にならなくて困った。 原因はseedの初期化をしていないかららしく、そういうものなのか...と思った。現在時刻をseedに使うようにしたら確かに乱数になった。2ヶ月ぐらいGo書いていなかったので色々忘れていたけど、「たしかこういう構文があった」とか「名前は忘れたがこんな関数が標準パッケージにあったはずだ」みたいな感じで気づくことは出来ているので、ある時期に集中的に書いていればしばらく書いていなくても何とかはなるなあとも思った。あと、やっぱり言語の色々がシンプルなのは人の記憶に優しいのかもなあとも思ったり。
Go言語、沢山書いていきたいですね。
vim-lspを使用してtsxファイルに対してtypescript-language-serverを動かす
環境
方法
前提:vim-lspはインストール済み
wikiの手順と同じだが、whitelistの設定が異なる。
- LSPをインストール
$ npm install -g typescript typescript-language-server
- 下記を.vimrcファイルに追加する
if executable('typescript-language-server') au User lsp_setup call lsp#register_server({ \ 'name': 'typescript-language-server', \ 'cmd': {server_info->[&shell, &shellcmdflag, 'typescript-language-server --stdio']}, \ 'root_uri':{server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), 'tsconfig.json'))}, \ 'whitelist': ['typescript', 'typescriptreact'], \ }) endif
デフォルトだとファイルタイプtypescriptのみが有効なので
.tsx
ファイルを開いてもLSPが動作しない.tsx
ファイルを開いて:LspStatus
するtypescript-language-server: running
と表示されればOK
vim-lsp-settings
(上記のvimrcを書かなくて済むので)vim-lsp-settingsを使いたかったが現状ではうまく動作しなかった
- ファイルタイプtypescriptreactに対して
:LspInstallServer
はサポートされていない(README.mdの表にない) - しかしtypescript-language-serverを使うことは変わりないので、
.ts
ファイルを開いて:LspInstallServer
してLSPをインストール let g:lsp_settings = {'typescript-language-server':{'whitelist': ['typescript', 'typescriptreact']}}
として上書きしたが、.ts
ファイルを開いた後に.tsx
ファイルを開くと動作する.tsx
ファイルを始めに開くと動作しない
動作することはするけど不完全だったので一応issueを作成してみた(英文難しい...)