2020年を振り返る

2020年も終わりということでガキ使でも見ながらゆるーく1年を振り返っていこうと思います。 (7月にiPhoneが壊れて全ての写真が消えてしまい振り返りながら悲しくなりました) 1月 今年の初めは学校の授業で台湾に6泊7日で行ってました。この授業ではみんながインスタに上げてるようなきれいな場所にはほとんど行かずに台湾南部のディープな街を探検しまくりました。このブログでは話せないような貴重な経験もたくさんできたので気になる人はオフラインで飲んだ時にでも聞いてください。 (大量の爆竹を使う台湾の祭り) あとは期末試験の勉強をしたり、長期インターンの仕事をしたり、成人式で9年ぶりに小学校の友達と再会したり、大学の同期と初めての旅行(USJ)に行ったりもしてました。 この時が一番"大学生"をしてた気がしますね。 2月 春休みに入ったので前半はずっとインターンの業務をしてました。この頃インターン先のコードに書かれているrepositoryやinterfaceが何のことかわからなくてDDDや設計について本や記事で何となく勉強し始めました。いまだに何もわかりませんが。 あとサイバーエージェントのCA Tech Dojoにも参加しました。Go言語を使ってAPIを開発した経験がなかったのでとても勉強になりました。ただコロナウイルスがちょうど猛威を奮ってきて1週間で中断になってしまいました。結局コロナが収まらず復活はなりませんでしたが、ここで一緒になったインターン生とは今も同じインターンをしていたり、近くに旅行に行った時は一緒に飲んだりしていて短いながらもとても濃いインターンだったなと感じてます。 (ランチで連れて行ってもらった焼肉屋の看板) 3月 3月はコロナが本格的に流行ってきたのでずっと家に引きこもってプログラミングをしてました。大学の新歓が中止になるという連絡がきてサークルに新入生集められなくてやばいなってなったので新歓サイトを友達と2人で作りました。100個以上のサークルが参加してくれてPVもかなりの数行ったので作ってよかったなって思います。 あとはサポーターズの逆求人にも初めて参加しました。たくさんの企業を知れただけでなく22卒のたくさんの学生の存在を知れたので参加してよかったです。(このイベントに参加するまでは22卒のWebエンジニアは20人くらいしかいないとマジで思ってた) 4月 4月はほぼ毎日インターンの面接や面談をしていました。前期の始まりが延期になり暇だったので空いた時間はLeetCodeを解いたり、技術書を買い漁って読んだりしてました。 唯一の大きいイベントとしてMacBookProの16inchを買いました。とてもサクサク動くし、画面もでかいし、スピーカーの音質も良くて最高です。前に使っていたMBP(2017年モデル)と比べて生産効率が倍くらいになった気がします。(本当か?) 5月 前期が始まりました。 でも授業は全てオンラインです。 なので引っ越しました。 大学に入ってからずっと大学の近くで一人暮らしをしていたのですが、今は姉と一緒に2人で暮らしています。その分家賃も安くなったし部屋も広くなったし都心に近くなったのでQOLが爆上がりしました。仲良い兄弟がいる人はやってみるといいのではないでしょうか。 5月は新生活の準備とオンライン授業による課題の爆増で結構しんどかったです。 6月 オンライン授業の攻略法もわかってきてかなり時間的な余裕ができたので新しくKADOKAWA Connectedでアルバイトを始めました。ここではGoやgRPC、Kubernetesをたくさん触れて最高でした。入社手続きなども全てオンラインで行って結局最終出社までは一回も出社しなかったです。 Webエンジニアのアルバイト最高〜。 あとサイバーエージェントのbackend tuning competitionにも参加しました。初めてのパフォーマンスチューニングで分からないことだらけでしたが、なんとか2位になれて良かったです。(パフォチューかなり楽しかったので来年一緒にISUCON出てくれる人募集してます) 7月 何やったか全然覚えてないです… インスタのアーカイブを見る限りだとディズニー行ったり、友達と遊んだり、ラーメン食べたり、アプリ作ったり、期末試験の勉強したりしてました。(結構充実してるのに全く覚えてないのなんでだ?) 8月 (お金がなくて自炊してた北海道旅行) 前期の間に2週間の夏休みがありました。残り少ない大学の休みということで大学の同期と御殿場と北海道に行きました。最高の夏休みを過ごすつもりでAirbnbで良い宿を借りたのですが、ありえない量の夏休みの課題を出されたせいでほとんど観光もせずに宿でPCをいじるはめになりました。ふざけんな。 夏休みが終わったタイミングでDeNAの2Daysのインターンにも参加しました。チーム開発でクソアプリ(←ここ重要)を改善するインターンだったのですがなんとか人様に使ってもらえるようなアプリに改善して優勝することができました。優秀なチームメンバーに本当に感謝です:pray: 9月 9月はDMM Guildというインターンに参加しました。このインターンは様々な部署から出されているissueを解決するという形式だったためDMMのいろいろな部署の仕事に触れることができてとても良かったです。R18関連のissueもあったのですがそれに挑戦できなかったのがいまだに後悔してます。 また運動不足で体に支障がきたし始めたのでダンベルを買ったり、キックボクシングのジムに入ったりもしました。(コロナ感染者が出てやめてしまった) 10月 10月はずっとリクルートでアルバイトをしてました。今まで関わったプロダクトの中でも規模が一番大きかったので開発の全てが新鮮でかなり楽しかったです。CIの改善やメトリクスの収集などSREの業務を中心に行っていました。 また10月からは就活が本格化してきて"人生"について考える時間が増えてきました。ありがたいことに10月中に1社から内定をいただけたので精神的には落ち着いて就活をすることができているのですが、まだまだ考えなきゃいけないことがたくさんあるので就活はゆっくりしていこうと思っています。 (秩父の山奥のパワースポットで力を集める僕) 11月 11月の中頃まではリクルートのアルバイトをしていました。最後の方ではエンジニアの業務をやるというよりもやってきたことを他の人にどのように伝えるかのプレゼン技術などをリクルートの方々からたくさん教わりとても勉強になりました。 またアルバイト終了後は束の間の休日を楽しんだ後に免許合宿に行きました。免許合宿の話は12月の方でしようと思います。 12月 12月の10日まで免許合宿に行ってきました。 免許合宿というと若い男女が一つ屋根の下で切磋琢磨しながら友情を育むというイメージがあると思います。 僕も楽しい生活が待ってることを夢見て山形まで行ってきました。 しかし、合宿所には田舎のヤンキーみたいな野郎供しか(ry 話すと長くなるので免許合宿のことは僕のツイートなどから察してください。

Read More

サイバーエージェントのBackend Tuning Competitionに参加しました

6月の7、8日にサイバーエージェントのBackend Tuning Competitionというインターンに参加してきました。 形式としては個人戦のISUCONのようなもので、2日間にわたってサーバサイドの実装やDBなどをチューニングしてスコアを競うというものです。 そこで自分がやったことなどを書いておこうと思います。 1日目 言語の選択 最初にプログラミング言語を選択するコマンドが用意されていたのでそれを使って使用言語の選択をしました。 選べる言語はGo, PHP, Node.js, Javaで僕は普段から使い慣れてるGo言語を選択しました。 この時点でベンチを回してスコアを計測したら750くらいでした。 プロファイリングの設定 DBやNginxのログ解析のための設定をしました。 以下のサイトを参考にツールなどを設定。 DB周りの解析 https://nishinatoshiharu.com/mysql-slow-query-log/ Nginxの解析 https://nishinatoshiharu.com/install-alp-to-nginx/ 周りの人はpprofなどを使って華麗に解析してたみたいなのですが、僕は導入することができなくて諦めました。。。 gitの管理など いじっていてコードが消えたら怖いのでレポジトリをgitで管理する設定をしました。 そこでローカルに落として作業するか迷ったんですが、結局VSCodeのRemote SSHを使ってコードの編集はしました。 N+1問題の解決 アプリケーションのコードを見てN+1問題が発生してそうなところの修正を行いました。 しかし修正をしたのですがスコアは全然変わりませんでした。 ここで集中が途切れたので「小説家になろう」で俺TUEEE系の小説を読んで精神統一をしました。 インデックスを貼る N+1問題を解決しても速くならなかったので無心でインデックスを貼り続けました。スロークエリログやNginxのログを見てボトルネックになってそうなクエリにインデックスを無限に貼り続けました。 この作業をすることでスコアが1500くらいになった気がします。ずっとスコアが変わっていなかったのでかなり安心しました。 強敵の出現 全てのクエリにインデックスを貼ったのですが、一つだけインデックスなどを貼っても一生速くならないクエリがありました。 SELECT article_id, count(user_id) as iineCnt FROM iines WHERE updated_at >= DATE_ADD(NOW(), INTERVAL -1 MONTH) GROUP BY article_id ORDER BY iineCnt DESC, article_id DESC LIMIT 5 これの解決方法を2時間くらい悩んだのですが全然解決できません。 そこで息抜きにISUCONの解説記事などを読んでいました。するとキャッシュに関する記事が大量にあったのでこいつもキャッシュで解決できるのではないかと思いやってみることにしました。 結果、めちゃくちゃスコアが上がりました。確か2000を超えた気がします。1位だったので調子に乗ってすぐにツイートもしてました(間違えてこのツイート消してしまった。。。)

Read More

SQLとリレーショナル代数

ビュー ビュー(view)とは仮想的なテーブルのことである. 保存されているわけではなく、問い合わせのたびにテーブルを作成する. create view View[(column_1, ..., column_m)] as select query; distinct句 行の重複を削除する. select distinct column_1, ..., column_n from R; order by句 行の並び替えを行う. select * from R order by column [desc|asc]; 複数テーブルからのデータ抽出 テーブルの和(union) select * from R where F1 union select * from S where F2; テーブルの積(intersect) select * from R intersect select * from S; テーブルの差(except) select * from R except select * from S; テーブルの結合 内部結合(inner join) 直積集合を求めてG.

Read More

リレーショナル代数

これは大学の講義内容をまとめたものです。 リレーショナル「代数」とは 単一または複数のリレーションに対して定義された演算の体系 線形「代数」: 線形空間の元(ベクトル)に対する和, 内積などの演算の体系 SQL言語の基礎 集合演算 関係演算(リレーショナル演算) 集合演算 和集合(union): \( R \cup S = \{t|t\in R \vee t \in S \} \) 共通集合, 積集合(intersection): \( R \cap S = \{t|t\in R \wedge t \in S \} \) 和両立(union compatible) リレーションスキーマ\( R(A_1, A_2, …, A_n) \)と\( S(B_1, B_2, …, B_n) \)が次の2つの条件を満たすとき, リレーションRとSは和両立である. RとSの次元が等しい(つまりn=m) 各\( i(1 \leq i \leq n)\) に対して, 属性\( A_i \) と \( B_i \)のドメインが等しい(つまり\( dom(A_i)=dom(B_i)\)) 必ずしも属性名は同じでなくてよい 直積演算 直積, デカルト積(Curtesiun product): \( R \times S = \{ (u, v) | u \in R \wedge v \in S \) 集合演算の演習 (1) 下記に示すリレーションRaとRbに対して、和集合、共通集合、差集合の各演算結果を求めよ A店舗取り扱い商品リスト Ra 商品番号 商品名 値段 P1 N1 C1 P2 N2 C2 P5 N5 C5 P6 N6 C6 P8 N8 C8 B店舗取り扱い商品リスト Rb 商品番号 商品名 値段 P1 N1 C1 P3 N3 C3 P4 N4 C4 P7 N7 C7 P8 N8 C8 結果 和集合 Ra\( \cup \)Rb 商品番号 商品名 値段 P1 N1 C1 P2 N2 C2 P3 N3 C3 P4 N4 C4 P5 N5 C5 P6 N6 C6 P7 N7 C7 P8 N8 C8 共通集合 Ra\( \cap \)Rb 商品番号 商品名 値段 P1 N1 C1 P8 N8 C8 差集合 Ra-Rb 商品番号 商品名 値段 P2 N2 C2 P5 N5 C5 P6 N6 C6 (2)下記に示すリレーションR1, R2に対して直積集合R1\(\times\)R2を求めなさい R1 A a b c R2 B C x 1 y 1 z 1 結果 R1 \( \times \) R2 A B C a x 1 a y 1 a z 1 b x 1 b y 1 b z 1 c x 1 c y 1 c z 1 関係演算 選択演算(selection) リレーションRの中から条件式Fを満たすタプルを抽出する演算 $$ \sigma_F(R) = \{ t | t \in R \wedge P_F(t) = true \} $$

Read More

リレーショナルデータモデル

データベースのための基礎理論 集合(set): 「もの」の集まり. 数, 文字, 記号など 要素(element): 集合に属する「もの」のこと. 元とも呼ぶ $$ a \in A $$ 空集合(empty set): 何も要素を含まない集合 $$ A = \phi $$ 例) $$ A = {-6, -5, -4, 1, 2, 6} $$ $$ A = {a, aba, ababa, abababa, … }$$ $$ A = {情報工学科, 機械工学科, 電気工学科, 工業化学科, 建築学科} $$ $$ A = {0, 1, 1} \times 集合ではない $$ 全く同じ要素が2つ以上含まれている場合、それは集合ではない. 集合演算 和集合 $$ A \cup B = {x|x\in A \vee x \in B } $$ 共通集合(積集合) $$ A \cap B = {x|x\in A \wedge x \in B } $$ 差集合 $$ A - B = {x|x \in A \wedge x \notin B } $$ べき集合 $$ 2^A = {X | X \subset A }$$ 直積集合 $$ A \times B = { (a, b) | a \in A \wedge b \in B }$$ リレーショナルデータモデル 実世界のモノ・概念を表(=リレーション)として表現

Read More