처음 자바를 배운 건 for 문 부터였다. 변수, 조건, 반복, 메서드. 정석. 그렇게 문법 을 외우고 나니 코드를 쓸 수 있게 됐다. 그런데 시스템을 만드는 단계는 거기서 한참 더 가야 했다. 그 거리를 어떻게 줄일 수 있는지 — 7년이 지난 지금이라면 다르게 가르칠 수 있을 거 같다.


TL;DR

단계 잘못 들이는 시간 진짜 가치
문법 너무 오래 1주일이면 충분
객체지향 너무 짧게 반년 이상손맛 필요
JVM 무시 그래도 알아야 함 (왜인지 본문)
Spring 너무 집중 프레임워크 의존 의 함정
시스템 안 가르침 모든 게 여기로 수렴

이 글은 왜 그런지어디서부터 어떻게 의 회고 + 권장 순서.


1. 자바를 다시 봐야 하는가 — AI 시대의 학습

Copilot 이 함수 본문을 그대로 채워준다. ChatGPT 가 Spring Boot 보일러플레이트를 완성된 프로젝트로 뽑아낸다. 그러면 자바를 깊이 배울 필요 가 있나?

답 : AI 가 더 잘 짤수록, 읽고 판단하는 사람 의 깊이가 더 중요해진다.

3년 전엔 코드 짜는 시간 이 일의 50% 였다. 지금은 20% 다. 나머지 80% 는 :

  • AI 가 뽑은 코드의 오류 가능성 검토
  • 왜 이렇게 짜야 하는지 설명 (팀원에게 / 본인에게)
  • 맞는 코드이지만 우리 시스템엔 안 맞는 경우 판별
  • 프레임워크의 함정 인지 비즈니스 문제 인지 분리

이 80% 의 일은 자바 문법 이 아니라 자바를 *왜 그렇게 짜야 하는가* 의 문제. 문법 위의 원리맥락. 그래서 깊이가 더 필요해졌다.

AI 가 문법 을 대신해주는 시대일수록, 사람은 문법을 넘어선 부분에 시간을 써야 한다.


2. 문법 은 1주일, 생각 은 평생

신입에게 문법 가르치는 데 한 달을 쓰는 건 잘못. 1주일이면 충분하다.

  • 변수, 타입, 연산자
  • 조건문, 반복문
  • 메서드 정의 / 호출
  • 클래스 / 객체 / 생성자
  • 컬렉션 (List / Map / Set) 의 기본 사용
  • 예외 처리의 기본 문법 (try / catch)

이 정도 1주일. 외워서 가 아니라 코드 100줄 쳐 보면서. 외우려고 하면 안 된다.

그러고 나면 문법 차원은 끝. 이후 8주는 같은 문법으로 다른 생각을 어떻게 표현하는지 의 영역이다.

// 둘 다 문법은 알 수 있다. 그런데 *왜 후자가 더 좋은가* — 이게 평생의 영역.

// A
public List<User> getActiveUsers(List<User> users) {
    List<User> result = new ArrayList<>();
    for (User u : users) {
        if (u.getStatus().equals("ACTIVE")) {
            result.add(u);
        }
    }
    return result;
}

// B
public List<User> getActiveUsers(List<User> users) {
    return users.stream()
        .filter(User::isActive)
        .toList();
}

A 는 문법, B 는 생각. 왜 B 가 좋은가비교 가능기준 을 갖춰야 한다. 그게 평생 의 학습.


3. 객체지향 — 반년 이상의 손맛

객체지향은 3일 강의로 끝낼 영역이 아니다. 책 1권 읽어도 안 된다. 직접 코드를 짜면서 망해 봐야 한다.

내가 신입 때 이런 코드를 썼다 :

public class OrderService {
    public void process(Order order) {
        // 200줄 — 결제 / 재고 / 배송 / 알림 / 로깅 다 한 메서드 안에
    }
}

문법은 맞다. 동작한다. 근데 6개월 뒤 다른 사람이 못 고친다. 왜 못 고치는지 — 책임의 분리 가 안 되어 있어서. 그걸 책으로 들어서 아는 것직접 고치다가 새벽에 운다 는 다르다.

객체지향은 4 가지 만 진짜로 익히면 된다 :

  1. 책임의 분리 — 한 클래스가 한 가지 일 만 한다. SRP.
  2. 의존성의 방향위가 아래를 안다 가 아니라 둘 다 추상에 의존. DI.
  3. 변하는 것과 변하지 않는 것의 구분 — interface 가 변하지 않는 쪽, 구현이 변하는 쪽.
  4. 상속보다 위임is-a 보다 has-a. composition over inheritance.

이 4개를 문장으로 외우는 건 의미 없다. 6개월 동안 잘못 짠 코드 리팩터링 하면서 몸에 새겨야 한다. 그게 손맛. 책으로 안 와닿는 영역.


4. JVM 을 알아야 하는가

“JVM 은 그냥 동작하는 거 아닌가요?”

맞다. 평소엔 그렇다. 그런데 시스템이 죽을 때 는 다르다.

  • OOM 으로 컨테이너가 OOMKilled 됐다. JVM heap 크기를 어떻게 정해야 하나?
  • GC pause 가 길다. G1 vs ZGC 어느 게 우리 시스템에 맞나?
  • 메모리는 안 늘어나는데 컨테이너 RSS 가 계속 증가. metaspace 인가, native memory 인가?
  • Thread dump 분석 으로 deadlock 위치 찾기

이 모든 게 JVM 모름 → 못 풂. 평소 안 보이다가 결정적 순간에 시스템 운영 가능한지 를 가르는 영역.

신입 때는 몰라도 됨. 1~2년 차에 부딪힐 때 배우면 충분. 단 이런 게 있다는 것 만은 알고 있어야 부딪혔을 때 어디서 시작할지 안다.

권장 :

  • 처음 6개월 : 무시
  • 1년차 : jvm options 의 의미 라도 한 번 읽기 (-Xmx, -Xms, -XX:+UseG1GC)
  • 2년차 : 처음 OOM 만나면 그때부터 본격 공부 (Visualvm, JConsole, jcmd)

5. Spring 의 함정 — 프레임워크 의존 으로 끝나는 학습

한국 백엔드에서 자바 = Spring 이라고 생각하는 경향이 강하다. 그래서 학습도 :

  1. 자바 문법 1개월
  2. 객체지향 1개월
  3. Spring Boot 6개월 ← 여기서 멈춤
  4. (없음)

Spring 을 깊이 익히는 건 좋다. 그런데 Spring 만 익히면 프레임워크 종속 이 된다. 면접에서 :

“Spring 안 쓰면 어떻게 짤 거예요?”

이 질문에 침묵 하면 프레임워크 종속 의 신호. Spring 이 해주는 것 / 어떻게 알아야 한다.

  • @AutowiredDI 컨테이너 없이 라면 어떻게 짜는가? → 생성자 주입의 원형.
  • @TransactionalAOP 없이 라면 어떻게? → try-catch + commit/rollback 직접 호출.
  • JpaRepository없으면 어떻게 쿼리 추상화? → DAO 패턴.

이걸 알아두면 Spring 이 왜 그렇게 설계됐는지 가 보인다. 프레임워크의 함정 에서 빠져나온다.

“Spring 을 잘 쓰는 사람” 이 아니라 “Spring 의 철학을 아는 사람” 이 되어야 한다.


6. 한국 백엔드의 자바 편중 을 어떻게 봐야 할까

한국 백엔드 채용의 70%+ 가 Java/Kotlin + Spring. 이 편향은 현실. 자바를 배우는 게 취업 측면 에서 옳은 선택이다.

그러나 자바만 알아서 는 안 된다. 이유 :

  1. 타 언어를 알면 자바를 더 잘 안다 — Python 의 간결함 을 보고 자바의 verbose 가 *어디서 오는지* 안다. Go 의 struct + method 를 보고 상속의 한계 가 보인다.
  2. 시장이 천천히 다양해진다 — 핀테크 / 글로벌 SaaS / AI 인프라 영역에서 Kotlin, Go, TypeScript, Rust 가 늘어남.
  3. MSA 환경에서는 언어 혼용 이 일반적 — 자바만 알면 팀의 일부분만 볼 수 있다.

권장 비중 :

  • 자바 / Spring : 주력 (70%)
  • 보조 언어 1개 : 깊이 기본 수준 (20%) — Python 또는 TypeScript
  • 보조 언어 2개 : 읽을 수만 (10%) — Go 또는 Kotlin

이 비중을 몇 년에 걸쳐 만들어 가면 된다.


7. 면접에서 묻는 것 vs 실 현장에서 쓰는 것

면접에서 자주 묻는 :

  • JVM 구조 / GC 의 종류
  • equals / hashCode
  • 동시성 (synchronized, volatile, Lock)
  • Spring 의 @Transactional 동작 원리
  • 디자인 패턴

실 현장에서 매일 쓰는 :

  • JPA N+1 문제 와 해결
  • 트랜잭션 경계 결정
  • DTO 변환 의 책임 위치
  • 예외 처리 의 일관성
  • 로깅 표준화

겹치는 게 적다. 면접 준비와 실력 키우기별개의 활동 일 수 있다는 뜻. 둘 다 해야 한다.

권장 :

  • 처음 6개월 : 실 현장 영역 (실수 → 학습 cycle)
  • 면접 직전 1~2개월 : 면접 영역 별도 학습
  • 자신 있는 면접 답변 = 현장 영역 의 경험 + 면접 영역의 정리

8. 내가 다시 시작한다면 — 8 단계 학습 순서

7년 전 나에게 보낸다면 이렇게 순서를 정하겠다 :

1주차    : 문법 (변수 / 조건 / 반복 / 메서드 / 클래스)
2주차    : 컬렉션 + 예외 + 제네릭의 기본
3주차    : 객체지향 의 *4 가지* 책임/의존/추상/위임
4주차    : 함수형 (람다 / 스트림 / Optional)
1개월    : *Spring 없이* 작은 CLI 앱 만들기 (예: 가계부, 일정관리)
2개월    : Spring Boot 입문 — 단 *AOP / DI 의 원형* 부터 이해
3개월    : JPA / DB 와의 진짜 싸움 — N+1, 영속성 컨텍스트
6개월    : *시스템 운영* 차원 — 로깅 / 모니터링 / 배포
1년+     : JVM 깊이 (OOM 만났을 때)
2년+     : 다른 언어 1개 (Python or TypeScript)
3년+     : *내가 가르치는* 단계 — 다른 사람을 가르치면서 *진짜* 안다

각 단계가 충분히 익으면 다음 으로. 시간보다 *손에 익었나 가 기준*.


9. 학습 매체의 우선순위

7년이 지난 지금 권장하는 매체 순서 :

순위 매체 이유
1 본인 코드 짜서 망하기 가장 안 잊힘
2 본인 코드를 다른 사람이 리뷰 무엇을 모르는지 알게 됨
3 오픈소스 코드 읽기 (Spring 자체, 좋은 프로젝트) 진짜 좋은 코드 보면 안목 생김
4 (Effective Java, 토비의 Spring) 정리된 지식
5 블로그 / 강의 빠른 이해, 단 얕음 주의
6 AI 챗봇 / Copilot 마지막 에. 안 그러면 생각 안 함

AI 챗봇을 6 번 에 두는 이유 : 너무 쉽게 정답 을 줌. 고민의 시간 이 사라짐. 고민이 학습 이다.


10. 마치며 — 코드 짜는 사람 이 아니라 시스템 만드는 사람

자바 학습의 끝은 코드를 잘 짜는 것 이 아니다. 코드로 시스템을 만들고 운영하는 것 이다. 그 거리가 6개월 → 6년 까지 차이 난다.

이 글의 모든 내용을 한 줄로 줄이면 :

문법은 1주, 객체지향은 반년, JVM 은 부딪힐 때, Spring 은 *그 함정까지 알고, 그 다음은 시스템.*

자바를 처음 배우는 사람 에게 이 글이 로드맵 이 되면 좋겠다. 7년 차에 다시 보는 사람에게 놓친 게 무엇인지 확인하는 글이 되면 더 좋겠고.

자바는 *언어가 아니라 *생각의 단위** 다. 그 생각을 어떻게 키울지가 학습의 본질.


본 글은 본인의 7년간 Spring Boot / 분산시스템 운영 경험에서의 회고. 모든 권장은 본인 경험 일 뿐 유일한 답 은 아니다. 다른 길로 더 잘 가는 사람도 많다. 본인이 손에 익은 길 을 권할 뿐.