기술면접 준비하기

aaron.park·2020년 2월 3일
379
post-thumbnail

2019-06-03 16:40 작성된 포스트


2019-12-06 추가)
어제(5일)자로 카카오 인턴십에 합격을 하였다. 그 동안 핑계로 미뤄왔던 포스팅을 보다 적극적으로 하여, 취준기간의 경험과 앞으로의 다짐, 생각 등을 포스팅 할 예정이다.

또한 본 게시글은 올해 여름에 웍스모바일 인턴십을 준비하면서 기록했던 포스트인데, 웍스모바일 한정된 내용을 삭제하고, 면접보러 다니면서 느꼈던 기업 공통적인 중요성 위주로 내용을 수정할 예정이다.
수정 전 내용은 따로 기록하지 않겠다. 낮부끄러운 말들이 많아서..

인턴 합격 후기는 이 다음에 따로 포스팅 할 예정.


2020-10-24 추가) 이 글이 인기가 많이 좋아져서(?) 따로 기술 면접 질문 모음 게시물을 작성했습니다!
나를 포함한 면접 준비생 분들께 도움이 됬으면 합니다!


그저께랑 어제 자료구조와 알고리즘을 정리하는데, 이미 알고있는 것을 정리하는 거라 간단할 줄 알았는데 생각보다 그렇지 않았다. 오래되서 기억이 잘 안나서 그렇거나, 원래 잘 모르는 것일수도..
아무튼 머리에 쥐날거 같은데 계속 알고리즘 정리하는 것보단, 잠시 환기 차원에서 면접 후기 등을 찾아보고, 남은 4일동안 공부해 가야할 것을 정리해야겠다.

  • 자기소개
    • 나의 장점, 단점
  • 자료구조
    • 손 코딩
    • 의사코드(pseudo-code)
  • 알고리즘
    • 손 코딩
    • 의사코드(pseudo-code)
  • 프로그래밍 지식 (소프트웨어 공학)
    • 가장 자신있는 언어
    • 특히 Java 의 데이터 타입(Array, ArrayList, LinkedList, Map, HashMap 등)과 그 외 전반적인 지식
    • MVC 구조란?
    • DTO, DAO, VO?
    • Restful 이란?
    • 젠킨스란?
    • 재귀
    • 로우 레벨 지식
    • OOP, AOP, FOP 등 프로그래밍 기법
    • 개발 방법론
  • 운영체제
    • 멀티 스레드 지식 (환경 구성 시 신경써야 하는 부분 등)
    • 스레드와 프로세스 차이
    • 동기, 비동기, 블로킹, 넌블로킹 차이
    • CPU 스케줄링
    • 프로세스 공간
  • 데이터베이스
    • 쿼리 속도 및 효율 향상법
    • 정규화
    • 인덱스
    • 로우 레벨 지식
  • HTTP 등 웹과 통신 지식
    • 주소창에 URL을 치고 엔터를 치면 흐름이 어떻게 되는가
    • HTTP/HTTPS 차이
    • CORS 이슈
    • OSI 7 계층 존재 이유
    • 로우 레벨 지식
  • 컴퓨터 아키텍쳐
    • 32비트, 64비트 차이
  • 디자인 패턴
  • 개인 프로젝트 경험
    • 진행하면서 어려웠던 점이 뭐고, 어떻게 극복했는 지? 사례 포함
  • 수업 경험
    • 가장 재밌었거나 기억나는 과목
  • 그 밖에 꼬리물기 식 질문이 많음

이 이외에, 핵데이 당시 멘토님의 조언은 다음과 같다.

  • 기본적인 것들을 착실히 공부해서 준비하라.
  • 시간복잡도 등 알고리즘 효율 생각하라.
  • Hackday 신청 당시 제출했던 자소서 기반으로 면접 준비하라.
  • Hackday 당시 진행했던 프로젝트 경험, 느낀 점 및 부족했던 점 보완해라.
  • GIF 만들기 프로젝트였던 만큼, 이미지 지식을 보충해서 가라.

추가로, 후기에서 말하고 있거나, 개인적으로 느낀 면접 TIP으로는 다음과 같다.

  • 당연한 말이지만, 위축되지 않고 당당한 자세
  • 과장되지 않고, 솔직하게 답변
  • 모르는 것은 모른다고 말하며, 면접관을 속이려 들지 말 것
  • 꼬리물기 식 질문이 많다고 하니, 답변을 추상적으로 하지 말고 구체적으로 하며, 잘 아는 쪽으로 답변할 것
    (즉, 질문 유도가 가능하다!)
  • 면접관이 꼰대 개발자일 수 있다. 이에 맞춰서 준비할 것
    (여기서 말하는 꼰대는 나쁜 뜻이 아니다. 자신의 개발 주관이 철저한 개발자를 뜻한다. 오히려 난 개발자는 꼰대여야 한다고 생각한다. 왜냐면 자신의 뚜렷한 주관없이 개발을 하게 된다면, 코드가 들쑥날쑥, 이랬다저랬다 할 수 있기 때문. 그렇다고 의사소통을 안하려 한다면 곤란하겠지만..)
  • 여러개를 짧게 답하는 것보다, 하나를 깊게 답하는게 나을듯

여기까지가 공부해야 할 점 정리였고, 아래는 실제 내용 정리이다.

자기소개

자기소개를 외워갈 필요는 없지만(있나?), 포함시켜야 할 점들을 정리하였다.

  • 서론 : 인사말, 자신을 표현
  • 본론 : 자신의 강점 어필
  • 결론 : 본론에서 언급한 강점이 어떻게 회사에 도움이 되는지 어필, 끝맺음
  • 자소서에 있는 내용을 활용, 키워드로 분명하고 확고하게 소개, 나만 해본 것을 키워드로 선정
  • 자신의 강점과 회사의 주력 제품의 일치성 어필

예시) 안녕하십니까! OOO에 지원하게 된 개발 벌레, 박현국입니다. 흔히 책을 즐겨 읽는 사람을 책벌레, 공부를 열심히 하는 사람을 공부벌레라고 하듯이, 저는 제 자신을 개발을 즐기면서 열심히 하는 개발 벌레라고 생각합니다.
제가 생각하는 저의 강점은 크게 두 가지가 있습니다. 첫 번쨰는 도전정신입니다. 저는 해커톤, 공모전 등의 활동을 두려움 없이 도전하여, 우수참가자로 선정되는 성과를 내었습니다. 두 번째는 소통력입니다. 저의 귀는 항상 열려있으며, 저는 팀원의 피드백과 조언을 적극 수용 및 존중하고, 저만의 스킨십으로 협업함으로서 프로젝트를 성공으로 이끈 경험이 있습니다.
저는 이러한 강점을 OOO에서 일하면서 살릴 수 있다고 생각합니다. 저는 저에게 어떤 업무가 주어져도, 저만의 도전정신으로 임할 것이며, 팀원과 소통 및 협업하여 목적을 달성하고, 최종적으로 OOO이라는 기업의 목적을 달성하겠습니다. 감사합니다.

위 예시와 같이 자기소개를 짜면 될 듯 하다. 이때 회사마다 서론과 결론을 바꾸는 것도 전략.

Java

Java의 Collection

자바의 대표 Collection에는 List, Map, Set, Stack, Queue와 같은 것들이 있다. 이 추상화된 Collection 인터페이스 아래, 특정한 기법으로 구현된 자료구조가 들어간다. 예를 들어, List라는 인터페이스에는 구현방법에 따라 ArrayList가 들어갈 수도, LinkedList가 들어갈 수도 있다.

  • List
    • ArrayList
      자바의 Vector를 개선한, 배열로 구현된 List이다. 그 말인 즉슨, 데이터가 저장된 순서가 같다는 말이다. 사실상 배열과 같은 자료구조이기 때문에, 리스트의 연산 자체의 수행시간 속도는 배열과 같다.
    • LinkedList
      다음 노드의 주소를 기억하고 있는 List로, 배열에 비해 삽입과 삭제가 간단하다. 그러나 탐색의 경우 첫 번째 노드부터 탐색해 나가야 하기 때문에 느리다.
  • Map
    • HashMap
      가장 일반적으로 사용하는 Map. HashTable을 사용, Key값에 해시함수를 적용하여 나온 index에 Value를 저장하는 식. 중복성을 허용하지 않으며, 순서가 없다는 것이 특징
    • TreeMap
      Red-Black Tree 자료구조를 이용한 Map이다. Tree 구조이기 때문에 어느 정도 순서를 보장한다.
    • LinkedHashMap
      LinkedList로 구현된 HashMap이다. List로 구현되어있기 때문에 순서가 보장된다. 하지만 LinkedList 특성상 랜덤 접근에서 느릴 수 있다.
  • Set
    • HashSet
      HashMap에서 Key값이 없는 자료형. 집합이라고 생각해도 무방하다. 값이 포함되어 있는지 아닌지만 관심이 있다. 순서를 보장하지 않으며, 중복값을 허용하지 않는다. Set중에는 가장 많이 사용된다.
    • TreeSet
      Red-Black Tree 자료구조를 사용한 Set.
    • LinkedHashSet
      LinkedList로 구현된 HashSet. 순서를 보장한다.
  • Stack & Queue
    • Stack
      직접 new 연산자로 객체를 생성하여 사용 가능.
    • Queue
      LinkedList 에 new 연산자로 객체를 생성함으로서 사용 가능.

추가로 자바 Array와 ArrayList의 다른점.
둘 다 배열이라는 점은 동일하나, Array는 인덱스로 접근하는 반면, ArrayList는 메서드를 통해 접근한다(어짜피 Index로 호출한다는 점은 동일 하겠지만..). 또한 Array는 Object 뿐만 아니라 원시 형태(Primitive, 예를 들어 int, double 등)도 담을 수 있지만, Array는 Object형(Reference, 객체)만 담을 수 있다. 따라서 정수를 ArrayList에 넣을 경우 Integer형은 가능하지만 int형은 안 된다. 덧붙여서, Integer처럼 int와 같은 원시타입을 담을 수 있는 객체를 Wrapper Class라고 한다.

OOP, AOP, FP

각각의 프로그래밍 기법에 대해 설명할 수 있어야 한다. 특히 OOP는 단골 질문이라 하니 중요.

  • OOP (객체지향 프로그래밍) (중요)
    객체지향 프로그래밍은 컴퓨터 프로그래밍 패러다임(견해, 사고법)의 하나로, 프로그래밍에서 필요한 데이터를 추상화 시켜서 상태(속성, 어트리뷰트)와 행위(메서드)를 가진 객체 로 만들고, 그 객체간의 상호작용을 통해 로직을 구성하는 방법.

    • 장점
      • 다른 클래스를 가져와 사용할 수 있고, 상속받을 수 있어 코드의 재사용성 증가
      • 절차지향보다 유지보수가 간단
      • 클래스 단위로 모듈화가 가능하여, 대형 프로젝트에 적합
    • 단점
      • 처리속도가 상대적으로 느리다.
      • 객체가 많으면 용량이 커진다.
      • 설계시 많은 노력과 시간이 필요하다.
    • OOP의 6가지 키워드
      • 클래스
        현실 세계의 객체를 추상화시켜, 속성과 메서드로 정의한 것 (논리적 개념)
      • 인스턴스
        클래스에서 정의한 것을 토대로 만든 실제 메모리상에 할당된 것, 실제 데이터
      • 추상화
        객체지향 관점에서 클래스를 정의하는 것, 불필요한 정보 외 중요한 정보만 표현함으로써 공통의 속성과 기능을 묶어 이름을 붙이는 것.
      • 캡슐화
        코드를 수정없이 재활용 하는 것을 목적으로 함. 클래스라는 캡슐에 기능과 특성을 담아 묶는다. 목적을 기준으로 묶는다.
        은닉화와의 차이 - 은닉화는 캡슐화의 일부라고 볼 수 있으며, 목적으로 묶인 캡슐 안을 사용자는 볼 수 없다는 것이 은닉화.
      • 상속
        클래스로부터 속성과 메서드를 물려받는 것을 말함. 다른 클래스를 가져와서 수정할 일이 있다면, 그 클래스를 직접 수정하는 대신 상속을 받아 변경하고자 하는 부분만 변경
      • 다형성
        하나의 변수명이나 함수명이 상황에 따라 다르게 해석될 수 있음. 대표적인 다형성이 오버라이딩과 오버로딩
    • OOP의 5가지 법칙 (SOLID)
      • Single Responsibility Principle, 단일 책임 법칙
        각 클래스는 목적을 하나씩만 가지고 그에 대한 책임을 져야 한다.
      • Open Close Principle, 개방 폐쇄 법칙
        각 클래스는 클래스에 대한 수정을 폐쇄하고, 확장에 대해 개방해야 한다.
        즉 클래스를 수정해야 한다면 그 클래스를 상속, 즉 확장하여 수정한다.
      • Liskov Substitusion Principle, 리스코프 치환 법칙
        자식 클래스를 사용 중일때, 거기에 부모 클래스로 치환하여도 문제가 없어야 한다.
      • Interface Segreation Principle, 인터페이스 분리 법칙
        각 행위에 대한 인터페이스는 서로 분리되어야 한다.
        핸드폰을 예로 들면, 전화를 하는데 핸드폰 카메라가 방해가 되면 안된다는 말.
      • Dependency Inversion Principle, 의존성 역전 법칙
        상위 클래스가 하위 클래스에 의존하면 안된다는 법칙. 즉 기본적인 공통되는 속성을 하위 클래스에 의존하면 안된다.
  • AOP (관점지향 프로그래밍)
    스프링 프레임워크의 핵심 요소 중 하나. 비즈니스 로직과 공통 모듈로 분리하고, 핵심 로직 사이사이에 공통 모듈을 잘 끼워 넣는 것을 말함. 이때 공통 모듈을 코드 밖에서 설정된다는 것이 핵심. 인증, 로깅, 트랜잭션 처리에 용이.

  • FP (함수형 프로그래밍)
    함수형 프로그래밍은 선언형 프로그래밍으로, 어떻게(How)가 아닌 무엇(What)을 정의한다. C, Java등의 언어는 명령형 프로그래밍이며, 알고리즘을 기술하고 목적은 기술하지 않는다. 선언형은 반대로 알고리즘은 기술하지 않고 목적 위주로 기술하며, 데이터의 입력이 주어지고 데이터의 흐름을 추상적을 정의하는 방식.

객체지향은 동작하는 부분을 캡슐화하여 이해를 돕고, 함수형은 동작하는 부분을 최소화하여 이해를 돕는다.

Stream API

SteamAPI는 Java의 Collection에서의 연속된 데이터의 반복 연산을 for문 등을 쓰지 않고, 추상화된 메서드를 통해 무엇(What)을 할 것인지 정의. 즉 FP이다. 스트림을 생성하는 최초연산, 중간의 로직을 구성하는 중간연산, 결과물을 처리하는 최종연산으로 나뉜다. 중간연산의 리턴값은 스트림으로, 계속해서 메서드 체이닝을 해 나갈 수 있다. 최종연산의 리턴값은 스트림이 아니며, 최종연산이 수행되지 않는다면 중간연산 역시 수행되지 않는다.

MVC 구조란?

모델-뷰-컨트롤러의 약자로, 디자인 패턴의 하나이다. 비즈니스 처리 로직과 사용자 인터페이스를 구분시켜 서로 영향없이 개발이 가능하다는 장점이 있다(MVC패턴).

모델(Model)은 어플리케이션이 "무엇"을 할 지에 대한 정의한다. 처리되는 데이터, 데이터베이스, 내부 알고리즘 등 내부 비즈니스에 관한 로직의 처리를 수행한다. 즉 사용자에게 보이지 않는 로직.

뷰(View)는 말 그대로 사용자에게 보여지는 영역이다. JSP등 사용자 인터페이스를 담당한다.

컨트롤러(Controller)는 모델에게 "어떻게"할 것인지를 알려주며, 모델과 뷰 사이를 연결하는 역할을 한다. 사용자의 입출력을 받아 데이터를 처리한다.

JVM

JVM에 대한 내용을 따로 정리하여 따로 포스팅하였다.
https://velog.io/@hygoogi/JVM-%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%9E%91%EB%8F%99-%EC%9B%90%EB%A6%AC

아직 미완성

GC

GC에 대한 내용을 정리하여 따로 포스팅하였다.
https://velog.io/@hygoogi/%EC%9E%90%EB%B0%94-GC%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C

아직 작성 중....

스프링 및 웹 개발

스프링 MVC에서의 컴포넌트
View - Jsp, Controller - Java Class, Model - JavaBean

컨테이너란?
프레임워크 안에서 인스턴스들의 생명주기를 관리하며, 생성된 인스턴스들에게 추가적인 기능을 부여한다. 내가 작성한 코드의 처리과정을 컨테이너에서 수행한다. 스프링 컨테이너는 스프링 프레임워크 핵심에 위치하여, DI를 통해 애플리케이션을 구성하는 컴포넌트들을 관리한다.

IOC 란?
Inversion Of Control, 제어의 역행이라는 뜻으로, 인스턴스의 생성 및 소멸을 개발자 대신 스프링 컨테이너가 한다. 그외 제어권을 프레임워크에서 가져간다는 말로도 쓰인다.

DI 란?
Dependency Injection, 의존성 주입이라는 뜻으로, IOC를 실제로 구현하는 방법. 의존성이 있는 컴포넌트를 개발자가 코드로 명시하는 것이 아니라 Spring이 런타임에서 연결해 처리해준다. XML파일을 통해 설정한대로, Bean객체 생성시 의존성 주입을 수행한다.

흐름(웹브라우저에서 Spring MVC로 요청했을 떄)
요청된 URL을 dispatcher-servlet에 전달 -> 핸들러 매핑(매핑 핸들러가 아닌듯)은 해당 URL에 매핑된 컨트롤러가 있는지 검사 후 컨트롤러에 전달 -> 해당 컨트롤러가 로직을 처리 -> 결과를 ModelAndView 객체 생성 후 담아 dispatcher-servlet에 전달 -> dispatcher-servlet은 전달 받은 View(jsp)가 있는지 검사하기 위해 ViewResolver로 보냄 -> ViewResolver는 받은 View(jsp)가 있는 지 검사 후 View로 보냄 -> View에서 Model과 같이 View(jsp)를 그린 후에 dispatcher-servlet으로 전달 -> 최종적으로 컨텐츠를 클라이언트에게 전달.

Bean 객체란?
자바에서의 POJO(Plain Old Java Object)로, XML 설정파일을 통한 생명주기, 종속성 등의 메타데이터를 가지고 스프링 컨테이너에서 생성된 객체이다. 컨테이너에서 생성되었다는 점을 제외하면 일반 자바객체와 같다.

DTO, DAO, VO 용어 정리

VO 란?
Value Object의 줄임말로, 값을 갖고있는 객체이다. 비즈니스 값을 가져올 때 사용하며, 보통 값을 수정할 수 없는 것으로 한다. DTO와 혼용해서 쓰기도 한다.

DTO 란?
Data Transfer Object의 줄임말로, VO와 같이 값을 갖고 있는 객체이다. VO와의 차이점은 DB로 치자면 하나의 인스턴스로, 데이터 핸들링에 사용되는 객체이다. DTO를 통해 데이터를 전달할 수 있다.

DAO 란?
Data Access Object의 줄임말로, 실제 DB에 접속하는 객체이다. Service와 DB사이에서 가져온 데이터를 엔티티로 변환시켜 가져온다. 대부분의 CRUD API를 제공한다.

Restful 이란?

REST란 REpresental State Transfer의 약자, 자원을 표현하여 상태를 전달한다는 뜻으로, 웹에 있는 자원을 HTTP를 통하여 직관적으로 전달하기 위한 간단한 인터페이스이다. Restful API는 대부분의 데이터를 JSON형식이나 XML형식을 담아서 HTTP 프로토콜 위에서 통신하는 API 인 것이다.
Restful 하다는 것은 REST 법칙에 통과한 것을 말하는데, 그 법칙은 다음과 같다.

  1. 자원
  2. 메소드(Method: GET, POST, PUT, DELETE)만으로 표현
  3. 동사말고 명사만
  4. 확장자는 포함하지 않음

즉 'naldo'라는 사용자를 찾는 URL 메서드를 설계할 때, Restful하다고 할 수 있는 예시는
/users/naldo (GET)
가 될 것이다.

메서드 종류 :
GET : 조회
POST : 추가
PUT : 수정
DELETE : 삭제

이런 메서드를 CRUD 연산과 연결지어서 사용 가능 (Create, Read, Update, Delete)

AJAX란?

Ajax란 좁은 의미로 클라이언트에서 서버가 비동기적으로 통신하는 기술
HTTP 요청 시 XMLHttpRequest라는 객체를 생성하여 수행한다.

request요청의 상태가 변할 때, readyState라는 플래그가 변하며, onreadystatechange라는 함수를 호출하게 된다.
readyState 상태 플래그
0 : 객체 생성 완료, open()함수 호출 전
1 : open()함수 호출 성공
2 : send()함수 호출 성공
3 : recv()함수 호출, 데이터 다운로드 중
4 : Done, 모든 작업이 끝남

운영체제

프로세스와 스레드

프로세스 는 실행 중인 프로그램이다. 디스크에서 메모리로 적재되어, CPU 자원의 할당을 받을 수 있는 것을 말한다. 프로세스 에 할당되는 메모리 안에는 스택, 힙, 데이터, 코드 영역을 포함한다.

PCB 란 Process Control Block의 약자로, 프로세스 제어 블록이다. 프로세스에 대한 중요한 정보를 저장하고 있다. 운영체제가 프로세스를 표현한 것이라고도 한다. 프로세스 생성시 만들어지며, 주기억장치에 유지된다. 문맥전환 등 다른 프로세스를 처리해야 할 때, PCB에 현재 상태를 저장함으로써 나중에 그 작업 상태를 불러와 작업 재개가 가능해진다. PID, 상태, 다음 명령어 주소 등의 정보가 저장됨.

PC 란 Program Counter의 줄임말로, 다음에 실행될 명령어의 주소가 들어있는 레지스터이다. 명령어가 인출되면, 자동으로 다음 명령어를 가리키도록 주소값이 증가된다.

캐시메모리 란 CPU의 레지스터와 메모리 사이에서, 캐싱을 통해 병목 현상을 완화하는 것을 말한다.

스레드 는 프로세스의 작업 실행 단위이다. 즉 멀티스레드라는 것은 한 프로세스 내에 여러개의 프로그램의 흐름을 말한다. 스레드간에는 프로세스의 주소나 자원을 공유할 수 있다. 스레드는 스레드 ID, PC, 레지스터 집합, 스택으로 구성된다. 스레드 간에는 각자 독립적으로 작업을 수행해야 하기 때문에, 각각 스택과 PC 레지스터를 받는다.

멀티 스레드 환경

하나의 프로세스에서 다수의 실행 단위로 구분하여 자원의 생성과 관리의 중복성을 최소화하여 효율을 높이는 것을 멀티 스레딩이라고 한다.

장점 :

  • 멀티 프로세스에 비해 메모리와 자원의 소모가 줄어든다.
  • 힙 영역을 사용하면 프로세스간 통신에 비해 스레드간 통신이 훨씬 간단하다.
  • 스레드의 문맥전환은 캐시메모리를 비울 필요가 없어 프로세스의 문맥전환에 비해 더 빠르다.
  • 그러므로, 시스템의 처리량이 늘며, 공간과 시간, 자원이 절약된다.

단점 :

  • 힙 영역을 공유하기 때문에, 해당 자원을 사용할 때 동기화를 해주어야 함.
  • 동기화를 위해 과도한 락 사용시 병목 현상때문에 성능이 저하될 수 있음

멀티 스레드 VS 멀티 프로세스
이 두 가지는 실행 단위를 구분한다는 점은 같지만, 멀티 스레드는 자원을 덜 소모하는 대신 하나의 스레드가 비정상적인 오류를 일으키면 다른 스레드도 종료될 수가 있다는 점과 동기화 문제를 안고 있다. 멀티 프로세스는 자원을 공유하지 않기에 서로간 통신이 멀티 스레드보다 불편하고, CPU 자원을 더 많이 소모한다. 결국 상황에 맞게 골라서 써야한다.

멀티 프로세싱과 멀티 프로그래밍 멀티 태스킹

CPU 코어의 관점에서 생각
CPU 코어 여러개로 프로세스를 여러개 수행한다 -> 멀티 프로세싱
CPU 코어 하나로 프로세스를 여러개 수행한다 -> 멀티 프로그래밍
CPU 코어 몇 개를 쓰던 간에 작업을 수행한다 (프로세스보다 확장된 의미) -> 멀티 태스킹

프로세스(스레드)의 동기화

경쟁 상태 (Race Condition) :
경쟁 상태란 두 개 이상의 프로세스 혹은 스레드가 공유 자원을 동시에 사용할 때 그 순서에 따라 결과가 달라지는 문제.
은행 잔고를 예제로 들면 은행 잔고라는 공유 데이터를 읽어와서 입금 연산과 출금 연산을 하는데, 동시에 접근해서 연산해버리면 한 쪽 연산이 반영이 안되는 문제

임계영역과 크리티컬 섹션 :
사전상으로는 같은 말이지만, 의미하는 바가 다를 수 있다.
임계영역은 프로세스간 자원이 공유될 수 있는 코드 블록을 의미하며, 크리티컬 섹션은 하나의 동기화 방법을 말한다. 임계 영역을 프로세스들이 같이 쓸 수 있는 전제 조건은 다음과 같다.

  • 상호 배제 (Mutal Exculsion) : 프로세스가 크리티컬 섹션에 들어가 있다면, 다른 프로세스는 크리티컬 섹션에 들어갈 수 없다.
  • 진행 (Progress) : 크리티컬 섹션에 들어가 있는 프로세스가 없다면 다른 후보 프로세스가 진입할 수 있다.
  • 한정된 대기 (Bounded Waiting) : 프로세스가 진입 가능한 횟수에는 제한이 있다(특정한 한 프로세스만 계속 진입하는 것을 방지).

Lock :
하드웨어 기반 처리로, 임계 영역에 진입하기 위해서는 Lock이 필요하다. 임계 영역에 들어가는 프로세스는 Lock을 획득하고, 빠져나올때 Lock을 반납한다. 다중 처리기 환경에서 성능을 보장할 수 없다.

세마포어 :
OS는 카운팅/이진 세마포어를 구분한다.

  • 카운팅 세마포어 : 동시에 사용가능한 자원에 대해 사용되며, 임계영역 안에 스레드나 프로세스가 들어오면 카운트를 증가시켜, 일정 숫자만큼의 스레드만 사용하게 하는 것
  • 이진 세마포어 : 0과 1로만 된 세마포어로, 임계영역 안에 하나의 프로세스만 들어갈 수 있다. 뮤텍스라고도 함.

단점 :
Busy Waiting : 임계 영역에 진입하려는 프로세스는 계속해서 진입하는 코드를 실행해야 한다. 따라서 성능의 저하가 발생할 수 있음.

세마포어에서도 데드락이 발생할 수 있다.

모니터 :
고급 언어의 개념으로, 추상화 메서드를 통해 동기화함. 세마포어에 비해 간단.

데드락

멀티 프로그래밍 환경에서 CPU와 같은 한정되고 공동된 자원을 사용할 때 데드락이 발생할 수 있다.
예를 들어 프로세스 A가 자원 1을 사용 중인 상태에서 자원 2를 사용하려고 하지만 프로세스 B가 자원 2를 이미 사용하고 있어 대기중이다. 그런데 프로세스 B가 자원 2 사용을 끝내려면 자원 1이 필요한데, 프로세스 A가 이미 자원 1을 사용하고 있기 때문에 대기해야 한다. 즉 서로의 자원을 쓰고 싶은데 서로가 쓰지를 못하니 무한 대기상태가 걸리는데 이를 데드락, 교착상태라 한다.

데드락의 발생 조건 4가지(모두 만족해야 함) :
상호 배제 : 한 자원은 한 프로세스에 의해서만 사용됨, 두 개 이상 사용 불가
점유 대기 : 프로세스는 자원을 가진 채 다른 자원을 기다릴 수 있음
비선점 : 다른 프로세스가 사용 중인 자원을 강제로 가져올 수 없음
순환 대기 : 프로세스의 집합에서, 각 프로세스는 순환적으로 다음 프로세스가 필요로 하는 자원을 가지고있다.

데드락 해결법 :
예방 : 4가지 조건 중 하나라도 만족되지 못하게 함
회피 : 알고리즘을 데드락이 발생하지 않도록 적용
회복 : 교착상태가 발생하면 그때 해결함
무시 : 회복과정의 성능저하가 더 심하다면 그냥 무시함

컨텍스트 스위칭

멀티 프로세스 환경에서 CPU 스케줄러가 인터럽트 발생 시 현재 프로세스의 상태를 PCB에 저장하고, 새로운 프로세스의 상태를 레지스터에 저장하는 것을 말함.

인터럽트의 종류 :
I/O Request : 입출력 요청
Time Slice Expired : CPU 사용시간 만료
Fork Child : 자식 프로세스 생성
Wait for interrupt : 인터럽트 처리 대기

컨텍스트 스위칭 시 CPU는 아무런 작업을 하지 못한다. 따라서 잦은 컨텍스트 스위칭은 성능 저하를 일으킴.

CPU 스케줄링

스케줄러란 CPU와 같은 자원을 우선순위에 기반하여 프로세스에 할당하는 방법을 말한다. 그 Queue에는 세 가지가 있다.

  • Job Queue : 현재 시스템 안에서 돌고 있는 프로세스의 집합
  • Ready Queue : 메모리 안에서 CPU의 할당을 기다리는 프로세스의 집합
  • Device Queue : 장치 입출력을 기다리고 있는 프로세스의 집합

스케줄러의 종류 세 가지 :

  • 장기 스케줄러 (잡 스케줄러) : 프로세스가 한꺼번에 많이 올라올 시, 메모리와 디스크 사이에서 메모리에, Ready Queue에 어떤 걸 집어넣을지 결정
  • 단기 스케줄러 (CPU 스케줄러) : CPU와 메모리 사이에서 Ready Queue에 있는 프로세스 중 어떤 것을 CPU 할당을 받게 할지 스케줄링
  • 중기 스케줄러 (Swapper) : 여유공간 부족 시 공간을 만들기 위해 메모리에서 쫓아내어 디스크로 옮김, 동시에 메모리가 많이 올라가는 것을 조절

CPU 스케줄링 방법 :
스케줄링 대상은 Ready Queue에 있는 프로세스 대상이다.

  • FCFS (First Come First Served) : 먼저 온 녀석이 먼저 스케줄링을 받음. 중간에 반환하지 않는 비선점형이며, 시간이 긴 프로세스가 먼저 오면 효율성이 떨어짐
  • SJF (Short Job First) : 늦게 오더라도 수행시간이 짧은 프로세스에 먼저 할당. 이렇게 되면 수행시간이 긴 프로세스는 영원히 할당받지 못할 수도 있음(Starvation). 수행시간(CPU Burst Time)은 알지는 못하고 예측만 가능하며, t가 실제시간, r이 예상 시간일때 rn+1=αtn+(1α)rnr_{n+1} = \alpha t_n + (1 - \alpha)r_n (α\alpha값은 가중치)
  • SRT (Short Remaining Time) : 현재 프로세스의 수행시간이 끝나는 시간보다 나중에 오는 프로세스의 수행시간 완료 시간이 더 짧다면, 그 즉시 그 프로세스에게 CPU를 할당. 선점형 스케줄링. Starvation과 CPU 수행 시간을 측정할 수 없다는 문제가 있음
  • 우선순위 : 정수로 표현된 우선순위가 더 높은 프로세스에게 할당한다. 선점형 방식과 비선점형 방식으로 나눌 수 있는데, 선점형 방식은 우선순위가 높은 프로세스가 도달하면 그 즉시 그 프로세스에게 CPU를 할당. 비선점형 방식은 Ready Queue의 맨 앞에 그 프로세스를 등록. Starvation과 CPU를 사용못하는 프로세스를 CPU가 무한 대기하는 상태가 있을 수 있음. 오래 기다렸을 경우 우선순위를 높이는 Aging을 통해 해결 가능.
  • Round Robin : 현대적인 CPU 스케줄링으로, 각 프로세스는 동일한 CPU 할당 시간을 갖게 됨. 할당시간 만료시 ready queue 맨 뒤에 가서 줄섬. CPU의 사용시간이 제각각일 때 효율적. 반응 속도가 빨라지며, 공정한 스케줄링. 주의할 점은 할당하는 시간(time quantum)이 너무 길다면 FCFS와 다를게 없음. 너무 작다면 잦은 컨텍스트 스위칭이 발생.

동기, 비동기, 블로킹, 넌블로킹 차이

동기는 어떤 일에 대한 요청과 응답(혹은 입출력)이 동시에 이루어져야 하는 것
비동기는 어떤 일에 대한 요청과 응답이 동시에 이루어질 필요 없이 따로 이루어지는 것.
블로킹은 어떤 요청에 대한 응답이 올 때까지 대기 하는 것. 즉 동기를 위해서는 블로킹 되어야 함
넌블로킹은 어떤 요청에 대해서 응답을 대기하지 않고 계속 루틴을 수행하는 것. 비동기를 위해서는 넌블로킹 되어야 하지만, 넌블로킹이 비동기는 아니다(포함관계라고 생각하면 될 듯). 예를 들어 넌블로킹이면서, 요청에 대한 응답을 계속해서 요구하는 폴링 방식의 경우, 비동기라 보기는 힘들다. 이벤트 핸들러나 인터럽트를 통해 응답을 받는 것이 비동기 모델.

메모리

단편화 :
단편화란 메모리 상에서 적재되고, 해제되는 과정에서 발생하는 메모리 사이의 사용하지 못할 정도로 작은 빈 공간이다. 크게 외부 단편화와 내부 단편화로 나뉜다. 외부 단편화는 프로세스와 프로세스 사이에 발생하는 빈 공간이고, 내부 단편화는 프로세스 안에서 발생하는 빈 공간이다. 외부 단편화는 메모리를 다시 재정렬하는 압축을 통해 해결할 수 있지만, 효율이 좋지 않다.

First Fit : 메모리를 할당할 때, 가장 먼저 발견한 곳에 집어넣음
Best Fit : 메모리를 할당할 때, 사용 가능한 공간 중 가장 작은 곳에 집어넣음(정렬 필요)
Worst Fit : 메모리를 할당할 때, 사용 가능한 공간 중 가장 큰 곳에 집어넣음(정렬 필요)
공간 효율성 : Best Fit > First Fit > Worst Fit
시간 효율성 : First Fit > Best Fit = Worst Fit

가상 메모리 :
가상 메모리는 기존의 물리 메모리를 물리 메모리와 논리 메모리로 나눔으로써 더욱 효과적으로 쓰기 위한 개념이다. 논리 메모리 테이블은 물리 메모리와 보조기억장치 메모리와 매핑되어 있으며, 프로세스는 가상메모리를 물리 메모리처럼 인식하고 사용하게 된다. 이전에는 가상 메모리는 보조기억장치를 주기억장치처럼 쓰게 하는 것으로 알고 있었는데, 이번에 다시 정리하게 되었다.

페이징 :
외부 단편화의 압축 작업을 해소하기 위한 방법론으로, 물리 메모리는 Frame, 논리 메모리는 Page라는 고정 크기의 블록으로 나눈다. 프로세스를 페이지 단위로 나눈 뒤에, 사용하지 않는 영역을 보조기억장치에 적재한다. 이를 페이징 되었다고 하는데, 만약 이 페이징 된 영역에 접근해야 하면 페이징 폴트를 발생시킨 후 메모리에 적재시킨다(요구 페이징). 페이징된 정보는 페이징테이블에 저장된다. 단점으로는 내부 단편화가 발생할 수 있다.

세그멘테이션 :
메모리를 페이지와는 다르게 가변 크기의 세그멘테이션으로 나눈다(물리 메모리 블럭 크기와 다르다). 나누는 시점은 메모리를 사용하게 되는 시점이다. 각 세그멘테이션은 스택, 데이터, 힙, 코드 영역 등으로 나뉘게 된다. 나뉜 세그멘테이션은 시작 주소값과 길이 값이 세그멘테이션 테이블에 저장된다. 자주 사용하면 외부 단편화가 발생할 수 있다.

보통 페이징과 세그멘테이션 둘 다 사용한다고 한다.

가상메모리의 요구 페이징 과정에서 만일 물리 메모리가 모두 사용중일 경우, 페이징 교체가 이루어져야 한다.
교체 흐름 :

  1. 디스크에서 필요한 페이지의 위치를 찾는다.
  2. 페이지 교체 알고리즘을 통해 희생될 페이지를 찾는다.
  3. 찾은 페이지를 비운 후 새 프레임을 덮어쓰고, 테이블을 수정한다.
  4. 프로세스를 재시작한다(?).

페이지 교체 알고리즘 종류

  • FIFO (First In First Out) : 말 그대로 먼저 들어온 페이지를 먼저 내보낸다. 간단한 알고리즘이지만, 페이지의 중요도를 따지지 않기 때문에 초기 변수가 담긴 페이지를 내려버리는 등 여러 문제를 초래할 수 있다.
  • 최적 페이지 교체 (Optimal Page Replacement) : 앞으로 가장 사용되지 않을 페이지를 계산하여 교체한다. 다만 모든 프로세스의 계획을 파악하기가 쉽지 않기 때문에, 어떤 페이지를 교체해야 하는가의 알고리즘을 구현할 때 어려움이 있다.
  • LRU (Last Recently Used) : 가장 나중에 사용된 페이지를 교체한다. FIFO보단 낫고 OPT보단 못하다.
  • LFU (Least Frequently Used) : 가장 덜 사용된 페이지를 교체한다. 활발한 페이지는 사용이 많이 되었을거라는 가정하에 만든 알고리즘. 초기에 많이 사용되었다가 지금은 사용되지 않는 페이지의 경우 교체가 이루어지지 않는다는 문제가 있다.
  • MFU (Most Frequently Used) : 가장 많이 사용된 페이지를 교체한다. 가장 적게 사용된 페이지가 최근에 올라오고 계속 사용될 것이라는 가정. 잘 쓰이지 않는다.

웹과 통신

소프트웨어 공학과 동급으로 중요하다고 생각한다. 백엔드 개발인 만큼 웹으로 통신 해야하는 일이 많기 때문.

HTTP 요청 흐름 (웹브라우저에서의 요청)

면접 단골 질문

브라우저에서 먼저 URL에 적힌 값을 파싱하여, HTTP 요청 메세지를 만든다. 만든 메세지를 웹 서버로 전송하는데, 이때 웹 브라우저 직접 전송을 하는것이 아니라 OS에 보내주십쇼~ 하고 의뢰를 하게 된다. OS는 DNS서버를 조회해서 Host이름을 보내야 할 IP 주소로 변환하게 된다.

프로토콜 스택(운영체제에 내장된 네트워크 제어용 소프트웨어, TCP/IP 계층)과 LAN 어댑터 에서 브라우저로부터 메시지를 받는다. 브라우저로부터 받은 메시지를 패킷 속에 저장한다. 그리고 수신 주소를 제어정보에 덧붙인다. 그 다음, 패킷은 LAN 어댑터에 넘긴다. LAN 어댑터는 패킷을 전기 신호로 변환시켜 LAN 케이블에 송출하게 된다.

허브, 스위치, 라우터 에서 LAN 어댑터로부터 송신한 패킷을 수신한다. 라우터는 패킷을 ISP에 전달, 인터넷으로 들어가게 된다.

액세스 회선, ISP : 액세스 회선이라는 것은 인터넷의 입구에 있는 통신 회선이다. 액세스 회선에 의해 통신사용 라우터(POP, Point Of Presence)까지 운반된다. POP를 거쳐 인터넷의 핵심부로 들어가게 된다. 고속 라우터들 사이로 목적지까지 패킷이 흘러가게 된다.

방화벽, 캐시서버 : 인터넷 핵심부를 통과한 패킷은 목적지의 LAN에 도착하게 된다. 방화벽이 먼저 패킷을 검사한 후, 캐시서버로 보내서 웹 서버까지 갈 필요가 있는지 검사한다.

웹 서버 : 패킷이 물리적 웹 서버에 도착하면, 웹 서버의 프로토콜 스택이 패킷을 추출하여 메시지를 복원하고, 웹 서버 애플리케이션에 넘긴다. 애플리케이션은 요청에 대한 응답 데이터를 넣어 클라이언트로 회송한다. 온 방식 그대로 전송되게 된다.

HTTP/HTTPS 차이

HTTP + SSL = HTTPS

HTTP는 평문 통신이다. TCP/IP 특성상 도청이 가능하며, 통신 상대를 확인하지 않기 때문에 위장이 가능하다. 가령 나는 IP가 A인 사람한테 보내고 싶은데, 악의적인 해커가 내가 IP A요 하고 말해도 검증할 방법이 없다는 것. 또한 완전성을 증명할 수 없기 때문에 변조가 가능하다. 보안 방법은 통신 자체를 암호화(SSL, TLS)하거나, 콘텐츠를 자체를(HTTP 메시지 컨텐츠를) 암호화 하는 것이다. 도청이 가능한 문제, 사용자를 확인할 수 없다는 문제, 정확성을 보장할 수 없다는 문제를 모두 해결할 방안으로 나온 것이 HTTPS이다.

HTTPS는 새로운 프로토콜이 아닌, HTTP에서 SSL 개념을 더한 프로토콜이다. 기존 HTTP는 TCP와 직접 통신했지만, HTTPS는 HTTP와 TCP 사이에 SSL, TLS가 끼워져 있는 것이다. HTTP는 SSL과 통신하고, SSL은 TCP와 통신하게 된다.
SSL의 원리를 간략하게 설명하면, 대칭키와 공개키 방식 두 암호화 방식을 사용하는데, 먼저 클라이언트가 서버에게 HELLO 메세지를 보내면, 서버가 클라이언트에게 HELLO 메세지를 보내면서, 서버 암호화 된 인증서와 랜덤 데이터를 넘겨주게 된다. HELLO 과정에서 어떤 암호화 프로토콜을 사용할 것인지 협상한다. 클라이언트는 받은 인증서를 CA리스트에서 조회 후 CA 공개키를 사용하여 인증서를 복호화한다. 복호화에 성공 했다면 이 서버는 신뢰할 수 있는 서버이다. 서버가 보낸 랜덤 데이터와 클라이언트의 랜덤 데이터를 조합해서 대칭키를 생성한다. 서버로부터 받은 공개키(인증서)를 사용하여 대칭키를 암호화 후에, 서버에게 보내게 된다. 서버는 암호화된 대칭키를 받고, 비밀키로 복호화 함으로써, 서버와 클라이언트가 서로 대칭키를 가지게 된다. 이 대칭키로 통신을 암호화한다.

TCP/UDP 등 로우레벨 통신 지식

TCP 3-way hand shake, 4-way hand shake
TCP는 흐름제어, 오류제어를 통한 연결 지향성, 순서 중요함, 오류시 재전송. 전이중과 점대점(각 연결이 정확히 2개의 종단점을 가지고 있음) 방식.
UDP는 비연결형 프로토콜, 상대방이 받든지 말든지 그냥 보낸다. 손상된 세그먼트에 대해 재전송하지 않는다. 만약 클라이언트 timeout이 발생하면 다시 보내면 그만이다.

CORS란?

Cross Origin Resource Sharing 약자. 말 그대로 다른 도메인간의 자원 공유를 의미한다. 본래 대부분의 브라우저는 타 도메인 간 요청을 Same-Origin-Policy에 의해 차단한다. 이런 설정을 우회하기 위해 여러 방법이 있었지만, HTML5가 등장하면서 CORS가 등장했다. CORS는 헤더를 통하여 Cross-Domain간 사용가능한 자원을 헤더를 통하여 알려준다.

Preflight Request : 실제 요청을 보내도 안전한지 판단하기 위해 브라우저에서 먼저 보내보는 Request. Option 메서드로 전송하여 CORS를 허용하는 지 확인한다. CORS를 지원하는 웹서버라면 사용가능한 리소스를 헤더에 담아 응답한다.

HTTP HeaderDescription
Access-Control-Allow-Origin접근 가능한 URL 설정
Access-Control-Allow-Credentials접근 가능한 쿠키 설정 (true, false)
Access-Control-Allow-Headers접근 가능한 헤더 설정
Access-Control-Allow-Methods접근 가능한 메서드 설정

OSI 7 계층 및 TCP/IP 계층

우선 OSI7 정의 : 통신 접속에서 완료까지 과정을 7단계로 정의한 국제 통신 표준 규약. 물데넷트세프어
TCP/IP 4계층 : 통신에 실제 사용되는 계층(프로토콜 스택). 링크,네트워크,트랜스포트,어플리케이션으로 이루어짐. 링크 = 물리+데이터링크, 어플리케이션 = 세프어

왜 쓰는가?
통신이 일어나는 과정을 단계별로 파악하여, 문제 발생시 트러블슈팅이 용이하다. 즉 분할 정복이 가능하다.

멀티파트 업로드

멀티파트란 각 여러 파일을 바디 하나에 메타 정보와 데이터를 boundary를 기준으로 나눠놓은것.

디자인패턴

MVC 패턴

위 스프링 MVC 설명하면서 써놨다.

싱글톤 패턴

객체를 하나만 생성해서 사용하는 패턴.

데이터베이스

주) 데이터베이스는 시간 부족으로 생략, 따로 읽어가자..
https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/Database#%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4

그 밖에 예상 질문

  • 스프링 프레임 워크에 대해서 설명해 보아라.
    자바 플랫폼에서 사용되는 오픈소스 웹 어플리케이션 프레임워크이다. 특징으로는 가볍고, 제어의 역행을 지원하여 복잡한 부분을 개발자가 담당할 필요가 없습니다. AOP를 지원합니다. 확장성이 높습니다.

  • 가장 좋아하는 정렬은?
    병합정렬입니다. 어떠한 경우에도 수행시간이 같기 때문입니다.
    (그러나 질문자의 의도에 따라 답이 달라질 수 있다. 예를 들어 자릿수가 똑같은 사원수를 정렬하는 경우 사용할 정렬은?)

  • 마지막으로 한 마디?
    면접관 님들 부족한 저를 면접 봐주시고, 또 도와주시느라 고생 많으셨습니다! 저 또한 이번 면접을 통해 많은 것을 배우고 공부한 것 같습니다. 이를 바탕으로 한 층 더 나은 개발자가 되도록 하겠습니다! 감사합니다!

profile
애런 퐉의 블로그

12개의 댓글

comment-user-thumbnail
2020년 3월 1일

NavigableSet, JVM 같은부분 도 알아두시면 큰힘이 되실듯..!
잘 읽고 갑니다

1개의 답글
comment-user-thumbnail
2020년 3월 14일

와..두고두고 봐야할 글이네요

1개의 답글
comment-user-thumbnail
2020년 3월 15일

양이 상당하네요. ! 한 수 배워갑니다.

1개의 답글
comment-user-thumbnail
2020년 4월 3일

좋은 글 감사합니다!

답글 달기
comment-user-thumbnail
2020년 4월 20일

좋은글 감사합니다 ~ 너무 잘 정리 하신거 같아요!!

답글 달기
comment-user-thumbnail
2020년 4월 30일

글을 읽으면서 예전에 대학 다니면서 배웠던 내용들이 새록새록 기억이 나네요.
인터뷰 준비하면서 정말 잘 체계적으로 정리를 잘 하셨네요.
공유할께요. 페이스북에서 공유할 때 사진이 제대로 나오지 않아서 조금 아쉽네요.
https://www.facebook.com/softwareDeveloperInterview

답글 달기
comment-user-thumbnail
2020년 12월 20일

우와진짜 잘봤습니다 ㅠㅠ너무깔끔하게 잘정리해주셨네염 참고해서 열심히 준비해볼게여 ㅎㅎ!!

답글 달기
comment-user-thumbnail
2021년 5월 7일

Thank you for sharing an amazing article. I found it very helpful. This is my first time to visit here. I liked the information and most discussion part. Visit https://www.sevenmentor.com/java-classes-in-delhi

답글 달기
comment-user-thumbnail
2022년 5월 19일

잘 읽고갑니다!!

답글 달기