ホームページ >バックエンド開発 >PHPチュートリアル >プログラミング能力の 7 つの段落

プログラミング能力の 7 つの段落

伊谢尔伦
伊谢尔伦オリジナル
2016-11-26 13:37:141064ブラウズ

はじめに

プログラマーのプログラミングスキルは、経験を積むことで徐々に向上していきます。プログラミング能力はいくつかのレベルに分けられると思います。

以下は、二次元によるプログラミング能力階層モデルの議論です。

1つの次元はプログラミングスキルのレベルであり、もう1つの次元はドメイン知識のレベルです。

プログラミングスキルレベル

プログラミングスキルレベルとは、プログラマーがプログラムを設計して作成する能力を指します。これがプログラマーの基礎です。

セクション 0—非プログラマー:

初心者プログラマーが問題に遭遇したとき、彼または彼女は完全に混乱しており、問題を解決するためのプログラミング方法がわかりません。つまり、あなたはまだ素人であり、まだ「プログラマー」とは言えません。彼の目の前にあるコンピューターは依然として謎のブラックボックスだった。

レベル 1—ベーシック プログラマー:

一定期間プログラミングを学習した後、タスクを受け取ったときにタスクを完了するプログラムを書くことができます。

書かれたコードは通常の環境下では動作しますが、実際の動作では、何らかの特殊な条件に遭遇すると、さまざまなバグが発生します。つまり、デモソフトを開発する能力はあっても、開発したソフトを実際に顧客に納品して使用すると、顧客からお叱りを受ける可能性があります。

プログラマはプログラムを書いていますが、なぜそれがうまく動作する場合とそうでない場合があるのか​​、プログラマ自身も知りません。

運用中にバグが発生したり、要件が変更されたりして、コードの修正や追加が必要になった場合、すぐにプログラムは構造的に混乱し、コードが拡張し、バグが発生します。すぐに、元の開発者自身でさえ、プログラムの保守を引き継ぐことに消極的になりました。

第 2 段落 - データ構造:

一定期間プログラミングを実践すると、プログラマは古代のことわざ「データ構造 + アルゴリズム = プログラム」の意味を理解するでしょう。彼らは問題を解決するためにアルゴリズムを使用します。さらに、アルゴリズムは本質的にデータ構造に依存していることを理解するでしょう。優れたデータ構造が設計されれば、優れたアルゴリズムが出現します。

データ構造の設計を誤ると、良いアルゴリズムを開発することはできません。

外国の賢人がかつてこう言ったのを覚えています:「あなたのデータ構造を見せてください!」

3 つの段落 - オブジェクト指向:

その後、プログラマはオブジェクト指向プログラミングの力を理解するでしょう。最新のプログラミング言語のほとんどはオブジェクト指向プログラミングをサポートしています。ただし、オブジェクト指向プログラミング言語を使用してプログラミングする場合、クラスを使用する場合、さらにはクラスを継承する場合でも、オブジェクト指向コードを作成していることを意味するわけではありません。

Java、Python、Ruby で書かれたプロセス指向のコードをたくさん見てきました。

インターフェイスをマスターし、ポリモーフィズムをマスターし、クラス、オブジェクト、オブジェクト間の関係をマスターして初めて、オブジェクト指向プログラミング技術を真にマスターすることができます。

オブジェクト指向プログラミングをサポートしていない従来のプログラミング言語を使用している場合でも、頭の中に「オブジェクト」があれば、オブジェクト指向プログラムを開発できます。

例えば、C言語でプログラムを書くときは、意識的にオブジェクト指向の手法を使ってプログラムを書いたり、設計したりしています。 struct を使用してクラスをシミュレートし、同じタイプの概念の関数をまとめてクラスをシミュレートします。オブジェクト指向コードが C 言語で記述できるかどうか疑問がある場合は、Linux カーネルを参照してください。Linux カーネルは C 言語で記述されていますが、そのソース コードの行から強力な「オブジェクト」が発せられていることがわかります。の味。

オブジェクト指向プログラミング技術を真に習得するのは簡単ではありません。

私の技術的なキャリアの中で、最も頭の痛いハードルが2つあります。

1 つのハードルは、Dos 開発から Windows 開発に移行する際、フレームワークの概念を長い間理解できなかったことです。 Dos 時代では、すべてが関数ライブラリへの呼び出しであり、プログラムは積極的に関数を呼び出します。 Windows の時代になると、それはフレームワークに置き換えられました。メインプログラムも実際にはフレームワークによって呼び出されます。 UI スレッドはオペレーティング システムからメッセージを取得し、処理のためにプログラムに送信します。 Java プログラマがよく知っている Spring フレームワークも、このような逆呼び出しフレームワークです。

最近では、「フレームワーク」という言葉が非常に高級なものに聞こえるため、多くの「クラスライブラリ」/「関数ライブラリ」が自らを「フレームワーク」と呼んでいます。私の意見では、これはすべて名前の誤用です。

「クラスライブラリ」/「関数ライブラリ」は、それらを呼び出すために書いたコードです。

「フレームワーク」とは、コールバック関数をフレームワークに登録し、フレームワークは私が書いた関数を呼び出すことを意味します。

もう一つのハードルはオブジェクト指向です。私は長い間、クラス間の関係をどのように設計すればよいのかわからず、クラス階層をうまく設計できませんでした。

外国の専門家の本を読んだのを覚えています。彼は非常にシンプルで実践的なオブジェクト指向設計手法について話していました。「問題を述べて、それから名詞を見つけて、それを使ってクラスを構築します。見つけ出す動詞を入れてください。」クラスのメソッドを構築するために使用します。」この手法は非常に効果的ですが、あまりにも草の根的で理論的根拠がなく、厳密ではありません。問題の表現が下手だと、結果として生じる階級制度に問題が生じることになる。

オブジェクト指向の思考を習得する方法はたくさんあるはずです。オブジェクト指向の設計思考を理解して習得するために、リレーショナル データベースからインスピレーションを得ました。

私の考えでは、リレーショナルデータベースのテーブルは実際にはクラスであり、レコードの各行はクラスのインスタンス、つまりオブジェクトです。テーブル間の関係はクラス間の関係です。 O-Rmapping テクノロジ (Hibernate など) は、オブジェクト指向コードからデータベース テーブルへのマッピングに使用されます。これは、クラスとテーブルが実際に論理的に同等であることも示しています。

データベース設計とクラス設計は同等であるため、オブジェクト指向システムを設計するには、リレーショナル データベースの設計スキルのみを使用する必要があります。

リレーショナルデータベースのテーブル構造の設計は非常にシンプルです:

1. テーブル間の関係、つまりクラス間の関係を特定します。 1 対 1、1 対多、多対 1、または多対多ですか。これがクラス間の関係です。

2. テーブルのフィールドを特定します。もちろん、オブジェクトには無数の属性があります (たとえば、人: 身長、体重、性別、年齢、名前、ID 番号、運転免許証番号、銀行カード番号、パスポート番号、香港およびマカオのパス番号、雇用番号、医療情報など)歴史、結婚歴など)、記録するプログラムを作成する必要があるのは、関心のある属性だけです。これらの重要なプロパティはテーブルのフィールド、つまりクラスの属性です。 「三千の弱い水、柄杓を持って飲みます」!

4 段落 - デザインパターン:

「100,000 行のコードがないなら、デザインパターンについて私に話すな。」 という文章をインターネットで見たことがあります。私も深く同意します。

初めて Gof のデザイン パターンに関する本を読んだとき、それまでデザイン パターンについて知らなかったものの、実際のプログラミング プロセスではいくつかのデザイン パターンを実際に意識的に使用していたことを覚えています。デザイン パターンはプログラミングの客観的な法則であり、誰かが発明したものではなく、一部の初期の上級プログラマーによって最初に発見されました。

デザインパターンがなくても、ニーズに合わせたプログラムを書くこともできます。ただし、その後のニーズが変化すると、プログラムは十分な柔軟性を失い、持続不可能になります。実際のプログラムが顧客に提供された後は、さらに需要のフィードバックが確実に発生します。後続のバージョンの開発により、需要は確実に増加します。これはプログラマーにとって避けては通れない現実です。

Web、デスクトップ、モバイル、ゲームのいずれであっても、UI プログラムを作成するときは、MVC デザイン パターンを使用する必要があります。そうしないと、その後の UI 要件の変更に直面してプログラムを維持できなくなります。

デザインパターンで最も重要な考え方はデカップリング、インターフェースを介したデカップリングです。このようにして、将来要件が変更された場合でも、新しい実装クラスを提供するだけで済みます。

主なデザインパターンは実はオブジェクト指向です。したがって、デザインパターンはオブジェクト指向の発展段階であると考えられます。デザインパターンをマスターすることによってのみ、オブジェクト指向の設計テクニックを真に完全にマスターしたとみなすことができます。

新しい言語 (関数型プログラミング言語などの非オブジェクト指向言語を含む) を学ぶときは、その構文を理解した後、さまざまなデザイン パターンがこの言語でどのように実装されているかに常に注目します。これはプログラミング言語を学ぶためのヒントでもあります。

5段落--言語専門家:

一定期間のプログラミングの練習を経て、プログラマーは一般的なプログラミング言語にかなり習熟しました。言語の使用法やさまざまな落とし穴を他のプログラマーに説明するのが得意な「言語弁護士」になる人もいます。

この段階のプログラマーは、自分が使用する言語を心から信じていることが多く、コミュニティやフォーラムで他の言語のユーザーとどの言語が最適なプログラミング言語であるかについて議論することがよくあります。彼らは、自分たちが使用している言語が、例外なく、世界で最高のプログラミング言語であると考えています。彼らは、自分たちが使用するプログラミング言語があらゆるシナリオに適していると信じています。彼らはハンマーしか見ていないため、すべてのタスクを釘として扱います。

6段落 - 多言語エキスパート:

この段階のプログラマーは、仕事上の関係、または純粋にテクノロジーへの興味のため、いくつかのプログラミング言語を学習し、習得しています。私はさまざまなプログラミング言語のさまざまな設計思想を経験しており、各言語の長所と短所をより深く理解しています。

彼らは今、プログラミング言語が最も重要ではなく、プログラミング言語は単なる基本的なスキルであると信じています。

今後、彼らは、さまざまなタスク要件やさまざまなリソースに基づいて問題を解決するためにさまざまなプログラミング言語を選択するようになり、開発に特定のお気に入りのプログラミング言語を使用しないことに文句を言うことはなくなります。

プログラミング言語には多くの流派や考え方があり、複数のプログラミングパラダイムを同時にサポートするプログラミング言語もあります。

静的型プログラミングパラダイム

静的型プログラミングパラダイムを採用するプログラミング言語では、その変数は明示的に型指定する必要があります。代表的な言語: C、C++、Pascal、Objective-C、Java、C#、VB.NET、Swift、Golang。

これを行う利点は次のとおりです:

1. コンパイラはコンパイル時に型エラーを見つけることができます。

2. コンパイラがコンパイル時に型情報を知っていれば、パフォーマンスを向上させることができます。

このパラダイムでは、プログラマーは変数の型を知っている必要があると考えられています。変数の型が分からない場合は、いじらないでください。コンパイル時に、プログラムはエラーを報告します。 SwiftとGoはどちらも静的に型付けられたプログラミング言語ですが、タイプを明示的に指定する必要はありませんが、推論を通じてコン​​パイラによって自動的にそのタイプを決定できます。

動的型プログラミングパラダイム

静的型プログラミングパラダイムを採用するプログラミング言語は、変数の型を明示的に指定する必要がありません。すべての変数は、任意のタイプのオブジェクトを指すことができます。代表的な言語:Python、Ruby、JavaScript。

動的型付けの哲学は、ダックタイピングの概念に要約できます。ジェームズ・ウィットコム・ライリーによって提案されたアヒルのテストは、次のように表現できます。「鳥がアヒルのように歩き、アヒルのように泳ぎ、アヒルのように鳴くのを見ると、その鳥はアヒルと呼ばれます

」。は、プログラマは変数の型と、変数がサポートするメソッドとプロパティを知っている必要があると考えています。変数の型が分からない場合は、いじらないでください。実行中にプログラムがクラッシュします。プログラムがクラッシュした場合、誰が責任を負うのでしょうか?自分を責めてください。あなたはプログラマーの資格がありません。

動的型付けの利点は次のとおりです:

インターフェイスと抽象型を明示的に定義する必要がありません。型が必要なメソッドとプロパティをサポートしている限り、問題ありません。手順は非常に柔軟かつ簡単になります。 C++、Java、および C# が生命線とみなすインターフェイス/基本クラスは、動的言語では何の役にも立ちません。

欠点は次のとおりです:

1. 型が間違っている場合、コンパイラはエラーを見つけることができませんが、プログラムは実行時にクラッシュします。

2. コンパイラーは変数の型を知らないため、パフォーマンスを最適化できません。

オブジェクト指向プログラミングのパラダイム

オブジェクト指向プログラミングのパラダイムは、1970 年代後半に台頭し始めました。コードをカプセル化するモジュールとして、クラスとクラスのインスタンスをサポートします。代表的な言語: Smalltalk、C++、Objective-C、Java、C#、VB.NET、Swift、Go、Python、Ruby、ActionScritp、OCaml

初期のプログラミング言語はすべてプロセス指向でした。関数を形成するのはシーケンス、条件、ループです。コードのサイズが大きくなるにつれて、コードをモジュール化する必要があることがわかります。コンセプトに対応するコードはファイルに配置されるため、同時開発とコード管理が容易になります。

人々はまた、「プログラム = データ構造 + アルゴリズム」の法則を発見しました。したがって、概念に対応するデータ構造と機能は 1 つのファイルに配置する必要があります。これがクラスの概念です。

オブジェクト指向プログラミングパラダイムは確かに生産効率を大きく向上させたので、言語レベルでオブジェクト指向プログラミングパラダイムをサポートする言語がたくさんあります。

C言語は言語レベルではオブジェクト指向プログラミングパラダイムをサポートしていませんが、現代のC言語開発はオブジェクト指向モジュールの考え方を適用し、同様の命名方法を使用して同じタイプのデータ構造と関数をファイルに配置します。 。

結局のところ、C言語は言語レベルでのオブジェクト指向サポートをサポートしていないため、多くのプログラマはC言語にオブジェクト指向サポートを追加したいと考えています。代表的なものはC++とObjective-Cです。

C++は新しい言語ですが、言語要素のほとんどはCと互換性があります。

Objective-CはCと完全な互換性があります。 Objective-C は、インターフェイス (つまり、他の言語のクラス) とプロトコル (つまり、他の言語のインターフェイス) をサポートするために、構文糖衣の薄い層を C に追加します。 Objective-C の初期実装も C 言語プリコンパイラでした。率直に言って、Objective-C は、追加された構文が C のフローに準拠していないことを除けば、オブジェクト指向のシステム設計において非常に精巧です。初期の頃、ジョブズは非常に洞察力があり、Objective-C をポケットに入れました。それは Apple/NextStep システム内で閉鎖されていたため、それについて知る人はほとんどいませんでした。 iOS システムの人気に伴い、Objective-C は近年世界中で有名になりました。

関数型プログラミングのパラダイム

関数型プログラミングのパラダイムは、一部の数学者によって発明されたプログラミング言語です。彼らはプログラムが数学的な関数であると信じています。代表的な言語: Lisp、Erlang、JavaScript、OCaml、Prog。

関数型プログラミング言語を強く支持し、それが非常に革新的であると考えている専門家はたくさんいます。しかし、彼らは関数型プログラミングのパラダイムの力を過大評価していたように思います。関数型プログラミングのパラダイムがオブジェクト指向プログラミングのパラダイムよりも優れているとは思いません。

関数型プログラミング言語の中核は関数であり、クラスという概念がありません。ただし、その関数は従来のプロセス指向言語の関数ではなく、「クロージャ」の概念をサポートしています。

私の意見では、「クロージャ」とも呼ばれる関数型プログラミング言語の関数は、端的に言えば実際には「クラス」です。今日に至るまでのプログラミング言語の開発には、モジュール化と「データ構造」と「アルゴリズム」の組み合わせが必要です。言語に関係なく、それらを組み合わせたプログラミング手法をとらなければどうしようもありません。

オブジェクト指向プログラミング言語はクラスを使って「データ構造」と「アルゴリズム」を組み合わせます。クラスの中核は「データ構造」、つまりその「プロパティ」であり、「アルゴリズム」やその「関数」ではありません。クラスでは、プロパティに関連付けられた関数です。

関数型プログラミング言語はクロージャを使って「データ構造」と「アルゴリズム」を組み合わせます。外部フィールドを取り込むことができる機能です。 「機能」に付随する「性質」です。

「クラス」は本質的には「閉鎖」と同じです。多くのオブジェクト指向プログラミング言語がクロージャをサポートするようになりました。彼らのコードを観察すると、実際に「クラス」を使用して「クロージャ」を実装していることがわかります。

「授業」と「閉会」ではどちらが使いやすいでしょうか?明らかに「クラス」です。

そして、「クロージャ」はより簡潔であるため、「クロージャ」はオブジェクト指向プログラミング言語で匿名クラスを置き換えるのによく使用されます。関数が 1 つしかないクラスの場合は、クラスとして記述するのは面倒なので、クロージャとして記述したほうが簡潔です。

OCaml 言語についての不満。その前身である Caml 言語は、オブジェクト指向メカニズムの完全なセットを追加しており、C++ と同様に学習が簡単です。 。 割れた。

JavaScript にイライラしていて、常に JavaScript にオブジェクト指向サポートを追加したいと考えているオブジェクト指向言語制御担当者もたくさんいます。 ActionScript もそのような試みの 1 つです。私も使ってみましたが、Java とあまり変わりません。

またExtJSについて愚痴る。 Web フロントエンド開発フレームワークを選択するときに、ExtJS と JQuery を比較しました。

ExtJS は明らかに Java の専門家によって開発され、JavaScript を使用して Swing の設計アイデアをシミュレートし、UI ライブラリを構築しました。

JQuery 開発者は明らかに JavaScript の関数型プログラミング パラダイムを理解しており、ExtJS をすぐに上回る JavaScript の動的関数型プログラミング言語の特性に基づいた UI ライブラリを作成しました。

ExtJS と JQuery の話から、多言語プログラミング機能がいかに重要であるかがわかります。 ExtJS の作者は Java に堪能で Java が大好きなので、Java を使うためのハンマーとして JavaScript を使い、手当たり次第に Java を叩いています。これはありがたいことです。

関数型プログラミング言語と末尾再帰などのヒント。末尾再帰では、再帰呼び出し中のスタック オーバーフローを防ぐためのスタックは必要ありません。

テンプレートプログラミングパラダイム

テンプレートプログラミングは型をパラメータとして使用することであり、関数のセットはあらゆる種類の型をサポートできます。代表的な言語:C++。

テンプレートプログラミングの必要性は、C++がコンテナライブラリを開発していたときに発明されました。コンテナーはあらゆる種類のオブジェクトを格納する必要があるため、ジェネリックスが必要になります。

C++テンプレートプログラミングとは、コンパイル時にソースコードでの使用法に基づいて、対応するタイプのコードを作成することです。 C++ のほかに、Java や C# にも「ジェネリック」と呼ばれる同様の機構がありますが、その実装方法は C++ テンプレートとは大きく異なります。彼らのコンパイラは新しいコードを生成せず、代わりにキャストを使用します。

テンプレート/ジェネリックのないプログラミング言語で、オブジェクトをコンテナに格納するにはどうすればよいでしょうか?パブリック基本クラス型 (Java、C#) または void* ポインター (C) のオブジェクトにアクセスし、それを取り出すときに自分で実際の型にキャストするだけです。動的型付け言語では型は気にされず、オブジェクトをコンテナに放り込んで取り出して直接使用するだけです。

C++ マスターの中には、テンプレートに基づいた「テンプレート メタプログラミング」を考案した人もいます。テンプレート プログラミングは C++ コンパイラによって実行されるため、テンプレート メタプログラミングではコンパイラに計算を実行させ、結果はコンパイル後に計算されます。研究とスキル披露以外に何の役に立つの?

まとめ

言語を学ぶ価値があるかどうかの基準はいくつかあると思います:

1. 使いたいかどうかに関係なく、使いたければ学ばなければなりません。 。結局のところ、私たちは皆食べなければなりません。

2.その言語的特徴が爽快感を与えるかどうか。そうであれば、入場料を払う価値はあります。たとえば、Go 言語では例外が廃止され、代わりに複数の値が返されます。そう思います。実際、私は長年にわたって例外を積極的に使用してきました。なぜなら、C は例外をサポートしていなくても問題なく動作できるのに、なぜ例外が必要なのでしょうか?エラーが発生し、エラーコードが返されました。取り返しのつかないエラーの場合は、プログラムを直接中止してください。さらに、例外は実際には手続き型プログラミングの原則に違反します。関数には入口と出口が 1 つだけ必要です。例外をスローするための出口は他にもあります。

3. あなたは特定の分野が得意ですか?ハンマーしか持っていない場合は、あらゆるタスクをハンマーのように扱うことになります。しかし、ツールボックスにさまざまなツールがあれば、さまざまなタスクに取り組むのがはるかに簡単になります。

第7段落 - アーキテクチャ設計

優れたソフトウェアを設計するには、アーキテクチャ設計の能力も習得する必要があります。アーキテクチャ設計にはいくつかのスキルがあります:

1. レイヤ化

ソフトウェアは通常、次のように分割されます:

プレゼンテーション層 - UI 部分

インターフェース層 - バックグラウンド サービスの通信インターフェース部分

サービス層 - 実際のサービス部分

ストレージ層 - ファイルまたはデータベースに保存される永続ストレージ部分。レイアウト ソフトウェアは各モジュールを分離し、並行開発をサポートし、変更が容易で、パフォーマンスを向上させることができます。

2. SOA

モジュール同士はネットワーク通信で接続されており、疎結合になっています。各モジュールは個別にデプロイでき、デプロイメント インスタンスを追加してパフォーマンスを向上させることができます。各モジュールは異なる言語やプラットフォームを使用して開発でき、以前に開発したサービスを再利用できます。 SOA、一般的に使用されるプロトコルには、WebService、REST、JSON-RPC などが含まれます。

3. パフォーマンスのボトルネック

1) 同期を非同期に変更します。

メモリキュー(Redis)、ワークフローエンジン(JBpm)などで実装。メモリ キューはデータが失われやすいですが、高速です。ワークフロー エンジンはリクエストをデータベースに保存します。

同期リクエストを非同期リクエストに変換することで、基本的にパフォーマンスの問題の 99.99% を解決できます。

2) 単一マシンの並列ハードウェア処理を使用します。

例えば、GPU、FPGA、その他のハードウェアを使用して処理を行い、パフォーマンスを向上させます。

3) クラスターコンピューターを使用して処理します。

たとえば、Hadoopクラスターは複数のコンピューターを使用してデータを並列処理します。

独自のソフトウェアスタックでは、モジュールの複数のコピーをデプロイし、それらを並行して処理することもできます。

4) リクエストを満たすためにキャッシュを使用します。一般的に使用されるコンテンツでキャッシュが加熱されると、多数のユーザー リクエストはメモリからデータを読み取るだけになり、パフォーマンスが大幅に向上します。

キャッシュは神のアルゴリズムであり、そのパフォーマンスが最適なパフォーマンスよりわずかに低いだけであるかのように覚えておいてください。あたかもあなたが神であり、未来を予見できるかのように。 X86 CPU は周波数制限に直面しているため、CPU のパフォーマンスを向上させる主な方法は高速キャッシュを追加することです。

4. 大規模システムには小さなことをしましょう

大規模なシステムに遭遇しても慌てず、複数のモジュールに分割し、複数の小さなプログラムを使用し、SOA連携で解決してください。これは Unix の設計哲学に準拠しています。 Unix では、多数の単一目的の小さなプログラムが開発されており、パイプラインを使用して複数の小さなプログラムを連携させてユーザーのニーズを解決することが推奨されています。もちろん、パイプライン通信には制限が多すぎて柔軟性が十分ではありません。したがって、URI と SOA を通じて複数のプログラムを連携させることができるようになりました。 Android と iOS 上のアプリケーションは、URI を通じて連携できるようになりました。これは Unix の設計思想を現代的に発展させたものと言えますね。 !

5.シャーディングスライス

今はIOEに行くという流れがあります。 I-IBM メインフレーム、O-Oracle データベース、E-EMC ストレージ。以前は、大規模システムは IOE を使用して構築され、メインフレーム上に Oracle データベースをデプロイすることが多く、Oracle データベースはデータの保存に EMC を使用していました。 IOE は、現在最も強力なコンピューター、データベース、ストレージです。しかし、巨大なシステムに抵抗できない時が来るでしょう。

OracleデータベースはShareeverythingであり、コンピュータクラスタ上で実行できます(サーバーノードは16を超えることはできません)。コンピューター クラスターはすべて同じストレージを共有します。

IOE運動への移行はShareEverythingモデルの破産を意味します。システムを無限に拡張できるようにするには、ShareNothing を使用する必要があります。

MySQL データベースを使用して、あらゆるサイズのデータ​​を処理します。前提として、シャーディングを理解していることが前提となります。大規模なシステムをいくつかの小さなシステムに分割し、それをいくつかの安価なサーバーとストレージに分割します。より現代的には、多数の仮想マシンに分割されます。

たとえば、鉄道省のウェブサイト 12306。私たちは、列車の切符が特定の列車に属していることを知っています。次に、各列車をユニットとして分割し、12306 の Web サイトを数千のモジュールに分割できます。仮想マシンは複数のモジュールをホストできます。特定のトレインがパフォーマンスのボトルネックになった場合、それらのトレインを独立した仮想マシンに移動できます。リストされているサービスの一部が利用できなくなったとしても、システムが完全に利用できなくなるわけではありません。

12306 Webサイトには、ユーザーログインというグローバル部分が1つだけあります。第三者に任せることも可能です。たとえば、ユーザーは WeChat、Weibo、QQ、その他のアカウントを使用してログインできます。

ユーザーログインサービスを自分で実装することもできます。または、スライシングを使用して、複数の Redis サーバーでサービスを提供します。 Redis サーバーは、ログインしている各ユーザーの sessionId と userId、ロール、権限、およびその他の情報を保存します。 sessionId はランダムに生成され、そのビットの一部を選択して、どの Redis サーバー上にあるかを識別できます。ユーザーがログインすると、sessionId が顧客に送信されます。 sessionId は、ユーザーがリクエストを行うたびにサーバーに送り返されます。サーバーは、ユーザー情報を照会し、ユーザー要求を処理するために、sessionId を Redis サーバーに送信します。 sessionId が Redis サーバー上に見つからない場合は、ユーザーにログインさせます。登録ユーザー全員が同時にログインしてもメモリをあまり必要としません。さらに、セッション メモリが多すぎる場合は、最も早くログインしたユーザーのセッションを削除し、強制的に再ログインさせることができます。同時にアクティブなユーザーの数はそれほど多くありません。

ドメイン知識のレベル

これまでのレベルはすべて、プログラミング自体のスキルに焦点を当てており、それ自体は基本的なスキルであり、それ自体では大きな価値を生み出しません。しかし、あまりにも多くのプログラマーがこれらの基礎的なレベルで多くの時間を無駄にしています。

プログラマの中には、新しいプログラミング言語が登場したり、古い言語がもてはやされるたびに、特にプログラミング言語を掘り下げるのが好きな人がいます。私もその一人で、プログラミング言語とトリックに多くのエネルギーを浪費しています。

C++ 言語は特に大きな落とし穴だと思います。元々はオブジェクト指向 C として開発されました。その後、テンプレート プログラミングが発見され、テンプレート プログラミングとさらにテンプレート メタ プログラミングが強く提唱されました。最近、C++11 や C++14 などの新しい標準が発表され、関数型プログラミングや型推論など、多くの新しいものが追加されました。 C++ は複雑すぎて落とし穴が多すぎるため、プログラマーのエネルギーが多大に消費されます。私が C++ を使用する場合、オブジェクト指向部分とテンプレート部分のみを使用し、その他の高度な機能は使用しません。

コンピューター サイエンスは非常に幅広い主題であり、価値のあるプログラムを作成できるようにするために、詳細な学習が必要であり、価値のある知識領域が数多くあります。ソフトウェアを実装したときに価値を発揮するには、ソフトウェアを業界に統合する必要があります。ドメイン知識を理解せずにプログラミングスキルを勉強するだけでは価値のあるプログラムを書くことはできません。

コンピューター サイエンスには多くの分野があります。ここではいくつかの例を示します:

ストレージ ---- ブロック デバイス、ファイル システム、クラスター ファイル システム、分散ファイル システム、光ファイバー SCSI、iSCSI、RAID など。

ネットワーク---イーサネット、光ファイバーネットワーク、携帯電話ネットワーク、WIFI、VLANなど。

コンピュータのアーキテクチャは主にCPUの命令セットです。 x86、ARMなど

USBプロトコル。 URB パッケージについて知る必要があります。

PCIプロトコル、PCI-Eプロトコル。最新のコンピューター周辺機器はすべて PCI プロトコルと PCI-E プロトコルに基づいています。グラフィックス カードはすべて PCI-E プロトコル経由でコンピュータに接続されるようになりました。相対的に言えば、学ばなければならない知識が大幅に減ります。仮想化に取り組むには、PCI プロトコルを深く理解する必要があります。

画像処理 -- 画像圧縮、リアルタイムビデオエンコードなど。

3Dゲーム

リレーショナルデータベース

NoSQLデータベース

オペレーティングシステム

分散オペレーティングシステム

コンパイル原理

機械学習 - 今すぐビッグデータを使用する必要があります!

これらの分野の知識を理解することには、この分野の既存の商用ハードウェア、商用ソフトウェア、オープンソース ソフトウェアを理解することも含まれます。多くの場合、完了したい作業には既製のツールがすでに用意されています。既製のツールを使用するだけで作業を完了でき、開発は必要ありません。場合によっては、既存のツールを組み合わせてスクリプトを作成するだけでタスクを完了することができます。

たとえば、一度に双方向の同期タスクを実装したいと考えています。優れたオープンソース ソフトウェア Unison を見つけ、設定ファイルを作成し、タスクを正常に完了しました。コードを記述する必要はありません。

また、高可用性を実現するために、Python を使用していくつかのオープンソース ソフトウェアを呼び出したところ、簡単に実現できました。

インストール プログラムを作成し、オペレーティング システムをカスタマイズします。オペレーティング システムの専門知識がわかれば、数行のスクリプトを作成するだけで簡単に実行できます。

ドメイン知識のない人は、多くの不必要な開発を実行しなければならない可能性があり、長い時間が経ってからこれが行き止まりであることに気付く可能性もあります。

さらに、確かなドメイン知識により、プログラミングのデバッグ機能とエラー チェック機能が大幅に向上します。コンパイラーとプログラミング言語ランタイムがどのように動作するかを理解すると、コンパイル エラーや警告に基づいてコードを迅速に変更できます。

オペレーティングシステムの基礎となる動作メカニズムを知ることで、ランタイムエラーの根本原因をすぐに見つけることができます。たとえば、かつて私は Windows アップグレード サービス プログラムを作成しました。これは Windows サービスであり、dos スクリプトを実行する必要があります。このスクリプトは Windows サービス自体を置き換えます。スクリプトの実行が無効になる場合があることがわかりました。一晩中確認したところ、Windows サービスのインストール後、初めてスクリプトを実行するときに権限の問題が発生することがわかりました。ログは正しいのですが。実際のスクリプトの実行には影響はありませんでした。ただし、Windows サービス プログラムが一度起動すれば、問題はありません。これは、Windows オペレーティング システムの基礎となるセキュリティ メカニズムに問題があるに違いありません。私は Windows カーネルについてあまり詳しくないため、この問題を発見するまでに長い時間がかかり、この根本的な原因はわかりません。問題。

パラグラフ 0 - ドメイン知識の新人

私はドメイン知識についてあまり知識がありません。検索エンジンでこの分野のソフトウェアとハ​​ードウェアに関する入門記事を見つけ、記事の指示に従ってソフトウェアを設定して使用します。 。既存のソフトウェアとハ​​ードウェアをほとんど使用できません。

レベル 1 - ドメイン知識エキスパート

現場で一般的に使用されるハードウェアを理解し、現場で一般的に使用されるソフトウェアの構成と使用スキルを深く習得しています。既存のソフトウェアやハードウェアを活用したソリューションを上手に構築し、実際の業務で遭遇するさまざまな問題を解決できる。

第 2 段落 - ドメイン知識の専門家

この分野のソフトウェアとツールをマスターし、その使用方法を知っているだけでなく、その原則、「それが何であるか、そしてなぜそうなのかを知っている」場合、あなたは専門家です。この分野の知識のある専門家。

ネットワークプロトコルの原理を知っている場合にのみ、ネットワークに問題が発生したときに問題がどこにあるのかを知ることができます。 MAC の競合、IP の競合、またはネットワーク ループですか?

ストレージの原理を知って初めて、なぜこのストレージ方法が仮想化に適していないのか、どのストレージ方法が仮想化に適しており、他の方法がデータバックアップに適しているのかを知ることができます。

PCI プロトコルを知っている場合にのみ、ハードウェア デバイスを仮想化する方法を知ることができます。

ネットワークカードのハードウェアプロトコルを知っている場合にのみ、仮想マシンが通常に使用できる仮想ネットワークカードをシミュレートできます。

ビデオのエンコード形式と原則を知っている場合にのみ、どのビデオ形式が最も少ない帯域幅を使用し、どのビデオ形式が最も少ない CPU を使用するかを知ることができます。

IntelVT/Amd V 命令セットを理解している場合にのみ、仮想化がどのように実装されているかを知ることができます。

ワークフローが実際にはステートマシンであることを理解した上で、複雑なワークフローに遭遇したときにのみ、要件を満たすワークフロー エンジンを設計する方法を知ることができます。

パラグラフ 3 - 科学者

あなたはドメイン知識の専門家ですが、知識はすべて本や他の人から得たものです。

専門分野の知識の専門家であることに満足している場合は、他人の知恵を拾うことしかできず、それを超えようとすることは決してありません。自分の研究結果をあなたに話したがらない人もいるかもしれません。誰かがあなたに教える頃には、最新の理論が発見され、新世代の製品がリリースされようとしているかもしれません。

科学者は未知を探究し、革新する勇気を持ち、人類社会の進歩を促す人々です。

伝説によると、シスコの幹部はかつて冗談半分でこう言ったそうです、「もしシスコが新技術の開発を止めたら、ファーウェイは方向性を見出すことができなくなるだろう」。これはファーウェイを揶揄したもので、ファーウェイはドメイン知識の専門家のレベルにすぎず、模倣することはできてもそれを超えることはできない。ファーウェイの実際の状況は分かりませんが、今ではファーウェイがトップランナーの地位に達していることを願っています。

アーヴィング・ジェイコブスはCDMA符号分割多元接続の原理を発見し、それが通信に大きな可能性を秘めていることを発見し、クアルコムを設立しました。クアルコムは主に特許ライセンス料で生活しており、通信分野の研究を行うために多数の科学者を雇用している。クアルコムは特許トロールだと言う人もいます。こういう人たちは知識の価値を理解していません。彼らの目には、Windows の適正価格は CD 1 枚の価格である 5 元であるはずです。 iPhone の価格はベアメタルデバイスで 1,000 元を超えるはずです。クアルコムは特許トロールだから、あなたも CDMA と LTE をトロールしてみませんか?

X86チップは仮想化を念頭に置いて設計されていません。したがって、いわゆる「仮想化の脆弱性」が発生します。つまり、一部の CPU 特権命令が実行された場合、仮想マシン環境では例外がスローされないため、ホストに切り替えることができません。このように、仮想マシンは X86 チップ上で実行できません。

VmWare社は1998年に米国の数人の科学者によって設立されました。彼らは、バイナリ変換テクノロジを使用して、x86 コンピュータ上で仮想マシンを実行できることを発見しました。

Xen仮想化ソフトウェアも数人の科学者によって発明されました。彼らは、仮想マシン オペレーティング システムとホスト オペレーティング システムのカーネルが変更され、「仮想化の脆弱性」命令を実行する必要があるときにホストの関数が直接呼び出されさえすれば、仮想化が実現され、実行パフォーマンスが向上することがわかりました。仮想マシンは大幅に改善されるでしょう。

その後、Intel は IntelVT 命令セットを自社チップに追加し、Amd は AmdV 命令セットを自社チップに追加して、「仮想化の抜け穴」を補いました。そこで、CPU ハードウェア命令を直接使用して仮想化を実装する KVM 仮想マシン ソフトウェアがあります。

KVMがCPU命令を実行する場合、物理CPU上で直接実行されるため、非常に効率的です。ただし、仮想マシンが仮想ペリフェラルを実行する場合、ソフトウェアによってシミュレートする必要があるため、仮想マシンの IO アクセス速度は非常に遅くなります。

IBM の科学者 Rusty Russell は、Xen の研究開発経験を活用して VirtIO テクノロジーを作成しました。これは、一連の PCI 仮想デバイスとドライバーを仮想マシンに書き込むことです。この一連の仮想 PCI デバイスには、仮想デバイス メモリがあります。この仮想デバイス メモリ ホストはアクセス可能であり、仮想マシンは VirtIO ドライバーを通じてアクセスすることもできます。つまり、メモリの一部が仮想マシンとホスト間で共有され、仮想マシンの IO パフォーマンスの問題が解決されます。

別の検索エンジンの話をしてください:

昔、私はプログラムに検索機能を追加したいと思っていました。 SQL クエリの実装を使い始めたところ、遅すぎることがわかりました。その後、オープンソースの Lucene プロジェクトを見つけました。逆インデックス技術を使用しており、ファイル内に逆インデックスを作成することで検索速度が大幅に向上します。

Google の 2 人の創設者は、HTML におけるリンクの秘密を発見し、HTML ページのリンク関係によって各 HTML ページの重みを設定できることを発見しました。それが PageRank アルゴリズムです。その結果、Google の自動検索エンジンは、Yahoo の手動で分類された検索エンジンを打ち負かしました。

OK、逆インデックス技術と PageRank、そして単純な HTML クローラー ロボットを使用して、検索エンジンを作成できます。しかし、インターネットは巨大であり、毎日大量の新しい Web ページが生成されるため、インターネット全体の逆インデックスを構築することは困難です。

数年後、Google はさらに 3 つの論文、Googlefs、Mapreduce、Bigtable を発表しました。そこで、Lucene プロジェクトの開発者は、Google の Mapreduce 論文に基づいて Hadoop プロジェクトを開発しました。 MapReduce は多数のコンピューターを使用してデータを保存し、計算を実行し、最終的に結果を要約します。 Hadoop+逆インデックス+PageRankを利用して検索エンジンを作成できます。 Yahoo、Baidu、その他の企業は、Hadoop に基づいて独自の検索エンジンを開発しました。

しかし、他社の検索エンジンの効果はまだまだGoogleには及びません。これは私たちプログラマーが一番よく知っています。私と同じように、Google を求めていつも壁の外に出ます。

Wu Jun 博士の記事の一部が Google Blackboard に掲載され、多くの機械学習の知識が紹介されました。記事からもわかるように、Googleは実際に機械学習を利用して収集したページを分析しています。 Google は明らかにこの計算式を公開しません。たとえいつか Google が本当にこの計算式を公開したとしても、そのとき Google は間違いなくもっと鋭い秘密を開発するだろうと考えられますし、模倣製品の検索エンジンへの効果は依然として Google ほどではないでしょう。

模倣はイノベーションへの唯一の方法です。その分野のリーダーになる前に、学習と模倣の段階を経なければなりません。しかし、業界のボスになるには、チャンピオンになるには、コーナーで他の人を追い越し、革新の道に勇敢に乗り出し、真の科学者、真の専門家になるのに十分な勇気が必要です。

まとめ

プログラミング能力は、プログラミングスキルのレベルと、ドメイン知識のレベルの2つの側面に分けることができます。

プログラマーの中には、プログラミングのスキルを向上させることにすべてのエネルギーを費やし、その分野についての知識がほとんどない人もいるかもしれませんが、これは実際、日常の業務において非常に有害です。一部のニーズには、既製のオープンソースの無料ソリューションがすでに存在する場合もあれば、既存のソフトウェアをいくつか組み合わせるだけですぐに解決できる場合もありますが、自社で開発するには多くの時間を費やす必要があります。さらに、ドメイン知識が不足していると、プログラムで予期しない状況が発生したときに、問題の原因を迅速に特定してバグを解決することが困難になります。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。