Java 기초 문법을 실전 문제로 연결하는 방법

Alchemist·2026년 10월 7일

KT AIVLE

목록 보기
68/130

Java의 변수, 연산자, 조건문, 반복문을 각각 이해했다고 해서 바로 프로그램을 만들 수 있는 것은 아니다. 실제 코드는 여러 문법을 동시에 사용해 하나의 문제를 해결한다.

이 글에서는 기초 문법을 서로 연결하는 연습 방법을 정리한다.

문제를 코드로 바꾸는 순서

처음부터 코드를 작성하기보다 요구사항을 작은 단계로 나누는 것이 좋다.

예를 들어 간단한 주문 프로그램을 만든다고 해보자.

요구사항:

1. 상품 가격을 입력받는다.
2. 수량을 입력받는다.
3. 총 주문 금액을 계산한다.
4. 50,000원 이상이면 배송비는 무료다.
5. 그렇지 않으면 배송비 3,000원을 추가한다.
6. 최종 결제 금액을 출력한다.

필요한 문법을 연결하면 다음과 같다.

Scanner → 입력
변수 → 값 저장
연산자 → 금액 계산
if → 배송비 결정
출력 → 결과 확인

예제: 주문 금액 계산

import java.util.Scanner;

public class OrderApp {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("상품 가격: ");
        int price = scanner.nextInt();

        System.out.print("수량: ");
        int quantity = scanner.nextInt();

        int orderAmount = price * quantity;
        int deliveryFee;

        if (orderAmount >= 50_000) {
            deliveryFee = 0;
        } else {
            deliveryFee = 3_000;
        }

        int paymentAmount = orderAmount + deliveryFee;

        System.out.println("주문 금액: " + orderAmount);
        System.out.println("배송비: " + deliveryFee);
        System.out.println("최종 결제 금액: " + paymentAmount);
    }
}

작은 프로그램이지만 대부분의 기초 문법이 함께 사용된다.

반복 입력으로 발전시키기

한 번 실행하고 종료하는 프로그램을 메뉴 방식으로 발전시킬 수 있다.

while (true) {
    System.out.println("1. 주문 계산");
    System.out.println("0. 종료");

    int menu = scanner.nextInt();

    if (menu == 0) {
        break;
    }

    if (menu == 1) {
        // 주문 계산
    }
}

여기서 while, if, break, Scanner가 연결된다.

범위 출력 문제로 반복문 익히기

두 숫자를 입력받아 작은 수부터 큰 수까지 출력해보자.

int first = scanner.nextInt();
int second = scanner.nextInt();

int start;
int end;

if (first <= second) {
    start = first;
    end = second;
} else {
    start = second;
    end = first;
}

for (int number = start; number <= end; number++) {
    System.out.println(number);
}

문제 하나 안에서 조건문과 반복문이 함께 사용된다.

누적 합계를 구하는 패턴

반복문에서 매우 자주 등장하는 구조다.

int sum = 0;

for (int i = 1; i <= 100; i++) {
    sum += i;
}

System.out.println(sum);

핵심은 반복문 밖에 누적 변수를 만들고 반복할 때마다 값을 더하는 것이다.

초기값 → 반복 → 누적 → 결과

이 패턴은 주문 금액 합계, 방문자 수 합계, 점수 합계 등 다양한 곳에서 사용된다.

평균 계산에서 형변환 확인하기

int sum = 10;
int count = 4;

double average = sum / count;

이 코드의 결과는 2.5가 아니라 2.0이다.

double average = (double) sum / count;

계산 전에 형변환해야 원하는 실수 결과를 얻을 수 있다.

코드가 길어지면 메서드로 나누기

처음에는 main() 안에서 모든 코드를 작성해도 된다.

하지만 프로그램이 길어지면 역할별로 메서드를 분리한다.

static int calculateOrderAmount(int price, int quantity) {
    return price * quantity;
}

static int calculateDeliveryFee(int orderAmount) {
    if (orderAmount >= 50_000) {
        return 0;
    }

    return 3_000;
}

이제 main()은 전체 흐름을 보여준다.

int orderAmount = calculateOrderAmount(price, quantity);
int deliveryFee = calculateDeliveryFee(orderAmount);

문제를 못 풀었을 때 학습하는 방법

프로그래밍 문제를 오래 고민하는 것만이 항상 좋은 학습은 아니다.

추천하는 순서는 다음과 같다.

  1. 요구사항을 한 줄씩 나눈다.
  2. 사용할 변수부터 적는다.
  3. 입력과 출력을 먼저 만든다.
  4. 조건문이나 반복문을 하나씩 추가한다.
  5. 작은 값으로 실행 결과를 확인한다.
  6. 막히면 정답이나 문서를 참고한다.
  7. 이해한 뒤 코드를 닫고 처음부터 다시 작성한다.

특히 마지막 단계가 중요하다. 정답을 읽어서 이해하는 것과 직접 다시 구현할 수 있는 것은 다르다.

디버깅할 때 출력 활용하기

초보 단계에서는 중간 값을 출력하는 것만으로도 많은 문제를 찾을 수 있다.

System.out.println("price=" + price);
System.out.println("quantity=" + quantity);
System.out.println("orderAmount=" + orderAmount);

예상 값과 실제 값을 비교하면서 어느 단계에서 잘못되었는지 찾는다.

익숙해지면 IDE의 디버거와 breakpoint를 활용하면 된다.

값 교환 패턴으로 대입 원리 익히기

두 변수의 값을 바꾸는 문제는 단순하지만 대입의 본질을 이해하기 좋다.

잘못된 코드부터 보자.

int first = 10;
int second = 20;

first = second;
second = first;

첫 번째 대입이 끝나는 순간 first의 기존 값 10을 잃어버린다. 그래서 임시 변수가 필요하다.

int temp = first;
first = second;
second = temp;

이 패턴은 "대입하면 오른쪽 값을 읽어 왼쪽을 덮어쓴다"는 규칙을 직접 체감하게 해준다.

입력 순서를 정규화하고 반복문으로 처리하기

두 숫자를 어느 순서로 입력하든 작은 값부터 처리하고 싶다면 먼저 상태를 정규화한다.

int first = scanner.nextInt();
int second = scanner.nextInt();

if (first > second) {
    int temp = first;
    first = second;
    second = temp;
}

for (int value = first; value <= second; value++) {
    System.out.print(value);

    if (value < second) {
        System.out.print(", ");
    }
}

핵심은 복잡한 반복문을 만드는 것이 아니라 반복 전에 데이터를 다루기 좋은 상태로 바꾸는 것이다.

최솟값·최댓값 찾기 패턴

int[] responseTimes = {130, 95, 410, 170};

int min = responseTimes[0];
int max = responseTimes[0];

for (int responseTime : responseTimes) {
    if (responseTime < min) {
        min = responseTime;
    }

    if (responseTime > max) {
        max = responseTime;
    }
}

이 코드는 배열 순회 + 조건문 + 상태 갱신을 조합한 대표적인 기초 패턴이다.

2차원 데이터를 행 단위로 집계하기

서비스별 일간 요청 수가 있다고 가정해보자.

int[][] requests = {
    {120, 150, 180},
    {90, 110, 130}
};

서비스별 합계를 구하려면 행마다 sum을 새로 만든다.

for (int service = 0; service < requests.length; service++) {
    int sum = 0;

    for (int day = 0; day < requests[service].length; day++) {
        sum += requests[service][day];
    }

    double average = (double) sum / requests[service].length;
    System.out.println("service=" + service + ", avg=" + average);
}

중첩 반복문, 배열 길이, 누적 합, 형변환을 한 번에 연결할 수 있는 좋은 연습이다.

메뉴 프로그램은 기초 문법 종합 문제다

while (true) {
    System.out.println("1. 등록");
    System.out.println("2. 조회");
    System.out.println("3. 종료");

    int menu = scanner.nextInt();

    switch (menu) {
        case 1 -> register();
        case 2 -> showList();
        case 3 -> {
            return;
        }
        default -> System.out.println("잘못된 메뉴");
    }
}

메뉴형 프로그램에는 자연스럽게 다음 개념이 모인다.

반복문       프로그램 계속 실행
Scanner      사용자 선택 입력
조건/switch  기능 분기
메서드       기능별 로직 분리
return       프로그램 흐름 종료

입문 문법을 한 번에 복습하기 좋다.

병렬 배열로 관리해보고 한계를 느껴보기

객체지향을 배우기 전에는 다음처럼 상품 데이터를 따로 관리할 수 있다.

String[] names = new String[5];
int[] prices = new int[5];
int productCount = 0;

상품을 하나 등록할 때 같은 인덱스를 사용한다.

names[productCount] = name;
prices[productCount] = price;
productCount++;

이 방식은 기초 문법을 연습하기에는 좋지만 데이터가 늘어나면 관리가 어려워진다. 예를 들어 재고, 카테고리, 상품 ID가 추가되면 배열이 계속 늘어난다.

이 불편함을 느끼는 것이 다음 단계인 클래스와 객체가 왜 필요한지 이해하는 좋은 출발점이다.

문제 풀이에서 리팩토링까지 한 번 더 한다

문제가 정답대로 동작했다고 바로 끝내지 말고 두 번째 단계로 코드를 개선한다.

첫 번째 목표:

일단 올바르게 동작하게 만들기

두 번째 목표:

중복 제거
이름 개선
스코프 축소
메서드 추출
매직 넘버 제거

예를 들어 배송비 계산이 여러 곳에 반복된다면 메서드로 추출한다.

static int calculateShippingFee(int amount) {
    if (amount >= 50_000) {
        return 0;
    }

    return 3_000;
}

기능을 먼저 완성한 뒤 구조를 개선하는 연습을 반복하면 문법 암기에서 실제 개발 습관으로 넘어갈 수 있다.

초보 단계의 디버깅 루틴

코드가 예상대로 동작하지 않으면 무작정 다시 작성하기보다 실행 흐름을 좁힌다.

  1. 입력값을 출력한다.
  2. 조건식의 각 결과를 출력한다.
  3. 반복문의 카운터를 출력한다.
  4. 누적 변수의 변경 과정을 출력한다.
  5. 배열이라면 현재 인덱스를 출력한다.
  6. 메서드라면 전달된 인수와 반환값을 확인한다.
System.out.println("i=" + i + ", sum=" + sum);

이런 단순 로그만으로도 많은 기초 버그를 찾을 수 있다.

입문 문법 다음에 무엇을 공부할까?

변수, 연산자, 조건문, 반복문, 배열, 메서드가 익숙해졌다면 다음 단계에서는 이 개념들을 더 큰 구조로 확장하면 된다.

클래스와 객체
    ↓
캡슐화 / 상속 / 다형성
    ↓
예외 처리
    ↓
컬렉션(ArrayList, Map 등)
    ↓
제네릭
    ↓
파일/네트워크/데이터베이스
    ↓
웹 백엔드 프레임워크

중요한 것은 한 번 읽고 넘어가는 것이 아니라 작은 프로그램을 직접 만들면서 문법을 계속 다시 사용하는 것이다.

핵심 정리

  • 실제 문제는 변수, 연산자, 조건문, 반복문을 함께 사용해 해결한다.
  • 요구사항을 작은 단계로 쪼개면 필요한 문법이 보이기 시작한다.
  • 입력 → 저장 → 계산 → 조건 처리 → 출력 순서로 생각하면 문제를 구조화하기 쉽다.
  • 누적 합계는 반복문에서 매우 자주 사용하는 기본 패턴이다.
  • 평균 계산에서는 정수 나눗셈으로 인한 소수점 손실을 주의한다.
  • 코드가 길어지면 역할별 메서드로 분리한다.
  • 정답을 참고한 뒤에는 반드시 직접 다시 구현해보는 것이 좋다.
profile
html_programming_language

0개의 댓글