์ „์ฒด ๊ธ€ (116)

๋ฐ˜์‘ํ˜•
07
05
๋ฐ˜์‘ํ˜•

# ๋ฉ€ํ‹ฐ๋ฐ”์ธ๋”ฉ `@IntoSet` `@IntoMap` `@Multibinds`

๋ฉ€ํ‹ฐ๋ฐ”์ธ๋”ฉ์€ ์—ฌ๋Ÿฌ ๋ฐ”์ธ๋”ฉ์„ ํ•˜๋‚˜์˜ ์ปฌ๋ ‰์…˜์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ตฌ์กฐ๋‹ค. Set, Map ์ปฌ๋ ‰์…˜์„ ์ง€์›ํ•˜๋ฉฐ  ์ค‘๋ณต๋ฐ”์ธ๋”ฉ์ด๋ž‘์€ ๊ฒฐ์ด ์ข€ ๋‹ค๋ฅด๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. 

Set์„ ์ด์šฉํ•œ ๋ฐฉ์‹์€ ๊ธฐ์กด @Providesํ•˜๋˜ ๋ฐ”์ธ๋”ฉ์— `@IntoSet`์„ ๋‹ฌ์•„์ฃผ๋ฉด ๋œ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์ปดํŒŒ์ผ ํƒ€์ž„์—์„œ Set์•ˆ์— @IntoSet์ด ์„ ์–ธ๋œ ๋ฐ”์ธ๋”ฉ์„ ๋ฌถ์–ด์„œ ๊ฐ–๊ณ  ์žˆ๊ฒŒ ๋œ๋‹ค. ๊ทผ๋ฐ ์ปฌ๋ ‰์…˜์œผ๋กœ ๋ฐ”์ธ๋”ฉ์„ ๊ด€๋ฆฌํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•˜๋‚˜ ์ƒ๊ธด๋‹ค.

 

๋‹จ๋… ๋ฐ”์ธ๋”ฉ์ผ ๋•Œ๋Š” EntryPoint์—์„œ @Injectํ•  ๋•Œ ์•Œ์•„์„œ ๊ฐ€์ ธ๊ฐ”๋Š”๋ฐ, ๋ฐ˜ํ™˜ํƒ€์ž…์ด Set<T>์œผ๋กœ ๊ฐ์‹ธ์ ธ์žˆ์–ด์„œ ๊ทธ๋ƒฅ @Injectํ•˜๋ฉด MissingBinding์„ ์˜ค๋ฅ˜๋กœ ๋‚ด๋ฟœ๊ฒŒ ๋œ๋‹ค.

 

๋‹จ๋… ๋ฐ”์ธ๋”ฉ์ด Set<T>์œผ๋กœ ๋˜์–ด์žˆ๋‹ค๋ฉด @IntoSet๋ง๊ณ  `@ElementsIntoSet`์„ ๋‹ฌ์•„์ค˜์•ผ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋‹จ๋… ๋ฐ”์ธ๋”ฉ ๋œ Set์˜ ์›์†Œ๋“ค์ด Set ๋ฉ€ํ‹ฐ ๋ฐ”์ธ๋”ฉ ๋ผ์„œ ๋“ค์–ด์˜จ๋‹ค.

@Module
@InstallIn(SingletonComponent::class)
class MultiBindModule {
    @Provides
    @IntoSet
    fun provideString(): String{
        return "test"
    }
}

// ์‚ฌ์šฉ์€ ์•„๋ž˜์ฒ˜๋Ÿผ Set์œผ๋กœ
@Inject
lateinit var str: Set<String>

Set์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ”์ธ๋”ฉ์„ ์“ด ๊ฑด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

@Module
@InstallIn(SingletonComponent::class)
class MultiBindModule {
    @Provides
    @IntoSet
    fun provideString(): String {
        return "test"
    }

    @Provides
    @ElementsIntoSet
    fun provideStrings(): Set<String> {
        return setOf("a", "b", "c")
    }
}

๊ทธ๋Ÿผ ์œ„์—์„œ str์€ Set์„ ๋ฐ›์•„์˜ค๋Š”๋ฐ, ๊ฒฐ๊ณผ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋‚˜์˜ฌ๊นŒ?

๋‹ค ๋‹ด๊ฒจ์„œ ๋“ค์–ด์˜จ๋‹ค. Set ๋ง๊ณ  Map์œผ๋กœ๋„ ๋ฉ€ํ‹ฐ๋ฐ”์ธ๋”ฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Map์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Key - Value ํ˜•์‹์ด๋ผ ํ‚ค๋ฅผ ์ง€์ •ํ•ด์ค˜์•ผํ•˜๋Š”๋ฐ, String, Int, Long, Class๋กœ ํ‚ค๋ฅผ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ Set๊ณผ ๋น„์Šทํ•œ๋ฐ, @IntoMap๊ณผ @"ํƒ€์ž…"Key("ํ‚ค ๊ฐ’")์„ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

@Provides
@IntoMap @IntKey(1)
fun provideName(): String{
    return "one"
}

@Provides
@IntoMap @ClassKey(Test::class)
fun provideNameOfClass(): String{
    return "Test Value"
}

Testํด๋ž˜์Šค๋ฅผ ํ‚ค๋กœ ์“ด๊ฑด๋ฐ ํ‚ค ํƒ€์ž…์ด `Class<*>`๊ฐ€ ๋œ๋‹ค. Map์„ ์‚ฌ์šฉํ•œ ๋ฉ€ํ‹ฐ๋ฐ”์ธ๋”ฉ์€ ํ‚ค๊ฐ’์ด ๊ฐ€์žฅ ์ค‘์š”ํ•ด์„œ ์กฐ์‹ฌํ•ด์•ผ๋œ๋‹ค.

@Inject
lateinit var mapInt: Map<Int, String>

@Inject
lateinit var mapClass: Map<Class<*>, String>

mapClass ๊ฐ’์€ `mapClass[Test::class.java]`๋กœ ๊บผ๋‚ด์“ด๋‹ค.

 

์ง€์ •๋œ ํƒ€์ž… ๋ง๊ณ ๋„ ํ‚ค๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. `@MapKey`๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐฉ์‹์ธ๋ฐ ํ‚ค๊ฐ€ ๋  enum class ๊ฐ™์€ ๊ฑธ annotation class๋กœ ์ปค์Šคํ…€ ํ‚ค ์–ด๋…ธํ…Œ์ด์…˜ ์„ ์–ธํ•ด์ฃผ๊ณ , @MapKey๋ฅผ ๋ถ™์—ฌ์„œ ์“ฐ๋ฉด๋œ๋‹ค.

@MapKey
annotation class CustomMapKey(val value: Keys)

enum class Keys {
    ONE,
    TWO,
    THREE
}

// ๋ชจ๋“ˆ์—์„œ๋Š” ์•„๋ž˜ ์ฒ˜๋Ÿผ
@Provides
@IntoMap
@CustomMapKey(Keys.ONE)
fun provideCK(): String{
    return "CK"
}

Inject ๋ถ€๋ถ„์—์„œ๋Š” Enum ํด๋ž˜์Šค๋ฅผ Key์— ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

 

`@Multibinds`๋Š” ๋ฐ”์ธ๋”ฉ ๋œ์ง€ ์•ˆ๋œ์ง€ ๋ชจ๋ฅด๋Š” ์ƒํƒœ์ด๊ฑฐ๋‚˜ ๋นˆ์ปฌ๋ ‰์…˜์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

 

๋„์›€์ด ๋๋‹ค๋ฉด ๋Œ“๊ธ€์ด๋‚˜ ๊ณต๊ฐ ๋ฒ„ํŠผ ํ•œ ๋ฒˆ์”ฉ ๋ˆ„๋ฅด๊ณ  ๊ฐ€์ฃผ์„ธ์š”!

 

๋ฐ˜์‘ํ˜•
COMMENT
 
07
05
๋ฐ˜์‘ํ˜•

# Binding?

flowchart LR
    Android -->|Compile, Request| Hilt
    Hilt -->|Runtime, Inject| Android
    AppModule ---> Hilt
    NetworkModule ---> Hilt

์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ํ–‰์œ„๋‚˜ ๊ฐœ๋ณ„์ ์ธ ์ธ์Šคํ„ด์Šค dependency(Inject๋กœ ๋˜์–ด์žˆ๋Š”) ๋ชจ๋‘ ๋ฐ”์ธ๋”ฉ์ด๋ผ๊ณ  ํ•œ๋‹ค. ๊ทธ๋ƒฅ ์˜์กด์„ฑ์„ ๋ฐ”๋กœ ๊ฝ‚์„ ์ˆ˜๋„ ์žˆ๊ณ , ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•  ๋ชจ๋“ˆ์„ ๋‘ฌ์„œ ๋ชจ๋“ˆ์„ HiltComponent์— ๊ฝ‚์•„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

# Dependency Injection - ์ƒ์„ฑ์ž ์ฃผ์ž…, ํ•„๋“œ ์ฃผ์ž…, ๋ฉ”์„œ๋“œ ์ฃผ์ž…

// ์ƒ์„ฑ์ž ์ฃผ์ž…
class Test @Inject constructor(foo: Foo){ // foo ์ฃผ์ž…๊ณผ ๋™์‹œ์— Test ๋ฐ”์ธ๋”ฉ
 
}
// ํ•„๋“œ ์ฃผ์ž…
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject // ์–˜๋Š” ์š”์ฒญํ•ด์„œ ์ฃผ์ž… ๋ฐ›๋Š” ๊ฒƒ
    lateinit var test: Test
    ...
}
// ๋ฉ”์„œ๋“œ ์ฃผ์ž…
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    
    @Inject
    fun foo(bar: Bar){
	...
}

์ƒ์„ฑ์ž ์ฃผ์ž…๊ณผ ํ•„๋“œ์ฃผ์ž…์€ ์ด์ „ ๊ฒŒ์‹œ๊ธ€์—์„œ ํ™•์ธํ–ˆ๋‹ค. ๋ฉ”์„œ๋“œ ์ฃผ์ž…๋งŒ ๋ณด๋ฉด ๋˜๋Š”๋ฐ, foo ๋ฉ”์„œ๋“œ๋Š” bar๋ผ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›๊ฒŒ ๋œ๋‹ค.

 

์ƒ์„ฑ์ž ์ฃผ์ž…์€ ๋”ฐ๋กœ ์Šค์ฝ”ํ”„ ์—†์ด Injectํ•ด๋ฒ„๋ฆฌ๋Š”๋ฐ ์ด ๊ฒฝ์šฐ Test ํด๋ž˜์Šค ์ž์ฒด๋„ ์ปดํŒŒ์ผ ํƒ€์ž„์— Hilt ์ปดํฌ๋„ŒํŠธ์— ๋ฐ”์ธ๋”ฉ๋œ๋‹ค๋Š” ํŠน์ด์ ์ด ์žˆ๋‹ค.  ๋ฉ”์„œ๋“œ ์ฃผ์ž…์€ Inject๊ฐ€ `super.onCreate` ์ดํ›„์— ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์„œ๋“œ์—์„œ lateinit var๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.

lateinit var fooFun: Foo

@Inject // method ์ฃผ์ž…
fun provideFoo(foo: Foo){ // super.onCreate ์ดํ›„์— Inject๋˜์–ด fooFun์€ ์ดˆ๊ธฐํ™” ๋œ ์ƒํƒœ๋กœ ์ ‘๊ทผ๊ฐ€๋Šฅํ•˜๋‹ค.
    fooFun = foo
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    assert(this::fooFun.isInitialized) // true์ด๊ธฐ ๋•Œ๋ฌธ์— crash ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
	...
}

๊ทผ๋ฐ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ ์ฃผ์ž…์€ ์•„๋ฌด๋ž˜๋„ ์‚ฌ์šฉํ•˜๋Š” ๋นˆ๋„๊ฐ€ ์ ์„ ๊ฒƒ ๊ฐ™๋‹ค.

# `@Qualifier` , `@Named("์‹๋ณ„๋ช…")`

Hilt๋Š” ํƒ€์ž…์„ ๊ธฐ์ค€์œผ๋กœ ์˜์กด์„ฑ์„ ๊ตฌ๋ถ„ํ•˜๋Š”๋ฐ ๊ทธ๋ž˜์„œ ์ค‘๋ณต ๋ฐ”์ธ๋”ฉ์ด ๋ฐœ์ƒํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋™์ผํ•œ ํƒ€์ž…์˜ ๋‘ ์˜์กด์„ฑ์„ ๊ตฌ๋ถ„ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. -> `Dagger/DuplicateBindings` ๋กœ ์—๋Ÿฌ๊ฐ€ ๋‚˜์˜จ๋‹ค. ๊ทผ๋ฐ ํƒ€์ž…์€ ๋™์ผํ•˜์ง€๋งŒ ์—ญํ• ์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ ๋‘ ๊ฐ€์ง€ ๋ชจ๋‘ ์‚ด๋ ค์•ผํ•  ๋•Œ๊ฐ€ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด Access Token์œผ๋กœ ์ ‘๊ทผํ•ด์•ผ ๋˜๋Š” ์˜์กด์„ฑ๊ณผ ๊ทธ๊ฒŒ ์—†์–ด๋„ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์˜์กด์„ฑ ์ด๋ ‡๊ฒŒ ๋‘๊ฐœ๋กœ ๋‚˜๋ˆŒ ๋•Œ๊ฐ€ ๊ทธ ์˜ˆ์‹œ๋‹ค.  ์ด ๊ฒฝ์šฐ Qualifier๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ์€๊ทผํžˆ ๊ฐ„๋‹จํ•˜๋‹ค.

@Qualifier
annotation class TestQualifier
@Module
@InstallIn(SingletonComponent::class)
object TestModule {

    @Provides
    fun provideTest(): Test {
        return Test(id = "Test")
    }

    @TestQualifier
    @Provides
    fun provideTest2(): Test {
        return Test(id = "TestQualifier")
    }
}

Qualifer ์–ด๋…ธํ…Œ์ด์…˜์„ ๋‹ฌ๊ณ ์žˆ๋Š” ์ปค์Šคํ…€ Qualifier annotation์„ ๋งŒ๋“ค๊ณ , ๊ทธ๊ฑธ ์ค‘๋ณต๋ฐ”์ธ๋”ฉ์ด ํ•„์š”ํ•œ ๊ณณ์— ๋‹ฌ์•„์ฃผ๋ฉด ๋œ๋‹ค.

@Inject
lateinit var test1: Test

@TestQualifier
@Inject
lateinit var test2: Test

// ๋ฉ”์„œ๋“œ ์ฃผ์ž…์˜ ๊ฒฝ์šฐ
@Inject
fun injectTest(@TestQualifier test: Test){
    testQualifier = test
}

๋ฌผ๋ก  ์ฃผ์ž…๋ฐ›์„ ๊ณณ์—๋„ ๋‹ฌ์•„์ค˜์•ผ๋œ๋‹ค.

๊ป๋ฐ๊ธฐ๋งŒ ๋งŒ๋“ค์–ด๋‘๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์†์„ฑ์„ ์ •์˜ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

@Qualifier
annotation class TestQualifier(val id: String)

์ด๋ ‡๊ฒŒ ์ •์˜ํ•˜๋ฉด Inject๋‚˜ ๋ฐ”์ธ๋”ฉ ํ•  ๋•Œ ์†์„ฑ๊ฐ’์ธ key๋ฅผ ๋ช…์‹œํ•ด์ค˜์•ผํ•œ๋‹ค.

์ด๋Ÿฐ ์‹๋ณ„๊ณผ์ •์„ ์ข€ ๋” ์‰ฝ๊ฒŒํ•˜๋Š” ๋ฐฉ๋ฒ•์ด `@Named`์ธ๋ฐ ์‹๋ณ„๋ช… ๋ฌธ์ž์—ด์„ id๋กœ ๊ฐ–๋Š” Qualifier๋ผ๊ณ  ๋ณด๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

@Module
@InstallIn(SingletonComponent::class)
object TestModule {

//    @TestQualifier
    @Named("Test")
    @Provides
    fun provideTest2(): Test {
        return Test(id = "TestQualifier")
    }
}

ํ•œ ๋ฐ ๋ชจ์•„ ๊ด€๋ฆฌํ•˜๊ธธ ์ข‹์•„ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ ์•„๋งˆ Named ๋ณด๋‹ค Qualifier๋ฅผ ์„ ํ˜ธํ•˜์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ•œ๋‹ค.

# Lazy์™€ Provider

Hilt์˜ Lazy ์ฃผ์ž…์€ by lazy๊ณผ ํŠน์ •์‹œ์ ์— ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๋Š” ์ ์—์„œ ์•ฝ๊ฐ„ ๋น„์Šทํ•˜๋‹ค. ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์‹œ์ ์„ ์กฐ์ ˆํ•œ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์ƒ์„ฑ๋น„์šฉ์ด ์ปค์„œ ์ด๊ฑธ ์กฐ์ ˆํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋„ ๋  ์ˆ˜ ์žˆ๋‹ค.

@Inject
lateinit var foo: Lazy<Foo> // Lazy

...
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    assert(foo.get().bar != null)

get์œผ๋กœ Lazy ์ฃผ์ž…์„ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ฃผ์˜ํ•  ์ ์€ Lazy๊ฐ€ dagger ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํƒ€์ž…์ด๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ์ฝ”ํ‹€๋ฆฐ๋„ Lazy๋ฅผ ๊ฐ–๊ณ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— import๋ฅผ ์ž˜๋ชปํ•˜๋ฉด get์œผ๋กœ ๋ชป๊ฐ€์ ธ์˜จ๋‹ค.

Lazy๋กœ ์„ ์–ธํ•œ ์ธ์Šคํ„ด์Šค๋Š” ํ•œ๋ฒˆ ์ฃผ์ž…๋˜๋ฉด ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

@Inject
lateinit var fooProvider: Provider<Foo>

Provider๋„ ๋น„์Šทํ•˜๋‹ค. get์œผ๋กœ ๊ฐ€์ ธ์˜ค๊ณ , ํ˜ธ์ถœํ•  ๋•Œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. Lazy์™€ ๋‹ค๋ฅธ ์ ์€ Lazy๋Š” ํ•œ๋ฒˆ ์ƒ์„ฑ๋˜๋ฉด ๊ทธ๊ฑธ ๊ฐ€์ ธ์˜ค๋Š” ๊ฑฐ๊ณ , Provider๋Š” ๋งค ํ˜ธ์ถœ๋งˆ๋‹ค ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ ํ˜ธ์ถœ์— ๋Œ€ํ•ด ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด Scope๋ฅผ ์ง€์ •ํ•ด์„œ(`@Singleton`์„ ๋ถ™์ธ๋‹ค๋˜๊ฐ€) ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•ด์•ผ๋œ๋‹ค.

# ๋ฐ”์ธ๋”ฉ ๊ธฐ๋ฒ• - `@Binds`

๋ฐ”์ธ๋”ฉ์€ DI ๊ทธ ์ž์ฒด(์ปดํฌ๋„ŒํŠธ์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ํ–‰์œ„) ๋˜๋Š” ๊ทธ ์˜์กด์„ฑ ์ž์ฒด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

๋ชจ๋“ˆ ์•ˆ์—์„œ ์ปดํฌ๋„ŒํŠธ์— ๋‹ฌ์•„๋†“๋Š” `@Provides`๋Š” ์ด์ œ ์ต์ˆ™ํ•ด์กŒ๋‹ค. ๊ธฐ์กด์— Provide ๋œ ๋ฐ”์ธ๋”ฉ์ด ์žˆ์œผ๋ฉด `@Binds`๋กœ ํšจ์œจ์ ์œผ๋กœ ๋‹ฌ์•„ ๋‘˜ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. Binds๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ ๋Š” ์–ธ์–ด ํŠน์„ฑ์ƒ ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์œผ๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜์— ํ•˜์œ„ ํƒ€์ž…์œผ๋กœ ๋ฐ”์ธ๋”ฉ์„ ๊ฑธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์ฆ‰ `@Binds`๋Š” ์ด๋ฏธ ๋ฐ”์ธ๋”ฉ ๋œ ์˜์กด์„ฑ์„ ํ™•์žฅ๊ด€๊ณ„์— ์žˆ๋Š” ์ƒˆ ํƒ€์ž…์œผ๋กœ ๊ฐ์‹ธ์„œ(์„ ํƒ์ ์œผ๋กœ ๋ชจ๋“ˆ ์„ค์น˜๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค) ๋ฐ”์ธ๋”ฉ ์‹œํ‚ฌ ๋•Œ ํšจ์œจ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ œ์•ฝ ์กฐ๊ฑด์ด ์กด์žฌํ•˜๋Š”๋ฐ,

  1. `@Binds`๋Š” ๋ชจ๋“ˆ ๋‚ด abstract ๋ฉ”์„œ๋“œ์— ์ถ”๊ฐ€๋ผ์•ผํ•œ๋‹ค.
  2. ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ•œ ๊ฐœ๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
  3. ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์ด ๋ฐ˜ํ™˜ ํƒ€์ž…์˜ ์„œ๋ธŒํƒ€์ž…์ด์–ด์•ผ ํ•œ๋‹ค.
  4. `@Scope` ๋ฐ `@Qualifier` ๋ž‘ ๊ฐ™์ด ์“ธ ์ˆ˜ ์žˆ๋‹ค. 

1, 2, 3 ๋ชจ๋‘ ํ™•์žฅ์ด ์šฉ์ดํ•œ ์–ธ์–ดํŠน์„ฑ์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜์˜ํ•œ ์กฐ๊ฑด๋“ค์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

abstract ๋ฉ”์„œ๋“œ๋Š” ๊ตฌํ˜„์ฒด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ผ ์ด๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๋Š”๋ฐ, provides๋Š” ๊ทธ๊ฒŒ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์•ผ๋œ๋‹ค.(ํŒŒ์ผ ์ž์ฒด๋ฅผ ๋ถ„๋ฆฌ ์‹œ์ผœ๋ฒ„๋ฆฌ๋Š” ๊ฒŒ ์ข‹๋‹ค.) ๋„ค์ด๋ฐ๊ทœ์น™์€ `bind์„œ๋ธŒํƒ€์ž…`์œผ๋กœ ์‹œ์ž‘ํ•œ๋‹ค.

@Module
@InstallIn(SingletonComponent::class)
// Binds๋ฅผ ์œ„ํ•œ ์ถ”์ƒ ๋ชจ๋“ˆ์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค
abstract class EngineModule {
    @Binds
    abstract fun bindGasolineEngine(engine: GasolineEngine): Engine

    @Binds
    abstract fun bindDieselEngine(engine: DieselEngine): Engine
}

Engine์€ ์ธํ„ฐํŽ˜์ด์Šค๊ณ , GasolineEngine, DieselEngine์€ ์ƒ์„ฑ์ž ๋ฐ”์ธ๋”ฉ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์— ๋‹ฌ๋ ค์žˆ๋Š” ์ƒํƒœ๋‹ค. ์ด๋Œ€๋กœ๋งŒ ๋†”๋‘๋ฉด Engine์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒŒ ์ค‘๋ณต๋ผ์„œ ์ค‘๋ณต๋ฐ”์ธ๋”ฉ์„ ํ—ˆ์šฉํ•˜์ง€์•Š๋Š” Hilt ํŠน์„ฑ์ƒ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. Named๋‚˜ Qualifier๋กœ ํ•ด๊ฒฐํ•˜๋ฉด ๋˜๋Š” ๋ถ€๋ถ„์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฑด ํ•„์š”์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

 

# ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ  `@BindsOptionalOf`

๋ฐ”์ธ๋”ฉ ๋˜์–ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๋Š” ์˜์กด์„ฑ์„ ์š”์ฒญํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. ์˜ต์…”๋„์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”์ธ๋”ฉ ๋˜์ง€์•Š์•„๋„ ์ผ๋‹จ ์ปดํŒŒ์ผ ์—๋Ÿฌ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋ฐ”์ธ๋”ฉ์ด ์•ˆ๋œ ๊ฒฝ์šฐ๋„ ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง€๋ฉด ์•ˆ๋œ๋‹ค. ๋˜ ๋ฐ›์•„์˜ฌ ์˜์กด์„ฑ๋„ Optionalํ•ด์•ผ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ์ž ๋ฐ”์ธ๋”ฉ ๋œ ์˜์กด์„ฑ๋“ค์€ ์ด๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

@Provides
fun provideFoo(): Foo{
    return Foo()
}

๊ทธ๋ž˜์„œ BindsOptionalOf๋Š” ๋”ฐ๋กœ provide๋œ ์˜์กด์„ฑ์„ ๋‹ฌ์•„์ค˜์•ผ๋œ๋‹ค.

@BindsOptionalOf
abstract fun bindDieselEngine(): Engine

์ด๋ ‡๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ• ๋ง๊ณ  ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„ ์ƒ์˜ ๊ด€๊ณ„์—์„œ ๋ชจ๋‘ `Optional<T>`๋กœ ์„ ์–ธํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.

@Inject
lateinit var foo: Optional<Foo>

BindsOptionalOf๋กœ ๋ฐ”์ธ๋”ฉ ๋œ ์˜์กด์„ฑ์„ ์š”์ฒญํ•  ๋•Œ๋Š” Optional๋กœ ๊ฐ์‹ธ์„œ ํ•ด์ฃผ๊ณ ,  get()์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.

๋ฐ”์ธ๋”ฉ ๋˜์ง€์•Š์•˜๋‹ค๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— isPresent๋กœ ์ฒดํฌํ•ด์ค˜์•ผ๋œ๋‹ค. 

`@BindsInstance`๋Š” ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ๊ณผ ๋™์‹œ์— ๋ฐ”์ธ๋”ฉ ๋˜๋Š” ๊ฑธ ๋งํ•œ๋‹ค. ๊ทผ๋ฐ ์ด๊ฑด ๋”ฐ๋กœ ์™ธ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค...

 

๋„์›€์ด ๋๋‹ค๋ฉด ๋Œ“๊ธ€์ด๋‚˜ ๊ณต๊ฐ ๋ฒ„ํŠผ ํ•œ ๋ฒˆ์”ฉ ๋ˆ„๋ฅด๊ณ  ๊ฐ€์ฃผ์„ธ์š”!

 

๋ฐ˜์‘ํ˜•
COMMENT
 
07
02
๋ฐ˜์‘ํ˜•

์ œ๊ฐ€ ๋ณด๋ ค๊ณ  ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณ„์† ๋‚ด์šฉ์ด ์ถ”๊ฐ€๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค

# SOLID ์›์น™

  • `Single Responsibility Principle` ๋‹จ์ผ์ฑ…์ž„์›์น™
    • ํ•œ ํด๋ž˜์Šค์— ํ•œ ์ฑ…์ž„์„ ๋ถ€์—ฌํ•ด์•ผํ•œ๋‹ค.
  • `Open Closed Principle`
    • ์ƒ์œ„ ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ค‘๊ฐ„์— ํ•˜๋‚˜ ๋‘ฌ์„œ ๋‚ด ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ๊ณ  ๋ณ€ํ™”์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ซํ˜€ ์žˆ์–ด์•ผํ•œ๋‹ค. Repo - RepoImpl๊ณผ ๊ฐ™์€ ๊ด€๊ณ„
  • `Liskov Substitution Principle` - ์ƒ์†์˜ ํŠน์„ฑ์„ ์ž˜ ํ™œ์šฉํ•˜๊ธฐ
    • ํ•˜์œ„ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋Š” ์ƒ์œ„ ๊ฐ์ฒด์— ๋„ฃ์–ด์„œ ์ƒ์œ„ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ์—ญํ• ์„ ํ•˜๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์–ด์•ผ๋œ๋‹ค.
    • ํ•˜์œ„ํด๋ž˜์Šค is a ์ƒ์œ„ํด๋ž˜์Šค
  • `Interface Segregation Principle`(์ธํ„ฐํŽ˜์ด์Šค ์ตœ์†Œ์ฃผ์˜ ์›์น™)
    • ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜์ง€์•Š๋Š” ๋ฉ”์„œ๋“œ์™€ ์˜์กด์„ฑ์ด ์žˆ์œผ๋ฉด ์•ˆ๋œ๋‹ค.
  • `Dependency Inversion Principle` - ์˜์กด์„ฑ ์—ญ์ „ ์›์น™
    • ๋ณ€ํ•˜๊ธฐ ์‰ฌ์šด๊ฒƒ์˜ ๋ณ€ํ™”์— ์˜ํ–ฅ์„ ๋ฐ›์ง€์•Š์•„์•ผํ•œ๋‹ค.  ๊ตฌํ˜„์ฒด์— ์˜์กดํ•˜์ง€ ๋ง๋ผ๋Š” ์–˜๊ธฐ๋‹ค.
    • ์ถ”์ƒํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ์ƒ์œ„ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ ๋ผ์›Œ์„œ ๋ณ€ํ™”์— ๋‘”๊ฐํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒŒ DIP์ด๋‹ค.

 

 

 

 


::์ถœ์ฒ˜::

https://github.com/VSFe/Tech-Interview?tab=readme-ov-file

https://github.com/WooVictory/Ready-For-Tech-Interview

https://github.com/gyoogle/tech-interview-for-developer

https://github.com/JaeYeopHan/Interview_Question_for_Beginner

๋„์›€์ด ๋๋‹ค๋ฉด ๋Œ“๊ธ€์ด๋‚˜ ๊ณต๊ฐ ๋ฒ„ํŠผ ํ•œ ๋ฒˆ์”ฉ ๋ˆ„๋ฅด๊ณ  ๊ฐ€์ฃผ์„ธ์š”! ๋กœ๊ทธ์ธ ์•ˆํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค ^_^

 

๋ฐ˜์‘ํ˜•

'CS๐Ÿ–ฅ๏ธ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค  (0) 2024.07.02
COMMENT
 
07
02
๋ฐ˜์‘ํ˜•

์ œ๊ฐ€ ๋ณด๋ ค๊ณ  ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณ„์† ๋‚ด์šฉ์ด ์ถ”๊ฐ€๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค

# ์ •๊ทœํ™”, ๋ฐ˜์ •๊ทœํ™”

RDB์—์„œ anomaly ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ ์ ˆํ•œ relation์œผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

`anomaly` -> ์ •๊ทœํ™”๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š์•„์„œ ์„œ๋กœ ๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ค‘๋ณต๋œ ์ปฌ๋Ÿผ ๊ฐ’์„ ๊ฐ–๊ฒŒ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์‚ฝ์ž…, ์‚ญ์ œ, ๊ฐฑ์‹  ์‹œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋กœ NULL๊ฐ’์ด ๋“ค์–ด๊ฐ€์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๊ฑฐ๋‚˜, ๊ฐฑ์‹ ๋ฌธ์ œ๋กœ ๋ชจ์ˆœ์ด ์ƒ๊ธฐ๊ฑฐ๋‚˜, ์˜๋„์™€ ์ƒ๊ด€์—†๋Š” ๋ฐ์ดํ„ฐ๊นŒ์ง€ ์‚ญ์ œ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

 

  • 1 ์ •๊ทœํ™”(First Normal Form - 1NF)
    • ๋ชจ๋“  ๋„๋ฉ”์ธ์€ ์›์ž๊ฐ’์œผ๋กœ๋งŒ ๊ฐ–๊ณ ์žˆ๋‹ค(๋‹จ์ผ๊ฐ’๋งŒ ๊ฐ€๋Šฅํ•˜๊ณ  ์—ฌ๋Ÿฌ๊ฐ’์„ ๊ฐ–๋Š” ์ปฌ๋Ÿผ์ด ์—†์–ด์•ผ๋œ๋‹ค)
    • ์ปฌ๋Ÿผ์— ๋ฐ˜๋ณต๋˜๋Š” ๊ทธ๋ฃน์ด ๋‚˜์˜ค์ง€ ์•Š์•„์•ผํ•œ๋‹ค.
    • ๊ธฐ๋ณธํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ ํŠœํ”Œ์„ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•œ๋‹ค.
  • 2 ์ •๊ทœํ™”
    • 1NF๋ฅผ ๋งŒ์กฑํ•˜๋Š” ์ƒํ™ฉ์—์„œ ๋ถ€๋ถ„์  ํ•จ์ˆ˜ ์ข…์†์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒฝ์šฐ๋‹ค.
    • ํ•จ์ˆ˜์  ์ข…์†์€ ์™„์ „ํ•จ์ˆ˜ ์ข…์†, ๋ถ€๋ถ„ํ•จ์ˆ˜ ์ข…์†์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ๋ณธํ‚ค(PK)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•œ๋‹ค. ๊ธฐ๋ณธํ‚ค๋Š” NULL์ด๋ฉด ์•ˆ๋˜๊ณ  ์ค‘๋ณต๋œ ๊ฐ’์„ ๊ฐ€์ง€๋ฉด ์•ˆ๋œ๋‹ค.
      • ์™„์ „ํ•จ์ˆ˜ ์ข…์† - `X -> Y`๋กœ X๊ฐ’์— ๋”ฐ๋ผ Y๊ฐ’์ด ๊ฒฐ์ •๋˜๋Š” ๊ฒฝ์šฐ. ๋ณตํ•ฉํ‚ค์—ฌ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
      • ๋ถ€๋ถ„ํ•จ์ˆ˜ ์ข…์† - ๋‹จ์ผํ‚ค๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ , ๋ณตํ•ฉํ‚ค ์ค‘ ํ•˜๋‚˜๋งŒ์œผ๋กœ๋„ Y๊ฐ’์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ
      • ์ดํ–‰์  ํ•จ์ˆ˜์ข…์† - `X -> Y -> Z`๋กœ Z๊นŒ์ง€ ์•Œ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ 
  • 3 ์ •๊ทœํ™”
    • ๊ธฐ๋ณธ ํ‚ค๊ฐ€ ์•„๋‹Œ ๋ชจ๋“  ์†์„ฑ์ด ํ‚ค๋ณธํ‚ค์— ๋Œ€ํ•ด ์ดํ–‰์  ํ•จ์ˆ˜ ์ข…์† ๊ด€๊ณ„๋ฅผ ๋Š์–ด๋ฒ„๋ฆฌ๋Š” ๊ฒƒ
    • ์†์„ฑ(์ปฌ๋Ÿผ)์ด `X -> Y -> Z`๋กœ ๊ฒฐ์ •๋˜๋Š” ๊ฑธ ๋Š์–ด์„œ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”๋กœ ๋งŒ๋“ค์–ด๋ฒ„๋ฆฐ๋‹ค.
  • BCNF(Boyce-Codd)
    • ๋ชจ๋“  ๊ฒฐ์ •์ž(`X->Y`์—์„œ์˜ X)๋Š” ํ›„๋ณดํ‚ค์–ด์•ผํ•œ๋‹ค.
    • ํ›„๋ณดํ‚ค, ๊ธฐ๋ณธํ‚ค, ์™ธ๋ž˜ํ‚ค ๊ฐ™์€ ์šฉ์–ด๋Š” https://jerryjerryjerry.tistory.com/49์—ฌ๊ธฐ์„œ ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค.
  • ๊ทธ ์ด์ƒ์˜ 4NF, 5NF๋Š” ๊ณ ๊ธ‰ ์ •๊ทœํ˜•์ธ๋ฐ ๋„ˆ๋ฌด ์ž˜๊ฒŒ ์ชผ๊ฐœ์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€์ž‘์šฉ์ด ์กด์žฌํ•œ๋‹ค

์ •๊ทœํ™” ๋‹จ์ ์ด๋ผ๋ฉด relation์ด ๋ถ„๋ฆฌ๋˜๋ฉฐ JOIN์—ฐ์‚ฐ์˜ ํ•„์š”์„ฑ์ด ๋” ๋งŽ์•„์ ธ์„œ ์ฟผ๋ฆฌ ์‘๋‹ต ์‹œ๊ฐ„์ด ๋Š๋ ค์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒŒ ์žˆ๋‹ค.

 

๋ฐ˜์ •๊ทœํ™”๋Š” ์กฐ์ธ์„ ์ค„์ด๋Š” ๊ฑด๋ฐ ๊ทธ๋Ÿฌ๋ฉด ์ •๊ทœํ™”๋ฅผ ๋ฐ˜๋Œ€๋กœ ํ•˜๋Š” ๊ฑฐ๋ผ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฐ›์•„๋“ค์ผ ์ˆ˜ ์žˆ๋‹ค. ์ •๊ทœํ™”๋ฅผ ํ•˜๋ฉด ์ •ํ•ฉ์„ฑ(๋ฐ์ดํ„ฐ๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ์ง€๋ž‘ ์ƒ๊ด€์—†์ด ๋ฐ์ดํ„ฐ๋“ค์˜ ๊ฐ’์ด ์ผ์น˜ํ•˜๋Š” ์ƒํƒœ)๊ณผ ๋ฌด๊ฒฐ์„ฑ์ด ๋ณด์žฅ๋œ๋‹ค. ๋ฐ˜์ •๊ทœํ™”์˜ ๋ชฉ์ ์€ ์˜๋„์ ์œผ๋กœ ์ค‘๋ณต์„ ๋งŒ๋“ค์–ด์„œ ์ฝ๊ธฐ ์„ฑ๋Šฅ์„ ์˜ฌ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฐ˜๋Œ€๋กœ ์ด์ƒํ˜„์ƒ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” `C,U,D`์— ์‚ฌ์šฉ๋˜๋Š” ์ž‘์—…์€ ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง„๋‹ค. DB๋Š” ๋ณด์กฐ๋ฉ”๋ชจ๋ฆฌ(๋””์Šคํฌ)์— ์ €์žฅ๋˜๋Š”๋ฐ, ์ฝ๊ธฐ์„ฑ๋Šฅ์„ ์˜ฌ๋ฆฌ๋ ค๊ณ  ์ ‘๊ทผํšŸ์ˆ˜๋ฅผ ์ค„์ด๋Š” ๋ฐฉ์‹์ด ๋ฐ˜์ •๊ทœํ™”์ด๋‹ค.

# RDBMS์™€ NoSQL(Not Only SQL)์˜ ์ฐจ์ด

Relation์œผ๋กœ ์ด๋ค„์ง„ ์Šคํ‚ค๋งˆ๋กœ ๊ตฌ์„ฑ๋œ RDBMS๋Š” scale-out(์ˆ˜ํ‰ ์Šค์ผ€์ผ ํ™•์žฅ) ์‹œ ๋ฒˆ๊ฑฐ๋กญ๋‹ค.

๋ฐ์ดํ„ฐ๊ฐ€ join์„ ํ†ตํ•ด ํ˜•์„ฑ๋  ๊ฒƒ์ด๊ณ  ๊ทธ๋Ÿฌ๋ฉด ์ˆ˜์ง์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋งŒ๋“ค์–ด์ ธ์žˆ์–ด์„œ ์ƒค๋”ฉํ• ๋•Œ ๊ฐ๊ฐ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ๋ถ™์–ด๋ฒ„๋ฆด ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค. NoSQL์€ ๋…๋ฆฝํ˜• ๊ฐ์ฒด๋กœ ์ €์žฅํ•˜๊ณ  ์žˆ์–ด์„œ ์• ์ดˆ์— ๋‹จ์ผ์„œ๋ฒ„์— ๊ทธ๋Œ€๋กœ ์ƒ์ฃผํ•˜๊ณ  ์žˆ๋‹ค. ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ์™€ ์กฐ์ธ ์—†์ด ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๊ทธ๋ž˜์„œ NoSQL์ด ๋น…๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์— ํšจ๊ณผ์ ์ด๋‹ค. ๋ถ„์‚ฐ ์ฒ˜๋ฆฌ์™€ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ๊ฐ€ ๋ถ„์‚ฐํ˜• ๊ตฌ์กฐ๋กœ ์ธํ•ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ฐ€๋Šฅํ•˜๊ณ  Relation์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜ํ‰ํ™•์žฅ์ด ์‰ฝ๋‹ค. 

๊ทธ๋Œ€์‹  relation์ด ์—†์–ด์„œ ์ผ๊ด€์„ฑ์ด ํ•ญ์ƒ ๋ณด์žฅ๋˜์ง€๋Š” ์•Š์•„ ์ฃผ์˜ํ•ด์•ผ๋˜๊ณ  ์กฐ์ธ์„ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ๊ฐ ํ…Œ์ด๋ธ”์„ ์ผ๋‹จ ๊ฐ€์ ธ์™€์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํ•ฉ์ณ์•ผํ•œ๋‹ค.

  1. ์ƒค๋”ฉ(Sharding) : ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ ์„ธํŠธ๋ฅผ ๋‹ค์ˆ˜์˜ DB์— ๋ถ„์‚ฐ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•. ์ฃผ๋กœ ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ ๋‹จ์ผ DB์— ์ €์žฅํ•˜๊ธฐ์—๋Š” ๋„ˆ๋ฌด ํด ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค
  2. ํŒŒํ‹ฐ์…”๋‹ : ๋…ผ๋ฆฌ์ ์ธ ๋ฐ์ดํ„ฐ element ๋“ค์„ ๋‹ค์ˆ˜์˜ entity๋กœ ์ชผ๊ฐœ๋Š” ํ–‰์œ„๋ฅผ ๋œปํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์šฉ์–ด ์ฆ‰ ํฐ table์ด๋‚˜ index๋ฅผ, ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด partition์ด๋ผ๋Š” ์ž‘์€ ๋‹จ์œ„๋กœ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค

# ํŠธ๋žœ์žญ์…˜

ํŠธ๋žœ์žญ์…˜์€ ๋…ผ๋ฆฌ์ ์ธ ์ž‘์—…๋‹จ์œ„๋กœ Commitํ•˜๊ฑฐ๋‚˜ Rollbackํ•ด์„œ ์‹คํ–‰์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค. ๋กค๋ฐฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒŒ ์žฅ์ ์ด๋‹ค. ๋ถ€์ •ํ•ฉ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋กค๋ฐฑ์‹œ์ผœ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ACID๋ผ๋Š” ์„ฑ์งˆ์ด ์žˆ๋‹ค.

  • `Atomicity`(์›์ž์„ฑ) - Commit or Rollback
    • ํŠธ๋žœ์žญ์…˜์˜ ์—ฐ์‚ฐ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ชจ๋‘ ๋ฐ˜์˜๋˜๋“ ์ง€ ์•„๋‹ˆ๋ฉด ์ „ํ˜€ ๋ฐ˜์˜๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
    • ํŠธ๋žœ์žญ์…˜ ๋‚ด์˜ ๋ชจ๋“  ๋ช…๋ น์€ ๋ฐ˜๋“œ์‹œ ์™„๋ฒฝํžˆ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๋ฉฐ, ๋ชจ๋‘๊ฐ€ ์™„๋ฒฝํžˆ ์ˆ˜ ํ–‰๋˜์ง€ ์•Š๊ณ  ์–ด๋Šํ•˜๋‚˜๋ผ๋„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒํƒœ๋ฅผ ํŠธ๋žœ์žญ์…˜ ์ž‘์—… ์ด์ „์œผ๋กœ ๋˜๋Œ๋ ค์„œ ์›์ž์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.
  • `Consistency`(์ผ๊ด€์„ฑ)
    • ํŠธ๋žœ์žญ์…˜ ์ˆ˜ํ–‰ ์ „๊ณผ, ์ˆ˜ํ–‰ ์™„๋ฃŒ ํ›„์˜ ์ƒํƒœ๊ฐ€ ๊ฐ™์•„์•ผ ํ•œ๋‹ค.
  • `Isolation`(๋…๋ฆฝ์„ฑ, ๊ฒฉ๋ฆฌ์„ฑ)
    • ๋‘˜ ์ด์ƒ์˜ ํŠธ๋žœ์žญ์…˜์ด ๋™์‹œ์— ๋ณ‘ํ–‰ ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ ์–ด๋Š ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰์ค‘์— ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ์—ฐ์‚ฐ์ด ๋ผ์–ด๋“ค ์ˆ˜ ์—†๋‹ค.
    • ์ˆ˜ํ–‰์ค‘์ธ ํŠธ๋žœ์žญ์…˜์€ ์™„์ „ํžˆ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค.
    • ๊ฒฉ๋ฆฌ์„ฑ์€ ์ฝ๊ธฐ ์ผ๊ด€์„ฑ๊ณผ ๋™์‹œ์„ฑ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์„ฑ์งˆ
  • `Durability`(์˜์†์„ฑ, ์ง€์†์„ฑ)
    • ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ํŠธ๋žœ์žญ์…˜์˜ ๊ฒฐ๊ณผ๋Š” ์‹œ์Šคํ…œ์ด ๊ณ ์žฅ๋‚˜๋”๋ผ๋„ ์˜๊ตฌ์ ์œผ๋กœ ๋ฐ˜์˜๋˜์–ด์•ผ ํ•œ๋‹ค.

ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ Level์ด๋ผ๋Š” ๊ฒŒ ์กด์žฌํ•œ๋‹ค. ์ด๊ฒƒ์— ๋”ฐ๋ผ ์ฝ๊ธฐ ์ผ๊ด€์„ฑ์ด ๋‹ฌ๋ผ์ง€๊ธฐ๋•Œ๋ฌธ์— ์ค‘์š”ํ•œ ๊ฐœ๋…์ด๋‹ค.

์œ„์—์„œ ๋ถ€ํ„ฐ ๋ ˆ๋ฒจ 0~3์ด๊ณ  ๋ ˆ๋ฒจ 2์ธ Repeatable Read๊ฐ€ MySQL InnoDB์˜ ๊ธฐ๋ณธ isolation level์ด๋‹ค.

๋ ˆ๋ฒจ์„ ๋„ˆ๋ฌด ๋‚ฎ๊ฒŒ ์žก์œผ๋ฉด ์ฝ๊ธฐ ์ผ๊ด€์„ฑ์„ ์ œ๋Œ€๋กœ ๋ณด์žฅํ•  ์ˆ˜ ์—†๊ณ , ๋„ˆ๋ฌด ๋†’๊ฒŒ ์žก์œผ๋ฉด ๋™์‹œ์„ฑ ํƒ“์— ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์†๋„๊ฐ€ ๋Š๋ ค์ ธ์„œ ์ ๋‹นํ•œ ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

  • ๋ ˆ๋ฒจ 0์ธ Read Uncommitted ๋Š” ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ ˆ๋ฒจ 1์ธ Read Committed ๋Š” ์ปค๋ฐ‹๋œ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ ˆ๋ฒจ 2์ธ Repeatable Read ๋Š” ์„ ํ–‰ ํŠธ๋žœ์žญ์…˜์ด ์ฝ์€ ๋ฐ์ดํ„ฐ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ๊ฐ€์ง€ ํ›„ํ–‰ ํŠธ๋žœ์žญ์…˜์ด ๊ฐฑ์‹ ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์€ ๋ถˆํ—ˆํ•จ์œผ๋กœ์จ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‘ ๋ฒˆ ์ฟผ๋ฆฌํ–ˆ์„ ๋•Œ ์ผ๊ด€์„ฑ ์žˆ๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.
  • ๋ ˆ๋ฒจ 3์ธ Serializable Read ๋Š” ์„ ํ–‰ ํŠธ๋žœ์žญ์…˜์ด ์ฝ์€ ๋ฐ์ดํ„ฐ๋ฅผ ํ›„ํ–‰ ํŠธ๋žœ์žญ์…˜์ด ๊ฐฑ์‹ ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜์ง€ ๋ชปํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ค‘๊ฐ„์— ์ƒˆ๋กœ์šด ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ๋„ ๋ง‰์•„์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์™„๋ฒฝํ•˜๊ฒŒ ์ฝ๊ธฐ ์ผ๊ด€์„ฑ ๋ชจ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๋‹จ, ๋™์‹œ์„ฑ์— ๋Œ€ํ•œ ์„ฑ๋Šฅ์€ ๋งค์šฐ ๋–จ์–ด์ง„๋‹ค.

# ๋™์‹œ์„ฑ ์ œ์–ด - ์ง๋ ฌ์„ฑ์„ ์ง€ํ‚ค๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ํ•„์ˆ˜ ์ž‘์—…

Locking, Timestamp, Validation์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.

  • `Locking`
    • ํŠธ๋žœ์žญ์…˜์ด ๋ฐ์ดํ„ฐ์— lock์„ ๊ฑธ๋ฉด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์€ unlock ์ „๊นŒ์ง€ ์ด ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.
    • ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋ง์€ ๊ต์ฐฉ์ƒํƒœ๋ž‘ ๊ธฐ์•„์ƒํƒœ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜์ด ์žˆ๋‹ค๋Š” ๋ง์ด ๋œ๋‹ค.
  • `Timestamp`
    • ๋จผ์ € ๋“ค์–ด์˜จ ํŠธ๋ž™์žญ์…˜์ด ํ•ญ์ƒ ๋” ๋นจ๋ฆฌ ์ˆ˜ํ–‰๋œ๋‹ค. ๋Šฆ์€ ๊ฒƒ ๋ถ€ํ„ฐ ์ฒ˜๋ฆฌํ•˜๋Š” ์Šค์ผ€์ค„๋ง ๋ฐฉ์‹๊ณผ ๋น„์Šทํ•˜๋‹ค.
  • `Validation`
    • ๋ฉ”๋ชจ๋ฆฌ์ƒ์˜ ๋ณต์‚ฌ๋ณธ์—์„œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๊ฒ€์ฆ์™„๋ฃŒ์‹œ DB์— ๋ฐ˜์˜ํ•œ๋‹ค. ์ฝ๊ธฐ-๊ฒ€์ฆ-์“ฐ๊ธฐ 3๋‹จ๊ณ„๋กœ ์ด๋ค„์ ธ์žˆ๋‹ค.
    • ์ฝ๊ธฐ๋Š” ๋ณต์‚ฌ๋ณธ์„ ๋”ฐ๋กœ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.
    • ๊ฒ€์ฆ๋‹จ๊ณ„์—์„œ๋Š” ํ•ด๋‹น ํŠธ๋žœ์žญ์…˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋™์•ˆ ์ง๋ ฌํ™”๊ฐ€ ์ง€์ผœ์กŒ๋Š”์ง€ ๊ฒ€์ฆํ•œ๋‹ค.
    • ์œ ํšจํ•˜๋‹ค๋ฉด ์—…๋ฐ์ดํŠธ ๋œ ๋ถ€๋ถ„๋“ค์„ DB์— ์ ์šฉํ•œ๋‹ค.

DB ์ธ๋ฑ์‹ฑ ๊ณต๋ถ€๋Š” ๋‚˜์ค‘์— ์ •๋ฆฌํ•ด์„œ ์˜ฌ๋ฆฌ๊ฒ ๋‹ค. ์•„๋ž˜๋Š” ๊ณต๋ถ€ํ•˜๊ณ  ์žˆ๋Š” ์ฐธ๊ณ ๋งํฌ

https://github.com/NKLCWDT/cs/blob/main/Database/Index%2C%20Hint.md

 

cs/Database/Index, Hint.md at main · NKLCWDT/cs

๐ŸŒˆ๊ธฐ์ˆ  ๋ฉด์ ‘ ๋Œ€๋น„ ๋ฐ ์ง€์‹ ํ•จ์–‘์„ ์œ„ํ•œ Repo ์ž…๋‹ˆ๋‹ค. Contribute to NKLCWDT/cs development by creating an account on GitHub.

github.com

 

 

 

 

 

 


::์ถœ์ฒ˜::

https://github.com/VSFe/Tech-Interview?tab=readme-ov-file

https://github.com/WooVictory/Ready-For-Tech-Interview

https://github.com/gyoogle/tech-interview-for-developer

https://github.com/JaeYeopHan/Interview_Question_for_Beginner

๋„์›€์ด ๋๋‹ค๋ฉด ๋Œ“๊ธ€์ด๋‚˜ ๊ณต๊ฐ ๋ฒ„ํŠผ ํ•œ ๋ฒˆ์”ฉ ๋ˆ„๋ฅด๊ณ  ๊ฐ€์ฃผ์„ธ์š”! ๋กœ๊ทธ์ธ ์•ˆํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค ^_^

 

๋ฐ˜์‘ํ˜•

'CS๐Ÿ–ฅ๏ธ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๊ธฐํƒ€ CS  (0) 2024.07.02
COMMENT