Upgrade to Pro — share decks privately, control downloads, hide ads and more …

早稲田大学アルゴリズムとデータ構造特別講義

 早稲田大学アルゴリズムとデータ構造特別講義

Yoshiyuki Asaba

December 23, 2017
Tweet

More Decks by Yoshiyuki Asaba

Other Decks in Technology

Transcript

  1. ビジネスのはじまりから成長をすべてサポートする freee 4 簡単:知識がなくても1クリックで給 与計算 勤怠:勤怠管理も簡単に オンライン:給与明細はオンラインで 配布 会計連動:会計ソフトと完全データ 連携

    政府連携:行政手続きもオンライン で完結 マイナンバー:マイナンバー管理も 完全対応 5分:会社設立用の書類を最短5 分で作成 モバイル:スマホ完全対応で、どこ でも会社設立 ワンストップ:実印発注や銀行口 座作成もできる 自動:銀行やカードの口座と連携し、人工 知能で会計帳簿を作成 簡単:簿記の用語を使わない画面設計で 簡単に使える 最適化:請求書発行や経費精算などの業 務も最適化 実績:クラウド会計ソフトシェア No.1 で安 心の実績 サポート:チャットによる迅速なサポートを 提供 決算:決算や個人事業主の申告まで自動 で簡単に ✩ はじめる ↻ 運営する ↗ 育てる 会社設立 freee (2015年6月リリース) クラウド会計ソフト freee (2013年3月リリース) 人事労務 freee (2014年5月リリース) シェアNo.1 シェアNo.1 開業 freee (2016年10月リリース)
  2. 6 Webサービス(1) • インターネット上で何かしらの価値を提供するサービス ◦ クラウドや*aaSなどと表現することもある ▪ SaaS, PaaS, Iaasなど

    ◦ freeeはビジネス向けのサービスを提供 ▪ B2B (Business To Business) ◦ ブラウザだけでなくiOSやAndroidのアプリからサービスを使 うケースも含める
  3. Webサービス(2) 7 • リクエスト ◦ ブラウザやアプリからWebサービスに対して何かの処理を 依頼すること • レスポンス ◦

    リクエストに対しての応答 ◦ レスポンスの内容に応じてブラウザやアプリが画面を書き換 える
  4. 8 Webサービスの全般的な要件 • 使いたいと思っている機能を基本的にはいつでも使える ◦ サービスが落ちていると嫌ですよね • 可能な限り速く結果を返す ◦ レスポンスが遅いとイライラしますよね

    ◦ できればミリ秒の単位でレスポンスを返したい ▪ 1秒 = 1000ミリ秒 • ユーザが識別されている ◦ プライベートな情報を、自ら公開せずに他人に情報を見られ ると嫌ですよね
  5. サービスが常時稼働しているとは? 9 • 前提:マシンは壊れるもの ◦ CPU, メモリ, ストレージ, 電源, などなど

    ◦ ソフトウェアのバグによって機能しなくなることもある ▪ OS, ミドルウェア, アプリケーション • 壊れても大丈夫なように複数のマシンでサービスを動かす ◦ 冗長化 ハードウェア(PC, tablet, smartphone等) OS(iOS, MacOS, Windows, Linux等) ミドルウェア アプリケーション
  6. レスポンスを速く返すとは? 10 • 計算を速く終わらせる ◦ ハードウェアのスペックをあげる ◦ ソフトウェアを効率よく動かす ▪ アルゴリズムとデータ構造が特に重要

    ◦ 不要な計算を後回しにする • サーバーの忙しさを下げる ◦ 少ない計算量でも、同じ処理が1台でたくさん動いていると待た される ▪ リクエストを複数の台数に振り分ける ▪ 負荷分散と呼ぶ • 待ち行列を減らす ◦ 高速道路の料金所でよく渋滞しますよね(ETCありますが) ◦ 待ち行列理論というのがありますが、それは飛ばします
  7. 冗長化と負荷分散 11 • 複数台でリクエストを受け付 ける(ロードバランサ) ◦ どれか故障してもサービ スを継続できる • リクエストを処理するのも複

    数台用意しておく ◦ 一台で処理できる数は限 界がある ◦ 複数台あれば限界がN 倍増える ▪ ただしお金がかかる
  8. データを保存する 12 • Webサービスは大抵は何かのデータを保存します ◦ 会計データ ◦ 画像 ◦ SNSの投稿

    ◦ チャットメッセージ • 保存するためのシステムがあります ◦ RDBMS, KVS, … ◦ あとで説明予定 これ
  9. 16 すべてを紹介するのは難しいので • RDBMS (Relational DataBase Management System) ◦ データの検索

    ◦ データの並び替え ◦ データの結合 • KVS (Key Value Store) • キューシステム
  10. 18 RDBMS • Relational DataBase Management System ◦ 簡単に言うと ▪

    安全にかつ高速に、大量のデータを保存・検索できるシス テム ◦ MySQLやPostgreSQLがよく使われている ◦ 大抵のサービスで使われていると思って良い データベースの授業は3年で開講されるそうですが、 その場合は絶対に受けておいたほうが良いです!!
  11. RDBMSのイメージ 19 • スプレッドシートみたいなもの ◦ テーブル ◦ 行 ◦ 列

    • 特徴 ◦ 検索ができる ◦ 大量データを扱える ◦ 同時操作が可能 ◦ その他にも色々ありますが、来 年の講義で学んでください
  12. SQL 20 • Structured Query Language ◦ RDBMSに命令をするための言語 ◦ 宣言的に欲しいデータの検索を記述

    ◦ データの挿入、更新、削除も可能 ◦ どのように検索するかはRDBMSが裏で決める SELECT 学籍番号, 名前 FROM 学生 WHERE 都道府県 = ‘東京都’ 命令:学生というテーブルの中から東京都の学生だけを学 籍番号と名前を抽出したい
  13. データの検索 22 • 線形探索 ◦ データをすべて検索する ▪ 配列を最初から最後までスキャンするイメージ ◦ ストレージの速度が速くなったとは言え、遅い

    ◦ フルスキャンと呼んだりします • インデックス探索 ◦ 次のページから説明します ◦ 二分木探索をイメージしてもらえると
  14. 例:教科書から特定の内容が書いてあるページに飛びたい 23 • 「クイックソート」というキーワードがあるページを探したい ◦ 本が1,000ページあるとする • 探し方 ◦ 巻末にある「索引」から「クイックソート」という単語があるか調べ

    て、あればそのページに移動する ▪ インデックススキャン ◦ 本を1ページ目から探していく ▪ 1,000ページを読み込まないといけないので時間がかかる ▪ 「変数」という一般的な用語だと色々なページに出てくるので 先頭から全部確認したほうが早い • 意味があるのかは置いておいて
  15. B+Treeの特徴 25 • 実際のデータは葉にしか持たない ◦ B-Treeは節にも持つ ◦ ブロックデバイスに適している ▪ ブロックデバイスとは簡単に言うと外部ストレージ(HDD,

    SSD等) ▪ 1回のストレージのオペレーションをブロックという塊で操 作する ◦ 節を1ブロックに大量に詰め込むことができるので木の高さが 低くなる
  16. B+Treeの挙動を知りたい場合 27 • 小さいCのコードがあります ◦ http://www.amittai.com/prose/bplustree.html $ gcc -g -O0

    btp.c $ ./a.out ... Enter any of the following commands after the prompt > : i <k> -- Insert <k> (an integer) as both key and value). f <k> -- Find the value under key <k>. p <k> -- Print the path from the root to key k and its associated value. r <k1> <k2> -- Print the keys and values found in the range [<k1>, <k2> d <k> -- Delete key <k> and its associated value. x -- Destroy the whole tree. Start again with an empty tree of the same order. t -- Print the B+ tree. l -- Print the keys of the leaves (bottom row of the tree). v -- Toggle output of pointer addresses ("verbose") in tree and leaves. q -- Quit. (Or use Ctl-D.) ? -- Print this help message. > i 3 3 |
  17. 巨大なデータのソート 30 • ソート例 ◦ 学生さんのリストをテストの成績順にソートしたい • メモリに収まる範囲であればクイックソートでソートする ◦ 数百行レベルであれば余裕でメモリ上でソートできる

    ◦ オンメモリで平均的に速いソートアルゴリズム • メモリに収まりきらない場合はファイルを使ったソート ◦ マージソート ◦ ファイルを使うので遅い
  18. Top-N sort (Top-k selection) 31 • 並び替えた結果から上位10件を取りたい ◦ SELECT *

    FROM students ORDER BY score DESC LIMIT 10 ◦ 該当する行をすべてとってきてソートするのではなく、上位N 件だけを保持してソートする
  19. テーブル結合とは 34 • 2つのテーブルを指定した条件で別のテーブルを作る(結合, JOIN)すること ◦ 例:数字が一致する行を結合したい 学籍番号 都道府県 コード

    4 101 2 102 1 102 7 104 都道府県 コード 都道府県名 101 東京都 102 神奈川県 103 長野県 104 愛媛県 駆動表 内部表 4 101 101 東京都 2 102 102 神奈川県 1 102 102 神奈川県 7 104 104 愛媛県 結合
  20. 結合例1 35 • 特定の学生がどこ出身か? ◦ 都道府県コードをキーにテーブルを結合 ◦ →学籍番号と都道府県名を取得可能になる 学籍番号 都道府県

    コード 4 101 2 102 1 102 7 104 都道府県 コード 都道府県名 101 東京都 102 神奈川県 103 長野県 104 愛媛県 学生テーブル 都道府県テーブル 4 101 101 東京都 2 102 102 神奈川県 1 102 102 神奈川県 7 104 104 愛媛県 結合
  21. 結合例2 36 • 特定の学生がどの講義を履修したか? ◦ 学籍番号ををキーにテーブルを結合 ◦ →学生番号と講義IDを取得可能になる ◦ →さらに講義名を取得したい場合は講義テーブルを結合

    学籍番号 名前 4 山田 2 田中 1 鈴木 7 木村 学籍番号 講義番号 1 1001 1 2001 4 3001 2 1022 7 4000 2 1001 講義番号 講義名 1001 英語 1022 会計学 3001 ネットワーク 2001 論理学 4000 線形代数 履修テーブル 学生テーブル 講義テーブル
  22. テーブル結合(JOIN)をどう実現するか 37 • 代表的なものは3つのアルゴリズム ◦ Nested Loop Join ◦ Merge

    Join ◦ Hash Join • すでに習ったアルゴリズムを組み合わせています • のちほど3つのアルゴリズムを実装していただきます
  23. サンプルデータ 38 4 9 2 1 7 2 10 5

    7 2 • 1次元の整数の配列を2つ用意 ◦ 整数は学籍番号や講義番号と思ってください ◦ 結合結果の順番は不定 2 2 2 2 7 7 結合
  24. Nested Loop Join 39 • 単純な2重ループのアルゴリズム ◦ 全組み合わせを比較し、条件にあったものを返す ◦ もう少し丁寧に書くと

    ▪ 駆動表の条件にマッチするのを内部表から持ってくる、と いうのを繰り返す ▪ B+Treeでは条件次第では内部表から早くデータを取って これる(下の図はフルスキャン) 4 9 2 1 7 2 10 5 7 2
  25. 擬似コード (PostgreSQLソースコードのコメントより引用) 41 Join { get initial outer and inner

    tuples INITIALIZE do forever { while (outer != inner) { SKIP_TEST if (outer < inner) advance outer SKIPOUTER_ADVANCE else advance inner SKIPINNER_ADVANCE } mark inner position SKIP_TEST do forever { while (outer == inner) { join tuples JOINTUPLES advance inner position NEXTINNER } advance outer position NEXTOUTER if (outer == mark) TESTOUTER restore inner position to mark TESTOUTER else break // return to top of outer loop } } }
  26. 42 1 2 4 7 9 2 2 5 7

    10 • 両方のデータをソートしてからスタート ◦ 現在の場所を両方のテーブルにマークする ◦ 1 != 2なので左をずらす
  27. 43 1 2 4 7 9 2 2 5 7

    10 • 2 == 2 ◦ どこから一致したかをマークする • 結果:{2,2}
  28. 44 1 2 4 7 9 2 2 5 7

    10 • 2 == 2 ◦ さらに進める • 結果:{2,2}, {2,2}
  29. 45 1 2 4 7 9 2 2 5 7

    10 • 2 < 5 ◦ 左のテーブルを先に進める ◦ 右のテーブルのマークを戻す • 結果:{2,2}, {2,2}
  30. 46 1 2 4 7 9 2 2 5 7

    10 • 4 > 2 ◦ 右のテーブルを先に進める • 結果:{2,2}, {2,2}
  31. 47 1 2 4 7 9 2 2 5 7

    10 • 4 > 2 ◦ 右のテーブルを先に進める • 結果:{2,2}, {2,2}
  32. 48 1 2 4 7 9 2 2 5 7

    10 • 4 < 5 ◦ 左のテーブルを先に進める • 結果:{2,2}, {2,2}
  33. 49 1 2 4 7 9 2 2 5 7

    10 • 7 > 5 ◦ 右のテーブルを進める • 結果:{2,2}, {2,2}
  34. 50 1 2 4 7 9 2 2 5 7

    10 • 7 == 7 ◦ どこから一致したかをマークする ◦ 右のテーブルを進める • 結果:{2,2}, {2,2}, {7,7}
  35. 51 1 2 4 7 9 2 2 5 7

    10 • 7 < 10 ◦ 右のテーブルのマークを戻す ◦ 左のテーブルを進める • 結果:{2,2}, {2,2}, {7,7}
  36. 52 1 2 4 7 9 2 2 5 7

    10 • 9 > 7 ◦ 右のテーブルを進める • 結果:{2,2}, {2,2}, {7,7}
  37. 53 1 2 4 7 9 2 2 5 7

    10 • 9 < 10 ◦ 右のテーブルを進めたいがこれ以上無いので終了 • 結果:{2,2}, {2,2}, {7,7}
  38. 擬似コード(再掲) 54 Join { get initial outer and inner tuples

    INITIALIZE do forever { while (outer != inner) { SKIP_TEST if (outer < inner) advance outer SKIPOUTER_ADVANCE else advance inner SKIPINNER_ADVANCE } mark inner position SKIP_TEST do forever { while (outer == inner) { join tuples JOINTUPLES advance inner position NEXTINNER } advance outer position NEXTOUTER if (outer == mark) TESTOUTER restore inner position to mark TESTOUTER else break // return to top of outer loop } } }
  39. 練習問題 56 • 以下のJOINアルゴリズムをC言語で実装してください ◦ Nested Loop Join ◦ Merge

    Join ▪ ソートは何で実装しても良いです ◦ Hash Join ▪ ハッシュテーブルは何で実装しても良いです • それぞれのJoinについてどういう特性があるか考えてみてくださ い
  40. 練習問題 58 • 出力 ◦ マッチした値と件数 ▪ 重複分も含める ▪ マッチした値の順番は問いません

    ▪ 件数がそれぞれのJOINで同じことを確認する 1 1 2 2 3 3 3 3 join count = 4
  41. KVS 60 • KVSはいろいろなミドルウェアがある ◦ Keyとそれに対するValueを保持する ▪ Keyでデータを検索 ◦ 代表的なものは連想配列をハッシュテーブルを使って実装

    • key-valueをオンメモリで持っておく実装が多いシステム ◦ データを永続化できるものもある ◦ キャッシュ用途に使われることが多い ◦ memoryが溢れそうな場合はLRU(Least Recently Used)等の ポリシーで消すこともある
  42. KVSの使用例 62 • sessionデータを一時的に保存し、リクエストごとに参照 ◦ sessionとはサービスにログインされると作られるデータ ◦ ハッシュテーブルはO(1) ◦ B+TreeはO(log_b

    N) ▪ bはどれくらい節に詰め込めるか(2分木だと2) ▪ 外部ストレージへのI/Oも発生する可能性がある web server web server SET (login時) GET (sessionの有効性の確認) session key value Athoh4Phu0aeng9wureJ Aさんの識別子 fohphaChahmoo1saizuu Bさんの識別子 Aeng6ei1phei0LohQu8i Cさんの識別子 ハッシュテーブル (session keyは実際 はもっと長い)
  43. キューの前に 64 • Webサーバは基本的に早く応答を返したい ◦ 重い処理を後回しにしたい • リクエストの同期処理と非同期処理 ◦ 同期処理とはユーザへ応答を返すときには処理が終わって

    いる処理 ◦ 非同期処理とはユーザへ応答を返すのとは別に裏で行われ る処理 ▪ 別の形でユーザへ通知するか、そもそも通知が不要なも のもある
  44. アルゴリズムとデータ構造を知っておくと良いこと 69 • データ構造とアルゴリズムは色々なところで使われている ◦ それぞれ特性があるので、状況に応じて使い分けることが大 事 ▪ 外部記憶領域に書き出す可能性があるからクイックソート ではなくマージソートを使う

    ▪ Merge Joinは結合の条件比較の数は少ないが、その代 わりに先にソートする必要がある、等 ◦ レスポンスが遅くなったときには裏でどういうアルゴリズムが 動いているかを知っているかで解決ができる つまり、サービス開発には欠かせない知識!