지피티에게 나의 실력을 객관적으로 평가해달라고 부탁했다.
그동안 너와 내가 상호작용하면서 내가 작성했던 모든 코드들의 대해서 평가해줄래? 이 채팅에 한해서가 아니라, 다른 모든 채팅에 대해서도 포함해줘. 내가 주로 작성한 언어는 리액트 타입스크립트이고, 어떤 수준의 레벨로 평가될 수 있는지를 냉정하게 이야기 해줘. 그리고 어떤 회사에 지원하는 레벨로 환상했을 때는 결격 사유가 될 수 있는지 알려줘.
결과는 충격적이었다. 평소에 하던 질문에서는 잘 답변해주지 않았던 객관적인 평가가 답변으로 돌아왔다.
나 스스로 알고도 모른척 했던 부분이나 심지어 이런 게 있는 줄도 모르는 지식들로 피드백해주었다.
피드백 내용으로는 다음과 같았다.
- 제네릭 default / skipped parameter, 조건부 타입 등 고급 타입 설계 경험이 드묾
- (TS를 사용 중이지만 실제로는 원시 타입만 명시를 해두고, 제네릭을 잘 사용하지는 못했다고 생각했다..)
- props drilling 최소화를 위한 Context·Provider 패턴 이해는 있지만 실제 코드에 불필요한 재렌더 발생
• A11y 속성 누락 잦음- (스읍.. 렌더링은 엄청 예민하게 관리하는데 그런적이 있었다고..?)
- 글로벌 캐시 → 로컬 스토어 sync 플로우 문서화 부족
• Observer pattern·Immutable data 이해는 있으나 실코드에 얽힌 메모리·성능 분석 부족- (인정. 뭔지는 알지만 실제 코드에 적용 해본 적 없음..)
- CI 단계별 캐싱·병렬화·테스트 분리 미흡
• 환경변수·시크릿 관리 실수(키 노출 우려 질문 다수)- (인정)
- 이미지 aliasing·scrollbar‑gutter 등 세밀 조정 질문에서 드러난 CSS 렌더링 엔진 이해 부족
- (인정)
- React‑Testing‑Library·Vitest 등 자동 테스트 빈도 낮음
- 진짜인정
- 광범위한 실험 후 정리·회고 문서 부족—팀 협업 시 지식 공유가 힘들 수 있음
- ...
엄청난 피드백으로 너덜너덜해졌다. 이 피드백을 바탕으로 로드맵을 구성해달라고 했다.
- Advanced TypeScript
- 조건부 타입·템플릿 리터럴 타입·Mapped Types로 utility‑first 라이브러리 하나 작성 → GitHub 포트폴리오.
- 테스트 퍼스트
- Storybook + Testing Library + Playwright 세트를 repo template로 고정.
- React‑Query 캐싱·Zustand selector 로직에 대한 unit test 작성.
- Performance & A11y
- Lighthouse + Web Vitals CI 통합.
- React Profiler API로 실제 프로젝트의 hydration 비용 / 렌더 매트릭스 기록.
- Design System & DX
- shadcn/ui fork → 자체 토큰·lint‑rule·Plop generator 적용, 팀 내 패키지로 배포.
- 문서화 습관
- RFC style 기술 제안 + ADR(Architectural Decision Record) 도입.
- PR Description 템플릿에 Problem → Context → Decision → Result 자동 삽입.
- 시큐어 DevOps
- SOPS·AWS Parameter Store 등으로 시크릿 관리.
- GitHub Actions OIDC·Least‑Privilege IAM Role 정립.
- System Design 인터뷰 준비
- TinyURL, file‑upload, real‑time chat 등 “FE <‑> BE” 전체 흐름을 화이트보드식으로 설계 + 문제점 보완 발표 연습.
1. Advanced TypeScript: 보이지 않는 스펙의 틈새
흔히 나오는 코드 냄새 왜 위험한가 구체적 개선 포인트
제네릭 기본값·스킵 불가 <T,U,V,W = any>() 처럼 마지막 파라미터에만 default |
인덱스 시그니처·Partial 지원형이 서로 엇갈리면서 “타입 지옥” 발생. 중간 파라미터를 건너뛰면 결국 any 전파 | Tuple‑style overloading 연구 → ts type Fn<T,U=void,V=void,W=void>=… 또는 REST 튜플 <T extends any[]>(…args:T)로 “hole‑skipping” 해결 |
유니온 분산 제어 미흡 T extends string ? … |
분산 조건부 타입은 유니온마다 독립평가→ 폭발적 타입 확장 | never 흡수 템플릿 패턴 사용: type NonNever<T>=T extends never? never:T |
any vs unknown 오용 | 테스트에서 무심코 any → 실제 코드에서 타입 safety 붕괴 | tsconfig strict + no‑unsafe‑assignment 룰 켜고 실배포에 unknown 사용 후 좁히기 |
매핑 · 템플릿 리터럴 타입 불사용 | 중복 인터페이스 확산 → 유지보수 비용 증가 | as const + keyof typeof 패턴 익히고, 템플릿 ${T & string}-error 활용 |
2. 컴포넌트 설계 & Re‑Render 제어
관찰된 문제 원인 · 징후 심층 피드백
Prop Drilling으로 3‑4단계 전달 | Context API 회피, 혹은 component co-location 전략 부재 | Smart vs Dumb 분리·Context Split 전략(읽기 전용/변경 전용) 도입. 불변 객체라도 referential equality 깨트리면 re‑render 유발 → useMemo/Selector 패턴 요구 |
불필요한 useCallback | 의존 배열에 상태 x —> stale closure 우려로 무조건 래핑 | 비용: 함수 객체 메모리·GC 부담 > 빈도 고려. “결국 memo 일관성이 더 중요하다” → Why Did You Render로 비용 vs 효과 계측 |
A11y 속성 누락 | 디자인 우선 구현 → aria-* 후순위 | Lighthouse a11y < 90 일 때 PR 머지 차단 규칙 권장. 키보드 포커스 실증(tabindex, focus-visible) |
3. 상태 관리 & 캐싱 전략
취약 지점 심층 설명 개선 레시피
React‑Query ↔ Zustand Sync 시 흐름 정리X | 캐시→스토어→UI 흐름을 문서화 안 하면 race condition, stale value | queryClient.subscribe 내부에 setState 두면 렌더 폭발. 대신 Selector+Shallow로 제한, “store migrates to server” 패턴(React‑Query만 source of truth) 검토 |
Observer 패턴 구현 시 메모리 누수 | WeakMap 키 누락 확인 용도 로그 부재 | 컴포넌트 unmount 시 unsubscribe 강제; jest heap‑snapshot으로 leak 검증 |
대형 리스트 렌더 성능 | 5천 개 map loop → Paint jank | react‑window + Suspense 또는 requestIdleCallback prefetch 기술 |
4. Build · CI/CD Tooling
문제 상황 심층 원인 개선 방향
GH Actions 캐시 miss → 5 분+ Yarn install | Node 버전별 캐시 키 strategy 미정 | actions/setup‑node@v4 cache: yarn + --immutable lockfile ⇒ 설치 30s 내 |
시크릿 노출 우려 | .env 텍스트 질문 빈번 | OIDC AssumeRole + SOPS AES‑256 → repo 엔 plaintext 부재. PR diff에서 leak scanner (gitleaks‑action) |
빌드 산출물 크기 편차 | 배포 아티팩트 diff 추적X | size‑limit + PR 댓글 bot → ±5 KB 초과시 경고 |
5. CSS & Rendering Deep Dive
발견된 이슈 근본 이유 전문가 팁
이미지 자글거림 | object-fit + SDL 비일치, image-rendering 속성 미활용 | 1) SVG 라운드트립 → Raster 2× export, 2) image-set() 브라우저별 해상도 대응 |
Scroll gutter · overscroll 작동 예상외 | Chrome & Firefox 벤더 차이, contain: size 영향 | MDN Layout NG 문서 참고→ scrollbar-gutter: stable both-edges + overflow: clip fallback |
Tailwind 클래식 남용 | Atomic 장점↑ vs Debug cost↑ | Tailwind @apply + Design Token 변수화로 추상화 레이어 추가 |
6. Testing & Quality Debt
현실 면접에서 어떻게 보이나 구체적 교정
E2E 부재 | “실제 사용자 시나리오 검증 불충분” → B급 코드 인상 | 최소 Critical Path (로그인, CRUD) 3개 Playwright 스크립트 배치 |
Coverage < 30 % | 큰 조직은 60 ~ 80% cut line | 단순 render test 지양 → behavior test (role, keyboard interaction). 빈 hook는 react-hooks-testing-library |
Mock server‑latency 미고려 | Stale store 이슈 재현 안 됨 | msw + ctx.delay 2 s 시뮬레이션으로 Suspense fallback·race test |
7. Documentation · Collaboration
적발된 허점 면접관 포착 포인트실전 팁
RFC/ADR 부재 | “팀 내 의사결정 공유 문화가 없나?” | 작은 것도 docs/adr/0001‑state‑library.md 채택 → 템플릿 자동화 |
커밋 로그 흐름 불일관 | Conventional Commits 규칙 안 지키면 릴리즈 노트 자동화 실패 | semantic‑release 연동 후 스쿼시 대신 rebase‑merge 유지 |
PR Review 대응 로그 없음 | 피드백 루프 → 성장 곡선 근거 | Before / After Screenshot, Benchmark diff 포함한 follow‑up commit 필수 |
8. Secure Coding & Runtime Hardening
현상 리스크 개선책
JWT 로컬스토리지 보관 | XSS = 계정 탈취 즉시 | HTTP‑only SameSite refresh + in‑memory access token 재발급 패턴 |
API Key 질문 빈번 | 비밀 관리 경험 부족 감지 | Public/Private repo flag 구분, .npmrc //registry.npmjs.org/:_authToken=${TOKEN} 암호화 예제 숙지 |
CSP 헤더 설정無 | 주니어 프로젝트 common | Helmet 미들웨어 기본값 + script-src 'self' 'sha256‑…' 보고서 작성 |
오늘부터 각각의 파트가 굵직해서 얼마나 걸릴지 모르겠지만 꾸준히 파봐야겠다.