読者です 読者をやめる 読者になる 読者になる

nigoblog

スタートアップのCMOブログ

これから先もプログラマーを続けるために重要なこと

アルゴリズム 考え コンピュータサイエンス

先日こんなニュースが
MozillaやApple、Javaの未解決の脆弱性に対処 Javaプラグインを無効に - ITmedia エンタープライズ
【速報】Javaに未修正の脆弱性、無効化を促す警告出される ネットベンチャーニュース

要はJavaは危険です、だから使わないように。
的な!!

個人的にはJavaはあまり使うことがなかったんですが、まぁどの言語にもこんなことはありえるなと思っています。
それは単に流行ってなくて使われてないだったりもそうだし、
こういう時困るのはその言語しか知らない、使えないっていう人ですよね。

例えば今回のを受けてJavaを書く機械が全くなくなったと。
Javaしか書けないAさん
→仕事ない
JavaRubyが書けるBさん
Rubyで仕事する
仮にRubyが使えなくなった場合
JavaRubyが書けるBさん
→仕事ない
RubyPythonが書けるCさん
Pythonで仕事する
…っていっても全然キリがありません。

というわけで本当に独断と偏見なのですが、
これから先どんなことがあってもプログラマーとして食っていける方法っていうのを書いていきます!
ちなみにweb系、業務系問わずなので。

この先身に付けるべき2つの知識

先程も書いたとおりの例ではどのようなプログラミング言語にフォーカスしても不測の事態には対応できません。
つまり何が重要かというと突然自分のメイン言語が使えなくなっても大丈夫である。ということが重要です。
それは単純に複数言語を学ぶということではありません。
何よりベースとなる知識を身につけるということです。
そうすることで急に他の言語をやることになっても臨機応変に対応することができます。
引っ張りましたがその2つは

  1. 数学
  2. コンピュータサイエンス

です。
というわけでそれぞれフォーカスしてその理由というのを説明します。

数学

数学をやるべき理由は色々ありますが、個人的には「論理性」というのがキーワードだと感じます。
特に数学の中でも「証明」というものを鍛えることによって論理力というのは身につきます。
実は証明には数種類しかなくその中でもプログラミングをやる上で重要な3つの証明について紹介します。

3段論法

もっとも有名で簡単な証明方法。

A = B
B = C
ならば
A = C

というような手法。代入や関数、オブジェクトが入り乱れているプログラミング言語の中では知らず知らずのうちに使われています。
意識してみると何かが変わるかも!?

背理法

若干複雑ですが、

Aはtrueであることを証明したい。
仮に
not(A) = B
Bはfalseである。
ならば
A = true

というような手法。Aがtrueであることを証明したい場合、Aの否定がfalseであることを証明することでAがtrueであることを証明する方法。
こちらもifという制御構文が入っているプログラミング言語では重要な証明方法。
それ以前にブール代数の知識があれば良いです。

数学的帰納法

こちらは背理法よりさらに複雑ですが

ある数列の一般項 a_0+a_1+a_2 = sum(n) であることを証明したい時
i ). n = 1の時に成り立つかどうかを調べる
ii ). n = kで成り立つと仮定し、
      n = k+1で成り立つかどうかを調べる

こちらはDRY(Don't Repeat Yourself)を実行するためには欠かせない理論です。
そもそもDRYというのは重複してコードを書かないという考えです。
つまり重複している部分を数列の一般項として考えることによってDRYなコードを書けるようになります。
再帰アルゴリズムにも対応できます。

以上が重要な数学証明編

今度はざっくばらんに見ていきます。

数列

先程も書きましたが、とにかくDRYなコードを目指すのに必要。
本日どうしても

1, -1, 1, -1, ... , 1, -1, 1, -1, ...
1, 1, -1, -1, ... , 1, 1, -1, -1, ...

という数列の一般項を求めたくて必死でした(どんな状況…)
一つ目であれば

(-1)^n

という感じで-1のn乗でOKです。
ただしこれ、プログラミング上めちゃくちゃイケてないです。
小さい数字であれば大丈夫なのですが、n = 1000とか、5000とか100000とかになるとどんどん遅くなります。コンピュータサイエンスのところでも説明しますが、とにかく掛け算は使うべきではない。
というわけで次のように変更しました。

sin(n*π)

すると数が大きくなろうと乗算は一回で全く同じ結果を出力させることができます。
ちなみに下の数列は

1, 1, -1, -1, 1, 1, -1, -1, ...

と仮定すると

cos((2n-1) *(π/4))

で表すことができます。
また入れ子を使い

(1, 1), (-1, -1), (1, 1), (-1, -1) , ...

と見た時、

1, -1, 1, -1, ...

と同義にすることもできます。
とにかく数列は奥が深いものがあります。黄金比を持つフィボナッチ数列など。
というわけで練習問題、
次の数列の一般項を考えてみましょう

1, -2, 3, -4, 5, -6, ...
1, 2, 3, 5, 8, 13, 21, 34, ...
1, 4, 9, 16, 25, ...

他にも数学で重要な概念がたくさんあるので徐々に紹介していきたいと思います。

コンピュータサイエンス

これが重要な理由は
数学と同様、こちらも変わることのない概念だからです。
例えば
プログラミング言語
関数型言語、手続き型言語、オブジェクト指向、…
データベース
RDBMS、ORDBMS、NoSQL、...
これらは過去数年でどんどん新しいものが出てきます。

しかしコンピュータサイエンス、つまりコンピュータの仕組みは
ずーっと変わらず「ノイマン型」!
さらにこの仕組みを知っていれば言語やDBの仕組みが変わっても本質的にコンピュータにとって最適化されているのはどっち?
ということがわかります。
ちなみにノイマン型とは異なるものも提唱されてきてはいますが実用化には程遠いでしょう。

先程も少し書きましたが、加算より乗算のほうが遅いなど。
こちらの理由としては加算は単純な加算。乗算はシフト演算と加算の組み合わせ。などのような理由があります。
アセンブラ言語などに触れてみるとわかるかもしれません。

データ構造

コンピュータサイエンスの中でもかなり基礎的な概念であるデータ構造。
問題を解決するために使う道具のようなものというのが一番しっくりくる気がします。
一番身近なデータ構造は配列です。この配列を様々な操作をすることによって他のデータ構造として考え利用することができます。

まだまだ他にも重要な要素はありますが、このへんで。
コンパイラのことを調べると様々な事柄が出てくるのでオススメです。

まとめ

以上、重要な2つの知識について書きました。
まだまだ他にも重要な要素はあります。

単純にアプリケーションを作るための勉強もいいですが、一旦基礎をやり直してみてもいいのではと思います。
それによって新しいことが入ってきやすくなると思います。
常にフレキシブルな技術を身につけるために基礎はしっかり身につけておきましょう!!

参考図書

数学ガール (数学ガールシリーズ 1)

数学ガール (数学ガールシリーズ 1)


数学入門編としてオススメ

プログラマの数学

プログラマの数学


同著者の本。こちらもプログラミングに重要な数学の特集。少し簡単すぎるかも。

いかにして問題をとくか

いかにして問題をとくか


プログラマーの数学本としては著名な本。マイクロソフトでは必読書になっていた時期があるらしい。

コンピュータアーキテクチャ (電子情報通信レクチャーシリーズ)

コンピュータアーキテクチャ (電子情報通信レクチャーシリーズ)


高専時代の教科書。今読むとわかりやすかったです。

平成25年度 イメージ&クレバー方式でよくわかる 栢木先生の基本情報技術者教室 (情報処理技術者試験)

平成25年度 イメージ&クレバー方式でよくわかる 栢木先生の基本情報技術者教室 (情報処理技術者試験)


資格とかは気にしないけど、基本情報技術者は体系的にコンピュータサイエンスが学べてよいと思う。
他にもビジネスやマネジメントを学ぶのにも良い。