1. 배열, 링크드리스트를 비교하여 설명해주실 수 있을까요?

  배열은 입력된 데이터들이 메모리 공간에서 연속적으로 저장되어 있는 자료구조이며 메모리상에서 연속적으로 저장되어 있는 특징을 갖기 때문에 index를 통한 접근이 용이하다는 장점이 있으나 삽입/삭제가 오래 걸리고 배열 중간의 데이터가 삭제 되면 공간 낭비가 발생할 수 있는 단점이 존재합니다. 

  링크드리스트(연결리스트)는 여러 개의 노드들이 순차적으로 연결된 형태를 갖는 자료구조이며 각 노드는 데이터와 다음 노드를 가리키는 포인터로 이루어져 있는 트리(tree)구조의 근간이 되는 자료구조입니다. 배열과 달리 메모리를 연속적으로 사용하지 않아 삽입/삭제에 용이하다는 장점이 있습니다. 그러나 index로 임의 접근이 불가하며 처음부터 탐색을 해야하는 단점이 있습니다.

  따라서 배열은 빠른 접근이 요구되고, 데이터의 삽입과 삭제가 적을 때 사용하고 링크드리스트는 삽입과 삭제 연산이 잦고, 검색 빈도가 적을 때 사용합니다.

 

2. CORS란 무엇이고 어떻게 허용할 수 있나요?

한 출처에 있는 자원에서 다른 출처에 있는 자원에 접근하도록 하는 것으로 교차되는 출처 자원들의 공유입니다. 다른 출처의 리소스를 가져오는 상황에서 SOP는 이 접근을 차단합니다. 하지만 CORS 설정을 통하여 Access-Control-Allpw-Origin을 서버의 응답헤더에 작성하게 되면 접근 권한을 얻을 수 있습니다.

 

3. 시간복잡도와 공간복잡도가 무엇인지 설명해주실 수 있을까요?

시간 복잡도란 특정 크기의 입력을 기준으로 할 때 필요한 연산의 횟수를 나타냅니다. 시간 복잡도에는 빅오 표기법이라는 복잡도를 나타내는 점근 표기법 중 가장 많이 사용되는 표기법을 사용합니다. 공간 복잡도는 프로그램 실행과 완료에 얼마나 많은 공간(메모리)가 필요한지를 나타냅니다. 알고리즘을 실행시키기 위해 필요한 공간, 고정 공간과 가변 공간이 있습니다.

 

4. 사용자 패스워드를 전송하고 보관하는 방법을 설명해주실 수 있을까요?

유저의 패스워드를 받은 클라이언트는 평문으로 서버로 전송합니다. 평문을 받은 서버는 패스워드를 단방향 해시 함수로 암호화하여 보관합니다. 단방향 해시함수는 수학적 연산에 의해 원본 데이터를 완전히 다른 암호화된 데이터(다이제스트)로 변환하는 것을 말합니다. 원본 데이터로는 다이제스트를 구할 수 있지만 다이제스트로는 원본데이터를 구할 수 없어야 합니다. 이것을 단방향이라 합니다. 단방향 해시함수는 브루트포스 공격으로 쉽게 당할 수 있기 때문에 이를 보완하기 위해 입력된 다이제스트를 N번 반복해서 생성하는 것인 key stretching과 원문 패스워드에 임의의 문자열을 추가하여 해싱하는 것인 salting을 이용해 보안의 강도를 높힐 수 있습니다.

 

5. 스택, 큐에 대해 설명해주실 수 있을까요?

- 스택은 쌓여있는 접시와 같다. 먼저들어온 자료가 나중에 나간다. FILO(First In Last Out.)
- 스택은 접근성에 제한이 있는 자료구조. 오직 맨 위에 추가(push)할 수 있고, 맨 위에 것만 나갈(pop) 수 있다.
- 큐는 놀이공원에 줄 서있는 사람들과 같다. 먼저 온 사람이 먼저 나간다. FIFO(First In First Out.) 
- 큐는 두가지 동작만 허용된 자료구조. Enqueue(들어옴)과 Dequeue(나감).
- Stack과 Queue의 가장 큰 차이점은 item을 삭제할 때 있다. 아이템을 삭제할 때, Stack은 가장 마지막에 추가되 있던 item을 삭제하고, Queue는 가장 처음으로 들어와 있던 item을 삭제한다.

 

6. DI와 IoC에 대해 아는 만큼 설명해주실 수 있을까요?

DI(Dependency Injection)란 스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능으로, 객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식이다. DI(의존성 주입)를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다. IoC(Inversion of Control)란 "제어의 역전" 이라는 의미로, 말 그대로 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부에서 결정되는 것을 의미한다. IoC는 제어의 역전이라고 말하며, 간단히 말해 "제어의 흐름을 바꾼다"라고 한다. 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 한다.

 

7. Call by reference란 무엇이고 보통 어떻게 쓰이나요?

Call by reference - 참조에 의한 호출로써, 함수가 호출될 때 메모리 공간 안에는 함수를 위한 별도의 임시 공간이 생성된다. 함수 호출 시 인자로 전달되는 변수의 레퍼런스를 전달하여 해당 변수를 가르킨다. 함수 안에서 인자의 값이 변경되면, 함수 호출 시에 있던 변수들도 값이 바뀐다.

Call by Value - 값에 의한 호출로써, 함수가 호출될 때 메모리 공간 안에는 임시의 공간이 생성된다. 함수 호출 시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다. 복사된 인자는 함수 안에서 지역적으로 사용하는 변수이다. JAVA 는 오직 Call by Value 로만 동작하고, Reference 의 값을 넘기는 것만 가능하다.

 

8. Override 와 Overload 를 설명해주실 수 있을까요?

- 오버로드(Overload) : 메서드의 이름은 같고 파라메터의 갯수나 타입이 다른 함수를 정의하는 것을 의미한다. (리턴값만을 다르게 갖는 오버로드는 작성 할 수 없다.)
- 오버라이드(Override) : 상위 클래스의 메서드를 재정의 하는 것이다.
메서드의 이름은 물론 파라메터의 갯수나 타입도 동일해야 하며, 주로 상위 클래스의 동작을 상속받은 하위 클래스에서 변경하기 위해 사용된다.
- 오버로딩(Overloading)은 기존에 없던 새로운 메서드를 정의하는 것이고, 오버라이딩(Overriding)은 상속 받은 메서드의 내용만 변경 하는 것이다.

 

오버로딩(Overload)은 메소드의 이름은 같고 매개변수의 개수나 타입이 다른 함수를 정의하는 것을 의미하며 여러개의 서브프로그램 생성을 가능하게 합니다. 오버라이딩(Overriding)은 상위 클래스의 메소드를 하위 클래스가 재정의 하는 것 의미하며 메소드 이름의 절약과 예상을 가능하게 합니다. 두 기능으로 JAVA에서 다형성을 구현하고, SOLID - OCP, LSP 원칙을 지킬 수 있습니다.

 

9. MVC 모델이란 무엇인지 설명해주실 수 있을까요?

- MVC 는 Model, View, Controller의 약자 입니다. 하나의 애플리케이션, 프로젝트를 구성할 때 그 구성요소를 세가지의 역할로 구분한 패턴입니다. 
- 사용자가 controller를 조작하면 controller는 model을 통해서 데이터를 가져오고 그 정보를 바탕으로 시각적인 표현을 담당하는 View를 제어해서 사용자에게 전달하게 됩니다.
- 이러한 패턴을 성공적으로 사용하면, 사용자 인터페이스로부터 비즈니스 로직을 분리하여 애플리케이션의 시작적 요소나 그 이면에서 실행되는 비즈니스 로직을 서로 영향 없이 쉽게 고칠 수 있는 애플리케이션을 만들 수 있게 됩니다.

 

 

10. JPA는 언제 필요하고 언제 필요하지 않은지 설명해주실 수 있을까요?

JPA는 java 진영의 표준 ORM으로 관계형DB와 객체지향 언어인 java 와의 관계에서 쿼리문 작성 없이 편하게 데이터 다룰 수 있게 해주는 도구입니다. 쿼리문을 직접 작성할 필요가 없어 생산성이 향상되고 오류의 여지가 적어지는 장점이 있지만 통계를 내는 등의 복잡한 쿼리의 작성이 필요한 경우 적절하지 않을수 있습니다. 일반적으로 많이 사용하지만 기술의 장단점을 인지하고 장점이 발휘될수 있는 환경에서 적절하게 사용하는게 좋습니다.

 

JPA란 Java Persistence API의 약어로 Java ORM 기술에 대한 표준 명세로 자바 어플리케이션에서 관계형 RDB를 사용하는 방식을 정의한 인터페이스이다. 데이터베이스가 바뀔 가능성이 있는 경우 JPA를 권장합니다. JPA는 추상화한 데이터 접근 계층을 제공하기 때문에 설정 파일에 사용할 데이터베이스를 등록하기만 하면 얼마든 데이터베이스를 변경할 수 있습니다. 하지만 통계처리나 동적 쿼리 같은 복잡한 쿼리를 사용하거나 관계 맵핑이 어려울 때에는 직접 쿼리문을 작성하는 것이 좋을 수 있다. (JPQL도 JPA이다. 하지만 Querydsl은 JPA가 아니다 -> 의존성을 따로 주입)

 

 

11. JPA의 더티 체킹이란 무엇인가요?

 
더티 체킹이란 “상태 변경 검사”입니다. JPA에서는 트랜잭션이 끝나는 시점에 최초 조회 상태로부터 변화가 있는 모든 엔티티 객체를 데이터베이스에 자동으로 반영해줍니다. 엔티티를 조회하면 해당 엔티티의 조회 상태 그대로 스냅샷을 만들어 놓고 트랜잭션이 끝나는 시점에는 이 스냅샷과 비교해서 다른점이 있다면 Update Query를 데이터베이스로 전달합니다. 상태 변경 검사의 대상은 영속성 컨텍스트가 관리하는 엔티티에만 적용됩니다. 즉, 준영속/비영속 상태의 엔티티는 더티 체킹의 대상에 포함되지 않아 값을 변경해도 데이터베이스에 반영되지 않습니다.

 

12. Annotation이란 무엇이고 구체적으로 어떤 것이 있는지 예시를 들어 설명해주실 수 있을까요?

Annotation은 코드 사이에 주석처럼 쓰이며 특별한 의미, 기능을 수행하도록 하는 기술입니다. Annotation을 활용하면 코드가 깔끔해지고 재사용에 용이합니다. Spring framework에서 제공하는 @ComponentScan는 하위 @Component 또는 직접 등록할 Bean 예를 들면 @Controller, @Service, @Repository 등을 스캐닝하여 Bean 등록합니다. @Autowired 같은 Annotation은 또 달리 등록 된 Bean을 찾아 의존성 주입을 위해 사용 됩니다. 또 다른 예로 Lombok 라이브러리에서 제공하는 Annotaion @Setter, @Getter 등은 코드를 줄여 가독성을 높여주는 역할을 합니다.

 

13. 인덱스란 무엇이고 일반적인 원리는 어떠한지 설명해주실 수 있을까요?

인덱스란 데이터와 데이터의 위치를 포함한 자료 구조이며, 이로써 DB 테이블의 검색 속도가 향상되어 데이터를 빠르게 조회할 수 있게 됩니다. 만약 인덱스를 사용하지 않고 조회를 할 시에는, 테이블 전체를 탐색하는 Full Scan이 수행됨으로써 처리 속도가 떨어지게 됩니다.

 

인덱스는 데이터베이스 테이블에 대한 검색 성능의 속도를 높여주는 자료 구조입니다. 특정 컬럼에 인덱스를 생성하면, 해당 컬럼의 데이터들을 정렬하여 별도의 메모리 공간에 데이터의 물리적 주소와 함께 저장합니다. 인덱스가 생성 되었다면 생성한 인덱스의 컬럼을 Where 조건으로 쿼리하면 옵티마이저에서 판단하여 생성된 인덱스를 타게 됩니다. 그러면 인덱스에 저장되어 있는 데이터의 물리적 주소로 가서 데이터를 가져오게 됩니다.

 

14. 이분탐색이 무엇이고 시간복잡도는 어떻게 되며 그 이유는 무엇인가요?

이분 탐색은 내가 찾고자 하는 값이 정렬된 배열의 중간 값보다 크면 중간값을 포함한 하위 값들은 탐색 대상에서 제외된시키고, 반대로 찾고자 하는 값이 배열의 중간 값보다 작으면 중간 값을 포함한 상위 값들은 탐색에서 제외 시킵니다. 정리하면 중간값과 찾으려는 값의 대소를 비교한 뒤 탐색 범위를 반으로 줄여가며 값을 찾는 탐색 알고리즘입니다. 이런 방식은 한번 탐색을 하고나면 탐색의 범위가 절반으로 줄기 때문에 logN의 시간복잡도를 보장합니다. 하지만 정렬되어 있는 자료에서만 사용할수 있다는 단점이 있습니다.

 

15. 모든 요소에 인덱스를 걸지 않는 이유는 무엇일까요?

인덱스를 사용하면 테이블을 검색하는 속도와 성능이 향상되는 장점이 있지만 인덱스를 관리하기 위한 추가 작업이 필요하며, 추가 저장 공간 또한 필요합니다. 잘못 사용하는 경우 오히려 성능이 저하될 수 있으며 인덱스가 적용된 칼럼에 삽입, 삭제, 수정이 잦다면 인덱스 또한 수정해야 하기 때문에 성능이 낮아지며. 또한 인덱스는 제거되는 것이 아니라 '사용하지 않음'으로 남겨 두기 때문에 인덱스가 과도하게 커질 수 있기 때문에 모든 요소에 인덱스를 걸지 않는다고 생각합니다.

+ Recent posts