ぽんぽんぺいんでつらたんなので、おしごとおやすみしまーす

🗣: バイクに乗ったり、ものづくりしたり、ひたすら寝たり。

運動神経ゼロの私が、普通二輪の卒業検定に受かるまで。

普通二輪免許を取得しました〜🎊👏👏

卒業証明書の状態なので、公道を走るまでにまだもう少し猶予があります。

教官に幾度となく「ギアの変え方忘れちゃったの!?」「交通法規守って!」のようなお言葉をいただき続けた練習期間だったので、皆様にご迷惑をおかけしない為にも家の周辺で練習をしていこうと思ってます…orz

実はこの免許を取るまでに卒検は3回受けました。

スペック:運動神経ゼロ奴

中学生まで自転車乗れなかったウーマン。
今は通勤でクロスバイクに乗ったりする。
球技スポーツなどは悉くノーコンなのでマジで参加したくない。多分球に対して特殊な磁場が発生している。

そんなウーマン、なんとなく、暇だな〜。遠くへ行きたい。二輪かっこいいという憧れを抱く

梅雨の時期のある日、家で開発したり本を読むなどしていたのですが、
目疲れたな…他の事やりたいとぼんやりするタイミングが増えました。

以前だったら水彩画を嗜んだりしていましたが、社会人になってから趣味が変遷してきたなー…と。
他に何をしてきたかというと、西関東へ鈍行で遊びに行ってコンデジで写真撮影したり、地元の美味しいものを食べたり…でも熱海とか箱根とか鉄板は行きつくした感ある…
足がほしい


何もしたくないときはゆるキャン△を見て脳のオーバーフローを鎮める作業に入る私なので、凛ちゃんが格好良く見えて仕方ないわけです。

\\ ---イメージをお伝えしたく、突然の素敵記事---
nlab.itmedia.co.jp


ちょっと田舎の方の緑に囲まれながら、風を切って走る。しかもこの乗り物は自分の主導権で動く!というポイントにも惹かれ、よし。申し込みしよう。と何も考えずに申し込みに向かったわけです。

即申し込み〜引き起こし

地元から近めで評価も高い尾久教習所にお世話になりました。
教習ってうんざりすることが多いけど、技術教習に関するレビューの高さが異様だったのでここに決定。
(別にHPのデザインが可愛いからとか、TLS接続しているからは決定打ではない)

受付のお姉さんに普通二輪を取得したい旨を伝えると、横から出てきたお兄さんが「バイクの引き起こしをしてください。出来なければ申し込みは受け付けられない」とおっしゃる訳です。わーお。

軍手を借りて、教習車が止まっている屋根下のスペースで引き起こし体験。

わっ!バイク思ってたより大きいなあ!
まあ腕筋については根拠のない自信もあるので、大丈夫でしょw

でもこの子207kgあるの。

www.bikebros.co.jp


掴んで、引き上げるをするだけで悲鳴をあげる私の腰。(なんかビッ!て音がした気がする)
お兄さんから引くのではなく押す、というレクチャーをいただき無事引き起こし完了。
「わっ。意外に力ありますね!」と私のゴリラっぷりを目の当たりにしたお兄さんに世辞をいただいて、ちょっと得意げになる私。しかし本当の地獄はこれからだった。

教習〜普通二輪には乗れないよ〜

教習開始早々、追突・車両横転・加速不良に苛まれる私。

だってバイク怖いんだも〜ん!!

そう、みんな簡単そうに走るけど、思ったよりも操作性が複雑で、加速するまでの指示系統が身につかないうちは

操作をミスると突然猛スピードで発車する重たい鉄の塊🏍🏍🏍=3


「えっ!?重ッ!?💢💢」と免許を取りに来たにも関わらず、車両に理不尽な逆ギレをする私。見かねた教官の指示で、125ccからの練習になったのでした。
そういえば私は原付にも乗ったことがなかった…
教習所で出来たお友達にお願いし、時間があれば夜の武蔵境で練習もしてみました。
速度とアクセルの回し方の雰囲気については学べるのでオススメ。
2回ほどで普通車の練習に戻ることができました。

番外)ばくおん!!

うだる暑い夏の日にそんな事をしているので、モチベーションも疲労とともにやって来やすいのです。そんな時は美少女とアニメで癒されよう……
という事で合間にばくおん!!をウォッチします🦀

bakuon-anime.com

けいおん!にかぶれとるな〜という第一印象から入りつつも、作中のバイクはどれも精巧に、格好良く描かれていて、その中にバイクを通して深まる関係性の描写もあり、普通に知識がなくても楽しめる作品でした。
ベテランがゆえに、バイクの定義にこだわってちょっとこじらせている中野ちゃんが好きです。

ミス・コースアウト

そんな感じでバランスを保って乗車できるようになるまでたくさん申し送りを受けて、同じ項目で人の倍教習を受けたと思ってます。

等間隔に置かれたパイロンを通過する時は、肩からハンドルを曲げる動きを練習してました。
狭路については低速で安全な走りを実現しなければならないところを、手が滑ってアクセルで速度がかかり、8の字の中に花壇に衝突して破壊活動を行うなどしてました。キャーーー!!!!>-🌷🌷🌷🏍=33


コースの植え込みを直している教官の大きな背中を見て、お花・教官マジですまんよ…と心の中で謝る日々。

教官にしつこく半クラッチを使用しての走行を要求される時。
同じ項目で受けている隣の教習生の走りがめっちゃ綺麗な時。
モチベが下がりまくるので上のばくおん!!鑑賞に戻ります。
(でも半クラは超大事)






後半に〜続く〜

Kotlin Fest2019に参加しました<<後編>>

残暑お見舞い申し上げます。

まだまだ暑い日が続きますが、次回の基本情報技術者試験まで1ヶ月強となりました。
午後の練習問題は相変わらず6割超えないくらいに終わってます…。


さて、転職したばかりの環境でヒィヒィ言っているうちにとうとう9月の中旬になってしまいました。増税前に会社の金で行ったKotlinFest後編についてまとめていこうと思います。


八木俊広さん ( @sys1yagi )
Kotlin コルーチンを 理解しよう 2019


小谷野 雄史さん ( @bandwagondagon )
Coroutinesから紐解くKtorの仕組み


Malvin Sutantoさん ( @MalvinSutanto )
Code Generation in Kotlin with Annotation and KotlinPoet


木原 快さん ( @gumimin_ )
もっと Kotlin × Spring


荻野陽太さん ( @youta1119 )
Kotlin/Nativeはなぜ動くのか?

Kotlin コルーチンを 理解しよう 2019

Ktorってなんとなく使ってみたけどこの記述は何をしているの?他のDIライブラリと何が違うの??という疑問にぴったりな講演でした。

Ktorとは?

KtorはDIをもたらすことで薄いフレームワークを作ってくれます。
よく***Application.ktに書いているinstallというブロックは機能の追加をする役割をしています。

Ktorは計算パイプラインの機構を提供しており、FeatureやRoutingの実行順序を柔軟に変更することができます。

例えば
Thread1はリクエストをするが、計算待ちの場合は他のリクエストを受け付け、
並行して走るThread2は計算ができます。
計算終了後、Thread2はThread1の処理と合流します。

suspend

別スレッドでリクエストを受け付ける事ができる

launch

ブロック内ではThread3を生成するが、終了しない場合は全てのパイプラインが実行を待つ。

async

ブロックでは別スレッドを生成し、これが終了するまで次のCallフェーズには移らない。

proceed, await

suspendしながら次のフェーズまで処理をする事ができる。最後のフェーズが終了したらまたMonitoringフェーズに戻り、全ての処理が完了したら処理が終了する。効率的に計算する事が可能。

Continuation(コールバックが入ったクラス)

suspend

コード実行を中断する可能性がある。同じサスペンドの中で呼び出す事ができる
通常の関数からはビルドエラーする
コンパイル後は引数にコールバックが入る+返り値がAnyになる

suspendの呼び方

suspendブロック内でstartCoroutineで走らせる事ができる
返り値(途中中断した場合マーカーがかえる)を持つ関数がある。

continuationを受け取る関数もある(状態の制御が可能)

マーカーを返却することで強制的にスレッドの終了が可能

ApplicationObjectをフェーズ間で共有する事ができる

Code Generation in Kotlin with Annotation and KotlinPoet

こちら外国の方の講演でした。KotlinPoetというAPIライブラリを使って、アノテーションを作っちゃおうぜというお話でした。

まず、全体的に話のレベルが高かったです。
おそらくこれはKotlinを使ってライブラリか何かを作りたい人向けのもので、
私が唯一感覚としてハマったのは、あるJsonパーサーを使っていて遭遇したキャスト関係のエラーについてくらいでした。


(正直よくわからんかったです。自分に知識が足らなすぎて…
下記内容はほぼほぼ自分の解釈+言葉遣いになるので、ニュアンスが違ったら教えてください。)


メタプログラミングについて

機能に振る舞いを加えたり、変更したりする。
ex)実行中はリフレクションやパーサーとして、コンパイル時はジェネレータとして、
実行中にファイルやプロパティを読みこむ。

ex)変数を読み込む、機能を呼び出す
xmljsonのように解釈する

保守しづらいバッドプラクティスなコードについて考えてみよう

入力に基づいてファイルを生成する
アノテーションソースコードバイトコードもしくはどのような種類のファイルでも出力できる。
安全にコンパイルする
静的にコードを解析し、実行前にエラーするのを防ぐ。

アノテーションプロセッサはJava6から加えられたAPI仕様。


@AutoMapはデータクラスをMapとして解析できるようにコンパイルしてくれます。
こやつから

@AutoMap
data class Person(
val id: Long,
val name: String?,
val address: Address
)

こう

/* *
* Converts [Person] to [Map].
*/
fun Person.toMap(): Map {
val map: Map = mapOf(
"id" to id,
"name" to name,
"address" to address
)
return map
}


kotlin-stdlibをGradleにDIすると使えます(not AndroidModule)


講演者はmetadataもオススメと話していましたが、こちらは割愛します🙇‍♂️

KotlinMetadataUtilsを実装するgetSupportedAnnotationTypesをオーバーライドする事で設定の文字列を返している。
@AutoPlocessorは別途build.gradleで追加する。


ClassNameで返り値のマップを指定できる

val returnType: ParameterizedtypeName = ClassName("kotlin.collections", "Map")
.plusParameter(String::class.asTypeName)
.plusParameter(Any::class.asTypeName().copy(nullable = true))

プレースホルダーで%T, %Mと変数をリプレース出来る
これはKotlin特有の型推論を使ったテクニック👏

if (element !is TypeElement || metadata == null) { …

mapOfの返り値を指定する
%S ->string, %L -> literal

Funspecでにアノテーションだけではなく、コメントを加えることができる。
引数の型と返り値の型、KDocを書いていく事ができる。

val mapClass = ("kotlin.collections", "Map")

val funSpec = FunSpec.builder("toMap")
.receiver()
.returns()
.addKdoc("Converts [%T] to [%T].", className, mapClass)
.addCode(codeBlockBuilder.build())
.build()

FileSpec.builder(className.packageName, className.simpleName)
.addFunction(funSpec)
.addComment("This is a generated file. Do not edit")
.build()
.writeTo(outputDir)

どんなコードができるかは101枚目のスライドを見てみましょう。

感想としては、自分たちが使っているライブラリたちは、きっとこのような過程を経て出来ていくんだなあ、と。言語特性をフル活用してコーディングする経験としてはライブラリ作成ってかなりいいのかも。
そして、完全にKotlin製のライブラリって実はOKHttp4のようにまだまだ少数派なのかも…と思い直す講演でした。

もっと Kotlin × Spring

こちらの講演は、今の現場でSpringを使うことが多い為に聴きに行きました。
別途まとめ直すかもしれません。

Kotlin/Nativeはなぜ動くのか?

CyberAgentからギークな新卒の方がお話をされにいらっしゃってました。
Kotlinをコンパイルする為に必要なミドルウェア(LVVM)のお話周りです。







f:id:letterneginr:20190912220843j:plain


f:id:letterneginr:20190912220554j:plain
KotlinFestのひよこ

前記事にも書きましたが、Kotlin界隈の方々は親しみやすく、一定数ギークな人たちが集まっているコミュニティという印象です。

そこでのエンジニアは純粋に好きなものを追いかけていて、それがどのような方向性であれ容認していくところが素晴らしいと感じています。


ちなみに、我が社のKotlin使いの先輩はGraphQL、Springなど使って管理画面を一新するそうです。。
酒の誘惑に負けずに共に頑張りましょう(私自身、酒はそんなに飲みませんが…)


私はもう少しSpringとお友達になることにします🌸

Spring Boot事始め

仕事でJavaを扱うようになったので、SpringBootと仲良くなる方向性になりました🐕

エンジニアなりたての頃にEclipse(pleadis)の重さに悩まされ、Javaのわからなさ・書けなさに悩んだ記憶から早3年…

今回はフレームワークの根幹であるSpringBootについて先輩からご教示いただいたので、メモっていきます。

SpringBootとは

Javaプラットフォーム向けのオープンソースライブラリ。 アスペクト指向プログラミングを根幹にしたフレームワークで、webやsecurity、batch処理などの機能を備えている。 DI機能を使うことができ、環境ごとに使う関数を切り替える事が出来るなどの旨味がある。

DIとは

依存性の注入のこと。 クラス内で使用するメンバにアノテーションを付与することで、宣言と初期化が同時に出来る。

そのインスタンスは外から参照されるものの、その状態を気にせず使用できるところがポイント。 イミュータブルなオブジェクトの作成が推奨される設計の場合非常に便利。ただし、意図的に初期化ができてしまう機能も存在する為、プロジェクトの設計方針に応じて使用する。

依存性の登録方法

①自動(コンパイル時によしなに依存性の注入を行う)

@Component
 ∟@Service
 ∟@Controller

②手動(作成者が意図的に依存性の注入を行う)

- XML
- JavaConfig

@Component

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed

などのinterface群により定義されている。 ルートのクラスで@ComponentScanを付与することによって、このアノテーションが付いた下位クラスを探す。 後述するBeanをDIコンテナに登録する為のアノテーション

JavaConfig

DIコンテナを登録する為のクラスファイル。定義ファイルなどではない。 @Beanアノテーションを付与することによって、メソッド名と同名のBeanが作成される。 インスタンスはSingletonに扱われ、DIコンテナ1つにつき1つ作成される。

Bean

ライフサイクルの衝突を避けてインスタンスを静的に生成する。 あるクラスのメンバをBean(豆)のように内包した形で上記を実現する。

依存性の種類

①フィールドインジェクション

②コンストラクタインジェクション

③セッターインジェクション

①フィールドインジェクション

独自に依存性の注入を行うや方法。

public class ImageThumbnail {
  @Autowired
  private ImageRepository imageRepository;   
  public ImageThumbnail() {   
  }
}

②コンストラクタインジェクション

springに依存せず、独自に依存性の注入を行う方法。

public class ImageThumbnail {
  private ImageRepository imageRepository;   

  public ImageThumbnail(ImageRepository imageRepository) {
      this.imageRepository = imageRepository;
  }
}

③セッターインジェクション

lombokを使用してgetter, setterを出力する方法。 イミュータブルではなくなってしまう為、扱いに注意が必要。

public class ImageController {
  private ImageRepository imageRepository;

  public void setImageRepository(ImageRepository imageRepository) {
    this.imageRepository = imageRepository;
  }
}

Springに捧げるとよしなにセットしてくれる

@Service
public class ImageService {
…
}

Kotlin Fest2019に参加しました<<前編>>

残暑お見舞い申し上げます。

新職場1週間目でした🎉🎉🎉 環境構築諸々など無事に済んでよかった。

今回はなんと会社のお金で週末にKotlinFestに参加する権利をいただき、エンジニアらしい行事に参ずる事ができて感無量でした。

小さな勉強会にはちょくちょく参加していましたが、Kotlin書く人達(Kotler?)は温和で親しみやすい雰囲気でありながら、ギークな部分が垣間見える面があり、非常に良い雰囲気の中で勉強させてもらいました。

断片的ではありますが、内容をまとめていきたいと思います。 自分が聞いたのは下記の5セッションです。

1. オープニングセッション
長澤太郎
Svetlana Isakova

2. Server-side Kotlin by Ktor
Coroutinesから紐解くKtorの仕組み
小谷野 雄史

[EN]
3. Code Generation in Kotlin with Annotation and KotlinPoet
Malvin Sutanto

4. もっと Kotlin × Spring
木原 快

5. Kotlin/Nativeはなぜ動くのか?
荻野陽太

オープニングセッション

遅刻したもので、長澤さんが「Have a nice Kotlin !!」という部分からの参加になってしまったorz Svetlana IsakovaさんはJetBrains社(Kotlinを開発した会社の人)らしく、これまでのKotlinの進化についてや、魅力的な機能を紹介してくださっていた。

Kotlinは既存のコードを壊さないような構造をしている

まだ自分の経験の中で実感できてはいないが、前の職場ではJavaのリプレースをKotlinで少しずつやっていて、共存が出来ていたので確かにこれは便利なものだと思っている。

コミュニティでは常に問題共有を行い、対応していくことを考えている

コミュニティについては、プロダクトコードをほとんど書いていなかったこともあり、胸を張って参加する事が出来ていなかったが、今後は積極的に情報のキャッチアップをしたい。(特にJavaの方も)

Kotlinをより良いプロダクトにする為にみなさんからフィードバックが欲しい

とのことで、いくつかの機能について紹介をいただく。

  • inline class
  • extention property
  • immutable collection
  • flow(experimental)
  • multi platform project

改めて思ったのは、本当にKotlinの言語仕様わかってなさすぎた… 他のエンジニアと自分のコードを見比べたり、客観的にアドバイスいただいて思うことはこの知識量の差でもあるなと実感。 Kotlinの良さをしっかり理解してコードを書くというよりも、今まではAndroidの機能を実装するということにウェイトを置いてしまっていたと実感した。

今はSvetlanaさんは新しいKotlinの本を執筆されているそうで(仮タイトルはAtomic Kotlinだったかな)、これはプログラミング初心者や、Java初心者でもついていけるような内容にしていくそう。

初めて型言語の大きな勉強会に参加したけど、Railsやフロントエンドの時よりも、女性エンジニアが少ないのが少し気になったのよね。 もう少し同士が増えたら嬉しいななんて思う。

www.coursera.org ちなみに、こちらのCouseraからAuditモードでKotlinの学習ができるそうです。

基調講演のSvetlanaさんのスライドはこちら

基調講演での技術紹介

ここからは聞き取れた内容と、Svetlaさんのスライドを雑に訳す+補足情報を加える事で自分が解釈できた情報を書いていきます。 まだ実際に試していない内容になるので、ご注意ください。 サンプルコードについては、スライドより抜粋させていただきました。

- inline class

オーバーヘッドなしに値をラップできる いまは実験段階

Duration APIは1.3.50で実験的に提供される

同じ関数を違う型で扱いたい時、その分だけオーバーロードするには冗長的すぎる。 そんな時、クラスでラップしてあげれば他の方のオブジェクトも割り当てる事ができる。

inline classを定義し、下部で関数を定義できる。

また、inline classではval(再代入不可)なコンストラクタしか宣言ができない。

この性質を利用して、明示的な単位を設定することができる。

val Int.seconds
  get() = toDuration(DurationUnit.SECONDS)
fun greetAfterTimeout(duration: Duration)
greetAfterTimeout(2.seconds)

- contract

日本語で契約、約定という意味。 スコープ関数として定義され、自身をレシーバとした関数を実施し、その内容を返す。 しかし、runブロックの中で初期化をしてしまうとコンパイラがそれを検知できない為、エラーを返す。(これについては仕様。後述する。)

isNullOrEmpty()についても同様。 レシーバにヌル許可を割り当てた場合、これを検知する為にエルビス演算子を挿入する必要がある。

しかし、contractsはコンパイラに明示的にコードのその他の情報を共有する。

ブロック内では1度きりのみ呼ばれるようになり、

関数が偽を返せば、レシーバがヌル不可であると解釈する。

これを利用してrunブロックでの変数初期化、エルビス演算子なしでの解釈が可能となる。

なぜコンパイラに情報が不足した状態だったのか 

それに依存する事でコードが壊れることを防ぐ為。

contractsを使うことでrunとisEmptyOrNullは便利になるし、独自に関数で定義できるようになる為便利ー。

- immutable collection

ImmutableListにPersistentListというキャストに便利な仲間が加わるよ。

オリジナルのリストデータ構造の一部を共有している。 なんとaddができる。ハッピー。

val list = persistentListOf(1, 2, 3)
val newList = list.builder().apply {
  add(4)
  add(5)
}.build()
println(newList) // [1, 2, 3, 4, 5]

- flow(experimental)

ReactiveStreamを基礎としたsuspend?

flow { emit(value) } 
  .map{}
  .filter{}
  .catch{}
  .collect{}

RxJavaとの統合

flow.asPublisher()
publisher.asFlow()

suspendのメカニズムによってBackpressureが起こります。

->余談 : BackPressureとは

https://github.com/Kotlin/kotlinx.coroutines/blob/master/reactive/coroutines-guide-reactive.md

https://qiita.com/pljp/items/f748125934fd3f880565 (上記の日本語訳)

同じ処理を追随させて別のスレッドで行わせる事ができる。メインスレッド側の最後の処理が終了した後、別スレッドの処理も完了する挙動をする。

Flowableとは

データの流れを消費する事ができる、ファクトリーメソッドとReactive Streams Patternを実装している。 PublisherとReactive StreamsはFlowableの継承をしていて、別のReactive Streamの操作とPublisherを直接的に受付けている。

- multi platform project(expect actual)

expect fun Char.isUpperCase(): Boolean
public actual fun Char.isUpperCase(): Boolean

ビジネスロジックを共有できる プラットフォーム依存のUIを保てる (共有部分は異なるかもしれない)

expectは共通部分に宣言する事ができる。 異なるプラットフォームにはactualが宣言できる。

共通部分については標準的なライブラリで使う事ができる。

標準的なもの、KtorHTTP client、serialization、couroutinesなどなど… すでに本番環境で動いている事例もあります。

マルチプラットフォームにモダンなアプローチをしています。

このように、共有したい部分を調整できます。

引用:

qiita.com

現場で役立つシステム設計の原則を読み終えたのでまとめていく

最近は無職期間を活用しながら普通二輪の教習に通っていたろんです。

開発に関してはサボりつつも、重要そうなエッセンスを取り入れる為には良いタイミングだと思い、ゆっくり掲題の本を読んでいました。

こちらは次の職場の先輩に勧められた本で、オブジェクト指向+ドメイン設計でのアプローチになるので読むといいと勧められました。

前職で同僚が読んでいたこともあり、前置きは少し読んでいたのですが

リーダブルコードを貸した後に、こちらの方が良いと思って読んでいると聞き、「ちょっとそういう主旨で読まないで欲しいんだけど…」と複雑な思いを抱えながらの出会いだった記憶があります。ちなみにその同僚にはやんわりとこれはリーダブルコードの代用ではないと伝えておきました。

結論から言うと、設計思想についての取っ掛かりとして良本だと思えました。

自分がいいと思ったポイントは下記で、

ドメイン設計の具体的な思考法

・画面とドメインロジックの分離について

・Web-APIの設計方法

などです。

業務についての理解が浅いことで、アプリケーションの整合性に支障をきたすという部分が実務において心当たりがあり、反省しました。

自分の話になりますが、 前述した同僚の彼は仕様把握に意欲を燃やしていて、カスタマーチームとの連携も積極的に話を聞きにいくなどしていた面が特に素晴らしいと思い、様子を見ていました。

彼はスクラムマスターを兼任していて、働きの結果として開発チームのタスクの量がかなり膨れてきた事が目につきましたが、これは潜在的に元からあった問題を表明する事が出来たので良い傾向だと感じました。

問題なのは優先順位で、つい「開発として実装が楽なのでこちらを先に実装してしまおう…」という意識で楽なタスクに手を出しがちなのですが、それで達成感はお手軽に味わえても、後々を考えたら「これってまとめて実装した方がよかったのよね…」とごちゃごちゃしたUIを目の当たりにして後悔する事になります。

これは、本の中でも述べられている設計の失敗だと思っていて、最初から情報量が多くなる事が想定されていれば、DBについては詳細情報として分離し、アプリケーション側としてはオブジェクト単位での実装を実現する事で仕様を把握する側、アプリケーションを実際に使用する側としてもわかりやすいものになったと思います。

ただ個人的にはこの思い切りの良さをどうやって推進するかが懸念点で、よく必要のないものは実装しない(YAGNI)と言われているように、 オペレーション / ユーザーが何をしていて、将来どういうことをしていくのかもわからないままにアプリケーションの設計の話をしていくのは難しいと考えます。 そこで文頭に戻り、やっぱりこのアプリケーションはどのように人の役に立つかを考える必要が出てきます。

これは今後の自分の課題で、

タスクの要件を満たす実装ではなく、本質的・根本的に考えて、ユーザーが欲しいものは何か

を知る / 思考する必要があります。ユーザーがアプリを使う背景についての解釈が曖昧だった為に、実装の条件を考える上で時間を使ってしまった事に気づいて、すぐに対処できなかったのが悔やまれます。

ちなみに、この本の対象者は、オブジェクト指向についてなんとなく理解はできたが、 そのアウトプットの仕方に迷っている人で、正直Rails(もしくはSTIなORマッパーを採用しているフレームワーク)から入ってきた人・開発してる人(初心者)にはそんなに意味を為さないと思っています…。(この書籍の内容を実現するとSTIで表現するには難しい部分があるんでは…と感じます。) そんな方々は技術書展とかで見かけるRailsの設計パターン系の話を読む方が臨場感あって(いろんな意味で)面白いと思うよ。。

また、引用元の本も記載されているのでこれから知見を広めていきたいという人にもおすすめです。

久々にブログを書いたので色々と辛い… 来週から社会性を取り戻しに新職場で頑張りたいと思います。

WordpressでSEOの環境を変えた話。

こんばんは。圧倒的にアウトプットが減ったもので、リハビリがてら業務で触れたものをはざ喰い的に紹介します。

※所感は個人のものなので、根拠としてあてにしないでください。また、諸事情により脚色部分があります。

改修から3ヶ月間でユーザーが200%超える月があったり、検索順位が4枚目から2枚目に上がった時の施策を書きます。

医療系のサイトの対応だったので、コンテンツの内容の専門性は問いません。

GoogleAnalyticsの画像
ユーザーが増えました

  1. サイトマップを改築する
  2. 正しい降順・用法でhtmlタグを使用する
  3. 正規リダイレクトを設定する
  4. インデックスの設定を更新する
  5. 膨大なアセットは最適化する

オプション コンテンツの拡充

1. サイトマップを改築する

最初の構造として、採番している命名のページはあるものの連番になっていなかったり、そもそもルートのディレクトリが違ったり、バラバラのパスを繋ぎ合わせてホームディレクトリに置いている状況でした。

/home
/about
/access-2
/course_category/internalmedicine
/course_category/medicalcheck
/medicalcheck/regularly

エンジニアとしてはこれでも気持ち悪いな…と感じますが、作った人の頑張りを蔑ろにしてはいけません。(戒め)

何がまずいか

今では強く言及されているポイントではないそうなのですが、サイト構造はクローラーフレンドリーにする事で検索エンジンの評価が変わるというものです。

クローラーアルゴリズムは、ホームディレクトリを拠点に、根から先へ伝うようにコンテンツのタイトルやディスクリプションを巡回するように作られていると言われています。

そこで意味や関連性のないキーワードをあげたり、コンテンツとして並列する事で、「ユーザーにとって情報収拾のしにくいページ」という評価を下されてしまうという事です。

具体的な解決法

指南役の方にアドバイスを頂き、下記のように改築しました。

/home
/about
/access
/department/internalmedicine
/department/medicalcheck
/medicalcheck/regularly

今回はテーマを購入して立てられていたので、ソースは落とさずGUIから丹念に設定を変えていきます。ソースコードはローカルに誘えないので、要素探しにgrepは使えません。ちなみにWordpressは経験なかったので調べました。褒めてェ…!

今回はAll in One SEOというプラグインを使っていたので、そこに配置されている.htaccessを改変します。

<IfModule mod_rewrite.c>
<b>RewriteCond %{THE_REQUEST} ^.*/index.(htm|html|php)
# medical_checkのパスからカテゴリーの健康診断ページを呼び出す
RewriteRule ^medical_check/(.+)$ http://mejiroekimae.com/course_category/medicalcheck [R=301,L]</b>
</IfModule>

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

太字が追加部分ですが、脚色してあります。 コピペで設定すると、間違った場合にキャッシュを持って正しいルートでの呼び出しに404で応答する可能性があります。公害になってしまうので、キャッシュを綺麗にするプラグインを入れるか慎重に調べて作業しましょう。

親を変更できないページについては、無理やり特定のパスの呼び出しがあった時に健康診断ページが呼ばれるという変更を施しました。 また、URL/index.htmlなどで/移行のないページに遷移するというのは意識的にトップページはやった方が良いという事で、改めて設定しています。

2. 正しい降順・用法でhtmlタグを使用する

Wordpressはデフォルトでロゴにh1をあててくれます。 おそらく多くのテーマがそうなっていて、どのページを閲覧してもヘッダにあるh1が露出します。

何がまずいか

それに気づかず個別の固定ページでh1を使いマークアップすると、本来1ページにひとつだけの用法であるのにも関わらず、1ページで複数登場してしまうようになるのです。

正しいマークアップSEO効果があると言い伝えられています。(いにしえ感)

具体的な解決法

まずどのような関連でビューが呼ばれているのか把握します。 親ページ、子ページ、ページビルダー、固定ページ専用、 固定ページ専用(サイドバーなし)、ヘッダ、フッタなど…大小様々なhtml, css, jsが呼ばれているのです。Railsやってる人はビューのrenderを連想すると解釈しやすいかもしれません。

今編集したい階層は/home/about

→管理画面のGUIから見るとaboutの編集は"固定ページ"の下にある
→固定ページの設定はサイドバーなし
→外観>テーマの編集>No sidebar固定ページテンプレート(page-noside.php)
が実際に適用される

→GoogleChromeDeveloperツールで立ち上げて観察しているとヘッダも呼ばれている
→使われている特徴的なクラス名をチェックする(IDでも良い)
→適用されている要素から、外観>テーマの編集>テーマヘッダー(header.php)が適用されているとわかる

3. 正規リダイレクトを設定する

  1. で紹介した部分がありますが、こんなパスでもリンク側からするとどのように設定されるかわからないし、仮に同名のファイルが置いてあって表示されたらたまったものではありません。 ユーザーはトップページにアクセスしたと思っているのに、prefixが違うせいで404を返すのは粋ではないですよね。 ここは割愛してしまいます。

4. インデックスの設定を更新する

インデックスとは、1ファイルに割り当てられている読み込みの順序だと認識しています。

何がまずいか
  • サイトの表示に不必要なページを読み込んでしまい、サイト自体が重くなる。
  • ユーザーがアクセスできるコンテンツの一部として認識されてしまい、秩序がないとさらにマイナス評価になる可能性がある。
  • コンテンツとして機能していないページであるにも関わらず、サイトマップに認識されてしまう。
具体的な解決法

GUIぽちぽちです。No indexで不要なコンテンツを選択してください。

All in One SEOのインデックス設定手順の画像
All in One SEO>No indexの対象を決める

5. 膨大なアセットは最適化する

適所適材の素材を扱いましょうという事です。 htmlの表示は素材(厳密にはhtmlタグ)→css類の順で描画されるので、 でかい画像を読み込んでリサイズすることは無駄感があります。

スマホコンテンツなどには適切にviewportにあったサイズのものを使用するといいかと思います。 今回思いついたものは画像サイズを小さくするなどに止まりますが…

squooshは便利でした。画像の容量を小さくしてくれるツールですが、ものによっては7割以上軽くなりました。

(イラストは多色のPNG、写真類は解像度低めのjpgと分けてもよかったのかも…?)

developer.mozilla.org

squoosh.app

ざっと書き出しましたが、思い出したら更新します。

最近は生ことりんにご執心です。

シナモン文鳥オスの画像
この世の不純を愛らしさを持って平穏へ導く鳥の画像

圧縮してないです。可愛いので出来るだけ原寸大+高画質で見てください😇

コンテンツの拡充

チョットマッテネ

組織でエンジニアとして働く自分について振り返る(Team geekの感想)

letterneginr.hateblo.jp

先日こういうオチのない記事を書いた。 本当は設計の正について調べなければいけないし、結局先輩の伝えたかった事ってなんだったのかを書いていかなければならないところなんだけど、 一旦勧めてもらった本を元に技術的ではない方向性のアプローチを学んだ。

Team geekという本。自分がもし新卒のエンジニアだったらリーダブルコードと共に読みたい本だった。 内容は筆者とプロジェクトの仲間たちの体験談を交えて、表題の通りに進んでいくのでかなり読みやすい。早い人だと仕事をしながらでも3日もかからないと思う。

コードを隠す 有害な振る舞いの追放 人に対する基本的な姿勢 プロダクトはユーザーに必要とされるもの

これらが一番刺さったと思う。

コードを隠す

努力や泥臭い部分を隠して仕事する人が多いという話、 でも実際にコミットの切り分けが綺麗だったり、細かい記法によく気がついて整備されたコードを書く人がいると思う。

それに、年数が浅いのに大きな機能の実装をやり遂げられたりとか、自学でセンスのあるエンジニアリングをしている人を見かけると、つい自分のやってきた事に対して自信が持てなくなる。

でもそことの向き合い方は恥だと考えて誰かと共有しないっていうのは本当に成長しない。 昨年いた環境はそれが顕著で、近いエンジニアと「出来ない」を頻繁に共有できなかったし、作るものの方向性も違って、楽しい気持ちすら共有できなかった。

正直に言って細部を理解する事に拒否的で、あたかも作り上げた自分がエライみたいな雰囲気を出す人は苦手だけど、 実際にそのプロダクトのオーナーはその人自身だし、誰かを喜ばせているには違いないんだなって思う。その行為だけで価値がある。

少し話が逸れてしまった気がするけど、技術に特化してプロダクトを美しくデザインする事にこだわりを持つ人が好きだ。 見えないところにこだわりを持てる人は細部をわかっているし、説明もうまい。話し方が論理的なので非常に助かる。

今はそういうレビュアーがいるところで仕事が出来て、彼は今度去ってしまう予定なんだけど、自分の浅いところをたくさん見てもらえてよかったと思ってる。 建設的な批判が出来るので、その行為が後戻りをすることはない。

有害な振る舞いの追放

これは多くが自分に当てはまる。 人間自身が悪いという視点を持つのではなく、その振る舞いがチームにもたらすことを考えなきゃいけない。 まずは、周囲に不安や動揺をもたらす行動をしない。w これが他人であった場合に、その振る舞いの理由と追い出し方を考えることが重要。 バイステックの個別化と似ているような気がする。

人に対する基本的な姿勢

Humility, Respect, Trustが大事だと。

実例でいえば、向き合っている人のスキルにもっと目を向けてもいいんじゃないかと思った。 みんなのわかる言葉で、物事をシンプルにしたり、困ったらこちらから頼ったり、何かを共有する時間を増やせば自然と健全な職場環境は出来ていく気がする。 (ランチでもいいけど、個人的にはランチ中に仕事の話はしないでほしい笑)

今の会社にいて思うのは、ユビキタス言語がバラバラで、エンジニアである自分ですら、参入後しばらくプロダクト自体について勘違いをしていた。 社内の人はお利口さんが多いので、なんとなく質問するのが憚られていたけど、ある日「めんどくせ」ってなったのでCSに仕様を聞いてみたりした。 あとでエンジニアに確認したところ、微妙にプロダクトの仕様の歴史に齟齬があり、新たな誤解を生んだ。 学んだのは「自分の立場を忘れない」「話し相手と自分の想像の同期を忘れない」事。

プロダクトはユーザーに必要とされるもの

なんかもうまともっぽく書くの疲れたので、3年弱くらい見てきたエンジニアについてを3行くらいでまとめる。

基本的に自分に自信がない
マゾが多い
自己顕示欲がすごいもしくは病んでいる

こういった特徴を持つ人間が集まるとどうなるか。必ず揉める。

決まって技術マウントもしくは宗教的な話が始まり、どっかの言語のコミュニティの有り体を借りるなら、「お前なんて俺の父ちゃんのパンチで一発だ」みたいなやり取りは1回はあると思う。

でも私たちがvimEmacsかで揉めているうちにユーザーの成功体験の機会は失われるか減る。

人に構われたくて、役に立ちたくて、喜ばれたくて技術を学んできたはずなのに、見えない状態になる。

この辺の話には深みが出るほどの経験は今の自分はしていない。思い出したら追記しようかと思う。