コンピューター関連

category

プログラム開発の基礎知識 〜 ホントにプログラミング学習を始めるときに

プログラム開発の基礎知識 〜 ホントにプログラミング学習を始めるときに

プログラムを作成して何かを成そうとしたとき、物事を合理的に作業を行うには広範な知識が必要であることを認識していない人には仕方がないことですが、ついついプログラム言語に目がいってしまいます。

現代のプログラム言語は、グループ開発が基本ですので、それらを達成するためのオブジェクト指向に基づくモジュール化や、バージョン管理、ソースファイルのロック、などなど、さまざまな機能を工夫し配慮された環境で開発されます。

大学の研究室レベルで一学生に丸投げしている環境ですら、厳しいソース管理(何をもってキビシイというか、何をもってソース管理というかは、全く、事実は小説より奇なり(Truth is stranger than fiction., G.G.Byron) 、ですが ^_^;)は存在します。

今回は、プログラム言語以外のプログラム開発の仕組みの一端を取り上げ、機械工学に非常に重要な”システム”という思想が関わる世の仕組みの一端を勉強します。

本学では、大変歴史ある「プログラム入門」という授業で、歴史あるプログラムの基本形態を学んでいます。言語こそは少し新しいC++に更新されたようですが、シーケンシャルな(フロー駆動型)プログラム構成はある意味、プロラミング言語の古典、という感じです。

プログラムの冒頭から、1行ずつ逐次実行し、せいぜい判断文の分岐があったとしても、基本的にはプログラムの最後までたどり着いて終了する、そういうプログラムは、もちろん現代でも使われています。しかし、それは機械工学で例えれば、ボルトやナットの製造、もっと言えば、その製造工程の鍛造部分やメッキ工程部分のようなものです。小さな世界を見て、その外の世界を正確に予測できる人は、ほとんどいません。

もちろんその工程が機械工学で軽視されるべきものでないことは当然ですが、それをもって機械工学を習得した、あるいは、機械工学の教育を行った、と言われて納得するでしょうか。

あ、すみません。最近の学生さんは、卒業至上主義に基づく単位取得第一主義ですので、最小努力による最大成果、として問題がないのですね。大学も教育担当者も含めて、win-win の関係が成り立っているので、この話題はタブー視されているのでした。納得する、という表現は不適切でした。申し訳ございませんでした。

このサイトでは、そういう本学の常識や“〇〇してないわけではないから問題はないじゃないですか”という思想の外側を扱っていますので、そういう内容が不快に感じたり同意しかねる方は、この先の記述に全く意味はございませんので、こちらのページにお進みいただくことを強く推奨するとともにお願いいたします。

さて、「世の中とは不条理なことには目を瞑って黙って、自分のことをやっておけば幸せなんだ」という忠告に従えない半端者の記事をまだ読まれるあなたが何者なのかは存じませんが、上記条件内容について同意されているものとみなさせていただきます。;-)


機械工学を、一を知って十を知る、で終わらせるには、被教育者にそれなりの勉強方法習得度が必要ですが、それは別記事にありますので、プログラムの話を続けます。


現代の、1980年ころに広まったオブジェクト指向思想に基づいて作成されたプログラムでは、モジュール化やイベントドリブンな割り込み処理、メモリ管理、などへの工夫に注力されています。それを複数で簡単に制作するには、かつてはコマンドツールを意識して使用し、今では環境ツールが簡単にサポートしてくれます。

本課程でも、部分的に unix※1の派生であるLinux※2のさまざまなディストリビューター※3を賛美する教員はいますので、その名前くらいは聞いたことがあることでしょう。

もともとunixは基本OS※4とそこで動くシステム管理系のソフトウエアの研究開発を行うためのプラットフォーム※5でした。したがって、新しいシステム、ソフトウエアを開発するのに広く使用されるようになりました。当然、開発ツールも多数開発され、UNIXに実装されていきました。本来、様々なシステムに実装するための開発プラットフォームだったUNIXですが、そもそも開発した環境を使う方が効率的、最新成果が早く使える、と考えられるのは自然で、同じ目的で開発されたC言語とともに、UNIXは世界に広がっていきました。そしてプラットフォームであったUNIXは、やがて成長したC言語で自身までもかきかえられました。

そのC言語はさらにオブジェクトである構造体がクラスへと明確化に進化し、関数志向なC++※6となり、それ以外の言語へと派生していきました。Apple Macintosh や Microsoft Windows のようにGUIを装備して※7一般の人(会社)へも広がりつつあります。

※1 正式商標はUNIX で、1969年 AT & T 社 BELL研究所で開発開始し、カルフォルニア大学バークレー本校の研究グループのBSD系が有名。貧乏教員にはFreeBSDはありがたいOSでした。
※2 UNIXをPCプラットフォームに対応させたもの。正確にはUNIXの正統派ではなく、UNIXの成果を利用したもの。同じPC OSでもMacOSはBSDの正統派です。Microsoft MS-DOS はバージョンアップごとに内部は Linux化している、ように思います。三系列プラス独立系があって、総数は250を超えてるようです。ペンギン→タスマニアデビルのLinuxカーネル、赤い帽子の red hat、ブドウのvine Linux、手裏剣のようなUbuntu、などなど。ソフト開発という意味では、開発ツールを使わないなら、無料、という以外にあまりメリットはないかもしれません。大多数のコンピューターユーザーにとっては、Windowsと比べれて無料というだけでもメリットは大変大きいですが。
※3 頒布者。頒布物。コンピューター界では改良変更版を作って有償無償で配布している人、あるいはその製品。
※4 コンピューターとソフトウエアの仲介をする一番基本の部分を担う“オペレーションソフトウエア(操作のためのソフトウエア=基本ソフト)”。パソコンOS黎明期のNEC N88-Basic のようなシングルタスクシングルユーザー時代から始まりマルチタスクマルチユーザーが一般になった。
※5 物事のベースになる基盤。MPU などのハードウエアからOSやネットワークシステムなどのソフトウエア、アーキテクチャーにも使用する。
※6 UNIX開発に使用されていたBCPLにイラっとしたことから簡素化したB言語から発展したC言語を改善した言語。システムプログラミングからアプリケーションプログラムまで対応可能な広範な機能を持つ。この分野のシステム技術者は遊び心が豊富でいいですね。
※7 GUIは、一般向けにはウインドウシステムです。例えばコンソールでコマンドを直打ちしないでいいようなインタフェースです。UNIX や Linux では、X-window を基本としたシステムが装備されてます。 Linux で、WindowsっぽいGUIなら Linux mint、Mac ライクなら elementary OS、なんかがよいかもです。
オブジェクト指向なプログラミング

簡単に言えば、重複するルーチンをひとまとめにして関数化することです。さらに言えば、狭義のプログラム上の重複ではなく、その機能について吟味して、その機能を汎用的に使用可能な形でモジュール化することです。前者と後者が全く異なる、と思えばかなり理解レベルが高いと思います。よくわからない人は、まず前者からはじめることです。そうすれば、実装時に、その体験から後者の意味が理解できるでしょう。このような作業が禁止されている一部研究室では、衝撃波冷凍光線攻撃をかわすため、別途、勉強専用プログラムを作成して絶対秘密、秘匿で作業してください。C++の理想的なメインプログラムは、main(){}、だとか。

オブジェクト化されたプログラムは、関数の目的が明確化し、呼び出しオブジェクトが簡素化し、モジュールごとに各人が作業でき、プログラム全体では常に最新状態を利用できます。実作業のベクトル化、並列化、みたいな感じですね。言語(当然その思想に沿ったプログラミング)は、組織運用にも影響を与えるということです。機械工学の、製品は社会に影響するのと同じですね。

 

イベント駆動型プログラム

数値計算には、基本的にフロー駆動型のプログラムで十分です。でも、プログラムの勉強には不十分です。もっと言えば、今はフロー駆動型のプログラミングは、プログラムの勉強には入らないでしょう。フロー駆動型プログラムを中心に使用し科学技術計算を学んでいる人は、その上にのっている数式について、物理的な理論や、数式、方程式としての解の安定性、解の唯一性、方程式系の妥当性、などの知識を十分つけることが重要です。そういう科学計算な部分の周辺は、イベント駆動型プログラミングの世界です。就職して、コンピューターアプリケーションに関わるのならGUIは必須ですし、その知識は重要です。プログラミングの大部分はそのような部分です。あなたがもしもプログラマーを目指しているのならば、イベント駆動型プログラムは重要になるでしょう。

開発ツール

雑多なものまで含まれます。ここでは前述のように、バージョン管理のお話です。開発の観点よりは、それらが発展したツールの恩恵の利用の一例の紹介です。

UNIXでは、上述の経緯から様々なツールがあります。

ファイル操作の grep、find をはじめ、コンパイルの対象ソースが増えた時のmake をはじめとするビルドツール、よりマニュアルに操作できる sh, cash, csh, tcl, AWK 、などのシェルやスクリプト。Git などのようなバージョン管理システム。さらには、コードの重複検出や間違い探しをするコード解析ツール、それらを組み込んでるemacsなどのエディター。そして、これらの総合統合環境である visual studio や MPLab X 、Unity などのIDEまであります。

このようなツールは、アプリケーションやデーターベースなどの入手のシステムに発展しているものもあります。みなさんの身近なところでは、モバイル端末の Google Play や Apple store をはじめ、アプリケーションの自動アップデーター、Linuxでは リポジトリ、のようになものもその類い、です。これらを賢く利用することで、プログラミング作業は簡素化、短期化します。

画像処理プログラム

市販ツールを使用するなら全く気にする必要はあません。自分でプログラムを作成する場合には、画像処理、とりわけ分解された画像を大量に操作する動画処理では、変数の扱いに気を配らないといけません。処理時間はもちろんですが、メモリ管理(といっていいのか)がかなり効いてきます。前者は、研究室レベルでは、自動処理プログラムで長時間実行で放置したり、複数プログラムの同時実行などである程度カバーできます。この時、処理回数が増えれば増えるほど、変数の破棄がきっちりできているかが致命的なメモリ不足を招きます。複雑な、あるいは汎用なプログラムになるほど、モジュールが複雑に呼び出されたりするので、各関数でしっかりとメモリの解放が必要になります。画像処理の手法自体は、今は日々進化する画像処理ライブラリを利用できるので、それらは情報を収集することで対応できます。でも、具体的にプログラムを作成するときは、画像処理は、多分、メモリあるいは変数の管理が大切に思います。そういう意味では、画像処理というよりは、大きなデーターを扱うプログラムのコツ、という方が正しいですね。新しい言語では、そういう作業を見越して、例えばC#のように専用の命令もあります。でも、それを適切に使用していても、上述の複雑さ(多分関数のバグ)によって、原因を見つけられないこともあります。この類のプログラムは、資源の重要性と後始末の大切さをよく学べます。

機械学習 〜 やっぱり時代は猫だった、、、!?

画像処理と同様に、基本的には外部ライブラリを利用したプログラム作成を行います。そもそも、2012 年の「Google のdeep learning※8 によるネコ学習認識※9」と「トロント大学のAlexNetによるILSVRC(画像認識コンテスト)大差優勝」が、現在のAIブームのきっかけだそうです。

ニューラルネットAI利用によるオリジナルの分類器を作成することは理想ですが、研究室レベルでは、その注視点を合理的に考えれば、必ずしも時間をかけた分類器作成はゴールにしなくてすみます。普通のハードウエアで、GitHubでOSS※10なフレームワーク(ほとんどが米大学ルーツ)を使用させてもらい、GPU、FPGA、ASICなどのAIチップや大量データーのエッヂサーバー構築も諦め(大学なので、という発想ははた迷惑ですよね)、有償が基本のAIプラットフォームさえなんとかCOTSできれば、本分の機械工学的には何か探求※11できそうです。

※8 シンプルなニューラルネットワークに比べると、二次的、三次的に中間層という判断ルールが利用されることで、より副次的に判断していることが特徴のようです。言われたことだけでなく、観察の結果、自分で派生的な基準も創造するところは、エンジニアや人にも大切ですよね。
※9 教えなくても猫を覚えたというのは少し誤解を与えると思うけども。赤ちゃんに教えるような手間はないけども、きちんと猫の情報を選別して与える必要はあるようです。いい加減な情報を与えるとアホに育ちます。大学の授業と同じ仕組みですね。すごい。
※10 GPLがいい、と思ってましたが、先進の大学等はすごいですね。MITライセンス、BSDライセンスやちょっと条件を足したApacheライセンスを適用するそれぞれの団体組織がフリーフレームワークでは主流だそうです。
※11 水増しと転移学習で賢く分類器を作れる可能性があります。過学習して頭がカチコチになってローカルな常識(独自の判断)を振りかざすこともないので、その方がよいかもしれません。

さて、ちょっと散漫な記事になってしまいましたが、実現するかどうかは別として、本研究室のテーマに必要な情報です。キーワードをもとに、調査、勉強してください。
プログラム開発は、自分たちが習っているものがどういうものかを広い情報で吟味して、技術者としての強みになってるか、プログラムに関するジャンルは放棄するのか、この記事がきっかけになれば成功です。
最近のプログラミングそのものを簡単にまとめると、

古典的プログラムは処理し続けているが、現代のプログラムは待機している。
古典的プログラムは宣言しっぱなしだが、現代のプログラムは諸処で調整している。
古典的プログラムは既得権益は離さないが、現代のプログラムは必要以上は返納する。
古典的プログラムは冗長的になりがちだが、現代のプログラムは短くて効率的にする。

なんか、古典的プログラムってプロフェザウルスのようですね(⌒-⌒; )
なお、AIが流行っていますが、フレームワークはもう数年でほぼ基本的なものは作成され尽くされて、商業的に成立しにくいスキマジャンルしか残っていないかのしれません。A.I.プラットフォームも、数値計算における差分法のように新規プラットフォーム開発は相当な資源が必要になっているかもしれません。WEBプログラマーのようなネットプログラムの業界の仕事内容の現状を調べれば、A.I.分野の未来も想像できるでしょう。
そういう意味では、古典的(オーソドックス)な機械技術者のスキルの需要は、情報系技術者の状況に似ているものの、穏やかに思えませんか?