ドキッ!湯けむりだらけの開発合宿

2019/01/12から2019/01/14の2泊3日五十沢温泉ゆもとかん(http://www.ikazawaonsen.com/)に宿泊して開発合宿をしました。

mokumoku-onsen.connpass.com

私は大学生で、スポンサーされる枠で申し込んでスポンサーしていただきました・・・!

1日目

到着まで

旅館がある六日町駅には東京駅から上越新幹線上越線を乗り継いで行くつもりでした。

しかし授業の都合で集合時間に間に合わなかった私は不幸にも黒塗りの高級車に追突してしまう・・・

旅館到着

無事に22:10くらいに旅館でラストサムライかましてしまった私はそのまま流れるようにフードファイトへ。

f:id:asmsuechan:20190115214352j:plain

とてもおいしくて20分くらいで食べ終わりました。魚が・・・魚が・・・とてもおいしかった・・・!

1日目夜

命の水の吸引力に勝てなかった我々はノールックで開封してしまう。

f:id:asmsuechan:20190115215533j:plain

自分がいた部屋はそのまま0時くらいには就寝しました。他の部屋ではスマブラやってたみたいです。

2日目

2日目の朝、部屋の窓を開けるとこんな景色が広がっていました。白い。

f:id:asmsuechan:20190115214705j:plain

そういえば隣の宴会場にいる若いパパママwithキッズがカラオケ大会で盛り上がっていたのがガン聞こえでいいコンテンツになりました。普通に上手くてよかったです。

この日は結構マジメに作業をしたおかげかちょっとだけ進捗が出ました。よかった。

開発開始

1日目を大きく遅刻してきた私は2日目の午前中より開発を開始しました。コードを書く以外のタスクがあまりにも多かったのでそれを3連休のうちに片付けようとセコセコと頑張っていました。

が、しかしやはり日本酒の吸引力には・・・・勝てなかった・・・・・(ここで手記は途切れている)

3日目

さて最終日。

朝はとても軽快な音楽が流れる食堂でバイキング形式の食事です。明太子がおいしかったです。

f:id:asmsuechan:20190115222703j:plain

午前中は温泉に入りアイスを食べ睡眠をとりました!進捗ですね。

ゴハン他人丼さんでした。おいしくいただきました。 f:id:asmsuechan:20190115220930j:plain

合宿でやろうと思っていたこと

  • 卒論バリバリ書く
  • 発表資料作成
  • 期末テストの勉強(2教科)
  • phpunit.xmlとの戦い

合宿で実際にやったこと

  • 期末テストの勉強(1教科)
  • 発表資料作成(半分)
  • phpunit.xmlとの戦い
  • アニメを見る
  • 寝る
  • 温泉
  • 日本酒

あはーーーん。やはり計画通りにはいかないものですね。卒論はファイルを開くことすらしなかった・・・

しかし半分くらいはやったので良しとしたいです。

まとめ

楽しかったです!!!!!ありがとうございました!!!!!

私もカッコいい大人になっていきたいと思います(東京都/23歳/学生)

写真を取り忘れたのですが、甘酒がめちゃくちゃおいしかったです。

その他

そういえば玄関には熊がいました。 f:id:asmsuechan:20190115213213j:plain

電話がなんかエモい f:id:asmsuechan:20190115220530j:plain

合わせて読みたい judeee-blog.hatenablog.com

takanakahiko.hatenablog.com

apolloオプション内でパスパラメーターを取得する

variables()prefetchの両方でparamsに関する処理を書かなければ動かない。これは自分のNuxtやapolloに対する不理解が原因でもあると思うが、違和感がハンパない。

<template>
  <themecontent :research-theme="researchTheme" />
</template>

<script>
import ThemeContent from '@/components/atoms/ThemeContent'
import gql from 'graphql-tag'

export default {
  components: {
    'themecontent': ThemeContent
  },
  data() {
    return {
      researchTheme: {}
    }
  },
  apollo: {
    researchTheme: {
      prefetch: ({ route }) => {
        return {
          name: route.params.name
        }
      },
      variables() {
        return {
          name: this.$route.params.name
        }
      },
      query: gql`
        query researchTheme($name: String!) {
          researchTheme(name: $name) {
            name
            content
            thumbnail_url
            title
          }
        }
      `
    }
  },
  methods: {}
}
</script>

Vue.jsのいい感じなctagを生成する

定義場所に直接ジャンプできる便利なctagをVue.jsで使うときにちょっと困りました。

Vue.jsのコンポーネント名のctagが自動では生成されない

ctagを生成するときはctags -R --extra=+fqってやるとファイル名のctagを生成してくれて便利なのですが、このタグには拡張子が付いています。

生成されるctagは例えば

App.vue  src/App.vue 1;" F

って感じです。これだとコード中にAppがあってもジャンプできません。

App  src/App.vue 1;" F

ですので拡張子.vueを含めない上のような形式にして欲しいのです。

しかしctagsコマンド単体では拡張子無しのタグを生成する方法が見つからなかったので、vimの保存時にsedでtagsファイルを置換するようにしました

" ~/.vimrc
function! _updateCtags()
  let tagsFile = getcwd() . '/tags'
  exec ":silent ! ctags -R --extra=+fq && sed -i -e 's/^\\([a-zA-Z0-9]*\\)\\.vue/\\1/' " . tagsFile
  " *.vueファイルの.vueの部分をsedで取り除く
endfunction
command! UpdateCtags call _updateCtags()
autocmd BufWritePost * :UpdateCtags

こんなコードを.vimrcに置けばvimの保存時にファイル名から生成したVueコンポーネントの名前のタグを自動生成できます。

(コンポーネントのnameオプションで別の名前を指定されると無理。また別の正規表現で抜き出す必要がある)

~/.ctagsこれをちょっといじって使っています。

クラウドワークスで1年くらい開発インターンしてた話

この記事はex-crowdworks Advent Calendar 2018の23日目です。

2016年から2017年にかけて1年ほどクラウドワークスで開発インターンをしていた思い出話です。これから開発インターンする人にも参考になると思います。

きっかけ

このミートアップの懇親会で社員さん捕まえて「ここで働かせてください!!!!!」って言ったら「勢いのある若者がいる」と認識されてインターンすることになりました。

そういえばインターン始まって最初にメンターさんと1on1した時、「東京タワーよりジャンプする方法って知ってる?」って聞かれて「ん???」ってなってたら「東京タワーはジャンプできないでしょ?」って返されて微妙な空気になったのが面白かったです。

やったこと

クラウドワークスの開発インターンは結構しっかりしていて、「新卒0年目」みたいな扱いでちゃんと(?)仕事を振ってくれて普通にレビューもしてくれてかなり力がついたと思います。

  • メッセージ周りに機能をちょっと追加
  • ServiceWorkerによるwebPushの実装
  • サポートチームからの要望による改修
  • webPush周りのリファクタリング
  • その他

最初はメッセージ改修チーム(メンバー1人+俺)に在籍して簡単なバグ修正や機能追加などメッセージ改修のお手伝いを少ししていました。

夏頃突然メンターさんに「メッセージが来た時にMessangerみたいな通知きたら嬉しいよね、やってみようよ!」みたいな感じの軽いノリで言われてからChromeで動くプッシュ通知の実装が始まりました。

「やってみようよ!」とは言われたもののメンターさんにはメンターさんの仕事があった(これとか)ので自分中心に分からないところは他の社員さん達に聞いて頑張って進めた結果、メンターさん曰く「気付いたらできてた」そうです。ドキュメントは頑張って残したつもりなんですがいやこれこの後誰がメンテすんねんって感じです。今誰がメンテしてくれてるんだろう・・・

クラウドワークスのwebPushは今も動いていて、来るたびちょっと嬉しいです。

バグらせた

開発にはバグが付きものです、と教わりました。私も一年の間にそこそこバグを生み出してしまいました。

  • メッセージ周りのデータ構造壊してデータ不整合
  • ServiceWorkerをインストールする際のハンドリングの凡ミスでIEで一晩動かなかった
  • ↑の再発防止としてエラートラッキングツールを内製しようとしたがGoogle Chromeのシークレットモードだけで動かない

特に一晩動かなかった時は、書いた報告書の損害額が結構デカくて一日めちゃくちゃヘコんでました。。。

障害の次の日、あまりにもヘコんでいたのを見かねた社員さんたちが私の机の上にスッとお菓子を置いていってくれたりコーヒーご馳走してくれたりめちゃくちゃ励ましてくれて「めっちゃいい人たちだ・・・・」って思ったのを覚えています。

気になったこと

当時の会社全体の雰囲気は謎のバッチサーバーさんのエントリを読めばなんとなく分かりそうですが、まあ良く言えば体育会系のノリが結構強いところでした。

例えば、開発じゃない他のチームのインターン生が社員さんに激詰めされてる声が頻繁に聞こえてくるなど。辞める際にマネージャーさんには話したのですが結構声デカくてうるさかったし自分のメンターさんがあれだったらすぐ辞めただろうなって感想です。

総括

とても楽しい時間を過ごさせてもらいました。クラウドワークスでインターンしたことは今の開発者としての自分にかなり大きな影響を与えていて、当時関わった方々にとても感謝しています。

当時お世話になった人たちとは今もまだ交流があって、Twitterで話したりたまに飲みに行ったりしててみんな仲良くていい雰囲気でとても楽しいです。これからもよろしくお願いします。

Vue.jsで使うGraphQLクライアントライブラリ

Vue.jsでGraphQL使ってみようかと思った時、GraphQLクライアントが結構ゴチャついててどのライブラリを組み合わせて使えばいいのか分かりにくかったのでまとめました

結論

コンポーネント内でリクエストの送信をするなら vue-apollo
Vuexのアクションでリクエストを送信するなら apollo-client
AWS Amplify + AppSyncの組み合わせなら aws-amplify

vue-apollo

コンポーネントに組み込むタイプのやつです。コンポーネントapolloオプション生やしてそこで指定されたリクエストはmountedで呼ばれます。

apolloオプション、ちょっと邪悪感が否めませんが、小さなアプリケーションを使うときはこいつで十分です。コンポーネントのテストにはvue-test-utilsなんかを使えば良いのではないでしょうか。

Vuexのライフサイクルとは合わないのでVuexのアクションでGraphQLエンドポイントにリクエスト投げる使い方をしたい人には向きません。

サンプルソース

<template>
  <div><span>{{ getTodo }}</span></div>
</template>

<script>
import Query from '@/apollo/query.gql'

export default {
  data() {
    return {
      getTodo: {}
    }
  },
  apollo: {
    getTodo: {
      variables: {
        id: 1
      },
      prefetch: true,
      query: Query,
    }
  },
  methods: {
  },
  async mounted () {
    this.$apollo.queries.getTodo.refetch().then(data => console.log(data))
  }
}
</script>

apollo-module

Nuxtでvue-apolloを使うためにvue-apolloをラップしたライブラリです。役割はvue-apolloと同じなので省略。

apollo-client

vue-apolloaws-appsync-sdkの大元になるライブラリです。ドキュメントの最初の方に書いてある通り、ビューレイヤーに組み込むことでキャッシュなどの機能を十分発揮してくれます。

こんな感じで簡単に書くことができます。

import ApolloClient from 'apollo-boost';
import gql from 'graphql-tag';

const client = new ApolloClient({
  uri: 'https://graphql.example.com'
});

client.query({
  query: gql`
    query TodoApp {
      todos {
        id
        text
        completed
      }
    }
  `,
})
  .then(data => console.log(data))
  .catch(error => console.error(error));

apollo-link

ただ単純にGraphQLのリクエストのみを送りたいときはこいつです。query/mutationを送りたいときはapollo-link-httpを使います。

こいつはexecutemakePromiseを組み合わせてよく便利に使っています。

import { execute, makePromise } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import gql from 'graphql-tag'
import query from './query.gql'

const operation = {
  query: gql`${query}`
}
const uri = 'http://localhost:4000/graphql/'
const headers = {}
const link = new HttpLink({ uri, headers })

makePromise(execute(link, operation))
  .then(data => {
    if (this.debug) console.log(`received data ${JSON.stringify(data, null, 2)}`)
    return data
  })
  .catch(error => {
    if (this.debug) console.log(`received error :${error}\n${this.baseURL}: ${query}`)
    return { error: error }
  })

aws-amplify

AmplifyでAppSync立てたならこいつを使うのが一番使い勝手良さそうです。というかCognitoのトークン取ってくる機能もAppSyncにリクエスト投げるのもこいつだけで完結できます。

ライブラリとしてすごく便利でいろんなことをやってくれるのですが「お前なんで勝手にそんなことしてるんだよ・・・」みたいな何でも詰め込んだ感じではなく適度に薄く使いやすいやつです。

※vue-apolloのようにコンポーネントに組み込んでよしなに勝手にやってくれるようなことはしません

ドキュメントからのコピペですがこんな感じのコードです。

import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as queries from './graphql/queries';

// Simple query
const allTodos = await API.graphql(graphqlOperation(queries.listTodos));
console.log(allTodos);

// Query using a parameter
const oneTodo = await API.graphql(graphqlOperation(queries.getTodo, { id: 'some id' }));
console.log(oneTodo);

aws-appsync-sdk

apollo-clientをラップしたライブラリで、query/mutationはapollo-clientとほとんど変わらなくてsubscriptionやofflineを使うには少し便利そうです。

コンポーネントに組み込まずに使う方法ありそうですが使ってないので不明です。サンプルではコンポーネントに組み込んでthis.$apolloで参照する使い方しか書かれていません。

感想

apolloさん関係のライブラリを使おうとする度に「俺はただいい感じにGraphQLのエンドポイントへfetch投げてくれるだけで満足するんだ・・・ただそれだけでいいんだ・・・」って気持ちになります。

Main Memory Database Systems: An Overview

読んだ論文

  1. Garcia-Molina, et al., Main Memory Database Systems: An Overview, in IEEE Trans. on Knowl. and Data Eng., 1992

この論文をざっくりまとめます。

要約

インメモリデータベース(MMDB)はデータをメインメモリに保存するデータベースのことである。MMDBは従来のデータベース(DRDB)と比べて高速に処理を行うことができるが(本当か?)、(xxxという欠点がある) この論文では、MMDBが動く仕組みと実際に開発されてきたMMDBの紹介を説明している。

1. INTRODUCTION

メインメモリデータベース(MMDB)はメインメモリにデータを保存するデータベースで、従来のデータベース(DRDB)はディスクにデータを保存するものである。 しかし、MMDBはバックアップとしてデータをディスクに保存し、DRDBはキャッシュとしてメインメモリにデータを保存する。このようにMMDBもDRDBもメインメモリとディスクの両方を使う

MMDBは近年(つっても1992年当時のこと)の半導体メモリチップの低価格化と集積度の向上により実用化されたもので、デッドライン時間が決まっているリアルタイムシステムにおいて効果的に使うことができる。

この論文ではMMDBにおいてメインメモリと磁気ディスクの差による影響に関して論じた。

以下の3つの質問と答えは、MMDBに関してよくある疑問である。

(1) データベースの全体ががメインメモリに収まると考えるのは合理的なことなのですか?

Yes

でも、衛星の画像データみたいな大きなデータだとメインメモリに格納しきれなくなってしまうだろうから、大きなデータと小さなデータは分けて管理する。

データにはよく使われるHotなデータとあまり使われないColdなデータがあって、Hotなデータをメインメモリに格納するようにしてColdなデータをディスクに格納するようにする。この時、MMDBとDRDBの2種類でデータが管理される。

(2) MMDBとめっちゃ大きなキャッシュをメインメモリに持つDRDBはどう違うのですか?

asmsuechan: これは私も真っ先に感じた疑問だからここに答えがあってよかった

まずインデックス構造が問題で、DRDBにおいてメインメモリの中に全てのデータがあったとしてもディスク用の設計が使われてしまう。さらに、データを使用するアプリケーションはデータがディスクに存在するかのようにバッファマネージャーを使うのでこうなるとあまりメリットはなくなる。

でも、良いDBMSはデータがメインメモリに保存されているかのように振る舞うようになるはずなので、将来的にはMMDBとDRDBの違いはなくなると思う。

(3) メインメモリは何か特別なハードウェアによって不揮発で信頼できるものになるのか?

これにはyesともnoとも答えられなくて、MMDBの設計によるとしか答えられない。なぜなら無停電装置を導入したりエラー検出をしっかりしたり冗長性を高めたりしても、それはメインメモリが落ちる確率を下げるだけでどんなに頑張っても0%にはならないから。だからバックアップは必ず必要になる。

2. メモリ常駐データの衝撃

この章ではDBMSにおいて重要ないくつかのコンポーネントにおいてメモリ常駐に関する事柄を説明する。

A. 並行実行の制御

DBの、トランザクションを並行実行する場合におけるデータのロックを制御する仕組みについて。

まず、データがメモリに常駐していてデータの競合が小さいならばロックの粒度を小さくしてもこの利点はないので、ロックの粒度をフィールドやレコードなどの小さい単位からリレーションなどの大きな単位にして良い。

最悪DB全体で1つの単位としてもよくて、実際これの研究も行われていた。これはトランザクション直列実行されることになる。 この場合ロック処理において、セット/リリースやデッドロックへの対処などの制御処理をほぼ無視できるのでトランザクションの直列実行は望ましい。

なお、実際のロック処理(排他ロック)は、2ビットでオブジェクトがロックされているかの情報をそのオブジェクトにトランザクション待ちが発生しているかどうかを表して実現する。

asmsuechan: このセクション、プロセスの並列処理周りの知識がないとちょっと難しい

B. コミット処理

処理の失敗に備えるために、トランザクションのログを取る必要がある。このログはディスクに保存しなければならないので、この保存処理がボトルネックになってスループットを下げてしまうことがある。

ディスクを使うDBでも同じ問題は起きるけど、MMDBではここが唯一ディスクを操作する操作だからよりシビアになってしまう。

今まで研究されてきている、この問題を解決するいくつかの手法を紹介する。

  1. stable メインメモリにログを保存する
    特別なプロセスやプロセッサを使ってstable メインメモリからディスクにデータを保存するようにする。いわゆるキューイングかな。
  2. precommitするようにする
  3. group commitという手法を使う。
    これはページがいっぱいになるまでログを溜めた後にまとめてディスクに保存する手法のことである。

C. アクセス手法

MMDBに置いて、B-Treeはあまり有用ではない。それはB-Treeのハッシュの仕組みが領域を大きく消費するからだ。

メインメモリにあるデータへアクセスするには、B-Treeのようにデータをインデックスに保存する必要がない。これは、メインメモリはディスクに比べてアクセス速度が速くポインタでも十分なスピードでデータを見つけることができるからだ。

このことより、インデックス中の可変長のフィールドに関する問題を解決したり、ポインターのサイズがデータより小さい場合は容量を削減したりできる。

D. データ表現

リレーションはデータのポインターのタプルとして表現される。ポインタによりスペースの効率利用が可能で、さらに可変長データの表現が容易になる。

E. クエリ処理

上でも述べたように、データのポインターでリレーションが表現できるなら、リレーション関連の処理が効率よく実行できる。

ここで一番重要なのは、「データがメモリにあるからクエリの速度を上げることができるようなコンパクトなデータ構造が可能である」ということである。

F. リカバリ

揮発性のメモリから不揮発性のメモリにデータをバックアップすることは必須である。

バックアップからデータをリカバリすることで大事なのは、(1) バックアップを最新に保つ処理と(2) 失敗から復旧する処理である。

以前Commitの部分で述べたように、DBに何か問題があったとき、ログからデータを復旧する。

チェックポインティングはなるべくトランザクションの処理を邪魔してはいけないが、どうしてもロックなどの処理が発生する。その代償として動機を行わないfuzzy dumpingが知られている。

G. パフォーマンス

メインメモリデータベースのパフォーマンスはだいたい処理時間に依存する。

H. APIと保護

DRDBに置いて、DBMSとアプリケーションのデータの受け渡しはプライベートバッファを会して行われている。これに対してMMDBではオブジェクトが直接メモリアドレスで参照される。

プライベートバッファをなくしてトランザクション時にオブジェクトに直接アクセスするようにすると、トランザクションがシンプルな場合にはトランザクションにかかる時間のほとんどがビット(?)をメモリからバッファにコピーする時間に費やされることになる。

しかしデータに直接アクセスするときには、DBMSが認知していないデータを変更できてしまうためにこの変更をDBMSが検知できずにログに書かれないという問題がある。

I. データクラスタリングマイグレーション

DRDBではデータオブジェクトはまとまって保存されたりクラスタ化されたりする。

asmsuechan: 空間的局所性やな

MMDBのデータはDRDBのデータと違って分散しているので、このデータをディスクに移すときどのように、またどこに保存するかという問題が発生する。

この解決方法には様々あって、ユーザーがデータの移動(migration)時にどうクラスタリングするかを手動で設定する方法から、アクセスパターンから自動でクラスタを決定する方法まである。

ここで私たちが言いたいのは、データの移動と動的クラスタリングはMMDBの要素であるということである。

3. システム事例

この章では、今まで理論の設計や実装がされてきたインメモリデータベース に関して述べる

A. OBE

OBEはIBMとOffice-By-Exampleの合同チームが開発したプロジェクトであり、IBM 370アーキテクチャの上で実行される。このDBはアドホッククエリの処理に重点が置かれている。

データ表現としてOBEではポインタが多用されていて、リレーションはタプルのリンク付きリストとして’保存される。

ジョインはネストされたループ(nested-loop)で実行され、インデックスはジョインの実行時にその場で作られる。

B-G

下書き保存し忘れて消えた、後ほど復旧。

結論

5分より短い間隔でアクセスされるデータはメモリに置くべきであるという調査がある。これは、データへのアクセスにかかる金銭的なコストから計算したものである。しかし一番大事なのは、メモリの値段が下がるにつれてこの時間も長くなるということだ。

まとめ

この論文はインメモリデータベースの基礎中の基礎を分かりやすく説明してくれているので、かなりしっかり読んでしっかり訳しました。

でも具体例のところは話が古くて正直あまりピンと来なかったところが結構あったのでもっと勉強せねばって気持ちです・・・

Database Systems Lesson #1 Course Introduction and History of Database Systems

www.youtube.com

クイズ

Andy Pavlo先生が毎セメスター出してるクイズ。

Q: なぜSNSとして先に登場したfriendstarというサービスは失敗して後続のFacebookが成功したのか A: FBはDBがしっかりしていたから。friendstarはDBが耐えられなくて遅くなって失敗した。

このコースについて

  • DBが内部でどんな風に動いているかを学ぶ
  • インメモリデータベースの内部構造を学ぶ
  • 分散システムは扱わない
  • SQLとか基礎的なアルゴリズムは事前に理解しておく必要がある
  • マルチスレッドプログラムをGDBデバッグする方法は学んでおく必要がある
  • C++11でプログラムを書く
  • Postgresの一部の大きなコードベースを使ってインメモリデータベースを作る

Reading Assignments

1授業につき1つの論文を読んで 概要(2文)、使われたシステムなど(1文)、評価法(1文) にまとめる。これを授業前までに行う。

Programming Project

Peltonって名前のPostgresをベースとしたインメモリデータベースをC++11で作る。課題は大きく3つに分けられる。

Project #1 and #2

#1はみんな同じものを実装して、#2はグループワークで分散B-Treeを実装する。

コードの剽窃をした人はクラスのwebサイトに永遠に名前を載せるらしい。剽窃に関してはめちゃくちゃ厳しくするって何度も言ってた。

Project #3

これもグループワークで、お題は自分たちで決めたものを実装するらしい。他のグループのコードを見てコードレビューしたり5分でキーポイントをまとめて発表したりする。

この課題は実装したパッチにPelotonのmasterブランチにマージされなければ完成とは認められない。しかもテストとドキュメントをしっかり書く必要もある。

History of Databases

データベースの歴史を1960年代から現在まで簡単に紹介していた。

  • 1960年代: IBM IMSという階層データモデルを採用したDB
  • 1970年代: CODASYLと言うもう使われていないCOBOLで使うためのネットワークデータモデルを採用したDB
  • 1970年代: Ted Coddという人がIBM IMSの開発者を見て辛い気持ちになったのでリレーショナルモデルを考えた
  • 1980年代: リレーショナルモデルがどんどん他のモデルのDBを駆逐していった
  • 1980年代: インスタンスをそのまま保存するオブジェクト指向DBが出たけど標準APIないわクエリが複雑になるわでもう使われなくなった
  • 1990年代: 新しいものが生まれない退屈な時代
  • 2000年代: インターネット時代で企業は大幅なトラフィックの増大に耐えるためにDBを独自にカスタマイズしていた
  • 2000年代: 可用性とスケーラビリティに注目してNoSQLシステムが生まれた
  • 2010年代: NewSQLの時代。「H-StoreというDBは私が書いた」
  • 2010年代: ハイブリットシステム

感想

まとめるために一時停止したり聞き取りにくかったところを巻き戻したりしてたら1回分(70分)を見るのに2時間近くかかった。

こんなん授業についていくのに必死で良い評価取れる気がしないわ・・・

毎週論文一本読んでSummerizeするの、結構楽しそう。

英語がめちゃくちゃ早くてよく聞き取れないところがあった。

オフィスアワーで「Relationshipsの相談も受け付けるよ」って言ってたのは面白かった。

この授業は多分もの凄くハードだけど、必死になってPostgresのような大きなコードベースを読み解くような経験をしたかしなかったかで今後の開発者としての経験値にはだいぶ差がつくと思う。頑張ってやり遂げたい。