ìë°ì€í¬ëŠœížìì ëìì± ì°ì ìì íì 구í곌 íì©ë²ì ìì볎ìžì. ë³µì¡í ë¹ëêž° ìì ìì ì€ë ëì ìì í ì°ì ìì êŽëŠ¬ë¥Œ 볎ì¥í©ëë€.
ìë°ì€í¬ëŠœíž ëìì± ì°ì ìì í: ì€ë ë ìì í ì°ì ìì êŽëЬ
íë ìë°ì€í¬ëŠœíž ê°ë°, í¹í Node.jsë ì¹ ì컀ì ê°ì í겜ììë ëìì± ìì ì íšìšì ìŒë¡ êŽëЬíë ê²ìŽ ë§€ì° ì€ìí©ëë€. ì°ì ìì íë í ë¹ë ì°ì ììì ë°ëŒ ìì ì ì²ëЬí ì ìê² íŽì£Œë ì ì©í ìë£ êµ¬ì¡°ì ëë€. ëìì± í겜ì ë€ë£° ë, ìŽë¬í ì°ì ìì êŽëŠ¬ê° ì€ë ëì ìì íëë¡ ë³Žì¥íë ê²ìŽ ë¬Žìë³Žë€ ì€ìí©ëë€. ìŽ ëžë¡ê·ž í¬ì€ížììë ìë°ì€í¬ëŠœížì ëìì± ì°ì ìì íì ê°ë ì ê¹ìŽ íê³ ë€ìŽ, ê·ž 구í, ì¥ì ë° ì¬ì© ì¬ë¡ë¥Œ íìí ê²ì ëë€. 볎ì¥ë ì°ì ììë¡ ë¹ëêž° ìì ì ì²ëЬí ì ìë ì€ë ë ìì í ì°ì ìì í륌 구ì¶íë ë°©ë²ì ìŽíŽë³Žê² ìµëë€.
ì°ì ìì íë 묎ììžê°?
ì°ì ìì íë ìŒë°ì ìž íë ì€í곌 ì ì¬í ì¶ì ë°ìŽí° íì ìŽì§ë§, í ê°ì§ ì¶ê°ì ìž í¹ì§ìŽ ììµëë€: íì ê° ììë ì°ì ìì륌 ê°ì§ëë€. ìì륌 ëí(dequeue)í ë, ê°ì¥ ëì ì°ì ìì륌 ê°ì§ ììê° ëšŒì ì ê±°ë©ëë€. ìŽë ìŒë°ì ìž í(FIFO - ì ì ì ì¶)ë ì€í(LIFO - íì ì ì¶)곌ë ë€ëŠ ëë€.
ë³ì ìêžì€ì ìê°íŽë³Žìžì. íìë€ì ëì°©í ììëë¡ ì¹ë£ë°ì§ ìê³ , ëì°© ìê°ê³Œ êŽê³ììŽ ê°ì¥ ìêží íìê° ëšŒì ì§ë£ë¥Œ ë°ìµëë€. ì¬êž°ì 'ìêžì±'ìŽ ë°ë¡ ì°ì ììì ëë€.
ì°ì ìì íì 죌ì í¹ì§:
- ì°ì ìì í ë¹: ê° ììì ì°ì ììê° í ë¹ë©ëë€.
- ììì ë°ë¥ž ëí: ììë ì°ì ììì ë°ëŒ (ê°ì¥ ëì ì°ì ììë¶í°) ëíë©ëë€.
- ëì ì¡°ì : ìŒë¶ 구íììë íì ì¶ê°ë í ììì ì°ì ìì륌 ë³ê²œí ì ììµëë€.
ì°ì ìì íê° ì ì©í ìëëŠ¬ì€ ìì:
- ìì ì€ìŒì€ë§: ìŽì 첎ì ìì ì€ìëë ꞎêžì±ì ë°ëŒ ìì ì ì°ì ìì륌 ì í©ëë€.
- ìŽë²€íž ì²ëЬ: GUI ì í늬ìŒìŽì ìì ë ì€ìí ìŽë²€ížë³Žë€ ì€ìí ìŽë²€ížë¥Œ 뚌ì ì²ëЬíì¬ ìŽë²€ížë¥Œ êŽëЬí©ëë€.
- ëŒì°í ìê³ ëŠ¬ìŠ: ë€ížìí¬ìì ìµëš 겜ë¡ë¥Œ ì°Ÿì ë ë¹ì©ìŽë 거늬ì ë°ëŒ 겜ë¡ì ì°ì ìì륌 ì í©ëë€.
- ì뮬ë ìŽì : í¹ì ìŽë²€ížê° ë€ë¥ž ìŽë²€ížë³Žë€ ëì ì°ì ìì륌 ê°ë ì€ì ìí©ì ì뮬ë ìŽì í©ëë€(ì: ë¹ì ëì ì뮬ë ìŽì ).
- ì¹ ìë² ìì² ì²ëЬ: ì¬ì©ì ì í(ì: ì ë£ êµ¬ë ì vs. ë¬Žë£ ì¬ì©ì)ìŽë ìì² ì í(ì: ì€ìí ìì€í ì ë°ìŽíž vs. 백귞ëŒìŽë ë°ìŽí° ëêž°í)ì ë°ëŒ API ìì²ì ì°ì ìì륌 ì í©ëë€.
ëìì±ì 곌ì
ìë°ì€í¬ëŠœížë 볞ì§ì ìŒë¡ ëšìŒ ì€ë ëì ëë€. ìŠ, í ë²ì íëì ìì ë§ ì€íí ì ììµëë€. íì§ë§ Promise, async/await, ì¹ ì컀 ë±ì íµí ìë°ì€í¬ëŠœížì ë¹ëêž° êž°ë¥ ëë¶ì ëìì±ì ì뮬ë ìŽì íê³ ì¬ë¬ ìì ì ëìì ìííë ê²ì²ëŒ 볎ìŽê² í ì ììµëë€.
묞ì ì : 겜ì ìí(Race Conditions)
ì¬ë¬ ì€ë ëë ë¹ëêž° ìì ìŽ ê³µì ë°ìŽí°(ìŽ ê²œì°, ì°ì ìì í)ì ëìì ì ê·Œíê³ ìì íë €ê³ í ë 겜ì ìíê° ë°ìí ì ììµëë€. 겜ì ìíë ì€í ê²°ê³Œê° ìì ìŽ ì€íëë ììž¡ ë¶ê°ë¥í ììì ë°ëŒ ë¬ëŒì§ ë ë°ìí©ëë€. ìŽë ë°ìŽí° ìì, ë¶ì íí 결곌 ë° ììž¡ ë¶ê°ë¥í ëììŒë¡ ìŽìŽì§ ì ììµëë€.
ì륌 ë€ìŽ, ë ê°ì ì€ë ëê° ëìì ê°ì ì°ì ìì íìì ìì륌 ëííë €ê³ íë€ê³ ììíŽë³Žìžì. ë§ìœ ë ì€ë ëê° íì ìí륌 ì ë°ìŽížíêž° ì ì 몚ë íì ìí륌 ìœëë€ë©Ž, ë ì€ë ë 몚ë ëìŒí ìì륌 ê°ì¥ ëì ì°ì ììë¡ ìë³í ì ììµëë€. ìŽë¡ ìžíŽ íëì ììë 걎ëë°ê±°ë ì¬ë¬ ë² ì²ëЬëë ë°ë©Ž, ë€ë¥ž ììë ì í ì²ëЬëì§ ìì ì ììµëë€.
ì€ë ë ìì ì±(Thread Safety)ìŽ ì€ìí ìŽì
ì€ë ë ìì ì±ì ì¬ë¬ ì€ë ëê° ëìì ë°ìŽí° 구조ë ìœë ëžë¡ì ì ê·Œíê³ ìì íëëŒë ë°ìŽí° ìììŽë ìŒêŽì± ìë 결곌륌 ìŒìŒí€ì§ ìëë¡ ë³Žì¥í©ëë€. ì°ì ìì íì ë§¥ëœìì ì€ë ë ìì ì±ì ì¬ë¬ ì€ë ëê° ëìì íì ì ê·Œí ëìë ììë€ìŽ ì°ì ìì륌 졎ì€íë©° ì¬ë°ë¥ž ììë¡ ìží(enqueue)ëê³ ëí(dequeue)ëëë¡ ë³Žì¥í©ëë€.
ìë°ì€í¬ëŠœížìì ëìì± ì°ì ìì í 구ííêž°
ìë°ì€í¬ëŠœížìì ì€ë ë ìì í ì°ì ìì í륌 구ì¶íë €ë©Ž ì ì¬ì ìž ê²œì ìí륌 íŽê²°íŽìŒ í©ëë€. ìŽë¥Œ ìíŽ ë€ì곌 ê°ì ë€ìí êž°ì ì ì¬ì©í ì ììµëë€:
- ì êž(뮀í ì€): ìœëì ìê³ êµ¬ì(critical section)ì 볎ížíêž° ìíŽ ì êžì ì¬ì©íì¬ í ë²ì íëì ì€ë ëë§ íì ì ê·Œíëë¡ ë³Žì¥í©ëë€.
- ììì ì°ì°: ê°ëší ë°ìŽí° ìì ì ìíŽ ììì ì°ì°ì ì¬ì©íì¬ íŽë¹ ì°ì°ìŽ ë¶ëЬë ì ìê³ ì€ëšëì§ ìëë¡ ë³Žì¥í©ëë€.
- ë¶ë³ ë°ìŽí° 구조: ì볞 ë°ìŽí°ë¥Œ ìì íë ëì ìë¡ìŽ ë³µì¬ë³žì ìì±íë ë¶ë³ ë°ìŽí° 구조륌 ì¬ì©í©ëë€. ìŽë ì êžì íìì±ì íŒí ì ìì§ë§, ë¹ë²í ì ë°ìŽížê° ìë í° íììë íšìšìŽ ëšìŽì§ ì ììµëë€.
- ë©ìì§ ì ë¬: ì€ë ë ê°ì ë©ìì§ë¥Œ ì¬ì©íì¬ íµì íšìŒë¡ìš ì§ì ì ìž ê³µì ë©ëªšëЬ ì ê·Œì íŒíê³ ê²œì ìíì ìíì ì€ì ëë€.
뮀í ì€(ì êž)륌 ì¬ì©í 구í ìì
ìŽ ìì ë 뮀í ì€(ìíž ë°°ì ì êž)륌 ì¬ì©íì¬ ì°ì ìì íì ìê³ êµ¬ìì 볎ížíë Ʞ볞 구íì 볎ì¬ì€ëë€. ì€ì í겜ììë ë ê°ë ¥í ì€ë¥ ì²ëЬì ìµì íê° íìí ì ììµëë€.
뚌ì , ê°ëší `Mutex` íŽëì€ë¥Œ ì ìíŽ ë³Žê² ìµëë€:
class Mutex {
constructor() {
this.locked = false;
this.queue = [];
}
lock() {
return new Promise((resolve) => {
if (!this.locked) {
this.locked = true;
resolve();
} else {
this.queue.push(resolve);
}
});
}
unlock() {
if (this.queue.length > 0) {
const nextResolve = this.queue.shift();
nextResolve();
} else {
this.locked = false;
}
}
}
ìŽì , `ConcurrentPriorityQueue` íŽëì€ë¥Œ 구ííŽ ë³Žê² ìµëë€:
class ConcurrentPriorityQueue {
constructor() {
this.queue = [];
this.mutex = new Mutex();
}
async enqueue(element, priority) {
await this.mutex.lock();
try {
this.queue.push({ element, priority });
this.queue.sort((a, b) => b.priority - a.priority); // ëì ì°ì ììê° ëšŒì
} finally {
this.mutex.unlock();
}
}
async dequeue() {
await this.mutex.lock();
try {
if (this.queue.length === 0) {
return null; // ëë ì€ë¥ ë°ì
}
return this.queue.shift().element;
} finally {
this.mutex.unlock();
}
}
async peek() {
await this.mutex.lock();
try {
if (this.queue.length === 0) {
return null; // ëë ì€ë¥ ë°ì
}
return this.queue[0].element;
} finally {
this.mutex.unlock();
}
}
async isEmpty() {
await this.mutex.lock();
try {
return this.queue.length === 0;
} finally {
this.mutex.unlock();
}
}
async size() {
await this.mutex.lock();
try {
return this.queue.length;
} finally {
this.mutex.unlock();
}
}
}
ì€ëª :
- `Mutex` íŽëì€ë ê°ëší ìíž ë°°ì ì êžì ì ê³µí©ëë€. `lock()` ë©ìëë ì êžì íëíë©°, ìŽë¯ž ì 겚ììŒë©Ž ëêž°í©ëë€. `unlock()` ë©ìëë ì êžì íŽì íì¬ ë€ë¥ž ëêž° ì€ìž ì€ë ëê° ì êžì íëí ì ìëë¡ í©ëë€.
- `ConcurrentPriorityQueue` íŽëì€ë `Mutex`륌 ì¬ì©íì¬ `enqueue()` ë° `dequeue()` ë©ìë륌 볎íží©ëë€.
- `enqueue()` ë©ìëë ì°ì ììì íšê» ìì륌 íì ì¶ê°í ë€ì, ì°ì ìì ìì(ê°ì¥ ëì ì°ì ììê° ëšŒì )륌 ì ì§íêž° ìíŽ í륌 ì ë ¬í©ëë€.
- `dequeue()` ë©ìëë ê°ì¥ ëì ì°ì ìì륌 ê°ì§ ìì륌 ì ê±°íê³ ë°íí©ëë€.
- `peek()` ë©ìëë ê°ì¥ ëì ì°ì ìì륌 ê°ì§ ìì륌 ì ê±°íì§ ìê³ ë°íí©ëë€.
- `isEmpty()` ë©ìëë íê° ë¹ìŽ ìëì§ íìží©ëë€.
- `size()` ë©ìëë íì ìë ììì ì륌 ë°íí©ëë€.
- ê° ë©ìëì `finally` ëžë¡ì ì€ë¥ê° ë°ìíëëŒë 뮀í ì€ê° íì ì êž íŽì ëëë¡ ë³Žì¥í©ëë€.
ì¬ì© ìì :
async function testPriorityQueue() {
const queue = new ConcurrentPriorityQueue();
// ëì ìží ìì
ì뮬ë ìŽì
await Promise.all([
queue.enqueue("Task C", 3),
queue.enqueue("Task A", 1),
queue.enqueue("Task B", 2),
]);
console.log("Queue size:", await queue.size()); // ì¶ë ¥: Queue size: 3
console.log("Dequeued:", await queue.dequeue()); // ì¶ë ¥: Dequeued: Task C
console.log("Dequeued:", await queue.dequeue()); // ì¶ë ¥: Dequeued: Task B
console.log("Dequeued:", await queue.dequeue()); // ì¶ë ¥: Dequeued: Task A
console.log("Queue is empty:", await queue.isEmpty()); // ì¶ë ¥: Queue is empty: true
}
testPriorityQueue();
íë¡ëì í겜 ê³ ë €ì¬í
ìì ìì ë Ʞ볞ì ìž í ë륌 ì ê³µí©ëë€. íë¡ëì í겜ììë ë€ì ì¬íì ê³ ë €íŽìŒ í©ëë€:
- ì€ë¥ ì²ëЬ: ììžë¥Œ ì ìì ìŒë¡ ì²ëЬíê³ ìêž°ì¹ ìì ëìì ë°©ì§íêž° ìíŽ ê°ë ¥í ì€ë¥ ì²ëЬ êž°ë¥ì 구íí©ëë€.
- ì±ë¥ ìµì í: `enqueue()`ììì ì ë ¬ ìì ì í° íìì ë³ëª© íìì ìŒìŒí¬ ì ììµëë€. ë ëì ì±ë¥ì ìíŽ ìŽì§ í곌 ê°ì ë íšìšì ìž ìë£ êµ¬ì¡°ë¥Œ ì¬ì©íë ê²ì ê³ ë €íìžì.
- íì¥ì±: ëìì±ìŽ ë§€ì° ëì ì í늬ìŒìŽì ì 겜ì°, íì¥ì±ê³Œ ëŽê²°íšì±ì ìíŽ ì€ê³ë ë¶ì° ì°ì ìì í 구íìŽë ë©ìì§ í륌 ì¬ì©íë ê²ì ê³ ë €íìžì. Redisë RabbitMQì ê°ì êž°ì ì ìŽë¬í ìë늬ì€ì ì¬ì©í ì ììµëë€.
- í ì€íž: ì°ì ìì í 구íì ì€ë ë ìì ì±ê³Œ ì íì±ì 볎ì¥íêž° ìíŽ ì² ì í ëšì í ì€ížë¥Œ ìì±í©ëë€. ëìì± í ì€íž ë구륌 ì¬ì©íì¬ ì¬ë¬ ì€ë ëê° ëìì íì ì ê·Œíë ìí©ì ì뮬ë ìŽì íê³ ì ì¬ì ìž ê²œì ìí륌 ìë³í©ëë€.
- 몚ëí°ë§: ìží/ëí ì§ì° ìê°, í í¬êž°, ì êž ê²œí©ê³Œ ê°ì ì§í륌 í¬íšíì¬ íë¡ëì í겜ìì ì°ì ìì íì ì±ë¥ì 몚ëí°ë§í©ëë€. ìŽë ì±ë¥ ë³ëª© íììŽë íì¥ì± 묞ì 륌 ìë³íê³ íŽê²°íë ë° ëììŽ ë©ëë€.
ë첎 구í ë° ëŒìŽëžë¬ëЬ
ìì ë§ì ëìì± ì°ì ìì í륌 구íí ìë ìì§ë§, ì¬ë¬ ëŒìŽëžë¬ëŠ¬ê° ë¯žëŠ¬ ë§ë€ìŽì§ê³ ìµì íëììŒë©° í ì€ížë 구íì ì ê³µí©ëë€. ì êŽëЬëë ëŒìŽëžë¬ëŠ¬ë¥Œ ì¬ì©í멎 ìê°ê³Œ ë žë ¥ì ì ìœíê³ ë²ê·ž ë°ì ìíì ì€ìŒ ì ììµëë€.
- async-priority-queue: ìŽ ëŒìŽëžë¬ëЬë ë¹ëêž° ìì ì ìíŽ ì€ê³ë ì°ì ìì í륌 ì ê³µí©ëë€. 볞ì§ì ìŒë¡ ì€ë ëì ìì íì§ë ìì§ë§, ë¹ëêž°ì±ìŽ íìí ëšìŒ ì€ë ë í겜ìì ì¬ì©í ì ììµëë€.
- js-priority-queue: ìŽê²ì ì°ì ìì íì ìì ìë°ì€í¬ëŠœíž êµ¬íì ëë€. ì§ì ì ìŒë¡ ì€ë ëì ìì íì§ë ìì§ë§, ì€ë ë ìì ëíŒë¥Œ 구ì¶íë êž°ë°ìŒë¡ ì¬ì©í ì ììµëë€.
ëŒìŽëžë¬ëŠ¬ë¥Œ ì íí ëë ë€ì ìì륌 ê³ ë €íìžì:
- ì±ë¥: í¹í í° íì ëì ëìì±ì ëí ëŒìŽëžë¬ëЬì ì±ë¥ í¹ì±ì íê°í©ëë€.
- êž°ë¥: ì°ì ìì ì ë°ìŽíž, ì¬ì©ì ì ì ë¹êµì, í¬êž° ì í곌 ê°ìŽ íìí êž°ë¥ì ëŒìŽëžë¬ëŠ¬ê° ì ê³µíëì§ íê°í©ëë€.
- ì ì§ë³Žì: íë°íê² ì ì§ë³Žìëê³ ê±Žê°í 컀뮀ëí°ë¥Œ ê°ì§ ëŒìŽëžë¬ëŠ¬ë¥Œ ì íí©ëë€.
- ì졎ì±: ëŒìŽëžë¬ëЬì ì졎ì±ê³Œ íë¡ì ížì ë²ë€ í¬êž°ì ë¯žì¹ ì ì¬ì ìí¥ì ê³ ë €í©ëë€.
êžë¡ë² 컚í ì€ížììì ì¬ì© ì¬ë¡
ëìì± ì°ì ìì íì ëí íìì±ì ë€ìí ì°ì 곌 ì§ìì ê±žì³ ììµëë€. ë€ìì ëª ê°ì§ êžë¡ë² ììì ëë€:
- ì ììê±°ë: êžë¡ë² ì ììê±°ë íë«íŒìì ë°°ì¡ ìë(ì: í¹êž ë°°ì¡ vs. ìŒë° ë°°ì¡)ë ê³ ê° ì¶©ì±ë ìì€(ì: íëí°ë íì vs. ìŒë° íì)ì ë°ëŒ ê³ ê° ì£Œë¬žì ì°ì ìì륌 ì í©ëë€. ìŽë¥Œ íµíŽ ê³ ê°ì ìì¹ì ìêŽììŽ ì°ì ììê° ëì ì£Œë¬žìŽ ëšŒì ì²ëЬëê³ ë°°ì¡ëëë¡ ë³Žì¥í©ëë€.
- êžìµ ìë¹ì€: êžë¡ë² êžìµ êž°êŽìì ìí ìì€ìŽë ê·ì ì걎ì ë°ëŒ êžìµ ê±°ë륌 êŽëЬí©ëë€. ê³ ìí ê±°ëë ì²ëЬëêž° ì ì ì¶ê°ì ìž ì¬ì¬ì ì¹ìžìŽ íìí ì ììŒë©°, ìŽë¥Œ íµíŽ êµì ê·ì ì ì€ìíëë¡ ë³Žì¥í©ëë€.
- í¬ì€ìŒìŽ: ì¬ë¬ êµê°ì íììê² ìë¹ì€ë¥Œ ì ê³µíë ì격 ìë£ íë«íŒìì ꞎêžì±ìŽë ì§ë³ ìíì ë°ëŒ íì ììœì ì°ì ìì륌 ì í©ëë€. ìŠììŽ ì¬ê°í íìë ì§ëЬì ìì¹ì êŽê³ììŽ ë 빚늬 ìëŽì ë°ì ì ììµëë€.
- ë¬Œë¥ ë° ê³µêžë§: êžë¡ë² ë¬Œë¥ íì¬ìì ꞎêžì±ê³Œ 거늬ì ë°ëŒ ë°°ì¡ ê²œë¡ë¥Œ ìµì íí©ëë€. ì°ì ììê° ëê±°ë ë§ê° êž°íìŽ ìŽë°í í묌ì ì¬ë¬ êµê°ì êµíµ, ë ìš, íµêŽê³Œ ê°ì ìì륌 ê³ ë €íì¬ ê°ì¥ íšìšì ìž ê²œë¡ë¡ ìŽì¡ë ì ììµëë€.
- íŽëŒì°ë 컎íší : êžë¡ë² íŽëŒì°ë ì ê³µì 첎ìì ì¬ì©ì 구ë ì ë°ëŒ ê°ì ëšžì 늬ìì€ í ë¹ì êŽëЬí©ëë€. ì ë£ ê³ ê°ì ìŒë°ì ìŒë¡ ë¬Žë£ í°ìŽ ì¬ì©ìë³Žë€ ëì 늬ìì€ í ë¹ ì°ì ìì륌 ê°ìµëë€.
ê²°ë¡
ëìì± ì°ì ìì íë ìë°ì€í¬ëŠœížìì 볎ì¥ë ì°ì ììë¡ ë¹ëêž° ìì ì êŽëЬíêž° ìí ê°ë ¥í ë구ì ëë€. ì€ë ë ìì ë©ì»€ëìŠì 구ííšìŒë¡ìš ì¬ë¬ ì€ë ëë ë¹ëêž° ìì ìŽ ëìì íì ì ê·Œí ë ë°ìŽí° ìŒêŽì±ì 볎ì¥íê³ ê²œì ìí륌 ë°©ì§í ì ììµëë€. ìì ë§ì ì°ì ìì í륌 구ííë Ʞ졎 ëŒìŽëžë¬ëŠ¬ë¥Œ íì©íë , ëìì±ê³Œ ì€ë ë ìì ì±ì ì늬륌 ìŽíŽíë ê²ì ê²¬ê³ íê³ íì¥ ê°ë¥í ìë°ì€í¬ëŠœíž ì í늬ìŒìŽì ì 구ì¶íë ë° íìì ì ëë€.
ëìì± ì°ì ìì í륌 ì€ê³íê³ êµ¬íí ëë ì í늬ìŒìŽì ì í¹ì ì구ì¬íì ì ì€íê² ê³ ë €íŽìŒ í©ëë€. ì±ë¥, íì¥ì±, ì ì§ë³Žìì±ìŽ ì£Œì ê³ ë €ì¬íìŽ ëìŽìŒ í©ëë€. ëªšë² ì¬ë¡ë¥Œ ë°ë¥Žê³ ì ì í ë구ì êž°ì ì íì©íšìŒë¡ìš ë³µì¡í ë¹ëêž° ìì ì íšê³Œì ìŒë¡ êŽëЬíê³ , êžë¡ë² ì¬ì©ìì ì구륌 충족íë ì 뢰í ì ìê³ íšìšì ìž ìë°ì€í¬ëŠœíž ì í늬ìŒìŽì ì 구ì¶í ì ììµëë€.
ì¶ê° íìµ ìë£
- ìë°ì€í¬ëŠœížì ìë£ êµ¬ì¡° ë° ìê³ ëŠ¬ìŠ: ì°ì ìì íì íì í¬íší ìë£ êµ¬ì¡° ë° ìê³ ëŠ¬ìŠì êŽí ìì 곌 ìšëŒìž ê°ì¢ë¥Œ íìíŽ ë³Žìžì.
- ìë°ì€í¬ëŠœížì ëìì±ê³Œ ë³ë ¬ì±: ì¹ ì컀, ë¹ëêž° íë¡ê·žëë°, ì€ë ë ìì ì±ì í¬íší ìë°ì€í¬ëŠœížì ëìì± ëªšëžì ëíŽ íìµíŽ ë³Žìžì.
- ìë°ì€í¬ëŠœíž ëŒìŽëžë¬ëЬ ë° íë ììí¬: ë¹ëêž° ìì ë° ëìì± êŽëŠ¬ë¥Œ ìí ì ížëЬí°ë¥Œ ì ê³µíë ìžêž° ìë ìë°ì€í¬ëŠœíž ëŒìŽëžë¬ëЬ ë° íë ììí¬ì ìµìíŽì§ìžì.