ソフトウェア設計者なら知っておきたい知識一覧
概要
ソフトウェア設計者ならコンピュータサイエンスを学習していると役に立つ場面が多々ある。
設計者は最新の技術を追う事に偏重してしまい、コンピュータサイエンスの基礎について語る人は意外に少ない。
ここでは、コンピュータサイエンスの基礎にフォーカスを当てる。
知っておきたい知識一覧
データ構造
リスト、配列、ツリー、ハッシュ、スタック、キューなどの違いが説明でき、
これから作成するソフトウェアについて、どれを使用すべきか適切に選択できる。
必要に応じてそれらを応用したデータ構造を自分で定義して使うことができる。
計算量(計算複雑性)
自身が記述したアルゴリズムが、O(1)、O(n)、O(n^2)、O(n^m)、O(n!)なのかを説明できる。
また、各プログラミング言語のライブラリで、どの操作がどの計算量で終わるのかを理解した上で使用することができる。
計算複雑性クラスの概要を知っていて、それぞれに例えばどういう問題(巡回セールスマン、ナップザック、集合打など)があるのか、
少なくとも一度は勉強したことがある。
探索や計算に膨大な時間が掛かる仕様が盛り込まれた場合、それを適切に説明し、場合によっては然るべきインデックス等を実装できる。
アルゴリズム
ソート、探索、文字列検索、データ符号化、圧縮、誤り検出・訂正等を説明できる。
"なぜソートが遅いのか"、"なぜ圧縮してもサイズが減らないのか(圧縮が無意味なのか)"等を適宜判断して修正できる。
数値計算
浮動小数点の仕組みと情報落ちや桁落ち等の理解、行列、線形代数、モンテカルロ法、ニュートン法、オイラー法、ルンゲクッタ法を説明できる。
また、必要な時に使用することができる。
グラフ理論
有向・無向グラフ、木、ループ、カット、彩色、結婚定理の基礎を理解している。
また、必要な時に使用することができる。
理論計算機
ステートマシン、オートマトン、チューリングマシン、正規表現、ラムダ計算等を理解している。
また、必要な時に使用することができる。
セキュリティ・暗号化
公開鍵、共通鍵、ハッシュ(ダイジェスト)、署名、乱数生成のためによく使用されるアルゴリズムを理解している。
アルゴリズムそのものに対する簡単な理解。(どういう原理でどんなことを行っているのかを説明できる)
プログラミングパラダイム
手続き、構造型、オブジェクト指向、関数型、静的型付け、動的型付け、ダックタイピング等の各特徴を理解している。
また、柔軟に使い分けることができる寛容さ。
並列・非同期処理の基礎
並列処理と並行処理の違い、並列処理が困難であるという認識、並列処理プログラムのデバッグができること。
スレッド、ブロッキング、メッセージング、セマフォ、ミューテックスを理解している。
Future、Promise、async、awaitがバックグラウンドで何を行っているか説明でき、どの場面で何を使用すべきか、何を使用してはならないのか判断できる。
出来れば知っておいた方がよいと考える知識一覧
ソフトウェア工学
設計論、エンジニアリング、ウォーターフォール、アジャイル、DDDとその実践経験。
CPU
命令セット、CPUの機能、分岐予測やハイパースレッディング等を理解している。
OS
メモリ空間、メモリ管理、仮想記憶、シグナル、IO、割り込み処理、タスク管理、ファイルシステム等を理解している。
ネットワーク(OSI参照モデルやTCP/IP 4層モデル、各プロトコル等)
Wiresharkやtcpdump、ngrep等でメッセージをダンプして原因を判断することができる。
OSがネットワーク関連のリソースをどのように管理しているかを理解している。
TCPの状態遷移を理解していて、netstatとかnmapとか基本的なコマンドを使用して知りたい情報を取得することができる。
セキュリティ
Wi-FiやHTTPSでの鍵交換で何を行っているかを説明できる。
どのようなソースコードを記述したらそのような脆弱性が生まれるかを理解している。
攻撃手法にはどのようなものが存在するか、また、その対策としてどういうことを施す必要があるのかを理解している。
統計・データマイニング・機械学習の基礎
回帰分析、最小二乗法、ニューラルネットワーク、SVM等を理解している。