Runner in the High

技術のことをかくこころみ

社会人エンジニアに求められたもの

 去年の4月から社会人としてエンジニアをやっている。

 いつのまにやらもう1年が経とうとしているが、自分が仕事としてコードを書くエンジニアになって、これまでにどんなことを学んできたのか? ということを文章として書き残していなかった。タイミング的に「新卒」というラベルが剥がれそうな時期であるので、ここに書き残してくこととする。

 が、なかなか自分自身の成長を文章で書くのはなんとももどかしいものがある。自分は人を褒めることを躊躇したくないし、自分自身を「謙遜」*1と称して蔑みたくないという気持ちがあるが、それでも実際はなんとも言えない感情との板挟みになる。ということで、折衷して自分自身を客観的に「社会人エンジニア」のひとりとして捉えて、彼に何が求められてきたのか、というのを文章にしてみることとした。

言語やフレームワークにこだわらずプロダクト開発ができる

 例えば、新しく会社でプロダクトを作る、となった際に、技術要件として自分がこれまで触ったことのない言語やフレームワークが非常に有用であるということが分かるのであれば、その時点で自分がその言語/フレームワークを触ったことがなかったり、得意ではなかったとしても、そのタイミングで即座に業務で使える程度の技術をすぐに身に付ける柔軟性が期待される。

 もちろん、人には向き不向きがあり、それを個人差として捉えることもできる。けれども、業務でコードを書くというのは最終的にはビジネスを実現するための手段としての位置づけであるということは間違いない。ビジネスというのは、大抵の場合市場競争に巻き込まれるものであるし、そこへ個人差が常に加味されるかと言われると、難しいものがある。

 とは言うものの、ある程度コードを書いた経験があれば、少しづつ横展開できる基礎知識はついてくるものなのではないかと思う。自分は社会人になって初めてScalaとElmを業務で書き始めたが、全く持って手も足もでないということはなかった。なんでもかんでも「まずやってみる」というのが大事だ。

チーム開発を想定できる

 弊社が非常に設計を大事にする社風である、ということはいつぞやの記事でも書いた。設計を大事にする、という点が意味するのは、開発におけるスケーラビリティを大事にしているということだ。この「開発がスケーラブルである」という言葉が表現したいものは、チームがいくら大きくなっても、全体のアーキテクチャが破綻することのないようルールづくりができているということ。

 学生の頃はチームで開発をするなどということは一ミリも考えたことがなかった。それは、10社以上のインターンを経ても変わらなかった。どの会社に行っても、せいぜいインターンでやるのはハッカソン的な開発か、中/長期でもちょっとしたバグフィクス程度のものだった。結局、そのようなタスクをするだけに終始しているようでは、チームで効率よく開発をしていける仕組みづくりや、運用に乗せる際にどういうことを考慮するべきか、のような「業務」としてのものづくりを体験することはできないし、ちょっとコードを書くだけのアルバイトでしかない。

 一方で(ここからはポジショントークになるが)弊社のインターンは学生にもチームの存在前提で設計をさせる。これは夏季の短期インターンでもそうだ。もちろん時間は全く持って足りていないし、思考の負荷も高い。けれども、チームで大きなアプリケーションを作るともなれば、予め負荷の前借りを設計の段階でしておかなければ、あっという間に雪だるま式に負債が溜まり込んでしまう。負債をゼロにし続けることは無理だが、それでも設計指針をきっちりと練っていくことで、負債が溜まるスピードを遅くすることはできる。

大規模トラフィックを想定できる

 これは非常に抽象的な話であるが、例えば自分は社会人になって初めてPub/Subやタスクキューの使い所を学んだ。

 CSVファイルをアップロードして一万人のユーザーを管理画面から登録させる、といった要件があるとしたら、学生のころの自分は全てリクエスト・ハンドラの中でまるごと処理しようとしていたのではないかなと思う。このようなことをしてしまうのは「もしこの機能が〇〇万人に使われるようになったら、どこがボトルネックになるのかな?」というような思考が働いていないからだ。

 このタイプの思考を巡らせるためには、スケールするもの/しないものの知識がまず前提にあり(たとえばCPUバウンドな処理はスケールさせることができるが、IOは一貫性とのバランスをとる必要がある、など)その上で、RDBMSやNoSQLのような道具に関する知識との掛け算が必要になる。もちろん、学生でもGCPAWSなどのツールを大規模のデータと共に運用していれば、勘所は抑えられるのではないかと思う。けれども、自分は全くと言っていいほど経験も、知識もなかった。

特定の言語・フレームワークにロックインされない設計の思想と知識がある

 コードを書くということは、インターネットに転がっているQiitaの記事を読んだり、リファレンスを読んだりすれば、すぐにできることであるが「どのようなコードを書くか」という方向性がなければ、いきあたりばったりで意図の読めないコードを量産するだけになってしまう。

 大事なことは、大局的な方向性として「変化に強いアプリケーションを作る」*2のを前提にすることだ。まさにこれは言語・フレームワークがなんであろうと関係がない。この前提を踏まえた上で初めて「じゃあ今回はクリーン・アーキテクチャでいきましょう」というような決定を下すことができる。逆に言えば、いくら流行っているからと言ってクリーン・アーキテクチャを採用しても、それが方向性にそぐわなければ、単に編集するファイル数が多くて面倒くさいアーキテクチャを採用しただけじゃないですか、という判断になりかねない。

 実際には設計のみならず、実装にも同様のことが言える。たとえば、Scalaのコンパニオン・オブジェクトを使ったコンストラクタ隠蔽やElmのOpaque Type、Golangのパッケージシステムを使ったプライベート化などは、どれも責務分離を表現するカプセル化の実装知識だが、逆に言うとカプセル化がどのようなケースで重要なのか、ということを理解するためには大局的な設計の思想が必要になる。

 言語やフレームワークが変わっても、我々が「変化に強いアプリケーション」を作る必要がある、という前提はこれから変わっていく可能性があるとは言いづらい。その前提を実現するために、様々な「設計」の思想を理解し、知識として持っておくことは言語・フレームワークに落とし込んだ個々の実装表現とは切り離されているという点で独立して重要だと言える。

*1:謙遜されないと不愉快になる、という人がいるが、このような謙遜を強いる人間というのは相手に自分自身の自己肯定感の低さを押し付けているだけだ。自信を持って悪いことなど何もない。

*2:ビジネスというのは常に同じ形であり続けない。市場が変わればアプリケーションの仕様も変わるし、仮に仕様が変わらなかったとしても、そのアプリケーションを支えるツールが変わる可能性は大いにある。変化に耐えられない組織が市場を制することができないという事実は、多くの有名な日系企業のこれまでの歴史が証明している。