JAVA

복습) 메모리, 스택 오버 플로우, 재귀 함수, 상태는 행위로 변경

JJJAEOoni 2022. 5. 30. 17:52
반응형

이클립스 설정

utf-8 설정

요새 기본 데이터베이스 세팅은 utf-8이 아닌 utf-8mb4이다.

얘는 이모지도 사용이 가능하다. 이모지는 그림이 아닌 글자이다.

회사에서 자바버전 11을 쓴다면 flux를 쓴다는 것이다.

flux -> 서드파티 라이브러리 (외부 라이브러리)가 인기가 많아서 표준이 되었다. -> 1.9

flux : 구독과 출판기술을 구현하게 해주는 라이브러리

구독과 출판? A 신문사는 출판을 한다. 스포츠를 할수도있고 음악을 할수도있고 게임을할수도있잖아.

그러면 구독자들은 신문사의 게임만 구독하면 게임이 딱 insert 됐으니까 모든 게임을 구독하고있는사람한테 push해주는 기능

보통 SSE response 선이 유지되어있지 않으면 못해준다.

 

외부 라이브러리 사용하고싶으면 다운받아서 빌드패스 설정해줘야함.

빌드패스?

a라는 프로그램이 만들어지기 위해서는 각종 라이브러리가 필요하다.

라이브러리가 모여있는 폴더가 있다.

그리고 이 폴더를 C:\lib폴더라고 하자.

그러면 a프로젝트는 프로젝트를 생성하고 나서 C드라이브를 클래스 패스로 지정해야한다.

즉 라이브러리가 있는 경로를 지정해둬야하는것이다.

이걸 지정하는것을 자바에서 빌드패스라고한다.

 

빌드가 만들다는거잖아 보통 실행파일을 만들때 사용하는 말인데

실행파일을 만들기 위해 라이브러리가 필요하기 때문에 빌드패스라고 한다.

 

만약 롬복 라이브러리를 추가하고싶어. .jar파일을

얘가 C:\lombok에 있다고 한다면 사용할 수 없다. 빌드패스를 지정해줘야한다.

그래서 우리는 이렇게 안만들거다.

 

다운과 빌드패스를 자동으로 해주고 실행파일을 만들때도 필요한 파일을 다 엮어서 만들어준다.

이런걸 의존성 관리 도구라고 한다.

 

gradle을 메타 프로그래밍이라고 한다.

 

내가 보글보글 프로그램 소스코드를 만들면 내가 실행파일로 생성해야하는데

실행파일을 생성해주는 애들을 메타 프로그래밍이라고 한다.

 

실제 프로그램을 도와주는 애들! 서포트!

 

gradle이 없다면 내가 직접 스크립트를 다 짜야한다. 컴파일하고, 라이브러리 지정하고, 등등

 

이클립스같은 툴이 export를 눌러 jar파일로 생성할 수 있게 툴에서 도와준다.

리눅스같은 CLI 환경에서는 툴을 사용할 수 없는데 그때는 내가 다 짜야하는것이다.

그때 도와주는 애들이 gradle, maven같은 의존성 관리도구, 메타 프로그래밍이다.

 

 


static은 클래스 내부에서만 만들 수 있다.

 

0년도~ 2022년도

0년도~~~~~~~~~~ 끝까지 : static 메모리를 너무 많이 잡아먹음

1999년도 ~~~~~~~ 죽을때까지 : heap 동적으로 떴다가 동적으로 사라짐

메모리 관리하려고 static과 heap을 나눔

메모리가 5000기가에 1원이라고 한다면 안나눴을거야

비싸기 때문에 메모리를 효율적으로 사용하기 위해 나온 기술임

행위가 시작될 때 메모리에 뜨는 것 : stack

재민이가 성현이 공격할 때 (행위) ->

성현이의 발 위치, 눈동자 위치 이런거 잠깐 떠서 기억해야 하는 것

행위가 끝나고 나면 다 날아가도됨

 

재민이가 치명적인 공격을 당했을 때 복수하기 위해 사라지지 않고 오래 기억하고 싶으면 heap으로 옮겨둔다.

 

클래스는 상태와 행위를 가진다.

상태는 있는데 행위는 없을 수 있지만 (변화가 필요없는 상태)

상태는 없는데 행위만 있는건 객체 지향 프로그램이라고 볼 수 없다.

 

객체지향 프로그래밍 1원칙. 상태는 행위를 통해 변경한다.

 

사자를 메모리에 띄울 책임은 누구에게도 없다. 이런건 메인에서 띄운다.

모든 프로그램의 모든 상태는 메인이 가지고있다.

메인이 컨텍스트를 가지고있다.

package site.metacoding.ex01;

// heap, stack, static(클래스 종속 키워드)
class Lion {
	int 배상태 = 0;
}

public class StackOverFlowEx01 {

	public static void main(String[] args) {
		// Lion을 new 할(메모리에 띄울) 책임은 누구도 없다 -> main
		Lion lion = new Lion();
	}
}

new를 한다는 것은 static이 아닌 모든것들을 heap에 띄운다는 것.

배고픔이 static이라면 lion이 new되었을 때 heap에는 아무것도 없다.

 

상태는 행위를 통해 변경해야하니까 행위를 만들어보자.

 

eat()을 통해 상태를 변경할거긴 하지만 얘로만 변경이 가능하다고 보장이 안된다.

lion.배상태 = 100000; 이 가능하기 때문이다.

private를 붙여줘야한다.

package site.metacoding.ex01;

// heap, stack, static(클래스 종속 키워드)
class Lion {
	private int 배상태 = 0;
	
	public void eat() {
		배상태++;
	}
}

public class StackOverFlowEx01 {

	public static void main(String[] args) {
		// Lion을 new 할(메모리에 띄울) 책임은 누구도 없다 -> main
		Lion lion = new Lion();
	}
}

 

메서드가 갖고있는 변수는 상태가 아니다.

먹을때마다 행복함을 기억하고싶어.

lion.eat하면 happy는 10이될텐데 메서드가 끝나고나면 happy는 0이 되는게 아니라 사라지게 된다.

분명히 먹었는데.

 

그리고 다시 eat( )을 호출하면 배상태는 2가 되고 배는 찼지만 행복은 10이된다.

 

eat( ) 스택의 메모리는 4바이트 공간이 생성되고 메서드가 종료되면 사라진다.

행위를 할 때만 단기기억하는것이다.

 

public void eat() {
	int happy = 0; // 지역 변수
	배상태++;
	happy = happy + 10;
	eat();
}
.
.
.
lion.eat();

 

만약 이렇게된다면?

 

첫번째 호출이 있고 다시 eat() 을 호출했을 땐 첫번째 호출 스택이 닫히지 않은 상태이다.

스택의 용량에 한계가 있을텐데 이때 스택오버플로우가 터진다.

 

스택오버플로우는 재귀메서드를 호출한다고 무조건 터지는게 아니라 스택이 스택을 호출하면서 ~~

 

이걸 멈추게 하려면 먹다가 break를 걸어주면 된다.

 

for문 돌리기 귀찮을때 재귀메서드를 사용한다.

package site.metacoding.ex01;

// heap, stack, static(클래스 종속 키워드)
class Lion {
	private int 배상태 = 0;
	
	public int get배상태() {
		return 배상태;
	}
	
	public void eat() { // 재귀 메서드

		int happy = 0; // 지역 변수
		배상태++;
		happy = happy + 10;
		
		if (배상태 >= 100) {
			
		} else {
			eat();
		}
	}
}

public class StackOverFlowEx01 {

	public static void main(String[] args) {
		// Lion을 new 할(메모리에 띄울) 책임은 누구도 없다 -> main
		Lion lion = new Lion();
		lion.eat();
		System.out.println("아 배불러 : " + lion.get배상태());
	}
}
반응형