본문 바로가기
게임서버-스파르타코딩NodeJs_7기/모의면접

면접카타 7,8 - 깊은 복사 & 얕은 복사, JWT

by GREEN나무 2025. 2. 13.
728x90

7.  깊은 복사와 얕은 복사의 차이는 무엇이고 JS에서 각각을 구현하는 방법은 어떻게 되는지 설명해주세요.

 

🔍 깊은 복사(Deep Copy) vs 얕은 복사(Shallow Copy)

✅ 개념 정리

  • 얕은 복사(Shallow Copy): 객체의 참조 값만 복사하여 원본과 복사본이 동일한 메모리 주소를 공유함.
  • 깊은 복사(Deep Copy): 객체의 모든 속성을 새로운 메모리 공간에 복사하여 원본과 독립적인 객체를 생성함.

🛠 JavaScript에서 구현 방법

✏️ 얕은 복사(Shallow Copy)

✔️ 대표적인 얕은 복사 방법

  • Object.assign()
  • 전개 연산자 { ...obj }
  • Array.prototype.slice() (배열 복사)
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };

shallowCopy.b.c = 99;
console.log(obj.b.c); // 99 (원본도 변경됨)

문제점: 중첩 객체(내부 객체)의 변경이 원본에도 영향을 미침.


✏️ 깊은 복사(Deep Copy)

✔️ 대표적인 깊은 복사 방법

방법 장점 단점
JSON.parse(JSON.stringify(obj)) 간단하고 빠름 undefined, Symbol, Function 미포함
structuredClone(obj) 최신 브라우저 지원, Map, Set도 복사 가능 브라우저 최신 버전에서만 가능
lodash.cloneDeep() 모든 데이터 타입 완벽 지원 외부 라이브러리 필요
재귀 함수 직접 구현 가능, 순환 참조 해결 가능 코드가 길어질 수 있음
Object.create() + Object.assign() 프로토타입 유지 가능 중첩 객체는 복사 안됨

 


🎯 추천 사용 시나리오

사용 상황 추천 방법
단순 객체 복사 (JSON 변환 가능) JSON.parse(JSON.stringify(obj))
브라우저 환경에서 최신 기능 활용 structuredClone(obj)
Node.js / 브라우저에서 완전한 복사 lodash.cloneDeep()
순환 참조 및 특정 데이터 타입 직접 관리 재귀 함수 구현
프로토타입 유지 필요 Object.create() + Object.assign()

💡 깊은 복사(Deep Copy) 방법 및 코드 예제

1️⃣ JSON 방식 (간단하지만 일부 데이터 손실 가능)

const obj = { a: 1, b: { c: 2 } };

const deepCopy = JSON.parse(JSON.stringify(obj));

deepCopy.b.c = 99;
console.log(obj.b.c); // 2 (원본 유지)

✅ 장점: 간단함
❌ 단점: undefined, Symbol, Function 미포함, 순환 참조 불가능


2️⃣ structuredClone(obj) (최신 브라우저 지원)

const obj = { a: 1, b: { c: 2 }, d: new Date(), e: [1, 2, 3] };

const deepCopy = structuredClone(obj);

deepCopy.b.c = 99;
console.log(obj.b.c); // 2 (원본 유지)

✅ 장점: 최신 브라우저에서 안정적 사용 가능
❌ 단점: Node.js에서는 기본적으로 지원 안 됨


3️⃣ lodash.cloneDeep() (완벽한 깊은 복사)

const _ = require('lodash');

const obj = { a: 1, b: { c: 2 }, d: function () { return 42; } };

const deepCopy = _.cloneDeep(obj);

deepCopy.b.c = 99;
console.log(obj.b.c); // 2 (원본 유지)
console.log(typeof deepCopy.d); // "function" (함수도 복사됨)

✅ 장점: 모든 데이터 타입 복사 가능
❌ 단점: lodash 라이브러리 설치 필요 (npm install lodash


4️⃣ 재귀 함수 (순환 참조 해결 가능)

function deepClone(obj, hash = new WeakMap()) {
    if (obj === null || typeof obj !== 'object') return obj; // 원시 값 반환

    if (hash.has(obj)) return hash.get(obj); // 순환 참조 방지

    const copy = Array.isArray(obj) ? [] : {};
    hash.set(obj, copy);

    for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
            copy[key] = deepClone(obj[key], hash); // 재귀 호출
        }
    }

    return copy;
}

const obj = { a: 1, b: { c: 2 }, d: [1, 2, { e: 3 }] };

const deepCopy = deepClone(obj);

deepCopy.b.c = 99;
console.log(obj.b.c); // 2 (원본 유지)

✅ 장점: 직접 구현 가능, 순환 참조 문제 해결 가능
❌ 단점: 코드가 길어질 수 있음


5️⃣ Object.create() + Object.assign() (프로토타입 유지)

function deepCloneWithPrototype(obj) {
    if (obj === null || typeof obj !== 'object') return obj;

    const copy = Object.create(Object.getPrototypeOf(obj));
    Object.assign(copy, obj);

    return copy;
}

const obj = new Date();
const deepCopy = deepCloneWithPrototype(obj);

console.log(deepCopy instanceof Date); // true

✅ 장점: 프로토타입 유지 가능
❌ 단점: 중첩 객체는 완전한 깊은 복사가 안 됨


🚀 결론

방법 추천 상황
JSON.parse(JSON.stringify(obj)) 가장 간단한 방법
lodash.cloneDeep() 가장 강력한 방법
structuredClone() 최신 브라우저에서 사용 가능
재귀 함수 가장 커스텀 가능한 방법

꼬리 질문 (Follow-up Questions)

  1. 얕은 복사가 위험한 상황은?
    • 원본 객체가 중첩된 객체(중첩 배열 포함)를 가질 경우, 얕은 복사를 하면 내부 객체의 변경이 원본에도 영향을 줌.
  2. JSON.stringify() 방식의 깊은 복사 단점?
    • undefined, Symbol, Function은 무시됨.
    • 순환 참조(Circular Reference)가 있으면 오류 발생.
  3. 객체 순환 참조가 있는 경우 깊은 복사하는 방법은?
    • lodash.cloneDeep()
    • structuredClone()
    • 재귀적으로 객체 복사하는 커스텀 함수 작성

8. JWT에 대해 설명해주세요. 구체적으로 JWT를 어디서 처리하는지, 어떠한 방식으로 검증하는지, 재발급 방식과 주기는 어떻게 처리하는지, 다른 API 서비스 호출 시 어떻게 잡아서 인증 처리하는지 말씀해주세요.

🛡️ JWT (JSON Web Token)

✅ JWT란?

  • 사용자의 인증 정보를 포함하는 토큰 기반 인증 방식.
  • JSON 포맷으로 Base64Url로 인코딩되어 전송됨.
  • Stateless(상태 비저장) 방식이므로 세션 저장소가 필요 없음.
  • 구성 요소: Header + Payload + Signature
    • Header: 토큰 유형과 해싱 알고리즘 (HS256, RS256 등)
    • Payload: 사용자 정보 (sub, role, exp 등)
    • Signature: 비밀키를 사용해 생성된 서명 (위변조 방지)

✅ JWT 처리 방식

📌 JWT 발급 과정

const jwt = require('jsonwebtoken');

const payload = { userId: 123, role: 'admin' };
const secretKey = 'your-secret-key';

// JWT 생성 (15분 유효기간)
const token = jwt.sign(payload, secretKey, { expiresIn: '15m' });

console.log(token);

✔️ 서버에서 로그인 성공 시 비밀키(Secret Key) 를 사용해 Access Token을 생성하여 클라이언트에 전달.
✔️ 발급된 JWT 를 클라이언트는 localStorage, sessionStorage, HttpOnly Cookie 등에 저장 가능.


📌 JWT 검증 과정

try {
    const decoded = jwt.verify(token, secretKey);
    console.log(decoded); // { userId: 123, role: 'admin', iat: ..., exp: ... }
} catch (error) {
    console.log('Invalid token');
}

✔️ 서버는 클라이언트가 보낸 JWT를 비밀키로 검증하여 유효한지 확인.

          Authorization: Bearer <JWT>형태로 헤더에 포함되어 요청
✔️ 만료된 경우 Refresh Token을 통해 재발급.


🔄 JWT 재발급 방식과 주기

토큰 종류 유효 기간 설명
Access Token 15~30분 API 호출 시 사용, 짧은 유효기간
Refresh Token 7~30일 Access Token이 만료되면 새로운 토큰 발급
// Refresh Token을 사용해 Access Token 재발급
const newAccessToken = jwt.sign({ userId: 123 }, secretKey, { expiresIn: '15m' });

✔️ Access Token이 만료되면 Refresh Token을 검증하여 새로운 Access Token을 발급.
✔️ Refresh Token도 만료되면 재로그인 필요.

 


🔗 다른 API 서비스 호출 시 인증 처리

✔️  마이크로서비스 환경에서는 API Gateway를 통해 JWT를 검증
✔️  각 서비스는 JWT 내 정보를 활용하여 요청을 처리
✔️  서명 검증을 위해 공개 키(Public Key)를 사용하여 검증 가능 (RS256)


🚀 결론

  • 간단한 깊은 복사 → JSON.parse(JSON.stringify(obj))
  • 완벽한 깊은 복사 → lodash.cloneDeep()
  • 최신 브라우저 지원 깊은 복사 → structuredClone()
  • 커스텀 깊은 복사 → 직접 재귀 함수 구현
  • JWT는 세션보다 확장성이 뛰어난 인증 방식
  • Access Token은 짧게, Refresh Token은 길게 설정하여 보안 강화

꼬리 질문 (Follow-up Questions)

  1. JWT를 세션 방식과 비교하면 어떤 장단점이 있는가?
    • 장점: 상태를 서버에 저장할 필요 없음(Stateless), 확장성이 좋음
    • 단점: 크기가 커서 네트워크 부하가 있을 수 있음, 토큰 탈취 시 보안 위험
  2. JWT가 탈취되었을 때 어떻게 대처할 수 있는가?
    • Refresh Token을 짧게 설정하고, 중요 요청에는 추가 보안 체크
    • 탈취된 토큰을 차단하는 블랙리스트 관리
  3. JWT의 서명을 검증하지 않으면 어떤 문제가 발생하는가?
    • 악의적인 사용자가 조작된 토큰을 서버로 보내면 검증 없이 무단 접근 가능
    • 따라서 서명 검증이 필수
  4. JWT를 안전하게 저장하는 방법은?
    • HttpOnly 쿠키 사용 (XSS 방지)
    • localStorage에 저장하면 XSS 공격에 취약

 참고

7. 얕은 복사(Shallow Copy) vs 깊은 복사(Deep Copy)

https://velog.io/@kbs2082/JS%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%ACShallow-Copy-vs-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%ACDeep-Copy

Shallow copy : 

- https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy

Deep copy :

https://developer.mozilla.org/en-US/docs/Glossary/Deep_copy

 

8. JWT : https://jwt.io/

- https://blog.bizspring.co.kr/%ED%85%8C%ED%81%AC/jwt-json-web-token-%EA%B5%AC%EC%A1%B0-%EC%82%AC%EC%9A%A9/