더 구체적인 학습 내용과 회고는 일일 학습 기록에서 확인할 수 있습니다.
[ 1주차 종료 이후 ]
1주차가 끝났습니다. 1주차 코드에서 정말 많은 코드리뷰를 받았습니다. 정리하자면 총 11명에게 코드리뷰를 받았고, 저는 8명에게 코드리뷰를 해주었습니다.
코드리뷰 내용을 요약하자면 "이해가 쉽고 깔끔하다"는 평가와 몇 가지 개선점 제시가 있었습니다.
여러 가지의 피드백이 있었지만, 제가 적극적으로 반영한 피드백은 크게 3개였습니다.
< 적극적으로 반영한 피드백 >
1. 스트림-람다 문법 사용해 보기
2. java.util.regex의 정규표현식을 사용해 보기
3. 다음 과제는 MVC 패턴으로 진행해 보기
하지만, 제가 받아들이지 못한 피드백도 있었습니다.
< 받아들이지 못한 피드백 >
1. 객체지향의 원칙과는 다소 거리가 먼 부분이 보인다.
= SOLID 원칙 중 어떤 원칙을 위반했는지 말씀하시지 않으셨습니다. 저는 간단한 계산기 과제의 복잡도를 올리지 않으면서도, 서로의 책임과 역할 구분을 명확히 하는 객체들과의 협력 세상을 구축했습니다. 비록 프로그램에 필요한 '메시지'가 몇 개 없어서 이것이 객체 지향 설계가 아니라 클래스(혹은 함수) 지향 설계로 보일 수 있습니다. 하지만, 이런 간극을 없애기 위해 추가적인 작업을 하는 것은 저에겐 좋은 설계가 아니라 틀에 맞추기 위한, 주어진 과제에 비해 복잡성을 너무 올리는 오버엔지니어링이라고 판단했습니다. 따라서 이 의견에는 수긍하지 못했습니다.
2. 출력은 OutputHandler가 담당하도록 하자.
= 1주차 과제는 단 한 번의 출력이 필요할 정도로 간단한 요구사항의 문제였습니다. 이 간단한 요구사항을 위해 출력 담당의 객체를 만드는 것도 오버엔지니어링이라고 판단했습니다. 역할과 책임을 명백히 하는 것도 물론 좋지만, 한 줄짜리 출력마저 빼는 것은 프로젝트 규모가 커져서 헷갈리기 시작할 때 유효하다고 생각합니다.
3. check() 메서드는 추상적이다.
= Validator의 check() 메서드는 파라미터로 넘어온 문자열의 검증을 맡는 함수입니다. 이 의견에 수긍하지 못한 이유는 check 메서드의 시그니처로 충분히 무슨 행동인지 파악할 수 있다고 판단했기 때문입니다. 예를 들어서 check()를 validateStringInput() 으로 구체화할 수 있지만, 메서드를 실제로 사용하는 부분에서는 validate.validateStringInput(String input, String customDelimiter) 이기 때문에 이것은 문맥의 중복이라고 생각했습니다. 따라서 validate.check(String input, String customDelimiter)의 시그니처로도 행동을 설명하는데 충분하다고 생각됩니다. 만약 구체적 예시를 제시하셨다면 저의 의견이 바뀌는 데에 도움이 됐을 것 같습니다! (저는 충분히 수용하려고 합니다)
4. StringParser가 문자열에서 구분자를 추출하는 것과, 문자열을 숫자 배열로 변환하는 두 가지 책임을 가지고 있다.
= 이 의견엔 완전히 수긍하지 못했습니다. 리뷰어분의 말씀처럼 만약 StringParser가 SRP 위반이라면 문자열을 구분자로 분리하는 클래스와, 문자열을 배열로 변환하는 클래스 이렇게 총 2개를 만들어야 한다는 뜻이 됩니다. 그러면 각 클래스마다 하나의 함수만 가지고 있어야 한다는 뜻이 됩니다. 따라서 리뷰어 분에게 추가적인 설명과 이해를 요청드렸습니다.
5. 상수는 따로 enum 파일로 관리하면 좋겠다.
= 물론 좋은 아이디어입니다만, 제가 학습해 본 enum은 약간은 복잡한 형식이었습니다. 사실 상수를 사용한 의미가 매직 넘버에 이름을 부여해서 가독성을 높이기 위해서였기 때문에 단순 상수 사용으로도 충분하다고 생각했습니다. enum은 나중에 적절한 상황이 올 때 사용할 예정입니다.
[ 2주차 시작 ]
2주차가 시작되었습니다. 2주차가 시작되고 나서 제일 먼저 한 것은 1주차때 피드백받은 스트림-람다 문법과 정규표현식을 배우는 것이었습니다. 정규표현식은 유튜브 생활코딩님의 정규표현식 강의 9개를 듣고 실제로 활용해 보면서 배웠고, 스트림-람다 문법은 관련 레퍼런스를 찾아보고 활용해 보며 배웠습니다.
여기서 정말 AI에게 도움을 많이 받은 게, GPT에게 정규표현식(그리고 스트림-람다)의 문제를 내라고 하고 완벽하게 다 맞출 때까지 계속 복습했습니다. 이렇게 한 3일 정도 반복적으로 복습하니까 정규표현식과 스트림-람다 문법도 꽤나 익숙해지게 되었습니다.
그리고 Java API에서 이미 제공하는 기능이 있으면 직접 구현하는 것보다 그 클래스를 사용하는 것이 훨씬 가독성이 좋고 여러모로 이득이기 때문에 Java API에 어떤 기능들이 내장되어 있는지 브리프 하게 학습하는 시간을 가졌습니다.
[ 자동차 경주 과제 ]
자동차 경주는 간단한 로직이지만, 객체지향 설계를 적용할만한 부분이 꽤 보이는 과제였습니다.
< 과제 설명 >
간단한 자동차 경주 게임을 구현하는 과제입니다.
사용자는 레이싱에 참여할 자동차 이름을 쉼표로 구분하여 여러 개 입력할 수 있습니다.
각 자동차는 전진하거나 멈출 수 있으며, 전진 여부는 0부터 9 사이의 무작위 값에 따라 결정됩니다.
값이 4 이상일 때 자동차는 전진합니다.
경기는 사용자가 지정한 N 라운드만큼 진행되며, 각 라운드에서 자동차는 한 번씩 이동 기회를 가집니다.
매 라운드 종료 시 경기 현황을 출력하고, 최종 라운드 종료 후 우승자 목록을 출력합니다.
< 해결 과정 >
객체 지향 설계와 MVC 패턴을 활용하여 과제를 해결해 볼 생각이었습니다.
"객체지향의 사실과 오해" 책에서 배운 What/Who 사이클 접근법으로 설계를 해봤습니다.
너무 구체적인 설계를 하면, 이전의 설계에 지나치게 의존하여 더 나은 방향을 찾지 못하는
역효과가 발생할 것 같아 추상적이라도 역할이 확실한 설계를 하도록 노력했습니다.
- 구현할 기능 목록
1. 자동차 이름과 시도할 횟수를 입력받는 기능
2. 입력 값이 올바른지 검증하는 기능
3. 무작위 값을 구한 후 4 이상인지 확인하는 기능
4. 무작위 값에 따라 차를 전진시키는 기능
5. 차의 이름과 현재 위치를 출력하는 기능
6. 우승자를 출력하는 기능
What(무엇이 필요한가)
1. 자동차가 필요하다
- 자동차는 이름과 위치를 필드로 가져야 한다.
2. 경주 게임이 필요하다
- 경주 게임은 자동차 목록이 필요하다.
- 시도할 횟수도 필요하다.
- 자동차를 규칙에 맞게 조작해야 한다.
- 게임 종료 시 우승자를 판단해야 한다.
3. 입력 처리가 필요하다
- 자동차 이름과 시도할 횟수를 입력받아야 한다.
4. 출력 처리가 필요하다
- 실시간 현황을 출력해야 한다.
- 최종 우승자를 출력해야 한다.
Who(누가 담당할 것인가)
Model/Car 클래스 (자동차 역할)
Controller/RacingGame 클래스 (경주 게임 역할)
View/InputHandler 클래스 (입력 처리 역할)
View/OutputHandler 클래스 (출력 처리 역할)
[ JUnit과 AssertJ ]
과제 요구사항으로 JUnit과 AssertJ를 활용해서 테스트 코드를 작성하는 것이 있었습니다.
테스트 코드를 작성하는 것도 처음이고, JUnit과 AssertJ라는 라이브러리를 사용하는 것도 처음이었습니다.
다행히 쉽게 설명된 레퍼런스가 많고, 사용법 자체도 많이 어렵지 않아서(특히 AssertJ는 상당히 직관적이었습니다) 테스트 코드 작성 자체는 수월했습니다.
하지만, 테스트 코드가 아니라 테스트하기 쉬운 설계를 만드는 것이 더 어렵다고 느꼈습니다..!
랜덤을 사용하는 함수를 테스트하는 것이 제일 구상하기 어려웠습니다. 결국엔 랜덤 함수를 큰 틀로 추상화한 다음 인터페이스를 만들어 구현하고, 구현된 랜덤 함수를 RandomMoveStrategy에서 DI 받아 활용하는 식으로 로직을 바꿨습니다.
[ 우테코 테코톡 ]
2주차 과정 중에서 새롭게 재미들린 것이 있다면, 매일 아침 샤워로 하루를 시작하면서 테코톡을 보는 것입니다. 뭔가 하루를 새로운 지식 혹은 기존 지식을 견고하게 하는 작업으로 시작하니까 기분이 좋았습니다.
다음은 2주차 과정 동안 본 테코톡 목록입니다:
- 웨지의 인텔리제이 디버깅
- 제리의 MVC 패턴
- 완태의 전략패턴
- 아루의 객체지향과 추상화 수준
- 웨지의 OOP
- 라테의 도메인 주도 설계
- 클로버의 SOLID
- 피카의 TTD와 단위테스트
- 로빈의 의존성 주입
- 도도의 좋은 단위 테스트란
- 해리&션의 MVC 패턴
또, 이번 과제의 공통 피드백 사항에 있던 디버깅 툴을 활용하라를 지키기 위해 디버깅 툴 사용법을 학습했습니다.
그런데, 무언가 익숙하지 않더라고요.. 한번 디버깅할 상황이 와서 직접 사용해 봐야 적응이 될 것 같습니다.
[ 끝없는 고민들 ]
사실 이번 과제는 공부 시간이 적었습니다. 과제의 요구 사항인 테스트 코드와, 제가 적용하기로 한 MVC 패턴에 대해 학습하는 것이 한 이틀 걸렸을까요. 나머지 시간은 모두 객체지향 설계와 그에 관련된 고민 그리고 회고로 꽉 찼습니다.
이번 과제를 진행하면서 정말로 고민되는 부분이 많았고.. 결국에 리팩토링을 계속하다가 이건 정해진 답이 없거나, 현재 내 수준에서 피드백 없이는 알기 힘들 것이라고 생각해서 코드 리뷰만 기다렸습니다.
코드 리뷰어분들이 제가 고민하는 부분을 콕 집어줄 수 있을 것 같아 README.md에 제가 고민했던 이야기들을 썼습니다.
< 고민 사항 >
1. Application.main()의 코드는 모두 Controller로 이동해야 할까?
= Application은 객체 생성과 협력을 조율하며, 전체적인 흐름을 담당합니다. 그러나 모든 과정이 레이싱 게임을 위해 설계된 만큼, 이것을 RacingGameController의 역할로 봐야 하는지 고민입니다. 만약 초기화를 Controller에서 담당한다면, Controller에서 View와 Model을 의존성 주입 없이 직접 생성해야 할 수밖에 없는 상황입니다.
2. racingGame.getCars() 메서드가 정보 은닉과 캡슐화를 저해하는가?
= RacingGameController는 View에게 경기 현황 출력을 요청합니다(outputView.printStatus()). 이때 getCars() 메서드를 통해 자동차 객체의 리스트를 넘기는데, 실제 필요한 정보는 자동차의 이름과 위치뿐입니다. getCars() 메서드가 자동차 객체 전체를 넘김으로써 불필요하게 .move() 등의 메서드도 노출되는 것이 문제가 될까요? 만약 그렇다면, CarStatus같은 새로운 모델을 생성하고 필요한 데이터만 매핑해서 전달하는 것이 더 나을까요? 이런 것들이 오버엔지니어링은 아닐지 고민입니다.
3. RacingGameController가 레이싱 게임 로직에 너무 깊이 관여하고 있는가?
= acingGameController의 startGame() 메서드는 RacingGame 모델에 게임 시작을 요청하는 대신, 한 라운드만 진행하는 .playOneRound()와 남은 라운드를 확인하는 .hasNextRound()를 호출하며 게임을 직접 조작합니다. 이렇게 하면 비즈니스 로직이 Controller에 포함되는 것일까요? 아니면 모델의 메서드를 적절히 활용한 흐름 제어라고 볼 수 있을까요?
4. MyTest의 자동차_현황_출력_테스트()는 유닛 테스트가 아니라 통합 테스트인가?
= 자동차_현황_출력_테스트()는 출력 기능만 테스트하는 것이 아니라, 자동차를 생성하고 모의 전략을 주입한 뒤, 각 차의 move() 메서드를 호출해서 모의 자동차 데이터를 만듭니다. 이것은 모의 자동차 정보를 생성하기 위한 일련의 과정이지만 이 과정에서부터 오류가 있다면 출력에 문제가 없더라도 오류가 나게 됩니다. 즉 출력 함수만 테스트 하는것이 아니라 일련의 과정을 테스트합니다. 그러면 이건 유닛 테스트가 아니라 통합 테스트라고 볼 수 있을까요? 그리고, 어차피 모의 자동차를 준비하는 일련의 과정에서 문제가 생길 예정이었다면 이전 테스트에서부터 오류가 났을 텐데, 이게 문제가 될까요? 아니면 출력 테스트를 준비하기 위한 과정이라고 볼 수 있을까요?
[ 회고 ]
2주차 과정에서 요구했던 회고가 있습니다.
< 우아한 테크코스에서 요구했던 회고 >
- 지원서에 작성한 목표를 얼마나 달성하고 있다고 생각하나요? 그 이유는 무엇인가요?
- 지원서에 작성한 목표를 변경해야 한다고 생각하시나요? 그렇다면 그 이유와 어떤 목표로 변경하고 싶으신가요?
- 프리코스를 진행하면서 눈에 띄는 변화나 깨달은 점이 있나요?
저는 정말 진심을 담아서 회고했습니다. 처음에는 사실 누군가가 보는 회고이기에 어느 정도 의식해서 존댓말로 작성했는데, 도저히 존댓말로 작성하니까 정말 진실한 저와의 대화가 안 되더라고요. 그래서 반말로 작성하고 글에서 양해를 구했습니다.
소감문에 제출한 회고가 저의 경험을 이해하는 데에 블로그 글보다 도움이 될 것이라고 생각하고 회고를 첨부하는 것으로 글을 마치겠습니다.
< 소감 및 회고 >
- 배운 점 -
1. MVC 패턴과 전략 패턴에 대해 학습하고 적용했습니다.
2. JUnit과 AssertJ를 통해 단위 테스트를 작성하는 방법을 학습했습니다.
3. 계속 변하는 값을 사용하는 함수를 테스트 하기 위해 모의 객체라는 개념을 학습했습니다.
4. 1주 차 때 피드백 받은 람다-스트림과 정규표현식을 학습하고 적극적으로 적용했습니다.
- 느낀 점 -
1. 유닛 테스트 코드를 작성하면, 나중에 로직을 변경하더라도 테스트 코드로 의도한 동작이 여전히 수행되는지 편하게 확인할 수 있다는 것이 큰 장점임을 느꼈습니다.
2. JUnit에 대해 학습하다 TDD라는 개발 방법론에 대해 알게 되었습니다. 비록 이번 과제에서는 TDD를 적용하진 않았지만, 유닛 테스트를 작성하려는 노력 자체가 코드의 구조와 설계를 자연스럽게 개선한다는 것을 느꼈습니다. 다음 과제는 가능하다면 TDD를 학습하고 적용해보고 싶다는 생각을 했습니다.
3. 프로그램을 단순히 객체 지향 / 절차 지향이다 라고 이분법적으로 분류하던 1주차의 제가 부끄러울 정도로 객체 지향 설계에 대해 많은 부분을 고민하며 깨달았습니다. 이러한 과정에서 제가 정말 빠른 속도로 성장하고 있다고 느꼈습니다.
- 많은 시간을 투자한 부분 -
1. 처음에는 MVC 패턴의 패키지 구조가 Model, View, Controller 3개로 이루어져야 한다고 착각했고 그대로 개발을 진행했습니다, 이것을 깨닫고 MVC 패턴의 본질을 이해하는데에 오랜 시간이 걸렸습니다.
2. 단위 테스트를 랜덤 값을 사용하는 함수에 적용하는 방법에 대해 고민하는 과정에서 시간이 많이 소요되었습니다.
아래는 2주차에서 요구했던 회고에 대한 결과입니다. 회고 특성상 존댓말이 어색해 평어체를 사용했습니다. 이해 부탁드립니다.
< 회고 >
지원서에 작성했던 프리코스에서의 목표는 자기주도적 학습의 방향을 점검하고, 다양한 사람들과 소통하며 피드백을 통해 성장하는 것이었다. 즉, 개발 역량과 주도적 학습 능력을 키우는 것이었다.
지원서에 작성했던 목표를 다시 생각해보자면 상당 부분 달성하고 있는 것 같다. 일단 분명히 나는 빠른 속도로 성장하고 있다. 2주의 시간 동안 너무 많아 여기서 다 열거할 수 없을 만큼 많은 것들을 배웠다. 또 내가 학습한 것 중에 상당수는 우아한테크코스에서 제시해 준 것이지만, 몇 개는 1주차의 코드 리뷰에서 받은 피드백 덕분이다. 예를 들어서 스트림-람다 문법에 대해서, 그리고 정규표현식을 사용할 생각은 리뷰어분의 피드백 덕분에 학습하게 되었다. 개발 역량은 분명히 빠르게 늘고 있으며 피드백을 통한 성장도 하고 있으니 개발 역량을 키우자는 목표는 잘 달성하고 있다고 생각한다.
남은 것은 자기주도적 학습 능력을 키우는 것이다. 지금 다시 생각해보자면 자기주도적 학습 능력을 키운다는 것은 너무 추상화된 메시지다. 자기주도적 학습 능력이라는 게 무엇일까? 딴짓 안 하고 책상 앞에 오래 앉아 있는 능력을 말하는 것은 아닐 것이다. 나는 지원서 작성 당시 자기주도적 학습 능력을 "홀로 학습 방향을 정하고 나아가는 힘" 으로 속으로 규정하며 말했던 것 같다. 2주 만에 "홀로 학습 방향을 정하고 나아가는 힘" 을 기르는 목표를 달성했다고 말할 수 있냐고 묻는다면 쉽지 않을 것 같다. 나의 자기주도적 학습 능력을 측정할 수 있는 객관적인 지표도 없기 때문이다. 그렇지만 앞으로 나의 자기주도적 학습 능력을 올려줄 수 있는 무언가를 깨달았다고 말하고 싶다.
지금부터 하는 이야기는 프리코스 2주차 과정에서, 특히 설계와 관련한 부분에 대해 깊게 고민하다가 깨달은 것이다. 우아한테크코스는 1주 차에서부터 프리코스 커뮤니티에서 현재 진행 중인 과제에 대한 기술적인 이야기를 금지했다. 사실 과제를 해결하는 데에 일주일이라는 시간을 주고 그 일주일이라는 시간 속에서 도움이 될 만한 레퍼런스를 던져주는 건 오히려 우아한테크코스다. 찾아볼 수 있는 걸 다 찾아볼 자유를 주면서 왜 프리코스 커뮤니티에서 직접적인 이야기는 금지할까? 그 이유를 내가 깨달은 과정을 잘 설명하기 위해 조금 자세한 배경을 이야기해 보겠다.
나는 2주차 자동차경주 게임 과제에서 1주차 때 익히 들었던 MVC 패턴을 설계에 적용해 봤다. 그러다가 의문점이 생겼는데, 많은 레퍼런스에서 비즈니스 로직은 오직 모델에만 포함되어야 한다고 하지만 아무리 해도 컨트롤러에서 비즈니스 로직을 뺄 수가 없었다. GameController는 게임의 전체적인 상황을 관리하면서, 게임이 끝났을 때 우승자를 색출하는 메서드가 있었다. 근데 여기서 우승자를 색출하는 메서드는 비즈니스 로직 아닌가? 그래서 많은 의문을 남기며 레퍼런스들을 찾아다녔지만, 명쾌한 대답은 어디서도 돌아오지 않았다.
해결법을 찾을 수 없어서 끙끙 앓은 지 몇 시간이나 되었을까. 어쩌다가 생각을 정리하기 위해 노트에 떠오르는 모든 것들을 적기 시작했다. 먼저 객체 지향에 대한 생각과 내가 지금까지 이해한 객체 지향에 대해 적었다. 그러고는 이런 생각들을 토대로 어떻게 설계하려고 했는지 적으며 현재 의문이 드는 부분과 그 이유를 적어 갔다. 이렇게 지금까지 했던 많은 고민들을 수 없이 써 내려가다 보니 생각이 정리되었고 어느새 해결책과 가까워지고 있었다. 먼저 GameController는 게임에 필요한 데이터인 자동차 목록과 라운드 수를 가지고 있었다. 그리고 게임이 끝났을 때 우승자를 색출하기 위한 메서드도 있었다. 그렇다, 이건 GameController가 아니라 GameModel에 가까웠다. MVC의 본질은 계층을 나눠서 관심사를 분리하고 서로에게 미치는 영향을 최소화하려는 것인데 GameController는 게임에 필요한 정보를 가지고 있으면서 View와 Car를 연결하며 중개했다. 이것이 문제였다. 수많은 레퍼런스에서 비즈니스 로직은 모델에만 있어야 한다고 한 건, 모델은 비즈니스 로직에 필요한 데이터가 모여져 있고 자신의 데이터는 자신이 책임지고 행동하는 것이 바로 객체지향의 본질이기 때문에 당연하게도 비즈니스 로직은 모델에밖에 있을 수 없다. 결국에 나는 지금까지 작성한 GameController는 완전히 잘못됐다는 것을 깨닫고 GameModel과 GameController로 분리하는 것이 맞다고 판단했다.
여기서 중요한 것은 아무리 찾아봐도 해결책이 안 나오는 상황을 풀어낸 방법이다. 나는 아무리 찾아봐도 해결책을 찾지 못했지만, 내가 알고 있는 객체지향에 대한 지식들과 그것을 반영해서 설계한 방법을 쭉 정리하고, 여기서 어떤 의문점을 가졌는지 쭉 내려 적자 근본적인 문제의 실마리가 나왔다. 되돌아보자면, 사실 나는 문제를 해결하기 위해 많은 것을 찾아봤지만 많은 것을 고민하진 않았던 것 같다.
우아한테크코스의 입학설명회에서 익히 들은 말이 있다. 바로 "메타인지"에 대해서다. 메타인지는 요약하자면 높은 차원에서 상황을 바라보는 능력을 말한다. 나는 이전의 문제들을 해결하기 위해서 너무 일차원적인 인지를 해왔었다. 문제를 해결하는 방법을 찾아보고 이것으로 해결이 안 됐다면 바로 차원을 높인 인지를 해야 했다. 즉, "내가 왜 이런 설계를 했고 여기서 어떤 문제를 겪었고 해결 못 하는 이유는 무엇인가"라고 고민해야 진실한 성장을 할 수 있었다. 만약 내가 이전으로 돌아가서 문제를 고민하는데, 누군가가 "당신이 작성한 코드는 컨트롤러가 아니고, 모델과 컨트롤러를 합쳐놓은 겁니다~" 했다면 비록 당장의 문제는 해결할 수 있더라도 금방 새로운 문제에 봉착하고 갇히기 마련일 것이다.
하지만 더 높은 차원의 고민 과정으로 사고하자, 문제 해결과 지식 이외에도 하나를 더 얻었다. 바로 우아한테크코스에서 그렇게 말하는 메타인지가 얼마나 문제를 효율적으로 해결하게 해주는지에 대해서 실감했다는 것이다. 혼자서 문제를 고민하는 것은 어렵지만 그 돌고 도는 의문들과 고찰에 갇혀 있다 보면 언젠가는 단순히 찾아보는 것에서 벗어나 한 단계 높은 차원에서 상황을 바라보는 과정을 거치게 되고, 그것으로 문제를 해결하게 된다면 "메타인지" 라는 것을 얻게 된다. 이것이 우아한테크코스에서 말하는 고민에 따른 성장 기회 같다.
정리하자면 나의 고민 없이 누군가가 해답을 알려주는 것은 당장의 문제를 해결하지만 내가 문제를 해결하는 방식을 키우진 못한다는 것을 깨달았다. 이번에 객체지향의 본질을 겉으로만 이해한 상태에서 MVC 패턴을 보고 적용하다가 문제를 겪었다. 이런 것들을 막으려면 내가 부족한 점을 잘 인지하고 지금 학습해야 하는 것이 무엇인지 파악하면서 공부를 이어 나가야 한다. 이런 점에서 봤을 때 메타인지는 결국에 효율적으로 문제를 해결하는 수단이기도 하지만, 궁극적으로는 학습 과정에서 문제에 봉착했다면 내가 어떤 것이 부족하기에 이런 문제를 겪고 있고 그것을 위해 무엇을 해야 할지 방향을 정할 수 있게 된다. 단순히 현재의 문제를 해결하는 것에서 더 나아가서 다음에는 이러한 문제점에 봉착하지 않을 정도로 기반을 견고하게 만들어준다.
나는 프리코스에서 정말 중요한 것을 깨달았다. 만약 누군가가 내가 높은 차원의 고민에 도달해서 이런 것을 깨닫기 이전에 정답을 알려준다면 너무나도 비극일 것 같다. 이번 2주차에서 느꼈던 메타인지의 힘을 계속 되새기며, 앞으로 문제를 겪을 때마다 더 높은 차원에서 문제에 대해 고민할 수 있을 것 같다. 이것은 결국에 장기적으로 내가 앞으로 자기주도적 학습을 "잘" 할 수 있는 힘을 길러줄 것이라고 확신한다.
이렇게 프리코스를 진행하며 매번 정말 많은 것을 배우고 깨닫는 중이다. 진실한 학습의 경험은 나를 정말 크게 성장시켜준다고 생각한다. 프리코스 기간 동안 컴퓨터 앞에 앉아 하루를 시작하고 일어나면서 하루를 끝내는 나, 쉬는 중에도 객체지향을 찾아볼 정도로, 진심으로 몰입한 나를 발견할 수 있었다. 앞으로 또 어떤 새로운 배움과 깨달음이 있을지 기대된다. 이것으로 회고를 마친다.
'우아한테크코스' 카테고리의 다른 글
[우아한테크코스 7기] 최종 합격 (0) | 2025.01.01 |
---|---|
[우아한테크코스 7기] 1차 합격 및 최종 테스트 회고 (3) | 2024.12.19 |
[우아한테크코스 7기] 프리코스 4주차 및 종료 회고록 (1) | 2024.11.16 |
[우아한테크코스 7기] 프리코스 3주차 회고록 (1) | 2024.11.06 |
[우아한테크코스 7기] 프리코스 1주차 회고록 (0) | 2024.10.21 |