JAVA 개발 환경
C, C++ 언어와는 다르게, 자바는 JVM(Java Virtual Machine)이 존재하고 자바는 이 JVM 덕분에 OS에 종속받지 않는다. 이 JVM과 자바 API를 포함하고 있는 환경이 JRE(Java Runtime Environment)이다. 하지만, JRE는 실제 개발에 필요한 컴파일러나 디버거 등의 도구는 포함하지 않고 있다. 때문에, 자바 프로그램을 개발하기 위해 JDK(Java Development Kit)가 필요하다. 이 JDK는 JRE를 포함하고 있으며 자바 컴파일러(javac), 인터프리터(java), 아카이버(jar), 문서 생성기(javadoc) 등과 같은 개발 도구를 포함하고 있다. 즉, 자바 프로그램을 실행시키는 데 필요한 모든 도구를 갖추고 있다.
[요약]
- 실행 환경 : JRE - (JVM + 자바 API)
- 개발 환경 : JDK - (JRE + 개발 도구)
개발 도구(Build Tool)
소프트웨어 개발 프로세스는 여러 단계를 거친다. 하지만 이런 단계를 수동으로 하는 것은 많은 시간과 노력이 필요하다. 때문에 이런 단계를 자동화하도록 나온 것이 빌드 도구이다. 즉, 빌드 도구는 개발 프로세스의 효율성을 높여주고 실수를 줄여준다.
빌드 도구 살펴보기
- Ant
- 자바 기반의 빌드 도구.
- XML 파일을 사용하여 빌드 과정 정의.
- 독립성이 뛰어나지만 XML 기반 설정이 복잡하고 의존성 관리 기능이 없다.
- Maven
- Ant의 단점을 보완한 빌드 도구로 프로젝트 전체 생명주기를 관리. (의존성, 프로젝트 정보, 빌드, 테스트, 배포 등)
- 하지만 여전히 XML 기반의 설정을 사용. 그래도 Ant에 비해 간결하고 직관적.
- Gradle (권장)
- Ant와 Maven의 장점을 합친 빌드 도구로 Groovy 또는 Kotlin을 사용한 스크립팅 언어이기 때문에 매우 유연하다.
- 그리고 기본적으로 인크리멘탈 빌드를 지원하고 병렬 처리와 캐싱을 통해 빠른 빌드 성능을 제공한다.
- 또한 Maven과 유사하게 강력한 의존성 관리 시스템을 제공한다.
*인크리멘탈 빌드(Incremental Build)란?
이는 전체 코드 베이스를 빌드하는 대신 마지막 빌드 이후에 변경된 부분만을 빌드하는 방식을 말한다.
통합 개발 환경 (IDE; Integrated Development Environment)
IDE는 소프트웨어 개발 과정에서 필요한 여러 도구를 하나의 프로그램 안에 통합시켜 놓은 환경을 말한다.
- Eclipse
- Intellij (권장)
유용한 단축키 (MAC) | |
'Option' + 'Enter' | 빠른 수정 |
'Command' + '1' | 폴더창으로 커서 이동 |
'Command' + 'N' | 새파일 생성 |
'Shift' + 'Shift' | 파일 이름 검색 |
'Option' + 'Up' 또는 'Down' | 단계별 블록 지정 |
'Command' + '/' | 주석 |
'Option' + 'Command' + 'L' | 코드 리포맷팅 |
'Ctrl' + 'T' | 리팩토링 |
'Shift' + 'Command' + 'A' | 명령어 검색 |
초보 개발자가 알면 좋은 정보
(1) Coding Convention
보통 팀이나 회사 개발 그룹에서 정해서 사용하고 만약, 정하지 않는다면 일반적인 자바 룰을 따른다.
다음은 일반적인 자바 룰이다.
- Indent : 들여쓰기 -> Tab과 Space를 섞어서 쓰지 않는다.
class className {} // X
class Class_Name {} // X
class ClassName {} // O
- Class Name은 대문자로 시작한다.
int var_Name; // X
int VarName; // X
int varName // O
void FuncName // X
void funcName // O
- 메소드나 변수명은 소문자로 시작한다.
(2) Reference
자바의 경우는 항상 Call By Value로 값을 넘긴다. 이 방식은 함수로 값을 전달할 때, 실제 값이 복사되어 전달된다. 즉, 함수 내에 해당 값을 변경해도 보통의 경우 변수에는 영향을 주지 않는다. 하지만 참조 변수인 경우에는 동일한 주소 값이 복사 되어 전달되기 때문에 변경 가능성이 아예 없는 것은 아니다.
반대로 Call By Reference 방식은 함수로 값을 전달할 때 값이 저장된 메모리의 주소가 전달된다. 즉, 함수 내에서도 해당 주소를 통해 직접 값을 변경할 수 있다.
public static void main(String[] args) {
User user = new User("name"); //(1) : 가장 먼저 User 객체 생성 및 할당
func(user); //(2) : user 객체가 복사되어 넘어간다.
System.out.println(user.name); //(5) : "name"
}
public static void func(User update){ //(3)
update = new User("update"); //(4) : 새로운 User 객체 할당
}
public static void main(String[] args) {
User user = new User("name"); //(1) : 가장 먼저 User 객체 생성 및 할당
func(user); //(2) : user 객체가 복사되어 넘어간다.
System.out.println(user.name); //(5) : "update"
}
public static void func(User update){ //(3)
update.name = "update"; //(4) : User의 name 변경
}
코드를 보면 이해하면 더 잘될 것이다.
(3) String
String a = "literal";
String b = new String("new");
자바에서 String은 리터럴 방식과 new 키워드를 사용하는 방식 2가지로 생성할 수 있다.
new 키워드로 생성하는 방식은 우리가 평소 알고 있던 객체 생성 방식처럼 새로운 메모리가 할당되는 방식이다.
하지만 리터럴 방식은 조금 다르다.
String a = "";
for(int i=0; i<3; i++){
a += i;
}
위 코드를 살펴보면, 'a' 변수에 계속 더해진다고 생각할 수 있다.
Constant Pool [
a == ""
a == "0"
a == "01"
a == "012"
]
하지만, 실제로는 위처럼, String 값이 바뀔때 마다, 새로운 메모리 주소가 할당된다. 즉, 총 3개의 String 영역이 더 생긴다.
위처럼 String은 Immutable(불변) 객체라는 것을 알 수 있다. 그리고 추가적으로 String의 리터럴은 Constant Pool(상수풀)을 이용한다. 즉, 값 생성 및 변경 시, 동일한 문자열이 상수풀에 들어있다면 새로 생성하지 않고 상수풀에 존재하는 리터럴 타입을 대입한다. 하지만 결국에 없는 것은 계속해서 메모리를 차지하기 때문에 비효율적이다.
그렇다면 Constant Pool에 등록된 리터럴은 GC의 대상일까?
다행히도 Java 7 이전에는 아니였지만 이후로 힙 영역으로 이동하게 되었다. 즉, String Pool에 저장되는 문자열 리터럴의 수에 대한 제약이 상당히 완화되었고 이로인해 String Pool에 있는 문자열 리터럴 객체들이 더 이상 참조되지 않을 때, GC의 대상이 되었다.
하지만 여전히, String은 불변 객체이기 때문에, 결국에 새로 생성한다는 것은 변하지 않는다. 즉, 메모리 사용에 여전히 비효율적이고 성능에 부담을 줄 수 있다. 따라서 문자열 결합이나 수정이 빈번하게 발생하는 경우에는 StringBuilder 혹은 StringBuffer를 사용하는 것이 좋다.
간단하게 두 객체에 대해 설명하면, StringBuffer는 각 메소드 별로 Synchronized 키워드가 존재한다. 즉 동기화되어 있기 때문에 Multi-Thread 환경에서 Thread-Safe하다. 하지만 StringBuilder : 동기화되지 않아 동시성 문제가 발생할 수 있지만 Single-Thread 환경에서 더 빠르게 동작한다. 때문에 상황에 맞게 사용하면 된다.
(4) Object 객체
- 이 객체는 모든 객체의 최상위 객체이다.
- 즉, 모든 객체는 Object 메소드를 호출할 수 있다.
(5) Git
- 깃을 사용하는 것은 기본기이다.
- 단, 명령어로 익힐 필요는 없다.
- 하지만, 어떻게 사용하는 지에 대해서는 알자.
하지만 꼭 알야아할 것은 '.gitignore' 이다.
- 포함되지 않아야 할 파일이 존재하면 좋지 않아 보인다. -> 감점 요소
- Ex) 빌드 결과 / 바이너리 / 제너레이트 가능한 파일들 / 로컬 설정 / 키 혹은 보완 관련 파일들
- 즉, *.class , *.jar , build/** , gradle/** , gradlew , gradlew.bat 과 같은 안올려도 되는 파일들은 .gitignore 파일에 기록해서 관리하자.
Tip) 'http://gitignore.io/' 에서 안올려야할 일반적인 파일을 생성할 수 있다.
참고 : KDT 프로그래머스 - 백엔드 데브코스
'Activity > 데브코스 - 백엔드 엔지니어링' 카테고리의 다른 글
벡엔드 데브코스 TIL - 동시성 이슈 해결하기 (4) | 2023.10.11 |
---|---|
벡엔드 데브코스 TIL - 프로젝트로 단축 URL 알아가기 (0) | 2023.10.04 |
벡엔드 데브코스 TIL - 프록시 패턴 발표 (1) | 2023.07.12 |
백엔드 데브코스 TIL - 동행 스크럼을 하다가 공부하게 된 Process와 Thread (0) | 2023.06.12 |
벡엔드 데브코스 TIL - 싱글톤 패턴 발표 (4) | 2023.06.08 |