ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머의 뇌] 2. 신속한 코드 분석
    📝 기록/독서 기록 2024. 1. 22. 22:29
    💡 <프로그래머의 뇌> '신속한 코드 분석' 챕터를 읽으면서 기억할 만한 부분을 기록한 포스팅입니다.

    - 챕터 목표: 코드를 빨리 이해하는 것이 왜 어려운지 이해하고, 어떻게 하면 코드를 더 빨리 읽을 수 있는지에 대해서 살펴본다.

     

    1. 코드를 신속하게 읽기

    코드를 읽을 때 우리는 그 코드에 존재하는 특정한 정보를 찾는다. 관련 정보를 신속하게 찾는 능력을 향상하면 코드를 다시 찾아보는 횟수를 줄일 수 있다.

    두뇌에서 무슨 일이 일어나는가?

    아래와 같이 삽입 정렬 알고리즘을 구현한 자바 코드를 작성한다고 생각해 보자.

    public class InsertionSort {
        public static void main(String[] args) {
            int[] array = {1,3,6,77,23,4};
            int temp;
    
            for (int i = 1; i < array.length; i += 1) {
                for (int j = i; j > 0; j -= 1) {
                    if (array[j] < array[j - 1]) {
                        temp = array[j];
                        array[j] = array[j - 1];
                        array[j - 1] = temp;
                      }
                  }
            }
    
            for (let i = 0; i < array.length; i += 1) {
                system.out.println(array[i]);
            }
        }
    }

    이때 코드를 읽는 과정에서 작동하는 인지 과정에 대한 설명, 변수명이나 변수의 값 등은 STM에 저장되고, for 루프와 같은 자바 문법에 대한 지식은 LTM으로부터 가져온다.

    두 번째 실험

    또, 아래와 같은 자바 코드가 있다고 가정한다.

    public void execute(int x[]) {
        int b = x.length;
    
        for (int v = b / 2 - 1; v >= 0; v -= 1) {
            func(x, b, v);
        }
    
        // 원소를 하나씩 추출한다
        for (int l = b - 1; l > 0; l -= 1) {
            // 현재 값을 마지막으로 옮긴다
            int temp = x[0];
            x[0] = x[l];
            x[l] = temp;
    
            func(x, l, 0);
        }
    }

    이 코드는 읽기 어려웠을 것이다. 그 이유는 우선 코드가 무슨 일을 하는지 알지 못하기 때문에 LTM에 저장된 지식을 사용해서 추측할 수 없다. 둘째, 의도적으로 for 루프의 변수명을 b나 l처럼 잘 쓰지 않는 '이상한' 이름을 사용했다. 이처럼 생소한 변수명을 사용하게 되면 패턴을 찾고 기억하는 것이 어려워진다.

    생소한 코드를 읽는 것은 왜 어려운가?

    생소한 코드를 기억하기 어려운 결정적인 이유는 STM의 용량에는 제한이 있기 때문이다. 연구에 의하면 STM은 읽거나 들은 정보를 짧은 시간(최대 약 30초)만 저장한다. 뿐만 아니라 크기 또한 제약된다. 최근 연구에 따르면 STM의 용량이 2개에서 6개 사이로, 심지어 더 적을 수도 있다고 추정한다.

    2. 기억의 크기 제한을 극복하기

    그렇기에 이러한 작은 용량으로 인한 STM의 문제점을 극복하기 위해 LTM과 협업하여, 읽거나 저장한 정보를 이해한다.

    단위로 묶는 것의 위력

    네덜란드 수학자 아드리안 더흐로트는 청크라는 개념을 처음 사용했다. 청크는 몇 개의 그룹으로 묶은 정보를 말한다. 특정한 주제에 대해 두뇌가 더 많은 정보를 저장하고 있다면 입력된 정보들을 효율적으로 청킹하여 그룹화하는 것이 수월해진다. 예를 들어, 'abk mrtpi gbar'와 'cat loves cake'라는 문장이 있을 때, 앞 문장보다 뒷 문장이 더 기억하기 쉽다. 여러 개의 문자를 한 단위로 묶어서(청킹) 'cat', 'loves', 'cake'로 기억했기 때문이다.

    3. 읽는 것보다 보는 것이 더 많다

    정보가 두뇌로 들어오면, STM에 도달하기 전에 감각 기억 공간(sensory memory)이라는 영역을 통과한다. 감각 기억 공간은 컴퓨터로 비유하면, 마우스와 키보드 같은 입력장치와 통신하는 입출력 버퍼라고 볼 수 있다. 즉, 주변장치로부터 전송된 정보가 잠시 저장되는 곳을 말한다.

    기억하는 대상이 중요한 것이 아니고 기억하는 방식이 중요하다

    1. 디자인 패턴 활용
    그룹으로 묶기 쉬운, 즉 청킹하기 쉬운 코드를 작성하려면 디자인 패턴을 사용하면 된다. 실제로 디자인 패턴에 대한 지식을 갖게 되면 청킹 능력이 향상되고 코드를 더 빠르게 수정할 수 있게 된다는 점이 연구를 통해 밝혀졌다.

    2. 주석문 활용
    어떠한 주석을 남기느냐에 따라 다른데, 예를 들어 '이 함수는 주어진 이진 트리를 중위 순회(in-order)하며 프린트한다'와 같은 고수준 주석문은 코드를 청크 단위로 쪼개는 데 도움이 된다. 반면, 'i++; 다음에 i를 1만큼 증가'와 같은 저수준 주석문을 넣는 것은 오히려 청킹 작업에 부담을 준다.

    3. 표식 활용
    표식은 개발자가 코드를 읽을 때 그 코드가 무엇을 하는지 이해하는 데 도움이 된다. 일반적으로 코드 내에서 사용하는 특정 자료구조, 알고리즘 혹은 접근 방식등을 보여주는 라인을 뜻한다.
    표식에는 단순 표식(simple beacon)과 복합 표식(compound beacon) 두 가지 종류가 있다. 단순 표식은 의미 있는 변수명같이 코드의 문법을 통해 의미가 자명한 표식을 말하고(예: root, tree, if, else, && 등), 복합 표식은 단순 표식보다 좀 더 큰 단위의 코드로 단순 표식들이 모여 함께 실행하는 기능에 대해 알려준다(예: for 루프 등).

    청킹 연습

    경험이 쌓이면서 프로그래밍에 대한 지식이 자연스럽게 늘어나긴 하지만, 코드청킹을 의도적으로 연습하는 방법이 몇 가지 있다. 의도적 연습은 어떤 기술을 향상하기 위해 조금씩 연습하는 것을 의미한다. 프로그래밍에서는 여러 가지 이유로 의도적 연습이 흔치는 않지만, 코드를 많이 작성해 보는 것으로 프로그래밍을 학습한다. 물론 효과적이지는 않을 수 있다. 청킹을 의도적으로 연습하기 위해서는 적극적으로 코드를 기억해 내는 것을 훈련하면 아주 좋다.


    ✍🏻 독후감

    최근에 코테 스터디를 진행하면서 하루에 많게는 3문제, 적게는 1문제씩 문제를 꾸준히 푸는 중인데, 그러다 보니 문제 풀 때 가장 중요한 건 귀납적 사고 능력과 청킹+링킹 능력이라고 절감하고 있다. 때마침 읽게 된 챕터 2에서 나온 내용이 많이 공감됐다. 이 책에서 알려준 내용을 명심하고 의도적인 연습을 꾸준히 해보자.

    1장에서도 느꼈지만, 2장에서도 역시나 단순히 과학 이론과 연구 결과를 설명하고 끝이 아니라 그렇다면 여기서 프로그래머라면 어떻게 사고하고 훈련해야 하는지를 알려주는 게 너무 좋다.. 한 챕터씩 뜯어보는 재미가 쏠쏠. 처음에는 그냥 읽었는데 블로그를 더 열심히 해서 나중에는 이 블로그 글이 주기적으로 읽어볼 수 있는 cheet sheet가 될 수 있게 더 열심히 정리해야겠다는 생각이 들었다.