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

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

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

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

Avatar for Yoshiyuki Asaba

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