Lambdaカクテル

ソフトウェア開発者です.玉石混淆です.

趣味のプログラミングから職業としてのプログラミングへ

この記事は,はてなエンジニアアドベントカレンダー2016の10日目の記事です.昨日は,id:dekokun によるVarnishによる一貫性を考慮した積極的キャッシュ戦略実験 - でこてっくろぐ ねおでした.今日は学生向け!フレッシュ!

こんにちは.はてなでアプリケーションエンジニアとして働いているid:Windymeltです. 今年の春から新卒として入社し,ようやく業務に慣れてきたものの,今までとはまったく違う環境での新生活に,ちょっぴり不思議な気持ちを味わっています.

私がソフトウェアエンジニアとして働いていることを知ると驚く人がいます. 私は法律系の学科を卒業しましたが,情報系の学科でないにもかかわらずソフトウェアエンジニアとして働いていることが意外に思われるようです. とはいえ,私は現在Scalaを主と使ってサービス開発に携わっており,日々なんとか設計とコーディングの経験を積むべく悪戦苦闘しています.私自身,実はソフトウェアを書く職に就くとは思っていなかっただけに,巡り合わせとは奇妙なものだなと思います.

この記事では,最初に趣味としてプログラミングに親しんでいた私が職業としてプログラミングをするようになった事で感じたいくつかのエピソードを紹介し,そしてこれからソフトウェアエンジニアとして働きたいと考えている学生に向けて,なかば備忘録として知見を紹介したいと思います.

アプリケーションエンジニアになるまでの10年間

私が趣味でコードを書き始めたのは中学生のころ,家族のWindowsマシンに雑誌の付録のSuSE Linuxをインストールしたのが始まりでした.当時は家にインターネットが来ていませんでしたから,めでたくも私はLinuxを弄って遊ぶ方向に進化してしまい,その過程でソフトウェアのインストールスクリプトを触ったり,ゲーム組込みのLuaを覚えたりしてコンピュータというものに親しみました*1

十分にコンピュータ熱を帯びたところで自宅にインターネットが開通,電子部品がインターネットで購入できると知るや否や,マイコン(SuperH)を買っては家族に怪しまれるなど,典型的理系学生もかくやと思われる遍歴を送ってきたものの,あいにく私は高校数学がからっきしダメで,文系として大学を受験して法学を4年間学ぶことになりました.「 LaTeXで卒論を出すのは君くらいだよ 」と言われたことを憶えています*2

大学の頃にPlay Frameworkに触れ,MVCアーキテクチャの基礎を理解しました.もっと出来る人ならば,既にWebサービスの1つくらい作っていたでしょうが,私のソフトウェア作成能力は取るに足らないものでした.学部3年生の夏にはてなサマーインターンに参加するその瞬間まで,ソフトウェアを作る人間を一度たりとも見たことがなく,どこに行けば会えるのかも分からなかったのです.それまでは貧弱な語彙でインターネットを検索するばかりでした.インターンの怒涛の研修日程でモリモリマッチョマンにされた私は,幸運にもScalaでコードを書く仕事ができています.高校の文理選択で人文系を選択したとき,もうプログラマーという選択肢は絶たれたのだと落胆してから,6年の月日が流れていました.

趣味と職業とでの,プログラミングの違い

自己紹介はこのくらいにしておいて,実際に職業として私が書いているコードの話に移りましょう.趣味で行うようなプログラミングと,職業として行うプログラミングとの違いは何でしょうか.またそれはどこから来る特徴なのでしょうか.実際に体験したプログラミングからは多くの気付きがあったため,初心を忘れないように書き残しておこうと思います.入社後8ヶ月にして拙速といったところですが,新卒社員の直感として大目に見ていただければと思います.

規模が大きい

入社当初,いつもの通りにコードを書いていたところ,コードレビューではねられてしまいました.ループの内側でDBにアクセスする,いわゆるN+1問題をはらんだコードを書いてしまったからです.プロダクトコードでは当然このようなコードは許容されないため回避策を採りましたが,当時の私の目には新鮮に写ったことを思い出します.

業務で書くコードは,趣味で書くコードよりもはるかに強力な負荷の試練を受けます.趣味のコードに掛かる負荷はたかが知れている上,コードを利用するタイミングを完全に制御できますし,望む限りの資源を自由に使うことができますが,業務で使うコードはそうはいきません.通常時の数十倍の負荷が突然発生することがありますし,それがいつ起きるのかを完全に予測することはできません.企業は利益を生み出さなければなりませんから,限られた計算資源を浪費するコードははっきりと悪であり,より効率的なコードが求められます.

修正を終えたコードは,いささか不恰好に見えました.現実の環境に合わせるためには,理想的なコードを諦めなければならないこともあるのだなと感じました.その落差をいかに小さく収めるかが肝心なのだと思います.

過不足がない

ある箇所を実装していた時のことです.突然,最高のかっこいい仕組みが頭にひらめきました. mapflatMapを駆使すると今書いている箇所が短く書けそうだったのです. 思い付きをそのままコードに反映させていると,結局もとのコードよりも複雑で,汎用性がなく,しかも遅そうなコードになってしまい,当然コードレビューで落とされました. 今はそこまでしなくてよいと教わって,少し残念な気持ちになりました.書けばいいってもんでもないんじゃないかな(ポロロ〜ン)*3,というわけです.

趣味のコードにはいくらでもパワフルな設計を織り込むことができますが,業務で書くコードには目的を十分に達成できるコードを織り込む程度に収めることが多いようです.あまりに強力な仕組みは扱いづらく,かえってメンテナンスのコストを上げてしまうことがあるからです.また,時間もコストですから,チューニングで時間を浪費するわけにはいきません.シンプルな手法は扱いやすく,見積りをしやすくします.

複数人のものである

私がコミットしたコードが時間をかけて他の箇所から呼び出されるようになり,いつのまにか思ってもみない使い方をされていた,ということがあります.後から考えてみると,最初から必要最小限な箇所のみを外部に公開しておけばよかったのに,どこからでもコードを使えるようにしていたのが問題でした.コードのリファクタリングには時間がかかり,最初から書き直したほうがよいのではないかと思わせるほどでした.

趣味のコードでは,一人がコードを書き,それが動けば良いとされますが,大抵の場合,業務で書くコードには複数の人々が関わり,各々の意思を反映する必要が出てきます.また,コードは書いた人の世代を越えて使われていく可能性をはらんでいます.

このような事情から,業務で書いたコードは簡単には作り直せなくなります.一度書いたコードは,それを維持するコストがかかりますし,作り直した場合にはより大きなコストがかかります.趣味のコードのように,カジュアルにぶっこわしたりできないので最初は慣れませんでした.

はみだしコラム: 法との共通点

昔大学の構内を歩いていたときに,「違反自転車は撤去する」という張り紙を見て,現実世界のルール,つまり法とコードは同じようなものだなあとなんとなく思っていました. それが実際にコードを書く職業に就くと,法とコードとの共通点がより明確に分かってきました.

法律同士は複雑に参照し合っているため慎重に定める必要があり,「民法」「刑法」といったパッケージにくるまれています. また法律は必要十分に記述されています.細かく書きすぎると運用の幅がなくなってしまうからです. そして一度制定した法律は永続的に適用され,人々の生活に影響するため,困ったらその都度変更するということはできるだけ避けられます.

同じような性質を持つものを他にも考えることができそうですが,特に法とプログラムについては,それが文書の形式で存在すること,それ自体が意味を持つものではなく,人との密接な関わり合いに重きが置かれているという点,そして論理演算子が複数存在する点*4が,他のものにはあまり見られない特質だと思います.

しかし厳密さという点については異なっています.法は厳密に適用する必要がある中で,解釈を積み重ねることで綿密な解釈を作り上げていくのに対して,プログラムは最初から綿密な記述が求められます.これは用途の違いによるものでしょう.

もし法に興味を持たれたならば,『現代法学入門 (有斐閣双書)』という書籍があるため,これを参考に学ばれるとよいと思います.

過去の自分へのアドバイ

入社から数ヶ月の間に学んだ事柄を書いてきましたが,もちろんこれで全てを知った気になっているわけではありません. 学ばなければならない事は山のようにありますし,そのための考え方なども洗練させていく必要があるでしょう. それを裏付けるかのように,しばしば知識や経験の壁が邪魔をして,入社する前にもっと勉強しておけばよかったのに,という悔しい感覚が胸の中に広がることもしばしばあります.

もし過去の自分に何かがアドバイスできるなら・・・という視点から,これからソフトウェアエンジニアを志す人,特に学生が何を学ぶとよいかについて,僭越ながらいくつかの事柄をおすすめしていこうと思います.

掘り下げる姿勢と前に進む姿勢

新しく学ぶ事柄には分からない要素がつきものです.そういったとき私は,掘り下げる姿勢と前に進む姿勢を持とうと努めています.掘り下げる姿勢とは,分からない要素について調べることで一歩ずつ知識の空白区間を埋めていく態度です.どちらかといえば理論や知識の獲得を重視する姿勢ですね.前に進む姿勢とは,分からない要素をひとまずそばに置いて,目的の達成を優先する態度です.これは何かを実装してみるとか,ライブラリを使ってみるとか,実用性や興味を重視する姿勢です.

相異なるふたつの姿勢

この二つの姿勢は相反するもののように見えますが,それぞれ違うアプローチを採るというだけで,実際はどちらも同じ学習という目標を目指しています. より深い理解に到達するためには一つ一つの要素を深く掘り下げていく必要がありますが,理解できないままに興味を失ってしまったり,嫌になってしまうことも考えられます. その一方で,問題を解決するためだけに知識を拾い食いしていては,付け焼刃の理解はできても体系的な理解をものにすることはできないでしょう*5

両者を適度に使いこなす

この二つの姿勢のうち,どちらかが良くてどちらかが悪いなどということはありません. 自分の理解状況に合わせて,歩みを早めたり遅くしたりすることが大事です.時として立ち止まり,使っている技術の土台を成す理論の方を向いてみたり,また時として気になったライブラリを使ってみたりしてもよい,ということです.同じ対象について学んでいるのに,部分部分で理解が早まったり遅まったりすることは,珍しくもなんともないことですから,焦ることはないと思います. ただし,歩いていなければ止まっているのと同じです.少しずつでもいいので,どこかへと歩く努力をしましょう.

日本語と英語は鍛えたほうがよい

あたりまえの話ですが,日本のソフトウェア開発者が最も使うのは日本語です.ScalaPerlではありません.ソフトウェアをつくるには,個人がコードや設計を行う技量が不可欠ですが,それができるのはチームの協働があってこそです.満ち足りた意思の疎通ができると,チームの力は個々人の力の総和よりも大きくなります.それが日本語を鍛えたほうがよい理由です.

そして,ライブラリや言語について分からないことがあったときに最初に見るべきものはオフィシャルなドキュメントです.経験上,解説サイトはオマケくらいに考えておいたほうが良いと思います.そして大抵のドキュメントは英語で書かれているので,どうしても英語が読めないと不利になります.書けるようになる必要性は日本語ほどではありませんが,読めるようになっていたほうが良いでしょう.

技術が好きなことが大事

小難しい事を書いていますが,これらの努力をつらぬくために大事にするべきは,技術が好きなことだと思います.技術が好きだからこそ学んだり使うための試行錯誤を行うことができます. 好きこそ物の上手なれ,というわけです.使える技術を増やしていって,また別の好きなものを広げていけたらいいなと思います.

株式会社はてなでは,技術が好きなエンジニアを募集しています.

hatenacorp.jp

次回予告

アーッ,なんかとりとめのないことを書いてしまった.もっとこう,技術的な話とかができればいいのだが,何を書いたらいいかまだよくわかりませんね・・・

明日のはてなエンジニアアドベントカレンダー2016は, id:stefafafan です.備えよう!

*1:MBRを壊して起動できなくなったり,データを消して怒られるなど,大抵の怒られることをしました

*2:OMakeでGraphvizやblockdiagなどを制御して,教授のためにエンコーディングを変換する所まで自動化していました.学部ではWordが多数派でしたが,教授はLaTeX好きだったようです.

*3:ガールズ&パンツァー 劇場版を買って勉強しよう!

*4:法律には,結合力の高い「及び」と結合力の弱い「並びに」という接続詞があり,perlにも結合力の高い&&と結合力の弱いandがあります.

*5:自分で言っておきながら耳が痛い話です.