エンジニアHubPowered by エン転職

若手Webエンジニアのための情報メディア

ある文系プログラマがテックリードを任されるまでに学んだこと ── 最前線で生き延びる4つの戦略

コンピュータサイエンスの専門教育を受けず、20代半ばで本格的なプログラミングを始めた文系エンジニアが、いかに学び、考え、生き延びてきたのかを伝えます。

Skydiver freedom concept vintage color www.shutterstock.com

こんにちは。白山@fushiroyamaと申します。現在は新聞社のデジタル事業部署で、モバイルアプリ開発のテックリードをしています。

自分のエンジニア人生を振り返ると、これまでの道のりは決して平坦ではありませんでした。コンピュータサイエンスの専門教育を受けず、本格的にプログラミングを始めた年齢も23、4歳と決して早くありません。

そんな自分が、いかにして開発チームのリーダーを任せてもらえるまでになったか? 考えてみると、次の4つの戦略で生き延びてきたようです。

  1. 自分だけの居場所を見つける
  2. 必要な知識を効率的に取捨選択する
  3. 他のエンジニアに差をつける
  4. モチベーションを下げない工夫とマインドセット

この戦略が、これからプログラマになりたい方や若手プログラマのみなさんに、少しでも何かを示唆するものになれば幸いです。

戦略1. 自分だけの居場所を見つける

僕のエンジニアとしての原点は、京都の小さなスタートアップです。当時、大学で学ぶ意味を見失って無為に過ごしていた僕は、友人であり恩人である先輩に誘われ、大学を中退してアルバイトとして参加。その後すぐに社員となって5年間働きました。

2000年代前半のWebの世界はおおらかで牧歌的であり、Ajaxも存在せず、基本的にはすべてがサーバサイドレンダリング。「動的なWebシステム」といえば、Perlで書かれたCGIという時代でした。

もちろんその当時からきちんと設計されたWebシステムも存在していたのでしょうが、僕が目にするようなソースコードはMVCを意識したものではなく、ビジネスロジックとともにViewのHTMLタグが直接コントローラの中に記述されたものばかり。データの永続化は、ロックファイルで排他処理をしながらファイルに追記しているものがほとんどでした。時間計算量なんて考えたこともありません。嗚呼、古き良き時代。

僕も学生時代は、趣味で簡単な掲示板をPerlで書いて自分のWebサイトで公開していたこともあり、「プログラマとしてなんとかやっていけるだろう」とたかをくくっていたのです。

しかし、入社後、プロダクトのソースコードを見て驚愕。まったく読めません。

その会社はもともと、国立大学の研究チームを中心とした産学官共同プロジェクトに端を発しており、創業者や社員はみんな信じられないほど優秀な人ばかり。システムは、WindowsでもLinuxでも1ソースで動くGUIアプリケーションとして、Java Swingで記述されたものでした。

多数の優秀な大学生や企業のプログラマによって、各コンポーネントは適切な単位で膨大な量のクラスに分割され、プロセス間通信や最適化のためのネイティブコードも複雑に関係し、とても当時の自分の手に負える代物ではありません。僕は即座に悟りました。

「このままではクビになる。」

このとき考えた生存戦略は

「そうだ。誰もやらない仕事をやろう。そうすれば誰も僕をクビにできないだろう。」

というシンプルなものでした。社内を見回すと、アプリケーションプログラマは充実している反面、サーバの設置や管理・メンテナンスを担当するインフラエンジニアが致命的に不足していました。サーバ室に入ると、社長が経営の片手間に、ひとりでルータの設定をしています。

「インフラで何か手伝えることはありませんか?」

僕がそう聞くと、社長は喜んですぐに仕事をいくつも割り振ってくれました。これが、僕の技術者としての出発点です。

趣味があなたの力になる

インフラエンジニアとして働くようになってから僕が始めたのが、自宅サーバの構築です。クラウド全盛の現在ではもはや死語かもしれませんが、自宅サーバとは、その名の通り自宅のネットワークインフラでサーバを運用することです。

お古のノートPCを引っ張り出し、会社と同じディストリビューションのLinuxをインストールして、NAPTとDDNSを設定してインターネット上にWebサーバを公開できたときには感動しました。2006年ごろ、まだ「クラウド」という言葉も日本であまり馴染みがなく、仮想化という技術が流行する前夜です。

その頃は、趣味と実益を兼ねて自宅サーバを立てる人が一定数いました。自分も業務の足しになればと軽い気持ちで始めた自宅サーバでしたが、運用を通じて、信じられないほどの知識を上積みできました。

例えば、XenやKVMといった仮想化ハイパーバイザが流行の兆しを見せはじめたときには、いち早く自宅サーバで試し、グローバルIPアドレスを自宅に8本(29ビットマスク)引いてインスタンスに割り当て、プログラマ仲間に有料で貸し出したりしていました*1

会社の役員にこれを話したところ非常に興味を持たれ、最終的に会社の業務に投入することになりました。単なる趣味で始めたものが、新たな価値に結実したのです。これは、どれだけ真面目に業務をこなしていても身につけられなかった知識です。

その後のエンジニア人生でも、趣味で始めたものが大きな力となり、他者との違いを生むという経験が幾度となくありました。みなさんも、何か始めてみてはいかがでしょう?

戦略2. 必要な知識を効率的に取捨選択する

晴れてインフラエンジニアとしての居場所を得たころの話に戻ります。当時は、実のところネットワークやサーバ管理の知識が皆無でした。学校でもプライベートでも、サーバ管理やインフラ構築をした経験がなかったのです。

ネットワークに詳しくなるべく「OSI参照モデル」について調べてみるもまったくピンとこないし、サーバに使われているLinuxのディストリビューションが何なのかすらよくわかりません。

このような状況で「とりあえず前に進む」ために参考にしたのが、パラシュート勉強法です。

パラシュート勉強法とは

パラシュート勉強法とは、経済学者の野口悠紀雄氏が著書『「超」勉強法』で紹介した、「必要になったものを必要なだけ学ぶ」という学習の手法です。

例えば数学のように、ある単元がその前の単元の知識を前提とする積み上げ型の教科を学習する場合、「今の単元がわからないので『数I・A』からやり直そう!」と考えがちです。しかし、十中八九、わずかに進めるだけで、目的に到達する前に力尽きてしまいます。

そうではなく、バラシュートでまっすぐに目的地に降りるように目標を定め、目的地に至るまで、必要な最低限の知識だけを補いながら進んでいくのがこの勉強法です。

僕の場合、まず会社の業務として必要とされるインフラの知識を書き出しました。

  1. サーバに特定のLinuxディストリビューションをインストールし、ファイアウォールなどのセキュリティ設定をする
  2. アプリケーションを実行するためのミドルウェアをインストールし、デプロイ環境を整える
  3. 必要なサーバには会社で所有するグローバルIPアドレスを割り当て、インターネットから直接到達する必要のないホストはローカルネットワークに閉じ込める

すると、覚えなければならないことは実のところ以下の3項目に集約されることがわかりました。

  1. OSは、業務で使うディストリビューションの使い方、セットアップ方法に絞って学習する
  2. コマンドも、業務に必要な最低限のものだけを覚える(必要になったらその都度学習する)
  3. ネットワークに関しては、LANとそのルーティングの知識を必要とする程度だったので、L3スイッチを設定できる最低限のルーティング知識に絞って学習する

この項目に従ってできるだけ寄り道をせず、ゴールに向かって進んでいくよう心がけました。

重要なのは「実際にLinuxを触る前からコマンド一覧をひたすら眺める」とか、「単純なルーティングも設定したことがないのに『マスタリングTCP/IP』を読みはじめる」 というようなことを一切しないことです。

必要なピースを拾い集めながら、知識のマスを少しずつ埋めていきます。上記でカッコ書きしたようなことは、勉強の初期段階よりも、学習が進んでから全体の横串を通すときに行ったほうが効果的です。

Webエンジニアに転身してもパラシュート的に学習

インフラエンジニアとしての業務が順調に進むようになると、空き時間でWeb開発をするようになりました。

このときもパラシュート勉強法は大いに役に立ちました。Webエンジニアとしては、次の2点のみに絞って学習しています。

  1. HTTPの基本原理
  2. 業務で必要な技術スタックとその周辺知識

HTTPはWebの根幹技術であるため、1.に関しては言うまでもありません。2017年現在においても、Webアプリケーションは当然のこと、iOS/Androidなどのネイティブアプリケーションでも、サーバとの通信の主たるプロトコルはHTTPという状況が続いています。

  • ステートレスなプロトコルであるHTTPがどのような方法でユーザを特定したり、一連のトランザクションを実現するのか
  • ヘッダとは何で、どのようなものか
  • リクエストとレスポンスはどのような形式をしているのか

Webエンジニアである以上、こういった知識は必須です。

2.に関しては、かなり割り切って学習しました。

この世には、Webアプリケーションに利用できるプログラミング言語は数多く存在し、そのアプリケーションフレームワークや、バックエンドで利用するRDBMSもいくつも存在します。これらすべてを覚えようとするのは意味がないので、会社やプロジェクトで利用するものだけに集中しました。

幸い、Web技術には見た目や思想や新旧の違いこそあれ、その根底にある目的は、言ってみれば「HTTPリクエストを効率よく返すこと」で共通しています。

Webアプリケーションフレームワークのスタックを何かひとつ理解していれば、どんなWebサーバやアプリケーションフレームワーク、キャッシュサーバ、DBサーバを使おうと、大きな違いはありません。

新しい知識には遅延評価的勉強法で対応する

ここ数年のWeb技術の発展と、関連する技術スタックの隆盛は目覚ましく、毎年覚えきれないほどの新しい言語・概念・フレームワーク・ライブラリが誕生し、目も回らんばかりです。

その渦中にあって投資すべきものを見定めるのは困難を極めますが、我々の限られた時間を効率的に使うためにも、それを見抜く目を是非とも養いたいものです。

自分はその目を持っているわけではないのですが、知識を取捨選択する際にある程度有効に機能している「遅延評価的勉強法」を紹介したいと思います。

遅延評価的勉強法とは、天野仁史@amachangさんや小飼弾@dankogaiさんがブログで言及していた学習方法です。

パラシュート勉強法と共通していますが、自分の理解では次の2つがポイントです。

  • 必要になるまでやらないこと
  • 必要になったらやりきること

例えば、新しい本を開いて何かを学ぼうとするときに、前から順番に最後のページまで読んでいくのはなかなか骨が折れますし、つまらない! 僕の場合は全体を見渡しながら、欲しい情報をかいつまんで

  1. 即座に利用するにはどこを読めばいいか
  2. 面白そうな部分はどこか

を探し、美味しいところからつまみ食いしていくスタイルを採っています。

薄くでも全体的に概念を知っておきたい場合は、まったく知らない状態で本なりまとめサイトなりをサラッと眺めて「バズワードとして意味や用途、利点をふわっと理解している」ぐらいに留めておき、必要になるまではその状態でやり過ごします。

この勉強法で重要なのは、いざ必要になったときには、全力で取り組むことです。全力で取り組む対象としては、次のようなものが挙げられます。

  • デファクトスタンダードになった技術
  • 会社のプロジェクトとして正式に採用されることになった技術やフレームワーク

このとき僕が気を付けていることが、dankogaiさんのエントリにもあるように、原典にあたることです。僕は必ず、英語であっても公式サイトで最新の一次情報を参照するよう心がけています。

本屋で立ち読みしたりQiitaや技術ブログで見かけたりした情報は、公開された瞬間から時々刻々と鮮度が落ちていきます。楽をするつもりでまとめサイトを参照したのに、情報が古くなっていてビルドすら通らず、かえって時間を無駄にした経験をお持ちの方もいらっしゃるのではないでしょうか?

こういった二次的な情報源は、短時間でまとまった情報が得られる点で大いに価値がありますが、それは前述の「ふわっとした理解」の助け程度に留めておき、いざ全力で取り組む際には公式サイトを参照することが、遠回りに見えてかえって近道であることがよくあります。

参考記事:ハッカーと遅延評価勉強法 - Slow Dance

真似て、盗む

もうひとつ、僕がプログラマとして成長する上で必要だったのが、人のコードをひたすら模倣して、テクニックを盗んでいくことです。

スティーブ・ジョブズはインタビューで、パブロ・ピカソの言葉を引用しています。

ピカソは言った「すぐれた芸術家は真似る、偉大な芸術家は盗む」。私たちはいつも偉大なアイデアを臆面もなく盗んできた。
(Picasso … said good artists copy great artists steal. And we have always been shameless about stealing great ideas …)

(1996年の番組「ナードの勝利(Triumph of the Nerds)」での発言、日本語訳はWikiquote

どんな巨匠も、いきなり自分だけのスタイルを確立したわけではなく、最初は他人の絵を真似して、描いて描いて描きまくったはずです。

プログラミングも同じです。僕も、初めて見る言語やパラダイムに触れたときは、とりあえず手を動かして、写経してみます。何回も書いて書いて書きまくっているうちに、手法やデザインパターンを吸収し、その場に応じて適切な形に書き換えるといった応用ができるようになります。

戦略3. 他のエンジニアに差をつける

ここまでは僕のエンジニア人生を振り返りながら、自分なりの生存戦略を紹介してきました。個人的には、必要なことを必要な場面で最低限こなしていれば、エンジニアとして生き残ることに何の不安も感じていません。

ここで言う「必要なことを最低限」とは、プログラマならば

  1. 意味のある単位でクラス、関数やメソッドの責務を分け、そのユニットテストを書く
  2. 自分の利用する技術スタックの最低限の知識をきちんと把握する

という程度のことです。総じて、技術に対して真摯でありさえすれば、おのずと達成できるようなことです。

それでは、プログラマとはそれだけの存在なのでしょうか。ただ漫然と、与えられたチケットを消化していればいいのでしょうか。

いいえ。僕の信じる限り、プログラマとは、いまこの世にない価値を生み出せる存在であるはずです。

ここからは、いまここにない価値を届けられるプログラマになるために、僕が必要だと考えていることを紹介します。ちょっとエモい内容になりますが、どうぞお付き合いください。

この便利なライブラリは誰が作ったのか

先ほども触れましたが、現在のWeb業界でプログラマとして禄を食み続けること自体は、さほど難しくないかもしれません。

例えば、ディレクターから「ボタンを押したら図形が大きさを変えながら回転するアニメーション」の開発を頼まれたとします。

実装方法がすぐに思いつかなくても、機能の概要をキーワードに、言語やフレームワークとあわせて検索すれば、たちまち目的を達成できそうなライブラリがいくつか見つかるでしょう。あとはこれを組み合わせるだけ。簡単!

では、このライブラリは誰が作ったのでしょう? 言うまでもなく、自分以外のどこかのプログラマが作ったのです。もしこのライブラリが存在しなければ、今回のタスクを完遂できたでしょうか……?

依頼されたアニメーションを実行するには、平面上の図形の回転座標を求めるために行列の計算や三角関数の知識が必要です。また、GUIアプリケーションの低レイヤな描画の仕組みへの理解が不可欠です。

これは一例にすぎませんが、Web、ひいてはITの世界で、いまここにない価値を生み出したければ、数学やコンピュータサイエンスに対する理解が必要不可欠なのです。

コンピュータサイエンスの基礎、アルゴリズム、データ構造を知る

コンピュータは、もともと計算機と呼ばれていました。計算機の仕事は、その名の通り数値計算を効率的に行うことです。我々が普段行っているプログラミングは、コンピュータに計算をさせるための指示書を書いている、とも言えます。

プログラムを書いていると、複数の値をリストにつっこんでループ処理したり、データの対応表をディクショナリ(連想配列、ハッシュテーブル)に保持して、後から参照したりするでしょう。

普通にWebエンジニアとして生活している限り、例えばリスト状のデータ構造が、配列をもとに実装されているのか、連結リストをもとに実装されているのか、はたまたリングバッファで実装されているのかを意識するようなケースは、それほど多くありません。典型的なWebシステムの場合、RDBMSからデータを読み出した時点でたかだか1万件程度に絞り込まれているように設計するのが当たり前だからです。

同様に、ディクショナリの使い方は知っていても、それがどのように実装されているのか(もっと言うと、どれくらいの計算量で実現されているのか)を普段まったく考えないという方も少なくないかもしれません。

ただ、その実装方法は知らなくとも、「リストはこういう場合に使い、ディクショナリはこういう場合に使う」ということは、ほとんどのプログラマが知っているはずです。

こういったリストやディクショナリのように、データの集まりをコンピュータで効率的に扱うための系統立てた分類を「データ構造」と呼び、それがどのような設計で実現するかという手順を定型化したものを「アルゴリズム」と呼びます。

アルゴリズムとデータ構造は、コンピュータサイエンスのもっとも重要な概念のひとつであり、どういったアルゴリズムとデータ構造を用いれば、どのくらいの速さで目的のデータを見つけられるか、ということに直接的な影響を及ぼします。「効率的な解法は現在まだないが、解決できれば何百万人をも幸せにできる問題」に取り組む場合、アルゴリズムと向き合うことは避けられません。

アルゴリズムは、それが必要になってから学べばいいという類のものではありません。なぜなら、アルゴリズムを知らなければ、必要になる場面を思いつくことすら困難だからです。さまざまなアルゴリズムを知っていて、はじめて「この場面ではアレが使えるかもしれない」と選べるのです。

計算量(computational complexity)
プログラムの計算量は、一般的に、ステップ数を多項式で表現し、最大次数以外の項と係数を除いて表します。
参考:[初心者向け] プログラムの計算量を求める方法 - Qiita

例えば、日本語入力システムの変換候補を実装するとします。

このとき、読みと変換候補の対応表を、単純なハッシュテーブルで持っていたとします。ハッシュテーブルは、完全一致の検索は非常に高速であるものの、変換候補のような前方一致には非効率です。

ここで、トライ木(プレフィックス木)というデータ構造を知っていれば、共通のプレフィックスを持つ単語を非常に高速かつ効率的に検索できます。

これが、プログラマの生産性が100倍にも1,000倍にも違ってくる理由です。そして、解決できなければゼロでしかありません。

トライ木(Wikimedia Commonsより)

プログラミングの新しいパラダイムに触れる

できるだけ多様なプログラミングパラダイムに触れることも、プログラマとして視野を広げる手助けになります。

例えば、僕は自分の視野を広げるために、関数型のプログラミング言語を学ぼうと思い立ち、業務時間の後に同僚と週1でSICPの読書会をしていました。

SICP(Structure and Interpretation of Computer Programs)
マサチューセッツ工科大学(MIT)の講義で使われていたコンピュータサイエンスの教科書の古典。1985年にMIT Pressから出版され、第二版(1996年)が『計算機プログラムの構造と解釈』のタイトルで邦訳されている。
参考:SICP Web Site for the Japanese Edition

SICPは、Lisp方言の関数型言語であるSchemeを題材にとり、再帰(スタックを消費する再帰と最適化可能な末尾再帰)、データ構造や高階関数、ストリーム、インタープリタの実装などなど、計算機科学の真髄が詰まったものすごい本でした。

僕はこれまで、JavaやPerl、Ruby、JavaScriptといった、C言語の子孫というべきプログラミング言語にしか触れたことがなかったので、forwhileもない、「ループ処理したければ再帰を書くしかない」という馴染みのない言語仕様や、S式と呼ばれる括弧だらけの連結リスト、それに対する関数適用という記述スタイルは大きなカルチャーショックでした。

別の曜日には、『すごいHaskellたのしく学ぼう!』の読書会を通じて純粋関数型言語Haskellの勉強をしました。

これまた、副作用のないプログラミングスタイルや高階関数(特にカリー化や関数合成)、Functorという抽象概念、モナド(MaybeやEitherなど)、純粋関数型言語におけるI/Oのような副作用の扱いなど、いままで使ってきた概念とは異なるパラダイムに触れることができました。

これらはいずれも、純粋に興味や教養として、プログラミングを楽しむために始めたもので、日々の業務とは一見無関係に見えますが、業務でも役立ついろいろなことが身につきました。

というのも、近年、関数型プログラミング言語が持つさまざまな良い要素に多くの人が気付き、関数型以外の、手続き型やオブジェクト指向のプログラミング言語でも、そのパラダイムを積極的に取り入れる傾向が拡大しています。

多くの近代的なプログラミング言語が、高階関数やラムダ式をサポートしていますし、map/filter関数のように、リストと関数(ラムダ式)を引数にとり、各要素に適用しながら次のリストを得るといった機能を提供しています。

また、近年大きな盛り上がりを見せているReactiveXのような、いわゆるリアクティブプログラミングの機能を提供するライブラリ群では、非同期処理やユーザのタッチイベント、単純なリストすらひとつづきのデータの流れ(ストリーム)とみなします。そこにデータが流れてきたときの操作をあらかじめ関数として登録しておいて、それを繋げながら変更を伝播させていく、というプログラミングパラダイムが採用されています。

こういった馴染みの薄い考え方に出会った際にも、関数型プログラミングを学んでいたことが理解の助けになりました。

参考書籍:Scala関数型デザイン&プログラミング ―Scalazコントリビューターによる関数型徹底ガイド

Linux/UNIXのアーキテクチャを理解する

LinuxやUNIXに関する一歩踏み込んだ学習も、問題を解決する際に大いに役立ちました。

ここでいう「一歩踏み込んだ」とは、単にターミナル越しにコマンドラインでLinux/UNIXを利用するのみならず、それがどのようなアーキテクチャで作られているのか、よく使うあのコマンドは裏でどのようなシステムコールを発行しているのか、といった部分を含めた理解です。

僕は、隔週で『詳解UNIXプログラミング』の輪読会を行い、少しずつ学んでいきました。

この書籍では、UNIXでファイルやディレクトリがどのように表現され、どのようにリンクされるか、inodeとは何かといった話題に始まり、標準入出力、プロセスのforkと環境変数、シグナル、スレッドとミューテックス、プロセス間通信など、普段コマンドラインで使っているだけでは表面的にしか触れないようなトピックに対して、実際にC言語でシステムコールを呼び出すサンプルコードを書きながら、学ぶことができます。

この本で得た知識も役立っています。以前、とあるLinuxソフトウェアのクラッシュに遭遇し、原因究明に苦慮していました。ふと思い立ってstraceコマンドを使い、システムコールを順に出力してつぶさに調べてみると、逆引きの名前解決をキャッシュするテーブルが壊れていることがわかり、問題を解決できたのです。

総合力で勝負する

冒頭で述べたように、僕はコンピュータサイエンスの専門教育を受けていません。数学も苦手で、図形の回転などで利用するような行列の一次変換(およびその前提知識となる三角関数やベクトルなど)を、社会人になってからパラシュート的に、かいつまんで再学習した程度です。

ここに至って痛感するのが、大学でちゃんと学んできた人には太刀打ちできないという点です。

特に、コンピュータサイエンスがカリキュラムに含まれている学科を出ている人と話していると、僕がここに列挙したような内容は、ほとんど(もっと遥かに深いレベルで)大学で学んでおり、その専門性を身につけた上で社会に出ている方がほとんどです。彼らは、スタート地点からもう応用が効きます。

この傾向は、同様に深い数学と計算機科学の理論に根ざした分野である「機械学習」の大流行で、ますます加速するのではないかと感じています。もはや、僕が余暇で身につけた教養で追えるレベルを超えています。

だからといって、絶望することはありません。エンジニアの生存戦略という観点で捉えた場合、重要なポイントは 「相手が何を求め、自分は何を提供できるか」だと思います。

ある分野で1位になろうと思うと、途端に苦しくなります。そうではなく、いま自分が持っているものに一番価値を感じてくれる相手を探そう、ということです。

例えば僕には、エンジニアとして次のような持ち玉があります。

  1. Androidアプリ開発がそれなりに得意
  2. インフラの経験がある
  3. サーバサイド開発も並行して長くやってきた

おそらく、どれひとつを取っても、その分野の第一人者には遠く及びません。しかし「アプリ開発ができて、サーバサイド開発も手伝ってくれて、簡単なデプロイフローも整備してほしい」という会社には、一番欲しい人材と思ってもらえる可能性があります(もうひとつ、僕は英語が比較的得意なので、なんとかこれを活かしたいです!)

このように、エンジニアの価値は単純に数値で定量化できるものではなく、多分にコンテクスチュアルな性質を備えています。暇なときにでも、是非自分の持っている強みを書き出してみてください! そして自分のなりたい方向に向かっているか、自問してみてください。

戦略4. モチベーションを下げない工夫とマインドセット

むしろ牛後となるも鶏口となるなかれ

中国の故事に「鶏口となるも牛後となるなかれ」という言葉があります。「大きな集団の中で尻にいて使われるよりも、小さな集団であっても長となるほうがよい」という意味です*2

僕は、個人的にこれと逆の意見を持っています。未熟なプログラマは、むしろ牛後となるも鶏口となるなかれです。

エンジニアとして生きていると、同僚に刺激を受けて奮起することは毎日のようにあります。いまでも思い出すのが、元同僚と食事をしているときに「そういえば白山さん、Android技術者でしたよね。Dalvik(Android 5.0未満で採用されていた仮想マシン)のGC(ガベージコレクション)ってどうなってるんですか?」と突然聞かれたのです。

DalvikはJavaバイトコードをモバイル環境に最適化したDEX(Dalvik Executable)を実行するため、インタプリタの仕組みもGCの仕組みも標準のJVMとは異なります。当時の自分は、標準のJVMのガベージコレクションの仕組みすらよく知りませんでした。

呆然としていると、Android技術者でもなんでもない別の同僚が僕に代わって滔々と説明してくれました。このときは非常に悔しかったですし、大きな刺激になりました。もっと勉強しなければと強く感じたのです。

また、当時会社で利用していたmemcachedサーバのクラスタで、一部サーバをメンテナンス等でスケールイン/スケールアウトした際に 「どうしてキャッシュサーバでこんなことが可能なんですか? 全サーバが全キャッシュを複製してるんですか?」 と質問したところ、会社の人に「コンシステントハッシュ法」というアルゴリズムを教えてもらって感動したのを覚えています。

これはキャッシュを各サーバに分散させるため、サーバ台数でモジュロ演算して割り振る方法ではスケールイン/スケールアウトしたときにキャッシュミスが発生しまくる問題を、キーのハッシュ値を取ることで解決したアルゴリズムです。少ない台数で効率よくキャッシュ分散できるだけでなく、サーバ削減時にも追加時にも極力キャッシュミスを起こさずに均等にキャッシュを再分配できます。

参考記事:スマートな分散で快適キャッシュライフ - mixi engineer blog

これを聞いたときは、本当に目からウロコでした。まさに「いまここにない価値」です。技術者とはこうでなくてはと感銘を受けました。

周りに優れた技術者がたくさんいると、毎日が新しい発見です。周りの技術者が自分を上のレベルに引っ張り上げてくれます。牛後として揉まれ、気付いたら鶏口になっていたという生き方も悪くありませんよ。

誰からも学ぶ姿勢を忘れない

また中国の故事からの引用ですが、論語に次のような一節があります。

子曰く、三人行なえば必ず我が師あり。
その善き者を択びてこれに従い、
其の善からざる者にしてこれを改む。

『論語』述而第七 21

誰かが3人集まれば、私はそこでかならず「師」を見つける。いい人のいい部分を見つけて見習い、悪い人の悪い部分を見て自戒する、という意味です。

特に僕自身、ネットワーク技術者から始まって二十歳(はたち)をとうに超えてからプログラムを書きはじめたこともあり、周りはいつも自分より優れた人ばかりでした。したがって、僕にとって、誰かに教えを乞うことは当たり前のことでした。

歳を重ねて三十路を迎えてからも、先月大学を卒業したばかりの新人のほうが僕よりものを知っていることはよくあります。僕は、これを恥ずかしいことだとは思っていません。その時点で何かを知らないことは恥ずべきことではありません。恥ずべきは、知らないことをそのままにしておくことです

「聞くは一時の恥、聞かぬは一生の恥」というように、相手が自分より若いからみっともなくて聞けないというようなことがあれば、それは非常にもったいないことです! 誰でも自分の師であると考えると、毎日得をします。

今後も、新しいパラダイムが生まれては、それを元に次のパラダイムが発展します。この流れが止まることは、コンピュータの歴史が続く限りないでしょう。

その度に、若くて優秀で頭の柔軟な師がどんどん現れるはずです。一時の恥を捨て、常に彼らに学び続ければ、いつまでもプログラマとして戦い続けられると信じています!

まとめ

1. 必要なことを最低限こなしていけば生き残ることは難しくない

僕は、本格的にプログラムを書きはじめた時期が他のプログラマに比べて遅く、なおかつコンピュータサイエンスの教育も受けていません。

それでも自分の関わる技術スタックに真摯に向き合い、ドキュメントを読み、ひとつひとつのタスクを着実にこなすことで、いつの間にか一人前のWebプログラマとしてやっていける程度の実力をつけることができました。

必要なのは「自分が書いた差分について、自分の意図をきちんと説明できるか?」というような些細なことです。「なんだそんなこと! 当たり前じゃないか」と思った方なら心配いらないでしょう。

2. 仕組みを「提供する側」に回るための王道はない!

ライブラリやフレームワークなどを「提供する側」に回るには、コンピュータサイエンスや数学、ときには物理の教養が求められることもあるはずです。

利用しているうちに「よく見かけるベストプラクティス」のような形で少しずつ自分の中に蓄積していくこともあるものの、高校や大学で体系的かつ網羅的に学習を積み重ねてきた技術者にはかなわないかもしれません。

これを一晩のうちに覆すような魔法は、残念ながら存在しません。ですから終業後に勉強会や読書会に参加して、少しずつでも教養を身につけてください。

体系的な知識は、学んだそばから役に立つような代物ではないかもしれませんが、技術者の基礎体力としていつか自分を助けてくれます。

3. 自分が提供できるバリューを再考する

技術者の価値は多面的で、点数を付けてランキング化できるようなものではありません。環境によって、必要とされる能力は変わってくるからです。

未熟ながらも圧倒的なスピードでプロトタイプを開発できる能力と、すでに稼働している複雑怪奇なシステムを一瞬もサービスを止めることなくリファクタリングしたり高速化したりできる能力に、優劣をつけられるものはありません。

幸運にも、この時代にITエンジニアとして生きている我々は、自分の力で少しだけ未来を良くする力を持っています。自分の持つスキルセットの組み合わせ、あるいは英語力、ときには趣味の自宅サーバ運用さえ、自分の手札となります。

是非、その力を発揮できる場所を見つけてください。絶えず、探し続けてください。

以上です。お読みいただきありがとうございました。

執筆者

白山 文彦(しろやま・ふみひこ) @fushiroyama

@fushiroyama
サーバサイド、Android、インフラなどなんでもやるプログラマ。Web系IT企業を数社渡り歩いたのち、2016年から新聞社でモバイルアプリの開発をしている。「良いコードは健康な筋肉から」が信条。

関連記事:体型を支える技術 ──35歳になっても現役で戦い続けるプログラマの体づくり

*1:その後、AWSのEC2がクロフネのようにやってきて爆発的に流行し、僕の商売は一瞬で上がったりになりました!

*2:故事ことわざ辞典 http://kotowaza-allguide.com/ke/keikoutonarumo.html より