본문 바로가기

일기

2023-02-22

면접 스터디를 시작하고 매주 받는 과제들로부터 조사한 내용들의 정리

 

 

 

 

  • 프론트엔드
    • Hoisting 이란? TDZ란?
    • parameter와 argument의 차이에 대해 설명해주세요.
  • 백엔드
    • DI(Dependency Injection)에 대한 설명과 해당 기술의 장점에 대해 설명해주세요.
    • DB에서 인덱스를 잘 사용하면 어떤 장점이 있을까요?

 

1. DI(Dependency Injection) 와 장점

스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능으로, 객체를 직접 생성하는게 아니라 외부에서 생성한 후 주입 시켜주는 방식을 말합니다.
이를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아지는 효과가 있습니다.

다만 DI 는 개발자가 직접 코딩을 하여 객체를 생성하는 것이 아니라, 컨테이너가 이를 생성시켜 주는 것입니다.
즉, 이를 위해 객체 생성, 객체 간의 의존성 결정, 객체 생명 주기 관리 등을 해주는 컨테이너가 필요합니다.
이렇게 되면 코드에서 직접적인 연관 관계가 발생하지 않아 각 클래스들의 변경이 자유로워 집니다. 이를 느슨한 결합 이라고합니다.

참고 영상 : https://www.youtube.com/watch?v=1vdeIL2iCcM

 

느슨한 결합과 강한 결합

예를 들어 위 이미지처럼 A객체가 B 객체를 사용한다고 가정합니다.
만약 A 객체와 B 객체가 강하게 결합되어 있다면, B 객체를 수정하거나 삭제하는 경우 A 객체에도 영향을 미치게 됩니다.
따라서 이러한 경우, 코드 수정과 유지보수에 어려움이 있습니다.
하지만, DI 를 사용해서 느슨한 결합 형태로 사용하면 B 객체를 A 객체에서 분리할 수 있습니다.
A 객체가 B 객체를 직접 생성하는 것이 아니라 B 객체를 주입받아 사용하는 형태이기 때문에 이 경우 B 객체의 내부 구현을 수정하거나 삭제 하더라도 A 객체는 그대로 유지될 수 있습니다.
따라서 DI 의 느슨한 결합을 사용함에 따라 코드 수정 및 유지보수가 있어서 편리해집니다.

 

의존성 주입의 장점

  • 코드의 유연성과 재사용성 좋아집니다.
    주입받는 대상이 변하더라도 그 구현 자체를 수정할 일이 없거나 줄어듭니다.
    즉, DI 를 통해 객체간의 결합도를 낮춰 객체를 수정하거나 대체하는 작업이 쉬워지므로 최종적으로는 유지보수에도 유리해집니다.
  • 테스트 코드 작성에 유리합니다.
    DI를 이용하면 의존성을 주입하기 때문에, 테스트를 수행할 때 실제 객체를 사용하는 것이 아닌 모의 객체를 사용할 수 있습니다. 이를 통해 테스트의 효율성을 높일 수 있습니다.
    • 모의 객체란 주로 객체 지향 프로그래밍으로 개발한 프로그램을 테스트 할 경우 테스트를 수행할 모듈과 연결되는 외부의 다른 서비스나 모듈들을 실제 사용하는 모듈을 사용하지 않고 실제의 모듈을 "흉내"내는 "가짜" 모듈을 작성하여 테스트의 효용성을 높이는데 사용하는 객체를 말합니다.
  • 코드의 가독성이 향상됩니다.
    의존성을 어떻게 주입하는지 명시적으로 표현되어 가독성이 향상됩니다.

 

의존성 주입의 3가지 종류 및 예시

  • 생성자 주입
    @Service
    public class UserService {
    	private final UserRepository userRepository;
    
    	public UserService(UserRepository userRepository) {
    		this.userRepository = userRepository;
    	}
    	...
    }
    

    객체 생성 시점에 생성자를 통해 의존성을 주입하는 방법입니다.

    생성자 주입은 생성자의 호출 시점에 1회 호출되는 것을 보장합니다.
    그렇기 때문에 주입받은 객체가 변하지 않거나 반드시 객체의 주입이 필요한 경우에 강제하기 위해 사용할 수 있습니다. 생성자가 1개만 있을 경우에는 @Autowired 를 생략해도 주입이 가능합니다.

  • Setter 주입
    @Service
    public class UserService {
    	private UserRepository userRepository;
    
    	@Autowired
    	public void setUserRepository(UserRepository userRepository) {
    		this.userRepository = userRepository;
    	}
    }
    

    Setter(수정자) 메서드를 통해 의존성을 주입하는 방법입니다.

    이는 필드값을 변경하는 Setter를 통해서 의존관계를 주입하는 방법으로, 생성자 주입과 다르게 주입받는 객체가 변경될 가능성이 있는 경우에 사용됩니다.
    @Autowired 로 주입할 대상이 없는 경우에는 오류가 발생합니다. 만약 주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false) 해주면 됩니다.

  • 필드 주입
    @Service
    public class MyService {
    	@Autowired
    	private MyRepository myRepository;
    	...
    }
    

    클래스의 멤버 변수(Field)에 의존성을 직접 주입하는 방식입니다.

    과거에 상당히 많이 이용되었던 주입 방법입니다.
    다만 이방법은 외부에서 접근이 불가능하다는 단점이 있습니다.
    따라서 현재에는 테스트 코드가 많이 사용됨에 따라 필드의 객체를 수정할 수 없는 필드 주입은 거의 사용되지 않게 되었습니다.

 

2. DB에서 인덱스 사용시 장점

데이터베이스에서 테이블의 검색 성능을 높여주는 방법을 말합니다.
특히 select ~ where 쿼리처럼 특정 데이터를 찾을 때 빠른 속도로 조회할 수 있게 해줍니다.
테이블에서 특정 컬럼(열)을 선택하여 해당 컬럼의 값을 정렬한 후, 이를 이용해 검색을 빠르게 수행해줍니다.


구조

  • 인덱스는 Btree, B+tree(가장 많이 사용), Hash, Bitmap 으로 구현할 수 있습니다.
    • 구조의 종류
      • B-tree 가장 일반적인 인덱스 구현 방법 중 하나입니다. 이진 트리의 일종으로, 모든 리프 노드가 동일한 깊이에 위치하는 균형 트리입니다. 루트 노드부터 리프 노드까지 내려가며 탐색하는 방식으로 검색을 수행합니다. 중복된 값을 가질 수 있으며 범위 검색에 효과적입니다.
      • B+Tree B-Tree 의 변형 버전입니다. 리프 노드에만 모든 데이터가 저장되고, 내부 노드에는 참조 정보만이 저장됩니다. 이로 인해 리프 노드의 개수가 많아지고, 범위 검색에서의 성능이 더욱 향상됩니다. 또한 Index-scan 과 같은 작업을 수행할 때 보다 효과적입니다.
      • Hash 인덱스 데이터의 위치를 해시 함수를 이용하여 계산하고, 인덱스를 생성하는 방식입니다. 인덱스 키를 해시 함수로 변환한 값을 인덱스로 사용합니다. 해시 함수의 결과가 충돌할 가능성이 있기 때문에 중복된 값을 가질 수 없습니다. 검색속도가 매우 빠르며, 동등 비교 연산에 최적화되어 있기에 범위 검색에는 적합하지 않습니다.
      • Bitmap 인덱스 인덱스 키의 모든 가능한 값을 비트 패턴으로 변환하여 인덱스를 생성하는 방식입니다. 인덱스 키의 값을 0 또는 1로 표현하고 비트 연산을 사용하여 검색합니다. 이 방식은 컬럼이 가질 수 있는 고유한 값의 수가 적을 때 효과적입니다.
  • 인덱스를 생성하면 특정 컬럼(속성)의 값을 기준으로 정렬하여 데이터의 물리적 위치 주소와 함께 별도의 파일에 저장합니다.
  • 이 때, 특정 컬럼을 ‘search-key’ 라고 하며, 실제 데이터의 물리적 위치 값을 ‘pointer’ 라고 합니다. 보통 index는 테이블 크기의 10% 정도의 저장 공간을 차지합니다.

 

특징

특정 조건의 데이터를 찾기 위해서는 테이블의 모든 데이터에 접근해 비교하는 과정이 필요합니다.
하지만 인덱스가 있는 경우 search-key 가 정렬되어 있기 때문에 조건 검색 시 속도가 빠릅니다.
만약, 대량의 데이터를 가지고 있고 select ~ where 같은 특정 조건의 데이터를 찾을 때, 인덱스를 활용하면 빠르게 데이터를 가져올 수 있습니다. 반대로, 데이터의 양이 많지 않을 경우에는 굳이 인덱스를 사용할 이유가 없어집니다.

하지만, insert, update, delete 등의 변동 사항이 있는 경우에는 불리합니다.
왜냐하면 데이터 변경 시 인덱스도 수정되어 추가 비용이 발생하기 때문입니다.
따라서, 인덱스는 ‘자주 조회’ 하고 ‘수정 빈도’ 가 낮으며 ‘데이터 중복’ 이 적은 컬럼에서 사용하는 것이 좋습니다.
이러한 조건이 갖춰졌고 데이터의 양이 많을수록 인덱스로 인해 얻게되는 이점이 커집니다.

 

장점 요약

  • 빠른 검색 속도 인덱스를 활용한 빠른 검색 속도로, 모든 레코드의 순차 검색이 아닌 특정 조건의 데이터만을 검색해 검색속도를 높여줍니다.
  • 정렬 인덱스는 데이터를 정렬하기 때문에 ORDER BY 절을 사용한 정렬 속도도 향상됩니다.
  • 유니크 제약 조건 유니크 제약 조건을 설정하면 중복된 데이터를 테이블에 입력하지 못하도록 막을 수 있습니다.

 

정리

1. DI(Dependency Injection)에 대한 설명과 해당 기술의 장점에 대해 설명해주세요.

스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능으로, 객체를 직접 생성하는게 아니라 외부에서 생성한 후 주입 시켜주는 방식을 말합니다.
이를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아지는 효과가 있습니다.
장점으로는 크게 아래의 세가지가 있습니다.

 

의존성 주입의 장점

  • 코드의 유연성과 재사용성 좋아집니다.
  • 테스트 코드 작성에 유리합니다.
  • 코드의 가독성이 향상됩니다.

 

2. DB에서 인덱스를 잘 사용하면 어떤 장점이 있을까요?

인덱스는 데이터베이스에서 테이블의 검색 성능을 높여주는 방법을 말합니다.
테이블에서 특정 컬럼(열)을 선택하여 해당 컬럼의 값을 정렬한 후, 이를 이용해 검색을 빠르게 수행해줍니다.
장점을 3가지 정도로 요약하면 아래와 같습니다.

  • 빠른 검색 속도
    인덱스를 활용한 빠른 검색 속도로, 모든 레코드의 순차 검색이 아닌 특정 조건의 데이터만을 검색해 검색속도를 높여줍니다.
  • 정렬
    인덱스는 데이터를 정렬하기 때문에 ORDER BY 절을 사용한 정렬 속도도 향상됩니다.
  • 유니크 제약 조건
    유니크 제약 조건을 설정하면 중복된 데이터를 테이블에 입력하지 못하도록 막을 수 있습니다.

'일기' 카테고리의 다른 글

2023-02-24  (0) 2023.02.25
2023-02-23  (0) 2023.02.23
2023-02-21  (0) 2023.02.21
2023-02-18  (0) 2023.02.18
2023-02-17  (0) 2023.02.17