본문 바로가기

웹 개념

[FE & WEB] 웹 개념 - cs, js[질&답식] - [1]

728x90

 

기본적인 개념의에 대한 명칭을 까먹어가지고, 이번 면접에서 아는 개념임에도 불구하고 명칭을 까먹어 버려가지고, 대답을 너무 많이 못했다. 이김에 한 번 싹 정리하고, 면접 보기 전에 한 번 보고 갈려고 정리하고자 한다.


 

1. 질문)  브라우저 주소창에 www.google.com을 입력하면 어떤 일이 일어나나요?

 

1. 답변)

 

브라우저 주소창에 www.google.com을 입력하면 다음과 같은 일련의 과정이 발생합니다:

ㅇ DNS 조회: 브라우저는 입력한 주소인 "www.google.com"을 IP 주소로 변환하기 위해 DNS(Domain Name System) 서버에 쿼리를 보냅니다. DNS는 도메인 이름을 해당 도메인의 IP 주소로 매핑하는 역할을 합니다.


ㅇ IP 주소 얻기: DNS 서버는 "www.google.com"에 해당하는 IP 주소를 찾아서 브라우저에 응답합니다. 이 IP 주소는 일반적으로 Google 서버를 가리키게 됩니다.


ㅇ 서버 연결: 브라우저는 얻은 IP 주소를 사용하여 Google 서버와 TCP/IP 연결을 맺습니다. 이를 통해 브라우저와 Google 서버 간의 통신이 이루어질 수 있게 됩니다.


ㅇ HTTP 요청: 연결이 수립되면, 브라우저는 HTTP 프로토콜을 사용하여 Google 서버에 요청을 보냅니다. 이 요청에는 브라우저가 원하는 페이지의 정보(예: 홈페이지, 검색 결과 등)가 포함됩니다.


ㅇ 서버 응답: Google 서버는 브라우저의 요청을 처리하고, 그에 따른 결과를 HTTP 응답으로 반환합니다.
웹 페이지 표시: 브라우저는 받은 HTTP 응답을 해석하여 웹 페이지를 렌더링하여 사용자에게 표시합니다. Google 홈페이지를 요청했다면, 사용자는 구글의 검색 홈페이지를 볼 수 있게 됩니다.
이렇게 브라우저는 DNS를 통해 도메인 이름을 IP 주소로 변환하고, 해당 IP 주소의 서버와 통신하여 웹 페이지를 요청하고 응답받아 화면에 표시하는 과정을 거치게 됩니다.

 


2. 질문 ) GET과 POST의 차이는 ?

 

2. 답변 ) 

 

GET과 POST는 HTTP 프로토콜에서 사용되는 두 가지 주요한 요청 메서드입니다. 이들은 클라이언트(브라우저)가 서버에 데이터를 보내는 방식에 차이가 있습니다.

GET:
데이터 전송 방식: GET은 요청하는 데이터를 URL의 쿼리 매개변수(query parameter)로 첨부하여 전송합니다. 이 매개변수들은 URL 뒤에 물음표(?)로 구분되며, 각 매개변수들은 '&'로 구분됩니다. 예를 들면, www.example.com/page?name=John&age=30와 같이 전송됩니다.


데이터 보안: GET 요청은 URL에 데이터가 노출되므로 보안에 취약합니다. 또한 URL의 길이 제한이 있어 큰 양의 데이터를 전송하기에 적합하지 않습니다.


캐싱: GET 요청은 서버에서 캐싱할 수 있으며, 같은 요청을 여러 번 보내더라도 결과가 동일하다면 캐시된 응답을 반환할 수 있습니다.


주요 용도: 서버로부터 정보를 요청하거나 조회하는 용도로 주로 사용됩니다.
POST:


데이터 전송 방식: POST는 요청하는 데이터를 HTTP 요청 메시지의 본문(body)에 포함하여 전송합니다. 따라서 데이터는 URL에 노출되지 않으며, 대용량의 데이터를 보내는데 적합합니다.


데이터 보안: POST 요청은 URL에 데이터가 노출되지 않기 때문에 GET보다 보안적으로 더 안전합니다. 그러나 여전히 데이터를 암호화해야하는 중요한 정보를 전송할 때는 HTTPS와 같은 보안 프로토콜을 사용하는 것이 좋습니다.


캐싱: POST 요청은 기본적으로 캐싱되지 않습니다. 서버에 요청이 동일하게 전달되더라도 서버는 매번 요청을 처리합니다.


주요 용도: 서버에 데이터를 제출하거나 업데이트하기 위해 사용됩니다. 로그인 정보, 폼 데이터, 파일 업로드 등에 많이 사용됩니다.


중요한 점은 GET과 POST 요청 모두 서버로 데이터를 보낼 수 있지만, GET은 데이터를 URL에 노출하고 캐싱되기 때문에 보안이나 데이터 길이에 제한이 있는 경우에 적합하지 않을 수 있습니다. 반면에 POST는 데이터를 본문에 담아 보내므로 보안적으로 더 안전하고, 대용량의 데이터를 전송하는 데 적합합니다. 올바른 상황에 맞게 GET과 POST를 사용하는 것이 중요합니다.

 


3. 질문 ) 객체지향 프로그래밍이란?

 

3. 답변 ) 

 

객체지향 프로그래밍(Object-Oriented Programming, OOP)은 소프트웨어 개발 방법론 중 하나로, 프로그램을 객체들의 집합으로서 바라보고 이들 객체들이 상호작용하며 프로그램이 동작하는 것을 중심으로 한다는 개념입니다. 객체는 데이터와 이 데이터를 처리하는 메서드를 포함하는 소프트웨어 개체를 의미합니다. 이러한 개체들은 클래스라는 템플릿을 기반으로 생성됩니다.

객체지향 프로그래밍의 핵심 개념은 다음과 같습니다:

ㅇ 클래스 (Class): 클래스는 객체들을 생성하는 템플릿이며, 객체들이 가지는 속성(데이터)과 메서드(기능)의 집합을 정의합니다. 클래스는 객체를 정의하기 위한 설계도와 같은 역할을 합니다.

ㅇ 객체 (Object): 클래스를 기반으로 실제로 생성된 개체를 말합니다. 객체는 클래스의 인스턴스이며, 클래스에서 정의된 속성과 메서드를 가집니다.

ㅇ 캡슐화 (Encapsulation): 객체지향 프로그래밍은 데이터와 해당 데이터를 처리하는 메서드를 하나로 묶어 캡슐화하는 개념을 갖고 있습니다. 이렇게 하면 데이터의 접근을 제어할 수 있고, 객체 간의 상호작용을 더 쉽게 관리할 수 있습니다.

ㅇ 상속 (Inheritance): 상속은 기존 클래스를 확장하여 새로운 클래스를 만드는 개념입니다. 상속을 통해 코드의 재사용성이 높아지고, 기존 클래스의 기능을 수정하거나 확장할 수 있습니다.

ㅇ 다형성 (Polymorphism): 다형성은 같은 이름의 메서드가 다른 클래스에서 다르게 동작하는 능력을 말합니다. 이를 통해 객체의 타입에 따라 다른 메서드가 호출될 수 있습니다.

객체지향 프로그래밍은 코드의 가독성과 유지보수성을 높이고, 큰 규모의 프로젝트를 보다 구조적으로 개발하는 데 도움이 됩니다. 주요 장점으로는 모듈화와 코드 재사용성이 높아지며, 현실 세계를 모델링하여 개발하는 데 유리한 점이 있습니다. 많은 프로그래밍 언어들이 객체지향 프로그래밍을 지원하고 있으며, 객체지향의 개념을 잘 활용하여 소프트웨어를 개발하는 것이 권장됩니다.

 


4. 질문 ) 프로세스와 스레드에 대해 설명해주세요 ?

 

4. 답변 )

 

프로세스(Process)와 스레드(Thread)는 컴퓨터에서 실행되는 프로그램들의 실행 단위를 나타내는 용어입니다. 각각의 프로세스와 스레드는 독립적으로 실행되며, 각각의 메모리 공간을 할당받습니다.

프로세스(Process):
프로세스는 운영체제로부터 자원을 할당받아 실행 중인 프로그램의 인스턴스입니다. 각각의 프로세스는 독립된 메모리 공간을 할당받으며, 서로 다른 프로세스 간에는 메모리 공간이 격리되어 있습니다. 따라서 하나의 프로세스가 비정상적으로 동작하더라도 다른 프로세스에는 영향을 주지 않습니다. 프로세스는 자체적으로 실행 중인 코드, 데이터, 스택, 힙 등을 포함하고 있으며, 운영체제는 각 프로세스 간의 자원과 데이터 접근을 보호하고 관리합니다.
프로세스는 일반적으로 독립적인 작업을 수행하며, 여러 프로세스들은 IPC(Inter-Process Communication) 메커니즘을 사용하여 데이터를 주고받을 수 있습니다.

스레드(Thread):
스레드는 하나의 프로세스 내에서 실행되는 실행 단위로서, 프로세스의 자원을 공유합니다. 스레드는 동일한 코드와 데이터를 공유하기 때문에 프로세스의 자원에 대한 접근이 빠르고 경제적입니다. 하나의 프로세스는 여러 개의 스레드를 가질 수 있으며, 이러한 스레드들은 프로세스 내에서 서로 다른 작업을 동시에 처리할 수 있습니다.
스레드는 프로세스의 스택 영역을 제외한 나머지 부분을 공유하므로, 하나의 스레드가 메모리를 수정하면 다른 스레드도 해당 변경 사항을 볼 수 있습니다. 이로 인해 스레드 간의 데이터 공유에 주의해야 하며, 동기화(Synchronization) 메커니즘을 사용하여 여러 스레드가 데이터에 동시에 접근하는 것을 제어해야 합니다.

스레드를 사용하면 멀티스레드 프로그램을 구현하여 여러 작업을 동시에 처리할 수 있으며, 이로 인해 성능 향상과 자원 활용에 이점을 얻을 수 있습니다. 하지만 스레드를 다루는 것은 복잡하고 동시성 문제를 주의해야 하는 등의 어려움이 있기 때문에 적절하게 관리해야 합니다.

 


5. 질문 ) rest api에 대해 설명?

 

5. 답변 ) 

 

REST(Representational State Transfer) API는 웹 서비스를 구현하고 통신하기 위한 아키텍처 스타일입니다. REST는 HTTP 프로토콜을 기반으로 하며, 클라이언트와 서버 간의 상태를 표현(Represent)하고 전달(Transfer)하기 위한 방법을 제공합니다. REST API를 통해 클라이언트 애플리케이션은 서버에 데이터를 요청하거나 서버의 동작을 수행할 수 있습니다.

REST API의 주요 특징은 다음과 같습니다:

자원(Resource): REST API에서 모든 것은 리소스(자원)로 표현됩니다. 예를 들어, 웹 서비스에서는 사용자, 상품, 주문과 같은 각각의 엔티티가 자원이 됩니다.

URI(Uniform Resource Identifier): 각 자원은 고유한 식별자인 URI를 갖습니다. 클라이언트는 이 URI를 사용하여 특정 자원을 참조하고 요청합니다. 예를 들어, /users, /products/123 등의 URI를 사용할 수 있습니다.

HTTP 메서드: REST API는 HTTP 메서드를 사용하여 자원에 대한 액션을 정의합니다. 가장 널리 사용되는 메서드는 GET(조회), POST(생성), PUT(수정), DELETE(삭제)입니다.

표현(Representation): 자원의 상태는 텍스트, XML, JSON 등과 같은 표현 형식으로 표현됩니다. 대부분의 경우 JSON 형식이 널리 사용되며, 클라이언트는 원하는 형식으로 자원을 요청할 수 있습니다.

REST API는 간결하고 직관적이며, 잘 디자인된 RESTful API는 쉽게 이해하고 사용할 수 있습니다. 이러한 특성으로 인해 REST API는 인기 있는 웹 서비스를 구축하는데 많이 사용되고 있습니다. 예를 들어, 웹 서비스의 회원 정보를 가져오기 위해 GET /users 요청을 보내거나, 새로운 주문을 생성하기 위해 POST /orders 요청을 보낼 수 있습니다.

또한 REST API는 인터넷의 기본 원칙에 따라 설계되었기 때문에 HTTP 프로토콜의 특성(무상태성, 캐시 기능 등)을 활용하여 네트워크 통신의 성능과 확장성을 개선할 수 있습니다.

 


6. 질문 )  프로미스와 콜백의 차이를 설명?

6. 답변 )

 

프로미스(Promise)와 콜백(Callback)은 비동기 프로그래밍에서 사용되는 패턴입니다. 주요 차이점은 비동기 작업을 다루는 방식과 코드 구조에서 나타납니다.

콜백(Callback):
콜백은 비동기적인 작업이 끝난 후 실행되는 함수를 의미합니다.
비동기 작업이 완료되면, 미리 정의된 콜백 함수가 호출되며 그 결과를 처리합니다.
콜백은 주로 함수의 인자로 전달되어 사용됩니다. 예를 들면, 파일을 읽는 비동기 함수를 호출할 때, 파일 읽기 작업이 완료되면 미리 정의된 콜백 함수가 호출되고, 읽은 데이터를 처리할 수 있습니다.

 

// 콜백 사용 예시
function readFileAsync(filename, callback) {
  // 비동기적으로 파일 읽기 작업을 수행
  // 작업이 완료되면 콜백 함수 호출
  // 읽은 데이터를 콜백으로 전달
}

function processFile(data) {
  // 읽은 데이터를 처리하는 로직
}

readFileAsync('file.txt', processFile);

콜백을 중첩해서 사용하면 콜백 헬(callback hell) 현상이 발생할 수 있어서 가독성이 떨어지고 유지보수가 어려워질 수 있습니다.

 

프로미스(Promise):
프로미스는 비동기 작업의 결과를 나타내는 객체입니다. 비동기 작업이 성공적으로 완료되면 resolve 메서드를 호출하고, 실패하면 reject 메서드를 호출하여 결과를 처리합니다.
프로미스는 비동기 작업을 더 간결하게 표현하고, 콜백 헬을 피할 수 있도록 합니다.
프로미스는 .then() 메서드를 사용하여 성공적인 경우의 동작을 지정하고, .catch() 메서드를 사용하여 실패한 경우의 동작을 지정합니다.

 

// 프로미스 사용 예시
function readFileAsync(filename) {
  return new Promise((resolve, reject) => {
    // 비동기적으로 파일 읽기 작업을 수행
    // 작업이 완료되면 resolve 메서드 호출, 읽은 데이터를 전달
    // 작업이 실패하면 reject 메서드 호출, 에러를 전달
  });
}

function processFile(data) {
  // 읽은 데이터를 처리하는 로직
}

readFileAsync('file.txt')
  .then(processFile)
  .catch((error) => {
    // 에러 처리
  });

프로미스를 사용하면 비동기 작업의 흐름을 보다 직관적으로 표현할 수 있으며, 여러 비동기 작업을 연결하여 순차적으로 처리할 수 있습니다. 또한 async/await와 같은 문법을 활용하면 더욱 가독성이 좋은 코드를 작성할 수 있습니다.

 


7. 질문 ) 호이스팅?

7. 답변 ) 

 

호이스팅(Hoisting)은 JavaScript에서 변수 및 함수 선언문이 해당 스코프의 최상단으로 끌어올려지는 동작을 말합니다. 이러한 동작은 코드의 실행 순서와는 상이하게 작동할 수 있어서 주의가 필요한 개념입니다.

호이스팅은 변수와 함수의 선언문에 적용됩니다.

변수 호이스팅:
변수 선언문(var, let, const)이 해당 스코프 내에서 최상단으로 끌어올려집니다. 하지만 변수의 초기화(값 할당)는 호이스팅되지 않습니다. 따라서 변수 선언은 스코프 상단으로 끌어올려지지만, 할당되기 전까지는 undefined로 초기화됩니다.

 

console.log(x); // undefined (호이스팅 발생)
var x = 10;
console.log(x); // 10 (실제 할당은 이 지점에서 이루어짐)

 

함수 호이스팅:
함수 선언식(Function Declaration)이 해당 스코프 내에서 최상단으로 끌어올려집니다. 함수 표현식(Function Expression)은 호이스팅되지 않습니다.

 

sayHello(); // "Hello!" (호이스팅 발생)

function sayHello() {
  console.log("Hello!");
}

sayHello(); // "Hello!" (실제 함수 호출)

하지만 함수 표현식의 경우, 변수 선언은 호이스팅되지만 함수의 할당은 호이스팅되지 않습니다.

sayHi(); // Error: sayHi is not a function (호이스팅으로 인해 변수 선언은 이루어지지만 함수 할당은 발생하지 않음)

var sayHi = function() {
  console.log("Hi!");
};

sayHi(); // "Hi!" (실제 함수 호출)

호이스팅은 주의해야할 개념이며, 코드를 작성할 때 변수와 함수의 선언을 최상단에 몰아두는 것이 가독성과 코드의 의도를 명확하게 표현하는 데 도움이 됩니다. 최신 버전의 JavaScript에서는 let과 const를 사용하여 블록 스코프를 갖는 변수를 선언하면 호이스팅 문제를 최소화할 수 있습니다.

 


8. 질문) 이벤트 버블링과 캡처링에 대해 설명해주세요.

8. 답변)

 

이벤트 버블링(Event Bubbling)과 이벤트 캡처링(Event Capturing)은 이벤트의 전파 방향과 순서에 대한 개념을 나타냅니다. 이벤트가 발생한 요소에서부터 상위 요소(부모 요소)로 이벤트가 전파되는 것을 이벤트 버블링이라고 하며, 상위 요소에서부터 하위 요소(자식 요소)로 이벤트가 전파되는 것을 이벤트 캡처링이라고 합니다. 따라서 전파되는 과정에 차이가 있습니다.

정확한 설명을 제공하기 위해 이벤트 버블링과 이벤트 캡처링에 대한 개념을 다시 정리하고 설명하겠습니다:

이벤트 캡처링 (Event Capturing):

이벤트가 최상위 요소(document)에서 시작하여 실제 이벤트가 발생한 요소까지 이벤트가 전파됩니다.
이벤트 캡처링 단계에서 등록된 이벤트 핸들러가 먼저 실행됩니다.
이벤트 버블링 (Event Bubbling):

이벤트가 실제 이벤트가 발생한 요소에서부터 시작하여 최상위 요소(document)까지 이벤트가 전파됩니다.
이벤트 버블링 단계에서 등록된 이벤트 핸들러가 먼저 실행됩니다.
즉, 이벤트 전파의 방향이 반대입니다. 이벤트 캡처링은 최상위 요소에서부터 시작해서 이벤트를 발생시킨 요소까지 내려가는 방식이고, 이벤트 버블링은 이벤트를 발생시킨 요소에서부터 시작해서 최상위 요소까지 올라가는 방식입니다. 이 두 개념은 이벤트의 전파 방향을 설명하는 것이며, 이를 활용하여 이벤트 처리를 다양하게 조작할 수 있습니다.

 

<!DOCTYPE html>
<html>
<head>
  <title>Event Bubbling and Capturing Example</title>
</head>
<body>

<div id="outer">
  <div id="middle">
    <div id="inner">Click me!</div>
  </div>
</div>

<script>
const outer = document.getElementById('outer');
const middle = document.getElementById('middle');
const inner = document.getElementById('inner');

function logEvent(phase, elementId) {
  console.log(`${phase}: ${elementId}`);
}

outer.addEventListener('click', () => logEvent('Bubbling', 'outer'));
middle.addEventListener('click', () => logEvent('Bubbling', 'middle'));
inner.addEventListener('click', () => logEvent('Bubbling', 'inner'));

outer.addEventListener('click', () => logEvent('Capturing', 'outer'), true);
middle.addEventListener('click', () => logEvent('Capturing', 'middle'), true);
inner.addEventListener('click', () => logEvent('Capturing', 'inner'), true);
</script>

</body>
</html>

 

Capturing: outer
Capturing: middle
Capturing: inner
Bubbling: inner
Bubbling: middle
Bubbling: outer

 


9. 질문 ) 클로져(Closure)에 대해 설명해주세요

9. 답변 ) 

 

클로저(Closure)는 함수와 해당 함수가 선언된 렉시컬 스코프(Lexical Scope)의 조합입니다. 클로저는 함수가 생성될 때 주변 환경(렉시컬 스코프)을 기억하고, 생성 이후에도 그 환경을 계속 접근할 수 있게 해줍니다. 이로 인해 함수가 종료된 이후에도 해당 함수의 변수에 접근할 수 있게 됩니다.

클로저를 이해하기 위해 먼저 렉시컬 스코프에 대해 알아야 합니다. 렉시컬 스코프는 함수가 선언된 위치에 따라 결정되는 스코프를 의미합니다. 즉, 함수가 어디에 선언되었는지에 따라 해당 함수가 접근할 수 있는 변수들이 결정됩니다.

아래는 클로저의 예시입니다:

 

function outerFunction() {
  const outerVariable = 'I am from outer';

  function innerFunction() {
    console.log(outerVariable); // outerFunction의 변수에 접근 (클로저)
  }

  return innerFunction;
}

const closureExample = outerFunction();
closureExample(); // "I am from outer"

 

위의 예시에서 outerFunction은 innerFunction을 반환합니다. 이때, innerFunction은 outerFunction의 렉시컬 스코프에 접근할 수 있습니다. 따라서 closureExample을 호출하면 "I am from outer"가 출력됩니다.

클로저는 다양한 상황에서 유용하게 활용됩니다. 주로 함수 팩토리(Function Factory), 비동기 코드에서의 데이터 보존, 정보 은닉 등에 활용됩니다. 또한 클로저를 적절히 사용하지 않으면 메모리 누수(memory leak)가 발생할 수 있으므로 주의가 필요합니다. 클로저를 사용할 때는 성능과 메모리 사용을 고려하여 적절하게 활용하는 것이 중요합니다.

 


10. 질문 )  실행 컨텍스트에 대해 설명해주세요.

10. 답변 ) 

 

실행 컨텍스트(Execution Context)는 JavaScript 코드가 실행되기 위해 필요한 환경을 제공하는 추상적인 개념입니다. JavaScript 엔진은 코드를 실행할 때 실행 컨텍스트를 생성하고, 코드를 해석하고 실행하는 데 필요한 모든 정보를 관리합니다.

실행 컨텍스트는 다음과 같은 세 가지 주요 구성 요소로 이루어집니다:

변수 객체(Variable Object): 해당 컨텍스트 내의 변수들과 함수 선언들을 포함하는 객체입니다. 변수의 식별자(이름)와 해당 변수에 저장된 값, 함수 선언 등이 포함됩니다.

스코프 체인(Scope Chain): 실행 컨텍스트가 생성될 때 해당 컨텍스트의 스코프와 상위 스코프들을 묶어서 생성됩니다. 이를 스코프 체인이라고 합니다. 스코프 체인은 변수를 검색하고 접근하는 규칙을 정의하는데 사용됩니다.

this 값: 해당 컨텍스트에서의 this 참조를 의미합니다.

실행 컨텍스트의 생성은 다음과 같은 상황에서 발생합니다:

전역 코드 실행: 전역 스코프에서 실행되는 코드가 있을 때 전역 실행 컨텍스트가 생성됩니다.

함수 호출: 함수가 호출될 때마다 새로운 함수 실행 컨텍스트가 생성됩니다.

eval() 함수 호출: eval() 함수를 호출하면 해당 스코프에 대한 실행 컨텍스트가 생성됩니다.

실행 컨텍스트는 스택(Stack) 자료구조에 저장되어 관리됩니다. 현재 실행 중인 코드의 컨텍스트가 스택의 맨 위에 있으며, 해당 코드가 실행을 마치면 해당 컨텍스트는 스택에서 제거됩니다. 이렇게 스택을 사용하여 실행 컨텍스트를 관리하면 코드의 실행 순서를 정확하게 추적할 수 있습니다.

코드가 실행되는 동안, 실행 컨텍스트는 변수의 생성과 초기화, 함수 호출 및 해당 함수의 반환 등을 관리하여 코드 실행에 필요한 환경을 유지합니다. 이를 통해 JavaScript 엔진은 코드를 순차적으로 실행하면서 적절한 변수와 함수에 접근할 수 있도록 합니다.

 


계속...2편으로

728x90