🥷

[Web開発] 初級エンジニアのための計画

2023/12/19に公開

「経験の浅い新人」から「頼もしいチームの一員」に入れ替わるための計画を紹介いたします。主な要素は4つ:

  1. 学習対象の厳選
  2. 自作プロジェクト
  3. ドリル
  4. フィードバック

早速ですが、本題に移りましょう。

学習対象の厳選

プログラミングを始めたきっかけは、「ホロウナイト」というゲームを初クリアし、「これほど素晴らしいゲームを産むことができれば、死んでもいい」と思ったことでした。それから数ヶ月Unityでグラフや迷路生成アルゴリズムを用いる簡単な3Dシーンの実装に没頭しました。この経験から「アルゴリズムってやっぱ便利よな」という錯覚を起こしました。
しかし、現職についてから同僚と話をしたところ、教科書に出てきそうな典型的なアルゴリズムを職場で活用した人は誰もいませんでした。とはいえ、アルゴリズムに用途はないというわけではないが、典型的なアルゴリズムよりも、Web開発に適したアルゴリズムを直接学んだ方がいいのではないでしょうか:

  • ユーザ入力の取得
  • ユーザ入力のdebounce
  • HTTP要求による外部リソースの取得

ジュニア開発者ならこれで十分だと考えます。

次に、現職で使っているスタックはこちら:

クライアント:

  • JavaScriptとTypeScript(8:2の割合で)
  • HTML、CSS(Tailwind)
  • React(状態管理:Redux)
  • React Router
  • WebSockets

サーバ:

  • Node(Express)
  • Postgres(ORM:Sequelize)
  • RestAPI
  • WebSockets

ユーティリティ:

  • エディタ:VS Code
  • テスト:Jest
  • パッケージマネージャ:NPM
    • NPMも一応マネージャですけど、部下を解雇するタイプではないため、安心
  • 静的検証:ESLint
  • メッセージキュー:RabbitMQ
  • 仮想化:Docker

自作プロジェクト

以上のすべてを活用するプロジェクトはいくらなんでもあります。従って、難易度が緩やかに上昇するような経路を準備することもできます。このやり方で基礎はきちんと記憶の中で手続き化されるため、順番通りに進むことをおすすめします:

ユーザ入力の取得

  1. Reactのフォームでユーザー入力を取得し、フォームの隣に列挙する:JavaScriptかTypeScript、HTML、React
  2. ユーザー入力をdebounceする
  3. Expressサーバに入力を送り、ログする:Node、Express
  4. Postgresデータベースに入力を保存:Postgres、Sequelize

おそらく、このプロジェクトの唯一の難関はdebounceとなるでしょう。

ポケモン図鑑

データ源:PokeAPI

英語版のポケモンで日本の名前で検索はできないものの、一括要求できますので大した問題ではありません。このプロジェクトのポイントはUIの例を見つけ、そのUIを正確に真似することです。これこそCSSやTailwindを鍛えるための究極の方法でしょう。

ここも、難易度別に分けましょう(以下の図は全て適当に検索して見つけたものです):

  1. 名前、番号と検索バー:
  2. 名前、番号、タイプと検索バー:
  3. 名前、番号、タイプ、検索バーと詳細メニュー:詳細メニューの例

プラスα:要求データのキャッシング。自動的にキャッシュするNode APIクライアント側のAPIがすでに存在しますが、自分でやってみても損はないでしょう。

合計で以下の技術の練習になります:

  • CSS、Tailwind
  • JSかTS、React
  • debounce(検索バー)
  • キャッシング(クライアント側)
  • React Router(ホームと詳細ページの切り替え)
  • Node、Express

ポケモン図鑑、フィールド編集可能版

今回のプロジェクトはポケモン図鑑UIに加え、全てのフィールドを編集可能にすることを目的とします。もちろん、編集の内容もサーバ側のデータベースに保存しないといけません。ここで使うのはpostgresですが、厳密にいえばMongoDBなどのNoSQLデータベースの方が適切かもしれません。postgresを活用したければ、他に大量編集モードを追加しても良いかと思います(例えば、全てのポケモン名の最初に適当な文字をつけると言った操作)。

スタック:

  • CSS、Tailwind
  • JSかTS、React
  • debounce(検索バー)
  • キャッシング:今回はDBとの整合性のため、キャッシュの更新と無効化も考えないといけない
  • React Router(ホームと詳細ページの切り替え)
  • Node、Express
  • Postgres、Sequelize

追加、クライアント側:状態管理の様々な実験

担当しているプロジェクトの状態はひどいです。本来の開発は経験が浅く、犯しうる誤りを全て犯したようです。その一つはReduxの使い方にあります。例えば、アクションを送信すれば、Storeが添えたデータ(payload)で更新されるのは普通でしょう。しかしながら、本プロジェクトではアクションがStoreに着く前に何回も変更されますので、アクション送信の結果が未定義動作になりやすいです。しかも、同じアクション変更の元はたいていバラバラです。

上記の理由で、Reduxに不信感を抱いてきましたが、やはりReduxを練習しない手はありません。

また、次のプロジェクトに備え、Redux以外の状態管理ライブラリを比較してもいいと思います。例えば:

  • Metaにより開発されているReact向けのRecoil
  • Recoilより手軽なJōtai

ライブライ以外:

  • Reactのカスタムフック(参考記事
  • GraphQLのようなクエリ言語・ライブラリにキャッシングを任せ、ひたすらデータを要求するのみ

その他:考慮中

スタックのほとんどに触れることができましたが、WebSockets、RabbitMQ、Dockerはまだです。加えて、認証・認可の導入も試みたいです。そのため、このセクションにプロジェクト提案を残します。

  • 認証・認可付きのRestAPI:SWAPI(スターウォーズAPI)、所属軍や専門別に宇宙戦搭乗を認可する
  • RabbitMQ+WebSockets+Docker:サーバAでFinnhubのような株式市場APIに接続し、RabbitMQに変動の通知を送る。サーバBでRabbitMQから通知を読み取り、WebSocketsを通してUIにメッセージを表示する。RabbitMQインスタンスとそれぞれのサーバをコンテナ化する

ドリル、集中的練習

プロジェクトを作るだけでは重複する部分が多いです。例えば、Reactプロジェクトのセットアップや入力のdebounceなど、過剰に繰り返す作業となります。ですがこれは問題ないと考えます。なぜなら、Web開発の基礎を過剰練習することでその記憶を固めることができれば損はありませんから。

しかし、あまり繰り返されない作業なら他の戦略が必要ですね。そこで、技術や能力別にいつでも実施できるドリルをいくつか考えました。自分の一番苦手なところの上達を目的に、当てはまるドリルを定期的に反復してみてください。

とはいえ、プロジェクトを実際に書いてみないと自分の苦手なところがわかりませんので、ひたすらドリルを繰り返すだけで上達が停滞したり、ドリルに含まれていないわけでなおざりにしている能力が退化したりする恐れもあります。または、ドリルがやや退屈である傾向もありますので、健康のためにも積極的に多種多様な練習方法を試しましょう。

以下はいくつかの技術に対するドリルの例:

UI作成

今までのプロジェクトではすでにCSSとReactを使いましたが、ポケモン図鑑のUIは比較的に単純だと考えます。私は自分のUI作成能力を上級まで高めるつもりです。

思いついたやり方は二つ:

  1. 適当にウェブサイトを開き、そのUIを複製する
  2. GitHub上に存在する複製UIの収集を利用する:100例以上あるAwesome Clones、とマリオのLinkedInまであるInterfaces Clone

JavaScript

JavaScriptでAtCoderの問題をできるだけたくさん解くほか、TDDを用いてJSの標準ライブラリを再実装する手もあります。

TypeScript

幸いなことに、Web開発を始める前にC・C++・Haskellの経験がありましたので、TypeScriptはどちらかというと私の得意分野になっております。だからと言って、成長の余地はないというわけではありません。

任意的に複雑な型の実装を練習したい時はType Challengesという難易度別の問題集をよく使います。VS Code拡張機能もあり、エディタ内にいつでも練習可能で非常に便利です。

Reactのカスタムフック

カスタムフック集をもとに、カスタムフックを繰り返し実装しましょう。

Node

Expressなどのフレームワークを介せず、Nodeをそのまま使ったことがありますか?Expressを使用すると分かりませんが、サーバ要求から戻るデータはBuffer状態にあり、数字の配列に過ぎません。そのため、Bufferデータが届く途中で使おうとすればもちろん変なことになるでしょう。

そこで、NodeとサーバIOに対する理解度を深めるには、Expressなしにサーバを立ててみるがいいと思います。

SQL

SQL構文の基本を押さえた上で、ある程度複雑なクエリでも正しいSQLを書きたいなら、以下のサイトをご覧いただければと思います。いずれもオンライン端末形式になり、苦手なクエリを覚えるまで繰り返し練習しましょう。

Docker

Docker exercisesで基本コマンドの復習ができます。

エディター操作

私はMac上にVS Codeを使いますが、マウスなしの操作はまだまだです。よく忘れるショートカット、または使い慣れていないショートカットは次の通り:

  • ワークスペース範囲の検索
  • ファイルの左右分割
  • ファイルを左右に持っていく
  • 別のエディタにフォーカスする
  • 上下にカーソルを増やす
  • 単語全体を選択

これらを練習するには、ウィンドウを開けば上記のコマンドを1〜3回繰り返すといいでしょう。

フィードバック

ここでいう「フィードバック」は仕事(コード)の質に対するフィードバックも、仕事のこなし方に対するフィードバックも含みます。

上達するには、フィードバックが欠かせません。フィードバックの内容自体はもちろん、他人に自分の仕事を評価してもらう姿勢も非常に大事です。

あいにく、人間はそう簡単に素直なフィードバックを受け入れることはできません。当然ながら、人目を過剰に気にする私も正しくその通りです。その結果、「フィードバックを時々求めましょうよ」と自分に言い聞かせたところで、1週間以内に挫折するのは落ちです。

それゆえ、「時々」フィードバックを求めるより、毎日フィードバックを求めればどうですか?「自分の仕事ぶりについてどう思いますか」、「私のコードに不備はないでしょうか」、「私に足りないものがあれば、それはなんでしょうか」など、毎日。

自分がジュニアであるからこそ、周りの優しい方々に気を遣割れることが多いという問題もあげられます。特に私のように1年以上苦労しながら、あまりいい業績を出せなかったとすれば、「こいつはメンタルや技術が弱い。簡単に傷つくだろう」と思われてしまうのではないでしょうか。間違ってはいませんが。

だからこそ、フィードバックを毎日要求し、自分のオープン性をアピールしましょう。また、先輩が毎日フィードバックを求めらると、「気遣う」か「事実を述べる」かのいずれを選ぶでしょう。ならば、誰から最も有益なフィードバックが得られるのかすぐに特定できるという利点も考えられます。

しかしながら、ここで一つの問題が発生します:フィードバックをもらうことは先輩がチームに残ることに依存するということです。この事から、先輩から率直なフィードバックを求める習慣を徹底しつつ、Web開発コミュニティとのつながりを深めた方がいいと考えます。これなら、先輩が入れ変わり、新しい先輩からフィードバックをうまく引き出せなくても、フィードバック源は完全に消えません。

フィードバック要求の習慣をつけるための手順:

  1. チームとのコミュニケーションを円滑に行う
  2. 自己分析を行う
  3. 率直なフィードバックを求める
  4. フィードバック源を増やす:コミュニティと繋がる
    1. #100DaysOfFeedback
    2. オープンソースプロジェクトに貢献
  5. フィードバック源を安定させる:指導者を見つける

チームとのコミュニケーションを円滑に行う

私は今まで、現状報告を怠ったり、同様先輩の邪魔をしないために大事な質問を数日間後回しにしたりしたことがあります。もちろん、これでかえって怠け者に見えてしまいます。

このような状況が二度と起こらないように、いくつかのチェックリストを提案させていただきます:

現状報告

  • 別の課題に切り替えるとリードに報告した
  • PRを公開する際、アサインしたレビュワーに報告した
  • 1週間以上続く課題の状況を約1種間ごとに報告した
  • Issueのないプロジェクト(例えば、ただいいアイデアに思いついた時)を始める前にリードと相談した

質問する際

  • 助けを求める前に、解決を30分試みた
  • 問題の説明をできるだけわかりやすく書いてみた
  • 問題をメール・メッセージで明確に伝えた
    • 問題の現状を説明した
    • 問題はどんな状況下に起きるか説明した
    • 現状は期待している状況とどう違うか説明した
    • 現状は最終的・望ましい状況とどう違うか説明した
    • 試した解決方法をリストアップした
    • 参考文献をリストアップした
  • メールを送れば答えを忘れないようにメモを取った

「ただの常識じゃないか」と思われる方もいらっしゃるかもしれません?残念ながら、人付き合いが本当に苦手な方ならご理解いただけると思いますが、「話すのが普通の怖い」という段階に至ると常識なんてただの言葉ですよ。だからこそ規則が必要になります。

自己分析を行う

自分自身の長短所を意識することで、後からもらうフィードバックをより深く処理できると考えます。また、自分の長短所のいずれかを分析すれば、もう一方を必ず分析しましょう。これにより、自分の性能に対する偏見を減らすことができるかもしれません(心理学の論文を調べたわけではありませんが、多分そう)。

私の長所は:

  • Web開発の基本はできている
  • 問題解決が好き
  • 時間管理
  • SNSを一才使わない

私の短所は:

  • 集中力
  • 必要な時にも休みを取らない
  • コミュニケーション回避
    • ゆえに、同僚との関係が浅く、チームに対する忠誠心は育てにくい
  • SNSを一才使わない

率直なフィードバックを求める

一部、Indeedの記事を参照しました。

  • チームのミッションをサポートするために、何を改善すべきですか?
  • 仕事のパフォーマンスを向上させるためには、どのようなスキルを身につけるべきですか?
  • 今後のプロジェクトに向けて、どのように準備すればいいですか?
  • 私が一番よく犯す間違いはなんですか?
  • 上級エンジニアになるためならなんでもします。教えてください、私はどうしたらいいでしょうか?

さらに聞くべき:

  • 何か手伝えることはありませんか?誰もしたくない課題や雑用はありませんか?

コミュニティと繋がる

コミュニティと繋がる一番単純な方法はStackOverflowなどで質問を投稿する事です。いい質問をするためのガイドが乗ってあり、非常に取っ付きやすく感じます。

より率直な答えを要する場合、Redditをおすすめします。

#100DaysOfFeedback

コミュニケーションが苦手な人なら、かなり明確にしたルーティンを用意しなければ、いずれ挫折します。#100DaysOfCodeコミュニティでは、日毎に旧TwitterとGitHubに自分の進歩を告げ、他のメンバーの進歩を再投稿するだけです。こういった行動により、最低限の所属意識と責任感が生まれます。しかも、100日連続コーディングもできます。
代用アプリ:Habiticaでパーティーと共に習慣をつけます。

さらにルールを設けましょう:

  • 毎日フィードバックをもらわなくてはいけない
  • フィードバックとは:あるやり方を修正・改善するために他人から得た助言(つまりコードレビューとペアプログラミングもOK)
  • フィードバックとみなさないもの:「〇〇をするためのDockerオプションって何」のように、仕事のやり方と関係のない質問
  • 十分フィードバックを求めた上で、どうしても得られなければそれでもOKとする
    • 「十分求めた」:少なくとも二つの場所・サイト・アプリで、あるいは合計3人に求めれば「十分」とみなす

オープンソースプロジェクトに貢献

OSSに貢献に貢献することで、あなたの感情よりもプロジェクトの状態をはるかに重視する人間に出会うことがあります。自分のコードの質に関するさまざまな汚い言葉を放り投げられる中、プログラム設計やOSSの理念をめぐる有益な会話ができます。

初貢献のために必須になるのはAwesome First PR Opportunities(初心者でも簡単に貢献できるプロジェクト集)

指導者を見つける

全てのジュニアは尊敬にあたる指導者に従い、厳しい指導を受けた末、自己超越の達成を望んでいることが私の持論です。そうでないと、私だけになりますから。

まずは、指導者を見つけましょう。先輩や同僚以外、 勉強したいことに関連するコミュニティを訪れ、投稿数の最も高いユーザーを見つけることもできます。この方はネットワーキング効果もあるかもしれません。

次に、相手の時間を意識しながら、個人プロジェクトの訂正を依頼しましょう。

あとは、関係を維持しましょう。多分2週間おきにメッセージ・質問・訂正依頼すれば良いでしょう。でしょう?正直、今まで高校・大学時代の友人との関係維持に失敗しまくってきましたので、私からすればこの問題は未解決です。

まとめ

私は自分のくだらないコミュ障に操られるためにこの世に生まれたのではありません。

Discussion