/note/tech

出来るプログラマーやエンジニアの方でも「何をやっているか分からない」「何が分からないか分からな...

私は出来るエンジニアじゃないせいか、何かちょっと経験の浅い分野のことをやると「何をやっているか分からない」「何が分からないか分からない」状態に陥ります。それで、Stack Overflowで調べたコード片をコピペして動かすことがあります。最近はGradleのビルドスクリプトの書き方が本当に何も分からなくてStack Overflowに世話になりました。

ただしそういう状態から脱するための対処法はそれなりに身につけていて、必要であれば遠からず解決できるので、その手順を説明しますね。

まずは試してみて動かすこと、次に概念を体系的に理解すること、それから実例と利用できる資源を網羅的に把握すること、最後に実践の機会を作って体得することです。

新しいツールや言語やライブラリを触っていてよく分からないとしましょう。たとえば以下では、Google Compute Engine(GCE)やDockerやKubernetesがよく分からない場合を考えましょう。

●動かしてみる

チュートリアルやGetting Startedのような案内文書があれば、まずは頭から愚直にやってみます。GCEでは対話的チュートリアルやその他のガイド、あるいはAPIから利用するためのサンプルプロジェクトがありますね。Dockerは本当に丁寧な101 Tutorial(初心者向け対話的学習シナリオ)を提供しています。KubernetesのLearn Kubernetes Basicsも丁寧で素晴らしいですね。

さて、チュートリアルに出てくるようなシナリオは比較的小さなつまらない例であることも多いです。初心者にも分かるような簡単なシナリオなので仕方がないんですけど。

そのせいで手を動かさなくても理解できるという誤った自信が湧いてきたり、読み飛ばしたい誘惑に駆られたりするんですが、そこを堪えて愚直にチュートリアルに書かれている通りの手順をやってみます。

チュートリアルで実際に手を動かしてみると、何かちょっとしたことについて間違った思い込みをして躓いたり、何か未知の用語が出てきて分からなくなったりします。ここまでくると、「何が分からないのか分からない」からは半歩ばかり脱しています。

なお、オンラインに良質なチュートリアルがあれば便利ですが、書籍に頼る必要があることもあります。「3日で分かる○○」とか「××で動かして分かる○○」とかそういう軽薄なタイトルの書籍でサンプルが豊富なものを探すと良いです。

●体系的概念理解

次の手順は、先ほど体験したつまずきや未知の用語を手がかりとしながら概念を理解することです。

何をやっているのか分からないという状態にあるとき、本当に知るべきは「どうやればよいのか」ではありません。その技術やツールがどういった体系で構成されていて、それらがどのように繋がっているのかです。 その技術やツールを整備した人は、現実の複雑な問題を整理して分かりやすくするために「仮想ディスク」や「ネットワーク」や「コンテナ」や「レイヤー」のような概念を定めて提供してくれています。その思考を理解しさえすれば、自分の状況に合わせて「どうやればよいのか」を考えるのは遥かに容易になります。

こういう概念の話は大切である一方で、いきなりこれに触れると抽象度が高すぎて何を言っているのか、なぜその抽象化が有用なのかわからなくなります。そこでそれを防ぐために、最初のステップで小さな実例を体験したことが役に立つのです。

たとえばGCEであればコンセプトという章があるので、それをきちんと読みましょう。またDockerであればGetting Startedを通じてContainerやImageやVolumeという概念を説明しています。KubernetesではやはりConceptsという章があります。

RESTful APIを提供しているようなサービスの場合であれば、RESTリソースは概念体系そのものなので、リソース一覧を眺めてそれらの関係を探ることも多いですね。

実際、Google Cloud Platformの新サービスを理解しようとするときには、まずはAPIリファレンスでリソース一覧を読みます。

この段階で頼りにする資料は必ずしもオンラインに転がっているとは限らなくて、特に若い技術ではまったく整備されていないこともあって辛いところです。一方、個別のHow-toよりは変化が少ないトピックなので良質な書籍があることも多く、そういうものを活用できると良いと思います。

あとは、習得しようとしているのが個別のサービスやツールではなく機械学習そのものとかであれば、ここで理解すべき概念というのが「言語モデル」だの「アクティベーション関数」だの「勾配」だので、初心者向け書籍でも結構分量があって大変ですけどね。

ともあれ、ここまで来られればもう何が分からないのかはかなり分かってきています。分からないことを更に調べたり、資料を読み返したりして理解を深めていきます。

●実例と網羅

ただし、抽象的な概念だけを読んで覚えた理解は脆弱です。実例に裏打ちされていないので思わぬ見落としをしますし、すぐに忘れます。また、何となく概念は分かってどのあたりに解決策があるか見当は付くようになったとしても、それで具体的にどうすれば良いのか分からなくて途方に暮れることもあります。

そこで、次にやるのが良い実例を読むと共に、利用できる資源を網羅することです。

新規に言語を覚える場合であれば、標準ライブラリのリファレンスを頭からすべて読みます。このことによって、先ほど「概念理解」のステップで読んだ言語要素が、実際のライブラリ設計においてどのように利用されているのか実例を豊富に学べます。また、標準ライブラリを把握することでその言語でコードを書くときに何を利用できるのかが分かるので、あとでコードを書くときに役立ちます。 RubyであればRuby リファレンスマニュアル 以下の文書すべて、GoであればDirectory src

以下をすべて読む感じですね。

同様に、フレームワークや開発者向けバックエンドサービスであればAPIリファレンスをすべて読みますし、コマンドラインツールであればhelp documentをすべて読みます。GCEならAPIとリファレンス以下の文書すべてとコマンドラインリファレンスをすべて、DockerならReference Documentation以下の文書すべてを読みます。

当然ながら、1度読んだところですべてを頭に入れることはできません。しかし、通読する過程で頭の中に大まかな目次が構築されますし、言語機能の良い利用事例を大量に読めるので有益です。

●体得する

最後に、実践してみる段です。

ここまで来れば、ちょっとした問題解決は自分で調べながらできるようになっています。あとはそれを実際にやってみて経験を積むだけです。

新規の言語を覚えるときには、Project Eulerなどの問題集をその言語で順に解いたり、今自分が欲しい小物ツールを敢えてその言語で書くことが多いですね。

この過程で新たに分からないことが出てくるのが普通なので、そのときは前のステップに戻って概念理解を整理したり、忘れていたことを復習したりします。

●まとめ

まずは試してみて動かしてみましょう。手を動かして躓きを体験すれば何が分からないのかの手がかりにもなりますし、動いているもののイメージが湧いたほうが新規技術習得の動機になります。

次に概念を体系的に理解しましょう。単に少し動かすやり方を覚えただけでは応用が利きづらいので、背景にある概念とそのつながりを理解することが大切です。ここでは整理された資料を参考にするのが望ましいので、良い書籍があればうまく活用しましょう。

それから、実例と利用できる資源を網羅的に把握しましょう。理解した概念を実例で裏打ちすることと、次のステップで利用できる手札を増やすのが目的です。

最後に、実践しましょう。ここまで来たら何が分からないのかは分かるようになっているので、経験を積むだけです。