취업준비생 개발자를 위한 실전 기술면접 질문 & 답변 총정리
React, JavaScript, 최적화, 비동기까지 한 번에!
🤔 면접관 질문: "React의 상태 관리 방법 중 useState와 useReducer의 차이점은 무엇인가요?"
💡 핵심 답변:
// useState: 간단한 상태
const [count, setCount] = useState(0);
// useReducer: 복잡한 상태 흐름
const [state, dispatch] = useReducer(reducer, initialState);
💼 실무 경험 포인트:
"저는 단순한 input은 useState로, API 요청이나 상태 흐름이 있는 UI는 useReducer로 관리합니다. 예를 들어 API 호출 시 loading, data, error를 묶어서 처리할 때 useReducer가 훨씬 직관적이에요!"
🤔 면접관 질문: "JavaScript에서 클로저란 무엇인가요? 어떤 상황에서 유용한가요?"
💡 핵심 답변:
클로저는 함수가 선언될 때의 환경(스코프)을 기억하는 함수예요.
📌 활용 상황:
setTimeout 같은 비동기 코드에서 유용// 클로저 예시: 캡슐화
function createCounter() {
let count = 0; // 외부에서 접근 불가
return function() {
return ++count; // 클로저로 count 기억
};
}
🤔 면접관 질문: "웹 페이지 렌더링 최적화를 위해 어떤 전략을 써본 경험이 있으신가요?"
💡 핵심 답변:
next/image 활용import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
ssr: false, // 클라이언트에서만 로드
loading: () => <div>로딩중...</div>
});
📊 성과 포인트:
"구글 분석에 의하면 페이지 로딩이 1초에서 3초로 느려질 경우 이탈률이 32% 증가해요. 그래서 항상 LCP를 3초 이하로 유지하는 걸 목표로 최적화 작업을 합니다!"
🤔 면접관 질문: "CORS란 무엇이고, CORS 문제가 발생하면 어떻게 해결하나요?"
💡 핵심 답변:
CORS는 Cross-Origin Resource Sharing으로, 브라우저가 다른 도메인에서 데이터를 가져오는 걸 기본적으로 막는 보안 정책이에요.
🔧 해결 방법:
1. 서버 측에서 허용 (Access-Control-Allow-Origin)
2. 프록시 서버 만들기 (Glitch, Next API Routes)
// Next.js API Routes로 CORS 우회
export default async function handler(req, res) {
const response = await fetch('외부API주소');
const data = await response.json();
res.json(data);
}
🤔 면접관 질문: "TypeScript를 실제로 사용해본 경험이 있으신가요? 장점과 단점은?"
✅ 장점:
❌ 단점:
🎯 핵심 한줄 요약:
"JS보다 엄격하지만, 안전하고 유지보수가 쉬운 언어예요!"
🤔 면접관 질문: "React.memo, useMemo, useCallback의 차이점은 무엇인가요?"
💡 핵심 답변:
| 훅 | 용도 | 사용 시점 |
|---|---|---|
| React.memo | 컴포넌트 메모이제이션 | props가 안 바뀌는 컴포넌트 |
| useMemo | 값 메모이제이션 | 계산 비용이 큰 연산 결과 |
| useCallback | 함수 메모이제이션 | 자식에 넘기는 함수 최적화 |
⚠️ 주의사항:
"오히려 렌더링보다 캐싱 비용이 더 크면 성능 저하 가능하니까, 꼭 필요한 상황에서만 사용해야 해요!"
🤔 면접관 질문: "이벤트 버블링과 캡처링이란 무엇인가요?"
💡 핵심 답변:
DOM 이벤트는 캡처링(부모→자식) → 타겟 이벤트 → 버블링(자식→부모) 순서로 전파돼요.
// 이벤트 전파 막기
function handleClick(e) {
e.stopPropagation(); // 상위로 이벤트 전파 차단
}
// 캡처링 단계에서 이벤트 감지
element.addEventListener('click', handler, { capture: true });
💼 실무 예시:
"모달 안의 버튼 클릭 시, 배경까지 클릭 이벤트가 전파되는 걸 막을 때
stopPropagation()사용해요!"
🤔 면접관 질문: "REST API와 GraphQL의 차이는 무엇인가요?"
💡 핵심 답변:
💼 선택 기준:
"데이터 구조가 복잡하고 N+1 문제가 많다면 GraphQL, 간단한 CRUD라면 REST가 적합해요!"
🤔 면접관 질문: "callback, promise, async/await의 차이를 설명해주세요."
💡 진화 과정:
getData(function(a) {
getMoreData(a, function(b) {
getMoreData(b, function(c) {
// 콜백 지옥...
});
});
});
getData()
.then(a => getMoreData(a))
.then(b => getMoreData(b))
.catch(error => console.error(error));
async function fetchData() {
try {
const a = await getData();
const b = await getMoreData(a);
return await getMoreData(b);
} catch (error) {
console.error(error);
}
}
🤔 면접관 질문: "컴포넌트 재사용성을 높이기 위한 방법에는 어떤 것이 있나요?"
💡 핵심 전략:
<Input />, <Button /><FormGroup />, <SearchBox /> <Header />, <ProductList />// 재사용 가능한 컴포넌트 예시
function Button({ variant = 'primary', size = 'md', children, ...props }) {
return (
<button
className={`btn btn--${variant} btn--${size}`}
{...props}
>
{children}
</button>
);
}
🔧 추가 기법: