LIVESENSE ENGINEER BLOG

リブセンスエンジニアの活動や注目していることを発信しています

回転寿司が会社にやってきた

はじめまして。 転職ナビでエンジニアをしている、negitorosanと申します。
事務職として 2015年6月リブセンスに入社しましたが、2016年1月からエンジニアに転向しました。

5月末、リブセンスのエンジニアを集めて『Engineer Drink UP』を行いました。
今回は、『Engineer Drink Up』を開催するまでのエピソードをご紹介します。

f:id:livesense-blog:20180615184546j:plain

Engineer Drink UPとは?

四半期ごとに開催される、リブセンスのエンジニアのための懇親会です。
エンジニアがあつまってお酒を飲みながら、LTをしたり、聞いたりして盛り上がり、普段なかなか交流のない別チームのエンジニア同士の横のつながりを強くすることを目的としています。
そして、毎回新鮮さを追求するために、下記の方針で開催しています。

  • 事業部毎の持ち回り制
  • 事業部の個性を発揮する

運営メンバーで話し合ったこと

まずは目標として、下記を設定しました。

  • 参加率の改善
  • 記憶に残る楽しい懇親会にする
  • LTの実施

参加率の改善

今までの懇親会では、エンジニア80名中30〜50名弱と、50%ほどの参加率でした。
どうして参加率が向上しないのかを話し合ったところ、下記のような問題点が見えてきました。

  1. 業務後に拘束されるのが嫌...
  2. オフィスから移動するのが嫌...
  3. 家庭があるため、夜は早めに帰らないといけない...
  4. 行かない人も多いのだから、自分も参加しなくてもいいだろうという気持ち...

2.に関しては大人数を収容できるセミナールームがオフィス内にあるため、大きな問題にならない見込みが立ちました。
そうなると、1.と3.を解決するにはどうしたらよいか。

私達が導き出した答えは・・・

業務時間に開催すればよい

業務時間内であれば、仕事の一環!
早く帰らないといけない人も参加できる!
あの人が行くなら自分も行こうかなと心揺れる人も増えるはず!
※ 弊社エンジニアは裁量労働制です。

記憶に残る楽しい懇親会にする

楽しいだけではなく、自分たちらしさ も出さなければいけません。
他の事業部と内容がカブってしまわないように注意が必要だったため、少し難航しました...
色々な案がでましたが、なかでもとびきりインパクトのあるものを選びました。

結論からいうと、会社内でお寿司を回しました。
自分たちでレーンを作りましたといえたら素敵ですが、出張回転寿司といったものがあるので、発注して当日設置してもらいました。

f:id:livesense-blog:20180615184724j:plain

今回利用したのは、サキガケサービスさんの「出張回転寿司(くるくる)」です。
https://www.sakigake-s.co.jp/sushi

実施時間は業務時間内の17:00〜19:00、場所はリブセンスのセミナールームで行いました。

結果

f:id:livesense-blog:20180615184833j:plain

70人弱のエンジニアが参加してくれました!!
回転寿司も好評だったようで、みなさん写真を撮ったりして楽しんでいたようです。
LTは、弊社の海外カンファレンス支援制度 を利用して Rails Conf 2018に参加した内山の体験談 や、今年度入社した新卒エンジニアからの熱い意気込みなど、様々なLTがありました。

ちなみに、 Engineer Drink Up 開催後に実施したアンケートの結果はこちらです。

f:id:livesense-blog:20180615184855p:plain f:id:livesense-blog:20180615184907p:plain f:id:livesense-blog:20180615184919p:plain

概ね、みなさんに楽しんでいただくことができました!!よかった!

懇親会を運営して得たもの

いままで話したことがなかった人と話す良いきっかけとなり、懇親会を開くことの大変さを知ることができました。
そして、この経験は業務にも活かしていくべきだなと感じました。

  • 問題点をみつけ
  • 改善策を練り
  • 準備を行い
  • 実行し
  • 振り返る

まさにPDCAですね。
参加メンバーが発言しやすい環境づくりを行い、準備し、実行する。
言葉にしてしまえばとても単純なことですが、その難しさと楽しさを再確認することができました!!

f:id:livesense-blog:20180619111155g:plain:w500

おまけ

出張回転寿司を頼む際の注意点

f:id:livesense-blog:20180619111219j:plain

1. 場所

回転寿司台を設置する関係、どうしても場所(テーブル 45cm × 180cmくらいのものを4~5台)と、職人さんの握り場所(1.8m四方位)が必要となります。
※さらにレーンなどを運んだ機材を置いておく場所も必要です。

2. 水場

調理器具などを洗う場所が必要になりますので、近くに水場があることも確認してください。

3. ネタ

各ネタの注文数には制限(最低参加人数の半分程度)があり、ネタの種類を多くし、それぞれの数を少なくする際は注意する必要があります。

DNS over HTTPSを使ってDNSレコードを外形監視

こんにちは、インフラグループの水野です。

みなさん、DNSのレコードの監視を行っていますか? DNSレコードの変更ミス等を検知することはもちろん、自分たちの運営しているサービスの名前解決がユーザ側でどのように見えているのかというのを確認することは大切です。

しかしながら、DNSレコードを外形監視してくれる監視ツールは数が少なく中々コレといったものがありません。 外部からの監視をしたいがためにパブリッククラウドに監視専用のインスタンスを建てるのももったいないです。

弊社ではメインの監視ツールとして Mackerel を利用していますが、MackerelにはURL外形監視はありますが、DNS外形監視はありません。 別途 pingdom のDNS外形監視を利用していましたが、pingdomではIPアドレスとのマッチしかできません。 IPアドレスもひとつしか登録できないため、ELBのようにIPアドレスが定期的に変わるCNAMEレコードなどを監視する際にはあまり相性がよくないという課題を抱えていました。

今回はDNS over HTTPSを使ってこの課題を解決した取り組みをご紹介したいと思います。

f:id:nashiox:20180518113217p:plain

DNS over HTTPS

DNS over HTTPS とは IETF1が標準化を進めているHTTPSを用いてDNSの通信を行う技術です。

従来のDNSの通信は主にUDPを用いて平文でやり取りされます。 この特徴はセキュリティ的にもプライバシー的にも問題視されており、その対策として誕生したのがDNS over HTTPSです。 既にGoogle Public DNSや先日話題となったCloudflareが提供を始めたパブリックDNSでもこの機能が提供されています。

従来のDNSのプロトコルで外形監視を行おうと思うと専用の機能が必要となりますが、HTTPのプロトコルを利用したURL外形監視であれば多くの監視ツールでサポートされています。 今回はこのDNS over HTTPSとMackerelのURL外形監視の機能を利用してDNSレコードの外形監視を実現します。

まずはDNS over HTTPSの動作を確認

今回はGoogle Public DNSCloudflareのパブリックDNS(1.1.1.1) 2つのDNS over HTTPSの機能を試してみたいと思います。 標準化が進んでるだけあってどちらもほとんど同じ使い勝手で使うことができます。

Google Public DNS

Google Public DNSのDNS over HTTPSではAPI版のURL(https://dns.google.com/resolve)、GUI版のURL(https://dns.google.com/query)が用意されています。 今回はAPI版を利用します。

サポートされているパラメータはいくつかありますが、name にFQDNを指定することでレコードを引くことができます。

$ curl -s 'https://dns.google.com/resolve?name=made.livesense.co.jp' | jq .
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "made.livesense.co.jp.",
      "type": 1
    }
  ],
  "Answer": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5,
      "TTL": 195,
      "data": "hatenablog.com."
    },
    {
      "name": "hatenablog.com.",
      "type": 1,
      "TTL": 31,
      "data": "13.230.115.161"
    },
    {
      "name": "hatenablog.com.",
      "type": 1,
      "TTL": 31,
      "data": "13.115.18.61"
    }
  ]
}

上記のようにレコードを引くことができます。 Answer 部分が応答になっており、 type がレコードタイプ(1がAレコード、5がCNAMEレコード)、 data がレコードの値になります。

パラメータで type を指定すると指定タイプのレコードを引くこともできます。

$ curl -s 'https://dns.google.com/resolve?name=made.livesense.co.jp&type=CNAME' | jq .
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5
    }
  ],
  "Answer": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5,
      "TTL": 298,
      "data": "hatenablog.com."
    }
  ]
}

CloudflareのパブリックDNS(1.1.1.1)

CloudflareのパブリックDNSのDNS over HTTPS(https://cloudflare-dns.com/dns-query)ではDNS WireformatとJSONフォーマットがAPIで用意されています。 今回はJSONフォーマットを利用します。

パラメータはGoogle Public DNS同様、 nametype 、更にMIME Typeを指定する ct がサポートされています。

$ curl -s 'https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=made.livesense.co.jp' | jq .
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "made.livesense.co.jp.",
      "type": 1
    }
  ],
  "Answer": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5,
      "TTL": 300,
      "data": "hatenablog.com."
    },
    {
      "name": "hatenablog.com.",
      "type": 1,
      "TTL": 24,
      "data": "13.115.18.61"
    },
    {
      "name": "hatenablog.com.",
      "type": 1,
      "TTL": 24,
      "data": "13.230.115.161"
    }
  ]
}

出力はGoogle Public DNSとほとんど同じです。 標準化って素晴らしいですね。

レコードタイプの指定も同様にできます。

$ curl -s 'https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=made.livesense.co.jp&type=CNAME' | jq .
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5
    }
  ],
  "Answer": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5,
      "TTL": 246,
      "data": "hatenablog.com."
    }
  ]
}

MackerelでDNS外形監視

ここまで来れば勘のいい人は大体お気づきだとは思いますが、MackerelのURL外形監視にDNS over HTTPSのURLを指定し、レスポンスボディのチェックでDNSレコードの外形監視をやってしまおうという魂胆です。

監視ルールを追加から外形監視を設定して新規監視ルールを作成します。 監視対象のURLに先ほど試した Google Public DNS または Cloudflare DNS のURLをパラメータを設定して入力します。

f:id:nashiox:20180517205103p:plain

レスポンスボディのチェックに監視したいレコードの内容を入れます。

f:id:nashiox:20180517205519p:plain

非常に簡単ですね。

後は実際に動作を確認するだけです。 レスポンスボディのチェックと実際に引ける内容が異なるときちんと通知されました。

f:id:nashiox:20180517211016p:plain

おわりに

DNS外形監視は今までこれというものが中々見つかりませんでしたが、今回のDNS over HTTPSを使った外形監視は結構使い勝手が良いんじゃないかと思っています。

DNS over HTTPSはまだドラフト段階ですが、2018年中には標準化を完了させる目標になっているそうです。 HTTPで利用できると言うのは他にも色々活用方法がありそうなので今後も色々試していきたいと思います。


  1. Internet Engineering Task Force (https://www.ietf.org/)

ビジョン合宿はやはり良かった

はじめまして。
昨年の11月にリブセンスにジョインして、今は転職会議のエンジニアをしたり、その他イロイロやっている しらかわ と申します。

先日 (といっても先月ですが) 、わたしの所属する組織では、One-DAYビジョン合宿というものが行われました。
そのときの様子と、なぜ合宿までしてビジョンを追求するのか。という話をしようと思います。

f:id:livesense-blog:20180427153342j:plain

なぜやるのか

この合宿を実施する上で、4つの理由がある。すべてはそこから始まりました。
開催にあたってのリーダーの言葉を借ります。

  1. 誰かがプロダクトを作るのではない。自分たちが作るんだ。
  2. ひとつ屋根の下、1日しゃべってお互いの理解を深めよう。
  3. 事業領域理解・自社理解を深めよう。
  4. 転職会議の進むべき方向性を決めるための素材を集めよう。

どんな準備が必要か

1. みんなが知っていることをそろえる

2時間くらい "合宿事前セミナー" というものを実施しました。
転職会議というプロダクトは人材業界と切り離して考えることはできません。
わたしたちが携わるプロダクトについて業界のプロに本格的な話をしてもらうことで、より理解や深まり、課題を掘り下げやすくなったと思います。

2. ひとりでじっくり考えてくる

シートを埋めました。宿題です。
項目はこんな感じでした。

  • なぜ存在するのか
  • ミッションはなにか
    • 誰に対して
    • どんな価値を
    • どのように提供するか
  • どうありたいか

この "どうありたいか" がビジョンになります。
これを、転職会議に訪れてくれるユーザと、転職会議に求人情報を載せてくれているクライアントに対して、それぞれ考えてみました。

3. 時間割をきめる

数名が "プレ合宿" と称して、合宿のリハーサルを行い、当日の時間割を考えました。
これがあったおかげで、当日の流れが大変スムーズになったと思います。

どんなことをしたのか

f:id:livesense-blog:20180427155029j:plain

阿佐ヶ谷の古民家!を丸一日借り切っての合宿となりました。
6〜7名くらいのグループを複数作り、お互いの宿題を見せ合いながら議論し、グループで一つの方向まで導きました。

f:id:livesense-blog:20180427153437j:plain

そして最後にグループ別に発表をして、1日を終えました。

もたらされたもの

まず、とにかく楽しい。楽しいというのはそれだけでも正義ですよね。
そして、普段多くを語らないようなメンバが本当は何を大切に思ってこのプロダクトに携わっているのか、お互いに気づくことができたと思います。自分では到底思いつかないようなアイデアもたくさん生まれ、何よりも視座が高まりました。

さらに、思いを持って仕事をしているモノ同士、大きな一体感を感じることができました。
これって会社の会議室ではない非日常な空間だからこそ、得られるものだったのではないでしょうか。

そして目的は達成されたでしょうか。

  1. 自分たちがプロダクトを作るんだ!という気持ちがより高まった!
  2. ひとつ屋根の下、1日話し合うことで、普段一緒に仕事をしていない仲間の考え方を知ることができた!
  3. セミナーを受けて、さらに自分で考える事で、そしてみんなでじっくり話し合うことで、事業領域理解・自社理解が深まった!
  4. 転職会議の進むべき方向性を決めるための素材がたくさん集まった!

なぜビジョンが大切か

ビジョンがあると、迷ったときの拠り所になるのではないでしょうか。
わたしたちは生まれも育ちも年齢も何もかも異なります。そして、迷ったり間違ったりする生き物です。
そんなバラバラでフワフワなわたしたちが一つのプロダクトを産み、育てていくのですから、やっぱりビジョンは大切なんだなぁ...と思います。

f:id:livesense-blog:20180427153229j:plain

またビジョン合宿やりたい!
ʕ•ᴥ•ʔ<やろうやろう!

付録

ビジョン合宿のあと、みんなと一緒にバスに乗って帰りました。
「バスっていいなあ。」と強く思ったので、社内でLTをしました。
こういう気持ちも、この合宿がもたらしたものの一つかもしれないです。

speakerdeck.com

リブセンスの海外カンファレンス渡航支援制度でRailsConf2018に参加しました

こんにちは。マッハバイトでエンジニア/マネージャーをしている内山です。

この度リブセンスでは「海外カンファレンス渡航支援制度」が始まりました。 当制度を利用して4/17(火)~4/19(木)にアメリカで行われたRailsConf2018に参加することができたので、それについて書きたいと思います。

海外カンファレンス渡航支援制度とは?

その名の通り、海外にて開催されるカンファレンスに、オーディエンスとして参加するにあたっての交通費や滞在費等を会社が支給してくれる制度です。
希望者は行きたい海外カンファレンスを宣言し、半年に1度、1名を対象に支援が行われます。 初回となる今回は僕のRailsConf行きを支援してもらうことになりました。

RailsConfとは?

これまたその名の通り、Ruby on Railsの国際カンファレンスで、年に1度開催されています。

railsconf.com

開催場所は毎年アメリカ国内を転々としているようで、去年はアリゾナ州フェニックスで、今年はペンシルベニア州ピッツバーグでの開催となりました。

来年はミネソタ州ミネアポリスで行われることが発表されています。

また、例年オープニングKeynoteをRails創始者であるDHH氏が務め、クロージングKeynoteをRubyとRailsのコアコミッターであるAaron Patterson氏が務めるというのが慣習のようです。

日本でもRubyの国際カンファレンスとしてRubyKaigiがありますが、Railsについてのセッションが行われることは稀です。
最近は日本でもRails Developers MeetupというRailsの知見が共有されるイベントが開催されていますが、やはりRailsコアコミッター自ら最新動向を話してくれる機会はなかなかないように思い、RailsConfに一度参加したいと思うようになりました。
(特にDHHはあんまり日本に来ないんですよね...)

ピッツバーグはどんな街?

アメリカ北東部に位置する人口30万人ほどの街です。 日本との時差は-13時間で、ニューヨークやワシントンD.C.と同じタイムゾーンに位置します。

南北を流れる2つの川にかかる橋や、川の合流地点を高台から眺められるインクライン(ケーブルカー)などで知られており、今回のRailsConfの各種デザインにもそれらがあしらわれていました。

f:id:livesense-blog:20180426020552j:plain
RailsConfのノベルティ

今回カンファレンスが行われたのは北側の川に面したDavid Lawrence Convention Centerです。 国際展示場や幕張メッセを小さくしたような施設と想像してもらえるといいのかもしれません。

ピッツバーグはアメリカでも「住みやすい街No.1」に選ばれたこともあるらしく、治安がとても良く、その点では会期中快適に過ごすことができました。 ただ一方で、関東暮らしが長い僕にとっては、なかなか厳しい4月の天候となりました。

f:id:livesense-blog:20180426014649j:plain
雪の降りしきるピッツバーグ

やはりそれは、世界中から集った多くのRubyistにとっても同じだったようで、オーガナイザーからの冒頭挨拶では「会場から上着が買える場所までの道順」をスライドに映し出して笑いを誘っていました。

セッションについて

RubyKaigiのセッションが「正直、難しくて理解できないとこもたくさんあったけど、なんか楽しかった!」となることが少なくない(個人的な感想です)一方で、どちらかと言えば、RailsConfのセッションはより多くの人が理解しやすいようになっているものが多かったように思います。

冒頭、オーガナイザーの「RailsConfに初めて来た人?」という問いに、自分を含む大半の人が手を上げていたので、それらの人への配慮もあるのかもしれません。
僕はリスニングスキルに長けているとは言い難いので、その点では、内容面が難しすぎないというのはありがたかったと思います。

f:id:livesense-blog:20180426035342j:plain
メインのホール

また、いわゆるTechTalkだけでなく、開発をめぐる"エモい"話などが多いのも特徴でしょうか。 TechTalkの傾向としては、テスト関連の話題、RailsアプリケーションにおけるJavaScript開発のTips、Kubernetesを始めとしたコンテナ技術の事例...などが目立ったように思います。

印象的だったセッションをいくつか取り上げます。
※これらのセッションの様子は一ヶ月以内にYoutubeで公開されるとのことです。興味を持たれた方は是非チェックしてみてください!

Turbo Boosting Real-world Applications - Akira Matsuda

  • 日本からもRubyとRailsのCommitterである松田さんが発表をされていました。
  • DBへのクエリ発行やPartialのレンダリングを、子スレッドを利用して行うことでRailsを高速化するというアプローチについて紹介されていました
  • スライド: Turbo Boosting Real-world Applications // Speaker Deck

Keynote: The Future of Rails 6: Scalable by Default - Eileen M. Uchitelle

  • GitHubのエンジニアであり、RailsコアチームでもあるEileenによる2日目のKeynoteです
  • Rails6で追加される並列テストや、複数DBのサポートについての話がありました
  • そのうえで「Scaling should make us happy」といった言葉とともに、スケーリングに応えるRailsであろうとする姿勢を力強く話されていました。
  • スライド: RailsConf 2018 | The Future of Rails 6: Scalable by Default // Speaker Deck

Inside Active Storage: a code review of Rails' new framework - Claudio Baccigalupo

  • Railsのissue対応を行っているClaudioからは、Rails5.2で追加されたActiveStorageについてのトークがありました。
  • ActiveStorageの使い方を踏まえた上でのコードの解説がとてもわかりやすく、勉強になりました
  • スライド: Active Storage // Speaker Deck

その他、ClaudioがRails公式サイトのブログにまとめ記事をあげています。併せてご確認ください!

weblog.rubyonrails.org

参加してみて

海外カンファレンス初参加となりましたが、慣れない英語を集中して聞き続けるというのはやはりドッと疲れるなぁ...というのが、恥ずかしながらも正直な感想です...。 事実、会期3日間のうち2日間は、カンファレンスが終わるとフラフラとホテルに直行し、夕食も取らずに寝てしまいました。

f:id:livesense-blog:20180426034703j:plain
元気があったカンファレンス前日に撮った夜景

最終日は、RailsConfに毎年来られている日本の方と夕食をご一緒する機会がありました。 全てのセッションを聞きつつもスピーカーとさほどコミュニケーションを取らず、夕飯以降の機会でも他の参加者らと交流を取っていない僕のことを、その方は冗談めかして「もったいない」と笑っていました。

確かに、Youtubeで全てのセッションが公開されることを考えれば、セッションにかじりついているだけでなく、その場での交流や情報交換までできてこそ、カンファレンスに参加した甲斐があったと言えるのかもしれません。 ...とは言っても、スピーカーの方らに拙い英語で話しかけることに気後れを感じてしてしまうのも事実です。 カンファレンスの準備として語学学習だけでなく、誰と話したいか、どんなことを話したいかといったことを予め考えておくのも重要だったのかもしれないなぁと今では思っています。

とは言え、もちろん現地でしか得られない経験もできました。 「How We Made Our App So Fast it Went Viral in Japan」というトークをしたdev.toのファウンダーの方に「I'm from Japan」と伝えて笑ってもらったり、自分がWebエンジニアを目指すにあたっての大きな拠り所となったRails Tutorialの作者に感謝を伝えたりすることもできました。 ランチタイムに他の参加者の方らと、日本とアメリカ各州の住宅費用やエンジニア年収について談笑したことも心に残っています。

本当はスポンサーによるエキシビジョンブースの様子なども書きたいのですが、長くなってきたのでこれくらいで...。

最後に

f:id:livesense-blog:20180426012356j:plain
帰りの空港にて

海外カンファレンスに参加すること自体も貴重な経験でしたが、今回「会社の金で行くぞ」という適度なプレッシャーが自分にとって英語学習のきっかけになったことも事実です。 日本にもRubyKaigiを始めとした国際カンファレンスがありますし、せっかくですから自分のペースでもう少し学習を続けたいと思っています。
来月は仙台でのRubyKaigiですね!楽しみです。

最後になりますが、リブセンスではエンジニアを募集中です!
海外カンファレンスに行ってみたいエンジニアの方からのご応募もお待ちしております!!

4Kモニターを仕事で使い始めたらやっぱり最高だった

こんにちは、マッハバイトエンジニアの黒川です。 今日は、最近会社で買ってもらって仕事で使っている4Kモニターが最高だという話をします。 エンジニアブログというよりは商品レポートなので、お気軽に読んでいただければ幸いです。

入社時点での設備

9月に入社した時点で私には、タッチバーつきスペックマシマシのMacBook Proが支給されました(デフォルトがそれなだけで、他のが良ければもちろん任意のマシンも申請可能でした)。 またモニターはオフィスにたくさん置いてあり、好きなだけ持っていって使って良いという状態でした。

しかしそこにはちょっとした問題点がありました。モニターのサイズが少し小さくて、解像度が低かったのです。 最強のMacBook Proがあるのに、USB-C変換アダプターをぶら下げてHDの解像度のモニターで仕事をするのは、せっかくマシンに投資してもらっているのにもったいないなと思っていました。

良いモニターがほしい!

もし良いモニターがあれば、最強のMacをさらに活かし良いものを作れるはずだということで、チームリーダーに相談してみました。するとリーダーがすぐに総務に相談してくれました。 その後はチーム内で他にも4Kモニターがほしい人がいないかアンケートを取ったうえで、無事購入してもらえました。

要望を言える空気、そして前向きに検討してもらえて叶える方向で動いてもらえる空気感の弊社は最高だなと思いました。 実際仕事場にモニターが来たらさらに最高でした。

どんな感じに最高なのよ

ここからは、仕事場に新しいMacBook Proと4Kモニターがあるとどう最高なのかを説明していきます。 ちなみに買ってもらったのはLGの27UD88-Wです。

まず何より、デカい

私は今までモニターを2枚並べて使っていましたが、2枚を横に並べると横幅が大きくなりすぎて、ひと目で全体を把握できませんでした。 またその関係上、よくマウスポインターがモニター上のどこにあるかわからなくなっていました。 これらの問題を、新しいモニターはそのデカさで補ってくれます。

f:id:blackawa:20171114171906j:plain

(左: 新しいモニター / 右: オフィスによく置いてあるモニター) 新しいモニターは、オフィスに置いてあるものに比べて一回りほど大きいです。 おかげで今は、1枚の大きなモニターに情報をまとめて表示できています。

文字が潰れない

今まで使っていたモニターはサイズが小さかったので、Mac側で文字サイズを小さくしてたくさんの情報を表示できるようにしていました。 しかしそうすると新たな別の問題が発生します。それは「文字が潰れる」ということです。 まずオフィスに置いてあるモニターを、手元のiPhone SEで写真に撮ってみました。

f:id:blackawa:20171114172100j:plain

画像も粗いし、「新妻」の「妻」の字は潰れてしまっています。 文字が潰れてしまう状態で大量の文字を読むと、だんだん目が疲れてきます。

次に、新しいモニターを見てみます。

f:id:blackawa:20171114172103j:plain

ひと目で分かるレベルで画像も文字もきれいに表示できています。 カメラ越しでもこの差!実際にはもっと見やすいです。 今もこの記事を新しいモニターで書いていますが、爽快な書き心地を体験できます。 いわんや、これがソースコードなら。

なめらかな角度調節・高さ調節

オフィスに置いてあるモニターの中には、高さの調節ができるものとできないものが混在しています。 高さが調節できないと目線が常に下になるので肩や首が疲れやすくなります。 また、姿勢も悪くなってしまいます。私は身長が190cm近くあるので、余計負担が大きかったです。 新しいモニターの要件にはもちろん高さ調節機能があります。

f:id:blackawa:20171114172445g:plain

もちろんモニターの角度も片手で滑らかに変えられます。

f:id:blackawa:20171114172448g:plain

これで、体格に合った高さと角度で業務に取り掛かることができます。

さらばケーブル・アダプター地獄

最後は少しTIPS感のある良さですが、これもこれでとても良いので紹介させてください。

Mac Book Pro 2016から、外部インターフェースがUSB Type-C限定になりました。 今まで通りのHDMIやUSBケーブル、Thunderboltケーブルを使うためには、専用のアダプターが必要でした。 このアダプターだけで1万円近くかかるという、便利になったのかなっていないのかよくわからない状態でした。

しかし、新しいモニターはUSB-Cがいかに優れモノかを見せてくれます。

f:id:blackawa:20171114172609j:plain

なんとモニターとMacをUSB-Cケーブルで接続するだけで、 - 画面表示できる - 充電できる - ディプレイのUSBポートに挿したキーボードを使える

のです。 下の写真のように、モニターにUSBケーブルを接続するとあたかもMacに挿しているのと同じように使えます。

f:id:blackawa:20171114172714j:plain

これで、離席する時にはMacに挿してある1本のケーブルを抜けば良いだけです。 席に戻ってきたら再び挿せばすぐに画面が表示されて充電が始まり、外付けキーボードのHHKBで作業ができます。 おかげでテーブルのまわりのケーブルがこんなにシンプルになりました。

f:id:blackawa:20171114172755j:plain

これで離席があってもストレスなく作業を再開できそうです。

まとめ

ここまで、4Kモニターとそれを買ってくれる弊社最高という話をしてきました。 ぜひ皆様のチームでも良いマシンと良い機材を導入してみてください。 全力で集中して長い時間使うオフィスの機材が良くなるのは最高の体験です。

CircleCI 2.0でbundle updateを定期実行してみた話

こんにちは、IESHILでエンジニアをしている須貝です。
今回は先月ローンチしたIESHIL CONNECT(イエシルコネクト)の運用で、CircleCI 2.0を使ってbundle updateを自動で実行するようにした話をします。CircleCI 1.0ではなく2.0というのがちょっとしたポイントです。

ところで、みなさんCircleCI 2.0を使っていますか? 2.0では純粋なDockerベースになっていてローカルでも実行可能、より柔軟に設定を記述できる、とにかく速いなど1.0と比較すると大幅に進化しています。どんどん使っていきましょう。

やろうとした背景

そもそも何でこれをやろうとしたの?という話なんですが、 IESHIL CONNECTはIESHILとは別に新規開発したRailsアプリです。せっかくの新規開発ですから、IESHIL本体の開発では手を回せていないことをやろう、というのが個人的にやりたいことでした。たとえばLint(rubocop, slim-lintなど)をCIで実行するなどです。

そのひとつが「bundle updateを定期的に実行する」ことでした。
依存しているライブラリの更新はこまめに実行したいところですが、こうした作業はどうしても忘れがち、後回しになりがちだと思います。 しかし、後でまとめてアップデートしようとすると、動作確認などのコストが非常に大きくなり負担となってしまいます。
ですので、リリースしたての今のうちにこの作業を自動化しよう、というのが今回の背景になります。

実現したいこと

やりたいことのおおまかな流れは下の図のとおりです。

f:id:ssugai:20171025164025p:plain

今回の場合、4, 5の部分はすでに設定済みなので、図の背景が緑の部分を作っていきます。

手順

ここからは手順とポイントを簡単に解説していきたいと思います。

1. Circle CIを起動する

Circle CI 1.0の場合はCircle CIの公式ドキュメントにあるように、Parameterized Build APIを利用して、Web API経由で任意の環境変数がセットされている場合に通常のCI以外の処理を走らせる、という方法で実現することができます。
以下、1.0の場合の例(公式ドキュメントより引用)です。

test:
  post:
    - >
      if [ -n "${RUN_NIGHTLY_BUILD}" ]; then
        ./bin/run-functional-tests.sh ${FUNCTIONAL_TEST_TARGET};
      fi

ややトリッキーですね。

一方、2.0の場合はもっとシンプルです。Parameterized Builds APIを利用するのは同じですが、設定ファイルに通常のCIとは別の任意のjobを定義しておいて、そのjob名をCIRCLE_JOBというパラメータにセットしてAPIを呼び出すだけで簡単に実現できます。
以下、2.0の設定ファイル例です。

# .circleci/config.yml
version: 2
jobs:
  build: # デフォルトで実行されるjob
  ...
  hello: # 任意のjob
    docker:
      - image: circleci/ruby:2.4.2
    steps:
      - run:
          name: Hello World
          command: |
            echo 'Hello, World'

上記のような設定を.circleci/config.ymlに記述しておくと、下記のようにAPIをコールすることでCircle CI上で任意のjobを実行できるようになります。

curl \
  -X POST \
  --header "Content-Type: application/json" \
  --data '{ "build_parameters": { "CIRCLE_JOB": "hello" } }' \
  https://circleci.com/api/v1.1/project/github/:username/:project/tree/master?circle-token=:token

これをcron的なもので定期実行するわけですが、IESHIL CONNECTはHerokuを使っているのでHeroku Schedulerを使ってAPIを呼び出しています。

なお、Circle CIのAPIを利用するにはトークンが必要なので、プロジェクトのSettingsからAPI Permissionsに遷移してCreate Tokenからトークンを発行しておく必要があります。

2. Circle CI上でbundle updateを実行する

次にCircle CI上でbundle updateを実行できるようにしていきます。

# .circleci/config.yml
  bundle_update: # bundle update用のjob
    docker:
      - image: circleci/ruby:2.4.2
    ... # 中略
    steps:
      - checkout
      ... # 中略
      - run:
          name: Run bundle update
          command: |
            if [ "${CIRCLE_BRANCH}" = "master" ]; then
              bundle update
              ... # 中略
            fi

念のためmasterブランチかどうかを確認しています。

3-1. Gemfile.lockに変更があればGitHubにpushする

続いてbundle updateした結果、Gemfile.lockに変更があればGitHubにpushします。
GitHubとCircle CIを連携済みであれば簡単にpushできるのでは?と思うところですが、ここは少し設定が必要です。 なぜなら、GitHubに登録されているCircle CIのdeploy keyがread権限のみだとCircle CIからpushできないからです。
というわけでwrite権限のあるdeploy keyを新たに追加しましょう。GitHubで対象プロジェクトの SettingsからDeploy keysを選択し、Add deploy keyボタンでdeploy keyを新たに追加します。

f:id:ssugai:20171025185023p:plain

その際に、Allow write accessにチェックを入れるのを忘れずに。
deploy keyを追加したら、公式ドキュメントを参考にconfig.ymlにwrite権限のあるdeploy keyを設定します。

# .circleci/config.yml
    steps:
      - checkout
      - add-ssh-keys:
          fingerprints:
            - "xx:xx:xx:xx:xx:xx:xx:xx"
      ...

ここで注意したいのが、- add-ssh-keys:の次行のfingerprints:のインデントです。

# NG
- add-ssh-keys:
  fingerprints:
    - "xx:xx:xx:xx:xx:xx:xx:xx"

# これだと評価した結果が下記のようになってしまう。
# => [{"add-ssh-keys"=>nil, "fingerprints"=>["xx:xx:xx:xx:xx:xx:xx:xx"]}]

# OK
- add-ssh-keys:
    fingerprints:
      - "xx:xx:xx:xx:xx:xx:xx:xx"

# => [{"add-ssh-keys"=>{"fingerprints"=>["xx:xx:xx:xx:xx:xx:xx:xx"]}}]

というわけでfingerprints:- add-ssh-keys:先頭の-から半角スペース4つ下げる必要があります。 私はややハマりました。

3-2. pushが成功したらPull Requestを作成する

最後にGitHubにプルリクエストを作ります。いろいろなやり方があると思いますが、今回はGitHubのWebAPIを利用することにしました。

curl \
  --header "Accept: application/vnd.github.v3+json" \
  --data "{\"title\": \"${BRANCH}\", \"head\": \"${CIRCLE_PROJECT_USERNAME}:${BRANCH}\", \"base\":\"${CIRCLE_BRANCH}\" }" \
  https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/pulls?access_token=${GITHUB_ACCESS_TOKEN}

なお、GitHubのAPIアクセストークンが必要なので取得しておく必要があります。
トークンはCircleCIの設定画面で環境変数として設定しておくと良いでしょう。私はGITHUB_ACCESS_TOKENという名前で登録しました。

最終的にできあがったconfig.yml(一部抜粋)は以下になります。

version: 2
jobs:
  build:
  ... # 中略
  bundle_update:
    docker:
      - image: circleci/ruby:2.4.2
        environment:
          TZ: "/usr/share/zoneinfo/Asia/Tokyo"
        environment:
          - RAILS_ENV=development
          - RACK_ENV=development
    working_directory: ~/ieshil-connect-dev
    steps:
      - checkout
      - add-ssh-keys:
          fingerprints:
            - "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
      - run:
          name: Run bundle update
          command: |
            if [ "${CIRCLE_BRANCH}" = "master" ]; then
              bundle update
              if [ -n "`git status -sb | grep Gemfile.lock`" ]; then
                BRANCH=bundle-update-`date -u "+%Y%m%d"`
                git config --global user.email ${BOT_EMAIL}
                git config --global user.name ${BOT_NAME}
                git checkout -b ${BRANCH}
                git add Gemfile.lock
                git commit -m "Bundle update `date -u '+%Y-%m-%d'`"
                if git push ${CIRCLE_REPOSITORY_URL} ${BRANCH}
                then
                  curl \
                    --header "Accept: application/vnd.github.v3+json" \
                    --data "{\"title\": \"${BRANCH}\", \"head\": \"${CIRCLE_PROJECT_USERNAME}:${BRANCH}\", \"base\":\"${CIRCLE_BRANCH}\" }" \
                    https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/pulls?access_token=${GITHUB_ACCESS_TOKEN}
                fi
              fi
            fi

Circle CI側が用意している機能を利用すればもっとスッキリと書けそうな感じもするので、改善の余地がありそうです。

実際にやってみた感想

月並みですが、「やっぱり自動化しておくと楽だなあ」という一言に尽きます。
現在は日次でbundle updateの実行をしていて、一度に更新されるgemの数も少なくそこまで負担は感じていません。

もちろん、ライブラリのアップデートをしたことが原因で不具合が発生するリスクもあります。そうしたリスクを軽減するためにもまず「テストを書く」ことが大切なのかなと思いました。今回のような仕組みを導入できたのも、高いテストカバレッジを保てていることが前提にあります。きちんとテストを書いている開発陣に感謝。

改めて今回やってみたことを書き起こして見るとそこそこ手間がかかるなあという印象もありますが、一回作ってしまったら後は非常に楽なのでぜひ試してみてください!

入社後、いきなりのサイトリニューアル

はじめに

みなさん、こんにちは。 アルバイト事業部で「マッハバイト」のフロントエンドエンジニアをやっています、山田と申します。 私は7月の頭に入社したばかりなのですが、入社後最初のミッションがサイトリニューアルでした。 今回はその話に触れていきたいと思います。

サイトリニューアルで行ったこと

リニューアルと言っても、フルスクラッチでプロダクトコードを全て書き直すわけではありません。 アーキテクチャの見直しなどは別チームが並行で進めており、僕らの行うことは画面のデザイン変更が主です。

その対応を、9/28のリリースに向けて進めていかなければいけませんでした。

その工程は困りごとの連続

作業を始めたはいいものの、その工程は困りごとの連続でした。

  • CSSの修正が想像よりもやりづらい。
  • 修正が必要な画面がどれくらいあるの把握出来ていない。
  • プロダクトコードがPHP(Symfony)とRuby(Ruby on Rails)に分離していて、戸惑う。
  • プロダクトが複雑で、一機能の仕様把握だけでもかなりエネルギーを使う。

一つずつ触れていこうと思います。

CSSの修正が想像よりもやりづらい

デザイン変更を始めて最初にぶつかった問題がこれでした。

マッハバイトはPCとSP(モバイル)でCSSが分離しています。 PCとSPのそれぞれで、CSSの設計思想が違っていたことが初期の参入コストを高めていました。

  • PC : FLOCSSベースの設計
  • SP : オリジナル設計

といった具合です。

これだけ見るとPCの方が修正しやすく思えるかもしれませんが、そうでもなかったりします。 マッハバイト(当時はリニューアル前のジョブセンスでしたが)はSPの方がユーザーが多く、 CVR向上のためのABテストが繰り返し行われてきました。そのため、設計自体は今風なPC側よりも こまめな整理がされてきたSP側の方が直しやすい場面が度々ありました。

それを踏まえつつ、以下のような方針で地道に修正を重ねました。

  • 不要物の削除
    • 使われなくなったページ、CSSがそのままになっているので消す。
  • 命名規則の統一
    • 今はハイフン区切りで運用しているが、数年前に作った古いページはキャメルケースになっている。
    • CSS用のクラス名が、JavaScriptのイベントトリガーで使われている箇所があるので分ける。
  • デバイス間の設計思想の統一
    • SPの思想を、PCに徐々に寄せていく。
  • 後回しにして放置してしまう展開を避けるため、「後で直す」をなるべくやらない。
    • 影響範囲の広い箇所も直すメリットが大きそうなら、恐れずに直す。リニューアル後になると、直しずらくなってしまう。

ありがちな話ではありますが、方針と対応を列挙してみました。 上記以外にも細かい課題はまだ残っているのですが、日々の小さな積み重ねの中で少しずつでも解決していけるように取り組みを進めています。

修正が必要な画面がどれくらいか把握出来ていない

次にぶつかった問題がこれでした。

入社して間もなかった人間が、プロダクトの機能を全て把握しているわけもなく、 画面数がどれくらいか把握しているわけでもない。 どの程度のペースで作業を進めていけばリリースに間に合うのか分からず、頭を抱えました。

しかし、この問題はすぐに解決しました。 僕の入社前に対応が必要な画面の洗い出しは既にGoogleスプレッドシートに纏まっており、 それらを片っ端からやっていけばOKという訳です。

最終的に、画面名を書いたポストイットをホワイトボードに全部張り出し、 修正が済んだらポストイットを剥がすという運用にしました。 (進捗の確認は毎日行っている夕会で各自報告し合う、というルールになっています) こうしておくことで、体の向きを少し変えるだけで残作業が一目で確認出来るようになりました。

「状況はスプレッドシートで確認出来ます」と言っても、案外見てもらえなかったりもします。 場合によっては、こうしたアナログなやり方の方が上手く機能することもあるので、今後も柔軟に考えていきたいです。

プロダクトコードがPHP(Symfony)とRuby(Ruby on Rails)に分離していて、戸惑う

マッハバイトのプロダクトコードはSymfonyとRailsが混在しています。

ジョブセンス時代は元々PHPで開発されており、それらのコードを順次Rubyに置き換えているため、 現在はそれぞれが混在している状況になっているという訳です。

「この画面のViewはPHPだけど、こっちの画面はRailsにあるSlimを触らないといけない・・」

こうした場面が度々あり、参加初期は混乱の連続でした。

PHPは経験があったので、手探りでSymfony実装に潜っていくことが出来たのですが、 Railsは数年前に少し触ったきりだったので、全く実装を追えませんでした。 そこに危機感を感じた僕は、プライベートでやっていた他言語の勉強を一旦全て中断。 PHPとRubyの学習に充てることにしました。

その甲斐もあってか、今はSlimの記法にも慣れ、 RailsのControllerの処理を追うこともなんとか出来るようになってきている実感があります。

これからもPHPやRubyに対する理解を深め、 プロダクトの改善に貢献できるように心がけようと考えています。

プロダクトが複雑で、一機能の仕様把握だけでもかなりエネルギーを使う。

長年続いている事業ならよくある話なのかもしれませんが、 以前はWeb制作の会社で働いていた僕にとっては結構な衝撃でした。

「求人を探し、バイトを見つける」

ユーザがサービス内で行う行動を言葉にするとシンプルに思えるのですが、 それを取り巻く様々な機能や仕様が存在しており、それらは長年の運用によって非常に複雑なものになっています。

サイトリニューアルを行う中で様々な画面を見て、そこに存在している事を知りました。 フロントエンド領域が僕の主戦場ではありますが、事業内で関われる領域を広げるためにも ビジネスロジックに対する深い理解は欠かせないと思うようになりました。

まとめ

3ヶ月弱の期間でサイトリニューアルをやると聞いた時は少し不安がありましたが、 周りの方々の助けを大いにアテにし、なんとか完遂することが出来ました。

今になって思えば、新参者が全画面を一通り触れたのは今後のサービス改善を進める上で 非常に有り難い機会だったとも感じています。

今後はリニューアルのタイミングで手が回らなかったCSS周りの設計整理や、TypeScriptの導入等に挑戦していく予定です。

チーム全員が知っててほしい抽象化のこと

はじめまして。転職会議ユニットでエンジニアをしている狩野です。
元々PHPerでしたが、最近はRuby(Rails)やReactを触ったりして楽しくやっています。

今回は、中堅エンジニア*1が最近受けた質問とそれに対する回答を、今までのシステム開発で得た知見と併せてブログを書きたいと思います。

はじめに

最近、若手のエンジニアから「クラスとかメソッドってどう分けるんですか?」という質問を受けました。
私は「実世界をそのまま表現するだけですよ。」と答えました。
真面目に答えたのですが、若手エンジニアには全く伝わっていないようでした*2

良い機会なので、実世界の抽象化について少し掘り下げて書いてみたいと思います。

システムとは?

基本的に、システムは「あるドメインを体系的に表現した仕組み」です。
システム開発*3とは、それを作る行為になります。

「ドメイン」とは全体の中に定義される一部の領域のことを指します。
日本語にすると「領域」です。事業を展開する領域*4と考えるのが分かりやすいです。
実際にその領域にいる人々*5に対して、我々はサービスを作って届けています。

ではどのように表現するのでしょうか。実世界は複雑です。そのまま表現はできません。ですので、モデル化(モデリング)して表現をします。
モデル化とは、抽象化のプロセスです。抽象化を行なうには知識(経験やセンス)が必要になります。
抽象化と言うと「曖昧にする」という印象ですが、寧ろ「強調したい一面を明確にする」為に抽象化を行います*6

抽象化について

例えば「人間」についてモデルを考えてみましょう。
「人間」とはなんでしょう?辞書を調べると「哺乳類、道具を使う、複雑な言語を持つ」と出てきました。「人間」を抽象化すると「哺乳類、道具を使う、複雑な言語を持つ」ということになります。
ここで疑問が生じます。例えば、生まれたばかりの赤ん坊は道具も使えないし言葉も話せません。そうなると赤ん坊はこの定義から外れます。赤ん坊は人間ではないのでしょうか。

このように、我々の行うモデルは曖昧です。
この場合、より具体的な「人間」という表現では赤ん坊は含みますが、より抽象的な「道具を使う、複雑な言語を持つ」いう表現では赤ん坊は含まないことになります。
この抽象化が絶対的な正解ということではなく、抽象化の進む方向は領域によって異なります。
対象としている領域に対して矛盾なく抽象化していくことが必要になります。

抽象化を行い、いくつかの正解(様々な解釈)の中から採用するモデルを決定します。改めて、関係する側面を抽象化して、集中するモデルを決定します。これを繰り返します。
この過程を経て、モデル化が進みシステムの表現がゴールへと向かいます。

さて、抽象化はどの程度行うべきなのでしょう。
答えは「時と場合による」です。
先にも書いたとおり、抽象化が絶対的な正解はありません。
身も蓋もないのですが、これが事実です。

よくある例えで、地図の話があります。
地図はモデルです。モデルは対象の概念を表現します。
例えば、近所のお店に行く為に世界地図を用意はしないでしょう。反対に、太平洋の航海を行う為に住んでいる街の地図を用意もしないでしょう。
近所のお店に行く時は住んでいる街が対象であり、太平洋を航海する時は世界が対象になるからです。
時と場合によって、適切な地図を使用します。

f:id:livesense-made:20171003110521p:plain:w300

適切さについて

「適切さ」こそがシステム開発の肝になります。
しかしながら、またしても身も蓋もないのですが、適切さを追い求める方法に正解は無いと思います。
ただそれで終わる訳にもいかないので、主観にはなりますが、3つほど進め方のヒントを挙げてみたいと思います。

1. サイクルを回す

適切さについて、サイクルを回して定期的に見直します。
有名なサイクルとして、PDCA(計画、実行、評価、改善)サイクルや、イテレーションの開発サイクルなどがあります。
最初から完璧な適切さを求めることはできないので、定期的に見直す必要があります。無理のない範囲で小さいサイクルで回して細かく合わせていくのが良いと思います*7
そういった意味でも、開発手法はウォータフォールよりもアジャイルが適しています。

アジャイル開発の中で、習慣的にリファクタリングを繰り返して、コードをきれいな状態に保ちます。
重要なモデルを追加すると同時に、役に立たないモデルを取り除きます。
可能な限りをコードで表現して、ドキュメントとしても価値のあるコードを書きます。コード単体で意図の伝わることが理想です。
それでも「何故」などはコードに残せないので、必要があればWhyをドキュメントとして表現します*8*9

実世界をモデル化する作業を「野球のグローブ」や「革のジャンパー」に例えた話もあります。
最初はしっくりきていなくても、使っている間に自分の手や身体に合った形に馴染んでくる例えです。
モデルも使い込んで見直していく間に蒸留されて、より適切な形になっていきます。

f:id:livesense-made:20171003111621p:plain:w300
2. コードの見通しを良くする

コードの見通しを良くすることで、適切さを維持します。
「見通し良さ」とはなんでしょう?

コメントをたくさん書けば良いという訳ではありません。寧ろ冗長になって見通しが悪くなることもあります*10
寧ろ、コメントを書かずに「シンプルに保つ」ことこそが見通しを良くする手段です。
簡単なコメントなら書かなくても伝わるようなコードを考えましょう。また、簡単なコメントを書かなければいけないのであればコードの表現が誤っている可能性があります。
先に述べたように、コメントを書かない訳ではありません。ただ、極力コメントを書かず、コード単体で意図の伝わることを目指します。

コメントは書き換えなくてもコードは動きます。
コードとコメントが密である間はまだ良いですが、改修を続けていると徐々にコードとコメントが離れていきます。
例えば、別ファイルに依存したコメントなどを書いてしまうと、その別ファイルのコードを更新した際にコメントを修正しなければいけないですが、別ファイルに記述されているコメントに気付くのはほぼ不可能です。そうなると実体を表さないコメントだけ残ることになり負債となります。

コメントも運用や保守の対象であることを認識して、コメントを書かなくても意図が伝わるコードを心掛ける必要があります。
コードの読み易さにこだわりましょう。

また、技術的な層とビジネスを表現した層を混在させないことも重要です。
責務の分割して層を分けて、見通しを維持します。
可能であれば、技術的な層はフレームワークやライブラリに任せるのが良いでしょう。
フレームワークが用意している思想に合わせると、共通の認識が持ちやすく、結果的に見通しも良くなります。
その一方で、得た知識を盲信してエンジニアの思想に閉じたコードになってしまわないよう、注意が必要です*11

オーバーエンジニアリングは柔軟性を与えてくれるように見えて、実は邪魔になることが多くあります。
適切に表現されたモデルはシンプルなものが多いです。

シンプルであることこそが、最適な抽象化です。最もシンプルな表現を心掛けます。
モデルは、それを変更しようとする別の人にとっても分かりやすくなければいけません。シンプルであれば変更も容易です。
YAGNI(You Ain't Gonna Need It.)や、KISS(Keep It Simple, Stupid.)などの法則もあります*12

3. 共通の言語を持つ

共通の言語を使うことで、適切さを正していきます。
共通の言語というのは「システムに関わる全ての人が、同じ領域においては同じ言語を使う」ということです。

このような言語は「ユビキタス言語」などと呼ばれることもあります。

一例で「あるサービスの名称」について考えてみます。
同じサービスを指す名称であっても、「サービスの商品名」「システム上でサービスを示す呼称」など、別名で呼ばれることがあります。
これらは本質的には同じものを指しているので、理想的には一致しているが望ましいです。「同じものは同じ名前を付ける」が鉄則で、脳内でのマッピングを回避できて理解しやすくなります。
しかしながら、下記に挙げるような制約で「仕方なく別名にしている」というのが現状です。

  • システム上では英語で呼ばれ、商品名は日本語で呼ばれる
  • 実体を表さない商品名
  • etc.

既存でそれなりに実体を表す共通の呼称があれば、それを採用するのが良いと思います。

良くあるのが、商品名は顧客に対する表面的な名称として使いつつ営業内で使用し、サービスの呼称はエンジニア内で使用する、という状況です。
ここで問題となるのが、商品名しか知らない営業とサービス名しか知らないエンジニアの会話です。
その解決策としては、下記に挙げる三択のいずれかになります。

  • 営業がサービスの呼称を知る
  • エンジニアが商品名を知る
  • 通訳を設ける

理想的なのは「営業がサービス名の呼称を知る」です。なぜなら、サービス名の呼称こそがそのものの実体を表現した名称になっている(はずだ)からです*13
実体を表さない商品名をエンジニアが常にキャッチアップするのは難しいです*14
通訳を設けるのであれば常にディレクターなどを同席させての会話が必要になります。

こういった前提があり、エンジニアに限らず浸透しやすく、誤解なく実体を表す命名が必要となります。
省略形の命名なども、対象となる領域で浸透していないのであれば、誤解の元となるので避けた方が良いでしょう*15

更に進んで、最初にサービスを示す呼称を決めきることは難しく、多いので時間の変化と共に見直していくのが良いです。
これは先に述べた「サイクルを回す」で対応できます。
しかしながら、技術的制約で名称変更が難しい箇所などは、最初の段階でどこまで想定して名前付けを行えるかが肝となります。

新しく定義した「user」や「status」という言葉が別の人に正しく伝わるとは限りません。
寧ろ、正しく伝わらない前提で進めるくらいが良いでしょう。
そういった観点が、より正しい言語を探す道へと続きます。

群盲象を評す」という寓話があります。
目の見えない人たちが全員で同じ象を触っているのに全員が違うことを言う、という例え話です。
サービスも目に見えないものなので、これと同じような状況にあることがあります。
全員が同じモデルを持つには、共通の言語が必要になります。

開発に着手する前に、対象を言葉で表現してみます。言葉で表現(言語化)できないものは理解できていない可能性があります。
名前付けは、運用や保守にとても重要です。寧ろモデル化の大部分は名前で決まると言っても過言ではありません。
名前がしっくりこない場合は、モデル化の構造自体を見直した方が良いでしょう。
言葉で表現できるようになってから、開発に取り掛かりましょう。

f:id:livesense-made:20171004110452p:plain:w300

進化する実世界

ここまで話して、実世界の対象となる領域をモデル化してシステム開発を進める方法は、何となくは伝わったかと思います。

しかしながら、システムは完成しません。
なぜなら、実世界は進化を続けているからです。

一般的な例として、サービス領域の拡張などがあります。
大きいものでは、任天堂が花札からビデオゲーム機に主力商品を変えたり、Amazon.comが書店から総合ECサイトになったり、などが挙げられます。
小さいものであれば、身近にも無数にあるかと思います。

VUCAという言葉があるそうで、Volatility(変動)、Uncertainty(不確実)、Complexity(複雑)、Ambiguity(曖昧)の頭文字を並べた用語です。
これはサービスの領域そのもので、システム開発でも言えます。

システムは実世界に同調し続けなければいけません。
サービスの領域について絶対的な表現は無く、その時点での最善で最適な表現を見つけます。

f:id:livesense-made:20171003112752p:plain:w300

最後に

繰り返しになりますが、実世界は複雑です。
複雑な実世界を表現する作業であるシステム開発が複雑なのは、必然です。

ここで述べたことはサービスに関わるチーム全員が考えなければいけないことであり、エンジニアだけの問題ではありません。

抽象化が進まないと、強調したい箇所が分かり難くなりモデルの表現力が弱まります。
モデルの表現力が弱まると、サービスとコードの乖離が進み、小手先の技術的な解決が増えます。
柔軟性や拡張性が失われ、要求に応えることが難しくなり、保守が難しくなります。
複雑さの泥沼にはまり込み、障害やバグの頻発する価値の薄いシステムに成り下がる末路が待っています。

良いシステムを維持し続ける為に、常に実世界と向き合って、適切な抽象化を繰り返してモデル化していく必要があります。
適切な抽象化はサービスの表現に力を与えます。

これからのシステム開発の手助けになれば、幸いです。

f:id:livesense-made:20171003133424p:plain:w300

*1:いわゆる「おっさん」です。

*2:「こいつは何を言ってるんだ?」くらいに思われた気がします。

*3:このブログでの「システム開発」は「Webサービスのシステム開発」について語っていきます。

*4:「事業ドメイン」という言葉は聞き覚えがあるかもしれません。

*5:利害関係者やステークホルダーなどを指します。

*6:要らない箇所を捨てる取捨選択の作業です。

*7:手法は合ったものを適切に取り入れましょう。手法の原理主義者になってはいけません。

*8:たまにWhatやHowをコメントに書いているコードを見掛けますが、冗長になるのでやめた方が良いでしょう。

*9:https://twitter.com/t_wada/status/904916106153828352

*10:「丁寧」と「冗長」を混同してはいけません。

*11:実世界に則さない過度な共通化などは、そのひとつです。

*12:実際のコードを書くテクニックとしては、「条件分岐は短く」「否定の否定など書かない」などありますが、ここでは割愛します。

*13:もちろん、本来であればこの命名に営業の方を巻き込めるのが最適ではあります。

*14:それでも、その商品名自体が浸透してくれば、そちらを共通の言語として使用することもあります。

*15:必要以上に省略形を使ったり、新しい語彙を増やしたがる人は、注意が必要です。

CSSは簡単だなんて誰が言った

f:id:sueshin:20170915154014p:plain はじめまして!正社員転職サービス転職ナビ(旧ジョブセンスリンク)のフロントエンドを担当しているsueshinです。
CSSはプログラミング経験の浅い方でも扱いやすく、比較的習得が早い言語だと言われることが多いと感じている次第です。
もちろん、それはCSSの素晴らしい側面の一つです。
一方で、設計のアンチパターンと言われることが、CSSでは積極的に採用され、長期の保守になると難しいという側面もあります。
今回は企業様用採用管理ツールのCSSの保守で苦戦し、リファクタリングした時のお話をいたします。
お手柔らかにどうぞ。
尚、ソースコードは一部記事に合わせて表現を変えています。

なぜCSSをリファクタリングしたの?

f:id:sueshin:20170915172411j:plain 企業様用採用管理ツールのCSSをリファクタリングする前は以下のような大きな問題を抱えていました。

管理されていないCSS

転職ナビはリブセンスの創業初期からある歴史あるプロダクトです。
デザインリニューアルだけでなく、ブランド名変更によるリブランディング等、度重なる大規模変更が過去にあり、数々の負債を抱えながら成長してきました。
そのため、非常にプロダクトが複雑で、社内用の管理ツール向けのCSSを修正すると企業様用採用管理ツールのビジュアルが崩れる等、非常に保守コストがかかっていました。
また、CSSの格納ディレクトリは全てのアプリケーションのCSSを含んでいるため、40000行を超え尚肥大化し続けています。
以下はCSSディレクトリの抜粋です。

css
├── 2009/
├── file/
├── user/
├── htmlMail/
├── lp/
├── manage/
├── pc/
├── pr/
├── sp/
├── admin/
└── blog/

意味のないファイル名

下記は企業管理画面のディレクトリツリー抜粋です。
一見、トップページ用にしか見えない命名のファイルがあらゆるページで使用されていました。
他にもページ単体で使用されているように見える命名のCSSが、多数のアプリケーション全体で使用されたまま放置されており、開発は長らく混乱していました。

manage
├── recruit/
│   ├── top.css
│   ├── works.css
│   ├── works_hint_detail.css
│   └── works_title.css
├── scout/
└── vendor/

どこにいったDRY原則

開発メンバが既存コードに合わせて実装しようとして、フロントエンドエンジニアの私に質問してくれても、そもそもの保守方針はなく、残念ながら歯切れの悪い回答しかできませんでした。
結果、開発スピードを重視して繰り返されるハードコピー。
DRY原則を意識した再利用性のあるコードを書けず、私はずっと歯がゆく思っていました。

いまどき生CSSなんか触りたくないと入社2年目の後輩にいわれた

大人でも辛くて泣きたくなる時はあります。

要約すると

f:id:sueshin:20170915172407j:plain 問題点を並べましたが、成し遂げたいことを箇条書きにするとこのようになります。

  • 他のアプリケーションを修正したらバグがでるという状況を阻止する
  • 保守方針を立てる
  • CSSからSassへ移行することで、より保守を容易にする

具体的にしたこと

f:id:sueshin:20170915172418j:plain

以下の手順で進めました。

  1. コードリーディング
  2. Sassの導入
  3. アプリケーションをまたいでいるCSSをひっぺがし
  4. 各ページ単体で使用しているCSSをそれぞれディレクトリごとに分類
  5. リンター導入
  6. README.mdを作成

1.コードリーディング

まず手始めにひたすらコードを読みました。
そうすると、読み進めていくうちに既存コードの以下のような特徴に気づきました。

  • 要素タグに対するスタイル定義がCSSファイルの上部に固まっている
  • 多くのページで呼ばれているCSSファイルに組み合わせが存在する
  • (一部のCSSファイルでは)id属性とclass属性で汎用性別に使い分けられていそう

これらを踏まえると下記のようにCSSを分類できそうだと判断しました。

  • ブラウザ定義スタイルのリセット
  • 各要素タグ毎の基本的な装飾
  • グローバルで使用できるコンポーネント定義
  • 各ページ固有のコンポーネント定義
  • ヘッダーやフッターのレイアウト定義

2.Sass導入

f:id:sueshin:20170915172355p:plain コードリーディングの結果、大多数のURLで同じ組み合わせのCSSが呼ばれていることがわかったので、これらを一つのファイル(application.scss)として再定義しました。
これらはsymfonyやRoRではレイアウトファイルに記述がまとめられていることが多いと思うので、パスの置換作業などは比較的容易かと思います。
その後、作成したapplication.scssを複数のファイルに分割しました。
分割することで数千行あるCSSの可読性を高めることが狙いです。

3.アプリケーションをまたいでいるCSSをひっぺがし

別アプリケーション名のディレクトリに存在しているCSSがあったので、ファイルをコピーして作業対象の企業管理画面では、専用のディレクトリからしかCSSをよばないようにしました。

4.CSSを使用されているディレクトリごとに分類

この作業に一番時間がかかりました。
URL別にCSSを読んでいたのですが、top.cssなのにトップページ以外からも呼ばれており、判断に迷いました。
それらも踏まえて大別すると以下の3パターンに分類できました。
※尚、各ページのパスを/module/action/と考えています。(例えばトップページなら/home/indexとなります。)

  1. 複数のmoduleで使用しているがグローバルなCSSというほどではない
    • →commonディレクトリを作成
  2. 固有のmodule内でしか使用されていない
    • →module名のファイルを作成
  3. ひとつのactionでしか使用されていない
    • →moduleディレクトリにaction名のファイルを作成

実際のディレクトリ構成です。

├── common
│   ├── company.scss
│   ├── scout.scss
│   ├── top.scss
│   ├── view.scss
│   └── works-skill.scss
├── home.scss
├── info
│   ├── help.scss
│   ├── home.scss
│   └── kiyaku.scss
├── recruit
│   ├── plan.scss
│   ├── works.scss
│   └── works-title.scss
└── detail.scss

5.リンター導入

f:id:sueshin:20170915173758p:plain 今回成し遂げたいことの一つは保守性の向上。
これを逃すと機会がないと思いやや強引ですが、ユーザー側で導入しているstylelintを導入しました。 各ファイル1行1行の修正は大変なので、ファイルごとに例外処理を追加して導入しました。

コード例

/* stylelint-disable selector-no-id, declaration-no-important  */

.test {
    color: #fff;
}

なぜ、例外処理を追加してでもリンターを導入したかというと、実装方針さえ決まっていたら、守ることが容易なルールがファイル内でさえ統一できていなかったからです。
目立ったところでいうと以下のようなルールです。

  • インデントはソフトタブかハードタブか
  • インデントの深さ
  • カラーコードは大文字か小文字か
  • 空行の有無
  • セレクタの後の半角スペース

6.README.md作成

本来はプロダクションコードからコーディングルールやクラス・ディレクトリ命名方針が類推できることが良いと思います。
ただし、今回のリファクタリングでは実装方針が定まっただけであり、コードの品質が高まっただけではないので、補足説明を手厚く書きました。

躓いたポイント

f:id:sueshin:20170915172359j:plain 上記の手順を立て、リファクタリングを進めましたがスコープがあまりにも大きく、何度もつまずきました。
以下は躓いたポイントです。

1.CSSハック

設定を変更したら、変更できたのかもしれませんが、どうやらSCSSにも許せないCSSハックがあるようでした。
私はWEBを覚えて浅いこともあり、ブラウザ対応はIE8からしか対応したことがありません。
既存コードがどういった目的でCSSハックをしているのか、わからない記述も多かったです。
調べても中々良い情報に出会えず途方に暮れている中、信じられそうな情報に出会えた時は感動しました。

具体例としては、下記のようなスラッシュハックを

#footer {
  /zoom: 0;
}

こちらのアスタリスクハックに変更することで

#footer {
    *zoom: 0;
}

無事CSSへのプリコンパイルができました。

2.CSSファイルパスの変更

ファイルのパスを変えてCUIで一括置換していたのですが、以下のコードが存在する可能性が有るためにリファクタリング中の不安は拭えませんでした。

<link rel="stylesheet" type="text/css" href="<?php echo(''/css/manage/' . $val . '.css''); ?>">

このようにgrepしても検索にヒットしないファイルの存在による置換もれをどのように対応するかは最後まで悩みました。
他にいい方法が合ったのかもしれませんが、最終的に私はPHPディレクトリのCSSという文字列を全部grepして目視して確認しました。

3.CSS最大の難関、詳細度戦争

世界各地で問題になっているCSSの詳細度がやはり頭痛の種でした。
今回迷ったのは以下のような場合です。 例えばこのようなコードがあったとします。

//1
.modal {
    color: #aaa;
}
//2
#top-modal {
    color: #bbb;
}
//3
#container .modal {
    color: #ccc;
}
//4
.detail-modal {
    color: #ddd;
}

1のmodalと2のtop-modalの順番を変更した場合デザインに影響がある可能性はあるのでしょうか?

//2
#top-modal {
    color: #bbb;
}
//1
.modal {
    color: #aaa;
}
//3
#container .modal {
    color: #ccc;
}
//4
.detail-modal {
    color: #ddd;
}

答えは「可能性はない」です。
では、1のmodalを4のdetail-modalの下に変更した場合デザインに影響がある可能性はあるのでしょうか?

//2
#top-modal {
    color: #bbb;
}
//3
#container .modal {
    color: #ccc;
}
//4
.detail-modal {
    color: #ddd;
}
//1
.modal {
    color: #aaa;
}

答えは「可能性はある」です。
幸いID属性とクラス名は飛び飛びで固まっていたため、セレクタがID属性同士、class属性同士で順番を変更しないように整理しました。 可読性はあまりよくないですが、デグレーションを避けるため順番はできるだけ変えないようにしました。 application.scssの例

@import "layout/header";
@import "layout/container";
@import "layout/aside";
@import "layout/footer";
@import "object/project/modal";
.clearfix {
    *zoom: 1;
}
.clearfix:after {
    content: '';
    display: block;
    clear: both;
}
@import "object/project/tooltip";
@import "object/project/link";
@import "object/utility/margin";
ul.modBtn,
.modInfo dl {
    *zoom: 1;
}
ul.modBtn:after,
.modInfo dl:after {
    content: '';
    display: block;
    clear: both;
}

4.ユーティリティクラスがユーティリティじゃない

ユーティリティクラスとして定義されているけど、実際に使われていないユーティリティクラスをどのように分類していいか非常に悩みました。

.txtRed {
    color: #f44336;
}
.txtOrange {
    color: #f60;
}
.txtGreen {
    color: #53acac;
}
.txtGray {
    color: #999;
}

これらは開発メンバの誰も知らないクラスです。
ユーティリティクラスとして分類しても、開発メンバが余計に混乱すると考え、ユーティリティクラス専用のディレクトリに分類しませんでした。

5.リンター導入の作業は地道でした

一部例外処理として設定しましたが、可能な限りリンターのルールに違反する箇所は修正しました。
膨大なソースコードのカラーコードを小文字にしたり、ソフトタブとハードタブを統一したりと地味に膨大なコストがかかってしまいました。
守ってくれたら儲けものと思って、アプリケーションを作った際は、コーディング規約を真っ先に導入すべきだと思いました。

そしてリリース!!

f:id:sueshin:20170915165124j:plain やりました。
もう後輩にCSSなんか触りたくないなんて言われません。
数々の困難と組織的な諸事情もあり最初のコミットからリリースまで1年以上経ってしまい、隣の島にいた後輩はもう近くにはいませんが。。。
でも、問題ございません。
我々が欲しいのはハッピーエンドではなく、鍛え抜かれたハッピーマインドなのだから。(*1)

まとめ

f:id:sueshin:20170915172423j:plain

  • 学び
    • 古くなった情報でも、レガシーコードを改善する上で役に立つことがある
  • 課題
    • フロントエンドエンジニア以外には改善が実感しにくいリファクタリングになってしまった
    • 大規模改修になるため画面チェックにコストがかかってしまった
  • 効果
    • 今ならあまり心を痛めること無くレビューができる気がします。
    • ソースコード量の減少に向けて舵を切ることができた。
    • 企業管理画面を修正するとリブセンス用のツールでエラーがでるということはありません
    • 現状を整理できたことで、開発メンバの学習コストがへった。
    • 新しい開発メンバが入ってくる度に怯えなくていい

さいごに

f:id:sueshin:20170915172403j:plain このリファクタリングを進める上で、チームメンバは勿論のこと、沢山のサイトや書籍に助けられました。
特にCSSハックに対する知見を共有しているサイトを夜中に見つけたときは、本当に感動しました。
この記事が少しでも負債と戦うエンジニアの助けになれば幸いです。

*1: 元ネタは矢沢あい著「ご近所物語」です

経験者が送る新卒入社後あたふたしないために心がけたい5箇条

はじめに

みなさんこんにちは。 16新卒入社したネイティブアプリチームの井上です。
2017年4月に入社された新卒のみなさんは、研修を経て現場での業務が始まるor始まっている頃かと思います。
正直言うと、私はチームに配属直後 とっってもあたふたしてました

〜配属前の私〜
「たくさん学んで早く活躍するぞ! (^ω^)」

〜配属後の私〜
「逃げちゃダメだ。逃げちゃダメだ。逃げちゃダメだ。うわあああああ(‘ω’)あああぁぁぁぁぁ」

はい、リアルにこんな感じでした。
例えば以下のようなことをやらかしてました。

  • リリース期日に実装が間に合わない
  • リリース後、実装箇所で落ちる
  • 自分のミスを自分でフォローできない
  • ディスカッションで発言できない
  • ブログ書いたらほぼ全直し(←new 本記事)

などなど…。

きっと新卒入社される方の中には、やる気に満ち溢れていて、これからが楽しみで仕方がないという人がたくさんいると思います。

そこで本記事では、みなさんにぜひ心がけてほしい点を「配属直後にあたふたしないための処方箋」として、私自身の経験を元にまとめていきたいと思います。

配属後のスタートダッシュで転ばないために参考にしてください。

アプリチームの仕事

実際に経験した業務は以下のようなもでした。
それぞれ簡単に内容を紹介していきます。

  • 施策検討
  • iOSアプリの新規開発
  • Android・iOSアプリの改善・グロース
  • APIの実装

施策検討

 プロダクトに携わる以上は、そこにどんな課題があり、どういう価値を提供すべきなのかということを、チームの一人一人が自分自身の中でしっかり理解し、納得することがとても重要です。弊社アプリチームの場合、職種関係なくチーム全員でさまざまなディスカッションを行い、「解消すべき課題は何か」「目的・手段は適切か」「いつまでにやるべきなのか」等を検討します。

iOSアプリの新規開発

 2016年秋頃からiOSアプリを開発することになり、私もそこにjoinしました。iOSアプリはSwiftで実装し、ライブラリの選定や基盤処理の実装、画面作成・メインロジックと幅広い範囲の業務を経験しました。
 この期間は余裕がなくかなり忙しかったですが、業務としてアプリの新規開発に携わるという非常に貴重な経験ができました。

アプリの改善・グロース

 日常的に行う業務のメインはAndroid・iOSアプリの改善とグロースです。施策検討時に決定した内容を、タスクとして各担当者に振り分け開発を進めていきます。
 チーム内のエンジニアはOSごとに担当が決まっているわけではなく、全員が両OSをカバーしています。施策によっては一時的に専任担当をつけるときはありますが、基本的にはどちらの開発も行うため、両OSの開発スキルが必要とされます。

web APIの実装

 弊社のアプリでは、サーバーとのデータのやりとりにweb APIを利用しているため、その開発・保守もアプリチームの担当です。
 web APIはRuby on Railsで実装されており、Android Java・Swifttの知識だけでなくサーバーサイド開発の知識も必要です。

働いて気づいた現実

f:id:omega999:20160227172243j:plain

配属前に、「やりたいこと」「やること」については事前に伺っており、私自身配属が楽しみでした。しかしいざ業務が始まってみると、

〜業務内容を聞いた私〜
「いっぱいやることある楽しそう、幅広く学べそう、グロースグロースぅ!(˘ω˘)」

〜業務が始まった後の私〜
「開発時間かけすぎた、アイディアまとまらない、ちょ時間足りない、助けて神様(˘ω˘;)」

はい、見事に理想と現実のギャップに悩まされました。
納得できる成果が見えなかったため、なかなか自信がつきませんでした
当時、特に悩んでいたことは以下のようなものです。

  • 満足できないアウトプット
  • スムーズに定着しないスキル

満足できないアウトプット

〜タスクが決まった私〜
「来週までに完成だから前日には完成させて別のタスクもやろう(˘ω˘)」

〜タスク締め切り前の私〜
「あれバグが、これ落ちるじゃんか、何やってんだ自分(˘ω˘;)」

 当時は目の前にある一つのタスクにしか手を付けられず、しかも十分な質・スピードで対応できなかったため、自分の成果に自信がをもてない状態でした。
 チーム配属後の最初のタスクは思ったよりも複雑で、予定よりもかなり時間を要してしまいました。その後のタスクでは、リリース後に不具合が発生したこともあり、とっても凹んでいたのを覚えています。
 自分がプロダクトにどういう貢献ができているかを考えたとき、何ができているんだろう?とモヤモヤしてました。チームに貢献できていないのではないかという思い込みで、1人勝手に悩んでいました。

スムーズに定着しないスキル

〜学び始めた私〜
「アプリ・サーバーサイド両方必要だからたくさん覚えないと(˘ω˘)」
〜学んできた私〜
「Android開発してたら、iOS開発忘れた、あれAPIも、おいおい身についてるのかこれ(˘ω˘;)」

 もともと私はAndroidアプリ開発経験がなかったため、配属直後はわからないことだらけでした。iOSは少しかじってましたが業務レベルだと全然通用せず。 さらに一つのことを覚えて、一つのことを忘れる時もありました。
 「何がわからないのかわからない」状態で、覚えなければいけないことが多すぎ、コーディングを楽しむと言うよりは、タスクをこなせるだけの知識を身に着けようと必死でした。
 十分に内容を理解し、キレイなコードで実装することが理想でしたが、当時は熟考するだけの余裕がなく、納期も守れず非常に悔しかったです。その後も自分で納得できるような仕事をできるようになるまでには、時間がかかりました。

あたふたしないために心がけたい5箇条

f:id:omega999:20170305224358j:plain

毎日がむしゃらに過ごしてきて、気づけばあっという間に1年が経っていました。
改めて振り返ると、当時もっと心がけておくべきだったなと思うことがいろいろ出てきます。
こうした経験から学んだことを今回は5つ紹介します。

  • 今の成果を認める
  • 最短最大の学習をする
  • 「マイペース」を作る
  • 好奇心を育む
  • 手段を正当化しない

今の成果を認める

〜今の成果を認められた私〜
「画面のデザインできた、ロジックも実装、MTGでも発言、前より成長している感じある(^ω^)」

 当時はアウトプットの質に満足いかないことが多かったですが、不完全であろうと、あるいは締め切りに遅れようとも、そこで何かしらの成果は出してきました。こだわりきれず、納得できない、という否定的な思いばかり抱く時もあると思います。
 そのような時には、まず、 現状の力を理解するために今の成果を認めることから始めるべきです。私はタスクが終わるごとに振り返りをし、そこからの学び等を整理しました。

  • 技術的に学んだこと
  • 意識的に改善したこと
  • つまずいたこと

 1つのタスクをこなし、それによって、自分がどこまでできるようになったのかを把握することはとても重要です。現状を理解すれば問題もわかるはずです。私の場合はチームメンバーからFBをもらうことができ、客観的に自分を評価できました。もし自分で成果を認められないと悩んでしまうなら、周りの方々にFBをお願いしてみると良いと思います。
 このように現状を理解する積み重ねがあるからこそ、学びを理解し成長を感じられるようになると思います。

最短最大の学習をする

〜最短最大の学習を意識した私〜
「効率的に業務を進められて、タスク間に合ってる、作業も早くなった(^ω^)」

 私は以前から、疑問に思ったことを調べるために多くの時間をかけがちで、業務の中でも答えが見つからないものを延々と調べていたことが何度もありました。それは実はプロダクト独自の仕様であったり、まだ情報が出回っていない不具合だったりしました。もう少しで答えが見つかる気がする、そんな思い込みで多くの時間を浪費してしまい、そしていつの間にか危険信号が点滅してしまっているのです。
 まずは 目の前の課題をどうすれば最短で解決できるのか、それを考えることが重要です。手段は多くありますが、まずはその調査方法が最短経路かを一度考え直してみましょう。

  • チームメイトに聞く
  • ネットで調査
  • 社内wikiから探す

 これまでは理解するまで時間をかけて解決してきましたが、業務という限られた時間の中ではその方法では効率が悪い時もあることに気づきました。 学習効率の非効率性を限りなく排除し、最短最大の学習方法を選択することが重要です。
 そして、当時周りの方々からよく言っていただいた 「わからないことは聞いてください」という言葉の本質はここにあるのだと理解できました。
 時間をかけるべきもの、時間をかけるべきではないもの、その判断を効率よく行うための方法にたどり着くには、自分ひとりの力では難しいこともあります。

「マイペース」を作る

〜マイペースを意識した私〜
「前より覚えがスムーズになった気がする、技術も吸収してる、学習に余裕がある感じ(^ω^)」

 業務のことで悩んでばかりいると、考えることに疲れてしまい、その結果、当時は自分の学習ペースが完全に乱れてしまっていました。気持ちが焦ってばかりで単純に疲弊していたんだと思います。未熟であるから焦るというのは良い刺激ですが、空回りしてしまっては問題の解決には至りませんし、むしろ悪化させる一方です。
 最短最大の学習をすることと上記で述べましたが、その 自分にあった学習方法を習慣化し維持できるようにマイペースを保つことが重要です。足りないと思っていた時間もペースを整えればうまく調整できることもあります。例えば私は以下の項目を見直してマイペースを整えました。

  • 生活リズムを整える
  • 自由時間を決める
  • 趣味の開発をする

 ちなみにマイペースとは無茶をしないということではありません。時には無茶だと思える挑戦も必要です。そういうときは計画的な無茶をすべきです。業務だけに浸らずに、やりたいことをこなし、学習意欲とモチベーションを維持していくことが重要です。

好奇心を育む

〜好奇心を取り戻した私〜
「こういう設計にすれば良いのか、早く家帰って作業しよう(^ω^)」

 入社してからずっと思っていましたが、弊社エンジニアの方々は技術に対する好奇心がとても強いなと思っていました。(弊社に限ったことではなく、エンジニアって好奇心の強い人が多いと思いますが)
 私のペースが乱れていた時を振り返ると、学びたいことよりも必要なことを優先して学習し、気持ちの余裕があまりなかったです。 自分の興味・関心の幅を広げ好奇心を育むことは、学習のモチベーションに直結しますし、なにより充実感を得られますよ。なのでアプリ開発業務以外のことをやる時間を増やしました。

  • 業務以外の開発
  • 技術書を読む
  • webの技術調査

 当時は「何を学ぶべきか」に迷ってなかなか学習もスムーズにいかなかったのを覚えています。業務優先ばかりで、好きなことをおろそかにすることはやめましょう。技術をもっと好きになるため好奇心には素直に向き合っていきましょう。

手段を正当化しない

〜手段を正当化しなくなった私〜
「これって最適?要件整理しなおそう、実装時間かかるな、今は人に聞こう、柔軟に対応できるようになった(^ω^)」

 目的を言語化し、目の前に掲げて行動することは重要なことです。一方で、目的設定をせず手段ベースで物事が進んでしまうのは、ゴールを見失うことになってしまい注意が必要です。
 私は焦って仕事をしていた時、形式的なことだけを重視した手段ベースの考えで行動してしまい、目的を後付けしてしまう時がありました。しかし、後付の目的設定をすると 手段が正当化されてしまい目的を達成するための手段が適切であったかの判断ができなくなります。そうならないためには、目的等をもう一度考えてみましょう。

  • 達成すべき目的はなにか
  • 得られる効果はなにか
  • 今の状況で最も良い手段はどれか

 振り返ると、あのときは別の方法を取った方が良かっただろうと思うことが多々あります。目的の理解が十分でないときには注意が必要です。
 このように、後付けの目的設定をしてしまっていると気付いた時は、何かを見落としているかもしれないと考え、その場面で最も良い手段を選択できるように心がけることが重要です。

最後に

 1年を振り返ると、自分はダメダメだったということがわかりました。そして今はそれらが改善されているかのように本記事を書いていますが、まだまだ未熟者です。
 ですが、社員皆様のお力添えのお陰でできることは増え着実に成長していることに喜びを感じています。いつもご指導ありがとうございます。

 そして新卒の皆さんはあたふたせず自分のやりたいことを実現していってください!
 私と同じようにうまくいかないなーと思った方の助けになれば幸いです。

おまけ(開発しているアプリ)

f:id:omega999:20170816180201j:plain:w115f:id:omega999:20170816180211j:plain:w115f:id:omega999:20170816180218j:plain:w115f:id:omega999:20170816180221j:plain:w115f:id:omega999:20170816180223j:plain:w115

弊社アプリの紹介をさせていただきます。 業務として担当したアプリについてですが、当時から弊社では転職ナビ(旧:ジョブセンスリンク)のアプリが公開されていました。
求人を評価することができる機能や、希望にあった求人を探しやすくする機能を取り入れており、分かりやすいUIとサクサクとした動作で、とても使いやすいアプリだと思います。
当時はAndroidアプリのみでしたが、2017年1月にはiOS版も公開し、今では多くのユーザーに利用されています。 ぜひみなさんも利用してみてください。

play.google.com

itunes.apple.com