데이터베이스 시스템

파일처리시스템의 문제점을 해결하기 위해 등장
다양한 형태의 데이터를 모아놓은 데이터의 집합체
데이터 베이스 관리 시스템

데이터 베이스의 등장 배경
이전에는 구조화되지 않은 파일처리 시스템이었다. 
하지만 파일처리에는 다양한 문제점들이 있어 데이터베이스 시스템이 등장하게 된다. 

 

 

 

 

*파일 처리 시스템의 문제점

 

1) 중복 : 파일처리시스템은 각 파일마다 필요한 데이터를 각각 가지고 있어야 하므로 전체적인 시간과 노력, 경제비용에 있어서 효율이 없다.

 

2) 비일관성 : 데이터에 변경사항이 조금만 있어도 각 파일에서 해당되는 데이터를 모두 변경해야 하므로 수정에 문제가 있고, 한꺼번에 수정이 되지 않으면 데이터값이 서로 틀리게 되는 문제점이 있다.

 

3) 응용 프로그램 개발 문제 : 기존의 파일 시스템은 파일 용도에만 맞춰서 제작되기 때문에 다른 프로그램을 만들때는 다시 데이터베이스 작업을 해야 한다는 문제가 있다

 

4) 데이터 추가 및 검색의 문제 : 데이터가 여러 파일에 산재하고 또 그 파일마다 데이터베이스 양식이 다르기 때문에 일률적인 검색이나 단순 추가 작업이 어렵다.

 

 

 

 

 


 

 

데이터베이스의 특징

1. 데이터의 독립성

  • 물리적 독립성 : 데이터베이스 크기를 늘리거나 성능 향상을 위해 데이터 파일을 늘리거나 새롭게 추가해도 관련 애플리케이션을 수정할 필요가 없다.
  • 논리적 독립성 : 데이터베이스는 논리적인 구조로 다양한 애플리케이션의 논리적 요구를 만족시켜준다.

 

2. 데이터의 무결성 

  • 데이터는 여러 경로를 통해서 들어오는데, 데이터에서 발생하는 경우의 수를 방지하는 기능으로 데이터의 유효성을 검사해서 무결성을 구현한다.

 

3. 데이터의 보안성

  • 인가된 사용자들만 데이터베이스나 데이터베이스 내에 자원을 접근할 수 있도록 계정 관리 또는 접근 권한을 설정

 

4. 데이터의 일관성

  • 연관된 정보를 논리적인 구조로 관리해서, 어떤 하나의 데이터만 변경했을 경우에 발생할 수 있는 불일치성을 배제할 수 있다.
  • 또 작업 중에 일부 데이터만 변경되서 나머지 데이터와 일치하지 않는 경우를 방지한다.

 

5. 데이터의 중복 최소화

  • 데이터베이스는 데이터를 통합해서 관리함으로써, 파일 시스템의 단점 중 하나인 자료의 중복과 데이터의 중복성 문제를 최소화할 수 있다.

 

데이터베이스의 장점

1. 데이터 공유

2. 데이터 중복의 최소화

3. 계속적 변화에 대한 적응

4. 보안성

 

 

 

데이터베이스의 성능

디스크 I/O를 어떻게 줄이냐에 따라 달려있다.

데이터를 읽는데 디스크 헤더의 위치 이동없이 얼마나 많은 데이터를 한번이 기록하느냐에 따라 결정된다.

따라서 순차적으로 I/O를 수행하는게 랜덤 I/O보다 빠르다.

 

 

 

쿼리 최적화, 빠른 쿼리를 위한 7가지 체크리스트

1. SELECT 시에는 꼭 필요한 칼럼만 불러와야 한다.

  • 너무 많은 필드값을 불러올 수록 DB는 더 많은 로드를 부담하기 때문에

 

2. 조건 부여시, 가급적 기존 DB값에 별도의 연산을 걸지 않는 것이 좋다.

  • 조건 검색이 필요할때 굳이 모든 필드 값을 탐색할 필요 없게 쿼리를 짜주자

 

3. LIKE 사용시 %(와일드카드문자열)를 string 앞부분에 배치하지 않는 것이 좋다.

  • 위의 2번과 마찬가지로 full table scan을 막게 다른 형태의 조건절을 사용하는것이 효과적이다.

 

4. SELECT DISTINCT, UNION DISTINCT와 같이 중복 값을 제거하는 연산은 최대한 사용하지 않아야한다.

  • 중복 값을 제거하는 연산은 시간이 많이걸리기 때문이다.
  • 차라리 EXISTS를 사용하자.

 

5. 같은 내용의 조건이라면, GROUP BY 연산 시에는 가급적 HAVING보다는 WHERE 절을 사용하는 것이 좋다.

  • WHERE 절이 HAVING절보다 먼저 실행되기 때문에 WHERE로 미리 데이터 크기를 줄여 놓는게 좋다.

 

6. 3개 이상의 테이블을 INNER JOIN 할 때는, 크기가 가장 큰 테이블을 FROM 절에 배치하고, INNER JOIN 절에는 남은 테이블을 작은 순서대로 배치하는 것이 좋다.

  • INNER JOIN 과정에서 최소한의 Combination을 탐색하도록 FROM & INNER JOIN의 순서를 배열하면 좋다는 이야기인데, 항상 통용되지는 않다.

 

7. 자주 사용하는 데이터의 형식에 대해서는 미리 전처리된 테이블을 따로 보관, 관리하는 것도 좋다.

 

 

 

 


<참고>

https://velog.io/@redgem92/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0%EC%99%80-%ED%8A%B9%EC%A7%95 https://yang1650.tistory.com/28

https://medium.com/watcha/%EC%BF%BC%EB%A6%AC-%EC%B5%9C%EC%A0%81%ED%99%94-%EC%B2%AB%EA%B1%B8%EC%9D%8C-%EB%B3%B4%EB%8B%A4-%EB%B9%A0%EB%A5%B8-%EC%BF%BC%EB%A6%AC%EB%A5%BC-%EC%9C%84%ED%95%9C-7%EA%B0%80%EC%A7%80-%EC%B2%B4%ED%81%AC-%EB%A6%AC%EC%8A%A4%ED%8A%B8-bafec9d2c073

스케줄러

Ready Queue에 존재하는 프로세스들을
특정한 우선순위를 기반으로 CPU를 할당받게 하는 역할로
장기, 중기, 단기 스케줄러가 있다.

 

프로세스를 스케줄링하기 위한 queue의 종류
1. Job Queue : 현재 시스템 내에 있는 모든 프로세스의 집합
2. Ready Queue : 현재 메모리 내에 있으면서 CPU를 할당 받기를 기다리는 프로세스의 집합
3. Device Queue : Device I/O 작업을 대기하고 있는 프로세스 집합

 

 

 


장기 스케줄러 Long - Term Scheduler

수행할 job이 10개, 메모리에는 6개 밖에 올릴 수 없는 상황
job 10개 중 6개를 골라서 올려야 하는데 이때 job을 고르는 역할을 하는 것이 장기 스케줄러
따라서 잡 스케줄러라고 불리기도 한다.

 

ready queue에 적재하는 메모리와 디스크 사이의 스케줄링을 담당하는 스케줄러인데,  I/O bound 중심의 프로세스들과 CPU bound 프로세스들의 적절한 비율을 조절해 올린다.

 

* I/O bound process : 입출력 많은 프로세스 (이 비율이 높으면 놀고 있는 cpu 많아짐)

CPU bound process : CPU가 계산을 해줘야 하는 비중이 큰 프로세스 (이 비율이 높으면 사용자와 상호적이지 못해서 실시간적인 의미 없어짐)

 

1. 어떤 프로세스를 Ready Queue에 삽입할지 결정

2. 메모리와 디스크 사이의 스케줄링을 담당

3. 프로세스에 메모리를 할당 

4. 메모리에 동시에 올라가 있는 프로세스의 수를 조절 

5. 프로세스의 상태[new -> ready(inmemory)]

 

 

 

 

단기 스케줄러 Short - Term Scheduler

장기 스케줄러를 통해서 job을 6개를 고른 상태
CPU에서 하나를 수행완료하고 나머지 job중 에서 하나를 골라야하는데 이걸 골라주는 스케줄러
따라서 CPU 스케줄러라고 불리기도 한다.

CPU가 낭비되지 않게 A라는 프로세스가 수행되다가 사용자의 입력을 받기 위해 cpu가 대기하는 상황이 되면 바로 B 프로세스로 교체해서 수행시킨다. 그러다 사용자의 I/O가 끝나면 다시 A프로세스를 cpu로 불러온다.

 

최소 100밀리 세컨즈마다 수행되어 단기 스케줄러라 불린다.

 

장기 스케줄러와 단기 스케줄러 -> CPU 스케줄러

요즘엔 virtual memory management가 발달해서 job이 10개면 메모리로 10개가 다 올라온다. 

즉, 장기 스케줄러의 의미가 없다는 것인데, long term이 없다면 short term의 의미가 무색해지기 때문에 주로 CPU 스케줄러라고 불린다. 

 

1. CPU와 메모리 사이의 스케줄링을 담당하며 CPU 스케줄러라고도함

2. Ready Queue에 존재하는 프로세스들 중 스케줄링 알고리즘에 따라 CPU를 할당할 프로세스 선택

3. 프로세스의 상태[ready -> running -> waiting -> ready]

 

 

 

 

 

중기 스케줄러 Medium - Term Scheduler

장기/단기 이후에 나왔다. 위에서 말했듯이 현재 개념은 가상 메모리개념이기 때문에 중기 스케줄러 또한 이용되지 않는다.

장기 스케줄러에 의해 10개 중 6개의 job을 올려서 수행중인 상태
CPU가 수행하려고 보니 감당하기엔 너무 많아 문제가 생겨 6개 중 2개를 내려보내면 상황이 해결될 것
6개 중 뭘 내려보낼지 결정하는 것이 중기 스케줄러의 역할 
Swapper라고도 불린다.

 

 

프로세스를 내릴 때 우선순위가 가장 낮은 프로세스나 일정 시간 동안 활성화되지 않았던 프로세스들을 내린다.

 

프로세스를 내리고 (swapping out) 다시 올려지는 (swapping in) swapping과정을 수행하기 때문에 swapper라고 불린다.

 

 

 1. 메모리에 적재된 프로세스의 수를 동적으로 조절

2. 메모리적재된 프로세스의 수가 많을 때 메모리를 통째로 디스크의 스왑 영역에 저장(Swap Out)

3. 프로세스의 상태[ready -> suspended]

 

 

 

 

 


<참고>

https://kmseop.tistory.com/119 https://jhnyang.tistory.com/372

Process Management 
프로세스가 여러 개 때, CPU가 CPU 스케줄링을 통해 관리하는 것
( 이때 CPU는 각 프로세스들이 누군지 알아야 관리가 가능하다. 이러한 프로세스들의 특징을 갖고 있는 것이 Process Metadata이다. )

 

[ Process Metadata ]

  • Process ID : PID(Process Identification Number)라고도 한다. // 프로세스 고유 식별번호
  • Process State : 프로세스의 현재 상태(준비, 실행, 대기)를 기억시킨다. //프로세스 상태
  • Process Priority : 프로세스 우선순위 등과 같은 스케줄링 관련 정보를 기억시킨다. //스케줄링 정보
  • CPU Registers : 프로세스의 레지스터 상태를 저장하는 공간으로 CPU 내 범용 레지스터, 데이터 레지스터, 세그먼트 레지스터 등이 갖고 있는 값을 기억시킨다.
  • Owner : CPU 사용시간의 정보(Quantum)과 각종 스케줄러에 필요한 정보를 기억시킨다. //계정 정보
  • 기억장치 관리 정보 : 프로그램이 적재될 기억 장치의 상한치, 하한치, 페이지 테이블 등의 정보를 기억시킨다.
  • 입출력 정보 : 프로세스 수행 시 필요한 주변 장치, 파일들의 정보를 기억시킨다.
  • 프로그램 카운터 : 다음에 실행되는 명령어의 주소를 기억시킨다. //계수기

이러한 정보들이 담긴 메타데이터는 프로세스가 생성되면 PCB라는 곳에 저장된다!

 


PCB (Process Controll Block)

프로세스 메타데이터들을 저장해 놓는 곳
하나의 PCB 안에는 하나의 프로세스의 정보가 담겨있다

프로그램 실행 -> 프로세스 생성 -> 프로세스 주소 공간에 (코드, 데이터, 스택) 생성 -> 이 프로세스의 메타데이터들이 PCB에 저장

 

 

PCB 상세 구조 ->

 

 

 

 

 

 

 

PCB가 필요한 이유 

CPU에서는 프로세스의 상태에 따라 교체 작업이 이루어진다.

이때 앞으로 다시 수행할 Block 상태의 프로세스의 상태값을 PCB에 저장해둔다. 

 

 

 

PCB의 관리 방식

Linked List 방식으로 관리된다. PCB list head에 PCB 생성될 때마다 붙게 된다. 연결이 이루어져있는 연결리스트 형태로 삽입, 삭제 용이

프로세스가 생성되면 해당 PCB가 생성되고 프로세스 완료시 제거가 된다.

 

이렇게 수행 중인 프로세스를 변경할 때, CPU의 레지스터 정보가 변경되는 것을 Context Switching이라고 한다.

 

 


 

Context Switching

CPU가 현재 실행하고 있는 task(process, thread)의 상태를 저장하고
다음 진행할 task의 상태 및 register 값들에 대한
정보(context)를 읽어 새로운 task의 context 정보로 교체하는 과정

 

* context란 : CPU가 다루는 Task(Process / Thread)에 대한 정보를 말하고, 대부분의 정보는 Register에 저장되고 pcb로 관리된다. 

 

 

인터럽트가 발생하거나, 실행 중인 CPU 사용 허가 시간을 모두 소모하거나, 

입출력을 위해 대기해야 하는 경우 Context Switching이 발생

프로세스가 Ready -> Running , Running -> Ready , Running -> Block 처럼 상태 변경 시에 발생

 

 

 

Context Switching 수행 과정

1. Task의 대부분 정보는 Register에 저장되고 PCB(Process Control Block)로 관리

2. 현재 실행하고 있는 Task의 PCB 정보를 저장 (Process Stack, Ready Queue)

3. 다음 실행할 Task의 PCB 정보를 읽어 Register에 적재하고 CPU가 이전에 진행했던 과정을 연속적으로 수행

 

 

Context Switching Cost

1. Cashe 초기화

2. Memory Mapping 초기화

3. 메모리의 접근을 위해서 항상 실행되어야 하는 kernel

위와 같은 Cost가 소요되기 때문에 잦은 context switching은 성능 저하를 가져온다.

 

* Process가 Thread보다 많이 든다. ( Thread는 stack영역을 제외한 모든 메모리를 공유하기 때문에 context switching 발생시 stack 영역만 변경하면 되기 때문)

 

 

 

Context Switching과 Interrupt

CPU는 하나의 프로세스 정보만을 기억한다.

여러 프로세스가 실행되는 다중 프로그래밍 환경에서는 CPU가 각각의 프로세스의 정보를 저장했다가 복귀하고 다시 저장했다가 복귀하는 일을 반복하는 것이다.

프로세스 중단과 실행시 interrupt가 발생하므로 context switching이 많이 발생한다는 것은 interrupt가 많이 발생한다는 것을 의미한다.

 

 

Context Switching과 시간 할당량

시간 할당량이 적어지면 :

문맥 교환 수, 인터럽트 횟수, 오버헤드가 증가하지만 여러 개의 프로세스가 동시에 수행되는 느낌을 갖는다.

 

시간 할당량이 커지면 :

문맥 교환 수, 인터럽트 횟수, 오버헤드가 감소하지만 여러 개의 프로세스가 동시에 수행되는 느낌을 갖지 못한다.

 

 

 


<참고>

https://m.blog.naver.com/adamdoha/222019884898 https://jhnyang.tistory.com/33

 

HTTP

웹 상에서 클라이언트와 서버 간에 데이터를 주고 받을 수 있는 프로토콜인
HTTP 메소드에는 크게 2가지 방식이 있는데
그것이 GET 방식과 POST 방식



GET 

'가져오다'
어떠한 정보를 가져와서 조회하기 위해서 사용되는 방식
  • URL에 변수(데이터)를 포함시켜 요청
  • 데이터를 header에 포함시켜 전송
  • URL에 데이터가 노출되어 보안에 취약
  • 캐싱 가능

GET은 URL끝에 ?와 함께 이름과 값으로 쌍을 이루는 요청 파라미터(쿼리 스트링)를 통해 필요한 데이터를 서버로 전송한다. 쿼리 스트링이 여러개일 경우 &로 연결해준다.

 

불필요한 요청을 제한하기 위해 요청이 캐시될 수 있다.

ex. js, css와 같은 데이터 양이 크고 변경될 일이 적은 정적 컨텐츠

정적 컨텐츠를 요청하고 나면 브라우저에서는 요청을 캐시한다. 동일 요청 발생시 서버로 요청을 보내지 않고 캐시된 데이터를 사용한다.

프론트앤드 개발시 정적 컨텐츠가 캐시되어 컨텐츠를 변경해도 적용되지 않는 경우 브라우저의 캐시를 지워주면 해결된다.

 

POST

'제출하다'
데이터를 서버로 제출하여 추가 또는 수정하기 위해 사용하는 방식, 작업 수행 시 사용됨
  • URL에 변수(데이터)를 노출하지 않고 요청
  • 데이터를 body에 포함시켜 전송
  • URL에 데이터가 노출되지 않아서 기본 보안이 되어있음
  • 캐싱 불가능

GET과 달리 http 메세지의 길이 제한이 없는 body에 담아서 보내기 때문에 대용량 데이터를 전송할 수 있다. 

 

GET보다는 보안성이 높지만 크롬 개발자 도구나 Fiddler와 같은 툴로 요청 내용 확인이 가능하기 때문에 민감 데이터 전송시에는 반드시 암호화를 해야한다.

 

POST는 요청 헤더의 content-type에 요청 데이터 타입을 표시해야 한다.

표시하지 않으면 서버는 내용이나 URL에 포함된 리소스 확장자명 등으로 데이터 타입을 유추하고, 알 수 없는 경우엔 aplication/octet-stream로 요청을 처리함

 

 

 

 

 

GET과 POST와 멱등성

멱등 - 동일한 연산을 여러 번 수행하더라도 동일한 결과가 나타나는 것

 

GET은 서버에게 동일한 요청을 여러번 전송하더라도 동일한 응답이 돌아와야하는 멱등성을 갖도록 설계되어있다.

서버의 데이터나 상태를 변경시키지 않아야 멱등성을 갖게 되기 때문에 GET은 주로 조회시 사용되는 것이다.

 

POST는 서버에게 동일한 요청을 여러 번 전송하더라도 응답은 다 다를 수 있다.

따라서 서버의 상태나 데이터를 변경시킬 때 사용이 된다.

 

 

 

 

 


<참고>

https://mangkyu.tistory.com/17 https://hongsii.github.io/2017/08/02/what-is-the-difference-get-and-post/ 

'🔥 > Network' 카테고리의 다른 글

[네트워크] OSI 7계층  (0) 2021.09.09
[네트워크] 웹 통신의 큰 흐름  (0) 2021.08.31
[네트워크] DNS round robin 방식  (0) 2021.08.25
[네트워크] HTTP와 HTTPS의 차이점  (0) 2021.08.18
[네트워크] TCP와 UDP 차이점  (0) 2021.08.10

항공기

 

⊙ AmsField

package ams;

public class AmsField {
	//				Key
	// 항공사, 항공기번호, 최대승객수, 출발지, 도착지
	String[][] arrPlane = new String[100][5];
	int insertCnt;
	int updateIndex;

	// 추가
	// 2차원 배열에 5개의 정보를 담기
	void insert(String[] arPlane) {
		arrPlane[insertCnt] = arPlane;
		insertCnt++;
	}

	// 수정
	void update(int index, String newValue) {
		boolean updateCheck = true;
		//항공사, 항공기번호, 승객수, 출발지, 도착지
		//0			1				2			3			4
		//index : 0, 1
			arrPlane[updateIndex][index+3] = newValue;
	}

	// 삭제
	void delete() {
	}

	// 검색
	String select(int index, String keyword) {
		int[] arIndex = null;
		int searchCnt = 0;
		String result = "";
		updateIndex = -1;
		
		for (int i = 0; i < insertCnt; i++) {
			if (keyword.equals(arrPlane[i][index])) {
				// i >> 행번호 : 검색할 비행기 번호
				searchCnt++;
				updateIndex = i;
				//바로 int배열에 담을 수 없기 때문에(검색 건수를 모르기 때문)
				//문자열에 검색된 행번호를 연결시켜 담는다.(", "는 구분점이다.)
				//구분점이 있어야지만 밑에서 각 값을 나눌 수 있기 때문이다.
				result += i + ", ";
			}
		}
		//검색 건수를 for문이 끝난 후에 알 수 있기 때문에
		//for문 밑에서 new 해준다.
		arIndex = new int[searchCnt];
		for (int i = 0; i < arIndex.length; i++) {
			//	result는 문자열이고 split() 사용시 
			//전체를 배열로 보기 때문에 그 뒤에 바로 []를 사용할 수 있다.
			arIndex[i] = Integer.parseInt(result.split(", ")[i]);
		}
		//list(int[] arIndex)메서드에 값을 전달하고 list(int[] arIndex)에서 리턴된
		//결과값을 select()에서 리턴한다.
		return list(arIndex);
	}

	// 목록
	String list() {
		String result = "항공사, 항공기번호, 최대승객수(명), 출발지, 도착지\n";
		for (int i = 0; i < insertCnt; i++) {
			result += "♥";
			for (int j = 0; j < arrPlane[0].length; j++) {
				result += arrPlane[i][j];
				result += j == arrPlane[0].length - 1 ? "" : ", ";
			}
			result += "\n";
		}

		if (insertCnt == 0)
			result = "목록 없음";

		return result;
	}
	
	String list(int[] arIndex) {
		String result = "항공사, 항공기번호, 최대승객수(명), 출발지, 도착지\n";
		for (int i = 0; i < arIndex.length; i++) {
			result += "♥";
			for (int j = 0; j < arrPlane[0].length; j++) {
				result += arrPlane[arIndex[i]][j];
				result += j == arrPlane[0].length - 1 ? "" : ", ";
			}
			result += "\n";
		}

		if (arIndex.length == 0)
			result = "검색 결과 없음";

		return result;
	}
	
}

 


 

⊙ AmsMain

package ams;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

public class AmsMain {
	public static void main(String[] args) {
		String title = "항공기 관리 프로그램";
		String[] menu = {"추가하기", "검색하기", "수정하기", "삭제하기", "목록보기"};
		String[] updateMenu = {"출발지 수정", "도착지 수정"};
		String[] updateMsg = {"출발지", "도착지"};
		AmsField af = new AmsField();
		ImageIcon icon = new ImageIcon("src/img/main.gif");
		int choice = 0;
		String[] arPlane = new String[5];
		String keyword = "";
		
		while(true) {
			choice = JOptionPane.showOptionDialog(null, "", title, JOptionPane.DEFAULT_OPTION,
					JOptionPane.PLAIN_MESSAGE, icon, menu, null);
			
			if(choice == -1) break;
			
			switch(choice) {
			//추가
			//항공사, 항공기번호, 최대승객수(명), 출발지, 도착지
			case 0:
				//5개의 값을 ", "로 구분하여 한번에 입력하기
				//split("구분점")은 리턴타입이 문자열 배열이다.
				//구분점이 있다는 것은 최소한 값이 2개 이상이기 때문에 배열로 리턴한다.
				arPlane = ("" + JOptionPane.showInputDialog(null,
						"항공사, 항공기번호, 최대승객수(명), 출발지, 도착지", title, JOptionPane.PLAIN_MESSAGE,
						icon,	null, null)).split(", ");
				
				af.insert(arPlane);
				break;
			//검색
			case 1:
				break;
			//수정
			case 2:
				String newValue = "";
				
				choice =JOptionPane.showOptionDialog(null, "", title, JOptionPane.DEFAULT_OPTION,
						JOptionPane.PLAIN_MESSAGE, icon, updateMenu, null);
				
				if(choice == -1) break;
				
				keyword = "" + JOptionPane.showInputDialog(null,
						"수정하실 항공기 번호를 입력하세요", title, JOptionPane.PLAIN_MESSAGE,
						icon,	null, null);
				
				if(af.select(1, keyword).equals("검색 결과 없음")) {
					JOptionPane.showMessageDialog(null, "수정 실패");
				}else {
					newValue = "" + JOptionPane.showInputDialog(null,
							"새로운 " + updateMsg[choice] + "를 입력하세요", title, JOptionPane.PLAIN_MESSAGE,
							icon,	null, null);
					af.update(choice, newValue);
					JOptionPane.showMessageDialog(null, "수정 성공");
				}
				
				break;
			//삭제
			case 3:
				break;
			//목록
			case 4:
				JOptionPane.showMessageDialog(null, af.list());
				break;
			}
		}
	}
}

 

생성자의 목적

1. 힙 메모리 영역에 클래스 필드를 생성해주는 목적

2. 초기화 역할

 

메서드의 모양 :  name ( )

생성자의 모양 : class name ( )

 

위처럼 생성자도 메서드와 생김새가 비슷하네?

생성자도 메서드다

그렇다면 왜 생성자는 메서드라고 하지 않을까?

 


 

생성자는 메서드의 기능과 똑같지만 return이 없기 때문에 메서드라고 부르지 않는다.

 


클래스를 만드는 순간 굳이 생성자를 일부를 만들어주지 않아도 기본 생성자라는 것이 생기는데, 보이진 않지만 내부적으로 올라간 것이다.

따라서 선언없이 사용이 가능하다.

 

기본 생성자

1. 클래스 선언 시 자동으로 생성된다.

2. 사용자가 직접 선언하지 않아도 사용 가능하다.

3. 사용자가 직접 생성자를 선언하는 순간 그것을 기본 생성자로 여겨서 따로 기본 생성자가 생기진 않는다.

 


< 변수 >

매개변수 : { } 안, 닫는 중괄호를 만날 때 끝난다

매개 변수와 지역변수는 stack에 저장이된다.

전역 변수는 data 영역에 저장된다.

 


오버 로딩 Overloading

매개변수의 개수나 타입이 다를 때, 같은 이름으로 선언할 수 있다.

         →  메서드의 이름은 같으나 매개변수의 갯수 혹은 타입이 다르면 선언 가능

load : 나갔다가 다시 불러올 때

over : 넘치게

overload : 넘치게 불러온다 (같은 이름이라) 

 

《 오버 로딩은 메서드의 첫 번째 기능 ≫

 


Car와 Road를 만들어보자

 

package studyalone;

public class Car {
	//Car 클래스는 브랜드, 색, 가격, 비번을 갖고 있다
	String brand;
	String color;
	int price;
	String pw="1122";
	
	//생성자 , 비번 새로
	public Car(String b, String c ,int p,String pw) {
		this.brand=b; this.color=c; this.price=p;this.pw=pw;
	}
	
	//생성자 , 초기 비번 그대로
	public Car(String b, String c ,int p) {
		this.brand=b; this.color=c; this.price=p;
	}
	
	//외부에서 비밀번호 입력받기
	//입력받은 비밀번호와 자동차의 비밀번호를 비교하기
	//비밀번호가 일치한다면 시동 켜주기
	//이미 시동이 켜져있다면 "시동이 이미 켜져있습니다"출력
	//이미 시동이 꺼져있다면 "시동이 이미 꺼져있습니다"출력
	//비번 3회 오류 시 경찰 출동
	
	boolean isOn=false;
	int policeCnt;
	
	//시동키는 메서드
	boolean engineStart(String pw ){
		boolean policeCheck=false;
		
		if(this.pw.equals(pw)) {
			if(!isOn) {
				System.out.println(this.brand+" 시동 킴");
				isOn=true;
				policeCnt=0;
			}else {
				System.out.println(this.brand+" 시동이 이미 켜져있음");
			}
		}else {
			policeCnt++;
			if(policeCnt==3) {
				System.out.println("경찰 출동");
				policeCheck=true;
			}else {
				System.out.println("비밀번호 오류");
			}
		}
		return policeCheck;
	}
	
	
	//시동끄는 메서드
	void engineStop(){
		if(!isOn) {
			System.out.println(this.brand+" 시동 끔");
		}else {
			System.out.println("시동이 이미 꺼져있습니다.");
		}
	}
	
	
	//자동차 정보 출력 메서드
	void show() {
		System.out.println(brand+", "+color+", "+price+"만원");
		//지역변수가 같은 이름이 아니라서 굳이 this.brand등등으로 하지 않은 것
	}

	
}
package studyalone;

import java.util.Scanner;

public class Road {
	public static void main(String[] args) {
		Car myCar=new Car("벤틀리","blue",1500,"981122");
		
		String menu= "1. 시동 켜기\n2. 시동 끄기";
		Scanner sc =new Scanner(System.in);
		int choice=0;
		String tryPw="";
		
		myCar.show();
		
		//무한반복 
		//시동을 한번이라도 킨 후 시동을 끄면  break
		while(true) {
			System.out.println(menu);
			
			choice=sc.nextInt();
			
			if(choice==1) {
				System.out.println("비밀번호를 입력하세요");
				tryPw=sc.next();
				
				if(myCar.engineStart(tryPw))
					break;
			}else if(choice==2) {
				//시동을 한번이라도 켜기 전엔 isOn이 false니까 break안함
				//한번이라도 시동을 겼다면 isOn은 true니까 break함
				if(myCar.isOn) {
					myCar.engineStop();
				}else {
					myCar.engineStop();
				}
			}
		}
		
	}
}

 

alt shift n 새로운 프로젝트 만들기
ctrl n 새로운 클래스 만들기 ( 해당 프로젝트의 src 선택 후 )
alt ㅁ 프로젝트, 클래스, 인터페이스에서 해당 이니셜로 선택할 수 있음
ctrl shift + 글씨 키우기
ctrl shift - 글씨 줄이기
ctrl m 전체화면
insert 쓰는것이 겹쳐지면서 지워지게하는 커서
alt shift s o 생성자 만들기
alt shift r 전체적으로 이름 바꾸기 ( class 이름도 )
ctrl space바 자동완성
ctrl z 뒤로가기
ctrl s 저장
ctrl x 저장하고 해당 영역 삭제
ctrl t 가족 관계도
ctrl shift o 자동 import
ctrl shift f 줄 맞춤
alt 위 아래 해당영역 위 또는 아래로 이동
ㅊ한자 제곱근이나 1/2같은 기호 사용

 


 

전역 변수는 data 영역에 저장된다.

전역변수는 자동 초기화가 된다.

 


%f 를 쓰면 기본적으로 소수점 6자리가 나온다.

float는 4바이트이자 32비트다.

 

3.7이란 숫자를 float로 저장한다고 하면

1bit 8bit 23bit
양수면 0 / 음수면 1 exp 진수 영역 f 가수 영역
3.7은 양수니까 0 3.7의 정수는 3이니까 0011

3.7의 0.7이 가수영역이니까 이진수로 교환 // 가수영역 * 2 한 값이 1보다 크면 1을 넣고 (계산값-1)*2를 해준다. 1.0이 되는 순간까지 무한 반복을 하거나 24비트에서 반올림 된다.

0.7*2=1.4 ---> 1써짐 ---> 1.4-1=0.4

0.4*2=0.8 ---> 0써짐

0.8*2=1.6 ---> 1써짐 ---> 1.6-1=0.6

           . . .

0 0000 0011 10110...

 

이런 식으로 비트가 반올림되는 컴퓨터 연산의 오류가 있다.

 

그래서 7자리 까진 정확하지 않고 기본적으로 6자리까지 정확하다.

따라서 %f 는 기본적으로 6자리까지 출력이 되는 것이다.

 


eclipse를 처음 깔면 perspective를 java로 선택이 되어있는지 확인해야 한다.

java로 선택해놓으면 package explorer이 켜지는 것이다.

+ Recent posts