Git은 버전 관리 시스템으로 개발 프로젝트의 소스 코드를 효과적으로 관리할 수 있게 해줍니다

그러나 모든 파일을 버전 관리에 포함하는 것은 필요하지 않을 때가 있습니다

예를 들어 개발 환경 설정 파일이나 빌드된 파일들은 보통 버전 관리에 포함되지 않아야 합니다

이러한 파일들을 Git으로 추적하지 않도록 설정하는데 사용되는 것이 .gitignore 파일입니다

 

.gitignore 파일 작성 방법

파일 및 폴더 지정

.gitignore 파일에 추적하지 않을 파일 또는 폴더를 지정합니다

각 줄에 하나의 파일 또는 폴더를 작성합니다

# 개발 환경 설정 파일
config.properties

# 빌드된 파일 폴더
build/

패턴 사용

.gitignore 파일에서는 와일드카드와 패턴을 사용하여 여러 파일을 한꺼번에 지정할 수 있습니다

# 모든 .log 파일
*.log

# 특정 폴더의 모든 하위 폴더 및 파일
logs/

주의 사항

  • .gitignore 파일은 Git 저장소의 루트 디렉토리에 위치해야 합니다
  • .gitignore 파일에 추가된 파일이더라도 Git에서 이미 추적중이라면 계속 추적하게 됩니다

.gitinore 파일 예제

# IDE 및 편집기 설정 파일
.idea/
.vscode/

# 빌드된 파일 및 디렉토리
build/
target/

# 로그 파일
*.log

config 파일

  1. 특징
    설정 값들을 특정 형식의 파일에 저장하는 방식
    주로 프로퍼티 파일(.properties), YAML 파일(.yml), JSON 파일(.json) 등을 사용한다
  2. 장점
    관리와 유지보수가 용이하다 . 설정 값들을 하나의 파일에 모아두기 때문에 코드와 분리되어 있어 변경이 쉽다
    배포와 환경 전환이 간편하다. 다른 환경으로의 전환 시 파일만 변경하면 되므로 유연한 운용이 가능하다
  3. 단점
    보안에 취약하다. 보안이 필요한 정보를 평문으로 저장하므로 노출될 경우 보안 문제가 발생할 수 있다

DB

  1. 특징
    설정 값을 데이터베이스에 저장하는 방식
    주로 관리자 설정, 시스템 설정 등의 정보를 저장한다
  2. 장점
    보안이 강화된다. 데이터베이스에 저장되므로 접근 제어와 암호화 등의 보안 수준을 높일 수 있다
    확장성이 높다. 대용량 데이터를 처리할 수 있고, 여러 서비스에서 공유하기 용이하다
  3. 단점
    성능 저하가 발생할 수 있다. DB 조회 시 시간이 소요되므로 설정 값의 빈번한 참조는 성능 저하를 야기할 수 있다
    별도의 관리가 필요하다. 데이터베이스 연결, 트랜잭션 관리 등 추가적인 작업이 필요하다

arg 변수로 입력

  1. 특징
    프로그램 실행 시 인자로 설정 값을 전달하는 방식
    명령행 인터페이스(CLI) 또는 실행 환경에서 직접 입력받는다
  2. 장점
    간편하다. 설정 값을 변경하려면 프로그램을 다시 빌드할 필요 없이 인자를 변경하면 된다
    테스트에 용이하다. 다양한 설정 값을 쉽게 시뮬레이션하고 테스트할 수 있다
  3. 단점
    관리가 어렵다. 실행할 때마다 설정 값을 일일히 입력해야 하므로 실수가 발생할 수 있다
    보안에 취약하다. 민감한 정보가 명령행에 노출될 수 있어 보안 문제가 발생할 수 있다

환경변수

  1. 특징
    운영 체제 또는 실행 환경에 설정되어 있는 값
    주로 운영 시스템이나 컨테이너에서 설정한다
  2. 장점
    보안에 용이하다. 환경변수는 보안에 민감한 정보를 안전하게 보관할 수 있는 방법 중 하나이다
    확장성이 좋다. 환경변수를 이용하여 다양한 환경에서 설정 값을 동적으로 관리할 수 있다
  3. 단점
    관리가 어렵다. 많은 환경변수가 설정되어 있을 경우 관리가 복잡해질 수 있다
    사용자가 변경하기 어렵다. 일반 사용자는 환경변수를 직접 수정하는 것이 어려울 수 있다

코드에 작성

  1. 특징
    설정 값을 코드 내에 하드코딩하는 방식
    직접 코드를 수정하여 설정 값을 변경한다
  2. 장점
    빠르게 접근할 수 있다. 설정 값을 변경할 필요 없이 코드를 수정하여 즉시 적용할 수 있다
    파일 또는 DB와 같은 외부 의존성이 없다
  3. 단점
    유지보수가 어렵다. 설정 값이 코드에 하드코딩되어 있기 때문에 변경이 필요할 때마다 코드를 수정해야 한다
    배포와 관리가 번거롭다. 설정 값이 코드와 결합되어 있기 때문에 변경 시 프로그램을 재배포해야 한다

의존성 주입(Dependency Injection, DI)은 현대 소프트웨어 개발에서 중요한 개념 중 하나입니다

이는 객체 간의 결합을 최소화하고 유연성을 향상시키는 데 큰 역할을 합니다

이번 글에서는 의존성 주입의 개념과 종류에 대해 알아보도록 하겠습니다

 

의존성 주입이란?

의존성 주입은 객체 간의 의존성을 외부에서 제공되는 방식으로 주입하는 걸 의미합니다

이는 객체가 직접 의존하는 객체를 생성하거나 참조하는 대신 외부에서 의존성을 주입받아 사용함으로써 결합도를 낮추고 재사용성과 테스트 용이성을 높입니다

종류

  • 생성자 주입(Constructor Injection)
    생성자 주입은 의존성을 객체 생성 시에 생성자를 통해 주입하는 방식입니다
    이는 객체가 생성될 때 의존성이 필요하다는 것을 명시적으로 표현합니다
    주로 사용되는 방식 중 하나로, 객체의 생성과 의존성 주입을 동시에 처리할 수 있습니다
  • 세터 주입(Setter Injection)
    세터 주입은 객체의 세터 메서드를 통해 의존성을 주입하는 방식입니다
    이는 생성자 주입과 달리 객체 생성 이후에 의존성을 주입받을 수 있습니다
    주로 선택적인 의존성을 가지는 경우나 런타임에 의존성이 변경될 수 있는 경우에 사용됩니다
  • 인터페이스 주입(Interface Injection)
    인터페이스 주입은 인터페이스를 통해 의존성을 주입하는 방식입니다
    의존성 주입을 위한 별도의 인터페이스를 정의하고 해당 인터페이스를 구현하는 방식입니다

장점

  1. 결합도 감소
    객체가 직접 의존성을 생성하거나 참조하지 않고 외부에서 주입받기 때문에 객체 간의 결합도를 낮출 수 있습니다
  2. 유연성 향상
    의존성이 외부에서 주입되므로 런타임에 다른 의존성을 주입하여 동작을 변경할 수 있습니다
  3. 테스트 용이성
    의존성을 주입하여 모의 객체(mock object)를 사용하여 테스트하기 쉽습니다

관점 지향 프로그래밍이란?

관점 지향 프로그래밍(Aspect-Oriented Programming, AOP)은 프로그래밍에서 다양한 관점을 분리하여 모듈화하고, 각 과점에 맞게 모듈을 조합하는 것을 강조하는 프로그래밍 패러다임입니다

이것은 소프트웨어 개발에서 반복되는 공통 관심사(예: 로깅, 트랜잭션 관리, 보안 등)을 캡슐화하고 분리함으로써 코드의 가독성, 유지보수성, 재사용성을 향상시킵니다

핵심 개념

  • 관점(Aspect)
    관점은 어플리케이션에서 수행되는 여러 작업들의 모듈화된 관심사를 나타냅니다
    예를 들어, 로깅은 하나의 관점일 수 있습니다
  • 조인 포인트(Join Point)
    관점이 적용된 수 있는 어플리케이션 실행 중의 특정 지점을 가리킵니다
    메서드 호출, 예외 발생 등이 조인 포인트의 예시입니다
  • 어드바이스(Advice)
    관점이 어떻게 적용되는지를 나타냅니다
    어드바이스는 조인 포인트에서 실행되는 코드 조각으로, 예를 들어 특정 메서드 호출 이전에 로그를 출력하는 등의 동작을 수행할 수 있습니다
  • 포인트컷(Pointcut)
    어떤 조인 포인트에 어드바이스를 적용할지를 결정하는 규칙입니다
    이는 특정 메서드 호출이나 패키지 내의 모든 클래스 등을 포함할 수 있습니다

관점 지향 프로그래밍의 장점

  1. 모듈화와 재사용성
    공통 관심사를 분리함으로써 모듈화되어 코드의 재사용성을 향상시킵니다
  2. 가독성과 유지보수성
    각 관점이 분리되어 있기 때문에 코드의 가독성과 유지보수성을 향상시킵니다
    예를 들어, 로깅 관점은 각 메서드에 로그 출력 코드를 추가하는 대신 로깅 관점만 수정하여 변경할 수 있습니다
  3. 비즈니스 로직 분리
    핵심 비즈니스 로직과 다양한 관점(예: 보안, 트랜잭션 관리)을 분리하여 관리할 수 있습니다

1. 목적과 활용

싱글톤 패턴은 어떤 클래스가 단 하나의 인스턴스만을 갖도록 하고, 그 인스턴스에 대한 전역적인 접근을 제공하는 디자인 패턴입니다

이는 특정 객체가 시스템 전체에서 공유되어야 하거나, 유일한 자원을 효율적으로 활용해야 하는 경우에 유용하게 쓰입니다

예를 들어, 데이터베이스 연결, 로깅, 설정 관리 등의 경우에 싱글톤 패턴이 적용될 수 있습니다

 

2. 싱글톤의 특징

유일한 인스턴스

싱글톤 패턴을 사용하는 클래스는 인스턴스가 하나뿐이어야 합니다

이는 private 생성자를 통해 외부에서의 객체 생성을 막고, 유일한 인스턴스를 유지함으로써 달성됩니다

 

전역적인 접근

어디서든지 해당 인스턴스에 접근 가능해야 합니다

이는 주로 `getInstance()`와 같은 정적 메서드를 통해 구현되며, 이 메서드를 통해 언제든지 유일한 인스턴스에 접근할 수 있습니다

 

3. 초기화 시점

즉시 초기화

클래스 로딩 시점에 인스턴스를 생성하는 방식입니다

단점으로는 애플리케이션이 시작될 때 무조건 인스턴스가 생성되므로, 불필요한 자원 소모가 발생할 수 있습니다

 

늦은 초기화

인스턴스가 필요한 시점에 생성하는 방식입니다

하지만 멀티스레딩 환경에서는 동기화 문제로부터 안정성을 보장하기 위해 추가적인 처리가 필요합니다

 

4. 멀티스레딩과의 대응

멀티스레딩 환경에서는 여러 스레드가 동시에 인스턴스를 생성하려는 시나리오가 발생할 수 있습니다

이를 해결하기 위해 동기화 처리가 필요하며, 이로 인한 성능 저하를 최소화하기 위해 더블 체크 락킹 등의 기법을 활용할 수 있습니다

 

 

팩토리 패턴의 개념

팩토리 패턴은 객체를 생성하는 인터페이스를 정의하고, 이를 통해 객체의 생성을 캡슐화하는 패턴입니다

즉, 어떤 클래스의 인스턴스를 만들지에 대한 결정을 서브클래스에 위임하는 것입니다

이는 객체의 생성과 사용을 분리함으로써 코드의 유연성을 향상시킵니다

 

구성 요소

1. 제품 인터페이스 (Product Interface)

팩토리 패턴에서 생성될 객체들의 공통 인터페이스를 정의합니다

이 인터페이스를 통해 클라이언트 코드는 구체적인 제품의 클래스를 알 필요 없이 해당 제품을 사용할 수 있습니다

 

2. 제품 클래스 (Product Class)

팩토리 패턴에서 생성될 구체적인 제품 클래스들을 구현합니다

이 클래스들은 공통된 제품 인터페이스를 따라야 합니다

 

3. 팩토리 인터페이스 (Factory Interface)

객체 생성을 위한 인터페이스를 정의합니다

이 인터페이스에는 객체를 생성하는 메서드가 선언되어 있습니다

 

4. 팩토리 클래스 (Factory Class)

객체의 생성을 책임지는 클래스로, 팩토리 인터페이스를 구현합니다

이 클래스에서는 어떤 구체적인 제품 클래스의 인스턴스를 생성할지를 결정합니다

 

팩토리 패턴의 장점

1. 객체 생성의 캡슐화

클라이언트 코드는 객체의 생성 방식을 알 필요가 없으며, 단지 팩토리 인터페이스를 통해 객체를 생성할 수 있습니다

이로써 객체 생성의 세부사항이 숨겨지고 유지보수가 용이해집니다

 

2. 클라이언트 코드의 단순화

클라이언트 코드에서는 구체적인 제품 클래스를 직접 참조하지 않고, 팩토리 인터페이스를 통해 객체를 생성하므로 코드가 단순해집니다

 

3. 확장성과 유연성

새로운 제품 클래스를 추가하거나 기존 클래스를 변경하지 않고도 팩토리 클래스를 확장하여 새로운 객체를 생성할 수 있습니다

 

// 제품 인터페이스
interface Product {
    void doSomething();
}

// 제품 클래스 1
class ConcreteProduct1 implements Product {
    public void doSomething() {
        System.out.println("Product 1 is doing something.");
    }
}

// 제품 클래스 2
class ConcreteProduct2 implements Product {
    public void doSomething() {
        System.out.println("Product 2 is doing something.");
    }
}

// 팩토리 인터페이스
interface Factory {
    Product createProduct();
}

// 팩토리 클래스 1
class ConcreteFactory1 implements Factory {
    public Product createProduct() {
        return new ConcreteProduct1();
    }
}

// 팩토리 클래스 2
class ConcreteFactory2 implements Factory {
    public Product createProduct() {
        return new ConcreteProduct2();
    }
}

// 클라이언트 코드
public class Client {
    public static void main(String[] args) {
        Factory factory1 = new ConcreteFactory1();
        Product product1 = factory1.createProduct();
        product1.doSomething();

        Factory factory2 = new ConcreteFactory2();
        Product product2 = factory2.createProduct();
        product2.doSomething();
    }
}

CDN(콘텐츠 전송 네트워크)는 현대 웹 개발에서 빠질 수 없는 중요한 요소 중 하나입니다

이 글에서는 CDN이 무엇이며, 프로그래밍 세계에서 어떻게 활용되고 있는지에 대해 알아보겠습니다

 

CDN이란?

CDN은 콘텐츠 전송 네트워크(Content Delivery Network)의 약어로, 전 세계 여러 지역에 분산된 서버 네트워크를 통해 웹 콘텐츠를 더 효율적으로 전달하는 기술입니다

이는 웹 페이지의 성능을 향상시키고, 사용자에게 빠르고 안정적인 경험을 제공하는 데 도움이 됩니다

 

CDN의 장점

  1. 로드 타임 감소: CDN은 사용자에게 가까운 서버를 사용하여 웹 페이지의 로드 타임을 감소시킵니다
  2. 대역폭 최적화: CDN은 대역폭을 효율적으로 사용하여 서버 부하를 분산시키고, 빠른 데이터 전송을 지원합니다
  3. 보안 강화: 일부 CDN은 보안 기능을 내장하고 있어 DDoS 공격 등을 방어하는 데 도움이 됩니다
  4. 고가용성 및 신뢰성: CDN은 여러 지역에 서버를 분산시키므로 단일 서버의 장애가 전체 서비스에 영향을 미치는 것을 방지합니다

 

프로그래밍에서의 CDN 활용

  1. 정적 파일 제공: CDN은 주로 정적 파일(이미지, 스타일시트, 자바스크립트 등)을 더 빠르게 제공하기 위해 사용됩니다. 프로그래머는 웹 애플리케이션에서 이러한 파일들을 CDN을 통해 쉽게 호스팅하고 활용할 수 있습니다
  2. 라이브러리 및 프레임워크 로딩: 많은 프레임워크와 라이브러리는 CDN을 통해 호스팅되어 있어, 프로그래머들은 이를 활용하여 라이브러리를 더 빠르게 로딩할 수 있습니다. 예를 들면, jQuery나 Bootstrap과 같은 라이브러리를 CDN을 통해 불러올 수 있습니다
  3. 동적 컨텐츠 캐싱: 일부 CDN은 동적 컨텐츠까지 캐싱하여 동적 데이터의 전송 속도를 향상시킵니다. 이는 프로그래밍에서 동적인 내용을 가진 웹 애플리케이션에서 특히 유용합니다

응집도 (Cohesion)

응집도는 모듈 내부의 요소들이 서로 얼마나 관련되어 있는지를 측정하는 것입니다

높은 응집도는 모듈 내의 요소들이 서로 긴밀하게 관련되어 있음을 나타내며, 모듈이 한 가지 기능이나 목적을 가지고 있음을 의미합니다

 

높은 응집도는 모듈을 이해하고 유지보수하기 쉽게 만들어줍니다

또한 모듈이 특정 기능에 집중하므로 재사용성이 증가하고 버그를 찾아내기 쉬워집니다

 

결합도 (Coupling)

결합도는 모듈 간의 상호 의존성을 나타냅니다

낮은 결합도는 모듈 간의 의존성이 낮음을 의미하며, 각 모듈이 독립적으로 존재할 수 있다는 것을 나타냅니다

 

서로 다른 모듈 간에 직접적인 데이터 교환 없이 인터페이스를 통해 통신하는 경우, 결합도는 낮다고 볼 수 있습니다

 

낮은 결합도는 모듈 간의 독립성을 증가시켜 변경이나 업그레이드가 쉬워지며, 모듈 간의 오류 전파를 방지합니다

또한, 모듈을 독립적으로 테스트할 수 있게 만듭니다

 

결론

응집도는 모듈 내부의 강도를 특정하고, 결합도는 모듈 간의 상호 의존성을 측정합니다

높은 응집도와 낮은 결합도는 이상적인 상태입니다

모듈은 자체적으로 강하게 구성되어 있으면서 다른 모듈과의 의존성이 최소화되어야 합니다

높은 응집도와 낮은 결합도를 모두 달성하는 것이 이상적입니다

하지만 어떤 경우에는 응집도를 높이기 위해서는 결합도를 어느 정도 희생해야 할 수도 있습니다

 

1. 크롤링

크롤링은 웹 페이지를 자동으로 돌며 웹 페이지의 링크를 추출하고, 이를 기반으로 다른 페이지로 이동하면서 데이터를 수집하는 프로세스입니다. 크롤러 또는 스파이더라고 불리는 프로그램이 여러 웹 페이지를 돌며 데이터를 수집하는 것이 크롤링의 핵심입니다

 

2. 스크래핑

스크래핑은 특정 웹 페이지에서 필요한 데이터를 추출하는 과정을 의미합니다. 크롤링으로 얻은 여러 웹 페이지 중에서 스크래핑을 통해 원하는 정보만을 추출하여 활용할 수 있습니다. 스크래핑은 HTML 태그를 분석하고 원하는 데이터를 추출하는 기술을 사용합니다

 

3. 크롤링의 스크래핑의 차이

목적

- 크롤링: 다수의 웹 페이지를 돌며 링크를 추출하고 새로운 페이지로 이동하는 것이 주된 목적입니다

- 스크래핑: 특정 웹 페이지에서 필요한 데이터를 추출하는 것이 주된 목적입니다

 

프로세스

- 크롤링: 여러 웹 페이지를 돌며 링크를 추출하고 새로운 페이지로 이동하여 계속해서 데이터를 수집합니다

- 스크래핑: 특정 웹 페이지의 HTML을 분석하여 원하는 데이터를 추출합니다

 

데이터의 규모 

- 크롤링: 대량의 데이터를 수집하는 데 주로 사용되며, 다양한 웹 페이지를 대상으로 합니다

- 스크래핑: 특정 웹 페이지에서 소량의 데이터를 추출하는 데 주로 사용되며, 목적에 맞게 정확한 정보를 추출합니다

 

기술적 측면

- 크롤링: 링크 추출, 다중 페이지 이동, 로봇 배제 프로토콜 등이 중요한 기술입니다

- 스크래핑: HTML 파싱, 정규표현식, 데이터 추출 알고리즘 등이 중요한 기술입니다

프로그래밍 개발은 복잡한 프로세스로, 효과적인 팀 협업과 소프트웨어의 원활한 개발을 위해 다양한 설계서와 명세서가 필요합니다

이 글에서는 주요 설계서와 명세서에 대해 살펴보겠습니다

 

요구사항 명세서

프로젝트의 출발점은 목적과 범위를 정의하는 단계입니다

이를 위해 요구사항 명세서가 사용되며, 프로젝트의 기능과 비기능적 요구사항을 명확히 정의하여 이해관계자 간의 의사소통을 원활하게 합니다

 

시스템 설계서

프로젝트의 구조를 결정하는 시스템 설계서는 시스템 아키텍처, 모듈, 그리고 컴포넌트의 상세 설계를 다룹니다

테이터베이스, 사용자 인터페이스, 시스템 흐름 등이 이 문서에 포함됩니다

 

기능 명세서

각 기능에 대한 세부적인 설명과 동작 방식을 다루는 기능 명세서는 개발자들이 소프트웨어의 각 부분을 구현할 때 참고하는 중요한 문서입니다

 

기술 명세서

기술 명세서는 소프트웨어 개발에 사용되는 기술적인 측면에 대한 세부 사항을 다룹니다

데이터베이스 스키마, 프로그래밍 언어, 프레임워크, 서버 구성 등이 여기에 속합니다

 

테스트 계획서

품질을 보장하기 위한 테스트 전략과 테스트 케이스를 정의하는 테스트 계획서는 시스템이 기대한 대로 동작하는 지 확인하는 데 중요합니다

 

사용자 매뉴얼

사용자를 위한 사용 방법에 대한 지침을 담은 사용자 매뉴얼은 최종 사용자가 소프트웨어를 효과적으로 활용할 수 있도록 도와줍니다

 

유지보수 문서

유지보수를 위한 문서는 코드 구조, 변경 이력, 버그 수정 내역 등을 포함하여 소프트웨어를 지속적으로 개선하는 데 필요한 정보를 제공합니다

 

객체 지향 프로그래밍의 상속, 캡슐화, 다형성, 추상화,, 들어도 들어도 헷갈려서 정리했습니다

 

상속

상속은 OOP의 중요한 특징 중 하나로, 기존 클래스의 특성을 그대로 이어받아 새로운 클래스를 생성하는 메커니즘입니다

상속을 통해 코드의 재사용성을 높일 수 있고, 코드 중복을 최소화할 수 있습니다

부모 클래스의 속성과 메서드를 자식 클래스가 물려받아 사용할 수 있으며, 자식 클래스에서는 필요에 따라 새로운 기능을 추가하거나 부모 클래스의 기능을 재정의할 수 있습니다

 

class Animal {
    void speak() {
        System.out.println("Animal speaks");
    }
}

class Dog extends Animal {
    void speak() {
        System.out.println("Dog barks");
    }
}

// 사용 예시
Dog myDog = new Dog();
myDog.speak();  // 출력: Dog barks

 

캡슐화

캡슐화는 객체의 상태와 행위를 하나로 묶고, 외부에서의 접근을 제어하는 것을 의미합니다

이는 정보 은닉을 통해 객체의 내부 구현을 외부로부터 숨기고, 오직 정의된 인터페이스를 통해서만 객체와 상호작용할 수 있도록 하는 것입니다

캡슐화는 코드의 모듈성을 높이고, 객체 간의 결합도를 낮춰 시스템을 유연하게 만듭니다

 

class Car {
    private int speed;  // 속성을 비공개로 설정

    int getSpeed() {
        return speed;
    }

    void setSpeed(int newSpeed) {
        if (newSpeed > 0) {
            speed = newSpeed;
        }
    }
}

// 사용 예시
Car myCar = new Car(60);
System.out.println(myCar.getSpeed());  // 출력: 60
myCar.setSpeed(80);
System.out.println(myCar.getSpeed());  // 출력: 80

 

다형성

다형성은 같은 인터페이스를 공유하면서 다양한 구현을 가질 수 있는 능력을 의미합니다

다형성은 코드의 유연성을 향상시키면, 동일한 메서드 호출에 대해 다른 동작을 수행할 수 있도록 합니다

이는 메서드 오버로딩과 메서드 오버라이딩을 통해 구현됩니다

 

abstract class Shape {
    abstract double area();
}

class Circle extends Shape {
    private double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    double area() {
        return 3.14 * radius * radius;
    }
}

class Rectangle extends Shape {
    private double length;
    private double width;

    Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }

    double area() {
        return length * width;
    }
}

// 사용 예시
Circle circle = new Circle(5);
Rectangle rectangle = new Rectangle(4, 6);
System.out.println(circle.area());      // 출력: 78.5
System.out.println(rectangle.area());   // 출력: 24

 

추상화

추상화는 복잡한 시스템에서 중요한 부분을 간추려 표현하는 과정입니다

이는 사용자에게 필요한 정보만을 제공하고 나머지는 숨겨짐으로써 시스템을 더 이해하기 쉽게 만듭니다

추상화는 클래스와 인터페이스를 통해 구현되며, 불필요한 세부사항을 숨기고 핵심 기능에만 집중할 수 있도록 도와줍니다

 

abstract class Shape {
    abstract double area();
}

class Circle extends Shape {
    private double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    double area() {
        return 3.14 * radius * radius;
    }
}

class Rectangle extends Shape {
    private double length;
    private double width;

    Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }

    double area() {
        return length * width;
    }
}

// 사용 예시
Circle circle = new Circle(5);
Rectangle rectangle = new Rectangle(4, 6);
System.out.println(circle.area());      // 출력: 78.5
System.out.println(rectangle.area());   // 출력: 24

JAVA 책으로 공부중인데 앞 쪽에 JAVA의 특징으로 멀티스레드가 언급되어 있었습니다

동시성과 병렬성에 대해서도 잠깐 언급되어 있는데

이 두 개념은 봐도봐도 헷갈립니다

 

그래서 이를 정리해봤습니다

 

동시성

동시성은 여러 작업이 동시에 진행되는 것처럼 보이게 하는 개념입니다

이는 시간상으로 겹치는 것처럼 보이지만, 실제로는 동시에 실행되지 않을 수 있습니다

프로그램이 여러 작업을 동시에 다루는 것을 통해, 시스템의 응답성을 향상시키고 작업을 더 효율적으로 다룰 수 있습니다

 

병렬성

병렬성은 여러 작업이 동시에 실행되는 개념으로, 실제로 동시에 여러 작업이 처리됩니다

주로 다중 코어 또는 다중 프로세서 시스템에서 성능을 극대화하기 위해 사용됩니다

 

차이점

- 실행 방식: 동시성은 하나의 프로세스 내에서 여러 스레드가 번갈아가면 실행되지만 병렬성은 여러 프로세스나 스레드가 동시에 실행됩니다

- 목적: 동시성은 주로 입출력 바운드 작업에 유용하며, 병렬성은 CPU 바운드 작업에 유용합니다

 

+ Recent posts