Basic Programming(기초 프로그래밍)/Java

[Java]우리는 자바를 어떻게 배워야 하는가?

Master_Worm 2021. 3. 15. 15:34

프로그래밍 언어를 배우면서 가장 근본적인 질문은 어떻게 배워야 하는가에 대한 질문 이었습니다. 프로그래밍은 우리에게 너무나 많은 일을 할 수 있는 강력한 힘을 줍니다. 하지만 문제가 있죠. 너무 강력한 힘을 주면서 동시에 너무나도 큰 자유를 선사해준다는 점입니다. 

자유

자유... 자유는 누구나 원하는 일이지만 갑자기 주어지면 뭘 해야 할지 감이 안 옵니다. 초등학교, 중학교, 고등학교에서는 하라는 데로 하기만 하면 됩니다. 심지어 대학교 조차도 커리큘럼이 있습니다. 이러한 커리큘럼을 특정한 시간 내에 특정한 주제가 정해진 상태로 우리는 하라는 일을 하면 됩니다. 하지만 프로그래밍은 우리에게 자유를 줌과 동시에 무엇을 해야 할지 우리가 스스로 결정해서 나가야 합니다. (물론 회사에 들어간다면 해야 할 일이 주어지지만 프로그래밍을 배우는 주된 이유는 내가 원하는 것을 마음껏 펼칠 수 있기 때문입니다.)

 

그렇다면 무엇을 배워야 할지 모르는 상태에서 나름의 틀을 주는 것은 무엇일까요? 그건 책이죠. 아무것도 할 줄 모른다면 일단은 머릿속에 무언가라도 넣은 상태에서 무엇을 해야 할지 결정해야 합니다. 그것도 싫다면 자바에서 주어지는 여러 기능을 시험삼아 테스트 해봐야 합니다. 틀이 주어지건 안 주어지건 간에 우리는 주어진 기능을 시험해보고 어떻게 사용해야 하며, 쓰다보면 생기는 질문을 꼭 해결하면서 진행해야 합니다. 

 

그렇다면 오늘의 포스팅에서는 어떻게 여러 기능을 연습해볼 수 있는지 살펴보도록 하겠습니다.

1. 어떻게 테스트를 할 것인가?


우리에게 가장 처음의 프로그래밍의 시작은 Hello, World가 주어진 것은 우연이 아닙니다. 가장 기본적인 입출력 프로세스를 익히기 위함이죠. Stdout이라 하는 Standard OutPut은 프로세스에서 가장 기본적인 인터페이스이죠. 그러면 단 한 줄을 분석해보도록 합시다.

 

System.out.println("Hello, World!");

 

자바의 기본적인 API를 확인할 수 있는 곳은

docs.oracle.com/en/java/javase/15/docs/api/index.html

 

Overview (Java SE 15 & JDK 15)

This document is divided into two sections: Java SE The Java Platform, Standard Edition (Java SE) APIs define the core Java platform for general-purpose computing. These APIs are in modules whose names start with java. JDK The Java Development Kit (JDK) AP

docs.oracle.com

이곳에서 확인할 수 있다. 필요한 내용이 있을 때마다 Search를 활용해서 사용하도록 해야 한다.

상단에 보면 Search가 있으니 궁금한 내용을 찾아보는 습관을 들이자. 참고로 영어가 잘 안되도 우리는 할 수 있다. 네이버 파파고와 구글 번역이 있으니 전혀 무섭지 않다. 번역기를 돌리면서 영어로도 한번 읽어보자. 차분히 영어 실력도 같이 늘어가는 것을 볼 수 있다. 언제까지고 영어가 두려워서 영어 페이지가 나오는 것을 외면할 것인가! 한번 시도해보자. 당장에 하루 이틀 만에 확 늘어날 수는 없지만 꾸준히 하면 영어 페이지가 나와도 읽을 만할 정도가 될 것이다. 

 

우리는 여기서 System을 찾아볼 것이다.

많은 검색 결과가 나온다. 그 중에서 java.lang.System을 클릭해서 들어가보자. 

두 가지 정보를 바로 얻을 수 있다. Module : java.base와 Package : java.lang 모듈과 패키지를 알아볼 수 있다. 그러면 우리가 모르는 정보는 모듈과 패키지란 단어를 모른다. 다시 찾아보면 된다. 어쨋든 모듈이란 기능상 비슷한 것을 모여서 만든 작은 부품이 조립된 하나의 덩어리를 모듈이라 부른다. 

 

모듈


현실 세계에서 자동차를 만들기 위해서는 수 많은 모듈이 필요하다. 모듈은 수 많은 부품으로 이루어져 있다. 이런 관점에서 보았을 때 모듈은 하나 또는 하나 이상의 기능을 하는 특정한 덩어리이며, 나사와 같은 작은 부품이 모여서 최소한의 기능을 할 수 있게 만들어주는 하나의 덩어리라고도 볼 수 있겠다. 대표적인 모듈은 ABS 모듈이다. 자동차 시스템에서 브레이크 시스템을 담당하는 녀석으로 Anti-lock Break System을 의미한다. 브레이크를 밝을 경우, 한 쪽 바퀴가 먼저 잠기는 것을 방지해서 차가 회전하는 것을 막아주는 역할을 한다.

 

ABS 모듈의 구성은 바퀴속도 감지기, ECU(전자 제어 모듈), 유압조정장치, 경고등 등이 기본적인 구성 성분이다. 여기서는 다른 모듈을 포함하기도 하는 것이 모듈이다. 소프트웨어에서도 마찬가지이다. 이러한 모듈의 크기는 천차만별인데, 모듈의 크기가 커지면 처음에 설계하기가 어려워지는 대신에, 모듈과 모듈을 합치는 과정이 편해진다. 반대로 모듈의 크기가 작아지면 처음에는 설계하기 쉽지만, 이러한 모듈들을 조립하는 단계에서 힘들어 진다. 자동차에서도 부품이 너무 많은 나머지 조립할 때, 일반인은 하지 못하는 것과 마찬가지이다. 하지만 조금 더 모듈의 크기가 큰 전자제품의 경우, 자동차 보다 조립하기는 쉬운 경향이 있다. 물론 이러한 예는 정확한 예는 아니지만 모듈에 대해 이해하기에는 충분하리라 생각한다.

 

모듈을 사용하는 이유는 사람이 다룰 수 있는 단위로 나누어서 소프트웨어를 설계하기 쉽고 유지보수 하기 쉽게 만들기 위함이다. 프로그램이 하나의 덩어리로만 이루어진다면 우리는 다음 소프트웨어 버전을 만들기 위해서 처음부터 설계해야할 것이다. 또한 특정 부분이 고장나서 고치려고 할 때, 그 소프트웨어를 다시 사야 할 것이다. 

 

지금 세상은 모듈화가 잘 이루어져 있어서 특정 예를 들긴 어렵지만, 소비자의 입장에서 예를 들어보로독 하자. 대표적인 덩어리 모듈의 예시를 들어보자면 핸드폰에서 탈착식 배터리와 일체형 배터리의 차이라 볼 수 있다. 탈착식 배터리의 장점은 배터리의 수명이 다 되어, 새 것으로 교체하고자 한다면 언제든지 교체가 가능하다. 하지만 일체형 배터리는 그렇게 하기 어렵다. 액정을 뜯어내야 하며, 그것을 다시 붙여야 한다. 이러한 과정에서 소비자가 직접 하기 힘든데다가 엔지니어에게 맡길 경우 많은 비용이 소모되는 것이다. 

 

패키지


  패키지란 Class들의 모음을 패키지라 한다. Package(패키지)란 말에서 알 수 있듯이 하나의 선물 꾸러미라 생각하면 편하겠다. 여기에 추가로 인터페이스를 같이 묶어두고 하나의 폴더에 저장해둔 것이다. 여기서 인터페이스라 하면 사용할 수 있게끔 만들어주는 장치라 보면 된다. 전자기기에서는 전기 코드가 인터페이스에 해당한다. (전기 코드 자체도 인터페이스이지만, 전자기기의 여러 버튼들 또한 인터페이스라 볼 수 있다.)Interface는 영어 단어 해석에서 보자면 [결합부], [접속기], [대면부] 등의 뜻을 가지고 있다. 특정 물체와 물체가 맞닿는 곳을 인터페이스라 할 수도 있다. 혹은 사물과 사용자가 서로 의사소통 할 수 있도록 만들어 놓은 매개체를 의미한다. 사용자와 맞닿은 인터페이스를 UI (User Interface)라 하기도 한다. 핸드폰에서 보이는 화면 대부분이 UI이기도 하다. 

  패키지를 두는 대표적인 이유 중 하나는 클래스 이름의 고유성을 보장하기 위해서이다. 프로그래밍 프로젝트가 커지면 커질 수록 패키지 이름이 겹치는 경우가 있는데, 이러한 상황에서 다른 패키지를 사용함으로써 중복을 회피할 수 있는 것이다.

  예로 들자면, A와 B는 파일 123을 저장하고 싶은 상태이다. 그런데 바탕화면에다가 저장하면 파일이 중복되서 하나의 파일이 사라질 확률이 있다. 이러한 상태에서 폴더를 따로 둠으로써 이를 피하는 것이다. A는 폴더 'A의 폴더'에 저장하고, B는 'B의 폴더'에 저장함으로써 파일 123은 유지가 되는 것이다.

  이제 불러오는 방식을 확인해보면, A의 폴더 -> 파일123B의 폴더 -> 파일123은 분명히 구분이 가능한 상태가 되었다.

 

* 이곳에서는 패키지의 사용법이 아닌 패키지가 무엇인지만 보도록 하고 나중에 패키지를 사용하는 방법에 대해 자세히 다루도록 하자.

 

 

자바에서 둘 사이의 차이점? 패키지와 모듈


그렇다면 모듈과의 차이점은 무엇인가? 패키지는 클래스와 인터페이스를 묶어놓은 하나의 폴더를 의미한다. 모듈은 이러한 패키지를 포함해서 특정 필요한 리소스를 모아놓은 하나의 컨테이너이다. 패키지보다는 모듈이 조금 더 상위 개념이라 볼 수 있지만, 그렇다고 패키지 위에 모듈이 있다고는 볼 수 없다. 실행가능하도록 최소한의 것들을 모아놓은 것이라 생각할 수 있다. 그래서 하드웨어적 성능이 떨어지는 IoT 기기 상에서도 응용 프로그램을 실행가능하다. 

 

 

다시 System.out.println으로 돌아가자.

여기서 System은 System class를 의미하고 있으며, 여러 class와 메소드를 포함하고 있는 것이다. 

module에서는 java.base, Package java.lang에 들어있다. 

여기에서는 PrintStream에서 out 필드임을 확인할 수 있다. out은 표준 출력 스트림을 의미한다. 여기서

 

스트림이란? 


  마우스와 키보드 같은 입력 장치와 모니터, 프린터기 같은 출력 장치에서 보낸 신호와 컴퓨터에서 보낸 신호는 컴퓨터 상에서 알아서 처리해준다. 우리는 하드웨어적인 부분을 신경쓸 필요가 없다. 이러한 작업을 해주는 것이 스트림이다. 

 

  스트림은 방향에 따라 두 가지로 나뉘어지는데, 컴퓨터 쪽으로 들어오는 스트림을 입력 스트림이며, 컴퓨터 쪽에서 사용자 방향으로 나가는 스트림을 출력 스트림이라 한다. 

 

여기까지만 공부해도 충분하다. 여기서 더 파고 들어서 그 원리까지 알면 좋겠지만, 마음이 허락 안할 수 있기에 이해력과 마음이 허락하는 한 파고들면 된다. 

 

 

스트림에 이어서 println


println은 특정 값을 입력받은 뒤에 사용자가 볼 수 있도록 출력해주는 역할을 한다. 하지만 println은 하나만 정의된 것이 아니다.

다양한 형태의 println이 정의되어 있다. 이렇게 하는 이유는 사용자가 어떤 값을 입력할지 모르기 때문이다. 우리가 앞서 보았듯이 컴퓨터는 한정된 형태의 데이터를 인식할 수 있다. 정수면 정수, 실수면 실수, 문자면 문자로 인식하는 것이다. 사람이야 각 형태를 따로 따로 자동으로 인식되지만 컴퓨터는 그러지 못하다. 그러므로 이를 모두 인식할 수 있도록 도와주는 것이 다양한 형태로 정의해두는 것이다. 우리는 이러한 형태를 자바의 다형성이라 불리며 실제 구현 방식 중 하나인 오버로딩(Overloading)방식이라 한다. 

 

같은 이름의 함수를 여러 개 정의하고, 매개변수와 그에 따른 유형 그리고 개수를 다르게 함으로써 사용자의 다양한 호출에 반응하기 위함이다. 그래야지 사용자가 숫자를 호출하건, 문자를 호출하건 다양하게 대응할 수 있는 것이다.