본문 바로가기

공부기록/42 Seoul

42 과제에서 배운 것 정리

Libft

libc의 유용한 함수들을 reproduce 하면서 나만의 C언어 라이브러리를 만들어본다.

memset, memcpy 와 같이 메모리를 만지는 함수 또는 substr, split과 같은 문자열 관련 함수를 만들면서 포인터와 메모리 관리를 이해할 수 있다. 구현해야할 함수가 정말 많은데, 하나하나 구현하는 과정이 다음 과제인 gnl과 ft_printf 를 구현하기 위한 기초체력이 된다.

netwhat

subnetmask 계산방법, IP 주소의 클래스, OSI layer 등 네트워크의 기초를 쌓을 수 있다. 문제은행식으로 진행되기 때문에 깊게 공부하지 않아도 통과할 수 있는데, 네트워크 분야에 어떤 키워드들이 있는지 알아둘 수 있었다.

get_next_line

데이터를 file descriptor로부터 \n 또는 EOF 기준으로 한 줄 씩 읽는 함수를 구현한다.

파일입출력을 위한 시스템콜 함수, static 변수에 대해 공부했다. 빈 파일을 읽는 경우, 개행문자로 끝나는 경우 등 다양한 상황을 고려하면서 내 코드의 로직을 갈아엎기도 하고 메모리 누수를 찾다가 포인터 책을 사서 공부하기도 하고 삽질을 많이 했던 과제.

ft_printf

printf 함수를 똑같이 구현하는 과제다.

이 과제에서 새로 배우는 개념은 가변 매개변수 va_arg 정도... ? 하지만 진짜 어려운건 이런게 아니지. 이 과제는 크게 파싱과 처리로 단계를 나눌 수 있는데, 파싱이랑 처리 둘다 너무 어려웠다. 고려해야할 경우의 수가 너무 많았기 때문이다. flag 종류도 많고 precision의 종류도 많고 서로의 우선순위까지 고려해야하다보니 짜증이 났다. 꼬박 두 달이 걸렸다. 지금도 왜 이렇게까지 세세하게 다 구현하라는 건지 납득이 안 간다. 시간 아깝다. exam02 의 printf 정도로만 했으면 적당했을 것 같다.

ft_server

처음으로 Docker 를 접해본다.

Wordpress, phpMyAdmin, SQL database 를 이용하는 nginx 웹서버를 구축해보는 과제다. self signed 인증서를 적용하면서 SSL 원리도 공부하고, Dockerfile에서 layer를 쌓아가며 Docker를 체험해볼 수 있다. 과제에서 docker-compose 를 사용하지 못하게 했는데, 토이 프로젝트 할 때는 docker-compose 도 알아봐야겠다.

cub3d

ray casting 이라는 그래픽 알고리즘을 이용해 1인칭 슈팅 게임엔진을 만들어본다.

플레이어가 1인칭 시점으로 자연스럽게 움직이는 것 처럼 보이려면 빛(ray)을 이용해 공간을 어떻게 그려야하는지에 대한 알고리즘을 공부할 수 있었다. 과제에서 요구하는 수준도 적당하고 오랜만에 수학적인 개념을 다루기도 했고 시각적인 요소도 있어서 그런가 나름 재밌게 했다. 하지만 아무래도 게임 만드는건 나랑 안 맞는 것 같다는 생각을 하게 됐다.

libasm

이 과제도 어셈블리어 맛보기 버전이라 재밌었다.

libft 에서 만들었던 strlen 같은 라이브러리 함수 몇가지를 어셈블리어로 짜는 과제다. 어셈블리어 문법, 메모리 구조, 레지스터, calling convention 에 대해 알 수 있었다. 전공자분들은 이미 학교에서 어셈블리 수업을 들어서 다 아는거라고 쉽게 하던데 난 이 과제에서 새로 알게된 지식이 정말 많았다.

minishell

bash 쉘을 구현하는 과제.

내 기준 printf 다음에 만나게 되는 두번째 고비(?)이다. 물론 printf 보단 재밌음. shell 에서 쓰이는 ls, cd, | (pipe), export, >> (redirection) 등의 명령어를 구현해야한다. 먼저 pipe(), fork(), dup2(), execve(), chdir() 와 같은 시스템함수들의 작동 원리를 이해해야 하고, 사용자의 비정상적인 명령어 입력을 방어해야해서 파싱규칙을 잘~ 정하고 명령어에 따른 처리를 해줘야하는데 그냥 다 어려웠다. 부모프로세스와 자식프로세스, 그리고 file descriptor에 대해 공부할 수 있다.

ft_services

9개의 docker container 로 구성된 쿠버네티스 클러스터를 구축한다

docker container 하나만 만들었던 ft_server 과제에서 한 단계 더 나아간다고 보면 된다. docker와 k8s의 등장배경과 서로의 관계 등의 배경지식을 공부하고 클러스터를 구축하면서 각 컨테이너들이 어떻게 통신하는지 알 수 있었다. 각 컨테이너들이 서로 통신할 수 있게 하고, 쿠버네티스가 이들을 바라볼 수 있게 설정하는 과정에서 삽질이 불가피하다. 이 과제는 동료 카뎃들과 슬랙 워크스페이스를 만들어서 하루하루 삽질했던 기록을 공유하면서 했는데, 서로의 삽질을 줄일 수 있었다. 내 삽질이 누군가에게 도움이 될 수 있음에 뿌듯한 기분은 덤.

Philosophers

운영체제의 deadlock 개념을 설명하기 위해 고안된 "식사하는 철학자" 문제를 코드로 해결해보는 과제이다.

기본적으로 프로세스와 스레드, mutex 와 semaphore 를 공부할 수 있다. 멀티 스레드, 멀티 프로세스를 어떻게 구현하는지 알았고 둘의 차이를 고려해 코딩해볼 수 있었다. CS 공부를 그냥 이론으로만 하면 재미없는데 주어진 문제를 해결하면서 자연스럽게 익히니까 지루할 틈이 없었다. 찾아보니 철학자 문제를 해결하는 로직도 여러가지더라. 나중에 보니 기억이 잘 안나는데 정리 더 꼼꼼히 해둘걸.

cpp module

객체지향프로그래밍 체험판(체험판 치고는 양이 많음;;)

c piscine 처럼 cpp00 부터 cpp08 까지 하나씩 깨면서 c++ 문법과 OOP 개념을 익힌다. 클래스, 인스턴스 개념부터 다형성, 상속, 템플릿, STL 까지 꼼꼼하게 다루는데 과제 컨셉이 너무 재미없어서 지루했다. 그냥 C++ 책 하나 정해서 패는게 더 재밌을 것 같다. 아무튼 여기서 C++이랑 많이 친해져야 다음 과제인 ft_container 와 webserv 를 수월하게 할 수 있다. 

webserv

HTTP 프로토콜 기반으로 소켓 통신을 하는 웹서버를 구현한다.

nginx를 만든다고 생각하면 될 것 같다. HTTP/1.1 의 RFC 명세를 준수해야해서 읽어야할 문서가 굉장히 많았다. 서버측의 소켓 프로그래밍이 어떤 흐름으로 이루어지는지, 클라이언트에서 http 요청을 보내면 서버에서 요청 메시지를 어떻게 파싱하는지, 어떻게 요청에 알맞은 응답을 만들어서 다시 클라이언트에게 전송하는지를 이해할 수 있었다. web의 통신방식에 대해 자세히 알 수 있는 과제였다.

공부는 공부고 구현은 구현이지... webserv는 스케일이 너무 방대해서 reference로 삼은 다른 사람의 코드를 읽고 이해하는 것만 해도 많은 시간이 걸렸다. 구현하고 갈아엎고 또 갈아엎는 과정을 더이상 겪기 싫어서 다양한 코드를 보고 괜찮게 설계했다는 생각이 드는 코드를 reference로 잡고 시작했다. webserv는 팀 과제다. 팀으로 진행하면 좋은점은, 나보다 잘하는 팀원이 어디까지 고민하는지 보고 그 과정을 배울 수 있다는 점인 것 같다. 다른 팀원이 디자인 패턴까지 고민하면서 코드를 개선하는 모습을 보고 평소에는 고려하지 않던 부분까지 생각해 볼 수 있어서 좋았다. webserv를 하면서 앞의 과제들을 찬찬히 밟아왔기 때문에 이 과제를 해낼 수 있었지 않았나하는 생각이 들었다. 예를 들어 CGI 처리는 프로세스를 새로 만들어서 처리해야 하는데, minishell 에서 fork, dup2 함수와 file descriptor 를 미리 다뤄본게 도움이 됐다. 그리고 지금까지 거의 모든 과제에서 파싱한 데이터를 어떻게 저장할지 고민해야했던 것도 도움이 된 것 같다. minishell, printf 에서는 한 line을 파싱하고, cub3d에서는 간단한 config 파일을 파싱한다. webserv에서는 중첩된 괄호로 이루어진 서버 설정 파일을 파싱해야 돼서 거의 파싱 끝판왕이었다. 처음으로 map 자료구조를 이용한 파싱을 해봤다. 그동안 파싱을 하면서 짜증만 났었는데, 작은 단위의 파싱을 조금씩 해보면서 올라온 게 그나마 다행이라는 생각을 했다.

 

 

ft_container, transcendence

아직 안함

 

총평

프로젝트 베이스 과제의 장점

  • 과제 해결이라는 동기가 있어서 공부를 의욕적으로 할 수 있음.
  • 사람마다 다르게 구현한 걸 보면서 다양한 스타일을 볼 수 있고 내가 생각 못한 지점을 체크할 수 있음.

42 커리큘럼 장점

  • 비전공자는 unmanaged language 를 이렇게 빡세게 해볼 수 있는 기회를 갖기 어려운데 그런 점에서 좋음.

 

잘한점?

  • 고민했던 부분들과 더 자세히 공부해본 내용을 블로그에 기록으로 남겨둔 것
    나중에 코드 다시 보면 정말 기억이 안나는데 블로그에 정리해둔걸 보면 기억을 되살리는데 도움이 많이 된다.
  • 평가자에게 최대한 잘 설명하기 위해 어떻게 설명할지 미리 고민하고, 애매하게 알고 있는 부분을 다시 정리함.
    내 머리속의 지식을 전달하는 연습을 하면서 이해를 더 탄탄하게 할 수 있게 되는게 동료평가의 장점인 것 같다.
  • 좀 더 확실히 알아두고 싶은 부분에 대해서는 책을 찾아봄. 책은 지식이 잘 정제돼 있어서 연관된 주제와 흐름을 볼 수 있어서 좋다.

 

아쉬운점?

  • 기록을 더 꼼꼼히 남기지 않은 것 (시간 없다는 핑계로)
  • 의문점이 생기면 100% 파보지 않고 60~70%정도만 파보고 관둔 것 (시간 없다는 핑계로)
  • 과제 통과 후 리팩토링을 시도하지 않은 것 (시간 없다는 핑계로)