ホームページ  >  に質問  >  本文

http - 如何通过 debugging 来学习软件的运行原理?

第一次在 SegmentFault 提问,请多关照 ^^

这个问题可能有点泛泛,请先让我具体描述一下。我是一个编程小白初学者(本职是设计,编程是好奇心作祟),不过我也系统学习了 HTTP 以及一些基本的编程技术,最近经人介绍学起了 Rails 才逐渐了解和学习到编程方方面面的知识,很喜欢,刚刚跟着一个教程编写了一个非常简单的注册/登录功能,目前工作良好。

然而我的导师(带我入门的朋友)跟我说:

在 Web 开发中,身份校验是非常典型的功能,所有的 Web 开发框架都会提供哪怕是最基本的支持,同样也有很多第三方的插件和扩展包来提供更丰富的接口和功能。尝试学习和了解经典的身份校验原理对于 Web 开发者来说简直就是必修课。比如你刚才实现的东西,行话说就是:'基于 cookie 的认证机制'。你觉得不难,那是因为 Rails 帮你做了很多很多事情,而你做的只是最表层的,也是最简单的一些必要步骤而已。有机会的话,不妨试试去跟踪登录时框架的全过程,对你大有裨益的。

以上是他的原话(略作整理),我听了以后第一感觉好像很有道理……于是我问他怎么跟踪这个过程,但由于我们通讯不便(在外地旅游),他只给我讲了一些很抽象很难懂的要点。他建议我上这里来问问各路英雄,遇见类似的问题(不限定于注册/登录,也不限定于 Rails/Ruby),如果你们需要跟踪源代码来学习和理解某一个具体的功能实现,一般会怎么做?有什么要注意的事项或技巧呢?

其实我自己知道是要用到 debugging 的技术的,一些基本的技术我之前也学习过,至少知道如何给自己写的代码打断点,然后查看运行时的变量值或者步进/跳转之类的。但是就上述问题来说,当我登录的时候,我并不知道(举例) Rails 框架何时何地向我的浏览器发送 cookie 等等,在这种情形下,面对庞大的框架(随便看看就头晕)我要如何找到下手的地方呢?

真心请教各位学长前辈们,希望能从你们身上获得宝贵的启发和经验,谢谢!

伊谢尔伦伊谢尔伦2761日前628

全員に返信(2)返信します

  • 阿神

    阿神2017-04-22 09:01:18

    個人的な意見ですので、ご参考までに。
    デバッグとコードを使用することはフレームワークを学ぶのに良い方法ですが、http プロトコル自体に慣れていない場合、これを実装するフレームワークを見ることは聖書を読むようなものです。

    例えばこの本人確認。
    まず、ほとんどの場合、http は短い接続であることを知っておく必要があります。クライアント (ほとんどの場合、ブラウザ) は http サーバーとの接続を確立し、データを送信し、サーバーから返されたデータを取得します。接続が切断されました。
    次に、http 通信のデータはリクエスト (Request) とレスポンス (Response) に分けられ、リクエストはクライアント (サーバー) から送信され、レスポンスはサーバーからクライアントに返されることを知っておく必要があります。リクエストとレスポンスはヘッダーとコンテンツ(Content)に分かれており、ヘッダーは必須で、コンテンツは空でも構いません

    上記2点を理解した上で、本人確認について見ていきましょう。
    本人確認は大きく2つのプロセスに分かれます:
    1. ユーザーログイン
    2. ユーザーが他のリソースにアクセスすると、ユーザーの ID を取得し、そのユーザーがこのリソースにアクセスできるかどうかを判断します。

    前述したように、http はほとんどの場合短い接続であり、上記のシナリオも短い接続です。

    ユーザーはログインして他のリソースにアクセスしますが、これは明らかに 2 つの接続です。
    この場合、サーバーは両方の接続がユーザーからのものであると判断できないため、リソースに 2 回目に接続するときにユーザー ID を取得するにはどうすればよいでしょうか?
    この問題を解決するために、http プロトコルでは Cookie が規定されています。

    最初の接続 - ユーザーのログイン処理時、ユーザーがログインに成功すると、サーバーの応答ヘッダー (Response) には、ユーザーの情報が含まれる Set-Cookie ヘッダーが含まれます。これは、クライアントがいくつかの Cookie を保存し、次のように規定していることを示します。どのような状況で (詳細については Cookie 規定を参照)、クライアントがこれらの Cookie をクライアントに送り返す必要があるか。

    2 回目の接続中 - リソースにアクセスするとき、Cookie を送信するための条件が満たされるため、クライアントは Cookie を Cookie ヘッダーとしてリクエスト (Request) のヘッダーに配置します。このように、サーバーはリクエスト ヘッダーを解析して Cookie を取得し、そこからユーザーの情報も取得します。

    これは、本人確認の基本的な実装プロセスです。

    このうち、ブラウザはレスポンスヘッダーのSet-Cookieを処理し、Cookieを保存し、条件が満たされた場合にリクエストヘッダーにCookieを入れてサーバーに送信します。

    応答ヘッダーに Set-Cookie を配置し、要求ヘッダーから Cookie 情報を読み取ることは、使用するフレームワークによって実装される場合があります。

    ////////// 回答に返信を追加 //////////
    質問者が回答した後、質問者と話し合った内容を回答に追記しました。
    上で述べたことは、フレームワークを理解するための前提条件です。つまり、まずフレームワークが何を行ったかを理解し、次にフレームワークがこれらのことをどのように行うかを検討する必要があります。
    以下はディスカッションの内容ですので、そのままコピペしてみました
    私の一般的な理解について話させてください。Web フレームワークは、リクエストのデコードと、レスポンスのエンコードとカプセル化を担当します。開発者がロジックを記述する必要がある場合、パラメータを取得してデータを返すだけで済みます。リクエストからパラメータを取得する方法と、返された結果をレスポンスにエンコードする方法はすべてフレームワークによって行われます。
    したがって、一般的には、作成したロジックの最初と最後にブレークポイントを設定し、フレームワーク内の処理をたどることができます。
    最後にブレークポイントを設定することから始めましょう。これは比較的簡単です。ロジック処理が完了してデータが返された後、データはフレームワークに渡されて処理されるため、この時点でフレームワークの内部を追跡できます。シングルステップ トレースを通じてコードを作成し、データがフレームワークによって処理されることをステップごとに確認します。
    もう 1 つは、最初にブレークポイントを設定することです。この時点で、フレームワークの処理部分は実際に実行されていますが、一般的なデバッグ ツールではコール スタックを使用して、フレームワークが以前に実行したコードを確認できます。次に、ロジック コードを実行して、リクエストが到着したコードを見つけて、ここにブレークポイントを設定し、リクエストを再度送信して、ステップごとに実行します。
    開始コードと終了コードに従うと、フレームワーク全体の処理フローをすでに理解していることになります。

    返事
    0
  • 天蓬老师

    天蓬老师2017-04-22 09:01:18

    まず、どの言語でもデバッグは必要です。言語に適切なデバッグ ツールが提供されていない場合。だから言語はクソだ。特に、必要のないいわゆるデバッグが嫌いです。書かれたとおりにコンパイルされるプログラム。

    何かを学ぶ方法は。まずは入門書をざっと見てみましょう。もう一度読んでください。概念を理解するだけです。その後、必要に応じてコーディングします。最初のものは正常にコンパイルできます (C++)。または (Python) を実行することもできます。この状態。主に IDE のエラー修正機能に依存します。

    IDEエラー修正が完了するまで待ちます。走行後にはさまざまな問題が発生します。主にロジック エラーまたは SegmentFault (C++)。
    このとき何をすべきか。コードを何度も見るのは耐えられません。

    一般的に初心者に教える人もいます。 Printf/System.Out.println/print/ およびその他の出力を使用して、各変数が正常であり、必要な値があるかどうかを確認します。
    これらは経験豊富な人には耐えられないものであり (プログラマーの 3 つの美徳 (イライラ、怠惰、傲慢) のうちの最初の 2 つの要件)、Print を書くのは非常に疲れます。また、公開され次第削除させていただきます。さらに、一部の呼び出しインターフェイスは戻り値を知りません。 printfを作成して実行します。時間とエネルギーがかかります。

    では、熟練した人は何をしているのでしょうか?デバッグ。これは、投稿者が言及したデバッグのソースです。
    もう印刷する必要はありません。各データが正常かどうかを直接確認できます。希望の値ですか。
    Java/C++ で。デバッグは大丈夫です。
    関数の戻り値や効果がわかりません。デバッグ中。実行する必要がある環境で停止します。テスト機能。対応する戻り値を知ることができます。書き続ける方法を知る。
    スタック上で実行時エラーが発生した場合は、対応するスタックにブレークポイントを直接設定します。どのコード部分が問題を引き起こしているのでしょうか?どの変数に null 値があるのか​​が一目でわかります。
    プログラムを実行するプロセスもあります。いくつかの操作を行いました。デバッグを制御することで、コード実行プロセスを追跡することもできます。これが投稿者が言っていた学習機能です。

    しかし、これは単なるデバッグです。
    後ろにはさらに 2 つあります:
    1 つはログです。オンラインでデバッグすることはできません。何か問題が発生した場合の対処方法。問題だと思うことを記録しておくと、いざというときにバグを見つけることが明確になります。 。
    1 つはテストです。単体テストのみです。テストは、コードが正常であることを確認するもう 1 つの方法です。たとえば、プロジェクトのごく一部を書きます。この部分の主な機能は非常に遠いところにあります。コードには非常に特殊な状況のみが関係します。 (もちろん、Java/Python では無制限の Main 関数を作成できますが、一部の関数は作成できません)。ただし、単体テストを作成した後です。単体テストから直接開始します。親切。必要な入力と出力をシミュレートします。機能エラーは時間内に発見できます。大きなプロジェクトをすべて書き出す必要はありません。次に、無数のスタックでエラーを探しました。
    また、単体テストにより、特定の環境でのバグを排除できます。たとえば、コードはコンピュータ上で通常どおり実行されます。全員満足。ただし、他のコンピュータでは正常に動作しません。単体テストを使用すると、コードのどの部分に問題があるかをすぐに見つけることができます。

    ここまで来たら。あなたはすでにプログラマーの資格を持っていると思います。

    しかしマスターにはあと2つあります。パフォーマンステストとパフォーマンス分析。ここまで。各言語に関する深い知識、または仮想マシンの基礎知識が必要です。私のような初心者のため、多くは言いません

    返事
    0
  • キャンセル返事