Node.js 인터뷰 질문 15

질문: Node.js에서 스트림(Streams)이란 무엇이며 어떤 종류가 있나요?

답변:

Node.js에서 스트림(Streams)은 데이터를 작은 청크(chunks)로 나누어 순차적으로 처리하는 추상적인 인터페이스입니다. 스트림을 사용하면 메모리 효율성이 향상되고, 특히 대용량 데이터를 처리할 때 유용합니다. 파일 읽기/쓰기, 네트워크 통신 등에서 널리 사용됩니다.

스트림의 장점

  1. 메모리 효율성: 전체 데이터를 메모리에 한 번에 로드하지 않고 조각으로 처리합니다.
  2. 시간 효율성: 전체 데이터를 기다리지 않고 도착하는 대로 처리할 수 있습니다.
  3. 조합 가능성: 여러 스트림을 파이프라인으로 연결하여 복잡한 데이터 처리 과정을 구성할 수 있습니다.

스트림의 종류

Node.js에는 네 가지 기본 스트림 타입이 있습니다:

1. 읽기 가능 스트림(Readable Streams)

데이터를 소비(읽기)할 수 있는 스트림입니다. 예: 파일 읽기, HTTP 요청, 프로세스 표준 입력(stdin) 등

const fs = require("fs");

// 파일을 읽기 가능 스트림으로 열기
const readableStream = fs.createReadStream("large-file.txt", {
  encoding: "utf8",
  highWaterMark: 16 * 1024, // 16KB 청크 크기
});

// 데이터 이벤트 구독
readableStream.on("data", (chunk) => {
  console.log(`Received ${chunk.length} bytes of data.`);
  console.log(chunk);
});

// 스트림이 끝났을 때
readableStream.on("end", () => {
  console.log("No more data to read.");
});

// 오류 처리
readableStream.on("error", (err) => {
  console.error("Error reading the file:", err);
});

2. 쓰기 가능 스트림(Writable Streams)

데이터를 쓸 수 있는 스트림입니다. 예: 파일 쓰기, HTTP 응답, 프로세스 표준 출력(stdout) 등

const fs = require("fs");

// 파일을 쓰기 가능 스트림으로 열기
const writableStream = fs.createWriteStream("output.txt");

// 데이터 쓰기
writableStream.write("첫 번째 데이터 청크\n");
writableStream.write("두 번째 데이터 청크\n");

// 쓰기 완료
writableStream.end("마지막 데이터 청크\n");

// 쓰기 완료 이벤트
writableStream.on("finish", () => {
  console.log("All data has been written to the file.");
});

// 오류 처리
writableStream.on("error", (err) => {
  console.error("Error writing to the file:", err);
});

3. 양방향 스트림(Duplex Streams)

읽기와 쓰기가 모두 가능한 스트림입니다. 예: TCP 소켓, Zlib 압축 등

const net = require("net");

// TCP 서버 생성
const server = net.createServer((socket) => {
  // 'socket'은 양방향 스트림
  socket.on("data", (data) => {
    console.log(`Received: ${data}`);
    // 데이터를 다시 클라이언트로 전송
    socket.write(`Echo: ${data}`);
  });

  socket.on("end", () => {
    console.log("Client disconnected");
  });
});

server.listen(3000, () => {
  console.log("Server started on port 3000");
});

4. 변환 스트림(Transform Streams)

데이터를 읽고, 변환한 후, 쓰는 양방향 스트림입니다. 예: 압축/해제, 암호화/복호화, 데이터 파싱 등

const { Transform } = require("stream");
const fs = require("fs");

// 대문자 변환 스트림 생성
const upperCaseTransform = new Transform({
  transform(chunk, encoding, callback) {
    // 텍스트를 대문자로 변환
    this.push(chunk.toString().toUpperCase());
    callback();
  },
});

// 파이프라인 설정: 파일 읽기 -> 대문자 변환 -> 파일 쓰기
fs.createReadStream("input.txt")
  .pipe(upperCaseTransform)
  .pipe(fs.createWriteStream("output.txt"))
  .on("finish", () => {
    console.log("Transformation completed!");
  });

스트림 파이프(pipe)

여러 스트림을 함께 연결하여 데이터 파이프라인을 만들 수 있습니다:

const fs = require("fs");
const zlib = require("zlib");

// 파일 압축 예제
fs.createReadStream("large-file.txt")
  .pipe(zlib.createGzip()) // 압축 변환 스트림
  .pipe(fs.createWriteStream("large-file.txt.gz"))
  .on("finish", () => {
    console.log("File compression completed.");
  });

// 체이닝 방식으로도 에러 처리 가능
fs.createReadStream("large-file.txt")
  .on("error", (err) => console.error("Read error:", err))
  .pipe(zlib.createGzip())
  .on("error", (err) => console.error("Compression error:", err))
  .pipe(fs.createWriteStream("large-file.txt.gz"))
  .on("error", (err) => console.error("Write error:", err));

스트림 모드

읽기 가능 스트림은 두 가지 모드로 작동할 수 있습니다:

  1. 흐름 모드(Flowing Mode): 데이터가 자동으로 읽히고 'data' 이벤트로 전달됩니다.
  2. 일시 정지 모드(Paused Mode): stream.read() 메서드를 명시적으로 호출하여 데이터를 읽어야 합니다.
// 흐름 모드
readableStream.on("data", (chunk) => {
  console.log(chunk);
});

// 일시 정지 모드
readableStream.on("readable", () => {
  let chunk;
  while (null !== (chunk = readableStream.read())) {
    console.log(chunk);
  }
});

객체 모드 스트림(Object Mode Streams)

일반적으로 스트림은 문자열이나 Buffer 객체를 처리하지만, 객체 모드에서는 JavaScript 객체를 직접 처리할 수 있습니다:

const { Transform } = require("stream");

const objectTransform = new Transform({
  objectMode: true,
  transform(chunk, encoding, callback) {
    // 입력 객체 변환
    chunk.processed = true;
    this.push(chunk);
    callback();
  },
});

스트림은 Node.js에서 대용량 데이터 처리의 핵심 기능으로, 메모리 효율적인 애플리케이션을 개발하는 데 필수적인 요소입니다.

results matching ""

    No results matching ""