Subscribed unsubscribe Subscribe Subscribe

SE Can't Code

A Tokyo based Software Engineer. Not System Engineer :(

diffを実装した.

Engneering

ソフトウェアエンジニアなら誰しもが触ったことのあるdiffアルゴリズムUNIXのdiffコマンドであったり、SVNやGitでのバージョン管理といった、普段の開発ではかなり利用頻度の高いアルゴリズムになる。そしてこうしたアルゴリズムは実は単純そうに見えて、割と複雑な計算原理によって実現されていたりする。

  • 編集距離 : 2つの要素列の違いを数値化したもの
  • LCS(Longest Common Subsequence): 2つの要素列の最長共通部分列
  • SES(Shortest Edit Script): ある要素列を別の要素列に変換するための最短手順

diffはこれらの計算原理を用いてエディットグラフというアルゴリズムを用いて実現されている。エディットグラフはたとえばカーナビの最短経路問題などでも使われている。で、Gitで使われているらしいMyersのアルゴリズムC++で実装してみたら、これがまた思いの外ハマってしまって、簡易的なコードでも気付いたら数時間が経っていた。

UNIXコマンドを自力で実装するというのはアルゴリズムの勉強に良いと聞いてやってみたけど、かなり重かった。僕らが何気なく普段から使っているUNIXコマンドやツールには、頭の良い人間が考えたアルゴリズムというものが詰まっている。

話が飛躍するが、昨今の技術、PaaSやSaaSといったサービスであったり、フレームワークなどが様々な技術をブラックボックス化して、利用者はそれらの原理原則を知らずとも扱える、という状態が進んでいる。しかし本当にそれらを利用者として扱うのみに留まるのはいかがなものかと思う。あくまで個人的にだが、こうした隠れたアルゴリズムを学んでおくとエンジニアとしての力になる気がする。というか単純にアルゴリズムは面白くて、Wikipediaでいろんなアルゴリズムを眺めるだけでも十分時間を潰せる。次は動的計画法でやってみたい。

Remove all ads

ニックというシニアエンジニア.

life

今年の中盤まで職場では英語を毎日話す環境があったのだが、今や英語なんて全く話すことがなくなった。ちょっとでも話さない時期ができると頭の中から英語ってやつが消えてしまう。定期的に訓練しないと去年に元通りになってしまうので、この頃またDMM英会話を受けたり土日に外国人がいるところへ飛び込んだりしている。

ついこの前、外国人エンジニアらと集まってもくもく会をした。データマイニング系をテーマにしていて、とある会社のオフィスに集まり、もくもく作業をする。会話は全部英語。外国人8割、日本人2割くらい。僕はMNISTのデータセットを使っていろんなDeepLearnig系のフレームワークを入門する、ということをそこでのテーマにした。たいしたことはしていない。

隣の外国人エンジニア、名前をニックというアメリカ人は、データマイニングは初めてのようだった。環境作りから始めていたので、ちょこちょこ手助けをしていた。ニックは35歳を越えたC++プログラマで、ちょっとその手の話で突くとかなり豊富な知識と経験が流れてきた。そんなベテランエンジニアなニックは初めての技術領域にチャレンジしようとしていた。

ニックは「機械学習はトレンドだけど、単純に興味があるので今日をきっかけにチャレンジしたいと思ってるんだ。この技術は夢があってワクワクするよね。」と楽しそうに話していた。そんな話をしていると周りのメンバーともワイワイと会話に混ざってきて、途中で僕はネイティヴな彼らの英語が聞き取れなくなったのだが、それでもその場で飛び交う夢みたいなワードが非常に心地よかった。

ニックにはそのあとPythonについていろいろと説明した。プログラマとして僕よりも圧倒的にスキルがある人なので、質問の鋭さから答えられないものもあったが、ニックは満足気に聞いていた。そのあと僕がただの愚痴で「この分野は数学と統計学機械学習の分野の勉強が必要だから結構辛い。時間が足りなさ過ぎる。」とこぼしたら、「でも面白いから続けてるわけでしょ?確かに勉強は辛いけど、それが出来るようになった時の嬉しさとか技術そのものに対する好奇心があるから僕らはエンジニアをやってるんじゃない?」とニックは笑って返してきた。そして、「こんな一生楽しめる仕事に就けて、僕は幸せだと思う。」と言った。

もくもくと作業をしに行っただけなのに、隣にいるエンジニアの大先輩の言葉に感動してしまった。外国人だからかわからないが、サクッとカッコいいセリフを言ってしまうところがまたカッコいい。惚れてしまうかと思った。そうだよなぁ、ただただ面白いから時間を忘れて家でもコード書いたり新しい技術を学んだりしてるんだよなぁ、と改めて思い知らされた。

今年に入って多少英語を話せるようになったのだが、外国人エンジニアと話せるようになったのが一番の収穫だったと思う。もっと訓練しないと全然駄目駄目なのだが、こういう英語の環境があると英語学習のモチベーションが上がる。そしていつか35歳オーバーのシニアエンジニアになった時に、若手のエンジニアにニックが言ったセリフと同じ事を言ってやろうと心に誓った。

Remove all ads

SICP2章, 公認インターフェース.

SICP Scheme

演算は手続きのリストとして表現することが出来る。要は信号処理のフィルタのように数珠繋ぎで演算が表現可能になるのだが、この時各リストの中の各種部品に類似性を見つけてあげると、それを"公認インターフェース"として柔軟かつ強力な設計が実現する。下記の例は2つの手続きを表現するプログラムである。

  1. 引数としてリストを取り、奇数である葉の二乗の和を計算する
  2. 引数として数値を取り、偶数のフィボナッチ数列のリストを作る

(define (sum-odd-squares tree)
   (cond ((null? tree) 0)
         ((not (pair? tree))
          (if (odd? tree)
              (square tree)
              0))
         (else
           (+ (sum-odd-squares (car tree))
              (sum-odd-squares (cdr tree))))))

(sum-odd-squares '(1 (2 3) (4 5)))
; 35

(define (even-fibs n)
  (define (next k)
    (if (> k n)
        '()
        (let ((f (fib k)))
          (if (even? f)
              (cons f (next (+ 1 k)))
              (next (+ 1 k))))))
  (next 0))

(even-fibs 20)
; (0 2 8 34 144 610 2584)


この2つのプログラムには類似性を見ることができる。並びは違えど、それぞれのプロセスは[enumerate, filter, map, accumulate]の4つの共通部品によって構成されているのがわかる。
f:id:fixxman:20161202013624p:plain

sum-odd-squares

  • 木の葉を数え上げる[enumerate]
  • 奇数でフィルタ[filter]
  • 選ばれた要素を二乗[map]
  • 要素を0初期値で加算[accumulate]

even-fibs

  • 整数を0からnまで数え上げる[enumerate]
  • それぞれの要素でFibonacci数を計算[map]
  • 偶数でフィルタ[filter]
  • 要素を空リスト初期値でcons[accumulate]


この[enumerate, filter, map, accumulate]ような独立的な部品(公認インターフェース)を組み合わせ、プログラムを並びの演算として表現することで様々な実装を実現する。このケースの公認インターフェースだと下記のように実装ができる。

(define (accumulate op initial items)
  (if (null? items)
      initial
      (op (car items)
          (accumulate op initial (cdr items)))))

(define (map proc items)
  (if (null? items)
    nil
    (cons (proc (car items)
          (map proc (cdr items)))))

(define (filter predicate items)
  (cond ((null? items) nul)
        ((predicate (car items))
         (cons (car items)
               (filter predicate (cdr items))))
        (else (filter predicate (cdr items)))))


このように表現すると下記のように柔軟に公認インターフェースを様々な用途で利用可能になる。

(accumulate + 0 (list 1 2 3 4 5))
-> 15

(accumulate * 1 (list 1 2 3 4 5))
-> 120

(map square (list 1 2 3 4 5))
-> 1 4 9 16 25

(filter odd? (list 1 2 3 4 5))
-> (1 3 5)


これをリストとして組み合わせて、順序を入れ替えると表現できることが無数に広がる。
始めて実装する時は共通部分を見出すことが難しいため、公認インターフェースを作り出すことは難しい気がする。ただ、実装が進んでいくにつれて、他に作り出された演算との類似性が見えてくるため、公認インターフェースを作り出すための抽象化がし易くなるんじゃないか。リファクタリングをする必要が出てくるのだが、処理というものを信号処理のようなリストというでデータ構造に落とし込むことで、実装の各ステージが明確になり、独立性を高めることができるようになる。

Remove all ads

英語の上達.

life

会社からの帰り道、駅のホームへ向かう途中で外国人が道を尋ねてきた。「六本木に行きたい」と切羽詰まった感じで聞いてきたので、駅のホームまで一緒に行ってどの電車に乗ってどこで乗り換えるのかと、よくある道案内を英語で対応した。忘れるといけないので、スマートフォンEvernoteに降りる駅の名前などを打ってあげたら、かなり感謝された。

中学生の頃、外国人に「Excuse me?」と尋ねられ、道案内をするという例文が教科書にあった気がするが、「英語なんて喋れるか」と当時は思っていた。あれから10年以上の時が経った今、その例文と同じ道案内のケースに遭遇し、英語で対応出来るようになった自分に帰りしな少し感動した。小さい話だが、当時やれないと思っていたことは案外やれるようになるんだな、と。

成長ってのは普段は全く感じやしないが、こうした小さな出来事でたまに実感するものなのかもしれない。まぁ英語は外国人エンジニアと比べるとマイナススタートでしかないので、それが0になっただけで何の自慢にもならないんだけどね。

Remove all ads

グループ会社のエンジニアの集まりに参加した.

life

先日の話だけれど、弊グループの各会社のエンジニアらが集まってワイワイ勉強会などをやってるコミュニティに参加して来た。何気に日本を代表するグループ会社の規模であると思うんだけど、その中でも各社のかなり技術力のあるメンツが集まってるっぽくて、個人的に凄いテンションが上がった。

有名なOSSのコミッターがいたり、セキュリティの研究をしている人やインフラ、言語処理系、機械学習に詳しい人、などなどバラエティに富んだエンジニアが沢山いて、彼らの話に付いていくのがやっとだった。懇親会ではC++の言語処理系の話やセキュリティでの逆アセンブラの話で盛り上がったりして知的好奇心がひたすら刺激を受けた。

僕は今までこういった会社関係のエンジニアの集まりには無縁だったので、なんだか嬉しくて終始舞い上がっていた。特に前の部署にいた頃は、技術に興味のある人が周りに全然いなくて、自分はよく異常値扱いを受けていたし、入社してガッカリしたことと言えばそれに尽きる。技術の話をして盛り上がるなんて限られた同期と先輩が数人いたぐらいで、あとはITに興味無い人がほとんど。入る会社を間違えてると何度人に言われてきたことか。

けどそれは一部の世界でしかなくて、ちょっと外へ出てみると自社にも凄いエンジニアが沢山いて、それこそグループ会社まで広げればもっと数も幅も増える。そしてそうしたエンジニアたちが集まって、意見を交わし、技術力を磨いてる世界は存在する。(まぁソフトウェアを売りにしてるし、知名度的に当然っちゃ当然なんだけど)

最近、あまりにも会社のこととか、グループ会社のことを知らなさ過ぎるな、ということを強く思う。これだけでかいんだ、ただ自分が知らないだけで、もっと面白い組織や仕事は実際にあるんだと改めて実感する。いろんな人に会って情報集めに奔走する日々を送っているが、知れば知るほど面白い。やっぱり一つのコミュニティに閉じるのはどうも良くない。特にエンジニアはね。

こんな当たり前なことに入社4年目にしてようやく気付いたのであった。

Remove all ads