코딩을 하는 사람이라면 누구나 더 아름답고 간결한 코드를 추구할 것이다. 대부분의 사람은 다양한 알고리즘, 자료구조를 찾아보고 다른 사람들의 프로그래밍 기법을 참고한다. 하지만 이 책은 그보다 더 근본적인 해결책을 제시한다. 바로 코딩하는 중에 우리의 뇌에서는 어떤 과정을 거치고 어디서 어떻게 작동하는지 파악한 후 개선 방법을 도출해내는 것이다. 제목 그대로다. 프로그래머의 뇌를 분석한다. 클린 코드 책을 뇌과학 측면에서 분석한 느낌이다.
코딩 중 겪는 혼란에 대한 이해
코드를 읽을 때 혼란이 생기는 이유, 잘 이해하지 못하는 이유는 3가지가 있다. 지식 부족, 정보의 부족, 두뇌의 처리 능력 부족.
여기서 말하는 지식과 정보는 완전히 다른 개념이다. 지식은 언어 문법, 알고리즘 등 학습을 통해 얻을 수 있는 단계의 데이터를 의미하고, 정보는 모듈, 라이브러리, 패키지 등 코드를 이해하기 위해 필요한 데이터를 의미한다.
지식 - 기억하는 내용을 반영구적으로 저장하는 곳인 두뇌의 장기기억 공간(Long-Term Memory, LTM)에 저장된다. 추상적인 알고리즘, int형의 범위 등이 여기 저장된다.
정보 - 기억하는 내용을 일시적으로 저장하는 곳인 단기 기억공간(Short-Term Memory, STM)에 저장된다. 특정 코드에서 변수명, 사용한 자료구조, 키워드 등이 여기 저장된다.
두뇌의 처리 능력 - 많은 정보를 처리하는 공간인 작업 기억 공간(Working Memory)에 영향을 받는다. 사고할 때 사용하는 영역이며 실제 사고 작용이 일어나는 공간이다.
이를 인지 과정을 중심으로 정리하자면,
1. LTM에서 정보를 인출한다. 코드에서 키워드의 의미 등이 여기에 해당된다.
2. 메소드나 변수의 이름과 같이 코드를 읽는 과정에서 발생하는 정보를 STM에 일시적으로 저장한다.
3. 작업 기억 공간에서 코드를 읽고 처리한다.
코드를 읽는 동안 이 세 과정은 순차적이 아니라 동시에 일어나며 서로 보완적으로 작용하게 된다.
이들이 각각 부족하다면 코드를 읽을 때 혼란이 생기게 된다. LTM, STM, WM는 서로 밀접하게 연관되어 있다. 우리가 사고할 때 이 세 가지 장소 모두 어느 정도 활성화된다. 코드에서 변수명은 STM에 저장되고 자료형 등의 정보는 LTM에서 인출한다. 해당 프로그램이 무엇을 하는지는 WM에서 파악한다.
신속한 코드 분석
생소한 코드 읽는 것이 어려운 이유 - STM의 용량에 제한이 있기 때문.
STM은 읽거나 들은 정보를 짧은 시간 동안만 저장한다. 연구에 의하면 최대 6개의 항목을 30초 이내의 시간 동안 저장한다고 한다. 뿐만 아니라 인간의 STM 개수와 그 용량도 제한적이다. 뇌 구조적으로 우리는 많은 정보를 오랫동안 기억할 수 없다. 물론 이를 극복하고 개선시킬 수 있다.
이 책에서 제시하는 방법은 기억 대상을 특정 단위로 묶기다. 이는 '마지막 몰입' 책에서 제시한 기억력 향상 기법과 유사하다. 차별화된 점은 LTM을 적극 활용한다는 점이다. 이미 LTM에서 기억하고 있는 지식을 끌어와 STM 사용을 줄인다. 간단한 예를 들자면, {1, 1, 2, 3, 5, 6, 1, 9}과 같은 숫자를 외워야 할 때, 8개의 숫자를 각각 기억하는 것이 아니라 피보나치 수 앞 5항, 6, 1, 9와 같이 STM을 활용한다는 것이다.
그 외에도 디자인 패턴, 주석문을 활용하는 방법도 있다.
암기 vs 구글링
코드를 짜다보면 특정 메소드, 정규식 등을 써야 하는데 오랜만에 쓰는 문법인 경우 까먹는 경우가 빈번하다. 그때마다 우리는 구글의 도움을 받는다. 검색 결과를 보면 아! 이렇게 쓰는 거였지 하고 깨닫지만 다음에 같은 내용을 다시 구글링 하게 된다. 언어별 문법도 다르고 메소드 형태도 다양해서 이 모든 것을 외우기는 사실상 불가능하다는 생각이 든다. 하지만 우리는 완벽하지 못하더라도 이들을 최대한 외우려고 노력해야 한다. 굳이굳이 외워야 하는 이유가 두 가지 있다.
1. 개념, 자료구조, 문법을 많이 알면 알수록 두뇌는 더 많은 코드를 분리하고 처리할 수 있다. 알고리즘 문제를 풀때에도 문제를 분석하고 해결 방법을 찾을 때 선택할 수 있는 방법이 다양해지고 더 효율적인 코드를 짤 수 있다. 즉, 생각과 선택의 폭이 확장된다.
2. 두뇌가 작업을 하다 구글링 등을 위해 하던 업무를 중단하게 되면 우리의 생각보다 훨씬 더 심한 영향을 받는다. 실제 업무에서 코딩하던 중 중단되는 경우 다시 그 업무로 돌아가는 데 평균 15분 정도 걸린다고 한다.
암기 능력을 향상시키는 방법은 오로지 연습뿐이다. LTM에 저장된 우리의 기억은 망각 곡선을 따라 시간이 지날수록 사라진다. 절대 영원한 기억은 없다. 주기적으로 오랫동안 반복적으로 학습하여 망각의 주기를 늘려야만 우리의 암기 능력은 향상된다.
더 오랫동안 기억하기
무언가를 기억한다는 것은 LTM에 저장하는 것과 LTM에서 꺼내어 떠올리는 것, 다른 말로 인출하는 것 이 두 단계로 나눌 수 있다.
즉 기억이라는 행위는 저장과 인출 두 과정으로 분리할 수 있다. 아무리 저장을 잘해도 인출을 하지 못한다면 기억을 필요한 상황에서 적절하게 사용할 수 없다. 따라서 인출 강도를 높이는 것도 저장 강도를 높이는 것 못지않게 매우 중요하다.
저장 강도 - 무언가를 LTM에 얼마나 잘 저장하고 있는가. 반복해서 학습할수록 저장 강도는 강화된다.
인출 강도 - 무언가를 얼마나 쉽게 떠올릴 수 있는가. 자신이 이미 알고 있다고 생각하는 내용을 기억하려고 노력하면 추가 학습 없이도 인출 강도가 강화된다.
시간이 지날수록 저장 강도는 감소하지 않고 늘어나는 반면 인출강도는 시간이 흐를수록 약해진다. 연습하지 않더라도 저장 강도는 감소하지 않지만 인출 강도는 점점 약해진다. 인출 강도를 강화시키는 연습은 꼭 필요하다.
정교화(Elaboration) - 정보에 대해 생각하는 과정.
우리 뇌에서 기억은 다른 기억과 사실에 연결되는 네트워크의 형태이다. 새로운 정보를 능동적으로 정교화하면 그 새로운 기억이 연결한 기억의 네트워크를 강화하고 쉽게 인출하는 데 도움을 준다. 능동적으로 기억하려고 노력할 때 그 정보가 우리 두뇌에서 더 잘 기억된다. 특정 단어가 떠오르지 않을 때 유사한 단어나 그 단어의 의미, 활용 사례 등 그 단어 주변 기억을 떠올리게 된다. 이 과정을 통해 기억 네트워크를 강화시킬 수 있고 자연스럽게 인출 강도를 높일 수 있다. 특정 단어나 개념이 떠오르지 않아 답답한 상황에서 떠오르지 않는다고 단념하지 말고 최대한 떠올리려고 노력해보자. 당장 시간이 아깝고 성과가 없더라도 다음에 같은 단어를 떠올리고 사용하는데 큰 도움이 될 것이다. 자주 구글에 의존하는 것은 자신의 능력을 깎아내리는 악습관이다.
복잡한 코드를 읽는 방법
1장에서 언급한 '코드를 읽을 때 혼란이 생기는 이유 3가지' 중 마지막, 두뇌의 처리 능력 부족에 대해 설명한다. 앞서 말했듯 '두뇌의 처리 능력'은 작업 기억 공간(WM, Working Memory)에 의해 결정된다. 따라서 작업기억공간의 기저에 있는 인지 과정을 살펴볼 필요가 있다. 2장에서 STM은 한 번에 2~6개의 항목만을 저장할 수 있다고 하였는데, WM도 동일하다. 조금 다른 점이라 하면 WM의 맥락에서 '2~6개'라는 용량은 인지 부하(Cognitive Load)이다. 인지 부하란 WM에 정보를 저장하거나 처리할 때 요구되는 노력의 총량이다. WM에 한 번에 너무 많은 항목이 들어오면 과부하(Overload) 상태가 된다.
인지 부하 종류 3가지
1. 내재적 인지 부하(Intrinsic Cognitive Load) - 문제 자체가 갖는 특성 때문에 발생하는 인지 부하.
2. 외재적 인지 부하(Extrameous Cognitive Load) - 내재적 부하에 더해서 문제에 추가되는 인지 부하. '외부적' 요인에 의해 문제에 추가된 것.
표현이 좀 어렵게 느껴질 수 있는데 실상은 별 거 없다. 이 책에서는 두 인지 부하의 특징과 차이점을 피타고라스의 정리를 예시로 설명한다.
왼쪽 그림을 보면 보자마자 피타고라스의 정리를 이용하여 빗변의 길이를 구해야겠다는 생각이 들 것이다. 이것이 문제에 내재되어 있는, 문제 자체가 갖는 특성 때문에 발생하는 내재적 인지 부하이다. 이 문제를 푸는 방법은 피타고라스의 정리를 사용하는 방법 밖에 존재하지 않는다. 이렇게 문제를 해결하는 다른 방법이나 더 간단하게 만드는 방법이 존재하지 않는 경우 내재적 인지 부하가 발생한다.
외재적 인지부하는 내재적 인지 부하에 추가되는 것이라 하였는데, 왼쪽 그림은 위 그림에서 추가적으로 a,b에 숫자를 대입하는 과정이 필요하다. 이 추가 과정 때문에 발생하는 인지 부하를 외재적 인지 부하라 한다. 위에서는 피타고라스 정리를 사용하는 인지 부하 하나가 발생한다면 왼쪽 그림에서는 피타고라스 정리를 사용한다는 것, 변수에 숫자를 대입해야 한다는 것 이렇게 2가지의 인지 부하가 발생한다.
3. 본유적 인지 부하 (Germane Cognitive Load) - 생각을 LTM에 저장하는 과정에서 일어나는 인지 부하. 10장에서 자세히 설명한다.
발생하는 인지 부하를 줄이는 방법 3가지.
1. 리팩토링(Refactoring)
코드가 외부적으로 제공하는 기능은 유지한 채 코드의 내부 구조를 개선하는 것을 의미한다. 대부분의 경우, 리팩토링은 코드의 유지보수를 쉽게 하기 위한 목적으로 이루어진다. 하지만 유지 보수 용의성과 가독성은 항상 비례하지는 않는다. 이 책에서 다루는 내용은 인지 부하를 줄여 복잡한 코드를 읽는 방법 즉, 가독성을 높이는 방법이다. 따라서 가독성을 우선시하여 설명한다. 유지 보수 용의성을 위해 외재적 인지 부하가 더해진 경우 가독성이 현저히 떨어진다. 이는 작업 기억 공간에도 어려움을 주게 된다. 따라서 유지 보수하기 좋은 코드보다는 장기적으로 가독성이 높은 코드를 작성하도록 리팩토링하는 것이 좋을 수 있다.
이러한 방식의 리팩토링을 인지적 리팩토링(Cognitive Refactoring)이라 한다. 현재의 시점에서 개발자가 읽기 쉬운 코드로 변경하는 것. 인지적 리팩토링은 개발자 자신만을 위한 것이다. 많은 경우, 인지적 리팩토링은 일시적이고 코드 이해를 목적으로 하므로 이해한 후에는 코드를 원래대로 되돌리면 된다.
2. 생소한 언어 구성 요소를 다른 것으로 대체하기
간단하게 정리하면 Lamba식이나 파이썬의 List comprehension을 for 루프 등으로 바꾸면 이해하기 쉽고 인지 부하를 줄일 수 있다는 것이다.
3. 기억 보조 수단 활용하기
- 의존 그래프(Dependency Graph)
비슷한 변수나 클래스의 인스턴스를 원으로 표시하고 선으로 연결하면 의존 그래프가 생성된다. 해당 변수가 정의, 초기화, 사용되는 곳을 한눈에 볼 수 있고 이를 통해 복잡하고 서로 밀접하게 연결되어 있는 코드를 이해하는 데 도움이 된다.
- 상태표(State Table)
코드의 실행 도중 변수가 갖는 값을 보여주는 상태표를 생성한다면 계산이 많이 수행되는 코드를 파악하는데 유용하다. 알고리즘 문제를 풀 때 잘못된 부분을 찾기 위해 코드 진행에 따라 변수들의 값 변화를 추적하기 위해 자주 사용하곤 하는데 정말 유용하다.
'Book Report' 카테고리의 다른 글
디지털 미니멀리즘 (0) | 2022.07.07 |
---|---|
어서 오세요, 휴남동 서점입니다 (2) | 2022.04.05 |
인공지능은 무엇이 되려 하는가 (12) | 2022.03.19 |
객체지향의 사실과 오해 - 7장, 후기 (1) | 2022.03.15 |
객체지향의 사실과 오해 - 6장 (0) | 2022.03.12 |