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

LINE NEWSにおけるJava移行の5年間の歩みとこれから / Five Years of Java Migration and the Future of LINE NEWS

LINE NEWSにおけるJava移行の5年間の歩みとこれから / Five Years of Java Migration and the Future of LINE NEWS

LINE NEWSでは約5年の歳月をかけて、バックエンドの開発言語をPerlからJavaへ移行してきました。
本セッションでは、Javaに移行した理由や、どのように移行していったのか、また、移行途中で発生したイシューについてどのように対処したかをご説明します。
技術的負債の返済やトラブルシューティングにご興味がある方は是非ご視聴ください。

森藤 賢司 / LINE

以下イベントでの登壇資料となります。
https://fortee.jp/jjug-ccc-2022-fall/proposal/21d0b5f4-2f79-41ee-a740-8eebfe0100ff

LINE Developers
PRO

November 27, 2022
Tweet

More Decks by LINE Developers

Other Decks in Technology

Transcript

  1. LINE NEWSにおける
    Java移行の5年間の歩みとこれから
    LINE株式会社 森藤賢司
    2022.11

    View Slide

  2. 1SPGJMF
    ೥݄ த్ೖࣾ
    -*/&."--ɺ-*/&Ϊϑτɺ-*/&#-0(ͳͲ
    1FSMͰ࣮૷͞ΕͨαʔϏεͷόοΫΤϯυ։ൃ
    Λओʹ୲౰
    ೥͔Β-*/&/&84ͷόοΫΤϯυ։ൃʹ
    ܞΘΓɺ೥͝Ζ͔Β+BWBΛϝΠϯͰॻ͖
    ࢝ΊΔ
    ৿౻ ݡ࢘ ,FOKJ .PSJUP
    -*/&גࣜձࣾ
    /&84։ൃνʔϜ
    Ϛωʔδϟʔ

    View Slide

  3. "HFOEB
    -*/& /&84ʹ͍ͭͯ
    1FSMUP+BWBϓϩδΣΫτ
    ϦϓϨΠεதʹൃੜͨ͠Πγϡʔ
    -*/&/&84ͷ͜Ε͔Β

    View Slide

  4. -*/& /&84ʹ͍ͭͯ

    View Slide

  5. χϡʔελϒ
    • -*/& "QQ಺ͷʮχϡʔεʯλϒ
    • ࠓ࿩୊ͷχϡʔε΍Ϣʔβʔͷڵຯʹ߹ΘͤͨهࣄΛදࣔ
    • Ϣʔβʔ͕ઃఆͨ͠ΩʔϫʔυʹϚον͢Δ࠷৽هࣄΛදࣔ
    Ͱ͖ΔʮϑΥϩʔʯλϒͳͲͦͷଞʹ΋͍͔ͭ͘ͷػೳ͕͋
    Δ

    View Slide

  6. χϡʔελϒ
    • ʮ஍ҬʯλϒΛ݄ʹ৽ઃ ʢ౎಺ͷҰ෦
    ϢʔβʔͷΈʣ
    • ݱࡏ஍ɾډॅ஍ɾۈ຿஍ɾΑ͘ߦ͘஍ҬͳͲ
    Ϣʔβʔͷੜ׆ΤϦΞʹີணͨ͠৘ใΛ഑৴
    • ஍Ҭ৘ใͰ͋Δχϡʔεɺఱؾɺӡߦ৘ใɺ
    ίϩφ৘ใΛఏڙ

    View Slide

  7. μΠδΣετ
    • -*/&ެࣜΞΧ΢ϯτͰχϡʔεΛఆ࣌഑৴͢Δػೳ
    • ଎ใੑͷߴ͍χϡʔε͸߸֎ͱͯ͠ଈ࣌഑৴͢Δ͜ͱ΋Ͱ͖Δ
    • Ϣʔβʔ͕ڵຯ͕͋Δ-*/&ެࣜΞΧ΢ϯτͱ༑ͩͪʹͳΔ͜
    ͱͰهࣄΛड͚औΔ͜ͱ͕Ͱ͖Δ

    View Slide

  8. -*/&εϚʔτ௨஌
    • Ϣʔβʔ͕ઃఆͨ͠৘ใΛϓογϡ௨஌Ͱ഑৴ͯ͘͠ΕΔػೳ
    • ఱؾ༧ใ
    • ๷ࡂ଎ใ
    • ϑΥϩʔதͷΩʔϫʔυʹϚον͢Δ৽ணهࣄ
    • FUD

    View Slide

  9. 5
    τϥϑΟοΫ
    CZUFTEBZ
    .
    $%/&EHF˞
    SFRVFTUTTFD
    QFBL

    ,
    0SJHJO ˞
    ˞೥݄࣌఺
    ˞೥݄࣌఺ɻը૾΍ಈըͷτϥϑΟοΫ͸আ͘
    CZUFTEBZ
    5
    0SJHJO ˞
    ."6˞

    View Slide


  10. αʔϏεϩʔϯν
    /BUJWF "QQ8FC


    -*/&ʹχϡʔελ
    ϒ௥Ճ
    -*/&/&84ͷྺ࢙

    ݕࡧػೳ௥Ճ

    μΠδΣετ഑৴։࢝

    χϡʔελϒͷϦ
    χϡʔΞϧ

    Ϣʔβʔ୯Ґͷهࣄ
    Ϩίϝϯσʔγϣϯ

    χϡʔελϒͷϦ
    χϡʔΞϧ

    /BUJWF "QQ൛
    -*/& /&84Ϋϩʔζ

    εϚʔτ௨஌
    ๷ࡂ଎ใ௥Ճ

    ϑΥϩʔλϒ௥Ճ

    ஍Ҭλϒ
    ݶఆެ։

    View Slide

  11. 1FSMUP+BWBϓϩδΣΫτ
    d

    View Slide

  12. +BWBϦϓϨΠεલͷγεςϜ֓ཁ
    -PBE #BMBODFS
    3FWFSTF1SPYZ 8FC"QQ 1FSM

    View Slide

  13. ͳͥ+BWBʹϦϓϨΠε͢Δඞཁ͕͋ͬͨͷ͔
    • 1FSMΤϯδχΞෆ଍
    • ࣾ಺Ͱ΋ෆ଍͍ͯ͠Δ
    • ৽ن࠾༻΋೉͍͠
    • -*/&ࣾ಺Ͱ͸+7.ݴޠ޲͚ͷΤίγεςϜ͕ॆ࣮͍ͯ͠Δ
    • %FQMPZNFOU -PH.BOBHFNFOU $PNNPO-JCSBSZ FUD
    • ӡ༻࣮੷΋ଟ͘ɺφϨοδ΋஝ੵ͍ͯ͠Δ

    View Slide

  14. ݴޠϦϓϨΠεͷͭΒΈ
    ػೳ։ൃ͸ࢭΊΒΕͳ͍
    1FSM͕ॻ͚ΔΤϯδχΞͰͳ͍ͱطଘͷ࣮૷Λཧղ͢Δͷ͕೉͍͠
    ࢖ΘΕͳ͘ͳͬͨ"1*ͳͲ͕ଘࡏ͠ɺͲΕΛҠߦ͢Ε͹͍͍ͷ͔Θ͔Γʹ͍͘

    View Slide

  15. ͲͷΑ͏ʹϦϓϨΠε͔ͨ͠
    • ৽ػೳ͸+BWBͰ࡞Δ
    • ػೳվमͷ৔߹΋ՄೳͳݶΓ+BWBʹϦϓϨΠε͢Δ
    • ػೳվमҎ֎ͰϦϓϨΠεͷࡍ͸ɺ"1* TQFD͸ݪଇมߋ͠ͳ͍
    • ϑϩϯτΤϯυଆ΍2"ͷίετ͕ൃੜ͢Δ
    • ৽چ"1*ͷ୯७ͳൺֱݕূ͕ͮ͠Β͘ͳΔ
    ػೳ։ൃ͸ࢭΊΒΕͳ͍

    View Slide

  16. +BWBϦϓϨΠεલͷαʔόʔߏ੒
    -PBE #BMBODFS
    3FWFSTF1SPYZ 8FC"QQ 1FSM

    /api/hoge/1

    View Slide

  17. +BWBϦϓϨΠεதͷαʔόʔߏ੒
    -PBE #BMBODFS
    3FWFSTF1SPYZ 8FC"QQ 1FSM

    /api/hoge/1
    8FC"QQ +BWB

    /api/hoge/**
    /z/**

    View Slide

  18. ͲͷΑ͏ʹϦϓϨΠε͔ͨ͠
    • 1FSMͱ+BWBͷ྆ํॻ͚ΔΤϯδχΞ͕ϦϓϨΠε͢Δͷ͕ཧ૝
    • 1FSMΤϯδχΞ͕࣮૷ΛυΩϡϝϯτʹىͯ͜͠ɺͦͷυΩϡϝϯτΛ΋ͱʹ+BWBΤϯδχΞ͕࣮૷
    • ͜ͷ৔߹υΩϡϝϯτΛॻ͍ͨ1FSMΤϯδχΞ͕ग़དྷ্͕ͬͨ"1*ͷݕূΛߦ͏
    • 1FSMΤϯδχΞ΋؆୯ͳ΋ͷ͔Β+BWB࣮૷ʹτϥΠ
    1FSM͕ॻ͚ΔΤϯδχΞͰͳ͍ͱطଘͷ࣮૷Λཧղ͢Δͷ͕೉͍͠

    View Slide

  19. ͲͷΑ͏ʹϦϓϨΠε͔ͨ͠
    • Ҡߦͱಉ࣌ฒߦͰ1FSMͷະ࢖༻ίʔυ࡟আ΋࣮ࢪ
    • ίʔυྔ͕ݮΓҠߦ࿙Εʹؾ͖ͮ΍͘͢ͳΔ
    • ௚ۙͷΞΫηεϩάʹه࿥ͷͳ͍"1*͸࡟আ
    • ࢖ΘΕ͍ͯΔ͔Ͳ͏͔ෆ໌ͳ"1* ·ΕʹΞΫηε͕͋Δ͕ϑϩϯτΤϯυͰ͸࢖ΘΕ͍ͯͳ͍͸ͣͷ"1*

    ͸ঃʑʹϑΣʔυΞ΢τ
    • Ұఆ֬཰ͰΤϥʔίʔυΛฦ͠ɺ໰୊͕ൃੜ͠ͳ͍͔िؒ΄ͲϞχλϦϯά
    • ໰୊ͳ͚Ε͹֬཰Λ্͍͖͛ͯɺ࠷ऴతʹ͸"1*Λ࡟আ͢Δ
    ࢖ΘΕͳ͘ͳͬͨ"1*ͳͲ͕ଘࡏ͠ɺͲΕΛҠߦ͢Ε͹͍͍ͷ͔Θ͔Γʹ͍͘

    View Slide

  20. ϦϓϨΠεதʹൃੜͨ͠Πγϡʔ
    • ࣮૷ݴޠ͕ͭڞଘ͢Δظ͕ؒ௕͔ͬͨͨΊɺػೳվम΍໰୊ൃੜ࣌ͷ੾Γ෼͚ͷ೉͠͞͸͋ͬͨ
    • ݴޠ࢓༷ͷࠩҟʹΑΓҾ͖ى͜͞Εͨόά͸ҙ֎ͱগͳ͔ͬͨ
    • Կ͔͋ͬͨͱͯ͠΋։ൃ؀ڥͰ༰қʹൃݟͰ͖ΔͨΊ
    • ෛՙʹ͞Β͞ΕΔ͜ͱʹΑΓൃੜ͢Δ໰୊͸ଟ͔ͬͨ
    • ($ 4UPQ5IF8PSME

    • .FNPSZMFBL΍3BDF $POEJUJPO
    • FUD

    View Slide

  21. ࣄྫ঺հ
    • ఆظϦϦʔεͰຊ൪؀ڥʹσϓϩΠΛߦͬͨͱ͜Ζ8FCαʔόʔͷϨεϙϯελΠϜ͕૿Ճ
    • Ωϟογϡऔಘ༻ͷ3FEJTίϚϯυͷλΠϜΞ΢τྫ֎΋ಉ࣌ʹେྔൃੜ
    • 3FEJTΫϥΠΞϯτͱͯ͠-FUUVDFΛར༻
    • ಛఆͷΩϟογϡΩʔ΁ͷภΓ͸ͳ͘ɺ΄΅͢΂ͯͷΩϟογϡΩʔͰϥϯμϜʹൃੜ
    [WARN] Get key from redis failed: cache:json://...
    io.lettuce.core.RedisCommandTimeoutException: Command timed out after 200 millisecond(s)
    at io.lettuce.core.ExceptionFactory.createTimeoutException(ExceptionFactory.java:51)
    at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:119)
    at io.lettuce.core.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:75)
    at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:79)
    at com.sun.proxy.$Proxy180.get(Unknown Source)
    ...

    View Slide

  22. Ծઆͱݕূᶃ
    • <Ծઆ>Ͳ͔͜ͷॲཧͰڊେͳΦϒδΣΫτΛΩϟογϡ͓ͯ͠Γɺ3FEJTͰεϩʔίϚϯυ͕ൃੜ͍ͯ͠Δʁ
    • 3FEJT͸γϯάϧεϨουͷͨΊεϩʔίϚϯυʹΑΓϒϩοΩϯά͕ൃੜ͢Δ͜ͱ͕͋Δ
    • <ݕূ݁Ռ> ✗
    • ຊ൪؀ڥʹΩϟογϡΦϒδΣεταΠζΛग़ྗ͢Δϩά࢓ࠐΜͩΓ3FEJTͷ4-08-0(Λ֬ೝ͕ͨ͠ಛ
    ʹҟৗͳ͠
    • ·ͨɺ3FEJTͷϒϩοΩϯά͕ݪҼͷ৔߹8FCαʔόʔҎ֎Ͱ΋λΠϜΞ΢τ͕ൃੜ͢Δ͸ͣ

    View Slide

  23. Ծઆͱݕূᶄ
    • <Ծઆ>($ ͕ݪҼʁ
    • ఆظϦϦʔεޙɺ($-PDLFS *OJUJBUFE($ʹΑΔఀࢭ͕࣌ؒ૿Ճ NBYNTNT͙Β͍

    • ($ʹΑΔεϨουఀࢭʹΑΓλΠϜΞ΢τ͕͓͖͍ͯΔͷͰ͸ʁ
    • ΩϟογϡΦϒδΣΫτͷѹॖॲཧͰKBWBVUJM[JQ*OGMBUFSJOGMBUF CZUF<>
    %FGMBUFSEFGMBUF CZUF<>

    Λසൟʹ࢖͍ͬͯΔͷͰɺ($-PDLFS*OJUJBUFE($͕ൃੜ͍ͯ͠Δ

    View Slide

  24. Ծઆͱݕূᶄ
    ͜ͷؒ($͕อཹ͞ΕΔ
    ※https://github.com/AdoptOpenJDK/openjdk-
    jdk11u/blob/fa3ecefdd6eb14a910ae75b7c0aefb1cf8eedcce/src/java.base/share/native/libzip/Inflater.c#L219-L242

    View Slide

  25. Ծઆͱݕূᶄ
    • +%,Ҏ߱JOGMBUFEFGMBUFϝιουʹ#ZUF#VGGFS͕౉ͤΔΑ͏ʹͳ͓ͬͯΓɺJOQVUͱPVUQVUͷόο
    ϑΝ͕྆ํͱ΋%JSFDU#VGGFSͰ͋Ε͹($อཹ͕ൃੜ͠ͳ͍
    ※https://github.com/AdoptOpenJDK/openjdk-
    jdk11u/blob/fa3ecefdd6eb14a910ae75b7c0aefb1cf8eedcce/src/java.base/share/native/libzip/Inflater.c#L268-L281

    View Slide

  26. Ծઆͱݕূᶄ
    • <ݕূ݁Ռ> ✗
    • ಛʹ࣮ߦස౓ͷଟ͍JOGMBUFΛ%JSFDU#VGGFSར༻ʹมߋͯ͠σϓϩΠͯ͠Έ͕ͨɺϨεϙϯε஗Ԇ΍
    λΠϜΞ΢τ໰୊͸վળͤͣ
    • ($-PDLFS *OJUJBUFE($΋ଟগݮ͔ͬͨͳʜʁͱ͍͏ײ͡
    • ͨͩ͠෭࢈෺ͱͯ͠ѹॖ͞ΕͨΩϟογϡΦϒδΣΫτల։࣌ͷύϑΥʔϚϯε͸ྑ͘ͳͬͨ
    Benchmark Mode Cnt Score Error Units
    DeflateCompressingCodecBenchmark.benchmarkDecodeValue thrpt 5 1365.530 ± 286.953 ops/ms
    Benchmark Mode Cnt Score Error Units
    DeflateCompressingCodecBenchmark.benchmarkDecodeValue thrpt 5 4108.440 ± 304.715 ops/ms

    View Slide

  27. Ծઆͱݕূᶅ
    • <Ծઆ>-FUUVDFͷΠϕϯτϧʔϓεϨουͰͷϒϩοΩϯάૢ࡞͕ݪҼʁ
    • -FUUVDF 3FGFSFODF (VJEFʹ͸ҎԼͷهࡌ͕͋Δ
    • As a rule of thumb, never block the event loop. If you need to chain futures using blocking calls, use the
    thenAcceptAsync()/thenRunAsync() methods to fork the processing to another thread. ˞
    • ϦϦʔε͞ΕͨίʔυΛͬ͘͡ΓಡΜͰΈͨΒ͔֬ʹLettuceͷεϨου্ͰJDBCͰΫΤϦΛ࣮ߦ
    ͍ͯ͠Δ…
    ※出典: https://lettuce.io/core/release/reference/#asynchronous-api.consuming-futures

    View Slide

  28. Ծઆͱݕূᶅ
    lettuceAsyncCommand.get(key)
    .thenApply(value -> {
    final var entity = hogeService.get(value.field);
    ...
    })
    ͜ͷ'VODUJPO͸-FUUVDFͷΠϕϯτϧʔϓεϨου্Ͱ࣮ߦ͞ΕΔ
    վળલ
    ※説明用のコードで実際に稼働中のものではありません

    View Slide

  29. Ծઆͱݕূᶅ
    lettuceAsyncCommand.get(key)
    .thenApply(value -> {
    final var entity = hogeService.get(value.field);
    ...
    })
    ͜ͷϝιουͷ಺෦Ͱ͸+%#$ʹΑΓ
    ΫΤϦΛ࣮ߦ ϒϩοΩϯάૢ࡞
    ͢Δ
    վળલ
    ※説明用のコードで実際に稼働中のものではありません

    View Slide

  30. Ծઆͱݕূᶅ
    lettuceAsyncCommand.get(key)
    .thenApplyAsync(value -> {
    final var entity = hogeService.get(value.field);
    ...
    }, executer)
    UIFO"QQMZ"TZOD
    Λ࢖ͬͯϒϩοΩϯάૢ࡞ΛผεϨουͰ࣮ߦ
    վળޙ
    ※説明用のコードで実際に稼働中のものではありません

    View Slide

  31. Ծઆͱݕূᶅ
    • <ݕূ݁Ռ> ˓
    • ݟࣄʹ3FEJTίϚϯυͷλΠϜΞ΢τ͕ফࣦʂ
    • αʔόʔͷϨεϙϯελΠϜ΋ਖ਼ৗʹ໭ͬͨʂ

    View Slide

  32. ࠶ൃ๷ࢭରԠ
    #MPDL)PVOE˞ಋೖ
    • ΠϕϯτϧʔϓεϨου಺ͰͷϒϩοΩϯάૢ࡞Λݕ஌ͯ͘͠ΕΔ+7.ΤʔδΣϯτ
    • -FUUVDFͷΠϕϯτϧʔϓεϨου಺ͰϒϩοΩϯάૢ࡞͕ߦΘΕͨͱ͖ʹϩάΛग़ྗ͢ΔΑ͏ʹ͠
    ͨ
    ։ൃ؀ڥͰͷఆظతͳෛՙςετ
    • ػೳΛϦϦʔε͢Δ·Ͱؾ͚ͮͳ͔ͬͨͱ͍͏൓লΛ౿·͑ͯɺ։ൃ؀ڥͰఆظతʹෛՙςετΛ
    ߦ͍ύϑΥʔϚϯε௿ԼΛݕ஌Ͱ͖ΔΑ͏ʹͨ͠
    ※BlockHound: https://github.com/reactor/BlockHound

    View Slide

  33. ࠶ൃ๷ࢭରԠ
    ※説明用のコードで実際に稼働中のものではありません
    #MPDL)PVOEಋೖ
    public class Application {
    public static void main(String[] args) {
    BlockHound.builder()
    .with(new LettuceBlockHoundIntegration())
    .blockingMethodCallback(method ->
    log.warn(”Blocking call detected”, new Throwable(method.toString())))
    .install();
    }
    }

    View Slide

  34. ࠶ൃ๷ࢭରԠ
    ※説明用のコードで実際に稼働中のものではありません
    #MPDL)PVOE˞ಋೖ
    public class Application {
    public static void main(String[] args) {
    BlockHound.builder()
    .with(new LettuceBlockHoundIntegration())
    .blockingMethodCallback(method ->
    log.warn(”Blocking call detected”, new Throwable(method.toString())))
    .install();
    }
    }
    ͜ͷΫϥεͷதͰ؂ࢹ͢ΔεϨου໊ͳͲͷ৚݅Λࢦఆ

    View Slide

  35. ࠶ൃ๷ࢭରԠ
    ※説明用のコードで実際に稼働中のものではありません
    #MPDL)PVOE˞ಋೖ
    public class Application {
    public static void main(String[] args) {
    BlockHound.builder()
    .with(new LettuceBlockHoundIntegration())
    .blockingMethodCallback(method ->
    log.warn(”Blocking call detected”, new Throwable(method.toString())))
    .install();
    }
    }
    ϒϩοΩϯάૢ࡞Λݕ஌ͨ͠ͱ͖ͷಈ࡞Λఆٛ

    View Slide

  36. ࠶ൃ๷ࢭରԠ
    ։ൃ؀ڥͰͷఆظతͳෛՙςετ
    • ࣾ಺ͷෛՙςετج൫ (SBGBOBLϕʔε
    Λར༻͠ςετ࣮ߦ
    • %BJMZͰ։ൃ؀ڥʹ޲͚ͯςετΛ࣮ߦ
    • γφϦΦͷϝϯςφϯείετ࡟ݮͷͨΊɺγφϦΦੜ੒ΛQVQQFUFFSΛ༻͍ͯࣗಈԽ

    View Slide

  37. -*/& /&84ͷ͜Ε͔Β

    View Slide

  38. +BWBϦϓϨΠεޙͷ࣍ͳΔ՝୊
    1FSM"QQαʔόʔͷTVOTFU
    ϨΨγʔͳ"QBDIFIUUQEͷϦϓϨΠε
    +7.ϥΠϒϥϦͷܧଓతͳΞοϓσʔτ
    ͜ΕΒ໰୊ղܾͷͨΊʹ,VCFSOFUFTҠߦΛਐߦத

    View Slide

  39. ,VCFSOFUFTҠߦ
    -PBE #BMBODFS
    3FWFSTF1SPYZ 8FC"QQ 1FSM

    8FC"QQ +BWB

    View Slide

  40. ,VCFSOFUFTҠߦ
    -PBE #BMBODFS
    8FC"QQ +BWB

    *OHSFTT
    3PMMPVUT

    View Slide

  41. ·ͱΊ
    • ࣮૷ݴޠͷϦϓϨΠεʹ͍ͭͯ
    • 1FSMͱ+BWB͕ڞଘͰ͖ΔΑ͏ʹͯ͠ɺαʔϏε։ൃΛࢭΊͣʹϦϓϨΠεΛߦͬͨ
    • ϦϓϨΠε͢Δ͜ͱʹ஫ྗ͠"1*TQFDͷมߋ͕ඞཁͳվળ͸ϦϓϨΠεޙʹରԠ͢Δ
    • ྆ํͷݴޠΛॻ͚Δਓ͕࣮૷͢Δ΋͘͠͸طଘͷ࣮૷ΛಡΊΔਓʹυΩϡϝϯτʹམͯ͠΋Βͬͯ
    ͔ΒϦϓϨΠε͢Δ
    • ະ࢖༻࣮૷΍ϦϓϨΠεࡁΈ࣮૷͸࡟আ͢Δ͜ͱͰҠߦ࿙Ε๷ࢭ
    • ϦϓϨΠεதʹൃੜͨ͠Πγϡʔ
    • ΠϕϯτϧʔϓεϨουͷϒϩοΩϯάૢ࡞͸#MPDL)PVOEͰݕ஌Ͱ͖Δ
    • ύϑΥʔϚϯε௿ԼΛ։ൃ؀ڥͰݕ஌͢ΔͨΊʹఆظతͳෛՙςετ΋ॏཁ
    • +BWBϦϓϨΠεޙͷ՝୊ղܾͷͨΊʹ,VCFSOFUFTҠߦΛਐߦத

    View Slide

  42. 8&`3&)*3*/(
    • -*/&Ͱ͸ΤϯδχΞΛืूதͰ͢ʂ
    • -*/& /&84ͷΑ͏ͳେن໛8FCαʔϏεͷ։ൃΛ͍ͨ͠ํ
    • IUUQTMJOFDPSQDPNKBDBSFFSQPTJUJPO
    • ͦͷଞʹ΋༷ʑͳϙδγϣϯ͕͋ΔͷͰ͝ڵຯ͕͋Δํ͸ੋඇʂ

    View Slide

  43. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide