カレーの恩返し

おいしいのでオススメ。

雑にaxiosの便利ラッパー書いた

フロント書くときにaxiosが便利なのでよく使うんだけどHTTPメソッドごとで引数の型が若干違うので毎回忘れてググってる。

なので引数が同じになるようなラッパーに雑に書いてgistにあげておくことにした。
特に変なことはしてないのでコピペで使えるはず。

RailsCSRF対応済み

gista6599bb16d9999ecfccf457a7513e04d

RubyKaigi 2018に行ってきた【Day1】

まだ途中ですが、公開してから考えようと思います。

Keynote

f:id:euglena1215:20180605102252j:plain

ことわざの話

「名は体を表す」= 名前重要

ソフトウェアの世界には物理的制約がなく、概念で構成されているため名前はとても重要。
なのでソフトウェアエンジニアは概念に名前をつける必要がある。

1. 振る舞いに名前をつける

クラス、メソッド、変数に名前をつけるのがこれに該当
よく「メソッドの命名が難しい」と言うが、名前をつけるのが難しいのではなく十分に概念を理解できていないだけ
使う場面、機能を十分に理解していれば難しくない
なのでいい名前がついている機能は自然と良い機能・実装となる

Rubyにはyield_selfというメソッドがある

class Object
  def yield_self(*args)
    yield(self, *args)
  end
end

何がしたいかという情報が入っていない
なので昨日コミットして新しいaliasを作った(matzがCRubyに機能面でコミットしたのは5年ぶりらしい!)
object.c: Add a new alias then to Kernel#yield_self · GitHub
thenという表現はmatzが推しているだけで他のRubyコミッターはみんな反対しているとのこと

2. プロジェクトに名前をつける

良い名前は求心力になる
例えばRuby
Rubyという名前をつけなかったら仙台に1000人以上集まってくれるような言語になってなかったんじゃないか
Rubyは良い名前付けだったなぁと思うが名前を付けたのは1993年の話
今つけるとしたらもっと違う名前をつけるかもしれない
今はググラビリティ(=Google検索時の単語のユニークさ)を意識した方がいい
悪い例としてGoやSwiftが挙げられる(www)
現代のプロジェクトの名前付けのトレンドとしては

  • 単語を組み合わせる(Ruby on Rails, tensorflowなど)
  • 既存の単語から1文字変えてみる
  • 変な単語を選ぶ(kaminari, hanami, kibaなど) ← 何をやっているのか分からないという弊害もある

名前はとても重要なので、良いプログラマーは名前つけにsensitiveであるべき

「時は金なり」= Time is Value

時間をどのように使うかが自分の人生を決定づける
プログラミングにおける時間は2つあると思っている

開発時間 ≒ エンジニアがPCに向かってる時間


Rubyは生産性が高い

  • 便利なメソッドがたくさんあるのでやりたいことはだいたい探せばある
  • 色んなフレームワークがある
  • Rubyを使っている人がたくさんいる
    • 個人の言語の選択基準は「近くに詳しい人がいる言語」を選ぶべき
  • (見かけ上)シンプルな構文

実行時間 ≒ コンピュータが処理する時間

パフォーマンスの話
Ruby 1.8以前は確かに遅かった
Ruby 2.6からはJIT compilerが入ったりとかなり改善されてきた
今まで言われ続けてきたconcurrency(=並列実行)もどんどん現実のものとなってきている
Ruby 3.0ではRuby 2.0の3倍速くなる
実行時間が短くなればサーバーのリソースを減らすことができて、その分が全て利益になる

「塞翁が馬」

人生の幸、不幸は予測できない=なにが起こるか分からない
1995-2004 Rubyを知らない人が多かった
2005-2012 普及し始め「Ruby is Great!」と言われるように
2013-2018 一時期の興奮が冷め安定期に入った
Rubyは死んだのか?という記事を目にするようになった
Rubyは毎年死んで毎年生まれ変わっている
Ruby is Dead Every Year
互換性は大事だが変化は止めてはいけない

RubyKaigiが「Rubyがもっとこうなったらいいなぁ」と考える機会になればいいなあと締めた。

Analyzing and Reducing Ruby Memory Usage

TODO: スライドを見つけたらまとめる

草生えるの人

feature cache Direct Isen - メモリをどのくらい使われているか調べる方法 - Reading code - Mall stack tracing - rubyは2つのヒープに分けられる - object space - allocation tracer - malloc stack logging :love: - プログラムがどのくらいメモリを使っているか - どこがメモリを食っているか - 誰がmallocしたのかが分からない - メモリ使用量を減少するパッチについて - feature cacheの最適化 - shared strings - 存在する文字列の添え字の調整で表現できるならそれで - 同じrequireは1度だけ - どうやって同じファイルとするのか? - 毎回requireされたかどうかチェックすると遅い - setupに時間がかかるようになる - key generation - ruby objectを消す - cacheを参照するときに生成していたruby objectを作成しないでよくする - rails アプリケーションのメモリ使用量4.2%減らせる - パッチを書く前にすでにないか調べてみよう - Stack VM - コード - AST - Linked List - Byte Code - Byte CodeはVMによって実行される - Linked List(T_NODE) -> ByteCode

puts “Hello World”

Hijacking Ruby Syntax in Ruby

www.slideshare.net Rubyの黒魔術を使ってfinal override abstract with deferといった他の言語にある機能を作ってみたよ、という発表。

使った黒魔術たち

Binding#local_variable_setはbindingした箇所でlocal変数を宣言できる
存在しない変数を定義したときはbindingのblockのスコープを抜けるとその変数定義は消える
存在する変数に対して定義したときはoriginalの変数定義を上書きする ← 🤔🤔🤔

ということは好きなところで変数の中身をいじれる!

TracePoint

ほぼ全てのイベントをhookに処理を走らせることができる

  • 行を移動したとき
  • raiseが発生したとき
  • classを定義したとき
  • returnしたとき…
  • bindingしたとき

これらの情報を合わせると コードの任意の箇所の変数を上書きできる!

refinements 前の記事を参照

euglena1215.hatenablog.jp

github.com

github.com

github.com

finalist, overrider, abstrikerで使われているMethod Hook

  • Module#method_added
  • Module#method_removed
  • Module#method_undefined
  • BasicObject#singleton_method_added
  • BasicObject#singleton_method_removed
  • BasicObject#singleton_method_undefined

Rubyはmethod定義の方法がたくさんあるため、このくらいMethod Hookをつける必要がある。 同じようなことをしようと思ったときは気をつけてねという話でした

TODO: 途中

All About RuboCop

TODO: スライドを見つけたらまとめる

英語が分からんぞ、、、

Fast Numerical Computing and Deep Learning in Ruby with Cumo

TODO: スライドを見つけたらまとめる

chainerの人 PFN Cumo

CUDA programming GPUはやい コア数の桁が違う 行列演算早い

CUDA GPUのメモリをallocate CPU メモリ -> GPU メモリ GPU側で計算 特徴 非同期になる GPU likes a job queue

Numo -> Cumoの文字列置換で動く element-wise operation 要素ごとの足し算 並列的に処理がしやすい reduction operation 和をとったりするやつ 並列かさせるのむずかしい 行列の積にも対応 cuBLAS

cudamallocが遅くなりやすい memory poolを使おう 一番簡単な実装は配列 best-fit hashのchain法かな? 基本はchain法、ほしいメモリサイズよりも大きいものが余ってたら切り出して利用する

rubyでは文字列評価によって行う

NumoよりCumoの方がめっちゃ早い 75倍早い

GPUGCと相性がよくないかも? mkmfの機能が足りない 第三のコンパイラの指定ができない broadcast operationが遅かった

すごそう +=のoverrideができない

A parser based syntax highlighter

speakerdeck.com

TODO: あとでまとめる

既存のhighlighterは正規表現で実装されている atomはcsonという形式で書かれてる

それの問題点は?

  • コードを読むのが辛い
    • 正規表現は難しい
      • 問題にぶつかったとき多くの人は正規表現で解決しようとするけど、問題が2つにふえる
  • highlightが完璧じゃない
    • トリッキーなコードを書いているとsyntax highlighterを倒すことができて
  • Iro
    • ripper based syntax highlighter
    • iro vs iro vim
      • iro vimがiroにデータを渡してiroで処理する
    • advantage iro
      • easy to read
        • parseはripperに任せている
      • ローカル変数をhighlightできる
      • parseがeditor依存じゃなくなる
    • implementation
      • Ripper.lex
        • tokenizeしていい感じに返す
          • 行番号と列番号
          • keyword, space, identify
          • その文字
          • lex state
      • Ripper.sexp
      • event driven

        - performanceのため

RailsのService層とうまく付き合うにはどうすればいいのか調べてみた

RailsのService層ってどう使っていくのがいいんだろうね?」って聞かれたときにすぐ答えられなかったのでまとめておきたいと思います。

※ Fat Modelの解決策としてTrailblazerが最近よく話題に上がりますが、私がまだ使ったことがないので触れない方向で行きます。

情報を漁る

まずは「Rails service」とググって検索して引っかかった記事を読みました。

 

techracho.bpsinc.jp

  • アクションが複雑になる場合 (決算期の終わりに帳簿をクローズする、など)
    → 複雑な処理をmodelから分離させたい
  • アクションが複数のモデルにわたって動作する場合 (eコマースの購入でOrder, CreditCard, Customer を使用する、など)
    → どのmodelに書けばいいのかよく分からないのでとりあえずserviceに書いとけ感ある
  • アクションから外部サービスとやりとりする場合 (SNSに投稿する、など)
    → 外部サービスだしServiceっぽい!
  • アクションが背後のモデルの中核をなすものではない場合 (一定期間ごとに古くなったデータを消去する、など)
    → 複雑な処理をmodelから分離させたい
  • アクションの実行方法が多岐にわたる場合 (認証をアクセストークンやパスワードで行なう、など)。これはGoF (Gang of Four) のStrategyパターンです。
    → 複雑な処理をmodelから分離させたい

 

qiita.com

  • 一つのModelで複数のミドルウェアと通信する場合はService層に書く
    → 複雑なロジックをmodelから分離したい
  • 複数のModelが絡み合う処理はService層に書く
    → どのmodelに書けばいいのかよく分からないのでとりあえずserviceに書いとけ感ある
  • Service層では振る舞いだけを定義する(状態を持たないためModuleで設計する)
    → テストをしやすいようにする、1serviceに責務を負わせすぎないようにする

 

qiita.com

  • クラス名には動詞と目的語と「Service」を付ける
    → ソースを読んだときにすぐServiceだと気づけるようにするため、命名を悩まないようにするため
  • 引数は出来る限りnewで渡してインスタンス化する
    → 1serviceに1つの役割だけを持たせるため、
  • 1つのサービスにpublicなメソッドは、原則1つにする
    → 1serviceに1つの機能だけを持たせるため、上と一緒
  • 初期化したインスタンスはprivateのattr_readerで呼ぶ   → なるべく隠蔽したい、attr_readerにまとめることで可読性が上がる
  • 切り分けたメソッドは全てprivateなgetterメソッドとして実装する
    → 可読性、隠蔽の面から

 

qiita.com

  • クラス名は「動詞 (+ 目的語)」にする
    命名を悩まないようにするため、機能を明確化させるため
  • 外部に公開するメソッドは call という名前のクラスメソッドのみ
    → 1つの機能しか実装できないようにするため、命名しやすく、

 

techracho.bpsinc.jp

  • 命名規則を1つに定める 記事では名詞+動詞orだと動詞に違和感がある場合があるので動詞+名詞の方がいいかもって言ってる
    → 可読性
  • Service Objectを直接インスタンス化しないようにする
    callをClass Methodとして実装することでステートレスなメソッドとして実装したい
  • Service Objectの呼び出し方法を1つに定める
    call , run, executeなどの意味を持たないメソッドを使うよう義務付けてクラス名でどんな機能なのか表現できるようにする、serviceを利用しようと思ったときに調べなくて済むようになる
  • Service Objectの責務を1つに絞り込む
    Manageなどの責務が曖昧な単語をserviceクラスの命名として使わないよう気をつける
    → 細かい粒度で作って疎にするため
  • Service Objectのコンストラクタを複雑にしない
    → 複雑なコンストラクタは責務が複雑な証拠。できるだけシンプルなserviceになるように心がける。
  • callメソッドの引数をシンプルにする 利用しやすいように、引数が2つ以上あるときはキーワード引数を使うとよい
  • 結果はステートリーダー経由で返す callによる副作用を期待するもの(DBに対する更新、メール/Slack送信など)だけではなく処理の結果を受け取りたいときはcallの返り値をservice objectそのものにすると柔軟な処理がかけて良い。
  • callメソッドの可読性を下げないようにする
    メソッドを分割して可読性を維持する
  • callメソッドをトランザクションでラップすることを検討する
    → 処理の中断によるバグをなくす
  • Service Objectが増えたら名前空間でグループ化する
    → 可読性向上

ServiceをCommandパターンで作るのをいい感じにサポートしてくれるGemが紹介されていた。

github.com

  • commandパターンの為のレールを敷いてくれる
  • 引数のvalidationができる
  • runrun!をいい感じに使い分けることができる
  • services/ではなくinteractions/として別のディレクトリを切ることを推奨している
  • そもそもserviceという曖昧な名前を使うのがよくないのではと思っていたのでこれはよさそう

 

記事で主張していることが被ってきたのでまとめてみると

Railsでよく使われているServiceの役割

ARを継承したクラス(≒テーブル)を利用しないロジックをまとめる

  • 便利ツール群みたいなイメージ
  • Gemが提供している機能を使いやすいようにwrapする、外部サービスとの連携など

複雑なロジックをまとめておきcontroller側で簡潔に呼ぶ

  • 複雑なロジックなのでCommandパターンを使ってできるだけ分割して書くと色々メリットがある
    • 可読性の向上
    • ステートレス(callのclass method化)にすることにより、テストをしやすくなる
  • 複数リソースを扱うために使うのもここに該当
  • starategyパターンもここに該当

オープンソースを眺めてみる。

理想はだいたい分かったので実際どんな感じになっているか確かめるためにオープンなRailsアプリケーションはどうなっているのか眺めてみた。

github.com

  • #{動詞}#{目的語}Serviceという命名規則
  • 基本的にServiceクラスのpublic methodはcallのみ
    • 綺麗なCommandパターン
  • callの見通しがよくなるように処理をprivateメソッドを切り出している
    • privateメソッド内で他serviceを呼んでいて綺麗に分離できていてすごい
  • 便利ツール群はlib/にあった

github.com

  • #{動詞}#{目的語}Serviceという命名規則
  • 機能によってnamaspaceが切られている
  • 基本的にServiceクラスのpublic metodはexecuteのみ
  • レコードオブジェクトを操作するタイプのServiceはレコードオブジェクトをそのまま返していることが多い
  • google-apiのwrapはlib/でしていた
    • 便利ツール群はlib/に書いてあるみたい

github.com

  • #{名詞}#{動詞}er/orという命名規則
  • 色々なメソッドが生えている
  • たまにCommandパターンのserviceがあったりする
  • 正直よくわからない
  • 便利ツール群はlib/にあった
  • discourseって意外とイケてない?

まとめ

  • Serviceという言葉は曖昧なのでプロジェクトごとでしっかりとルールを決めよう。
    • Commandパターンで実装するのか、全部のせServiceクラスを作って実装するのか
    • 多くの記事がCommandパターンを用いた実装を推奨
    • でも、ある程度の経験がないとどのくらいの粒度で作ればいいのか悩むかも?
  • 複雑なロジックを整理するためにServiceを使うときはCommandパターン使って上手に分割しよう。
    • Serviceクラスを作るときはManageなどの責務の広そうな単語を使わないよう注意する。
    • Commandパターンのような一貫したルールがあるのとないのとでは初見でServiceのコードを見たときのインパクトが全然違う。
  • 今まで便利ツール群はServiceに置いてたけどlib/に置くのがベターっぽい。

追記

色々書きましたが Service層とうまく付き合うには texta.fm の 3. Low-Code Developmentを聞いてもらうのが一番です。聞いたことない人はぜひ聞いてみてください。Service層に対する解像度がぐっと高まると思います。

呉高専HPをスクレイピングしてワードクラウドを作った

これは呉高専エンジニア勉強会Advent Calendar 2017の15日目の記事です。

こんにちは。呉高専OB1年目の@euglena1215です。

AdventCalendar 4記事目になります。
あと6,7記事書かないと埋まらないだろうと思っていたのですが、色々な人に手伝ってもらって気付いたら全部埋まっていました!
もう感謝感激です。

f:id:euglena1215:20171215031355p:plain

こんな感じになりました。
高専はものづくりと国際交流を頑張ってるみたいです。

 

 

で、終わってもいいんですがちょこっと作り方をまとめてみます。

ソースコードはこちらになります。
GitHub - kure-kosen/kurekosen_wordcloud

基本的にはこのページを参考に(ほぼパクリ)しました。 qiita.com

!!!注意!!!

今回はrobots.txtを目視で確認したところ404が返ってきたのでスクレイピングしても問題ないと判断し、プログラム上ではrobots.txtのチェック処理を入れていません。
他のサイトへスクレイピングを行う際はrobots.txtを確認した上で実行してください。
また、リクエストの間隔を1秒以上空けるのがマナーなので気をつけましょう。

処理の流れ

  1. python get_url.pyhttps://www.kure-nct.ac.jp/ からアクセスできる呉高専ドメインのhtmlファイルのURLを全て取得し、url.txtに書き出します。
    イメージとしては、アクセスしていないURLのスタックとアクセス済みのURLのスタックを用意してアクセスしていないURLのスタックから済みのスタックへと移していきアクセスしていないURLのスタックが空になった時点で済みのスタックを書き出す感じです。

  2. python get_wordlist.py でurl.txtを元にhtmlファイル内の必要なテキストに形態素解析をかけて単語ずつに切り分けURLごとのファイルに書き出します。

  3. python wordcloud.pyで2. で書き出された単語を元にワードクラウドを生成します。
    2.で書き出されたファイルのファイル名はURLとほぼ同じものにしてあるので、読み込むファイル名を正規表現で絞ってやれば今年の高専日誌の情報のみなど任意の条件からワードクラウドを生成することができます。


最後に面白いと思った結果を紹介します。

f:id:euglena1215:20171215031802p:plain 2015年の高専日誌から抽出したワードクラウド

f:id:euglena1215:20171215031816p:plain 2016年の高専日誌から抽出したワードクラウド

f:id:euglena1215:20171215031832p:plain 2017年の高専日誌から抽出したワードクラウド

 

例年高専日誌は部活動やコンテストの結果を載せることが多いので「大会」や「チーム」といった単語が多いのですが、今年は「大会」と同じくらいの文字サイズで「イベント」がありました。

これはインキュベーションワークやその他の活動によって色々なところでイベントがたくさん開催されるようになった裏付けなのではないでしょうか。

ワードクラウドを使って1年を振り返るのもなかなかいいですね。

Podcast配信機能をRailsに組み込んでみた

これは呉高専エンジニア勉強会 Advent Calendar 2017の9日目の記事です。

高専OB1年目の@euglena1215です。
今年の12月はすごい勢いで記事書いてます。

とあるラジオのサイトでPodcastを配信したくなったのでどう実現するべきなのかを考えた過程を書いていこうと思います。

コードだけ見たい人はこちら

podcastを配信する仕組みについて

AppleのQ&Aから引用させてもらうと

Can I host my podcast on Apple Podcasts?

No, Apple Podcasts does not host podcasts. You must host media files and RSS feeds on your own web servers or use a third-party host. You can then submit your podcast feed for inclusion in the iTunes Store podcast directory.

What is a podcast feed?

A podcast feed is a URL to an RSS (rich site summary) in XML format. RSS is a technology for announcing updates to a website, and XML is a format for creating content on the Internet.

To publish a podcast on Apple Podcasts, use an Apple Podcast Hosting Partner or create a website that generates a feed conforming to RSS 2.0. When you update the site that hosts your podcast, the RSS feed notifies Apple Podcasts that a new episode is available.
iTunes Connect Resources and Help

とのことです。

ざっくり説明すると Appleではホスティングはしてないよ、何らかの方法でRSSを公開してURLを登録してくれればPodcastとして登録してあげるよ。ってことですね。

ふわっと理解するにはこのページが分かりやすいです。
haruthanatos.wixsite.com

ちなみにTech系Podcastとして有名なrebuildはRSSはこんな感じです。
http://feeds.rebuild.fm/rebuildfm

調査してみる

まずPodcastを配信する方法はなにがあるのかを調べたところ以下を発見しました。

Wordpressプラグイン

wordpressでぽちぽちすればPodcast配信機能を追加できる。

参考:Podcast番組の作り方・配信方法【WordPressで30分でラジオを始める方法】 – ヒーローズジャーニー

Octopod

Octopod is a set of Jekyll templates, helpers and extensions to deliver your podcasts the cool text file lover's way.
https://github.com/pattex/octopod

設定ファイルをYAMLで書くだけでpodcastRSSと良い感じのpodcastのページが表示してくれるwebサーバを立てられる

rebuild.fm のrssには <generator>Jekyll</generator> と書かれてあるのでこれを利用しているっぽい?

dropcaster

With Dropcaster, you simply put the mp3 files into the Public folder of your Dropbox. Then run the Dropcaster script that generates the feed, writing it to a file in your Dropbox, e.g. index.rss. All mp3 files in the Public folder of your Dropbox are already accessible via HTTP, and so will the RSS file. You can then take the RSS file's URL and publish it (again, this is because any file in the Public folder of a Dropbox automatically gets a public, HTTP-accessible URL).
https://github.com/nerab/dropcaster

dropboxにmp3ファイルをアップロードして設定ファイルを作るとrssを自動生成してくれるGem 生成されたrssレンタルサーバーやS3にアップロードすればpodcastをすぐ配信できるようになる

rss(Ruby標準ライブラリ)

生成されるRSSpodcast配信に必要なnamespaceに対応していたので頑張れば書けそう

選択してみる

今回の要件としては

  1. podcastが配信できる
  2. podcast配信以外にも他の機能も組み込みやすい
  3. なるべく簡単に作れる
  4. Rails wayに外れすぎない

wordpressとoctopodはアプリケーションとして完結してしまっていて機能を組み込む余地が少ないのでパス、
dropcasterでdropboxを使わずにRSSを生成することも考えましたがコード読むより作った方が早そうだったのでRuby rssを使って実装することにしました。

設計してみる

擬似コードでやりたいことを表現したらこんな感じです。
日本語で説明するのは苦手なのでやりたいことを察してほしい。。。

# routes.rb
Rails.application.routes.draw do
  # /podcast にGETでアクセスすると
  # PodcastControllerのindexメソッドの結果を返す
  get "/podcast", to: "podcast#index"
end

# podcast_controller.rb
class PodcastController < ApplicationController
  def index
    rss = if RSSがキャッシュに存在する
            cached_rss
         else
            radios = Radio.published # 公開されているラジオ全件取得
            Podcast.Feed.new(radios).generate # podcast用RSSを文字列として出力
         end
    render xml: rss # xml形式のデータとしてrssを出力
  end
end

# radio.rb
class Radio < ApplicationRecord
  # レコードが追加/更新/削除された後実行される
  after_save :update_rss_cache

  def update_rss_cache
    # キャッシュを更新
    cached_rss = Podcast.Feed.new(radios).generate
  end
end

RSSを文字列として出力できるモジュールを実装してしまえばpodcastを配信できるイメージが湧いたので実装に移っていきます。

実装してみる

rssのドキュメントとrebuildのrssをにらめっこします。
そしてできたのが feed.rb, config.rb です。

Configにプロジェクトに依存しているデータを集め、FeedではRSSを生成する処理に専念できるようにしてます。

initializeの引数に取っているradioのschemaはこんな感じです。

# == Schema Information
#
# Table name: radios
#
#  id                     :integer          not null, primary key
#  title                  :string(255)      not null
#  description            :text(65535)      not null
#  mp3(ファイルパス)        :string(255)      not null
#  created_at             :datetime         not null
#  updated_at             :datetime         not null
#  published_at           :datetime
#  duration(再生時間[sec]) :integer          not null 
#  size(バイト数)          :integer          not null
#

複雑なことはしてないのでなんとなく処理の流れはつかめると思います。

PRはこんな感じになりました。
https://github.com/kure-kosen/cho_kure_web/pull/26

テストしてみる

いつか絶対にテストを書くという強い意志は持って日々を過ごしています。

まとめ

少しの実装でPodcast配信機能を実装することができました。
テストはきちんと書きましょう。

筑波大学に編入して半年経ったのでまとめてみる

呉高専エンジニア勉強会 Advent Calendar 2017の6日目の記事です。

高専OB1年目の@euglena1215です。
Advent Calendar 2記事目になります。全埋めの先は長そうです。

筑波大学 情報科学類へ編入して半年とちょっとが過ぎたので編入してからいままでやったことをまとめてみたいと思います。

編入体験記はこちら

euglena1215.hatenablog.jp

筑波大学について

テストについて

テストの難易度は高専のときと大差ないと思ってます。
自分は電気系科目に本当に興味がなくて大変だったのですが、 大学に編入してからは情報系の科目ばかりなので頭に入りやすくていい感じです。

高専時代の成績

1年次 17位
2~4年次 9~11位
5年次 21位

http://euglena1215.hatenablog.jp/entry/2016/07/31/065327

高専のときと同じくらい勉強すれば大丈夫ということを伝えたい

課題について

TAが課題の採点をするという制度が確立しているためか高専のときよりも課題は多いように感じます。

また、実験は選択したテーマによって重さは色々ですが基本的に高専のときよりも軽いと思います。
毎週手書きで20枚前後のレポートを作成しろとかは聞かないです。

総合大学として

高専は理系しかいない+高校1年から5年間ずっと同じクラスと良くも悪くも偏っていると思っていたので色んな人がいそうな総合大学に行くことにしました。

筑波大学は大学内ですれ違うユニークユーザー数(Daily Daigaku Surechigau Unique User)を計測すればかなり上位にランクインすると思います。
しかしそれを生かせているかといえばそうでもなく、情報系の友達(主に編入生)orサークルの友達で固まっている感があります。

ほんとアクティブな人すげえなぁって思います。

他の学類の授業を受けられる

筑波大学には他の学類の授業を取っても単位として認定される仕組みがあって、認定される単位数は学類によって定められています。

ですが

  • 情報科学類はその単位数がとても少ない(単位変換で消滅してしまった)
  • 3年次で卒業に必要な単位を取りきろうとすると時間割がほぼ埋まってしまい単位にならない科目を受講する余裕があまりない

などの理由で、他学類の授業はあまり受けてないです。。。

情報科学類について

志望するときに迷った情報科学類(coins)とメディア創成学類(mast)を比較して考えてみます。

coinsはTHE Computer Science という感じで根幹となっている基礎理論を勉強できる科目が多いです。
なので

人は向いているのかなという感じです。

 

mastはComputer Scienceもやっているものの、サービスやメディアの見せ方や作り方など使っている人や社会にどうすれば影響を与えやすいかといった内容の科目が多いと聞いています。
なので

  • サービスを作るのが好き
  • 自分の作ったものがどんな影響を与えるのか考えるのが楽しい
  • ツールをうまく使って面白いものを作りたい
  • 落合陽一大好き

人は向いているのかなという感じです。

学類の雰囲気としてはcoinsは黙々と何かしてる印象でmastはワイワイしている印象です。(mast楽しそう)
mastの方がサービスを作るのが好きな人が集まっているからか手を動かしている人が多いんじゃないかと思います。

個人的には科目内容はcoinsで正解だったと思いつつ学類の雰囲気はmastの方が楽しそうだなぁと思っています。

つくばの立地

つくばエクスプレスの終点の秋葉原までは1時間かからないくらいなので呉-広島くらいの感覚です。
行こうと思えば行けるって感じです。(交通費は呉-広島の倍くらいだけど…)

ただ、秋葉原からIT企業が多い渋谷, 目黒, 恵比寿に行くと30分くらいかかるのでちょっと遠いなと感じることは結構あります。

サークル

なにか非開発系のサークルに入りたいなぁと思っていて、新歓を回っていたいたときに楽しそうだったねっしー(自然教育研究会)に入会しました。

ねっしーとは…
筑波大学ねっしー・自然教育研究会」は、つくば近辺に住んでいる小中学生を対象に、キャンプや自然観察会などのイベントを行っている筑波大学公認サークルです。
1980年発足当時から、多くの子どもたちに参加いただき、大変好評を得ながら現在にいたっております。
現在も活発に活動しており、2、3ヶ月に1度くらいの割合でイベントを行い、子どもたちに多くのことを学び、そして楽しんでもらっています。
筑波大学ねっしー・自然教育研究会‐公式Webページ‐

最近バタバタしていて参加率があまり高くないのをなんとかしたい…
ねっしーのHPもなんとかしたいのですが、全然手が回らずという感じです。

大学外での活動

イベント参加

逆求人系面談イベント

IT系(他もあるのかも?)は自分のやってきたことをスライドにまとめ、IT企業のエンジニアや人事の人とスライドを交えながら談笑するイベントがあります。
下に書いてあるインターンもこの逆求人イベントからエントリーしました。

イベントの開催場所は東京か関西であることが多いですが、広島からだと交通費で3万円もらえたりするみたいなのでお金はあまり気にしなくていいみたいです。

売り手市場を感じますね…!!!

定番の逆求人系はジースタイラスの逆求人とサポーターズの二つだと思います。
自分はサポーターズをよく利用してました。

www.studenthunting.com

supporterz.jp

スライドとか作るのめんどくさいけどとりあえず様子を見てみたいって人は 問答無用で交通費1万円支給してもらえるギークフェスタおすすめです。

supporterz.jp

学校で{プログラミング好き && 焼肉食べたい}人をある程度集めると焼肉を食べさせてくれる人を召喚できるようになるのもアツいです。

Rubykaigi

Rubyのコミッターが世界中から集まって今後のRubyについてトークしてくれるカンファレンスが広島であったので参加してきました。

今回はRuby 3x3(Ruby version3で従来の3倍速くさせる)をどうやったら実現できるのかという話と Rubyの苦手な範囲もカバーしたい(機械学習やIoTとか)話とかが多かった気がします。 セッション中にみんながどうして笑っているのかよく分からなかったり分からなすぎて段々と眠くなってきたり 言語の壁や技術力の壁をひしひしと感じました。
来年はスタッフ側として参加しようと思ってます。

ステッカー収集が捗ります

ISUCON

ISUCONとはIikanjini Speed Up CONtest の略でwebサービスが動いているサーバが与えられ インフラ、データベース、アプリケーションなど色々な箇所に手を加えながらレスポンス速度を向上させるコンテストです。

その予選、本選(学生枠)に参加してきました。
記事にしているのでここでの内容は割愛します。

euglena1215.hatenablog.jp euglena1215.hatenablog.jp

インターン

ドリコム

1週間講義+2週間実務で合計3週間のインターンでした。

会社ブログとして書かせてもらったのでこれを参考にしてもらえればと思います。

ドリコムのインターンシップはいいぞ! - Tech Inside Drecom

エイチーム

3日間コンテスト形式のインターンで3,4人1組のグループを作ってスコアを競い合うといった内容でした。

ゲームとは
webアプリのソースと修正したい箇所がまとめられた資料(Redmine)が渡され、改修するとポイントがもらえるといったwebアプリのCTFっぽいものや
社内ツールのソースと社員からのアンケートを元に必要な機能を考えて実装し、発表する
などがありました。

使ったことのあるGemを手札に殴り合うバトルと化していましたがイベントとして楽しかったです。

株式会社エイチーム 2019卒サマーインターンシップ【受付終了】

Wantedly

実務2週間のインターンでした。

feedの一覧ページに表示される投稿のアルゴリズムを追加
アクセスログをBig Queryで整形して次の施策を考える
などをしていました。

Wantedly Summer Internship 2017 - X YOU | 2017年度サマーインターンの募集が始まりました!

現在も週1で通わせてもらっています。

その他

今年編入した情報系3編生をメインに構成された yakiniku-lovers
今年明石高専からmastに編入してきた@at_sushi_atが元々やっていたグループ Cyder
インターンの感想(愚痴も含む)を赤裸々に話せるサービス ittern(未リリース)
とあるラジオポータルサイト cho_kure_web
ActiveRecordっぽいO/Rマッパーの再実装 my_active_record

とか何か作ってます。(この辺は書くと長くなりそうなので割愛します)

 


 

こんな感じで楽しくやってます。

ISUCON7本選に参加して何もできませんでした

f:id:euglena1215:20171202041006j:plain
よく見たらISUCON8だった。謎だ...

そもそもISUCONとは

isucon.net

ISUCONとはIikanjini Speed Up CONtest の略でwebサービスが動いているサーバが与えられ インフラ、データベース、アプリケーションなど色々な箇所に手を加えながらレスポンス速度を向上させるコンテストです。

このあたりを読むとISUCONがどんなものなのかざっくりと分かると思います。
インターン生向けのISUCON CM - Qiita

個人的に感じる面白さは

  • 普段webアプリケーションを作る上ではそこまで気にしてないところまで知る良い機会になる
  • パフォーマンスがスコアとして表示されるのでゲームとして楽しい
  • web系企業のリードエンジニアと呼ばれる人がたくさん参加しているので凄さを肌で実感できる

あたりだと思っています。

興味をもった呉高専生がいたら自分に声かけてください! なんかします!

Advent Calendarっぽい内容はこれで終わりで以降は普通のISUCON本選エントリです。


ISUCON7本選に参加して何もできませんでした

先週の土曜日に開催されたISUCON7本選に学生枠として参加してきました。

チーム名は「なにもしちょらんのに壊れた」です。
一緒に参加したのは予選と同じく@k5342@chigichan24の強い編入生達です。

f:id:euglena1215:20171202041938j:plain

マイメロディのパチモンも一緒に参加しました。
(chigichan24がICPCアジア大会に行ったときに買ってきたやつ)

 

予選のエントリはこちら euglena1215.hatenablog.jp

 

メンバーの本選エントリはこちら chigichan24.hatenablog.com blog.ksswre.net

前日

予選ではオンメモリする気満々で突撃して失敗したので 本選ではレギュレーションをしっかり読もうとかN+1をまず潰そうとか当たり前のことをちゃんとやろうと話をしました。

つくばから新宿に9時はつらいと思ったので自分と同じように編入した@planetary3gearの家に泊まらせてもらいました。ありがたい。

当日

コンテストが始まる前はtrelloの予選ボードにあるカードを本選ボードに移し戦いに備えました。

今回はwebsocketを使った多人数で行えるクッキークリッカー(のようなもの)でした。
レギュレーションには今回のスコアの算出はHTTPリクエストによるものではなく クッキークリッカーの操作の回数と書いてあってふむふむと思いながら読みました。

やったこと

  • DBのschema, SELECT * FROM hoge LIMIT 5 のようなレコードのプレビューをSlackに貼った

  • 定番プロファイリング系ツールのmyprofiler, kataribe, rack-lineprofを入れた
    myprofilerで見たところ、room_timeのtimeにindexを貼ったくらいであとは特にすることがなかった。
    今回はwebsocketがメインだったのでアクセスログはほぼ出力されていなかったのでkataribeは使えなかった。
    rack-lineprofではcalc_statusの後半部が圧倒的に遅いということがわかった。

  • m_itemsテーブルのレコードがアプリケーション内で変更がないことが分かったのでグローバル変数化した。
    が、擬似production環境での動作は確認したがベンチが通らなかったので放置した。
    m_itemsをグローバル変数にしてみた by euglena1215 · Pull Request #5 · k5342/isucon7-final · GitHub

  • calc_statusで毎回全てを計算し直していたので確実にこれが原因だよねという話になり、状態をグローバル変数で持ち毎回差分のみを計算すればいいように変更しようとした。
    が、全てを一度に修正しようとして頭がパンクしてしまい全然終わらなかった。

  • calc_statusを半分諦めた状態で他のところを見ていると、Concurrent::Channel.ticker(0.5) となっている箇所を発見した。
    レギュレーションでは「クッキークリッカーの操作を行ってから1秒以内に操作が反映されること」と書いてあった気がした(予選でも謎のsleep(1)があったのでそーいう系かと思った)ので0.8秒に伸ばしベンチをかけてみたがあまり変化は見られなかった。
    えいやっと0.5秒 -> 10秒とかに変えてみてもfailせずスコアが下がるだけだったので???となり放置した。
    Tickerの時間をいじってみた by euglena1215 · Pull Request #9 · k5342/isucon7-final · GitHub

  • 上の変更がうまくいかなかったので逆にループ回数を減らせるのではないかと思い1000 -> 500にしてみたがfailするようになりダメだったので放置した。
    tickerの時間にあわせてループ回数を変更してみた by euglena1215 · Pull Request #10 · k5342/isucon7-final · GitHub

  • 残り時間も少なくなり何をすればいいのか分からなくなったのでとりあえずベンチをEnqueueする機械と化していた。

f:id:euglena1215:20171202044127p:plain

結果としては19位となり、下から2番目で本選出場が決まったわりには悪くない?結果でした。
(初期スコアが6000前後だったので1,2つ変更が効いたくらいのスコア?)

ただ個人では スコアには何も貢献できませんでした。

予選もほぼ貢献できなかったのでメンバーには申し訳ねぇという気持ちとありがてぇという気持ちがフルスロットルです。。。

反省

  • 実装力が低い
    コンテスト後の講評ではcalc_statusの変更はまぁ終わるよね、という感じで実際ある程度のスコアを出しているチームはcalc_statusの修正はきちんと終えているようでした。
    一方自分は一度に全部修正しようとして頭がパンクしてわちゃわちゃしてバグ連発みたいな感じだったので実装力がまだまだ足りてないなぁと思いました。

  • 問題を段階的に解決できなかった
    calc_statusで問題を一度に解決しようとして分からなくなっていました。
    終わってから考えてみると、シミュレーションしている処理と今までのを計算している処理でfor文を分離させるなど段階的に修正を加えることは可能だったことに気づき問題を段階的に解決することが全然習慣になってないなぁと思いました。
    また、他のエントリを見ていると処理をループの外に出すなど簡単に高速化を図れる部分もあったみたいで問題への見方が偏っていたんだなと感じました。

問題に対して

nginxやDBの設定周りのチューニングはなかったものの、デカいメソッドが1つあってそいつが重すぎて話にならないといったケースは現実世界によくありそうで良い問題だったなぁと思いました。
(まずオンメモリにするところから始まるといった想定解答はどうなんだろうという気はしますが…)

来年が学生枠で出場できる最後のチャンスっぽいので頑張ろうと思います。
できれば来年も同じメンバーで出たいな。。。