답변: HTTP(Hypertext Transfer Protocol)는 클라이언트와 서버 간의 데이터 교환을 위한 application layer 프로토콜입니다. 주요 특징으로는:
HTTP는 웹 브라우저와 웹 서버 간의 통신뿐만 아니라, RESTful API 등 다양한 네트워크 통신에서 널리 사용됩니다.
답변: 웹소켓은 클라이언트와 서버 간의 실시간, 양방향 통신을 가능하게 하는 프로토콜입니다.
주요 특징은:
1. 양방향 통신: 클라이언트와 서버 모두 언제든 메시지를 보낼 수 있습니다.
2. 실시간 통신: 연결이 유지되므로 지연 시간이 매우 짧습니다.
3. 효율적인 통신: 한 번 연결되면 추가적인 HTTP 요청 없이 데이터를 주고받을 수 있습니다.
HTTP와의 주요 차이점:
답변: Canvas는 HTML5에서 도입된 요소로, JavaScript를 사용하여 그래픽을 그릴 수 있는 영역을 제공합니다. 주요 특징은:
사용 사례:
Canvas는 SVG와 달리 해상도 종속적이며, 스크립트로 모든 그리기 작업을 제어해야 합니다.
이 프로젝트에서는 사용자의 서명을 받기 위해 Canvas를 활용했습니다. react-signature-canvas 라이브러리를 사용하여 서명 기능을 구현했고, Canvas API를 통해 서명 데이터를 이미지로 변환하여 저장하는 기능을 구현했습니다. 이를 통해 사용자가 웹 브라우저에서 직접 서명을 할 수 있고, 그 서명을 이미지로 저장하여 서버로 전송할 수 있게 되었습니다.
답변: 레거시 코드는 오래되고 유지보수가 어려운 코드를 의미합니다.
주요 특징은:
1. 문서화가 부족하거나 없음
2. 현대적인 개발 방식과 맞지 않음
3. 테스트 코드가 없거나 부족함
4. 기술 부채가 높음
레거시 코드를 다룰 때의 접근 방식:
레거시 코드는 완전히 제거하기 어려운 경우가 많으므로, 점진적인 개선과 병행 운영 전략이 중요합니다.
답변: Batching은 여러 작업을 그룹화하여 한 번에 처리하는 기법입니다. 프론트엔드 개발에서는 주로 성능 최적화를 위해 사용됩니다.
주요 특징과 이점:
사용 예:
Batching을 통해 애플리케이션의 반응성을 높이고, 서버 부하를 줄일 수 있습니다. 하지만 실시간성이 중요한 경우에는 신중히 사용해야 합니다.
답변: nvm은 Node.js의 여러 버전을 관리하고 전환할 수 있게 해주는 도구입니다.
주요 기능과 이점은:
사용 예:
nvm install 14.17.0 // 특정 버전 설치
nvm use 14.17.0 // 특정 버전 사용
nvm alias default 14.17.0 // 기본 버전 설정
nvm을 사용하면 여러 프로젝트의 Node.js 버전을 독립적으로 관리할 수 있어, 호환성 문제를 줄이고 개발 환경을 유연하게 관리할 수 있습니다.
답변: 대표적인 Git 브랜치 전략으로 Git Flow를 예로 들 수 있습니다.
Git Flow의 주요 브랜치와 특징은:
장점:
다른 전략으로는 GitHub Flow, GitLab Flow 등이 있습니다. 프로젝트의 규모와 특성에 맞는 전략을 선택하는 것이 중요합니다.
효과적인 브랜치 전략은 코드 품질 유지, 협업 효율성 증대, 빠른 이슈 대응 등에 도움을 줍니다.
답변: 세 가지 모두 클라이언트 측 데이터 저장 방식이지만, 특징과 용도가 다릅니다.
로컬스토리지:
세션스토리지:
쿠키:
주요 차이점:
보안 민감한 정보는 이들 저장소에 저장하지 않는 것이 좋습니다.
답변: SSR과 CSR은 웹 페이지를 렌더링하는 두 가지 주요 방식입니다.
SSR (Server-Side Rendering):
CSR (Client-Side Rendering):
최근에는 두 방식의 장점을 결합한 하이브리드 접근법(예: Next.js의 SSR+CSR)도 많이 사용됩니다. 프로젝트의 요구사항에 따라 적절한 방식을 선택하는 것이 중요합니다.
이 프로젝트는 React를 사용한 CSR 방식으로 구현되어 있습니다.
답변: 단방향 바인딩과 양방향 바인딩은 데이터와 UI 요소를 연결하는 두 가지 방식입니다.
단방향 바인딩:
양방향 바인딩:
선택 기준:
최근 트렌드는 단방향 바인딩을 선호하는 경향이 있으나, 프로젝트의 요구사항에 따라 적절한 방식을 선택해야 합니다.
React를 사용하고 있으므로, 이 프로젝트는 단방향 데이터 바인딩을 사용합니다.
답변: 로그인 페이지 구현 시 고려해야 할 주요 요소들:
서버:
세션:
쿠키:
HTTP 헤더:
JSON:
구현 순서:
1. 클라이언트에서 사용자 입력 받기
2. HTTPS를 통해 서버로 로그인 요청 전송 (JSON 형식)
3. 서버에서 인증 처리 및 세션/토큰 생성
4. 인증 성공 시 세션 ID나 토큰을 클라이언트에 전달
5. 클라이언트에서 received token이나 세션 ID 저장
6. 이후 요청 시 header에 토큰을 포함하여 인증 상태 유지
보안 고려사항:
답변: 네트워크 요청 시 다양한 예외 상황이 발생할 수 있으며, 이에 대한 적절한 처리가 중요합니다.
주요 예외 상황 및 처리 방법:
서버 에러 (500번대):
클라이언트 에러 (400번대):
네트워크 연결 실패:
타임아웃:
CORS 에러:
구현 예시 (using axios):
axios.get('/api/data')
.then(response => {
// 성공적인 응답 처리
})
.catch(error => {
if (error.response) {
// 서버가 2xx 범위를 벗어나는 상태 코드를 반환한 경우
switch(error.response.status) {
case 401:
// 인증 실패 처리
break;
case 404:
// 리소스 없음 처리
break;
// ... 기타 상태 코드 처리
}
} else if (error.request) {
// 요청은 보냈지만 응답을 받지 못한 경우
console.log('네트워크 에러');
} else {
// 요청 설정 중 에러 발생
console.log('요청 설정 에러', error.message);
}
});
전역 에러 핸들러를 설정하여 공통적인 에러 처리 로직을 구현하는 것도 좋은 방법입니다.
src/apis/index.js 파일에서 다음과 같은 네트워크 예외 처리 코드를 볼 수 있습니다:
privateAxios.interceptors.response.use(
response => {
return response;
},
async err => {
if (err.response && err.response.status === 401) {
// 토큰 갱신 로직
}
return Promise.reject(err);
}
);
답변: 프론트엔드 애플리케이션에서 발생할 수 있는 주요 장애 상황과 대처 방안:
서버 다운:
느린 네트워크:
브라우저 호환성 문제:
메모리 누수:
제3자 서비스 장애:
보안 취약점:
대처 전략:
1. 모니터링 시스템 구축: 실시간 에러 추적 및 로깅
2. 그레이스풀 디그레이데이션: 핵심 기능 유지하며 성능 저하
3. 장애 복구 계획 수립: 자동화된 복구 프로세스 구현
4. 사용자 커뮤니케이션: 장애 상황과 예상 복구 시간 안내
5. 캐싱 전략: 중요 데이터의 로컬 캐싱으로 오프라인 지원
6. 코드 스플리팅: 필요한 코드만 로드하여 초기 로딩 시간 단축
예시 코드 (서비스 워커를 이용한 오프라인 지원):
// service-worker.js
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then((response) => {
// 캐시에 있으면 캐시된 응답 반환
if (response) {
return response;
}
// 없으면 네트워크 요청
return fetch(event.request);
})
.catch(() => {
// 오프라인 폴백 페이지
return caches.match('/offline.html');
})
);
});
장애 상황에 대한 체계적인 대비와 신속한 대응은 사용자 경험 향상과 서비스 신뢰도 제고에 중요합니다.
답변: 프론트엔드와 서버 간 효율적인 통신을 위해 고려해야 할 주요 사항들:
RESTful API:
GraphQL:
WebSocket:
데이터 포맷:
인증:
에러 핸들링:
캐싱:
성능 최적화:
CORS 설정:
버전 관리:
예시 코드 (Axios를 사용한 통신):
import axios from 'axios';
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: {'Authorization': `Bearer ${token}`}
});
// GET 요청
api.get('/users')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error fetching users:', error);
});
// POST 요청
api.post('/users', { name: 'John', email: 'john@example.com' })
.then(response => {
console.log('User created:', response.data);
})
.catch(error => {
console.error('Error creating user:', error);
});
이 프로젝트에서는 RESTful API를 사용하여 서버와 통신하고 있습니다.
예를 들어, src/apis/auth.js 파일에서:
export const postLogin = async info => {
const res = await publicAxios.post('/v1/vendor/auth/login', info);
return res;
};
효율적인 서버 통신을 위해서는 적절한 기술 선택, 보안 고려, 성능 최적화, 에러 처리 등을 종합적으로 고려해야 합니다. 또한, 서버 개발자와의 긴밀한 협업을 통해 일관된 인터페이스를 유지하는 것이 중요합니다.