1. 동기와 비동기를 비교하여 설명해주실 수 있을까요?

"동기(synchronous)"와 "비동기(asynchronous)"라는 용어는 컴퓨터 프로그래밍에서 매우 중요한 개념으로, 함수의 호출 방식을 설명하는데 주로 사용됩니다.

  • 동기(synchronous) 방식은 호출된 함수의 결과를 기다리고, 그 함수가 작업을 완료하고 제어를 호출자에게 반환한 후에야 호출자가 다음 작업을 수행할 수 있습니다. 즉, 한 작업이 완료될 때까지 다음 작업이 대기 상태에 있어야 하는 방식입니다.
    예를 들어, 파일을 읽는 동기적인 작업에서는 파일이 완전히 읽히기 전까지 프로그램이 다른 작업을 수행하지 못하고 대기하게 됩니다. 이러한 방식은 구현이 비교적 간단하지만, 대기 시간 동안 프로그램이 멈춰 있어 효율성이 떨어질 수 있습니다.
  • 반면에, 비동기(asynchronous) 방식은 함수를 호출한 후 그 결과를 기다리지 않고 바로 다음 작업을 수행합니다. 호출된 함수는 작업이 완료되면 적절한 방식(예: 콜백 함수, 프로미스, 이벤트 등)으로 호출자에게 작업 완료를 알립니다.
    이 방식은 동시에 여러 작업을 수행할 수 있어 효율성이 높습니다. 그러나 비동기적인 작업의 제어 흐름을 관리하는 것이 복잡하고, 코드를 이해하고 디버깅하기 어려울 수 있습니다.

요약하면동기 방식은 작업의 순서를 보장하며 코드가 단순하고 이해하기 쉬우나대기 시간 동안 다른 작업을 수행할  없어 효율성이 떨어질  있습니다반면비동기 방식은 여러 작업을 동시에 수행할  있어 효율성이 높지만작업의 순서를 보장하기 어렵고 코드가 복잡해질  있습니다.

 

동기는 데이터의 요청과 결과가 한 자리에서 동시에 일어나는것을 말합니다. 사용자가 데이터를 서버에게 요청한다면 그 서버가 데이터 요청에 따른 응답을 사용자에게 다시 리턴해주기 전까지 사용자는 다른 활동을 할 수 없으며 기다려야만합니다. 비동기는 동시에 일어나지 않는다는 의미입니다. 서버에게 데이터를 요청한 후 요청에 따른 응답을 계속 기다리지 않아도되며 다른 외부 활동을 수행하여도되고 서버에게 다른 요청사항을 보내도 상관없습니다.

동기는 순차적으로 작업이 수행될 때 앞의 작업이 수행 중이면 다음 작업은 대기하게 되고, 요청에 대한 값이 반환되기 전까지는 blocking되어 있는 방식을 의미한다. 비동기는 요청에 대한 값이 반환되지 않더라도 non-blocking 상태로 이벤트 큐에 넣거나 백그라운드 스레드에게 해당 task를 위임하고 바로 다음 코드가 진행되는 작업이다.

 

동기는 요청과 그 결과가 동시에 일어나는 것을 의미하므로, 요청을 하면 시간이 얼마나 걸리든, 요청한 자리에서 결과가 주어져야 함을 의미합니다. 비동기는 요청과 그 결과가 동시에 일어나지 않는다는 의미입니다. 동기 방식은 설계가 매우 간단하고 직관적이지만, 결과가 주어질 때까지 아무것도 못하고 대기해야 한다는 단점이 존재하고, 비동기 방식은 동기보다 복잡하지만 결과가 주어지는데 시간이 걸리더라도 그 시간 동안 다른 작업을 함으로써 자원을 효율적으로 사용할 수 있다는 장점이 존재합니다.

 

동기적 처리(Synchronous)는 코드가 위에서부터 아래로 내려오면서 하나가 끝나면 다음 코드가 실행되는 방식을 말한다. 동기는 디자인이 비동기보다 간단하고 직관적이지만 결과가 주어질 때 까지 아무것도 못하고 대기해야하는 문제가 있다 비동기 처리(Asynchronous)는 동기적 코드가 전부 실행 되고나서 값을 반환한다. 비동기는 동기보다 복잡하지만 결과가 주어지는데 시간이 걸려도 그 시간동안 다른 작업을 할 수 있어서 보다 효율적일 수 있다.

 

2. 동기와 비동기의 개념을 설명해주세요.

동기(Synchronous)와 비동기(Asynchronous)는 작업의 실행 방식을 나타내는 개념입니다.

  • 동기(Synchronous) 방식은 한 작업이 완료될 때까지 기다렸다가 다음 작업을 실행하는 방식입니다. 이 방식을 사용하면 실행 순서를 예측하기 쉽지만, 앞의 작업이 끝나기를 기다려야 하기 때문에 시스템의 전체적인 효율이 떨어질 수 있습니다.
  • 비동기(Asynchronous) 방식은 작업이 끝나는 것을 기다리지 않고 다음 작업을 즉시 실행하는 방식입니다. 방식은 여러 작업을 동시에 진행할 있기 때문에 시스템의 효율성을 높일 있습니다. 하지만 작업의 완료 순서를 예측하기 어렵고, 동기 방식보다 복잡한 코드를 작성해야 있습니다.

3. 동기와 비동기 방식의 장단점은 무엇인가요?

동기 방식의 장점:

  1. 설계가 단순하고 이해하기 쉽습니다. 요청과 응답이 순차적으로 이루어지므로, 각 과정을 순서대로 파악하기 쉽습니다.
  2. 데이터의 정합성이 보장됩니다. 요청이 완료될 때까지 다른 작업을 수행하지 않으므로, 동시성 문제를 방지할 수 있습니다.

동기 방식의 단점:

  1. 요청이 완료될 때까지 시스템 자원이 대기 상태로 낭비될 수 있습니다. 이로 인해 전체 시스템의 성능이 저하될 수 있습니다.
  2. 하나의 요청이 지연될 경우 이후의 요청들도 모두 지연되는 병목 현상이 발생할 수 있습니다.

비동기 방식의 장점:

  1. 시스템 자원을 효율적으로 활용할 수 있습니다. 요청이 완료되는 것을 기다리지 않고 다음 작업을 수행할 수 있으므로, 시스템 자원을 놀리지 않고 사용할 수 있습니다.
  2. 여러 요청을 동시에 처리할 수 있으므로, 동기 방식에 비해 빠른 응답 시간을 제공할 수 있습니다.

비동기 방식의 단점:

  1. 설계가 복잡하고 디버깅이 어려울 있습니다. 비동기 방식은 동시에 여러 작업을 처리하므로, 데이터의 동기화 문제나 데드락 같은 동시성 문제가 발생할 가능성이 있습니다.
  2. 요청의 순서가 보장되지 않습니다. 이로 인해 결과가 예측과 다르게 나올 있으며, 이를 관리하기 위한 추가적인 로직이 필요할 있습니다.

4. 동기 방식과 비동기 방식을 사용하면 어떤 상황에서 어떤 차이가 발생하는지 예를 들어 설명해주세요.

동기 방식과 비동기 방식의 차이를 설명하는 가장 간단한 예는 웹서버에 데이터를 요청하는 상황입니다.

  1. 동기 방식의 예:
  2. 웹서버에 데이터를 요청하고, 해당 요청이 완료될 때까지 기다리는 것입니다. 즉, 사용자는 요청한 데이터가 도착하기 전까지는 다른 작업을 수행할 수 없습니다. 예를 들어, 웹 페이지에서 이미지를 로딩하는 동안 사용자는 다른 행동을 할 수 없고, 화면은 멈춘 상태가 됩니다.
  3. 비동기 방식의 예:
  4. 웹서버에 데이터를 요청하고, 요청이 완료되기를 기다리지 않고 바로 다음 작업을 진행하는 것입니다. 즉, 데이터가 도착하면 그때 처리하는 방식입니다. 예를 들어, 웹 페이지에서 이미지를 로딩하는 동안에도 사용자는 다른 작업을 계속 진행할 수 있으며, 이미지는 나중에 도착하면 그때 화면에 표시됩니다.

따라서 동기 방식은 간단하고 순차적인 작업에 적합하며, 비동기 방식은 복잡하고 시간이 걸리는 작업에 적합합니다. 동기 방식은 설계가 간단하지만, 전체 시스템의 효율을 떨어뜨릴 있습니다. 반면 비동기 방식은 설계가 복잡하지만, 시스템의 효율을 높이는 도움이 됩니다.

 

5. 동기적으로 처리해야 하는 작업을 비동기적으로 처리하면 어떤 문제가 발생할 수 있는지 설명해주세요.

동기적으로 처리해야 하는 작업을 비동기적으로 처리하게 되면, 데이터의 일관성과 순서 등이 보장되지 않을 수 있습니다. 이는 특히 작업의 순서가 중요한 경우나 다른 작업의 결과에 의존하는 경우에 문제가 될 수 있습니다.

예를 들어, 사용자 정보를 데이터베이스에 저장하고 바로 그 정보를 이용해 추가적인 작업을 수행하는 경우를 생각해보겠습니다. 만약 이 두 작업이 비동기적으로 처리된다면, 두 번째 작업이 첫 번째 작업이 완료되기 전에 시작될 수 있습니다. 결과적으로는 아직 데이터베이스에 저장되지 않은 사용자 정보를 참조하려는 상황이 발생할 수 있고, 이는 오류를 발생시키거나 부정확한 결과를 초래할 수 있습니다.

따라서 동기적으로 처리되어야 작업을 비동기적으로 처리하면, 의도치 않은 사이드 이펙트를 초래할 있으며, 이는 프로그램의 복잡도를 높이고 버그를 발생시킬 있습니다. 이러한 이유로, 작업의 성격과 요구사항에 따라 동기적인 처리와 비동기적인 처리를 적절하게 선택하고 사용해야 합니다.

 

6. 동기와 비동기 방식의 선택의 기준

  1. 작업의 성격: 작업이 순차적으로 실행되어야 하며 이전 작업의 결과에 다음 작업이 의존하는 경우, 동기 방식이 적합합니다. 반면, 여러 작업이 독립적으로 실행되고, 이들 간에 상호 의존성이 없는 경우 비동기 방식이 적합합니다.
  2. 자원의 효율적 사용: 비동기 방식은 IO-bound 작업(: 네트워크 요청, 디스크에 데이터 쓰기 ) 적합합니다. 이러한 작업은 대기 시간이 긴데, 동기 방식으로 처리하면 대기 시간 동안 CPU 일을 하지 않고 놀게 됩니다. 반면, 비동기 방식으로 처리하면 대기 시간 동안 다른 작업을 수행할 있어 자원을 효율적으로 활용할 있습니다.
  3. 복잡도와 버그: 동기 코드는 순차적으로 실행되기 때문에 이해하고 디버그하기 쉽습니다. 반면, 비동기 코드는 복잡도가 높아져 이해하거나 디버그하기 어려울 있습니다.
  4. 응답 시간과 사용자 경험: 사용자 인터페이스를 다루는 작업의 경우, 작업이 오래 걸리면 사용자 경험에 악영향을 있습니다. 이럴 때는 비동기 방식을 사용해 UI 멈추지 않도록 있습니다.

7. Java에서 동기 및 비동기 처리를 하는 방법

동기 처리:
동기 처리는 기본적으로 코드가 순차적으로 실행되는 방식입니다. 작업이 끝날 때까지 다음 작업은 기다려야 합니다.

void doSomething() {
    task1(); // task1이 완료될 때까지 기다림
    task2(); // task1이 완료되면 task2를 실행
}

비동기 처리:
Java에서 비동기 처리를 하는 방법은 여러 가지가 있습니다.

Thread 사용: Java에서는 Thread 클래스를 사용하여 비동기 처리를 있습니다.

Thread thread = new Thread(() -> {
    // 비동기로 처리할 작업
});
thread.start(); // 새로운 스레드에서 작업을 시작

ExecutorService 사용: ExecutorService 스레드 풀을 관리하는데 사용되며, 작업을 비동기로 실행할 있게 합니다.

ExecutorService executor = Executors.newFixedThreadPool(4); // 4개의 스레드를 가진 스레드풀 생성
executor.submit(() -> {
    // 비동기로 처리할 작업
});

CompletableFuture 사용: CompletableFuture Java 8 도입된 기능으로, 비동기 연산을 표현하고 컴포즈하는 사용됩니다.

CompletableFuture.supplyAsync(() -> {
    // 비동기로 처리할 작업
}).thenAccept(result -> {
    // 작업이 완료된 후 수행할 작업
});

8. 싱글 스레드와 멀티 스레드에서 동기와 비동기 처리 방식이 어떻게 다른지 설명해주세요.

1. 싱글 스레드 환경:

  • 동기 처리: 작업이 순차적으로 실행됩니다. 한 작업이 완료되어야만 다음 작업이 실행될 수 있습니다. 따라서 I/O 작업이나 네트워크 호출 등 블로킹 작업이 일어나면, 그 작업이 완료될 때까지 프로그램 전체가 대기 상태에 빠질 수 있습니다.
  • 비동기 처리: 비동기 처리를 사용하면, 블로킹 작업이 발생하더라도 해당 작업을 기다리는 동안 다른 작업을 실행할 수 있습니다. 블로킹 작업이 완료되면 콜백 함수를 통해 결과를 처리합니다.

2. 멀티 스레드 환경:

  • 동기 처리: 동기 처리 방식은 여전히 한 작업이 완료될 때까지 다음 작업이 기다려야 합니다. 하지만 멀티 스레드 환경에서는 여러 작업을 동시에 실행할 수 있으므로, 한 스레드가 블로킹 작업에 빠져 있더라도 다른 스레드는 계속 작업을 진행할 수 있습니다.
  • 비동기 처리: 스레드는 독립적으로 비동기 작업을 처리할 있습니다. 스레드에서 블로킹 작업이 발생하더라도, 스레드만 대기 상태가 되고, 다른 스레드는 계속해서 작업을 진행할 있습니다. 또한, 비동기 처리 방식을 사용하면, 블로킹 작업이 완료되는 시점에 콜백 함수를 통해 결과를 처리할 있습니다.

9. 비동기 프로그래밍을 구현할 때 어떤 문제점을 경험했고, 어떻게 해결했는지 설명해주세요.

1. Race Condition

비동기 프로그래밍에서 여러 스레드가 동시에 데이터에 접근하게 되면, 데이터의 일관성이 깨질 수 있는데 이를 '경쟁 상태(Race Condition)'라고 합니다.

해결방법: 이를 해결하기 위해 동기화(synchronization) 메커니즘이나 락(locking) 기법 등을 사용할 수 있습니다. 예를 들어, 자바에서는 synchronized 키워드를 이용해 특정 부분의 코드에 대한 동시 접근을 제한할 수 있습니다.

2. Deadlock

두 개 이상의 프로세스나 스레드가 서로 상대방의 작업이 끝나기만을 기다리고 있어 결과적으로 아무것도 완료되지 못하는 상태를 '데드락(Deadlock)'이라고 합니다.

해결방법: 데드락을 피하는 방법 중 하나는 자원에 대한 접근 순서를 정해주는 것입니다. 또는 '락 타임아웃'을 설정하여 일정 시간이 지나면 자동으로 락이 해제되게 하는 방법도 있습니다.

3. Callback Hell

비동기 프로그래밍에서 콜백 함수를 너무 많이 사용하면 코드의 가독성이 떨어지는 문제가 발생하는데 이를 '콜백 지옥(Callback Hell)'이라고 합니다.

해결방법: 자바 8부터 지원하는 CompletableFuture 연속적인 비동기 작업을 간결하게 표현할 있게 도와줍니다. 또는 함수형 프로그래밍 패러다임을 이용하면 콜백 지옥 문제를 해결할 있습니다.

 

10. 프로젝트에서 어떤 기능을 구현하면서 동기와 비동기 방식 중 어느 것을 선택했는지, 그 이유는 무엇인지 설명해주세요.

스프링 부트 프로젝트에서는 HTTP 요청을 처리하는 웹 애플리케이션을 개발하였습니다. 사용자의 요청을 처리하는 동안, 서버는 여러 외부 서비스에 데이터를 요청하거나 보내야하는 상황이 있었습니다. 이 경우, 동기적 방식으로 구현하면 사용자의 요청을 처리하는 동안 외부 서비스에 대한 요청을 기다려야하기 때문에 전체적인 응답 시간이 증가하게 됩니다.

따라서 이러한 상황에서는 비동기 방식을 선택했습니다. 외부 서비스로의 요청을 비동기적으로 처리하면, 서버는 다른 작업을 계속 처리할 수 있으며, 외부 서비스의 응답을 기다리는 동안 사용자의 요청을 더 빨리 처리할 수 있습니다.

Java에서는 CompletableFuture를 이용하여 비동기 처리를 할 수 있으며, 스프링에서는 @Async 어노테이션을 사용하여 비동기 메서드를 쉽게 구현할 수 있습니다. 이렇게 비동기적으로 처리하면 서버의 자원을 효율적으로 활용하면서 동시에 여러 요청을 빠르게 처리할 수 있습니다.

그러나, 모든 요청이 비동기적으로 처리되어야 하는 것은 아닙니다. 일부 요청에서는 외부 서비스로부터의 응답을 받아야 다음 작업을 수행할 있는 경우가 있을 있습니다. 이러한 경우에는 동기적 방식을 선택하여 요청과 응답이 순차적으로 이루어지도록 필요가 있습니다. 이처럼 동기와 비동기 방식의 선택은 구현하려는 기능의 특성과 요구사항에 따라 달라집니다.

 

11. 이벤트 루프(Event Loop)와 이벤트 드리븐(Event-Driven) 프로그래밍에 대해 설명해주세요.

12. Promise나 Async/Await와 같은 비동기 처리 패턴에 대해 설명해주세요