Showing Posts From

눈치

8개월 차, 아직도 컴포넌트 분리를 헷갈리는 이유

8개월 차, 아직도 컴포넌트 분리를 헷갈리는 이유

8개월 차, 아직도 컴포넌트 분리를 헷갈리는 이유 오늘도 코드리뷰에서 혼났다 출근하자마자 슬랙 알림. 심장이 쿵 내려앉았다. "이신입님, 이 컴포넌트 너무 크지 않나요? 분리하면 좋을 것 같은데요." 민수 선배다. 항상 친절하게 말하지만 그게 더 무섭다. 어제 올린 PR이었다. UserProfile.jsx 파일. 300줄짜리. "아... 네네 수정하겠습니다." 일단 답장부터. 그리고 코드를 다시 봤다. 뭘 분리하라는 건지 솔직히 모르겠다. 전부 프로필 관련 코드인데. 프로필 사진, 이름, 소개, 팔로우 버튼, 게시글 목록, 좋아요 수. 다 유저 프로필이잖아. 그럼 UserProfile 컴포넌트에 있는 게 맞는 거 아닌가. 근데 선배는 분리하래.8개월 됐다. 근데 아직도 모르겠다. 컴포넌트를 어떻게 나누는 게 정답인지. 부트캠프 때는 간단했다. 헤더는 Header.jsx, 버튼은 Button.jsx. 그게 끝이었다. 근데 실무는 다르다. UserProfile.jsx를 열면 그 안에 또 뭐가 들어가야 하는지. ProfileHeader? ProfileInfo? UserAvatar? FollowButton? 어디까지가 한 덩어리고 어디서부터 분리해야 하는지. 그냥 다 한 파일에 쓰면 안 되나. 길어도 Ctrl+F 하면 찾을 수 있는데. 선배들이 말하는 '재사용성' "재사용 가능하게 만들어야죠." 코드리뷰 댓글에 항상 나오는 말. 재사용성. 근데 뭘 재사용한다는 건지 모르겠다. 이 프로필 페이지는 프로필 페이지에서만 쓰는데. 다른 데서 언제 쓴다고. FollowButton을 분리했다. 그럼 다른 페이지에서도 팔로우 버튼 쓸 수 있으니까 재사용 가능한 거다. 이해했다고 생각했다. 근데 일주일 뒤 또 지적받았다. "ProfileInfo도 분리하면 좋을 것 같아요." ProfileInfo는 이름이랑 소개 보여주는 부분. 이건 어디서 재사용해. 프로필 페이지에서만 쓰는데. 물어봤다. 용기 내서. "선배님, 근데 ProfileInfo는 프로필에서만 쓰지 않나요?" "지금은 그렇죠. 근데 나중에 모달에서도 쓸 수도 있고, 카드 형태로 보여줄 수도 있잖아요." 나중에. 모달. 카드. 모르겠다. 나중은 언제고 모달은 아직 없는데 지금 분리하라는 건가.그래서 분리했다. ProfileInfo.jsx. 그 안에 이름이랑 소개만 넣었다. 30줄. 30줄짜리 파일을 만드는 게 맞나. components 폴더 열 때마다 파일이 수십 개다. 뭐가 뭔지 모르겠다. Button.jsx, CustomButton.jsx, StyledButton.jsx, PrimaryButton.jsx. 다 버튼인데 뭐가 다른 건지. 누가 정리 좀 해줬으면 좋겠다. 컴포넌트 분리의 기준이 뭔데 구글링했다. "React 컴포넌트 분리 기준". 블로그마다 다르다. 어떤 글은 "50줄 넘으면 분리하세요"래. 그럼 난 이미 300줄인데 6개로 쪼개야 하나. 어떤 글은 "단일 책임 원칙"이래. 하나의 컴포넌트는 하나의 일만. 그게 뭔데. 프로필 보여주는 게 한 가지 일 아닌가. 어떤 글은 "props가 5개 넘으면 분리"래. 그럼 지금 당장 분리해야 할 게 10개는 넘는다. 유튜브도 봤다. 영상마다 다르다. "작게 쪼갤수록 좋습니다." vs "너무 잘게 쪼개면 오히려 복잡해져요." 둘 다 맞는 말 같은데 반대다. 뭘 믿어야 하지. ChatGPT한테 물어봤다. 코드 붙여넣고 "이거 어떻게 분리하면 좋을까요?" 3가지 방법을 알려줬다. 전부 다른 방법. 어느 게 정답이래. "상황에 따라 다릅니다." 상황. 그 상황을 내가 모르는데 어떡하라고. 분리했더니 props 지옥 결국 분리했다. UserProfile을 5개로 쪼갰다. ProfileHeader, ProfileAvatar, ProfileInfo, FollowButton, PostList. 뿌듯했다. 이제 각 파일이 50줄 정도. 깔끔하다. PR 올렸다. "props drilling이 너무 심한 것 같아요." 뭐라고. UserProfile에서 userId를 받아서 ProfileHeader한테 넘기고, ProfileHeader가 또 ProfileAvatar한테 넘기고, ProfileAvatar가 이미지 URL 받아오려고 또... props가 3단계를 내려간다. userId -> ProfileHeader -> ProfileAvatar -> 실제 사용. "Context API 쓰시거나 상태관리 라이브러리 고려해보세요." Context API. 배웠다. 근데 언제 쓰는 건지 모르겠다. 이 정도면 쓰는 건가. 아직 안 쓰는 건가. Zustand? Recoil? Redux는 너무 어렵다고 하던데. 뭘 선택해야 하나. 일단 물어봤다. 또. "선배님, 이거 Context 써야 할까요?" "음... 지금은 괜찮을 것 같은데요. 나중에 상태가 복잡해지면 그때 고민해봐요." 나중에. 또 나중에.그래서 원래대로 돌렸다. props 3개만 넘기게. 근데 그러니까 ProfileHeader가 너무 많은 일을 한다고 또 지적받았다. "ProfileHeader가 너무 많은 책임을 가지고 있네요." 책임. 또 책임. 뭐가 책임인지 모르겠다. 그냥 props 전달하는 건데. 이것도 책임인가. 결국 정답은 없다는 걸 깨달았다 3주 걸렸다. 한 페이지 리팩토링하는 데. 처음 300줄 UserProfile.jsx는 이제 10개 파일이 됐다. components/profile 폴더에 들어가면 파일이 즐비하다. ProfileHeader.jsx ProfileAvatar.jsx ProfileBadge.jsx ProfileInfo.jsx ProfileBio.jsx FollowButton.jsx FollowStats.jsx PostList.jsx PostItem.jsx PostImage.jsx 10개. 원래 하나였는데. 깔끔한가. 모르겠다. 파일 찾으려고 왔다 갔다 하는 게 더 불편한 것 같기도 하다. 근데 민수 선배는 좋다고 했다. "이제 훨씬 읽기 좋네요. 수고했어요." 읽기 좋다고. 진짜 그런가. 난 아직도 헷갈리는데. 어제 신입이 한 명 더 들어왔다. 나보다 3개월 늦게. 이름은 김신입. "선배님, 컴포넌트 어떻게 나누는 게 좋아요?" 물어봤다. 나한테. 선배라고. "음... 재사용 가능하게? 그리고 너무 길어지면 분리하고..." 내가 하는 말이 민수 선배랑 똑같다. 웃겼다. 근데 김신입이 물었다. "그럼 몇 줄 정도가 적당한가요?" "그게... 상황에 따라 달라요." 이 말을 내가 하고 있다. 3주 전에 제일 듣기 싫었던 말을. 아직도 모르지만 조금 알 것 같기도 하다 오늘도 컴포넌트 분리했다. 새로운 기능. 장바구니 페이지. 처음부터 나눴다. ShoppingCart.jsx 하나에 다 쓰지 않았다. CartHeader, CartItem, CartSummary, CheckoutButton. 4개로 시작했다. 200줄이 4개 파일, 50줄씩. PR 올리기 전에 스스로 봤다. CartItem이 좀 긴 것 같다. 80줄. 분리했다. CartItemImage, CartItemInfo, CartItemQuantity. 혼자 했다. 지적받기 전에. 뿌듯했다. 조금. 아주 조금. 그리고 민수 선배가 approve 눌렀다. 댓글 없이. 댓글 없는 게 제일 좋은 거다. 배웠다. 여전히 모른다. 정확한 기준 같은 건. 몇 줄에서 나누고, 어떤 이름을 붙이고, props를 몇 개까지 넘기고. 근데 계속 하다 보니까 감이 생긴다. 이 정도면 분리해야겠다. 이건 하나여도 되겠다. 틀릴 때도 있다. 많다. 근데 틀리면 또 고치면 된다. 3주 걸려도 되고. 8개월 차. 아직도 주니어. 컴포넌트 분리는 여전히 어렵다. 근데 3개월 전보다는 덜 어렵다. 그게 성장인가 보다. 내일도 분리하겠지. 또 헷갈리겠지. 그래도 해본다.김신입한테 알려줄 건 생겼다. "일단 해봐. 틀려도 돼."

서울 원룸 월세 55만원과 개발자의 삶

서울 원룸 월세 55만원과 개발자의 삶

서울 원룸 월세 55만원과 개발자의 삶 7평짜리 내 전부 월세 55만원. 관리비 8만원. 합치면 63만원이다. 연봉 3400에서 세금 떼면 실수령 280 정도. 22%가 집세다. 원룸이라고 했지만 사실 오피스텔이다. 7평. 침대 놓고, 책상 놓으면 끝이다. 화장실 문 열면 무릎이 변기에 닿는다. 창문은 하나. 서쪽이라 오후만 해가 든다. 맞은편 건물이 3미터 앞이다. 커튼 안 치면 눈 마주친다.여기가 내 전부다. 출근 준비하고, 퇴근하고, 자고, 일어나는 곳. 가끔 이 방이 내 인생 같다는 생각이 든다. 좁고, 답답하고, 햇빛도 잘 안 든다. 퇴근 후 책상 앞 퇴근하면 7시 반. 씻고 밥 먹으면 8시 반이다. 편의점 도시락 전자레인지 3분. 설거지는 없다. 책상에 앉는다. 듀얼 모니터가 켜진다. 왼쪽에 인프런 강의. 오른쪽에 VS Code. 오늘은 '클린 코드' 강의를 들어야지. 10분 지나면 눈이 감긴다.강의 화면이 그대로다. 진도는 3분 10초. 내일 보자. 내일은 집중할 수 있을 거다. 그렇게 일주일이 지나간다. 결제한 강의만 17개다. 선배가 말했다. "퇴근 후 2시간씩 공부하면 1년 뒤 달라져." 나는 2시간을 앉아있지도 못한다. 회사에서 8시간 코딩하고 오면 모니터가 싫다. 주말의 계획과 현실 금요일 저녁. 다짐한다. "이번 주말엔 포트폴리오 정리한다. 블로그도 쓴다." 토요일 아침 10시. 눈을 뜬다. 일단 침대에서 유튜브 본다. 30분만. 1시간 지났다. 점심 먹는다. 편의점 컵라면. "밥 먹고 바로 시작하자." 오후 2시. 책상에 앉는다. 노션을 연다. "포트폴리오 구성" 페이지를 만든다.프로젝트 1: 투두리스트 프로젝트 2: 날씨 앱 프로젝트 3: ...뭘 써야 하지?생각하다가 유튜브를 켠다. "포트폴리오 만드는 법" 검색. 영상을 본다. 30분짜리. "오 이렇게 하면 되겠네." 그런데 배가 고프다. 저녁 6시다. 치킨을 시킨다. 맥주도 한 캔. 저녁 8시. 배가 부르다. 침대에 눕는다. "소화되면 하자." 일요일 저녁 9시. 아무것도 안 했다. 게임만 6시간 했다. 롤 티어는 올랐다. 월요일 아침의 자책 월요일 7시 반. 알람이 울린다. 또 일주일이 시작된다. 주말에 뭐 했지? 아무것도 안 했다. 포트폴리오는? 안 했다. 블로그는? 안 했다. 출근길 지하철에서 생각한다. "나 이러다가 평생 이렇게 사는 거 아냐?" 옆에 앉은 사람도 개발자 같다. 맥북을 보고 있다. 화면에 깃허브가 보인다. 커밋이 초록색으로 빼곡하다. 나는 이번 주말에 커밋 0개다. 회사에 도착한다. 슬랙을 연다. 선배가 올린 글이 보인다. "주말에 토이프로젝트 배포했습니다. 피드백 부탁드려요." 나는 주말에 롤만 했다. 이 좁은 방과 내 인생 퇴근하고 원룸 문을 연다. 7평. 똑같다. 어제랑 똑같다. 침대. 책상. 모니터. 창문. 맞은편 건물의 불빛들. 이 방에서 나는 뭘 하고 있나? 일하러 가기 위해 자고 일어나는 곳. 그게 다인가? 선배들 말이 맞다. 퇴근 후가 진짜 실력 차이를 만든다고. 1년 차와 3년 차의 차이는 회사에서 만들어지는 게 아니라고. 집에서 얼마나 했냐의 차이라고. 근데 나는 못 하겠다. 회사에서 8시간 코딩하고 오면 진짜 모니터 보기 싫다. 그냥 멍 때리고 싶다. 게으른 걸까? 의지가 부족한 걸까? 아니면 이게 정상인 걸까? 모르겠다. 그냥 피곤하다. 55만원의 의미 월세 55만원. 부모님한테 손 안 벌리고 내는 첫 월세다. 적은 돈은 아니다. 편의점 도시락 55개 값이다. 치킨 22마리 값이다. 근데 이게 내가 살 수 있는 최선이었다. 서울에서. 회사에서 30분 거리에서. 보증금 500만원으로. 더 싼 곳도 봤다. 40만원짜리 고시원. 창문이 없었다. 침대만 있었다. 화장실은 공용이었다. 거기서는 못 살겠더라. 역세권 원룸은 70만원이었다. 못 낸다. 그래서 여기다. 역에서 도보 15분. 오르막길. 이 방이 내 연봉을 말해준다. 3400만원의 삶이 이런 거다. 7평짜리 방에서 혼자 밥 먹고. 침대에 누워 강의 보다 자고. 주말엔 게임하다 자책하고. 그래도 내 방 근데 가끔은 좋다. 금요일 저녁에 치킨 시켜서 혼자 먹을 때. 창문 열고 밤바람 쐴 때. 아무도 안 보는데 코딩 공부 30분 했을 때. 이 방은 좁지만 내 공간이다. 누가 뭐라 안 한다. 청소 안 해도 혼나지 않는다. 밤새 게임해도 뭐라 안 한다. 부모님 집에 있을 때는 눈치 봤다. "너 방에서 뭐 하니?" "공부 좀 해라." "게임만 하냐?" 여기선 그런 말 없다. 그냥 내 마음대로다. 좁아도. 책상 앞에 앉아서 창밖을 본다. 맞은편 건물에도 불이 켜져 있다. 저 방에도 누군가 산다. 저 사람도 나처럼 월세 내고, 출퇴근하고, 피곤할까? 서울에는 이런 방이 몇 개나 될까? 좁은 원룸에서 혼자 사는 20대가 몇 명이나 될까? 다들 비슷하게 사나? 변하지 않는 일상 월요일. 화요일. 수요일. 출근. 점심. 퇴근. 편의점. 침대. 반복이다. 계속 반복이다. 가끔 친구한테 전화가 온다. 대학 친구. "요즘 어때?" "응 그냥. 출퇴근 반복이지." "주말에 만날래?" "음... 다음에." 귀찮다. 나가기 귀찮다. 옷 입고 머리 감고 약속 장소까지 가는 게 귀찮다. 그냥 방에 있고 싶다. 아무것도 안 하고 침대에 누워있고 싶다. 이게 번아웃일까? 아니면 원래 이런 걸까? 사회초년생은 다 이런가? 선배한테 물어봤다. 조심스럽게. "형은... 퇴근하고 뭐 해요?" "운동하지. 헬스장 다녀." "매일요?" "응 거의. 안 하면 몸이 찌뿌둥해." 나는 운동할 기력도 없다. 회사에서 앉아만 있는데 왜 이렇게 피곤할까? 집도 직장도 내 인생 어느 날 깨달았다. 이 원룸이 내 인생이구나. 좁다. 답답하다. 햇빛도 잘 안 든다. 근데 이게 현재 내가 가진 전부다. 회사도 비슷하다. 중소기업. 연봉 3400. 수습 기간. 일은 어렵고 모르는 건 많고 혼나는 건 무섭다. 근데 이게 내가 선택할 수 있었던 최선이었다. 6개월 부트캠프 나와서 취업할 수 있는 곳. 서류 20곳 넣고 면접 3곳 보고 붙은 곳. 더 좋은 회사? 나를 안 뽑았다. 더 좋은 집? 돈이 없다. 그래서 여기다. 이 원룸이고 이 회사다. 불만은 있다. 많다. 근데 어쩔 수 없다. 이게 현실이다.좁은 방에서 오늘도 모니터를 켠다. 내일은 강의 20분 볼 수 있을까?

코드 복붙의 유혹: 스택오버플로우와의 싸움

코드 복붙의 유혹: 스택오버플로우와의 싸움

코드 복붙의 유혹: 스택오버플로우와의 싸움 오전 10시, 에러와의 조우 출근했다. 어제 짠 코드가 안 돌아간다. 빌드 에러 메시지가 터미널을 가득 채웠다. 빨간 글씨 50줄. 읽어봤자 모른다. "Cannot read property of undefined" 어쩌고. 일단 구글에 에러 메시지 복사. 엔터. 첫 번째 링크. 스택오버플로우. 당연하지.질문은 2019년. 답변은 초록 체크. 좋아요 847개. 믿을 만하다. 분명. 코드 블록을 드래그했다. Ctrl+C. 내 에디터로 왔다. Ctrl+V. 3초. 파일 저장. npm run dev. "이번엔 되겠지." 10시 5분, 새로운 에러 안 된다. 아까와 다른 에러. "Module not found." 당황했다. 뭐가 문젠데. 다시 스택오버플로우. 새 탭. 검색. 또 답변 찾았다. 이번엔 2020년 거. 좋아요 623개. npm install some-package --save터미널에 붙여넣었다. 엔터. 패키지 설치 중. 로딩 바가 천천히 움직인다. "이제 되겠지."10시 15분, 무한 루프 또 에러. 이번엔 "Dependency conflict." 뭔 소리야. 검색. 스택오버플로우. 복붙. 에러. 검색. 복붙. 에러. 30분이 지났다. 원래 코드가 뭐였는지 기억이 안 난다. 복붙을 5번 했나 6번 했나. 에디터에 주석 처리된 코드가 10개 쌓였다. 다 스택오버플로우에서 가져온 거다. "아... 이러면 안 되는데." 알고 있다. 이해하고 써야 한다는 거. 하지만 일단 돌아가게 해야 한다. 급하다. 왜 이러는 걸까 내가 나쁜 개발자인가. 아니다. 다들 그런다. 선배도 그랬을 거다. 분명. 스택오버플로우는 마약이다. 달콤한 마약. 문제가 생기면 일단 거기로 간다. 구글 검색하면 첫 번째 링크가 거기다. 어쩔 수 없다. 답변은 친절하다. 코드 블록도 예쁘게 정리되어 있다. 복사하기 버튼도 있다. "Use this code, it works." 그 말이 날 유혹한다.복붙의 3단계 1단계: 희망. "이 코드면 되겠네." 복붙. 실행. 2단계: 혼란. "어? 왜 안 돼?" 다시 검색. 또 복붙. 3단계: 절망. "뭐가 뭔지 모르겠다." 코드가 엉망. 처음부터 다시. 매번 이렇다. 그래도 또 한다. 내일도 할 거다. 오늘의 기록 오후 2시. 점심 먹고 왔다. 선배가 내 화면을 봤다. "이거 왜 이렇게 짰어?" "스택오버플로우에서..." "그거 코드 버전 안 맞아. 우리 프로젝트는 React 18인데 저건 16 코드야." 몰랐다. 복붙할 때 버전은 안 봤다. 좋아요 개수만 봤다. "다음부턴 날짜 확인하고, 답변 읽어봐. 코드만 보지 말고." "네..." 알고 있었다. 진짜로. 하지만 안 했다. 왜 읽지 않는가 시간이 없어서? 아니다. 귀찮아서? 솔직히 맞다. 하지만 진짜 이유는 다르다. 읽어도 모른다. "This happens because of closure scope blah blah..." 무슨 말인지 모른다. 클로저? 스코프? 들어는 봤다. 하지만 설명을 읽으면 머리가 아프다. 코드를 보는 게 편하다. 코드는 일단 작동한다. 작동하면 됐다. 이해는... 나중에. 나중이 안 온다는 걸 알면서도. 선배들의 흔적 우리 회사 코드베이스를 보다가 발견했다. 주석. // From Stack Overflow // https://stackoverflow.com/questions/...선배도 복붙했다. 링크까지 남겼다. 웃겼다. 그리고 안심됐다. 나만 그런 게 아니구나. 복붙 고수의 경지 팀장님이 말했다. "스택오버플로우 쓰는 건 괜찮아. 프로들도 다 써. 근데 아는 게 중요해." "뭘 알아야 하는데요?" "왜 이 코드가 작동하는지. 내 상황에 맞는지. 부작용은 없는지." "..." "그냥 복붙은 주니어. 이해하고 수정하면 시니어." 명언이다. 메모장에 적었다. 실천은 못 하겠지만. 오후 4시, 또 복붙 또 에러가 났다. 이번엔 useEffect 관련. 검색했다. 스택오버플로우 열었다. 답변을 읽기 시작했다. 5줄 읽었다. "아... 모르겠다." 스크롤 내렸다. 코드 블록까지. 드래그. 복사. 붙여넣기. 저장. 실행. 됐다. "역시." 뿌듯했다. 3초간. 죄책감의 무게 퇴근 전. 오늘 짠 코드를 봤다. 내가 이해하는 줄은 30%. 나머지는 스택오버플로우 거다. 커밋 메시지 쓰려는데 손가락이 안 움직인다. "Fix: update component logic" 거짓말이다. 내가 고친 게 아니다. 복붙했다. 하지만 푸시했다. 어쩔 수 없다. 내일 PR 올리면 선배가 볼 거다. 코드리뷰 들어올 거다. "이 부분 왜 이렇게 짰어요?" 대답 못 한다. 복붙이라고 말 못 한다. "제가... 찾아보고 적용했습니다." 거짓말 반 진실 반. 동기의 고백 저녁. 동기 단톡방. "야 너네 스택오버플로우 얼마나 써?" "매일. 하루 10번?" "나 20번." "나 코드 80%가 거기서 온 거 같은데 ㅋㅋ" 다들 그렇다. 안심됐다. "근데 이거 면접 때 들키면 어떡해?" "모르면 되지 뭐." "맞네 ㅋㅋ" 웃었다. 씁쓸했다. 복붙의 순간들 이번 주에 복붙한 것들. 월요일: axios interceptor 코드. 화요일: custom hook 3개. 수요일: 날짜 포맷 함수. 목요일: 에러 핸들링 로직. 금요일: 오늘. useEffect cleanup. 매일이다. 하루도 빠짐없다. "이러다 성장하나?" 의문이 든다. 하지만 내일도 할 거다. 읽어보려는 시도 오늘 저녁. 다짐했다. "오늘은 답변을 끝까지 읽어보자." 스택오버플로우 열었다. 질문 하나 골랐다. 답변을 읽기 시작했다. "The reason this works is because JavaScript's event loop..." 이벤트 루프? 뭐지. 새 탭 열었다. 이벤트 루프 검색. MDN 문서 나왔다. 영어로 빼곡하다. "Callstack, task queue, microtask..." 머리 아프다. 탭 닫았다. 다시 스택오버플로우. 코드 블록으로 스크롤. 복붙. "내일 읽어야지." 선배의 조언 점심시간. 선배가 말했다. "신입 때 나도 그랬어. 복붙만 했지." "그럼 어떻게 벗어났어요?" "안 벗어났어. 지금도 해." "예?" "대신 이제는 알고 해. 이게 왜 작동하는지." "어떻게요?" "복붙하고 나서 한 줄씩 읽어봐. 모르는 거 나오면 검색. 천천히." "시간 오래 걸리지 않아요?" "응. 근데 나중엔 빨라져. 같은 패턴 보이거든." 고개 끄덕였다. 실천할 수 있을까. 모르겠다. 복붙의 미래 5년 뒤 나는 어떨까. 여전히 복붙하고 있을까. 아니면 코드를 이해하고 있을까. 상상이 안 된다. 지금은 그냥 살아남는 게 목표다. 복붙이라도 해서 일단 작동하게 만드는 거. 그게 지금 내 전부다. 퇴근길 생각 9시 퇴근. 지하철에서 생각했다. "오늘 뭘 배웠지?" 솔직히 모르겠다. 코드는 짰다. 10개 파일. 하지만 내 코드가 아니다. 짜깁기다. "이게 맞나?" 질문이 맴돈다. 하지만 내일도 출근한다. 또 복붙한다. 내일의 다짐 내일은 다르게 해보자. 복붙하되 읽어보자. 한 줄이라도. 모르는 용어 나오면 메모하자. 퇴근 후 검색하자. 천천히 성장하자. ... 이렇게 다짐한 게 이번 주만 세 번째다. 하지만 내일은 다를 거다. 분명.오늘도 복붙. 내일도 복붙. 언젠간 이해할 거다. 아마.

수습 평가 D-90: 새벽 3시에 깨는 이유

수습 평가 D-90: 새벽 3시에 깨는 이유

수습 평가 D-90: 새벽 3시에 깨는 이유 또 깼다 새벽 3시 12분. 눈이 떠졌다. 이유도 모르고. 어제는 2시 47분이었다. 그제는 3시 반. 화장실 가려고 깬 게 아니다. 갈증도 아니다. 그냥 깬다. 눈 뜨면 바로 생각난다. 수습 평가. D-90. 정확히는 D-87.계산이 시작된다 침대에 누워서 눈만 뜬 채로 계산한다. 지금까지 8개월. 남은 기간 3개월. 지금 내 실력으로 괜찮은가. 아니다. 어제 선배가 말했다. "이신입씨, 이거 왜 이렇게 짰어요?" 대답 못 했다. "아... 그게..." 머릿속이 하얘졌다. 그 코드 짠 게 사흘 전이다. 왜 그렇게 짰는지 나도 모른다. ChatGPT가 알려준 대로 했다. 그게 문제였다.체크리스트 어둠 속에서 머릿속으로 리스트를 만든다. 할 줄 아는 것:React 기본 문법 컴포넌트 만들기 useState 쓰기 구글링못하는 것:useEffect 정확히 이해 못 함 TypeScript 제네릭 뭔지 모름 상태관리 라이브러리 실무에서 못 써봄 테스트 코드 한 번도 안 짬 Git conflict 나면 당황 Docker는 들어만 봄 API 설계 못 함 데이터베이스 쿼리 최적화? 모름못하는 게 더 많다. 아니, 훨씬 더 많다. 손가락으로 세다가 포기했다. 다른 신입들은 부트캠프 동기 단톡방 켰다. 밤 12시에 올라온 메시지. "오늘 Redux 완강했다ㅠㅠ 드디어" 새벽 1시. "면접 봤는데 React Query 물어보던데 이거 필수인가" 새벽 2시. "다들 자나요? 저 내일 코테 보는데 긴장돼서..." 다들 뭔가 하고 있다. 나는 뭐 했나. 어제 퇴근하고 편의점 갔다. 맥주 두 캔 샀다. 집 와서 유튜브 켰다. '프론트엔드 로드맵 2024'. 10분 보고 잤다.선배가 던진 말 지난주 금요일. 퇴근 30분 전. 선배가 슬랙 DM 보냈다. "이신입씨 잠깐 통화 가능?" 심장이 멈췄다. "네 가능합니다" 전화 왔다. "이번 주 작업 보니까 좀 아쉬운 부분이 있어서요." "...네." "컴포넌트 분리를 좀 더 신경 써야 할 것 같고, 네이밍도 좀 더 명확하게 하면 좋겠어요." "아... 네네." "그리고 커밋 메시지도 컨벤션 맞춰주세요. 이거 몇 번 말씀드린 것 같은데." "죄송합니다." "괜찮아요. 아직 신입이니까. 근데 조금씩 개선되면 좋겠어요." "네 그렇게 하겠습니다." 끊고 나서 손이 떨렸다. '아직 신입이니까' 이 말이 계속 맴돈다. 지금은 신입이지만 3개월 뒤에는? 수습 평가 기준 입사할 때 받은 서류 다시 꺼내 봤다. 수습 평가 항목:업무 이해도 기술 역량 커뮤니케이션 조직 적응도 자기개발 의지각 항목 A부터 D까지. C 두 개 이상이면 재평가. D 하나라도 있으면 위험. 지금 나는? 업무 이해도: C 기술 역량: D 커뮤니케이션: C 조직 적응도: B 자기개발 의지: C 솔직하게 매기면 이렇다. D가 하나 있다. 오늘 한 일 어제 하루를 복기한다. 9시 10분 출근. 슬랙 확인. 읽지 않은 메시지 12개. 다 읽는 데 20분. 이해 못 한 건 5개. 일단 넘김. 10시 데일리 스크럼. 어제 한 일: "로그인 폼 스타일링 완료했습니다." 오늘 할 일: "회원가입 유효성 검사 추가하겠습니다." 실제로 한 일: 유튜브에서 '리액트 폼 validation' 검색. 점심 12시. 편의점. 참치김밥 하나. 바나나우유. 먹으면서 인프런 강의 10분 봤다. 오후 1시부터 코딩. input에 onChange 걸고 state 업데이트. 에러 났다. 뭔지 모름. console.log 찍었다. 7개. 이해했다. 아니, 이해한 척. 복붙해서 돌아간다. 커밋. 오후 4시 회의. "이번 스프린트 목표는..." 졸음 왔다. 커피 마셨다. 무슨 말인지 30%만 이해. 끄덕였다. 다들 끄덕이니까. 오후 6시. 선배가 내 PR에 코멘트 8개. 심호흡. 하나씩 읽었다. "이 부분 useMemo로 감싸면 어떨까요?" useMemo가 뭐였지. 검색했다. 아... 맞다. 최적화. "네 수정하겠습니다." 9시 퇴근. 집 도착 10시. 씻고 누웠다. 11시. 내일 뭐 공부하지 생각하다가 잤다. 이게 내 하루다. 충분하지 않다 새벽 3시 12분. 이불 속에서 생각한다. 이 정도로 충분한가. 동기들은 토이 프로젝트 한다. 나는 주말에 게임했다. 동기들은 블로그 쓴다. 나는 노션에 '오늘 배운 것' 2줄 적고 말았다. 동기들은 스터디 한다. 나는 혼자 강의 듣다가 잔다. 차이가 벌어지고 있다. 지금 당장은 아니어도 3개월 뒤면 드러난다. 수습 평가 때 물어볼 것 같다. "이신입씨, 이번 기간 동안 어떤 걸 공부했나요?" "음... 리액트 강의 들었습니다." "프로젝트는?" "아... 회사 업무가 바빠서..." "본인 강점이 뭐라고 생각하세요?" "..." 대답 못 한다. 지금도 못 한다. 악순환 불안하다. 불안해서 유튜브 본다. '주니어 개발자 공부법' 영상. 20분 본다. 동기부여된다. 노트에 적는다. '내일부터 매일 1시간 공부' 다음 날. 퇴근하면 녹초다. 침대에 누운다. 5분만 쉬자. 눈 뜬다. 새벽 2시. 또 불안하다. 또 영상 본다. 악순환이다. 선배들도 그랬을까 팀장님은 개발 10년 차. 코드 보면 깔끔하다. 회의 때 말하는 것도 논리적이다. 막히는 게 없어 보인다. 저 사람도 신입 때 이랬을까. 새벽에 깨서 불안했을까. 수습 평가 걱정했을까. 물어보고 싶다. 못 물어본다. "팀장님 신입 때 어떠셨어요?" 이렇게 물으면 이상할까. 아니, 이상한 게 아니라 내 불안이 들킬 것 같다. '쟤 요즘 불안해하네' 이렇게 생각할까 봐. 그래서 혼자 끙끙댄다. D-87의 무게 87일. 길다면 길다. 짧다면 짧다. 매일 1시간씩 공부하면 87시간. 강의 10개는 볼 수 있다. 토이 프로젝트 2개는 만들 수 있다. 블로그 글 20개는 쓸 수 있다. 계산은 완벽하다. 실행이 문제다. 어제도 계획했다. 오늘도 계획했다. 내일도 계획할 것이다. 실행은 모레쯤. 모레도 계획만 한다. 불 켜고 일어났다 3시 12분. 더 이상 못 눕겠다. 불 켰다. 노트북 켰다. 뭐라도 해야 할 것 같다. '리액트 공식 문서' 탭 열었다. 읽는다. 5분 읽었다. 졸리다. 아니다, 졸리면 안 된다. 커피 끓였다. 마신다. 다시 읽는다. useEffect 문서. "의존성 배열에 들어간 값이 변경될 때마다..." 알고 있다. 근데 실전에서 헷갈린다. 예제 코드 따라 쳤다. 돌려봤다. 이해했다. 조금. 시계 봤다. 4시 23분. 출근까지 4시간 반. 더 할까. 아니다. 자야 한다. 내일 졸면 안 된다. 눕는다. 잠이 안 온다. 당연하다. 커피 마셨으니까. 반복되는 다짐 이불 속에서 또 다짐한다. 오늘은 정말 한다. 퇴근하고 바로 집 온다. 편의점 안 간다. 유튜브 안 본다. 노트북 켜서 코드 짠다. 토이 프로젝트 시작한다. 간단한 거. Todo 앱. 이미 100번 만들어 봤지만 또 만든다. 이번엔 TypeScript로 만든다. 제대로 공부하면서. 블로그도 쓴다. '오늘 배운 것' 정리한다. 주말에는 스터디 찾아본다. 혼자 하니까 안 되는 거다. 같이 하면 된다. 다짐한다. 또. 어제도 다짐했다. 그제도 다짐했다. 이번엔 다르다고 믿는다. 믿고 싶다. 7시 알람 눈 떴다. 7시. 4시간 잤다. 머리 무겁다. 일어나야 한다. 씻는다. 옷 입는다. 현관문 열기 전에 거울 봤다. 다크서클 짙다. "오늘도 화이팅..." 누가 들으면 웃긴다. 나도 웃긴다. 밖으로 나간다. 지하철 탄다. 핸드폰 켠다. 부트캠프 동기 단톡. 새벽 6시에 올라온 메시지. "오늘 알고리즘 1문제 풀고 출근합니다!" 나는 새벽에 뭐 했나. 다짐만 했다. 오늘도 출근 9시 10분. 책상 앉았다. 슬랙 켰다. 읽지 않은 메시지 15개. 오늘도 시작이다. 수습 평가 D-87. 내일은 D-86. 모레는 D-85. 숫자는 줄어든다. 실력은 늘고 있을까. 모르겠다. 그래도 출근했다. 그게 어디야.새벽 3시에 깨는 건 불안 때문이다. 그 불안은 정당하다. 근데 불안만으로는 안 된다. 내일은 정말 뭐라도 해봐야지. D-86부터는 다르게. 그렇게 믿고 또 출근한다.

회의 중 고개만 끄덕이기, 신입의 생존 기술

회의 중 고개만 끄덕이기, 신입의 생존 기술

회의 중 고개만 끄덕이기, 신입의 생존 기술 오늘도 회의 오전 10시. 슬랙에 알림. "30분 후 회의실 B. 신기능 설계 논의" 심장이 쿵 내려앉았다. 설계 논의. 내가 뭘 알아. 일단 노션 켰다. 지난주 회의록 검색. "API 구조 재설계, Redis 캐싱 도입 검토" Redis가 뭐더라. 검색했다. "인메모리 데이터베이스". 아직도 모르겠다. 10시 28분. 화장실 갔다 왔다. 회의 2분 전에 들어가는 게 제일 안전하다. 너무 일찍 가면 선배랑 어색한 대화해야 함.회의실 입성 문 열고 들어갔다. "안녕하세요." 벌써 앉아있는 선배들. 김 선배, 박 선배, 팀장님. 나는 제일 구석 자리. 노트북 열고, 메모장 켰다. 펜도 꺼냈다. 쓸지 모르지만. 팀장님이 말을 시작했다. "이번에 유저 피드 성능 개선하려고 하는데." 고개를 끄덕였다. 유저 피드. 그거 내가 건드린 적 없다. "현재 API 응답속도가 평균 2.3초거든." 끄덕. 2.3초가 느린 건가 빠른 건가. "DB 쿼리 최적화랑 캐싱 레이어 추가 검토 중이야." 끄덕끄덕. 캐싱 레이어. 어디다 추가하는 거지. 김 선배가 말했다. "Redis로 가는 게 나을 것 같은데, 세션 관리도 같이 옮기면 어때?" 끄덕. Redis. 아까 검색한 그거. 세션 관리는 또 뭐지.모르는 용어의 향연 박 선배가 화이트보드에 뭔가 그렸다. "클라이언트-서버-DB-Redis 구조로 가면." 끄덕. 화살표가 5개쯤 그려졌다. 하나도 모르겠다. 팀장님이 물었다. "신입이는 어떻게 생각해?" 심장이 멈췄다. "아... 좋을 것 같습니다." 내가 한 말이다. 좋을 것 같다니. 뭐가. "구체적으로는?" 끝났다. "음... 성능도 개선되고, 유지보수도 편할 것 같아서요." 유지보수. 어디서 들은 단어. 팀장님이 고개를 끄덕였다. 살았다. 김 선배가 말을 이었다. "TTL은 얼마로 잡을까?" 끄덕. TTL. Time To Live인가. 아닌가. 메모장에 적었다. "TTL - 나중에 검색" 회의가 40분째 진행 중이다. 내가 한 말은 딱 한 문장. 고개는 스무 번 넘게 끄덕였다. 끄덕임의 기술 회의 중 고개 끄덕이기에도 기술이 있다. 너무 자주 끄덕이면 이상하다. "너 진짜 이해하고 있어?" 너무 안 끄덕이면 더 이상하다. "너 듣고 있긴 해?" 적당히 끄덕여야 한다. 3초에 한 번. 아니면 문장 끝날 때. 선배가 나를 쳐다보면 더 끄덕인다. "네네, 맞습니다." 팀장님이 말할 때는 살짝 앞으로 몸을 기울인다. 경청하는 자세. 실제로는 하나도 안 들린다. 메모는 계속 한다. 뭐라도 적는다. "Redis 검토", "성능 개선", "API 2.3초" 나중에 읽어보면 아무 의미 없다. 그래도 적는다. 적는 사람은 일하는 것처럼 보인다.질문이 무서운 이유 회의에서 제일 무서운 순간. "질문 있어?" 없다. 질문하면 더 모르는 게 드러난다. 한 번 질문했던 적 있다. "저기, API 엔드포인트가 정확히 어디 있는 건가요?" 선배들이 나를 쳐다봤다. 3초간 침묵. 김 선배가 말했다. "너 이거 작업하기 전에 문서 읽었어?" 죽고 싶었다. 그 이후로 질문 안 한다. 모르면 나중에 검색한다. 회의 끝나고 선배 책상 옆 지나가면서 슬쩍 물어본다. "저기, 아까 말씀하신 Redis 관련해서..." 일대일이면 덜 창피하다. 회의실에서는 무조건 끄덕인다. 이해하는 척한다. 살아남는다. 회의 후 현타 회의 끝났다. 50분 진행. 노트북 덮고 일어섰다. 선배들은 계속 얘기하고 있다. "그럼 이거 내일까지 POC 만들어볼게." POC. 또 모르는 단어. 자리로 돌아왔다. 아까 적은 메모 봤다. "Redis 검토" "TTL" "캐싱 레이어" "POC" 하나도 모르겠다. 구글 켰다. "Redis란 무엇인가" "TTL 뜻" "POC 개발 용어" 검색 결과 읽었다. Proof of Concept. 개념 증명. 아. 이제 알았다. 회의 중에는 몰랐다. 메모장에 정리했다. 나중에 또 까먹을 거다. 슬랙에 회의록이 올라왔다. 김 선배가 작성. 읽어봤다. 회의 중에 들었던 내용이 맞긴 한데. 여전히 무슨 말인지 모르겠다. 선배도 그랬을까 점심시간. 편의점 갔다. 김치찌개 도시락 데웠다. 김 선배가 옆에 앉았다. "신입이, 오늘 회의 어땠어?" 심장이 또 쿵. "아... 좋았습니다." "이해되긴 했어?" 끝났다. 솔직하게 말할까. "솔직히... 반은 모르겠어요." 김 선배가 웃었다. "나도 신입 때 그랬어." 진짜? "나는 80% 몰랐는데." 위로가 됐다. "지금도 가끔 모를 때 있어. 그럼 나중에 검색하지 뭐." 선배도 그랬구나. "회의 중에 모르는 거 물어보기 무섭지 않았어요?" "무섭지. 그래서 안 물어봤어. 너처럼." 웃었다. 처음으로. "근데 나중에 보면 다 별거 아니더라. 하나씩 알아가는 거야." "네." "오늘 회의 내용 중에 궁금한 거 있으면 나한테 물어봐. 회의실 밖에서." 고마웠다. 도시락 먹으면서 물어봤다. "Redis가 정확히 뭔가요?" 김 선배가 설명해줬다. 10분 동안. 회의실에서 들었던 것보다 10배 이해가 잘 됐다. 그래도 나는 끄덕인다 오후 3시. 또 회의 알림. "긴급 회의. 버그 대응" 또 회의실 갔다. 또 끄덕였다. 이번에는 조금 달랐다. "API 응답 지연"이라는 말이 들렸다. 아까 점심시간에 김 선배한테 들은 내용이다. "Redis 캐싱으로 해결 가능할까요?" 내가 말했다. 선배들이 나를 봤다. 팀장님이 고개를 끄덕였다. "그것도 방법이네." 살았다. 아니, 살았다를 넘어섰다. 회의가 20분 만에 끝났다. 짧은 회의가 제일 좋은 회의다. 자리로 돌아왔다. 가슴이 두근거렸다. 내가 한 말이 말이 됐다. 처음이다. 메모장에 적었다. "오늘 회의에서 Redis 얘기 꺼냄. 팀장님이 끄덕였음." 작은 성공이다. 하지만 성공이다. 언젠가는 저녁 7시. 퇴근 준비. 오늘 회의 두 개. 끄덕인 횟수 아마 50번. 실제 이해한 비율 30%. 그래도 괜찮다. 입사 8개월. 처음엔 10%도 못 알아들었다. 지금은 30%. 3배 성장이다. 내년 이맘때면 50%쯤 될까. 2년 후면 김 선배처럼 설명해줄 수 있을까. 모르겠다. 하지만 조금씩 나아지고 있다. 회의실에서 끄덕이는 게 창피했다. 지금도 창피하다. 하지만 이게 신입의 생존 기술이다. 끄덕이면서 배운다. 모르는 걸 적고, 나중에 찾아본다. 선배들한테 하나씩 물어본다. 조금씩 이해한다. 언젠가는 나도. 회의에서 먼저 말하는 사람이 되겠지. 그때까지는. 오늘도 끄덕인다.회의 후 검색창에 남은 단어가 다섯 개. 내일은 네 개로 줄이고 싶다.

면접 때 '네' vs 현재의 '아니'

면접 때 '네' vs 현재의 '아니'

면접 때 '네' vs 현재의 '아니' 그날의 '네' 면접은 5월이었다. 작년 5월. 면접관이 물었다. "React 다룰 줄 아세요?" 나는 대답했다. "네." 거짓말이었다. 아니 거짓말은 아니었다. 부트캠프에서 했으니까. Todo 앱 만들었고, 날씨 앱도 만들었다. 컴포넌트 나누는 것도 알고, props 전달하는 것도 안다. useState도 쓸 줄 알고, useEffect도... 뭐 대충 안다. "TypeScript도 가능하신가요?" "네, 괜찮습니다." 이것도 거짓말은 아니었다. 부트캠프 마지막 프로젝트에서 썼다. 타입 지정하는 거. interface 쓰는 거. 에러 나면 any 박는 거. 다 안다. 면접관이 고개를 끄덕였다. "좋습니다. 저희 스택이랑 잘 맞네요." 그날 집에 가는 길이 기억난다. 지하철에서 유튜브 쇼츠 보면서 웃었다. 합격할 것 같았다. 아니 합격해야 했다. 6개월 동안 구직 활동 했다. 면접 8번 떨어졌다. 이번엔 될 것 같았다.입사 첫날의 '아니' 입사는 7월이었다. 첫날 선배가 코드베이스 보여줬다. "이게 우리 메인 프로젝트고요, 여기가 컴포넌트 폴더예요." 화면을 봤다. 모르는 게 보였다. 아니 아는 게 없었다. const { data, isLoading } = useQuery(...)useQuery가 뭐지. React에 이런 거 있었나. <Suspense fallback={<Loading />}>Suspense는 또 뭐지. 이것도 React야? 선배가 설명했다. "React Query 쓰고 있어요. 서버 상태 관리 라이브러리죠." 고개를 끄덕였다. 이해 못 했다. "그리고 여기 보면 Zustand로 클라이언트 상태 관리하고요." 또 끄덕였다. Zustand가 뭔지 모른다. 첫날 저녁 7시에 퇴근했다. 원룸 와서 노트북 켰다. '리액트 쿼리 튜토리얼' 검색했다. 영상 10분 보다가 잤다. 일주일 차의 '전혀 아니' 첫 태스크를 받았다. "이 버튼 클릭하면 모달 띄워주세요. 간단한 거예요." 간단하다고 했다. 간단하지 않았다. 모달 컴포넌트를 찾았다. 코드가 200줄이었다. props가 15개였다. 주석은 없었다. interface ModalProps { isOpen: boolean; onClose: () => void; children: React.ReactNode; size?: 'sm' | 'md' | 'lg'; closeOnOverlayClick?: boolean; // ... }어떤 props를 써야 하는지 몰랐다. 다른 페이지 코드를 봤다. 복사했다. 붙여넣었다. 에러가 났다. Type 'string' is not assignable to type 'ModalSize'타입 에러였다. any를 박았다. 에러가 사라졌다. 동작했다. PR을 올렸다. 손이 떨렸다. 30분 뒤 코드리뷰가 달렸다. "any 사용은 지양해주세요. 타입을 명시적으로 지정해주시면 좋겠습니다." "onClose 함수를 useCallback으로 감싸주세요." "이 부분은 custom hook으로 분리하면 더 좋을 것 같아요." useCallback이 뭐지. custom hook은 또 뭐지. 구글에 검색했다. 블로그 3개 읽었다. 이해 안 됐다. 유튜브 봤다. 10분짜리 영상. 7분에 멈췄다.한 달 차의 '완전히 아니' 회의가 있었다. 기술 스택 논의. "Next.js 14 App Router로 마이그레이션 어떨까요?" "Server Component 쓰면 성능 개선 확실할 거예요." "RSC 도입하면 클라이언트 번들 사이즈도 줄고." 무슨 말인지 하나도 모르겠다. Next.js는 React 아니었나. App Router는 또 뭐고. RSC는 뭐야. 고개만 끄덕였다. 회의록을 적었다. 나중에 찾아보려고. 퇴근 후 검색했다. 'Next.js 14 App Router' 공식 문서가 나왔다. 영어였다. 번역기 돌렸다. 이해 안 됐다. 유튜브에 '넥스트 14 튜토리얙' 검색했다. 40분짜리 영상. 재생했다. 5분 보다가 다른 영상으로 넘어갔다. '리액트 기초부터'. 그날 깨달았다. 나는 React를 모른다. 면접 때 '네'라고 했던 그 React를. 두 달 차의 '절대 아니' 선배가 물었다. "신입님, useEffect 의존성 배열 왜 비워두셨어요?" 나는 대답했다. "한 번만 실행하려고요." 선배가 말했다. "여기 state 참조하고 있는데요?" 코드를 봤다. useEffect(() => { fetchData(userId); }, []);userId가 바뀌면? 음... 모르겠다. "의존성 배열에 userId 넣어야죠." "아 네." 고쳤다. 다시 에러가 났다. 무한 루프였다. console.log가 100번 찍혔다. 선배가 옆에 와서 봤다. "fetchData를 useCallback으로 감싸야 해요." 또 useCallback이다. 유튜브에서 봤는데. 이해 못 했는데. "네... 그렇게 할게요." 검색했다. 'useCallback 언제 써요'. 블로그 10개를 읽었다. 하나도 이해 안 됐다. 예제 코드를 복사했다. 붙여넣었다. 됐다. 왜 되는지 모른다. 그날 저녁 편의점에서 삼각김밥 샀다. 참치마요. 500원 할인이었다. 앉아서 먹으면서 생각했다. 나는 React를 모른다. TypeScript도 모른다. 면접 때 '네'라고 했던 건 뭐였을까.세 달 차의 '그래도' 오늘 PR이 머지됐다. 첫 번째 기능 완성. 로그인 페이지 에러 처리였다. 일주일 걸렸다. 코드는 80줄. 코드리뷰는 12개 받았다. 수정은 7번 했다. 하지만 머지됐다. 선배가 슬랙에 메시지 보냈다. "고생하셨습니다 👍" 답장했다. "감사합니다." 저장했다. 그 슬랙 메시지 스크린샷. 노션에 붙였다. '칭찬 모음' 페이지에. 그리고 생각했다. 면접 때 '네'라고 했던 나를. 거짓말쟁이라고 생각했다. 사기꾼이라고 생각했다. 회사를 속였다고 생각했다. 근데 지금은 생각한다. 그때 '아니요'라고 했으면 어땠을까. 면접 떨어졌을 거다. 여기 못 왔을 거다. 지금 이 코드도 못 봤을 거다. useQuery도 몰랐을 거고, Zustand도 몰랐을 거고, useCallback도 몰랐을 거다. 모르는 게 많다. 여전히 많다. useEffect 의존성 배열 아직도 헷갈린다. TypeScript any 아직도 쓴다. 코드리뷰 받을 때마다 심장 뛴다. 근데 3개월 전보다는 안다. 조금은 안다. PR 2개 머지했다. 버그 1개 고쳤다. 선배한테 칭찬 1번 받았다. 용서 면접 때 '네'라고 했던 나에게. 미안하다고 하고 싶었다. 거짓말쟁이라고 하고 싶었다. 근데 지금은 안다. 그건 거짓말이 아니었다. '할 수 있다'는 건 '지금 할 수 있다'가 아니라 '배워서 할 수 있다'는 거였다. 면접 때 나는 대답했다. "네, React 할 줄 압니다." 정확히는 이거였다. "네, React 배워서 할 수 있습니다." 지금도 못한다. 여전히 모른다. 하지만 배우고 있다. 매일 조금씩. 그게 '할 줄 안다'는 거였다. 부트캠프 동기가 어제 톡 보냈다. "면접 때 뻥쳤던 거 생각나서 밤에 잠 안 와." 답장했다. "그거 뻥 아니야. 진짜야. 우리 지금 하고 있잖아." 읽씹이었다. 10분 뒤 답장 왔다. "ㅇㅈ"면접 때 '네'는 거짓말이 아니라 약속이었다. 지금 그 약속 지키는 중이다.

퇴근 후 인프런: 10분 강의, 10분 수면

퇴근 후 인프런: 10분 강의, 10분 수면

오늘은 다르다고 생각했다 퇴근했다. 7시 50분. 회사에서 원룸까지 30분. 지하철에서 서서 왔다. 앉으면 잔다. 문 열고 들어왔다. 책상 위에 어제 켜놨던 노트북. 인프런 강의가 일시정지 상태다. 12분 23초에서 멈춰있다. 어제도 못 봤다는 뜻이다. 오늘은 다를 거라고 생각했다. 지하철에서도 생각했다. '오늘은 최소 1시간은 본다. React 훅 제대로 이해한다. useEffect 의존성 배열 완벽하게 이해한다.' 씻었다. 편의점 도시락 데웠다. 3900원짜리 제육볶음. 밥을 먹으면서도 생각했다. '밥 먹고 바로 시작한다. 30분만 쉬고.'30분이 1시간이 되는 법칙 침대에 누웠다. 30분만. 유튜브 쇼츠 켰다. 개발 관련 영상이다. 공부다. 이건 공부의 일부다. 쇼츠가 20개 지나갔다. 시계를 봤다. 8시 40분. 50분이 지났다. 일어났다. 책상 앞에 앉았다. 노트북을 켰다. 인프런을 켰다. 내 강의 목록이 보인다."React 완벽 가이드" - 진도율 14% "TypeScript 기초부터" - 진도율 8% "클린코드 실전" - 진도율 3% "JavaScript 심화" - 진도율 22%다 돈 주고 샀다. 총 27만원. 할인할 때 샀다고 했지만 27만원이다. 부모님한테 용돈 받은 돈으로 샀다. 명절 때. 오늘은 React를 본다. 클릭했다. 로딩됐다. 강사 얼굴이 나온다. 밝은 목소리다. "안녕하세요 여러분!" 나도 안녕하세요. 근데 좀 피곤하긴 하다.10분의 전투 재생했다. 1.5배속이다. 1배속으로 들으면 시간이 너무 오래 걸린다. 1.5배속도 느린 것 같은데 2배속은 못 알아듣는다. "오늘은 useEffect의 의존성 배열에 대해 알아보겠습니다." 바로 이거다. 내가 모르는 거다. 집중한다. 메모장을 켰다. 필기한다. "의존성 배열은..." 눈이 감긴다. 아니다. 떴다. 계속 본다. "...배열 안에 들어가는 값이 변경될 때마다..." 고개가 앞으로 간다. 아니다. 다시 든다. 커피를 마신다. 아까 편의점에서 산 아메리카노. 식었다. "...그렇기 때문에 의존성 배열을 비워두면..." 3분 지났다. 아직 7분 남았다. 할 수 있다. 화면을 본다. 코드가 나온다. 따라 친다. VSCode를 켰다. 새 파일을 만들었다. test.jsx. 강의 코드를 따라 친다. useEffect(() => {}, [])입력하다가 멈췄다. 뭘 치는 거였지. 강의를 다시 돌렸다. 10초 전으로. "...여기서 console.log를 찍어보면..." 아 맞다. console.log. 쳤다. useEffect(() => { console.log('마운트') }, [])눈이 또 감긴다. 안 된다. 일어났다. 스트레칭했다. 제자리에서 10번 뛰었다. 다시 앉았다. 강의는 계속 재생 중이다. 5분 지났다. 강사는 계속 말한다. 밝게. "이해되셨나요? 그럼 이제..." 이해 안 됐다. 근데 계속 간다.침대가 부른다 7분 지났다. 3분 남았다. 할 수 있다. 거의 다 왔다. 근데 침대가 보인다. 책상 바로 옆이다. 원룸이니까. 1.5미터 거리다. 이불이 보인다. 푹신해 보인다. 아까 누웠을 때 기억이 난다. 좋았다. 강의는 계속된다. "...dependency array의 두 번째 활용법은..." dependency array. 의존성 배열. 알아들었다. 이 정도면 됐다. 오늘 뭔가 배운 것 같다. 8분. "잠깐만 눈 붙이고 다시 보면 되지 않나." 이 생각이 들면 끝이다. 알고 있다. 근데 생각이 들었다. "10분만. 타이머 맞추고." 핸드폰을 들었다. 타이머 10분. 시작. 침대로 갔다. 누웠다. 이불을 덮었다. 노트북에서 강의 소리가 들린다. "...그래서 이 부분이 중요한데요..." 중요하구나. 근데 눈이 감긴다. "10분만. 10분 후에 일어나서 다시 본다." 눈을 감았다. 다음날 아침 알람이 울렸다. 7시. 일어났다. 책상을 봤다. 노트북이 켜져 있다. 화면보호기가 떠 있다. 핸드폰을 봤다. 타이머가 7시간 전에 울렸다. 못 들었다. 노트북을 깨웠다. 인프런 화면이다. "이 영상이 도움이 되셨나요?" 팝업이 떠 있다. 강의는 끝까지 재생됐다. 나는 10분 보고 잤다. 진도율을 봤다. 14%에서 15%가 됐다. 1% 올랐다. 오늘 출근하면 또 선배한테 useEffect 질문 들어올 것 같다. 모른다고 해야 한다. 또. 씻으러 갔다. 거울을 봤다. "오늘 저녁엔 진짜 본다." 어제도 했던 말이다. 그제도 했다. 27만원의 무게 출근길 지하철이다. 선 채로 간다. 핸드폰으로 인프런 앱을 켰다. 내 강의 목록을 본다. 진도율들을 본다. 계산했다. 평균 진도율 11.75%. 총 결제금액 27만원. 본 만큼 나누면 약 3만원어치 봤다. 24만원이 날아갔다. 아니다. 아직 안 날아갔다. 강의는 거기 있다. 내가 안 본 것뿐이다. "오늘은 진짜 본다." 옆 사람이 쳐다본다. 혼잣말했다. 회사 도착했다. 9시 8분. 자리에 앉았다. 슬랙을 켰다. 선배가 멘션을 날렸다. "@이신입 어제 말한 거 useEffect로 처리 가능할 것 같은데 한번 해볼래요?" 심장이 뛴다. "네 해보겠습니다." 검색했다. "useEffect 사용법". 또. 어젯밤 10분 들은 강의가 떠오른다. 뭐라고 했더라. dependency array가... 뭐라고 했지. 기억 안 난다. 유튜브를 켰다. "useEffect 5분 정리". 영상을 봤다. 5분짜리는 본다. 안 졸린다. 이해했다. 코드를 짰다. 돌아간다. PR을 올렸다. 선배가 approve 했다. "굿!" 기분이 좋다. 근데 생각한다. '어젯밤에 10분만 더 봤으면 유튜브 안 찾아봐도 됐을 텐데.' 오늘 저녁 계획 점심시간이다. 편의점에 갔다. 삼각김밥 두 개. 2600원. 먹으면서 생각한다. 오늘 저녁 계획. '퇴근하고 씻고. 밥 먹고. 바로 책상 앞에 앉는다. 침대는 쳐다도 안 본다. 1시간 본다. 무조건.' 동기한테 카톡이 왔다. "너 요즘 공부 어떻게 해?" "강의 듣는데 잘 안 돼ㅠ" "나도ㅠㅠ 퇴근하면 너무 피곤해" "인정... 근데 해야 하는데" "ㅇㅈ... 주말에 하자" 주말. 토요일. 11시에 일어난다. 점심 먹는다. 오후 2시. '저녁 먹고 하지.' 저녁 먹는다. 7시. '소화 좀 시키고.' 9시. '내일 하자.' 일요일도 똑같다. 알고 있다. 주말에 안 한다는 거. 그래도 말한다. "ㅇㅇ 주말에 몰아서 하자" "ㅇㅋㅇㅋ" 안 될 거다. 우리 둘 다. 삼각김밥을 다 먹었다. 편의점 커피를 샀다. 1500원. 오늘 세 번째 커피다. 자리로 돌아왔다. 오후 업무 시작이다. 선배가 또 말했다. "신입아 이거 보면 state 관리 로직이..." 모르는 말이 나온다. 고개를 끄덕인다. "네네." 퇴근까지 5시간. 오늘은 정시 퇴근이다. 6시. '오늘은 진짜 공부한다.' 어제도 한 생각이다. 그저께도. 내일도 할 것 같다.인프런 강의가 14개다. 총 금액 60만원. 평균 진도율 9%. 오늘도 10분 볼 거다. 내일도.

점심시간, 편의점 삼각김밥과 함께 강의 보기

점심시간, 편의점 삼각김밥과 함께 강의 보기

점심시간, 편의점 삼각김밥과 함께 강의 보기 12시 30분, 편의점 가는 길 점심시간이다. 팀원들이 우르르 나간다. "신입님도 가시죠?" 물어본다. "저는 도시락 싸왔어요." 거짓말이다. 도시락 같은 거 안 쌌다. 그냥 혼자 먹고 싶다. 대화가 피곤하다. 무슨 말 해야 할지 모르겠다. "요즘 뭐 공부해요?" 물어보면 대답이 막힌다. 엘리베이터 타고 1층 내려간다. 편의점은 건물 옆이다. 2분 거리. 바람이 시원하다. 8월인데도 오늘은 좀 선선하다. 이럴 땐 밖에서 먹을까 생각했다가 관둔다. 노트북 들고 나오기 귀찮다.편의점 삼각김밥 고르기 편의점 문 열고 들어간다. 시원하다. 삼각김밥 코너로 간다. 오늘은 뭐 먹지. 참치마요? 아니 어제 먹었다. 김치참치? 별로다. 불고기? 그거 밥이 너무 적다. 결국 스팸마요 집는다. 항상 먹는 거다. 바나나우유도 하나 집는다. 2900원이다. 계산하고 나온다. 사무실로 돌아간다. 책상에 앉는다. 주변에 아무도 없다. 다들 밥 먹으러 나갔다. 1시까지는 조용하다. 노트북 켠다. 슬랙 알림 끈다. 유튜브 연다.'10분 안에 이해하는 useEffect' 오늘 볼 강의는 이거다. '10분 안에 이해하는 useEffect 완벽 정리'. 조회수 12만. 댓글 보면 다들 "이제 이해했어요!" 이런다. 나도 이해할 수 있을까. 재생 누른다. 삼각김밥 뜯는다. "안녕하세요 여러분~" 강사가 밝게 인사한다. 나는 스팸마요 한 입 먹는다. 맛있다. "useEffect는 React의 생명주기를 다루는..." 설명이 시작된다. 고개 끄덕인다. 두 입 먹는다. 강의는 계속된다. "의존성 배열에 따라서..." 뭔 소리지. 세 입 먹는다. 바나나우유 빨대 꽂는다. 빨대 소리가 좀 크다. 주변 둘러본다. 아무도 없다. 괜히 부끄럽다. 강의는 4분째다. 나는 절반 먹었다. 이해는? 잘 모르겠다.멀티태스킹이라는 착각 강의 들으면서 먹으면 더 잘 들어온다고 생각했다. 거짓말이다. 삼각김밥 먹는 데 집중한다. 씹는 데 집중한다. 우유 마시는 데 집중한다. 강의는 배경음악이다. 귀로는 들린다. 머리로는 안 들어온다. "그래서 cleanup 함수를 사용하면..." 강사가 말한다. cleanup? 뭐였지. 지난주에 찾아봤던 것 같은데. 되감기 누른다. 10초 전으로 돌아간다. 다시 듣는다. "cleanup 함수를 사용하면..." 아 맞다. 정리 함수. 컴포넌트 언마운트될 때. 근데 언마운트가 정확히 뭐였지. 일시정지 누른다. 검색한다. "react 언마운트 뜻". 블로그 글 하나 연다. 읽는다. "컴포넌트가 DOM에서 제거될 때..." 아 그거구나. 알 것 같다. 다시 강의 재생한다. 벌써 7분 지났다. 삼각김밥은 다 먹었다. 10분 강의, 25분 소요 강의는 10분이다. 나는 25분 걸렸다. 되감기 3번. 일시정지 5번. 다른 탭 열어서 검색 7번. 강의 끝났다. "오늘도 시청해주셔서 감사합니다!" 강사가 웃는다. 나는? 이해했나? 글쎄. useEffect는 알겠다. 의존성 배열도 알겠다. cleanup도 알겠다. 근데 내 코드에 어떻게 쓰지? 모르겠다. 내일 또 찾아볼 것 같다. "useEffect 의존성 배열 언제 써야 하나요". 이런 거. 휴지로 입 닦는다. 쓰레기 버린다. 시계 본다. 12시 57분. 3분 남았다. 슬랙 알림 켠다. 메시지 17개. 읽는다. "신입님 오후 3시 회의 있어요." 아 맞다. 잊고 있었다. 오후 3시 회의 전까지 회의까지 2시간이다. 오전에 못 끝낸 작업 이어서 한다. 버튼 컴포넌트 만들기. 간단해 보였다. 근데 props 타입 정의하는 게 헷갈린다. interface? type? 뭘 써야 하지. 검색한다. "interface vs type typescript". 블로그 10개 열린다. 읽는다. "interface는 확장 가능하고..." "type은 유니온 사용 가능하고..." 뭔 소리야. 그냥 선배 코드 본다. 선배는 interface 썼다. 나도 interface 쓴다. interface ButtonProps { children: React.ReactNode; onClick: () => void; }복사 붙여넣기 한다. 수정한다. 에러 난다. "Type 'MouseEvent' is not assignable to..." 뭐라는 거야. ChatGPT 연다. 에러 복사해서 붙여넣는다. "이 에러는 이벤트 타입이..." 답변 나온다. 코드 복사한다. 붙여넣는다. 에러 사라진다. 신기하다. 저장한다. 커밋한다. 푸시한다. 시계 본다. 2시 50분. 회의 10분 전이다. 화장실 간다. 볼일 보고 나온다. 손 씻는다. 거울 본다. 피곤해 보인다. 회의실 간다. 아직 아무도 없다. 자리 잡고 앉는다. 노트북 연다. 사람들 들어온다. "신입님 먼저 오셨네요?" 웃으면서 말한다. "네..." 대답한다. 회의 시작한다. 회의 중 멍때리기 "지난주 작업 현황 공유드리겠습니다." 팀장님이 말한다. 파워포인트 화면 바뀐다. 간트차트 같은 게 나온다. 빨강 노랑 초록 막대기들. "A 프로젝트는 80% 진행..." 고개 끄덕인다. A 프로젝트? 내가 하는 건가. "B 프로젝트는 일정이 지연..." 또 끄덕인다. 지연? 누구 때문이지. 나는 아니겠지. "신입님은 버튼 컴포넌트 작업 어떻게 돼가요?" 갑자기 내 이름 나온다. 놀란다. "아... 네. 거의 다 했습니다." 대답한다. 거의? 사실 70%도 안 됐다. "언제까지 가능할까요?" 팀장님이 묻는다. 언제까지? 모르겠다. 내일? 모레? "내일까지 하겠습니다." 입에서 나온다. 후회한다. 내일은 목요일이다. 할 수 있을까. "좋습니다. 그럼 다음..." 화면 넘어간다. 안도한다. 회의는 계속된다. 나는 멍하니 듣는다. 점심시간에 본 강의 생각난다. useEffect. 의존성 배열. cleanup. 아직도 잘 모르겠다. 내일 또 찾아봐야겠다. 퇴근 후 다시 보는 강의 9시에 퇴근한다. 집 가는 지하철. 앉아서 폰 꺼낸다. 유튜브 연다. 점심시간에 본 강의 다시 연다. '10분 안에 이해하는 useEffect 완벽 정리'. 이번엔 제대로 볼 거다. 집중해서. 이어폰 꽂는다. 재생 누른다. "안녕하세요 여러분~" 익숙한 목소리다. "useEffect는 React의 생명주기를..." 설명 시작한다. 3분 듣는다. 이해된다. 오 점심시간보다 낫다. 5분 듣는다. 눈이 감긴다. 피곤하다. 7분 듣는다. 깬다. 뭐라고 했지. 되감기 누른다. 10분 끝난다. 내 역이다. 내린다. 집 들어간다. 씻는다. 침대에 눕는다. 노트북 켠다. 강의 또 들어야 하나. 고민한다. 내일 하자. 눈 감는다.삼각김밥 먹으면서 보는 강의는 맛있지만, 머리엔 안 들어온다. 내일 또 볼 거다.

TypeScript any 남발 사건, 또는 선배한테 혼난 날

TypeScript any 남발 사건, 또는 선배한테 혼난 날

TypeScript any 남발 사건, 또는 선배한테 혼난 날 사건의 발단 오늘 아침에 PR 올렸다. 회원가입 폼 기능 추가. 이틀 걸렸다. 자신 있었다. 일단 돌아갔으니까. 로그인도 되고 회원가입도 되고. 테스트도 다 통과했다. 내가 봐도 깔끔했다. 점심 먹고 돌아왔는데 슬랙 알림 6개. 심장이 쿵 내려앉았다. "이신입님, PR 확인 부탁드립니다." 선배 멘션이었다. 그것도 김민수 선배. 우리 팀에서 제일 무서운 분. 클릭했다. 코멘트 12개. 빨간 줄이 화면을 가득 채웠다. 첫 줄부터 시작됐다. "any 타입 왜 이렇게 많나요?"any가 뭐가 문제인데 처음엔 이해가 안 갔다. 돌아가는데 뭐가 문제야. TypeScript 배울 때 강의에서 들었다. "타입을 지정하세요." 근데 any도 타입 아닌가. 에러도 안 나는데. const handleSubmit = (data: any) => { // 이게 뭐가 문제지? }이렇게 쓰면 편했다. 빨간 줄도 안 생기고. 일단 돌아가니까. 김민수 선배 코멘트를 하나씩 읽었다. "여기 data 타입 명시 필요합니다." "any 쓰면 TypeScript 쓰는 의미가 없어요." "FormData 타입 만들어서 쓰세요." FormData? 그게 뭔데. 또 다른 코멘트. "response도 any네요. 이것도 인터페이스 만드세요." 인터페이스. 들어본 적은 있다. 근데 어떻게 만드는지 모른다.변명의 시간 일단 답장을 써야 했다. "아... 네네 수정하겠습니다." 손이 떨렸다. 뭘 어떻게 고쳐야 할지 모르겠는데. 5분 뒤에 선배가 또 슬랙을 보냈다. "신입님, 잠깐 통화 가능하세요?" 끝났다. 진짜 혼나는 거다. 구글 미트 켰다. 선배 얼굴이 나왔다. 화난 것 같지는 않았다. 그게 더 무서웠다. "신입님, any 타입 많이 쓰셨네요." "아... 네... 그게..." 변명이 나왔다. "타입을 어떻게 지정해야 할지 몰라서요. 에러가 계속 나서..." 선배가 한숨을 쉬었다. 조용한 한숨. 실망한 한숨. "TypeScript는 타입을 지정하라고 쓰는 건데, any 쓰면 JavaScript랑 다를 게 없어요." 알았다. 머리로는. "근데 제가 타입을 몰라서..." "그럼 공부하셔야죠." 할 말이 없었다. 선배의 수업 선배가 화면 공유를 시작했다. 내 코드가 떴다. const handleSubmit = (data: any) => { console.log(data); // ... }"이거부터 볼까요. data가 뭐가 들어올지 알죠?" "네... 이메일이랑 비밀번호요." "그럼 이렇게 쓰면 돼요." interface FormData { email: string; password: string; }const handleSubmit = (data: FormData) => { console.log(data.email); // 자동완성도 됨 }아. 이렇게 하는 거구나. 선배가 계속 설명했다. "이렇게 하면 타입 안전성이 생겨요. data.eamil 이렇게 오타 내면 에러 나죠." 신기했다. 그동안 난 뭐 한 거지. "response도 마찬가지예요." const response: any = await fetch('/api/login');"이거 말고," interface LoginResponse { success: boolean; token?: string; error?: string; }const response: LoginResponse = await fetch('/api/login').then(r => r.json());"이렇게 쓰면 response.token 자동완성도 되고, 오타도 방지되고." 머리가 띵했다. 이렇게 쓰는 거였구나.any를 쓴 이유 선배가 물었다. "근데 왜 any를 이렇게 많이 쓰신 거예요?" 솔직하게 말했다. "타입 지정하려고 하면 빨간 줄이 너무 많이 생겨서요. 에러 메시지도 무슨 말인지 모르겠고." "'Type string is not assignable to type number' 이런 거요?" "네... 그래서 일단 any 쓰면 없어지니까..." 선배가 웃었다. 비웃는 게 아니라 이해한다는 웃음이었다. "저도 처음엔 그랬어요. any 쓰면 편하죠. 근데 나중에 더 힘들어져요." "어떻게요?" "코드가 커지면, any 때문에 어디서 에러 날지 모르거든요. 런타임에 터져요." 런타임. 그게 뭐지. 모르는 척했다. 일단 고개만 끄덕였다. "그리고 any 쓰면 자동완성도 안 돼요. 매번 뭐가 들어있는지 확인해야 하고." 아. 그래서 내가 맨날 console.log 찍었구나. 고치는 시간 통화 끝나고 코드를 다시 봤다. any가 17개였다. 하나씩 고쳤다. 선배가 알려준 대로. 첫 번째. FormData 인터페이스 만들기. interface SignupFormData { email: string; password: string; name: string; age: number; }age는 number구나. 당연한데 몰랐다. 두 번째. API response 타입. interface ApiResponse { success: boolean; data?: any; // 이것도 any네... error?: string; }data도 타입을 지정해야 했다. 뭐가 들어올까. 회원 정보니까. interface UserData { id: number; email: string; name: string; }interface ApiResponse { success: boolean; data?: UserData; error?: string; }이렇게 하니까 깔끔했다. 뭔가 프로 같았다. 세 번째부터는 좀 빨라졌다. 패턴이 보였다.any 찾기 뭐가 들어오는지 생각하기 인터페이스 만들기 적용하기2시간 걸렸다. any가 0개가 됐다. PR 다시 올렸다. 코멘트 달았다. "any 타입 모두 수정했습니다. 확인 부탁드립니다." 다시 코드리뷰 30분 뒤에 선배가 답글 달았다. "훨씬 좋아졌네요 👍" 심장이 두근거렸다. 칭찬이다. 선배한테 칭찬 들은 건 처음이다. "몇 가지만 더 수정하면 될 것 같아요." 또 코멘트가 달렸다. 3개. 아까보다 훨씬 적었다. "여기 optional 타입 물음표 빼도 될 것 같아요." "이 부분은 타입 추론 되니까 명시 안 해도 돼요." "Union 타입 쓰면 더 정확할 것 같네요." Union 타입? 또 모르는 용어다. 검색했다. string | number 이런 거였다. 아 이런 것도 있구나. 고쳤다. 다시 올렸다. 10분 뒤에 Approve 떴다. "LGTM! Merge 하셔도 됩니다." LGTM. Looks Good To Me. 이건 안다. 부트캠프에서 배웠다. Merge 버튼 눌렀다. 초록색으로 바뀌었다. "Merged". 기분이 이상했다. 뿌듯한데 부끄러웠다. 이제야 제대로 한 거 같은데, 진작 이렇게 했어야 했는데. 그날 저녁 퇴근하고 편의점 갔다. 맥주 2캔 샀다. 삼각김밥도. 원룸 들어와서 노트북 켰다. 인프런에 TypeScript 강의 검색했다. "타입스크립트 올인원" 결제했다. 66000원. 아깝지만 필요했다. 첫 강의 재생했다. "TypeScript가 뭔가요?" 알 것 같으면서도 모르겠다. 제대로 배워본 적이 없으니까. 강의 들으면서 메모했다. 노션에.any는 최대한 쓰지 말기 인터페이스로 타입 정의하기 타입 추론 활용하기 Union 타입 (|) Optional 타입 (?)메모하다가 든 생각. 나 지금까지 뭐 한 거지. 부트캠프 6개월. TypeScript 2주 배웠다. 근데 any만 썼다. 제대로 배운 게 없었다. 입사하고 8개월. 그동안 계속 any 썼다. 아무도 안 알려줬다. 물어보지도 않았다. 선배가 오늘 처음 짚어줬다. 그것도 코드리뷰에서. 부끄러웠다. 강의 1시간 들었다. 눈이 떠지는 기분이었다. "타입은 문서예요. 코드를 설명하는." 아. 그래서 타입을 정확히 써야 하는구나. "any는 타입 시스템을 무너뜨려요." 내가 한 짓이 그거였다. 타입 시스템을 무너뜨린 거. 다음날 아침 출근했다. 9시 8분. 오늘은 일찍 왔다. 슬랙 켰다. 김민수 선배가 메시지 보냈다. "신입님, 어제 수정 잘 하셨어요. 앞으로도 타입 꼼꼼히 지정하시면 좋을 것 같아요." "네 감사합니다. TypeScript 강의 결제했습니다." "오 좋네요. 궁금한 거 있으면 언제든 물어보세요." 물어봐도 되는구나. 몰랐다. 항상 혼자 끙끙댔는데. 오늘 작업 시작했다. 새로운 기능 추가. 장바구니 API 연결. 이번엔 달랐다. 먼저 타입부터 정의했다. interface CartItem { id: number; name: string; price: number; quantity: number; }interface CartResponse { items: CartItem[]; total: number; }코드 쓰기 전에 타입 먼저. 선배가 알려준 대로. 신기했다. 자동완성이 됐다. item. 찍으니까 id, name, price, quantity가 뜬다. console.log 안 찍어도 됐다. 뭐가 들어있는지 알았으니까. 에러도 빨리 찾았다. item.price 를 item.cost로 잘못 썼는데 바로 빨간 줄 떴다. "Property 'cost' does not exist on type 'CartItem'." 아. 이게 TypeScript구나. 2주 후 PR 올렸다. 장바구니 기능 완성. any는 0개. 김민수 선배가 리뷰했다. 코멘트 2개. "타입 정의 깔끔하네요." "LGTM!" 2개. 처음으로 한 자릿수 코멘트. Approve 바로 떨어졌다. Merge 했다. 슬랙에 선배가 또 메시지 보냈다. "신입님 많이 늘었어요. 타입 쓰는 거 보니까." 기분이 좋았다. 진짜 좋았다. 인정받는 기분. 선배한테 혼난 지 2주 만에. 그날 저녁에 부트캠프 동기 단톡방에 썼다. "너네 TypeScript any 쓰지 마. 진짜로." "왜? 편한데?" "나 그거 때문에 혼났어. 제대로 배워." "ㅋㅋㅋ 오케이." 얘들도 언젠가 혼날 거다. 나처럼.any는 마약이었다. 당장 편하지만 나중에 독이 됐다. 2주 동안 TypeScript 강의 10시간 들었다. 이제야 TypeScript 쓰는 이유를 알았다. 선배한테 혼나서 다행이다. 안 그랬으면 계속 any 썼을 거다.