카카오 테크 캠퍼스 1주차

boseung·2023년 4월 21일
0

카카오 테크 캠퍼스 Week 1

1주차 강의는 Java에 대한 기초적인 내용이었다.

강의 내용을 그대로 학습일지로 작성하기보다 강의를 들으면서 헷갈렸던 부분들과 떠오른 의문들을 확장해나가는 방향으로 적어나갔다.

Java 메모리 할당

강의를 듣다가 new라는 키워드를 사용할 때, 자바에서 Heap 메모리에 객체가 할당된다는 것을 알게 되었다.

운영체제 과목에서 Stack과 Heap에 대해서 배우고 있어서 이것과 관련해서 추가로 공부해보았다.

자바에서는 어떻게 Stack과 Heap 메모리에 할당이 이뤄질까?

이를 이해하기 위해서는 먼저 JVM(자바 가상 머신)이 운영체제로부터 할당받는 메모리 영역에 대해서 이해할 필요가 있다.

메모리 영역

JVM은 크게 Method, Stack, Heap 메모리 영역으로 구분해서 메모리를 할당한다.

Method 영역의 경우 클래스 정보, 메서드, 클래스 변수(정적 변수), 상수(Final) 등이 저장된다.

Heap 메모리 영역의 경우 프로그램이 실행 도중에 동적으로 할당 받는 공간으로, new 연산자로 객체를 생성할 때마다 객체가 저장된다.

Stack 메모리 영역의 경우 메서드의 지역변수, 메서드 호출 정보, 스택 프레임(각 메서드 호출마다 생성되는 영역) 등이 저장된다.

public class StudentTest{
	public static void main(String[] args) {    
		int old = 20;
		// old는 지역 변수 -> stack에 할당
		// 10은 기본 자료형 타입 -> stack에 할당
		Student student = new Student();
		// student는 지역 변수 -> Stack에 할당
		// new Student() -> Heap에 동적 할당
    }
		String s = "Kang"
		// s는 지역 변수 -> stack에 할당
		// "Kang"은 String Object -> Heap에 할당
}

Challenging(학습하며 어려웠던 점)

운영체제 과목에서 배웠던 메모리 영역과 JVM에 의해 나뉘어지는 메모리 영역이 조금 달라서 헷갈렸다.

JVM에 대한 추가적인 학습이 필요해 보인다.

Access Modifier(접근 제어자)

접근 제어자는 4가지가 있다.

  • private
    • 같은 클래스에서만 가능(외부 클래스, 상속관계 클래스도 불가능)
  • default
    • 같은 패키지에서만 가능(상속 관계라도 패키지 다르면 불가능)
  • protected
    • 같은 패키지, 상속 관계에서만 접근 가능
  • public
    • 클래스 외부에서나 어디든지 접근 가능

Encapsulation(캡슐화)

  • 캡슐화를 하는 가장 큰 이유는 정보 은닉이다.
  • 대부분의 멤버 변수와 메서드를 감추고 외부에 통합된 인터페이스만을 제공한다.
  • getter, setter를 이용해서 구현할 수도 있다.

예제

public class MakeReport {

	StringBuffer buffer = new StringBuffer();
	
		private String name = "이름";
		private String address = "주소";
		private String phoneNum = "010-1234-5678";
	private void makeName()
	{
		buffer.append(name);
	}
	
	private void makeAddress()
	{
		buffer.append(address);
	}
	
	private void makePhoneNum()
	{
		
		buffer.append(phoneNum);
	}
	
	public String getReport()
	{
		makeName();
		makeAddress();
		makePhoneNum();
		return buffer.toString();
	}
}
  • makeName, makeAddress, makePhoneNum 메서드를 getReport에서 호출하여 클래스 외부로 메서드들을 노출시키지 않았다.
public class TestReprt {

	public static void main(String[] args) {

		MakeReport report = new MakeReport();
		String builder = report.getReport();
		
		System.out.println(builder);
	}

}
  • MakeReport의 캡슐화로 Report를 만드는 구체적인 메서드의 내용을 클래스 외부에서 알 수 없다.

객체 자신을 가리키는 this

  • 인스턴스 자신의 메모리를 가리킴
  • 자신의 주소값을 반환
public class Book{
	String title 
	public void SetTitle(String name){
		this.title = name; 
		// 여기서 this는 자신의 메모리(자신의 주소값 반환), 
		// 즉 인스턴스 자신을 가리킴
	}
}
  • 생성자에서 또 다른 생성자를 호출할 떄 사용
  • this()로 생성자를 호출할 때, 그 이전 statement는 사용할 수 없다는 점에 유의
public class Person {

	String name;
	int age;
	
	public Person() {
		// 이렇게 다른 생성자를 호출할 때, 그 이전 statement 사용x
		this("이름없음", 1);
		// 생성자가 여러개인 경우, this를 사용하여 생성자에서 다른 생성자 호출 가능
	}
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
}

Singleton 패턴

Singleton 패턴이란?

프로그램에서 인스턴스가 단 한개만 생성되어야 하는 경우 사용하는 디자인 패턴이다.

강의 예제

public class Company{
	private static Company instance = new Company();
	private Company(){}
	public Comany getInstance(){
		if (instance == null){
			instance = new Company();
		}
		return instance;
	}
}

내 기억 속에 있는 Singleton 패턴과는 달라서 추가로 검색해보았다.

그 결과 위와 같은 Singleton 패턴은 Eager Initialization으로 객체를 사용하지 않더라도 무조건 객체를 생성하기 때문에 자원낭비가 발생할 수 있다는 단점이 있다는 것을 알게 되었다.

현재 가장 널리 쓰이는 Singleton 패턴은 Inner Static Helper Class를 사용하는 구현 방식이다.

public class Singleton{
	private Singleton(){}
	public static class SingletonHelper{
		private static final Singleton INSTANCE = new Singleton();
	}
	public static Singleton getInstance(){
		return SingletonHelper.INSATNCE;
	}
}

이와 같은 lazy-loading 방식으로 자원의 낭비를 피할 수 있다.

물론 이 방식도 Java의 Reflection을 사용하면 private 생성자, 메서드에 접근이 가능해져서 단 하나의 객체라는 조건을 깨뜨릴 수도 있다는 단점이 있다.

싱글톤 패턴 예제

public class CarFactoryTest {
    public static void main(String[] args) {
				// 아래와 같은 코드가 작동하도록 클래스를 작성하시오
        CarFactory factory = CarFactory.getInstance();
        Car mySonata = factory.createCar();
        Car yourSonata = factory.createCar();

        System.out.println(mySonata.getCarNum()); // 10001
        System.out.println(yourSonata.getCarNum()); // 10002
    }
}

나는 아래와 같이 작성하였다.

public class CarFactory {
    private int num = 10000;
    private CarFactory(){};
    private static CarFactory INSTANCE = new CarFactory();
    public static CarFactory getInstance(){
        return INSTANCE;
    }

    public Car createCar() {
        return new Car(++num);
    }
}
public class Car {
    int num;
    public Car(int num){
        this.num = num;
    }
    public int getCarNum(){
        return num;
    }
}

그림으로-보는-자바-코드의-메모리-영역스택-힙

JAVA 메모리 이야기 - Stack 과 Heap

싱글톤 패턴 구현 방법

profile
Dev Log

0개의 댓글

관련 채용 정보