【42Tokyo】本科のカリキュラムと得られるスキルや投下時間 【開始半年で500時間】
無事にブラックホールを生き残ることができ、達成感が非常に大きいので、今年の振り返りも兼ねて、半年やった結果を色々とまとめていきたいと思います
対象
これから42Tokyoに通おうと思ってる人
今42Tokyoで課題を進めている人
この記事では、42Tokyo本科で課題を進める上で各課題にどれくらい時間がかかり、どういったスキルを身につけることが出来るのか?ということを実際に私の例で説明しようと思っています。
課題を進める上での目安にしていただければと思います
前提知識の違いなどによってかかる時間は変わってくると思うので、あくまでも目安程度にしていただければと思います
また、ネタバレを多く含んでいるので、新鮮な気持ちで課題に取り組みたいという方は参照されないほうが良いと思いますのでご注意ください
前置き
42に入学する前はこういうステータスでした
大学はCS専攻ではなく化学専攻修士卒
いわゆるWeb系のエンジニアとして2社で10年勤務の36歳
C言語はほぼ触ったことがない(ポインタって何?状態)
42Tokyoを通おうと思った理由やバックグラウンドなどはこちらに詳しく書きましたのでご参照いただければと思います。
今時点での42Tokyoでのステータスとしてはこんな感じです
2020年6月に入学
週に3日勤務して、残りの週4日を42にあてる
課題はクリアだけを目指すのではなくできるだけ脇道にそれるスタンス
Level3のBlack Hole(課題の締め切り)を締め切り三日前にクリア
Level3の課題は未着手
42はレベルが21まであるので、半年やっただけの本当に序盤の序盤に関する情報にはなりますが、2020年の振り返りも兼ねて共有したいなと思います
Piscne 【92時間】2020/2/3 - 2020/2/28
Piscineに関わる情報は一切出すことができないので、時間だけです。
私は、働きながらだったということもあり投下時間は比較的少なめになりました。
Level 0【58時間】
libft 【58時間】2020/6/4 - 2020/7/1
42Tokyoに入学して最初に着手する課題です
libcのサブセットを50個近く再実装する課題になります
この課題では以下のスキルを重点的に学びます
manの読み方
文字リテラル・文字列リテラル
Cにおける文字列操作・複製
型のビットパターンやキャストの挙動理解
メモリ管理・操作
(関数)ポインタの扱い方
このサブセットは、今後の課題でもlibraryとして利用していくことになるもので、以降の課題でも必要に応じて追加していくことになります
私の場合は、そこまで足してないですがminiRTで必要になったatofを追加したりしました
スクラッチで一からパーツを組み上げていく感じがDr. Stoneみたいな感じですね
こちらの課題のレビュー時間は、50個近くあるファイルを一つずつ見ていきながら動作を確認するので、スムーズにいけば1時間、しっかり一つ一つ見ていくと2時間ぐらいレビューになります
私がレビューする場合は、自作のテストツールで一通りの動作を見て、failしたところを重点的に確認し、それ以外の部分は通読して問題がなさそうか確認する形で進めていました。
commit logを見ると 2020/6/4 - 2020/7/1まで1ヶ月程度取り組んでいたようです
Author: Sukesan1984 <****>
Date: Wed Jul 1 10:16:02 2020 +0900
Modify dependency of clean and fclean
...
Author: Sukesan1984 <****>
Date: Thu Jun 4 19:11:49 2020 +0900
Add libft ft_strlen.c and Makefile
Level1 【110時間】
Level1では3つの課題があり、ネットワークの基礎を学ぶもの、おなじみのprintfを再実装するも、のテキストファイルを一行ずつ読み込むモジュール
といったものがあります。
netwhat【13時間】 2020/7/4 - 2020/7/13
IPアドレスやOSI参照モデルや各種プロトコルについての基礎を学びます
具体的に得られるスキルとしては
IPアドレスとネットワークの基礎
TCP/UDPの違い
各レイヤの主要なプロトコルの概要
と言った知識系カリキュラムになっていて、マスタリングTCP/IPを通読しながら色々調べたりして、これぐらいの時間になりました。
IPアドレスとネットワークマスクから、ネットワークアドレスやブロードキャストアドレス、通信可能なホストなどを見抜くことができるようになります
こちらの課題のレビュー時間はスムーズに行けば15分、しっかり説明すると1時間ぐらいが目安になります。
手元のtogglでの記録によると2020/7/4 - 2020/7/13まで取り組んでいたようです
ft_printf【65時間】2020/7/29 - 2020/8/19
得られるスキルは
可変長引数の扱い方
仕様通りに作りあげるスキル(printfの場合精度や幅や各種フラグ)
少し大きなプログラムを書いていく方法
must項目ではないが、浮動小数点数の扱い
などを学ぶことができます
可変長引数は
man va_arg
で使い方を調べながら取り組みます
va_list構造体がどうなっていて、va_startやva_argをcallしたときにどの用になっているかと言うのはABIで決められていてこちらを読むと詳細を把握することができます。
基本的には、一つ一つ実装していく感じだと思います。
最初は変換指定子を受け取らずただの文字列リテラルをそのままwriteするところから始めます
私は、この課題はあまり時間がなくてbonus課題まで取り組むことができず%fなど面白そうな変換指定子に関しては未実装に終わってしまったのが残念でした。
最終的には、%u, %d, %i, %c, %s, %p, %x, %X, %oと、+,-,#,*,\s,.などのフラグを対応したので手一杯でした・・・
浮動小数点数をprintfで出力する方法に関しては、dnakanoさんがこちらの記事で詳しくまとめられているので是非御覧ください!
printfの課題のレビューは、定められた変換指定子を順番に動作確認していくのですが、事前にテストケースを準備しておく事ができるので、自前で用意しておくのが良さそうです。
テストケースを見つつ、コードを見てとやっているとおおよそ1時間ぐらいでしょうか。
commit logを見ると2020/7/29 - 2020/8/19まで取り組んでいたようです
Author: Kosuke Takami <****>
Date: Wed Aug 19 10:53:17 2020 +0900
Modify Makefile
...
Author: Sukesan1984 <****>
Date: Wed Jul 29 13:53:19 2020 +0900
Add libft
get_next_line 【32時間】2020/7/4 - 2020/7/28
こちらのカリキュラムで得られるスキルは
file descripterの扱い方
static local variableの使い方
エラーハンドリング
見通しの良くすっきりとしたコードの書き方
メモリをリークの検知
この課題では、与えられたfile descripterから-Dで与えられるバッファのサイズでファイルをリードし一行単位で文字列としてメモリを確保し与えられたアドレスに書き込んで、ステータスを返す以下のような関数を実装します
int get_next_line(int fd, char **line);
課題を解く上での制限が多く、いかに効率よく見通しの良い関数に切り出して、エラーハンドリングも適切にできるか?ということを学ぶことができます。
またこの課題では、文字列をコピーしたり、改行で分割したり、改行を探索したりと文字列操作をしつつメモリをリークさせずに安全に文字列をコピー出来るか?といったところを気にしながらコーディングする必要があるため、メモリリークに対する意識が上がります。
また、自身の実装したコードがリークしているかどうかをvalgrindやleaksといったツールを使って検証する方法についても学びます。
get_next_lineに関しては、JUNさんが詳細な記事を書かれていたのでこちらも御覧ください!
get_next_lineのレビューは動作確認とリークチェックになるかと思います。
EOFに改行を含む場合、含まない場合や、Bufferサイズが特定のサイズのときといったファイルを事前に用意しておいて、そちらの返り値や挙動を確認できる実行ファイルを用意しておくのが良い気がします。なかなか自前でテストを書くのは難しいかもしれないなと思っています。
大体、30分から一時間ぐらいがレビューの目安といった印象があります。
commit logを見ると 2020/7/4 - 2020/7/28まで取り組んでいたようです
Author: Sukesan1984 <takamikousuke@gmail.com>
Date: Tue Jul 28 22:02:05 2020 +0900
Add bonus file
...
Author: Sukesan1984 Date: Sat Jul 4 14:11:36 2020 +0900
Initial commit
Level2 【237時間】
レベル2は3つの課題があり、一つは、RayTracingと3次元ダンジョンを作るような課題(こちらはやってないのでわからないです)から一つ選ぶもの、もう一つは、httpサーバーの構築の課題、もう一つはオフライン試験です。
miniRT【200時間】2020/8/19 - 2020/12/17
序盤の大ボスです
総投下時間も200時間に至りました
この課題では以下のスキルを獲得できます
ファイルの入力値の値変換およびdispatch
各種エラーハンドリング
浮動小数点数変換atof
レイトレーシングの基本
球・平面・四角形・三角形・円柱との衝突判定
空間把握能力
ShadeとShadowを落とす方法
bmp形式のへのbinary書き出し
エッジケーステスト
私は週末レイトレーシングでスタートしましたが、これが若干悪手だったかもしれません
というのも、この課題では、グリッチ(オブジェクト表面に出るノイズ)を許さない仕様となっているのですが、週末レイトレーシングはいわゆるパストレーシング(モンテカルロレイトレーシングの手法)を紹介しているためです。
パストレーシングでは、規定のBounces内で、光源に届かないケースが多く、グリッチが出てしまうことを避けられない気がするのと、レンダリング時間も直接光の影響のみを考える手法に比べるとレンダリング時間が長くかかってしまうかと思います。
ノイズに関しては、こちらの記事にあるようなNext Event Estimationなどの手法を使えば消せるのではないか?というところまで調べたのですが、タイムアップで、Phongの反射モデルを使って直接光のみを考慮した方法で実装するように切り替えました。
が、すでにその時は12月に入っていて、他の実装(bmp書き出し、エラーハンドリング、コード規約に準じたコードの修正)も色々と残っていたので、かなりぎりぎりになってしまいました・・
また、もう一つ失敗したなと思ったのが、オブジェクトの座標を浮動小数点数で記載出来るので、そちらを読み出すときに、atofが必要になったため、atofの実装の方にガッツリと入ってしまって、なんだかんだで一ヶ月ほど費やしてしまったことでした。
詳しくはこちらにまとめています
この辺りは、本来であれば、一旦ライブラリを使うようにして全体を通すようにしてから、必要な場所を自分の実装に置き換えていくという方が時間的に余裕を持って進められただろうという反省があります。
一方で、普段の業務ではyak shavingの深みをどこまでもたどり続けるなんてことはなかなか出来ずある程度のところで切り上げる必要がありますが、42ではblack holeという期限さえ気をつければどこまでも自分の好きなだけ調べていけるという良さがあるなぁと改めて感じました。
ちなみに、この記事のサムネに使用している画像は、今回の課題で作ったレイトレーサーで球、円柱、キャップあり円柱、平面、三角形、四角形を描画したものです。
こちらのレビューは自分はやっていただいたことしかないのですが、一つ一つの動作確認を丁寧に行って、コードもしっかり読んで、色々なケースを試していただくと3時間近くかかってしまう印象があります。
事前に用意したファイルで動作チェックしていく方法であれば、1時間程度になるでしょうか。このレビューのプロセスでこうやったらどうなるかなぁというのを説明しながら入力ファイルを作っていくのは空間把握能力を高めるのに寄与した気がします。
comit logによるとなんと、2020/8/19 - 2020/12/17までかれこれ4ヶ月近く取り組んでいたようです
Author: sukesan1984 <****>
Date: Thu Dec 17 09:30:21 2020 +0100
Modify square Leak
...
Author: Sukesan1984 <****>
Date: Wed Aug 19 17:45:41 2020 +0900
Empty Makefile
ft_server【25時間】 2020/12/13 - 2020/12/16
black hole(締切)が 2020/12/21 とかなり差し迫っており、さらにminiRTもまだ終わっていなかったので、急ピッチで仕上げましたので、こちらの課題はほとんど寄り道せずという形になりました
こちらの課題で得られるスキルセットは
httpサーバー (nginx) 構築
SSL/TLSの仕組み及び設定
MySQLの構築
FastCGIの仕組み(nginx to php-fpm)
wordpress/phpmyadminの構築
Dockerの仕組み
です。
最初に入った会社ではLAMP構成でソーシャルゲームの開発サーバの構築とかを雰囲気でやっており、本当はちゃんと取り組んでもう少し深く理解したかったのですが、あまり理解せずに課題をこなすだけになってしまったのが非常に残念でした・・
次のレベルでkubernetesの課題があるのでそちらの方で、もう少し深堀りしたいと考えています。
commitログによると2020/12/13 - 2020/12/16まで取り組んでいたようです
Author: Sukesan1984 <****>
Date: Wed Dec 16 11:15:42 2020 +0900
Modify Volume and php-mbstring
...
Author: sukesan1984 <****>
Date: Sun Dec 13 11:25:43 2020 +0100
initial commit
オフライン試験02 【12時間】
Level2には、オフライン試験も課されています
これは一定時間のうちに出題される実装課題を完成させ、提出すると機械判定により合格不合格が出る仕組みで、オフライン環境で受けることになるものです。
緊張感があり、非常に手に汗を握る試験なので、楽しいです
一回落ちても期間内であれば、何度も再チャレンジすることが出来るようになっています。
こちらの試験対策にはおよそ12時間ほどかけました。
ネタバレにはなってしまいますが、問題がいくつかある中の一つがprintfを一定時間で書く必要があるというものだったので、それを練習していました。
そちらの様子に関しては試験終わりでまだある程度覚えている状態で再現してみた動画を上げてみたのでそちらも良ければ御覧ください
解説はこちらに載せています。
個人的な肝としては、最初に自作テストを短時間で書けるようにしておくところかと思っています
なにせ、printfはstdio.hをincludeしてしまえば、ライブラリの動作を確認する事ができるわけなので、そちらとの挙動確認ができる技を持っていれば、安心感が違います。
本ちゃん提出前に自分である程度のテストケースで検証して自信を持って提出できますし、何か修正した時のエンバグにも当然気付ける。
というわけです。
共通し学習できるスキルセット
また、特定課題に依存しませんが、下記のスキルはカリキュラム全体を通じて習得していくことになります。
エディタ操作
ターミナルやセッション操作
UNIXコマンド全般
Testの書き方
効果的なコードレビューの方法
エディタはVS Codeを使っている人が多い印象ですが、viを使う人も比較的多い気がします。emacsはあまりいないのかもしれません。
セッション管理にはtmuxを使う人が多い印象です。
私もずっとscreenでしたが、tmuxに変更しました。
一度もレビューで使ったことはないのですが、同一セッションに入ることでVS Codeのようにライブシェアで操作を共有したりみたいなことが出来るみたいです。
Testは、shellで書いたりCで書いたり併用することが多い感じです
コードレビューに関しては、1対1で画面を見ながら、動作確認とコードを一行ずつ読むということをやるので時間はかかりますが、他人のコードをしっかり読む訓練になりますし、自分のコードを相手に伝わるように説明する訓練になります。
一つの課題に付き決められた回数レビューを受ける必要があるので、同じ課題であっても取り組む人の数だけやり方があり、何らかの学びが絶対にあるというのがとてもおもしろいところです。
最後に
こちらは、42Tokyoが始まった6月からの月ごとの投入時間です。
見てわかる通り、9月,10月,11月とかなりコミット量が減ってしまって、締切が近づいた12月に一気にコミット量が増え、完全に夏休みの宿題状態になっています。
ちなみに、8月にも締め切りがあったわけですね。
こういうのでは本当によくない!ということで今日から気を引き締めて、しっかりとコミットしてコンスタントに進捗を積み上げていかねばと心を入れ替えていきたいと思います。
数えてみると500時間とかなりの時間を投下しているわけですが、まだまだだなと感じることのほうが多く、本当に始めて良かったなという気持ちで、42Tokyoを開校してくださった方々には感謝しかないですね。
本当にありがとうございます。