新着記事

【合格体験記】新卒4ヶ月でAWS Certified Solutions Architect - Associate (SAA)を取得した話

新卒で入社して5ヶ月経つ高津です。

8/6にCLF、8/26にSAAに合格したのでそれについて書いていこうと思います。

なぜ受けようと思ったのか

会社からの推奨もあって4月に基本情報技術者試験を受けたのですが、

「基本情報くらいノー勉で受からなきゃ話にならん」

といきがってノー勉で受けたところ見事にあと1問のところで午前試験で落ちてしまいました。

運が悪かったと思いつつもあまりにも不甲斐ない結果で終わってしまったので流石に何か他の資格でもとっておこうと思い、色々検討した結果、今まで個人開発等で触ったことがありかつ弊社でも採用しているクラウドサービスであるAWSの資格試験は非常に馴染みが深く障壁が小さいと思い挑戦しようと思いました。

また普段使う機会のないサービスを学んだり体系的な知識を身につけるという面でも今後にとってプラスになるのではないかと思い受験しました。

勉強開始前のスペック

  • 個人開発で基本的なサービス(EC2,S3,Route53,RDS,IAM,CloudFront etc)は触ったことがある
  • 実務では前のインターン先で少し触ったくらい

CLF受験

CLFは巷では「簡単すぎて受ける価値が無い」などと言われていたりもしますが、SAAの勉強をいきなり開始するのは少し腰が重いと思って受けることにしまいした。結果的にCLFを最初に受けたことでCLF合格→SAA合格までのハードルがかなり低く感じて非常に良かったと思っています。

また、合格特典でSAA受験費用が半額になるのも非常に良いです。

勉強方法

AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー

AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー という参考書を1周して脳にある程度インデックスを貼ってからUdemyの模擬試験問題集をひたすら解きました。

このときに学んだことが土台となってSAAの勉強にもかなり生きた実感はあります。

結果としては797点(700点が合格ライン)で100点近く余裕を持って合格できました。

SAA受験

CLFと同様まずは参考書で体系的な知識をインプットしようと思い**AWS認定 ソリューションアーキテクト − アソシエイト教科書という参考書を1周しました。**

CLFの勉強で使用した参考書のSAA版である**AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイトよりも図を用いて丁寧に解説されていたので頭に入ってきやすかったです。しかし、これ1冊で合格するのはCLFと同様難しいのでUdemyの過去問をひたすら解きました。**

CLF合格後、通勤の時間で軽く勉強する程度でまったりと勉強していたのですが、8月下旬にSAA02→SAA03に改定されて試験範囲が広くなることを知り慌てて1週間前に申し込んで追い込みました。

勉強する時間が全然確保できなかったので正直厳しいと思いましたがなんとか合格できました。

改定される前に取得できて本当に良かったです。

資格を取得して思ったこと

資格を取得しても何か特別な能力が身についたり給料が急に上がったりはしませんが、AWS全般的に自身がついたと思います。今までは必要にかられて少し勉強する程度だったのでAWSへの苦手意識もあり、そこまで自信はなかったです。しかし、取得後はプライベートでも気楽にAWSを触れるくらいハードルが下がり、会社内で飛び交うAWS関連の会話も難なくついていけるようになりました。車の免許を取得しただけで日頃から運転しないと運転できないペーパードライバーであるようにAWSの資格も取得しただけでは形だけのものになってしまうのでしっかり手を動かしてAWSを触り続けることは非常に重要です。資格を取得するだけではさほど意味は成さないと思いますがAWSを触るきっかけとしては資格取得は悪くないと個人的に思いました。

今後も余裕があればDVAやSOAも取得して4冠を目指して行きたいと思います。

RaycastとDashで爆速でドキュメント検索する(IDEでも可能)

イベント開発の保坂です。

今回はランチャーアプリ「Raycast」とドキュメント検索アプリ「Dash」を組み合わせたら便利すぎたので、そちらの紹介をしたいと思います。
数クリックでできてしまうので是非試してみてください。

1. Raycastをインストールする

最近話題のランチャーアプリ「Raycast」をまだインストールしていない場合はインストールします。

https://www.raycast.com/
Raycastとは? という方はググってみると紹介されている素晴らしい記事がたくさんあるので、そちらを参考にしてみてください。


raycast

私は使い始めたばかりなのですが特に
  • Quicklinks
  • プラグインのAWS
  • プラグインのNotion
  • Calculator(計算機)
をよく使っている気がします。


2. Dashをインストールする

こちらもまだインストールしていない場合はインストール(購入)をします。

これはドキュメントを一元管理することができ、検索したい内容をいちいち、ググって、公式ページから該当箇所を見つけるという大体毎日するであろうタスクから解放してくれるアプリです。


Django Queryset

ググってみるとスニペット用のアプリと紹介されていますが、私は Dash で スニペット機能は使用していません。

Dash は有料アプリで約30$で購入できます。たまにアップグレード版が出て有料アップデートらしいのですが、公式サイトから最新版をダウンロードしてライセンスを使用してアクティベートしようとしたら私のラインセンスはver5で古いと言われ、勝手に新しいライセンスをダウンロードするリンクがメールで送られて来たので最新ver6を使用できています。


3. Raycast と Dash をつなげる


Raycast の extentions からDash のプラグインをダウンロードすることができます。


これで Raycast 上で dash と打ち込みそのプラグインをエンターしてあとは探したい語句を打ち込むだけです。


4. (おまけ)IDE と Dash をつなげる

Dash はIDEのプラグインにもよくあります。私は Jetbrain の IDE を使用しているのですが、マーケットプレイスからDashを入れます。

プラグインの使い方説明に Cmd-Shift-D (Mac)とあるので、エディター上でググりたい単語にマウスカーソルを合わせて、そのコマンドを打てば一発でそちらのドキュメントが開きます。

検索したい時は大抵開発中でエディターと向かい合っていると思うので、Raycastを使うよりさらに早く開けます。初めてやってみると速すぎて驚きます。



Web ページの動作検証のためのボットスクリプトを Windows 上で作る

この文書は、開発経験の無いチームがウェブアプリケーションの動作検証の責任を持つケースで、検証を簡単なプログラムで行うアプローチについての手法を解説しています。

Webアプリケーションの動作検証の際、手動で実行する以外にプログラムで検証すると便利です。開発者であればは検証コードを書くのは簡単ですが、開発経験の無い方はどこから始めたらいいかわからないと思いますので、比較的用意にスクリプトに入門できるように紹介します。OS は Windows を対象としています。

本記事で紹介しているようなプログラムによるリクエストは悪意の有無にかかわらず、不正アクセス禁止法での不正アクセスとみなされたり、電子計算機損壊等業務妨害罪等に問われる可能性があります。実際にリクエストを行う場合は、自社の管理する、許可されたサーバに対してのみ行うようにしてください。

HTTP の リクエスト・レスポンスの仕組みを知る

まずは、ウェブサーバと通信している HTTP のリクエストがどのようなものか知ることが必要です。この知識があいまいなままだとボットのスクリプトは書けません。

まずは、ウェブブラウザに搭載されている開発者ツールを使ってリクエストやレスポンスを観察するのが、良い勉強になります。

ウェブサーバに対して、

  • どの URL に対して
  • どのHTTP メソッドで (GET, POST, HEAD, PUT 等)
  • どのような HTTP ヘッダーで
    • cookie
    • referer
    • user-agent
  • どのようなリクエスト本文(body)で

以上を意識して、ブラウザの行っているリクエストをスクリプトで再現できれば、どのようなクライアントを使おうが、ウェブサーバからはブラウザでのリクエストと同じようにレスポンスが返ってきます。

Chrome のデベロッパーツールの使い方

  1. Google Chrome を起動してください。
  2. Shift + Ctrl + I を押してください。
    右側にデベロッパーツールが表示されます。
  3. デベローパーツールの上部のタブで、Network を選択してください。
  4. ブラウザの URL 欄に適当にページを打ち込み、ページを表示されてください。
  5. リクエスト一覧が表示されますので、適当なリクエストをクリックして選択してください。
  6. Headers にリクエストヘッダ、レスポンスヘッダ
    Payload にリクエスト本文
    Response にレスポンス本文
    が確認できます。
    特に、Headers のリクエストヘッダでどのようなヘッダを送っているか、確認してください。

Headers の中でも、cookie は特に注目してください。cookie の扱いはボット作成の中で最上位に重要な項目です。不安があれば、他のサイトや書籍を参考に学習してください。

また、 cookie の内容は認証情報を含むため、サイトのログインパスワードと同じぐらい重要な秘密情報です。安易にコピーは行わず、また絶対に他者に教えないようにしてください。ブラウザの cookie を格納している場所は安全ですが、他の場所にコピペすると漏洩リスクとなり、ログイン権限を奪われる危険性があります。

HTTPヘッダとクッキーの学習ができるサイト

HTTP ヘッダ、クッキーについての概要は、とほほ先生のサイト、わわわ先生のサイト、あと Wikipedia を読めば理解できます。

HTTPヘッダ

Cookie

ブラウザを手動で操作する以外での HTTP リクエストを行う方法

HTTP リクエストは、結局は特定の文字をサーバに送るだけですので、様々なクライアントで行うことができますが、よく使われるものを紹介します。

Postman

https://www.postman.com/
フリーの Windows クライアントがあります。GUI でリクエストを構築することができますし、スクリプトによる制御処理も書けます。有用なツールですが、最初は機能が多く複雑なため戸惑うかもしれません。

長所
  • GUI で完結する
  • 大量のテストリクエストの管理がしやすい
  • 署名の計算等、複雑な計算を伴う処理も行える。
短所
  • 複雑なため習得が難しい
  • 単純なリクエストを出すだけであれば冗長

curl

mac や linux を使う方には定番のコマンドラインツールです。Windows 10 からは標準でインストールされています。

長所
  • インストール済みなのですぐに使える
  • 単純なリクエストを1発出すだけなら一番適している
短所
  • 計算を伴う順次リクエストには向かない

Selenium や Puppeteer

プログラムで Chrome などのブラウザを実際に起動し、自動操作するための Selenium や Puppeteer といったツールがあります。

ブラウザを起動するため、ページ内で JavaScript を豊富に扱うページも自動操作し、検証することができます。

最近のウェブサイトは、React や Vue といった JavaScript を用いて表現するサイトが多くなってきており、その場合は Postman, curl, 後述するシンプルなスクリプトでは十分な検証ができない場合がありますので、 ページ内の JavaScript の動作検証が必要になる場合実際のブラウザを実行させる以外に無く、自動操作するには Selenium や Puppeteer を使うしかありません。

扱うには高度なプログラミング知識が必要ですので、今回は言及しません。

長所
  • ブラウザでの JavaScript の実行が必要であればこれ一択
  • 表示レイアウトの確認にも使える
短所
  • 実行環境の構築が難しくて、手間がかかる。
  • 他の、単純なリクエストを出す方式に比べると遅い。
  • 様々な要因により安定させて動作させるのは難しい。業務レベルで使うには高い技術が必要。

Rest Client ( .http)

ドットエイチティーティーピーファイルを作り、その記述したリクエストを簡易に何度も再現させることができます。VSCode や JetBrains エディタの機能として扱うことができ、記述が簡単で読みやすいため私は(当社内でも)かなり使います。

長所
  • 習得が容易
  • スクリプトの構文が容易で書きやすく読みやすい
  • スクリプトのチーム内共有が容易
  • レスポンスへの簡易的なテストを行うことができる
短所
  • 計算を伴う複雑な逐次処理はできない

プログラミング言語でスクリプトを組む

Python, PHP, Javascript, Ruby などで、既にある便利な HTTP クライアントライブラリを使ってスクリプトを組む方法です。
今回の記事ではこちらを今回紹介します。

長所
  • 条件分岐を含む複雑な制御処理が得意
  • 複数セッションによる並列リクエストを再現したい場合は一択
  • 完全無人での自動実行が容易
  • 書いたコードの再利用が容易
  • 処理結果の外部ツールへの連携が柔軟に行える
短所
  • 環境構築が手間
  • 単発のリクエストを検証したい場合は RestClient や Curl, Postman と比べても冗長

Windows に Python 実行環境をインストールする

Microsoft Store からの Python のインストール

Microsoft Store で Python パッケージが提供されるようになり、昔と比べて環境構築が楽になりました。

Microsoft が提供している、初心者向けの Python の開発ガイドが良くできています。この流れにそって進めれば問題なく進められますので、こちらも参考にしてください。

Microsoft Store のアプリを開き、 Python を検索して Python 3.10 をインストールします。

インストール後、念の為再起動を行い、その後コマンドプロンプトを起動して python と打ち込んで、 python が起動するか確かめてください。

Python 公式サイトからの Python のインストール

コマンドプロンプトで、 python と打ち込んで python が起動しないようであれば、Microsoft Store からインストールした Python はアンインストールし、 Python の公式サイトから Windows 版のインストーラパッケージをダウンロードしてインストールしてください。

その際、PATH を追加編集するかのオプションが表示されるので、チェックを入れてください。

https://www.python.org/downloads/

requests ライブラリのインストール

Python の インストールが完了したら、ウェブを操作するボットの作成に必須ともいえる、 requests ライブラリをインストールします。

コマンドプロンプトや PowerShell で、

python -m pip install requests

と入力すると、インストールが完了します。

Visual Studio Code のインストール

エディタは Visual Studio Code を使います。

Microsoft Store から Visual Studio Code を検索してインストールしてください。

プロジェクトフォルダの準備

Windows の、ドキュメントフォルダの下にtest-bot フォルダを作ってください。

VSCode を起動し、 File -> Open Folder で test-bot フォルダを開いてください。

フォルダを開いたら、左側のペインで右クリックし、 New File から first_bot.py というファイルを作ってください。

作成後、右下に「インタープリターを選択」と表示されているようであればクリックしてください。Microsoft Store からインストールした Python が、おすすめに表示されているので選択します。

右下に CRLF と表示されている箇所は、改行コードの設定が表示されています。CRLF は一般的ではないため、クリックして LF に変更しておきます。

Python の機能拡張のインストールがおすすめされると思いますので、Python, Pylance の機能拡張をインストールします。

スクリプトを書く

レスポンス本文を表示するだけのスクリプト

import requests
response = requests.get('https://www.torico-corp.com/')
print(response.text)

これは、 https://www.torico-corp.com/ のレスポンス本文を表示するだけの単純なプログラムです。
書いたら、右上の ▶ ボタンを押して、実行させてください。
出力結果がずらっと表示されます。

requests ライブラリについてのドキュメント

レスポンスの経過時間とステータスコードを表示するスクリプト

import requests
response = requests.get('https://www.torico-corp.com/')
print('経過時間 {}ms'.format(response.elapsed.microseconds / 1000))
print('ステータスコード {}'.format(response.status_code))

このスクリプトは、レスポンスの応答時間とステータスコードをコンソールに表示します。

Python に慣れてきたら、結果をファイルに記録するように改修することで、簡易的な負荷監視などに応用できます。

サイトの検索結果ページからを解析するスクリプト

Webサイトの検索ページにリクエストを行い、結果の HTML をパースしてコンソールに表示するスクリプトです。

HTMLをプログラムで扱えるように解析するために、 BeautifuSoup というライブラリをインストールします。

BeautifulSoup のインストール方法

コマンドプロンプトで

python -m pip install beautifulsoup4

でインストールできます。

BeautifulSoup の解説記事

コード

import requests
from bs4 import BeautifulSoup
response = requests.get('https://tech.torico-corp.com/search/?q=docker')
soup = BeautifulSoup(response.content, features='html.parser')

for h2 in soup.find_all('h2'):
a = h2.find('a')
if not a:
continue
print(a.text)
print(a['href'])

上記スクリプトは、TORICO の技術開発ブログを「docker」で検索し、出てきた記事のタイトルとリンクURL を表示しています。

メールアドレスとパスワードでウェブサイトにログインする

最後に、メールアドレスとパスワードでログインをするスクリプトの雛形を記載します。

requests ライブラリは、クッキー管理を行うことのできる Session というしくみがありますので、それを使います。

解説記事

検証するサイトによりますが、多くの場合は、ログイン時に「CSRFトークンの検証」と「Refererヘッダの検証
User-Agent が悪質なボットでないかの検証」を行っていると思いますので、そこを考慮してスクリプトを作れば、ログインが行えるはずです。

下記のような自動ログインのスクリプトは、必ずご自身が権限を持つサーバにのみ行うようにしてください。他者のサーバに行うと罪に問われる可能性があります。

URL 等は架空のものです。

import requests
from bs4 import BeautifulSoup

# session を作る
s = requests.session()
# User-Agent を設定する場合
s.headers['User-Agent'] = 'Tester Python Bot'

# ログインフォームを取得する
response = s.get('https://example.com/login-form/')

# HTTP のステータスコードに異常が無いか確認
response.raise_for_status()

# ログインフォームをパースする
soup = BeautifulSoup(response.content, features='html.parser')

# パースしたログインフォームから CSRF トークンを取得する
csrf_token = soup.find('input', {'name': 'csrftoken'})['value']

# ユーザー名とパスワードをいれてログインフォームを送信する。
response = s.post(
'https://example.com/login-form/',
data={
'email': 'tester@example.com',
'password': 'MY_AWESOME_PASSWORD',
# 先程取得した CSRF トークンを付与
'csrftoken': csrf_token
},
headers={
# Referer を付与
'Referer': 'https://example.com/login-form/',
})

# HTTP のステータスコードに異常が無いか確認
response.raise_for_status()

# ログイン後の URL が正しいものであるか確認
assert response.url == 'https://example.com/mypage/'

# この時点で、セッション s はログイン済みの状態なので、
# マイページ等をリクエストすることが可能
response = s.get('https://example.com/mypage/myprofile/')

そうだ、mysql8.0サーバーを構築してみよう

ども、お久しぶりです。

オンプレのインフラ構築を担当することが多い四斗邊です。

今回は社内の要望でmysql8.0サーバーを社内ネットワーク上に構築する!というのが目標です。

結構ありふれたネタだと思いますが、社内に向けた手順書のような形で残しておきたかったので今回記事しました。

PC構成


  • CPU intel i5-12400 6コア12スレッド 2.5GHz

  • メモリー CT2K32G4SFD832A メモリー32GB 1枚(レイテンシーは特に考えていない)

  • ベアボーンキット DeskMini B660

  • SSD WDS100T3X0E 1TB

これで10万円を切った構成になっています。
安くてそれなりに社内サーバーとしてはそこそこパワーがある構成にしてみました。
一番の特徴はなによりもベアボーンキットなのでコンパクトなのがいい。
個人的にはCPUはAMD派ですが、2022年8月上旬ではintelが安くてちょうどいいかんじでした。
家庭用なので消耗とか気になりますが、4年ぐらいは耐えてくれてると信じたい。

OSソフトウェア構成


OS ubuntu 22.04
DB mysql8.0.30

ubuntu以外も候補はありますが、構築経験があるのでこちらかなと。

mysqlインストール手順


*注意事項
手順の前にsshとかOS周りの設定は一通りしております。今回の手順はmysqlインストールに特化したものとご了承ください。

mysql-serverのインストール

$sudo apt install mysql-server

mysqlにログインする。

$sudo mysql
#ユーザー確認
mysql >select user,host from mysql.user;

インストールしているときに、すでにrootユーザーは作られているので、以下のコマンドでパスワードを改変する。hogeの部分は任意なパスワードに変える。

mysql > USE mysql; 
mysql >ALTER USER 'root'@'localhost' identified BY 'hoge';
一応権限の確認は以下で確認できる
mysql > show grants for 'root'@'localhost';

後々構築した後に気づいた点で、localhostになっているので、リモート時にはrootユーザーに入れないことがあった。

やっぱりここはrootユーザーのhost=%を作るに限る。(セキュアな面ではもうちょっとhost部分は制限したほうがいいかも)

mysql > CREATE USER 'root'@'%' IDENTIFIED BY 'hoge';
mysql > GRANT ALL ON *.* TO 'root'@'%';

これでリモート上でもrootで入れる。

文字のエンコードはutf-8に設定したかったので、my.cnfを以下のようにいじる。参考にしたURL↓

https://qiita.com/is0me/items/12629e3602ebb27c26a4

まずはmy.cnfの場所の特定。どうやら/etc/my.cnfが先で、次に/etc/mysql/my.cnfの順番で読み込まれるようだ。

mysql --help | grep my.cnf 
#以下結果 
order of preference,my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf

/etc/mysql/my.cnfの中身を見ると以下のような記載がありました。

!includedir /etc/mysql/conf.d/ 
!includedir /etc/mysql/mysql.conf.d/

/etc/mysql/conf.d/のディレクトリに入れると反映されるのでは?ということで、ここにmy.cnfを設置してみる。

保存するその前に、一旦、サーバー上でmysqlが止まっているか確認する。

mysqlが止まっているか以下でわかる。(すでに稼働している場合は周りに影響しないか注意してください。)

$sudo service mysql stop
#以下の内容を入れて/etc/mysql/conf.d/my.cnfに保存する。 
[mysqld]
character-set-server=utf8mb4
[mysql]
default-character-set=utf8mb4
[client]
default-character-set=utf8mb4
#更新したら以下でリスタートする。
service mysql restart

あとは、リモート上でも接続できるようにサーバー上でリッスンを設定する。今回は、mysqlのポート3306をリッスンさせる。

mysqlインストール時にすでにポートはリッスンしているので、bind-addressとmysqlx-bind-addressのアドレスを変更するようです。

/etc/mysql/mysql.conf.d/mysqld.cnf
#bind-address = 127.0.0.1
#mysqlx-bind-address = 127.0.0.1

更新したら以下でリスタートする。

service mysql restart

そうすると、自動的に全てのアドレスから全てのアドレス:3306でリッスンできる。

sudo ss -talpn 
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 151 *:3306 *:* users:(("mysqld",pid=3822,fd=23))
ただ、この設定は少し強引すぎる。

社内サーバー用とかで事前に外部からのアクセスを制限できているなど限定した場面で活用するのが望ましい。というか一応ufwも確認する。

sudo ufw allow 22 #ssh 
sudo ufw allow 3306 #mysql
sudo ufw enable
sudo ufw status numbered
To Action From -- ------ ----
[ 1] 22 ALLOW IN Anywhere
[ 2] 3306 ALLOW IN Anywhere
[ 3] 22 (v6) ALLOW IN Anywhere (v6)
[ 4] 3306 (v6) ALLOW IN Anywhere (v6)

これでmysqlとsshのみ通るようにポートは開けることが確認できた。

ここまでで一通りのmysqlサーバの完成となる。実際に自身のPC上で確認してみてください。

以下のコマンドで入れたら成功です。

(もちろんローカル上にもmysqlは入れてるよね?)

mysql -h XXXX.example.co.jp -u root -p
パスワードを入力:hoge

できましたかね?これであなたもmysqlサーバー構築者だ、おめでとう!

できない人は個別のトラブルシューティングに従って解決してください。

結構最低構成でできたはずなので、時間はかからないのかなと思っています。

みなさん試してみてください。

便利なfabricを使ってみる!

4月1日に新卒で入社したエンジニアの宮副です。
入社してすでに3ヶ月が過ぎました。
今回は、業務の中でもよく使われている「fabric」について書いていきます。

fabricとは

fabricはpythonのライブラリで、コマンドラインで関数を実行できるツールです。
さらに、SSH経由でシェルコマンドを実行することでもできます。
fabricをに定義することで、デプロイ時などで毎回打つ幾つものコマンドを省略することができるのでとても便利です。

実際にやってみる

実際にどういう風に使っているかを書いていきます。
まずはfabric(fabric3)をインストールします。

$pip3 install fabric3

次にfabric.py か fabfile/__initi__.py 内に関数を書くことでコマンドを実行できるようになります。
会社では fabfile/__init__.py 使っています。

def hello():
    print("Hello world!")

と書くと、

$fab hello

これで print() が実行されます。

では、次に少し応用してみます。

from fabric.api import local

def deploy_git():
    local("git add . && git commit -m 'commit message'")
    local("git push")

実行してみましょう。

$fab deploy_git

これでgitコマンドを打たなくても、pushすることができます。

また、

from fabric.api import local

def add():
        local("git add .")

def commit():
        local("git commit -m 'commit message'")

def push():
        local("git push")

def deploy_git():
    add()
        commit()         push()

このように構造化することで便利になります。

それぞれの環境にデプロイするときには、hostを指定してデプロイすることもできます。

from fabric.api import local

#開発環境
def dev():
    env.hosts = ['dev.example.com']

#本番環境
def production():
    env.hosts = ['www.example.com']

def deploy_env():
        #デプロイ処理
$fab dev deploy_env
#開発環境にデプロイ

$fab production deploy_env
#本番環境にデプロイ


__init__.py
に書いてるコマンドを見たいときには、

$fab -l

とするとfabコマンドを一覧で見ることができます。

まとめ

今回は業務のデプロイ作業で使っているfabricについて紹介しました。
入社して3ヶ月経ちましたが、まだまだ分からないことだらけの毎日です。
そんな僕でも、先輩エンジニアの方々に質問すれば丁寧に優しくわかりやすく教えていただけるので楽しく業務をすることができています。

コピペですぐ動く! Gmail をスプレッドシートに書き出す Google Apps スクリプト

あるメーリングリスト(Google グループ) に送信しているメールアドレスの一覧を作りたかったので今回のスクリプトを書きました。

普段 Gmail を使われている場合、Google Apps Script (GAS) を使うことでメールの処理をスクリプトで簡単に自動化することができます。

今回は、Gmail で受信したメールを検索し、検索結果を Google スプレッドシートに書き出す方法を紹介します。

ウェブ上のツールでスクリプトを少し書くだけで実現できます。メールを使う業務の自動化に応用できると思います。

1. Gmail の検索条件を作る

Gmail を開き、検索窓を使って対象のメールを絞り込みます。

to:label: などの演算子を活用して、絞り込んでください。

例えば、 mailinglist@example.com に向けて送信されている、 14日以内に受信したメールを絞り込む場合、

to:mailinglist@example.com newer_than:14d

として検索します。

その他の演算子はこちらに紹介があります。

Gmail で使用できる検索演算子 - Gmail ヘルプ

作成した検索条件は記録しておきます。

2. 書き出し先のスプレッドシートを作る

Google スプレッドシートを開きます。

https://docs.google.com/spreadsheets/

「新しいスプレッドシートを作成」の「空白」を選択します。

作成されたスプレッドシートのURL を確認します。

https://docs.google.com/spreadsheets/d/<ここの部分>/edit#gid=0

上記の、英語の乱数部分がスプレッドシートのIDです。これを記録しておきます。

3. Google Apps Script を作る

https://script.google.com/ を開きます。

「新しいプロジェクト」をクリックします。

「無題のプロジェクト」となっている箇所をクリックし、「メールをスプレッドシートに書き出し」など、適当に変更します。

スクリプトの内容は、下記内容をそのままコピペします。

function exportGmails() {
var book = SpreadsheetApp.openById('<ここにスプレッドシートIDを記入>');

var criteria = '<ここにGmail検索条件を記入>';
var threads = GmailApp.search(criteria);

var sheet = book.getActiveSheet();
sheet.getRange(1, 1).setValue('日付');
sheet.getRange(1, 2).setValue('宛先');
sheet.getRange(1, 3).setValue('From');
sheet.getRange(1, 4).setValue('ReplyTo');
sheet.getRange(1, 5).setValue('件名');

for (var i = 0; i < threads.length; i++) {
messages = threads[i].getMessages();
message = messages[0];
console.log(message.getFrom());
rowNumber = i + 2;
sheet.getRange(rowNumber, 1).setValue(message.getDate());
sheet.getRange(rowNumber, 2).setValue(message.getTo());
sheet.getRange(rowNumber, 3).setValue(message.getFrom());
sheet.getRange(rowNumber, 4).setValue(message.getReplyTo());
sheet.getRange(rowNumber, 5).setValue(message.getSubject());
}
}

<ここにスプレッドシートIDを記入> の箇所を、2で作成した スプレッドシートのURLに含まれるIDに書き換えます。

<ここにGmail検索条件を記入> の箇所を、1で作成した Gmailの検索条件に書き換えます。

保存ボタンを押して、実行を押します。

初回起動時は、「承認が必要です」というダイアログが表示されるので、「権限を確認」をクリック。

個人用の Gmail の場合、「このアプリは Google で確認されていません」となるので、「詳細」をクリックして 「(安全ではないページ)に移動」をクリック。
(企業の Google Apps の場合、この警告は出ません)

許可ダイアログで「許可」をクリック

するするっとコードが実行されて、スプレッドシートに書き込まれます。

スプレッドシートに書き出す項目を変更する場合、コードを修正してください。

コード中に、message.getDate(), message.getTo() などのメソッドでメール内の属性を取得していますが、その他の属性も書き出すことができます。メールオブジェクトのメソッドのリファレンスはここにありますので参考にしてください。

Class GmailMessage | Apps Script | Google Developers

Ubuntu22 に MicroK8s で Kubernetes 環境を構築し、その中で Rancher を起動する

今まで(2021年頃まで) は、社内サーバの Kubernetes 環境を作る際は、 Rancher を Docker で起動し、その中の RKE で Kubernetes クラスタを構築していました。

ところが、それだと OS のアップデートがあったりした時など、年一回ぐらいのペースでトラブルがあり、環境が再構築不能になってしまっていました。

Rancher + RKE で Kubernetes 環境を作っている場合、トラブルの原因を追うのが非常に難しくて、原因まで解明して解決できたことはありません。

今回は、 Kubernetes 環境は Ubuntu の MicroK8s で起動し、その K8s の中で、 Deployment として Rancher を起動するようにしました。

試してみた所、なかなか快適だったため、今後もこのパターンは使っていこうと思います。

OS は Ubutntu 22.04 で、ノードはシングルノード構成です。やはり OS が Ubutnu の場合は MicroK8s が簡単で安定しており、Ingress なども一発で有効化できるため、セットアップは楽でした。

1. MicroK8s の セットアップ

1-1. インストール

sudo snap install microk8s --classic

1-2. ユーザーに権限を付与する

sudo usermod -a -G microk8s ubuntu
sudo chown -f -R ubuntu ~/.kube
newgrp microk8s

1-3. DNS, Ingress の有効化

microk8s enable dns ingress

1-4. ダッシュボードを使う場合

Rancher が起動したらダッシュボードは不要だと思いますが、Rancher 起動前の確認用として重宝します。

microk8s enable dashboard

Kubernetes のノード上で

microk8s kubectl port-forward -n kube-system service/kubernetes-dashboard --address 0.0.0.0 31443:443

してから、https://<your-host>:31443/ を見る

2. kubeconfig の取得

microk8s config

コピペして、 Mac の .kube/config-<Config名> にコピーしておく

3. namespace の作成

※ Macで実行

#!/usr/bin/env zsh

export KUBECONFIG=${HOME}/.kube/config-<Config名>

kubectl create namespace <ネームスペース>

4. secrets の作成

SSL証明書 (wildcard.example.com.key, wildcard.example.com.crt) を mac のディレクトリに用意して、

※ Macで実行

#!/usr/bin/env zsh

export KUBECONFIG=${HOME}/.kube/config-<Config名>

kubectl -n <ネームスペース> create secret tls tls-certificate \
--key <wildcard.example.com.key> \
--cert <wildcard.example.com.crt>

5. Rancher のインストール

サーバに /data/rancher ディレクトリを作っておく

deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-awesome-rancher-deployment
namespace: <ネームスペース>
spec:
replicas: 1
selector:
matchLabels:
app: my-awesome-rancher
template:
metadata:
labels:
app: my-awesome-rancher
spec:
containers:
- name: my-awesome-rancher
image: rancher/rancher:v2.6-head
imagePullPolicy: Always
ports:
- containerPort: 80

volumeMounts:
- name: data-rancher
mountPath: /var/lib/rancher

imagePullSecrets:
- name: ecr-credeintial

volumes:
- name: data-rancher
hostPath:
path: /data/rancher

service.yml

apiVersion: v1
kind: Service
metadata:
  name: my-awesome-rancher-service
namespace: <ネームスペース>
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
name: my-awesome-rancher-http
selector:
app: my-awesome-rancher

ingress.yml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-awesome-rancher-ingress
namespace: <ネームスペース>
spec:
tls:
- hosts:
- my-awesome-rancher.example.com
secretName: tls-certificate
rules:
- host: my-awesome-rancher.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-awesome-rancher-service
port:
number: 80

※ mac で実行

#!/usr/bin/env zsh

export KUBECONFIG=${HOME}/.kube/config-<Config名>

kubectl apply -f deployment.yml
kubectl apply -f service.yml
kubectl apply -f ingress.yml

6. Rancher の ブートストラップパスワードの取得

Rancher を起動すると、「ブートストラップパスワード」が発行され、ログに表示されます。

今回は Kubernetes の Pod として起動しているため、Pod のログを grep します。

 ※ Macで実行

#!/usr/bin/env zsh

export KUBECONFIG=${HOME}/.kube/config-<Config名>

pods=( $(kubectl get pod -n <ネームスペース> | egrep -o "my-awesome-rancher-deployment-[a-zA-Z0-9-]+") )

for pod in "${pods[@]}" ; do
kubectl logs -n <ネームスペース> ${pod} | grep "Bootstrap Password:"
done

7. ブラウザから Rancher へのログイン

my-awesome-rancher.example.com (仮のドメインです) というドメインで Rancher が起動しているはずなので、DNS を設定してからブラウザでアクセスします。

Bootstrap Password の入力を求められるので、先程取得したものを入力します。

ローカルで起動している MicroK8s のシングルノードクラスタを自動的に認識し、管理できるようになります。

付録

kubernetes の secret へ、AWS の EKS のログイントークンを登録する Python スクリプト

当社は、Docker イメージリポジトリは AWS ECR を使っています。
ローカルPCの ~/.aws/credentials の認証情報を元に、 Kubernetes の Secret を作るスクリプトを紹介します。

#!/usr/bin/env python3

import subprocess
import re
import sys

namespace = '<ネームスペース>'
secret_name = 'ecr-credeintial'
aws_region = 'ap-northeast-1'
docker_server = 'https://<AWS-ID>.dkr.ecr.ap-northeast-1.amazonaws.com'


def main():
output = subprocess.check_output([
'/usr/bin/aws', 'ecr', 'get-login',
'--no-include-email', '--region', aws_region,
]).decode()
words = output.split()
username = words[words.index('-u') + 1]
password = words[words.index('-p') + 1]

// 既に作成済みの secret を消す
command = [
// kubectl の実行環境に合わせて調整してください
'microk8s', 'kubectl', '-n', namespace, 'delete', 'secret', secret_name]
subprocess.run(command)

// secret を再登録する
command = [
'microk8s', 'kubectl', '-n', namespace, 'create', 'secret',
'docker-registry', secret_name,
f'--docker-username={username}',
f'--docker-password={password}',
f'--docker-server={docker_server}'
]
subprocess.run(command)


if __name__ == '__main__':
main()

新卒1ヶ月目の業務内容

4/1から新卒でエンジニアとして入社した高津です。
今回は新卒で入社1ヶ月でどのような業務を行ったのか紹介していきたいと思います。
TORICOにエンジニアとして入社を検討している人に少しでも参考になれば幸いです。

主な業務内容

自分はコーマス開発部で、漫画全巻ドットコムの開発をメインでやっています。

簡単なバグ(UI)の修正漫画全巻ドットコムのリニューアルの大きく2つに分けられます。

簡単なバグ(UI)の修正

こちらは数時間で終わるような簡単なUIの修正(改修)で入社して3日後にはプルリクエストを出していました。

  • アイコン(font-awesome)が正しく表示出来るようにする
  • 個人情報同意フォームの改修
  • 電話番号記入欄のに数字が4文字入るようにする
    などの業務を行いました。

漫画全巻ドットコムのリニューアル

漫画全巻ドットコムは10年以上続く歴史のあるサービスで最初はPHPで作られていました。
メンテナンス性に問題があったのでDjango+Nuxt.jsにリプレイスしています。
今回自分は電子新着ページ電子割引ページをリニューアルしました。(ブログを書いている時点で実装は終わっていますがレビューが終わってないので本番にはまだ反映されていません)
Nuxt(フロントエンド)は先輩方が作ってくれた雛形を軽く修正して利用出来るのでDjnago(バックエンド)の実装がメインでした。
今回はその中でも難しかったポイントをいくつか列挙したいと思います。

キャッシュを効かす

同じ値を取得して返すだけなのに毎回SQLを叩くのは無駄なのでkye-value型のNoSQLであるredius(メモリ)に一定時間値を保管し、値がキャッシュされていなければSQL等を叩く処理を行います。(keyは引数、valueは返り値で保存)
ページ単位(view)単位でキャッシュする方法とクラスメソッド単位でキャッシュする方法の2パターンあります。
カテゴリー別の作品数を取得する処理はページ間(異なるurl)でも共通したしょりなのでクラスメソッド単位でキャッシュする必要があり、少々手こずりました。

SQLの実行回数(IO)を極力少なくしパフォーマンスをあげる

今回一番苦戦しましたポイントです。
ただ実装するだけであればすぐ終わったのですが、最初の実装ではSQLを12回叩いてしまっていたのでリファクタリングする必要がありました。(俗に言うN+1問題が発生していました)
こちらはやり方を先輩方にご教示頂き、MySQLにだけサポートされているconcat関数をraw_queryで使い1回で取得することに成功しました。
実際には以下のようなSQLに落ち着きました。

select GROUP_CONCAT(sample_id) AS ids, group_type from
dtb_sample WHERE aggregate_type=
'%s' AND product_type = 2
group by group_type ORDER BY sort_key;

テスト

TORICOの開発ではただ動くものを作るだけでなくその後の保守運用のことも考慮して単体テスト、統合テストも書くように徹底されています。
特にDB設計が少々複雑なこともありテストデータを作るところはかなり苦戦しました。

具体的には以下のようなことをテストしました。

  • 各URLにgetして正しい値やstatusが返ってくるか
  • 各メソッドのすべての条件分岐において正しく動作するかどうか
これらのテストを書くことでテストのしずらいメソッドが見つかり、それをリファクタリングすることで保守性の高いコードに改善出来ます。

また、仕様が分からない人がみても理解できるようにWhy「なぜこの処理を書くのか?」を極力書くように意識しました。

まとめ

如何でしたでしょうか?

今現在23卒のエントリーを受け付けています。
少しでも興味を持ってくれた人は是非応募して頂けると幸いです。

AWS RDSで大量のデータを削除する時等に、性能劣化を避けるために確認すべき項目(クレジット残高)

RDS で、大量のIO を伴う処理を行うと、処理途中で性能が大きく劣化することがあります。
不要になった大量の過去データをバッチで削除する時によく発生します。

これは、ストレージへの IO を規定量より高い頻度で行った時に減少するクレジットがあり、それが 0 になった時、パフォーマンスに制限がかかってしまうためです。

制限のかかった状態では通常通りのサービス運用はできなくなってしまうため、過去データ削除などの高負荷のバッチは、RDSのモニタリングページを見ながら注意深く実施する必要があります。

今回は、パフォーマンス低下を避けるために確認すべき RDS クレジットのメトリクスについて書きます。

各メトリクスの詳細は、AWS の公式ドキュメントに詳細な解説があります。 

高負荷な処理を行う際に確認すべきメトリクス

EBS Byte Balance

AWS のドキュメントによると、「RDS データベースのバーストバケットに残っているスループットクレジットの割合。」とのこと。データ転送量で減少していくのでしょうか。重い SQL を実行することで減ることがあります。

0になるとパフォーマンスが大幅に劣化します。

クレジットを消費するような SQL を実行しなければ、自動的に回復します。

EBS IO Balance

AWSドキュメントによると「RDS データベースのバーストバケットに残っている I/O クレジットの割合。」とのこと。広範囲の DELETE 文など、 IO が多く発生する SQLを実行するとどんどん減っていき、0になるとパフォーマンスが大幅に劣化します。クレジットを消費するような SQL を実行しなければ、自動的に回復します。

Burst Balance

AWSドキュメントによると「汎用 SSD (gp2) のバーストバケット I/O クレジットの利用可能パーセント。」プロビジョンド IOPS の RDSには項目がありません。GP2 ストレージの場合に、広範囲の DELETE 文など、 IO が多く発生する(IOバーストがされる) SQLを実行すると減っていきます。

CPU クレジット残高

T系インスタンスの場合にあります。CPUを多く使う(CPUバーストがされる)処理を行うと減っていき、0になるとパフォーマンスが大幅に劣化します。T系のEC2とお使いであれば、おなじみの項目ですね。

バイナリログのディスク使用状況とリードレプリカのレプリケーション遅延

リードレプリカをマスターより低い性能で運用している場合、マスターで行った処理を同じ速度で処理することができず、レプリケーション遅延が発生することがあります。

この時、リードレプリカが処理できないバイナリログはマスターの RDS に蓄積されるため、バイナリログのサイズが溜まっていき、リードレプリカの遅延もどんどん大きくなります。

解消させるにはマスターの処理のペースをリードレプリカに合わせて減らすしかありません。

状況に気づかずに大きな遅延とバイナリログができてしまった場合、遅いリードレプリカの処理を待つより、一度リードレプリカを削除し、新たに作り直したほうが時間短縮になる場合があります。

まとめ: 高負荷な SQL を発行する時に気をつけること

クレジット消費で一番やりがちなのは DELETE 文で多くのレコードを消そうとした場合です。また、その DELETE で変更されたストレージを最適化させるための OPTIMIZE TABLE でも多くのクレジットが消費されることがあります。

DELETE を行う場合、量にもよりますが、一発で済まそうとせず、範囲を絞って何度か実行するような SQLでメンテナンスしたほうがトラブルを避けられます。また、範囲指定もインデックスを使うようにし、意図しない広範囲のロックを避ける必要があります。

OPTIMIZE TABLE は範囲を絞ることはできないため、メトリクスを監視しながら、クレジットが 50% を切るようであれば停止を検討したほうが良いでしょう。

OPTIMIZE TABLE に限らず、10分以上かかるSQL の場合は、AWSコンソールから上記 EBS Byte BalanceEBS IO BalanceBurst BalanceCPU クレジット残高バイナリログのディスク使用量またリードレプリカの遅延 のメトリクスを常に監視し、クレジットの使い切りを発生させないようにしてください。

TORICOの品質管理業務 2. 検証に必要となる知識


こんにちは、品質管理チーム (QCチーム) の渡辺です。
ちょっと遡りますが、わたしがQCチームに初めて配属時とこれまでのお話をしましょう。

どこにでもシステムは組み込まれている

 わたしはこれまでは運営業務のお仕事が中心でした。
リアル店舗では接客、商品仕入れ、コーナー作り、特典作成、Web店舗では通信販売、電子書籍販売、バナー、サイトページ、企画などのページ作成、またカスタマー業務と幅広く携わってきました。
 お勧めの作品がお客様の目に留めてもらうために、工夫を凝らして試行錯誤して、作品の売行きが好転すると、次回も頑張ろうと意欲が湧くものでした。
そのために、システム開発者に協力をお願いし、サイトのレイアウトや企画を伝えては、変更やシステム開発をしてもらっていました。
漫画のコマをページに載せたり、スクロールしても付いてくるキャラ画像を設置してもらったり、特典のダウンロード機能を付けてもらったりと、工夫を凝らしたシステムを作ってもらい導入してもらいました。
現在も漫画全巻ドットコムサイトで継続されている全力推し宣言もその一環でした。数年後にお勧め作品がすべてアニメ化になった時は、心の中でガッツポーズしたものです。
わたし自身のWeb業務は、HTMLタグで色や文字を変更したり、時にはサイトのプログラムリニューアルで当時人気のBootstrapに切り替える作業や自社レジ作成のお手伝いをしていました。そんな中で、Web初心者よりは“Webを理解している”と思ってました。

 ご興味あればこちらから ⇒ 漫画全巻 全力推し宣言ページ

あの頃のWeb知識は初心者と一寸法師の背比べ

昨年10月にQCチームが立ち上がり、配属されたわたしは、今までの経験が活かせると大いに喜びました。
なぜかというと、業務内容が「デバッグ作業」という、サイトの中でお客様が検索や購入する操作をセッションごとにテストいき、操作中に不具合は出現しないか、レイアウトは崩れていないか、バグ発見次第に開発者へ報告する、ということだったからです。
また「開発中システムのテスト検証」もお客様にみせるサイトに関わる事なので、どちらもいままでの経験が役立っています。
そしてもう一つのミッションが「セキュリティ強化対策の検証」です。
この3つの業務を通して、システム開発者のお話を聞く機会も増えてきて、ようやく、わたしの持つWeb知識があまりにも少なくまた基礎が無いことが気づきました。開発者では良く会話の中に登場するAPI、プロトコル、AWSなど、単語の意味が分からない。いまや小学生から習う“インターネットの仕組み”も理解していませんでした。

Web知識は本から取得するのも一つの手


 そんな時に上司より良い教材を提供された、SB Creative刊『イラスト図解式 この一冊で全部わかるWeb技術の基本を読みました。
インターネットの基礎知識からセキュリティの脆弱性の脅威まで幅広く扱っていて、単語も調べられるので、とてもに役立っており、いまでも読んでいます。

本の詳細は出版社サイトへ⇒『 イラスト図解式 この一冊で全部わかるWeb技術の基本 』

読んでいくとスマートフォンでおなじみの「アプリ」画面は、chromeの画面と同じ「ブラウザ」であるなど、目から鱗なお話もあり、面白いです。
まだまだ、初心者に毛が生えたレベルのわたしですが、ここからもっと知識を蓄えて開発者たちの会話が分かるように努力していきます。

TORICOの品質管理業務 1. システムの動作検証の流れ



こんにちは、品質管理チーム (QCチーム) の渡辺です。
QCチームのお仕事の中に『システム動作の検証』というお仕事があるので、少しお話をしようと思います。

検証とは?

検証とは、2つの意味があります。
一つは、仮説が正しことを証明するために調べる事、もう一つは、しっかり調べ事実確認する事です。
わたしたちのお仕事の検証は前者の[仮説が正しことを証明するために調べる事]です。
どの部分で検証するかというと、システム開発担当が、構築したプログラムをサイトの本番環境(お客様が閲覧する環境)へ反映する前にわたしたちが検証を行っています。
ここでは検証の環境に応じて、テスト環境ではテスト検証、本番環境では本番検証と使い分けしておきます。
【参照】実用日本語表現辞典【検証】

完成されたシステムでも仮説?

開発者は依頼された仕組み(システム)をプログラミングします。この時の環境はローカル環境(開発者のパソコン内)だったり、開発者同士の共有環境だったりと、外部には絶対に流出しない環境で作成され、完成した段階で、本番環境にもっとも近いテスト環境に反映されます。
開発者の環境では完成しているのだから、もうすでに仮説ではなく定説になるのではと思われるかもしれません。
しかし、ここで問題なのが、正しく動作するという『証明』が開発者の環境下のみというところにあります。
わたしたちのお客様はいろんな端末を使って、サイトに訪れてくれます。
そのお客様が開発者と同じ端末で操作が行われることはそう多くないのです。
そのため、開発者の環境下の端末だけでは、完全には『証明』が出来ないのです。

QCチーム作業が始まる

ここからが、わたしたちQCチームの作業になります。
テスト環境に反映されたシステムをテスト検証します。
テスト項目書に「〇〇をクリックすると◎◎が開く」とあれば、そちらに沿って正しく動作をするかを調べます。
システムが正しく動作していれば「結果=◎◎が開く」となります。こちらで1項目クリアになります。
一見、すぐに終わるのでは?と思われがちですが、端末やブラウザを変えて、同じテスト項目を繰り返し行っているので時間がかかります。

端末は複数台を常時稼働

主に使用している端末はパソコン、スマートフォンのiPhone、android、ブラウザは、edge、chrome、firefox、safariにて行っています。
ボタンを1つ押してページが切り替わるという単純なテスト検証でも少ないても6回は行っていることになります。
また操作する人が変わると同じ端末であっても、なぜか結果が変わることもしばしばあるので、できるだけ数人で行うようにしています。

気になる事はとことん

そして、少しでも気になることがあれば、同じ操作を繰り返し行い、これは正しく動作していると納得いくまで行います。
何か引っかかる事がある場合、本番反映された時にそれが致命的なことになりかねないので、原因が判明するまでは検証を繰り返します。
どんな操作を用いても正しく動作することを「証明」するには、何度も繰り返し検証をしてみるということがとても重要なことなのです。

最後は本番環境

テスト検証にて、動作確認が終わったら、本番に反映されます。
テスト環境が本番環境に一番近いとはいえ、本番環境においても動作を『証明』しなければなりません。
また、稼働中のサイトなので、お客様がいつシステムを使用するか分かりません。
そのため、速やかに追加したシステムが正常に動作をするか、既存システムも動作しているかを素早く検証する必要があります。
そして、全てのシステム動作の検証が終わり、ようやく追加プログラムが正しい事を『証明』できたことになるのです。

以上、QCチームの『システム動作の検証』について、掻い摘んで解説してきましたが、いかがだったでしょうか?
この記事を通して、少しでもわたしたちのお仕事に興味を持っていただけたら、幸いです。

Flutter riverpod + hooks_riverpod の基本的な状態管理の使い方を Vuex (typed-vuex/vuex-module-decorators)と比較して紹介

当社 TORICO ではモバイルアプリ開発のフレームワークに Flutter を採用し、ウェブのフロントエンドのフレームワークとしては Nuxt を採用しています。

普段 Nuxt で開発している方が Flutter での開発を始める際、Flutter での状態管理フレームワークとして、riverpod + hooks_riverpod を使う場合、基本的な使い方を Vuex と比較すると理解が早まります。

状態管理とは

フロントエンド開発の際、「状態管理」という言葉がよく使われます。この「状態」という言葉、最初聞いた時は「この処理はステートフルだ」という言い回しでよく使う「ステート」と同じものだと思っていたのですが、実際はそれより狭い意味であり、「変数の変化をUIの再描画にリアクティブに伝える仕組み」ぐらいに思っておくと良いと思います。

今回の例では、数字の配列から平均値を求めてUIに表示していますが、「配列に値を追加する」という処理を書いただけ(実行するだけ)で、平均値の再計算と必要なUIの再描画が自動で行われます。この一連の自動処理を、「状態管理」と呼ぶと思ってください。

Nuxt + Vuex のカウンターアプリ

Githubでにソースコードを公開しています。

まずは、Nuxt + Vuex でカウンターアプリを作ってみます。上のボタンを押すと、カウンターが増え、下のボタンを押すと、そのカウントを Array に追加します。ついでに Array の平均値も表示するようになっています。

Vuex を TypeScript で書く場合、サポートライブラリとして nuxt-typed-vuex を使う方法と vuex-module-decorators を使う方法がありますが、今回はその両方の比較も兼ねて、両方のパターンで書いてみました。

Nuxt typed-vuex で書いたストア

Github で見る

import {getterTree, mutationTree, actionTree} from 'typed-vuex'

export const state = () => ({
// カウンター
count: 0 as number,
// カウンターの値を追加するリスト
countList: [] as number[]
})

export type RootState = ReturnType<typeof state>

export const getters = getterTree(state, {
// countList の平均値を求める
average: (state) => state.countList.length
? state.countList.reduce((p: number, c: number) => p + c, 0) / state.countList.length
: 0
})

export const mutations = mutationTree(state, {
// カウンターを増加
countUp(state) {
state.count += 1
},
// カウンターリストに追加する
appendCount(state, value: number) {
// nuxt の場合再代入の必要なし。push で再描画される。
state.countList.push(value)
}
})

export const actions = actionTree(
{state, getters, mutations},
{
// 現在のカウンターの値を countList に追加するアクション
async addToCountList({commit, dispatch, getters, state}) {
commit('appendCount', state.count)
}
}
)

Nuxt vuex-module-decorators で書いたストア

Github で見る

import {Module, VuexModule, Mutation, Action} from 'vuex-module-decorators'

@Module({
name: 'counter',
stateFactory: true,
namespaced: true
})
export default class extends VuexModule {
// カウンター
count: number = 0

// カウンターの値を追加するリスト
countList: number[] = []

// countList の平均値を求める
get average() {
return this.countList.length
? this.countList.reduce((p: number, c: number) => p + c, 0) / this.countList.length
: 0
}

// カウンターを増加
@Mutation
countUp() {
this.count += 1
}

// カウンターリストに追加する
@Mutation
appendCount(value: number) {
// vuex の場合再代入の必要なし。push で再描画される。
this.countList.push(value)
}

// 現在のカウンターの値を countList に追加するアクション
@Action({rawError: true})
addToCountList() {
this.appendCount(this.count)
}
}

両方のコードはまったく同じ動作をします。

ポイントとして、 appendCount のミューテーションですが、countList に .push で値を追加しているだけです。

リアクティブに状態の更新を UI に伝えるために、新しい Array を作って countList に代入しなくて大丈夫か、という感じはしますが、vuex の場合は Array や Object がステートに登録された場合、Observer というクラスを介して操作され、内容の変更もリアクティブに再描画されるようになりますので、これで大丈夫です。

Observerは、一部の Array のメソッドが使えなかったり、デバッグ時に値が直接見にくいなどの弊害もあるので、個人的には、この挙動はお節介すぎる気がしますが、理解して使えばコードを短く書けるため、上手に使いましょう。

Flutter + riverpod + hooks_riverpod で書いた場合

これと同様のアプリを Flutter + Riverpod + riverpod hooksで書いています。

Github で見る

counter_controller.dart

Githubで見る

import 'package:hooks_riverpod/hooks_riverpod.dart';

// カウンター
final countState = StateProvider<int>((ref) => 0);

// カウンターの値を追加するリスト
final countListState = StateProvider<List<int>>((ref) => []);

// countListState の平均値を求める
final averageProvider = Provider<double>((ref) {
final productList = ref.watch(countListState);
return productList.isNotEmpty
? productList.fold<int>(0, (v, e) => v + e) / productList.length
: 0.0;
});

final counterController =
Provider.autoDispose((ref) => CounterController(ref.read));

class CounterController {
final Reader _read;

CounterController(this._read);

// カウンターを増加
void countUp() {
// この update は、以下と同じ動作をする
// _read(countState.notifier).state = _read(countState) + 1;
_read(countState.notifier).update((s) => s + 1);
}

// 現在のカウンターの値を countList に追加するアクション
void addToCountList() {
_read(countListState.notifier).update((s) => [...s, _read(countState)]);
}
}

ほぼ同じ感覚で書けています。

vuex store でいう state は、StateProvider を使い、getter は Provider を使って書けます。

mutation は、 StateProvider に対し、 _read(myStateProvider.notifier).state = xxx とします。
これにより、状態の変更が StateProvider を Watch しているウィジェットに伝わり、再描画を行います。

action で書くようなロジックは、それらのメソッドを持つクラス(上記例では CounterController )を作り、そのインスタンスを Provider として作っておくのが良いと思います。 WidgetRef にアクセスさえできればどこに書いても動くのですが、vuex を真似て、StateProvider 等が書いてあるファイル中に一緒にコントローラークラスとして作っておくと、Flutter のプロジェクトも Nuxt のプロジェクトも同じような感覚で修正できるので、楽になるのではないでしょうか。

UI 側のコード(main.dart)の抜粋

Github で見る

class CounterWidget extends HookConsumerWidget {
const CounterWidget({Key? key}) : super(key: key);

@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countState);

return Column(children: [
Text(count.toString(), style: const TextStyle(fontSize: 48)),
ElevatedButton(
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
),
onPressed: () {
ref.read(counterController).countUp();
},
child: const Text('CountUp'))
]);
}
}

HookConsumerWidget を継承したウィジェットを作り、その中で ref.watch すると、その変数が更新された時に UI が再描画されます。

これからアプリケーションエンジニア(プログラマ) になるための準備

この記事は、株式会社TORICO Advent Calendar 2021 12/21 の記事です。

他社の方と話をした際、お子さんがアプリケーションエンジニアに興味があるという話を聞いたので、これからアプリケーションエンジニアになる人に向けての記事を書こうと思いました。

この記事の中にはエンジニアという言葉が何度も出てきますが、機械・工学のエンジニアのことではなく、コードを書いて機械を自動的に動かす人のことです。区別するために、なるべくアプリケーションエンジニアという表現をするようにしています。

アプリケーションエンジニア(プログラマ)とはどんな仕事か

エンジニアの業態は、大きく分けて、自社開発と受託開発があります。

自社開発とは

サービスの提供と開発を同じ会社で行っている場合がこのケースに当てはまります。社会人経験の少ない方は、おそらくサービス提供会社がアプリケーション開発も行っている印象を持たれる方は多いかもしれませんが、売上を上げるサービスをすべて自社開発している会社は、みなさんが考えているよりずっと少ないです。

サービスを自社で開発する会社は、企画を実現させるための工程が少ないため、スピード感のあるサービス開発が行えます。トライアル&エラーの手数も多く、開発技術がサービスに強く反映されます。

会社規模によっては十分なエンジニアチームが作れていない場合もあり、エンジニア人数が少ない場合、知識・技術に偏りが出たり新技術をうまく採用できていない場合があるため、求人応募する際は十分にチーム構成を調べたほうが良いでしょう。最新技術を十分に取り込んでいても、自分の求める開発チームの理想形とマッチしていない場合もあります。会社の技術ブログを見て自分にマッチしているかは事前によく調べておいてください。

会社の中の開発チームは、単純なプログラミング以外でも技術全般を広く担当する場合が多いため、ユーザー行動の解析だったり業務会計データの集計・整形だったり、社内LANの構築やグループウェアのメンテナンス、デザインや動画編集なども頼まれる場合があります。会社規模が小さいほど広い担当範囲を求められます。

そもそも自社開発の場合、会社組織がエンジニアに求めることが、「プログラムを書く」ではなく「業務課題に対して技術で貢献する」である場合が多いです。会社によると思いますが、私が今まで経験した会社はすべてそうでした。仕事をする上で、「プログラムを書く」かどうかはあまり関係無く、「新しいサービスをできるだけ多くのお客様に使ってほしい」といった業務課題があり、エンジニアはサービスの実態を作ることができるのでその分野で貢献します。ただ作るだけではなく、他メンバーとゴールやKPIを共有し、どうすれば合理的にその目標を達成できるか考えながら仕事をしていきます。

そのため、自社開発のエンジニアはビジネス的な観点も必要とされますし、ビジネス成果がエンジニアの評価とされる場合も多くあります。自分が書いたコードがお客様や会社の売上に直接影響することを実感できますし、誤って不具合を含んだコードをリリースしてしまった際は、お客様や他のメンバーから辛辣な苦情を受けることになります。

求人応募者にはエンジニアとしての即戦力を求めるため、受託開発より基準は高くなると思います。採用面接時には技術的な質問を多くされ、即戦力でなさそうだったり、業務水準に達するまでの成長時間が長くかかりそうだと判断されれば採用見送りとなります。中途採用の場合は、未経験だと採用は厳しいでしょう。未経験の場合は、業務以外の開発成果(ブログ・ポートフォリオサイト・オープンソースライブラリへの貢献等) を積極的に伝えると良いでしょう。

受託開発とは

受託開発とは、アプリケーション開発をする専門の会社(システムインテグレーター・SIer) が、開発機能を持たない会社からアプリケーション開発を依頼され、その依頼に従ってアプリケーションを作り、納品することをいいます。

開発を依頼する際に、どういったものを作ってほしいかを契約書で取り決め、受託開発会社はその契約を満たすものを作ることを最終ゴールとします。開発物がどれほどのビジネスインパクトを発揮するかは考慮する必要は無く、指示されたものを忠実に作ります。早く納品することが一番の価値となります。

場合によっては、アプリケーションサービス提供会社(発注者)が得た売上成果の一部を開発会社の売上とする「レベニューシェア」という形態を取る場合があります。ゲームなど、開発技術が売上に直結するようなものだったり、継続的な機能追加が必要なものはレベニューシェアとなる場合が多いです。レベニューシェアの場合、開発会社の責任領域がサービス売上にも及ぶため、完全な受託開発より開発の意見・提案が影響力を持つようになります。

現代のアプリケーションソフトウェアは複雑なため、開発依頼時点で開発物の仕様が十分に決まっている場合は多くありません。大抵は、正常に動作するいくつかのパターンの仕様のみが決められており、特殊なケースは考慮されてない場合も多いため、都度依頼者に確認するなどの対応をする必要がります。その際に新たな機能が必要なことが判明し、開発工期の再見積もりが必要になってしまうのはよくある話です。

これは依頼者の考慮不足といえばそうなのですが、現代のアプリケーションを仕様書で完璧に組み上げることは不可能です。完璧を目指せば、それはプログラムコードと同じものになるので、人に依頼するよりコードを書いたほうが早いってなります。

開発依頼時点で開発物の仕様が十分に決まっていない理由としては、「最終目標に破綻の無いように、詳細な動作仕様を決める」というところまで、依頼内容に含むと考えていることも多いです。どこまでを誰が考えるか、あいまいなまま開発を進めてしまうと、問題が発生した時に責任問題となりますので、契約時の段階でアプリケーションサービス提供の内容をお互いにしっかり合意しておく必要があります。…が、現代のプログラムは契約書で責任分掌がはっきりできるほど単純なものではないので、けっこう揉めることは多いです。大きなコミュニケーション能力が必要とされます。

会社によるかもしれませんが、求人応募者に対してそれほど技術的な点を深く求める会社は多くないように思います。開発未経験でも学歴を見て採用が決まる場合は多いと感じます。

受託開発会社は、社員がほぼエンジニアで構成されるため、知識が共有しやすく、能力による給与評価や昇格も制度が固まっていて、フラットに行われやすいように思います。

自社開発・受託開発 どちらが良いか

個人的には、断然自社開発をおすすめします。業務課題を社内のチームで共有し、みんなで解決策を考え、開発したサービスが顧客体験に直接影響し、会社の売上につながっていく様子を間近で見れることは、エンジニアにとって大きなモチベーションとなります。これこそが、開発をしていて楽しいと思う瞬間です。

ただし、会社によっては開発チームの技術が停滞していたり、経営層が開発チームに十分なコストを投資しない場合があり、そのような会社で開発者を続けていくのはかけがえのない人生を棒に振ることになりますので、十分考慮して判断するようにしてください。

アプリケーション(プログラム)開発とは何か

新しい価値の提供

今まで全く存在しなかった価値を、エンジニアは作り出すことができます。ゲームによるエンターテイメント体験、SNSによる承認欲求の充足、動画投稿サイトでの顧客間での放送、動画ミーティング、顧客間での商取引サービス…昨今台頭した強い新体験を持つサービスは、アプリケーションエンジニアリングの賜物です。これらのサービスは、スマートフォンやPCなどあればどこでも利用できるため、使用者は金銭的にも時間的にも、心理的にも安価に体験を得ることができます。スマートフォン含め、最近の情報機器もサービスも、どこかの会社のエンジニアとボランティアのエンジニアの協力により成り立っています。

雇用コストの削減

例えばECサイトで商品を販売することで利益を上げている会社の場合、接客・商品の販売・代金の回収 すべをプログラムで処理します。おそらく、商品の在庫管理、発注、会計処理などもプログラムが行っています。このプログラムは、会社の業務フローそのものです。エンジニアは、この「会社の業務フローそのもの」をメンテナンスする仕事です。

現代の業務フローは、大量のデータをルールに沿って自動的に処理するために、プログラムによる自動化が必須です。自動処理を構築しない場合、その分余計な人件費がかかることになります。

雇用の賃金が上がり、労働の自由度が増すことで労働者が働きやすくなるほど、経営者は人を雇いにくくなります。また、情報処理はより複雑化しながらも、PCは高性能化し利便性が高くなったことで、知識が乏しい人が誤った情報の使い方をした場合、指先ひとつで会社を終わらせるような情報漏洩被害に発展する場合も考えられます。日々、それを誘発するような攻撃を仕掛け続けている人もたくさんいます。現代において、人を雇用するというのは大きなコストとリスクを負うことになります。

会社にとって、同じ経常利益を上げるとしたら、人は少ないほうが絶対に有利です。人が行う処理をプログラムにすることで、雇用という大きなコストとリスクを回避できます。
プログラム開発者は、人が行っている業務フローを自動化し、人がいなくても(採用しなくても)機械を使うことで自動的に大量の情報処理ができる組織を構築することができます。
究極的には、人的労働力をほぼかけずに商品を販売し続けるサービスを、全業種の中で唯一エンジニアは作ることができます。

コンビニは、店舗のマネージャーが業務フローマニュアルを使ってアルバイトの店員をマネジメントすることで商品を販売します。ECサイトの開発者は、人を使わず機械をマネジメントすることで、商品を販売します。そのマネジメントするための業務フローを記述したものが、プログラムというわけです。

今後の雇用情勢

エンジニアは、雇用する人数を減らすことのできる唯一の職種といえます。現在、色々な会社で業務フローは高度にプログラムにより自動化されていってます。エンジニアは業務フローを自動化でき、雇用を削減できる職種として、会社経営者から強く求められており、人類の理想とするAIが誕生するまでこの情勢は変わらないと考えます。プログラム開発を仕事にして、前線を走り続けることで、仕事に困ることは無いでしょう。

開発者の担当領域による分類

ゲーム開発者

現代では、Unity や Unreal Engine 等ゲームエンジンを使ってゲームを開発する人です。
私は専門外なので割愛します。

組み込み/IoT エンジニア

家電や自動車制御プロセッサ、自動販売機、デジタル看板、ルーターやLANハブなどのプログラムを開発する人です。
基本は C++ や Java だと思いますが、最近は開発環境の進歩により、 C#, JavaScript, Python などでも開発できます。
私は専門外なので割愛します。

Webアプリケーションエンジニア

ネットワークを介して処理をするアプリケーションを作るエンジニアです。
基本的にはブラウザ上で動くアプリケーションを作ります。

現代は様々なものがネットワークにつながるようになっており、家電もネットにつながったりしますし、スマホにインストールするモバイルアプリも大抵はネットワークを介してサーバと通信することで機能を提供します。そのサーバサイドを作るエンジニアでもあります。

アプリケーションエンジニアになるには

まず、全くの未経験であれば、教則サイト ( Progate, PyQ 等) の有料会員になって、最後まで進めましょう。最初はモチベーションが上がらずに、苦痛を感じるかもしれませんが、最後まですすめてください。教則サイトは誰にでもわかるように一つ一つ丁寧に教えてくれます。もし、教則サイトで知識的に躓くようであれば、エンジニアに向いてないように思います。幼稚すぎてだるい、と感じるようであればちょうど良いです。

10年前であれば、有名な本を買ってそこから学ぶのが効果的だったと思いますが、今は親切丁寧に解説してくれる教則サイトがいくつもサービスされていますので、便利に使いましょう。

教則サイトを一通り終わらせることができれば、おそらくプログラムとは何なのかが体感できたはずです。次は、自分の生活の中で困ったことを開発で解決させてください。

例えば、PCを使っている時に、自動的にフォルダ内の全ファイルをリネームしたいとか。ネット上に散らばっている画像を自動的に収集したいとか。クリップボードにコピーした文字列を自動的に整形してどこかに共有したいとか。自分の所属するサークルやクラブのための情報共有ツールを作りたいとか、スコアを統計したいとか。まわりを見渡すと、アプリケーションエンジニアリングで解決できそうなことが山ほどあるはずです。

ひとつづつ、手をつけていきましょう。おそらく、なんとなくロジックはわかるけどどういうプラットフォーム上でプログラムを動かしたらいいかわからない、という状態になるのでは無いでしょうか。

テキスト処理や計算処理をするだけなら、HTML + JavaScript だけで解決できる場合もあります。

計算するだけなら、 Google Colaboratory で十分かもしれません。

スプレッドシートやメールを自動処理するなら、Google Apps Script が良いでしょう。

Mac でファイルに対して自動処理を処理したいなら、ターミナルで動くテキストベースのアプリケーションスクリプトを書きましょう。最初は Python か Node.js がおすすめです。

Apple や Google の App Store に並んでいるような綺麗でかっこいいアプリを作る必要はありません。まずは、自分の身の回りのことを、自分でコードを書いて自動化していってください。技術がついていかず、途中で開発が詰まることはよくあると思いますが、考えてもわからないものは一旦放置して、別の問題を解決するコードを書いてください。

できたコードは Github に プライベートリポジトリにして保存しておきましょう。もし、公開してもセキュリティ的に絶対大丈夫だと自信があるものだけ、パブリックリポジトリにして上げてください。

多くのコードを自分で書かなければいけないわけではありません。誰かが作ってくれている、素晴らしく便利なものをうまく組み合わせて、自分の課題を楽に解決してください。会社内のエンジニアの仕事というのは、いつもこの延長です。有料のサービスも、無理のない範囲でどんどん使いましょう。機械的な動きや計測が求められるラズベリーパイやスイッチボットなども買って使ってみましょう。

慣れてきたら、Webサイトを作成しサービスしてください。最初は自分のポートフォリオやブログ だったり、自分の趣味研究の成果の公開、またはサークル・クラブのサイトを作るのが、モチベーションを高く保てて良いと思います。ログイン機能を提供するなど個人情報を扱う場合は十分注意し、絶対に自作はせず、認証サービス ( Firebase, Cognito, Auth0等 )を使うか Webアプリケーションフレームワーク(Django, Rails, Laravel等) を必ず使うようにしてください。

あとは、自分の思想とあっている会社を見つけて採用応募し、「自分が今までどういったことを自動化してきたのか」を丁寧に説明してください。その自動化の成果や方針が会社の思想とマッチしていれば、会社組織の一員として安定したエンジニアリング人生をやっていけます。

フリーランスでやっていくのは、他のエンジニアと良好な人間関係を構築するのにひとつ壁があるため、あまりおすすめしません。ビジネスに共感を持った会社の、正社員として採用されることが、エンジニアとしての人生を豊かにすると、私は考えています。

アプリケーションエンジニアとして生きること

アプリケーションエンジニアは、人間の職業のひとつの極限だと感じています。アスリート、漫画家、数学者、棋士、芸術家などと同様に、「十分な域に達するには一生分の時間では到底足りない」職業です。課題や習得することは無数にあり、一生…60年ほどを使っても、全ノウハウの1%も習得できないでしょう。そのため、自分に合ったスタイルを取捨選択し、日々自分の技術を磨き続ける人生になります。毎日が新しい挑戦の連続で、毎日限界まで頭脳を使い、自分の能力の低さを痛感し、何度も停滞し、何度も失敗します。しかし課題解決をした時のリターンが予想しやすく、かつ経済的な価値が大きいものである場合が多いため、他の業種より安定した生活が継続してできるでしょう。

エンジニアが新しい価値を作り、何かを自動化するということは、おそらくその時点で既存のビジネス(業務) の価値を下げ、いくらかの人への報酬を奪うことになり、エンジニアリングをする人としない人で格差ができます。その社会は20世紀後半から既に始まっています。

もし、あなたがアプリケーションエンジニアになろうと思っているのであれば、先輩として応援します。アプリ開発はめちゃめちゃ面白い上に、人から必要とされます。自分では、今まで開発者をやってきてよかったと思いますし、あなたも10年後、間違いなくそう思います。

特にここ40年は、電子計算が飛躍的に向上し、インターネットが一般化した、人間史の中で一番面白い時期であることは間違いありません。そしてこれからも、量子計算の一般化やシンギュラリティ、人工生命の誕生など従来の人間の価値観が覆るイベントが目白押しです。その転換期に立ち会えることができてよかったと思っています。

新入社員が入社後数ヶ月でコミックリーダーアプリのレビュースコアを 1.4 → 4.7 に改善した話

はじめに

この記事は株式会社TORICO Advent Calendar 2021 の7日目の記事です。

こんにちは!開発部の三枝です。

やや誇張気味なタイトルのようでもありますが、「新入社員が入社後数ヶ月でコミックリーダーアプリのレビュースコアを 1.4 → 4.7 に改善した話」とし、2021 年末のアドベントカレンダーの一記事として投稿します。

同僚の Flutter エンジニアが、同じアドベントカレンダーの記事「Flutter でECアプリを新規開発してみて」で、弊社の別の Flutter 製の EC アプリの新規開発の過程や選定技術・アーキテクチャについて書いているので、そのような話題についてはぜひそちらの記事もご覧ください。

この記事では、新入社員だった私がどのようにコミックリーダーアプリの開発タスクに関わったかに触れながら、TORICO の開発体制や環境の魅力や楽しさも伝えられたら良いなと思います。

MZ Reader review score before after


私は 2021 年 3 月に Flutter エンジニアとして TORICO に入社しました。以前はヨーロッパの自動車産業系の会社で機械振動の解析の研究に従事したり、医療業界を対象にした SaaS のサービスを開発する会社に勤めたりしており、漫画やエンタメ業界については知らないことばかりだったので、入社して最初に驚いたのは、毎日たくさんの漫画が購入され日本中・世界中の多くの人々に楽しまれているということです。

電子コンテンツについても同様で、弊社のコミックリーダーアプリ「MZ Reader」でも漫画を読むのを楽しむことができます。

入社前の面接のときから、この MZ Reader の開発を担当することになるのは聞いており、新規開発したい機能があることも聞いていました。

本棚機能の開発

弊社の提供するコミックリーダーアプリは、それまで他社製のものを提供していたものを、Flutter を用いて社内で開発された MZ Reader がリプレイスする形でリリースされたものだと聞いています。MZ Reader ではじめに提供すべき機能を選定する際に、以前のコミックリーダーアプリにはあった「本棚機能」を削ることにした結果、それが想像以上にお客様に重宝されていたこともあり、レビューのスコアが 1.4 と悪化してしまっていました。

「本棚機能」とは、私たちが紙の本を本棚のスペースごとに区切って整理するように、お客様が購入済みの書籍をアプリ内で自分の好きなように分類するような機能です。YouTube や Spotify などの動画・音楽のストリーミングアプリで、プレイリストとして、同ジャンルや好きなコンテンツを集めて整理する機能に似ています。

お客様のレビューの内容を見てみると、Flutter 製の新たな MZ Reader をシンプルで良くなったと言って下さる方もいる一方で、やはり自分好みに書籍を整理するための「本棚機能」がなくなって使いづらくなったという意見を仰る方がいました。

そこで、入社後少ししてから初めての中規模程度以上の開発タスクとして、本棚機能の開発にアサインされました。

開発タスクの主な内容

上で述べたような「本棚機能」の開発タスクとは、単に Flutter のクライアントアプリにその機能を実装するだけではありませんでした。入社前から聞いていましたが、弊社の開発部では、モバイルアプリ、Web クライアントサイド、Web サーバサイドのエンジニアといった明確な区別や役割分担はありません。メンバーや領域によって経験や習熟度の違いはあれど、いろいろなタスクを皆で協力しながら進めています。

たとえば、入社直後には、会社のビジネスの主な流れや、サービスに関するどんな情報がどんなテーブルに保存されていて、他のどんなテーブルを参照しているのか、ソースコードのどこにどんなロジックが書かれているかなど、何が何だか全く分からなかった状態から、お客様からの注文に関する問い合わせや、電子コンテンツのデータの不整合の確認、運営チームからの突発的なビジネスデータの集計依頼なども、少しずつ対応できることが増えていきました。

はじめは先輩や同僚がそのような対応をしているのを横で見ることしかできずに歯がゆい思いもしていましたが、時には分からないことを尋ねて必要なサポートをしてもらいながら馴染んでいくことができる環境です。

さて、コミックリーダーアプリの「本棚機能」の話に戻りますが、上で述べたような何でも挑戦していく弊社の開発チームの環境では

  • Flutter のクライアントアプリに本棚機能を実装する
  • 本棚機能に関わる Django の API を実装する。その際、本棚機能に関する全く新しいテーブルをいくつか DB に追加する
  • Web 版漫画全巻ドットコムのマイページに、同等の本棚機能を Nuxt.js で実装する

というのが「本棚機能」の開発タスクに含まれました。

Flutter, Dart 以外にも Python 言語自体には多少の経験はありましたが、業務レベルで Django (Django REST framework) によるサーバサイドの開発をすることも、Nuxt.js や TypeScript を書くことも初めてだったので当初は不安もありつつも、なんとか最後までやりきることができました。

開発の流れ

MZ Reader は購入した書籍をオフラインでも読めるコミックリーダーアプリなので、「本棚機能」は、それぞれのユーザーの本棚(プレイリスト)は Django の API を通じて作成・保存・更新しつつも、その本棚情報の API のレスポンスを元に、Flutter で SQLite を扱う sqflite とその ORM である sqfentity を用いてローカルストレージに保存することで、オフラインでも動作するよう実装する必要がありました。

前に述べた通りの理由で、Django の API の実装には時間がかかると判断し、まずはローカルストレージだけで、Flutter のクライアントアプリで本棚機能が動作するように実装をしました。

冒頭で紹介した記事の EC アプリと異なり、ある程度の規模の Flutter アプリの状態管理の定番が Provider (Riverpod) + StateNotifier + freezed に収斂されていくような昨今の流れ(異論もあるかもしれませんが...)が出てくる随分前から開発されていた MZ Reader は、かっちりとした特定のアーキテクチャを採用している訳でもなく、シンプルな MVVM + Store パターンといったところですが、登場するレイヤーが少なく新しく入った私にもキャッチアップしやすい内容でした。一長一短ではあるでしょうが、何でも流行りの方法でやるべきだ、みたいな開発上の前提がそれほどないことや、ビジネスの成功のためのアプリや Web サービスだという前提(上司である部長がよく言っているので心に残っています)が浸透しているように思えるのも、TORICO の開発チームの好きなところです。

Flutter アプリのオフライン機能としてある程度動作するようになった後は、Django の API の実装に進みました。「本棚」と「本棚に保存した本」という機能を実現するために、「本棚」に相当するテーブルと、「本棚」とユーザーの購入済みの書籍(ある「本棚」には複数の書籍が紐付けられるし、ある書籍は複数の「本棚」に属して良いので N 対 N の関係)を結びつける「本棚内書籍アイテム」といった意味合いの中間テーブルと、それらに対応するモデルを新規作成して、本棚を作成・編集・削除・並び替えするような API と本棚に書籍を追加・削除・一括追加・一括削除するような API を、Django の APIView や ModelViewSet を継承したクラスに実装していき、それぞれのユニットテストの記述まで済ませました。

その後は、Flutter アプリからそれらの API をコールし、必要なレスポンスを端末の DB に保存していく実装を済ませて、ようやく Flutter アプリに「本棚機能」を実装することができました。ここまでで一ヶ月半ほどかかったと記憶していますが、多くの学びがあった貴重な機会だったと思います。

その間の週末や退社後の趣味の時間に Nuxt.js や TypeScript を触って遊んでいたので思ったよりはスムーズに、それでも 2〜3 週間ほどかかりましたが、Web 版漫画全巻ドットコムのマイページに同等の本棚機能を実装を済ませて、一通りのタスクを完了させました。

心に残っていること

Flutter の開発以外にも、入社前にはほとんど経験のなかったことを含めて色々な学びがあった「本棚機能」の開発は、入社後に任せてもらった最初のタスクで良かったなと思っていますが、他にも心に残っていることがあります。

というのは「本棚機能」全体に比べると細かい話にはなるのですが、コミックリーダーアプリで「本棚」に追加する書籍を選択する際のアニメーションに関するものです。「本棚」に追加する書籍を複数選択するために、対象書籍を長押しすると、iOS の写真アプリの選択モードのように、選択された書影に薄暗い影がついた上で、書影の隅に丸囲みのチェックマークがつくような UI を実装していました。ちなみに弊社にはアプリケーションの見た目に関するイニシアティブを取るデザイナーのような役割はいないので、クライアントアプリの開発者が自主的に提案しつつ他の開発者や運営チームと議論し合意を図るようになっており、やはり、単に仕様通りに機能を実装する以上の自主性が求められますし、良い意見であればそれが尊重されます。

それを Flutter アプリの開発レビューをしてもらっていた開発本部長 (CTO) に見せてみると「ちょっとで良いから...。なんか... もっと色気がほしいな」といった趣旨のフィードバックを受けたのです。

明確に不可ということはないだろうとは思っていましたが、聞いた瞬間「色気を求めらるとは!」と少し驚き、その数秒後にはすごく納得したのをよく覚えています。

TORICO は「世界に『楽しみ』を増やす」をミッションとしています。

コミックリーダーアプリにせっかく実装した「本棚機能」はなるべく多くのお客様に、便利に、そして楽しく使ってもらいたいものです。実装にかかった工数は Django の各種 API の方がよっぽど多いのですし、Flutter の Animated Widget のひとつを使用したたった数行の内容ですが、「色気がほしい」というフィードバックと一緒にもらったアドバイスをもとに、書籍を複数選択する際の、波紋を出しつつ、コインが裏返るようアニメーションでチェックマークが付く(つまり丸囲みのチェックマークの幅方向に長さ 0〜直径のアニメーション)機能は個人的に気に入っていますし、そのお陰で少しでも多く・楽しくお客様に「本棚機能」が使用されていたらな、と思っています。

その後

「本棚機能」が少しずつ使用され始め、アプリのその他の機能も改善されたり安定化されたりしたというタイミングでレビュースコアの改善施策にも取り組んだこともあり、タイトルのように、2021年12月20日時点で、iOS の App Store では 349 件の平均レビュースコアが 4.7 まで回復しました。

また、「本棚機能」のタスクが済んだ後は、ますます Django や Nuxt.js の開発タスクに従事する機会が増えて、いまでは業務中は毎日 Django, Python に多くの時間を割いています(一応アイデンティティは Flutter エンジニアのつもりなので、業務後や週末の趣味や個人開発の時間では、毎日欠かさず Flutter と Dart を書いて、最新の SDK バージョンにもキャッチアップしています)。

先日 Web 版漫画全巻ドットコムのサービスについて、カート機能や決済機能の比較的規模の大きいリニューアルがあったのですが、その決済手段のひとつの Django での実装を主に担当するなど、まだまだ他の同僚や先輩のように素早いスピードで開発をどんどん進められないことには自信を持てないところがあるものの、入社した頃よりはできることことも増えたなと実感していますし、そのような環境で働かせて下さっている上司やチームの皆さんには感謝の気持ちでいっぱいです。

最後に

技術ブログというよりは、新入社員のエンジニアが TORICO の開発チームに馴染んでいったか、その中で印象に残っていることや、新入社員だった私にとって TORICO の開発チームや環境がどのようなものに映っていたか、といった内容にフォーカスした記事となりました。

弊社のサービスや開発チームに興味をもって下さる方の参考になれば幸いです。

ありがとうございました!

若手アプリケーションエンジニア(プログラマ)に読んでほしい本

主に私の会社 TORICO の若いアプリケーションエンジニア(プログラマ)や、部下・チームを持ったエンジニアに読んでほしい本をリストアップしました。

若手アプリケーションエンジニアに読んでほしい本

リーダブルコード : より良いコードを書くためのシンプルで実践的なテクニック

読みやすいコードの書き方が学べます。必ず読んでください。

版元ドットコムで見る

プリンシプルオブプログラミング

名著の総集編・いいとこ取りの本です。

版元ドットコムで見る

UNIXという考え方

コマンドラインツールの設計思想について書かれています。

版元ドットコムで見る

達人プログラマー(第2版)

ソフトウェアエンジニアを業務とする上での哲学書。タツプロ。

版元ドットコムで見る

コードコンプリート 第2版

具体的なプログラミングテクニックの本。上下巻になっていてそこそこ高いので余裕があれば。

版元ドットコム 上 

エキスパートPythonプログラミング 改訂3版

Python入門書。エキパイ。Python で業務コードを書く時に読んでおいてください。

版元ドットコムで見る

Pythonプロフェッショナルプログラミング第3版

より実践的な Python と周辺ツールの紹介。

版元ドットコムで見る

執筆者のビープラウド社は Python の Eラーニングも手頃な値段でサービスしているのでそちらもチェック。PyQ

実践ハイパフォーマンスMySQL 第3版

MySQL は業務でかなり使います。新規機能を設計する上で必須の知識が学べます。甘いクエリを発行してのサービス障害を防ぐためにも、十分学習してください。

版元ドットコムで見る

SQLアンチパターン

SQL を設計する上でやってはいけないことを紹介しています。アラフォーエンジニアが読むと、「過去の現場であったわー」ってなって盛り上がれます。

版元ドットコムで見る

体系的に学ぶ 安全なWebアプリケーションの作り方 第2版

Webセキュリティを一通り網羅しています。とくまる本。

詳説正規表現

正規表現も、本で体系的に学ぶのが一番早いと思います。この本一冊読んでおけばOK。

版元ドットコムで見る

暗号技術入門 : 秘密の国のアリス

暗号の入門書。

版元ドットコムで見る

世界でもっとも強力な9のアルゴリズム

ソフトウェアエンジニアリングのエポックメイキングの歴史書。

版元ドットコムで見る

部下やチームを持った人に読んでほしい本

エンジニアリング組織論への招待 : 不確実性に向き合う思考と組織のリファクタリング

版元ドットコムで見る

Think CIVILITY 「礼儀正しさ」こそ最強の生存戦略である

版元ドットコムで見る

GREAT BOSS

遠慮せず本音を言え、という本。

版元ドットコムで見る

ゆとりの法則 : 誰も書かなかったプロジェクト管理の誤解

英題 Slack ですが アプリの Slack とは関係ありません。ゆとり世代とも関係ありません。仕事にはリラックスが必要という本です。

版元ドットコムで見る

ソフトウェア・ファースト

版元ドットコムで見る

図解 ドラッカーがわかる本

廉価版のコンビニ本ですが、内容がわかりやすくすぐ読めて実りあるものだったので紹介。紙は絶版だと思いますが、電子書籍ならすぐ読めます。Kindleで見る

版元ドットコムで見る

デザイン/DTP もたまにする人に

ソシム社の3部作が、時代をとらえていてサンプルも豊富でコンセプトも良く、役に立ちます。

ほんとに、フォント。

Amazon で見る

あたらしい、あしらい。

版元ドットコムで見る

けっきょく、よはく。

版元ドットコムで見る

人生・哲学・啓発

好き嫌いはあると思いますし必読ではありませんが、個人的なおすすめ。

あなたの知らない脳

無意識の解説と鍛え方など。非常に有用でした。

版元ドットコムで見る

嫌われる勇気

私の人生においては非常に有用でした。コンセプトも上手で読みやすい。物語形式です。

版元ドットコムで見る

幸せになる勇気

嫌われる勇気の続編。出だしから登場人物の荒ぶり方が面白い。

版元ドットコムで見る

哲学的な何か、あと科学とか

著者の飲茶さんのブログが好きで昔から見ていたのですが、その内容の書籍化。哲学の入門書。

版元ドットコムで見る

哲学的な何か、あと数学とか

上記作者の別の本。

版元ドットコムで見る

ゾーンに入る技術

集中するのは大事、という本。今になって思うとそれほど重要な本では無いと思うのですが、当時読んだ時は影響を受け、私の人格形成の一部となっていると感じているため一応掲載します。

Amazon で見る

趣味の物理本

最後に趣味本の紹介をします。読んだ中でも面白かったもの。仕事には一切関係ありません。

隠れていた宇宙 上下

版元ドットコムで見る 上

量子コンピュータ (ブルーバックス)

量子コンピュータ解説書の中で一番おもしろかったのはブルーバックスのもの。だけど今読んでみると内容は古い感じがしますね。

版元ドットコムで見る

量子計算ロジックの解説はみんなの量子コンピュータがわかりやすく書かれていると思います。全然理解できませんが。

宇宙に外側はあるか

版元ドットコムで見る

日経BP社「世界でもっとも美しい〜」シリーズ

世界でもっとも美しい10の科学実験

もうひとつの「世界でもっとも美しい10の科学実験」

世界でもっとも美しい10の物理方程式

世界でもっとも美しい量子物理の物語

強い力と弱い力 : ヒッグス粒子が宇宙にかけた魔法を解く

著者の大栗博司さんの本はどれも面白いです。同じ幻冬舎から重力の本「重力とは何か」も出されています。

ブルーバックスでも「大栗先生の超弦理論入門」を出されています。一部内容が重複する所はありますが、どれも、今読んでも面白いです。

四次元の世界

新装版が出てました。なかなか読まれているんですかね。四次元の具体化に良い参考になると思います。

版元ドットコムで見る

PyCharm, WebStorm, PHPStorm など JetBrains エディタで必須で覚えるショートカット・機能

TORICOでは、開発者のエディタは JetBrains のもの (PyCharm, WebStorm, PHPStorm ) を使うことにしています。今回、最初に必ず覚えたいショートカット・機能を紹介します。

かなり使うキーボードショートカット

Shift 2回 なんでも検索 (神検索)

Shift をダブルクリック なんでも検索ができます。クラス、ファイル、関数などなんでも検索できます。

Shift 2回のあとさらに Shift2回 (つまり Shift4回) で、プロジェクト外のファイル ( Django や Vue などの依存ライブラリのコード)も対象に検索します。

このなんでも検索時、ファイルパスの末尾に :行数 が入っている場合、例えば auth/index.html:20 のような文字列で検索した場合、検索該当結果を開いた時その行がすぐに表示されるため、スタックトレースのログから該当箇所を開きたいとき重宝します。行数ごとコピーしてそれで検索すれば一発で見たい行が表示されます。

そのほかの検索

調べる対象が絞り込めている場合は、特定のカテゴリで検索したほうが検索結果を絞り込めるため見やすいです。

⌘+O … クラス名で検索

⌘+Shift+O … ファイル名で検索

⌘+Shift+F … ファイルの中身で検索

複数のファイル(プロジェクトに含まれる全ファイルや、特定のディレクトリ以下のファイル)から、内容にマッチするものを検索します。

⌘+Shift+A … アクション検索

エディタの機能を検索できます。ショートカットキーを忘れた時のチートシートとしても使えます。いくつかの設定項目の変更も、このショートカットから行えます。

⌘+[ … 戻る

コードの関数実行箇所などで ⌘+クリック することで定義にジャンプして、コードを読み進めていきますが、そのナビゲーションを戻る時に使います。ブラウザで戻るようにコードを戻ることができます。おそらく、マウスを使っている場合は戻るボタン(第4ボタン)がそのまま使えるはずです。

Control+Tab … スイッチャー

ブラウザのタブ切り替えと同じショートカットキーになっているはずです。

押し方によっていくつかの使い方があります。

Control を押しながら Tab を押してすぐに両方離す と、「1つ前に編集していたファイル(タブ)」に戻ります。⌘+[ の「戻る」とは違い、ファイル単位での行き来しかできません。

連続で押すことで、2うのファイルを交互に見比べられます。

このショートカットでファイルを切り替えた場合は戻るスタックに積まれるため、さきほどの ⌘+[ の戻るショートカットで戻れます。

Control を押しながら Tab を2回押すことで2つ前のファイルに戻れます。

閉じてしまったタブには移動できません。

Control を押しながら、Tab を押して離し、Control は押しっぱなしにする にすることで、Switcher が開きっぱなしになります。右側のペインにはタブ一覧が表示され、左側のペインには ウインドウが一覧表示されるので、直接クリックして選択したり、ショートカットキー(⌘+数字)を確認するチートシートとしても使うことができます。

このショートカットキーはJISキーボードではめっちゃ押しやすいのですが、USキーボードだと少し押しにくいので、Macの設定で Caps Lock キーをControl にしてしまうのがおすすめです。とにかく押しやすいため、タイピングが得意でなくても、キーボードを見なくてもミスらないという利点がありますので、積極的に使ってほしいです。

⌘+E … 最近使ったファイル

さきほどの Switcher と似ていますが、こちらはキーを放しても閉じません。なので、「最近使ったけど何個前に使ったかは覚えていない」ファイルであれば、このショートカットで一覧から探す。明確に 1つ(もしくは2)前に使った、と理解しているファイルであれば Control+Tab の Switcher で切り替えると良いでしょう。

タブを閉じてしまったファイルを選択した場合、新たにエディタタブで開いて表示します。

⌘ を押しながら、E を2回押す と、最近修正したファイルに絞って表示します。

⌘+Option+L … コードの整形

設定した整形ルールに応じてコードを整形します。

プロジェクトルートに .editorconfig がある場合、その内容に従ってフォーマットします。

あくまで簡易的なものとわりきり、本格的なコードのフォーマットは別途ファイルの保存時に行ったほうが良いです。

TypeScript なら eslint --fix (設定の ESlint 内にチェックボックスがある), Python なら autopep8 (file watcher  で), PHP なら csfixer (file watcherで) をファイル保存時に自動整形をかけることが簡単にできるので、設定してください。

⌘+Shift+N … New Scratch File

新しいスクラッチファイルを作ります。スクラッチファイルとは、プロジェクトに含めないメモ的なファイルを瞬時に作れる機能です。

新しい Python や TypeScript ファイルを作って即時実行させたり、SQLファイルを作ってDBを検索したりできます。中でも便利なのが、http 入力することで出てくる HTTP Request ファイルで、Postman ほど高機能ではないですが、簡単な HTTP リクエストをスクリプト化して実行できます。ターミナルから curl コマンドを実行するより簡単でパラメータも読みやすく、ログも残るため使い勝手が良いです。

開発環境を Docker で構築している場合、Python ファイル等を実行する場合はスクラッチファイルのディレクトリを Docker でマウントしてパスマッピングを設定することで実行できます。

HTTPリクエストファイルの解説記事

pleiades.io の翻訳記事: IntelliJ IDEA コードエディターの HTTP クライアント

私が前に書いた Qiita 記事: .http で簡単HTTPテストリクエスト

ショートカットキーでは使わないけど便利な機能

Find Usages

指定したワードの出現箇所を検索して表示します。ショートカットキーはデフォルトで設定されていますが、Option+F7 と若干複雑なため、もっぱら右クリック(二本指タップ)→コンテキストメニューから Find Usages を選択することが多いです。

リファクタリングする際、メソッドがどこで使われているか、とか、クラスをどこで継承しているかを調べる時によく使います。

Select Opened File

Project ウインドウの中にある、ライフル銃のスコープをモチーフとしたボタンです。押すことで、今エディタで開いているファイルをProject ウインドウの中心に持ってきます。検索や ⌘+クリックで掘り進んでいったファイルがどこにあるかを調べたり、その周りのファイルを読む時に使います。

Open In Github

エディタで該当行をドラッグして選択→二本指タップ(コンテキストメニュー)→ Open In → Github

すると、ブラウザが起動し指定行が Github で表示されます。

URL を Slack で他のメンバーに送ることで、課題箇所の共有ができます。

Enter Presentation Mode

部門会議などで共有スクリーンにコードを表示する時は、

View -> Appearance -> Enter Presentation Mode を行うと、コードが大きな文字で表示され、コードレビューがしやすくなります。

デバッガの「Evaluate Expression」

エディタでブレイクポイントを設定し、ブレイクさせた時にデバッガウインドウが表示されます。
このデバッガウインドウの上部に、電卓のようなボタンがあり、これを押すと小さなウインドウ (Evaluate ウインドウ) が表示されます。

Evaluate ウインドウの中の、Expression フィールドの中に Python のコードを書くと、それが評価されて Result に結果が表示されます。単純に変数の中身を見たり、メソッドのリターンを確認したりと重宝します。

デバッガの Pythonコンソール

ブレイク中に、デバッガウインドウ内にある Python ロゴボタンを押すと、Python コンソールが起動してデバッグプロセスにアタッチされた状態になります。

できることとしては、先程の Evaluate Expression とほぼ同じなのですが、こちらは Python の対話コンソール上で評価されるので、不足している import を実行したり、関数を定義したりもできます。 Evaluate Expression と合わせてデバッグ時には必須の機能なので、活用していきましょう。

Alfred から プロジェクトを開く

Alfred から プロジェクトを横断的に検索して開けると便利だと思ってるのですが、Alfred 内から JetBrains のプロジェクトを横断的に検索できるワークフローは、期待通り動くものが現状無く、作るのも難しそうです。

ただし、単純に何かのホットキー(例: Control + ⌘ + スペース ) で JetBrains Toolbox を起動するようにすると、起動した瞬間にプロジェクト横断検索のテキスト入力にフォーカスが移動するため、そのままキーボードでプロジェクトを検索して開けるので便利です。

関連記事

以前に、エディタの複数行同時編集の記事も書いているので参考にしてください。

テキストエディターの複数行同時編集で仕事がはかどる

仕事をスケジュールに沿って進捗させるために「完了」の条件をチームで共有する

開発者は、日々進行する業務を「タスク」や「課題」「イシュー」という単位にして、管理します。

ディレクションチームから、新たな機能開発の課題が生まれた時、それを課題トラッキングツールに作り、完了になるまでその業務をすすめていくことになりますが、この時ディレクションチームと開発チームで「完了」状態のイメージを揃えておかないと、この課題だけではなく、その次の課題の進捗にも遅延が発生します。お互いに、「完了」とは何かをより具体的にイメージしておくことが、開発をスムーズに進めることに繋がります。

「完了」とは何か

完了の定義は組織によって少しずつ変わってくるものだと思いますが、私が開発者に強くイメージしてほしい完了のイメージは、「もう作業をしなくていい状態」です。その課題に対して、もう何も考えなくてよくなったら、その課題は完了しています。

開発の進め方として

  1. 何か業務課題が見つかる
  2. 業務課題を解決させるために開発課題が生まれる
  3. コードを書いてテストする
  4. プルリクエストしてレビューする
  5. レビュー指摘箇所を直してマージする
  6. 検証環境に反映する
  7. 検証環境で動作検証し、不具合箇所の修正や調整をする
  8. 本番環境にリリースする
  9. 本番環境で動作検証する
  10. ディレクションチームに説明する

チーム編成や動作環境・開発手法の違いにより細かい所で違いはあると思いますが、おおよそこのような流れになります。

この中で、開発者は2-10まで担当することになると思います。動作検証に関しては、専用の検証チームや外注がいるかもしれませんが、検証中は開発者がのんびり待ってるわけでもなく、発見された不具合箇所の修正をしたり、サーバ側のデータを見て動作の確認をしています。

見積もりとタスク量

1. で業務課題が見つかり、2. で開発課題が生まれた時、ディレクションチームは業務課題の解決のために必要なコストの見積もりをします。コストの多くは開発時間で、開発には仕入れや材料が不要なため、単純な時間コストだけ聞く場合がほとんどです。「どれぐらいでできる?」と聞いてくるやつです。

その時、開発者は完了の状態をイメージしますが、そこでイメージするのは、多くは 3. が終了し、4. プルリクエストを出すタイミングでしょう。実際にそれで問題無い組織環境もあるかもしれませんが、TORICO や私がいままで所属していた企業では、「プルリクエスト出したら完了」とイメージするのは、関係者の考えている完了とは一致していないため、危険です。

ディレクションチームの完了条件

ディレクションチームが考える開発の完了した状態というのは、「開発成果が業務課題の改善に対して効果を発生し始める」時です。つまり、本番反映が終わりお客さんが使える状態になっている状態、ということです。

ディレクションをしている方は、開発者に「どれくらいでできる?」と聞いた時に「3日」と回答をもらったら、念の為に一度「開発着手してから3日で、お客さんが不具合なく完全に使える状態になっているか」を改めて聞いたほうが良いでしょう。開発者もそれを汲み取って、「本番環境で完全に動作する」と保証できる日程を答えなければなりません。必要以上に急いだり背伸びをする必要はな無く、大事なのは「本番環境で完璧に動作し、業務課題の改善に効果を発生している」状態を作ることです。そして、その状態にするためにどれだけの時間コストがかかるかの意識をなるべく正確に共有し、遠慮せずに伝える必要があります。

開発者の次の課題

コードを書いてプルリクエストを出した所で、開発担当者は一旦の区切りとなるため、そこまでを開発期間とイメージしがちです。わかります。実際はプルリクエストを出したら次の開発課題に着手することになると思うので、実際そうとも言えます。

ただし、次の開発課題を始めた後も、前の課題進捗は進むため、レビュー指摘箇所の直しだったり動作検証の不具合修正だったりで時間を使います。その対応を行っている時は、新しい開発課題は停止するので、新しい開発課題についても概ねのスケジュールを伝えているとしたら、遅延の原因になります。

別のタスクの開発時間を奪うような状態の課題は、「完了している」とは言えません。

そのため、「開発課題の完了」とは、その開発課題について何かを考慮することが無くなり、新しい開発課題に全力で集中できる状態をイメージすると良いでしょう。

本番環境て完全に動作する

さきほど、本番環境で完全に動作すること、ということを完了条件とする、と書きましたが、「完全に動作する」という文言に嫌悪感かある開発者もいるかもしれません。Windowsにも脆弱性があり修正パッチが月に何度も出ている、だから完全なんて保証できるものではない、という実例を話したくなるかもしれませんが、そういうことではないんです。本番リリースしたコードに不具合などのリスクがあることは、チーム全員もう知っています

そうではなく、本番リリースにあたり自分の責任範囲でやることを全部かったか?ということを考えてほしいのです。もし、そこで「本番環境特有のある条件下でのある動作が検証できておらず、不安がある」と感じているのなら、検証するかチームに共有してください。リスクと時間を考慮して、チーム全体で対応策を考えられます。それらの細かい残件の対応を行い、もう確認すべき所は無い状態になり、「残課題はありません」と胸を張って言える状態が、もう作業をしなくていい状態であり、完全に動作する(かもしれない)状態です。機能リリースにはリスクがあり、不安があるかもしれませんが、検証を十分にやっているなら、具体的な理由のない不安は考えるだけ時間の無駄です。ダメな所がなければOKです。気にせず早くリリースしましょう。

実際のタイム感

おおよそですが、ウェブサービスの開発の場合は、プルリクエストを行うまでが、実際の開発進捗の半分ぐらいのイメージで良いと思います。コードを書きはじめて、プルリクエストまで3日だったら、検証と調整と本番リリースであと3日ぐらいかかる感覚です。

逆に、リリースしたい日がすでに決まっているのであれば、開発着手からリリース日までの半分のあたりで、一通りコードが書き終わってないといけません。リリース直前にコードが書き終わるイメージをしているのであれば、その開発課題のリリースは遅延します。

予定通りに完了できなさそうな時どうするか

完了タイミングを関係者に伝えているにもかかわらず、予定通りに計画が進まずに、進捗が遅延しそうな時はよくあります。

特にアプリケーション開発は、予期しない計算(計画)の連続であり、現代のアプリケーション開発で開発終了時刻を正確に見積もることは、正直に言うなら困難です。

現代のアプリケーション開発は、業務が十分に抽象化(自動化)されている現場であれば、作業時間を見積もれるような定形作業はまずありません。

もし、開発作業内に定形作業があるとすれば、それはロボット(スクリプト)にやらせることだからです。

アプリケーション開発というのは、誰もやっていない新しい課題への挑戦です。具体的には、他の開発者が開発したコードを目的のために計算して組み合わせ、求める計算結果を出させ、それを出力し記録する。というのがおおまかな流れです。他の開発者が開発したコードが、今求めているビジネス領域にどれぐらいマッチするかは誰もやったことが無く誰にもわからないため、未来に発生するトラブルを事前に知ることは不可能です。それどころか、ビジネス課題を解決するプロダクトの完成イメージさえ、開発着手時には十分決まっているわけではありません。コードを書いて、動作をチーム全員で試してから、ブラッシュアップしていくのが現代のアプリケーション開発です。

アプリケーション開発が実際にどのようなものか、未経験者に伝えることは難しいですが、例えば問題集のようなものだと考えています。達成するには全問正解する必要がありますが、問題集を開くまでは中にどのような問題が書かれているかはわからず、設問自体が自分の理解できる言語で書かれていない可能性もあります。ただし、問題集の厚みだけは見えます。その問題集を全問正解するまでの時間を、開発者は毎回見積もります。なので、見積もりはけっこうテキトーですし、楽観的に答えがちな人、悲観的に答えがちな人など、答え方に個性も出ます。(もし、それと似た問題集を解いたことがあるようであれば、似た問題集を全問正解するための見積もりはしやすでしょう。)

アプリケーション開発は、実際に書き始めてみないと難易度を理解するのは難しいため、開発途中で未知のトラブルに遭遇したり、方針の変更により、予定通り完了できない時もよくあります。

長期の開発案件でプロジェクトが予定通り進んでおらず、途中から助っ人を追加するとしたら、追加する人をよく考えて選ばないといけません。作業者より上位の人(部署リーダー等)であれば、大抵はうまくいきます。同僚の場合、(通常は別の課題を担当しているなどで) 現在の具体的な課題まで把握できていないとしたら、情報共有だけで1-2週間かかりそうです。実状をまったく知らない部外の開発者であれば、現状把握に1-2ヶ月程度かかることも考えられます。新規参加メンバーに情報共有をする場合、教えられる側はもちろん、教える側も大きな作業工数がかかりますので、新しい人を参加させ、開発のスタート地点に立たせるだけで大きな時間を使いますし、もし新規参加の方であれば、実状を把握してコードを書けるようになってから、支払った時間を回収できるだけの成果を出すことは非常に難しいです。

そのため実際にスケジュールの遅延がありそうな時は、スケジュールの計画を関係者で共有し、現行のメンバーで問題無い品質を達成するまで開発し続けるのが、おそらく最も合理的です。

予定通りに完了できなかった時にどうするか

次回の見積もり時に今回の反省点を活かした見積もりをするのは当然として、開発者はどうすれば早く開発できるかを常に考えていかなければなりません。自分の実力が 100 として、今回の開発は 99 しか出せてなかったのではないか? を自問自答してみて、 99 だったかも…ではだめです。 100 出せなかった原因を取り除き、次回は 100 を出してください。

最後に

開発課題の「完了」とは、「もう作業をしなくていい状態」であり「開発成果が業務課題の改善に対して効果を発生できる状態」です。

実務経験で出会った便利なあれこれ

新卒エンジニアとして半年間働いてきて、現場でさまざまなことを勉強させていただきました。その中でも、もっと早く知っておきたかった便利なツール、Python の書き方など、幅広いあれこれを記事にしたいなと思います。

あれこれ、というざっくりとした括りになってしまっているのでまずは紹介したいものを示しておきたいと思います。

  • git submodule
  • Fabric3
  • Flake8
  • Python
    • 型ヒント
    • 整形文字列 f-string

git submodule

git submodule とは、git のレポジトリをサブモジュール化して複数のプロジェクトで共有することができる機能のことです。これを使うことで一度開発したコードを別のプロジェクトで簡単に再利用できます。例えばTORICOでは、 TORICO-ID のソーシャルログイン機能や決済機能だけでなく、ユーティリティ関数などを Django, Vue, Flutter それぞれのフレームワークでまとめたレポジトリが用意されてあります。

導入も至ってシンプルです。プロジェクト内で

git submodule add <リポジトリURL> <インストールパス>

たったこれだけで、今まで開発してきたコードを再利用することができます。わざわざプロジェクト間でコピペをしてくる必要はありません。さらに、git submodule はバージョン管理もしてくれます。サブモジュールを更新しても影響があるのはそのプロジェクト内だなので安心してサブモジュールの改良をすることができます。

1点注意として、submodule はメインのプロジェクト内で git clone や git pull を行っても自動で更新されることはありません。そのため、

git submodule update (初回のみ -i オプションで初期化)

コマンドを忘れずに実行する必要があります。

Fabric3

こちらは Python のモジュールの一つで、所定のアクションをコマンド一つで呼び出すことができます。例えば、デプロイするときの一連の流れを Python コードにしておくことで、ターミナルに fab deploy と入力するだけでその流れを自動で行ってくれるようになります。流れは以下のように記述します。

env.hosts = ['app1.sample.com', 'app2.sample.com']
def deploy():
    #  通知などを行う
    slack_announce('deploy')
    with cd ('/var/src'):
        run('git checkout master')
        run('git pull origin master')
        run('git submodule update')

このように一連の流れをコードとして残しておくことで、それをコマンド一つで呼び出すことができるようになります。さらに、新規に加入したメンバーでも簡単にデプロイができるというメリットがあります。その環境に慣れていない人が、例えば git submodule などのコマンドを忘れる心配もありません。また、私のような実務経験の無い人でもコードを確認することで流れを理解することができます。

TORICO では上記の git submodule を使ってほぼ全てのプロジェククトに deploy, ssh, flake8(後述), dsh (docker 環境にSSH)のコマンドが用意されています。

Flake8

こちらも Python のモジュールで、自動でコードレビューをしてくれます。導入は pip でインストールするだけです。実行は flake8 コマンドとオプションをターミナルにします。

flake8 --exclude="*migrations/*,venv/*,.venv/*,~* .

flake8 result

すると、このようにコードレビューをして規約に反する部分を教えてくれます。規約コードも教えてくれるため、わからない部分は検索できるようになっています。また、どうしても諸事情で変更できない場合は

from django.contrib import admin  # NOQA: F401

とコメントをつけることで、指定した規約コードの違反を行単位で無視させることもできます。

TORICO では毎回オプションを入力するのは面倒なため、上の Fabric3 を使って実行を簡単にしています。

Python 型ヒント

Python3.5 から導入された機能で型ヒントというものがあります。これは引数や帰り値の型をコードに書くことで可読性を向上させることができる機能です。

def hello(name: str) -> str:
    return f'hello, {name}.'

型ヒントはあくまでも補助的な役割のため、宣言とは異なる型を渡したところでエラーになることはありません。ただ、PyCharmでは型ヒントとは違う型を渡すと警告をしてくれます。可読性が飛躍的にあがるので、ぜひとも書くことを癖にしたいなと思っています。

Python F文字列

上の例でもしれっと使っていましたが、F文字列を使用することで .format 部分を短縮することができます。さらに、f文字列では変数だけでなく式なども使用できます。

print({a} + {b} = {a + b})  # format では a + b はエラーになる

format で記述するとコードが長くなる傾向があるので、スッキリと書けるf文字列は積極的に使用しています。

最後に

今回は現場で知った便利なあれこれを記事にしました。個人で勉強をしているとフレームワークや言語の知識は増やせますが、運用に関わる部分はなかなか知ることができないと思います。便利だなと思ったら、ぜひ積極的に使用してみてください。

新卒エンジニアが今になって就職前にやっておけば良かったと思うこと3選



就社してからは初めてのブログ投稿となります。
お久しぶりです。開発部の鈴木海人です。

株式会社TORICOにエンジニアとして入社して、半年が経ちました。
今回のブログでは、過去の内定をいただいてから入社までの間に対して何もしなかった自分に対して
入社までにやっておいたほうがいいことについてまとめました。
過去の自分のような過ちを他の人が犯さないようにまとめましたのでエンジニア内定をもらって何をすればいいかわからない人はぜひ参考にしてみてください。



私の簡単な経歴はこちら↓
都内私立文系大学卒業
大学3年時の夏に某大手プログラミングスクールに通い、プログラミングの基礎について学ぶ
スクール卒業後、都内のスタートアップの会社で2ヶ月ほどインターン(作業内容は主にLPの作成を行っていました)
大学4年時は就活を行い、株式会社TORICOに内定をいただき、今に至ります。



注意事項
簡単なコーディング知識があることを前提にお話しします。もしプログラミングが全くわからないという人はprogateなどのプログラミングを簡単に学べるサイトでまずは学びましょう。



それでは本題に戻ります。
まず結論からお話しします。以下の3つになります。
  1. タイピング強化

  2. 会社で使用する言語の参考書を1冊読んでおく

  3. ドキュメントで調べる癖をつける





それでは1つずつ説明していきます。

1.タイピング


これはどんな人でも絶対にやっておきましょう。
目安としましてはe-typingで安定してA以上や寿司打で1万円コースクリアでしょうか。
上記のサイトですと日本語入力ですので英単語を打つようなサイトを探してみてもいいかもしれません。
僕は入社してから、過去タイピング練習をしてこなかったことを最も後悔しています。

タイピングを強化しておくメリットには下記が挙げられます。
  1. 仕事スピードが上がる
  2. 成長スピードが上がる
  3. 教えていただいている時の時間を少なくできる


考えてみれば当たり前なのですが、タイピングスピードが2倍になればかけるコードも2倍になり、そのため成長スピードも2倍になります。
逆にタイピングスピードが1/2倍になればかけるコードも1/2倍になり、そのため成長スピードも1/2倍になります。
もはやエンジニアにとって一番重要なのではと思っています。
もちろん最初はコードを書くことよりも調べたり読んだりする時間の方が長いので、タイピングスピードの恩恵をあまり受けられないかもしれません
しかし後々大きく影響してくるので鍛えておきましょう。
後、単純にタイピングで遅くてミスりまくると恥ずかしいです。
1日10分とかでもいいので毎日タイピングの練習をするのがおすすめです。私も練習中です
タイピングに慣れてきたら数字や記号などもしっかりと打ち込めつように練習しましょう。

また少し話はタイピングから話がずれてしまうのですが、
よく使用するショートカットキーの暗記やカーソルの移動スピードmaxなどの使いやすいPC設定も行っておきましょう
こちらもPCを使う上での基礎スキルとなり、使っているか使っていいないかで作業効率が大幅に変わるので意識してみてください。






2.会社で使用する言語の参考書を1冊読んでおく


参考書を読むというのに抵抗感がある人は多いのではないでしょうか?
実際僕もそうでした。ネットなどで調べてみると「ネットに全部載っているのに本を買う必要はない」、「わからないことはその都度ググって調べればいい」など
本に対しては比較的、良い情報が流れていないようなイメージが僕にはあります。
これは私の上司から教えていただいて、確かにとなったのですが、本は体系的(一つ一つのものがある系統に従ってまとまっているさまのことという意味みたい)になっているため正確な情報をしっかりとインプットできるのです。
今までとりあえずわからなくなったらググってを繰り返していたのですが1通り本を読むことにより、もちろん完全暗記はできませんがコードを書いているとき、あれが使えるかなとか、それが出てこなくても
調べて出てきたメソッドなど、そういえばこんなのあったなと思い出せます。
また、おすすめの参考書なのですが
私の上司のおすすめの参考書はとりあえず分厚い本みたいです。。。
残念ながら優しくて短い本では情報量が少なすぎたりであまりお勧めをしていないようです。
参考書を買うときは分厚くて情報量の多い参考書を選びましょう。
こちらもタイピングと同様少ない時間でもいいので移動時間などを活用して少しずつ読み進めましょう。






3.ドキュメントで調べる癖をつける


皆さんはドキュメントで調べ物をしていますか?
僕は基本的にQiitaだったり個人ブログなどを参考にすることが多いです。。。
わかりやすいですよね。。。
なるべく意識はしていますが今でもあまりできていないのが現状です。
ドキュメントで調べる癖をつけた方がいい理由は、正確な情報が手に入れられるからです。
調べ物をしているとき正確な情報じゃないことや、記事が古く参考にならなかったり、バージョン違いで動作しなかったりと
結構クソみたいな記事が上に表示されることはあるあるではないでしょうか
ドキュメントで調べる癖をつけておくと正確な情報を手に入れることができるのはもちろんなのですが
英語で文を読む癖がついたり、英語で調べたりする癖がつくのでためになると思います。
日本語検索とは比べ物にならないほど英語の情報は出てくるので、英語めっちゃできるぜ!って感じを目指さなくてもいいですが
グーグル翻訳を使いながらでも少しずつ調べ物ができるようになると良いです。
プログラミングをしている人にとって英語は切っても切り離せない関係なので
早い段階で慣れておきましょう。





以上3つが私が入社前にやっておけば良かったことになります。
最後にもう1度
  1. タイピング強化

  2. 会社で使用する言語の参考書を1冊読んでおく

  3. ドキュメントで調べる癖をつける



重要順は上から1.2.3となります。
ぜひエンジニアに、これからなる人なりたい人は参考にしてみてください。




ビジネスサイドに知ってほしいエンジニア用語

今回の記事は新型コロナウイルスの影響で普段リモート開発をしていて浮き彫りになった問題点の1つとして「開発側と運用側でコミュニケーションが難しい時がある」といったものがありましたので、その原因として考えられる「IT専門用語が難しくしている」に焦点を当てて、業務中に発生した知ってもらえたら嬉しい用語を(個人的頻出度で)紹介していきます。(かなり噛み砕いていますので厳密で完璧にあっているものではないものもあります)




  1. デプロイ
    頻出度第一位は「デプロイ」です。ほぼ毎日slack上で打ち込んでいる気さえしてくる単語です。開発側が作った制作物を他人にも見てもらえるように反映することです。英和辞書などで調べると「配置する」といった意味がでてきますが、このままだと日常会話で出てくることもないでしょうし、直感的に理解することが難しいですね。もし自分がエンジニアをしていなく、デプロイと聞いたらどこかの国がミサイルでも配置しているのかと思ってしまうでしょう。


  2. 本番環境 & 検証環境
    1位のデプロイと関連しまして、よく使う定番フレーズが「本番環境にデプロイしました。」とか「検証環境にデプロイしました。」です。環境の単語がイメージしにくいのではないでしょうか。
    環境は目に見えるものではないので、得体の知れないところにデプロイしましたと言われたところで「どこか知らないけど、反映したことはわかったで。」のような感覚かと思います。この文脈でいう「環境」はサービスが動いているサーバーのことです。本番環境は実際にユーザーが見るサーバーで、検証環境はつくったサービスをいきなり公開にするのは怖いので、社内向けへの確認や動作の確認をするためのサーバーです。
    別名で本番環境はプロダクション( Production )環境、検証環境はデベロップメント( Development )環境やステージング( Staging )環境と呼ばれることもあります。

    ここまでで、もし「プロダクション環境にデプロイしました」というフレーズを聞いたらそれは「ユーザーが使えるように反映した」のような意味です。


  3. サーバー & サーバーサイド
    こちらは「サーバーが落ちた。」などで聞くと思われます。「サービスが動いている場所」のような感覚でなんとなくわかるけど、具体的にはよくわからない言葉ではないでしょうか。

    サービスが動いている場所というのは間違っていないですが、サーバーは英語の[ Server ]から来ており、給仕する人という意味で何かを給仕しているのですが、特定のものに限定されません。アプリケーションを動かす役割をサーブ( serve )していればアプリケーションサーバーで、データベースの役割をしていればそれはDB( データベースサーバー )です。そしてこの例のようにアプリケーションとデーターベースのサーバーが分けられていることもあれば1つのサーバーが両方を兼ねていることもあります。

    「サーバーが落ちた。」というのは何かしらの役割を給仕できなくなった状態です。

    そしてよくサーバーサイドとクライアントサイドのようなフレーズも見かけるかもしれません。ネットサーフィンしている私たちはクライアント(客)としてサービスを給仕されているのでサービス使用者はサーバーサイドに触れることができません。

    サーバーサイドエンジニアはユーザーが触れることができない箇所を開発しているエンジニアです。代表的なサーバーサイドを開発するプログラミング言語ではPHP、Ruby、Python( 当社で使用しているメイン言語 )があります。


  4. クライアント
    クライアントはつまりユーザーのことです。ですがユーザーは人間なので上記のサーバーから来たものを受け取ることもできません。なのでここでいうクライアントはブラウザやスマートフォンのことです。ブラウザとはSafari、Chrome、Firefox、Microsoft Edgeなどで、スマートフォンでは主に知られているのがiOSで動くiPhoneとAndroid OSを載せたものです。それぞれ動作は同じではなく、違いがあります。

    ブラウザではサーバーから受け取ったものを解釈してそれを表示するようにしますが開発に主に使用されるプログラミング言語はJavaScriptです。またスマートフォンではiOSならSwift、AndroidならKotlinなどがあります。当社ではブラウザ側ではJavaScriptのフレームワークNuxt.jsとスマートフォンではiOSとAndroid両方同時に開発できるFlutterを採用しています。


  5. Cookie (クッキー)
    業務でなくとも、プライベートでネットサーフィンをしていれば、途中で見かけた人も多いのではないでしょうか。もちろん、甘くて美味しいお菓子のクッキーではありません。そもそもこのCookieは何のためにあるかといえばユーザーの情報を覚えておくためにあります。そしてその保管場所です。

    本来はネットサーフィンをしていてもあなたのことをサービスは判断できません。ユーザーAさんがまた同じサイトに訪れてもAさんということはわかりません。データベースに情報を保存してあっても誰かわからないので何を返してよいかはわかりません。つまりCookieがないとあなたが大好きなAmazonでショッピングカートに商品を入れても、カートの商品はそのまま入ったままではいてくれません。それでは困るので、初回のサイトへのアクセス時に使っているブラウザ( SafariやChromeなど )にCookieをサイトは仕込み、今後はCookieが送信されサービスはそれを頼りにあなたを認識してくれます。

    他にもあなたが気になる商品の広告が出てくるのもこのCookieが原因です。


  6. セッション
    上のCookieでユーザーを認識してくれると書きましたが、Cookieはサーバーにアクセスした時に持っていれば自動的に送られるデータです。
    先ほどの例につづき、ショッピングだったら、何の商品をカートに入れたかを認識するためにあるのがセッションIDです。これがあなたのブラウザのCookieの中に一部として入っており、サービスを利用しているとセッションIDがCookieごとサービスに密かに送られ、サービスはセッションIDを元にしてカートに入れる、外す、購入するなどの利用状態( セッションデータ )を判断しています。

    そして例えばログイン済みのユーザーがログアウトすると、以後、利用状態を追いかける必要はないのでセッションIDは捨てられます。この一連の流れをセッションという単位で表します。個人を認識するための値なのでこれはセキュリティの観点からもれては他人に知られてはいけません。

    開発中に当社のサービスの1つでイベント申し込みをしたのに申し込み済みになっていない。というケースがあったのですが、こちらのセッションが切れているので申し込みをしたユーザーだと認識できていないことが原因でした。


  7. Cache (キャッシュ)
    こちらも普段、ネットサーフィンをしていれば、見かけたことがある言葉かもしれません。
    業務ではよくある問い合わせで開発側が「デプロイしました。」と反映したが運用側では「確認したのですが、変わっていません」です。これはキャッシュが悪さをしているかもしれません。( キャッシュは悪いやつではありません )。

    インターネットを利用する上で、同じサイトにまた行くというのはかなりよくあることだと思います。例えば写真が多いサイトは読み込む写真が多いので当然、完全にページを表示するのは文字だけのページと比べれば遅いです。そこで自動的にページの一部のデータを保存しておき、また来た時に、それを利用し早く表示するということをやっています。それのデータの保存場所がキャッシュです。

    なのでページの表示が変わっていないというのはこのキャッシュにためられた古い情報を使うとしていることが原因になっていることがあります。なのでブラウザの設定各種からこちらを消せば解決することがあります。

    本質的には一度した処理を保存しておき、効率的に再度利用するためのものなので、今回のテーマはビジネスサイドなのでブラウザのキャッシュを取り上げましたが、他にもコンテンツキャッシュサーバーやクエリキャッシュがあります( 興味があれば調べてみてください )


  8. AWS
    AWSはAmazon Web Serviceの略称です。Amazonと聞くとどうしても買い物のAmazonや電子書籍のKindle、映画のAmazon Premiumを想像すると思いますが、実はWebサービスのインフラ( 基盤 )をネット上( クラウド )で提供しています。

    AWSはサーバーをネット上使えるEC2というサービスや、データベースのRDS、世界各地に置かれたコンテンツキャッシュサーバーの集合のCDN( Content Delivery Network )であるCloud Frontというサービスなどを提供しています。それを利用することで場所にとらわれずにサービスのインフラを構築することができます。

    逆にオフィスにコンピューターを冷却するスペースを用意し、実際に現物のサーバーを購入したりして、設置する方式はオンプレミスと呼ばれたりします。




番外編

  1. hoge
    たまにエンジニアがデプロイしました。と言い確認してみると次の言葉を見かけることがあるかもしれません。こちらはエンジニア達の中では有名なダミーテキストです。実際に使用できる形を想定したデータを用意しお見せするのがいいのですが、もし見かけてもこれはふざけてやっているわけではない可能性が高いです。

  2.  lorem ipsum
    こちらもよく使われるダミーテキストです。ダミーテキストなので意味は特になく、仮置きに使われます。少し長めのダミーテキストであり、一般的には

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    として使用されることが多いです。


今回はビジネスサイドに知って欲しい用語を技術的な部分には触れない範囲で紹介してみました。これでみなさんのプロジェクトでのコミュニケーションがより円滑になる助けになれば嬉しいです。また需要があれば更新もしくは続編を出すかもしれません。それでは良い開発ライフを。

Search