첫 기술 면접 후기 - 평가는 없었고 성장만 있었다

꾸Jun·2025년 7월 17일
0

🍎 iOS

목록 보기
22/25

최근, 평소에 관심을 갖고 지켜보던 한 IT 기업의 iOS 개발자 직무로 1차 기술 면접을 볼 기회가 있었다. 첫 기술 면접이라 많이 떨렸지만, 30분이라는 짧은 시간 동안 4년간 배운 컴퓨터 과학의 핵심을 압축적으로 돌아보는 매우 깊이 있는 경험이었다.

단순한 iOS 지식을 넘어, 소프트웨어 엔지니어로서의 기본기를 얼마나 중요하게 생각하는지 온몸으로 느낄 수 있었다. 모든 질문을 다 기억하지는 못하지만, 내가 기억하는 선에서 받았던 질문들과 그에 대해 다시 공부하며 정리한 내용들을 복기해보고자 한다.



1. 데이터의 가장 작은 단위부터

면접은 가장 근본적인 질문에서부터 시작되었다.

  • Q: 1바이트(Byte)가 무엇이고, 이걸로 무엇을 할 수 있나요?

    A: 1바이트는 8개의 비트(bit)로 이루어진 데이터의 기본 단위다. 컴퓨터가 데이터를 처리하고 메모리 주소를 지정하는 가장 작은 단위이기 때문에 중요하다. 면접관님께서 이걸로 무엇을 할 수 있는지 추가로 물어보셨고, 나는 아스키(ASCII) 코드처럼 간단한 문자들을 표현할 수 있다고 답했다.

  • Q: 부동소수점의 오류에 대해 이야기하다가, 그렇다면 int 자료형에서 음수는 어떻게 표현하는지 질문하셨습니다.

    A: 64비트 시스템에서 Int는 보통 8바이트(64비트)의 크기를 가진다. 부호가 있는 정수(signed integer)의 경우, 맨 앞의 1비트는 부호(0은 양수, 1은 음수)를 나타내는 데 사용하며, 음수는 2의 보수(2's Complement) 방식으로 표현한다. 어떤 수의 모든 비트를 뒤집고 1을 더하는 방식인데, 이렇게 하면 컴퓨터가 덧셈 연산만으로 뺄셈을 수행할 수 있어 하드웨어적으로 매우 효율적이다. 이 때문에 Int64의 범위는 (263)-(2^{63}) 부터 26312^{63}-1 까지가 된다.

  • Q: let a = (0.1 + 0.2 == 0.3) 일 때 print(a)의 결과는 무엇이고, 그 이유는 무엇인가요?

    A: 결과는 false가 나온다. 이는 컴퓨터가 0.1이나 0.2와 같은 십진수 소수를 이진수로 정확하게 표현하지 못하기 때문에 발생하는 부동소수점(Floating-point)의 근사치 오류 때문이다. 0.1 + 0.2의 결과는 0.3이 아닌 0.30000000000000004와 같은 근사값이 되어, 0.3과의 비교는 false를 반환한다.



2. 화면을 그리는 원리 (Image & Pixel)

  • Q: 픽셀(Pixel)이란 무엇이며, 색은 어떻게 표현되나요?

    A: 사실 이 질문은 제가 면접에서 가장 아쉬웠던 답변이다. 픽셀의 색 표현을 빛과 0, 1 같은 추상적인 개념으로만 설명했는데, 면접이 끝나고 동기들에게 물어보니 선형대수학 시간에 배운 '벡터와 행렬' 개념이라는 것을 깨달았다.

    이를 바탕으로 다시 정리해보자면, 픽셀은 이미지를 구성하는 가장 작은 점이며, 각 픽셀은 보통 RGBA(Red, Green, Blue, Alpha) 값의 조합으로 색상을 표현한다. 각 픽셀은 R, G, B, A 값을 갖는 하나의 '벡터'로 볼 수 있는 것이다. 예를 들어 (255, 0, 0, 255)는 투명도 100%의 빨간색을 의미한다.

  • Q: 손실 압축과 비손실 압축의 차이는 무엇이며, PNG와 JPG는 각각 어디에 해당하나요?

    A: 비손실 압축(Lossless)은 원본 데이터를 100% 그대로 보존하는 방식으로, 압축을 풀어도 원본과 완벽히 동일하다. 로고나 텍스트처럼 경계가 명확한 이미지에 적합한 PNG가 대표적이다. 반면 손실 압축(Lossy)은 사람의 눈이 잘 인지하지 못하는 데이터를 일부 제거하여 파일 크기를 획기적으로 줄이는 방식이다. 풍부한 색상을 가진 사진에 적합한 JPG가 이에 해당한다.



3. 프로그램은 어떻게 살아 움직이는가? (OS & Memory)

  • Q: 시스템 콜(System Call)은 무엇인가요?

    A: 우리 앱(User Mode)이 파일 시스템 접근이나 네트워크 통신처럼 운영체제(Kernel Mode)의 보호된 기능에 접근하기 위한 공식적인 통로(Interface)다. 앱이 직접 하드웨어를 제어하는 위험을 막고, 운영체제를 통해 안전하게 기능을 요청하는 방식이다.

  • Q: 프로세스(Process)와 스레드(Thread)의 차이점은 무엇인가요?

    A: 프로세스는 실행 중인 앱 하나하나의 독립적인 인스턴스로, 각자 고유한 메모리 공간을 할당받는다. 스레드는 그 프로세스 내에서 실행되는 작업의 흐름 단위다. 하나의 프로세스는 여러 개의 스레드를 가질 수 있으며, 이 스레드들은 프로세스의 메모리 공간(e.g., Heap)을 공유한다.

  • Q: 메모리 영역(Stack, Heap 등)에 대해 설명하고, static 키워드가 붙은 변수나 ViewModel 인스턴스는 각각 어느 영역에 할당되는가?

    A: 메모리는 크게 코드, 데이터, 힙(Heap), 스택(Stack) 영역으로 나뉜다.

    • Stack: 함수 호출 시 생성되는 지역 변수나 매개변수가 저장된다. 함수가 끝나면 자동으로 사라지며, 매우 빠르다.
    • Heap: 개발자가 직접 생성하는 객체(클래스 인스턴스 등)가 저장된다. 개발자가 동적으로 메모리를 할당하고 해제하며, ARC가 이 영역을 관리한다.
    • Data(Static): 전역 변수나 static 키워드가 붙은 변수가 저장된다. 프로그램이 시작될 때 할당되어 종료될 때까지 유지된다.

    따라서 static 변수는 Data 영역에, ViewModel 클래스의 인스턴스는 동적으로 생성되는 객체이므로 Heap 영역에 할당된다.



4. 데이터를 효율적으로 다루는 법 (Database)

  • Q: MySQL 테이블에서 특정 사용자의 이메일을 조회할 때, 어떻게 하면 빠르게 찾을 수 있을까요?

    A: 이메일 컬럼에 인덱스(Index)를 생성해야 한다. 인덱스가 없다면 데이터베이스는 모든 사용자의 데이터를 처음부터 끝까지 스캔(Full Table Scan)해야 해서 매우 비효율적이다.

    인덱스는 책의 '찾아보기'처럼, 특정 데이터가 디스크의 어느 위치에 저장되어 있는지 미리 정렬된 상태로 가지고 있는 별도의 자료구조다. 주로 B-Tree해시 테이블 방식으로 구현된다. 이메일로 검색 시, 전체 테이블이 아닌 훨씬 작은 인덱스 테이블만 탐색하면 되므로 검색 속도가 비약적으로 향상된다.

    특히, 해시 테이블(Hash Table) 인덱스의 동작 원리는 다음과 같다.

    1. 해시 함수(Hash Function): 먼저, 이메일 주소('키')를 해시 함수에 넣어 특정 숫자('해시 값')로 변환한다.
    2. 직접 접근: 이 해시 값을 배열의 인덱스로 사용하여, 데이터가 저장된 위치를 단 한 번의 연산으로 바로 찾아간다.

    이러한 방식 덕분에, 키를 처음부터 끝까지 검색(O(n))하는 것이 아니라 해시 함수 계산(O(1)) 한 번으로 위치를 알아낼 수 있어, 평균적으로 O(1)의 매우 빠른 시간 복잡도를 가진다. B-Tree 인덱스가 범위 검색(BETWEEN, >)에 유리하다면, 해시 테이블 인덱스는 이메일처럼 특정 값과 정확히 일치하는 데이터를 찾을 때(동등 비교) 최고의 성능을 발휘한다.

  • Q: 딕셔너리 자료형으로 값을 찾을 때, 시간 복잡도가 왜 O(1)인가요? 키값을 어차피 찾아야 하면 O(n) 아닐까요?

    A: 이 질문에 나는 Array는 O(n), Dictionary는 O(1)이라고 답했지만, 왜 O(1)인지 그 원리는 정확히 설명하지 못했다.

    다시 공부해보니, 딕셔너리는 내부적으로 해시 테이블(Hash Table)로 구현되어 있기 때문이었다. 키값을 그냥 순서대로 찾는 것이 아니라, 해시 함수(Hash Function)를 통해 키를 특정 숫자(해시 값)로 변환한다. 이 해시 값은 배열의 인덱스로 사용되어, 데이터가 저장된 위치를 단 한 번의 연산으로 바로 찾아갈 수 있다. 키를 처음부터 끝까지 검색(O(n))하는 것이 아니라, 해시 함수 계산(O(1)) 한 번으로 위치를 알아내는 것이다. 물론 해시 충돌이 발생하면 성능이 저하될 수 있지만, 평균적으로는 O(1)의 매우 빠른 시간 복잡도를 가진다.



5. iOS 개발자라면 반드시 알아야 할 것

  • Q: iOS의 ARC란 무엇인가요?

    A: ARC(Automatic Reference Counting)는 Swift의 메모리 관리 방식으로, 각 클래스 인스턴스가 몇 개의 강한 참조(Strong Reference)에 의해 참조되고 있는지 그 횟수를 자동으로 추적한다. 이 참조 카운트가 0이 되면, 더 이상 해당 인스턴스를 사용하는 곳이 없다고 판단하여 메모리에서 즉시 해제한다.

  • Q: 메인 스레드와 백그라운드 스레드는 왜 구분해서 사용해야 하는가?

    A: 메인 스레드는 오직 UI 업데이트와 사용자 이벤트 처리만을 위해 예약된 전담 스레드다. 만약 여기서 네트워크 통신이나 파일 저장 같은 무거운 작업을 실행하면, UI가 멈추고 앱의 반응성이 떨어지는 '프리징(Freezing)' 현상이 발생한다. 따라서 이런 무거운 작업들은 반드시 백그라운드 스레드로 보내 처리하고, 그 결과값을 가지고 UI를 업데이트해야 할 때만 다시 메인 스레드로 돌아와야 한다.

  • Q: 아이폰 화면 밝기를 다르게 하고 스크린샷을 찍으면, 결과물이 다를까요?

    A: 나는 "같을 것 같습니다"라고 답했다. 그 이유에 대해 "자세한 내용을 모르겠지만 추측하자면, UI를 그리는 것은 메인 스레드에서 담당하고 스크린샷 기능은 백그라운드에서 담당해서 실제 영향을 주지 않을 것 같습니다"라고 답했다.

    면접이 끝나고 다시 생각해보니, 내 추론의 방향은 맞았지만 더 근본적인 원리가 있었다. 스크린샷은 GPU의 프레임 버퍼(Frame Buffer)에 렌더링된 디지털 데이터를 직접 이미지 파일로 저장하는 과정이다. 화면 밝기 조절은 이 프레임 버퍼의 데이터가 디스플레이 패널로 전송된 후, 패널 자체의 밝기(백라이트 등)를 조절하는 하드웨어적인 제어다. 따라서 원본 데이터 자체는 동일하기 때문에 스크린샷 결과물은 항상 같다.



느낀점: 평가는 없었고, 성장만 있었다

처음에는 면접이라는 생각에 많이 긴장했지만, 딱딱한 질의응답이 아닌 선배 개발자님과 편안하게 이야기하는 방식으로 진행되어 금방 긴장을 풀 수 있었다. 특히 인상 깊었던 점은, 내가 정답을 말하지 못할 때도 다그치기보다는 내가 가진 지식을 바탕으로 최대한 답에 근접하게 추론할 수 있도록 질문을 던져주셨던 것이다. 그래서 나도 아는 부분은 자신감 있게 설명하고, 모르는 부분은 솔직하게 모른다고 말씀드리면서도 내 생각을 끝까지 이야기해볼 수 있었다.

항상 면접은 '나를 평가받는 어려운 자리'라고만 생각했는데, 이번 경험을 통해 '내가 4년간 배운 지식에 대해 전문가와 즐겁게 떠드는 자리'가 될 수도 있다는 것을 깨달았다. 면접을 준비하고, 또 직접 면접을 보는 모든 과정 속에서 내가 한 뼘 더 성장했음을 느낀다.

이 글을 보실지는 모르겠지만, 좋은 질문과 인사이트를 통해 배움의 기회를 주신 면접관님께 진심으로 감사하다는 말을 드리고 싶다🙏🏻.



마치며

30분 동안 정말 많은 것을 돌아볼 수 있는 귀중한 시간이었다. 모든 질문에 완벽하게 답하지는 못했지만, 이번 면접을 통해 내가 어느 부분이 부족하고 무엇을 더 깊이 공부해야 하는지 명확하게 알 수 있었다. 앞으로의 성장 방향을 잡는 데 큰 도움이 된, 중요한 터닝포인트가 될 것이다.

profile
꾸준🐢

0개의 댓글