우아한테크코스 3기 백엔드 Lv2 모의면접 대상 학습로그 모음

김태희·2021년 4월 20일
0
post-thumbnail

Lv1


🚀 로또 - 1단계 - 자동


[설계] 클래스 다이어그램 - 5

내용

  • 맨 처음 설계 과정에서 페어와 함께 클래스다이어그램을 그렸다.
    모든 세부사항, 구체적인 연관관계를 그렸다.
    하지만 UML 정식 형식과 많이 달랐고, 너무 복잡해 이해하기 힘들었다.

  • 페어프로그래밍을 종료하고, [UML 실전에서는 이것만 쓴다 / 로버트 C.마틴] 책을 보았다.
    그런데 오히려 로버트 마틴은 "세세하게 이것저것 다 적어놔봤자 알아보기만 힘들고,
    구체적인것은 코드 구현시점에 정하면 된다. 모두가 잘 이해할 수 있도록 간소화 된 형식으로 UML을 작성해야 한다."
    라고 했다.
    점선, 집합, 합성도 구분하지 말고, 단순히 관계만 알아보기 쉽게 표현하라고 했다.

  • 로버트 마틴의 말을 참고해 최대한 이해하기 쉽도록 다시 UML을 그렸다.

링크


[설계] MVC - 3

내용

  • 핵심 비즈니스 로직을 가지는 도메인 객체들을 domain 패키지에, UI와 관련된 객체들을 view 패키지에 구현했다.

  • MVC 패턴 기반으로 view 패키지의 객체가 domain 패키지 객체에 의존할 수 있지만,
    domain 패키지의 객체는 view 패키지 객체에 의존하지 않도록 구현했다.


[TDD] 테스트 주도 개발 - 4

내용

  • 모든 코드작성을 페어와 함께 TDD로 구현하였다.
  • TDD로 진행하니 구현된 코드의 기능에 확신을 가질 수 있었다.
  • 리팩토링시, 테스트코드의 위력을 느낄 수 있었다. 자유롭고 확신있는 수정이 가능했다.

링크


[OOP] - 원시값 포장 - 2

내용

  • 로또 번호 등 모든 원시값을 포장했다.
  • 포장된 원시값이 하나의 도메인이 됐다.
  • 생성자에서 유효성 검사가 가능해져, 코드가 깔끔해졌다.

링크


[OOP] - 일급 컬렉션 적용 - 2

내용

  • 도메인을 담는 컬렉션들은 모두 일급 컬렉션으로 감싸서 최대한 캡슐화하고, 다양한 비즈니스 로직을 내부에 구현했다.
  • 외부에서는 내부의 구현은 모른 채, 단순히 요청 메시지만 보내고 응답 메시지를 받는, OOP적인 구현을 했다.

링크


[JDK] - Enum - 4

내용

  • 당첨 순위를 Enum으로 선언했다.
  • 각 등수를 상수로 구분하고, 관련된 메시지나 당첨 상금들을 각각 묶으니 분리와 활용이 편리해졌다.
  • 해당 Enum 클래스와 관련된 함수들 또한 클래스 내부에 위치시켜, OOP적으로 구현했다.

링크


[JDK] - Stream API - 2

내용

  • 모든 함수의 인덴트를 1로 맞추고, 가독성 좋은 코드를 작성하기 위해 Stream API를 적극 활용했다.

링크


[OOP] - Domain validation - 2

내용

  • Validation을 최대한 도메인 객체 내부의 생성자에서 했다.

  • 아무리 생각해도 도메인 내부에 어울리지 않는 Validation 작업들은 도메인 외부 InputView의 함수에서 했다.

링크


[JDK] - OS 독립적 개행문자 - 2

내용

  • OS마다 개행문자가 다르다는것을 간과하고 코드에 개행문자를 \n 로 지정했다.
  • 리뷰어 휴가 이에 대한 피드백으로 System.lineSeparator() 에 대해 찾아보라고해서 오라클 자바 문서를 찾아보았다.
  • 해당 함수는 운영체제에 맞는 개행문자를 반환해준다. 즉, OS로부터 독립적인 개발을 할 수 있는 것이다. 이런게 있었다니!! 엄청난 꿀팁이다!!

링크



🚀 로또 - 2단계 - 수동 구매


[JDK] Map API - 1

내용

  • 리뷰어 휴의 피드백을 받아, Map에서 get()으로 꺼내 값을 증가시킨 후 다시 put()으로 저장하도록 작성했던 코드를, Map API computeIfPresent() 를 사용해 더욱 명시적이고 우아하게 바꿨다.

링크


[TDD] 테스트 코드 네이밍 컨벤션 - 2

내용

  • 페어가 테스트 코드 함수 네이밍 컨벤션 적용을 제시하여, 이에 대해 찾아보고 적용했다.
  • 훨씬 더 의도를 파악하기 쉬워졌다.

링크


[Markdown] 체크박스 적용 - 1

내용

  • 리뷰어 휴가 README.md 파일의 기능구현 목록에 체크박스 적용을 제안해, 적용했다.

  • 구현이 완료된 것들과 아직 완료되지 않은 것들이 직관적으로 구별되어 구현 진행과 관리가 더욱 편해졌다.

링크


[Naming] 명확한 이름 - 4

내용

  • 모든 이름들을 영어 문법을 지키면서 최대한 구체적으로 자세하게 지으려다 보니,
    지나치게 길어지고 중복되는 부분들이 생겨, 오히려 의미전달력이 떨어지는 현상이 발생했다.

  • 리뷰어 휴가 공유해 준 영어권에서 작성된 글을 참고하여
    최대한 직관적으로 명확하게 알아볼 수 있도록 네이밍을 변경했다.

  • 문법을 지킨 길고 자세한 이름들 보다 더욱 직관적으로 알아보기 쉬워졌고, 코드가 깨끗해졌다.

링크


[OOP] Caching - 3

내용

  • 코치 제이슨이 로또번호 객체 캐싱을 제안해, 이를 적용했다.

  • 반복되어 사용되는 객체(로또번호)들을 캐싱해 재사용하였다.

  • new 연산자를 통해 계속 생성할 필요 없이 캐싱되어있는 로또번호들을 가져다가 쓰니
    메모리도 절약되고, 코드도 깔끔해졌다.

링크


[JDK] Custom Exception - 2

내용

  • 리뷰어 휴가 원시값에 대한 유효성 검사 시, 예외에 Custom Exception을 적용해볼 것을 제안해 적용다.

  • 예외가 더욱 명확해져, 다른 예외들과 직관적인 구분이 가능해졌다.

링크


[OOP] Caching - 3

내용

  • 리뷰어 휴의 제안으로 Integer.valueOf() API 를 참고하여 캐싱 방식을 개선했다.

  • LottoNumber.valueOf() 와 같이 API 사용 형식이 더욱 깔끔하고 명확해졌다. 의미 전달력도 매우 향상되었다.

링크


[JDK] BigDecimal API - 3

내용

  • 수익률 소수점 계산에서 BigDecimal API 사용이 필요했다.

  • 사용법을 제대로 숙지하지 않은 채 사용해, 소수점 셋 째 자리에서 반올림이 되지 않는 버그가 발생했다.

  • BigDecimal API 문서 와 구글링을 참고하고, 학습 테스트 를 통해 정확한 API 사용법을 익혀 버그를 고쳤다.

  • 맨 처음 구현할 때, 구글링을 통해 찾은 잘못된 자료 를 참고해서 코드를 작성했다. 사용법이 애매할 때는 학습 테스트 로 제대로 익힌 뒤에 사용해야 겠다.

링크



🚀 블랙잭 - 1단계


[OOP] 추상클래스 - 5

내용

  • 도메인들의 공통 부분을 추상클래스로 뽑아 추상화 했다.
  • 중복이 사라지고, 자식클래스들이 매우 간단해졌다.
  • 인터페이스를 추상클래스에서 implements하면 무조건 인터페이스의 모든 메소드들을 구현해야 하는 줄 알았는데, 인터페이스의 일부 메소드들을 추상메소드로 둘 수 있음을 배웠다.

링크


[OOP] 인터페이스 - 5

내용

  • 공통 메소드들을 인터페이스로 뽑아 추상화 했다.

링크


[TDD] 테스트 주도 개발 - 5

내용

  • TDD를 통해 메시지(책임)로부터 시작하여 그에 따라 필요한 속성들이 자연스럽게 정해지는 OOP를 구현했다.
  • 이는 책 [객체지향의 사실과 오해] 를 읽고 적용한 것이다.
  • TDD로 구현하니 테스트 할 수 있는 코드를 작성하게 되었다.
  • 적절한 단위 테스트 케이스 작성을 통해, 안전하고 점진적인 리팩토링을 할 수 있었다.

링크


[JDK] Enum - 3

내용

  • Enum을 사용해 관련된 상수들을 하나로 묶어 명확하고 편리하게 활용했다.

  • 상수와 관련된 값들을 같이 묶어 활용했다.

링크


[디자인 패턴] 전략패턴 - 4

내용

  • 딜러가 몇 장의 카드를 반환할지 결정하는 데에 전략패턴을 사용했다.

  • 전략패턴을 적용하면 최소한의 코드 수정으로 전략을 다르게 가져갈 수 있고, 확장에도 자유로움을 알 수 있었다.

링크


[디자인 패턴] 싱글톤 패턴 - 2

내용

  • 페어 멍토의 제안으로, 애플리케이션 전체에서 공유되는 카드 뭉치 객체에 싱글톤 패턴을 적용했다.

  • 애플리케이션 전체에서 공유되는 객체에 대해서는 static 적용만 해왔는데, 싱글톤 패턴 적용에 대해 새롭게 배웠다.

링크


[OOP] 정적 팩토리 메서드 - 3

내용

  • new 연산자는 단순히 생성밖에 못한다.
  • 정적 팩토리 메서드를 이용하면, 호출하는 메서드에 따라 로직을 적용해 다른 생성 결과를 낼 수 있다.

링크



🚀 체스 - 1, 2, 3단계


[OOP] 추상클래스 - 5

내용

  • 도메인들의 공통 부분들을 추상클래스로 뽑아 추상화 했다.
  • 중복이 사라지고, 자식클래스들이 매우 간단해졌다.
  • 메서드 오버라이딩을 통한 다형성을 구현했다.

링크

[OOP] DTO - 2

내용

  • Domain, Controller, View간의 의존성을 분리하기 위해 DTO를 사용했다.

  • 필요한 데이터들을 알맞게 담아 넘겨줄 수 있었다.

    링크

  • CommandRequestDTO


[OOP] 의존성 주입 - 4

내용


[JDK] Enum - 5

내용

  • Enum 클래스로 상수들을 종류별로 묶어서 관리했다.

  • 상수들을 종류별로 편리하게 관리하고 사용할 수 있었다.

  • 한 Enum 클래스에서 다른 Enum 클래스의 상수들을 묶어 활용하는 것을 경험할 수 있었다.

    링크

  • File

  • Rank

  • Command

  • Direction

  • PieceType

  • PieceWithColorType

  • TeamColor


[OOP] 일급 컬렉션 - 3

내용

  • 컬렉션을 클래스로 포장해 일급 컬렉션으로 만들었다.

  • 함수를 통해 컬렉션 활용을 다양하게 할 수 있었다.

  • 캡슐화를 하여 컬렉션의 남용을 방지했다.

    링크

  • Board

  • PositionsCache

  • PiecesCache

  • Players


[OOP] Caching - 4

내용

  • 체스 보드 칸의 위치들과 기물들을 캐싱했다.

  • 객체를 새로 생성하지 않고 재사용해, 메모리를 절약할 수 있었다.

  • static 메서드를 사용해 객체를 편리하게 가져올 수 있었다.

    링크

  • PositionsCache

  • PiecesCache


[JUnit] Nested 어노테이션 - 5

내용

  • 동일한 맥락의 테스트 코드들을 Nested 어노테이션을 사용해 묶었다.

  • Nested 어노테이션을 사용하지 않을 때는 연관된 테스트들끼리 구별하기가 어려웠는데, 이를 사용하니 훨씬 편해졌다.

  • @BeforeEach, @AfterEach의 적용 범위가 해당 어노테이션이 있는 클래스 범위에 한정되는 장점을 활용할 수 있었다.

    링크

  • ChessGameTest


[Test] 테스트하기 쉬운 코드 - 5

내용

  • 처음에는 테스트 코드를 체스 보드의 위치값 문자열로만 테스트해, 작성하기도 어렵고 이해하기도 어려웠다.

  • 테스트하기 쉬운 코드로 리팩토링 하고 나니 테스트 코드가 직관적이 되어 이해하기도, 작성하기도 쉬워졌다.

    링크

  • ChessGameTest


[JDK] Stream - 3

내용



🚀 체스 - 4, 5단계


[OOP] DTO - 5

내용

  • Domain, Controller, View 간의 데이터 전달에 DTO를 사용했다.
  • 필요한 데이터들을 알맞은 형태로 담아 전달했다.
  • DTO를 통해 Layer들 간의 결합도를 낮췄다.

링크


[OOP] Caching - 5

내용

  • DB에 체스 보드 모든 칸들의 위치 정보들과 모든 색깔별 기물들의 정보를 저장해 두었다.
  • 애플리케이션이 실행될 때 이 정보들을 DB로부터 불러와, 객체 형태로 애플리케이션 내에 캐싱했다.
  • 자주 쓰이는 값들을 캐싱해 DB 쿼리 조회 수를 많이 줄여, 성능이 매우 개선됐다.
  • 애플리케이션 내에서 해당 객체들을 사용하기 편했다.

링크


[OOP] 점진적 리팩토링 - 5

내용

  • Web View UI 와 DB를 적용하기 위해 많은 변경이 필요했다.
  • 안전하게 점진적 리팩토링을 했다.
  • 항상 모든 테스트코드들이 통과하도록 했다.
  • 리팩토링에 확신을 갖고 자유롭게 할 수 있었다.
  • 자주 테스트 하고 싶어졌다.

[SQL] Query 최적화 - 5

내용

  • DB에서 필요한 데이터들만 조회하는 쿼리를 작성했다.
  • 원하는 데이터를 조회하기 위해 쿼리를 여러 번 날리지 않고, JOIN 등을 사용해 한 방 쿼리로 가져왔다.
  • 요청 쿼리 수가 확연히 줄어 성능이 많이 개선됐다.

링크


[OOP] Domain 의존성 분리 - 5

내용

  • 이전에는 BoardPiece를 알고, PieceBoard를 알고 있었다.
  • 이는 서로 의존성이 높음을 의미한다.
  • 기물 이동 요청에 대해 이동이 가능한지 판단하는 책임을 MoveChecker 객체로 완전히 분리했다.
  • BoardPiece간의 의존성을 현저히 낮출 수 있었다.
  • 이전에는 플레이어의 점수 계산을 Pieces 도메인에서 했다.
  • 점수 계산 책임을 ScoreCalculator 객체로 분리했다.

링크


[DB] 테이블 연관관계 매핑 - 5

내용

  • 인프런에서 김영한 님의 JPA 강좌에서 공부했던 내용들을 기반으로 DB 테이블 연관관계를 외래키를 통해 매핑했다.
  • N : 1 (다대일) 관계를 실무에서 제일 많이 쓰고, N : M (다대다) 관계는 중간에 N : 1 (다대일), 1 : M (다대일) 관계의 중간 테이블을 만들어 풀어내야 한다고 하셨다. 그래야 매핑 관리에 유리하고, 각 매핑에 대한 추가적인 정보를 중간 매핑 테이블에 저장할 수 있기 때문이다.
  • 김영한 님의 강의 내용을 바탕으로 위와 같이 DB 스키마를 설계했다.


Lv2


🚀 Spring 체스 - 1, 2단계


[Spring] DI(의존성 주입) 적용 - 4

내용

  • 기존 코드는 객체들이 서로 강하게 결합되어 있었다.
  • Spring Bean 생성자 주입 방식으로, 모든 객체들 간의 결합도를 낮췄다.

태그

Spring, DI, OOP


[Spring] Web MVC 적용 - 3

내용

  • Spark Java를 제거하고, Spring Web MVC를 적용했다.
  • 추상화가 잘 되어있어 Controller의 코드가 매우 간결하고 깔끔해졌다.

태그

Spring, MVC


[JDBC] JdbcTemplate 적용 - 4

내용

  • Mysql Jdbc Driver 만 사용해서 작성했던 DAO 클래스들에 JdbcTemplate 를 적용했다.
  • 한 단계 더 추상화 되어있어, 코드가 많이 줄어들고 깔끔해졌다.
  • queryForObject() 로 DB에서 값을 조회할 때, 결괏값의 개수가 0개이면 EmptyResultDataAccessException 가 발생해, try ~ catch 문으로 직접 예외를 처리해야 하는 부분이 아쉬웠다.

태그

JDBC


[OOP] 도메인 분리 - 5

내용

  • 기존 코드는 도메인Spring과 관련된 Repository 들이 모두 얽혀있었다.
  • 모든 도메인이 Spring에 의존하고 있었다.
  • 테스트도 @SpringBootTest 를 사용해 Spring 자체를 실행시켜야 가능했다.
  • 코드 리뷰어 김고래 의 피드백을 적용하면서, 도메인은 순수 자바 객체로 유지되어야 함을 깨달았다.
  • 불가피하게 Spring을 띄워야 하는 Repository 관련 테스트를 제외하고, 도메인 관련 테스트들은 모두 순수 자바로만 실행할 수 있게 되었다. 테스트 속도가 매우 빨라졌다.
  • 도메인 자체만 테스트하다보니, 각 객체별로 작은 단위의 테스트를 매우 간단하게 할 수 있었다. 이전에는 모든 의존성을 알맞게 주입해 놓아야 테스트가 가능했다.
  • 콘솔 게임은 Spring 없이 순수하게 자바로만 실행할 수 있게 되었다.

태그

OOP, Domain, Test, Spring


[Test] In-Memory DB 적용 - 3

내용

  • 이전에는 테스트를 실제 DB를 통해서 했었다.
  • 코드 리뷰어 김고래 의 피드백으로 Test들은 In-Memory DB인 H2 DB를 적용했다.
  • 테스트가 훨씬 가벼워져 속도가 빨라지고, 외부 DB에 의존하지 않게 되었다.

태그

Test, DB



🚀 Spring 체스 - 3단계, 추가미션


[Spring MVC] @(Rest)ControllerAdvice - 3

내용

  • Controller와 Exception의 범위를 지정하면, Exception을 알아서 잡아준다.
  • try ~ catch 문을 없앨 수 있어, 비즈니스 로직이 매우 깔끔해진다.

태그

Spring, MVC, Exception


[HTTP] REST API - 2

내용

  • 삭제 요청을 POST "/delete" 로 했었다.
  • DELETE "games/${gameId}" 로 바꾸니, API가 더욱 명시적으로 됐다.

태그

HTTP, REST, API


내용

  • 클라이언트에 값을 저장하고, 이후 요청마다 해당 값을 포함시키는데 적합한 쿠키를 사용했다.
  • 한 번 쿠키를 발급해주면, 만료되기 전 까지 매 요청에 쿠키를 포함해 보내기 때문에 인증에 유용하다.

태그

HTTP, Cookie


[보안] Hash 암호화 - 4

내용

  • 프로그래밍 요구사항에서 비밀번호를 클라이언트에 저장하고, 매 요청에 같이 보내라는 부분이 있었다.
  • 이 방식은 보안에 매우 취약하기 때문에, Hash 암호화를 사용했다.
  • 쿠키나 요청 데이터가 탈취당하더라도 Hash 함수로 암호화 되어있기 때문에, 암호 본문은 알 수 없어 보안에 유리하다.

태그

보안, Hash


profile
Web Back-End (Spring, JPA, AWS)

0개의 댓글