본문 바로가기

TIL

Hello Java!

오늘부터 본격적으로 자바에대해서 학습을한다.

이전에 이미 spring으로 rest api를 만들줄알고 JPA등을 사용할 줄은 알지만,

정확히 이게 무엇인지 왜 어떨때 사용하는지에 대한 개념이 없기때문에, 여기사 정확하게 학습하고 가고자 한다.

 

이전에 이미 JVM에 대해서 조금 깊게 공부한 경험이있어서 JDK ,JVM에관한 내용은 알고있는 사항이었다.

 

☕ JDK / JRE / JVM 개념 & 구성 원리 💯 총정리

자바를 처음 설치하면 C:\Program Files\Java 폴더에 아래와 같이 JDK와 JRE 가 각각 설치되는 것을 볼 수 있다. 그렇다면 이 JDK와 JRE의 역할은 무엇인지 그리고 자바 프로그램(JVM)은 어떤식으로 돌아가

inpa.tistory.com

 

 

☕ JVM 내부 구조 & 메모리 영역 💯 총정리

저번 포스팅에서는 JRE / JDK / JVM에 대해서 간략하게 알아보는 시간을 가졌다면, 이번 포스팅에서는 JVM의 내부 구조에 대해 좀 더 자세하게 알아보도록 할 예정이다. JVM(자바 가상 머신)은 자바 언

inpa.tistory.com

내가 자주 읽어보는 인파님의 블로그인데 jvm이 뭐하는놈인지 강의보다 조금 심도있게 알고자 한다면 해당 글들을 읽어봐도 좋을거같다.

 

JAVA의 특징

c,c++ 같은 언어들은 운영체제마다 코드를 다시 작성해야했지만, 자바는 그렇지 않다

1. 플랫폼의 독립성 :  JVM을 통해 어느 환경에서든 실행이 될 수 있는것이다.( Write Once, run anywhere)

2. 객체지향 : java의 모든 것들을 객체(class) 로 이루어져 있다.

3. 거대한 생태계 : 가장 많이전세계에서 사용하고있는 언어로 확실히 구글링도 잘되고 커뮤니티가 잘 되어있다.

 

JDK?? JVM?? 

JDK란 자바프로그램을 개발할때 필요한 개발도구의 모음. 강의에선 두가지 구성요소만 소개를 해줬다.

javac, JVM

Javac 란 Java Compiler의 줄임말이고 파일을 JVM이 이해할 수 있는 바이트 코드로 변환을 해준다.

간단하게 첨언을 하자면, 우리가 코드를 작성하고 동작을할때 우리가 작성한거처럼 int i = 0; 이걸 그대로 컴퓨터가 이해할 수없기때문에 컴퓨터가 이해할 수 있는 언어로 변환을 시켜준다.

하지만 os별로 (window,mac등) 이걸 이해하는 언어가 다 다르기때문에 c,c++같은 언어들이 각각의 os별로 코드를 작성해야 하는것이다.

 

하지만 java는 jvm을통해 모든 코드를 해당 os에 맞게 변환을 해주기때문에 javac는 jvm이 이해할 수 있는 언어로 변환을 시켜주는 것이다. 

* 보면 알겠지만 JVM을통해 파일을 두번 변환하는 만큼 한번만 변환하는 c,c++ 보다 속도가 느리다는 단점이있다.게임이나 속도가 중요한 프로그램을 c,c++ 로 만드는 이유가 여기에있다. 

* 느리다는 단점을 보안하기위해 JIT컴파일러같은걸 사용하지만 그래도 c의 속도는 따라잡을 수 없었다.

 

자바의 모든 코드는 class안에서 실행이 되며

class 클래스이름 {

		public static void main(String[] args) { // 프로그램의 시작점
				// 실행될 명령어들을 작성하는 공간입니다.
		}
}

public static void main은 제일먼저 실행 되어야하는 부분을 표시하는 약속된 규칙이다.

 

객체지향

나는 사실 이것이 자바의 정수라고 생각하지만, 아직도 이해하지 못했다.

객체지향하면 SOLID 원칙이며, class 제어가 상송 생성자 등 알아야할 개념과 객체지향 자체의 개념또한 모호한데 일단

이것만 오늘은 이해해도 좋을거같다.

  • 자바는 모두 객체(클래스) 로 이루어져있다.
  • 서로 관련있는 기능을 묶어 하나의 클래스로 관리한다.

객체와 클래스는개념적으로 다르지만, 일단은 이정도만 이해해도 충분하다고 생각한다.

개념 비유 설명
클래스 설계도 객체를 만들기 위한 정의
객체 설계도를 기반으로 만들어진 존재 클래스에서 만들어진 존재

 

컴퓨터의 기억 방법 (RAM, SSD)

간단하게 CS공부도 같이했는데, 컴퓨터의 저장장치는 주기억장치와 보조 기억장치가 존재합니다.

주기억장치 : RAM(메모리) 라고 하며 빠른속도와 휘발성이 특징이라고 할 수 있다.

보조기억장치 : 컴퓨터가 꺼져도 정보를 저장하기 위해 하드디스크 등에 저장하는 장치 입니다. 영구적으로 저장하지만 느리다는 단점이있습니다.

 

바이트 - 컴퓨터가 데이터를 저장하고 처리하는 단위 1바이트는 8비트로 구성되어있고

비트 - 1혹은 0을 저장할 수있는 공간이다 하나씩 늘어날때마다 저장할 수 있는데이터가 2배씩 들어나고

바이트 하나엔 8개의 비트가있으니 2^8 = 256(0~255)개의 데이터를 저장할 수 있다.

 

Java의 네이밍 방법

기본적으로 자바에서는 카멜케이스 방식을 사용한다.

카멜케이스(CamelCase) 

firstName, lastName, fullName

스네이크케이스(snake_case)

first_name, last_name, full_name

 

Pakage , Class

패키지는 관련된 자바 클래스들을 그룹으로 묶는 기능,

클래스는 객체지향에서 객체를 만들기 위한 설계도 라고 생각하면 좋을거같다.

(ex. 자동차를 구성하기 위한 "색상","모델" 같은 속성이 있고, "가속" "정지" 같은 행위의 청사진 을 클래스[설계도] 라고하며, 

객체는 이 설계도를 활용해 실제로 만든 자동차를 객체(인스턴스) 라고한다)

아래와 같은 코드가 있다고 생각해보자

UserData userData = new User();

그럼 여기서 가장 앞에 UserData 이부분은 변수의 타입인데 내 생각엔 미묘하게 다르지만 클래스라고 생각하면 될거같다.

그리고 그 뒤에 userData 이부분은 객체의 주소를 담고있는 변수 (JVM저장 공간을 공부해보면 무슨의미 인지 더 와다을듯하다)

new User()해당 부분이 실제 데이터가 담겨있는 객체 데이터이다.

 

Java코드를 작성해보자

변수와 자료형에 대해 공부하면서 간단하게 자바 코드를 실제로 작성해보자

 

변수? 자료형?

수업에선 상자로 표현했는데, 지금 나에겐 조금 와닿지않아서 고민을 좀 했다.

변수란 실제 데이터가 존재하는메모리의 주소를 나타낸다고 보면 될거같다.

이게 진짜 애매하다고 생각이 드는데,,,, 예시로 생각해보자.

int a = 10

이런 코드가 있다고 생각을 해보자.

우리가 아까 공부했을던 주기억장치가 기억나는가? 메모리 비트 어딘가에 10이라는 데이터가 0과1 의형태로 저장이 되어있을거다.

근데 그 메모리가 어디있는지 어떻게 알 수 있을까?

그 어디있는지 정보를 a안에 담아두고있는것이다.

 

그냥 직관적으로 [a = 10] 이 아니라 [a = 메모리주소값] 인셈인데, 사실 내가 이해한 부분이 맞는지. 정확히 모르겠어서 

튜터님에게 질문을 했더니 조금 다르지만 더 지금은 더 깊게파지않고 그렇게 이해해도 괜찮다고 하셔서 그렇게 이해를 하려했다.

 

그럼 어차피 주소를 가지고있는것이라면 a=10 이라고 생각하면 되는거 아닌가? 맞다 하지만 이런 내용을 알고 평소에 직관적으로 인지하는것과 모르고 코딩을하는건 하늘과 땅 차이라고 생각한다.

나는 이런부분을 지금까지 놓치면서 코딩을 했고 다시금 수업을 들으면서 이해하는 과정을 거치니 솔직히 코딩이 조금 재밌기까지하다.

 

그럼 자료형은 무엇인가

나는 이전까지 그저 문자열인지 숫자인지, 실수인지, 참인지 거짓인지를 나타낸다고 생각했다.(맞는말이긴 한데..)

일단 자료형이 무엇이냐면 해당 데이터가 어떤 타입인지 문자인지 숫자인지 참과 거짓을 나타내는값인지 나타내는 것인데

 

왜 쓰냐면

데이터를 저장할때 메모리를 얼마나 사용할지 미리 공간을 확보하는것이다.

그러면 같은 저장공간을 사용하는 int float는 뭐냐 라고 할 수 있는데,

모양이 다르다고 이해를 했다,

예를들어 내가 비빔면과 국물라면을 끓였다고 생각해보자, 이 두개의 용량은 같다 = 사용하는 공간이 같다.

라고 가정을하고 만약 국물라면을 평평한 그릇에 담았다고 생각해보자 그럼 국물이 다 밖으로 흘러넘쳐 그건 더이상 라면이 아니게된다.

이런 맥락으로 자료형은 데이터를 해석할때 어떤 규칙으로 해석할지 컴파일러에게 알려주는 것이다.

 

연산자, 조건, 반복, 배열 수업에선 그동안 수업이 많이 코딩을하면서 마주한 것들이라 가볍게 들으면서 리마인드했다.

간단하게 개념만 보면

 

연산자

값을 계산 할때 사용하는 기호이다 우리가 흔히 사칙연산할때 사용하는 + -  * / 등이있고 

대입 증감 비교 논리 연산자 등이있다.

주의할게 두가지 정도있는데

증감연산자에서 전위 연산과 후위 연산에 대해 주희 할 필요가있다.

전위 연산(++i)
연산 후 값이 적용

int a = 5;
System.out.println("++a: " + (++a));  // 6 (먼저 증가 후 출력)
System.out.println("현재 a 값: " + a);  // 6

후위연산(i++)
값이 사용된 후 연산

int b = 5;
System.out.println("b++: " + (b++));  // 5 (출력 후 증가)
System.out.println("현재 b 값: " + b);  // 6

두번째로 문자열비교가있다.

문자열을 비교할때 "==" 사용하지않고 .equals()를 사용한다.

 

조건

조건 수식이 참인지 거짓인제 따라 명령문 실행여부를 판단한다.

switch문에서 break;이 없으면 아래까지 실행된다는것을 조금 잘 생각해보면 좋을거같다.

 

반복 , 배열

조건문에 만족하는동안 명령문을 계속반복해서 수행한다. 

배열을 가지고 반복문을 거는 경우가 매우많으며 

향상된 for문을 정말 많이 사용하니 사용방법을 익혀두면 좋을듯하다.

 

메서드

정말 중요한 개념이다. 사용방법보단 왜 사용하는가를 조금 생각해보자.

만약 메서드가 없다면 모든 기능을 하나의 클래스 파일에서 한줄 한줄 모두 적거나, 클래스가 방대하게 많아지게 된다.

만약 메서드 없이 사칙연산을 구현한다고 생각해보자.

main 안에 한줄한줄 다 더하거나, 더하기 클래스 빼기 클래스 나누기클래스 를 나누어 하나하나 다 불러와야 할것이다.

public class Main {

    public static void main(String[] args) {
		    
		    // 기능 1: 더하기
		    int a = 10;
		    int b = 2;
		    int result = a + b;
		    System.out.println("더하기 결과: " + result1);
		    
		    // 기능 2: 빼기
		    int c = 2;
		    int d = 1;
		    int result2 = c - d;
		    System.out.println("빼기 결과: " + result2);
        
        // 기능 3: 구구단 기능
				// ...
				// ...
				// 기능 200
    }
}

너무 비효율 적이지 않은가

차라리 Calculate.class 파일을 하나 만들어 거기에 add , minus , multiplied, divide 등 기능단위로 메서드를 나누는게 좋을것이다.

 

내가 잘 기억하는건지 모르겠지만 여기서 객체지향적 포인트가 나온다.

클래스를 어떤단위로 묶을것인지 메서드는 한번에 하나의 기능만을 담담해야 한다는 등의 개념이 나온다.

 

앞으로 객체지향 이해하기 강의를 들을텐데 이 부분을 잘생각하면서 수업을 수강하면 좋을듯하다.