협업과 인성 질문 - 갈등·실패·피드백
이 장에서 배우는 것
협업과 인성 질문은 성격이 좋은지 확인하는 잡담이 아니다. 면접관은 지원자가 의견이 다른 사람과 어떻게 일하는지, 실수를 어떤 근거로 설명하는지, 같은 문제를 줄이려고 무엇을 바꾸었는지 확인한다. 결과가 좋았다는 말보다 당시의 제약과 자신의 행동을 구분해서 말하는 능력이 중요하다.
앞 장에서 운영과 장애를 다룰 때는 문제를 발견하고 대응하는 과정에 집중했다. 이번에는 그 과정에서 사람들과 판단을 맞추고 자신의 행동을 고친 경험을 살핀다. 가상의 중고 거래 서비스 팀에 지원한 신입 개발자의 답변을 따라가며, 경험을 꾸미지 않고도 구체적인 답을 만드는 방법을 익힌다.
- 의견 충돌을 사람에 대한 평가가 아닌 판단 기준의 차이로 설명한다.
- 실패와 피드백 경험에서 자신의 행동, 결과, 남은 한계를 구분한다.
- 마감과 품질을 함께 고려하고 코드 리뷰와 질문에 필요한 근거를 준비한다.
- 회고 기록의 사실·감정·행동·다음 시도를 점검하는 프로그램으로 답변의 빈칸을 찾는다.
문제 상황
지원자는 세 명이 함께 만든 중고 거래 과제 프로젝트를 설명하고 있다. 발표까지 이틀 남았는데 판매자가 상품을 수정할 때 입력한 설명이 사라지는 문제가 발견되었다. 한 팀원은 사진 미리보기를 먼저 완성하자고 했고, 지원자는 수정 화면의 오류부터 고치자고 했다. 두 사람 모두 발표를 잘 마치려 했지만 중요하게 보는 위험이 달랐다.
지원자는 처음에 “사용자에게 중요한 기능부터 하자”라고만 말했다. 상대는 사진도 사용자에게 중요하다고 답했다. 대화는 제자리였다. 이후 지원자는 설명이 사라지는 재현 순서와 사진 미리보기가 없는 경우의 대체 화면을 함께 제시했다. 팀은 설명 손실을 먼저 고치고 사진 미리보기의 표시 범위를 줄이기로 합의했다.
면접관은 이 이야기를 듣고 묻는다.
“결국 본인 의견대로 한 것처럼 들리는데, 상대 의견 때문에 바뀐 부분도 있나요?”
여기서 “제가 설득을 잘했습니다”라고 답하면 합의의 실제 모습이 드러나지 않는다. 지원자는 자신이 원했던 전체 수정 범위 중 무엇을 내려놓았는지, 누가 어떤 일을 맡았는지, 결과를 어디까지 확인했는지 설명해야 한다. 면접은 이야기의 결말보다 그 결말을 만드는 동안의 판단을 더 자세히 묻는다.
경험을 평가 가능한 근거로 바꾸기
답변은 ‘결론 먼저 → 근거 → 내 경험·예시 → 한계와 대안’ 순서로 구성한다. 결론은 자신의 판단 원칙이다. 근거는 그 원칙이 당시 상황에 맞았던 이유다. 경험에서는 자신이 실제로 한 일을 말한다. 마지막에는 확인하지 못한 범위와 다음에 바꿀 일을 덧붙인다. 네 부분을 기계적으로 길게 말하기보다 질문에 맞는 근거를 고르는 것이 중요하다.
예를 들어 “갈등은 대화로 풀었습니다”는 결론처럼 보이지만 판단 기준이 없다. “서로 중요하게 보는 위험을 재현 결과로 비교했습니다”라고 말하면 뒤에 어떤 근거가 나와야 하는지 분명해진다. 그렇다고 모든 갈등을 실험으로 해결할 수 있다는 뜻은 아니다. 역할 분담이나 일정처럼 수치로 비교하기 어려운 문제에서는 담당자의 책임 범위와 합의 절차가 근거가 될 수 있다.
| 질문 | 의도 | 답변 핵심 | 꼬리 질문 |
|---|---|---|---|
| 팀원과 의견이 충돌한 경험이 있나요? | 차이를 다루는 방법 | 공통 목표, 판단 기준, 합의 과정 | 본인이 양보한 것은 무엇인가요? |
| 실패한 경험과 배운 점은 무엇인가요? | 책임 인식과 재발 방지 | 기대와 실제의 차이, 내 행동, 변경 | 그 변경이 효과가 있었나요? |
| 피드백을 받고 바꾼 일이 있나요? | 수용과 검증 능력 | 피드백 내용, 수정, 확인 결과 | 동의하지 않은 부분도 있나요? |
| 마감과 품질이 충돌하면 어떻게 하나요? | 위험과 범위 조정 | 필수 기준, 줄일 범위, 공유 시점 | 일정을 지킬 수 없다면요? |
| 코드 리뷰에서 지적받으면 어떻게 하나요? | 논의 태도와 근거 | 의도 확인, 수정 또는 근거 있는 제안 | 취향 차이라면 어떻게 하나요? |
| 모르는 것을 언제 질문하나요? | 독립성과 협력의 균형 | 시도한 일, 막힌 지점, 필요한 도움 | 상대도 답을 모르면요? |
| 팀원이 맡은 일을 끝내지 못하면요? | 문제 공유와 역할 조정 | 막힌 이유 확인, 범위와 담당 재합의 | 대신 처리하면 해결되나요? |
| 본인의 실수를 어떻게 알리나요? | 투명성과 대응 우선순위 | 확인된 영향, 불확실성, 다음 행동 | 영향을 아직 모른다면요? |
| 기여도가 낮았던 경험도 있나요? | 자기 인식과 정직성 | 실제 역할, 부족했던 이유, 개선 | 팀 성과와 개인 성과를 나눠 보세요. |
| 같은 문제가 반복되면 무엇을 바꾸나요? | 개인 반성을 절차로 연결하는 능력 | 작은 규칙, 적용 조건, 확인 방법 | 규칙이 부담만 늘리면요? |
사실·감정·행동·다음 시도를 나눈다
사실은 다른 사람이 기록이나 재현으로 확인할 수 있는 내용이다. 감정은 그 상황에서 자신이 느낀 반응이다. 행동은 자신이 실제로 한 일이다. 다음 시도는 비슷한 상황에서 적용할 구체적인 변화다. 감정은 없애야 할 잡음이 아니다. 당황해서 공유를 늦췄다면 감정과 행동의 연결을 살펴볼 필요가 있다. 다만 “무시당했다”는 느낌을 곧바로 상대의 의도라는 사실로 바꾸지 않는다.
“팀원이 무책임해서 일정이 밀렸다”는 문장에는 평가와 원인 추정이 섞여 있다. “합의한 시점에 수정 화면이 연결되지 않았다”는 사실, “발표가 걱정되었다”는 감정, “남은 작업을 함께 나누었다”는 행동으로 나누면 추가로 확인할 것이 보인다. 상대가 왜 늦었는지 듣지 않았다면 그 부분은 모른다고 남겨 두어야 한다.
네 항목이 있다고 답변이 충분해지는 것은 아니다. “다음에는 잘하겠다”는 다음 시도 칸을 채우지만 실행 조건이 없다. “완료 예상이 합의한 시점을 넘길 것으로 보이면 다음 회의 전에 막힌 이유와 줄일 범위를 공유하겠다”처럼 언제 무엇을 할지 적어야 한다. 뒤에서 만드는 점검기도 항목의 존재만 확인하며, 문장의 구체성이나 진실성을 판정하지 않는다.
경험의 크기보다 경계를 정확히 말한다
업무 경험이 없다면 과제나 개인 프로젝트에서 실제로 겪은 일을 사용한다. 함께 정한 제출 순서가 어긋난 경험, 설명이 부족한 변경 요청을 다시 쓴 경험도 근거가 된다. 다만 혼자 생각을 바꾼 일을 팀 갈등으로 포장하지 않는다. 협업 경험이 적다면 그 사실을 먼저 밝히고, 가장 가까운 실제 사례와 입사 후 적용할 방법을 구분해서 말한다.
“팀 개발에서 큰 의견 충돌을 해결한 경험은 아직 없습니다. 수업 과제에서 역할 범위를 다시 정한 경험은 있습니다. 당시 제가 한 일은 남은 작업을 정리하고 분담안을 제안한 것이며, 최종 결정은 팀이 함께 했습니다.”
설명용 예시를 자신의 경험처럼 외우면 꼬리 질문에서 담당 범위와 결과가 어긋난다. 아래 답변도 구성 방법을 보여 주는 가상 사례다. 실제 면접에서는 자신의 기록으로 바꾸어야 한다. 수치가 기억나지 않으면 추정치를 사실처럼 말하지 말고, 어떤 결과를 확인했는지 설명한다.
네 가지 질문을 끝까지 답하기
의견 충돌: 이긴 사람이 아니라 합의의 근거를 설명한다
| 구분 | 답변 예시 | 면접관이 확인할 수 있는 것 |
|---|---|---|
| 나쁜 답 | 팀원이 고집을 부려서 제가 끝까지 설득했습니다. | 상대 평가만 있고 판단 근거가 없다. |
| 보통 답 | 오류 수정이 더 중요하다고 설명해서 먼저 처리했습니다. | 우선순위는 보이지만 합의 과정이 빠져 있다. |
| 좋은 답 | 설명 손실과 미리보기 부재의 영향을 비교하고, 오류 수정과 화면 범위 축소를 함께 합의했습니다. | 비교 기준과 조정한 범위가 보인다. |
“의견이 다를 때는 공통 목표와 확인 가능한 영향을 먼저 맞추려 합니다. 중요하다는 표현만으로는 서로 다른 위험을 비교하기 어려웠기 때문입니다. 중고 거래 과제에서 저는 상품 수정 오류를, 팀원은 사진 미리보기를 우선하자고 했습니다. 설명이 사라지는 순서를 함께 재현하고, 미리보기 없이도 선택한 파일명을 보여 줄 수 있음을 확인했습니다. 팀은 설명 손실을 먼저 고치고 미리보기 범위를 줄였습니다. 저도 수정 화면의 문구 정리까지 하려던 계획을 미뤘습니다. 다만 발표 경로만 확인했으므로 다른 입력 조합까지 검증했다고 말할 수는 없습니다. 다음에는 우선순위를 정할 때 확인할 범위도 함께 적겠습니다.”
면접관이 “끝내 합의하지 못하면요?”라고 묻는다면 무조건 양보하거나 계속 설득한다고 답하지 않는다. 결정 시한과 책임자를 확인하고, 대안별 위험을 정리해 결정을 요청한다. 자신의 반대 근거를 남기되 결정 이후에는 맡은 일을 수행한다. 그 과정에서 새롭게 확인된 위험은 다시 공유할 수 있다.
실패: 반성의 강도보다 바뀐 행동을 보여 준다
| 구분 | 답변 예시 | 부족하거나 드러나는 근거 |
|---|---|---|
| 나쁜 답 | 다른 사람이 늦어서 실패했고 저는 할 일을 다 했습니다. | 자신이 영향을 줄 수 있었던 행동을 돌아보지 않는다. |
| 보통 답 | 일정 예측을 잘못했고 다음부터 더 신경 썼습니다. | 원인은 있으나 바뀐 행동을 확인하기 어렵다. |
| 좋은 답 | 화면 연결 시간을 빠뜨렸고, 이후에는 작업 목록에 연결 확인을 별도 항목으로 넣었습니다. | 예측의 누락과 변경한 절차가 연결된다. |
“제가 맡은 작업의 완료 기준을 좁게 잡아서 통합 확인이 늦어진 경험이 있습니다. 함수가 동작하면 끝났다고 판단했지만 실제로는 화면에서 결과를 확인해야 했습니다. 상품 수정 함수를 만든 뒤 완료로 표시했고, 발표 전날 화면과 연결하는 과정에서 설명이 사라지는 문제를 발견했습니다. 저는 상태 표시를 너무 일찍 바꾼 책임이 있습니다. 이후 작업 목록에 ‘화면에서 수정하고 다시 조회하기’를 넣었고, 다음 수정 작업에서는 연결 확인 후 완료로 표시했습니다. 그 한 번의 적용만으로 일정 예측이 좋아졌다고 단정할 수는 없습니다. 다음 작업에서도 누락된 확인이 있는지 기록해 기준을 다듬겠습니다.”
“그래서 실제 피해는 무엇이었나요?”라는 질문에는 과제의 규모를 부풀리지 않는다. 실제 사용자 데이터 손실이 아니라 발표 준비 시간이 줄어든 일이었다면 그대로 말한다. “운영 장애를 냈다”는 표현으로 경험을 키우는 대신, 어떤 준비가 밀렸고 팀에 언제 알렸는지를 설명한다.
피드백과 코드 리뷰: 동의 여부와 후속 행동을 연결한다
| 구분 | 답변 예시 | 면접관이 이어서 물을 지점 |
|---|---|---|
| 나쁜 답 | 리뷰는 다 받아들였습니다. 상대가 더 잘 알기 때문입니다. | 수정 이유를 이해했는가? |
| 보통 답 | 함수가 길다는 의견을 받고 나눴습니다. | 나눈 뒤 어떤 문제가 줄었는가? |
| 좋은 답 | 검증과 저장이 섞여 읽기 어렵다는 의견을 받고 경계를 나눈 뒤, 실패 경로를 함께 확인했습니다. | 변경 기준과 확인 범위를 설명할 수 있는가? |
“피드백은 해결하려는 문제를 이해한 뒤 반영하려 합니다. 제안을 그대로 적용해도 이유를 모르면 다음 코드에서 반복할 수 있기 때문입니다. 상품 등록 함수에 검증과 저장이 섞여 있다는 리뷰를 받았을 때, 어떤 경로를 따라가기 어려운지 물었습니다. 팀원은 검증 실패 후 저장이 실행되는지 한눈에 보기 어렵다고 했습니다. 저는 검증 부분을 분리하고 실패 시 저장하지 않는 경로를 함께 확인했습니다. 다만 함수를 나누는 것만으로 읽기 좋아지는 것은 아닙니다. 단순한 문장까지 잘게 나누면 흐름이 끊길 수 있어, 이름으로 역할을 설명할 수 있는 경계인지 같이 살폈습니다.”
“동의하지 않는 리뷰에는 어떻게 하나요?”라는 꼬리 질문에는 반례나 대안을 제시한다. “이 방식은 취향 같습니다”라고 대화를 닫기보다 해결하려는 문제와 팀의 기존 규칙을 묻는다. 두 방법의 차이가 작다면 합의한 규칙을 따르고, 오류 가능성이나 변경 비용이 다르다면 작은 예시로 비교한다. 리뷰하는 입장에서도 “이 코드는 이상하다”보다 “이 조건에서 저장이 실행될 수 있는지 함께 확인하고 싶다”처럼 대상과 이유를 명시한다.
마감과 품질: 줄일 것과 지킬 것을 구분한다
| 구분 | 답변 예시 | 판단의 특징 |
|---|---|---|
| 나쁜 답 | 마감이 중요하니 일단 올리고 나중에 고칩니다. | 허용하기 어려운 위험까지 미룰 수 있다. |
| 보통 답 | 중요한 기능부터 완성하고 나머지는 미룹니다. | 중요함의 기준과 결정 과정이 없다. |
| 좋은 답 | 데이터 손실 방지 기준을 지키고 부가 화면의 범위를 줄이는 안을 공유하겠습니다. | 품질 기준과 기능 범위를 나누어 판단한다. |
“마감이 촉박하면 먼저 지켜야 할 기준과 줄일 기능 범위를 나누겠습니다. 모든 작업을 같은 수준으로 줄이면 데이터 손실 같은 문제까지 남길 수 있기 때문입니다. 과제에서는 상품 설명을 보존하는 수정 흐름을 먼저 확인하고, 사진 미리보기의 표시 범위를 줄였습니다. 줄인 내용과 남은 제약은 팀이 함께 확인했습니다. 다만 실제 서비스에서 제가 혼자 공개 여부를 결정할 수는 없습니다. 필수 기준을 충족할 수 없다면 확인된 위험과 대안을 일찍 공유하고, 담당자와 일정 변경이나 해당 기능의 제공 보류를 결정하겠습니다.”
“야근해서 모두 끝내면 되지 않나요?”라는 질문에는 추가 시간만으로 해결되는지부터 구분한다. 작업량이 분명하고 짧은 추가 작업으로 끝나는 경우도 있다. 그러나 원인과 남은 시간이 불확실하다면 의지만으로 완료를 약속하기 어렵다. 가능한 선택지, 예상되는 영향, 다시 판단할 시점을 제시해야 한다.
질문과 회고를 반복 가능한 행동으로 만들기
모르는 것을 묻는 일에도 판단 기준이 필요하다. 짧은 탐색으로 해결할 수 있는 문제는 먼저 확인하되, 혼자 기다리는 시간이 다른 작업을 막는다면 일찍 알린다. 정해진 시간을 채웠는지만 보지 말고 문제의 영향과 자신이 가진 단서를 함께 본다. 질문에는 목표, 기대한 결과와 실제 결과, 시도한 일, 막힌 지점, 필요한 도움을 담는다.
“상품 설명을 수정한 뒤 다시 조회하면 빈 문자열이 나옵니다. 저장 직전 값과 조회 결과를 비교했고, 화면에서 값을 넘기는 부분까지 확인했습니다. 함수에 직접 값을 넣으면 보존됩니다. 화면 입력값이 전달되는 경로를 함께 확인해 주실 수 있나요?”
이 질문은 상대에게 전체 문제를 넘기지 않는다. 어디까지 확인했는지와 어떤 도움이 필요한지를 알려 준다. 오류 기록을 공유할 때는 계정 정보나 개인 정보가 들어 있지 않은지도 확인한다. 상대도 답을 모른다면 함께 확인할 범위를 나누고, 알아낸 내용을 기록한다. 답을 받은 뒤에는 해결 여부를 알려 대화를 닫는다.
회고 역시 적는 것만으로 끝나지 않는다. 다음 시도를 다음 작업의 확인 항목으로 옮겨야 한다. 프로그램은 빈 항목을 찾아 이 연결의 출발점을 만든다. 내용은 사람이 읽고 판단한다.
완성 코드
다음 내용을 main.py로 저장한다. 기록은 ‘분류: 내용’ 형식으로 작성한다. 프로그램은 콜론 앞의 표지를 읽어 문장을 네 항목으로 분류한다. 문장의 뜻을 추측하는 방식이 아니므로 작성자가 붙인 분류가 맞는지는 사람이 검토한다. 첫 기록에는 다음 시도가 없고, 두 번째에는 네 항목과 잘못 쓴 표지가 섞여 있다.
CATEGORIES = ("사실", "감정", "행동", "다음 시도")
RECORDS = (
(
"첫 회고",
(
"사실: 발표 전날 상품 수정 화면 연결이 끝나지 않았다.",
"감정: 준비 시간이 줄어들어 조급했다.",
"행동: 남은 작업과 막힌 지점을 팀에 공유했다.",
"행동: 사진 미리보기 범위를 줄이기로 함께 정했다.",
"다음 시도: ",
),
),
(
"보완 회고",
(
"사실: 함수 구현만 끝내고 작업을 완료로 표시했다.",
"감정: 완료 판단이 빨랐다는 점이 아쉬웠다.",
"행동: 화면에서 수정 후 조회하는 확인 항목을 추가했다.",
"다음 시도: 다음 수정 작업은 화면 확인 후 완료로 표시한다.",
"평가: 나는 협업을 잘한다.",
),
),
)
def classify(lines: tuple[str, ...]) -> tuple[dict[str, list[str]], list[str]]:
groups: dict[str, list[str]] = {name: [] for name in CATEGORIES}
unclassified: list[str] = []
for line in lines:
label, separator, body = line.partition(":")
label = label.strip()
body = body.strip()
if separator and label in groups and body:
groups[label].append(body)
elif line.strip():
unclassified.append(line.strip())
return groups, unclassified
def report(title: str, lines: tuple[str, ...]) -> None:
groups, unclassified = classify(lines)
print(f"[{title}]")
for name in CATEGORIES:
items = groups[name]
print(f"{name}: {len(items)}개")
for item in items:
print(f" - {item}")
missing = [name for name in CATEGORIES if not groups[name]]
print("빈칸: " + (", ".join(missing) if missing else "없음"))
print(f"미분류: {len(unclassified)}개")
for line in unclassified:
print(f" ? {line}")
if missing:
print("점검: 빈 항목을 실제 경험으로 보완한다.")
else:
print("점검: 네 항목이 있다. 구체성과 진실성은 사람이 확인한다.")
def main() -> None:
for index, (title, lines) in enumerate(RECORDS):
if index:
print()
report(title, lines)
if __name__ == "__main__":
main()
외부 패키지와 파일 입력은 사용하지 않는다. 난수와 현재 시각도 사용하지 않으므로 같은 코드로 실행하면 같은 결과가 나온다. 회고의 개수를 점수로 바꾸지 않는 이유는 항목의 존재와 협업 역량이 서로 다른 판단이기 때문이다.
줄별 해설
CATEGORIES는 허용하는 네 분류와 출력 순서를 정한다. 집합이 아니라 튜플로 두어 순서를 명시한다. RECORDS는 제목과 문장 묶음으로 이루어진 고정 입력이다. 첫 기록의 다음 시도는 표지만 있고 내용이 없도록 구성했다. 이 문장을 유효한 항목으로 세지 않는지가 첫 번째 확인 대상이다.
classify의 인자는 문자열 튜플이다. 반환값은 분류별 문장 목록을 담은 사전과 미분류 문장 목록의 쌍이다. 형 표기는 자료의 모양을 설명하며, 실행 중 입력 형식을 자동으로 검사하는 장치는 아니다. 이 예제에서는 코드 안의 고정 입력이 해당 형식을 따른다.
groups를 만드는 줄은 네 분류마다 새 목록을 만든다. unclassified는 인식하지 못한 문장을 보존한다. 입력을 조용히 버리면 표지 오타나 빈 내용을 알아차리기 어려우므로 별도 목록에 남긴다.
partition(":")은 첫 콜론을 기준으로 표지, 구분자, 내용을 나눈다. 콜론이 없으면 구분자는 빈 문자열이 된다. 내용 안에 콜론이 더 있어도 첫 콜론 뒤의 내용은 그대로 유지된다. 이어지는 두 strip() 호출은 표지와 내용의 앞뒤 공백을 제거한다.
if separator and label in groups and body는 구분자가 있고, 알려진 표지이며, 공백을 제외한 내용도 있을 때만 분류한다. elif line.strip()은 비어 있지 않은 나머지 문장을 미분류에 넣는다. 따라서 빈 줄은 무시하지만 ‘다음 시도:’처럼 표지만 있는 줄은 점검 대상으로 남긴다.
report는 분류 함수를 호출한 뒤 정해진 순서로 개수와 내용을 출력한다. missing을 만드는 줄은 목록이 비어 있는 항목의 이름을 모은다. 네 항목이 모두 있더라도 문장의 질을 확인한 것은 아니므로 출력 문구도 그 한계를 밝힌다.
main은 두 기록을 차례로 출력한다. enumerate의 첫 번호는 0이므로 첫 기록 앞에는 빈 줄을 찍지 않고 이후 기록 사이에만 빈 줄을 넣는다. 마지막 조건문은 이 파일을 직접 실행했을 때 main을 호출한다.
실행 결과
터미널에서 다음 명령을 실행한다.
python3 main.py
예상 출력은 다음과 같다.
[첫 회고]
사실: 1개
- 발표 전날 상품 수정 화면 연결이 끝나지 않았다.
감정: 1개
- 준비 시간이 줄어들어 조급했다.
행동: 2개
- 남은 작업과 막힌 지점을 팀에 공유했다.
- 사진 미리보기 범위를 줄이기로 함께 정했다.
다음 시도: 0개
빈칸: 다음 시도
미분류: 1개
? 다음 시도:
점검: 빈 항목을 실제 경험으로 보완한다.
[보완 회고]
사실: 1개
- 함수 구현만 끝내고 작업을 완료로 표시했다.
감정: 1개
- 완료 판단이 빨랐다는 점이 아쉬웠다.
행동: 1개
- 화면에서 수정 후 조회하는 확인 항목을 추가했다.
다음 시도: 1개
- 다음 수정 작업은 화면 확인 후 완료로 표시한다.
빈칸: 없음
미분류: 1개
? 평가: 나는 협업을 잘한다.
점검: 네 항목이 있다. 구체성과 진실성은 사람이 확인한다.
첫 회고는 행동을 두 개 적었지만 다음 시도가 비었다. 행동을 많이 적는다고 빠진 항목이 채워지지는 않는다. 보완 회고의 ‘빈칸 없음’도 합격 판정이 아니다. ‘나는 협업을 잘한다’는 문장은 알려진 분류가 아니어서 미분류로 남았으며, 네 항목의 존재와 별도로 검토해야 한다.
실무에서 자주 틀리는 것
공백만 있는 내용을 유효한 기록으로 센다
다음 코드는 공백 문자열도 값이 있다고 판단한다. 다음 시도를 적지 않았는데 빈칸이 사라지는 문제가 생긴다.
body = " "
if body:
print("내용 있음")
앞뒤 공백을 제거한 뒤 내용이 남는지 확인한다. 공백 제거는 의미를 검증하지는 않지만, 빈 문자열을 항목으로 세는 오류를 막는다.
body = " ".strip()
if body:
print("내용 있음")
else:
print("내용 없음")
모든 콜론을 나누어 내용까지 깨뜨린다
내용에도 콜론이 있으면 다음 대입은 나뉜 조각이 너무 많아 실패한다.
line = "행동: 팀에 공유했다: 남은 작업과 막힌 지점"
label, body = line.split(":")
첫 콜론만 경계로 삼고 구분자가 없는 경우도 처리한다. 이렇게 해야 내용을 쓰는 사람이 콜론을 피할 필요가 없다.
line = "행동: 팀에 공유했다: 남은 작업과 막힌 지점"
label, separator, body = line.partition(":")
if separator:
print(label.strip())
print(body.strip())
분류별 목록이 같은 객체를 가리키게 만든다
다음 코드는 하나의 빈 목록을 모든 분류의 값으로 사용한다. 사실에 문장을 추가하면 다른 분류에서도 같은 문장이 보인다.
groups = dict.fromkeys(CATEGORIES, [])
groups["사실"].append("수정 화면 연결이 늦었다.")
분류마다 별개의 목록을 만들어야 한다. 회고에서 서로 다른 항목을 섞지 않으려는 목적이 자료 구조에도 반영되어야 한다.
groups = {name: [] for name in CATEGORIES}
groups["사실"].append("수정 화면 연결이 늦었다.")
형식 점검을 사람에 대한 평가로 확대한다
네 칸을 채운 것만으로 협업을 잘한다고 결론 내릴 수 없다. 사실 칸에 추측을 적거나 행동 칸에 다른 사람의 기여를 적어도 이 프로그램은 구분하지 못한다.
if all(groups[name] for name in CATEGORIES):
print("협업 역량 우수")
자동으로 확인한 범위만 보고한다. 면접 준비에서도 빈칸을 찾는 도구와 경험을 검토하는 사람의 역할을 구분한다.
if all(groups[name] for name in CATEGORIES):
print("항목 누락 없음. 근거와 담당 범위는 직접 확인한다.")
한눈에 보기
| 주제 | 드러낼 근거 | 마지막 점검 |
|---|---|---|
| 의견 충돌 | 공통 목표, 서로의 우려, 바뀐 범위 | 상대 의견 때문에 달라진 점이 있는가? |
| 실패 | 기대와 실제의 차이, 자신의 판단 | 이후 바뀐 행동을 말할 수 있는가? |
| 피드백 | 문제 이해, 수정 이유, 확인 결과 | 수용했다는 말 뒤에 행동이 있는가? |
| 마감과 품질 | 필수 기준, 줄일 범위, 결정 주체 | 불확실한 완료를 약속하지 않았는가? |
| 질문하기 | 목표, 실제 결과, 시도, 요청 | 상대가 어디부터 도우면 되는가? |
| 정직한 설명 | 내 역할, 팀의 역할, 확인 범위 | 추정이나 예시를 실제 경험으로 말하지 않는가? |
| 회고 점검기 | 네 분류의 존재와 미분류 문장 | 형식 충족을 역량 판정으로 바꾸지 않는가? |
연습 문제
- “팀원이 제 의견을 무시해서 답답했다. 그래서 제가 전부 고쳤다”라는 회고를 사실·감정·행동·다음 시도로 검토하라. 주어진 문장으로 확인할 수 없는 내용은 만들지 말고, 추가로 확인할 질문 두 개를 적어라.
- 점검기에 “행동: 팀에 공유했다: 남은 작업과 막힌 지점”과 “다음 시도”를 입력하면 각각 어떻게 처리되는지 설명하라. 두 번째 문장을 임의로 다음 시도로 분류하지 않는 이유도 적어라.
- 네 분류가 모두 한 문장 이상일 때도 ‘다음 시도: 다음에는 잘한다’가 유용한 계획인지 프로그램은 알 수 없다. 사람이 확인할 기준 두 개를 제시하고 이 문장을 구체적으로 바꾸어라. 실제 경험이 아니라 계획의 예시임을 밝혀라.
- 마감 전날 상품 설명 손실 문제와 사진 미리보기 작업이 남았다. ‘결론 먼저 → 근거 → 내 경험·예시 → 한계와 대안’ 순서로 답하라. 실제 경험이 없다면 상황에 대한 가정 답변으로 쓰고, 팀에 공유할 선택지와 결정 주체를 포함하라.
정답과 해설
- ‘답답했다’는 감정이고 ‘제가 전부 고쳤다’는 행동에 대한 주장이다. ‘무시했다’는 상대의 의도를 해석한 표현일 수 있어 그대로 사실로 확정하기 어렵다. 어떤 제안에 어떤 답이 왔는지 확인해야 한다. 다음 시도는 제시되지 않았다. 추가 질문은 “제안과 상대의 응답을 구체적으로 설명할 수 있는가?”와 “전부 고쳤다는 작업 범위는 무엇이며 분담 변경에 합의했는가?”가 될 수 있다. 답을 얻기 전에는 대화나 결과를 새로 만들어 채우지 않는다.
- 첫 문장은 첫 콜론을 경계로 행동에 분류된다. 내용은 ‘팀에 공유했다: 남은 작업과 막힌 지점’으로 보존된다. 두 번째 문장은 구분자가 없으므로 미분류에 들어간다. 글자가 분류 이름과 같더라도 수행할 내용이 없으며, 표지 없는 문장의 뜻을 추측하는 것은 이 프로그램의 기능 범위에 포함되지 않는다.
- 발동 조건이 있는지, 실행 후 확인할 행동이 있는지를 살필 수 있다. 계획 예시는 “작업을 완료로 바꾸기 전에 화면에서 수정한 값이 다시 조회되는지 확인하고 결과를 작업 목록에 남긴다”다. 이 문장도 실제로 수행했는지는 별도로 확인해야 한다. 계획을 적은 사실과 개선 효과가 나타난 사실은 구분한다.
- 가정 답변은 다음처럼 구성할 수 있다. “설명 손실을 막는 기준을 먼저 지키고 미리보기 범위를 줄이는 안을 제안하겠습니다. 입력 내용이 사라지는 문제는 상품 수정의 기본 목적을 해치기 때문입니다. 제시된 상황에서는 손실을 재현한 결과와 파일명만 표시하는 대체안을 팀에 공유하겠습니다. 다만 수정 시간과 영향 범위를 아직 모르므로 완료를 약속하지 않겠습니다. 팀의 결정 담당자와 기능 제공 보류 또는 일정 변경을 포함해 선택하고, 다시 판단할 시점을 정하겠습니다.” 실제 경험을 묻는 자리라면 먼저 해당 경험이 없음을 밝히고 이 가정 답변을 구분해서 제시한다.