TECH PLAY

株式会社ラクス

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

935

こんにちは ラク スの iketomo です。 今回は アジャイル 開発( Agile ) について紹介させていただきます。 アジャイル 開発の特徴や ウォーターフォール と比較、弊社での スクラム の取組事例などを紹介させていただきます。 皆様が アジャイル 開発手法をどう取り入れるべきかのご参考になればと思います。 ① アジャイル開発とは? アジャイルソフトウェア開発宣言 ② アジャイル開発の特徴とウォーターフォール開発との違い 戻らないことを前提としたウォーターフォール 戻ること(仕様変更)を前提としたアジャイル開発 開発サイクルの違い ③ アジャイル開発のメリット・デメリット アジャイル開発のメリット アジャイル開発のデメリット ④ アジャイル開発で気を付けるべきこと アジャイル開発≠ドキュメントを作らない 適時のコミュニケーションと確認 顧客にチーム参画してもらう ⑤ スクラムの取組事例 配配開発チームでのスクラムの取り組み 不確実性の低減 改善文化の醸成 楽楽明細開発チームのスクラムの取組 失敗から学びとスクラムとウォーターフォールの融合 ⑥ アジャイル開発の関連書籍の紹介 SCRUM BOOT CAMP THE BOOK アジャイルサムライ みんなでアジャイル アジャイルレトロスペクティブズ Fearless Change アジャイルに効く アイデアを組織に広めるための48のパターン スクラムガイド アジャイルマニフェスト ① アジャイル 開発とは? アジャイル には「素早い」や「機敏」という意味があります。 従来の ウォーターフォール モデルと呼ばれる開発手法が「技術や環境の変化」に対して仕様変更を即応することが難しくなる側面がありました。 アジャイル 開発はそのような煩わしさから解放されるために作られた開発手法になります。 アジャイル 開発の基本概念はあまりに有名すぎるので、割愛させていただきリンクだけ張らせていただきます。 アジャイル ソフトウェア開発宣言 agilemanifesto.org ② アジャイル 開発の特徴と ウォーターフォール 開発との違い 戻らないことを前提とした ウォーターフォール ウォーターフォール では基本的に各工程(要件定義・概要設計・詳細設計)は一方通行で戻らないことを前提としています。 ウォーターフォール 開発において工程が戻るということは、大きなリソースを消費することになるため、避けなければいけません。 そのため 各工程では入念にレビューやチェック、関係者の承認を得て 進むことになります。 ただ開発をしたことがある皆様はわかると思いますが、どれほど入念にレビューしても後工程で問題が発生し仕様変更をしなければいけないことは現場ではよくあります。 例えば実装フェーズで仕様に問題があった時に「概要設計」「詳細設計」まで戻って修正し さらには実装前にテストケースまで作っていた場合、ほとんどのテストケースを作り直しということもあり そういった場合、そこまでに使っていた大きなリソースを無駄にしてしまうこともあります。 また実際に開発完了して顧客に 検収 してもらうと「まったく思っていたものと違う」と言われて呆然としまうこともあるでしょう。 そこで アジャイル 開発の登場です。 戻ること(仕様変更)を前提とした アジャイル 開発 アジャイル 開発では 戻ること(仕様変更)を前提 としています。 そのため、 ウォーターフォール に比べ重厚なチェックなどは行わずに ある程度仕様が纏まったら、とりあえず作って、実物を見てもらいチェックしてもらおうという進め方になります。 見てもらう相手(承認者)は開発内部だけではなく、場合によっては顧客を含めることもあります。 承認者から違うと言われ、仕様変更になれば即対応を行います。 なぜそれができるかというと 開発サークルの単位が小さい からです。 開発サイクルの違い アジャイル 開発では イテレーション (スプリント)と呼ばれる小さいサイクルの開発を反復して行います。 通常 イテレーション は 1週間~長くても1カ月位の単位 で反復して機能追加を行っていきます。 各 イテレーション の中で設計・実装・テストを行い、必要であれば承認者(顧客も含むこともある)に実際の機能を見てもらうことになります。 見てもらった時に、もし予定外の機能要望や変更等があれば、また イテレーション のサイクルを繰り返すことになりますが、小さいサイクルなので問題がありません。 ③ アジャイル 開発のメリット・デメリット アジャイル 開発のメリット 前述していますが、 アジャイル 開発の大きなメリットは 不具合や仕様変更が発生した時の手戻り・ 工数 が少ない ことです。 これにより柔軟に顧客の要望を取り入れやすく、 顧客ニーズに最大限に答えることができます。 また 要件がはっきり決まっていない案件 でも作りながら見てもらいながら開発を進めることができるのでそういった案件には アジャイル 開発が向いているでしょう。 アジャイル 開発のデメリット 全体のスケジュール・予算が見えずらい アジャイル 開発では開発初期に全体のかっちりした仕様を決めずに、仕様変更を許容しているため、全体像がぼやけています。 仕様変更・追加を繰り返していくと、当初計画から大きくスケジュールがずれてしまうこともあります。 この点については下記の対策をする必要があります。 ・仕様変更などを考慮し、バッファをもったスケジュールにしておく ・全体進捗を監視し最終的な納期に間に合うかどうかを常に判断する ・顧客とスケジュールのずれについて合意しておく 開発 工数 が大きくなったり、スケジュールが伸びてくると、予算・リソースについても同様のことが言えます。 全体が見えずらいため、ある時に予算オーバーとなってしまった。開発リソースが確保できなくということもあり得ます。 ・仕様変更・追加に伴い予算追加の議論ポイントについて顧客と合意する ・リソースが大きくなった時に、確保できるように関係各署と交渉しておく といった前準備が必要になるでしょう。 アジャイル 開発と ウォーターフォール 開発のメリット・デメリットを整理すると、以下の表のようになります。 ④ アジャイル 開発で気を付けるべきこと アジャイル 開発≠ドキュメントを作らない ウォーターフォール のように重厚なドキュメントを作るということではありませんが アジャイル 開発においても場合に応じて各種ドキュメントを作成し、要求者と認識が合っているかを確認することが必要です。 適時のコミュニケーションと確認 小さいサイクルだから作った後に見てもらえば大丈夫!!という考え方は間違っています。 小さいサイクルと言えども、何度も繰り返し修正が積み重なると、大きなリソースを失いますし、進捗せずにスケジュールが伸びてしまいます。 あれ?と迷った時や疑問に感じるならば、即時で各関係者へ確認することによって、修正の度合いを減らすことができます。 どちらのケースでも言えますが、仕様変更・追加があっても修正するから確認しなくても大丈夫。 ということではなく、あくまで修正は少ない方が良いという考え方をバランスよく持ち合わせる必要があります。 顧客にチーム参画してもらう 顧客が忙しくて見ることができません。最後にできたものを見ます。という状態に陥ると アジャイル 開発の意味をなさなくなります。 開発前にしっかりと顧客と事前合意して、チームの一員となってもらい、各 イテレーション ごとの成果物を見てもらいましょう。 ⑤ スクラム の取組事例 スクラム とは アジャイル 開発の手法を取り入れた フレームワーク の1つで最も有名な開発手法の1つになります。 弊社で実際に スクラム 開発手法を取り入れたチームの状況を説明させていただきます。 配配開発チームでの スクラム の取り組み 不確実性の低減 スクラム 導入前の開発チームはスケジュールの遅延が多発し、メンバーは 疲労 していたのですが スクラム 導入によって、チームで少しずつ解消していきました。 ただ、導入当初はタスクを順番通りに進めていくという ウォーターフォール 的な進め方で開発していたため、重要なタスクが後の方に残ったり、個人の遅れがそのままチームの進捗遅れに繋がってしまっていました。 これを打破するため 1週間毎のスプリント反復開発 と カンバン を導入しました。 カンバンによって終わらないタスクが可視化され、終わらないタスクは スウォーミング(問題のある所に人が集まり解決する) でチームで解決していきました。 1週間毎に計画・振り返りを行うことで、プロジェクトが進むごとに計画の不確実性が低減していくという良い循環になりつつあります。 改善文化の醸成 スプリント毎の振り返りで改善のア イデア を出し合うことを反復することでチームメンバーに改善の文化が醸成されていきました。 こういった意識が芽生えたことで 「顧客から始める」という アジャイル 原則 に回帰し チームの在り方、将来のロードマップを作るという、より本質的な改善を行うことができました。 詳細な記事は下記をご覧ください。 speakerdeck.com speakerdeck.com 楽楽明細開発チームの スクラム の取組 失敗から学びと スクラム と ウォーターフォール の融合 楽楽明細の開発チームでは2019年春~ スクラム の取り組みを始めました。 スクラム を取り入れたものの当初は大きな課題にぶつかってしまいました。 開発した成果物を営業・企画に見てもらうと 「思っていた機能と全然違う!!」 と言われてしまい 大きな仕様変更が発生 。 「多分こうだろう。違ってもスプリントごとに見てもらえるからまぁ大丈夫か。」といった過信が原因です。 そこで 「小さめの案件は今まで通りの アジャイル 開発」 「大きめの機能は ウォーターフォール と アジャイル の融合」 といったやり方に方針変更。 大きめの機能は要件定義の段階で前よりは詳細に設計を進めることにしました。 今では小さな手戻りはあるものの 大きな手戻りはなくなり効率よく開発 を進める事ができています。 ・ スクラム の取組で良かった点 昔は開発メンバーが増えてきたが 1人の熟練技術者に設計が依存していて ボトルネック になることが課題でした。 アジャイル 開発手法の導入で設計フェーズが軽量化されたことにより ボトルネック が分散され 全体の開発力・スピード が向上することができました。 また営業・企画がスプリントごとにフィードバックしてくれることで、営業・企画との連携・風通しが良くなってます。 詳細な記事は下記をご覧ください。 speakerdeck.com ⑥ アジャイル 開発の関連書籍の紹介 SCRUM BOOT CAMP THE BOOK スクラム のことを知るならまずこの本。 アジャイル の必読入門書。 www.shoeisha.co.jp アジャイル サムライ アジャイル とセットで語られる事が多い手法やプ ラク ティスが一通り網羅されており、 アジャイル のマインドや全体像を抑えることができる、 アジャイル の現場の教科書。 shop.ohmsha.co.jp みんなで アジャイル 手法が中心の書籍が多い中で、顧客からはじめるのが アジャイル であると言い切っている点で貴重な書籍。 www.oreilly.co.jp アジャイル レトロスペクティブズ アジャイル に挑戦するときに多くの人が最初に取り組み、馴染み深いが実は奥が深い「ふりかえり」にスポットを当てた、ふりかえりの教科書とも言うべき書籍。 shop.ohmsha.co.jp Fearless Change アジャイル に効く ア イデア を組織に広めるための48のパターン アジャイル に取り組む中で直面する様々な課題に向き合うためのマインドや行動様式を48のパターンを通して学ぶことができる。 www.maruzen-publishing.co.jp スクラム ガイド 言わずと知れた スクラム のルールブック。 スクラム 実践者の多くが経験を積めば積むほど結局ここに立ち戻るとも言われている。 https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf アジャイル マニフェスト アジャイル の原典にして原点。 agilemanifesto.org 今回ご紹介した アジャイル 開発のご紹介が、これから アジャイル 開発を導入を検討されている方々の一助となれば幸甚です。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに Webスクレイピングの基本事項 Webスクレイピング(Scraping)とは Webスクレイピングの活用シーン Webスクレイピングの基本的な仕組み Webスクレイピングの注意事項 取得先への攻撃とみなされたり、規約違反や、著作権法違反に問われることもある 取得先の変更に影響を受ける 取得先がAPIを公開しているならそちらを活用する方が良い Webスクレイピングの実践方法 Webスクレイピングを実践するには 1. ベンダーのサービスやツールを利用する 2. 自分でプログラムを作成する なぜPythonなのか? Pythonでのスクレイピング実践方法 事前準備 BeautifulSoup4のインストール 模擬Webサイトの構築 Webサーバーを立ち上げる 初級編:特定の要素から単一の要素を抜き出す 中級編:あるページから繰り返しを伴う複数の要素を抜き出す 上級編:複数のページから複数の要素を抜き出し、CSVに出力する おわりに はじめに みなさんこんにちは。フジサワです。 みなさんも一度や二度は、インターネット上の情報を収集して分析するという作業を行ったことがあるのではないでしょうか。 調べる対象のWebサイトが数ページくらいであれば、ブラウザを開いてコピー&ペーストを繰り返すだけでもなんとかなりますが、 対象が数十、数百ともなると、途端に人力で情報収集を行うことが難しくなります。 こうした時に用いられるのが「Web スクレイピング 」という手法です。 先日、とあるWebサイトから情報を集めて分析するという作業をやっていたのですが、チマチマ手作業でやろうとするも精神的に限界を迎えたので、Web スクレイピング してうまく情報を集められないかと考えました。 ところが、 簡単なWeb スクレイピング であれば、さほど技術的に難易度の高いものではないのですが、調べてみると、意外とWeb スクレイピング には法要件など、技術面以外で注意しなければならないポイントが多いようです。 そこで、本稿では「Web スクレイピング とは何なのか?」「Web スクレイピング で気を付けなければならないこと」などの基本事項と併せて、「 Python を用いてWeb スクレイピング を実践するにはどうすればよいのか」といったあたりを解説したいと思います。 特にエンジニア諸氏におかれては、「あまり意識せずにWeb スクレイピング していた」人も少なくないのではないでしょうか? Web スクレイピング について初めて学ぶ方はもちろん、既に実践されている方も、本稿を読んで改めてWeb スクレイピング について整理して頂けると幸いです! Web スクレイピング の基本事項 Web スクレイピング (Scraping)とは Web スクレイピング とは、Webサイトに含まれる情報から必要なものを抽出する技術・行為を指すものです。 ※なお、本稿では「Web」 スクレイピング と正確に記載するようにしていますが、単に「 スクレイピング 」と呼ぶ場合も、おおよそWeb スクレイピング を指していることが多いと思います。 Web スクレイピング と並んで、よく耳にする言葉に、Webクローリング(Crawling)というものがありますが、これは、あるURLを基に、そのWebページに含まれているリンクを辿りながら、情報を収集する仕組みを指します。 ちょっとややこしいですが、この両者の違いは「 クローラー が集めた情報を スクレイピング する」という文章にすれば、より分かりやすいのではないでしょうか。 Web スクレイピング の活用シーン Web スクレイピング の基本的な狙いは、膨大な情報の収集を手作業ではなく自動化することにより業務を効率化することです。 主な活用シーンとしては次のようなものが挙げられます。 マーケティング や研究分野におけるデータ分析 機械学習 におけるモデル作成のための学習データとして Web スクレイピング の基本的な仕組み Web スクレイピング の基本的な仕組みは次の通りです。 あるWebサイトからHTMLデータを取得する HTMLデータをタグ構造に従って分解・分析(パース)する 目的となる情報を選び出し、ファイルやDBに保存する 1.~3.のプロセスを、複数のページに対して繰り返して実行する Web スクレイピング の注意事項 Web スクレイピング はデータ収集を行う上でとても強力な手段ですが、注意しなければならない点がいくつかあります。 取得先への攻撃とみなされたり、 規約違反 や、 著作権法 違反に問われることもある 取得先への攻撃 Web スクレイピング はプログラムが自動で実行するという性質上、人間には不可能な大量のリク エス トをデータの取得先に送信することができてしまいます。 しかしながら、短時間に大量のリク エス トを送信することは、取得先のサーバーの処理を遅延させ、場合によってはサーバーをダウンさせるなどの損失を与えてしまいます。過去に、この件で逮捕されてしまった事例などもあるので、慎重に考える必要があるでしょう。 では、どれくらいの頻度であれば許容されるのかというと、残念ながら明確な基準はありません。 Webサイトの運営者が robots.txt を設置している場合は、クロールして良いURL/良くないURLや許容するアクセス頻度について明言されている場合がありますので、そちらも確認しましょう。 robots.txt …Webサイトの運営者が、 Google などの 検索エンジン の クローラー 向けに配置するファイル。通常は、対象 ドメイン のルートに配置されます。(例: https://xxxx.example.com/robots.txt ) 利用規約 違反 Webサイトによっては、明確に スクレイピング することを禁止しているものも存在します。 スクレイピング する際には、十分に取得先のWebサイトの 利用規約 を確認するようにしましょう。 著作権法 違反 Web スクレイピング の対象となる情報に 著作権 が生じている場合、活用方法を誤ると 著作権法 違反となりますので注意が必要です。 なお、 著作権法 では、第三十条の四にて「情報解析の用に供する場合」は 著作権 者の承諾なく利用することができるとされています。 活用事例として挙げた「マーケテイングや研究分野におけるデータ分析」や「 機械学習 におけるモデル作成のための学習データ」として スクレイピング した情報を活用することは問題ないと言われています。 ※筆者は法律の専門家ではないので、この点については改めて十分に確認されることをお薦めします 取得先の変更に影響を受ける スクレイピング の基本的な仕組みは、「HTML要素を特定のパターンに沿って抽出する」ことですので、データの取得先の仕様変更やデザイン変更によって、HTML構造が変わり、うまく抽出できなくなってしまうことがあります。 スクレイピング が上手く処理されない場合は、取得先のHTML構造に変化がないか確認し、調整をする必要があります。 そのほか、 スクレイピング が過度に相手先に負荷をかけていなかったとしても、相手先の通信拒否リストに載ってしまい、 スクレイピング ができなくなるような場合もあります。 取得先が API を公開しているならそちらを活用する方が良い ここまで述べたとおり、Web スクレイピング にはセンシティブな問題や面倒ごとがつきまといますので、データ取得先が API で必要な情報を公開している場合は、そちらを活用する方が安全だと思います。 本当にWeb スクレイピング する必要があるのかどうかをまず考えましょう。 もちろん、 API を利用する際にも、 利用規約 があればしっかり確認してくださいね。 Web スクレイピング の実践方法 Web スクレイピング を実践するには Web スクレイピング を実践するには、次のいずれかを選択することになります。 1. ベンダーのサービスやツールを利用する ベンダーが提供しているサービスはとても種類が多く、紹介しきれないので、ここでは簡単に導入できる Chrome 拡張をいくつか紹介します。 Instant Data Scraper 複数ページにまたがる一覧画面からの スクレイピング に特化した拡張で、起動すると自動で画面上の一覧要素を判定して抽出してくれます。あとは、次のページに進むボタンがどれかを指示するだけで、自動で スクレイピング してくれます。 Scraper とてもシンプルな スクレイピングツール 。ブラウザ上の右クリックメニューから実行できるなど、現在表示しているサイトの情報を簡易的に抽出したい場合には手軽に活用できます。 Web Scraper 複数ページに対するクローリングの設定や、動的ページへの対応など、使い方を覚えるのに少し時間が必要な半面、自由度が高く高機能な スクレイピングツール です。 2. 自分でプログラムを作成する Python や Java , PHP , Ruby といったプログラム言語を用いて、 スクレイパー を作成する方法です。 費用もかからず、自由度も高いため、簡単な スクレイピング 処理であれば、慣れているエンジニアにとってはベンダーのサービスやツールを使用するよりも手軽かもしれません。 仮に、ベンダーのサービスやツールを利用する場合であっても、内部で動作しているプログラムの基本的な考え方は同じですので、ツールの機能を理解するために、 スクレイパー の実装を把握しておくのも良いのではないでしょうか。 それでは、実際に Python でWeb スクレイピング をするプログラムを作成してみましょう。 なお、本稿では、 Python のバージョンはPython3系を用いて解説していますが、Python2系をお使いの方はご了承ください。 なぜ Python なのか? Python 以外の言語でも同様のことは実現できるのですが、 Python の場合、Web スクレイピング を実現するために必要なライブラリや書籍などが豊富だからです。 Python での スクレイピング 実践方法 Python でWeb スクレイピング を実現する方法は様々です。 本稿では、比較的ベーシックな作り方である、 Python ライブラリの「 BeautifulSoup4 」を使用した実践例を解説します。 他の方法としては、「Scrapy」というWeb スクレイピング に特化した フレームワーク を用いる場合や、「 Selenium 」などの Webブラウザ を動作させて実行するライブラリを用いる場合、あるいは少しWeb スクレイピング の本流からは離れますが、「Pandas」を用いたデータ解析などが挙げられます。 事前準備 BeautifulSoup4のインストール HTMLの解析を行うライブラリに、もっとも定番のライブラリと言われている「BeautifulSoup4」を使って解説します。 「BeautifulSoup4」は次のようにインストールすることができます。 なお、今回のサンプルでは、対象のWebサイトにアクセスするためのライブラリとして、こちらも Python では定番となっている Requests を使用するので、併せてインストールしています。 ※ Python 実行環境の構築や、pip( Python のライブラリ管理ツール)の導入については本稿では触れませんのでご了承ください。 $ pip install beautifulsoup4 requests 模擬Webサイトの構築 それでは、 スクレイパー を実装するにあたり、模擬的なデータ取得元のWebサイトを構築しましょう。 次のファイルを、 Python を実行する ディレクト リと同じ階層に配置してください。 index.html < html > < head >< meta charset = "utf-8" />< title > フルーツショップ </ title ></ head > < body > < h1 > 商品一覧 </ h1 > < ul class = "fruits_list" > < li >< a href = "http://localhost:8000/apple.html" > りんご </ a ></ li > < li >< a href = "http://localhost:8000/grape.html" class = "new_item" > ぶどう </ a >< span style = "color:red" > 新商品! </ span ></ li > < li >< a href = "http://localhost:8000/banana.html" > バナナ </ a ></ li > </ ul > </ body > </ html > apple .html < html > < head >< meta charset = "utf-8" />< title > 商品 </ title ></ head > < body > < p id = "item_name" > りんご </ p > < p id = "item_price" > 100円 </ p > </ body > </ html > grape.html < html > < head >< meta charset = "utf-8" />< title > 商品 </ title ></ head > < body > < p id = "item_name" > ぶどう </ p > < p id = "item_price" > 200円 </ p > </ body > </ html > banana.html < html > < head >< meta charset = "utf-8" />< title > 商品 </ title ></ head > < body > < p id = "item_name" > バナナ </ p > < p id = "item_price" > 79800円 </ p > </ body > </ html > Webサーバーを立ち上げる 上記のファイルを配置した ディレクト リで、下記のコマンドを実行して、 Python のビルトインサーバー機能を使って、Webサーバーを立ち上げましょう。 $ python -m http.server 8000 ブラウザを起動し、 http://localhost:8000 にアクセスをして、次のような画面が表示されればOKです。 なお、次節以降でWeb スクレイピング を行う Python プログラムを実行しますが、上記コマンドを実行したターミナルとは別のターミナルを立ち上げて実行する形を想定しています。 初級編:特定の要素から単一の要素を抜き出す それでは、先ほど作成したフルーツショップサイトから、「新商品」マークがついている商品の名前を取得してみましょう。 以下の Python コードを scraping_beginner.py というファイル名で保存します。 Python コード例 import requests from bs4 import BeautifulSoup target_url = "http://localhost:8000/" r = requests.get(target_url) # target_urlにアクセスして、HTMLを取得 r.encoding = 'utf-8' # 文字化け対策のため明示的に文字コードを指定 bs = BeautifulSoup(r.text, 'html.parser' ) new_fruit = bs.find(class_= 'new_item' ) # HTML要素の中から目的の要素を探す print (new_fruit.text) 実行結果 $ python scraping_beginner.py ぶどう Python コード解説 bs = BeautifulSoup(r.text, 'html.parser') ここではHTML文字列を元にパースを実行し、 Python プログラムで扱いやすくするオブジェクトへの変換を行っています。 第一引数 r.text には、 target_url にアクセスした際のレスポンスのHTML文字列が格納されています。 今回は、実際にWebサイトにアクセスしていますが、次のような形で文字列を直接渡すことや、ファイルオブジェクトを渡すことも可能です。 開発中や デバッグ の際に活用すると便利ですね。 bs = BeautifulSoup('<b class="boldest">Extremely bold</b>', 'html.parser') 第二引数 html.parser は、HTMLの解析を行うライブラリに何を指定するかを記述します。 上記のものも含め、 Python の定番パーサーを列挙します。 ・ html.parser  …  Python の標準機能として備わっているパーサーで、手軽に利用できる半面、 Python で記述されているため処理速度が遅い。 ・ lxml … C言語 で記述された高速なパーサーがあり、大量のHTMLを処理するのであればこちらを利用することがお薦めだが、別途OSに lxml をインストールする必要がある。 ・ html5lib … HTMLが正しく記述されていないなどの多少の問題があっても柔軟に解釈してくれる一方、処理速度がとても遅い。 Python 標準のライブラリではないので、別途pipでインストールが必要。 new_fruit = bs.find(class_='new_item') ここでは、パースされたHTML要素の中から、目的の要素を探す処理を行っています。 今回の例であれば、 class に new_item が指定されている要素のうち、最初に見つかったものを返す、という処理になります。 ※ちなみに、キーワードが class_ となっているのは、 class という文字列が Python の 予約語 だからです。 BeautifulSoupは、HTML要素にアクセスするために必要な機能を揃えています。 イメージを掴みやすくするため、いくつかの例を紹介しておきます。 ・IDが name である <a> 要素の href 属性の値を取得する bs.find('a', id= name ) ・ class に parent が指定されている <div> の子要素である <p> を取得する bs.select( div.parent > p ) 中級編:あるページから繰り返しを伴う複数の要素を抜き出す 次に、フルーツショップサイトから、商品の名前一覧と、商品の詳細ページへのリンクURLを全て取得してみましょう。 以下の Python コードを scraping_intermediate.py というファイル名で保存します。 Python コード例 import requests from bs4 import BeautifulSoup target_url = "http://localhost:8000/" r = requests.get(target_url) r.encoding = 'utf-8' bs = BeautifulSoup(r.text, 'html.parser' ) fruits = bs.find( 'ul' , class_= 'fruits_list' ).find_all( 'li' ) for fruit in fruits: fruit_name = fruit.a.text fruit_detail_url = fruit.a[ 'href' ] print (fruit_name) print (fruit_detail_url) 実行結果 $ python scraping_intermediate.py りんご http://localhost:8000/apple.html ぶどう http://localhost:8000/grape.html バナナ http://localhost:8000/banana.html Python コード解説 fruits = bs.find('ul', class_='fruits_list').find_all('li') ここでは、二段階で要素の検索を行っています。 一段階目の find では、 class に fruits_list を持つ <ul> 要素を探し、二段階目でその子要素の <li> を全て取得しています。 初級編で解説した通り、 find は最初に見つかった要素を1つ返すだけでしたが、 find_all は、見つかった要素を全て、配列で返却します。 for fruit in fruits: fruit_name = fruit.a.text fruit_detail_url = fruit.a['href'] find_all で取得した配列を走査し、それぞれのテキスト要素と、 href 属性要素を抜き出しています。 上級編:複数のページから複数の要素を抜き出し、 CSV に出力する ここまでは、ある単一のWebページから情報を抽出するだけでした。 最後に、極めて初歩的ではありますが、Web クローラー としての振る舞いをもったプログラムを作成します。 フルーツショップサイトのトップページに記載されている全商品の詳細ページに含まれている、商品の金額情報を集め、 CSV に出力してみましょう。 以下の Python コードを scraping_advanced.py というファイル名で保存します。 Python コード例 import csv import requests import time from bs4 import BeautifulSoup target_url = "http://localhost:8000/" r = requests.get(target_url) r.encoding = 'utf-8' bs = BeautifulSoup(r.text, 'html.parser' ) fruits = bs.find( 'ul' , class_= 'fruits_list' ).find_all( 'li' ) fruit_prices = [] for fruit in fruits: time.sleep( 5 ) # 一定時間待つ fruit_name = fruit.a.text fruit_detail_url = fruit.a[ 'href' ] r_detail = requests.get(fruit_detail_url) r_detail.encoding = 'utf-8' bs_detail = BeautifulSoup(r_detail.text, 'html.parser' ) fruit_price = bs_detail.find( 'p' , id = 'item_price' ).text fruit_prices.append([fruit_name, fruit_price]) with open ( 'fruit_prices.csv' , 'w' ) as csvfile: csvwriter = csv.writer(csvfile) for fruit_price in fruit_prices: csvwriter.writerow([fruit_price[ 0 ], fruit_price[ 1 ]]) 実行結果 $ python scraping_advanced.py では、出力された CSV を見てみましょう。 $ cat fruit_prices.csv りんご,100円 ぶどう,200円 バナナ,79800円 期待通り、それぞれのページを参照して、必要な情報を集めることができていますね。 Python コード解説 r = requests.get(target_url) … [A] : fruits = bs.find('ul', class_='fruits_list').find_all('li') … [B] : for fruit in fruits: : fruit_detail_url = fruit.a['href'] : r_detail = requests.get(fruit_detail_url) … [C] 上記の処理が、とても簡単な処理ですが、この一覧の動きがWeb クローラー としての振る舞いになります。 [A]でトップ画面にアクセスし、[B]で表示されている果物リストを取得し、[C]で、それぞれの詳細ページにアクセスをする、という流れになっています。 time.sleep(5) # 一定時間待つ 5秒間待ってから、次のページへのアクセスを行っています。 この処理はとても重要で、本稿で既に述べた通り、一定時間待つという処理を挟まない場合、データ取得先のサーバーに大きな負荷をかけてしまうことになるので、かならずスリープを挟むようにしましょう。 with open('fruit_prices.csv', 'w') as csvfile: csvwriter = csv.writer(csvfile) for fruit_price in fruit_prices: csvwriter.writerow([fruit_price[0], fruit_price[1]]) fruit_prices.csv というファイル名で、 スクレイピング した情報を CSV に出力しています。 今回の例では、 CSV に出力していますが、ここの処理をDBへの登録処理や、 Excel ファイルへの出力処理など、用途に応じて変更すると良いです。 とても簡単なサンプルでしたが、Web スクレイピング 、およびWeb クローラー の基本的な仕組みは以上です。 おわりに さて、いかがでしたでしょうか。 今回は、Web スクレイピング を活用する上での前提知識、注意事項をふまえつつ、 Python プログラムの実装例を紹介しました。 みなさんもぜひ、Web スクレイピング を活用して、業務の効率化をされてはいかがでしょうか。 くれぐれも、 ・データ取得先のサーバーへの過度な負荷をかけないこと ・ 利用規約 を守ること ・ 著作権法 を守ること について、ご注意くださいませ。 ではでは、みなさま良きWeb スクレイピング ライフを。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに 今回は10/28開催の ラク スMeetup 『 SaaS プロダクトのフロントエンド/Vue.js、React、TypeScript、E2Eテスト』 の様子をお届けします! ラク スがこれまで開催してまいりましたイベントの中でも最多の申し込みをいただき、 ラク スエンジニア3名が日々のフロントエンド技術の取り組みを堂々と発表させていただきました。 はじめに イベントテーマ概要 発表の紹介 テスト稼働の削減とフロントエンドの品質担保を行うE2Eテスト Vue.js + TypeScriptによる新規サービス開発ふりかえり 息の長いサービスのフロントエンドを少しずつ改善していく営み おわりに イベントテーマ概要 今回のMeetupでは ラク スが展開する新旧3種類のサービスから、各サービスにおけるフロントエンドに関する取り組みを発信させていただきました。 10月にリリースしたばかりの 楽楽勤怠 、急速に利用者が拡大する チャットディーラー 、すでに数多くの利用者を抱える歴史ある 楽楽明細 より、それぞれ開発をリードするエンジニア達が登壇させていただきました。 それぞれの局面を迎える3サービスでフロントエンド技術をどのように活用しながらサービスを成長させているか、またモダンなフロントエンド技術をどのように大規模 SaaS に取り入れていくかをメインテーマとした登壇となりました。 発表の紹介 それではここから各発表内容と資料を共有させていただきます! テスト稼働の削減とフロントエンドの品質担保を行うE2Eテスト まずはチャットディーラーのフロントエンド開発とバックエンド開発で横断的に活躍する川又が、フロントエンドの効率的な品質担保策として導入したE2Eテストを紹介させていただきました。 そのサービスの特性上、大前提となる自動応答処理(ユーザから質問に対し、想定した回答を返す)を担保するのが非常に重要なチャットディーラー。 かつては多大なる 工数 によってテストを行い、その品質を担保していました。 今回ご紹介しましたのはそんな状況を回避すべく、Puppeteerを中心としたE2Eテストです。 同じ悩みに直面している方には、川又の発表から解決のヒントを掴んでいただければと思います。 speakerdeck.com Vue.js + TypeScriptによる新規サービス開発ふりかえり 10月にリリースされたばかりの ラク ス最新のサービスである楽楽勤怠について、リリースに至るまでの約1年間の振り返りを共有させていただきました。 ラク ス初のフロントエンド・バックエンド分離の体制、またVue.jsとTypeScriptを中心としたモダンなフロントエンド技術での開発、この2つの側面から良かった点・苦しんだ点が詳細に紹介されています。 ラク ス初のフロントエンドエンジニアであり、フロントエンド組織の拡大にも従事する北嶋がこれらの学びを今後どう活かし、 ラク スのサービスの発展に挑戦していくか注目です。 speakerdeck.com 息の長いサービスのフロントエンドを少しずつ改善していく営み 最後に楽楽明細のリードエンジニアとして中心的に活躍する三田より、2010年リリースのサービスのフロントエンドを改善していく取り組みを紹介させていただきました。 リリースからこれまでの10年以上に、今後10年もより加速度的に利用者が拡大することを見込み、楽楽明細では現状の問題点を分析しながらフロントエンドの改善に取り組んでいます。 モダンな技術の導入には技術・組織・人などの課題をクリアしていく必要がありますが、ここまでの改善に至る地道な取り組みが紹介されています。 ご参加の方の中には、 ラク スが組織的に取り組む技術ロードマップについて関心を持っていただけた方もいらっしゃったようです。 ぜひとも多くのエンジニアの方のご参考としていただきたい内容です。 speakerdeck.com おわりに ラク スによるフロントエンドの取り組み、参考にしていただける知見はありましたでしょうか? 多くの方に支持いただける大規模 SaaS が故の制約と闘いつつ、それでも技術の進化を止めない ラク スの戦略を感じ取っていただけたのではないかと思います。 今後も ラク スMeetupでは日々のエンジニアの取り組みを発信してまいりますので、次回もぜひご参加いただけますと幸いです。 そして直近ですが、フロントエンドがテーマのイベントが予定されています! 前回の実施の際にも多くの方にご参加いただけ、盛況なイベントとなりました。 今回も面白く有益な場となりますので、是非ご参加いただけますと幸いです! rakus.connpass.com
アバター
こんにちは。株式会社 ラク スで先行技術検証を行っている技術推進課のt_okkanです。 現在、フロントエンドの技術検証をしているのですが、手頃にバックエンドの API を構築したいと思い JSON Serverを利用しました。 同じようにバックエンドを手軽に構築する手段としては、FirebaseなどのBaaSを利用することがあげられますが、より手軽にローカルで構築できる手法を紹介しようと思います。 さらに今回はDockerでの JSON Serverの構築と、デフォルトの JSON Serverの機能を拡張し認証機能を追加する方法を紹介しようと思います。 JSON Server JSON Serverの実装 フォルダー構成 API仕様 data.json JSON Serverの実装 Docker環境 実行 まとめ JSON Server JSON Serverは、フロントエンド開発者向けプロトタイピング時のバックエンド API のモック作成ライブラリです。ローカルに用意した JSON ファイルをリソースとして API を構築することができ、その JSON ファイルの構成から自動的にURLが生成されます。 www.npmjs.com Expressベースでサーバーを構築しているので、Expressのモジュールを使用してカスタマイズを実装できます。 今回はその仕組みを利用して、認証機能付きの JSON Serverを構築します。 タイトルの 30秒で構築できる はコードがあれば、30秒で構築できるということです。 デフォルトの認証なしの機能なら、 Getting started 通りに構築するとコードレスで、30秒で REST API を構築できます。 公式ドキュメント でもアピールしています。 Get a full fake REST API with zero coding in less than 30 seconds (seriously) JSON Serverの実装 フォルダー構成 今回構築する API サーバーのフォルダー構成は以下のようになります。 ./server フォルダー内にDockerコンテナへ配置する、 JSON Server用のファイル群を配置します。 ./ |- server | |- data | | |- data.json | |- server.js | |- package.json |- docker-compose.yml |- Dockerfile server.js にはExpressのモジュールを利用してデフォルトの Json Serverをカスタマイズした機能を実装します。今回は認証処理を実装します。 data.json には API で管理するリソースデータを記述します。 API 仕様 今回構築する API サーバーの主な仕様です。このほかにも PUT や DELETE も使用できます。 今回はブログ記事の API を想定しています。ログイン・ブログ記事取得、の API にのみ認証なしアクセスでき、それ以外の API にアクセスするには認証が必要となります。 URL メソッド 機能 認証 http://localhost:33000/blogs GET ブログ一覧取得 なし http://localhost:33000/blogs POST ブログ記事追加 あり http://localhost:33000/blogs/:id GET ブログ取得 なし http://localhost:33000/users GET ユーザー一覧取得 あり http://localhost:33000/users/:id GET ユーザー一覧取得 あり http://localhost:33000/auth/login POST ログイン なし data. json data.json はデータベースのように、 API で扱うデータを保存します。今回は、ユーザー情報とブログ情報を保存するようにします。 { " blogs ": [ { " id ": 1 , " title ": " Java ", " body ": " Java Beans ", " post ": " 2020/10/01 ", " userid ": 1 } , { " id ": 2 , " title ": " Python ", " body ": " Python3.10 ", " post ": " 2020/10/04 ", " userid ": 1 } , { " id ": 3 , " title ": " JavaScript ", " body ": " Vue.js ", " post ": " 2020/10/10 ", " userid ": 2 } ] , " users ": [ { " id ": 1 , " name ": " user one ", " email ": " one@example.com ", " password ": " userone " } , { " id ": 2 , " name ": " user two ", " email ": " two@example.com ", " password ": " usertwo " } ] } JSON Serverの実装 ではプログラムを実装し、 JSON Serverを拡張し認証付き REST API サーバーを構築していきます。 まずはNode.jsのプロジェクトの package.json を以下のように設定します。 { " name ": " json-server-docker ", " version ": " 1.0.0 ", " description ": " Json Server on Docker ", " author ": " XXXX@example.com ", " main ": " server.js ", " scripts ": { " start ": " node server.js " } , " dependencies ": { " body-parser ": " ^1.19.0 ", " helmet ": " ^4.1.1 ", " json-server ": " ^0.16.1 ", " jsonwebtoken ": " ^8.5.1 " } } main , scripts , dependencies 以外は好みの値に設定してください。 今回は認証にJWTでの トーク ン認証を使用するので、 jsonwebtoken を依存関係に追加します。 では次に、サーバー本体となる server.js を以下のように実装します const jsonServer = require( "json-server" ); const fs = require( "fs" ); const bodyParser = require( "body-parser" ); const jwt = require( "jsonwebtoken" ); const helmet = require( "helmet" ); // JSON Serverで使用するJSONファイルを設定 const server = jsonServer.create(); const router = jsonServer.router( "./data/data.json" ); // JSON形式のリクエスト対応 server.use(bodyParser.urlencoded( { extended: true } )); server.use(bodyParser.json()); // 署名 const JWT_SECRET = "jwt_json_server" ; // 有効時間 const EXPIRATION = "1h" ; // データーベースの作成 const db = JSON.parse(fs.readFileSync( "./data/data.json" , "UTF-8" )); // ①ログイン用のルート server.post( "/auth/login" , (req, resp) => { const { email, password } = req.body; // ログイン検証 if ( db.users.findIndex( (user) => user.email === email && user.password === password ) === -1 ) { resp. status (401).json( "Unauthorized" ); return ; } // ログイン後、アクセストークンの生成 const access_token = jwt.sign( { email, password } , JWT_SECRET, { expiresIn: EXPIRATION, } ); resp. status (200).json( { access_token } ); } ); // ②ログイン認証が必要ないルート // 記事一覧を取得 server.get( "/blogs" , (req, resp) => { const blogs = db.blogs; resp. status (200).json( { blogs } ); } ); // 記事IDから記事を取得 server.get( "/blog/:id" , (req, resp) => { const id = req.params.id; const blog = db.blogs.find((blog) => blog.id === Number (id)); resp. status (200).json( { blog } ); } ); //③ 認証が必要なルート server.use((req, resp, next) => { // 認証形式チェック if ( req.headers.authorization === undefined || req.headers.authorization.split( " " ) [ 0 ] !== "Bearer" ) { // 認証形式が異なる場合 resp. status (401).json( "Unauthorized" ); return ; } // 認証チェック try { var decode = jwt.verify( req.headers.authorization.split( " " ) [ 1 ] , JWT_SECRET ); // 認証に成功した場合は、next関数を実行しJSON Serverの機能を利用する next(); } catch (e) { // 認証に失敗した場合 resp. status (401).json( "Unauthorized" ); } } ); // JSON Serverを起動する server.use(router); server.use(helmet); server.listen(33000, () => { console.log( "JSON Server Start" ); } ); JsonServer Access Control を参考に実装しました。 実装した ルーター としては、 ログイン用( /auth/login ) 認証なしで公開( /blogs 、 /blogs/:id ) 上記以外で認証が必要 の3種類を実装しています。 jsonwebtoken や、 body-parser の使い方はこちらを参考にしています。 jsonwebtoken - npm body-parser - npm Docker環境 Dockerを用いて JSON Serverを構築します。 Dockerfile と docker-compose.yml は以下のようにしました。 Dockerfile FROM node:latest RUN yarn add global json-server docker-compose.yml version: "3" services: json-server: build: context: . dockerfile: Dockerfile volumes: - ./server:/data/server:delegated tty: true working_dir: /data/server command: sh -c "yarn install && yarn start" container_name: jsonserver-docker ports: - "33000:33000" 実行 では最後にDockerコンテナ上で実行しましょう。 $ docker-compose build $ docker-compose up -d 起動後に curl で http://localhost:33000/users にアクセスしてください。認証をしていないので、 Unauthorized が返ってきます。 $ curl http://localhost:33000/users "Unauthorized" /auth/login でログインしてから、レスポンスのアクセス トーク ンをヘッダーに付与して同じURLにアクセスしてみます。 $ curl -X POST -H "Content-Type: application/json" -d '{"email": "one@example.com", "passowrd": "userone"}' http://localhost:33000/auth/login { "access_token": "アクセストークン" } $ curl -H "Content-Type:application/json" -H "Authorization:Bearer アクセストークン" http://localhost:33000/users [ { "id": 1, "name": "user one", "email": "one@example.com", "password": "userone" }, { "id": 2, "name": "user two", "email": "two@example.com", "password": "usertwo" } ] レスポンスから分かるように、ユーザー一覧を取得できます。 /blogs のGETメソッドとPOSTメソッドでも試してみてください。 まとめ JSON Serverを利用して認証機能付きのモック REST API を構築しました。 一度作成してしまえば、Dockerを起動するだけでいつでも30秒でバックエンドの API を構築できます。 日々の勉強や、ちょっとした検証などに利用してみてください。 GitHub にもコードを上げています。参考にしてみてください。 https://github.com/txkxyx/jsonserver-docker github.com エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
アバター
はじめに こんにちは、itoken1013です! 定期的に発信しています入門シリーズ、今回のテーマは Emacs の使い方 です! 昔から多くの人から熱い支持があるエディタである Emacs ですが、使い方をマスターするととても便利に素早くコーディングが可能となります。 今回の記事を読んでいただき、ぜひ使い方を身につけていただければと思います! はじめに インストール手順(Windows) インストーラを入手する インストールを実施する インストール手順(Mac) 前提知識 コマンドの表記 C-x M-x Return バッファ ウィンドウ ミニバッファ 基本的なコマンド Emacsを起動する ファイルを新規作成する 移動する(上下左右) 文字を削除する Undo(変更の取り消し) ファイルを保存する ファイルを閉じる ファイルを開く 上書き保存 Emacsを終了する 困った時の中断コマンド その他のコマンド一覧 終わりに インストール手順( Windows ) 使い方の前に、まずはWindow向けの Emacs のインストール手順からです。 Catalina以前の Mac もしくは Linux を利用の方は Emacs はインストール済ですので、デフォルトの状態で Emacs を利用可能です。 このインストール手順をスキップし、次項の『前提知識』へ進んでください。 インストーラ を入手する まずは Emacs の インストーラ のダウンロードからです。 今回は使い方の説明を優先するため、 Windows の スタンドアロン 版 Emacs をご案内します。 以下の公式ページにアクセスし、 Windows 項配下の nearby GNU mirror をクリックしてください。 バージョン別の Emacs が表示されます。 www.gnu.org 今回は執筆時点の最新版である「 emacs -27/」を選択します。 次に インストーラ は「 emacs -27.1- x86 _64.zip」を選択します。 ダウンロードが完了しましたら、 Windows の任意のツールを使って zipファイルを解凍します。 特にこだわりがなければ、 Windows でよく使われる Lhaplus や 7-Zip などでよいでしょう。 インストールを実施する 次にインストールを実施します。 解凍したフォルダにアクセスし、binフォルダ配下の runemacs.exe を起動してください。 起動後、こちらのウィンドウが立ち上がれば、インストール完了です! これで無事に Emacs が起動し、 Windows でも使い方を学ぶ準備ができました。 インストール手順( Mac ) Catalina( macOS 10.15)から Emacs は Mac に同梱されなくなりました。 このため、利用にはアプリケーションのダウンロードが必要になります。 詳細はこちらをご確認いただき、セットアップをお願いします。 applech2.com 前提知識 それではさっそく使い方を説明していきたいのですが、まずは前提知識と用語を説明させてください。 Emacs は他のツールとコマンドの表記が異なる点もあり、前提知識を踏まえた方がスムーズに使い方を理解できるはずです。 コマンドの表記 公式ページや各種リファレンスのコマンドは、 Emacs に初めて触れる方には見慣れない表記となります。 本記事も表記内容を揃えて掲載しますので、以下の点は使い方を読む前に理解してください。 C-x 『Ctrl を 押しつつ 、x(任意のキー)を押す』 を指します。 C-f であれば『Ctrl を押しつつ f を押す』、C-g であれば『Ctrl を押しつつ g を押す』となります。 ( Windows だとCtrl、 Mac ではcontrolに読み替えてください) 最初は表記内容と使い方と結びつけるのが大変ですが、何度か練習すると慣れてきます。 M-x C-x と混同しがちですが、こちらは 『ESCを 押した後 、x を押す』 または 『Altを 押しつつ 、xを押す』 を指します。 MではなくESCもしくはAlt、またESCだとC-xと違って「押した後」である点に注意してください。 (ちなみにMとは現行のキーボードに存在しない「Metaキー」に由来しており、ESCキーがMetaキーの代替を担っています) Return Mac には存在しますが、 Windows ではEnterキーを指します。 バッファ Emacs 上でファイルを開いている領域を 「バッファ」 と呼びます。 このバッファと呼ばれる領域上にファイルを読み込み、 Emacs 上で編集した内容をファイルに書き込む流れでファイルを更新していきます。 Emacs では同時に複数のバッファを開くことができ、表示するバッファを切り替える操作ができます。 ウィンドウ ファイルを開いた際に、テキスト内容が表示される Emacs の領域を指します。 ミニバッファ Emacs を起動した際、コマンド入力やメッセージが表示される領域を指しています。 上述のバッファと混同しないよう、ご注意ください。 基本的なコマンド それでは一般的な テキストエディタ として必要な Emacs の使い方を説明していきます。 最低限必要なコマンドと使い方を以下に示しますが、説明を読むだけでなく、 Emacs を立ち上げて一緒に操作してみると使い方を早く身につけられるはずです! No コマンド名 用途 1 emacs Emacs を起動する 2 C-x → C-f ファイルを新規作成する 3 C-f 右に移動する 4 C-n 下に移動する 5 C-b 左に移動する 6 C-p 上に移動する 7 C-d 文字を削除する 8 C-x → u 変更の取り消し 9 C-x → k ファイルを閉じる 10 C-x → C-f ファイルを開くする 11 C-x → C-s 上書き保存する 12 C-x → C-c Emacs を終了する 13 C-g コマンドを中断する Emacs を起動する Windows の場合、インストール時に指定した runemacs.exe をダブルクリックすることで起動完了です。 Mac の場合、ターミナル上で 「 emacs 」 を入力してください。 ファイルを新規作成する まずは練習用に編集するファイルを作成してみましょう。 Emacs 上で 『C-x』の後に『C-f』 を入力してください。 最下段(「ミニバッファ」と呼びます)に現在の ディレクト リが表示されますので、今回は「 emacs .txt」というファイル名を入力してみます。 ファイル名を入力後、バッファ上に「 emacs .txt」というファイルが作成されます。 移動する(上下左右) まずは通常のテキスト入力の要領で、以下の3行を入力してみましょう。 初心者でも分かる Emacsの使い方 Windowsのインストール手順・コマンド一覧付き 次にファイル内のカーソル移動です。 Emacs では矢印キーでもカーソル移動が可能ですが、 ホームポジション から手を離すこととなるため、編集時にタイムロスが発生がちです。 対して以下のキーを使うことにより、 ホームポジション にステイしたままで素早くカーソル移動ができます。 それぞれ試してみてください。 右/C-f  ※f はForward 下/C-n ※n はNext line 左/C-b ※b はBackward 上/C-p ※p はPrevious line 文字を削除する 文字の削除も通常の テキストエディタ 同様、BackspaceとDeleteキーで可能です。 ただ矢印キー同様、 ホームポジション から離れずに実現するには 『C-d』 を使うことで現在カーソルがある文字を削除することが可能です。 試しに最後の行を削除してみましょう。 Undo(変更の取り消し) 先ほど削除した行を復活させるためには、 『C-x』の後に『u』 を打つことで直前の変更を取り消すことができます。 ファイルを保存する それではこのファイルを保存してみましょう。 ファイルの保存には 『C-x』の後に『C-s』 を打ちます。 これでバッファの内容が新たに作成されたファイルに記録され、 エクスプローラ からもファイルが確認できるはずです。 ファイルを閉じる 正確にはバッファーを閉じることを意味しますが、編集中のファイルを閉じてみましょう。 『C-x』の後に『k』 を打つと、ミニバッファ上に『Kill buffer(default emacs .txt)』と表示されますので、「 emacs .txt」を入力の上、Enterを押下してください。 これでバッファーを閉じることができます。 この際、未保存の場合には追加で yes か no の選択を求められますので入力の上、Enterを押下してください。 この後、 Emacs を起動した際の画面に戻れば、保存完了です。 ファイルを開く ただいま閉じたファイルをもう一度開いてみましょう。 『C-x』の後に『C-f』 でファイル検索ができますので、「 emacs .txt」を指定してください。 上書き保存 「 emacs .txt」が無事に開けましたら、今度はファイルを編集し、上書き保存してみましょう。 末尾を改行して「編集しました」と加えた後、 『C-x』の後に『C-s』 で上書き保存を実施します。 ミニバッファ上に「Wrote ・・・・ / emacs .txt 」と表示されれば、上書き保存が完了しています。 Emacs を終了する 最後に Emacs を終了するコマンド 『C-x』の後に『C-c』 です。 ファイル編集後に保存していない場合にはミニバッファ上にメッセージが表示されますので、必要なキーを入力してください。 入力後、 Emacs のウィンドウがクローズされれば完了です。 困った時の中断コマンド ハンズオン形式で Emacs のコマンドを説明してきましたが、いかがでしたでしょうか? 途中でコマンドを打ち間違えたり、謎の文字列が表示されたりして戸惑う方もいたかと思います。 そんな時のお助けコマンドとして、 『C-g』 で実行中のコマンドを中断することができます。 コマンド入力後、ミニバッファには「Quit」が表示されます。 より上級的な使い方でもこの中断コマンドは使えますので、身につけていただければと思います。 その他のコマンド一覧 ここまで簡単なテキスト編集に必要な Emacs の操作を説明してきました。 より応用的なコマンドと使い方は以下にまとめてありますので、こちらも実際に Emacs を触りながら手に覚えさせていただければと思います。 No コマンド名 用途 1 C-スペース 範囲選択 2 M-w コピー 3 C-w カット 4 C-y ペースト 5 C-a 行頭に移動する 6 C-e 行末に移動する 7 M-< 先頭に移動する 8 M-> 末尾に移動する 9 C-p 1行上を移動する 10 C-n 1行下を移動する 11 C-s 文字列の検索 12 M-% 文字列の置換 終わりに 超入門ということで最低限なコマンドの使い方を紹介しましたが、利用イメージを持ってもらえましたでしょうか? Emacs を使い方を身につけることで開発効率を爆速化することができます。 Windows は最初のインストールだけが少し手間ですが、インストールの手間を大きく上回るリターンが得られることでしょう。 また今回は触れませんでしたが、 Emacs ではブラウザなどの各アプリケーションを操作するなどの使い方も可能です。 ぜひ使い方を体に馴染ませて、 Emacs をマスターしていってください! それでは~! 今回引用させていただきました記事はこちらです。 applech2.com エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
アバター
はじめに こんにちは。 sts -250rrです。 いきなりですが、皆さま開発において フレームワーク は使われていますでしょうか? 世の中のサービスはもちろん、 ラク スのシステムにおいても様々な フレームワーク が使われているわけですが、 フレームワーク 自体も時代の流れに沿って、新しいものが出てきています。 新規サービスは新しい技術を、既存のサービスは新しい技術に置き換えていくなど日々試行錯誤をしている方もおられるかと思います。 今回はそんな Java フレームワーク を7つご紹介したいと思います。 他にも魅力的なものがあるとは思いますがご了承ください。 私が使用したことのあるものについてはちょっとした感想なども添えていますのでご参考程度に読んでいただければ幸いです。 はじめに フレームワークの良さって? メリット デメリット Javaフレームワーク Spring Framework DI(Dependency Injection:依存性の注入) AOP(Aspect Orientation Programming:アスペクト指向プログラミング) Play Framework Spark Framework Apache Struts Seasar2 Java EE(Java Platform, Enterprise Edition) JSF(JavaServer Faces) まとめ フレームワーク の良さって? メリット サービスを開発する上で、チームや複数メンバーで開発することは避けて通ることはできないプロセスです。 しかし、スキルやバックボーンが異なるそれぞれのメンバー間でプログラムの書き方がバラバラになってしまうと、統一感が崩れてしまうことによる可読性の低さや、改修コストが上がってしまう恐れが出てきます。 フレームワーク を利用することでチーム内で共通の規則に沿った書き方に統一することができ、これらの問題を解決することが可能です。 また、 フレームワーク 側が用意している機能を用いることで、セキュリティや認証の機能を低コストで実装することができる場合もあり、開発速度を上げることにも繋がります。 デメリット 基本的な Java の知識に加えて、 フレームワーク 特有の機能やその書き方を理解する必要があるため、それに伴い学習コストは上がってしまうことは避けられません。 他の フレームワーク で開発されていた方や若いエンジニアの方は苦労するポイントになってくるかと思います。 特に新卒エンジニアは フレームワーク の知識が先についてしまい、 Java の基本がわからなくなってしまう。いざプレーンな Java のプログラムを書こうとすると手が止まってしまうなんていう落とし穴もあるのではないでしょうか。(これは結構に身に覚えがあります。) Java フレームワーク フレームワーク についてメリット・デメリットをお伝えしましたが、本項では Java 開発における有名どころの フレームワーク をご紹介します。 2020年現在のトレンドや過去に活躍した フレームワーク を選抜してみましたのでお楽しみください。 Spring Framework Webアプリケーションやモバイルアプリをはじめとした様々な開発に適している フレームワーク で、 ラク スでも利用実績があります。 2020年現在「 Java といえばSpring」のようなイメージを持っている方もいるほど、スタンダードになりつつある フレームワーク なのではないでしょうか。 私も最近になってこの フレームワーク で開発を行う機会が増えてきました。 Spring Framework の特徴は DI( Dependency Injection:依存性の注入) と AOP ( Aspect Orientation Programming: アスペクト指向 プログラミング) の概念を取り入れることで機能開発や改修が楽にできる点が挙げられます。 簡単ですがDI・ AOP のメリットは以下のようなものがあげられます。 DI( Dependency Injection:依存性の注入) クラス間の依存関係を解消し、 疎結合 にすることで保守性を高めることが可能。 依存関係のある他のクラスが完成していなかったとしても、Mockに置き換えてやることで、テストを実行することが可能。 AOP ( Aspect Orientation Programming: アスペクト指向 プログラミング) ログの出力や認証など、共通で行うような処理を1つの機能として抜き出し、プログラム内のいろいろな場所で横断的( Aspect )に利用することが可能 共通の処理が抜き出されているため、業務ロジックに集中した開発が可能。 また、 Spring Framework には多くのプロジェクトが存在するため、作成するシステムによって必要なプロジェクトを使い分けることで様々なアプリケーションの開発に適することができていると言えます。 ただし、多くのプロジェクトが存在する反面、多くのことができてしまうため、必要な要素を適切に利用することが大切です。 また、 フレームワーク が担える範囲が広い(≒隠ぺいできる範囲が広い)ため、開発に慣れていない方にとってはどこで何をしているかわからない。といったことが起こりがちなように思います。 spring.io Play Framework Play Framework(プレイ・ フレームワーク )は、 Scala と Java 言語で書かれた フレームワーク で、生産性を重視した フレームワーク になっています。 既存の Java のWebアプリケーションの開発手法では、 JSP や サーブレット をコツコツと書いて、コードを修正したら コンパイル して、ビルドして、初めて編集した内容が確認できる。といった状況であったため、コーディング以外にとられる時間もあり、しんどさを感じている方が少なくなかったようです。 そういった状況の中で、 Ruby の「 Ruby on Rails 」や Python の「 Django 」のような開発を、 Java でもやりたいというニーズで生まれた背景を持つようです。 そのため、Play Frameworkは「 Ruby on Rails 」、「 Django 」の影響を強く受けているといわれています。 Play Frameworkの特徴は コンパイル が早く、コードの追加・修正がすぐに反映され確認できる 点と、使用するCPUリソースやメモリ使用量が少ないため、 システムが大規模なものになったとしても動作するシステムを作ることができる 点です。 Java の弱点であった コンパイル に時間がかかるという欠点をなくし、メリットである堅牢性や高速な動作を活かすことができるようになっています。 また、 MVC (Model-View-Controller) アーキテクチャ を使用しているため、開発者にとって理解しやすく高速なアプリケーション開発に適しているとされています。 もともと Java で開発をしていなかった方にとって、他の開発言語の流れを汲んでいるPlay Frameworkは馴染みやすいのではないでしょうか。 Spark Framework Spark Frameworkは、シンプルな構成でできていいる軽量な フレームワーク で、軽量であるためにマイクロ フレームワーク とも呼ばれています。 ここまでで紹介してきた Spring Framework やPlay Frameworkは複雑で大きなシステムを開発する際にも活躍しますが、シンプルで小さなシステムを作る際にはあまりに機能が豊富で大げさになってしまうため、よりシンプルな フレームワーク として生まれました。 Ruby の「 Sinatora 」という フレームワーク に影響を受けており、多くの アノテーション の記述や設定ファイルを必要としないため、開発する際の負担を軽減してくれます。 これらの特徴に加え、Lambda式とstaticメソッドを活用することで手軽に実装することが出来るということが挙げられています。 Apache Struts 2013年にEOLを迎えた フレームワーク ではありますが、 Spring Framework が出てくるまでは「 Apache Struts が Java の主流 フレームワーク 」と言われていました。世の中で動いているシステムで Apache Struts を採用しているプロジェクトも少なくないと思われますのでご紹介します。 ※2007年に新しく Struts2 という フレームワーク が誕生していますが、今回はStruts1についてです。 Apache Struts の特徴は MVC (Model-View-Controller)の アーキテクチャ に基づいた、 Java サーブレット や JSP ( JavaServer Pages )の仕組みを組合せてWebアプリケーションを作成することができる フレームワーク です。 XML ベースの設定ファイルを記述することで、ユーザのリク エス ト(URL)を適切な Java クラスに割り振るような動きや、JavaBeanに値を自動設定できるようにするなど、 Java プログラムのコーディング削減ができるような仕組みがそろっています。 ただし、 XML の設定ファイルが便利である反面、様々な設定ファイルを書かなければならないというデメリットとして挙げられることもあります。 Seasar2 2016年にEOLとなっている フレームワーク ですが、日本国産の フレームワーク ということでご紹介します。 前述した Apache Struts では設定ファイルの記述が多くなることがデメリットとして挙げられるとお伝えしました。 また、修正したプログラムの動作を確認するためにデプロイをしなければならないという点で開発速度を上げていきたいエンジニア的には煩わしい部分になっていました。 Seasar2 はそういった部分を解消するため、設定ファイルの記述を 命名規則 や アノテーション でカバーすることで設定ファイルを少なくし、 ホットデプロイ の機能を取り入れることで修正のたびにデプロイの作業をせずに開発を進めることが可能です。 ただし、個人的には 命名規則 などを誤ると途端に動かなくなってしまうため、 フレームワーク 特有のルールを理解する必要がある点はちょっとした学習コストがかかるなと感じる部分だと思っています。 ちなみに、Springの項でご紹介したDIや AOP は SAStruts でも利用することができ、個人的に Seasar2 からSpringへの学習は割とスッと入ってくる印象を受けました。 Java EE(Java Platform, Enterprise Edition) Java EE は、エンタプライズ(企業)向けのシステム構築するために作られた Java 標準仕様の フレームワーク です。 Java SEにサーバー関係のライブラリなどを追加することで、Webアプリケーション開発ができるようになっています。 Servlet ・ JSP 、 EJB に加え Java の各種 API など、大規模システムの構築に必要な機能がまとめて提供されています。 JSF(JavaServer Faces) JSF は Java EE の中のサブシステムですが、 フレームワーク としての役割を持っています。 Apache Struts と同じく MVC を利用していますが、 XML 方式のHTMLを利用した、 コンポーネント ベース フレームワーク であるため、 Apache Struts とはまた異なります。 JSF は専用のタグライブラリを使ってWeb画面の構築を行う「フェースレット」とフェースレットと関連づけた処理をおこなったり、値設定をしたりする Java のクラス「マネージド ビーン 」で構成されています。 まとめ 今回 Java フレームワーク についてまとめてみましたが、いかがだったでしょうか? 改めて見比べてみてもどの フレームワーク にも特徴があり、すべてにおいて最も優れているというものはなかったように感じます。 当たり前のことではありますが、「目的(作りたいシステムや、開発手法)に合わせて、最適な フレームワーク を選択する」ことが開発を『楽』にする第一歩であると思います。 私事かつ話がそれますが、私が関わっているプロジェクトで徐々にSA Struts からSpringに乗り換えようとする動きがあり、 Struts とSpring共存した状態で動作させるということを行ってます。 ただし、これもそう簡単なことではなく、既存の Struts の機能に引っ張られてSpringの機能が上手く使えない、ということも発生しておりこれを解決しようと思うと新旧両者の知識を求められるためなかなかに苦労しています。 皆様の フレームワーク 選択の足掛かりになれば幸いです。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
技術広報の syoneshin です。 リモートワークの普及とともに帳票管理や押印を SaaS で代替する動きが注目され、システム化に必要な棚卸しに フローチャート (フロー図)を使う機会が増えていると聞きます。 10年以上前、今でいうPMOとして内部統制や業務改善に関わる多くの フローチャート (フロー図)を書いた経験から、今回は当時の上司やコンサルのプロたちのもとで学んだ フローチャート (フロー図)の書き方についてご紹介します。 ※本記事は初級者向けに フローチャート (フロー図)の書き方をまとめた内容になります。 フローチャート(フロー図)とは? フローチャート(フロー図)の書き方 よく使う記号 プログラミングフローチャート(フロー図) の書き方 フローチャート作成ツール まとめ   もし、当社の雰囲気・技術内容等にご興味を持たれましたら以下サイトの募集職種をお気軽にご確認ください! フローチャート (フロー図)とは? フローチャート とは、業務やシステムにおける工程やプロセスの各ステップや アルゴリズム などの流れを、長方形・ひし形・楕円形などの記号で表示し、流れの方向を矢印でつなげて視覚的に表した図の事です。 フローチャート には管理観点で主に以下4つの種類があり 文書 フローチャート :複数の部門に閲覧してもらうための文書の流れを記した図 データ フローチャート :システムのデータの送信経路を記したり管理したりするための図 システム フローチャート :プログラム、サーバー、ネットワークなどシステムの物理的な構成要素をデータがどのように経由するかを記した図 プログラム フローチャート :システムのプログラム処理や管理形態を記した図 また、一般的な業務フローなどで使われる ワーク フローチャート :業務処理、文書・データ情報の流れなどを含むオフィス業務に関わる仕事の流れを記した図 などがあります。 フローチャート を使い、業務・作業プロセスを可視化することで、第 三者 への情報伝達や説明、認識の統一が簡単になり、不要・不足の業務をみつけたり、引継ぎを早めたりなど業務の効率化と品質の維持向上に役立ちます。 フローチャート (フロー図)の書き方 では フローチャート の書き方について説明します。 フローチャート は仕事の流れや構造を整理・可視化し、関係者の間で仕事の流れや構造を理解・共有できるようにすることを目的にしています。そのため フローチャート の書き方の基本は、「誰が・何が」「いつ、何をきっかけに・どういう場合に」「どんな作業・処理を」行っているかを、シンプルに分かり易くに書き表わすことが求められ、作成目的をしっかりと理解し、対象範囲を決めて書くことが必要になります。 以下4点は フローチャート の書き方で気を付けるべきポイントです。 フローは流れを上から下へ、左から右へ流れるよう要素を配置すること 各ステップには図記号が持つ基本的な意味を理解して配置すること 図記号と図記号の間隔は開けて重ならないようにすること 時系列が分かるよう並列に書かずテキストは簡潔に分かり易くすること また、 フローチャート を書く際、ページを分割したりまたがると、流れや構造を追いにくくなる傾向があるため、基本的には1ページにまとめて書くことに努めましょう。 以上が基本的な フローチャート の書き方になります。 よく使う記号 それでは次に フローチャート でよく使う記号と意味を見て行きます。 フローチャート の書き方をマスターするためには、各図記号の意味と用途を理解することが必要です。 各記号の意味・用途・事例を見て フローチャート の書き方の参考にしてください。 端子・開始/終了 業務プロセスやプログラムの開始/終了やスタート/ゴールを表す記号。角の丸い四角形で一般的に”端子”と呼ばれフローの始まりと終わりに配置する必要がある。また業務のトリガーとなるきっかけを表すこともある。 処理 フローチャート の1つのステップ・作業・処理を表す記号。四角形で"処理"とよばれ、一般的な処理、作業、手続きを表す際に配置。基本的には1ボックスにつき、1つの処理内容を記載。※複数の処理を記載すると、わかりづらくなるため注意。 判断・条件分岐 「真/偽」もしくは「Yes/No」が答えとなる判断や、複数の選択肢に分かれる判断を表す記号。ひし形の図形で”判断”もしくは”条件分岐”と呼ばれ、2つ以上の判断処理を表す際に配置。1つの図形各頂点から「Yes」or「No」/「真」or「偽」もしくは複数の判断に対応する線や矢印を次のステップ(図形)に向けて書く。 ループ開始/終了 何度も繰り返しで行う処理を表す記号。台形のような六角形の図形で、繰り返し条件と繰り返し終了条件を表す際に配置。ボックスの中に繰り返し名と条件を記入し、間に処理を挟む。 システム・データベース・磁気ディスク 業務システムやデータベースへの入出力や保管を表す記号。円柱の図形で、”システム”もしくは”データベース”、エクセルの フローチャート では”磁気ディスク”と呼ばれ、システムやデータベースへのデータの入出力や保管を表す際に配置。使用システムが複数ある場合、システム名称も記載することが多い。 データ・入出力 媒体を指定しないデータやファイルなどの参照や書込み、入出力を行う機能を表す記号。平行四辺形の図形で”データ”もしくは”入出力”、”I/O”とも呼ばれ、主にデータベースとファイルを分けて図示したい際に配置。 書類 ・ドキュメント 受発注書・請求書・伝票などの書類や帳票を表す記号。一般的には”書類”と呼び、処理に応じて発生する際は処理の記号と重ねて記載し、2つ以上の書類・ドキュメントが1つの段階に含まれている場合は”複数書類”の記号を使うことになる。 定義済み処理・サブルーチン 処理の一部を別 フローチャート と分けて作成する場合や、使用頻度や認知が高い場合に配置する記号。 フローチャート を1枚にまとめる際に長くなるケースは,この記号で一部フローを分けて記載することが多い。 結合子 フローチャート が長くなったり、複雑になったりした際に同じ フローチャート 内で別の処理に飛ばす場合に配置する記号。結合子の中に参照先を記載することが多い。 外部結合子 こちらも フローチャート が長くなり、後工程を別ページにまたいで記載する必要がある場合に使用する記号。外部結合子の中に参照先を記載することが多い。 ここではよく使う フローチャート の記号を紹介しましたが、 フローチャート 作成では記号の種類を増やさず、できるだけシンプルに書くよう気を付けましょう。また記号の持つ意味や用途を正確に理解して作成することで、読み手に伝わりやすい フローチャート になるでしょう。 プログラミング フローチャート (フロー図) の書き方 プログラミングの フローチャート の書き方ですが、まずは基本的な以下3点の書く目的をしっかりと理解することが大切です。 プログラム構造の整理 目的の1つ目は、プログラム構造の整理・理解をすることです。 プログラムは、書き方によって処理スピードや可読性に大きな影響を与えます。 実際のプログラミング前には、最適な設計が可視化され共通認識されていることが望まれます。 プログラミング速度を上げるため(効率化) 目的の2つ目は、プログラミングの速度を上げることです。 しっかり設計ができていれば、その通りに効率的にプログラムを書けます。設計ができていなければ、後々修正が多く発生し余分に時間が掛かかってしまいます。 プログラム品質の向上 目的の3つ目は、プログラミング品質を向上させることです。 フローチャート を書くことでプログラムの全体像が明確になり、設計漏れやバグを減らせます。つまり、プログラムの品質が上がります。 フローチャート を使って他者と事前レビューをすることで、更に品質を上げることもできます。 次にプログラミングの フローチャート の書き方を紹介します。 プログラミングにおける フローチャート には、よく使われる以下の「型」がありますので、まずは「型」を覚えることが、プログラミング フローチャート の書き方をマスターする近道です。 それでは代表的なプログラミングの フローチャート の書き方(事例)を見て行きます。 順次構造 順次構造の フローチャート の型はプログラム処理を順番通りに記述しているプログラムの構造を表します。「開始」の記号が上にあり、上から一番したにある「終了」の記号へ向けての処理がシンプル書かれていく構造です。 分岐構造 分岐構造の フローチャート の型は「条件分岐」の記号が使用され、条件によって処理内容が分かれている構造を表します。 具体的にはコード記述で使用する「switch/case文」や「if/else文」を表す構造です。 switch / case文 if / else文 反復構造(ループ) 反復構造の フローチャート の型は、「条件分岐」や「ループ開始/終了」の記号が使用され、繰り返し処理のあるプログラムの構造を表します。具体的にはコード記述で使用する「for/while文」「do while文」などを表す構造です。 for / while文 do while文  ※最初に処理を実行するか・しないかの違いだけのため省略 またプログラミングの フローチャート の書き方において、 アルゴリズム 理解は必須となります。 そもそも アルゴリズム を理解しなければ、プログラミングの フローチャート は書けません。 以下に代表的 アルゴリズム のうち「ソート」と フローチャート の書き方(事例)を一つ紹介します。 バブルソート バブルソート とは、ソート(データの集合を一定の規則に従って並べること)の一つで、バラバラに並んでいるデータ要素を「昇順(小さい順)」もしくは「降順(大きい順)」に並べ替えるやり方のひとつです。隣接する要素の大小比較と並べ替えを繰り返すことで全体を昇順(降順)に並べ替えるやり方です。 (例) 他、代表的なソートには以下があります。 選択ソート 選択ソートも「昇順(小さい順)」もしくは「降順(大きい順)」に並べ替えるやり方のひとつです。バラバラに並んでいるデータ要素の中で一番小さい値を探し、1番目の要素と交換し、次に2番目に小さい値を探し出し、2番目の要素と交換し...をデータがなくなるまで繰り返すことで全体を昇順(降順)に並べ替えるやり方です。 クイックソート クイックソート も「昇順(小さい順)」もしくは「降順(大きい順)」に並べ替えるやり方のひとつです。バラバラに並んでいるデータ要素から 軸要素となる基準値を決め 基準値より大きい値を基準値より右に置く 基準値より小さい値を基準値より左に置く の3ステップを「基準値よりも大きいグループ」と「基準値よりも小さいグループ」に対して何回も繰り返すことで全体を昇順(降順)に並び替えます。 ソート以外の アルゴリズム について、ここでは省略します。 他 アルゴリズム 種類について詳しく知りたい方は以下入門書がおススメです。 www.shoeisha.co.jp ここでは、プログラミングの フローチャート の書き方について見てきました。 プログラミングの フローチャート の書き方をマスターするには、まずたくさんの「型」を覚え、実践では書く目的をしっかり意識するように心がけましょう。 フローチャート 作成ツール ここでは フローチャート 作成ツールを紹介します。 フローチャート はMSOfficeのWord、 Excel 、 PowerPoint の図形挿入を使っても簡単に作成できますが、以下の様な フローチャート 作成ツールでも簡単に作る事ができます。 google スライド docs.google.com Google ドライブ で無料使用できるプレゼン用ツールの『 Google スライド』でも フローチャート の作成は可能。安全なデータ共有・観覧による第 三者 とも共同編集も可能。 フローチャート を作成するための機能やパーツ数は少ないが、シンプルなチャートを作れる。 draw.io www.draw.io 完全無料で会員登録やインストール不要な『draw.io』は、高機能で使いやすいのが特徴の フローチャート 作成ツール。 記号もテンプレートも豊富かつ図形から自動で線や矢印を伸ばすことができるため、初心者にも直感的な操作ができる点が魅力。作成した図はOneDriveや Google ドライブや GitHub に保存できます。豊富な機能とテンプレートで素早く フローチャート を作成したい方におすすめ。 CaCoo cacoo.com 『CaCoo』は完全無料オンライン使える フローチャート 作成ツール。 マインドマップ やプレゼンなどのテンプレートや、 スマートフォン 用の ワイヤーフレーム が用意されていたりとパーツが多いため、リッチな フローチャート を書くことができる。また、共 有機 能を利用して他メンバーとのチャットや同時編集もできる点も魅力。 まとめ 最後に フローチャート の書き方で参考になる書籍もご紹介。 システム分析・改善のための業務 フローチャート の書き方 改訂新版 https://www.amazon.co.jp/%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E5%88%86%E6%9E%90%E3%83%BB%E6%94%B9%E5%96%84%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E6%A5%AD%E5%8B%99%E3%83%95%E3%83%AD%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88-%E6%A0%84%E5%8F%A3%E6%AD%A3%E5%AD%9D/dp/4382055776 www.amazon.co.jp 業務改革、 見える化 のための業務フローの描き方 https://www.amazon.co.jp/%E6%A5%AD%E5%8B%99%E6%94%B9%E9%9D%A9%E3%80%81%E8%A6%8B%E3%81%88%E3%82%8B%E5%8C%96%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E6%A5%AD%E5%8B%99%E3%83%95%E3%83%AD%E3%83%BC%E3%81%AE%E6%8F%8F%E3%81%8D%E6%96%B9-%E3%83%97%E3%83%AC%E3%83%9F%E3%82%A2%E3%83%A0%E3%83%96%E3%83%83%E3%82%AF%E3%82%B9%E7%89%88-%E5%B1%B1%E5%8E%9F-%E9%9B%85%E4%BA%BA/dp/4839965560 www.amazon.co.jp 今回は フローチャート の書き方を紹介しました。 特に若手のうちはできるだけ多くの フローチャート を書くことをおススメします。 頭で理解しているつもりの流れを フローチャート で可視化すると、意外な発見や不要・不足のステップが多くあることに気づき、自身の業務理解を早めるだけでなく、マネジメントに必要な「俯瞰する力」、「整理・要約する力」、「他者に説明する力」も高めてくれるはずです。 今回ご紹介した フローチャート の書き方が これから フローチャート を書く方々の一助となれば幸甚です。   当社ではエンジニア 中途採用 に力を入れております。 もし、当社の雰囲気・技術内容等にご興味を持たれましたら以下サイトの募集職種をお気軽にご確認ください! エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
こんにちは、株式会社 ラク スで先行技術検証や、ビジネス部門に技術情報を提供する取り組みを行っている技術推進課に所属している鈴木( @moomooya )です。 ラク スの開発部ではこれまで社内で利用していなかった技術要素を自社の開発に適合するか検証し、ビジネス要求に対して迅速に応えられるようにそなえる 「 開 ( か ) 発の 未 ( み ) 来に 先 ( せん ) 手をうつプロジェクト(通称:かみせんプロジェクト)」 改め 「技術推進プロジェクト」 というプロジェクトがあります。 2020年度上期に「サービス分割を見越した ドメイン 層設計」について取り組んだので、概要を紹介したいと思います。 今までの記事はかみせんカテゴリからどうぞ。 tech-blog.rakus.co.jp 今回の目標 余談:「開発速度を維持するために」サービス分割を検討するというのはなぜ なぜ最初からサービス分割をしないのか モノリスで困ること モジュラーモノリスとは ビジネスロジックの設計方法 実装と機能修正の範囲限定 データストアについて 結論 今後の課題 参考文献 書籍 論文 ブログ記事 今回の目標 2017年に社内で マイクロサービスアーキテクチャについて検証した 際には「サービス立ち上げ時にはマイクロサービス アーキテクチャ は選択するべきではない」という結果が導かれました。 この判断結果は2020年時点でも変わらないものだと感じています。とはいえサービスが大きくなったときに「開発速度を維持するためサービスの分割を検討することになる」というのも正だと思います 1 。 このとき必要に応じて「サービスを分割することが出来る」設計になっていなければ、年単位で移行したという事例が散見されるように、 モノリス からマイクロサービスへの移行は極めて難しい判断になるでしょう。 サービス分割の肝となる部分は「 ビジネスロジック = ドメイン 層が分割可能かどうか」という点だと考えています。なので今回のテーマは「サービス分割を見越した ドメイン 層設計」と設定し調査検証を行っていきました。 余談:「開発速度を維持するために」サービス分割を検討するというのはなぜ プログラマー が扱える適切な ソースコード 量(プログラムの規模)には上限があります。 プログラミング言語 等にも大きく依存しますが、1万行であるとか、1画面に収まる量であるとか、いろいろな観点で語られますが人間に認知限界が存在する限りどこかに限界があります。 そして(特に エンタープライズ 領域の)プログラムの ソースコード は数十万をゆうに超え、数百万を超える場合もあります。明らかに人間が扱える上限を超えています。 上限を超えたプログラムがどうなるか、というと「ロジックのミス」「想定しないバグ」「修正漏れ」が増加することは想像に難くないと思います。そのため適切なボリュームになるようプログラムを分割する必要があると考えます。 なぜ最初からサービス分割をしないのか まずは「サービス立ち上げ時にはマイクロサービス アーキテクチャ を選択しない」のはなぜなのかという話を振り返ります。マイクロサービス アーキテクチャ を採用する、ということがどういうことなのか噛み砕くと以下のようになると思います。 複数の Webサービス を開発・運用し、連携させる (理想としては) Webサービス ごとにチームを構成し、互いに内部の構造は依存しない 複数の Webサービス として作ることでマイクロサービスのメリットとされる技術異質性が確保できたり、物理的にロジックの汚染を防ぐことは出来ますが、それらのメリットを覆すだけの運用コストが発生してしまいます。 Kubernetes などのコンテナ オーケストレーション ツールを高レベルで使いこなすだけの運用スキルがチーム内にあれば解決できるかもしれませんが、結局「高レベルのスキル=高コスト」なので立ち上げ時には向きません。 また Webサービス ごとにチームを構成することで迅速な開発を行っていけるのもメリットですが、物理的に別サービスになっていることと、チームが分かれていることでサービス境界の定義の見直しがしにくくなります。サービス境界の定義が不適切だとマイクロサービス化して得られるはずのサービス感の独立性が失われるため、いわゆる「分散 モノリス 」という アンチパターン に陥ってしまいます。サービス立ち上げ時は一般的に ドメイン 知識も乏しく適切なサービス境界の定義は難しいため選択しにくい選択肢になります。 またサービス立ち上げ時は「扱えない規模のプログラム規模拡大」も「大きな負荷」もまだ発生していません。利益が発生していない時点で、発生していない問題にコストを投入するのは悪手と言えるでしょう。 モノリス で困ること マイクロサービス アーキテクチャ が流行し始めた2016年頃から「モノリシック アーキテクチャ は悪」という主張が散見されました。これには誤りが含まれています。 まずモノリシック(1枚岩) アーキテクチャ の特徴としてデプロイメントラインが1つであることが挙げられます。これは明確にマイクロサービス アーキテクチャ に対してメリットです。複数のデプロイメントラインが存在するとその分デプロイコストはかさみます。 ではモノリシック アーキテクチャ は何が「悪」なのか、というと体験している人も多いと思いますが、モジュール間の参照が複雑に交差することによるスパゲッティ化( Big ball of mud = 大きな泥団子、とも)が起こりやすいことがモノリシック アーキテクチャ の真の問題です。 マイクロサービス アーキテクチャ は構造的にスパゲッティ化が起こりにくい アーキテクチャ です。しかし立ち上げ時にはコスト的に見合いません。であれば、スパゲッティ化しにくい方法(適切なモジュール分割)を適用した モノリス が実現できれば立ち上げ時の有力な候補となりえると考えました。 モジュラー モノリス とは 適切なモジュール分割を行った モノリス を調べていくとそれが「モジュラー モノリス 」と呼ばれていることを知りました。端的に言うと理想的なモジュール分割が行われた「きれいな モノリス 」です。 1つのプログラム内で独立性の高いモジュールとして分割されることで、規模が大きくなったときのサービス分割もやりやすそうに見えました。 またモジュール分割の境界線(サービス境界)を見直したくなった場合でも1つのプログラムの中の話なので、マイクロサービスに比べて見直しやすいとも感じます。 当然 モノリス なのでデプロイメントラインも1つです。 ビジネスロジック の設計方法 実際の ビジネスロジック 層の設計はDDDで出てくるアグリゲートパターン 2 が適用できそうです。 加えてファクトリパターン 3 も適用候補として準備しておくと良いと思います。ちなみに今回の検証ではファクトリパターンを候補にしていなかったため実装の段階で課題に直面することになりました。 詳細はDDD本を参照していただきたいですが、アグリゲートパターンは アグリゲート(集約) 関連するオブジェクトの集まり データを変更する単位(≒DB トランザクション の単位) アグリゲーションルート 外部のアグリゲートとコミュニケーション可能な唯一のオブジェクト(=エンティティ) という概念に基づいていて、アグリゲートの生成もアグリゲーションルートのインタフェース(コンスト ラク タとか)により行います。 ただし、アグリゲートがある程度複雑になってくると生成ロジックも分離したほうがよくなってきます。生成ロジックの分離と カプセル化 を行ったものをファクトリとして扱うのがファクトリパターンです。 ファクトリパターンと言っても実装方法(実装場所)はさまざまなようです。 アグリゲートルート 集約ルート内にファクトリメソッドとして実装 もちろんコンスト ラク タでもよい アグリゲートパターンの部分で触れたケース (アグリゲート内の)別のオブジェクト 生成に関連がつよいオブジェクトにファクトリメソッドをもたせる (アグリゲート外の)別のオブジェクト(もしくは別のサービス) 生成ロジック的にアグリゲート内に収めるべきではない場合はアグリゲートの外におくことをためらわない また、アグリゲートパターンに代わる別の設計手法としてMichael Nygard氏により「ライフサイクルによる分割( Services by Lifecycle )」も提唱されていますが、今回は未検証です。 実装と機能修正の範囲限定 結局実装してみないとわからないので試しに実装してみました。お題は弊社「 楽楽明細 」のような帳票発行サービスをイメージして作ってみました。 アプリ(サービスレイヤ)の部分は ウェブアプリケーション フレームワーク のルーティング処理の実装箇所だと思ってください。 上記のような設計をして、実際に実装してみたのですが先述の通りファクトリパターンを把握していなかったため「アプリ(サービスレイヤ)」の部分に初期化処理を実装してしまいました。 それの何が悪かったかというと機能追加のアップデートを実装したときに顕在化しました。 請求書のテンプレートを送付方法に応じて使い分ける事ができる機能を追加しました。送付方法は「メールにPDF添付」「印刷して郵送」を想定しています。点線部分は追加、修正が入ったモジュールになります。 見ての通り「アプリ(サービスレイヤ)」に修正が入ってしまってます。今回の前提(モジュラー モノリス )であれば実質的な問題はほとんどありませんが、サービス分割後を想定するとサービス全体が停止することになってしまいます。ファクトリメソッドとしてアグリゲートルート内もしくはアグリゲート内にファクトリオブジェクトとして持っていれば「アプリ(サービスレイヤ)」には影響がなく、修正が入っていない受領者アグリゲート、売上レコードアグリゲートに関する機能は動かし続けることが可能になります。 データストアについて 今回は利用していませんでしたが、データストア、主に RDB についても分けておいたほうが良いです。 物理的にDBサーバーを別で用意するとやはり手間がかかるので MySQL でいうdatabase( PostgreSQL だとschema)の単位で分けるとか、もっと簡易にテーブル名で分けておくとかやり方はいろいろあると思いますが、分けておくと良いでしょう。 DBの分け方については参考文献の"Monolith to Microservices"のchapter.4が参考になると思います。 結論 実際に設計、実装してみた感じでもモジュール化(モジュラー モノリス )を目指すことでサービス分割を低コストで実現することは可能そうに思えました。ただし、昔ながらの モノリス より手間が増えることは間違いありません。手間が増える量がマイクロサービスに比べてはるかに少なく現実的な選択肢になるところまで落ち着く可能性がある、というのが適切な評価だと思います。 なので結局はバランスの問題ですが、ある程度サービス拡大が見込める場合には先行投資的にモジュラー モノリス で構成し、賭けの要素が強いサービスの場合は モノリス でコスト最小で昔ながらの モノリス で構成する、といった選択になるのかな、と感じました。 今後の課題 アグリゲートパターンはやはりサービス境界(アグリゲート バウンダリ 、アグリゲート境界)の定義に ドメイン 知識を必要とするため難しい、というのは解決されていません。 モノリス であることで取り返しはつくようになるものの ドメイン 知識が乏しい立ち上がり時に設計することは難易度が高いと思います。 「ライフサイクルによる分割( Services by Lifecycle )」ではサービスの利用フェイズをもとにサービス境界を定義していくという発想によりサービス境界の定義を比較的容易に行うことが出来る可能性を感じるため、ライフサイクルによる分割について今後検証していきたいと考えています。 参考文献 書籍 クリス・リチャードソン『 マイクロサービスパターン 』( インプレス , 2020) ヴァーン・ヴァーノン『 実践ドメイン駆動設計 』( 翔泳社 , 2016) エリック・ エヴァ ンス『 エリック・エヴァンスのドメイン駆動設計 』( 翔泳社 , 2011) サム・ニューマン『 Monolith to Microservices 』( オライリー , 2019) 洋書 nginxから 無料版PDFが配布 されています 論文 Brian Foote & Joseph Yoder, " Big Ball of Mud " ブログ記事 The awesomeness of Modular Monolith (投稿日: 2017/05/08) Sebastian Gebski CTO at Gemius (デジタル マーケティング 企業) マイクロサービスへのアンチテーゼ The Modular Monolith: Rails Architecture (投稿日: 2018/01/23) Dan Manges CTO at Root Insurance ( 自動車保険 ) 元創業CTO at Braintree (支払いプラットフォーム) Rails アプリの アーキテクチャ としての提案 今回扱う内容についての言及はおそらくこれが最初 Deconstructing the Monolith: Designing Software that Maximizes Developer Productivity (投稿日: 2019/02/21) Kirsten Westeinde Dev. Mgr. at Shopify Shopifyによる事例紹介 Modular Monoliths — A Gateway to Microservices (投稿日: 2019/03/31) Natalie Conklin Modular Monolith Primer (投稿日: 2019/12/03) Kamil Grzybek engineer at ITSG Global モジュラー モノリス 入門 モノリスの分解において、マイクロサービスは必然ではない - QCon LondonにおけるSam Newman氏の講演より (投稿日: 2020/06/29) エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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 他にも大きくなってきた負荷を適切に分散したい、なども理由になると思います。 ↩ エリック・ エヴァ ンス『エリック・ エヴァ ンスの ドメイン 駆動設計』 p.123 ↩ エリック・ エヴァ ンス『エリック・ エヴァ ンスの ドメイン 駆動設計』 p.134 ↩
アバター
はじめに こんにちは!three_yagiです。 今回は自宅で使っている Mac と会社で使っている Windows 両方にDockerをインストールし、Docker Hubによるコンテナの共有を試してみたのでそちらの手順について説明してみようと思います。 はじめに Dockerってなに? Docker Hubってなに? WindowsでのDockerインストール 動作環境 手順 MacでのDockerインストール 動作環境 手順 Docker Hubでコンテナを共有 コンテナイメージをPushする docker build docker run docker push コンテナイメージをPullする docker pull おわりに Dockerってなに? Docker社が提供しているコンテナ型の仮想環境を作成、配布、実行するためのプラットフォームです。 コンテナを作成することでOSなどの違いに左右されずに環境を構築することができます。 Dockerやコンテナについては過去の記事で詳しく解説されていますので、ぜひそちらをご覧ください。 tech-blog.rakus.co.jp tech-blog.rakus.co.jp Docker Hubってなに? 同じくDocker社が クラウド サービスとして提供しているDocker向けのコンテナ共有サービスです。 Docker Hubを利用することで他ユーザとのコンテナの共有を行うことができます。自分でコンテナイメージを作成する手間が省けたり、別の環境で同じコンテナを起動したりすることができます。 また、タグを利用して GitHub のようにバージョン管理を行うことも可能です。 利用にはユーザ登録が必要です。 以下の公式サイトの Sign Upからユーザを登録しておきましょう。 Docker Hub Windows でのDockerインストール まずは Windows へのインストールからです。 動作環境   Windows10 Pro (バージョン2004, OSビルド19041.572) 手順 まずは公式サイトからDocker Desktopをダウンロードしましょう。 Get Started with Docker | Docker 公式サイトからDownload for Windows を選択して インストーラ をダウンロードします。 ダウンロードした「Docker for Windows Installer」を起動すると以下の画面が表示されます。 Windows10のバージョン2004からWSL2が正式に導入され、Dockerのバックエンドとして利用できるようになりました。 以前までは Windows でDockerを利用する場合はVirtual Boxや Hyper-V を利用する必要がありましたが、WSL2を利用することでより軽量かつ高速にDockerを使用することができます。 ということで、今回はWSL2でDockerの環境を構築します。「Install required Windows components for WSL2」にチェックをいれてOKを押すとインストールが開始されます。 インストールが完了するとPCの再起動を求められます。 Close and restartをクリックして再起動します。 再起動し、晴れてDockerのインストール完了…となるはずでしたが、以下のようなアラートウインドウが表示されました。 どうやらWSL2のインストールが不完全なようです。 記載されているリンクからWSL2の Linux カーネル を最新化する更新プログラムをダウンロードしましょう。 以前のバージョンの WSL の手動インストール手順 | Microsoft Docs ダウンロードした更新プログラムを実行すると インストーラ が立ち上がるので指示に従ってインストールします。 インストール自体は数秒で完了するはずです。 インストール後、再度先程のアラートウインドウに戻り、RestartをクリックするとDocker Desktopが起動しました! 設定を確認すると、WSL2もちゃんと使われていることが確認できます。 これで Windows へのDockerインストールは完了です。 Mac でのDockerインストール 次に Mac へのDockerインストールについて説明します。 動作環境    MacOS Mojave (10.14) 手順 Windows と同様、公式サイトからDocker Desktopをダウンロードします。 Get Started with Docker | Docker ダウンロードした「Docker. dmg 」を実行すると以下のウィンドウが表示されます。DockerアイコンをApplicationフォルダにdrag and drop してDockerをアプリケーションに追加しましょう。 Launchpadに追加されたDockerアイコンをクリックするとDocker Desktopが起動します。 初回起動時にはDockerの機能がネットワークを使用することに対しての許可を求められます。"OK"を選択し、OSユーザーのパスワードを入力してこれを許可します。 Docker Desktopの初期画面が表示されました。 これで Mac へのDockerのインストールは完了です! Docker Hubでコンテナを共有 Mac とWindowにDockerがインストールできたので、Docker Hubを使って両者間でコンテナを共有してみます。 コンテナイメージをPushする まず Mac 側で共有するコンテナイメージを作成します。 GitHub の チュートリアル を参考にコンソール上に アスキーアート を表示するコンテナを作成します。 ターミナルを開いたら任意の作業 ディレクト リに移動して、git cloneでDocker リポジトリ をクローンします。 ----Mac----- $ git clone https://github.com/docker/doodle.git Cloning into 'doodle'... remote: Enumerating objects: 73, done. remote: Total 73 (delta 0), reused 0 (delta 0), pack-reused 73 Unpacking objects: 100% (73/73), done. docker build 次にコンテナイメージをビルドします。 ビルドは「docker build」コマンドで実行できます。「-t」オプションには作成するコンテナイメージのイメージ名を指定します。今回は"xxxxxxx(DockerHubアカウント名)/cheers2019"をイメージ名としてビルドしました。 ----Mac---- $ cd doodle/cheers2019 $ docker build -t xxxxxxx/cheers2019 . [+] Building 66.4s (12/12) FINISHED => [internal] load build definition from Dockerfile 0.0s 〜〜中略〜〜 => => naming to docker.io/xxxxxxx/cheers2019 docker run ビルドが完了するとコンテナを起動することができます。 「docker run」コマンドでコンテナを起動します。「-it」は対話的な操作を可能にするオプションで、「--rm」はコンテナ終了時にコンテナを自動的に削除するオプションです。 起動に成功すると"Cheer"の アスキーアート が出力されます。ぜひご自身の端末で試してみてください。 ----Mac---- $ docker run -it --rm xxxxxxx/cheers2019 docker push 作成したコンテナイメージをDocker Hubにプッシュしてみます。 「docker login」でDocker Hubにログインします。先程登録したログインIDとパスワードを入力して自分のアカウントにログインします。 「docker push」で自身のアカウントのDocker Hubのレポジトリにコンテナイメージをプッシュできます。 "Pushed"と表示されたら成功です。 ----Mac---- $ docker login Username: xxxxx Password: Email: XXXXXX@XXXXXXX Login Succeeded $ docker push xxxxxxx/cheers2019 The push refers to repository [docker.io/xxxxxxx/cheers2019] 1e2fa4a93dd1: Pushed latest: digest: sha256:7be1af3fac3de80eac34491a7e031123ba5488d92a8f2e563c2a3b057d3253b7 size: 527 ブラウザのDocker Hubにログインするとプッシュしたコンテナイメージが存在することを確認できました。 コンテナイメージをPullする ではDocker Hub上にあるコンテナイメージを Windows 側でPullしてみましょう。 docker pull コマンドプロンプト を起動し「docker login」でDocker Hubにログインします。 「docker pull」でGit Hubの レジストリ からコンテナイメージをローカルにもってきます。 "Pull complete"と表示されたら成功です。 ----Windows---- > docker pull xxxxxxx/cheers2019 Using default tag: latest latest: Pulling from xxxxxxx/cheers2019 3b5197dd02a5: Pull complete Digest: sha256:7be1af3fac3de80eac34491a7e031123ba5488d92a8f2e563c2a3b057d3253b7 Status: Downloaded newer image for xxxxxxx/cheers2019:latest docker.io/xxxxxxx/cheers2019:latest 「docker images」でローカルにあるコンテナイメージを確認できます。 Pullしたコンテナイメージがローカルにあることを確認できました。 ----Windows---- >docker images REPOSITORY TAG IMAGE ID CREATED SIZE xxxxxxx/cheers2019 latest b0d6c9e01637 37 hours ago 4.01MB 「docker run」でコンテナの起動も実行してみたところ、 Mac で起動したときと同じ結果が出力されました。 これで Mac と Windows の間でコンテナの共有ができました。簡単ですね! ----Windows---- >docker run -it --rm xxxxxxx/cheers2019 ~~結果略~~ おわりに Docker Hubを利用して Windows と Mac の両者間でコンテナを共有することができました。 Docker Hubを活用することで別PC、別OSでも簡単に同じ環境を構築できます。複数台のPCをまたいでの開発でも環境構築に頭を悩ませることなく快適に開発できそうです。もちろん他の人とも共有できるので、複数人の開発でも効力を発揮しそうですね。 エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに こんにちは、新卒1年目のYoshidaMichaelです。 私の所属しているチームでは1年目に OSS -DB Silverを取得するという目標があり、この度無事取得に至りましたので私の行った学習方法とその比較、今ゼロから学習を進めるならもっとこうできたな、といった内容をご紹介していきたいと思います。 学習前の知識量は簡単な SQL くらいはわかるけれど運用の知識や細かい SQL は全くわからない程度です。 学習期間は2週間半 (時間にして55時間位?) 、得点は94点でした (合格ライン64点) 。 OSS -DB Silverのスコアレポート はじめに OSS-DB Silverとは 学習方法 学習するときに意識していたこと 学習に使った教材 学習の進め方 反省点 所感 終わりに OSS -DB Silverとは 「そもそも OSS -DB Silverとはなんぞや?」ということなんですが、 特定非営利活動法人 LPI-Japanが オープンソース データベースに関する技術力と知識を公平かつ厳正に、中立的な立場で認定してくれる試験です。Silverの他にGoldというより上位のレベルも存在します。 (とはいえSilverとGoldは全く別物という話もありますので、GoldができればSilverの範囲はマスターできているかと言われるとそれは違うのかなと思ったり) oss-db.jp 学習方法 学習するときに意識していたこと 私が学習を進める上で一番意識していたことは「どういう機能があるか、何ができて何ができないかを覚える。」です。 正直試験なので調べたら一発でわかるようなオプション周りの話とかも出るのですが、その辺りは結構無理して丸暗記しながらも調べてもわからないような「そもそも何ができるか」というところを意識して覚えるようにしていました。 資格だけ取れても使い物にならない技術だと意味ないと個人的には思いますので。 学習に使った教材 OSS 教科書 OSS -DB Silver Ver2.0対応 www.amazon.co.jp 教科書としては優秀だと思います。 会社にあったので辞書的に活用していました。 正直「問題」という点ではあまり試験に役に立ったという実感はないので他でたくさん解いたほうがいいと思います。 本の初めに付いてるチェックリストは試験直前に見返す上で役に立ちました。 サンプル問題/例題解説 oss-db.jp 公式にあるサンプル問題と例題解説です。 サンプルと言いながらもかなり問題数があり、これを2周3周するだけでも十分な力がつくと思います。 ただ、解説はそこまで丁寧ではないので、ここで間違えた問題を OSS 教科書や公式ドキュメント等で調べるのが良いかと。 Ping -t 最強WEB問題集 OSS -DB Silver (Ver2.0) ping-t.com たまたま別件で有料会員だったのでついでにと思い使っていました。 問題数が505問と豊富なこと、解説がそこそこ丁寧なこと、 スマホ 対応なことなど色々便利でした。 これだけやっていても合格はできると思いますが、得点を取るという部分にやや傾倒しているのを感じたので、 PostgreSQL の知識を深めたいという方はその他の方法と合わせたほうが良いかと思います。 学習の進め方 これらの教材を使った上で私は次のように学習を進めていきました。 後述しますが、後から思い返すと1. の部分は無くても良かったかなと思いました。 まず OSS 教科書を一通り読む (約3日) OSS -DBに関してほとんど知識がなかったので、まずは全体観を掴むために3日ほどかけて全部読みました。 この時点では知識の定着を目的とはしていなかったので、「あー、こんなのがあるんだー」くらいで流し読みしました。 サンプル問題、 Ping -tの問題をひたすら解く (約12日) 1周目の時点では OSS 教科書の内容はあまり定着しておらず、ほとんど間違えると思います。 そこで間違えた問題に対して初めて深く学習します。 Ping -t有料会員の方はその解説で学習してもいいと思いますし、そうでない方は OSS 教科書や公式ドキュメントを辞書的に使うといいと思います。 このときも、丸暗記しないといけない部分は仕方ないですが、理由がある部分はそれも合わせて覚えたほうが良いと思います。 ある程度知識が定着してきた単元については通勤中にも Ping -tで問題を解いたりしていました。こういうところは強いですね、 Ping -t。 OSS 教科書の模擬問題を解く (約半日) これはチームのルールとして模擬問題である程度 (9割) 点数が取れてから受験というものがあるので受けました。 サンプル問題で8割、 Ping -tで9割程度正答していましたが模試の結果は68%と結構凹みました。 間違った部分の復習は当然必要ですが、今までの学習がゼロになったわけではないのでもし点数が低くても前向きに学習を続ければ良いと思います。 適宜復習 (約1日) もうここまで来ればあとは各々不足している部分を補う段階かと思います。 OSS 教科書をお持ちの方ははじめについているチェックシートがさっと見直せて個人的には大変便利でした。 反省点 結果無事合格はできたのですが、今この経験を持った上でゼロからまた受験をするとしたらこうしたほうが良かったなという点がいくつかあるので挙げていきます。 はじめの OSS 教科書を一通り読む段階が不要だった どうせ定着する形で頭に入っていないためです。 目次を見て、各箇所の概要説明だけ読んですぐに問題に移行したほうが良かったなと思いました。 サンプル問題、 Ping -tで視野が狭まっていることに気が付かなかった 私の体感ですが、情報の深さは 公式ドキュメント > OSS 教科書 > サンプル問題 > Ping -t の順で深いと思いました。 サンプル問題や Ping -tの問題を解くだけであれば知らなくても良いオプション等についても OSS 教科書には載っているなんてことも何度もありました。 OSS 教科書を推すわけではありませんが、公式のドキュメントなど、より濃い情報があるものをもっと活用するべきだと感じました。 あまり手を動かさなかった しっかりと環境を用意するのが面倒で、職場以外ではあまり手を動かした学習をしていませんでした。 やはりコマンドを実際に打ち込んでその結果を見ると頭に残りますし、何より楽しいので少し時間を使ってもそのような環境は作ったほうが良いと思いました。 最近だとDockerなどを使うと楽なのかもしれないので早くDockerマスターになりたいですね。 所感 実は受験前からこのような記事を書こうと決めていたので記事に説得力を持たせるためにも高いスコアで合格したいと考えていました。 もちろん自宅での学習もかなり行ったのですが、業務時間でも学習用の時間をいただくことが出来たので本当に恵まれているなぁと感じます。 まだまだ実務経験が浅いこともあり、実際に業務に活かせるかはまた別の問題になりますが、一通り体系的な知識を得ることが出来たので良い経験となりました。 次はこの知識が少しでも今後に活かせるようアウトプットについても考えていきたいですね。 終わりに いかがでしたでしょうか? 今回は OSS -DB Silverの学習体験記とその反省について記事を書かせていただきました。 この記事が今から OSS -DB Silverを受験してみようという方の参考に少しでもなれば幸いです。 それではまた! エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
こんにちは、 MasaKu です。 2020年9月8日に Laravel 8 がリリースされました。 laravel.com Laravel 8 では セキュリティ周りの強化として Laravel Jetstream という新しいスキャフォールディングが注目されています。 jetstream.laravel.com しかし、レート制限の新機能にも注目です! 今回はレート制限の解説と新機能部分の説明を行いたいと思います。 レート制限とは 1. 特定のアクション(APIなど)に個別の制限をかける 2. 認証を通過したユーザとゲストユーザで制限を分ける 3. 特別なオプションを保有しているユーザだけは制限を開放する おわりに 参考サイト レート制限とは Laravel には DoS攻撃 などの大量アクセス対策として、単位時間当たりに一定以上のアクセスを検知するとアクセス拒否する機能が導入されておりました。 readouble.com 最初にこの機能を知ったときは Apache や Nginx などの Webサーバ側で制限すればいいんじゃないの? と思っていましたが、以下のようなケースではアプリケーション側で制御するほうが都合が良いことに気が付きました。 特定のアクション( API など)に個別の制限をかけたい 認証を通過したユーザとゲストユーザで制限を分けたい 特別なオプションを 保有 しているユーザだけは制限を開放したい 上記はいずれも Laravel 8 以前から実現できましたが、より直感的かつ簡潔に実装できるようになりましたので、Laravel 8 での実装方法について説明したいと思います。 1. 特定のアクション( API など)に個別の制限をかける まず、前提としてレート制限は throttle という ミドルウェア を利用して実装します。 この ミドルウェア にリミッター名と任意のレート制限を設定します。 app/Providers/RouteServiceProvider.php の configureRateLimiting メソッドに以下のような処理を追加します。 <?php // 一部省略 class RouteServiceProvider extends ServiceProvider { // 一部省略 protected function configureRateLimiting () { // リミッター名と制限値を設定 RateLimiter ::for ( 'testLimit' , function ( Request $ request ) { // 1分間に5アクセスまでの制限を追加 return Limit :: perMinute ( 5 ) ; }) ; } } 後は、ルーティングを記載している routes/web.php にレート制限をかけたいアクションに対し throttle ミドルウェア を設定するだけです。 throttle ミドルウェア には上記で設定したリミッター名を指定します。 <?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\TestController; // アクセス制限をかけたいアクションに上記で設定したリミッター名を設定 Route :: middleware ([ 'throttle:testLimit' ]) -> get ( '/test' , [ TestController :: class , 'index' ]) ; なお、 ミドルウェア は複数のアクションをグルーピングできますので、以下のように各アクションに対して同じリミッターを適応することもできます。 <?php Route :: middleware ([ 'throttle:testLimitUser' ]) -> group ( function () { Route :: get ( '/test1' , [ TestController :: class , 'index' ]) ; Route :: get ( '/test2' , [ TestController :: class , 'index' ]) ; }) ; 上記のように記載することで /test1 と /test2 それぞれへのアクセスの合計回数を1分間5回にする制限を付けることができます。 2. 認証を通過したユーザとゲストユーザで制限を分ける 次はログイン認証を通過したユーザとゲストユーザで制限を分けてみます。 先ほど修正した app/Providers/RouteServiceProvider.php の configureRateLimiting メソッドを以下の通り修正します。 <?php RateLimiter ::for ( 'testLimit' , function ( Request $ request ) { return $ request -> user () ? Limit :: none () : Limit :: perMinute ( 5 ) ; }) ; ログイン認証を通過しているユーザがアクセスした場合、Request オブジェクトにはユーザ情報がセットされます。 そのため、認証済みのユーザの場合はレートの制限が解放されますが、認証前のユーザの場合は1分間5アクセスまでの制限を付けられます。 3. 特別なオプションを 保有 しているユーザだけは制限を開放する 認証後のユーザオブジェクトは app\Models\User.php モデルが利用されますので、こちらに独自メソッドを追加することで特別なオプションを持つユーザだけをレート制限から解放することができます。 まずは、以下のようにして app\Models\User.php に独自メソッドを追加します。 <?php // 省略 class User extends Authenticatable { // 省略 public function vipCustomer (){ // rakus.co.jp のドメインで登録されているユーザのみ制限を解除する if ( strpos ( $ this -> email, '@rakus.co.jp' ) !== false ){ return true ; } return false ; } } あとは、リミッター内で上記で設定した独自関数を実行すれば特別なオプションを持つユーザのみアクセス制限を解除することができます。 <?php RateLimiter ::for ( 'testLimit' , function ( Request $ request ) { return $ request -> user () -> vipCustomer () ? Limit :: none () : Limit :: perMinute ( 5 ) ; }) ; また、上記に加えて、 by でメソッドチェインをすると特定のIPからのアクセスを制限する、などの処理を追加できます。 <?php RateLimiter ::for ( 'testLimit' , function ( Request $ request ) { return $ request -> user () -> vipCustomer () ? Limit :: none () : Limit :: perMinute ( 5 ) -> by ( $ request -> ip ()) ; }) ; おわりに いかがでしたでしょうか。 Laravel は非常に多くの機能があるため、こんなこともできるんだ!と驚くような便利な機能に気づいていないことがあります。 新機能のリリースによって、前バージョンよりも使いやすくなったりわかりやすくなることによって、いままで注目されていなかった機能にも気づいてもらいやすくなるのではないかと思います。 そのほかにも、便利な機能がリリースされておりますので、気になった方は是非ご確認ください! 参考サイト Release Notes - Laravel - The PHP Framework For Web Artisans Introduction | Laravel Jetstream ルーティング 8.x Laravel LaravelのAPIで429 Too Many Requestsが返る - suzu6の技術ブログ エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
はじめに こんにちは、 @rs_tukki です。 突然ですが、皆さんは iOS でアプリをリリースする際、以下のような表示を見たことがあるでしょうか。 輸出 コンプライアンス 情報 Appには暗号化が使用されていますか?Appに使用されているのが iOS および macOS の標準的な暗号化のみである場合も「はい」を選択します。 暗号化というと難しく聞こえますが、実は一般的な HTTPS 通信もこの暗号化に含まれています。 *1 そして、 App Store や Google Play でリリースするアプリにこの暗号化が使用されている場合、「年度末自己分類報告書」というものを毎年作成し、提出する必要があります。 今回は、その書類の書き方・出し方を調べてみました。 はじめに なぜ「年度末自己分類報告書」の記載が必要なのか? 報告書の書き方 報告書の出し方 まとめ 参考 なぜ「年度末自己分類報告書」の記載が必要なのか? そもそも何故このような報告書を記載しなければいけないのかというと、 ざっくり言ってしまえば「 アメリ カの輸出規制の法律に対応するため」です。 App Store や Google Play でリリースするアプリはいずれも アメリ カのサーバから配信されており、日本を対象としたアプリをリリースする場合、厳密には アメリ カから日本へ輸出されるもの とみなされます。 暗号化の技術を使用した商品を アメリ カ国外へ輸出する場合、それがどういうものなのかを記載し、 アメリ カ政府に報告する義務があると定められています。 報告書はその年の1月~12月までに作成された商品である場合、翌年の2月1日までに提出する必要があります。 特に スマホ アプリの場合は、全く変更がなかったとしても毎年提出しなければなりません。 報告書の書き方 アメリ カに出す報告書とあって記載内容は全て英語ですが、そこまで難しい内容ではないため身構える必要はありません。 アプリごとに、以下12の項目を csv ファイルに記載するのみです。(1行目にはこれらの項目名を記載します) PRODUCT NAME MODEL NUMBER MANUFACTURER ECCN AUTHORIZATION TYPE ITEM TYPE SUBMITTER NAME TELEPHONE NUMBER E-MAIL ADDRESS MAILING ADDRESS NON-U.S. COMPONENTS NON-U.S. MANUFACTURING LOCATIONS PRODUCT NAME 商品名。ストアで公開しているアプリ名を英語で記載すればOKです。 MODEL NUMBER モデル番号。 iOS , Android どちらもアプリ固有のIDを記載すれば問題ないはずです。 App Store の場合はこちら、 Google Play の場合はこちらに記載されています。 MANUFACTURER アプリの主な提供社名。提出者本人が主な提供者であれば「SELF」と記載します。 ECCN 輸出規制分類番号。 スマホ アプリは5D002もしくは5D992に分類されますが、 HTTPS 通信のみを行うアプリであれば5D992でOKです。 *2 AUTHORIZATION TYPE 暗号化認証タイプ識別子。ENCもしくはMMKTのどちらかですが、ECCNの項目が5D992の場合はMMKT(Mass Market)を選択するのが一般的のようです。 ITEM TYPE 商品分類。 スマホ アプリの場合は「mobility and mobile applications n.e.s.」と記載します。 SUBMITTER NAME TELEPHONE NUMBER E-MAIL ADDRESS MAILING ADDRESS この辺りはそのまま、提供者名/電話番号/メールアドレス/住所を記載すればOKです。特に理由がなければ、ストアに登録したものを流用すればよいかと思います。 NON-U.S. COMPONENTS アメリ カ以外で作成された暗号化技術を使っているかどうか。 HTTPS 通信しか使用していないのであれば「NO」でOKです。 NON-U.S. MANUFACTURING LOCATIONS アメリ カ以外で作成されたアプリの場合、その場所を記載します。「Tokyo Japan」といった粒度の記載で大丈夫です。 報告書の出し方 さて、これで完成した csv ファイルですが、特に難しい手続きを行う必要はなく、以下2種類のメールアドレスに添付して送信すればOKです。 crypt-supp8@bis.doc.gov enc@ nsa .gov Subject:Annual Self Classification Report Dear Sir/Madam, Thank you very much for your time reading this message. Please find attached our report. If you require any further information, let me know. Best Regards, まとめ 今回は、意外と気にしてない年度末自己分類報告書の書き方とその出し方について記事にしてみました。 分かってしまえば何のことはない内容ですので、ぜひこれを機に書いてみてください。 何か間違っている箇所があれば教えていただけると助かります(小声) 参考 輸出コンプライアンスの概要 - App Store Connect ヘルプ https://blog.hakoniwa.net/archives/1537 http://www009.upp.so-net.ne.jp/kgm1_ear/cipher4/Howto_file_selfClassify.htm iOSアプリ提出の輸出コンプライアンスで、通信にHTTPSを使っているだけの場合の解釈 - Qiita §742 付則 No.8 暗号品目に対する自己番号分類報告 カテゴリー5-通信及び”情報セキュリティ”/パート 2-”情報セキュリティ” アメリカ合衆国からの暗号の輸出規制 - Wikipedia app store - Which ECCN should I use for iOS app which uses HTTPS? - Stack Overflow エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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 : 輸出コンプライアンスの概要 - App Store Connect ヘルプ には「セキュリティで保護されたチャンネル (例: HTTPS 、 SSL など) を使って電話をかける場合」が暗号化の使用にみなされるとの記載がある。 *2 : 参考: アメリカ合衆国からの暗号の輸出規制 - Wikipedia
アバター
はじめに こんにちは、itoken1013です。すっかり秋ですね! 今回は近年エンジニアに大人気のエディタの1つである Visual Studio Code ( VSCode )のインストールと日本語表記の手順を示し、入門エンジニアがいち早く開発のスタートラインに立てるようにご説明していきたいと思います。 Visual Studio Code は ラク スの中でも支持するエンジニアが多く、実際の開発業務でも十分活用していけるツールです。 一方で Visual Studio Code は世界中で利用されているため、インストール直後では英語表記となっており、日本語のツールをメインで使う入門エンジニアには若干の使いづらさを感じさせる見た目となっています。 今回は Windows と MacOS 別に日本語表記の手順を示していきますので、どちらのユーザーの方も安心して読んでいただければと思います! tech-blog.rakus.co.jp はじめに 手順のご紹介 手順1. VSCodeのインストール Windowsの場合 Macの場合 手順2. VSCodeの日本語化 手順2-1. 「Extension」を表示する 手順2-2. Marketplaceから日本語用の拡張機能を探す 手順2-3. 日本語の表示設定に変更する 手順2-4. VSCodeを再起動する 補足. 一時的に日本語以外の表記でVSCodeを起動する方法 終わりに 手順のご紹介 それでは早速ここから Visual Studio Code ( VSCode )のインストールと日本語化のステップに分け、手順を紹介してまいります! 手順1. VSCode のインストール まずはインストールの手順からです。 お使いのOSが Windows ・ Mac かに関わらず、まずは VSCode の インストーラ およびパッケージの入手が必要となります。 ブラウザを開いて、 VSCode の作成元である Microsoft 社のページ(以下)にアクセスしてください。 ページにアクセスすると、中央に Visual Studio Code のダウンロード案内が確認できます。 visualstudio.microsoft.com Windows の場合 「 Visual Studio Code のダウンロード」の右端にある下矢印マークをクリックし、「 Windows x64」をクリックすると VSCode の インストーラ のダウンロードが開始されます。 ダウンロードの完了後、 インストーラ をクリックして起動しましょう。 最初の「使用許諾契約書の同意」を「同意する(A)」に変更する以外はデフォルトの状態で進み、インストールを実行してください。 手順を進むと最後に「 Visual Studio Code を実行する」がチェックONの状態となります。 このまま「完了」をクリックし、 VSCode が起動すればインストール完了です! Mac の場合 「 Visual Studio Code のダウンロード」の右端にある下矢印マークをクリックし、「 mac OS 」をクリックすると VSCode のパッケージがダウンロードされます。 次にFinder上でダウンロードフォルダへ移動し、「 Visual Studio Code 」をアプリケーションフォルダへドラッグしてください。 これで Mac 上で VSCode を起動する準備ができました。 あとはアプリケーションフォルダ上で「 Visual Studio Code 」をダブルクリックし、 VSCode が起動すればインストール完了です! 手順2. VSCode の日本語化 次に VSCode を日本語の表示に変更する手順を説明します。 VSCode ではインターネット上の Marketplace という場所から「 拡張機能 」をインストールし、様々な機能を追加してカスタマイズを加えていくことができます。 日本語化も 「Japanese Language Pack for Visual Studio Code 」 という 拡張機能 をインストールすることで、 VSCode の表示を日本語に変更できます。 ここから先の手順は Windows でも Mac でも共通となりますので、1つの手順として日本語化の流れを紹介していきます。 手順2-1. 「Extension」を表示する VSCode を起動して、左側のアクティビティバー一番下にある「Extension」をクリックしてください。 クリック後、インストール可能な 拡張機能 が一覧表示されます。 ※アクティビティバーが表示されていない場合には、上部にあるメニューバーから以下の手順で表示させてください。 View > Appearance > Show Activity Bar (日本語だと表示 > 外観 > アクティビティバーを表示する) 手順2-2. Marketplaceから日本語用の 拡張機能 を探す 次に表示されたテキストボックスに 「Japanese Language Pack」 と入力すると、今回のインストール対象の日本語化の 拡張機能 「Japanese Language Pack for Visual Studio Code 」が表示されます。 名称を確認の上、「Japanese Language Pack for Visual Studio Code 」の右下にある「Install」をクリックしてください。これで日本語化の 拡張機能 がインストールされます。 手順2-3. 日本語の表示設定に変更する インストールが完了すると、手順2-2では「Install」と表記されていた箇所が歯車マークに変わります。 マークの変更を確認後、次に VSCode の日本語化用に表記設定を変更します。 Windows の方は「Control + Shift + P」、 Mac の方は「Command + Shift + P」でコマンドパレットを起動し、 「Configure Display Language」 と入力してEnterキーを入力してください。 次に言語の選択が求められます。 「en」と「ja」が表示されますので、「ja」を選択してEnterキーを入力してください。 これで日本語化になるよう、 VSCode 内で設定が変更されます。 手順2-4. VSCode を再起動する この後、「A restart is ~ 」という表記のダイアログが表示されますので、「Restart」を選択してください。(「言語の切り替えには、 VSCode の再起動が必要です」という案内になります) 再起動後、無事に各箇所が日本語化されているはずです。 無事に日本語化されましたか? これで今回の作業は完了です!お疲れ様でした! 補足. 一時的に日本語以外の表記で VSCode を起動する方法 ここまで日本語に表示を切り替える設定方法を紹介してきましたが、何らかの理由で一時的に日本語以外の表記へ変更したいケースがあるかもしれません。 現在起動している Visual Studio Code だけ日本語ではない表記に変更するには、 コマンドライン から Visual Studio Code を起動し、オプションに ロケール (言語と地域の設定情報)を明示的に指定することで実現できます。 この手順も実際にやってみましょう。 まずはコマンドから Visual Studio Code を立ち上げるために、ターミナルを立ち上げましょう。 Windows であれば コマンドプロンプト や GitBash、 Mac であればターミナルでよいでしょう。 次にターミナルが立ち上がりましたら、ターミナルの コマンドライン 上に「code」と入力してEnterキーを押してください。 これだけで Visual Studio Code がオープンします。 ただしこの状態だと、画面上から Visual Studio Code を起動した場合と同様、 ツールバー などが日本語で表示されている状態となります。 いったん Visual Studio Code を終了して、再度ターミナルに戻って下さい。 次に日本語以外(ここでは英語とします)の ロケール を指定するために、 コマンドライン 上に「code --locale="en" 」と入力して、Enterキーを押してください。 あらためて Visual Studio Code が立ち上がり、 ツールバー などが英語で表示されていることが確認できるはずです。 これで日本語以外での表示を実現できました! ちなみにターミナルは Visual Studio Code にも備え付けられていますので、上記の ロケール 指定は Visual Studio Code からも実施できます。 (ターミナルは上部にあるメニューバーの ターミナル > 新しいターミナル から起動できます) Visual Studio Code のターミナル上で同様のコマンドを打てば、「現在立ち上がっている Visual Studio Code は日本語だけど、もう1つ別の言語の VSCode を立ち上げたい」ということも実現できます。 (以下の図では左が日本語、右が英語で立ち上げています) 日本語以外に切り替えるケースはなかなか実施機会は少ないかもしれませんが、日本語の表示設定を実施したからといって別の言語へ変更できないわけではないという点を覚えておいていただければと思います。 またこちらで説明した内容は、 Visual Studio Code に用意されている コマンドライン インターフェース機能( CUI )に関連しています。 コマンドライン インターフェースには ロケール の切り替え以外にも、様々な機能が用意されています。 また日本語や英語以外の表記についても、各国の ロケール を指定することで実現が可能です。 ご興味のある方はこちらをご確認の上、日本語と英語以外の言語にも切り替えてみていただければと思います。 vscode-doc-jp.github.io 終わりに いかがでしたでしょうか? 終了してしまえば簡単な作業だったかもしれませんが、何の ガイドライン もなく、いきなり日本語へ切り替えずに操作をするのは少しハードルが高く感じてしまう方が多いのではないかと思います。 VSCode には日本語への切り替え以外にも便利な 拡張機能 が豊富に用意されており、皆さんの開発を手助けする便利ツールに溢れています。 無料で使えて超便利な VSCode を使いこなし、上級者への道を進んでいただければと思います! それではまた次回の記事でお会いしましょう! エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
アバター
はじめに 社会人として2年目になろうというタイミング(今年の4月)で急遽、 スマホ アプリの開発を担当することになりました。 スマホ アプリは初めての開発だったため、 Android ・ iOS それぞれの開発の学習を行いました。 iOS : Xcode /Swift Android : Android Studio /Kotlin 両方の学習を終えて振り返ってみると、 Android より Xcode を用いた iOS の開発の方が新しい発見が多く、面白く感じました。そこで今回は、 Xcode で開発した iOS アプリを 実機/ iPhone でデバック・動作確認を行うまでの流れを解説しようと思います。 はじめに そもそもX-codeとは ダウンロード・インストール 作業時の落とし穴 1. Xcodeをインストールできない場合がある 2. XcodeとSwiftのバージョンの組み合わせは決まっている プロジェクトを作成する/選択する 実機でデバックするための設定 おまけ:Provisioning Profile とは さいごに ※記事作成時の環境 MacOS :Catalina Xcode :ver.12 そもそもX-codeとは 「 Xcode 」とは、 MacOS で使用できる開発ツールの一つで、様々な Apple 製品( iOS / iPhone 、watchOS/ Apple Watch 、etc...)で使用できるアプリを作成することができます。 Xcode に記述していく プログラミング言語 である「Swift」または「 Objective-C 」を用いてコードを記述していき、実機・ エミュレーター を使った動作確認や、開発に必須なテスト・デバックも簡単に実行可能です。 「 App Store 」に様々なアプリが公開されていますが、そのほとんどが Xcode で作成されていると言っても過言ではありません。つまり、この Xcode を使いこなすことができれば、 iPhone アプリなどを自作することができるということです。 ダウンロード・インストール Xcode の一番手軽なインストール方法は MacBook の「 App Store 」からのダウンロードです。 App Store で 「 Xcode 」と検索すれば出てきます。 ※すでに Xcode がインストール済みのため「アップデート」になっていますが、未インストールであれば「インストール」が表示されます 「インストール」を押すと、 MacBook にダウンロード・インストールが開始されます。(約8Gあるので時間がかかります。) これで最新版の Xcode をインストールでき、さらに新しいバージョンの Xcode が公開されたときも、「 App Store 」から簡単にバージョンアップが可能となります。 作業時の落とし穴 「とても簡単!」と思うかもしれませんが、 実はここまでで一つ 落とし穴 があります。 これから解説する以下の点を疎かにすると危険ですので、作業前に必ずご一読ください。 1. Xcode をインストールできない場合がある お使いの MacBook の「 MacOS のバージョン」によって、インストールできる「 Xcode のバージョン」に"上限"があり、昔のバージョンの MacOS を使用していると、特定のバージョン以降の Xcode がインストールできなくなります。 2. Xcode とSwiftのバージョンの組み合わせは決まっている Xcode をインストールするとSwiftも自動的にインストールされるため、そのままSwiftのコードを記述することができます。 裏を返すと、インストールする際にSwiftのバージョンを選ぶことができません。 整理すると、 MacOS 、 Xcode 、Swift それぞれのバージョンの組み合わせに制約があるこということになります。 App Store には最新版が公開されているので、 最新の MacOS でなければインストールできない可能性が高い 最新のバージョンのSwiftがインストールされる ということになります。 「バージョンなんて気にしない/しなくても良い」という方は、 App Store での管理が一番楽だと思います。 しかし、環境の影響で MacOS を自由にアップデートできない・指定のバージョンのSwiftを使用したい といったケースは少なくないと思います。 そういった場合は、「 App Store 」からではなく、 Apple Developerサイトからから任意のバージョンの Xcode を直接ダウンロードしてください。 https://developer.apple.com/download/more/ ダウンロードしたファイルを実行することでインストールを行うことができます。 ここでも一つ注意しなければいけないことがあります。 「 Xcode のバージョン」によってデバック・動作確認することができる「実機のOSのバージョン」に 上限 があります。つまり、古い Xcode を使うと、 iPhone の iOS のバージョンによって開発したアプリをインストールできないケースがあるのです。 このパートをまとめると、 Xcode をインストールする前に以下のそれぞれのバージョンを確認し、条件にあったバージョンを選択する必要があるということです。 MacOS のバージョン 接続するデ バイス OSバージョン 使用したいSwiftのバージョン 何も意識せず、 Xcode をインストールするとハマる場合があるのでご注意ください。 ※各バージョンがどのように紐づいているかは、ググれば簡単に出てくると思います。 プロジェクトを作成する/選択する Xcode を起動すると、以下の画面が表示されます。 ※ここからの画面画像は Xcode のバージョンによって若干異なることが多々あります。 Create a new Xcode project:新規プロジェクトを作成する。新しくアプリを作成する場合はここから。 Clone an existing project:Git Repositoryからプロジェクトを作成する。 Open a project or file:ローカルにあるプロジェクトを開きます。 プロジェクトを初めて作成する場合は「Create a new Xcode project」を押下します。 Xcode11には「Get started with a playground:Swiftプログラムを記述し動作確認を行うモード」があり、練習に使ってましたがXcode12で消えてしまいました、、、(探したらあるかもしれない) 次に、以下のような画面が表示されます。 ここでは、開発するOSとそのテンプレートを選択します。 OS 開発しようとしているアプリのOSを選択してください。 テンプレート はじめて Xcode を触る方でとりあえず実機でのデバックを行いたい(Hellow Worldを表示させたい)ということであれば、「Single View app」を選択します。 作成するアプリが決まっている方は任意に選んでいただいて構いません。 次の画面です。 Product Name:プロジェクトの名前です(任意の値に設定) Team:プロジェクトを作成するアカウント・チームを選択します Xcode に設定した Apple IDで選択可能なチームから選択できます(後ほどログインに関して説明します) Noneでも開発可能ですが実機でデバックすることができません(後から変更可能) Organization Identifier:アプリを一意に識別する”Bundle Identifier”に用いられる 今回は任意の名称で構いません。アプリを公開する場合には、慎重に作成してください。 Organization Identifier + . + Product Name になる Interface:SwiftUIかstoryboardから選択できます Life Cycle:SwiftUI App か、UIKit App Delegate から選択できます Language:コーディングする際の言語を選択する(SwiftとObject-Cから選択可能) 上記の設定が完了すると、プロジェクトを作成する場所(保存先)の設定画面に進みますので、任意の場所を選択してください。 ここまでの設定が完了すると、いよいよ Xcode の開発画面が表示されます。 実機でデバックするための設定 昔は" Apple Developer Program"という有料プラン(年間 11800円)に加入していることが必須でしたが、現在は無料で実機にデバックすることができます。(ただし以下の制限があります) デバックのみ(リリースは不可能) アプリの有効期限は7日 プッシュ通知機能を使用することができない 今回は、無料の方法を説明していきます。 有料/無料の違いで、手順が異なるようです。 1: Apple ID でログインする Xcode で、 Apple のアカウントにログインする必要があります。 メニューバー > Xcode > Preferences > Accounts 画面へ進み、左下の「+」→「 Apple ID」→「Continue」の順にクリックします。 Apple IDの情報を入力し、登録処理を完了させてください。 2:証明書を作成し、キーチェーンに登録する メニューバー > Xcode > Preferences > Accounts 画面へ進み、右下の「Manage Certificates…」をクリックします。 左下の「+」ボタン →「 iOS Development」を選択 → 「Done」をクリックします。 これで、実機でデバックを行うための証明書が作成され、キーチェーンに登録されます。 3: iPhone に開発元を信用させる 上記の部分を接続している自分の iPhone を選択して実行することでデバックが可能となります。 まず、 iPhone と Mac をUSBで接続します。 そして、接続した実機を選択します。(ここで、任意の エミュレーター を選択すれば画面上で動作を確認することもできます) 再生ボタン:▶ を押下すると実機に対してインストールを行い、デバックが可能となるはずですが、このタイミングでエラーが発生することが多いです。 一例の解決方法を紹介します。 3.1:Bundle Identifierが重複している Bundle Identifierが重複しないように複雑なものに変更してください。 3.2:「Team」が指定されていない 「Team」の設定が"None"になっていたら、登録した自分の Apple ID に変更してください。(または、「Team」設定に問題がないか確認してください) 上記エラーは初めての操作の場合、必ず発生します。 以下の手順を「接続している iPhone 」で行うとアプリが実行可能になります。 1. 「設定」 > 「一般」 > 「プロファイルとデ バイス 管理」画面を開く 2. 「 デベロッパ App」の欄に表示されている「登録した Apple アカウント」をタップする 3. 再び「登録した Apple アカウント」をタップする 4. 表示されるダイアログで「信頼」をタップする ここまで完了すると、ホーム画面(アプリ一覧画面)でインストールしたアプリの動作確認ができます。 おまけ:Provisioning Profile とは Xcode を使って、実機に対してビルドする際に必要なのが、Provisioning Profileです。 Provisioning Profile とは、アプリ情報、 Apple ID、証明書、実行可能デ バイス の情報が紐づいたデータで、 Xcode 上でアプリを実機用にビルドする際に必要なものになります。 ビルド時に、Provisioning Profile の情報から以下を確認し、問題がない場合はビルドされます。 開発者として登録した証明書がキーチェーンに登録されたPCであること 開発機として登録されているデ バイス がインストール対象であること このような制限を設けることで、アプリが不正に配布されることを防いでいます。 無料でデバックする場合は、プロビジョニングファイルを意識する必要がありませんでしたが、おそらく 「実機でデバックするための設定」の1~3の手順を踏んでいる裏で 作成されているのではないかと推測します。(違っていたらごめんなさい、、、) " Apple Developer Program"に登録している場合は、 Apple DeveloperサイトにUDID(デ バイス 情報)などを登録し、同サイトで作成、 Mac へダウンロードする必要があるみたいです。(こちらも詳しく確認したかったのですが、お金に余裕ができてからにします、、、) さいごに 自作したアプリが自分の iPhone で動かせるようになると、開発のモチベーションになると思います。 私も便利なアプリを自作し、お金に余裕ができたら" Apple Developer Program"に登録しようと思います! エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 rakus.hubspotpagebuilder.com ラク スDevelopers登録フォーム https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! ◆TECH PLAY techplay.jp ◆connpass rakus.connpass.com
アバター
はじめに 9/29(水)に行われました 『UI/UXデザイナーLT会 #uiuxdesignerslt』 のイベントレポートを発信させていただきます! 申し込みは300名の満枠、当日もたくさんの方にご参加いただけたイベントになりました! rakus.connpass.com はじめに イベント概要 発表の紹介 1. 伝わらない UI UX の 正しい伝え方 / 木村圭 2. UIを止めるな! ~UIデザインのコンサルティングで話すこと~ / yumemiさん 3. デザイナーとして入社した私がフロントエンド領域から届ける体験価値とは / Three4Cさん 4. 三次元的アクセシビリティ解釈。価値、多様性、そして時間 / masuP9さん 5. 新卒2年目のデザイナーが大事にすること / yuriさん 6. TypeScriptで解説する催眠術のかけ方 / Ouji Miyaharaさん 7. Adobe XDでつくるVUIプロトタイピング / Makiko Odaniさん 8. デザイナー採用のUXデザインに取り組み始めた話 / TomoyoHirokawaさん 9. UIデザインの呪術性 - 覚書- / yuki_sasakiさん 10. デザイナー 1 年目のわたしが考えるデザイン / uknmrさん 11. 生産性が上がる文章の書き方と、デザインと文章の関係性 / ShinyaSatoさん 12. 技術とデザインの間 / takanoripさん 13. TypeScriptではじめるUIデザイン / kgsiさん 14. Web UIの実装で考えていることと気をつけたいこと / yamanokuさん 15.3次元のカラーピッカー的なものを作ってみた / chooさん 16. BtoB SaaSのUIリニューアルの苦労 / 小林肇 おわりに イベント概要 今回はUI/UXデザイナー16名による怒涛のLT会を開催させていただきました。 UI/UXデザインをテーマとしたイベントはconnpassを探しても多くなく、16名という大人数でもあっという間にLT枠が埋まりました。 また今回が登壇へ初チャレンジでした方々には、登壇機会をご提供できた形となったことを大変嬉しく思います。 当日は各登壇者16名の個性的な発表により、最後までコメントやツイートが止まりませんでした。 Twitter のタイムラインも大変賑わい、催眠術とカレーという謎の文言の他、ご参加の方からも便利情報のリンクなどをシェアいただけました。 タイムラインを眺めるだけでも学べる情報に溢れていますので、ぜひご覧になっていただき、当日の盛り上がりを感じていただければと思います。 twitter.com ちなみに当日イベントに参加いただいた方の職種は、以下の割合でした。 UI/UXデザイナー:41% エンジニア:39% 学生:5% その他デザイン関連職種:5% その他ビジネス職種:10% 発表の紹介 それでは今回ご登壇いただいた16名の方のコンテンツを紹介させていただきます。 本当に幅広いキャリアの方々に発表をいただき、ありがとうございました! 1. 伝わらない UI UX の 正しい伝え方 / 木村圭 まずは ラク スのマネージャーである木村から、UI/UXデザイナーの立場からのプロジェクトメンバーとのコミュニケーション(説明力)について、発表させていただきました。 関係するメンバーに思うように意図を伝えられない、UI/UXの重要性が浸透しない、などの悩みを抱えている方には必見の内容です! speakerdeck.com 2. UIを止めるな! ~UIデザインの コンサルティング で話すこと~ / yumemiさん UIデザインと コンサルティング に取り組まれている yumemiさんより、日々のお仕事で考えている「デザインの使いやすさ、デザインの本来あるべき姿」を オブジェクト指向 UIの例などを交えつつ、ご紹介いただきました。 「行動」と「結果」が直接結びつかなくなった歴史を踏まえると、「UIを止めるな」の意図が深く理解できた気がします。 エンジニア目線でもUXに関わる上で必要な視点のように思えますね。 speakerdeck.com 3. デザイナーとして入社した私がフロントエンド領域から届ける体験価値とは / Three4Cさん 新卒2年目のデザイナーであるThree4Cさんが考える、デザイナーとしてのフロントエンド領域への関わり方を発表いただきました。 ご自身の経験をもとに企画・分析・開発チームと関わる上での姿勢や知識の深め方、今後のありたい姿を語っていただきました。 ご自身の現在地と置かれている状況をしっかり客観視されており、初登壇とは思えない素晴らしい発表でした。 speakerdeck.com 4. 三次元的 アクセシビリティ 解釈。価値、多様性、そして時間 / masuP9さん masuP9さんは非常に個性的に登場し、なんと その場で説明資料を作成される斬新な発表 でした! 発表は アクセシビリティ と「価値」に対するお考えが中心でしたが、その発表方法はとても衝撃的でした。 発表動画を公開できないことが残念です! また ラク スの主催イベントでのご登壇を楽しみにしています! 5. 新卒2年目のデザイナーが大事にすること / yuriさん デザイナー新卒2年目のyuriさんより、freeeさんの共通の価値観である「マジ価値」に基づき、 組織での動き方でデザイナーとして大事と考えられている点、そして B2B サービスのUIを作っていく上で大事と考えられている点を話していただきました。 司会者も話していましたが、新卒2年目とは思えない堂々としたお姿に尊敬のまなざしでした。 日々の思考と「マジ価値」への共感の積み重ねによる成果ではと感じていました。 初のLT挑戦の場として ラク スを選んでいただき、ありがとうございました。 t.co 6. TypeScriptで解説する催眠術のかけ方 / Ouji Miyaharaさん 事前に伺っていたタイトルとは一切関係ない 催眠術のかけ方 について、TypeScriptを交えながらご紹介いただきました! イベントの空気が一変したタメになるご発表、ありがとうございました! 催眠術にご興味をお持ちのデザイナーの方、ぜひこちらのスライドをご覧ください! t.co 7. Adobe XDでつくるVUIプロトタイピング / Makiko Odaniさん Makiko Odaniさんも初のLT挑戦として、 Google Home や Amazon Echo によって注目されているVUI(Voice User Interface 、音声を使って操作するインターフェース)をご紹介いただきました。 発表中には実際に作成されたプロトタイプでのデモも実施いただきました。 デザイナーの方には馴染みのある Adobe XDで手軽に作成できるそうですので、ご興味のある方はぜひお試しいただければと思います! 8. デザイナー採用のUXデザインに取り組み始めた話 / TomoyoHirokawaさん プロダクトデザイナー のTomoyoHirokawaさんには勢いでイベントにご参加いただき(直前の欠員を埋めていただき、ありがとうございました!)、初のデザイナー採用での体験設計に取り組まれた際のエピソードを語っていただきました。 初の取り組みとのことでしたが、仮説検証 → 修正 → 実行 → 振り返りのステップを着実に踏めていらっしゃる印象を受けました。 特に経営層や他職種を巻き込んでアクションが体現された点、素晴らしいです! 2周目以降の取り組みも応援しています!! 9. UIデザインの呪術性 - 覚書- / yuki _sasakiさん 呪術的思考 とUIデザインの関連について、以下の2つの補助線を用いてご説明いただきました! 一体どのようにUIデザインにつながるのか謎に感じておりましたが、最後は絶妙にUIデザインへと結び付けていただきました! 非常に深く、まるで催眠術にかかったような気分でした! クロード・ レヴィ・ストロース 『野生の思考』 ジャック・ラカン 『光点としてのまなざし』 speakerdeck.com 10. デザイナー 1 年目のわたしが考えるデザイン / uknmrさん エンジニアからデザイナーの道へと進まれたuknmrさんより、 プロダクトデザイナー 半年のご経験を踏まえてデザインとは何なのかを語っていただきました。 スライドに出てきます 『”デザイン”はデザイナーだけのものではない』 に込められた深い洞察はとても参考になりました。 あと催眠術にかかったのか、なぜか焼きそばが食べたくなりました! www.notion.so 11. 生産性が上がる文章の書き方と、デザインと文章の関係性 / ShinyaSatoさん ShinyaSatoさんからはあえてデザインをテーマとした発表ではなく、「文章の書き方」を中心にしたノウハウをご紹介いただきました。 「書く力」はデザイナーにとっても重要度が高く、とはいえ他職種よりも機会が少ないものということで、ご参加の方々からは大好評の内容でした。 在宅ワーク が本格化した今のタイミングでは、デザイナー以外のどの職種でも学ぶことばかりの貴重なお話だったと思います。 speakerdeck.com 最後にご紹介いただきましたShinyaSatoさんの個人ブログはこちらになります。 学びの宝庫です…!! https://shinya-it.com/work/sentence_of_import shinya-it.com 12. 技術とデザインの間 / takanoripさん デザイナーとエンジニアが分業体制である歴史を踏まえつつ、デザイナーが技術の仕組みを理解する重要性をご説明いただきました。 デザイナーにとって技術への理解が「なぜ必要なのか?」が明確となり、技術とデザインが切り離せないものであることを認識できた方も多いと思います。 エンジニア・デザイナー両方のご経験があるtakanoripさんの実感が強く感じられる内容でした。 speakerdeck.com 13. TypeScriptではじめるUIデザイン / kgsiさん UIの情報整理の難しさと理想を踏まえ、TypeScriptを使った方法を説明いただきました。 TypeScriptの言語仕様を踏まえ、実際にトライされたケースへの所感がとても参考になりました。 あと催眠術にかかったのか、なぜかカレーが食べたくなりました! speakerdeck.com 14. Web UIの実装で考えていることと気をつけたいこと / yamanokuさん 普段取り組まれている業務でのご経験を踏まえ、UI実装に対する深いお考えを発表いただきました。 ボタンUI1つをとっても思慮がとても深く、ぜひ全てのデザイナーの方にご覧いただきたい内容です。 LTへのご挑戦、ありがとうございました! scrapbox.io 15.3次元のカラーピッカー的なものを作ってみた / chooさん 「色は本質的に三次元(の要素で表現される)だから、二次元のUIはムリがあるのでは」という仮説に基づき、 三次元のColor Picker を紹介いただきました。 これは凄いです…私の説明よりも、ぜひこちらにアクセスいただいてお試しください!! t.co docs.google.com 16. BtoB SaaS のUIリニューアルの苦労 / 小林肇 最後は ラク スのUI開発チームの小林より、 ラク スでの17年間のサービスデザインでの歴史を語らせていただきました。 およそ半分が10年以上の歴史を持つ ラク スのサービスですが、現在に至るまで、実に多くのお客様からのお声をいただきながら成長させていただきました。 厳しいご意見からお褒めの言葉まで、お客様からの貴重なフィードバックが重要であることをあらためて考えるきっかけとなりました。 お客様にとって使いやすく、課題解決につながるサービスを目指していきたいという小林からの声で今回のLTを締めさせていただきました。 おわりに ラク ス初のUI/UXデザイナー向けのイベントでしたが、いかがでしたでしょうか? 個性的な16名の登壇者の方々、イベントを盛り上げていただいて誠にありがとうございました! また次回開催でのご登壇を楽しみにお待ちしています! さて、今月 ラク スでは フロントエンド技術への取り組み を発信させていただく予定です。 ご都合のよろしい方は是非、こちらのイベントに気軽にご参加いただけますと幸いです! rakus.connpass.com また プロジェクトマネジメント にも関わっている方には、こちらのイベントがお勧めです! アウトプットに飢えているPMの方、お待ちしています! rakus.connpass.com それではまた次回のブログで。 長文をご覧いただき、ありがとうございました! 技術広報のitoken1013でした! エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
こんにちは。技術推進課のt_okkanです。 最近業務でFlutterを使用することになり、少しずつですがFlutterを学習しています。 そこで今回はFlutterで、実機( iPhone )のカメラを利用してみました。カメラを使用するための プラグイン の追加から、カメラでの画像の撮影と保存、保存した画像の表示までを行います。 環境 Flutterについて アプリ作成〜プラグインのインストール 実装 使用できるカメラの取得 カメラ制御の初期化 カメラのプレビューの実装 画像の撮影と保存の実装 撮影した画像を表示する 全体のソースコード まとめ 参考 環境 使用した環境は以下になります。 Flutter 1.22.0 Visual Studio Code macOS Catalina 10.15.6 iOS 13.7 Flutterの環境構築は、公式HPに詳しく記載されています。 https://flutter.dev/docs/get-started/install 上記を参考に、 macOS + VSCode の環境を構築してください。 Flutterについて Flutterについて少しだけ紹介します。 Google が提供しているUIツールキットで、主に iOS ・ Android アプリの クロスプラットフォーム ツールとして利用されています。最近はWeb対応が進み、モバイル・ウェブ・デスクトップと真の クロスプラットフォーム を目指している注目のツールです。 Flutterは Dart という言語で実装されています。カメラなどのデ バイス 固有の機能にアクセスするには、各プラットフォームのネイティブの実装を必要とします。 Flutterではそのような各ネイティブの実装を必要とする プラグイン をPluginパッケージとして提供しています。 プラグイン は pub.dev で公開されています。 アプリ作成〜 プラグイン のインストール Flutterのプロジェクトを作成して、 camera の プラグイン と、カメラとマイクへのアクセス許可の確認までを設定します。また、画像を保存するために各プラットフォームのパスを取得する必要があるので、 path_provider と path プラグイン もインストールします。 まずはコマンドでFlutterのプロジェクトを作成します。 $ flutter create camera_app その後 プラグイン を追加します。Flutterでは pubspec.yaml ファイルに使用する プラグイン を記載します。今回は以下のようにします。 dependencies : camera : ^0.5.8+5 path_provider : ^1.6.14 path : ^1.7.0 flutter : sdk : flutter 次に、カメラを使用の許可を促すメッセージを表示するための設定を行います。 ios/Runner/Info.plist ファイルに以下を追加します。 <key> NSCameraUsageDescription </key> <string> Can I use the camera please? </string> <key> NSMicrophoneUsageDescription </key> <string> Can I use the mic please? </string> また Android で使用する場合は、 SDK の最低バージョンを 21 を指定する必要があります。 android/app/build.gradle に以下を追加します。 defaultConfig { // TODO : Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.camera_app" minSdkVersion 21 targetSdkVersion 29 versionCode flutterVersionCode. toInteger () versionName flutterVersionName } 準備は以上です。では実際にコードを書いていきます。 実装 まずは camera プラグイン で使用するクラスを紹介します。 CameraController 端末のカメラを制御するクラス。このクラスに制御したいカメラを渡すことで、プレビューの表示や、写真・動画の撮影を行うことができます。 CameraDescription カメラの情報(フロント・バック)を管理しているクラス。 CameraController クラスにこのクラスを渡すことで、カメラの制御を行うことができます。 CameraPreview カメラが取得している映像(静止画の連続)を画面に表示する ウィジェット 。 今回はカメラで画像を撮影・保存し表示するまでの手順を順番に説明します。最後に必要なコードを全て載せますので、先に見たい方はそちらからどうぞ。 では、以下の手順で実装していきます。 使用できるカメラの取得 カメラ制御の初期化 カメラのプレビューの実装 画像の撮影と保存の実装 撮影した画像を表示する 使用できるカメラの取得 まずは端末から使用できるカメラを取得します。 今回は取得したカメラから、背面のカメラを使用します。 // runAppが実行される前に、cameraプラグインを初期化 WidgetsFlutterBinding . ensureInitialized (); // デバイスで使用可能なカメラの一覧を取得する final cameras = await availableCameras (); // 利用可能なカメラの一覧から、指定のカメラを取得する final firstCamera = cameras.first; プラグイン の availableCameras メソッドで、端末で使用可能なカメラを配列で取得できます。 ここで取得したカメラを、表示する ウィジェット に渡すことで、カメラを使用できます。 では次に、取得したカメラを制御するための準備をします。 カメラ制御の初期化 取得したカメラの制御を行うために、 CameraController クラスを初期化する必要があります。 ここではカメラ用の画面 CameraHome の構築から、 CameraController クラスの初期化までを実装します。 // ① class CameraHome extends StatefulWidget { final CameraDescription camera; const CameraHome ({ Key key, @required this .camera}) : super (key : key); @override State < StatefulWidget > createState () => CameraHomeState (); } class CameraHomeState extends State < CameraHome > { // デバイスのカメラを制御するコントローラ CameraController _cameraController; // コントローラーに設定されたカメラを初期化する関数 Future < void > _initializeCameraController; @override void initState () { super . initState (); // ② // コントローラを初期化 _cameraController = CameraController ( // 使用するカメラをコントローラに設定 widget.camera, // 使用する解像度を設定 // low : 352x288 on iOS, 240p (320x240) on Android // medium : 480p (640x480 on iOS, 720x480 on Android) // high : 720p (1280x720) // veryHigh : 1080p (1920x1080) // ultraHigh : 2160p (3840x2160) // max : 利用可能な最大の解像度 ResolutionPreset .max); // ③ // コントローラーに設定されたカメラを初期化 _initializeCameraController = _cameraController. initialize (); } // ④ @override void dispose () { // ウィジェットが破棄されたタイミングで、カメラのコントローラを破棄する _cameraController. dispose (); super . dispose (); } @override Widget build ( BuildContext context) {} } カメラを起動する画面を構築する カメラを起動する画面として StatefulWidget を使用し、画面を構築します。 コンストラクター で CameraDescription クラスを受け取り、使用するカメラを設定します。 カメラコントローラーを初期化します CameraController の コンストラクター の第一引数に CameraDescription を指定し、制御対象のカメラを設定します。第二引数に、列挙型 ResolutionPreset からカメラの解像度を指定します。今回は使用できる最大の解像度を指定します。 カメラコントローラーに設定されたカメラを初期化します CameraController クラスに設定された端末のカメラを、 initialize メソッドを実行して初期化します。 initialize メソッドは非同期処理を行うメソッドのため、 Feature オブジェクトを返します。 ウィジェット 破棄のメソッドの追加 StatefulWidget の dispose メソッド内で、 CameraController クラスの dispose メソッドを呼び出します。 ウィジェット が破棄されたタイミングで、 CameraController クラスも破棄する用になります。 以上がカメラの初期設定になります。次は、カメラが取得した画像を画面に表示する プレビュー機能 を実装します。 カメラのプレビューの実装 camera プラグイン の CameraPreview クラスを利用して、カメラが取得した画像をプレビューとして画面に表示します。先ほどの CameraHomeState クラスの、 build メソッドに以下のコードを追加します。 @override Widget build ( BuildContext context) { return Scaffold ( appBar : AppBar ( title : const Text ( '' ), ), // FutureBuilderを実装 body : FutureBuilder < void > ( future : _initializeCameraController, builder : (context, snapshot) { if (snapshot.connectionState == ConnectionState .done) { // カメラの初期化が完了したら、プレビューを表示 return CameraPreview (_cameraController); } else { // カメラの初期化中はインジケーターを表示 return const Center (child : CircularProgressIndicator ()); } }, ), ); } FutureBuilder クラスは、非同期で画面を構築できます。引数の future で非同期処理を設定し、 builder で非同期処理が完了した場合と完了していない場合の処理を実装します。今回は、非同期処理としてカメラの初期化を行う initialize メソッドを実行し、カメラの初期化が完了するとプレビュー画面を、完了していない場合はインジケーターを表示するようにします。 以上がカメラのプレビューを表示するための実装です。 画像の撮影と保存の実装 次は、カメラのシャッターボタンを実装し、画像の撮影と保存を行います。カメラのシャッターボタンは FloatingActionButton で実装します。 FloatingActionButton の onPressed 引数でボタンが押下された場合の実装をします。 @override Widget build ( BuildContext context) { return Scaffold ( appBar : AppBar ( title : const Text ( '' ), ), body : FutureBuilder < void > ( // 省略 ), floatingActionButton : FloatingActionButton ( child : const Icon ( Icons .camera_alt), // ボタンが押下された際の処理 onPressed : () async { try { // ①画像を保存するパスを作成する final path = join ( ( await getApplicationDocumentsDirectory ()).path, ' ${DateTime.now()} .png' , ); // ②カメラで画像を撮影する await _cameraController. takePicture (path); // ③画像を表示する画面に遷移 Navigator . push ( context, MaterialPageRoute ( builder : (context) => CameraDisplay (imgPath : path), ), ); } catch (e) { print (e); } }, ), } 画像を保存するパスを作成 path プラグイン の join メソッドを使用して、画像を保存するパスを作成します。 path_provider プラグイン の getApplicationDocumentsDirectory メソッドを使用することで、アプリ専用の ディレクト リを取得できます。 写真を撮影し、作成したパスに保存 CameraController クラスの takePicture メソッドで画像の撮影を行うことができます。引数に指定したパスに画像を保存できます。 撮影した画像を表示する画面に遷移 画像を表示する画面は次で実装します。ここでは、画面の コンストラクター に先ほど画像を保存したパスを渡します。 以上が画像の撮影から保存までの実装です。 ここまでの実装で、以下のようなカメラから取得した画像を表示し、撮影用のボタンを表示する画面が出来上がります。 カメラ撮影画面 最後に撮影ボタンを押下後、保存した画像を表示する画面を作成します。 撮影した画像を表示する 最後に、撮影し保存した画像を表示する画面を作成します。 画像を表示するためには、 Image ウィジェット を使用します。 コンストラクター に表示したい画像のパスを指定することで画像を表示できます。 class CameraDisplay extends StatelessWidget { // 表示する画像のパス final String imgPath; // 画面のコンストラクタ const CameraDisplay ({ Key key, this .imgPath}) : super (key : key); @override Widget build ( BuildContext context) { return Scaffold ( appBar : AppBar ( title : const Text ( 'Picture' ), ), body : Column ( // Imageウィジェットで画像を表示する children : [ Expanded (child : Image . file ( File (imgPath)))], ) ); } } これで以下のような画像を表示する画面を作成できます。 画像表示 実装は以上になります。全体の ソースコード は以下になります。 全体の ソースコード 全体のソースコード import 'dart:async' ; import 'dart:io' ; import 'package:camera/camera.dart' ; import 'package:flutter/material.dart' ; import 'package:path/path.dart' show join; import 'package:path_provider/path_provider.dart' ; Future < void > main () async { // runAppが実行される前に、cameraプラグインを初期化 WidgetsFlutterBinding . ensureInitialized (); // デバイスで使用可能なカメラの一覧を取得する final cameras = await availableCameras (); // 利用可能なカメラの一覧から、指定のカメラを取得する final firstCamera = cameras.first; runApp ( MyApp (camera : firstCamera)); } class MyApp extends StatelessWidget { final CameraDescription camera; const MyApp ({ Key key, @required this .camera}) : super (key : key); // This widget is the root of your application. @override Widget build ( BuildContext context) { return MaterialApp ( title : 'Flutter Demo' , theme : ThemeData ( primarySwatch : Colors .blue, visualDensity : VisualDensity .adaptivePlatformDensity, ), home : MyHomePage ( camera : camera, ), ); } } class MyHomePage extends StatelessWidget { final CameraDescription camera; const MyHomePage ({ Key key, @required this .camera}) : super (key : key); @override Widget build ( BuildContext context) { return Scaffold ( appBar : AppBar ( title : const Text ( 'Camera Example' ), ), body : Wrap ( children : [ RaisedButton ( child : const Text ( 'Camera' ), onPressed : () { Navigator . push (context, MaterialPageRoute (builder : (context) { return CameraHome (camera : camera,); })); }), ], ), ); } } class CameraHome extends StatefulWidget { final CameraDescription camera; const CameraHome ({ Key key, @required this .camera}) : super (key : key); @override State < StatefulWidget > createState () => CameraHomeState (); } class CameraHomeState extends State < CameraHome > { // デバイスのカメラを制御するコントローラ CameraController _cameraController; // コントローラーに設定されたカメラを初期化する関数 Future < void > _initializeCameraController; @override void initState () { super . initState (); // コントローラを初期化 _cameraController = CameraController ( // 使用するカメラをコントローラに設定 widget.camera, // 使用する解像度を設定 // low : 352x288 on iOS, 240p (320x240) on Android // medium : 480p (640x480 on iOS, 720x480 on Android) // high : 720p (1280x720) // veryHigh : 1080p (1920x1080) // ultraHigh : 2160p (3840x2160) // max : 利用可能な最大の解像度 ResolutionPreset .max); // コントローラーに設定されたカメラを初期化 _initializeCameraController = _cameraController. initialize (); } @override void dispose () { // ウィジェットが破棄されたタイミングで、カメラのコントローラを破棄する _cameraController. dispose (); super . dispose (); } @override Widget build ( BuildContext context) { return Scaffold ( appBar : AppBar ( title : const Text ( '' ), ), // FutureBuilderを実装 body : FutureBuilder < void > ( future : _initializeCameraController, builder : (context, snapshot) { if (snapshot.connectionState == ConnectionState .done) { // カメラの初期化が完了したら、プレビューを表示 return CameraPreview (_cameraController); } else { // カメラの初期化中はインジケーターを表示 return const Center (child : CircularProgressIndicator ()); } }, ), floatingActionButton : FloatingActionButton ( child : const Icon ( Icons .camera_alt), // ボタンが押下された際の処理 onPressed : () async { try { // 画像を保存するパスを作成する final path = join ( ( await getApplicationDocumentsDirectory ()).path, ' ${DateTime.now()} .png' , ); // カメラで画像を撮影する await _cameraController. takePicture (path); // 画像を表示する画面に遷移 Navigator . push ( context, MaterialPageRoute ( builder : (context) => CameraDisplay (imgPath : path), ), ); } catch (e) { print (e); } }, ), ); } } class CameraDisplay extends StatelessWidget { // 表示する画像のパス final String imgPath; // 画面のコンストラクタ const CameraDisplay ({ Key key, this .imgPath}) : super (key : key); @override Widget build ( BuildContext context) { return Scaffold ( appBar : AppBar ( title : const Text ( 'Picture' ), ), body : Column ( // Imageウィジェットで画像を表示する children : [ Expanded (child : Image . file ( File (imgPath)))], ) ); } } まとめ Flutterでカメラ機能を実装してみました。以前、 Swiftでカメラ機能を実装したこと があるのですが、その時と比べ必要なクラスが プラグイン ですでに実装されているので、シンプルに実装することができました。 またFlutterの特徴として宣言的にUIを構築できるので、楽に開発できます。 今回はシンプルなカメラ機能だけの紹介でしたが、 GitHub にインカメの切り替えのできるコードを置いています。興味があれば確認してみてください。 参考 Take a picture using the camera | Flutter エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
こんにちは、takaramです。 私が担当しているサービスでは、 RDBMS に PostgreSQL を利用しています。今回は業務で行った デッドロック の調査で知った、 PostgreSQL の仕様に関して書いていきます。 ここでは デッドロック や パーティショニング といった用語が登場しますが、今回これらの説明は割愛します。 パーティショニングについてご存じでない方は、まずはこちらの記事をお読みください。 tech-blog.rakus.co.jp qiita.com なお、この記事の内容は PostgreSQL 12.3で確認したものです。 テーブルのロック 子テーブルの作成 パーティションの追加 デッドロックが起こりそうな例 前提 デッドロックの発生 対策 まとめ テーブルのロック PostgreSQL のロックについては、以下のドキュメントに詳しく書かれています。 www.postgresql.jp これによると、テーブルレベルのロックだけで8種類が存在します。 LOCK TABLE 文でロックが獲得されるのは言うまでもありませんが、INSERT文やUPDATE文、SELECT文ですら対象のテーブルのロックを獲得します。 さらに、実は以下のような操作でもテーブルのロックが獲得されます。 子テーブルの作成 PostgreSQL の継承機能を利用し子テーブルを作成すると、親テーブルのロックが獲得されます。例として、 psql コマンドで以下のような SQL を実行してみます。 partition_test=# CREATE TABLE parent (); partition_test=# BEGIN; BEGIN partition_test=# CREATE TABLE child () INHERITS (parent); CREATE TABLE ここで別のコンソールからロックの状態を確認してみましょう。 PostgreSQL の場合、 pg_locks を参照することでロック状態が確認できます。結果を見てみると、 parent テーブルのSHARE UPDATE EXCLUSIVEロックが獲得されているのがわかります。 partition_test=# SELECT d.datname, l.locktype, l.relation::regclass, l.mode FROM pg_locks l LEFT JOIN pg_database d ON l.database = d.oid WHERE l.pid != pg_backend_pid(); datname | locktype | relation | mode ----------------+---------------+----------+-------------------------- | virtualxid | | ExclusiveLock partition_test | object | | AccessShareLock partition_test | relation | 16428 | AccessExclusiveLock | transactionid | | ExclusiveLock partition_test | relation | parent | ShareUpdateExclusiveLock (5 行) パーティション の追加 PostgreSQL 10以降では宣言的パーティショニングがサポートされていますが、 パーティション テーブルに パーティション を追加する際に、 パーティション テーブルのロックが獲得されます。これも psql コマンドで確認してみます。 partition_test=# CREATE TABLE partition (id integer) PARTITION BY LIST (id); CREATE TABLE partition_test=# BEGIN; BEGIN partition_test=# CREATE TABLE partition_1 PARTITION OF partition FOR VALUES IN (1); CREATE TABLE 別コンソールの psql で確認すると、 パーティション テーブルの ACCESS EXCLUSIVEロックが獲得されているのが確認できます。 partition_test=# SELECT d.datname, l.locktype, l.relation::regclass, l.mode FROM pg_locks l LEFT JOIN pg_database d ON l.database = d.oid WHERE l.pid != pg_backend_pid(); datname | locktype | relation | mode ----------------+---------------+-----------+--------------------- | virtualxid | | ExclusiveLock partition_test | object | | AccessShareLock partition_test | relation | 16434 | AccessExclusiveLock partition_test | relation | partition | AccessExclusiveLock | transactionid | | ExclusiveLock (5 行) デッドロック が起こりそうな例 上記のように PostgreSQL では パーティション の追加などの操作でもロックが発生します。こうした挙動を把握、意識していないと、うっかり デッドロック を引き起こしてしまう場合があります。 前提 あるアプリケーションにユーザとグループが存在し、一人のユーザは複数のグループに所属することができるとします。 これをデータベース上で表現しようとすると、ユーザとグループは多対多の関係なので、ユーザテーブル、グループテーブルと、この2つを結ぶ中間テーブルを作成することになると思います。 ユーザとグループのER図 この中間テーブルはレコード数がとても多くなりそうなので、グループごとにパーティショニングすることにしました。グループテーブルにレコードを挿入するたびに、トリガーで新しい パーティション を追加します。 以上を SQL で表現すると、以下のようになります。 CREATE TABLE users ( id serial PRIMARY KEY, name text ); CREATE TABLE groups ( id serial PRIMARY KEY, name text ); CREATE TABLE user_group ( user_id integer , group_id integer ) PARTITION BY LIST ( group_id ); CREATE FUNCTION groups_insert_trigger_func() RETURNS trigger AS $$ BEGIN EXECUTE ' CREATE TABLE user_group_g ' || NEW.id || ' PARTITION OF user_group FOR VALUES IN ( ' || NEW.id || ' ) ' ; RETURN NEW; END ; $$ LANGUAGE plpgsql; CREATE TRIGGER groups_insert_trigger AFTER INSERT ON groups FOR EACH ROW EXECUTE FUNCTION groups_insert_trigger_func(); デッドロック の発生 上記のようなテーブル、トリガーを作成した状態で、2つの トランザクション A, Bで以下のような順序で操作を行うと デッドロック が発生します。 トランザクション SQL A LOCK TABLE user_group; B INSERT INTO groups (name) VALUES ('group 1'); A LOCK TABLE groups; トランザクション BでINSERT文を実行すると、 groupsテーブルをロックし行挿入 トリガーでuser_groupの パーティション を作成 user_groupのロック待ち となり、その後で トランザクション Aがgroupsのロックを獲得しようとすると デッドロック 状態になってしまいます。 トランザクション Bでは見た目上はgroupsテーブルに挿入しているだけなので、これで デッドロック が発生するとは気づきにくそうです。 ここでは例として宣言的パーティショニングを使ったケースを挙げていますが、子テーブルの作成でもロックが発生するため、継承によるパーティショニングでも同様に デッドロック が起こり得ます。ただし宣言的パーティショニングの場合、 トランザクション Bが獲得しようとするuser_groupのロックはもっとも厳しい ACCESS EXCLUSIVEロックなので、 LOCK TABLE user_group; を SELECT * FROM user_group; などに置き換えても同じく デッドロック してしまいます。 対策 このような デッドロック を回避する方法の一つは、テーブルのロック順序に気をつけることです。 上の例でいうと、 トランザクション Aでuser_groupよりも先にgroupsをロックすると、 デッドロック が発生しなくなります。 まとめ 子テーブルの作成( CREATE TABLE ... INHERITS ... )の際、親テーブルがSHARE UPDATE EXCLUSIVEロックされる パーティション の作成( CREATE TABLE ... PARTITION OF ... )の際、大元の パーティション テーブルが ACCESS EXCLUSIVEロックされる エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 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
アバター
こんにちは!akiponxといいます。 さて、今回のブログはメールのあれこれについて書きます。 メールというと、いつでも送信できて、いつでも受信できる。 これが当たり前ですよね。 まれにメールが届かない。という声を聴くことがあります。 今回はメールが届かない原因について触れてみたいと思います。 まずはRakusのブログではメール関連の記事があまりないので今回は仕組みの部分。イメージを付けていただければと思います。 当たり前にメールの送受信ができる裏側で何が起きているのか見ていきましょう! 1. メールとは ①手紙を作る ②郵便配達の人が頑張って宛先の住所に手紙を届けます。 ③家のポストを確認して手紙を受け取る 2. メールの送信・受信 ①手紙を作る部分:メールを作成して送信ボタンをクリック ②郵便配達の人が頑張る部分:メール送信サーバが受信サーバへメール送信 ③郵便ポストにメールを取りに行く部分:受信者がメーラで受信メールサーバに届いているか確認しに行く メール送信 メール受信 全部をマージするとこんな感じ 3. メールが届かない原因 スパムメールとは スパムメール対策 4. SPF 5. DKIM 6. DMARC 7. まとめ 1. メールとは メールとは手紙のやり取りと似たようなものです。 画像①を使って説明します。 ①手紙を作る 封筒に下記を書く 宛先の住所 差出人の名前 手紙の本文を書く ポストへ投函 ②郵便配達の人が頑張って宛先の住所に手紙を届けます。 ③家のポストを確認して手紙を受け取る メールの送信・受信もイメージは同じです。 2. メールの送信・受信 こちらについてもメールの仕組みで使った図と見比べて説明していこうと思います。 ①手紙を作る部分:メールを作成して送信ボタンをクリック メーラ( gmail など)でメールを作成 (図1の封筒にあたる部分) 宛先メールアドレスを記載 (例: hoge @ example.com ) 自動で入力されていることが多いですが、差出人アドレスを記載 (例:akiponx@rakus.co.jp) 本文を入力 (図1の本文にあたる部分) 送信ボタンを押す (図1のポストに投函にあたる部分) ②郵便配達の人が頑張る部分:メール送信サーバが受信サーバへメール送信 この時にメール送信サーバが行っている処理をざっくり説明。 宛先メールアドレスの ドメイン ( example.com )を名前解決してメール受信サーバのインターネット上の住所である IPアドレス を取得。 メール受信サーバへメールを送信 ③郵便ポストにメールを取りに行く部分:受信者がメーラで受信メールサーバに届いているか確認しに行く メール受信はメーラによってメール受信サーバにメールが届いているか確認しに行く作業。 さて。ざっくりとした流れは説明した通りですが、送信・受信についてもう少し細かく見ていきます。 メール送信 ①の部分を切り取った画像がこちら。さらに処理の内容を記載しています。後で全部マージします。 1-1. 差出人アドレスがメールを送信していいかどうか認証する( SMTP 認証と呼ばれているもの。) 1-2. 認証が通れば送信する準備に入る 続いて②を切り取った画像。 ②の中身を細かく分割するとこんな感じです。では説明していきましょう。 2-1. どこに送ればいいのか確認するため、 送信先 メールアドレスの ドメイン 部分を確認。 2-2. 確認した ドメイン の住所がどこなのか DNS レコードにMXレコードを問合せ 2-3. DNS から 送信先 アドレスの住所をもらう。 2-4. DNS からもらった住所宛にメールを送信する。 ※MXレコードとはメールをどこに送ればいいのかを教えるための、 DNS レコードの一種です。 メール受信 さて、続いてメール受信ですが、メールが受信できるようになるまでもいくつか過程があります。 メール送信の段階で②の処理が全て終わっているように思われますが、実はまだ終わっていません。 続きはメール受信サーバ側で処理がされているためこちらに続きを記載します。 2-5. 届いたメールの差出人アドレスの ドメイン を確認 2-6. DNS に SPF (または DKIM の公開鍵)を問合せ 2-7. SPF (または DKIM の公開鍵)の評価を実施 ※1 2-8. 問題なければメールを受け入れる処理を実施 2-9. メー ルボックス (イメージ的にはポスト)にメールを置く。 3-1. メーラが POP3 or IMAP でメールがあるかどうか確認しに行く ※2 3-2. 新着メールが存在していればダウンロードして表示する。 ※1  SPF (または DKIM )の評価によってはメールが拒否されることがある。 ※2  POP3 や IMAP はメールを受信する用の 通信プロトコル 。    また、POP3SやIMAPSといった SSL証明書 を利用した プロトコル もある。 SPF や DKIM については後程説明します。 全部をマージするとこんな感じ 3. メールが届かない原因 さて、メールの送信・受信についてはある程度説明できたかと思います。 続いては当たり前に届くはずのメールが届かないことがある原因ついて、考えられることを書いていきます。 スパムメール 判定がされている メールアドレスが間違っている etc... メールが届かない原因として スパムメール と評価されてしまい、拒否されているケースが多いです。 スパムメール とは スパムメール とは迷惑メールの一つで、主に広告や宣伝、ウィルス付きメールなどに使われることが多いです。 広告や宣伝に使われるならいいんじゃない?と思う方もいるかと思いますが、そうではありません。 主に詐欺やデータを取る目的で送られていることが多いです。 そもそもメール配信などはオプトイン(メルマガ送ってもいいですよ。という意志表明)が無いと送ってはいけないのがルール。 そのオプトインがない人にメールを大量に送る。迷惑ですよね。 スパムメール 対策 スパムメール を受信しないようにする対策として、 スパムフィルター を実装する 逆引きが設定されていない IPアドレス からは受信しない SPF チェックが通らないものを受信しない DKIM 署名がないものを受信しない ブラックリスト に登録されている ドメイン ( IPアドレス )からのメールは拒否する などがありますが、「メールが届かない!」ということは大きなクレームにもつながるため、 なかなか SPF や DKIM を設定していないメールは受信しない。という強気な対応に踏み切れないところがあります。 そんなこんなで続いては SPF とか何か、 DKIM とは何か。について書いていきます。 4. SPF SPF とは、 DNS のTXTレコードにあたります。 送信元 ドメイン の名前解決を実施しTXTレコードに記載がある SPF の値を確認します。 例を出すと基本的にこんな感じの SPF が設定されています。 # SPFの例 rakus.co.jp descriptive text "v=spf1 include:spf.rakus.co.jp ip4:xxx.xxx.xxx.xxx ~all" SPF の値には IPアドレス などが記載されており、送信サーバの IPアドレス が SPF に記されていればOK、記載されていなければ基本的にNGとなります。 受信メールサーバ側の設定によりますが、この SPF のチェックを通らないとメールを受信しない。という設定もできます。 もし「メールが届かない…orz」となった方は SPF をチェックしてみるのもいいかもしれないですね。 5. DKIM DKIM とは、これも DNS のTXTレコードを利用した技術です。 SPF より少し複雑。 ざっくりとした流れとしては メール送信サーバがメールヘッダーに 電子署名 を実施 メール受信サーバが DNS サーバに問い合わせを実施し、公開鍵を入手 入手した公開鍵で 電子署名 が複合化し、認証を実施。 こんな感じで DKIM は評価されます。 DKIM 署名を実装する方法などなどは今回は書きません。 6. DMARC DMARCとは SPF と DKIM の合わせ技です。 基本的にメール受信については SPF が設定されていなくても、 DKIM が設定されていなくても、 そのメールを受信するかどうかは受信メールサーバ側が決めています。 DMARCを設定することによって、メール送信者側が挙動を指定できます。 例えば、 SPF が通らなければメールを拒否(迷惑メールに振り分け)する DKIM の署名がなければメールを拒否(迷惑メールに振り分け)する 上記の設定をすることによって、自分の ドメイン を語ったメールを受信させないようにできます。 また、DMARCを設定することによって、自分の ドメイン を語ったメール( SPF や DKIM の評価が通らなかったもの)が何通送られているのか というレポートメールを受け取ることができます。 これを受け取ったから何ができるのかといわれると難しいですが、DMARCの運用を考えていかないといけないですね。 7. まとめ メールが届かない原因は今回記載した以外にもありますが、 本記事に記載されている内容を踏まえてメールが届かなった原因の調査や対策をしてみていただければと思います。 大手フリーメールの会社ではセキュリティが厳しくなってきており、迷惑メールフォルダに振り分けられてしまうこともしばしばあります。 迷惑メールフォルダに振り分けられないように、 SPF ・ DKIM の対策をしっかりしていきましょう! そのうち別のメール関連の記事も書きます。 参考にさせていただいたページ DMARK エンジニア 中途採用 サイト ラク スでは、エンジニア・デザイナーの 中途採用 を積極的に行っております! ご興味ありましたら是非ご確認をお願いします。 https://career-recruit.rakus.co.jp/career_engineer/ カジュアル面談お申込みフォーム どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。 以下フォームよりお申込みください。 forms.gle イベント情報 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com
アバター
はじめに 技術広報のitoken1013です。 いつも ラク スのエンジニアブログのご購読、そしてエンジニアイベントへのご参加、ありがとうございます! 今回は9/16(水)に行われた ラク スMeetup『持続可能な大規模 SaaS 企業の開発戦略』を紹介させていただきます。 イベントにご参加いただきました方も初めてご覧になる方も、4名のエンジニアの発表内容をご覧いただけますと幸いです! rakus.connpass.com イベントテーマ概要 本日は以下の計5つの「中小企業を強くする」ための大規模 クラウド サービスに関わるアプリケーションエンジニア、インフラエンジニアから発表をさせていただきました。 メールディーラー 楽楽販売 配配メール Curumeru チャットディーラー 上記どのプロダクトもおかげさまで拡大を続けていますが、裏側ではエンジニアがプロダクトを持続的に開発・運用するために日々工夫を重ねています。 今回は ラク スの開発組織に根付く 費用対効果を考え、やるべき最適な対策をとる文化 をアウトプットすべく、各プロダクトでの取り組みを発信させていただきました。 発表の紹介 長期的に考える技術的負債マネジメント戦略 「負債を返すチャンスは来るので、そのチャンスを逃さないために 諦めずに負債の局所化や新しく作り込まないなど準備をしておくのが大事 」 今回のMeetupのコンセプトを象徴するようなコメントですが、トップバッターであるやなせ(メールディーラー担当)から出てきた言葉でした。 これまでのMeetupでも度々登場してきたメールディーラーは歴史が深く、いわゆる「技術的負債」と向き合う機会も度々あります。 今回はあらためて技術的負債とは何なのか、そしてどのように立ち向うべきかを、やなせの経験と理論を踏まえて語らせていただきました。 会計的な負債と比較した場合の見えにくさ、またビジネスの側面も踏まえての方法論は多くのエンジニアに参考にしていただけると思います。 speakerdeck.com DB容量肥大化への取り組み 次の発表は 「データの肥大化問題」 がテーマです。 Webデータベースである楽楽販売を担当する山内より、その製品の特長上、深刻となったデータ量の問題に 「Cloudian HyperStore」 というオブジェクトストレージを導入して対処したエピソードを発表させていただきました。 アプリ・インフラどちらにも多大な影響を与える一大プロジェクトでしたが、今後も持続的に楽楽販売を利用いただける環境を作り上げるため、山内をはじめとするチームは主に3つの課題と対峙しました。 データ量に関する問題は長くプロダクトを運用していく上で避けられない問題です。 現在同じ問題を抱える方には、今回の発表からヒントを得ていただけると幸いです。 speakerdeck.com 4年間の レガシーシステム 運用から学んだトラブル対策の取り組み方 運用の スペシャ リストとして配配メールとCurumeruの2プロダクトに関わる西尾より、運用面からプロダクトを支えるためのプ ラク ティスを発表させていただきました。 どんなに緻密に作ったプロダクトでもトラブルを全て未然に防ぐことは難しいものです。 特に西尾が関わるプロダクトはメール配信サービスであるが故、以下の3フェーズそれぞれでプロダクト固有の問題、またメール プロトコル や業界固有の問題を抱えています。 メールを「作る」 メールを「送る」 メールを「届く」 今回の発表では未然にトラブルを防ぐことに全力を注ぐのではなく、起こってしまったトラブルに如何に迅速に対応するかを語っています。 サービスの外側・内側それぞれで学びとなるプ ラク ティスが提供できる内容です。 speakerdeck.com Infrastructure as Codeによるインフラ構築の自動化により、オペレーションミスを防ぐ仕組みづくり 最後にインフラエンジニアである山村よりインフラエンジニア目線での技術的負債とは何か、そしてInfrastructure as Codeを中心とした技術的負債への対処方法を発表させていただきました。 チャットディーラーの運用・保守をメインに担当する山村ですが、着任より現在に至るまで様々な技術的負債に着目する中、特に「共有不足で実装内容の ブラックボックス 化による負債」には強い問題意識を持っていました。 解決策として編み出したプ ラク ティスは属人性の解消のみならず、いまや作業 工数 としても大きく寄与するソリューションとなっています。 インフラ・アプリに関わらず、どのエンジニアにも是非ご参考にしていただきたいプ ラク ティスばかりです。 speakerdeck.com おわりに 持続可能な大規模 SaaS 企業の開発戦略、いかがでしたでしょうか? ラク スは多様な SaaS を長く開発し続けることで、 費用対効果を考え、やるべき最適な対策をとるための戦略と思考 が根付いています。 今回の4名のエンジニアの発表より、その一端を感じ取っていただければ幸いです。 次回はそんな多様な SaaS から フロントエンド に特化したテーマで、10月にMeetupを開催予定です! Vue.js、Typescriptなどのモダンなフロントエンドにご興味のある方は、ぜひconnpassをウォッチいただければと思います! rakus.connpass.com rakus.connpass.com
アバター
こんにちは。 やなせたかし です。 今回は「繰り返し」について掘り下げてみようと思います。 PHP に限ったことではないですが、繰り返しはプログラミングでは基本的な操作です。たとえば、 while for など、処理を繰り返す構文です。その中でも利用頻度が高いのは for でしょうか?サンプルコードでも配列を繰り返す時に使われたりと目にすることが多いと思います。 PHP であれば、 foreach という構文もあります。これも繰り返しのようです。 この中でも、 for と foreach どちらを使うのか?が議論されたり、どちらのほうが性能がいいだの悪いだの、過去にも比較されてきました。2020年の現在、(あくまで PHP 上での)両者にどんな差があるのでしょうか。 forを眺める 以下のコードを例に考えてみます。何の変哲もない PHP コードです。 <?php $ a = [ 1 , 2 , 3 ] ; $ b = 0 ; for ( $ i = 0 ; $ i < count ( $ a ) ; $ i ++ ){ $ b += $ a [ $ i ] ; } 配列の和を計算しています。この for の終了条件は $i < count($a) です。配列の大きさまで $i が増加すると終了します。 とくに何かあるわけではないコードのようにも見えますが、よく見るとコードの関心ごとがバラバラなことに気づきます。 たとえば、 $i はただの変数で、配列そのものとの関係はない ループ内でアクセスしている配列が $a であるかはループの条件に絡まない 和をとる配列は $a でなくても $aa にしても構わない そう、 for はただのループで、「配列の操作」とは関係がないのです。 この「関係がない」というのは、コードを見てもわかることですが、どこまで関係がないのか? 改めて for を振り返ってみましょう。 まず、 for という構文について。 さきほども書いた通り、ループを表現する構文です。では構文としてはどのようなルールになっているでしょうか? ルールを正確に知るため、 PHP のパーザーを呼んで文法そのものを見てみましょう。 PHP のコードを理解している部分ですから、正確な文法がわかるはずです。 PHP そのもののソースは、以下から手に入ります。 https://github.com/php/php-src ということで PHP のパーザーでは、 for の構文は以下のように定義されています。 %token T_FOR "for (T_FOR)" statement: | T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement { $$ = zend_ast_create(ZEND_AST_FOR, $3 , $5 , $7 , $9 ); }; for() の中に for_exprs というのが並んでいるのがわかります。そして、最後に for_statement というものがあります。 この for_exprs というものは何を表しているでしょうか。これは何もない(NULLと表します)か、カンマ区切りの expr のリストのようです。 ちなみに、 expr は式を表します。メソッド呼び出しのほか、 $a だけでも式ですし、 $i = 0 なども式にあたります。 そして zend_ast_create というものを呼び出しています。ここで ZEND_AST_FOR というものを渡しているので、ここで for文 を作っているようです。 $3,$5... はこのパーザーにマッチした要素の位置っぽいですね。 正規表現 のマッチっぽくも見えます。 さらに追っていくと、 PHP の for の定義が見えてきます。 void zend_compile_for(zend_ast *ast) { zend_ast *init_ast = ast->child[ 0 ]; // ← 1つ目のfor_exprs zend_ast *cond_ast = ast->child[ 1 ]; // ← 2つ目のfor_exprs zend_ast *loop_ast = ast->child[ 2 ]; // ← 3つ目のfor_exprs zend_ast *stmt_ast = ast->child[ 3 ]; // ← for_statement //.... } ということで、パーザーは for をこんな風に理解しています。 <?php for ( 開始状態の式; 終了条件の式; ループ式 ) for内部の文 となります。当たり前のことですが、調べてみるとしっかり書かれているものです。では、 for の命令を確認してみましょう。 以下のソースのopcodeをダンプします。 opcodeとは、 PHP で書かれたコードを コンパイル して得られるもので、Zendエンジンで直接実行されます。 <?php $ a = [ 1 , 2 , 3 ] ; $ b = 0 ; for ( $ i = 0 ; $ v = count ( $ a ) ; $ i ++ ) { $ b += $ a [ $ i ] ; } すると、以下のようなダンプが出力されます。 L0 (3): EXT_STMT L1 (3): ASSIGN CV0($a) array(...) L2 (4): EXT_STMT L3 (4): ASSIGN CV1($b) int(0) L4 (6): EXT_STMT L5 (6): ASSIGN CV2($i) int(0) L6 (6): JMP L12 L7 (7): EXT_STMT L8 (7): T6 = FETCH_DIM_R CV0($a) CV2($i) L9 (7): ASSIGN_ADD CV1($b) T6 L10 (6): T8 = POST_INC CV2($i) L11 (6): FREE T8 L12 (6): T9 = COUNT CV0($a) L13 (6): T10 = IS_SMALLER CV2($i) T9 L14 (6): EXT_STMT L15 (6): JMPNZ T10 L7 L16 (10): RETURN int(1) なんだか アセンブリ っぽいですね。 処理を見ていきましょう。L3までは for と関係ない処理です。ということで、それ以降を確認していきましょう。ループに関する個所は以下のような感じです。わりとイメージ通りの命令になっているのではないでしょうか。 行 処理 L5 $i に 0 を アサイ ン L6 L12 に飛ぶ L7 - L9 $b += $a[$i] の処理 L10 - L11 $i++ L12 T9 に count($a) の結果を保存 L13 T10 に $i < T9 の結果を保存 L15 T10 が 0 でなければ L7に飛ぶ さきほどまとめた文法と照らし合わせると、それぞれの式・文が評価されている命令の並びがわかります。初めに終了条件の式に飛ぶ以外は、普通にループしているだけですね。 要素 行 開始状態の式 L5 for内部の文 L7 - L9 ループ式 L10 - L11 終了条件の式 L12 - L15 ここで注目したいのが、 for内部の文 です。命令の L8 を見てみましょう。配列から値を取り出す処理です。 L8 (7): T6 = FETCH_DIM_R CV0($a) CV2($i) ここで使われている命令は、 FETCH_DIM_R となっています。これは配列にインデックスアクセスするときの命令です。当たり前のことを確認しているようですが、結構大事なところです。 このように実際の命令まで追っていくと、やはり for というのは「配列の操作」とは直接関係のない構文である、と言えるでしょう。 foreachを眺める 続いて、 foreach を見てみましょう。ソースは以下の通りです。やりたいことは変わりません。 <?php $ a = [ 1 , 2 , 3 ] ; $ b = 0 ; foreach ( $ a as $ v ) { $ b += $ v ; } では、まずは foreach の文法を確認しましょう。さきほどと同じように、 PHP のパーザーにある定義を確認します。 %token T_FOREACH "foreach (T_FOREACH)" statement: | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement { $$ = zend_ast_create(ZEND_AST_FOREACH, $3 , $5 , NULL, $7 ); } | T_FOREACH '(' expr T_AS foreach_variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement { $$ = zend_ast_create(ZEND_AST_FOREACH, $3 , $7 , $5 , $9 ); } どうやら foreach は2つの文法が定義されているようです。 上側は配列の value だけを、下側は T_DOUBLE_ARROW とあるように配列の key, value 両方使用するタイプですね。 ここで出てくるそれぞれの要素も、なんとなくイメージできそうです。 そして、さらに追いかけると、 foreach の定義にたどり着きます。 void zend_compile_foreach(zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[ 0 ]; // foreachで回すもの zend_ast *value_ast = ast->child[ 1 ]; // foreachで回される「値」 zend_ast *key_ast = ast->child[ 2 ]; // foreachで回される「キー」 zend_ast *stmt_ast = ast->child[ 3 ]; // 逐次処理される文 //・・・ } PHP パーザーはこのように理解しています。余談ですが、読み進めていくと foreach は「値」が参照かどうかで処理を切り替えている、ということもここから読み取れます。 今回は値を渡した時の挙動に絞って見ていきましょう。 ということで、実行されている様子を調べます。 調べるのは以下のコードです。 <?php $ a = [ 1 , 2 , 3 ] ; $ b = 0 ; foreach ( $ a as $ v ) { $ b += $ v ; } このopcodeのダンプは以下の通りです。 L0 (3): EXT_STMT L1 (3): ASSIGN CV0($a) array(...) L2 (4): EXT_STMT L3 (4): ASSIGN CV1($b) int(0) L4 (6): EXT_STMT L5 (6): V5 = FE_RESET_R CV0($a) L10 L6 (6): FE_FETCH_R V5 CV2($v) L10 L7 (7): EXT_STMT L8 (7): ASSIGN_ADD CV1($b) CV2($v) L9 (6): JMP L6 L10 (6): FE_FREE V5 L11 (10): RETURN int(1) LIVE RANGES: 5: L6 - L10 (loop) 見ての通り、 for と比べてかなり異なります。 L3までは飛ばして、 foreach 内部を見ていきましょう。 行 処理 L5 V5 に $a の イテレータ ーを保存 無ければL10へ L6 $v に V5 から値を取得し アサイ ン 終端ならL10へ L8 $b += $v L9 L6に飛ぶ L10 V5 を解放 opcodeレベルではとてもシンプルになっています。ここで注目したいのは、 L5 - L6 の部分です。 FE_RESET_R , FE_FETCH_R は、 foreach で使用する命令です。配列 $a からの値の取得自体が foreach の機能である、ということですね。 逆に for は普通の配列アクセス命令でした。こういったところにも単純な繰り返しの for と、配列を逐次処理する foreach の違いがあります。 まとめ for と foreach の両者を比較してみると、構文ごとの目的の違いがわかりました。 for は繰り返し処理のための構文 foreach は逐次処理のための構文 一見どちらも繰り返しを目的としているようですが、 foreach のほうが用途を限定されています。 foreach はしばしば for をシンプルに書けるようになったと表現されたりしますが、実際にopcodeで比較してみると、 for の シンタックス シュガーではなく、内部ではしっかり別の処理です。 何気なく使っている構文でも、調べてみると意外と奥深いものです。
アバター