[Kakao Cloud School] 7번째 회고록

lango·2022년 12월 20일
0
post-thumbnail

Intro


Deep Dive

Java를 내가 가장 자신있는 언어로 선택하였고, Java를 사용해왔지만 솔직히 기초적인 수준으로, 남들에게 잘한다고 말할 정도는 더욱 아니었다.

이번 교육과정에서 Java를 배울 때는 단지 공부를 위해서, 배우기 위한 부분도 중요하지만 왜 Java를 배우는지, 왜 Java를 사용하는 것인지, Java 개발자로서 어떤 산출물을 낼 수 있는지 등 본질적인 질문들을 계속 스스로에게 던지며 공부하려 한다.

어중간한 자세로 공부할 시점은 지났다고 생각한다. 이제는 Java든, Spring이든 Deep Dive하여 공부해야할 시점이기에 먼저 적용해보기 전에 내가 이해한 내용인지 점검해보도록 하자.




Day - 29

이번 주부터는 Java를 배우기 시작했다. Java를 접한지는 수년이 되었지만, Java에 대해선 기초 수준에 머물러있던 것 같다. 이번 Java를 배우는 과정 속에서 왜 Java를 배우는지, Java를 통해서 어떤 것들을 만들어 낼 수 있는지, Java 개발자로서의 방향성 등을 많이 생각하게 되었다.

Java는 어떻게 등장하게 되었을까?

Java(이하 자바)는 선마이크로시스템즈(Sun Micro Systems)의 제임스 고슬링(James Gosling)이 개발하게 된 객체지향 프로그래밍 언어이다.

본래 자바는 일반적인 컴퓨터에서 사용할 목적으로 개발된 것이 아니었다. 기존의 C++은 컴퓨터 플랫폼(Platform)에 종속적이기에 운영체제 별로 즉, 플랫폼 별로 소스를 다시 컴파일하거나 다시 작성해야 하는 단점이 존재했다. 이 단점으로 인해 컴파일러가 운영체제에서 실행되는 코드를 생성하기에 운영체제가 변경되면 당연하게도 그에 맞게 코드도 변경해야 했다.

플랫폼이란?
사전적인 플랫폼의 의미는 기차를 승차하는 공간, 강사, 음악 지휘자 선수들이 사용하는 무대 강단 등을 뜻하는데, 여기서는 어떠한 목적을 수행할 수 있는 실행환경이나 개발환경등같은 환경을 뜻한다. Window나 Mac 같은 운영체제가 플랫폼에 해당된다고 볼 수 있다.

이에 선마이크로시스템즈는 다양한 플랫폼에서 실행되는 프로그램에서 효율적인 코드 작성을 위해 플랫폼에 독립적(Platform Independent)인 언어가 필요했다.

그렇게 메모리 사용량이 적은 오크(Oak)라는 새로운 언어를 개발하게 되었는다. 오크는 초기에는 많이 알려지지 않았지만, 인터넷과 웹이 급속도로 발전하게 되면서 함께 대두되기 시작했다. 그렇게 선마이크로시스템즈는 오크를 인터넷 환경에 맞게 발전시켰고 1995년 Java(자바)라는 이름으로 발표하게 되었다.

Java 이름의 유래는?
오크란 이름은 선마이크로시스템즈 사무실 앞 참나무(Oak)에서 가져온 것인데, 이미 오크란 상표가 등록되어있어 자바로 바꾸어 발표한 것이라고 한다.
Java(자바) 이름의 유래 중 가장 유력한 가설 2가지가 있는데 하나는 개발자들은 커피를 많이 마신다. 에서 가져온 것이라고 하며, 하나는 개발팀 핵심 멤버인 James Gosling, Arthur Van Hoff, Andy Bechtolsheim에서 따왔다는 가설이 있다고 한다.

당시 넷스케이프(Netscape) 웹 브라우저에 자바 기술이 적용되며 자바는 더욱 커지게 되었고, 지금 시대에서 가장 강력한 프로그래밍 언어 중 하나로 자리잡게 되었다. 또한, 2009년에 오라클에서 선마이크로시스템즈를 인수하게되어 오라클에서 자바를 제공하고 있다.

그에 반해 Java는 플랫폼 독립적이기에 여러 운영체제에서 실행되는 프로그램을 한 번만 작성하면 되며, JRE(JVM)가 이해할 수 있는 코드를 컴파일러가 생성해준다. 결국 운영체제 별로 각각의 JRE를 설치하여 운영체제 단에서 프로그램을 실행해준다.

플랫폼에 독립적이다..?

C, C++등 자바 등장 이전의 프로그래밍 언어들로 작성된 프로그램들은 컴파일되면 실행될 컴퓨터의 플랫폼, 즉 운영체제에 종속된 기계어 코드로 변환된다.

예를 들어 Intel CPU와 리눅스 운영체제가 탑재된 컴퓨터에서 컴파일된 기계어 코드는 Intel CPU와 윈도우가 탑재된 컴퓨터에서는 실행할 수가 없다는 것이다. 결국 각 운영체제에 맞는 기계어 프로그램을 실행해야 하기 때문에 플랫폼에 종속적(Platform Dependence)인 특성을 지닌다.

그런데 자바는 플랫폼에 독립적인 언어로 개발되었기에 자바로 작성된 프로그램에서 컴파일된 자바 코드는 운영체제나 CPU 등 플랫폼에 상관없이 JVM(Java Virtual Machine, 자바 가상 기계)만 있다면 어디서든 실행할 수가 있다. 이이를 WORA(Write Once Run Anywhere)라고 한다.

이러한 자바는 플랫폼에 독립적인 특성을 지니기에 리눅스가 설치된 컴퓨터나, 애플 운영체제가 설치된 컴퓨터나, 윈도우가 설치된 컴퓨터 어디서든 별도의 수정없이 실행할 수가 있는 것이다.



Java를 사용하는 이유는?

자바는 전 세계 개발자들 사이에서 인기가 많은 프로그래밍 언어이고 자바가 제공하는 웹 개발 기능은 엄청난 호응을 얻어왔다.

많은 개발자들이 왜 자바를 사용하는지 그 이유에 대해서 알아보려 한다.

플랫폼에 영향을 받지 않는다.

먼저 자바는 플랫폼에 구애받지 않기 때문에 별도의 작업없이 서로 다른 기기에서 동일하게 동작하는 프로그램을 개발할 수 있다는 점이다. 다양한 플랫폼에서 동일한 애플리케이션을 실행할 수 있다는 점은 웹 애플리케이션에서는 필수적이라고 볼 수 있다.

풍부한 기능을 제공하는 오픈소스이다.

자바에서는 클래스뿐만 아니라 자료구조, 입출력, 예외처리 등에 최적화된 알고리즘 라이브러리를 제공하는 JDK(Java Development Kit, 자바 개발 키트)가 있기에 다양한 기능을 빠르게 구현할 수 있다.

JDK(Java Development Kit, 자바 개발 키트)란?
자바 개발키트(Java Development Kit)의 약자로 개발자들이 자바로 개발하는 데 사용되는 SDK 키트이다.

SDK(Software Development Kit, 소프트웨어 개발 키트)란?
SDK란 하드웨어 플랫폼, 운영체제 또는 프로그래밍 언어 제작사가 제공하는 툴이다. 키트의 요소는 제작사마다 다르다. SDK의 대표적인 예로, 안드로이드 스튜디오 등이 있다. 이 SDK를 활용하여 애플리케이션을 개발할 수 있다.

그래서 JDK안에는 자바를 개발 시 필요한 라이브러리들과 javac, javadoc 등의 개발 도구들을 포함되어 있고, 개발을 하려면 자바 프로그램을 실행도 시켜줘야 하기 때문에 뒤에서 배울 JRE(Java Runtime Environment)도 함께 포함되어 있다.

그리고 자바는 뛰어난 에코시스템을 갖추었기 때문에 오픈소스 프로젝트가 굉장히 많아 여러가지 래퍼런스를 개발에 참고할 수 있다.

자바 개발에 편리한 라이브러리인 apache common, 자바 개발에 편리한 프레임워크인 spring이나 struts, 검색 엔진인 Lucene, NoSQL의 Cassandra, 분산 파일 시스템의 Hadoop 등을 활용하여 개발할 수 있다.

또한, Jyton, Scala, Kotlin, Closure, Jruby, Groocy 등 JVM 기반의 언어들이 많이 구현되어있다.

객체지향 언어이기에 유지보수와 확장에 용이하다.

자바는 처음 개발할 때부터 객체 지향 언어로써 사용하기 위해 개발되었기 때문에 객체지향적인 개념을 정확하게 적용하고 있는 언어이다.

객체지향적 원리를 적절히 적용하여 개발하게 된다면 객체의 역할과 구현을 명확히 해주어 공통으로 사용하는 부분을 별도로 수정하지 않고도 프로그램에 새로운 기능을 쉽게 추가할 수 있다.

결과적으로 절차가 관점인 절차지향과 다르게, 코드의 중복이 줄어들고 각각의 객체가 책임을 가지면서 전체적인 수정이 아닌 일부분만 수정할 수 있게 되는데, 이러한 점은 결국 개발자가 유지보수하는데 편하며, 추가적인 기능을 개발하는데 부담을 줄일 수 있다.



Day - 30

자바에서 사용되는 다양한 자료형과 타입에 대해서 배웠다. 다른 언어들에서 보았던 것들도 있었지만 처음보는 생소한 내용들도 있었다.

제네릭(Generic)이란?

이전에 템플릿 프로그래밍, 템플릿 메서드란 이름을 종종 들었는데, 그 중심에는 대부분 제네릭이 등장했었다. 그래서 제네릭에 대해서 궁금해졌다.

흔하게 사용하는 ArrayList나 LinkedList를 생성할 때를 생각해보면
객체<타입> 객체이름 = new 객체<타입>(); 이러한 구문으로 사용하게 된다.

ArrayList<Integer> intergerList = new ArrayList<Integer>();
ArrayList<String> StringList2 = new ArrayList<Integer>();
LinkedList<Double> doubleList = new LinkedList<Double>():
LinkedList<Character> CharList = new LinkedList<Character>();

우리는 결국 <>라는 괄호 안에 데이터의 타입을 지정해주게 된다.

그런데 String타입이나 Integer타입을 모두 지원하고 싶다면 String이나 Integer에 대한 클래스를 타입에 따라 별도로 만든다면 개발자입장에서는 비용이 많이 소모된다.

이러한 문제를 개선하기 위해서 제네릭을 사용할 수 있다.

제네릭이란?
제네릭을 바로 번역하면 일반적인이라는 뜻이다. 자바에서는 데이터의 타입을 일반화(generalize)한다는 것을 의미한다.

제네릭은 클래스나 메서드에서 사용할 내부데이터 타입을 컴파일 시에 미리 지정하는 방식이다.

데이터 타입을 컴파일 시에 지정한다면 챙길 수 있는 이점은 다음과 같다.

  • 클래스나 메서드 내부에서 사용되는 객체의 타입 안정성을 높일 수 있다.
  • 리턴값에 대한 타입 변환 및 타입 검사에 들어가는 노력을 줄일 수 있다.
  • 코드의 재사용성이 향상된다.

보통 아래의 표에서 볼 수 있는 타입들이 많이 사용된다고 보면 된다.

타입설명
<T>Type
<E>Element
<K>Key
<V>Value
<N>Number

위 표처럼 무조건 한글자로 표현할 필요는 없지만 통상적으로는 위와 같이 표현한다.



Wrapper 클래스란?

자바에서 int와 Integer를 많이 사용해왔는데 이 둘은 무슨 차이가 있고 용도가 어떻게 다른 것인지 제대로 짚고 넘어가려 한다.

자바의 기본 타입(primitive type)에는 char, int, long, float, double, boolean, byte, short가 있으며, 참조 타입(reference type)에는 class, interface 등이 있다.

그런데 개발을 하다보면 기본 타입을 가지는 데이터를 객체로 다뤄야 하는 경우가 많다. 예를 들어 메서드의 인수로 객체만을 전달해야 한다면 기본 타입의 데이터를 사용할 수는 없다. 이 때 기본타입의 데이터를 객체로 변환해야 하는데 바로 래퍼클래스(Wrapper Class)를 이용할 수 있다.

java.lang 패키지에 모두 포함되어 제공되는 래퍼클래스는 다음과 같다.


기본 타입래퍼 클래스
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

래퍼클래스 중에서 Integer 클래스와 Character 클래스만 기본 타입과 래퍼클래스 이름이 다르다.



Day - 31

Java의 자료형과 제어문, 배열에 대해서 기본적인 내용을 배웠다. 성능적인 이슈를 생각하게 되는 정렬이나, 검색 등을 배우고 실습해보며 동작하는 원리나 문법적인 내용을 알 수 있었다.


문자열 간에 +연산을 지양해야 한다고?

자바에서 + 연산자를 이용하여 문자열을 결합하는 작업을 종종 접하게 되는데 + 연산자를 통해 문자열을 합치는 작업은 성능면에서 어떤 퍼포먼스를 내는지 궁금해서 알아보려 한다.

먼저 String 클래스는 불변성을 지닌 클래스임을 유의해야 한다. 불변성을 가진다고 함은 결국 내용을 변경할 수 없다는 것이다.

그런데 아래와 같이 String 변수로 선언한 뒤 + 연산자로 새로운 문자열을 추가할 수 있지 않나?

String str = "Hello";
str += " World!";

하지만 찾아보니 한번 String으로 생성된 인스턴스의 문자열은 읽어올 수만 있다. +연산자를 이용하여 World!라는 문자열을 str이라는 String 변수에 합하여 Hello World!라는 문자열로 변경되는 것이 아니라 새로운 인스턴스인 World! 문자열이 생성되는 것이다.

그런데 여기서 새로운 의문이 생겼다. 새로운 인스턴스가 생성될 뿐인데 어떻게 Hello World!로 합쳐져 출력되는 것인가?

Java에서 String의 +연산자는 Java 컴파일러에서 구현되며 컴파일되는 시점에 내부적으로 StringBuilder 클래스를 만들어 문자열로 반환하기 때문에 Hello World!로 결합되는 것이라고 한다.

StringBuilder란?
말 그대로 String을 만드는 객체인데, 문자열을 배열처럼 관리하며 추가, 삭제, 삽입을 용이하게 하기 위해 사용하는 클래스이다. 문자를 추가, 삭제, 삽입, 뒤집기 등의 작업을 통해 문자를 관리하는 클래스이다.

String str = "Hello";
str += " World!";

String str2 = new StringBuilder("Hello").append(" World!").toString();
System.out.println(str);
System.out.println(str2);
System.out.println(str.equals(str2));

// Hello World!
// Hello World!
// true

위와 같이 StringBuilder 클래스로 만들어 문자열로 반환하기 때문에 +연산이 가능한 것이라고 볼 수 있다. 결국 StringBuilder는 String과 다르게 문자열의 내용을 변경할 수 있다는 것을 확인했다.

다음으로 문자열을 결합할 때, 왜 +연산을 지양해야 하는지, 아니 바로 둘의 성능을 비교해보면 알 수 있을 것 같으니 성능을 직접 비교해보자.

class Main {
    public static void main(String[] args) {
        StringTest();
        StringBuilderTest();
    }

    private static void StringBuilderTest() {
        String str = "Hello";
        long start = System.currentTimeMillis();

        for(int i=0; i<100000; i++) {
            str += " World!";
        }
        
        long end = System.currentTimeMillis();
        System.out.println("String exec time: " + (end-start));
    }

    private static void StringTest() {
        StringBuilder sb = new StringBuilder();
        sb.append("Hello");
        long start = System.currentTimeMillis();

        for(int i=0; i<100000; i++) {
            sb.append(" World!");
        }
        
        long end = System.currentTimeMillis();
        System.out.println("StringBuilder exec time: " + (end-start));
    }
}

위와 같이 Hello라는 문자열에 100000번의 World! 문자열을 추가하는 작업을 String의 +연산과 StringBuilder의 append() 메서드를 통해 비교하였다.

StringBuilder exec time: 21
String exec time: 5000

실행결과를 살펴보면 String의 +연산을 이용하는 것보다 StringBuilder를 통해 문자열을 합치는 작업이 더욱 뛰어난 성능을 보여줌을 알 수 있었다.

String의 +연산은 결국 StringBuilder로 변환하는 과정이 발생하기 때문에 반복문의 횟수만큼 StringBuilder가 만들어진 후 문자열을 합치는 작업을 하기 때문에 실행 시간이 많이 걸리게 된다.

결론을 정리하자면, 문자열을 합치는 등 문자열에 변경점을 주어야 하는 작업이 필요하다면 String 클래스의 +연산자를 통한 작업은 생각지도 말고 StringBuilder를 통해 작업을 해야 한다.



키보드로 입력한 데이터가 어떻게 출력되는 걸까?

우리가 키보드로 입력한 정보들은 어떻게 바로 모니터로 볼 수 있는 걸까?
바로 입력 및 출력과 버퍼(Buffer)와 관련이 있다.

키보드를 통해서 입력하는 정보들은 바로 애플리케이션에서 읽어 들이는 것이 아니라 임시 메모리 공간인 버퍼(Buffer)라는 곳에 저장이 된다는 것을 알 수 있다. 그리고 나서 입력 버퍼에 존재하는 데이터가 입력 스트림을 통해 프로그램으로 이동하는 것이다.

이와 동일하게 애플리케이션에서 출력과 관련된 함수 호출을 통해서 모니터에 데이터를 출력하려는 경우에도 곧바로 출력되는 것이 아니라, 먼저 출력 버퍼라는 곳에 저장이 되었다가 출력 스트림을 통해 모니터에 전송하게 된다.

버퍼(Buffer)란?
하나의 장치에서 다른 장치로 데이터를 전송할 경우에 양자간의 데이터의 전송 속도나 처리 속도의 차를 보상하여 양호하게 결합할 목적으로 사용하는 기억영역이라고 한다.

여기서 궁금한 것은 키보드에 입력한 정보들이 버퍼에 담기는 시점이 언제일까?
바로 Enter 키를 누르는 시점이다. 이 말은 Enter 키를 누르기 전까지는 버퍼가 비어있다는 뜻이다.

또한, 왜 버퍼에 담기는 시점이 다른 걸까?
여기서 중요한 점은 두 장치 사이에서 속도 차이를 줄이기 위함이라는 것을 알고 넘어가야 한다. 속도가 빠르다는 것은 한번에 처리할 수 있는 데이터의 양이 많다는 것이다. 결국 장치가 처리할 수 있는 만큼의 데이터를 버퍼에 모아 두었다가 전달해야 더욱 효율적으로 데이터를 처리할 수 있고 두 장치의 속도 차이를 줄일 수 있다고 느꼈다.

IT와 관련된 CS를 배우며 일상과 관련된 의문점들을 공부하고 알아보니 흥미롭고 재밌는 사실들이 있음을 깨닫곤 한다.



Day - 32

Java를 통한 객체지향 프로그래밍 OOP에 대해서 배우게 되었다. 클래스와 인스턴스 메서드를 생성하거나 사용하고 관리할 때 어떻게 객체 지향적으로 접근할 수 있는지 고민해볼 수 있는 시간을 가졌다.


함수(Function)과 메서드(Method)의 차이는?

함수와 메서드의 큰 차이를 모르겠어서 여러 문서를 찾아보고 공부하게 되었다.

함수(Function)란?

함수란 하나의 기능을 수행하는 일련의 코드 즉, 특별한 목적을 위한 작업을 위해 독립적으로 설계된 코드의 집합이다. 함수로 구현된 기능은 여러 곳에서 호출하여 사용할 수 있다. 함수를 활용하여 코드의 재사용성과 가독성을 높일 수 있다.

자바에서 함수는 다음과 같이 사용할 수 있다.
FunctionTest라는 클래스에 addWithInteger라는 함수를 작성하였다.

public class FunctionTest {
    public static int addWithInteger(int first, int second){
    	int sum = first + second;
        return sum;
	}
    public static void main(String[] args) {
		int result = addWithInteger(5,2);
		System.out.println(result);
	}
}
// 7 출력

메서드(Method)란?

메서드란 객체의 기능을 구현하기 위한 클래스 내부에 구현되는 함수이며 멤버 함수랃고도 불린다. 메서드를 구현한다는 것은 결국 객체의 기능을 구현하는 것이다.

메서드 예제도 한번 작성해보자.
Post라는 클래스에 2개의 메서드를 작성하였다.

public class Post {
	public int postId;
	public String title; 
	public String author;
    
	public String getTitle() {
		return title;
	}
	public void showPostInfo() { //학생 정보 출력
		System.out.println("게시글 번호:" + postId);
		System.out.println("게시글 제목:" + title);
		System.out.println("작성자:" + author);
	}
}

getTitle과 showPostInfo 메서드를 호출할 Main 클래스를 작성하였다.

	public class PostMain {
	public static void main(String[] args) {
		Post post = new Post(); //객체 생성
		
		//객체에 값 대입
		post.postId = 1;
		post.title = "게시글 제목입니다.";
		post.author = "lango";
		
		//메서드 호출
		post.getTitle();
		post.showPostInfo();
	}
}

함수 VS 메서드

위 코드를 보며 함수와 메서드의 차이에 대해서 어느정도 이해할 수 있었다. 함수는 독립적으로 존재하기에 함수 자체로 호출이 가능하지만 메서드의 경우는 클래스에 대한 인스턴스를 생성해야 호출할 수 있다는 것이다.

함수나 메서드를 통칭하여 불렀던 경우가 많은데 함수와 메서드를 비슷한 것 같지만 확실하게 다름을 알 수 있었다.



Day - 33

객체를 새로 생성할때 최초로 한번 실행되는 생성자에 대해서 다시 한번 공부하게 되었다.


상속(Inheritance) 관계를 통한 참조형 변수의 대입과정에 대해서..

참조형 변수를 선언할 때 자신의 참조형 데이터의 참조만 대입할 수 있다고 배웠다.

상속 관계라면 참조형 변수에 하위클래스의 인스턴스 참조값을 대입할 수 있다. 다만, 하위클래스 타입을 가지는 참조형 변수에는 상위클래스 타입의 인스턴스 참조를 대입할 수는 없다.

간단하게 코드로 살펴보자.

Super라는 클래스와 Sub라는 클래스가 존재하고 Sub는 Super 클래스를 상속받은 하위클래스라고 하자.

Super sp1 = new Super();
Sub sb1 = new Sub();

그러면 위 코드처럼 당연하게도 각자의 참조형 변수에 자신의 인스턴스를 대입할 수 있다.

Super sp2 = new Sub();
Sub sb2 = new Super(); // Error

그리고 상위클래스의 타입을 가지는 참조형 변수에는 하위클래스 타입의 인스턴스 참조를 바로 대입할 수 있지만, 하위클래스 타입을 가지는 참조형 변수에는 상위클래스의 인스턴스를 대입할 수 없다.

그런데 강제 형 변환을 통해서 하위클래스 타입의 참조형 변수에 상위클래스의 인스턴스를 대입할 수는 있다.

Super sp = new Sub(); // 1
Sub sub1 = (Sub) sp; // 2
Sub sub2 = (Sub) new Super(); // 3

// 2번과 3번 구문 모두 컴파일 에러가 발생하지는 않는다.
// 3번 구문은 호출(실행)되는 시점에 Error

위 코드를 보면 1번 구문의 sp 변수는 상위클래스 타입을 가지는 참조형 변수인데, 하위클래스인 Sub의 인스턴스를 대입하여 생성하였다.

그리고 Sub형 sub1 변수에 위에서 만든 sp 변수를 Sub형으로 강제 형 변환하여 대입하였다.

마지막으로 Sub형 sub2 변수에는 new Super(); 구문을 통해 Super형의 인스턴스를 만들어 Sub형으로 강제 형 변환하여 대입하였다.

sub1과 sub2 변수는 결국 자료형 자체는 같기 때문에 컴파일 시점에서는 에러가 발생하지 않는다.

중요한 것은 실행되어 실제로 저 두 변수가 호출되는 시점이다.

sub1 변수는 sp 변수를 대입하였는데 sp변수를 들여다보면 new Sub(); 구문을 통해 만들어진, 즉 Sub형의 인스턴스를 가지고 있기에 문제는 없다.

문제는 sub2 변수이다. sub2 변수는 Sub형의 타입을 가지는데, 호출 시점에 대입되는 new Super(); 구문을 들여다보게 되면 Super형의 인스턴스이기 때문에 자료형이 일치하지 않아 실행되는 시점에 에러(java.lang.ClassCastException)가 발생하게 된다.


결국 이러한 참조형 변수를 대입하여 사용할 때 상속관계가 어떻게 이루어져있는지 잘 고려하면서 사용해야 한다.






Final..

일주일동안 Java의 기초를 배우면서 기술적이고 문법적인 내용을 많이 배웠다. 또한, 내가 Java를 왜 배우는 것인지에 대한 의문들을 해결하기 위한 공부도 필요했다.

Java를 선택한 가장 큰 이유는 래퍼런스의 양 때문이다. 전 세계적으로 많은 사용자가 있으니 그만큼 많은 래퍼런스가 존재한다. 이는 내가 부딪히거나 막혔던 문제들을 해결하기 위한 유사한 해결책들을 찾아볼 수 있다는 것이다. 다양한 래퍼런스나 오픈소스들을 참고하면 내 수준에선 웬만하면 해결할 수 없는 문제는 없을 것이라고 생각한다.

Java 개발자로 성장해가며 기술적인 부분들을 쌓아가며 쌓아가는 이유에 대해서도 확실하게 짚고 넘어가는 자세를 지녀야 한다고 느꼈다.



혹여 잘못된 내용이 있다면 지적해주시면 정정하도록 하겠습니다.

게시물과 관련된 소스코드는 Github Repository에서 확인할 수 있습니다.

참고자료 출처

profile
찍어 먹기보단 부어 먹기를 좋아하는 개발자

0개의 댓글