プログラムを書く仕事に移る

Ryohei Tsuda
22 min readJun 14, 2020
プログラムが動かないときの気持ち

会計の仕事を退職してプログラムを書き始めてだいたい半年くらい経って小さな会社で見習いプログラマの地位を手に入れたので、ここまでのまとめを書こうと思う。

前の仕事では経理をやったりこのようなシステムの Product Manager をやっていた。しかしプログラムは書けないので、要求を考えたり進捗を把握し社内外の利害関係者(社内のマイクロサービス、経理、内部監査、会計監査人など…)と合意形成するのが主な仕事だった。

プログラミングのレベルはちょっとした Slack の bot や抽象度の低い仕事を自動化する Google Apps Script を書いたりカルネージハートでロボットを動かせるくらいだった。あれは素晴らしいゲームで、もし私が石油王だったら大金を投じて続編を作りたいゲーム TOP 3 には入る。

そんなレベルでも辛うじて雇ってもらえたのは今の雇い主が知り合いだったからなので、転職の参考にはならないかもしれない。

はじめに

実際に今のプログラムを書く仕事に転職したのは2020年4月だったが、退職後の有給消化で2019年12月中旬から暇だったこともありその頃からプログラムの勉強をしていた。

より具体的にいうと、さくらインターネットで VPS を借りて Debian をインストールし、 Web サーバの設定を書き換えたり簡単な HTML/CSS を書いてそれを JavaScript で操作するみたいなことをやっていた。

また、「初めての JavaScript 第3版」というあまり初めての人向けじゃなさそうなぶ厚い本を一通りなぞって JavaScript の文法や機能について勉強した。

本をいくら読んでも現実の問題に向き合ってみると自分の知識や理解が十分でなかったことに気がつくので、本のどこに何が書かれているか分かったら現実の問題を解くことに時間を使うべき。困ったら本に戻ればよい。

1月 January

自分の手で生 HTML/CSS を書いて20世紀感の溢れる Web サイトを作ったり、生 CSS を Bootstrap で置き換えたり、 CSS を Sass で生成できるようにしたり、デプロイ用のスクリプトを書いたりした。

また、よく使いそうだと思ったので Node.js を使って SaaS の公開 API で取得したデータを集計・加工して Slack に投稿したり Google スプレッドシートに追記するプログラムを書いたりしていた。

まずは Postman で API の挙動を調べ、やるべきことを整理した上でプログラムを書き始めた。経理の仕事をしていたときに Python で同じようなプログラムを書いたことがあったので簡単にできそうだと思っていたが、 JavaScript の非同期プログラミングの概念がなかなか理解できず、データが入っていない変数を呼び出して undefined をたくさん出した。非同期の文法を会得するには Promise の本がとても役に立った。

JavaScript の文法や機能について勉強したいときは Mozilla Developer Network(MDN) 内で検索するのがおすすめ。単に機能の説明だけでなく、歴史の話もたくさん書かれている。私は「MDN に書いてありそうだな」と思ったら Google でなく MDN 内で検索するようにしている。

HTML/CSS/JavaScript の基本をやりながら分からないことを MDN で調べていたら1ヶ月くらい過ぎていた。

この頃から3月くらいまでは業務委託で幾つかの会社を手伝ってお小遣い稼ぎをしていた。

2月 February

ここで書いた通り、42 Tokyo の Piscine を受けた。途中で数えるのをやめたが移動込で毎日12時間くらい、4週間で300時間以上を費やした。

両手両足を縛られた状態で(※比喩です) C 言語を書き、1日1万回感謝の Segmentation Fault を出す日々だった。最初は Hello World を printf 関数で出力できるくらいのレベルだったので、自分が何もできないことを思い知らされて吐きそうだった。独学では味わえなかったドーンときてガシャーンとやられる感覚を味わった。

冷静に考えると1人ですら凄いノーベル賞を10人以上輩出するようなベル研究所の超エリート達が自分たちで OS を開発するために作った言語をコンピュータの初心者に勉強させるのおかしくないか?

「C はポインタの理解が難しい」という話を事前に聞いていたが、4週間 C を書いた後の私は(同じ話かもしれないが)メモリ管理というか、カジュアルに意図しないメモリ領域にアクセスしてしまうことを防ぐ方法を習得する方が 2³¹ - 1 倍くらい難しいと考えるようになった。ポインタは近くに座っていた情報系の優秀な大学生に丁寧に教えてもらったら割とすんなり理解できた。セグフォには最後の最後まで苦しめられたし、今も苦しんでいる。

この1ヶ月の成果として、システムコールを使って幾つかの標準 C ライブラリ関数や UNIX コマンドの再実装ができるようになった。OS やカーネルの仕組み(プロセス、ストリーム、ファイルシステムの関係など)の基礎についても学ぶことができた。この動画で説明されているような内容を少し簡単にしたやつをやってた気がする。

複数のコマンドを組み合わせて複雑な処理をするシェルスクリプトも自力で書けるようになった。例えばファイルの出力をパースして特定のフィールドから特定の条件を満たす値を sed や awk でごにょごにょしその結果を基に何か処理するみたいなやつだ。こういうパズルが何の役に立つのか分からないが、シェルスクリプトは一行書くだけでいろいろできて楽しい。

3月 March

42 Tokyo の Piscine に参加した後、データ構造やアルゴリズムについて能力不足を感じたので競技プログラミングの AtCoder を始めた。それ以来、毎週コンテストに参加している。しかし、Rating は大して上がってない…

本やチュートリアルを読みながら Node.js の Express という Web アプリケーションフレームワークで簡単な Web サイトをサーブできるようにしたり、Pug というテンプレートエンジンを使ってページを生成したりした。Router を使ってリクエスト先によって経路を切り替えたり、ミドルウェアを作って条件に応じて処理を分岐させたりできるようになった。また、Node.js のプロセスをターミナルから切り離しシグナルを送って起動/終了の操作をするシェルスクリプトを書いた。シェルスクリプトは少し書くだけでたくさんのことができて楽しい。

更に React という JavaScript ライブラリのチュートリアルを何回かやって、 DOM をより抽象的に扱う方法を学んだ。React は jQuery のなんかすごいやつだ。コンポーネントと呼ばれる仮想的な DOM を JSX と呼ばれる奇妙な XML っぽい文で記述し、それを使って画面を組み立てる。コンポーネントとして DOM を抽象化することで diff/patch 処理が速くなったり画面を構成するデータの流れを組み立てやすくなるというメリットがある。

React や類似のライブラリである VuejQuery 等のよく使われていたライブラリとは考え方が大きく違うので過去の知識を unlearning する必要があるらしいのだが、大して jQuery をやってなかった私はさほど混乱せずに進むことができた。React については何とか動く画面が作れるくらいのレベルなので、これで仕事ができるかと言われたらまだまだと言わざるを得ない。

3月末になって「これだけプログラミングやってこの程度しかできていないようだと、自分でプログラミングして作りたいものを自由に作れるようになる頃には死んでるのではないか?」と焦ってきた。

4月 April

今の会社に雇っていただいたものの、本をなぞった程度の知識では大して役に立てることが無かったので、掃除したり経理や労務の仕事や新型コロナ支援策の調査したりしながらプログラミングの勉強をしていた。定期的に社長がやってるビアバーのサーバーを分解洗浄していたので、初対面の人に「何エンジニアなんですか?」と聞かれた時は「サーバーエンジニアです」と答えていた。俺はサーバーには詳しいんだ。

お店用に POS の API で取得した情報を加工・集計したり Slack に投稿したり Google スプレッドシートに書き込んだりするプログラムを書いたので、 AWS Lambda にデプロイして CloudWatch Events で定期的に呼び出すようにした。

ここで、 Google スプレッドシートの API を呼ぶための認証情報は AWS Secrets Manager に保存していた。 Lambda の環境変数に AWS のアクセスキーを保存したら Secrets Manager に保存した認証情報を取得できるかと思ったが(後から考えるとセキュリティ意識の欠如が甚だしい)、 AWS 側に弾かれたので AWS よくできてるな〜すごいな〜〜と思った。その後 IAM について勉強して、ちゃんとした権限を設定した。複数人で触ることを考えると多分サービスアカウントとか使うべきだった。

デプロイを SAM でやろうと考えて YAML を書いてみたが丸1日使ってうまくいかなかったので zip でアップロードしたら一瞬で終わった。いろいろ反省はあったけど、自分が仕事で書いたプログラムがちゃんと働いているのを見るのはとても楽しい。

一つのちゃんと動くプログラムを完成させてレビューしてもらったことで、自分の理解が不十分な箇所や避けるべき慣習について学ぶことができた。レビューはプログラムの文法自体だけでなく問題解決の新しい視点や自分が見落としていた点も知ることができる。私の知らないことは無限にあるので、これからもレビューを大切にしていきたい。

会社が3月決算なので、経理の仕事として決算の処理をいろいろやった。会社では会計に freee を使っている。freee は会計処理というイベントを「取引」や「口座」という概念で抽象化しており、私のような経理経験者は逆にその概念に馴染むまで時間がかかるが、慣れるとそこそこ使いやすい。不満が無いといえば嘘になるが、社員数人レベルの零細企業にとっては月 2,000 円くらいでだいたいのことはできるのでありがたい。

また、会社のSlack の履歴を API で取得して加工し別の場所に投稿するスクリプトを書いたりした。公式の移行ツールを使えば多分すぐ終わるのだが、こういうちょっとしたツールを作ってレビューを受けることで「単に動くだけの」プログラムではない、仕事に役立つプログラムを書けるようになる…気がする。

会社の Web サイトが Next.js で作られたシンプルなページで、それにニュースを掲載する簡単な CMS を追加した。 Next.js は React で Web アプリを作るための便利な開発用のツールやコンポーネントが詰まったライブラリで、静的な HTML を生成(Static Site Generation: SSG)するので速いし安全らしい。設定ファイルでこのページは SSG してこのページは SSR(Server Side Rendering)する…とかも柔軟に対応できる。あと Link コンポーネントにマウスオーバーしたとき勝手に 裏側でリンク先を prefetch する便利機能があったりして動作がめっちゃ速い。使ってない機能は全く把握してないので、これから使い込んでいきたい。

コンテンツの管理は当初 JSON 形式で日付やタイトル、本文(HTML)を書いていくようにしたが、マークアップを書くのがとても面倒だったので特定のフォルダにマークダウン形式のファイルを置いていくように変更した。ついでに TypeScript を使い始めた。型の定義やらが面倒でゼロからだと結局 JavaScript で書いてしまうのだが、やりたいことは分かるし仕事で書くなら TypeScript だろうなという思いがあるのでやっていきたい。

Next.js はチュートリアルがとてもよくできているので私のような初心者でも安心。私がチュートリアルを終えたタイミングで丁度チュートリアルがリニューアルされて、一粒で2度おいしい思いができた。

ちなみに FACTFULNESS という有名な本の日本語訳をした上杉さんという方が Next.js の会社でソフトウェアエンジニアとして働いていて、プログラムやチュートリアルを書いているそうだ(現時点で最新 ver の 9.4 リリースにも登場する)。

休日など空いた時間では C で高校数学の問題を解いたりしていた。中高大入試の過去問を集めてプログラムで解く本とか同人誌とか出したら売れると思う。少なくとも私は買う。数学はちゃんと勉強したみがあるので、死ぬまで生きるのに困らない程度のお金を稼いだら勉強して大学にいきたい。切実にカネが欲しい。

5月 May

簡単なスキーマ設計をすることになったので DB について勉強した。DB については前の仕事で SQL ちょっと書いてたし簡単だろって思ったけど、よく考えたら SELECT しか書いてなかったしプロのエンジニアがちゃんと設計したスキーマやプロのエンジニアがメンテナンスしてくれている環境の上で踊っていただけだった。

MySQL を使い始めるにあたり、 Docker を使って開発環境を構築してみた。Docker は「コンテナ」と呼ばれる仮想環境を通じてアプリケーションを開発・実行するためのプラットフォームで、以下の3層からなる。

  1. 開発者が Docker の機能を呼び出すための CLI
  2. コンテナやイメージを管理する Daemon(1から操作される)
  3. 仮想環境をホストする Registry(2から呼び出される)

仕組みや VM との比較などはさくらのナレッジというサイトで分かりやすく説明されていたのでそれを読んだ。初めて使ったのだが、使ってみると非常に便利(環境の構築や破棄、共有が一瞬でできる!)だった。むしろ初心者こそ簡単にいろいろ試せる Docker を使うべきだと感じた。

その後、かんたんな Web アプリケーションを作り、セッションを使った簡単な認証を自分で書いてみた。また、 cookie の各ヘッダの仕様について MDN で勉強して自分でいろいろ試してみたり、 memcached (”めむきゃっしゅと”だと思ったが”めむきゃっしゅでぃー”らしい。d は daemon の d??)でセッションを永続化したりしてみた。

そしてレビューで脆弱性に関する指摘をいろいろされた。ということで、徳丸先生の YouTube を観たり情報処理推進機構(IPA) の Web サイトでセキュリティの基礎について勉強した。

徳丸先生の YouTube はよくある脆弱性だけでなく時事ネタ(最近あったお名前ドットコムっぽい話とか雇用調整助成金っぽい話とか)も取り上げており、時間も10分少々と短く私のようなセキュリティ素人でも論点が分かりやすいので万人におすすめだ。

また、 IPA の「安全なウェブサイトの作り方」はウェブサイトに起きがちな脆弱性や CWE(Common Weakness Enumeration)、有効な対策について一通り読めて無料なので、できるだけ多くの人、できれば私と同じ初心者の方に読んでほしい。

6月 June

引き続きセキュリティの勉強を兼ねて自分が書いたコードの脆弱性を攻撃してクラッカー気分を味わっていた。SQL インジェクションは直感的に重要性や対策が理解しやすく再現もしやすかったが、 CSRF とかは(やってみれば難しくないのだが)攻撃を考えるのが地味に面倒だった。

SQL インジェクションや CSRF 、 HTTP ヘッダインジェクション、セッションハイジャック等の手法についていろいろ勉強になったのだが、その中でも驚いたのは Twitter でよく見かける高木浩○さんという方が産総研の情報セキュリティ部門の研究員で私が読んでいた IPA の様々な資料を書いた方々の一人だったということだった。大変失礼な物言いだが、てっきり個人情報が大好きなインフルエンサー的な人だと思っていた。高木先生いつもありがとうございます。

セキュリティって無限にやることがあって、ものが動く仕組みをきちんと理解していないと脆弱性が生じる理由もその対策も理解できないので、仕事としてやってる人は凄いなと思う。ただそういう人たちも全てを見られる訳ではないので、普段プログラムを書いたり仕様を考える人がこういう基本的な知識を身に着けて自分にできることを全てやっておくべきなんだろうなと感じた。

あとは仕事で自分が紙に書いた Web アプリケーションの試作の画面を Next.js と styled-components で作ったりしていた。アプリ全体で状態を管理する仕組みは Next.js には無いので、 Redux とか Recoil とか React Hooks みたいなのを使って状態に応じて view を切り替えるみたいなのをやっていきたい。

休みの日はアニメ観たりクソみたいな Web アプリを考えたり(そのうち出したい)詰め将棋を解いたりしていた。3手詰とか5手詰とか短めの詰将棋はすぐ終わるので仕事中のいい気分転換にもなる。

現状

ここまで読んでいただいた方なら分かる通り、あまり目につくようなアウトプットはない。半年弱プログラム書いてても(途中で横道にそれたりもしたけど)特にこれといったアウトプットがないというのはちょっとショックだけど、これから頑張ろう。

歩みは遅いが、何とか時間をかければ最低限の動くものは作れるようになってきた。事前に想像していたよりもずっと大変だった。多分これからも大変だと思う。プログラミングは分からないことだらけで無限にやることがある…

とりあえずできるようになったことは下記の通り。

  • C で標準ライブラリ関数や UNIX コマンドを再実装する
  • 最低限の HTML / CSS / JavaScript
  • Node.js で簡単な Web アプリケーションを作る
  • React(というか Next.js)と CSS でダサい画面を作る
  • SQL や HTTP ヘッダの Injection, XSS, CSRFなどの脆弱性の理解と対策
  • 最低限の SQL(スキーマ定義や SELECT/UPDATE/INSERT/DELETE)

半年くらいでやろうと思ってできなかったことは下記の通り。

  • アルゴリズムとデータ構造をたくさん学ぶ(AtCoder やってるけど10回ちょっと参加して最高パフォ 715 なので 1000 くらい出したい)
  • 個人でなにかしら Web アプリを作って出す

あとはデザインのセンスが酷すぎるので画面をたくさん作って学んでいきたいところ。

困ったこと

私がこの半年くらいで特に辛かったと感じていることは以下の通り。

  • CSS の全て
  • JavaScript の非同期プログラミング
  • C の Segmentation Fault

CSS は非常に難しい。まず初見ではどこに何が効いてるのか全く分からないのが辛い。最初は「このフォームとボタンを縦に中央揃えにしたいな〜」とかいうのに2-3時間くらいかかったりする。これは自分で CSS をたくさん書いて Chrome DevTools とかで一つ一つ見ながら実戦で学んでいくしかないと思っている。世の中のプログラマはどうやって CSS を学んでるんだ。

非同期プログラミングについては、初心者が直感的に理解しづらい点が多いと思っている。JavaScript ではプログラムは上から読み込まれるが(必ずしも)上から結果が返ってくるわけではない。人間は文章を上から読んで上から理解することに慣れているので、ついコンピュータもその順番でやってくれると思ってしまう。これについては Promise の本に救われた。これに出会わなければ未だに理解できてなかったかもしれない。

C はちょっと複雑なことをやろうとすると無限に Segmentation Fault が出てくるのでその原因を探すのが辛い。ただコンパイラという仕組みは素晴らしくて、プログラムを実行する前に間違っている箇所を指摘してくれるのでそこは助かっている。

プログラミング入門について

プログラミングを始めるときは大抵わからないことだらけなので、公式ドキュメントとかから持ってきた「動くコード」をちょっとずつ変更しながら動く状態を保ちつつ新しい概念を習得していくのがよい。

動かない状態を何とかしようとして深みにハマっていくことがよくあるので、「動かなくなったら動く状態まで巻き戻す」と決めてからコードを書き換えて自分の理解を確認しつつ進んでいくと、どこで詰まったかが分かりやすくなるので人にも質問しやすくなる。一番使った git のコマンドは commit でも add でもなく stash。

こういったやり直しの容易さやコンピュータが答えを教えてくれるところがプログラミングの良いところだ。後はやはり自分で何かしら動かしながら学ぶのがよい。本やドキュメントを読むだけでは自分が理解できていないことを認識することはできない。

キャリア

Mark Andreessen がその昔 “Software Is Eating the World” と言ったが、事実としてこの10年20年で最も経済的な付加価値の高いビジネスはソフトウェアだったし、これから暫くもそうだと思う。

そういう世界では私のように、何かしら別分野の経験を持ってプログラマのキャリアに移る(もしくはその逆)という経歴の人が少しずつ増えていくだろうという実感がある。

経済的により豊かになるためには社会全体で人やお金がより付加価値の高い会社や事業に移っていくようにしなければならないし、ソフトウェアで解決されることを待っている問題にはある程度その領域の経験や専門性が必要とされるものがたくさんあるからだ。

他の仕事をしていてプログラマに興味がある人(もしくはその逆)はまずやってみたらいいんじゃないかな。向いてなかったら戻ればいいし。

プログラミングスクールについて

プログラミングを始めるときに TECH::CAMP みたいなスクールに行くか迷っている人は多いと思っている。

私は 42 Tokyo の入試を300時間強にわたって受けたが、それなりに満足している。何より無料だし、同程度のレベルの人がたくさんいて詰まったところを相談したり課題を一緒にすすめることができ、学習効率がとても高かった。腕試し的な感じで来ている情報系の優秀な学生も多く、皆で助け合って乗り越えよう的な空気がよかった。実は新型コロナウィルス感染拡大の影響で本番はまだ始まってないのだが、入試だけでも勉強になった。

結局は学校に何を求めるかで、それが明確であればあるほど学校での学習効果は高いと思う。ただ、個人的な意見として「スクールで教えるのが上手い人は講師やるよりプログラマとして普通に働いた方が稼げるのでは…」という懸念があり、良い講師を探すのは大変だと思うので、興味がある方は知り合い経由で良い講師のいる学校を探すのが良さそう。

最近はフィヨルドブートキャンプというところが良いらしいという評判を至るところで聞く。

JavaScript と私

この半年は、主に JavaScript (TypeScrypt)を書いていた。JavaScript でプログラミングに入門するのは大きなメリットがある。

最大のメリットは活躍の場が多いこと。ブラウザでの操作に応じて画面を書き換えたりサーバでリクエストを処理してレスポンスを返したり、 人間が Web アプリを作りたいと考えたとき必要となるプログラムの大部分は JavaScript で書ける。そして利用者が多いので、便利な実行環境や開発者ツール、ライブラリなどが作られていく。

欠点としては(これは大抵のプログラミング言語に通じそうだが)適当に書いても動いてしまうので、「ちゃんとした人」にレビューして貰える環境で書かないと分かりづらいプログラムを書いてしまう癖がつきそうという特徴もある。実際、書く人や時代によって大きく文法が違うので、コピペばかりしていると訳のわからないプログラムになる。

また、積み重ねた歴史の中で現れた問題を解決するために様々な仕組みが導入されているのだが(例えば非同期処理でコールバックが多重になることを防ぐための Promise やそれを発展させた async/await など)、私のような初心者が文法だけなぞると歴史的背景が分からないので「これは何をしてるんだ?」と混乱しやすいと思う。

私は非同期プログラミング(というか Promise)の使い方がよく分からず、ここ半年間で一番苦労したポイントと言ってもいい。 Promise について勉強する上で、下記のページが非常に役に立った。

https://azu.github.io/promises-book

この「Promise の本」を無料で読むのが申し訳なく感じたので著者に Gumroad で $4.5 を送金した。自分のプログラムでお金が稼げるようになったら僭越ながら GitHub Sponsor をやっていきたい。

ちなみに同一の著者に依る JS Primer という Web サイトもあって、これを読めば JavaScript に入門したい人が ECMAScript 2015 以降をベースにして一から JavaScript を学べる。今年の4月には書籍も出版されたそうだ。神なのか?

TypeScript は始めたばかりなのであまりよく分かってないのだが、やりたいことは共感できるのでやっていきたい。

これから

1ヶ月単位くらいでやったことをアウトプットしていきたい。当面の目標は会社のサービスに「プログラマとして」貢献することだ。

拾ってもらった恩もあるし、仕事としてプログラムを書く以上はプログラムでお金を稼いで会社に貢献したいという気持ちがある。

私はとても小さな会社で働いていて製品やサービスもまだ無いし言えることは無いのだが、自分が働いている分野に興味がある人とは仲良くしていきたいので、将来的にはプログラムだけでなく発信も頑張っていきたい。

あと個人で簡単な Web アプリ作って出したい。自分の責任においてメンテナンスし続けることで学べる分野がたくさんありそうなので。

--

--