2025 상반기 ICT 학점연계 인턴십 지원 후기 를 작성한지 벌써 6개월이 넘는 시간이 흘렀다. 지난 3월~8월까지 구름이라는 회사에서 있었던 경험에 대해 되돌아보는 의미에서 회고를 하게 되었다.
두서 없이 작성하여 글의 흐름이 자연스럽지 않은 점 양해 부탁드립니다 !
인턴십이 끝난지 벌써 2주가 지나서 기억이 더 휘발되기 전에 작성했다…
공식 홈페이지에서는 ICT 학점연계 인턴십을 다음과 같이 소개하고 있다.
💡
국내·외 기업에서 제안한 ICT분야 직무중심의 프로젝트, 서비스 개발 등에 대학생이 참여하여 인턴십을 수행하고, 이를 학점으로 인정받도록 하는 이론과 실무 역량을 겸비한 문제해결형 창의인재양성 프로그램입니다.
지원 후기에서도 언급했듯이 필자가 재학 중인 학교에서는 졸업 요건 중에 인턴십 진행이라는 항목이 있기도 했고, 캡스톤 디자인이라는 과목을 인턴십을 통해 한 번 대체할 수 있기에 해당 인턴십에 지원했다. (15학점도 인정해줘서 지원하지 않으면 손해인 프로그램이었다!)
필자는 구름이라는 회사에 풀스택 엔지니어로 합류할 수 있었다 !
지원 과정은 총 3개의 기업을 선정해서 지원했고, 필자는 2개의 기업에 대해 서류 합격 후 면접을 볼 수 있었다. 두 기업 모두 대면 면접으로 진행되었으며, 최종적으로 하나의 기업 구름이라는 기업에 풀스택 엔지니어 직무로 합격하였다 !
(면접 질문 관련해서는 지원 후기에서 자세히 서술하였으로 생략했다.)
면접도 개인적으로 못봤다고 느꼈고, 사전 과제도 면접 때 시연하였을 때 중요 기능이 동작하지 않아서 너무 당황스러웠다. 가장 부끄러웠던 순간은 면접 때 맥북을 처음 사용해서 개발자 도구를 통해 반응형 디자인을 시연하는 과정에서 f12를 눌러도 개발자 도구가 켜지지 않고 볼륨이 계속 커져서 너무 당황했고 머리 속이 하얗게 질렸다. 그래서 크롬 설정 → 도구 → 더보기 → 개발자 도구 혹은 마우스 우클릭 → 검사 와 같이 개발자 도구를 활성화할 수 있는 방법이 전혀 떠오르지 않았고 개발자 도구를 사용할 줄 모르는 웹 개발자로 보일까봐 너무 민망했던 기억이 난다.
그래도 합격해서 너무 행복했었다.

(너무 신나서 인스타 스토리도 올리고 자랑도 많이 했었다ㅎㅎ..)
필자는 구름이라는 회사를 IDE 서비스를 처음 접하게 되었다. 대학교 1학년 때 얼핏 듣었다가 군대에서 코딩을 할 수 있는 IDE 웹 서비스를 찾던 도중 한국 서비스가 있어서 잠깐 사용하면서 접했었다.

구름 공식 홈페이지에서는 다음과 같이 소개하고 있다.
💡
구름은 ‘모두가 개발자가 된다’라는 비전으로 언제 어디서나 AI∙SW 개발을 배우고,
원하는 결과물을 구현할 수 있도록 ‘개발자 성장 중심’의 생태계를 만들어 나가고 있습니다.
구름은 설치가 필요없는 온라인 IDE 서비스를 제공하는 구름IDE 뿐만 아니라 인프런과 같이 SW 교육 영상들을 제공하는 플랫폼인 구름EDU, 알고리즘 온라인 저지 사이트 구름LEVEL, 코딩 테스트 환경을 제공하는 구름DEVTH 등과 같이 다양한 IT 서비스를 제공하는 회사이다.
또한, 다양한 교육 사업들도 운영한다 ! (대표적으로 구름 DEEP DIVE)
회사는 판교 디지털 센터 A동 9층에 위치해있다.
입사 전에는 별다른 준비를 할 것은 없었지만 회사 문화 중 영어 이름을 쓰는 문화가 있어 영어 이름을 정하느라 고민했었다..
고민 끝에 예전에 인상 깊게 본 영화인 인터스텔라에서 주인공 쿠퍼와 끝까지 함께 했던 인공지능 로봇 타스(TARS)에서 이름을 따왔다.

(영화 속 타스처럼 다재다능하게 역할을 회사에서 하고 싶다는 이유였다ㅋㅋ..)
또, 입사 전에 풀스택 엔지니어 직무로 입사하게 되어 걱정이 앞섰다. 풀스택으로 진행한 프로젝트가 있었지만, 필자는 프론트엔드 개발자를 지향했기 때문에 백엔드 관련 지식이 프론트엔드에 비해서 매우 빈약했기 때문이다. 그래서 “회사에서 진행하는 업무에 적응하지 못하고 짐이 되면 어떡하지?, 업무를 진행하지 못해서 얻어 가는게 없으면 어떡하지?”와 같은 걱정을 많이 했었다.
하지만 입사 후 ‘위 같은 걱정은 정말 괜한 걱정이었구나’ 라고 느꼈다. 입사 후 모든 분이 모르는 부분에 대해 잘 알려주셨고, 업무도 최대한 내가 해결할 수 있는 업무들로 할당해주셨기 때문이다 ! (다들 너무 감사했습니다!!!!!)
입사 후 2주 간은 온보딩을 진행했었다. 구름의 문화, 복지, 내가 속한 팀이 어떤 업무를 진행하는지, 구름의 개발 문화 등에 대해 들을 수 있었다.
온보딩을 하면서 가장 인상 깊었던 부분은 구름 사내 디자인 시스템이 있다는 점이었다. 구름 사내 디자인 시스템에 대해 설명을 들으면서 디자인 시스템이 무엇인지, 또 어떤 디자인 시스템이 존재하는지 알게 되어 너무 유익했었다.
💡
디자인 시스템이란,
서비스의 일관성을 유지하고 효율적인 디자인 및 개발을 돕기 위해 컬러, 타이포그래피, 레이아웃, 컴포넌트 등 디자인 요소를 표준화하여 규칙과 가이드라인으로 정의한 체계적인 시스템이다.
온보딩 시점에서는 구름 디자인 시스템을 오픈소스화 할 예정이라고 했고 현시점에서는 오픈소스로 공개되어 모두가 사용하고 기여할 수 있게 되었다 ! (구름 디자인 시스템 : vapor-ui 공식 문서)
필자는 보통 9시 ~ 9시반 사이에 출근했다. (구름은 유연출근제였기 때문에 고정 출근 시간이 따로 없었다 !)
보통 오전과 오후가 다를 것이 없었다.
요약하자면, 오전, 오후 모두 진행하고 있는 프로젝트를 개발하거나 문서화를 하고 회의가 있으면 회의에 참석하는 식으로 출근 ~ 퇴근이 반복되었다.
필자가 속한 팀은 일일 체크인을 진행했는데, 팀원 모두가 모여 현재 업무 진행사항을 공유하고 간단하게 의견을 나눌 안건이 있으면 의견을 나누는 시간을 가졌었다. 또한 마지막에는 오늘의 컨디션을 공유하는 시간을 가졌는데, 체크인을 통해 팀에 빠르게 적응할 수 있었다.
퇴근은 보통 일 8시간을 채우고 퇴근하였다. (오후6시 ~ 6시반 정도에 퇴근했던 것 같다.)
점심은 회사 건물 지하에 있는 구내 식당에서 먹을 수 있었다. 식대가 나오기에 점심은 부담 없이 즐길 수 있었다 ! A, B, C 코스 총 3가지의 식사 혹은 샐러드가 선택지로 주어지는데, 필자는 샐러드를 제외하고 맛있어 보이는 코스를 선택했다.
구내 식당의 좋은 점은 밥을 마음대로 먹을 수 있다는 점이었다. (그래서 필자는 밥을 2그릇씩 먹었었다)
필자가 속한 팀은 구름의 교육 사업 운영을 관리하고 편의성을 제공하는 사내 서비스를 개발하는 팀이었다. 사내 서비스를 개발하는 팀이라 외부로 보여줄 제품이 별로 없어 아쉽지만, 대표적으로 구름에서 진행하는 사업에서 모집 혹은 설문조사를 할 때 사용할 수 있는 구름만의 폼 서비스를 개발하였다. (구름 DEEP DIVE - 풀스택 개발자 과정 지원서)
필자는 풀스택 엔지니어 직무였지만, 팀 리더께서 필자가 프론트엔드 개발자를 지향하는 것을 고려해서 팀에서 진행하는 프로젝트의 프론트엔드 담당으로서 업무를 할당해주셔서 너무 감사했다 !
그래서 인턴십 기간 3 ~ 8월동안 프론트엔드 개발에 몰두할 수 있었다.
진행한 업무
입사 후 약 6주 간 구름에서 신제품으로 출시할 서비스의 TF로 편성되어 해당 서비스의 QA 사항들을 반영하는 업무를 할당 받았다.
CSS만 수정하는 단순한 업무를 진행하기도 했지만, 제품의 나름(내 기준) 중요한 버그도 수정하는 경험을 할 수 있었다 !
Fixed the bug where editor not close when deleting folders or files.
Fixed the bug for deleted file tags in SideChat.
(내가 고친 버그가 실서비스의 릴리즈 노트에 기록되는 경험이 너무 뿌듯했다.)
또한 레거시 코드를 수정하여 버그를 고치거나, 신규 기능을 추가하는 경험도 하였는데, JQuery, React의 class component를 다루어 보는 소중한 경험을 할 수 있었다.
느낀 점
신제품 개발 TF 업무를 하면서 느꼈던 점은 신규 기능을 빠르게 개발하는 능력도 중요하지만, QA 사항을 빠르게 반영할 수 있도록 기존 코드를 빠르게 이해하는 능력도 겸비해야 하는 것을 느꼈다. 현업에서는 내가 작성한 코드만 수정하는 것이 아닌 전임자 혹은 다른 동료가 개발한 기능에서 발생한 버그를 수정해야 하는 일이 빈번하기에 코드를 이해하는 능력이 정말 중요하다고 느껴졌다. 또한 타 개발자가 코드를 읽었을 때, 이해하기 좋은 코드를 작성하는 능력 즉, 유지 보수에 좋은 코드를 작성하는 능력도 중요함을 느꼈다 !
진행한 업무
위에서 언급했듯이 내가 속한 팀은 구름 자체 폼을 만들고 관리하는 서비스를 개발하였다.
가끔 디자인 공수가 나지 않을 때, 직접 시안을 만들어서 개발까지 하는 경험도 했다 !
가장 기억에 남은 일은 다음과 같다. 팀에서 axios 대신 AJAX 라이브러리로 ky라는 라이브러리를 활용했다. ky는 axios과 비슷하게 instance를 활용하여 header, fetch option 등을 계속 재사용할 수 있었다. 우리 팀은 ky 인스턴스를 싱글톤 패턴을 활용해서 하나의 인스턴스를 사용했다.
또한 인증 체계는 jwt 방식을 활용했는데, 여기서 문제가 발생했다.
보통 jwt 방식의 경우,
1. access token 만료 시 401 에러
2. 401 에러 발생 시 refresh token으로 access token 재발급 요청
3. access token 재발급 요청 성공 시 401 에러로 실패했던 요청들 재시도
4. access token 재발급 요청 실패 시 로그인 페이지로 redirect
위 같은 방식으로 인증 체계를 구현할 것이다.
하지만 우리 프로젝트의 경우, 로그인을 해야만 접근이 가능한 페이지로 로그아웃 상태로 접근 시 로그인 페이지로 리다이렉트 되어야 하지만 그렇지 않고 흰 화면에서 웹 사이트가 멈추는 문제가 있었다. 이는 사용성에 악영향을 미치는 버그였기에 고치고자 하였다.
하지만 디버깅을 위해 console.log를 찍어도, debugger를 사용해도 어느 부분에서 프로세스가 블로킹되는지 찾을 수가 없었다.
이를 해결하기 위해 ky 인스턴스의 인증 체계를 분석했다.
분석 결과는 다음과 같았다.
1. access token 만료 시 401 에러
1. 401 에러로 실패한 요청들을 retry queue에 push
2. 401 에러 발생 시 refresh token으로 access token 재발급 요청
3. access token 재발급 요청 성공 시 retry queue에 있는 요청들 재시도
4. access token 재발급 요청 실패 시 retry queue = [] 로 변경 후, 401 에러 throw
문제는 로그아웃 상태에서도 401 에러가 throw되지 않는 것이 원인임을 파악할 수 있었다. 그리고 왜 401 에러가 throw되지 않는지 분석을 했다. 분석 결과 문제는 retry queue = [] 에 있었다. retry queue 있는 Promise들을 resolve 혹은 reject하지 않은 상태로 retry queue를 [] 로 변경하니,
const exampleResponse = await ky.get('api/example');
---
ky 인스턴스
const retryQueue = [Promise(ky.get('api/example')]
// exampleResponse가 Promise(ky.get('api/example')를 참조 중
refresh token으로 access token 발급 실패 시
const retryQueue = [];
-> Promise(ky.get('api/example')는 여전히 exampleResponse가 참조하여
-> Garbage Collector가 Promise(ky.get('api/example')를 메모리 해제하지 않음
-> const exampleResponse = await ky.get('api/example');의 await를 해소하지 못해 process block
위와 같은 문제가 있었고, 해당 문제를 아래와 같이 해결하였다.
1. access token 만료 시 401 에러
1. 401 에러로 실패한 요청들을 retry queue에 push
2. 이 때, 비동기 요청만 queue에 push하는 것이 아닌 해당 Promise의 resolve, reject 함수도 함께 push
ex) [Promise()] => [{Promise(), resolve(), reject()}]
2. 401 에러 발생 시 refresh token으로 access token 재발급 요청
3. access token 재발급 요청 성공 시 retry queue에 있는 요청들 재시도
4. access token 재발급 요청 실패 시
1. retry queue에 있는 Promise들의 reject()를 통해 전부 reject
2. 이후, retry queue = []
3. throw 401 error
해당 버그를 해결하여 로그아웃 상태에서 서비스 접근 시 로그인을 요구하는 페이지라면 정상적으로 로그인 페이지로 리다이렉트 되도록 하여 서비스의 완성도를 높힐 수 있었다. 또한 jwt 인증 체계를 확실하게 학습할 수 있었으며, Javascript의 메모리 누수와 Garbage Collector의 개념에 대해서도 학습할 수 있었다.
마지막으로 console.log로도 로깅이 되지 않는 버그를 해결한 것이라 너무 뿌듯했다 !!
배운 점
나는 팀에서 진행한 프로젝트에서 프론트엔드 개발자로서 개발할 수 있었다. 개발을 하며 배운 점은 아래와 같다.
팀에 처음 합류하고 적응을 위해 팀에서 진행하는 프로젝트를 봤을 때, Pick<T, 'a'>, Omit<T, 'etc'>, Partial<T, 'a'> 와 같은 타입을 봤었다. 또한 Example[’ex1’] 과 같이 타입을 재사용하는 코드를 보면서 나는 여태까지 typescript를 제대로 사용하지 않았다는 것을 느낄 수 있었다.
팀에서 진행한 프로젝트를 개발하면서 typescript의 유틸리티 타입, Indexed Access Type 등과 같은 편리한 기능에 대해서 학습할 수 있었다.
팀에서 개발하는 프로젝트의 폴더 구조는 FSD(Feature-Sliced Design) 구조를 채택하였다. 필자는 여태까지 진행한 프로젝트 모두 FSD 구조를 사용하였기에 이름은 낯설지 않았다. 하지만 FSD 구조를 전부 이해하지 못한 상태로 적용하여 layer-slice-segment 계층 구조에서 layer, slice 까지는 프로젝트에 적용하였으나, segment (세그먼트) 까지는 적용하지 않았다. 하지만 내 팀에서 개발하고 있던 프로젝트에서는 segment 개념까지 도입하여 FSD 구조를 엄격하게 지키려고 노력하셨다. segment 개념은 익숙치 않아서 초기에는 사수 분께 계속 ‘이 컴포넌트는 어떤 layer(apps, pages, widgets, features, entities) 중 어디가 어울릴까요 ?, 슬라이스는 어디에 ? , segment는 이 곳이 적절할까요 ?’와 같은 질문을 엄청 많이 했었다. 하지만 익숙해지고 난 뒤로는 코드의 폴더 위치만으로도 어떤 기능을 제공할 지가 예상돼서 내가 작성하지 않은 코드도 빠르게 이해할 수 있었다.
또한 TEO님의 FSD 관점으로 바라보는 코드 경계 찾기 글을 이전에 읽었었는데, 다시 읽어보니 이해가 조금 더 잘 되는 감이 있었다.
물론 폴더 구조는 절대적으로 정해진 부분이 없지만 프로젝트를 진행함에 있어 팀원 모두가 아키텍처를 얼마나 잘 이해하는 지가 업무의 효율을 크게 올릴 수 있음을 느낄 수 있었다.
인턴십을 통해 배운 FSD 구조를 추후 진행하는 프로젝트 등에 적용을 해서 FSD 구조의 개념을 더욱 단단하게 굳혀야 겠다고 느꼈다 !
프론트엔드 개발자라면 RHF (react-hook-form)를 활용해서 Form 컴포넌트를 구현해본 경험이 있을 것이다. 필자도 React를 처음 입문했을 때, 개념도 잘 안잡혀있는 상태에서 react-hook-form으로 로그인 폼을 구현했던 경험이 있었다. 하지만 하나의 컴포넌트로 구현하는 방법 밖에 알지 못해 RHF를 제대로 사용했다고 할 수는 없었다. 하지만 팀에서 폼 서비스를 개발하며 RHF로 폼을 구현할 때, formContext, useController 등을 활용해서 각 기능 별로 컴포넌트화 시킬 수 있음을 알 수 있었다.
또한 react-router에서 제공하는 loader라는 기능, axios에 비해 훨씬 경량화된 ky 라이브러리, 전역 상태 관리 zustand 등 다양한 라이브러리를 활용하면서 서드파티에 대한 시야를 넓히고 공식 문서를 읽는 힘을 기를 수 있었다.
필자가 초기 PR을 올리면 항상 리뷰로 많은 피드백을 사수들께서 해주셨다. 그 중에서 컴포넌트의 추상화 수준에 대한 피드백을 들을 수 있었다. ‘좋은 코드는 추상화를 잘해서 모두가 읽었을 때, 한번에 이해할 수 있을 정도로 하는 것이 best case이다. 컴포넌트를 어디까지 추상화해서 재사용할 수 있게 할 수 있을 것일까요?’ 와 같은 의견과 질문을 받을 수 있었다. 이러한 질문과 의견을 들으면서 내 나름대로의 추상화 기준을 정할 수 있었고 나중에는 좋은 코드를 작성했다는 리뷰를 받을 수 있었다.
아직도 여전히 추상화가 어렵게 느껴지지만 이번 인턴십을 통해 조금이나마 협업 개발자분들의 의견을 듣고 배울 수 있어서 좋았다.
가장 많이 배웠던 부분은 협업이었다. 사이드 프로젝트에서도 협업을 하지만 현업은 실제 돈과 관련된 제품에 대해 협업을 진행하므로 사이드 프로젝트에 비해 느낌이 많이 달랐다. 프론트엔드, 백엔드, 디자이너, 기획자들이 모여 하나의 기능을 기획하고, 문서화하고, 개발하고, QA를 통해 테스트를 하고 최종 릴리즈까지 하나의 사이클을 반복적으로 경험하며 협업에 대해 많은 것을 배울 수 있었다.
디자이너분과의 협업을 할 때, 사용성, 시안과 구현 가능성 등에 대해 의견을 나눌 때 어떻게 하면 상대의 기분을 상하지 않게 하면서 의견을 효과적으로 전달해 설득할 수 있을지 등과 같은 고민을 많이 하였다. 이는 백엔드 개발자와 소통을 할 때도 마찬가지로 고민했다. 이러한 고민을 통해 내 의견을 너무 둘러 말하지는 안되, 의견을 어필할 수 있는 나만의 방법을 조금은 찾을 수 있지 않았을까 싶다. 이전 프로젝트에서는 무조건 상대의 의견을 수용하는 입장이었지만, 인턴십을 하면서는 내 의견을 전부는 아니더라도 일부는 지킬 수 있었던 것 같다. 물론 여전히 협업은 어려운 것 같다 (모두가 행복한 협업을 하는 것이 내가 생각하는 좋은 협업이라고 생각하기에..) 하지만 이번 인턴십을 통해 오랜 시간 협업을 하면서 성장할 수 있지 않았나 싶다.
이외에도 태스크 관리 등 정말 글로는 다 적을 수 없을 정도로 많은 것을 배울 수 있었던 인턴십이었다.
ICT 인턴십을 통해 3 ~ 6월까지 구름에서 인턴 생활을 할 수 있었다. 또한 회사에게 2개월의 연장 제안도 주셔 7~8월에도 인턴십을 진행할 수 있었다.
네부캠을 하면서 만난 분들께서 인턴십은 기회되면 꼭 해보라고 강추하신 이유가 너무 잘 느껴진 경험이었다. 사이드 프로젝트로는 얻지 못하는 너무 값진 경험을 할 수 있어서 좋았다.
필자의 성격 상 기능 구현을 할 때에도 특수한 케이스까지 전부 고려해서 버그를 찾고 해결하려는 성향이 있다. 이 성격 때문에 실제 릴리즈된 서비스에서도 버그를 몇 번 찾았었다. 가끔 퇴근시간이 다 되었을 때, 이렇게 버그를 찾은 적이 몇 번 있었는데 퇴근이 늦더라도 찾은 버그를 함께 해주신 팀원들께 너무 감사했다. 다시 생각해보니깐 진짜 너무 감사했다.
약 6개월동안 좋은 회사에서, 너무 좋은 팀에서, 너무 좋은 선배 개발자 분들과 소중한 경험을 할 수 있어서 너무 행복했다.
대학교로 돌아가 나머지 학업을 마무리하며, 소중했던 경험을 토대로 프론트엔드 개발자로서 열심히 나아가야겠다고 느낀 소중한 6개월이었다. 다들 너무 감사했습니다 !
수고많으셨습니다 영재님~ 👍