1차 과제때는 사실 내용도 제대로 이해하지 못한 채로 그저 ai가 하라는대로, 시키는대로 이해하거나 응용하려는 의지없이 딸깍딸깍 키보드, 마우스질만 해서 급하게 냈었다. 그 과정을 겪으면서 이렇게 의미없이 구색만 맞춰서 과제를 내는게 무슨 의미가 있을까 싶었다. 다시 처음부터 해설 강의를 들으면서 처음부터 끝까지 내 손으로 직접 코드를 쓰면서 생각하면서 학습을 시작했다.
꽤나 오랜 시간을 부여받았었다고 생각했는데 그럼에도 시간이 많이 걸렸는데, 대부분 코드는 그럴듯해 보이는데 실제로 돌려보면 이상하게 동작하는 케이스였다. 까먹기 전에 정리해둔다.
1. while (조건) ; — 세미콜론 하나가 멈춤을 만들었다
exit 입력 전까지 반복하게 만들려고 이렇게 썼다.
while (!exit.equals("exit")) ;
{
System.out.println("첫 번째 숫자를 입력하세요: ");
...
}
실행했더니 아무것도 안 뜨고 그냥 멈춰있었다. 알고 보니 while문 뒤의 세미콜론이 문제였다.
자바에서는 while(조건) ; 이라고 쓰면 세미콜론 자체가 while문의 몸체가 된다. 그러니까 "조건이 참인 동안 아무것도 하지 않는다"를 무한 반복하는 코드가 된 거다. 그 아래 있는 { } 블록은 while문과 아무 상관없는 별개의 코드 블록이라서 영원히 도달하지 못한 것이었다.
세미콜론을 지우니 해결됐다. 한 번 영문모를 오류를 겪고 나니까 무심코 세미콜론을 붙이는 버릇을 고쳐야겠다 싶었다.
2. switch문 안에만 들어있던 출력 — 케이스별로 동작이 달라졌다
사칙연산 결과를 출력하는 코드를 switch의 / 케이스 안에만 넣어놨다.
case '/' -> {
if (num2 == 0) {
System.out.println("0으로 나눌 수 없습니다.");
break;
}
result = num1 / num2;
System.out.println("결과 : " + result); // 여기 있었음
}
나눗셈은 결과가 잘 나오는데 더하기, 빼기, 곱하기는 결과가 화면에 안 떴다. 한참 들여다보다가 sout("결과 " : result) 가 switch 블록 밖이 아니라 / 케이스 안에만 있다는 걸 발견했다. switch 밖으로 빼서 모든 연산이 공통으로 한 번만 출력하게 고쳤다.
생각해보면 당연한 거였는데, 쓸 때는 아무 생각없이 썼다가 왜 안되는지 찾는건 머리 터져버린다. 문장 하나, {} 하나 잘못쓰는건 1초도 안걸리지만 찾아내는건 1시간도 걸린다.
3. Calculator 클래스로 분리하고 나서 한 번 더 꼬였다
STEP 2 로 넘어가면서 연산 로직들을 Calculator 클래스로 옮기는 작업을 했는데, 중간에 그동안 연습용으로 쓰고있던 다른 파일의 main 메서드 코드를 제출용 App.java에 통째로 덮어쓴 적이 있다.
겉으로 보면 코드는 멀쩡해 보이는데, calculator.calculate(...)를 호출하는 줄이 하나도 없으니까 IntelliJ가 "Calculator 클래스가 한 번도 사용되지 않습니다"라는 경고를 띄웠다. 컴파일 에러는 아니라서 그냥 실행은 됐는데, 경고문은 신경이 쓰였다.
자세히 들여다봐도 도저히 모르겠어서 ai한테도 도움을 요청하니 원인을 알려줬다.
딱 이때 들었던 느낌이 뭐가 어디서부터 잘못된지도 모르겠고 분명 문장하나 글씨 몇글자만 바꾸면 될 것같은데 순간 머리속이 새하얗게 변하면서 내가 다루던 코드가 무슨 줄이었는지 어디서부터 손을 대야하는지 막막해졌었다.
별로 길지도 않은 이 코드를 다루면서도 갑자기 멘붕에 빠지는 모습을 보면서 앞으론 정신을 똑바로 차리고 "지금 당장 내가 뭘 하고 있었고 뭘 하려고 했는지" 를 또렷히 기억하는게 중요하다는 생각이 들었다.
Double result = calculator.calculate(...)라고 선언해놓고 바로 아래에 옛날 switch문 로직을 그대로 남겨둬서 double result;를 또 선언하는 식으로 변수가 중복된 적도 있었다. 컴파일러가 에러를 잡아줘서 다행이었다.
이건 결국 "지금 내가 보고 있는 파일이 진짜 내가 의도한 파일인지" 매번 확인하는 습관이 필요하다는 교훈으로 남았다.
4. 캡슐화하고 나서 삭제 메서드가 매번 실행됐다
결과 리스트에서 가장 먼저 저장된 값을 지우는 기능을 만들면서, "yes"를 입력했을 때만 지우게 하려고 했는데 실제로는 입력값과 상관없이 항상 지워지고 있었다.
String answer = sc.next();
calculator.removeResults(); // 조건 없이 항상 실행되고 있었음
if ("yes".equals(answer)) {
System.out.println("...");
}
removeResults() 호출이 if 블록 밖에 있어서, "yes"든 아니든 무조건 한 번씩 지워지고 있었던 거다. 그래서 계산을 여러 번 해도 리스트에 결과가 하나도 안 쌓이고 매번 비워지는 것처럼 보였다. removeResults()를 if 블록 안으로 한줄 옮겨주니 바로 해결됐다.
줄하나 괄호 하나에 따라 결과가 천지차이다. 항상 집중하고 한줄한줄의 의도를 계속 생각해야 한다.
5. 나눗셈만 실수로 처리하려다 타입 통일 문제에 부딪혔다
처음엔 나눗셈 결과만 double로 받고 나머지 연산(+, -, *)은 int로 받고 싶었다. 그런데 결과를 저장하는 리스트가 List<Double> 하나로 통일되어 있으니까, 같은 메서드 안에서 타입을 섞어서 반환할 수가 없었다.
ai한테 물어보니 java는 원래 안된다더라.. 너무 쉽게 생각했었나
결국 저장 자체는 double로 통일하고, 화면에 보여줄 때만 연산자가 /가 아니면 정수로 보이게 하는 식으로 타협하려고 했는데, 시간 관계상 이번 제출에는 반영하지 못했다. 다음에 여유 있을 때 출력 부분만 분기 처리해보고 싶다.
6. STEP 3는 결국 손도 못 댔다
트러블이라면 트러블...원래 STEP 3에서는 실수 입력 처리, 결과 조회 기능 말고도 람다랑 스레드까지 다뤄볼 수 있는 과정이 있었다. 근데 STEP 1, 2 짜는데도 시간을 너무 많이 써서 STEP 3는 시작도 못 했다.
1차 과제땐 ai가 시키는대로만 뇌빼고 옮겨적다가 내버리고 2차 과제때는 열심히 학습해서 커머스까진 못해도 계산기 만큼은 완벽하게 마스터해서 내보고 싶었는데 결국 1차랑 마찬가지로 하나도 구현하지 못하고 제출한게 너무 아쉽다.
지금까지 배운 건 객체지향으로 넘어가는 기초 단계(클래스 분리, 캡슐화)였는데, 람다나 스레드는 또 완전히 다른 영역이라 이번에 못 만져본 게 계속 마음에 걸린다. 특히 스레드는 동시성이라는 개념 자체를 한 번도 안 다뤄봤어서, 이번 기회에 건드려라도 봤다면 좋았을텐데 하는 생각이 든다.
다음에 시간 날 때 STEP 3 요구사항만 따로 떼서 한 번 더 연습해보고 싶다. 일단 이번엔 본격적인 Spring 과정을 들어가기전 계산기 STEP 1, 2를 제대로 굴러가게 만드는 데 의의를 두기로 한다.
느낀 점
오늘 겪은 버그들을 보면 전부 문법은 맞는데 줄 구분 실수나 괄호 처리의 미숙함으로 의도한 흐름과 다르게 동작하는 패턴이었다. 컴파일러가 안 잡아주는 종류의 실수라서, 직접 실행해보고 입력값을 바꿔가면서 테스트하는 게 왜 중요한지 다시 느꼈다. 다음 과제에서는 기능 하나 만들 때마다 내가 만든 코드가 모든 경로에서 의도한 대로 동작하나를 한 번씩 점검하고 넘어가야겠다.
'Camp > 과제' 카테고리의 다른 글
| [TIL]일정 관리 앱 Develop (0) | 2026.07.09 |
|---|---|
| [TIL]CH 3 일정 관리 앱 만들기 (0) | 2026.07.01 |
| [Java] 계산기 과제 Lv.2 트러블 슈팅- 클래스 분리가 왜 이렇게 헷갈렸나 (0) | 2026.06.19 |
| [Java] 코드카타 트러블 슈팅 (0) | 2026.06.17 |
| Camp/과제[TIL] CH2 Java 계산기 과제 Lv.2 (트러블 슈팅) (0) | 2026.06.16 |