크래프톤 정글에 들어오게 된 이유 중 하나. 기대했었고, 만족한다.
C언어로 자료구조를 구현하면서 포인터에 상당히 익숙해졌다. 그러나 구현하는 과정에서 이중 포인터와 타입 캐스팅, (char **) / (void **) 가 쉽게 이해되진 않았다. 공통 퀴즈를 풀면서, 변수 타입을 읽는 방법도 서툴다는걸 알았다. 이번 기회에 AI 문제를 풀면서, 취약점을 빠르게 보완했다. 덕분에 수요코딩회때 B+Tree 인덱스 구조체와 split을 빠르게 이해할 수 있었다.
구현하면서 필요성을 절실히 느꼈다. malloc을 implicit linked list로 구현했었다. 어렵지 않게 구현을 완료했는데, 테스트에서 문제가 발생했어. 테스트 파일이 10개였는데 9,10번에서 통과를 못했다. 테스트파일마다 특정 함수를 확인하도록 만들어져있었다. 따라서 해당 함수에서 디버깅을 시작했다.
문제는 다른 함수에 있었다. 원인은 힙 상태가 예전에 깨졌었고, 나중에야 문제가 터진 것이다. 추적하면서 하나하나 고쳐나가니 시간도 오래 걸리고, 더 많은 에너지가 필요했다. gdb 프로그램을 이용해 메모리에 저장된 값을 확인하면서 추적했고, 결국 매크로를 잘못써서 생긴 문제였다.
다루는 구조체 상태를 제대로 관리하지 못하면, 시한폭탄이 될 수 있다. 그래서 explicit linkedl list로 구현할땐, 기능을 구현할때마다 assert와 힙 상태를 체크하는 함수를 별도로 사용해 의도한대로 동작했는지를 추가 확인했다. 문제는 무조건 생기는데, 나중에 터지는것보다 바로바로 잡아내는것이 중요하다.
PintOS에선 AI를 전혀 사용하지 않고, 개발해야한다고 들었다. 이때, gdb같은 디버깅 프로그램을 사용해 해결해야한다. 그래서 최소한의 구현이후에 디버깅 경험을 쌓는걸 목표로 잡았다.
일부 코치님들은 gdb말고 더 좋은 디버깅툴이나 방법이 있다고 하신것같다. 그런데, 그게 무엇인지는 알려주시진 않았다.

B+Tree 인덱스를 활용한 DB를 만들어보고, 전체 순회와 인덱스 성능 비교
저번 파일 기반으로 DB를 만든 저번주 과제에서 확장시킨 프로젝트다.
삽입은 인덱스가 없는것이 더 빠르다. 테이블에 레코드를 삽입 후, 인덱스 갱신 작업이 들어가기 때문이다. 대체적으로 order가 클수록 삽입 속도도 빨라졌다. 꼭 그런것은 아닌게 기억에 남았다. order가 커지면 트리 높이가 줄어들 순 있지만, 한 노드에서 비교할 키가 많아지게 된다. 따라서 order가 크다고 항시 빨리지진 않았다.
탐색 속도는 인덱스를 사용하는게 압도적으로 빨랐다. 키 별로 인덱스를 만들 수 있는데, 포인트는 인덱스에 사용할 키를 선정하는것이다. 인덱스는 탐색할 대상을 빠르게 찾아주는데, 찾아야할 대상이 많아진다면 순차탐색보다 매력적이지 못하다. 따라서 키가 조건을 만족할 때 결과가 크지 않아야 한다. 의문은 실행하기 전에, 어떻게 결과가 많고 적은지 알 수 있냐는 것이다. AI에게 물어보면, 이전 결과를 기반으로 통계를 낸다고 한다. 통계상 이 조건을 사용하면 얼만큼의 결과가 생길것인지 보고, 순회할지 인덱스를 사용할지 판단한다.
order가 커진다고 좋은것은 아니다. 진행한건 간이 DB이기 때문에 적용되는지는 모르겠다. 그러나 실제 DB는 디스크 기반으로 알고있다. 그래서 한 노드 정보가 한 페이지안에 들어가야, 탐색 시간이 줄어든다. 때문에 order크기가 페이지보다 커지지 않게 설정해야한다.
B-tree 대신 B+tree를 선택한 이유는 범위 탐색도 있지만, B-tree 노드가 B+tree보다 무겁기 때문이다. B-tree는 내부 노드에 비교하는 키 값들이 같은 경우에 즉시 해당 레코드에 접근할 수 있다. 노드에 데이터 포인터가 들어있기 때문이다. 그래서 B-tree 노드는 B+tree 노드보다 무겁다. 한 페이지에 많은 정보를 저장해서 디스크 암을 최대한 덜 이동시키는게 포인트다. B+tree 노드는 비교할 키값과 자식 노드 포인터들만 담고 있기 때문에 메모리 측면에서 B+tree가 유리하다.
B+tree 에서 Delete 연산을 구현하면 redistribution, merge 작업도 배울 수 있었을 것이다. 과제 범위 밖이기도 했고, 이번 협업 방식으로는 구현할 시간이 부족했다.
B+tree 장점 중 하나가 범위 탐색이다. 그런데, 내가 만든 SQL 파서기에 between을 처리하는 기능이 없다. 그렇다고 그걸 추가로 구현할 시간을 내기도 어려웠다.

개념 퀴즈
제한시간동안 수요코딩회에 사용되는 개념들을 빠르게 학습하고, 각자 퀴즈를 풀어보았다. 퀴즈는 이번 프로젝트에 필요한 개념, 관점을 AI를 통해 만들었다. 이해수준을 확인하여 내가 제대로 학습하고 있다는걸 확인할 수 있었다. 인상적인건 B+Tree index split 과정을 직접 손으로 작성해보는 문제였다. 직접 해보니 내 생각과 다른 결과가 정답이였다. 어떤 규칙이 있는건지 명확히 이해하는 계기가 되었다. 배워야할게 정말 많지만, 당장 필요한것 순으로 학습하니 프로젝트 진행에 효과적이였다.
분업
지금까지 경험으로 작업은 병렬적으로 진행되도록 만드는것이 중요하다. 특히, 하루라는 짧은 기간내에서는 더욱 중요하다. 누군가의 작업이 끝나긴 할지, 끝나면 언제인지 모른다. 그 동안 다른 작업을 하면 된다고 생각했지만 작고 빠르게 만들어보는게 학습 효과가 더 높다. 그런면에서 팀은 밴치마크, 엣지 케이스, 발표 준비등으로 분업이 잘 되어 나름 빠르게 끝낼 수 있었다.
사이클 3번로 인한 피로
학습을 위해 프로젝트를 기본 기능을 3단계로 나누어 진행했다. 한 사이클은 45분 학습으로 구성되었다. 이 동안 개념학습과 사이클 목표까지 구현하는것이다. 구현이야 AI를 이용하면 만족스러운 결과가 나온다. 그러나 45분씩 학습을 3번 진행하면 집중력을 유지하기 어려웠다. 춘공증, 더위도 한 몫 했다. 조금 더 여유를 가지면 좋지 않았을까.
파편된 이해도
분업이 작업을 효과적으로 진행시킬 순 있지만, 전체를 이해하기 어렵다. 본인 담당 내용만 알게 되고, 다른 사람의 작업은 이해하기 어렵다. 더군다나 시간이 부족해지면서 더욱 여유가 없어진다.
퀴즈를 적극 이용
공용 퀴즈가 프로젝트에 필요한 개념 학습에 효과적이였다. 매번 사이클마다 퀴즈를 풀어보면 좋을 것 같다.
자신의 작업을 문서로 남기고 공유하기
본인의 작업을 문서로 조금씩 정리하고, 매 시간마다 공유하는것이다. 담당하는 업무와 진행상황을 이해시켜, 프로젝트 전반 이해도를 높여보려 시도해봐야겠다.
좋은 글 잘 보고 갑니다.