
안녕하세요! <코딩 자율학습 나도코딩의 자바 입문> 교재와 함께 진행하는 코딩학습단 21기, 2주차 학습을 성공적으로 마무리했습니다.
1주차 과정이 변수, 자료형, 연산자 등 데이터를 담고 연산하는 기본적인 ‘재료’를 준비하는 과정이었다면, 6일차부터 10일차까지 진행된 2주차(4장~7장) 과정은 그 재료들을 활용해 실제 프로그램의 로직을 구성하는 핵심 단계였습니다. 조건문으로 분기를 나누고, 반복문으로 처리 효율을 높이며, 배열을 통해 대량의 데이터를 체계적으로 관리하는 방법을 집중적으로 학습했습니다. 그 구체적인 5일간의 실습 기록을 정리해 봅니다.
6일차: 문자열 조작의 디테일과 메모리 참조 개념 (4장)
6일차에는 단순한 텍스트 출력을 넘어, 문자열(String) 객체 내의 데이터를 가공하고 검증하는 다양한 내장 메서드들을 깊이 있게 다뤘습니다. 실무에서 외부 데이터를 파싱하거나 정제할 때 반드시 알아야 하는 기능들입니다.
- 문자열 가공: 특정 문자열을 찾아 다른 문자로 치환하는
replace(), 인덱스를 기준으로 원하는 구간만 추출하는substring(), 불필요한 여백을 제거하는trim(), 그리고 문자열을 결합하는concat()과+연산자의 활용을 실습했습니다.
- 문자열 비교의 함정 (
equals()vs==): 자바에서 가장 실수하기 쉬운 문자열 비교 방식의 차이를 확인했습니다.
equals()와 equalsIgnoreCase()는 문자열이 가진 실제 데이터 값(내용) 자체를 비교합니다.
반면 == 연산자는 데이터 값이 아닌, 객체가 생성된 메모리의 참조 주소를 비교합니다. 따라서 new String("1234") == new String("1234")를 실행하면, 내용은 같지만 서로 다른 메모리 공간에 할당되었기 때문에 false가 반환된다는 중요한 개념을 짚고 넘어갔습니다.
이스케이프(Escape) 문자: 콘솔 출력 시 줄바꿈(\n)이나 탭 여백(\t)을 강제로 삽입하여 출력 포맷을 정렬하는 기법을 익혔습니다.
package chap_04;
public class _chap04_ex1 {
public static void main(String[] args) {
String s = "I like Java and Python and C.";
// 데이터 가공 실습
System.out.println(s.replace(" and", ",")); // I like Java, Python, C.
System.out.println(s.substring(7)); // 지정된 인덱스부터 끝까지 추출: Java and Python and C.
// 문자열 메모리 참조 비교
String s6 = new String("1234");
String s7 = new String("1234");
System.out.println(s6 == s7); // false (서로 다른 객체 주소를 참조하므로)
// 이스케이프 문자를 활용한 출력 정렬
System.out.println("해물파전\t\t9,000원"); // 탭 간격 적용
}
}7일차: 논리적 분기 처리, if문과 switch-case (5장)
7일차에는 프로그램의 실행 흐름을 조건에 따라 동적으로 분기하는 제어문을 학습했습니다.
if - else if - else문: 논리 연산자(AND, OR)를 결합하여 복합적인 조건을 순차적으로 검증할 때 사용합니다. 위에서부터 아래로 순차적으로 조건을 평가하며, 참(true)인 블록을 만나면 해당 코드를 실행하고 전체 조건문을 빠져나가는 구조를 실습했습니다.
switch-case문: 특정 변수의 값(상수)과 정확히 일치하는 케이스를 찾아 실행 흐름을 이동시킵니다. 범위 조건(>,<등)을 평가하는if문과 달리, 회원 등급이나 메뉴 번호처럼 명확하게 분절된 값을 판별할 때 코드의 가독성을 크게 높일 수 있습니다. 특히break;키워드를 생략할 경우 발생하는 ‘Fall-through(조건 누적 실행)’ 현상을 실습하며 로직을 제어하는 방식을 확인했습니다.
8일차: 데이터 처리를 위한 핵심 로직, 반복문 (6장)
8일차는 코드의 중복을 제거하고 대량의 연산을 자동화하는 반복문의 3가지 형태를 비교 학습했습니다.
for문:(초기화; 조건식; 증감식)의 구조를 가지며, 반복 횟수가 명확하게 정해져 있을 때 가장 직관적으로 사용할 수 있습니다.
while문 &do-while문:while문은 진입 시점에 조건을 먼저 평가하여 거짓일 경우 단 한 번도 실행되지 않을 수 있습니다. 반면do-while문은 무조건 블록 내부의 코드를 최소 1회 실행한 후 조건을 검사하므로, 사용자 입력을 먼저 받아야 하는 로직 등에 적합합니다.
가장 집중했던 부분은 중첩 반복문(Nested Loop)이었습니다. 바깥쪽 for문이 행(Row)을, 안쪽 for문이 열(Column)을 제어하는 방식을 이용해 점진적으로 증가하는 별(*) 찍기 실습을 진행하며, 다차원적인 데이터 처리 로직을 구상하는 훈련을 했습니다.
9일차: 반복문 흐름의 세밀한 제어, break와 continue (6장 이어서)
9일차에는 전날 배운 중첩 반복문을 응용해 구구단 전체를 출력해 보았고, 반복문의 실행 흐름을 강제로 제어하는 break와 continue를 치킨집 판매 로직 예제로 실습했습니다. 단순히 반복하는 것을 넘어, 특정 예외 상황이 발생했을 때 시스템이 어떻게 대응해야 하는지를 코드로 구현하는 과정입니다.
continue(흐름 건너뛰기): 현재 진행 중인 반복 회차의 남은 코드를 스킵하고, 바로 다음 회차의 조건 검사(또는 증감식)로 넘어갑니다. 예제에서는 ‘노쇼 손님’이 발생했을 때 해당 번호를 건너뛰고 다음 대기 번호를 호출하는 로직에 적용했습니다.
break(완전 탈출): 감싸고 있는 가장 가까운 반복문 자체를 즉시 종료하고 빠져나갑니다. 일일 최대 판매 수량(재료)이 모두 소진되었을 때 시스템을 강제 종료하는 기능으로 구현했습니다.
package chap_06;
public class _05_ChickenShop {
public static void main(String[] args) {
int max = 20; // 일일 최대 한정 판매량
int sold = 0; // 실시간 판매 누적량
int noShow = 17; // 나타나지 않은 예약 손님 번호
for (int index = 1; index <= 50; index++) {
System.out.println(index + "번 손님, 주문하신 치킨 나왔습니다.");
// 예외 1: 노쇼 손님 발생 시 카운트를 올리지 않고 다음 루프로 건너뜀
if (index == noShow) {
System.out.println(index + "번 손님, 안 계셔서 차례를 넘깁니다.");
continue;
}
sold++;
System.out.println("판매 완료! 현재까지 판매량: " + sold + "마리");
// 예외 2: 재료 소진 시 더 이상 루프를 돌지 않고 즉시 종료
if (sold == max) {
System.out.println("금일 재료가 모두 소진되었습니다.");
break;
}
}
System.out.println("영업을 종료합니다.");
}
}10일차: 대량의 데이터를 체계화하는 배열과 아스키코드 (7장)
2주차 마지막 날인 10일차에는 동일한 자료형의 변수들을 연속된 메모리 공간에 하나로 묶어 관리하는 배열(Array)을 학습했습니다.
단일 차원의 배열을 순회할 때 인덱스를 직접 제어하는 일반 for문 대신, 배열의 요소들을 처음부터 끝까지 안전하게 꺼내올 수 있는 향상된 for문(for-each) 구문을 작성해 보며 코드의 간결성을 높였습니다.
특히 2차원 배열 실습이 인상적이었습니다. 영화관 좌석표처럼 행과 열을 가진 String[][] seats 객체를 생성한 뒤, 알파벳 문자를 표현하는 아스키코드(ASCII)의 특징을 응용했습니다. char ch = 'A';로 시작하여 행이 바뀔 때마다 문자형 변수에 1을 더해(ch++) B, C, D 등으로 자동 치환시키는 로직을 구현했습니다. 값을 일일이 하드코딩하지 않고 컴퓨터의 연산 방식을 이용해 데이터를 자동 생성하는 프로그래밍적인 접근법을 익힐 수 있었습니다.
package chap_07;
public class _03_MultiArray {
public static void main(String[] args) {
// 10행 15열 규모의 2차원 배열 메모리 할당
String[][] seats3 = new String[10][15];
char ch = 'A'; // 좌석 행을 표기할 아스키코드 기준 문자
// 2차원 배열 데이터 초기화 (A1 ~ J15 자동 생성)
for(int i = 0; i < seats3.length; i++) {
for(int j = 0; j < seats3[i].length; j++) {
// 문자형 변수 ch를 String으로 변환 후 열 번호 결합
seats3[i][j] = String.valueOf(ch) + (j + 1);
}
ch++; // 다음 행으로 넘어갈 때 알파벳 아스키코드 값 1 증가 (A -> B)
}
// 초기화된 배열 전체 순회 및 출력
for(int i = 0; i < seats3.length; i++) {
for(int j = 0; j < seats3[i].length; j++) {
System.out.print(seats3[i][j] + " ");
}
System.out.println(); // 단일 행 출력이 끝나면 개행 처리
}
}
}2주차 마무리 총평
조건과 반복, 그리고 배열의 개념이 결합되면서 단순했던 코드가 점점 체계적인 구조를 갖춘 ‘프로그램’의 형태를 띠기 시작했습니다. 특히 2차원 배열의 인덱스와 아스키코드를 수학적으로 계산하여 좌석 번호를 자동 생성하는 실습은, 알고리즘적인 사고를 훈련하는 데 매우 효과적이었습니다.
다음 3주차부터는 자바 언어의 핵심이자 설계의 근간이 되는 ‘객체 지향 프로그래밍(클래스, 메서드, 객체)’ 챕터에 진입하게 됩니다. 절차적인 흐름 제어를 넘어 데이터와 기능을 하나의 객체로 캡슐화하는 과정을 집중적으로 파고들 예정입니다. 다음 주 학습 기록으로 다시 찾아뵙겠습니다!
