< 교착 상태(Dead Lock) ? >

컴퓨터 시스템에서 프로세스(일련의 명령어로 구성된 작업)를 실행하려면 여러 가지 리소스(메모리, CPU 시간, 디스크 공간 등)가 필요하다. 시스템은 이러한 리소스를 프로세스에 순차적으로 할당하며, 프로세스가 작업을 완료하면 사용한 리소스는 시스템에 다시 반납된다.

그러나 여러 프로세스가 동시에 실행되는 시스템에서는 복잡한 상황이 발생할 수 있다. 이를 이해하기 위해 간단한 예시로, 세 가지 프로세스 P1, P2, P3와 세 가지 리소스 R1, R2, R3이 있다고 가정해보자. 이 시점에서 각각의 프로세스는 이미 하나의 리소스를 할당 받았다고 가정하자: P1은 R1, P2는 R2, P3는 R3을 갖고 있다고 가정.

그런데 이후에 추가적인 리소스를 필요로 하는 상황이 발생하였다. P1이 R2를 필요로 하고, P2가 R3를 필요로 하며, 마지막으로 P3는 R1을 필요로 하게되었다.

문제는 이제 각 프로세스가 필요로 하는 리소스가 이미 다른 프로세스에게 할당되어 있어서 사용할 수 없는 상황이다. 따라서, 모든 프로세스들은 각자 필요한 리소스가 반납될 때까지 대기 상태에 빠지게 되며, 이는 데드락이라는 현상으로 이어져버린다. 데드락은 프로세스들이 더 이상 진행할 수 없는 상태로, 시스템 성능에 심각한 영향을 미치게 된다.

교착 상태를 표현한 상황, P1 프로세스는 R2자원이 끝나길 기다리고 있고, P2 프로세스는 자원 R2를 할당 받은 채 R3의 자원이 끝나길 기다리는 상황

 

< 데드락 발생 조건 >

데드락이 발생하려면 아래와 같은 네 가지 조건이 만족되어야 한다.

Mutual Exclusion (상호 배제) : 리소스는 한 번에 한 프로세스만 사용할 수 있다.
Hold and Wait (점유와 대기) : 프로세스는 이미 할당된 리소스를 가진 상태에서 다른 리소스를 기다린다.
No Preemption (비선점) : 한 프로세스가 이미 점유하고 있는 리소스를 다른 프로세스가 강제로 빼앗을 수 없다.
Circular Wait (원형 대기) : 프로세스 A, B, C가 있을 때 A는 B가 가진 리소스를, B는 C가 가진 리소스를, C는 A가 가진 리소스를 기다리는 상황을 말한다.

 

프로세스 간의 관계를 그래프로 도식화해 보면 데드락이 발생할지 예상할 수 있다. 이 그래프를 Resource-Allocation Graph(자원 할당 그래프)라고 한다. 예시를 하나 살펴보자.

R은 자원이고 P는 프로세스를 의미한다. 자원 내의 동그라미는 자원(인스턴스)의 개수이다. 

자원 → 프로세스로 향하는 간선은 해당 자원을 프로세스가 보유 중(Allocate)이라는 의미이고, 프로세스 → 자원으로 향하는 간선은 프로세스가 해당 자원을 요청(Request)했다는 의미이다. 

만약 그래프에 사이클(Cycle)이 없다면 Deadlock이 아니다. 반면, 사이클이 있다면 Deadlock이 발생할 '수' 있다. 

정확히 말하면, 자원당 하나의 인스턴스만 있는 경우엔 Deadlock이고, 여러 인스턴스가 존재하는 경우엔 Deadlock일 수도 있고 아닐 수도 있다. 
위의 그림에서는 왼쪽 그래프는 Deadlock이지만, 오른쪽 그래프는 Deadlock이 아니다. 

Deadlock문제를 해결하기 위한 방법으로는 대표적으로 미리 예방하는 방법(Prevention)과 Deadlock이 발생하지 않도록 피하는 방법(Avoidance), 그리고 발생했을 때 처리하는 방법(Detection and Recovery), 무시하는 방법(Ignorance) 총 네 방법으로 나뉜다. 


이 네 가지 조건 중에서 하나라도 만족되지 않으면 데드락은 발생하지 않는다.

< 데드락 해결 방법 >


그렇다면 이러한 데드락을 어떻게 해결할 수 있을까? 데드락을 처리하는 방법에는 크게 세 가지가 있다.

 

1.데드락 예방, 2. 데드락 회피,3. 데드락 복구가 있다.

[데드락 예방]
데드락 예방은 데드락 발생 조건 중 하나를 만족시키지 않도록 하여 데드락이 발생하지 않도록 하는 방법이다. 하지만 이 방법은 장치 효율과 시스템 성능을 떨어트릴 수 있다.

[데드락 회피]
데드락 회피는 데드락이 발생할 것 같을 때는 아예 리소스를 할당하지 않는 방법이다. 이 방법은 시스템 상태를 항상 안전한 상태로 유지하는 것이 중요하며, 리소스 할당 그래프를 통해 데드락 가능성을 판단한다. 만약 리소스 타입이 여러 개라면 은행원 알고리즘(Banker's Algorithm)을 사용한다.

[데드락 복구]
데드락 복구는 데드락이 발생한 후에 어떤 프로세스를 중단시킬지 결정하는 것이. 여기에는 프로세스의 중요도, 실행 시간, 사용 리소스 양, 필요 리소스 양 등 다양한 판단 기준이 있다.

[리소스 선점]
데드락을 해결하기 위해 리소스 선점 방식을 사용할 수도 있다. 하지만 이 경우 어떤 프로세스를 중단시킬지 결정하는 것이 중요하며, 데드락 발생 전 상태로 되돌리는 rollback 과정이 필요하다. 그리고 계속 같은 프로세스가 중단되는 starvation 문제를 피해야 한다.

 

 

Reference : https://www.javatpoint.com/os-deadlocks-introduction

 

What is Deadlock in Operating System (OS)? - javatpoint

What is Deadlock in Operating System (OS)? with Definition and functions, OS Tutorial, Types of OS, Process Management Introduction, Attributes of a Process, Process Schedulers, CPU Scheduling, SJF Scheduling, FCFS with overhead, FCFS Scheduling etc.

www.javatpoint.com

https://parksb.github.io/article/11.html

 

🦕 공룡책으로 정리하는 운영체제 Ch.7: Deadlocks

Operating System Concepts Ch.7 DeadlocksCh.6 Synchronization에서 잠시 언급했듯이 데드락은 프로세스가 리소스를 점유하고 놓아주지 않거나, 어떠한 프로세스도 리소스를 점유하지 못하는 상태가 되어 프로

parksb.github.io

 

 

'컴퓨터구조,운영체제' 카테고리의 다른 글

명령어 사이클과 인터럽트  (0) 2023.06.07
CPU 레지스터(Register)  (0) 2023.06.07
동기화 기법(뮤텍스 락,세마포,모니터)  (0) 2023.06.07
프로세스 동기화  (0) 2023.06.07
CPU 간편 소개  (0) 2023.04.25

※ 해당 글은 아래의 포스트를 읽은 다음, 읽는 것이 더 좋습니다. 

https://taeyoungcoding.tistory.com/345

 

프로세스 동기화

컴퓨터 환경에서 여러 프로세스가 동시에 실행될 때, 공동의 목적을 올바르게 수행하기 위해 서로 협력하고 영향을 주고 받는다. 예를 들어, 워드 프로세서에서는 사용자 입력을 받는 프로세스,

taeyoungcoding.tistory.com

프로세스의 동기화는 어떻게 이루어질까? 어떻게 해야 임계 구역에 오직 하나의 프로세스만 진입하게 하고, 올바른 실행 순서를 보장할 수 있을까? 이를 위해 동기화를 위한 대표적인 도구인 뮤텍스 락, 세마포,모니터가 있다. 

 

< 뮤텍스 락 (Mutex Lock) > 

뮤텍스 락은 프로세스의 동기화를 위한 가장 기본적인 도구이다. Mutex란 'Mutual Exclusion'의 약자로, 한 번에 하나의 프로세스만 공유 자원에 접근할 수 있게 하는 기법을 말한다. 이는 동시에 실행되는 여러 프로세스 또는 스레드가 동일한 자원을 동시에 사용하려 할 때 발생하는 경쟁 조건을 방지하는데 사용된다.

 

Java에서는 'synchronized' 키워드를 사용해 뮤텍스 락을 구현할 수 있고, Lock 인터페이스를 이용하는 방법이 있다. 

 

synchronized 키워드 : 이 키워드를 메서드 또는 블록 앞에 사용하면 해당 메서드는 블록에 동시에 하나의 스레드만 접근할 수 있다. 'synchronized' 키워드는 내부적으로 락을 관리하므로 사용자가 락을 명시적으로 획득하거나 해제하는 코드를 작성할 필요가 없다. 그러나 'synchronized' 키워드를 사용할 때는 잘못된 사용으로 인해 교착 상태(deadlock)이 발생할 가능성을 주의해야 한다.

 

[synchronized 키워드를 이용한 뮤텍스 락 구현 코드 1]

class SharedResource {
    synchronized void accessResource() {
        // 임계 영역
    }
}

[synchronized 키워드를 이용한 뮤텍스 락 구현 코드 2]

class SharedResource {
    synchronized void access(String threadName) {
        System.out.println(threadName + " is accessing shared resource");
        // 작동하는 코드 여기 넣기
        System.out.println(threadName + " is leaving shared resource");
    }
}

이 코드에서 synchronized 키워드는 한 번에 한 스레드만 'access'메서드를 실행할 수 있게 해준다. 이런 방식은 "영화관에서 한 번에 하나의 티켓만 팔 수 있다"는 개념과 유사하다.

 

 

Lock 인터페이스 (ReentrantLock 클래스): 

java.util.concurrent.locks 패키지에 있는 Lock 인터페이스와 그 구현체인 ReentrantLock 클래스를 사용하면 뮤텍스 락을 구현할 수 있다. 이 방법을 사용하면, 락의 획득과 해제를 명시적으로 제어할 수 있다. 또한, 'tryLock'메서드를 사용해 락을 시도적으로 획득할 수 있는 옵션이 있어 데드락을 피하는 데 도움이 될 수 있다.

 

[ReentrantLock 클래스를 구현해서 만든 뮤텍스 락]

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class SharedResource {
    private Lock lock = new ReentrantLock();

    void accessResource() {
        lock.lock();
        try {
            // 임계 영역
        } finally {
            lock.unlock();
        }
    }
}

< 세마포어 (Semaphore) >

세마포어는 뮤텍스 락과 비슷하게 공유 자원에 대한 접근을 제어한다. 그러나 세마포어는 한 번에 여러 개의 동일한 자원을 사용할 수 있는 프로세스나 스레드의 수를 제한할 수 있다. "한 번에 n 개의 티켓을 팔 수 있는 영화관"과 유사한 개념이다.

 

자바에서는 'Semaphore' 클래스를 사용해 세마포어를 구현할 수 있다.

import java.util.concurrent.Semaphore;

class SharedResource {
    private Semaphore semaphore = new Semaphore(3);

    void access(String threadName) {
        try {
            semaphore.acquire();
            System.out.println(threadName + " is accessing shared resource");
            // 여기다가 작동할 코드넣기
            System.out.println(threadName + " is leaving shared resource");
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

< 모니터 (Monitor) >

모니터는 뮤텍스 락과 세마포어를 확장한 개념이다. 모니터는 공유 자원에 대한 접근을 제어하는 동시에, 특정 조건을 만족할 때까지 프로세스나 스레드를 대기 상태로 만든다. 이것은 "영화가 시작할 때까지 대기실에서 기다리는 고객"과 유사한 개념이다.

C#에서는 Monitor 클래스를 사용해 모니터를 구현할 수 있다.

using System;
using System.Threading;

class SharedResource {
    private static readonly object _lock = new object();

    public void Access(string threadName) {
        Monitor.Enter(_lock);
        try {
            Console.WriteLine($"{threadName} is accessing shared resource");
            // do some work here
            Console.WriteLine($"{threadName} is leaving shared resource");
        } finally {
            Monitor.Exit(_lock);
        }
    }
}

 

Reference: https://www.guru99.com/mutex-vs-semaphore.html

 

Mutex vs Semaphore – Difference Between Them

Mutex vs Semaphore: The key difference between Mutex and Semaphore is that Mutex is a locking mechanism whereas Semaphore is a signaling mechanism.

www.guru99.com

혼자 공부하는 컴퓨터 구조+운영체제

https://product.kyobobook.co.kr/detail/S000061584886

 

혼자 공부하는 컴퓨터 구조+운영체제 | 강민철 - 교보문고

혼자 공부하는 컴퓨터 구조+운영체제 | 혼자 해도 충분합니다! 1:1 과외하듯 배우는 IT 지식 입문서42명의 베타리더 검증으로, ‘함께 만든’ 입문자 맞춤형 도서이 책은 독학으로 컴퓨터 구조와

product.kyobobook.co.kr

 

'컴퓨터구조,운영체제' 카테고리의 다른 글

CPU 레지스터(Register)  (0) 2023.06.07
교착 상태(Dead Lock)  (0) 2023.06.07
프로세스 동기화  (0) 2023.06.07
CPU 간편 소개  (0) 2023.04.25
Memory란?  (0) 2023.04.13

컴퓨터 환경에서 여러 프로세스가 동시에 실행될 때, 공동의 목적을 올바르게 수행하기 위해 서로 협력하고 영향을 주고 받는다. 예를 들어, 워드 프로세서에서는 사용자 입력을 받는 프로세스,입력된 내용의 맞춤법을 검사하는 프로세스, 그리고 그 내용을 화면에 출력하는 프로세스가 있다. 이러한 프로세스들은 각기 독립적이지만 공동의 목적을 위해 서로 협력한다.

이렇게 협력하여 실행되는 프로세스들을 올바르게 관리하기 위해 프로세스 동기화가 필요하다.

< 프로세스 동기화란? >

프로세스 동기화는 한마디로 말하자면, 여러 프로세스 사이의 실행 순서를 조정하는 것이다. 이를 통해 다음과 같은 두 가지 중요한 기능을 수행한다.

  • 실행 순서 제어 : 프로세스를 올바른 "순서대로" 실행하기
  • 상호 배제 : 동시에 접근해서는 안되는 자원에 하나의 프로세스만 접근하게 하기

※ 스레드 등 실행의 흐름을 갖는 모든 것도 동기화에 대상이며, 이를 통해 특정 자원에 한 개의 프로세스만 접근하게 하거나, 프로세스를 올바른 순서대로 실행하는 것을 보장한다.

< 동기화 예시 >

실행 순서 제어 예시: "Writer" 프로세스와 "Reader" 프로세스가 동시에 실행되고 있다고 가정해 보자. Writer 프로세스는 파일에 값을 쓰는 역할을 하고, Reader 프로세스는 해당 파일에서 값을 읽어 들이는 역할을 한다. 이 경우, Reader 프로세스가 Writer 프로세스가 파일에 값을 쓴 이후에야 실행될 수 있어야 한다. 이렇게 실행 순서를 제어하는 것이 프로세스 동기화의 첫 번째 요소이다.

상호 배제 예시: 두 프로세스가 동시에 한 계좌에 입금을 하는 상황을 생각해 보자. 프로세스 A2만 원을 입금하고, 프로세스 B5만 원을 입금한다. 이 두 프로세스가 동시에 계좌에 접근하면 잔액이 올바르게 갱신되지 않을 수 있다. 이런 상황을 방지하기 위해 한 번에 하나의 프로세스만 계좌에 접근할 수 있도록 하는 것이 상호 배제이다. 이것이 프로세스 동기화의 두 번째 요소이다.

 

프로세스 A가 실행되는 과정을 조금 더 자세히 표현해 보면 아래와 같이 나타낼 수 있다.

①계좌에 잔액을 읽어 들인다.

②읽어 들인 잔액에 2만 원을 더한다.

③더한 값을 저장한다.

 

마찬가지로 프로세스 B가 실행되는 과정은 아래와 같은 순서로 나타낼 수 있다.

①계좌의 잔액을 읽어 들인다.

②읽어 들인 잔액에 5만 원을 더한다.

③더한 값을 저장한다.

 

이제 프로세스 A와 B와 동시에 실행되었다고 가정해 보자. 당연히 실행 결과 17만 원이 계좌에 남을 것을 기대할 것이다. 하지만 동기화가 제대로 이루어지지 않은 경우 아래와 같이 전혀 엉뚱한 결과가 나올 수 있다.

 

 

왜 이런 일이 발생했을까? A와 B는 '잔액'이라는 데이터를 동시에 사용하는데, A가 끝나기도 전에 B가 잔액을 읽어 버렸기 때문에 엉둥한 결과가 나온 것이다. A와 B를 올바르게 실행하기 위해서는 한 프로세스가 잔액에 접근했을 때 다른 프로세스는 기다려야 한다. 아래와 같이 말이다.

이렇게 동시에 접근해서는 안 되는 자원에 동시에 접근하지 못하게 하는 것이 상호 배제를 위한 동기화 이다.

 

 

동시에 실행되는 프로세스나 스레드는 종종 공유 자원에 대한 접근이 필요하다. 이 공유 자원은 메모리,파일,데이터베이스 연결 등 다양한 형태를 가질 수 있다. 이런 공유 자원에 대한 접근이 잘못 관리되면 데이터 불일치와 같은 문제가 발생할 수 있다. 그래서 이를 방지하기 위해 프로세스 동기화를 통해 공유 자원에 대해 접근을 제어한다.

< 공유 자원과 임계 구역 >

공유 자원은 여러 프로세스나 스레드가 동시에 접근하려고 하는 자원이다. 이런 자원에 동시에 접근하면 데이터의 일관성이 깨질 수 있으므로, 이를 방지하기 위한 동기화 메커니즘이 필요하다.

 

이런 공유 자원을 접근하는 코드 영역을 임계 구역이라고 한다. 임계 구역은 한 번에 하나의 프로세스나 스레드만이 실행할 수 있어야 하는 부분이므로, 두 개 이상의 프로세스가 동시에 임계 구역을 실행하면 문제가 발생할 수 있다.

 

< 상호 배제 >

이러한 문제를 방지하기 위한 주요 동기화 기법 중 하나가 상호 배제 이다. 상호 배제는 한 번에 하나의 프로세스만이 임계 구역을 실행하도록 하는 동기화 기법이다. 상호 배제는 다양한 방법으로 구현될 수 있으며, 그 중 일부는 세마포어,뮤텍스,모니터 등의 동기화 메커니즘을 사용한다.

 

 

Reference : 혼자 공부하는 컴퓨터 구조+운영체제

https://product.kyobobook.co.kr/detail/S000061584886

 

혼자 공부하는 컴퓨터 구조+운영체제 | 강민철 - 교보문고

혼자 공부하는 컴퓨터 구조+운영체제 | 혼자 해도 충분합니다! 1:1 과외하듯 배우는 IT 지식 입문서42명의 베타리더 검증으로, ‘함께 만든’ 입문자 맞춤형 도서이 책은 독학으로 컴퓨터 구조와

product.kyobobook.co.kr

'컴퓨터구조,운영체제' 카테고리의 다른 글

교착 상태(Dead Lock)  (0) 2023.06.07
동기화 기법(뮤텍스 락,세마포,모니터)  (0) 2023.06.07
CPU 간편 소개  (0) 2023.04.25
Memory란?  (0) 2023.04.13
CPU 란  (0) 2023.04.05

< 가비지 컬렉션이란? >

Java에서 가비지 컬렉션(Garbage Collection, 이하 GC)은 프로그램이 동적으로 할당한 메모리를 자동으로 관리하는 과정이다. 이는 프로그래머의 잘못으로 인한 메모리 누수 및 메모리 부족 문제를 방지하는데 매우 중요한 역할을 한다.

C/C++과 같은 언어에서는 프로그래머가 객체를 생성하고 파괴하는 것을 직접 관리해야 하는데. 이 과정에서 프로그래머의 실수로 불필요한 객체가 제거되지 않는다면, 시간이 지남에 따라 메모리 공간이 부족해져 프로그램이 비정상적으로 종료될 수 있다. 이러한 문제를 방지하기 위해 Java에서는 GC라는 기능을 제공해준다. GC는 더 이상 사용되지 않는 객체를 자동으로 감지하여 메모리에서 제거하는 역할을 한다.

< 가비지 컬렉션의 원리 >

Java의 GC는 자동적으로 작동한다. 이 과정은 Heap 메모리를 살펴보고 사용 중인 객체와 사용하지 않는 객체를 구분하여 사용하지 않는 객체를 삭제하는 과정이다. 여기서 사용 중인 객체란 프로그램의 어떤 부분이라도 그 객체에 대한 참조를 가지고 있는 객체를 의미하며, 사용하지 않는 객체란 프로그램의 어떤 부분도 해당 객체를 참조하고 있지 않는 객체를 의미한다.

 

< 가비지 컬렉션의 동작 방식 >

Minor GC: 새로운 객체가 생성되면 처음에는 'Young Generation'이라는 힙 영역에 배치되고, 'Young Generation' 영역이 가득 차면, GC는 이 영역에서 더 이상 참조되지 않는 객체들을 제거하는 Minor GC를 수행한다.


Major GC (Full GC): Young 영역에서 오랫동안 살아남은 객체들은 'Old Generation' 영역으로 이동된다. 이 영역에서는 객체들이 덜 빈번하게 제거되기 때문에, GC는 주로 Minor GC에 비해 덜 빈번하게 발생하는 Major GC를 수행한다.

 

 


실제 프로그램에서는 GC가 실행되면, GC를 실행하는 스레드외에 나머지 스레드는 멈춘다.

Minor GC같은 경우 영역이 작기 때문에  잠깐 멈추는 것이기에 Impact가 적지만, 만약에 Old Generation이 가득 차서 Major GC가 발생하면 오래된 시간 동안 프로그램이 동작하지 않을 수 있다. 그러면 큰 문제가 생길 수 있기에 주의해야 한다. 

 

< GC로 인해 애플리케이션이 멈추는 시간을 최소화하는 방법 >

 

Heap 사이즈 조정: GC가 발생하는 주된 이유는 힙 메모리가 부족하기 때문이다. 따라서 힙 메모리를 적절하게 확장하는 것은 GC를 효과적으로 관리하는 방법 중 하나다. 하지만 너무 큰 힙 사이즈는 GC 시 정지 시간을 늘릴 수 있으므로 적절한 사이즈 조정이 필요하다.

GC 알고리즘 선택: Java는 서로 다른 GC 알고리즘을 제공하며, 각 알고리즘은 다른 유형의 워크로드에 적합하다. 예를 들어, G1 (Garbage-First) GC와 CMS (Concurrent Mark Sweep) GC는 GC 정지 시간을 최소화하는 데 초점을 맞추고 있다. ZGC (Z Garbage Collector)나 Shenandoah와 같은 알고리즘들은 정지 시간을 매우 짧게 유지하면서 대용량 힙을 관리할 수 있다.

객체 할당과 생존 기간 최적화: 객체의 생명 주기를 최적화하면 GC가 더 효율적으로 작동할 수 있다. 장기간 살아있는 객체를 줄이고, 불필요한 객체 생성을 피하는 것이 중요하다. 이렇게 하면 Young Generation에서 대부분의 객체가 처리되고, Major GC를 피할 수 있다.

GC 로그 분석: GC 로그를 주기적으로 분석하면 GC의 동작 방식을 더 잘 이해하고 문제를 조기에 발견할 수 있다. GC 로그는 어떤 종류의 GC 이벤트가 발생했는지, 얼마나 자주 발생했는지, 그리고 얼마나 오래 걸렸는지 등의 중요한 정보를 제공한다.

자바 버전 업데이트: 새로운 자바 버전은 종종 성능 개선과 함께 GC 알고리즘의 개선을 포함하고 있다. 최신 버전의 Java를 사용하면 GC 성능이 향상될 수 있다.

 

 

 

 

Reference : https://www.geeksforgeeks.org/garbage-collection-java/

 

Garbage Collection in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

'Java' 카테고리의 다른 글

Thread async in Java  (0) 2023.06.02
Assert.isTrue()  (0) 2023.05.15
Wrapper Class  (0) 2023.05.14
05.인스턴스 생성과 힙 메모리  (0) 2023.04.23
04.객체의 속성은 멤버 변수로, 객체의 기능은 메서드로 구현한다.  (0) 2023.04.23

컴파일과 인터프리트의 이해를부터 먼저 해야 한다.

 

C#이나 Java 같은 프로그래밍 언어로 코드를 작성하더라도 컴퓨터는 바로 이해하지 못한다.

 

왜냐하면 컴퓨터는 0과 1, 즉 이진법으로 이루어진 기계어를 이해하는데, 우리가 사용하는 프로그래밍 언어는 이 기계어와 상당히 다르기 때문이다.

이 문제를 해결하기 위해 프로그래밍 언어를 컴퓨터가 이해할 수 있는 기계어로 변환해 주는 과정이 필요한데, 이 과정이 바로 '컴파일'과 '인터프리트'이다.

컴파일은 프로그래밍 언어로 작성된 코드를 한 번에 기계어로 번역하는 과정을 의미한다. 이렇게 번역된 코드는 실행 시간에 바로 실행될 수 있으며, 그 결과 프로그램의 실행 속도가 빠르다.

반면에, 인터프리트는 프로그래밍 언어로 작성된 코드를 한 줄씩 실시간으로 기계어로 번역하며 실행하는 방식이다. 이 방식은 실행 시간에 번역과 실행이 동시에 이루어지기 때문에 컴파일 방식보다 실행 속도는 느리지만, 코드 수정이 빠르고 간편하다는 장점이 있다.

C 계열 언어와 자바는 컴파일 방식을 사용하는 언어에 속한다.

 

그러나 Java는 C와 같은 기존의 컴파일 언어와는 다른 점이 있다.

일반적으로 Compiled된 코드는 특정 운영체제에서만 실행될 수 있다. 예를 들어, Windows 용으로 컴파일된 코드는 Linux나 Mac에서 실행할 수 없다.

 

하지만 자바는 JVM(Java Virtual Machine)이라는 중간 매개체를 통해 이 문제를 해결한다. 자바로 작성된 코드는 JVM이 설치된 모든 운영체제에서 실행될 수 있다.

 

자바로 작성된 코드는 먼저 '자바 컴파일러'에 의해 바이트코드로 변환된다.  이 바이트코드는 기계어가 아닌 중간 코드로, JVM이 이해할 수 있는 언어이다. 그 후 JVM은 이 바이트코드를 각 운영체제에 맞는 기계어로 번역하여 실행한다.

 

새로 개발하는 요리의 레시피를 작성하는 것에 비유하자면 코딩한 결과,  즉 레시피를 컴파일해서 컴퓨터에게 건내주면 컴퓨터는 이 번역본을 보고 요리를 하는 것이다. 

 

컴퓨터가 종류마다  다른 언어를 쓰는 국가라고 치고  Windows, Mac, Linux 이렇게 3개의 국가가 있다고 가정해 보자.

 

C나 C++ 등의 언어로 레시피를 작성하고 나면 이것들을 각국의 현지어로 번역해서 보내야 했다.

코드를 실행할 컴퓨터의 종류에 따라  따로따로 컴파일을 해야 하니 여간 번거로운 일이 아닐 수 없다.

 

그런데 Java는 다른 방식을 도입했다.

Windows, Mac, Linux 이렇게 3개의 국가에 JVM-자바 가상 머신이라는 주방장을 파견한다

실행할 컴퓨터에 JVM이란 프로그램을 다운로드하는 것이다.

 

그럼 이 주방장들은 두 가지의 언어를 할 줄 아는 것이다. 먼저, 자기가 파견된 현지의 언어. 즉, 해당 컴퓨터의 기계어를 할 줄 아는 것이다. 다른 하나는 "자바 바이트코드"라는 주방장 공용어이다.

 

자바로 짠 코드는 바로 이 언어로 컴파일된다.

 

그래서 자바를 사용하는 레시피 개발자들은 레시피를 작성한 다음 이걸 단 하나의 언어 "자바 바이트코드"로 번역해서  각 국에 보내면 이 JVM이란 주방장들이 공통 번역본을 읽고 파견된 국가의 직원들, 즉, 컴퓨터 자원들에게 현지어로 지시를 내리는 것이다. 자바 개발자들은 자바를 실행할 컴퓨터 및 기기에 이 JVM이라는 프로그램만 설치해 두면 개발을 할 때 어떤 언어로 컴파일을 해야 할지 전혀 신경 쓰지 않아도 되는 것이다.

 

자바를 실행하기 위해 만들어진 JVM은 Kotlin, 스칼라, 그루비, Clojure  몇몇 다른 언어들에서도 사용할 수 있다.

 

이 언어들도 자바 바이트코드로 컴파일되도록 만들어졌기 때문이다.

 

그래서 안드로이드 앱을 만들거나 스프링 부트로 서버를 프로그래밍할 때 자바뿐만 아니라, Kotlin 등도 사용할 수 있는 것이다.

오늘날에는 JVM 말고도 많은 다른 언어들이 각각의 가상머신들을 사용해서 동작하고 있다.

이제는 가상머신을 쓴다는 것이 자바만의 강점은 아닌 것이다.

 

그럼 JRE는 뭐 JDK는 무엇일까?

 

자바 개발에 필요한 도구와 라이브러리를 제공하는 것이 JDK(Java Development Kit)이다.

JDK에는 자바 컴파일러와 JVM이 포함되어 있다.

즉, 자바로 프로그램을 개발하고 실행하기 위해서는 JDK가 필요하다.

 

레시피를 개발하는 회사로 비유할 수 있다. JDK(회사)안에 JRE(식당)가 있고, JRE안에 JVM(주방장)이 있는 것이다. 

 

JRE(Java Runtime Environment)는 자바 프로그램을 실행하기 위한 환경을 제공한다. JRE에는 JVM과 필수적인 라이브러리들이 포함되어 있다. 


아까 현지에 파견된 주방장을 JVM이라고 했는데, 현지 식당을 JRE이라고 할 수 있다.


최신의 자바 버전에서는 JRE를 별도로 배포하지 않고, JDK 안에 JRE를 포함시키는 방향으로 가고 있다.

따라서 개발자들은 JDK를 설치하면 자바 프로그램을 개발하고 실행하는 데 필요한 모든 것을 가질 수 있게 되었다.

 

 

 

 

Reference : 자바를 알아보자 (+ JVM, JRE, JDK의 정체)

 https://www.youtube.com/watch?v=OxvtGYvVkRU 

'Developer 지식' 카테고리의 다른 글

스택 메모리(stack memory)  (0) 2023.06.15
스크립트 언어와 컴파일 언어의 차이점  (0) 2023.06.06
Process와 Thread  (0) 2023.06.06
자료구조와 알고리즘이란?  (0) 2023.06.02
Port kill 방법  (0) 2023.05.28

< 인덱스(Index) 개념 >

  • 인덱스는 데이터를 빠르게 찾을 수 있는 수단으로서, 테이블에 대한 조회 속도를 높여 주는 자료 구조이다.
  • 인덱스는 테이블의 특정 레코드 위치를 알려 주는 용도로 사용한다.
  • 인덱스는 자동으로 생성되지 않는다.

  • 기본 키(PK; Primary Key) Column은 자동으로 인덱스가 생성된다.
  • 연월일이나 이름을 기준으로 하는 인덱스는 자동으로 생성되지 않는다.
  • '테이블의 이름' Column에 index가 없는 경우, 테이블의 전체 내용을 검색한다.(테이블 전체 스캔; Table Full Scan).
  • 인덱스가 생성되어 있을 때 데이터를 빠르게 찾을 수 있다.(인덱스 범위 스캔; Index Range Scan).
  • 조건절에 '='로 비교되는 컬럼을  대상으로 인덱스를 생성하면 검색 속도를 높일 수 있다.

< 인덱스(Index)의 종류 >

종류 설명
순서 인덱스(Ordered Index) 데이터가 정렬된 순서로 생성되는 인덱스,
B-Tree 알고리즘 활용(오름차순/내림차순 지정가능)
해시 인덱스(Hash Index) 해시 함수에 의해 직접 데이터에 키 값으로 접근하는 인덱스,
데이터 접근 비용이 균일, 튜플(Row) 양에 무관
비트맵 인덱스(Bitmap Index) 각 컬럼에 적은 개수 값이 저장된 경우 선택하는 인덱스,
수정 변경이 적을 경우 유용하다(생년월일, 상품번호 등)
함수 기반 인덱스(Functional Index) 수식이나 함수를 적용하여 만든 인덱스
단일 인덱스(Singled Index) 하나의 컬럼으로만 구성한 인덱스,
주 사용 컬럼이 하나일 경우 사용.
결합 인덱스(Concatenated Index) 두 개 이상의 컬럼으로 구성한 인덱스,
WHERE 조건으로 사용하는 빈도가 높은 경우 사용한다.
클러스터드 인덱스(Clutered Index) 기본 키(PK)를 기준으로 레코드를 묶어서 저장하는 인덱스,
저장 데이터의 물리적 순서에 따라 인덱스가 생성된다.
특정 범위 검색 시 유리 하다.

< 인덱스(Index) 생성 및 삭제, 변경 하기 >

[생성]

CREATE [UNIQUE] INDEX 인덱스명 ON 테이블명(컬럼명);

 

여기서 [ ]는 생략 가능해도 되고 안해도 된다는 것.

UNIQUE : 인덱스 걸린 컬럼에 중복 값을 허용하지 않는다.

인덱스명 : 생성하고자 하는 인덱스 테이블명

테이블명 : 인덱스 대상 테이블명

컬럼명 : 테이블의 특징 컬럼명(복수 컬럼 지정 가능)

 

예를 들어  CREATE UNIQUE INDEX A ON STUDENT(ID); 이렇게 인덱스를 만들 수 있다.

혹은 UNIQUE를 생략하고 

 

CREATE INDEX idx_employee_name
ON Employee (name);

이렇게도 만들 수 있다. 

 

 

[삭제]

DROP INDEX 인덱스명;

여기서 '인덱스명'은 생성된 인덱스명을 의미하며, 인덱스를 테이블의 종속 구조로 간주하고, 삭제 시 테이블 변경 명령어가 사용된다. ALTER TABLE 명령 뒤에 DROP INDEX 명령이 추가되는 형태로 사용 된다.

 

[변경]

ALTER [UNIQUE] INDEX 인덱스명 ON 테이블명(컬럼명);

 

일부 제품은 인덱스에 대한 변경 SQL 문이 없다.

기존 인덱스를 삭제 하고 신규 인덱스를 생성하는 방식으로 사용이 권고 된다. 

 

이를 실제로 생성부터 데이터 삽입과 인덱스 생성, 인덱스를 사용해서 데이터를 검색하는 쿼리를 구현하면 다음과 같다.

[employee Table 생성]

CREATE TABLE employee (
  id INT PRIMARY KEY AUTO_INCREMENT,
  first_name VARCHAR(50) NOT NULL,
  last_name VARCHAR(50) NOT NULL,
  birth_date DATE,
  hire_date DATE
);

[데이터 삽입]

INSERT INTO employee (first_name, last_name, birth_date, hire)
VALUES ('윤태영', '박', '1920-03-14', '1935-10-01');

[인덱스 생성]

CREATE INDEX idx_employee_last_name
ON employee (last_name);

 

[인덱스 사용]

SELECT * 
FROM employee
WHERE last_name = '박';

 

 

※주의점: 데이터 삽입, 변경이 수시로 일어나면 매번 인덱스를 변경해야 하므로, 성능 저하를 막기 위한 고려가 필요하다. 

 

Reference : 2023 수제비 정보처리기사

https://product.kyobobook.co.kr/detail/S000200275590

 

2023 수제비 정보처리기사 필기 1권+2권 합본 세트 | NCS 정보처리기술사 연구회 - 교보문고

2023 수제비 정보처리기사 필기 1권+2권 합본 세트 | ㆍ 암기비법 PDF 제공ㆍ 2023년 최신 출제기준 반영!ㆍ 최적의 암기비법(두음쌤)과 학습 Point 수록ㆍ 합격만을 위한 수제비 학습 전략 안내ㆍ 각

product.kyobobook.co.kr

 

'SQL 이론' 카테고리의 다른 글

뷰(View)  (0) 2023.06.05
SQL Joins  (0) 2023.05.17
정규화(Normalization)  (0) 2023.05.16
DBMS의 동시성 제어  (0) 2023.05.16
DataBase Key  (0) 2023.05.16


< 컴파일 언어 >

컴파일 언어는 소스코드를 작성한 후 컴파일러를 통해 사전에 컴파일되어 기계어 상태로 번역 되어 실행된다.

컴파일 단계에서 소스 코드를 기계어 코드로 변환하고 최적화 작업을 진행함으로써 실행 시간을 빠르게 할 수 있는 장점이 있다.

주로 C, C++, Java 등이 이에 해당한다.

장점:

  • 실행이 빠르다.
  • 컴파일을 통해 최적화가 가능하다.

단점:

  • 개발과 디버깅 시간이 오래 걸린다.

< 스크립트 언어> 

스크립트 언어는 코드를 한 줄씩 기계어로 번역한 후 실행한다. 이렇게 함으로써 컴파일 단계를 생략할 수 있지만, 그로 인해 실행 속도가 느려질 수 있다. 또한 스크립트 언어는 전체 코드에 대한 실행 코드 최적화가 어렵다.

주로 Python,Javascript가 있다. 

 

장점:

  • 컴파일 언어에 비해 느리지만 빠른 디버깅과 개발이 가능하다.

단점:

  • 실행이후에 번역하여 실행이 느리다.
  • 실행 코드 최적화가 어렵다.

 

Reference: 컴파일 언어와 인터프리터 언어의 차이

https://www.youtube.com/shorts/xz-orzhlzQk

 

'Developer 지식' 카테고리의 다른 글

스택 메모리(stack memory)  (0) 2023.06.15
JVM에 대한 이해 및 JRE,JDK  (0) 2023.06.06
Process와 Thread  (0) 2023.06.06
자료구조와 알고리즘이란?  (0) 2023.06.02
Port kill 방법  (0) 2023.05.28

  <프로세스(Process)와 스레드(Thread)>

이 두 개념을 혼동하기 쉬우나, 이 두 개념의 차이점을 이해하는 것은 동시성(concurrency) 및 병렬성(parallelism) 문제를 해결하면서 효율적인 Software를 구현하는 데 있어서 매우 중요한 개념이라고 할 수 있다. 여기서는 C#을 중심으로 설명하겠다.

 

귀여워서 쓰는 gifㅎㅎ

<프로세스(Process)>

프로세스는 운영체제로부터 자원을 할당받아 실행되는 작업 단위를 말한다. 프로세스는 각각 독립된 메모리 영역(Code,Data,Stack,Heap)을 가지며, 이는 운영체제로 부터 할당 받는다.

  • Code : C#을 사용한다고 가정하면, C# Program code가 저장되는 영역이라 할 수 있다. 이 부분은 읽기 전용이고, 변경이 불가 하다.

[코드 영역이 읽기 전용인 이유]

만약, 프로그램 코드가 프로그램 실행 중에 변경된다면, 프로그램은 의도치 않은 방식으로 동작하거나 오류를 발생시킬 수 있기에, 코드의 무결성을 보장하기 위해 코드 영역은 보호되어야 하기에 읽기 전용으로 설정된다. 

또한 악성 코드가 있다면, 프로그램의 동작을 변경하려고 시도할 수 있기에 읽기 전용으로 해놓는 이유도 있다.

  • Data: 전역 변수와 정적(Static) 변수 등이 저장되는 영역. 이 부분은 읽기와 쓰기가 가능하다.

[Data는 읽기가 쓰기가 왜 가능할까?]

여기는 전역 "변수", 정적 "변수"가 저장되는 영역이라고 했다. 변수라는 것은 , 즉 변할 변 이기에 변할 수가 있는 것이다.

그럼, 이 변수들은 프로그램 실행 도중에 읽거나 변경할 수 있는것이다. 예를 들어서 프로그램이 사용자의 입력을 받아서 전역 변수의 값을 변경하거나, 계산 결과를 전역 변수에 저장하는 등의 작업을 수행하게 된다. 이런 이유로 데이터 영역은 읽기와 쓰기가 모두 가능한것이다.

  • Stack : 함수 호출 정보(지역 변수, 매개 변수, 반환 주소 등)가 저장되는 영역, 읽기와 쓰기가 가능하고, 함수의 호출과 함께 할당되고 함수의 반환과 함께 해제된다. 
  • Heap : 동적 할당을 위한 영역, 필요에 따라 크기를 조절할 수 있는 영역으로 이 부분은 읽기와 쓰기가 가능하다.

new 키워드를 사용해서 동적으로 객체를 생성하면 이 영역에 할당된다. 

 

여기서 주의해야 할 것은 코드를 변경 가능 하다는 것이 아니라. '객체'를 변경 가능하다는 것이다.

예를 들어

using System;

public class Service
{
    public string Name { get; set; }
}

public class Program
{
    public static void Main()
    {
        // 객체 생성
        Service service = new Service();

        // 객체의 상태 변경
        service.Name = "Initial Name";
        Console.WriteLine(service.Name); // "Initial Name"

        // 객체의 상태 변경
        service.Name = "Changed Name";
        Console.WriteLine(service.Name); // "Changed Name"
    }
}

이 예제에서 'Service' 객체의 Name 프로퍼티는 프로그램이 실행 중일 때 변경된다. 이런 변경은 프로그램을 다시 컴파일하거나 실행하지 않고도 일어난다.

using System;

public class Program
{
    // Data 영역: 전역 변수가 이곳에 저장된다.
    static int globalVariable = 10;

    // Code 영역: 함수 및 메서드가 이곳에 저장된다.
    public static void Main()
    {
        // Stack 영역: 지역 변수와 함수 호출 정보가 이곳에 저장된다.
        int localVariable = 20;

        Console.WriteLine("Global Variable: " + globalVariable);
        Console.WriteLine("Local Variable: " + localVariable);

        // Heap 영역: 동적으로 할당된 데이터가 이곳에 저장된다.
        int[] dynamicArray = new int[10];
        dynamicArray[0] = 30;
        Console.WriteLine("Dynamic Array Value: " + dynamicArray[0]);
    }
}

여기서 'globalVariable'은 전역 변수로서, Data 영역에 저장된다.

Main 함수는 Code 영역에 저장된다.

localVariable은 Main 함수 내의 지역 변수로서, Stack 영역에 저장된다.

dynamicArray는 new 키워드를 사용하여 동적으로 할당되므로 Heap 영역에 저장된다.

 

프로세스는 집으로도 비유할 수 있다.

Code: 집의 설계도와 같다. 설계도는 집이 어떻게 생겼는지, 어떤 방들이 있는지 등의 정보를 담고 있다. 이 설계도는 읽기만 가능하고 변경할 수 없다. 마찬가지로, 코드 영역에는 프로그램 코드가 저장되어 있고, 이는 변경할 수 없다.
Data: 집안에 있는 물건들과 같다. 예를 들어, 가구나 컴퓨터 등이 이에 해당한다. 이들 물건들은 위치를 이동하거나 상태를 변경하는 것이 가능하다. 마찬가지로, 데이터 영역에는 변수와 같은 데이터가 저장되며, 이는 읽기와 쓰기가 가능하다.
Stack: 이는 집안의 할 일 리스트나 메모와 같다. 할 일을 추가하거나 완료하면 메모를 변경하게 된다. 마찬가지로, 스택 영역에는 함수 호출 정보가 저장되며, 함수 호출이 발생하거나 완료될 때마다 정보가 변경된다.
Heap: 이는 집의 창고와 같다. 필요에 따라 물건을 가져다 놓거나 물건을 가져갈 수 있다. 마찬가지로, 힙 영역은 동적 할당을 위한 공간으로, 필요에 따라 메모리를 할당하고 해제할 수 있다.


<스레드(Thread)>

Thread는 Process 내에서 실행되는 흐름의 단위를 의미한다. 하나의 Process 내에서 여러 Thread를 생성할 수 있고,

Thread들은 Process의 Memory 영역(Code,Data,Heap)을 공유하면서 실행된다. 그러나 각 Thread는 자신만의 Stack영역을 가지고 있다. 각 Thread가 별도의 함수 호출을 관리하기 때문이다.

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread thread = new Thread(PrintNumbers);
        thread.Start();

        PrintNumbers();
    }

    static void PrintNumbers()
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine(i);
        }
    }
}

이 코드를 예로 설명하자면 여기서는 총 두 개의 스레드가 실행된다. 하나는 Main() 함수가 실행되는 메인 스레드, 또 하나는 Thread thread = new Thread(PrintNumbers);에 의해 생성되는 새로운 스레드다. 

Main() 함수에서 thread.Start();를 호출하면서 새로운 스레드가 시작되며, 이 스레드는 PrintNumbers() 함수를 실행한다. 동시에 Main() 함수 내에서  PrintNumbers() 함수를 호출하여 메인 스레드에서 동일한 함수가 실행된다.

 

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 첫 번째 추가 스레드 생성
        Thread thread1 = new Thread(PrintNumbers);
        thread1.Start();

        // 두 번째 추가 스레드 생성
        Thread thread2 = new Thread(PrintLetters);
        thread2.Start();

        // 메인 스레드에서 PrintNumbers와 PrintLetters 실행
        PrintNumbers();
        PrintLetters();
    }

    static void PrintNumbers()
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine(i);
        }
    }

    static void PrintLetters()
    {
        for (char c = 'a'; c <= 'j'; c++)
        {
            Console.WriteLine(c);
        }
    }
}

이렇게 하면 된다.   총 3개의 스레드가 실행 된다. 

< 프로세스와 스레드의 관계와 차이점 >

프로세스는 운영체제로부터 자원을 받아 할당하고, 스레드는 프로세스로부터 자원을 할당받아 실행되는 것이라고 할 수 있다.

즉, 프로세스는 독립적인 실행 단위이며, 스레드는 프로세스 내에서 독립적인 실행 흐름을 나타내는 단위이다. 따라서 여러 스레드를 생성하는 것은 하나의 프로세스 내에서 병렬적인 작업을 수행하는 것을 가능하게 함으로써 여러 작업을 동시에 처리할 수 있으므로 프로그램의 실행 속도를 향상시킬 수 있다. 예를 들어, 한 스레드에서 데이터를 로드하는 동안 다른 스레드에서는 계산을 수행하는 등, 여러 작업을 동시에 진행하면 전체 실행 시간을 줄일 수 있다. 또한 사용자 인터페이스를 가진 Application에서는 별도의 스레드에서 오래 걸리는 작업을 수행하면, 주 스레드(일반적으로는 UI스레드 라고 한다.)는 사용자 입력에 대응하거나 인터페이스를 업데이트하는 등의 작업을 계속 할 수 있다.

하지만 주의해야 할 점은, 프로세스 내의 스레드들이 메모리를 공유하기 때문에 동시성 제어가 필요하다. 예를 들어, 두 스레드가 동일한 메모리 위치에 동시에 접근하려고 시도한다면, 예측할 수 없는 결과를 초래할 수 있다.

 

C# Threads

https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread?view=net-5.0 

 

Thread Class (System.Threading)

Creates and controls a thread, sets its priority, and gets its status.

learn.microsoft.com


"Processes and Threads" - Linux Documentation Project

https://tldp.org/LDP/LG/issue23/flower/threads.html

 

Processes and Process Context

There are two types of threads: user-space and kernel-space.  User space threads consist of internal cooperative multitasking switches between sub tasks defined with a process.   A thread may send a signal, perform it?s own switch or be invoked by a tim

tldp.org

 

1236번 문제 같은 경우, 모든 행과 모든 열에 한 명 이상의 경비원이 있어야 한다고 한다.

그러면 행 기준,열 기준으로 필요한 경비원의 수를 각각 계산하여 더 큰 수를 출력하면 최소한의 경비원의 수가 된다.

 

이 문제를 풀기 위해선 행 기준 열 기준으로 비어있는 경비원을 구하기만 하면 된다.

 

행 기준으로 보았을 때, 만약 두 행에 대해서 경비원이 존재하지 않고,

열 기준으로 보았을 때 , 한 열에 대해서 경비원이 존재하지 않으면,

 

더 큰 값을 가지는 행 부분이 필요한 경비원의 수라고 할 수 있다.

 

n, m = map(int, input().split())
array = []

for _ in range(n):
    array.append(input())

row = [0] * n
column = [0] * m

for i in range(n):
    for j in range(m):
        if array[i][j] == 'X':
            row[i] = 1
            column[j] = 1

row_count = 0
for i in range(n):
    if row[i] == 0:
        row_count += 1

column_count = 0
for j in range(m):
    if column[j] == 0:
        column_count += 1

print(max(row_count, column_count))

여기서는 경비원이 존재하는 위치가 if array[i][j] == 'X': 로 담기게 된다.

 

그렇기 때문에, 각각의 행과 열에 대해 반복문을 통해서 경비원이 존재하지 않는 행에 대해 count를 증가 시킨다.

그 다음에 행,열 기준으로 각각의 count를 비교해서 더 큰값이 print(max(row_count, column_count))를 통해 필요한 최소 경비원의 수가 출력 되도록 했다.

'코딩테스트' 카테고리의 다른 글

BACKJOON 1668번 (트로피 진열)  (0) 2023.06.05
BACKJOON 1302번 (베스트셀러)  (0) 2023.06.05
BACKJOON 1568번 ( 새 )  (0) 2023.06.05
BACKJOON 1543번 (문서 검색)  (0) 2023.06.05
BACKJOON 2751번 (수 정렬하기 2)  (0) 2023.06.05

< View의 개념 >

  • View는 논리 테이블로서 사용자에게(생성 관점 아닌 사용 관점에서) 테이블과 동일하다.
  • View는 TABLE A와 같은 하나의 물리 테이블로부터 생성 가능하며, 다수의 테이블 또는 다른 뷰를 이용해 만들 수 있다.
  • View와 같은 결과를 만들기 위해 Join 기능을 활용할 수 있으나, View가 만들어져 있다면 사용자는 조인 없이 하나의 테이블을 대상으로 하는 단순한 질의어를 사용할 수 있다.

< View 장단점 >

[장점]

논리적 독립성 제공 : 데이터베이스에 영향을 주지 않고 애플리케이션이 원하는 형태로 데이터에 접근 가능하다.

데이터 조작 연산 간소화 : 애플리케이션이 원하는 형태의 논리적 구조를 형성하여 데이터 조작 연산을 간소화 한다.

복수 테이블에 존재하는 여러 종류의 데이터에 대해 단순한 질의어 사용이 가능하다.

보안 기능(접근제어) 제공 : 특정 필드만을 선택해 View를 생성할 경우 애플리케이션은 선택되지 않은 필드의 조회 및 접근이 불가 하다. 

또한 중요 보안 데이터를 저장 중인 테이블이나 컬럼에는 접근이 불허된다.

 

 

[단점]

View 자체 인덱스 불가 : 인덱스는 물리적으로 저장된 데이터를 대상으로 하기에 논리적 구성인 뷰 자체는 인덱스를 가지지 못한다.

View 변경 불가 : 뷰의 정의를 변경하려면 뷰를 삭제하고 재생성 해야한다. 뷰 정의는 ALTER 문을 이용하여 변경할 수 없다.

(View는 CREATE 문을 사용하여 정의, 뷰를 제거할 때는 DROP문을 사용한다.)

데이터 변경 제약 존재 : 뷰의 내용에 대한 삽입,삭제,변경 제약이 있다. 

 

< View 명령어 >

① 뷰 생성

  • 뷰 생성의 일반 형태는 다음과 같다.
상황 뷰 생성 쿼리문
테이블 A 그대로 CREATE VIEW VW_A AS
SELECT *
   FROM A;
테이블 A 일부 컬럼 CREATE VIEW VW_B AS
SELECT 컬럼1, 컬럼2
   FROM A;
테이블 A와 테이블 B 조인 결과 CREATE VIEW VW_C AS
SELECT *
   FROM A, B
WHERE A.컬럼1 = B.컬럼1;

SELECT문에는 UNION이나 ORDER BY절을 사용할 수 없다.컬럼명을 기술하지 않으면 SELECT 문의 컬럼명이 자동으로 사용된다.

 

②뷰 삭제/변경

  • 뷰 정의 자체를 변경하는 것은 불가능하다.
  • 뷰 이름이나 쿼리문을 변경하는 수단은 제공되지 않는다.
  • 뷰 삭제와 재생성을 통해 뷰에 대한 정의 변경이 가능하다.

ⓐ DROP VIEW 문법

DROP VIEW 문법은 다음과 같다.

 

DROP VIEW 테이블명 [CASCADE | RESTRICT];

 

ⓑ DROP VIEW 명령어 옵션

DROP VIEW 명령어의 옵션에는 CASCADE와 RESTRICT가 있다.

 

CASCADE : 참조하는 테이블까지 연쇄적으로 제거하는 옵션

RESTRICT : 다른 테이블이 삭제할 테이블을 참조 중이면 제거하지 않는 옵션 

 

Source :2023 수제비 정보처리기사

https://product.kyobobook.co.kr/detail/S000200275590

 

2023 수제비 정보처리기사 필기 1권+2권 합본 세트 | NCS 정보처리기술사 연구회 - 교보문고

2023 수제비 정보처리기사 필기 1권+2권 합본 세트 | ㆍ 암기비법 PDF 제공ㆍ 2023년 최신 출제기준 반영!ㆍ 최적의 암기비법(두음쌤)과 학습 Point 수록ㆍ 합격만을 위한 수제비 학습 전략 안내ㆍ 각

product.kyobobook.co.kr

 

'SQL 이론' 카테고리의 다른 글

인덱스(Index)  (0) 2023.06.06
SQL Joins  (0) 2023.05.17
정규화(Normalization)  (0) 2023.05.16
DBMS의 동시성 제어  (0) 2023.05.16
DataBase Key  (0) 2023.05.16

+ Recent posts