>  Q&A  >  본문

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

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

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

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

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

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

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

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

伊谢尔伦伊谢尔伦2712일 전583

모든 응답(2)나는 대답할 것이다

  • 阿神

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

    개인적인 의견이니 참고용으로만 사용하세요.
    디버깅과 코드를 활용하는 것은 프레임워크를 배우는 좋은 방법이지만, 기본 지식을 이해하는 것이 전제입니다. http 프로토콜 자체에 익숙하지 않은 경우 이를 구현하는 프레임워크를 보는 것은 성경을 읽는 것과 같습니다.

    예를 들어 신원 확인이요.
    우선, 대부분의 경우 http는 짧은 연결이라는 것을 알아야 합니다. 클라이언트(대부분의 경우 브라우저)는 http 서버와 연결을 설정하고 데이터를 보낸 다음 서버에서 반환된 데이터를 받습니다. 연결이 끊어졌습니다.
    둘째, http 통신에서 데이터는 요청(Request)과 응답(Response)으로 구분된다는 것을 알아야 합니다. 요청은 클라이언트에서(서버로) 전송되고, 응답은 서버에서 클라이언트로 반환됩니다. 요청과 응답은 헤더(Header)와 응답(Response)으로 구분되며, 헤더는 필수이며, 내용은 비어 있을 수 있습니다.

    위 두 가지 사항을 알아본 후, 본인 인증에 대해 살펴보겠습니다.

    신원 확인은 크게 두 가지 과정으로 나누어집니다.
    1. 사용자 로그인
    2. 사용자가 다른 리소스에 액세스하면 사용자의 신원을 파악하고 해당 리소스에 액세스할 수 있는지 여부를 결정합니다.

    위에서 언급했듯이 http는 대부분의 경우 짧은 연결이고, 위의 시나리오도 짧은 연결입니다.

    사용자는 로그인하고 다른 리소스에 액세스합니다. 이는 분명히 두 개의 연결입니다.
    그러면 서버는 두 연결이 모두 사용자로부터 온 것인지 확인할 수 없습니다. 그러면 두 번째로 리소스에 연결할 때 사용자 ID를 어떻게 얻습니까?
    이 문제를 해결하기 위해 http 프로토콜은 쿠키를 규정합니다.

    첫 번째 연결 중 - 사용자 로그인을 처리할 때 사용자가 성공적으로 로그인하면 서버의 응답(Response) 헤더에 사용자 정보가 포함된 Set-Cookie 헤더가 포함되어 클라이언트가 일부 쿠키를 저장함을 나타냅니다. 클라이언트가 이러한 쿠키를 클라이언트에게 다시 보내야 하는 상황(자세한 내용은 쿠키 조항 참조)을 규정합니다.

    두 번째 연결 중 - 리소스에 액세스할 때 쿠키 전송 조건이 충족되었으므로 클라이언트는 요청(Request) 헤더에 쿠키를 쿠키 헤더로 넣습니다. 이런 방식으로 서버는 요청 헤더를 구문 분석하여 쿠키를 가져오고, 여기에서 사용자 정보도 가져옵니다.

    이것은 신원 확인의 기본 구현 프로세스입니다.

    그 중 브라우저는 응답 헤더에서 Set-Cookie를 처리하고 쿠키를 저장한 후 요청 헤더에 쿠키를 넣어 조건이 만족되면 서버로 보냅니다.

    응답 헤더에 Set-Cookie를 배치하고 요청 헤더에서 쿠키 정보를 읽는 것은 사용하는 프레임워크에 의해 구현될 수 있습니다.

    ////////// 답변에 답변 추가 //////////
    질문자 답변 후 질문자와 논의한 내용을 답변에 추가하였습니다.
    위에서 언급한 내용은 프레임워크를 이해하기 위한 전제 조건입니다. 즉, 먼저 프레임워크가 수행한 작업을 이해한 다음 프레임워크가 이러한 작업을 수행하는 방법을 살펴봐야 합니다.
    다음은 토론 내용인데, 게을러서 직접 복사해서 붙여넣었습니다.
    나의 일반적인 이해에 대해 이야기하겠습니다. 웹 프레임워크는 요청의 디코딩과 응답의 인코딩 및 캡슐화를 담당합니다. 개발자가 로직을 작성해야 하는 경우 매개변수를 가져오고 데이터를 반환하기만 하면 됩니다. 요청에서 매개변수를 가져오는 방법과 반환된 결과를 응답으로 인코딩하는 방법은 모두 프레임워크에서 수행됩니다.
    따라서 일반적으로 작성하는 논리의 시작과 끝 부분에 중단점을 설정한 다음 프레임워크 내부의 처리를 따를 수 있습니다.
    먼저, 마지막에 중단점을 설정합니다. 논리 처리가 완료되고 데이터가 반환된 후 처리를 위해 프레임워크로 전달되기 때문에 비교적 간단합니다. 단일 단계 추적을 통해 데이터가 프레임워크에 의해 처리되는 것을 단계별로 관찰합니다.
    다른 하나는 처음에 중단점을 설정하는 것입니다. 이때 프레임워크의 처리 부분이 실제로 실행되었지만 일반 디버깅 도구에서는 호출 스택을 사용하여 이전에 프레임워크가 어떤 코드를 실행했는지 확인할 수 있습니다. 그런 다음 요청이 방금 도착한 코드를 찾아 여기에 중단점을 설정하고 요청을 다시 보낸 다음 단계별로 따르세요.
    시작 코드와 종료 코드를 따라가면 전체 프레임워크의 처리 흐름을 이미 이해할 수 있습니다.

    회신하다
    0
  • 天蓬老师

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

    우선 모든 언어에는 디버깅이 필요합니다. 언어가 좋은 디버깅 도구를 제공하지 않는 경우. 그러니 언어는 똥이다. 특히 나는 필요하지 않은 소위 디버깅을 싫어합니다. 작성된 대로 컴파일되는 프로그램입니다.

    무언가를 배우는 방법은. 먼저 소개서부터 간단히 살펴보겠습니다. 다시 읽어보세요. 개념만 이해하시면 됩니다. 그런 다음 필요에 따라 코딩합니다. 첫 번째 항목은 성공적으로 컴파일될 수 있습니다(C++). 또는 (파이썬)을 실행할 수 있습니다. 이 상태. 주로 IDE 오류 수정 기능에 의존합니다.

    IDE 오류 수정이 완료될 때까지 기다리세요. 실행 후 다양한 문제가 발생합니다. 주로 논리 오류 또는 SegmentFault(C++)입니다.
    이때 해야 할 일. 코드를 계속해서 보는 것은 참을 수 없습니다.

    일반적으로 어떤 사람들은 초보자에게 말합니다. Printf/System.Out.println/print/ 및 기타 출력을 통해 각 변수가 정상인지, 원하는 값이 있는지 확인합니다.
    이것은 숙련된 사람들(프로그래머의 세 가지 미덕(과민성, 게으름, 오만함) 중 처음 두 가지에 대한 요구 사항)에게는 참을 수 없는 일이며, Print를 쓰는 것은 매우 피곤한 일입니다. 게시되면 삭제됩니다. 그리고 일부 호출 인터페이스는 반환 값을 모릅니다. printf를 만들고 실행해 보세요. 시간과 에너지가 필요합니다.

    그렇다면 숙련된 사람은 어떤 일을 할까요? 디버그. 이는 원본 포스터에서 언급한 디버그 소스입니다.
    더 이상 인쇄할 필요가 없습니다. 각 데이터의 정상 여부를 직접 확인할 수 있습니다. 원하는 값인가요?
    자바/C++에서. 디버그는 괜찮습니다.
    함수의 반환 값이나 효과를 알 수 없습니다. 디버깅. 실행이 필요한 환경에서는 중지하세요. 테스트 기능. 해당 반환 값을 알 수 있습니다. 계속해서 글을 쓰는 방법을 알아보세요.
    스택에 런타임 오류가 발생하면 해당 스택에 직접 중단점을 설정합니다. 어떤 코드가 문제를 일으키는가? 어떤 변수에 null 값이 있는지 한눈에 알 수 있습니다.
    프로그램을 실행하는 과정도 있습니다. 몇 가지 작업을 수행했습니다. 디버그를 제어하여 코드 실행 프로세스를 추적할 수도 있습니다. 포스터에서 언급한 학습 기능입니다.

    하지만 이것은 단지 디버그일 뿐입니다.
    마지막에는 두 가지가 더 있습니다:
    하나는 로그입니다. 온라인으로 디버깅할 수 없습니다. 문제가 발생하면 어떻게 해야 할까요? 문제라고 생각하는 내용을 기록해두면 때가 되면 버그를 찾는 것이 명확해질 것입니다. .
    하나는 테스트입니다. 단위 테스트만 가능합니다. 테스트는 코드가 올바른지 확인하는 또 다른 방법입니다. 예를 들어, 프로젝트의 아주 작은 부분을 작성합니다. 이 부분의 주요 기능은 아주 멀리 떨어져 있습니다. 코드에는 매우 특별한 상황만 포함됩니다. (물론 Java/Python은 무제한의 Main 함수를 작성할 수 있지만 일부는 그렇지 않습니다.) 하지만 단위 테스트를 작성한 후에는 말이죠. 단위 테스트로 직접 시작하세요. 친절. 원하는 입력과 출력을 시뮬레이션합니다. 기능 오류는 시간이 지나면 발견될 수 있습니다. 큰 프로젝트를 전체적으로 작성할 필요는 없습니다. 그런 다음 수많은 스택에서 오류를 찾았습니다.
    또한 단위 테스트는 특정 환경에서 버그를 제거할 수 있습니다. 예를 들어 코드는 컴퓨터에서 정상적으로 실행됩니다. 모두 만족합니다. 하지만 다른 컴퓨터에서는 제대로 작동하지 않습니다. 단위 테스트를 사용하면 어떤 코드 부분에 문제가 있는지 빠르게 확인할 수 있습니다.

    여기에 도착했다고 가정해 보겠습니다. 나는 당신이 이미 자격을 갖춘 프로그래머라고 믿습니다.

    하지만 마스터에게는 두 가지가 더 있습니다. 성능 테스트 및 성능 분석. 이 시점까지. 각 언어에 대한 심층적인 지식이나 가상 머신에 대한 기본 지식이 필요합니다. 저 같은 초보자에게는 많은 말을 하지 않겠습니다

    회신하다
    0
  • 취소회신하다