개발자 면접 노트

동기(Synchronous)와 비동기(Asynchronous)의 차이점

해로몬 2025. 6. 24. 21:49

✅ 동기(Synchronous)란?

작업이 순차적으로 진행되며, 하나의 작업이 완료되기 전에는 다음 작업으로 넘어가지 않습니다.

예시

A 작업이 끝나야만 B 작업을 시작할 수 있는 구조입니다.

주요 특징

  • 순차적 실행: 하나의 작업이 끝나야 다음 작업으로 진행됨
  • 직관적인 흐름: 코드 흐름이 간단하고 이해하기 쉬움
  • 성능 저하 가능성: 시간이 오래 걸리는 작업이 전체 흐름을 지연시킬 수 있음

언제 사용하면 좋을까?

  • 작업의 순서가 중요한 경우
  • 이전 작업의 결과가 바로 다음 작업에 필요할 때
  • 간단한 스크립트나 소규모 프로그램에 적합

✅ 비동기(Asynchronous)란?

작업이 서로 독립적으로 실행되며, 하나의 작업이 끝나기를 기다리지 않고 다음 작업을 수행할 수 있는 방식입니다.

예시

A 작업이 완료되기를 기다리는 동안 B 작업도 같이 수행됩니다.

주요 특징

  • 병렬적인 작업 처리 가능
  • 대기 시간 최소화: 사용자가 느끼는 응답 속도가 빨라짐
  • 복잡한 구조: 콜백, 프로미스, 예외 처리 등으로 코드가 복잡해질 수 있음

언제 사용하면 좋을까?

  • 네트워크 요청, 파일 읽기/쓰기 등 시간이 오래 걸리는 작업
  • 여러 작업을 동시에 처리해야 할 때
  • UI 응답성을 유지해야 할 때
  • 대규모 트래픽을 처리하는 서버 애플리케이션

🔁 주요 비동기 프로그래밍 패턴

1. Callback

작업 완료 시 특정 함수를 호출하는 방식

  • 장점: 간단한 구조
  • 단점: 콜백 지옥(Callback Hell) 발생 가능
function getData(callback) {
  setTimeout(() => {
    const data = "데이터";
    console.log("1. 데이터를 가져왔습니다.");
    callback(data);
  }, 1000);
}

function processData(data, callback) {
  setTimeout(() => {
    const processed = data + " → 처리됨";
    console.log("2. 데이터를 처리했습니다.");
    callback(processed);
  }, 1000);
}

function displayResult(result) {
  console.log("3. 결과:", result);
}

// 실행
getData(function(data) {
  processData(data, function(result) {
    displayResult(result);
  });
});

--------------------------------
(1초 후) 1. 데이터를 가져왔습니다.  
(1초 후) 2. 데이터를 처리했습니다.  
        3. 결과: 데이터 → 처리됨

🧩 설명

  1. getData() → 1초 후 "데이터" 반환
  2. 반환된 데이터를 processData()로 넘김
  3. 처리된 결과를 displayResult()에서 출력

2. Promise / Future

작업의 성공/실패 결과를 약속하는 객체를 사용하여 흐름 제어

  • 장점: 체이닝(Chaining) 으로 가독성 향상
  • 단점: 예외 처리가 복잡할 수 있음
function getData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("데이터");
        }, 1000);
    });
}

getData()
    .then(data => console.log(data))
    .catch(error => console.error(error));

🧩 설명

  • getData()는 1초 후 "데이터"를 반환하는 비동기 함수
  • .then() 안의 콜백은 작업이 성공(resolve) 되었을 때 실행됩니다.
  • .catch()는 작업이 실패(reject) 했을 때 에러를 처리합니다.

3. Async / Await

비동기 코드를 동기 코드처럼 작성할 수 있게 해주는 문법

  • 장점: 가독성 좋고 직관적
  • 단점: 구형 환경이나 일부 언어에서는 지원하지 않을 수 있음
async function main() {
  try {
    const data = await getData();
    const processed = await processData(data);
    displayResult(processed);
  } catch (error) {
    console.error("에러 발생:", error);
  }
}

main();

⚠️ 비동기 프로그래밍 시 주의할 점

  1. 동시성 문제(Concurrency)
    • 여러 작업이 동시에 실행되면서 예상치 못한 결과가 발생할 수 있음
  2. 복잡한 흐름 제어
    • 예외 처리, 상태 관리가 까다로울 수 있음
  3. 과도한 사용은 오히려 성능 저하
    • 필요하지 않은 곳에 비동기를 사용하면 오히려 디버깅이 어려워지고 CPU 리소스 낭비
  4. 블로킹 코드 주의
    • 비동기 흐름 중 동기 함수가 전체 흐름을 막는 경우 있음

 

항목 동기(Synchronous) 비동기(Asynchronous)
실행 방식 순차적 병렬 가능
코드 흐름 단순, 직관적 복잡하지만 유연
성능 작업 지연 시 전체 지연 작업 병렬 처리로 성능 향상
적합한 상황 작업 순서 중요, 단순한 로직 I/O, 대기 많은 작업, 대규모 처리 필요