서론

시간이 많이 지났지만 농협은행 합격 후기를 적어보려고 한다.

 
농협은행은 취준생 시절에 1순위 목표였던 기업이었다. 집이랑 가까워서.
매일 도서관에 박혀 공부하다가 지칠 때면, 농협은행 합격 후기를 작성하는 상상을 하곤 했다.
 
화장실 들어갈 때와 나올 때의 마음이 다르다고 했던가.
막상 합격하고 나니 이런저런 핑계로 블로그 작성을 미뤘다.
 
두 달에 가까운 연수가 끝나고, 업무에 배치받은 지 이제 겨우 한 달이 지났다.
어느덧 상반기 채용 시즌이 다시 찾아왔다. 블로그를 써야겠다는 생각이 들었다.


스펙

취준생 시절에 정말 많은 취업 후기를 읽어보았다.
 
항상 스펙이 먼저 눈에 들어왔다.
정량적으로 측정하기 쉬운 스펙을 두고 나와 비교해 보며, 스스로의 합격 가능성을 따져보기도 했다.
지금은 스펙이 크게 중요하지 않다는 것은 알지만, 보는 사람의 흥미를 위해서 적었다.

학교: 중경외시
학과: 상경 계열
학점: 3점 초반대

인턴: x
창업: 1회
SW 교육: SSAFY 12기, 애플디벨로퍼아카데미 2기

수상: x
프로젝트: 다수 (대표 프로젝트 2개)
어학: 토익 885 / OPIc IM2
자격: 정보처리기사, SQLD

 
 
취준생으로서 특이사항은 3가지 정도 있었다.
 

1. 창업 경험

약 1년 8개월 간의 창업 경험이 있다. 개발 업무는 아니었고, 기획과 제작에 가까웠다.
시드 투자도 받았고, 꽤 열심히 살았다.
 
다른 사람에게도 티가 나는지, 항상 창업 관련된 질문을 깊게 받았다.
그때 쌓아둔 경험이 취준생으로서 가장 큰 무기였다.

 
2. 비전공자 문과

개발 직군 취준을 하다 보면 경쟁자들은 보통 컴공 혹은 관련 전공자.
복수전공 혹은 부전공. 아니어도 이공계.
 
문과 단일 전공이 흔치는 않다.
그래서 개발자를 하게 된 계기나, 적성에 맞는다는 것을 증명할 방법이 필요하다. 꼭 한 번은 물어보더라.
싸피 같은 교육 경험이 있으면 대처가 어렵지는 않을 것이다.

 
3. iOS

특이하게도 iOS 프로젝트 경험만 갖고 있었다.
필수 소양인 JAVA도 취준 당시에 전혀 할 줄 몰랐다. 그러나 지금은 백엔드 직무에서 JAVA를 사용하고 있다.
 
대기업이면서도 서비스 기업이 아닌 농협은행 특성상, 언어가 크게 중요하지는 않은 듯하다.


전형

2024년 하반기 기준

 
 
전형이 조금 많은 편이다.
처음에는 막막하기만 한데, 막상 시작하면 또 어떻게든 하게 된다.
 
각 전형별로 간단하게만 경험을 적어보겠다.
 

1차(서류)

자소서 문항

1. 온라인 인적성평가(Lv.1)

온라인으로 진행한다.
홈페이지에서 농협은행 인재상 찾아보고 하면 된다.
 
솔직하게 하는 것이 가장 좋고, 걱정된다면 페르소나를 하나 만들면 좋다.
인재상과의 일치성, 답변의 일관성이 포인트이다.
 
2차 평가도 있으므로 답변했던 맥락을 기억해 두자.
 

2. 자기소개서

자소서는 특별하지 않았다.
그래도 잘 읽히게 쓰려고 노력했다. 
 
무조건 두괄식으로 썼다.
경험 중심으로 썼다. 경험의 결과는 전부 숫자로 적었다.
미사여구, 내가 느꼈던 감정 이런 건 다 뺐다.
 
농협은행에서 진행 중인 사업과 경험을 엮어서 로열티를 보여줬다.
문장력을 높이기 위해 chatGPT도 적극적으로 사용했다.
 
+ 농협은행의 경우 서류 가점 항목의 기준이 까다로운 편이다.
필자는 싸피 미수료 상태에서 지원했던 것이어서, 서류 가점이 없는 상태로 지원했다.
 

2차(필기)

1차 서류 합격 결과가 나오고, 바로 그 주에 2차 전형을 진행한다.
시간이 촉박하기 때문에 합격 전에 미리 준비하거나, 평소 실력으로 박치기해야 한다.
 
코딩테스트는 토요일에 온라인으로 진행하고,
나머지 3개의 필기 시험은 일요일에 고사장에 모여서 진행한다.
 
필기 시험은 체력의 소모가 크긴 한데, 반나절이면 끝이 나서 나름의 재미가 있다.
초코바 같은 것도 나눠주어서 수능 때 기분도 살짝 난다.

3. 온라인 코딩테스트 

SQL 2문제 + 알고리즘 3문제이다.
 
SQL은 GROUP BY, IFNULL 활용하는 문제였다.
어렵지는 않았다.
 
알고리즘은 단순 구현 / 수학 / 그래프 탐색 유형이었다.
난이도는 백준 기준 실버 상위 - 골드 중하위 정도.
 
아주 쉽지도 아주 어렵지도 않았다.
합격자의 경우 평균 3-4솔 정도였다.
 
나는 1솔했다. 다소 어이가 없는 결과였다.
그렇지만 다음날 필기 시험으로 충분히 만회할 수 있었다.
그러니 알고리즘에 너무 목을 매지도 걱정하지도 말자.

4. 인적성평가(Lv.2)

1차 인적성평가 때의 선택을 잘 기억하면서 선택하면 된다.
필기 시험의 첫 번째 과목으로, 몸풀기하면서 적응하는 시간이었다.

5. 직무능력평가

보통 NCS라고 불리는 유형의 시험이다.
60문제였고, 예년과 다르게 오답 감점은 없어서 시원하게 찍었다.
수리 논리 유형보다는, 비문학 유형이 주로 출제됐다.
 
합격자의 경우 35-40문제 정도 풀었고, 필자는 50문제 정도 풀었다.
코테의 실책을 만회할 수 있었다.
 
팁이 있다면 이자율 계산처럼 시간을 잡아먹는 문제는 과감하게 넘겼다.
배점이 높을 수는 있겠지만, 저런 문제에 집착하다 보면 시간 조절에 실패하여 시험 전체를 망치게 된다.

6. 논술평가

약술형 1문제 (A3 절반 분량)
논술형 1문제 (A3 2장 분량)
 
약술형은 농협과 관련된 주제가 나온다.
주제에 대해 알고 있으면 좋지만, 몰라도 괜찮다. 어차피 다들 잘 모른다.
 
논술형은 기술과 관련된 주제이다. 논술형은 길게 써야하므로 주제에 대해 지식이 조금 있어야 한다.
그러나 굉장히 일반적인 수준의 주제이므로, 개발 직군으로 취준을 하고 있다면 크게 어렵지 않을 것이다.
 
필자가 작성한 내용은 특별하지는 않았지만, 구조를 갖춰서 작성하려고 노력했다.
구조: 서론 - 본론 (주요 관점 3가지 -> 반대 관점 3가지) - 결론
 
시험지 맨 뒷 장에 글의 구조도를 그려놓았는데, 이것이 어필이 됐는지는 모르겠다.
분량은 꽉 채워서 썼다.
 

3차(면접)

필기 결과 발표 이후 면접까지는 1-2주 정도가 주어진다.
다들 면접 스터디를 하지만, 필자는 면접 경험이 있어서 따로 준비하지는 않았다.
 
만약 면접이 처음이라면 스터디를 추천한다.
하다 보면 떨지 않게 되고, 떨지 않으면 하고 싶은 말을 제대로 할 수 있다.
그것만으로도 눈에 띄는 지원자가 될 수 있다.
 
농협은행 5급 공채는 3가지 면접을 원데이로 진행한다.
역시 반나절 정도 소요되고, 면접 순서는 사람마다 다르다.

7. 적합성면접 (40분)

지원자 4 : 면접관 3.
 
프로젝트 경험, 자신 있는 언어, 농협은행에 대한 로열티, 인성 질문 등으로 구성된다.
가장 일반적인 면접이고, 날카로운 질문도 없었다. 적당한 분위기이다.
 
다대다 면접이기에 주변 분위기에 휩쓸리지 않는 것이 중요하다.
면접관의 질문에 첫 번째 지원자가 잘못 대답하자, 나머지 지원자도 모두 잘못 대답하는 상황이 있었다.
그럴 때 정신 차리고 똑바로 대답하면 득점할 수 있다.
 
두괄식으로 대답하고, 중언부언하지 않고, 말끝 흐리지 않고, ... 이런 건 생략하겠다.

8. 토론면접 (40분)

지원자 8(4:4) / 면접관 3
 
금융 + IT 관련 주제가 정해져 있고, 면접장에 들어가서 랜덤으로 찬/반을 나누어 토론을 진행한다.
토의가 아니고, 토론이기에 상대방을 설득하는 것이 중요하다. 이 부분은 현장에서도 강조한다.
 
주제에 대한 자료와 함께 5-10분 정도 읽을 시간이 주어진다.
자료 분석 시간이 끝나면, 진행 없이 자율 토론이 시작된다.
 
주제는 익숙하지는 않았지만, 자료를 보면 충분히 이해할 수 있는 내용이었다.
 
토론은 번갈아 가면서 진행하는 것이 아니고, 정말 자율적으로 한다.
토론은 튀지 않고 무난하게 하는 것이 좋다는 말도 있는데, 필자는 엄청 튀었다.
 
적극적으로 의견을 개진하고, 적극적으로 반박했다.
물론 쿠션어를 열심히 사용했지만, 나중에 면접장을 나와서 상대 측에게 미안하다고도 했다.
 
일단 토론을 이길 수 있는 주제로 이끌어 가는 게 중요하다.
찬성과 반대 측에는 각각 핵심적이면서도 반박하기 어려운 논제가 있을 것이다.
토론의 프레임을 해당 논제로 유도하면 이기기 쉽다.
 
다음으로는 메모하는 게 중요하다.
토론이 과열되면 누가 무슨 말을 했는지 기억하기 어렵다.
이때 메모해 두었던 내용을 바탕으로 언급하면, 주장에 힘이 생긴다. 최소한 그런 것처럼 들린다.
 
이기고 있는 토론에서는 주도하기가 쉽다.
적절한 예시도 잘 떠오르고, 합의점을 유리하게 제안하기도 쉽다.
 
주도할 수 있으면 주도하자.
득점은 못 하더라도 다음 면접을 자신감 있게 볼 수 있다.
 

9. PT면접 (20분)

지원자 1 : 면접관 3
 
금융 + IT 관련 주제와 자료를 나눠주고, 5-10분 동안 읽게 한다.
이후 면접실로 옮겨서 8분 발표, 12분 면접을 본다.
 
PT 주제가 꽤 어려웠다. 처음 들어보는 주제였다.
그래도 PT 자체를 구조에 맞춰서 진행하는 것은 어렵지 않았다.
 
그러나 이후 면접이 쉽지 않았다. 기술 면접 + 압박 면접이었다.
하나의 주제 관련 꼬리 질문이 계속되었는데, 필자는 얕은 수준만 대답하고 모르겠다고 했다.
이런 상황이 여러 번 반복이 되니까 의도된 압박이라는 걸 알면서도 난감했다.
 
당시에는 떨어졌다고 생각했는데, 다른 사람도 다 어려웠나 보다.
이럴 때는 아는 만큼만 이야기하고, 모르면 모른다고 하는 것이 낫겠다.


마치며

최종 합격 소식을 확인했을 때는 방방 뛰고, 세상이 떠나가라 소리 지를 줄 알았는데 그러지는 않았다.
그냥 좀 좋았다. 오히려 주변 사람들이 더 기뻐해 줬다.
 
비전공자로서 개발 직군 취준에 대한 막막함이 있었다.
2년에 가까운 시간 동안, 기존 직무로 돌아갈까 하는 마음도 여러 번 들었다.
하지만 모든 일이 그렇듯, 뚝심 있게 하다 보면 안 되는 것은 없더라.
 
최종 합격 후기를 쓰고 있으려니,
길고 길었던 취업 준비 기간이 이제서야 막을 내렸구나 싶다.

'회고' 카테고리의 다른 글

싸피 12기 비전공자 최종 합격 후기  (0) 2024.06.23
내 생각을 토해놓는 블로그  (0) 2024.01.10

1.1. 컴퓨터 구조를 알아야 하는 이유

  • 문제 해결 능력이 향상된다.
  • 입출력에 매몰되는 것을 넘어, 성능ㆍ용량ㆍ비용을 고려하는 개발자가 될 수 있다.

 

1.2. 컴퓨터 구조의 큰 그림

출처: https://velog.io/@seok9403/컴퓨터-구조

 

컴퓨터 구조를 이해하기 위해 필요한 지식은 크게 2가지이다.

  • 컴퓨터가 이해하는 정보
  • 컴퓨터의 4가지 핵심 부품

 

1.2.1. 컴퓨터가 이해하는 정보

컴퓨터는 0과 1로 표현된 정보만 이해한다.

0과 1로 표현되는 정보에는 크게 두 가지가 있다.

데이터명령어.

 

데이터: 컴퓨터가 이해하는 숫자, 문자, 이미지, 동영상과 같은 정적인 정보

명령어: 데이터를 움직이고, 컴퓨터를 작동시키는 정보

 

1.2.2. 컴퓨터의 4가지 핵심 부품

외관과 용도를 막론하고 컴퓨터의 핵심 부품은 CPU(중앙처리장치), 메모리(주기억장치), 보조기억장치, 입출력장치이다.

 

주기억장치에는 RAM(Random Access Memory)와 ROM(Read-Only Memory) 두 가지가 있으나, 일반적으로 RAM을 의미한다. 이후 작성될 글에서도 주기억장치는 RAM으로 간주하겠다.

 

1.2.2.1. 메모리

메모리는 현재 실행되는 프로그램의 명령어와 데이터를 저장하는 부품이다.

 

프로그램이 실행되기 위해서는 반드시 메모리에 저장되어 있어야 한다.

메모리에 저장된 값의 위치는 주소로 알 수 있다.

 

1.2.2.2. CPU

컴퓨터의 두뇌이다.

 

메모리에 저장된 명령어를 읽어 들이고, 읽어 들인 명령어를 실행하고, 실행한다.

CPU 내부는 ALU(산술연산장치), 레지스터, 제어장치로 구성되어 있다.

 

ALU: 계산기. 컴퓨터 내부 대부분의 계산을 담당.

레지스터: 임시 저장 장치. CPU에는 여러 개의 레지스터가 존재하고, 각기 다른 이름과 역할이 이싿.

제어장치: 전기 신호를 내보내고, 명령어를 해석하는 장치

 

1.2.2.3 보조기억장치

메모리와 다르게, 전원이 꺼져도 저장된 내용을 잃지 않는 저장 장치.

관점에 따라 입출력 장치라고 볼 수 있으나, 일반적으로 입출력장치와 합해 주변장치로 통칭한다.

 

1.2.2.4 입출력장치

마이크, 스피커, 프린터, 마우스 등 컴퓨터 외부에 연결되어 컴퓨터 내부와 정보를 교환하는 장치.

 

1.2.2.5 기타

메인보드(==마더보드)

핵심 부품을 비롯한 여러 컴퓨터 부품을 설치하고 연결하는 판

 

버스

연결된 부품끼리 데이터를 주고 받을 수 있는 통로.

 

컴퓨터의 핵심 4가지 부품은 시스템 버스를 통해 데이터를 주고 받는다.

시스템 버스는 주소 버스, 데이터 버스, 제어 버스로 구성된다.

 


참고

혼자 공부하는 컴퓨터구조 + 운영체제, 강민철, 1판

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV2b7Yf6ABcBBASw


문제 분석

target 이상이면서 가장 작은 조합을 구하고, 조합의 합과 target의 차이를 return 하라.

 

접근

N = 20이므로, 백트래킹으로 풀이하면 2 ** 20 ~= 1,000,000 정도일 것이다.
총합이 target 이상이 되면, target과의 차이를 현재 result 값과 비교하여 갱신한다.

 

모든 원소에 대하여 (추가하거나 / 추가하지 않거나)의 경우를 고려하고, 모든 원소를 탐색하면 result를 갱신한다.

 

코드

def solve(i, total):
    global n, target, res

    if i == n:
        if total >= target:
            res = min(res, total - target)
        return

    solve(i + 1, total + heights[i])
    solve(i + 1, total)


T = int(input())
for tc in range(T):
    n, target = map(int, input().split())
    heights = list(map(int, input().split()))
    res = 1e9
    solve(0, 0)
    print(f'#{tc + 1} {res}')

 

간단한 코드이지만, 2 * n개의 경우의 수를 고려하는 백트래킹 문제의 뼈대 코드인 듯하다. 

https://swexpertacademy.com/main/code/userProblem/userProblemDetail.do?contestProbId=AWKaG6_6AGQDFARV


문제 분석

시작점부터 도착점까지 가장 빠른 길을 찾아야 한다. -> BFS
섬(1)은 지나갈 수 없다.
소용돌이(2)는 지나갈 수 없다. 다만 한 번 통과한 경우 지나갈 수 있다.
    소용돌이(2)는 0초부터 시작해서 2초 동안 유지되고 1초 동안 잠잠해지는 패턴을 반복한다.

 

접근

BFS 탐색을 하다가 소용돌이를 만났을 때는 판단을 해야 한다.
    방문한 위치인 경우 -> 지날 수 있다
    방문하지 않은 위치인 경우
        time % 3 == 2인 경우, 지날 수 있다
            이때 2를 0으로 바꿔야 한다. 한 번 방문한 뒤에는 언제든 지나갈 수 있기 때문에.
        나머지의 경우, 지날 수 없다.

BFS 탐색을 하는 경우
    큐에는 (x, y, time)이 담겨야 한다.
        그래야 최단 경로를 판단할 수 있기 때문에
    visited 배열은 (x, y, time)의 원소가 완벽하게 같은 경우 걸러낸다.

    4방향 탐색이 아니라, 가만히 있기를 포함한 5방향 탐색이기 때문에, 방문 여부를 결정하기 위해 time이 필요하다.

 

코드

from collections import deque

dx = [1, -1, 0, 0, 0]
dy = [0, 0, 1, -1, 0]

def bfs(a, b, time):
    q = deque()
    q.append((a, b, time))
    visited = []
    visited.append((a, b, time))

    while q:
        x, y, t = q.popleft()

        if x == ex and y == ey:
            return t

        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]

            if nx < 0 or nx >= n or ny < 0 or ny >= n:
                continue

            if matrix[nx][ny] == 1:
                continue

            if matrix[nx][ny] == 2:
                if t % 3 == 2:
                    matrix[nx][ny] = 0
                    q.append((nx, ny, t + 1))
                    visited.append((nx, ny, t + 1))
                else:
                    continue

            if (nx, ny, t + 1) not in visited:
                q.append((nx, ny, t + 1))
                visited.append((nx, ny, t + 1))


testCase = int(input())

for tc in range(testCase):
    n = int(input())
    matrix = [list(map(int, input().split())) for _ in range(n)]
    sx, sy = map(int, input().split())
    ex, ey = map(int, input().split())

    result = bfs(sx, sy, 0)
    print(f"#{tc + 1} {result}")

 

 

swea에서 해당 문제의 python 제출을 허용하지 않아, 정확한 정답 여부는 알 수 없다.

 

코테에서 유사한 문제를 풀었던 경험이 있어 어렵지 않게 풀었다.

"제자리에 있기"를 탐색 방향에 포함하는 것이 까다로운데, 시간까지 포함한 visited 배열로 관리하면 풀이할 수 있다.

 

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5LwsHaD1MDFAXc


문제 분석

지뢰찾기 형태의 2차원 배열.

지뢰가 아닌 곳을 모두 오픈하기 위한 최소 클릭 수를 구하라.

단, 주변의 지뢰 개수가 0인 곳을 클릭하면 주변 위치까지 연쇄적으로 오픈된다.

 

접근

DFS 혹은 BFS가 적절하다.

최소 값을 구하는 문제이므로 BFS로 진행하자.

 

최소가 되게 하는 클릭 수를 구하는 것이 까다롭다.

그러나 몇 가지 케이스를 상상하다보면 다음을 알 수 있다.

  • 값이 0인 곳들이 인접한 경우, 아무거나 클릭해도 모두가 연쇄적으로 클릭된다.
  • 0인 곳을 모두 클릭하고 나면, 나머지 원소는 모두 일일이 클릭해야 한다.

 

첫 번째 탐색 

  • 행렬의 모든 원소에 인접 지뢰 개수 표시 

두 번째 탐색 

  • 값이 0인 원소는 주변을 방문 처리
  • 방문 처리 중에 만나는 값이 0인 원소는 q에 삽입 후 탐색
  • 그렇지 않은 원소는 방문 처리만 

세 번째 탐색 

  • 남은 .의 개수 세기

 

코드

from collections import deque

dx = [1, 1, -1, -1, 1, -1, 0, 0]
dy = [1, -1, 1, -1, 0, 0, 1, -1]

def openMatrix(x, y):
    tmp = 0
    for i in range(8):
        nx = x + dx[i]
        ny = y + dy[i]

        if nx < 0 or nx >= n or ny < 0 or ny >= n:
            continue
        if matrix[nx][ny] == "*":
            tmp += 1
    
    matrix[x][y] = tmp


def clickZeroElement(a, b):

    q = deque()
    q.append([a, b])
    matrix[a][b] = "*"

    while q:
        x, y = q.popleft()

        for i in range(8):
            nx = x + dx[i]
            ny = y + dy[i]

            if nx < 0 or nx >= n or ny < 0 or ny >= n:
                continue

            if matrix[nx][ny] == 0:
                q.append([nx, ny])
                matrix[nx][ny] = "*"
            
            elif matrix[nx][ny] != "*":
                matrix[nx][ny] = "*"

testCase = int(input())

for tc in range(testCase):
    n = int(input())
    matrix = [list(input()) for _ in range(n)]
    total = 0

    for i in range(n):
        for j in range(n):
            if matrix[i][j] == ".":
                openMatrix(i, j)
    
    for i in range(n):
        for j in range(n):
            if matrix[i][j] == 0:
                clickZeroElement(i, j)
                total += 1
    
    for i in range(n):
        for j in range(n):
            if matrix[i][j] != "*":
                total += 1
    
    print(f"#{tc + 1} {total}")

 

 

전형적인 삼성 스타일의 문제인 듯하다.

그래도 아주 어렵지는 않다.

 

클릭 수가 최소가 되게 하는 방법을 고민하다보면, 완전 탐색으로는 불가능하다는 것을 알게 된다.

그 상태에서 문제의 조건에 집중하면 풀이에 접근할 수 있게 된다.

 

직관적으로도 지뢰찾기 게임을 할 때 0부터 클릭하지 않는가.


참고

https://heo-it-til.tistory.com/entry/SWEA-D4-%ED%8C%8C%ED%95%91%ED%8C%8C%ED%95%91-%EC%A7%80%EB%A2%B0%EC%B0%BE%EA%B8%B01868-Python

https://app.codility.com/programmers/lessons/9-maximum_slice_problem/max_double_slice_sum/


문제 분석

주어진 배열에서 최대가 되는 부분합을 찾아야 한다.

이때 조건으로 X, Y, Z 3개의 범위를 고려해야 한다.

 

X보다 큰 범위이어야 한다.

Y는 제외해야 한다.

Z보다 작은 범위이어야 한다.

`DoubleSlice의 합: A[X + 1] + A[X + 2] + ... + A[Y − 1] + A[Y + 1] + A[Y + 2] + ... + A[Z − 1]`

 

접근

head: 왼쪽 -> 오른쪽 방향의 부분합 / tail: 오른쪽 -> 왼쪽 방향의 부분합을 구함.

Y를 기준으로 head[i-1] + tail[i+1]의 최댓값을 구함.

 

 

A = [3, 2, 6, -1, 4, 5, -1, 2]일 때 두 배열의 누적합을 구하면 다음과 같다.

head = [0, 2, 8 7, 11, 16, 15, 0]

tail = [0, 16, 14, 8, 9, 5, 0, 0]

 

위 두 배열을 Y를 기준으로 head[i-1] + tail[i + 1]이 최대가 되는 값을 구하면,

Y를 기준으로 왼쪽 배열의 최대 부분합 + 오른쪽 배열의 최대 부분합을 구하는 것과 같다.

 

풀이

def solution(A):
    if len(A) == 3: 
        return 0
        
    head = [0] * len(A)
    tail = [0] * len(A)

    for i in range(1, len(A) - 1):
        head[i] = max(0, head[i - 1] + A[i])
    
    for i in range(len(A)-2, 0, -1):
        tail[i] = max(0, tail[i + 1] + A[i])
    
    max_sum = 0

    for i in range(1, len(A) - 1):
        max_sum = max(max_sum, head[i - 1] + tail[i + 1])

    return max_sum

 

 

참고

https://jaejade.tistory.com/121

https://gets-better.tistory.com/m/9

https://sustainable-dev.tistory.com/25

 

 

 

 

서론

 

4트 만에 싸피를 합격했다.

첫 번째 이후로는 간절하게 준비하지는 않았지만, 합격은 언제나 기분이 좋다.

 

싸피에 대한 정보는 이미 넘쳐흐른다. 분명 다른 곳에서 더 잘 다루고 있을 것이다.

아래 글에서는 개인적인 내용에 대해서 담아보겠다.


스펙

학교: 중경외시
학과: 상경 계열
학점: 3점 초반대

인턴: x
창업: 1회
SW 교육: 다수 (장기 2회, 단기 3회)

수상: x
프로젝트: 다수 (대표 프로젝트 2개)
어학: 토익 885 / OPIc IM2
자격: 정보처리기사

 

가장 관심이 많을 것 같다.

성인이라면 누구나 숫자에 민감하지 않은가.

뛰어나고, 부족하고를 떠나서 본능적으로 관심이 생기는 듯하다. 나도 그랬다.

 

채용자의 입장에서 나의 스펙을 분석해 보자.

 

학교는 나쁘지 않다.

학과는 특이하다. SW 비전공자. 면접 때마다 질문받는 나의 약점이자 기회이다. 다행히 수학이랑은 꽤 친했다. 독학으로 CS 과목을 공부했다. 부족하지만 지금껏 면접 질문에는 잘 대답했다.

학점은 부족하다. 반대급부로 SW 관련 전공에 대한 학점이 아니기에, 학점과 관련된 공격을 받아본 적은 없다.

 

인턴 경험이 없다. 이것도 단점이다. 면접 스터디를 해보면 보통 인턴 1회쯤은 있더라.

창업은 나의 가장 큰 무기이다. 회사가 20여 명 규모로 커질 때까지 해봤다. 모든 면접에서 관련 질문을 받았다. 나로서도 할 말이 많다.

SW 교육은 넘치게 받았다고 생각한다. 사실 이제는 취업을 해야 하는 타이밍이다.

 

수상 경험이 없다. 이것도 약점이다.

프로젝트는 많이 해봤다. 팀 프로젝트, 개인 프로젝트 모두 했다. 이런저런 기술적 문제와 갈등 해결 경험이 있다.

어학은 평범하다. 공식 문서나 영문 정보를 접하는 데에 문제가 없는 수준이다.

자격은 기사 자격증이 하나 있다.

 

종합해 보면 면접관 입장에서는 다음과 같은 질문을 하고 싶어진다.

  • 비전공자인데 개발을 하게 된 이유?
  • 개발을 잘하는지?
  • 회사 잘 다닐 수 있는지?

싸피도 다르지 않았다.

구체적인 인터뷰 질문을 언급할 수는 없지만, 대략 이런 느낌으로 질답이 오갔다.

 

 

싸피 준비 과정

 

싸피를 4트 했다.

또 상반기에는 치열하게 취업 준비를 했다.

 

그래서 이번에는 싸피를 위해 따로 준비한 것은 없다.

그렇지만 몇 가지를 적어보겠다.

 

에세이

싸피를 첫 번째로 도전할 때는 그런 내용을 적었다.

나는 어떤 사람이고, 무엇 때문에 개발을 시작했고, 싸피에서는 스터디를 만들어서 어떻게 해보겠다.

 

첫 번째, 두 번째, 세 번째 모두 떨어졌다.

그래서 이번에는 솔직하게 적고 싶은 것을 적었다.

 

취업 과정에서 코딩 테스트를 통과하기 위해 내가 노력한 것.

현재 부족한 유형과 그것을 위해 노력하고 있는 것.

싸피를 이용해서 취업을 하기 위한 로드맵.

 

에세이가 이번 합격의 핵심 변수인지는 모르겠다.

어쨌든 솔직하게 구체적으로 적었더니 합격했다.

 

테스트 (수추리 / CT)

수추리: 10문제

1차 CT: 올솔

 

수추리는 항상 특정 유형이 까다롭다. 나머지는 모두 풀었다.

1차 CT는 내가 응시한 타임이 쉬웠다. 검산까지 하고 시간이 조금 남았다.

 

원래 숫자를 좋아하고, 알고리즘 문제를 꾸준히 풀고 있어서 따로 준비하지 않았다. 취준으로 바쁘기도 했다.

다만 첫 번째 응시 때 '에듀윌 SSAFY 통합 기본서'를 한 권 풀었었다.

 

본인이 비전공자이고, 수추리 문제에 대한 경험이 부족하다면 아무 서적이나 한 권 정도 푸는 것을 추천한다.

각 유형에 대한 풀이법을 익히는 것이 중요하기 때문이다.

싸피의 수추리는 시간이 부족한 편이다.

 

 CT는 기본적인 알고리즘 문제 몇 개 풀어보고 응시하면 좋다.

유형은 상관없다. 이쪽 뇌를 활성화시키는 게 중요하다. 그래도 고르자면 DP.

본인이 멘사 퀴즈에 관심이 많은 사람이라면, 따로 공부하지 않아도 잘 풀 것이다.

 

인터뷰

2차 CT

올솔. 어렵지 않았다. 1차 CT보다는 시간이 부족했다.

 

PT 면접

모두가 아는 강민혁 님의 그 영상을 보고 그대로 준비했다.

IT 상식은 뉴스 보는 게 취미라서 따로 공부하지는 않았다.

 

시간이 많다면 슈카월드를 꾸준히 보면 좋다.

시간이 부족하다면 과기정통부 블로그, 삼성 기술 블로그, 지디넷코리아, 네이버 뉴스 IT탭 등에서 소스를 얻으면 좋다.

 

IT에 대한 관심을 보일 수 있는 정도이면 된다.

이것만을 위해서 논문을 찾아보지 않아도 괜찮다.

 

무엇보다 PT 할 때 논리적인 구조를 갖고 하는 것이 가장 중요하다.

 

인성 면접

취준 하며 정리했던 예상 질문 + 싸피(SW 교육)에서 나올 수 있는 질문을 준비했다.

이미 기업 면접 스터디를 하고 있었기에 싸피를 위한 스터디는 따로 하지 않았다.

 

느낀 바가 있다면 나에 대한 메타인지가 중요하다.

나는 왜 그 선택을 했는가?를 항상 달고 다니자.


나에게 싸피란?

 

여기까지 보는 사람은 많이 없을 것이라고 생각한다.

있다면 나의 채용을 고민하는 누군가이지 않을까.

 

내가 싸피를 선택한 이유는 2가지이다.

 

1. 지원

싸피가 지원해 주는 것은 교육지원금, 학습 환경, 강의가 주요하다.

 

교육지원금을 받으면 여유가 생겨서, 기업을 지원할 때 난사하는 것이 아니라, 정말 가고 싶은 곳을 꼼꼼하게 따져볼 수 있게 된다.

학습 환경은 오프라인에서 개발에 열정적인 친구를 만날 수 있는 것이 크다. 질답과 토론을 통해 학습한 지식은 무엇보다 단단하다. 비전공자로서 SW를 공부할 때 가장 아쉬운 부분도 이것이다. 그래서 오프라인 SW 교육을 찾아다녔다.

강의도 알고리즘 중심이라는 것이 좋았다. 여러모로 취준에 최적화된 커리큘럼이라고 느꼈다.

 

2. 백엔드

프로젝트에서 백엔드까지 다뤄보고 싶었다. iOS 개발자로 취업을 준비하면서, 현실의 개발은 그리 단순하지 않다는 것을 알게 됐다. 특히 올리브영 앱 개선 프로젝트를 하면서 하나의 기능을 구현하기 위해 FE, BE 지식을 학습해 가는 재미가 쏠쏠했다. 직접 개발하지 않더라도 알 때와 모를 때의 소통 비용 차이는 현격하다. 

 

2024 하반기이자 싸피의 1학기에는 iOS 직군으로 계속 해서 취업에 도전할 것이다.

경험도 있고, 자신감도 충분하고, 흥미도 있기 때문이다.

 

동시에 BE에 소홀하지 않을 것이다.

iOS + BE를 연결한 프로젝트를 만들기 위해서도, 프로젝트에 충분한 기여를 하기 위해서도 그렇다.

첫 번째 목표는 싸피 1학기 성적 우수상이다.

 

마무리

 

iOS와 BE 둘 다 잘하려면?

시간을 갈아 넣어야 한다. 그렇게 할 것이다.

 

정규 시간에는 BE

그 외 시간에는 iOS

스터디는 알고리즘 / CS

 

취업하는 그날까지 다시 열심히 달려보자.

아자아자.

https://app.codility.com/programmers/lessons/9-maximum_slice_problem/max_slice_sum/


문제

A non-empty array A consisting of N integers is given. 
A pair of integers (P, Q), such that 0 ≤ P ≤ Q < N, is called a slice of array A. 
The sum of a slice (P, Q) is the total of A[P] + A[P+1] + ... + A[Q].

Write a function:
    def solution(A)
that, given an array A consisting of N integers, returns the maximum sum of any slice of A.

For example, given array A such that:
A[0] = 3  A[1] = 2  A[2] = -6
A[3] = 4  A[4] = 0

the function should return 5 because:
(3, 4) is a slice of A that has sum 4,
(2, 2) is a slice of A that has sum −6,
(0, 1) is a slice of A that has sum 5,
no other slice of A has sum greater than (0, 1).
Write an efficient algorithm for the following assumptions:

N is an integer within the range [1..1,000,000];
each element of array A is an integer within the range [−1,000,000..1,000,000];
the result will be an integer within the range [−2,147,483,648..2,147,483,647].

문제 분석

Maximum slice 유형.

번역을 한다면 '배열에서 최대가 되는 부분합' 정도가 되겠다.

배열의 길이가 1,000,000 이하이므로 반드시 O(N) 이하의 시간복잡도로 풀어야 함.

 

배열의 원소의 범위는 [-1,000,000 ... -1,000,000] 이다.

Codility의 교육 자료에 있는 O(N)으로 풀이하려 했으나, 추가적으로 원소가 음수인 경우를 처리해야 한다.

 

풀이

def solution(A):
    max_ending = max_slice = A[0]

    for i in range(1, len(A)):
        max_ending = max(A[i], max_ending + A[i])
        max_slice = max(max_ending, max_slice)
    
    return max_slice

 

max_ending과 max_slice를 명확히 하고 넘어가야 이 간단한 코드를 이해할 수 있다.

  • max_ending: 현재 인덱스까지의 부분 배열 중에서 가장 큰 합
  • max_slice: 현재까지 찾은 모든 부분 배열 중에서 가장 큰 합

좀 더 설명해 보자면,

max_ending은 반복문을 실행하는 각 단계에서, 현재 부분 배열(지금 배열이 최선이라고 가정하고 계산 중인)의 최대 합을 계산한다.

max_slice은 모든 max_ending을 비교하여(실제로는 모든 값을 나열하고 비교하지 않는다. 하지만 모든 max_ending은 max_slice에 게 도전하게 된다.) 최대 합을 계산한다.

 

한 줄씩 이해해 보자.

 

`max_ending = max_slice = A[0]`

초기화 하는 부분이다.

배열의 첫 번째 원소로 초기화 한다.

0으로 초기화를 하면, 모든 원소가 음수인 경우 0을 반환하는 문제가 생긴다.

 

`for i in range(1, len(A)):`

첫 번째 원소로 초기화 했으니, 첫 번째 원소는 건너뛴다.

 

`max_ending = max(A[i], max_ending + A[i])`

가장 고민을 많이 한 부분이다.

max_ending을 갱신할 때 무엇과 비교해야 하는가?

 

max() 함수의 두 번째 인자는 현재 부분 배열에 새로운 값을 더한 것이다. 자연스럽다.

첫 번째 인자는 A[i], 현재 항이다.

현재 진행 중인 부분 배열 vs 새로 시작하는 것 중에서 비교하는 것이다.

 

`max_slice = max(max_ending, max_slice)`

현재 진행 중인 부분 배열이, 현재까지 최대 합인 max_slice에 도전하는 부분이다.

현재 진행 중인 것이 더 크면 왕위를 계승한다.

직관적이다.

 

후기

Maximum slice 유형을 O(N)에 풀이할 수 있는 뼈대 코드이다.

그래서 좀 깊게 분석해봤다.

+ Recent posts