1x Engineer

何かの折で見かけたこちらのページなのですが、探してみると和訳がなかったので和訳することにしました。

一見、平凡なエンジニアであることの自虐であるかのように見えますが、実態は、本文中でも言及されている 10x Engineer に対するアンチテーゼ、そしてそれを吹聴する人々への反発です。

1x.engineer

今でも更新が続けられているようで、以下の和訳はコミットハッシュ 71821ac の断面になります。また日が開いて本家が更新されたら、和訳も更新しなおしましょうかね。

以下和訳です。もし間違えていても、責任は負いかねます。ごめんね。
原文英文を引用符でくくって、その下に和訳を書いていきます。


What is a 1x Engineer? You might have already heard of a 10x engineer. Probably too often, actually. If there's such a thing as a 10x engineer, surely there must be a 1x engineer, too?

Of course there is! Let's dig into a non-exhaustive list of what qualities make up a 1x engineer.

1x Engineer とは何でしょうか? 10x Engineer でしたらあなたも耳にしたことがあるかもしれません。実際のところ、頻繁に耳にしたことがあるかもしれません。もし、10x Engineer なんてものがあるとするならば、きっと 1x Engineer も存在するはずじゃないでしょうか。

その通り。存在します! どんな性質が 1x Engineer を作り上げているのか、その一例を掘り下げていきましょう。

A 1x Engineer...

1x Engineer は...

Searches Google, Duckduckgo, Bing, or wherever they like when they're not sure what's up.

何が起きているかわからないとき、GoogleDuckDuckGo、Bing、その他自分の好きな検索エンジンで検索します。

Copy/pastes code snippets from Stack Overflow, Glitch, Codepen, or wherever they find answers.

Stack Overflow、Glitch、Codepen、そのほか、解答を見つけた場所がどこであれ、そこにあったコードスニペットをコピペします。

Gives credit where credit is due.

認めるべき功績を認めます。

Creates community and shares knowledge.

コミュニティを作り、知識を共有します。

Spends time on things outside of engineering, like hobbies, friends, and family.

エンジニアリング以外の物事(趣味や友人、家族といった)にも時間をかけます。

Has a schedule that allows them to maintain a healthy work-life balance, and respects others' time-boundaries, too.

予定を守ることで健康的なワークライフバランスを保つことができ、同様に他人の時間的な制約も尊重します。

Isn't measured by arbitrary contribution scores on any website, and doesn't judge others for theirs either.

あらゆる web サイトのどんな貢献度スコアによっても測られることはなく、またそれによって他人を判断することもありません。

Writes code that — gasp — has bugs.

バグがあるコードを書きます。

Writes code that others can read.

他人が読めるコードを書きます。

Reads the Docs.

ドキュメントを読みます。

Updates the Docs.

ドキュメントを更新します。

Doesn't need to be passionate about the code they write or the problems they solve, but may be.

自分の書くコードや、取り組んでいる問題に熱心になる必要はありません。しかしながら、熱心になることもあります。

Doesn't act surprised when someone doesn’t know something.

誰かが何かについて知らなくても、驚くことはありません。

Is willing and able to collaborate with others.

他人と協力することができ、そうする意思もあります。

Publicly celebrates others for their wins.

他人の成功を公的に称賛することができます。

Ask questions before providing critical feedback.

批判的なフィードバックをする前には、いくつかの質問をします。

Gives tough feedback privately.

厳しいフィードバックは、他の人に見えないように行います。

Treats others how they would like to be treated.

自分がして欲しいように、他人に接します。

Provides code reviews and feedback to their peers that are constructive, helpful, and presented tactfully, helping their peers to grow personally and professionally.

建設的かつ有用かつ巧妙な表現で、同僚が個人的にそして職業的に成長するのを手助けできるような、コードレビューとフィードバックを行います。

Expresses appreciation for code reviews and feedback from their peers that are constructive and helpful.

同僚からの、建設的で有用なコードレビューとフィードバックに感謝します。

Sometimes feels hurt by critical feedback, but doesn't react destructively.

ときには、批判的なフィードバックには傷つくこともあります。しかし破壊的な反応はしません。

Sometimes takes short breaks to clear their head.

頭を整理するために、短い休憩を取ることがあります。

Makes mistakes from time to time, and finds growth in those mistakes.

何度も何度も失敗をします。が、その失敗の中から成長していることが見て取れます。

Willing to admit when they're wrong, and aren't afraid to say "I don't know."

自身の過ちを認めることができ、「わかりません」ということを恐れません。

May or may not like writing documentation, but does it anyway for future maintainers.

資料を書くのが好きでも好きではなくても、未来にメンテナンスをする人のためにそれを書きます。

May or may not like writing tests, but tries to learn to do so if the team or project needs it.

テストを書くのが好きでも好きでなくても、チームやプロジェクトでそれが必要ならば、それができるように努力します。

Thanks others for their time, effort, and energy.

他人の時間、努力、気力や行動力に感謝します。

Can have colorful desktop backgrounds.

デスクトップの背景をカラフルにすることができます。

Supports code in production, even if they did not write it.

たとえ自分が書いたものでなくても、本番稼働しているコードを保守します。

Can feel like an imposter at times, and understands others may, too.

時には、自分が詐欺師であるかのように感じてしまうことがあります。他人もそうであることを理解しています。

Believes that everyone in the room is equally as smart and capable as they are.

同じ部屋にいるみんなが、同じくらい賢く能力のある人だと信じています。

Will help level-up others, and asks for help when they need it.

他人の能力向上を手伝うことができるし、必要なときは、他人に助けを求めることができます。

Never stops learning, but can feel totally overwhelmed by the amount of learning there is to do.

学びを決して止めません。しかし、学ばねばならばい事柄の総量に完全に圧倒されてしまうこともあります。

Tries to keep discussions productive and lets others have their say before the team makes a decision.

ディスカッションが生産的なものであるように努め、チームが決定をする前には他人の意見を聞きます。

Is willing to leave their comfort zone.

自分の殻を破る意思があります。

Contributes to the community in their own way when possible, and appreciates the ways that others contribute when they can.

自分の方法でできる限りコミュニティに貢献し、そして、他人の貢献の仕方の良さも認めます。

Can be a slow coder.

遅いコーダーかもしれません。

Has productive and unproductive days.

生産的な日とそうでない日があります。

Doesn't take themselves too seriously.

あまり深刻に考えすぎません。

Says, "I've never heard of that," in lieu of nodding and pretending.

頷いたり、分かったふりをしたりする代わりに、「それは聞いたことがないです」と言います。

Is trustworthy.

信頼に値します。

Works to live, rather than living to work.

働くために生きるというよりも、生きるために働いています。

Sometimes loses their work.

ときには、職を失います。

Doesn't have to have the entire codebase memorized.

全てのソースコードを覚える必要はありません。

Respects and upholds community Codes of Conduct.

コミュニティの行動規範に敬意を表し、支持します。

May work from home, the office, a coffee shop, or where ever else best works for them.

家、オフィス、コーヒショップ、その他もっともよく仕事ができる場所で仕事をします。

Doesn't hate on tools, processes, or languages that they'd rather not use, or that others are using.

自分が使いたくなかったり、他人が使っているツールやプロセス、言語を嫌いません。

Is not defined by the computer they're using.

使っているコンピュータによって定義されません。

May decorate their laptop and workspace in any way they like, and is respectful of others' decor (or lack thereof), too.

ラップトップや仕事場を、自分の好きなように飾り立てても構いません。同様に他人の飾り付け(や、逆に飾りがないこと)を尊重します。

Isn't defined by myopic Tweetstorms by clueless VCs.

無知な VC*1 達よる、近視眼的な Twitter の流行りによって定義されません。

Doesn't riddicule entire professions within engineering, especially not when in a position of leadership.

エンジニアリングに関わる全ての職業を馬鹿にしません。特にリーダーシップを発揮すべきポジションに就いているときは。

Notice something missing from the list? 1x engineers are often humble and willing to accept Pull Requests to fix mistakes. If you feel like you've got something that's missing from the list, feel free to open a Pull Request against the website's repo.

リストに不足しているものに気が付きましたか? 1x Engineer は多くの場合、謙虚なので、誤りを修正するためのプルリクエストを受け入れるつもりです。
もしリストに足りないものがあると感じたら、webサイトのリポジトリに遠慮せずプルリクエストを送ってください。


以上、1x Engineer でした。
GitHub の URL はこちら。 github.com

*1:何の略称か確証が得られていないですが、おそらく Venture Capital ?

Node.js, JavaScript 系アプリの雛型コードを公開しました

GitHub - katoufuji-banana/my-application-templates
お品書きは以下の3本立て。

サーバーサイド

  • ほぼほぼすっぴん Node.js アプリ(Babel 付き)
  • Express Web サーバー

クライアントサイド

  • React.js

よければ、皆さんの開発の何かにお役立てください。
では。

スクラムガイド バックナンバー

過去のスクラムガイドへのリンクが公式のダウンロードページから消えていたので、サルベージしてきました。

スクラムガイド 2020年 英語版
スクラムガイド 2020年 日本語版
スクラムガイド 2017年 英語版
スクラムガイド 2017年 日本語版
スクラムガイド 2016年 英語版
スクラムガイド 2016年 日本語版
スクラムガイド 2013年 英語版
スクラムガイド 2013年 日本語版
スクラムガイド 2011年(10月) 英語版
スクラムガイド 2011年(7月) 英語版
スクラムガイド 2010年 英語版

スクラム開発は銀の弾丸となるか?

お察しの通りこういうタイトルの書き方をしているということは、私の答えは No なんですけどね。 スクラム開発のメリットやそれが向くような条件はあります。ただ何もかもに有効というわけではないというのが私の答えです。

現在の職場では、スクラムによる開発を2案件連続でやりました。まあそのどちらもろくな終わり方しなかったのですが。

1案件目はどこから始まったのかはわかりませんが流れでスクラム開発をやっており、2案件目は会社として抱える諸問題を解決するための期待のフレームワークとして、スクラムが導入されました。

この経験と我流の分析を踏まえたうえで、スクラム開発はそれ自体が何でも解決してくれるフレームワークではないという話をしたいと思います。

スクラム開発を始めるにあたって

では、まずはスクラムガイドを見ていただいて。

こちらの資料にはスクラム開発のやること・作るもの・心構え・各々の役割が書かれています。この通りに、イベントを実施して各種作るものを作っていけば、スクラムという単語の定義上あなたはスクラムができたことになります。Conguraturation!!

スクラムをやってみたいという方でしたら、この記事はここまででよいと思います。やるだけならば公式ガイドでほぼ十分です。他にも気になるならば他の方々の体験談とかを読むのもおすすめです。

このフレームワークは何をもたらすのか?

続いて、スクラム開発がもたらしてくれるものを考えるために、スクラム開発ではどのような作業をしていくかを整理いたしますと、

  • プロダクトバックログの作成・更新
    Input:不定(市場状況など)
    Output:プロダクトバックログ

  • 作業可能なプロダクトバックログアイテムの選定
    Input:プロダクトバックログ
    Output:選定されたプロダクトバックログアイテムのリスト

  • スプリントバックログの作成
    Input:選定されたプロダクトバックログアイテムのリスト
    Output:スプリントバックログ

  • スプリントバックログの実行とデイリースクラム
    Input:今のプロダクト(初期値は無), スプリントバックログ, 開発に必要なリソース
    Output:新しいプロダクト

  • スプリントレトロスペクティブ
    Input:上記4つの作業の内容, 上記4つの作業の結果
    Output:改善された新しい4つの作業の内容

これらの Input と Output を良しなにつなげていくと、スクラム開発全体の Input と Output はこのようになります。

  • スクラム開発
    Input:不定(市場状況など), 今のプロダクト(初期値は無), 開発に必要なリソース
    Output:新しいプロダクト

...なんと、これではただのシステム開発です。

そう。そうなんです。ただのシステム開発なんです。 スクラム開発と非スクラム開発の違いは、内部での処理の分け方です。結局全体として支払うものと、手に入るものは変わりません。

スクラム開発は他の開発手法と何が違うのか?

仮にスクラム開発におけるスプリントをプロジェクト期間全体とし、プロダクトバックログアイテムの選定の際にすべてのアイテムを選定するならば、それは従来のウォーターフォール開発と変わりません。

逆にいえば、プロダクトバックログの一部の機能のみのリリースとする代わりに、リリースの期間を短くすることができるのがスクラム開発というフレームワークです。

この特徴が生きるのは、「プロダクトの価値の変化が激しい」市場となります。 昨日までは見向きもされなかった機能が脚光を浴びたり、逆に当初は皆に迎え入れられた機能がすぐに使われなくなったり。

裏返すと、「プロダクトの価値の変化があまり起きない」市場ではスクラム開発と非スクラム開発に優劣の差はありません。

もしあなたがそういった市場におけるシステム開発に従事しており、スクラム開発の導入を検討しているのならば、スクラム開発よりも慣れ親しんだフレームワークを選ぶほうが良いかもしれません。

スクラム開発に致命的な問題があるわけではありませんが、スクラム開発を学習するためのコストや、不慣れなフレームワークの中でのトラブルシューティングにより多くのコストをかけてしまうのならば、従来の手法を採用するほうが無難であると思われます。

またスクラム開発の注意点として、開発期間がスプリントの期間を超過してしまう機能をプロダクトに追加したい場合は、プロダクトバックログアイテムを小分けにしてあげる必要があります。そのための作業コストと、それにより本来実現したかった機能が実現できなくなるリスクが生まれる点はスクラム開発の明確な弱点です

不自然なイベント設計

そしてスクラム開発には通常のシステム開発に必須ではない項目として、スプリントレトロスペクティブがあります。スプリントレトロスペクティブがやろうとしていることはただの PDCAKPT 分析と変わりません。ただしそれが実施されるタイミングに問題があり、そのことがスクラムガイド上規定されてしまっているのです。

この類の振り返りに必要なのは適切な入力であり、スプリントレトロスペクティブの場合は「今回のスプリントはいい結果だったのか、悪い結果だったのか」です。そのための適切な指標が集められたうえでスプリントレトロスペクティブは開催されなければなりません。

スクラムのイベント上、スプリントレトロスペクティブが開かれるまでに得られるフィードバックはスプリントレビューしかありません。スプリントレビューで得られるのは、ステークホルダーの反応だけです。

プロダクトを作る目的は「そのプロダクトにより、市場からお金を引き出すこと」なのであって、「ステークホルダーが動くものを見て満足すること」ではないはずです。ステークホルダーがプロダクトの価値を正確に評価できない限りは、この2つは一致しません。

不適切な指標に基づく"振り返り"が実施され続けた場合、スクラムチームの開発がどのようなものへと変化していくかは、想像に難くないはずです。

スクラム開発のメリット・デメリット

つまりスクラム開発とは「頻繁にリリースを行う」ことができるフレームワークであり「ちょっと妙なタイミングで振り返りをする」フレームワークなのです。

別にスクラム開発によって品質が上がるわけでも、開発期間を短縮できるわけでもありません。 それは個々人の技術やノウハウ、またはスクラムとは別のフレームワークによってもたらされるものであり、スクラムがもたらすものではありません。

幸いスクラム開発は他のフレームワークと掛け合わせて実行することが可能ですので、唯一の制約である「定められた期間ごとのリリース」と競合しない限りは、品質向上のフレームワークであるとか、コスト削減のフレームワークであるとかと掛け合わせることができます。品質向上には品質向上のための、コスト削減にはコスト削減のためのフレームワークの導入をお勧めします。

もしあなたがスクラム開発を導入するとすれば、それは頻繁なリリースを行いたい場合のみです。他の目的のためのフレームワークを探しているのならば、スクラム開発以外のフレームワークの検討をお勧めします。

利益分配ゲーム!! いえーい!!

ちょっと仕事上思うことがあったので備忘のため。

問1
とある会社が新規システムを導入しようと考えています。
仕様は固まっており、そのシステムが導入されることで5000万円の利益が得られる見込みです。 あなたは、その会社のシステム構築を請け負おうとしているSIerです。そのシステムを構築するためのあなたの費用は1500万円の見込みです。
あなたは、案件の受注額を提示することができます。あなたの提示した価格でよければ、相手方の会社はその値段で案件を発注し、さもなければ案件は発注されず、両社とも0円の利益となります。
あなたは、受注額を何円で打診すべきでしょうか?

有名な問題で、答えは「5000万-ε*1円」ですね。 利益をほぼ丸々ぶん取れますね。ひでぇ。

問2
この商談に、ライバル会社である別のSIerが現れました。
その会社が同様のシステムを作るのにかかる費用は1200万円になる見込みです。 あなたの会社とそのライバル会社で同時に受注額を提示し、より良い条件を提示した会社(=提示額が低い方)に、案件が発注されることになりました。
このとき、案件を受注するのはどちらの会社となり、受注額はいくらになるでしょうか?

これも有名な問題で、答えは「ライバル会社」が「1500万-ε円で受注する」になります。 そんな価格で出されたら、こちらは赤字確定です。世知辛い世の中ですね。

問3
今度はシステムの仕様も提案できるようになりました。
あなたの会社がいくつかの追加仕様をいれてシステムを導入すると、発注側の会社は6000万円の利益が挙げられる見込みです。あなたの会社の費用は少し増え1800万円になります。 一方ライバル会社は以前と変わらず、5000万円のシステムを1200万円で作成します。
この場合どちらの会社がいくらで受注するでしょうか?

「2200万-ε円」で「あなたの会社」が受注します。おそらく。

問4
実は、相手方の会社は今回のシステム導入のための予算として2000万円しか用意していませんでした。予算をこえた額を提示した会社には、案件は発注されません。 この場合どちらの会社がいくらで受注するでしょうか?

「2000万円」で「あなたの会社」が受注します。むこうの予算で売るのが限界ですね。 というか2000万円で5000万円以上のものを買おうとする相手方企業、虫が良すぎません?

一般化すると、発注側企業の予算B、各社iの持つ提案jの価値をV_{ij}、費用をC_{ij}とした際、以下略。数式を書く気力が付きました。

言葉でいうと、

  • 費用が予算を超えている提案は最初にフィルターをかけて落として、
  • 価値 -費用でソートすると、
  • 案件を受注できる会社と、その会社の各提案が発注側企業に選ばれるための受注額の上限値が確定するので、
  • その中から案件を受注できる会社にとって最適な提案を選べば

OK です。

とはいえ、ここまでの議論には「入札前に、他社の提案の価値と費用が分かっている」というあまり現実的ではない仮定があるため、それを改善したものが以下になります。

問5
発注側企業は予算 B を提示する。これを受けた各社は、自社の提案すなわち、価値 V_i(B) と費用 C_i(B) および提示額 O_i(B) を決定する。これをもとに発注側企業は案件を発注する企業を決定する。
以下この操作を繰り返す。
この場合、案件を受注する企業およびその提示額はいくらに収束するか?

案件を受注する企業は入札前に他社の提案の価値と費用が分かっているときと同じ企業に収束するような気がします。提示額は初期値に依存するような気もします。*2

結局のところ改善したケースにおいても V_i - C_i が一番大きい会社と発注側の会社の二社のみが利益を享受し、受注側の会社の利益は入札に参加した他の会社の V_iC_i に依存する、といった結論になりそうです。

当然といえば当然で「価値あるものを、いかに安く作れるか」という至極当然な結論です。ただ、どーも弊社はこの点に関して新人に嘘を教えていそうだったのでいつかのために記します。

*1:微小量。以下同じ。

*2:あまり厳密な検討ではないので誰かが論文にしてくれていることを祈ります。読みます。

AtCoder Beginner Contest 162

AtCoder Beginner Contest 160 - AtCoder

結果:4AC(1WA)
3240 位。みなさん解くの早すぎません?

問題 A, B

特にいうことなし。

問題 C

いざ書いてみたら計算量 200 \times 200 + 200 \times 200なのに、ずっと頭の中で 200 \times 200 \times 200だと勘違いし続けて、時間を消費。

問題D

第一条件を満たすパターンから、第二条件を満たさないかつ第一条件を満たすパターンを引いた。後者のパターンは愚直に数え上げたが、なぜこれが計算量間に合っているのか検討がつかない。

問題E

問題Cと同じアルゴリズムを使うと、 O(k^{2} \times n)。そんなぁ。
解答見ました。計算量が10^{6}程度行ってそうに見えるんですが...?

問題F

思いついた解答の計算量 10^{6}程度行っちゃいそうだったので、時間もなかったのので撤退。
解答みました。どちゃくそ頭のよい dp で計算量 O(n)で答え出せるっぽいです。テーブル2つ作るのか...。

感想

うーん。
これはひどい

どうも、「計算量は 10^{6}まで行くと解けない場合がある」と思っていたのですが、W - 2.06.計算量曰く、

AtCoderの問題では実行時間制約が2秒くらいであることが多いです。 コンテストに参加する人は、1秒あたり 10^{8}回くらいの計算ができることを覚えておきましょう。

とのこと。どっかで覚え違いをしていたかもしらん。*1

反省。

*1:とはいえ、上のページは C++ 前提で書かれているようなので、Python では事情が違うことはあるかもしれませんが

AtCoder Beginner Contest 160

AtCoder Beginner Contest 160 - AtCoder

結果:5AC(1WA)
ほげーーー。グラフわからん。

問題A

言ってることそのまま式に。
うっかり添え字を1引き忘れてて提出するところだった...

問題B

500円玉の枚数を最大化。

問題C

一番間隔が広い家のペアを求めて、それらを始点・終点に。

問題D

ショートカットするかしないかの2ケースを検討すれば、頂点pから頂点qまでの最短距離が求まる。先に、全頂点の組合わせの最短距離を出して、そこから最短距離がkなのは何組って吐き出してAC。

問題E

ソートして切って、ソートして切って、ソートして切って、全部結合して、またソートして切って、sum関数にぽい。

問題F

解けませんでした。解説を見ましょう。

(中略)
後は、上記の木 dp を元に全方位木 dp を行うことで、O(N) でこの問題を解くことができます。

全方位木 dp 。知らない子ですね...。

OK。あした調べましょう。

感想

幸い問題Eが早い段階で解けていたので、まあまあな順位に滑り込み。久しぶりに、知らない単語が出てきたので、お勉強するぞー。おー。