Skip to content

Latest commit

ย 

History

History
145 lines (113 loc) ยท 8.43 KB

File metadata and controls

145 lines (113 loc) ยท 8.43 KB

logo

ํ†ตํ•ฉ ์†Œ์…œ ํ”ผ๋“œ ์„œ๋น„์Šค


Table of Contents


์†Œ๊ฐœ

์—ฌ๋Ÿฌ ์†Œ์…œ ๋ฏธ๋””์–ด ์„œ๋น„์Šค์— ์˜ฌ๋ผ์˜จ ๊ฒŒ์‹œ๋ฌผ์„ ํ•ด์‹œํƒœ๊ทธ ๊ธฐ๋ฐ˜์œผ๋กœ ์ทจํ•ฉํ•˜์—ฌ ํ†ตํ•ฉ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ฐ˜ ๊ธฐ์ˆ 

Static Badge Static Badge Static Badge

  • ์–ธ์–ด
    • Java 17
  • ์›น ํ”„๋ ˆ์ž„์›Œํฌ
    • SpringBoot 2.7.17
  • DB ์ ‘๊ทผ ๊ธฐ์ˆ 
    • Spring Data JPA
    • Spring JDBC (Bulk Insert์‹œ ์ฟผ๋ฆฌ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ์‚ฌ์šฉ)
    • QueryDSL
  • DBMS
    • H2 (SpringBoot embedded)
    • (JPA์™€ ANSIํ‘œ์ค€ SQL๋ฌธ ์‚ฌ์šฉ์œผ๋กœ, ๋Œ€๋ถ€๋ถ„์˜ RDBMS์™€ ํ˜ธํ™˜๋  ๊ฒƒ์œผ๋กœ ์ƒ๊ฐ๋จ.)

API Reference

์ž‘์„ฑ์˜ˆ์ •

ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ๋ฐ ์ด์Šˆ ๊ด€๋ฆฌ

Notion GithubProject

๊ตฌํ˜„๊ณผ์ •(์„ค๊ณ„ ๋ฐ ์˜๋„)

๋ฌดํ•œ ์Šคํฌ๋กค์„ ๊ณ ๋ คํ•œ ์œ ์ € ๋งž์ถค ์ปจํ…์ธ  ์กฐํšŒ - click
  • ์„œ๋น„์Šค ํŠน์„ฑ
    • ์†Œ์…œ๋ฏธ๋””์–ด์˜ ํŠน์„ฑ์ƒ ๊ฒŒ์‹œ๋ฌผ์ด ์ž์ฃผ ์—…๋ฐ์ดํŠธ๋จ.
    • ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฌดํ•œ์Šคํฌ๋กค ๋ฐฉ์‹์˜ UX๋ฅผ ์ฑ„ํƒํ•  ๊ฒƒ์ž„.
    • ๋ชจ๋“  SNS ๊ฒŒ์‹œ๋ฌผ์„ ์ „๋ถ€ ํฌ๋กค๋งํ•˜์—ฌ ์ €์žฅ ๊ฒƒ์€ ๊ฒƒ์€ ์‚ฌ์‹ค์ƒ ๋ถˆ๊ฐ€๋Šฅํ•จ.
      • ๋ณธ ์„œ๋น„์Šค์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ํ•ด์‹œํƒœ๊ทธ๊ฐ€ ํฌํ•จ๋œ ๊ฒŒ์‹œ๋ฌผ์— ํ•œํ•ด์„œ ์ €์žฅํ•˜๊ฒŒ ๋จ.
      • ๋•Œ๋ฌธ์—, ๋ณธ ์„œ๋น„์Šค์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๋Š” ์ˆœ์„œ๋Š” ์‹ค์ œ ๊ฒŒ์‹œ๋ฌผ์ด ๊ฒŒ์‹œ๋œ ์ˆœ์„œ์™€ ์ „ํ˜€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ.(๋ณธ ์„œ๋น„์Šค์—์„œ ๊ด€๋ฆฌํ•˜๋Š” PK ์ƒ์„ฑ ๋ฐฉ์‹๊ณผ ๊ด€๋ จํ•˜์—ฌ ๊ณ ๋ คํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ.)
  • ๋ฌดํ•œ์Šคํฌ๋กค ๊ตฌํ˜„
    • ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๊ฒฐ์ •(๋งˆ์ง€๋ง‰ ์กฐํšŒ ๊ฒฐ๊ณผ ์ดํ›„ ์‹œ์ ๋ถ€ํ„ฐ ์ฟผ๋ฆฌ)
      • ๋‹จ์ˆœ offset ์‚ฌ์šฉ์€ ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จํ•จ.
        • ๋‹ค์Œ ํŽ˜์ด์ง€๋ฅผ ์กฐํšŒํ•˜๊ธฐ ์ „์— ์ƒˆ๋กœ์šด ๊ฒŒ์‹œ๋ฌผ์ด ์˜ฌ๋ผ์˜จ๋‹ค๋ฉด, ์ค‘๋ณต๋˜๋Š” ๊ฒŒ์‹œ๋ฌผ์ด ๋“ฑ์žฅํ•  ์ˆ˜ ์žˆ์Œ.
        • UX ์ธก๋ฉด์—์„œ, ์Šคํฌ๋กค์„ ๋‚ด๋ฆด ๋•Œ, ์ค‘๋ณต๋œ ๊ฒŒ์‹œ๋ฌผ์ด ๋“ฑ์žฅํ•˜๋Š” ๊ฒƒ์€ ์ข‹์ง€ ๋ชปํ•จ.
      • ๋งˆ์ง€๋ง‰ ์กฐํšŒ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๊ทธ ์ดํ›„์˜ ๊ฒฐ๊ณผ๋ฅผ ์กฐํšŒํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฒฐ๋ก ์„ ๋ƒ„.
    • ๋งˆ์ง€๋ง‰ ์กฐํšŒ ๊ฒฐ๊ณผ๋ฅผ DB์—์„œ ์–ด๋–ป๊ฒŒ ํŠน์ •ํ•  ๊ฒƒ์ธ๊ฐ€
      • Incremental, ํ˜น์€ Time-Based๋กœ ์ƒ์„ฑ๋œ PK๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‚˜, ๋ณธ ์„œ๋น„์Šค์—์„œ๋Š” ๋ถ€์ ์ ˆํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•จ.
        • ์—ฌ๋Ÿฌ SNS์˜ ๊ฒŒ์‹œ๋ฌผ ID ํƒ€์ž…๊ณผ ๊ด€๋ฆฌ ์ฒด๊ณ„๊ฐ€ ๋‹ค๋ฆ„. ๋•Œ๋ฌธ์— ๋ณธ ์„œ๋น„์Šค์—์„œ๋Š” ๋Œ€๋ฆฌํ‚คPK๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ํŒ๋‹จํ•˜์˜€์Œ.
        • SNS ๊ฒŒ์‹œ๋ฌผ์˜ ์‹ค์ œ ๊ฒŒ์‹œ ์‹œ์ ๊ณผ, ๋ณธ ์„œ๋น„์Šค์—์„œ DB์— ์ €์žฅํ•œ ์‹œ์ ์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ.
      • ์œ„ ๋ฌธ์ œ๋Š” ์ •๊ทœํ™”๋ฅผ ํฌ๊ธฐํ•˜๊ณ , ํ•ด์‹œํƒœ๊ทธ๋งˆ๋‹ค Content๋ฅผ ์ค‘๋ณต ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ธฐ๋Š” ํ•˜์ง€๋งŒ, ๋ณด๋‹ค ์˜จ๊ฑดํ•œ ๋ฐฉ๋ฒ•์„ ์ฑ„ํƒํ•จ.
        • ๋ฌธ์ œ์˜ ์‹ฌ๊ฐ์„ฑ์— ๋น„ํ•ด์„œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์ด ๋„ˆ๋ฌด ๊ธ‰์ง„์ ์ด๋ผ๊ณ  ํŒ๋‹จํ•จ.
        • ํ†ต๊ณ„ ๊ด€๋ จ ๊ธฐ๋Šฅ ๊ตฌํ˜„์‹œ ์• ๋กœ์‚ฌํ•ญ์ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ•จ.
      • ๋งˆ์ง€๋ง‰ ์กฐํšŒ๋œ ๊ฒŒ์‹œ๋ฌผ์„ ํŠน์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ์‹œ์ ์ธ createdAt์„ ํ™œ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•จ.
  • ์ฟผ๋ฆฌ ์„ฑ๋Šฅ ๋ฌธ์ œ
    • ๋ฌธ์ž์—ด ๋งค์นญ ์„ฑ๋Šฅ ๋ฌธ์ œ
      • Content.hashtag๋ฅผ ๊ณต๋ฐฑ ๊ตฌ๋ถ„ ๋ฌธ์ž์—ด๋กœ ์ €์žฅํ•จ.
      • like %tofind%๋กœ ๊ฒ€์‚ฌํ•  ๊ฒฝ์šฐ, ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์— ํฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•จ.
      • ํ•ด๊ฒฐ๋ฐฉ๋ฒ•
        • HashtagContent ์—”ํ‹ฐํ‹ฐ(ํ…Œ์ด๋ธ”)๋ฅผ ๋งŒ๋“ค์–ด ์ตœ์ ํ™”๋ฅผ ์‹œ๋„ํ•˜์˜€์Œ.
          • HashtagContent
            • Long id(๋Œ€๋ฆฌํ‚ค, PK)
            • String hashtag
            • Long contentId(์™ธ๋ž˜ํ‚ค)
    • Join ์ฟผ๋ฆฌ ์„ฑ๋Šฅ ๋ฌธ์ œ
      • ์ธ๋ฑ์Šค๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ
        • ์•ž์„œ ์–ธ๊ธ‰ํ•œ ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด์ „ ๊ฒŒ์‹œ๋ฌผ์„ ํŠน์ •ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ์ดํ›„, ์ธ๋ฑ์Šค๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ• ์ˆ˜ ์—†๋‹ค๋Š” ์ ์„ ์ธ์ง€ํ•˜์˜€์Œ.
      • ํ•ด๊ฒฐ๋ฐฉ๋ฒ•
        • ์ •๊ทœํ™”๋ฅผ ์กฐ๊ธˆ ํฌ๊ธฐํ•˜๊ณ , HashtagContent์— createdAt ์ปฌ๋Ÿผ์„ ์ถ”๊ฐ€ํ•จ.
          • join์‹œ, ๋“œ๋ผ์ด๋น™ ํ…Œ์ด๋ธ”์˜ Row ์ˆ˜๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ž„.
          • createdAt์„ HashtagContent์— ์ถ”๊ฐ€ํ•  ๊ฒฝ์šฐ, ๋“œ๋ผ์ด๋น™ ํ…Œ์ด๋ธ”์—์„œ ๋ชฉ๋ก ์ปจํ…์ธ  ์ฟผ๋ฆฌ์— ํ•„์š”ํ•œ ๋ชจ๋“  ์กฐ๊ฑด์„ ์™„์„ฑํ• ์ˆ˜ ์žˆ์Œ.
            • ์ฟผ๋ฆฌ ์กฐ๊ฑด์„ HashtagContent์— ์„ค์ •๋œ ๋ณตํ•ฉ ์ธ๋ฑ์Šค (hashtag, createdAt)๋ฅผ ํ†ตํ•ด ์™„์ „ํžˆ ์ปค๋ฒ„ ๊ฐ€๋Šฅํ•จ.
          • ๋“œ๋ฆฌ๋ธ ํ…Œ์ด๋ธ”์˜ ๊ฐ’(์ด ๊ฒฝ์šฐ Content.createdAt)์— ์˜์กด์ ์ด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ฟผ๋ฆฌ ๋น„์šฉ ์˜ˆ์ธก์ด ์‰ฌ์›Œ์ง.
  • ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ ์‹œ์ ์˜ ์„ธ๋ถ„์„ฑ(granularity)๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์ œ
    • ์™ธ๋ถ€ SNS์—์„œ ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ ์‹œ์ ์„ ์–ผ๋งˆ๋‚˜ ์ƒ์„ธํ•˜๊ฒŒ ์ œ๊ณตํ•˜๋А๋ƒ์— ๋”ฐ๋ผ์„œ ์ฟผ๋ฆฌ ๋ฐฉ์‹์— ์ž ์žฌ์ ์ธ ๋ฌธ์ œ ๋ฐœ์ƒ์ด ๊ฐ€๋Šฅํ•จ.
      • DB์—๋Š” ์ˆ˜~์ˆ˜์‹ญms ๋‹จ์œ„๋กœ ์„ธ๋ถ„ํ™”๋œ ์‹œ๊ฐ„ ์ •๋ณด๋ฅผ ์ €์žฅ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์™ธ๋ถ€ ์„œ๋น„์Šค๊ฐ€ ์‹œ๊ฐ„์„ ์–ผ๋งˆ๋‚˜ ์ž์„ธํžˆ ์ œ๊ณตํ•˜๋Š”์ง€ ๊ณ ๋ คํ•˜์—ฌ์•ผํ•จ.
      • ๋งŒ์•ฝ API๋กœ ์ œ๊ณต๋˜๋Š” ๊ฒŒ์‹œ๋ฌผ์˜ ์‹œ๊ฐ„ ๋‹จ์œ„๊ฐ€ 1์ดˆ, 1๋ถ„๊ณผ ๊ฐ™์ด ํฐ ๋‹จ์œ„๋กœ ์ œ๊ณต๋œ๋‹ค๋ฉด, ๋™์ผํ•œ ์‹œ๊ฐ„์— ์ƒ์„ฑ๋œ ๊ฒŒ์‹œ๋ฌผ์ด ์—ฌ๋Ÿฟ ์กด์žฌํ•  ์ˆ˜ ์žˆ์Œ.
        • ์ด ๊ฒฝ์šฐ, createdAt์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฌดํ•œ์Šคํฌ๋กค์„ ๊ตฌํ˜„ํ•œ ๋ณธ ์„œ๋น„์Šค์—์„œ, ๋™์ผํ•œ ๊ฒฐ๊ณผ๋งŒ ์ง€์†์ ์œผ๋กœ ์ฟผ๋ฆฌ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.
    • ํ•ด๊ฒฐ๋ฐฉ๋ฒ•
      • ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ์— offset ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•˜๊ณ , ๋‹ค์Œ ์ฟผ๋ฆฌ์— offset ์„ค์ •์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ(๋งˆ์ง€๋ง‰ ์กฐํšŒ๋œ ๊ฒŒ์‹œ๋ฌผ์˜ ์ƒ์„ฑ์‹œ์ ๊ณผ, ๊ทธ ์งํ›„์˜ ์ƒ์„ฑ์‹œ์ ์ด ๊ฐ™์€ ๊ฒฝ์šฐ), ์ด๋ฅผ ํŒ๋‹จํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋„๋ก api ์ŠคํŽ™์„ ์ž‘์„ฑํ•˜์˜€์Œ.
      • createdAt ํŒŒ๋ผ๋ฏธํ„ฐ๋„ ์—ฌ์ „ํžˆ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ƒˆ ๊ฒŒ์‹œ๋ฌผ๋กœ ์ธํ•ด์„œ ์ค‘๋ณต๋œ ๊ฒฐ๊ณผ๊ฐ€ ์กฐํšŒ๋˜๋Š” ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ• ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐ๋จ.
    • ์ถ”๊ฐ€๋กœ ๊ณ ๋ คํ•ด์•ผํ•  ์ 
      • offset์˜ ํŠน์„ฑ์ƒ, ์—„์ฒญ๋‚˜๊ฒŒ ์ธ๊ธฐ์žˆ๋Š” ํ•ด์‹œํƒœ๊ทธ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผํ•  ๊ฒฝ์šฐ, ์ฟผ๋ฆฌ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ด์•ผํ•  ํ•„์š”๊ฐ€ ์žˆ์„ ์ˆ˜๋„ ์žˆ์Œ.
        • ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ contentId๊นŒ์ง€ ๋ฐ›๊ณ , ์ •๋ ฌ ์กฐ๊ฑด์— ํฌํ•จ์‹œํ‚จ ๋’ค, contentId ์ดํ›„์˜ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์‹์œผ๋กœ ๊ตฌํ˜„ํ• ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™์Œ.
        • ๋‹จ, contentId ์ปฌ๋Ÿผ๊นŒ์ง€ ์ธ๋ฑ์Šค์— ํฌํ•จ๋  ๊ฒฝ์šฐ, ์ธ๋ฑ์Šค์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์ ธ์„œ ์ „๋ฐ˜์ ์ธ ์ฝ๊ธฐ ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง€๋Š” trade-off๊ฐ€ ์กด์žฌํ•จ.
        • ์ถ”ํ›„ sns์—์„œ ์ œ๊ณตํ•˜๋Š” ์‹œ๊ฐ„ ์‘๋‹ต ๊ฐ’์ด ์–ด๋–ค์ง€ ํ™•์ธํ•˜๊ณ , ์‹ค์ œ ์„œ๋น„์Šค์˜ ์œ ์ฆˆ์ผ€์ด์Šค๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋‹ค๋ฅธ ๋ฐฉ์•ˆ์„ ์ƒ๊ฐํ•ด๋ณผ๊ฒƒ.
์™ธ๋ถ€ API ํ˜ธ์ถœ ์ถ”์ƒํ™” - click
  • ์™ธ๋ถ€ ์†Œ์…œ๋ฏธ๋””์–ด ์„œ๋น„์Šค์˜ API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ณผ์ •์„ ์ถ”์ƒํ™”ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ตฌํ˜„์ฒด๋กœ ๋Œ€์ฒดํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ๊ตฌํ˜„
    • ExternalApiHandler ์ธํ„ฐํŽ˜์ด์Šค
      • ExternalApiHandler๋ฅผ ํ†ตํ•ด ๊ฐ ์†Œ์…œ ๋ฏธ๋””์–ด ํ”Œ๋žซํผ์˜ API ํ˜ธ์ถœ์„ ์ถ”์ƒํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.
        • InstagramApiHandler , FacebookpiHandler , TreadsApiHandler , TwitterApiHandler๋“ฑ์˜ ๊ตฌํ˜„์ฒด๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
      • getSourceType ๋ฉ”์„œ๋“œ๋Š” ๊ฐ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์–ด๋–ค ์†Œ์…œ ๋ฏธ๋””์–ด์˜ API๋ฅผ ๋‹ค๋ฃจ๋Š”์ง€ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค.
      • like์™€ share ๋ฉ”์„œ๋“œ๋Š” ๊ฒŒ์‹œ๋ฌผ์— ์ข‹์•„์š” ๋˜๋Š” ๊ณต์œ ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • ExternalApiHandlerResolver
      • ๋‚ด๋ถ€์— ExternalApiHandler์˜ ๊ตฌํ˜„์ฒด๊ฐ€ ๋งคํ•‘๋œ Map ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, sourceType์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ExternalApiHandler๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
      • ์ƒ์„ฑ์ž์—์„œ ExternalApiHandler๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋“ค์„ ์ฃผ์ž…๋ฐ›์•„ sourceType์„ ๊ธฐ์ค€์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ ํด๋ž˜์Šค๋“ค์„ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.

TIL ๋ฐ ํšŒ๊ณ 


Authors


References