エンジニア備忘録

駆け出したエンジニア

2020年1月の振り返り(バックエンドエンジニア:4ヶ月目)

振り返りの前に

先月は振り返りを書くのが遅れたけど、今月は2日から書けているので優秀!

1月度の感想

(この1ヶ月のパソコン活動:Qbserve)

f:id:fujiten3:20200201221319p:plain

(緑が生産活動、青がニュートラル、赤がTwitterとか。棒1本が1日で左から右に31日間ある)

今月の学習時間: 約36時間

アプリいわく36時間ぐらい。微妙だなー。

徒歩でポッドキャストとか聞いてるの入れても恐らく、勉強時間としての合計は50時間いかないぐらいって感じで、ちょっと少なかったかな、と思います。

ただ、これには言い訳があって、正社員としての労働が忙しかったんですよ、今月。(残業はしてないんだけど)

正社員としての労働で体力を使うと、やはり帰ってから勉強だったりするリソースを割くのが大変。このあたりのバランスと言うか、仕事でパフォーマンス出しながら、帰宅してからの作業の効率を上げるってのは、大事にしていきたいよね。

雑感

進捗駄目です(泣)

MUST(必ずやること)が終わらねーよ、MUSTが重すぎる。過去の俺が未来の俺に負債させてる量が半端ではない。負債がめきめき溜まっていってるんだよな……なんとかしないと。

余談だけど、なんか今月寒かった…。大阪から上京してきた身分なので、東京での初めての冬だったんだけど、まあとくに寒さに違いはなくて、大阪と同じでふつうに寒かったね。起きるたびに「寒いよ〜」って言ってた思う。対策も思いつかなかった。

今月学習したこと

MUST(かならずやる)って先月言ってたやつ

  • Udemy (Understanding TypeScript - 2020 Edition)

終わらし。結構長かったけど、英語の勉強にもなったし、TypeScriptやりたみが増した。しかし実際どこで使おうってのがちょっと課題なんだよな……。

  • 螺旋本

アルゴリズムをやっていっている。JSで書いてます。

しかし、やっぱアルゴリズムの勉強ってあまり即効性感じないと思ってしまうのは僕だけだろうか。(というか、ほんとに役立つのかなー、とちょっと思ってしまってる。)まあatcoderで下から3つ目の色ぐらいにはなりたいと思ってるから、(ゲーム攻略的な意味で)、一応やっていく予定です。数学チックで好きだし。

  • Web API The Good Parts 2章まで

仕事ではほぼRailsAPI触りマンと化しているので読み直し。

10%ぐらい進めた。先月「今月に読み終わるかな?」って言ってた気がする。亀の歩み。

  • 達人に学ぶSQL徹底指南書

また読んでない。2ヶ月連続積みは「一生積みフラグ」だから注意しないとな。

英語

  • Podcast(「Stuff you should kwon」と「Software Engineering Daily」)

  • ゲーム実況

ダンガンロンパシリーズを見終わり。V3おもしろかった!! もっかい見直しながらセリフ覚えていこうかな。

予定してないがやっていたこと

Google拡張機能で遊ぶ

先月に続き、単語帳機能をブラウザ上で実現するために触ってた。引き続きやる予定。

2回勉強会に行った。

blogs.partner.microsoft.com

findy.connpass.com

今月やること

MUST

バックエンドに強くなる系(仕事系)を今月は多めにしようかなあ、と。先に述べたように社内で求められる技術的知識の深さが強くなってきたのと、質問に対して的確な概観を提供しなければならない機会は増えてるから、データベース周りや、APIについて、掘っていく感じの1ヶ月にしたい。

んで、今月は本ベースにする予定。本を消化してるときが、あんたは「えらい!」感が出る。

をやります。なんか先月、MUSTって言ってたのに今月出来てない事が多すぎて「俺はだめだ。目標を達成できていない」感が出てしまってるので、よくない。自分なりに頑張ってるはずなのに目標が達成できてない現実があるせいで、頑張ることに対するインセンティブがめきめき下がっているのを感じる。

なので、簡単な目標を先においておくことにする。これはメンタルテクニックとしては初歩的だが、効果のほどを見てみたい。

WANT(やれればやる)

ここはメモ代わりにおいておく。

  • 達人に学ぶSQL徹底指南書

  • 螺旋本(アルゴリズム

  • パケットキャプチャの教科書

  • OAuth 徹底入門

  • Electron講座

おわりに

今月もわくわくしながら生きていこう! 2月は28日しかない。28日間を有意義に生きるんだ!

あ、1月、リングフィットアドベンチャー買って、やっていってたんですが、首を痛めてしまったので休止しています(ゲームのせいでなく、枕のせいだと思う)。

枕は大事ですね。

以上です。

2019年12月の振り返り

振り返りとは

就業時間以外に学んだことや考えたことをブログとして残しておくこと。

「毎月あげる目標達成の積み重ね → 長期目標の達成」を狙ってます。

振り返りの前に

12月度の振り返りを書くのが遅れたのは、正月にガッツリ体調崩してしまい4日間ほど寝込んでいたからです……。(今日、やっと復活して体調70%モード。)

体調崩したわけは、おそらく、寒い早朝に日記をカタカタ書いて、そこからお酒を飲んで、それで、夜に暴食したからではないかなあ、と思っています。

年末年始のまとまった時間で積んでいた教材なんかを消費したかったので、わりと計画が狂ってショックなところもあるのですが、失った時間は戻らないので、また目標をセットしなおそうという心持ちです。

そして、実家で家族と一緒だからといって、食べるものに気を抜いてはいけないな、というのも思いました。親が作ってくれると、全部食べないと申し訳ないという気になって、食べすぎ傾向にあるのがよくない。ということで、自分のことは自分で管理できるようになるというのが2020年の抱負の1つとなりました。(中学生じみているが)

12月度の感想

いろいろと雑ではあったものの、月初めに今月終わらせたいことを決めたことで、1日1日を無駄にしない意識がかなりついてよかったな、と思ってます。なので、この振り返りの習慣は、続けられる限り続けようかな。

雑感

月初めに立てた目標ベース的には、達成率はそこまでよくない。というのも、やろうと決めていたもの以外に手が伸びることも多かったのが原因かな。ただ、自宅で行う勉強の習慣自体は順調についてきたので、あとは、しっかり質を意識して、時間内で多く学ぼうとすることが大事かなあという感。

学習時間を自動で追跡してくれるデスクトップアプリを導入したので、これを使って、時間管理は無意識的にやっていくつもりです。

今月学習したこと

MUST(かならずやる)って先月言ってたやつ

React + TypeScript

英語教材を主にやっているのは、もちろん、英語の学習も兼ねて。さいきん、ヒアリングより、リーディングに課題感を感じてきているので、わからなかった単語をメモするなりして、語彙力をつけていきたいな。

読むと言っていた本たち

読み終わり。自分が課題感を感じていた、アルゴリズムの初歩的なところについて、広範にインデックスを作ってくれる本でありながら、詳細な解説も随時あってよかったです。コードでアルゴリズム実装してくれてたり、P・NPだったりの世界観を教えてくれたりというのも推せるポイント。

20%ぐらい進めた。今月中に読み終わるかな?

  • 達人に学ぶSQL徹底指南書

読んでねえー。exists関数のとこまで読んでたのは覚えている。

TOEIC

東大駒場キャンパスにて対戦しましたが、最後列近くの席を引き、リスニングで不利を背負ってしまったので再戦希望です。

ドラムを叩いた

久しぶりにスタジオに入ったら下手すぎて泣いた。ストレス解消どころか、ブランクありすぎて「あの頃は俺もうまかったのに……」と哀愁が漂う時間となったしまったので対策が必要。具体的にはしばらくドラムは諦めるか、週1でスタジオ入るか。じゃっかん前者寄り。

予定してないがやっていたこと

Google拡張機能で遊ぶ

単語帳機能をブラウザ上で実現したくて(わからなかった単語を保存しておき、あとで確認する)、すこしChrome拡張機能について触った。今月中に実装終えたほうがよさそう、方針は立ってる。

2回勉強会に行った。

銀座Rails#16 @リンクアンドモチベーション - connpass

Tech Talk vol.2 Backend Engineer 〜マイクロサービスの冪等性〜 - connpass

「白と黒のとびら オートマトン形式言語をめぐる冒険」を読んだ。

コンピューターに計算できることとできないことの境目とはなんだろう、言語とはなんだろう、と、今まで考えもしなかった問いを頭につくってくれて、とても知見のある本でした。

N予備校のプログラミングコースの授業を一部受けた

形式言語論に興味をもったので、その授業もちょっと受けました。

Expressで開発

Docker環境作ってHelloWorldしといた。

「ゼロ・トゥ・ワン」を読んでいる

60%ぐらい。

来月やること

MUST

今月のMUST項目全て。

あとSQLアンチパターン読む。

WHAT

先月書いてたやつと、N予備校のWebエンジニアコース(雑)

あと、「コンピューターシステムの理論と実装」という本を入手したので、こちらもやっていきたい。(相当ヘビーらしいので、計画的に。)

総括と抱負

2019年はエンジニアになるためにずっと勉強していた年で、なんとか10月に東京で就職し、正社員として働かせてもらっていて生き延びているという感じです。

2020年の目標は、ひとまず

  • TOEIC 950
  • 非連続的な成果を求める
  • 勉強の1年

となってます。

英語かな、英語をバンバンやりたいな!

2020年1月は、とりあえず積み系教材をガンガン消化したい。やりたいことがたくさんあることはいいことだけど、やりきった感を覚えるタイミングの消失という問題に出くわしているので、それを防ぐためにもね。

というわけで、みなさま、今年もよろしくおねがいします。

2019年11月の振り返り

振り返りとは

就業時間以外に学んだことや考えたことをブログとして残しておくこと。

「毎月あげる目標達成の積み重ね → 長期目標の達成」を狙ってます。

今月度の感想

総評:85点

(達成度チェックを来月からやりたい)

まあ基準がまったくない中の85点なので、とくに意味はない。

雑感

引っ越しもあって少し慌ただしい一ヶ月だったけど、早朝や就業時間後にちょこちょこと勉強時間を稼げてよかった。

学習履歴について、時間で管理せず量で管理していくタイプなので、就業時間以外で具体的に何時間勉強したかとかはわからない。たぶん60時間ぐらいかな? 我ながらなかなか多くて偉いな。まあマジレスすると勉強してるだけじゃ別にえらくはないんだけど。そしてガチで批評するなら今の自分の余暇時間レベル(1ヶ月720時間中、160時間労働、210時間睡眠で、単純計算で350時間の余剰がある)で60時間しか稼働できてないようだとちょっと効率が悪いぐらいなんだけど。まあ、初月だし多少はね

学習したことの管理については、JootoというWebアプリケーションを使っている。もともとは複数人でのプロジェクト管理アプリらしい。

使い心地は普通。ガントチャートを見れるアプリを探していたのだけど、なさそうだったので、ググって良さげだったこれを使っている。ほとんどTodoリストとしてしか使えてない。

学習したこと

DB関連

  • 達人に学ぶ設計指南書

  • SQLの苦手を克服する本

  • SQL Zoo ちょっとだけ

Ruby/Rails

低レイヤー

  • TCP/IPのきほんがわかる

趣味開発

  • RubyでLambda用のDocker環境を作るなど

  • 速習!TypeScript

  • 動画でTypeScriptやるなど。

  • Reactチュートリアルをやった

React、チュートリアルの段階だとVueと似てる部分があって(state管理とかpropsでの値受け渡しとか)、結構スラスラいけた。

変なところでハマりたくはなかったので、TypeScript + Reactではまだやってない。

English

  • Software Engineering Daily というPodcastを通勤のときに。

もともと昼休みも散歩しながら聞いてたんだけど、冬が本格化してきて寒いので、さいきんは室内でKindle読むことが増えました。

  • 英語でのYoutubeのゲーム実況動画

半分趣味。しかしヒアリングは少しずつ慣れてきているが、結局単語力とかイディオム力が全く向上していない気がしていて、やっぱ書く・話すも単独でやってかないとだめだなあと思っている。

競プロ

  • Code War 5問ほど

毎日解くとか言うてたくせにそこまで解いてなくてワロタ

まあ毎月5問を目標にします

AtCoderはもうちょっとアルゴリズムに慣れてきて、解説見て理解できるレベルになってから再挑戦しようと思ってる。

食生活(健康)

炭水化物を制限している。あと昼食をすごく軽めにとっている。夜に自重での筋トレなど。

昨日、冷蔵庫が届いたから久しぶりに自炊したら、あんまりうまくできなかった。ただ栄養のいいものを食べたいので、自炊は続ける。

来月度の目標

MUST(かならずやる)

  • React(TypeScript) + Electronの学習

仕事でElectron + Reactで書かれたOSSに手を加えてデスクトップ用のアプリを開発していく(かもしれない)ことになったのでここに多めに時間をかけていく。

11月に読み始めてまだ読み終わってないものたち。TypeScript講座は長いので、12月度については途中まででよい。ソフトウェアテストも長かったので途中まででもよい。

  • 12月15日TOEIC受けるのでその前に模擬テスト1回

点とれるかなあ。あまり自信がない。

  • 達人に学ぶSQL徹底指南書

途中まで読んでるので、読み切る。(読み通すのがむずかしそうなら積読

WANT(できればやる)

  • フロント・バックの言語をともにTypeScriptで作るSPA

これについては、できれば今月に作りたい、けど、どのくらいの時間がかかるかわからないし、そもそも作りたいアプリのアイデア駆動開発じゃなくて、触りたい言語駆動開発なこともあり、アプリの要件定義の時間が地味に掛かりそうということもあって(せっかく作るならちょっと運用していきたいという欲があるから、アイデアはなくても設計したい)、WANTにしとく。

実務で触るし、ライブラリを掘りにいったりもするのだが、やっぱり体系的に学ばないと身につきづらいな、というのを実感として思うようになった。

RailsガイドのRackの項目は12月中に目を通したい。

内容むずかったので積読している。読んでちゃんと理解できるようならやりたい。

  • Docker関連の本を1冊。

Dockerを体系的にやっときたいけど、良い資料がまだ見つかってない。

  • Webpackについて体系的に学ぶ

これも資料をまだ見つけてない。

  • GithubActionsについて触る

すこし触ったけど、Githubの多くのイベントをトリガーに、Dockerコンテナを立てて任意のコードを走らせられてあれこれできそうで便利と思った。(まだあまりしらない)

次に作るアプリのCI/CDをこれで実装したいとは思っている。

  • 前月の復習

定着してないところもありそうなので。

  • ドラムで1曲コピーする

スティックは先月買ったんだ。新品のまま机の上に転がってるよ。

総括

時間をどこにどう投資していくか、むずさがある。

前にTwitterでRTした内容に関連することだけど、「いますぐに実務に役立つ外部ライブラリを操る力の学習」と、「CSに関する知識の学習」はけっこうトレードオフ関係になって、まったく同時に進めることは難しいと思ってる。(並行しての学習は可能。)

で、前者の学習は直近1〜2年での効用が高くて、後者は5〜10年の効用が高い分野だと個人的には感じていて、だからこそバランス良く学習し、ソフトウェアエンジニアとしての価値・実装力を高めていく道をまずはキャリアとして歩みたい。

OSSへの貢献だったり、LTやイベントでの登壇だったり、自分のプレゼンスを上げる行為についての比重はまだ上げるつもりはなくて、このあたりは「チャンスがあればやってみる」領域として考えている。

以上っ!

だから僕はプログラミングが出来ない

競プロ・アルゴリズムに関するお話。

TL;DR

こんな問題に出会った。

< Double Cola >

https://www.codewars.com/kata/double-cola/

(概要)

自動販売機に人が並んでいる。その並んだ人の名前をあらわすための配列が渡される。

たとえば["A", "B", "C"]みたく、配列には、列に並ぶ人間たちの名前がString型で定義されている。

並んだ人は、自動販売機でジュースを買ったあと、もう一度並びなおして、そして並び直したさいに「2倍に増殖する」。まるでドラえもんバイバインのように。

つまり、最初に並んでた人がみんな買い終わったときの配列は、["A", "A", "B", "B", "C", "C"]。

FIFOのキューみたく、左から順に配列は処理されていく。

以上の条件で、要素としてStringを複数もつ配列aと、整数nが与えられたとき、n番目にジュースを買う人間は、いったい配列aの中のどのStringになるのか出力せよ、というもの。

僕の考え方(きっとよくない例)

なるほど…。こういうのは、だいたい具体的な例から考えるとわかりやすいんだよな。

たとえば、列に5人並んでるとする。
わかりやすく、名前はa = ["一郎", "二郎", "三郎", "四郎", "五郎"]としよう。

最初に買う順番は単純で、前から1, 2, 3, 4, 5って数えていけばいいな。
たとえばn=1だったら、"一郎"。n=4だったら"四郎"だ。

問題は2周目以降だ。
次は["一郎", "一郎", "二郎", "二郎" ... ]みたく、みんな増殖してる。

n番目だけに着目すると、[6, 7]番目は"一郎"、[8, 9]番目は"二郎", 
[10, 11]番目は.. ,[12, 13].., [14, 15]..みたいな感じか
このとき、たとえばn=10のとき"三郎"、n=15のとき"五郎"になる。

その次は[16, 17, 18, 19] ...(略)... [32, 33, 34, 35]。
さらに倍増してるけど、まだそのまま計算できる範囲。

その次は[36...43] ...(略)... [68...75]。
n=36なら答えが"一郎"ってのはわかる。ただ、もうこのあたりから単純計算だと難しいな。
さて…どう処理していこうか。

ん?よく見れば、倍増する前に全員を処理することを1週と考えたとき、
各周の最後の数字だけに着目すると、数列になってないか?

1週目の最後は5。
2週目の最後は15
3週目の最後は35
4週目の最後は75。

おお、10, 20, 40と増えていく数列だ!

こういう増え方はなんて言うんだっけ?

(3分ほどググって…)

そうそう、等比数列の和ね、うん。久しぶりに見た。

ということは、与えられたnが何周目に位置しているかは、この等比数列の和と組み合わせて考えれば解けそうだぞ。

(ここから30分ほど色々ググって…)

よし、与えられたnが何周目に位置するかを表す数式が書けた。(lapsが何周目になるか表す)

laps = (Math.log2(((n-1) / 5.0) + 1)).floor + 1

たとえば、n=43と入れてみると、lapsは4で、そのnは4週目に位置すると求められる。

これさえわかれば、たとえばn=123017423みたいな巨大な数字が与えられても、
それが何周目に位置するかわかって、そこからは何とか計算できそうだぞ!

ん……? でも、たとえば与えられたnが124週目にあるとわかっても、
そこからそのnが「123週目の終わりと125週目のはじめを基準として、
それを5分割したうちのどの部分に位置するか」を求めないと、
「"一郎"か"二郎"かそれとも…」っていうふうに導き出すことはできないのか。

しかも、よく考えれば、今回は aの配列の要素数は5とも限らない。配列の要素数に応じて、処理を変えるように式を書き換えないとな…。

よし、じゃあもう一度最初から見直して、書き直していくか!

これがこの問題に直面したときの僕の思考でした。

このあと、案の定、ぶじ面倒になって答えを見ました。

そして圧倒的回答(一例)

def whoIsNext(names, r)
  r -= 1
  while r >= names.size
    r -= names.size
    r /= 2
  end
  names[r]
end

圧倒的短さ

しばらく考えてコードの意味を理解したとき、自分がいかにプログラミングのための思考法になってないか気づきました。

これ、単純に言うと、与えられた条件の処理を、逆向きにループしていく処理なんですよね。

「数列を探して〜」とか、「nが何周目に位置するから〜」とか、高校数学のときに考えるような、「xを求めるための式をまず探して、そして左辺がx=になるように分解していく」ようなアプローチは全くしていない。

ただアルゴリズムを探して、そしてそのアルゴリズム通りに動くプログラムを書いているだけ。

い、今まで人生でアルゴリズムを探したことなんてなかったし

そして、僕は自分が(競技)プログラミングが出来ないわけがわかりました。

アルゴリズムの勉強もしてない、アルゴリズムに対する知識量も足りない、そして、そもそもアルゴリズムを探すというアプローチさえ出来ていない。

ああ…。

そりゃできるわけねーわ。

自分が、いかにプログラミングに適応した思考法になっていないか、この問題で痛感しました。

とはいえ、アルゴリズム以外にも勉強することはある

とはいっても、他にも勉強することは山程あるわけで、アルゴリズムだけに時間を投資することは無理なんですけど。

複雑な問題を、アルゴリズムを使って効率的に解くってのはかっこいいし、「データ処理の基本」であると思うので、これからもしっかりやっていかないとな、と、そう思ったわけであります。

そんな気持ちでこのブログを書き始めたんですが、特に落ちがないのでゆるキャンをはりつけて終わっておきます。

alu.jp

よーし、プログラミングがんばるぞーっ。

おわり。

駆け出しエンジニアとして考える、今後の方針

2018年12月からプログラミングの勉強を初めて、現時点でだいたい10ヶ月目ぐらいになります。

エンジニアという職業を選択できたことはとても幸福だったし、今後もずっとこの職には関わっていきたい、と思っています。

ただ、どういったキャリアを目指すか、といった点については、自分はまだ曖昧なままです。

この記事は、そんなキャリアについての今後の概観と、あとは、勉強素材について、まとめておこうかな、ということで書き始めてます。

自分の性格とキャリア

キャリア、というのは「どう生きたいか」に深く関わるので、自分の性格と見直すのは大事だと思ってます。

自分の性格として「チームで働くこと」が大好きなので、フリーランスになる、という選択肢は今後たぶんとらないだろうなと思っています。

なんでチームで働くのが好きなのかはわかりません。今まで入ってた部活は文化系(軽音楽・文芸部)だけだったので、体育会系大好きってわけじゃないです。いや、チームスポーツ経験ないからこそ、チームっていう単位に憧れてんのかも。(青春を取り戻す的な。)ま、そこは謎です。

とりあえず、その上で、いったいどのようなエンジニアになるのか、どういった形のキャリアにしていくのか、ということを、最近よく考えます。

といっても、大枠では決まっていて、「技術的に強いエンジニアになる」というのは、絶対的なものとして考えてます。

自分の性格として、「不効率であること」がとても嫌いというのがあり、そんな状況を解決してくれる一つの策が技術力だと思っています。技術的な能力を上げることで、解決したい課題だったりを発見したときに、それを解決するための手法を実装する設計が思いつきやすくなり、かつ実装できるということを担保してくれる、と思っている、ということです。

もちろん、技術力というのも幅があるのは承知してますが、とりあえず、しばらく勉強は続けたいな、という感じです。

それで、なりたいエンジニア像決まってて、あとは何を悩むねん、というご意見があるでしょうが、僕が悩んでいるのは「マネー」についてです。

I want money

もともと物欲そんなにある方ではないのですが、転職のさいにお金に苦労したという面もあり、「早めにいっぱい稼げる人になりたい!!!」という気持ちがめちゃくちゃ強いです。

現状、26なんですけど、30までには「なかなか稼いでるじゃん」っていう位置には立ってたいんですよね。

となると、4年で結果出さないといけないわけで、正攻法だけでは難しい、というのもヒシヒシと感じているので、なにか、妙案はないかなあ〜というのを、考えてる、というわけです。

まあ、もちろん、詐欺まがいの変な方法で稼ぎたくはないなというのはあるので、できれば、エンジニアという職に関連して、かつ、楽しめながら副業とか出来ないかな〜…なんて…。まあ、そんなうまい話はなかなかないでしょうけど。

あと、一度海外で働いてみたい欲も強いので、それまでにお金貯めたいってのもあります。

いよいよむずいなあ。

まあ、とにかく、今は勉強と、仕事でパフォーマンス出すことが第一、って考えています!

あと、エンジニア同士で交流・協力していきたいなって思ってるので、ぜひ、声かけてください。未経験エンジニアの方とかも、聞きたいことあったら気軽に聞いてください。質問されると嬉しくなるタイプなので。

ここからは、これから学ぶ勉強範囲だったり、今年の目標だったりを書いとくメモです。半分自分用です。

英語

現在7月頃に受けたTOEIC830がベストスコアで、できれば今年中にTOEICを900点を目指したい。TOEICが役立つ英語かどうかみたいな議論あるけど、アメリカ人がTOEIC受けたらほぼ全員980ぐらい取ると思うし、つまり、TOEICである程度スコア取れるのは大事や(確信)。

Podcastでいっぱい英語聞いてたら、なんか聞き取り能力上がった気がする。900点取れたら、スピーキングもやってく。

勉強素材以下の予定

  • Podcast
  • 英文法の本(ロイヤル)
  • abceed(TOEIC対策アプリ)
  • 海外ドラマ(Apple TV)
  • Youtube(英語ゲーム実況)

データベース

バックエンドエンジニアとしてパフォーマンス出したいっていうのがあるので、DBにもちゃんと強くなりたいなってのがあります。(ただ、あんまり得意じゃないかもしれない。)

なので、以下の本を今年中にやろうかな、と。3割ぐらいは終わってます。

  • 達人に学ぶDB設計指南書
  • 達人に学ぶSQL徹底指南書

趣味の読書

文芸部に所属していたということもあり、「死ぬまでにアレは読んどかないとなあ」的な本が、まだ数冊あります。

小説は「即効性はないものの、じわじわと生き方に良い影響を与えてくれる」類のものだと思っていて、26になって、「ヒマで仕方ない大学生のときに格好つけて小説読んどいてよかった〜」と思うことも多いです。ですので、積読している以下の4冊(読みたいと思ってる)を、来年4月ぐらいまでには消化したいな!

アンナ・カレーニナを今年中に読みたい!

低レイヤー(CS・アルゴリズム・ネットワーク)

「じわじわと良い影響を与える」でいうと、このあたりの勉強も欠かせない…。ということで、以下資料は今年中にやっときたいというのがあります。一番下の本はめちゃくちゃ重そうなので、今年中は無理そう!

サーバーレス

AWSのLambda楽しそう!便利そう! ということで、1個アプリ作りたいんですよね。Sinatra使ってめちゃくちゃ簡素なやつは作ったことあるので、ほかになにかできないかな、と考えてます。これは今年中にやりたい。

RubyRails

ふだん業務でやってるし、やっぱ仕事の質を上げるためにもやっときたい。

おわりに

こんなもんかなあ。

jootoというRedmineのようなスケジュール管理アプリケーションを見つけたので、これでやっていこうと思います。

Ruby on Railsで分間100万リクエストを捌くコードの書き方

Rails効率化に関する記事を読んだので、ポイントだけまとめておこうと思います。

engineering.shopify.com

ActiveRecordのパフォーマンス改善

SQLが実行されるタイミングを知る

たとえば下のようなコードは、すぐにクエリが発行されてしまう。

post.comments << user.comments.build

#    (0.1ms)  begin transaction
#  Comment Create (0.4ms)
#  INSERT INTO "comments" ("created_at", "updated_at", "post_id", "user_id")
#  VALUES (?, ?, ?, ?)  [["created_at", "2019-07-11 22:16:43.818858"], ["updated_at", "2019-07-11 22:16:43.818858"], ["post_id", 1], ["user_id", 2]]

予期せぬクエリ発行はパフォーマンス低下につながるので、クエリ発行のタイミングにはいつも注意しよう。

いつ発行されるか知るためには、経験を積んで、あとドキュメントとかいっぱい読もう、とのこと。

出来るだけ少なく選択する

Blog.select(:id)
#   Blog Load (0.2ms)  SELECT "blogs"."id" FROM "blogs" LIMIT
# => #<ActiveRecord::Relation [#<Blog id: 1>, #<Blog id: 2>, #<Blog id: 3>, #<Blog id: 4>, ...]>

Blog.pluck(:id)
#   (1.2ms)  SELECT "blogs"."id" FROM "blogs"
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

このようにidだけほしいならselectよりpluck。ActiveRecordオブジェクトを作るコストが減る。

クエリキャッシュを忘れる

Railsは一つのリクエストで同じクエリを発行するとき、その内容を自動的にキャッシュする機能がある。

Blog Load (0.2ms)  SELECT "blogs".* FROM "blogs" WHERE "blogs"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
CACHE Blog Load (0.0ms)  SELECT "blogs".* FROM "blogs" WHERE "blogs"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
CACHE Blog Load (0.0ms)  SELECT "blogs".* FROM "blogs" WHERE "blogs"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]

でも、これは一つのリクエストの話。リクエストをまたがってクエリを出したとしたら、この機能はべつに効率的に働かないので頼りすぎないこと。

インデックスのないカラムにSQLを打つことを避ける

インデックスなしのカラムを検索しようとすると、「フルテーブルスキャン(前表スキャン)」になって遅い。

だからよく検索で使うカラムにはインデックスをつけるのが大事。ただ、「ALTER TABLE」で後からインデックスを付けようとすると、何百万レコードとあるテーブルだった場合、半端ではない遅さになるそう。あとDBがロックされてその間書き込みできないらしい(このへんは自分のDBへの知識不足で、詳細不明)

なので俺達のチームでは自作Gemを使ってるぜ! とのことです。

https://github.com/shopify/lhm

Railsのパフォーマンス改善

全てをキャッシュする

Rals.cache.fetchメソッドを使うことで、「キーとバリューの組み合わせ」を、キャッシュとして保存できる(たぶんRedisとかに)。

もう一度fetchすれば、クエリを発行せずにキャッシュからデータを引っ張ってこれる。

expires_inで、有効期限の設定も可能。

Rails.cache.fetch("plan_names") do
  Subscription::Plan.all.map(&:name)
end

Rails.cache.fetch("blog_#{blog.id}_posts_#{posts.max(:updated_at)}") do
  blog.posts.as_json
end

Rails.cache.fetch("comment_count", expires_in: 5.minutes) do
  Comment.approved.count
end

これ、うまく使えばめちゃくちゃ効率的だなあ、と思った。クエリ発行しないから、「データの厳密性が必要なとき」は、使うべきじゃないけど、それを差し引いても有用に見えるからどんどん使ってみたい。

ボトルネックを調整する

キャッシュできないものに対する対策。

rack-attackというGemを使うことで、Railsに辿り着く前に、特定のIPによる連続リクエストを拒否する。

Rack::Attack.throttle("limit login by IP", limit: 10, period: 15.minutes) do |request|
  if request.path == "/admin/sign_in" && request.post?
    request.ip
  end
end

Railsに辿り着く前に拒否できるから、パフォーマンスよし、とのこと。

(Jobを使って)後で実行する

重い処理はJobで切り出して、他のプロセスに処理を委譲しようぜ! とのこと。

依存関係をダイエットする

Gemを入れすぎると、依存関係がやばくなるから注意。Dependabot入れると、依存パッケージがバージョンアップすると、プルリクでお知らせしてくれるから便利だよ、とのこと。

Rubyのパフォーマンス改善

メタプログラミングは少しだけ使う

メタプロ(動的なメソッド定義など)は遅いから自分でやるときは、本当に必要なときだけにしようぜとのこと。

O(1)とO(n)の差を知る

serializers = [UserSerializer]
serializers.find do |serializer|
  serializer.accepts?(object.class)
end

serializers = { User => UserSerializer }
serializers[object.class]

上の例のように、O(1)にしたほうが効率いいから、そう設計していこうぜとのこと。

割りあて(Allocation)は少なく

Rubyではよく「!」がついた類の破壊的メソッドは危険だから、あんまり使うなって言われるけど、使い方しだいでは、効率化につながる。

arr = %i(a a b c)

#これより
new_arr = arr.uniq

#こっちのが効率いい
arr.uniq!

既存のオブジェクトを破壊して、新しいオブジェクトを作るほうが、割当てが減って効率がいい、とのこと。もちろん、破壊的変更は使い方を間違えると危ないので注意とのこと。

なるほどねえ。。使っていきたい。

間接化は最小限に

No code is faster than no code.

(ノーコードに優るコードはない)

間接的に複雑な処理を行えば行うほど、パフォーマンスは落ちてしまう。

即座に最適化には結びつかないけど、リファクタリングに大事な考えだから、覚えておくほうがいいとのこと。

最後に

ソフトウェア開発にはトレードオフがいっぱい。速さがいつも「開発で一番大事にしないといけないこと」ではない。

Shopifyでは「速さは機能の一つ」としか考えてなくて、それは「ユーザー体験の向上」と、「サーバー請求額の減額」にはつながるけど、開発者の幸福より優先されて取り組むことではないと思っている。

楽しんで早くしていこうぜ!

感想

Railsのキャッシュとかマジで全く知らなかったから、チャンスがあれば使ってみたいなあ、と思った。(コナミ

あとは、Rubyでの破壊的変更の利用とかも、意識すればすぐに実務で使っていけそうだから、これも覚えておきたい。

未経験からエンジニアになるための学習ロードマップ

完全に未経験から、エンジニアになりたい人向けの記事です。

自分がRailsで就職したので、このロードマップ自体はRailsエンジニア(バックエンドエンジニア)になることに特化していますが、Ruby以外の言語や、フロントエンドへの転職を希望している場合も、Rubyの部分がPHPJavaになったり、JavaScriptへの勉強量が変わるぐらいで、そこまで大きな違いはないと思います。

また、あくまでも自分がこういう風に学習してよかった、というたぐいのものですので、当たり前にサンプル数n=1ですし、そこはご了承ください。

ロードマップ

勉強期間は1ヶ月240時間以上、それを半年間続ける、という流れで考えています。ちょっと長めに見えるかもしれませんが、このぐらいの勉強期間をとって、就職後にいち早くチームの一員として認められる道を、自分としてはオススメします。

大まかな技術範囲については、以下記事がとても参考になるので、確認しておきましょう。

RubyとRailsの学習ガイド2019年版

ここに乗っている技術範囲を、どういう風に勉強していくか、というのが、目下の目標になります。

まずは大雑把に書いてます。詳しい教材内容については、最後に一気にまとめるので、参考にしてください。

1ヶ月目

HTML・CSSを知る

  • Progate
  • Udemy
  • ドットインストール

などで、基礎講座を受けましょう。

プログラミング言語(Ruby)に触れる

まずは、プログラミング言語(今回の場合はRuby)を知りましょう。プログラミング言語は、それ自体で完結している上に、最初から最後まで最も重要です。

ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)

ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)

Ruby勉強の最初の1冊として、上の本がおすすめです。チェリー本は初学者には難しいので、いきなり手を出してはいけません。

フレームワーク(Rails)に触れる

最初の1ヶ月目に触れておきましょう。もちろんこの時点では何がなんだかわからないと思いますので、「これをしたらこう動くんだ、へえ」ぐらいの理解で大丈夫です。

ネットワーク基礎を知る

ネットワークについては、学習の初期から当たり前にずっと触れていく部分になるので、早めに学んでおきましょう。

2ヶ月目

HTML・CSSを使う

デプロイしなくてもいいので、ローカルで学習継続。

Rubyを知る

  • paiza
  • Codewar

などのサイトで、Rubyの問題を解きましょう。また、「たのしいRuby」で、Rubyの基礎について学びましょう。(IOクラス、Fileクラス、Dirクラス、Encodingクラスの章については、現時点では飛ばして大丈夫です。)

Railsに触り続ける

ハンズオン形式の動画や、初心者本などで学びながら、Railsの挙動を覚えていきましょう。ただ、Viewの機能(クライアント層)については、今はRailsで担保せず、別でサーバーを立ててすることも多くなっているので、そこだけは薄めに勉強しても大丈夫かもしれません。

SQLに触る

バックエンドエンジニアを目指す場合は、SQLの理解は不可欠です。Railsの「ActiveRecord」が、SQL文の発行を代行してくれるとはいえ、自分も知っておく必要があるので、基礎文法は早めに学びましょう。

Gitに触る

Progateで学んでいるとは思いますが、チームで使う上に、ミスが起こるとチームメンバーに迷惑をかかることが多いので、早めに、深く学んでおきましょう。「仕組み」自体の理解はそこまで深堀りしなくてもいいですが、「挙動」と「コマンド」については、絶対的な自信を持つぐらいにやっておくことをオススメします。

HTTPについて学ぶ

バックエンドはHTTPリクエストを受け取り、処理を行うことが主な仕事の一つです。HTTPリクエストについて、学んでおきましょう。

Webを支える技術に触れる

抽象的な概念が多いので、気合を入れて取り組みましょう。「なんかよくわからん…」と思った場合は、立ち止まってググりましょう。または、知り合いのエンジニアや、メンターの方に質問してもいいかもしれません。

3ヶ月目

Rubyを使う

問題を解きつつ、チェリー本といった、少しレベルの上がった実践的な本にチャレンジしてみましょう。「こんなことが出来るんだ」、「やってて楽しいな」というレベル感を持ててるのであれば、よいペースです。

Railsを知る

たぶん、まだRailsブラックボックスだと思います。触り続けましょう。また、今まで学んだRailsアプリを自己流に改造したりして、挙動を試してみましょう。

JavaScriptに触る

このあたりで、JSについて触っておきましょう。Rubyを学ぶ方法と同じで大丈夫です。

Linuxについて知る

Shellの仕組みやコマンドについて学んでおきましょう。

セキュリティ・暗号技術について知る

基本的なセキュリティ対策や、暗号技術について勉強しましょう。実務上、すぐに必須というわけではないですが、とても大事な分野ですし、未経験のうちに頭に概観とインデックスを作っておくのは大切です。

アルゴリズムを知る

基本的なアルゴリズムを知っておきましょう。

復習する

1,2ヶ月目の内容を復習して起きましょう。

4ヶ月目

RubyRails、JSを学び続ける

学習を続けましょう。かんたんでもいいので、1つ目のポートフォリオも、そろそろ作っておくとよいです。また、開発でよく使うGemについて、ドキュメントなどを読む練習をしておきましょう。

Dockerについて知る

開発環境を素早く安定的に構築したり、ミドルウェアの依存関係を管理しておく上で、Dockerの技術は必須で、現場でもよく使います。コマンドだけでなく、Dockerが保証している内容や、Dockerの仕組みついても学びましょう。

AWS(or GCP)、Herokuに触る

ポートフォリオをデプロイするときに触ると思いますので、やっておきましょう。また、NginxやUnicorn、Rackについても、調べておきましょう。

設計について知る

オブジェクト指向設計実践ガイド」で、どうして設計が重要か、機能の追加・変更が容易なアプリケーションを作るためにはどうすればいいか、について学びましょう。

Rubyをもっと知る

メタプログラミングRuby」やりましょう!

JavaScriptフレームワークに触る(React、Vue等)

バックエンド志望の場合でもちゃんと触って、ある程度の挙動(クライアント層で解決したい課題とは何か)について知っておきましょう。フロントエンド志望の方は、この時点で、こちら側に勉強をシフトしましょう。(もっと早く移動してもいいかも。)

Githubについて知る

プルリクエストの作り方だったりのGithub Flowを勉強しておきましょう。チーム開発で必要になります。

5ヶ月目

ポートフォリオを作る

学習と並行して、ちゃんと作っておきましょう。

DB設計について知る

DB構造の基本的なアンチパターンについて学んで起きましょう。

テストについて知る

どうしてテストが必要なのか、またRSpecのテストとはどのようなものか、について学びましょう。

どのようなエンジニアになりたいか考える

たぶんもっと前から考えていると思いますが、決まっていない場合は、考えておきましょう。

6ヶ月目

ポートフォリオを完成させる

基本機能については、実装を完了させデプロイしておきましょう。

就活を行う

インターンでもいいです。

技術を学び続ける

入社したい企業が使ってる技術について、学んでおきましょう。(例: CircleCI、OpenAPI、Swagger、Firebase、Lambda、Kubernetesなど)

また、余裕があれば低レイヤーの知識(CPU、OSなど)も、学んでおきましょう。

以上のことを学べば、「未経験なのによく勉強しているね」という水準には確実に達しています。

もちろん、勉強期間を3ヶ月にして、「インターンとして働きながら勉強する」といった戦略に切り替えたりするのもよいと思いますので、そこは柔軟に行動してください。

心構え

上に挙げた学習ロードマップは、あくまでも「順調に学習をこなせた場合」です。かなり量がありますし、ぶっちゃけ、結構お腹いっぱいになって、「とても終わらねえよ」、「つらみが深い」という状況になることも予想されます。

ただ、出来る限り、以下のような心構えで、頑張って欲しいと思います。(これはぼくが考えていたことなので、心構えについては、各々で設定していいと思います。)

勉強時間にこだわる

「プログラミングに投資した時間」を、いかに伸ばしていくか。質も大事ですが、前提として量は必要不可欠です。

習慣を作る

おそらく、最低でも一日に8時間勉強が必要になると思いますが、この時間数を実際に達成するのは実はかなり難しいです。意思の力に頼っていては無理で、かつ、がむしゃらに気合でクリアできるというものでもありません。人によってクリアの仕方は異なるとは思いますが、「モチベーション」に頼って勉強時間を増やそうとすると挫折しやすいので、習慣化して達成を目指すといいと思います。

ちなみに、習慣化したあとに「プログラミングが辛すぎる」と思った場合、無理をしていることが多いので、一度休んだほうがいいです。自分のキャパシティを超えたり、背伸びをしすぎた学習を行っている場合があります。(掛け算を知らないのに、因数分解を解いているような状況)。そういう心の声を無視すると、あとで歪みが出るし、そもそもの効率が悪くなります。

僕の場合は幸いにも「プログラミングが辛い」と思うことはほとんどなかったですが、エラーに襲われているスクールの同期の方などは、わりとつらみマシマシな状況に見えたので、そういう場合は、出来る限り自分を客観視して、「なぜ辛いのか」を探るのがいいと思います。

だましだましでもいいので、「学習って楽しいなあ」レベルを維持しましょう。自分のペースで勉強出来る、という状況で、「辛い」と思ってしまっているのは、もったいないです。

学習素材を知る

世の中にはたくさん媒体があります。本を読むのが辛いときは動画で、動画が辛いときはネット記事で、ネット記事が辛いときは、誰かと話して、誰とも話したくないときは、Twitterで情報収集して、それが嫌ならPodCastでラジオ聞いて…。

選択肢をたくさん持ちましょう。少ないとすぐに飽きます。

教材に出し惜しみをしない

本や動画は、欲しくなったら惜しまずバンバン買いましょう。2000~3000円の出費を躊躇していてはいけません。もちろん、買うだけでやらないのは無駄なので、買ったら出来る限り早く消化しましょう。

理解できないとき、悪いのは「教材」(と思おう。)

「あなたが相対性理論を理解できないとき、悪いのはあなたではなく、相対性理論を説明している教材です。」

この意見は議論を呼ぶかもしれませんが、とにかく自分が伝えたいことはひとつ。学習初期の段階で、自分の才能を疑うことはしてはいけないということです。

どんなに頑張っても理解できないとき、悪いのは自分ではない、と思い込んで、教材レベルを落とすなどして対応しましょう。

掛け算の意味を全く理解していない状況で、九九を理解しようとしても、それは力になりません。まして、何も理解のないまま暗記などしても、結局、大事なところで使うことができません。

おわりに

とても長くなってしまいましたが、自分も独学を続けていたとき、「いったい何をやればいいんだ」と悩んでいた経験があったので、そういう方に向けて、役に立つ記事になっていればと思います。

たのしみましょう!

自分が主にお世話になった文献・記事・動画など

Ruby

書籍
サイト

Rails

書籍
  • Ruby on Rails5 アプリケーションプログラミング
  • 現場で使える Ruby on Rails 5速習実践ガイド
動画
  • フルスタックエンジニアが教える 即戦力Railsエンジニア養成講座(Udemy)
サイト

JavaScript

書籍
サイト

SQL・DB

  • SQL ゼロから始めるデータベース操作
  • 失敗から学ぶRDBの正しい歩き方

ネットワーク系

  • 3分間ネットワーク基礎講座
  • プロになるためにWeb技術入門
  • Webを支える技術
  • Real World HTTP
  • Web API The Good Parts

以下、箇条書き

とりあえず、Kindleに入ってるのを書き出しました。

良い本・動画ばかりなので、ぜひやってみてください!