基盤ソフトウェア 6/5

昼ごはんを食べながら今日は何を話そうかと考えていたら
事務的な手続きで忙しく何も考えていない
休みにしようかと思ったけどやります

世間的には大学の先生は毎年同じ授業を
やってはいけないという風潮がある
世間的な大学の講義のイメージは
老教授がカビの生えているようなノートをもって
10年以上同じことを繰り返している
それに続く言葉は、大学の先生っていーよなー
同じことずっとやっていればいいのだから

でも実際、やる内容ってそんなに変わらない
演習も毎年問題を変える
でも良い問題をやらせたい
でも古典的な問題はそんなに数があるわけではない
ハノイの塔とか
でも去年やった問題だとよくないので、
翌年はちょっと難しいハノイの塔をやらせる
でも学生はあまり解けない
古典的ではないへんてこなりんな問題を出すか周期的に古典的な問題を出す
あまりよくない
苦労する
院試もつらい
名作だと自負できる問題が作れるときもある
でも一回世の中に登場しただけで消えてしまう

  • -
分散処理技術 今でこそ分散はどこにでもある ネットワークがどこにでもある言っても 皆さんはそれが当然だと思っているだろうけど私にしては驚きの時代 ネットワークのシステムを作るプログラミングの技術が どういうふうに変化していったか説明する 大学の研究室などに普及し始めたのは1980年代後半 一台100万くらいのマシンがわらわらわらっとあった時代 BSD Socketの実装 4.x BSD Unix 今はLinuxに置き換わってしまったけど皆さんUnixって知ってるんですかねえ ローカルエリア・ネットワークが普及 普及したと当時のSocketは不安定 ちょっとプログラムを間違えるとOSを巻き込んでクラッシュする Socketプログラムをするには能力が必要だった Socketは何を提供するかというと 8bitのバイト列を送信受信する機能 双方向Stream通信 Stream:送った順番で受信できる 最初ネットワークを扱うための技術はいろいろ考えられていた sendとreceiveを用意するといったやり方が原始的 塊を送ると塊を受信できる Streamは送った順番で取り出せるのが特徴 Bufferを使っていっぺんに取り出すことも可能 大事なのは、とにかく1byteの列を送るとその順番で受信できるということ 素直に考えると ハードウェアはStreamにはなっていない 10バイトのデータをsendすれば相手に10バイト届く Socketを作った人たちはsend,receiveではなくて なぜStreamを採用したのか?  何でStreamが生き残ったのかを考えて欲しい まあ、いつもの事ですが理由は私もよくわからない 正解はない でも一般的に多くのアプリケーションはStreamだと扱いやすい ファイルのread、writeがそもそもStream 初期の頃のOSの仕様だとブロックを読むというものが残っている セクタ単位で読む、というインターフェースをOSが提供していた時代もあった ハードウェアと直結しているので性能は良いがプログラミングには不便 ちょうどあるデータがブロックの境にあるような場合などに不便 Linuxだとよくパイプを使って処理する その入出力もStream ファイルを扱うプログラムをパイプを扱うプログラムも同じように作れる それゆえにネットワークもStreamにしておけば ファイルとパイプと同じように扱えるから便利だと思ったのかもしれない 複雑なデータをやり取りしようとすると面倒 512bytes単位のブロックにきちんと配置しようとすると煩わしい 1byte単位で好きな切れ目で読めた方がいい そうするとStreamを使うという発想がでてくる 理由はよくわからないが少なくとも生き残ったのはStream 今でもSocket直接使っているソフトウェアは多い その後いろいろなものが登場する 様々なパラダイムが登場し消えていった Remote Prodecure Call 非同期メッセージ - Ajax 並列loop PhD languages これは単なる皮肉 誰も使わない言語を作って博士号を取る 80年代はいろいろなパラダイムは乱立した時代 何か新しいパラダイムをでっちあげる それを組み込んだプログラミング言語を作る 実装して論文して博士論文書いてめでたく卒業 もちろん作った言語は忘れてしまう どこかのディスクの屑になる それくらい色々なパラダイムが登場して切磋琢磨淘汰されていった 悪いことではなくて いろんなものが考えられて生き残ったやつはよいもの
  • -
Remote Procedure Call (RPC) あるいはRMI 一言で言ってしまえば透明化 通常の文法で関数やメソッドを呼び出して、 同一マシン上の関数ならその関数を実行 遠隔マシン上の関数ならsocketで通信して実行 これは今でも使われている 何がうれしいかというと 分散を考えずプログラムを書いても 一部のオブジェクトとか関数を別のマシンに配置しても 分散アプリケーションが書ける 今だと全部Webに置き換わってしまったが 昔はアプリケーションごとに専用のクライアントプログラムを用意していた 例えば成績表を見るプログラム 大学のサーヴァにある関数を実行して手許のマシンにその結果を表示する そういうものを書くのは非常に便利 これは口で言うほど簡単ではない 基本的にソケットの上に作られている 普通ソケットライブラリを使ってRPCは実装されている ソケットは8bitの値しか遅れない 関数は入力が引数で出力が戻り値 int型の値とかそのまま送れない byteの配列に直さないとデータの送受信をやらなければいけない RPCライブラリの大きな仕事というか面倒な部分は、 引数をバイトの配列に変換すること intだったら8bitずつに分解すればいいだけだが (32bitだったら4つに分ければいい) 難しいのはポインタを含む場合など ポインタを相手のマシンに送っても全く意味がない ポインタの先が指しているメモリのデータもまとめて送る そのデータを送っただけではなくてそのポインタの値も書き換えないといけない 値を返す時も同じようなことをやる (ポインタだけ渡して、 相手のマシンから逆呼び出しをかける、といったやり方もある または分散共有メモリとか) しかしそれだけではダメで C言語の場合、あるメモリブロックの長さはわからない 文字列の場合、最後がnull文字なのでそこまで でも絶対そうであるという保障はない 何バイトコピーすればいいのか ここら辺をどうするのかが格好な研究テーマ これで博士を取った人も少なくない こんな研究が山のようにあった というわけでまとめると どうやってオブジェクトをバイトの配列に直すかは結構難しい 今でも一応RPCは残っているけど RPCの専用言語は残っていない JavaでもRMIがあるけど言語仕様にはない C#にも言語の一部にはなっていなかったはず MicrosoftC#は大概の機能を入れてくるのに サーヴァとクライアントで同じ言語を決めて作るのは難しい 2チームで作る場合はやっぱりSocketを使って、 やり取りをする手順、データのフォーマットだけお互いに決めて 後は好きな言語を使うというケースが殆ど できるだけ仕事を切り分けられるようにするというのが ソフトウェア開発の基本
  • -
代わりに普及したのは IDL - Interface Definition Language HTTPはソケットを前提としているプロトコル 定義を呼んで手でプログラミング 定義を英語で書くのは面倒 仕様を機械が読み取れる形にしましょうというのがIDL Java RMIではJavaのインターフェースをIDL代わりにしている コンパイルすると自動的に、 クライアント用およびサーヴァ用のプログラム(Stub)を生成してくれる 歴史的には専用言語を作ろうという話になったのだけれど やっぱり言語を強制するのはよくないから バイト配列を使ってやり取りをする でも定義が英語で書いてあってプログラムを書きにくいから プロトコルプログラミング言語で書いて自動化できるところは自動化しましょう ということになった 手でやる部分、機械的にやる部分を行ったりきたりしている 専用言語だと機械化しすぎて融通が利かないから捨てられた 全部手で書いて英語で仕様を書くのも面倒
  • -
なかなかWebの世界では互換性の問題もあってIDLということにはならなくて 今でも手で書いている CGI(HTML+HTTP) とにかく全部文字列にして、Formとして引数を送信、HTMLとして受信 そういうふうな仕様になっている Webプログラミングをややこしいものにしている大きな原因の一つ 代案としてはSOAP 4、5年くらい前から流行りだして一世を風靡した感がある XMLにして送りましょう、というのがSOAPの発想 Formとかを使うと、 どういうパラメータがあるのかというのは仕様書を見ないとわからない そのパラメータが何を意味しているのか仕様書を見ないとわからない XMLは文字列には違わないけどタグが付いているので プログラムでデータを解析することができる なんか中途半端なのか 今の段階で普及しているかどうかは… 使ってるの見たことあります?
  • -
Ajax RPCがやりたい 非同期のRPCがやりたい そこで無理やり登場したのはAjax データを何かの形にエンコードして送って返してもらう RPCそのもの 言いたいことは歴史が繰り返しているということ 初めは英文プロトコル仕様書 手作業でソケットプログラミング IDLが登場して自動化 CGIでは元に戻った 手作業でプログラミング SOAPで少し自動化 Ajaxでは非同期通信