# 인지 부하가 중요합니다 ## 소개 (Introduction) 세상에는 수많은 유행어와 모범 사례가 있지만, 대부분은 실패했습니다. 우리에게는 더 근본적인 것, 틀릴 수 없는 무언가가 필요합니다. 때때로 우리는 코드를 살펴보면서 혼란을 느낍니다. 혼란은 시간과 비용을 초래합니다. 혼란은 높은 *인지 부하*로 인해 발생합니다. 높은 인지 부하는 화려하고 추상적인 개념이 아니라 **근본적인 인간의 제약**입니다. 상상 속의 존재가 아니라 실제로 존재하며 우리가 느낄 수 있는 것입니다. 우리는 코드를 작성하는 시간보다 읽고 이해하는 데 훨씬 더 많은 시간을 소비하므로, 코드에 과도한 인지 부하를 심고 있지는 않은지 끊임없이 자문해야 합니다. ## 인지 부하 (Cognitive load) > 인지 부하란 개발자가 작업을 완료하기 위해 생각해야 하는 양입니다. 우리는 코드를 읽을 때 변수 값, 제어 흐름 논리, 호출 순서와 같은 것들을 머릿속에 넣습니다. 평균적인 사람은 작업 기억에 대략 [4개의 덩어리](https://github.com/zakirullin/cognitive-load/issues/16)를 담을 수 있습니다. 인지 부하가 작업 기억의 임계값에 도달하면 내용을 이해하기가 훨씬 더 어려워집니다. *완전히 낯선 프로젝트의 수정 요청을 받았다고 가정해 봅시다. 정말 똑똑한 개발자가 이 프로젝트에 기여했다고 들었습니다. 수많은 멋진 아키텍처, 화려한 라이브러리, 유행하는 기술이 사용되었습니다. 다시 말해, **작성자가 우리에게 높은 인지 부하를 안겨준 것입니다.***

|| 토큰은 requires ((!P<T> || !Q<T>))와 requires (!(P<T> || Q<T>))에서 다른 의미를 갖습니다. 첫 번째는 제약 조건 논리합이고, 두 번째는 예전의 논리 OR 연산자이며, 다르게 동작합니다.memcpy하는 것만으로는 추가적인 노력 없이 객체의 수명을 시작할 수 없습니다. 이것은 C++20 이전의 경우였습니다. C++20에서 수정되었지만 언어의 인지 부하는 증가했을 뿐입니다.🤯🤯0xd34df00d님 작성 감사합니다.
\n
롭 파이크
좋은 기사입니다.
안드레이 카르파티 (ChatGPT, 테슬라)
소프트웨어 공학에 대한 좋은 글입니다. 아마도 가장 사실에 가깝지만 가장 실천되지 않는 관점일 것입니다.
일론 머스크
사실입니다.
애디 오스마니 (크롬, 세계에서 가장 복잡한 소프트웨어 시스템)
똑똑한 개발자들이 최신 디자인 패턴과 마이크로서비스를 사용하여 인상적인 아키텍처를 만든 수많은 프로젝트를 보았습니다. 하지만 새로운 팀원이 변경을 시도했을 때, 모든 것이 어떻게 맞춰지는지 이해하는 데만 몇 주를 보냈습니다. 인지 부하가 너무 높아 생산성이 급락하고 버그가 증식했습니다.
아이러니한 점은? 이러한 복잡성을 유발하는 패턴 중 다수가 "클린 코드"라는 이름으로 구현되었다는 것입니다.
정말로 중요한 것은 불필요한 인지 부담을 줄이는 것입니다. 때로는 이것이 많은 얕은 모듈 대신 더 적고 깊은 모듈을 의미하기도 합니다. 때로는 관련된 로직을 작은 함수로 나누는 대신 함께 유지하는 것을 의미하기도 합니다.
그리고 때로는 영리한 해결책보다 지루하고 간단한 해결책을 선택하는 것을 의미하기도 합니다. 최고의 코드는 가장 우아하거나 정교한 코드가 아니라 미래의 개발자(자신 포함)가 빠르게 이해할 수 있는 코드입니다.
당신의 기사는 우리가 브라우저 개발에서 직면하는 문제들과 정말로 공감됩니다. 현대 브라우저가 가장 복잡한 소프트웨어 시스템 중 하나라는 당신의 말은 절대적으로 옳습니다. 크로미움에서 그 복잡성을 관리하는 것은 인지 부하에 대해 당신이 지적한 많은 점들과 완벽하게 일치하는 끊임없는 도전입니다.
크로미움에서 이를 처리하는 한 가지 방법은 신중한 구성 요소 격리와 하위 시스템(렌더링, 네트워킹, 자바스크립트 실행 등) 간의 잘 정의된 인터페이스를 통하는 것입니다. 유닉스 I/O를 사용한 깊은 모듈 예제와 유사하게, 우리는 상대적으로 간단한 인터페이스 뒤에 강력한 기능을 목표로 합니다. 예를 들어, 우리의 렌더링 파이프라인은 엄청난 복잡성(레이아웃, 합성, GPU 가속)을 처리하지만 개발자는 명확한 추상화 계층을 통해 상호 작용할 수 있습니다.
불필요한 추상화를 피하는 것에 대한 당신의 지적도 정말 마음에 와 닿았습니다. 브라우저 개발에서 우리는 웹 표준 및 호환성의 고유한 복잡성을 처리하면서 새로운 기여자가 코드베이스에 접근하기 쉽게 만드는 것 사이에서 끊임없이 균형을 맞춥니다.
때로는 복잡한 시스템에서도 가장 간단한 해결책이 최선일 때가 있습니다.
antirez (레디스)
완전히 동의합니다 :) 또한, 언급된 "소프트웨어 설계 철학"에서 빠졌다고 생각하는 것은 "설계 희생"이라는 개념입니다. 즉, 때로는 무언가를 희생하고 단순성이나 성능, 또는 둘 다를 얻을 수 있습니다. 저는 이 아이디어를 지속적으로 적용하지만 종종 이해받지 못합니다.
좋은 예는 제가 항상 해시 항목 만료를 거부했다는 사실입니다. 이것은 설계 희생입니다. 왜냐하면 최상위 항목(키 자체)에만 특정 속성이 있는 경우 설계가 더 간단해지고 값은 그냥 객체가 되기 때문입니다. 레디스에 해시 만료 기능이 추가되었을 때 좋은 기능이었지만 (실제로) 많은 부분에 많은 변경이 필요하여 복잡성이 증가했습니다.
또 다른 예는 제가 지금 하고 있는 벡터 세트, 새로운 레디스 데이터 유형입니다. 저는 레디스가 벡터에 대한 진실의 원천이 아니라 근사치 버전만 가져갈 수 있도록 결정했습니다. 그래서 디스크에 큰 부동 소수점 벡터를 유지하려고 하지 않고 삽입 시 정규화, 양자화를 할 수 있었습니다. 많은 벡터 DB는 사용자가 입력한 내용(전체 정밀도 벡터)을 기억한다는 사실을 희생하지 않습니다.
이것들은 단지 두 가지 임의의 예일 뿐이지만, 저는 이 아이디어를 모든 곳에 적용합니다. 이제 문제는 물론 올바른 것을 희생해야 한다는 것입니다. 종종 매우 큰 복잡성을 차지하는 5%의 기능이 있는데, 그것이 바로 없애야 할 좋은 것입니다 :D