TIL

TIL_2025-01-06

explosion149 2025. 1. 6.

|첼린지|스탠다드|강의|

퀵 정렬



const quickSort = (array) => {
  // 배열이 비어있거나 길이가 1이면 그대로 반환
  if (array.length <= 1) {
    return array;
  }

  // 피벗 선택 (여기서는 배열의 첫 번째 요소를 피벗으로 선택)
  const pivot = array[0];

  // 피벗을 기준으로 배열을 나누기
  const left = [];   // 피벗보다 작은 요소들
  const right = [];  // 피벗보다 큰 요소들

  // 배열의 두 번째 요소부터 끝까지 반복
  for (let i = 1; i < array.length; i++) {
    if (array[i] < pivot) {
      left.push(array[i]);  // 피벗보다 작으면 왼쪽으로
    } else {
      right.push(array[i]); // 피벗보다 크면 오른쪽으로
    }
  }

  // 재귀적으로 왼쪽과 오른쪽 배열을 정렬하고 피벗을 합쳐서 반환
  return [...quickSort(left), pivot, ...quickSort(right)];
};

피벗!!!!!!!!!

우리가 정렬할 숫자들 중에서 하나를 고른다!!!!!!!!!!!!!!!!!!!

이 숫자를 피벗이라 부른다!!!!!!!!!!!!!!!!!!!!!!!!!!!

[ 8, 3, 1, 7,] 숫자들이 있다면 우리가 8을 피벗으로 선택한다!!!!!!!!!!!!!!!


배열나누기!!!!!!!!!!

이제 피벗을 기준으로 숫자들을 나누자!!!!!!!!!!!!!!!!!!!!!!

피벗보다 작은 숫자는 왼쪽으로!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

큰 숫자는 오른쪽으로!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

위의 예시에서 8을 기준으로 한다면

[3,1,7] 은 왼쪽으로 간다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

[8] 은 가운데에 온다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

오른쪽에는 아무것도 남지 않는다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


재귀적 정렬하기

왼쪽 의 [3, 1, 7]에 대해서도 같은 과정을 거친다!!!!!!!!!!!!!!!!!!!!!!!!!!!

여기에서도 하나의 피벗을 정하고 나눈다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

[3]을 피벗으로 선택하면 [1]은 왼쪽으로 간다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

[7]은 오른쪽으로 간다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

[1, 3, 7] 결국에는 이런 결과가 된다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


반복

이렇게 과정을 반복한다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

더이상 버틸수가 없다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

모든 숫자가 정렬된 상태가 된다!!!!!!!!!!!!!!!!!!!!!!!!!


최종 장막

모든 과정을 거쳤다면 순서대로 배열이 정렬된다!!!!!!!!!!!!!!!!!!!!!

[1, 3, 7, 8]


요약

퀵정렬은 피벗을 기준으로 배열을 나누고 각 부분을 반복 정렬해서 최종적으로 모든 숫자가 크기 순서대로 나오는 방법입니다.
찡긋 ㅇ _ <


레이턴시

레이턴시(latency)는 데이터가 전송되기 시작한 시점과 수신자가 데이터를 수신한 시점 사이의 지연 시간을 의미합니다. 주로 네트워크 통신, 컴퓨터 시스템, 게임, 비디오 스트리밍 등에서 중요한 개념으로, 레이턴시가 낮을수록 데이터 전송이 빠르게 이루어집니다.


물리적 거리: 데이터가 이동해야 하는 거리.
네트워크 장비: 라우터, 스위치 등의 성능.
프로토콜: 데이터 전송에 사용되는 프로토콜의 효율성.
트래픽 부하: 네트워크의 사용량과 혼잡도.
처리 시간: 데이터가 전송되고 처리되는 데 소요되는 시간.


레이턴시는 일반적으로 밀리초(ms)로 측정되며, 레이턴시가 낮을수록 시스템이나 네트워크의 반응성이 높아집니다. 레이턴시를 줄이기 위한 다양한 기술이 개발되고 있으며, 이는 사용자 경험을 개선하는 데 중요한 요소입니다.


네트워크 최적화:

CDN(Content Delivery Network): 콘텐츠를 사용자와 가까운 위치에 저장하여 전송 시간을 줄입니다.
TCP 최적화: TCP 연결의 설정 및 확인 과정을 최적화하여 지연 시간을 줄입니다.
UDP 사용: 실시간 데이터 전송이 필요한 경우, TCP 대신 UDP를 사용해 지연을 최소화할 수 있습니다.


캐싱:

데이터 캐싱: 자주 요청되는 데이터를 메모리에 저장하여 접근 시간을 단축합니다.
브라우저 캐시: 웹 애플리케이션에서 정적 자산을 브라우저에 캐싱하여 페이지 로딩 시간을 줄입니다.


서버 최적화:

서버 위치: 사용자와 가까운 데이터 센터를 선택하여 지연 시간을 줄입니다.
부하 분산: 여러 서버에 요청을 분산시켜 서버의 응답 시간을 줄입니다.


애플리케이션 최적화:

비동기 처리: 요청을 비동기적으로 처리하여 사용자 인터페이스의 반응성을 향상시킵니다.
최적화된 데이터 전송: 필요한 데이터만 전송하고, 데이터 크기를 최소화합니다.


데이터베이스 최적화:

쿼리 최적화: 비효율적인 쿼리를 개선하여 응답 시간을 줄입니다.
인덱스 사용: 적절한 인덱스를 사용하여 데이터 검색 속도를 향상시킵니다.


레이턴시 마스킹

레이턴시 마스킹(latency masking)은 시스템의 응답 지연 시간을 사용자에게 느끼지 않도록 숨기거나 줄이는 기술을 의미합니다.
주로 실시간 애플리케이션이나 사용자 경험이 중요한 시스템에서 사용되며,
레이턴시를 사용자에게 인지되지 않도록 하는 방법입니다.


비동기 처리:

작업을 비동기적으로 수행하여 메인 스레드의 블로킹을 방지합니다.
사용자가 다른 작업을 수행할 수 있도록 하여 지연을 느끼지 않도록 합니다.


프리로딩(Preloading):

사용자가 필요로 할 가능성이 있는 데이터를 미리 로드하여,
실제 요청 시 지연 없이 빠르게 제공할 수 있도록 합니다.


스켈레톤 화면(Skeleton Screen):

콘텐츠가 로드되는 동안 빈 공간 대신 미리 정의된 레이아웃을 보여주어
사용자가 기다리는 동안 지루하지 않도록 합니다.


로딩 애니메이션:

데이터가 로드되는 동안 시각적 피드백을 제공하여
사용자가 시스템이 작동하고 있다는 것을 인지하도록 합니다.


데이터 캐싱:

자주 사용하는 데이터를 미리 캐싱하여, 다음 요청 시 빠르게 응답할 수 있도록 합니다.


지속적인 업데이트:

사용자의 인터페이스를 지속적으로 업데이트하여
사용자가 시스템과 상호작용하고 있다는 느낌을 유지합니다.


경량화된 프로세스:

사용자가 요청하는 작업을 경량화하여 처리 시간을 줄이는 방법입니다.
예를 들어, 요청을 최소화하고 필요한 데이터만 가져옵니다.

/* 
이 코드는 TCP 서버를 초기화하고 실행하는 기능을 제공합니다.
서버는 클라이언트의 연결을 처리하기 위해 `onConnection` 이벤트 핸들러를 사용하며,
서버가 성공적으로 시작되면 실행 중인 주소를 로그로 출력합니다.
초기화 과정에서 오류가 발생할 경우, 오류 메시지를 출력하고 프로세스를 종료합니다.
*/

import net from 'net';  // net 모듈 임포트
import initServer from './init/index.js';  // 서버 초기화 함수 임포트
import { config } from './config/config.js';  // 설정 파일 임포트
import { onConnection } from './events/onConnection.js';  // 연결 이벤트 핸들러 임포트

const server = net.createServer(onConnection);  // 서버 생성

// 서버 초기화 및 실행
const startServer = async () => {
  try {
    await initServer(); // 서버 초기화
    server.listen(config.server.port, config.server.host, () => {
      console.log(`서버가 ${config.server.host}:${config.server.port}에서 실행 중입니다.`);
      console.log(server.address()); // 서버 주소 출력
    });
  } catch (err) {
    console.error(err); // 오류 로그 출력
    process.exit(1); // 오류 발생 시 프로세스 종료
  }
};

// 서버 초기화 및 실행
startServer();

/* 
이 코드는 서버 초기화 작업을 수행하는 함수를 정의합니다.
게임 자산과 프로토타입을 로드하고, 데이터베이스 연결을 테스트합니다.
오류가 발생하면 로그를 출력하고 프로세스를 종료합니다.
*/

import { loadGameAssets } from './assets.js';  // 게임 자산 로드 함수
import { loadProtos } from './loadProtos.js';  // 프로토타입 로드 함수
import { testAllConnections } from '../utils/db/testConnection.js';  // 데이터베이스 연결 테스트 함수
import pools from '../db/database.js';  // 데이터베이스 풀

// 서버 초기화 함수
const initServer = async () => {
  try {
    await loadGameAssets();  // 게임 자산 로드
    await loadProtos();  // 프로토타입 로드
    await testAllConnections(pools);  // 데이터베이스 연결 테스트
    // 다음 작업
  } catch (e) {
    console.error(e);  // 오류 로그 출력
    process.exit(1);  // 오류 발생 시 프로세스 종료
  }
};

export default initServer;  // 초기화 함수 내보내기


/* 
이 코드는 게임 자산을 로드하고 관리하는 기능을 구현합니다.
JSON 파일에서 게임 자산을 비동기적으로 읽어와 전역 객체에 저장하며,
자산을 반환하는 함수도 포함되어 있습니다.
*/

import fs from 'fs';  // 파일 시스템 모듈
import path from 'path';  // 경로 모듈
import { fileURLToPath } from 'url';  // URL 모듈

// import.meta.url은 현재 모듈의 URL을 나타내는 문자열
// fileURLToPath는 URL 문자열을 파일 시스템의 경로로 변환

// 현재 파일의 절대 경로. 이 경로는 파일의 이름을 포함한 전체 경로
const __filename = fileURLToPath(import.meta.url);

// path.dirname() 함수는 파일 경로에서 디렉토리 경로만 추출 (파일 이름을 제외한 디렉토리의 전체 경로)
const __dirname = path.dirname(__filename);
const basePath = path.join(__dirname, '../../assets');  // 자산 파일이 저장된 기본 경로
let gameAssets = {};  // 전역 변수로 게임 자산을 저장

// 파일을 비동기적으로 읽는 함수
const readFileAsync = (filename) => {
  return new Promise((resolve, reject) => {
    fs.readFile(path.join(basePath, filename), 'utf8', (err, data) => {
      if (err) {
        reject(err);  // 오류 발생 시 거부
        return;
      }
      resolve(JSON.parse(data));  // JSON 데이터를 객체로 변환하여 해결
    });
  });
};

// 게임 자산을 로드하는 비동기 함수
export const loadGameAssets = async () => {
  try {
    // 여러 파일을 비동기적으로 읽기
    const [stages, items, itemUnlocks] = await Promise.all([
      readFileAsync('stage.json'),
      readFileAsync('item.json'),
      readFileAsync('item_unlock.json'),
    ]);
    gameAssets = { stages, items, itemUnlocks };  // 읽어온 데이터 저장
    return gameAssets;  // 게임 자산 반환
  } catch (error) {
    throw new Error('Failed to load game assets: ' + error.message);  // 오류 발생 시 예외 처리
  }
};

// 게임 자산을 반환하는 함수
export const getGameAssets = () => {
  return gameAssets;  // 전역 변수에서 게임 자산 반환
};

'TIL' 카테고리의 다른 글

TIL_2025-01-08  (0) 2025.01.08
TIL_2025-01-07  (0) 2025.01.07
TIL_2025-01-03  (0) 2025.01.03
TIL_2025-01-02  (0) 2025.01.02
TIL_2024-12-31  (0) 2024.12.31

댓글

💲 추천 글