ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 실용주의 프로그래머 - 3장 기본 도구
    Study 2023. 6. 18. 19:31
    • 모든 제작자(maker)는 모두 좋은 품질의 기본 도구 세트가 필요하다.
    • 언제나 일을 하는데 더 나은 방법이 없는지 살펴라.
    • 필요에 따라 도구를 취하도록 하라.
    • 많은 신참 프로그래머가 특정 통합 개발 환경(IDE) 같은 강력한 도구 하나만 고집하는 실수를 저지르고, 그 익숙한 인터페이스에서 떠날 생각을 하지 않는다.
      • 우리는 IDE가 갖는 한계를 넘어설 수 있어야 한다.
      • 유일한 방법은 기본 도구들을 언제나 곧바로 사용할 수 있도록 예리하게 유지하는 것이다.

    Topic 16. 일반 텍스트의 힘

    • 실용주의 프로그래머로서 우리의 기본 재료는 나무나 쇠가 아니라 지식이다.
    • 우리가 수집하는 요구 사항은 지식이고, 우리는 그 지식을 설계와 구현, 테스트, 문서로 표현한다.
      그리고 우리는 지식을 저장하는 최고의 포맷이 일반 텍스트(plain text)라고 믿는다.
    • 일반 텍스트를 사용하면 수작업으로든 프로그램으로든 동원 가능한 거의 모든 도구로 지식을 다룰 수 있게 된다.
      • 데이터가 데이터를 만드는 애플리케이션에 독립적인 것이다.

    일반 텍스트란?

    • 일반 텍스트는 사람이 이해할 수 있어야 한다.

    Tip 25. 지식을 일반 텍스트로 저장하라.

    텍스트의 힘

    • 일반 텍스트가 형식이 없는 텍스트를 의미하는 것은 아니다.
    • HTML, JSON, YAML 등은 모두 일반 텍스트이다.
    • HTTP, SMTP, IMAP 등 인터넷에서 사용되는 핵심 프로토콜도 대부분 일반 텍스트다.
    • 이렇게 일반 텍스트가 널리 쓰이는 이유는 다음과 같다.
      • 지원 중단에 대한 보험
        • 사람이 읽을 수 있는 형태의 데이터와 그 자체만으로 의미가 드러나는 데이터는 다른 어떤 형태의 데이터보다, 심지어 그 데이터를 생성한 애플리케이션보다 더 오래 살아남을 것이다.
      • 기존 도구의 활용
        • 버전 관리 시스템에서 에디터, 명령 줄 도구에 이르기까지 컴퓨터 세계의 거의 모든 도구는 일반 텍스트를 다룰 수 있다.
        • 유닉스 철학
          • 유닉스(Unix)는 작고 예리한 각각의 도구가 한 가지 일만 잘하도록 만들자는 철학에 따라 설계된 것으로 유명하다.
            이 철학은 줄 단위로 처리하는 일반 텍스트 파일을 기반 포맷으로 공유하기 때문에 가능해졌다.
      • 더 쉬운 테스트
        • 시스템 테스트에 사용할 합성 데이터를 일반 텍스트로 표현하면 특별한 도구를 만들 필요 없이 간단하게 테스트 데이터를 추가하거나 수정할 수 있다.

    최소 공통분모

    • 모든 참가자가 하나의 공통 표준을 사용해서 소통하도록 해야 한다.
    • 일반 텍스트가 바로 그 표준이다.

    도전해 볼 것

    • 원하는 언어를 사용해서 단순한 이진 형식을 사용하는 자그마한 주소록 데이터베이스(이름, 전화번호 등)를 설계해 보라.
      다음을 읽기 전에 직접 해보자
      • XML이나 JSON을 사용해서 포맷을 일반 텍스트로 바꿔 보라.
      • 이진 형식 버전과 일반 텍스트 버전에 각각 그 사람의 집으로 가는 길을 입력하는 '찾아가는 길'이라는 가변 길이 필드를 새로 추가하라.
    • 버전 관리와 확장성 면에서 어떤 문제가 생기는가? 어떤 형태가 수정이 용이했는가? 기존 데이터를 변환하는 것은 어땠는가?

    Topic 17. 셸 가지고 놀기

    • 모든 목수는 훌륭하고 튼튼하며 믿을 만한 작업대가 필요하다.
    • 텍스트 파일을 다루는 프로그래머에겐 명령어 셸이 작업대이다.
    • 셸 프롬프트에서 모든 종류의 도구를 불러다 쓸 수 있다.
    • 파이프를 이용해 원 개발자가 꿈도 꾸지 못했을 방식으로 도구를 결합할 수도 있다.
    • GUI와 IDE만 사용해서는 도구를 결합해서 자신에게 꼭 맞는 '매크로 도구'를 만들 수 없다.
    • GUI의 장점은 WYSIWYG(What You See Is What You Get)이고 단점은 WYSIAYG(What You See Is All You Get)이다.
    • GUI 환경의 기능은 일반적으로 설계자가 의도한 범위를 넘어설 수 없다.
    • 실용주의 프로그래머는 오직 코드만 쏟아 내거나, 객체 모델만 개발하거나, 문서만 작성하거나, 빌드 과정 자동화만 하지는 않는다.
      이 모든 일을 다 한다.

    Tip 26. 명령어 셸의 힘을 사용하라.

    • 셸에 익숙해지면 우리의 생산성이 급상승할 것이다.

    자신만의 셸

    • 목수가 작업 공간을 자신에게 맞추어 바꾸듯이 개발자도 셸을 자신에게 맞추어야 한다.
    • 보통 다음 사항들을 바꾼다.
      • 색깔 조합 설정
      • 프롬프트 설정
      • 별칭(alias)과 셸 함수
        • 만날 사용하는 명령어에 간단한 별칭을 만들어서 작업을 단순화하라.
        • 만약 실수로 rm 명령어를 사용하여 파일을 지우는 낭패를 여러 번 보았다면 다음부터는 삭제할 때 확인 과정을 거치도록 별칭을 만들어라.
          alias rm = 'rm -iv'
      • 명령어 자동 완성

    도전해 볼 것

    • 평소 GUI에서 수동으로 하는 작업이 있는가? 동료에게 "이 버튼을 누르세요.", "이 항목을 선택하세요." 같이 여러 단계에 걸친 사용법을 일일이 가르쳐 주는가? 이걸 자동화할 수 있겠는가?
    • 새 환경으로 옮겨갈 때면 언제나 어떤 셸을 사용할 수 있는지 먼저 알아보라. 기존에 사용하던 셸을 그대로 이용할 수 있는지 확인하라.
    • 현재 사용하는 셸의 대안은 없는지 조사하라. 여러분의 셰로 처리할 수 없는 문제를 만난다면 다른 셸은 좀 더 잘 처리할 수 있는지 알아보라.

    Topic 18. 파워 에디팅

    • 텍스트는 프로그래밍의 기본 원재료이므로 우리는 텍스트를 최대한 손쉽게 조작할 수 있어야 한다.
    • 이 책의 1판에서 우리는 하나의 에디터로 코딩, 문서 작성, 메모, 시스템 관리 등 모든 작업을 하라고 추천했었다.
      하지만 이제는 약간 물러서기로 했다. 여러분이 원한다면 에디터를 몇 개 사용하든 상관없다.
      다만 각각의 에디터에 유창해지도록 노력해야 한다.

    Tip 27. 에디터를 유창하게(fluency) 쓸 수 있게 하라.

    • 왜 에디터에 유창해지는 것이 중요할까? 시간을 많이 절약할 수 있어서일까?
    • 진짜 중요한 것은 유창해지는 것의 가장 큰 이점은 더는 에디터 사용법을 생각하지 않아도 된다는 것이다.

    어떤 것이 '유창'한 것인가?

    • 어느 정도 에디터를 써야 유창하다고 볼 수 있을까? 다음 과제들에 도전해 보라
      • 텍스트를 편집할 때 문자, 단어, 줄, 문단 단위로 커서를 이동하거나 내용을 선택하라.
      • 코드를 편집할 때 반대쪽 괄호로 이동하거나, 함수, 모듈 등 다양한 문법 단위로 커서를 이동하라.
      • 변경한 코드의 들여 쓰기(indent)를 자동으로 맞춰라.
      • 여러 줄의 코드를 명령어 하나로 주석 처리했다가 다시 주석을 해제하라.
      • 실행 취소를 여러 번 했다가 취소한 명령을 재실행 기능으로 다시 수행하라.
      • 에디터 창을 여러 구역으로 쪼개라. 그리고 각 구역 사이를 이동하라.
      • 특정 줄 번호로 이동하라.
      • 여러 줄을 선택한 후 가나다순으로 정렬하나.
      • 문자열로, 또 정규 표현식으로 검색하라. 이전에 검색했던 것을 다시 검색하라.
      • 선택 영역이나 패턴 검색을 이용하여 일시적으로 여러 개의 커서를 만든 다음, 동시에 여러 곳의 텍스트를 편집하라.
      • 현재 프로젝트의 컴파일 오류를 표시하라.
      • 현재 프로젝트의 테스트를 실행하라.
    • 이 과제들을 마우스나 트랙패드 없이 모두 수행할 수 있는가?
    • 여러분이 현재 사용하는 에디터로는 수행 불가능한 것이 몇 가지 있다고 할지도 모르겠다. 그렇다면 에디터를 바꿀 때인 것은 아닐까?

    유창해지기

    • 우리의 삶을 편하게 해주는 명령어를 배워라.
      • 삶이 편해지는 방법은 꽤 간단하다.
        • 우리가 에디터를 사용하는 모습을 관찰할라.
        • 무언가 같은 일을 반복하는 것을 발견할 때마다 이렇게 생각하는 습관을 들여라.
        • '분명 더 나은 방법이 있을 텐데' 그리고 더 나은 방법이 있는지 찾아보라.
      • 유창한 기능을 새로 찾았다면 이 기능을 우리의 몸이 기억하도록 만들어야 한다. 그래야 반사적으로 사용할 수 있다.
      • 우리가 아는 유일한 방법은 반복이다.
    • 에디터 성장시키기
      • 강력한 프로그래머용 에디터는 대부분 기본이 되는 핵심부 위에 여러 가지 확장 기능을 얹은 형태로 이루어져 있다.
      • 필요한 기능을 추가하는 확장 기능을 찾아보라.
      • 때로는 더 멀리까지 나아가서 온전한 확장 기능을 만들어 낼 수도 있을 것이다. 그렇다면 그 확장 기능을 공개하라.
      • 우리가 필요한 것은 다른 사람도 필요할 것이다.

    도전해 볼 것

    • 자동 반복은 이제 그만
      • 마지막으로 입력한 단어를 지우고 싶다고 해 보자. 백스페이스키를 누른 다음 손을 떼지 않은 채로 키보드의 자동 반복이 작동할 때까지 기달리 것이다. 누구나 이렇게 한다. 아마 자동 반복을 자주 사용한 탓에 여러분의 뇌는 키보드에서 손을 떼는 타이밍을 정확하게 잴 수 있을 것이다.
      • 이제 자동 반복 기능을 끄자. 대신 문자, 단어, 줄, 문단 단위로 이동하거나 선택, 삭제하는 단축키를 배워라.
    • 마우스나 트랙패드를 치워라.
      • 1주일 동안 키보드로만 에디터를 사용하라.
      • 포인터 이동 후 클릭하는 방식 외에 달리 방법을 모르는 일들이 많이 나타날 것이다. 이제 배움의 시간이다. 새로 배운 단축키를 메모로 남겨라. 구식이지만 종이와 연필 사용을 추천한다.
        며칠간은 생산성이 뚝 떨이질 것이다. 하지만 손을 키보드에서 떼지 않고 일하는 방법을 배워 나갈수록 과거보다 더 빠르고 능숙하게 에디터를 사용할 수 있을 것이다.
    • 우리가 하는 일을 에디터에 통합하는 방법을 찾아라.
    • 우리가 원하는 일을 하는 플러그인이나 확장 기능을 찾을 수 없다면 하나 만들어 보라.
      찾을 수 없다면 만들어라!

    Topic 19. 버전 관리

    진보라는 것은 변화와는 거리가 멀고 오히려 기억에 의존한다. 과거를 기억하지 못하는 사람은 과거를 반복할 운명이다.
    - 조지 산타야나
    • 우리가 사용자 인터페이스에서 중요하게 여기는 것 중에 '실행 취소(undo)' 키가 있다.
      하지만 실수가 지난주에 발생했고 그 이후로 컴퓨터를 열 번은 껐다 켰다면 어떨까? 이것이 바로 버전 관리 시스템(version control system, VSC)을 사용하는 데서 생기는 여러 가지 이득 가운데 하나다.
    • 버전 관리 시스템은 일종의 거대한 '실행 취소' 키와 같다.
    • VCS는 공동 작업, 배포 파이프라인, 이슈 추적에다 일반적인 팀 상호작용까지 아우르는 훨씬 더 큰 세상 가지고 있다.

    공유 디렉토리는 버전 관리 시스템이 아니다.

    소스 코드부터 시작

    • 버전 관리 시스템은 소스 코드나 문서의 모든 변경 사항을 기억한다.
    • 좋은 VCS를 사용하면 변경 사항을 추적하여 코드의 이 줄을 누가 바꿨을까?, 현재 버전과 지난주 버전은 어디가 달라졌나? 이번 릴리스에 코드를 몇 줄이나 바꿨을까? 어느 파일이 가장 자주 바뀌나? 이런 종류의 정보는 버그 추적이나, 감사(audit), 성능 관리, 품질 관리를 해야 할 때 매우 귀중하다.
    • VCS를 사용하면 둘 이상의 사용자가 동일한 파일들을 동시에 작업할 수 있다.

    Tip 28. 언제나 버전 관리 시스템을 사용하라.

    • 언제나. 혼자서 한 주짜리 프로젝트를 진행하는 경우일지라도, 나중에 '버리기로 한' 프로토타입일지라도, 심지어 소스 코드가 아닐지라도, 모든 것을 버전관리 아래 둬라.

    브랜치 사용하기

    • 브랜치는 개발중인 내용을 따로 떼어 격리하는 기능이다.
    • 브랜치에서 작업한 내용은 다른 브랜치로부터 격리되지만, 작업한 브랜치를 나중에 다른 브랜치로 '병합(merge)'할 수도 있다.
    • 브랜치는 프로젝트의 작은 복사본이라고 할 수 있다.

    프로젝트 허브로서의 버전 관리

    • 버전 관리는 팀에서 사용할 때 그 진가가 드러난다.
    • 중앙 저장소 시스템을 사용하는 것을 추천한다.
    • 저장소 관리가 우리 회사의 핵심 업무는 아니므로 외부 서비스 이용을 추천한다.
      다만 다음과 같은 기능이 있어야 한다.
      • 확실한 보안과 권환 관리
      • 직관적인 UI
      • 명령 줄에서도 모든 작업 수행 가능(작업을 자동화할 때 필요하다.)
      • 자동화된 빌드와 테스트
      • 브랜치 병합(풀 리퀘스트(pull request)을 잘 지원
      • 이슈 관리, 커밋이나 브랜치 병합과 연계가 가능하고 지표도 구할 수 있으면 이상적이다.
      • 적절한 보고서 기능, 칸반 보드 형식으로 처리할 이슈나 작업을 표시할 수 있으면 매우 유용하다.
      • 원활한 팀 의사소통을 돕는 기능, 변경 사항이 있을 때 이메일 혹은 다른 수단으로 알려준다든지, 위키를 제공한다든지 하는 등등
    • VCS를 다음과 같이 설정해 놓는 팀이 많다.
      특정 브랜치에 push를 하면 시스템을 빌드하고, 테스트를 수행한 다음, 테스트가 성공하면 새로운 코드를 서비스에 배포한다.
    • 무서운 방식 같은가? 버전 관리 시스템을 사용한다면 걱정하지 않아도 된다. 언제든지 rollback 할 수 있다.

    도전해 볼 것

    • VCS를 사용하면 이전의 어떤 상태로든 롤백할 수 있다는 것을 배웠다. 그런데 정말로 롤백할 수 있는가? 안전하게 롤백하는 명령어를 아는가? 사고가 발생했을 때 압박감 속에서 배우려 하지 말고 지금 미리 익혀 둬라.
    • 예상치 못한 일이 발생했을 때 여러분의 노트북 환경을 복구하는 것에 대해 시간을 두고 고민해 보라. 무엇을 복구해야 할까? 복구해야 하는 것의 대부분은 그냥 텍스트 파일일 것이다. VCS에 들어 있지 않다면 VCS에 추가하는 방법을 찾아라. 노트북 바깥의 VCS를 사용해야 한다. 그다음으로 설치한 프로그램, 시스템 설정 등 다른 것도 생각해 보자. 어떻게 하면 이것들도 텍스트 파일로 표현해서 저장할 수 있을까?
      재미있는 실험을 해 볼 수도 있다. 어느 정도 작업을 한 것 같으면 더 이상 사용하지 않는 오래된 컴퓨터를 한 대 구한 다음, VCS를 활용한 새로운 방식으로 컴퓨터를 설정할 수 있는지 확인해 보라.
    • 지금 사용하고 있는 VCS, 그리고 다른 호스팅 서비스의 기능을 의식적으로 둘러보라. 여러분의 팀이 기능 브랜치를 사용하지 않고 있다면 실험적으로 도입해 보라. 풀 리퀘스트나 병합 요청, 지속적 통합, 빌드 파이프라인, 지속적 배포도 마찬가지다. 위키나 칸반 보드 같은 팀 의사소통 도구도 살펴보라.
      이런 도구들을 꼭 사용해야 하는 것은 아니다. 하지만 결정을 내리려면 적어도 이것들이 무엇을 하는 것인지는 알아야 한다.
    • 프로젝트 이외의 것에도 버전 관리를 사용하라.

    Topic 20. 디버깅

    참으로 고통스러운 일입니다.
    자신이 겪는 어려움을 보고는 알게 되죠.
    다른 누구도 아닌 바로 자신이 문제를 만들었다는 걸.
    - 소포클레스
    • 소프트웨어 결함은 요구 사항을 오해하는 것부터 코딩 오류에 이르기까지 여러 모습으로 나타난다.
    • 아무도 완벽한 소프트웨어를 작성하지 못하므로 하루 대부분을 디버깅으로 보낼 것이라는 건 기정사실이다.
    • 디버깅에 관련된 몇몇 문제를 살펴보고, 꼭꼭 숨어있는 버그를 찾아내는 일반적인 전략을 몇 가지 알아보도록 하자.

    디버깅의 심리

    • 디버깅은 많은 개발자에게 예민하고 감성적인 주제다.
    • 디버깅은 단지 문제 풀이일 뿐이라는 사실을 받아들이고, 그런 마음으로 공략하라.
    • 다른 사람의 버그를 발견한 후, 그 버그를 만들어 낸 부정한 범죄자를 비난하는 데에 시간과 노력을 쏟을 수도 있다.
      하지만 기술의 전당에서는 남을 비난하기보다 문제를 고치는 데에 집중해야 한다.

    Tip 29. 비난 대신 문제를 해결하라.

    • 버그가 우리의 잘못인지 다른 사람의 잘못인지는 중요치 않다.
      어쨌거나 그 버그를 해결해야 하는 사람은 우리다.

    디버깅 사고방식

    가장 속이기 쉬운 사람은 자기 자신이다.
    - 에드워드 불워-리턴
    • 디버깅을 시작하기에 앞서 올바른 마음가짐이 중요하다.
    • 자신의 자아를 보호하기 위해 늘 켜 놓는 많은 방어막을 꺼 버리고, 우리를 짓누르고 있는 프로젝트의 압력을 무시해서 자신을 편안하게 만들어야 한다.
    • 그리고 무엇보다도 다음 디버깅 제1 법칙을 기억하라.

    Tip 30. 당황하지 말라.

    • 버그라고 생각하는 증상의 원인이 무엇일지 진짜로 생각해 보는 것이 정말 중요하다.
    • '그럴 리가 없는데'라는 생각으로 신경 세포 하나도 낭비하지 말라. 
      왜냐하면 실제로 일어났기 때문이다.
    • 디버깅할 때 근시안의 함정에 주의하라.
    • 표면에 보이는 증상만 고치려는 욕구를 이겨 내라.
    • 실제 문제는 우리의 눈앞에 있는 것에서 몇 단계 떨어져 있고, 또 다른 여러 가지와 연관되어 있을 확률이 다분하다.
    • 겉으로 드러난 특정한 증상만 고치려고 하지 말고, 항상 문제의 근본 원인을 찾으려고 노력하라.

    실마리 찾기

    • 버그를 살펴보기 전에 일단 작업 중인 코드가 경고 없이 깨끗하게 빌드되는지부터 확인하라.
    • 우리는 늘 컴파일러의 경고 수준을 최고로 높게 맞춘다.
      • 컴퓨터가 대신 찾아 줄 수 있는 문제를 우리가 찾느라 시간을 허비한다는건 말도 안 된다!
      • 우리는 당면한 더 어려운 문제에 집중해야 한다.
    • 일단 정확하게 관찰해야 한다.
    • 처음에 받은 자료 이상을 얻기 위해서 버그를 보고한 사용자를 인터뷰할 필요도 있다.
    • 인공적인 테스트는 애플리케이션을 충분히 테스트하지 못한다.
      • 경계 조건(boundary condition)과 실제 최종 사용자의 사용 패턴 모두를 철저히 테스트해야 한다.
    • 테스트를 체계적으로 해야 한다.

    디버깅 전략

    • 버그 재현하기
      • 버그를 고치는 첫걸음으로 가장 좋은 것은 그 버그를 재현할 수 있게 만드는 것이다.
      • 재현할 수 없다면 그 버그를 고쳤다는 것을 확인하기 힘들다
    • 디버깅의 가장 중요한 규칙은 이것이다.

    Tip 31. 코드를 고치기 전 실패하는 테스트부터

    • 버그가 발생하는 상황을 다른 것들로부터 분리하다 보면 어떻게 고쳐야 할지에 대한 통찰을 얻기도 한다.

    미지의 세계에 온 프로그래머

    Tip 32. 그놈의 오류 메시지 좀 읽어라.

    • 이상한 결과
      • 프로그램이 죽는 것이 아니라 결과가 이상한 상황이면 어떻게 해야 할까?
        • 디버거를 붙인 다음 실패하는 테스트를 이용하여 문제를 재현하라.
        • 무엇보다 먼저 디버거에 잘못된 값이 나타나는지부터 확인하라.
        • 버그를 추적했는데 해당 코드에 문제가 없을 수도 있기 때문이다.
      • 디버거에서 호출 스택 위아래로 어떻게 이동하고, 스택의 지역 변수를 어떻게 확인하는지 숙지하라.
      • 디버깅 과정을 메모하면 도움이 될 때가 많다.
      • 스택 트레이스(stack trace)가 너무 길다면 '이진 분할(binary chop)'을 하면 된다.
    • 입력값에 따라 바뀜
      • 잘 동작하다가 특정한 데이터 세트만 들어오면 죽어 버린다.
      • 데이터 세트를 복사한 다음, 개발 환경에서 실행시킨 애플리케이션에 입력해서 여전히 프로그램이 죽는지 확인하라.
      • 프로그램이 죽는다면 이진 분할을 활용해서 정확히 어떤 입력값이 범인인지 찾아내라.
    • 릴리스 사이에서 발생한 문제(regression)
      • 일주일 전에는 괜찮았던 코드에서 언제부터 있었는지 모를 버그가 나타났다.
      • 정확하게 어떤 변경 사항 때문에 버그가 발생했는지 알아낼 수 있다면 좋지 않을까?
      • 이진 분할을 활용하자.

    이진 분할

    • 이진분할 사용법
      • 거대한 스택 트레이스가 눈앞에 있다.
      • 우리는 이 중에서 정확히 어떤 함수에서 문제가 되는 값을 엉망으로 만들었는지 찾아내려 한다.
      • 검색을 시작하기 위해 중간 즈음에서 스택 프레임을 하나 골라서 값이 정상인지 확인한다.
      • 정상이라면 그 위의 프레임들을 확인해야 하고, 아니라면 그 밑의 프레임들을 확인해야 한다.
      • 다시 반복한다.
      • 이 방식을 사용하면 답을 빠르게 찾아낼 수 있다.
      • 특정 데이터 세트에 대해서만 버그가 나타나는 경우에도 마찬가지로 이진 분할을 사용할 수 있다.
        • 데이터 세트를 둘로 나누고, 각각을 프로그램에 넣었을 때 문제가 발생하는지 살펴보라.
        • 문제가 발생하는 가장 작은 데이터 세트를 만들 때까지 나누기를 반복하라.
      • 현재 릴리스에서 예전 릴리스에 없었던 버그가 발생했다면 역시 마찬가지 종류의 기법을 사용할 수 있다.
        • 현재 릴리스에서 실패하는 테스트를 만들어라.
        • 문제가 없었던 버전 중 가장 최근 버전과 현재 버전 사이에서 중간 정도에 위치한 릴리스를 골라라.
        • 테스트를 수행한 후, 결과에 따라 어느 쪽을 탐색할지 골라라.
        • 많은 VCS은 이 과정을 자동으로 수행한다.
          테스트 결과에 따라 문제가 처음 발생하는 릴리스를 자동으로 찾아 준다.
    • 로깅과 트레이싱
      • 디버거는 일반적으로 프로그램의 현재 상태에 주목한다. 그러나 때로는 그 이상이 필요하다.
      • 트레이싱(tracing) 구문은 작은 진단용(diagnostic) 메시지를 일컫는다.
      • 트레이싱은 여러 프로세스가 동시에 작동하는 경우, 실시간(real-time) 시스템, 이벤트 기반 애플리케이션 등, 시간 자체가 중요한 요소가 되는 시스템에서 이루 말할 수 없이 소중하다.
      • 호출 트리(call tree)에서 내려갈 때마다 트레이싱 구문을 추가할 수 있다.
      • 트레이싱 구문으로 남기는 메시지는 규칙적이고 일관된 형식이어야 한다.
    • 고무 오리
      • 다른 사람에게 우리가 당연히 여기고 지나가는 부분들까지 코드가 무엇을 해야 하는지 차근차근 설명하듯이 코드에 대해 명시적으로 이야기해야 한다.
      • 이런 가정 몇 가지를 입 밖에 내면, 문제에 대한 새로운 통찰을 불현듯이 얻을 수도 있다.
    • 소거법
      • OS나 컴파일러 혹은 외부 제품에 버그가 있을 수도 있다.
      • 하지만 처음부터 그런 생각을 하지는 말라.
      • 우리의 코드에 문제가 없다는 것을 확인하라.
    우리가 맡았던 프로젝트에서 한 고참 엔지니어는 select 시스템 콜이 특정 유닉스 시스템에서 제대로 작동하지 않는다고 확신했고 수 주에 걸쳐 문제를 해결하지 못했다.
    결국 자리에 앉아서 select에 관한 문서를 읽을 수밖에 없게 되자 그는 원인을 발견해 냈고, 몇 분 만에 문제를 해결했다.
    우리는 둘 중 하나가 자신의 실수일 수 있는 일을 시스템의 문제라고 탓하기 시작하면 우리는 그 사건을 떠올리며 'select가 망가졌어'라는 표현을 사용한다.

    Tip 33. "select"는 망가지지 않았다.

    놀라운 구석

    • '놀라운' 실패를 대면했을 때 자신이 세운 가정이 적어도 하나는 잘못되었다는 것을 받아들여야 한다.
    • 버그와 관련된 루틴이나 코드가 제대로 작동하는 걸 '안다'고 해서 대충 얼버무리고 지나치지 말라.
    • 그것을 증명하라. 이 맥락 안에서, 이 데이터로, 이 결계조건하에서 증명하라.

    Tip 34. 가정하지 말라. 증명하라.

    • 놀라운 버그를 마주쳤을 때, 단순히 그걸 고치는 것을 넘어서 왜 이 문제가 더 일찍 발견되지 않았을까 생각해 봐야 한다.
    • 버그를 미리 잡을 수 있도록 단위 테스트나 다른 테스트를 수정할 필요가 있는지 고민해 보라.
    • 버그를 수정하는 김에, 혹시 이것과 동일한 버그가 있을 법한 다른 코드가 있는지 살펴보라.
      바로 지금 그것들을 찾아서 고쳐야 한다.
    • 어떤 일이 일어났든지 간에 똑같은 일이 다시 발생하면 그 사실을 알 수 있도록 하라.
    • 이 버그를 고치는데 시간이 오래 걸린다면 왜 그런지 자문하라.
    • 무엇을 하면 다음번에 이 버그를 좀 더 쉽게 고칠 수 있을까? 더 나은 테스트 훅(test hook)을 만들어 넣거나, 로그 파일 분석기를 작성할 수도 있겠다.

    디버깅 체크리스트

    • 보고된 문제가 내재하는 버그의 직접적 결과인가 아니면 단순히 증상일뿐인가?
    • 버그가 정말로 우리가 사용하는 프레임워크에 있나? OS에? 아니면 우리의 코드에 있나?
    • 이 문제를 동료에게 상세히 설명한다면 어떻게 말하겠는가?
    • 의심 가는 코드가 단위 테스트를 통과한다면 테스트는 충분히 갖춰진 것인가? 이 데이터로 테스트를 돌리면 무슨 일이 생기는가?
    • 이 버그를 야기한 조건이 시스템의 다른 곳에도 존재하는가? 다른 버그가 유충 단계에서 성충이 될 날만을 기다리고 있는 것은 아닌가?

    Topic 21. 텍스트 처리

    Tip 35. 텍스트 처리 언어를 익혀라.

    Topic 22. 엔지니어링 일기

    • 회의에서 메모할 때나 작업하는 내용을 써 놓을 때, 디버깅하다가 변수의 값을 적어 놓을 때, 무엇을 어디 두었는지 기록을 남길 때, 엉뚱한 생각을 기록할 때, 아니면 때로는 그냥 낙서할 때 일지를 쓴다.
    • 일지의 장점
      • 기억보다 더 믿을 만하다.
      • 진행 중인 작업과 직접적인 관계가 없는 발상을 일단 쌓아 놓을 수 있는 곳이 생긴다.
        그러면 위대한 발상을 잊어버릴 걱정 없이 지금 하는 일에 계속해서 집중할 수 있다.
      • 고무 오리와 같은 역할을 할 수 있다.
        • 무언가를 쓰기 위해 하던 일을 멈추면 우리의 뇌도 기어를 바꾼다.
    • 파일이나 위키 말고 종이를 사용하라.

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    반응형

    댓글

Designed by Tistory.