Maximize Your Potential

Developer Study

에슬레저 기업 파이썬 백엔드 개발자 코딩 테스트와 면접 후기

maxworld 2024. 9. 23. 13:05
728x90
반응형

에슬레저 기업 코딩 테스트와 면접 후기

 

 

서울에 위치한 모 에슬레저 기업의 개발자 채용 과정에서는 코딩 테스트와 면접이 동시에 진행되었습니다. 코딩 테스트는 주로 알고리즘 문제를 평가하며, 면접에서는 그동안의 실무 경험과 기술적 지식을 기반으로 한 질문들이 주를 이뤘습니다. 이번 글에서는 코딩 테스트의 구체적인 문제와 해결 과정을 자세히 설명해보려고 합니다.

2시간 가량 코딩테스트 진행

 

1번 문제

번식하는 드래곤 문제

문제 설명
다음과 같이 번식하는 드래곤이 있습니다. 갓 낳은 드래곤 알 하나를 집으로 데려왔을 때, n일 후엔 드래곤과 드래곤 알이 몇 개일지 알아내려 합니다.

드래곤 알은 이틀 뒤에 부화합니다.
부화한 드래곤은 매일 알을 하나씩 낳습니다.
부화한 드래곤은 네 번 알을 낳은 후, 더 이상 알을 낳지 않습니다.
n이 매개변수로 주어질 때, n일 후 드래곤과 드래곤 알이 몇 개 있는지 return 하는 solution 함수를 완성해주세요.

제한 조건
n은 45 이하인 자연수입니다.
입출력 예
n return
6 12
입출력 예 설명
일수 0 1 2 3 4 5 6
알을 낳을 수 없는 드래곤 수 0 0 0 0 0 0 1
알을 낳을 수 있는 드래곤 수 0 0 1 1 2 3 4
드래곤 알 수 1 1 1 2 3 5 7
0일~1일: 드래곤 알이 하나 있습니다.
2일: 초기 드래곤이 부화해, 알을 하나 낳았습니다. 따라서 드래곤 수와 드래곤 알 수의 합은 2입니다.
3일: 초기 드래곤이 한 번 더 알을 낳았습니다. 따라서 드래곤 수와 드래곤 알 수의 합은 3입니다.
4일: 이틀 차에 낳은 드래곤 알이 부화했습니다. 부화한 드래곤과 초기 드래곤이 알을 하나씩 낳았습니다. 따라서 드래곤 수와 드래곤 알 수의 합은 5입니다.
따라서 6일 후 드래곤과 드래곤 알은 총 12개가 됩니다.
def solution(n):
    if n == 0:
        return 1
    
    dragons = [0] * (n + 1)
    dragon_eggs = [0] * (n + 1)
    
    dragon_eggs[0] = 1
    
    for day in range(1, n + 1):
        # 현재 날짜에서 알을 낳을 수 있는 드래곤 수 계산
        dragon_eggs[day] = dragons[day - 1] if day - 1 >= 0 else 0
        
        # 현재 날짜에서 부화한 드래곤 수 계산
        dragons[day] = dragons[day - 1] + dragon_eggs[day - 1] if day - 1 >= 0 else 1
        
        # 다섯 번 알을 낳은 후에 더 이상 알을 낳지 않도록 설정
        if day >= 5:
            dragon_eggs[day] -= dragon_eggs[day - 5]
    
    return dragons[n] + dragon_eggs[n]

# 예시 입력과 출력 테스트
print(solution(6))   # 출력: 12

 

2번 문제

A-B 경로문제

 

 

 

문제 설명:
첫 번째 문제는 BFS(너비 우선 탐색) 알고리즘을 이용해 주어진 A 지점에서 B 지점까지의 최단 경로를 찾는 문제였습니다. 각 지점(노드)과 그 사이의 연결(간선)이 주어졌으며, 모든 간선의 비용이 동일했습니다.

문제 해결 과정:

  1. 그래프 생성: 주어진 데이터를 바탕으로 인접 리스트 형식으로 그래프를 구성했습니다. 이 리스트는 각 노드에 연결된 다른 노드들을 저장합니다.
  2. BFS 구현: BFS는 너비 우선 탐색이기 때문에, 출발점에서 가까운 노드부터 차례대로 방문하면서 최단 경로를 찾는 데 적합합니다. BFS에서는 주로 자료구조를 사용해 탐색을 진행합니다.
  3. 방문 기록: 이미 방문한 노드를 기록해 중복 방문을 방지했습니다.
  4. 경로 출력: 목표 노드에 도달하면 그때까지의 경로를 반환합니다.
from collections import deque

# BFS를 이용해 A에서 B로 가는 최단 경로 찾기
def bfs_shortest_path(graph, start, goal):
    # 큐 초기화: (현재 노드, 경로)
    queue = deque([(start, [start])])
    visited = set()

    while queue:
        node, path = queue.popleft()
        if node in visited:
            continue
        visited.add(node)

        # 목표 지점에 도착했으면 경로 반환
        if node == goal:
            return path
        
        # 인접 노드 탐색
        for neighbor in graph[node]:
            if neighbor not in visited:
                queue.append((neighbor, path + [neighbor]))

    return None  # 경로가 없으면 None 반환

코드 설명

  • bfs_shortest_path 함수는 BFS 알고리즘을 구현하여, 주어진 그래프에서 시작점(start)에서 목표 지점(goal)까지의 최단 경로를 찾습니다.
  • 큐(queue)에는 현재 노드와 그때까지의 경로(path)를 저장하여, 목표 지점에 도착할 때까지 큐에서 노드를 하나씩 꺼내며 탐색합니다.
  • 경로를 찾으면 해당 경로를 반환하며, 경로가 없을 경우 None을 반환합니다.
 

3번 문제

OAuth Access Token을 받기 위한 절차

OAuth 인증 플로우 중 "Authorization Code" 방식을 예로 설명합니다.
사용자가 클라이언트 애플리케이션에 로그인합니다.
클라이언트 애플리케이션은 OAuth 인증 서버에 사용자 인증을 요청하고, 사용자는 권한 부여를 수락합니다.
OAuth 인증 서버는 인증 코드를 클라이언트 애플리케이션에 제공합니다.
클라이언트 애플리케이션은 인증 코드를 사용하여 OAuth 인증 서버에 Access Token을 요청합니다.
OAuth 인증 서버는 Access Token을 클라이언트 애플리케이션에 반환합니다.

 

4번 문제
캠페인 클래스와 그룹 클래스에서 Campaign Name 필드를 그룹 클래스에서 불러오려면?
캠페인 클래스와 그룹 클래스 간에 관계를 설정해야 합니다. 가장 흔한 방법은 ForeignKey 또는 ManyToManyField를 사용하는 것입니다. ForeignKey를 예로 들겠습니다.
캠페인 클래스에 그룹을 가리키는 ForeignKey 필드를 추가합니다.
그룹을 생성할 때 해당 캠페인을 연결합니다.
이제 그룹 클래스의 인스턴스에서 캠페인 이름을 가져오려면 group.campaign_name을 사용하면 됩니다.

 

5번 문제

판다스 형식 빈칸 넣기

판다스의 DataFrame에 빈 값을 채우려면 fillna() 메서드를 사용합니다.

import pandas as pd

# 데이터프레임 생성
df = pd.DataFrame({'A': [1, 2, None, 4, 5], 'B': [None, 2, 3, None, 5]})

# 빈 값을 0으로 채우기
df.fillna(0, inplace=True)

# 결과 출력
print(df)

 

6번 문제
모델 Unique 모델 설정법
Django 모델에서 특정 필드를 고유(unique)하게 설정하려면 해당 필드에 unique=True 옵션을 추가합니다.

from django.db import models

class MyModel(models.Model):
    unique_field = models.CharField(max_length=100, unique=True)


뷰 시리얼라이저 상속 및 어노테이션 설명:

Django Rest Framework에서 뷰와 시리얼라이저를 사용할 때, 다음과 같이 상속과 어노테이션을 사용합니다.

from rest_framework import views, serializers, status
from rest_framework.response import Response

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = '__all__'

class MyModelView(views.APIView):
    def get(self, request):
        queryset = MyModel.objects.all()
        serializer = MyModelSerializer(queryset, many=True)
        return Response(serializer.data)

    @classmethod
    def post(cls, request):
        serializer = MyModelSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

 


7번 문제

request. 형식 문제



request 객체는 Django 뷰 함수나 Django Rest Framework 뷰 클래스에서 사용되며, 클라이언트의 HTTP 요청 정보를 담고 있습니다. 예를 들어, request.method, request.GET, request.POST 등을 사용하여 요청 정보에 접근할 수 있습니다.


Requests 라이브러리를 사용하여 HTTP POST 요청을 JSON 형식으로 보내는 예제입니다.

import requests
import json

# URL 설정
url = 'https://example.com/post'

# JSON 데이터 설정
json_data = {
    'key1': 'value1',
    'key2': 'value2'
}

# POST 요청 with JSON
response = requests.post(url, json=json_data)

# 응답 내용 출력
print(response.text)

 

JSON 요청 형식은 이미 제시된 예시와 같이 requests 라이브러리를 사용하여 JSON 데이터를 HTTP POST 요청으로 보내는 방법입니다. JSON 데이터는 Python 딕셔너리로 표현하고, json 매개변수를 사용하여 JSON 형식으로 전달합니다. 위의 예시에서는 'key1'과 'key2'를 가진 JSON 데이터를 POST 요청으로 보내고, 응답 내용을 출력하고 있습니다.

8번 문제
XPath 사용법

XPath는 XML 문서에서 원하는 요소를 선택하기 위한 언어입니다. 예를 들어, lxml 라이브러리를 사용하여 파싱할 때 XPath를 사용할 수 있습니다.

 

from lxml import etree

xml_string = '<root><element>Value</element></root>'
root = etree.fromstring(xml_string)

# XPath를 사용하여 요소 선택
element = root.xpath('//element')[0]
print(element.text)  # 출력: 'Value'

 

 

 

면접질문

퀴리셋(Quireset)과 오브젝트(Object)의 차이
퀴리셋은 데이터베이스에서 데이터를 조회하거나 필터링하는데 사용되는 질의(쿼리)의 집합입니다. 주로 SQL 등의 데이터베이스 질의 언어를 사용하여 데이터를 조작합니다.
오브젝트는 프로그래밍에서 데이터와 해당 데이터를 조작하는 메서드(함수)를 함께 묶어서 사용하는 데이터 구조입니다. 객체 지향 프로그래밍에서 주로 사용됩니다.

 

DRF (Django Rest Framework)가 뭔지
DRF는 Django 프레임워크의 확장으로, RESTful API를 쉽게 만들고 관리할 수 있는 도구입니다. 웹 애플리케이션에서 데이터를 CRUD(Create, Read, Update, Delete)하는 API를 빠르게 개발할 수 있도록 도와줍니다.

 

OOB OAuth
OOB는 Out-Of-Band의 약어로, OAuth 1.0a 인증 프로토콜에서 사용되는 인증 방식 중 하나입니다. 인증 프로세스에서 사용자가 인증 코드를 받는 데 다른 수단(예: 브라우저 외의 애플리케이션)을 사용하는 경우에 사용됩니다.

 

RDB와 NoSQL의 차이
RDB(관계형 데이터베이스)는 테이블과 스키마를 사용하여 데이터를 저장하며 SQL 쿼리를 사용하여 데이터를 조작합니다.
NoSQL은 비정형 또는 반정형 데이터를 저장하는데 사용되며, 스키마가 유연하며 대체로 확장성이 뛰어납니다.

 

Python 리스트와 튜플의 차이
리스트는 수정 가능하며, 요소를 추가, 삭제, 변경할 수 있습니다.
튜플은 수정 불가능하며, 한 번 생성되면 요소를 변경할 수 없습니다.

 

Composition(컴포지션)이 뭔지
컴포지션은 객체 지향 프로그래밍에서 클래스 간의 관계를 나타내는 개념입니다. 한 클래스가 다른 클래스의 인스턴스를 포함하는 방식으로 관계를 형성합니다.

 

API와 REST API의 차이
API는 응용 프로그램 간의 상호 작용을 위한 인터페이스를 나타냅니다.
REST API는 HTTP 프로토콜을 기반으로 하며, 자원을 고유한 URI로 표현하고, HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용하여 상호 작용합니다.

 

NumPy 쓰임새
NumPy는 파이썬의 과학 및 수학 계산 라이브러리로, 다차원 배열과 행렬 연산을 지원합니다. 과학, 통계, 머신러닝, 데이터 분석 등 다양한 분야에서 사용됩니다.

 

init, self, __super__이 뭔지
이것들은 파이썬의 특별한 메서드(매직 메서드) 중 일부입니다.
__init__은 클래스의 생성자 메서드로, 객체가 생성될 때 초기화 작업을 수행합니다.
__self__는 현재 객체를 가리키는 참조입니다.
__super__는 부모 클래스의 메서드를 호출하기 위해 사용됩니다.

 

오버라이딩(Overriding)과 오버라이드(Override)의 차이점
오버라이딩은 서브클래스에서 부모 클래스의 메서드를 재정의하여 동작을 변경하는 것을 말합니다.
오버라이드는 오버라이딩을 한 특정 메서드에 대한 언어적 주석(Annotation) 또는 주석 기능을 나타냅니다. 이것은 코드의 가독성을 높이고 개발자에게 오버라이딩을 의도적으로 한 것임을 알려줍니다.