概要
非情報系出身ということもあり、データ構造とアルゴリズムという領域にあまり馴染みがなかったため、とりあえず初心者を脱却するためにLeetCodeの問題を解いて記事を書く、という活動を100問続けてみました。
100回というのはキリが良さそうだったのと、Googleに新しく始めたことを継続するといいよ!って言ってる人がいたので参考にしました。(こちらは30日間ですが・・・)
この記事では活動を続けることで得られた知識や発見について書いて行こうかと思います。
なお、活動記録が見たい方は以下がまとめページとなっています。
Python3で解いています。
ひとまず100日間続けたので、Qiitaでの記事投稿はやめて、個人の技術ブログでのみ更新していこうかと思います。
で?LeetCode解いてアウトプット続けてなんか良いことあった?
やっぱりこの記事を読んでいる方が気になるのはここだと思います。
毎日解いて記事を書き続けてここは良かったなぁ、という点について触れていきたいと思います。
データ構造とアルゴリズムの知識が付く
これがLeetCodeを解き続けることで得られる最も大きなメリットかと思います。
僕自身、コンピューターサイエンス周りの専門的な教育を受ける機会がないままにIT業界へと入ってきたので、こういった知識を持っている方々とお話をする上で知っているのと知らないのでは大きな差が生まれる、と感じていました。
知らないまま業務を行っていると、データのソートの仕方一つとっても非常に非効率的な方法を使っている場合が多々あります。例えば、とある現場ではググってとりあえず出てきたソート法をそのまま使っているため、非常に非効率的なソートの仕方がコードとして残っており、担当者がパフォーマンスチューニングをする際にそのソースコードを見た時に愕然とした、ということを他社の方から聞いたことがあります。
計算量や原理を知ることでそういった致命的な失敗を避け、より効率的に業務を遂行出来る様になる・・・かもしれません。
(実際はみんながみんなそういった開発等に関わるとは言い切れないため、ここでの断言は避けておきます)
コーディング面接でどういうことをやるのかを身をもって体験できる
これはいわゆる技術的に尖っている会社でキャリアを積みたい方にとっては興味深い話ではないでしょうか。
多くの外資系IT企業や国内のメガベンチャーなどの優秀なITエンジニアが集まっているとされている企業では、志望者に対して技術的な知識量を測るために面接の一環としてコーディング面接、というものを行います。
これは、面接官が適当な条件を与え、志願者がそれを解決するために面接官とコミュニケーションを取りながらホワイトボードや用意されたPC上にプログラムを実装する、というものなのですが、LeetCodeは元々こういった面接の対策を行うためのサイトとして広く知られています。
LeetCodeの特徴としては、
- 実際にGAFAMの面接で出題されたような問題が1000問以上閲覧できる(問題によっては課金する必要があり)
- 志願者がどういうフローで内定まで至ったか、もしくは落ちたかの体験記を閲覧できる
といった志願者の生の情報を得られる、というところが非常に良い点だと思います。
一般的な正攻法としては普段は無料の問題を習慣的に解き続け、面接を受けることになったら課金をして面接対策用の問題をアンロックして直前まで解きまくる、というのが多いようです。
どの問題を解いたか、そして難易度やどういったものを解いたのかを以下のような形できちんと管理してくれているので、管理自体はしやすいです。
例えば、僕の活動記録はこんな感じです。
(2020/7/20時点)
ちょいちょい穴があるのは問題を解くだけ解いて後から解説記事を書く、みたいな形式を取っていた時期があるためですね。
また、何回も提出しているのは速度を改善させるために色々と書き直したりして試しているためです。
どこかで見た情報なのですが、中国からGAFAMやUber、Airbnbなどの有名なテックカンパニーに入ろうとする人は400問くらい解いてから応募するらしいです。それも僕よりも短い期間で解いたりするらしいので、受験の時の過去問対策みたいな感じですね。
なお、上記のいずれかの企業でソフトウェアエンジニアとして勤務している方にどれくらいのレベルまでやれば良いのか、という話を聞いたことがあるのですが、Medium程度の問題を何も見ずに実装できて、そのアルゴリズムについて十分ディスカッションできるレベルであれば知識的には十分だそうです。
Hardクラスの問題が出ることもあるにはあるが、大体の人はそんなにすらすら書けないし、時間も足りないため、その場合は面接官としっかりコミュニケーションを取り、その上で要件をしっかりすり合わせながら書いていくことが好ましいようです。コミュニケーション力大事!!
単純に解いていて楽しい、そして反応があると嬉しい
一日一問解いて記事を書く、という活動が100日も続いたのはここに大きな要因があるかと思います。
このLeetCodeというサイトは上手くできていて、難易度でいうと、
-
Easy
-
Medium
-
Hard
といった風にカテゴライズされているのですが、ここの難易度の調整が絶妙です。
例えば、Easyの問題を解く上で必要とされている能力は数学的な要素はほとんど必要なく、書くプログラミング言語の条件分岐や繰り返しの処理、そして組み込み関数やライブラリについての知識を知っていれば解ける問題がほとんどであり、僕のようなそこまでデータ構造とアルゴリズムに関して知らない初心者でも楽しく解くことができました。
実際1行で解けるような問題も多々あります。ぱっと見で何をしているのか分かりづらくはなりますが。
次のMediumに関してですが、ここから次第に中学受験的な算数や、高校数学の要素といった知識が必要とされてきます。
これらの問題の多くは、知識があると簡単に解法を思いつくが、知らないとめちゃくちゃ非効率的な思考法に陥る、というような特徴があります。ただ、多くの場合基本的な確率や整数などの知識をささっとおさらいすれば大丈夫ですし、問題を解いて慣れていけば典型的な問題は解けるようになっていきます。
僕は最近ここら辺を重点的に解いています。
最後のHardに関しては、正直そこまで解いていないので詳しい説明はできませんが、Mediumまでと比べるとより複雑な条件を与えられるので、書くコードの量が増えます。それ故にMediumまでの問題と比べると解くのに時間がかかります。
この解く時間がかかるというのが限られた時間でレビューまで行う必要性がある面接では出されにくいという要因にもなっているため、無理してHardを解くよりはMediumまでの基本的な問題を解いた方が面接対策としては有効かもしれません。
ただ、Mediumじゃ物足りないからもっと面白い問題解きたいんだよね・・・という強い人にはおすすめです。きっと楽しいですよ!
そしてPython3で解いて解説記事を書いてください、僕が読みたいので。
単純に与えられた要件を頭を使ってあーでもない、こうでもない、と試行錯誤をして良さげば解き方をコードに落とし込む、というのは楽しいですし、解いた問題の管理等もしてくれるので、楽しく勉強が進められるのはとても良い、と思います。
問題数は現時点で1521問(2020/7/22時点)で、しかもテーマ別で分類されていたり、実際にここで対策をしてGoogleなどの企業に入社した方々が問題集を作ってくださっていたりするので、そういったテーマに則って解いていくのも楽しいかもしれません。
投稿することへの苦手意識がなくなる
アウトプットすることが基本的には推奨されているITエンジニア界隈ですが、なかなかアウトプットに踏み切れない方も多いと思います。
僕もそうだったのですが、ある時、某Rubyのパパの講演会に参加しました。
その時に印象的だったのが、YouTuberの話でした。
簡単にいうと、誰でもYouTuberにはなれるが、心理的な抵抗からやらない人が多い。それと同様のケースを技術者に当てはめてみると、自身の技術的な未熟さなどからマサカリが飛んでくることを恐れてアウトプットをしない人が多いので、アウトプットするだけで差別化が図れる、そして続けることで苦手意識がなくなり、さらにアウトプットをする。それがずっと続くと特定の分野で自分しかできないことが生まれる、という話です。
そして実際に100日間アウトプットを続けてみましたが、これは事実でした。
始める前は迂闊なこと書いて炎上したらどうしようとか色々とやらない理由を考えていましたが、活動を続けていく内に、そもそも多くの人はそこまで自分に興味がないことに気付きましたし、同時に、本当に興味がある人はただアウトプットを続けるだけでもしっかり見てくれている。
そしてそういうのを積み重ねていくことで次第に個人として成長していく、ということなのだと僕は感じました。
ただ、毎日問題を解く、というのは比較的簡単なのですが、毎日こうやって解いたよ!というアウトプットまでするのは億劫な日がどうしてもあります。
そうなった時にも大丈夫なように僕は
- 問題を解ける時にできるだけストックを溜めておく
- 記事のテンプレートを用意して書き換えが必要なところをできるだけ少なくする
- 朝早起きして、早い時間に記事を完成まで持っていく
というようなルールを作り、できるだけ後回しをしない、楽をできるところは楽をする、というようにしていました。
実際記事の投稿が億劫になり、かなり夜遅くになることもありましたが、実際に決めた期間を完走できたのでそこらへんも今となってはいい思い出です。
#逆にここがイマイチ
個人的に感じていたイマイチポイントは一つだけです。
- 日本では人口が少ないので誰かとワイワイしながらやる感じではない
という点です。
最近、特に競技プログラミング、特にAtCoderが盛り上がっており、週末にAtCoderなどを楽しんでいる方をTwitter上でよく見ます。
僕はAtCoderを含む競技プログラミングというフィールドには過去問をちょっと解くくらいでしか関わったことがないのですが、コンテストが行われた後には強い人から初心者までワイワイ情報共有をしているのをよくみます。
やはりモチベーションというのは周りにやっている人がいるか、といった競技人口にある程度左右されるものでしょうし、多くの場合誰もやってないよりはやっているものの方が楽しそうに見えるものです。
例えば、Qiita上でのタグ付けされた記事の投稿数をAtCoderとLeetCodeで比較してみると、
-
AtCoder:2242件
-
LeetCode:543件
(2020/7/22時点)
この内、僕が投稿したLeetCodeの記事がおよそ100件程度あることを考えると、かなりの差があることがわかります。
こればかりは積み上げてきたものがあるでしょうし、AtCoderのコミュニティ作りの上手さやそれに参加している方々のレベルの高い解説記事があるのは新しく始める方からすると安心できる材料だと思うので、解説がほとんど英語や中国語であるLeetCodeが遅れを取っているのは仕方がないのかもしれません。
また、競技プログラミングの基本的な属性として、みんなで同じ時間に同じ問題を解く、という同時性が存在するというのも大きな点かと思います。
LeetCodeにもContestというものがあるのですが、こちらを知っている方はあまりいない印象があります。
(日本勢で積極的に参加していてランキング上位の方もいるのでゼロ、というわけではない)
なので、みんなでワイワイやりたい場合は現段階では間違いなく競技プログラミングの方がおすすめです。
逆にいうと、今はまだまだ解説記事を書いている人口が少ないのでアルゴリズム、データ構造ガチ勢の方が解説記事を丁寧に書けば日本のLeetCodeコミュニティでかなり突出した存在になれると思います。
そして僕のような初心者が毎日投稿することで、投稿する行為自体のハードルはかなり下げたと思うので、是非気軽に記事を投稿していただけるとコミュニティが活性しますし、何より他人の書いたコードや解説を見るのはとても勉強になるので読みたいです。
あとはコンテンツが全て英語なので英語が苦手な方にはしんどいかもしれない、というのもあるかもしれませんが、最近では翻訳ソフトも進化していますし、最悪問題文を翻訳にかけてしまえば分かるようにしてくれるので英語に対して苦手意識があってもある程度は大丈夫です。
まとめ
長々書いてしまいましたが、技術的にはアルゴリズムとデータ構造の基本的な知識を得られて、そして心理的にはアウトプットへの抵抗心をなくすことができた。これだけでも大きな収穫でした。
そしてこんな記事を最後まで読んでくださってありがとうございます。
AtCoderなどに比べると国内でのLeetCodeの存在はそこまで大きいものではないですが、僕みたいな初心者でも楽しく学ぶことができたので、気になる方はぜひLeetCodeの問題を解いて解法などを共有してみてください!
きっと楽しいですよ!