'개발자 지망생의 고군분투' 시리즈신입 개발자 기술면접 준비하기

문제는 이곳에서 발췌한 것과 제가 임의로 추가한 내용입니다. 아래에는 제가 아는 정도만 작성하였으며 지속적으로 추가할 예정입니다. 잘못된 지식에 대한 비판은 언제나 환영이며 적극적으로 수용하도록 하겠습니다.


전산 기초

개발상식

객체 지향 프로그래밍이란 무엇인가?

절차지향은 오로지 컴퓨터 관점에서의 프로그래밍 패러다임이라면 객체지향은 인간이 구분할 수 있는 요소를 객체로 표현한 인간 중심적 프로그래밍 패러다임이다. 객체는 기억장소와 이 기억장소의 값을 변경할 수 있는 연산의 집합 클래스가 정의되면 객체를 선언할 수 있다. 많은 객체 지향 언어에서 객체는 클래스로 그룹화 된다. 생성된 클래스로 객체의 특정 예를 생성하는데 이를 인스턴스라고 부른다. 객체 간의 정보 교환이 모두 메시지 교환을 통해 일어난다.

함수형 프로그래밍이란?

객체 지향 언어의 유일한 단점은 객체가 상태를 가지고 있다는 것이다. 함수형 프로그래밍에선 모든 오퍼레이션이 새로운 오퍼레이션을 가진다. 인풋을 변경시키지 않고 변경한 아웃풋만 제공한다. 대표적인 함수형 언어 Rust-Lang에서는 기본적으로 변수가 immutable로 선언되고 변수의 변경이 필요한 경우 mutable로 따로 선언해야 한다. 함수형 프로그래밍이 언제나 높은 효율을 보이는 것은 아니다. 상황에 따라 다르며 특히 맵리듀스를 해야하는 상황이라면 효율적이다.

RESTful API란 무엇인가?

REST는 자원(Resource), 행위(Verb), 표현(Representations)으로 구성된 웹의 장점과 HTTP의 우수성을 적극 활용할 수 있는 아키텍처이다. HTTP URI를 통해서 자원을 명시하고 HTTP Method(POST, GET, PUT, DELETE)를 통해서 해당 자원의 CURD 연산을 적용하는 것을 의미한다. 코드의 재사용성을 높일 수 있으며 프론트엔드와 백엔드의 완전한 분업이 가능하다.

TDD란 무엇이며 어떠한 장점이 있는가?

테스트 주도 개발(Test Driven Development), 테스트를 먼저 만들고 테스트를 통과하기 위한 코드를 작성하는 것을 의미하며 모듈화가 자연스럽게 잘 이루어지면서 개발이 진행된다. 테스트 커버리지가 높아져 리팩토링과 유지보수가 쉬워진다.

MVC 패턴이란 무엇인가?

모델, 뷰, 컨트롤러가 분리된 형태의 아키텍처. 세가지가 결합된 형태에서는 어플리케이션의 확장이 어렵다. 모델은 데이터 처리, 뷰는 사용자 인터페이스 처리, 컨트롤러는 비즈니스 로직을 처리하는 등 각각의 요소가 하나의 역할만 담당한다.

Git과 GitHub에 대해서

버전 관리를 위한 도구

Docker와 VM의 차이점

Dcoker는 하드웨어를 가상화하는 계층(Hyper-V)이 없으며, 호스트의 자원을 직접 이용하기 때문에 메모리 접근, 파일시스템, 네트워크 속도가 가상머신에 비해 월등히 빠르다.

자료구조

순차 자료구조 vs 연결 자료구조

순차 자료구조는 메모리 상에서 일렬로 나열된 데이터형이며 연결 자료구조는 메모리 상에서는 분산되어 있지만 하나의 노드가 다음으로 이어지는 포인터를 가지고 있어 연속적으로 접근이 가능한 데이터형이다.

  • 데이터 삽입 : 순차 자료구조의 마지막에 데이터를 삽입하는 경우는 빠르지만 처음과 중간에 삽입하는 경우에는 자리교환으로 인한 오버헤드가 발생하여 느리다. 연결 자료구조는 데이터를 어디에 삽입하던 해당 위치까지 엑세스하는 시간만 소요되지만 자료 추가시 링크만 교체하면 되므로 빠르다.
  • 데이터 읽기 : 연결 자료구조는 위치를 알던 모르던 관계없이 헤더부터 찾으려는 위치까지 탐색해야 하므로 느리다. 순차 자료구조는 탐색하려는 위치를 알고 있다면 즉시 엑세스 할 수 있으므로 빠르며 탐색하려는 위치를 모른다고 하더라도 메모리 상에서 근접한 데이터의 접근이 더 빠르므로 연결 자료구조보다 빠르다.
스택과 큐

스택은 가장 먼저들어온 개체가 가장 마지막에 나가는(Last in first out, LIFO) 방식을 사용하는 자료구조이며 대부분은 펜케이크에 비유하곤 한다. 아래에서 위로 데이터를 쌓고 위에서 아래로 데이터를 지운다. 큐는 가장 먼저 들어온 개체가 가장 먼저 나가는(First in first out, FIFO) 방식을 사용하는 자료구조이며 대부분은 택시정거장에 비유하곤 한다.

트리

트리는 계층구조를 표현하기 위해서 사용하는 자료구조이다. 트리의 크기를 제한하면 트리의 연산이 단순해지고 명확해지는데 차수를 2개 이하로 정의한 것이 이진 트리이다. 이진 트리의 종류로는 스레드 이진 트리, 이진 탐색 트리, AVL 트리 등이 있다.

힙(Heap)

힙는 이진트리의 한 종류로 나열한 두 가지 조건이 성립하는 이진 트리를 의미한다. 우선 완전 이진 트리여야 한다. 또한 부모 노드와 자식 노드간에 크기 관계가 성립해야 한다. 루트 노드가 가장 크고 자식 노드가 부모 노드보다 작으면 최대 힙, 반대의 경우는 최소 힙이다. 각각 최댓값과 최솟값에 접근하기 위해 사용하며 성능이 매우 좋다.

해쉬

해쉬는 임의의 크기를 가진 데이터를 고정된 크기의 값으로 변환시키는 것을 말한다. 해쉬를 이용하여 임의의 데이터를 숫자로 변경하는 해쉬 함수를 정의하면 배열의 인덱스를 원하는 데이터 값으로 저장하거나 찾을 수 있다. 기존에는 탐색을 위한 시간이 소모됨에 반해 해쉬를 이용하면 즉시 데이터에 엑세스 할 수 있다.

그래프

정점과 에지로 이루어진 형태의 자료구조다. 에지의 방향성의 존재 유무에 따라서 유향 그래프와 무향 그래프로 분리되며 에지가 가중치를 가지고 있지고 있다면 가중치 그래프라고 부른다. 그래프는 행렬과 연결리스트를 활용하여 구현할 수 있는데 행렬의 경우 정점의 존재 여부와 상관없이 항상 n^2의 공간 복잡도를 가진다.

트리와 그래프의 차이점

구현이나 동작의 형태로는 트리와 그래프는 동일하다고 생각된다. 트리와 그래프의 유일한 차이점은 그래프에는 루트 노드가 존재하지 않는 다는 것. 트리에서는 루트 노드로 되돌아오는 에지가 존재하지 않다는 점이다.

네트워크

GET, POST 방식의 차이점
  • GET : 데이터가 Header의 URI에 담겨서 전송되므로 데이터 크기가 제한적이며 데이터가 사용자에게 그대로 노출되어 보안이 필요한 경우 적절하지 않다. GET 요청은 캐싱이 가능하므로 데이터가 사용자에게 노출되어도 상관없다면 적극적으로 활용하는게 좋다.
  • POST : 데이터의 크기가 GET 방식보다 현저하게 크며 데이터가 일반 사용자에게 노출되지 않으므로 안정적으로 데이터를 전송할 수 있다. POST는 대부분 데이터의 변경을 위해서 사용한다.
TCP 3-way-handshake
  • Client는 Server에 접속 요청 메세지(SYN)을 전송하고 SYN_SEND 상태가 된다.
  • Server는 SYN 요청을 받고 Client에 요청을 수락(SYN+ACK)하고 SYN_RECEIVED 상태가 된다.
  • Client는 Server에게 수락 확인(ACK)를 보내고 Server는 ESTABLISHED 상태가 된다.
TCP와 UDP의 차이점
  • TCP : 신뢰성과 순차적인 전달이 필요한 경우 사용한다. TCP 서비스는 송신자와 수신자 모두가 소켓이라고 부르는 종단점을 생성함으로써 이루어진다. TCP는 멀티캐스팅이나 브로드캐스팅을 지원하지 않는다.
  • UDP : 비연결형 프로토콜이며 손상된 세그먼트의 수신에 대한 재전송을 하지 않는다. UDP를 사용하는 것에는 DNS가 있다. 사전에 설정이 필요하지 않으며 그 후에 해제가 필요하지 않다.
HTTP와 HTTPS의 차이점

HTTP의 문제점은 평문 통신이기에 도청이 가능하다는 것과 통신 상대를 확인하지 않기 때문에 위장이 가능하다는 것과 완정성을 증명할 수 없기 때문에 변조가 가능하다는 것이다. TCP/IP 구조의 통신은 패킷을 수접하는 것만으로도 도청할 수 있다. 이를 해결하는 방법으로 통신 자체에 SSL을 적용하거나 콘텐츠 자체를 암호화하고 복호화하는 처리를 진행할 수 있다.

DNS round robin 방식

DNS를 이용해서 하나의 서비스에 여러 대의 서버를 분산 시키는 방법이다. 동일한 이름으로 여러 레코드를 등록 시키면 질의 할 때마다 다른 결과를 반환하며, 이 동작을 이용함으로써 여러 대의 서버에 처리를 분산 시킬 수 가 있다. 단점은 아래와 같다.

  • 서버의 수 만큼 공인 IP 주소가 필요하다.
  • DNS 질의 결과 캐싱으로 인해 균등하게 분산되지 않는다.
  • 서버가 다운되어도 확인이 어렵다,
웹 통신의 흐름

운영체제

프로세스와 스레드의 차이
  • 프로세스 : CPU가 처리할 수 있는 작업의 단위 (자세한 건 PCB 참고)
  • 스레드 : 프로세스 안에서 공유 자원 (공유 자원 관리법은 Mutex, Semaphore 참고) 을 가지고 작업을 하는 흐름의 단위 둘의 가장 큰 차이점은 ‘공유 자원을 가지고 있는가’ 로 표현될 수 있다. 기본적으로 프로세스는 프로세스의 메모리를 가지고 있고, 스레드는 프로세스 안에서 공유 메모리를 지니고 있다.
스케줄러의 종류

스케줄러는 적용 시점에 따라 선점, 비 선점 2가지로 구분할 수 있다

  • 비선점형 : 상당히 Greedy한 스케줄링으로 프로세스가 CPU에 할당되면 그 프로세스가 종료하거나 인터럽트가 발생하기 전까지 계속 실행하도록 보장한다. 따라서 문맥 교환이 거의 일어나지 않아 오버헤드가 상당히 적고 프로세스의 처리 시간을 미리 예측이 가능하다. 하지만 Starving 현상이 일어날 위험성이 크다.
  • 선점형 : 어떤 프로세스가 CPU에 할당되어 있어도 인터럽트를 발생시키면 사용중인 프로세스를 중지할 수 있다. 즉 모든 프로세스에게 동일한 사용 시간을 보장할 수 있어 Starving 현상이 일어나지 않지만 문맥 교환이 많이 일어나 오버헤드가 커질 수 있다.
CPU 스케줄러
동기와 비동기의 차이

동기와 비동기의 가장 큰 차이점은 return 값을 가져올 때의 시점이다 동기는 System Call이 끝날 때 까지 기다렸다가 return 값을 가져 오고 비동기는 System Call이 완료 되지 않아도 나중에 끝나면 return 값을 가져온다.

멀티스레드
프로세스 동기화
메모리 관리 전략
가상 메모리
캐시의 지역성

데이터베이스

사용하는 이유
인덱스
정규화
트렌잭션
Statement vs PrepareStatement
NoSQL


프로그래밍 언어

Java

JVM, GC의 원리

GC는 JVM의 Heap Memory 내에 존재하는 Garbage를 찾아 내 처리하여 Heap Memory를 회수하는 작업이다. 어떤 객체가 Garbage인지 판별은 Reachability라는 개념을 사용한다. Reachability 가 Unreachable 이 되면 GC 가 일어나게 되는 것이다.

콜렉션

데이터의 집합으로 어떤 데이터를 담을 수 있는 자료구조를 가진 클래스이다. 크게 Collection과 Map으로 나누어 진다. 컬렉션은 Value 값만 있는 자료구조인 List(LinkedList, Vector, ArrayList 등등)로 이루어져 있고 Map은 Key 와 Value가 있는 자료구조이다.

어노테이션

자바 소스 코드에 주석처럼 추가하여 사용할 수 있는 메타데이터의 일종이다.

제내릭

제네릭은 다양한 타입의 객체들을 다루는 메서드나 컬렉션에 컴파일 시 타입 체크를 해주는 기능이다. 클래스 내부에서 사용할 데이터 타입을 나중에 인스턴스를 생성할 때 확정하는 것을 제네릭이라 한다. 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움이 줄어든다.

파이널

로컬 원시 변수의 경우 immutable하여 상수에 사용 가능 객체 변수에 final를 하게 되면 레퍼런스 변경이 불가능하다. 하지만 그 객체 자체는 mutable하다. Method에 final 선언 시 override가 불가능 하다. Class에 final 선언 시 상속이 불가능하다.

오버라이딩 오버로딩

오버로딩 : 같은 이름의 Method를 여러 개 가지면서 Return 타입과 매개 변수가 다른 클래스를 정의 오버라이딩 : 상속 시 부모 Class의 Method를 상속 받은 Class에서 재정의(부모 Class의 Method와 같은 이름) 해서 사용한다

Access Modifier

접근 지정자로 OOP의 정보 은닉, 캡슐화를 구현해 준다.

Wrapper class

Java의 객체는 기본적으로 기본형, 참조형 둘로 나뉘어 진다. Wrapper class는 기본형 객체를 참조형 객체로 구현해 놓은 것이다. Java 1.5부터는 기본형과 Wrapper class 간에 Boxing, Unboxing으로 상호 변환이 쉽게 가능하다. Wrapper class를 사용하는 이유는 매개변수로 객체가 요구될 때. 기본형 값이 아닌 객체로 저장해야 할 때. 객체간 비교가 필요할 때. 등

Multi-Thread 환경에서의 개발

Javascript

자바스크립트 이벤트 루프
Hoisting
Closure
this에 대해서
Promise

Python

Generator
클래스를 상속했을 때 메서드 실행 방식

인스턴스의 메서드를 실행한다고 가정할 때 __getattribute__()로 bound 된 method 를 가져온 후 메서드를 실행한다. 상속할때 왼쪽에 가까운 순서대로 우선순위가 높아진다.

GIL과 그로인한 성능 문제

GIL은 여러 스레드가 동시에 실행되는 걸 막는다. 덕분에 구현이 간단하고 레퍼런스 카운팅 오버헤드가 적다. GIL 때문에 성능 문제가 대두되는 경우는 압축, 정렬, 인코딩 등 수행시간에 CPU 의 영향이 큰 작업(CPU bound)을 멀티 스레드로 수행하도록 한 경우다. 이 땐 GIL 때문에 멀티 스레드로 작업을 수행해도 싱글 스레드일 때와 별반 차이가 나지 않는다. 이를 해결하기 위해선 멀티 스레드는 파일, 네트워크 IO 같은 IO bound 프로그램에 사용하고 멀티 프로세스를 활용해야한다.

GC 작동 방식

레퍼런스 카운팅과 순환 참조 감시

Celery
PyPy가 CPython 보다 빠른 이유

CPython은 일반적인 인터프리터임에 반해 PyPy는 JIT(Just In Time)이 겸비된 인터프리터이기 때문이다. JIT는 인터프리터의 단점을 보완하기 위해 기계어 코드를 생성하면서 그 코드를 캐싱하여, 같은 함수가 여러 번 불릴 때 매번 기계어 코드를 생성하는 것을 방지한다.

메모리 누수가 발생할 수 있는 경우

메서드 기본 인자 값으로 mutable 객체를 사용하고 있는 경우, 클래스 내 __del__ 메서드를 재정의 하는 경우

Duck Typing

Duck typing이란 특히 동적 타입을 가지는 프로그래밍 언어에서 많이 사용되는 개념으로, 객체의 실제 타입보다는 객체의 변수와 메소드가 그 객체의 적합성을 결정하는 것을 의미한다. 하나의 외부 메서드를 통해서 서로 다른 객체의 인자의 같은 이름의 메서드를 호출할 수 있다.


분야별

프론트엔드

브라우저의 작동 원리
Document Object Model
CORS
크로스 브라우징
웹 성능 문제점
서버 사이드 렌더링 vs 클라이언트 사이드 렌더링
CSS Methodology
normalize.css vs react.css

'개발자 지망생의 고군분투' 시리즈

개발자로 취업하려면 도대체 뭘 준비해야할까? 저도 그걸 몰랐습니다. 그래서 무작정 제가 하고 싶은대로 준비하였고 이 시리즈는 그 과정을 담아냈던 공간입니다. 다른 누군가가 취업을 준비할 때 참고가 된다면 좋을 것 같습니다. 도움이 될 수 있다면 더 좋겠네요! 😃
baealex
0분전
작성된 댓글이 없습니다. 첫 댓글을 달아보세요!
    댓글을 작성하려면 로그인이 필요합니다.