byworld 님의 블로그

[자바단기심화 입문 TIL 4일차] 면담, Spring 입문 강의 1장 수강 본문

TIL

[자바단기심화 입문 TIL 4일차] 면담, Spring 입문 강의 1장 수강

byworld 님의 블로그 2026. 2. 12. 17:38

서론

오늘도 그다지 집중을 못하고 분산이 됐다. 이정도면 그냥 나 혼자서 공부하는 것이 문제인 것 같다. 환경을 집이 아닌 다른 공유오피스 같은 곳으로 바꿔볼까 한다.

 

면담 내용

내가 한 것을 통한 질의 응답과 기술 면접이 있었다. 나름대로 답변을 하기는 했지만 아쉬운 부분들이 많이 있었다. 그건 차차 채워가야겠다. 배우려고 왔으니 말이다. 다음은 생각나는 기술 질문, 내가 했던 답변, AI가 쓴 모범 답안이다.

 

OOP 추상화

내가 했던 답변: ArrayList같은 하위 수준의 클래스/인터페이스를 List 같은 상위 수준의 연산만으로 정의되는 인터페이스로 받아서 추상적으로 사용하여 구현체를 몰라도 사용할 수 있게 한다. OCP같은 원칙으로 상위 수준의 클래스/인터페이스를 수정하지 않고 확장을 할 수 있다.

 

모범 답안: 추상화는 구현이 아니라 역할과 책임 기준으로 의존하도록 만들어 변경에 강한 구조를 만드는 것이고, List는 인터페이스에 의존하면 내부 구현이 ArrayList에서 Linked List 같은 다른 자료구조가 되어도 상위 로직은 영향받지 않는다.

SOLID 에서 DIP는?

내가 했던 답변: ArrayList, List같이 상위수준의 포괄적 객체가 하위수준의 객체를 담는 의존 역전 구조다.

 

모범 답안: DIP는 고수준 정책이 저수준 구현에 직접 의존하지 않고, 둘 다 추상(인터페이스)에 의존하도록 의존성 방향을 바꾸는 원칙이다. 예를 들어 OrderService가 JpaRepository에 직접 의존하지 않고, OrderRepository 인터페이스에 의존하는 구조이다.

 

OCP 목록

SRP: 클래스는 변경 이유가 하나여야 한다. (책임 분리)

OCP: 기능 확장은 추가로, 기존 코드는 수정 최소(확장에 열려있고, 수정에 닫힘, 수정하면 Patch(앱 새로 깔기))

LSP: 자식은 부모를 대체 가능해야한다. (자식은 부모의 기능은 사용 가능)

ISP: 인터페이스는 작고 목적 단위로 해야한다.(비대한 인터페이스 안하기)

DIP: 상위 로직은 하위 구현이 아니라 추상에 의존한다.

DB 인덱스

내가 했던 답변: 컬럼이나 키를 B+ 같은 자료구조로 정렬하여 행 조회를 할 때 log(n) 시간 이하로 빠르게 할 수 있게 하는 DB 인덱싱 방법이다.

모범 답안: 내가 했던 조회 시간 감소 + 쓰기 성능과 저장공간 비용이 늘어나서 무분별 인덱스는 오히려 역효과

 

DB 무결성 4가지(이 질문이 아닐 수도 있다)

내가 했던 답변: ACID 개념이냐고 질문을 했지만 아니었다. 배우고 오겠다고 했다. 사실 배웠던 내용이긴 했다.

모범 답안: 개체 무결성(기본키), 참조 무결성(외래키), 도메인 무결성(범위), 사용자 정의(업무) 무결성(업무 수행하는 방법이나 데이터 처리 규칙)

 

Trigger (질문이 아니라 해결 방식 제시였던 것 같다)

모범 정리: 이벤트 발생 시 DB가 자동으로 실행하는 프로시저. 감사 로그, 변경이력, 간단한 무결성 보조. 앱 레벨에서 놓칠 수 있는 강제 규칙.

 

Transaction

내가 했던 답변: 어떤 작업이 일어났을 때, All or Nothing으로 처리가 되거나 안되거나 하여 DB에 안정적으로 작업 반영을 하게 해준다.

모범 답안: 했던 답변 + 중간에 실패 시 롤백해서 데이터 불일치 방지

 

고 수준 트래픽에서 Redis 분산을 왜 쓰는지

내가 했던 답변: 여러 도메인을 MSA같은 방식으로 할 때 Redis 같은 시스템을 쓰면 트래픽을 분산하는 밸런싱같은 역할을 할 수 있다. Redis를 안 배웠지만 배워서 프로젝트 해보면서 어떤 이점이 있는 지 알아가겠다.

모범 답안: Redis는 인메모리 저장소로써 캐시, 세션 공유, 분산 락 등을 통해 DB 부하를 줄이고, 분산 환경에서 상태를 공유하기 위해 사용함.

영속성

내가 했던 답변: @Transactional이나 saved 같은 방식으로 트랜잭션 단위로 안정적으로 반영을 하게 해준다.

모범 답안 : 프로그램 종료 후에도 데이터가 유지되는 성질이며, JPA 에서는 엔티티가 영속성 컨텍스트에 의해 관리되는 상태.

내가 말했던 것은 이미 영속 상태인데 또 save()를 불러서 중복이다.라는 피드백. 신규 생성, 트랜잭션 밖에서 detached 객체를 merge할 때 save가 필요함. @Transactional은 영속성 컨텍스트 범위를 정의하고, save는 엔티티를 영속상태로 전환하는 역할임. 이미 영속 상태인 엔티티는 Dirty Checking으로 update 되기 때문에 트랜잭션 내부에서 save가 필수 아님.

 

동기/ 비동기 방식

내가 했던 답변: 동기는 직렬적으로 하나의 작업이 일어나고 나서 다음 작업이 일어나는 선형적인 방식이라면, 비동기는 쓰레드의 방식처럼 병렬적으로 분기되어 비선형적으로 작업을 한다.

모범 답안: 동기/비동기는 결과를 기다리느냐의 문제. 스레드가 멈추느냐 아니냐는 블로킹/논블로킹.

 

사용자에게 어떤 아이템을 띄울 것인가

내가 했던 답변: 내가 생각하기로는 추천시스템과 연관이 있을 것 같다. 사용자 히스토리를 활용하여 CBF같은 방식이나 AI 모델을 통해 사용자에 맞는 상위 아이템을 띄울 것 같다. (백엔드와는 좀 포인트에 안맞는 것 같다.)

모범 답안: 최신순/인기순, 캐시/페이지네이션, 성능/정책 등으로 말했어야 함.

 

강의 1장 완료

드디어 1장은 완료했다. JDBC, DB, SQL 등을 봤다. SQL 위주로 했던 것 같은데, 이미 데이터베이스라는 과목에서 했던 내용을 했다. DDL은 잘 안했는데, DDL 위주로 나와서 조금 당황스러웠다. 1장 숙제는 내가 그래도 찾아보면서 다 했다. 이제 JPA, IoC 등을 하는 다음 장을 학습해야겠다.

 

결론

역시나 한눈 팔면 시간이 빨리 간다. 독서실로 가든지 해야지. 집에서는 관찰자가 없으니 안하게 된다.