Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
【Go活用事例】 安全運転支援サービスを支える 運用管理システム
Search
Hirotaka Suzuki
November 01, 2019
Technology
3
1.5k
【Go活用事例】 安全運転支援サービスを支える 運用管理システム
2019/11/1 の、DeNA.go #3 の発表資料です。
Hirotaka Suzuki
November 01, 2019
Tweet
Share
More Decks by Hirotaka Suzuki
See All by Hirotaka Suzuki
サーバーエンジニアがFlutterに挑戦している話
suhirotaka
0
110
Other Decks in Technology
See All in Technology
現地速報!Microsoft Ignite 2025 M365 Copilotアップデートレポート
kasada
2
1.6k
『星の世界の地図の話: Google Sky MapをAI Agentでよみがえらせる』 - Google Developers DevFest Tokyo 2025
taniiicom
0
170
ローカルVLM OCRモデル + Gemini 3.0 Proで日本語性能を試す
gotalab555
1
120
はじめての OSS コントリビューション 〜小さな PR が世界を変える〜
chiroito
4
350
膨大なデータをどうさばく? Java × MQで作るPub/Subアーキテクチャ
zenta
0
120
ECS組み込みのBlue/Greenデプロイを動かしてELB側の動きを観察してみる
yuki_ink
3
410
Axon Frameworkのイベントストアを独自拡張した話
zozotech
PRO
0
230
個人から巡るAI疲れと組織としてできること - AI疲れをふっとばせ。エンジニアのAI疲れ治療法 ショートセッション -
kikuchikakeru
4
1.8k
IaC を使いたくないけどポリシー管理をどうにかしたい
kazzpapa3
1
130
PostgreSQL で列データ”ファイル”を利用する ~Arrow/Parquet を統合したデータベースの作成~
kaigai
0
160
新しい風。SolidFlutterで実現するシンプルな状態管理
zozotech
PRO
0
130
AI エージェント活用のベストプラクティスと今後の課題
asei
1
120
Featured
See All Featured
BBQ
matthewcrist
89
9.9k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Designing for Performance
lara
610
69k
Embracing the Ebb and Flow
colly
88
4.9k
Bash Introduction
62gerente
615
210k
Six Lessons from altMBA
skipperchong
29
4.1k
Mobile First: as difficult as doing things right
swwweet
225
10k
Optimizing for Happiness
mojombo
379
70k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Rails Girls Zürich Keynote
gr2m
95
14k
The Cult of Friendly URLs
andyhume
79
6.7k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
680
Transcript
ʲ(P׆༻ࣄྫʳ ҆શӡసࢧԉαʔϏεΛࢧ͑Δ ӡ༻ཧγεςϜ ླ༟ਸ!TVIJSPUBLB ΦʔτϞʔςΟϒࣄۀຊ෦εϚʔτυϥΠϏϯά෦γεςϜ։ൃάϧʔϓ גࣜձࣾσΟʔɾΤψɾΤʔ The Go
gopher was designed by Renee French.
ࣗݾհ ླ༟ਸ!TVIJSPUBLB ϑϦʔϥϯεɾϔϧεςοΫܥελʔτΞοϓΛܦͯɺ %F/"ೖࣾɻ ަ௨ࣄނݮαʔϏε%3*7&$)"35ͷαʔόʔΞϓϦ έʔγϣϯ։ൃΛ͍ͬͯ·͢ɻ 8FCͷਐԽͱͱʹಈըαΠτ͔ΒϞϏϦςΟαʔϏε ·ͰؔΘ͖ͬͯͯɺͬͱͬͱ8FC͕׆༂͢Δࣾձʹ
͍͖͍ͯͨ͠ɻ
ຊͷΞδΣϯμ (PΛͬͨ։ൃͷݱͷงғؾΛ͓͍͑ͨ͠ʂ • (PΛͬͯͳʹΛͭͬͨ͘ͷʁ • ͳΜͰ(PΛ࠾༻ͨ͠ͷʁ • ͲΜͳϥΠϒϥϦΛͬͯΔͷʁ • ۩ମతͳ࣮ʹ͍ͭͯ
• 3BJMTͱͷซ༻ͷίπ • ։ൃͰۤ࿑ͨͯ͠͠Δ͜ͱʁ
(PͰͳʹΛ͍ͭͬͯ͘Δ͔
%3*7&$)"35ͱʁ
%3*7&$)"35ͱ 4 A2 DRIVE CHART
%3*7&$)"35ͷ࣮ূޮՌ 5 A3 DRIVE CHART
ं֎ΧϝϥͷΑ͏͢ 㾎ंؒڑෆ 㾎Ұ࣌ෆఀࢭ 㾎ա
ंΧϝϥͷΑ͏͢ 㾎ݟ 㾎ډΓ
ʑͷӡసϨϙʔτ 9 A7 ӡసͷΫηΛݟ͑ΔԽ͠ɺةݥͳಈը͚ͩϐοΫΞοϓɻ
%3*7&$)"35ͷӡ༻ཧ͕Ͱ͖Δ 8&#γεςϜΛͭ͘Γ·ͨ͠
ͨͱ͑ɺ͜Μͳ͜ͱ͕Ͱ͖·͢ ✓ ֤ςʔϒϧʢҎ্ʣͷ$36%ૢ࡞ΠϯϙʔτɾΤΫεϙʔτ ✓ ंࡌثͷ෦Λൃͯ͠ɺൃॻͷ1%'Λμϯϩʔυ͢Δ ✓ ෦͕ೲ͞Εͨͱ͖෦͕༻͞Εͨͱ͖ʹɺࡏݿΛਖ਼͘͠อͭ ✓ ͰͷंࡌثͷΈཱ͔ͯΒൃૹ·ͰΛτϥοΩϯά͢Δ ✓
Ͳͷंࡌث͕Ͳͷं྆ʹऔΓ͚ΒΕ͍ͯΔ͔ཧ͢Δ ✓ ंࡌثʹ৴͢ΔΞϓϦέʔγϣϯΛΞοϓϩʔυ͢Δ ✓ "*ʹΑΔϢʔβʔͷإೝূͷਖ਼֬ੑΛνΣοΫ͢Δ ✓ Ϣʔβʔ͔ΒͷϑΟʔυόοΫΛ֬ೝͯ͠ɺϝʔϧฦ৴͢Δ ✓ ϢʔβʔͷݖݶΛΘ͔Γ͍͢(6*Ͱ֬ೝɾมߋ͢Δ ✓ ंࡌثͷՔಇঢ়گΛϦΞϧλΠϜͰूܭ͢Δ ɾɾɾɾɾɾ
ը໘հ
ं྆Ұཡը໘
ं྆Ұཡը໘ʢ֦େʣ $47Πϯϙʔτ $47ΤΫεϙʔτ ϑΟϧλʢΠϯΫϦϝϯλϧαʔνʣ ϑΟϧλʢϓϧμϯʣ ৄࡉදࣔϘλϯ আϘλϯ ҹϘλϯ
෦ൃը໘
ंࡌثऔΓ͚ը໘
ंࡌثΞϓϦέʔγϣϯ৴ը໘
Ϣʔβʔཧը໘
(PΛ࠾༻͢Δ·ͰͷಓͷΓ
ΞʔΩςΫνϟ
ΞʔΩςΫνϟʢ֦େʣ (P 3BJMT ֤ίϯϙʔωϯτ ϚΠΫϩαʔϏεԽ
(PͰॻ͔Ε͍ͯΔͷ • ӡ༻ཧγεςϜͷ"1*ɾϏϡʔ 3BJMTͰॻ͔Ε͍ͯΔͷ • ंࡌثͱͷ௨৴"1* • ंࡌث͔ΒͷϑΝΠϧΞοϓϩʔυ"1* • 8&#ΫϥΠΞϯτͱͷ௨৴"1*
• ఆظόονσʔϞϯ 3BJMT͕ଟ͍ ΞʔΩςΫνϟʢݴޠผʣ
%3*7&$)"35ࣄۀԽ·ͰͷಓͷΓ ࣮ূ࣮ݧʢ̎ʣ ύʔτφʔ༷ͱ࣮ݧతʹαʔϏεΛӡ༻ͯ͠ɺຊʹަ௨ࣄނݮޮՌ͕͋Δͷ͔Λݕূ ‑ ࣄۀԽ0,͔ͷஅ ͠/(Ͱ͋Εɺ࣮ূ࣮ݧதͷιʔείʔυ͓ଂೖΓʹɾɾɾ ‑ ຊαʔϏε։࢝ ظؒͷαʔϏεΛܧଓΛલఏʹɺεέʔϥϏϦςΟΛߟྀͨ͠γεςϜߏங͕ඞཁ
(PPS3BJMT ˒࣮ূ࣮ݧ࣌ɺεϐʔυॏࢹͰ3BJMT 8FC։ൃʹඞཁͳϥΠϒϥϦ͕ͦΖ͍ͬͯͯɺͳΜͱ͍ͬͯ։ൃ͕͍ w ࣮ূ࣮ݧதසൟʹ༷มߋ͕ൃੜ͠ɺεϐʔυউෛ ˒ຊαʔϏεɺύϑΥʔϚϯεॏࢹͰ(P ࣮ߦͷ͞ • ͕̎ഒʹͳΕαʔόʔ͕ͰࡁΉʢίετϝϦοτʣ ੩తܕ͚
• ظؒͷӡ༻Λߟ͑Δͱɺܕ͕͋Δ͜ͱͰେنͳϦϑΝΫλϦϯάָ͕ʹͳΔ ʢӡ༻ϝϦοτʣ
(PͰॻ͔Ε͍ͯΔͷ • ӡ༻ཧγεςϜͷ"1*ɾϏϡʔ 3BJMTͰॻ͔Ε͍ͯΔͷ • ंࡌثͱͷ௨৴"1* • ंࡌث͔ΒͷϑΝΠϧΞοϓϩʔυ"1* • 8&#ΫϥΠΞϯτͱͷ௨৴"1*
• ఆظόονσʔϞϯ 3BJMT͕ଟ͍ ΞʔΩςΫνϟʢݴޠผʣ ࣮ূ࣮ݧதʹ ͳ͔ͬͨαʔϏε ࣮ূ࣮ݧத͔Β ͋ͬͨαʔϏε
ӡ༻ཧγεςϜ͔Β(PΛ࠾༻͠ɺ ͦͷଞͷαʔϏε ॱ࣍(PʹϦϓϨΠε༧ఆ
(PΛ͞Θͬͯ࠷ॳʹײͨ͜͡ͱ • ίϯύΠϧ͕௨Εɺ͍͍ͩͨҙਤ௨Γʹਖ਼͘͠ಈ͍͍ͯΔɻݴޠઃ ܭ͕लҳͳͷͩͱࢥ͏ • ܕ·ΘΓ͕ॊೈͳͷͰɺಈతܕ͚ͷݴޠ͔ΒͰۤ࿑͠ͳ͍ • "5PVSPG(PΛҰ௨Γऴ͑Εɺ044ͷιʔείʔυಡΊΔ • ιʔε͕͍ɾɾɾ
• จࣈྻૢ࡞େมɾɾɾ
͍ͬͯΔϥΠϒϥϦ
8"'ʢϑϨʔϜϫʔΫʣ ˒(PͷϑϨʔϜϫʔΫΛίϯηϓτ͔Βେࡶʹ̎ͭʹେผ͢Δͱɾɾ ϑϧελοΫɾ.7$WTϛχϚϧɾߴ ˒ͳͥͳΒɾɾ w యܕతͳ8FCγεςϜͷͨΊɺϑϧελοΫϑϨʔϜϫʔΫͷԸܙʹ͔͋ͣΓ͍ͨ w ӡ༻ཧγεςϜ͕ߴʹಈ࡞͢Δඞཁੑ͏͍͢
ݕ౼ͨ͠ϑϨʔϜϫʔΫ #FFHP ˕ 3FWFM ͻͱͱ͓ΓͷػೳͦΖ͍ͬͯΔ͕ɺఀؾຯ *SJT ϓϩδΣΫτͷӡӦ໘ͰΛ๊͍͑ͯΔΑ͏ ࠓճͬͪ͜ʂ
#FFHPʹ͍ͭͯ • ϑϧελοΫͷ.7$ϑϨʔϜϫʔΫ • தࠃͰਓؾ͕͋ΓɺΤϯλʔϓϥΠζͰͷ࣮๛ʢςϯηϯτɾϑΝʔΣΠɾɾɾʣ • 8FC։ൃ͚ͷػೳҰ௨ΓͦΖ͍ͬͯΔ •
֤ػೳϞδϡʔϧԽ͞Ε͓ͯΓɺ͖ͳϥΠϒϥϦʹೖΕସ͑ΒΕΔ • ηογϣϯɾΩϟογϡɾϩΨʔɾJOɺɺɺ03.·Ͱ͍͍ͭͯΔ • ϑϧελοΫϑϨʔϜϫʔΫͷΘΓʹɺϕϯνϚʔΫ͍ͦͦ͜͜ • 3BJMTಉ༷ʹɺCFFͱ͍͏$-*πʔϧ͕͋Δ • ίʔυࣗಈੜʢTDBGGPMEJOHʣͰ͖Δ
ϥΠϒϥϦհ 03. (03. কདྷͷ3BJMT͔ΒͷϦϓϨΠεͷͨΊɺ"DUJWF3FDPSEʹ ࣅͨػೳ͕΄͍͠ ϩΨʔ MPHSVT #FFHPͷMPHTϞδϡʔϧ༻ҙ͞Ε͍ͯΔ͕ɺMPHSVTΛ
༻͍ͯ͠Δ ڥઃఆ $POpHPS ڥ͝ͱʹઃఆϑΝΠϧΛ࡞Ͱ͖Δ ύοέʔδཧ HMJEFˠ (P.PEVMFT HMJEFΛ͍͕ͬͯͨɺ(P.PEVMFTͷಋೖޙʹҠߦ ߦऔಘ XIFSFBNJ ࣮ߦதͷιʔείʔυͷߦΛऔಘͰ͖ΔɻΤϥʔ௨ ࣌ʹ༻
ϥΠϒϥϦհ ߏମͷൺֱ HPDNQ ߏମͳͲͷҰகΛྑ͍ײ͡ʹൺֱͯ͘͠ΕΔ *%ੜ YJE ϢχʔΫ*%Λੜ͢ΔɻΞηοτͷμΠδΣετ༩ ͳͲͰ༻
1%'ੜ HPQEG ຊޠ͖Ε͍ʹ1%'ग़ྗͯ͘͠ΕΔɺ͋Γ͕͍ͨϥ ΠϒϥϦ ը૾ੜ HH ͖ͳϑΥϯτΛϩʔυͯ͠ςΩετΛը૾ԽͰ͖Δ όʔίʔυੜ #BSDPEF 23ίʔυͷ࡞ʹ༻
࣮ʹ͍ͭͯ
#FFHPΛͬͯ ࣮͍͖ͯ͠·͢
࣮ʢ$POUSPMMFSʣ ˒ϕʔεͷίϯτϩʔϥߏମΛఆٛ͢Δ • ϨεϙϯεͷϑΥʔϚοτʢ)5.-+40/ʣͰɺߏମΛ͚Δ // controllers/html/base.go type HTMLController
struct { beego.Controller accesslog *logger.AccessLog } // controllers/api/base.go type APIController struct { beego.Controller accesslog *logger.AccessLog }
࣮ʢ$POUSPMMFSʣ ˒ϧʔςΟϯάΛఆٛ͢Δ // routers.go // ϩάΠϯ༻ΤϯυϙΠϯτ beego.Router("/login", &opshtml.HTMLController{},
"get:LoginIndex") beego.Router("/api/login", &opsapi.APIController{}, "post:LoginIndex")
࣮ʢ$POUSPMMFSʣ ˒ίϯτϩʔϥڞ௨ॲཧΛ࣮͢Δ • 1SFQBSF Ͱίϯτϩʔϥͷલॲཧɺ'JOJTI Ͱίϯτϩʔϥͷޙॲཧ͕ॻ͚Δʢ3BJMT ͷCFGPSF@BDUJPOɾBGUFS@BDUJPOͷΑ͏ͳͷʣ //
controllers/api/base.go func (c *APIController) Prepare() { // ΫοΩʔೝূݖݶνΣοΫͳͲ } func (c *APIController) Finish() { // ϩάͷॻ͖ग़͠ͳͲ }
࣮ʢ$POUSPMMFSʣ ˒ίϯτϩʔϥݸผॲཧΛ࣮͢Δ // controllers/api/login.go func (c *APIController) LoginIndex()
{ // ϩάΠϯॲཧΛͯ͠ɺJSONΛฦ͢ c.ServeJSON() } // controllers/html/login.go func (c *HTMLController) LoginIndex() { // ϩάΠϯϖʔδͷϏϡʔΛฦ͢ c.TplName = "ops/login/index.tpl" }
࣮ʢ.PEFMʣ ˒%#εΩʔϚʹରԠ͢ΔߏମΛఆٛ͢Δ // models/car_schema.go type Car struct {
ID int `gorm:"column:id;primary_key" json:"id" csv:"id" chart:"display:ID;sortable:true;filterable:true;type:number;formable:f alse;listable:true"` Name *string `gorm:"column:name" json:"name" csv:"name" chart:"display:ं྆ ໊;sortable:true;filterable:true;type:text;formable:true;listable:true "` // ...... }
࣮ʢ.PEFMʣ ˒Ϩίʔυͷݕࡧ݁ՌΛ֨ೲ͢ΔߏମΛఆٛ͢Δ // models/car_schema.go type Cars struct {
Cars []Car `json:"data"` CountTotal int `json:"recordsTotal"` // ...... }
࣮ʢ.PEFMʣ ˒ϞσϧϩδοΫΛ࣮͢Δ • ϝιου໊ɺ"DUJWF3FDPSEͷϝιου໊Λҙࣝ͢Δ • (03.ͷϑοΫʢ#FGPSF$SFBUFɾ"GUFS$SFBUFʣ͕͑Δ // models/car.go
func (car *Car) FindBy() error { // ̍݅औಘ } func (cars *Cars) Where() error { // ෳ݅औಘ } func (car *Car) Update() error { // ̍݅ߋ৽ } func (cars *Cars) UpdateAll() error { // ෳ݅ߋ৽ }
࣮ʢ7JFXʣ ˒ϏϡʔςϯϓϨʔτΛ࣮͢Δ • HPͷςϯϓϨʔτύοέʔδΛ͏ • +40/ϏϡʔΛΘͣʹɺϞσϧͷߏମͰϨεϙϯεΛఆٛ͢Δ {{/* views/login/index.tpl
*/}} <div> <img src="{{ .baseURL }}/logo.png" width="100" height="100"> </div>
// main.go beego.Run()
্࣮ͷ
εΩʔϚߏମ ˒ςʔϒϧ͝ͱʹɺ%#ͷεΩʔϚఆٛΛөͨ͠εΩʔϚߏମΛͭ͘Δ ˒ܕͱWBMJEBUFλάͰεΩʔϚΛදݱ͢Δ w (03.ͷ্༷ɺ/6--ڐՄͷΧϥϜϙΠϯλܕʹ͢Δඞཁ͕͋Δ type TableExample struct
{ // int unsigned (NOT NULL) DeviceID int `validate:"min=0"` // int unsigned (NOT NULL DEFAULT 0) UserCertBy *int `validate:"min=0"` // int unsigned UserID *int // varchar (NOT NULL) Result string `validate:"required"` // varchar Name *string }
εΩʔϚߏମ ˒ΫϥΠΞϯταΠυͰͷڍಈΛߏମͷλάʹఆٛ͢Δ • +BWB4DSJQUʹλάͷ༰Λ+40/Ͱฦ٫͢Δ • ʢྫʣ͋ΔΧϥϜʹରͯ͠ɺιʔτػೳΛ༗ޮʹ͢Δ͔Ͳ͏͔ • ʢྫʣ͋ΔΧϥϜΛɺ$47ͷग़ྗରʹ͢Δ͔Ͳ͏͔
type TableExample struct { Name *string `gorm:"column:name" json:"name" csv:"name" chart:”display:Name;sortable:true;filterable:true;type:text;formab le:true;listable:true"` UpdatedByUserName string `gorm:"-" json:"updated_by_user_name" csv:"-" chart:"display:ߋ৽ ऀ;sortable:false;filterable:false;type:text;formable:false"` }
࣮ͷڞ௨Խ ˒ଟͷςʔϒϧʹରͯ͠ɺڞ௨ͷػೳΛ࣮͍ͨ͠ • ʢྫʣDBSTʹର͢Δ$SFBUFͷϩδοΫͱɺVTFSTʹର͢Δ$SFBUFͷϩδοΫಉ͡ ˒͔͕͠͠ɾɾ • ςʔϒϧ͕ଟ͍ͷͰɺಉ͡ϩδοΫ࣮Λڞ௨Խ͍ͨ͠ • (PʹδΣωϦΫε͕ͳ͍ʢ˞࣮࣌࣌ʣͷͰɺڞ௨ϝιουΛͭ͘Δ͜ͱ͍͠ •
·ͨڞ௨ϝιουʹͯ͠͠·͏ͱɺ༷ͷॊೈੑ͕ࣦΘΕΔ ‑ ϞσϧɾίϯτϩʔϥɾϏϡʔͷܗΛࣗಈੜͰ͖ΔΑ͏ʹ͢ΔʢಠࣗͷTDBGGPMEJOHػೳʣ
ͱ͍͑ɺଞͷαʔϏε 3BJMTͰಈ͍͍ͯΔɾɾ
3BJMTαʔϏεͱͷซଘ ˒%#·ΘΓͷఆٛͷڞ௨Խ • (PͷαʔϏεͱ3BJMTͷαʔϏε͕ಉ͡%#Λࢀর͍ͯ͠Δ߹ɺ%#·ΘΓͷఆٛͷ ߋ৽͕ࠩόάͷԹচʹͳΔ • Ͱ͖Δ͚ͩೋॏཧΛආ͚ΔΑ͏ʹ͢Δ ڞ௨ԽͷҰྫ
%#εΩʔϚఆٛ 3VCZ SJEHFQPMF ͰҰݩཧ εΩʔϚߏମ %#εΩʔϚ͔ΒεΩʔϚߏମΛࣗಈੜɻ·ͨɺ%#εΩʔ Ϛͱͷ͕ࠩൃੜ͍ͯ͠ͳ͍͔ΛνΣοΫ͢ΔπʔϧΛ༻ҙ FOVNఆٛ ZBNMʹFOVNͷఆٛΛॻ͖ग़͠ɺ྆γεςϜ͔ΒಡΈࠐΉ
3BJMTαʔϏεͱͷซଘ ˒҉߸Խ·ΘΓͷڞ௨Խ • ҰํͷαʔϏεͰ҉߸Խͨ͠Λ͏ҰํͷαʔϏεͰࢀর͍ͨ͠߹ɺ҉߸Խํࣜ 伴Λ߹ΘͤΔඞཁ͕͋Δ • ʢྫʣγϯάϧαΠϯΦϯ • ෳͷαʔϏεͰɺಉ͡Ϣʔβʔ໊ɾύεϫʔυͰϩάΠϯ͍ͨ͠ •
3VCZͷ%FWJTFɺϢʔβʔύεϫʔυͷ҉߸Խʹ#$SZQUΛ༻͢Δ • (PଆͰ#$SZQU·ΘΓͷॲཧΛ࣮͢Δඞཁ͕͋Δ • 伴ͷཧ͕໘ʹͳΔ • 伴ͷߋ৽λΠϛϯάΛͦΖ͑ΔͳͲͷ • ΫϥυαʔϏεΛ͏ͱָʢ"844FDSFUT.BOBHFSͳͲʣ
3BJMTαʔϏεͱͷซଘ ˒ϢʔςΟϦςΟػೳͷڞ௨Խ • ൚༻తͳϢʔςΟϦςΟΛͲͪΒଆͷαʔϏεʹ࣮͢Δ͔ʁ • ϝʔϧૹ৴ɾ௨γεςϜɾ֎෦"1*࿈ܞɾɾɾ • ͲͪΒ͔ҰํʹدͤΔʁ • αʔϏεؒͷ௨৴͕ൃੜ͢Δʢ3&45"1*PSH31$ʁʣ
• υΩϡϝϯτඋͷඞཁੑ্͕͕Δ • ྆αʔϏεͰ࣮͢Δʁ • ࣮ίετ͕ΒΉ • ߋ৽͕ࠩόάͷԹচʹͳΔ
͜Ε͔Β(PΛ ͕Μ͕Μ͍͖ͬͯ·͢