TECH PLAY

株式会社ラクス

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

927

こんにちは!新卒のrs_chankoです。 エンジニアとして就職して早半年になります。 大学でもプログラミングを学んだものの、チーム開発は初めて。 就職してから「 バージョン管理システム 」というものに触れました。 とても便利ですよね。 しかしその反面、難しい。 僕が最初にハマった落とし穴。 「git rebase」 です。 間違えて必要のないファイルをpushしちゃった!ってことありませんか? ありますよね?僕はあります。 玄人の皆さんには簡単なことかもしれませんが、 初心者の僕は解釈違いで落とし穴に…。 自分の失敗を繰り返さないよう、超初心者 僕も含め の皆さんにイメージをつかんでもらえたらなと。 ということで、今回は詳しい使い方というより Gitに慣れていない方へ向けイメージをつかみやすいように 僕なりに解釈した「commitを取消すコマンド」についてたとえ話を交えて書いていきたいと思います。 間違えていないといいな イメージをつかむ git reset git revert git rebase おわりに イメージをつかむ プログラマー に必須の力に「想像力」があります。(持論) それぞれどんな挙動を起こすのか。それが想像できないと痛い目を見ます 僕がそうです そしてGItでcommitを取消す方法もいくつかあります。 それぞれ似ているようで少し動きが違うようで。 ここでは3種類のコマンドを紹介したいと思います。 それぞれ「 ハッシュ値 」を、「夏休みの宿題の日記の日付○月×日」としてたとえ話にしています。 git reset イメージとしては 「日記のページを特定の日まで破り捨てる」 感じですかね。 例えば $ git reset --soft [ハッシュ値] このコマンドをたたくと、現時点から、○月×日の翌日までの日記を破り、○月×日の次から今日のことを書く感覚です。 resetのイメージ図 破ったページは捨てずに置いてあるので、戻すことも可能です。 しかし、机の中にしまっておくので、先生(共同作業者)には見られません。(画像ではC~Fがしまってあるような感じ、) ただし「特定の1つのコミット」を消すわけでなく、 「特定のコミットまですべてのコミット」を消すことになるので、注意が必要です。 (作業状態はオプション次第で残せる) git revert こちらは 「日記の特定の日を破り捨て、破り捨てたことを報告するページを一番新しいページに貼り付ける」 といった感じでしょうか。 「日記でそんなこと絶対やらないよ!」とは思いますが… $ git revert [ハッシュ値] このコマンドで○月×日のページを破り捨て、 新たに「○月×日のページ破り捨てたよ~」と最新のページの次のページに付け足します。 先生に怒られそうですね。 revertのイメージ図 しかし、チーム開発では何を削除したのか、これが重要になると思いますので、 とても便利ですね。 (僕はこれを使いたかった) git rebase こちらは 「日記の特定の日を破り捨てて、その日から書き直す」 といった感じ。 どういうこっちゃといった感じですが。 こちら、厄介なことに「HEAD」が移動するのです。 $ git rebase -i [ハッシュ値] こちらをたたくとviに ハッシュ値 以降のコミットが表示され、 各コミットのコマンドを編集することで作業ができます。 例えば○月×日の次の日を削除します。 すると、突如タイムスリップします。(本当に唐突ですがこれがHEADが移動したというやつ) ○月×日の次の日から日記を書くことになるのですが、夏休み最終日、 何故かもう一冊の日記(タイムスリップする前のもの)が存在するのです。 どっちが本物だ、、、となるため、競合が発生します。 rebaseのイメージ図 こんな感じのことが起きています。削除したコミットよりもあとを編集してpushしようとすると コンフリクトが大量発生… 僕はこれで痛い目を見ました。 おわりに そんなこんなでイメージはつかめたでしょうか。 自分の実現したい挙動をするコマンドを探すために 「想像力」が大切。(だと思います) commitを取消するのには気を付けようという話でした。 実践編はまた後日! エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに ラク スに入社して1年のitoken1013です。 ラク ス入社前まで SIer でPM補佐やPMOを経験してきましたが、 この度あらためてプロジェクトマネジメントについて学ぶ機会がありました。 そこで今回は PMBOK を用いて、プロジェクトマネジメントの基礎知識についてご紹介したいと思います。 これからPMを目指す方や、ベテランの方の復習にお役立ていただけますと幸いです。 PMBOK とは PMBOK (Project Management Body Of Knowledge)は アメリ カの 非営利団体 「PMI」が定めた、プロジェクトマネジメントに関する知識体系です。 不確実要素が多いプロジェクトを成功させるために、必要とされる知識を体系的に定めています。 IT業界以外でも PMBOK は活用されており、組織全体におけるプロジェクト管理標準のベースとして PMBOK を採用している企業もあります。 プロセス群・プロセス 最新となる第6版の PMBOK では、プロジェクトの実施に必要な計49種類のプロセスを定めています。 またそれらをプロジェクトのライフサイクルに則した下記5つのプロセス群に分類しています。 すべてのプロセスをご紹介することはできませんが、プロセス群の紹介と共に代表例を挙げていきたいと思います。 普段何らかのプロジェクトに属しながら仕事をされている方であれば、 ご自身の業務に当てはめてイメージいただければ分かりやすいかと思います。 1. 立ち上げプロセス群 対象となるプロジェクトまたはフェーズを定義した上で、関係者から認可を得るためのプロセスです。 認可を得るためには対象となるプロジェクトの目的やスコープを明確化する必要があり、プロセスには「プロジェクト憲章作成」と「 ステークホルダー 特定」の2つが含まれます。 2. 計画プロセス群 プロジェクトでの目標を達成するための計画を具体化するためのプロセス群です。 「プロジェクト計画書作成」「コスト見積もり」「 WBS 作成」など計20プロセスが属します。 3. 実行プロセス群 計画プロセス群で定めた計画に則り、作業を完了させるためのプロセス群です。 プロジェクトチーム内に対するプロセスである「チームの育成」や「品質のマネジメント」の他、 「 ステークホルダー ・エンゲージメント・マネジメント」などチーム外の関係者を含めたプロセスが定義されています。 4. 終結 プロセス群 「プロジェクトやフェーズの 終結 」プロセスが示す通り、プロジェクトを公式に終了するためのプロセス群です。 またプロジェクトで得た教訓(Lessons Learned)を組織の資産として蓄積し、次のプロジェクトの品質向上に役立てていくことが PMBOK では重要視されています。 5. 監視・コン トロール プロセス群 プロジェクト計画通りに上記1~4のプロセス群が進捗するようにコン トロール するためのプロセス群です。 「プロジェクト作業の監視・コン トロール 」「統合変更管理」等のプロセスによって、プロジェクト計画との差異の識別・是正を行います。 プロジェクトマネジメント知識エリア 次にご紹介するのは、各プロセスの実施に必要となる知識をカテゴライズした10種類の知識エリアです。 プロジェクトを円滑に進めるために、マネジメントをすべき分野と言い換えてもよいでしょう。 統合マネジメント スコープマネジメント スケジュールマネジメント コストマネジメント 品質マネジメント 資源マネジメント コミュニケーションマネジメント リスクマネジメント 調達マネジメント ステークホルダー マネジメント 経験上、特に重視しなければならないと考えているのは リスクマネジメント と ステークホルダーマネジメント です。 リスクマネジメントは将来に起こるかもしれないリスクを取り扱い、 ステークホルダー マネジメントは「プロジェクトに反対する人」も含む関係者との関わりを取り扱います。 どちらにも共通する点として自分達からは見えづらい側面、つまり 不確実性 が伴うため、コン トロール が特に難しいマネジメント領域として考えられます。 これらは エンジニアリング組織論への招待 でいうところの 環境不確実性 (未来)と 通信不確実性 (他人)の要素を含んでおり、書籍で触れられているような不確実性に向き合うための思考力と行動力が必要となります。 PMBOK を学ぶことで役立ったこと 断片的にしか理解できていなかったプロジェクトマネジメント知識を体系化できた他、私が PMBOK を学んで日々の仕事に役立っていることは主に3点です。 1. 計画作業の標準化 プロジェクト全体のマネジメントに限らず、特定のフェーズの計画や管理にも PMBOK の知識は有効であると感じています。 ラク スで私が 結合テスト の計画書作成を任された際には、テストを円滑に進めるために必要となる要素を洗い出す際に PMBOK を参考にして構成を練っていました。 計画作業の標準化や客観的に計画を捉える視点を養うためにも、 PMBOK の理解は有効です。 2. プロジェクトの共通認識 体系化されたマネジメント知識をチームメンバー全員がインプットできていると、全員が同じ共通認識のもとでプロジェクトを円滑に進めることができます。 特に多くの ステークホルダー が関わるプロジェクトの場合には、孤独なマネージャーを近い目線で助けられるメンバーはとても重宝されます。 またマネージャー視点からは見えにくいリスクを提起できるメンバーも、計画通りにプロジェクトを進行するために貴重な人材かと思います。 3. 個人タスクへの応用 自身が担当しているタスクの遂行にも、 PMBOK の知識は応用できると考えています。 タスクの前後で関わる人と適切なタイミングでコミュニケーションをとれる、事前に関係者へリスクを共有できる等ができると、円滑に仕事を進められる確率が上がるためです。 コミュニケーションマネジメントや ステークホルダー マネジメントのエッセンスから学べる点は多いかと思います。 ちなみに ラク スの社員はお互いの仕事の影響を考えて動いてもらえる方が多く、エンジニアに限らず、どの社員ともとても仕事を進めやすいと感じています。 まとめ PMBOK をもとにプロジェクトマネジメント知識をご紹介してきました。 実際のプロジェクトでは特有の業務知識や技術知識、現場での経験や勘が要求されるため、これさえ抑えればプロジェクトは成功!とはいかないケースがほとんどのはずです。 ですがプロジェクト実施中に何らかの問題が発生した際、闇雲に解決策を探るのではなく、ベストプ ラク ティスを凝縮した PMBOK を活用することで成功の確率を上げることはできるのではないかと思います。 PMBOK にご興味がある方がいましたら、より詳細な関連書籍を読み進めていただければと思います。 ブログをお読み下さり、ありがとうございました。
アバター
はじめに こんにちは、 @rs_tukki です。上半期も終わったところでこの六ヶ月のうちに書いた言語を数えてみたところ、実に7つもの言語を触っていたことに気づき驚いています。 さて、先日コードを書いているうちに以下のようなことが必要になりました。 「Web上でファイルを選択したと同時に、そのファイルデータをサーバ上で処理させる」 色々実現方法を考えていたのですが、今回はそのための方法として Ajax に触れたのでご紹介します。 はじめに Ajaxとは ファイル選択時に起動するjavascript ファイルをバイナリデータにして送信してみる まとめ 参考 Ajax とは 困ったときの Wikipedia 先生。 Ajax - Wikipedia Ajax (エイジャックス[1][2]、 アジャックス [3])は、ウェブブラウザ内で非同期通信を行いながら インターフェイス の構築を行うプログラミング手法である[4]。 XMLHttpRequest (HTTP通信を行うための JavaScript 組み込みクラス)による非同期通信を利用し、通信結果に応じてダイナミックHTML (DHTML) で動的にページの一部を書き換えるというアプローチを取る[5]。 Ajax とは、 A synchronous Ja vaScript + X MLの略語で、 JavaScript の組み込みクラスを使用することで、ページ遷移をすることなく非同期にサーバとやりとりしたり、ページを書き換えたりする手法を指します。 例えば、入力フォームで郵便番号を入力したとき、自動的にその番号に対応する住所を入力してくれる…といったシステムも Ajax を使っていることが多いです。 ファイル選択時に起動する javascript さて、今回は Jquery を使って ajax によるサーバ通信を行い、ファイル選択と同時にそのファイルデータをサーバに送ってみます。 まずはHTML側から。 file.html < html > : (中略) : < input type = "file" name = "file" onchange="file.fileAttach ( this ) ; return false ;" /> : (中略) : </ html > input type="file" は下記のように、何らかのファイルを選択できる入力フォームです。 これに onchange 属性を組み合わせることで、フォームの中身が変わったとき、つまりファイルが選択された時に任意の javascript 関数を実行させることができます。 ファイルをバイナリデータにして送信してみる 続いて、今回の肝となる javascript の中身を見てみます。 今回、 Ajax の実現には Jquery の ajax メソッドを使用しました。 file.js fileAttach: function (inputFile) { var file = inputFile.files [ 0 ] ; //ファイルデータを取得 var url = 'https://hogehoge.co.jp' ; //リクエスト先を指定 var reader = new FileReader(); var formData = null ; reader.onload = function () { formData = reader.result; } reader.readAsBinaryString(file); setTimeout(() => { $.ajax( { url: url, cache: false , //キャッシュを使用しない type: "POST" , data: { "formData" : formData, } , } ).done( function (data) { //成功時 console.log( "success" ); } ).fail( function () { //失敗時 console.log( "failed" ); } ); } , 500); //少し待ってから実行する } , 発火元の入力フォームからファイルを取得してきて、それをバイナリデータに変換しています。 FileReader は javascript でファイルデータを扱うためのオブジェクトで、今回はonload=読み込みが完了したタイミングでバイナリ文字列を取得しています。 そのデータをパラメータに格納して Ajax 通信を行うことで、 画面遷移させることなくデータをサーバに送信することが出来ます。 実際に試してみると、サーバ側で以下のようにバイナリ文字列を取得できていることが分かるかと思います。 あとはこれをbyte型に変換してやればOKです。 まとめ 今回は、画面遷移をすることなくサーバへバイナリデータを送信する方法について説明しました。 自分でもまだ勉強が足りないため、もう少し綺麗な方法がある気がしますが…それはまた機会があれば。 参考 Ajax - Wikipedia $.ajax() | jQuery 1.9 日本語リファレンス | js STUDIO FileReader.readAsBinaryString() - バイナリ文字列として読み込む | File APIリファレンス エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに 性能 回帰テスト を自動化するプロジェクトを開発をしながら隙間を見つけてチームメンバーと行なっておりました。 完成して運用している今、下記3つをポイントに紹介していきたいと思います。 どのようにプロジェクトを進めたのか 進める上でどのような課題が出て解決したのか 運用方法 昨年の弊社 アドベントカレンダー ( 性能回帰テストの自動化プロジェクト始めました )にてプロジェクトの進め方を紹介しました。 そこから再編集を行い、この記事にて完結編とさせていただきます。 自動化と言う前にやったこと 自動化!! すごく楽になるそんな夢のような仕組み。 自動化する目的は?自動化して得られる効果は?手段が目的になっていませんか? 技術というのは課題、問題を解決する手段の一つです。 自動化すると言って手を動かす前に、目的を整理する。 自分やプロジェクトが抱えてる課題は本当に自動化で解消、緩和されますか? 漠然と自動化すればなんとかなると考えていないですか? 整理した後、フィードバックをオススメします。 目的、手段、背景・課題、効果 この観点で概要をまとめました。 ■ 概要説明 ■ <目的> テストコストの抑制/削減を行う <手段> ・ CI環境に組み込みテスト実行と結果出力を自動化する ・ JMeterでテストシナリオを実行し、レスポンスタイムを計測する <背景・課題> 性能改善を実施したが新機能追加、改修を続けながら性能を維持する必要がある。 しかし、そのためには機能開発毎にテストが必須となり、テストコストの増加が予測できる。 <効果> 毎日自動でテスト実行することで以下のような効果が得られる ・ 自動化することにより、性能劣化を担保するテストコストを削減することができる。 ・ 毎日テストを実行することで、性能劣化の早期発見、早期対応が可能となり、   アプリケーションの保守コストを最小限に抑えることができる。 現状把握 目的地までの道順を確認する時、自分の現在地がわからないと道順も出てきません。 日常生活の中で何気なくやってる思考が仕事でも十分役立ちます。 CIに組み込むと意気込んだものの、今動いてる環境の構成図ありませんでした。先輩から後輩と一緒レクチャーを受け後輩に構成図を描いてもらいました。 既存の構成図に新しく構築したいものを組み込んで完成!ドキュメント作成はメンバーと認識を共有するするためのものです。毛嫌いする人もいますが、コミュニケーションをとる手段の1つではないでしょうか。 青線が静的解析のフローで、オレンジ線が今回追加しようと動いている性能 回帰テスト のフローになります。 どんなテストフローにするのか 人の手でやっているテストを実行するまでの段取りを書き出してみました。 基本的に人が手でやってたことを自動にすることが自動化だと私は理解しています。 いつ(何時から)どんなデータでどのようなテストを行う? 描いたシナリオ テストデータは毎日作って破棄 全画面のレスポンスを測定するテストシナリオ 0時からテスト開始、8時には完了 レスポンスタイム結果を出力 まず、 1.テストデータは毎日作って破棄 日々新規開発は続いているので、それに合わせると毎日テストデータは作る方がメンテコストが抑えられる。 2.全画面のレスポンスを測定するテストシナリオ せっかくの自動化なのでテストできるものは全部組み込んでしまおう。 3.0時からテスト開始、8時には完了 弊社の始業時間は9時なので、1時間前までには終わればいいかな程度。8時間あれば終わるでしょうという考え。 4.レスポンスタイム結果を出力 とりあえず出力結果を CSV で出力、レスポンスタイムの平均値とか スループット の表を出力します。可視化もしたいが、まずは結果を出力するまでを行う。 案外ざっくり決めです。 実際にシナリオ流してみた 試しに流してみると、テストデータを作るのに4〜5時間。全画面のテストの3割を流すのに3時間はかかってしまうことがわかったのです。3割で3時間。 このままでは、 全画面テストは想定している時間内で実行できない可能性が高い テストデータの作成に想定していたより時間がかかる ということに気づきました。 考えていたストーリーが本当に実現できるのか? というのを早めに試作して検証することをオススメします。 新規機能の開発も同じですが、想定外なことが起こることは早めに気づくと リカバリ という手段が見いだせます。 課題と課題解決 テストデータの作成に想定していたより時間がかかる テスト数全体の3割で3時間の実行時間がかかる テストシナリオの管理、メンテナンスどうするか 日々の結果はどうやって確認するのか テストデータの作成に想定していたより時間がかかる テストデータを毎度作成するには不安定であることと、テスト時間に収めるためにあらかじめデータを入れたdumpファイルを作成し、それをrestoreすることにした テスト数全体の3割で3時間の実行時間がかかる そもそも全画面のテストを流す必要はあるのだろうか? テストの目的を考え抜いた結果、 テストで最も品質を担保したい画面を選抜することにした。 その結果、テストデータ作成からテスト実行からテスト結果の出力まで、当初考えていた8時までに収めることができた テストシナリオの管理、メンテナンスどうするか テストシナリオは資産である ソースコード と同じで、Gitに新しくシナリオ管理用のプロジェクトを作りバージョン管理 メンテナンスもバージョンごとに必要であれば行い、バージョンごとにタグを打ち、それをメンテナンス完了している印とした 日々の結果はどうやって確認するのか テスト結果は csv で出力する 性能劣化が誰が見ても一目でわかるように、横軸を日付、縦軸をレスポンスタイムにして、折れ線グラフで可視化した テスト結果はデータベースに管理 パーティショニングを使ったテーブル構成 redashというツールを使いテーブルからデータを読み込んでグラフにする ここまで考えたのですが、タイムアップにより csv を VBA に読み込ませグラフ化するシェルを手動実行 に留まっており、可視化した結果をチームの 有識者 が日々確認しています。 運用スケジュール 月曜日から金曜日の深夜12時半から性能 回帰テスト を実行、朝8時半には完了 土曜日のみ昼12時半から負荷テストを実行、13時半には完了 実は、負荷テストのjobがすでに存在していたため、これを機にCIに組み込み、バージョン管理も始めました。 テストシナリオ、テストデータの配置 サーバーに手動で配置 変更することがほとんどないため固定とした テストがあることのメリット 性能改善を行った時のテストが楽 日々の結果をグラフにしているので、改善したコードをmasterにマージした翌日から、改善できたことが一目でわかる 正常系のシナリオを作っているので、性能改善以外にも デグレ していないかの担保にもなる サーバーやOSのリプレイス、MWのメジャーバージョンアップをした時のテストに使える バージョンを上げる前のデータを取り直す必要もなく、比較ができるためわざわざテストを組む必要がない JenkinsのJobを作って退勤時にボタンをポチッとするだけで、翌朝にはテストが終わって業務時間を有効に使うことができる 人がテストをする必要がなく、より創造的なことに時間を使うことができます。 最後に 『まずは価値を届ける』 を軸にこの改善プロジェクトを進めました。 テストがあることのメリット は、実際に運用を始めた後に実務で活用した事例です。 タイムアップして手動にとどまった点もありますが、手動の部分があっても十分に性能 回帰テスト の価値を届けられています。むしろプラスαで活用できています。 今後、手動部分を自動にして少しでも手がかからないようにしていきたいです。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
こんにちは、株式会社 ラク スで横断的にITエンジニアの育成や、技術推進、採用促進などを行っている開発管理課に所属している鈴木( @moomooya )です。 前回は匿名化したデータがどの程度匿名化されているかの指標についてお話ししました。 tech-blog.rakus.co.jp 今回は今回の取り組みの中で実際にデータを匿名加工する際にどのような流れで進めたのかについてお話ししていこうと思います。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは データ匿名化 第5回:データ匿名化の指標 データ匿名化 第6回:実際の匿名化 ←今読んでいる記事 匿名加工処理の流れ 実際のデータ匿名化の流れは以下のようになります。 利用用途の定義 対象デー タセット の選定 対象デー タセット における識別子、準識別子、機密属性の定義 デー タセット の加工 ツールによる評価 状況によっては多少順序が前後する工程もありそうですが、だいたいはこの流れで問題ないと思います。 それでは1つずつ見ていきたいと思います。 1. 利用用途の定義 まずは匿名加工したデータをどのような目的で利用するかを定義します。 データの匿名化作業に慣れている場合には問題ないのかもしれませんが、以降の工程でどの項目が準識別子なのか、どの項目が機密属性なのか、どの項目をどの程度一般化して問題ないのか、という判断をする際に目的を明確にしておかないと「この項目を一般化するのが一般的」という感覚に引きずられて遠回りをしがちです。 例えば今回のような検索性能の検証データとしてデー タセット を匿名化していく場合にも、主な検索項目が 自然言語 によるフリーテキストなのか、数値項目なのか、日付項目なのか、によってもどの項目をどの程度一般化するのか、という判断が変わってきます。 2. 対象デー タセット の選定 対象のデー タセット は社内で開発しているサービスのデー タセット であれば比較的容易に定まるのではないでしょうか。 この際できるだけ実際に運用しているリアルなデー タセット を採用する方が良いでしょう。データ定義を元に作成したサンプルデータだとどうしてもデータ作成者によるバイアスがかかってしまい理想のデー タセット になってしまいがちです。 社内で ドッグフーディング している環境があれば理想的だと思いますが、目的が「特定の顧客で発生している性能問題の原因特定」みたいな場合は顧客担当者に交渉してデータを利用させてもらうなどの手順を踏まなければならないでしょう。 3. 対象デー タセット における識別子、準識別子、機密属性の定義 対象となるデー タセット が決まったら識別子、準識別子、機密属性の定義です。 tech-blog.rakus.co.jp 識別子は用途に左右されずに比較的 機械的 に定義できると思います。準識別子デー タセット に依存する部分はありますが、頻繁に扱われるであろう住所、年齢、性別などは準識別子となるでしょう。 機密属性(漏洩すると問題になる項目)はデー タセット によりけりなので都度判断が必要になってくると思います。 4. デー タセット の加工 識別子、準識別子、機密属性が決まったらデータを加工していけます。 識別子の削除 識別子は無条件で削除されます。 準識別子の加工 準識別子については秘匿すると情報量が大きく減ってしまうため、できるだけ秘匿しないよう一般化していきます。 匿名化後のデー タセット の用途を考慮して、準識別子の項目を一般化していきます。 以下の記事のように準識別子をそのままにしてしまうと高い確率で特定されてしまうので何らかの加工を加えると良いと思います。 jp.techcrunch.com 具体的な加工方法については第4回の記事で解説しています。 tech-blog.rakus.co.jp 5. ツールによる評価 実際のデー タセット に含まれるレコード数は少なくとも数万件以上あると思いますので手動で評価を行うことは非現実的だと思いますので、ARXといった匿名加工ツールを利用します。 arx.deidentifier.org 前回説明させていただいたk-匿名性、l-多様性というプライバシーモデルについてもこちらのツールで設定することができます。 tech-blog.rakus.co.jp ARXの概要 ARXはデータ匿名化に関する包括的な オープンソース ソフトウェアです。 指定した入力データソースを対象に 各種プライバシーモデルを設定し デー タセット の変換や デー タセット の評価 を行うことができます。今回は変換には利用せず、デー タセット の評価にのみ利用しました。 Java 製のアプリケーションなので Windows / macOS / Linux 問わず利用することができます。 ARXの基本的な設定方法 インストールを終えて起動したらデータを読み込みます。 CSV データを入力するケースを例にします。 CSV ファイルを読み込む もしくはメニューから [File] > [Import data...] を選択。 ※このとき読み込み済みのデータと設定はリセットされるため注意。 各カラムの識別子区分を設定する 各カラムに識別子区分を設定していく。 識別子区分は以下の通り。 非機密属性: Insensitive 機密属性: Sensitive 準識別子: Quasi-idepntifying 識別子: Identifying 評価指標を設定する k-多様性を追加する場合は k-Anonymity を選択してkの値を設定して OK をクリック。 評価結果を確認する 攻撃モデル 3種類の攻撃モデルに対する特定確率という形式で評価されます。 Prosecutor attacker model / 検察官攻撃者モデル(検察官リスク) 特定の人を特定することを目的とした攻撃 匿名化されたデー タセット 内に存在することがわかっている個人に対して、匿名化されたデー タセット 内の情報を利用して特定を試みる Journalist attacker model / ジャーナリスト攻撃者モデル(ジャーナリストリスク) 特定の人を特定することを目的とした攻撃 匿名化されたデー タセット 内に存在することがわかっている個人に対して、公開されている別の情報ソースを利用して特定を試みる Marketer attacker model / マーケッター攻撃者モデル(マーケッターリスク) 不特定多数を特定することを目的とした攻撃 特定結果の一部が誤っていることを問題としない 検察官リスク、ジャーナリストリスクは必ずマーケッターリスクと同等もしくはそれ以上になる 評価値 Records at risk 閾値 を超えるリスクを伴うレコードの割合 Highest risk 単一レコードでもっとも高いリスク(特定可能性) k=2 であれば多分50%になる Success rate 平均再特定リスク Risk thresholds リスク 閾値 Highest risk Records at risk を算出するための 閾値 この値を超えるレコードの比率が Highest risk となる これらの指標値を元にプロジェクトごとに設定した 閾値 をパスするようデータを加工します。当然1度の加工でパスしない場合は一般化の度合いを調整するなどして試行錯誤が必要になります。 参考:今回の取り組みでの目標 閾値 今回の取り組みでは以下4点を満たす場合に 匿名化されている と設定してデータ加工を行ないました。ご参考になれば。 Risk thresholds / Main - Highest risk 50%以下 Records at risk(%) 0% Highest risk(%) 1%以下 Success rate(%) 1%以下 まとめ 今回は実際のデータをどのように匿名化していくのかについてお話ししました。 本連載はこれで終わりとなります。 今回の取り組みではElasticsearchとデータ匿名化手法をテーマにし、主にデータ匿名化についての調査、検証を進めていました。 今まではデータの匿名化というものについてなんとなくではわかっているものの、どういうアプローチが確立されていて、どういう評価をすれば良いのかはわかっていませんでしたが、本連載でまとめた内容を理解することでだいぶ理解が進められたと思います。 少し前にTechCrunchで以下のような記事が公開され話題になっていましたが、今であれば「一般化もしない準識別子を残していれば特定できるのは当たり前」だと冷静に読み解くことができるようになりました。 jp.techcrunch.com 今後、業務で機密属性を含むデータを取扱うことになった場合にもさらに安全に安心してデータを取扱っていけると思います。 かみせんプロジェクトでは今後もテーマを設定して検証を進めていきます。 次のテーマが決まり、検証が進んだらまたレポートを公開していきたいと思いますのでよろしくお願いします。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは データ匿名化 第5回:データ匿名化の指標 データ匿名化 第6回:実際の匿名化 ←今読んでいる記事
アバター
初めまして。新卒1年目エンジニアのrs_shoです。 今回はGitのcommitタイミングと注意点について書いていきたいと思います。 はじめに そもそもcommitって? commitのタイミング commitする際の注意点 おわりに 参考資料 はじめに 皆さん、 バージョン管理システム のGit、使ったことありますか? 僕は、社会人になって初めて「 バージョン管理システム 」を使いました。かなり便利ですね! 過去のある状態に戻したり、元のファイルを編集しないようにブランチを切って編集後に差分を反映したり・・・ 学生時代から使っておきたかった、なんで使ってないんだ!過去の自分よ・・・と思うくらい便利です。 そもそもcommitって? 「commitってなんだ」と思う方もいるかもしれないので、つかみ程度に・・・ ・Gitで「追加編集したファイルを登録するコマンド」のこと ・編集した履歴、差分などが記録される ・commitしたポイントに戻ることができる 3つ目が個人的にかなり便利だと思います。 具体的にはcommitする前にファイルをaddするなんてことも必要ですが、今回説明は割愛します。 commitのタイミング ではそろそろ本題へ・・・ commitって便利ですが、「いつすればいいの?」っていう人多いんじゃないでしょうか。 僕がGitを使って間もない頃、 commitをし忘れ たり、 あまり意味のないタイミングでcommit して、 一緒に研修していた同期に「またか」と言われてました。 (だっていつしていいかわからない・・・) 実際、「commitのタイミング・頻度」ってどれくらいがいいのか、難しいところだと思います。 $ git add [ファイル名] $ git commit コマンドとしてはこれだけです。addしたファイルだけコミットされます。簡単ですね! ではcommitっていつすればいいのという話ですが・・・ 実は 絶対この時commitするべき 、 この時はしない方がいい というタイミングはありません。 (じゃあなんでこの記事書いたんだというツッコミはご遠慮ください) 実はこの問題、 僕もすごく悩みました 。 ネットで記事を探すと色々書いてありますが、僕が導き出した答えは以下の通りです。 会社の規則に従う(会社で決まっているタイミングで行う) 個人的に「この部分へは戻る可能性がある」と思ったとき タスク単位(機能単位)※単一機能追加のみ クラス単位(編集しているクラス1つにつき1回) 個人的な意見としては会社でグループ開発をしている場合は1つ目が絶対だと思います。 個人開発や他人に迷惑をかけない(自分のみが編集する部分)に関しては、個人のタイミングで良いと思います。 自分がcommitしてなくて最初からやり直し・・・なんてことになっても自分の責任で済みますからね・・・ 僕は研修の時はクラス単位でcommitしていましたが、配属されてからは機能単位でcommitしています。 commitする際の注意点 commitする時に注意したいのが、 余計なものはcommitするファイルに入れない ことです。 僕が配属されてから失敗したこととして、 commitしなくていい(しない方がいい)ファイルまでaddしてcommit していました。 つまり、 機能に関わりのない個人設定のファイル や 間違って編集したファイル はcommit対象にするべきではないということです。 理由としては、 余計なファイルが入ると、確認する際(個人環境に持ってきたとき)に動作の妨げとなることがある 機能単位で確認する際に編集した内容が見づらくなってしまう などがあげられます。(実際に先輩に指摘を受けました) 1点目についてはレビュワーへの被害が大きいです。余計なファイルがあると、どこを編集したのか確認が大変です。 2点目は1点目に繋がりますが、後から見た人が「これ編集してあるみたいだけど、どう関係してるファイル?」となってしまいます。 個人で開発しているならまだしも、グループ開発だと、周りに 多大な迷惑&手間 をかけてしまうことがあります。 おわりに 皆さん、いかがでしたか? commitのタイミングと注意点について個人的な意見ですがまとめてみました。 commitのタイミングについて困った方の参考になれば幸いです。 参考資料 はじめてのGit!コミット(commit)でファイルを登録してみよう 【初心者向け】「コミットの粒度がわからない問題」の模範解答を考えてみた エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
はじめに こんにちは。新卒2年目のtaku_76です。 以前FirebaseでLINEbotを作成するという勉強会に参加してきました。 しかし、元々Firebaseについて名前を聞いたことがあるくらいで知識が全くありませんでした。 そこで今回は実際に使ってみることで理解を深めようと思い、簡単なものではありますが FirebaseのRealtime Databaseを使ってリアルタイムチャットを作成しましたので、Firebaseとは、というところから紹介していきます。 はじめに Firebaseとは Realtime Databaseとは 実装 Firebaseでプロジェクトの作成 ログイン方法の設定 Realtime Databaseの作成 Firebaseの読み取りの書き込み データベース参照を作成 チャット作成 送信準備 送信処理 受信処理 終わりに 参考 Firebaseとは Firebaseは Google が提供しているモバイルおよび Web アプリケーションのバックエンドサービスです。 ユーザーの初期登録や認証を簡単に実装できる機能や、 ホスティング 機能など様々な機能がありますが、 今回はリアルタイムでクライアント全体の状態を同期させることができるRealtime Databaseを利用します。 Realtime Databaseとは クラウド ホスト型 NoSQLデータベースで、ユーザー同士でデータをリアルタイムで保存・同期ができる機能です。 編集したデータは クラウド に保存され、数ミリ秒で各端末に同期されるため、ユーザー同士はリアルタイムでの共同作業が可能になります。データは JSON フォーマットで保存されます。 実装 Firebaseでプロジェクトの作成 以下にアクセスしてプロジェクトを作成します。 https://firebase.google.com プロジェクトが作成できたらウェブアプリにFirebaseを追加します。 scriptタグが表示されるので、これを今回作成するファイルchatapp.htmlのscript内に貼り付けます。 ログイン方法の設定 ログイン方法を選択するのですが、今回は匿名を有効にしておきます。 Realtime Databaseの作成 次にRealtime Databaseの作成を行います。 左のメニューからDatabaseを選択し、Realtime Databaseを作成します。 ルールについては開発時なのでテストモードを選択します。 chatapp.htmlに入力欄のdivタグを追加します。 <div> <div> <input type="text" id="name"> </div> <div> <textarea id="message" row="10"></textarea> <button id="send">send</button> </div> <div id="output"></div> </div> Firebaseの読み取りの書き込み データベース参照を作成 データベースでデータの読み書きを行うためには、firebase.database.Referenceの インスタンス が必要ですので 以下のコードを追加します。 var database = firebase.database(); チャット作成 送信準備 var database = firebase.database(); let room = "chat_room"; const send = document.getElementById("send"); const name = document.getElementById("name"); const message = document.getElementById("message"); const output = document.getElementById("output"); let room ="chat_room";で指定したroomにデータを記録しています。 この値を変更することによってデータの格納先を変えることができます。 送信処理 send.addEventListener('click', function() { database.ref(room).push({ name:name.value, message:message.value }); message.value=""; name.value=""; }); メッセージの送信はpush()を使うことによってデータベースに登録することができます。 データベースへのデータを書き込むメソッドは他にもset(),update(),transaction()があります。 受信処理 database.ref(room).on("child_added", function(data) { const v = data.val(); const k = data.key; let str = ""; str += '<div class="name">名前:'+v.name+'</div>'; str += '<div class="text">メッセージ:'+v.message+'</div>'; output.innerHTML += str; }); Firebase内のデータを取得するためにchild_addedイベントを使用します。 このイベントは子ごとに1回トリガーされ、新しい子が追加されるとそのたびに再度トリガーされます。 今回の実装では、push() メソッドによる新しい子の追加で、child イベントがトリガーされるという動作になっています。 実装完了後、2つのブラウザを立ち上げて動作確認を行います。 nameとmessageを入力してsendボタンを押すことで、以下のようにリアルタイムにチャットができたら成功です。 FirebaseのRealtime Databaseを見てみるとnameとmessageが記録されていることも確認できます。 以上でリアルタイムチャットの実装は完了になります。 終わりに Firebaseを使うことによってデータベースへの読み書きが楽になり、 リアルタイムチャットの開発がすごく簡単になったことを実感しました。 Firebaseを理解して使いこなせるようになると個人的に開発する際のコストを下げられると思いましたので、他の機能も学習していきたいと思います。 参考 www.topgate.co.jp アプリ開発が怖いほど楽になる「Firebase」を徹底解説!【初心者向け】 ウェブでのデータの読み取りと書き込み  |  Firebase Documentation ウェブでのデータの読み取りと書き込み  |  Firebase Documentation エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
はじめに こんにちは、strongWhiteです。今回は大阪オフィスで開催された9月ビアバッシュをご紹介いたします。 前回の記事はこちら↓ tech-blog.rakus.co.jp はじめに 発表一覧 個人的に気になった発表 1日で学ぶ機械学習 エンジニアの知的生産術を読んで スクリプト言語のベンチマーク おわりに 発表一覧 今回はオンラインでつないで東京オフィスのエンジニアと合同で開催することとなりました。 以下が今回の発表一覧です。多くの方に発表していただきました! 自由枠(質疑応答込みで13分) らくらくでないLINE@連携 まず、やってみる(社内/社外イベント取り組みの振り返り) 1日で学ぶ 機械学習 社外イベント登壇の取り組みの実績 エンジニアの知的生産術を読んで GASとclaspについて iOS13で実装された念願の『アレ』の話 LT枠(5分厳守) Akka(と scala )でたこ焼きを焼く スクリプト言語 の ベンチマーク reveal.jsについて 全体に触れると長くなってしまうため、個人的に気になった発表をピックアップしてご紹介いたします。 個人的に気になった発表 1日で学ぶ 機械学習 Chainerが公開している 機械学習 の学習教材に取り組んだお話でした。 機械学習 と聞くと漠然と難しいイメージですが、この教材では Python や数学、確率・統計の基礎から学べるので入門者にはとっておきの学習教材です。 開発環境は Google Colaboratoryを使えば、初めから主要なライブラリを利用することができます。 個人的には開発環境構築が必要ないのは、学習の負担削減になり魅力的だなと感じました。 機械学習 は マーケティング や製造、情報セキュリティなど様々な分野で活用されており、いまホットなテーマなので、基礎を学ぶにはちょうどいいなと思いました。 Information Chainer Google Colaboratory エンジニアの知的生産術を読んで 『エンジニアの知的生産術』を読んで実践したことを共有していただきました。 書籍には「学びのサイクル」が紹介されており、すなわち情報収集→モデル化→検証→※最初に戻るを繰り返すことで学びを繰り返すことができます。自分が学びたいことを「情報収集」し、集めた情報を KJ法 などで「モデル化」、最後にモデル化した情報を本当に理解しているか「検証」するフェーズを実施します。 個人的にはそもそも何を学べばいいかわからない事態に陥ることが多いのですが、ひとまずは(IT分野に限らず)興味のあるものは何でも学んでみようというスタンスで「学びのサイクル」を実行するとうまく知識が定着するのかなと思いました。 Information エンジニアの知的生産術 KJ法 スクリプト言語 の ベンチマーク 各言語の最新バージョンで ベンチマーク を実施したお話でした。 対象言語はWeb界隈でメジャーな PHP 、 Ruby 、 Python 、 Perl 、Node.jsで、 フィボナッチ数列 や竹内関数(たらい回し関数)などを検証されました。 今回の発表では主にNode.jsが速く、検証する関数に 再帰 が多いと速いのかもしれないという推測ができました。 個人的には一時期流行った「ズンドコキヨシ」の ベンチマーク を実施した話が面白かったです。5000回実行した場合の時間を計測されましたが、結果的には Perl が一番速かったです。 Information フィボナッチ数列 竹内関数 ズンドコキヨシ おわりに 今回は東阪合同だったのがとても新鮮でした。ふだん関わりの少ないメンバーも積極的に発表に参加してくださり、いつものビアバッシュとは違った雰囲気でした。 今年度入社・配属された方も発表に参加してくださり、ますますビアバッシュが盛り上がっていく感じがします。 今後もビアバッシュの内容はブログという形でレポートしていきますので、どうぞお楽しみに!!
アバター
はじめに こんにちは、新卒3年目エンジニアの @rs_tukki です。先日開発オフィスが移転となり、美味しい昼食を探し求める日々が続いています。 さて、来る9/20(現地時間)、ついにiOS13がリリースされました! ダークモードやSwiftUIなど、利用者としてだけでなく開発者としても魅力的な機能が様々追加されているそうですが、今回はその中でも、ついにアップデートされたCoreNFCについてまとめてみます。 はじめに CoreNFCとは 今までは Suicaの履歴を読み取ってみる Xcodeプロジェクトの設定 読み取り開始まで 読み取った内容の解析 結果確認 まとめ 参考 CoreNFCとは CoreNFCとは NFC 規格の通信 フレームワーク のことで、 apple ではiOS11から採用されていました。 NFC は近距離無線通信の略で、よく皆さんが使っている Suica や Edy などの 電子マネー や、最近では マイナン バーカードなどにも搭載されている「かざして通信する」ことができるシステムを総称してこう呼びます。 iOS13からは、このCoreNFCの機能がアップデートされ、上記のようなカードの読み書きが、 サードパーティ 製のアプリでも行えるようになりました。 今までは iOS12までのCoreNFCは、NDFC( NFC Data Exchange Format)という規格の「読み取り」にしか対応していませんでした。 NDFCはURLなど超小容量のデータしか通信できないため、CoreNFCと言いながらもほぼ QRコード と同等以下のシステムでしかないと言えます。 iOS12までで Suica カードなどの読み取りを行いたい場合、 iPhone と外部機器を BlueTooth で接続する必要がありました(当然、書き込みはできません)。 楽楽精算のICリーダーも、 iOS 版はこの仕組みで読み取っています。 楽楽精算ICリーダー 株式会社 ラク ス ビジネス 無料 apps.apple.com Suica の履歴を読み取ってみる というわけで早速、アップデートされたCoreNFCの機能を使い Suica の乗降履歴情報を取り込んでみましょう。 実装については以下のサイトを参考にさせていただきました。 iOSでSuicaの履歴を読み取る - Qiita Xcode プロジェクトの設定 まずは、 Xcode のプロジェクト上でCoreNFCを使用するための設定を行います。 プロジェクトを開き、TARGETS>Signing & Capabilitiesから左上の「+」ボタンを押すと、プロジェクトに追加するネイティブ機能を選択できます。 iOS13に対応した Xcode であれば、 Near Field Communication Tag Reading (= NFC タグの読み取り)の機能があるので、この機能を有効にします。 続いて、Info.plistを編集します。 ISO18092 system codes for NFC Tag Reader Session には、読み取りたいカードの「システムコード *1 」を入力します。 たとえば、 Suica や PASMO などの 交通系ICカード を読み取りたい場合、システムコードは0003になります。 配列型で複数のシステムコードを登録できますが、 ワイルドカード で全てのカードを読み取れるようにする...といったことは残念ながらできません。 読み取り開始まで さて、前準備も終わったところで早速カードの読み取りをしてみましょう。 まず初めに、CoreNFCをインポートしておきます。 import CoreNFC カードを読み取らせるときは、 NFCTagReaderSession 型の変数を定義しておき、どのような規格のカードを読み取るか設定します。iso18092は NFC TypeF、つまり Suica に代表される Felica 規格のことを指します。 bigin() を呼び出すとカードの読み取り状態になります。現在のところは iOS 固有のUIが表示されるため、独自の読み取り画面を表示させるといったことはできなくなっています。 //NFCタグを読み取るための変数を定義 var session : NFCTagReaderSession? :   (中略) : //読み取り開始時 self .session = NFCTagReaderSession(pollingOption : .iso18092, delegate : self ) self .session?.alertMessage = "カードをiPhoneに近付けてください。" self .session?.begin() カードを読み取る際は、それぞれ以下に記載したタイミングで3つのメソッドが呼ばれます。 もし読み取りが何らかの理由で失敗した場合は、2番目のメソッド内で error 引数を元にエラーハンドリングを行います。 //読み取り状態になったとき func tagReaderSessionDidBecomeActive (_ session : NFCTagReaderSession ) { } //読み取りが完了したとき func tagReaderSession (_ session : NFCTagReaderSession , didInvalidateWithError error : Error ) { } //読み取りが成功したとき func tagReaderSession (_ session : NFCTagReaderSession , didDetect tags : [ NFCTag ] ) { 読み取った内容の解析 続いて、読み取りに成功してからの処理です。 引数の tags には、読み取った全ての NFC 対応カードの情報が入っています。最初に認識したカードが正しく読み取れているか、 Felica 規格のものかどうか確認しておきましょう。 func tagReaderSession (_ session : NFCTagReaderSession , didDetect tags : [ NFCTag ] ) { let tag = tags.first ! session.connect(to : tag ) { (error) in if nil != error { print( "Error: " , error) return } guard case .feliCa( let feliCaTag ) = tag else { session.alertMessage = "FeliCa以外の規格が検出されました。FeliCa規格のカードで再試行してください。" return } このタイミングで、既に IDm *2 と、先ほど指定したシステムコードは読み取ることが出来ます。 更に乗車履歴などの詳細な情報を読み取る場合、その情報が格納されている場所を サー ビスコ ード として指定します。このとき難儀なのが、サー ビスコ ードをリ トルエン ディアン *3 で指定しなければいけない、ということです。有志の方のサンプルコードを読む前に私も実装にチャレンジしてみたのですが、ここの指定が上手くいかず挫折していました... その後は読み取る範囲を指定してから、 requestService でいよいよ乗車履歴を読み出します。 中身のデータが存在していればFFが返ってくるはずですので、そこも一度確認しておきましょう。 let idm = feliCaTag.currentIDm.map { String(format : "%.2hhx" , $0 ) }.joined() let systemCode = feliCaTag.currentSystemCode.map { String(format : "%.2hhx" , $0 ) }.joined() let serviceCode = Data([ 0x09 , 0x0f ].reversed()) feliCaTag.requestService(nodeCodeList : [ serviceCode ] ) { nodes, error in if let error = error { print( "Error:" , error) return } guard let data = nodes.first, data != Data([ 0xff , 0xff ]) else { print( "履歴情報が存在しません。" ) return } Suica をはじめとする 交通系ICカード は全部で20件の乗降履歴を保持できますが、現在の使用では一度に12件までしか読み取れないようです。 読み取る範囲を指定したら readWithoutEncryption を実行します。戻り値としてstatusが2種類返ってきますが、この値が両方とも00であれば、めでたく履歴を取得できています。 読み取り中のUIは session.invalidate() で閉じておきましょう。 中身のデータがどのような形式で格納されているか...についてですが、独自に解析している方がおり、それを参考にすることができます。 今回はサンプルコードから引用させていただきましたが、参考資料にはデータの格納情報が更に詳しく載っていますので、気になる方は読んでみてください。 let block :[ Data ] = ( 0 ..< 12 ).map { Data([ 0x80 , UInt8( $0 )]) } feliCaTag.readWithoutEncryption(serviceCodeList : [ serviceCode ] , blockList : block ) {status1, status2, dataList, error in if let error = error { print( "Error: " , error) return } guard status1 == 0x00 , status2 == 0x00 else { print( "ステータスコードが正常ではありません: " , status1, " / " , status2) return } session.invalidate() print( "IDm: \( idm ) " ) print( "System Code: \( systemCode ) " ) dataList.forEach { data in print( "年: " , Int(data[ 4 ] >> 1 ) + 2000 ) print( "月: " , ((data[ 4 ] & 1 ) == 1 ? 8 : 0 ) + Int(data[ 5 ] >> 5 )) print( "日: " , Int(data[ 5 ] & 0x1f )) print( "入場駅コード: " , data[ 6 ... 7 ].map { String(format : "%02x" , $0 ) }.joined()) print( "出場駅コード: " , data[ 8 ... 9 ].map { String(format : "%02x" , $0 ) }.joined()) print( "入場地域コード: " , String(Int(data[ 15 ] >> 6 ), radix : 16 )) print( "出場地域コード: " , String(Int((data[ 15 ] & 0x30 ) >> 4 ), radix : 16 )) print( "残高: " , Int(data[ 10 ]) + Int(data[ 11 ]) << 8 ) } } } } } 結果確認 さて、ここまでの実装を踏まえて実際に Suica を読み取ってみると... IDm システムコード 利用年月日 入場駅コード・出場駅コード 入場地域コード・出場地域コード *4 残高 が取得できているのが分かるかと思います! まとめ 今回は、iOS13でアップデートされたCoreNFCについて説明しました。 Android ではかなり前から読み取れていましたが、ようやく iOS も追いついた形になります。これを機に今までのアプリも色々アップデートされていきそうで楽しみです! 参考 iOS13 CoreNFCの使いみちとQRコード、BLEとの比較 - Qiita iOS13ではNFC機能をサードパーティに開放、行政手続きなどに利用可能 - iPhone Mania 「iOS 13」ベータ版をインストールする方法 iOS 13 で FeliCa (Suica) にアクセス | notes from E iOSでSuicaの履歴を読み取る - Qiita エラー ‐ 通信用語の基礎知識 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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 : カードの利用目的ごとに割り振られた番号 *2 : カードごとに割り振られた番号 *3 : http://e-words.jp/w/%E3%83%AA%E3%83%88%E3%83%AB%E3%82%A8%E3%83%B3%E3%83%87%E3%82%A3%E3%82%A2%E3%83%B3.html *4 : 0はJR、もしくは関東の私鉄、バスを指す。
アバター
こんにちは、新卒2年目のEngawaです。 今回はサーバにデプロイしたWEBアプリを Eclipse でリモート デバッグ する方法を書いていきたいと思います。 はじめに 普段から開発を行っている際は、 Eclipse の デバッグ 機能を使い処理の流れや変数の値を確認しながら実装しているのですが、ローカル環境では実行できない部分(外部サービスと連携した後の処理とか)の実装では処理の流れや、変数には何が入っているかわからない上、動作確認もサーバにデプロイして確認しているのですが、エラーが出た時も詳細なエラー原因を探すのに苦労しました。 そこでサーバにデプロイしたWEBアプリを Eclipse でリモート デバッグ する方法を簡単にまとめてみました。 はじめに 設定 終わりに 参考 設定 まずは Tomcat の設定からです。 起動シェルの以下の1文を変更 $SU - $ TOMCAT _USER -c "${CATALINA_HOME}/bin/catalina.sh start" ↓ $SU - $ TOMCAT _USER -c "${CATALINA_HOME}/bin/catalina.sh jpda start" 上記内容で変更したら Tomcat を再起動して、 Tomcat の設定の変更は完了。 続いて、 Eclipse の設定を行います。 1. 実行 > デバッグ の構成 > リモート Java アプリケーションを右クリック > 新規構成 を選択 2. プロジェクト に デバッグ するプロジェクトの名前、 ホスト に接続先の IPアドレス をそれぞれ入力(それ以外はデフォルトで問題なし) 3. 適用を押下 これで設定は完了です。 設定完了後、 デバッグ で実行し、 デバッグ タグで接続先の IPアドレス が表示されれば接続完了です。 あとはいつも通り ブレークポイント を置いてからブラウザでアクセスすると、 ブレークポイント を置いた部分で処理が止まってくれます。 終わりに 今回はサーバにデプロイしたWEBアプリを Eclipse でリモート デバッグ する方法について簡単にまとめました。 同じような境遇になった方の参考になれば幸いです。 参考 qiita.com www.ibm.com エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
初めまして、hidePoohです。 第四回を担当させていただきます。 私たちが住む日本では、携帯電話という文化は独自の進化をしてきました。 キャリアメールも例外ではなく、各キャリアごとに特徴を出したものへと進化してきました。 なお、「キャリアメール」とは携帯電話事業者が各社ごとに提供している( ~@ docomo .ne.jp、~@ ezweb .ne.jp、~@ softbank .ne.jp などの)メールのことです。 詳細は下記をご参照ください。 ja.wikipedia.org これまでのキャリアメールは携帯電話と一緒に進化してきた キャリアごとに違う 文字コード 日本のPC向けメールの 文字コード は一般的に「 ISO-2022-JP 」が使われています。 ですが、携帯向けの 文字コード は、各キャリアごとに 文字コード に違いがあります。 ※キャリアとは    NTTドコモ 、 au 、 ソフトバンクモバイル などの携帯電話会社の事を指します。 NTTドコモ :Shift-JIS au :Shift-JIS ソフトバンクモバイル : UTF-8 上記のように、配信されるアドレス(キャリア)によって 文字コード を変える必要がありました。 特に、昨今のシステムは UTF-8 が主流となっています。 キャリアごとの 文字コード を対応させることはとても面倒ですね。 絵文字の登場 日本の携帯といえば、「絵文字」が有名ですね。 現在では、 “emoji”という言葉があるくらい、世界中に広がりました。 でも当初登場したときは、キャリアごとにバラバラで配配メール側での実装も大変だったと聞いています。 ※ NTTドコモ が提供しているドコモ絵文字の一部 *1 絵文字は、キャリアごとに種類も違い、絵文字の種類も数も違います。 配配メールでも例外ではなく、どのように考慮するか大変でした。 現在では、キャリア同士でも、絵文字の違いを保管できるように各絵文字専用の 文字コード を用意し、配信時にその 文字コード を指定する仕様が公開されています。 ※ NTTドコモ が提供している絵文字変換表 https://www.nttdocomo.co.jp/binary/pdf/service/imode_mail/function/emoji_convert/pictogram.pdf ※配配メールでは、上記の図のドコモ絵文字から各キャリアのコードをマッチングできるような仕組みを構築しています。 配配メールではこれらの進化に合わせてキャリアメールに対応している ここまで説明したように、配配メールの送信PGでは 文字コード ・絵文字を配信されるアドレス(キャリア)ごとに処理を行うようにしています。 メール作成:本文内の絵文字挿入(ドコモ絵文字) ------ メール配信処理開始 ------ メール配信処理開始 配信するアドレスからキャリアを確認 本文内に絵文字が見つかったら、配信アドレスに合わせて各キャリアごとの絵 文字コード 表から対応する絵文字に変換    → PG内部で絵 文字コード 用 マトリックス を作成しており、送信時に変換処理を実施 文字コード を変換 配信完了 こうやって書くと簡単に見えますが、携帯向け配信は各キャリアごとの仕様を把握しながら配信しなければならず、とても面倒な作業です。 スマホ の登場によってこれらの違いがなくなりつつある ここまで書いてきたのは、特に“ フィーチャーフォン (※ ガラケー )”を意識した配信です。 最初に書いたように日本は、キャリアが携帯機種を開発している歴史があり、機種に依存した問題も多く、キャリアが提供している仕様に合わせる事が大事でした。 ですが、“ スマートフォン (※ スマホ )”の登場で大きく変わりつつあります。 スマホ が登場したときは、各キャリアの仕様がそのまま適用されており、 ガラケー と同じように扱うような仕様となっていました。 最近は、 Gmail や Yahoo! メールなどの フリーアドレス も多く利用されるようになり、ほぼPCと同じ仕様でメールを配信する事ができるようになりました。 文字コード の制限もなくなりつつあります。 (※キャリアメールは 文字コード に準拠する必要がありますが、そこは置いといて・・・) また、絵文字も大きく変わりつつあります。 Unicode での絵文字が提供されたことです。 つまり、 Unicode ( UTF-8 )であれば、絵文字を表示させることができるようになりました。 ja.wikipedia.org ※ Unicode の絵文字の一部 この絵文字を使えば、 スマホ でも、PC向けメールにも同じ絵文字を配信できるようになります。 また、 文字コード も UTF-8 に統一され、受信する媒体(PC・ スマホ )に関係なく、同じ仕様で配信する事が可能になります。 今後、携帯はPCとの垣根なく対応させることができるようになる!(と、私は思っている) まとめ 日本独自の進化をとげた携帯電話というデ バイス 。 でも、 スマホ の登場で色々な事がかわりつつあります。 我々、メール配信システムを作るものとしても、統一した仕様での実装ができることはとてもうれしい事でもあります。 特に私が入社したころは、以下のような事がよくありました。 ○○の機種だけで文字化けするんですけど・・・ 絵文字が正しく表示されないんですけど・・・ 今後は、携帯電話というものから、PCも携帯電話も一緒のメールが統一して送信する事ができる! そんな配信がすぐそこまで来ていると思います。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com *1 : NTTドコモ : https://www.nttdocomo.co.jp/service/imode_mail/function/pictograph/
アバター
みなさんこんにちは。フジサワです。 前回の記事 でお伝えしていたElasticsearchの検証がひと段落しましたので、検証結果をレポートいたします。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 ←今読んでいる記事 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは データ匿名化 第5回:データ匿名化の指標 データ匿名化 第6回:実際の匿名化 はじめに 検証を行うにあたり、私たちは前回、以下の通りゴール設定をしました。 『検索機能を有する新規サービスの アーキテクチャ 検討段階で、 RDB だけでなくElasticseachが比較検討材料として挙がる状態を作る』 この検証を行うにあたり、以下のようなサービスをモデルとして設定しました。 扱うデータのレコード数は、多くても100万件オーダー ※当社はBtoB向けのサービス、かつ中小企業のお客様を主たる顧客層としているので、1顧客でウン千万件、ウン億件というようなレコードが発生するケースよりは上記程度のデータ量が検証対象としては妥当だろうと判断しました。 テキストデータに対する、中間一致検索(いわゆるLIKE検索)機能を持つ ※従来の技術領域を代替するもの、という位置付けで RDB でパフォーマンス劣化が発生しがちな中間一致検索を採用 また、当社では RDB に PostgreSQL を採用する場合が多いのですが、デフォルトの PostgreSQL では比較の余地がないので、 PostgreSQL の 全文検索 プラグイン である pg_bigm を比較対象として採用することにしました。 結論から言うと… 「従来型のLIKE検索を行う代替手段」としては、速度・機能面でElasticsearchは候補になりうる。しかし、その目的だけであれば、pg_bigmを採用するほうがデメリットが少なく、わざわざElasticsearchを導入する必要は無い。 Elasticsearchを採用するのであれば、 形態素 型インデックスの特徴を活かした「自然な文書検索」や「あいまい検索」、「スケーラビリティ」などの要件を重視するべきである。 いずれを選択するかは、機能要件・用途や、データの特性に応じて選択をすべきである。 以下、上記結論に至った検証結果をご覧ください。 データストアとしての振る舞いの特徴 検証結果をお伝えする前に、Elasticsearchのデータストアとしての特徴を確認しておきましょう。 ドキュメント型データベースである ElasticSearchはドキュメント型データベースで、自由なレイアウトでのデータ表現が可能です。 スキーマ にとらわれず、様々な形式の文書データを横断的に検索することに優れています。 スケーラブル Elasticsearchはデー タセット を分割の最小単位となるシャードに分け、複数のノードにシャードを分散して配置します。シャードを動的に再配置することで柔軟にスケールアウトさせることができます。 トランザクション がない Elasticsearchには トランザクション がありません。データの登録に失敗した、登録中に他プロセスから検索がかかった、といったACID性を求められる局面では別途考慮が必要です。 結合は不得手 前述の通り、Elasticsearchは複数のノード(およびシャード)にデー タセット を分散して保持します。この特性から、 RDB における正規化、結合といった使い方には適していません。 また、インデックス間の結合を行う機能はなく(限定的に、親子関係での結合を行うことはできる)、出来るだけ非正規化することが 推奨されています 。 こうした特徴から単純に RDB の代替として採用するというよりは、 大量の文書を高速に検索することに適した仕組み を活かして、限定的に使用するのが良いでしょう。 検証: PostgreSQL のLIKE検索と同じ検索結果を得ることができるか Elasticsearchを使用した場合でも、 PostgreSQL のLIKE検索と同様の結果を得ることができるのでしょうか。 結論から言えば、 PostgreSQL のLIKE検索と同様の検索結果を得ることができる ことが分かりました。 ただし、 Analizerについての前提知識とその特性について理解 したうえで、 match_phraseクエリを使用する 必要があります。 Analizerとは Elasticsearchにおける、文書データ、および検索クエリ文字列を分解・加工することで効率よく検索を行うための仕組み。 文書データをインデキシングする際、「一定のルール」に従って文字列を分割する。 検索クエリに対しても同じルールで文字列を分割し、分割された状態で検索を行うため、1バイトずつ探索を行うのに比べて、高速に検索を行うことができる。 この、「一定のルール」を司るのがTokenizerと呼ばれるもので、 形態素解析 型、 N-Gram 型(文字列をN文字長分割する)などがある。 文書データをどう扱いたいのかによって、どのようなAnalizerを選択するかを決定する必要がある。 形態素解析 型を用いたAnalizer(Kuromoji Analysis Plugin)の場合 形態素解析 型を用いた場合、「 全文検索エンジン 」という文字列は次のように分割されます。 curl -X POST -k -H 'Content-Type: application/json' '/_analyze' --data '{ "analyzer" : "kuromoji", "text" : "全文検索エンジン" }' { "tokens": [{ "token": "全文", "start_offset": 0, "end_offset": 2, "type": "word", "position": 0 }, { "token": "検索", "start_offset": 2, "end_offset": 4, "type": "word", "position": 1 }, { "token": "エンジン", "start_offset": 4, "end_offset": 8, "type": "word", "position": 2 }] } N-gram 型のAnalizerの場合 N-gram 型を用いた場合、「 全文検索エンジン 」という文字列は次のように分割されます。 なお、検証に使用したAmazonESには、 N-gram 型のAnalyzerがありませんので、自分でTokenizerを指定してカスタムAnalyzerを定義しています。 curl -X PUT -k -H 'Content-Type: application/json' '/bigram' --data '{ "index":{ "analysis":{ "tokenizer" : { "bigram" : { "type": "nGram", "min_gram" : 2, "max_gram" : 2, "token_chars": [ "letter", "digit" ] } }, "analyzer" : { "bigram" : { "type" : "custom", "tokenizer" : "bigram" } } } } }' curl -X POST -k -H 'Content-Type: application/json' '/bigram/_analyze' --data '{ "analyzer" : "bigram", "text" : "全文検索エンジン" }' { "tokens": [{ "token": "全文", "start_offset": 0, "end_offset": 2, "type": "word", "position": 0 }, { "token": "文検", "start_offset": 1, "end_offset": 3, "type": "word", "position": 1 }, { "token": "検索", "start_offset": 2, "end_offset": 4, "type": "word", "position": 2 }, { "token": "索エ", "start_offset": 3, "end_offset": 5, "type": "word", "position": 3 }, { "token": "エン", "start_offset": 4, "end_offset": 6, "type": "word", "position": 4 }, { "token": "ンジ", "start_offset": 5, "end_offset": 7, "type": "word", "position": 5 }, { "token": "ジン", "start_offset": 6, "end_offset": 8, "type": "word", "position": 6 }] } 上記において、例えば「エンジ」というキーワードで検索を行った場合、 形態素 型のAnalizerを用いた場合はHitせず、N-gran型のAnalyzerを用いた場合はHitします。 もし、Elasticsearchを、 RDB の代替としてLIKE検索と同等の検索を行うのであれば、 N-gram 型のAnalyzerを使用することで実現できます。 一方で、 形態素 型のAnalyzerを使用する方が、検索結果としてはより自然な検索結果を得ることができます。 今回は、LIKE検索の代替という観点で検証するため N-gram 型を採用しましたが、Analyzerの選択については、本来は下記の基準で選ぶことになります。 確実にキーワードが含まれる検索結果を得たい場合 ⇒ N-gram 型 取り漏らしがあるが、自然な結果を得たい場合 ⇒  形態素 型 なお、Elasticsearchは、複数のAnalyzerを複合的に用いることもできますが、これについては今回の検証内容からは外しています。 match_phraseクエリ Elasticsearchを用いて 全文検索 を実行する際、どのような問い合わせを実行するかを指定することができます。 クエリ一覧 match クエリは、指定したクエリ文字列をAnalizerによって分解し、 それぞれのトークンの順序によらず、トークンが含まれているかどうか によって検索結果を導出します。 GET /_search { "query": { "match" : { "message" : { "query" : "全文検索エンジン" } } } } 例えば、「 全文検索エンジン 」というキーワードで問い合わせを行った時、AnalyzerにKuromojiを使用していれば、検索キーワードは 全文 、 検索 、 エンジン という3つの トーク ンに分割されます。 この時、「 全文検索エンジン とは」という文章だけでなく、「 エンジン が 全文 を 検索 します」という文章も、検索結果にHitします。 一方、LIKE検索のような中間一致検索にElasticsearchを使用したい場合は、 match_phrase クエリを使用する必要があります。 GET /_search { "query": { "match_phrase" : { "message" : { "query" : "全文検索エンジン" } } } } match_phraseクエリは、 それぞれのトークンの順序・出現位置が一致する ものを検索結果に導出します。 ですから、「 全文検索エンジン とは」という文章はHitしますが、「エンジンが全文を検索します」や、「全文を検索するエンジンです」といった文章はHitしません。 検証: PostgreSQL (pg_bigm)と比較してどれだけの検索性能が発揮できるか 次に、Elasticsearchとpg_bigmの検索速度の比較による検索性能の検証結果を見ていきましょう。 pg_bigmとは? PostgreSQL 上で動作する日本語に対応した 全文検索 用モジュール N-gram 方式で、2文字単位で分割する インストールやインデックスの構築が容易 SQL をそのまま利用できる 公式ドキュメント 検証に使用したデータ、およびデータ量 Wikipediaの日本語版全データ データ件数:約230万件 計測方法 無作為に選定したキーワード群からランダムに選定したキーワードを用いて1000回問い合わせを行い、問い合わせに要した時間(ネットワーク経路に係る時間などを除く)と、対象のキーワードでHitした文章の数をグラフにプロットする Elasticsearch、pg_bigmを適用した PostgreSQL 、無調整(B-treeインデックス)の PostgreSQL の3者に対して同様の検索を行い、グラフを比較する 計測に使用した環境 それぞれの検証に使用した環境およびスペックについては下記の通りです。なお、Elasticsearchは最小構成でも3ノードを要するうえ、Elasticsearchも PostgreSQL も、チューニングによって性能が変わるため、厳密にスペックを揃えることはしていません。(※傾向を掴むことを主目的としています) Elasticsearch Amazon Elasticsearch Service v6.7 インスタンス タイプ:t2.small × 3ノード PostgreSQL (pg_bigm) Amazon EC2 上に PostgreSQL をインストール(RDSではpg_bigmがサポートされていないため) v9.6( PostgreSQL ) v1.2(pg_bigm) インスタンス タイプ:t2.large × 1ノード PostgreSQL (デフォルト) Amazon EC2 上に PostgreSQL をインストール v9.6( PostgreSQL ) インスタンス タイプ:t2.large × 1ノード 計測結果と考察 まずはデフォルト(B-treeインデックス)の PostgreSQL の計測結果を見てみます。キーワードやそのキーワードのHit件数によらず、最低でも50秒以上の時間を要することがわかります。これは、キーワードによらず、シーケンシャルスキャン(テーブルの全レコードの走査)が行われるため、一定の時間がかかっていることが要因です。 デフォルトの PostgreSQL 次に、同一のスケールの場合のElasticsearchとpg_bigmの計測結果を見てみましょう。 この結果を見ると、双方、キーワードにHitするレコードの数に応じて速度が遅くなっている事が分かります。デフォルトの PostgreSQL が固定でシーケンシャルスキャンのコストがかかっているのに比べると、高速化が見込めることが分かります。しかし、キーワードHit数が多くなるにつれて、検索速度がかなり遅くなっていくようです。場合によっては、デフォルトの PostgreSQL と同等のパフォーマンスになるケースがあるようにも見えます。 Elasticsearch pg_bigm ※なお、このグラフを見ると、pg_bigmの方が高速であるように見えますが、これは検証に使用した環境の性能差によるものだと考えられます。ここでは詳細を述べませんが、Elasticsearchのノード数を増やす、 インスタンス タイプのグレードを上げることで、検索速度が向上することが確認できています。 先ほどのスケールでは分かりにくいので、もう少し拡大したグラフで計測結果を見てみましょう。 これを見ると、Hit件数が少ない場合(1000件~2000件程度)であれば、遅くとも数秒以下の速度で検索結果が得られているようです。 elasticsearch(拡大) pg_bigm(拡大) では、次のデータを見てみましょう。これはElasticsearch,pg_bigm双方で、「検索キーワードにHitした先頭10件」を検索するのに要した時間です。試行回数は1000回、単位はmsecです。   Elasticsearch pg_bigm 平均値 9 75 中央値 10 25 最大値 159 3641 これを見る限り、最大値こそpg_bigmで少し遅い結果が得られていますが、平均値・中央値を見る限り、「キーワードにHitする件数によらず、全体から先頭の少数の結果を取得することは、十分に高速な速度で実行できる」ということが分かります。 つまり、ここまで見てきた結果から、Elasticsearch, pg_bigmはいずれも次の傾向であると言えると考えられます。 キーワードにHitする件数によらず、全体から先頭の少数の結果を取得することは、十分に高速な速度で実行できる キーワードにHitする件数が膨大で、そのすべての結果を得る場合はデフォルトの PostgreSQL と同等、ないしそれ以上の時間を要する 一般的に、膨大な検索結果を一度に取得するケースは少なく、ページネート機能や無限スクロール機能を持ったUIデザインを用いて、部分的に順次読みだしていくという利用シーンの方が多いと考えられるため、後者のデメリットが顕在化することはあまりないのではないかと考えられます。 以上から、 検索速度という点 においては、 Elasticsearchとpg_bigmの間には決定的な差が無く、双方とも必要十分な検索性能を有する のではないか、という結論に達しました。 なお、今回は詳細に触れませんが、 RDB でLIMIT-OFFSETを使用して、集合の後半の検索結果を得る場合、速度が遅くなるケースがあります(これは SQL チューニングなどで対応できます)。 この現象はElasticsearchでも同様で、これを解決する手段として、Elasticsearchは次のような機能をデフォルトで持っています。 Search After ページネーションに最適化された検索方式で、検索結果を先頭ページから順次検索する際に利用できる Scroll 検索結果をキャッシュして、後から部分的に再利用できるようにする仕組み。初回のキャッシュ作成時は時間がかかる。 まとめ Elasticsearchは『速度改善』だけで選ぶものではない 私たちは、当初Elasticsearchを導入することによって検索機能の速度改善が見込めるのではないかという仮説に基づき検証を進めてきましたが、速度改善だけを主目的として導入の判断をすべきではないということが分かりました。 従来型の検索方式や使い方だけで判断するのであれば、わざわざElasticsearchを導入する必要はなく、pg_bigmでも十分に速度改善を見込む事ができます。 Elasticsearchには次のようなデメリットがあり、必ずしも選定条件として優位とは言えません。 Elasticsearchとpg_bigmを比較した場合のデメリット 学習コストがかかる Elasticsearchの特性や運用方法についての理解、 REST API の使い方を新たに習得する必要があります。一方、pg_bigmであれば、既存の SQL の知識をそのまま活用することができます。 別のサーバーリソースを要する Elasticsearchを耐障害性なども考慮して使用する場合、最低でも3台のノードを必要とし、 RDB とは別にリソースを確保する必要があります。 正規化できない、 トランザクション がない 前述の通り、Elasticsearchは正規化や結合が苦手ですので、マスタDBを使用した絞り込みなどの用途には向いていません。 また、 トランザクション が無いため、ACID性を期待しないか、または、別途仕組みを講じる必要があります。 この点においては、 PostgreSQL と一体になっているpg_bigmの方が設計やデータの取り回しがしやすいと言えるでしょう。 ※pg_bigmにも「インデックスサイズが大きくなる」「更新処理にオーバーヘッドが増える」というデメリットがありますが、これはElasticsearchを採用した場合と比較しての明確なデメリットとは言えないと考えています。 餅は餅屋である では、Elasticsearchはどのようなシーンで採用するべきなのかというと、 「Elasticsearchでしかできないこと」 が開発するシステムの要件に含まれている場合だと考えています。具体的には、 自然言語 で記述された大量の文書データに対して、 より文章として自然な検索結果を得たい 検索キーワードを基にした あいまいな検索結果を得たい システムの運用を継続するにつれて肥大化していくデータに対して、 動的に クラスタ 構成をスケーリングしたい というようなシーンではないでしょうか。こうした点については、 RDB では対応が難しい場合が多く、文章の検索に特化したElasticsearchならではの活用範囲であると考えています。 つまり、 従来型の検索方式の『代替』としての役割を期待することが間違っている のであり、 Elasticsearchの得意分野、かつ RDB では代替できないところ に採用することで、 Elasticsearchの価値が享受できる ということです。 最後に 今回の検証を行うまでは、ただ漠然と「Elasticsearchを使うと 全文検索 が速くなるらしい」といった程度の認識でしかありませんでしたが、検証を通して、Elasticsearchの特性や、活用範囲などを理解することができました。 今後、新規サービスの アーキテクチャ を検討する段階で、Elasticsearchの特性がうまく適用できるかどうか、という点が、 アーキテクチャ 選定の材料にできると考えています。 今回の検証結果が、少しでも皆様のお役に立てば幸いです。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 ←今読んでいる記事 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは データ匿名化 第5回:データ匿名化の指標 データ匿名化 第6回:実際の匿名化 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
こんにちは、株式会社 ラク スで横断的にITエンジニアの育成や、技術推進、採用促進などを行っている開発管理課に所属している鈴木( @moomooya )です。 前回はデータを匿名化する際の一般化の例についてお話ししました。 tech-blog.rakus.co.jp 今回は匿名化したデータがどの程度匿名化されているか数値化する方法についてお話ししていこうと思います。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは データ匿名化 第5回:データ匿名化の指標 ←今読んでいる記事 データ匿名化 第6回:実際の匿名化 匿名化指標 匿名化されたデータの特性を表す観点は複数あり、これらを指標としてデータがどの程度匿名化されているかを判断します。 これらのデータ特性はすべてを適用しなければならないものではなく、用途に応じて必要な特性を適用していくことが重要です。なぜならこれらのデータ特性を適用していくことによりデータの匿名性が上がりますが、元のデータからの乖離もまた大きくなるためです。データの匿名性を追求するあまり、利用の要件を満たさなくなってしまうようでは本末転倒です。 そのような中でも、k-匿名性は比較的どんな場合にでも利用出来そうに感じました。l-多様性も多くのケースで適用できそうです。ただし、t-近似性などは用途に応じて検討が必要になるでしょう。 k-匿名性 / k-Anonymity k-匿名性 はもっとも一般的な特性です。すべての準識別子を複合させた値で見た場合に、最低限 k 件のレコードが存在することにより k-1 件を区別することができない状態を指します。 例えば以下のようなデー タセット で考えてみます。 識別子 / Identifying 「名前」 準識別子 / Quasi-identifying 「色」 「種類」 機密属性 / Sensitive 「取引先」 漏洩したくない情報 とします。 匿名化の手順については第3回の記事で説明した通りです。 tech-blog.rakus.co.jp まずは識別子が削除されます。 そして準識別子は全て複合された項目として扱われるので以下のようになります。 注意:実際には「色」と「種類」が1カラムにまとめられるわけではないが理解のためこのように表現しています。 この時、準識別子の値を見ると全レコード異なった値になっています。例えば「緑の野菜」という情報があれば機密属性である取引先は「A商店」と確定してしまいます。他のレコードもこのままでは準識別子が特定された場合に機密属性である取引先が明確になってしまいます。 この状態は k=1 と表現し、 k-1 = 1-1 = 0 件が特定できない状態=必ず特定できる状態、となります。 k の値を増やすために色の情報を秘匿してみます *1 。 こうなると準識別子で特定できるレコード数は 「果物」「野菜」が 3 レコード 「花」が 2 レコード となり、k の値は最小の値を表現するので k=2 となり、 k-1 = 2-1 = 1 件となるので特定の1件を特定することはどの値をとった場合でもできない状態となりました。 例えば「花」という情報があっても「花」のレコードが2件あるのでどちらが特定したいレコードなのか判断できない状態になっていることを指します。 l-多様性 / l-Diversity しかしながら見ての通り「花」というレコードは2レコードありますが、どちらも機密属性である取引先が「B商事」となっており、レコードは特定できなくとも機密属性の特定はできてしまいます。 これに対応する指標が l-多様性 となります。 l-多様性とは同一の準識別子に対して、機密属性の値が何パターンがあるかという指標になります。 上述の場合、k=2になっているものの、l=1となっているため、機密属性が特定される状態になっています。 このとき、l の値を大きくする方法として 準識別子の一般化を見直す lが小さな項目を秘匿してしまう 通常は一般化の見直しが理想的ですが、問題になっている値のグループが少数の場合には秘匿してしまうのもアリでしょう。 種類が「花」の取引先を秘匿したことで機密属性も特定できなくなりました。種類が「果物」「野菜」の取引先は「A商店」と「B商事」の2種類を含んでいるため l=2 となります。 t-近似性(近接性とも) / t-Closeness l-多様性について準識別子ごとに特定される機密情報を複数にするというアプローチを撮りましたが、デー タセット によってはデータの偏りが発生することがあります。 たとえばデー タセット 全体としては全国の取引先が入っているのに、特定の準識別子には特定地域の取引先しか入っていないなどです。 こういったデー タセット 全体に対するデータの偏りを t 以下にする指標が t-近似性 です。 t の値はデー タセット 全体と、準識別子ごとのサブデー タセット の分布の距離によって定められますが、この分布の距離を測定する方法としては 地球移動距離(EMD: Earth Mover's Distance) という距離尺度で測定するのが一般的なようです。しかし今回の検証ではt-近似性までは必要としなかったため詳細について気になる方は各自ご確認いただければと思います *2 。 その他 上述の他にもk-Map、δ-Presense、δ-Disclosure privacy、β-Likenessなどがあるようですが、これらは調査できていないためキーワードの列挙のみとさせてください。 まとめ 今回は匿名化したデータがどの程度匿名化されているか数値化する方法について触れました。 これらの指標値がどの程度の値になれば適正なのかは第2回で説明したリスクメトリクスの考え方を組み合わせて判断していくことになります。 tech-blog.rakus.co.jp 次回は実際のデータ匿名化を行う流れと、評価に利用したツールについてお話ししたいと思います。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは データ匿名化 第5回:データ匿名化の指標 ←今読んでいる記事 データ匿名化 第6回:実際の匿名化 *1 : 第3回の記事ではなるべく秘匿しないように、と書きましたがここでは説明を簡単にするため秘匿します。 *2 : すごく大雑把にいうと各分布に含まれる要素間の距離を重みを考慮して総和したようなものらしいです。
アバター
こんにちは、新卒2年目のmrym_618です。 今回は、 VBA やマクロを使わずに、 Excel で 正規表現 を使って置換する方法についてまとめていきたいと思います。 はじめに エディタを使って置換する方法 最後に はじめに 最近、業務で Excel を 正規表現 を使って置換したいことがありました。 しかし、 Excel の置換機能では、 正規表現 を使うことができませんでした。 VBA やマクロを使えばできそうですが、 VBA やマクロの知識があまりないので少し難しそうだと思っていました。 そこで、もっと簡単に 正規表現 を使える方法について調べてみると、エディタを使うことでできることがわかりましたので、その方法を紹介していきたいと思います。 エディタを使って置換する方法 今回は、 サクラエディタ を使った方法について紹介します。 まず、 Excel をコピーし、 サクラエディタ に貼り付けます。 その後、 サクラエディタ のメニューバーの「検索」→「置換」を選択します。 ここで、「 正規表現 」にチェックを入れ、置換したい文字列を入力します。 最後に、置換した文字列を Excel に貼り付けることで、 Excel の文字列を 正規表現 を使って置換することができます。 最後に 今回は、エディタを使い Excel で 正規表現 を使って置換する方法についてまとめました。 この方法を使うことで、 VBA やマクロの知識がなくても 正規表現 を使って置換することができますので、もし同じことで困っていれば、参考にしてもらえると幸いです。 また、今回は サクラエディタ を使う方法を紹介しましたが、他のエディタでも同様のことができるはずなので、ぜひ試してみてください。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
こんにちは、株式会社 ラク スで横断的にITエンジニアの育成や、技術推進、採用促進などを行っている開発管理課に所属している鈴木( @moomooya )です。 前回はデータを匿名化していく手順と、匿名化したデータを比較するための情報量の算出についてお話ししました。 tech-blog.rakus.co.jp 今回は匿名化する中で一般化をする際の具体的な値の置き換え方法についてお話ししていこうと思います。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは ←今読んでいる記事 データ匿名化 第5回:データ匿名化の指標 データ匿名化 第6回:実際の匿名化 一般化とは 前回お話させてもらいましたが 一般化 値をグルーピングした値に置き換えることで特定しにくい状態にする 「1989年09月14日生まれ」を「1989年生まれ」にする、など 一般化の前後で情報量を計測し、差分を求めることで失われた情報量を 定量 化する 秘匿してしまうとデータが完全に失われてしまうため、まずは出来るだけ一般化することができないかを検討すると良いでしょう。 ということです。 ただし、一言に一般化と言っても具体的な値の置き換え方は色々あります。また、前回は グルーピングした値に置き換えることで としていましたが、これは一例に過ぎず一般化の範囲はもう少しバリエーションがあります。 それぞれについて見ていきたいと思います。 一般化の方法 一般化の方法は値の種類――日付であったり、数量であったり、自由入力テキストであったり――によって変わってきます。 日付、時刻 日付や時刻を一般化する際には大きく分けて「間隔を維持したい場合」と「間隔を維持する必要がない」ケースに分かれます。 間隔を維持する場合 レコード間の日付や時刻の分布や感覚を維持したい場合は一律n日/n時間ずらすといった固定でスライドする方法があります。 例)3日ずらす 2019/08/29 → 2019/09/02 2019/09/01 → 2019/09/04 ※2日の間隔は維持される 間隔を維持する必要がない場合 間隔を維持する必要がない場合や「だいたい同程度」「平均で同程度」の間隔になればいいケースでは、各レコードに一律の値ではなく -n 〜 +n の範囲でランダムな値でずらす方法があります。 こちらの方がより情報量が低下(=特定しにくくなる)します。 数量、年齢 数量や年齢についてはデータの分布具合に応じて調整が必要になることがあります。 単純な一般化 [23, 30, 42, 48, 51] を1の位で切り捨てて [20, 30, 40, 40, 50] などとする。いわゆる年齢についての20代、30代というのがこちらです。 基準に応じた一般化 先ほどと同じデータですが、 マーケティング の年齢区分(1: 20~34, 2: 35~49, 3: 50~)などの基準で分ける分け方もあります。 [23, 30, 42, 48, 51] 上記に従うと [1, 1, 2, 2, 3] となります。これに性別(F: 女性, M: 男性)を組み合わせることで マーケティング でよく耳にする「F1層」などとなってきます。こちらも一般化の1例となります。 自由入力テキスト 自由入力のテキスト項目というのは匿名化を考える上で、どんな情報が含まれるのか読みにくいため厄介なものです。 対応としてはあらかじめ定義したルールに従って置き換えを行う ルールベースでの一般化 と統計や 機械学習 を利用する パターンベースの一般化 があります。 それぞれルールベースでは検出漏れが少なく、モデルベースでは誤検出が少ないと言われ、ルールベースで検出した後にモデルベースで検出するのが理想とされています。 今回の取り組みではルールベースでの置き換えを試しました。 今回はElasticsearchの性能検証を行うためのテストデータだったことと、自由入力テキスト項目が特別重要というわけではなかったため、Elasticsearchと同じ 形態素解析 エンジンであるkuromojiを利用して 形態素解析 を行い、名詞の大部分を意味のない文字列(「●●●●」など)に単純に置き換えています。 例) ラクスは新宿にある会社です。 ↓ ●●●●は●●●●にある●●●●です。 まとめ 今回はデータ項目の一般化について具体的な置き換えルールについて触れました。 しかしこれらはほんの1例であり、扱うデータ項目の意味合いに応じて適切な一般化ルールを設定していく必要があります。 次回は実際にデータを置き換えた後のデー タセット が「どの程度匿名化されているのか」を表現する方法についてお話ししたいと思います。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは ←今読んでいる記事 データ匿名化 第5回:データ匿名化の指標 データ匿名化 第6回:実際の匿名化
アバター
こんにちは。最近、体型維持の目的で筋トレを始めたbadaikiです。 先日、業務で PostgreSQL のテーブルサイズを調査することがあり、 PostgreSQL の仕様の理解が不足していると実感しました。今回はそのことについて備忘録的に書いていこうと思います。 はじめに PostgreSQLのデータサイズの持ち方 概要 TOASTテーブル 実際に取得してみる システムカタログ 取得手順 おわりに 参考 はじめに 冒頭にも記載しましたが、業務で PostgreSQL のテーブルサイズを調査する機会がありました。テーブルサイズを調査する上で PostgreSQL の仕様について理解したことや、テーブルサイズの調べ方をまとめていきます。 実は過去に資格受験でこの辺りを学習していたのですが、すっかり内容を忘れておりました。 資格学習での知識って実用可能なレベルで理解するのは難しいですね... PostgreSQL のデータサイズの持ち方 概要 PostgreSQL は固定長のページサイズ(通常8kB)を使用し、複数ページにまたがる行(tuple)を許しません。それによって大規模なフィールド値を直接格納することができません。そこでフィールド値を圧縮したり、複数の物理的な行に分割するTOASTと呼ばれる技法を用いたりして大規模なフィールド値を格納しています。 ※なお、TOASTは可変長(varlena)表現を持つデータ型のみサポートしています。 TOASTテーブル ページサイズを超過し物理的に分割された行はTOASTテーブルに格納されます。TOASTテーブルは通常のテーブルを定義するとそのテーブル専用のTOASTテーブルが作成されます。TOASTテーブル名は pg_toast_{対象テーブルのoid} になります。 テーブルリスト TOASTテーブルの構成は以下のようになっています。 名前 型 説明 chunk_id oid 特定のTOAST化された値を識別するOID chunk_seq integer 値の塊に対する連番 chunk_data bytea 塊の実際のデータ そして chunk_data の値が TOAST_TUPLE_TARGET バイト(通常1994Byte)より小さくなるかそれ以上の縮小ができなくなるまで、フィールド値の圧縮や行外への移動を繰り返します。 下のレコードは約150kBのフィールド値をもつテーブルのTOASTテーブルです。 TOASTテーブル 実際に取得してみる システムカタログ テーブルサイズを取得するために登場するシステムカタログを紹介します。その中でも登場するカラムのみ抜粋して説明していきます。 pg_class このカタログは、テーブルとその他に列を持つもの、あるいはテーブルに似た全てのものを列にしています。その中にはインデックス(pg_indexも参照)、シーケンス、ビュー、マテ リアライズ ドビュー、複合型およびTOASTテーブルが含まれます。 名前 型 説明 oid oid 行識別子(隠し属性です。明示的に選択しなければなりません) relname name テーブル、インデックス、ビューなどの名前 relnamespace oid このリレーションを持つ 名前空間 のOID reltoastrelid oid このテーブルに関連しているTOASTテーブルのOID。 何もない場合はゼロです。 TOASTテーブルは"行に収まらない"大きい属性を副テーブルに格納します。 relkind char rは通常のテーブル、iはインデックス、Sはシーケンス、vはビュー、mはマテ リアライズ ドビュー、cは複合型、tはTOASTテーブル、fは外部テーブルを表します。 pg_namespace pg_namespaceカタログは 名前空間 を保存します。 名前空間 は SQL スキーマ の裏にある構造です。それぞれの 名前空間 は、リレーション、型などの集合を、名前が競合することなく、個別に持ちます。 これは pg_class.relnamespace から参照されます。 名前 型 説明 oid oid 行識別子(隠し属性です。明示的に選択しなければなりません) nspname name 名前空間 の名前 取得手順 ① 対象テーブル情報を取得する SELECT pc.oid, relname, reltoastrelid FROM pg_class pc INNER JOIN pg_namespace pn ON relnamespace = pn.oid WHERE nspname IN ( ' public ' , ' pg_catalog ' ) AND relkind IN ( ' r ' , ' S ' , ' i ' ) AND relname = ' {対象テーブル名} ' ORDER BY relname; 対象テーブル情報取得結果 WHERE句の条件にTOAST要素を追加するとTOASTテーブルも取得できます。 SELECT pc.oid, relname, reltoastrelid FROM pg_class pc INNER JOIN pg_namespace pn ON relnamespace = pn.oid WHERE nspname IN ( ' public ' , ' pg_catalog ' , ' pg_toast ' ) AND relkind IN ( ' r ' , ' S ' , ' i ' , ' t ' ) AND relname = ' pg_toast_16404 ' ORDER BY relname; TOASTテーブルのoid取得結果 ② 対象テーブル中の行の長さを取得する SELECT tuple_len FROM pgstattuple( 16408 ); pgstattuple() 関数を呼び出すにはモジュールを取り込む必要があります。 取り込み方法は↓のサイトに記載されています。 https://www.postgresql.jp/document/9.4/html/contrib.html pgstattuple() 関数の引数はテーブル名でも可能です。 select tuple_len from pgstattuple( ' big_tuple ' ); select tuple_len from pgstattuple( ' pg_toast.pg_toast_16404 ' ); TOASTテーブルは pg_toast というTOAST専用の スキーマ に所属しており、またpg_toastは スキーマ サーチパスに含まれていないので、検索するときは スキーマ 名をテーブル名の前に付けておきます。 ③ (参考)TOASTテーブルの取得 SELECT chunk_id, chunk_seq, chunk_data, OCTET_LENGTH(chunk_data) FROM pg_toast.pg_toast_16404 TOASTテーブル(再掲) おわりに 今回は業務で PostgreSQL のテーブルサイズを調査したことをきっかけに、どのような構成でTOASTが成り立っているのかを更に調べました。1行に大規模なデータが格納されている場合に、どのような仕様で実際どのような形で格納されているのかを確認することができました。 1つの物事に焦点を当て、深掘りする楽しさを経験することができました。 参考 www.bishounen.sakura.ne.jp kaigai.hatenablog.com detail.chiebukuro.yahoo.co.jp エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
こんにちは、株式会社 ラク スで横断的にITエンジニアの育成や、技術推進、採用促進などを行っている開発管理課に所属している鈴木( @moomooya )です。 前回は匿名化された個人情報において 個人が特定されない とはどういうことなのかについてお話ししました。 tech-blog.rakus.co.jp 今回は匿名化のプロセスについてどういった手順で行うのかをお話ししていこうと思います。 第1回、第2回がこってりした文量になってしまったので今回は軽めに行きたいと思います。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス ←今読んでいる記事 データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは データ匿名化 第5回:データ匿名化の指標 データ匿名化 第6回:実際の匿名化 匿名化の手順 デー タセット を匿名化する場合に以下の手順で進めて行きます。 対象デー タセット 内の識別子と準識別子を定義する 識別子を削除する 準識別子をなるべく秘匿せずに一般化する 検証要件に合わせて一般化の度合いを調整する 平均情報量を計測する それぞれ見て行きましょう。 1. 対象デー タセット 内の識別子と準識別子を定義する まずはデー タセット の各項目を 識別子 と 準識別子 に分けていきます。 識別子 その情報単体で個人を特定できる情報 氏名、社員番号、会員番号、など 準識別子 他の情報と容易に照合することができ、それにより特定の個人を識別することができることとなるもの 性別、年齢、 都道 府県、居住ビル、など 2. 識別子を削除する 次に識別子をすべて削除します。削除は非可逆な置き換えを含みます。 3. 準識別子をなるべく秘匿せずに一般化する 秘匿 、 一般化 という言葉が出てきました。 準識別子を匿名化する場合にはこんな方法があります。 秘匿 外れ値などの特定しやすい値を(NULLなどで)上書きする 上書きの単位は項目単位やレコード単位で行う 秘匿されたデータの量は 欠損 としてメトリクス化される 項目単位の欠損は セル欠損 、レコード単位の欠損は レコード欠損 と呼ばれる 一般化 値をグルーピングした値に置き換えることで特定しにくい状態にする 「1989年09月14日生まれ」を「1989年生まれ」にする、など 一般化の前後で情報量を計測し、差分を求めることで失われた情報量を 定量 化する 秘匿してしまうとデータが完全に失われてしまうため、まずは出来るだけ一般化することができないかを検討すると良いでしょう。 サブサンプリング デー タセット のレコード数が必要以上に多い場合は必要なレコード数を抽出(サンプリング)することで、デー タセット のサブセットを作ることも匿名化に有効な手段になります。 サブセットを作ることでデー タセット に含まれているか、含まれていないかという情報を秘匿することができます。 一般化でグルーピングする範囲 一般化でグルーピングする範囲には注意が必要です。 例えば以下のような値の場合に単純に10ごとのグルーピングをすると実質的に一般化されていないことになります。 13才, 27才, 32才, 59才, 61才 ↓ 10代, 20代, 30代, 50代, 60代 このような場合は 0〜39才, 0〜39才, 0〜39才, 40〜79才, 40〜79才 といったようにグルーピングする値域を変えなければなりません。 ただし、大量のレコードを含むデー タセット の場合には各値を見ながらグループの値域を判断するというのは現実的ではありません。Mondrian アルゴリズム *1 というグループの値域をもとめる アルゴリズム があるので、こちらを用いて値域を求めるのが良いでしょう。 4. 検証要件に合わせて一般化の観点や度合いを調整する 一般化は1度行って終わりではありません。 デー タセット の用途に応じて一般化の観点や度合いを調整する必要があります。どういうことかというと、 [リンゴ, レモン, キウイ, ニンジン, レタス, ダイコン, タンポポ, スズラン] というデー タセット を [果物, 果物, 果物, 野菜, 野菜, 野菜, 花, 花] と種類で一般化した場合に、検証したい内容が「種類で絞り込んだ検索性能」だったとしたら、一般化する観点を「種類」以外の観点に変えるべきでしょう。 一般化の観点が変われば情報量も変化することになります。変化した情報量が問題ないかどうかは匿名加工の方法を変更するたびに計測する必要があります。 5. 平均情報量( エントロピー )を計測する 平均情報量( エントロピー )とは ここまでに何度か「情報量」という表現が出てきていますが、厳密には 平均情報量( エントロピー ) を扱い、確率の小ささの度合いを示します。 平均情報量の算出方法 例をあげると 赤玉4個、青玉2個、黄玉2個が入った袋から1個を取り出す時の平均情報量を求める時、それぞれの確率は 赤玉の確率 4/8 = 1/2 青玉の確率 2/8 = 1/4 黄玉の確率 2/8 = 1/4 となります。 情報量を求める公式は「 」 *2 で、平均情報量は各場合の総和となります。 ちなみに分数の対数(log)は対数(log)の引き算に直せて、 なので $$ \begin{align} \log_2\frac{1}{\frac{2}{3}} &= \log_2{1} - \log_2{\frac{2}{3}} \\ &= 0 - \log_2{\frac{2}{3}} \\ &= -\log_2{\frac{2}{3}} \end{align} $$ とか $$ \begin{align} \log_2\frac{1}{\frac{1}{2}} &= \log_2{1}-\log_2{\frac{1}{2}} \\ &= \log_2{1} - (\log_2{1} - \log_2{2}) \\ &= 0 - (0 - \log_2{2}) \\ &= \log_2{2} \end{align} $$ と変換できます。 先ほどの確率を公式に当てはめると $$ \begin{align} \log_2\frac{1}{\frac{1}{2}} + \log_2\frac{1}{\frac{1}{4}} + \log_2\frac{1}{\frac{1}{4}} &= \log_2{2} + \log_2{4} + \log_2{4} \\ &= 5 bit \end{align} $$ となります。 今度は色を全て混ぜて(一般化して)灰玉8個から1つを選ぶ場合(当然常に灰玉が選ばれます) $$ \begin{align} \log_2\frac{1}{\frac{8}{8}} &= \log_2\frac{1}{1} &= \log_2{1} \\ &= 0 bit \end{align} $$ となり、情報量は0 bitとなります。この時、一般化によって情報量が5から0に損なわれていると考えます。 なお、情報量が損なわれる=レコードが特定しにくくなるということなので、匿名加工後の情報量が大きければ大きいほどレコードを特定しやすいという見方ができます。ただし、これは情報量の多寡を比較することができますが、デー タセット 自体の特性によって基準が変わるため「一律で情報量がいくつ以下であれば安全」という使い方はできないので勘違いしないでください。 具体的な例 [リンゴ, レモン, キウイ, ニンジン, レタス, ダイコン, タンポポ, スズラン] といった値がバラバラなデー タセット を「果物」「野菜」「花」と種類により一般化したとします。 [果物, 果物, 果物, 野菜, 野菜, 野菜, 花, 花]と一般化 この時の一般化前の情報量は $$ \begin{align} 8 \times \log_2\frac{1}{\frac{1}{8}} &= 8 \times \log_2{8} \\ &= 24 bit \end{align} $$ 一般化後の情報量は $$ \begin{align} \log_2\frac{1}{\frac{3}{8}} + \log_2\frac{1}{\frac{3}{8}} + \log_2\frac{1}{\frac{1}{4}} &= -\log_2\frac{3}{8} - \log_2\frac{3}{8} + \log_2{4} \\ &= 4.83 bit \end{align} $$ *3 ここで一般化したデータが種類で一般化されたものでは検証に適さなかったため、色で別れるように一般化を見直したとします。 [赤, 赤, 黄, 黄, 緑, 緑, 白, 白]と一般化の観点を変更 その場合の情報量は $$ \begin{align} 4 \times \log_2\frac{1}{\frac{1}{4}} &= 4 \times \log_2{4} \\ &= 8 bit \end{align} $$ となり、種類で一般化したデー タセット (情報量 4.83 bit)よりも情報量が増しています。 情報量が増している、すなわちレコードが特定しやすくなっている ため、 リスクマトリクスを再計測して匿名化度合いが十分かどうか再評価 する必要がある、という考え方をします *4 。 まとめ 今回はデータを匿名化するにあたっての手順と、匿名化したデータの情報量の算出について触れました。 これで異なる匿名化方法を選択したデータ同士を比較することができるようになりました。 次回は一般化の具体的なデータ置き換え例についてお話させていただければと思います。 連載目次 『全文検索 〜 Elasticsearchとデータ匿名化手法』 『全文検索の探求 Elasticsearch(1) 』: プロジェクト方針およびElasticsearch概要 大量データを検索するサービスでElasticsearchはRDBの代替候補になりうるか?(Elasticsearch vs pg_bigm)』 データ匿名化 第1回:匿名化された個人情報とは何なのか データ匿名化 第2回:個人情報は匿名化しても意味がないのではないか? データ匿名化 第3回:個人情報を匿名化するプロセス ←今読んでいる記事 データ匿名化 第4回:匿名化のために行うデータ項目の一般化とは データ匿名化 第5回:データ匿名化の指標 データ匿名化 第6回:実際の匿名化 MathJax.Hub.Config({ tex2jax: { inlineMath: [["\\(","\\)"] ], displayMath: [ ['$$','$$'], ["\\[","\\]"] ] } }); *1 : 名前の由来は コンポジションシリーズ で有名な画家 ピエト・モンドリアン かと。 *2 : ちなみに対数の底は2に限らないようですが、底が2の場合に単位をbitとするようなので本稿では2を用います。 *3 : 対数の計算は Google 計算機や Excel や 関数電卓 で計算してしまうのが楽です。 *4 : 情報量が増す≠特定されるのでダメ、ではありません。情報量が増した場合にはその情報量が「問題あるのかないのか」を 再測定する必要 があるという考え方をしましょう。
アバター
こんにちは。新卒2年目のchoreiiです。 最近は会社所有の書籍を読むのが趣味になってきています。 今回のブログはそんな書籍のうちから ソフトウェアテスト に関する1冊を紹介します。 目次 目次 はじめに ソフトウェアテスト手法 同値クラステスト 境界値テスト ペア構成テスト 最後に 参考 はじめに 今回紹介するのは「はじめて学ぶ ソフトウェアテスト のソフト技法」という書籍になります。 https://www.amazon.co.jp/dp/B00HE8082Q 今まで業務でテストを作成・実施してきましたが、テストの手法などについて意識したことがあまりなく、既存のテスト仕様書に書き方や粒度をあわせて実施することが多かったです。書籍を読むことで、何気なくおこなっていたことが ソフトウェアテスト の手法の一つであることに気づかされたり、その手法を取った際のメリットなどについて体系的に学ぶことができました。 書籍で紹介されているテスト手法を簡単に紹介していきます。 ソフトウェアテスト 手法 ソフトウェアテスト の手法には、大きく分けて ブラックボックステスト の手法と ホワイトボックステスト の手法があります。 ブラックボックステスト 同値クラス テスト(同値分割) 境界値テスト(境界値分析) デシジョンテーブル ペア構成テスト(オールペア法) 状態遷移テスト ドメイン 分析テスト ユースケース テスト ホワイトボックステスト 制御フローテスト データフローテスト 今回は ブラックボックステスト の一部の項目について紹介します。 ちなみに、 デシジョンテーブル については ラク スのエンジニアがすでに解説している記事がありますので、よろしければこちらもご覧ください。 tech-blog.rakus.co.jp 同値クラス テスト 同値クラス テストとは、期待するテスト結果をグループ分けすることでテストを効率的に行う手法です。 例えば以下のような条件のシステムが存在するとします。 バイトの時給区分を決めるシステム 15歳未満は、雇用不可 15歳以上22歳未満は、学生 22歳以上は、一般 この場合、16歳や20歳の期待値はともに「学生」のはずです。今回のように項目が少なければ全ての歳のパターンをテストすることは可能ですが、これが1500〜1800などのグループで同一のテスト結果が期待である場合、全ての数値をテストすることは難しいですし非効率的です。今回の要件ですと、15〜21の数値のいずれかをテストすれだけで、期待値が「学生」のグループが正しく実装されているかどうかのテストは十分であると言えるでしょう。 同値クラス テストという名称を聞いたことがない、または普段意識していなくても何かをチェックする時は無意識のうちにこの手法が使われています。 境界値テスト 境界値テストは上記の 同値クラス テストと関連が深いです。 同値クラス テストが効率的にテストする手法なのに対し、境界値テストは効果的にテストを行う(バグを見つける)手法になります。上記のシステムですと、「雇用不可」と「学生」の境目は15歳になります。システムの設計者・実装者が少し間違えると境目が16歳になってしまうかもしれません。このようにバグは境界値とその周辺におこりやすいと言われています。この境界値を確認することで効果的にバグを発見することができます。 ペア構成テスト ペア構成テストは組み合わせテストの一つです。 入力項目(フォーム)が一つであればパターンもそんなに多くはなりませんが、項目が2つ3つとなっていくと入力のパターンは2乗3乗と膨れ上がっていきます。例えば0〜2が入力できるフォームが4つあるシステムを考えてみます。パターンは3の4乗で81パターンになります。これら全てのパターンをテストするのは難しいです。また、システムの欠陥の傾向として2つまでのパラメータによる欠陥が全体の欠陥の9割を占めるという話があるようです。そのためペア構成テストでは全ての入力項目のうち2つの入力値を抜き出したさいに全てのペアを網羅するようなテストパターンを作成します。 パターン 入力1 入力2 入力3 入力4 1 0 0 0 0 2 0 1 1 1 3 0 2 2 2 4 1 0 2 1 5 1 1 0 2 6 1 2 1 0 7 2 0 1 2 8 2 1 2 0 9 2 2 0 1 上記の表で全てのペアのパターンが網羅されていることがわかると思います。このペアを作るツールとして、 PICT(Pairwise Independent Combinatorial Testing tool) などが存在します。 最後に このブログを見て、 ソフトウェアテスト の手法のさわりを理解して興味を持っていただけたなら、是非とも紹介書籍を読んでみてください。今回紹介したようなテスト手法だけでなく、なぜテストをするのかといったテストの意義などの根本から順序立てて説明されているので本当におすすめです。実際の業務でのテストと照らし合わせながら読んでみると気づきや発見が出てくるので中々面白いです。私自身一通り読みましたがさらっとしか読めていないので、今度はじっくりともう一周読んでいきたいと思います。また他にもいい書籍を読みましたらご紹介できればと思っています。 参考 qiita.com gihyo.jp
アバター
こんにちは。2年目のy_kwmtです。業務でESLintに触れる機会があったので、ESLintについてブログにまとめます。 ESLintとは インストール 実行 エラー、警告の種類 最後に 参考 ESLintとは ESLintは JavaScript のための静的検証ツールです。 ファイル内のバグを見つけたり、括弧やスペースの使い方などのスタイルが統一されているかチェックします。 自分で検証ルールを設定することができるので、プロジェクトに合わせたルールを設定することができます。 インストール ESLintはNode8.10.0以降を利用して実行することができます。 Node.js のパッケージ管理ツールnpmを利用してインストールします。 > npm install -g eslint バージョン確認はこちらから実行することができます。 > eslint -v v6.3.0 実行 ESLintを実行するにあたって以下の2つのファイルを用意します。 hello.js function helloWorld(name) { document .body.textContent = "Hello World. " + nama + "!" } helloWorld( "World" ); .eslintrc { " root ": true , // 親階層を見るか否か " parserOptions ": { // サポートするJavaScript言語オプション " ecmaVersion ": 6 // ES6構文 } , " env ": { " browser ": true , // ブラウザのグローバル変数を有効にするか否か " commonjs ": true , // CommonJSグローバル変数とCommonJSスコープを有効にするか否か " node ": true , // nodeのグローバル変数とnode特有のルールを有効にするか否か " mocha ": true // mochaのグローバル変数を有効にするか否か } , " extends ": [ " eslint:recommended " ] , " rules ": { " array-bracket-spacing ": [ " warn ", " never " ] , // 配列内の括弧の間隔 " arrow-body-style ": [ " warn ", " as-needed " ] , // 矢印関数本体の周りの波括弧の使用 " arrow-parens ": [ " warn ", " as-needed " ] , // アロー関数の括弧の一貫した使用 " arrow-spacing ": " warn ", // アロー関数の矢印の後か前かにスペースを要求するか " brace-style ": [ " warn ", " 1tbs " ] , // ブレーススタイルを適用 " camelcase ": " warn ", // キャメルケース " comma-spacing ": [ " warn ", { " after ": true }] , // カンマ前後のスペース " dot-notation ": " warn ", // ドット表記スタイルの使用の奨励 " eqeqeq ": [ " warn ", " smart " ] , // 型安全でない等価演算子を排除 " indent ": [ " warn ", 2 , { // インデント " SwitchCase ": 1 , // ネストの深さ " FunctionDeclaration ": { " parameters ": 1 } , // 関数宣言のパラメータのインデントレベル " MemberExpression ": 1 , // 複数行のプロパティチェーンのインデントレベル " CallExpression ": { " arguments ": 1 } // 関数呼び出し式の引数のインデントレベル }] , " key-spacing ": [ " warn ", { " beforeColon ": false , " afterColon ": true , " mode ": " minimum " }] , // オブジェクトリテラル・プロパティのキーと値の間の間隔を強制 " keyword-spacing ": " warn ", // キーワードとキーワードの間隔 " no-console ": " off ", // consoleを許可しない " no-empty ": " off ", // 空のブロックステートメントを許可しない " no-multi-spaces ": " warn ", // キーワード間の2つ以上のスペースを許可しない " no-redeclare ": " off ", // 複数回同じ変数を宣言許可しない " no-restricted-globals ": [ " warn ", " Promise " ] , // 指定したグローバル変数を利用しない " no-trailing-spaces ": " warn ", // 行の末尾に空白を入れない " no-undef ": " error ", // 宣言していない変数を使用しない " no-unused-vars ": [ " warn ", { " args ": " none " }] , // 利用していない変数を警告 " one-var ": [ " warn ", " never " ] , // ブロックスコープ内では1度の宣言で必要な変数宣言を行う " padded-blocks ": [ " warn ", " never " ] , // ブロック内のパディングを強制 " object-curly-spacing ": [ " warn ", " never " ] , // 1行でオブジェクト定義する際、波括弧の前後に空白を入れない " quotes ": [ " warn ", " single " ] , // クォート " react/prop-types ": " off ", // propsの値に対してPropTypesを指定していない場合に警告 " react/jsx-no-bind ": " off ", // jsx内でのbindを禁止する " semi ": [ " warn ", " always " ] , // ASIのセミコロンの使用を許可するか否か " space-before-blocks ": [ " warn ", " always " ] , // ブロック前のスペースを許可しないかするか否か " space-before-function-paren ": [ " warn ", " never " ] , // 関数の括弧の前にスペースを許可するか否か " space-in-parens ": [ " warn ", " never " ] , // 括弧内のスペースを許可するか " strict ": [ " warn ", " global " ] // use strict を記述すること } } こちらの.eslintrcのrulesにコーディングのルールを追加、削除することができます。 サンプルコードhello.jsに対して次のコマンドを実行します。 > eslint hello.js(ファイル名) eslintコマンドを実行すると次のような結果が得られます。 合計で7つのエラーが発生しています。左から順に行番号と位置、警告かエラーか、警告とエラーの種類、.eslintrcに追加されているルール名が表示されています。 エラー、警告の種類 Use the global form of 'use strict' 'use strict'を省略しているので、警告が発生しています。 警告を出さないようにするにはファイルの先頭に'use strict'を追記してください。 こちらは「"strict": ["warn", "global"]」でルールを設定、解除できます。 Expected indentation of 2 spaces but found 4 インデントでスペース2個分開ける必要があるのに4個分開けているので警告が発生しています。 警告を出さないようにするにはインデントを修正してください。 こちらは「indent」でルールを設定、解除できます。 Strings must use singlequote シングルクォートを使用しなければいけないが、ダブルクォートを使用しているので、警告が発生しています。 警告を出さないようにするにはシングルクォートを使用してください。 こちらは「"quotes": ["warn", "single"]」でルールを設定、解除できます。 nama is not defined 「nama」という変数が定義されていないと怒られています。 エラーを出さないようにするにはnamaという変数を定義するか、削除してください。 こちらは「"no-undef": "error"」でルールを設定できます。 Missing semicolon 行末に セミ コロンがないので、警告が発生しています。 警告を出さないようにするには セミ コロンを追加してください。 こちらは「 "semi": ["warn", "always"]」でルールを設定、解除できます。 発生した7つの警告、エラーの修正を行い、再度eslintコマンドを実行して問題なければ、何も表示されません。 最後に ESLintで発生した警告の改修を業務で行ったことをきっかけに、ブログにESLintについてまとめました。 JavaScript のコーディングを行う方々の参考になればと思います。 コードを変更する際、コードが読みづらいと理解、変更に時間がかかってしまうので、 他の開発者に迷惑をかけないよう、設定されているコード規約を守り、読みやすいコードを書くことを心掛けていきます。 参考 qiita.com eslint.org エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
私の所属する開発チームで行ったモブプログラミングの様子についてご紹介します。 これからモブプログラミングしようかと考えているが、 ハードル高いなぁと感じているチームリーダーの方 チームに対してモブプログラミグを提案したいと思っているいちメンバーの方   こんな方に一読いただいて、文字だらけで恐縮ですが、イメージが湧いて参考になると幸いです。 きっかけ 巷で噂のモブプログラミング=通称モブプロ お隣の開発チームがやっていて、うちのチームもやらないといけない空気感に腹をくくる所から始まりました。 きっかけがやや不純ですが、チーム内で商材の知識と商材の実装経験の差が課題だった(商材特有の癖とか)のもありました。 モブプロをチームで体験してみるという目的をもち、巷でメリットと言われてることは本当なのか、身をもって確かめてみることにしました。 準備 やるからには、生半可なことをしてはいけません。 何事も準備で9割は決まると言われています。お隣のチームがモブプロを行った時の反省点や、いくつかモブプロに関するブログを読んで準備をしました。 参考までに https://takaking22.com/2018/mob-advent/ https://qiita.com/TAKAKING22/items/31e027dfb6ea8b1a8d69 https://speakerdeck.com/oohira/why-mob-programming 準備内容 モブプロやります!!宣言 チームメンバーに対して、そして周りに対して。言った以上、やらないわけにはいきません。 モブプロの素材を用意   メリットと言われてる、 暗黙知 の共有や実装しながらコードレビューが出来るなど、すぐに活かせそうということで、通常の機能開発で試すことにした。 例えモブプロがうまくいかなくても、メンバーとその機能の関連するコードについて試行錯誤したことは無駄にはならないだろうという考え。 使い捨て出来るようにあらかじめモブプロ用のbranchを用意しておく。細かい所ですが、お隣のチームの反省点より。   機能のどの部分を作るかを決めておく  初回は難しい箇所を選ばないことがベター。処理フロー図とかがあればより初回のハードルが下がる。 初回の役割を決めておく  ドライバー、ナビゲーター、 ファシリテーター (タイムキーパー) ナビゲータの調査用PCを用意 ドライバーのみPCというパターンが多いが、各自好きなタイミングでコードの調査ができるようにあえて用意 ディスプレイがあるもしくはプロジェクターを使える会議室 2時間予約(1時間半はモブプロ、残りの30分は振り返り) Let's モブプロ 開始ものの数分後、やるべき事の認識を合わせてる途中に仕様の曖昧な部分が発覚。 少し考え始めましたが、他部署との調整が必要なことがわかったので、曖昧な部分はモブプロ後に確認し、確実に仕様が決まっている箇所から実装を進めることにしました。 気づけば20分経過。。。 まだ1行もコードを書いていない。 これは、、まずい、そんな空気になりました。 「ここで課題見つかって良かったよね~」 とポジティブな発言で乗り切れるチームでよかったです。 最初こそロスはしたものの、その後気づけば1時間経過。 目的としていた箇所の大枠は実装し終え、挙動の確認ができている状態に。 最初の20分が嘘のようで、アウトプットを出すことができた。 <その1時間のまとめ> 機能の過去の経緯や背景 共通メソッドの選び方のレクチャー、考え方、 暗黙知 の共有 どういうロジックにするのか、各々案を出す こんなことを話しながら、気づいたら全員で楽しんでいました。普段、個々でもくもくと実装していると決してできない体験ができた。 初回のモブプロを終えて どうやら、巷での噂はホントっぽい。 <よかったこと・気づき> 暗黙知 の共有はできる 他の人がどの様に考えているかの勉強になった(ベテランのエンジニア同士のモブプロをしたため) 特にエラーの切り分け方とか、若手のメンバーに見せたい内容だった 1人で悩まずに済む 慣れたり、題材によってはコードレビューまで出来そうという前向きな感想も出た 実際にやってみてモブプロに対する不安感、抵抗感が一気にさがった(メンバーも私自身も) またモブプロやりたいと思える会だった 意見交換ができて、充実していた ドライバーは変えなかったが、その場の状況次第で決めればいいと思った 絶対にこうしなければならないということに縛られない方がよい 目的が達成できるなら手段は 臨機応変 に 参考ブログをみると、ナビゲーターの発言の仕方の注意点があったりしたが、そこに困ることはなかった チームで協力する際のメンバーの一面を見ることができた、人の意見に耳を傾けること、無下に案を却下したりしない相手に対してのリスペクト、気遣いができる所を改めていいなぁと思いました 初回に難しい箇所を選ばなかったのは吉 ドライバー(役割)を強要しない(初回は止むを得ず強要しました、ごめんなさい。一度体験すると抵抗はなくなってました) <課題感> 点でみるとコストをかけすぎな様に見える 手戻りでやり直すコストを抑えられるなら初期投資としてトータルで元はとれるのでは 準備する負担はややかかる 今回1人でやった準備をメンバーで分担すれば負担は軽減できる。が、現状では定期開催、週1回とかは現実的ではない ドライバーは普段使い慣れてないノートPCでやや使いにくかった   <今後の展望> レビューまで終わらせたい 若手を巻き込んでやってみたい 定期開催したい   まとめ 新しい取り組みを実際に 「やってみる」 、踏み出す一歩は勇気が要りますが、ダメでもともとと思えば(とはいえ、本気で成功させるための準備を決して怠ってはなりません)、 チャレンジすることのハードルは下がるのかもしれません。もちろん、良い面ばかりでもなく課題があるのは事実なので、濁すことも、隠すこともしていません。 その上で一度、騙されたと思ってモブプロをご賞味ください。 得られるものがあると思います。 追伸 先日、今後の展望の レビューまで終わらせたい 若手を巻き込んでやってみたい この2点にチャレンジしてみました。 レビューはなかなか遠いですが、難易度をあげても 何をやるか。 を明確にして準備をしていれば実装の大枠はアウトプットできることがわかりました。 若手(新卒2年目)を2人巻き込んで参加してもらい、 ツールの使い方 1人で悩まなくてもいい 気をつけるべきことをその場で共有できる この辺りにモブプロの良さを感じてくれていました。
アバター