ProgramingLake

ナレッジ置き場

要件定義

とりまく環境
・要件定義を明らかにするプロセスを得意とするSEが不足している。
・プロトタイプに頼るあまり、行き当たりばったりの開発が横行し、結果的に設計書が書けるSEが減ってしまった。

要件定義フェーズにおける注意点
・大方針としてゼロベースで検討するのか?それとも現行のシステムを参考にして進めるのか
・手戻り、納期遅延の根源は要件定義。
・読む人が判断に迷わないものを作成するべきで定量的な表現がベターで、
 次の工程の担当者に何をすべきかを伝える目的がある。
・当フェーズで曖昧さを解消するのは骨が折れる。ただ、これを怠ると後工程に皺寄せがいくだけ。
・見積もり時、コミュニケーションオーバーヘッドがあるので、開発要員を増やしてもスピードは倍にならない。むしろ低下することを考えなければならない。
・アリバイレビューではなく、ユーザーを巻き込んだ実質的なレビューが必要。
・プロトタイプで行きましょう = 「今、丁寧に要求を洗い出すのはやめましょう」という意味では無いことを確認すべき。
・この言葉に「仕様の決定を先送りにしましょう」という意味合いが含まれているのであれば一度立ち止まるべき。
・1:1, 1:n, n:1, n:nを考える
・見積もり時は変動要素をよく考える必要がある。
・要求事項というのは発散しがち、それぞれが問題、解決に貢献する要求なのかを判断する必要がある。
・業務理解が大事な理由。それは仕様漏れの芽を潰せる。また、例外業務があるかというのがわかる。
ヒアリング時は無理に整然としたフローを作ろうとするな。業務は実際は複雑であるため。
・美しくない業務の流れがあれば改善する必要が出てくる場合もある。

・机上で仕様を詰めていても、実画面が動く姿を見て違和感を感じるというケースは多い。
・プロトタイプに頼りすぎると、システムエンジニアの行動が計画的でなくなる。

発注元のユーザに対して
・丸投げ的な発想はシステムにおいては通用しない。同じ業態であっても、会社が違えば考え方が違う。
 最もパッケージ製品に馴染むと言われている給与システムや会計システムでも曖昧さを解消しないと失敗すると言われている。
 協業して進めていかなければ必ず失敗する。 

ヒアリング
・ユーザーは抱えているニーズを自ら列挙することはできない(忘れや漏れが必ず生じる)
・これは当たり前だろうと思っていることを語ることができない。
・あなたと異なる意見を言う差は他にいませんか?という観点も大事
ヒアリングの難しさ、聞いたことが情報が得られるが、聞いていないことは分からない。
・「何か問題がありますか?」が一番 NG。漏れだらけになる。
・あなたの意見は部署全体で見て標準的ですか?例外的ですか?
・この人だったらどう答えると思いますか?それにはどういう思惑があるからだと思いますか?
・ドキュメント調査が必要。現場で使われているマニュアルやちょっとしたメモも大事。あとは開発ドキュメント。

一般法則
・遅れは遅れを呼ぶ。一度遅延したプロジェクトはもう一度遅延する。(プロジェクトマネジメントの一般法則)
・挽回するシナリオよりも現状維持か、それより悪くなるというシナリオを想定しておいた方がよい。それが現実的。
・正しくないものを急いで作っても仕方がない。
・なぜ遅延するのか?それは正しくないものを作ってしまうから。
・例えば冗長な作業、ヒューマンエラーを削減するべき。担当者の注意力で解決するというのは一番やってはダメ。個人の成長を待たずに遂行できるのが理想。
・FIT & GAP をして総括的に一致するので進めていたが、ミクロな視点で見ると不一致があるというケースがある。
・ミクロな視点に傾きすぎると、システム構築本来の目的を見失ったり、優先度が定まらなくなる。

開発側の社内の課題
・報告用の対応等に時間が費やされるのは無駄。実質的には何も解決されていないままである為。

発散した要求事項の絞り込み
・要件定義で最も恐れるべきなのは仕様の漏れであるグレーゾーンのものまで切り捨てると必要なものまで捨ててしまうリスク。
・意見、指摘、愚痴は多ければ多いほどいい。そこからは取り組むべき重要なテーマが見えてくる。
・例えば冗長な作業、ヒューマンエラーを削減するべき。担当者の注意力で解決するというのは一番やってはダメ。個人の成長を待たずに遂行できるのが理想。
トヨタのなぜなぜ分析を5回すると、自然に問題の核心に迫っていき、本質的な問題が発見される。最終的には数個程度の根っこに当たる問題に収束するのが普通である。
ボトルネックを探そう。ボトルネック=投資効果が高い観点である。
・機能というキーワードだけだと色々な解釈ができるため、なるべく要件定義では使わない方がベター。具体的な例で補う必要がある。
・解決したい問題と実装すべき機能のマッピングが必要
・必要であろう機能の洗い出しが完了しても、まだその機能を実装する価値があるかどうかの判断はできていない状態である。

パーソナル

失敗・ミス

ミスの元凶は「過去の失敗が共有されていないこと」「個人の注意力で解決しようとしていること」

因果関係と相関関係は違う

その「原因」が再発したら必ずその「結果」になるのか、なれば因果関係。ならなければ相関関係。
最近「原因と結果の経済学」という本を読んでいる。今まで相関関係と因果関係を混同していた。
一見、関連性があるように見えても
「ただの偶然なのでは無いかと考える」
「原因と結果が逆になっていないか考える」
「原因と結果の両方に絡んでいる第三因子が無いか考える」
が大事。

ドメイン知識以外の知識を積極的に取り込もう

現場が長くなるとドメイン知識だけでも立ち回れてしまう。そうなると結果的に他の現場に移った時に自分は通用するのか?という不安に繋がるので精神衛生上良くない。

対人関係

・自分のタスクに余裕ができると他の人のニーズに耳を傾ける余裕が生まれる。

他人に相談する時

まずは事前に相談したい旨を相手に伝えよう。相談される相手からしてみたら予定外の差し込みの作業となり、突発的な相談は作業効率が著しく低下させてしまう。何をやって、何をやっていないのか。何に困っているのかは明文化しよう。それが出来ていない場合はまだ相談して良い状態ではない。

相談される時

一般論でのアドバイスに終始しないようにしよう。一般論は刺さらないことが多く、相手の個性を加味したアドバイスをするのが理想。

こんな人は無視

感情(怒り)で相手をコントロールしようとする人。 怒っても仕事は何も進捗しない。残業・稼働時間でマウントとってくる。 稼働が高くなりがちな職種・ポジションで働いている以上、仕方がないだろう。 たくさん働くのが嫌なら異動・転職すればいい。それだけ。

イチイチきつく当たってくる人

結構な低評価・感想・愚痴を頂くこともままある。反省すべき点は反省すべきだが、それはあくまでもサンプル数1の評価でしかない。間に受けすぎないこと。

悩み

休みの日も仕事のことを考えてしまう 不安事項を書き出す。そして1つ1つ何が原因で不安なのかを分析。余裕があれば「なぜなぜ分析」し、不安の元凶を明らかにする。

楽しいことToDoリストを作成する

「仕事終わりに1つでも楽しいことをやる」ということを生活リズムに盛り込む。 仕事のことを思い出すのは「暇な時間」があるから。一時的に「忘れる」には他のことをするしかない。

仕事術

疲れる前に休もう。 疲れてから休むのではなく、疲れる前に休む。毎日全力で仕事するよりも、いかに翌日への余力を残して働くのが大事。結局、仕事は続けることが大事。

自分を守る為に上を巻き込もう

上を巻き込めば、何かあった時に自分だけのせいではなくなる。要所要所でチェックしてもらい、何かあっても連帯責任ということを周囲に自覚させることが大事。

なるべく細かい単位のタスクを切ろう

「タスク消化」という成功体験を積み重ねることは精神衛生上オススメ。 翌日のToDoリストを作成した上で仕事を切り上げよう

システム化する上で考えるべきこと

・システム化が最適解とは限らない
 (業務の工夫でなんとかできるケースもある。特に短期ミッション完遂の支援を目的に存在するシステム)
・無理に作ったシステムを維持運用していく覚悟はありますか?
定量的な効果を算出するのは難しいケースがある。
・その数字を無理にでっちあげるのは意味がない
・因果関係を証明するのも難しい
・定常業務を持たない部門からのシステム要望は要注意。業務上の変数や例外が多い為。
・誰も使わないシステムでも、休日や深夜に出勤してお守りする運用部隊がいる。


・要件定義とそれ以降は一旦区切った方がいい
・要件定義が詳細化されないと後続工程の見積もりが不可能なため。
・変更管理のルールやプロセスはあらかじめ決めておくべき
 (様々な変更を評価して承認。却下の判断をするための手順を決めるべき)

MongoDB

一般
MongoDBのレプリケーション:

MongoDBでは、データの耐障害性や可用性を高めるためにレプリカセットという概念を採用しています。レプリカセットは、複数のサーバー(ノード)からなる一組のデータベースサーバーで、1つのプライマリノードと複数のセカンダリノードから成り立っている。

プライマリノード

書き込み操作を受け付ける唯一のノード。このノードでの書き込み操作が成功すると、その操作はセカンダリノードにもコピー(レプリケート)される。

セカンダリノード

プライマリからのデータの変更を継続的にコピーして同期をとるノード。読み取り負荷の分散やデータの冗長性のために使用される。

レプリケーション遅延

レプリケーション遅延は、プライマリノード上でのデータ変更がセカンダリノードに反映されるまでの時間の遅れを指す。具体的には、プライマリでの操作がセカンダリにレプリケートされるまでの時間差。

コマンド

データベース確認

show dbs

データベース切り替え

use new_db

コレクション(=テーブル)一覧

show collections

件数指定検索

db.cities.find().limit(10)

件数

db.cities.find(
    {"area": "kanto"}
).count()

項目絞り込み

db.cities.find(
    {"area": "kanto"},{ "_id": 0, "name": 1 }
)

mongoシェル(jsファイル)実行

$ mongo < input2.js
$ mongo --port 40001 < input2.js
$ mongo localhost:40001 < input2.js

(ナレッジ)Linux

#!/bin/bash

if [ "$1" = "dev" ]; then
  user_name="user_1"
  db_name="pass_1"
  echo "xxxxxxxxxxxxxxxxします"
elif [ "$1" = "stg" ]; then
  user_name="user_2"
  db_name="pass_2"
  echo "xxxxxxxxxxxxxxxxします"
else
  echo "終了します。(実行時パラメータにはxxxxxを指定してください)"
  exit;
fi

echo -n "よろしいですか? [y/n]"
read answer
if [ "$answer" != "y" ]; then
  echo "停止しました"
  exit;
fi

# DB操作
export PGPASSWORD=${db_pass}
psql -U ${user_name} -d ${db_name} -h ${host_name} << EOF
set session timezone = 'Asia/Tokyo';
set search_path to ${schema_name};
${set_role};

DELETE FROM sample;
EOF

/var/log/journal に保存されているジャーナルファイルの容量が大きくなった場合

# 100MBを残し削除
sudo journalctl --vacuum-size=100M

とっさの

ファイル検索(permission error回避)

find ./ -name data -type d 2> /dev/null
find ./ -name mongod.conf -type f 2> /dev/null

SGのインバウンド設定にIPアドレス設定したいから教えて

$ ip -4 a
$ ip -4 a | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

プロファイルを作成したい

aws configure --profile any_name

AWSクレデンシャル情報確認を確認したい

cat ~/.aws/credentials
cat ~/.aws/config

鍵作成したい

cd ~/.ssh
ssh-keygen -t rsa -f fuji_keypairs
秘密鍵(fuji_keypairs_rsa)と公開鍵(fuji_keypairs_rsa.pub)が作成される

公開鍵を出力したい

cat ~/.ssh/fuji_keypairs_rsa.pub > /Users/username/Documents/authorized_keys.txt

(ナレッジ)ServerlessFramework

Serverless Applicationを構成管理&デプロイするためのツール。
Node.jsで作られたCLIツールの為、Node.jsをインストールする必要あり。(Node.jsのv4以上が必要)
 
インストールコマンド
npm install --save serverless
 バージョン確認
serverless --version
 モジュールを一緒にdeployするためのプラグインもインストール
npm install --save serverless-python-requirements
 localでlambdaスクリプトを実行するためのライブラリをインストール
pip install python-lambda-local
 
プロバイダーアカウントのセットアップ
(どのクラウドサービスを使用してServerlessを動かすか)
 Serverlessは「サービス」という単位で実行環境を作る
AWSをプロバイダーとしてpython3でサービスを開設する場合は以下の手順
serverless create --template aws-python3 --name requests-test --path ./requests-test
 
上記を実行すると「requests-test」のディレクトリが作成され、その配下に
以下のファイルが作成される。
.gitignore
serverless.yml
handler.py
 
handler.py内に、デプロイしたいLambdaのコードを書く
 
 
ローカルで試す
(まずは引数用の event.json を作成)
実際は使わないので、空のjson。中身は{}だけ。
python-lambda-local -f main handler.py event.json --log
(mainはメソッド名、.pyは実行ファイル名、event.jsonは実行時引数、--logオプションで実行時ログが確認できる)
 必要なパッケージをrequirements.txtにかく
pip3 freeze | grep requests > ./requirements.txt
 
serverless.ymlを編集
service: requests-test
provider:
name: aws
runtime: python3.7
region: ap-northeast-1
 
functions:
requests-test-lambda:
handler: handler.main
 
plugins:
- serverless-python-requirements
 
custom:
pythonRequirements:
dockerizePip: true
 
# dockerrizePip:true = Lambda関数の実行環境とほぼ同等のDockerイメージを利用する、という意味
   
AWS環境にデプロイ
(裏でCloudFormationが動く。ローカルのコードがS3経由でLambdaにdeploy。)
serverless deploy function -f <yourfunction> --verbose --aws-profile {プロファイル名}
(verboseを付けると途中経過がターミナル上で確認できる。-vでもOK)
(参考)
秘匿したい情報はssmパラメータを参照することで実現できる
 
Githubに上がった既存のサービスをインポート
serverless install -u [GITHUB URL OF SERVICE]