1. 동기식 입출력 VS 비동기식 입출력

  • 동기식 입출력
    : I/O 요청에 따른 입출력을 OS가 직접 해주어야 하는데, 이 때 프로세스가 그 시간을 기다려 주는 것
    • 구현방법
      • I/O가 끝날 때 까지 CPU를 낭비시킴
      • 매시점 하나의 I/O만 일어날 수 있음
    • 구현방법2
      • I/O가 완료될 때까지 해당 프로그램에게서 CPU를 빼앗음
      • I/O 처리를 기다리는 줄에 그 프로그램을 줄 세움
      • 다른 프로그램에게 CPU를 줌
  • 비동기식 입출력(Asynchronous)
    : I/O가 시작된 후 입출력 작업이 끝나기를 기다리지 않고 제어가 사용자 프로그램에 즉시 넘어감. 즉 원래 CPU를 받아서 사용하던 그 프로그램이 계속 다른일을 함

 

2. 쓰레드(Thread)

: Thread는 CPU의 수행단위이다. 전통적인 개념의 heavyweight process는 하나의 thread를 가지고 있는 task로 볼 수 있다.

  • Thread의 구성
    • program counter
       : 스레드가 현재 실행중인 명령어의 메모리 주소를 저장하는 레지스터이다. 각 스레드는 자신만의 PC를 가진다
    • register set
       : 레지스터 세트는 데이터의 조작 및 처리를 위해 사용된다. 이 레지스터 세트를 이용해 각각 독립 수행이 가능하다.
    • stack space
       : 스택 공간에서는 수행단위로서 존재하는 쓰레드가 함수 호출, 지역 변수 및 임시 데이터 저장등을 위해 사용하는 공간이다.
  • Thread가 서로 공유하는 부분(=Task)
    • code section
    • data section 
    • OS resources
  • 프로세스는 Code, Data, Stack 으로 이루어진 주소공간이 생기고, 이를 관리하기위한  PCB이 생긴다
    • 주소공간에서 Stack부분은 쓰레드의 갯수만큼 각각의 Stack을 가진다

1)쓰레드의 장점

  1. 응답성 : 빠르다. 스레드가 여러개이면 먼저 처리가 끝난 결과를 받아볼 수 있게 된다. 이미지를읽어오는동안 프로세스를 블럭시키는게 아니라, 텍스트를 보여주도록 비동기식 으로 동작하게 된다.
  2. 자원 공유 : 똑같은 일을 하는 CPU수행 단위만 늘렸을 땐, PC, Register, stack을 제외하고는 공유(Task)하기 때문에 자원 낭비가 떨어진다
  3. 경제성 : 좀 더 빠르다? 프로세스를 만든다 → 오버헤드가 크다 but 쓰레드를 늘린다 → 오버헤드가 그렇게 크지는 않다.
    +문맥교환이 일어나는것은 오버헤드가 크지만 CPU내 스레드만 변경하는것은 오버헤드가 그렇게 크지 않다.
  4. CPU가 여러개 일때, 스레드별로 CPU를 할당받아서 작업이 가능해진다. : 각각의 스레드가 각각의 서로 다른 CPU에서 병렬적으로 일을 하게 되면, 빠른 연산이 가능해진다

2) 쓰레드의 구현

  1. 커널 쓰레드 : 쓰레드가 여러개 있다는 사실을 운영체제 커널 쓰레드가 알고 있다. 한개의 쓰레드에서 다른 한개의 쓰레드로 CPU가 넘어가는 것도 커널이 CPU 스케쥴링처럼 넘겨주는 것
    Ex) Window 95,98, Solaris, Digital UNIX
  2. 라이브러리 쓰레드 : 프로세스 안에 여러개의 쓰레드가 있다는 것을 커널은 모르고 유저레벨 쓰레드가 알아서 관리하는 것이다. 커널이 봤을 땐 일반적인 프로세스처럼 보이지만, 실제로는 쓰레드가 나뉘어져 있다.
    Ex)  POSIX Pthreads, Mach C-Threads, Solaris threads

'OS' 카테고리의 다른 글

#2. Process  (0) 2023.04.13
#1.2 System structure & Program execution  (0) 2023.04.11
#1. System structure & Program executio  (0) 2023.03.29
#0. Introduction to Operating Systems  (0) 2023.03.27

오늘 N:N 테이블 사이에서 DTO변환을 하다가 다음과 같은 오류를 만났다.

 

cannot deserialize from Object value (no delegate- or property-based Creator)

 

처음엔 이해가 되지 않았다. 분명히 DTO변환에 필요한 생성자(파라미터가 들어가는) 만들어 두었고, mapper를 이용한 변환에도 특별히 문제가 될만한 설계상의 실수는 존재하지 않았다. 그렇게 몇분간 방법을 찾아 헤매다가,

 

이 문제가 Jackson 라이브러리는 기본 생성자가 존재하지 않으면 객체를 생성할 수 없다는 사실을 상기하게 되었다.

 

Jackson 라이브러리가 객체를 생성할 때, Java Reflection API를 사용하게 된다. 이는 Spring Framework를 공부하면서 이따끔씩 만나게 된 용어인데, 이 API를 사용하는 대표적인 예시로는 Spring의 Bean Factory, Jackson library, intellij를 들 수 있겠다. Reflection API에 대한 예시를 통한 이해는 https://tecoble.techcourse.co.kr/post/2020-07-16-reflection-api/ 이 글을 참고하도록 하고 '하루회고' 포스트에서는 그래서 왜 ?

 

  1. 우리가 기본생성자를 열어두어야하는지
  2. 어떤 이점이 있을 수 있는가
  3. 어떠한 문제가 생길 수 있는지 생각해보자

 

1. 왜 기본 생성자를 열어 두어야 하는가?

 

왜 기본 생성자가 필요한 것인가에 대해 찾아보다가, 이런 문장을 발견하였다

It's not mandatory to define default constructor, but if you are writing Hibernate persistent class, JPA entities, or using the Spring framework to manage object creation and wiring dependencies, you need to be a bit careful. Many of open source framework, uses reflection to create instance or Object at runtime, based upon the name of the class.

 

기본생성자가 꼭 필요한 것은 아니지만, 하이버네이트 영속성 클래스, JPA 엔티티와 같이 지금 프로젝트에 반드시 사용하는 프레임워크 안에서는 객체는 생성하고 의존성 주입에 있어서 Reflection을 사용하기 때문에 필요하다는 이야기다.

그래서 리플렉션은 무엇인가를 다시한번 찾아보았다.

 

리플렉션(Reflection)은 Java에서 실행중인 프로그램의 구조를 분석하거나 조작할 수 있는 기능이다.  쉽게말하면 클래스, 메서드, 필터등에 접근할 수 있으며, 동적으로 객체를 생성하고 메서드를 호출할 수 있게 해준다. 이 때 Java Reflection이 가져올 수 없는 정보 중 하나가 바로 생성자의 인자 정보들이다. 따라서 기본 생성자 없이 파라미터가 있는 생성자만 존재한다면 java Reflection이 객체를 생성할 수 없게 되는 것이다.

 

아 그렇다면, Java Reflection의 기능을 사용하는 프레임워크 or 라이브러리는 "항상 기본생성자를 열어 두도록 하자! "라고 결론 지을 수 있었다.

 

2. 어떤 이점이 있을 수 있는가?

 

첫째로, 리플렉션 API를 사용하는 Jackson 라이브러리를 통해 JSON 데이터를 Java객체로 동적으로 생성하고 필요한 값들을 할당할 수 있게된다. (오늘 생겼던 문제)

 

둘째,  Spring을 시작하면서 가장 먼저 배웠던 Bean과 Bean Factory도 Reflection API와 관계가 깊다. 일반적으로 Spring 애플리케이션의 시작 시점에 Bean Factory는 설정된 빈들을 생성하고 의존성 주입을 수행한다. 이 과정에서 리플렉션을 사용하여 동적으로 객체를 생성하고, 필드를 설정하거나 메소드를 호출하는 등의 작업을 수행한다.  

 

세번째, 우리가 개발하는 동안 가장 많이 사용하는 인텔리제이(IntelliJ)의 자동 완성 기능은 리플렉션을 사용하여 사용자가 작성한 클래스의 메서드나 필드 목록을 가져와 자동 완성 목록에 표시한다

결론적으로, 리플렉션에 기반한 프레임워크와 라이브러리에서 많이 사용되며, 클래스에 대한 정보를 런타임에 얻고 동적으로 처리하기 위해 사용되어 개발을 좀 더 쉽게 해줄 수 있게 해준다.

 

3. 어떠한 문제가 생길 수 있는지 생각해보자

 

개발자가 편해지면서 얻게되는 기술들은 적절히 사용하는 것을 기본 원칙으로 하되, 이 기술을 사용했을 때 나타날 수 있는 문제에 대해서도 한번은 짚고 넘어갈 필요가 있다. 


이런 Reflection 의 가장 치명적인 단점으로는 성능 오버헤드가 크다고 한다. 컴파일 타임이 아닌 런타임에 동적으로 타입을 분석하고 정보를 가져오므로 JVM을 최적화할 수 없기 때문이다. 뿐만 아니라 직접 접근할 수 없는 private 인스턴스 변수, 메서드에 접근하기 때문에 내부를 노출하면서 추상화가 깨진다. 이로 인해 예기치 못한 부작용이 발생할 수 있다.


그래서 결론은?

"Java Reflection API 는 개발자가 런타임환경에서 구체적이지 않은 객체를 해결해주는 아주 좋은 API구나. 기본생성자는 열어두도록하지만, 오버헤드로 인한 문제는 기억해두도록 하자" 로 결론 지을 수 있을것 같다.

 

OS에 관한 포스팅은 이화여자대학교 반효경 교수님의 수업을 수강하여 정리한 내용임을 밝힙니다.

 

1. 프로세스의 개념

  • 프로세스란 실행중인 프로그램
  • 프로세스의 문맥(Context)
    • CPU 수행 상태를 나타내는 하드웨어 문맥
      • Program Counter : 사용자 프로그램의 코드를 읽어온다
      • Register : Instruction읽어오면 레지스터에 값을 넣고 산술논리연산장치를 통해 연산을 한다
    • 프로세스의 주소공간
      • Code 명령어의 집합이며 프로그램이 메모리에 로드될 때 생성된다. 한개씩 실행된다
      • Data 프로그램 실행시 생성되며,  전역변수 정적변수등이 포함된다.
      • Stack   함수의 호출과 리턴에 관한 데이터를 저장함. 지역변수와 매개변수 관리
    • 프로세스 관련 커널 자료구조
      • Data : 사용자 프로그램A의 PCB (CPU를 얼마나 줄지, 메모리는 얼마나 줄지 관리함)
      • Stack : A의 커널 스택

 

2. 프로세스의 상태

  • 프로세스 상태(State)가 변경되며 수행된다.
  • 종류
    • Running : CPU를 잡고 실행중인상태
    • Ready : CPU만 오면 GO!
    • Blocked : 
      • CPU를 줘도 Instruction을 수행할 수 없는 상태
      • Process 자신이 요청한 event가 즉시 만족되지 않아 이를 기다리는 상태
      • ex) 디스크에서 file을 읽어와야하는 경우
    • New : 프로세스가 생성중인 상태
    • Terminated : 수행(execution)이 끝난 상태

Process state diagram

  • 동작방식
    1.  운영체제 커널이 I/O queue 요청을 함(running -> waiting)
    2. 키보드 입력 완료
    3. I/O controller가 CPU에게 Interrupt 전달
    4. CPU 동작을 정지 한 후, OS에게 간 이후에 프로그램 상태 변경 (waiting -> ready)

 

3. PCB

  • 운영체제가 각 프로세스를 관리하기 위해 프로세스당 유지하는 정보
  • 다음의 구성요소를 가진다
    1.  OS가 관리상 사용하는 정보
      • Process state, Process ID
      • scheduling information, priority
    2. CPU 수행 관련 하드웨어 값
      • Program Counter
      • Register's
    3. 메모리 관련
      • Code, data, stack의 위치정보
    4. 파일 관련
      • Open file descriptor
       

PROCESS CONTROL BLOCK

4. 문맥 교환 (Context Switch)

  : CPU는 빠른자원으로 한 프로세스가 계속 독점하는게 아니라, 썼다 안썻다를 반복하는데, 뺏긴 시점의 문맥을 기억하고 있어야 다시 시작할 때, 그 문맥에서부터 이어서 할 수 있다. 그래서 CPU에 있는 PC(program counter)와 Register값들을 계속 바꾸는 행위를 하게된 것이다. 이런 문맥교환은 캐쉬메모리의 내용을 전부 지워야하므로 오버헤드가 큰 편이다.

  • CPU를 한 프로세스에서 다른 프로세스로 넘겨주는 과정
  • CPU가 다른 프로세스에게 넘어갈 때 운영체제는 다음을 수행
    • CPU를 내어주는 프로세스의 상태를 그 프로세스의 PCB에 저장
    • CPU를 새롭게 얻는 프로세스의 상태를 PCB에서 읽어옴
  • System Call이나 Interrupt 발생시 반드시 Context Switch가 발생하는것은 아니다
    • 사용자 프로세스 A -> Kernel Mode : 문맥교환이 일어난 것은 아니다
    • 사용자 프로세스 A -> Kernel Mode -> A blocked -> 사용자 프로세스 B : A에서 B로 문맥교환이 일어났다

 

5. 스케줄러

  • Long term scheduler (장기 스케줄러 or Job 스케줄러)
    • 시작 프로세스 중 어떤 것들을 ready queue로 보낼지 결정 : new -> ready로 넘어가는 admitted과정
    • 프로세스에 memory를 주는 문제
    • degree of Multiprogramming 을 제어 : 메모리의 프로세스의 수를 관리
    • time sharing system 에는 보통 장기 스케줄러가 없음(무조건 ready)
  • Short-term scheduler ( 단기 스케줄러 or CPU 스케줄러)
    • 어떤 프로세스를 다음번에 running시킬지 결정
    • 프로세스에 CPU를 주는 문제
    • 충분히 빨라야함 (millisecond)
  • Medium-term scheduler(중기 스케줄러 or Swapper)
    • 여유 공간 마련을 위해 프로세스를 통째로 메모리에서 디스크로 쫓아냄(Suspended상태가 된다)
    • 프로세스에게서 memory를 뺏는 문제
    • degree of Multiprogramming 을 제어

'OS' 카테고리의 다른 글

#2.2 Process  (0) 2023.05.04
#1.2 System structure & Program execution  (0) 2023.04.11
#1. System structure & Program executio  (0) 2023.03.29
#0. Introduction to Operating Systems  (0) 2023.03.27

네트워크 내용은 '성공과 실패를 결정하는 1%의 네트워크 원리' 라는 책의 내용을 작성자가 정리한것임을 밝힙니다.

 

1. HTTP 리퀘스트 메시지를 작성한다.

  • URL의 가장 앞에는 http:, ftp:, file: 등의 문자열이 따라 붙는데, 이는 엑세스 대상이 어떤 프로토콜을 가지고 있는지 나타낸다
  • 사용자명과 패스워드는 생략이 가능하다
  • ' // ' 는 이후 이어지는 문자열이 서버의 이름임을 나타낸다.
  • URL에 따른 리퀘스트 작성은 브라우저가 담당한다.
#예시1번
http://user:password@www.kakao.co.kr:80/dir/file.html
<프로토콜><사용자명><">    <웹서버:도메인명><포트><파일의경로명>

#예시2번
ftp://user:password@www.kakao.co.kr:80/dir/file.html
<프로토콜><사용자명><">    <웹서버:도메인명><포트><파일의경로명>

#예시3번
file://localhost/c:/window/file1.zip
      <컴퓨터명>  <파일의경로명>
   
#예시 4번
http://www.kakao.tistory.co.kr/dir/

1.1 파일명을 생략하는 경우

  • 예시 4번과 같이 파일의 경로명을 생략할 수 있다.
  • 기본적으로는 'index.html' 또는 ' default.html'로 붙는다

1.2 HTTP의 기본개념

  • 프로토콜 : 통신 동작의 규칙을 정한 것을 '프로토콜'이라 한다.
  • 이 통신 프로토콜은 클라이언트(브라우저)와 서버가 주고받는 내용이나 순서를 정한 것 이다.
  • 주고 내용
    • 무엇을 : URI (Uniform Resource Identifier)
    • 어떻게 : Method (Post, Get, Update, Delete)
    • Header: 보충정보( +Data)
    • Content
  • 받는 내용
    • Status Code
    • Header
    • Content
# method="Get"인 경우 메시지
GET /user/sample.txt?Field=userinfo&SendButton=SEND HTTP/1.1 #리퀘스트라인

# method="POST" 인 경우
POST /user/sample.txt HTTP/1.1 #리퀘스트라인
Field=userinfo&SendButton=SEND #메시지 헤더
# 공백
<메시지 Content> #메시지본문


# RESPONSE MESSAGE
HTTP/1.1 200 OK
Date: Sat, 12 Feb 2023 ~~~
<Another Tag> : <Value>
<Anotehr Tag2> : <Value2>

+ 헤더 필드의 종류는 굉장히 많으므로 필요에 따라 찾아보는것을 추천한다.

 

2. 웹 서버의 IP 주소를 DNS 서버에 조회한다.

  1. IP 주소의 기본
    1. IP주소 : 네트워크 번호 + 호스트 번호
      • XX동 XX번지 => 네트워크 번호(어디 네트워크에 속하는지 나타냄)
      • 김코딩 씨 => 호스트 번호(개별적으로 할당된 호스트의 주소를 나타냄)
    2. TCP/IP 네트워크 : 작은 서브넷을 라우터로 연결하여 전체 네트워크를 완성한 것을 말한다. (+작은 서브넷 : 허브에 몇 대의 PC가 접속된 것)
    3. 네트워크 번호 + 호스트 번호 = 32비트(4바이트)
      •  몇바이트로 나눌지 기준이 존재하지 않는데, 이것의 기준이 되는게 '넷마스크' 이다.
      • 넷마스크가 '1'인 부분은 네트워크 번호이고, '0'인 부분은 호스트 번호이다.
  2. 도메인명과 IP주소를 구분하여 사용하는 이유
    • IP 주소는 32비트, 즉 4바이트에 해당하는 개수밖에 없지만, 도메인 명은 적어도 수십 바이트부터 최대 255 바이트나 있다
    • 라우터 부하가 증가하여 데이터 운반동작에, 시간이 증가한다. 즉 네트워크의 속도가 느려진다
  3. Socket 라이브러리가 IP 주소를 찾는 기능을 제공한다.
    1. DNS 서버에 IP 주소를 조회 한다는 것은 DNS서버에 조회 메시지를 보내고, 거기에서 반송되는 응답 메시지를 받는 것 이다.
    2. DNS resolver = '리졸버' 가 해당역할을 해주며, 얘는 Socket 라이브러리 안에 들어있는 부품화한 프로그램 이다.
    3. Socket 라이브러리OS에 포함되어 있는 네트워크의 기능을 애플리케이션에서 호출하기 위해 모아놓은 부품이다.
  4. 리졸버 내부의 작동
    1. 리졸버 호출 시점에 애플리케이션(브라우저) 동작은 일시 정지하고 제어가 넘어간다
    2. 리졸버는 DNS 서버에 문의하기 위한 메시지를 작성한다 (by Socket라이브러리).
    3. 프로토콜 스택을 이용하여 메시지를 송신한다
    4. LAN 어뎁터를 통해 메시지가 DNS서버로 전달된다.

 

 

 

 

 

OS에 관한 포스팅은 이화여자대학교 반효경 교수님의 수업을 수강하여 정리한 내용임을 밝힙니다.

 

인터럽트의 종류

  • 하드웨어 인터럽트 : I/O device 에서 발생하는 인터럽트로 예시로는 마우스나 키보드 입력이 될 수 있다.
  • 소프트웨어 인터럽트 : 소프트웨어 (프로세서)에서 발생하는 인터럽트로 시스템콜, 예외 상황이 있다.
  • 타이머 인터럽트 : 정해진 CPU할당시간이 지난 경우 발생하는 인터럽트로, 다른 사용자 프로그램에 CPU가 할당된다.

소프트웨어  인터럽트의 발생과정(Simplified)

  • I/O device 에 작업 요청에 따른 인터럽트 발생 
  • CPU modebit이 0이 되어 커널모드가 됨
  • 커널 내부에 인터럽트 벡터가 있고, 그 벡터엔 해당 인터럽트가 어떤 인터럽트인지 알 수 있는 엔트리가 있음
  • 인터럽트 서비스 루틴에 따라 요청을 처리함

What is 프로그램 카운터 레지스터?

 : CPU가 현재 실행중인 명령어의 위치를 가리키는 레지스터이다. CPU는 이 레지스터의 값을 읽어와서 해당 위치의 명령어를 읽어와 실행합니다

 

동기식 입출력과 비동기식 입출력

동기식 입출력

  • I/O 요청 후 입출력 작업이 완료된 후에야 제어가 사용자 프로그램에게 넘어감
  • 구현방법 1
    • I/O가 끝날 때까지 CPU를 낭비시킴
    • 매시점 하나의 I/O만 일어날 수 있음
  • 구현 방법 2
    • I/O가 완료될 때까지 해당 프로그램에게서 CPU를 빼았음
    • I/O 처리를 기다리는 줄에 그 프로그램 줄을 세움
    • 다른 프로그램에게 CPU를 줌

비동기식 입출력

  • I/O가 시작된 후 입출력 작업이 끝나기를 기다리지 않고 제어가 사용자 프로그램에 즉시 넘어감

 

DMA (Direct Memory Access)

DMA

  • 빠른 입출력 장치를 메모리에 가까운 속도로 처리하기 위해 사용
  • CPU의 중재 없이 device controller가 device의 buffer storage의 내용을 메모리에 block 단위로 직접 전송
  • 바이트 단위가 아니라 block단위로 인터럽트를 발생시킨다

필요한 이유

  : 원래는 device controller에 직접 접근하는 것은 CPU만 하는데, 인터럽트가 너무 자주 발생해서 그것을 처리하기 위한 오버헤드가 점점 커진다 → 대신 같이해줄 친구를 구했음 → Direct Memory Access가 버퍼에있는 내용을 메모리로 카피를 한다.

 

Memory Mapped I/O

개념

 : Memory Mapped I/O 면 입출력 장치와 메모리 간의 데이터 전송이 일반적인 메모리 접근과 같은 방식으로 처리되도록 한다.  즉 CPU는 입출력 장치를 다루기 위해 별도의 입출력 명령을 사용할 필요가 없이, 메모리에 접근하는 것과 같은 방식으로 입출력 장치에 접근 할 수 있게 된다

 

장점

: 입출력 장치와 메모리 간의 데이터 전송 속도를 높이는 장점이 있다. 또한, 입출력 장치가 메모리와 같은 방식으로 다뤄지기 때문에 입출력 장치의 주소를 다루는 복잡한 로직을 구현할 필요가 없어지게 된다.

 

단점

: 입출력 장치와 메모리가 동일한 주소 공간을 공유하기 때문에 충돌 문제가 발생할 수 있게 된다. 또한, 입출력 장치가 메모리와 같은 방식으로 다뤄지기 때문에 입출력 장치의 동작과 관련된 레지스터나 제어 신호가 메모리에 노출될 수 있으므로 보안에 취약할 수 있는 단점이 있다

 

저장장치 계층 구조

  : 위에 있을 수록 Speed가 빠르고, Cost와 Volatility가 높다

  1. Primary (Executable)
    1. Register
    2. Cache memory
    3. memory
  2. Secondary
    1. Magnetic Disk
    2. Optical Disk
    3. Magnetic Tape

 

프로그램의 실행(메모리 load)

  1. File System(보조기억장치)에 있는 실행파일 A, B를 가상메모리에 load 한다
  2. 가상메모리 구성
    1. stack: 함수의 호출과 반환에 관한 데이터를 저장하며, 스택프레임에 매개변수, 지역변수 등을 저장한다
    2. data: 프로그램의 실행에 사용되는 전역 변수, 정적변수, 초기화된 데이터 등을 저장하는 메모리 영역이다. 프로그램이 실행될 때 생성된다
    3. code: 명령어를 저장하는 역할이며, CPU가 한개씩 실행한다. 실행파일이 메모리에 로드될때 생성된다.
    +가상메모리를 사용하는 이유
    1. 가상의 메모리를 사용하면, 사용하지 않는 메모리를 따로 할당하지 않아도 되므로 메모리 사용의 효율성을 높인다
    2. 가상의 주소는 프로그램마다 다르기 때문에, 여러 프로그램이 동시에 실행될 때 발생할 수 있는 충돌을 방지할 수 있다.
  3. AddressTranslation : 가상 메모리를 실제 물리 주소로 변경한다

 

커널 주소 공간의 내용

code

  • 시스템 콜, 인터럽트 처리코드
  • 자원 관리를 위한 코드
  • 편리한 서비스 제공을 위한 코드

Data

  • 각 하드웨어마다 관리하기 위한 자료구조를 가지고 있음
  • 현재 실행중인 프로그램을 관리하기 위한 자료구조가 필요하다 : PCB (process control block)
  • CPU
  • mem
  • disk
  • ProcessA 의 PCB
  • ProcessB 의 PCB

stack

  • 각 사용자 프로그램이 운영체제 커널의 코드를 불러서 실행시킬 수 있다. (함수호출 발생 → 사용자 프로그램마다의 커널 스택에 접근)
  • ProcessA의 커널 스택
  • ProcessB의 커널 스택

What is PCB?

PCB(Process Control Block)는 프로세스에 대한 정보를 저장하고 있는 운영체제의 자료 구조이다. 

PCB는 운영체제가 프로세스를 관리하고 제어하기 위해 필요한 정보를 저장합니다. 예를 들어, PCB에는 프로세스 식별자, 프로세스 상태, CPU 레지스터 값, 프로세스 우선순위, 프로세스 자원 요구사항 등의 정보가 저장된다. 이러한 정보는 프로세스가 실행될 때 CPU에 의해 처리되므로, 프로세스가 중단되거나 재개되는 경우에도 유지된다.

PCB는 프로세스의 생성부터 종료까지의 모든 단계에서 사용된다. 새로운 프로세스가 생성될 때는 새로운 PCB가 생성되고, 프로세스가 종료될 때는 PCB가 삭제됩니다. PCB는 운영체제가 프로세스를 관리하기 위한 핵심 자료구조 중 하나다.

 

'OS' 카테고리의 다른 글

#2.2 Process  (0) 2023.05.04
#2. Process  (0) 2023.04.13
#1. System structure & Program executio  (0) 2023.03.29
#0. Introduction to Operating Systems  (0) 2023.03.27

벌써 섹션4가 끝났다... 시간이 진짜 빠른것같다. 아직 하고 싶은것이 많은데 시간이 참 빠르게 간거같다.

이미 지나간건 평가해야하니까... 섹션3 회고때 했던 내용을 바탕으로 회초리와 칭찬을 할 필요가 있겠지..

  • 다음 회고 때 판별 가능한 것
    • 블로그 포스팅 20개
    • 코테문제 60개 풀기, 커밋으로 기록 남겨두기
    • 스프링 고급원리 week2에 끝내기
    • 게시판 만들기 완료

 

실제평가

  • 블로그포스팅 20개 -> 15개 작성 (이틀에 한개씩은 작성했음 ㅎㅎ) 
  • 코테문제 60개풀기 -> 40개 풀기(하하 많이 부족했다) 
  • 스프링 고급원리 -> 아직도 못끝냄.. ㅠㅠ
  • 게시판 만들기 완료 -> 1단계, 2단계 절반완료

 

정말 잘 보낸건 아니지만, 총점 67점 정도로 한달을 보낸것같다.

 

✔️ KEEP

  • 운영체제 공부 하루 한시간씩 유지하기
  • 자료구조 한 유닛씩 꾸준히 하기
  • 네트워크 책 읽기
  • SQL책 읽기
  • 스프링 고급원리 완강하기 ㅠ

✔️ Problem

  • 스프링 씨큐리티 인증관련하여 혼자서 보지않고 진행하기는 어려움.
  • 공식문서만 보고 필요한 요소를 적절히 쓸 수 있는 프로그래머가 되기.
  • 메인프로젝트 주제에 대해서 생각해보고 결정해보기

✔️ 회고

열심히 안한건 아닌데, 생각보다 많이 못한것같아서 아쉬운 한달 이었다. 항상 욕심은 더 가지고 있는데, 체력이 안된다거나 집중력이 모자란다거나 해서 못할때도 좀 나왔던것같다. 그래서 스스로에게 아쉽다고 느껴진 부분이 있었는데, 중간에 3월 그로잉데이에 참석하고나서 힘을 참 많이 얻었던것같다. 그런 자리를 만들어준 코드스테이츠분들께 굉장히 감사하다.


또 앞으로 남은기간은 프리프로젝트와 메인프로젝트를 앞두고 있는데, 걱정반 설렘반이다. 항상 부족하다고 생각하면서도 어떻게든 잘 해내리라는 믿음이 강하게 있다. 누구와 함께하던지, 긍정적인 분위기에서 좋은 결과를 만들 생각이다. 이번 한달 선방했지만 나에게 주어진 2달은 더 후회없는 날들로 채울 생각이다. 나를 포함한 모든 동기분들 진심으로 화이팅이다!

✔️ Try

  • Problem에 대한 해결책
    • 유어클래스보면서 다시한번 구현해보기. +항상 전체적인 구조를 그리면서 타이핑하기(입으로뻥끗뻥끗!)
    • 코딩에서 자주 쓰이는 용어를 정리하고, 정확히 이해되지않는 부분은 따로 모아두기
    • 프리프로젝트 하면서 열심히 생각해보기??
  • 다음 회고 때 판별 가능한 것
    • 운영체제 수강 완료
    • 자료구조 공부완료
    • 네트워크 책 완독
    • SQL책 완독
    • 고급원리 완강하기
  • 당장 실행 가능한 것
    • 오늘 하기로 한 일 마무리하기
    • 너무 늦지않게 잠자기

'Reminiscence' 카테고리의 다른 글

코드스테이츠 섹션2 회고  (0) 2023.02.10
코드스테이츠 섹션1 자바 회고..  (0) 2023.01.11

The Abstract Factory Pattern is a design pattern that provides an interface for creating families of related or dependent objets without specifying their concrete classes. This pattern is particularly useful when you need to create objects that are part of a group or have some common characteristics.

 

Key concepts of the Abstract Factory Pattern:

  1. Separate the process of creating objects from the actual implementation.
  2. Use interfaces to define factories and product families.
  3. Provide a common interface for creating a family of related objects.
  4. Enhance the maintainability and flexbility of the code by eliminating the need for hard-coded dependencies.

To further illustrate the Abstract Factory Pattern's advantages, let's consider an example involving a "Vehicle" class hierarchy. A vehicle can have different types such as car, motorcycle, or truck. Each vehicle type can have various attributes, such as color, engine type, number of wheels, etc. Using the Abstract Factory Pattern, you can create instances of different vehicle types while using the same construction process, making it easier to create different vehicle variations without having to write separate constructors for each combination.

 

Implementing the Abstract Factory Pattern:

  1. Create an interface for the abstract factory that declares methods for creating abstract products.
  2. Implement concrete factories that inherit from the abstract factory interface and create concrete products.
  3. Create an interface for each type of abstract product, which declares methods that the products must implement.
  4. Implement concrete products that inherit from the abstract product interfaces.
  5. Use the concrete factories to create instances of concrete products.

Here's a simple example of implementing the Abstract Factory Pattern using a "Vehicle" class hierarchy:

 

Abstract Vehicle class:

public abstract class Vehicle {
    public abstract String getColor();
    public abstract String getEngineType();
    public abstract int getNumberOfWheels();
}

 

Concrete Car class:

public class Car extends Vehicle {
    private String color;
    private String engineType;
    private int numberOfWheels;

    public Car(String color, String engineType, int numberOfWheels) {
        this.color = color;
        this.engineType = engineType;
        this.numberOfWheels = numberOfWheels;
    }

    @Override
    public String getColor() {
        return color;
    }

    @Override
    public String getEngineType() {
        return engineType;
    }

    @Override
    public int getNumberOfWheels() {
        return numberOfWheels;
    }
}

 

Abstract Factory interface:

public interface VehicleFactory {
    Vehicle createVehicle(String color, String engineType, int numberOfWheels);
}

 

Concrete CarFactory class:

public class CarFactory implements VehicleFactory {
    @Override
    public Vehicle createVehicle(String color, String engineType, int numberOfWheels) {
        return new Car(color, engineType, numberOfWheels);
    }
}

 

Client code:

public class Main {
    public static void main(String[] args) {
        VehicleFactory carFactory = new CarFactory();
        Vehicle car = carFactory.createVehicle("Red", "Gasoline", 4);
        System.out.println("Car color: " + car.getColor());
        System.out.println("Car engine type: " + car.getEngineType());
        System.out.println("Car number of wheels: " + car.getNumberOfWheels());
    }
}

Using the Abstract Factory Pattern improves the maintainability and flexibility of your code, making it easier to create complex objects with various attributes, and simplifying the process of extending the code with new types of objects.

'Java > Design Pattern' 카테고리의 다른 글

Understand of Builder Pattern  (0) 2023.04.06


Recently,  while studying Spring Security, I noticed a repetitive pattern in instance creation. I discovered that Java employed well-known design patterns following Object-Oriented Programming (OOP) principles. Today, I will explore the Builder Pattern sugin some exmaples.

 

The Builder Pattern is a design pattern that separates the construction of a complex object from its representation, allowing the same construction process to create different representations. This pattern is particularly useful when an object has many optional attribute, and it reduces the need for numerous constructors or complex parameter sets.

 

An example of using the Builder Pattern is when you have a class representing a sandwich. A sandwich can have various combinations of ingredients like bread, cheese, vegetable, and sause, Using the Builder Pattern, you can create different sandwich instances with different ingredients while following the same construction process

 

Key concepts of the Builder Pattern:

 

  1. Separate the construction of a complex object from its representation.
  2. Use the same construction process to create different representations.
  3. Reduce the need for multiple constructors or complex parameter sets.
  4. Simplify the creation of complex objects, making the code more maintainable and flexible.

 

To further illustrate the Builder Pattern's advantages, let's consider an example involving a "Car" class. A car can have different attributes such as color, engine type, number of doors, etc. Using the Builder Pattern, you can create car instances with different attributes while using the same construction process, making it easier to create different car variations without having to write separate constructors for each combination.

Implementing the Builder Pattern:

 

  1. Create the Builder class as a Static Nested Class. By convention, append "Builder" to the target class name. For example, the Builder class for a Car class would be named "CarBuilder".
  2. Make the Builder class's constructor public and accept essential values as parameters.
  3. Provide methods for optional values, ensuring that each method returns the Builder object itself.
  4. Define the build() method within the Builder class to provide the final product to the client program. Since object creation is provided only through build(), the target class's constructor should be private.
  5.  
public class Car {
    //required parameters
    private String engine;
    private int tires;

    //optional paramters
    private boolean ambientColor;
    private boolean extraTire;

    public String getEngine() {
        return engine;
    }

    public int getTires() {
        return tires;
    }

    public boolean isAmbientColor() {
        return ambientColor;
    }

    public boolean isExtraTire() {
        return extraTire;
    }

    private Car(CarBuilder builder) {
        this.engine = builder.engine;
        this.tires = builder.tires;
        this.ambientColor = builder.ambientColor;
        this.extraTire = builder.extraTire;
    }
    
    //Builder Pattern
    public static class CarBuilder{
        //required parameters
        private String engine;
        private int tires;

        //optional paramters
        private boolean ambientColor;
        private boolean extraTire;

        public CarBuilder(String engine, int tires) {
            this.engine = engine;
            this.tires = tires;
        }

        public void setAmbientColor(boolean ambientColor) {
            this.ambientColor = ambientColor;
        }

        public void setExtraTire(boolean extraTire) {
            this.extraTire = extraTire;
        }

        public Car build() {
            return new Car(this);
        }
    }
}

 

Using the Builder Pattern improves the maintainability and flexibility of your code, making it easier to create complex objects with various attributes.

 

This example is a code sinppet from the SecurityFilterChain class, used to configure an HttpSecurity instance. Although the concept is more complex than the previous example, it still applies the Builder Pattern to create an HttpSecurity instances.

 

    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .headers().frameOptions().sameOrigin() 
                .and()
                .csrf().disable()               
                .formLogin()                      
                .loginPage("/auths/login-form") 
                .loginProcessingUrl("/process_login")   
                .failureUrl("/auths/login-form?error")  
                .and()
                .logout()                       
                .logoutUrl("/logout")           
                .logoutSuccessUrl("/")
                .and()
                .exceptionHandling().accessDeniedPage("/auths/access-denied")
                .and()
                .authorizeHttpRequests(authorize -> authorize
                        .antMatchers("/orders/**").hasRole("ADMIN")       
                        .antMatchers("/members/my-page").hasRole("USER")  
                        .antMatchers("⁄**").permitAll()
                );              

        return http.build();
    }

 

In this code snippet, the Builder Pattern is used to configure various security settings for an HttpSecurity instance, such as headers, CSRF protection, authentication, and authorization. The builder methods are chained together to create a concise and readable configuration. The build() method at the end is called to create the final HttpSecurity instance with the specified configuration. This example demonstrates how the Builder Pattern can improve the readability and maintainability of code, even in more complex scenarios.

'Java > Design Pattern' 카테고리의 다른 글

About the Abstract Factory pattern  (0) 2023.04.09

+ Recent posts