이해의 기쁨과 힘

2 days ago 8
  • 소프트웨어를 깊이 이해하면 도구에 끌려가지 않고, 자신이 책임지는 시스템에 대한 통제와 소유권을 가질 수 있음
  • 검색과 LLM은 빠른 답을 주지만, 설명할 수 없는 해법을 복사하는 습관은 수정 능력과 핵심 역량을 약화시킬 수 있음
  • 일회성 스크립트나 저위험 내부 UI에서는 생성·복붙이 합리적일 수 있지만, 오래 유지할 코드는 깊이 아는 기술로 만들어야 함
  • 생산성을 코드 줄 수나 PR 수 같은 output으로만 재면 쉽게 왜곡되며, 안정적인 릴리스·단순화·자동화·테스트 같은 outcome이 장기 가치에 더 가까움
  • 현대 소프트웨어는 런타임, 네트워크, 보안, 데이터베이스, AI까지 복잡해졌지만, 기초 원리를 익히면 새 도구와 접근법을 더 빠르게 이해할 수 있음

이해가 주는 통제와 즐거움

  • 깊은 이해는 코드와 시스템을 고치고 바꾸기 위한 실질적 조건
  • 이해하지 못하는 대상은 수정하거나 변경하기 어렵고, 결국 책임지는 코드에 대한 통제와 소유권도 약해짐
  • 이해는 도구의 주인이 되게 할 뿐 아니라 심리적으로도 만족감을 줌
  • 환경을 더 잘 통제하게 해주는 행동이 긍정적 감정과 연결되는 것은 자연스러운 일로 볼 수 있음

인간의 게으름과 LLM 의존

  • 인간은 에너지 사용을 줄이고 투자 대비 보상을 키우려는 성향을 가짐
  • 게으름은 지루하고 비용 큰 작업을 자동화하는 동기가 되지만, 학습과 숙련에서는 약점이 될 수 있음
  • 인터넷과 LLM 덕분에 비슷한 문제의 답을 원하는 형태로 쉽게 얻을 수 있어, 이해 과정을 건너뛰기 쉬워짐
  • SQL을 직접 배우는 대신 테이블과 원하는 데이터를 LLM에 알려주고 결과만 복사하면 당장은 쉽지만, 제대로 다루는 능력은 쌓이지 않음
  • LLM이 SQL을 더 빨리 만들어 주더라도, 과거에 직접 반복하며 기른 읽기·이해 능력은 쓰지 않으면 줄어듦
  • LLM과 검색 엔진은 최선의 경우 역량 증폭기(force multiplier) 이지만, 먼저 강한 기본기가 있어야 함
  • 핵심 기술과 지식은 검색·프롬프트·수동 검증만으로 유지되기 어렵고, 직접 구축하고 창작하는 과정에 참여해야 함
  • 정기적으로 게으른 성향에 맞서 문서와 소스를 읽고, 해법의 이유와 도구의 트레이드오프를 이해하며, 해법과 알고리듬을 직접 설계해야 함

단기 생산성과 장기 이해의 균형

  • 모든 코드와 해법을 완전히 이해해야 하는 것은 아니며, 상황에 따라 기준을 달리할 수 있음
  • 낮은 중요도와 위험의 일회성 스크립트는 복사하거나 생성해도 괜찮음
  • 두세 명이 쓰는 내부 UI나 페이지도 같은 방식이 허용될 수 있음
  • 몇 달이나 몇 년 동안 소유·유지·진화시킬 코드는 깊이 아는 언어와 기술로 만들어야 함
    • 모든 줄, 단어, 문자, 설정 옵션을 이해할 수 있거나 그 방향으로 가야 함
    • 지금 당장 많은 산출물을 내는 것보다 장기 이해·유지보수성·생산성을 최적화해야 함
  • MVP나 기존 제품 안의 실험 기능처럼 성공 여부가 불확실한 경우에는 품질과 이해 기준을 조금 낮출 수 있음
  • 이런 선택은 인지 부채를 지는 것과 비슷함
    • 지금은 더 빨리 움직일 수 있음
    • 제품이나 기능이 작동하거나 수정·변경이 필요해지면 나중에 더 많이 갚아야 함
  • 그래도 최소한 자신 있게 “작동한다”고 말할 수 있을 정도로는 이해하고 검증해야 함
  • 일부 경우에는 생성한 뒤 검증하고, 처음부터 다시 작성하는 전략이 합리적일 수 있음

기술 스택과 숙련의 복리 효과

  • 가끔 쓰는 프로그래밍 언어, 라이브러리, 도구라면 깊은 학습과 숙련에 시간을 많이 투자하지 않아도 됨
  • 결과를 검증할 수 있다면 부분적으로 이해한 것을 복사·생성하는 방식도 때로는 괜찮음
  • 하지만 학습과 고생의 단계를 건너뛰면 해당 기술을 숙련하고 생산적으로 다룰 가능성을 스스로 줄이게 됨
  • 정기적으로 사용하는 핵심 기술 스택에서는 숙련이 수백 배, 수천 배로 보상될 수 있음
  • 지식과 기술은 복리 효과를 가짐
    • 더 많이 알수록 스스로 더 빠르게 만들 수 있음
    • 새로운 지식과 기술도 점점 더 빠르게 습득할 수 있음
    • 역량이 늘수록 새로운 해법과 아이디어를 떠올릴 수 있음

Output보다 Outcome에 맞춘 생산성

  • 생산성을 이해하고 측정하는 방식은 크게 output 중심outcome 중심으로 나뉨
  • output 측정은 쉽고 숫자로 세기 쉬움
    • 생산한 코드 줄 수
    • 열고 병합한 PR 수
    • 구현한 기능 수
    • 발견하고 고친 버그 수
    • 완료한 작업 수
  • output 중심 지표는 쉽게 조작될 수 있음
    • 장황한 코드를 쓸 수 있음
    • 작은 PR을 많이 만들 수 있음
    • 작업을 인위적으로 쪼갤 수 있음
    • 쓸모없는 기능을 추가할 수 있음
  • 숫자가 늘어도 올바른 방향이라고 보장하기 어려움
    • PR이 많을수록 반드시 좋은 것은 아님
    • 코드베이스가 커지는 것이 늘 바람직한 것도 아님
    • 기능을 더하는 대신 쓰지 않는 기능을 제거하는 편이 나을 수 있음
  • outcome 중심 예시는 장기 가치와 더 직접 연결됨
    • 새 CI/CD 프로세스로 프로덕션 릴리스가 안정화됨
    • 리팩터링과 단순화로 유지보수와 향후 변경이 쉬워짐
    • 통합 해법 재설계로 새 파트너 추가가 빨라지고 컴퓨팅 자원을 절약함
    • 테스트를 늘려 버그를 사전에 잡고 회귀를 막음
    • 지표와 알림을 추가해 잠재 문제와 버그를 선제적으로 발견함
    • 지루한 수작업을 자동화해 시간을 절약하고 치명적 오류 가능성을 줄임
  • 장기 생산성과 이해는 outcome 중심 지표와 더 잘 맞으며, 더 많은 output이 항상 더 나은 것은 아님

복잡해지는 소프트웨어와 기초 원리

  • 소프트웨어 공학의 기본 정리는 “컴퓨터 과학의 어떤 문제도 또 다른 간접 계층으로 풀 수 있지만, 너무 많은 간접 계층 문제는 예외”라는 문장으로 요약됨
  • 현대 소프트웨어 개발은 여러 계층과 요소 때문에 매우 복잡함
    • 런타임과 플랫폼: 브라우저, 서버, 클라우드, 모바일, 데스크톱, 임베디드
    • 네트워크: HTTP, DNS, TLS, TCP, UDP, IP, WebSockets, WebRTC, 데이터베이스와 메시지 브로커의 프로토콜
    • 보안, 인증, 인가
    • 운영체제
    • 가상화, 컨테이너화, Kubernetes 계열 오케스트레이션
    • 데이터베이스: SQL, NoSQL, 로컬, 원격, 분산
    • 고수준 프로그래밍 언어와 컴파일러·인터프리터·트랜스파일러 파이프라인
    • 라이브러리, 프레임워크, 패키지 매니저
    • API와 외부 서비스
    • CI/CD, TDD, BDD, GitOps, IaC, DDD, EDA, Event Sourcing, CQRS, SSR, CSR, Clean Architecture, Hexagonal Architecture, Modular Monolith, Microservices, Microfrontends
    • LLM과 AI
  • 복잡성에 대응할 수 있는 이유도 있음
    • 많은 시스템은 과도하게 설계되어 있으며 상당히 단순화될 수 있음
    • 특정 기간에는 보통 소프트웨어 개발 지형의 작은 부분만 전문적으로 익히면 됨
    • 나머지는 인식 수준으로 충분할 수 있음
    • 도구 뒤의 일반 패턴과 원리를 익히면 새 도구·접근법·기술 학습에 지렛대가 됨

기초 원리의 범위와 효과

  • 기초 원리는 소프트웨어 개발에 쓰이는 도구, 라이브러리, 프레임워크, 프로토콜, 구성요소 밑에 있는 기본적이고 잘 변하지 않는 규칙·제약·메커니즘임
  • 핵심 범위에는 여러 분야가 포함됨
    • 컴퓨터 아키텍처와 하드웨어: CPU 구조, 명령 실행, 메모리 계층, 레지스터, 캐시, 저장 장치
    • 기계어, 어셈블리, 고수준 언어: 어셈블러, 컴파일러, 인터프리터가 필요한 이유와 언어 유형별 트레이드오프
    • 운영체제: 프로세스, 스레드, 스케줄링, 락, 동기화, 가상 메모리, 파일 시스템, IPC, 시스템 콜, I/O
    • 알고리듬, 자료구조, 복잡도 분석
    • 네트워크: 컴퓨터 간 통신, 신뢰성, 처리량, 지연시간, 계층 구조
    • 데이터베이스와 데이터 시스템: ACID, 트랜잭션, 격리 수준, 인덱스, 저장 방식, 관계, 데이터 모델링
    • 소프트웨어 설계와 아키텍처: 모듈성, 의존성과 책임 관리, 정보 은닉, 캡슐화, 계층, 클라이언트-서버, 이벤트, 결합도와 응집도
    • 상태와 데이터 흐름: 식별성, 단일 진실 공급원, 충돌 해결, 캐시와 메모이제이션, 상태 무효화, 상태 기계, 일관성과 동기화
    • 분산 시스템: CAP 정리, 복제, 지연, 파티션, 합의, 서비스 디스커버리, 최종적 일관성
    • 동시성과 병렬성: 락, 동기화, 병렬화 가능성, 경쟁 상태, 교착 상태
  • 모든 분야를 숙달할 필요도 없고 가능하지 않을 수 있지만, 각 분야를 조금씩 알고 선택한 몇 가지에서 뛰어나지는 것을 목표로 해야 함
  • 기초 원리에 초점을 맞추면 시간이 지나며 보편적 직관이라는 메타 기술이 생김
  • 컴퓨팅과 컴퓨터가 단독·클러스터에서 어떻게 작동하는지 깊이 이해하면, 계속 바뀌는 도구와 프레임워크의 세부사항에 덜 휘둘림
  • 이 수준에 이르면 새롭게 유행하는 도구를 배우는 일도 훨씬 쉬워짐

이해의 기쁨과 영향력

  • Leonardo da Vinci의 말처럼 “가장 고귀한 즐거움은 이해의 기쁨”임
  • 소프트웨어 개발에서 이해는 즐거움뿐 아니라 실용적인 영향력과 힘을 줌
  • 소프트웨어 공학의 범위는 매우 넓지만, 기초 원리에 집중하면 다룰 수 있는 영역이 커짐
  • 현재의 인지 한계를 계속 밀어붙이는 태도가 정기적인 기쁨과 영향력 확대로 이어짐
Read Entire Article