Accepting The Funny Mediocrity

2 年前に書いた Having Fun on The Dead Carrier は思ったより正しかった。けれどまだ板についていない。

8 年くらい前、それまで Web に傾倒していた反動で Android アプリプログラマに鞍替えした。結局モバイルはそれほど好きでないと思いつつ今日に至っている。ML やクラウドといった世の流行りに沿った仕事ができる日はこないだろうし、勤務先はともかく一般にモバイルエンジニアの給料は低い。だから異業種も同業種も転職のあてはない。なら今の職場で出世できないかと頑張ってみたが器でないことがわかった。

もはや仕事には大きな変化を期待していない。今のような業務が、少しずつ姿を変えながら、少しずつ給与を下げながら、ずっと続くのだろう。続くならまだいいが、勤務先でもレイオフが起きた。もはや継続性すら疑わしい。レガシー分野のプログラマ、将来が不安。

日々の業務が嫌というわけではない。チームを移ったばかりで ramp up するストレスはあるにせよ、理不尽なことにイライラしたり退屈すぎてうんざりといったことはない。ぼちぼちコードをかいて、ミーティングとかで人と話したりして、他人のドキュメントやコードをレビューもして、定刻に職場を出て家に帰る。20 代や 30 代のような熱意はないが、嫌でもない。コードを書いて何かが動けば多少の満足はある。レイオフは、今のところやり過ごせた。日々は平凡なりに滞りない。

憂鬱なのは将来を考えるときだ: 大きなことを成し遂げることはないだろう。大きな何かに立ち会うこともない。かつてのように夢中で働くこともない。でも、それがキャリアの帰結なので仕方ない。ぱっとしませんでした、残念でしたね。というだけ。

スキルがレガシーで、特定大企業に最適化されていて、その企業の先行きは不安。しかし現代的で勢いのある職場・職種に鞍替えする資源やリスク予算がない。息苦しい。「仕方ない」とは言いたくないが、自分のパラメタを鑑みて現状を選んでいる。より良い答えは特にない。ぱっとしない中年、将来が不安で息苦しいですね、というだけ。

一年の終わりやはじまりに我が身を振り返り将来を思うと、憂鬱が露わになる。それをを拭うことはできないかと考え、できないと思い至り絶望する。何度も何度もこれをループして時間を溶かし、心をすり減らせる。不毛。


業務でない課外活動は将来への準備だと思っていた。けれど準備が実ったことはない。大した準備もできなかった。少しばかり課外活動をしたくらいで将来有望な仕事に鞍替えできはしない。暇も体力もない自分が、暇で元気な若者が注ぎ込む湯水のような時間の勢いに競り勝てるはずがない。(これはぱっとしないなりに結果を出した裏返しでもある。全てを投げ出し新しい分野に掛け金を突っ込むよりは目先の仕事を続けたほうがマシと考えているのだから。)

新しい仕事のために新しいテクノロジを学ぶ – そんなファンタジーがなくなると「将来への準備」はただ気が重い。出世のための本を読む。LeetCode でレイオフに備える。希望を呼び起こしてくれた課外活動が、不安と憂鬱を反芻する時間になる。とても続けられない。無念や不安と毎日向き合う根性は無い。

準備はもういやだ。キャリアの残念さや、将来の不安や、根性のなさは受け入れるから、課外活動くらい楽しいことをしたい。それが Having Fun on The Dead Carrier だった。この結論は今も変わらない:

職業プログラマとしてのキャリアが冴えない結末を迎えるとしても、迎えるからこそ、そのキャリアを通じて発見した価値を大切にしたい。新しいテクノロジを触る刺激。コンピュータサイエンスのセンスオブワンダー。プログラミングの充足感。枯れ果てた未来の水やりに追われてこの美しい園を失ってしまったらあまりに悲しい。

日々の業務はきんとやるとして、その外では楽しいこと、役に立たない学びのあることを好きにやる。課外活動は将来のキャリアへの準備ではなく、キャリアから得た楽しみの養生。この二つが交わらないのは残念だが、交わらない以上どちらかを選ぶ必要がある。


トレードオフ。

課外活動では、被雇用準備による将来収入の改善という金銭的な利得を、価値観の養生という Well-being と引き換えている。根性がなく、頑張ってなにかやるのが高く付く(頑張れない)のでこのトレードオフを選んでいる。

昼の仕事では、やりがいや裁量といった個人的な関心を引き換えに、払いの良さという金銭的な利得と9時5時労働という時間的な利得を選んでいる。家族を養う稼ぎの必要性と家事子守という家庭の責務からこのトレードオフを選んでいる。

この二つを組み合わせると、昼の仕事で金銭を選ぶ代わりに課外活動で金銭以外を選んでいるとも言える。トレードオフとしては妥当な範囲と言えるんじゃないか。

トレードオフが必要という事実、つまり仕事のやりがいと収入が両立しなかったり、課外活動の充足と将来の準備が両立しないのは残念だが、それがまさにキャリアの失敗であり、ぱっとしなさなわけじゃん。それを無視してうまく行っているフリをしたら、家庭や Well-being や金銭を予期せぬ形で損ねてしまう。金銭は家庭や Well-being の足場なので、結局は家庭と Well-being を選んでいる。書いてみるとあたりまえの話だった。


もっと根性や計画性や先見の明があってキャリアをうまく積み上げられればよかったとは思う。けれどそうした後悔で日々を惨めなものにしたくもない。だから Have Fun と繰り返し言い聞かせ、選んだ現実を日常に塗り重ねていく。

In 2020s, Don’t Listen to Java Haters

To me, the book “A Philosophy of Software Design” was hard to go through.

An example of many frustrations: When talking about a hypothetical HTTPRequest class, the author first shows the “bad” version of an API:

public Map<String, String> getParams() { … }

And criticism is:

This method is shadow, and exposes the internal representation used by the HTTPRequest class to store paramters. Any change to that representation a change to the interface, …

Okay, what’s the alternative then?

Here is a better interface for retrieving parameter values:

public String getParameter(String name) { … }
public int getIntParameter(String name) { … }

getParameter returns a parameter value as a string. It provides a slightly deeper interface than getParams above; more importantly, it hides the internal representation of parameters. getInParameter converts the value of a parameter from its string form in the HTTP request to an integer. This saves the caller from having to request string-to-integer conversion separately, and hides that mechanism from the caller. Additional methods for other data types, such as getDoubleParameter, could be defined if needed.

Ouch.

  • If you are bothered by converting String to int, you shouldn’t program in Java1. Whether you like it or not, composing small methods is a way to write Java code. Going against the community norm has a price, and the author doesn’t seem aware of it.
  • Talking about awareness, I’m not sure the author is aware that Map is an interface and doesn’t have to be an “internal representation”. This signals the insufficient competence of the author as a Java programmer.

There are a lot like these. Zooming out, the hate for the convention of the Java community, and some of today’s programming practices (which are more modern than Java’s) permeates throughout the book. It seems that the author is primarily using C++. Also, his suggestions feel more applicable to C++ than to Java.

If so, the author should have used C++ instead of Java. If you don’t like Java, why bother? Everyone knows it’s a language out of fashion. Maybe the author thought Java was still more appealing than C++ to the general audience or their students? I have no idea.

Because of this dissonance, I have a hard time trusting the author – If the author thinks they know what they actually don’t, are his claims actually trustworthy?


But for the sake of a better review, let me mute my loud disbelief.

The problem with this book is that it claims the suggestions are generalizable when they don’t. Each programming language has its own trade-off, from the grammar to the runtime to the ecosystem. Things that matter for C++ won’t matter in Java, Python, or more modern languages.

My sense is that the suggestions in this book aren’t even appropriate for today’s C++. However, it makes more sense for thicker API boundaries like OS system calls and RPCs/REST where type systems are limited and programming language matters less. Ideas like “Deep module” and premature generalization can shine in this worldview.

This observation aligns with who is praising the book: Apparently, people around distributed systems and infrastructure platforms like this book a lot. In that world, the programming language does matter less: Things are polyglot and the boundaries between modules are thicker there.

On the other hand, to someone who works on a big monolithic code base written in non-C++, this book is baffling.

If this book were titled something like “A philosophy of platform modularization and API design” and was written with that focus, dropping all the irrelevant rumblings, it could have come out great and I might have loved it3.


It is OK to write code with minimum utilization of the language-specific features. Such an attitude was common until the early 2000s when the mainstream languages were poor. It is still okay sticking that same style today, but I don’t think that is what a reader expects from a book published around 20202.

Also, it’s fine to criticize Java. In the late 2000s, there was a large disappointment in Java. It accelerated the adoption of “lightweight” languages like Ruby, Python, and JavaScript. It also prompted the rise of modern statistically typed languages like Go and Kotlin.

But if you do criticize, do it well. What “A Philosophy of Software Design” did is less than talking two decades past. As a reader, I expect something better.

Talking about the reader’s expectations, chapter 19, “Software Trends”, is truly a killer. Why are you talking about OOP, Agile, and Design Patterns as trends now? Pleaaase!

Footnotes

  1. You should use Kotlin – I’m kind of kidding.
  2. The first edition was published in 2018.
  3. Here is another and narrower criticism of this book I wrote before. I won’t write another one.

Link: “The worst part of this is that everyone at GitHub is now forced to use Microsoft Teams.”

The worst part of this is that everyone at GitHub is now forced to use Microsoft Teams.

GitHub to layoff 10% and closing all offices | Hacker News

I haven’t used Teams and am not sure why it gathers that much hate. I’ve been “forced” to use Google Chat. It’s not as good as Slack I guess, but I’m fine with it.

Why do people love Slack so much? Do you like workspace chat in general? I like group chat but only if it’s private and among friends.

A Corner to Breathe

I haven’t taken a “real” break at work since I moved to the new office. The building of the new office is small and packed. It doesn’t give me either space or anonymity. The real break needs both – You need space where no one notices you, where you can take a breath and let your mind dress down.

Luckily, or by design (to the credit of the employer), there is always space. Many buildings have a few corners with sofas or stools. What’s missing is anonymity. So I walked to the building next to my new office, lurking around, and found this:

This is the perfect corner to have a break:

  • Nobody in my team will come here. Nothing fancy is around.
  • Nobody is stopping here. People tend to choose somewhere close to drinks and snacks. It’s on the other side of the building.

This place is too bland for the tastes of many, and that creates the anonymity I need. It has moderate foot traffic and therefore is not super silent, but that’s fine. I’m not asking much. Or I can keep searching for even more perfect corners if I desire. For now though, this will suffice.

When you move, you lose something subtle you don’t notice. You might need a checklist to pick it up again, and this is the first item of that list: Find a corner to breathe.

Peak and Bubble

During the tax return prep, I found my total income declined 10+ percent last year. This is primarily because of the stock price drop.

Next year or the year after, my income will fall, possibly another 10+ percent, this time because of lower performance ratings1. I had a long tenure in my last team and my previous manager gave me a high rating. As I moved to a new team starting a new role, the good rating is unlikely to sustain.

This is not a pessimism. It’s just a phase I have to go through. It happened the last time I moved, although, unlike this time, the stock growth softened the impact. That won’t be the case this time.

A slightly pessimistic twist: I’m not sure if I can “recover” my rating. I think my nice rating reflected a good opportunity I had, which is not common these days in hindsight. Also, my energy level has fallen for years. I’ll do my best to keep up, but don’t expect much.

This means that: 2021 was probably the year when my income hit its peak. I won’t see that price tag again in my career.

This might sound sad, but I am not that disappointed. I rather feel a kind of gratitude. The tech sector has been in a longstanding bubble, and we are all the tulips. I’m glad I was able to experience this bubble. It wouldn’t have happened if I wasn’t here. This is a sheer fortune.

And now, the party is coming to an end2.

The bubbles did feel nice. They were just a bit slippery, as are their residues. From now on, I have to walk a bit more slowly so as not to stumble.

Footnotes

  1. In addition to an extra stock price fall which is pretty much possible.
  2. Another party is starting, but I don’t think I’m in the room.

Link: Ask HN: Suggestions for working effectively with junior devs at FAANG | Hacker News

I’m a senior dev at one of the FAANGs with more than 15 years of experience, but the rest of my team consists of devs with an average of 2 years of experience. At first when I joined, I thought this was an aberration, but there are many teams around me that are structured similarly. Is this how FAANGs try to scale teams?

Ask HN: Suggestions for working effectively with junior devs at FAANG | Hacker News

The top comment:

And in general, there are two ways to go. The first is to accept the fact that many senior engineering and most staff engineering gigs are more about this kind of mentorship approach than actually doing work. And basically accept that the prime “getting shit done” years of your career are done and you will mostly be working in this new way now.

Unfortunately you will either need to change your attitude or change teams. In y… | Hacker News

One day I pointed out the massive amount of the code and design doc reviews the TL of my team is conducting every day, to the TL himself. His response was something like the top comment.

According to him, he used to do everything but that wasn’t sustainable. He was told to “delegate”, and in my guess, to mentor. That is what he’s doing these days.

I cannot articulate what I think here. He’s a good mentor, a good lead, and I appreciate that, but…?