$30 off During Our Annual Pro Sale. View Details »

新しいプログラミング言語の学び方 HTTPサーバーを作って学ぶ Java, Scala, Clojure

新しいプログラミング言語の学び方 HTTPサーバーを作って学ぶ Java, Scala, Clojure

JJUG CCC 2017 Fallでの発表資料です。

Shunsuke Tadokoro

November 24, 2017
Tweet

More Decks by Shunsuke Tadokoro

Other Decks in Technology

Transcript

  1. DDD@H
    ৽͍͠ϓϩάϥϛϯάݴޠͷֶͼํ
    )551αʔόʔΛ࡞ֶͬͯͿ

    +BWB 4DBMB $MPKVSF
    ++6($$$'BMM
    !UPEPLS
    ָ͍͠

    View Slide

  2. IUUQTUXJUUFSDPNNBUUO@KQTUBUVT

    View Slide

  3. IUUQTUXJUUFSDPNNBUUO@KQTUBUVT

    View Slide

  4. DDD@H
    DDD@H

    View Slide

  5. DDD@H
    ୭ͩ
    ాॴॣ༎!UPEPLS
    w גࣜձࣾϏζϦʔν4DBMBΤϯδχΞ
    w ٻਓݕࡧΤϯδϯ8FCΫϩʔϥʔ΍޿ࠂγεςϜ։ൃͳͲ
    w Ұ෦ͷਓ͔Β͸ΤϞδχΞͱݺ͹Ε͍ͯ·͢
    w จࣈίʔυͱ͔&NBDT͕޷͖ͳωΦ࿝֐

    View Slide

  6. DDD@H
    ৽͍͠ϓϩάϥϛϯάݴޠΛֶͿ
    w εΩϧ΍ϓϩάϥϛϯάελΠϧͷ෯Λ޿͛ΔͨΊ
    w ७ਮʹָ͠ΈͷͨΊ

    View Slide

  7. DDD@H
    ֶͿखஈͷҰͭͱͯ͠
    )551αʔόʔ։ൃ͕

    ͓͢͢ΊͰ͢

    View Slide

  8. DDD@H

    View Slide

  9. DDD@H

    View Slide

  10. DDD@H

    View Slide

  11. DDD@H
    ͓࿩͢͠Δ͜ͱ
    w ͳͥ)551αʔόʔ
    w 4DBMB $MPKVSFʹ͍ͭͯ
    w )551αʔόʔΛ࡞Γͳ͕Βֶ΅͏
    w ͬ͘͟ΓΞʔΩςΫνϟ
    w ֤ݴޠͰ࣮૷ͯ͠ΈΔ
    w 4PDLFUͷѻ͍
    w ਖ਼نදݱ
    w Ϧιʔεͷ։์
    w ฒྻॲཧ
    w จࣈྻͷѻ͍
    w ·ͱΊ

    View Slide

  12. DDD@H
    IUUQTHJUIVCDPNUPEPLSTJNQMFIUUQTFSWFS

    View Slide

  13. DDD@H
    ͳͥ)551αʔόʔʁ

    View Slide

  14. DDD@H
    ৽͍͠ݴޠΛֶͿ࣌ʹΑ͘΍Δ͜ͱ
    w )FMMPXPSME 'J[[#V[[Λ΍Δ
    w ॻ੶ΛಡΉ
    w 50%0ΞϓϦͳͲ؆୯ͳ8FCαʔϏεΛ࡞Δ
    w FUD

    View Slide

  15. DDD@H
    ৽͍͠ݴޠΛֶͿ࣌ʹΑ͘΍Δ͜ͱ
    w )FMMPXPSME 'J[[#V[[Λ΍Δ
    w ॻ੶ΛಡΉ
    w 50%0ΞϓϦͳͲ؆୯ͳ8FCαʔϏεΛ࡞Δ
    w FUD

    View Slide

  16. DDD@H
    8FCαʔϏεʁ

    View Slide

  17. DDD@H
    8FCαʔϏεʹ͸%#͕͋Δ
    w ͱΓ͋͑ͣ)Ͱྑ͍͔ʜ
    w .Z42-8PSL#FODIͰ࡞ͬͨ%%-͕ྲྀͤͳ͍ʂ
    w ϩʔΧϧͷ.Z42-͕ݹ͍ɻCSFXVQEBUFʂ
    w ͍΍VQHSBEFͩͬͨ
    w %PDLFS ͱ͔͍͏΍ͭͰ .Z42-Λಈ͔͢ͷ͕

    φ΢͍ΜͰ͔͢Ͷ
    w IFSPLV͸1PTUHSF42-ͳΜͩͬͨ

    View Slide

  18. DDD@H
    8FCαʔϏεʹ͸ը໘͕͋Δ
    w ͱΓ͋͑ͣద౰ʹCPPUTUSBQͰ࡞Ζ͏ʂ
    w ΄͏΄͏ɺ4FNBOUJD6*ͷ΄͏͕ΠϚυΩͬΆ͍Β͍͠
    w ςϯϓϨʔτΤϯδϯʁ࣌୅͸41"Ͱ͠ΐ
    w ੜ$44ਏ͍͔Β4BTTʹ͠Α͏
    w 8FCQBDL CBCFMMPBEFS ͳʹͦΕ͓͍͍͠ͷʁ
    w EJW͕தԝʹدΒͳ͍

    View Slide

  19. DDD@H
    ͦΕͬͯ΍Γ͍ͨ͜ͱ͚ͩͬʁ

    View Slide

  20. DDD@H
    %POUTIBWFUIBUZBL
    w ผʹ%#Λ৮Γ͍ͨΘ͚Ͱ͸ͳ͍
    w ผʹը໘Λ࡞Γ͍ͨΘ͚Ͱ͸ͳ͍
    w ৽͍͠ݴޠΛֶͼ͍ͨ

    View Slide

  21. DDD@H
    ͦ͜Ͱ)551αʔόʔͰ͢Α

    View Slide

  22. DDD@H
    )551αʔόʔͳΒ
    w %#΍ը໘Λ༻ҙ͢Δखؒͳ͘ɺखܰʹ։ൃ͕࢝ΊΒΕΔ
    w 8FC։ൃʹඞཁͳཁૉʹͦͦ͜͜Ұ௨Γ৮ΕΒΕΔ
    w จࣈྻૢ࡞ɺೖग़ྗɺฒྻॲཧͳͲ
    w ҧ͏ݴޠɺಉ͡࢓༷Ͱ࡞Ε͹ݴޠͷൺֱ΋͠΍͍͢

    View Slide

  23. DDD@H
    )551αʔόʔͬͯԿͯ͠Δͷʁ

    View Slide

  24. DDD@H
    )551αʔόʔ͕΍͍ͬͯΔ͜ͱ
    w ΫϥΠΞϯτ͔Βͷ઀ଓΛ଴ͪड͚
    w ΫϥΠΞϯτ͔ΒૹΒΕ͖ͯͨ)551ϦΫΤετΛύʔε
    w ϦΫΤετʹج͍ͮͯ)551ϨεϙϯεΛੜ੒
    w ΫϥΠΞϯτʹϨεϙϯεΛฦ͢

    View Slide

  25. DDD@H
    )551ͷ࢓༷
    w 3'$ʢ3FRVFTU'PS$PNNFOUTʣ
    w *&5'ʹΑΔٕज़࢓༷ͷอଘɺެ։ܗࣜ
    w ϓϩτίϧ΍ϑΝΠϧϑΥʔϚοτͳͲ͕த৺
    w )551͸3'$d

    View Slide

  26. DDD@H
    IUUQTUPPMTJFUGPSHIUNMSGD

    View Slide

  27. DDD@H
    IUUQIUUQXHPSH

    View Slide

  28. DDD@H
    ؆қͳ࣮૷ͳΒ਺ඦߦఔ౓

    View Slide

  29. DDD@H
    1ZUIPOͷ4JNQMF)5514FSWFS
    w 1ZUIPOͷ4JNQMF)5514FSWFSΛࢀߟʹ͢Δͷ΋̋
    w ܥ
    w ܥ
    $ python -m SimpleHTTPServer
    $ python -m http.server

    View Slide

  30. DDD@H
    4DBMB$MPKVSF

    View Slide

  31. DDD@H
    4DBMB

    View Slide

  32. DDD@H
    4DBMB
    w +BWBͱͷ૬ޓӡ༻ੑ
    w γʔϜϨεͳݺͼग़͠ɺ+BWBඪ४ϥΠϒϥϦͷ࠶ར༻
    w ؆ܿੑ
    w লུՄೳͳߏจɺܕਪ࿦ɺڧྗͳඪ४ϥΠϒϥϦ
    w ந৅౓ͷߴ͍ίʔυɺ৽੍͍͠ޚߏจΛఆٛͰ͖Δදݱྗ
    w 8IBUͷڧௐɺ)PXͷӅณ
    w ੩తܕ෇͚
    w ݕূՄೳੑɺϦϑΝΫλͷ͠΍͢͞ɺυΩϡϝϯτੑ

    View Slide

  33. DDD@H
    4DBMBͬͯόϦόϦͷ

    ؔ਺ܕݴޠͳΜͰ͠ΐ

    View Slide

  34. IUUQTMFBOQVCDPNGQNPSUBMTSFBE

    View Slide

  35. IUUQTMFBOQVCDPNGQNPSUBMTSFBE

    View Slide

  36. DDD@H
    1MFBTF EPOUEPUIJTJO4DBMB
    .BSUJO0EFSTLZ

    View Slide

  37. DDD@H
    1MFBTF EPOUEPUIJTJO4DBMB
    .BSUJO0EFSTLZ
    ௨শখా޷ઌੜ

    View Slide

  38. DDD@H
    4DBMBͷ࡞ऀ
    1MFBTF EPOUEPUIJTJO4DBMB
    .BSUJO0EFSTLZ
    ௨শখా޷ઌੜ

    View Slide

  39. DDD@H
    ΦϒδΣΫτࢦ޲ͱؔ਺ܕͷʮ౷߹ʯ
    w ΦϒδΣΫτࢦ޲ͷ֓೦Ͱؔ਺ܕͷػೳΛղऍ
    ஋ΦϒδΣΫτ
    DBTFDMBTT
    ୅਺తσʔλܕ
    001 '1

    View Slide

  40. DDD@H
    $MPKVSF

    View Slide

  41. DDD@H
    $MPKVSF
    w -JTQ
    w จ๏͕গͳ͍ɺσʔλͱͯ͠ͷίʔυ
    w ؔ਺ܕϓϩάϥϛϯάͷͨΊͷݴޠ
    w ୈҰڃؔ਺ɺΠϛϡʔλϒϧͳσʔλߏ଄ɺ࠶ؼతͳϧʔϓ
    w +BWBͱͷ૬ޓӡ༻ੑ
    w ฒߦॲཧͷͨΊʹઃܭ
    w 3&1-Λ׆͔ͨ͠ΠϯλϥΫςΟϒΠϯΫϦϝϯλϧͳ
    ։ൃ

    View Slide

  42. DDD@H
    ίϯηϓτ͕໘ന͍
    w ঢ়ଶʹ͍ͭͯͷߟ͑ํɺ*EFOUJUZ 4UBUF 7BMVFͷ෼཭
    w γϯϓϧ͞ʹ͍ͭͯ
    ͍Ζ͍Ζܹࢗత

    View Slide

  43. DDD@H
    IUUQCPYPGQBQFSTIBUFOBCMPHDPNFOUSZTJNQMF@NBEF@FBTZ

    View Slide

  44. DDD@H
    -JTQͷγϯλοΫε
    ׅހͷ࢝·Γ͔ΒऴΘΓ·Ͱ͕୯Ґ
    (ԿΒ͔ͷॲཧ ॲཧͷର৅ͳͲ…)

    View Slide

  45. DDD@H
    $MPKVSF͸Χοίͷछྨ͕ଟ͘ɺಡΈ΍͍͢
    ͨͱ͑͹ؔ਺ͷҾ਺
    $PNNPO-JTQ
    4DIFNF
    $MPKVSF
    (defun square (x)
    (* x x))
    (define (square x)
    (* x x))
    (defn square [x]
    (* x x))

    View Slide

  46. DDD@H

    େৎ෉

    View Slide

  47. DDD@H
    جຊจ๏Ͱ΢ΥʔϛϯάΞοϓ

    View Slide

  48. DDD@H
    ࢛ଇԋࢉ
    12 + 40
    10 - 1
    2 * 3
    5 / 2
    +BWB
    4DBMB
    (+ 12 40)
    (- 10 1)
    (* 2 3)
    (/ 5 2) ; -> 5/2 ෼਺Λѻ͏Ratioܕ
    $MPKVSF

    View Slide

  49. DDD@H
    ม਺એݴ
    int x = 10;
    +BWB
    val x = 10
    val x: Int = 10
    4DBMB
    (def x 10)
    (let [y 10]
    (+ y 3))
    ; y͸letͷׅހ಺͚ͩͰࢀরͰ͖Δ
    $MPKVSF

    View Slide

  50. DDD@H
    ϝιουɾؔ਺એݴ
    public int f(int x) {
    return x + 1;
    }
    +BWB
    (defn f [x]
    (+ x 1))
    $MPKVSF
    def f(x: Int) = x + 1
    4DBMB

    View Slide

  51. DDD@H

    View Slide

  52. DDD@H
    )551αʔόʔΛ

    ࡞Γͳ͕Βֶ΅͏

    View Slide

  53. DDD@H
    ࠓճ༻ҙͨ͠)551αʔόʔ
    w ىಈ͠ɺMPDBMIPTUͷಛఆͷϙʔτͰ)551ϦΫΤετΛ଴ͪड͚Δ
    w ରԠ͢Δ)551ϦΫΤετϝιου͸(&5ͷΈ

    ͦΕҎ֎ͷϝιου΋(&5ͱΈͳ͢
    w QVCMJDσΟϨΫτϦΑΓ্ͷ֊૚΁ͷϦΫΤετʹ͸

    'PSCJEEFOΛฦ͢
    w Ϧιʔεͷ.*.&͸֎෦ϑΝΠϧͰઃఆͰ͖Δ
    w ϦΫΤετΛϒϩοΫ͠ͳ͍ʢϚϧνεϨουʣ
    w ,FFQ"MJWF͸͠ͳ͍ɻίωΫγϣϯ͸౎౓DMPTF͢Δ
    w )551$BDIF͸͠ͳ͍ɻ͸ฦ͞ͳ͍

    View Slide

  54. DDD@H
    ىಈ
    w +BWB
    NWODPNQJMF
    NWOFYFDKBWB
    w 4DBMB
    TCUSVO
    w $MPKVSF
    MFJOSVO

    View Slide

  55. DDD@H
    ͭ͘Γʹ͍ͭͯͬ͘͟Γͱ
    ├── MimeDetector.java
    ├── Request.java
    ├── RequestHandler.java
    ├── RequestParser.java
    ├── Response.java
    ├── SimpleJavaHttpServer.java
    └── WorkerThread.java
    ΞϓϦέʔγϣϯͷΤϯτϦʔϙΠϯτ
    3FRVFTU
    *OQVU4USFBN
    3FTQPOTF
    0VUQVU4USFBN
    ϦΫΤετͷύʔε
    ϦΫΤετͷϋϯυϦϯά
    Ϩεϙϯεͷ8SJUF

    View Slide

  56. DDD@H
    ͭ͘Γʹ͍ͭͯͬ͘͟Γͱ
    ├── MimeDetector.java
    ├── Request.java
    ├── RequestHandler.java
    ├── RequestParser.java
    ├── Response.java
    ├── SimpleJavaHttpServer.java
    └── WorkerThread.java
    )551ϦΫΤετΛύʔε͢Δ
    3FRVFTU
    *OQVU4USFBN
    3FTQPOTF
    0VUQVU4USFBN
    ϦΫΤετͷύʔε
    ϦΫΤετͷϋϯυϦϯά
    Ϩεϙϯεͷ8SJUF

    View Slide

  57. DDD@H
    ͭ͘Γʹ͍ͭͯͬ͘͟Γͱ
    ├── MimeDetector.java
    ├── Request.java
    ├── RequestHandler.java
    ├── RequestParser.java
    ├── Response.java
    ├── SimpleJavaHttpServer.java
    └── WorkerThread.java
    ϦΫΤετΛද͢ΦϒδΣΫτ
    3FRVFTU
    *OQVU4USFBN
    3FTQPOTF
    0VUQVU4USFBN
    ϦΫΤετͷύʔε
    ϦΫΤετͷϋϯυϦϯά
    Ϩεϙϯεͷ8SJUF

    View Slide

  58. DDD@H
    ͭ͘Γʹ͍ͭͯͬ͘͟Γͱ
    ├── MimeDetector.java
    ├── Request.java
    ├── RequestHandler.java
    ├── RequestParser.java
    ├── Response.java
    ├── SimpleJavaHttpServer.java
    └── WorkerThread.java
    ϦΫΤετ͔ΒϨεϙϯεΛੜ੒
    3FRVFTU
    *OQVU4USFBN
    3FTQPOTF
    0VUQVU4USFBN
    ϦΫΤετͷύʔε
    ϦΫΤετͷϋϯυϦϯά
    Ϩεϙϯεͷ8SJUF

    View Slide

  59. DDD@H
    ͭ͘Γʹ͍ͭͯͬ͘͟Γͱ
    ├── MimeDetector.java
    ├── Request.java
    ├── RequestHandler.java
    ├── RequestParser.java
    ├── Response.java
    ├── SimpleJavaHttpServer.java
    └── WorkerThread.java
    ϨεϙϯεΛද͢ΦϒδΣΫτ
    3FRVFTU
    *OQVU4USFBN
    3FTQPOTF
    0VUQVU4USFBN
    ϦΫΤετͷύʔε
    ϦΫΤετͷϋϯυϦϯά
    Ϩεϙϯεͷ8SJUF

    View Slide

  60. DDD@H
    ͭ͘Γʹ͍ͭͯͬ͘͟Γͱ
    ├── MimeDetector.java
    ├── Request.java
    ├── RequestHandler.java
    ├── RequestParser.java
    ├── Response.java
    ├── SimpleJavaHttpServer.java
    └── WorkerThread.java
    )551ϨεϙϯεΛ8SJUF
    3FRVFTU
    *OQVU4USFBN
    3FTQPOTF
    0VUQVU4USFBN
    ϦΫΤετͷύʔε
    ϦΫΤετͷϋϯυϦϯά
    Ϩεϙϯεͷ8SJUF

    View Slide

  61. DDD@H
    ֤ݴޠͰ΍ͬͯΈΔ
    w 4PDLFUͷѻ͍
    w ਖ਼نදݱ
    w Ϧιʔεͷ։์
    w ฒߦॲཧ
    w จࣈྻͷѻ͍

    View Slide

  62. DDD@H
    ࡞Γ࢝ΊΔίπ
    w ೉͘͠ߟ͑͗͢ͳ͍
    w ॳΊ͔Βߟ͑ํΛࠜຊతʹม͑Δඞཁ͸ͳ͍
    w O೥ޙʹ΋͏Ұ౓࡞Γ௚͢ͱ੒௕͕࣮ײͰ͖Δ͔΋

    View Slide

  63. DDD@H
    4PDLFUͷѻ͍

    View Slide

  64. DDD@H
    4PDLFU

    View Slide

  65. DDD@H
    4PDLFU
    w ௨৴ʹ͓͚ΔΤϯυϙΠϯτΛදݱͨ͠σʔλϞσϧ
    ֤ΤϯυϙΠϯτΛࣝผ͢Δ̎ͭͷ஋ɺ

    ͢ͳΘͪ*1ΞυϨεͱϙʔτ൪߸͸ɺ

    ଟ͘ͷ৔߹ιέοτ TPDLFU
    ͱݺ͹ΕΔɻ
    ʮ6/*9ωοτϫʔΫϓϩάϥϛϯάʯ

    View Slide

  66. DDD@H
    4PDLFU௨৴ͷ໛ࣜਤ
    ΫϥΠΞϯτ αʔόʔ

    View Slide

  67. DDD@H
    4PDLFU௨৴ͷ໛ࣜਤ
    ΫϥΠΞϯτ αʔόʔ
    αʔόʔιέοτ

    View Slide

  68. DDD@H
    4PDLFU௨৴ͷ໛ࣜਤ
    ΫϥΠΞϯτ αʔόʔ
    αʔόʔιέοτ
    ΫϥΠΞϯτιέοτ

    View Slide

  69. DDD@H
    4PDLFU௨৴ͷ໛ࣜਤ
    ΫϥΠΞϯτ αʔόʔ
    αʔόʔιέοτ
    ΫϥΠΞϯτιέοτ
    ઀ଓཁٻ

    View Slide

  70. DDD@H
    4PDLFU௨৴ͷ໛ࣜਤ
    ΫϥΠΞϯτ αʔόʔ
    αʔόʔιέοτ
    ΫϥΠΞϯτιέοτ
    ઀ଓ

    View Slide

  71. DDD@H
    4PDLFU௨৴ͷ໛ࣜਤ
    ΫϥΠΞϯτ αʔόʔ
    αʔόʔιέοτ
    ΫϥΠΞϯτιέοτ

    View Slide

  72. DDD@H
    4PDLFUͷѻ͍
    // αʔόʔιέοτͷੜ੒
    ServerSocket serverSocket = new ServerSocket(8080);
    while (true) {
    // ઀ଓΛ଴ͪड͚Δɻ઀ଓ͞ΕΔ·ͰϒϩοΫɻ
    Socket socket = serverSocket.accept();
    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();
    ...
    }
    4JNQMF+BWB)UUQ4FSWFSKBWBʢൈਮʣ

    View Slide

  73. DDD@H
    4PDLFUͷѻ͍
    // αʔόʔιέοτͷੜ੒
    val serverSocket = new ServerSocket(8080)
    while (true) {
    // ઀ଓΛ଴ͪड͚Δɻ઀ଓ͞ΕΔ·ͰϒϩοΫ
    val socket = serverSocket.accept
    val in = s.getInputStream
    val out = s.getOutputStream
    ...
    }
    4JNQMF)UUQ4FSWFSTDBMBʢൈਮʣ

    View Slide

  74. DDD@H
    4PDLFUͷѻ͍
    (let [server-socket (new ServerSocket 8080)]
    (while true
    (let [socket (.accept server-socket)
    in (.getInputStream socket)
    out (.getOutputStream socket)]
    ...)))
    DPSFDMKʢൈਮʣ

    View Slide

  75. DDD@H
    4PDLFUͷѻ͍ʹֶ͍ͭͯΜͩ͜ͱ
    w 4FSWFS4PDLFUΦϒδΣΫτΛੜ੒͠ɺ

    ΫϥΠΞϯτ͔Βͷ઀ଓΛBDDFQUͰ଴ͪड͚Δ
    w 4PDLFUΦϒδΣΫτʢΫϥΠΞϯτιέοτʣ͔Β

    *O0VUQVU4USFBN͕औಘͰ͖Δ
    w *OQVU4USFBN͔Β)551ϦΫΤετΛ3FBE͠ɺ

    0VUQVU4USFBNʹ)551ϨεϙϯεΛ8SJUF͢Δ

    View Slide

  76. DDD@H
    ਖ਼نදݱ

    View Slide

  77. DDD@H
    ਖ਼نදݱ
    w 4PDLFUͷ*OQVU4USFBNΛ

    ҰߦಡΉ

    ˠSFRVFTUMJOF
    w ֤ཁૉΛநग़͍ͨ͠

    View Slide

  78. DDD@H
    ਖ਼نදݱ
    w 4PDLFUͷ*OQVU4USFBNΛ

    ҰߦಡΉ

    ˠSFRVFTUMJOF
    w ֤ཁૉΛநग़͍ͨ͠

    View Slide

  79. DDD@H
    w 4PDLFUͷ*OQVU4USFBNΛ

    ҰߦಡΉ

    ˠSFRVFTUMJOF
    w ֤ཁૉΛநग़͍ͨ͠
    ਖ਼نදݱ

    View Slide

  80. DDD@H
    ໊લ෇͖άϧʔϓ

    View Slide

  81. DDD@H
    ໊લ෇͖άϧʔϓ
    w ਖ਼نදݱͷάϧʔϓʹ໊લΛ෇͚Δ͜ͱ͕Ͱ͖Δ
    w άϧʔϓͷॱং͕มΘͬͨͱͯ͠΋औΓग़͢ॲཧ͸ͦͷ··
    import java.util.regex.*;
    String regex = "(?\\d+)/(?\\d+)/(?\\d+)";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher("2017/11/18");
    if (m.find()) {
    System.out.println(m.group("year")); // 2017
    System.out.println(m.group("month")); // 11
    System.out.println(m.group("day")); // 18
    }

    View Slide

  82. DDD@H
    w ϦΫΤετϥΠϯͷ֤ཁૉʹ໊લΛ෇͚ͯநग़
    public static Pattern requestLinePattern =
    Pattern.compile("(?.*) (?.*?) (?.*?)");
    public Request fromInputStream(InputStream in){
    BufferedReader reader =
    new BufferedReader(new InputStreamReader(in));
    String requestLine = reader.readLine();
    Matcher matcher = requestLinePattern.matcher(requestLine);
    if (!matcher.find()) return null;
    String method = matcher.group("method");
    String targetPath = matcher.group("path");
    String httpVersion = matcher.group("version");
    return new Request(method, targetPath, httpVersion);
    }
    ໊લ෇͖άϧʔϓ
    3FRVFTU1BSTFSKBWBʢൈਮʣ

    View Slide

  83. DDD@H
    ύλʔϯϚον
    S

    View Slide

  84. DDD@H
    ύλʔϯϚον
    w +BWBͷTXJUDIจʹࣅ͍ͯΔ͕ɺΑΓॊೈͰڧྗ
    w ஋ʹҰக͢Δ͔͚ͩͰͳ͘ɺܕ΍ߏ଄Ͱ΋෼ذ
    0 match {
    case 0 => "Zero" // "Zero"
    case _ => "Other"
    }
    List(1, 2, 3) match {
    case List(_, x, _) => x // 2
    case _ => -1
    }
    1 match {
    x: Int => s"$x͸Int" // 1͸Int
    x: String => s"$x͸String"
    x => s"$x͸???"
    }

    View Slide

  85. DDD@H
    ύλʔϯϚον
    w ࠓޙ+BWBʹ΋ೖΔ͔΋͠Εͳ͍
    IUUQPQFOKELKBWBOFUKFQT

    View Slide

  86. DDD@H
    ύλʔϯϚον
    w ਖ਼نදݱΦϒδΣΫτʹରͯ͠΋Ϛονͤ͞ΒΕΔ
    val pattern = "(.+)/(.+)/(.+)".r //.rͰregexܕ
    "2017/11/18" match {
    case pattern(y, m, d) => s"${y}೥${m}݄${d}೔"
    case _ => "???"
    }

    View Slide

  87. DDD@H
    ύλʔϯϚον
    val pattern = "(.+) (.+) (.+)".r
    requestLine match {
    case pattern(method, path, version) =>
    Some(Request(method, path, version))
    case _ => None
    }
    3FRVFTU1BSTFSTDBMBʢൈਮʣ

    View Slide

  88. DDD@H
    0QUJPOܕ
    requestLine match {
    case pattern(method, path, version) =>
    Some(Request(method, path, version))
    case _ => None
    }
    w +BWBͰ͍͏0QUJPOBM
    w 4PNFͱ/POF͔ΒͳΔܕ
    w ஋͕͋Δ͔ͳ͍͔෼͔Βͳ͍ঢ়ଶΛද͢
    w ஋͕ଘࡏ͢Δ͔ͷνΣοΫΛڧ੍Ͱ͖Δ

    View Slide

  89. DDD@H

    SFpOE

    View Slide

  90. DDD@H
    SFpOE
    w ਖ਼نදݱʹϚονͨ͠จࣈྻΛऔಘ
    w Ҿ਺ʹάϧʔϓԽͨ͠ਖ਼نදݱΦϒδΣΫτΛ౉͢ͱɺ

    ઌ಄ʹ͸Ϛονͨ͠จࣈྻશମɺҎ߱ʹΩϟϓνϟ͞ΕͨจࣈྻͷϕΫλʔ
    ;; #"" ͸java.util.regex.PatternͷϦςϥϧ
    (re-find #"(.+)/(.+)/(.+)" "2017/11/18")
    ;; => ["2017/11/18" "2017" "11" "18"]
    ;; restͰઌ಄Ҏ֎ͷཁૉΛऔಘ
    (rest (re-find #"(.+)/(.+)/(.+)" "2017/11/18"))
    ;; => ("2017" "11" "18")

    View Slide

  91. DDD@H
    [JQNBQ
    w ڧྗͳίϨΫγϣϯϥΠϒϥϦ͸$MPKVSFͷಛ௃
    w [JQNBQ͸ͭͷίϨΫγϣϯ͔Β.BQΛ࡞Δ
    w $MPKVSFͰ͸ΫϥεΑΓ΋.BQΛ޷Ή
    (zipmap [:a :b :c]
    [1 2 3])
    ;; => {:a 1, :b 2, :c 3}

    View Slide

  92. DDD@H
    SFpOE[JQNBQ
    (let [line (.readLine reader)]
    (zipmap [:method :path :version]
    (rest (re-find #"(.+) (.+) (.+)" line))))
    ;; => {:method "GET", :path "/", :version "HTTP/1.1"}
    SFRVFTU@QBSTFSDMKʢൈਮʣ

    View Slide

  93. DDD@H
    SFpOE[JQNBQ
    (let [line (.readLine reader)]
    (zipmap [:method :path :version]
    (rest (re-find #"(.+) (.+) (.+)" line))))
    ;; => {:method "GET", :path "/", :version "HTTP/1.1"}
    SFRVFTU@QBSTFSDMKʢൈਮʣ
    <NFUIPEQBUIWFSTJPO>
    <(&5)551>

    View Slide

  94. DDD@H
    SFpOE[JQNBQ
    (let [line (.readLine reader)]
    (zipmap [:method :path :version]
    (rest (re-find #"(.+) (.+) (.+)" line))))
    ;; => {:method "GET", :path "/", :version "HTTP/1.1"}
    SFRVFTU@QBSTFSDMKʢൈਮʣ
    <NFUIPEQBUIWFSTJPO>
    <(&5)551>

    View Slide

  95. DDD@H
    ਖ਼نදݱʹֶ͍ͭͯΜͩ͜ͱ
    ໊લ෇͖άϧʔϓ
    ύλʔϯϚον

    S
    SFpOE


    ఴࣈͰΞΫηε͢ΔΑΓ҆৺
    ߏ଄ͷ෼ղʹ΋࢖͑Δ
    ݁Ռ͸ίϨΫγϣϯɺڧྗͳίϨΫγϣϯૢ࡞ͱ૊Έ߹Θͤͯ

    View Slide

  96. DDD@H
    Ϧιʔεͷղ์

    View Slide

  97. DDD@H
    Ϧιʔεͷղ์
    w ετϦʔϜ΍%#ίωΫγϣϯɺιέοτ͸

    ࢖͍ऴΘͬͨΒDMPTF
    w ๨ΕΔͱϝϞϦϦʔΫͷݪҼʹͳΔ͜ͱ͕͋Δ
    w खͰDMPTFॻ͖ͨ͘ͳ͍ʂ

    View Slide

  98. DDD@H
    5SZXJUI3FTPVSDFT

    View Slide

  99. DDD@H
    5SZXJUI3FTPVSDFT
    try (InputStream in = new FileInputStream(file)) {
    // Կ͔ϦιʔεΛѻ͏ॲཧ
    }
    // try۟Λൈ͚ͨΒclose
    w USZ۟Λൈ͚ͨΒࣗಈͰDMPTF
    w ର৅͸KBWBJP$MPTFBCMF 

    KBWBMBOH"VUP$MPTFBCMFͷ࣮૷Ϋϥε

    View Slide

  100. DDD@H
    -PBO1BUUFSO

    View Slide

  101. DDD@H
    -PBO1BUUFSO
    w ʮआΓͨΒฦ͢ʯΛ࣮֬ʹߦ͏
    w ੍ޚߏ଄ͷΑ͏ʹݟ͔͚࣮ͤͯ͸ϝιου
    val reader = new BufferedReader(...)
    using(reader) { r =>
    // readerΛ࢖ͬͨԿ͔ͷॲཧ
    }
    // ϒϩοΫΛൈ͚ͨΒreader͸close͞Ε͍ͯΔ

    View Slide

  102. DDD@H
    -PBO1BUUFSOͷ࣮૷
    def using[A, R <: Closeable](resource: R)(f: R => A): A = {
    try {
    f(resource)
    } finally {
    resource.close()
    }
    }

    View Slide

  103. DDD@H
    -PBO1BUUFSOͷ࣮૷
    def using[A, R <: Closeable](resource: R)(f: R => A): A = {
    try {
    f(resource)
    } finally {
    resource.close()
    }
    }
    ܕม਺3͸$MPTFBCMF

    View Slide

  104. DDD@H
    -PBO1BUUFSOͷ࣮૷
    def using[A, R <: Closeable](resource: R)(f: R => A): A = {
    try {
    f(resource)
    } finally {
    resource.close()
    }
    }
    3ܕͷԿ͔Λड͚औΓɺԿΒ͔ͷܕ"Λฦؔ͢਺ΛҾ਺ʹͱΔ

    View Slide

  105. DDD@H
    -PBO1BUUFSOͷ࣮૷
    def using[A, R <: Closeable](resource: R)(f: R => A): A = {
    try {
    f(resource)
    } finally {
    resource.close()
    }
    }
    Ϧιʔεʹରͯؔ͠਺Λద༻

    View Slide

  106. DDD@H
    -PBO1BUUFSOͷ࣮૷
    def using[A, R <: Closeable](resource: R)(f: R => A): A = {
    try {
    f(resource)
    } finally {
    resource.close()
    }
    }
    ࠷ޙʹDMPTF

    View Slide

  107. DDD@H
    ׅހ
    ͱதׅހ\^
    "hoge".startsWith{"ho"} // ͋·Γ΍Βͳ͍
    "hoge".replace{"ho", "fu"} // Ͱ͖ͳ͍
    "hoge" map { c =>
    c.someFunc
    ...
    } // Α͘΍Δ
    w Ҿ਺͕Ұ͚ͭͩͷ৔߹ɺׅހΛதׅހͰॻ͍ͯ΋ྑ͍
    w Ҿ਺ʹؔ਺Λ౉͢৔߹ɺதׅހΛ࢖͏͜ͱ͕Α͋͘Δ

    View Slide

  108. DDD@H
    -PBO1BUUFSO
    using(socket) { s =>
    val in = s.getInputStream
    val out = s.getOutputStream
    val request = parser.fromInputStream(in)
    val response = request.map(handleRequest)
    response.foreach(_.writeTo(out))
    }
    4JNQMF)UUQ4FSWFSTDBMBʢൈਮʣ

    View Slide

  109. DDD@H
    XJUIPQFO

    View Slide

  110. DDD@H
    w -PBO1BUUFSOʹࣅͨXJUIPQFOͱ͍͏ϚΫϩ
    w MFUͱಉ͡Α͏ͳײ͡Ͱ࢖͏
    XJUIPQFO
    (with-open [f (io/file "test.txt")]
    ...)

    View Slide

  111. DDD@H
    XJUIPQFO
    (with-open [s socket]
    (-> (request-parser/from-input-stream
    (.getInputStream s))
    (request-handler/handle-request)
    (response-writer/write (.getOutputStream s))))
    DPSFDMKʢൈਮʣ

    View Slide

  112. DDD@H
    Ϧιʔεͷղ์ʹֶ͍ͭͯΜͩ͜ͱ
    5SZXJUI3FTPVSDFT
    -PBO1BUUFSO
    XJUIPQFO
    USZ۟Λൈ͚Δ࣌ʹDMPTF
    ؔ਺͕஋Ͱ͋Δ͜ͱΛ׆͔͠ɺ੍ޚߏจͷΑ͏ʹݟͤΔ
    DMPTFͯ͘͠ΕΔMFUΈ͍ͨͳΠϝʔδ

    View Slide

  113. DDD@H
    ฒߦॲཧ

    View Slide

  114. DDD@H
    ฒߦॲཧ
    w ϦΫΤετΛγϦΞϧʹॲཧ͢ΔͱଞͷϦΫΤετΛ଴ͨͤͯ͠·͏
    w ͳͷͰϦΫΤετΛड͚෇͚ͨઌ͸ฒߦʹॲཧ͢Δ
    w +7.ݴޠͳͷͰϚϧνεϨουͰ

    View Slide

  115. DDD@H
    5ISFBE
    &YFDVUPS4FSWJDF

    View Slide

  116. DDD@H
    5ISFBE
    class HogeThread extends Thread {
    public void run() {
    // Կ͔ඇಉظʹ࣮ߦ͍ͨ͠ॲཧ
    }
    }
    HogeThread h = new HogeThread();
    h.start();
    class FugaRunnable implements Runnable {
    public void run() {
    // Կ͔ඇಉظʹ࣮ߦ͍ͨ͠ॲཧ
    }
    }
    FugaRunnable f = new Thread(new FugaRunnable());
    f.start();
    5ISFBEΛFYUFOET3VOOBCMFΛJNQMFNFOUT

    View Slide

  117. DDD@H
    5ISFBE
    public class WorkerThread extends Thread {
    private Socket socket;
    private RequestParser parser;
    private RequestHandler handler;
    public WorkerThread(
    Socket socket, RequestParser parser,
    RequestHandler handler) {
    ...
    8PSLFS5ISFBEKBWBʢൈਮʣ
    4JNQMF+BWB)UUQ4FSWFSKBWBʢൈਮʣ
    Thread worker =
    new WorkerThread(socket, parser, handler);
    worker.start();

    View Slide

  118. DDD@H
    &YFDVUPS4FSWJDF
    ExecutorService cachedPool =
    Executors.newCachedThreadPool();
    cachedPool.execute(runnable);
    ExecutorService fixedPool =
    Executors.newFixedThreadPool(4);
    fixedPool.execute(runnable);
    w ʮλεΫʯΛผεϨουͰॲཧ͢ΔͨΊͷ࢓૊Έ
    w εϨουϓʔϧͷछྨΛࢦఆͰ͖Δ

    View Slide

  119. DDD@H
    'VUVSF

    View Slide

  120. DDD@H
    'VUVSF
    w 'VUVSFBQQMZ͸౉͞ΕͨॲཧΛඇಉظʹ࣮ߦ
    w ͍ͭͲͷΑ͏ʹඇಉظʹ࣮ߦ͢Δ͔͸&YFDVUJPO$POUFYU࣍ୈ
    import scala.concurrent.Future
    // ForkJoinPoolɺσϑΥϧτͰ͸ίΞ਺෼ͷฒྻ౓Ͱॲཧ
    import scala.concurrent.ExecutionContext.
    Implicits.global
    val result: Future[User] = Future {
    userRepository.fetch(userId)
    }
    result.map(user => user.id)

    View Slide

  121. DDD@H
    &YFDVUJPO$POUFYU͸Ͳ͏ड͚औΔʁ
    w 'VUVSFBQQMZʹ͸Ҿ਺ϒϩοΫ͕ͭ
    w ͭ໨ͷҾ਺ϒϩοΫͰ&YFDVUJPO$POUFYUΛड͚औΔ
    object Future {
    ...
    def apply[T](body: =>T)(implicit executor: ExecutionContext)
    }
    Future {
    userRepository.fetch(user)
    }
    Future.apply(
    userRepository.fetch(user)
    )

    View Slide

  122. DDD@H
    JNQMJDJU8IBUͱ)PXͷ෼཭
    w )PX͕ڊେʹͳΔͱɺίʔυͷຊདྷͷҙਤ͕ຒ΋Εͯ͠·͏
    w JNQMJDJUͷେ͖ͳϞνϕʔγϣϯ͸)PXͷӅณ
    w 8IBUͱ)PXΛ෼཭͢Δ͜ͱͰɺ໨తΛ୺తʹࣔ͢͜ͱ͕Ͱ͖Δ
    val values: Seq[(String, Option[Int])]
    val sorted = sort(values)(
    tuple2Comparator(
    stringComparator,
    optionComparator(intComparator)))
    val sorted = sort(values) // implicit

    View Slide

  123. DDD@H
    IUUQHBLV[[[[HJUIVCJPTMJEFTJNQMJDJU@SFJOUSPEVDUJPO

    View Slide

  124. DDD@H
    UISFBE

    View Slide

  125. DDD@H
    $MPKVSFͷฒߦॲཧؔ਺
    w $MPKVSFͷฒߦॲཧؔ਺͸ͨ͘͞Μ͋Δ
    w HP
    w UISFBE
    w TFOE
    w TFOEPGG
    w GVUVSF
    w FUD

    View Slide

  126. DDD@H
    IUUQUZBOPTIFMpODDPNQPTUDMPKVSFDPODVSSFOU

    View Slide

  127. DDD@H
    $MPKVSFͷฒߦॲཧؔ਺
    εϨουϓʔϧ εϨου਺
    TFOE 'JYFE5ISFBE1PPM ίΞ਺
    TFOEPGG $BDIFE5ISFBE1PPM ੍ݶͳ͠
    GVUVSFGVUVSFDBMM
    QNBQQDBMMT
    $BDIFE5ISFBE1PPM ੍ݶͳ͠
    HP 'JYFE5ISFBE1PPM ίΞ਺
    UISFBE

    UISFBEDBMM
    $BDIFE5ISFBE1PPM ੍ݶͳ͠
    SFEVDFST 'PSL+PJO1PPM ࣗಈ੍ޚ
    IUUQUZBOPTIFMpODDPNQPTUDMPKVSFDPODVSSFOU

    View Slide

  128. DDD@H
    *0ό΢ϯυ$16ό΢ϯυ
    w $MPKVSFͷฒߦॲཧؔ਺͸ɺ*0$16ό΢ϯυͷछྨʹେผ
    *0ό΢ϯυͳॲཧ͸ɺ࣮ߦதͷॲཧ͕$16ΑΓ΋*0ॲཧʹ

    ڧ͘ґଘ͠·͢ɻ%#ΞΫηεͱ͔ϦϞʔτ௨৴ͱ͔Ͱ͢Ͷɻ

    ผεϨουͰ͜ͷॲཧΛ࣮ߦͨ͠৔߹ɺεϨου͸େ෦෼Λɺ

    *0ॲཧ଴ͪঢ়ଶͰա͝͠·͢ɻ
    $16ό΢ϯυͳॲཧ͸ɺ్தʹ*0଴ͪͷΑ͏ͳʮ଴ػʯ͕

    ൃੜͤͣɺ$16ΛͿΜճ͠ଓ͚ΔΑ͏ͳॲཧͰ͢ɻ

    શσʔλ͕ϝϞϦʹࡌ͍ͬͯͯɺ$16͕ϑϧՔಇͰͦΕΒΛ

    ॲཧ͢ΔΑ͏ͳέʔεͰ͢ɻ
    IUUQUZBOPTIFMpODDPNQPTUDMPKVSFDPODVSSFOU

    View Slide

  129. DDD@H
    $MPKVSFͷฒߦॲཧؔ਺
    εϨουϓʔϧ εϨου਺
    TFOE 'JYFE5ISFBE1PPM ίΞ਺
    TFOEPGG $BDIFE5ISFBE1PPM ੍ݶͳ͠
    GVUVSFGVUVSFDBMM
    QNBQQDBMMT
    $BDIFE5ISFBE1PPM ੍ݶͳ͠
    HP 'JYFE5ISFBE1PPM ίΞ਺
    UISFBE

    UISFBEDBMM
    $BDIFE5ISFBE1PPM ੍ݶͳ͠
    SFEVDFST 'PSL+PJO1PPM ࣗಈ੍ޚ
    IUUQUZBOPTIFMpODDPNQPTUDMPKVSFDPODVSSFOU

    View Slide

  130. DDD@H
    $MPKVSFͷฒߦॲཧؔ਺
    εϨουϓʔϧ εϨου਺
    TFOE 'JYFE5ISFBE1PPM ίΞ਺
    TFOEPGG $BDIFE5ISFBE1PPM ੍ݶͳ͠
    GVUVSFGVUVSFDBMM
    QNBQQDBMMT
    $BDIFE5ISFBE1PPM ੍ݶͳ͠
    HP 'JYFE5ISFBE1PPM ίΞ਺
    UISFBE

    UISFBEDBMM
    $BDIFE5ISFBE1PPM ੍ݶͳ͠
    SFEVDFST 'PSL+PJO1PPM ࣗಈ੍ޚ
    IUUQUZBOPTIFMpODDPNQPTUDMPKVSFDPODVSSFOU

    View Slide

  131. DDD@H
    UISFBE
    (thread
    (with-open [s socket
    in (.getInputStream s)
    out (.getOutputStream s)]
    (-> (request-parser/from-input-stream in)
    (request-handler/handle-request)
    (response-writer/write out))))
    DPSFDMKʢൈਮʣ

    View Slide

  132. DDD@H
    ฒߦॲཧʹֶ͍ͭͯΜͩ͜ͱ
    5ISFBE

    &YFDVUPS4FSWJDF
    'VUVSF
    UISFBE
    FYUFOET5ISFBEJNQMFNFOUT3VOOBCMF
    5ISFBE্ཱͪ͛Ͱ͸ͳ͍ɻ

    Ͳ͏࣮ߦ͢Δ͔͸&YFDVUJPO$POUFYU࣍ୈɻ

    JNQMJDJUʹΑΔ)PXͷӅณɻ
    *0$16ό΢ϯυ͔Λҙࣝ͠Α͏

    View Slide

  133. DDD@H
    จࣈྻͷѻ͍

    View Slide

  134. DDD@H
    จࣈྻ݁߹
    w ϨεϙϯεʢΦϒδΣΫτϚοϓʣ͔Β

    )551ϨεϙϯεϔομΛ૊Έཱ͍ͯͨ
    public class Response {
    public final Status status;
    public final String contentType;
    public final int contentLength;
    public final byte[] body;
    }

    View Slide

  135. DDD@H

    4USJOH#VJMEFS

    View Slide

  136. DDD@H
    4USJOH#VJMEFS
    String response =
    "HTTP/1.1 " + status.statusCode + CRLF +
    "Server: SimpleJavaHttpServer" + CRLF +
    "Content-Type: " + contentType + CRLF +
    "Content-Length: " + 

    String.valueOf(contentLength) + CRLF +
    "Connection: Close" + CRLF +
    CRLF;
    3FTQPOTFKBWBʢൈਮʣ
    ࠷దԽ͞ΕΔ͔ࣗ৴͕ͳ͚Ε͹KBWBQD

    View Slide

  137. DDD@H
    4USJOH*OUFSQPMBUJPO
    5SJQMF2VPUF

    View Slide

  138. DDD@H
    4USJOH*OUFSQPMBUJPO
    w จࣈྻϦςϥϧͷલʹTΛ෇͚Δͱɺม਺Λల։Ͱ͖Δ
    val price = 1000
    s"Price is $price"
    // => Price is 1000

    View Slide

  139. DDD@H
    5SJQMF2VPUF
    "Hello triple quote!\nHello stripMargin!"
    """Hello triple quote!
    Hello stripMargin!"""
    """|Hello triple quote!
    |Hello stripMargin!""".stripMargin
    w վߦΛؚΉจࣈྻΛຒΊࠐΉʹ͸ɺΛ࢖͏
    w ΠϯσϯτΛଗ͑Δʹ͸Πϯσϯτจࣈ c
    ͱTUSJQ.BSHJOΛ࢖͏

    View Slide

  140. DDD@H
    4USJOH*OUFSQPMBUJPOͱ5SJQMF2VPUF
    val response =
    s"""HTTP/1.1 ${status.value}
    |Date: ${rfc1123Formatter.format(now)}
    |Server: SimpleScalaHttpServer
    |Content-Type: $contentType
    |Content-Length: ${body.length.toString}
    |Connection: Close
    |
    |""".stripMargin
    3FTQPOTFTDBMBʢൈਮʣ

    View Slide

  141. DDD@H
    TUS

    View Slide

  142. DDD@H
    w $MPKVSFͰ͸จࣈྻͷ݁߹͸Ͱ͸ͳ͘TUS
    w Մม௕Ҿ਺ɺ4ࣜͳΒͰ͸
    TUS
    (+ "hoge" "fuga")
    ClassCastException java.lang.String cannot
    be cast to java.lang.Number
    clojure.lang.Numbers.add (Numbers.java:128)
    (str "hoge" "fuga" "piyo")
    // => hogefugapiyo

    View Slide

  143. DDD@H
    TUS
    (let [header (str
    "HTTP/1.1" sp status sp reason-phrase crlf
    "Content-Length:" (count body) crlf
    "Content-Type:" content-type crlf
    "Connection: Close" crlf
    crlf)]
    ...)
    SFTQPOTF@XSJUFSDMKʢൈਮʣ

    View Slide

  144. DDD@H
    จࣈྻ݁߹ʹֶ͍ͭͯΜͩ͜ͱ

    4USJOH#VJMEFS
    4USJOH*OUFSQPMBUJPO

    5SJQMF2VPUF
    TUS
    KBWBQD
    ͪΐͬͱͨ͠ςϯϓϨʔτΤϯδϯΈ͍ͨʹ࢖͑Δ
    ָ͞͸4ࣜͳΒͰ͸ɻͪΐͬͱ-JTQ͕޷͖ʹͳΔ

    View Slide

  145. DDD@H
    ֤ݴޠͰ΍ͬͯΈͨ
    w 4PDLFUͷѻ͍
    w ਖ਼نදݱ
    w Ϧιʔεͷ։์
    w ฒߦॲཧ
    w จࣈྻͷѻ͍

    View Slide

  146. DDD@H
    ·ͱΊ

    View Slide

  147. DDD@H
    )551αʔόʔΛ࡞ͬͯݴޠΛֶ΅͏
    w %#΍ը໘Λ༻ҙ͢Δखؒͳ͘ɺखܰʹ։ൃ͕࢝ΊΒΕΔ
    w 8FC։ൃʹඞཁͳཁૉʹͦͦ͜͜Ұ௨Γ৮ΕΒΕΔ
    w จࣈྻૢ࡞ɺೖग़ྗɺฒྻॲཧͳͲ
    w ࠷ॳ͸೉͘͠ߟ͑͗͢ͳ͍ɻ

    ॳΊ͔Βߟ͑ํΛࠜຊతʹม͑Δඞཁ͸ͳ͍
    w طʹ஌͍ͬͯΔ͜ͱͱEJGGΛͱͬͯΈΑ͏
    w ͦͷݴޠͷੈք؍Λ஌Δख͕͔Γ͕ͦͷEJGGʹ͋Δ͔΋

    View Slide

  148. DDD@H
    w ڭཆͱͯ͠ͷ$MPKVSFʢճ໨ظ೔ະఆʣ
    w ڭཆͱͯ͠ͷ4DBMBʢ༧ఆʣ
    w DPOQBTTͰ%$VCFͷϝϯόʔʹͳΔͱ

    ͓஌Β͕ͤಧ͖·͢
    ڭཆγϦʔζ༧ఆ͍ͯ͠·͢

    View Slide

  149. DDD@H

    (PPE$PEJOH

    View Slide