TECH PLAY

株式会社ラクス

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

927

はじめまして。新規サービスの開発チームに所属しているkarabishです。 前から気になっていた Grafana Loki をローカルで試してみました。 Grafana Lokiはログ集約システムで、似たものとしては Elasticsearch や Splunk になるのかと思います。 公式ドキュメントでも Elasticsearch との 比較 が記載されています。 環境構築 1. ロギングプラグインのインストール 2. docker-compose.ymlにLokiを追加 3. docker-composeの起動 ログの閲覧と検索 初期設定 ログの閲覧 最後に 環境構築 今回は、 docker-compose でローカルにLokiを構築した手順になります。 PostgreSQL のログを転送させるようにしています。 1. ロギング プラグイン のインストール PostgreSQL のログをLokiに直接転送するためにdocker pluginをインストールします。 docker pluginについては Docker Driver Client に記載されています。 $ docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions latest: Pulling from grafana/loki-docker-driver 0974501310e6: Download complete Digest: sha256:436fb0e17e7dde023398b539b03d91d902d5293da199a6ef6bb0b8262b8801e7 Status: Downloaded newer image for grafana/loki-docker-driver:latest Installed plugin grafana/loki-docker-driver:latest $ 2. docker-compose.ymlにLokiを追加 ドキュメント に紹介されていたdocker-compose.ymlを参考に記載したものです。 PostgreSQL のログをLokiに転送するためにloggingプロパティでLokiの接続情報を記載しています。 version: "3.8" networks: loki: services: postgres: image: postgres:12.3 container_name: postgresql ports: - 5432:5432 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres - POSTGRES_DB=sample restart: always logging: driver: loki options: loki-url: http://localhost:3100/loki/api/v1/push volumes: - postgresdata:/var/lib/postgresql/data loki: image: grafana/loki:1.5.0 container_name: loki ports: - 3100:3100 command: -config.file=/etc/loki/local-config.yaml networks: - loki grafana: image: grafana/grafana:master container_name: grafana ports: - 3000:3000 networks: - loki volumes: postgresdata: driver: local 3. docker-composeの起動 $ docker-compose up -d Creating network "grafana-loki_default" with the default driver Creating network "grafana-loki_loki" with the default driver Creating volume "grafana-loki_postgresdata" with local driver Creating loki ... done Creating grafana ... done Creating postgresql ... done $ ログの閲覧と検索 初期設定 Grafanaにログインします。 URLは http://localhost:3000/ です。 初回はEmail or username: admin 、Password: admin でログインできます。 Add your first data sourceからLokiを選択して、URL欄に http://loki:3100 を入力の上、[Save&Test]ボタンを押せば初期設定は完了です。 ログの閲覧 サイドメニューからExploreにアクセスします。あとは、Log lablesを設定するとログが閲覧できます。 下の画像は container_name ラベルで postgresql コンテナのログを閲覧した結果です。 最後に 比較的少ない作業で PostgreSQL のログをLokiで集約してGrafanaで閲覧するまでの構築はできました。 PostgreSQL のログを見るだけであれば docker logs で問題ないのですが、他のログもあわせてみたい時があるので今後は集約するログを増やしていければと思います。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
皆さんこんにちは。 ラク スのフジサワです。 以前、TypeScriptを始める前は 「学習コストが高そう」「今動いているサービスに導入するのは難しいんだろうなあ」 というイメージが強かったのですが、なんてことはなく、タイトルにある通り、 「TypeScript使わないという選択肢なくね?むしろレガシーなアプリケーションこそ、使っていくべきじゃね?」 と手のひらがグリングリン回転したので、ぜひ皆さんに紹介させてもらいたいと思い、この記事を書くことにしました。 TypeScriptとは Microsoft 製のAltJS( JavaScript の代替となるもの)で、 OSS で開発されている 静的型付き言語で、直感的にいえば「 JavaScript +型」 TypeScript コンパイラ や、webpack、Babelなどで JavaScript にトランスパイルして使用する フロントエンド(ブラウザ)、バックエンド(Node.js)双方の開発で活用できる 理由① 『TypeScriptは JavaScript のスーパーセットである』 これは、 公式サイト の冒頭に出てくる言葉なのですが、ちょっと何言ってるか分からないですよね。 簡単にいうと、 「TypeScriptは JavaScript の上位互換であり、 JavaScript の文法・知識がそのまま適用できるよ」 ということを言っています。 もちろん、TypeScript固有の言語仕様や、便利な使い方などは存在するのですが、それを習得していなくてもTypeScriptを利用することができます。 もっと言えば、「 JavaScript と思って使うこともできるし、必要に応じてTypeScriptならではの機能を使うこともできる」と表現できます。 理由②  型推論 の恩恵により型に対する安全性を獲得できる 型推論 とは、変数や関数 シグネチャ の型を明示的に宣言しなくても、初期化の際に代入する値や、関数呼び出しの実引数などの情報や文脈から、自動的に型を推測して決定する仕組みのことを言います。 これにより、いちいち型を書くと冗長な記述になりがちな型システムによる安全性を享受しながら、冗長さを回避したシンプルな記述ができると言われています。 ※なお、 型推論 については賛否があり、 型推論 を活かしたコードは、明示的に型が表現されないので、予想外の推論結果になったり、逆にわかりにくくなってしまうという意見もあります。 TypeScriptの 型推論 がなぜレガシーコードにとって重要なのか? 前述の通り、TypeScriptの 型推論 の機能によって、既存の JavaScript コードが型宣言を行っていなくても、型を推測し、 コンパイル 時に適切にチェックを行ってくれるようになります。 これは、「もともと型の概念が存在していないコード」であったとしても、部分的に型安全を保っていくことができるということを意味しています。 コードの具体例をいくつか挙げながら、どのように 型推論 が行われ、 コンパイル 時の型チェックに利用されるかを紹介します。 TypeScriptにおける 型推論 の例 例1 : let/const let foo = 'hello' ; // 明示的に指定していないが、fooはstringであると認識される foo = 1; // コンパイルエラー console.log(foo); 1行目でfooは string であることがわかっているので、2行目の number 型の値を代入しようとするとエラーになる 例2 : return値① function someFunc() { return 100; // 明示的に指定していないが、返却値はnumberであると認識される } let message: string = someFunc(); // コンパイルエラー someFuncの戻り値が number であることが分かっているので、 string 型の値への代入が コンパイル エラーになる 例3 : return値② function multi(a: number, b:number) { return a * b; //number * number = number } 引数が number なので、演算結果も number であると推論される 例4 : 配列 let foo = [ 0, 1, 2 ] // foo: number[]と推論 let bar = [ 0, 1, 'aaa' ] // bar: (number | string)と推論 例5 : Object const user = { name: 'Taro' , // name: stringと推論 age: 20 // age: numberと推論 } /* 以下の型を持つオブジェクトであることが推測される const user: { name: string; age: number; } */ JSON let data = [ { "id" : 100, "name" : "Taro" } , { "id" : 101, "name" : "Hanako" } ] /* 以下の型を持つオブジェクトであることが推測される let data: { id: number; name: string; }[] */ レガシーコードが、TypeScriptの導入によって恩恵を得るサンプル 下記のようなコードがすでにシステム上に実装されているコードだとします。 function someFunc(foo) { if (foo > 0) { return foo * 2; } } var bar = someFunc(1); console.log(bar.toString()); もちろん、この JavaScript は問題なく動作しますが、このコードには一つの問題が潜んでいます。 パラメータに負値を渡すとどうなるでしょうか。 var baz = someFunc(-1); // 負の値を渡すとundefinedが帰ってくる console.log(baz.toString()); baz.toString() は、 baz が undefined なので、ランタイムエラーが発生します。 しかし、これは実行しなければ検出することができません。 では、これをTypeScript環境で コンパイル するとどうなるでしょうか? コンパイル エラーが発生する var baz = someFunc(-1); console.log(baz.toString()); // コンパイルエラー:Object is possibly 'undefined'. コンパイラ がコードを解析して 型推論 した結果は次の通りとなり、 number または undefined を返すメソッドであると認識されます。 function someFunc(foo: any): number | undefined someFunc は undefined を返す可能性があるため、その返却値を代入している baz に対する操作が危険であることを、 コンパイラ が教えてくれるようになります。 someFuncを安全に使用するには、次のようなコードに修正する必要があります。 var bar = someFunc(-1); if (bar === undefined ) {   // undefinedのチェック bar = 0; } console.log(bar.toString()); 上記のように記述すれば、 コンパイル エラーは起きなくなります。 bar === undefined のチェックがあることで、 toString が実行されるタイミングでは number しか到達しないことをTypeScriptが理解するようになるからです。 ※なお、このような型の絞り込み処理を「型ガード」と呼びます。 先程は someFunc を使う側のコードの問題をTypeScriptが検出してくれる例を見ましたが、実は someFunc 自体にも問題が潜んでいます。 コンパイル 時のオプション noImplicitReturns を有効にすると、次のような コンパイル エラーが発生する function someFunc(foo) { // コンパイルエラー:Not all code paths return a value. if (foo > 0) { return foo * 2; } } someFunc がすべてのパスで返却値を返しておらず、意図しないundefinedを返す可能性を教えてくれるようになります。 このように、既存コードに型宣言など、型の情報を与えていないにもかかわらず、 型推論 によって未然に不具合を検出することができるようになったのが分かるかと思います。 理由③  JavaScript ライブラリとの連携が容易である レガシーなシステムにはすでにたくさんの JavaScript で記述されたライブラリが使用されています。 TypeScriptには、こうした JavaScript ライブラリとうまく連携する仕組みが備わっています。 JavaScript で記述されたライブラリをTypeScriptに導入する方法はいくつか存在します。 型宣言ファイルを自作する DefinitelyTypedで公開されている型定義ファイルを使用する allowJSオプションを活用する 型宣言ファイル(d.tsファイル)を自作する方法 「型宣言ファイル」を作成し、TypeScriptにライブラリの型情報を伝えることで実現する方法です。 例えば、次のような JavaScript で記述されたライブラリ calc.js があるとします。 // calc.js exports.sub = function (a, b) { return a - b; } このライブラリを利用するには、次のような型宣言ファイルを作成して配置することで実現可能です。 ※今回の例では、tsファイルと同じ ディレクト リに配置するようにしています。 // calc.d.ts export function sub(a: number, b: number): number; これにより、 exec.ts は calc.d.ts を通して sub 関数を認識することができ、 コンパイル が通るようになります。 // exec.ts import { sub } from "./calc" ; console.log(sub(100, 1)); 型宣言ファイルの定義に基づき、 コンパイル 時に 型推論 や型チェックが行われるようになります。 もちろん、 IDE にも認識されるのでコード補完なども有効になります。 DefinitelyTyped(@types)で公開されている型定義ファイルを使用する方法 jQuery やChart.jsといったライブラリをTypeScriptに導入する際にも、この「型宣言ファイル」が必要になります。 しかし、規模の大きなライブラリに対して、先ほどの例のようにこれを自分で作成するのは骨が折れる作業です。 これに対し、DefinitelyTyped( http://definitelytyped.org/ )というコミュニティプロジェクトが存在しており、ここには JavaScript で記述されたライブラリの型宣言ファイルが集まっています。 ※あくまでコミュニティによる OSS なので、最新バージョンに追従していない、正しくないという場合も無くはないので注意が必要です。 DefinitelyTypedに対象のライブラリの型宣言ファイルが存在するかは、TypeSearch( https://microsoft.github.io/TypeSearch/ ) で検索することができます。 DefinitelyTypedに登録されている型宣言ファイルは、npmコマンドでプロジェクトに取り込むことができます。 npm install --save @types/jquery jQuery の型定義が導入された状態で、 jQuery の addClass メソッドを記述してみましょう。 $( function () { $( '#foo' ).addClass( 'bar' ); } ); TypeScriptが jQuery のメソッドを認識しているので、上記のコードは コンパイル エラーにはなりません。 では、ここで、 addClass の引数に数値を渡してみましょう。 $( function () { $( '#foo' ).addClass(1); } ); すると、下記のような コンパイル エラーが発生するようになります。 Argument of type '1' is not assignable to parameter of type 'string | string[] | ((this: HTMLElement, index: number, currentClassName: string) => string)'. 上記から、 jQuery が提供する関数の型定義が正しく認識されていることがわかります。 allowJSオプションを使用する方法 JavaScript で記述されたライブラリをTypeScriptに導入するには、 allowJS オプションを有効にする方法もあります。 ※通常は.ts拡張子のみ コンパイル され、.js拡張子のファイルは コンパイル の対象にはなりませんが、このオプションを有効にすることで、.jsファイルも コンパイル の対象にすることができます。 $ tsc --allowJS calc.js exec.ts ただし、素の状態の JavaScript は型の情報が与えられていないため、かなり緩い 型推論 結果になることに注意してください。 // calc.js exports.sub = function (a, b) { return a - b; } /* 推論されたシグネチャ sub(a: any, b: any): number */ しかしながら、もともと型の概念を持っていなかったレガシーなライブラリが、「ただ読み込ませただけ」で、多少なりとも型による安全性の能力を手に入れることができていることが注目すべきポイントです。 JSDocによって型定義をすることも可能 下記のようにJSDocを記述すると、詳細に型の定義を行うことができます。 /** * @param {number} a * @param {number} b * @return number */ exports.sub = function (a, b) { return a - b; } /* 推論されたシグネチャ sub(a: number, b: number): number */ ただ読み込ませるだけで 型推論 の恩恵を得ることができる、だけでも十分であることはすでに述べた通りですが、既存プロジェクトがきっちりとJSDocが記述している環境であれば、TypeScriptへの移行はなおさら恩恵を得やすいと言えるでしょう。 どの方法を採用すれば良いのか? ここまで紹介した、既存のJSライブラリをTypeScript環境に導入する方法は、それぞれにメリット・デメリットがあるので、プロジェクトの状況に応じて使い分けるのが良いと思います。 型宣言ファイルについては、ライブラリ自身が型宣言ファイルを公開している場合もあります。 まずはライブラリ公式、もしくはDefinitelyTyped上のものを探し、存在していない場合はallowJSオプションを使用して、徐々に型宣言ファイルを作る、もしくはライブラリ側をTypeScript仕様に変える、というアプローチが良いのではないでしょうか。 理由④ 段階的なTypeScript化を助ける コンパイル オプションがある TypeScriptには、 コンパイル 時のチェック内容を柔軟に変えることができるオプションが備わっています。 これらを使用することで、プロジェクトの状況に合わせたTypeScript導入を行うことができます。 noImplicitAny 暗黙的に 型推論 の結果 any 型となった場合に コンパイル エラーにするオプション OFFにすることで、暗黙的な any を許容できる 明示的に型指定を行わない場合、メソッドの引数などは any 型になる any 型は、その名前の通り「なんでもあり」の型なので、あまり良いものではなく、 any 型を避けるのが望ましい ただし、もともと JavaScript で記述されているコードについては、一旦このオプションをOFFにしておいて、 コンパイル エラーを目印に、徐々に型指定を増やしていくのが良いと思われる strictNullChecks null型、undefined型にのみ、 null 、 undefined の代入を許可する設定 null型: null のみを許容する特殊な型 undefined型: undefined のみを許容する特殊な型 T | null 型と null 型は別物と扱われ、T | null 型には null を代入できない これにより、意図しない undefined や、意図しない null を防ぐことができる noImplicitAny同様、最初はオプションをOFFにしておき、ONにした時に見つかる コンパイル エラーを徐々に修正すると良いと思われる ずさんなコードの匂いを検出してくれる便利な コンパイル オプション noUnusedLocals 未使用のローカル変数があるとエラーになる noUnusedParameters 未使用の引数があるとエラーになる noImplicitReturns 既出。メソッド内の全てのパスでreturn文が無い場合エラーになる noFallthroughCasesInSwitch Switch文内におけるbreak漏れがエラーになる まとめ:TypeScriptは、 JavaScript プロジェクトからうまく移行する環境が整っている TypeScriptは JavaScript のスーパーセットなので、既存のコードをそのまま使うことができる 型推論 によって、ただの JavaScript が型の力を手に入れることができる JavaScript で記述された既存資産を柔軟に組み入れる仕組みやそれを支えるコミュニティが存在する 柔軟な コンパイル オプションによって、レガシーなコードを段階的に厳密なコードに変えていくことができる おわりに TypeScriptの導入がいかに容易で、かつどれだけメリットがあるかをこの記事で紹介させて頂きました。 この記事をご覧になった方で、TypeScript導入に及び腰の方がいらっしゃいましたら、ぜひトライしてみて頂ければ幸いです! 参考文献 本記事執筆にあたり、私が学習に使用した書籍を下記に紹介します。 速習TypeScript まずTypeScriptを「完全に理解した」状態にするのにおすすめ 速習TypeScript: altJSのデファクトスタンダートを素早く学ぶ! 速習シリーズ 作者: 山田祥寛 WINGSプロジェクト Amazon 実践TypeScript 型やTypeScriptの便利な機能について詳しく書かれているので、「完全に理解した」状態から「色々わかってないことに気づくフェーズ」にちょうどよい 後半にReactやVue、Node.jsに導入する際の実践例の記載もあるので、名前の通り実践向き 実践TypeScript 作者: 吉井 健文 マイナビ出版 Amazon TypeScript実践プログラミング 上記2冊より広い分野の話が書かれており、知識の補完に便利でした TypeScript実践プログラミング (Programmer's SELECTION) 作者: スティーブ・フェントン 翔泳社 Amazon エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに こんにちは、 @rs_tukki です。 新型コロナウイルス の影響で大分ドタバタしていましたが、弊社ではようやく社員研修を終えた新卒社員の配属の話が本格化してきました。 新しい開発メンバーを受け入れるとき、まずやってもらうのは部署ごとの開発フローと、実際に開発するプロダクトの中身を学んでもらうことかと思います。 そこで今回は、その2点を一気に解決できる「実装過去問」について話していきたいと思います。 はじめに 実装過去問とは 実装過去問の実施手順 問題集から取り組む問題を決める プロジェクトのgitブランチから、問題を修正する前のブランチをcheckoutする 問題を解き、テスト項目書に沿ってテストを行う レビュー担当者がレビューを行う 過去問を行うメリット まとめ おまけ 実装過去問とは 実装過去問とは、私たちの部署で採用している学習プログラムの1つで、 簡単に言うと「そのプロダクトで実装された機能を学習のために後追いで実装してみる」というものです。 一般的に過去問というと、入学試験や資格試験で過去に出題された問題を集めたものですが、 この学習プログラムも「過去に開発された内容を」「いくつか抜粋して」「練習のために」やってみるという点から、過去問という名前がついています。 実装過去問の実施手順 では、実際に過去問を行う手順を紹介します。 問題集から取り組む問題を決める まずは、あらかじめドキュメント化されている過去問の中から、どの問題に取り組むかを決めます。 問題は現時点で27問用意されており、各問題に対して☆1~☆5までの難易度が振られています。 ☆1や☆2の問題は簡単なUIやUXバグの修正ですが、☆5は実装方法から悩まされるような難問。 この難易度は最初は問題作成者の主観によるものですが、過去問に取り組んだ人の感想次第で修正されたりします。 中には当初☆3だったものが☆5に引き上げられた事例も… 新規メンバーは☆3の問題から取り組んでもらい、合格(後述)なら☆4の問題へ、不合格なら同じ☆3または☆2の問題へ移ります。 そうして、☆4の問題に合格するのがひとまずの目標です。 プロジェクトのgitブランチから、問題を修正する前のブランチをcheckoutする 各問題のドキュメントには、実装内容・設計書のリンク・派生元のブランチ・制限時間などが記載されています。 私たちの部署が開発してるプロダクトは、gitでリリースバージョンごとにブランチを作成しているので、 その機能が実装される直前のリリースブランチをcheckoutすることで、修正後の実装を見ることなく後追いの実装が可能になっています。 問題を解き、テスト項目書に沿ってテストを行う あとは、設計書の通り、checkoutしたブランチに実装をしていくだけです。 このとき注意点として、以下の制限があります。要するに カンニング はNG ということです。 リリース済みの既存コードを参照することは禁止 既存コードをテスト環境で動かしてみて動作確認するのはOK 誰かにアド バイス を求めることはOKだが、実装方法を直接尋ねることは禁止 設計書などのドキュメントを参照することはOKだが、実際のPRを参照することは禁止 全て実装が終わったら、実装した人本人がテスト項目書を見ながらテストを実施します。 全ての項目をテストする必要はありませんが、当然この後レビューがありますので、そこでミスが出ないようテストはしっかり行う必要があります。 レビュー担当者がレビューを行う 実装とテストが終わったら、その内容をgitにpushしてPRを作成し、レビューを依頼します。 このときのレビュー担当者は、その過去問を解いたことがあるメンバーが実施することが多いです。 過去問ごとにレビューの観点もドキュメント化されており、PRの内容がその観点を満たせていれば晴れて合格となります。 過去問を行うメリット 過去問を行うメリットですが、 Wikipedia の 過去問題集 というページには以下のように記載されています。 ある試験を受けるにあたって過去問を解くことは、次の意味で利点がある。 試験の合否ラインと比較する形で、自分の力を測ることができる。 実際の試験問題を解く方法を直接的に身に付けることができる。 資格試験の場合は過去に出題された問題がそのまま出題されることがある。 入学試験の場合は全く同じ問題は出題されないものの、よく似た問題が出題される。(まれに出題傾向が一定でない学校もある) 早い時期に解いておくと、自分の不足している部分を把握し、その後の勉強の方針を立てることができる。 試験問題は比較的良い問題であることが多いため、他の問題を解く場合に比べて効率的に、自分の理解や知識を深めることができる。 多くの場合、問題の出題範囲が幅広くばらけているため、全体の理解度や到達度について、限られた時間で把握することができる。 入試や資格試験の過去問と違い、実装過去問では当然全てが当てはまるわけではありませんが、 実際の開発業務でやることになる問題に取り組むことで自分の力を測れる 本番のフローに則って取り組むので開発の練習になる 様々な傾向の問題があるため、実際の業務で必要となる知識を効率よく理解することができる といった点は共通しているかと思います。 まとめ 今回は、新規メンバーの受け入れに最適な「実装過去問」について解説しました。 メンバーを入れ替えながら長く開発と改修を続けていくプロジェクトでは必ず役に立つと思いますので、ぜひ取り入れてみてはいかがでしょうか。 おまけ 先日、弊社のオンラインイベントで発表する機会がありました。 SaaS の開発原則である「Twelve-Factor App」について語った内容で、資料もアップロードしていますのでぜひご覧になってみてください。 rakus.connpass.com speakerdeck.com
アバター
はじめに 技術広報のitoken1013です。こんにちは。 定期開催させていただいています ラク スMeetup、2月に大阪で盛況でした 『 SaaS を支える開発原則/DDD、 心理的 安全性、Twelve-Factor』 をテーマに、登壇者と発表内容を新たに刷新して6/24(水)に開催しました。 今回で2回目のオンライン開催となりましたが、60名の方にご参加いただき(満員!)、 Twitter や Zoom上にはコメントが溢れる盛況のイベントとなりました。 今回は当日の発表をご紹介させていただきます! rakus.connpass.com イベントテーマ概要 ソフトウェア開発には様々な原則・法則が存在します。 これらの開発原則が ラク スの SaaS 開発でどのように活かされているか、開発チームで主要な役割を担う若手・中堅・ベテランの3名のエンジニアから紹介させていただきました。 SaaS 開発ならではの原則、拡大する開発規模を乗り越えるための原則、新たなサービス開発で ドメイン イベントを活用するための取り組みなど、幅広い内容となりました。 発表の紹介 Twelve-Factor Appで読み解く、モダンなアプリの理想とレガシーなアプリの現実 多くの方々に ラク スを知っていただくきっかけとなりました 楽楽精算 。 この楽楽精算の開発チームで活躍する矢須より、 Twelve-Factor App に存在する4つの原則を紹介させていただきました。 2009年にリリースされた楽楽精算は Twelve-Factor App よりも長い歴史を持つサービスですが、Twelve-Factor Appに存在する原則との共通点と現状のギャップに触れつつ、理想的なWebアプリケーションの姿を解説しています。 speakerdeck.com 開発グループが開発チームになるまでの歩み 同じく楽楽精算においてPMを務める紀井が紹介するのは、以下の3つの原則です。 2年間で急速に規模が拡大した楽楽精算の開発チームを軌道に乗せるために、紀井が挑戦した取り組みを紹介させていただきました。 OODAループ 心理的安全性 銀の弾などない 発表では大きく3ステージに渡る課題が取り上げられましたが、どのステージでの挑戦も参加者の皆様に共感いただける登壇となりました。 speakerdeck.com 紀井の登壇については、別途logmiでも紹介しております。 ぜひ当日の発表内容をご覧いただければと思います。 logmi.jp 結果整合性ができない開発者の ドメイン イベント活用例 ラク スの数々のサービスを成功に導いてきた峰村が紹介しましたのは、 DDD ( ドメイン イベント、集約)と 結果整合性 です。 ドメイン イベントとは、 ドメイン 内で発生する「○○したら××になる」といった出来事を表現する ドメイン モデルです。 今回は峰村がリードエンジニアとして取り組む新規サービスの開発で ドメイン イベントを活用した知見を、実例を交えて紹介させていただきました。 ドメイン イベントを導入することで得られるメリットの他、導入のための困難、そしてチームに ドメイン イベントを定着させるための取り組みを紹介させていただいています。 speakerdeck.com おわりに 多くの方に数々の共感をいただけました ラク スMeetup、ご参加いただきました皆様、ありがとうございました。 ラク スでは7月・8月もMeetupやLT・勉強会を開催予定です。 今後もエンジニアの皆様へ有益な情報を発信する場にしていければと思いますので、 どうぞ引き続きよろしくお願いいたします! rakus.connpass.com rakus.connpass.com
アバター
はじめに こんにちは、MasaKuです。 昨今、 コロナウイルス の影響により、オフラインで開催される勉強会が自粛の流れになっており、逆にオンライン開催される勉強会が増えてきていると思います。 そこで先日、以下のイベントに参加しましたので、参加した感想について述べていきたいと思います。 nrs-seminar.connpass.com YouTube Live のアーカイブはこちら はじめに 参加したイベント 参加動機 感想 コード理解はまず全容把握から 図解はやはり強力 コードのわかりやすさも重要だがディレクトリ構造はもっと重要 PHPのマジックメソッドはコードリーディングにおいてかなり曲者になる 参加者のコメントもインプットになる おわりに 参加したイベント ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本 の著者 成瀬允宣さん主催のオンライン勉強会ということで、 他人がどんな風にコードを読んでいくか を知ることを目的とした勉強会です。 今回は、 PHP フレームワーク の Laravel の内部を見ていこうという趣旨のコードリーディングでした。 なお、今回の フレームワーク 読解の目標としては 「自作 フレームワーク を作るために参考にする」 という体で進められていました。 www.shoeisha.co.jp 参加動機 そもそも、なぜ私がこの勉強会に参加しようと思ったのかをご説明しようと思います。 ほかの人がどのようにしてコードを読んでいるのか単純に興味がある 人気の フレームワーク の中身を読んでみたいけど、一人で読んでいると行き詰ってしまう Eloquent (Laravel の標準ORM)のソースを軽く読んだことはあるが、 フレームワーク の全容を意識して読んだことはなかった フレームワーク を読み進める上でのテクニックを吸収したい 定石パターンなどがあれば今後ソースの読み書きをする上でも参考になりそう ちなみに、主催の成瀬さんについてですが、2019年のPHPerKaigiの際にアンカンファレンスにて発表されていた内容が非常に興味深かったことを覚えています。 そのことがきっかけでまたお話を伺いたいなと思ったことも動機の一つです。 (2019年のPHPerKaigi のイベントレポートは以下) tech-blog.rakus.co.jp 感想 コード理解はまず全容把握から コードを追いかけるスピードはさることながら、コードを読むテクニックについても勉強させていただきました。 例えば、 フレームワーク の様な全容の大きいプログラムは、一度にすべてを丁寧に読み込んでいこうとするのではなく、 まずは全体を眺める ことが大事です。 「この変数にはどういう値が入っていて、どういうメソッドに渡されて、ここでオブジェクトに格納されているプロパティを取得して・・・」などということをすべて頭に入れながら読み進めていくと、間違いなくオーバーフローを起こして思考が停止してしまいます。 なので、まずはざっくりと全体の流れを把握して、それから、気になるところを読み返していく、という読み方が良いそうです。 この点に関しては、私も業務で開発しているプログラムを読み進めていく際に気を付けているポイントだったので、自分の進め方が大きく間違っていないことに安心しました。 いくつもの業務ロジックが関連するような処理を読み込んでいく際は、最初から細かに処理を追いかけるのではなく、ざっと処理の流れを把握してから細かい仕様を確認するようにしています。 全容がわかっていれば各処理の細かい仕様がなぜそうなっているのかも紐づけて考えやすいと思います。 図解はやはり強力 また、 フレームワーク の全容理解を進める上では、 図解するのが一番良い と思いました。 Laravelにはリク エス ト情報をコントローラに渡す前やViewに返す前に Middleware という処理を追加できます。 この仕様については把握していたのですが、何となく把握していたことを図解してもらえるだけで、Middleware が フレームワーク のどのような位置でどのような処理をしてるのかが、より詳しく理解できたような気がしました。 自分の理解を振り返るためにも、図解しておくことは強力な理解促進につながると思います。 コードのわかりやすさも重要だが ディレクト リ構造はもっと重要 フレームワーク ではアプリケーション開発で必要になる様々な処理を実現するために、各機能を適切な粒度でグルーピングして ディレクト リを切って管理しています。 配置するプログラムがきちんとグルーピングされた ディレクト リに管理されていると、とある処理を追いかけていた際にたまたま見つけた特定処理に関連するパーツがどこで管理されているかも分かりやすくなります。 もちろん、コード内からジャンプして、 参照元 へどんどんたどっていくこともできますが、関連する処理がどこにあるのかがわかっていると、リファレンスを読まなくても フレームワーク が行っているその他の処理を知るきっかけにもなります。 逆に、 ディレクト リ構成が支離滅裂でどこに何が配置されているのかがわかりにくい状態になっていると処理を追いかける際の可読性を下げてしまうばかりでなく、管理も煩雑になってしまって保守性も低下してしまうでしょう。 PHP のマジックメソッドはコードリーディングにおいてかなり曲者になる PHP には マジックメソッド という特殊なメソッドがあります。 中でも __call() や __callStatic() はコードリーディングを難解にさせるマジックメソッドの一つです。 例えば __callStatic() は、オブジェクト内の静的メソッドを呼び出そうとする際に、アクセス 不能 な場合に実行されるメソッドです。 <?php // 以下サンプルコード class MagicMethodTest { public static function __callStatic ( $ name , $ arguments ) { echo "あなたが呼び出したメソッドは ' $ name ' " . implode ( ', ' , $ arguments ) . " \n " ; } } MagicMethodTest :: runMethod ( '引数1' , '引数2' ) ; // 実行結果 // あたなが呼び出したメソッドは 'runMethod' 引数1, 引数2 フレームワーク ではこうしたメソッドが頻繁に登場するようなのですが、普段のアプリケーション開発時はあまり目にする機会が少ないだけに、一瞬思考が止まっていしまいます。 しかし、主催者の方や参加者の方々と、まるで ペアプロ しているかのように読み進めていくことで、マジックメソッドの意味を冷静に考えながら読み進めていくことができます。 参加者のコメントもインプットになる 今回のイベントは YouTube Live で公開されていたため、他の参加者の方のコメントを読むこともできました。 コメントの中には自分と同じようなことを感じながらコードを読み進めている方がいらっしゃったり、別視点の深い内容のことをコメントされている方がいて、コードリーディングのモチベーションを高めながら参加することができました。 (参加者の中にはLaravelに非常にお詳しい方も参加されていたようで、鋭いコメントをされる方もいらっしゃいました。) 参加者間のコミュニケーションが活発であったことも非常に印象的で、終始途切れることなくコメントが流れていました。 おわりに 今回、オンラインのコードリーディングに参加させていただき、他の人がどのようにコードを読み進めているのかを拝見することができました。 フレームワーク のような巨大なコードを読む上では、まずはざっと全容を把握してから、細かいポイントを振り返って理解しながら読み進めていくべきだと思いました。 振り返っていくときのポイントとして、とある処理で利用されるクラスには他にどのようなメソッドがあるのか、というところまで視野を広げることで、 フレームワーク が実現できる他の処理を知るきっかけにもなることを理解しました。 これらをスマートに進めるためにも、 ディレクト リ構成をしっかりとルール付けして、正しく管理しておくことが重要です。 これらのノウハウは業務で開発しているプログラムを読み込む際にも使えるテクニックだと思いました。 例えば、ドツボにはまってしまって、同じところをグルグル読み返してしまう、なんてことが起きないようにするための方法として、いろいろと参考になることを得られたかなと思いました。 次回の開催も楽しみです! なお、弊社 ラク スでもオンラインで PHP の勉強会を開催しています。 LaravelについてもLTなどで過去に何度か話題になっていますので、ご参加いただけると幸いです。 rakus.connpass.com
アバター
はじめに 技術広報のitoken1013です。こんにちは。 今回は Scrum Fest Osaka 2020 に登壇しました新卒エンジニアの 樋口(@YokoHiguchi1) からの登壇レポートを紹介させていただきます! confengine.com ふりかえりが重要ではない!?~ふりかえりの活用方法について~ from ssusera3f4f9 www.slideshare.net はじめに Scrum Fest Osaka 2020について 樋口のイベント後記 今回のイベントに登壇しようと考えたきっかけ 発表テーマ「ふりかえりが重要ではない!?ふりかえりの活用方法について」を選んだ理由 初めてのオンライン登壇 今回の登壇を通じた学び・発見 終わりに Scrum Fest Osaka 2020について スクラム の初心者からエキスパート、ユーザー企業から開発企業、立場の異なる様々な人々が集まる学びの場 として毎年開催されているScrum Fest、今年は初のオンライン開催となりました。 当日はDiscord上で運営が行われ、登壇者はZoomから発表を行う形式でした。 www.scrumosaka.org イベント詳細はこちらで紹介していますので、参考にしていただければと思います。 ちなみに ラク スもスポンサーとして、イベント協賛をさせていただいておりました。 tech-blog.rakus.co.jp 樋口のイベント後記 今回のイベントに登壇しようと考えたきっかけ 今回Scrum Fest に登壇しようとした"きっかけ"は 自分で得たものをアウトプットすることで、悩んでいる人でも、何かを感じてほしい と思ったからです。 以前の私は スクラム に関わらず、「ふりかえり」と呼べるもの全てに対して何故必要なのか、そもそも「ふりかえり」が何なのか分からない状態でした。 でも、分からないと思ったものは自分の中に落とし込むことが大事と考え、様々な人と会話してアウトプット・インプットを繰り返し、自分にとってふりかえりとは何かを考えてきました。 その際に得たものはきっと自分だけのものではないし、私のように悩んでいる人がいるのなら、私が発信することで何かを感じ取ってもらえるのではないか。 そう思い、登壇を決意しました。 発表テーマ「ふりかえりが重要ではない!?ふりかえりの活用方法について」を選んだ理由 「ふりかえりが重要ではない」という文字が、今回の登壇に至るきっかけでした。 私は合宿イベント LED-Camp の運営に携わっています。 ここでは参加者にふりかえりを重点的に教えたのですが、LED-Camp が終わった後の参加者アンケートの中に「ふりかえりは重要ではないと考えている」と回答がありました。 その回答が私の中に残り、「何故、ふりかえりは重要ではないのだろう?」と考えていたら、ふりかえりは何故必要か、ふりかえりはそもそも何であるか、が私自身も全く分からなくなってしまいました。 この「ふりかえりが重要ではないと考えている」という言葉が ふりかえりとは何かを改めて考える機会となり、このタイトルを選ぼうと決めました。 初めてのオンライン登壇 初めてのオンライン登壇は、ひとことで言うと”楽しかった!”です。 オフラインでは相手の顔を見ることができるため、その場の空気感によって話すスピード等を調整することができますが、オンラインだと1人で喋っている感覚があり、本当に相手に伝わっているのか?という疑問がずっと付きまとい、初めての感覚で最初は不安と緊張しましたが、 とても新鮮でいい経験ができました。 また発表中に参加者の方々からの意見がチャットで見られ、フィードバックをその場で受けるという感じはすごく面白く、その際は オフラインよりも参加者と距離を近くに感じ取れた のがとても良かったです。 今回の登壇を通じた学び・発見 たくさんの学びがあった取り組みでした。 まず登壇が決まってから、私にとってのふりかえりは何かをより一層考えるきっかけにもなり、資料を作成しながらもふりかえりについて考えることもできて、すっごく楽しかったです! 登壇後は参加者の人達にJamboardの付箋でアウトプットしていただいたのですが、付箋にはびっしり私の話から学んだこと、疑問に思ったことが書かれていました。 それを見て、発表して本当によかったなって。 アウトプットすることの大切さを改めて実感できたイベントでした! 終わりに 入社間もないタイミングでScrum Festへ挑戦した樋口の取り組み、いかがでしたでしょうか? 今回樋口が発表しました内容については、7/13(月)に開催される以下のイベントで再演される予定となっています。 ご興味のある方は、是非イベントへご参加いただけますと幸いです。 retrospective.connpass.com 当社はこれからもイベント登壇やブログ発信など、エンジニアのアウトプット活動を活発に行っていきます!
アバター
id:radiocat です。6/26、27に開催されたScrum Fest Osaka 2020に参加し、登壇させて頂きました。イベントをレポートします。 Scrum Fest Osaka 2020とは? どんなイベント? 会場はDiscord セションはZoom 数々の企業・団体スポンサーが支援 基調講演 ちょっとした「うっ」は成長のチャンス 登壇レポート スクラムちゃうがなと言われてもやってみぃひん? ふりかえりが重要ではない!?ふりかえりの活用方法について 非秩序を乗りこなすアジャイルなイベントでした Scrum Fest Osaka 2020とは? www.scrumosaka.org 公式サイトには次のように書かれています。 Scrum Fest Osakaは スクラム の初心者からエキスパート、ユーザー企業から開発企業、立場の異なる様々な人々が集まる学びの場です。 昨年が初開催で、今回が2回目となるイベントです。前回は2トラックで20以上のセッションが行われ、関西としては スクラム に限らずエンジニア向けイベントとして最大級のイベントです。全国から様々な境遇や立場の人が集まって、それぞれの取り組みや知見を共有しあう、参加者全員の学びの場です。 ちなみに、昨年と今回オンライン開催に変更される前まで会場となる予定だった 関西大学 梅田キャンパス KANDAI MeRISE は弊社の大阪オフィスのすぐ隣です。 どんなイベント? 登壇者は昨年から公募され、既に決まっていましたが、コロナの影響でオンライン開催に変更となり、全国19コミュニ ティー を集めて各トラック並行で開催されるという異例の内容・規模となりました。19トラックともなると、ご覧のとおり一覧で見ることができない規模です。 19トラックのイベント一覧 オンライン開催ということで、参加者は Discord と Zoom の利用が必須となりました。 会場はDiscord 参加の申込みを行って運営側へDiscordのアカウントを連絡するとイベント専用のDiscordサーバへ招待されます。Discordにはイベントのお知らせや、各種連絡、当日のオープニングや基調講演で使われるメインチャンネル、各コミュニ ティー のチャンネルに加え、雑談、トイレ?、2次会など、参加者が思い思いに参加できる無数のチャンネルがあります。 Discordの画面 イベントの申し込みが終わるとイベント開催の数日前からDiscordに招待され、当日だけでなく準備中の状況なども確認できるようになっていました。もちろん、開催前から参加者同士で交流することができます。そして、開催後の現在も継続して交流可能です。開催当日を軸としつつも、その前後の時間も使って参加者全員でイベントを作り上げていく形が、イベントの新しいスタイルとして、オンラインイベントの可能性を感じることができます。 セションはZoom 開催当日は、セッション開催の時間になるとDiscordのチャンネルにZoomのURLが流れてきます。そこからZoom上で登壇者の発表を聞くという流れです。 セッションの様子 登壇者から聴講者への一方向のセッションだけでなく、オンラインの視聴者を巻き込んだりチャットツールを使ってディスカッションするなど、オンラインでの新たな試みを行っているセッションもありました。 数々の企業・団体スポンサーが支援 アジャイル を実践中の様々な企業・団体がスポンサーとしてイベントを支援しています。弊社もシルバースポンサーとして参加させて頂きました。 スポンサーの紹介 オープニングイベントでしっかり紹介して頂いていました。参加したイベントのスポンサーに自社が名を連ねているのはいつ見ても嬉しいものです。 基調講演 基調講演は アジャイル コーチであり、『SCRUM BOOT CAMP THE BOOK』の共著者としてもおなじみの株式会社アト ラク タの永瀬さんによる『今あえての スクラム 』でした。 真ん中が空いた、縦書きの、変わったスライドになっているのは理由があります。なんと、画面共有でスライドを投影するのではなく、ご本人が真ん中に映りながらバーチャル背景にスライドを投影するというスタイルで発表されたのです! その様子は参加者だけのお楽しみなのでご紹介できなくて残念ですが、背景に使われたスライドを見ながらなんとなく想像していただければと思います。 ちょっとした「うっ」は成長のチャンス 今回の登壇にあたり、イベントがオンライン開催に変更されたことで最初は「うっ」と思われたとのことです。これは私も登壇させて頂いたのでわかります。オンラインという形で前提が変わって、どのようなセッションを行おうかと戸惑いました。しかし、このような状況にチャレンジすることは成長のチャンスでもあるということです。 スクラム は非秩序な状況を乗りこなすことに適した フレームワーク です。 染み付いた行動の癖で、予見できる範囲でスプリントを回していないか? ふりかえりでプロブレムに対するトライばかりしていないか? 行動する前に既存の価値観で判断してしまっていないか? 変化の時代だからこそチャレンジしてみよう。やってみて、失敗して、学習しよう。そういう内容のセッションでした。そして、前述のように背景にスライドを投影するという発表にチャレンジすることでもそれを伝えていただいた内容だったと思います。この発表を聞くだけでもイベントに参加する価値のある内容でした。 登壇レポート 2日目は19トラックに分かれて各セッションが行われました。セッションだけでなく、各コミュニ ティー のDiscordチャンネルでは様々な情報交換がされていてとても賑わっていました。 ちなみに、セッションは録画され(登壇者が承諾した場合)、当日の参加者には約1ヶ月間公開されているので、19トラックの発表を後日ゆっくり見ることができます。アフターイベントとして、録画試聴会なども開催されています。これもオンラインイベントの新たなスタイルです。 最後に、弊社から登壇させて頂いた内容についてレポートさせてください。 スクラム ちゃうがなと言われてもやってみぃひん? スクラム は理解は容易ですが、習得は困難だと言われています。実際にやろうとすると、思ったとおりできないと感じることが多々あります。特に我々のような中小企業の開発の現場では制約も多く、長年やってきた従来型の 開発プロセス を全て刷新して充分環境を整えてから スクラム を導入できるケースは稀です(もちろん中小企業ではなくても様々な制約はあると思いますが、今回の発表は我々の境遇に視点をあてた内容になっています)。同じ境遇の方々に我々の取り組みが参考になればとの思いで発表させていただきました。 スクラム ちゃうがな問題 少しずつ カイゼン する カイゼン 文化をつくるには、まず スクラム のベースとも言える PDCA を回す状態をつくることです。課題が山積していていることは認識していても、計画を立てて、実行後に振り返る流れが習慣化していなければ カイゼン は進みません。 それができたらチームで開発している状態をつくることに着手します。従来型の 開発プロセス でよくある課題が、縦割りで担当者に業務が アサイ ンされ、隣の人が何をやっているかもわからない状態で仕事をしている状態です。スケジュールマネジメントをしっかり行い、チームとして成果を出せる状態をつくることで、個の活動からチームの活動になり、 カイゼン をチームの文化にする土台ができます。 少しずつ カイゼン する(私たちの場合) ありたい姿を探る カイゼン は進みましたが、いつ スクラム になるかのゴールが見えませんでした。そこでチームとして「中小企業のエンジニアチームを楽にするモデルをつくる」というビジョンを設定し、それに到達するまでのロードマップをつくりました。ロードマップの段階を踏んでいくことで スクラム に近づき、チームのあるべき姿に到達させるのです。 チームのロードマップ 原則を土台にする チームのロードマップをつくって進めていたものの、自分たちの視点に偏っていて顧客視点が持てていないことに気づきました。自分たちの カイゼン を進めてチームをアップデートしても顧客に価値を届けられなければ意味がありません。 アジャイル の原則に立ち返れば当たり前のことができていないと気づいたのです。 原則にむきなおる 経験から学ぶ これらの取り組みから、 カイゼン とありたい姿、原則の土台を3つの柱として経験しながら学ぶことで スクラム に近づくと考えました。これは経験学習というモデルをベースにしています。 経験から学ぶチームで スクラム に近づく 「 スクラム ちゃうがな」から始まる 経験から学ぶモデルの中心には「意欲と信頼」があります。私たちは「 スクラム ちゃうがな」と感じて悩んだとき、何かを変えたいという意欲を持っています。つまり「 スクラム ちゃうがな」と感じたことは経験から学んで スクラム に近づくスタート地点なのです。 スクラム ちゃうがなから始まる オンラインならではのチャレンジ スライドではわかりませんが、イベント当日は途中でネコが合いの手やツッコミを入れる部分を、あらかじめ録音しておいた合成音声を流すことで自問自答する雰囲気を演出してみました。これも私なりのオンラインならではのチャレンジです。 ネコによるツッコミ ふりかえりが重要ではない!?ふりかえりの活用方法について 弊社からもう1名がふりかえりについて発表させて頂きました。発表は参加者と一緒にふりかえりについて考えるスタイルになっており、Discordのチャンネルで様々な意見が共有されていました。これもまたオンラインならではのスタイルです。 retrospective.connpass.com この発表は、再演イベントが企画されていますので内容の紹介は割愛させて頂きます。興味のあるかたはぜひイベントにご参加ください。 非秩序を乗りこなす アジャイル なイベントでした イベント全体を通して、参加者全員で変化に向き合って適応しようと取り組み、みんなでイベントの新しい形をつくりあげていく空気に溢れていました。イベント自体が アジャイル な体験だったと言えます。 オンラインでのこのようなイベントは世界レベルでみてもまだ事例が少ないのではないかと思います。そんな中で最終的に500人以上がDiscordに集まる大盛況のイベントとなったようです。そんなイベントを作り上げた実行委員のみなさんのコメントや裏話が Youtube で公開されていますので合わせてご覧ください。 スクラムフェス大阪 開催中に実行委員が感慨を語る Discordのチャンネルでは現在も様々な情報交換が行われており、その刺激を受けて参加者がそれぞれの現場で次のScrum Festに向けた取り組みをスタートさせています。私たちもまた次回のイベントで採択されるようにチャレンジを続けたいと思っています。 弊社でも様々なオンラインイベントが企画されており、取り組み内容を共有しています。7月末には楽楽明細開発チームの スクラム 事例の発表も予定されています。よろしければぜひご参加ください。 rakus.connpass.com
アバター
はじめに  こんにちは、tuq376sです。今回は最近触り始めたE2Eテストの フレームワーク 、 TestCafe での初歩的な画面操作についてまとめたいと思います。  というのも、TestCafeはTypeScriptを用いて記述するのですが。 そもそも自分がTypeScriptも初めてかつ、 JavaScript も自信を持ってすらすら書ける! とは言えないレベルなので、 まずは「こう書けばとりあえず動作する」から覚えていこうという次第です。   はじめに アクセス先とテストケース 要素を取得 クリック テキストフィールドへの入力 ファイルアップロード おわりに アクセス先とテストケース  まずはアクセス先の指定とテストケースの書き方から。 fixture("サンプル").page("https://hogehoge/"); test("テストケース1" , async (t) => { //テスト内容 }); test("テストケース2" , async (t) => { //テスト内容 });   fixture は複数のテストケースをまとめるカテゴリの役割を果たします。 そして続く .page は始めにアクセスするURLを指定しています。 .beforeEach や .afterEach で事前・事後処理を記述することもできるようです。  実際のテストケースは test で宣言します。実行結果ではこのテストケースごとに成功と失敗が返される形になります。 要素を取得  ここからの内容は、 test の中で書いていきます。 まずは画面を操作していくために、ページ上の要素を変数に取得していきます。 const button = Selector('input').withAttribute("value","ボタン").nth(0);   Selector は指定した要素を取得します。ここにはタグ名だけではなく、class や id も指定することができます。   WithAttribute は、属性の名前と値で要素を絞り込みます。リンクやボタンなどであれば、だいたいこれで一意に絞れるのではないかと思います。  それでも一意にならない時(自分は同じ属性を持った要素が並ぶ一覧画面でつまづきました)、便利なのが nth です。これは条件に一致した要素のうち、上から何番目の要素を取得するかを指定できます。これが素敵なのは、HTML上で何番目になるかが同じであれば、もし属性の値が変更されたとしてもテストコードを書き直さずに済むところです。 クリック  さて、ようやく画面自体の操作です。 await t.click('#nextLink');  クリック操作は click で行います。要素の指定は上記のようにidを直接書いたり、先ほどのSelectorで取得したものを渡したりします。  ここで指定したものが複数に該当してしまっていると、エラーになってしまいますので注意です。(例えば一つしかボタンがないと思っていたら、実はhidden状態の同じボタンがもう一つ存在してたりとか……ありました) テキストフィールドへの入力  続いて、テキストフィールドへの入力操作についてです。 const textArea = Selector('input').withAttribute("name","入力場所"); await t.typeText(textArea, "入力したい値");   typeText を用います。Selectorで取得したテキストエリア要素と、入力する値を指定します。  どうやら指定した要素をクリックしてフォーカスしてから入力を行っているようで、クリックした段階で正しくフォーカスできなかった場合、書き込みは行われないようです。 ファイルアップロード  最後に、ファイルをアップロードする操作です。 await t.setFilesToUpload(linkInputFile, "ファイルパス");   setFilesToUpload を使って、ファイルを設定する要素とファイルパスを記述します。ファイルパスは [ 'ファイル1', 'ファイル2', 'ファイル3' ] といったように複数を指定することも可能です。 おわりに  というわけで、これらがわかれば最低限テストケースを作って画面操作してみる、ということはできるはずです。  テストと言いつつ アサーション には触れられていませんが、そちらはまたもう少し理解できたら、いずれ記事にしてみたいなと思います。
アバター
はじめに 技術広報のitoken1013です。こんにちは。 先日6/17(水) 、当社主催のMeetup 『SaaSを支える品質担保術/レガシーコード、アーキテクチャ、EOL』 を開催いたしました。 今や ラク スの恒例行事となりましたMeetupですが、今回は初のオンライン開催となり、 40名超のお客様にご参加いただけました。 今回は当日の発表内容について、簡単にご紹介をさせていただければと思います。 イベントテーマ概要 ラク スでは数多くの to B 向け SaaS の開発を行っています。 サービスにはこれから新たにリリース予定のものもあれば、 クラウド サービスの黎明期から存在する歴史の深いサービスまで、多くのお客様のご支持によって幅広く展開させていただいています。 今回はそんなサービスの中から代表し、以下の3つのサービスがどのような品質担保を行っているかをエンジニアから紹介させていただきました。 メールディーラー チャットディーラー 楽楽労務 発表の紹介 社内最長老のシステムに PHPUnit で立ち向かう方法 リリースから18年ほど稼働しているメールディーラーを担当中の柳瀬から、 EOLを迎えた PHP をバージョンアップした際の経験を紹介させていただきました。 当時 PHP 歴3カ月だった柳瀬が直面した突然の全機能テストを乗り越えた事例について、語られています。 speakerdeck.com 正攻法はあるのか !? 泥臭く戦った Node.js バージョンアップ一部始終 次は同じくEOLを迎えたNode.jsを 6系 → 10系にバージョンアップすることとなったチャットディーラーでの濃密な戦いを、西原が発表させていただきました。 調査・テスト(× 3回)・リリース後のトラブル対応、そこから得た学びが示されています。 タイトルの通り「泥臭いバージョンアップ」にピンと来る方には、共感をいただけるはずです。 Rakus MeetUp 正攻法はあるのか!?泥臭く戦ったNode.jsバージョンアップ一部始終 from masatonishihara www.slideshare.net ArchUnit で Java / Kotlin アプリケーションの アーキテクチャ を CI する 最後は当社のリードエンジニアである川並です。 開発プロセス の中でコードレビューは取り入れられていても、 アーキテクチャ 観点でのレビューや全員が同じ設計レベルで開発を行うのは、難易度が高いことかと思います。 川並が担当する楽楽 労務 ではそんな問題に対し、 ArchUnit を使った アーキテクチャ 観点での品質担保に取り組んでいます。 speakerdeck.com 終わりに 初のオンライン開催となりましたMeetupですが、ご参加いただきました皆様のおかげで、 高い満足度をいただくことができました。 Meetupは来月・再来月も開催を予定しておりますので、ご興味のある方はお申込みいただけますと幸いです。 詳しいイベント情報については、Connpassをご確認ください。 ありがとうございました! rakus.connpass.com
アバター
今後の新サービスの立ち上げに向けて技術検証を行う技術推進課に所属している鈴木( @moomooya )です。今年度から新設の部署に(課長とふたりぼっちで)異動となりました。 最近マイクロサービスと関連して オブジェクト指向 について取り組んでいるので、 デメテル の法則に関する記事を書いてみようと思います。タイトルは1度くらい煽りタイトルをつけてみたかったので出来心です。 デメテル の法則って? デメテル の法則(LoD: Law of Demeter)は ノースイースタン大学で作成されたガイドライン が原典となり、 達人プログラマー でも(あまり詳しくは書かれていませんが)紹介されています。 ちなみにみんな大好き Wikipedia ではこのように説明されています。 簡潔に言うと「直接の友達とだけ話すこと」と要約できる。基本的な考え方は、任意のオブジェクトが自分以外(サブ コンポーネント 含む)の構造やプロパティに対して持っている仮定を最小限にすべきであるという点にある。 ―― Wikipedia - デメテルの法則 より抜粋 なんとなくわかりますが、実装レベルでどうすればいいのか理解するにはもう少し説明がほしいところです。具体的な対応方法としては 「メンバを直接参照せずにアクセッサ(getter/setter)経由で参照すればいい」 とか 「オブジェクトのメンバを直接参照しない」 「オブジェクトのメンバのメンバを直接参照しない」 とよく言われています。 Java のサンプルコードで見てみましょう。お題は乗り物です。 // Demeter1.java class Engine { // エンジンクラス String status; } class Vehicle { // 乗り物クラス Engine engine; Vehicle() { engine = new Engine(); } } public class Demeter { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); vehicle.engine.status = "発進" ; // ×××オブジェクトの内部を直接操作しない××× System.out.println(vehicle.engine.status); } } これは vehicle.engine.status で直接参照しているため デメテル の法則に違反している例です。 「メンバを直接参照せずにアクセッサ(getter/setter)経由で参照すればいい」んでしょ? // Demeter2.java class Engine { protected String status; // ★getter/setter作った String getStatus() { return status; } void setStatus(String status) { this .status = status; } } class Vehicle { protected Engine engine; Vehicle() { engine = new Engine(); } // ★getter作った Engine getEngine() { return engine; } } public class Demeter { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); vehicle.getEngine().setStatus( "発進" ); // ★getter/setter使って更新 System.out.println(vehicle.getEngine().getStatus()); } } ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ お可愛いこと…… メンバ変数名にそのままget/setをつけたメソッドを用意したところで本質的には何も変わっていません。 ただの素直か! メンバを protected (または private でも)にしているのでリードオンリー/ライトオンリーなどの制御は可能ですが 疎結合 にはなりません。 このへんは IDE の功罪 というかgetter/setterの自動生成によって洗脳されてしまっている人も結構いる気がします。 さらに言えば vehicle.getEngine().setStatus("発進"); の部分がオブジェクトの内部構造(Vehicle内のEngineの構造)を意識してしまっています。 「オブジェクトのメンバのメンバを直接参照しない」ようにすればいいの? // Demeter3.java class Engine { protected String status; String getStatus() { return status; } void setStatus(String status) { this .status = status; } } class Vehicle { protected Engine engine; Vehicle() { engine = new Engine(); } Engine getEngine() { return engine; } // ★engine用のgetter/setter作った String getEngineStatus() { return engine.getStatus(); } void setEngineStatus(String status) { engine.setStatus(status); } } public class Demeter { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); vehicle.setEngineStatus( "発進" ); // ★Engineのメソッドを利用 System.out.println(vehicle.getEngineStatus()); } } ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ` ニ|ュ _二,    ''''7  _二,  | ヽヽ_」_」_ _|_ :/ ヘ 入呈   _ノ 、   ̄( ̄  _ノ  |__丿 } .-' ノ よ {_,, .|  ` ̄         `    ,,...-=ミミミミミヽ、   /ミ////////////ハ  ./ミ;;;;;:////////////}  {:::ミ  `ヾ/////////リ  .{;;;;:   : :.////////ノ  r、ミ_,,,_,,;;;::://////ソ‐,  {iハ〔i77777ハ77777!〕:/  ヽ.Yゝ___ノ ::ゝ_;;;;//ノ     ',  ::i 、,//////{        ,、     ',  ,ィ彡//////>、_____//〉    ノヽ´ ̄;///////////////////ァ-=ュ ─''"{: : :.\_;;;///////////////////////Y 、: : : |: : : :.Y /\ //: : / ..:::".:://///////ハ : ヘ: :.|: : : : :{'   `/: :/...:....::////////////リ 、: :ヽ:{: : : : :.}   //: :\:://////////////ハ : \: :{: : : : :.}  /:::: : : : :\/////////////ハ : : : ヽヘ: : : :.!/: :::::::::..: : : : :.ヽ////////////} : : : : : \,ィ'": : :.::::::::::::::.: : : /////////////ハ : : : :>'i: :::.:.:.: :::::::::::::::::: :///////////////// : ://:./:∪:::::::: ::::::::::::::::://///////////////// :(;': /::: : ::::::::: ::::::::::::://///////////∠////// Y: (:::: : : :::::: ::::::://///////////'''`ミミ:ヽ://// .\: : : : : :::: :::////////////ノ: : :::::.: ::::://///   /ヽ; : : : /////////-'''":{::::.: : : :::::::::::///// . /: r.、二、:{: : : >':::::: : : ::: : :ゝ: ::.:.::::::::///// /: : ゝ-、 `ヽ-{: : : : : : : :::::.:.:.:.:::::://///// {: : :._/    ∨: : : ::::: : : : :.//////// Vehicle と Engine の関連を Vehicle 内に移譲しているのでだいぶ良くなってはいます。これだと Engine (原動機)が Human (人力)に変わったとしても Vehicle の修正だけで済み、mainメソッドは内部構造(動力)を意識しなくてよくなりました。 しかし Engine のステータスが "発進" なのか 1 なのかはmainメソッド側では意識する必要がないものです。 さらに現実的な実装として操作先のオブジェクトが準備完了かどうかを判定してからステータス更新を行うと思います。 // Demeter4.java class Engine { // ...略... } class Vehicle { // ...略... // ★動力があるか返す boolean isReady() { return engine != null ; } } public class Demeter { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); if (vehicle.isReady()) { // ★動力があるかチェック vehicle.setEngineStatus( "発進" ); } System.out.println(vehicle.getEngineStatus()); } } こんな感じ。 尋ねるな、命じろ (Tell, Don't Ask) で、結局どうするんだ。という話ですが、こうするのが良いとされています。 // Demeter.java class Engine { // ...略... } class Vehicle { protected Engine engine; Vehicle() { engine = new Engine(); } // ★進むための処理 // engineへの操作はここで行う void start() throws Exception { if (engine != null ) { engine.setStatus( "発進" ); } else { throw new Exception( "エンジン盗まれた" ); } } // ★Vehicleの状態として返す String getStatus() { // 必要に応じて整形(ここではそのまま返す) return engine.getStatus(); } } public class Demeter { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); try { vehicle.start(); // ★ただ「進め」と命じる System.out.println(vehicle.getStatus()); // ★vehicleの状態として取得 } catch (Exception e) { System.out.println(e); // ★ダメなら例外処理(場合によってエラーコード処理でも) } } } こうすることでmainメソッドからは Vehicle のみを意識すればよく、 Engine とのことはすべて Vehicle 内に閉じることになります。 むかしばなし ずいぶん昔に所属していたチームで「getter/setterを経由しなければならないんDA!!」というお可愛いコードを主張する方がいたのですが int getA() { if (A == null ) { return B; } return A; } といったコード書いてたのを発見したときに、「[検閲削除]」「[検閲削除]」「[検閲削除]」といったことを心の中で叫んだ記憶が蘇りました。 まとめ イケてるインタフェース設計を心がけましょう。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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:FM_Harmony です。 Rakus Developers Blogでは約一年振りの投稿になります。 さて、今年から楽楽精算の スマートフォン アプリ開発 に携わることとなり、業務知識としてSwiftを学習しています。 そこで、今回はSwiftのいいなと思った箇所について、簡単にまとめてみました。 これからSwiftの学習を始める方に、Swiftの良さが伝えられれば幸いです。 はじめに いいところ①:型推論 いいところ②:nullの取り扱い いいところ③:文字列補完 おわりに 参考文献 いいところ①: 型推論 Swiftは静的型付け言語ですが、 型推論 を持っています。 そのため、変数宣言時は定数かどうかのみを意識すればよく、簡潔なコードを書くことができます。 var n = 1 print(type(of : n )) // → Int いいところ②:nullの取り扱い Swiftでは、変数にnull( nil )を代入するためには、Optional型として宣言する必要があります。 // var m = nil → コンパイルエラー var n : Int ? = nil print(type(of : n )) // Optional<Int> Optional型はアンラップしなければ利用できないため、nullかもしれない値を安全に利用することができます。 アンラップする方法の一つに、 if - let 構文があります。 var n : Int ? = 1 print(n) // Optional(1) // n += 1 → コンパイルエラー if let m = n { print(m) // 1 m += 1 } また、 guard - else 構文により、Optionalの値がnullだった場合はリターンし、そうでない場合はアンラップした値を変数に代入する、といったこともできます。 guard let n = hoge() else { return } print(n) // → hoge()の戻り値がnilでなければ、その戻り値を表示する guard - else 構文では、複数の変数に代入することもできます。 guard let m = hoge(), let n = fuga() else { return } print(m) print(n) // ↑ hoge()、fuga()の戻り値がnilでなければ、その戻り値を表示する いいところ③:文字列補完 文字列 リテラル に、 \(変数) という形で変数の値を埋め込むことができます。 変数の値と文字列 リテラル の結合もできるのですが、文字列補完を利用した方が簡潔なコードを書くことができます。 let year = 2020 let month = 6 let day = 24 print( " \(year) 年 \(month) 月 \(day) 日" ) // 2020年6月24日 おわりに いかがでしたでしょうか。 Swiftを使うことで、簡潔かつ安全なコードを書けるということが伝えられていれば幸いです。 他にも、extensionやprotocol、 クロージャ というように、過去の記事で紹介されている文法があります。 tech-blog.rakus.co.jp tech-blog.rakus.co.jp そういったものについても今後理解を深めていき、 スマートフォン アプリの機能開発に活かせればと思います。 参考文献 詳細!Swift 4 iPhoneアプリ開発 入門ノート Swift 4+Xcode 9対応 作者: 大重 美幸 メディア: Kindle 版
アバター
はじめに こんにちは。itoken1013です。 今回は Markdown (マークダウン) の超入門として、利用度が高い記法10選を紹介します。 入社研修が終わって配属先の上司や先輩とコミュニケーションをとられている新入社員の方や、在宅勤務で以前よりもオンラインコミュニケーションの機会が増えた方には是非とも覚えていただきたい記法ばかりです。 皆様の日々のコミュニケーションにお役立てください! はじめに そもそもMarkdown(マークダウン)とは何か Markdownが使えると何が便利か コミュニケーションがスムーズ になる ツールが変わっても使える これだけ覚えれば安心な記法10選 1. 見出し オープニング Meetupの発表内容 ①Twelve-Factor Appで読み解く、モダンなアプリの理想とレガシーなアプリの現実 ②開発グループが開発チームになるまでの歩み ③結果整合性ができない開発者のドメインイベント活用例 2. 改行 3. リスト(箇条書き) 4. 番号付きリスト 5. 表(テーブル) 6. 強調、太文字 7. 取り消し線 8. リンク 9. 引用 10. 水平線 終わりに そもそも Markdown (マークダウン)とは何か 文章に見出しや箇条書きなど、文章に簡単に装飾を施すための記述法が Markdown (マークダウン)です。 簡単な記述ルールに従って文章を作成するとHTMLへ変換され、装飾が施された文章が出来上がります。 例として以下は ラクスのConnpassページ でのイベントの紹介文ですが、ただの文字の羅列である上図よりも、 Markdown によって装飾された下図の方が圧倒的に読みやすいことがお分かりいただけるかと思います。 Markdown なし Markdown あり ちなみに ラク スでは社内のチャットツールにMattermostを採用していることもあり、 若手から部長まで Markdown を使ったコミュニケーションが毎日行われています。 エンジニア以外でも利用できる方は多いです。 Markdown が使えると何が便利か コミュニケーションがスムーズ になる 上述のように文章に手軽に装飾を加えることができ、圧倒的に意見を伝えやすくなります。 日常のコミュニケーションの他、議事録やIssueでも読みやすい文章を作成することができるようになるでしょう。 ツールが変わっても使える Markdown を採用しているツールやサービスは数多く(以下)、一度記法を覚えてさえしまえば、利用するツールが変わっても同様の記法で文章を作成することが可能です。 ちなみにこのブログも Markdown で書いています。 GitHub Qiita 各種エディタ Mattermost Backlog ...etc これだけ覚えれば安心な記法10選 それでは代表的な記法を紹介していきます。 ここで紹介する10個の記法を身につければ、普段のコミュニケーションに困ることは無くなるはずです。 1. 見出し まずは見出し(例. 1章、第5節など)です。 見出しを表現するには 「 # + 半角スペース 」 の後、見出し名をつけることで表現できます。 また # を重ねることで、見出しの階層を表現することもできます。 議事録や アジェンダ を示す際には、以下のような見出しがあると読みやすいですよね。 例として、以下では見出し4と5を組み合わせています。 書き方例 #### オープニング #### Meetupの発表内容 ##### ①Twelve-Factor Appで読み解く、モダンなアプリの理想とレガシーなアプリの現実 ##### ②開発グループが開発チームになるまでの歩み ##### ③結果整合性ができない開発者のドメインイベント活用例 表示例 オープニング Meetupの発表内容 ①Twelve-Factor Appで読み解く、モダンなアプリの理想とレガシーなアプリの現実 ②開発グループが開発チームになるまでの歩み ③結果整合性ができない開発者の ドメイン イベント活用例 2. 改行 次はシンプルですが、改行です。 改行は文末に 半角スペース2つ をつけることで実現できます。 書き方例 文末に半角スペースを2つ付けると、改行できますよ→ 改行できました。 表示例 文末に半角スペースを2つ付けると、改行できますよ→ 改行できました。 3. リスト(箇条書き) 先頭にハイフン をつけることで、箇条書きを表現することができます。 また 半角スペース2つでインデント をつけることで、階層構造を示すことできます。 ロジカルに考えを伝えたい場合など、多用するシーンが非常に多い記法です。 書き方例 - 好きな言語 - Java - PHP - 好きなエディタ - VSCode - Vim - Typora - 好きなメディア - はてなブックマーク - Qiita 表示例 好きな言語 Java PHP 好きなエディタ VSCode Vim Typora 好きなメディア はてなブックマーク Qiita 4. 番号付きリスト 先頭に番号をつけたリストを表示したい場合には、 先頭に番号 を付けて表現します。 また箇条書きと同様、インデントによって階層構造を示すことも可能です。 書き方例 1. 住みたい町 1. 鎌倉 1. 神楽坂 1. 荻窪 1. 部屋の条件 1. 騒音 1. ペット可 1. 駅から徒歩3分 表示例 住みたい町 鎌倉 神楽坂 荻窪 部屋の条件 騒音 ペット可 駅から徒歩3分 5. 表(テーブル) 表は少し複雑ですが、 パイプ と ハイフン で作成できます。 またヘッダーと各行の間の1行にはハイフンを指定する必要がありますが、 ハイフンの左右に コロン を指定することで 右寄せ、左寄せ、中央揃え を指定することができます。 書き方例 |日付 | カテゴリー | イベントテーマ | |---:| :---: | :--- | |2020/6/17 | Meetup | SaaSを支える品質担保術| |2020/6/19 | PHP | TechCafe| |2020/6/24 | Meetup | SaaSを支える開発原則| |2020/6/26 | オブジェクト指向 | オブジェクト指向LT会| |右寄せ| 中央揃え | 左寄せ | 表示例 日付 カテゴリー イベントテーマ 2020/6/17 Meetup SaaS を支える品質担保術 2020/6/19 PHP TechCafe 2020/6/24 Meetup SaaS を支える開発原則 2020/6/26 オブジェクト指向 オブジェクト指向 LT会 右寄せ 中央揃え 左寄せ 6. 強調、太文字 文章の中で強調したい文言がある場合、 文言の前後を アスタリスク で囲む ことで表現できます。 一見して注目ポイントがアピールできるため、利用頻度が高い記法の一つです。 ※ツールによって アスタリスク の個数が異なる場合があるため、各ツールのガイド等を確認ください。 書き方例 7月もラクスの** Meetup **と** 勉強会 **が目白押しだよ!! 表示例 7月も ラク スの Meetup と 勉強会 が目白押しだよ!! 7. 取り消し線 取り消し線は 文言の前後を チルダ (~~)で囲みます。 一度書いた文面に誤りや変更があった場合、私はよくこの取り消し線を使います。 書き方例 アンケートの結果、先月は実に~~80%~~ 90% の方から高い満足度が得られました! 表示例 アンケートの結果、先月は実に 80% 90% の方から高い満足度が得られました! 8. リンク 日々のコミュニケーションで、参照先のURLを紹介することは多いかと思います。 URLを貼り付けて示してもよいですが、分量が多くなってしまう場合、こちらのリンク記法が便利です。 リンクは 角カッコと丸カッコ を組み合わせて記述します。 書き方例 ラクスのイベント情報は、[Connpass](https://rakus.connpass.com/)をチェックしてね! 表示例 ラク スのイベント情報は、 Connpass をチェックしてね! 9. 引用 メールの返信で、複数の話題に触れる際には引用を使うことがあるかと思います。 Markdown でも引用をする際には、 > を使うことで表現をします。 書き方例 > 次回の勉強会のテーマについて オブジェクト指向です。 > イベント開催日 6/26(金)です。 > 場所 オンラインです。 https://rakus.connpass.com/event/178556/ 表示例 次回の勉強会のテーマについて オブジェクト指向 です。 イベント開催日 6/26(金)です。 場所 オンラインです。 https://rakus.connpass.com/event/178556/ 10. 水平線 まとまった情報を示したり 文面にメリハリを加えることができます。 水平線は ハイフン3つ を挟むことで、簡単に記述できます。 書き方例 ラクスのイベント情報を紹介したいと思います。 下記の内容をご確認ください。 --- - [【オンライン】SaaSを支える開発原則/DDD、心理的安全性、Twelve-Factor](https://rakus.connpass.com/event/178046/) - [【オンライン】PHP::LT会 【LT枠@2:途中参加OK】](https://rakus.connpass.com/event/178724/) - [【オンライン】オブジェクト指向LT会 vol.2(途中参加OK)](https://rakus.connpass.com/event/178556/) --- たくさんの皆様のご参加、お待ちしています! 表示例 ラク スのイベント情報を紹介したいと思います。 下記の内容をご確認ください。 【オンライン】SaaSを支える開発原則/DDD、心理的安全性、Twelve-Factor 【オンライン】PHP::LT会 【LT枠@2:途中参加OK】 【オンライン】オブジェクト指向LT会 vol.2(途中参加OK) たくさんの皆様のご参加、お待ちしています! 終わりに 利用度が高い Markdown の記法を紹介してきました。 まだまだ便利な記法はありますが、この10記法を覚えておけば、 十分にご自身が伝えたいことを読みやすく文章を起こすことができるはずです。 Markdown が使えるツールやサービスは日々増えていますので、このブログをご活用いただけましたら嬉しいです。 ではでは。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
こんにちは、技術広報の syoeshin です。 当社 ラク スの開発では様々ツールを使ってますが テキストエディタ を使用するケースも多く 若手もベテランも自分に合う テキストエディタ ”マイ・エディタ” を愛用してます。 テキストエディタ って種類が多くて ・結局どれを選ぶか? ・となりのあの人は何を使っているか? 気になりますよね。 そこで、今回は当社の若手からベテランにまで 普段愛用している テキストエディタ ーと おすすめポイントを聞きました。 質問:「愛用のエディタは何ですか?」 当社調査結果のグラフは以下 ●愛用エディタの調査結果 やはりと言いますか 当社 ラク スで1位のおすすめエディタは ●VisualStudioCode ヤングからベテランまで幅広い層で支持 以下、愛用者達からのおすすめコメント 今や最主流なので便利 プラグイン や記事なども VSCode 前提のものが多い。 Atom やBracketと比べて軽かった(今はわからない) GIT MarkDown Python PHP Docker AWS なんでもあり 軽い。多機能! 発表資料を Markdown で書いてプレビュー、からのPDF出力まで VSCode でできちゃう(marp) 新しいものに惹かれて Atom から乗り換えました 軽い、Remote Containerが便利。最近校正くん対応したので文章書くときにも使える 見易さ。編集し易さ。 デフォルトのHTML スニペット が素晴らしい。さくさくHTMLコーディングしつつ、Live Serverで保存→即時サーバ反映で良い感じ WSL と繋げて使うのもできる。npm スクリプト の実行もクリック操作で可能なので、Node.js使う系の作業に特に重宝している マークダウンでの原稿作成チェック。目に優しいので好きです。 ファイルサーバ上のテキストファイルを同時編集可能 → 他者による上書き防止 会議中の議事作成や多拠点間での同時作業時など、リアルタイムでテキストの共有を行う時に便利 明示的に保存していなくても再起動時に編集中の内容が再表示される 単純な テキストエディタ にも、開発にも使える。 プラグイン がとにかく豊富。その気になれば自分でも プラグイン を作れる。 息子も使っていて幅広い用途や年齢層で使われているところが良い。 etc... 世間的にも全世代で幅広く支持され 当社ではついに親子で使っている例も登場! 次いで、当社で2位のおすすめエディタは ● サクラエディタ ※意外にも こちらもヤングからベテランまでの幅広い層で支持 (筆者も markdown チェックで利用) 以下、愛用者達からのおすすめコメント ちょい使いには楽。巨大なテキストファイルでも割と軽い。テキスト エンコーディング の操作で慣れている。 テキスト整形とかする時、ショートカットキーがなじんでいるのがこっちなのでこっち使っちゃう 目に優しい 新人の頃、先輩に サクラエディタ の超絶技巧を見せていただき感動したため テキスト操作がやりやすい 自分なりの最適化が サクラエディタ で出来上がってしまった。いくつかのショートカットキーを多用しています。(ソート:Alt+A、マージAlt+M) 使用ソフトに厳しい客先でもなぜか使うことが許されている Sier 御用達エディタ 割と起動が軽いので大きなログファイルなどはサクラで開きます。 grep からのジャンプやマクロが便利。 軽いしプロセスが落ちたりとかもしないのでいつも重宝してます 起動が早い。メモ用、 文字コード 変換用 メモや SQL をサッと書く時には便利 置換はこれに限る。 文字コード 変換も便利。はるか昔に jar ファイルを base64 エンコーディング してコピペ => base64 デコードして保存 で手を入れていたのが懐かしい。 メモ書きから、ちょっとした編集まで大抵これを使っています 置換、マージ&ソート、矩形選択辺りを多用しています 正規表現 での置換や 文字コード 、改行コードの変換に利用しています Java や SQL の シンタックス ハイライトが使えるのも嬉しいです etc... Grep 機能、アウトライン解析はとても便利! 当社で同率3位のおすすめエディタは”Typora”と” Vim ” ●Typora 無料で、Win/ Mac / Linux に導入可能 シンプルなHTMLにエクスポートできる 強力な Markdown エディタ 以下、愛用者達からのおすすめコメント Markdown エディタ、書いた瞬間変換されるので書いていて気持ちいい リアルタイムにマークダウンを反映してくれて、手軽に綺麗に書けるため マークダウンがリアルタイムで反映され文章作成がしやすいため Markdown のエディタ。スタイルされた状態で編集できるのがいい "マークダウン見るときはこれ。とにかく見やすいと感じています。" etc... リアルタイムプレビューのUI シンプルデザイン、直感的操作を好む人におススメ! ● Vim 二大エディタの一つ 誰かが言われてました テキストエディタ には三種類しか存在しない。 " Vim " か " Emacs " か "それ以外か" だ。 ※ 引用元 以下は当社の愛用者達からのおすすめコメント 覚えてしまうとあちこちに指を伸ばさなくて良くて楽だなと思います。使いこなせるようになりたい。 ターミナル操作してる流れでは Vim を使用。一時は プラグイン 入れたりカスタマイズに凝っていたが、今はデフォルトで使用。 Viでも可。設定を変えたけど、どこに設定あるか忘れるので、検証機移行時にあせる vi よりも vim がいい派。サーバー上でちょっとした編集をしたいときにあると嬉しい Web系エンジニアでviを使わない人はいないはず。その延長で Vim を日常的に使うのは必然。 etc... Vim は、古くから多くのエンジニアに愛されてきたエディタです。 故に、"愛"も"圧"も強め! 次いで、当社で5位のおすすめエディタは ● emacs 以下、愛用者達からのおすすめコメント サーバ上で CLI でちょこっと編集するのに○。 Lisp で拡張できるので細かいところも自分好みにできる 手元メモ用とターミナル上での作業用。他のエディタを emacs 風 キーバインド にするのは嫌い。 現在、もはやメモ帳としてしか使っていないがおすすめ etc... 拡張性が高く、自由にカスタマイズができる! これにつきるのでは? 次いで、当社で6位のおすすめエディタは ●cotEditor 以下、愛用者達からのおすすめコメント ちょい使いに楽。テキスト エンコーディング の変換がかんたん。 手軽に使える。メモによく使ってる etc... 以下エディタ群は利用者が同率でした。 ● Atom 以下、愛用者達からのおすすめコメント 拡張性と操作性で選んでます 軽快に動作してくれたらもっと嬉しい etc... ● Eclipse ( IDE ) 以下、愛用者達からのおすすめコメント 学生の頃からプライベートでは一番使っています 重いという人がいますが、重くなるようなPC使ってるのがいけないのですw etc... ●JetBrains ( IDE ) 以下、愛用者達からのおすすめコメント ス クラッチ ファイルを軽い気持ちで使っている プロジェクトに属さずにコーディングができ、 IDE の支援も受けられる etc... ● Sublime Text 以下、愛用者達からのおすすめコメント ちょっとした スクリプト を見るときに使います 特に理由があるというより昔から使っていた無償版を今も使っています etc... ●nano 以下、愛用者達からのおすすめコメント 操作が直感的なのでviが使いこなせない方にはおすすめです etc... ● TeraPad 以下、愛用者達からのおすすめコメント 個人的に サクラエディタ よりもアイコンが好きです etc... ●Textastic 以下、愛用者達からのおすすめコメント WorkingCopy(gitクライアント)と併せて iOS からブログ更新用に etc... 最後に 「愛用のエディタは何ですか?」と 当社メンバーに ヒアリ ングしていた際 ・ sublime 派は今? ・ emacs 派は? vim 派は?なし? など 世にいう"エディタ戦争"の少し手前まで 盛り上がり、各メンバーが回答してくれました。 戦争手前で論争を終える事ができたのは きっと『愛』という言葉のおかげだと 勝手に解釈しております。 2020年、皆さんの愛用のエディタは何ですか? エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに こんにちは、mrym_618です。 今回は、普段業務で使用しているPhpStormの プラグイン のうち、個人的におすすめの3つを紹介したいと思います。 はじめに Rainbow Brackets deep-assoc-completion String Manipulation おわりに Rainbow Brackets Rainbow Brackets とは、対応する括弧の色を変えて見やすくする プラグイン です。 複数のif文などによりネストが重なっていくと、どの括弧とどの括弧が対応するか分かりにくくなり、コードが読みにくくなってしまいます。 そこで、この プラグイン を導入することで対応する括弧が分かりやすくなりますので、コードが読みやすくなります。 導入方法は、 Setting > Plugins で 「Rainbow Brackets 」を検索し、インストールしてPhpStormを再起動するだけです。 また、 Editor > Color Scheme > Rainbow Bracket より括弧の色をカスタマイズできますので、自分の見やすいようにカスタマイズして使用してもらえればと思います。 deep-assoc-completion deep-assoc-complatetionとは、配列の補完をしてくれる プラグイン です。 連想配列 の予測補完やDocCommentに配列の構造を定義するとそれも解釈してくれるなど、配列の操作が楽になる プラグイン です。 導入方法は、上記と同様で Setting > Plugins で 「deep-assoc-completion」を検索し、インストールしてPhpStormを再起動するだけです。 String Manipulation String Manipulationとは、文字列操作をできる プラグイン です。 文字列をキャメルケースやスネークケースに変換したり、 エス ケープや エンコード などができます。 使用方法は、 String Manipulation を導入後に、操作したい文字列を選択し、 Alt + m を押すことで表示されるドロップダウンから操作したい処理を選択するだけです。 導入方法は、上記と同様で Setting > Plugins で 「String Manipulation」を検索し、インストールしてPhpStormを再起動するだけです。 おわりに 今回はPhpStormの個人的におすすめの プラグイン を3つ紹介しました。PhpStormには、今回紹介した プラグイン 以外にも多くの プラグイン がありますので、いろいろ試して業務効率を上げていきたいと思います。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに こんにちは。新卒3年目のchoreii です。 今回は PostgreSQL の実行計画について記事を書こうと思います。 私が初めて実行計画について知った時は難しそうなイメージが先行しており、実際に調べてみても情報量が多くハードルが高かったです。ですが調べていくうちに自分が難しく感じていた理由がわかりました。 それは、 多くの記事が「実行計画の基礎知識」と「実行計画をどのようにパフォーマンス改善に活かすか」という2種類の情報を織り交ぜて記載されていたから です。 今回はできるだけ情報量を削減し、 「実行計画の基礎知識」 にフォーカスした記事を作成しました。これから実行計画を学ぶ人の最初の一歩となれば幸いです。 実際のパフォーマンスのチューニング方法や、検証するための大量データの登録に興味がある方は下記のブログもご覧ください。 tech-blog.rakus.co.jp tech-blog.rakus.co.jp 目次 はじめに 目次 1. 実行計画とは 2. 実行計画の出し方 3. 実行計画の読み方 3-1. 実行計画を読む順番 3-2. スキャン演算子 3-3. 結合演算子 3-4. その他の演算子(検索結果の整形など) 4. おまけ(コストとANALYZE) おわりに 参考文献 1. 実行計画とは 実行計画とはユーザが問い合わせたクエリ( SQL 文)を実行する手順書になります。「どの順番にテーブルを結合するか」「ソート方法」「検索方法』などの作業内容や、想定される実行コストが記述されています。 2. 実行計画の出し方 実行計画の出し方ですが、実行計画を確認したい SQL 文の先頭に EXPLAIN と付け足すだけです。 例として、itemテーブルから全件取得する SQL は SELECT * FROM item; となりますが、この SQL の実行計画を知りたい場合は EXPLAIN SELECT * FROM item; とするだけで実行計画が取得できます。 ※ オプションで出力内容や方法を設定できますがここでは割愛します。 EXPLAIN SELECT * FROM item; QUERY PLAN --------------------------------------------------------- Seq Scan on item (cost=0.00..12.20 rows=220 width=328) 3. 実行計画の読み方 前項の通り実行計画を表示することはできました。次はもう少し複雑な SQL の実行計画を使って実行計画の読む順番や、それぞれの行が何を意味しているかを解説していきます。以下が解説に使用する SQL 文とその実行計画です。 EXPLAIN SELECT * FROM item INNER JOIN customer ON item.customer_id = customer.id WHERE customer.name = '佐藤' ORDER BY item.id; QUERY PLAN --------------------------------------------------------- Sort (cost=27.07..27.08 rows=1 width=574) Sort Key: item.id -> Hash Join (cost=14.03..27.06 rows=1 width=574) Hash Cond: (item.customer_id = customer.id) -> Seq Scan on item (cost=0.00..12.20 rows=220 width=332) -> Hash (cost=14.00..14.00 rows=2 width=222) -> Seq Scan on customer (cost=0.00..14.00 rows=2 width=222) Filter: ((name)::text = '佐藤'::text) 3-1. 実行計画を読む順番 実行計画はよく見るとツリー構造になっており、インデント下げや「->」などで表されます。(出力方法によって異なります。)以下に先の実行計画のツリー構造を簡単に図にしたものがあります。 図1: 実行計画のツリー構造 読む順番のルールは2つだけです。 順番に子要素をたどり一番子孫の要素から実行し、親要素に遡っていく 兄弟要素がある場合は先に記述されている行から順に子要素をたどる 今回の場合、一番深い子要素は7,8行目になりますが、5行目と6行目が兄弟要素にあたります。そのため最初に5行目を実行してから6行目の子要素をたどっていくことになります。図に読む順番を追記すると以下のようになります。 図2:実行計画のツリー構造(読む順番) 読む順番に迷った際はツリー構造がどうなっているかを一度図にしてみるとわかりやすいと思います。 3-2. スキャン 演算子 次に個別の行の解説をします。最初に実行される以下の行の先頭に Seq Scan と書かれています。 -> Seq Scan on item (cost=0.00..12.20 rows=220 width=332) これは、単語の意味通りitemテーブルの中から必要な行を順番に検索することを意味する行で、もっとも基本的な検索(スキャン)方法になります。スキャン 演算子 は Seq Scan 以外にもインデックスが利用できる場合に選択される Index Scan などがあります。 3-3. 結合 演算子 3,4行目ではテーブルの結合を行っています。ハッシュとついているのは一方のテーブルから作られたハッシュ表を元に結合しているからで、最初のハッシュ表の作成は6行目でおこなわれています。メモリ上にハッシュ表が作成されるため、メモリに余裕がある場合は高速に動きます。結合 演算子 は他に Nested Loop や Merge Join が存在します。 -> Hash Join (cost=14.03..27.06 rows=1 width=574) Hash Cond: (item.customer_id = customer.id) 3-4. その他の 演算子 (検索結果の整形など) 1,2行目ではソートを行っています。スキャンや結合よりも直感的に何をしているかが分かりやすいと思います。(ここでは SQL のORDER BY句で指定したようにitemテーブルの‪‪id列でソートがかかっています。) Sort (cost=27.07..27.08 rows=1 width=574) Sort Key: item.id 他にも Group や Limit など、特定の SQL を記述した際に検索結果を整形するための 演算子 が存在します。 4. おまけ(コストとANALYZE) 演算子 の意味について解説しましたが、 演算子 の後ろにカッコ書きで数値などが記載されています。 -> Seq Scan on item (cost=0.00..12.20 rows=220 width=332) これは、実行計画通りに SQL を実行した場合の推測値で、左から順に以下の数値になっています。 初期コスト:検索結果の1行目を返すまでにかかる準備のコスト(秒数ではない) 総コスト:初期コストを含めた処理完了までにかかるコスト(秒数ではない) 行数:返却される検索結果の行数 行の長さ:返却される1行あたりの長さ(横幅) パフォーマンスを確認する際は総コストを確認して、 SQL の組み方を変更することによってコストを抑えることができないかを調節することが多いです。 しかし、出てくる結果はあくまで推測値なので実際に SQL を実行してみた結果と食い違うことがあります。その場合は ANALYZE オプションを使用し実際に SQL を実行してみた結果、実行計画のどの部分にどれだけの時間やコストがかかったかを確認する必要があります。(以下のような出力になります) ※ 「EXPLAIN」の直後に「ANALYZE」と付け足す EXPLAIN ANALYZE SELECT * FROM item INNER JOIN customer ON item.customer_id = customer.id WHERE customer.name = '佐藤' ORDER BY item.id; QUERY PLAN --------------------------------------------------------- Sort (cost=27.07..27.08 rows=1 width=574) (actual time=0.037..0.037 rows=4 loops=1) Sort Key: item.id Sort Method: quicksort Memory: 25kB -> Hash Join (cost=14.03..27.06 rows=1 width=574) (actual time=0.025..0.027 rows=4 loops=1) Hash Cond: (item.customer_id = customer.id) -> Seq Scan on item (cost=0.00..12.20 rows=220 width=332) (actual time=0.006..0.006 rows=8 loops=1) -> Hash (cost=14.00..14.00 rows=2 width=222) (actual time=0.008..0.008 rows=1 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Seq Scan on customer (cost=0.00..14.00 rows=2 width=222) (actual time=0.005..0.005 rows=1 loops=1) Filter: ((name)::text = '佐藤'::text) Rows Removed by Filter: 1 Planning time: 0.159 ms Execution time: 0.062 ms (actual time=0.008..0.008 rows=1 loops=1) が行末に追加されたり、QUERY PLANの最後に実際の実行時間などが出力されるようになっています。この記事では詳細は割愛しますが、このように実際に実行してみた結果を取得することも可能です。 おわりに 今回は実行計画の最低限の知識に絞って解説してみました。できるだけ初心者の人が最初に疑問に思うことをピックアップしたつもりなので、この記事を読んでからさらに詳しい解説記事を見ていただければ学習がはかどると思います。私自身まだ浅い基礎知識しか定着しておらず、業務で実行計画を使いこなせているとは言い難いです。今回、基本的な情報を整理する中での気づきもありましたので、さらに学習を深め身につけていきたいと思います。 参考文献 EXPLAIN PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~ PostgreSQLの実行計画について調べてみた | キャスレーコンサルティング株式会社 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
はじめに こんにちは。新卒3年目になりましたtaku_76です。 今回は SQL についての記事を書こうと思います。その経緯としては、業務で SQL を少し書くことはあったのですが、 必要な情報を取り出せたらいいや、くらいの意識しかなく、あまりパフォーマンス面を意識するということはありませんでした。 しかし、今後の新規開発で SQL の改修があった際、パフォーマンスの考慮は必ず必要になってきますので学習することにしました。 学習にあたっては以下の書籍を用いて学習しました。1部と2部に分かれているのですが、今回の記事では1部について、パフォーマンス面に注視して印象に残ったことを具体例とともに取り上げています。あくまで考え方を取り上げたかったため、文法の説明などは割愛しています。 www.shoeisha.co.jp はじめに パフォーマンスの向上のために覚えるべきこと CASE式 CASE式の中で集約関数を使う EXISTS述語 述語とは 全称量化と存在量化 テーブルに存在「しない」データを探す ウィンドウ関数 ウィンドウ関数 vs 相関サブクエリ おわりに パフォーマンスの向上のために覚えるべきこと CASE式 CASE式を使うことで複数の SQL 文を1つにまとめ、可読性もパフォーマンスも向上することができます。それを以下に示します。 CASE式の中で集約関数を使う 以下のような社員と所属サークルを一覧化するテーブルを考えます。主キーは、社員番号とサークルIDとします。 shain_cricleテーブル shain_id circle_id circle_name main_circle_flag 1000 1 野球 YES 1000 2 サッカー NO 2000 2 サッカー NO 2000 3 バスケットボール YES 2000 4 バレーボール NO 3000 4 バレーボール NO 4000 5 吹奏楽 NO 5000 6 水泳 NO 社員は複数のクラブに所属している場合と、1つにしか所属していない場合があります。 複数のクラブを掛け持ちしている社員は、メインのサークルを示すフラグ列にYESまたはNOの値が入ります。そうでない社員はNOが入ります。 このテーブルから次のような条件でクエリを発行するとします。 1つだけのクラブに所属している社員については、そのサークルIDを取得する 複数のクラブを掛け持ちしている社員については、メインのサークルIDを取得する 1.2.についてそれぞれ以下のようなクエリを発行すれば抽出が可能です。 -- 1つのサークルに所属している社員を抽出 SELECT shain_id, MAX(circle_id) AS main_circle FROM shain_circle GROUP BY shain_id HAVING COUNT(*) = 1 ORDER BY shain_id; -- 結果 shain_id | main_circle ----------+------------- 3000 | 4 4000 | 5 5000 | 6 (3 行) -- サークルを掛け持ちしている社員を選択 SELECT shain_id, circle_id AS main_circle FROM shain_circle WHERE main_circle_flag = 'YES' ORDER BY shain_id; -- 結果 shain_id | main_circle ----------+------------- 1000 | 1 2000 | 3 (2 行) 上記でも条件を満たした抽出ができるのですが、場合によって複数の SQL が必要になりパフォーマンスの問題が発生します。 これをまとめたものを、CASE式を使えば1つの SQL で書くことができます。(UNIONでは結局クエリの発行回数は変わらないためパフォーマンスは同じ) SELECT shain_id, CASE WHEN COUNT(*) = 1 THEN MAX(circle_id) ELSE MAX(CASE WHEN main_circle_flag = 'YES' THEN circle_id ELSE NULL END) END AS main_circle FROM shain_circle GROUP BY shain_id ORDER BY shain_id; -- 結果 shain_id | main_circle ----------+------------- 1000 | 1 2000 | 3 3000 | 4 4000 | 5 5000 | 6 (5 行) ポイントとしては、「1つだけのサークルに所属しているのか、複数のサークルに所属しているのか」という条件分岐をCASE式で表現することです。 元々、集計結果に対する条件はHAVING句を使うと学んでいましたが、CASE式を使うことでSELECT句でも同じような条件分岐を実現することができました。 CASE式はSELECT句で集約関数の中にも外にも書けたりと自由度が高いのでうまく扱えるようになりたいと思います。 EXISTS述語 EXISTSは複数行を一単位と見なした条件を記述することができ、相関サブクエリを利用するにもかかわらずパフォーマンスが優れているという特徴があります。 結論から言うと、EXISTSは「量化」という述語論理の機能を実現するために SQL に取り込まれました。 述語とは 一言でいうと関数のことですが、EXISTSはSUMなどの普通の関数とは異なり、戻り値が真理値になる関数の事を指します。 例として、=,<,>,などの比較述語や、BETWEEN,LIKE,IN,IS NULLなどがあります。 ここで、=やBETWEENなどと、EXISTSを比較すると「引数に何を取るか」という面で大きな違いがあります。 =やBETWEEN 「x = y」や「x BETWEEN y AND z」などの述語の引数は、数字や名前といった単一の値、スカラ値。 EXISTS 行の集合(例. SELECT * FROM ○○テーブル WHERE ○○=○○) 上記から分かるように、EXISTSは入力のレベルに特徴があります。述語論理では「入力のレベル」に応じて述語が分類されています。 そして、=やBETWEENなど1行を入力とする述語を「一階の述語」、EXISTSのように行の集合を入力する述語を「二階の述語」といいます。 全称量化と 存在量化 述語論理には、量化子という特別な述語が存在します。量化子とは以下の2つの文を書くための道具です。 全称量化子 すべてのxが条件Pを満たす 存在量化 子 条件Pを満たすxが(少なくとも1つ)存在する EXISTS述語は、述語論理の 存在量化 子を実装したものです。ここで重要なことがあるのですが、 SQL にはもう一方の全称量化子に対応する述語は導入されませんでした。 しかし、全称量化子と 存在量化 子は片方が定義されていれば同値変形の規則がありますので、「すべての行が条件Pを満たす」という文を「条件Pを満たさない行が存在しない」と変換することで表現できます。これについてEXIST述語を使って書いていきます。 テーブルに存在「しない」データを探す データベースからデータを検索する場合、一般的にはある条件を満たすものを抽出します。しかし、時にはテーブルに存在「しない」データを抽出する場合もあります。 例えば、複数回行われるミーティングと出席者を記録しておくテーブルがあるとします。 meetingsテーブル meeting shain 1回目 A 1回目 B 1回目 C 2回目 A 2回目 D 2回目 C 3回目 B 3回目 D 今回はこのテーブルから「出席しなかった社員」を求めます。 存在するデータに対して「○○という性質を満たす」という条件を設定するのではなく、そもそも「データが存在するかどうか」という、次数の1つ高い問題設定を行います。 これが「二階の問い合わせ」であり、EXISTS述語を使う機会です。 考え方としては、全員が出席したと仮定した場合の集合から、現実に出席した人を引き算することで求めます。 1.全員が出席した場合の集合を求める SELECT DISTINCT m1.meeting,m2.shain FROM meetings m1 CROSS JOIN meetings m2 ORDER BY meeting, shain; -- 結果 meeting | shain ---------+------- 1回目 | A 1回目 | B 1回目 | C 1回目 | D 2回目 | A 2回目 | B 2回目 | C 2回目 | D 3回目 | A 3回目 | B 3回目 | C 3回目 | D (12 行) 2.meetingsテーブルに存在しない組み合わせに絞り込む SELECT DISTINCT m1.meeting,m2.shain FROM meetings m1 CROSS JOIN meetings m2 WHERE NOT EXISTS (SELECT * FROM meetings m3 WHERE m1.meeting = m3.meeting AND m2.shain = m3.shain) ORDER BY meeting, shain; -- 結果 meeting | shain ---------+------- 1回目 | D 2回目 | B 3回目 | A 3回目 | C (4 行) これでうまく抽出することができました。このようにEXISTS述語を使うことで存在「しない」データを抽出することができます。 SQL を書くときに述語論理を意識的に考えることはなかったので、今後そういう視点からも考えてみたいと思います。 ウィンドウ関数 今回、ウィンドウ関数について基本的なことは割愛します。応用方法としては、特に、これまで行間比較において相関サブクエリを使わなければならなかったケースにおいて、 ウィンドウ関数を使うことでスッキリとした SQL 文を記述することができます。 ウィンドウ関数 vs 相関サブクエリ 相関サブクエリとウィンドウ関数を比較すると以下のような違いがあります。 ウィンドウ関数は、サブクエリを使っているが、「相関」サブクエリではないためサブクエリ単体で実行することができる。 そのため、可読性が高く動作も理解しやすい テーブルに対するスキャンが1度だけで済むので、パフォーマンスが良い。 検証は割愛しますが、相関サブクエリもウィンドウ関数も、集合のカットとレコード単位のループという同じ機能を実現していると言えるので置き換えることができます。 次のような商品の名前や価格を格納するテーブルを見てみます。 shohinテーブル shohin_id shohin_name shohin_bunrui tanka 1 マウス PC 3500 2 扇風機 家電 7000 3 キーボード PC 1500 4 文房具 シャーペン 600 5 ドライヤー 家電 3000 6 電球 家電 600 7 電動歯ブラシ 家電 800 8 ボールペン 文房具 150 このshohinテーブルから、各商品分類について平均単価より高い商品を抽出してみます。(相関サブクエリで解く典型的な問題) まずは、相関サブクエリです。 SELECT shohin_bunrui, shohin_name, tanka FROM shohin s1 WHERE tanka > (SELECT AVG(tanka) FROM shohin s2 WHERE s1.shohin_bunrui = s2.shohin_bunrui GROUP BY shohin_bunrui) ORDER BY shohin_bunrui; -- 結果 shohin_bunrui | shohin_name | tanka ---------------+-------------+------- PC | マウス | 3500 家電 | 扇風機 | 7000 家電 | ドライヤー | 3000 文房具 | シャーペン | 600 (4 行) ポイントとしては、「s1.shohin_bunrui = s2.shohin_bunrui」というs1集合とs2集合に対するバインド条件です。これにより、2つのテーブルの商品分類を同じレコード集合に限定して、その集合の平均単価と各レコードの単価を1行ずつ比較しています。 上記コードと同じ結果を抽出するウィンドウ関数は次のようになります。 SELECT shohin_name, shohin_bunrui, tanka FROM (SELECT shohin_name, shohin_bunrui, tanka, AVG(tanka) OVER(PARTITION BY shohin_bunrui) AS avg_tanka FROM shohin) tmp WHERE tanka > avg_tanka; -- 結果 shohin_name | shohin_bunrui | tanka -------------+---------------+------- マウス | PC | 3500 ドライヤー | 家電 | 3000 扇風機 | 家電 | 7000 シャーペン | 文房具 | 600 (4 行) こちらの挙動としては、まずサブクエリのウィンドウ関数で商品分類ごとの平均単価( avg _tanka)を計算しています。 SELECT shohin_name, shohin_bunrui, tanka, AVG(tanka) OVER(PARTITION BY shohin_bunrui) AS avg_tanka FROM shohin; -- 結果 shohin_name | shohin_bunrui | tanka | avg_tanka --------------+---------------+-------+----------------------- キーボード | PC | 1500 | 2500 マウス | PC | 3500 | 2500 ドライヤー | 家電 | 3000 | 2850 扇風機 | 家電 | 7000 | 2850 電球 | 家電 | 600 | 2850 電動歯ブラシ | 家電 | 800 | 2850 シャーペン | 文房具 | 600 | 375 ボールペン | 文房具 | 150 | 375 (8 行) あとは各行で「tanka > avg _tanka」という条件で簡単に平均単価と単価の比較が行えます。 このウィンドウ関数の結果のよいところは、商品分類ごとの平均単価を計算しますが、この際、レコードを集約せずに元のテーブルに列として結果を追加するだけ、という情報 保全 性が働くところです。 個人的に相関サブクエリは動作の理解が難しくあまり好んではいなかったのですが、ウィンドウ関数で同じことを表現することができ、 パフォーマンスも可読性もよいことが分かったので学習を進めてみたいと思いました。 おわりに いかがだったでしょうか。もし私と同じように、 SQL のパフォーマンスを向上するにはどうすればよいか、何を使えば分からないという方の学習のきっかけになれば幸いです。 今回紹介しているのはほんの一部ですので、他にも知りたい、深掘りをしたいと思った方にはぜひおすすめの書籍です。 SQL を書くときの考え方が変わるかと思います。 私も今回学習してみて新しい気付きがたくさんありましたので、何度か読み直してみて定着させたいと思います。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
初めに こんにちは。 mako _makokです。 フロントを Vue + Vuex + TypeScript で新規開発中の SaaS プロダクトに携わることになり、急ピッチでVueを学習しています。 今回はVuexについて学習したので、その結果をまとめました。 Vuexは一言で表すと、単一方向のデータフローを持った状態管理パターンのライブラリです。 記事内でサンプルが登場しますが、Vueのバージョンは2系で書いています。 初めに Vuexをなぜ使うのか? Fluxについて Vuexのアーキテクチャ Store State Getter Mutation Mutationを書くときのコツ Action まとめ おわりに Vuexをなぜ使うのか? Vueアプリケーションを開発しているとアプリケーションの状態を参照し、 コンポーネント の動作を変えたくなることがあります。 例えば、カレンダーアプリなどでは"現在表示する月"を状態として持ち、"現在表示する月"を参照して表示する日付・日数・予定を変えたくなると思います。 このような動作をする処理を愚直に実装すると、状態自体が複数の コンポーネント に分散してしまったり、状態を変更するロジックが分散、重複してしまうケースが考えられます。 では状態を抽出し、グローバルなオブジェクトで持てば解決するのでは?と考えるかもしれません。 ですが、これは コンポーネント 分割している意味がありません。 コンポーネント ツリーのどこからでもアクションを実行することや、状態を変化させることができてしまいます。それはもはや巨大な コンポーネント が出来上がるのと同義です。 そこで、状態管理に関わる部分を 定義・分離・ルール化 してコードの構造と保守性の向上を目的としたライブラリがVuexです。 Fluxについて Vuexの話を続けていきたいところですが、Vuexの 公式 には以下のようにあります。 Flux、 Redux そして The Elm Architectureから影響を受けています。 最初に書いた、 単一方向のデータフローを持った状態管理パターン というのはFluxに特に影響を受けています。 まず最初にFluxを知ることによって、Vuexをより理解しやすくなるのではと思います。 Fluxとは、 Facebook が提唱している アーキテクチャパターン です。 以下は Facebook が実際にFluxの実装を行ったサンプル リポジトリ です。 https://github.com/facebook/flux Fluxでは MVC やMVVMと異なり、単一方向のデータフローを有していることが特徴です。 具体的には以下の図のようになります。 Fluxの アーキテクチャ Store アプリケーションのデータ(状態)を保持する Dispatcherから更新される publicなsetter を持ってはならない publicなsetterがあると、無秩序にStoreを書き換えることができてしまう Dispatcher Actionを受け取って Storeを更新 する すべてのアクションを受け取る Action Storeをどのようなロジックで更新するか記載した命令 *1 View VueやReactで言うところの コンポーネント 正直これはだけではパっとしないと思うのでToDoアプリでToDoを追加する動作を例にとってみます。 アプリケーションはToDoを保持しているStoreを持っている ToDoを入力し、追加ボタンを押すとToDoを追加する ActionがDispatcherに命令 命令を受け取った DispatcherがActionを実行 し、StoreにToDoを追加する StoreにToDoが追加されたので、更新を検知したViewは再 レンダリング を行い、追加されたToDoを表示する ActionはToDoを直接更新せず、Dispatcherに命令を渡しているところがミソとなります。 以上がFluxの概要になります。ここでポイントとなるのは以下の2点です。 Fluxは 単一方向のデータフロー をもった アーキテクチャ である StoreはActionを受け取ったDispatcherからでしか更新できない Vuexの アーキテクチャ いよいよVuexの アーキテクチャ について説明します。以下図はVuexの アーキテクチャ です。 Vuexの アーキテクチャ FluxからState, Getter, Mutationが増えています。また単一方向のデータフローを持っていることがわかると思います。 VuexではFluxで登場したStoreやDispatcherとコンテキストが微妙に変わっている箇所があります。 Store → Vuexの インスタンス State → FluxでいうところのStore Getter → Stateから値を取得する Mutation → Stateを更新する 。FluxのDispatcherの更新部分だけを切り離したようなイメージ Dispatch → Actionを実行する役割に特化 Action → State をどのようなロジックで更新するか記載した命令 以上が簡単な アーキテクチャ の説明です。なんとなくFluxから言葉が変わったり、Dispatcherの役割が分かれたんだなーくらいの感覚を持っていただければ大丈夫です。 今回はToDoアプリケーションを作りながらそれぞれ説明していきます。 Store StoreはVuexの インスタンス です。主にstate, getters, mutations, actionsから構成されます。 詳しく知りたい方は Vuex.StoreのAPIリファレンス を御覧ください。 const store = new Vuex.Store( { state: {} , getters: {} , mutations: {} , actions: {} } 重要なのはStoreはアプリケーション内で 常に1つであるように設計 するということです。 理由は後述します。 State アプリケーションの状態を保持します。Stateは 信頼できる唯一の情報源 でなくてはなりません。 Storeの項で、Storeはアプリケーション内で常に1つであるように設計すると述べました。 Storeが一つということはStateも一つしかないことが担保されますので、Stateは "信頼できる唯一の情報源" が実現します。 Stateは以下のようにオブジェクトを記述していきます。 state: { todos: [] } , Getter GetterはStateの一部や、Stateで計算された値を返します。 Getterの特徴として、Getter内での 計算結果はキャッシュされます。 キャッシュされたGetterの結果は、Stateが更新されるとクリアされます。 今回はStateから完了済みのToDoを返すGetterを作成しました。 getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } } Mutation MutationはStateを更新する唯一の手段です。 Mutationにはいくつかのルールがあります。 Mutation以外がStateを更新すること は禁止 Mutationは直接参照しない。 Store.commit() から呼び出す Mutationには非同期処理を書いてはならない devtoolでmutationの更新履歴を追いかけづらくなる 意図しないタイミングで更新処理が入る VueのdevtoolではStateの更新履歴を追うことができるのですが、Mutationで非同期処理を書いてしまうと 意図しないタイミングで更新され、どのようにStateが書き換わったかわかりづらくなってしまうので規約レベルで禁止されています。 以上のことを踏まえ、Mutationを書いていきます。 MutationにはStateを第一引数に渡します。また、Mutationには追加の引数を渡すことができます。 追加の引数のことを ペイロード と呼びます。 storeのオブジェクトを直接弄るように書きます。 mutations: { HOGE (state) { state.hoge = "hoge" } , FUGA (state, payload) { state.fuga = payload.content } } 2のルールに則り、Mutationはstore.FUGAなどと呼び出すことは禁止されています。 Mutationを呼び出すために、以下のように store.commit を使用します。 store.commit( 'FUGA' , { content: 'fuga' } ) ToDoリストにToDoをpushする処理を書いていきます。 mutations: { PUSH_TODO(state, { content, done } ) { state.todos.push( { content: content, done: done } ) } } Mutationを書くときのコツ 余談ですが、MutationではStateを更新する処理を書くべきで、具体的な更新内容を書くべきではありません。 具体的な動作は後述するActionに記述します。 カウンターアプリであれば、例えばStateのcounterを1足したい時 increment という関数はMutationに記述せず、 Mutationには数値を受け取ってcounterを変更する changeCounter() を作成します。 Actionに increment という関数を定義し、 increment 内で changeCounter を呼び出し、1を渡してあげましょう。 このように記述することで、 decrement を作成したくなったときも効率的に書くことができると思います。 Action Actionは最終的にMutationをcommitします。 Mutationでは非同期処理を書くことは禁止されていましたが、Actionには 非同期処理を書くことができます 。 第一引数には コンテキスト 、第二引数にはMutationと同様 ペイロード を渡すことができます。 コンテキストはオブジェクトなので、 分割代入 で使用するものだけ渡すとスッキリします。 actions: { doHoge (context) { context.commit( 'HOGE' ) } , doFuga ( { commit } , payload) { commit( 'FUGA' , payload) } } Actionは直接呼び出せません。 store.dispatch から呼び出します。 store.dispatch( 'doFuga' , payload) ToDoアプリのactionは以下のように書いていきます。 図からも分かる通り、 API で通信処理などはここに書きます。 ToDoアプリでいい非同期処理を思いつかなかったのでとりあえず1秒ずらしてToDoを追加します actions: { addTodo( { commit } , { content } ) { commit( 'PUSH_TODO' , { content: content, done: false } ) } , addTodoAsync( { commit } , { content } ) { setTimeout(() => { commit( 'PUSH_TODO' , { content: content, done: false } ) } , 1000) } } これでToDoアプリのStoreが完成しました。 最後にVue コンポーネント にstoreオブジェクトを渡して完成です。 new Vue( { el: "#app" , store, Vue コンポーネント にstoreを渡しているだけなので this.$store からアクセスできます。 今回は直接storeを代入していますが、webpackを使用している場合はVuexをimportしてきて Vue.use(Vuex) でも同じことができます。 完成形を以下においておきます。 jsfiddle.net まとめ ここまでVuexについて書いてきました。 以下にポイントをまとめます。 Storeはアプリケーションに1つだけ存在するように設計する Stateは直接更新しない。必ずMutationから更新すること Mutationは直接呼び出さないこと。 store.commit で呼び出す Mutationには非同期処理を書かない Actionは直接呼び出さないこと。 store.dispatch で呼び出す おわりに 基本的に規約を守って書けばVuexのコードを書くのにそこまで苦労はしないかと思います。 Vuexは難しいと聞いていましたが、 API も多くなく基本的な書き方自体はスッと入ってきた気がします。 しかし、本当に難しいと感じたのはそもそもプロジェクトにVuexを入れるべきか *2 、どこまでStoreに持たせるか、ということです。 また、Vuex + TypeScriptのツラミやVue3 + Vuexなど色々ネタがあるのでこの辺も記事にしていけたらと思います。 私たちは一緒に働くメンバーを募集しています。 ご興味を持たれましたら以下のサイトからお問い合わせください。 career-recruit.rakus.co.jp *1 : アクションはViewから発火させることが多いですが、Viewから発火させないケースもあります *2 : Storeパターンの独自実装を行う, Firebaseなどを使用するなどVuexに頼らなくてもStateを管理できる
アバター
こんにちは、tarakamです。 普段プログラミングをする際、使い慣れた IDE や テキストエディタ があるという方は多いかと思います。では、そこで使う フォント にはこだわっているでしょうか?今回はプログラミングのためのフォント選びについて記します。 Why プログラミングフォント? どんなフォントがいいの? おすすめフォント Ricty Diminished Source Han Code JP Cica おわりに Why プログラミングフォント? 一般的なフォントの場合、アルファベットのI(大文字)とl(小文字)、0(数字)とO(大文字)などが見分けづらいことがあります。普通の文章であれば文脈でわかるでしょうが、プログラミングの場合はそうでないこともあります *1 。見間違えないフォントになっていれば、コードを書くのも読むのも楽になります。 また美しいフォントを使うことで、モチベーションアップにも繋がるかもしれません。 どんなフォントがいいの? 好みにもよるかと思いますが、以下のような条件を満たすものだといいでしょう。 等幅フォント I(大文字のアイ), l(小文字のエル), 1(数字の1), |( バーティカルバー )が区別できる O(大文字のオー), 0(数字のゼロ)が区別できる 日本語に対応している 日本語非対応だと英語と日本語が違うフォントで表示され、字の大きさや線の太さが異なるなど違和感があります 太字・斜体に対応している エディタによっては シンタックス ハイライトで太字や斜体を使うこともあるため これらを踏まえて、以下で筆者のおすすめのフォントをいくつかご紹介します。 おすすめフォント Ricty Diminished Ricty Diminished Ricty Diminished は、英字フォントInconsolataと日本語フォントCircle M+ 1mを元に作成されたフォントです。バグの原因になりやすい全角スペースを区別できるのが特徴の一つです(上記画像の「計算する」の右に全角スペースが入っています)。その他、半濁点が大きく「ば」と「ぱ」などを区別しやすいことも特徴です。 姉妹フォントの Ricty もありますが、ライセンスの関係で手元で スクリプト を実行してフォントを生成する必要があります。Dinimishedの方が漢字の収録数が少ないのですが、一般的に使う漢字は大体カバーされているので、手軽な Ricty Diminishedでも十分でしょう。 Source Han Code JP Source Han Code JP Source Han Code JP (別名 源ノ角ゴシック Code)は Adobe によって作成されたフォントで、Source Code Proと源ノ角ゴシックが元になっています。一般的なフォントは半角と全角の横幅が1:2になっていますが、このフォントは2:3になっているのが特徴です。半角文字の幅が広いため、ゆったりとした印象があります。 Cica Cica Cica は英字フォントのHackとDejaVu Sans Mono、日本語フォントのRounded Mgen+など複数のフォントが元となっているフォントです。 Ricty を参考に作られていて、全角スペースが Ricty Diminishedと同様に可視化されています。 おわりに 今回は3つのフォントの紹介に留めましたが、これ以外にもプログラミングフォントはたくさん存在します。ぜひ自分のお気に入りのフォントを見つけてみてください! *1 : ループカウンタでl(小文字)一文字の変数などよくありますね
アバター
はじめに こんにちは。itoken1013です。 今年も ラク スにたくさんの新入社員が入社しました。 日本中の新エンジニアが研修に取り組んでいるであろうこの頃、今回はGitと GitHub の超基本的な使い方をまとめてみたいと思います。 今やエンジニアにとって必須であるGitですが、チーム開発を行うためには GitHub も使いこなせると、 よりスムーズに開発を進めることができるでしょう。 まずは今回の記事で基本的な使い方を押さえていただければと思います。 弊社ブログのGitに関わる関連記事もぜひご一読ください! ・ 【Git入門】git cloneで既存リポジトリをクローンしよう! ・ 【Git入門】git stashで作業を便利に退避する ・ 【Git入門】git commitを取り消したい、元に戻す方法まとめ はじめに 基本知識 まず、バージョン管理とは Gitとは リポジトリとは GitHubとは 1. GitとGitHubの超基本的な使い方 1-1. Gitのインストール 1-2. Gitの初期設定 1-3. GitHubのアカウント作成 1-4. リモートリポジトリを作成する 1-5. ローカルリポジトリを作成する 1-6. ローカルリポジトリにコミットする 1-7. リモートリポジトリにプッシュする 2. GitとGitHubを使ったチーム開発の超入門 2-1. リポジトリをクローンする 2-2. ブランチを作成する 2-3. ブランチでコミットする 2-4. リモートリポジトリにプッシュする 2-5. コードレビュー・マージ 2-6. リモートリポジトリからプルする まとめ   基本知識 まず、バージョン管理とは ソースコード をはじめとしたファイルの変更履歴(バージョン)を管理することを「バージョン管理」と呼びます。 ファイルの追加や変更の履歴情報を管理することで、過去の変更箇所を確認する、特定時点の内容に戻す、などの「バージョン管理」という作業が可能となります。 このバージョン管理という概念が存在しない状況下での開発作業を考えた場合、 バグ発生時には混入時期が分からず、修正が遅れる、発生したバグによる影響度が不明確になる、 結果としてユーザーの満足度低下につながるなどのリスクが高まります。 また後述するチームでの開発においても、メンバー間での開発内容を連携することが難しくなり、 開発の生産性を大きく損なうことにつながります。 以上のことより、ソフトフェアの開発において、バージョン管理への理解は必須となります。 Gitとは 上記で説明しましたバージョン管理を行うためのシステムがGitです。 他の バージョン管理システム と比較したGitの特徴として、「分散型」の バージョン管理システム である点が挙げられます。 バージョン管理システム は大きく「集中型」と「分散型」に分けられます。 「集中型」の バージョン管理システム では、特定の場所にある リポジトリ への接続が必須となりますが、 「分散型」の バージョン管理システム では個々人のマシン上に リポジトリ を作成して開発を行うことができ、現在のチーム開発における主流となっています。 Gitの具体的な使い方は、後ほど紹介していきます。 リポジトリ とは バージョン管理によって管理されるファイルと履歴情報を保管する領域を、 リポジトリ と呼びます。 リポジトリ の配下でファイルや ディレクト リを操作することで、私たちはバージョン管理を行うことができます。 分散型の バージョン管理システム であるGitでは、まず個々人のマシン上にある リポジトリ 上で作業を実施後、 作業内容をネットワーク先のサーバー上などにある リポジトリ に集約する流れで開発を進めていきます。 この個々人の リポジトリ を「ローカル リポジトリ 」、集約先となる リポジトリ を「リモー トリポジ トリ」と呼びます。 Gitを使った開発ではこの区別が重要となるため、しっかり理解いただければと思います。 GitHub とは 複数人のエンジニアがリモー トリポジ トリとして活用する他、チーム開発を行うための機能を提供する WEBサービス が GitHub です。 リポジトリ としての機能を持つ他にも、コード レビュー機能 や Wiki などのコミュニケーションツールとしての機能を持ち、組織規模を問わず、多くの企業・団体がソフトウェア開発で利用しています。 後述ではリモー トリポジ トリの作り方、またコードレビューを実施する方法を紹介していきます。 1. Gitと GitHub の超基本的な使い方 概要の説明を踏まえたところで、まずはGitと GitHub の超基本的な使い方を説明していきます。 Gitの初期設定を踏まえ、以下の流れで GitHub にファイルを反映してみましょう。 Gitのインストール Gitの初期設定 GitHub のアカウントを作成 リモー トリポジ トリを作成する ローカル リポジトリ を作成する ローカル リポジトリ にコミットする リモー トリポジ トリにプッシュする 1-1. Gitのインストール まずはGitを利用できる状態にしていきましょう。 Mac の場合 Mac であればGitはインストール済となりますため、本作業は不要です。 Windows の場合 公式ページ から インストーラ ーをダウンロードします。 インストーラ ーを起動すると多くの設問が表示されますが、 本記事の作業では全てデフォルトの状態で問題ありません。 「Next」ボタンをクリックし続け、以下の画面まで辿り着きましたら「Install」ボタンでインストールを行います。 インストールが完了しましたら、Git Bash を起動します。 Git Bash とは、 Windows 上でGitのコマンドを操作するためのツールです。 Git Bash を起動後、以下のコマンドを入力してGitのバージョン情報が表示されることを確認してください。 $ git --version git version 2.26.2.windows.1 ※以降のGit操作は全てターミナルやGit Bash などの コマンドライン として紹介していきますが、 Gitは GUI ツールを使って利用することも可能です。 「Git GUI 」などで検索の上、利用シーンに応じて使い分けていただければと思います。 1-2. Gitの初期設定 Mac だとターミナル、 Windows だとGit Bash での作業です。 Gitでは ソースコード の変更履歴を確認できますが、「誰が」変更したかを確認するための情報が必要となります。 この作業者を識別するための情報として、ユーザ名とメールアドレスを登録する作業を行います。 ユーザ名 以下のコマンドを入力してください。 git config --global user.name 任意のユーザ名 メールアドレス 以下のコマンドを入力してください。 git config --global user.email 任意のメールアドレス 最後に以下のコマンドを入力すると、上記のユーザ名とメールアドレスが登録されていることを確認できます。 $ git config --list core.symlinks=false core.autocrlf=false color.diff=auto ・ ・ 中略 ・ ・ user.name=設定したユーザ名 user.email=設定したメールアドレス ・ ・ 1-3. GitHub のアカウント作成 次に GitHub にアカウントを作成してみましょう。 GitHub へアクセスし、ユーザ名・メールアドレス・パスワードを入力し、「 Sign up for GitHub 」ボタンをクリックします。 次に以下の画面で「Verify your account」の設問に回答後、「Join a free plan」を選択します。 次に「Welcome to GitHub 」と表示された画面へ進みますが、一番下まで進み、 「Complete setup」ボタンをクリックしてください。 ~~ 中略 ~~ 最後にこちらの画面が表示され、入力したメールアドレスへ認証用のメールが配信されます。 メールを確認の上、認証を行ってください。 ここまでで GitHub のアカウント作成は完了です。 1-4. リモー トリポジ トリを作成する GitHub にアクセスし、リモー トリポジ トリを作成します。 トップ画面で「Create Repository」ボタンをクリックしてください。 リポジトリ 作成画面に移動します。 以下の画面では、「Repository name」には任意の リポジトリ 名を入力します。 ※ここでは例として、「rakus」という リポジトリ 名を入力します。 次に リポジトリ の種類として、「Public」か「Private」を選択します。 GitHub では長らく有料会員のみ「Private」を選択できていましたが、2019年からFreeプランでも「Private」を作成できるようになりました。 今回はどちらを選択いただいても構いません。 「Public」を選択した場合:他のユーザーが ソースコード を閲覧することが可能となります。 「Private」を選択した場合:非公開となります。 次に「Initialize this repository with a README」ですが、 リポジトリ の説明や使い方を記述するREADMEファイルを事前作成しておく場合にはチェックをONにします。 最後の「.gitignore」や「license」は None を選択で構いません。 最後に「Create repository」ボタンをクリックすると、 リポジトリ が作成されます。 1-5. ローカル リポジトリ を作成する 次にローカル リポジトリ を作成していきます。 ※記事では例として「rakus」という ディレクト リを作成します。 その後、 git init コマンドを入力することで、作成した ディレクト リをgit リポジトリ として初期化します。 コマンドは作成した ディレクト リ上で実施する必要がある点に注意してください。 git init 1-6. ローカル リポジトリ にコミットする コミット(commit) とは、ファイルの追加・変更をローカル リポジトリ に反映する操作を意味します。 実際にローカル リポジトリ にファイルを追加してみましょう。 まずは1-5で作成した ディレクト リ配下で「index.html」というファイルを作成します。 テキストエディタ などでファイルを作成してください。 この状態ではファイルを作成しただけですので、まだ リポジトリ にはファイルは追加されていません。 次に以下のコマンドを入力し、インデックスへ「index.html」を追加します。 インデックスとは、コミット前に変更内容を一時的に保存する領域を指し、インデックスに追加されたファイルのみがコミットの対象となります。 git add index.html 最後に、インデックスへ追加したファイルをコミットします。 以下のコマンドを入力すると、インデックスに存在するファイルがローカル リポジトリ へ追加されます。 git commit -m "[Add] index" ここで -m はコミットメッセージを入力するためのオプションです。 コミットメッセージを残すことでより詳細な履歴情報を残すことができ、後々ログからコミット内容を確認する際に役立ちます。 積極的に活用しましょう。 また、コミットメッセージを含めた変更履歴(ログ)は、以下の git log コマンドを入力することで以下のように確認できます。 $ git log commit 6a8e257...コミットハッシュ.....642e3 (HEAD -> master) Author: ユーザ名 <メールアドレス> Date: Tue May 26 18:45:56 2020 +0900 [Add] index 1-7. リモー トリポジ トリにプッシュする 最後にローカル リポジトリ の変更を GitHub 上のリモー トリポジ トリに反映する プッシュ(push) を行います。 まずはローカル リポジトリ とリモー トリポジ トリを紐づけをするために、ローカル リポジトリ 配下で以下のコマンドを入力します。 git remote add origin https://github.com/ユーザ/[作成したリポジトリ].git これでリモー トリポジ トリの情報がローカル リポジトリ に登録されました。 次にローカル リポジトリ の変更内容をリモー トリポジ トリに反映させるため、以下のコマンドを入力してプッシュを行います。 GitHub のユーザ名とパスワードを求められますので、アカウント登録時に設定した内容を入力してください。 git push origin master これでリモー トリポジ トリへ反映させることができました。 GitHub でも変更内容が反映されていることが確認できます。 ※ GitHub 上に公開鍵情報を登録することで、プッシュ時にユーザ名とパスワードを都度入力する手間を省くことができます。 詳細な手順は割愛しますが、興味のある方は調べてみてください。 git commit、git stashのやり方を知りたいという方は以下ブログも参考に下さい。 ・ 【Git入門】git commitを取り消したい、元に戻す方法まとめ - RAKUS Developers Blog | ラクス エンジニアブログ ・ 【Git入門】git stashで作業を便利に退避する - RAKUS Developers Blog | ラクス エンジニアブログ 2. Gitと GitHub を使ったチーム開発の超入門 ここまでGitと GitHub 基本的な使い方を紹介してきましたが、チームで他のメンバーと開発を行う際の使い方についても、基本的な操作を紹介していきたいと思います。 Gitには ブランチ(branch) という仕組みがあり、チーム開発を行う際にはブランチを使いこなす必要があります。 2-1. リポジトリ をクローンする あなたが新たに開発現場に参加することになった場合、すでに存在するリモー トリポジ トリから ソースコード を取得することになります。こちらの作業を実施してみましょう。 先ほど作成した ディレクト リとは別の ディレクト リ(当記事では「rakuraku」とします)を作成し、以下のコマンドを実行してください。 コマンドは作成した ディレクト リ上で実施する必要がある点に注意してください。 git clone https://github.com/ユーザ名/[作成したリポジトリ].git 新しく作成した ディレクト リ(rakuraku ディレクト リ)上に先ほどプッシュした index.html が表示されたかと思います。 このようにリモートから リポジトリ から取得する作業を クローン(clone) と呼びます。 2-2. ブランチを作成する ソフトウェア開発では同時進行で複数のバージョンの開発が行われることは珍しいことではありません。 また突発的なバグ対応が発生することもあり、こちらも新たにリリースするバージョンとは別軸で対応する必要が出てきます。 これらを並行しつつ開発を実現するための仕組みとして、Gitには ブランチ(branch:枝、枝分かれ) という機能が提供されています。 以下の図に示すようにブランチを使い、変更履歴を分岐した開発を実現することができます。 ブランチを作成するには、 git branch コマンドを使います。 例として、現在作業中のブランチ(デフォルトで存在するブランチを「master」と呼びます)から「feature1」というブランチを作成してみます。 以下のようにコマンドを入力してください。 git branch feature1 これでmaster からfeature1 ブランチが作成されました。 次にfeature1 ブランチ上で作業を行うために、checkoutコマンドを入力してブランチを移動します。 git checkout feature1 ここで git branch コマンドを入力すると、現在ローカル リポジトリ 上に存在する「master」と「feature1」というブランチが表示されます。 「*」は作業を行っているブランチを示しています。 $ git branch * feature1 master 2-3. ブランチでコミットする feature1ブランチでの作業として、今度はlogin.htmlというファイルを作成してみます。 作成したlogin.htmlをfeature1ブランチにコミットします。 以下のコマンドを入力してください。 git add login.html git commit -m "[Add] login" 2-4. リモー トリポジ トリにプッシュする 次に、リモー トリポジ トリ( GitHub )にもfeature1ブランチの内容を反映します。 1-7の手順と異なり、push先のブランチが feature1 になっている点に注意してください。 git push origin feature1 GitHub にアクセスすると、2つのブランチ(master と feature1)が存在することが確認できます。 またfeature1 ブランチには変更内容がプッシュされたことが確認できます。 逆にプッシュ先ではないmaster には変更内容が反映されていないことも確認できます。 2-5. コードレビュー・マージ ブランチでの開発作業が完了しましたら、メインとなるブランチ(一般的には master)に変更内容を取り込み、開発内容を統合します。 このように特定のブランチの変更内容を別のブランチに取り込むことを マージ と呼びます。 このマージを行う際、 GitHub 上では プルリク エス ト と呼ばれる機能を使い、コードレビューを行うことができます。 指摘がある場合にはコメントを追加し、作業者に修正を促すことができます。 こちらの概要についても説明します。 レビューの依頼 まずは Github 上でfeature1ブランチを開き、「New Pull Request」をクリックします。 次にプルリク エス トを作成します。 以下の点を確認・入力の上、「Create pull request」ボタンをクリックしてください。 ① マージ元・先のブランチ ② レビュアー(レビューを行う人) ③ レビュー内容 ④ レビュー・マージ対象の ソースコード レビューの実施 プルリク エス トを受取ったレビュアーは「Pull requests」タブを開き、「Files changed」から ソースコード を確認します。 指摘がある場合には、 ソースコード のビュー上にコメントを追加し、開発者へ修正を促します。 内容に問題がなければ、「Conversation」の「Merge pull request」をクリックしてレビューを完了します。 このタイミングでブランチのマージも実施され、feature1 の内容が master にも反映されます。 マージを行ったことで、login.html が master 上にも表示されることが確認できます。 実際のレビューでは、開発する機能やバグ修正の複数の ソースコード をプルリク エス トで確認することとなります。 また指摘が発生し、何度も開発者とレビュアーとの往復が発生することも珍しくはありません。 こちらの基本的な流れをベースに、実務でのコードレビューに臨んでいただければと思います。 2-6. リモー トリポジ トリからプルする リモー トリポジ トリの master にはマージが行われましたが、あなた(および他の開発者)のローカル リポジトリ 上の master にはまだマージ内容が反映されていません。 今後も開発作業を進めていくには、マージした内容(ここでは login.html )をローカル リポジトリ の master に取得し、最新化する必要があります。 この場合、 プル(pull) という操作を行うことで、リモー トリポジ トリから変更内容を取得することができます。 まずはブランチをmaster に切り替えてみましょう。 この時点ではまだ先ほどマージしたlogin.html が確認できないはずです。 git checkout master 次に git pull コマンドを実行し、リモー トリポジ トリのmaster から最新の変更内容を取得します。 git pull remote: ・・・・ ・ ・ ・ From https://github.com/ユーザ名/[作成したリポジトリ] f5・・27 e4・・0f master -> origin/master Updating f5・・27 e4・・0f Fast-forward login.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 login.html これでローカル リポジトリ のmaster には、リモー トリポジ トリの最新の内容が反映されました。 ls コマンドを実行すると、login.html を確認することができます。 またgit log コマンドを入力することで、これまでの全作業の変更履歴を確認することもできます。 $ ls index.html login.html $ git log commit 99c9637・・・・5281c0e (HEAD -> master, origin/master, origin/HEAD) Merge: f5・・27 e4・・0f Author: ユーザ名 Date: Fri May 29 19:28:48 2020 +0900 Merge pull request #1 from リポジトリ名/feature1 [Add] login commit e4ccb0fa2・・・・・3e33b983c0 (origin/feature1, feature1) Author: ユーザ名 <メールアドレス> Date: Fri May 29 19:26:08 2020 +0900 [Add] login commit f5dbc270a・・・・・735f93a53d90a1c1068 Author: ユーザ名 <メールアドレス> Date: Tue May 26 18:45:56 2020 +0900 [Add] index このようにして他の開発者が変更した内容も取得することで、チームでの開発を進めていくことができます。 まとめ Gitと GitHub の超入門として、概要を紹介しました。 Gitも GitHub もここだけでは全てを紹介し切れない奥が深いツールになります。 今回紹介しました基本的な内容をベースに、より理解を深めていっていただければ嬉しいです。 ではでは。   エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 https://rakus.hubspotpagebuilder.com/visit_engineer/ rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
アバター
こんにちは。badaikiです。 新型コロナウィルスの影響で ラク スも緊急事態宣言の発令に伴い、感染防止のためリモートワークに移行しておりました。先日のブログでは、 ラク ス社員がリモートワーク中にどのような工夫をして効率を上げていたのかについてまとめられていました。私も仕事以外の時間には業務用PCを見えない場所に片づけるようにしてメリハリをつけながら、週に3、4回ほど夜中にランニングをするなど体調管理に気を付けていました。 tech-blog.rakus.co.jp はじめに オンライン勉強会のメリット 参加した勉強会の紹介 おわりに はじめに 私は一人暮らしのため業務外の時間になると、世間から遮断されたように誰とも会話することもなく誰の声を聞くこともなく、ただただ暇つぶしにテレビを観たりゲームをしたりといった自粛生活を送っていました。 今回のブログでは、そんな空いた時間を活用しようと参加したオンライン勉強会を紹介していこうと思います。 恥ずかしながら、これまで他社の勉強会に参加したことがありませんでした。勉強会に参加しないとな、、、という意思は持っていたものの参加できていなかったのですが、手始めにオンライン勉強会に参加してみよう!と思い立ち、申し込みボタンをクリックしました。 オンライン勉強会のメリット 勉強会には参加したほうがいいとはわかっているものの、なかなか行動に移せていない人も多いのではないかと思います。そこで オンライン勉強会のメリット を挙げてみます。 移動しなくていい リモートならではですよね。PCを立ち上げてURLをクリックするだけでいいんですから!普段なら参加できない遠方の勉強会に参加できるのも魅力ですよね! 懇親会がない これは良し悪しありますが、勉強会に参加できていない理由の一つとしてコミュニケーションが心配という方もいらっしゃるのではないでしょうか。 時間が短い 私が参加したものだと30分のものもありました。普段の勉強会だと移動時間+開催時間で最低でも3時間くらいはかかってしまうので、手頃ですね! ラジオ感覚で聞ける これは自分が参加してみて一番感じました。オフラインの勉強会と比べてかなり気軽に聞けるのはとても大きいと感じました。 この自粛期間を利用して4つの勉強会に参加させていただいたのですが、中には退勤した直後から参加したり、 トークショー だと夕飯を作りながら聞いていたものもありました。 参加した勉強会の紹介 freee Tech Night Online #1「ふりてくおんらいん」 freee-tech-night.connpass.com こちらはfreee株式会社主催の トークショー でした。情シスの方が「リモートワーク開始の裏側をゆるーく語る」をテーマに トーク を繰り広げられていました。テーマの通りゆるーく会話されていましたが、内容はなかなか相当壮絶なものでした。普段は聞けない話が多く、とても新鮮でした。 ラク スも情シスなどの方々が動いてくださって不便なくリモートワークへ移行できましたので、本当に感謝です。 Cybozu Tech Meetup #1 kintone開発チーム cybozu.connpass.com こちらは サイボウズ 株式会社主催のMeetupでした。kintone開発チームの内情について、開発チームの方やQAチームの方の発表を聞くことができました。kintoneチームがどのようにリモートでモブプロを行っているのか、新卒エンジニアやIT業界未経験QAエンジニアがどのように立ち上がったのかという内容でした。私は新卒入社のため、新卒エンジニアさんの発表に注目しておりました。学生時代に手あたり次第気になった技術を触っていたそうで、1つのサービスを突き詰めていくマインドをどのように育んでいくかという内容でした。新卒社員の多くが通る悩みだと思いますので、新卒社員やこれから入社する学生にも見ていただきたい発表でした! 【オンライン】関西 PHP 勉強会 phpkansai.connpass.com こちらは「 PHPカンファレンス 関西2020」がコロナの影響で中止となったため、PHPer同士の交流の場を増やしたいというのを目的としたLT会でした。個人的に興味を持ったのは「PhpStorm中級入門」と「LaravelでDB操作を監視する」ですね。PhpStormを使い始めて約2年になりますが、まだまだ使いこなせていないなーと感じました。DB操作の監視は知らない技術だったため、興味を持ちました。顧客との「何もしてないのに壊れた」のやりとりのとき、皆さんの共感がすごかったですねw 「関西 PHP 勉強会」ではありますが、全国からPHPerが集まっていてオンラインの良さが際立っていました! 【オンライン】PHPerによるPHPerのための「 PHP のニュースや記事を語り合う」TechCafe rakus.connpass.com こちらは弊社 ラク スが主催のLT& トークショー でした。普段は、弊社オフィスに来社頂き、特定のテーマについてディスカッションやもくもく自習などを行っているのですが、初のオンライン開催となりました。 トーク テーマは「 PHP のニュースや記事を語り合う」ということで、 ラク スのエンジニアが気になった記事を持ち寄って紹介し トーク を繰り広げるというものでした。一人でもくもくと情報収集するのもいいですが、ほかの人に共有して意見交換するのも自分と違った観点での意見が聞けたりするのでおもしろいなと感じました。 おわりに 以上が私が自粛期間中に参加したオンライン勉強会でした。 トークショー やLT会など様々な内容の勉強会に参加させていただきました。まだしばらくはオンラインの勉強会が開催されると思いますので、どんどん参加していきましょう!私も積極的に参加し、オフラインの勉強会にも参加していくようにします! 最後まで読んでいただきありがとうございました!
アバター