📜 제목으로 보기

레벨 인터뷰 관련

  • 레벨로그를 작성해서 공유하여 레벨 1학습한 것을 정리

  • 메타인지: 자신이 아는지 모르는지 성찰하는 능력, 자신의 생각에 대해 생각하는 능력

  • 6명: 1인터뷰이 -> 3인터뷰어(질문자) + 2옵져버(피드백 기록-어떤점이 부족하고 어떤점을 보완했으면 좋겠다.)

  • 명당 30분(인터뷰 20분 + 피드백 10분) image-20220418212815514
    • 내가 인터뷰어일 때, 해당하는 인터뷰이의 레벨로그를 읽어보고 참석해야한다
    • 내가 옵져버일 때, 말하기 역량에 대한 피드백을 준비한다.
  • 레벨 2 시작하고 수, 목 14시~17시

    • 코치들이 난이도 있는 질문을 추가적으로 한다.

    image-20220418212911139

준비

레벨 로그

TDD
  • test 파일부터 만들어서 개발을 시작한다. 메서드명은 한글로 사용해도 상관 없으며 단위테스트가 의미하는 바를 잘 나타내야한다.
  • 테스트시 코드를 작성할 때 당장 존재하지 않는 클래스, 메서드를 사용해서 작성한 뒤, red(error)를 발생시킨다.
    • red를 제거하여 green(pass)이 되는 방향으로 프로덕션 코드를 작성한다.
    • pass된 프로덕션 코드를 바탕으로 기존 프로덕션 코드를refactoring한다.
    • 더이상 refactoring할 것이 없다면 새로운 단위테스트를 만들어서 이어나간다.
    • 요약하면 fail하는 test -> pass하도록 빠르게 production 수정 -> refactoring
  • 할 수 있다면 주석으로 //given //when //then 3단계로 나누어서 테스트코드를 작성하여 예상값과 실제값을 비교한다.
  • 직전과 비슷한 test case를 작성한다면 코드를 복사하여 붙여넣기를 활용하면 좋다.
테스트 하기 힘든 것을 전략패턴으로
  • 자동차 미션의 랜덤한 값에 따라 자동차가 움직임 , 로또 미션의 자동 로또를 랜덤하게 생성함, 블랙잭 미션의 랜덤한 카드덱을 매번 생성, 체스 미션의 매번 DB에 연결하는 Dao
  • 각 미션마다 테스트하기 힘든 부분을 어느 추상체에 대한 구현체 중 1개로 보고 해당코드를 추상화한다. 이 때, 추상화된 인터페이스를 파라미터에서 받아 외부에서 주입받도록 한다면 전략패턴이 되는 것이다. 이제 테스트 하기 힘든 구현체와 같은 레벨의 테스트 하기 쉬운 구현체를 작성하여 Test코드에서 외부에서 주입할 수 있다.
상속, 추상클래스, 조합
  • 상속은 같은 레벨의 클래스들이 중복된 코드를 가질 때 고려해볼 수 있다.
    • 공통된 메서드나 필드가 발견되면 그것들을 모아놓은 부모클래스를 생성하고 그 메서드나 필드를 받아 쓸 자식클래스들은 해당 클래스를 상속한다.
  • 이후 공통적이지 않은 메서드들에 대해서는 구현부는 다를지언정 메서드명을 추상화할 수 있는지 고려해보아야한다.
    • 자식클래스들에 대해 서로 다른 구현부를 가진 메서드에 대해서 메서드명이 추상화가 된다면, 추상화된 메서드명으로 abstract method를 정의해주자. intellij가 알아서 abstract class로 변경하라고 메세지를 보내준다.
    • 메서드명의 추상화 성공시, 또다른 중복코드가 발생할 수 있는데 다시 abstract class로 공통 부분들을 올려주면 된다.
  • 조합은 공통되는 코드를 부모클래스를 생성하여 올리는 것이 아니라, 따로 클래스로 추출한 뒤, 기존 클래스의 생성자호출시 주입하여 상태값(필드)로 가지고 있게 된다. 코드중복을 상태값으로 간 객체의 메서드호출로 해결할 수 있다.
    • 상속의 단점이자 조합의 장점
      • 기존 클래스의 변화에 영향이 적어지며, 안전하다.
      • 메서드를 호출하는 방식으로 동작하기 때문에 캡슐화를 깨뜨리지 않는다.
    • 조합대신 상속을 고려해볼만 할 때
      • 확장을 고려했는데도 설계한 확실한 is - a 관계(부모가 변할일이 없을 때)

대본

TDD
  1. 정의: 켄트 백에 의해 창시된 TDD는, 기존의 [ 설계-> 개발-> 테스트 ]의 과정과 다르게, [설계 -> 테스트 -> 개발]의 과정으로 진행되며, 테스트 자체도 red->green->refactoring 3가지 cycle로 돌아갑니다. 1) red로 테스트를 작성하고 2) green으로 기능을 완성하되 빠르게 완성시킵니다. 3) 다음 case로 넘어가기 전에 refactoring을 실시합니다.

  2. 장점: 마음에 안정감이 생기면서, 디버깅 시간을 줄이면서, 그 자체로 명세 역할을 할 수 있습니다. 1) 안정감이 생기는 이유는, 자연스럽게 작은 단위를 테스트하도록 작성하므로, 단일책임원칙을 지키면서 코딩할 수 있었습니다. 하지만, TDD에 실패하는 대부분의 이유가 추상체가 아닌 구현체를 테스트하는 경우임을 인식해야합니다. 인터페이스를 테스트해서 무엇보다도, 초록색불을 보면 안정감이 생겼습니다. 2) 디버깅 시간을 줄인다는 의미는 프로덕션 코드 이전에 설계 후 테스트가 이어지기 때문에, 테스트과정에서 설계가 바뀐다면 빠르게 설계를 수정할 수 있습니다. 처음에는 오히려 시간이 많이 걸릴지도 모르지만, 엎어지는 설계를 하는 과정에서도 도메인 지식이 쌓이게 되어 장기적으로는 빠르게 코드를 완성할 수 있습니다. 3) 자체로서 명세역할을 한다는 의미는, 팀원이 TDD의 과정으로 개발된 프로젝트는 테스트 코드만 봐도, 로직을 이해할 수 있게 되기 때문입니다.

상속

같은 레벨의 클래스들이 중복코드를 가져서 코드중복 제거을 위해 고려해볼 수 있다.

상속의 예시: 체스판 위의 기물들, 예를 들면 킹,퀸,룩,비숍,나이트,폰 등을 표현하고자 할 때, 각 기물들은 구현하다보면, move라는 공통 기능을 발견하게 됩니다. 이 때, 각 기물들을 자식클래스라고 생각하고 Piece라는 부모클래스를 만들어서 공통기능을 위임하고 코드 중복을 제거할 수 있습니다.

하지만, 상속에서 자식은 이미 부모가 불변할 것이라고 가정하고, 추가적인 역할을 얹어 사용하는 경우가 많은데, 이렇게 사용할 경우, 부모가 더이상 base문제를 해결하지 못하게 되면, 그 위에 쌓인 자식의 기능들도 다같이 무용지물이 되게 됩니다.

이럴 때, 고려하는 것이 조합입니다. 조합은 부모의 코드를 바로 내려받는 것 아니라, 공통 기능을 외부 주입으로 통해 받아 변화에 대응할 수 있게끔 합니다. 마치, 원신값 대신 VO를 사용하듯이, 포인터의 포인터를 사용해 공통기능의 변화가 발생하면, 변화된 코드를 받아 사용할 수 있습니다.

만약, 상속을 유지하겠다면, 자식에게는 최소한의 역할만 배정하는 게 좋습니다. 추상클래스를 하면서, 템플릿메소드패턴을 사용해서 위임할 수 있는 가장 작은 구현책임만 자식에게 위임할 수 있습니다.

하지만, 여러 기물들을 차례로 하다보면 구현하다보면 공통된 기능이 아니라 서로 다르게 구현해야함을 발견할 수 있습니다. 이 때, 메서드명만 추상화한 추상클래스로 정의해볼 수 있습니다. 더욱이, move뿐만 아니라 canMove? 등의 메서드를 구현하다보면, 자식들마다 구현이 다른 코드가 축적되게 되고, 특히 폰의 경우 그렇습니다.

이렇게 자식의 책임이 커질 때는, 부모클래스가 더이상 필요 없을 수 있습니다.

혹은 공통된 기능만 주입받는 조합을 고려해볼 수 있고, 부모의 역할에상속을 이용하는 것보다, 모든 책임을 위임하도록 인터페이스와 구현체로 전환을 고려해볼 수 있습니다.

이 때, 조합이나 인터페이스로 변경을 통해, 상속이 가지는 단점인 부모 코드에 대한 의존성, 높은 결합도를 줄여볼 수 있습니다.

전략패턴 -> 로또미션 + 체스dao로 예시들기

피드백

같은 조 인터뷰 피드백 전체

  • 경험을 바탕으로 말하라.
  • 실패 사례도 같이 예시 들기
  • 학습 방식도 같이 말하기
  • 뜻을 잘 모르겠으면 다시 질문의 묻기
  • 생각할시간달라하기
  • 물어본 것부터 답변후 사례나열하기

    • 주관식답변 + 3줄 정도만 답변후, 더 답변을 원하는 눈빛을 보이면 하기
  • 말하기 전 3~5초 잠깐 생각하고 말하기

    • 아는 것 나왔다고 바로 답변하지 않기
  • 잘모르는 키워드, 단어는 꺼내지도 마라

    • ex>일급컬렉션 -> 불변으로 연결안되면 꺼내지도 마라.

    • “그것에 대해서는 학습이 많이 필요한 상태입니다.!”

  • 계속 질문한다면 고집스런 모습이 없는지 파악하는 것일 수 있다. 다른쪽으로 유도 되는 질문을 잘 파악하기
  • 상상력을 요구하는 꼬리질문에 대해서, 단정짓게 끝내지마라.
  • 급한 느낌을 받았다.
    • 내가 말할 수 있는 목적을 간단명료하게 하는 것이 학습로그의 목적> 질문 듣고, 말하기 전에 3~5초는 잠깐 생각하고 말하기
    • 주관식답변 + 3줄 정도만 답변후, 더 답변을 원하는 눈빛을 보이면 하기
  • 잘하는 부분과 못하는 부분 같이 말하며 현장감이 드는 설명하기

레벨1 피드백

  • 일급컬렉션 반례: 객체생성비용이 많이 드는 경우도 있다.
    • ex> db컨넥션, 웹소켓 객체들은..
      • 생성비용 크다 -> 일급x
      • 재사용 및 상태변경이 일어남 -> 일급X
  • mvc 장점:
    • 레이어간의 책임분리(레이어분리)로 요구사항 변경에 대한 확산이, 딱 그 레이어까지만 일어나게
  • 중복된 코드 제거의 목적 :
    • 가독성 뿐만 아니라, 요구사항 변경의 전파를 막기(격리) 위해 중복코드를 제거함. By한 부분만 수정
  • 어필하기 위한 글쓰기도 전략
    • 어려운 것 질문하기 쉽게 내지마라.
    • 예) 수달님의 레벨로그
      • 방어적 복사 vs Unmodifiable vs CopyOf
      • 답변:
        • 방어적 복사: 파라미터로 넘어오는 객체(컬렉션)에 대해서 연결을 끊어놓고 받아 사용하고 싶을 때
          • new ArrayList<>( 파라미터로 넘어온 컬렉션 )
        • Unmodifiable < CopyOf
          • getter 내가 가지고 있는 컬렉션끊어서 줄 때
  • 개념 -> 사례순으로 나열하기

개인 피드백

  1. 할 말이 많아도 천천히 말하기 -> 못 따라간다.
  2. 사례를 많이 말한다 -> 말이 빠르다 + 정정하는 말이 많았다. -> 많은 사례에 비해 들리는 것이 없었다.
  3. 중간 중간 분위기를 풀어주는 농담이 좋았다.
  4. 여러 사례에서 넘어갈 때 텀과 포인트가 필요하다.
  5. 모범답안이 아니라, 주관적인 답변이 개발적 가치관을 알 수 있어 좋았다.
  6. 작은 질문에 비해, 답변을 많이 했다. 밸런스가 중요한데, 질문할 텀을 좋은 것 같다.
  7. 경험이 잘 전달되는 인터뷰라 좋았지만, < 급한 느낌을 받았다. 내가 말할 수 있는 목적을 간단명료하게 하는 것이 학습로그의 목적>

  8. 질문듣고, 말하기 전에 3~5초는 잠깐 생각하고 말하기

내 인터뷰 답변 내용 기록

  1. 테스트 네이밍 메소드 명과 같이 카멜케이스 사용 혼자서 작성할 때는 한글, 그렇지 않은 경우는 영어로

  2. 중복된 코드를 줄이기 위해 인터페이스가 아닌 상속을 사용한 이유

  • 같은 레벨에 있는 클래스를 작성할 때 중복 코드가 발생
  • 인터페이스를 사용하지 않는 이유는 부모의 역할이 클 때는 상속을 사용하고, 확장성이 있다면 조합이나 인터페이스를 사용해서 진행
  1. 조합을 사용해본 경험 프로젝트에서 조합을 사용해보려 했으나 실패, 상속에 비해 조합이 부모 클래스에 대한 의존을 줄일 수 있음

  2. 전략패턴 분기를 줄이는데도 사용, 테스트를 줄이기 위해 사용

  3. TDD의 장점
  4. 테스트 코드 안정감
  5. 단일 책임 원칙을 지킬 수 있음
  6. 디버깅 시간을 줄일 수 있음 + 숙달 시 설계 시간을 줄임
  7. 자체로 명세가 될 수 있음

  8. TDD의 단점 시간이 너무 오래 걸린다. 절충이 필요한 점. 작은 프로젝트에 적합하지 않다고 생각

  9. 큰 프로젝트에서 요구사항 변경이 생긴다면 TDD가 적합하지 않지 않을까 TDD가 익숙하다면 무조건 유리할거 같다.

  10. TDD를 학습하기 위한 전략 메인 로직을 짜다가 작은 단위를 테스트하고 올라오고 반복

  11. TDD를 큰 로직을 성공 후 작은 로직을 개발하다가 전체가 문제가 생긴 경험?
  • TDD가 실패를 기반으로 개발하다 보니 전체가 문제가 생긴 경험이 많음.
  1. 테스트 코드 + 프로덕션 코드 변경이 많은 경우
  • 주요 로직이 아니라면 삭제, 삭제가 불가능한 경우 테스트 코드 자체를 리팩토링 해야한다고 생각
  1. 추상화란 무엇인지
  • 비슷한 역할을 하는 것들이 보이면 추상화의 대상이 된다고 판단. 최초로 코드를 짤 때는 추상화를 고민하지 말고, 리팩토링 할 때 추상화를 고려해보아야 한다.
  1. 중복된 코드는 왜 제거해두어야 할까?
  • 다른사람이 읽거나 찾아가는데 방해가 되는 경우 중복된 코드를 내버려두어도 된다.”