2022 SK ICT Family 신입 개발자 채용 챌린지 코딩 테스트 1차 후기 (합격)

취업 과정|2022. 3. 3. 10:01
728x90

합격 전 후기


프로그래머스를 통해 SK에 대한 공채 프로세스가 진행되었다.

 

보통 유명한 IT기업(네이버, 라인, 카카오 등)들은 이미 자소서나 스펙 입력을 최소화하고 자격만 갖추었다면 무조건 코딩 테스트를 볼 수 있게 하여 서류전형 없이 오직 지원자의 개발 능력만을 검증하는 프로세스를 적용했다.

 

또한 유명하진 않더라도 조건이 상당히 좋은 튼실한 IT기업들도 정량적인 스펙이 개발 역량을 대변하지 않기 때문에 지원자의 역량 평가 기준으로 서류전형을 생략한 채용 프로세스를 진행하고 있는 추세다. 

 

하지만 흔히 어르신들도 잘 아시는 대기업(삼성, LG, SK)들은 아직 개발자를 채용할 때 서류전형으로 먼저 당락을 결정하고 개발 능력을 검증하는 경향이 있다.

 

그래서 필자도 조금 놀라웠는데 본인이 아는 한 아마 유명하고 오래된 대기업 중에서는 처음으로 서류전형을 생략하고 오직 개발자의 능력 검증만으로 채용하는 첫 기업이 SK인 것 같다.

 

그걸 잘 알아서 그런지 채용 내용에도 상당히 강조해 놓은 것을 확인할 수 있었다.

 

SK 공고
SK 공고

 

또한 여태까진 계열사에 대한 지원을 일일이 했어야 했지만 이번에는 모집분야를 선택하여 해당 분야를 모집하는 모든 계열사에 대해 지망을 선택하여 한꺼번에 지원 가능하단 점이 상당히 편했다.

 

전체적인 일정은 1~2차 코딩 테스트 -> 1~2차 면접 -> 입사 순으로 진행되며 이번에 1차 코딩 테스트를 보게 되었다.

 

언어는 대부분의 코테에서 통용되는 언어들(C, C++, Java, Python 등)을 사용할 수 있어서 딱히 걱정할 필요는 없을 것 같다.

 

1차 코딩 테스트는 3시간 동안 4문제를 풀게 되며 당연한 말이지만 문제에 대한 정보는 저작권법에 의해 공개가 불가능하다.

 

다만 말할 수 있는 점은 다양한 문제가 나왔다는 것이며 보통의 코테는 문제당 30분을 기준으로 출제되는데 역시 문제당 시간이 긴 만큼 까다로운 문제가 포함된 것 같다.

 

필자는 주로 트리와 최적화 문제(까다로운 DP)에 약한 편인데 다행히 카카오를 제외한 대부분의 기업은 효율성 테스트를 적게 보는 듯 하지만 이번에 나온 트리 문제도 역시 어떻게 풀어야 되는지 감을 잡기 힘들었다.

 

물론 아마 감을 잡았다고 하더라도 풀긴 힘들었을 것 같다.

 

2문제를 푸는데 약 4~50분이 걸렸으나 그래프 문제에서 아이디어를 떠올리는 것과 조건 처리가 까다로워 약 한 시간 반 정도 걸렸다.

 

이 문제도 제시된 테스트 케이스와 직접 만든 테스트 케이스도 통과하긴 했으나 "맞았다"라는 확신을 갖기엔 조금 부족한 느낌이다.

 

따라서 남은 시간은 30분 정도기에 구현할 시간은 부족했을 것이다.

 

아마 체감상 까다로운 문제가 두 문제 있기도 하고 2차 코테가 예정되어 있기 때문에 합격권은 2~3개가 아닐까 생각한다.

 

필자는 그래프 문제를 제대로 풀었다면 3문제, 조건에서 틀린 부분이 있다면 2문제를 맞았기 때문에 합격 컷에 비슷하리라 짐작한다.

 

오픈 단톡방에서도 2문제가 가장 많았고 그다음이 3문제라서 충분히 합격을 기대해 볼 수 있을 것 같다.

 

여러 기업의 코테를 경험해보고 네이버, 라인 등의 합격 컷 수준까진 올라왔단 자만심에 여태 트리는 단순하게 구현과 탐색 정도의 준비만 했어서 부족한 걸 알면서도 SSAFY 강의 듣는다고 피곤하다는 자기 합리화에 빠져 외면했었던 것 같다.

 

보다 안정적인 합격권을 위해서 지금부터라도 부족한 부분을 채워나가야겠다.

 

합격 후기


오늘 (2022.03.16, 수) 코테 합격 메일이 왔다.

 

지난 토요일(2022.03.12)에 코테를 봤으니 4일 만에 결과 발표가 된 것이다.

 

합격 메일
합격 메일

이번 채용 과정 자체가 다른 직무, 각 계열사에 대한 지망 순위를 받고 다 같이 코테를 봤기 때문에 아마 거기서 합격 컷이 조금 달라질 수 있을 것이라 생각한다.

 

필자 또한 확신이 안 서는 문제 포함해서 3문제를 풀어서 합격했고 단톡방을 보아하니 비록 개인의 의견이라 확실한 것은 아니지만 다소 다양하게 합격했단 소리가 들렸다.

 

따라서 "몇 문제를 풀면 합격이다 아니다" 라고 정확히 말을 할 순 없겠지만 4문제를 기준으로 3문제 정도를 풀면 다소 합격 안정권이라 생각하면 되지 않을까 생각한다.

 

사실 어느 코테나 75% 정도면 합격권이긴 하지만 말이다.....

 

2차 코테를 볼 때까지 이틀의 시간이 남았지만 사실 SSAFY 강의도 듣고 공채 시즌이기에 지원서도 작성하고 강의에서 부족한 부분을 복습하다 보니 특별히 알고리즘을 위해 공부를 할 시간은 거의 없을 것 같다.

 

2차도 마찬가지로 평소 실력대로 보되 트리에 관한 문제만 한 두 개 정도 익히고 시험을 보도록 해야겠다. 

 

 

728x90

댓글()

[Programmers] Python 프로그래머스 주식가격 Level 2

728x90

https://programmers.co.kr/learn/courses/30/lessons/42584

 

코딩테스트 연습 - 주식가격

초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요. 제한사항 prices의 각 가격은 1 이상 10,00

programmers.co.kr

 

분류는 스택/큐로 구분되어있지만 사실 완전 탐색으로도 풀리는 문제다.

 

문제풀이


지문 자체가 어렵다는 사람들이 많은 것 같아서 문제를 좀 더 쉽게 설명하겠다.

 

prices의 가격들은 매초 변하는 가격을 뜻하고 가격이 떨어지지 않는 기간은 현재 가격보다 더 낮은 가격이 나온 시간까지 매초(가격의 수) 세면 된다는 뜻이다.

 

그래서 예시에서 \1은 그 뒤에 \1보다 낮은 시간이 없기 때문에 4초(4개의 가격) 동안 가격이 떨어지지 않는 것이고 마지막 \3은 그 뒤에 남아있는 시간이 없기 때문에 0초가 된 것이다.

 

단지 지문에서 "가격이 떨어지지 않은 기간은 몇 초인지"라고만 있었기에 이를 헷갈려서 질문에 올린 사람들이 많은 것 같다.

 

어려운 문제가 아니므로 바로 전체 코드로 넘어가겠다.

 

def solution(prices):
    answer = []
    for i in range(len(prices)):
        cnt=0
        for j in range(i+1,len(prices)):
            if prices[i]<=prices[j]:
                cnt+=1
            else:
                cnt+=1
                break
        answer.append(cnt)
    return answer

 

3번째 줄은 prices의 전체 범위를 탐색하겠다는 것을 뜻하고 5번째 줄은 현재 가격보다 떨어지는 시간이 나올 때까지 남은 시간을 반복하여 세는 반복문이다.

 

만약 현재 가격보다 낮은 시간이 있다면 그 뒤에 가격은 고려할 필요가 없기에 break를 통해 바로 반복문을 탈출하면 된다.

 

그렇게 카운트한 값을 answer에 추가하면 된다.

 

결과 화면
결과 화면

 

다만 의문인 점은 prices의 길이는 100,000(10만) 이하이고 완전 탐색은 O(n^2)의 시간 복잡도가 걸리므로 1초당 5천만~1억 정도 연산이 가능한 Python을 기준으로 최악의 테스트 케이스가 나온다면 시간 초과가 걸릴 수밖에 없다.

 

하지만 Input이 작은 정확성까진 이해가 됐으나 상당히 큰 Input이 들어오는 효율성까지 통과된 거로 봐서는 최악의 경우까진 Input이 들어오지 않게 설정한 것 같다.

728x90

댓글()

[Programmers] Python 프로그래머스 프린터 Level 2

728x90

https://programmers.co.kr/learn/courses/30/lessons/42587

 

코딩테스트 연습 - 프린터

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린

programmers.co.kr

 

큐를 사용하면 쉽게 풀 수 있는 문제이다.

 

스택과 큐에 대해 익숙하지 않거나 까먹었다면 먼저 이전 포스팅을 참고하여 이해하고 오는 것을 추천한다.

2021.12.04 - [알고리즘/알고리즘 강의] - [알고리즘] 스택(Stack)과 큐(Queue) 데크(Deque)까지 (Python)

 

[알고리즘] 스택(Stack)과 큐(Queue) 데크(Deque)까지 (Python)

설명 자료구조(Data Structure)를 공부할 때 가장 처음 접하는 것은 스택(Stack)과 큐(Queue)다. 그전에 자료구조란 Data를 효율적으로 저장하고 접근하여 사용하는 방법을 뜻한다. 적합한 상황에 적절한

khsung0.tistory.com

 

문제풀이


눈여겨봐야 할 점은 3가지다.

 

  1. 대기목록에서 꺼낸 문서보다 중요도가 높은 문서가 대기목록에 남아있다면 꺼낸 문서를 다시 대기 목록에 넣는다.
  2. 대기 목록에는 최대 100개의 문서가 있다.
  3. 중요도는 숫자가 클수록 중요하다.

대기 목록인 priorities의 첫 원소를 차례대로 빼면서 나머지 원소 중 최대 중요도를 비교하여 뺀 문서보다 중요도 높은 문서가 있다면 뒤에 추가하는 형식으로 풀면 될 것이다.

 

이때 최대 100개의 문서밖에 없으므로 O(n)의 시간 복잡도를 가지는 max 함수로 최대 중요도를 비교하면 된다.

 

동시에 location에 해당하는 문서가 몇 번째에 출력되는지 묻는 문제이므로 원소를 pop 할 때마다 location을 감소시키고 음수가 되면 대기 목록의 마지막에 추가되었다고 생각하면 된다.

 

간단한 문제이므로 바로 전체 코드로 넘어가겠다.

 

def solution(priorities, location):
    answer = 0
    while len(priorities)>0:        #대기 목록에 문서가 있는 동안 반복
        temp=priorities.pop(0)      #첫 번째 문서 꺼내기
        if len(priorities)==0:      #껴낸 문서가 마지막 일때 종료
            answer+=1
        else:
            if temp>=max(priorities):   #꺼낸 문서의 중요도가 제일 높을 때
                if location==0:         #찾고자 하는 문서일 때 종료
                    answer+=1
                    break
                else:
                    location-=1
                    answer+=1
                        
            #꺼낸 문서보다 중요도가 높은 문서가 대기 목록에 존재할 때
            else:
                priorities.append(temp)
                location-=1
                if location<0:
                    location=len(priorities)-1
    return answer

 

3번째 줄은 대기 목록에 문서가 있는 동안 반복하기 위해 while문을 선언하였고  4번째 줄은 pop(0)을 통해 0번째 인덱스의 원소를 제거하며 반환한다.

 

또한 5번째 줄은 꺼낸 문서가 마지막 문서일 때 (더 이상 대기 목록에 문서가 없을 때) 고려할 조건이 없으므로 answer을 증가시킨 후 바로 종료한다.

 

8번째 줄의 if문은 max로 대기 목록의 중요도를 비교하여 더 높은 중요도가 없으면 출력하는 문서로 판단하고 location을 감소시킨다.

 

이때 location이 0이라면 꺼낸 문서가 찾는 문서이므로 answer을 증가시킨 뒤 break를 통해 반복문을 빠져나온다.

 

17번째 else는 대기 목록에 더 높은 중요도가 있을 때 뒤에 추가하는 구문으로 만약 location이 음수가 되면 대기 목록의 마지막에 추가했다는 의미이므로 현재 priorities 길이의 -1로 변경하면 된다.

 

결과 화면
결과 화면

 

이 문제는 Input Size가 상당히 작아서 굳이 시간 복잡도를 계산할 필요까진 없었던 것 같다.

 

조건만 잘 확인하고 구현한다면 충분히 쉽게 통과할 수 있을 것이다.

 

이 프린터 문제는 우선순위 큐란 알고리즘이다.

 

다만 우선순위 큐는 힙(Heap)이란 자료 구조를 사용하고 내부 구조에서 최댓값, 최솟값을 갱신하는데 O(logn)의 효율적인 시간 복잡도를 가진다.

 

파이썬은 Heapq란 모듈을 통해 쉽게 우선순위 큐를 구현 가능하며 해당 문제에서는 큐를 연습하기 위해 일부러 Input을 적게 주고 우선순위 큐의 결과를 나타낼 수 있도록 유도한 것 같다.

 

코테에서도 은근히 우선순위 큐를 사용하는 문제가 나오므로 우선순위 큐를 구현하는 힙에 대해서 포스팅하겠다.

728x90

댓글()

[Programmers] Python 프로그래머스 기능개발 Level 2

728x90

https://programmers.co.kr/learn/courses/30/lessons/42586

 

코딩테스트 연습 - 기능개발

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는

programmers.co.kr

 

프로그래머스의 분류에도 나와 있듯이 큐를 사용하면 쉽게 풀 수 있는 문제이다.

 

스택과 큐에 대해 익숙하지 않거나 까먹었다면 먼저 이전 포스팅을 참고하여 이해하고 오는 것을 추천한다.

 

https://khsung0.tistory.com/14?category=1038750 

 

[알고리즘] 스택(Stack)과 큐(Queue) 데크(Deque)까지 (Python)

설명 자료구조(Data Structure)를 공부할 때 가장 처음 접하는 것은 스택(Stack)과 큐(Queue)다. 그전에 자료구조란 Data를 효율적으로 저장하고 접근하여 사용하는 방법을 뜻한다. 적합한 상황에 적절한

khsung0.tistory.com

 

문제 풀이


눈여겨봐야 할 점은 5가지다.

 

  1. 작업의 개수는 100개 이하
  2. 작업 진도는 100 미만의 자연수
  3. 작업 속도는 100 이하의 자연수
  4. progresses의 순서대로 배포한다.
  5. 배포는 하루에 한 번만 이루어진다.

 

문제를 보자마자 떠올린 생각은 day를 하루씩 증가시키면서 progresses 리스트에 speeds 리스트의 원소를 계속 더하고 progresses의 길이가 0이 될 때까지 같은 날에 0번째 인덱스의 원소가 100 이상이면 pop 하면서 카운트하여 answer에 추가하는 방식이었다.

 

애초에 작업의 개수가 100개 이하고 작업 진도가 1, 작업 속도가 1일 때 최대 99일이므로 Input이 작아 가능성은 있어 보였다.

 

하지만 Python의 pop함수에서 0번째 인덱스를 제거하는 pop(0)은 O(n)의 시간 복잡도를 가지므로 원소를 제거하는 과정에서 추가적으로 불필요한 연산이 생기기에 상당히 비효율적인 방식이라 다른 방법을 생각해봤다.

 

그 결과 굳이 매번 원소들을 더하는 게 아니라 day를 증가시키면서 같은 day일 경우를 카운트하여 answer에 추가하고 기존의 리스트에 대한 변경 없이 현재 어떤 인덱스를 가리키는지 알려주는 curr_index를 선언한다면 매번 원소를 제거할 때 드는 시간 복잡도도 없어질 것이라 판단하였다.

 

전체 코드를 통해 설명하면 이해가 더 빠를 것이다.

 

def solution(progresses, speeds):
    answer = []
    day=0           #개발 일수
    curr_index=0    #현재 작업 Index

    #작업 Index를 0번 부터 끝까지 반복
    while curr_index<len(progresses):

        #현재 작업이 100% 넘을 때까지 day 증가
        while progresses[curr_index]+speeds[curr_index]*day<100:
            day+=1

        #완료된 작업 개수 카운트
        cnt=0

        #완료된 작업 카운트
        while curr_index<len(progresses) and progresses[curr_index]+speeds[curr_index]*day>=100:
            cnt+=1
            curr_index+=1
        answer.append(cnt)
    return answer

 

7번째 줄을 통해 progresses 리스트를 전체 반복하고 10번째 줄을 통해 현재 작업이 100%가 될 때까지 day를 증가시킨다.

 

day를 찾으면 같은 날일 때 몇 개의 작업을 배포할 수 있는지 세기 위해 14번째 줄에 cnt를 선언하여 0으로 초기화한다.

 

초기화된 cnt를 기반으로 17번째 줄에서 배포 가능한 작업들을 세며 curr_index를 증가시킨다.

 

이때 while문에서 curr_index<len(progresses)를 먼저 선언한 이유는 curr_index가 증가할 때 progresses의 리스트 범위를 벗어나 Index Error를 일으킬 수 있기 때문이다.

 

프로그래밍 언어에서 조건을 판단할 때 앞에 있는 조건이 False라면 뒤에 있는 조건을 확인하지 않기 때문에 이처럼 Index Error를 방지하는 조건이나 시간 복잡도를 최대한 줄일 수 있는 조건은 되도록이면 앞에 쓰는 습관을 들이자.

 

마지막으로 카운트한 작업 수를 answer에 추가하면 끝이다.

 

결과 화면
결과 화면

 

이렇게 구현한 방식은 리스트의 원소를 제거하는 등 불필요한 연산을 줄였기 때문에 day를 증가시키는 연산(최대 99번), progresses 리스트를 탐색하는 연산(최대 100번)을 하면 최대 약 10,000번의 연산을 한다.

 

엄밀히 말하자면 큐로 푼 게 아니라 리스트의 인덱스 접근을 통해 풀었고 처음에는 상당히 비효율적인 방식을 생각했었다.

 

항상 문제의 조건을 정확히 파악하여 자신이 생각한 방식의 시간 복잡도를 계산해보고 보다 더 효율적인 방식이 있는지 끊임없이 고민하는 습관이 상당히 중요한 것 같다.

 

 

728x90

댓글()