プログラミングスキルの世界観に戻るプログラミング作法の世界観3(エキスパート)プログラミング作法に関する世界観3(エキスパート)です。プログラミングの基本SEの仕事は問題を解決することシステムエンジニアの仕事は、「問題を解決すること」です。要求されている問題を明確に定義します。顧客の要求を考えたり、実際の現場から何が問題として求められているのかを考えます。どのようなシステムを構築すれば問題を適切に解決できるかを明確にします。次に、そのようなシステムをどのようにすれば構築できるかを考えます。その後に、システムの設計を行い、設計からプログラムを実装し、コードを書きます。テストし、納品し、システムの保守を行います。実際のところ「コードを書いている時間よりも、考えている時間の方が多い」とよく言われます。プログラミングとは、「問題を解決する」ことそのものです。どのように計算し、操作し、処理し、実行すれば問題の「ソリューション」(解決方法、答え)を与えられるかを考えるのです。数値の変換プログラミングにおいては、「数値の変換」という発想がよく起きる。「入力された文字を人数分表示する」というプログラムがあったとして、ここでは、人数が表示回数に変換されている。人数が3人居たとして、その3人がそのまま3回になる。このように、「ある数字が別の数字の元になる」。10人居れば10回になる。3×10という単純な計算を、プログラミングではそのように行う。それぞれの人数だけ行うように、それぞれの数を別の数にする。条件式や分岐にすることもある。プログラムに必要な機能をよく分析しようプログラムを開発するコツは、「プログラムに必要な機能をよく分析すること」です。テキストエディタを作るのであれば、バッファに文字列を格納し、テキストエリアに整形して表示する機能がまず必要です。バッファが更新されたら、ビューも更新しなければいけません。ファイルから読み込む機能、ファイルに書き込む機能も必要です。検索や置換、あるいは比較のような機能があると、テキストエディタらしくなるでしょう。テキストエリアには、キーワードを色分けする機能(シンタックスハイライト)があると良いでしょう。機能を分類できたら、今度はどのようなクラス設計でそれを実現するかを考えます。バッファをメンバ変数としたエディタークラスを作ります。同時に、シンタックスハイライトとビューの常時更新機能をつけたテキストエリアコンポーネントを作ります。同時に、ファイルを管理する開く・保存機能を作ります。最後に、検索と置換の関数を作ります。これらをまとめて、エディタークラスに実装します。常時更新機能を実装するには、バッファを編集するのに専用のインターフェースを設けて、テキストエディタにビューを更新する関数を作り、バッファのインターフェースが呼び出されたら、必ずその更新関数が呼び出されるようにします。この更新関数はどこからでも呼び出せるようにして、ファイルを開いたり保存したり、設定を変えた時にも呼び出します。シンタックスハイライトを作るには、テキストエディタコンポーネントが表示する処理を行う時に、バッファ読み込みとビューの表示の間に介入して、ひとつひとつのキーワードを解析し、その情報をテキストにタグのような形で付け足して、表示する処理の部分で、テキストに付属された情報の通り、テキストエリアで文字色を変えてフォントを表示するようにします。そのように、どんな機能が必要かを考えることで、クラスの設計もしやすくなります。入念に作っておいて、あとは何度でも再利用できるプログラミングを行うよりも、手動で操作した方が簡単にできることは確かにあります。テキストエディタで検索・置換を行ったり、行ごとにカウントして処理したりすることは、確かに手動でも行えます。プログラムの真価は再利用できることにあります。一度自動化してしまえば、あとは何度でも再利用できるのです。そのため、テキストエディタを使うところをRubyを使うようにするだけで、作業ははるかに楽になります。ファイル一覧を得るPHP/Rubyなどの関数であるglob()などを使うことで、ひとつのファイルだけではなく、多くのファイルを簡単に操作することができます。構成や設計を作る能力をつけるプログラミングを行う上で必要なのは、構成や設計を行う能力です。オンラインショッピングサイトを作るような「やり方」を学ぶことで、学ぶだけではなく実務的なプログラミングができるようになります。これについては、Railsのようなフレームワークで実際のやり方を学んだり、本を読んでやり方を学ぶこともできますが、以下に挙げるプログラミングスクールに通うのもおすすめです。プログラミングスクール方法として言えるのは、リナックスアカデミーや侍エンジニア塾やGEEKJOBやプログラマカレッジなどのプログラミングスクールに通うことです。以下にリナックスアカデミーの評判があるので参考にしてください。授業料は高いですがリナックスアカデミーの評価はおおむね良しです。お金があるならおすすめします。【辛口評価】リナックスアカデミーの評判は悪い?最悪?リアルな口コミだけを調査した感想|NANOBLOGアーキテクチャ概念の構築また、プログラミングについて言えるのは、「アーキテクチャ概念の構築」です。MozillaのXULや、RailsのMVCフレームワークなどがこれに当たります。プログラミングは、単に作るものの枠組みを考えてコードを書くだけの作業ではありません。自分の考えたアーキテクチャ概念を「発明」するという仕事なのです。ただのコードを書くだけの「コーダー」と呼ばれるエンジニアではなく、アーキテクチャを創造する「アーキテクト」になってください。アーキテクチャを創造するためには、プログラムの全体像の設計や構成ができることに加えて、必要となる技術やプラットフォームやシステムデザインに精通し、プログラミング以外の能力も必要になるでしょう。色んなやり方や色んなプログラムがあるため、一概に「このように開発しろ」とは言わないが、アプリケーションの設計と実装の手順の一例として、以下が参考になるかもしれない。どのような処理が必要になるか、明確化する。プロ仕様など)また、こうして出てきた「漠然とした全体像」を、明確に、それ以上細分化できないところまで細分化し、決まっていないことが何もないぐらい明確化する。明確化した内容を、実際のプログラムにするために、「クラス」と呼ばれる単位に分割し、クラスとクラスの関係性を記述する「クラス図」と処理の流れを記述する「シーケンス図」を描く。最後に、これらに基づいてコードを書く。ここで、初めて、プログラミング言語の知識の内容を活かすことができる。後日注記:実際のところ、上記はMFCのドキュメント・ビューのような場合に限られる。一般的には、「処理の流れをどうするか」「内部的な設定情報をどのように保持するか」「ライブラリや再利用可能なコンポーネントをどのように利用・構築するか」などといった具合になる。エンジニア向け読み物Qiitaでエンジニア向けの読み物系ページをまとめていらっしゃる方がおられます。制御構造とフローチャートifやforなどの「条件分岐」と「繰り返し」は、その時その時の場合によってプログラムが何を実行し、何を実行しないか、どれだけ実行し続けるか、を条件的に記述します。変数が何を持っているか、条件式が何を判断しているか、実行するか実行しないかの範囲と内容は何か、いつどのように実行されるか、いつどのように実行されないか、などを考えると良い。紙にフローチャートを書いて練習すると良いでしょう。条件式に応じたプログラミングここで重要なのは、「条件式」です。条件式に応じて、条件が満たされる間繰り返し処理を実行したり、分岐して別々のコードブロックを実行したり、変数に別の値を代入したりします。当然のことながら、条件式が間違っていた場合は、プログラムは正しく動きません。条件によって別の関数を実行する関数のように、「ラッパー的な関数」を作ることもあります。ゲームであれば、ランダムな数値を変数に代入したり、敵が出現するかどうかの判定や、キャラクターの攻撃が当たるかどうかの判定、敵の生死の判定、ターンごとに攻撃に参加できるかどうかの判定などにも、条件式と変数の代入を使います。データベースやファイルシステムであれば、データの一意の識別のためにキーとなるIDナンバーやiノードなどを代入して、条件ごとにコードブロックや関数を実行します。代入されている変数の値に応じて、別々の処理や制御を行うこともあります。先のゲームの判定で言えば、代入されている値に生存が代入されていればゲームを続け、死が代入されていればゲームを終了する、といった具合です。条件式に応じたプログラミングは、C言語のコマンドラインプログラムなどに多くみられます。イベント駆動によるプログラミング条件式以外の制御フローとしては、イベント駆動などが考えられます。ゲームであれば、キャラクターがジャンプした時、どれくらいキャラクターが上に飛び上がるかとか、キャラクターが前方方向に進んだ場合に敵に当たらないか、ステージから落ちないか、画面をスクロールするかどうか、のようなことをイベント駆動で行います。これはイベントループによって、何らかのイベントが生まれるまで待機し、何らかのプレイヤーの操作が行われたらそれに応じた処理や判定をして画面を再描画する、といった具合で実現できます。イベント駆動によるプログラミングは、UNIXのカーネルや、GUIのプログラム、ネットワークサーバーなどに多くみられます。GUIではメッセージループとイベント駆動により、ツールキットフレームワークを使ったプログラム開発を行うため、CUIのプログラムよりも冗長で複雑かつ、プラットフォーム依存のプログラムになります。抽象的な基盤システムの構築また、プログラムを作る上で重要な考え方が、「抽象的な基盤システムの構築」です。ゲームを作るのであれば、ひとつひとつの対戦画面を作るのではなく、ひとつの「共通の対戦を行うための画面」を作って、そこに具体的なデータを流し込んで、戦闘画面を作ります。そのため、ピカチュウとカイリューが戦うのであっても、ニドキングが戦うのであっても、作るべきなのは、ひとつの「対戦画面」です。マップ画面やダンジョン画面も同じです。ひとつひとつのダンジョンを一から作るのではなく、「共通のマップ画面」を作り、そこにキャラクターの「ドットイメージ」をマスの中に表示していきます。どんなゲームであっても、これは変わりません。カードゲームなら、盤面の画面をひとつ作ります。3D対戦ゲームなら、3D画面を作ります。シミレーションRPGであっても、マップを移動するそれぞれの「駒」を適切に表示するような画面を作ります。繰り返しを使ったプログラムプログラム初心者が忘れがちなこととして、「繰り返しの回数も数である」というのがある。10という数字が与えられて、10回繰り返しの中の文を繰り返すプログラムというのがこれである。このため、回数も数である、ということは大切である。繰り返しには条件式を使ったり、あるいはbreak文が実行されるまで永遠に繰り返したりなど、「繰り返しを終える条件」というのも必要である。味方の全キャラクターが死ぬか、敵の全キャラクターが死ぬまで、互いにキャラクター一人ずつが互いに攻撃する、といったゲームがこうしたプログラムである。正規表現を使ったプログラムまた、繰り返しと良く似ているのが、正規表現を用いた文字列をパターンマッチングさせるプログラム。HTMLをTeX文書に変換するスクリプトなどがこれである。HTMLをTeXにコンバートするためには、それぞれのタグをTeXのマクロに変換する必要がある。1.コメント部分(<!--~-->)を削除する。(これだけでも、きちんと作るのは大変)2.<body>から</body>までを切り出す。3.切り出した内容について、<script>~</script>を削除する。4.<h1>~</h1>などをsectionやsubsectionなどに変換する。5.それぞれのタグ(<li>など)を適切にTeXのマクロに変換する。6.必要のないタグ(<p>など)を削除する。7.最後に、TeXの適切な記述をヘッダ部分とフッタ部分に追記する。実用性を考えるならば既にあるコンバートツールを使うか、手動でテキストエディタで検索・置換を繰り返した方が良いだろうが、プログラミングの勉強としては最適である。関数は自動の実行処理また、関数は自動の実行処理です。ある引数に基づいて、どのような処理を行うかが、汎用的に記述され、汎用的に実行されます。引数とreturnを上手く使いましょう。再帰を使うことも良くあります。再帰とは「その関数の中でその関数を呼び出すこと」です。後日注記:言ってしまえば、定型の処理をあらかじめ記述しておいて、そこにどんな引数が来ても良いようにプログラムを記述し、さまざまな引数によって呼び出して実行し、その結果となる返り値を返す、これが関数の基本です。そのため、自動の実行処理と言えます。サブルーチンはサブのルーチンまた、サブルーチンはサブのルーチンだと思えば良く分かります。「メインのルーチン」があったとして、そこに「サブのルーチン」を作り、メインからサブを呼び出すのです。ひとつの処理の流れがあったとして、関数やサブルーチンにはそのメイン処理とは別の処理の流れがあります。メインルーチンからさまざまなサブルーチンに移動することでプログラムは動きます。「メインのプログラムとは別個にあるサブのプログラム」があり、「プログラムが別のプログラムを呼び出す」ような形で全体のプログラムを作ることで、構造化プログラミングは成り立ちます。小規模プロジェクトと大規模プロジェクトプログラムには、小規模プロジェクトと大規模プロジェクトがあります。小規模プロジェクトは、たとえば簡単なUNIXコマンドや、掲示板スクリプトなどです。した小規模のプログラムは、ひとつのファイルで正しく制御フローを記述します。関数もいくらかしかありません。httpdサーバなどです。した大規模なプログラムは、ディレクトリを大きなサブディレクトリ階層構造に正しい規則で分類し、ソースファイルは関数だけではなくライブラリやコンポーネント機構を使ってモジュール化していきます。小規模でも大規模でもない、普通ぐらいの規模のプログラムというものも存在します。これはIEコンポーネントを用いたタブブラウザや、テキストエディタなどです。どんなプログラムを作るのであっても、まずは小さなプロトタイプの開発から始めます。データ型や汎用的な関数は開発の途中段階で開発します。リファクタリングとテストを行い、ひとつひとつソースファイルを整理していきます。同時に、保守がしづらくならないように、分類の方法、分化の方法を考えながら開発を行います。動くためのアルゴリズムやアーキテクチャも考えなければなりません。中心となるアルゴリズムを、どのような設計と実装で実行するように作るかが鍵となります。プログラミングとは手続きの記述また、プログラミングとは「手続き」の記述であると考えられます。これは、ハードウェアに近い処理で言えます。顕著なのがネットワーク処理(ネットワーキング)です。ネットワークでは、ソケットインターフェースを使って、手続きそのもののプログラミングを行います。多くのコードが、形式的な手続きの記述になります。パソコンはテキストの動く機械また、現代的なコンピュータは、「テキストの動く機械」であると考えられます。この「テキスト」とは、プログラムの書かれたソースコード、設定ファイルや設定データベース、そしてデータファイルやログファイルなどが言えます。UNIXのプログラムは、プログラムのソースコードとバイナリファイル、設定ファイル、データファイルがセットになっています。プログラムが設定とデータを読み込んでプログラムの動作が決定されます。場合によっては、コマンドの実行オプションや引数、そしてプログラムをコンパイルする時のビルドオプションまでが、プログラムの動作を決定すると考えることができます。ほかにも、モジュールや拡張機能などで、プログラムをカスタマイズできます。ソースコードを直接編集しなくても、オブジェクト指向の機能やマクロ言語などの機能を用いて、プログラムをカスタマイズすることができることもあります。Linuxをやると良く分かります。Gentooでは、Portageと呼ばれるソースベースのパッケージ管理システムを使うことで、プログラムをコマンドに応じて自動でダウンロード・ビルド・インストールできます。「Linuxがどのように形作られるのか」を、コンパイルやインストールなどの出力を「自分の目で見る」ことで知ることができます。Gentooでは設定を自分で設定ファイルに手動で書くことによって行いますが、これにより、「自分で設定した内容を自分で見て設定する」ことができます。インストーラもありませんが、ローリングリリースを採用しており、一度インストールしたら二度同じことをする必要はありません。変数には、一時的な記憶領域と、関数の間で共有されるデータ構造がある僕は、変数には二種類の使われ方があると思います。1.一時的な記憶領域。コードブロックの中で、ローカル変数として宣言される。2.各関数の間で共有されるデータ構造。グローバル変数あるいは引数での構造体のポインタとして定義される。オブジェクト指向ではクラスやオブジェクトのメンバ変数がこれに相当する。この2種類は、「スコープが消えても残り続けるかどうか」という違いがある。ローカル変数はスコープから抜ければ消え去る。構造体のポインタはスコープが消えても残り続ける。C言語でも、C++などのオブジェクト指向言語でも、この2種類があります。これを分かっておくことで、Linuxカーネルなどのコードを理解しやすくなります。一つのやり方があるとしたら、3.関数の呼び出し元と呼び出し先の間でやり取りされる変数。引数や返り値あるいは戻り値と呼ばれる。外部に状態を設定ファイル・データファイルとして保存するプログラム、特にゲームのようなプログラムに言えることとして、外部に設定ファイルやデータファイルを作り、キャラクターの状態やゲームの進行状況などを保存する、といったことがあります。普通にPerl/CGIでプログラムを組んでいると、変数とrand()関数のようなランダム数値だけで、おおざっぱなルーチンは簡単に作れますが、これだと、毎回実行するたびにキャラクターの能力やヒットポイントが最初に戻ってしまいます。いう時、Perl/CGIでは外部に設定や状態を保管するデータファイルを作り、それを読み出します。したデータファイルを作る時は、Perlでは文字列を分割するsplit関数を用いて読み出し、書き込む時はjoin関数を使うと便利です。その上で適切に読み込みオープン・書き込みオープンを使い分けながら、データファイルを読み書きしましょう。ポインタとメモリ管理ポインタと参照型変数C言語のポインタは、以下のような場合に使うことが多い。1.スコープ外の変数にアクセスするための参照としてのポインタ2.要素や配列の動的確保のためのポインタ3.配列としてのポインタ4.関数を保持するためのポインタただ、これらのポインタの利用は、C++ならもっと別の書き方が出来る。Qiitaを参照のこと。(上の箇条書きはこのページからの引用です。)ポインタに限らず、参照型の変数は、「同じ領域を違う名前が参照する」という考え方をします。このため、メモリアドレス(変数の場所)をポインタとして操作するC言語だけではなく、PHPなどでも同様に参照型の考え方を良く用いるため、C言語プログラマではなくても、「参照型」という考え方は知っておきましょう。10;とするのを、「int型の変数xに整数値10を代入する」と表現しますが、この時、変数とは「名札」とか「値を入れる箱」などと言った説明がされると思います。先の例で言えば、xという「名札」のついた「箱」に、10という「整数値」を入れます。この時、なんとなく、「名札=箱」だと思っていると思いますが、ポインタを使うと、ひとつの「箱」に対して複数の「名札」を付けることができます。*/とすると、int型変数へのポインタyは、xと「同じ箱」を指しながら、「別の名前」を使っています。そのため、yの参照先を変えると、xの参照先も変わるのです。プログラミングにおけるポインタを理解するためには、このように「名札と箱は必ずしもイコールではない」と考える必要があります。ポインタを使うのか、という答えは、ポインタでしか作れないデータ構造や、ポインタを使った方が作りやすい関数などがあるためです。連結リストを作ったり、あるデータ構造体の一部として別の変数を参照したい場合、あるいはカーネルのファイルバッファにアクセスしたい場合など、さまざまな低レベルな部分でポインタを使います。ポインタとは「名札ごとに箱を作るのではなく、たくさんの名札で箱を共有する(値の共有ではない)」ということです。この箱がメモリアドレスなのです。Javaにポインタがあったとしたら僕は、ポインタは変数を名前で管理するのとは別に、絶対的な位置によって管理・参照する方法だと考えると分かりやすいと思います。Javaにポインタはありませんが、もしもJavaにポインタがあったとしたら、以下のようになるでしょう。//textと表示される。1;はスタックで、mallocなどの動的にメモリを管理しているものはヒープで、変数の値を確保する。スタックは、最後に確保した領域を最初に解放する。ヒープは、もっと動的に確保するために使うが、自分の手でメモリを管理しなければならない。Cメモリアドレス空間Linuxでは、プログラムがメモリ上にロードされると、カーネルがメモリアドレス空間にテキスト領域(プログラムコードを格納する)、ヒープ領域、スタック領域を各プロセスごとに割り当てる。このうち、ヒープ領域とスタック領域がプログラムのデータの格納のために使われる。機械語の論理アドレスは、カーネルによって仲介され、メモリ上の物理アドレスへと翻訳される。それぞれに割り当てられたメモリは「ページ」という小さな単位でカーネルによってメモリ上に領域を割り当てられる。動的なメモリ確保ポインタは、動的に確保したメモリ領域を配列としてアクセスしたり、配列の要素にひとつひとつ順番にアクセスするために使うこともある。動的なメモリ確保の例は、以下のようになる。printf("%d番目の値は%dです。Hanakiより編集して引用。)スマートポインタとガーベッジコレクションJavaでは、ガーベッジコレクションがあるため、mallocやfreeのようなメモリ管理に煩わされることが無い。C++のようなガーベッジコレクションがない言語でも、最近はスマートポインタを使うことで勝手に使われないメモリを破棄してくれる方法が存在する。Rustでは、ムーブセマンティクスと所有権の考え方によって、GCを使わずにして不要なメモリを削除する方式を提供した。ガーベッジコレクション(GC)がある言語でも、GCのやり方はそれぞれの言語によって違う。参照カウント方式、マーク・アンド・スイープ方式、コピーGC方式などが存在する。i686)となり、それ以降はItaniumなどのIA-64とx86互換のAMD64(x86_64)となります。他に、携帯デバイスとして使われるARMや、昔のMacで使われていたIBMのPowerPC、Sunの開発していたSPARCなどがあります。Intel以外のCPU歴史的にUNIXはC言語で書かれたことから、移植性が高いと言われるが、オープンソース系UNIXでは、NetBSDの移植性が高いことで有名だ。Linuxもさまざまなアーキテクチャに移植されているが、移植にはLinuxカーネル、Glibc、GCCなどの対応が必要(僕も詳しくは知らない。LLVMやNetBSDのlibcを使うこともあるらしい。)なことから、新しいCPUアーキテクチャに対応するのは簡単ではない。GNU/Linuxは、さまざまなアーキテクチャに向けたバイナリパッケージを公式で配布していることで有名だ。Linuxは、ソースベースのパッケージ管理システムを採用することで、さまざまなCPUアーキテクチャに対応している。ほとんどのパッケージでコンパイルが必要だ。Fedoraなどのメジャーなディストリビューションも、ARMには対応する傾向にある。いずれにせよ、Intel以外のCPUアーキテクチャでLinuxなどを使う場合は、自分で問題に対処出来る問題解決能力が必要だ。システムコール・APIにいろいろと書いています。コンパイラを作るコンパイラ開発を参照のこと。手法あるものを使うだけでほとんどのことは出来る2017-10-28より。プログラミングは、「あるものを使うだけ」でほとんどのことは出来てしまう。パソコンは基本的に使うだけだ。自分で独自に作ることはあまりない。それで良いと思った方が良い。高度な大規模アプリケーションは、会社でみんなで作るだけの人間しか居ないからだ。RubyによるWebプログラミングのようなものある意味、プログラミングなんて、ただ使うだけだ、ということも出来る。endendとRubyでいくらか書いてやるだけで、簡単に動くRubyのCGIファイルを作ることが出来る。日付を追加する時はdiary_2017.11.txtだけを編集すれば良い。何をするにしても、プログラミングはただ使うだけだ。自分で何も作っていない。使うだけに終始する、それがプログラミングなのだ。上のコードを綺麗な関数にすると以下のようになる。endenddiary_list("diary_2017.09.txt")diary_list("diary_2017.10.txt")diary_list("diary_2017.11.txt")また、オブジェクト指向でなぜ作るのか、という話が分からない人が多いが、フィールドは視点を変えてみるとグローバル変数と似ている。クラスの中だけで使われるグローバル変数だ。いう風に考えると、JavaやRubyのカプセル化という発想も良く分かると思う。・ビューを操作した時に配置オブジェクトとビューを更新する描画モード・配置オブジェクトの編集機能ではないかと思う。(2018-01-24より引用。)きっと、ブラウザなども同じ要領で作れる。MFCにはドキュメント・ビューという概念が存在するが、僕はそれには詳しくない。基本的に、配置メソッドは四角形の領域を表示するようにして、表示メソッドによってビューに「全ての配置オブジェクトを表示する」機能をつけて、描画モードによって操作に応じて部分的に配置オブジェクトの表示を更新する機能をつける。保存する時はデータオブジェクトに変換すれば良い。オブジェクト指向は、クラスによってデータとメソッドを一体化させ、その上でメモリの管理をオブジェクト単位で行い、オブジェクトを簡単に作成・削除し、グローバル変数のようにクラス内部のメソッドからオブジェクトのメンバ関数を処理するものだ、と考えると良く分かる。タスクからシステムを作る2018-02-27より。僕は、出来ればプロジェクトマネジメントの研究をしたい。グーグルの戦略と働き方に興味がある。マイクロソフトの働き方に興味がある。国連の活動に興味がある。先日は、国連の広報ブログを読んでいた。プログラムとは、手順書だ。パソコンをアセンブリから見ると、ただの電卓だ。プログラムとは計算の手順であり、コンパイラは計算の手順をより基本的なものに変換する。プログラムを実現するのはカーネルだが、ファイルシステムなどは本来は必要ない。システムを具体的に実現するのがソフトウェアだ。プログラミングとは、手順書を書くことでシステムのインフラ基盤を作る作業だ。やることが定まっている全てのタスクは、きちんとシステムを作れば簡単に実現できる。普通、描画システムぐらい簡単に作れる。ブラウザではレンダリングエンジンと言う。一つ一つのシステムを作って、細分化させながら組み合わせれば、きっとIllustratorも作れる。プログラミングは、ある意味自動実行とリクエストだ。サーバーをやるとできるようになる。コンパイラは、トークンを解析するシステム、文法を成り立たせるシステム、実行内容を作るシステム、アセンブラを吐き出すシステムを作れば作れる。コンパイラは決して難しくない。機能と構文ごとにシステムを作れば作れる。Rustなら、借用やトレイトの解釈システムと実行システムを作れば作れる。Linuxのおしいところ2018-03-01より。コンパイラは、段階的なステージに応じて中間コードを作る必要がある。C言語なら、ifやforをアセンブリに直して、型や関数を変換すれば、コンパイラは作れる。自分は、これ以外にもネットワークが分かっていて、特にCGIのようにインターネットで繋がる仕組みが分かっている。技術だけでなく、社会的なことが分かっている。ネットの言葉から、経験的にみんなが繋がるシステムを分かっていた。パソコンの良い点は、良いライブラリを使うとあるものを使うだけで簡単にシステムが作れることだが、一概にそれは良いとは言えない。Qtなんか使うと、Qtべったりの依存性の高いシステムになる。プログラミングをするなら、考えないといけない。ライブラリを作る時も、バランスを考えないといけない。Cには何もなさすぎるが、Railsは決まりが多すぎる。Javaのクラスライブラリが一番使いやすい。本当は、ボーランドが賢かった。時代は、アプリケーションをローカルで動かすのではなく、サービス化の流れが止まらない。ローカルアプリケーションをオープンソースにすることにこだわる必要はもうないのかもしれない。コピーレフトは、ソフトウェアよりコンテンツの時代だ。YouTube方式が増えるだろう。サーバーではLinuxは勝っているが、サーバーのシステムまでオープンには出来ない。GNUは新しい戦略を考えないといけない。サーバー管理者は敵ではないから、味方として考えないといけないだろう。GNUは、どこまでをアプリケーションと呼ぶのか、どこからをアプリケーションを利用したサービスと呼ぶのかを、現実のLinux勢力を見た上で、オープンサーバーソフトウェアの可能性を柔軟に考えてほしいと思う。本当は、Mozillaのような発想が良い。XULのような技術を全部独自に作って、公開するのが良い。今からのインターネット時代、さまざまな独自な技術を作ることができるが、これからは自分で作った技術をオープンにし、他社の製品にも採用させ、業界標準の地位を奪いとるのが良いだろう。Linuxの最大の問題点は、「使い方が分かる人間がどこにも居ない」ことだと思う。周りに、Windowsユーザーのような使い方を教えてくれる存在が居ない。ネットのLinux情報は、単発の情報ばかりで、その通りにやってもうまくいかない人間が多い。インストールしたLinuxの意味が分からない。Linuxの一番の問題点は、馬鹿な本が多いことだ。馬鹿な本を読んでも何も出来ない。Linuxをやるための方法は、大学のように自分独自で研究すること以外にない。明らかに普通の人間には使えないのが誰でも分かる。Macとは違って、デスクトップはオリジナルではない。劣悪なコピーに見える。Linuxを使っていると、自分だけの力で上手く使いこなせるか不安になる。何かをやるために出来ることが何なのか分からない。さまざまなアプリケーションを入れたくても、アプリケーション名が分からない。検索でかかるのはWindowsの情報ばかりだ。これで、普及はしない。Linuxを使いたいなら、自分の「サーバー管理がしたい」とか「プログラミングの勉強がしたい」という目的を、もう少し別の形で実現しようと考え直す必要がある。Linuxをインストールしただけでプログラマにはならない。使うだけで諦めてしまっては、夢とLinuxの成果がもったいない。ファイルシステムに関しても不安はある。文字化けや、扱えないファイル形式などをどのように操作すれば良いのか、Linuxでは不安になる。Windowsよりも安定していて、起動可能になるスピードも早いのに、その長所を活かせていない。定番の「使い方」を誰かが書けば良いのかもしれない。起動可能になるスピードではなく、起動してから使用可能になるスピードでした。最近は何も分からず書いているので、そういうところを頭の中で良く間違える。姉の仕事2018-04-07より。姉に、プログラマとして何をやっているかを少し聞いた。工場のライン処理など、さまざまな業務用のシステムを作っている。Formsでインターフェースを書いて、HTTPで通信し、サーバー側のバックエンドで処理をしている。チームで仕事をし、一年以上の単位でシステムを作る。コードを書いている時間は少なくて、どんなシステムを作るのかを考えている時間の方が長い。ウォーターフォールで要求定義からテストまでの過程を経てシステムを作る。姉夫婦は、プログラミングを初めてやるのであれば、エクセルについているVBAでやるのが一番良いと言っていた。標準でエクセルについているソートのような探索アルゴリズムを自分で作るのが良いとのこと。姉が言うに、教えるのは「面倒くさい」と言うことだった。難しいわけではなく、やれば誰でも出来るということ、姉は「慣れと記憶でやっている」ということだった。VBを使うのは出来る人が多いものを使うということで、それぞれの担当がそれぞれのことをチームでやっていると言う。僕は、GUIプログラミングには主に3つの方法があると思っている。Windowsのメッセージループや、X11のイベントループ、Swingのリスナのように、「メッセージループ」を行うことでイベントを分類する方式。次に、MFCのような、継承とオーバーライドでオブジェクト指向でメソッドを書き換える方式。GTK+やVBのような、ウィジェットにコールバック関数でイベントドリブンを行う方式。どの方式も一長一短があるが、少しずつレベルと抽象度が高くなっていく、と考えると良いだろう。理想はGTK+やVBだ。処理は画面のウィンドウではなく、CPUがやっているパソコンの初心者が勘違いしやすいこととして、「パソコンの処理は、画面に出てくるウィンドウがやっている」ということがある。本当は、ウィンドウはただやりとりを表示しているだけで、実際の処理はCPUとハードウェアがやっている。ある意味、「実行ファイルがやっている」という考え方はおかしくはない。それは、OSが実行ファイルを実行する、という発想から生まれている。本当の処理はCPUがやっている。画面に出てこない色々なことを全て、CPUがプログラムコードを実行してやっている。そのことを覚えておくと、パソコンが長い間停止して何をやっているのか分からない、という時でも、「ああ、CPUは今頑張っているのだな」ということが分かる。プログラムとは何なのか、コードはどんなことを書いてどんなことを実行させているのか、良く分かるようになる。共有されるデータを変数に格納し、関数を作って呼び出すプログラムを作るセオリーとして、オブジェクト指向のやり方が良く使われます。それは、「共有されるデータを変数に格納し、関数を作って呼び出す」ということです。多くの場合、これでプログラムは書けます。具体的には、下のカーナビのシステムが参考になるかもしれません。カーナビを作るたとえば、カーナビのシステムを作る場合。地図データがあります。この地図データを、まず、変数に格納します。機能を作る前に、マッピングとして、地図データの基本的な操作メソッドと、ディスプレイやモニター画面に地図を表示する関数群(API)を作ります。ような機能を作ります。これは画像的なライブラリを使うと良いでしょう。地図を解析して、道順を知るための機能は、まず、膨大な地図データをデータベースに登録します。そのために、画像から自動で地図データの「属性」を取得し、自動で登録する解析プログラムを作ります。このデータには、道路の長さと、必要な移動時間、そして道路の右端と左端の位置情報や、道の分岐の情報を登録します。現在地と目的地の位置情報から、「どんな道のりのパターンがあるか」を、道路の右端と左端の位置情報や分岐の情報を上手く繋ぎ合わせることで、全パターン洗い出します。それぞれのパターンにかかる時間を計算し、それをソートして完成です。その上で、さまざまなナビゲーションに必要な機能(道のりを別の色で表示したり、状況に応じてナビゲーションする機能)をつけて、カーナビのシステムを作ることができます。このような場合にも、必要なのは、「データを保持する部分と、そのデータを操作する関数の部分を作ること」です。言えば、「どの道からどの道に繋がるか」というリンク情報をデータベースに登録しておくと、あとあと便利かもしれません。さまざまなボタンやメニューを作って、イベント駆動のメソッドを書く必要があるでしょう。動くかを確認するために、テスト関数のようなものを用意して、さまざまな条件と結果をチェックするようにしましょう。現在位置を取得するGPS機能や、現在位置の変化とともに画面を移動させていく「リアルタイム解析機能」も必要になるでしょう。ブラウザを作るみんな、Webブラウザのようなものは難しすぎて誰にも作れないのだろうと考えているかもしれないが、意外と簡単である。HTMLを装飾と文字データの属性を持ったレイアウト情報(レイアウト文字データ)に変換する。ここでCSSを考慮しても良いだろう。与えられたオプションから四角形の領域を表示する部分を実装する。「divとspanだけを作れば作れる」からである。pタグやh1タグのようなものは、全部divとspanを使って作れば良い。レイアウト部分が作れたら、次は装飾部分を作る。文字を表示しなければならない。次に、文字と背景と線に色をつけなければならない。最初からCSSを考慮した設計にすると、あとで楽が出来るだろう。その上で、画像を表示したり、さまざまな機能を作ったりする必要はある。JavaScriptの実装も難しいし、そのためにはDOMを実装しないといけない。これくらいの、HTMLをパースして領域を表示する部分は、むしろ、僕のロボット(人工知能)のプログラムを参考にすると上手く作れるだろう。HTMLを読み込んで、CSSを解釈し、タグをパースし、領域とレイアウトを決め、装飾をつけて、最終的にモニターに表示するのを、ひとつの制御の流れとして実装すれば、あとはオプションを解釈して動作を変えるだけで、おそらく作れるだろう。テキストエディタを作る本当はコントロールを作るのが難しいのだが、テキストエディタは既にあるコントロールを継承して改良することで簡単に作ることができる。驚き最小の原則とは、特にPerlなどのプログラミング言語などの設計に言われる考え方で、「みんなが驚いたり勘違いしたりすることを極力なくして、当然そのように発想するように設計しよう」という設計の考え方。車輪の再発明(はやめよう)車輪の再発明とは、一度作った基本的なベースシステムをもう一度作り直す(再発明)のではなく、出来るだけ共有して再利用しよう、という考え方。UNIXなどの他、Windowsなどでも言われる。後日注記:実際のところ、「絶対に動くサブルーチン」を作ってしまえば、あとはそのサブルーチンや関数を再利用するだけで絶対に動く。プログラミングではそういう発想をする。同じ処理を別々の場所に何度も書いていると、後で直すのにも時間がかかる。stupid.(シンプルを保て、愚か者め)とは、UNIXで言われる考え方で、「シンプル(単純)」な状態を保っておかなければ、すぐに使い物にならなくなる(設計の間違いを生む)、という考え方。UNIX哲学として「システムのパワーは、プログラム自身からではなくプログラム間の関係から生じる」という考え方が言われている。ひとつのプログラムを使うのではなく、たくさんのプログラムを使って成り立たせるソフトウェアの環境がシステムのパワーを発揮する。findやgrepのような小さなコマンドプログラムを組み合わせて使う、といった時に言われる。個別のプログラムだけがパワーを発揮するのではなく、プログラムをとりまくシェルやOSなどの環境の関係がシステムのパワーを発揮するという、システムエンジニアらしい考え方である。Railsで言われる考え方で、複雑な設定をするよりもある程度の規約をそれぞれが守るようにした方が、フレームワークの管理は簡単になる、という考え方。目玉の数さえ十分あれば、どんなバグも深刻ではないLinuxやオープンソースで言われる考え方で、バグがいくらあったとしても、それを修正するための発見者や貢献者の目玉がたくさんある(たくさんの人がコードを検査している)のであれば、バグは深刻ではない、とする考え方。Reading」という本がおすすめです。さまざまなコードの技法について、専門的な内容が詰まっており、僕の書いたこの文章なんかとは比較にならないほど、賢い技法と解説が掲載されています。この本の内容が理解出来るようになれば、もうあなたはハッカーの仲間入りです。以下に目次を引用します。要素のパッケージ化とアーキテクチャの再利用には、以下のようなものがある。モジュール分割要素としてはもっとも一般的で、プロシージャ呼び出しやデータ共有を通して、コンポーネントを参照し、サービスを提供する。名前空間モジュールの重要な概念に「情報隠蔽」の原則があるが、識別子が漏れないように名前空間を区別する。オブジェクトその内部にカプセル化されたデータへアクセスするための実行時エンティティ。オブジェクトがメッセージを送受信したり、他のオブジェクトのメソッドを呼び出すことで処理が行われる。同じ種類のオブジェクトの動作は、クラスという形で抽象化される。関連のあるクラスは継承階層という形で構成されている。オーバーロード、各言語のクラスなどがある。ジェネリックインプリメンテーション任意のデータ型に対して使用できるような、マクロやテンプレートといった機能。抽象データ型データ構造のカプセル化の仕組みの1つで、一般的に使われるデータ編成(ツリー、リスト、スタックなど)をカプセル化したり、データ型の実装の詳細を利用者側から見えなくする目的でよく利用される。ライブラリある共通の目的を持つ複数のモジュールを取りまとめて1つにしたもの。コードの再利用やカプセル化、構造化、ビルドプロセスの最適化、コードサイズの削減、動的リンクのために使われる。プロセスとフィルタプロセスを使ってシステムを構築する。利点として、以下のメリットがある:1.プロセスが障害分離のための障壁の役割をする2.各プロセスが使用するリソースの検査や管理を個別に行うことができる3.プロセスはそれぞれ別個にコンパイルされるので、大規模なシステムのビルド手順が単純になるコンポーネントプログラムの構成単位のひとつで、自己完結型となっており、きちんと定められてかつドキュメント化されたインターフェースを備えたもの。使用する側とは別の言語で使用することもできる、バイナリ形式でパッケージ化されていることが多い、複数のオブジェクトをカプセル化できる、一般にはオブジェクトよりも堅牢、などといった利点がある。目にするコンポーネント技術には、CORBA、ActiveX、JavaBeansがある。データリポジトリ純粋なデータリポジトリを中心とした分割が行われていることもある。単純なファイル、ディレクトリ階層、構造化ドキュメント、あるいは完全なデータベースなど。フレームワーク大規模なシステムは、ある共有の目的(GUIや通信など)を達成すべく編成された複数のクラスを実装または使用する形でデザインされていることが多い。これらのクラスの集まりおよびそれに対応するインターフェースは、一般に「フレームワーク」と呼ばれる。GUIアプリケーションのフロントエンドの実装。統一されたUI、キーボードやマウスの入力、ウィンドウのシステムイベント、複数の入出力部品(コントロール)の関係といったものをきちんと処理するのは、とても大変な作業となる可能性がある。X11のXtおよびMotifツールキットなどは、MVC(Model-View-Controller)フレームワークを実装しているのが一般的である。フレームワークを使用して構築されたアプリケーションが、シンプルさとはほど遠いものとなっていることは良くある。フレームワーク上に構築されているアプリケーションを詳しく調べていくときには、まずはフレームワーク自体を学ぶことから始めるべきである。コードウィザード多くのフレームワークアーキテクチャは、習得に至るまでの道のりが平坦ではないことから、コードウィザードと呼ばれる機能が用意されるようになった。アプリケーションに開発者に対して、一連の質問や選択肢が提示され、それを元にして出来合いのコードが生成される。ウィザードによって生成されたコードを読むときには、過度な期待をしないこと。すれば失望しなくてすむ。(プレミアムブックス版)を参考に執筆しました。)大規模なプロジェクト大規模なプロジェクトでは、以下のような設計と実装のテクニックを使う。ソフトウェアのライフサイクルと、正式な作法が開発やコードベースの一部となってくる。言語の使い方、プロジェクトの編成方法、ドキュメント化、ライフサイクル活動のプロセスを明確化する。システムの構造、管理の仕方、システム要素のモジュール化、フレームワーク、設計パターン、ドメイン固有のアーキテクチャなど。実装レベルでの、関数、オブジェクト、抽象データ型、コンポーネントのような機構による構成要素の分解。移植性についての取り組み。複雑さへの対処としての、オブジェクト指向の設計テクニックと実装テクニック。C++やHaskellにより、演算子のオーバーロードを使ってプロジェクト固有のデータ型を一般市民に格上げする。オブジェクトモジュールのライブラリや再利用可能なコンポーネント、独立した別々のプロセスへの分解。アセンブラやC/C++での、プロプロセッサを用いた言語の拡張。(プレミアムブックス版)を参考に執筆しました。)プロジェクトのサブディレクトリプロジェクトで共通に使われているサブディレクトリ名には以下のようなものがある。ユーザー提供のツールとコード。一般にメインプロジェクトの外で保守される。(プレミアムブックス版)を参考に執筆しました。Overflowという良質なコミュニティ(質問サイト)があるので、そこで修業すると良いかもしれません。見ていると、日本語のサイトもあるようです。僕は英語圏のコミュニティは詳しくないので、申し訳ないです。Careersスタック・オーバーフローWeb上でプログラミングWeb上で開発・コンパイル・実行オンラインでソースコードを開発・コンパイル・実行できるサービスは以下のようなものがあります。Qiitapaiza.IOpaiza.IOはWeb上でプログラムのソースコードを記述し、オンラインでコンパイル・実行できるサービス。Rubyなどさまざまな言語に対応している。Cloud9は本格的なオンライン開発環境。無料の会員登録が必要。Cloud9(ブラウザのみでコードを記述、実行できるクラウドIDE)|AWS。