반응형

목적

API Gateway의 목적은 클라이언트와 백엔드 서비스 간의 중간 계층 역할을 하면서 다양한 기능들을 수행하여 시스템의 효율성과 보안성을 높이는 것

특징

1. 단일 진입점 제공 (Single Entry Point)

  • 클라이언트는 여러 백엔드 서비스를 직접 호출하지 않고, API Gateway 하나만 호출하면 됨.
  • 마이크로서비스 아키텍처에서 특히 유용.

2. 요청 라우팅 (Request Routing)

  • 들어오는 요청을 적절한 백엔드 서비스로 라우팅
  • 예: /user → 사용자 서비스, /order → 주문 서비스

3. 보안 관리

  • 인증(Authentication), 인가(Authorization)를 중앙에서 처리
  • JWT 토큰 검사, API 키 체크 등

4. 로깅 및 모니터링

  • 요청 로그를 수집하거나, 트래픽 분석 등 관측 기능을 제공
  • 성능 모니터링, 트래픽 제어 등도 가능

5. 요청/응답 변환

  • 요청 또는 응답의 포맷을 변환 (예: XML ↔ JSON)
  • 백엔드는 단순하게 유지하고, 클라이언트 맞춤 응답 제공 가능

6. 로드 밸런싱 및 장애 처리

  • 여러 백엔드 인스턴스 사이에서 트래픽 분산
  • 장애 발생 시 다른 인스턴스로 우회

7. 속도 제한 및 트래픽 제어 (Rate Limiting)

  • 남용 방지를 위해 호출 빈도 제한
  • 과도한 요청에 대한 보호

8. 캐싱

  • 빈번한 요청 결과를 캐싱하여 응답 속도 개선 및 서버 부하 감소.

API Gateway는 다음과 같은 역할을 하며 시스템을 더 안전하고, 효율적이며, 확장 가능하게 도움을 준다.

API Gateway의 부하 분산

1. API Gateway가 부하 병목이 될 수 있는 이유

  • 모든 요청을 한 곳(API Gateway)으로 집결시키므로, 트래픽 집중이 발생.
  • 트래픽이 급증하면, API Gateway가 요청을 처리하는 데 시간이 오래 걸릴 수 있음.

2. 부하를 분산시키는 방법

2.1 수평 확장(Scaling Out)

  • API Gateway 서버를 여러 대 운영하고, 그 앞단에 로드 밸런서(Load Balancer) 를 두어 부하를 분산
  • 예: Nginx, AWS ALB, Google Cloud Load Balancing 등

2.2 캐싱(Caching) 활용

  • 자주 요청되는 결과를 캐싱하면, Gateway가 각 요청마다 백엔드까지 직접 호출할 필요가 없어짐
  • 응답 속도 향상 및 서버 부하 감소

2.3 비동기 처리(Async)와 메시지 큐(Message Queue)

  • 어떤 요청은 즉시 처리가 필요하지 않을 수 있습니다(예: 이메일 전송, 비동기 트랜잭션 등)
  • 메시지 큐(Kafka, RabbitMQ 등)를 통해 처리할 수 있도록 하여 Gateway가 동기 처리 부담을 완화

2.4 서버리스(Serverless) 사용

  • AWS API Gateway + Lambda 조합 등으로 필요한 시점에만 자동 확장이 가능하도록 설계
  • 초당 수백만 건의 요청도 일정 수준까지는 감당하도록 구성 가능

2.5 API Gateway 경량화

  • Gateway 레이어에 지나치게 많은 기능(인증/인가, 변환, 로깅 등)을 몰아넣으면 부하가 커지기에 잘 고려해야함
  • 꼭 필요한 기능만 Gateway에서 처리하고, 나머지는 별도 마이크로서비스 혹은 다른 계층에서 담당하게 하여 Gateway의 역할을 경량화

3. 단일 장애 지점을 피하는 고가용성(HA) 구성

  • API Gateway가 멈추면 모든 서비스가 사실상 중단될 가능성이 있음
  • 따라서, 멀티 AZ(가용 영역), 멀티 리전 또는 다중 Gateway 인스턴스 구성을 통해 장애 발생 시에도 서비스 중단이 최소화되도록 하는 구성이 필요

4. 결론

  • API Gateway가 모든 트래픽의 단일 진입점으로 동작하므로, 제대로 설계하고 확장 전략을 마련하지 않으면 병목 및 장애 지점이 될 수 있다.
  • 하지만 수평 확장, 캐싱, 비동기 처리, 고가용성 구성 등을 통해 충분히 분산 설계가 가능함
  • 즉, 잘못 설계하면 병목이 되지만, 올바른 인프라/아키텍처 구성과 모니터링을 통해 API Gateway의 이점(중앙 집중 관리, 보안, 모니터링 등)을 극대화하면서도 부하 문제 완화가능
반응형

'공부 > CS' 카테고리의 다른 글

워터마크 기술 개념  (0) 2025.03.03
아키텍처 간략 정리  (0) 2025.01.05
언어별 연산 속도  (0) 2024.12.30
Context Switching(문맥 교환)  (0) 2024.09.19
해시 - 솔트치기  (0) 2024.08.25
반응형

워터마크(Watermark)란?

워터마크(Watermark)는 디지털 콘텐츠(이미지, 영상, 오디오, 문서 등)에 저작권 보호, 출처 표기, 위변조 방지 등의 목적으로 삽입되는 표식이다. 워터마크는 가시적(Visible)비가시적(Invisible) 방식으로 나뉜다.


1. 가시적 워터마크 (Visible Watermark)

  • 정의

이미지, 영상, 문서 등에 눈에 보이는 형태로 삽입된 워터마크를 의미한다.

  • 특징
    • 사람이 직접 볼 수 있음 (예: 로고, 텍스트, 투명한 마크)
    • 저작권 보호 및 출처 표시 목적
    • 복제 방지를 위한 억제 효과
    • 그러나 이미지 편집 기술(포토샵 등)로 제거 가능
  • 예시
    • 사진에 삽입된 "© 2025 PhotographerName" 표시
    • 영상의 한쪽 구석에 있는 방송국 로고 (예: "KBS", "MBC")
    • PDF 문서의 배경에 투명하게 삽입된 회사명

2. 비가시적 워터마크 (Invisible Watermark)

  • 정의

사람의 눈에는 보이지 않지만, 디지털 신호(이미지, 영상, 오디오, 문서)에 숨겨진 형태로 삽입된 워터마크를 의미한다.

  • 특징
    • 사람이 직접 볼 수 없음 (특정 소프트웨어나 알고리즘을 통해 확인 가능)
    • 저작권 보호 및 원본 출처 확인
    • 변형, 편집 후에도 검출 가능 (강인성에 따라 다름)
    • 이미지, 오디오, 영상에 널리 사용됨
  • 기술적 기법
    • 공간 영역 기법: 픽셀값에 미세한 변화 삽입
    • 주파수 영역 기법: 푸리에 변환(DFT), 웨이브렛 변환(DWT) 등을 활용해 삽입
    • 양자화 지수 변조(QIM): 특정 패턴을 신호에 삽입하여 탐지
  • 예시
    • 사진 속 특정 픽셀에 디지털 서명 숨기기
    • 영화나 음악 파일에 저작권 정보 삽입
    • 문서에 특정한 패턴을 추가해 출처 확인

3. 가시적 vs 비가시적 워터마크 비교

비교 항목 가시적 워터마크 비가시적 워터마크
눈으로 보이는지 O (보임) X (보이지 않음)
저작권 보호 효과 높음 (사람들이 인식) 높음 (탐지 필요)
위변조 방지 제거 가능성 높음 강인한 방식은 제거 어려움
출처 추적 육안으로 확인 가능 디지털 분석 필요
사용 예시 사진 로고, 방송국 마크, PDF 배경 디지털 인증, 영상·음원 추적

결론

  • 가시적 워터마크는 저작권 보호를 강조하고 쉽게 알아볼 수 있는 장점이 있지만 제거될 가능성이 있다.
  • 비가시적 워터마크는 콘텐츠의 무결성을 유지하면서도 추적이 가능하지만, 분석 도구가 필요하다.
  • 두 가지 방법을 함께 사용하면 보안성과 저작권 보호 효과를 극대화할 수 있다.
반응형

'공부 > CS' 카테고리의 다른 글

API Gateway  (0) 2025.03.24
아키텍처 간략 정리  (0) 2025.01.05
언어별 연산 속도  (0) 2024.12.30
Context Switching(문맥 교환)  (0) 2024.09.19
해시 - 솔트치기  (0) 2024.08.25
반응형

백준 감소하는 수(줄어드는 수)

https://www.acmicpc.net/problem/1174

https://www.acmicpc.net/problem/1038

접근 방식

최초엔 n까지 범위의 수를 생각했는데, 잘못 생각한 것이였고, 앞자리부터 점점 감소하는 수의 모든 경우의 수 중 몇번째인지 n으로 입력받아 찾는 문제


구현 방법

  • 감소하는 수에 대해 모든 조합을 찾은 후 정렬해 수행
  • 이 때 최대 수의 범위까지 1씩 더해가며 찾는 것이 아닌, 값이 들어갈 수 있는 범위에 대해서만 찾기

  • 9876543210 까지가 최대 수
  • 재귀에서 자릿수(depth)를 받아서 depth 범위만큼 foreach돈다.
  • 기본적으로 for문 돌 때 자기보다 낮은 수에 대해서만 수행
  • 재귀 안에서 count가 같으면 return - count는 static으로 갖고있기에 종료가능
  • for문이 다 돌면 재귀호출 시행

풀이

package Baekjoon.gold;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

public class p1174 {

    static Stack<Long> st = new Stack<>();
    static ArrayList<Long> al = new ArrayList<>();

    static int count = 0;
    static int n;
    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        n = Integer.parseInt(br.readLine());

        /*
         0, 1, 2, 3, 4, 5, 6, 7, 8, 9
         10 | 20, 21 | 30, 31, 32 | 40, 41, 42, 43 | 50, 51, 52, 53, 54 |
         60, 61, 62, 63, 64, 65 | 70, 71, 72, 73, 74, 75, 76 |
         80, 81, 82, 83, 84, 85, 86, 87 | 90, 91, 92, 93, 94, 95, 96, 97, 98 |
         210 |320, 321, 310 | 410, 420, 421, 430, 431, 432
         */

        //9 -> 8 7 6 5 4 3 2 1 0
        //8 -> 7 6 5 4 3 2 1 0
        //7 -> 6 5 4 3 2 1 0
        //6 -> 5 4 3 2 1 0
        //5 -> 4 3 2 1 0
        //4 -> 3 2 1 0
        //3 -> 2 1 0
        //2 -> 1 0
        //1 -> 0

        // 10 20 21 30 31 32
        //9876543210 까지가 최대 수
        //재귀에서 자릿수(depth)를 받아서 depth 범위만큼 foreach돈다.
        //기본적으로 for문 돌 때 자기보다 낮은 수에 대해서만 수행
        //재귀 안에서 count가 같으면 return - count는 static으로 갖고있기에 종료가능
        //for문이 다 돌면 재귀호출 시행

        if(n <= 10){
            System.out.println(n-1);
            return;
        }
        recur(10);
        List<Long> list = al.stream().sorted().collect(Collectors.toList());

        long result = -1;
        if(list.size() >= n){
            result = list.get(n-1);
        }

        System.out.println(result);
    }

    private static void recur(long nowNum){
        for(long i = 0; i < nowNum; i++){
            count++;
            st.push(i);
            st.forEach(sb::append);
            al.add(Long.valueOf(sb.toString()));
            sb.setLength(0);
            recur(i);
            st.pop();
        }
    }
}

후기

최초에 문제를 잘못 읽었고, 이후엔 전체 탐색을 효율적으로 하기위한 노력(가지치기)을 하는 데 시간을 많이 썼음

반응형
반응형

AtomicInteger.class의 메서드를 탐방하다 발견하게 된 native 키워드 탐방

@IntrinsicCandidate
public final native boolean compareAndSetInt(Object o, long offset, int expected, int x);

native 키워드는 Java에서 네이티브 코드를 사용해 자바 코드로는 직접 수행하기 어려운 작업을 해결하기 위해 사용됨. Java는 기본적으로 플랫폼 독립성을 목표로 설계된 언어지만, 외부에 작업 수행을 맡기기도 한다.

native 키워드의 역할 및 특징

운영체제, 하드웨어 종속작업 처리

Java는 플랫폼 독립성을 가진 언어이지만, 운영 체제나 하드웨어에 종속적인 작업을 처리해야할 때 C/C++로 작성된 네이티브 코드를 호출해 운영 체제의 API나 하드웨어를 직접 제어해야 한다.

  • 예:
    • 파일 시스템 접근 (FileInputStream, FileOutputStream)
    • 네트워크 소켓 관리
    • 그래픽 처리를 위한 GUI 라이브러리 (AWT/Swing)
    • 시스템 시간 가져오기 (System.currentTimeMillis())
    • concurrent(동시성) 관련 코드

성능 최적화

Java는 일반적으로 JVM 위에서 동작하므로 C/C++로 작성된 네이티브 코드에 비해 약간의 오버헤드가 존재. 특히, 자바의 네이티브 메서드는 속도가 중요한 저수준 작업에서 성능을 극대화하기 위해 사용.

  • 예:
    • AtomicInteger와 같은 CAS (Compare-And-Swap) 연산은 C/C++로 구현된 네이티브 코드를 호출하여 고성능을 보장.
    • arraycopy()는 배열 복사를 네이티브 코드로 처리하여 높은 속도를 보장.

하드웨어 제어

Java는 추상화된 언어로, 하드웨어를 직접 제어하는 데 적합하지 않다. 하지만 네이티브 코드를 사용하면 Java 프로그램이 특정 하드웨어 장치를 제어하거나 센서 데이터를 읽을 수 있다.

  • 예:
    • 임베디드 시스템에서 Java와 네이티브 코드를 조합해 사용.
    • 특정 하드웨어 기능 호출.

멀티스레딩 및 동기화

Java는 스레드 관리와 동기화 관련 기능을 제공하지만, JVM의 성능을 극대화하거나 플랫폼 종속적인 동기화 메커니즘을 사용하기 위해 네이티브 메서드가 필요할 수 있다.

  • 예:
    • Thread.sleep()와 같은 메서드는 네이티브 코드를 통해 구현되어 운영 체제의 스레드 관리 기능을 호출.
    • AtomicIntegercompareAndSet() 같은 원자적 연산은 하드웨어 명령을 활용한 네이티브 코드로 구현.
반응형
반응형

아키텍처 간략 정리

1. MVC (Model-View-Controller)

구성 요소

  • Model: 데이터와 비즈니스 로직을 관리합니다.
  • View: 사용자에게 정보를 시각적으로 표시합니다.
  • Controller: 사용자 요청을 처리하고 Model과 View를 연결합니다.

특징

  • 역할이 분리되어 코드의 가독성과 재사용성이 높습니다.
  • 사용자가 View와 상호작용하면 Controller가 이를 처리하고 Model을 업데이트한 후, View에 결과를 표시합니다.

활용

  • 웹 애플리케이션(스프링 MVC, Ruby on Rails 등)
  • 데스크톱 애플리케이션

2. MVVM (Model-View-ViewModel)

구성 요소

  • Model: 데이터와 비즈니스 로직.
  • View: UI 요소.
  • ViewModel: View와 Model 사이의 중간 계층으로, View의 상태를 관리하고, 데이터 바인딩을 지원합니다.

특징

  • 양방향 데이터 바인딩을 통해 View와 ViewModel의 동기화를 자동으로 처리합니다.
  • View는 데이터에 대한 의존성을 최소화합니다.

활용

  • WPF(Windows Presentation Foundation)
  • Angular, Vue.js, React + Redux/MobX와 같은 SPA(Single Page Application) 프레임워크

3. MVP (Model-View-Presenter)

구성 요소

  • Model: 데이터와 비즈니스 로직.
  • View: 사용자 인터페이스(UI).
  • Presenter: View의 로직을 담당하며 Model과 상호작용한 후 데이터를 View에 전달합니다.

특징

  • View는 단순히 UI를 표시하는 역할만 하고, 모든 로직은 Presenter에서 처리됩니다.
  • View와 Presenter는 1:1 관계를 갖습니다.

활용

  • 안드로이드 애플리케이션
  • 레거시 데스크톱 애플리케이션

4. Clean Architecture

구성 요소

  • Entities: 애플리케이션의 비즈니스 규칙을 캡슐화.
  • Use Cases: 애플리케이션의 특정 작업이나 기능을 정의.
  • Interface Adapters: 데이터와 UI의 변환 계층.
  • Frameworks & Drivers: 데이터베이스, UI, 외부 API 등.

특징

  • 의존성 규칙: 안쪽 계층은 바깥쪽 계층을 알지 못합니다.
  • 비즈니스 로직이 프레임워크와 독립적이어서 확장성과 유지보수가 용이합니다.

활용

  • 대규모 시스템
  • 멀티 플랫폼 애플리케이션

5. Layered Architecture (계층형 아키텍처)

구성 요소

  • Presentation Layer: 사용자 인터페이스.
  • Application Layer: 비즈니스 로직.
  • Data Layer: 데이터베이스 및 데이터 액세스.

특징

  • 계층 간 명확한 분리가 이루어집니다.
  • 단순하고 이해하기 쉬운 구조지만, 복잡한 시스템에서 성능 저하가 있을 수 있습니다.

활용

  • 전통적인 웹 애플리케이션(3-tier 아키텍처)
  • 엔터프라이즈 애플리케이션

6. Microservices Architecture

구성 요소

  • 애플리케이션을 독립적으로 배포 가능한 작은 서비스들로 나눕니다.
  • 각 서비스는 고유한 비즈니스 기능을 담당하며 API로 통신합니다.

특징

  • 독립적인 배포와 확장이 가능합니다.
  • 서비스 간 통신 오버헤드가 있고, 분산 시스템의 복잡성이 증가할 수 있습니다.

활용

  • 대규모 분산 시스템
  • 클라우드 네이티브 애플리케이션

7. Event-Driven Architecture

구성 요소

  • Event Producer: 이벤트를 생성하고 발행.
  • Event Consumer: 이벤트를 처리.
  • Event Broker: 이벤트를 전달하거나 중개.

특징

  • 비동기 통신을 기반으로 설계되어 높은 확장성을 제공합니다.
  • 복잡한 이벤트 흐름을 관리하기 위한 설계가 필요합니다.

활용

  • IoT 시스템
  • 실시간 애플리케이션(채팅, 트랜잭션 시스템)

8. Hexagonal Architecture (Ports and Adapters)

구성 요소

  • Core (Application Logic): 애플리케이션의 핵심 비즈니스 로직.
  • Ports: 외부와의 상호작용을 정의하는 인터페이스.
  • Adapters: 특정 구현을 제공하여 Core와 통신.

특징

  • 비즈니스 로직과 외부 시스템 간의 의존성을 최소화합니다.
  • 높은 테스트 가능성과 확장성을 제공합니다.

활용

  • 복잡한 도메인 로직이 있는 시스템
  • 시스템 간 통합이 필요한 애플리케이션

9. Serverless Architecture

구성 요소

  • 클라우드 기반 서비스와 함수(Function-as-a-Service)를 이용하여 애플리케이션을 실행.
  • 서버를 관리하지 않고도 클라우드 제공자가 모든 인프라를 처리.

특징

  • 확장성과 비용 효율성이 높습니다.
  • 서버 환경에 대한 제어가 제한적입니다.

활용

  • 이벤트 중심 애플리케이션
  • 간단한 API 백엔드

10. CQRS (Command Query Responsibility Segregation)

구성 요소

  • Command: 데이터 변경 작업(쓰기).
  • Query: 데이터 읽기 작업.

특징

  • 읽기와 쓰기를 분리하여 각 작업을 최적화합니다.
  • 복잡한 시스템에서 동시성과 확장성을 지원합니다.

활용

  • 이벤트 소싱 시스템
  • 고성능 읽기/쓰기 작업이 필요한 시스템

11. Pipe and Filter Architecture

구성 요소

  • Filters: 데이터를 처리하는 독립적인 컴포넌트.
  • Pipes: 필터 간 데이터를 전달.

특징

  • 데이터 흐름을 직관적으로 표현할 수 있습니다.
  • 처리 단계가 많아지면 성능 저하가 발생할 수 있습니다.

활용

  • 데이터 처리 파이프라인
  • 이미지 또는 오디오 프로세싱

12. Service-Oriented Architecture (SOA)

구성 요소

  • 독립적인 서비스들로 구성되며, 각 서비스는 특정 비즈니스 기능을 제공합니다.
  • 서비스는 표준 프로토콜(예: SOAP, REST)을 통해 통신합니다.

특징

  • 서비스 간 의존성이 낮아 확장성과 재사용성이 높습니다.
  • 복잡한 통합과 관리가 필요합니다.

활용

  • 엔터프라이즈 애플리케이션
  • 분산 시스템

CSR에서 자바 스프링 백엔드 아키텍처

  1. 계층형 아키텍처 사용 (Layered Architecture)
  2. RESTful API 서버로 프론트엔드와 데이터 통신
  3. JPA + Hibernate를 통한 데이터베이스 연동
  4. JWT를 통한 보안 및 인증 처리
  5. 마이크로서비스 및 API Gateway 적용 가능 (Spring Cloud Gateway)
  6. 비즈니스 로직, 예외 처리, 로깅, 모니터링 구성

➡️ CSR 환경에서는 프론트엔드가 주로 UI를 렌더링하고, 자바 스프링 백엔드는 데이터 제공, 비즈니스 로직 처리, 보안, 데이터베이스 연동을 주로 담당합니다.

아키텍처 패턴 선택 가이드

  1. 프로젝트 규모:
    • 작은 프로젝트: MVC, MVP
    • 대규모 프로젝트: Microservices, Clean Architecture
  2. 프론트엔드 및 백엔드 협업:
    • 단일 애플리케이션: MVVM, MVC
    • 분리된 환경: RESTful API 기반 MC
  3. 확장성 요구:
    • 높은 확장성: Microservices, Serverless
  4. 실시간 처리:
    • 실시간 데이터: Event-Driven, CQRS
반응형

'공부 > CS' 카테고리의 다른 글

API Gateway  (0) 2025.03.24
워터마크 기술 개념  (0) 2025.03.03
언어별 연산 속도  (0) 2024.12.30
Context Switching(문맥 교환)  (0) 2024.09.19
해시 - 솔트치기  (0) 2024.08.25
반응형

언어별 연산 속도

단순 연산 기준으로 나눠본 언어별 연산 속도 + 특징

Python

  • 인터프리터 언어
  • 연산 속도 : 1초에 1억
  • C 기반의 확장 라이브러리(ex:Numpy)를 활용해 연산이 빠를 수 있음
  • PyPy (JIT 컴파일러) 약 2~10배 빠름

JavaScript

  • 인터프리터 언어
  • 연산 속도 : 1초에 1억 ~ 5억
  • JIT 컴파일러를 통해 연산속도 보완

Java

  • 컴파일 언어
  • 연산 속도 : 1초에 5억 ~ 10억
  • Java는 JVM 위에서 실행되며, JIT컴파일링, 런타임 최적화 등이 있음, 기본 연산속도로 따졌을 때 Python보다 약 1020배, JavaScript보다 약 25배 빠름

C / C++

  • 컴파일 언어
  • 연산 속도 : 1초에 10억 ~ 50억
    • C와 C++은 컴파일 언어로, 코드가 기계어로 직접 변환되기에 가장 빠른 속도
  • 하드웨어와 매우 가까운 수준에서 작업 가능

C#

  • 연산 속도 : 1초에 5억 ~ 10억
  • C#은 Java와 유사한 속도, .NET의 JIT 컴파일러와 런타임 최적화가 되어있음

PHP

  • 인터프리터 언어
  • 1초에 약 1억 ~ 2억
  • C 기반으로 구현된 함수와 라이브러리를 호출

데이터 베이스 구현 언어

현재 주력 데이터베이스들인 MySQL, PostgreSQL, Oracle등 대부분의 데이터베이스는 C 또는 C++로 구현되어 있어 기계어에 가까운 최적화된 실행 성능을 갖고 있다.

정리

기본 연산속도가 가장 빠른 언어는 C, 그 외의 언어는 연산속도를 보장하기 위해 JIT 컴파일러, c언어 기반의 최적화된 라이브러리 등을 지원하여, 연산속도를 보완한다.

추가로 개발자들이 사용하는 것들(ex: MySQL, PHP, 파이썬 라이브러리)이 C 기반으로 만들어지는 이유를 추측하자면, 연산속도를 포함하여 low한 레벨에서 하드웨어에 가깝게 빠른 동작을 실행하려면 메모리, Disk I/O등 C언어 방식으로 직접 관리하는 것이 가장 최적화에 도움을 주는 방식이기 때문이 아닐까 생각된다.

반응형

'공부 > CS' 카테고리의 다른 글

워터마크 기술 개념  (0) 2025.03.03
아키텍처 간략 정리  (0) 2025.01.05
Context Switching(문맥 교환)  (0) 2024.09.19
해시 - 솔트치기  (0) 2024.08.25
CGI, FastCGI  (1) 2024.07.23
반응형

타입은 자바스크립트에서 제공하는 (숫자, 문자열, 불리언, null, undefined, 심벌, 객체) 타입이 있다. 이 때 크게 원시 타입(primitive type)과 객체 타입(object type)으로 구분되는데, 다른 점이 크게 세가지 있다.

  • 원시 타입의 값은 변경 불가능한 값이다. 이에 비해 객체 타입의 값, 즉 객체는 변경 가능한 값이다.
  • 원시 값을 변수에 할당하면 변수(확보된 메모리 공간)에는 실제 값이 저장된다. 이에 비해 객체를 변수에 할당하면 변수(확보된 메모리 공간)에는 참조 값이 저장된다.
  • 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달된다. 이를 값에 의한 전달(call by value) 이라 한다. 이에 비해 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다. 이를 참조에 의한 전달(call by reference)이라 한다.

원시 값

변경 불가능한 값

원시 타입의 값은 변경 불가능하기에, 한번 생성된 원시 값은 읽기 전용 값으로써 변경할 수 없다.

변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체이고, 값은 변수에 저장된 데이터로서 표현식이 평가되어 생성된 결과를 말한다. 변경 불가능하다는 것은 변수가 아니라 값에 대한 진술이다.

즉 “원시 값은 변경 불가능하다”는 말은 원시 값 자체를 변경할 수 없는 것이지 변수 값을 변경할 수 없다는 것이 아니다. 변수는 언제든지 재할당을 통해 변수 값을 변경할 수 있다.

//상수 o에 값 할당을 다시 못할 뿐, o에 최초할당 된 객체인 o의 프로퍼티는 변경할 수 있다.
const o = {};

o.a = 1;
console.log(o); // {a: 1}

변수에 값 할당이 여러번 이루어질 때 메모리는 말 그대로 재할당이기 때문에 메모리 공간에 특정 값을 등록 후 해당 위치로 변수가 바라보는 주소값을 변경하는 것이다.

let a = 1;
a = 3;

//값이 변경되는 것이 아닌, 값을 재할당

문자열과 불변성

자바스크립트의 문자열은 원시타입으로써 변경 불가능하지만 위와 동일하게 다른 주소를 할당하는 방식으로 변수에 재할당이 가능하다

값에 의한 전달

var score = 80;
var copy = score;

console.log(score); //80
console.log(copy); //80
//score와 copy가 보고있는 80은 서로 다른 메모리주소

score = 100;

console.log(score); //100
console.log(copy); //80

원시값에 대해서는 값을 기존의 값을 복사해서 전달하는 call by value가 일어난다.

객체

객체는 프로퍼티의 개수가 정해져 있지 않으며 동적으로 추가, 삭제가 가능하다.
따라서 객체는 원시 값과 같이 확보해야 할 메모리 공간의 크기를 사전에 정할 수 없다.

프로토타입 객체지향언어 자바스크립트와 클래스 기반 객체지향언어

클래스 기반 객체지향언어는 클래스 내에 이미 생성된 프로퍼티와 메서드가 정해져 있으며, 객체가 생성된 이후에는 프로퍼티를 삭제하거나 추가할 수 없다.

자바스크립트는 클래스 없이 객체 생성이 가능하며, 동적으로 프로퍼티와 메서드를 추가할 수 있다.
하지만, 편한 만큼 클래스 기반 언어보다 객체의 생성과 프로퍼티 접근에 비용이 더 많이든다.

변경 가능한 값

객체 값은 변경이 가능한 값(mutable value)이다.

var person = {
    name: 'Lee'
};

var sang = person;

sang.name = 'ss';

console.log(sang.name);
console.log(person.name);

객체는 원시 값이 값의 주소를 갖고있는 것과 다르게, 참조 값에 접근할 수 있다. 참조 값은 생성된 객체가 저장된 메모리 공간의 주소 그 자체다.

때문에 위의 코드처럼 sang, person이 같은 주소인 0x00000001 을 바라보고 있으며 값이 동시에 변경된다.

이를 얕은복사 라고 하며, 참조에 의한 전달이 된다

반응형
반응형

객체란?

자바스크립트는 원시 값을 제외한 나머지 값(함수, 배열, 정규 표현식 등)은 모두 객체

원시 타입은 단 하나의 값만 나타내고, 객체 타입은 다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료구조다.
또 원시 값은 변경 불가능한 값이지만, 객체는 변경 가능한 값이다.

객체는 0개 이상의 프로퍼티로 구성된 집합이고, 키(key)와 값(value)으로 구성되어 있다.

var person = {
    name: 'Lee', //- 프로퍼티
    age: 20 // age : 키, 20 : 값
}

자바스크립트의 함수는 프로퍼티의 값으로 사용할 수 있다. 프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메서드라고 부른다.

var counter = {
    num: 0,
    increase: function () {
        this.num++;
    }
};
  • 프로퍼티 : 객체의 상태를 나타내는 값
  • 메서드: 프로퍼티를 참조하고 조작할 수 있는 동작

객체 리터럴에 의한 객체 생성

자바스크립트는 프로토타입 기반 객체지향 언어로서 클래스 기반 객체지향 언어와는 달리 다양한 객체 생성 방법을 지원한다.

  • 객체 리터럴
  • Object 생성자 함수
  • 생성자 함수
  • Object.create메서드
  • 클래스(ES6)

이러한 객체 생성 방법 중에서 가장 일반적이고 간단한 방법은 객체 리터럴을 사용하는 방법이다.

객체 리터럴은 중괄호 내에 0개 이상의 프로퍼티를 정의한다. 변수에 할당되는 시점에 자바스크립트 엔진은 객체 리터럴을 해석해 객체를 생성한다.

var person = {
    name: 'Lee';
    sayHello: function() {
        console.log('Hello! My name is $(this.name}.');
    }
};

console.log(typeof person); // object
console.log(person); // {name: "Lee", sayHello: f}

var empty = {};
if(empty){

}
//if문의 코드블록에는 세미콜론 x

객체 리터럴의 중괄호는 코드 블록을 의미하지 않는다는 데 주의.
코드 블록의 닫는 중괄호 뒤에는 세미콜론을 붙이지 않고, 객체 리터럴의 닫는 중괄호 뒤에는 세미콜론을 붙인다.

프로퍼티

객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성된다.

var person = {
    name: 'Lee',
    age: 20
};

프로퍼티를 나열할 때는 쉼표(,)로 구분한다. 일반적으로 마지막 프로퍼티 뒤에는 쉼표를 사용하지 않지만, 사용해도 문제되지 않는다.

프로퍼티 키와 프로퍼티 값으로 사용할 수 있는 값은 다음과 같다.

  • 프로퍼티 키: 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
  • 프로퍼티 값: 자바스크립트에서 사용할 수 있는 모든 값

이 때 네이밍 규칙을 따라야 프로퍼티 키값에 따옴표를 생략할 수 있다.

var person = {
    firstName: 'Ung-mo', // 식별자 네이밍 규칙을 준수하는 프로퍼티 키
    'last-name': 'Lee' // 식별자 네이밍 규칙을 준수하지 않는 프로퍼티 키
}

console.log(person); // {firstName: "Ung-mo", last-name: "Lee"}

메서드

자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값으로 사용할 수 있다, 그렇기 때문에 자바스크립트의 함수도 프로퍼티 값으로 사용할 수 있다.

프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드라 부른다.

var circle = {
    radius: 5, // 프로퍼티

    // 원의 지름
    getDiameter: function () { // 메서드
        return 2 * this.radius; // this는 circle을 가리킨다.
    }
};

console.log(circle.getDiameter()); // 10

프로퍼티 접근

프로퍼티에 접근하는 방법은 다음과 같이 두 가지다.

  • 마침표 프로퍼티 접근 연산자를 사용하는 마침표 표기법
  • 대괄호 프로퍼티 접근 연산자를 사용하는 대괄호 표기법

프로퍼티 키가 식별자 네이밍 규칙을 준수하는 이름, 즉 자바스크립트에서 사용 가능한 유효한 이름이면 마침표 표기법과 대괄호 표기법을 모두 사용할 수 있다.

var person = {
    name: 'Lee'
};

console.log(person.name); // Lee

console.log(person['name']); // Lee

대괄호 프로퍼티 접근 연산자 내부에 지정하는 프로퍼티 키는 반드시 따옴표로 감싼 문자열이 되어야 한다.

문제 예시

var person = {
    name: 'Lee'
};

console.log(person[name]); // ReferenceError: name is not defined

객체에 존재하지 않는 프로퍼티에 접근하면 undefined를 반환한다. 이때 ReferenceError가 발생하지 않는데 주의하자.

프로퍼티 값 갱신

이미 존재하는 프로퍼티에 값을 할당하면 프로퍼티 값이 갱신

var person = {
    name: 'Lee'
}

person.name = 'Kim';

console.log(person); // {name: "Kim"}

프로퍼티 동적 생성

존재하지 않는 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성되어 추가되고 프로퍼티 값이 할당된다.

var person = {
    name: 'Lee'
};

person.age = 20;

console.log(person); // {name: "Lee", age: 20}

프로퍼티 삭제

delete 연산자는 객체의 프로퍼티를 삭제한다. 이때 delete 연산자의 피연산자는 프로퍼티 값에 접근할 수 있는 표현식이어야 한다. 만약 존재하지 않는 프로퍼티를 삭제하면 아무런 에러 없이 무시된다.

var person = {
    name: 'Lee'
};

person.age = 20; // 프로퍼티 동적 생성

delete person.age;

delete person.address; // 없는 프로퍼티를 삭제해도 에러반환 x

console.log(person);

ES6에서 추가된 객체 리터럴의 확장 기능

ES6에서는 더욱 간편하고 표현력 있는 객체 리터럴의 확장 기능을 제공한다.

프로퍼티 축약 표현

객체 리터럴의 프로퍼티는 키, 값으로 구성된다.

//ES5
var x = 1, y = 2;

var obj = {
    x: x,
    y: y
}

console.log(obj); // {x: 1, y: 2}

ES6에서는 프로퍼티 값으로 변수를 사용하는 경우 변수 이름과 프로퍼티 키가 동일한 이름일 때 프로퍼티 키를 생략할 수 있다. 이때 프로퍼티 키는 변수 이름으로 자동 생성된다.

//ES6
let x = 1, y = 2;

const obj = { x, y };

console.log(obj); // { x: 1, y: 2 }

계산된 프로퍼티 이름

문자열 또는 문자열로 타입 변환할 수 있는 값으로 평가되는 표현식을 사용해 프로퍼티 키를 동적으로 생성할 수도 있다. 단, 키를 대괄호로 묶어야 한다.

//ES5
var prefix = 'prop';
var i = 0;

var obj = {};

// 계산된 프로퍼티 이름으로 프로퍼티 키 동적 생성
obj[prefix + '-' + ++i] = i;
obj[prefix + '-' + ++i] = i;
obj[prefix + '-' + ++i] = i;

console.log(obj); // {prop-1: 1, prop-2: 2, prop-3: 3}

ES6에서는 객체 리터럴 내부에서도 계산된 프로퍼티 이름으로 프로퍼티 키를 동적 생성할 수 있다.

//ES6
const prefix = 'prop';
let i = 0;

// 리터럴 내부에서 계산된 프로퍼티 이름으로 프로퍼티 키를 동적 생성
const obj = {
    [`${prefix}-${++i}`]: i,
    [`${prefix}-${++i}`]: i,
    [`${prefix}-${++i}`]: i
};

console.log(obj); // {prop-1: 1, prop-2: 2, prop-3: 3}

메서드 축약 표현

ES5는 프로퍼티 값으로 메서드를 정의, ES6에서는 메서드 정의할 때 function 키워드 생략 가능

//ES5
var obj = {
    name: 'Lee',
    sayHi: function() {
        console.log('Hi! ' + this.name);
    }
};

//ES6
const obj = {
    name: 'Lee',
    // 메서드 축약 표현
    sayHi() {
        console.log('Hi! ' + this.name);
    }
};

obj.sayHi(); // Hi! Lee
반응형
반응형

타입 변환이란?

자바스크립트의 모든 값은 타입이 있다.

개발자가 의도적으로 값의 타입을 변환하는 것을 명시적 타입 변환 또는 타입 캐스팅 이라 한다.

var x = 10;

var str = x.toString();
console.log(typeof x, x); // string 10

개발자의 의도와는 상관없이 암묵적으로 타입이 자동 변환되기도 한다. 이를 암묵적 타입 변환 또는 타입 강제 변환 이라한다.

var x = 10;

var str = x + '';
console.log(typeof str, str); // string 10

타입 변환이 기존 원시 값을 직접 변경하는 것은 아니다. 원시 값은 변경 불가능한 값이므로 변경할 수 없다. 타입 변환이란 기존 원시 값을 사용해 다른 타입의 새로운 원시 값을 생성하는 것이다.

이 타입변환을 모던하게 사용하려면, 개발자가 의도했다는 명확한 표현력이 적은 암묵적 타입 변환보다는, 의도를 명확하게 담은 명시적 타입 변환을 사용하는게 좋다.

암묵적 타입 변환

코드의 문맥을 고려해 암묵적으로 데이터 타입을 강제 변환하는 경우를 살펴보자.

문자열 타입으로 변환

1 + '2' // "12"

+연산은 문자열이 피연산자중 하나라도 있을 경우 문자열로 연결된다.

숫자 타입으로 변환

1 - '1' // 0
1 * '10' // 10
1 / 'one' // NaN

산술 연산자를 활용하면 문자를 숫자로 읽어들인다. ‘one’같은 경우는 숫자로 변환하지 못하기에 NaN을 출력

불리언 타입으로 변환

조건식의 경우도 암묵적 타입변환

if('') console.log('1');
if(true) console.log('2');
if(0) console.log('3');
if('str') console.log('4');
if(null) console.log('5');

// 2 4

false로 형변환 되는 값

  • false
  • undefined
  • null
  • 0, -0
  • NaN
  • ‘’(빈 문자열)

명시적 타입 변환

개발자의 의도에 따라 명시적으로 타입을 변경하는 법

  • 표준 빌트인 생성자 함수
  • 빌트인 메서드
  • 암묵적 타입 변환

문자열 타입으로 변환

  • String 생성자 함수를 new 연산자 없이 호출
  • Object.prototype.toString 메서드
  • 문자열 연결 연산자 이용
String(1);
(1).toString();
1 + '';

숫자 타입으로 변환

  • Number 생성자 함수를 new 연산자 없이 호출
  • parseInt, parseFloat 함수를 사용
    • 단항 산술 연산자를 이용
    • 산술 연산자를 이용
Number('0');
parseInt('0');
'0'*1;

불리언 타입으로 변환

  • Boolean 생성자 함수를 new 연산자 없이 호출
  • ! 부정 논리 연산자를 두번 사용
Boolean('x');
!!'x';

단축 평가

논리합과 논리곱은 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환한다. 이를 단축 평가라 한다. 단축 평가는 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말한다.

논리합(||) 논리곱(&&) 연산자 표현식의 평가 결과는 불리언 값이 아닐 수 있다.

'Cat' && 'Dog' // -> "Dog"

논리곱(&&) 연산자는 두 개의 피연산자가 모두 true로 평가될 때 true를 반환한다.

'Cat' || 'Dog' // -> "Cat"

논리합(||) 둘 중 하나만 true여도 true를 반환하기에 Cat부터 True이기 때문에 Cat을 반환

반응형
반응형

Context Switching(문맥 교환)

병렬처리에 관해 이야기할 때 항상 등장하는 단어인 Context Switching에 대해 공부 해보았다. 해당 단어를 꺼내기 위해서는 기본적으로 알아둬야 할 사전지식이 필요하다. 해당 사전지식도 가볍게 다루며 콘텍스트 스위칭에 대하여 작성해보자.

프로세스

프로세스는 컴퓨터에서 프로그램이 실행될 때 사용되는 실행 단위로, 실행 중인 프로그램의 인스턴스다. 메모리와 CPU 자원을 할당받아 동작하는 상태를 의미하며, 우리가 코드를 통해 만든 하나의 애플리케이션이 실행될 때 생성된다.

멀티 프로세스, 멀티 스레드

  • 멀티 프로세스는 여러 개의 독립된 프로세스를 생성하여 각각의 메모리 공간을 가지고 병렬로 동작
  • 멀티 스레드는 하나의 프로세스 내에서 여러 스레드가 메모리 자원을 공유하며 동작

CPU의 동작

CPU는 하나의 프로세스만을 담당하는 것이 아니라, 컴퓨터에서 실행된 모든 프로그램의 동작을 담당해야 한다.

CPU는 여러 프로그램을 동시에 처리하는 것처럼 보이지만, 사실은 매우 짧은 시간 간격으로 각 프로세스의 작업을 번갈아가며 처리하고 있다. 이 때 각 프로세스는 자신이 중단된 지점의 상태, 즉 레지스터, 스택 포인터, 프로그램 카운터 등의 정보를 저장하고, 다른 프로세스의 상태를 불러와 실행을 이어간다. 이 정보를 Context(문맥) 라고 한다.

Context Switching(문맥 교환)

문맥 교환(Context Switching)은 여러 프로세스나 스레드가 CPU를 사용할 수 있도록 문맥을 저장하고 불러오는 작업을 의미한다. 이 과정에서 실행 중인 프로세스의 상태를 저장하고 다른 프로세스의 상태를 복원하는 작업이 필요하므로 일정한 오버헤드(비용) 가 발생한다. 따라서 병렬 처리를 통해 성능을 개선하려면, 문맥 교환의 빈도와 그로 인한 오버헤드가 전체 성능에 미치는 영향을 신중하게 고려해야 한다.

반응형

'공부 > CS' 카테고리의 다른 글

아키텍처 간략 정리  (0) 2025.01.05
언어별 연산 속도  (0) 2024.12.30
해시 - 솔트치기  (0) 2024.08.25
CGI, FastCGI  (1) 2024.07.23
Web Server  (0) 2024.07.22

+ Recent posts