TECH PLAY

株式会社ラクス

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

935

はじめに はじめまして、新卒1年目のyykaoruです。 今回は私事ですが、引っ越しをした際に実家にキーボード・マウスをおいてきてしまい、キーボード・マウス・モニターがない状態でなんとかして Raspberry Pi にアクセスするお話です。 やってみたこと概要 Raspberry Pi を購入しウキウキで 開封 していた際に、あることに気が付きました。 「あれ、ノートPCはあるけど、 Raspberry Pi 用のキーボードとマウスない・・・?」 しかし、どうにかして早くさわりたい...しばらく考えた結果 「せや!ネットワークに接続された Raspberry Pi の IPアドレス (プライベート)特定して SSH 接続でなんとかしたらええんや!」 今回は Raspberry Pi をセットアップする際にノートPCはあるのですが、キーボード・マウス・モニターがない場合に Raspberry Pi の IPアドレス を特定し、 SSH を利用して Raspberry Pi にアクセスする方法を紹介しようと思います。 今回の使用機器&環境 Raspberry Pi 4 Model B(8GB) Raspberry Pi 4 Model B用電源(USB Type-c 5V 3A) ノートPC(windows10) microSD (32GB) microSD をPCに接続するためのアダプタ(USBタイプ、SDカードタイプなどお好みで!) 有線LANケーブル ネットワーク環境 環境構築 Raspberry Pi の OS インストールは ラズベリー パイ財団公式が提供している Raspberry Pi Imager を利用します。 今回は Raspberry Pi で使用するOSとして Ubuntu 20.04.1 LTSを使用します。 OSのインストールが完了した後にSDカードをもう一度マウントするとSDストレージが出現し、中身はboot ディレクト リになっています。 ここの中に新たに ssh というファイル名のファイルを作成しておきます。 これにより、初期起動時に ssh 機能が有効になります。 Raspberry Pi に電源とネットワークルータにつながった有線LANケーブルを接続します。 2~3分くらい待ちます。 これで準備は完了です。 ノートPCから Raspberry Pi に SSH で接続 ノートPCで「 windowsキー + R」をし、入力欄に「cmd」と入力します。 すると コマンドプロンプト が起動します。 そこに「 arp -a」を打ち込みます。 すると同じネットワークに接続されている IPアドレス と MACアドレス が表示されます。 表示された一覧の情報で MACアドレス が「B8:27:EB:」か「DC:A6:32:」か「E4:5F:01:」で始まるものを探します。 これは Raspberry Pi の MACアドレス のレンジがこの3つに割り当てられているのでそれを利用して Raspberry Pi を特定する為です。 詳細は以下のサイトで確認できます。 udger.com 今回紹介した MACアドレス で始まる MACアドレス が書かれた行の IPアドレス をメモしておきます。 今回私の環境では「192.168.10.110」が割り当てられていました。 これで Raspberry Pi の IPアドレス が特定することができたので、 SSH 接続を試みます。 「 ssh ubunntu@192.168.10.110」を コマンドプロンプト に入力します。 すると以下の画像のように Raspberry Pi の Ubuntu に接続することができました。 ログインの初期パスワードはOSが Ubuntu の場合「 ubuntu 」となっているので、これを入力し、 新たにログ インパス ワードの設定を行うように要求されるのでパスワードを設定します。 これで、もう一度 SSH 接続をし、設定したパスワードでログインすると、 Raspberry Pi に接続することができます。 後は SSH のセキュリティ設定をするなり、お好きなツールのインストールを行ったり好きなようにできます! 所感 今回は休日で Raspberry Pi で遊ぼうとしたところ、肝心な入力系の機器を用意し忘れてしまったことから 新たな方法でのセットアップ方法を習得することができました。 始まりはとても初歩的なミスでしたが、結果として新しい知識を得ることができたのでとても満足しています。 セットアップした Raspberry Pi はせっかくなのでお家環境モニタリングシステムにでも活用しようと思います。 そのお話はまたいつかの機会にできたらと思います! では! エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
こんにちは、 id:eichisanden です。 社内の有志とDDD( ドメイン 駆動設計)関連の2冊の書籍の読書会を開催したので、ふりかえって書いていきたいと思います。 1冊目:「エリック・ エヴァ ンスの ドメイン 駆動設計」 エリック・エヴァンスのドメイン駆動設計 作者: Eric Evans 発売日: 2013/11/20 メディア: Kindle 版 最初の題材として選んだのは、DDDの原典「エリック・ エヴァ ンスの ドメイン 駆動設計」です。 長いので以後は「 エヴァ ンス本」と呼びます。 今年の1月〜6月に掛けて、計17回開催しました。 読書会をやるきっかけ ある日の社内チャットで、 エヴァ ンス本に挫折したことで盛り上がったのがきっかけでした。 章と書いてますが部の間違いです かく言う自分も Tweet をさかのぼると3年前に挫折していて、いつかリベンジしたいと思っていました。 第4部の途中まで読んだけど、途中から字面を追ってるだけになったので再読する前提で最後までキーワードだけ拾い読みした。普通に読んだら1ヶ月じゃ終わらんなこれ。 — A1 (@EichiSanden) 2017年1月31日 良い機会なのでみんなで読書会しようと言うことになり、社内で声をかけたところ10人のメンバーが参加してくれました。 本は会社経費で購入させてもらいました。技術書としても高い部類の本に入るので非常にありがたいです。 壮観ですが本当はもっとあります 読書会の形式 週に1回 各回1.5時間 エクストリームリーディング 形式 そもそも私自身が読書会を主催したことが無いため色々調べた結果、この方式に決めました。 なぜこの形式にしたかと言うと、下記のような仮説があったからです。 事前準備が必要だと参加者の負担が大きいのでは? 誰かが講師になるスタイルだとその人に掛かる負担が大きいのでは? 参加者の負担が大きいと参加が離脱していってしまうのではないか? 特に事前準備はせず(と言っても主催者の私は不安なので読みましたが)、読書会当日は数ページ程度のパートに切って、読んでは議論を数セット繰り返しました。 分からなかったことや他の人の意見を聞きたいことは付箋に書いおいて、読み終わったらホワイトボードに貼って議論しました。 やってみてどうだったか? みんなで理解を補いながら読めるから理解しやすい 参加者の中にはDDDを実践しているチームの人や、以前にこの本やIDDD本を読んで知識がある人がいたりして、 意味が分からなかったところは他の人の解釈を聞くことで理解の助けになりました。 ただし難しいところはみんなで読んでも難しい 内容の難しさに輪をかけて文章の構造が分かりにくくて意味が掴めない箇所については、 みんなで束になって掛かっても分からないこともありました。 10章しなやかな設計の「概念の輪郭」が意味わからなすぎて辛い。頭が割れるー — A1 (@EichiSanden) 2020年3月2日 理解できた方が良いんですが、みんなも分からないのだから自分だけ理解力がない訳ではないと言う変な安心感もありました(笑) これについては他の本も含め行ったりきたり何度も読むことでブレイクスルーがあるかもしれないと思いました。 もしかすると分からない文は英語の原書も併せて読むことで理解できる物もあるかもと思いました(これは実践できてませんが) 事前に読んできてもらうスタイルの方が良かったかもしれない 参加者の負担を下げたことで完走率は高くなったとも思いますが、 この本のように難易度が高い場合は、事前に読んできてもらい当日は議論に集中した方が良かったかもしれないとも思っています。 これは読書会に求める期待効果によって実施スタイルは今後は使い分ようと終わってみて思いました。 技術書を読む習慣がない人にもっと本を読んで欲しい  → 本を読む機会を作ることが目的なので当日読めば良い 本の内容を深く理解するため他の人と議論したい  → 事前に読んできてもらって議論を中心にする 2冊目:「 ドメイン 駆動設計 モデリング /実装ガイド」 booth.pm 今年の7月〜8月に掛けて、計8回開催しました。 読書会をやるきっかけ エヴァ ンス本でモデルや ユビキタス 言語など戦略的な設計はなんとなくは理解できたが、具体的なイメージが湧かなかったため評判が良かったこの本を読んでみたところ良い本でしたので読書会の題材にしました。 コロナの影響でオンラインでの開催になり場所の制約がなくなったため、他拠点のメンバーにも声をかけたところ18名ものメンバーが参加してくれました。 読書会の形式 オンライン形式(ZOOM) エクストリームリーディング形式 事前に Github のIssueに持ち回りで概要をまとめておく 当日は疑問点などをSli.doに書いてもらって読み終わったら議論した やってみてどうだったか? エヴァ ンス本に比べて本の内容がスッと頭に入ってくるので、当日読むスタイルでも無理なくやれました。 本を読んでもらった後、 Github のIssueにまとめた意訳と自分の理解のDiffをとることで更に理解が進みました。 メンバーが拡大したことでDDDを実践している人も増えて、他サービスでDDDを実践して困ってることなど生きた情報が共有されて良い読書会になりました。 番外編: モデリング 大会 参加者から発案で、去年にネット上で流行っていたチケット料金 モデリング を読書会の集大成として皆んなでやってみました。 実際に手を動かしてみると自分の理解度合いが分かりますし、コードも書いてみないとモデルを完成させるのが難しいと言うのを肌で感じることができました。 拙作ですが、モデルには「振る舞い」まで書かない方が良いかもね、と他の参加者にフィードバックもらいました。 github.com チケット料金 モデリング はお題としてちょっと難しかった気がするので、 もっとシンプルなお題でまたやってみたいと思っています。 最後に 読書会の題材としてDDDの本は向いていて、 エヴァ ンス本は複数人で助け合いながら読むのが良かったです。 エヴァ ンス本で モデリング や ユビキタス 言語の重要性を理解した後で、噛み砕いた本で理解を深めるのは順番としては悪くなかったのではと思っています。 読書会を開催する時の参考になれば幸いです。
アバター
はじめに PHP8で導入されるmatch式が導入されます。 プログラマ としてはどういった場面で使いやすいのか、バグが入りやすさはどうなのかといった点が気になるのではないかと思います。 この記事では、match式についてswitch文との違いを述べながら、構文の性質からどういった場面で役立ちそうかを私なりに考えまとめました。 はじめに match式とは matchは式。値を代入する場面で真価を発揮する 文とは 式とは breakが不要。バグが入りにくくシンプルな記述ができる switch match 条件の記入忘れにエラーで気付ける switch match 厳密な比較 switch match おまけ おわりに match式とは match式の基本的な構文と、switchとの相違点を大まかに記載します。 簡単に言ってしまうとswitchのような分岐の構文です。 $param = 1; $result = match($param) { 1 = > "1の結果", 2 = > "2の結果", } // 与えられた引数($param)に対して一致するケース(1または2)の結果(= > の右側)を返す // 結果:$result = "1の結果" 下記にswitch文との大まかな違いを記載します。 switch match 返り値 なし あり breakの記述 必要 不要 各条件の処理 ブロックで記述可能 1行でしか書けない 比較 緩やか(==) 厳密(===) どの条件にも当てはまらない場合 そのまま実行される エラーになる 次の章以降では、PHP8で導入されるmatch式がどのような場面で生きてきそうかを紹介します。 match式の詳しい仕様は下記もご参照して頂くとより分かりやすいかと思います。 参考: wiki.php.net qiita.com matchは式。値を代入する場面で真価を発揮する 比較表で返り値が、matchは「あり」、switchは「なし」と記載しました。 これは、matchが 式 であり、ifやswitchが 文 であるためです。 この章では、式と文の違いを見た上で、match 式 が役立ちそうな場面を紹介します。 文とは ざっくり説明すると、返り値を返さず、右辺に配置できないものです。 例:ifやswitchがこれにあたります。右辺に配置できないため直接値の代入はできません。 // 下記のような直接値を代入するような書き方は「文」ではできない $result = if($param == 1){… $result = switch($param){… このため、各条件での代入が必要であり、代入忘れの恐れがあります。 // ifやswitch文では各条件で代入が必要。ケースが増えると代入忘れが怖い /** if **/ if($param == 1){ $result= "1の結果"; } elseif($param == 2){ $result = "2の結果"; } /** switch **/ switch ($param) { case 1: $result = "1の結果"; break; default: $result = "defaultの結果"; } 式とは ざっくり説明すると、返り値を持ち「=」の右辺に配置できるもの。また文としても使えます 例:matchがこれにあたります。直接値の代入が可能なので、代入を各条件に記述する手間がなく、代入忘れもなくなります。 $result = match($param) { 1 = > "1の結果", 2 = > "2の結果", }; もちろん不要であれば代入しない書き方もできます。 match($param) { // $result = の部分は取り外し可能 1 = > func_hoge(), 2 = > func_huga(), }; 参考: jsprimer.net breakが不要。バグが入りにくくシンプルな記述ができる switchでは明示的にbreakの記述が必要です。breakを毎回書く必要があり書き忘れのチェックが必要なので、労力がかかります。ただし、そのまま次の条件の処理を実行(フォールスルー)する記述は簡単に書けます。 switch breakは明示的に記述が必要。フォールスルーがデフォルトであり、フォールスルーを想定した記述は簡単にできますが、その代わりにbreak忘れによるバグが入りやすい構造になっています。 switch ($param) { case1: func_hoge();// break忘れ case2: func_fuga();// case 1でヒットしても処理fugaも実行される } ただし、case1の場合はcase1,2を、case2のときはcase2のみを実行したい場合は上記のコードであっています。 breakを書かないことによりフォールスルーを簡単に実現できますが、その分「break忘れ」というバグが入り込む副作用を持っています match フォールスルーできない。その代わりbreakを明示的に記載する必要がなく、break忘れを気にしなくてよいです。 match ($param) { 1 = > func_hoge(), 2 = > func_fuga(), }; フォールスルー(case1の場合はcase1,2を、case2のときはcase2のみを実行)したい場合はmatchには向きません。 というのも、基本的にフォールスルーしない仕組みであることに加え、matchは条件の右辺に1行しか記載ができないからです。 このため、上記のswitchと同じことをしようとすると下記のようになります。 match ($param) { 1 = > func_hogefuga(), // ここに2行以上の記述はできない 2 = > func_fuga(), }; function func_hogefuga() {// 関数切り出しが必要になる func_hoge(); func_fuga(); } 条件の記入忘れにエラーで気付ける 分岐に限らず、予期せぬ値が代入される場合 や 意図せず何も代入されなかった場合は、エラーやログで気付ける方がよいです。 match式ではどの条件にもあてはまらない場合エラーになるため、誤りに気づきやすいです。 switch 条件が抜けていてもそのまま実行されます。 switchのようなエラーがでない仕組みの場合、バグが発生した時にケース忘れの可能性を考えることが必要となります。数行ならよいですが、ケースや処理が多い時は確認が大変です。 foreach ($users as $user) { switch ($user- > score) { case "good": $command = "upgrade"; break; case "bad": $command = "BAN"; break; // $user- > scoreがnormalの場合、どのケースも通らず値の代入が行われない。 // このため、次のループ処理にそのまま$commandの値が引き継がれる } $commandQue[$user- > id] = $command; } // batchキューに入れる // 日時で実行されるバッチで普通のユーザがBANされてしまう match 条件が抜けているとエラーになります。 matchのようにエラーとなる仕組みの場合、ケースの記述忘れを気にする必要がりません。 foreach ($users as $user) { $command = match ($user- > score) { "good" = > "upgrade", "bad" = > "BAN", // normalの場合はケースが無いので、エラーとなり、処理が中断される } $commandQue[$user- > id] = $command; } 厳密な比較 matchは厳密な比較のため「数値だと思っていたら文字列であり思わぬ分岐に入った」といったことががなくなります。 ただし、 PHP はそもそも厳密な比較を前提として作られているとは言えないので、厳密な比較にすることでエラーになることもあるので注意が必要です。(おまけで記載します) switch $hoge = "hoge"; switch ($hoge) { case 1: echo "1の結果"; break; case "hoge": echo "hogeの結果"; break; } // "1の結果" match $hoge = "hoge"; match ($hoge) { 1 => "1の結果", "hoge" => "hogeの結果", } // "hogeの結果" 一見すると厳密な比較の方が良さそうです。ただし、元々型を気にせず気軽に書けることが特徴でもあった PHP 。 古いコードでmatchを導入する際にはまずは、型をしっかり整備するなど対策が必要そうです。 おまけ PHP の関数が厳密な型を意識した作りでないため、思わぬエラーが発生する例を紹介します。 例:拡張子でケースを分けたい場合 下記の例では画像ファイル名の拡張子から処理を分岐させるコードです。 $img_name = "img.jpg"; /** switch_正規表現 **/ switch (true) { case preg_match('/(\.jpg)$/', $img_name): echo "jpgだよ"; break; case preg_match('/(\.png)$/', $img_name): echo "pngだよ"; break; // gif等その他の分岐が続く default: echo "defaultだよ"; } // = > "jpgだよ" /** match_正規表現 **/ echo match (true) { preg_match('/(\.jpg)$/', $img_name) = > "jpgだよ", preg_match('/(\.png)$/', $img_name) = > "pngだよ", // gif等その他の分岐が続く default = > "defaultだよ" }; // = > "defaultだよ" 実はpreg_matchは該当する場合trueでなく、1を返します。このためmatch式ではtrue===1となり、 正規表現 に該当してもそのケースに入ることはありません。 このように既存の関数の性質を正しく理解していないと思わぬバグを生む可能性があります。 おわりに この記事ではPHP8で導入されるmatch式について、switchと比較しながら、有効そうな場面やバグの入りにくさについて記載しました。 今後導入を検討している方やmatch式について知りたい方の一助になっていれば幸いです。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
はじめに こんにちは!技術広報チームの itoken1013です。 2020年に入ってから、 ラク スはオンラインイベント開催に積極的に取り組んでいます! 今回はその中でも多くの方に参加をいただき大好評である、 エンジニアの勉強法ハックLT を紹介します。 rakus.connpass.com はじめに イベント概要 LTの紹介 1. ゲームで学ぶマネジメント/白柳隆司さん 2. 私にとっての学び/ariakiさん 3. esaを使ったインクリメンタル勉強法/Eiichi Horiuchiさん 4. 面倒臭がりだってキャッチアップしたい - RE:Bot から始めるものぐさ生活/みのるさん 5. 三日坊主でも勉強がしたい/脱脂綿さん 6. 自己学習を支える Inoreader + Notion/Logyさん 7. やはり俺のLT登壇はまちがっている。/moomooyaさん おわりに & 次回予告 イベント概要 先日9/9(水)で2回目の開催となりました『エンジニアの勉強法ハックLT』は名前の通り、エンジニアの勉強法や情報収集のノウハウを気軽に5分間のLTで紹介しあうイベントです。 今回は計8名からLT枠のご参加、またエンジニア志望の学生さん、新人・ベテランエンジニア、デザイナーさんと幅広い層の方々にご来場いただきました。 Twitter もZoomのチャットも賑やかにしていただき、中の人である私も大忙しのイベントでした…! togetter.com LTの紹介 1. ゲームで学ぶマネジメント/白柳隆司さん いつも ラク スの主催イベントにご参加いただいている白柳さんより、 5種類のゲームから学べるマネジ メントス キルをご紹介いただきました。 おざなりにしがちなマネジメントを、気楽に楽しめるゲームの中で学ぶ発想に驚きました。 動画化も密かに楽しみにしています。 speakerdeck.com 2. 私にとっての学び/ariakiさん Zoomフル活用の双方向LTを展開いただいたariakiさんには、「学ぶこと」のそもそも論を語っていただきました。 原動力となる欲求に素直に従うことで、「やらされている感」で学習をしている人は悪循環から脱却できるのではと共感していました。 私もいつか日本酒の席に同席したいです。 docs.google.com 3. esa を使ったインクリメンタル勉強法/Eiichi Horiuchiさん 時間のない中で、どのように学習を継続的に実施していくかを esa を使った事例と共に語っていただきました。 学習計画をマークダウンで手軽に作成したスケジュールに落とし込み、週次で消化していくというものでしたが、同じく esa を使っている私からは驚きのクオリティでした。 そして編み出した方法論もさることながら、継続を支える知識欲への情熱とセルフマネジメント力には感服でした! esa.io 4. 面倒臭がりだってキャッチアップしたい - RE: Bot から始めるものぐさ生活/みのるさん みのるさんが取り組んだ情報収集の カイゼン をご紹介いただききました。 特徴的だったのは、自発的に探すのではなく Bot で自動化を目指した点、そして自動化を実現するまでの作業を楽しんで取り組まれた点でした。 日常生活を改善している感覚、楽しいですよね。 面倒臭がりでもキャッチアップしたい- RE:Bot から始めるものぐさ生活 - from MinoruIto3 www.slideshare.net 5. 三日坊主でも勉強がしたい/脱脂綿さん 脱脂綿さんには「やる気に頼らずに」続けるための勉強方法の実践例を3つ教えていただきました。 個人的にずっと気になっていたお風呂用の防水カバーを紹介いただき、 私も購入して湯舟読書に取り組みたいと思いました。 読書家の多い ラク スの社員でも、欲しいと思ってくれる人がいるはず…! speakerdeck.com 6. 自己学習を支える Inoreader + Notion/Logyさん 膨大な情報を収集して学習に活用するためのフローを、Logyさんから紹介いただきました。 噂に聞いていた2つのツールを組み合わせており、私もさっそくアプリをインストールしてみました。 チラッと映りましたタグがとても緻密で驚きました…! 取得漏れの少ない RSSリーダー Inoreader biz-notion.northsand.co.jp メモ、プロジェクト管理、タスク管理の All-in-One ツール Notion www.notion.so speakerdeck.com 7. やはり俺のLT登壇はまちがっている。/moomooyaさん 主催者のmoomooyaさんには今回のイベントも含めたアウトプット駆動学習とLT中毒について熱く語っていただきました。 全国の登壇者を喚起し、アウトプットに役立つ内容に溢れています。 moomooyaさんには今後も適度なボリュームのLT会をどんどんドライブしていっていただきたいです。 speakerdeck.com おわりに & 次回予告 今までになく Twitter にはコメントが多く、私たちも楽しく学ばせていただきながら運営を行うことができました。 LTにご登録いただきました方々、賑やかしていただいた皆様、ご参加ありがとうございました! 3回目の開催も近々行われるかもしれませんので、どうぞお楽しみに。 さて、10月以降も ラク スではイベント開催を加速させていきます! ITエンジニア的はじめての経験 を1分で語りたい方、お早めにご応募ください! rakus.connpass.com その他のイベントへのご参加もお待ちしています! rakus.connpass.com
アバター
こんにちは、west-cです。 業務にて要件定義を行う機会があり、その成果物である要求仕様書の書き方を学ぶために『 【改訂第2版】[入門+実践]要求を仕様化する技術・表現する技術 』という書籍を読みました。今回はその内容をご紹介します。 【改訂第2版】[入門+実践]要求を仕様化する技術・表現する技術 ~仕様が書けていますか? 作者: 清水 吉男 技術評論社 Amazon ◆ 関連ブログ 仕様書 とは 【まとめ】 おすすめの読者層 要求仕様書の目的・ゴールが曖昧な方 自身が作成した仕様書において、仕様漏れや仕様の衝突が後工程で発生したことがある or 発生しないか不安を抱えている方 依頼者から要求を引き出す方法の糸口を掴みたい方 要求仕様書とは 書籍では、要求仕様書を「 要求について、関係者がその内容について認識を特定できている文章 」と定義しています。 要求 (今回の機能で実現したいこと)は曖昧なものを含んでいるため、具体的な振る舞いや制限として 仕様 化することが要求仕様書の役割となります。 要求仕様にまつわる問題 多くの現場における要求仕様にまつわる問題として以下が挙げられています。 多くの現場では、設計の様子が見えるような具体的なレベルの仕様は、設計工程の中で掘り下げるものと考えられている。 そのような考えで書かれた要求仕様書は設計や実装のイメージにはつながらず、設計工程や実装工程で具体化するなかで仕様の漏れや衝突に気づくことになる。 これは私にとっては耳の痛い話で、はじめて仕様書作成を担当した機能において具体的な仕様に落とし込めていない仕様書を作成し、実装工程になってから実装担当者から質問が頻発する、という苦い経験がありました。 要求仕様書というと上流工程に位置することから細かい仕様は後工程で決める印象を持ちがちですが、少なくとも仕様の衝突が発生しない程度には具体化する必要があると改めて感じました。 仕様化のテクニック 要求仕様書では、依頼者から引き出した要求を仕様に落とし込む必要があります *1 。 仕様へ落とし込む方法について、書籍では以下に基づいたテクニックが紹介されています。 要求という振る舞いの中に含まれている動き(=動詞)をすべて表現してしまえば、それぞれの動詞および目的語について必要な仕様をもれなく記述できる。 例えば、以下のような要求があったとします。 印刷途中で、用紙やトナーの不足が分かった時点で担当者にメールで知らせる。 この文章において直接見えている動詞は以下の通りです。 不足が"分かる" メールで"知らせる" しかし、この要求に含まれる動詞はこれだけではなく、よく読むと以下の動詞も見えてきます。 用紙やトナーの量を"知る" メールを"組み立てる" 担当者のメールアドレスを"読み出す" これらの動詞をもとに仕様化を行う、というのが書籍で紹介されている仕様化のテクニックです。それぞれの動詞に対して仕様化すべき内容としては以下のようなものがあるでしょう。 用紙やトナーの量を知る 用紙・トナーの残量をどのように入手するか 不足が分かる 用紙・トナーの残量がどれくらいであれば不足と判断するか メールを組み立てる メッセージの構成をどうするか 担当者のメールアドレスを読み出す メールアドレスをどこから読み出すか メールで知らせる どのように通知するか 再送方法をどうするか 「よく読むと見えてくる動詞」は慣れないと洗い出しが難しそうですが、個人的には、その要求を実現するためのプロセスをイメージすれば、そのプロセス一つひとつが動詞と対応付くのではと感じました。設計や実装のイメージを持ちながら要求仕様書の作成を行う考え方は、ここに直結するのだと思います。 実践してみた 書籍にはこの他にも要求仕様書の作成に関するテクニックが紹介されており、筆者が推奨するフォーマットも提示されています。そこで、過去に自分が要件定義を行った機能について、改めて書籍の手法を用いて仕様化を行ってみました。 ちなみに書籍で紹介されている要求仕様書の作成手法は USDM という名前が付いているようです。調べると資料も見つかりますので、詳しく知りたい方は書籍と併せてそちらもどうぞ。 作成した要求仕様書 書籍で紹介されているフォーマットに厳密には従っていませんが、一つひとつの要求を仕様にブレークダウンする書き方は踏襲しています。また、要求に複数の動詞が含まれる場合は、要求をもう一段階層化して動詞を分解しています。 実践した感想 (良くも悪くも)考えるスコープを絞り込める 一つの動詞+目的語に絞り込まれた要求を仕様に落とし込んでいくため、考えるべきスコープを絞って集中的に仕様化できることを実感しました。これまでの私は思いつくままに仕様化していましたが、全体から詳細にブレークダウンしていくことでより網羅的に仕様の洗い出しができている感覚がありました。 一方、考えるスコープが絞られるということはより近視眼的になることでもあります。仕様化を進める中でも、複数の要求にまたがるような仕様が漏れそうという不安がありました。定期的に要求レベルに立ち返って全体を俯瞰するなど、鳥の目・虫の目の視点の切り替えが肝になると感じました。 要求と理由をセットで記述するのは効果あり 書籍では、「なぜこの要求を実現したいのか」という依頼者の思いを明らかにするため、要求は理由とセットで記述するよう紹介されています。 実際に理由を添えて記述することで、「そういえばこの要求はなぜ必要なのだろう?」と初心に立ち返りながら考えることができました。背景や理由を明文化することで、要求を実現するためのよりよい解に至ることもできるのではと思いました。 また、仕様の経緯を辿れるようにする意味でも、背景や理由をドキュメントに残しておく意義はあると思います。 おわりに 試しに実践してみたことで、書籍のテクニックが仕様漏れ防止の一助になると感じました。このフォーマットをいきなり既存の要求仕様書に置き換えるのはハードルが高そうなため、まずは抜け漏れ防止のクロスチェック的な立ち位置で部分的に取り入れたいです。 また当然ではありますが、いくら漏れなく仕様化できたとしても、そもそもの要求の認識が依頼者とズレていたのであれば元も子もありません。今後は要求の引き出し方についても深く学んでいきたいです。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com *1 : この記事では割愛していますが、書籍内には依頼者から要求を ヒアリ ングする方法も紹介されています。
アバター
はじめに はじめまして、新卒1年目のyykaoruです。 今回はDockerを勉強しようと思い、Dockerで PHP の実行環境を構築してみたお話です。 前提 Docker、docker-composeがインストールされていること やってみること概要 今回行うことは、 php コンテナにローカルストレージのsrcをマウントし、nginxコンテナからアクセスして確認、という流れです。 ファイル構成と ソースコード を順番に説明し、最後に実行してみたいと思います。 はじめに 前提 やってみること概要 ファイル構成 ソースコード docker-compose.yml default.conf Dockerfile php.ini index.php 実行 最後に ファイル構成 今回Dockerで PHP の実行環境を作成する上でのファイル構成は以下の通りです。 nginx Dockerコンテナ起動時、nginx内の設定ファイルに書かれている設定に上書きします。 なぜDockerファイルがないかは後に記述します。 php PHP コンテナを建てるために必要なDockerファイルと、 PHP コンテナの中に配置する PHP の環境設定ファイルとして php .iniを作成しておきます。 src 実行する php ファイルを配置しておきます。 このsrc配下のファイルがnginxで配信されます。 docker-compose.yml このファイルでnginx、 php コンテナをまとめてインストールできます。ホント便利。 │ docker-compose.yml │ ├─nginx │ default.conf │ ├─php │ Dockerfile │ php.ini │ └─src index.php ソースコード それでは今回使用するファイルの ソースコード を紹介していきます。 docker-compose.yml version: '3' services: nginx: image: nginx:stable-alpine ports: - "8080:80" volumes: - ./src:/var/www/html - ./nginx/default.conf:/etc/nginx/conf.d/default.conf php: build: ./php volumes: - ./src:/var/www/html docker-compose.ymlには、nginx, php コンテナのインストール内容が書かれています。 それぞれのコマンド名を簡単に説明していきます。 version: composeファイルのフォーマットのバージョンを明記しています。 services: コンテナのインストール内容が書かれます。 nginx: サービス「nginx」のインストールを示しています。 php : サービス「 php 」のインストール内容を示しています。 image: Dockerでは後述するDockerfileでコンテナのイメージ名を明記してインストールするのが基本ですが、imageでインストールイメージを指定することもできます。 今回はnginxコンテナはcomposeファイルでインストール、 php コンテナはDockerfileでインストールしています。 ports : ここではコンテナ側のポートとローカル側のポートをつなぐ役割をしています。 nginxの場合は「- "8080:80"」と書かれていますが、ローカル側の8080番をコンテナ側の80番とつなぐという意味を表しています。 volumes: ここではローカル側の ディレクト リ内容をコンテナにマウントする設定が書かれています。 今回はnginx配下で「- ./src:/var/www/html」と示していますが、これはローカル側の./srcをコンテナ側の/var/www/htmlにマウントするという意味を表しています。 build: 作成したDockerfileの場所を指定することで、指定したDockerfileの内容に従ってコンテナがインストールされます。 ※以前までは links: というものを書いてコンテナ間のネットワークに参加させる必要があったのですが、現在は書かなくてもデフォルトで network: というものが働く様になったようで、これにより各コンテナはそのネットワークに参加した状態になるということのようです。 default.conf server { listen 80; root /var/www/html; index index.php index.html; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } default.confにはnginxの設定内容を記述します。 よくハマってしまう点としては「 fastcgi _pass」の設定です。 デフォルトの fastcgi _passは 127.0.0.1 :9000を指定しており、これはnginxコンテナの localhost を指定してしまうために502エラーを返してしまいます。(BadGateway) このエラーを解決するためには php コンテナを指定する必要があり、「 fastcgi _pass php :9000;」と明記することでサービス名( php )で php コンテナを指定することができます。 Dockerfile FROM php:fpm COPY php.ini /usr/local/etc/php/ Dockerfileでは php のコンテナイメージのインストール、 php 設定ファイルの上書きを行っています。 FROM php :fpmと指定することでDocker公式が提供している PHPイメージ をインストールします。 COPY ローカルにある php .iniをインストールした php .iniにコピー、上書きします。 php .ini [Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese" php .iniには php 実行環境の設定を記述します。 必要に応じて設定を追加します。 index. php <?php echo "Hello World!"; phpinfo(); ここでは php スクリプト を書いています。 内容はお好みでどうぞ! 実行 以上のファイルが用意できたら、Docker、Docker-composeがインストールされている環境で以下のコマンドを入力します。 docker-compose build コマンド入力後、dockerコンテナのビルドが走ります。 ビルドが正常に終了したことが確認できたら、以下のコマンドでコンテナを立ち上げます。 docker-compose up コンテナが立ち上がった後に localhost:8080 にアクセスすると以下のような画面が表示されます。 これで php の実行環境は完成です! 後は、src内で php ファイルを変更したりしてみましょう! 最後に 今回はDockerを利用して PHP の実行環境を構築してみました。 今回は必要最小限の構成なので、次回記事を書く機会には PHP の フレームワーク であるLaravel開発環境をDockerを利用して構築したお話をしたいと思います。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
id:radiocat です。2020年8月27日に開催された Developers Summit 2020 KANSAIに登壇させていただきました。今回はそのレポート記事です。 セッションの様子 Developers Summit 2020 KANSAI について 「 Developers Summit 」通称「 デブサミ 」は 翔泳社 さん主催の IT技術 者向けイベントです。近年は東京で夏と冬、そして関西と福岡で年1回開催されています。今回は関西で開催されて記念すべき10周年となったイベント「 デブサミ 関西」で登壇の機会を頂きました。 event.shoeisha.jp 今回のテーマは「The Future Has Come」ということで、少し先の未来の「変化」の到来に関するチャレンジをシェアしようという思いが込められたテーマでした。私も大阪オフィスで9年間勤務して様々な変化にチャレンジしてきました。貴重な機会を頂いたので、9年間の取り組みを可能な限り盛り込んで発表させて頂きました。 関西的なノリで変化の波をノリこなすチームの取り組み speakerdeck.com チームでの変化へのチャレンジのこれまでの経験を振り返ってみて、大切な要素のひとつが大阪のチームならではの「関西的なノリ」なのではないか?と考えたことが今回のテーマのきっかけです。もちろん、関西のノリがなければ変化に適応できないという意味ではありません。「関西のノリの中に変化に適応していくヒントがあるのではないか?」、「過去の経験を振り返ってそのヒントを整理してみたい!」という思いが、 デブサミ 関西に向かううえでの私自身のチャレンジでした。 基本的に不確実な変化の波を乗りこなすのは難しい そもそも変化の波を乗りこなすのは簡単ではありません。大阪では2018年に 地震 、豪雨、台風と、1ヶ月おきに災害が発生して、出勤できないなどで仕事の予定を調整せざるを得ない経験をしました。私自身、 地震 が発生した日は当時担当していたサービスのリリース当日で、たまたま出勤できたメンバーとリモートでやり取りしながら対応した経験があります。 2018年の関西 不確実な波を乗りこなすために、世の中に溢れている アジャイル の手法やマネジメントの事例を取り入れようとしますが、それもなかなかうまくいきません。変化の波を乗りこなすつもりが、気づいたら情報の波の乗りこなそうとしてしまい、溢れる情報のより複雑な渦に飲み込まれてしまうこともあります。 情報の波は複雑性の渦を呼び込む ノリで変化の波をノリこなす 不確実な波に抗わず、困難な状況に向き合って起きたことに対処するためには、「状況の洞察」と「ポジティブな姿勢」が大切だと考えました。これこそが今回のテーマである「ノリ」です。 ノリは「状況の洞察」と「ポジティブな姿勢」 変化の波をノリこなす3つのステップ ノリで変化の波を乗りこなし続けるには、3つのステップでノリを広げていくことが大切です。この3つのステップをこれまで経験してきた事例を交えながらご紹介しました。 変化の波をチームでノリこなす3つのステップ 自分らしさのリーダーシップ まず最初のステップが、チームで働く土台として一人ひとりが自分らしさのリーダーシップを持つことです。これは近年のリーダーシップ論で「オーセンティック・リーダーシップ」と呼ばれています。 オーセンティック・リーダーシップ チームの中で互いに自分らしさを持ちつつ、他者を理解しあう取り組みの事例として、以前このブログにも投稿したリモートワーク時の取り組みを「自己開示と安心・安全な仕組みに身を預ける」という2つのポイントでご紹介しました。 tech-blog.rakus.co.jp 自己開示と安心・安全な仕組みに身を預ける取り組み チームで経験から学ぶ 2つ目のステップの「チームで経験から学ぶ」については「 アジャイル の原則」「 カイゼン 文化」「ありたい姿」の3つを軸にすることをお話しました。 経験から学ぶチームのモデル これは Scrum Fest Osaka 2020で発表させていただいた内容 を引用していますが、今回は大阪のチームで過去に経験した開発プロジェクトを一通り振り返ってお話しました。 大阪のチームで経験した開発プロジェクト 過去の開発プロジェクトの反省点を突き詰めれば アジャイル の原則に向かうことは認めつつも、予測できない様々な変化の波を乗りこなしていくためには アジャイル の手法だけにとらわれず、チームが経験から学ぶ方向に向かうことが変化を乗りこなすことにつながると考えています。 イテレーティブなプロセスを繰り返して経験から学ぶ 枠を超えてつながる 3つ目のステップの「枠を超えてつながる」では、小さく始めた社内勉強会が組織や会社全体を巻き込んだイベントへと発展した事例をご紹介しました。 勉強会イベント主催の様子 変化の波の中で自分たちも変化していくために、少しずつ枠の外に向かっていくことが変化の波を乗りこなすことにつながるという内容です。 枠を超えてつながるノリの大切さ 枠を超えることよにって、つながった人たち同士で継続的な相互アップデートを生み出すことができました。 枠を超えたつながりによって得られたこと 以上の3つのステップを外側に向けて広げることが様々な変化の波を乗りこなすことにつながると私は考えています。 外側に向けてステップを広げる 関西人はノリこなすのが得意? 突然のリモートワークへの移行の中で「大変だけど、これはこれでオモロそう」と言ったメンバーがいました。この「オモロそう」が変化の波を乗りこなす「ノリ」のヒントだと私は考えました。 大変だけど「オモロそう」 「オモロそう」は、過去にやったことが無いけど、これからやる価値がありそうでポジティブなことです。つまり、「オモロそう」には「状況の洞察」と「ポジティブな姿勢」のノリで対処するための要素が含まれています。 「オモロそう」とは そして、関西人は突然怖い人が借金を取りに来てもノリで対処する喜劇やどんな無理難題でもノリで調査・報告する探偵番組など、普段からノリでノリこなす文化の中で生きています。 某喜劇のイメージ 関西人らしく「オモロそう」を引き寄せて外側へステップを進めていくことが、変化の波をノリこなすことにつながるのではないかと私は考えています。 「オモロそう」引き寄せて変化の波をノリこなす デブサミ も変化の波を乗りこなす 今回はオンライン開催ということでしたが、セッション内容はリアルタイム配信ではなく事前撮影方式でした。テレビ撮影のようにカメラを向けられてマイクで音声を拾ってもらいながら行うセッションは初めてで、とても貴重な経験をさせて頂きました。 デブサミ 自体も新たな変化に向けてチャレンジしていることを改めて実感できる体験でした。 セッション撮影の様子 枠を超えてつながりたい 今回の発表をきっかけに、これまで以上にたくさんの方々と枠を超えてつながることができればと思っています。今月も様々なイベントが計画されていますので、興味を持たれましたらぜひご参加ください。 rakus.connpass.com
アバター
はじめに こんにちは。kkystです。 開発を担当しているプロダクトではpg_bigmを利用して 全文検索 機能を提供しています。 今回、その 全文検索 を行っているテーブルにINSERTを行う一部の処理で、 応答時間 が増えていることを検知しました。 そこでその原因を調査していったところ、GINインデックスのGIN高速更新手法にたどり着き、待機リストの有無による 応答時間 の検証を行いました。 その結果として、GIN高速更新手法の有効性を確認することができたので、検証の記録を残しておきたいと思います。 はじめに 概要 GIN高速更新手法とは 検証環境 検証内容 検証結果 おわりに 概要 GIN高速更新手法とは GINインデックスは 全文検索 向けのインデックスで文書中の単語の位置を保持しているため、使用することで特定の単語の検索を効率的に行えるようになります。 基本的には英文(英単語)を意識したものとなっていますが、pg_bigmなどのモジュールを導入することで日本語でも利用できます。 GINインデックスの高速更新手法については、 PostgreSQL の リファレンス には下記のように記載されています。 1つのヒープ行の挿入または更新によりインデックスへの挿入が多く発生するという、 転置インデックス の本質的な性質のためGINインデックスの更新は低速になりがちです。 (各キー用のヒープ行はインデックス付けされた項目から取り出されます。) PostgreSQL 8.4からGINは、新しいタプルを一時的なソートされていない、待機中の項目リストに挿入することにより、この作業の大部分を遅延させることができるようになりました。 (中略) この手法の大きな欠点は、検索時に通常のインデックス検索に加え待機中の項目リストのスキャンを行わなければならない点です。 このため、待機中の項目リストが大きくなると検索が顕著に遅くなります。 他の欠点は、ほとんどの更新は高速ですが、待機中の項目リストが「大きくなりすぎる」きっかけとなった更新は即時の整理処理を招くことになり、他の更新に比べ大きく低速になります。 自動バキュームを適切に使用することで、これらの両方の問題を最小化することができます。 「整理処理を行う更新処理が大きく低速となる」という部分が実際にどれくらい低速となるの?という疑問が浮んだので、この部分に着目して実際の処理時間を計測することにしました。 検証環境 ローカル環境:Windows10 Intel (R) Core(TM) i7-8550 CPU @1.8GHz RAM:16GB SSD 512GB Docker for Windows version 2.3.0.3 PostgreSQLの公式Dockerイメージ(v12.4) テーブル構造 create table sample_table(id integer, note text); create index sample_table_ix1 on sample_table using gin (note gin_bigm_ops); ※待機リストを利用しない場合は、WITH (FASTUPDATE = OFF)を付与してインデックス再作成を実施。 検証内容 以下の状態でASCIIコードのランダム1000バイトの文字列データを1件挿入し、処理時間を計測する。 初期データなし 待機リストあり(空) 待機リストあり(最大≒gin_pending_list_limit(4MB):1000バイト * 170件) 待機リストを利用しない 初期データ100万件(各行1000バイト) 待機リストあり(空) 待機リストあり(最大≒gin_pending_list_limit(4MB):1000バイト * 170件) 待機リストを利用しない 検証結果 待機リスト(空) 待機リスト(最大) 待機リストなし 初期データなし 89.034ms 97.462ms 83.937ms 初期データあり 70.088ms 863.200ms 827.526ms この結果より、インデックスへの整理処理そのものに時間がかかり、整理する対象のデータ件数による差はほとんどありませんでした。 また、今回用意したパターンであれば、その整理処理自体も1秒を切っているので、他の処理との兼ね合いもありますがオンラインで利用しても許容できる速度であることがわかりました。 このことから、大半の更新処理が高速になるGIN高速更新手法は非常に有効であり、特別な要件がない限りは有効にしておくべきものだということがわかりました。 検証結果の詳細を展開 1.1. 初期データなし-待機リストあり(空) dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 4294967295 | 4294967295 | 0 | 0 | 0 | 2 | 1 | 0 | 0 | 2 dev=# INSERT INTO sample_table SELECT 1000000, STRING_AGG(str, '') FROM ( SELECT chr(40 + (RANDOM() * 1000)::INT % 84 ) AS str FROM GENERATE_SERIES(1, 1000) length) t; INSERT 0 1 時間: 89.034 ミリ秒 dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 2 | 4 | 5680 | 3 | 1 | 2 | 1 | 0 | 0 | 2 1.2. 初期データなし-待機リストあり(最大) dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 347 | 4 | 5660 | 177 | 59 | 2 | 1 | 0 | 0 | 2 dev=# INSERT INTO sample_table SELECT 1000000, STRING_AGG(str, '') FROM ( SELECT chr(40 + (RANDOM() * 1000)::INT % 84 ) AS str FROM GENERATE_SERIES(1, 1000) length) t; INSERT 0 1 時間: 97.462 ミリ秒 dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 2 | 4 | 5660 | 3 | 1 | 2 | 1 | 0 | 0 | 2 1.3. 初期データなし-待機リストを利用しない dev=# create index sample_table_ix1 on sample_table using gin (note gin_bigm_ops) WITH (FASTUPDATE = OFF); CREATE INDEX 時間: 43.528 ミリ秒 dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 4294967295 | 4294967295 | 0 | 0 | 0 | 2 | 1 | 0 | 0 | 2 dev=# INSERT INTO sample_table SELECT 1000000, STRING_AGG(str, '') FROM ( SELECT chr(40 + (RANDOM() * 1000)::INT % 84 ) AS str FROM GENERATE_SERIES(1, 1000) length) t; INSERT 0 1 時間: 83.937 ミリ秒 dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 4294967295 | 4294967295 | 0 | 0 | 0 | 2 | 1 | 0 | 0 | 2 2.1. 初期データあり-待機リストあり(空) dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 4294967295 | 4294967295 | 0 | 0 | 0 | 212649 | 2764 | 209881 | 7224 | 2 dev=# INSERT INTO sample_table SELECT 1000001, STRING_AGG(str, '') FROM ( SELECT chr(40 + (RANDOM() * 1000)::INT % 84 ) AS str FROM GENERATE_SERIES(1, 1000) length) t; INSERT 0 1 時間: 70.088 ミリ秒 dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 212646 | 212648 | 5740 | 3 | 1 | 212649 | 2764 | 209881 | 7224 | 2 2.2. 初期データあり-待機リストあり(最大) dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 212646 | 213158 | 5940 | 513 | 171 | 212649 | 2764 | 209881 | 7224 | 2 dev=# INSERT INTO sample_table SELECT 1000001, STRING_AGG(str, '') FROM ( SELECT chr(40 + (RANDOM() * 1000)::INT % 84 ) AS str FROM GENERATE_SERIES(1, 1000) length) t; INSERT 0 1 時間: 863.200 ミリ秒 dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 4294967295 | 4294967295 | 0 | 0 | 0 | 212649 | 2764 | 209881 | 7224 | 2 2.3. 初期データあり-を利用しない dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 4294967295 | 4294967295 | 0 | 0 | 0 | 212649 | 2764 | 209881 | 7224 | 2 (1 行) 時間: 63.233 ミリ秒 dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 4294967295 | 4294967295 | 0 | 0 | 0 | 212651 | 2764 | 209886 | 772968 | 2 dev=# INSERT INTO sample_table SELECT 1000001, STRING_AGG(str, '') FROM ( SELECT chr(40 + (RANDOM() * 1000)::INT % 84 ) AS str FROM GENERATE_SERIES(1, 1000) length) t; INSERT 0 1 時間: 827.526 ミリ秒 dev=# SELECT * FROM gin_metapage_info(get_raw_page('sample_table_ix1', 0)); pending_head | pending_tail | tail_free_size | n_pending_pages | n_pending_tuples | n_total_pages | n_entry_pages | n_data_pages | n_entries | version --------------+--------------+----------------+-----------------+------------------+---------------+---------------+--------------+-----------+--------- 4294967295 | 4294967295 | 0 | 0 | 0 | 212651 | 2764 | 209886 | 772968 | 2 おわりに 今回は、GIN高速更新手法の待機リストの整理処理による低速化に着目して検証し、GIN高速更新手法の有効性を実感することができました。 時間の都合もあり現時点における検証はここまでですが、gin_pending_list_limitなどの適切な設定値やデータ量や偏りとの関連などもありそうなので、今後もこのGIN高速更新手法について別な切り口で検証していきたいと思います。
アバター
はじめに はじめまして、新卒一年目のYoshidaMichaelです。 研修でGitの使い方を学び、「家で作ってる Bot もGitで管理しちゃうぞー!」なんて意気込んでいたわけですが、 うっかり トーク ンが載った状態のコードをpushしてしまって大変なことになりそうでした。 今回はそれを GitHub に助けていただいた、そんなお話です。 はじめに シークレットスキャニング 提携サービス 根本対処 方法1: 別のファイルに記述してそれを読み取る 方法2: 環境変数に記述する まとめ シークレットスキャニング シークレットスキャンニングについて - GitHub Docs GitHub は リポジトリ をスキャンして既知のシークレットのタイプを探し、誤ってコミットされたシークレットの不正使用を防止します なんと GitHub ではpushされた際に自動で トーク ン (ここではシークレットと表現されています) が含まれていないか 確認してくれるんですね。 どうやら私のようなうっかりミスをする人は多いらしく、 トーク ンスキャニングを導入してから発見された トーク ン 流出は1年間で10億件にものぼるそうです。 この機能が導入されてなかったと思うと恐ろしい話ですね......。 提携サービス 実は トーク ンが流出した当初、私はシークレットスキャニングが GitHub の機能であることを知りませんでした。 というのも、私が GitHub へpushした際に受けた警告は以下のようなものだったのです。 トーク ン流出時に受け取ったメッセージ これを見て「うわー、Discordって GitHub の投稿まで見てるんだ!すごい!」なんて思ったわけですが、調べてみると GitHub が調査して トーク ンを発見、提携しているサービスと情報を共有しているそうです。 現在 GitHub は32のサービスプロバイダと提携しており、それらのサービスであれば万一 トーク ンが流出しても大惨事になることは防げそうです。 根本対処 今回はシークレットスキャニングが優秀だったおかげで トーク ンを発見してもらい、すぐさまDiscordに トーク ンを リセットしてもらえたわけですが、いつも発見してもらえるかは正直わからないところです。 また、そもそも GitHub と提携していないサービスの トーク ンであれば検出されず、そのまま外部へ流出してしまうこともあるでしょう。 そこでここでは「そもそも トーク ンを流出させない工夫ってないの?」という方法を調べてみましたので紹介しようと 思います。 方法1 : 別のファイルに記述してそれを読み取る Bot を動かす環境に トーク ンの記述されたファイルを用意してそれを読み取る方法です。 ファイルは GitHub にはpushせず、 Bot を動かす環境だけで管理するようにします。 この方法は別の環境で Bot を動かしたい場合全ファイルを動かすだけで良いので楽な反面、そのファイルをうっかり GitHub などにアップしないことは気をつけなければなりません。 方法2: 環境変数 に記述する どうやらメジャーな方法はこちらのようです。 環境変数 自体は Windows でプログラミングをする際にPathを通す過程で触った方も多いのではないでしょうか。 環境変数とは - IT用語辞典 e-Words 環境変数 とは、OSが設定値などを永続的に保存し、利用者や実行されるプログラムから設定・参照できるようにしたもの。プログラムの実行時などに必要となる、利用者やコンピュータごとに内容が異なる設定値などを記録するために用いられる。 Python では標準ライブラリで 環境変数 の設定、取得等が行えるそうなので Python を利用した開発ではこちらの方法も気軽に利用できそうですね。( Python 以外でも気軽かはわかりません。) 私も今後はこちらで トーク ン管理をしようかなと思います。 まとめ 今回は GitHub のシークレットスキャニングと トーク ン管理の方法について紹介しました。 皆さんの トーク ン流出によるリスクを少しでも下げることに貢献できましたら幸いです。 それでは!
アバター
はじめに いつも ラク スエンジニアブログをご覧いただき、ありがとうございます! 技術広報のitoken1013です。 今回は8月第2回目のMeetup 『 SaaS 新規プロダクトの技術』 のコンテンツを紹介させていただきます。 当日は ラク スMeetup史上、最多の120名超の方々にご参加いただき、熱いイベントとなりました。 ご参加いただきました方々、本当にありがとうございました! rakus.connpass.com イベントテーマ概要 ラク スでは多くの to B向け SaaS を展開し続ける傍ら、新たな領域のサービス立ち上げに向けて企画が日々進められています。 今回はイベントテーマの『新規プロダクト』が表す通り、以下の新規 HRTech系プロダクトの開発より得られた知見を紹介させていただきました。 楽楽労務 楽楽勤怠 技術選定・開発・インフラそれぞれの立場より4名のエンジニアが発表させていただき、今までになく幅広いコンテンツを皆様にご提供できたイベントだったのではないかと思います。 ご参加いただきました方の中には新規プロダクト開発に関わっている方も多く、今回のMeetupを通じて日々の開発に役立つ情報をご提供できましたのであれば、大変幸いです。 発表の紹介 それでは今回発表させていただきました内容を紹介させていただきます! 発表スライドとlogmiから、当日の様子を感じ取っていただけますと幸いです! 新サービス立ち上げ時の技術選定と、サービス立ち上げに向けた ラク スの取り組み まずは ラク スの先行技術検証を主導しつつ、今年度はオンラインイベントのパーソナリティとしても大活躍中の鈴木より、楽楽 労務 における アーキテクチャ 選定のご紹介からです。 エンジニアであれば新サービス開発にはモダンな先端技術を導入したいものですが、 組織の 全体最適 を考えた結果、技術導入を見送ることも珍しいことではないかと思います。 今回、鈴木の紹介ではこのようなさまざまな経緯を踏まえて「導入しなかった技術」に着目し、 LADR(Lightweight Architecture Decision Records) という手法を紹介させていただきました。 技術検討から判断にいたるまでの意思決定の過程を可視化できるため、多くの ステークホルダー の関わる組織でプロダクト開発にお悩みの方には、ぜひ鈴木作成のテンプレートをご活用いただければと思います。 LADRを導入する上でのメリット・デメリットについても語られているため、多くのエンジニアにお役立ていただけるはずです。 logmi.jp speakerdeck.com はじめてのフロントエンド・バックエンド分離 2本目は楽楽勤怠でバックエンドエンジニアとして関わる西角より、 ラク ス初のフロントエンド・バックエンドを分離したプロダクト開発で得られた知見を紹介させていただきました。 2019年から開発がスタートした楽楽勤怠では、フロントエンドとバックエンドとのインターフェースとなるWeb API の開発を進めるにあたり、チーム間の連携にいくつかの課題を抱えていました。 フロントエンド・バックエンド双方のチームの生産性をより上げるための取り組みは、チーム開発に関わる日本中のエンジニアの皆様に参考にしていただけるはずです。 ラク スにとっても西角と楽楽勤怠チームが試行錯誤を繰り返して得た知見は、今後のプロダクト開発の大きな財産になっていくでしょう。 logmi.jp speakerdeck.com 新規プロダクトの開発速度と品質の両立を支える自動テスト 3本目は福岡より、楽楽 労務 での自動テストの取り組みの紹介です。 タイトルの通り、楽楽 労務 では開発のスピードと品質を両立するためにエンジニアが様々な取り組みを行っています。 今回はその中でも不可欠な3種類の自動テストを語らせていただきました。 各テストがもたらす恩恵、またどんな観点での品質担保を目的としてテストを作っていくのが最適なのか、開発の最前線に関わる福岡が詳細に紹介しています。 ユニットテスト ( JUnit ) アーキテクチャ テスト(ArchUnit) E2Eテスト(Puppeteer) テストコードを書くことが当たり前の文化となっている楽楽 労務 の開発チームから、品質担保と早期のプロダクトマーケットフィットの両立を実現する理想的な開発フローを知っていただけると幸いです。 logmi.jp speakerdeck.com 積極的に AWS サービスと自動化を使ってto Bの SaaS をローンチしたその後 最後はインフラエンジニアの柏木より、to B向け SaaS に AWS を活用する際のポイントを紹介させていただきました。 いまや IaaS の王道である AWS では数多くのサービスを利用可能ですが、楽楽 労務 をはじめとした大規模 SaaS を運用する柏木はインフラエンジニアとしてより長期的な目線に立ち、本質を捉えた利用ポイントを語っています。 後半に紹介される事例でも単に自動化を行うのではなく「なぜ?」を追求しており、柏木の理論から ラク スに根付く戦略志向を感じ取っていただけるはずです。 logmi.jp speakerdeck.com おわりに 新規プロダクトにおける ラク スの取り組み、いかがでしたでしょうか? 新たなプロダクトの開発に奮闘するエンジニアの皆様に参考となる情報があれば幸いです。 さて、次回9/16(水)のMeetupでは 『プロダクトを持続的に開発・運用し続けるための取り組み』 を紹介する予定です。 長く幅広く SaaS を展開する ラク スだからこそできる開発戦略にご注目いただければと思います。 皆様のご参加をお待ちしています! rakus.connpass.com
アバター
先日行われました、フロントエンドLT会 vol.1 -2020夏祭り- にて初LTを無事終えました。logy0704です。 rakus.connpass.com 今回はLT会で発表した内容に加えて、スライドには収めきれなかった話について書きたいと思います。 speakerdeck.com Nuxt.jsとfirebaseに興味を持ったきっかけ 他にハマったこと RealtimeDatabase vs FireStore おわりに Nuxt.jsとfirebaseに興味を持ったきっかけ vue.jsとfirebaseの組み合わせについては、過去のエンジニアブログでも何度か触れられていたこともあり、いつか触りたいという思いがありました。 tech-blog.rakus.co.jp tech-blog.rakus.co.jp 加えて、環境構築周りの負荷軽減(vuex, vue-router)、将来的にPWAにも触れてみたいというモチベーションでNuxt.jsとfirebaseの組み合わせに至りました。 他にNuxt.jsを採用する理由としては、 SSR (サーバーサイド レンダリング )が思い浮かびますが、今回の学習ではSPAモードを利用し、 SSR は採用しませんでした。 理由は、スライドにもある通り、バックエンド周りのことを極力気にしたくなかったからです。 他にハマったこと RealtimeDatabase vs FireStore これはハマったことというよりも知見がなかったため、考察に時間がかかったというほうが正しいです。 どちらもFirebaseによって提供される クラウド ホスト型 NoSQL データベースですが、似て非なる特徴を持っています。 具体的な選定ポイントについては、こちらのページを参考にさせていただきました。 firebase.google.com ページの記載からは、ややFireStore推しであるようにも受け取れますが、それぞれの特徴を踏まえた選択を行う必要があります。 特に、データモデルが異なるため、一度片方を利用し始めた後に、もう一方に乗り換えるのはなかなか難しいため注意が必要です。 今回のアプリでは、Realtime databaseを選択しました。 理由は、簡易なTODOアプリとしての利用であれば、FireStoreのような複雑なクエリは必要ないと判断したからです。 実際の商用レベルのアプリであれば、将来の機能拡張を加味した検討が必要になると思います。 おわりに 100人以上が聞いてくれている中での発表でLTデビューというのは多少緊張しましたが、良い経験になりました。 他の方の発表が良い刺激になったことは勿論、いざ自分が発表するとなると、あれこれ準備したりする分、やりっぱなしよりも知識が定着する気がします。 これが登壇駆動開発…!
アバター
こんにちわ @kawanamiyuu です。今回は私の所属する 楽楽労務 の開発チームで運用している コードレビュー ガイドライン とコードレビューにまつわる少し変わった取り組みについて紹介しようと思います。 楽楽労務の開発体制 コードレビューガイドライン策定の背景 コードレビューガイドライン策定の目的 レビュー指摘の重要度 コードレビューの工夫 「おやつ」という発明 おわりに 楽楽 労務 の開発体制 チーム 開発拠点は東京と大阪 1 チームあたり 3 〜 5 名の、合計 3 チーム(+ スクラム マスター等)で スクラム 開発 *1 私はそのうちの 1 チームのリーダーを担当 ツール GitLab でソース管理し、Merge Request *2 を活用してコードレビューを実施 レビューを通ったコードがメインブランチにマージされる 開発タスク(PBI *3 、SBI *4 )は Trello で管理 コードレビュー ガイドライン 策定の背景 開発規模拡大のための人員増とそれに伴う複数チーム体制への移行により、 チームごとにコードレビュー指摘の重要度や観点にばらつきがある 開発メンバーが自身の成長を測る指標として、Merge Request の差し戻し回数より細かい粒度の情報を収集しづらい といった課題が出てきていました。 コードレビュー ガイドライン 策定の目的 これらの課題を解決するためのコードレビュー ガイドライン を策定し、次の実現を目指しています。 開発チーム全体で同じ基準でコードレビューを行い、修正要否を判断できるようにする 開発メンバーがレビュー指摘を重要度や観点ごとに分析し、自身のふりかえりに活かせるようにする 観点を明文化することで、レビューイーのセルフチェックやレビュアー育成のインプットとして使えるようにする レビュー指摘の重要度 コードレビューで発生する指摘には必ず優先度を付け、プロダクト品質に対する重要度を表現します。 重要度 説明 MUST 必ず修正すべき。われわれが期待する当たり前品質に達しておらず、そのままではリリースできない。今放置するとあとで大きな負債になる SHOULD 可能なら修正すべき。リリーススケジュールを優先するため戦略的に修正を見送ることもできるが、その場合は次バージョンで修正を検討すべき IMO 修正判断はレビューイーに委ねられる。別解の提案や現時点では判断が難しい課題など、レビュアーの意見に過ぎない レビュアーはこれらの「重要度」に「観点」 *5 を加えて、Merge Request 上のコードに対してレビュー指摘を記述します。 <レビュー指摘の記述例> コードレビューの工夫 MUST レベルのレビュー指摘はリリース品質を満たしていないことを意味するため、必ず修正する必要がありますが、SHOULD レベルのレビュー指摘の修正判断には裁量があります。 私がリーダーを担当するチームでは 「SHOULD レベルのレビュー指摘はすぐには修正せずいったん負債として積み上げる」 という運用を試みています。平たくいうと、未修正の SHOULD レベルのレビュー指摘が残っていても Merge Request をマージしてよいことにしています。 これは、 まずはリリース可能品質到達を最速で目指すことで、開発の後工程のスケジュール上のリスクを減らしたい コードの問題を「いつ」「どの程度ちゃんと」修正するかという意思決定によって開発速度と品質のバランスを調整したい という考えが背景にあり、担当チームメンバーと開発チーム全体に説明のうえ、このような工夫を試しています。 この運用によって後回しにした負債タスクも Trello 上で管理しています。 その名も「 SHOULD 」レーン(まんま)です。 このレーンのタスクは、実装タスクのレビュー待ち時間やスプリントの切れ目など、主に開発業務のリードタイムが発生したときに、開発業務の 箸休め的なタスク として、各自が自主的に取って解消していく運用としています。 「おやつ」という発明 さて、いよいよ本題ですが、最近のスプリント終了時の振り返りで、私のチームのあるメンバーが「今回のスプリントはタイミングよく負債タスクを消化できた。おやつ感覚だった。」と発言しました。その瞬間、メンバー全員が「これだ!」と思いました。 そして 爆誕 したのが「 おやつ 」レーン(名前変えただけ)です。 この並びに「おやつ」の文字が並ぶのは面白いですね。 プログラマー にとって名前付けはとても重要です。 その対象の特徴を適切に捉えた良い名前が与えられることで、非常にすっきりとその世界観を理解することができます。 また、今回、負債タスクに「おやつ」という名前がついたことで、負債というネガティブなイメージがポジティブなイメージに変わり、負債解消に前向きに取り組むことができるようになりました。 おわりに 今回紹介したコードレビューに対する取り組みは、現状うまく回っています。開発中に発生した一部のレビュー指摘を負債として一時的に後回しにはするものの、「おやつ」感覚で適宜消化し、負債を溜め込まない状態をキープできています。 私たちの取り組みが、開発速度と品質を両立し、技術的負債に対して前向きに取り組みむためのア イデア となれば嬉しいです。 -- P.S. その後、次のような名言(迷言)も生まれています。 おやつの鮮度が落ちると背景理解に時間がかかる = 負債を放置すると、実際に修正しようとしたときにどんなコンテキストでの指摘だったのか思い出して理解するのに時間がかかる おやつを食べすぎた = メインの実装タスクよりも負債の解消を優先してしまい、実装タスクの完了が遅れた *1 : LeSS のようなイメージ *2 : GitHub でいうところの Pull Request のこと *3 : Product Backlog Item *4 : Sprint Backlog Item *5 : 外部品質上の指摘観点:「不具合」「互換性」etc。内部品質上の指摘観点:「理解容易性」「変更容易性」etc。
アバター
はじめに こんにちは。dd_fortです。 前回に引き続き、Dockerについての話になります。 Dockerの学習中に詰まった権限についての問題と、その解決法を紹介します。 はじめに ボリューム(Data Volume)とは permission denied が発生する問題 解決法 解決法1:マウントしたボリュームの権限を書き換える 解決法2:ユーザ情報の書かれたファイルを読み込み専用でマウントする 解決法3:コンテナ作成時にユーザとグループを追加する まとめ ボリューム(Data Volume)とは ボリュームとは、データを永続化できる場所を指します。 Dockerのコンテナ内部のデータはコンテナ破棄をすると消えてしまうため、 データを永続化させるための手段として ボリューム(volume) が存在します。 コンテナ内部の永続化の詳しい内容については、こちらの記事を参照ください。 tech-blog.rakus.co.jp permission denied が発生する問題 Linux 上でDockerコンテナ内でボリュームをマウントした際に、ホストからアクセスした場合に パーミッション の問題が発生することがあります。 ホストOSで使っているユーザとコンテナ内で使っているユーザのUIDと GID が不一致になることが原因のようです。 そのため、Docker for Mac / Windows ではほとんど発生しません。 $ id uid=1000(test) gid=1000(test) groups=0(test) # (コンテナ内) # id uid=0(root) gid=0(root) groups=0(root) 発生する環境 Linux ( Ubuntu , CentOS etc) WSL2 解決法 解決法1:マウントしたボリュームの権限を書き換える permission deniedが発生した ディレクト リ、ファイルの権限を直接書き換えることで解決することができます。 $ chmod 777 /var/project しかし、permission denied が発生しているファイル、フォルダのすべての権限を書き換えないといけないため、根本的な解決にはなりません。 解決法2:ユーザ情報の書かれたファイルを読み込み専用でマウントする コンテナ内のUIDと GID がホストOSと同じになるように、コンテナ起動時にUIDと GID を指定します。 また、 /etc/passwd との不整合が起きないようにホストOSの /etc/passwd をマウントする必要があります。 最後に、コンテナから /etc/passwd を書き換えないようにread only ( :ro ) でマウントします。 $docker run \ -u "$(id -u $USER):$(id -g $USER)" \ -v /etc/passwd:/etc/passwd:ro \ -v /etc/group:/etc/group:ro \ -it ubuntu 実行結果 $ id uid=1000(test) gid=1000(test) groups=1000(test) # (コンテナ内) test@hogehoge:~$ id uid=1000(test) gid=1000(test) groups=1000(test) 問題なくコンテナ内とホストOSでユーザ情報が共 通化 されていることが確認できました。 ただしこの方法のデメリットとして、別プラットフォーム間ではDockerファイル等を共有することができなくなります。 解決法3:コンテナ作成時にユーザとグループを追加する ホストOSのユーザ(UID)、グループ( GID )を 環境変数 として渡し、コンテナ内でユーザとグループを追加します。 # Dockerfile FROM ubuntu:latest RUN apt update \ && apt -yq dist-upgrade \ && apt install -yq --no-install-recommends \ sudo COPY entrypoint.sh /var/tmp CMD bash -E /var/tmp/entrypoint.sh && /bin/bash コンテナが終了しないように /bin/bash で対話モードで動かし続けます。 # docker-compose.yml version: "3" services: override: image: example/override-ids build: . container_name: override environment: - USER_NAME - USER_ID - GROUP_NAME - GROUP_ID volumes: - ./:/mnt/working tty: true 環境変数 で、ユーザ(UID)、グループ( GID )を渡すように設定します。 # entrypoint.sh useradd -s /bin/bash -m ${USER_NAME} export HOME=/home/${USER_NAME} usermod -u ${USER_ID} ${USER_NAME} groupadd -g ${GROUP_ID} ${GROUP_NAME} usermod -g ${GROUP_NAME} ${USER_NAME} useradd 、 groupadd でユーザとグループを追加。 usermod でユーザとグループを設定。 コンテナをビルドして実行します。 $ docker-compose build $ USER_NAME=$(id -un) \ USER_ID=$(id -u) \ GROUP_NAME=$(id -gn) \ GROUP_ID=$(id -g) \ sudo -E docker-compose up -d 実行結果 $ id uid=1000(test) gid=1000(test) groups=1000(test) $ docker exec -it override su - $(id -un) test@hogehoge:~$ id uid=1000(test) gid=1000(test) groups=1000(test) まとめ Dockerのコンテナ内にvolumeをマウントする際は、UID/ GID を正しく設定しなければなりません。 簡単な手段としての解決法は1,2ですが、解決法3を使うとほとんどの問題を解決することができます。 Dockerではまだまだ勉強を始めたばかりなので学習を進めていこうと考えています。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
はじめに こんにちは、yk_itgです。 これまでいくつか PostgreSQL の記事を作成しましたが、今回は知っていると便利だと思う テーブル・DBの閲覧・コピー に関するtipsをまとめてみました。 私はテストを実施する時に結果を確認したり、データを用意する際によく使います。 PostgreSQL ユーザなら必須のテクニックを紹介していきますので、どうぞお役立てください! はじめに テーブルを閲覧する テーブルの情報を確認したい:\d テーブルの一覧を確認したい:\dt 実行結果を見やすくしたい:\x 実行結果をファイルに出力して確認したい:\o DBを閲覧する DBの一覧を確認したい:\l テーブルをコピーする テーブルの構造をコピーしたい:CREATE TABLE (LIKE) テーブルのレコードをコピーしたい:INSERT INTO SELECT DBをコピーする DBをコピーしたい:createdb -T DBをコピーしたい:pg_dump 最後に 関連記事 テーブルを閲覧する テーブルの情報を確認したい: \d \d {テーブル名} を psql 上で実行するとテーブルの情報を表示することができます。 インデックスやシーケンスなどテーブル以外のリレーションを表示することも可能です。 postgres=# \d test テーブル "public.test" 列 | 型 | 照合順序 | Null 値を許容 | デフォルト ------+---------+----------+---------------+------------ id | integer | | not null | hoge | text | | | 'a'::text インデックス: "test_pkey" PRIMARY KEY, btree (id) "test_hoge_idx" btree (hoge) postgres=# \d test_pkey インデックス "public.test_pkey" 列 | 型 | キー? | 定義 ----+---------+-------+------ id | integer | はい | id プライマリキー, btree, テーブル "public.test" 用 テーブルの一覧を確認したい: \dt \dt を psql 上で実行するとテーブルの一覧を表示することができます。 テーブル以外にも \di 、 \ds 、 \dv を使えば、それぞれインデックス、シーケンス、ビューの一覧を表示することができます。 postgres=# \dt リレーション一覧 スキーマ | 名前 | 型 | 所有者 ----------+------+----------+---------- public | test | テーブル | postgres (1 行) 実行結果を見やすくしたい: \x \x を psql 上で実行すると SQL やメタコマンド等の実行結果を拡張表示(縦に表示)することができます。 例えば、カラムが多すぎてターミナルで折り返して表示されてしまう場合に便利です。 逆に見づらい場合には、もう一度 \x を実行すると元の表示に戻ります。 postgres=# SELECT * FROM test; id | hoge1 | hoge2 | hoge3 | hoge4 | hoge5 | hoge6 | hoge7 | hoge8 | hoge9 | hoge10 | hoge11 | hoge12 | hoge13 | hoge14 | hoge15 | hoge16 | hoge17 | hoge18 | hoge19 | hoge20 ----+------------+-------+-------+-------+-------+-------+-------+-------+-------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-------- 1 | ABCDEFGHIJ | | | | | | | | | | | | | | | | | | | (1 行) postgres=# \x 拡張表示は on です。 postgres=# SELECT * FROM test; -[ RECORD 1 ]------ id | 6 hoge1 | ABCDEFGHIJ hoge2 | hoge3 | hoge4 | hoge5 | hoge6 | hoge7 | hoge8 | hoge9 | hoge10 | hoge11 | hoge12 | hoge13 | hoge14 | hoge15 | hoge16 | hoge17 | hoge18 | hoge19 | hoge20 | 実行結果をファイルに出力して確認したい: \o \o {ファイルパス} を psql 上で実行すると実行結果を指定したファイルに出力することができます。 ターミナル以外で実行結果を確認したい場合や保存したい場合に便利です。 SQL 実行後に \o を実行すると出力先を標準出力に戻すことができます。 postgres=# \o result.txt postgres=# SELECT * FROM test; postgres=# \o postgres=# SELECT * FROM test; id | hoge ----+------------ 8 | ABCDEFGHIJ (1 行) result.txt id | hoge ----+------------ 8 | ABCDEFGHIJ (1 行) DBを閲覧する DBの一覧を確認したい: \l \l を psql *1 上で実行するとDBの一覧を表示することができます。 または psql -l でターミナルを起動せずに表示することもできます。 postgres=# \l データベース一覧 名前 | 所有者 | エンコーディング | 照合順序 | Ctype(変換演算子) | アクセス権限 -----------------------------------+----------+------------------+----------+-------------------+----------------------- postgres | postgres | UTF8 | C | C | template0 | postgres | UTF8 | C | C | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | C | C | =c/postgres + | | | | | postgres=CTc/postgres (3 行) テーブルをコピーする 続いてはコピー作業のテクニック、まずはテーブル編の紹介です。 なお、これからご紹介する内容は、本番環境での利用は想定していません。 誤って重要なデータの書き替えが発生してしまう可能性もありますので、ご利用にはくれぐれもご注意ください。 テーブルの構造をコピーしたい: CREATE TABLE (LIKE) CREATE TABLE {コピー先} (LIKE {コピー元} ) *2 の SQL を実行するとコピー元と同じ構造のテーブルを作成することができます。 LIKEの中で INCLUDING ALL を指定すると構造だけでなく、制約やデフォルト値、付与されているインデックス等もコピーすることができます。 postgres=# CREATE TABLE test2 (LIKE test); CREATE TABLE postgres=# \d test2 テーブル "public.test2" 列 | 型 | 照合順序 | Null 値を許容 | デフォルト ------+---------+----------+---------------+------------ id | integer | | not null | hoge | text | | | postgres=# CREATE TABLE test3 (LIKE test INCLUDING ALL); CREATE TABLE postgres=# \d test3 テーブル "public.test3" 列 | 型 | 照合順序 | Null 値を許容 | デフォルト ------+---------+----------+---------------+------------ id | integer | | not null | hoge | text | | | 'a'::text インデックス: "test3_pkey" PRIMARY KEY, btree (id) "test3_hoge_idx" btree (hoge) テーブルのレコードをコピーしたい: INSERT INTO SELECT INSERT INTO {テーブル名} SELECT * FROM {テーブル名} の SQL を実行するとSELECTの結果をそのままコピーすることができます。 そのままコピーすると主キー制約に引っかかる場合には、 CREATE TABLE {コピー先} (LIKE {コピー元} ) を使ってtempテーブルを作成し、変更したいカラムのみをUPDATEしてからINSERTすると主キーのカラム以外を考えずにコピーすることができます。 postgres=# SELECT * FROM test2; id | hoge ----+------------ 10 | ABCDEFGHIJ (1 行) postgres=# INSERT INTO test2 SELECT * FROM test2; INSERT 0 1 postgres=# SELECT * FROM test2; id | hoge ----+------------ 10 | ABCDEFGHIJ 10 | ABCDEFGHIJ (2 行) postgres=# SELECT * FROM test; id | hoge ----+------------ 1 | ABCDEFGHIJ (1 行) postgres=# CREATE TEMPORARY TABLE temp_test (LIKE test); CREATE TABLE postgres=# INSERT INTO temp_test SELECT * FROM test WHERE id = 1; INSERT 0 1 postgres=# UPDATE temp_test SET id = 2; UPDATE 1 postgres=# INSERT INTO test SELECT * FROM temp_test; INSERT 0 1 postgres=# SELECT * FROM test; id | hoge ----+------------ 1 | ABCDEFGHIJ 2 | ABCDEFGHIJ (2 行) DBをコピーする テーブルの次はDB編のご紹介です。 こちらもテーブル編と同様、本番環境での利用は想定したものではありません。 環境へ重大な影響を及ぼす内容となりますため、ご注意の上での利用をお願いします。 DBをコピーしたい: createdb -T createdb -T {コピー元} {コピー先} *3 のコマンドを実行するとコピー元DBの内容でコピー先DBを作成することができます。 後述の pg_dump と比較すると実行速度が速い印象です。 >psql -U postgres -d postgres postgres=# \dt リレーション一覧 スキーマ | 名前 | 型 | 所有者 ----------+-------+----------+---------- public | test | テーブル | postgres public | test2 | テーブル | postgres public | test3 | テーブル | postgres (3 行) >createdb -T postgres -U postgres postgres2 >psql -U postgres -d postgres2 postgres2=# \dt リレーション一覧 スキーマ | 名前 | 型 | 所有者 ----------+-------+----------+---------- public | test | テーブル | postgres public | test2 | テーブル | postgres public | test3 | テーブル | postgres (3 行) DBをコピーしたい: pg_dump pg_dump {コピー元DB} > {dumpファイル} *4 のコマンドを利用するとデータベースをバックアップするdumpファイルを作成することができます。 作成したdumpファイルを psql {コピー先DB} < {dumpファイル} でリストアすることによってコピー先のDBにコピー元のDBをデータを再現することができます。 前述の createdb -T と比較すると、dumpファイルがあれば同じサーバにコピー元のDBがなくてもコピーできる点で汎用的です。 また、 -n や -t のオプションを指定すると一致する スキーマ やテーブル単位でコピーすることもできます。 > pg_dump -U postgres postgres > postgres_dump > ls -1 | grep postgres_dump postgres_dump > createdb -U postgres -T template0 postgres3 > psql -U postgres -d postgres3 < postgres_dump > psql -U postgres -d postgres3 postgres3=# \dt リレーション一覧 スキーマ | 名前 | 型 | 所有者 ----------+-------+----------+---------- public | test | テーブル | postgres public | test2 | テーブル | postgres public | test3 | テーブル | postgres (3 行) 最後に PostgreSQL でのテーブル・DBの閲覧・コピーに関してご紹介してみましたが、いかがでしたでしょうか。 効率的な作業のお役に立てば幸いです。 関連記事 tech-blog.rakus.co.jp tech-blog.rakus.co.jp tech-blog.rakus.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 *1 : https://www.postgresql.jp/document/9.3/html/app-psql.html *2 : https://www.postgresql.jp/document/9.3/html/sql-createtable.html *3 : https://www.postgresql.jp/document/9.2/html/app-createdb.html *4 : https://www.postgresql.jp/document/9.2/html/app-pgdump.html
アバター
はじめに こんにちは。Engawaです。 最近の業務でOAuthについて触れる機会がありました。 それまでの業務では担当経験はなく全く仕組みを理解できていなかったため、これを機に仕組みについてちょっと学習してみました! 参考にした書籍は以下になります。 https://www.amazon.co.jp/dp/484437818X www.amazon.co.jp OAuthとは OAuthとは「 サードパーティ アプリケーションによるHTTPサービスへの限定的なアクセスを可能にする認可 フレームワーク 」です。 上記だけだと意味が分からないので、画像編集アプリを例にします。 画像編集アプリで Google Photo上の画像を編集する際、ログインアカウントには Google アカウントを使いたい場合を考えてみましょう。   サードパーティ アプリ→画像編集アプリ HTTPサービス→ Google Photo 限定的なアクセス:ユーザーが許されている操作は画像のダウンロードのみで、それ以外の操作をしようとした場合は、HTTPサービスはアクセスを拒否しなくてはならない 認可 フレームワーク :アクセス トーク ン発効方法のルール(全てのアクセスに対して、許可していいアクセスかどうかをアクセス トーク ンを用いて判断する。) 上記の例を踏まえてOAuthの「 サードパーティ アプリケーションによるHTTPサービスへの限定的なアクセスを可能にする認可 フレームワーク 」を言い換えると 『画像編集アプリによる Google Photoへの限定的なアクセスを可能にするための「アクセス トーク ン発効方法のルール」』となります。 各役割の関係性 各役割 OAuthの基本的な役は大体以下の4つになります。 リソースオーナー リソースの所有者。 サードパーティ アプリにリソースへのアクセス権限を委譲しており、決められた権限の範囲内でリソースへのアクセスが可能になります。 クライアント 保護されたリソースにアクセスしようとするアプリケーション。 リソースサーバー データや機能を提供するサービス。一般的にはWebAPIの形で提供されている。 リソースサーバーはリソースオーナーが許可したアクセスを受け入れる必要があり、その手段がアクセス トーク ンとなります。 アクセスのたびにアクセス トーク ンの確認を行い、許可していいアクセスかどうかを判断する。 認可サーバー 認可サーバーの機能は以下の3つになります リソースオーナーを認証する(ログインの認証ではなく、リソースのオーナーであることを確かめるための認証) クライアントのリソースへのアクセスについてリソースオーナーの同意を得る アクセス トーク ンを発行する 上記例だと、リソースオーナーが Google アカウントにログインし、「画像編集アプリが Google Photoにアクセスすること」について同意すると、クラアントに対してアクセス トーク ンを発行します。 それぞれの関係 続いてそれぞれの関係についてざっくりまとめます。 ① 認可サーバに対して「リソースへのアクセス権」を要求する ② 認可サーバーは「クライアントへのアクセス権の委譲」についてリソースオーナーに確認を行う ③ リソースオーナーはアクセス権の委譲に対して同意をする ④ 認可サーバーはアクセス権が委譲された証であるアクセス トーク ンをクライアントに発行する ⑤ クライアントはアクセス トーク ンをもってリソースへのアクセスを実施する 終わりに 今回はOAuthについて、学習を行った内容を簡単に書かせていただきました。 まだまだ理解できないことがたくさんあるので引き続き学習を行なっていき、OAuthに関する記事の作成を行なっていければなぁと思います。
アバター
はじめに はじめまして。 ラク スの iketomo (いけとも) と申します。 弊社のオフショア開発拠点( ラク ス ベトナム )は2014年に新規で立ち上がり、今期で7年目に突入してます。 私は4年目~6年目までの3年間を拠点長として ベトナム 現地で務めさせていただき、今年6月に帰任させていただきました。 私自身 ベトナム では色々と楽しいことや、苦労したこともありました。 そこでの実体験・経験を踏まえたお話をさせていただきます。 ネット記事を漁ればオフショア開発に関する記事は散見されると思います。 そういった あるある記事 と、 ベトナム 現地での3年間の オレオレ経験 とを照らし合わせて紹介させていただきます。 そこからオフショア開発の現実・真実を感じ取ってもらえればと思います。 下記の5つの観点からご紹介させていただ、最後にまとめとして感想を少し述べさせていただきます。 はじめに (1). コスト (2). 技術・品質 (3). コミュニケ―ション (4). IT人材 (5). 離職・定着率 ベトナム現地での3年間のオレオレまとめ この記事では ベトナム ( ホーチミン )での弊社での経験が主軸となっており、他の国の事とは事情が異なる点や、主観が混ざっている点もありますのでご了承ください。 いきなり話が脱線しますが ベトナム人 に「いけとも」と自己紹介しても「いけもと」って呼ぶ人が多かったです。 なぜかというと ベトナム では 味の素( あじ のもと) が昔から根付いていて「いけもと」の方が呼びやすいのでしょう。に気づくのに3年かかりました。 では主軸の話へと移らさせていただきます。 (1). コスト ● あるある記事 一般的にオフショア開発では コストが安価 だとされています。 現在の ベトナム において、IT人材は初任給で言えば日本の 1/4 ~ 1/3 といったところでしょうか。 ただし成果を鑑みると、そのまま人件費がそのまま直結してコストが 1/4 ~ 1/3となりません。 ITにおいて、日本と同じ成果がでるわけではないので、上記の給与差がそのまま反映されることはないです。 ●オレオレ経験 弊社でも3年前は日本の 1/4 ~ 1/5 位の給与でした。 が、後述しますが、 ベトナム においてIT人材は売り手市場であり、年々給与アップしています。 現在では日本の 1/4 ~ 1/3 位まで上がりました。 ではコストはどうでしょう。 弊社では成果から計算した開発コストを日本と比べると、日本の 1/1.5 ~ 1/2 となっております。 現状において ベトナム のオフショア開発をやればコストメリットは出ると確実に言えます。 ただし、給与が上がっていくので、数年後にコストメリットがでるかどうかは、オフショア開発拠点の成果と品質によるところが大きなウエイトを占めると言えます。 給与の増加と共に、成果を大きくしないと、コストメリットはどんどん下がっていきます。 なので 給与アップに負けない成長や独自性 が必須だと言えるでしょう。 弊社においては ラク スの クラウド サービスの開発において、成長と独自性を追求する事としました。 半期、通期で ベトナム の成果や目指すべき方向( ベトナム においての Saas 開発No1)、そして本社の業績を定期的に報告・共有しメンバーと会社の成長を感じてもらうようにしました。 最近ではコストメリットというところを脱し、 ラク スの クラウド サービス拡大していく中で純粋に絶対必要な開発チームという位置づけに変わりつつあります。 ※普段は陽気ですが仕事中は真剣 (2). 技術・品質 ● あるある記事 一般的には、日本よりオフショア開発拠点の技術・品質は低いと言われています。 ただし ベトナム の IT技術 者は他の東南 アジア諸国 より技術力が高い とされています。 ベトナム ではテストを苦手とするエンジニアもおり、案件によっては品質が高かったり、低くなる時もあります。 QC(テスター)を実装を行うメンバーとは別に アサイ ンすることもあります。 ●オレオレ経験 弊社のオフショア開発立ち上げの初期では、技術・品質が低いと感じることも多くありました。 が、年数を重ね ベトナム の 開発メンバーが成長することで、日本の技術・品質に近づいていくことができました。 最近では技術・品質が日本を上回っているケースも散見され、 一部のメンバーは日本メンバーよりもコード・仕様に詳しくなってきています。 ベトナム人 の IT技術 者のレベルが低いか?と聞かれれば、個人的にそうではないと考えています。 では何の差があるかと言うと 「日本と持っているスキルセットが違う」 「日本のベテランメンバーが近くに居てすぐに聞きアド バイス を貰うということができない」 という2点の差があります。 「日本と持っているスキルセットが違う」 日本人は品質の部分では優位性を持っています。 一方で ベトナム人 は新しい技術をすぐに吸収するといった特性があります。 それぞれに良いところがあり、どちらが優れているという優劣はないと感じています。 日本では新卒は研修を数か月した後に、ようやく開発に入ったりすることがありますが ベトナム では新卒が入社後に直ぐに開発に入って活躍することができます。 スキルセットは環境が整えば日本と同様のスキルセットを吸収します。若ければ若いほど吸収の速度が速いのは自明の理でしょう。 「日本のベテランメンバーが近くに居てすぐに聞きアド バイス を貰うということができない」 これは日本でも開発メンバーが離れていたり、コミュニケーションが上手くいかないと同様のことが発生すると思います。 聞ける人が近くにいて認識齟齬をなくして開発できる。これが良い開発環境における大きくウエイトを占める部分と考えています。 言葉・文化が違い、距離が離れている異国間ではこういった良い環境を保ちづらいデメリットがあります。 こういった日本との差は、日本側の開発メンバーとのコミュニケーションの風通しが良くしたり、オフショア開発拠点にベテランメンバー(該当会社での在籍が3年以上)が増えてくれば徐々に環境の差を縮めることができます。 また日本化することもできます。なぜなら ベトナム人 は向上心が強く、日本をリスペクトしており日本から学ぼうとする姿勢が強いからです。 日本→ ベトナム または ベトナム →日本へ出張することで日本風のやり方・文化を学んでもらうことも効果があります。 弊社では改善・ PDCA ・振り返りを繰り返し行うことで次第にメンバーは自発的に考えながら自己成長していく組織へと変貌していきました。 ※コードレビュー指摘の振り返り (3). コミュニケ―ション ● あるある記事 オフショア開発ではどういったコミュニケーションをするのでしょう。 コミュニケーションをするには以下の方法があります。 「コミュニケーター(通訳兼翻訳)を介す」 「 BSE (ブリッジSE)を介す」 「英語でやりとりする」 リソースとスキルによりいずれかの方法を選択することになります。 コミュニケーターでもOKですし。 社内の英語スキルが高ければ英語でやるのも良し。 優秀な BSE を採用できるのであれば BSE でも良し。 ベトナム は 親日 な人が多く日本語ができるコミュニケーター、 BSE が数多くいるといった特徴があります。 時に言葉・文化の違いからか時に認識齟齬が発生することもあり、思ったように指示が通らなかったり、思った成果がでないこともあります。 ●オレオレ経験 弊社では 「コミュニケーターを介す」 を選択しました。 設計書などのドキュメントは日本語←→ ベトナム語 に翻訳します。 単純な質問は英語で行っています。 難しい質問は、チャット上で翻訳してもらうか、 MTG を開いてコミュニケーターに通訳してもらいます。 で、結果がどうだったかと言われると、現在では幸いなことにコミュニケーションによる認識齟齬は殆ど発生していません。 がそこに至るまでは、色々な障壁があり対応してきました。 ●コーディングなどの専門的な難しい内容になると通訳の品質が落ちる。 これに対しては週1でIT勉強会をして、通訳を BSE に近い状態になってもらいました。 Webサーバとはなんぞや?というところからプログラミング演習まで行い、IT知識を自学できるとこまで成長してもらいました。 コミュニケーターは沢山いても、ITコミュニケーターは多くはいないという考えで自ら育てるという方針でいきました。 ●わからない時でも質問をせずに進め、後に認識齟齬が発生する。 これには2つの要因があります。 「なるべく早くすることを良しとする ベトナム 文化」 開発においては認識齟齬が一番駄目だ! 報連相 が大事だ!ということを繰り返し伝え、質問文化を醸成しました。 もう1つは「日本との上下関係から委縮して質問できなくなってしまう」ことです。 日本メンバーが ベトナム人 を褒めたり、質問には即答してもらうことで、質問しやすい状況を作り、徐々に解決していきました。 ●大事な内容が伝わっていない。 重要な事と認識するポイントに文化間の差があり、日本が重要視することが見落とされていて、逆に重要視しないところに重きを置くことがあります。 私は難しい話をする時は、先にコミュニケーターにじっくりと説明して理解してもらい、実際の通訳の時に落ち着いて通訳してもらうようにしました。簡易でもいいので口頭だけではなくアウトプットがあるとさらに通訳の難易度が下がり理解度が上がります。 通訳はリアルタイムで難しい作業です。いきなり専門的な難しい話をして、口頭で話して、はいこれを通訳してくださいと言っても、なかなかできるものではありません。 まずは内容を理解するという時間でしっかり理解してもらい、それをベースに通訳してもらえば、私たちの意図を効率よく伝えてもらうことができます。 ※チームワークとコミュニケーションが大切 (4). IT人材 ●あるある記事 オフショア開発と言ってもいろいろな国があります。 ベトナム は他の東南アジアより優秀なIT人材が豊富に揃っていると言われています。 若く優秀な人材を安いコストで獲得することができるというのが通説です。 が、日系や欧米企業の参画が多く近年では 「需要 > 供給」 で売り手市場となっており 年々給与ベースが上がってきています。 ●オレオレ経験 優秀なIT人材が他の東南アジアの国より多いというのは事実です。 また日本よりIT人材を獲得しやすいか問われればその通りです。 では自社が求めるIT人材を簡易に獲得できるかと言われれば、そんなことはないです。 上記しましたが「需要 > 供給」 となっている中では各社で創意工夫が必要です。 ただし、 親日 の国であり、日本企業に入りたい!日本企業で学びたい!と思うIT人材も数多くいます。 そういった人材の中から自社に合った人材を獲得することになります。 スキルや性格にこだわりがなければ、簡易に獲得することができますが 弊社では求める部分も多く、色々な努力をしつつ、なんとか獲得できているといったところです。 「良い人材へのオファーは当日中に出す」「 Facebook で魅力アピール」「過去の面接者にも再度連絡」「 リファラル採用 のキャンペーン」等、できることはなんでもトライしました。 ※表彰することでモチベーションアップ (5). 離職・定着率 ●あるある記事 ベトナム においては 日本と比べてIT人材の 離職率 は高く、定着率は低い とされています。 ジョブ ホッピング も当たり前で、新卒は2年位で転職することが普通とされています。 せっかく育てたメンバーが、、、と各日本企業の頭を悩ませています。 離職が多くとも成り立つ組織。または離職しない組織を目指すことになります。 ●オレオレ経験 弊社でも例にもれず、2年、3年前は 離職率 が高かったですが、最近ではかなり低くなってきました。 離職率 が高くなると、会社としてのノウハウの蓄積ができず、組織としての成長は望めませません。 離職率 が高く、定着率が低いことは、どの会社でも大きな課題 です。 弊社では最初の3年間はスタートアップということもあり、それ程 離職率 は高くありませんでした。 その後、弊社での経験をベースに他社に転職することもあり、 離職率 が高くなりました。 そして現在 離職率 は低くなっています。 では、何が変わったのか?変えたのか? 弊社では 「会社の独自性と居心地の良さ」というところを強め他社との差別化を図りました。 「自発的な組織」 言われたことをやるだけではなく自発的に動く。 トップダウン ではなく ボトムアップ の行動をより評価する。 「改善・ PDCA 」 の徹底。昔は拒否感が強かったですが、繰り返し実施することでチームとしての成長を感じてくれ、今ではこれが普通になり何も言わずとも振り返りMTGを行ってくれます。 「とにかく楽しい」 を目指す。何が楽しいかを自分たちで議論させ、実行・主催してもらうようにしました。 「給与アップ」することである程度転職を防ぐことはできます、がそれは青天井で限界があります。 給与を求めるメンバーは給与アップしたとしても、さらに高い給与を目指して転職してしまいます。 そういったメンバーはいつか去る事になるので引き留めない方が良いでしょう。 ※コアバリューの浸透で社内文化の醸成 ベトナム 現地での3年間のオレオレまとめ 他文化・他言語ということもあり、いろいろ苦労した側面がありました。 が、いつでも ベトナム人 の優しさと明るさ が私を支えてくれました。 結果としては私が想像していた以上に、 ベトナム人 の向上心は強く、大きく成長してくれ 、今では思った以上の成果を出せる誇らしい組織と変貌することができました。 個人的には 安易にコストメリットだけを見てオフショア開発をやってみることはおススメできません。 コストメリットは何もしなければ風化していくからです。 彼らと一心同体となって成長することを決心してください。 その気持ちが伝わり、適切な仕組みやアド バイス をすれば必ず成長してコストメリットを超えた 期待以上の成長と成果を出してくれます。 会社独自の戦略で社員の定着率を高めてください。 離職率 を抑えることができたなら、あとは成長が待つのみです。 上記のご紹介した内容が皆様のオフショア開発を始めるきっかけや、課題や懸念の解決の糸口になれば幸いです。 長文になりました。最後まで読んでくださった方ありがとうございます! ※誕生日はちょっとした社内パー ティー エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに こんにちは、itoken1013です。暑い毎日が続きますね! 今回紹介するのは、実務でも個人開発でもオススメのHeroku(ヘロク)の基礎的な使い方になります。 Herokuを使うことで、開発したWEBアプリケーションを手軽に公開することができます。 この記事ではHerokuの概要を説明した後、簡単な公開(デプロイ)の手順を紹介することで、初心者でもHerokuを使った開発者に入門できる内容となっています。 今回の記事を参考に、ステイホーム中の スキルアップ を進めていただければ幸いです! はじめに Herokuの概要 まず、PaaSとは それでは、Herokuとは 多様な言語・FWをサポートしている プランによっては無料で使える Gitコマンドで操作できる 拡張機能が非常に多い Herokuを使ってみる Herokuのアカウントを登録する Heroku CLIをインストールする Windows の場合 Mac の場合 Herokuにログインする デプロイを行う アプリケーションの取得 デプロイ実施 動作確認 おわりに Herokuの概要 まず、PaaSとは クラウド サービスは大きく SaaS 、PaaS、IaaSの3種類に大別されますが、Herokuはこのうち、PaaS(Platform as a Service)に分類されます。 PaaSとは、開発したWEBアプリケーションを開発・実行するための基盤(プラットフォーム)を提供するサービスを指します。 PaaSを利用することで、それまで必要だったサーバーの購入やOS、DB、WEBサーバなどの ミドルウェア 類のセットアップが不要となり、開発者はインターネット越しでPaaSを操作するだけで、手軽にWEBアプリケーションの ホスティング ができるようになりました。 また画面や コマンドライン 上でスケールアップ/アウトを手軽に行うことができ、この点もWEBアプリケーションの公開のハードルを下げた一因です。 このようにPaaSが普及したことで、開発者は本質的な開発作業に集中することが可能になりました。 それでは、Herokuとは 上記で説明しましたPaaSであるHerokuを使うことで、作成したアプリケーションを手軽に公開することが可能となります。 他のPaaSと比較した際のHerokuの特徴には、以下の点が挙げられます。 多様な言語・FWをサポートしている 元々は Ruby 向けのPaaSだったHerokuですが、現在では国内で扱われている主要言語とFW(以下)をほぼカバーしています。 この対応言語の広さが、PaaSの中でもHerokuが多く活用される一因でしょう。 Ruby ( Rails 含む) PHP Java Node.js Python Go Scala (Play含む) Clojure また公式サポートされている上記以外にも、buildpackと呼ばれる機能を利用することで、希望の言語・FWをHeroku上で利用することもできます。 jp.heroku.com プランによっては 無料 で使える Herokuが普及した最大の要因といっても過言ではないのが、利用プランです。 Herokuには数種類の利用プランがありますが、 Freeプランを利用の場合、無料でHerokuを利用することができます。 もちろん無料であるが故に制約は存在しますが、個人的な スキルアップ を目的とした利用にあたってはFreeプランで差し支えないはずです。 (少なくとも私がプライベートで個人利用している中では、一度もプラン変更は発生していません) 収入を目的にアプリケーションを公開する場合ではFreeプランでは耐えられないかと思いますが、あくまで スキルアップ のための利用であれば、Herokuを無料活用することが可能です。 ただし、今後プランの見直しが発生する可能性はありますので、ご利用の際は事前に以下の公式ページを参照いただければと思います。 jp.heroku.com Gitコマンドで操作できる Herokuではアプリケーションをデプロイする操作として、エンジニアならお馴染みのGitコマンドを利用します。 このため、Herokuへのデプロイ作業のために覚えることは最小限で済みます。 Herokuをリモー トリポジ トリとして git push するイメージですので、普段からエンジニアの手慣れた操作で手軽にアプリケーションを公開することができます。 なお、後続の手順ではGitを使った操作が必要となります。 Gitを未インストールの方、Gitコマンドの利用経験が浅い方は、まずはこちらを参照いただければと思います。 tech-blog.rakus.co.jp 拡張機能 が非常に多い 今回は紹介しませんが、Herokuには数多くの 拡張機能 (アドオン)が存在おり、自前で実装せずに便利な機能を利用することができます。 中には無料のプランを提供している機能もあり、代表的な 拡張機能 を以下に紹介しておきます。 興味のある方は、ぜひご自身の開発で活用してみてください。 SendGrid:メール配信 PaperTrail:ログ管理 New Relic APM :監視 Herokuを使ってみる Herokuのアカウントを登録する それではここから、Herokuを利用するための操作を簡単に紹介していきます。 まずはHerokuのアカウントを取得しましょう。 以下の画面より必要事項を入力の上、「無料アカウント作成」をクリックしてください。 signup.heroku.com 上記で入力したメールアドレスに認証メールが届きますので、メール内のリンクをクリックしてアカウントを有効化します。 最後にパスワード設定を求められますので、任意のパスワードを設定してください。 ここまで完了し、以下の画面が表示されればアカウント登録の作業は完了です。 Heroku CLI をインストールする 次にHerokuを コマンドライン 上から操作するためのツールをインストールします。 後続のデプロイ作業には、こちらのツールが必要となります。 以下のページにアクセスし、ご利用のOSに応じた手順でインストールを行っていきます。 devcenter.heroku.com Windows の場合 Windows 用の インストーラ が提供されていますので、ダウンロードの上、 インストーラ を起動してください。 今回は全てデフォルトの状態で進んでいただき、「Install」ボタンをクリックいただければ問題ありません。 Mac の場合 Mac では インストーラ を用いず、上記ページにあるコマンドをターミナル上で入力してください。 ※パッケージマネージャである Homebrew がインストール済である必要があります。 brew tap heroku/brew && brew install heroku ここまで完了しましたら、 CLI を起動してみましょう。 Windows であれば コマンドプロンプト やGit Bash 、 Mac であればターミナルを起動し、以下のコマンドを入力してください。 無事にバージョン情報が表示されれば、 CLI のインストールは完了です。 $ heroku --version heroku/7.42.6 win32-x64 node-v12.16.2 Herokuにログインする 先ほど作成したアカウントを使い、 CLI 上でHerokuにログインします。 heroku login -i を入力すると コマンドライン 上でログインを求められますので、アカウント作成時のメールアドレスとパスワードを入力してください。 ※ iオプション を付けない場合、ブラウザ上にHerokuのログイン画面が立ち上がりますが、同様にログイン認証を進めれば問題ありません。 $ heroku login -i heroku: Enter your login credentials Email: メールアドレス Password: パスワード Logged in as メールアドレス デプロイを行う ここからは、実際にHeroku上にアプリケーションをデプロイしてみましょう。 GitHub 上のサンプルプログラムを使い、デプロイの手順を紹介していきます。 簡単なデプロイのイメージを示します。 アプリケーションの取得 まずは任意の場所に ディレクト リを用意しましょう。 今回は「rakus」という ディレクト リ配下で作業を進めていきます。 $ mkdir rakus rakus ディレクト リへ移動後、次にデプロイ用のアプリケーションを GitHub より取得します。 git clone を使い、任意の リポジトリ (今回はHerokuのサンプルアプリケーションを使います)からクローンを行います。 ※実際の開発ではここが開発対象の リポジトリ となり、ローカル リポジトリ を最新化しておく必要があります。 $ git clone 'https://github.com/heroku/java-getting-started.git' Cloning into 'java-getting-started'... ・ ・ ・ Resolving deltas: 100% (179/179), done. デプロイ実施 Heroku上にデプロイを行うためのアプリケーション作成を実施します。 まずはクローンしたアプリケーション配下へ移動します。 $ cd java-getting-started/ 次に heroku create コマンドを入力すると、デプロイ用のアプリケーションが作成されます。 この際、 コマンドライン 上に表示されるURLを控えておいてください。 また、以下に示す XXXX-ZZZZ-123456 (例)が作成したアプリケーション名を表しています。 ※アプリケーション名は heroku create コマンドの引数で指定可能です。 指定がない場合、「XXXX-ZZZZ-123456」のようなランダムな名称が割り振られます。 $ heroku create Creating app... done, XXXX-ZZZZ-123456 https://XXXX-ZZZZ-123456.herokuapp.com/ | https://git.heroku.com/XXXX-ZZZZ-123456.git 最後に git push heroku master を入力すると、Heroku上へのデプロイが行われます。 $ git push heroku master Enumerating objects: 400, done. Counting objects: 100% (400/400), done. Delta compression using up to 4 threads. Compressing objects: 100% (190/190), done. Writing objects: 100% (400/400), 178.59 KiB | 25.51 MiB/s, done. Total 400 (delta 152), reused 400 (delta 152) remote: Compressing source files... done. ・ ・ ・ remote: https://XXXX-ZZZZ-123456.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/XXXX-ZZZZ-123456.git * [new branch] master -> master これでデプロイ作業は完了です。 動作確認 ここまででデプロイ作業は完了ですが、最後にデプロイしたアプリケーションを確認してみましょう。 上記の デプロイ実施 で表示されたURL(上記であれば https://XXXX-ZZZZ-123456.herokuapp.com/ )をブラウザに入力してください。 以下のような画面が表示されれば、正常にデプロイが完了しています。 無事に画面が表示されましたか? 今回の作業は以上で完了となります。 お疲れ様でした! おわりに 今回はHerokuを使ったアプリケーションの公開手順を紹介してきましたが、いかがでしたでしょうか? 思っていたよりも簡単な手順だと感じた方が多いのではないでしょうか? 実際の開発でHerokuを応用的に活用していくためには、Heroku固有の概念(DynoやHeroku Flowなど)への理解がまだまだ必要です。 ですが、最低限のプラットフォームとしての機能と利便性は、この記事を使って理解いただけたはずです。 今回の内容を足がかりにしていただき、今後の開発にお役立ていただけると幸いです。 ではでは、またの機会に。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
はじめに 技術広報のitoken1013です。こんにちは。 いつも ラク スのイベントにご参加いただいている方々、本当にありがとうございます! 今回は8月1回目のMeetup 『レガシーを吹き飛ばすPHPer実践テクニック』 について、コンテンツを紹介させていただきます! イベントテーマ概要 今回は 『レガシーを吹き飛ばす』 という強力なイベントタイトルを掲げさせていただき、 リリースから10年以上 の以下サービスに携わるエンジニア3名が登壇させていただきました。 これらのサービスは多くのお客様に長くご利用いただき、現在でも新たな機能追加を進めています。 その一方で長い開発で蓄積しているレガシーな面とも向き合う必要性が高まっており、開発速度と品質を落とさないための取り組みが求められています。 今回はそんな取り組みの中でも、より実践的なテクニックを紹介させていただきました。 楽楽販売 メールディーラー 配配メール ちなみにご参加の方へ利用言語をお聞きしたところ、(当然ではございますが…)大半が PHP 使いの方でした。 また、登壇者と同じように レガシーシステム の開発に携わっている方もいらっしゃり、今回のイベントで得たテクニックを早速活用したいと言っていただける場面もありました。 ラク スでは PHP 中心のイベントを頻繁に開催しておりますので、今後もイベントにご参加いただけますと嬉しいです! 発表の紹介 それでは3名のエンジニアによる発表を簡単に紹介させていただきます! 「指摘の 見える化 」SonarQubeを使って、新規不良コードをデビューさせない仕組みづくり 楽楽販売の開発に携わる凪から、静的コード解析ツール 「SonarQube」 を使ったコードレビューの改善についての発表となります。 主にレビューを中心に担当する凪ですが、日に日に増大するレビュー負荷という課題を踏まえ、静的コード解析ツールの導入を決定しました。 数あるツールからSonarQubeを選択した背景、実際に運用を開始してからの効果について詳細に語られています。 サービスの急拡大に伴ってレビューが追い付かない!、という悩みをお抱えの方には是非ご参考にしていただきたい内容です。 speakerdeck.com PHP 標準関数との闘い PHP のバージョンアップ(7.1 から 7.3)に伴う count()関数 の仕様変更にまつわる、 ラク ス最古参のサービスであるメールディーラー(2001年4月リリース)でのエピソードを加納より紹介させていただきました。 リリースよりおよそ20年、メールディーラーではありとあらゆる場所でcount()関数を呼び出しており(呼び出し数は、ぜひ資料をご覧ください…)、あるべき論だけでは語れない戦いが繰り広げられることとなりました。 さらには開発体制に起因する新たな問題も生まれてしまい…という苦労を抱えたエピソードになっております。 言語や フレームワーク の仕様変更は、ソフトフェア開発では避けては通れない戦いです。 今回は歴史を抱えたサービスを支えるための戦いではありますが、ご紹介のノウハウはどの開発でも活用できるはずです。 ぜひ多くのエンジニアに役立てていただければと思います。 speakerdeck.com 13年続くレガシーサービスを安全にリリースし続けるための、E2Eテストと カバレッジ ツールを利用したテスト戦略について リリースから13年が経過した配配メールにおける、吉元が取り組むテスト戦略をお話させていただきました。 名著のレガシーコード改善ガイドでは『自動テストが無いコードはレガシーコードである』と触れられていますが、吉元の携わる配配メールではまさに自動テスト環境が存在せず、高い品質を保ったリリースに課題を抱えていました。 www.amazon.co.jp 「プロダクトコードの複雑性」や「計画の不確実性」といった課題を抱えていた開発チームですが、これらに向き合った「重要機能テストの自動化」や「 テスト駆動開発 」などの戦略が語られています。 詳細で実践的な内容であるため、ご自身の開発現場でも活用できそうと感じていただけるはずです。 speakerdeck.com おわりに レガシーに向き合う ラク スエンジニアの取り組み、いかがだったでしょうか。 簡単な課題は1つも存在しませんが、多くのお客様にご利用いただける期待に応えるため、日々レガシーを吹き飛ばすテクニックに取り組んでいます。 さて、次回のMeetup(8/25開催予定)は 『新サービス』 がテーマです! すでに100人以上の方に申し込みいただけており、大イベントになりそうな予感がしています。 rakus.connpass.com また PHP に関するイベントも8月中に2回開催予定です。 こちらもたくさんのご参加をお待ちしています! rakus.connpass.com rakus.connpass.com
アバター
はじめに 技術広報のitoken1013です。こんにちは。 6月に多くの方にご参加いただきました ラク スMeetup、7/29(水)にも 『 SaaS 開発リーダーが実践する開発速度向上プ ラク ティス/海外拠点、 スクラム 、時間管理』 をタイトルにオンライン開催させていただきました。 今回も当日の発表を簡単に紹介させていただきます! イベントテーマ概要 ラク スでは『企業で働く人々の生産性を向上し、より豊かな社会の実現』を掲げて、多様な SaaS をお客様に展開しています。 そのために ラク スのエンジニア自身も日々、開発速度や生産性向上に向けたプ ラク ティスに取り組んでいます。 今回は多くのお客様にご支持をいただいています 楽楽精算 と 楽楽明細 の開発に携わるエンジニア3名が登壇し、それぞれが挑戦中の取り組みをご紹介させていただきました。 個人・チーム・オフショアの3つの視点からのプ ラク ティスが紹介され、多様なポジションの参加者の方からコメントをお寄せいただけました。 発表の紹介 25 + 5分で開発速度を上げる時間管理術! ポモドーロテクニック の紹介 まず楽楽精算で開発・運用とマルチな役割を担う平山から、作業時間を管理するための ポモドーロテクニック を紹介させていただきました。 開発に限らず生産性向上のテクニックとして広く知られる ポモドーロテクニック ですが、今回は平山の具体的な課題のエピソードと実践後の効果が語られることで、日々のお仕事で取り入れてみたいと感じていただけたのではないでしょうか。 若手・中堅・ベテランのどのエンジニアにもお勧めしたいテクニックです。 www.slideshare.net スクラム 開発ドキュメンタリー ~なぜなぜ、落ちる スクラム 開発速度~ 次は楽楽明細で スクラム 開発を実践中の柴田より、開発デモで起きてしまった、とある苦いエピソードを紹介させていただきました。 開発サイドとビジネスサイド(もしくはユーザー)で生まれる認識のズレややり直しは、どの企業様に所属するエンジニアの方でもご経験のあるトラブルかと思います。 柴田が所属する楽楽明細チームではこれらのトラブルに対し、 スクラム の枠組みに捕らわれずに柔軟に開発スタイルを変更することで改善を図っていきました。 いまだ試行錯誤を続けながらの取り組み、今後の成果に期待です。 speakerdeck.com Quality First & Fastを実現するオフショア開発のポイント9選 今回のラストは、楽楽明細の開発リーダーを務める樋口です。 ラク スの子会社である ベトナム の『RAKUS Vietnam Co., Ltd.』のエンジニア陣をマネジメントする樋口ですが、開発速度と品質の両立のために駆使するテクニックを具体的に紹介させていただきました。 『日本が特殊な国だということを理解する』『日本の設計観点を伝える』など、複数国の方との仕事経験が豊富な樋口ならではの発表でした。 またオフショアをテーマにした内容ではありますが、日本人のエンジニア同士でも参考にしていただけるプ ラク ティスを見つけていただけるはずです。 speakerdeck.com おわりに 今回は特定の技術スタックに偏ったイベントテーマではなかったこともあり、さまざまなレイヤーの方にご参加いただけました。 プロジェクトマネジメントに課題を抱える方、個人のスケジュール管理がうまくいかない方などの参考にしていただけますと幸いです。 ラク スでは8月以降もMeetupやLT・勉強会の開催を予定しています。 すでに多くの方にお申し込みいただき、ありがとうございます! 今後も ラク スエンジニアからの情報発信をどうぞお楽しみに!! rakus.connpass.com rakus.connpass.com
アバター
技術広報の syoeshin です。 当社では最近、下記2つの定期的な読書会を企画し、スタートしました。 社内の有志達がリードして、それぞれが好きな本を読み/紹介しあう読書会 社内の 有識者 達がリードして、選定した技術書の理解を深める読書会 定期的な読書会を組織の取組みとして始めた目的は "個と組織の成長" です。 成長のプロセスは 知識を得る (勉強会で話を聞く、本を読む、ニュース/記事を読む など) 訓練する (繰り返し修練、習慣にする など) 実践する に分解できます。 定期的な読書会の機会をつくり、参加してもらう事で 成長の源泉となる 知識を得る   ×   訓練する のサイクルは定着させる事ができます。 もちろん 実践する はとても重要ですが 私たちの開発組織は 支援の厚い実践シーンの連続 ですので 知識を得る   ×   訓練する サイクルが定着すれば 個の成長が加速する事は、言うまでもありません。 さて まずは 知識を得る   ×   訓練する のサイクル定着を目的として始めた読書会は 早速、以下のようなうれしい副次効果も見られ始めました。 組織内コミュニケーションの ダイバーシティ 化 要約/意見をまとめる/人前で話すスキルの向上とリーダーシップの育成 組織内での専門性/ アイデンティティ の確立 ーー組織内コミュニケーションの ダイバーシティ 化 私たちの開発拠点は 東京・大阪・ ベトナム と分かれており これまで社内イベントは拠点を中心とした開催が主で 業務外のコミュニケーションも拠点が中心となっておりました。 密を避けるべき状況下で、読書会はオンライン開催となったため これまでの様に拠点別の開催ではなく 東京、大阪、 ベトナム から社員が一斉参加できる読書会は 拠点を問わず、若手・中堅・ベテランを問わず 業務外コミュニケーションも交わせる機会の一つとなりました。 ーー要約/意見をまとめる/人前で話すスキルの向上とリーダーシップの育成 読書会にはさまざまな形式がありますが、当社が実施している 社内の有志達がリードして、それぞれが好きな本を読み/紹介しあう読書会 の参加目的は「それぞれの自由でよし」としています。 こちら読書会の参加者には 会の冒頭で 「今日はどこまで読む」と読書宣言をしてもらい 1~1.5hの読書後 に 読んだ本/部分を要約し、参加メンバーに伝えてもらうようにしております。 また、参加者から ファシリテーター (簡単な司会進行)を選出し 会の進行をしてもらいます。 ・読書宣言 ・読んだ本/部分の要約を発表 ・読書会の司会進行 をしてもらう事で  知識を得るためだけの読書会ではなく ・人前で話す ・意見をまとめる ・人の意見を聞きながら結論を導く場を作る というト レーニン グになり、スキルを磨くことができる仕組みで 参加者は 心理的 負担が小さい中で リーダーシップに必要な要素が身に付けられるようになってます。 ーー組織内での専門性/ アイデンティティ の確立 社内では ・ アーキテクチャ に詳しい 人 ・ アジャイル 開発や スクラム に詳しい 人 ・フロントエンドに詳しい 人 等々 おりますが そういったメンバーは”特定分野の知識と経験が豊富”と社内で認識されており 特に知識面では、その分野に関わるたくさんの本を何度も深く読んでいる事が多いです。 社内の 有識者 達がリードして、選定した技術書の理解を深める読書会 では 特定分野や技術テーマに沿って読書会が開催されており 読書会を主催するメンバー達は、 ”特定分野に詳しい人” と社内で認識され 自身の専門性と アイデンティティ を確立しています。 また 当社では有志達が始めた社内勉強会から発展した 「 TechCafe※ 」という 社外向け勉強会コミュニ ティー を運営しており 社外向けに特定分野/技術のベントを主催する事で 社内だけでなく社外にも自身の専門性と アイデンティティ の確立を進めています。 ※TechCafe詳細「TechCafeができるまで」 tech-blog.rakus.co.jp ーーまとめ 読書会の開催/参加メリットは世間でさまざまに言われてますが 社内で読書会を開催してみて 世間で言われているどのメリットも得られる というのが現時点での所感です。 まだまだ開催の実績は少ないですが 中核メンバーや管理職、開発組織以外メンバーの参加が増えていけば ・組織コミュニケーションの ダイバーシティ 化 ・組織メンバーのリーダーシップ育成 ・組織メンバーの専門性/ アイデンティティ の確立 の進化ができ ”個と組織の成長”を加速できる と考えているため 今後もより多くのメンバーが参加しやすく 何より楽しめる「読書会」を企画していこうと考えております。 当社運営の勉強会コミュニ ティー は以下サイトからご参加ください。 rakus.connpass.com また、私たちは一緒に働くメンバーを募集しています。 ご興味を持たれましたら以下のサイトからお問い合わせください。 career-recruit.rakus.co.jp
アバター