TECH PLAY

株式会社ラクス

株式会社ラクス の技術ブログ

953

こんにちは、takaramです。 メール配信サービス 配配メール / クルメル の開発チームでは昨年、 はいくる通信 と題し、メール配信に関する技術・ノウハウをご紹介しました。 今回はその続編として、 配信エラー解析 についてお話したいと思います。 配信エラー解析とは 配信エラー解析のしくみ 二種類のFromアドレス 配信エラーと到達率 まとめ 配信エラー解析とは 「自分の送ったメールが届かなかった」という経験はあるでしょうか?メールの送信に失敗する原因としては、例えば以下のようなものがあります。 メールアドレスが間違っている 相手の メールボックス が満杯になっている 相手に受信拒否されている サーバ間で通信に失敗した 特に メールマガジン などの一斉配信においては、配信エラーは珍しくありません。内容に興味がなくなった読者に受信拒否されたり、そもそも登録したアドレスが間違っていたりといったケースです。 エラー理由によって解決策は全く変わってくるため、メールが届かないとの問い合わせを読者から受けた際にはまず理由を把握する必要があります。また、配信エラーを放置し届かないメールを送り続けることはコストの無駄になってしまいます *1 。 そこで、我々の開発している配配メール/クルメルには 配信エラー解析 機能があります。 配配メールの配信エラー解析( 配配メールWebサイト より) 配信に失敗したアドレスとその理由がわかるほか、配信エラーが一定回数発生するとそのアドレスへの配信を自動で停止します。アドレス間違いなどの恒久的なエラーの場合は1回、メー ルボックス の容量オーバーなどの一時的なエラーの場合は3回の配信エラーで配信を停止します(回数は設定で変更可能)。 しかし、一斉に配信したうちのどのアドレスがなぜ配信エラーになったのか、どうやってわかるのでしょうか。 配信エラー解析のしくみ みなさんはこのようなメールを受け取ったことはありませんか? これは バウンスメール と呼ばれるもので、送信したメールが相手に届かなかったことを知らせるメールです。受信拒否などの場合は 送信先 サーバから、アドレスの@以降が間違っている、 送信先 サーバへの接続に失敗したなどの場合は送信元サーバからバウンスメールが送られます。 ではバウンスメールの宛先はどのアドレスかというと、もちろんメールのFrom(差出人)アドレスです。とはいっても、ここで言うFromアドレスは、みなさんが思い浮かべるものとは少し違っています。 二種類のFromアドレス メールの送受信の際、サーバやPCの間では以下のようなデータがやり取りされています。 Date: Mon, 9 Mar 2019 12:34:56 +0900 From: taro@example.com To: hanako@example.jp Subject: Test Mail こんにちは! 本文は「こんにちは!」の一行だけですが、件名や送信日時などが書かれた メールヘッダ が付け加えられています *2 。ここでFromに書かれているのが受信者が目にするFromアドレスで、 ヘッダFrom と呼ばれます。メルマガなら通常メールを作成した会社やブランドのアドレスになります。 一方、メールデータ(メールデータ+本文)を送信する際、送信元サーバはメールヘッダとは別に差出人と宛先のアドレスの情報を送信します。このFromアドレスを エンベロープ From といいます。ヘッダFromと違い、基本的にコンピュータ間の通信用にのみ使われるアドレスで、配配メールを使って送信したメールなら配配メールのサーバのアドレスになります。バウンスメールはこの エンベロープ From宛に送信されるのです。 メール送受信のイメージ 配配メールでは、一斉配信でも一通一通異なる エンベロープ Fromを利用していて、アドレスの中にメールIDや読者IDなどの情報が含まれています。そのため、受信したバウンスメールの宛先を見れば、誰が誰に送ったどのメールが配信エラーになったかがわかるのです。 ではエラー理由はなぜわかるかというと、バウンスメールの本文を解析しています。文面はバウンスメールを送信するサーバのソフトウェアによって異なりますが、そこに含まれるフレーズを元に判定をします。例えば「user unknown」というフレーズが含まれればアドレス間違い、「Rejected as spam 」が含まれれば受信拒否、といった形です。 配信エラーと到達率 ここまで配信エラー解析のしくみをご紹介しましたが、実はこの機能、 我々のサービスの質を守る ためにも重要なのです。 もし配信エラー解析機能がなく、利用者が配信エラーに気づかなければ、使われていないアドレスにもメールを送り続けることになります。これは 第1回の記事 で紹介した「 IPレピュテーション 」を下げる要因となります。 すなわち、受信サーバが配信サーバを「 適当なアドレスにメールを送りつけるスパムサーバ 」と認定し、メールを受け付けてくれなくなるのです。 メール配信サービスとしてメールをしっかりと届けるためにも、配信エラー解析は重要な機能なのです。 まとめ メール配信サービス 配配メール/クルメルの配信エラー解析のしくみ、ご理解いただけたでしょうか? 利用者が配信の状況を把握できるだけでなく、サービス全体の到達率を維持するためにも重要な機能となっているのです。 *1 : メール配信サービスの利用料金は、一般的に配信通数やアドレス登録数で決まります。 *2 : 実際は本文の 文字コード 、返信先アドレス、メッセージIDなどもっと多くの情報が書かれています。
こんにちは。 本日は ソフトウェアテスト の教科書 JSTQB の内容と実際に業務に反映した例をご紹介します JSTQB とは 日本における ソフトウェアテスト 技術資格認定の運営組織です。 ISTQB(International Software Testing Qualifications Board)という ソフトウェアテスト 技術者の国際的な資格認定団体がありますが、 JSTQB はその日本版にあたります。 いくつかテストに関する出版をされていますが、私が選んだ本は以下に掲載します。 ソフトウェアテスト教科書 JSTQB Foundation 第4版 シラバス2018対応 選んだ理由は下記の通りです。 ソフトウェアテスト を体系的に学べること 最新かつ網羅的なテスト技法を習得できること( シラバス 2018対応は2020年2月テストより実施) 資格試験の取得にもつながること テストの目的 そもそもテストの 目的 ってなんでしょうか。というところから本書では書かれています。 テスト期間、テスト 工数 (実施する時間)、メンバーのスキルレベル、開発担当者との関わり方などなど その条件によってもテストの 目的 は変わってきます。 要件を満たしている 妥当性の確認 ステークホルダー が判断できる情報提言 品質レベルのリスク低減 契約・法律・規約の検証 故障や欠陥を発見する 欠陥の作りこみを防ぐ 品質レベルの確認 評価 など、その目的は多岐にわたります。 製品を開発する上でもいくつかの観点がありますね。 機能追加の案件なんかは製品企画やお客様とお約束した要件を満たしているかチェックが欠かせません。 また、新しい機能を追加すればするほど、今まで当たり前のように動いていた機能は これからも当たり前のように動くことを保証しなければなりません。 言うのは簡単ですが、実際に実践するのは難しいです。 機能を追加すると思わぬところに影響を及ぼしたり、処理を追加しなければいけないところが漏れていたりと 大規模な製品ほど品質レベルを維持するのは難易度が高くなりますよね。 そんな難しい観点を網羅的にテストする一つのツールとして本書からヒントを得られればと思います。 ※実際の品質を保証するものではないので、利用状況に応じて善にも悪にもなるところは注意が必要です。 テストの7原則 目からウロコだったので、詳しくレポートします。 テストは欠陥がないことは示せない 確かにそうですね。 アプリケーションの ホワイトボックステスト をすべて網羅したとしても、 顧客が実際に動作させるOS/ブラウザの状況はすべて再現できるわけではありません。 どんなにテストしても「絶対に100%欠陥はありません!」ということを言い切るのは難しいですし、 正確な情報ではありません。 もちろんバグが限りなく0になるようにテストはすべきです。 全数テストは不可能 例えば、画面に文字を打てる入力欄があった時点で無理です。 ローマ字26文字×2(大文字、小文字)、ひらがなカタカナは濁音や半濁音を含まなくても50文字ずつ、漢字は・・・。 その組み合わせは実質無限であり、どこまでいっても全パターン網羅ではありません。 早期テストで時間とコストを節約 ソフトウェアテスト の特徴として、V字モデルがよく話に出ます。 要件定義に何か問題があった場合は、最も 下流 工程の システムテスト で見つかったり、 詳細設計や実装などの問題は 単体テスト を見つかったりと、 問題があったときに検知できるフェーズがV字のような形なので問われています。 テストにおけるコスト同じで、品質における問題が発見されるのが、 後の工程ほど上流工程に戻って修正するコストが多く発生します。 なるべく早期に問題を発見することでリリースまでの時間の節約につながります。 欠陥の偏在 テストにおける欠陥の8割はプログラムの2割部分に集中して存在する説があります。 見落とした観点と、見落としに関連する観点が依存しているからだと思いますが、 私の経験上も感覚が近いので、その通りかと思います。 殺虫剤の パラドックス 特定の虫に同じ殺虫剤を与え続けても、いずれ虫のほうが殺虫剤に対する免疫をつけるため、 どんどん効果が薄くなることを例にしています。 ソフトウェアテスト においても同様で、同一観点で何度テストしても問題の検知がし難いです。 テスターを変える、やり方を変える、観点を変えるなど何かしら前回のテストと差をつけて 取り組むことが必要です。 テストは状況次第 上述した目的から、テストの在り方が変わってきます。 24時間稼働のシステムであれば過負荷でもシステムダウンしないこと、 eコマースであれば外部に公開するのでセキュリティ面で問題ないか念入りにチェックします。 「バグゼロ」の落とし穴 ある観点ではバグがない状態でも、他の観点ではそうではないケースがあります。 入力欄が4桁しか入力できない問題を解決するために、5桁に変更しました。 「4桁しか入力できない」欠陥はなくなりますが、 代わりにデータベースの書き込み速度が遅くなる、といった新しい問題が発生しました。 その直し方が製品全体を見たときに本当に正しい形をよくよく考える必要があります テストの心理学 人それぞれ立場や理解が異なることから、協力体制を考えねばなりません。 心に刺さった一例を掲載します。 <一例> 開発担当者の心情として下記があげられます。 何度もテストしたから実装コードが正しいはずだ(確証バイアス) テスト担当者よりも製品の仕様をよく知っている(指摘を受けにくい) こうなってしまうと「開発担当者 vs テスト担当者」の対決構図になってしまいます。 「良い品質の製品を納品する」という共通認識のもと、協力体制で行わなければなりません。 テストで発見した指摘は下記の効果があります 欠陥情報の把握 品質向上 開発担当者の スキルアップ コスト削減 お互いの信頼のために、開発担当者は否定的に反応した理由を、テスト担当者は理解する努力が必要です。 相互の認識の確認と、顧客の問題を解決することが目的であるという認識のもと 製品の製造を進めていくことが大事ですね。 カバレッジ 上述した全件テストが不可能という話がありましたが、その中でもなるべく網羅的に テストがすることが求められています。 カバレッジ とはテストケースを利用して特定のアイテムを実行したときの度合いを示した式になります。 デシジョンカバレッジ(%)= (テストにより実行した判定結果の数 / テスト対象の判定結果の合計数) × 100 これをどれだけあげられるかが欠陥が限りなく0に近い製品を生めるかのポイントになります。 カバレッジ の実践 実際にある案件のテストケースレビューでこの観点を取り上げる場面がありました。 伝票のヘッダーに対して明細が1:2のテストをするとき、 「複数明細の伝票」という観点でテストケースが生成されていました。 しかしユーザーの操作は明細がいくつも作れるので、1:2だけのテストでは不十分です。 もちろんテストに対する 工数 も有限なので実施できるパターンはやはり限られます。 しかし カバレッジ を少しでもあげることは、欠陥の少ない製品に近づけるので 時間の許す限り、実践していくのが良いと判断し、メンバーに追加のテストを依頼しました。 テスト技法 一般的に紹介されていました。 個々の詳しい説明については割愛します。 ブラックボックステスト プログラム内部は参照せず、画面/ API などのUIから思いつく操作を実施する手法です。 ホワイトボックステスト  プログラム内部を参照し、分岐処理を網羅的に打鍵する手法です。 同値分割法  条件的に同じ判定になりうるパターンはグルーピングして一つのパターンとみなしてテストする手法です。  例: 6歳未満は無料 6歳から12歳以下は半額 13歳以上は定額 上記の条件であれば、「ありえない」「無料」「半額」「定額」の4つのパターンとみなしてテストします。 境界値分析  同値分割法の一種ですが、どの範囲で同値とみなすかを定めています。  例:20~34歳までの男性がアクセスするとM画面を表示する 2ポイント境界値分析法 3ポイント境界値分析法 デシジョンテーブル それぞれ;の因子を掛け合わせた観点をテストする手法です。 例: ある美術館の入館料は次の通りになっている   個人入館料 大人・高校生:2000円 中学生・小学生:1000円 幼児:600円 学校団体入館料 大人・高校生:1200円 中学生:720円 小学生:600円 幼児:360円   ※ただし、個人・団体を問わず県民の日は高校生以下無料 上記のケースだと全部で19ケース存在します。 ユースケース テスト ビジネスシナリオやシステムの使い方に基づいてテストケースを設計します。 結合テスト に近いです。 ユースケース 名、目的、アクター、事前条件、事後条件、基本フロー、代替フロー、例外フロー、備考など 実際に使われうるケースで要素を考えます。 状態遷移テスト その製品の操作状況によって実施するパターンを遷移していきます。 状態遷移テストの実践 応用して 経理 システムに反映すると下記のようになります。 実際に利用するとパターンが増えるので、より可視化が重要になります。 テストツール それぞれ紹介されていました。 実際の業務で利用されるものばかりです。 要求マネージメントツール  TestLink 欠陥マネージメントツール  Redmine , Bugzillia 構成管理ツール Git, Subversion 継続的 イテレーション ツール Jenkins レビューツール  Redmine 、 Trac 、ReviewBoard 静的解析ツール SpotBugs, Checkstyle テスト設計ツール PictMaster モデルベースドテストツール GraphWalker テスト実行ツール  Selenium , JUnit 要求 カバレッジ ツール OpenClover 性能テストツール  Jmeter 動的解析ツール Valgrind 数々の要素 上述したもの以外にもたくさんの要素がテストに関係しています。 経験ベースのテスト技法 これはエラー推測が重要になります。 アプリケーションの過去の動作状況 開発担当者が犯しやすい誤りの種類 他のアプリケーションで発生した故障 探索的テスト チェックベースドテスト マネージメント、レビューも良いテストを実現するために大きく左右します。 まとめ それぞれの状況に応じてベストプ ラク ティスは異なります。 テスト技法を用いて個々の状況に適したテストを選択できるかがポイントです。 おのおの限りがあるコストの中で重大な欠陥、故障を見つけることが必要になります。 そのために実行するテストの優先順位づけも重要です。 先人が行っていたテンプレートを鵜呑みにせず、テストケースの作成、 テストの実行時に 気づいた観点はすぐ実行することが 重大なシステム欠陥を防止する策になると思います。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
logy0704です。 今回は自分のコンテナ知識をアップデートするために調べたことを記事にしようと思います。 動作確認はDocker Desktop for Mac 2.1.0.5, Docker Engine 19.03.5で行なっています。 課題 解決策 結局どっち使えば良いの volume 名前付きvolumeと匿名volume -vと--mount まとめ 課題 基本的にコンテナを消すと中の状態を復元することはできません。 しかし、以下のようなケースでデータの永続化を行いたいことがあります。 データベースコンテナの状態を保存しておきたい。 別のコンテナにデータ移行したい。 解決策 コンテナのデータを永続化させる方法がdockerの機能として用意されています。 主な手段は次の二つです。 volume ホスト側のdocker管理 ディレクト リ以下をコンテナにマウントする。 bind mount ホスト側の ディレクト リをコンテナにマウントする。 結局どっち使えば良いの 公式ドキュメントではvolumeを推奨しています。 理由はいくつかありますが、代表的なものとしては、セキュリティ上の懸念があることが挙げられます。 bind mountの場合、コンテナからホスト側のdocker管理領域以外へのアクセスができるため、 コンテナへ侵入を許した際にホスト側にまで被害が拡大する可能性があります。 とはいえ、一部の ユースケース ではbind mountを使用したほうが望ましいケースもあります。 詳しくは公式ドキュメントを参照してください。 今回はvolumeについてもう少し見ていきます。 volume docker runコマンドに-v(--volume) or --mountを指定することで、volumeをマウントした状態のコンテナを作成することができます。 volume名とコンテナ側の ディレクト リを指定して実行してみます。 $ docker run -d --name sample -v my-vol:/app nginx:latest docker inspectコマンドでコンテナの情報を確認してみると、以下のようにvolumeがマウントされていることがわかります。 " Mounts " : [ { " Type " : " volume " , " Name " : " my-vol " , " Source " : " /var/lib/docker/volumes/my-vol/_data " , " Destination " : " /app " , " Driver " : " local " , " Mode " : " z " , " RW " : true , " Propagation " : "" } ] , docker volume lsコマンドで存在するボリュームの一覧を取得することができます。 $ docker volume ls DRIVER VOLUME NAME local my-vol コンテナ内にファイルを作成してから、コンテナを消してみます。 $ docker exec -it sample bash /# echo "hoge" > /app/hoge.txt $ docker rm -f sample $ docker volume ls DRIVER VOLUME NAME local my-vol コンテナが消えてもvolumeは消えていません。 再度、コンテナを作成し、先ほど作ったvolumeを指定してみます。 $ docker run -d --name sample -v my-vol:/app nginx:latest $ docker exec -it sample bash /# ls /app hoge.txt 先ほど作成したファイルを残すことに成功しました。 名前付きvolumeと匿名volume volumeには大きく次の2種類があります。 名前付きvolume その名の通り、名前を持ったvolumeです。先ほどのmy-volの部分が名前にあたります。 匿名volume 名前を指定しなかった場合に作られるvolumeです。docker側でユニークになるように ハッシュ値 の名前が振られます。 docker run -d --name sample2 -v /app nginx:latest " Mounts " : [ { " Type " : " volume " , " Name " : " a41506ad65ef324b213c6dd6cb246532a264193e8fe6fcda25829119817a0ec5 " , " Source " : " /var/lib/docker/volumes/a41506ad65ef324b213c6dd6cb246532a264193e8fe6fcda25829119817a0ec5/_data " , " Destination " : " /app " , " Driver " : " local " , " Mode " : "" , " RW " : true , " Propagation " : "" } ] , 名前付きvolumeのほうがなんのためのvolumeなのかわかりやすいため、基本的には名前を指定するほうが良いと思います。 -vと--mount volume作成には、-vと--mountの二つのオプションが使用できます。 厳密には挙動が異なる部分がありますが、ほとんど同じものです。 サンプルでは-vを使用しましたが、--mountのほうが新たに導入されたオプションで、直感的に記述できるため、こちらを使うのがおすすめです。 まとめ dockerコンテナのデータを永続化するにはvolumeを使う volumeを作成する際には名前をつけよう 使うオプションは--mountがおすすめ エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
こんにちは、新卒1年目のtakaramです。まもなく入社して丸一年となり、ほとんど経験のなかった SQL の力もついてきたと思っています。 しかし、パフォーマンス面も考慮した SQL となると、まだまだ知識が足りないと感じています。 特に、一対多の関連テーブルの一方を使って他方を絞り込む、といった SQL は、ネットを見てもEXISTSが速いという記事があったり相関サブクエリだから遅いという情報があったり……何が本当かよくわかりません。そこで、今回自分で調べてみることにしました。 なお、今回検証に用いたのは PostgreSQL 11.4 です。 検証 テスト用データ 1:2020年入社の社員がいる部署名を抽出 2:開発1課~9課の従業員を抽出 結論 検証 テスト用データ テスト用テーブルとして、従業員テーブル employees と部署テーブル departments を用意し、それぞれ5万件、1000件のレコードを挿入しました *1 。各テーブルはIDと名前のほか、従業員テーブルは所属部署IDと入社年を入れています。 これを使って2種類のデータを抽出する SQL を、それぞれIN, EXISTS, JOINの3パターンで作成し、 EXPLAIN ANALYZE で実行時間・コストを比較しました。 1:2020年入社の社員がいる部署名を抽出 まず、各パターンのクエリはこんな感じです。 -- INパターン SELECT name FROM departments WHERE id IN ( SELECT department_id FROM employees WHERE join_year = 2020 ); -- EXISTSパターン SELECT name FROM departments d WHERE EXISTS ( SELECT 1 FROM employees e WHERE e.department_id = d.id AND e.join_year = 2020 ); -- JOINパターン SELECT d.name FROM departments d INNER JOIN ( SELECT DISTINCT department_id FROM employees WHERE join_year = 2020 ) tmp ON tmp.department_id = d.id; それぞれの実行計画を出してみます。 IN QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- Hash Join (cost=963.88..994.63 rows=1000 width=12) (actual time=5.690..6.153 rows=720 loops=1) Hash Cond: (departments.id = employees.department_id) -> Seq Scan on departments (cost=0.00..17.00 rows=1000 width=16) (actual time=0.023..0.178 rows=1000 loops=1) -> Hash (cost=954.66..954.66 rows=737 width=4) (actual time=5.651..5.651 rows=720 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 34kB -> HashAggregate (cost=947.29..954.66 rows=737 width=4) (actual time=5.376..5.500 rows=720 loops=1) Group Key: employees.department_id -> Seq Scan on employees (cost=0.00..944.00 rows=1318 width=4) (actual time=0.014..5.045 rows=1253 loops=1) Filter: (join_year = 2020) Rows Removed by Filter: 48747 Planning Time: 0.614 ms Execution Time: 6.336 ms EXISTS QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- Hash Join (cost=963.88..994.63 rows=1000 width=12) (actual time=5.262..5.723 rows=720 loops=1) Hash Cond: (d.id = e.department_id) -> Seq Scan on departments d (cost=0.00..17.00 rows=1000 width=16) (actual time=0.006..0.171 rows=1000 loops=1) -> Hash (cost=954.66..954.66 rows=737 width=4) (actual time=5.237..5.237 rows=720 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 34kB -> HashAggregate (cost=947.29..954.66 rows=737 width=4) (actual time=4.957..5.084 rows=720 loops=1) Group Key: e.department_id -> Seq Scan on employees e (cost=0.00..944.00 rows=1318 width=4) (actual time=0.010..4.628 rows=1253 loops=1) Filter: (join_year = 2020) Rows Removed by Filter: 48747 Planning Time: 0.570 ms Execution Time: 5.902 ms JOIN QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- Hash Join (cost=971.25..990.88 rows=737 width=12) (actual time=7.757..8.241 rows=720 loops=1) Hash Cond: (d.id = employees.department_id) -> Seq Scan on departments d (cost=0.00..17.00 rows=1000 width=16) (actual time=0.009..0.174 rows=1000 loops=1) -> Hash (cost=962.03..962.03 rows=737 width=4) (actual time=7.739..7.740 rows=720 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 34kB -> HashAggregate (cost=947.29..954.66 rows=737 width=4) (actual time=4.406..7.568 rows=720 loops=1) Group Key: employees.department_id -> Seq Scan on employees (cost=0.00..944.00 rows=1318 width=4) (actual time=0.007..4.041 rows=1253 loops=1) Filter: (join_year = 2020) Rows Removed by Filter: 48747 Planning Time: 0.127 ms Execution Time: 8.359 ms 予想外だったのですが、この3パターン、 ほとんど同じ実行計画になりました !INとEXISTSは全く同じ、JOINもコストの数値が若干異なるだけです。 2:開発1課~9課の従業員を抽出 こちらの SQL は以下のようにしました。 -- INパターン SELECT name FROM employees WHERE department_id IN ( SELECT id FROM departments WHERE name LIKE ' 開発_課 ' ); -- EXISTSパターン SELECT name FROM employees e WHERE EXISTS ( SELECT 1 FROM departments d WHERE e.department_id = d.id AND name LIKE ' 開発_課 ' ); -- JOINパターン SELECT name FROM employees e INNER JOIN ( SELECT DISTINCT id FROM departments WHERE name LIKE ' 開発_課 ' ) tmp ON e.department_id = tmp.id; では実行計画を見てみます。 IN QUERY PLAN -------------------------------------------------------------------------------------------------------------------- Hash Join (cost=19.51..970.32 rows=50 width=11) (actual time=0.283..16.909 rows=450 loops=1) Hash Cond: (employees.department_id = departments.id) -> Seq Scan on employees (cost=0.00..819.00 rows=50000 width=15) (actual time=0.007..7.910 rows=50000 loops=1) -> Hash (cost=19.50..19.50 rows=1 width=4) (actual time=0.104..0.105 rows=9 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Seq Scan on departments (cost=0.00..19.50 rows=1 width=4) (actual time=0.051..0.100 rows=9 loops=1) Filter: (name ~~ '開発_課'::text) Rows Removed by Filter: 991 Planning Time: 0.160 ms Execution Time: 16.985 ms EXISTS QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- Hash Join (cost=19.51..970.32 rows=50 width=11) (actual time=0.276..16.525 rows=450 loops=1) Hash Cond: (e.department_id = d.id) -> Seq Scan on employees e (cost=0.00..819.00 rows=50000 width=15) (actual time=0.006..7.664 rows=50000 loops=1) -> Hash (cost=19.50..19.50 rows=1 width=4) (actual time=0.103..0.104 rows=9 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Seq Scan on departments d (cost=0.00..19.50 rows=1 width=4) (actual time=0.050..0.099 rows=9 loops=1) Filter: (name ~~ '開発_課'::text) Rows Removed by Filter: 991 Planning Time: 0.161 ms Execution Time: 16.608 ms JOIN QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ Hash Join (cost=19.54..970.35 rows=50 width=11) (actual time=0.392..16.747 rows=450 loops=1) Hash Cond: (e.department_id = departments.id) -> Seq Scan on employees e (cost=0.00..819.00 rows=50000 width=15) (actual time=0.009..7.770 rows=50000 loops=1) -> Hash (cost=19.53..19.53 rows=1 width=4) (actual time=0.161..0.161 rows=9 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Unique (cost=19.51..19.52 rows=1 width=4) (actual time=0.149..0.156 rows=9 loops=1) -> Sort (cost=19.51..19.52 rows=1 width=4) (actual time=0.148..0.150 rows=9 loops=1) Sort Key: departments.id Sort Method: quicksort Memory: 25kB -> Seq Scan on departments (cost=0.00..19.50 rows=1 width=4) (actual time=0.054..0.115 rows=9 loops=1) Filter: (name ~~ '開発_課'::text) Rows Removed by Filter: 991 Planning Time: 0.123 ms Execution Time: 16.836 ms こちらもパターン1同様、INとEXISTSは全く同じ実行計画です。JOINの方はDISTINCTのUnique, Sortが入っていますが、コストはわずかです。 結論 単純なクエリではIN, EXISTS, JOINとも、おおむね同様の実行計画となることがわかりました。 オプティマ イザが思った以上に賢かったですね! より複雑なクエリや、インデックスの有無によっては変わってくるかもしれませんが、この程度のシンプルなクエリならあまりパフォーマンスを気にする必要はないと考えていいでしょう。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com *1 : 参考までに、利用した SQL は こちら です
はじめに こんにちは。新卒2年目のEngawaです。 アプリ開発 を行うチームに配属された際に Android アプリの開発の入門とした簡単なアプリの開発をした時の所感を書こうと思います。 学習で参考にしたサイトはこちらになります 開発環境のインストール方法から エミュレーター の作成方法まで詳しく書かれているので、 Android Studio のバージョンで差異は若干ありますが簡単に設定することができます。 codeforfun.jp 所感 今まで開発はHMTLなどで見た目を整理して逐一確認をしていたのですが、ボタンの配置などは必要な物を引っ張るだけで簡単に作成できるのでHTML等を使用して見た目を作成するのよりはるかに楽でした。 下図の赤枠の部分から ドラッグ&ドロップ するだけ。 ただし、参考にしたサイトにも書いてありますが、ボタンなどを引っ張ってくると xml のコードがごちゃごちゃして見にくくなるので注意が必要です。 私自身はごちゃごちゃしていても(自分だけが見る場合なら)全然気にしないタイプなのですが、そうでない方は手入力での作成の方がスッキリ整えるので手入力をしていただければと思います。 実際に挙動を確認するのもシミュレーターがあるので私のように Android 端末持ってないけど、なんとなく アプリ開発 をやってみたいという方でも実機なしですぐに動作確認できます。 Android だと機種ごとで一部見た目が変わっているのですが、シミュレーターを使えば端末ごとにレイアウトがどうなっているかすぐに確認できるのでとても便利でした。 終わりに 使用する言語は主に Java なのでアプリを作成するなら Android アプリからはじめて見てもいいかもしれません。実際にリリースするなら費用も安いので。 参考にしたサイトには音楽プレーヤーの作り方もあるので時間があったら作っても見ようと思います。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
こんにちは、株式会社 ラク スで横断的にITエンジニアの育成や、技術推進、採用促進などを行っている開発管理課に所属している鈴木( @moomooya )です。 今回は dev.to で人気記事になっていた「 The 25 most recommended programming books of all-time. (史上最もおすすめされているプログラミング本【25選】)」を紹介したいと思います。 注:本記事は2020年2月18日に Pierre 氏がdev.toに投稿した The 25 most recommended programming books of all-time. を執筆者Pierre氏の了承のもと、日本語で紹介する記事です。 訳書の邦題について、訳書に改訂などがあった場合は出来る限り最新版の邦題で記載しています。 おすすめのプログラミング本を選んだ方法 「Best Programming Books」などのクエリで Google 検索しました。そのすべての結果をWeb Scraping API の Scraping Bee を利用して スクレイピング しました。 約150のリンクが収集でき、それらのページタイトルを以下のように集約しました。 特定の技術またはプラットフォームに焦点を当てたリスト 特定の年に焦点を当てたリスト 無料の本に焦点を当てたリスト Quora 1 および Reddit 2 のスレッド 最終的に70個のリストを抽出しました。 それらのリストに対して Python とBeatifulSoupを用いて、書名のリストを抽出しプログラミング本に対する約1300件のおすすめを抽出しました。 集計の結果はこちらの リポジトリ を参照してください。 注: 1300件 という数値は元記事中には記載ありませんが、参照先レポジトリ内の中間集計データより補完しています。 史上最もおすすめされているプログラミング本 25冊 注:元の記事では各プログラミング本の紹介が Amazon.com から転記されていましたが、こちらは Amazon.co.jp 版に置き換えています。 25. Jez Humble & David Farley, "Continuous Delivery" 邦題 『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 おすすめスコア 8.8% amazon.co.jp より いつまで手動でデプロイしているんですか? 現代では継続的にソフトウェアをリリースすることが必須になっています。本書は、継続的なソフトウェアのデリバリーを実現するためのビルド、デプロイ、テスト、リリースの自動化についての本格的な解説書です。 24. Robert Sedgewick & Kevin Wayne, "Algorithms" 邦題 未訳? おすすめスコア 8.8% 鈴木注 おそらく訳書は出ていないと思われます。 ただし著者のRobert Sedgewick氏が執筆したプログラミング本として "セジウィック:アルゴリズムC" という類書は和訳されています。 セジウィック:アルゴリズムC 第1~4部 ―基礎・データ構造・整列・探索― 作者: ロバート セジウィック 近代科学社 Amazon 23. Cory Althoff, "The Self-Taught Programmer" 邦題 『独学プログラマー』 おすすめスコア 8.8% amazon.co.jp より 本書は「 Python だけ」を学ぶ本ではありません。 Python を使ってプログラミングを紹介していますが、伝えたい内容は Python に限らない「プログラミング全般」の知識です。 プログラマ になるためのスキルを独学できる本です。 Python プログラミングの基本を学べるだけでなく、 プログラマ として必要なスキル(シェル、 正規表現 、パッケージ管理、バージョン管理、データ構造、 アルゴリズム 、仕事の始め方・やり方)もひと通り学べるのが特徴です。 「プログラミングを始めたい」「できればその道でプロを目指してみたい」――そんな読者にオススメです。 本書の著者、コーリー・アルソフ(Cory Althoff)は、「独学 プログラマー 」です。本書は、彼が独学で、ゼロからプログラミングを学んだ体験に基づいて書かれました。 プログラミングを独学で身に付けるために、著者が Python を通して学んだエッセンスが書かれています。彼の独学 プログラマー としての学び方は、 Amazon.com での本書の評価を見るとわかるように、多くの人に支持されています。 ――訳者あとがきより 鈴木注 原著が Kindle Unlimitedで読めます!!! (2020年3月12日現在) 22. Steve McConnell, "Rapid Development" 邦題 『ラピッドデベロップメント―効率的な開発を目指して』 おすすめスコア 8.8% amazon.co.jp より ソフトウェア開発のスケジュールを正確に管理するための、全ての戦略、良い方法、価値のあるTipsを紹介。具体的な ケーススタディ も収録した実践テキスト。 21. Peter Seibel, "Coders at Work" 邦題 『Coders at Work プログラミングの技をめぐる探求』 おすすめスコア 10.2% amazon.co.jp より どうやってプログラミングを学んだ? 他人のコードをどうやって読む? ソフトウェアはどう設計する? バグを追跡する方法は? プログラミングの将来はどうなる? プログラミング言語 が果たす役割は? プログラマ であるピーター・サイベル氏が15人の偉大な プログラマー (コーダー)から その技を聞き出すインタビュー集を、『Joel on Software』訳者の 青木靖 氏が翻訳。 20. Eric Evans, "Domain-Driven Design" 邦題 『エリック・エヴァンスのドメイン駆動設計』 おすすめスコア 10.2% amazon.co.jp より ソフトウェア開発コミュニティでは、 ドメイン モデリング がソフトウェア設計の中心であることが広く認められてきています。 ドメイン モデルを通して、ソフトウェア開発者は豊富な機能を表現し、それをユーザの要求に本当の意味で応えるソフトウェアの実装に移すことができます。しかし、明らかに重要であるにもかかわらず、効果的な ドメイン モデリング をどのようにソフトウェア 開発プロセス に組み入れるかを説明する、実用的なリソースはほとんど存在しませんでした。 ドメイン 駆動設計はこの要求に応えるものです。これは具体的な技術についての本ではなく、読者に ドメイン 駆動設計への体系的なアプローチを提示するものです。設計のベストプ ラク ティスの応用的なセット、経験に基づくテクニック、さらに、複雑な ドメイン に直面するソフトウェアプロジェクトにおける開発を容易にする基本原則を紹介する一冊です。 19. Donald E. Knuth , "The Art of Computer Programming" 邦題 『The Art of Computer Programming 日本語版』 おすすめスコア 10.2% シリーズ一覧 The Art of Computer Programming Volume 1 Fundamental Algorithms Third Edition 日本語版 The Art of Computer Programming Volume 2 Seminumerical Algorithms Third Edition 日本語版 The Art of Computer Programming Volume 3 Sorting and Searching Second Edition 日本語版 The Art of Computer Programming Volume 4A Combinatorial Algorithms Part1 日本語版 amazon.co.jp より アルゴリズム のバイブル。 Knuth 先生の名著『The Art of Computer Programming』シリーズ 鈴木注 TeX はこの本を作るために生まれたらしいです。 シリーズ物となっており、原書では第4巻分冊が6冊目まで発行されて現在も刊行中です。 訳書としては第1巻~第3巻と第4巻分冊の1冊目までが和訳されています。 執筆予定は スタンフォード大学内のWebサイト で公開されています。第5巻は2025年予定だそうです。 18. Harold Abelson / Gerald Jay Sussman / Julie Sussman, "Structure and Interpretation of Computer Programs" 邦題 『計算機プログラムの構造と解釈 第2版』 おすすめスコア 13.2% amazon.co.jp より 言わずと知れた「計算機科学の古典的名著」復刊! プログラミング言語 LISP の方言である Scheme を使用し、抽象化、 再帰 、 インタプリタ 、 メタ言語 的抽象といった計算機科学における概念の真髄を丁寧に解説した古典的名著。また計算機科学教育に多大な影響を与えたことはもちろん、「 関数型言語 」の 聖典 のひとつとしても挙げられる。いわば、現代の計算機科学( コンピュータサイエンス )の礎であり、プログラミングの始原であり、すべてのITの原点といえる1冊。 17. Martin Fowler, "Patterns of Enterprise Application Architecture" 邦題 『エンタープライズ アプリケーションアーキテクチャパターン』 おすすめスコア 14.7% amazon.co.jp より エンタープライズ アーキテクチャ のレイヤ化とは? エンタープライズ アプリケーション開発は、多くの新しい技術の出現から利益を得てきました。 Java と.NETのようなマルチレイヤをなす オブジェクト指向 のプラットフォームは、今では一般的になっています。これらの新しいツールや技術は、強力なアプリケーションを構築することができます。しかし、これらの実装は容易ではありません。 オブジェクト開発を経験した技術者が、 アーキテクチャ を理解しないまま開発を行うために、 エンタープライズ アプリケーション開発では共通の失敗がしばしば生じます。本書は、 エンタープライズ アプリケーション開発者が直面するやっかいな課題に対する直接的な回答を示したものです。技術は変化( Smalltalk から Java 、.NET。CORBAまで)していても、共通の問題を解決するために同じ基礎的な設計の考え方を適用することができるのです。 本書は40以上のパターンを紹介しています。これらは、 エンタープライズ アプリケーションプラットフォームに適用可能な解決策です。前半は、 エンタープライズ アプリケーション開発についての短い チュートリアル です。 後半は、各パターンについて詳細に解説しています。各パターンは、 Java または C# でコード例を詳述し、使用法および実装について説明します。概念についても、豊富な UML ダイアグラムで例証します。 16. Jon Bentley, "Programming Pearls" 邦題 『珠玉のプログラミング 本質を見抜いたアルゴリズムとデータ構造』 おすすめスコア 16.1% amazon.co.jp より: 情報系の勉強をしたことのある人ならば、誰しもプログラムにおける アルゴリズム の概念に触れたことがあるだろう。 同じ動作をするプログラムでもエレガントな アルゴリズム を持つものと そうでないものの間には実行時間や堅牢性、リソースの利用量などにおいて 大きな隔たりがあり、時には劇的なほどパフォーマンスの差があることも珍しくはない。 一方でそのような アルゴリズム を創出することがいかに難しいかも周知のことである。 そのため現在では納期や効率に重点をおいたプログラミングが優先されることが多いが、 単純で美しいプログラムを書くことは何より重要なことである。 本書は著者を含めた プログラマー たちが扱った問題をベースに、 エレガントなプログラムを書く際のさまざまなアド バイス や手法について解説したものである。 大学での アルゴリズム 講義に登場してくる探索やソート、データ構造といった内容に触れており、 現実的な題材の下に要求の定義、リソースの活用の仕方、動作する環境などのさまざまな側面から どのように アルゴリズム を組むべきかといった、プログラムを組む上での原理原則を学べるように構成されている。 このように題材となっている内容は決して特殊ではなく、 プログラムを組んだ経験のある人ならば必ず触れたことのあるレベルなので、 高級言語 でのプログラムが書ける人ならば誰でも理解できる内容になっている。 随所に登場する設問や読書案内も読者が学習する上で役に立つだろう。 数理的な解析に重点を置く大学での アルゴリズム 講義の内容は 実際のプログラミングに生かしにくいが、本書では応用や実際のコード化といった面に 重点が置かれて説明がされているので実務上も大いに役立つ。 自分のプログラミングを原則的、一般的な見地からよりよいものにしていくために必ず役立つ本だ。(斎藤牧人) 15. Tom DeMarco & Tim Lister, "Peopleware" 邦題 『ピープルウエア 第3版』 おすすめスコア 17.6% amazon.co.jp より: ●ソフト開発の現場で多くの熱い共感を呼んだ名著! 開発プロジェクトで技術よりも何よりも大事なもの――それは「人」。一人一人の 人格の尊重、頭を使う人間にふさわしいオフィス、人材の選び方・育て方、結束した チームがもたらす効果、仕事は楽しくあるべきもの、仕事を生み出す組織づくり、 という6つの視点から「人」を中心としたプロジェクト開発の大切をユーモラスに 語っている。1987年の初版発行以来、多くのソフトウエア・エンジニアの共感を 呼んだ名著の改訂第3版。 ●プロジェクト管理に関わる新規書き下ろしを収録! 第3版では、時代の変化に対応し、以下の章が追加された。「リーダーシップについて 話そう」、「他者とうまくやっていく」、「 幼年期の終わり 」、「リスクとダンスを」、 「会議、ひとりごと、対話」、「E(悪い)メール」。 14. Thomas H. Cormen / Charles E. Leiserson / Ronald L. Rivest / Clifford Stein, "Introduction to Algorithms" 邦題 『アルゴリズムイントロダクション 第3版 総合版』 おすすめスコア 17.6% amazon.co.jp より: 原著は,計算機科学の基礎分野で世界的に著名な4人の専門家がMITでの教育用に著した計算機 アルゴリズム 論の包括的テキストであり,その第3版.前版までで既に アルゴリズム とデータ構造に関する世界標準教科書としての地位を確立しているが,より良い教科書を目指して再び全面的な記述の見直しがなされ,それを基に新たな章や節の追加なども含めて,大幅な改訂がなされている. 単に アルゴリズム をわかりやすく解説するだけでなく,最終的な アルゴリズム 設計に至るまでに,どのような概念が必要で,それがどのように解析に裏打ちされているのかを科学的に詳述している. さらに各節末には練習問題(全957題)が,また章末にも多様なレベルの問題が多数配置されており(全158題),学部や大学院の講義用教科書として,また技術系専門家のハンドブックあるいは アルゴリズム 大事典としても活用できる. 本書は,原著の第1~35章,および付録A~Dまでの完訳総合版である.また巻末の索引も圧巻で,和(英)‐英(和)という構成により,「数理用語辞典」としてもまことに有用である. 13. Charles Petzold , "Code" 邦題 『CODE: コードから見たコンピュータのからくり』 おすすめスコア 19.1% amazon.co.jp より Windows プログラミングの雄、チャールズ・ ペゾルド が10年来あたため続けてきたという注目の企画が、ついに1冊の本になった。 本書はコンピュータの動作を根本から解説するもので、データのやり取りを中心に、コンピュータの動作原理を解説している。序盤では 点字 やモールス信号などを題材とするコードの歴史と、実際に通信や演算を行うためのハードを詳細に扱っている。中盤からは、2進数の処理、リレーによる演算の方法、メモリやオートメーション、終盤ではプロセッサの構造から低級言語・ 高級言語 、OSなどにも触れている。 計算機工学、 論理回路 学などの高度な内容にも触れているため、理系の、できれば工学系の知識がある方が望ましい。とはいえ、読み物形式なので、順番に読んでいくことで予備知識がない方でも理解することはできるはずだ。懐中電灯、黒猫、シーソーなど、一見コンピュータと何の関係もなさそうな例をもとに、コンピュータのしくみを明かしているのは、本書の最大の魅力である。 先に述べた内容以外にも、ファイル形式や開発環境、グラフィックに関する解説など、まさしくコンピュータに関わるすべてに言及している。とくにプロセッサやOS、アプリケーションなどの歴史に関する部分は興味深い。数学的な部分にあまり興味がない方にとっても、読む価値は十分にあるだろう。コンピュータの動作や根本原理を知りたいという知的好奇心あふれる読者に、ぜひおすすめしたい1冊である。(斎藤牧人) 12. Steve Krug , "Don't Make Me Think" 邦題 『超明快 Webユーザビリティ ―ユーザーに「考えさせない」デザインの法則』 おすすめスコア 19.1% amazon.co.jp より: 明白で使いやすいサイトを実現するには? ↓ ユーザーに考えさせちゃダメ! Apple 、 Bloomberg 、 Lexus などを顧客としてきた、 ユーザビリティ コンサルタント の第一人者にして激安ユーザーテストの伝道師 ス ティー ブ・クルーグが説く、 ユーザーに「考えさせない」サイトの作り方。 20か国で翻訳、累計45万部超の世界的ベストセラー、ウェブ&モバイル ユーザビリティ の定番書『Don't Make Me Think』の日本語版です。 ちゃんと使ってもらえるサイトにしたいWeb担当者、コンバージョン率を上げたいEC担当者におすすめの一冊。 11. John Sonmez, "Soft Skills" 邦題 『SOFT SKILLS ソフトウェア開発者の人生マニュアル』 おすすめスコア 22% amazon.co.jp より ソフトウエア開発者専用に、「より良い人生」を送るためのノウハウ・スキルを網羅した、生き方バイブル本です。 プログラマー が良い人生を送るためには、技術習得法やキャリア構築法といったノウハウに加え、対人的な交渉・指導・意思疎通などをうまく行える能力や知恵、すなわちソフトスキルが不可欠です!本書では、キャリアの築き方、自分の売り込み方、技術習得法、生産性の高め方といった仕事で成功する方法だけでなく、財産の築き方、心身の鍛え方、恋愛で成功する方法など、「人生全般をより良く生きる方法」を具体的に説明します。 ■序文から抜粋 あなたがこの複雑な産業で活路を開こうとしている若いソフトウェア開発者なら、今手にしているこの本は、多くの知恵と優れたアド バイス を与えてくれるはずだ。 ロバート・C・マーティン(アンクル・ボブ) ■「解説」から抜粋 本書はソフトウェア技術者向けの書籍ではありますが、いわゆるテク ノロ ジー のことはほとんど書いてありません。しかし、「成功者」になるために必要なそれ以外の多くのことが書いてあります。(中略)今こそ私たちがもっと成功に貪欲になれるチャンスなのではないでしょうか。 ■「訳者あとがき」から抜粋 全体を読み通して感じたのは、人の弱さを十分に意識して書かれていること、率直であ ること、上からではなく同じ高さから話しかけてくることでした。(中略)校正のために読み返してみると、株や栄養や腹筋のことなど、「何かで読んだんだけどさあ」という枕で出てくるような話の多くを本書で覚えたことに気づきました。無意識のうちにいろいろな影響を受けているようです。この本、ただものではないですよ。 10. Gayle Laakmann McDowell, "Cracking the Coding Interview" 邦題 『世界で闘うプログラミング力を鍛える本 ~コーディング面接189問とその解法~』 おすすめスコア 22% amazon.co.jp より トップIT企業が出題するコーディング面接にチャレンジ! 人気のあるトップIT企業で行われるコーディング面接に合格し採用されるための攻略本として、グーグル等でエンジニアとして働き、かつ多くの採用プロセスに関わってきた著者によって本書は執筆されました。米国で大人気のコンピュータプログラミングに関するベストセラー書(Cracking the Coding Interview: 189 Programming Questions and Solutions)の日本語版です。 本書で取り上げるプログラミング問題はトップIT企業が求める能力が凝縮されている、面接で実際に使われたものです。そしてなによりも アルゴリズム を中心とした コンピュータサイエンス の基礎知識や活用法を楽しみながら学べる内容となっています。 前著「世界で闘うプログラミング力を鍛える150問」と比べ計算量に関する説明がより詳細になりました。新規の問題はもちろん、既存の問題についても時間計算量・空間計算量の記述が追加され、計算量の見積もりについての話題も参考になるでしょう。また木とグラフ・探索 アルゴリズム に関する説明も充実したものになり、純粋なプログラミング技術書としてのバランスと深みが増しました。 Big-O記法の解説章や発展課題、解き方のヒントの追加、また全ての問題がカテゴライズされより読みやすくなりました。 本書が支持されている理由は「面接」という限られた時間だけにフォーカスするのではなく、その前後における行動までアド バイス してくれている点です。「エンジニアとして日々をどう過ごすか」を考える上で非常に有益でしょう。 自分が プログラマ として現在「どんな分野」に関して、どの程度の「能力」があるのか。これからのキャリアアップに必要な知識やスキルを考える手がかりとして。あるいは本当に優秀な候補者を採用する面接を行うための一冊として。 本書にはそのヒントがたくさん含まれています。 9. Erich Gamma / Richard Helm / Ralph Johnson / John Vlissides, "Design Patterns" 邦題 『オブジェクト指向における再利用のためのデザインパターン』 おすすめスコア 25% amazon.co.jp より オブジェクト指向 における再利用のための デザインパターン 建築の発想を持ち込む オブジェクト指向 はソフトウエア開発の手法として誕生したが,ほかの分野にも広がりつつある。その一つとして注目すべきなのが「デザイン・パターン」の登場である。 デザイン・パターンとは, オブジェクト指向 でソフトウエア設計を行う際に利用するカタログ集である。例えば,経験豊かな プログラマ は以前に解いた問題と,これから新しく解こうとしている問題が類似していることに気づけば,以前に使った解法が応用できる。デザイン・パターンとはこうした解法をだれでも再利用できるように一般化(パターン化)したものの寄せ集めと考えればよい。 この考え方と実現手法は,一般に GoF ( Gang of Four :4人組)本と呼ばれる本書で有名になった。 GoF 本は建築家の クリストファー・アレグザンダー がまとめた都市計画のカタログ集『時を超えた建設の道』( 鹿島出版会 )に強い影響を受けている。この点はたいへん興味深い。 オブジェクト指向 の導入で,ソフトウエアの世界においても 建築学 のように,構造をパターン化できることを示しているからだ。 8. Michael Feathers, "Working Effectively with Legacy Code" 邦題 『レガシーコード改善ガイド』 おすすめスコア 26.4% amazon.co.jp より: あなたは、 Java や.netでレガシーコードを書いていませんか? 本書は、システム保守の現場でありがちな、構造が複雑で理解できないようなコードに対する分析手法・対処方法について解説します。つまり、コードを理解し、テストできるようにし、 リファクタリング を可能にし、機能を追加できるテクニックを紹介しています。レガシーコードとは、 メインフレーム のアプリケーションのことではなく、変更することが困難なコードを指しています。著者は、本書で「私にとって、テストがないコードはレガシーコードだ」「テストコードがあれば振舞いを変えても、すばやく変更、確認することができる。もし、テストコードがなければ振舞いを変更しても、それが正しいのか、悪いのか判断できない」「 ソースコード がきれいで、良い構造であれば十分か?そうではない。もし、テストコードなしで大幅な修正を加えるとしたら、信じられないほどのスキルと明確な理解が必要になる」と述べています。本書は Java 、C、 C++ でサンプルを記述していますが、記載されているテクニックは言語依存するものではないため、他の言語( Delphi 、 Visual Basic 、 COBOL 、 FORTRAN )でも使えます。 7. Robert Martin, "The Clean Coder" 邦題 『Clean Coder プロフェッショナルプログラマへの道』 おすすめスコア 27.9% amazon.co.jp より ソフトウェアのプロになるには本書が必要だ! ソフトウェアのプロとは? プロの行動とは? 衝突・厳しいスケジュール・理不尽なマネージャにどう対応すべきか? いつ・どのようなときに「ノー」と言うべきか? プロはプレッシャーにどう対応するのか? 6. Frederick P. Brooks Jr, "The Mythical Man-Month" 邦題 『人月の神話【新装版】』 おすすめスコア 27.9% amazon.co.jp より ソフトウェア開発の定番書『人月の神話』。「 ブルックスの法則 」で知られる ブルックス 教授によるこの名著が、同教授の35年ぶりの新刊「The Design Of Design」 (邦題「デザインのためのデザイン」)を記念し、従来の縦組みから横組みに変わり、 表紙カバーを新たに新登場。 IBM の大型コンピュータSystem/630、および オペレーティングシステム OS/360 の 開発チームを率いた著者が、プロジェクトで発生した問題点を詳細に分析し、 ソフトウェア開発にまつわる困難と展望について持論を展開したエッセイ集。 原著初版(1975年)の刊行から35年がたつ現在でも、大規模開発プロジェクトにおける ソフトウェア工学 の古典として読み継がれ、多くの読者を獲得している。 とくに、「遅れているソフトウェアプロジェクトへの要員追加は、 さらにプロジェクトを遅らせるだけだ」という ブルックスの法則 は名高い。 開発において「人員×月日」というスケジュール見積もりが適用されている問題を指摘し、 ソフトウェア産業 において広くいきわたっている「人月の神話」を明らかにした。 また、刊行20周年記念して発行された増訂版では、発表当時大きな議論を巻き起こした 「銀の弾はない」をはじめとして、初版刊行以降に発表された著者の代表的な論文4編を収録。 各方面から寄せられたさまざまな議論に対して、著者があらためて自身の見解を述べている。 5. Eric Freeman / Bert Bates / Kathy Sierra / Elisabeth Robson , "Head First Design Patterns" 邦題 『Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本』 おすすめスコア 29.4% amazon.co.jp より 初めて学ぶ方、過去に挫折した経験のある方、知識を確固たるものにしたい方を対象に、イラストや写真を使ってやさしく楽しく解説する人気のHead Firstシリーズの デザインパターン 編。 刺激的なレイアウト、思わず膝を叩く見事なたとえ、引き込まれる小話、楽しいクイズやパズルで飽きることなく読み進むことができます。 複雑難解な デザインパターン の概念が面白いほどよくわかる、目からウロコの画期的な書籍です。 4. Martin Fowler, "Refactoring" 邦題 『リファクタリング(第2版): 既存のコードを安全に改善する』 おすすめスコア 35% amazon.co.jp より ソフトウェア開発の名著、第2版登場! リファクタリング は、ソフトウェアの外部的な振る舞いを保ったままで、内部の構造を改善する作業を指します。本書は リファクタリング のガイドブックであり、 リファクタリング とは何か、なぜ リファクタリング をすべきか、どこを改善すべきか、実際の事例で構成され、ソフトウェア開発者にとって非常に役立つものとなっています。 本第2版では、約20年前のオリジナル原稿の構成は変わらないものの、大幅に書き換えられているほか、サンプルコードが Java から Java Scriptになるなど、現代的にアレンジされています。 3. Steve McConnell, "Code Complete" 邦題 『Code Complete 第2版 完全なプログラミングを目指して』 おすすめスコア 42% amazon.co.jp より 本書は効果的なコンスト ラク ションプ ラク ティスについての知識を集めた、実践的なプログラミング解説書です。ソフトウェア開発プ ラク ティスは目覚しい進歩を遂げていますが、一般の プログラマ にはなかなか浸透しません。本書は、業界の第一人者らの知識と、一般の商用プ ラク ティスとの橋渡しをします。10年前の第1版とコンセプトは同じですが、第2版は、全体を通じて オブジェクト指向 の考え方が反映されたものになっています。また、「 リファクタリング 」の章が追加され、サンプルコードは C++ 、 C# 、 Java 、 Visual Basic などにアップデートされています。本書は、ソフトウェア開発の総合ガイドを求めている経験豊富な プログラマ 、経験の浅い プログラマ を教育する技術指導者、正式なト レーニン グを受けたことのない独学 プログラマ 、これから社会に出る学生や新人 プログラマ などを特に対象としています。本書で説明されている研究成果や過去の経験は、高品質なソフトウェアを作成し、問題を少なく抑えて作業をより短期間で行うのに役立ちます。また、大きなプロジェクトを制御し、要求の変更に応じてソフトウェアの保守や修正を適切に行うのにも役立ちます。 2. Robert C. Martin, "Clean Code" 邦題 『Clean Code アジャイル ソフトウェア達人の技』 おすすめスコア 66% amazon.co.jp より コードを書き、読み、洗練する 本書の ケーススタディ を注意深く読むことで、コードを洗練していく過程で行うべき判断について学ぶことができます。プログラムが動作したからといって、プログラミングが終わったことにはならないのです。 1. David Thomas & Andrew Hunt, "The Pragmatic Programmer" 邦題 『新装版 達人プログラマー 職人から名匠への道』 おすすめスコア 67% amazon.co.jp より 経験に裏打ちされたヒントを満載し、実践可能なプログラムの作り方を教える。より効率的、そして生産的な プログラマー を目指す人に向け、具体的なアド バイス を、解決策のシステムを構成するよう関連付けて編集。 鈴木注 1位は 毎年少なくとも一つの言語を学習する で有名な『達人 プログラマー 』でした。原書では20周年版が去年2019年に出版されているので和訳版の改訂にも期待。 コメント欄から抜粋 私はいつも、Scott Rosenbergの「Dreaming in Code」を追加したいと思っています。 Dreaming in Code: Two Dozen Programmers, Three Years, 4,732 Bugs, and One Quest for Transcendent Software (English Edition) 作者: Rosenberg, Scott Crown Amazon The Phoenix Projectにも言及した方がいいんじゃないか? ;) Phoenix Project: A Novel About It, Devops, And Helping Your Business Win 作者: Kim, Gene , Behr, Kevin , Spafford, George It Revolution Press Amazon 挙げられている中で『計算機プログラムの構造と解釈』や『Art of Computer Programming』 など何冊かは読むことには実用的な意味がありません 。 多くの人が推奨していますが、実際に読む人はほとんどいません。 それらは題材としてすでにマイナーな言語を使用し、現在では時代遅れまたは不要な概念を多く扱っています。 プログラミングの心理学 要求仕様の探検学―設計に先立つ品質の作り込み どちらもGerald Weinbergによるものですが、Martin Fowlerよりも質の高い本を書いています。 もう1人の素晴らしい著者はJuval Löwyで、彼の本をすべて推薦します。 特に彼の最新刊: Righting Software これらが次の上位25のリストに載っていても驚かないでしょう。 プログラミングの心理学 25周年記念版 作者: ジェラルド・M・ワインバーグ 日経BP Amazon 要求仕様の探検学―設計に先立つ品質の作り込み 作者: ゴーズ,D.C. , ワインバーグ,G.M. , Gause,Donald C. , Weinberg,Gerald M. , ヤナ川 志津子 , 純一郎, 黒田 共立出版 Amazon Righting Software (English Edition) 作者: Juval, Löwy Addison-Wesley Professional Amazon 素晴らしいリスト。 私もお勧めします: FreemanとPryceの『実践 テスト駆動開発 』 実践テスト駆動開発 (Object Oriented SELECTION) 作者: Steve Freeman , Nat Pryce 翔泳社 Amazon お見事! The Pragmatic Programmerを読んでいない人には絶対にお勧めします。 私が読んだ最初の技術書であり、今でも私のお気に入りです。 素敵なリスト。 Kent Beck の" Smalltalk Best Practice Patterns"が含まれていなかったことが信じられません。 これは信じられないほどの良書であり、 Smalltalk だけの話ではありません。 これはすべての人におすすめできます。 ケント・ベックのSmalltalkベストプラクティス・パターン―シンプル・デザインへの宝石集 作者: ケント ベック ピアソンエデュケーション Amazon 「Getting Real」も素晴らしい読み物です。 Getting Real: The smarter, faster, easier way to build a successful web application 作者: 37signals, 37signals , Fried, Jason , Heinemeier Hansson, David , Linderman, Matthew 37signals Amazon 所感 原書と訳書の表紙を並べて表示してみました。こういうの見比べるのが好きなんですよね……。 というわけでランキングのおさらいです。 1位『達人 プログラマー 』 2位『Clean Code』 3位『Code Complete』 4位『 リファクタリング 』 5位『Head First デザインパターン 』 6位『人月の神話』 7位『Clean Coder』 8位『レガシーコード改善ガイド』 9位『 オブジェクト指向 における再利用のための デザインパターン 』 10位『世界で闘うプログラミング力を鍛える本』 11位『SOFT SKILLS』 12位『超明快 Web ユーザビリティ ―ユーザーに「考えさせない」デザインの法則』 13位『CODE』 14位『 アルゴリズムイントロダクション 』 15位『ピープルウエア』 16位『珠玉のプログラミング』 17位『 エンタープライズ アプリケーション アーキテクチャパターン 』 18位『計算機プログラムの構造と解釈』 19位『The Art of Computer Programming 日本語版』 20位『エリック・ エヴァ ンスの ドメイン 駆動設計』 21位『Coders at Work』 22位『ラピッドデベロップメント』 23位『独学 プログラマー 』 24位『Algorithms』 25位『継続的デリバリー』 頻繁におすすめされるような有名なプログラミング本で、未読のものはあっても知らないものはそんなにないかな、と思っていたのですが意外と知らない本を発見できて嬉しかったです。日本語圏と 英語圏 でもまた違いがあったりするのでしょうか。 読みたいと思っていながら読めていなかったプログラミング本もたくさん思い出せたので、合間を見つけながらせっせと読んでいきたいと思います。 最後に改めて。了解をくれたPierreさん、ありがとう。 Pierre, thank you for your consent. エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com Q&Aコミュニティサイト ↩ 匿名 掲示 板サイト ↩
はじめに こんにちは。新卒2年目のtaku_76です。といってもあと半月ほどで3年目になります。 今回は以前ある記事でコンテナ技術の習得は必須ということを見て、コンテナ技術について表面的なことしか知らないなーと思い、学習しています。まだ学習途中ですが、初めに学んだ基本的な内容をまとめておこうと思います。 はじめに Dockerとは コンテナ型の仮想化とは Dockerイメージとは Dockerコンテナの実行 helloworldイメージの実行と動作解説 nginxイメージの実行と動作解説 最後に Dockerとは Docker社が提供しているコンテナ型のアプリケーション実行環境です。 コンテナ型の仮想化とは OSの カーネル を利用してホストOS上にアプリケーション実行環境を作るものです。 以下のような構造となっています。 コンテナ型仮想化の構成 Docker Engineがコンテナ型仮想化のコアとなる部分で、コンテナの作成、起動、停止、削除などの操作はDocker Engineを介して行われます。使い方としましてはDockerのコマンドを実行することでDocker Engineに指示を出すことになります。 以下にコンテナ型仮想化のメリットとデメリットをまとめます。 メリット ホストOSの カーネル を使用するため、動作が早くリソースの使用率が少ない 同じDockerイメージからコンテナを起動することで、環境が変わっても問題なく動作させることができる デメリット コンテナはホストOSの カーネル を使用して動作するため、 カーネル を共有できないOSでコンテナを動作させることができない Dockerイメージとは 特定のコンテナを実行するのに必要なファイルをまとめた ファイルシステム です。一般的にOSのライブラリやアプリケーションなどがあり、Dockerイメージは自分で作成することもできます。構成としてはイメージのデータはレイヤーで構成され、読み取り専用なので編集することはできません。以下Dockerイメージの構成となります。 左がDockerイメージで右がDockerイメージから作成したコンテナの図になります。Dockerイメージは図のように階層構造でデータが管理されており、各層のレイヤーはコマンドを実行する際に階層が積み重ねられます。そして、Dockerイメージを元にコンテナを起動すると読み書き可能なコンテナレイヤーの層が作られます。コンテナレイヤー上にファイルの追加など行い、それをまたイメージとして保存することも可能です。注意として、過去のレイヤーで追加したファイルをコンレナレイヤーで削除し、新しいイメージを作成しても過去のレイヤーから対象のファイルが消えることはありません。よって、無駄なファイルがイメージに含まれないように作成することが大切です。 Dockerコンテナの実行 helloworldイメージの実行と動作解説 コンテナの実行は簡単です。以下のコマンドをターミナルで入力します。 $ docker run hello-world すると結果を以下のようになります。 Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 1b930d010525: Pull complete Digest: sha256:f9dfddf63636d84ef479d645ab5885156ae030f611a56f3a7ac7f2fdd86d7e4e Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ ここで起こっていることを説明します。 1.まずローカルでDockerクライアントがDockerデーモンに接続してhello-worldのイメージを探します。 2.今回はローカルにhello-worldのイメージは存在しないので、インターネットを経由してDocker社が ホスティング しているDocker Hubのサーバに探しに行きます。 3.イメージが見つかればダウンロードしてローカルに保存します。 4.保存したイメージをもとにコンテナを起動して、コンテナに定義されたコマンドを実行します。 ※同じイメージがローカルに存在する場合は、2と3は省略されます。(ダウンロードがないので早く実行される) ちなみに、docker runコマンドは複数のコマンドをまとめて実行したもので、以下のコマンドをまとめています。 1.docker pull:イメージの取得 2.docker create:コンテナの作成 3.docker start:コンテナの起動 取得したイメージは以下のコマンドで確認することができます。 $ docker imeges 結果は以下のようになります。 REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest fce289e99eb9 14 months ago 1.84kB リポジトリ に含まれるイメージがTAGによって管理されているのですが、特にTAGを指定しなかった場合にはlatestTAGのイメージがダウンロードされます。 また、以下のコマンドでイメージの詳細情報を表示することができます。 $ docker inspect hello-world 結果は以下のようになります。 [ { "Id": "sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e", "RepoTags": [ "hello-world:latest" ], "RepoDigests": [ "hello-world@sha256:f9dfddf63636d84ef479d645ab5885156ae030f611a56f3a7ac7f2fdd86d7e4e" ], "Parent": "", "Comment": "", "Created": "2019-01-01T01:29:27.650294696Z", "Container": "8e2caa5a514bb6d8b4f2a2553e9067498d261a0fd83a96aeaaf303943dff6ff9", "ContainerConfig": { "Hostname": "8e2caa5a514b", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, (中略) Dockerコンテナの設定情報として、ホスト名や 環境変数 コンテナ起動時に実行されるコマンドやコマンド実行時の ディレクト リの情報などが表示されます。そのほかにも様々な情報が表示されていますので、詳細情報を確認する際によく使われるコマンドです。 そして、ローカルで取得したイメージの削除を行います。次のコマンドで削除することができます。 $ docker rmi hello-world 強制削除を行う場合は-fオプションを使用します。 ここまででhello-worldイメージを用いてDockerイメージの取得から削除までを解説しました。 nginxイメージの実行と動作解説 ここではnginxイメージを使用してデフォルトのnginxの画面が表示されるところまで進めます。 nginxコンテナを立ち上げるコマンドは以下になります。 $ docker run --name <コンテナ名> -d -p <ホスト側のポート番号>:<コンテナ側のポート番号> <イメージ名> コマンドの解説ですが、runについては説明済みですので割愛します。--name <コンテナ名>ですが、コンテナを識別したりコンテナの操作を行うために、起動するコンテナに名前をつけるオプションです。引数は任意の名前をとります。-dオプションはデタッチモードとしてコンテナの実行をバッググラウンドで行うためのオプションです。-pオプションは、コンテナのポートをコンテナ外に公開する設定です。ホストマシンが外部に公開するポート番号:コンテナに マッピング するポート番号という構成です。 それでは実際にnginxコンテナを起動してみます。 $ docker run --name nginx-test -d -p 8080:80 nginx 以下のような結果になります。 Unable to find image 'nginx:latest' locally latest: Pulling from library/nginx 68ced04f60ab: Pull complete 28252775b295: Pull complete a616aa3b0bf2: Pull complete Digest: sha256:2539d4344dd18e1df02be842ffc435f8e1f699cfc55516e2cf2cb16b7a9aea0b Status: Downloaded newer image for nginx:latest この状態で http://localhost:8080/ にアクセスするとデフォルトのnginxの画面が表示され、nginxコンテナが正常に起動できていることが確認できます。 こちらについて解説しますと、nginxコンテナの80番ポートをコンテナを実行している 仮想マシン の8080番ポートに対応させています。これによって 仮想マシン の8080番ポートにアクセスした場合、nginxコンテナのネットワークインターフェースの80番ポートに転送するように設定されます。そして80番でlistenしていたnginxがコンテンツを返し、ウェブブラウザの画面にデフォルトが表示されます。 ここで、コンテナの状態を確認するために以下のコマンドを実行します $ docker ps 以下のような結果になります。 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 14da03714d91 nginx "nginx -g 'daemon of…" 26 minutes ago Up 3 minutes 0.0.0.0:8080->80/tcp nginx-test STATUSを見ると、現在実行中であり起動して3分経過していることがわかります。 そして以下のコマンドでコンテナの実行を停止することができます。 $ docker stop nginx-test 状態を確認します。 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 14da03714d91 nginx "nginx -g 'daemon of…" 32 minutes ago Exited (0) 6 seconds ago nginx-test STATUSがExited状態となり停止していることが確認できます。 ここまでで、nginxコンテナの起動から停止までの解説をしました。 最後に 今回はDockerについて基本的なことや操作をまとめました。Dockerファイルについても記載したかったですが、次の記事を書く機会に自分の作成したいアプリケーション実行環境を構築した話を書きたいと思っています。
こんにちわ @kawanamiyuu です。早いものでもう開催から 1 ヶ月経ちましたが、先月開催された Object-Oriented Conference で登壇してきました。また、弊社はブロンズスポンサーとして協賛していました。 イベント概要 登壇資料 登壇に対する反応 登壇までのチャレンジ 〜登壇駆動登壇の実践〜 Appendix. イベント概要 日時:2020 年 2 月 16 日 (日) 会場: お茶の水女子大学 公式 HP: https://ooc.dev/ ハッシュタグ : #ooc_2020 ooc.dev 登壇資料 speakerdeck.com 登壇資料のサマリー 登壇に対する反応 since:2020-02-16_16:30:00_JST until:2020-02-16_16:50:00_JST #ooc_e 今回の発表の軸となる主張に共感いただけて良かったです。 「 アーキテクチャ の正体は依存関係の取り決め」、確かにだった。 アーキテクチャ テスト導入しているけど、自分の実装ミスに気付くだけでなく違反を起点に話し合うきっかけにもなっているのでもっと広まればいいなと思う。 #ooc_2020 #ooc_e — west-c (@west_c_) 2020年2月16日 アーキテクチャ は依存関係を適切に設計したいだけ →わかる。適切に設計したい理由はいろいろあるけど、「テストしやすいため」が個人的には一番。 #ooc_2020 #ooc_e — ウホーイ (@the_uhooi) 2020年2月16日 依存の向きにフォーカス、うん大好きさ #ooc_e — suzuki- hoge (@suzuki_ hoge ) 2020年2月16日 登壇までのチャレンジ 〜登壇駆動登壇の実践〜 今回の登壇にあたって 1 つチャレンジがありました。それは 登壇駆動登壇 の実践です。「 アドベントカレンダー (12月) → 社内ビアバッシュ (1月) → 自社主催のMeetup (2月) → 本番 (2月)」と アウトプットを重ねながら 言語化 に取り組む ことで発表の完成度を上げていきました。 今回は特にアウトプットのスパンが短かったためとても緊張感があり骨の折れる作業でしたが、プロポーザル作成時には整理しきれていなかったア イデア を 言語化 でき、満足のいく発表に仕上がりました。 何度か登壇を経験し人前で話すこと自体へのハードルはほとんど感じなくなった私ですが、「 言語化 」することが苦手な私にとっては今回の取り組みで得られた手応えは、今後の登壇に対するブレイクスルーになったと感じています。 Appendix. アーキテクチャ テストに興味がわいた方はこちらもぜひ↓ tech-blog.rakus.co.jp
こんにちは、株式会社 ラク スで横断的にITエンジニアの育成や、技術推進、採用促進などを行っている開発管理課に所属している鈴木( @moomooya )です。 ラク スの開発部ではこれまで社内で利用していなかった技術要素を自社の開発に適合するか検証し、ビジネス要求に対して迅速に応えられるようにそなえる 「 開 ( か ) 発の 未 ( み ) 来に 先 ( せん ) 手をうつプロジェクト(通称:かみせんプロジェクト)」 というプロジェクトがあります。 2019年度下期にこのプロジェクトで「 機械学習 プロジェクトの進め方」について検証したので紹介したいと思います。対象読者は非エンジニアを含む、 機械学習 を用いた機能を企画・設計する全ての関係者 となります。 今までの記事はかみせんカテゴリからどうぞ。 tech-blog.rakus.co.jp 今回の目標 参考書籍 あらためて機械学習とは 何ができるのか 機械学習プロジェクトのアンチパターン システムに組み込むまでの手順 プロジェクトの進め方 問題の明確化 システム設計 機能設計 アルゴリズム選定 前処理 モデルの作成 モニタリング 2つのモニタリング 活用事例 大日本住友製薬と英Exscientiaの創薬事例 講談社のTEZUKA2020プロジェクト 結論 社内勉強会の際に挙がった声と回答 今回の目標 「 人工知能が幻滅期に入った 」と言われるようになったので 1 、啓蒙活動期に向けて本格的な検証を開始しています。 プロダクトに 機械学習 を利用した機能を実装するにあたってエンジニ アサイ ドだけではなく、ビジネスサイドも含めて、どういった考えで取り組むべきなのかをまとめます。 いきなり難しい領域に取り組むのは無謀なので一番わかりやすい「 教師あり学習 」のみを想定します。 toB サービスの場合だとクライアントに説明しにくい処理を組み込むのはハードルが高すぎるということも考慮しています。 参考書籍 仕事ではじめる機械学習 作者: 有賀 康顕 , 中山 心太 , 西林 孝 オライリージャパン Amazon 特に第1部第1章は関係者全員に読ませましょう。 人工知能システムのプロジェクトがわかる本 企画・開発から運用・保守まで (AI & TECHNOLOGY) 作者: 本橋 洋介 翔泳社 Amazon プロジェクトを進めていくにあたっての ケーススタディ が豊富。 あらためて 機械学習 とは 何ができるのか 大まかにいって 入力データを分類すること 入力データから数値を予測すること の2つです 2 。 機械学習 プロジェクトの アンチパターン 「 機械学習 でなにかすごいことをしたい」という上司が現れて、何をすればいいかというところから頭をひねるようなプロジェクトになってしまい、うまくいかない結果に終わる危険性が高まります。 『仕事ではじめる 機械学習 』第1部第1章「 機械学習 プロジェクトのはじめ方」より 「言わずもがな」ですね。 システムに組み込むまでの手順 まずはデータがないと話がはじまりません。後から出てくるScikit-Learnの チートシート ではデータの特徴によって適切な アルゴリズム が選択できますが、 少なくとも50サンプル以上 が必要となります。他にも基準として「1万サンプルを超えるか」「10万サンプルを超えるか」という目安が 大規模なデータかどうか という基準として出てきます。 データを用意したら次に行うことはデータの前処理です。 機械学習 の世界では 「前処理8割」 という言葉があるようで、非常に重視されています。収集した生のデータはそのままだと扱いにくい書式や値であることが多く、それを学習 アルゴリズム への入力として都合の良い形に整形しましょう、というのが「前処理」になります。 取り組む前は次の学習モデル作成が大変なのかと思っていましたが、自前の アルゴリズム 構築を行わない場合は前処理工程の方が遥かに大変です。 前処理を行ったデータを入力として学習モデルの作成を行います。自前で学習 アルゴリズム の構築を行わない場合、公開されている アルゴリズム 選択 チートシート と 機械学習 ライブラリを用いて、学習 アルゴリズム の選定と実装ができるので比較的容易に学習モデルの作成は出来ます。 作成した学習モデルをシステムに組み込みます。組み込みの際には作成した学習モデルファイルを読み込んで利用します。併せてモニタリングに必要な数字も取得できるように作り込みましょう。 プロジェクトの進め方 問題の明確化 機械学習 を使っても 人間が真偽を判断できない問題は解くことが出来ません 3 。 注意しなければならないのは「人間が判断できるかどうか」を考えるときに所要時間はあまり意識する必要がないことです。例えば「何日もかければ正しいかどうか判断できる」というような実務上現実的ではない時間がかかる場合でも、 判断することができれば多くの場合問題ない です。なぜならプログラムの実行速度は人間の何倍もの速度があるため時間的な制約は問題にならないためです。 問題と対になる成果の指標も最初に決めておきましょう。 機械学習 を利用した機能の運用は高コストになりがちなので ビジネスに貢献出来ていることが必須 です。ビジネス観点でのKPIを定めておくべきです。 問題を人間が解けることの確認とKPIが定まったら、取り組む問題が本当に必要なのか、取り組む問題に 機械学習 が必要なのかを検証しましょう。『仕事ではじめる 機械学習 』でも大きく扱われているように 機械学習 を使わない方法を検討します。想定しているよりも機能や利用シーンが制限されたものでもよいのでプロトタイプを作成し、問題設定が想定通りかどうか検証しましょう。 検証の結果、 機械学習 を利用しなくても要件を満足することもある と思います。その時はオーバースペックなものを作らずに済んだと喜びましょう。 手段を目的と勘違いしてはいけません 。 システム設計 機能設計 データ収集方法 予測誤りのカバー方法 撤退ラインの定義 先述の通り、データ収集の仕組みが必要になります。数千サンプルのデータを継続的に収集することは手作業では割に合わない作業です。最初の1, 2回を検証を兼ねて手作業でやることは否定しませんが、それが3回、4回と続くようなら見直したほうが良いでしょう。 また、 機械学習 では誤った結果を出力する ことがあります。大体よく見かける予測正解率は80~90%程度なので5~10回に1度くらいと、 それなりの頻度で誤った結果を出力するため仕組みとして誤った結果を出力しても問題にならないような機能設計が必要 です。 そしてこのフェイズを超えたあたりからサンクコスト効果により、撤退判断が遅れやすくなります。なので、この時点で撤退条件を定義しておくとよいでしょう。 アルゴリズム 選定 機械学習 アルゴリズム の選定については自前で アルゴリズム を構築しない場合であれば以下で アルゴリズム 選定用の フローチャート が公開されています。 scikit-learn - Choosing the right estimator 機械学習アルゴリズム チート シート - Azure Machine Learning 昔は アルゴリズム から開発することが必要だったようですが、現在は優秀な アルゴリズム が簡単に利用することができます。感謝して使わせてもらいましょう。 前処理 いちばん大変な工程です。 機械学習 はデータからデータを導く アルゴリズム なので入力データが重要で、最終的な予測精度にも影響するようです。なのでたくさんのデータを集めて精度を上げるわけですが、 収集したデータが都合の良い書式であるとは限りません 。というよりも 都合が悪い形式であることを前提に取り組んだほうが良さそう です。データソースが1つであればまだマシでしょうが、複数のデータソースからデータを集めてきた場合にはさらに手間が増加するでしょう。 「前処理8割」という言葉があるらしいですが、以下のような様々な処理が必要になるようです。 データクリーニング(データクレンジングとも) 不要なサンプルの除去 ノイズとなる外れ値の除去 値がない項目の処理 値の整形 値の分布を正規化 よくあるのは0~1の範囲に変換 細分化しすぎている分類を集約 自然言語 での時制、語尾変化、類語の統一 これらを実現するための手法もいろいろ考案されているようで、前処理だけに絞った書籍も複数出版されています。 今回は前処理がこんなに奥深いテーマだということを知らなかったため深追いしませんでしたが、来年度の取り組みテーマとして前処理の掘り下げを予定しています。 モデルの作成 判断材料となるデータは場合によっては非常に大きなデータサイズになり得るため、そのままシステムに組み込むわけには行きません。そのため 機械学習 アルゴリズム を通して作成した 学習モデルのみを組み込み ます。学習モデルは誤解を恐れずに言うとデータを分析して抽出した条件式の詰め合わせのようなイメージです。 機械学習 アルゴリズム の選定や実装も先述の通り、既存の フローチャート やライブラリを利用することで比較的容易に実現することが出来ます。 ただし忘れてはいけないのは運用を開始しても、新たに収集したデータを元に定期的に学習モデルの再作成(再学習)が必要になります。 再学習を行わないと入力傾向の変化や未知の入力パターンに適応できなくなる ためで、この現象はコンセプトドリフトと呼ばれています。 モニタリング 2つのモニタリング 機械学習 の予測精度は入力傾向の変化によりいつかは劣化します。予測精度劣化の兆候を検知するためにもモニタリングは必要です。 予測結果が把握できている入力デー タセット を ベンチマーク デー タセット として利用します 。このデー タセット のことを「ゴールドスタンダード」というそうです。 もう一つはビジネス的な成果のモニタリングです。機能を作成してもビジネスに貢献できていなければ意味がありません。ビジネス観点の指標をモニタして成果が上がっていることを確認しましょう。 活用事例 では進め方はともかくどのような使い方をすればよいのでしょうか。 システム設計の項で触れた「誤った結果を出力しても問題にならないような機能設計」という観点を交えて見ていくと非常に参考になるケースを見つけました。 大日本住友製薬 と英Exscientiaの 創薬 事例 www.itmedia.co.jp こちらの 大日本住友製薬 と英Exscientiaが2020年1月30日に発表したAIを活用した新薬が 臨床試験 を始めた事例です。新薬開発の世界では膨大な組み合わせの中から候補となる組み合わせを専門家の知識と経験で見つけ出し、それを検証して製品化につなげるそうです。この事例では「膨大な組み合わせの中から候補となる組み合わせを見つけ出す」部分にAIを活用しているそうです。 膨大な組み合わせから候補を探すという「0を1にする」部分においては専門家が取り組んでもとても時間がかかる部分ですが、専門家よりもたとえ精度が劣ったとしても圧倒的な早さで候補を挙げてくれるとすれば大きな成果となるでしょう。もちろん専門家が取り組んだ場合に比べて使えない候補は多かったと考えられます。ただし使える候補か使えない候補か判断する部分に専門家(人間)が入ることで誤った結果を排除し、 臨床試験 に望むまでを4年半から12ヶ月未満と大幅に縮めることが出来たよい活用事例だと考えられます。 他にも同じような活用事例として、 三菱マテリアル も同様のプロセスで新素材の開発に活用しているようです。 三菱マテリアル は 機械学習 プロジェクトを始める際のビジネス フレームワーク となる 機械学習プロジェクトキャンバス を作成し公開してくれています。今回の取組中にも参考にさせてもらいました。 講談社 のTEZUKA2020プロジェクト www.itmedia.co.jp こちらは2020年2月26日に発表された 講談社 による「 手塚治虫 が新作を作ったらどんな漫画になるだろう」という課題にAIを活用したものです。 こちらも本質的なプロジェクトの進め方は上記の 創薬 プロジェクトと同様で、漫画の軸となるプロットとキャ ラク ターデザインの候補をAIが提示し、それを人間の判断により選び出し制作を行うという流れで取り組んだそうです。 結論 分類と数値予測 入力データの収集が必要 入力データはそのまま使えない、整形には手間とノウハウが必要 従来の方法では手間がかかりすぎることをやらせると良い 「人間ができること」を「間違えることもあるが」「高速に判断できる」 間違えたときのカバーする仕組みが大事 運用を始めると必ず劣化するので監視と再学習が必要 社内勉強会の際に挙がった声と回答 エンジニア、ビジネスサイドを交えた勉強会を社内で実施したときの声をいくつかピックアップします。 Q. プロジェクトに着手して試行錯誤しながらやることを決めると思うけど見積もりできなくない? A. 最初から正確な見積もりはできないのはそのとおりで、段階的に見積もることになります。数段階再見積もりを行うフェイズを計画時に設定し、段階的に精度を上げていくことになると思います。 Q. ユーザーに選択を求めるようなインタフェースで選択結果を正解として再学習すれば精度は上がる? A. 特定のケースに特化して学習してしまう「 過学習 」の状態にならないよう注意が必要です。 過学習 になってしまうと新しい入力パターンに弱くなってしまいます。 「お客さんの利用方法や行動をもとにアップセル候補の抽出に使えるかも。ベテランの勘を実装できれば」 「被検索などのデータから広報施策のタイミングとか見つけられそう」 「逆に 機械学習 ではないけど世間でAIと呼ばれている領域の知識も知りたい」 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com ちなみにハイプ・サイクルにおいて幻滅期は「衰退」「流行の終わり」といった勘違いをしやすい言葉ですが、まったくの逆で「 バズワード が定番技術に変わる準備期間」くらいの認識が正しいです。 ↩ 一般的な説明だと「分類」「回帰」「 クラスタリング 」「次元削減」と言われますが、最初の段階だと「分類」「数値予測」で話をした方が理解しやすいと思います。 ↩ 教師なし学習 とか、もっと言えば深層学習とかだとこの領域にも答えを見つけられるかもしれませんが、今回扱う 教師あり学習 の範囲では人間が判断出来ない問題は解けません。 ↩
こんにちは。 @penguin_no_045 です。 先日開催された[ PHPerKaigi 2020 で登壇させてもらいました。皆様どうもありがとうございます。 資料 speakerdeck.com 「PHPerがこれから「型」とお付き合いしていくために 」というタイトルでした。最近の PHP は型に関する進化が多いような気がしたのでテーマとして選定しました。 また、私の観測範囲内ですが、一時期別の言語ユーザーの間で 静的型付き言語 vs 動的型付き言語 だったり、動的型付き言語は 型推論 が入っているので云々といった話題が見られました。そこで、これからPHPerとして型と触れ合う機会が増える前に知識を整理しておこうと思い立ったわけです。 私はもともと静的型付き言語ユーザーだったので、型システムは身近なものでした。そこで軽い気持ちでプロポーザルをまとめたのですが、実際は今回のセッションの準備中に学んだ知識のほうが多かったです。 概念としてはずっと触れてきたものでも、改めて体系的に学ぶとあやふやな理解をしていた個所などはすぐに化けの皮が剥がれるものですね。 とくに型システムというテーマは不正確な情報がけっこう頻繁に流布されている印象があったので、自分もそうならないように気を付けました。諸先輩方からはどのように映ったのでしょうか? 発表内容について触れると、立て付けとしては型システム入門以前、といった感じになったと思います。そのため、今回のセッションでは簡単のために説明を省いた部分や、意図的にセッションのスコープから除外した領域が結構あります。 型システムに詳しい方は物足りなさを感じられたかもしれませんし、今回のセッションの中でも必要な概念が一部説明できないままの個所もあります。その部分についてはいつか語りたいなと思っています。 また、質疑などでより深い内容について質問をいただくことができ、その場で捕捉したいことを話すことができたのは幸いでした。改めて皆様ありがとうございました。 少しだけの補足 そんな質疑の中で1つ特に印象的だったものがありまして、「 PHP で型安全に配列を扱うには?」というものがありました。 これについてはよくある話で、私も「コレクションを定義するのが良い」と回答しましたが、そこにはたくさんの壁が待ち受けているということを説明できていませんでした。 実際にコレクションライブラリの自作にチャレンジして、 心が折れる 、というのは昔から繰り返されてきたものではないかと思います。( PHP に限らず) そういった際にこういった機能が使えると勝率が上がる、というものを紹介します。 ジェネリクス 現在の PHP でコレクションクラスを作るとしたらどのような シンタックス になるでしょうか。 簡単のためインターフェースなどの定義は省くと、こんなクラスになるでしょう。 class MyCollection { public function __construct () { } //実装は省略 } これでは何も得ることはできないですね。そこでほしくなるのが ジェネリクス です。 型を変数のように扱うことで、コレクションの「中身」の型を決めずにコレクション型を定義できるわけです。 class MyCollection[T] { /** * @var T[] */ private $elements; /** * MyCollection constructor. */ public function __construct () { } //実装は省略 // こうやって使う $foo = new MyCollection[MyType](); これができると、1つのコレクションの定義で色々な型を操作できます。 しかもこの型引数( [T] の T の部分)がインターフェースの場合、継承したクラスをなんでも入れられるという寸法です。便利ですね。 そして沼へ続く ただし、これを便利に使おうとすると大きな問題が発生します。次は引数の型が欲しくなるのです。 たとえば配列関数の中にある array_filter や array_map を実装するとします。するとこう書きたくなります。 // class MyCollection[T] 内 public function filter(closure[T, boolean] $filterFunc): MyCollection[T] { // .... } public function map[S](closure[T, S] $mapFunc): MyCollection[S] { // .... } もう少し便利な関数も追加しましょう。 flatMap というものをご存じでしょうか。これは関数型の考え方が入ったコレクションライブラリではよくある機能(というより基本的な機能)です。 どういう機能かというと、 map して flat にするのですが、ソースを見るとイメージしやすいと思います。 $mapFunc = function($elem){ return new MyCollection($elem, $elem + 1); } ); // 自分と、自分に1足したものをコレクションにして返す $example = new MyCollection(1, 2, 3); $mappedSample = $example- > map($mapFunc); // MyCollection( // MyCollection(1, 2), // MyCollection(2, 3), // MyCollection(3, 4) // ) $flatMappedSample = $example- > flatMap($mapFunc); // MyCollection(1, 2, 2, 3, 3, 4) と、こんな風にネストをはがしてくれるものです。これを実装しようとすると型引数はこのようになります。 // class MyCollection[T] 内 public function flatMap[S](closure[T, MyCollection[S]] $mapFunc): MyCollection[S] { // .... } ね?簡単でしょ?と言わんばかりですが、型を書くことでコレクションライブラリの実装ができそうな雰囲気は伝わりましたでしょうか?さらに言えば、ここまで定義してきた MyCollection をさらに抽象化して、ほかのコレクションや集合、 Optional のようなものを定義できそうにも思えないですか? 共通の概念のようなもの?それは モナド ・・・ これ以上は 関数型プログラミング の世界にも踏み込んでいくことになるので、追いかけるのはこのぐらいにしておきましょう。 まだまだ課題はある もちろんこのままでは型引数を書かないといけない、毎度毎度型を合わせないといけないなど実際に使用していくうえで面倒と感じる部分が多いままです。しかも、こういったときに頼りになる 型推論 は言語の仕組み上安全に実装できないなど、いろいろな壁が立ちはだかってくるでしょう。このような ジェネリクス を導入しただけでは解決できない課題はたくさんあります。そのほかにも様々な トレードオフ と戦わないといけない個所が山のようにありますが、面倒ではあるが安全に倒しきった形でのコレクションライブラリの実装は ジェネリクス があればできそうな予感がします。 まとめ さきほど「面倒」というキーワードが出てきましたが、静的型付き言語のデメリットとしてよく「実装が面倒」ということを上げられます。そうです。これをそのまま使うとその「面倒」を持ち込んでしまうのです。これをもっと便利に使えるようにしたい!となった場合は、より高度な型システムの概念が必要です。これから PHP がどのような方向へ進化していくのかはふんわりと見えている状態ではありますが、高度な型システムを獲得できるのは少なくともまだ先のこととなるでしょう。当分の間は将来の進化を期待しながら array と付き合っていくのが得策ではないか、と思います。 イベントの話といいつつ、ほとんど ジェネリクス の話になってしまいましたがここまでとします。 今回のイベントで関わってくださった皆様、本当にありがとうございました!
先日、弊社がスポンサーとなっている PHPer Kaigi 2020 に、私 Y-Kanoh も参加してまいりました。 PHPer Kaigiとは? 公式サイトによると、 PHP に携わる人が、技術的なノウハウと PHP 愛を共有するためのイベントです。 一般から公募された登壇者の トーク セッションや、アンカンファレンス、懇親会などのイベントが3日にわたり催されていました。 私は開催場所が東京だったこともあり、最終日である3日目のみ参戦させていただきました。 会場について すでに二日間開催されていたためなのか、会場に到着すると、すでに活気付いた雰囲気がありました。 朝早いはずですが、会場のいたるところにエンジニアが集まりコミュニケーションをとっています。 これは、なんといっても今回取り入れられた トレーディングカード が大きいと思います。 この トレーディングカード は、上記のように、入場と同時に他 ノベルティ と共に1人100枚配られます。 配られた100枚のカードには、その参加者の Twitter アイコンが印刷されており、会場内ではこれを他の参加者と交換することが推奨されます。 なにせ100枚もあるので、躊躇していては交換しきれません。参加者はお互いにこのカードを配りきることを目的に他の参加者とコミュニケーションをとる必要があり、他者へ話しかけるハードルがとても下がりました。 このカードを用意するためには、参加者全員分のアイコンを取り込み、カードを印刷する必要があると思います。運営スタッフ皆さまは大変だったと思いますが、このカードのおかげで、セッション外の時間でも始終盛り上がっていたと感じました。 私自身も、オープニングが終わったと同時にカードの交換を申し込まれ、他エンジニアの方と交流することができ、最終的には配られたカードの半分ぐらい交換することができました。 セッションについて 参加した日は、弊社のエンジニアが登壇した「PHPerがこれから「型」とお付き合いしていくために」や、「Zend VM における例外の実装」など、 PHP の内部構造についてのセッションが多かったように思います。 普段特に意識したことがない PHP のしくみや、仕様の理由などを考えることができました。 さらに PHP の 中間言語 の話まで聞くことができ、とても興味深かったです。 今回は用意されたセッションだけでなく、アンカンファレンスでの トーク にも参加しました。 おそらくほとんどの方がスライドなど用意していないかと思いますが、とても面白い トーク ばかりでした。 LT登壇について イベントの最後は恒例のLT大会です。 私も PHP の RFC の読み方をテーマに登壇させていただきました。 speakerdeck.com 自分の番になるまでは緊張していましたが、前に立った時には比較的落ち着いてお話しすることができました。 (調子に乗って喋りすぎたせいか、演台にタイマーとして使っていた スマートフォン を置き忘れ、私の後に登壇した MasaKu に取ってきてもらいました...) ちなみに、 トレーディングカード を配り切れていなくて焦っていた私は、LTで トレーディングカード 交換の宣伝もしてました(笑) 懇親会について 懇親会では、先に触れた トレーディングカード のおかげで、様々な方と交流することができました。 途中から始まった懇親会LT大会では、私自身が普段業務で関わっている ベトナム とのオフショア開発についての発表があったりと、とても楽しむことができました。 最後に 率直に、とても楽しいイベントでした! 1日のみの参加だったのが残念でしたが、 トレーディングカード や懇親会を通じてたくさんのエンジニアとコミュニケーションが取れ、有意義な1日だったと思います。 来年もぜひ、参加します!!
新卒2年目のyk_itgです。早いもので社会人2年目も残り1ヶ月となりました。 パフォーマンスチューニングの開発をする際に、indexはどのようなカラムに貼るのが良いのか気になったので、今回はそこで調べたことを書いてみます。 PostgreSQL のバージョン: 11.5 まずはindexを貼ってみる indexを使ってみる カーディナリティ カーディナリティを変えて比べてみる 参考資料 まずはindexを貼ってみる まずはindexを貼るためのテーブルを作っていきます。 テーブルには主キーのidの他に以下の2つのカラムを定義します。 sequence_number 一意な数字が入る2つのカラムを持つテーブルを用意します。 type 3種類の値(1, 2, 3)のいずれかが入る CREATE TABLE test ( id integer primary key, sequence_number integer , type integer ); そのテーブルに1つのtypeごとに100万件、計300万件のレコードを入れて、 INSERT INTO test(id, sequence_number, type ) SELECT i, i, ' 1 ' FROM generate_series( 1 , 1000000 ) AS i; INSERT INTO test(id, sequence_number, type ) SELECT i, i, ' 2 ' FROM generate_series( 1000001 , 2000000 ) AS i; INSERT INTO test(id, sequence_number, type ) SELECT i, i, ' 3 ' FROM generate_series( 2000001 , 3000000 ) AS i; sequence_numberとtypeの2つのカラムにindexを貼ります。 CREATE INDEX index_test_number ON test(sequence_number); CREATE INDEX index_test_type ON test( type ); indexが貼れたかどうかは、システムビューのpg_indexesで確認できます。 postgres=# SELECT * FROM pg_indexes WHERE tablename = 'test'; schemaname | tablename | indexname | tablespace | indexdef ------------+-----------+-------------------+------------+----------------------------------------------------------------------------- public | test | test_pkey | | CREATE UNIQUE INDEX test_pkey ON public.test USING btree (id) public | test | index_test_type | | CREATE INDEX index_test_type ON public.test USING btree (type) public | test | index_test_number | | CREATE INDEX index_test_number ON public.test USING btree (sequence_number) (3 rows) 主キーのカラムにはindexが元々 付いているようです。 indexを使ってみる 作ったindexがどのように使われているのか EXPLAIN ANALYZE で確認していきます。 比較をしやすいようにindexを貼る sequence_number と type を WHERE句に入れて、まずは何も貼っていない状態で試してみます。 実行前に ANALYZE を忘れずにしておきましょう。 また、indexを使ってもらえるようにenable_seqscanを off にし、見やすいようにパラレルクエリもoffにしておきます。 ANALYZE test; SET enable_seqscan TO 'off'; SET max_parallel_workers_per_gather TO '0'; EXPLAIN ANALYZE SELECT id, sequence_number, type FROM test WHERE type = 1 AND sequence_number = 1000000; ---------------------------------------------------------------------------------------------------------------------- Seq Scan on test (cost=10000000000.00..10000061217.00 rows=1 width=12) (actual time=87.978..235.451 rows=1 loops=1) Filter: ((type = 1) AND (sequence_number = 1000000)) Rows Removed by Filter: 2999999 Planning Time: 0.124 ms Execution Time: 235.470 ms (5 rows) 235.470 ms とそこそこ時間がかかっていることがわかります。 続いて2つのカラムにindexを貼った状態で試してみます。 EXPLAIN ANALYZE SELECT id, sequence_number, type FROM test WHERE type = 1 AND sequence_number = 1000000; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- Index Scan using index_test_number on test (cost=0.43..8.45 rows=1 width=12) (actual time=0.022..0.023 rows=1 loops=1) Index Cond: (sequence_number = 1000000) Filter: (type = 1) Planning Time: 0.168 ms Execution Time: 0.044 ms (5 rows) 何も貼っていない状態と比べると、 235.470 ms と 0.044 ms で何倍も早くなっていることがわかりますね! ただ、sequence_numberだけでなく、typeにもindexを貼ったのに使われていません。 今度はtypeにだけindexを貼った状態で試してみます。 EXPLAIN ANALYZE SELECT id, sequence_number, type FROM test WHERE type = 1 AND sequence_number = 1000000; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- Index Scan using index_test_type on test (cost=0.43..36304.43 rows=1 width=12) (actual time=184.283..184.284 rows=1 loops=1) Index Cond: (type = 1) Filter: (sequence_number = 1000000) Rows Removed by Filter: 999999 Planning Time: 0.526 ms Execution Time: 184.341 ms (6 rows) 今度はtypeのindexを使ってくれました! ただ、indexを貼ったのにも関わらず、 235.470 ms から 184.341 ms に代わっただけで、sequence_numberの方の 0.044 ms と比べるとほとんど効果が出ていないことがわかります。 この違いは何でしょうか。 カーディナリティ typeのindexの効果が出ない理由は、テーブルの行数に対してtypeのカーディナリティが低いためです。 カーディナリティ *1 とはそのカラムにある値の種類の絶対値(今回のtypeの場合は 3 )のことを指します。 テーブルの行数 300万 に対して、typeのカーディナリティは 3 しかなかったため、ほとんど効果が出なかったわけです。逆に一意でカーディナリティが高いsequence_numberのindexではかなり効果が出ています。 カーディナリティを変えて比べてみる 行数は300万のままで、typeのカーディナリティを変えて何パターンか実行してみました。 結果は以下のようになりました。※実行時間は同じ環境でも変動があります。 typeのカーディナリティ indexありの実行時間(ms) 2 324.752 3 223.665 4 193.7 10 66.488 100 6.953 1000 1.064 10000 0.073 100000 0.034 カーディナリティが1000を超えたあたりからだんだん効果が薄くなっていくのがわかります。 参考資料 カーディナリティについてまとめてみた https://qiita.com/soyanchu/items/034be19a2e3cb87b2efb カーディナリティ https://www.shift-the-oracle.com/words/cardinality.html 用語集 http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19217-02/glossary.htm 41.32. pg_indexes https://www.postgresql.jp/document/8.0/html/view-pg-indexes.html postgreSQL でインデックス一覧の表示 https://hacknote.jp/archives/2474/ エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com *1 : 問合せの結果行数を指すこともあるそうです
はじめに こんにちは。aa_cryingです。早いもので、4月で入社して3年目になります。 2020/2/13-14 で実施された Developers Summit 2020 に参加してきましたので、 event.shoeisha.jp 今回はそのレポートとして、 聞いてきたセッションの内容の紹介と感想を残していこうと思います。 はじめに Developers Summit とは? セッション内容を紹介 【14-D-5】マルチクラウドに向けてNGINX活用促進する為に知っておいてほしいこと 【14-E-6】生涯イチ・エンジニアとして好きな技術でジャンプアップし続けよう - 夢のつづきはビッグデータで 【14-E-7】月間約10億件のクラッシュデータから見えたアプリ品質の実態! エンジニアが仕掛ける、『ONE TEAMで挑む、賢いアプリの品質管理』とは? 終わりに Developers Summit とは? 翔泳社 が主催されており、「技術者コミュニティとの連携から生まれた総合ITコンファレンス」というテーマで年に数回開催されています。 総合コンファレンス ということもあり、内容は技術寄りの話から、サービス運用の話、マインド的な話など多岐に渡っていました。 数あるセッションの中から3つのセッションを選び聞いてきたので、それらの紹介をしようと思います。 セッション内容を紹介 【14-D-5】マルチ クラウド に向けてNGINX活用促進する為に知っておいてほしいこと まず1つ目は技術寄りのセッションになります。こちらは マルチ クラウド ・ NGINX というワードに惹かれて選んだセッションですが、 思ったより技術寄りの内容でした。 まだスライドが公開されていませんので、内容を軽くご紹介しますが、 内容の趣旨としては「NGINXはこんなこともできます」という紹介でした。 DockerコンテナやJenkins等と連携してNGINXを利用することが出来ますよーと話や GKE ( Google Kubernetes Engine) や AKS (Azure Kubernetes Service) 上ではこういう活用が出来ますよーという話がありました。 2年目エンジニアの私には首をひねる内容が多かったですが、終了後に調べ、GKEや Kubernetes 等の技術について知り、興味を持つきっかけになりました。 新たに追加された機能である External Name についてはデモを交えて説明していただき理解できましたし、画期的なシステムだなと思いました。 External Nameを使用することで、部分的に (このバージョンのみ等)他の クラウド サービスを使用したりといったことが可能になるそうです。 また、マルチ クラウド で共通の設定をすることが可能なので、マルチ クラウド を管理するのが便利になりそうだなと思いました。 【14-E-6】生涯イチ・エンジニアとして好きな技術でジャンプアップし続けよう - 夢のつづきは ビッグデータ で 2つ目のセッションはマインド的な話でした。 こちらはスライドが公開されていましたので、詳細は以下をご覧いただければと思います。 speakerdeck.com 私の中では以下の話が印象に残りました。 常にホームランを打つという強い意志は大事だが、結果は三振だろうが気にしない。 (結果を出すためには失敗を恐れない) 「こうなりたい」ではなく、「なるんだ」という強い意志が大事。 まずは小さな夢・目標でいいから立てて、それを叶える・達成していくことでジャンプアップ(成長)できる。 心が折れないように趣味等で自分をケアすることが大事。 「結果を出すためには失敗を恐れない」ということの例えで アダム・ダン 率の話が出てきたりと、野球に例えて表現されるのが面白かったです。 33-4 も出てきました (笑) 好きな技術でジャンプアップ の前に、私はまず好きな技術を見つけるために様々な技術を学んでいきたいです。 【14-E-7】月間約10億件のクラッシュデータから見えたアプリ品質の実態! エンジニアが仕掛ける、『ONE TEAMで挑む、賢いアプリの品質管理』とは? こちらは スマホ アプリのサービス運用の話になります。 こちらもスライドが公開されていないため、内容を簡単に説明させていただきます。 登壇された方は スマホ アプリのエラー解析ツールである「SmartBeat」というツールの開発チームに属している 本ツールでは1ヶ月に10億件以上のエラーを検出している アプリのクラッシュが起こるとそれが★1レビューに繋がり、最終的にはユーザーが離れていってしまう アプリのクラッシュはアプリを使わなくなる理由の7割にものぼる データの消失が起きてしまったりすると大惨事に... なぜクラッシュするのか Android の場合 → 端末依存のクラッシュが多い 全ての Android 端末を集めてテストする、というのは難しい。 iOS の場合 → iOS のアップデートによりクラッシュの発生や再現が変わってくる クラッシュしないためには エラーの検知率を上げる (アラートメールや本ツールの使用等) すぐ直す・直さないの判断や、どこから直すかの判断を的確に行う 影響を最低限にとどめる工夫が大事 エラーが分かっておりすぐに直せない場合は早めにアナウンスする等 私が関わっている製品でもアプリを配信しているので、他人事ではないなと思い申し込みをしました。 また、私達のチームでは クラッシュしないためには に記載されている事項は的確に行われており、 サービス運用については上位者の皆さんにさすがの一言です。 終わりに このような大きなカンファレンスには初参加でしたが、学びやエンジニアとしてのモチベーション等得られるものが多く、また行きたいと思えました。 案内があった後すぐに動けず、題名や登壇者名から「気になる!」と思い申し込もうとしたら 既に満員 になってしまっているということが多かったのが心残りです。 次回以降は気になるセッションに参加できるよう、すぐに動きたいと思います。
id:logy0704 です。 もうすぐJava14がリリースされますね。 いくつかの変更が予定されていますが、その中でも今回はswitch文の変更についてご紹介しようと思います。 *1 そもそもswitch文って? 従来のswitch文の課題 fall through ブロック 文であること これからのswitch 矢印構文の導入 式として扱えるように 最後に 参考 そもそもswitch文って? Java を学んだことのある方ならば一度は触れたことがあるかと思います。 以下のような形式で複数分岐を表現することができ、特に Enum と組み合わせて使われることが多いです。 switch(case) { case1: hoge; break; case2: huga; break; default: piyo; } 従来のswitch文の課題 fall through switch文ではマッチしたラベル以降の分岐がすべて実行されてしまいます。 一つの分岐のみ実行したい場合にはbreak文を追加してあげる必要があります。 *2 ブロック switch文ではブロック全体が一つのスコープとみなされるため、変数名の競合や想定外の再代入が発生する可能性がありました。 *3 文であること switch文(switch statement)と表現されるように、これまではswitchは文としてのみ扱われてきました。 *4 そのため、条件によって変数を変化させたい場合、switch文をそのまま変数に設定することはできず、一度、switch文の中で変数に値を設定してから利用する必要がありました。 int hoge; switch(case) { case1: hoge = "huga"; break; case2: hoge = "piyo"; break; default: } System.out.println(hoge); これからのswitch これらの課題を解消するため、switchに変更が加えられました。 *5 ※ サンプルコードは https://openjdk.java.net/jeps/361 から引用させていただきました。 矢印構文の導入 ラムダ式 で見かけるような矢印を使った記法が導入されました。 switch (day) { case MONDAY, FRIDAY, SUNDAY -> System.out.println(6); case TUESDAY -> System.out.println(7); case THURSDAY, SATURDAY -> System.out.println(8); case WEDNESDAY -> System.out.println(9); } label -> 実行したい内容 という構文でそれぞれの条件分岐を表現することができます。 カンマ区切りで複数のラベルを並べることで、複数ケースにマッチする条件も表現できます。 この構文の場合、break文は必要とせず、一度条件にマッチした後、switchから離脱します。 見た目もスッキリするだけでなく、うっかりbreak文を書き忘れて想定外のバグが…なんてことがなくなりますね。 また、変数のスコープもそれぞれの矢印の右辺に閉じるため、変数名の重複等に気を使う必要がなくなりました。 式として扱えるように switchの結果を引数に渡したり、変数に格納することが出来るようになります。 static void howMany(int k) { System.out.println( switch (k) { case 1 -> "one" case 2 -> "two" default -> "many" } ); } 最後に switchの新たな記法についてご紹介しました。 Java14はLTSではないため、まだ導入される方は少ないかもしれませんが、将来的に利用できる記法として頭の片隅に置いておくと良いかもしれません。 参考 JEP 361: Switch Expressions Java SE 12の拡張switch文/式の完全ガイド エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com *1 : Java12からプレビュー版として提供されていた内容ですが、フィードバックを経てJava14で正式導入されます。 *2 : あえてbreak文を書かないことで複数の条件にマッチさせるような書き方もできます。 *3 : 各ラベルごとにブロックを区切ってあげることで回避する方法が一応存在します。 *4 : Java における文の正確な定義については Oracle社公式ページ を参照してください。 *5 : 正確には課題の解消だけでなく、現在プレビュー中のパターンマッチング機能への布石としての側面もあるようです。
こんにちは!遅くなってしまいましたが、今回は1月21日に行われたビアバッシュのご紹介をします。 今回のビアバッシュは自由枠の発表とLTの構成となっております。 発表一覧 自由枠 情報管理アプリ「Notion」 へんな Scala ドメイン 駆動設計を支える アーキテクチャ テスト LT git switch & git restore PHPerKaigi2019の参加がきっかけで社内勉強会を主催するようになった話 発表内容 情報管理アプリ「Notion」 サンフランシスコにオフィスを構えるNotion社が開発した情報管理アプリ「Notion」について紹介してくださいました。 議事録などのテンプレートを用意することができるなど便利な機能がそろっています。 非常に柔軟でアイディア次第で何でもできるアプリですが、柔軟すぎるがゆえに迷うこともあるそうです。 へんな scala 今月も Scala が好きなエンジニアが Scala について語ってくださいました。本発表では Scala の処理系について紹介してくださいました。 Scala .js   Scala をJSにトランスパイルすることができます。 ScalaNative   Java スタンダードライブラリを一部使用することができます。 Ammonite   Scala で スクリプト を書くことができます。replだけでなく、shellも書くことができます。 Dotty   Scala の新しい処理系。 コンパイル 速度が速くなります。 Scala .net  NET用の実行ファイルを作成します。公式サポートされていましたが、2012年でサポートが終了しました。 ドメイン 駆動設計を支える アーキテクチャ テスト 2/16に開催されたOOC2020の先取りの発表をしてくださいました。 Java と アーキテクチャ テストツールの ArchUnit を用いた ドメイン 駆動な アーキテクチャ 設計を運用する方法についてのお話です。 また、 PHP の アーキテクチャ テストツールの紹介もしてくださいました。 こちらが実際にOOCで発表されたスライドなので気になる方はどうぞ。 speakerdeck.com git switch & git restore Git2.23の新機能で、gitのブランチを変更する「switch」とファイルを変更する「restore」コマンドについて紹介して頂きました。 「switch」と「restore」は「checkout」を分割した機能です。 ただ本人曰くcheckoutの方が打ちやすいらしいです PHPerKaigi2019の参加がきっかけで社内勉強会を主催するようになった話 若手エンジニアがPHPerKaigi2019に参加したことがきっかけで開催した社内勉強会についてのお話です。 勉強会を開催したきっかけや開催してよかったこと、気づいたことなどを語ってくださいました。 勉強会の開催を実行、継続する難しさを発表から感じました。 終わりに 今回のビアバッシュではGitの便利な機能など、業務の役に立ちそうなものや、 勉強会開催で得たものについての発表などためになる話を聞くことができました。 今後もビアバッシュの内容をブログに掲載しますので、どうぞお楽しみに!
はじめに こんにちは。新卒2年目のmrym_618です。 最近業務で Chrome 拡張の「Stylus」を使い、 CSS の設定とデザインの変更を行うことがありましたので、 今回はその使い方について紹介していきたいと思います。 はじめに Stylusとは インストール方法 CSSの設定方法 おわりに Stylusとは Stylusとは、特定の CSS をブラウザ側で設定するための Chrome 拡張機能 です。 インストール方法 インストール方法は、以下のサイトより chrome.google.com Chrome ウェブストアを開き、「 Chrome に追加」を押してインストールするだけです。 インストールが完了すると以下の画像のようなアイコンが表示されます。 CSS の設定方法 CSS を設定したいサイトを開いたままインストール完了後に表示されるようになったSのアイコンをクリックします。すると以下のようなダイアログが表示されますので、赤枠のように CSS を設定したいURLをクリックします。 すると、スタイルの編集画面が表示されますので、実際に適用したい CSS を記述します。 今回は、このサイトのタイトルと注釈の色を変更してみたいと思いますので、以下のように記述します。 .header-image-enable #blog-title #title a { color : #000000 ; } .header-image-enable #blog-title #blog-description { color : #000000 !important ; } CSS 設定後、Sアイコンで表示されるダイアログにチェックを入れることで CSS を適応することができます。 CSS の適応を無効にしたいときは、 チェックボックス のチェックを外すかすべてのスタイルをオフにするにチェックを入れることで無効にすることができます。 CSS を編集したい場合は、鉛筆マークを押すことで編集画面に遷移することができます。 おわりに 今回は、 CSS を設定することで自由にデザインの変更をできるStylusについて紹介しました。 Stylusを使い自分独自の CSS を設定することで、Webサイトを見やすくて使いやすいようにカスタマイズすることができますので、皆さんもぜひ試してみてください。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
はじめに こんにちは、 MasaKu です。 PHPer による PHPer のためのお祭り、 PHPerKaigi が今年も開催されました。 (弊社もスポンサーをさせていただいております) PHPerKaigi2020 phperkaigi.jp 今回は LT にチャレンジさせていただいたのですが、登壇にあたり様々な学びがありました。 本記事では、LT にチャレンジする上で学びにつながった以下のポイントについて記載していきたいと思います。 本記事で記載する内容 トーク テーマの選定 発表資料の作成 LT 発表 登壇資料 speakerdeck.com 参加にあたって 去年の PHPerKaigi2019 には一般参加という形で参加させていただいており、大変興味深い発表ばかりだったので、 「来年こそはぜひスピーカーに!」 と意気込んでおりました。 去年の参加レポートは こちら tech-blog.rakus.co.jp 実は昨年開催された PHPerKaigi2019 のプロポーザルにも挑戦していたのですが、残念ながら非採択という結果になってしまっていました。 そのため、今年の開催で トーク が採択された時は嬉しさ半分驚き半分といった気持ちでした。 なお、昨年度の トーク テーマは以下です。 Laravel + MongoDB でつなげる、つながるオープンデータ エンジニアとしての成長を加速させた3つの取り組み fortee.jp fortee.jp プロポーザル応募 今回のプロポーザル募集にあたり、話したい トーク テーマはすぐに思いつきました。 というのも、PHPerKaigi の参加がきっかけで社内で行った上映会からいろいろな活動を開始するようになったので、その経過報告をしようと考えていたからです。 社内のビアバッシュでも何度か発表したテーマでしたが、今回の PHPerKaigi2020 でも発表することができれば最高だなあと考えていたためです。 しかし、どのような展開で話していけば盛り上がるかという視点はサッパリだったので、 トーク の方向性についてはブレブレでした。 個人としてのモチベーションの変化を話すべきか 勉強会開催にあたってのノウハウを話すべきか テーマ検討で トーク を聞いてくださる方に受けそうなのはどちらか、自分として話しやすいのはどちらか、という視点でテーマ選定を行っていきました。 発表資料の準備 トーク が採択された後は発表資料の準備を始めましたが、弊社で定期的に開催している MeetUP という社内イベントで登壇した経験があったため、どのように話を構築していくと資料が作りやすいかというノウハウがあったため、資料作りはスムーズに進みました。 イベントページ rakus.connpass.com 登壇資料 speakerdeck.com 今回の登壇資料の作成は以下のような流れで進めました。 トーク テーマの再確認 伝えたいポイントを大きく書き出す そのポイントを一番盛り上げられそうな話の展開を考える 箇条書きレベルで話を整理してアウトラインを作成する アウトラインをレビューしてもらう レビュー結果を元にスライドを作成する 個人的に一番大切だと思うのは 4 番目の内容です。 箇条書きレベルで話がまとめられていると、それをスライド化するのは非常に容易です。 「それならスライドを作りながら内容を整理しても同じなのでは?」と思うかもしれません。 これは個人的な感覚ですが、 グラフィカルなアウトプットができてしまうと伝えたいポイントが見えにくくなる気がするので、まずは文字ベースのアウトプットを作成するのが良い と思っています。 逆に、文字ベースでも自分の話たい内容がきちんと整理できていればそれをスライド化するのは難しくなく、むしろ、図的な説明も可能になるので、自分としてもより納得できる説明を組み立てられるようになります。 発表練習 発表練習は個人でやるのも大切だと思いますが、やはりフィードバックをもらえる環境で実践するのが最適です。 幸いにも今回は発表練習をする機会が豊富だったので、実践的な練習を繰り返すことができました。 今回、発表練習を通して得た教訓としては、LT で登壇するう上で特に気をつけなければならないポイントは以下のように感じました。 ウケを狙うポイントはちゃんと意識すること 画面を読んでいるときはどこを読んでいるのかを分かるようにすること 5 分間フルで使い切ること 特に、 5分間をフルで使い切ること は大切だと感じました。 通常の発表の場合は話たい内容を時間内に収められるように簡潔に話すことが重要かと思いますが、様々なカンファレンスのLTを見て感じることとしては、 LT では 5 分間という時間を綺麗に使い切ることのほうが芸術点が高い ように感じておりました。 そのため、タイムキーパーの「終了です!」の一言と同時に発表をキレイに切れるように、最後のスライドに向けてどれくらいの時間を残すかということを意識して練習するようにしました。 登壇してみて PHPerKaigi2020 登壇風景 LT の会場には推定 200 人を超える参加者の方がいらっしゃったように思います(もっと多かったかも) このような大勢の前で発表した経験がこれまでなかったこともさることながら、カンファレンスでの登壇も初めてでしたので非常に緊張した 5 分間でした。 練習通りにできたところもあれば、自分で何を話しているのかすらわからなくなるような場面もありましたが、非常にいい経験になったと思っています。 会場内から笑いの声や拍手が聞こえてくると勇気づけられるような感覚があった ので、今後、こういったカンファレンスに出席する際は、 リアクション増しを意識 していきたいと思いました。 最後に いつかはスピーカーとして登壇したいと思っていたカンファレンスに出ることができてとても良い経験ができたと思っております。 発表内容について Twitter でたくさんのリアクションをいただいておりましたが、自分が想像していた以上に発表内容に共感していただけたようで嬉しかったです。 イベントを通して様々な方と交流することができたこともとても良い経験になったと思います。 今回の PHPerKaigi2020 での登壇をきっかけとして、また次のステップに向けて再チャレンジしていければと思います。 参考サイト PHPerKaigi 2019 PHPerKaigi 2020
こんにちは。新卒2年目のbadaikiです。業務でできることが徐々に増えていくなかで、まだまだ自分はできていないなと感じる日々を過ごしております。 はじめに オールペア法とは テストケース生成ツール PICT(Pairwise Independent Combinatorial Testing tool) pairwiser おわりに はじめに 前回ではテストの網羅率の向上、可視化するディシジョンテーブルについて記事を書きました。 tech-blog.rakus.co.jp ディシジョンテーブルは網羅率は高められるものの、ターゲットによってはすべてのケースを消化するだけでとんでもない 工数 がかかってしまうことがわかりました。 そこで今回はどうすればケース数を減らし、効率的にテストを実施できるかについて調べてみました。 以前私がテスト実施から参入した開発で、先輩社員がケースを作成したものを複数人で実施していくということがありました。条件がかなり複雑に絡み合う機能であったため、ケース数が爆発しているんだろうなーと予測していたのですが、いざケースを確認してみると予測していたケース数の1/3ほどのケース数で驚きました。聞くとオールペア法を活用していました。 オールペア法についてはケース数が減るよ。という知識しかなく、なぜ減らせるのか、漏れは起きないのかということまで理解できておりませんでしたので、この機に調べてみようと思いました。 オールペア法とは オールペア法(ペアワイズ法ともいう)とは組み合わせテストの技法の1つです。 組み合わせテストとは、多数の入力条件の値をいろいろと組み合わせて実施するテストです。しかし前項でも述べたように、全ての入力条件で値の組み合わせを考えると、膨大な数になり全てをテストするのは現実的ではありません。例えば3つの選択肢があるプルダウンが4つあり、その組み合わせだけで 3の4乗 = 81ケース となるわけです。81ケースと聞くとできそうな気がしますが、それぞれが4つの選択肢になるだけで256ケースと3倍以上に増えてしまいます。 以降ではプルダウンのような入力条件を因子、その値を水準と呼びます。 ある文献 *1 ではソフトウェアのバグの7割から9割が1つまたは2つの因子の組み合わせによって発生していることが記されています。以下がそれを示した表です。 要因数 組込み機器(医療系) ブラウザ( Netscape ) サーバ( Apache ) データベース 1 66 29 42 68 2 31 47 28 25 3 2 19 19 5 4 1 2 7 2 5 2 0 6 1 4 そこで2つの因子の組み合わせをつくり、すべての水準の組み合わせのケースを作成するのがオールペア法という技法です。 例えば、プルダウンが3つの組み合わせを考えてみます。 因子 水準 プルダウンA 0,1 プルダウンB 0,1 プルダウンC 0,1,2 これの全組み合わせは 2 * 2 * 3 = 12ケース 。 これをオールペア法で作成するには 1. まずそれぞれの因子のペア(AB、AC、BC)を作成し、水準の組み合わせの全パターンを作成します。 AB AC BC 00 00 00 01 01 01 10 02 10 11 10 11 11 12 2. 1で作成した水準の組み合わせをAB列から順に取り出します。 No A B C 1 0 0 2 0 1 3 1 0 4 1 1 3. 次にAC列、BC列と順に当てはまる行に割り付けていきます。このときに着目しているペア以外のペアも同じ組み合わせが現れないように割り付ける必要があり、これがケース数を最小にするために重要です。←これがややこしいです。例えばAC列の(10)を割り付けるとき、(1,0,0)の組み合わせではなく、(1,1,0)の組み合わせにします。AC列の(00)を割り付けるときに(0,0,0)の組み合わせが既に出来上がっており、BC列の(00)が2か所で作成されてしまうためです。 No A B C 1 0 0 0 2 0 1 1 3 1 0 1 4 1 1 0 5 0 0 2 6 1 1 2 このようにオールペア法で作成すると今回の例ではケース数が12ケースから6ケースと半分になりました。ただし、理屈がわかっても実際自分で作成しようとすると難しいです。。。加えて、実際のシステムでケース作成を行う場合には、A=0のときはB=0になるなどの制約条件があるとさらに複雑になってきます。上記の例は簡単な例でしたが、複雑になっていくと考えるを諦めてしまいそうですよね。実は制約条件も考慮して自動生成してくれるツールが提供されています! テストケース生成ツール オールペア法のテストケース生成ツールは多く提供されており、以下のサイトにまとめられていました。ここで紹介されているツールだけで現在51種類もあり、驚きました。この中で PICT と pairwiser について使い方を紹介したいと思います。 http://www.pairwise.org/tools.asp www.pairwise.org PICT(Pairwise Independent Combinatorial Testing tool) http://www.pairwise.org/tools.asp 特徴: 無料 Microsoft 社が開発 コマンドプロンプト で実行する 多機能 ダウンロードするとHTMLのマニュアルがついてくる(英語) 使い方: 1. パラメータを定義する PICTではモデルファイルと呼びますが、txtファイルで作成します。 基本的なモデルファイルは、末尾が : で終わるパラメータと、 ⁠, で区切られた値の並びとからなるモデル定義部のみで構成されます。 A: 0,1 B: 0,1 C: 0,1,2 2. 1で作成したファイルをpict.exeで実行する。 pict test.txt これだけです。 すると以下の結果が出力されます。 A B C 1 1 1 0 0 0 1 0 1 1 1 0 1 1 2 0 0 2 0 1 1 結果をリダイレクトする場合には以下で実行できます。 pict test.txt 1>result.txt 2>error.txt 1 は出力結果、 2 はエラーが発生したときにエラー内容が出力されます。 制約条件を設定する場合にはモデルファイルの末尾に制約条件を追記します。記述方法は独自の スクリプト言語 が用いられており,因子を [] で囲み,水準が文字列の場合は, " で囲み, ステートメント の末尾は ; で終わります。条件にはパラメータと値の関係を評価する関係式を用いて 条件付き制約 と必ず成立する 無条件制約 があります。 #パラメータ定義 A: 0,1 B: 0,1 C: 0,1,2 #制約条件定義 #条件付き制約 if [A] = 1 then [C] <> 2; #無条件制約 [A] <> [B] or [A] <> [C] or [B] <> [C]; 上記のモデルファイルで実行すると以下のケースが出力されます。制約条件通り、A=1の場合はC=2にはならず、A=B=Cになるケースは作成されません。 A B C 0 0 1 0 0 2 0 1 0 0 1 1 1 0 0 0 1 2 1 0 1 1 1 0 pairwiser Pairwiser - Pairwise Testing and Test Generation Tool 特徴: 無料(ユーザ登録が必要) INDUCTIVE社という ノルウェー の企業が開発しているWebアプリケーション カバレッジ などの解析が容易 生成したケースをエクセル形式でダウンロードできる pairwiser 使い方: 基本的に、左から右へタブに必須情報を入力してテストケースを生成します。それぞれのタブの「Save」ボタンを押さないとデータが保存されません。また、データが保存されていないタブよりも右側のタブの内容は更新が効かないようになっています。 Webアプリのため、直感的に操作がやりやすいです。 Define Parameters タブでパラメータ定義や制約条件を設定でき、 Generate Tests タブでケース作成ができます。 Generate Tests タブの上部にある Export to Excel ボタンをクリックすることで Excel ファイルもダウンロードすることができますので、業務でテストケースを Excel で書かれている場合にはそのまま活用することができて便利ですね! pairwiser 結果 また、公式ページには チュートリアル やヘルプもあるので、初めてさわる場合でも安心ですね! おわりに 前回のディシジョンテーブルに引き続き、今回は組み合わせテストのオールペア法について調べ、自動生成ツールを使ってみました。オールペア法について知ることで、なぜそのケース数で十分なのか、どのように作成されているのかが理解できました。また、自動生成ツールを用いることで制約条件など細かな設定も行え、ツールによっては Excel ファイルに変換してくれるなど、人手で行うよりもとても効率的にケース作成が可能だとわかりました。今後、条件が複雑に絡み合う機能のテストではオールペア法を用いて網羅性を保証しつつ、効率的に進めていこうと思います。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com *1 : R.D.Kuhn et al.“⁠Software Fault Interactions and Implications for Software Testing,⁠”⁠ IEEE Transactions on Software Engineering, 30(6), June 2004
はじめに こんにちは。choreiiです。最近自チームで扱っている商材のフロントエンドのテストコードを大量に書く機会がありました。その中で大きくハマった3点について紹介します。 はじめに 環境 1. ライフサイクルフックをmock化(上書き)したい 2. テストによってcomputedを差し替えたい 3. localStorageをmock化したい まとめ 参考 環境 Vue:2.6.11 vue-test-utils:1.0.0-beta.29 Jest:23.6.0 1. ライフサイクルフックをmock化(上書き)したい 以下のようにbeforeMountで初期化処理を書いている場合、beforeMountをまるごとmock化(上書き)したくなる時があります。 <script> export default { beforeMount() { // コンポーネントで必要なデータの取得や初期化の処理 } , methods: { sampleMethods() { // 何らかの処理 } } } ; </script> methodsの内容を上書きする時は以下のようにすれば差し替えることができるので、ライフサイクルフックの場合も上書きできると考えていたのですができませんでした。 test( "test" , () => { const wrapper = shallowMount(Sample, { beforeMount() { // これで空の内容で上書きできるはず -> できない。。。 } methods: { sampleMethods() {} // 空の内容で上書きできる } } ); } ); vue-test-utilsのガイドには特に記載がなかったので手元で色々頑張ってみたのですが、下記のissueを発見。 github.com ライフサイクルフックは上書きできないので、処理を上書きしたい場合はbeforeMountの処理をmethodsに切り出して、その切り出した内容を上書きするのが良さそうです。 <script> export default { beforeMount() { this .initData(); // methodsに切り出し } , methods: { initData() { // コンポーネントで必要なデータの取得や初期化の処理 } , sampleMethods() { // 何らかの処理 } } } ; </script> test( "test" , () => { const wrapper = shallowMount(Sample, { methods: { initData() {} , // methodsの方で上書き sampleMethods() {} } } ); } ); ちなみに、shallowMount(mount)した後から、 setMethods を使っても上書きできます。 test( "test" , () => { const wrapper = shallowMount(Sample); wrapper.setMethods( { initData(): {} // 後から上書き } ) } ); 2. テストによってcomputedを差し替えたい 条件が少しだけ異なるテストを書く際に、毎回shallowMount(mount)を行うのはコード記述が増えるのであまりやりたくないです。methodsやcomputedだけを後から差し替える方法があれば完璧です。上記で述べたように、methodsは後から上書きすることができます。 describe( "test" , () => { const wrapper = shallowMount(Sample); test( "test1" , () => { wrapper.setMethods( { sampleMethods(): {} // test1用の処理 } ) } ); test( "test2" , () => { wrapper.setMethods( { sampleMethods(): {} // test2用の処理 } ) } ); } ); setMethods があるなら setComputed もあるだろうと考えていましたが、これまたvue-test-utilsのガイドには記載がありません。 ガイド記載のwrapperのメソッド抜粋 他にもset系のメソッドが用意されていながら、computedだけがありません。。。嫌な予感がしながら情報を探してみると下記のissueを発見(デジャヴ)。 github.com 昔は用意されていたものの、バグがテストをすり抜ける可能性があるので廃止されたようです。バグをなくすためと言われては仕方がないのでテストごとにshallowMount(mount)をするようにしています。 describe( "test" , () => { const render = ((sampleComputedStub), { const wrapper = shallowMount(Sample, { computed: { sampleComputed: sampleComputedStub } } ); } ); test( "test1" , () => { const wrapper = render( { // sampleComputedを上書きしたい処理 } ): } ); test( "test2" , () => { const wrapper = render( { // sampleComputedを上書きしたい処理 } ): } ); } ); 3. localStorageをmock化したい テストでlocalStorageをそのまま使うわけにはいかないので、mockに差し替える必要があります。 localStorageについては以下を参照 developer.mozilla.org jest.spyOn(localStorage, 'setItem' ); spyOnの使い方は間違えていないのに、以下のようなエラーがでてしまいました。 TypeError: object [ methodName ] .mockImplementation is not a function localStorageの中で、setItemが見つからないみたいです。またまた嫌な予感がしましたが今回は解決方法がありました。 stackoverflow.com 以下のように proto を使用するとアクセスできるようです。ただリンク先にも記載がある通り、 proto は非推奨とのことなのであまり多用するのはよろしくなさそう。今回はどうしてもjest.spyOnを使って呼び出し回数や呼び出し引数のテストを書きたかったので使用しています。 jest.spyOn(localStorage.__proto__, 'setItem' ); まとめ Vue/Jestの書き方は公式のガイドが充実しているので、ガイド通りに進めている間はスムーズに進みます。その反面、ガイドに載っていないことをやろうとすると情報がなかなか見つからず痛い目をみることが多かったです。 テストの主目的はプロダクトコードの品質担保なので、あまりテストの書き方を調べるのに時間をかけたくありません。今後は多少記述が増えたり冗長になったとしても、ガイドに従いながらテストを書き、どうしても実現できないことだけ別途調査することにします。 参考 Vue インスタンス — Vue.js ガイド | Vue Test Utils https://jestjs.io/docs/ja/23.x/getting-started エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
次週、都内ではPHPerKaigi 2020が開催されます! ラク スからは3名のエンジニアが登壇することとなりました! また、Silverスポンサーとしてイベント協賛をさせていただいております。 イベント概要 日時:2020 年 2 月 9 日 (日) ~ 11 日 (火) 会場: 練馬区 立 区民・産業プラザ Coconeri ホール( 練馬駅 から徒歩1分) 公式 HP: https://phperkaigi.jp/2020/ ハッシュタグ : #phperkaigi phperkaigi.jp セッションのご紹介 セッション内容とエンジニア3名からのコメントをご紹介します!  やなせ たかし/PHPerがこれから「型」とお付き合いしていくために(30分 トーク ) 日時:2 月 11 日 (火) 11:25 場所:Track A コメント: PHP 界隈でも最近何かと話題に上がる型システムのお話をします。   ・型システム でできること   ・動的型付き言語と静的型付き言語   ・ PHP と型 という内容を予定しています。 fortee.jp 加納悠史/ RFC の歩き方(LT) 日時:2 月 11 日 (火) 15:45 場所:Track A コメント: せっかく東京まで行くので、自身の発表含め最後まで楽しもうと思います。 発表では、興味を持った人でないと近寄りがたい、 PHP の RFC について紹介します。 fortee.jp MasaKu/PHPerKaigi2019への参加がきっかけで社内勉強会の主催するようになった話(LT) 日時:2 月 11 日 (火) 15:50 場所:Track A コメント: 昨年開催された PHPerkaigi2019 に参加させていただいた時から、「次回こそは登壇したい!」と思っていたので、CfPが採択された時は嬉しかったです。 良い発表ができるように、しっかりと準備して登壇に向かいたいと思います。 fortee.jp PHPerチャレンジ また、イベント中にはPHPerチャレンジという企画が開催されます。 会場や関連サイトに散らばった  #任意の文字列  形式のPHPer トーク ンを探して合計スコアを競う、というものです。 blog.phperkaigi.jp 本ブログを読んでいただいた皆様には、 ラク スからのPHPer トーク ンを受け取っていただければと思います! ラク スのPHPer トーク ンはこちらです! ↓ #RAKUSMeetup2020 それでは皆様、当日は弊社エンジニア陣の登壇にご期待ください! itoken1013でした!