부서지기 직전의 재료로 작업하기

안녕하세요. 이번 글은 책 ”일의 감각, 원제 Expert”에서 발견한 한 문장에서 시작했습니다. 장인의 작업을 소개하며 “부서지기 직전의 재료로 작업하기”라는 개념이 있었는데 아마 재료 그 물성의 한계를 파악하고 최고의 결과를 얻기 위해 해당 재료가 허용하는 한계까지 밀어붙여 작업하는 걸 의미했던 것 같습니다. 다중 감각을 이용하여 작업물의 상태를 파악하고 재료의 한계를 직감적으로 파악하여 다루는 장인의 모습이 멋졌습니다. 그럼 저와 같은 소프트웨어 엔지니어에겐 “부서지기 직전의 재료로 작업하기”는 무얼 의미할까요. 먼저 소프트웨어라는 작업물이 부서지는 상황을 생각해 봤습니다.

소프트웨어가 동작하기 위해선 프로그램 소스의 문법적 오류가 없어야 하고 소프트웨어의 내적 논리가 완전해야 합니다. 곧, 두 조건을 깨뜨리는 상태로 이끌고 가면 소프트웨어는 부서집니다. 그렇다면 부서지기 직전의 소프트웨어는 어떤 모습일까요? 저는 이렇게 생각합니다. 소프트웨어에 기능을 추가하거나 변경하는 일은 국지적 소란을 일으킵니다. 소프트웨어는 잠시동안 동작하지 못하는 상태가 되었다가 다시 동작할 수 있는 상태로 돌아옵니다. 가장 소규모로는 지역 변수의 이름을 바꾸는 일이 될 수도 있고 더 큰 규모로는 동기식 라이브러리를 비동기식 라이브러리로 교체하는 작업이 될 수도 있습니다. 소프트웨어는 일반적으로 생각하는 것만큼 논리의 결정체, 빈틈없이 쌓아 올린 블록 같은 게 아닙니다. 그보다는 원시적인 형태의 생명에서 고차원적인 생물로 진화해 나가는, 변화 속에서 살아가는 존재에 가깝습니다. 계속해서 상황과 조건이 바뀌므로 소프트웨어 엔지니어는 리팩터링 이란 이름으로 보수작업, 개량을 반복합니다. 이 시기엔 소프트웨어 코드 속으로 의도된 불확실성이 주입되며 결과적으로는 더 일관된 의미를 가진 소프트웨어로 탈바꿈합니다. 여기서 소프트웨어 장인은 더 큰 불확실성을 끌어안은 채 다양한 영역에 걸쳐 작업을 수행할 수 있습니다.

어떻게 소프트웨어 장인은 더 복잡하고 어지러운 상황을 감내하며 작업을 이어나갈 수 있을까요? 여기서 작업 메모리를 생각해 볼 수 있습니다. 작업 메모리는 우리가 어떤 일을 할 때 한 번에 생각할 수 있는 기억 용량 같은 겁니다. 물론 그 용량은 무한하지 않습니다. 소프트웨어 역시 모든 기능을 머릿속에서 동시에 생각하며 만들 수 없습니다. 이런 문제를 해결하기 위해 다양한 접근 방식이 나타났고 소프트웨어 엔지니어가 사용할 수 있는 도구들도 생겨났습니다. 기능들을 컴포넌트 내지는 모듈 형태로 추상화시켜 생각의 범위를 한정 지을 수 있습니다. 이렇게 범위를 정해두면 작업 메모리는 해당 범위에 속하는 개념들만을 다루면 되기 때문에 인지적 부하가 줄어듭니다. 좀 더 미시적인 관점에서는 함수를 통한 기능 분리가 있습니다. 여러 Linter (코드 정적 분석 도구)에서 가이드하는 부분 중에는 하나의 함수 혹은 하나의 클래스 메서드에서 사용할 수 있는 변수의 개수를 제한하거나 코드의 길이를 제한하는 부분이 있습니다. 이 역시 한 번에 생각해야 하는 범위를 줄여 오류를 방지하기 위함입니다.

그렇다면 소프트웨어 장인은 더 많은 작업 메모리를 갖고 있는 걸까요? 아마 이 부분에 대한 대답은 체스에서 찾을 수 있을 것 같습니다. 프로 체스플레이어는 체스 경기의 장면을 사진 찍듯 기억하고 다시 복기해 낼 수 있습니다. 이건 아마 바둑에서도 마찬가지일 겁니다. 체스나 바둑의 초심자는 그만큼 정확하고 빠르게 복기할 수 없었지요. 재밌는 실험이 있었는데 앞서 언급했던 프로 체스플레이어에게 똑같이 체스판의 내용을 암기하라는 요구를 했습니다. 하지만 여기서 체스 말들은 경기의 규칙을 따르지 않은 채로 배열되어 있었습니다. 이 경우 프로 체스플레이어도 초심자처럼 쉽게 체스 경기를 복기해 낼 수 없었습니다. 왜인고 하니 체스판을 기억할 때 하나하나의 말의 위치를 기억하는 대신 말들의 묶음, 곧 덩어리 (Chunk) 단위로 기억하는 전략을 사용했기 때문입니다. 이런 덩어리 짓기를 이용하면 인지 부하를 줄이면서 작업을 효율적으로 수행할 수 있습니다. 그럼 소프트웨어 장인들도 비슷한 전략을 구사하는 게 아닐까요? 소프트웨어 작성을 수년간 경험하면서 여러 번 반복해 오며 접한 문제들과 해결책이 있을 것입니다. 또한 패턴이라는 이름으로 소개된 전략들도 존재하고요. 장인들은 이런 개념적인 틀을 이용하여 불확실성을 제어합니다. 코드 속에 소란이 발생하더라도 개념적으로 한정되어 있고 서로 연결되어 있는 지점들이기 때문이 그 자취를 기억할 수 있고 빼먹지 않고 수정할 수 있습니다.

여러분은 어떤 일을 하고 있나요? 여러분 역시 부서지기 직전의 재료로 작업해 본 경험이 있나요? 저는 이번 글에서 소프트웨어라는 재료를 다뤄봤는데요. 다른 분야에서는 어떤 모습으로 작업이 펼쳐질지 궁금해집니다.