英語で萌えよう!

この記事は、 OIT Advent Calendar 2016の19日目の記事です。

OITでAdvent Calendarが書かれるのは感慨深いです。

自己紹介

2003年入学、2009年修士卒のOBです。HxSコンピューターサークルとF教授の研究室にいました。今は、某IT系企業でエンジニアをやっています。 Twitterでは@kodukiで活動しています。大学関係者はパスカルの方が分かる人多いかも?

大学時代は北山祭で餅ついて売ったり、バケツでプリン作ったり、コーラにメントス入れたり、 「何を言ってるかさっぱりわからない研究でも必ず質問をする」という謎のマイルールで6年間いろんな研究室の発表を見に行ってたらしまいにはメガネの魔王とか言われたのは良い思い出です。

学祭や卒研発表には今でも顔を出しに行くことが多いので、見かけたら声をかけてくださいー。

また、今年はKirika_K2氏と一緒に大学院の講義の「情報科学特別講義C 」を一つ受け持つこともしました。

今回はOITのアドベントカレンダーということなのでせっかくなので、学生の人たちに読んでもらいたいなー、と思う記事を書いてみることにしました。

この記事は特段技術系ではないので、技術系の記事読みたい人は他のアドベントカレンダーだけど下記あたりをどうぞ。

英語やってますか?

在学中、6年間LL教室に入り浸ってはいましたが、遊んでただけで特に英語の勉強をすることは無く、TOEICの点数も300点以下という悲惨な感じでしたが、 趣味の技術関係や研究に必要な技術資料は自分の英語力でもある程度読めるし問題ないかなーと思ってました。

でも、就職して思ったのは英語が出来るとやっぱ世界が広がんるんですね。

色んなソフトや技術を選ぶなかで「日本語でのサポートの有無」を前提にしなくて良くなりますし、
海外の会社だと身構えることなくいろんな人と直接コミュニケーション出来ますし、
イベントで発表して質問が英語だったり、そもそも会場が英語だったりでも対応できますし、
ある日突然明日から会社の公用語は英語ねって言われても困らないですし、
JavaC++などどんな言語よりもエンジニアが覚えて損しない言語だと思っています。

別の会社に行った人やIT関係以外の人も含めても聞く限り、意外に学生時代に思ってるよりは「明日から英語ね」とか「ちょっと海外行って来て」と言われるケースは多いと思います。 飲食店やスーパーでさえその辺にいる外国人が店に来た時は対応してる店員よく見かけますし。私の想像力が足らなかっただけかもですが。

そんなわけで英語学習の話をしたいと思います。

どうやって英語を勉強するの?

「学べ、そして使え」これだけです。簡単でしょ? ...ええ、言うのは。

今は英語の勉強は一昔前より圧倒的に簡単です。 ネットで良質なネイティブの英語コンテンツ(TEDとかCNNとか)は無料で山ほど手に入りますし、英単語もスマホアプリ化されて学習がかなり効率化されてますし、Skype英会話で英会話だって格安で簡単に始めれます。

また、効果的な勉強の仕方も共有されていて、例えばTOEICとかも英語上達完全マップとかに書いてある事を丁寧に実践すれば確実に上がります。

実際、私や知り合いが英語のスコアを上げた勉強法もこのサイトに書いてある事かその延長法ですしね。

http://mutuno.o.oo7.jp/mutuno.o.oo7.jp

でも、英語学習はトレーニングです。タフなタスクなんです。強いモチベーションが必要です。ともすれば英語を嫌いになってしまいます。 もちろん私も勉強は嫌いです。なので、英語を嫌いにならないために自分の好きなものと組み合わせることにしました。そうだ、萌えよう、と。

萌え + 英語教材を使ってみる

まずは王道というか初歩。教材編です。

萌えを売りにした英語教材っていくつかありますよね? 例えば「もえたん」はその走りであり代表例です。

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

もえたん新装版
価格:1234円(税込、送料無料) (2016/12/19時点)


英語を勉強するには単語だけじゃなくて文法も必要です。中高時代にやったはずですが過去分詞とかみんな忘れましたよね? もえたんサブリーダーはそんなあなたに最適な本です。

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

もえたんサブリーダー
価格:1543円(税込、送料無料) (2016/12/19時点)


もえたんの良いところは単に表紙が萌え萌えしてるだけじゃなくて、オタクならくすりっと笑えるその文章にあります。

コンテンツ自体にアニメネタを散りばめたのだと下記あたりもお勧めです。 英単語だけじゃなく英文法の解説やハルヒのやつみたいに小説仕立てになってるのもあるので、 ある程度長文が載ってるのもあるので精読->多読/速読と重ねて英語を読み慣れる教材としても使えたりするかもです。

直接的に既存のアニメと絡めてない教材としては下記の2つがお勧めです。


中学生の時の英語の教科書はなんでしたか? 私はNEW HORIZONです。

グリーン先生やパウロ・シルバー。ユミやケンが出てくる奴ですね。タイムマシンで未来に行ったりもしましたね。

「ミライ系NEW HORIZON」は、そんなNEW HORIZONから大人になったユミやケン、ケンのアメリカでの友達のルーシーを交えたSchool Daysもとい三角関係をラノベ仕立てでにした例文で進む英語教材です。

かなり読みやすいのですし、リスニングCDも付いてるのでお勧めです。ルーシーの声がかわいいので。とりあえずケンがいつか刺されると思う。音読やリスニング教材としても良いです。


TOEICテストにでる単600語」の方は一見硬派なタイトルで、中身もたまにイラストに女の子が載ってるだけで例文も良くも悪くも普通です。むしろ普通のTOEIC本。

ただ、リスニングCDがすごい。すみっぺが日本語訳を話してくれます。

リスニングの疲れをすみっぺの声で癒されるという良いサイクルが出来ています。

割り切って英語はネイティブがしゃべってるのも良いですね。

ちなみに割とTOEIC界隈で有名な人が書いていて本当に超頻出単語が載ってるので普通に教材として出来が良い。

しかし、ロシア語の教材じゃないがいいんだろうか...

本以外だと、「鬼桃語り」というスマホアプリもあります。

www.onimomogatari.com

英単語がメインで正直、iKnowmikanに比べたら学習効率は落ちると思いますが、ふつうにソシャゲーみたいな感じなので息抜きにやるには最適ですね。

MANGAを読もう!

どんなに親しみやすくても「教科書はなーっ」てそんなあなた。うん。分かる。

なので、普通にMANGAを読みましょう。マンガじゃないですよMANGAです.つまり、英訳版ですね。 昔は、大きな書店に行かないと手に入りませんでしたが、今はKindleKobo、それにBookWalkerで簡単に手に入ります。 一番簡単なのは専門サイトもあるBookWalkerですね。Kindleでは最近日本からは一部の本が買えないように制約が入ったみたいです。

global.bookwalker.jp

ちなみに、私は最近はUQ HolderとかMushoku Tensei読んでます。

基本的にはローマ字やカタカナをそのまま英単語にすれば良いのですが、 「Is It Wrong to Try to Pick Up Girls in a Dungeon?(ダンジョンに出会いを求めるのはまちがっているだろうか?)」なんかはタイトルがちゃんと英訳されてるので、 日本人からすると逆に探しづらいでしょうから絵から頑張りましょう。

NOWAY(そんなのってないよ、馬鹿な、まじ?)とかDammit(ちくしょう)とか覚えておけば、あとは絵を見て何となくわかります。 絵が相当に理解を助けてくれるので英文をスムーズに読む、という習慣をつけるには悪く無い気はしています。

「Shinmei school Secret Technique!(神鳴流奥義!)」とか「Spirit Circuits(精霊回廊)」とか「Magical Girl(魔法少女)」とかいろんな語彙が増えます! TOEICにも英検にも出ることは無いでしょうけど。。。

ちなみにラノベの英語版もありますが、読むのに結構パワーを使うので最初はMANGAから始めたほうが気軽で良いと思います。

Animeを視よう

マンガよりアニメが良い! という人もいるでしょう。

じゃあ、アニメを見ましょう。いわゆる北米版アニメというやつですね。

去年までなら英語版のNetflixやHuluで簡単に見れたんですが、最近は規制が厳しくなったので日本からNetflixを見るのは難しそうです。

かといって、日本版のNetflixには英語版はほとんど登録されてないので、今後どうするかは難しいところ。

ちなみに、英語版のアニメを見るにあたって一番覚えておくべきことはDub/Dubbed(音声吹替え)とSub/Subbed(字幕)の違いです。

英語の勉強として使いたいならDubの方が断然いいですね。

また、Dubで字幕を付けることも当然可能なんですが、なぜか「言ってる事」と「書いてある事」が結構違うのが問題。

瀬戸の花嫁とかは結構ひどくて、主人公の呼び方が音声と字幕で異なっていたので、いっそのこと英語だけ聞いた方が分かりやすい、というケースもありました。

日本製じゃなくてRWBYみたいな海外製もあります。まあ、これはアニメというよりMMD動画見てる気分になりますがw

www.youtube.com

注意点として私を含めてほとんどの人が英語でAnimeを視てもリスニングというよりヒアリングレベルになることが多いでしょうから、慣れるまで息抜き以上の意味はないです。

でも、普通に視てて楽しめますし、ご飯食べながらでも良いし、自分のまだ見てないアニメを積極的に見る事でモチベーションにもなりやすいので「英語を嫌いにならない」って目的には一番あってるかもですね。

一応、英語のイントネーションや言い回し、音の強弱に慣れるって効果は多少はある気がします。

まどマギは英語版を何度も見たので 「It makes no sense at all!(分けが分からないよ)」とか明日から使える英語を覚えることもできました!

www.nicovideo.jp

ラブライブは英語版しか見てないので、たまにニコ動とかで見つけて関西弁でしゃべられると「こんなしゃべり方だったの!?」とビビりますが、それもまた面白い体験ですね。

ちなみに、ガチでやりたい人はWelcome to Anime Transcripts@アニメで英語とか使いながら反復練習するのが良いと思います。

よろしい、ならばゲームだ!

ゲーム派のあなたにも朗報です。Steam使えば結構英語版でゲームを楽しめるんです。

閃乱カグラ」や「シャドウバース」のようなゲームを英語テキストでやるもよし、 「CLANNAD」や「ひぐらしのなく頃に」「グリザイアの果実」「Shuffle!」なんかの往年のギャルゲーもあります。

なんか最近、Steamで出すのが流行ってるみたいなので、私が名前知らないだけで最近のゲームもある気はします。

CLANNAD」とか普通に日本語でもクリアするのにGWを使った気がしますが、英語版にクリアした暁には人生について英語で語れるようになってるんじゃないかなー。

store.steampowered.com

日本語で普通にやれるゲームだと英語でわざわざするモチベーション無い人もいるでしょう。

一応、Steam専用として最初から英語で作られている「Sakura Spirit」とか「Gaokao.Love.100Days」とか「Go! Go! Nippon! ~My First Trip to Japan~」もあります。

探せば他にもたくさんありそう。特に「Sakura Spirit」は日本をリスペクトした海外製ギャルゲーということでも有名ですね。続編というか同じメーカーからのSakuraシリーズは結構他にも出ています。

store.steampowered.com

まとめ

英語に萌える方法、いくつか紹介してみましたが如何でしたでしょうか?

英語の勉強は大変ですが、何事も息抜きを入れることでもうちょっとだけ頑張れるかな、と思っています。

個人的には海外発の萌えコンテンツに興味があるので、誰か見つけたらコメントやTwitterで教えてください。

さて、みなさんモチベーション管理の準備はできましたか? ツラくなったらMANGAやANIMEを見る準備はOK?

では、英語上達完全マップを見ながらTOEICの公式問題集と格闘する日々に戻りましょう。

ふつうのユニットテストのための7つのルール

最近、久しぶりにコードレビューをすることが増えたのですが、UnitTestのコードを見るとヒドイ部分が多く残念な気持ちになることもあります。

原因のひとつとして、プロダクトコードと違いテストの書き方をあまり書き方を明文化してなかったのが悪かったなと思い、とりあえず明文化してみました。

今回は、命名規則とかそのレベルまではいかず「ユニットテストかくあるべし」ってところまでをまとめます。正直、これ守ってくれたらあとは好みの世界もあるしね。

追記: テクニカルな部分も最低限ですがQiitaに記載しました。

qiita.com

追記: もうちょっと大上段の規約に関してもまとめてみました。

koduki.hatenablog.com

前提

ここではユニットテストを関数レベルのテストをJUnitのような自動テストツールで取り扱う場合に限定します。 また、Mavenでビルド時は常にテストを回すことを想定しているので、それを踏まえたルールだと思ってください。

ルール

ポータビリティを大事にする

CIサーバや他人のPCで動かないテストコードを書いてはいけません。他所で動かないコードは不要では無く害悪です。 後述のルールでも具体的に触れていきますが、まずこの大前提を忘れないでください。

プロジェクト配下のディレクトリのみを使う

本番環境の「/var/hogedata」や「D:\hogedata」みたいなパスを前提にしたテストを書いてはいけません。 gitから落としたら即座に利用できるようにsrcまたはtarget配下を前提として相対パスでテストデータの配置やファイル入出力を行ってください。

DBやネットワークといった外部環境への依存を無くす

日付やDBやネットワーク(WebAPIとか)といったものに依存するコードをユニットテストに書くべきではありません。ユニットテストはあくまでロジックの検証にとどめるためにMockやその他テストダブルを活用してください。 ネットワークの場合はBetamax、それ以外の場合はJMockit等を使うこともできます。 DIコンテナやフィールドをパッケージレベルにするとで依存性を注入できるようにするとなお良いです。

SQLそのものをテストしたい場合等の重たいテストはIntegration Testとして、mavenのテストフェーズではなくintegration-testフェーズ等で実行してください。

繰り返し実行できるように作る

上記、2つのルールと被るところもありますが、手動手順無く繰り返し実行できるように作る必要があります。 環境の初期化と後始末を含めてすべてをテスト内で表現してください。setUpとtearDownで初期化とクリーンアップを適切に実施してください

標準出力にログを出さない

printlnや各種Logger等でユニットテストのために標準出力にログを出してはいけません。テストの結果は人間が目視で確認するのではなく、すべてコード上のアサーションに表れているべきです。 結果としてユニットテスト向けに人間が見るためのログが出ることはノイズにしかならないので、原則出力するべきではありません。 特に「エラーが正常に出ることを確認する場合」にprintStacktraceをするのはログが汚染されて本当に困るのでやめてください。本当のビルドエラーを追うのが困難になります。

とはいえ、ユニットテストのデバックのためにログを出したいケースもあると思いますので、その場合は一時的に書いてちゃんと消すか、traceレベルのログを使ってください。

ひとつのテストケースにはひとつの観点しか検証しない

一つのテストケースでは一つの観点でしか検証をしてはいけません。テストがこけたときに原因の切り分けが出来なくなるからです。 手動で実行してる分けではないので、テストケースの圧縮を過度にする必要はありません。

もちろん、同じ観点でのパラメータ化テストや、一つの検証観点で複数の検証項目がある(例えばBeanの各プロパティをチェックとか)場合にassertをいくつも書くのは問題ないです。

問題なのはテストXを実行したときに「ロジックAの動作」と「ロジックBの動作」を同時に検証することです。たとえ、AとBが依存してても個別のテストケースに落とすべきです。

ユニットテストを見て何をしてるか分かるように書く

稀にユニットテストの中が「test001」から「test010」まで並んでいて、なにを検証してるのかが別で作られてるExcelのテスト仕様書をみないとサッパリわからないUTがあります。 テストケースはふるまいを確認するための重要なコードなので、きちんと名称等にも気を使って書くべきです。

日本語圏のエンジニアが中心ならテストケース名を日本語で書くのもありでしょうし、せめてコメントで記載されてるだけでもずいぶん違います。最悪でもそのテスト仕様書の場所をコード内に書いてください。

BDDテストツールを使えばそれがベストかもしれませんが、そのあたりは本題から外れるので割愛。

番外ルール

「-Dmaven.test.skip=true」ダメ、ゼッタイ!

ちょっと粒度が違うので番外ルールですが、気軽に「-Dmaven.test.skip=true」を使うのはダメダメです。

これは「CI上ですでにいろんなテストがパスしたことを確認したのちにリリース担当者がビルドするとき」とか、結構特殊なケースのみで使うべきものです。

「あれ? なんかビルド失敗する。テストか、とりあえずskipしよう」みたいな事考えだすと後からひどい目にあいます。

CI使ってもテストがこけるのは分かるようになりますが、例えば標準出力の汚染とかビルド時間の増加とかは分かんないので、みんなが日々ビルドしてることが大事ですね。

テストとコンパイルとパッケージを含めてこそのビルドです。

まとめ

さて、いくつかまとめてみましたが、あくまで個人的なポリシーなので異論については大いに議論したいなと思います。

このあたりを整備した後はもっと具体的な命名規則とかテストの種別によるJUnitや各テストツールの具体的な使い方をまとめた資料が必要になってる来ると思いますが、テクニカルなところは結構世の中にも良い資料がたくさんある気がするのでそっちにお任せ。

またMavenを前提に考えてますが、今ならDockerがローカルにもCI環境にもあることを前提にすれば、また違った考え方は出来そうですね。

それではHappy Hacking!

自動テスト関係のメモ

そのうちちゃんと調べたいので忘れないようにメモ

EvoSuite

github.com

JUnitのテストケースの自動生成.

[シンボリック実行を活用した 網羅的テストケース生成 - Fujitsu]

シンボリック実行に入門しようとした

ntddk.github.io

用語とか基本知識の解説

coq-chick-blog

github.com

証明支援システムCoqで作られたブログ。Webアプリの証明。

gitの良さは未だに分からないがPullRequestの良さはちょっとだけ分かるぞい

スマートニュース見てたらこんな記事が上がってました。

crapp.hatenablog.com

まあ、gitの良いところはそれなりにありますがローカルコミットを上手に使えるようになるまでの壁はとても高いですよね。

正直言えば私もrebaseとかなるべく打ちたくないし、使いこなせてるとは言い難い。

とはいえPR(本文中はマージリクエスト)がレビューを強制するので良くないとか、trunkに直接コミットすれば良くないとかはどうなん? と思ったり。

そもそも個人的にはSVNとgitで運用方式がさほど変わるとは思えないのですよ。実際変えなかったし。

というわけで、私が使ってるコード管理方式について語りたいと思います。タイトルはちょっと釣り... というかぞいぞい言いたかっただけです!

そもそもSVNでどう運用していたか?

たぶん、多くのサービスがそうであるようにSVNからGitに移行しました。もっと言うとさらに昔はCSVでした。

それも、色々な理由でSVNから短期間でgitの運用らしくないところもありますが、今は当時無理やりgit-flowとか入れなくて良かったなぁとは思ってます。

じゃあ、そもそもSVNでどんな運用してたのよ? という話になりますがおおむね下記のような運用でした。

  1. trunkは常に本番環境と一致。リリース時にはタグを打つ
  2. 開発時にはプロジェクト毎にtrunkから開発ブランチを作る。これが同時並行で大量にできる
  3. 検証環境向けのブランチに開発ブランチをマージしてテストする。検証期間/環境の都合でリリース日の異なる複数のプロジェクトがマージされる事がある
  4. 3の前後でtrunkと開発ブランチとの差分をとってReviewBoardとかでレビューする
  5. 3,4の完了したら開発ブランチをtrunkにマージ。タグ打ってリリース

f:id:pascal256:20161004032717p:plain

実のところ結果としてGitHub Flowに結構近い運用だと思っています。違うところは3の検証ブランチでしょうけど、検証ブランチ自体はどこにもマージされないので大差は無いんじゃないかと。 まあ、この手のベストプラクティスは似通ってくるものなので不思議ではないですね。

なんで移行したのか?

移行した理由は2つあります。一つはSVNがあまりにとろく、特にマージやDiffが地獄のような重さでした。普通に数分から十数分オーダー。

これはおそらく大量のブランチを運用してたり、用意されていたインフラと管理していたリポジトリ規模がアンマッチだったことがあります。

当時の私はレビューアーとライブラリアンも担当してたので、gitに移行前からsvn-gitとかを使ってローカルリポジトリを運用してました。パフォーマンスマジ大事。

もう1点はPRですね。会社で共通基盤としてStashを導入することは知ってたので、上記のパフォーマンスの理由もあって協力に推進しました。

Gitでどのように運用しているのか?

では、本題のGitでの運用方式です。正直、パフォーマンスがダメダメなだけで運用プロセスには大きな不満があった分けではないので、ほぼそのまま移行しました。

  1. masterは常に本番環境と一致。リリース時にはタグを打つ
  2. 開発時にはプロジェクト毎にmasterから開発ブランチを作る。これが同時並行で大量にできる
  3. 検証環境向けのブランチに開発ブランチをマージしてテストする。検証期間/環境の都合でリリース日の異なる複数のプロジェクトがマージされる事がある
  4. 3の前後でmasterと開発ブランチとのPRでレビューする
  5. 3,4の完了したらPRをマージしてmasterにマージ。タグ打ってリリース

f:id:pascal256:20161004032835p:plain

外部システムのReviewBoardがPRになり、マージ依頼と統合されました。なにこれ便利すぎる! と狂喜乱舞したのは私です。

それ以外は、まったくと言って良いほど同一プロセスです。gitの操作が独特だったり複雑ってのもTortoiseSVNからTortoiseGitに変わっただけなので、あまり大きな変化はありません。

まあ「Pushを忘れるな!」と徹底するくらいですかね。rebaseでコミットログを綺麗にしようとすると、ドキドキする運用がいっぱい待ってますが「そんなことしなくて良いんです」。

確かに残念なログは入り込みますしが、良くわかってないメンバーが使ってリポジトリがぶっ壊されるよりはマシです。

別に、コミットログが多少汚れてても、リリースのタグだけ適切に管理できてればそんなに困りません。clone/checkout/pull/merge/commit/pushくらい使えれば十分ですね。

なので、これ以外の操作をするときは権限を与えた特定メンバーに依頼しろという運用にしています。ちょっと窮屈だけど、窮屈だと思える程度にスキルがある人には権限与えれば良いですしね。

で、基本的にこれで運用してましたが、いきなり5の手順でmasterに取り込んでリリースをしてましたが、切り戻しが大変というリスクがありました。

特に、一日に何度もリリースする時に朝のリリースがこけると午後のリリースの準備がパーになるのでツラい。

なので、現在はリリースブランチを作って下記のように運用しています。

  1. masterは常に本番環境と一致。リリース時にはタグを打つ
  2. 開発時にはプロジェクト毎にmasterから開発ブランチを作る。これが同時並行で大量にできる
  3. 検証環境向けのブランチに開発ブランチをマージしてテストする。検証期間/環境の都合でリリース日の異なる複数のプロジェクトがマージされる事がある
  4. 3の前後でmasterと開発ブランチとのPRでレビューする
  5. 3,4の完了したらmasterからリリースブランチを作成して開発ブランチを取り込む。3のPRは破棄。
  6. リリースブランチをリリース。無事リリースされたらmasterにマージしてタグを打つ

f:id:pascal256:20161004032842p:plain

この手順にすることで、リリース失敗時の切り戻しが簡単になる上に、リリース前にリリースブランチをリグレッションテストできるので品質面でも貢献できました。

ちなみにこの改良版の手順も含めてSVNでできないのはPRくらいでしょう。これもReviewBoardとかの外部ツールで代替はできますが。

PRによるレビューはなぜ重要なのか?

元記事ではさんざん言われてるPRによるコードレビューだけど、これは超重要だと思っています。「あなたがgitに移行するべきたった一つの理由」とか言うそれっぽい記事のタイトルにできそなほどに。

重要な理由は2点あります。

1. 保守性の担保

元記事では「採用ミスの尻ぬぐいだ!」と言わんばかりのコードレビューですが、確かに読んでバグ見つけるよりは動かして見つけた方がずっと早いし合理的です。

が、コードレビューはバグ発見より可読性や設計レベルの保守性を主にチェックする行為だと考えています。コードは読み物なので第三者が読んで読みづらいのはダメです。

これは私やおそらく元記事の方を含むほとんどのエンジニアに必要な行為で、当然ですが自分より優秀な人が書いたコードのレビュー指摘なんていくらでもしたことがあります。

静的解析で基本的な部分はかなり潰れるんですが、設計レベルに由来するところは人が見ないと分からないですがねー。

一応、高いスキルを持ったエンジニアがお互いのコンテキストを良く理解しあった上で開発すればレビューとかいらない気がしますが、 そんな事例1ケースしか私は聞いたことが無いのと、それこそハイスキルな行為ですね。

2. 適切なマージがされるかの確認

これはPR最大の利点ですね。なんとgitはPR出た差分の通りにマージされるんです! ライブラリアン的な作業をしないと気づきづらいかもしれませんが、マージってのは「コンフリクトもせずに開発者の意図とは違うマージになる」可能性があり得るんです 。 gitはsvnよりずいぶんマシとはいえ、しょせんテキストベースのマージですからね。同じコードの一番上と一番したに同じメソッドを追加しても追加したら両方正しく取り込まれますけど、コンパイルエラーになりますよね?

これを防ぐにはSemanticMergeみたいなもう少しインテリジェンスなツールを使う必要があります。

通常は同じ行を修正してれば正しくコンフリクトしますが、コンフリクトの解決を適当にされると稀に「マージの時系列」や「同じ行としての判定」が狂う可能性があります。

この場合、何が怖いってSVNとかの場合は「Diffツールで見た結果と実際のマージ結果が異なる可能性がある」ってことです。せっかくレビューしたのにマージ結果が異なるとかツラい。

そのためリリース時のマージではマージした後に想定したマージ内容になってるかを差分確認という二度手間になっていました。

PRであれば、そもそもマージ申請なので見た目の差分通りに取り込まれるので、初回のレビューしっかりやるだけで良いので簡単ですし、安心感がありますね!

GitではなくSVNに回帰するべきなのか?

正直、管理をしない側がGitとSVNでたいそうな差があるとは思えません。

プロジェクト規模や体制にもよるでしょうが50%から80%くらいの人はrabaseがどうの以前にlogコマンドすら打たないんじゃないかな?

なので、管理者/ヘビーユーザに都合が良いGitから回帰するメリットは特に無いのだけど、全員がrebaseを使うような複雑な運用プロセスはやめたほうが良い気がしますね。

少数精鋭チームなら問題ないかもだけど、大半が初心者なら入れるメリットのがデメリットを上回らない気がします。

あと、これは私が「システムの整合性を保つ唯一の機械的な方法はリポジトリである」という単一リポジトリ教に入ってるせいもありますが、

SVNのようにディレクトリ単位で落とせてもいいんじゃないかなー、とは思ったり。あとshallow cloneにcommitできるとか。

正直、10GB級の巨大リポジトリを運用しようとするとcloneがHTTP Proxyに切断されるとか、サーバの方でハングするとかツラい事象が...

その辺を考慮したツールが欲しいなぁ。

余談

>コードレビュー導入は終局的には「コードはできるだけ書かない」という境地に至る。

本題とは本当に関係ないのだけど、元記事の人と意見が真逆で面白かったのでピックアップ。

「コードはできるだけ書かない」はプログラマーが目指すべき一つの境地だと思ってます。ここだけの秘密ですがコードを書くとバグが発生する可能性が上がるんですよ?

まとめ

元記事で言う「中規模以上のプロジェクトのリリースを本格的に管理する側」を経験した人間なので、ちょっとカウンター記事を書いてみました。

正直、10個も20個もあるそんなに短くないプロジェクトを並行運用するのをみんなどうやってるんだろう? という疑問をずっと持ってたので、 とりあえず自分の現状を公開してあわよくばコメントをもらおうという算段もあったります。

というか、そういうツラい運用したくないからリリーススケジュールをシリアライズして並行稼働開発をしないのが正しい組織運用かもしれないデス。

それでは、Happy Hacking!

技術的負債はリボルビング払いで返そう!

qiita.com

という記事がTwitterに上がってたので見てみましたが、大変共感できるものでした。

システム開発をしていれば技術的負債はつきものです。特にサービス運営をしていれば、「たとえ借金をしてでも今出すべき!」ってタイミングは良くあります。

技術的負債はあくまで価値を生む資産であって、有用なものなのです。返済しないといけないのと利子が付くだけで....

で、元記事の中で、「技術的負債を大きく返すパターン」「技術的負債を小さく返すパターン」が書かれていますが、これって実際の金銭的負債の考え方で言えばリボ払いですよね!

というわけで、今回は技術的負債を実際のクレジットカードの返済方式になぞらえて返し方を考えてみました。

主なクレジットカードの支払い方式

さて、なぞらえるからには前提の説明が必要でしょう。絵心無いですが簡単なイラストにしてみました。

f:id:pascal256:20160927022819p:plain

大別すると以下の三つです。

  • 一括払い : 利用日の翌月払いです。クレジットカードだと利子かかりません!
  • ボーナス払い : ボーナス月にまとめて払う方式です。特定月しか支払わなくて良いのがポイント。
  • リボ払い : 毎月決められた金額だけ支払う。ご利用は計画的に。

本当は他にも分割払いとかもありますが、正直技術的負債を分割払いで考えることは無いと思うので割愛。

技術的負債における支払い方式

さて、それではそれぞれの支払い方式で技術的負債を返済する場合を考えてみます。

一括払い

利用日の翌月とありますが、言ってしまえばプロジェクトリリース直後とかですかね。

リリース当日には無理してでも間に合わせる。出してから直せば良い。まあ、良く「考える」ケースですねー。

リリース直後に対応するのであれば、保守性の低下という手数料の支払いもゼロなので、悪く無い方式です。

一方で、それなりの支払い能力、すなわち余剰生産力が必要です。なにしろリファクタリングとか直接的には利益を生みづらい作業をするので、それをしても問題がない組織的な余裕が必要になってきます。

また、プロジェクト内で技術的負債が消化できないレベルのリリースの直後とか、どうせトラブるので人的リソースは枯渇し技術的負債は滞納されます。チーン

ボーナス払い

会社にもよりますが、繁忙期とそうでない時期があります。

そうでない月をボーナス月としましょう。この間に、たまった技術的負債を返すのです!

クレジットカードの支払い方式のイラストを見てわかる通り特定月以外は請求されないので、その分の生産力をトラブル対応や新たな機能の開発に充てることが出来るので、リソースを効果的に使いシステムやサービスの価値を高めることが出来ます。

でも、ちょっと待ってください! 本当にボーナスは支払われるのでしょうか?

年に2回しかないボーナス月です。それまでにたまった負債はとても一人が片手間に返せるものではありません。 私は社会人としてSEになって7年くらいになりますが、プロジェクトの切れ目なんて見たことありません。ましてやチーム単位で。

そう、多くの会社は(技術的負債返却という意味では)ボーナス月の存在しないブラック企業なので、技術的負債は滞納されます。チーン

リボ払い

さて、最後に悪名高きリボ払いです。

これは元金にかかわらず毎月決められた額だけ支払う方式です。これをシステム開発で言うなら一定のコストを常にリファクタリング向けに許容するという事になりますね。

人的リソースを消費しますが、そもそも支払い能力すなわち組織としてプロジェクト影響が許容できる範囲を決めて払いづづければいいのです。

カードでの支払い方式のイラストでも、固定の小さな額だけ払えば良いので負担はちいさそうですよね?

自らが決めてコントロールできるので、技術的負債を返済し続けることが出来ます。そう、つまり滞納しないんです! グレート

ただ、決めた量以上が減らないため、借金する速度の方が返済速度より早ければ元金は減るどころか増え続け、無限に支払いをし続けることになります。

でも、だから何だっていうんでしょうか? サービスが死ぬまで技術的負債を払い続ける覚悟をすれば良いだけじゃないですか! 死んだら払わなくて良いのです!

f:id:pascal256:20160927030701j:plain

まあ、あんまり元金増えすぎると利子(保守性の低下)が溜まり過ぎて、死ぬんですけどね!

でも、多少は減り続けるだけ、他の方式よりましだとおもいませんか?

まとめ

さて、あおりっぽくタイトルは「技術的負債はリボルビング払いで返そう!」としましたが、他よりマシってだけで、これだけやればOKという方式でもないかなと思います。

実際には本当の金銭の負債と同様に支払い能力に余裕があるうちはプロジェクト期間内または直後の一括払いを前提として、 手元にキャッシュ(人的リソース)を残してほかの生産的な作業に充てたいときはリボ払い方式を採用しつつ、 ボーナス月が来たらおまとめ払いで元金を可能な限り減らすというのが現実的でしょう。

個人的には技術的負債はずっと付き合っていかなければならないものだと思っているので、計画的に支払い続けれるリボ払い方式を採用できる体制にしていきたいなと思っています。

まあ、カードのリボ払いは手数料高いからしたくないけどね!

それでは、Happy Hacking!

分散バッチフレームワークとしてのApache Spark

ヌラーボさんのGeeks Who Drinkで分散バッチフレームワークとしてのApache Sparkというタイトルで話させていただきました。 nulab.connpass.com

資料はこちらになります。 Apache Spark as Batch

最近、Sparkを触り始めたんですが、世の中の資料は機械学習やログ解析がほとんどで、普段作ってるようなジョブをあんまりどう書くかが議論されていません。 ただ、SparkのAPIScalaのコレクションAPI。つまり、map/reduce/filter/foreach/groupby等による普通の近代的なコレクション操作APIです。 なので、普通の業務バッチで長時間掛かってるはずやつにも適用できるはず、という観点でこの資料を作ってみました。

個人的にはSparkおよびHadoopシステムはバッチシステムとしての完成度というか作りこみが凄く、管理系の機能が豊富なのでそこまでビックなデータじゃなくても基盤として有用だと考えています。

また、今回はあまり触れてませんがJavaからもふつうに使うことが出来るので、ScalaエンジニアがいなくともJavaエンジニアだけで開発できることも大きなポイントですね。

アクティブアクティブでスケールアウトするバッチサーバを検討中なら多少オーバーヘッドがあることを加味してもありだと思いますね。 DAGの可視化と各処理の実行時間がわかるのはかなり便利だし。

ただ、新しいミドルの運用という別タスクが増えるので、このトレードオフがペイするかは要件等ですね。

ちなみに、他の発表でWebクリエイターボックスの@chibimanaさんがリモートワークについて話されてました。 リモートワークとは少し違いますが、離れた拠点と仕事することは多いので、なるほどなー、と感じることも多くてとても興味深い話しでした。

あと、LTされたKAGURAっていうソフトがかなり面白そうでした。 私も音楽センス0なので、そんな私でもそれっぽい演奏ができるんだろうか? という夢と、MIDIがつながるのでジェスチャーで色んなデバイスを触るためのUIとしても 使えるんじゃないかなー、とおもったり。というわけでbackingはしてみました。ワクワク

Geeks Who Drinkは勉強会というわけではなく、食べ飲みだべりメインでなんかあれば発表もする、というスタイルみたいですね。 これはこれで面白いので、機会があればまた行ってみたいなー、と思います。

それではHappy Hacking!

参考: