seri::diary

日常

技術で生きていきたいから信じてコードを書く

tl;dr

  • エンジニアとしてどういう風に生き残ればよいかという問いについてずっと考えてきた。
  • でもようやく今後の自分のキャリアをこうしたい!というのが固まってきたよ。
  • それをやるためにコードを書き続けるよ。

エンジニアきのこ話

他の人も良く考えているのか、身近なエンジニアと飲みに行くと大体このきのこ話になるし、その手のネット記事は月に1回ぐらいは見る。

例えば今年だとこういう記事を読んだ。

f-shin.net

srknr.hatenablog.com

エンジニア 生存戦略 とかでおググりになってほしい。大量に出てくる。 媒体も法人メディア、個人ブログ、Qiitaと幅広い。それだけみんな関心があるんだろうな。

自分も長いこと次のキャリアを色々と考えてきた。
現場を離れてピープルマネジメントをする、プロダクト自体のマネジメント方面にシフトするなど、少なくとも今のwebアプリケーションエンジニアのままではいられないと思っていた。 また、プログラミングを職業にしているせいで発生するつらみが大きくなりすぎて、エンジニアのポジションをそもそも辞めようと思ったことも何度かある。1

ここ数年、20代後半になってからずっと将来の結構キャリアに迷ってきたが、色々痛い目を見たり考えたり人の話を聞いたりする中で、ようやくやりたいことがはっきりしてきた。 自分は今後これをやって飯を食っていくんだ、と思えるものがようやく固まってきた。これが2016年後半の出来事。
それからはずっと、そのキャリアを実現するためだけに動いてきた。 そして、来年からはそのキャリアを実現するために実際にいくつかアクションを起こしていく。

で、何やるの

それをどうやって達成するかだが、自分が目的を達成するために足りない技術を勉強し、その上でコードを書き続けるしかないと考えている。 コードを書くことだけが云々、もう歳なんだから云々、という声も聞こえてくるし自分も直接言われたことがある。でも結局自分で手を動かして実感を得ながらでないと、どんな分野でもコンピュータの世界においては「わかった」ことにならないと思っている。だからこれはもうこの業界にいる以上、一生続けたい。

最近はrailsエンジニアとして仕事をする一方で、プライベートでは全然仕事で使わないような技術分野を勉強したりコードを書いたりしている。例えばHadoopのソースを読んだり、量子コンピュータスパコンや分散処理についての本を読んだり、自分でMapReduceを実装したりしている。2

その分野が何なのかは、2018年の自分のアウトプットを見てももらえれば誰から見ても分かるようにしていきたい。それが2018年の目標だ。


  1. プログラミングは好きだが仕事としてはつらい、という感じのやつ。なのでこういうこと も積極的に意識するようになった

  2. これについてはソースを公開するタイミングでこのブログで詳細を書きたいと思う

webサービス業界で働き始めて丸5年が経とうとしている

いわゆる「webサービス業界」というものに入ってから、今年の12月で丸5年が経とうとしている。

一般的に使われる「web業界」(もう死語かな)ではなく「webサービス業界」と書いたのは、「作って別の組織に納品して終わりというスタイルの開発だけではない開発をするようになってから5年が経とうとしている」という意味で区別したかったので、本エントリではこのように書くことにする。因みにそれ以前はSIerと受託開発をしていた。

この5年間はどんな5年間だったかを一度ここらで振り返っておきたい。

最初の3年間

完全に自分の力を伸ばすための期間だった。 当初の所感とかは以下のエントリに書いている。

serihiro.hatenablog.com

serihiro.hatenablog.com

この業界でやりたいことも将来やりたいことも何も考えずに、ひたすら自分のスキルを伸ばして、業界内での存在感を出そうとしていたように思う。とにかくエンジニアとして周りと比べて劣っている自分を何とかする、ということしか眼中になかった。

当時具体的にやったことを書いていく。

まず与えらえた仕事はかなり必死こいてやった。スキルも大したことがなかったので「必死こかざるを得なかった」というのが正解かもしれないが、とにかく早く、正確に、与えられたタスクをひたすら消化することに集中していたと思う。

夜9時に退社するのも普通に感じてたのもこの頃だった。自宅で勉強することよりも職場で学べることの方が圧倒的に多かったので、職場で大量に仕事をこなすことが一番の近道だと信じていた。実際、自分よりも何年もキャリアが長くスキルも高い先輩に囲まれて、とにかく自分が頑張れば頑張るほど自分の成長が見えて楽しい時期だったし、仕事もそれなりに上手くいっていたように思う。

この間、仕事で使う言語もjavarubyの2つの言語を経験したことで、静的型付け言語と動的型付け言語の両方のpros/consを学ぶことができた。どちらもOOP言語だったことで移行がスムーズだったように思う。その前のphpjavaが結構大変だったのに対して。

仕事以外の活動として、勉強会を主催するようになった。渋谷javaという、今でも別の方による運営が続いてる勉強会を立ち上げて、自分で運営して、ついでに自分も発表するというようなことをしていた。

ただ、当時はjavaを極めてjavaで一生食ってこうなんていう気持ちはあまりなかったように思う。自分自身が色んな勉強会に出るようになったことで感じたミュニティの力の大きさに感動して、とにかくコミュニティに貢献したいという気持ちと、自分のプレゼンスを上げて会社外でも名前を知られる存在になりたいという感じの自己承認欲求が主なモチベーションだった。 それを実現するためのテーマとして、当時仕事で使っていたjavaを選んだという感じだった。実際、このころ何かjavaについて取り立てて詳しい訳でもなく、OSSのプロダクトも作っていなかったから、発表した内容はせいぜい自分が見つけた便利なライブラリ紹介をする程度に留まっていた。それが限界だった時代だった。

今でこそembulk、digdagといった著名なjava製のツールをソースレベルで仕様を調べてそれなりに使っているので、もう少し気の利いた話を出来そうなものである。しかし、当時の自分にとって、javaはwebアプリケーションを書くための言語という位置づけでしかなかった。そもそもwebアプリケーションを書くのが自分が出来る精いっぱいのことだったし、それ以外の世界を知らなかった。

次の2年間

10年後ぐらいにこの2年間を振り返った時、大きなターニングポイントになった2年間だったと自分が評価するであろう期間だと思っている。

この2年間で大きく変わったのは自分への評価だ。 それまでは、最初の3年間が終わるその時まで、自分は同業者に対してものすごい劣等感を感じ続けていた。そしてそれをモチベーションに仕事をしてきた節があった。

しかし、この2年間でその劣等感はだいぶ払拭されたように感じる。単なる思い込みや驕りかもしれないが、一応webアプリケーションを書いてる人間としては、そこそこ出来る方の側に属するのではないか、と感じるようになった。

転職して仕事のスタイルが大きく変わったことも大きい。以前、以下のエントリにも書いたが、セルフマネジメントをしなければならない領域が最初の3年間と比べて大幅に増えた。

serihiro.hatenablog.com

具体的な指示もない中で自分で会社にとって何が必要か、今何をすべきかを必死に考えて実践しなければならなくなった。恐らく世の中のスタートアップと呼ばれる企業はどこもそのような要素を多かれ少なかれ含んでいるのだと思うが、自分が入った会社もまさにそうだった。

この環境で鍛えられたのは単純な技術的なスキルというよりは、何をすべきかを自分で考え出すスキルだったと思う。

プロジェクトにアサインされている時は、APIメンテナとして要件をまとめて設計をし実装とテストをするというそれまでと変わらない仕事もした。しかし、それ以外に、今プロジェクトの中で自分が何をしなければならないか、何をすればプロジェクトがうまく進むのか、ということを考えて行動する必要が出てきた。

特に人を動かすという部分ではそうだった。エンジニア出身でない人に何がどういう理由で必要かを説明し、説得し、動いてもらう。そういう技能が要求される画面が増えた。 それまでは、ほぼエンジニアとデザイナ(フロントエンドの実装も兼任する)とマネージャー(エンジニア出身の)とだけコミュニケーションが取れればよく、コミュニケーションに悩んだことはあまりなかった。コンテキストが重なる領域が多いので、ある程度ツーカーで会話ができていた。 しかし、エンジニアリングの知識が無いが、重要なドメイン知識を持つメンバーと仕事をするケースが増えた。そのため、そういったメンバーとのコミュニケーションを行い、上手くその人達と協業するためのコミュニケーションを円滑に行うというタスクが大幅に増えたと言える。 今まで単にそういうことが必要なかったのは他の人がやってくれていたおかげだが、組織が変わってそれを自分でやる必要が出た。最初はうまくいかない面も多かったが、最近はそういうコミュニケーションミスに起因して発生するトラブルを先回りして回避するためのプロジェクト進行上のテクニックがかなり身に付いたように思う。

プロジェクトにアサインされていない時は、今メンテしているプロダクトに何が必要かを考えてタスクを自ら生み出す必要があった。 これは逆にこれまでの貯金が生きた部分で、驚くほど上手くハマった事例をいくつか作ることができた。今までのプロジェクトでやってよかったこと、悪かったことに関する知見をフルに活かすことができた。

今の職場での入社直後に集中的にこれまでの知見を用いて開発環境をもろもろいじったのだが、何をやったかは以下のエントリに書いた。

serihiro.hatenablog.com

プロダクトの設計面では、自分が以前から構想していたrailsにおける非同期jobを管理するためのアーキテクチャを導入して実装したりもした。サブシステムを丸々一つ一人で実装するようなこともあって、そういう時はこれまでやりたくてもやれなかったようなアイデアを堂々と導入することができた。

それ以外の面では属人化していたスキルや知識をパブリックにすることに力を注いだ(誰も気にしていない領域だったので勝手にやった)。

自分が入るまで特定のエンジニアにしか出来なかったことを管理画面に移植してセールスやサポートチームでも出来るようにしたり、社内コミュニケーション用のツールとして使っている esa.io#知見 というタグをつけて、こまめに社内向けの知見(歴史的経緯で分かりづらくなっている機能の仕様だとか分かりづらいモデリングに関する解説だとか)書き残したりしている。

特に、特定のプロダクトや機能に関する解説資料は、 #徹底解説シリーズ というタグをつけてかなりの長文で解説記事を書いたりもした。読まれているものもそうでないものもあるが、主に自分が仕様を思い出したり、他のエンジニアに仕様を説明したりするのに役立っている。

これまで書いた #徹底解説シリーズ で一番社内の反応が多かったのは、APIが参照しているDBのモデルに関する解説記事だった。 これは、主要なモデルに関するドメインレベルでの解説と、それらのモデルを検索するための用途別のSQL例をセットで記載したもので、非エンジニアにもSQLを覚えれば自由にデータを参照できるようになってもらうことが目的だった。まぁ実際にSQLを書いてくれる人が増えた訳ではなく、結局エンジニアやデータサイエンティストがSQLを書いてデータをBigQueryから取り出す状態は変わらなかったが、それでもこれから入ってくるエンジニアやデータサイエンティストのためのオンボーディング資料として役に立つんじゃないだろうか。

仕事以外の部分ではいくつかのgemをリリースした。殆どがrailsに関連するものだが、例えばflatten_routesは自分が趣味で作ってたrails productで必要だったので作ったものだが、実際にこれは似たようなgemを見たことがないという点ではそれなりに意味のあるgemだったのではないかと思っている。あとshoryuken, google-auth-library-ruby, ruby-openid といったgemにcontributeすることもできた。

github.com

あと開発手法に関するLTを社外で2回行った。どちらも大した話はしてないが、両者ともその後の懇親会ではそれなりに好意的なコメントを直接いただいた。

speakerdeck.com

speakerdeck.com

こういった経験で得たいくつかの成功体験を通して、自分自身はまぁまぁ出来る方のエンジニアだなとうっすらと感じるようになった。(もちろんやらかした事例もある)

現職の他のエンジニアも優秀なメンバーが多いと感じるが、彼らとうまく連携して仕事ができているという点と、それまで出来ていなかったことをそれなりに達成できたという点で自分もまぁそれなりにできる方になっていたのではないかと感じる。特にrailsによるweb appの開発という面において技術面では大きな課題を感じたことは殆どなかった。どちらかと言えば課題を感じたのは、上述したプロジェクトの進め方をいかに円滑にするかという部分だった。

新しく興味を持ったもの

一方で、ここ2年間で技術的にはwebアプリケーション以外の領域に目が向くようになった。

今何か作りたいものがありますか?と聞かれたら自分はBigQueryのような大規模データ分析基盤、もしくはそのBackEndで動作する分散job workerか分散File Systemと答える。
きっかけは今の会社に入ってから使うようになったBigQueryで、これは本当に革新的だと思った。

BigQueryは使う人から見たらただのRDBMSじゃん、と思うかもしれない。しかし、MySQLOracleを仕事で使ってきた人なら分かると思うが、比べ物にならないぐらいのreadパフォーマンスを何のチューニングもしなくても出せるという一点で、RDBMSとは全く異なる存在である。 実際自分も使ってみるまではそのパフォーマンスに懐疑的だったが、数千万行から数億行のレコードをフルスキャンしなければ実現できないような集計クエリが20秒程度で返ってきた時は度肝を抜かれた。また、日々どれだけレコードが増えてもパフォーマンスが殆ど劣化しない。雑にBQにdatasetとテーブルを作ってembulkで流し込みさえすれば、後は自由にクエリを書いてデータをシュッと取り出せる。

この体験は使ってみないと分からないと思うが、入社して初めてnginxのログをBQで検索したときは本当に革新的だと思った。こういうものこそが自分がそれまで必要としていたものだった。

これまで、著名なサービスを除けば世の中のサービス開発はデータを軽視されていたと個人的に感じていたのだけど、それは大規模なデータを取り扱うためのDWHのようななにがしかを「サービスが稼働し始めた後から」作るイニシャルコストが無視できないほど大きかったからだと考えている。大企業はともかく、スタートアップとしてはそのような大型投資を簡単にできない状況が多いと思われる。

しかしBigQueryは、PaaSとしては高い方だと思ったけど、テーブルを作ってデータをinsertするだけなら大した額はかからない。しかも、すぐに始められるから、どれぐらいの投資が必要か判断できなくてもスモールスタートで「とりあえずこのテーブルだけ分析できるか検証してから決めたい」という時にすぐに判断ができる。本番のDBに投げたら絶対返ってこないようなクエリがすぐに打てる。これがビジネスにどれだけの影響を与えるか。

というような具合に、ビジネス面でのインパクトも感じたが、一方でそもそもどういう風に実装されているのかという点に自分は興味を持った。
分散データ処理と言えばおなじみMapReduceだが、そもそも自分はMapReduceを使ったこともなければ使いどころについても検討したことがない。まずはこっからだ、ということで今年に入ってからMapReduceのオリジナルの論文や、Hadoopの高速化に関する論文を読んだり、ここ数年のビッグデータの処理基盤に関する傾向を調べたりした。 分かったことは、今の時代ではHadoopがかつて抱えていた問題(それこそ論文で議論されていたような)を解決するようなossが増加し(spark, kuduなど)、MapReduceはオワコンみたいな話をえらい人がパブリックな場でするようになって、もはや枯れた技術となってきているということが分かった。が、大規模なデータを処理するためのアルゴリズムとしては優れており、それを支えるためのストレージ/NWの技術は着実に進歩しているし、個人的にはまだ研究したいと思える技術ではある(まぁproductionで使ったことないし)。

次の5年間

今までは自分の劣等感をモチベーションとした「成長」だけを意識して仕事をしてきたが、これからは作りたいものを作るための技術習得にフォーカスして、作りたいものをやるために仕事をしようと思う。ビジネスのための手段としてwebアプリケーションを作るという意識が強かったが、単純に自分が作りたいと思うものに技術をつぎ込んだ結果、それがビジネスになり自分のお賃金になる。そういうポジションを目指したいと思う。

健康面で気を付けていること

台風がいくつか過ぎ去ってようやく秋らしくなってきた気がする。
そのせいか身の回りでは体調を崩す人が多い。自分も微妙に体調が悪い日はたまにある。

20代の頃ならば何も考えていなくても体調は崩さないし、崩したとしてもすぐに治るから普段から気に掛けてはいなかった。しかし自分の場合、30歳になったのを境に、急に体調の治りが悪くなった。一度体調を崩すと同じ症状が最低2日は続く。頭痛、睡眠障害、異常なだるさ、消化器官の不調、あと典型的な風邪の症状。「あ、ヤバイな」と思った時にはそこから数えて最低2日は同じ症状が続くようになった。認めたくはないが、自分も老化という現象が自己主張をし始める年齢に来たのだなと思う。

これはいかんなと思って体調をようやく気遣うようになり、最近は周りが風邪引いたりしている中であっても体調を維持できている。備忘録として何に気を付けているか書き記しておきたい。

睡眠時間の確保

適切な睡眠時間については諸説あるが、自分は眠りが浅い日が多いのでその分時間でカバーできるように7時間半~8時間は寝るようにしている。具体的には23時ぐらいに寝て6時30分ぐらいに起きるのを標準としているが、コード書いてたり本読んでたりすると気が付くと日付を過ぎていることもあって、寝る時間はマチマチだったりする。それでも睡眠時間はできるだけ一定時間を確保できるように、なるべく早く寝ることに努めている。

睡眠時間よりも起床時間の方が重要だという話も読んだことがあるが、平日の1日を通してみると前日の睡眠時間が不十分だと明らかに日中に眠くなり、パフォーマンスが低下するため、どちらかと言えば睡眠時間の確保を優先していることが多い。

suimin-supple.com

運動する

とか言いつつ10月入ってから仕事の関係で一度もやってなかったりするのだが(よくない。。)、ジムで筋トレとジョギングを週1ぐらいでしている(た)。本当は毎日やった方がいいのだが、英語とか数学とかその他技術書読む時間を夜に確保したい関係でなかなか毎日は難しい状態である。

社会人になってから運動しなくなったという話以前に、そもそも大学入学以降は普段から全く運動などしていなかったのだが、30代になるとその弊害が顕著に出てくるらしい。なので30代になってから運動するのは結構必須っぽい気がする。*1運動の効果は言わずもがなだが、一番大きいのは体を動かすことでストレスが解消できる点だと思う。

この稼業は基本1日中座りっぱなしで、その上ストレスフルな状況に1日中晒されているので仕事終わりには相当ストレスが溜まっている状態になっていることが多い。
1日に受けた体と精神へのストレスはその日のうちに解消できるのが一番いいはずで、それを行う上で軽い運動をするのが一番効率がよいのではないだろうかということで、今後も続けていきたい所存。

野菜を意識して食べる

意識しないと肉ばかり食べてしまうので意識的に野菜を取るようにしている。

コンビニとかスーパーの出来上いのサラダばっか食べてて、本当はそれも添加物と残留農薬だらけであまり良くないんだろうなぁと思うが背に腹は代えられぬ。 一人暮らしなので個々に野菜買ってサラダ作っても食べきる前に野菜が傷む問題がどうしても解決しないので諦めている。

あとはまぁ添加物使ってないと主張する体に良さげな(オーガニックとかエスニックとかっていう冠詞がついた)店舗で食事をするとか。実際自分は週に1回はランチにサラダがやたら多いランチコースがあるアジア系料理のカフェで食事をしている。

あと野菜不足を補うためにベジールという野菜ジュースを定期購入して飲んでいる。これも効果があるかどうかは定かではないが一応飲み続けている。

www.oisix.com

瞑想

サーチ・インサイド・ユアセルフを読んでから習慣的に瞑想をするようになったが、果たして体調にまで効果があるかはよく分かっていない。

しかし、1日にあった出来事を振り返るための時間を強制的に取れたり、高ぶった感情を鎮めるため(まぁ仕事でイライラしてると結構眠れないものである)という目的においてはかなり効果があると感じる。

イライラしたらなぜイライラしているかを考える

自分の体はどうもストレスに弱いらしく、ストレスフルな状況になると体調を崩しやすくなる傾向にあるようだ。 なので、ストレスを強く感じてるなーと思ったらなぜストレスを感じているのか?を考えるようにして、できるだけ明確にするようにしている。

やり方として、今不満に思っていることをeditorでも紙でもホワイトボードでも何でもいいので書き出してみて、それを眺めて根本の原因を突き詰めていく方法を取っている。大体10個ぐらい書き出せばまぁ何となく原因らしいものは見えてくるので、それは解決すべき問題かどうか、そもそも自分に解決できるのかどうか、どういうやり方で解決するか、というのを考える。

この作業の結果、具体的な解決策が見いだせればそれを実行するし、自分の力ではどうにもならんなと思ったらまぁ諦めてしまうことにしている。仕事のストレスの原因のうち殆どは後者で、どうしようもなく遠い所で発生している問題が、たまたま担当者として自分の所まで降りてきただけだなということがよくある。

自分をほめる

これもストレス緩和のための施策の一つだが、ほめるのである。31歳のおっさんが、自分を。考えただけで気持ち悪いだろう。

でも自分をほめられるのは自分だけなのである。仕事や趣味の活動で他人にほめられた経験なんて殆どない。誰かをほめたことはあるが、それによって相手が満足したかどうかは定かではない。しかし、自分であれば、自分の行動を検証した上で納得のいく評価ができる。その上で、よくやったなと思ったら自分で自分をほめても良い、ということにしている。

ここまで書き出してみて我ながら気持ち悪いことしてるなぁと思うが、実際そうでもしなければやっていけないし、自分を褒めて、例えば本を一冊買うことを許可するとかSteamでクソゲー一本買うのを許可するなんてのは安いもんである。 いくら社会のために仕事をしているという大義はあっても、それを感じられるのは本当に稀である。めちゃくちゃ大変なプロジェクトを何とか達成したとしても必ずしもそれが客観的な評価につながることは稀である。でも一方で、検証した上で自分なりに評価されてもいいと(もしくは評価されるべきでないと)判断することはできる。

自分の一番の理解者は自分なのであると思う。だから、ほめるべき仕事をしたなぁと思ったら自分で自分をほめてやることにしている。結局、歳を取れば取るほどポジティブに自分を明示的に評価してくれる他人がいなくなっていくのが人生というものなのだろうとも最近思うようになった。*2 ちなみにこんな本もあるらしい。まだ読んでないけど。

併せて読みたい

眠くならない飲み物の摂取の仕方が参考になった。

blog.satotaichi.info

*1:のでジム通いは再開したい

*2:ドラえもんも「大人ってかわいそうだね。自分より大きなものがいないもの。よりかかってあまえたり、しかってくれる人がいないんだもの。」と言っていた。

余裕はあるけど今やらなくても良さそうだけどいつかやった方がいいタスク問題

こういうタスクは大体「溜まる」傾向にある。 github issueでいえば いつかやる とか NiceToHave なんていう、何とも第三者から見ると全くプライオリティが想像できないタグが付けられて、そして1か月もたつとissueの存在すら忘れる。*1

自分の場合、こういうのを貯めておくと気持ち悪いので、それほど余裕がなくてもスキを見てさっさと片付けてしまう傾向にある。今日も例外発生時の調査用のログフォーマットを調整するだけのPRを出した。*2

余裕ができると自分はリファクタリングのPRを週に10個近く出していることがある。流石にレビューを依頼される同僚からはドン引きされたのではなかろうかと思うが、プロジェクトの谷間とかで急ぎの仕事がなければそういうことをせざるを得ない時もあるのである。

そのため、自分がアサインされているissueは遅くても1か月にはcloseされている傾向にあるようだ。ようだ、というのは正確に計測した訳ではなく肌感覚だからなのだが、少なくとも3か月以上closeされていないissueに関して言えば自分は1つしか持ってない。これはやらないのではなく色々な事情でcloseできておらず目の下継続中のタスクなのだ。

さて、こういうタスクに関してだが、他のメンバーを見ると結構古いissueをずっと抱えているのをよく見かける。openなissue絶対closeするマンの自分は、時間ができると他の人のissueを見て回って「進捗どうですか?」的質問をして状況を確認し、わざわざその時のステータスをコメントに書いてみたり、アサインされていないものは適当にやれそうな人をアサインしておくことがある。あるいは自分で勝手に巻き取ってやってしまうこともある。自分がやれるタイミングなら自分がやるのが一番早いからだ。

自分の場合、積み残した仕事というのがそもそも自分として許せない存在であり、改めて検討した結果やる必要がないと判断できるならすぐcloseしてしまうし、イシューになっている(githubのissueではなく本来の意味のissue)時点でそれは自分のチームの責務なので、なるはやでcloseに向けて動くのが仕事だと思っている。

こういう積みタスクというのは、クライアントにも同僚にも喜ばれる華々しい機能追加ではなく、大抵はちょっとしたtypoを直すとか、社内用の画面のちょっとしたバグだとか、急いでいたので黙認したrubocopの警告を直すとか、ライブラリのバージョンを上げるとか、拡張性の悪いクラスを細かく分割してspecを書き直す、とか、めったに起きないエラーを調査して直すとか、使ってないクラスを既存コードに影響しないように取り外すとか、使ってないのになぜかDBに残ってるテーブルをdropするとか、not null制約がないとどう考えてもおかしいのに付いてないカラムに付けるとか、そういうやつである。

そのため、会社の売上にも貢献できず、その上誰からも感謝もされず、評価もされにくい貢献だと思われがちなせいか、多くの人は避けたがる。だがその思い込みは恐らく間違いだ。そうこうしているといつか大きな負債を生んで自らを苦しめる(もしくは苦しめられた)例を自分は沢山知っているし、逆に自分が時間がある時に仕込んだ詳細なログのおかげで命拾いしたことが何度もある。これはれっきとした技術的負債の返済であり、将来の自分たちを救うための重要なタスクなのだ、と思ってもらいたい(のだが、一度そういうマインドが染みついた人の思想を変えるのは実際難しい)。

こういうタスクは実際会社の売上には1円も影響しないかもしれないが、将来発生し得る100万円の損害を1万円に抑えられるかもしれない可能性を秘めている。いざ大障害が起きてから「ログが少なくて状況が分かりません」だとか「コードが汚くて修正するのに時間がかかります」などと言ってられるだろうか。そういう目にあってから初めて目を覚ますのでは遅すぎる。

こういう負債をまとめて返済すべく派手にリファクタリングするのはデグレのリスクが大きくなる。そのため、5行とか10行とかの小さなPRを普段から出し続けて地道に改善するしかないのである。GoogleUeyama Ruiさんのブログにも同じような話が書かれている。

blog.sigbus.info

自分はオープンソースに何度かPRを出してマージされたことがあるが、基本的に仕事でコードを書くのとオープンソースのコードをいじるのとは全く同じスタンスで考えている。つまり、変更の意図が分かりやすく、必要な量のコメントが書いてあって、自分以外の誰かが次にいじる時に困らないようにするということを常に守っている。実際、オープンソースにPRを出す練習のつもりで、これまでつらつら述べてきた「誰もやりたがらないタスク」を片付けている部分もある。そう考えればそこまで退屈なタスクでもないし、タイムアタックだといわんばかりに1日に何個片付けられるか挑戦してみたりすることで自分はそれなりに退屈しないでいられるのだが、もしかしたら自分が変わってるだけなのかもなぁという気持ちにもなっている昨今である。

*1:こういうタスクどうやって管理するのがいいのかいまだによく分からないがどうやっても発生してしまう。定期的に棚卸すればいいのだろうか。誰か教えてくれ。

*2:今の会社に入ってからBugsnag入れたりログを増やしたりログを検索できるようにしたり、エラーを可視化する仕事ばかりしている気すらする。この手の運用に強いコードにするためのリファクタリングのコンサル業だけで飯が食えそうな勢いである。

業務と勉強

少し前にtwitter界隈で話題になった話に軽く便乗してみる。

と言っても、プライベートの時間に勉強しなければいけないかどうかとかそういう話ではない。業務の余った時間を自分の勉強に宛ててよいか、どうかという話。*1

先に断っておくが、「自分の勉強」とは、仕事に関係あるものではなく、使うかどうか全く分からない技術のことを指す。

どこまで関係あってないかという線引きもかなり主観的なものなので難しいが、採用可能性が少しでもあるものは「仕事に関係がある勉強」。何をどう考えても仕事で採用可能性がないものは「仕事に関係がない勉強」と定義する。

自分の場合、前者は最新バージョンのrubyrailsのコードを読んで動向を知るとか、AWSの新しいサービスを試してみるとか、Rの新しいプラグインを試してみる、とかが該当する。後者は、数学だったり、Hadoop3の動向を追っかけるためにJIRAを読んでいたり、DockerでHDFSクラスタを作ってIrisデータをいじくっている、といったものが該当する。少なくとも今の会社でデータストアを自前でホスティングして使うことはしない。

で、自分は会社で「勉強」するのが物凄く苦手である。

もちろんタスクがある時は全力でやっている。しかし、大抵予定していたスケジュールより早く自分の仕事は終わってしまうため、プロジェクトとプロジェクトの間が1週間から2週間空くことがある。もちろん、その間何も仕事をしていない訳ではないが、単発的に1日に1時間かそこら集中してやれば終わってしまうタスクがたまに発生するだけの状態になってしまうことがある。

そういう時に何をするか。それが目の下の問題である。

まずは積んであるbugfixとかリファクタリングのissueを片付けまくる。だがそれもなくなってしまい、他のメンバーに仕事はないかと聞いて回っても見つからなくなるといよいよ困る。

そういう状態のときに、一応やるべきことはすべてこなしたし、好きなことをしていても(多分)文句はないはずだが、それが中々できない。

なぜかといえば、自分は手持ち無沙汰なのに、周りの社員はプロジェクトに従事して各自の仕事をしていて、そういう社員に対する後ろめたさみたいなものが影響しているのだと思われる。

忙しそうにしているからには手伝いたいのだが、なかなかうまく途中参加できないケースもあるし、そもそも職種が違う関係ですぐに手が出ないケースもある。*2同じサーバーサイドのタスクであればいくらでも引き受け放題なのだが、そういうケースばかりでないのが厳しい所である。

普通に考えれば仕事がないのは別に自分のせいでもないし、別にサボって仕事をしていない訳ではない。だから堂々とすればよいのだが、なぜだか他の社員に対し後ろめたさを感じてしまう。勤務中は会社のためになることをすべきである、という考えが強すぎるのかもしれないが、とにかくせっかくスキマ時間を生み出しても、上手く自分のために時間を使えていないように感じている。

こういった複雑な葛藤を一切持たずして勉強できるようになるのは退勤してからである。オフィスを一歩出たら仕事のことは一切考えず(とは言ってもやはり少しは考えてしまうのだが)やりたいことに集中するようにしている。逆に仕事をしている間は仕事のことしか考えない。

そうやってメリハリをつけて、少しでも仕事を早く終わらせて、やりたいことをやる時間を最大化するための努力をすることが今のところ勉強時間を確保するためにしていることである。

いつか自分が勉強したいことと仕事で必要なことが綺麗に一致して、業務時間中の勉強はすべて業務のためになる、というような状況を自分で作り出したいものである。

*1:プライベートの勉強はやりたきゃやればよいし、会社から露骨に強制されたら業務内でやらせてくれと主張すれば良いだけではないだろうか。

*2:自分の場合、フロントエンドやiosは普段触ってないだけにすぐに手伝える状態ではない

やりたいことを最初にやる,あるいは効率の良いプログラミングの勉強法について

去年は数ⅡB辺りを勉強したので今年は線形代数を勉強している。サラスの方法や余因子展開を使って行列式を求めたり、行列をあれこれ変形してrankを求めて一次方程式の解が求まるかどうかを日々検討しているのである。

しかし、勉強を始めたもともとの動機は、別の本を読んでたら出てきた「固有値」とか「固有ベクトル」という言葉の意味ってなんだっけ?という疑問であった。だから線形代数の本を買ってきて固有ベクトルの章だけ読めばよい。最初はそう思っていた。ところが、固有ベクトルの章だけ読んでもそれ以前の前提知識(特に行列式の意味や正則な行列の性質)がなければ理解できない内容だった。なので諦めて最初から参考書籍を読み問題集を解いているのである。

ちなみに読んでる本はこれ。とても分かりやすい。

プログラミングのための線形代数

プログラミングのための線形代数

問題集はこれ。学部生向けの模様。

新版 演習線形代数 ((新版演習数学ライブラリ))

新版 演習線形代数 ((新版演習数学ライブラリ))

線形代数のように順番に勉強しないといけないということは結構ある。多分資格の勉強とかも大体そうだろうと思う。しかし、新しいITスキルを習得しようとする時はどうだろうか?なぜこんなことを突然言い出したのかと言えば、今日図書館で線形代数の勉強をしていた時にふと思いついたからである。

かつての自分がやっていた「間違ったプログラミングの勉強法」

例えば、新しい言語を勉強する時に初心者用の入門書を買ってきて、頭から最後まで全部読んでからコードを書き始めるだろうか。実際、自分は一度だけやったことがある。webサービスを作りたくて,phpの入門書を買ってきて最初のページから写経し始めたのである。

ただ今振り返れば、phpを覚えてから7年ぐらい経っても未だに一度も使ったことがない関数やクラスのsampleコードを必死に写経していたのはかなり無駄だったなと感じる。もちろん、「こういうのがあるのか」というのを知っておくことは重要である。問題なのは、肝心のウェブサービスを作る上では不必要な知識だったということである。

実際に自分がphpwebサービスを作るために自分はどうしたか?入門書の最後の方に「応用課題」として掲載されていた掲示板だのSNSだののサンプルコードをコピペしまくって改造したのである。そうしなければwebサービスは作れなかった。その章に行き着くまでに多くのコードを書いたが、それだけでは足りなかったのである。echo "Hello, php!"; から始まり mysql_connect('localhost', 'root', 'pAssw0rd') or die('データベース接続エラー');みたいなことをやるscriptをいくら書いてもwebサービスを作ることはできなかったのである。

何が足りなかったのか?

いや、足りなかったというよりそもそも努力の仕方が間違っていた。webサービスを作りたければ、まずコピペでもなんでもいいから完成させてみることが重要だった。そうすれば自ずと何が必要か分かってくる。実際、自分のプログラミングのスキルや技術の知見は掲示板っぽい何かの実装を通じて大きく広がった。最終的にはさくらのVPSを借りてCentOSの使い方も調べてドメインまで取って、今見たらどうしようもなく意味の分からないみたいな掲示板もどきサービスを公開するところまで行った訳だが、プログラミングは覚えたので次はLinuxについてじっくり勉強してから。。などとやっていたらおそらく一生公開できなかったと思う。

それがなぜ公開にこぎつけられたかと言えば、まずやってみて、足りないと感じるものだけを補うように途中から方向転換したからだと思っている。それが結局は効率が良かった。勉強と言えばまず基礎をガッチリ固めて次に応用問題を。。という、高校までのスタイルにどっぷり浸かっていた自分は、当初プログラミングに対しても同じスタンスで挑んだが、プログラミングは学問ではない。道具なのだ。金槌を使えるようになるためにまず金槌の歴史の勉強から始める必要があるだろうか?全くないとは言い切れないが、大抵の人は金槌をまず握ってみるだろう。何なら叩いても良さそうなものを叩いてみるはずである。

プログラミングも多分同じだと思う。まず今必要なことをその言語でやってみる。次にそれで分かった足りないことを知るために書籍に立ち返って必要な部分を集中的に勉強する。結局、これが効率がよい勉強の仕方ではないかと自分では思っている。

自分がEffective Javaを読んだのはjavaを書くようになって1年近く経った後、Effective Rubyを読んだのもrubyを書くようになって2年以上経った後だったが、逆に初心者の頃だったら、何に役に立つのか分からずに多くの学びは得られなかったと思う。

新しいアプローチによる学習例

今でも新しいことを勉強するときはこのアプローチでやっていることが多い。
今年に入ってからはデータ分析の業務でpythonを結構書くようになったが(去年もNNの実装で使ったが)、何も考えずにまず brew install pyenv して pyenv install anaconda3 してjupyter notebookをinstallしてpandasでBigQueryのデータをいじり始めた。ハマりまくったが結局やりたいことはできた。*1
たまたま別件で調べ物をしていて見つけた某大学のシステムプログラミングの講義資料が面白くなってしまい全部写経して、まだ作ったことがなかったwebサーバーを書いた。Cを集中的に書いていた時はCがどういう風にメモリを管理するかロクに知らなかったので構造体を使ったコードを書いたら至る所でSEGVの嵐で泣きたくなったが、お陰様で低レイヤーの技術とアセンブラに興味が沸いて今では社内輪読会でパタヘネを読んでいる。

このアプローチの応用で、自分がまだやれたことがないと思うのが「自分が一番難しいと思うこと」からやってみる、というものである。これまでは「多分実現可能っぽくて(周りがやってたりするので)一番やりたいこと」から手を付ける、という感じではあったのだが、それだとどうしても自分のスキル面での成長が止まってしまうと危惧しており、逆に「実現可能か全然分からないけど自分の中で一番難しいと思うこと」から手を付けてみたいと考えるようになった。

実際には時間的な制約でできなかったり、あまりに壮大過ぎて結構本気でどこから手をつけていいか分からないというものだったりするのだが*2、少しずつ課題を切り崩して、何とかとっかかりを見つけていきたいものである。

併せて読みたい(というかこれ読めば上記の文は読まなくてよい)

luccafort.hatenablog.com

*1:のちにpyenvとanacondaは自分には不要とわかり使わなくなった。とりあえずpython機械学習したーいという人には最初からpyton3をbrewで入れる方法を勧めている

*2:具体例を挙げると「HDFSより使いやすいインターフェースを備えた分散ファイルシステム」「でかすぎるjobは勝手にクラスタ内のnodeにバラまいて分散処理してくれるworker」「一度に大量のtopicを並列readできるQueue Store」「ぼくがかんがえた最強のBaaS」「Cコンパイラ」「sparkのRDDよりさらに抽象化された分散プログラミングモデル」

英語のリーディング勉強方法についての振り返り

洋書の技術書や英語の論文を読むようになって3か月ぐらいになる。

とは言え、母語が日本語なので日本語の方が圧倒的にinputは早いため、読んでる本の言語比率は日本語:英語 = 8:2といったぐらいである。全然である。「洋書を読んでいる」なんて決して人前で言える量ではない。*1

ちなみに英語で読んでいる技術書は下記。パラパラとわかるところだけ読んでいるものもあれば最初から読んでいるものもある。もともと本は5~6冊をパラレルで読んでいくタイプなので洋書もそんな感じで読んでいる。

Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems

Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems

Distributed Computing: Principles, Algorithms, and Systems

Distributed Computing: Principles, Algorithms, and Systems

Big Data: Principles and Best Practices of Scalable Real-Time Data Systems

Big Data: Principles and Best Practices of Scalable Real-Time Data Systems

Java Concurrency In Practice

Java Concurrency In Practice

なぜ英語で読むのかと言えば、技術書に関しては翻訳がなかったり日本語版が絶版になっていたりするため。論文はそもそも基本的に英語しかない。

そのため今は英語のリーディング力を高めるために主に語彙を増やす勉強を中心にしている。

英語の教材としてTOEIC対策の単語帳を使っている。*2

TOEIC(R)TEST英単語スピードマスター NEW EDITION

TOEIC(R)TEST英単語スピードマスター NEW EDITION

手順としては以下のようにしている。大体これで40分ぐらいである。

  1. 1回の学習で50単語ぐらいを目標として覚える範囲を決める
  2. 例文を読んで、意味やニュアンス、類似語、例文を丸暗記するぐらい読み込む
  3. 解説が不十分だと思えば辞書を読んでニュアンスを覚える。
  4. 一通りやったところで赤シートを使って覚えているかどうかを確認する。覚えてなければその部分を集中してやる。
  5. 覚えた単語をざっくりノートに書きだして、それを眺めて意味やニュアンスがすぐに思いつくかどうかを再度確認。

こんな感じでやっているのだが、語彙力がなかなか伸びずに苦労している。 どのように苦労しているかと言えば大きく下記の2点である。

1. 覚えたかどうか分からない

それはともかく、この手の方法で単語を勉強してきたつもりだが、何というか本当に覚えたかどうか、つまり語彙力がついたのかどうか確認する手段があまりにも乏しい。確認できるのは英文を読んでいてその単語が出てきたときに「この単語見たことあるやつだ!」と思えた時か、commit logを書いていて「この場合はあの単語が使える!!!」というひらめきを感じた時ぐらいである。

それでいて2週間ぐらいだってから単語帳で同じ単語を眺めた時に「あれ、これなんだっけな…」となるケースも結構あり、覚えている率は肌感覚で1/4ぐらいであるのだが、果たして本当にそうなのかを定量的に計測する手段がない。これって単語テスト付きの単語帳でも使えばもっと正確に計測できるのだろうか?そういう単語帳買うべき??うーむ。。

2. しんどい

単語のみを覚える努力をしたことのある人ならわかってくれると思うが、使うか使わないか分からない単語を必死に覚えるのはなかなかにしんどい。

「なるほど!こういう言い回しがあるのか!」という発見はそれなりに楽しいにせよ、普段日本語で日常生活を送り日本語で仕事をしている人間にとってはやはり普段使いようがない知識である。どうしても仕事で疲れ切った頭にムチ打って図書館で必死に単語帳とにらめっこしていると純粋にしんどいと思うことも多い。どうして俺は生涯一回使うか使わないかってぐらいめったに見ない「embrace」みたいな単語の使い方を覚えているのか。他にやるべきことがあるのではないか、という気分にもなるが、とはいえ語彙力が貧弱であることは間違いないので頑張ってやるしかない。しかしどこか非効率だなという気分は拭えない。

こんなことを今年入ってからずっと続けてるので、かれこれ半年ぐらいはやってきた計算になる。しかし、いい加減この方法は間違っている気になってきた。

最近採用したやりかた

やり方を間違っている気になってきたので、単語帳作戦は一旦やめることにした。

代わりに、TOIEC Part5-7の問題集を解きまくって、分からない単語出てくる度に調べてメモって覚える方式に切り替えた。ネットで検索するとこっちの方が語彙力上げる手段としては効率が良いという意見もあるし、自分としてもまだ印象に残りやすいと感じている。しばらくはこの方法でやってみる。

また、技術書や論文に出てきた単語も覚えやすいということに気が付いた。 英文を読むとき、分からない単語を無視してとりあえず1センテンス読んで、それから分からない単語でどうしても類推できない単語だけ辞書を引くようにしたら「皆目分からない単語」だけをピンポイントだけで覚えられるようになってこれは効率が良いのではないかという気分になっている。「〇〇から遮断する」という動詞である「insulate」がアーキテクチャの解説でよく出てくるのだが*3、この単語は手持ちの単語帳の動詞コーナーには載ってなかった(索引がないので確定はできないが多分なかった)。そう考えるとやはり技術書に必要な英語は技術書を読みながら身に着けた方が早そうな気がする。

今のところリーディングさえできれば自分の用は事足りるので、もう何も考えずにいきなり英文を読み倒して分からない単語だけ辞書に当たる方が効率がよさそうである。

「英語学習にはまず単語帳が必要だ!」と思い込んでいたのは、大学受験時代の習慣というか思い込みみたいのが強かったからかなぁと思う。しかし、今や大学受験以上の語彙数力必要だとわかってる以上、異なるアプローチが必要なのは自明だよなぁと、自分の短絡さを反省する次第である。

*1:半々ぐらいになったら「趣味は洋書を読むことです」とか言っても差し支えないのではないだろうか。早く意識高い感じになりたい。

*2:ちなみにこの本、今amazonで調べたら結構辛辣なレビューがついていたのでTOIECの勉強にはあまり向いてないのかもしれない。。

*3:モジュール間の疎結合性を説明する文脈とかで