모호한 의견에서 본질을 찾기: 문제 정의와 Principal Engineer의 사고 방식
📌 이 글에서 다루는 내용
🔍 핵심 주제
- 본질을 찾는 능력의 정체: 상대의 말을 이해하는 게 아니라, 상대가 표현하지 못한 생각을 재구성하는 능력
- 증상과 원인의 분리: “검색이 불편해요”가 정말 검색 문제인지, 정보 구조 문제인지 갈라내기
- 문제 정의를 여러 개 만드는 훈련: 하나의 요구를 최소 3개의 문제 정의로 다시 쓰기
- Senior와 Principal의 차이: 기능을 잘 만드는 사람과, 무슨 문제를 풀지 정의하는 사람
🎯 이 글의 결론
뛰어난 엔지니어는 해결책을 빨리 떠올리는 사람이 아니라, 문제를 더 정확하게 정의하는 사람이다.
시작은 하나의 질문이었다
이 글은 하나의 질문에서 출발했다.
“타인이 대충 던진 의견도 핵심을 파악하고 구체화할 수 있는 능력은 무엇이며, 어떻게 키워야 할까?”
회의에서, 슬랙에서, 복도에서 우리는 매일 다듬어지지 않은 말들을 듣는다. “이거 좀 불편해요”, “검색이 느려요”, “안정성을 높이면 좋겠어요.” 대부분은 감정이거나 증상이거나, 반쯤만 완성된 생각이다. 그런데 어떤 사람은 그 반쪽짜리 문장에서 상대조차 정확히 몰랐던 진짜 문제를 끄집어낸다. 나는 오래전부터 그 능력의 이름이 궁금했다. 이름을 찾으면 훈련법도 보일 것 같았다.
이 능력의 정체
결론부터 말하면, 이 능력은 하나의 단어로 정의되지 않는다. 다음 능력들의 조합에 가깝다.
- 추상화(Abstraction) — 구체적인 현상을 한 단계 위 개념으로 끌어올리기
- 구조화(Structuring) — 흩어진 말을 사실·문제·목표·제약으로 정렬하기
- 문제 정의(Problem Framing) — 무엇을 풀 문제로 삼을지 결정하기
- 본질 파악(First Principles Thinking) — 관습이 아니라 근본에서 다시 쌓기
- 질문하는 능력 — 답이 아니라 더 나은 질문을 던지기
핵심은 이것이다. 상대가 한 말을 이해하는 것이 아니라, 상대가 표현하지 못한 생각을 재구성하는 능력. 즉,
말을 듣는 능력이 아니라, 생각을 구조화하는 능력이다.
어떻게 사고하는가 — 증상과 원인을 분리한다
예를 들어 “검색이 불편해요”라는 말을 들었다고 하자. 이 능력이 없는 사람은 곧장 해결책으로 뛴다. “검색창을 크게 하자”, “자동완성을 붙이자.” 반면 이 능력이 있는 사람은 해결책 대신 질문을 먼저 꺼낸다.
- 언제 불편한가?
- 무엇이 불편한가?
- 검색 속도인가?
- 검색 결과인가?
- 탐색 구조인가?
이 질문들을 따라가다 보면 종종 놀라운 사실을 만난다. 이건 “검색” 문제가 아니라 “태그 구조” 문제이거나, 더 근본적으로는 “정보 구조” 문제일 수도 있다는 것. 사용자는 검색창 앞에서 불편을 느꼈지만, 진짜 원인은 애초에 검색에 의존할 수밖에 없게 만든 콘텐츠 구조에 있다.
핵심은 하나다. 증상과 원인을 분리하는 것. 사용자가 가리키는 곳은 아픈 곳이지, 병의 위치가 아니다.
좋은 사고의 순서 — 한눈에 보기
좋은 사고는 요구에서 해결책으로 직행하지 않는다. 사실에서 시작해 여러 단계를 거친다.
flowchart LR
F["사실<br/>Fact"] --> P["문제<br/>Problem"]
P --> C["원인<br/>Cause"]
C --> G["목표<br/>Goal"]
G --> K["제약<br/>Constraint"]
K --> S["해결책<br/>Solution"]
P -. "여기서 바로 뛴다" .-> S
많은 사람은 Problem에서 곧장 Solution으로 점프한다(점선 경로). 문제를 하나로 확정하자마자 답을 찾기 시작하는 것이다. 하지만 뛰어난 사람은 다르다. Problem을 여러 개 정의한 뒤에 Solution을 고른다. 문제 정의가 하나뿐이면 해결책도 하나로 정해지지만, 문제 정의가 셋이면 서로 다른 세 갈래의 해결책이 후보로 열린다.
훈련 방법 다섯 가지
이 능력은 재능이 아니라 습관이다. 나는 다음 다섯 가지를 반복 훈련으로 삼는다.
(1) 구조화 — 회의를 다섯 칸으로 정리한다
회의가 끝나면 오간 말을 다음 다섯 칸에 나눠 담는다.
- Fact — 관찰된 사실 (측정값, 실제로 일어난 일)
- Problem — 무엇이 문제인가
- Goal — 어떤 상태가 되면 해결된 것인가
- Constraint — 시간·비용·인력·기술의 제약
- Solution — 그래서 무엇을 할 것인가
말들이 감정인지 사실인지, 문제인지 해결책인지 자리를 찾아주는 것만으로도 논의의 절반은 정리된다.
(2) 추상화 — 한 단계 위 개념으로 올린다
구체적인 말을 한 단계 위 개념으로 바꾼다.
버튼이 많다 → 인지 부하가 높다 → 사용성이 낮다
“버튼이 많다”에 머물면 “버튼을 줄이자”밖에 안 나온다. “인지 부하”까지 올라가면 그룹핑·기본값·점진적 노출 같은 다른 해법이 보인다.
(3) 구체화 — 추상적인 말을 분해한다
반대 방향의 훈련도 필요하다. 추상적인 말을 들으면 그것이 구체적으로 무엇을 의미하는지 분해한다.
안정성을 높인다 → 어떤 안정성? 장애율? SLA? 메모리? 복구 시간(MTTR)?
“안정성”은 아름답지만 텅 빈 단어다. 무엇을 측정할지 정하지 못하면 개선했는지조차 알 수 없다.
(4) 여러 관점으로 보기
동일한 문제를 여러 이해관계자의 언어로 각각 설명해 본다.
- 사용자 관점: 무엇이 불편하고 무엇을 기대하는가
- 개발자 관점: 구현·유지보수 비용은
- 운영 관점: 배포·모니터링·장애 대응은
- 비용 관점: 인프라·인건비 트레이드오프는
- 보안 관점: 새로 열리는 공격면은
한 관점에서 최적인 답이 다른 관점에서는 최악인 경우가 흔하다. 관점을 바꿔 설명해 보면 그 충돌이 미리 드러난다.
(5) 한 문장으로 요약
회의가 끝나면 스스로에게 묻는다. “결국 핵심은 무엇인가?” 이걸 한 문장으로 못 쓰면, 아직 문제를 이해하지 못한 것이다. 한 문장은 이해의 리트머스 시험지다.
가장 중요한 훈련: 요구 하나를 문제 정의 셋으로
위의 다섯 가지 중에서도 사고 수준을 가장 크게 끌어올린 훈련은 따로 있다.
요구사항을 들으면 바로 해결책을 생각하지 말고, 최소 3개의 문제 정의를 만들어 본다.
이 한 가지 습관이 전부를 바꾼다. 해결책은 매력적이라 우리를 빨리 붙잡는다. 하지만 매력적인 해결책 하나는 대안을 볼 눈을 닫아 버린다. 문제를 세 가지로 다시 쓰는 순간, 뇌는 “어떻게 풀까”에서 “무엇을 풀 것인가”로 축을 옮긴다.
사례: “검색이 느립니다”
한 요구가 들어왔다. “검색이 느립니다.” 보통은 반사적으로 이렇게 생각한다. “Elasticsearch를 붙이자.” 하지만 문제 정의를 세 개로 늘려 보면 완전히 다른 세계가 열린다.
flowchart TB
R["요구: '검색이 느립니다'"]
R --> D1["문제 정의 1<br/>검색 알고리즘이 느리다"]
R --> D2["문제 정의 2<br/>사용자가 느리다고 느낀다"]
R --> D3["문제 정의 3<br/>검색을 너무 자주 한다"]
D1 --> S1["인덱스 튜닝<br/>Elasticsearch"]
D2 --> S2["스켈레톤 UI<br/>점진적 로딩"]
D3 --> S3["정보 구조 개선<br/>태그 · 카테고리"]
같은 한 문장이지만, 문제 정의가 달라지면 해결책도 완전히 달라진다.
- 정의 1(알고리즘이 느리다)은 실제 응답 시간이 느린 경우다. 인덱스, 쿼리, 검색 엔진의 문제 → Elasticsearch가 답이 될 수 있다.
- 정의 2(느리다고 느낀다)는 응답 시간은 멀쩡한데 체감이 나쁜 경우다. 로딩 중 빈 화면이 문제라면 스켈레톤 UI와 점진적 로딩이 답이다. 엔진을 바꿔도 체감은 그대로일 수 있다.
- 정의 3(너무 자주 검색한다)은 애초에 검색에 의존하지 않아도 되게 만드는 문제다. 정보 구조를 개선하고 태그·카테고리로 탐색을 돕는 것이 답이다. 검색 자체를 빠르게 하는 게 아니라 검색의 필요를 줄인다.
Elasticsearch로 직행했다면, 문제가 실은 2번이나 3번이었을 때 몇 주를 쓰고도 사용자는 여전히 “검색이 느려요”라고 말했을 것이다.
그래서 얻은 결론
여기서 하나의 문장이 남는다.
좋은 엔지니어는 문제를 해결하는 사람이다. 하지만 더 뛰어난 엔지니어는 문제를 다시 정의하는 사람이다.
Principal Engineer는 무엇이 다른가
문제 정의라는 주제는 자연스럽게 다음 질문으로 이어졌다. Principal Engineer는 무엇이 다른가?
많은 사람이 Principal Engineer를 “코드를 가장 잘 짜는 사람”이라고 생각한다. 하지만 실제 역할은 다르다. Principal Engineer는 조직 전체의 기술 방향을 결정하는 사람이다. 코드는 그 결정을 뒷받침하는 근거이자 수단이지, 역할의 본질이 아니다.
Senior와 Principal의 차이
| Senior Engineer | Principal Engineer | |
|---|---|---|
| 초점 | 기능을 잘 만든다 | 어떤 문제를 풀지 정의한다 |
| 품질 | 코드의 품질을 높인다 | 조직 전체의 기술 품질을 높인다 |
| 시간축 | 현재를 최적화한다 | 2~3년 뒤를 설계한다 |
Senior는 주어진 문제를 훌륭하게 푼다. Principal은 그 앞에 서서 “이게 정말 우리가 풀어야 할 문제인가?”를 먼저 묻는다. 앞의 문제 정의 훈련이 개인의 사고 습관이라면, Principal의 일은 그 습관을 조직의 의사결정 규모로 실행하는 것이다.
Principal Engineer의 사고 방식
회의에서 이런 의견이 나왔다고 하자. “Redis를 도입합시다.” Principal은 Redis를 곧바로 논의하지 않는다. 대신 한 단계 뒤로 물러선다.
flowchart TB
X["'Redis를 도입합시다'"] --> Q{"왜 Redis가<br/>필요한가?"}
Q --> A["속도 문제인가?"]
Q --> B["DB 부하 문제인가?"]
Q --> C["비용 문제인가?"]
Q --> D["동시성 문제인가?"]
Q --> E["사용자 경험 문제인가?"]
A -.-> Y["Redis는 '해결책'이지<br/>'문제'가 아니다"]
B -.-> Y
C -.-> Y
D -.-> Y
E -.-> Y
Principal이 분리해 내는 것은 단 하나다. Redis는 “문제”가 아니라 “해결책”이다. 팀이 해결책을 문제인 양 들고 오면, 그는 그 뒤에 숨은 진짜 문제를 먼저 드러낸다. 문제가 무엇이냐에 따라 Redis가 최선일 수도, 오히려 인덱스 하나 추가가 답일 수도, 캐싱이 아니라 쿼리 재설계가 답일 수도 있기 때문이다.
최종 결론
이 긴 사고의 여정은 결국 하나로 요약된다.
뛰어난 엔지니어는 해결책을 빨리 떠올리는 사람이 아니라, 문제를 더 정확하게 정의하는 사람이다.
그리고 이를 위해서는 추상화 · 구조화 · 질문 · 본질 파악 · 다양한 문제 정의 · 트레이드오프 분석을 반복적으로 훈련해야 한다. 특히 실무에서는 다음 질문 하나를 습관으로 만드는 것이 가장 효과적이었다.
이 요구사항을 최소 3개의 서로 다른 문제 정의로 해석할 수 있는가?
이 질문 하나가, Senior Engineer의 사고에서 Principal Engineer의 사고로 넘어가는 가장 중요한 전환점이다.
다음 학습 (Next Learning)
- Python Backend Engineer 직무 기술서 — 레벨별 역할과 요구 역량 맵
- The Pragmatic Programmer: 실용주의 장인의 습관 — 문제를 다루는 장인의 태도
- Domain-Driven Design — 문제 공간(도메인)을 먼저 이해하고 해결 공간을 설계하기