기록하며 성장한다 - 개발, 회고

일반 회고록

[ 기술 면접 회고록 ] 이력서를 넣고, 면접을 다니며 받은 질문

전대홍 2024. 3. 4. 19:44

 

서론

글을 쓰는 시각 기준으로, 아직 필자는 취업 전이며, 계속해서 구직활동 중이다. ( 2024-03-04 )
오늘 글을 쓰는 이유는 구직활동과 면접으로 인해 기술블로그에 글을 안올린지 한 달 정도 되어가기 때문도 있고, 여태까지 받은 면접 질문을 간단하게나마 정리하여, 이후에 다시 돌아보기 위함이다.
그러면서 아쉬웠던 점은 더 공부하여 남기기 위함도 있다.

참고로, 필자는 기술블로그와 공부TIL 블로그가 따로 있다.
TIL 블로그에는 공부한 걸 지금도 꾸준히 계속 글로 남기고 있다.
( https://jeondaehong.github.io/TIL/ )

오늘은 기술적인 질문을 위주로 글을 작성하였다.
그리고 면접 질문도 어떻게보면 대외비가 될 수 있기 때문에, 회사명은 적지 않았으며, 순서도 섞어서 포스팅 하였다.

또한 너~~~무 간단한 질문 역시 넣지 않았다.

 

 


본론

1)
[ 질문 ] :
여러가지 언어가 많은데, 웹 & 애플리케이션을 개발할 때 Java와 Spring을 사용하는 이유가 뭔가요?

[ 대답 ] :
  * Java는 JVM 기반으로 동작하는 언어이기 때문에 특정 OS에 한정되어 실행되지 않습니다. 그렇기 때문에 다양한 환경에서 사용해야하는 웹&애플리케이션을 개발할 때 유용합니다. Spring의 경우는 그런 Java를 가장 잘 쉽고, 잘 활용할 수 있게 해주는 프레임워크입니다. 특히 Java의 큰 특징으로는 객체지향이 있는데, Spring은 Spring Container를 통하여 그러한 객체지향의 특징을 잘 살리고 활용할 수 있게 도와주기 때문입니다.

[ 더 잘 대답했으면 좋았을 부분? ]
  * Java를 사용하는 이유에서 JVM의 특징을 좀 더 심층적으로 설명했으면 좋았을 거 같다. 예를들어 JVM 은 가상머신으로 OS위에 설치가 되므로, JVM만 설치 할 수 있으면 어떤 OS환경에서도 실행할 수 있고, 그 이유는 컴파일된 언어를 JVM에 맞는 바이트코드로만 변환하면 되기 때문임을 추가로 설명할 수 있으면 좋았을 거 같다.
 * Spring의 경우에도 IoC 제어의 역전이나, DI 의존성 주입을 추가로 설명하면 좋았을 것 같다. 우리가 Spring을 사용하는 가장 큰 이유가 SOLID 원칙을 잘 지키며 개발 할 수 있도록 도와주는 것인데, 이 부분을 좀 더 설명했으면 하는 아쉬움이 있다.
 * 그 밖에도 이미 많은 기업에서 사용하고 있고, 무료로 사용할 수 있는 DB나 IDE와도 활용하기 편하기 때문에 비용적 절감도 될 수 있는 점을 이야기 했으면 어땠을까 싶다. ( 너무 기술적인 답변만 하는 것이 아닌, 현실적인 답변도 섞는 것이다. )

 

 

2)
[ 질문 ] : 시간 복잡도에 대하여 설명해주세요

[ 대답 ] : 
  * O(n) 과 O(n^2) 을 예시로 설명드리자면, O(n) 은 코드가 실행된 횟수만큼의 시간을, O(n^2) 은 해당 코드가 말그대로 제곱번만큼 실행되었음을 의미합니다. 저희가 기본적으로 코드 1억회 실행에 1초 정도가 소요되는데 시간복잡도를 통하여 이 부분을 미리 어느정도 파악할 수 있습니다. O(n) 의 대표적인 예시로는 for문이 있고, O(n^2) 의 예시로는 이중for문이 있습니다.

[ 더 잘 대답했으면 좋았을 부분? ]
  * "문제를 해결하는데에 걸리는 시간과 입력의 함수 관계" 라는 정의를 먼저 명확하게 설명했으면 좋았을 것 같다. 그리고 우리가 사용하는 시간 복잡도는 Big-O 표기법을 보통 따르며 O(1) 이나 O(log n)과 같은 시간 복잡도의 다른 종류들도, 예시까지는 아니더라도 몇 가지 더 설명했으면 좋았을 거 같다.

 

2-1 꼬리물기 )
[ 질문 ] : 그럼 Sort(정렬) 알고리즘 중 하나를 설명해주시고, 시간 복잡도를 말씀해주세요

[ 대답 ] : 
  * 정렬에는 버블정렬, 선택정렬, 삽입정렬 등이 있습니다. 이 중 선택정렬을 예시로 들면 배열에  있는 인덱스를 순서대로 돌아가며 최소값을 찾고, 그 최소값과 자리를 바꾸는 정렬 알고리즘입니다.
( 이 때, 당황해서 시간 복잡도를 이야기하지 못하였습니다. )

[ 더 잘 대답했으면 좋았을 부분? ]
  * 시간 복잡도가 위에서 설명한 O(n^2) 인데.. 이걸 당황해서 이야기하지 못한게 너무 아쉬웠다.

 

 

3)
[ 질문 ] : 재고가 1개가 남았을 때, 동시에 2개의 스레드가 접근하여 제품을 구매하면 생길 수 있는 문제를 답변해주세요. ( 운영중인 서버가 한 대임을 가정합니다. )

[ 대답 ] : 
  * 멀티스레드가 동시에 접근하는 것을 방어하는 로직이 없다고 가정한다면, 동시성 이슈가 발생할 것이라고 생각합니다. 이를 해결하기 위해서는 여러가지 방법이 있는데, DB에 거는 비관적 락이나, Spring Data JPA를 활용하여 애플리케이션 단에서 막을 수 있는 낙관적 락 등이 있습니다. 그러나 서버가 한대고 해당 이슈를 빠르게 처리해야 한다면 우선 Syncronized 를 활용하여 동시에 스레드가 접근하는 것을 방어 할 것 같습니다.

[ 더 잘 대답했으면 좋았을 부분? ]
  * 이력서에 작성한, 이 전 회사의 이슈를 처리한 내용에 대하여 질문해주신 것 같은데, 잘 대답했다고 생각한다. 그래도 굳이 회고하자면 동시성 이슈가 무엇인지를 먼저 설명했으면 좋았을 것 같고, 동시성 이슈가 발생하는 이유를 설명하면 좋았을 것 같다.
( 톰캣에는 스레드 풀이라는 것이 있는데, 여기서 스레드를 할당받아서 들어가므로 동시에 여러개의 스레드가 접근 할 수 있으며, 그렇게 될 경우 A트랜잭션처리가 되어 남은 재고가 0개가 되기 전에, B트랜잭션에서 현재 재고인 1개를 또 가져가버려서 둘 다 물건을 주문하게 되는 현상이 동시성 이슈이다. )


 

4)
[ 질문 ] : 객체지향의 특징을 설명해주세요

[ 대답 ] : 
  * 공통적인 특징을 추출하여 정의한 추상화, 기존에 구현한 클래스를 재활용 할 수 있는 상속, 부모 인스턴스로 자식 클래스를 핸들링 할 수 있는 다형성, 외부로부터의 접근을 최소화하고 개발자의 의도대로 접근할 수 있게 클래스를 묶어버리는 캡슐화가 있습니다.

[ 더 잘 대답했으면 좋았을 부분? ]
  * 해당 답변을 마치고, 객체지향의 요소도 설명해 달라고 하였는데, 이 부분에 대하여 클래스, 필드, 메서드라고 답변을 하였다. 이후 찾아보니 정답은 객체, 클래스, 메시지(메서드), 상속 이렇게 4가지였다.



 

5)
[ 질문 ] : MyBatis 와 JPA 의 차이를 설명해주세요

[ 대답 ] : 
  * MyBatis 는 SQL 문을 별도의 XML 파일로 저장하고 객체와 SQL을 연결 시켜주는 기능을 하지만, JPA 는 ORM으로써 테이블과 Entity 를 매핑하여 데이터에 접근합니다.

[ 더 잘 대답했으면 좋았을 부분? ]
  * 좀 더 자세히 답변 할 수 있으면 좋겠겠지만, 필자는 Mybatis 와 JPA 에 대한 공부가 부족하였음. 면접 이후 이 부분을 공부하였고, 지금이라면 MyBatis의 장점으로는 SQL을 직접 제어하고, Join과 함께 복잡하고 긴 쿼리문을 사용해야하는 특정 도메인을 대상으로는 JPA보다 나을 것 같다고 답변할 것 같음. 또한 JPA에 비해 학습면에서 빠른 학습이 가능하다는 장점도 어필 할 것 같음.

 

5-1 꼬리물기 )
[ 질문 ] : 그럼 둘 중에 어떤 걸 사용하는게 성능적으로 좋을까요?

[ 대답 ] : 
  * 제 생각에는 직접적으로 쿼리문을 제어하는 MyBatis가 성능적으로는 더 뛰어나다고 생각합니다. 제가 이 부분에 대하여는 명확한 공부가 부족하여 더 자세한 답변은 하지 못하였습니다.

[ 더 잘 대답했으면 좋았을 부분? ]
  * Join 을 여러군데 사용해야하는 복잡한 쿼리문의 경우 Mybatis가 JPA보다 성능이 좋다는 부분을 이제 어필 할 수 있을 것 같다. 그 외의 간단한 쿼리 작업의 경우는 지연로딩이나 1차캐시 등이 있는 JPA가 성능적으로 이점이 있을 것 같다.

 

 

6)
[ 질문 ] : 웹에서 "송금" 버튼을 누르면 DB로 갈 때까지 벌어지는 일을 순차적으로 설명해주세요.

[ 대답 ] : 
  * 송금 버튼을 누르면, 프론트 단에서 작업되어 있는 코드에 따라 서버로 보낼 객체를 만들고, 서버에 Request 합니다. 그럼 서버의 톰캣의 스레드 풀에서 스레드를 할당 받아 웹 컨테이너에 있는 Filter 에 먼저 접근합니다. Filter 에서 직접 Request한 객체를 핸들링 할 수 있습니다. 이후 스프링 컨테이너로 접근하게 되는데, 처음에는 인터셉터를 거치게 되어 로그인이나 권한등을 체크하게 되고, 그 다음 AOP를 통한 인프라 로직이 있으면 그 인프라 로직을 실행한 후, 컨트롤러 -> 서비스 -> Mapper 순으로 동작하여 DB에 접근합니다. 이후 역순으로 번환 됩니다.

[ 더 잘 대답했으면 좋았을 부분? ]
  * 이 부분은 대답을 잘 한 것 같다. 그러나 조금 더 덧붙이자면 Dispatcher Servelet 과 preHandler, postHandler 에 대한 설명도 했으면 좋았을 것 같다.

 

 

7)
[ 질문 ] : 스프링과 스프링부트의 차이는 무엇인가요?

[ 대답 ] : 
  * 스프링부트는 스프링을 보다 쉽게 사용할 수 있게 만든 프레임워크입니다. 또한 스프링시큐리티나 스프링배치와 같은 기능을 설정 파일로 작성하지 않아도 사용할 수 있습니다.

[ 더 잘 대답했으면 좋았을 부분? ]
  * 스프링은 개발자가 직접 설정 파일을 작성하고, 빈 객체를 등록하고, 빈 객체 간의 의존성을 설정한다는 부분도 넣었으면 좋았을 것 같다. 하지만 결국 핵심은 개발자가 스프링을 보다 간편하게 사용할 수 있게 해준 것이 스프링부트임은 변함 없다.

 

 


결론

현재까지 기술적으로 질문 받은 내용은 이 정도이다.
아직 많은 곳들에서 면접을 보지 않았고, 면접을 보더라도 인성 면접이나 이력서 상의 내용을 다루는 면접 질문들이 더 많았다.

이후 면접을 보면, 면접에서 받은 기술 질문들은 계속해서 추가할 계획이다.

또한, 지금 이력서 수정과 면접 활동등으로 인해 F-lab 회고록을 올리지 못하고 있는데, 이 부분도 조만간 정리해서 올릴 계획이다.

마지막으로, 남는 시간에는 계속 코딩테스트 공부를 병행하는 중이며, 백준과 프로그래머스 위주로 풀고 있다.

꼭 내가 원하는 회사에 취업을 성공하고 싶다 !!!