yamarkz's blog

紫陽花

最近の学び 雑記

最近学んだことを雑記として残しておきます、あくまで雑記なので読んでもあまり理解できないかもしれません。
最近職場の方にビシバシ教わっているのでそのまとめになります。めちゃくちゃわかりやすく教えてもらっていて2004年ごろから開発されているエンジニアの方はレベルが本当に高くてすごいです。



プログラマとしての三原則

三原則

1. とりあえず動くものつくる(マスト)

2. 拡張性がとれたものを作る

3.パフォーマンスがいいものをつくる。(アルゴリズムetc...)

1はプログラムを書く者として最低限、というより必ず守るべきライン。ここができなければ何もできないと同じ。
拡張性がとれるものを作れれば一人前。さらにパフォーマンスを考えられていれば完璧。
ただし、2と3に関してはトレードオフなためどっちつかずになってしまう場合がある。
例 ) パフォーマンスをとることで拡張性がなくなってしまう etc...

書店で売ってある技術書は基本的にこの3つのどれかについてしか書かれていない。この3つさえ押さえればいい。

言語の特徴

1.手続き型言語
shell, C, Java, Perl, PHP

2. オブジェクト言語
Java, Ruby, Python

3. 関数型言語
Scala Haskell

4.低レベル言語
C

パフォーマンスを考えると言語的には圧倒的にCが早い。ぶっちぎりで1位
言語にはそれぞれ特性や特徴がありそれぞれに合った活用の仕方が存在する。

算数と数学の違いはなんだろうか?

算数
(1+2) * (3-10 * 100) = 600

数学
(x + 3) * (z - a) * 100 = c

c = x * 3

a = 4 + b

d = 5 - 1


いろいろと違いはあると思うけど、あえて簡潔に言うならば、具体的なのが算数抽象的なのが数学だろう。
算数は常に具体的な数字が与えられて足し引き、乗除を行い答えを導き出す。

一方数学は数字がxyなどの文字に置き換えられる。
xに10という数字があてはめられる時もあれば、yに7という数字が当てはめられる時もある。具体的な数字は定められておらず抽象的。
プログラミングでいう変数は数学でのxやyの文字の部分になる。

フローチャート

フローチャート
f:id:katlez:20160219010530p:plain

数学的な考え方を加えそれを処理として表してみるのがフローチャート
プログラムの流れをフローチャートで示すと上のようになる。
基本的にプログラムはこのフローチャートのように処理が川の流れのように続いている。
規模が大きくなればなるほどフローの長さは長くなっていく。

タコフローチャート

f:id:katlez:20160219010819p:plain

規模が大きくなり処理が増えていくと最終的に上の画像のようなフローチャートになる。
一般的にタコフローチャートなどと呼ばれるものになってしまう。
こうなってしまうとどこでどの処理が行われているか把握するのは容易ではない、というより難しいし、ほぼ無理。お手上げ。

そうなった時に考えられたのが手続き&構造化プログラミング

構造化プログラミング


構造化プログラミングって?
Wikipedia
構造化プログラミング - Wikipedia

構造化プログラミング(こうぞうかプログラミング、英: structured programming)とは、1960年代後半にエドガー・ダイクストラらによって提唱された仮想機械モデルに基づく段階的詳細化法を用いたプログラミングのことを言う。歴史的経緯から、構造化プログラミングはIBMのMillsの提案に由来するgoto-lessプログラミングとして一部分を切り取られた形で広く知られている[1][2][3]。

構造化プログラミングは3つの構造化文の書き方によって成り立っている。

順次反復分岐

f:id:katlez:20160219011654j:plain

この3つの書き方でほぼすべての処理を網羅する。3つの構造にまとめることは革新的だった。タコフローチャートはなくなり、簡潔で分かりやすく綺麗な処理が生まれた。
だいたいの初心者向けのプログラミングで紹介されるのはこの3つの部分が一番コアに紹介されてる。それぐらい大事、というかプログラムを書く上で当たり前な考え方。

アルゴリズム

プログラムの処理のパフォーマンスを考えることは最適はアルゴリズムを考えることになる。
アルゴリズムとはゴールまでの手順のこと。
例 )
1. カップ麺を食べたい(START)
2. カップ麺をコンビニで買う
3. 封を開ける
4. お湯を沸かす
5. お湯を入れる
6. 3分待つ
7. いただく(GOAL)

この1から7までがアルゴリズム(手順)

データ構造とアルゴリズムなどと言われていたりするが、あれはデータ構造(処理を加える前のデータと処理を加えたデータ、そしてその間のアルゴリズム(処理))について考えるものというのが本来の意味。
アルゴリズムは最短距離

2/20 追記↓

オブジェクト指向

手続き型の処理は規模が大きくなっていくとデータ構造が不安定になっていく。
どの処理でデータに変化が加えられているのかがわからなくなる。
リファクタリングが難しくなる(規模が大きすぎて手がつけられない)
テスト大変(泣)

オブジェクト指向が考えられた!

オブジェクト指向って何?

class? インスタンス? パーツ? 部品?
確かにそれらはオブジェクト"指向"を語る上で使われる言葉ではある。

結論は一言で、「目的のために"何の情報に対して"ふるまうか!」になる。

"オブジェクト指向は扱うデータに対して振舞ってもらう"ことを前提として作る。←この振る舞いをメソッドと呼ぶ
情報(データとその構造)を意識した処理の抽象化をする。
たいてい。DBのテーブル1に対して1つのclassを作り、共通化できる処理をmodule化して呼び出して使う。

ポリモーフィズム
ポリモーフィズムとは|polymorphism|ポリモルフィズム|多相性 - 意味/定義 : IT用語辞典



複数のDBテーブルにまたがった処理を行うときはどうするのか?
DBは二次元。それとClassをどう結びつけるのか。
そこで出てくるのが、O/Rマッパー
・O/Rマッパー
Hibernateで理解するO/Rマッピング(1):O/Rマッピングの役割とメリット - @IT

昔は、DAO(Database Access Object)


極論を言えば、DBの設計さえ完璧にできていればOK
あとの処理的な部分はフレームワークの使い方やら、処理の書き方を覚えてちゃちゃっとやっちゃえばいい。
処理だけに意識がいきすぎてDB設計がおろそかになっては本末転倒
DBのモデリングはかなり重要。


3/22 追記↓

考えることを考える

センスとはなんだろうか?

色々な定義などがあるけれど自分なりの仮説としては、
センスが良い = 素早く最適な 選択 or 決断 ができること。

ファッションセンスが良い人は、自分に合った服もしくは合わせる服を最適にかつ素早く選ぶことできる人だ。
サッカーセンスが良い人は、自分にボールが渡って来た時、他の人が考えつかないような選択を素早くすることができる人だ。

よってセンスが良い人は 素早く、最適な、選択 or 決断ができる人だ。

このセンスは人によって異なってくるがある程度のレベルまでは努力でカバーすることができる。ようは鍛えることができるということだ。

エンジニアの風林火山

風のエンジニア
長所
・CPUが早い → 仕事が早い
短所
・応用力がない (Rubyしかできない)(構築しかできない) etc....

林のエンジニア
長所
・謀略家 策を練り上げる 先手必勝 柔軟性がある 戦術 最強の現場エンジニア
短所
・突出したものがない 仕事をしていないように思われる

火のエンジニア
長所
・革新 新技術 方法 暴走
短所
・炎上エンジニア ボヤ騒ぎ
山のエンジニア
長所
・構成 計略 マネジメント セキュリティ
短所
・融通が利かない


エンジニアのランク
1. 達人クラス
2. 優秀クラス
3. まともクラス
4. 足掛けクラス ← me ......
5. 丁稚クラス

思考のフレームワーク

f:id:katlez:20160323015034p:plain

1. 念じる
2. 発散
3. 集中
4. 整査

考に深みを持たせる

常に意識するのは 6W6H
who
whom
when
where
what
why

how
how to
how long
how much
how many
how in the futuer

発想を広げる

"+ 同一カテゴリの要素を加える
"- 何かを消す
×  異なったカテゴリを加える
÷  細分化して1つに特化
←  連想配列
like 比喩 例え
◯  連想

f:id:katlez:20160323015152p:plain


4/8 追記↓

設計

設計することの根底は定義することである。

定義すること とは、前提条件、仮説、期待を決めること。

f:id:katlez:20160407233202p:plain

「なぜ、その実装なのか。」

が、答えられるかどうか。

アプリケーションのメソッドはインプットは何か、アウトプットは何かを実装前に定義してから実装を行う。
アプリケーション開発で一番難しいことは決めること。

どのような背景があって、どのような仮説を立て、どのように期待する振る舞いにするかを決めることが重要になる。

定義は断定的に決める。決断する。
システム問わず、技術の世界では定義が全て(前提条件/仮説/期待)

事業は論理の世界、どんな事業も理論が通ってなければ成功しない。(dowangoの川上さんも言ってたりする)

ソースコードはデリケートな商品。振る舞い1つにしても定義をすることが当たり前。
戦う前から勝負は決まっている、実装する前が勝負。

f:id:katlez:20160407233229p:plain

動けばいい、作ればいいという話は足掛けエンジニアまでは許される(かも

自分が実装するときに最低限必要な情報のレベルを知ることができているのはエンジニアで飯を食っていく上で重要、自分のレベルを上げる上でも重要。
Webアプリケーションであれば、ワイヤーフレーム・ER図・サイトマップ は最低限必要。

f:id:katlez:20160407233242p:plain

サービス(企画)を設計に落とし込む能力があるかどうかがデキるエンジニアの差になる。
設計側にいくほどサービスに与える影響が大きくなる。
だから、設計は重要になる。

アジャイル開発は設計を省いて実装を行う。
しかし、それは「アジャイル開発を行う人間が設計(定義すること)について理解している。」という前提条件のもと行うが故に上手くいく開発手法であるということ。
逆を言えば、設計を理解していないエンジニアが、"自称アジャイル開発" を行うというのは、突貫工事でアプリケーション開発を行っているということになる。結果、悲惨な開発になる。。。。