Showing Posts From
실수할
- 09 Dec, 2025
새 팀원이 실수할 때마다 드는 생각
새 팀원이 실수할 때마다 드는 생각 오늘도 PR이 날아왔다 알림이 울렸다. 신입 민수의 PR이다. 제목부터 불안하다. "로그인 기능 수정". 뭘 수정했길래. 코드를 열었다. 첫 줄부터 눈에 띈다. if (password == user.getPassword())문자열 비교를 ==로 했다. 자바 기본 중의 기본이다. 한숨이 나온다. 근데 참는다. 스크롤을 내린다. 더 있다. try { // 200줄의 로직 } catch (Exception e) { System.out.println("에러남"); }Exception을 그냥 잡아서 출력만 한다. 로그도 없다. 키보드에 손을 올렸다가 뗀다. 뭐라고 써야 하나. "이건 왜 이렇게 하셨나요?"는 너무 공격적이다. "equals() 써야 합니다"는 너무 교과서적이다. 결국 이렇게 쓴다. "문자열 비교는 equals() 메서드를 사용해주세요. == 연산자는 객체 참조를 비교해서 예상과 다르게 동작할 수 있습니다." 친절하게 썼다고 생각한다. 근데 속으로는 욕이 나온다. 이건 3년 차면 당연히 알아야 하는 거다. 아니, 신입도 알아야 한다.3년 전 내 코드가 떠오른다 근데 코멘트를 달다가 멈췄다. 문득 3년 전 내가 쓴 코드가 생각났다. 당시 팀장님이 내 PR에 코멘트를 달았었다. "N+1 쿼리 문제가 있을 것 같은데요. fetch join 고려해보시겠어요?" 그때 난 몰랐다. N+1이 뭔지도. 검색해서 알았다. 창피했다. 이런 기초도 모르고 있었다니. 근데 팀장님은 그냥 "고려해보시겠어요?"라고 물었다. 명령이 아니었다. 그래서 나도 찾아봤다. 공부했다. 고쳤다. 만약 팀장님이 "이것도 모르세요?"라고 했으면 어땠을까. 아마 위축됐을 거다. 질문도 못 했을 거다. 민수의 코드를 다시 본다. 완벽하진 않다. 근데 노력은 보인다. 변수명도 신경 썼고, 주석도 달았다. 틀렸지만. 코멘트를 수정한다. "equals()를 쓰면 더 안전합니다. 참고: [자바 문자열 비교 docs 링크]" 이 정도면 될 거다.당연한 게 어디 있나 점심시간이다. 민수가 옆자리에 온다. "형, 코멘트 확인했어요. 제가 equals()를 써야 하는 이유를 몰랐네요." 솔직하다. 좋다. "응, == 연산자는 객체 주소를 비교하거든. 그래서 내용이 같아도 false가 나올 수 있어." "아... 그럼 항상 equals()를 써야 하나요?" 질문이 나왔다. 좋은 신호다. "문자열은 그래. 근데 equals()도 null 체크를 해야 해. 아니면 Objects.equals()를 쓰거나." 민수가 고개를 끄덕인다. 노트에 적는다. 예전엔 이런 게 답답했다. '이 정도는 당연한 거 아닌가?' 근데 지금은 안다. 당연한 게 없다는 걸. 나도 7년 차지만 모르는 게 수두룩하다. 어제도 코틀린 코루틴 관련해서 검색했다. 3시간 걸렸다. 리액트 개발자한테 물어봤다. "이거 당연한 건가요?" 했더니 웃었다. "저도 처음엔 헷갈렸어요. 당연한 거 없어요." 그 말이 위로가 됐다. 민수한테도 그래야겠다고 생각한다. "당연한 거 없어. 다 배우는 거야."실수를 바라보는 법 민수의 두 번째 PR이 왔다. 이번엔 equals()를 썼다. 그런데. if (user.getName().equals(null))null을 뒤에 뒀어야 했는데 앞에 뒀다. NPE 터진다. 또 한숨이 나온다. 근데 참는다. 코멘트를 단다. "null 체크는 null을 뒤에 두면 안전합니다. 혹은 Objects.equals() 추천드려요." 이번엔 왜냐고 안 물었다. 예시 코드를 같이 올렸다. // NPE 위험 if (user.getName().equals(null))// 안전 if (null == user.getName()) if (Objects.equals(user.getName(), null))30분 뒤에 답이 왔다. "아 이런 방법이! 감사합니다!" 수정 커밋이 올라왔다. Objects.equals()를 썼다. approve를 눌렀다. 실수는 반복된다. 어쩔 수 없다. 나도 지금 실수한다. 어제 배포에서 env 파일 빠뜨렸다. 30분 롤백했다. 팀장님이 뭐라고 했나. "괜찮아요. 다음엔 체크리스트 만들어봐요." 혼내지 않았다. 해결 방법을 알려줬다. 그래서 나도 민수한테 그렇게 한다. "틀렸네요"가 아니라 "이렇게 하면 더 좋아요"로. "이것도 몰라요?"가 아니라 "저도 헷갈렸어요"로. 시간이 오래 걸린다. 설명하는 게 직접 고치는 것보다 3배는 느리다. 근데 이게 맞는 거 같다. 민수가 스스로 고치고, 이해하고, 다음엔 안 틀리는 게 낫다. 내가 고쳐주면 당장은 빠르다. 근데 민수는 배우지 못한다. 그럼 똑같은 실수를 반복한다. 결국 더 느리다. 가르치는 게 배우는 거다 리뷰를 하다 보니 내가 더 배운다. 왜 equals()를 써야 하는지 설명하려면 내부 동작을 알아야 한다. 그래서 다시 찾아봤다. String pool이랑 intern() 메서드까지. 7년 차인데 제대로 몰랐다. 그냥 쓰기만 했다. 민수한테 설명하려고 정리했다. 내가 더 명확해졌다. null 체크도 그렇다. "왜 null을 뒤에 둬요?" 물어봤을 때 대답을 못 했다. 그냥 그렇게 하라고 배웠으니까. 이유는 몰랐다. 찾아봤다. Yoda notation이라는 게 있었다. 스타워즈 요다에서 따온 이름이다. "null is name" 이런 식으로 읽힌다고. 재밌다. 근데 요즘엔 Objects.equals()를 더 권장한다는 것도 알았다. 민수 덕분에 배웠다. 예전 팀장님 말이 생각난다. "가르치는 게 제일 공부 많이 돼요." 맞는 말이다. 혼자 코드 짤 땐 대충 넘어간다. '일단 되네, 됐어.' 근데 누군가한테 설명하려면 제대로 알아야 한다. 그래서 찾아본다. 정리한다. 내 것이 된다. 민수가 물어볼 때마다 귀찮다. 솔직히 그렇다. 근데 동시에 고맙다. 내가 더 성장한다. 인내심이 필요하다 오늘 민수가 세 번째 실수를 했다. git commit에 node_modules를 올렸다. 200MB다. 한숨이 나온다. 또. ".gitignore에 추가해주세요"라고 썼다. 근데 민수가 ".gitignore가 뭐예요?"라고 물었다. 순간 멈췄다. 이것까지 모르나. 화가 났다. 솔직히 말하면. '깃도 제대로 모르고 어떻게 입사했지?' 근데 참았다. 심호흡했다. 예전 내가 생각났다. 첫 회사 들어가서 깃 쓸 줄 몰랐다. SVN만 써봤다. merge conflict 나면 패닉했다. 선배가 옆에 앉아서 30분 동안 알려줬다. 짜증 한 번 안 냈다. 그 선배 덕분에 깃을 배웠다. 지금도 감사하다. 그래서 민수한테 답했다. ".gitignore는 git에 올리지 않을 파일을 정의하는 거예요. 같이 볼까요?" 화면 공유했다. 10분 설명했다. "아~ 이래서 템플릿이 있었구나. 감사합니다!" 민수가 이해했다. 다음 커밋엔 제대로 했다. 인내심이 필요하다. 매일. 실수는 반복된다. 다른 실수지만. 그때마다 설명한다. 참는다. 기다린다. 3개월 뒤면 민수도 달라질 거다. 6개월 뒤면 더. 1년 뒤엔 혼자 할 수 있을 거다. 그럼 나도 편해진다. 지금 투자하는 시간이 나중을 위한 거다. 그렇게 생각하면 견딜 만하다. 완벽한 사람은 없다 퇴근 전에 슬랙 메시지가 왔다. 팀장님이다. "개발님, 오늘 배포 건 확인 부탁드려요." 내가 짠 코드다. 테스트 다 통과했다. 배포했다. 10분 뒤에 알림이 울렸다. 에러다. 로그를 봤다. NullPointerException. 내 코드에서 났다. null 체크를 안 했다. 아까 민수한테 null 체크하라고 했는데. 나도 안 했다. 창피했다. 얼굴이 뜨겁다. 급하게 고쳤다. 롤백하고 재배포했다. 팀장님한테 보고했다. "제가 null 체크를 빠뜨렸습니다. 죄송합니다." "괜찮아요. 급한 건 아니었으니까. 다음부턴 조심하시면 돼요." 혼나지 않았다. 오히려 위로받았다. 그제야 깨달았다. 나도 실수한다. 매일. 7년 차도 이런데 3개월 차는 오죽할까. 민수의 실수가 이해됐다. 완전히. 당연한 게 없다. 누구한테도. 시니어도 틀린다. 주니어는 더 틀린다. 당연하다. 그래서 서로 봐줘야 한다. 코드 리뷰로. 페어 프로그래밍으로. 혼자선 못 본다. 같이 봐야 한다. 결국 팀이다 민수가 한 달 지났다. 실수는 여전히 한다. 근데 줄었다. 같은 실수는 안 한다. 새로운 실수를 한다. 그게 성장이다. 어제 민수가 내 코드에 코멘트를 달았다. "형, 이 부분 Optional 쓰면 더 안전할 것 같아요." 맞는 말이다. 내가 놓쳤다. approve 눌렀다. "좋은 지적이에요. 고맙습니다." 민수가 웃는 이모지를 보냈다. 이게 팀이다. 서로 실수하고, 서로 고쳐주고, 서로 배운다. 완벽한 사람은 없다. 완벽한 코드도 없다. 그래서 같이 한다. 리뷰하고, 논의하고, 개선한다. 민수의 실수를 볼 때마다 짜증났다. 솔직히. 근데 지금은 안다. 그게 과정이라는 걸. 나도 그 과정을 거쳤다. 지금도 거치고 있다. 앞으로도 실수할 거다. 민수도, 나도. 그때마다 서로 알려주면 된다. "이렇게 하면 더 좋아요." "저도 헷갈렸어요." "같이 볼까요?" 그게 시니어가 하는 일이다. 코드를 잘 짜는 것만이 아니다. 팀을 키우는 것도. 민수가 1년 뒤엔 또 달라질 거다. 2년 뒤엔 더. 그럼 나도 편해진다. 민수한테 맡길 수 있다. 그리고 민수도 후배를 가르칠 거다. "당연한 거 없어. 다 배우는 거야." 내가 했던 말을.내일도 민수의 PR이 올 거다. 또 실수가 있을 거다. 그래도 괜찮다. 인내심 가지고 본다.