레벨1 레벨 인터뷰 및 피드백
레벨1 레벨 인터뷰
📜 제목으로 보기
레벨 인터뷰 관련
-
레벨로그를 작성해서 공유하여 레벨 1학습한 것을 정리
-
메타인지: 자신이 아는지 모르는지 성찰하는 능력, 자신의 생각에 대해 생각하는 능력
-
6명: 1인터뷰이 -> 3인터뷰어(질문자) + 2옵져버(피드백 기록-어떤점이 부족하고 어떤점을 보완했으면 좋겠다.)
- 명당 30분(인터뷰 20분 + 피드백 10분)
- 내가 인터뷰어일 때, 해당하는 인터뷰이의 레벨로그를 읽어보고 참석해야한다
- 내가 옵져버일 때, 말하기 역량에 대한 피드백을 준비한다.
-
레벨 2 시작하고 수, 목 14시~17시
- 코치들이 난이도 있는 질문을 추가적으로 한다.
준비
레벨 로그
TDD
- test 파일부터 만들어서 개발을 시작한다. 메서드명은 한글로 사용해도 상관 없으며 단위테스트가 의미하는 바를 잘 나타내야한다.
- 테스트시 코드를 작성할 때 당장 존재하지 않는 클래스, 메서드를 사용해서 작성한 뒤,
red(error)
를 발생시킨다.- red를 제거하여
green(pass)
이 되는 방향으로 프로덕션 코드를 작성한다. - pass된 프로덕션 코드를 바탕으로 기존 프로덕션 코드를
refactoring
한다. - 더이상 refactoring할 것이 없다면 새로운 단위테스트를 만들어서 이어나간다.
- 요약하면
fail하는 test
->pass하도록 빠르게 production 수정
->refactoring
- red를 제거하여
- 할 수 있다면 주석으로
//given //when //then
3단계로 나누어서 테스트코드를 작성하여 예상값과 실제값을 비교한다. - 직전과 비슷한 test case를 작성한다면 코드를 복사하여 붙여넣기를 활용하면 좋다.
테스트 하기 힘든 것을 전략패턴으로
- 자동차 미션의
랜덤한 값에 따라 자동차가 움직임
, 로또 미션의자동 로또를 랜덤하게 생성함
, 블랙잭 미션의랜덤한 카드덱을 매번 생성
, 체스 미션의매번 DB에 연결하는 Dao
- 각 미션마다 테스트하기 힘든 부분을 어느 추상체에 대한 구현체 중 1개로 보고 해당코드를 추상화한다. 이 때, 추상화된 인터페이스를 파라미터에서 받아 외부에서 주입받도록 한다면
전략패턴
이 되는 것이다. 이제 테스트 하기 힘든 구현체와 같은 레벨의 테스트 하기 쉬운 구현체를 작성하여 Test코드에서 외부에서 주입할 수 있다.
상속, 추상클래스, 조합
-
상속
은 같은 레벨의 클래스들이 중복된 코드를 가질 때 고려해볼 수 있다.- 공통된 메서드나 필드가 발견되면 그것들을 모아놓은 부모클래스를 생성하고 그 메서드나 필드를 받아 쓸 자식클래스들은 해당 클래스를 상속한다.
- 이후 공통적이지 않은 메서드들에 대해서는 구현부는 다를지언정 메서드명을 추상화할 수 있는지 고려해보아야한다.
- 자식클래스들에 대해 서로 다른 구현부를 가진 메서드에 대해서 메서드명이 추상화가 된다면, 추상화된 메서드명으로 abstract method를 정의해주자. intellij가 알아서
abstract class
로 변경하라고 메세지를 보내준다. - 메서드명의 추상화 성공시, 또다른 중복코드가 발생할 수 있는데 다시 abstract class로 공통 부분들을 올려주면 된다.
- 자식클래스들에 대해 서로 다른 구현부를 가진 메서드에 대해서 메서드명이 추상화가 된다면, 추상화된 메서드명으로 abstract method를 정의해주자. intellij가 알아서
-
조합
은 공통되는 코드를 부모클래스를 생성하여 올리는 것이 아니라, 따로 클래스로 추출한 뒤, 기존 클래스의 생성자호출시 주입하여 상태값(필드)로 가지고 있게 된다. 코드중복을 상태값으로 간 객체의 메서드호출로 해결할 수 있다.- 상속의 단점이자 조합의 장점
- 기존 클래스의 변화에 영향이 적어지며, 안전하다.
- 메서드를 호출하는 방식으로 동작하기 때문에 캡슐화를 깨뜨리지 않는다.
- 조합대신 상속을 고려해볼만 할 때
- 확장을 고려했는데도 설계한 확실한 is - a 관계(부모가 변할일이 없을 때)
- 상속의 단점이자 조합의 장점
대본
TDD
-
정의: 켄트 백에 의해 창시된 TDD는, 기존의 [ 설계-> 개발-> 테스트 ]의 과정과 다르게, [설계 -> 테스트 -> 개발]의 과정으로 진행되며, 테스트 자체도 red->green->refactoring 3가지 cycle로 돌아갑니다. 1) red로 테스트를 작성하고 2) green으로 기능을 완성하되 빠르게 완성시킵니다. 3) 다음 case로 넘어가기 전에 refactoring을 실시합니다.
-
장점: 마음에 안정감이 생기면서, 디버깅 시간을 줄이면서, 그 자체로 명세 역할을 할 수 있습니다. 1) 안정감이 생기는 이유는, 자연스럽게 작은 단위를 테스트하도록 작성하므로, 단일책임원칙을 지키면서 코딩할 수 있었습니다. 하지만, TDD에 실패하는 대부분의 이유가 추상체가 아닌 구현체를 테스트하는 경우임을 인식해야합니다. 인터페이스를 테스트해서 무엇보다도, 초록색불을 보면 안정감이 생겼습니다. 2) 디버깅 시간을 줄인다는 의미는 프로덕션 코드 이전에 설계 후 테스트가 이어지기 때문에, 테스트과정에서 설계가 바뀐다면 빠르게 설계를 수정할 수 있습니다. 처음에는 오히려 시간이 많이 걸릴지도 모르지만, 엎어지는 설계를 하는 과정에서도 도메인 지식이 쌓이게 되어 장기적으로는 빠르게 코드를 완성할 수 있습니다. 3) 자체로서 명세역할을 한다는 의미는, 팀원이 TDD의 과정으로 개발된 프로젝트는 테스트 코드만 봐도, 로직을 이해할 수 있게 되기 때문입니다.
상속
같은 레벨의 클래스들이 중복코드를 가져서 코드중복 제거을 위해 고려해볼 수 있다.
상속의 예시: 체스판 위의 기물들, 예를 들면 킹,퀸,룩,비숍,나이트,폰 등을 표현하고자 할 때, 각 기물들은 구현하다보면, move라는 공통 기능을 발견하게 됩니다. 이 때, 각 기물들을 자식클래스라고 생각하고 Piece라는 부모클래스를 만들어서 공통기능을 위임하고 코드 중복을 제거할 수 있습니다.
하지만, 상속에서 자식은 이미 부모가 불변할 것이라고 가정하고, 추가적인 역할을 얹어 사용하는 경우가 많은데, 이렇게 사용할 경우, 부모가 더이상 base문제를 해결하지 못하게 되면, 그 위에 쌓인 자식의 기능들도 다같이 무용지물이 되게 됩니다.
이럴 때, 고려하는 것이 조합입니다. 조합은 부모의 코드를 바로 내려받는 것 아니라, 공통 기능을 외부 주입으로 통해 받아 변화에 대응할 수 있게끔 합니다. 마치, 원신값 대신 VO를 사용하듯이, 포인터의 포인터를 사용해 공통기능의 변화가 발생하면, 변화된 코드를 받아 사용할 수 있습니다.
만약, 상속을 유지하겠다면, 자식에게는 최소한의 역할만 배정하는 게 좋습니다. 추상클래스를 하면서, 템플릿메소드패턴을 사용해서 위임할 수 있는 가장 작은 구현책임만 자식에게 위임할 수 있습니다.
하지만, 여러 기물들을 차례로 하다보면 구현하다보면 공통된 기능이 아니라 서로 다르게 구현해야함을 발견할 수 있습니다. 이 때, 메서드명만 추상화한 추상클래스로 정의해볼 수 있습니다. 더욱이, move뿐만 아니라 canMove? 등의 메서드를 구현하다보면, 자식들마다 구현이 다른 코드가 축적되게 되고, 특히 폰의 경우 그렇습니다.
이렇게 자식의 책임이 커질 때는, 부모클래스가 더이상 필요 없을 수 있습니다.
혹은 공통된 기능만 주입받는 조합을 고려해볼 수 있고, 부모의 역할에상속을 이용하는 것보다, 모든 책임을 위임하도록 인터페이스와 구현체로 전환을 고려해볼 수 있습니다.
이 때, 조합이나 인터페이스로 변경을 통해, 상속이 가지는 단점인 부모 코드에 대한 의존성, 높은 결합도를 줄여볼 수 있습니다.
전략패턴 -> 로또미션 + 체스dao로 예시들기
피드백
같은 조 인터뷰 피드백 전체
- 경험을 바탕으로 말하라.
- 실패 사례도 같이 예시 들기
- 학습 방식도 같이 말하기
- 뜻을 잘 모르겠으면 다시 질문의 묻기
- 생각할시간달라하기
-
물어본 것부터 답변후 사례나열하기
- 주관식답변 + 3줄 정도만 답변후, 더 답변을 원하는 눈빛을 보이면 하기
-
말하기 전 3~5초 잠깐 생각하고 말하기
- 아는 것 나왔다고 바로 답변하지 않기
-
잘모르는 키워드, 단어는 꺼내지도 마라
-
ex>일급컬렉션 -> 불변으로 연결안되면 꺼내지도 마라.
-
“그것에 대해서는 학습이 많이 필요한 상태입니다.!”
-
- 계속 질문한다면 고집스런 모습이 없는지 파악하는 것일 수 있다. 다른쪽으로 유도 되는 질문을 잘 파악하기
- 상상력을 요구하는 꼬리질문에 대해서, 단정짓게 끝내지마라.
- 급한 느낌을 받았다.
- 내가 말할 수 있는 목적을 간단명료하게 하는 것이 학습로그의 목적> 질문 듣고, 말하기 전에 3~5초는 잠깐 생각하고 말하기
- 주관식답변 + 3줄 정도만 답변후, 더 답변을 원하는 눈빛을 보이면 하기
- 잘하는 부분과 못하는 부분 같이 말하며 현장감이 드는 설명하기
레벨1 피드백
-
일급컬렉션 반례: 객체생성비용이 많이 드는 경우도 있다.
- ex> db컨넥션, 웹소켓 객체들은..
- 생성비용 크다 -> 일급x
- 재사용 및 상태변경이 일어남 -> 일급X
- ex> db컨넥션, 웹소켓 객체들은..
- mvc 장점:
- 레이어간의 책임분리(레이어분리)로 요구사항 변경에 대한 확산이, 딱 그 레이어까지만 일어나게
- 중복된 코드 제거의 목적 :
- 가독성 뿐만 아니라, 요구사항 변경의 전파를 막기(격리) 위해 중복코드를 제거함. By한 부분만 수정
-
어필하기 위한 글쓰기도 전략
- 어려운 것 질문하기 쉽게 내지마라.
- 예) 수달님의 레벨로그
- 방어적 복사 vs Unmodifiable vs CopyOf
-
답변:
-
방어적 복사:
파라미터로 넘어오는 객체
(컬렉션)에 대해서 연결을끊어놓고 받아 사용
하고 싶을 때- new ArrayList<>(
파라미터로 넘어온 컬렉션
)
- new ArrayList<>(
- Unmodifiable < CopyOf
- getter
내가 가지고 있는 컬렉션
을끊어서 줄 때
- getter
-
방어적 복사:
- 개념 -> 사례순으로 나열하기
개인 피드백
- 할 말이 많아도 천천히 말하기 -> 못 따라간다.
- 사례를 많이 말한다 -> 말이 빠르다 + 정정하는 말이 많았다. -> 많은 사례에 비해 들리는 것이 없었다.
- 중간 중간 분위기를 풀어주는 농담이 좋았다.
- 여러 사례에서 넘어갈 때 텀과 포인트가 필요하다.
- 모범답안이 아니라, 주관적인 답변이 개발적 가치관을 알 수 있어 좋았다.
- 작은 질문에 비해, 답변을 많이 했다. 밸런스가 중요한데, 질문할 텀을 좋은 것 같다.
-
경험이 잘 전달되는 인터뷰라 좋았지만, < 급한 느낌을 받았다. 내가 말할 수 있는 목적을 간단명료하게 하는 것이 학습로그의 목적>
- 질문듣고, 말하기 전에 3~5초는 잠깐 생각하고 말하기
내 인터뷰 답변 내용 기록
-
테스트 네이밍 메소드 명과 같이 카멜케이스 사용 혼자서 작성할 때는 한글, 그렇지 않은 경우는 영어로
-
중복된 코드를 줄이기 위해 인터페이스가 아닌 상속을 사용한 이유
- 같은 레벨에 있는 클래스를 작성할 때 중복 코드가 발생
- 인터페이스를 사용하지 않는 이유는 부모의 역할이 클 때는 상속을 사용하고, 확장성이 있다면 조합이나 인터페이스를 사용해서 진행
-
조합을 사용해본 경험 프로젝트에서 조합을 사용해보려 했으나 실패, 상속에 비해 조합이 부모 클래스에 대한 의존을 줄일 수 있음
-
전략패턴 분기를 줄이는데도 사용, 테스트를 줄이기 위해 사용
- TDD의 장점
- 테스트 코드 안정감
- 단일 책임 원칙을 지킬 수 있음
- 디버깅 시간을 줄일 수 있음 + 숙달 시 설계 시간을 줄임
-
자체로 명세가 될 수 있음
-
TDD의 단점 시간이 너무 오래 걸린다. 절충이 필요한 점. 작은 프로젝트에 적합하지 않다고 생각
-
큰 프로젝트에서 요구사항 변경이 생긴다면 TDD가 적합하지 않지 않을까 TDD가 익숙하다면 무조건 유리할거 같다.
-
TDD를 학습하기 위한 전략 메인 로직을 짜다가 작은 단위를 테스트하고 올라오고 반복
- TDD를 큰 로직을 성공 후 작은 로직을 개발하다가 전체가 문제가 생긴 경험?
- TDD가 실패를 기반으로 개발하다 보니 전체가 문제가 생긴 경험이 많음.
- 테스트 코드 + 프로덕션 코드 변경이 많은 경우
- 주요 로직이 아니라면 삭제, 삭제가 불가능한 경우 테스트 코드 자체를 리팩토링 해야한다고 생각
- 추상화란 무엇인지
- 비슷한 역할을 하는 것들이 보이면 추상화의 대상이 된다고 판단. 최초로 코드를 짤 때는 추상화를 고민하지 말고, 리팩토링 할 때 추상화를 고려해보아야 한다.
- 중복된 코드는 왜 제거해두어야 할까?
- 다른사람이 읽거나 찾아가는데 방해가 되는 경우 중복된 코드를 내버려두어도 된다.”