사실 책 스터디를 반년 동안 지속하기란 쉽지 않다. 그럼에도 다들 꾸준히 하는 이유는 이 책을 가장 잘 이해하고 넘어갈 수 있는 스터디 그룹이라는 자부심이 있어서라 생각한다. 사실 책 스터디 그룹도 엄청 많고, 책 스터디의 방법론 또한 엄청 많다. 이번 글은 가볍게 현재 우리 스터디가 책 한권을 잡고 진행을 어떻게 하고 있는지에 관해 소개하려 한다.
사실 이전에 발표를 했었는데 이 내용을 글로 옮긴다 날로먹는다 할 수 있는데 그래도 나름 글쓰는데 오래 걸렸다ㅠㅠ
https://www.slideshare.net/ssuser8fdee2/200531-jandi
사실 나는 개발자는 책을 많이 읽어야 한다는 말을 잘 몰랐다. 기존에는 그냥 "문제가 생기면 구글링을 해서 찾아야지"라는 생각이었다. 하지만 이 말은 매우 위험하다. 애초에 무엇을 모르는지 모르는 상황에서 모르는 게 있으면 찾아본다는 점 자체가 문제가 있다. 요즘에는 개발자가 책을 읽는 이유를 말하라 하면 기존에 사용하던 기술을 좀 더 올바르게 사용할 수 있어서, 모르는 부분에 대한 키워드는 새롭게 알아볼 수 있는 트리거가 되어서라는 이유로 대답할 것이다.
이렇게 기존에 책에 대해 회의적이었던 태도가 바뀌게된 이유는 이펙티브 자바를 읽으면서였다. 그동안 아무 생각없이 언어의 특성을 이해하지 못하고 코딩을 하고 있었구나 라는 점을 깨달았기 때문이다. 정말 가볍게는 primitive와 wrapper 타입에 대해 뚜렷한 기준을 세우고 사용하지 않았었으며, 좀 더 하드 하게는 직렬화에 자체를 잘 몰랐던 것이 기억이 난다.
우리 스터디가 이펙티브 자바를 읽으면서 지향한 것은 "한 문장이라도 모르는 것을 대충 넘어가지 말자" 이런 지향점을 설정을 하니 정말 코드 한 단락 가지고도 1시간 동안 토론을 하는 등 책을 공격적으로 읽을 수 있었다. 이를 위해 우리 스터디는 두 가지를 이용한다. github 레포지토리와 팀블로그 를 이용한다
1. 스터디 사이클
자바봄 스터디는 일주일 단위로 사이클을 돌면서 이루어진다. 매주 토요일 모여서 책을 읽은 내용을 약 1~2시간 토론하는 시간을 가진다. 이때 주된 토론의 내용은, 책을 읽으면서 모르는 점에 대한 답변으로 이루어진다. 따라서 모든 스터디원이 책을 읽고 해당 분량에 대한 내용을 이해했다는 것을 전제로 한다. 이 전제를 바탕으로 모르는 내용에 대한 답변은 해당 주에 책을 리딩하는 사람이 책임지고 해야 한다. 혹시 못하더라도 같이 이야기하면서 답을 찾는다.
이 방식으로 했을 때 생각보다 양질의 질문이 나오고, 한번더 책의 내용을 음성로 전달하는 효과가 있어 기억에 오래 남는다. 그리고 스터디 당일이 끝나면, 리딩 하는 사람은 토론 내용을 다시 텍스트로 정리해야 하며, 이 사이클이 마치면 책 리딩이 다른 사람에게 넘어간다.
2. github 레포지토리 - issue 활용
issue의 기능은 간단하다 모르는 내용을 질문하는 게시판이다. 스터디 사이클에서 질문 & 답변에 해당하는 부분으로 이 부분이 핵심이다. 이펙티브자바를 읽으면서 궁금한 내용을 "한 문장이라도 모르는 것을 대충 넘어가지 말자"라는 목표로 열심히 질문과 답변을 이어간다. 이펙티드 자바를 읽으면서 애매한 부분에 대한 정리는 대부분 이 레포지토리에 정리가 되어있으며, 링크는 아래와 같다.
https://github.com/Java-Bom/ReadingRecord/issues
스터디 당일인 토요일 전까지 스터디원들은 책을 읽고 좀 더 세세하게 알고 싶은 내용이 있다면 github issue를 활용하여 질문을 남긴다. 해당 질문 내용을 그 주에 책을 리당하는 사람이 책임지고 답변을 달아둔다. 이때 주로 언급되는 내용은 아래와 같다.
- 처음 보는 용어에 대한 설명 요구
- 글로만 적혀있는 기술에 대한 사용법 요구
- 예제 코드에 대한 설명
- 문단 문맥 이해
- 코드에 대한 분석 요구 ( 주로 JDK 구현 방식에 대한 상세 설명)
- 관련 기술 사용 예제 요구
초반에는 용어 및 코드에 대한 설명이 우선이었다면, 요즘에는 텍스트로 적혀져있는 내용에 대한 직관적 이해를 위한 예제 코드를 작성해달라는 요구가 우세하다. 또한 실무에서 어떻게 사용할지까지 추가해서 생각한다.
문제를 해결하는 방법은 여러 가지가 있으나 크게 4가지로 나뉜다.
- 구글링을 통한 기술 블로그 참고
- 공식 java doc 활용
- 실제로 코드를 작성하여 해결
- JDK 내부 구현을 확인하여 해결
지금부터 아래 3가지 예시를 보면서 이렇게 공부하는 사람들도 있구나하고 넘기면 된다.
A. 간단한 Q&A 예시
정말 간단한 예시를 들자면 아래와 같다. 아래와 같은 질문이 들어오면 스터디 전까지 리딩하는 사람은 대답을 해야 한다. 위 유형중 다음 질문은 "글로만 적혀있는 기술에 대한 사용법 요구"에 해당한다 볼 수 있을 것 같다.
따라서 위 방법중 질문에 대해 적합한 방법을 골라 해결한다.
위 질문의 경우에는 공식문서를 찾아본 후에 실제로 코드를 작성하여 확인하는 방식으로 답변을 주었다.
B. 책의 내용을 넘어서는 예제 코드 작성하기
사실 여기까지 들으면 이거 다 할 수 있는거 아니야?라고 생각할 수 있다. 근데 진짜 묘미는 생각지도 못한 코드 짜기에 있다.
위와 같은 질문은 정말 세세하게 책을 읽어야 가능하다. 사실 위 문장은 그냥 그렇구나 하고 넘어갈 수 있는 부분이다 (내가 그랬다.) 근데 확실히 해당 공격을 직접 작성하면서 확인을 하면 여기에 있는 TOCTOU 공격에 대한 이해 뿐만아니라 멀티스레딩 환경에서의 검증을 위한 테스트 코드 작성 스킬 향상이라는 효과도 함께 따라온다.
@Getter
public class Period {
private Date start;
private Date end;
public Period(Date start, Date end, CountDownLatch latch, CountDownLatch latch2){
// start가 end보다 나중일때 exception
if (start.after(end))
throw new IllegalArgumentException(start + "가" + end + "보다 늦다");
latch2.countDown();
try {
latch.await(); // 다른 쓰레드에서 공격이 끝날 때까지 걸려있어야 한다.
} catch (InterruptedException e) {
e.printStackTrace();
}
this.start = new Date(start.getTime());
this.end = new Date(end.getTime());
}
@Override
public String toString() {
return "Period{" +
"start=" + start +
", end=" + end +
'}';
}
}
class PeriodTest {
static Period period = null;
@Test
@DisplayName("유효성 검사를 먼저 할 때")
void checkingValid() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
CountDownLatch latch3 = new CountDownLatch(1);
Date start = new Date();
start.setTime(1000);
Date end = new Date();
start.setTime(10000);
new Thread(() -> {
period = new Period(start, end, latch, latch2);
System.out.println("maker : " + period);
latch3.countDown();
}).start();
latch2.await(); // 검증이 끝날 때까지 걸려있어야 한다.
end.setTime(100);
latch.countDown();
latch3.await(); // 생성이 끝날 때까지 걸려있어야 한다.
// start가 end보다 나중이다.
assertThat(period.getStart().after(period.getEnd())).isTrue();
}
}
사실 이 코드는, 당일 토론시간을 이용해 스터디 원들의 도움을 받아 작성하였다. 원래 코드는 Thread.sleep()을 사용해서 시간에 의존적인 테스트를 작성하여 검증했었는데, 위와 같이 멀티 스레딩 환경의 테스트의 경우에는 CountDownLatch를 활용하여 작성해야 함을 다 같이 짚어보고 넘어간 순간이었다.
C. 확장하여 관련 개념 공유하기
가끔 리딩하는 사람이 아니어도 해당 이슈에 대하여 관련된 내용을 오프라인으로 전달하며 개념을 확장해서 이야기할 때도 있다. 그 예시로는 아래 상황이었는데
병렬 스트림에 관한 이야기였다. 답변자 내용을 보면 이펙티브 자바의 내용을 이해하기 위해 모던 자바 인 액션이라는 다른 책을 참고했음을 알 수 있는데, 이런 적극적인 문제 해결이 가능하다는 점에 놀라웠다.
뿐만 아니라 당일에는, 이 splitator에 관해 더 열심히 알아봤다는 스터디원이 있어 자신이 알아본 내용을 오프라인에서 설명한 후 우리 블로그에 다시 정리해서 올렸다. https://javabom.tistory.com/59
해당 문제에 대해서만 답변을 다는 것이 아니라 추가적으로 확장해서 해당 개념을 알고 넘어갈 수 있었다. 또한 이 병렬 스트림은 ForkJoinPool과도 연결이 되어있는 개념이었는데, 당일에 ForkJoinPool에 대한 내용을 마찬가지로 확장해서 설명한 후 넘어가기도 했었다.
결론적으로 책을 읽고 모르는 내용을 공유하고, 내가 아는 내용도 공유하는 것이 우리 스터디 토론시간의 특별한 점이었다. 사실 500 페이지의 책을 반년 동안이나 읽고 있다는 점에 다들 의아할 수 있는데, 문제 하나라도 깊게 보려는 지향점이 있었기 때문에 가능한 일이었다.
3. 블로그 활용
스터디가 끝나고나면, 토론한 내용을 바탕으로 크게 3가지 작업이 이루어진다.
- issue를 정리해서 close 한다.
- 팀블로그에 토론 내용을 반영하여 이펙티브 자바 정리 글을 작성한다.
- 위에서 말한 병렬 스트림 사례처럼, 새로운 파생 글을 만들어 공유한다.
그래서 실제 지금까지 이펙티브 자바를 읽으면서 정리한 내용은 모두 이 블로그에 있다. 아직 조금 더 채워 넣어야 하지만
이 글은 모든 책 스터디가 반드시 이래야 한다는 점을 시사하지 않는다. 사실 우리 책 스터디가 이렇게 지속될 수 있었던 이유는 3가지 조건이 충족되었기 때문이다.
- Java를 좋아하는 사람이 모였다는 점
- 모두 0년 차 혹은 1년 차로 이 책을 읽으면서 얻고 싶은 점이 동일했다는 점
- 책을 읽는 속도에 모두가 동의했다는 점
사실 한 가지만 만족이 되지 않았더라도 한 명이 이탈했을 가능성이 매우 크다. 그래서 이 글을 읽는 사람들에게 자신의 상황에 맞게 책 스터디를 꾸려보라는 이야기를 하고 싶다.
N연차 직장인이라서 시간 효율적으로 공부해야 하기 때문에 각자 스터디 시간에 모여서 책을 읽고, 정기적으로(달에 한 번씩) 회고하는 시간을 갖는 방식, 한 사람이 읽은 내용을 정리하고 다른 사람들에게 공유하는 방식, 지정한 날까지 각자 알아서 읽는 스터디 등등 방법은 다양하다.
모든 책 스터디의 공통점은 같이하는 사람들의 특성을 파악하고 모두의 니즈를 파악해야 오래갈 수 있다는 것이다.
결론은 이것이다. 당신의 책 스터디가 이펙티브 자바를 읽고 있다면 혹은 혼자 이펙티브 자바를 읽는데 지루하다면 우리 자바봄 레포지토리와 블로그를 애용해 주었으면 한다. 책을 읽다가 모르는 내용을 issue에서 찾아보았을 때 못하게 같은 고민을 했던 사람들을 찾아볼 수 있을 것이다.
만약 고민하는 내용이 있다면 issue를 남겨라! 다들 궁금한걸 못 참아하는 성격이라 한번 열심히 해결해 보겠다!! 😉😉😉
https://github.com/Java-Bom/ReadingRecord/issues
김민정 - JavaBom | Backend 개발자 github : https://github.com/mjung1798 linkedin : https://www.linkedin.com/in/minjeong-kim-268796164/ blog : https://jyami.tistory.com/ |
'스터디' 카테고리의 다른 글
SI 기업 1년차에 서비스기업 이직 성공했습니다. (35) | 2020.06.06 |
---|