ピクシブの春インターンに参加しました

2018/02/26から03/02の間、PIXIV SPRING BOOT CAMP に参加させて頂きました。これはピクシブさんが開催しているインターンの1つで、5日間という短い期間ですが、実際の業務に近いサービス開発に関わることができます。私は今回のインターンで、pixiv のコードを実際に見て、触ることができて、5日間とは思えない密度の濃い体験をすることができました。

やったこと

私は新技術プロジェクトチームのメンターさんに教えていただきながら開発を行いました。実際にやったことは、pixiv Sketch LIVE でのユーザーの配信開始をフォロワーに知らせる pixiv アプリ向け push 通知機能のフィルタリングに関する実装とテストを、PHP を使用して行いました。

現時点で、pixiv Sketch LIVE の配信開始に関する push 通知はまだ実際に行われていません。私がインターンに参加し始めた時には、基本的な機能の実装は終わっていましたが、まだいくつかの問題点を抱えていました。私が今回取り組んだのは、問題点の1つである「R-18 または R-15 の指定がされているライブ配信でも、全員に通知されてしまう」という課題の解決と、その実装に関するテストコードの実装でした。実装内容は、いくつかのデータベースの情報から、ユーザのフィルタリングを行っただけですが、コードの量が膨大なため、コードリーディングに時間がかかりました。しかし、既存のコードのほとんどはクラスやメソッドの名前を見ただけで内容の推測ができたため、とても読みやすかったです!

わからなかった単語リスト

わからなかった単語リストとは、インターンやテック系のイベントに参加した時に、その場では理解できなかった単語を後から調べるためにメモするという自分の習慣の1つです。今回のインターンでも作ったので、その中からいくつかの単語をピックアップして、簡単に解説してみます。

これらの単語は、業務内の会話ではもちろん、社員さんや他インターン生との雑談中に出てきた単語も含むので、今回のインターンでどのような会話をしていたのかがなんとなく伝われば、と思います。

  • github flow: github を使用した共同開発におけるワークフローの1つ。master ブランチには常にデプロイ可能なコードがあり、新しい機能やバグを直す際は master からブランチを作り、作業が終われば pull request を送る。git flowとは異なるワークフローである。プロダクション環境へのデプロイを毎日行うような、リリースという概念がない開発に向いている。
  • tig: git クライアントの1つで、tigというコマンドから使用できる。git addgit commit を tig 上で行えるのはもちろん、過去のコミットの diff が簡単に見ることができてとても便利。
  • Ctags: ソースコード内にある名前のインデックスファイルを作成するプログラム。導入することによって、エディタから変数やクラスの定義の元へ容易に参照できる。
  • Redis: Key-Value 型の NoSQL データベースの1つ。高速にアクセスできるため、キャッシュサーバとして使用されることが多い。
  • PWA (Progressive Web Apps): ウェブとアプリの両方の利点を兼ね備えたアプリ。ウェブサイトをホーム画面に追加して、今までネイティブアプリしかできなかったプッシュ通知やオフラインでの利用などの機能をブラウザでできるようにする試み。
  • Blue-Green Deployment: 本番システムのデプロイ手法の1つ。サーバを現在コードが動いているサーバと、新しくデプロイするためのサーバの2つに分け、新しいサーバにデプロイし問題が無いことが確認でき次第、サーバを切り替える。これによって、サーバ切替時のダインタイムが無くなる。
  • チューリング完全: 万能チューリングマシンと同じ計算能力を持つことを示す言葉。 うっかりチューリングになっちゃったもの というおもしろいサイトを教えてもらった。
  • 「光は遅い」: 光は1秒間で地球を7周半回ることができるが,ネットワークは様々なサーバを経由しながら進むため最短距離とは限らず、また本当に欲しい以外のメタデータなどもやりとりするため、ウェブサイトは遅くなりがち。 ウェブパフォーマンスの基礎とこれから

インターンを終えて

5日間のインターンを通して印象的だったのは、 1. チームや役割を超えてコミュニケーションを取りやすかったこと 2. モノづくりが好き!という社員さんが多いこと

テーブルがすべて連結されていてそもそもチームの境目がわからなかったり、チームが役割で分かれているのではなく、目的によってわかれているのも印象的でした。 また、本業以外でも何かを作っているという創作活動が好きな社員さんも多く、ピクシブならではの雰囲気だったと思います。

どんな分野でも大丈夫なエンジニアになる!

今回のインターンを通してあやふやだった自分の将来像が少し見えてきた気がします。今まで、興味がある技術をどんどんつまみ食いしてきたせいか、得意分野があまりなかったことをコンプレックスに思っていました。しかし、今インターンでお世話になったメンターさんのように、1つの分野のスペシャリストになるよりも、どんな分野のどんな技術にも対応できるエンジニアになることを目標にこれからも勉強していきます!

C言語で進数変換プログラム

整数 x を n 進数で表記するプログラム

#include <stdio.h>
#include <math.h>

int convert(int x, int n){
    int y=0, i=0, z;
    while(x > 0){
        z = x%n;
        y += z*pow(10, i);
        x = x/n;
        i++;
    }
    return y;
}

int main(void){
    printf("%d\n", convert(5, 2));
}

アルゴリズム解説

  1. xが0以下の場合、ループ終了
  2. zにxをnで割った剰余を代入
  3. yにy+z*10iを代入
  4. xをnで割った商を代入
  5. iにi+1を代入
  6. 1へ戻る

実行を追ってみる

例)x=5, n=2のとき つまり、10進数の値5を2進数に変換したいとき

while文 1ループ目( x : 5)
- z : 5%2 = 1
- y : 0 + 1*100 = 1
- x : 5/2 = 2
- i : 1になる

while文 2ループ目(x : 2)
- z : 2%2 = 0
- y : 1 + 0*101 = 1
- x : 2/2 = 1
- i : 2になる

while文 3ループ目(x : 1)
- z : 1%2 = 1
- y : 1 + 1*102 = 101
- x : ½ = 0
- i : 3になる

while文 4ループ目(x : 0)
xが0になったため、ループを抜けて y を返す

整数の一次元配列から最大値を求める再帰的アルゴリズムについて

最大値を求める再帰的プログラム

大きさが n であり、任意の整数を各要素にもつ一次元配列 a から最大値を求める再帰的アルゴリズムをC言語で書いてみた。

int func(int a[], int n){
    int v1, v2;
    if(n == 1){
        return a[0];
    }else{
        v1 = func2(a, n-1);
        v2 = a[n-1];
        if(v1 > v2){
            return v1;
        }else{
            return v2;
        }
    }
}

実行の様子を追ってみる

func({3,2,1,7,5}, 5)の場合

1巡目:func({3,2,1,7,5}, 5)
2巡目:func({3,2,1,7,5}, 4)
3巡目:func({3,2,1,7,5}, 3)
4巡目:func({3,2,1,7,5}, 2)
5巡目:func({3,2,1,7,5}, 1)

5巡目で n==1 となるので、return a[0] が返る。再帰的呼び出しは4回。

次はreturnで何の値が返ってくるのかを追う。
5巡目:n==1 より return[0] -> 3
4巡目:v1=3, v2[1]=2, v1>v2 より return v1 -> 3
3巡目:v1=3, v2[2]=1, v1>v2 より return v1 -> 3
2巡目:v1=3, v2[3]=7, v1<=v2 より return v2 -> 7
1巡目:v1=7, v2[4]=5, v1>v2 より return v1 -> 7

よって最大数 7 を得ることができる。