Vallista
TIL

2022년 8월 24일

· 3 min read · 1,676 words

로고
로고

오늘 한 일

  • 프로그래머의 뇌 4장

프로그래머의 뇌 4장 - 복잡한 코드 읽는 방법

  • 코드가 혼란스러운 이유: STM 정보 부족 / LTM 지식 부족
  • 이번 장에서 다룰 내용: 두뇌의 처리 능력 부족

복잡한 코드를 이해하는 것이 왜 어려운가

  • 작업 기억 공간은 두뇌가 생각하고 새로운 아이디어를 형성하고 문제를 해결하는 능력에 해당함 (작업기억공간은 두뇌의 프로세서와 같음)

작업 기억 공간과 STM의 차이

  • STM은 한 번에 2개에서 6개까지 항목만 저장할 수 있다
    • 단어나 체스 오프닝, 디자인 패턴과 같이 인식 가능한 청크는 더 많은 정보를 담을 수 있음
  • 작업기억공간도 한 번에 2개에서 6개까지만 기억할 수 있다.
    • 작업 기억 공간의 맥락에서 이 용량을 인지 부하라고 부른다.
    • 너무 많은 요소가 있어 청크로 나뉘지 않는 문제를 풀려고 할 때 작업 기억 공간은 과부화 상태가 된다.

프로그래밍과 관련한 인지 부하의 종류

  • 인지 부하 이론은 오스트레일이아의 존 스웰러 교수가 처음 제안했다
    • 내재적(intrinstic), 외재적(extraneous), 본유적(germane) 세 가지로 구별했다.
코드를 읽을 때 내재적 인지 부하
  • 문제 그 자체가 갖는 특성 때문에 발생하는 인지 부하
  • 피타고라스의 정리를 활용해서 문제를 푸는 것과 같이 문제 자체의 존재하는 특성이 내재적 인지 부하의 원인이라고 말함
코드를 읽을 때 외재적 인지 부하
  • 어떤 문제가 두뇌에 일으키는 자연적이고 내재적인 부하에 더해서 문제에 추가되는 인지 부하
  • 피타고라스를 이용해 문제를 풀 때, 빗변의 길이를 계산하는 것을 다른 방식으로 만들었을 때, 값을 연결시키거나 해서 추가적인 작업이 생긴 경우를 외재적 인지 부하라고 한다.
  • 문제가 실제로 어려워지진 않았지만 추가로 업무를 수행하면 그렇게 된다.

인지 부하를 줄이기 위한 기법

  • 코드가 작업 기억 공간에 과부하를 초래하는 다양한 방식이 있음. 이는 인지 부하를 줄여야 쉽게 이해하는 코드를 작성할 수 있다.

리펙터링

  • 코드가 외부적으로 제공하는 기능은 유지한 채 코드의 내부 구조를 개선하는 것을 의미
  • 코드 블록의 길이가 너무 길면 여러 개의 함수로 나누거나 재사용을 위해 중복된 코드를 하나로 통합하는 것
  • 장기적으로 가독성이 높은 코드를 작성하도록 리펙토링하라
    • 이러한 방식을 인지적 리팩터링(cognitive refactoring)이라고 정의한다.
    • 현 시점에서 개발자가 읽기 쉬운 코드로 변경하는 걸 뜻함
    • 때론 역 리펙토링(reverse refactoring)을 수반할 수도 있다.

생소한 언어 구성 요소를 다른 것으로 대치하기

  • 현대의 많은 프로그래밍 언어는 람다(lambda)와 같은 익명 함수를 지원한다. 하지만 많은 프로그래머는 람다에 익숙하지 않다.
  • 읽거나 작성하는 코드가 간단하고 명확하면 문제가 되지 않지만, 복잡한 코드는 작업 기억 공간에 과부하가 발생한다.
  • 팀원이 이해가 어렵다면 for-loop로 변경하여 리펙터링 하는게 좋다.

플래시카드에 코드 동의어 추가

  • 고급 개념에 대해서 프롬프트 대신 플래시카드 앞면까지 양면에 모두 코드를 적어서 더 나은 효과를 얻도록 외우도록 한다

작업 기억 공간에 부하가 오면 쓸 수 있는 기억 보조 수단

  • 복잡한 구조의 코드는 두 가지 방식으로 작업 기억 공간에 과부하를 유발한다
    • 정확히 코드의 어디를 파악해야 하는지 모를 때: 이 경우 필요 이상으로 많은 코드를 읽게 되어 작업 기억 공간이 처리할 수 잇는 것보다 많은 양이 된다.
    • 코드가 서로 밀접하게 연결되어 있는 경우 두뇌는 두 가지 작업을 동시에 수행: 코드의 개별 라인을 이해하면서 어느 부분을 읽어야 하는지 판단을 위해 코드의 구조를 이해해야 한다.

의존 그래프 생성

  • 코드를 바탕으로 의존 그래프(dependency graph)를 만들면 흐름을 이해하고 논리적 흐름에 따라 코드를 읽는 데 도움이 된다.
    • 먼저, 코드를 복사하거나 pdf로 딴다.
    • 첫 번째: 모든 변수를 원으로 표시한다
    • 두 번째: 비슷한 변수를 선으로 연결한다.
    • 세 번째; 모든 메서드나 함수 호출을 원으로 표시한다.
    • 네 번째: 메서드나 함수 호출을 정의와 연결한다.
    • 다섯 번째: 클래스의 모든 인스턴스를 원으로 표시한다.
    • 여섯 번째: 클래스와 그 클래스의 인스턴스를 연결한다.
  • 6가지 단계를 통해 만든 패턴은 코드의 흐름을 보여주고 코드를 읽는 보조 수단으로 사용할 수 있다.

상태표 사용

  • 코드의 구조 때문에 이해가 어려운게 아닌, 계산 로직 때문에 어려워 질 수 있음
  • 복잡한 계산을 수행하는 이 같은 코드를 이해하기 위해 의존 그래프 같은 보조 수단을 사용할 수 있지만, 계산이 많은 코드를 파악할 때 도움이 되는 보조 수단은 상태표(state table)이다.
  • 상태표는 코드의 구조보다 변수의 값에 중점을 둔다.

상태표를 만드는 단계

  1. 모든 변수를 나열
  2. 테이블을 만들고 각 열에 하나의 변수를 기입
  3. 코드의 실행 단계마다 행을 만든다.
  4. 코드를 각 단계별로 실행하고 그 단계에서 변수들의 값을 해당하는 열과 행에 적는다.
    • 코드를 머리로 실행해보는 과정을 트레이싱(tracing) 혹은 인지적 컴파일(cognitive compiling)이라고 한다.

의존 그래프와 상태표의 혼용

  • 다른 측면에서 코드의 정보를 제공한다.
    • 의존 그래프: 코드의 구조를 보여줌
    • 상태표: 코드에서 이루어지는 계산 결과를 보여줌