bong-u/til

๐Ÿ  home ๐Ÿˆ repository ๐Ÿ“ก rss
new RAG ์ด๋ก  ์ •๋ฆฌ + OpenSearch
๐Ÿค– ์ธ๊ณต์ง€๋Šฅ
RAG (Retrieval-Augmented Generation) RAG๋Š” ๊ฒ€์ƒ‰๊ณผ ์ƒ์„ฑ์„ ๊ฒฐํ•ฉํ•œ ๋ชจ๋ธ๋กœ, ๊ฒ€์ƒ‰์„ ํ†ตํ•ด ์–ป์€ ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ƒ์„ฑ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ๋ธ LLM์˜ ๋ฌธ์ œ์  ํ• ๋ฃจ์‹œ๋„ค์ด์…˜: ์ƒ์„ฑ ๋ชจ๋ธ์ด ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ์— ์—†๋Š” ๋‚ด์šฉ์„ ์ƒ์„ฑํ•˜๋Š” ํ˜„์ƒ ์ตœ์‹ ์˜ ์‘๋‹ต์„ ๊ธฐ๋Œ€ํ•˜๋Š” ์ƒํ™ฉ์—์„œ ์˜ค๋ž˜๋˜์—ˆ๊ฑฐ๋‚˜ ์ผ๋ฐ˜์ ์ธ ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฌธ์ œ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ถœ์ฒ˜๋กœ๋ถ€ํ„ฐ ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฌธ์ œ RAG๋Š” ์œ„์—์„œ ์„œ์ˆ ํ•œ LLM ๋ฌธ์ œ์˜ ์ผ๋ถ€๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์ด๋‹ค. OpenSearch OpenSearch๋Š” ์˜คํ”ˆ์†Œ์Šค ๊ฒ€์ƒ‰ ๋ฐ ๋ถ„์„ ์—”์ง„์œผ๋กœ, ์—˜๋ผ์Šคํ‹ฑ์„œ์น˜์˜ ํฌํฌ ๋ฒ„์ „ ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค : ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์ฟผ๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฃผ์š” ๊ธฐ๋Šฅ ๋ถ„์‚ฐ ๊ฒ€์ƒ‰ ๋ฐ ๋ถ„์„ ๋ณด์•ˆ ์‹œ๊ฐํ™”์™€ ๋Œ€์‹œ๋ณด๋“œ ์ง€์› index์™€ document index : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค document : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋˜๋Š” ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋ถ„์„๊ธฐ Analyzer (Character Filter + Tokenizer + Token Filter) ํ…์ŠคํŠธ๋ฅผ ํ† ํฐํ™”ํ•˜๊ณ  ํ•„ํ„ฐ๋งํ•˜๋Š” ๊ณผ์ •์„ ์ˆ˜ํ–‰ ๋ถ„์„ ๊ณผ์ • Character Filter ํŠน์ • ๋ฌธ์ž๋ฅผ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ Tokenizer ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ณต๋ฐฑ์„ ๊ธฐ์ค€์œผ๋กœ ํ…์ŠคํŠธ๋ฅผ ๋ถ„๋ฆฌ Token Filter ํ† ํฐ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ OpenSearch์—์„œ ์ง€์›ํ•˜๋Š” ์š”์†Œ Tokenizer Standard Tokenizer : ๊ณต๋ฐฑ์„ ๊ธฐ์ค€์œผ๋กœ ํ…์ŠคํŠธ๋ฅผ ๋ถ„๋ฆฌ, ๋ฌธ์žฅ ๋ถ€ํ˜ธ ์‚ญ์ œ Letter Tokenizer : ๋ฌธ์ž๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ…์ŠคํŠธ๋ฅผ ๋ถ„๋ฆฌ Whitespace Tokenizer : ๊ณต๋ฐฑ์„ ๊ธฐ์ค€์œผ๋กœ ํ…์ŠคํŠธ๋ฅผ ๋ถ„๋ฆฌ Ngram Tokenizer : ๋ถ€๋ถ„ ๋ฌธ์ž์—ด๋กœ ํ…์ŠคํŠธ๋ฅผ ๋ถ„๋ฆฌ Token Filter Standard Token Filter : ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š์Œ Lowercase Token Filter : ํ…์ŠคํŠธ๋ฅผ ์†Œ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ Synonym Token Filter : ๋™์˜์–ด ์ฒ˜๋ฆฌ Analyzer Standard Analyzer : Standard Tokenizer + Standard Token Filter Simple Analyzer : Letter Tokenizer + Lowercase Token Filter Whitespace Analyzer : Whitespace Tokenizer + Lowercase Token Filter OpenSearch ์ ‘๊ทผ์„ ์œ„ํ•œ cURL ๋ช…๋ น์–ด ์ธ๋ฑ์Šค ์กฐํšŒ 1curl -X GET -u {username}:{password} \ 2"http://localhost:9200/_cat/indices" ํŠน์ • ์ธ๋ฑ์Šค ์กฐํšŒ 1curl -X GET -u {username}:{password} \ 2"http://localhost:9200/{index_name}" ์ „์ฒด ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์กฐํšŒ 1curl -X GET -u {username}:{password} \ 2"http://localhost:9200/{index_name}/_search" ํŠน์ • ๊ฒ€์ƒ‰์–ด๋กœ ๊ฒ€์ƒ‰ํ•œ ๊ฒฐ๊ณผ ์กฐํšŒ 1curl -X GET -u {username}:{password} \ 2"http://localhost:9200/{index_name}/_search" \ 3-H "Content-Type: application/json" \ 4-d '{"query": {"match": {"field": "value"}}}' ์ธ๋ฑ์Šค ์‚ญ์ œ 1curl -X DELETE -u {username}:{password} \ 2"http://localhost:9200/{index_name}"
new OpenSearch๋ฅผ ํ™œ์šฉํ•œ RAG ์‹ค์Šต
๐Ÿค– ์ธ๊ณต์ง€๋Šฅ
๋ฐฐ๊ฒฝ ํ…Œ์ปค ๋ถ€ํŠธ์บ ํ”„์—์„œ ํŒ€ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ ์ค‘์ด๋‹ค. ์šฐ๋ฆฌ ํŒ€์˜ ์ฃผ์ œ๋Š” ํŠน์ • ์ธ๋ฌผ์—๊ฒŒ ์ƒ๋‹ด์„ ๋ฐ›๋Š” ๊ฒƒ ๊ฐ™์€ ๋Œ€ํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ์ฑ—๋ด‡์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ํŠน์ • ์ธ๋ฌผ์ด ํ–ˆ๋˜ ๋ง์„ ๋ชจ์•„ ๋ฐ์ดํ„ฐ์…‹์œผ๋กœ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ RAG ๋ชจ๋ธ์— ์ ์šฉ์‹œํ‚ค๋ ค๊ณ  ํ•œ๋‹ค. ์ˆœ์„œ ์ผ๋ก  ๋จธ์Šคํฌ๊ฐ€ TED์—์„œ ํ•œ ์ธํ„ฐ๋ทฐ๋ฅผ ํ…์ŠคํŠธ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค. OpenSearch ๋„์ปค ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์ž„๋ฒ ๋”ฉํ•ด์„œ OpenSearch์— ์ €์žฅํ•œ๋‹ค. RAG ๋ชจ๋ธ์ด OpenSearch๋ฅผ ์ฟผ๋ฆฌํ•˜์—ฌ ๋Œ€๋‹ต์„ ์ƒ์„ฑํ•œ๋‹ค. 1. ์ผ๋ก  ๋จธ์Šคํฌ ์ธํ„ฐ๋ทฐ ํ…์ŠคํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ ํŠœ๋ธŒ์—์„œ “์Šคํฌ๋ฆฝํŠธ ๋ณด๊ธฐ"๋ฅผ ํ†ตํ•ด ์ธํ„ฐ๋ทฐ ์ž๋ง‰์„ ๊ฐ€์ ธ์˜จ๋‹ค. 122:03 2EM: ์ด ํฐ ํŠธ๋Ÿญ์„ ๋ชฐ๋ฉด์„œ ๋ง๋„ ์•ˆ๋˜๋Š” ์›€์ง์ž„์„ ๋ณด์˜€์ฃ . 3CA: ์•„์ฃผ ๋ฉ‹์ง€๋„ค์š”. ์ž, ๊ทธ๋Ÿผ ์ •๋ง ๊ต‰์žฅํ•œ ์‚ฌ์ง„์—์„œ 422:09 5์กฐ๊ธˆ์€ ๋œ ๊ต‰์žฅํ•œ ์‚ฌ์ง„์„ ๋ณด์ฃ . "์œ„๊ธฐ์˜ ์ฃผ๋ถ€๋“ค"์ธ๊ฐ€์—์„œ ๋‚˜์˜ค๋Š” ๊ท€์—ฌ์šด ์ง‘ ์‚ฌ์ง„์ธ๋ฐ์š”. 622:15 7์ด๊ฒŒ ๊ฐ‘์ž๊ธฐ ์™œ ๋‚˜์˜จ๊ฑฐ์ฃ ? 8... ์ผ๋ก  ๋จธ์Šคํฌ๊ฐ€ ํ•œ ๋ง๋งŒ ์†์ˆ˜ ์ •๋ฆฌํ•œ๋‹ค. 1๋„ค. ์ œ ์Šค์Šค๋กœ๋„ ๊ทธ ์งˆ๋ฌธ์„ ์ž์ฃผ ํ•˜๋Š” ํŽธ์ž…๋‹ˆ๋‹ค. 2์ €ํฌ๋Š” LA์˜ ์ง€ํ•˜์— ๊ตฌ๋ฉ์„ ๋‚ด๋ ค๊ณ  ํ•˜๋Š”๋ฐ์š”. ์ด๋Š” ๊ตํ†ต ์ฒด์ฆ์„ ์™„ํ™”์‹œํ‚ค๊ธฐ ์œ„ํ•œ 33์ฐจ์› ๋„คํŠธ์›Œํฌ์˜ ํ„ฐ๋„์ด ๋  ์ˆ˜๋„ ์žˆ๋Š” ์‹œ๋ฐœ์ ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค. 4๊ตํ†ต ์ฒด์ฆ์€ ์˜ค๋Š˜๋‚  ์šฐ๋ฆฌ์˜ ์˜ํ˜ผ์„ ํƒˆํƒˆ ํ„ฐ๋Š” ๋ฌธ์ œ ์ค‘์˜ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. 5์„ธ๊ณ„ ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์˜ํ–ฅ์„ ๋ผ์น˜๊ณ  ์žˆ์ฃ . ์ธ์ƒ์—์„œ ๋„ˆ๋ฌด๋„ ๋งŽ์€ ๋ถ€๋ถ„์„ ๊ฐ€์ ธ๊ฐ‘๋‹ˆ๋‹ค. 6... 2. OpenSearch ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ 1docker create -it -p 9200:9200 -p 9600:9600 -e OPENSEARCH_INITIAL_ADMIN_PASSWORD={password} -e "discovery.type=single-node" -v opensearch_vol:/usr/share/opensearch/data --name opensearch opensearchproject/opensearch ์„ค๋ช… -p 9200:9200 : OpenSearch HTTP ํฌํŠธ -p 9600:9600 : OpenSearch ๋ชจ๋‹ˆํ„ฐ๋ง ํฌํŠธ -e OPENSEARCH_INITIAL_ADMIN_PASSWORD={password} : ์ดˆ๊ธฐ ๋น„๋ฐ€๋ฒˆํ˜ธ ์„ค์ • -e “discovery.type=single-node” : ๋‹จ์ผ ๋…ธ๋“œ๋กœ ์‹คํ–‰ -v opensearch_vol:/usr/share/opensearch/data : ๋ฐ์ดํ„ฐ ๋ณผ๋ฅจ ๋งˆ์šดํŠธ SSL ์˜ค๋ฅ˜ ๋ฐœ์ƒ๊ณผ ํ•ด๊ฒฐ ํ•˜์ง€๋งŒ ์œ„ ๋ช…๋ น์–ด๋กœ ์‹คํ–‰ํ•˜๋ฉด ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค 12024-07-05 22:15:12 Caused by: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: ... 22024-07-05 22:15:12 at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1314) ~[netty-handler-4.1.110.Final.jar:4.1.110.Final] 32024-07-05 22:15:12 at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1387) ~[netty-handler-4.1.110.Final.jar:4.1.110.Final] 42024-07-05 22:15:12 at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530) ~[netty-codec-4.1.110.Final.jar:4.1.110.Final] 52024-07-05 22:15:12 at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469) ~[netty-codec-4.1.110.Final.jar:4.1.110.Final] 62024-07-05 22:15:12 ... 16 more ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„์ด ๊ธธ์ง€ ์•Š๊ณ , ํ•ด๋‹น ํฌํŠธ๋Š” ์™ธ๋ถ€์— ๋…ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ SSL์„ ๋„๊ณ  ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํ•ด๊ฒฐํ•˜์˜€๋‹ค. 1/usr/share/opensearch/config/opensearch.yml 2# ๋ณ€๊ฒฝ ์ „ 3plugins.security.ssl.http.enabled: true 4# ๋ณ€๊ฒฝ ํ›„ 5plugins.security.ssl.http.enabled: false 3. ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ ์ž„๋ฒ ๋”ฉ ๋ฐ OpenSearch์— ์ €์žฅ RAG ์„ธ์…˜์„ ํ•ด์ฃผ์‹  ๋ฉ˜ํ† ๋‹˜์ด ์งœ์ค€ ์ฝ”๋“œ๋ฅผ ์ ๊ทน! ์ฐธ๊ณ ํ•˜์—ฌ ์ž‘์„ฑํ•˜์˜€๋‹ค. OpenSearch ์ธ๋ฑ์Šค ์ƒ์„ฑ 1from opensearchpy import OpenSearch 2import torch 3from transformers import AutoTokenizer, AutoModel 4from langchain.text_splitter import RecursiveCharacterTextSplitter 5from langchain_community.document_loaders import TextLoader 6from langchain_community.vectorstores import OpenSearchVectorSearch 7 8INDEX_NAME = "elon_musk" 9FILE_NAME = "ted_elon_musk_script.txt" 10 11## OpenSearch ์—ฐ๊ฒฐ ์„ค์ • 12client = OpenSearch( 13 hosts=[{"host": "localhost", "port": 9200}], http_auth=("admin", {password}) 14) 15 16## ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ 17loader = TextLoader(file_path=FILE_NAME, encoding="utf-8") 18docs = loader.load() 19 20text_splitter = RecursiveCharacterTextSplitter( 21 chunk_size=100, 22 chunk_overlap=0, 23 separators=["\n"], 24 length_function=len, 25) 26 27documents = text_splitter.split_documents(docs) 28 29# print(documents) 30 31## Embedding ๋ชจ๋ธ ์ •์˜ 32class MyEmbeddingModel: 33 def __init__(self, model_name): 34 self.tokenizer = AutoTokenizer.from_pretrained(model_name) 35 self.model = AutoModel.from_pretrained(model_name) 36 37 def embed_documents(self, doc): 38 inputs = self.tokenizer( 39 doc, return_tensors="pt", padding=True, truncation=True, max_length=512 40 ) 41 42 with torch.no_grad(): 43 outputs = self.model(**inputs) 44 embeddings = outputs.last_hidden_state.mean(dim=1).tolist() 45 46 return embeddings 47 48 def embed_query(self, text): 49 inputs = self.tokenizer( 50 [text], padding=True, truncation=True, return_tensors="pt", max_length=512 51 ) 52 with torch.no_grad(): 53 outputs = self.model(**inputs) 54 embeddings = outputs.last_hidden_state.mean(dim=1).tolist() 55 return embeddings 56 57 58## index ๊ตฌ์กฐ ์ •์˜ 59index_body = { 60 "settings": { 61 "analysis": { 62 "tokenizer": { 63 "nori_user_dict": { 64 "type": "nori_tokenizer", 65 "decompound_mode": "mixed", 66 "user_dictionary": "user_dic.txt", 67 } 68 }, 69 "analyzer": { 70 "korean_anlyzer": { 71 "filter": [ 72 "synonym", "lowercase", 73 ], 74 "tokenizer": "nori_user_dict", 75 } 76 }, 77 "filter": { 78 "synonym" :{ 79 "type": "synonym_graph", 80 "synonyms_path" : "synonyms.txt" 81 } 82 } 83 } 84 } 85} 86 87## Embedding ๋ชจ๋ธ ์ƒ์„ฑ 88my_embedding = MyEmbeddingModel("monologg/kobert") 89 90## OpenSearch์— ๋ฐ์ดํ„ฐ ์‚ฝ์ž… 91vector_db = OpenSearchVectorSearch.from_documents( 92 index_name=INDEX_NAME, 93 body=index_body, 94 documents=documents, 95 embedding=my_embedding, 96 op_type="create", 97 opensearch_url="http://localhost:9200", 98 http_auth=("admin", {password}), 99 use_ssl=False, 100 verify_certs=False, 101 ssl_assert_hostname=False, 102 ssl_show_warn=False, 103 bulk_size=1000000, 104 timeout=360000, 105) 106 107result = vector_db.add_documents(documents, bulk_size=1000000) tokenizer๋Š” ํ•œ๊ตญ์–ด๋ฅผ ์ง€์›ํ•˜๋Š” “nori_tokenizer"๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค. embedding ๋ชจ๋ธ์€ ์ €๊ฑฐ ๋ง๊ณ ๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ, ์–ด๋–ค ๋ชจ๋ธ์ด ํ”„๋กœ์ ํŠธ์— ๊ฐ€์žฅ ๋ถ€ํ•ฉํ•˜๋Š” ๋ชจ๋ธ์ธ์ง€๋Š” ์‹คํ—˜์„ ํ•ด๋ณผ ๊ฒƒ์ด๋‹ค. curl์„ ํ†ตํ•ด localhost:9200/elon_musk/_search๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด ์ž„๋ฒ ๋”ฉํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž˜ ๋“ค์–ด๊ฐ”๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 4. RAG ๋ชจ๋ธ์ด OpenSearch๋ฅผ ์ฟผ๋ฆฌํ•˜์—ฌ ๋Œ€๋‹ต ์ƒ์„ฑ 1from langchain.prompts import PromptTemplate 2from langchain.chains import LLMChain 3from langchain_openai import ChatOpenAI 4from opensearchpy import OpenSearch 5import os 6 7INDEX_NAME = "elon_musk" 8 9# ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ • 10os.environ["OPENAI_API_KEY"] = {api_key} 11 12llm = ChatOpenAI( 13 model_name="gpt-3.5-turbo", 14) 15 16prompt_template = PromptTemplate( 17 input_variables=["context", "question"], 18 template=""" 19Imagine you are {character_name}, 20a wise and experienced advisor. Given the context: "{context}", 21how would you respond to this inquiry: "{question}"?', 22(in korean) 23""", 24) 25 26 27llm_chain = LLMChain(llm=llm, prompt=prompt_template) 28 29client = OpenSearch( 30 hosts=["http://localhost:9200"], 31 http_auth=("admin", {password}), 32 use_ssl=False, 33 verify_certs=False, 34 ssl_assert_hostname=False, 35 ssl_show_warn=False, 36) 37 38def search_documents(query): 39 search_body = {"query": {"match": {"text": query}}} 40 response = client.search(index=INDEX_NAME, body=search_body) 41 hits = response["`its"]["hits"] 42 return [hit["_source"]["text"] for hit in hits] 43 44if __name__ == "__main__": 45 question = input("Enter your question\n") 46 search_results = search_documents(question) 47 48 print(search_results) 49 50 # context = " ".join(search_results) 51 context = "" 52 53 response = llm_chain.invoke({"character_name": INDEX_NAME, "context": context, "question": question}) 54 55 print (response["text"]) OpenSearch์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฟผ๋ฆฌํ•˜์—ฌ RAG ๋ชจ๋ธ์— ๋„ฃ์–ด ๋Œ€๋‹ต์„ ์ƒ์„ฑํ•œ๋‹ค. search_documents ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด OpenSearch์— ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ด๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ context๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ๊ฒฐ๊ณผ ์งˆ๋ฌธ ํ…Œ์Šฌ๋ผ์— ๋Œ€ํ•ด์„œ ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•ด? RAG๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์„ ๋•Œ์˜ ๋Œ€๋‹ต ํ…Œ์Šฌ๋ผ๋Š” ํ˜์‹ ์ ์ธ ๊ธฐ์—…์œผ๋กœ์„œ ๋ฏธ๋ž˜๋ฅผ ํ–ฅํ•œ ๋น„์ „์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์˜ ์ „๊ธฐ ์ž๋™์ฐจ ๊ธฐ์ˆ ๊ณผ ์—๋„ˆ์ง€ ์†”๋ฃจ์…˜์€ ์ „ ์„ธ๊ณ„์ ์œผ๋กœ ์ฃผ๋ชฉ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์Šฌ๋ผ์˜ ํ˜์‹ ์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹๊ณผ ์ง€์† ๊ฐ€๋Šฅํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋ชจ๋ธ์— ๋Œ€ํ•ด ๋งค์šฐ ๊ธ์ •์ ์œผ๋กœ ์ƒ๊ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. RAG๋ฅผ ์‚ฌ์šฉํ• ๋•Œ ์ ์šฉ๋œ context [‘๊ธธ๊ฒŒ ๊ฐˆ ๊ฒƒ ๊ฐ™์ง€๋Š” ์•Š์•„์š”.\n๊ทธ๋Ÿฌ๋„ค์š”. ์ €๋Š” ์ตœ๋Œ€ํ•œ ์˜ค๋žซ๋™์•ˆ ํ…Œ์Šฌ๋ผ์— ๋จธ๋ฌผ ์ƒ๊ฐ์ด์—์š”.\n๊ทธ๋ฆฌ๊ณ  ์ค€๋น„ ์ค‘์— ์žˆ๋Š” ํฅ๋ฏธ๋กœ์šด ์ผ๋„ ๋งŽ๊ณ ์š”. ์•„์‹œ๋‹ค์‹œํ”ผ, ๋ชจ๋ธ 3์ด ์ถœ์‹œ ์˜ˆ์ •์ด๊ณ ์š”.’, ‘์˜ฌํ•ด ๋ง๊นŒ์ง€ LA์—์„œ ๋‰ด์š•๊นŒ์ง€\n์™„์ „ ์ž์œจ ์ฃผํ–‰์œผ๋กœ ํšก๋‹จํ•˜๋Š” ๊ณ„ํš์— ๋งž์ถฐ์„œ ์ง„ํ–‰ ์ค‘์ด์—์š”.\n์‚ฌ๋žŒ์ด ํ…Œ์Šฌ๋ผ์— ํƒ€์„œ ์šด์ „๋Œ€๋ฅผ ์žก์ง€ ์•Š๊ณ  “๋‰ด์š•"์„ ์ฐ์œผ๋ฉด ๊ทธ๋ฆฌ๋กœ ๊ฐ„๋‹ค๋Š” ๋ง์ด๋„ค์š”.’, ‘๊ธธ๊ฒŒ ๊ฐˆ ๊ฒƒ ๊ฐ™์ง€๋Š” ์•Š์•„์š”.\n๊ทธ๋Ÿฌ๋„ค์š”. ์ €๋Š” ์ตœ๋Œ€ํ•œ ์˜ค๋žซ๋™์•ˆ ํ…Œ์Šฌ๋ผ์— ๋จธ๋ฌผ ์ƒ๊ฐ์ด์—์š”.\n๊ทธ๋ฆฌ๊ณ  ์ค€๋น„ ์ค‘์— ์žˆ๋Š” ํฅ๋ฏธ๋กœ์šด ์ผ๋„ ๋งŽ๊ณ ์š”. ์•„์‹œ๋‹ค์‹œํ”ผ, ๋ชจ๋ธ 3์ด ์ถœ์‹œ ์˜ˆ์ •์ด๊ณ ์š”.’, ‘์˜ฌํ•ด ๋ง๊นŒ์ง€ LA์—์„œ ๋‰ด์š•๊นŒ์ง€\n์™„์ „ ์ž์œจ ์ฃผํ–‰์œผ๋กœ ํšก๋‹จํ•˜๋Š” ๊ณ„ํš์— ๋งž์ถฐ์„œ ์ง„ํ–‰ ์ค‘์ด์—์š”.\n์‚ฌ๋žŒ์ด ํ…Œ์Šฌ๋ผ์— ํƒ€์„œ ์šด์ „๋Œ€๋ฅผ ์žก์ง€ ์•Š๊ณ  “๋‰ด์š•"์„ ์ฐ์œผ๋ฉด ๊ทธ๋ฆฌ๋กœ ๊ฐ„๋‹ค๋Š” ๋ง์ด๋„ค์š”.’] RAG๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์˜ ๋Œ€๋‹ต ์ €๋Š” ํ…Œ์Šฌ๋ผ๋ฅผ ๋งค์šฐ ๊ธ์ •์ ์œผ๋กœ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์Šฌ๋ผ๋Š” ํ˜์‹ ์ ์ธ ๊ธฐ์ˆ ๊ณผ ์ง€์† ๊ฐ€๋Šฅํ•œ ๋ฏธ๋ž˜๋ฅผ ์œ„ํ•œ ๋น„์ „์„ ๊ฐ–์ถ˜ ๊ธฐ์—…์œผ๋กœ์„œ, ์ž์œจ ์ฃผํ–‰ ๊ธฐ์ˆ ์„ ํ†ตํ•ด ์šฐ๋ฆฌ์˜ ์‚ถ์„ ํ˜์‹ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ „๊ธฐ์ฐจ ์‹œ์žฅ์„ ์„ ๋„ํ•˜๊ณ  ํ™˜๊ฒฝ์— ์นœํ™”์ ์ธ ์ฐจ๋Ÿ‰์„ ์ œ๊ณตํ•˜๋Š” ๋ฉ‹์ง„ ๊ธฐ์—…์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์Šฌ๋ผ์˜ ๋ฏธ๋ž˜๊ฐ€ ๋ฐ๊ณ  ํฅ๋ฏธ๋กœ์šด ์ผ๋“ค์ด ๊ณ„์†ํ•ด์„œ ์ผ์–ด๋‚  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค. ๊ณ ์ฐฐ ํ™•์‹คํžˆ RAG๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์„ ๋•Œ๋Š” ๊ฐ๊ด€์ ์ด๊ณ  ์ผ๋ฐ˜์ ์ธ ๋Œ€๋‹ต์„ ํ•˜๋Š” ๋ฐ˜๋ฉด, RAG๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํ…Œ์Šฌ๋ผ์— ๋Œ€ํ•ด ๊ธ์ •์ ์ธ ์ผ๋ก  ๋จธ์Šคํฌ์˜ ๋Œ€๋‹ต๊ณผ, ์ž์œจ์ฃผํ–‰ ๊ธฐ์ˆ ์„ ์–ธ๊ธ‰ํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐ˜์˜ํ•˜์—ฌ ๋Œ€๋‹ต์„ ์ƒ์„ฑํ•˜์˜€๋‹ค.
new ์ปดํŒŒ์ผ๋Ÿฌ๊ฐœ๋ก 
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
๊ฐœ์š” ์ปดํ“จํ„ฐ์™€ ์ธ๊ฐ„์ด ์†Œํ†ตํ•˜๋Š” ๋ฐฉ๋ฒ• ์–ด์…ˆ๋ธ”๋ฆฌ์–ด ์–ด์…ˆ๋ธ”๋ฆฌ์–ด์˜ ๋ฒˆ์—ญ๊ธฐ๋Š” ์–ด์…ˆ๋ธ”๋Ÿฌ(Assembler)๋ผ๊ณ  ํ•œ๋‹ค cpu์นฉ์…‹์ด ๋ฐ”๋€”๋•Œ๋งˆ๋‹ค ์–ด์…ˆ๋ธ”๋ฆฌ์–ด๊ฐ€ ๋ฐ”๋€๋‹ค ๊ณ ๊ธ‰์–ธ์–ด ๊ณ ๊ธ‰์–ธ์–ด์˜ ๋ฒˆ์—ญ๊ธฐ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ(Compiler)๋ผ๊ณ  ํ•œ๋‹ค ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ •ํ™•ํ•œ ์ •์˜ ์–ด๋–ค ์–ธ์–ด๋กœ ์“ฐ์—ฌ์ง„ ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐ™์€ ์—ญํ• ์˜ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ 1952๋…„ ๊ทธ๋ ˆ์ด์Šค ํ˜ธํผ(Grace Hopper)๊ฐ€ UNIVAC์šฉ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์–ธ์–ด A-0 ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์ œ์ž‘ ์ปดํŒŒ์ผ๋Ÿฌ vs ์ธํ„ฐํ”„๋ฆฌํ„ฐ ํ”„๋กœ๊ทธ๋žจ ์ฒ˜๋ฆฌ๊ณผ์ • ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ฒ˜๋ฆฌ ๊ณผ์ • Lexical analysis (์–ดํœ˜ ๋ถ„์„) token์„ ์ƒ์„ฑํ•˜๋Š”์ผ, token์€ ์–ดํœ˜์˜ ์ตœ์†Œ ๋‹จ์œ„ Syntax analysis (๊ตฌ๋ฌธ ๋ถ„์„) token์„ ์ฝ์–ด์„œ ์˜ค๋ฅ˜๋ฅผ ๊ฒ€์ƒ‰, ๊ตฌ๋ฌธ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ ๋‹ค (์ฃผ๋กœ ํŠธ๋ฆฌํ˜•ํƒœ) Semantic analysis (์˜๋ฏธ ๋ถ„์„) type checking Intermediate code generation (์ค‘๊ฐ„ ์ฝ”๋“œ ์ƒ์„ฑ) ์ค‘๊ฐ„ ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ Code optimization (์ฝ”๋“œ ์ตœ์ ํ™”) ์ค‘๊ฐ„ ์ฝ”๋“œ๋ฅผ ๋” ํšจ์œจ์ ์œผ๋กœ ๋ณ€ํ™˜ Code generation (์ฝ”๋“œ ์ƒ์„ฑ) ๋ชฉ์  ์ฝ”๋“œ ์ƒ์„ฑ Lexical analysis (์–ดํœ˜ ๋ถ„์„) token : ๋ฌธ๋ฒ•์ ์œผ๋กœ ์˜๋ฏธ์žˆ๋Š” ์ตœ์†Œ ๋‹จ์œ„ FSA (Finite State Automata, ์œ ํ•œ ์ƒํƒœ ์˜คํ† ๋งˆํƒ€) token์„ ์ธ์‹ํ•˜๋Š” ๋ฐฉ๋ฒ• ์‹œ์ž‘ ์ƒํƒœ ํ•œ ๊ฐœ์™€ ๋ ์ƒํƒœ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ๊ฐ€์ง DFA (Deterministic Finite Automata) FSA์˜ ํ•œ ์ข…๋ฅ˜ ๊ฐ ์ƒํƒœ์—์„œ ๋ป—์–ด๋‚˜๊ฐ€๋Š” edge๊ฐ€ ํ•˜๋‚˜์”ฉ๋งŒ ์กด์žฌ ฮต๊ฐ€ ๋ถ™์€ edge ์—†์Œ ๋ถ„์„ํ•œ ํ† ํฐ์„ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ• Lexeme = <ํ† ํฐ๋ฒˆํ˜ธ, ํ† ํฐ ๊ฐ’> ์˜ˆ์‹œ if X < Y … (29, 0) (1, X) (18, 0) (1, Y) … ์‹๋ณ„์ž์˜ ํ† ํฐ๋ฒˆํ˜ธ๋Š” 1๋ฒˆ, ์ƒ์ˆ˜๋Š” 2๋ฒˆ ๋“ฑ์œผ๋กœ ๊ณ ์ • Syntax analysis (๊ตฌ๋ฌธ ๋ถ„์„) token์„ ์ฝ์–ด์„œ ์˜ค๋ฅ˜๋ฅผ ๊ฒ€์ƒ‰, parse tree๋ฅผ ๋งŒ๋“ ๋‹ค CFG (Context Free Grammer) ๊ตฌ๋ฌธ์„ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ• G = (N, T, P, S) N = nonterminal symbol ์•ŒํŒŒ๋ฒณ ๋Œ€๋ฌธ์ž๋กœ ํ‘œํ˜„ T = terminal symbol (token) ์•ŒํŒŒ๋ฒณ ์†Œ๋ฌธ์ž+์ˆซ์ž, ์—ฐ์‚ฐ์ž, ๊ตฌ๋ถ„์ž, ํ‚ค์›Œ๋“œ ๋“ฑ P = production rule ์˜ˆ) S -> T+T, T -> ‘0’|‘1’|‘2’ S = start symbol L(G) : ์ด ๋ฌธ๋ฒ•์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์–ธ์–ด ์—ฌ๋Ÿฌ๊ฐ€์ง€ CFG ํ‘œํ˜„๋ฒ• BNF (Backus-Naur Form) EBNF (Extended BNF) ์œ ๋„ (derivation) ์ƒ์„ฑ ๊ทœ์น™๋ฅผ ์ ์šฉํ•˜์—ฌ ๋ฌธ์žฅ์„ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ • ์œ ๋„๋ฅผ ํ•˜๋Š” ๊ณผ์ •์—์„œ ํ•˜๋‚˜์”ฉ ๊ณจ๋ผ์„œ ๋ฐ”๊ฟˆ ์œ ๋„ ํŠธ๋ฆฌ : ์œ ๋„ ๊ฒฝ๋กœ๋ฅผ ์ถ”์ƒํ™” ์‹œ์ผœ ํ‘œํ˜„ํ•œ ๊ฒƒ ์ขŒ์ธก ์œ ๋„(leftmost derivation) ๊ฐ€์žฅ ์™ผ์ชฝ์— ์žˆ๋Š” nonterminal์„ ๋จผ์ € ๋Œ€์น˜ ์šฐ์ธก ์œ ๋„(rightmost derivation) ๊ฐ€์žฅ ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” nonterminal์„ ๋จผ์ € ๋Œ€์น˜ ๋ชจํ˜ธ์„ฑ (ambiguity) ๋ฌธ๋ฒ• G์— ์˜ํ•ด ์ƒ์„ฑ๋˜๋Š” ์–ด๋–ค ๋ฌธ์žฅ์ด ๋‘๊ฐœ ์ด์ƒ์˜ ์œ ๋„ํŠธ๋ฆฌ๋ฅผ ๊ฐ–๋Š”๋‹ค๋ฉด ๋ฌธ๋ฒ• G๋Š” ๋ชจํ˜ธํ•˜๋‹ค๊ณ  ํ•œ๋‹ค ๋ชจํ˜ธํ•˜์ง€ ์•Š์€ ๋ฌธ๋ฒ•์€ ์ขŒ์ธก ์œ ๋„์™€ ์šฐ์ธก ์œ ๋„๊ฐ€ ๊ฐ™๋‹ค ๋ชจํ˜ธ์„ฑ ํ•ด๊ฒฐ ์—ฐ์‚ฐ์ž ์šฐ์„ ์ˆœ์œ„ ๋„์ž… ๊ฒฐํ•ฉ ๋ฒ•์น™ ๋„์ž… Left Recursion์€ ์ขŒ์ธก ๊ฒฐํ•ฉ์— ์‚ฌ์šฉ ex) A -> A+a | a Right Recursion์€ ์šฐ์ธก ๊ฒฐํ•ฉ์— ์‚ฌ์šฉ ex) A -> a+A | a ๊ตฌ๋ฌธ ๋ถ„์„์˜ 2๊ฐ€์ง€ ๋ฐฉ์‹ top-down, bottom-up Top-down parsing Top-down ๋ฐฉ์‹ ์ขŒ์ธก ์œ ๋„์™€ ๊ฐ™์€ ์ˆœ์„ ์˜ ์ƒ์„ฑ ๊ทœ์น™ ์ ์šฉ backtracking : ์œ ๋„๋œ ๋ฌธ์ž์—ด๊ณผ ์ž…๋ ฅ ๋ฌธ์ž์—ด์ด ๊ฐ™์ง€ ์•Š์œผ๋ฉด ๋‹ค๋ฅธ ์ƒ์„ฑ๊ทœ์น™ ์ ์šฉ Bottom-up ๋ฐฉ์‹ ์šฐ์ธก ์œ ๋„์˜ ์—ญ์ˆœ์˜ ์ƒ์„ฑ ๊ทœ์น™ ์ ์šฉ LL ํŒŒ์‹ฑ ์™ผ์ชฝ->์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ฝ์–ด์„œ ์ขŒํŒŒ์Šค ์ƒ์„ฑ backtracking X, ๋น ๋ฅด๋‹ค ๊ฒฐ์ •์ ์œผ๋กœ ํŒŒ์‹ฑ ์‚ฌ์šฉ๋œ ์ •์˜ ฮต-์ƒ์„ฑ๊ทœ์น™ Nonterminal A๊ฐ€ ฮต๋ฅผ ์œ ๋„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉด A๋ฅผ nullableํ•˜๋‹ค๊ณ  ๋ถ€๋ฅธ๋‹ค lhs, rhs A->XXX์—์„œ lhs๋Š” A, rhs๋Š” XXX โŠ• (Ring Sum) A์— ฮต๊ฐ€ ์žˆ์œผ๋ฉด, AโŠ•B = (A์—์„œ ฮต๋นผ๊ณ  A ํ•ฉ์ง‘ํ•ฉ B) A์— ฮต๊ฐ€ ์—†์œผ๋ฉด, AโŠ•B = A First nonterminal A๋กœ ๋ถ€ํ„ฐ ์œ ๋„๋˜์–ด ์ฒซ๋ฒˆ์งธ๋กœ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ๋Š” terminal์˜ ์ง‘ํ•ฉ X->Y1Y2Y3์ผ๋•Œ, FIRST(X) = FIRST(X) U FIRST(Y1) โŠ• FIRST(Y2) โŠ• FIRST(Y3) Follow A ๋‹ค์Œ์— ๋‚˜์˜ค๋Š” terminal์˜ ์ง‘ํ•ฉ A->ฮฑBฮฒ, ฮฒ != ฮต ์ผ๋•Œ, FOLLOW(B) = FOLLOW(B) U (FIRST(ฮฒ)-{ฮต}) A->ฮฑB ๋˜๋Š” A->ฮฑBฮฒ, FIRST(ฮฒ)์— ฮต๊ฐ€ ์†ํ•  ๋•Œ, FOLLOW(B) = FOLLOW(B) U FOLLOW(A) LL์กฐ๊ฑด FIRST(ฮฑ)์™€ FIRST(ฮฒ)๊ฐ€ ๊ฒน์น˜๋ฉด ์•ˆ๋œ๋‹ค FIRST(ฮฑ)์— ฮต๊ฐ€ ์žˆ์œผ๋ฉด, FOLLOW(ฮฑ)์™€ FIRST(ฮฒ)๊ฐ€ ๊ฒน์น˜๋ฉด ์•ˆ๋œ๋‹ค LL ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ฌธ๋ฒ• = LL ํŒŒ์‹ฑ ๋˜๋Š” ๋ฌธ๋ฒ• LL(1) ๋ฌธ๋ฒ• ์ž„์˜์˜ ๋ฌธ๋ฒ•์— ๋Œ€ํ•˜์—ฌ LL ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” CFG 1 : LOOKAHEAD๊ฐ€ 1๊ฐœ๋ผ๋Š” ์˜๋ฏธ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ LL(1)๋ฌธ๋ฒ•์ด ๋˜์ง€ ์•Š๋Š”๋‹ค ๋ชจํ˜ธํ•œ ๋ฌธ๋ฒ• ์šฐ์„ ์ˆœ์œ„ ์ฃผ๊ธฐ, ๊ฒฐํ•ฉ๋ฒ•์น™ ๋ฐ˜์˜์œผ๋กœ ํ•ด๊ฒฐ left-factoring์ด ๋˜๋Š” ๊ฒฝ์šฐ ๊ณตํ†ต ์•ž๋ถ€๋ถ„์„ ์ƒˆ๋กœ์šด nonterminal๋กœ ๋งŒ๋“ค์–ด ํ•ด๊ฒฐ left-recursiveํ•œ ๊ฒฝ์šฐ ์ง์ ‘ recursion : A -> Aฮต ์ธ๊ฒฝ์šฐ ๊ฐ„์ ‘ recursion : A -> B, B -> A ์ธ๊ฒฝ์šฐ LOOKAHEAD ์–ด๋–ค ๊ทœ์น™์ด ์ ์šฉ๋˜์—ˆ์„๋•Œ ๋งจ ์ฒ˜์Œ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋Š” terminal ์ง‘ํ•ฉ A->X1X2X3์ผ๋•Œ, LOOKAHEAD(A) = FIRST(X1) โŠ• FIRST(X2) … โŠ• FOLLOW(A) Strong LL(1) LL(1)๊ณผ ํ•ญ์ƒ ๋™์ผ (1์ด ์•„๋‹๋•Œ๋Š” ๋‹ค๋ฆ„) LOOKAHEAD(A->ฮฑ)์™€ LOOKAHEAD(A->ฮฒ)๊ฐ€ ๊ฒน์น˜์ง€ ์•Š๋Š” ๋ฌธ๋ฒ• LL(1) ํŒŒ์„œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• Recursive descent parser ์žฅ์  : ์ง๊ด€์  ์‰ฝ๋‹ค ๋‹จ์  : ์ƒ์„ฑ ๊ทœ์น™์ด ๋ฐ”๋€Œ๋ฉด ๊ตฌ๋ฌธ ๋ถ„์„๊ธฐ๋ฅผ ๊ณ ์ณ์•ผ ํ•œ๋‹ค Predictive parser PDA(PushDown Automata)์— ๊ธฐ๋ฐ˜ ์ƒ์„ฑ ๊ทœ์น™์ด ๋ฐ”๋€Œ๋ฉด ํŒŒ์‹ฑ ํ…Œ์ด๋ธ”๋งŒ ์ˆ˜์ • ํŒŒ์‹ฑํ…Œ์ด๋ธ” ์˜ˆ์‹œ (?์—๋Š” ๊ทœ์น™๋ฒˆํ˜ธ๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค) a b S ? ? A ? ? ํŒŒ์‹ฑํ…Œ์ด๋ธ”์— ๋‘๊ฐœ ์ด์ƒ์˜ ์ƒ์„ฑ ๊ทœ์น™์ด ๋“ค์–ด๊ฐ€๋Š” ๊ฒฝ์šฐ -> NOT LL(1) Stack์˜ ์˜ˆ์‹œ Bottom-up parsing left-recursive ๋ฌธ๋ฒ•๋„ ํŒŒ์‹ฑ ๊ฐ€๋Šฅ LL(k) ์ขŒ์ธก์œ ๋„ ๊ธฐ๋ฐ˜ k๊ฐœ์˜ symbol์„ lookahead Top-down parsing, recursive descent parsing, predictive parsing, LL parser ํŒŒ์ŠคํŠธ๋ฆฌ๋ฅผ pre-roder๋กœ ์ˆœํšŒ ๋ฐ ์ƒ์„ฑ LR(k) ์šฐ์ธก์œ ๋„ ๊ธฐ๋ฐ˜ k๊ฐœ์˜ symbol์„ lookahead Bottom-up parsing, shift-reduce parsing, LR parser ํŒŒ์ŠคํŠธ๋ฆฌ๋ฅผ post-order๋กœ ์ˆœํšŒ ๋ฐ ์ƒ์„ฑ Reduce S=>ฮฑฮฒฯ‰์ด๊ณ  A->ฮฒ์ด๋ฉด ฮฒ๋ฅผ A๋กœ ๋Œ€์น˜ํ•˜๋Š” ๊ฒƒ : S=>ฮฑAฯ‰ ์‹œ์ž‘ symbol์ด ๋‚˜์˜ฌ ๋•Œ๊นŒ์ง€ reduce ํ•œ๋‹ค Handle S=>ฮฑฮฒฯ‰์ด๊ณ  A->ฮฒ์ด๋ฉด ฮฒ๋ฅผ ฮฑฮฒฯ‰์˜ handle์ด๋ผ๊ณ  ํ•œ๋‹ค ๋‘ ๊ฐœ ์ด์ƒ์˜ handle์ด ์กด์žฌํ• ๋•Œ -> ๋ชจํ˜ธํ•˜๋‹ค Shift์™€ Reduce๋กœ Parsing ํ•˜๊ธฐ Stack์˜ ์˜ˆ์‹œ Issue Shift์™€ Reduce ์ค‘ ์–ด๋А ๊ฒƒ์„ ํ• ๊นŒ? Stack์˜ top์—์„œ ์–ผ๋งˆ๋งŒํผ์„ handle๋กœ ๋ณผ ๊ฒƒ์ธ๊ฐ€? ํ•ด๊ฒฐ๋ฐฉ๋ฒ•: LR Parsing Table YACC LALR ํŒŒ์„œ ์ƒ์„ฑ๊ธฐ foo.y –(yacc)–> y.tab.c –(gcc)–> a.out *.y ํŒŒ์ผ ๊ตฌ์กฐ 1<์„ ์–ธ๋ถ€> 2... 3%% 4... 5exp : exp '+' term; 6factor : ident; 7... 8%% 9<์—ฌ๋Ÿฌ ํ•จ์ˆ˜> ๋ชจํ˜ธํ•œ ๋ฌธ๋ฒ•์œผ๋กœ LR Conflict ๋ฐœ์ƒ ์‹œ ์„ ์–ธ๋ถ€์—์„œ ์šฐ์„ ์ˆœ์œ„ ์ง€์ •ํ•˜์—ฌ ํ•ด๊ฒฐ LR Parsing Table Action table : Action + Parser ์ƒํƒœ Goto table : Parser ์ƒํƒœ LR(0) ํŒŒ์‹ฑ ํ…Œ์ด๋ธ” ๋งŒ๋“ค๊ธฐ LR(0) ์•„์ดํ…œ rhs์— ์ (’.’) symbol์„ ๊ฐ€์ง„ ์ƒ์„ฑ ๊ทœ์น™ ex) A->ฮฑ.ฮฒ, A->. closure ์ (’.’)๋’ค์— non-terminal์ด ์˜ค๋ฉด ์žฌ๊ท€์ ์œผ๋กœ ์ถ”๊ฐ€ S’ -> S, S -> (L)|id, L -> S | L,S closure({[S’->.S]}) = {[S’->.S], [S->.(L)], [S->.id]} goto goto(I, X)์ด๋ฉด ์ ์„ X๋’ค๋กœ ์˜ฎ๊ธฐ๊ณ  closure๋ฅผ ์ทจํ•œ๋‹ค X๊ฐ€ ์—†์œผ๋ฉด ๋„ฃ์ง€ ์•Š๋Š”๋‹ค I={[G->E=E], [E->E.+T]} ์ผ๋•Œ, goto(I, +) = closure({E->E+.T}) : ์ ์„ +๋’ค๋กœ ์˜ฎ๊น€ C0 ์ƒ์„ฑ๊ทœ์น™ S’->S์—์„œ๋ถ€ํ„ฐ ์ฐจ๋ก€๋กœ closure์™€ goto๋ฅผ ์ ์šฉํ•˜์—ฌ ์–ป์€ ๋ชจ๋“  ํƒ€๋‹นํ•œ LR(0)์˜ ์•„์ดํ…œ ์ง‘ํ•ฉ๋“ค Item์˜ ์ข…๋ฅ˜ [A->X.Y] : X!=ฮต์ผ๋•Œ kernel item [A->.X] : closure item [A->X.] : reduce item SLR ํŒŒ์‹ฑ ํ…Œ์ด๋ธ” ๋งŒ๋“ค๊ธฐ reduce Item์ด [X->ฮฑ.]์ผ๋•Œ, FOLLOW(X)์˜ ๋ชจ๋“  terminal์—๋งŒ reduce action์„ ๋„ฃ๋Š”๋‹ค ๋‚˜๋จธ์ง€๋Š” LR(0)๊ณผ ๋˜‘๊ฐ™๋‹ค LR(0)๋ณด๋‹ค conflict๊ฐ€ ์ ์–ด, ๋” ์ •๊ตํ•˜๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. LALR Parsing ์ •๊ตํ•œ ์ˆœ์„œ LR(0) < SLR < LALR(1) < LR(1) ํŒŒ์„œ ์ƒํƒœ์˜ ๊ฐœ์ˆ˜ SLR = LALR « LR(1) SDD, AST SDD (Syntax Directed Definition) SDD : semnatic action์„ ์ •์˜ํ•˜๋Š” ์ถ”์ƒ์ ์ธ ๋ช…์„ธ์„œ Semnatic Actions : ๊ทœ์น™์— ๋Œ€ํ•œ Action Yacc/Bison : $$, $1, $2, ... ์‚ฌ์šฉ ANTLR : $<name> ์‚ฌ์šฉ Type declaration Attribute ์ข…๋ฅ˜ synthesized attr. : children์— ์˜ํ•ด ๊ณ„์‚ฐ (terminal) inherited attr. : parent, sibling์— ์˜ํ•ด ๊ณ„์‚ฐ AST (Abstract Syntax Tree) ํŒŒ์ŠคํŠธ๋ฆฌ์—์„œ ๋ถˆํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ฑฐํ•œ ํ˜•ํƒœ AST๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ• ํŒŒ์‹ฑ๋‹จ๊ณ„์—์„œ ๋งŒ๋“ค๊ธฐ : LL, LR ํŒŒ์ŠคํŠธ๋ฆฌ๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ๋งŒ๋“ค๊ธฐ : SDD ์‚ฌ์šฉ (Yacc etc.) evaluation : ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๋ฉด์„œ ์ž‘์—…ํ•˜๋Š” ํ–‰์œ„ On-the-fly evaluation S-attributed SDD: synthesized attribute๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” SDD L-attributed SDD: synthesized attribute๋งŒ ๊ฐ€์ง€๋Š” ๊ฒฝ์šฐ + ๊ฐ’์ด ์™ผ์ชฝ์—์„œ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ํ˜๋Ÿฌ ๊ณ„์‚ฐ์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒฝ์šฐ IR (Intermediate Representation) IR์ด๋ž€? Tree๋‚˜ Instruction list ํ˜•ํƒœ instruction(node)๊ฐ€ ์ ์–ด์•ผ ์ตœ์ ํ™”/๋ฒˆ์—ญ์— ์ข‹์Œ High Level IR High์™€ Low๋Š” ์ƒ๋Œ€์ ์ธ ๊ฐœ๋… High level IR: ์—ฌ๊ธฐ์„œ๋Š” AST์˜ ๋ณ€ํ˜•๋งŒ ์ƒ๊ฐ ์ข…๋ฅ˜ : AST, TCOL Low Level IR ๋‹จ์ˆœํ•œ instruction์œผ๋กœ ๊ตฌ์„ฑ ๊ฐ€์ƒ๊ธฐ๊ณ„(์ฃผ๋กœ RISC)๋ฅผ emulate N-tuple ํ‘œ๊ธฐ๋ฒ• (3-address code) a = b OP c ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๊ณ„์–ด๊ฐ€ ๊ฐ€์ง€๋Š” ํ”ผ์—ฐ์‚ฐ์ž ๊ฐœ์ˆ˜ <= 3 quadruple : (์—ฐ์‚ฐ์ž, ํ”ผ์—ฐ์‚ฐ์ž1, ํ”ผ์—ฐ์‚ฐ์ž2, ๊ฒฐ๊ณผ) Stack machine code Java byte code, U-code : AST๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ์ด ์šฉ์ด Tree ํ‘œํ˜„ ๊ธฐ๊ณ„์–ด ์ƒ์„ฑ ์šฉ์ด IR ์˜ˆ์‹œ GCC - GIMPLE (3-address code) GCC์˜ ์ค‘๊ฐ„์ฝ”๋“œ : GENERIC -> GIMPLE -> RTL 1D.1954 = x*10 // D.1954๋Š” ์ž„์‹œ๋ณ€์ˆ˜ 2gimple_assign <mult_exprt, D.1954, x, 10> LLVM - bit (3-address code) LLVM IR : ์–ธ์–ด์™€ ๋จธ์‹ ์— ๋…๋ฆฝ์  1@var = global i32 14 ; ์ „์—ญ๋ณ€์ˆ˜ var์— 14 ๋Œ€์ž… 2define i32 @main() nounwind { ; i32(int) ๋ฐ˜ํ™˜ํ˜• 3 entry: 4 %a = alloca i32, align 4 ; ์ง€์—ญ๋ณ€์ˆ˜ a ์„ ์–ธ, int ํ• ๋‹น 5 %1 = load i32 * @var ; %1 ์ž„์‹œ๋ณ€์ˆ˜์— var๊ฐ’ ๋Œ€์ž… 6 ret i32 %1 ; ์ž„์‹œ๋ณ€์ˆ˜ ๊ฐ’ ๋ฐ˜ํ™˜ 7} JVM - byte code (stack machine code) ๊ฐ€์ƒ ๊ธฐ๊ณ„ ์ฝ”๋“œ (Bytecode, MSIL) ๊ฐ€์ƒ ๊ธฐ๊ณ„์—์„œ ๋™์ž‘ํ•˜๋„๋ก ํ•จ ์ด์‹์„ฑ, ํ˜ธํ™˜์„ฑ์ด ๋ชฉ์  : java bytecode๋Š” machine ํ˜ธํ™˜์„ฑ, c# msil์€ language ํ˜ธํ™˜์„ฑ 1public Employee(String strName, int num) 2{name = strName; idNumber = num; storeData(strName, num);} 3Method Employee(java.lang.String, int) 4 50 aload_0 ; 0๋ฒˆ์งธ ๋กœ์ปฌ๋ณ€์ˆ˜(this)๋ฅผ ์Šคํƒ์— push 61 invokespecial #3 <Method java.lang.Object()> ; ํ•จ์ˆ˜ ํ˜ธ์ถœ 7--- 84 aload_0 95 aload_1 ; strName์„ ์Šคํƒ์— push 106 putfield #5 <Field java.lang.String name> ; name์— strName ๋Œ€์ž… 11--- 129 aload_0 1310 iload_2 ; num์„ ์Šคํƒ์— push 1411 putfield #7 <Field int idNumber> ; idNumber์— num ๋Œ€์ž… 15--- 1614 aload_0 1715 aload_1 ; strName์„ ์Šคํƒ์— push 1816 iload_2 ; num์„ ์Šคํƒ์— push 1917 invokespecial #9 <Method void storeData(java.lang.String, int)> ; ํ•จ์ˆ˜ ํ˜ธ์ถœ 2020 return line number : ๋ช…๋ น์ด ์‹œ์ž‘ํ•˜๋Š” ๋ฐ”์ดํŠธ ์ฃผ์†Œ aload : ๊ฐ์ฒด๋ฅผ push, iload : ์ •์ˆ˜๋ฅผ push ์›๋ž˜๋Š” aload๊ฐ€ ๋ช…๋ น, ์ž์ฃผ ์“ฐ๋Š” ๋ช…๋ น aload 0์„ ๋ฌถ์–ด์„œ bind -> aload_0 CIL (Common Intermediate Language) (stack machine code) C#, VB.NET, J# ๋“ฑ์—์„œ ์‚ฌ์šฉ MSIL์€ ์˜›๋‚  ์ด๋ฆ„ 1.assembly Hello {} ; .assembly: ์–ด์…ˆ๋ธ”๋ฆฌ ์„ ์–ธ 2.assembly extern mscorlib {} 3.method static void Main() { 4 .entrypoint 5 .maxstack 1 6 ldstr "Hello, world!" ; stack์— ์ €์žฅ 7 call void [mscorlib]System.Console::WriteLine(string) 8 ret 9} GCC RTL(Register Transfer Language) (Tree๊ตฌ์กฐ ์ฝ”๋“œ) Lisp S-expression ์‚ฌ์šฉ 1(set (reg:SI 140) 2 (plus:SI (reg:SI 138) 3 (reg:SI 139))) => reg140 = reg138+reg139 IR generation 3-address Translation ๊ทœ์น™ Binary operations: t = [[el OP e2]] Unary operations: t = [[OP el]] Array access: t = [[ v[e] ]] Structure access: t = [[ v.f ]] Short-circuit OR: t = [[ el SC-OR e2]] Statement sequence: [[s1; s2; ...; sN]] Variable assignment: [[ v = e ]] Array assignment: [[ v[e1] = e2 ]] If: [[ if(e) then s ]], [[ if(e) then s1 else s2]] While: [[ while (e) s ]] Switch: [[ switch (e) case v1:s1, ..., case vN:sN ]] Function Call: [[ call f(e1, e2, ..., eN) ]] Fucntion Return: [[ return e ]] Statement Expression Statement๋„ expression ์ฒ˜๋Ÿผ ๊ฐ’์„ ๊ฐ€์ง€๋„๋ก ํ™•์žฅ t = [[ S ]]๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ฒฐ๊ณผ๊ฐ’์„ ์ €์žฅํ•˜์ž Nested Expressions t = [[ (a - b) * (c + d) ]] t = [[ if c then if d then a = b ]] ๊ฐ€์žฅ ํฐ ๋ฉ์–ด๋ฆฌ๋ถ€ํ„ฐ ๋ฐ”๊พผ๋‹ค Storage Management 2๊ฐ€์ง€ Storage Register : ๋น ๋ฅธ ์ ‘๊ทผ, ๊ฐ„์ ‘ ์ ‘๊ทผ ๋ถˆ๊ฐ€ Memory : ์ƒ๋Œ€์ ์œผ๋กœ ๋А๋ฆฐ ์ ‘๊ทผ, ๊ฐ„์ ‘ ์ ‘๊ทผ ๊ฐ€๋Šฅ 2๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ์‹ All memory approach ๋ชจ๋“  ๋ณ€์ˆ˜๋ฅผ memory์— ์ €์žฅ, ๊ฐ€๋Šฅํ•œ๊ฒƒ๋งŒ register Standard approach Global, Statics, Local(composite)๋Š” memory์— ์ €์žฅ Local(scalar)๋Š” memory ๋˜๋Š” virtual register์— ์ €์žฅ Memory์˜ 4๋Œ€ ์˜์—ญ Code space : ๋ช…๋ น์–ด๋ฅผ ์ €์žฅ read-only์ผ๋•Œ ๋น ๋ฆ„ Static data : ํ”„๋กœ๊ทธ๋žจ๊ณผ lifetime์„ ํ•จ๊ป˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ Stack : Local ๋ณ€์ˆ˜๋“ค Heap : ๋™์ ์œผ๋กœ ํ• ๋‹น๋˜๋Š” ๋ฐ์ดํ„ฐ File Format Windows : PE (Portable Executable) Unix : ELF (Executable and Linkable Format) ๋ณ€์ˆ˜ ๋ฐ”์ธ๋”ฉ environment : <๋ณ€์ˆ˜, storage location> ์ •๋ณด state: <๋ณ€์ˆ˜, ๊ฐ’> ์ •๋ณด ์–ด๋–ค ๋ณ€์ˆ˜ N์ด storage location S์— ์ง€์ •๋˜๋ฉด ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค๊ณ  ํ•œ๋‹ค Static Allocation ํ”„๋กœ๊ทธ๋žจ ์ˆ˜ํ–‰ํ•˜๋Š” ๋™์•ˆ ๋ณ€ํ•˜์ง€ ์•Š๋Š” location์œผ๋กœ ๋ฐ”์ธ๋”ฉ Heap Allocation ์—ฐ์†์ ์ธ global ์˜์—ญ์˜ ์ผ๋ถ€๋ฅผ OS๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๊ฒƒ ํ”„๋กœ๊ทธ๋žจ ์ˆ˜ํ–‰ ์ค‘ ์š”์ฒญ๊ณผ ๋ฐ˜ํ™˜ Stack Management Run-time stack : ํ•œ ํ•จ์ˆ˜ call๋งˆ๋‹ค ํ•˜๋‚˜์”ฉ๋‘๋Š” frames Activation record : ํ•จ์ˆ˜ ์ˆ˜ํ–‰์„ ์œ„ํ•œ execution env(local var, parameter, return address, etc.) Top frame : ํ˜„์žฌ ์ˆ˜ํ–‰์ค‘์ธ ํ•จ์ˆ˜์˜ frame Stack pointers SP : Frame top FP : Frame base ๋‘ ๊ฐœ๋ฅผ ์“ฐ๋Š” ์ด์œ  ๊ฐ€๊นŒ์šด ๊ฑฐ ๊ธฐ์ค€์œผ๋กœ offset ๊ณ„์‚ฐ -> small offset ์œ ์ง€ ์ˆ˜ํ–‰ ์ค‘ top frame์˜ ์œ„์น˜๋ฅผ ์•Œ ์ˆ˜ ์—†์Œ Semantic Analysis - Symbol Tables Scope Identifier: ์‹๋ณ„์ž Lexical Scope: ํŠน์ • ๋ฒ”์œ„ ์‹๋ณ„์ž์˜ Scope: ๊ทธ ์‹๋ณ„์ž์˜ ์„ ์–ธ์ด ์ฐธ์กฐ๋˜๋Š” lexical scope Symbol Table Name Kind Type Attribute foo func int, int -> int extern m arg int tmp var char const ํ•˜๋‚˜์˜ lexical๋งˆ๋‹ค ํ•˜๋‚˜์˜ symbol table symbol table์€ ๊ณ„์ธต์ ์ด๋‹ค ํ˜„์žฌ scope์— ์—†์œผ๋ฉด ์ƒ์œ„ scope๋กœ ์˜ฌ๋ผ๊ฐ€๋ฉด์„œ ์ฐพ๋Š”๋‹ค Symbol Table Implementation AST๊ฐ€ ๋งŒ๋“ค์–ด์ ธ์•ผ ๊ฐ€๋Šฅ Local Table์€ hash table ์‚ฌ์šฉ Global Table์€ N-array tree ๊ตฌ์กฐ ์‚ฌ์šฉ ์ฝ”๋“œ๋ฅผ ์ˆœ์ฐจ๋Œ€๋กœ ์ฝ์œผ๋ฉด์„œ ๋งŒ๋“ฌ (scope ์Šคํƒ์„ ์‚ฌ์šฉ) Type Checking Type Expressions Array types: T[], T[10] Structure types : {id1: T1, id2: T2 …} Pointer types: T* Function types: T1 X T2 X … X Tn -> T_return Type Judgement A โ”œ E : T A ์ƒํ™ฉ์—์„œ E๋Š” Tํƒ€์ž…์„ ๋งŒ์กฑํ•œ๋‹ค A โ”œ if(E) S1 else S2 : T ์œ„ ์กฐ๊ฑด์€ ๋ชจ๋“  E, S1, S2, A, T์— ๋Œ€ํ•œ ๊ฐ€์ •์ด ์„ฑ๋ฆฝํ•  ๋•Œ ๊ฒฐ๋ก  T๊ฐ€ ์„ฑ๋ฆฝํ•œ๋‹ค Proof Tree (ํƒ€์ž… ์œ ๋„ ํŠธ๋ฆฌ) ์—ญ์‚ผ๊ฐํ˜• ๋ชจ์–‘ ๋งŒ์กฑํ•˜๋Š” proof tree๊ฐ€ ์žˆ๋‹ค -> ํƒ€์ž… ์˜ค๋ฅ˜๊ฐ€ ์—†๋‹ค ๊ทธ ์™ธ Semantic Analyses break, continue, goto ๋ฌธ์ด ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜์— ์žˆ๋Š” ์ง€ ๋“ฑ ์ปดํŒŒ์ผ๋Ÿฌ ํ›„๋ฐ˜๋ถ€ (๋น ๋ฅด๊ณ , ์‹ค์ œ ๋Œ์•„๊ฐ€๋Š” ์ฝ”๋“œ๋กœ ๋ฐ”๊พธ๊ธฐ) Instruction Selection Tree ๊ธฐ๋ฐ˜ Intermediate Representation MEM(e) : ์ฃผ์†Œ e๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ํ•œ word์˜ ๋‚ด์šฉ TEMP(t) : ๋ ˆ์ง€์Šคํ„ฐ t SEQ(s1, s2): ๋ฌธ์žฅ s1 ์ˆ˜ํ–‰ ํ›„ s2 ์ˆ˜ํ–‰ ESEQ(s, e): ๋ฌธ์žฅ s ์ˆ˜ํ–‰ ํ›„ (๊ฒฐ๊ณผ ์—†์Œ) e๊ฐ€ ์ถ”๊ฐ€ ์ˆ˜ํ–‰ BINOP(o, e1, e2) : ์—ฐ์‚ฐ์ž o, ํ”ผ์—ฐ์‚ฐ์ž e1, e2, ๊ฒฐ๊ณผ ์ €์žฅ๋œ ์ฃผ์†Œ ๋ฐ˜ํ™˜ const(i): ์ •์ˆ˜ ์ƒ์ˆ˜ i Register Allocation ์ตœ์ ํ™” ํ•˜๊ธฐ ์œ„ํ•ด ์ตœ๋Œ€ํ•œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์„ Register์— ์ €์žฅ Interference ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ definition์ด live range ์—์„œ ๊ณตํ†ต operation์„ ๊ฐ€์ง€๊ณ ์žˆ๋Š” ๊ฒฝ์šฐ Interference Graph : ์„œ๋กœ interfere ํ•˜๋ฉด ์—ฐ๊ฒฐํ•˜๋Š” ๊ทธ๋ž˜ํ”„ Graph coloring : ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋Š” ๋‹ค๋ฅธ ์ƒ‰์œผ๋กœ ์น ํ•˜๊ธฐ Instruction Scheduling instruction์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ์–ด stall ๊ฐœ์ˆ˜ ๋“ฑ์„ ์ค„์—ฌ์„œ ์ˆ˜ํ–‰์†๋„๋ฅผ ๋†’์ด๋Š” ๊ฒƒ stall : ๋‹ค๋ฅธ ๋ช…๋ น์–ด ์ˆ˜ํ–‰์„ ๊ธฐ๋‹ค๋ฆฌ๋А๋ผ CPU๋ฅผ ๋‚ญ๋น„ํ•˜๋Š” ๊ฒƒ ๋ชฉํ‘œ Wasting time์„ ์ค„์ธ๋‹ค ๋™์ผํ•œ ์ฝ”๋“œ๊ฐ€ ๋‚˜์™€์•ผํ•œ๋‹ค register spilling์„ ํ”ผํ•ด์•ผํ•œ๋‹ค Static scheduling ๋‹จ๊ณ„ Local basic scheduling, Loop scheduling, global scheduling Local basic scheduling List scheduling : greedy, heuristic, local technique ์‚ฌ์šฉ precedence graph๋ฅผ ๋งŒ๋“ ๋‹ค ๊ฐ ๋…ธ๋“œ์— priority function์„ ์ ์šฉํ•œ๋‹ค “ready-operation queue"๋ฅผ ์—์„œ ready operation์„ ํ•˜๋‚˜ ์„ ํƒ ํ›„ scheduling, ready operation queue๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค. Longest latency-weighted path๋ฅผ ์ด์šฉํ•ด์„œ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ •ํ•œ๋‹ค ๊ธฐํƒ€ Optimization ๋ฐฉ๋ฒ• addr r1 1 -> inc r1 ํŠน์ˆ˜ ์„ฑ์งˆ์˜ ๋ ˆ์ง€์Šคํ„ฐ ํ™œ์šฉ ํŠน์ˆ˜ ๋ชฉ์ ์˜ ๋ช…๋ น์–ด ํ™œ์šฉ Register ๊ฐ„ mov ์ œ๊ฑฐ ์ค‘๋ณต๋œ load ์ œ๊ฑฐ Control Flow Optimizations(์ตœ์ ํ™”) ์ฃผ์–ด์ง„ ์ž…๋ ฅ ํ”„๋กœ๊ทธ๋žจ์„ ์ข€ ๋” ํšจ์œจ์ ์ธ ์ฝ”๋“œ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ถ„๋ฅ˜ ๋ฐฉ๋ฒ• ๋ถ„์„ : Control Flow Analysis vs Data Flow Analysis ์ตœ์ ํ™” Inner basic block(local) vs Inter basic block(global) Cyclic code opt vs Acyclic code opt Control Flow Analysis Control Flow ํ”„๋กœ๊ทธ๋žจ์˜ ๊ฐ€๋Šฅํ•œ ์ˆ˜ํ–‰์ˆœ์„œ (๋ถ„๊ธฐ) Branch Execution -> dynamic control flow : ์‹คํ–‰ ํ•ด๋ด์•ผ ํ™•์ธ ๊ฐ€๋Šฅ Compiler -> static control flow : ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ถ„์„ํ•ด์„œ ์•Œ ์ˆ˜ ์žˆ์Œ Analysis ์ •์  ์„ฑ์งˆ (static property): ํ”„๋กœ๊ทธ๋žจ ์ˆ˜ํ–‰ ์—†์ด ๋„์ถœ ๋˜๋Š” ์„ฑ์งˆ CFA(Control Flow Analysis) : ์ฝ”๋“œ์˜ ๋ถ„๊ธฐ ๊ตฌ์กฐ๋ฅผ CFG ํ˜•ํƒœ๋กœ ํ‘œํ˜„ Basic Block ๋™์ผํ•œ execution condition์„ ์ ์šฉ๋ฐ›๋Š” instruction ๋ฌถ์Œ instruction ์™ธ์—๋Š” branch๊ฐ€ ์—†์Œ Maximal basic block ๊ตฌํ•˜๊ธฐ BB์˜ leader(์ฒซ๋ฒˆ์งธ instruction)๋ฅผ ์ฐพ๋Š”๋‹ค ๋‹ค์Œ leader ์ด์ „๊นŒ์ง€์˜ instruction์„ ๊ตฌํ•œ๋‹ค Weighted CFG Profiling: ๋ฐ˜๋ณตํ•ด์„œ ์ˆ˜ํ–‰ํ•ด๋ณด๋ฉด์„œ ์‹คํ–‰ํšŸ์ˆ˜๋ฅผ ์–ป์Œ ์–ป์€ weight๋ฅผ edge์— ํ‘œ์‹œ Control Flow Optimization Acyclic Code Loop๊ฐ€ ์—†๋Š” ์ฝ”๋“œ ๋ถ„์„ ๋ฐ ์ตœ์ ํ™”๊ฐ€ ์ƒ๋Œ€์ ์œผ๋กœ ์‰ฌ์›€ ์ข…๋ฅ˜ Inner basic block opt. = Intra opt. = Local opt. Inter basic block opt. = Global opt. Inner Basic Block Optimization Commn subexpression elimination ๊ณตํ†ต๋œ ๋ถ€๋ถ„์ด ์žˆ์œผ๋ฉด ํ•œ๋ฒˆ๋งŒ ๊ณ„์‚ฐ Algebraic simplification ๋Œ€์ˆ˜๋ฒ•์น™์„ ์ด์šฉํ•˜์—ฌ ์‹์„ ๊ฐ„์†Œํ™” ex) x=1*y; -> x=y; Strength reduction ์—ฐ์‚ฐ์ž์˜ ๋น„์šฉ์ด ์ ์€ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ๊ธฐ ex) x=x*2; -> x=x+x; ex) y=a/4; -> y=a>>2; Constant folding / propagation folding: ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ์ƒ์ˆ˜์‹์„ ์ง์ ‘์‹œ๊ฐ„ propagation : ๊ณ ์ •๋œ ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๋ณ€์ˆ˜๋ฅผ ์ƒ์ˆ˜๋กœ ๋Œ€์ฒด Inter Basic Block Optimization Global application of inner basic block optimization Global common subexpression elimination basic block ๊ฐ„์˜ ๊ณตํ†ต ๋ถ€๋ถ„์‹์— ๋Œ€ํ•ด ํ•œ๋ฒˆ๋งŒ ๊ณ„์‚ฐ Global constant folding / propagation basic block ๊ฐ„์˜ ์ƒ์ˆ˜๋ฅผ ์ธ์‹ํ•˜์—ฌ ํ•œ๋ฒˆ๋งŒ ๊ณ„์‚ฐ Other transformation Branch to unconditional branch ๋ถˆํ•„์š”ํ•œ ๋ถ„๊ธฐ ์ œ๊ฑฐ Unconditional branch to branch ๋ถ„๊ธฐ ํ›„ ๋ฐ”๋กœ ๋ถ„๊ธฐ -> ๋ถ„๊ธฐ ํ•œ๋ฒˆ์œผ๋กœ ๋ณ€๊ฒฝ Branch to next basic block (next instr) ๋ถ„๊ธฐ ํ›„ ๋ฐ”๋กœ ๋‹ค์Œ basic block์œผ๋กœ ๋ถ„๊ธฐ ์ œ๊ฑฐ Basic block merging ๋‘ basic block์„ ํ•ฉ์นจ Branch to same target ๊ฐ™์€ basic block์œผ๋กœ ๋ถ„๊ธฐํ•˜๋Š” ๊ฒƒ์„ ์ œ๊ฑฐ Branch target expansion ๋ถ„๊ธฐ ๋Œ€์ƒ์ด ๋˜๋Š” basic block์„ ํ•ฉ์นจ Unreachable code elimination Entry์—์„œ ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ‘unreachable’ block ์ œ๊ฑฐ Loop Optimization Loop๋Š” ํ•œ๋ฒˆ optimizeํ•˜๋ฉด ํšจ๊ณผ๊ฐ€ ํฌ๋‹ค Loop unrolling : ๋ฐ˜๋ณต๋ฌธ์„ ํ’€์–ด์„œ ๋ฐ˜๋ณต ํšŸ์ˆ˜๋ฅผ ์ค„์ž„ Loop invarient : ๋งค๋ฒˆ ๋™์ผํ•œ ๊ฐ’์„ ๋‚ด๋Š” ๋ฌธ์žฅ์„ ๋ฐ˜๋ณต๋ฌธ ๋ฐ–์œผ๋กœ ๋นผ๋ƒ„ Count up to zero : i๋ฅผ ๊ฐ์†Œํ•˜๋Š” ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋ณ€๊ฒฝ (i๋ฅผ 0๊ณผ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์ด n๊ณผ ๋น„๊ตํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋น ๋ฆ„) Dataflow Analysis + Optimization Dataflow Analysis ํ”„๋กœ๊ทธ๋žจ ๋‚ด์— ๊ฐ data ๊ฐ’๋“ค์ด ์ƒ์„ฑ/์†Œ๋ฉธ๋˜๋Š” ์ •๋ณด๋ฅผ ๋ชจ์œผ๋Š” ๊ฒƒ Reaching Definition Analysis definition : ํ•ด๋‹น ๋ณ€์ˆ˜๊ฐ€ assign๋˜๋Š” ๊ฒƒ reach : definition d๊ฐ€ ํŠน์ • ์œ„์น˜ p์— ๋„๋‹ฌํ•œ๋‹ค kill : definition d์˜ ๋‘๊ฐœ์˜ ํฌ์ธํŠธ์‚ฌ์ด์—์„œ ๋‹ค๋ฅธ definition์ด ์กด์žฌํ•œ๋‹ค GEN/KILL GEN: ๋ธ”๋ก ๋‚ด์—์„œ ์ƒ์„ฑ๋œ definition KILL: ๋ธ”๋ก ๋‚ด์—์„œ ์†Œ๋ฉธ๋œ definition IN/OUT IN : ์ด์ „ ๋ธ”๋ก์˜ OUT์˜ ํ•ฉ์ง‘ํ•ฉ OUT : IN์—์„œ GEN์„ ๋”ํ•˜๊ณ  KILL์„ ๋บ€ ๊ฒƒ
new Nginx์—์„œ HTTPS ์„ค์ •ํ•˜๊ธฐ
๐Ÿ”จ ๊ฐœ๋ฐœ ๋„๊ตฌ
๋ฐฐ๊ฒฝ ํ…Œ์ปค ๋ถ€ํŠธ์บ ํ”„๋ฅผ ์ง„ํ–‰์ค‘์ด๋‹ค. ๋ชจ๋“  ํ”„๋กœ๊ทธ๋žจ์€ docker-compose๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. AWS EC2์— ๊ตฌ๋™ ์ค‘์ธ ์„œ๋ฒ„์— HTTPS๋ฅผ ์ ์šฉํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ๋„๋ฉ”์ธ ๊ตฌ๋งค ์—†์ด ์‹œ๋„๋ฅผ ํ–ˆ์œผ๋‚˜, AWS์—์„œ ์ œ๊ณตํ•˜๋Š” ๋„๋ฉ”์ธ์œผ๋กœ SSL ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์—†์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ๋„๋ฉ”์ธ์„ ๊ตฌ๋งคํ•˜๊ณ , Route 53์„ ํ†ตํ•ด ๋„๋ฉ”์ธ์„ ์—ฐ๊ฒฐํ–ˆ๋‹ค. ๋ชฉํ‘œ Nginx๋ฅผ ์ด์šฉํ•˜์—ฌ HTTPS๋ฅผ ์ ์šฉํ•œ๋‹ค. ๋ฐฉ๋ฒ• 1. docker-compose.yml์— certbot ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. 1certbot: 2 image: certbot/certbot 3 container_name: certbot 4 volumes: 5 - ./certbot/conf:/etc/letsencrypt 6 - ./certbot/www:/var/www/certbot 7 depends_on: 8 - nginx 9 10 # certbot์„ ๋ฌดํ•œ๋ฃจํ”„๋กœ ๋Œ๋ฆฌ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ 11 entrypoint: "/bin/sh -c 'trap exit TERM; while :; do sleep 6h & wait $${!}; done;'" 2. nginx.conf๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค. # certbot์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ • location /.well-known/acme-challenge/ { allow all; root /var/www/certbot; } 3. certbot ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ™œ์šฉํ•ด์„œ SSL ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰๋ฐ›๋Š”๋‹ค. 1docker exec -it certbot certbot certonly \ 2 # ์›น ๋ฃจํŠธ ๋ฐฉ์‹์œผ๋กœ ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑ 3 --webroot \ 4 # ์›น ์„œ๋ฒ„์˜ ์›น ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์ง€์ • 5 --webroot-path=/var/www/certbot \ 6 # ์ธ์ฆ์„œ ๊ฐฑ์‹  ๋ฐ ์ค‘์š”ํ•œ ์•Œ๋ฆผ์„ ๋ฐ›์„ ์ด๋ฉ”์ผ ์ฃผ์†Œ๋ฅผ ์ง€์ • 7 --email {์ด๋ฉ”์ผ ์ฃผ์†Œ} \ 8 # Let's Encrypt ์„œ๋น„์Šค ์•ฝ๊ด€์— ๋™์˜ 9 --agree-tos \ 10 # EFF(Electronic Frontier Foundation) ๋‰ด์Šค๋ ˆํ„ฐ๋ฅผ ๋ฐ›์ง€ ์•Š๋„๋ก ์„ค์ • 11 --no-eff-email \ 12 # SSL ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•  ๋„๋ฉ”์ธ ์ด๋ฆ„์„ ์ง€์ • 13 -d {๋„๋ฉ”์ธ ์ด๋ฆ„} 4. Nginx ์›น ์„œ๋ฒ„์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  SSL ์„ค์ • ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ๋‹ค์šด ๋ฐ›์€ ํ›„ ํŒŒ์ผ์„ ์•Œ๋งž์€ ์œ„์น˜๋กœ ์ด๋™์‹œํ‚จ๋‹ค. ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์—์„œ๋Š” /etc/letsencrypt/๋กœ ์ด๋™์‹œ์ผฐ๋‹ค. 1sudo curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "./options-ssl-nginx.conf" 2 3sudo curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "./ssl-dhparams.pem" 5. nginx.conf๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค. ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ถ”๊ฐ€ํ•˜์˜€๋‹ค. server { listen 80; charset utf-8; server_name {๋„๋ฉ”์ธ ์ด๋ฆ„}; # HTTP ์š”์ฒญ์„ HTTPS๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; charset utf-8; server_name { ๋„๋ฉ”์ธ ์ด๋ฆ„ }; # SSL ์ธ์ฆ์„œ ์„ค์ • ssl_certificate /etc/letsencrypt/live/api.forest-of-thoughts.site/fullchain.pem; # SSL ์ธ์ฆ์„œ ํ‚ค ์„ค์ • ssl_certificate_key /etc/letsencrypt/live/api.forest-of-thoughts.site/privkey.pem; # SSL ์„ค์ • ํŒŒ์ผ ํฌํ•จ include /etc/letsencrypt/options-ssl-nginx.conf; # Diffie-Hellman ํ‚ค ์„ค์ • ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } 6. nginx ์ปจํ…Œ์ด๋„ˆ ์„ค์ •์„ ์ˆ˜์ •ํ•œ๋‹ค. 1nginx: 2 image: nginx:stable 3 ports: 4 - "80:80" 5 - "443:443" 6 volumes: 7 - ./nginx.conf:/etc/nginx/nginx.conf 8 - ./certbot/conf:/etc/letsencrypt 9 - ./certbot/www:/var/www/certbot ํ•ด ํšŒ๊ณ  ๋ณดํ†ต crontab์„ ํ™œ์šฉํ•ด์„œ ์ž๋™์œผ๋กœ ์ธ์ฆ์„œ ๊ฐฑ์‹ ์„ ๋ฐ›๋Š”๋‹ค. ์ด๋ฒˆ์—๋Š” ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„์ด ๊ธธ์ง€ ์•Š์•„์„œ, ์ˆ˜๋™์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋‹ค. ๋‹ค์Œ์—๋Š” ์ž๋™์œผ๋กœ ์ธ์ฆ์„œ ๊ฐฑ์‹ ์„ ๋ฐ›๋Š” ๊ฒƒ๋„ ๋„์ „ํ•ด๋ณด์ž.
new Issue - yaml ๋ฌธ์ž์—ด ์† colon(์ฝœ๋ก )
๐ŸŽธ ๊ธฐํƒ€
๋ฌธ์ œ์ƒํ™ฉ TIL ๋ธ”๋กœ๊ทธ ์ž๋™ ๋ฐฐํฌ github action ์ฝ”๋“œ์— yaml ํŒŒ์ผ์— ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค ์ถ”๊ฐ€ํ•˜๋Š” ๋ฌธ์ž์—ด์— ์ฝœ๋ก ์ด ํฌํ•จ๋˜์–ด ์žˆ์–ด์„œ action์—์„œ ์—๋Ÿฌ๋ฅผ ๋„์› ๋‹ค ๋ฌธ์ œ์˜ ์ฝ”๋“œ 1- name: Add google analytics id 2 run: echo -e "\nparams:\n googleAnalytics : \"$GA_TRACKING_ID\"" >> config.yaml ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ์šฐ์—ฌ๊ณก์ ˆ ๋์— ์œ„์™€ ๊ฐ™์ด 2์ค„๋กœ ๋‚˜๋ˆ„์–ด์„œ ํ•ด๊ฒฐํ–ˆ๋‹ค 1 - name: Add google analytics id 2 run: | 3 echo -e "\nparams:" >> config.yaml 4 echo -e " googleAnalytics: \"$GA_TRACKING_ID\"" >> config.yaml
new [๋ชจ๊ฐ์ฝ”24ํ•˜๊ณ„] 01 : ๊ฒฐ๊ณผ
๐Ÿ‘จโ€๐Ÿ’ป ๋ชจ๊ฐ์ฝ”
django์—์„œ swagger ๋ฌธ์„œํ™” ๊ตฌํ˜„ํ•˜๊ธฐ ๊ฐœ์š” ์žฅ๊ณ  ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ์ ์ธ CRUD ๊ธฐ๋Šฅ๊ณผ, REST API๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž. ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ 1. 2โ”œโ”€โ”€ db.sqlite3 3โ”œโ”€โ”€ djtest (๋ฉ”์ธ ์•ฑ) 4โ”‚ โ”œโ”€โ”€ __init__.py 5โ”‚ โ”œโ”€โ”€ asgi.py 6โ”‚ โ”œโ”€โ”€ settings.py 7โ”‚ โ”œโ”€โ”€ urls.py 8โ”‚ โ”œโ”€โ”€ views.py 9โ”‚ โ””โ”€โ”€ wsgi.py 10โ”œโ”€โ”€ manage.py 11โ”œโ”€โ”€ paste (์ƒ์„ฑํ•œ ์•ฑ) 12โ”‚ โ”œโ”€โ”€ __init__.py 13โ”‚ โ”œโ”€โ”€ admin.py 14โ”‚ โ”œโ”€โ”€ apps.py 15โ”‚ โ”œโ”€โ”€ migrations 16โ”‚ โ”œโ”€โ”€ models.py 17โ”‚ โ”œโ”€โ”€ serializers.py 18โ”‚ โ”œโ”€โ”€ tests.py 19โ”‚ โ”œโ”€โ”€ urls.py 20โ”‚ โ””โ”€โ”€ views.py 21โ””โ”€โ”€ requirements.txt ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” Django ๋ช…๋ น์ž 1# ์ƒˆ๋กœ์šด Django ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑ 2python manage.py startproject 3# ์ƒˆ๋กœ์šด Django ์•ฑ์„ ์ƒ์„ฑ 4python manage.py startapp 5# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ์šฉํ•  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์„ ์ƒ์„ฑ 6python manage.py makemigrations 7# ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์„ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ์šฉ 8python manage.py migrate 9# ๊ด€๋ฆฌ์ž(superuser) ๊ณ„์ •์„ ์ƒ์„ฑ 10python manage.py createsuperuser 11# ํ”„๋กœ์ ํŠธ์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์‹คํ–‰ 12python manage.py test 13# ํ…Œ์ŠคํŠธ์šฉ ์„œ๋ฒ„๋ฅผ ํŠน์ • ์„ค์ •์œผ๋กœ ์‹คํ–‰ 14python manage.py testserver CRUD ๊ตฌํ˜„ Paste ๋ชจ๋ธ ์ •์˜ 1from django.db import models 2 3class Paste(models.Model): 4 title = models.CharField(max_length=100) 5 content = models.TextField() 6 # auto_now_add : ๊ฐ์ฒด๊ฐ€ ์ฒ˜์Œ ์ƒ์„ฑ๋  ๋•Œ๋งŒ ํ˜„์žฌ ๋‚ ์งœ์™€ ์‹œ๊ฐ„์„ ์ž๋™์œผ๋กœ ์„ค์ • 7 created_at = models.DateTimeField(auto_now_add=True) 8 # auto_now : ๊ฐ์ฒด๊ฐ€ ์ €์žฅ๋  ๋•Œ๋งˆ๋‹ค ํ˜„์žฌ ๋‚ ์งœ์™€ ์‹œ๊ฐ„์„ ์ž๋™์œผ๋กœ ์„ค์ • 9 updated_at = models.DateTimeField(auto_now=True) 10 class Meta: 11 ordering = ['-created_at'] 12 def __str__(self): 13 return self.title Serializer ์ •์˜ 1from rest_framework import serializers 2from .models import Paste 3 4class PasteSerializer(serializers.ModelSerializer): 5 class Meta: 6 model = Paste 7 fields = '__all__' 8 # ์ง์ ‘ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ• 9 # fields = ['title', 'content'] View ๊ตฌํ˜„ PasteView 1class PasteView(APIView): 2 def get(self, _): 3 pastes = Paste.objects.all() 4 serializer = PasteSerializer(pastes, many=True) 5 return Response(serializer.data, status=status.HTTP_200_OK) 6 7 def post(self, request): 8 serializer = PasteSerializer(data=request.data) 9 if serializer.is_valid(): 10 serializer.save(user=request.user) 11 return Response(serializer.data, status=status.HTTP_201_CREATED) 12 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) PasteDetailView 1class PasteDetailView(APIView): 2 def get(self, _, pk): 3 try: 4 paste = Paste.objects.get(pk=pk) 5 serializer = PasteSerializer(paste) 6 return Response(serializer.data, status=status.HTTP_200_OK) 7 except Paste.DoesNotExist: 8 return Response(status=status.HTTP_404_NOT_FOUND) 9 10 def put(self, request, pk): 11 try: 12 paste = Paste.objects.get(pk=pk) 13 except Paste.DoesNotExist: 14 return Response(status=status.HTTP_404_NOT_FOUND) 15 16 if paste.user != request.user: 17 return Response(status=status.HTTP_403_FORBIDDEN) 18 19 serializer = PasteSerializer(paste, data=request.data) 20 if serializer.is_valid(): 21 serializer.save() 22 return Response(serializer.data, status=status.HTTP_200_OK) 23 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 24 25 def delete(self, request, pk): 26 try: 27 paste = Paste.objects.get(pk=pk) 28 except Paste.DoesNotExist: 29 return Response(status=status.HTTP_404_NOT_FOUND) 30 31 paste.delete() 32 return Response(status=status.HTTP_204_NO_CONTENT) urls.py 1from django.urls import path 2from paste.views import * 3 4urlpatterns = [ 5 path('', PasteView.as_view(), name='paste_list_create'), 6 path('<int:pk>', PasteDetailView.as_view(), name='paste_get_update_delete'), 7] Swagger ์ ์šฉ PasteView PasteView 1class PasteView(APIView): 2 @swagger_auto_schema( 3 operation_description="Get list of pastes", 4 operation_summary="Get list of pastes", 5 responses={200: PasteSerializer(many=True)}, 6 ) 7 def get(self, _): 8 ... 9 10 @swagger_auto_schema( 11 operation_description="Create a new paste", 12 operation_summary="Create a new paste", 13 request_body=PasteSerializer, 14 responses={201: PasteSerializer, 400: "Bad Request"}, 15 ) 16 def post(self, request): 17 ... PasteDetailView 1class PasteDetailView(APIView): 2 @swagger_auto_schema( 3 operation_description="Get a paste by ID", 4 operation_summary="Get a paste by ID", 5 responses={200: PasteSerializer, 404: "Not Found"}, 6 ) 7 def get(self, _, pk): 8 ... 9 10 @swagger_auto_schema( 11 operation_description="Update a paste by ID", 12 operation_summary="Update a paste by ID", 13 request_body=PasteSerializer, 14 responses={ 15 200: PasteSerializer, 16 400: "Bad Request", 17 403: "Forbidden", 18 404: "Not Found", 19 }, 20 ) 21 def put(self, request, pk): 22 ... 23 24 @swagger_auto_schema( 25 operation_description="Delete a paste by ID", 26 operation_summary="Delete a paste by ID", 27 responses={204: "No Content", 404: "Not Found"}, 28 ) 29 def delete(self, request, pk): 30 ... swagger ์ ์šฉ ๊ฒฐ๊ณผ django์—์„œ JWT ์ธ์ฆ ๊ตฌํ˜„ํ•˜๊ธฐ ์žฅ๊ณ ์—์„œ๋Š” djangorestframework-simplejwt ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JWT ์ธ์ฆ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. requirements 1pip install djangorestframework-simplejwt settings.py 1INSTALLED_APPS = [ 2 ... 3 'rest_framework', 4 'rest_framework_simplejwt', 5] 1REST_FRAMEWORK = { 2 # ๊ธฐ๋ณธ ์ธ์ฆ ํด๋ž˜์Šค๋ฅผ ์„ค์ • 3 'DEFAULT_AUTHENTICATION_CLASSES': ( 4 'rest_framework_simplejwt.authentication.JWTAuthentication', 5 ), 6 # ๊ธฐ๋ณธ ์Šคํ‚ค๋งˆ ํด๋ž˜์Šค๋ฅผ ์„ค์ •, CoreAPI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž๋™์œผ๋กœ API ๋ฌธ์„œํ™”๋ฅผ ์ƒ์„ฑ 7 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema', 8 # ๊ธฐ๋ณธ ๊ถŒํ•œ ํด๋ž˜์Šค๋ฅผ ์„ค์ •, AllowAny๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ์š”์ฒญ์„ ํ—ˆ์šฉ 9 'DEFAULT_PERMISSION_CLASSES': ( 10 'rest_framework.permissions.AllowAny', 11 ), 12} 1from datetime import timedelta 2 3SIMPLE_JWT = { 4 # ์•ก์„ธ์Šค ํ† ํฐ์˜ ์œ ํšจ ๊ธฐ๊ฐ„์„ ์„ค์ • 5 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30), 6 # ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์˜ ์œ ํšจ ๊ธฐ๊ฐ„์„ ์„ค์ • 7 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), 8 # ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์ด ๊ฐฑ์‹ ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ • 9 'ROTATE_REFRESH_TOKENS': False, 10 # ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์ด ๊ฐฑ์‹ ๋œ ํ›„ ์ด์ „ ํ† ํฐ์„ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ • 11 'BLACKLIST_AFTER_ROTATION': True, 12 13 # JWT ํ† ํฐ์˜ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ค์ • 14 'ALGORITHM': 'HS256', 15 # JWT ํ† ํฐ์„ ์„œ๋ช…ํ•  ๋•Œ ์‚ฌ์šฉํ•  ํ‚ค๋ฅผ ์„ค์ • 16 'SIGNING_KEY': SECRET_KEY, 17 # ํ† ํฐ ๊ฒ€์ฆ์— ์‚ฌ์šฉํ•  ๊ณต๊ฐœ ํ‚ค๋ฅผ ์„ค์ • 18 'VERIFYING_KEY': None, 19 # ํ† ํฐ์˜ ๋Œ€์ƒ์ž(aud) ํด๋ ˆ์ž„์„ ์„ค์ • 20 'AUDIENCE': None, 21 # ํ† ํฐ์˜ ๋ฐœ๊ธ‰์ž(iss) ํด๋ ˆ์ž„์„ ์„ค์ • 22 'ISSUER': None, 23 24 # ์ธ์ฆ ํ—ค๋” ํƒ€์ž…์„ ์„ค์ • 25 'AUTH_HEADER_TYPES': ('Bearer',), 26 # ์ธ์ฆ ํ—ค๋”์˜ ์ด๋ฆ„์„ ์„ค์ • 27 'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION', 28 # ์‚ฌ์šฉ์ž ๋ชจ๋ธ์—์„œ ์‚ฌ์šฉ์ž ID ํ•„๋“œ๋ฅผ ์„ค์ • 29 'USER_ID_FIELD': 'id', 30 # JWT ํ† ํฐ์—์„œ ์‚ฌ์šฉ์ž ID๋ฅผ ์ €์žฅํ•  ํด๋ ˆ์ž„์„ ์„ค์ • 31 'USER_ID_CLAIM': 'user_id', 32 33 # ์ธ์ฆ์— ์‚ฌ์šฉํ•  ํ† ํฐ ํด๋ž˜์Šค๋“ค์„ ์„ค์ • 34 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',), 35 # ํ† ํฐ์˜ ์œ ํ˜•์„ ์ €์žฅํ•  ํด๋ ˆ์ž„์„ ์„ค์ • 36 'TOKEN_TYPE_CLAIM': 'token_type', 37} urls.py 1from django.urls import path 2from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView 3from rest_framework_simplejwt.authentication import JWTAuthentication 4 5urlpatterns = [ 6 # JWT ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•˜๋Š” ๋ทฐ 7 path("token/", TokenObtainPairView.as_view(), name="token_obtain_pair"), 8 # JWT ํ† ํฐ์„ ๊ฐฑ์‹ ํ•˜๋Š” ๋ทฐ 9 path("token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), 10] views.py 1from rest_framework import permissions 2from rest_framework_simplejwt.authentication import JWTAuthentication 3from drf_yasg.utils import swagger_auto_schema 4 5 6class PasteView(APIView): 7 8 def get(self, request): 9 ... 10 11 def post(self, request): 12 ... 13 14 def get_permissions(self): 15 # SAFE_METHODS : GET, HEAD, OPTIONS 16 if self.request.method in permissions.SAFE_METHODS: 17 self.permission_classes = [permissions.AllowAny] 18 else: 19 self.authentication_classes = [JWTAuthentication] 20 self.permission_classes = [permissions.IsAuthenticated] 21 return super().get_permissions() 22 23 24class PasteDetailView(APIView): 25 26 def get(self, request, pk): 27 ... 28 29 def put(self, request, pk): 30 ... 31 32 def delete(self, request, pk): 33 ... 34 35 def get_permissions(self): 36 # SAFE_METHODS : GET, HEAD, OPTIONS 37 if self.request.method in permissions.SAFE_METHODS: 38 self.permission_classes = [permissions.AllowAny] 39 else: 40 self.authentication_classes = [JWTAuthentication] 41 self.permission_classes = [permissions.IsAuthenticated] 42 return super().get_permissions() ๊ฒฐ๊ณผ TokenObtainPairView๋ฅผ ํ†ตํ•ด access token๊ณผ refresh token์„ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. TokenRefreshView๋ฅผ ํ†ตํ•ด refresh token์„ ์‚ฌ์šฉํ•˜์—ฌ access token์„ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค. access token๊ณผ refresh token์€ settings.py์—์„œ ์„ค์ •ํ•œ ์œ ํšจ ๊ธฐ๊ฐ„์— ๋”ฐ๋ผ ๋งŒ๋ฃŒ๋œ๋‹ค. Blacklist ์ ์šฉ settings.py 1INSTALLED_APPS = [ 2 ... 3 'rest_framework_simplejwt.token_blacklist', 4] 1SIMPLE_JWT = { 2 ... 3 # ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ํ† ํฐ์„ ์ถ”๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉํ•  ๋ชจ๋ธ์„ ์„ค์ • 4 'BLACKLIST_AFTER_ROTATION': True, 5} ๊ฒฐ๊ณผ TokenRefreshView๋ฅผ ํ†ตํ•ด ํ† ํฐ์ด ์žฌ๋ฐœ๊ธ‰๋  ๋•Œ, ์ด์ „ refresh token์„ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•œ๋‹ค.
new Fastapi - ํ†ตํ•ฉํ…Œ์ŠคํŠธ In-Memory DB์—์„œ ํ…Œ์ด๋ธ”์ด ์—†๋‹ค๋Š” ๋ฌธ์ œ
๐Ÿ Python
์ƒํ™ฉ ํ…Œ์ปค ๋ถ€ํŠธ์บ ํ”„์—์„œ ํŒ€ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ ์ค‘์ด๋‹ค. ๋‹จ์œ„ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์ž‘์„ฑ์ด ์™„๋ฃŒ๋˜์—ˆ๊ณ , ํ†ตํ•ฉํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑ ์ค‘์ด๋‹ค. sqlite in-memory db๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ…Œ์ŠคํŠธ ์ค‘์ธ๋ฐ, ํ…Œ์ด๋ธ”์ด ์—†๋‹ค๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ „์— ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ธ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์•„๋‹Œ ํŒŒ์ผ๋กœ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ๋ฌธ์ œ์˜ ์›์ธ์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ฝ”๋“œ 1from database import Base, engine 2from fastapi.testclient import TestClient 3 4from main import app 5from models import * 6 7# ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค 8Base.metadata.create_all(bind=engine) 9 10client = TestClient(app) 11 12 13class TestUserApi: 14 15 def test_create_user(self): 16 test_nickname = "test_nickname" 17 # ์•„๋ž˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค 18 response = client.post( 19 "/api/users", 20 json={"nickname": test_nickname}, 21 ) 22 assert response.status_code == 200 23 assert response.json()["nickname"] == test_nickname ์›์ธ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ• ๋•Œ ๋งŒ๋“ค์–ด์ง€๋Š” ์„ธ์…˜๊ณผ TestClient๊ฐ€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์„ธ์…˜์ด ๋‹ค๋ฅด๋‹ค. ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• TestClient๋‚ด์— get_db() ํ•จ์ˆ˜๋ฅผ ์ž„์˜๋กœ ์ฃผ์ž…ํ•œ๋‹ค ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์—ฐ๊ฒฐํ• ๋•Œ, ๋‹จ์ผ ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•œ๋‹ค. 1from database import Base, engine, get_db 2from sqlalchemy.orm import sessionmaker 3from fastapi.testclient import TestClient 4 5from main import app 6from models import * 7 8Base.metadata.create_all(bind=engine) 9 10client = TestClient(app) 11 12# ํ…Œ์ŠคํŠธ์—์„œ ์‚ฌ์šฉํ•  ์„ธ์…˜์„ ์ƒ์„ฑํ•œ๋‹ค 13TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) 14 15 16Base.metadata.create_all(bind=engine) 17 18# get_db() ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•œ๋‹ค 19def override_get_db(): 20 try: 21 db = TestingSessionLocal() 22 yield db 23 finally: 24 db.close() 25 26# get_db() ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•œ ํ•จ์ˆ˜๋ฅผ ์ฃผ์ž…ํ•œ๋‹ค 27app.dependency_overrides[get_db] = override_get_db 28 29 30class TestUserApi: 31 32 def test_create_user(self): 33 test_nickname = "test_nickname" 34 response = client.post( 35 "/api/users", 36 json={"nickname": test_nickname}, 37 ) 38 assert response.status_code == 201 39 assert response.json()["nickname"] == test_nickname 1engine = create_engine( 2 os.getenv("DATABASE_URL"), 3 # sqlite๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ์—ฐ๊ฒฐ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค์ •ํ•œ๋‹ค 4 connect_args={"check_same_thread": False}, 5 # ๋‹จ์ผ ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ•œ๋‹ค 6 poolclass=StaticPool, 7)
new Issue - fastapi์—์„œ websocket 404 ๋ฌธ์ œ
๐Ÿ Python
๋ฐฐ๊ฒฝ ํ…Œ์ปค ๋ถ€ํŠธ์บ ํ”„ ์ตœ์ข…๋ฐœํ‘œ ์ „๋‚ ์ด๋‹ค. gpt ํ”„๋กฌํ”„ํŠธ ๋ถ€๋ถ„ ์ˆ˜์ •์„ main ๋ธŒ๋žœ์น˜์— ๋ฐ˜์˜ํ•˜๊ณ , EC2 ์„œ๋ฒ„์— ๋ฐฐํฌํ–ˆ๋‹ค. ๋ฌธ์ œ ๋ฐฐํฌํ•œ ์„œ๋ฒ„์—์„œ websocket ์—ฐ๊ฒฐ์ด 404 ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (๋‚ด์ผ์ด ์ตœ์ข… ๋ฐœํ‘œ์ธ๋ฐ,,,) ๋‹ค๋ฅธ http ์š”์ฒญ์€ ์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์ง€๋งŒ ์›น์†Œ์ผ“๋งŒ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค. nginx์˜ log 1{IP์ฃผ์†Œ} - - [02/Aug/2024:10:59:04 +0000] "GET /ws/chatrooms/294?user_id=296 HTTP/1.1" 404 22 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15" 2{IP์ฃผ์†Œ} - - [02/Aug/2024:10:59:05 +0000] "GET /ws/chatrooms/294?user_id=296 HTTP/1.1" 404 22 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15" ์‚ฌ๊ณ ํ๋ฆ„ nginx ์„ค์ • ๋ฌธ์ œ์ธ๊ฐ€? X nginx ์„ค์ •์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค. ๋ฐฐํฌํ™˜๊ฒฝ์˜ ๋ฌธ์ œ์ธ๊ฐ€? X ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•œ ์„œ๋ฒ„์—์„œ๋„ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค. ์ด๋ฒˆ ๋ฐฐํฌ์—์„œ ๋ณ€๊ฒฝ๋œ ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ๋ฌธ์ œ์ธ๊ฐ€? X ์œก์•ˆ์œผ๋กœ ํ™•์ธํ–ˆ์„ ๋•Œ๋Š”, ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„์ด ์›น์†Œ์ผ“๊ณผ ๊ด€๋ จ์ด ์—†๋‹ค. ๋กœ์ปฌ์—์„œ ์ด์ „ ๋ฒ„์ „์œผ๋กœ reset ํ›„ ์‹œ๋„ ํ•ด๋ณด์•˜์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜๋‹ค. Docker image ๋ฌธ์ œ์ธ๊ฐ€? X ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋Š” python:slim ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ํ•ด๋‹น ์ด๋ฏธ์ง€๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ๋กœ์ปฌ์—์„œ docker image๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์‹คํ–‰ํ•ด๋ณด์•˜์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜๋‹ค. ์ด๋•Œ, ๋กœ๊ทธ์—์„œ warning ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ–ˆ๋‹ค. WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually. ์›์ธ ๋ชจ์ข…์˜ ์ด์œ ๋กœ, ์ด์ „์— ๊ฐœ๋ฐœ/๋ฐฐํฌํ• ๋•Œ์—๋Š” ์กด์žฌํ–ˆ๋˜ ์›น์†Œ์ผ“ ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‚ฌ๋ผ์ง„ ๊ฒƒ์ด๋‹ค. ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์กฐ์‚ฌํ•ด๋ณธ ๊ฒฐ๊ณผ fastapi ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— 6์‹œ๊ฐ„ ์ „ merge๋œ PR์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. (https://github.com/fastapi/fastapi/pull/11935) ํ•ด๋‹น PR์—์„œ๋Š” pip install fastapi[standard] ๋ฅผ ํ†ตํ•ด ํ‘œ์ค€ ์ข…์† ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค. ์ด๋กœ ์ธํ•ด, uvicorn[standard] ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜์ง€ ์•Š์•˜์„ ๋•Œ, ์›น์†Œ์ผ“ ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์„ค์น˜๋˜์ง€ ์•Š์•„ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์˜€๋‹ค. ํ•ด๊ฒฐ requirements.txt์— websockets๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋ฐฐ์šด ์  ์ค‘์š”ํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•  ๋•Œ requirements.txt์— ํ•ญ์ƒ ๊ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋ฒ„์ „์„ ๋ช…์‹œํ•ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค. ์ด๋ฒˆ์—๋„ ๋ฒ„์ „์„ ๋ช…์‹œํ–ˆ๋‹ค๋ฉด, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜๋”๋ผ๋„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜์„ ๊ฒƒ์ด๋‹ค. ๋˜ํ•œ, ๋กœ๊ทธ๋ฅผ ์ž˜ ํ™•์ธํ•˜๊ณ , warning ๋ฉ”์‹œ์ง€๋ฅผ ๋†“์น˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ด์•ผ๊ฒ ๋‹ค.
new Spring ๊ฐœ๋… - DI (Dependency Injection)
๐Ÿƒ Spring
์˜์กด ์ฃผ์ž… (DI : Dependency Injection)์„ ํ•˜๋Š” ๋ฐฉ๋ฒ• Assembler๋ผ๋Š” ๋ณ„๋„์˜ ํด๋ž˜์Šค ์ƒ์„ฑ 1public class Assembler { 2 private MemberDao memberDao; 3 private MemberRegisterService regSvc; 4 5 public Assembler() { 6 memberDao = new MemberDao(); 7 regSvc = new MemberRegisterService(memberDao); 8 } 9 10 public MemberDao getMemberDao() { 11 return memberDao; 12 } 13 14 public MemberRegisterService getMemberRegisterService() { 15 return regSvc; 16 } 17} Spring์—์„œ ์ง€์›ํ•˜๋Š” DI ์‚ฌ์šฉ 1@Configuration 2public class AppCtx { 3 @Bean 4 public MemberDao memberDao() { 5 return new MemberDao(); 6 } 7 @Bean 8 public MemberRegisterService memberRegSvc() { 9 return new MemberRegisterService(memberDao()); 10 } 11} DI ๋ฐฉ์‹ Constructor ๋ฐฉ์‹ 1@Bean 2 public MemberListPrinter listPrinter() { 3 return new MemberListPrinter(memberDao(), memberPrinter()); 4 } Setter method ๋ฐฉ์‹ 1@Bean 2public MemberInfoPrinter infoPrinter() { 3 MemberInfoPrinter infoPrinter = new MemberInfoPrinter(); 4 infoPrinter.setMemberDao(memberDao()); 5 infoPrinter.setPrinter(memberPrinter()); 6 return infoPrinter; 7} constructor ๋ฐฉ์‹์ด ํ›จ์”ฌ ๊น”๋”ํ•ด๋ณด์ธ๋‹ค. java bean์—์„œ๋Š” getter์™€ setter๋ฅผ ์ด์šฉํ•ด์„œ property๋ฅผ ์ •์˜ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋‘ ๊ฐœ ์ด์ƒ์˜ Configuration ํŒŒ์ผ ์‚ฌ์šฉ : @Autowired ํ™œ์šฉ AppConf1.java 1@Configuration 2public class AppConf1 { 3 ... 4} AppConf2.java 1import org.springframework.beans.factory.annotation.Autowired; 2 3@Configuration 4public class AppConf2 { 5 @Autowired 6 private MemberDao memberDao; 7 @Autowired 8 private MemberPrinter memberPrinter; 9 10 ... 11} MainForSpring.java 1ctx = new AnnotationConfigApplicationContext(AppConf1.class, AppConf2.class); Autowired annotation์„ ํ†ตํ•ด ๋‹ค๋ฅธ ์„ค์ • ํŒŒ์ผ์˜ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๋‘ ๊ฐœ ์ด์ƒ์˜ Configuration ํŒŒ์ผ ์‚ฌ์šฉ : @Import ํ™œ์šฉ AppConfImport.java 1import org.springframework.context.annotation.Import; 2 3@Configuration 4@Import(AppConf2.class) 5public class AppConfImport { MainForSpring.java 1ctx = new AnnotationConfigApplicationContext(AppConfImport.class); 2// ํด๋ž˜์Šค ํ•œ ๊ฐœ๋งŒ ๋ช…์‹œํ•ด์ค˜๋„ ๊ฐ€๋Šฅ ํƒ€์ž…๋งŒ์œผ๋กœ ๋นˆ์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค 1VersionPrinter versionPrinter = ctx.getBean(MemberPrinter.class); ๋‹ค๋งŒ, ๊ฐ™์€ ํƒ€์ž…์˜ ๋นˆ ๊ฐ์ฒด๊ฐ€ 2๊ฐœ ์ด์ƒ ์กด์žฌํ•œ๋‹ค๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒ
new Spring ๊ฐœ๋… - Testing
๐Ÿƒ Spring
Unit Test (๋‹จ์œ„ ํ…Œ์ŠคํŠธ) ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„ (ํด๋ž˜์Šค ๋˜๋Š” ๋ฉ”์†Œ๋“œ)๋ฅผ ๊ณ ๋ฆฝ์‹œ์ผœ์„œ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ์‹ ๊ด€๋ จ ์šฉ์–ด SUT (Sytem Under Test) ํ…Œ์ŠคํŠธํ•˜๊ณ ์žํ•˜๋Š” ์ฃผ์š” ๋Œ€์ƒ์ด ๋˜๋Š” Unit DOC (Depended On Component) SUT๊ฐ€ ์˜์กดํ•˜๋Š” ๊ฐ์ฒด Test double DOC๋ฅผ ๋Œ€์‹ ํ•ด ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด Test double์˜ ์ข…๋ฅ˜ : Mock, Stub Mock ํ–‰์œ„ ๊ฒ€์ฆ (๊ฐ์ฒด๊ฐ€ ํŠน์ • ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š”์ง€ ๊ฒ€์ฆ) ์‚ฌ์šฉ test framework : Mockito, JMock, EasyMock Stub ์ƒํƒœ ๊ฒ€์ฆ (๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜์—ฌ ๊ฒ€์ •) ์‚ฌ์šฉ Integration Test (ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ) ์—ฌ๋Ÿฌ ๊ฐœ์˜ Unit์„ ํ†ตํ•ฉํ•ด์„œ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ์‹ JUnit ๋งค ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋งˆ๋‹ค ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑ -> ๋…๋ฆฝ์ ์ธ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ Annotation ์ œ๊ณต -> ํ…Œ์ŠคํŠธ life cycle ๊ด€๋ฆฌ assert ๋ฉ”์†Œ๋“œ ์ œ๊ณต -> ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ํŒ๋ณ„ JUnit5 = JUnit Platform + JUnit Jupiter + JUnit Vintage JUnit Platform : JVM ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŒ… ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ธฐ ์œ„ํ•œ ๊ธฐ๋ฐ˜ ๋ชจ๋“ˆ JUnit Jupiter : JUnit5๋ฅผ ์œ„ํ•œ Test Engine API ์ œ๊ณต JUnit Vintage : JUnit3, JUnit4๋ฅผ ์œ„ํ•œ Test Engine API ์ œ๊ณต org.junit.jupiter.api.Assertions.* assertEquals 1assertEquals(0, 1+1); assertThrows, assertAll org.hamcrest.MatcherAssert.* assertThat 1// assertEquals ๋ณด๋‹ค ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค 2assertThat(1+1, equalTo(2)); org.hamcrest.Matchers.* equalTo, is, not anyOf, everyItem hasSize, containsInAnyOrder, hasItem (collection์— ๋Œ€ํ•ด ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ง€์›ํ•œ๋‹ค)
new 221207 SYSP
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
09-process1 ์˜ˆ์™ธ์ ์ธ ์ œ์–ด ํ๋ฆ„ ํ•˜์œ„ ๋งค์ปค๋‹ˆ์ฆ˜ ์˜ˆ์™ธ (Exception) ์ƒ์œ„ ๋งค์ปค๋‹ˆ์ฆ˜ ํ”„๋กœ์„ธ์Šค ์ปจํ…์ŠคํŠธ ์ „ํ™˜ OS ์†Œํ”„ํŠธ์›จ์–ด์™€ ํ•˜๋“œ์›จ์–ด ํƒ€์ด๋จธ๋กœ ๊ตฌํ˜„ ์‹œ๊ทธ๋„ OS ์†Œํ”„ํŠธ์›จ์–ด๋กœ ๊ตฌํ˜„ nolocal ์ ํ”„ ์˜ˆ์™ธ ํ…Œ์ด๋ธ” (Exception Tables) ๊ฐ ์ด๋ฒคํŠธ ํƒ€์ž…์€ ์˜ˆ์™ธ๋ฒˆํ˜ธ k๋ฅผ ๊ฐ–๋Š”๋‹ค ๋น„๋™๊ธฐํ˜• ์˜ˆ์™ธ (Interrupt) ์ž…์ถœ๋ ฅ ์ธํ„ฐ๋ŸฝํŠธ (ctrl + c) ํ•˜๋“œ ๋ฆฌ์…‹ ์ธํ„ฐ๋ŸฌํŠธ ์†Œํ”„ํŠธ ๋ฆฌ์…‹ ์ธํ„ฐ๋ŸฝํŠธ ๋™๊ธฐํ˜• ์˜ˆ์™ธ Traps : ๋ช…๋ น์–ด์˜ ๊ฒฐ๊ณผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ์˜๋„์ ์ธ ์˜ˆ์™ธ (syscall) Faults : ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ •์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์—๋Ÿฌ์˜ ๊ฒฐ๊ณผ๋กœ ๋ฐœ์ƒ (page faults) Aborts : ๋ณต๊ตฌ ๋ถˆ๊ฐ€๋Šฅํ•œ ์—๋Ÿฌ์˜ ๊ฒฐ๊ณผ๋กœ ๋ฐœ์ƒ Page Fault ์‚ฌ์šฉ์ž ๋ฉ”๋ชจ๋ฆฌ์˜ ํŠน์ • ํŽ˜์ด์ง€๊ฐ€ ํ˜„์žฌ ํ•˜๋“œ๋””์Šคํฌ์— ์œ„์น˜ํ•˜๋Š” ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌํ›„์— ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ ๋ช…๋ น์–ด๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•œ๋‹ค 1int a [1000]; 2int main () { 3a[500] = 13; 4} Process ํ”„๋กœ์„ธ์Šค : ์šด์˜์ฒด์ œ๊ฐ€ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ํ•œ ์‹คํ–‰ ์˜ˆ ํ”„๋กœ๊ทธ๋žจ์— 2๊ฐœ์˜ ์ค‘์š”ํ•œ ์ถ”์ƒํ™” ์ œ๊ณต ๋…ผ๋ฆฌ์ ์ธ ์ œ์–ด ํ๋ฆ„ : ๊ฐ ํ”„๋กœ๊ทธ๋žจ์ด CPU๋ฅผ ๋…์ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•œ๋‹ค ์‚ฌ์ ์ธ ์ฃผ์†Œ ๊ณต๊ฐ„ : ๊ฐ ํ”„๋กœ๊ทธ๋žจ์ด ์ฃผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋…์ ํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ด๋„๋ก ํ•œ๋‹ค ์–ด๋–ป๊ฒŒ? ํ”„๋กœ์„ธ์Šค์˜ ์‹คํ–‰์ด ์„œ๋กœ ๊ต๋Œ€๋กœ ์‹คํ–‰๋œ๋‹ค ์ฃผ์†Œ๊ณต๊ฐ„์˜ ๊ฐ€์ƒ๋ฉ”๋ชจ๋ฆฌ ์‹œ์Šคํ…œ์— ์˜ํ•ด ๊ด€๋ฆฌ Multiprocessing (๊ณผ๊ฑฐ) ํ˜„์žฌ ๋ ˆ์ง€์Šคํ„ฐ๋“ค์„ ๋ฉ”๋ชจ๋ฆฌ์— ๋ณด๊ด€ ๋‹ค์Œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์Šค์ผ€์ฅด๋ง ๋ณด๊ด€๋œ ๋ ˆ์ง€์Šคํ„ฐ๋“ค์„ ๊ฐ€์ ธ์˜ค๊ณ  ์ฃผ์†Œ๊ณต๊ฐ„์„ ์ „ํ™˜ (context switch) Multiprocessing (ํ˜„๋Œ€) ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ”„๋กœ์„ธ์„œ ๊ฐ ์ฝ”์–ด๋Š” ๋ณ„๋„์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ ๊ฐ€๋Šฅ ๋™์‹œ์„ฑ ํ”„๋กœ์„ธ์Šค ๋‘ ํ”„๋กœ์„ธ์Šค์˜ ์‹คํ–‰์‹œ๊ฐ„์ด ์„œ๋กœ ์ค‘์ฒฉ๋˜๋ฉด -> concurrent ์ค‘์ฒฉ๋˜์ง€ ์•Š๊ณ  ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค๋ฉด -> sequential fork 1int fork(void) ํ˜ธ์ถœํ•˜๋Š” ํ”„๋กœ์„ธ์Šค์™€ ๋™์ผํ•œ ์ƒˆ ํ”„๋กœ์„ธ์Šค ์ƒ์„ฑ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋Š” 0์„ ๋ฆฌํ„ด ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค๋Š” ์ž์‹ ํ”„๋กœ์„ธ์Šค์˜ pid ๋ฆฌํ„ด exit 1void exit(int status) ์ข…๋ฃŒ ์ƒํƒœ status ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์ข…๋ฃŒ (์ •์ƒ์ด๋ฉด 0) atexit() ํ•จ์ˆ˜๋Š” exit ํ•  ๋•Œ ์‹คํ–‰ํ•  ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋ก ์ข€๋น„ (Zombies) ์ข…๋ฃŒ๋˜์—ˆ์ง€๋งŒ, ์•„์ง ์ •๋ฆฌ๋˜์ง€ ์•Š์€ ํ”„๋กœ์„ธ์Šค 1void fork8() { 2if (fork() == 0) { 3 printf("Running child, PID = %d\n", getpid()); 4 while (1) 5 ; 6} 7else { 8 printf("Terminating Parent, PID = %d\n", getpid()); 9 exit(0); 10} 11} 10-process2 wait 1int wait (int *child_status) ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ž์‹ ์˜ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋“ค ์ค‘์— ํ•˜๋‚˜๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์ •์ง€์‹œํ‚จ๋‹ค ๋ฆฌํ„ด๊ฐ’์€ ์ข…๋ฃŒํ•œ ์ž์‹ ํ”„๋กœ์„ธ์Šค์˜ PID child_status != NULL์ธ ๊ฒฝ์šฐ, ์ž์‹ ํ”„๋กœ๊ทธ๋žจ์˜ ์ข…๋ฃŒ ์ด์œ ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ƒํƒœ์ •๋ณด๋ฅผ ๊ฐ–๋Š”๋‹ค example 1pid_t wpid = wait(&child_status); 2if (WIFEXITED(child_status)) 3 printf("Child %d terminated with exit status %d\n", wpid, WEXITSTATUS(child_status)); 4else 5 printf("Child %d terminate abnormally\n", wpid); waitpid 1waitpid(pid, &status, options) pid : ํŠน์ • pid์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค. -1์ด๋ฉด wait()๊ณผ ๋™์ผ options : 0 (์ข…๋ฃŒ๋œ ์ž์‹์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค), WNOHANG(==1 ํ•œ๋ฒˆ๋งŒ ์ฒดํฌ), WUNTRACED(==2, ์ •์ง€๋˜๊ฑฐ๋‚˜ ์ข…๋ฃŒ๋œ ์ž์‹์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค) sleep 1// ์ž๊ธฐ ์ž์‹ ์„ secs์ดˆ ๋™์•ˆ ์ •์ง€ 2unsigned int sleep(unsigned int secs) 3// ํ˜ธ์ถœํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ๊ทธ๋„ ๋ฐ›์„ ๋•Œ ๊นŒ์ง€ ์ž ์žฌ์šด๋‹ค 4int pause(void) execve 1int execve(char *filename, char *argv[], char *envp[]) ์‹คํ–‰ ํŒŒ์ผ filename์„ ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค์˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด์„œ argv๋กœ ํ˜„์žฌ์˜ code, data, stack์„ ๋ฎ์–ด ์”Œ์›€ example 1if ((pid = fork()) == 0) { 2 if (execve(myargv[0], myargv, environ) < 0) { 3 printf("%s: Command not found.\n", myargv[0]); 4 exit(1); 5 } 6} shell ์‚ฌ์šฉ์ž์˜ ๋ช…๋ น์„ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ Utility : file๋กœ ๊ตฌํ˜„๋œ ๋ช…๋ น์–ด Built-in : ์ฝ”๋“œ๋กœ ๊ตฌํ˜„๋œ ๋ช…๋ น์–ด eval 1void eval(char *cmdline) { 2 char *argv[MAXARGS]; 3 int bg; 4 pid_t pid; 5 6 bg = parseline(cmdline, argv); 7 if (!builtin_command(argv)) { 8 if ((pid = fork()) == 0) { 9 if (execve(argv[0], argv, environ) < 0) { 10 printf("%s: Command not found.\n", argv[0]); 11 exit(0); 12 } 13 } 14 15 if (!bg) { 16 int status; 17 if (waitpid(pid, &status, 0) < 0 ) 18 unix_error("waitfg: waitpid error"); 19 } 20 else 21 printf("%d %s", pid, cmdline); 22 } 23} -> ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์ด ์ข…๋ฃŒ๋˜๋ฉด zombie๊ฐ€ ๋œ๋‹ค ํ•ด๊ฒฐ๋ฐฉ๋ฒ• : signal 11-signal Signal ์–ด๋–ค ์ด๋ฒคํŠธ๊ฐ€ ์‹œ์Šคํ…œ์— ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ์•Œ๋ ค์ฃผ๋Š” ์งง์€ ๋ฉ”์‹œ์ง€ Receiving a signal ๋ชฉ์ ์ง€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ๊ทธ๋„์„ ๋ฐ›์„ ๋•Œ, ์–ด๋–ค ํ˜•ํƒœ๋กœ๋“  ๋ฐ˜์‘์„ ํ•˜๋„๋ก ์ปค๋„์— ์˜ํ•ด ์š”๊ตฌ๋ ๋•Œ, ์‹œ๊ทธ๋„์„ ๋ฐ›๋Š”๋‹ค๊ณ  ํ•œ๋‹ค. 3๊ฐ€์ง€ ๋ฐ˜์‘ ๋ฌด์‹œ ๋Œ€์ƒ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ข…๋ฃŒ signal handler๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ์œ ์ €๋ ˆ๋ฒจ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์‹œ๊ทธ๋„์„ ์žก๋Š”๋‹ค ์‹œ๊ทธ๋„์˜ ํŠน์ง• ํ”„๋กœ์„ธ์Šค๋Š” ํŠน์ • ์‹œ๊ทธ๋„์˜ ์ˆ˜์‹ ์„ ๋ธ”๋กํ•  ์ˆ˜ ์žˆ๋‹ค. ๋Œ€๊ธฐํ•˜๋Š” ์‹œ๊ทธ๋„์€ ์ตœ๋Œ€ ํ•œ๋ฒˆ๋งŒ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปค๋„์ด context์— ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋น„ํŠธ๋ฒกํ„ฐ pending : ๋Œ€๊ธฐ ์‹œ๊ทธ๋„๋“ค์„ ํ‘œ์‹œ ๋„์ฐฉํ• ๋•Œ๋งˆ๋‹ค pending๊ฐ’์˜ k๋ฒˆ์งธ ๋น„ํŠธ๋ฅผ 1๋กœ ์„ค์ • ์ˆ˜์‹ ํ• ๋•Œ๋งˆ๋‹ค pending๊ฐ’์˜ k๋ฒˆ์งธ ๋น„ํŠธ๋ฅผ 0์œผ๋กœ ์„ค์ • blocked : ๋ธ”๋ก๋œ ์‹œ๊ทธ๋„๋“ค์„ ํ‘œ์‹œ sigprocmask ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์ด 1๋˜๋Š” 0๋กœ ์„ค์ • ํ”„๋กœ์„ธ์Šค ๊ทธ๋ฃน ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๊ทธ๋ฃน์— ์†ํ•œ๋‹ค ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž์‹์€ ๋ถ€๋ชจ์™€ ๊ฐ™์€ ๊ทธ๋ฃน์— ์†ํ•œ๋‹ค ์‰˜์€ ๊ฐ job๋งˆ๋‹ค ๋ณ„๋„์˜ ํ”„๋กœ์„ธ์Šค ๊ทธ๋ฃน์„ ๋งŒ๋“ ๋‹ค getpgrp() : ํ”„๋กœ์„ธ์Šค์˜ ํ”„๋กœ์„ธ์Šค ๊ทธ๋ฃน์„ ๋ฆฌํ„ด setpgid() : ํ”„๋กœ์„ธ์Šค์˜ ๊ทธ๋ฃน์„ ๋ณ€๊ฒฝ kill kill -9 24818 : SIGKILL์„ pid 24818๋กœ ๋ณด๋ƒ„ kill -9 -24817 : pgid 24871์˜ ๊ฐ ํ”„๋กœ์„ธ์Šค์— SIGKILL์„ ๋ณด๋ƒ„ ํ‚ค๋ณด๋“œ๋กœ๋ถ€ํ„ฐ ์‹œ๊ทธ๋„ ๋ณด๋‚ด๊ธฐ ํ‚ค๋ณด๋“œ๋กœ ctrl+c (ctrl+z)๋ฅผ ๋ˆ„๋ฅด๋ฉด SIGINT(SIGTSTP) ์‹œ๊ทธ๋„์ด ํฌ๊ทธ๋ผ์šด๋“œ ํ”„๋กœ์„ธ์Šค ๊ทธ๋ฃน์˜ ๋ชจ๋“  ์ž‘์—…์œผ๋กœ ์ „์†ก๋œ๋‹ค SIGINT : ๊ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ชจ๋‘ ์ข…๋ฃŒ์‹œํ‚จ๋‹ค. SIGTSTP : ๊ธฐ๋ณธ ๋™์ž‘์€ ๊ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ •์ง€์‹œํ‚จ๋‹ค. ์‹œ๊ทธ๋„ ๋ฐ›๊ธฐ ์ปค๋„์€ pnb = pending & ~blocked ๋ฅผ ๊ณ„์‚ฐ ๊ฐ ์‹œ๊ทธ๋„ ํƒ€์ž…์€ ์‚ฌ์ „์— ์ •์˜๋œ ๊ธฐ๋ณธ ๋™์ž‘์„ ๊ฐ€์ง„๋‹ค. ๊ธฐ๋ณธ ๋™์ž‘์€ signalํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•œ๋‹ค (SIGSTOP๊ณผ SIGKILL์€ ์˜ˆ์™ธ) ์‹œ๊ทธ๋„ ํ•ธ๋“ค๋Ÿฌ์˜ ์„ค์น˜ 1handler_t *signal(int signum, handler_t *handler) handler์˜ ๊ฐ’ SIG_IGN : signum ํƒ€์ž… ์‹œ๊ทธ๋„ ๋ฌด์‹œ SIG_DFL : signum์˜ ๊ธฐ๋ณธ๋™์ž‘์œผ๋กœ ๋ณต๊ท€ ์ด์™ธ์˜ ๊ฒฝ์šฐ : signal handler์˜ ์ฃผ์†Œ ์‹œ๊ทธ๋„ ๋ธ”๋กํ•˜๊ธฐ์™€ ํ•ด์ œํ•˜๊ธฐ sigprocmask ์ด์šฉ 1int sigprocmask(int how, const sigset_t *set, sigset_t *oldest); how๊ฐ’์— ๋”ฐ๋ผ ๋™์ž‘์ด ๊ฒฐ์ •๋œ๋‹ค SIG_BLOCK : blocked = (blocked | set) SIG_UNBLOCK : blocked = blocked & ~set SIG_SETMASK : blocked = set set ๊ด€๋ จ ์ง€์› ํ•จ์ˆ˜ sigemptyset : ๋ชจ๋“  ์‹œ๊ทธ๋„์ด ๋น„์–ด์žˆ๋Š” ์ง‘ํ•ฉ ์ƒ์„ฑ sigfillset : ๋ชจ๋“  ์‹œ๊ทธ๋„ ๋ฒˆํ˜ธ๋ฅผ 1๋กœ ์„ค์ • sigaddset : ํŠน์ • ์‹œ๊ทธ๋„ ๋ฒˆํ˜ธ๋ฅผ 1๋กœ ์„ค์ • sigdelset : ํŠน์ • ์‹œ๊ทธ๋„ ๋ฒˆํ˜ธ๋ฅผ 0์œผ๋กœ ์„ค์ • ๊ฒฝ์ฃผ Race ํ˜„์ƒ์œผ๋กœ ์ธํ•œ ๋™๊ธฐํ™”์˜ ๋ฌธ์ œ 1void handler(int sig) { 2 int olderrno = errno; 3 sigset_t mask_all, prev_all; 4 pid_t pid; 5 6 sigfillset(&mask_all); 7 while ((pid = waitpid(-1, NULL, 0)) > 0 ) { 8 sigprocmask(SIG_BLOCK, &mask_all, &prev_all); 9 deletejob(pid); 10 sigprocmask(SIG_SETMASK, &prev_all, NULL); 11 } 12 if (errno != ECHILD) 13 sio_error("waitpid error"); 14 errno = olderno; 15} 16 17int main(int argc, char **argv) { 18 int pid; 19 sigset_t mask_all, prev_all; 20 int n = N; // N = 5 21 sigfillset(&mask_all); 22 signal(SIGCHLD, handler); 23 initjobs(); 24 25 while (n--) { 26 if ((pid = fork()) == 0) { 27 execve("/bin/date", argv, NULL); 28 } 29 // !! ์—ฌ๊ธฐ์„œ SIGCHLD๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์˜ค๋ฅ˜ 30 31 // ํ•ธ๋“ค๋Ÿฌ์—์„œ job์„ accessํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ชจ๋“  signal block 32 sigprocmask(SIG_BLOCK, &mask_all, &prev_all)๋ฅ˜ 33 addjob(pid); 34 sigprocmask(SIG_SETMASK, &prev_all, NULL); 35 } 36 exit(0); 37} ๋ถ€๋ชจ๊ฐ€ ๋จผ์ € SIGCHLD ์‹œ๊ทธ๋„์ด ํ„ฐ์ง€๊ธฐ ์ „์— SIG_BLOCKํ•˜๊ณ  addjob์„ ํ•˜๋Š” ๊ฒฝ์šฐ -> OK ๋ถ€๋ชจ๊ฐ€ SIG_BLOCKํ•˜๊ธฐ ์ „์— ์ž์‹์ด ๋๋‚˜๋Š” ๊ฒฝ์šฐ handler๊ฐ€ ๋จผ์ € ์‹คํ–‰๋œ๋‹ค addjobํ•˜๊ธฐ์ „์— deletejob ์ˆ˜ํ–‰ ๋ฌดํ•œ ๋ฃจํ”„ ๋ฐœ์ƒ ๊ฒฝ์ฃผํ˜„์ƒ์„ ํšŒํ”ผํ•˜๋Š” ๋™๊ธฐํ™” ๋ฐฉ๋ฒ• 1int main(int argc, char **argv) { 2 int pid; 3 sigset_t mask_all, mask_one, prev_one; 4 int n = N; // N = 5 5 sigfillset(&mask_all); 6 sigemptyset(&mask_one); 7 sigaddset(&mask_one, SIGCHLD); 8 signal(SIGCHLD, handler); 9 initjobs(); 10 11 while (n--) { 12 sigprocmask(SIG_BLOCK, &mask_one, &prev_one); // block SIGCHILD 13 if ((pid = fork()) == 0) { 14 // ์ž์‹์€ SIGCHLD๋ฅผ blockํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๋‹ค์‹œ unblock 15 sigprocmask(SIG_SETMASK, &prev_one, NULL); // unblock SIGCHLD 16 execve("/bin/date", argv, NULL); 17 } 18 sigprocmask(SIG_BLOCK, &mask_all, NULL); 19 addjob(pid); 20 sigprocmask(SIG_SETMASK, &prev_one, NULL); 21 } 22 exit(0); 23} ๋ถ€๋ชจ์ž…์žฅ์—์„œ fork๊ฐ€ ์‹คํ–‰๋˜๊ณ  ๋‚˜์„œ SIGCHLD๊ฐ€ unblock ๋˜๋Š” ์ˆœ๊ฐ„์ด ๋‹จ ํ•œ๋ฒˆ๋„ ์กด์žฌ ํ•˜์ง€ ์•Š์Œ. ํ•ญ์ƒ addjob์ด ๋จผ์ € ์‹คํ–‰๋จ -> ์˜ค๋ฅ˜ X ๋ช…์‹œ์ ์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ฐฉ์‹ 1volatile sig_atomic_t pid; // pid๋Š” ์ „์—ญ๋ณ€์ˆ˜๋กœ ์„ ์–ธ 2void sigchld_handler(int s) { 3 int orderrno = errno; 4 // sigchld_handler์—์„œ waitpid ํ•˜๋Š” ๋ฐฉ์‹ 5 pid = waitpid(-1, NULL, 0); 6 errno = olderrno; 7} 8void sigint_handler(int s) {} 9 10int main(int argc, char **argv) { 11 sigset_t mask, prev; 12 int n = N; // N = 10 13 signal(SIGCHLD, sigchld_handler); 14 signal(SIGINT, sigint_handler); 15 sigemptyset(&mask); 16 sigaddset(&mask, SIGCHLD); 17 18 while (n--) { 19 sigprocmask(SIG_BLOCK, &mask, &prev); // block SIGCHILD 20 if (fork() == 0) 21 exit(0); 22 23 pid = 0; 24 sigprocmask(SIG_SETMASK, &prev, NULL); 25 26 // Wait for SIGCHLD to be recieved 27 while (!pid) 28 ; 29 30 // Do some work after receiving SIGCHLD 31 printf("."); 32 33 printf("\n"); 34 exit(0); 35} sigsuspend๋ฅผ ์‚ฌ์šฉํ•œ ์‹œ๊ทธ๋„ ๋™๊ธฐํ™” 1int sigsuspend(const sigset_t *mask); 2// ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ๊ณผ ๋™์ผ 3sigprocmask(SIG_SETMASK, &mask, &prev); 4pause(); 5sigprocmask(SIG_SETMASK, &prev, NULL); sigsuspend๋ฅผ ์ด์šฉํ•œ ์‹œ๊ทธ๋„ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ 1int main(int argc, char **argv) { 2sigset_t mask, prev; 3int n = N; // N = 10 4signal(SIGCHLD, sigchld_handler); 5signal(SIGINT, sigint_handler); 6sigemptyset(&mask); 7sigaddset(&mask, SIGCHLD); 8 9while (n--) { 10 sigprocmask(SIG_BLOCK, &mask, &prev); // block SIGCHILD 11 if (fork() == 0) 12 exit(0); 13 14 pid = 0; 15 // Wait for SIGCHLD to be recieved 16 while (!pid) 17 sigsuspend(&prev); 18 19 // Optionally unblock SIGCHILD 20 sigprocmask(SIG_SETMASK, &prev, NULL); 21 22 // Do some work after receiving SIGCHLD 23 printf("."); 24} 25printf("\n"); 26exit(0); 27}
new Stream, Optional
โ˜• Java
Lambda ํ‘œํ˜„์‹ ๋งค๊ฐœ๋ณ€์ˆ˜ ํ™”์‚ดํ‘œ(->) ํ•จ์ˆ˜๋ชธ์ฒด๋กœ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ๋ชธ์ฒด๊ฐ€ ๋‹จ์ผ ์‹คํ–‰๋ฌธ์ด๋ฉด ๊ด„ํ˜ธ{}๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ๋ชธ์ฒด๊ฐ€ return๋ฌธ์œผ๋กœ๋งŒ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋ฉด ๊ด„ํ˜ธ{}์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1(int x) -> x+1; 2(int x, int y) -> x+y; 3(Thread lamT) -> { lamT.start(); } Stream ํŠน์ง• ์›๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์š”์ฒญ๋˜์—ˆ์„๋•Œ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค. parallelStream()์„ ์ด์šฉํ•˜์—ฌ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. ์˜ˆ์ œ1 1List<String> highCaloriesFoodName = foodList.stream() 2 .filter(food -> { 3 System.out.println("filter : " + food.getName()); 4 // 400์ด์ƒ ์นผ๋กœ๋ฆฌ์ธ ์Œ์‹๋งŒ ํ•„ํ„ฐ๋งํ•œ๋‹ค 5 return food.getCalories() > 400; 6 }) 7 .map(food -> { 8 System.out.println("map : " + food.getName()); 9 // ์Œ์‹ ์ด๋ฆ„๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค 10 return food.getName(); 11 }) 12 .limit(3) 13 .collect(Collectors.toList()); 14 15System.out.println(highCaloriesFoodName); ์˜ˆ์ œ2 1List<Integer> redHeavyAppleUid = appleList.parallelStream() // ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ 2 .filter(apple -> apple.getColor().equals("RED")) // ๋นจ๊ฐ„์ƒ‰ ์‚ฌ๊ณผ ํ•„ํ„ฐ๋ง 3 .sorted(Comparator.comparing(Apple::getWeight)) // ๋ฌด๊ฒŒ ์ˆœ์„œ๋Œ€๋กœ ์ •๋ ฌ 4 .map(Apple::getUidNum).collect(Collectors.toList()); // ์‚ฌ๊ณผ ๊ณ ์œ ๋ฒˆํ˜ธ ์ถœ๋ ฅ Optional ํŠน์ง• Optional<T>๋Š” null์ด ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ๊ฐ์‹ธ๋Š” Wrapper ํด๋ž˜์Šค์ด๋‹ค. ์˜ˆ์ œ1 1List<String> nameList = Optional.ofNullable(getNames()) 2 .orElseGet(() -> new ArrayList<>()); ์˜ˆ์ œ2 1String result = user.map(UserVO::getAddress) // ์ฃผ์†Œ ๊ฐ€์ ธ์˜ค๊ธฐ 2 .map(Address::getPostCode) // ์šฐํŽธ๋ฒˆํ˜ธ ๊ฐ€์ ธ์˜ค๊ธฐ 3 .orElse("์šฐํŽธ๋ฒˆํ˜ธ ์—†์Œ"); // ์—†์œผ๋ฉด "์šฐํŽธ๋ฒˆํ˜ธ ์—†์Œ" ์ถœ๋ ฅ
new Spring ๊ฐœ๋… - JDBC, DBCP, JdbcTemplate
๐Ÿƒ Spring
JDBC ์ž๋ฐ” ํ”„๋กœ๊ทธ๋žจ์„ DB์™€ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” API JDBC ๋“œ๋ผ์ด๋ฒ„ DBMS์™€ ํ†ต์‹ ์„ ๋‹ด๋‹นํ•˜๋Š” ์ž๋ฐ” ํด๋ž˜์Šค JDBC ๋“œ๋ผ์ด๋ฒ„๋Š” 4๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค (Type 1~4) Mysql์€ Type 4๋ฅผ ์ง€์›ํ•œ๋‹ค ์˜ˆ์ œ - Connection์„ ์ง์ ‘ ์—ฐ๊ฒฐ 1public List<UUID> findAllIds() { 2 List<UUID> uuids = new ArrayList<>(); 3 try ( 4 var connection = DriverManager.getConnection(url, username, password); 5 var statement = connection.createStatement(); 6 var resultSet = statement.executeQuery(SELECT_ALL_SQL); 7 ) { 8 while (resultSet.next()) { 9 var customerName = resultSet.getString("name"); 10 var customerId = toUUID(resultSet.getBytes("customer_id")); 11 var createdAt = resultSet.getTimestamp("created_at").toLocalDateTime(); 12 uuids.add(customerId); 13 } 14 } catch (SQLException e) { 15 logger.error("Error while connecting to DB", e); 16 } 17 return uuids; 18} DBCP (DataBase Connection Pool) ์„œ๋ฒ„๊ฐ€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„์— Connection์„ ๋งบ๋Š” ๊ฒƒ์€ ์ž์›์„ ๋„ˆ๋ฌด ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค ๋”ฐ๋ผ์„œ, DBCP๋ฅผ ์ด์šฉํ•ด์„œ ๋ฏธ๋ฆฌ Connection์„ Pool์— ๋‹ด์•„๋‘๊ณ , ์š”์ฒญ์ด ์˜ฌ๋•Œ๋งˆ๋‹ค Connection์„ ์ œ๊ณตํ•œ๋‹ค DataSource DataSource๋Š” Spring์—์„œ DBCP ์—ญํ• ์„ ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค ์˜ˆ์ œ - DataSource ์‚ฌ์šฉ 1@Override 2public Optional<Customer> findById(UUID customerId) { 3 List<Customer> allCustomers = new ArrayList<>(); 4 try ( 5 var connection = dataSource.getConnection(); 6 var statement = connection.prepareStatement("select * from customers where customer_id = UUID_TO_BIN(?)") 7 ) { 8 statement.setBytes(1, customerId.toString().getBytes()); 9 try (var resultSet = statement.executeQuery()) { 10 while (resultSet.next()) { 11 mapToCustomer(allCustomers, resultSet); 12 } 13 } 14 } catch (SQLException e) { 15 logger.error("Got eror while closing connection", e); 16 throw new RuntimeException(e); 17 } 18 return allCustomers.stream().findFirst(); 19} HikariCP DBCP์˜ ์ผ์ข…, JDBC DataSource์˜ ๊ตฌํ˜„์ฒด spring-boot-starter-jdbc์— ํฌํ•จ๋˜์–ด์žˆ๋‹ค Spring Boot 2.0๋ถ€ํ„ฐ Tomcat JDBC ๋Œ€์‹ ์— Hikari๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค ํƒ€ CP๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ณด๋‹ค ๋น ๋ฅด๋‹ค Hikari ์„ค์ • 1@Bean 2public DataSource dataSource() { 3 return DataSourceBuilder.create() 4 .url(url) 5 .username(username) 6 .password(password) 7 .type(HikariDataSource.class) 8 .build(); 9} JdbcTemplate ์œ„ ์˜ˆ์ œ์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๊ฐ€ ์—„์ฒญ ๋งŽ์•„์ง„๋‹ค ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด JdbcTemplate๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค ์‚ฌ์šฉ๋ฒ• queryForObject : ๋‹จ์ผ ๊ฒฐ๊ณผ ํ–‰์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ query : ๋‹ค์ˆ˜ ๊ฒฐ๊ณผ ํ–‰์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ update : ์ถ”๊ฐ€, ์ˆ˜์ •, ์‚ญ์ œ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” DataSource๋ฅผ ์ฃผ์ž…๋ฐ›์•„์•ผ ํ•œ๋‹ค 1@Bean 2public JdbcTemplate jdbcTemplate(DataSource dataSource) { 3 return new JdbcTemplate(dataSource); 4} RowMapper ๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ ResultSet์€ resultSet.next()๋กœ ์ˆœํšŒํ•˜๋ฉด์„œ ๊ฐ์ฒด์˜ setter๋ฅผ ํ˜ธ์ถœํ•˜์˜€๋‹ค JdbcTemplate์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” RowMapper<T>๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ์•ผ ํ•œ๋‹ค 1RowMapper<Customer> customerRowMapper = (resultSet, i) -> { 2 var customerName = resultSet.getString("name"); 3 var email = resultSet.getString("email"); 4 return new Customer(customerName, email) 5} ์˜ˆ์ œ - JdbcTemplate, queryForObject, RowMapper ์‚ฌ์šฉ 1@Override 2public Optional<Customer> findById(UUID customerId) { 3 try { 4 return Optional.ofNullable(jdbcTemplate.queryForObject("select * from customers where customer_id = UUID_TO_BIN(?)", customerRowMapper, customerId.toString())); 5 } catch (EmptyResultDataAccessException e) { 6 logger.error("Got empty result", e); 7 return Optional.empty(); 8 } 9} NamedParameterJdbcTemplate ๊ธฐ์กด์˜ jdbcTemplate์—์„œ๋Š” query์— ?๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ž๋ฅผ ์น˜ํ™˜ํ•˜์˜€๋‹ค ๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด์„œ, ์ˆœ์„œ๋ฅผ ํ—ท๊ฐˆ๋ฆฌ์ง€ ์•Š๊ธฐ ์œ„ํ•ด์„œ NamedParameterJdbcTemplate์„ ์‚ฌ์šฉํ•œ๋‹ค NamedParameterJdbcTemplate์—์„œ๋Š” “:๋ณ€์ˆ˜๋ช…"์„ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ๋‹ค ์˜ˆ์ œ - NamedParameterJdbcTemplate ์‚ฌ์šฉ 1var update = jdbcTemplate.update("UPDATE customers SET name=:name, email=:email, last_login_at=:lastLoginAt WHERE customer_id = UUID_TO_BIN(:customerId)", 2 new HashMap<>() {{ 3 put("customerId", customer.getCustomerId().toString().getBytes()); 4 put("name", customer.getName()); 5 put("email", customer.getEmail()); 6 put("lastLoginAt", customer.getLastLoginAt() != null ? Timestamp.valueOf(customer.getLastLoginAt()) : null); 7 put("createdAt", Timestamp.valueOf(customer.getCreatedAt())); 8 }});
new ์˜ํ™”์™€ ๋ฌธํ•™
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
๋งค์ฒด ๋ณ€ํ™˜์ด๋ž€ ์†Œ์„ค, ํฌ๊ณก, ์‹œ, ์˜ํ™” ๋“ฑ ๊ฐ๊ฐ์˜ ๋งค์ฒด ํ˜•์‹์„ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ๋งค์ฒด ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ ๋คผ๋ฏธ์—๋ฅด ํ˜•์ œ์— ์˜ํ•ด์„œ ์˜ํ™”๊ฐ€ ๋ฐœ๋ช…๋œ ํ›„, 1910๋…„๋Œ€๋ถ€ํ„ฐ ๊ธฐ์กด ๋ฌธํ•™ ์ž‘ํ’ˆ์„ ์˜ํ™”์˜ ํ˜•์‹์— ๋งž๋„๋ก ๊ฐ์ƒ‰ํ•˜๋Š” ์–‘์ƒ์ด ์ธ๊ธฐ๋ฅผ ์–ป๊ฒŒ ๋จ. ๋งค์ฒด ๋ณ€ํ™˜ ์–‘์ƒ ๋ถ„์„ ๊ณผ์ •์—์„œ ๊ณ ๋ คํ•ด์•ผํ•  ์‚ฌํ•ญ ๊ตฌ์„ฑ์˜ ์ƒ๋žต๊ณผ ์••์ถ• ํ…์ŠคํŠธ -> ์˜ํ™”, ์‹œ๊ณต๊ฐ„์  ์ œ์•ฝ์„ ๋ฐ›์„ ์ˆ˜ ๋ฐ–์— ์—†๋‹ค ๋”ฐ๋ผ์„œ, ์ƒ๋žต๊ณผ ์••์ถ•์€ ํ•  ์ˆ˜ ๋ฐ–์— ์—†๋‹ค ์‹œ๊ฐ„๊ณผ ๊ณต๊ฐ„์˜ ์˜์ƒ์  ๋ณ€ํ™˜ ์‹œ๊ณต๊ฐ„์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์€ ๋งค์ฒด์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ๋ฐ–์— ์—†๋‹ค. ์‚ฌ๊ฑด์˜ ๋ณ€ํ™” ๋ฐฉ์‹ ์š”์•ฝ๊ณผ ์ƒ๋žต : ํ…์ŠคํŠธ ๊ธธ์ด > ์˜ํ™” ๊ธธ์ด ์žฅ๋ฉด : ํ…์ŠคํŠธ ๊ธธ์ด = ์˜ํ™” ๊ธธ์ด ์—ฐ์žฅ : ํ…์ŠคํŠธ ๊ธธ์ด < ์˜ํ™” ๊ธธ์ด ๊ณต๊ฐ„์˜ ๋ณ€ํ™” ๋ฐฉ์‹ : ์‹ค์ œ ์žฅ์†Œ๋กœ ๋ณด์—ฌ์ค˜์•ผํ•จ ๊ฐ์ • ์ด์ž…๊ณผ ์„œ์‚ฌ์  ์—ฐ์ถœ ์˜ํ™”์˜ ๊ฒฝ์šฐ, ์‹œ์ ์ด๋ผ๋Š” ํ˜•์‹œ์ ์ธ ์š”์†Œ๊ฐ€ ์ผ๊ด€์ ์œผ๋กœ ์œ ์ง€๋˜์ง€ ์•Š์Œ ๊ฐ๋…์€ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ๊ฐ์ •์„ ์ž˜ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์„์ง€ ๊ณ ๋ฏผํ•ด์•ผํ•จ ๋งค์ฒด ๋ณ€ํ™˜์—์„œ ๋ฐ˜๋“œ์‹œ ๊ณ ๋ คํ•ด์•ผํ•  ๊ฒƒ ์ฃผ์ œ ์˜์‹์˜ ๋ณ€ํ™” ๋“ฑ์žฅ์ธ๋ฌผ์˜ ๋ณ€ํ™” ํ•ต์‹ฌ ์„œ์‚ฌ์˜ ๋ณ€ํ™” ์ž‘ํ’ˆ์„ ์˜ฌ๋ฐ”๋กœ ๊ฐ์ƒํ•˜๋Š” 4๊ฐ€์ง€ ๋ฐฉ๋ฒ• ์ž‘๊ฐ€ ์ค‘์‹ฌ (์ž‘๊ฐ€๋ก ) : ์ž‘ํ’ˆ์˜ ์˜๋ฏธ๋ฅผ ์ž‘๊ฐ€์˜ ์ƒ์• , ์‚ฌ์ƒ, ์ž‘๊ฐ€๊ฐ€ ๋‚จ๊ธด ๋ง ๋“ฑ์„ ๊ทผ๊ฑฐ๋กœ ํ•ด์„ํ•˜๋Š” ๋ฐฉ์‹ ์ž‘ํ’ˆ ์ค‘์‹ฌ (์ž‘ํ’ˆ๋ก ) : ์ž‘ํ’ˆ์˜ ์˜๋ฏธ๋ฅผ ์ž‘ํ’ˆ ์ž์ฒด๊ฐ€ ์ง€๋‹ˆ๊ณ  ์žˆ๋Š” ๊ตฌ์กฐ์  ์กฐ๊ฑด์œผ๋กœ๋ถ€ํ„ฐ ๊ทผ๊ฑฐ๋ฅผ ๋‘๊ณ  ํ•ด์„ํ•˜๋Š” ๋ฐฉ์‹ ์‹œ๋Œ€ ๋ฐ ์‚ฌํšŒ์  ๋ฐฐ๊ฒฝ ์ค‘์‹ฌ (๋ฐ˜์˜๋ก ) : ์ž‘ํ’ˆ์˜ ์˜๋ฏธ๋ฅผ ์ฐฝ์ž‘ ๋‹น์‹œ์˜ ์‹œ๋Œ€์ , ์‚ฌํšŒ์  ๋ฐฐ๊ฒฝ์œผ๋กœ๋ถ€ํ„ฐ ๊ทผ๊ฑฐ๋ฅผ ๋‘๊ณ  ํ•ด์„ํ•˜๋Š” ๋ฐฉ์‹ ๋…์ž ์ค‘์‹ฌ (ํšจ์šฉ๋ก ) : ์ž‘ํ’ˆ์˜ ์˜๋ฏธ๋ฅผ ์ฃผ์ฒด๋กœ์„œ์˜ ๋…์ž๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ํ•˜์—ฌ ํ•ด์„ํ•˜๋Š” ๋ฐฉ์‹ ๊น€๊ธฐ์˜ ๊ฐ๋…์˜ <ํ•˜๋…€> ๋ถ„์„ํ•˜๊ธฐ ์ž‘๊ฐ€๋ก  ๋ถ„์„ ์ด๋ฆ„ : ๊น€๊ธฐ์˜ ํ•™๋ ฅ : ์„œ์šธ๋Œ€ ์˜ํ•™๊ณผ ์„์‚ฌ ๋ฐ๋ท” : 1955๋…„ <์ฃฝ์—„์˜ ์ƒ์ž> ๋‚จ๊ธด ๋ง : “์ธ๊ฐ„์˜ ๋ชธ์„ ํ•ด๋ถ€ํ•˜๋ฉด ๊ฒ€์€ ํ”ผ๊ฐ€ ๋‚œ๋‹ค. ๊ทธ๊ฒƒ์ด ์š•๋ง์ด๋‹ค” ํ•˜๋…€์˜ ์—ฐ์ž‘ 1960๋…„: <ํ•˜๋…€> 1971๋…„: <ํ™”๋…€> (<ํ•˜๋…€>๋ฅผ ๋ฆฌ๋ฉ”์ดํฌ) 1972๋…„: <์ถฉ๋…€> (<ํ•˜๋…€>๋ฅผ ๋ฆฌ๋ฉ”์ดํฌ) 1982๋…„: <ํ™”๋…€ 82> (<ํ™”๋…€>๋ฅผ ๋ฆฌ๋ฉ”์ดํฌ) 1984๋…„: <์œก์‹๋™๋ฌผ> (<์ถฉ๋…€>๋ฅผ ๋ฆฌ๋ฉ”์ดํฌ) ๊น€๊ธฐ์˜ ์˜ํ™”์˜ ์—ฌ์ฃผ์ธ๊ณต์€ ๋‹น๋Œ€ ์„ ํ˜ธํ•˜๋Š” ์—ฌ๋ฐฐ์šฐ์™€ ๋‹ค๋ฅด๊ฒŒ ์ฐจ๊ฐ‘๊ณ  ํ‘œ๋…์Šค๋Ÿฌ์šด ์ด๋ฏธ์ง€๋ฅผ ์ง€๋‹Œ๋‹ค. 1990๋…„ ๋งˆ์ง€๋ง‰ ์ž‘ํ’ˆ์„ ๋์œผ๋กœ ์‚ฌ๋žŒ๋“ค์˜ ๊ธฐ์–ต์—์„œ ์žŠํ˜€์กŒ์ง€๋งŒ, ์ปฌํŠธ ๋งˆ๋‹ˆ์•„๋“ค์— ์˜ํ•ด์„œ ๋‹ค์‹œ ์„ธ์ƒ์˜ ๋น›์„ ๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค. ๊น€๊ธฐ์˜ ๊ฐ๋…์€ ์ž์‹ ์˜ ์ž‘ํ’ˆ ์ด๋ฆ„์„ ์ฆ‰ํฅ์ ์œผ๋กœ ์ง€์—ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„ ์˜ํ™” ์† ๋‚จ์„ฑ์€ ๋ฌด๋Šฅ๋ ฅํ•˜๊ณ  ์˜ค๋กœ์ง€ ์„ฑ์  ์š•๋ง์„ ์ฑ„์šฐ๋ ค๋Š”๋ฐ ์ง‘์ค‘ํ•˜๋ฉฐ ์—ฌ์„ฑ์€ ์ž์‹ ์˜ ์š•๋ง์„ ์‹คํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๊ทธ๋Ÿฌํ•œ ๋‚จ์„ฑ์„ ํŒŒ๋ฉธ๋กœ ๋ชฐ์•„๊ฐ€๋‹ค๊ฐ€ ์ž์‹  ์—ญ์‹œ ํŒŒ๋ฉธ์„ ๋งž์ดํ•˜๋Š” ๋ชจ์Šต์œผ๋กœ ๋“œ๋Ÿฌ๋‚œ๋‹ค ๋ฐ˜์˜๋ก  ๋ถ„์„ ์ƒˆ๋กœ์šด ๊ฐ€๋ถ€์žฅ์ œ์˜ ๋ชจ์Šต, ๊ฐ€์กฑ ๋“œ๋ผ๋งˆ 1960๋…„๋Œ€๊ฒฝ ๋ถ€ํ„ฐ ๊ฐ€์กฑ์ด ์ค‘์‹ฌ์ด ๋˜์–ด ๋ฒŒ์–ด์ง€๋Š” ์ด์•ผ๊ธฐ๋ฅผ ๋‹ด์€ ์ผ๋ จ์˜ ์˜ํ™”๋“ค์ด ๋“ฑ์žฅํ•˜๊ธฐ ์‹œ์ž‘ํ•จ ์ด ์˜ํ™”๋“ค์€ ๊ฐ€์กฑ์„ ์ค‘์‹ฌ์œผ๋กœ ์ผ์–ด๋‚˜๋Š” ๋‹ค์–‘ํ•œ ์‚ฌ๊ฑด๋“ค์„ ์†Œ์žฌ๋กœ ํ•˜์—ฌ ์ž์‹๊ณผ ๋ถ€๋ชจ์˜ ์„ธ๋Œ€ ๊ฐˆ๋“ฑ ๋ฌธ์ œ, ์•„๋ฒ„์ง€๊ฐ€ ๊ฐ€์กฑ์„ ์œ„ํ•ด ํฌ์ƒํ•˜๋Š” ๋ชจ์Šต, ๊ฐ€์กฑ์˜ ํ–‰๋ณต์„ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๋Š” ๋ชจ์Šต ๋“ฑ์„ ๋‹ค๋ฃจ์—ˆ๋‹ค. ๋‹น์‹œ ์ค‘์‚ฐ์ธต ๊ฐ€์ •์—๋Š” ์‹๋ชจ์™€์˜ ๊ฐˆ๋“ฑ์ด ๋งŽ์•˜๋‹ค. ๊น€๊ธฐ์˜ ๊ฐ๋…์˜ <ํ•˜๋…€>๋Š” ๊ธฐ์กด์˜ ํ•œ๊ตญ์˜ํ™”์™€ ๋งค์šฐ ์ด์งˆ์ ์ธ, ๊ทธ๋กœํ…Œ์Šคํฌํ•˜๊ณ  ์Œ์‚ฐํ•œ ์•Œ๋ ˆ๊ณ ๋ฆฌ์˜ ๊ณต๊ฐ„์„ ๊ตฌ์„ฑํ•ด๋ƒ„. ์ž‘ํ’ˆ๋ก  ๋ถ„์„ ์ค„๊ฑฐ๋ฆฌ ๋“ฑ์žฅ์ธ๋ฌผ ๋™์‹(๊น€์ง„๊ทœ), ๋™์‹ ๋ถ€์ธ (์ฃผ์ฆ๋…€), ํ•˜๋…€ (์ด์€์‹ฌ), ์กฐ๊ฒฝํฌ(์—„์•ต๋ž€), ์• ์ˆœ(๊ณ ์„ ์• ) ํŠน์ง• ์•ก์ž๊ตฌ์กฐ ์˜ํ™” ์† ์ด์•ผ๊ธฐ๊ฐ€ ์‹ค์ œ ์‚ฌ๊ฑด์ด ์•„๋‹˜์„ ๊ฐ•์กฐํ•˜๊ธฐ ์œ„ํ•ด์„œ (์‚ฌํšŒ์  ๋ถ„์œ„๊ธฐ, ๊ฒ€์—ด) ๋™์‹์ด ๋งˆ์ง€๋ง‰์— ๊ด€๊ฐ๋“ค์„ ํ–ฅํ•ด ํ›ˆ๊ณ„์™€ ์งˆ๋ฌธ์„ ํ†ตํ•ด ์ด๋Ÿฌํ•œ ์ด์•ผ๊ธฐ๊ฐ€ ์–ผ๋งˆ๋“ ์ง€ ์‹ค์ œ๋กœ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Œ์„ ์•”์‹œํ•จ ์ธ๊ฐ„์˜ ๋‹ค์–‘ํ•œ ์š•๋ง์„ ๋…ธ๊ณจ์ ์œผ๋กœ ๋ณด์—ฌ์คŒ ๋™์‹ : ๋Šฅ๋ ฅ์ด ๋ณ„๋กœ ์—†์Œ, ๊ฐ€์žฅ์œผ๋กœ์„œ์˜ ๊ถŒ์œ„ ํšŒ๋ณต์ด๋ผ๋Š” ์š•๋ง์„ ์ง€๋‹˜, ๊ฒฝํฌ์™€ ํ•˜๋…€์˜ ์„ฑ์  ์š•๋ง์œผ๋กœ ์ธํ•ด ํŒŒ๋ฉธ ํ•˜๋…€ : 1์ฐจ(๋ˆ์— ๋Œ€ํ•œ ์š•๋ง), 2์ฐจ(๋™์‹์„ ํ–ฅํ•œ ์„ฑ์  ์š•๋ง), 3์ฐจ(์‹ ๋ถ„์ƒ์Šน์— ๋Œ€ํ•œ ์š•๋ง), 4์ฐจ(ํŒŒ๊ดด์˜ ์š•๋ง) ๋ถ€์ธ : ์„œ๋ฏผ์—์„œ ์ค‘์‚ฐ์ธต์œผ๋กœ ์ง„์ž…ํ•˜๋ ค๋Š” ์š•๋ง, ์ด์ธต์ง‘์œผ๋กœ ์ด์‚ฌํ•ด์„œ ์•„๋“ค์„ ๋‚ณ์•„์„œ ํ™”๋ชฉํ•œ ๊ฐ€์ •์„ ์ด๋ฃจ๋ ค๋Š” ์š•๋ง, ํ•˜๋…€๋ฅผ ๋‚™ํƒœ์‹œํ‚ค๋ ค๋Š” ์š•๋ง ๋…ํŠนํ•œ ์ง‘์˜ ๊ตฌ์กฐ 1์ธต : ๋™์‹์„ ์œ„ํ•œ ๊ณต๊ฐ„์ด X, ๋ถ€์ธ์ด ๊ฐ€์žฅ์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ 2์ธต : ๊ทผ๋Œ€์ ์œผ๋กœ ์น˜์žฅ๋œ ๊ณต๊ฐ„, ํ•˜๋…€(์ „๊ทผ๋Œ€์ )์ด ์ถฉ๋Œ, ๋™์‹์™€ ํ•˜๋…€์˜ ๊ณต๊ฐ„, ์ฃฝ์Œ์˜ ๊ณต๊ฐ„ ๋ถ€์—Œ : ๋”ฐ๋œปํ•œ ๊ณต๊ฐ„์—์„œ ์ฃฝ์Œ์„ ์ค€๋น„ํ•˜๋Š” ๊ณต๊ฐ„์œผ๋กœ ๋ฐ”๋€œ (๋…์•ฝ) ๋…ํŠนํ•œ ์—ฐ์ถœ ๊ธฐ๋ฒ• ํ•˜๋…€ = ์ฅ ์—ฐ์ƒ๋ฒ• ๊ณ„๋‹จ = ์ฃฝ์Œ, ์‹ ๋ถ„ ์ƒ์Šน์˜ ์š•๋ง ์˜๋„์  ํด๋กœ์ฆˆ์—… ํ™œ์šฉ : ๊ด€๊ฐ๋“ค์—๊ฒŒ ๊ทน๋„์˜ ๊ณตํฌ๊ฐ ์กฐ์„ฑ ํšจ๊ณผ ๊ฐ์ข… ์†Œํ’ˆ์„ ํ†ตํ•œ ์˜๋ฏธ ์ƒ์„ฑ ํ”ผ์•„๋…ธ ๋™์‹ : ๊ฐ€์žฅ์œผ๋กœ์„œ์˜ ๊ถŒ์œ„๋ฅผ ๊ทธ๋‚˜๋งˆ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ˆ˜๋‹จ ํ•˜๋…€ : ๋™์‹์„ ์œ ํ˜นํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ ๋ถ€์ธ : ๋™์‹์„ ์œ ํ˜นํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ ์žฌ๋ด‰ํ‹€ ์•„๋‚ด์˜ ๋ฌผ์งˆ์— ๋Œ€ํ•œ ์š•๋ง์„ ๋“œ๋Ÿฌ๋‚ด๋Š” ๋„๊ตฌ ๋Š์ž„์—†์ด ๋ˆ์„ ๋ฒŒ์–ด์•ผํ•˜๋Š” ์•…์ˆœํ™˜์„ ์˜๋ฏธ ๊ฐ€๋ถ€์žฅ์  ์ง€์œ„๊ฐ€ ๋ฌด๋„ˆ์ง€๊ณ , ์—ฌ์„ฑ์˜ ํž˜์ด ํ™•๋Œ€๋˜๊ณ  ์žˆ์Œ์„ ์˜๋ฏธ 1960๋…„๋Œ€ ์‚ฐ์—… ์ž๋ณธ์ฃผ์˜ ๋ฌผ์งˆ ์†Œ์œ ์˜ ์ค‘์š”์„ฑ์„ ๊ฐ•์กฐ “ํ•˜๋…€"๋ฅผ ๋ณด๊ณ  ์ƒ๊ฐํ•ด๋ด์•ผ ํ•˜๋Š” ๊ฒƒ ์ฅ์™€ ๋‹ค๋žŒ์ฅ์˜ ์ฐจ์ด ํ•˜๋…€ ์ด์™ธ์˜ ๋‹ค๋ฅธ ์ธ๋ฌผ๋„ ์ฅ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€ ๋‹ค๋žŒ์ฅ๋Š” ๋ˆ„๊ตฌ์ธ๊ฐ€ ๋™์‹์€ ์™œ 3๋ช…์ด ๋™์‹œ์— ์œ ํ˜น ํ–ˆ๋Š”๋ฐ, ํ•˜๋…€์˜ ์œ ํ˜น์—๋งŒ ๋„˜์–ด๊ฐ”๋Š”๊ฐ€ ๊ฐ‘์„ ๊ด€๊ณ„ ์—ฌ๊ณต ์—ฌ๊ณต์˜ ์ฃฝ์Œ์œผ๋กœ ์•ฝํ•ด์กŒ์„๋•Œ ํ•˜๋…€๊ฐ€ ๊ฐ€์žฅ ์ด๋ป์„œ? ์–ด๋–ค๊ฒŒ ๊ฐ€์žฅ ์ ์ ˆํ•œ์ง€ ์ƒ๊ฐํ•ด๋ณผ๊ฒƒ ๋™์‹ ๋ถ€์ธ์ด ํ•˜๋…€๋ฅผ ๋‚™ํƒœ์‹œํ‚ค๋Š” ์žฅ๋ฉด -> ๋„๋•์ ์œผ๋กœ ์ •๋‹นํ•œ๊ฐ€ ๋ถ€์ธ์ด ํ•˜๋…€๋ฅผ ๋…์‚ดํ•˜๋ ค๋Š” ๊ฒƒ -> ๋„๋•์ ์œผ๋กœ ์ •๋‹นํ•œ๊ฐ€ ํ•˜๋…€์˜ ์š•๋ง์ด 4๊ฐ€์ง€๋กœ ์ง„ํ™” 4๊ฐ€์ง€ ์ค‘์— ์ง„์ •์œผ๋กœ ์ด๋ฃจ์ž ํ–ˆ๋˜ ์š•๋ง์€ ๋ฌด์—‡์ธ๊ฐ€? ๊ณ„๊ธ‰ ๋ฌธ์ œ ๊ณ„๊ธ‰ ์ด๋ž€ ์ผ์ •ํ•œ ์‚ฌํšŒ์—์„œ ์‹ ๋ถ„, ์žฌ์‚ฐ, ์ง์—… ๋”ฐ์œ„๊ฐ€ ๋น„์Šทํ•œ ์‚ฌ๋žŒ๋“ค๋กœ ํ˜•์„ฑ๋˜๋Š” ์ง‘๋‹จ ๋˜๋Š” ๊ทธ๋ ‡๊ฒŒ ๋‚˜๋‰œ ์‚ฌํšŒ์  ์ง€์œ„ ๊ณ„๊ธ‰์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•œ ์ด๋ก  ๋ถ€๋ฅด๋””์™ธ(ํ”„๋ž‘์Šค ์‚ฌํšŒํ•™์ž) : “์ฒญ๋…„๊ณผ ๋…ธ์ธ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๋‚˜์ด์˜ ๊ฒฝ๊ณ„๊ฐ€ ๋ชจํ˜ธํ•จ์—๋„ ๋…ธ์ธ์ด ์žˆ๋“ฏ, ํ˜„๋Œ€์— ๊ณ„๊ธ‰ ๊ฐ„ ๊ฒฝ๊ณ„๊ฐ€ ํฌ๋ฏธํ•ด์กŒ๋‹ค๊ณ  ํ•ด๋„ ๊ณ„๊ธ‰์ด ์—„์—ฐํžˆ ์žˆ๋‹ค.” ๊ตฌ๋ณ„์ง“๊ธฐ : ์šฐ์›”ํ•œ ๊ณ„๊ธ‰์„ ํŠน์ง•์ง“๋Š” ๋ณ€๋ณ„์  ์†์„ฑ๋“ค์˜ ์ด์ฒด. -> ํƒœ์–ด๋‚  ๋•Œ ๋ถ€ํ„ฐ ๊ฐ€์ง€๋Š” ํŠน์ง•์„ ๋–จ์ณ๋‚ด๊ธฐ ์–ด๋ ต๋‹ค ์ž๋ณธ์˜ ์ข…๋ฅ˜ : ๊ฒฝ์ œ, ๋ฌธํ™”, ์‚ฌํšŒ ์ž๋ณธ์œผ๋กœ ๊ตฌ๋ณ„๋˜๋ฉฐ, ์ด๋ฅผ ๋ชจ๋‘ ๊ฐ–์ถ”๊ฒŒ ๋˜๋ฉด ์ƒ์ง• ์ž๋ณธ์„ ์†Œ์œ ํ•จ์œผ๋กœ์จ ์œ„๊ณ„์ ์ธ ๊ด€๊ณ„์—์„œ ๊ถŒ๋ ฅ์„ ์†์— ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค ๊ฐ๊ฐ ์„œ๋กœ ๋‹ค๋ฅธ ๋™์ผํ•œ ํŠน์„ฑ์„ ๊ณต์œ ํ•œ ์ง‘๋‹จ๋“ค์€ ๋Š์ž„์—†์ด ์„ธ ๊ฐ€์ง€ ์ž๋ณธ์„ ์ฐจ์ง€ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๋Š์ž„์—†์ด ํˆฌ์Ÿํ•˜๊ณ  ๊ฒฝํ•ฉํ•œ๋‹ค ์„ธ ๊ฐ€์ง€ ์ž๋ณธ์˜ ๊ตฌ์ฒด์ ์ธ ํŠน์ง• ๊ฒฝ์ œ ์ž๋ณธ : ์—ฌ๋Ÿฌ ์ƒ์‚ฐ ์š”์†Œ(ํ† ์ง€, ๊ณต์žฅ, ๋…ธ๋™๋ ฅ)๊ณผ ๊ฐ์ข… ์žฌํ™”(์ž์‚ฐ, ์†Œ์œ ๋ฌผ)๋กœ ๊ตฌ์„ฑ๋จ. ์ฆ‰๊ฐ์ ์ด๊ณ  ์ง์ ‘์ ์œผ๋กœ ํ™”ํ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๊ณ  ์žฌ์‚ฐ๊ถŒ์˜ ํ˜•ํƒœ๋กœ ์ œ๋„ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•จ ๋ฌธํ™” ์ž๋ณธ : ๊ฐ€์กฑ์— ์˜ํ•ด ์ „์ˆ˜๋˜๊ฑฐ๋‚˜ ๊ต์œก ์ฒด๊ณ„์— ์˜ํ•ด ์ƒ์‚ฐ๋จ. ํŠน์ • ์กฐ๊ฑด์—์„œ ๊ฒฝ์ œ ์ž๋ณธ์œผ๋กœ ๋ณ€ํ™˜๋จ. ๊ฐœ์ธ์˜ ๋ชธ์— ์ถ•์ ๋˜๋Š” ๋Šฅ๋ ฅ์ด์ž ์ง€์‹ ์‚ฌํšŒ ์ž๋ณธ : ๊ฐœ์ธ ๋˜๋Š” ์ง‘๋‹จ์ด ๋™์›ํ•˜๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌํšŒ์  ์—ฐ์ค„๊ณผ ๊ด€๊ณ„๋ง. ํŠน์ • ์กฐ๊ฑด์—์„œ ๊ฒฝ์ œ ์ž๋ณธ์œผ๋กœ ๋ณ€ํ™˜๋จ. ์„ธ ๊ฐ€์ง€ ์ž๋ณธ ์ค‘ ๊ณ„๊ธ‰์˜ ์ฐจ์ด๋ฅผ ๊ทผ๋ณธ์ ์œผ๋กœ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋ฌธํ™” ์ž๋ณธ์ด๋‹ค. ๊ฐœ์ธ์ด๋‚˜ ์ง‘๋‹จ์€ ์ž์‹ ์ด ์ง€๋‹Œ ๋ฌธํ™” ์ž๋ณธ์„ ํ† ๋Œ€๋กœ ํƒ€์ธ๋ณด๋‹ค ์šฐ์œ„์— ์„œ๊ฑฐ๋‚˜ ๊ทธ๋ ‡์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ์Œ ๊ณ„๊ธ‰์ด ๋†’์„ ์ˆ˜๋ก ํ›„์†์—๊ฒŒ ๊ฒฝ์ œ ์ž๋ณธ์„ ์ƒ์†ํ•˜๊ธฐ ์•ž์„œ ๋ฌธํ™” ์ž๋ณธ์„ ์Šต๋“์‹œํ‚ค๋Š” ๊ฒƒ์— ๋”์šฑ๋” ์—ด์ค‘ํ•  ์ˆ˜ ๋ฐ–์— ์—†์Œ ์ตœํ•˜์ธต ๊ณ„๊ธ‰์˜ ๊ฒฝ์šฐ ์ž์‹ ์ด ์ฒ˜ํ•œ ์ƒํ™ฉ์—์„œ ๋ฒ—์–ด๋‚˜๊ธฐ ์–ด๋ ค์›€, ๊ฒฝ์ œ ์ž๋ณธ์˜ ํš๋“์„ ์œ„ํ•ด ํ•„์ˆ˜์ ์ธ ๋ฌธํ™” ์ž๋ณธ์˜ ์ถ•์  ์ž์ฒด๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ ๋ฌธํ™” ์ž๋ณธ์˜ ์Šต๋“์„ ์œ„ํ•ด์„œ๋Š” ์‹œ๊ฐ„๊ณผ ๋…ธ๋ ฅ๋„ ํ•„์š”ํ•˜์ง€๋งŒ, ๊ฒฝ์ œ ์ž๋ณธ์ด ๊ฐ–์ถฐ์ ธ ์žˆ์–ด์•ผ๋งŒ ๊ฐ€๋Šฅํ•จ. ๊ณ„๊ธ‰ ๊ฐ„ ๊ถŒ๋ ฅ๊ณผ ์ด๋ฐ์˜ฌ๋กœ๊ธฐ ๊ถŒ๋ ฅ : ๋‘๊ฐ€์ง€๋กœ ๋‚˜๋‰œ๋‹ค ํƒ€์ž๊ฐ€ ์ง€๋ฐœ์ ์œผ๋กœ ๊ถŒ๋ ฅ์ž์—๊ฒŒ ๋ณต์ข…ํ•˜๋Š” ๋ฐฉ์‹ ํƒ€์ž๋กœ๋ถ€ํ„ฐ ๋ณต์ข…์„ ๋Œ์–ด๋‚ด๊ธฐ ์œ„ํ•˜์—ฌ ์ž์œ ๊ฐ€ ์•„๋‹Œ ํญ๋ ฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹ ํญ๋ ฅ ์ฃผ๊ด€์  ํญ๋ ฅ : ์ •์ƒ์ ์ด๊ณ  ํ‰์˜จํ•œ ์ƒํƒœ๋ฅผ ํ˜ผ๋ž€ ์‹œํ‚ค๋Š” ํญ๋ ฅ. ์ฆ‰, ์ง์ ‘์ ์ด๊ณ  ๋ฌผ๋ฆฌ์ ์ธ ํญ๋ ฅ ๊ฐ๊ด€์  ํญ๋ ฅ : ์ •์ƒ์ ์ธ ์ƒํƒœ์— ๋‚ด์žฌํ•˜๋Š” ํญ๋ ฅ, ์‚ฌํšŒ ๊ตฌ์กฐ์  ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ทผ๋ณธ์ ์ธ ํญ๋ ฅ, ์ƒ์ง•์  ํญ๋ ฅ(์–ธ์–ด ํญ๋ ฅ), ๊ตฌ์กฐ์  ํญ๋ ฅ(๊ณ„๊ธ‰, ์ฒด์ œ ํญ๋ ฅ) ๋“ฑ์ด ์žˆ์Œ ๊ณ„๊ธ‰ ์ฐจ์ด๋กœ ์ธํ•ด ๋ฐœ์ƒํ•˜๋Š” ๋‹ค์–‘ํ•œ ๊ฐ์ •๋“ค ํ˜์˜ค ์‚ฌ๋žŒ์ด๋‚˜ ๋Œ€์ƒ์„ ์„œ์—ดํ™”ํ•ด์„œ ํŠน์ •ํ•œ ๋Œ€์ƒ์„ ์ฒœํ•œ ๊ฒƒ์„ ๊ฐ„์ฃผ ํ˜์˜ค ๋Œ€์ƒ์ด ์ž์‹ ์˜ ์˜์—ญ์— ์นจ๋ฒ”ํ•˜๊ณ ์ž ํ•  ๋•Œ ์ฐจ๋ณ„๊ณผ ํญ๋ ฅ์„ ๋ฐœ์ƒ์‹œํ‚ด ์ˆ˜์น˜์‹ฌ ์ž์‹ ์˜ ์•ฝ์ ์ด ๋…ธ์ถœ๋˜์—ˆ์„ ๋•Œ ์ƒ๊ธฐ๋Š” ๊ณ ํ†ต์Šค๋Ÿฌ์šด ๊ฐ์ • ์‚ฌํšŒ๋Š” ์ˆ˜์น˜์‹ฌ์„ ํ†ตํ•ด ํŠน์ •ํ•œ ์ง‘๋‹จ๊ณผ ๊ฐœ์ธ์„ ์„ ํƒํ•˜๊ณ , ๊ทธ๋“ค์„ ๋น„์ •์ƒ์œผ๋กœ ๊ตฌ๋ณ„ํ•จ 21์„ธ๊ธฐ ์ž๋ณธ์ฃผ์˜ ์‚ฌํšŒ์— ์ƒˆ๋กญ๊ฒŒ ๋“ฑ์žฅํ•œ ๊ธ€๋กœ๋ฒŒ ๊ฒŒ๊ธ‰ ๊ตฌ์กฐ ์ƒ์œ„์ธต ๊ณ„๊ธ‰ ๊ทน์†Œ์ˆ˜ ๋ถ€ํ˜ธ ๊ณ„๊ธ‰ : ์žฌ๋ฒŒ ์—˜๋ฆฌํŠธ ๊ณ„๊ธ‰ : ๊ฒ€/ํŒ์‚ฌ, ๊ตญํšŒ์˜์›, ๋Œ€๊ธฐ์—… ์ž„์› ๋“ฑ ์ƒ๋Ÿฌ๋ฆฌ์•„ํŠธ : ์ƒ๋Œ€์ ์œผ๋กœ ์•ˆ์ •๋œ ๋ด‰๊ธ‰ ์ƒํ™œ์ž ํ”„๋กœํ”ผ์‹œ์–ธ : ํ”„๋ฆฌ๋žœ์„œ ์ „๋ฌธ๊ฐ€ ํ•˜์œ„์ธต ๊ณ„๊ธ‰ ํ”„๋กค๋ ˆํƒ€๋ฆฌ์•„ : ์ฃผ๋กœ ๋…ธ๋™์œผ๋กœ ๋จน๊ณ  ์‚ฌ๋Š” ์‚ฌ๋žŒ ํ”„๋ ˆ์นด๋ฆฌ์•„ํŠธ : ๋ถˆ์•ˆ์ •ํ•œ ๋…ธ๋™์œผ๋กœ ๋จน๊ณ  ์‚ฌ๋Š” ์‚ฌ๋žŒ ๋ฃธํŽœ ํ”„๋ ˆ์นด๋ฆฌ์•„ํŠธ : ๋…ธ์ˆ™์ž, ๊ทน๋นˆ์ธต, ์•ฝ๋ฌผ์ค‘๋…์ž ๋“ฑ์˜ ์‚ฌํšŒ ๋ถ€์ ์‘์ž ๊ธฐ์ƒ์ถฉ ๋ถ„์„ ์˜ํ™” <๊ธฐ์ƒ์ถฉ>์—์„œ ๋‹ค๋ฃจ๊ณ  ์žˆ๋Š” ๋ฌธ์ œ์  ํ˜„์‹ค ๋ถˆํ‰๋“ฑํ•œ ๊ณ„๊ธ‰ ๊ตฌ์กฐ์—์„œ ๊ธฐ์ธํ•˜๋Š” ๋ชจ์ˆœ๋œ ์ •ํ™ฉ๋“ค ์ƒ์ธต๊ณผ ํ•˜์ธต ๊ณ„๊ธ‰์ด ๋ช…๋ฃŒํ•˜๊ฒŒ ๋ถ„ํ• ๋œ ์‚ฌํšŒ์™€ ๊ทธ๋กœ ์ธํ•ด ํŒŒ์ƒ๋˜๋Š” ๋ถ€์ •ํ•œ ์ƒํ™ฉ์— ์ดˆ์ ์„ ๋งž์ถค ์ฃผ๋ชฉํ•  ์ ์€ <๊ธฐ์ƒ์ถฉ>์— ๋‚˜ํƒ€๋‚˜๋Š” ๊ณ„๊ธ‰ ๋ฌธ์ œ๊ฐ€ ํ•œ๊ตญ๋งŒ์ด ์•„๋‹Œ ๋Œ€๋‹ค์ˆ˜์˜ ๋‚˜๋ผ์—์„œ๋„ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ž„ ๊ทธ๋Ÿผ์—๋„ ๋ณผ๊ตฌํ•˜๊ณ , ํ•œ๊ตญ์ธ๋งŒ์ด ๋ผ›์†๊นŒ์ง€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์š”์†Œ๋กœ ํฌ์ง„๋˜์–ด ์žˆ์Œ (๋ฐ˜์ง€ํ•˜, ํ•™๋ฒŒ์ค‘์‹ฌ์ฃผ์˜, ์ž์˜์—…์ž์˜ ๋ชฐ๋ฝ ๋“ฑ) ์ œ๋ชฉ <๊ธฐ์ƒ์ถฉ>์˜ ์˜๋ฏธ ์ž‘ํ’ˆ ์† ํ‰๋ฒ”ํ•œ ์‚ฌ๋žŒ๋“ค์„ ‘์ถฉ’์ด๋ผ๊ณ  ์ง€์นญํ•จ์œผ๋กœ์จ ํ•œ๊ตญ ์‚ฌํšŒ์— ๋งŒ์—ฐํ•œ ์ž์กฐ์  ๋ถ„์œ„๊ธฐ๋ฅผ ๋Œ€๋ณ€ ์Šค์Šค๋กœ๋ฅผ ๋ฒŒ๋ ˆ์— ๋น—๋Œ€์–ด ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ ๊ทธ์ž์ฒด๋กœ ์„ฑ์žฅ๊ณผ ์„ฑ์ทจ์˜ ๊ฐ€๋Šฅ์„ฑ ์ œ๊ฑฐ <๊ธฐ์ƒ์ถฉ>์€ ์ œ๋ชฉ์ฒ˜๋Ÿผ ํ•œ๊ตญ ์‚ฌํšŒ์˜ ์ „๋ฉดํ™”๋œ ๋ฌด๊ธฐ๋ ฅ์„ ํฌ์ฐฉ, ๋ชจ๋“  ์ฑ…์ž„์„ ์ž์‹ ์˜ ๋ฌด๋Šฅ๊ณผ ๋ถˆ์šด์œผ๋กœ ๋Œ๋ฆฌ๋Š” ๊ฒƒ์ด ๋” ์•ˆ๋ฝํ•œ ์‹œ๋Œ€๋กœ ์ „๋ฝํ–ˆ์Œ์„ ํ‘œํ˜„ ๋“ฑ์žฅ์ธ๋ฌผ ๋˜๋Š” ์ง‘๋‹จ ๋ถ„์„ ๊ธฐํƒ ๊ฐ€์กฑ (ํ”„๋ ˆ์นด๋ฆฌ์•„ํŠธ ๊ณ„๊ธ‰) ํ›”์ณ์„œ ์“ธ ์ˆ˜ ๋ฐ–์— ์—†๊ณ  ์–ธ์ œ ๋Š๊ธธ์ง€ ๋ชจ๋ฅด๋Š” ์™€์ดํŒŒ์ด ์ฃผ๋กœ ์‚ฌ๋žŒ์ด ์‚ด๊ธฐ ์–ด๋ ค์šด ์Šตํ•˜๊ณ  ๋”๋Ÿฌ์šด ํ™˜๊ฒฝ์— ๊ฑฐ์ฃผํ•˜๋Š” ๊ณฑ๋“ฑ์ด์˜ ์ถœ๋ชฐ ์•ˆ์ „ํ•œ ์ฃผ๊ฑฐ ํ™˜๊ฒฝ์ด ์•„๋‹˜์„ ์ฆ๋ช…ํ•˜๋Š” ๋…ธ์ƒ๋ฐฉ๋‡จ์ž ํ•ญ์ƒ ์ฃผ๊ด€์  ํญ๋ ฅ์— ๋…ธ์ถœ๋˜์–ด ์žˆ๋Š” ๋ถˆ์•ˆ์ •ํ•œ ์‚ถ์„ ์‚ด์•„๊ฐ ๋ฐ˜์ง€ํ•˜ ์ฃผ๊ฑฐ = ํ”„๋ ˆ์นด๋ฆฌ์•„ํŠธ ๊ณ„๊ธ‰์˜ ์‚ถ์„ ๋ช…์‹œํ•˜๊ณ  ์ƒ์ง•ํ•˜๋Š” ์žฅ์†Œ ๋ฐ˜์ง€ํ•˜๋Š” ํ•˜์œ„์ธต ๊ณ„๊ธ‰์˜ ๋นˆ๊ณคํ•œ ๊ฒฝ์ œ ์ž๋ณธ์œผ๋กœ ๋ถ€์œ ํ•œ ์‚ฌ๋žŒ๋“ค์˜ ๊ฒฝ์ œ ์ž๋ณธ์„ ์ฑ„์›Œ์ฃผ๋Š” ์—ญํ•  ํ™”์žฅ์‹ค์ด ๊ฐ€์žฅ ์œ„์— ์žˆ์Œ -> ๋ฐ˜์ง€ํ•˜ ์ค‘์—์„œ๋„ ๊ธฐ๊ดดํ•œ ์ง‘์˜ ํ˜•ํƒœ ํ”„๋ ˆ์นด๋ฆฌ์•„ํŠธ ๊ณ„๊ธ‰์ž„์—๋„ ๊ธฐํƒ๊ฐ€์กฑ์€ ๋นˆ๊ณคํ•˜๊ณ  ํฌ๋ง์ด ์—†๋Š” ์‚ถ์— ๋Œ€ํ•œ ์šธ๋ถ„์ด๋‚˜ ๋ถ„๋…ธ, ์Šฌํ””์ด ์ „ํ˜€ ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ -> ์ ˆ๋ง์ ์ธ ์ƒํ™ฉ์„ ์ˆ˜์šฉํ•  ์ˆ˜๋ฐ–์— ์—†๋„๋ก ์ž์‹ ์„ ์„ธ๋‡Œ ๊ธฐํƒ๊ฐ€์กฑ์€ ์ฒ˜์Œ์— ์ƒ์œ„ ํ”„๋กค๋ ˆํƒ€๋ฆฌ์•„ ๊ณ„๊ธ‰ -> ๊ณผ๊ฑฐ ๊ธฐํƒ์˜ ํ”„๋žœ์ฐจ์ด์ฆˆ ์‚ฌ์—… ์‹คํŒจ -> ํ”„๋ ˆ์นด๋ฆฌ์•„ํŠธ ๊ณ„๊ธ‰์€ ์•„๋ฌด๋ฆฌ ๋…ธ๋ ฅํ•˜๋”๋ผ๋„ ๋ฏธ๋ž˜๋ฅผ ๊ฟˆ๊ฟ€์ˆ˜ ์—†๋Š” ์ง‘๋‹จ ๋™์ต ๊ฐ€์กฑ (์ตœ์ƒ์œ„ ์—˜๋ฆฌํŠธ ๊ณ„๊ธ‰) ๋™์ต๊ฐ€์กฑ์˜ ์ง‘์€ ์ฒ ์ €ํžˆ ์€ํ ๋ชจ๋“  ์นจ์ž…์œผ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ -> ๊ณ„๊ธ‰๊ฐ„ ์„ž์ผ ์ˆ˜ ์—†์Œ (๊ตฌ๋ณ„์ง“๊ธฐ) ๋™์ต๊ฐ€์กฑ์€ ๊ต‰์žฅํžˆ ์  ํ‹€ํ•˜๊ณ  ์‹ฌํ”Œํ•˜๊ฒŒ ๊ทธ๋ ค์ง, ๋ˆ๊ณผ ๊ถŒ๋ ฅ์— ์ง‘์ฐฉํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฌด๋ก€ํ•˜์ง€ ์•Š์Œ -> ๊ธฐํƒ๊ฐ€์กฑ์˜ ํ–‰์œ„๊ฐ€ ๋”์šฑ ์น˜์กธ, ์ถ”์žกํ•ด ๋ณด์ด๋Š” ํšจ๊ณผ ์ž์‹ ๋„ ๋ชจ๋ฅด๊ฒŒ ๊ธฐํƒ, ๋ฌธ๊ด‘-๊ทผ์„ธ ๋ถ€๋ถ€์—๊ฒŒ ๊ฐ๊ด€์  ํญ๋ ฅ -> ์ฃผ๊ด€์  ํญ๋ ฅ์œผ๋กœ ์ด์–ด์ง ๋ฌธ๊ด‘-๊ทผ์„ธ ๋ถ€๋ถ€(๋ฃธํŽœ ํ”„๋ ˆ์นด๋ฆฌ์•„ํŠธ ๊ณ„๊ธ‰) ๊ทผ์„ธ : ์ฑ„๊ถŒ์ž๋ฅผ ํ”ผํ•ด 4๋…„ ๋™์•ˆ ๋ฐฉ๊ณตํ˜ธ์— ์ˆจ์–ด์ง€๋‚ด๋Š” ์ธ๋ฌผ ๋™์ต ๊ฐ€์กฑ์„ ์šฐ์ƒํ™”ํ•˜๋Š” ๋‚ด๋ฉดํ™”๋œ ์กด์žฌ ๊ณ„๊ธ‰ ๊ฐ„ ๊ฐˆ๋“ฑ ๊ตฌ์กฐ ๊ธฐํƒ ๊ฐ€์กฑ vs ๋™์ต ๊ฐ€์กฑ ๊ฐˆ๋“ฑ์˜ ์‹œ๋ฐœ์  : ๋™์ต ๊ฐ€์กฑ์œผ ์™ธ์ถœ๋กœ ์ธํ•œ ๋ถ€์žฌ๋ฅผ ํ‹ˆ ํƒ„ ๊ธฐํƒ ๊ฐ€์กฑ์˜ ์ƒ๋ฅ˜์ธต ์ฒดํ—˜๊ณผ ์ขŒ์ ˆ ๋™์ต ๊ฐ€์กฑ์˜ ๋ณต๊ท€ -> ํ”„๋ ˆ์นด๋ฆฌ์•„ํŠธ ๊ณ„๊ธ‰์œผ๋กœ์„œ ๊ธฐํƒ๊ฐ€์กฑ์˜ ํ˜„์‹ค์„ ๊นจ๋‹ซ๊ฒŒ ๋งŒ๋“ฌ ๋™์ต์ด ์–ธ๊ธ‰ํ•œ ๋ƒ„์ƒˆ, ๊ธฐํƒ๊ฐ€์กฑ์„ ํ˜์˜ค ๋Œ€์ƒ์œผ๋กœ ๋‚™์ธ, ๋ชจ๋ฉธ๊ฐ๊ณผ ์ˆ˜์น˜์‹ฌ์„ ๋ฐœ์ƒ ๋™์ต ๊ฐ€์กฑ์— ํ˜์˜ค ๋Œ€์ƒ์œผ๋กœ ๋‚™์ธ ์ฐํžŒ ํ›„ ๊ธฐํƒ ๊ฐ€์กฑ์˜ ๋ชจ์Šต์€ ๋Š์ž„์—†์ด ํ•˜๊ฐ• -> ํ”„๋ ˆ์นด๋ฆฌ์•„ํŠธ ๊ณ„๊ธ‰์˜ ์œ„์น˜๋ฅผ ๋ณด์—ฌ์คŒ ๋™์ต์ด ์–ธ๊ธ‰ํ•œ ๋ƒ„์ƒˆ, ์ง‘์œผ๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ธธ ํญ์šฐ -> ๋ƒ„์ƒˆ๊ฐ€ ์ง€์›Œ์ง€์ง€ ์•Š๋Š” ํ˜„์‹ค, ๋ฌผ๋‚œ๋ฆฌ -> ์ตœ์•…์˜ ์ƒํ™ฉ ๊ธฐํƒ๊ฐ€์กฑ์€ ๋ชจ๋ฉธ๊ฐ์„ ๋ฐ›์•˜์Œ์—๋„ ๊ณ„์†ํ•ด์„œ ์ƒ์œ„์ธต ๊ณ„๊ธ‰์„ ์œ„ํ•ด ๋…ธ๋™๋ ฅ์„ ์ œ๊ณต, ๋™์ต๊ฐ€์กฑ์€ ๊ณ„์† ๊ณ ์šฉ์ฃผ๋ฅผ ์ด์–ด๋‚˜๊ฐ ๊ธฐํƒ ๊ฐ€์กฑ vs ๋ฌธ๊ด‘-๊ทผ์„ธ ๋ถ€๋ถ€ ํ•˜์œ„์ธต ๊ณ„๊ธ‰๊ณผ ๊ทธ๋ณด๋‹ค ๋” ๋‚ฎ์€ ๊ณ„๊ธ‰์˜ ์ƒ์กด์„ ์œ„ํ•œ ์‚ฌํˆฌ ์„œ๋กœ ํž˜์„ ํ•ฉ์น˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ์„œ๋กœ๋ฅผ ์ œ๊ฑฐํ•˜๋ ค๋Š” ํญ๋ ฅ์„ ๋ฐœ์ƒ์‹œํ‚ด ๋™์ต ๊ฐ€์กฑ์€ ์ด๋“ค์˜ ์‚ฌํˆฌ๋ฅผ ์•Œ์ง€๋ชปํ•˜๊ณ , ๊ด€์‹ฌ์กฐ์ฐจ ์—†์Œ ๋™์ต ๊ฐ€์กฑ vs ๊ธฐํƒ ๊ฐ€์กฑ vs ๋ฌธ๊ด‘-๊ทผ์„ธ ๋ถ€๋ถ€ ๋‘ ํ•˜์œ„ ๊ณ„๊ธ‰์˜ ์ถฉ๋Œ์€ ๊ฒฐ๊ตญ ์‚ด์ธ๊ณผ ๊ทธ๋กœ ์ธํ•œ ํฌ์ƒ์œผ๋กœ ์ด์–ด์ง„๋‹ค -> ๋™์ต์˜ ์ฃฝ์Œ ํ•˜์œ„ ๊ณ„๊ธ‰๊ฐ„ ์ˆ˜ํ‰ ํญ๋ ฅ์ด ๊ณ„๊ธ‰ ๊ฐ„ ์ˆ˜์ง ํญ๋ ฅ์œผ๋กœ ์ „์ด -> ๊ณ„๊ธ‰ ๋ฌธ์ œ๋Š” ์‚ฌํšŒ์  ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ, ๋‹ค๋ฅธ ํญ๋ ฅ์œผ๋กœ ์ด์–ด์ง€๋Š” ์•…์ˆœํ™˜์„ ํ‘œํ˜„ ๋…๋ฆฝ์˜ํ™” ๋…๋ฆฝ์˜ํ™”์˜ ์ •์˜์™€ ํŠน์ง• ์ด์œค ์ถ”๊ตฌ๋ฅผ ์ตœ์šฐ์„  ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ์ผ๋ฐ˜ ์ƒ์—… ์˜ํ™”(๋Œ€์ค‘ ์˜ํ™”)์™€๋Š” ๋‹ฌ๋ฆฌ ์ฐฝ์ž‘์ž์˜ ์˜๋„๊ฐ€ ์ค‘์‹œ๋˜๋Š” ์˜ํ™” ํŠน์ง• ์ฃผ๋กœ ๊ธด ์ƒท(๋กฑ ํ…Œ์ดํฌ)๋ฅผ ์ž์ฃผ ์‚ฌ์šฉ ์ž์—ฐ์Šค๋Ÿฝ๊ณ  ์ฆ‰ํฅ์  ๋Œ€์‚ฌ๋ฅผ ์„ ํ˜ธ ํ—๋ฆฌ์šฐ๋“œ์‹ ์Šคํ† ๋ฆฌํ…”๋ง(๊ธฐ์Šน์ „๊ฒฐ)์— ๋Œ€ํ•œ ํƒˆํ”ผ ์‹œ๋„ ๊ฐ๋…์˜ ๋น„์ค‘์ด ์ปค์ง. ํ˜„์‹ค๊ณ ๋ฐœ์ ์ธ ๋‚ด์šฉ์„ ๋งŽ์ด ๋‹ค๋ฃจ๋ฉฐ ์ด๋กœ ์ธํ•˜์—ฌ ์ •๋ถ€์™€์˜ ํ˜‘์กฐ์ ์ด์ง€ ์•Š์€ ๊ด€๊ณ„๊ฐ€ ์„ฑ๋ฆฝํ•˜๊ธฐ๋„ ํ•จ ๋‹ค์Œ ์‹œ๊ฐ„๊นŒ์ง€ ์ค€๋น„ํ•  ์‚ฌํ•ญ ๊ฐ์ƒํ•œ ์ž‘ํ’ˆ์„ ํ† ๋Œ€๋กœ ๊ฐ๊ฐ์˜ ์ฃผ์ œ๊ฐ€ ๊ตฌํ˜„๋˜๋Š” ๋ฐฉ์‹๊ณผ ์ด๋ฅผ ํ†ตํ•˜์—ฌ ์ƒ๊ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ๋Š” ํŠน์ง•์€ ๋ฌด์—‡์ธ์ง€ ๊ณ ๋ฏผํ•ด์˜ฌ ๊ฒƒ ํ•œ๊ตญ ์˜ํ™” ์† ์ฒญ๋…„ ์„ธ๋Œ€์˜ ๋ชจ์Šต 1970๋…„๋Œ€ : ๋Œ€๋Ÿ‰ ์ƒ์‚ฐ, ๋Œ€๋Ÿ‰ ์†Œ๋น„๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง€๋ฉด์„œ ๋Œ€์ค‘ ๋ฌธํ™”์˜ ์˜์—ญ์ด ํ™•์žฅ๋œ ์‹œ๊ธฐ ๋Œ€์ค‘์†Œ๋น„์‚ฌํšŒ์˜ ํ™•์‚ฐ ๊ฐ€์†ํ™” 1960๋…„๋Œ€๋ณด๋‹ค ์ƒ์—…์ , ์˜ˆ์ˆ ์  ์ธก๋ฉด์—์„œ ์˜ํ™”๊ฐ€ ๋’ค๋–จ์–ด์ง ์ด์œ  : ํŒŒ์‹œ์ฆ˜์  ๋…์žฌ ์ •์น˜, ์‚ฐ์—…์ž๋ณธ์ฃผ์˜์˜ ๊ณ ๋„ํ™”, ๋…ธ๋™๋ฌธ์ œ์™€ ๋„์‹œ๋ฌธ์ œ์˜ ๋Œ€๋‘, ํ–ฅ๋ฝ์‚ฐ์—…์˜ ์„ฑ์žฅ ์ฒญ๋…„์„ธ๋Œ€๋ฅผ ์ฃผ์ธ๊ณต์œผ๋กœ ์‚ผ์€ ์˜ํ™”๊ฐ€ ๋งŽ์•˜์Œ ์ด ์‹œ๊ธฐ ์˜ํ™”๋“ค์€ ํ™œ๋ ฅ๊ณผ ์šฐ์šธ์ฆ์˜ ์ง•ํ›„๋“ค์ด ๊ธฐ๋ฌ˜ํ•˜๊ฒŒ ๊ณต์กด 1980๋…„๋Œ€ : ์ •์น˜์ , ์‚ฌํšŒ์  ๊ฒฉ๋ณ€์˜ ์‹œ๊ธฐ์ด์ž ๋ถˆ์•ˆ๊ณผ ๊ธด์žฅ์ด ์ง€์†๋˜๋Š” ์‹œ๋Œ€ ์ „๋‘ํ™˜ ์ •๊ถŒ์˜ ๋Œ€์ค‘ ํ†ต์ œ ์ •์ฑ…, ์ „๋‘ํ™˜ ์ •๊ถŒ์˜ ๋ชฐ๋ฝ๊ณผ ๋ฏผ์ฃผํ™” ์ฒด์ œ์˜ ์‹œ์ž‘ ๋‚ฎ์—๋Š” ์ •๊ถŒ์˜ ํญ์••์ •์น˜์— ๋งž์„œ ๋Œ์„ ๋˜์ง€์ง€๋งŒ, ๋ฐค์—๋Š” ์ •๊ถŒ์— ๋งž์ถฐ ์‹ธ๊ตฌ๋ ค ์—๋กœ ์˜ํ™”๋ฅผ ์ฆ๊น€ 3S์ •์ฑ…๊ณผ ๊ฒ€์—ด๋•Œ๋ฌธ์— ์—๋กœ ์˜ํ™”๊ฐ€ ๋ฒ”๋žŒ 1980๋…„๋Œ€ ์ค‘๋ฐ˜ ์ดํ›„ ์ฒญ์ถ˜ ์˜ํ™”๊ฐ€ ๋‘๊ฐ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์‹œ์ž‘ ์ Š์€ ๊ฐ๋…์„ ์ค‘์‹ฌ์œผ๋กœ ํ˜„์‹ค ๋น„ํŒ์ ์ธ ์ž‘ํ’ˆ๋“ค์ด ๋‚˜์˜ค๊ธฐ ์‹œ์ž‘ํ•จ 1990๋…„๋Œ€ : ์ฒญ๋…„์˜ํ™”๊ฐ€ ๊ฑฐ์˜ ์—†์Œ ํ˜„์žฌ(2000๋…„๋Œ€) ๋” ์ด์ƒ ์ฒญ๋…„ ์„ธ๋Œ€๋Š” ์†Œ๋น„์™€ ๋ฌธํ™”์˜ ์ฃผ์ฒด๋กœ์„œ์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ•˜๋Š” ์กด์žฌ๋กœ ์ „๋ฝ ์‹ ๋นˆ๊ณค์˜ ์ƒํ™ฉ : ๊ฒฝ์ œ์  ๋ฐ•ํƒˆ + ์‚ฌํšŒ์  ๋ฐฐ์ œ + ๋ฌธํ™”์  ์†Œ์™ธ -> ์‚ฌํšŒ์  ๋ถˆํ‰๋“ฑ ์ฒญ๋…„์€ ์ž ์ž˜ ๊ณณ์„ ์ฐพ์•„ ๋– ๋„๋Š” ‘homeless’, ๋ชจ๋“  ์‚ฌ์  ๊ด€๊ณ„๊ฐ€ ์™€ํ•ด๋˜๋Š” ๊ณ ๋ฆฝ์˜ ์ƒํ™ฉ์œผ๋กœ ์žฌํ˜„๋จ ์˜ํ™” <์†Œ๊ณต๋…€> ๋ถ„์„ ์ œ๋ชฉ์˜ ์˜๋ฏธ ์†Œ๊ณต๋…€ : 1905๋…„ ๋ฐœ๊ฐ„๋œ ๋ฏธ๊ตญ์˜ ์—ฌ์„ฑ์ž‘๊ฐ€ ํ”„๋žœ์‹œ์Šค ๋ฒ„๋„ท์˜ ์†Œ์„ค๊ณผ ๋™์ผํ•œ ์ œ๋ชฉ ๊ณตํ†ต์  : ์†Œ์„ค ์† ์ฃผ์ธ๊ณต ์ƒˆ๋ผ์™€ ์˜ํ™” ์† ์ฃผ์ธ๊ณต ๋ฏธ์†Œ ๋ชจ๋‘ ํ–‰๋ณต์„ ์ถ”๊ตฌ ์ฐจ์ด์  : ์ƒˆ๋ผ์˜ ๊ฒฝ์šฐ ํƒ€์ธ์˜ ๋„์›€์œผ๋กœ ๊ฒฝ์ œ์  ์•ˆ์ • ๋ฐ ํ–‰๋ณต์„ ์„ฑ์ทจ, ๋ฏธ์†Œ๋Š” ์ž์‹ ์˜ ํž˜์œผ๋กœ ์ž์‹ ๋งŒ์˜ ๊ณต๊ฐ„ ํ™•๋ณด ์˜์–ด ์ œ๋ชฉ <Microhabitat> : ์„œ์‹์ง€ ๋“ฑ์žฅ์ธ๋ฌผ์˜ ํŠน์ง• ๋ฏธ์†Œ ์ผ์ข…์˜ ์ฒญ๋…„ ๋‚œ๋ฏผ : ์ถฉ๋ถ„ํ•œ ๊ฑฐ์ฃผ ๊ณต๊ฐ„์ด ์—†์œผ๋ฉฐ, ์–ด๋–ค ๊ณต๋™์ฒด๋„ ์ด๋ฃจ์ง€ ๋ชปํ•จ -> ์ฒญ๋…„ ์„ธ๋Œ€๊ฐ€ ์‚ฌํšŒ์  ์ฃผ์ฒด๋กœ ์ธ์ •๋ฐ›์ง€ ๋ชปํ•˜๋Š” ์›์ธ ์ž์‹ ์˜ ์ƒํ™ฉ์„ ํž˜๋“ค์–ดํ•˜๊ฑฐ๋‚˜ ๋ถ€๋„๋Ÿฌ์›Œํ•˜์ง€ ์•Š์Œ ์Œ€์ด ์—†์–ด ๋ผ๋‹ˆ๋ฅผ ๋•Œ์šฐ์ง€ ๋ชปํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋„ ์œ„์Šคํ‚ค์™€ ๋‹ด๋ฐฐ๋ฅผ ํฌ๊ธฐํ•˜์ง€ ์•Š์Œ ์˜ค๋Š˜๋‚  ์ฒญ๋…„์„ธ๋Œ€๊ฐ€ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋Š” ๊ฐ€์น˜๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ƒ๊ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ์Œ ์ž์‹ ์ด ์ข‹์•„ํ•˜๋Š” ๊ฒƒ์„ ์œ„ํ•˜์—ฌ ๊ธฐ๊บผ์ด ์ฃผ๊ฑฐํ™˜๊ฒฝ(์ง‘)์„ ํฌ๊ธฐ ๋ฌธ์˜ ์ข‹์€ ์ง์žฅ์— ๋‹ค๋‹ˆ๋Š” ์ •๊ทœ์ง, ๋” ์ข‹์€ ์ง์—…์„ ๊ฐ–๊ณ ์ž ๋…ธ๋ ฅํ•˜๋Š” ์ธ๋ฌผ ์„ฑ๊ณผ ์ฃผ์ฒด์  ์ธ๋ฌผ : ์„ฑ์ฐฐ์„ ์ƒ์‹คํ•œ ์ธ๊ฐ„ + ์žํ์  ์„ฑ๊ณผ ๊ธฐ๊ณ„ ๋ฌธ์˜์—๊ฒŒ ์žˆ์–ด์„œ ์ผ์€ ๋‹จ์ˆœ ๋…ธ๋™์ด์ž ๋” ๋†’์€ ๊ณณ์œผ๋กœ ์˜ฌ๋ผ๊ฐ€๊ธฐ ์œ„ํ•œ ๋ฐœํŒ ๋ฏธ์†Œ์™€ ๋Œ€๋น„ ํ˜„์ • ์ „ํ˜•์ ์ธ ํ•œ๊ตญ ๊ฐ€๋ถ€์žฅ์ œ ๊ฐ€์กฑ ์† ๋ฉฐ๋А๋ฆฌ์˜ ์‚ถ ๊ฐ€์กฑ ๊ตฌ์„ฑ์›์œผ๋กœ์„œ ๋™๋“ฑํ•œ ์ธ๊ฒฉ์ฒด๊ฐ€ ์•„๋‹Œ ๋‹จ์ˆœ ๊ฐ€์‚ฌ๋…ธ๋™์ž๋กœ ์ „๋ฝํ•œ ๋ชจ์Šต ๊ฐ€์กฑ๊ฐ„ ์†Œํ†ต์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์œผ๋ฉฐ, ๊ทธ๋กœ ์ธํ•œ ์ด๊ธฐ์‹ฌ์˜ ๋งŒ์—ฐ ๋ฐ ๊ทธ์— ๋”ฐ๋ฅธ ํฌ์ƒ ๊ฐ•์š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ ํ˜„์‹ค๊ณผ ํƒ€ํ˜‘ํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ฒฐํ˜ผ์„ ์„ ํƒํ•œ ์ฒญ๋…„์„ธ๋Œ€์˜ ์žํ•˜์†ฝ ๋Œ€์šฉ ์˜ค๋Š˜๋‚  ์ฒญ๋…„์„ธ๋Œ€์˜ ๊ฒฐํ˜ผ ๋ฐ ์ฃผ๊ฑฐ ๋ฌธ์ œ๋ฅผ ์ƒ์ง•ํ•˜๋Š” ์ธ๋ฌผ ๊ฒฐํ˜ผ์„ ์ดํ˜ผ์œจ์ด ๋” ๋†’์€ ์ฒญ๋…„ ์„ธ๋Œ€์˜ ๋ฌธ์ œ๋ฅผ ๋“œ๋Ÿฌ๋ƒ„ ์ผ์ข…์˜ ํ•˜์šฐ์Šคํ‘ธ์–ด์ด์ž, ์ž๋ณธ์ฃผ์˜ ์‚ฌํšŒ์˜ ์ „ํ˜•์  ๋ถ€์ฑ„์ธ๊ฐ„์ž„ ์ง‘์€ ๋”ฐ๋œปํ•˜๊ณ  ์•ˆ์ „ํ•œ ๊ณต๊ฐ„์ด ์•„๋‹Œ, ๋ถ€์ฑ„๋กœ ์ธํ•œ ๊ณ ํ†ต์˜ ๊ณต๊ฐ„์œผ๋กœ ๋ณ€์งˆ ์ž๋ณธ์ฃผ์˜ ์‚ฌํšŒ์—์„œ ์ฒญ๋…„ ๊ฒฐํ˜ผ๋ฌธ์ œ์™€ ์ฃผ๊ฑฐ ์ง‘์ฐฉ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ์Œ ๋ก์ด ๋ถ€๋ชจ๋กœ๋ถ€ํ„ฐ ๊ฒฝ์ œ์  ๋…๋ฆฝ์„ ํ•˜์ง€ ๋ชปํ•œ ์ฒญ๋…„ ์„ธ๋Œ€ ๋ถ€๋ชจ์˜ ๋„์›€์—†์ด ๊ฒฐํ˜ผ์กฐ์ฐจ ๋งˆ์Œ๋Œ€๋กœ ํ•  ์ˆ˜ ์—†๋Š” ์ฒญ๋…„ ์„ธ๋Œ€ ๋ก์ด ๊ฐ€์กฑ์˜ ๋ชจ์Šต์„ ํ†ตํ•˜์—ฌ ์˜ค๋Š˜๋‚  ๊ธฐ์„ฑ ์„ธ๋Œ€์™€ ์ฒญ๋…„ ์„ธ๋Œ€์˜ ๊ฐ€์น˜๊ด€ ์ฐจ์ด๊ฐ€ ๋ฌด์—‡์ธ์ง€๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Œ (๊ฐœ์ธ์˜์ง€์™€ ์ž์œ ์˜์‹ vs ์ „ํ†ต์ ์ธ ํšจ ๊ด€๋…๊ณผ ๊ฒฐํ˜ผ์— ๋Œ€ํ•œ ๊ฐ€์น˜๊ด€) ๊ธฐ์„ฑ์„ธ๋Œ€๊ฐ€ ๋ฐ”๋ผ๋Š” ๊ฐ€์ •์ด๋ผ๋Š” ์•ˆ์ •๊ณผ ์ฃผ๊ฑฐํ™˜๊ฒฝ์ด๋ผ๋Š” ์šธํƒ€๋ฆฌ ํ™•๋ณด vs ์–ด๋””์—๋„ ๊ตฌ์†๋ฐ›์ง€ ์•Š๊ณ  ์‚ด์•„๊ฐ€๊ณ ์žํ•˜๋Š” ์ฒญ๋…„์„ธ๋Œ€์˜ ๋Œ€๋ฆฝ ์ •๋ฏธ ๊ฒฐํ˜ผ์ด๋ผ๋Š” ์ œ๋„๋ฅผ ํ†ตํ•˜์—ฌ ๋‚จ๋“ค์ด ๋ถ€๋Ÿฌ์›Œํ•˜๋Š” ๊ฒฝ์ œ์ ์œผ๋กœ ํ’์š”๋กœ์šด ์‚ถ์„ ์‚ด์•„๊ฐ€๋Š” ์ฒญ๋…„ ์„ธ๋Œ€์˜ ๋ชจ์Šต ๊ฒฝ์ œ๋ ฅ์„ ๊ณผ์‹œํ•จ์œผ๋กœ์จ ํƒ€์ธ์—๊ฒŒ ๋ถ€๋Ÿฌ์›€์„ ์‚ฌ๊ณ , ์ด๋ฅผ ํ†ตํ•˜์—ฌ ์ฆ๊ฑฐ์›€์„ ์–ป๊ณ ์žํ•˜๋Š” ์ฒญ๋…„์„ธ๋Œ€์˜ ๋ชจ์Šต ์ „ํ˜•์ ์ธ ํ—ˆ์„ธ๋ฅผ ์ถ”๊ตฌํ•˜๋Š” ์‚ถ ๊ฐ€์ง„ ๊ฒƒ์ด ์—†์–ด๋„ ๋‹น๋‹นํ•œ ๋ฏธ์†Œ์˜ ๋ชจ์Šต์— ๋ถˆํŽธํ•จ์„ ๋А๋‚Œ, ๊ฒฝ์ œ๋ ฅ๋งŒ ๊ฐ€์ง€๊ณ ๋Š” ํ–‰๋ณต์„ ์–ป์„์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์คŒ ํ•œ์†” ๊ฐ€์žฅ ์˜ค๋Š˜๋‚  ์ฒญ๋…„ ์„ธ๋Œ€์˜ ๋ชจ์Šต๊ณผ ๋‹ฎ์•„ ์žˆ๋Š” ์ธ๋ฌผ ํ˜„์‹ค์ด๋ผ๋Š” ๋ฌด๊ฒŒ๋กœ ์ธํ•˜์—ฌ ์ž์‹ ์˜ ๊ฟˆ๊ณผ ํฌ๋ง, ๊ทธ๋ฆฌ๊ณ  ์‚ฌ๋ž‘๋งˆ์ € ํฌ๊ธฐํ•  ์ˆ˜ ๋ฐ–์— ์—†์Œ์„ ๋ณด์—ฌ์คŒ ํ•œ์†” ์—ญ์‹œ ์ฒญ๋…„์ด๋ผ๋Š” ๊ธฐ์ค€์—์„œ ์ ์  ๋ฉ€์–ด์ง€๋Š” ๊ฒƒ์„ ๋А๋ผ๊ฒŒ ๋จ์œผ๋กœ์จ ๋‚จ๋“ค์ฒ˜๋Ÿผ ์กฐ๊ธˆ ๋” ์•ˆ์ •์ ์ธ ์‚ถ์„ ๋ˆ„๋ฆฌ๊ณ ์ž ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ์Œ ์—”๋”ฉ ๋งˆ์ง€๋ง‰ ์žฅ๋ฉด์—์„œ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฏธ์†Œ์˜ ๋ณ€ํ™”๋Š” ๋ฌด์—‡์ธ๊ฐ€? -> ๋ฐฑ๋ฐœ (์•ฝ์„ ํฌ๊ธฐ) ๊ฒฐ๊ตญ, ๋ฏธ์†Œ๊ฐ€ ์ •์ฐฉํ•˜๋Š” ๊ณต๊ฐ„์€ ์–ด๋””์ด๋ฉฐ, ๊ทธ ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€? -> ํ…ํŠธ ๋ฏธ์†Œ์™€ ๊ทธ ์™ธ ๋“ฑ์žฅ์ธ๋ฌผ๋“ค์˜ ๋น„๊ต๋ฅผ ํ†ตํ•ด ์ „๋‹ฌํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฉ”์‹œ์ง€๋Š” ๋ฌด์—‡์ธ๊ฐ€? ์˜ํ™”์— ๋‚˜ํƒ€๋‚œ ์ฒญ๋…„์˜ ์‚ถ ๋ฏธ์†Œ : ๊ธฐ์„ฑ์„ธ๋Œ€๊ฐ€ ์ œ์‹œํ•œ ํ–‰๋ณตํ•œ ์‚ถ์˜ ๋ฐฉ์‹(๋ถ€๋ชจ๋กœ์„œ์˜ ์‚ถ)์„ ๋ฒ—์–ด๋‚œ ์ธ๋ฌผ, ๊ธฐ์„ฑ์„ธ๋Œ€์˜ ๊ฐ€์น˜๊ด€์„ ๊ฑฐ๋ถ€ํ•˜๋ฉด ์ž˜๋ชป๋œ ์‚ถ์ด๋ผ๊ณ  ๋‚™์ธ์ฐ๋Š” ํ˜„๋Œ€ ์‚ฌํšŒ์˜ ๋ชจ์Šต์„ ๋ณด์—ฌ์คŒ ๋ฌธ์˜ : ๊ธฐ์„ฑ์„ธ๋Œ€์˜ ์š”๊ตฌ๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์ˆ˜์šฉ, ๋ฏธ์†Œ๊ฐ€ ์žฌ์›Œ๋‹ฌ๋ผ๋Š” ๋ถ€ํƒ์„ ๊ฑฐ์ ˆ -> ํ•˜์ง€๋งŒ ๋ฌธ์˜์„ ์š•ํ•  ์ˆ˜๋Š” ์—†์Œ ํ˜„์ • : ๊ธฐ์„ฑ์„ธ๋Œ€์˜ ์š”๊ตฌ๋ฅผ ์ˆ˜์šฉ, ์ฃผ๋ฅ˜์‚ฌํšŒ์— ํŽธ์ž…, ํ•˜์ง€๋งŒ ์ž์‹ ์˜ ๊ฟˆ ํฌ๊ธฐ, ๊ตฌ์„ฑ์›๊ด€ ๊ด€๊ณ„ ๋’คํ‹€๋ฆผ ๋Œ€์šฉ : ๊ธฐ์„ฑ์„ธ๋Œ€๊ฐ€ ์š”๊ตฌ๋ฅผ ์ˆ˜์šฉ, ํ•˜์ง€๋งŒ, ๊ฒฐํ˜ผ ์‹คํŒจ, ๋ถ€์ฑ„๋กœ ์ธํ•œ ๊ณ ํ†ต ๋ก์ด : ๊ธฐ์„ฑ์„ธ๋Œ€์˜ ์š”๊ตฌํ•œ ์‚ถ์— ์™„๋ฒฝํžˆ ๊ฐ‡ํžŒ ์ธ๋ฌผ, ๋ฏธ์†Œ๋ฅผ ์ฒ ๋ถ€์ง€๋กœ ์น˜๋ถ€ ์ •๋ฏธ : ๊ฒฐํ˜ผ์„ ํ†ตํ•ด ์‹ ๋ถ„ ์ƒ์Šน, ํ‘œ๋ฉด์ ์œผ๋กœ ํ–‰๋ณตํ•œ ์‚ถ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๊ณผ๊ฑฐ์˜ ์ž์‹ ๊ณผ ๊ฑฐ๋ฆฌ๋ฅผ ๋‘๊ณ  ์‚ถ, ๋‚จํŽธ์—๊ฒŒ ์ˆ˜๊ธ, ๊ฐ•๋ฐ•์ ์œผ๋กœ ํ˜„๋ชจ์–‘์ฒ˜๋กœ ๋ณด์ด๋ ค๋Š” ๋ชจ์Šต ์ฒญ๋…„ ์„ธ๋Œ€๋ฅผ ์œ„ํ˜‘ํ•˜๋Š” ์„ธ๊ฐ€์ง€ ์ฃผ๋ฅ˜ ๋ฌธํ™”์˜ ๋ฌธ์ œ์  ์ทจ์—… (์ž์•„์‹คํ˜„) ๊ธฐ์กด์˜ ์ง€๋ฐฐ๋ฌธํ™”์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ํ–‰๋ณตํ•œ ๋ฏธ์†Œ์˜ ๋ชจ์Šต์„ ๋ณด์—ฌ์คŒ์œผ๋กœ์จ ๊ธฐ์กด์˜ ์ง€๋ฐฐ๋ฌธํ™”๊ฐ€ ์ฒญ๋…„ ์„ธ๋Œ€๋ฅผ ์œ„ํ˜‘ํ•˜๋Š” ์š”์†Œ์ผ์ˆ˜๋„ ์žˆ์Œ์„ ๋ณด์—ฌ์คŒ ๊ฒฐํ˜ผ ๋Œ€์šฉ์„ ํ†ตํ•ด์„œ ๋Œ€์šฉ์„ ํ†ตํ•ด ์˜๋ฌธ์„ ๋˜์ง, ์ •๋ฏธ๋ฅผ ํ†ตํ•ด ๊ฒฐํ˜ผ์„ ์œ„ํ•ด ํฌ๊ธฐํ•ด์•ผํ•˜๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์คŒ ์ง‘ ํ…ํŠธ๋ฅผ ์„ ํƒํ•œ ๋ฏธ์†Œ๋ฅผ ํ†ตํ•ด ์œ ๋ชฉ๋ฏผ์ฒ˜๋Ÿผ ๋– ๋Œ์ˆ˜ ๋ฐ–์— ์—†๋Š” ์ฒญ๋…„ ์„ธ๋Œ€๋ฅผ ๋ณด์—ฌ์คŒ ์ง‘์„ ์–ป์–ด๋„ ํ–‰๋ณตํ•˜์ง€ ์•Š์„ ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์คŒ ๋ฏธ์†Œ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์ด์ƒ์  ํŒํƒ€์ง€์  ์ฒญ๋…„ ์„ธ๋Œ€์˜ ๋ชจ์Šต ํฌ๊ธฐ ๋ฌด์†Œ์œ  2000๋…„๋Œ€ ์ดํ›„ ๊ฐ์ข… ์ฝ˜ํ…์ธ ์— ์žฌํ˜„๋œ ‘์ฒญ๋…„์„ธ๋Œ€’์˜ ๋ชจ์Šต ์ด์ƒ์ ์ธ ์ž์•„ ๋ฐ˜์˜ ์ฃผ๋กœ ์›นํˆฐ์œผ๋กœ ํ‘œํ˜„ : ์˜ค๋Š˜๋‚  ์ฒญ๋…„ ์„ธ๋Œ€๊ฐ€ ํ˜„์‹ค์—์„œ ์‰ฝ๊ฒŒ ์ด๋ฃฐ ์ˆ˜ ์—†๋Š” ์ด์ƒ์ ์ธ ๋ชจ์Šต์„ ๊ทธ๋ ค๋ƒ„ <๋ฏธ์ƒ>, <๋ชฉ์š•์˜ ์‹ >, <๋ฌดํ•œ ๋™๋ ฅ>, <์ดํƒœ์› ํด๋ผ์“ฐ> ๋“ฑ ์ฃผ๋กœ ์ฒญ๋…„ ์ƒˆ๋Œ€๊ฐ€ ๋งˆ์ฃผํ•˜๋Š” ์ทจ์—…, ์‹ค์—…, ์‹ค์—ฐ, ๊ฑฐ์ฃผ, ์„ธ๋Œ€ ๊ฐˆ๋“ฑ ๋“ฑ์˜ ๋ฌธ์ œ๋ฅผ ์ค‘์ ์ ์œผ๋กœ ๋‹ค๋ฃธ ๊ธฐ์„ฑ์„ธ๋Œ€๊ฐ€ ๋ฐ”๋ผ๋Š” ์ฒญ๋…„ ์ฃผ๋กœ ๋“œ๋ผ๋งˆ๋กœ ํ‘œํ˜„ : ๋ฉœ๋กœ๋“œ๋ผ๋งˆ ํ”Œ๋กฏ + ์ฒญ๋…„๋“ค์˜ ์—ฐ์• ์™€ ๊ฒฐํ˜ผ 2000๋…„๋Œ€ ์ด์ „์—๋Š” ๋Œ€๋ถ€๋ถ„ ์‹ ๋ฐ๋ ๋ผ ํ”Œ๋กฏ์„ ํ™œ์šฉ, 2000๋…„๋Œ€ ์ดํ›„ ์ฒญ์ถ˜์˜ ์‹œ์„ ์œผ๋กœ ์ฒญ์ถ˜์˜ ํ˜„์‹ค์„ ๋‹คํˆฌ๊ณ ์ž ํ•จ <์ด๋ฒˆ ์ƒ์€ ์ฒ˜์Œ์ด๋ผ>, <์Œˆ, ๋งˆ์ด์›จ์ด>, <์†ก๊ณณ> ๋“ฑ ๋Œ€๋ถ€๋ถ„ ๊ธฐ์„ฑ์„ธ๋Œ€๊ฐ€ ๋ฐ”๋ผ๋Š” ํ–‰๋ณตํ•œ ์‚ถ์˜ ๋ฐฉ์‹์„ ๊ทธ๋Œ€๋กœ ๋‹ต์Šตํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ทธ๋ ค์ง ๋„ํ”ผ์ ์ธ ํŒํƒ€์ง€ ์ฃผ๋กœ ์˜ํ™”๋กœ ํ‘œํ˜„ : ๊ธฐ์กด ๊ฐ€์น˜๊ด€์— ์˜๋ฌธ์„ ๋˜์ง€๋ฉฐ ์‚ถ์˜ ๋‹ค์–‘์„ฑ์„ ๋ชจ์ƒ‰ํ•˜๊ณ  ํ˜„์‹œ๋Œ€์˜ ๊ณ ๋ฏผ ์ง€์ ์„ ์ œ์‹œํ•จ <๋ณ€์‚ฐ>, <๋ฆฌํ‹€ ํฌ๋ ˆ์ŠคํŠธ>, <์†Œ๊ณต๋…€>, <๋ฒ„๋‹> ๋“ฑ ๊ธฐ์„ฑ์„ธ๋Œ€์˜ ๊ธฐ์ค€์—์„œ ๋‚™์˜ค๋˜์—ˆ์ง€๋งŒ, ์ž์‹ ๋งŒ์˜ ํ–‰๋ณต์„ ๊ฟˆ๊พธ๋Š” ๋ชจ์Šต์œผ๋กœ ๊ทธ๋ ค์ง ๊ณต๊ฐ ์ธ์ง€์  ๊ณต๊ฐ : ์ƒ๋Œ€๋ฐฉ์˜ ์ž…์žฅ์— ์„œ๋ณด๋ฉฐ ์™œ ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•˜๊ณ  ๋А๋ผ๋Š” ์ง€ ์ดํ•ดํ•˜๋Š” ๋Šฅ๋ ฅ ์ •์„œ์  ๊ณต๊ฐ : ์ƒ๋Œ€๋ฐฉ์ด ๋А๋ผ๋Š” ๊ฐ์ •์„ ํ•จ๊ป˜ ๋А๋ผ๋Š” ๋Šฅ๋ ฅ ์†Œ์™ธ
new C++ ๊ฐœ๋… ์ •๋ฆฌ
๐ŸŒŠ C/CPP
๋ณธ ๋‚ด์šฉ์€ 2023 MISRA-CPP ๊ฐ€์ด๋“œ๋ผ์ธ์„ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๊ฐœ๋…์„ ์ •๋ฆฌํ•œ ๊ฒƒ์ด๋‹ค. ์ฐธ์กฐ(Reference)์™€ ํฌ์ธํ„ฐ(Pointer) ํฌ์ธํ„ฐ(Pointer) ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜ 1// ๋ณ€์ˆ˜ ์„ ์–ธ 2int a = 10; 3int* b = &a; // a์˜ ์ฃผ์†Œ๋ฅผ ์ €์žฅ 4 5// ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ 6void add(int* a, int* b) { 7 *a + *b; 8} 9 10add(&a, &b); ์ฐธ์กฐ(Reference) ๋ณ€์ˆ˜์— ๋ณ„์นญ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ ์ด๋ฆ„์œผ๋กœ ๋Œ€์ƒ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ์ œ์•ฝ์‚ฌํ•ญ ์ฐธ์กฐ๋Š” ์„ ์–ธ๊ณผ ๋™์‹œ์— ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•œ๋‹ค. ์ฐธ์กฐ๋Š” ํ•œ ๋ฒˆ ์ดˆ๊ธฐํ™”๋˜๋ฉด ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. ์ฐธ์กฐ๋Š” NULL๋กœ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์—†๋‹ค. 1// ๋ณ€์ˆ˜ ์„ ์–ธ 2int a = 10; 3int& b = a; // a์˜ ๋ณ„์นญ์„ b๋กœ ์ง€์ • 4 5// ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ 6void add(int& a, int& b) { 7 a + b; 8} 9add (a, b); ํ…œํ”Œ๋ฆฟ (Template) ํ…œํ”Œ๋ฆฟ์€ ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ, ํƒ€์ž…์„ ์ผ๋ฐ˜ํ™”ํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ• ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ 1template <typename T> 2T add(T a, T b) { 3 return a + b; 4} ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ 1template <typename T> 2class Point { 3public: 4 T x, y; 5 Point(T x, T y) : x(x), y(y) {} 6}; ํ…œํ”Œ๋ฆฟ ํŠน์ˆ˜ํ™” (Template Specialization) ํ…œํ”Œ๋ฆฟ์„ ํŠน์ • ํƒ€์ž…์— ๋Œ€ํ•ด ๊ตฌ์ฒดํ™”ํ•˜๋Š” ๊ฒƒ ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ ๋ช…์‹œ์  ํŠน์ˆ˜ํ™” 1template <typename T> 2T add(T a, T b) { 3 return a + b; 4} 5 6// int ํƒ€์ž…์— ๋Œ€ํ•œ ํŠน์ˆ˜ํ™” 7template <> 8int add(int a, int b) { 9 return a + b; 10} ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ ๋ถ€๋ถ„ ํŠน์ˆ˜ํ™” 1template <typename T> 2T add(T a, T b) { 3 return a + b; 4} 5 6// ํฌ์ธํ„ฐ ํƒ€์ž…์— ๋Œ€ํ•œ ๋ถ€๋ถ„ ํŠน์ˆ˜ํ™” 7template <typename T> 8T add(T* a, T* b) { 9 return *a + *b; 10} ์†์„ฑ (Attribute) ์ปดํŒŒ์ผํ• ๋•Œ ํŠน์ • ๋ฉ”์‹œ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํŠน์ • ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ [[noreturn]] (~c++11) ํ•จ์ˆ˜๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ํ˜ธ์ถœ์ž์—๊ฒŒ ์ œ์–ด๊ถŒ์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Œ์„ ๋‚˜ํƒ€๋ƒ„ [[noreturn]]์œผ๋กœ ์„ ์–ธ๋œ ํ•จ์ˆ˜๊ฐ€ ์ •์ƒ์ ์ธ ๋ฐ˜ํ™˜์„ ์‹œ๋„ํ•˜๋Š” ๊ฒฝ์šฐ undefined behavior ๋ฐœ์ƒ 1[[noreturn]] void error() { 2 throw "error"; 3} 4int32_t main() { 5 error(); 6 return 0; // dead code๋กœ ์ตœ์ ํ™”๋  ์ˆ˜ ์žˆ์Œ 7} [[maybe_unused]] (~C++17) ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ๋งค๊ฐœ๋ณ€์ˆ˜, ํƒ€์ž…์— ๋Œ€ํ•œ ๊ฒฝ๊ณ ๋ฅผ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฌด์‹œํ•˜๋„๋ก ๋ช…์‹œ 1[[maybe_unused]] int a = 10; [[nodiscard]] (~C++17) ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ๋ฌด์‹œํ•˜๋Š” ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒฝ๊ณ ํ•˜๋„๋ก ๋ช…์‹œ ๋ฐ˜๋Œ€๋กœ (void) ํ˜•ํƒœ๋กœ ์บ์ŠคํŒ…ํ•˜์—ฌ ๊ฒฝ๊ณ ๋ฅผ ์–ต์ œํ•  ์ˆ˜ ์žˆ์Œ 1[[nodiscard]] int add(int a, int b) { 2 return a + b; 3} [[fallthrough]] (~C++17) switch๋ฌธ์—์„œ case ๋ผ๋ฒจ์„ ์‚ฌ์šฉํ•  ๋•Œ, break๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๊ฒฝ๊ณ ๋ฅผ ์–ต์ œ 1switch (a) { 2 case 1: 3 std::cout << "1" << std::endl; 4 [[fallthrough]]; // ์˜๋„์ ์œผ๋กœ 2๋กœ ๋„˜์–ด๊ฐ„๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹œ 5 case 2: 6 std::cout << "2" << std::endl; 7 break; 8 default: 9 std::cout << "default" << std::endl; 10 break; 11} if constexpr (~C++17) compile time์— ์กฐ๊ฑด๋ฌธ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ ์กฐ๊ฑด์ด ๊ฑฐ์ง“์ธ ๊ฒฝ์šฐ ํ•ด๋‹น ๋ธ”๋ก์€ ์ปดํŒŒ์ผ๋˜์ง€ ์•Š์Œ ํ…œํ”Œ๋ฆฟ๊ณผ ๋น„์Šทํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ ํ…œํ”Œ๋ฆฟ์€ compile time์— ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜์ง€๋งŒ if constexpr๋Š” ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑ 1template <typename T> 2void print(T value) { 3 if constexpr (std::is_same_v<T, int>) { 4 std::cout << "int: " << value << std::endl; 5 } else if constexpr (std::is_same_v<T, double>) { 6 std::cout << "double: " << value << std::endl; 7 } else { 8 std::cout << "unknown type" << std::endl; 9 } 10} Lambda (~C++11) ์ต๋ช… ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๋Š” ํ‘œํ˜„์‹ ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ ์‚ฌ์šฉ 1auto add = [](int a, int b) { 2 return a + b; 3}; Transient/Non-transient lambda Transient lambda ์ฆ‰์‹œ ํ˜ธ์ถœ๋˜๊ณ  ์†Œ๋ฉธ๋˜๋Š” ๋žŒ๋‹ค ํ•จ์ˆ˜ 1 int x = 10; 2 auto result = [](int x) { 3 return x * 2; 4 }(); // ์ฆ‰์‹œ ํ˜ธ์ถœ Non-transient lambda ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜์–ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๋žŒ๋‹ค ํ•จ์ˆ˜ 1std::function<int32_t()> add = [](int a) { 2 return a + 10; 3}; 4 5int32_t result = add(10); Closure (~C++11) lambda expression์—์„œ ์™ธ๋ถ€ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์บก์ฒ˜ํ•˜๋Š” ๋ฐฉ์‹ 1int a = 10; 2auto add = [&a](int b) { 3 return a + b; 4}; Capture lamda ํ•จ์ˆ˜์—์„œ ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ํ•จ์ˆ˜ ๋‚ด๋ถ€๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ lambda ํ•จ์ˆ˜๊ฐ€ ์ •์˜๋œ ์‹œ์ ์˜ ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ parameter ๋ฐฉ์‹๊ณผ์˜ ๋น„๊ต 1// parameter ๋ฐฉ์‹ 2void addAndPrint(int a, int b) { 3 std::cout << a + b << std::endl; 4} 5 6int main() { 7 int x = 10; 8 int y = 20; 9 addAndPrint(x, y); // ๋งค๋ฒˆ ํ˜ธ์ถœํ•  ๋•Œ ๊ฐ’์„ ์ „๋‹ฌํ•ด์•ผ ํ•จ 10} 1// capture ๋ฐฉ์‹ 2int x = 10; 3int y = 20; 4 5auto addAndPrint = [&x, &y]() { // ์™ธ๋ถ€ ๋ณ€์ˆ˜ x์™€ y๋ฅผ ์ฐธ์กฐ๋กœ ์บก์ฒ˜ 6 std::cout << x + y << std::endl; 7}; 8 9addAndPrint(); // ๋งค๊ฐœ๋ณ€์ˆ˜ ์—†์ด๋„ ์™ธ๋ถ€ ๋ณ€์ˆ˜์— ์ ‘๊ทผ ๊ฐ€๋Šฅ Capture List [&] : ๋ชจ๋“  ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐ๋กœ ์บก์ฒ˜ [=] : ๋ชจ๋“  ์™ธ๋ถ€ ๋ณ€์ˆ˜๋ฅผ ๊ฐ’์œผ๋กœ ์บก์ฒ˜ [a] : ๋ณ€์ˆ˜ a๋ฅผ ๊ฐ’์œผ๋กœ ์บก์ฒ˜ [&a] : ๋ณ€์ˆ˜ a๋ฅผ ์ฐธ์กฐ๋กœ ์บก์ฒ˜ Escape Sequence ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์—์„œ ํŠน์ • ๋ฌธ์ž๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด Escape Sequence Description \' ์ž‘์€ ๋”ฐ์˜ดํ‘œ \" ํฐ ๋”ฐ์˜ดํ‘œ \? ๋ฌผ์Œํ‘œ \\ ์—ญ์Šฌ๋ž˜์‹œ \a ๋ฒจ ์†Œ๋ฆฌ \b ๋ฐฑ์ŠคํŽ˜์ด์Šค \f ํผ ํ”ผ๋“œ \n ๊ฐœํ–‰ \r ์บ๋ฆฌ์ง€ ๋ฆฌํ„ด \t ์ˆ˜ํ‰ ํƒญ \v ์ˆ˜์ง ํƒญ \0 ๋„ ๋ฌธ์ž \nnn 8์ง„์ˆ˜ \xnn 16์ง„์ˆ˜ Encoding C++์—์„œ๋Š” ๋ฌธ์ž ๋ฆฌํ„ฐ๋Ÿด์— ์ ‘๋‘์‚ฌ๋ฅผ ๋ถ™์—ฌ ์ธ์ฝ”๋”ฉ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ Encoding Prefix Example Literal Wide L L'A' Literal UTF-8 u8 u8'A' Literal UTF-16 u u'A' Literal UTF-32 U U'A' ASCII none '\x41' UTF-8 none '\xC3\xA9' Unicode (UTF-16) none '\u0041' Unicode (UTF-32) none '\U00000041' Cast Operator C++์—์„œ๋Š” ๋‹ค์–‘ํ•œ ํ˜•๋ณ€ํ™˜ ์—ฐ์‚ฐ์ž๋ฅผ ์ œ๊ณต static_cast ๋…ผ๋ฆฌ์ ์œผ๋กœ ํ˜•๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์— ์‚ฌ์šฉ ๊ธฐ๋ณธ ํƒ€์ž… ๊ฐ„์˜ ๋ณ€ํ™˜, ํฌ์ธํ„ฐ/์ฐธ์กฐ ๊ฐ„์˜ ๋ช…์‹œ์  ๋ณ€ํ™˜์— ์‚ฌ์šฉ ์ปดํŒŒ์ผ ์‹œ์ ์— ๊ฒ€์ฆ -> ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋งž์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋ฐœ์ƒ 1int a = 10; 2double b = static_cast<double>(a); dynamic_cast ์ƒ์† ๊ด€๊ณ„์—์„œ์˜ ํ˜•๋ณ€ํ™˜์„ ์œ„ํ•ด ์‚ฌ์šฉ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ์•ˆ์ „ํ•œ ํ˜•๋ณ€ํ™˜์„ ๋ณด์žฅ ๋ฐ˜๋“œ์‹œ ๊ฐ€์ƒ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ํด๋ž˜์Šค์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋‹ค์šด์บ์ŠคํŒ… ์‹œ, ํ˜•๋ณ€ํ™˜์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ nullptr์„ ๋ฐ˜ํ™˜ 1class Base { 2public: 3 virtual void print() {} 4}; 5class Derived : public Base { 6public: 7 void print() override {} 8}; 9 10Base* base = new Derived(); 11Derived* derived = dynamic_cast<Derived*>(base); // ์•ˆ์ „ํ•œ ๋‹ค์šด์บ์ŠคํŒ… const_cast ํฌ์ธํ„ฐ ๋˜๋Š” ์ฐธ์กฐํ˜•์˜ const ์†์„ฑ์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ ์ƒ์ˆ˜ํ˜• -> ๋น„์ƒ์ˆ˜ํ˜•์œผ๋กœ ๋ณ€ํ™˜ ๋ถˆ๋ณ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋ฉด undefined behavior ๋ฐœ์ƒ 1const int a = 10; 2int* b = const_cast<int*>(&a); reinterpret_cast ํฌ์ธํ„ฐ ํ˜•๋ณ€ํ™˜์ด๋‚˜ ๋น„๋…ผ๋ฆฌ์  ํ˜•๋ณ€ํ™˜์„ ์œ„ํ•ด ์‚ฌ์šฉ ๋ฉ”๋ชจ๋ฆฌ ๋ ˆ์ด์•„์›ƒ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํฌ์ธํ„ฐ๋ฅผ ๋ณ€ํ™˜ undefined behavior๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ ์™„์ „ํžˆ ๋‹ค๋ฅธ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Œ 1int a = 10; 2int* b = reinterpret_cast<int*>(&a); constexpr (~C++11) ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ํ‰๊ฐ€๋˜๋Š” ํ‘œํ˜„์‹์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ ๋ณ€์ˆ˜ compile time ์ƒ์ˆ˜์—๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ 1constexpr int num1 = 10; 2 3int a = 20; 4constexpr int num2 = a; // error: ๋ณ€์ˆ˜ a๋Š” runtime์— ๊ฒฐ์ •๋˜๋ฏ€๋กœ ์‚ฌ์šฉ ๋ถˆ๊ฐ€ ํ•จ์ˆ˜ ํ•จ์ˆ˜๊ฐ€ compile time์— ์‹คํ–‰๋˜๋„๋ก ๋ณด์žฅ ์ธ์ž ๊ฐ’์ด compile time ์ƒ์ˆ˜์ธ ๊ฒฝ์šฐ -> constexpr ํ•จ์ˆ˜๋กœ ๋™์ž‘ ์ธ์ž ๊ฐ’์ด compile time ์ƒ์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ -> constexpr ํ•จ์ˆ˜๋กœ ๋™์ž‘ body์—์„œ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ตฌ๋ฌธ goto try-catch ์ดˆ๊ธฐํ™” ์ˆ˜ํ–‰์ด ์—†๋Š” ๋ณ€์ˆ˜ ์„ ์–ธ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์ด ์•„๋‹Œ ๋ณ€์ˆ˜ ์„ ์–ธ static ๋ณ€์ˆ˜ ์„ ์–ธ tls(thread local storage) ๋ณ€์ˆ˜ ์„ ์–ธ ๋“ฑ… 1constexpr int fibonacci(const int n) { 2 if (n <= 1) return n; 3 return fibonacci(n - 1) + fibonacci(n - 2); 4} 5fibonacci(10); // compile time์— ๋‹ค ๊ณ„์‚ฐ๋˜์–ด์„œ 55๋กœ ๋Œ€์ฒด๋จ lvalue, rvalue ์ฐธ์กฐ lvalue ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฉ”๋ชจ๋ฆฌ ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํ‘œํ˜„์‹ lvalue ์ฐธ์กฐ 1int b = 10; 2int& a = b; // a๋Š” b์˜ ์ฐธ์กฐ์ž (lvalue ์ฐธ์กฐ) 3a = 20; ๋ฉค๋ฒ„ ํ•จ์ˆ˜์—์„œ์˜ ์‚ฌ์šฉ ์˜ˆ์‹œ 1class MyClass { 2public: 3 void show() & { 4 std::cout << "lvalue function called (object is lvalue)" << std::endl; 5 } 6}; 7 8MyClass obj; 9obj.show(); // lvalue ๊ฐ์ฒด์—์„œ ํ˜ธ์ถœ rvalue ๋ฉ”๋ชจ๋ฆฌ์— ์œ„์น˜์— ํ• ๋‹น๋œ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๋Š” ํ‘œํ˜„์‹ ์ฃผ์†Œ๊ฐ€ ์—†๊ฑฐ๋‚˜, ์ž„์‹œ๋กœ ํ• ๋‹น๋œ ๊ฐ’ ์ฃผ๋กœ ํ‘œํ˜„์‹์ด๋‚˜ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์ด๋‹ค. move semnatics๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์›์„ ํšจ์œจ์ ์œผ๋กœ ์ด๋™์‹œํ‚ค๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค. rvalue ์ฐธ์กฐ (~C++11) 1int&& a = 10; 2 3void show() && { 4 std::cout << "rvalue function called (object is rvalue)" << std::endl; 5} ๋ฉค๋ฒ„ ํ•จ์ˆ˜์—์„œ์˜ ์‚ฌ์šฉ ์˜ˆ์‹œ 1class MyClass { 2public: 3 void show() && { // rvalue์—์„œ๋งŒ ํ˜ธ์ถœ ๊ฐ€๋Šฅ 4 std::cout << "rvalue function called (object is rvalue)" << std::endl; 5 } 6}; 7 8MyClass().show(); // rvalue ๊ฐ์ฒด์—์„œ ํ˜ธ์ถœ ๊ฐ€์ƒํ•จ์ˆ˜ ์ƒ์† ๊ด€๊ณ„์—์„œ ๋™์  ๋ฐ”์ธ๋”ฉ์„ ์œ„ํ•ด ์‚ฌ์šฉ ๊ฐ€์ƒ ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง„ ํด๋ž˜์Šค๋ฅผ ๋‹คํ˜•์„ฑ ํด๋ž˜์Šค(polymorphic class)๋ผ๊ณ  ํ•จ ์ˆœ์ˆ˜ ๊ฐ€์ƒ ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง„ ํด๋ž˜์Šค๋ฅผ ์ถ”์ƒ ํด๋ž˜์Šค(abstract class)๋ผ๊ณ  ํ•จ virtual ์ง€์ •์ž ๊ฐ€์ƒ ํ•จ์ˆ˜ : ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ์„ ํƒ์ ์ž„ ์ˆœ์ˆ˜ ๊ฐ€์ƒ ํ•จ์ˆ˜ : ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ํ•„์ˆ˜์ž„ 1class Base { 2public: 3 // ๊ฐ€์ƒํ•จ์ˆ˜ 4 virtual void show() { 5 std::cout << "Base::show()" << std::endl; 6 } 7 8 // ์ˆœ์ˆ˜ ๊ฐ€์ƒํ•จ์ˆ˜ 9 virtual void print() = 0; 10}; override ์ง€์ •์ž ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ๋ช…์‹œ์ ์œผ๋กœ ํ‘œ์‹œ 1class Derived : public Base { 2public: 3 void show() override { 4 std::cout << "Derived::show()" << std::endl; 5 } 6}; final ์ง€์ •์ž ์ƒ์†์„ ๋ฐฉ์ง€ํ•˜๋Š” ํ‚ค์›Œ๋“œ ํด๋ž˜์Šค์— ์‚ฌ์šฉ : ์ƒ์†์„ ๋ฐฉ์ง€ ํ•จ์ˆ˜์— ์‚ฌ์šฉ : ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ๋ฐฉ์ง€ 1// ์ƒ์†์„ ๋ฐฉ์ง€ 2class Car final { ... }; 3 4// ์ƒ์†๊ณผ ๊ฐ™์ด ์“ฐ์ด๋Š” ๊ฒฝ์šฐ 5class Derived final : public Base { ... }; 6 7class Base { 8public: 9 // ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ๋ฐฉ์ง€ 10 void show() final { ... } 11}; enum vs enum class enum ๊ธฐ์กด์˜ C ์Šคํƒ€์ผ ์—ด๊ฑฐํ˜• ์ปดํŒŒ์ผ ์‹œ์ ์— ์ •์ˆ˜ํ˜• ์ƒ์ˆ˜๋กœ ๋ณ€ํ™˜ -> ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ์—†์Œ ๋‹ค๋ฅธ enum ์˜์—ญ์ด๋ผ๋„ ๋ณ€์ˆ˜๋ช…์ด ์ค‘๋ณต๋˜๋ฉด ์ถฉ๋Œ ๋ฐœ์ƒ 1enum Color { 2 RED, 3 GREEN, 4 BLUE 5}; 6Color color = RED; enum class (~C++11) enum์˜ ํ™•์žฅ๋œ ๋ฒ„์ „ ๋ฌต์‹œ์  ํ˜•๋ณ€ํ™˜์ด ๋ถˆ๊ฐ€๋Šฅ -> ๋ช…์‹œ์  ํ˜•๋ณ€ํ™˜ ํ•„์š” enum ์˜์—ญ์ด ๊ฒฉ๋ฆฌ๋˜์–ด ๋ณ€์ˆ˜๋ช…์ด ์ค‘๋ณต๋˜์–ด๋„ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ 1enum class Color { 2 RED, 3 GREEN, 4 BLUE 5}; 6Color color = Color::RED; explicit ์ง€์ •์ž ๋‹จ์ผ ์ธ์ž ์ƒ์„ฑ์ž์˜ ์•”์‹œ์  ํ˜•๋ณ€ํ™˜์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ ๋‹จ์ผ ์ธ์ž ์ƒ์„ฑ์ž ์•ž์— ์‚ฌ์šฉ 1class MyClass { 2public: 3 explicit MyClass(int a) : a(a) {} 4} 5 6MyClass obj = 10; // error: ์•”์‹œ์  ํ˜•๋ณ€ํ™˜ ๋ถˆ๊ฐ€ 7MyClass obj(10); // ok ์ˆจ๊ฒจ์ง„ friend ํ•จ์ˆ˜ ํด๋ž˜์Šค์˜ private ๋ฉค๋ฒ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํ•จ์ˆ˜ ๋ฉค๋ฒ„ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ํด๋ž˜์Šค์˜ private ๋ฉค๋ฒ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Œ ํด๋ž˜์Šค ๋‚ด๋ถ€์— ์ •์˜ํ•ด์•ผ ํ•จ ADL๋กœ๋งŒ ํ˜ธ์ถœ ๊ฐ€๋Šฅ 1namespace MyMath { 2 class Point { 3 int x, y; 4 5 Point(int x, int y) : x(x), y(y) {} 6 7 friend void operator+(Point& a, Point& b) { 8 a.x += b.x; 9 a.y += b.y; 10 } 11 }; 12} 13int32_t main() { 14 MyMath::Point a(10, 20); 15 MyMath::Point b(30, 40); 16 17 a + b; 18} ADL (Argument Dependent Lookup) ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ์ธ์ž์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ์ฐพ๋Š” ๊ฒƒ 1namespace MyMath { 2 struct Point { 3 int x, y; 4 Point(int x, int y) : x(x), y(y) {} 5 }; 6 7 void operator+(Point& a, Point& b) { 8 a.x += b.x; 9 a.y += b.y; 10 } 11} 12int32_t main() { 13 MyMath::Point a(10, 20); 14 MyMath::Point b(30, 40); 15 16 a + b; // ADL๋กœ ์ธํ•ด MyMath::operator+ ํ•จ์ˆ˜ ํ˜ธ์ถœ 17 MyMath::operator+(a, b); // ADL์ด ์—†์—ˆ๋‹ค๋ฉด ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœ 18} std::variant (~C++17) ์—ฌ๋Ÿฌ ํƒ€์ž… ์ค‘ ํ•˜๋‚˜๋ฅผ ์ €์žฅํ•˜๋Š” ํด๋ž˜์Šค union๊ณผ ๋˜‘๊ฐ™์ด ๋™์ž‘ํ•˜์ง€๋งŒ, type-safeํ•จ 1std::variant<int, double, std::string> value = 1; 2cout << std::get<int>(value) << endl; // 1 3 4value = 3.14; 5cout << std::get<double>(value) << endl; // 3.14 6 7value = "hello"; 8cout << std::get<std::string>(value) << endl; // hello ๋ฉค๋ฒ„, ๋น„๋ฉค๋ฒ„ ํ•จ์ˆ˜ index() : ํ˜„์žฌ ์ €์žฅ๋œ ํƒ€์ž…์˜ ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜ holds_alternative<T>() : ํŠน์ • ํƒ€์ž…์ด ์ €์žฅ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ get<T>() : ํŠน์ • ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ (ํƒ€์ž…์ด ๋งž์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ) get_if<T>() : ํŠน์ • ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ (ํƒ€์ž…์ด ๋งž์ง€ ์•Š์œผ๋ฉด nullptr ๋ฐ˜ํ™˜) visit() : ์ €์žฅ๋œ ํƒ€์ž…์„ ๋ชฐ๋ผ๋„ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ 1std::variant<int, double, std::string> value; 2 3value = "hello"; 4value.index(); // 2 (ํƒ€์ž… ์ˆœ์„œ๋Œ€๋กœ index ํ˜•์„ฑ) 5 6std::holds_alternative<double>(value); // true 7 8value = 1; 9std::get<int>(value); // 1 10std::get_if<int>(&value); // 1 11 12std::visit([](auto& arg) { 13 std::cout << arg << std::endl; 14}, value);
new ์ •๋ณด์ฒ˜๋ฆฌ๊ธฐ์‚ฌ ํ•„๊ธฐ ์ค€๋น„
๐ŸŽธ ๊ธฐํƒ€
1๊ณผ๋ชฉ : ์†Œํ”„ํŠธ์›จ์–ด ์„ค๊ณ„ ๊ฒฐํ•ฉ๋„ ์ž๋ฃŒ ๊ฒฐํ•ฉ๋„ : ๋ชจ๋“ˆ ๊ฐ„์˜ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ž๋ฃŒ ์š”์†Œ๋กœ๋งŒ ๊ตฌ์„ฑ๋  ๋•Œ์˜ ๊ฒฐํ•ฉ๋„ ์Šคํƒฌํ”„ ๊ฒฐํ•ฉ๋„ : ๋ชจ๋“ˆ ๊ฐ„์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋ฐฐ์—ด์ด๋‚˜ ๋ ˆ์ฝ”๋“œ ๋“ฑ์˜ ์ž๋ฃŒ ๊ตฌ์กฐ๊ฐ€ ์ „๋‹ฌ๋  ๋•Œ์˜ ๊ฒฐํ•ฉ๋„ ์ œ์–ด ๊ฒฐํ•ฉ๋„ : ํ•œ ๋ชจ๋“ˆ์ด ๋‹ค๋ฅธ ๋ชจ๋“ˆ๊ณผ ์ œ์–ด ์‹ ํ˜ธ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ†ต์‹ ํ•˜๊ณ , ๊ณต์œ ๋˜๋Š” ๊ณตํ†ต ๋ฐ์ดํ„ฐ ์˜์—ญ์„ ์‚ฌ์šฉํ•  ๋•Œ์˜ ๊ฒฐํ•ฉ๋„ ์™ธ๋ถ€ ๊ฒฐํ•ฉ๋„ : ์–ด๋–ค ๋ชจ๋“ˆ์—์„œ ์„ ์–ธํ•œ ๋ฐ์ดํ„ฐ(๋ณ€์ˆ˜)๋ฅผ ์™ธ๋ถ€์˜ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์ฐธ์กฐํ•  ๋•Œ์˜ ๊ฒฐํ•ฉ๋„ ๊ณต์œ  ๊ฒฐํ•ฉ๋„ : ๊ณต์œ ๋˜๋Š” ๊ณตํ†ต ๋ฐ์ดํ„ฐ ์˜์—ญ์„ ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์ด ์‚ฌ์šฉํ•  ๋•Œ์˜ ๊ฒฐํ•ฉ๋„ ๋‚ด์šฉ ๊ฒฐํ•ฉ๋„ : ํ•œ ๋ชจ๋“ˆ์ด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์˜ ๋‚ด๋ถ€ ๊ธฐ๋Šฅ ๋ฐ ๊ทธ ๋‚ด๋ถ€ ์ž๋ฃŒ๋ฅผ ์ง์ ‘ ์ฐธ์กฐํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ๋•Œ์˜ ๊ฒฐํ•ฉ๋„ ์‘์ง‘๋„ ์ˆœ์ฐจ์  ์‘์ง‘๋„ (Sequential Cohesion) ๊ตํ™˜์  ์‘์ง‘๋„ (Communicational Cohesion) ์ ˆ์ฐจ์  ์‘์ง‘๋„ (Procedural Cohesion) ์‹œ๊ฐ„์  ์‘์ง‘๋„ (Temporal Cohesion) ๋…ผ๋ฆฌ์  ์‘์ง‘๋„ (Logical Cohesion) ์šฐ์—ฐ์  ์‘์ง‘๋„ (Coincidental Cohesion) ์œ ์Šค์ผ€์ด์Šค(Use Case)์˜ ๊ตฌ์„ฑ ์š”์†Œ ๊ฐ„์˜ ๊ด€๊ณ„ ์—ฐ๊ด€ ๊ด€๊ณ„ ํฌํ•จ ๊ด€๊ณ„ ํ™•์žฅ ๊ด€๊ณ„ ์ผ๋ฐ˜ํ™” ๊ด€๊ณ„ ์ž๋ฃŒํ๋ฆ„๋„์˜ ๊ฐ ์š”์†Œ๋ณ„ ํ‘œ๊ธฐ ํ˜•ํƒœ Process : ์› Data Flow : ํ™”์‚ดํ‘œ Data Store : ํ‰ํ–‰์„  Terminator : ์‚ฌ๊ฐํ˜• ์ถ”์ƒํ™”์˜ ์ข…๋ฅ˜ ์ž๋ฃŒ ์ถ”์ƒํ™” ๊ณผ์ • ์ถ”์ƒํ™” ์ œ์–ด ์ถ”์ƒํ™” UML ๋ชจ๋ธ์—์„œ์˜ ๊ด€๊ณ„ Aggregation : ์ง‘ํ•ฉ ๊ด€๊ณ„ Generalization : ์ผ๋ฐ˜ํ™” ๊ด€๊ณ„ Composition : ํฌํ•จ ๊ด€๊ณ„ Dependency : ์˜์กด ๊ด€๊ณ„ Realization : ์‹ค์ฒดํ™” ๊ด€๊ณ„ 2๊ณผ๋ชฉ : ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ ๋ฒ•์น™ ํŒŒ๋ ˆํ†  ๋ฒ•์น™ : ์˜ค๋ฅ˜์˜ 80%๋Š” ์ „์ฒด ๋ชจ๋“ˆ์˜ 20% ๋‚ด์—์„œ ๋ฐœ๊ฒฌ๋œ๋‹ค๋Š” ๋ฒ•์น™ ํ•ด์‹ฑํ•จ์ˆ˜ ์ข…๋ฅ˜ ์ œ์‚ฐ๋ฒ•, ์ œ๊ณฑ๋ฒ•, ํด๋”ฉ๋ฒ•, ๊ธฐ์ˆ˜ ๋ณ€ํ™˜๋ฒ•, ๋Œ€์ˆ˜์  ์ฝ”๋”ฉ๋ฒ•, ๊ณ„์ˆ˜ ๋ถ„์„๋ฒ•(์ˆซ์ž ๋ถ„์„๋ฒ•), ๋ฌด์ž‘์œ„๋ฒ• ํ…Œ์ŠคํŠธ ์ข…๋ฅ˜ ์•ŒํŒŒ ํ…Œ์ŠคํŠธ : ๊ฐœ๋ฐœ์ž์— ์˜ํ•ด ์ˆ˜ํ–‰๋˜๋Š” ํ…Œ์ŠคํŠธ ๋ฒ ํƒ€ ํ…Œ์ŠคํŠธ : ์‚ฌ์šฉ์ž๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ํ…Œ์ŠคํŠธ 3๊ณผ๋ชฉ : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์ถ• ์Šคํ‚ค๋งˆ ์ข…๋ฅ˜ ๊ฐœ๋… ์Šคํ‚ค๋งˆ : ๊ฐœ์ฒด, ์†์„ฑ, ๊ด€๊ณ„๋ฅผ ์ •์˜ํ•˜๋Š” ์Šคํ‚ค๋งˆ ๋‚ด๋ถ€ ์Šคํ‚ค๋งˆ : ๋ฌผ๋ฆฌ์  ์ €์žฅ ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•˜๋Š” ์Šคํ‚ค๋งˆ ์™ธ๋ถ€ ์Šคํ‚ค๋งˆ : ์‚ฌ์šฉ์ž ๋ทฐ๋ฅผ ์ •์˜ํ•˜๋Š” ์Šคํ‚ค๋งˆ ์ด์ƒํ˜„์ƒ ์‚ฝ์ž… ์ด์ƒ, ์‚ญ์ œ ์ด์ƒ, ๊ฐฑ์‹  ์ด์ƒ ๋กœํ‚น ๋กœํ‚น ๋‹จ์œ„ โฌ‡๏ธ -> ๋ณ‘ํ–‰์„ฑ ์ˆ˜์ค€ โฌ†๏ธ 4๊ณผ๋ชฉ : ํ”„๋กœ๊ทธ๋ž˜๋ฐ์–ธ์–ดํ™œ์šฉ ๊ต์ฐฉ ์ƒํƒœ์˜ ์กฐ๊ฑด Mutual Exclusion Hold and Wait No Preemption Circular Wait 5๊ณผ๋ชฉ : ์ •๋ณด์‹œ์Šคํ…œ๊ตฌ์ถ• ๊ด€๋ฆฌ ๋ธŒ๋ผ์šฐํ„ฐ : ๋ธŒ๋ฆฌ์ง€์™€ ๋ผ์šฐํ„ฐ์˜ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ๊ฐ–์ถ”๊ณ  ์žˆ๋Š” ๋„คํŠธ์›Œํฌ ์žฅ๋น„ Cocomo ๋ชจํ˜• ์กฐ์งํ˜• (Organic Mode) : 5๋งŒ ๋ผ์ธ ์ดํ•˜์˜ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ์œ ํ˜• ๋ฐ˜๋ถ„๋ฆฌํ˜• (Semi-detached Mode) : 30๋งŒ ๋ผ์ธ ์ดํ•˜์˜ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ์œ ํ˜• ๋‚ด์žฅํ˜• (Embedded Mode) : ์ดˆ๋Œ€ํ˜• ๊ทœ๋ชจ์˜ ์†Œํ”„ํŠธ์›จ์–ด, 30๋งŒ๋ผ์ธ ์ด์ƒ
new ์ตœ์‹ ์ปดํ“จํ„ฐํŠน๊ฐ•
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
1์ฃผ์ฐจ - ์›์œ ์žฌ ๊ต์ˆ˜๋‹˜ - ์ฒจ๋‹จ๋ถ„์•ผ ํ˜์‹ ์œตํ•ฉ๋Œ€ํ•™์‚ฌ์—… (COSS: Convergence and Open Sharing System) ์ถ”์ง„๋ฐฐ๊ฒฝ : ๋””์ง€ํ„ธ ์ „ํ™˜, ๊ธ€๋กœ๋ฒŒ ๊ฒฝ์Ÿ ์‹ฌํ™”์— ๋”ฐ๋ผ ์‹ ๊ธฐ์ˆ  ์ดˆ๊ฒฉ์ฐจ ํ™•๋ณด ๋ฐ ๊ธ‰์ฆํ•˜๋Š” ์‹ ์‚ฐ์—… ์ธ๋ ฅ ์ˆ˜์š”์— ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋Š” ์ธ์žฌ ์–‘์„ฑ ์ถฉ๋‚จ๋Œ€ํ•™๊ต : ๋ธ”๋ก์ฒด์ธ ๋ถ„์•ผ ํŠนํ™”, ์—ฐ๊ตฌํ˜‘๋ ฅ(์—ฐ๊ตฌ๋‹จ์ง€) ์ค‘์‹ฌ ํŠนํ™” 5๊ฐœ ์œต๋ณตํ•ฉ์ฐฝ์˜์ „๊ณต ๋ธ”๋ก์ฒด์ธ์œตํ•ฉ์ „๊ณต ์‚ฌ์ด๋ฒ„๋ณด์•ˆ์œตํ•ฉ์ „๊ณต ํด๋ผ์šฐ๋“œ์œตํ•ฉ์ „๊ณต ๋ฐ์ดํ„ฐ๋ณด์•ˆํ™œ์šฉ์œตํ•ฉ์ „๊ณต : ์ปดํ“จํ„ฐ ๋น„์ „๊ณต์ž ๋Œ€์ƒ ๊ฐœ์ธ์ •๋ณด๋ณดํ˜ธ์œตํ•ฉ์ „๊ณต 25-1ํ•™๊ธฐ ์ถฉ๋‚จ๋Œ€ํ•™๊ต ๊ฐœ์„ค ๊ณผ๋ชฉ ๋ธ”๋ก์ฒด์ธ ๊ฐœ๋ก  ๋ธ”๋ก์ฒด์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋””์ง€ํ„ธ ์ž์‚ฐ๊ณผ ๋ธ”๋ก์ฒด์ธ ํ•™์ƒ์ง€์› ํ˜์‹ ์œตํ•ฉ๋Œ€ํ•™ ํ•™์œ„ ์ทจ๋“ ์žฅํ•™๊ธˆ ์ง€์› ์ „๋ฌธ๊ฐ€์™€ ๊ต๋ฅ˜ ๊ธฐํšŒ ํ•™์Šต๊ธฐ๊ธฐ ์ง€์› ํ˜„์žฅ์‹ค์Šต ๊ธฐํšŒ 3์ฃผ์ฐจ - ๊น€ํ˜•์‹  ๊ต์ˆ˜๋‹˜ AI๊ธฐ์ˆ ์˜ ์ž„๋ฒ ๋””๋“œ ์‹œ์Šคํ…œํ™” ์ด์œ  Privacy (๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ) Latency (์ง€์—ฐ์‹œ๊ฐ„) Cost (๋น„์šฉ) Embedding Resnet Resnet์„ ์ž„๋ฒ ๋””๋“œ ์‹œ์Šคํ…œ์— ์ ์šฉํ•จ Resnet : ํ•ฉ์„ฑ๊ณฑ ์‹ ๊ฒฝ๋ง ๋ชจ๋ธ ์ž์œจ์ฃผํ–‰ ์ž๋™์ฐจ์—์„œ์˜ ๋”ฅ๋Ÿฌ๋‹ ๊ตฌํ˜„ Image Classification DNN and MAC operation DNN : Deep Neural Network MAC : Multiply and Accumulate ์ž„๋ฒ ๋””๋“œ AI ํ•˜๋“œ์›จ์–ด Qualcomm Hexagon DSP Performance with low power ๊ณ ์† MAC ๊ธฐ๋ฐ˜ ํ”„๋กœ์„ธ์„œ Apple Neural Engine ๋‰ด๋Ÿด๋„ท ๊ฐ€์†๊ธฐ์™€ MMA ๊ธฐ๋ฐ˜ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌํ˜• GPU ํฌํ•จ Nvidia Jetson ๋‹ค์ˆ˜์˜ PE ๊ธฐ๋ฐ˜ MMA ๊ฐ€์†ํ˜• ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ GPU ์–‘์žํ™”, ํ”„๋ฃจ๋‹ ํ•˜๋“œ์›จ์–ด ์ง€์› ์ตœ์ ํ™” SW ์Šคํƒ ์ง€์› Nvidia Xavier NX ์ปดํ“จํ„ฐ Nvidia Jetson ์‹œ๋ฆฌ์ฆˆ ์ค‘ ํ•˜๋‚˜ Tensor Processing Unit (TPU) Google ์‚ฌ์—์„œ ๊ฐœ๋ฐœํ•œ ๋‰ด๋Ÿดํ”„๋กœ์„ธ์„œ ๊ฒ€์ƒ‰์—”์ง„, ์•ŒํŒŒ๊ณ ์— ์‚ฌ์šฉ Google TPU : High-level Architecture FPGA๊ธฐ๋ฐ˜ ๊ฐ€์†๊ธฐ (Accelerator) ๋„๋ฉ”์ธ๊ณผ ์‘์šฉ์— ํŠนํ™”๋œ ๊ฐ€์†ํšŒ๋กœ๋ฅผ FPGA๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์†Œํ”„ํŠธ์›จ์–ด ์Šคํƒ์„ ์ œ๊ณต Microcontrollers(MCU) ์ œ์–ด์šฉ ์ž„๋ฒ ๋””๋“œ ํ”„๋กœ์„ธ์„œ๋กœ ์—ฐ์‚ฐ ์„ฑ๋Šฅ์ด ๋งค์šฐ ๋‚ฎ์œผ๋ฉฐ, AI๋ฅผ ์œ„ํ•œ ๊ฐ€์†๊ธฐ๋Šฅ์€ ์—†์ง€๋งŒ, ๋ชจ๋ธ ๊ฒฝ๋Ÿ‰ํ™”, ์••์ถ•์„ ํ†ตํ•ด ์ตœ์ ํ™”๋ฅผ ์ ์šฉ ์‹ค์‹œ๊ฐ„ ์˜จ๋ณด๋“œ AI ์ปดํ“จํŒ… CESL์˜ ์—ฐ๊ตฌ ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด DNN ์ถ”๋ก  ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ธฐ PyTorch, Tensorflow ์—†์ด ๋ชจ๋“  ์ถ”๋ก  ๋ฃจํ‹ด์„ C๋กœ ๊ตฌํ˜„ ์‹ค์‹œ๊ฐ„ ์ถ”๋ก  ๋ฉ”๋ชจ๋ฆฌ ๊ณ„์ธต์„ ํ™œ์šฉํ•˜๋Š” ์ˆ˜ํ•™ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ตœ์ ํ™” CPU, GPU, DSP, NPU ์ตœ์  ์›Œํฌ๋กœ๋“œ ํ• ๋‹น์„ ํ†ตํ•œ ๊ณ„์‚ฐ ๊ฐ€์† NN/LLM ์••์ถ• ์†๋„ ํ–ฅ์ƒ ์ •ํ™•๋„ ์†์‹ค ์—†์Œ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ TensorRT, ONNX RT Triton, GEMM, llama.cpp Darknet, OpenCL 4์ฃผ์ฐจ - ์กฐ์Šน๋ฒ” ๊ต์ˆ˜๋‹˜ ์ด๋ก  ์ „์‚ฐํ•™ ์ˆ˜ํ•™์„ ์ด์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์ „์‚ฐํ•™ ๊ด€๋ จ ๋ฌธ์ œ๋“ค์„ ์ •์˜ํ•˜๊ณ  ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ํ•™๋ฌธ 1. Integer Sequence Representation ์•ŒํŒŒ๋ฒณ size๊ฐ€ |A|์ด๊ณ  ๊ธธ์ด๊ฐ€ n์ธ integer sequence๋ฅผ ๊ฐ€๋Šฅํ•œ ์ž‘์€ ๊ณต๊ฐ„์— ์ €์žฅํ•˜๊ธฐ, ๋‹จ, ์ผ๋ฐ˜์ ์ธ array ์ฒ˜๋Ÿผ random acess๊ฐ€ ๊ฐ€๋Šฅํ•ด์•ผ ํ•จ ๋ฐฉ๋ฒ• 1: ๊ฐ alphabet ๋งˆ๋‹ค 4๋น„ํŠธ์”ฉ ํ• ๋‹นํ•จ -> 4n bits, O(1) access time ๋ฐฉ๋ฒ• 2: ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  10^n๊ฐœ์˜ sequence์— ๋Œ€ํ•ด ์ˆœ์„œ๋Œ€๋กœ ์ˆซ์ž๋ฅผ ๋ถ€์—ฌํ•จ $$ \left\lceil \log_2(10^n) \right\rceil = \left\lceil n \cdot \log_2 10 \right\rceil \approx \left\lceil 3.32n \right\rceil \text{ bits} $$ O(n) access time 2. Edit Distance edit distance : ๋‘ ๋ฌธ์ž์—ด์„ ๊ฐ™๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ์—ฐ์‚ฐ ํšŸ์ˆ˜ ์—ฐ์‚ฐ ์ข…๋ฅ˜ ์‚ฝ์ž… (Insert) ์‚ญ์ œ (Delete) ๋Œ€์ฒด (Replace) SETH๊ฐ€ ๊ฑฐ์ง“์ด ์•„๋‹ˆ๋ฉด $O(n^2)$ ๋ณด๋‹ค ๋นจ๋ฆฌ ๊ณ„์‚ฐํ•  ์ˆ˜ ์—†์Œ SETH(Strong Exponential Time Hypothesis) : ๊ฐ•ํ•œ ์ง€์ˆ˜ ์‹œ๊ฐ„ ๊ฐ€์„ค 3. Optimal online binary search tree ๋ชฐ๋ฃจ 4์ฃผ์ฐจ - ๊ถŒ์ง„๊ทผ ๊ต์ˆ˜๋‹˜ - RNN/LSTM RNN (Recurrent Neural Network) $$ h_t = f(Vx_{t} + Ah_{t-1}) $$ f: tanh $x_t$: ํ˜„์žฌ ์ž…๋ ฅ $h_{t-1}$: ๊ณผ๊ฑฐ์ •๋ณด LSTM (Long Short Term Memory) ์ด์ „์˜ ์ž…๋ ฅ ์ •๋ณด๊ฐ€ ์˜ค๋ž˜ ๊ธฐ์–ต๋˜๋„๋ก ๊ตฌ์กฐ ๊ฐœ์„  Attention Network ๋””์ฝ”๋”์—์„œ ์ถœ๋ ฅ ๋‹จ์–ด๋ฅผ ์˜ˆ์ƒํ•˜๋Š” ๋งค time step๋งˆ๋‹ค, ์ธ์ฝ”๋”์—์„œ์˜ ์ „์ฒด ์ธํ’‹์„ ํ•œ ๋ฒˆ ๋” ์ฐธ๊ณ  Transformer RNN์—†์ด Attention๋งŒ์œผ๋กœ Encoder์™€ Decoder๋ฅผ ์„ค๊ณ„ ๊ธฐ๋ณธ ๊ตฌ์กฐ : ๋‹ค์ธต ๊ตฌ์กฐ์ธ N๊ฐœ์˜ encoder layer์™€ N๊ฐœ์˜ decoder layer๋กœ ๊ตฌ์„ฑ ํฌ์ง€์…”๋„ ์ธ์ฝ”๋”ฉ (Positional Encoding) RNN์€ ๋‹จ์–ด์˜ ์œ„์น˜์— ๋”ฐ๋ผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ž…๋ ฅ์„ ๋ฐ›์•„ ๊ฐ ๋‹จ์–ด์˜ ์œ„์น˜ ์ •๋ณด๋ฅผ ๊ฐ€์ง ํŠธ๋žœ์Šคํฌ๋จธ๋Š” ๋‹จ์–ด ์ž…๋ ฅ์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐ›๋Š” ๋ฐฉ์‹์ด ์•„๋‹ˆ๊ธฐ์— ๋‹จ์–ด์˜ ์œ„์น˜ ์ •๋ณด๊ฐ€ ํ•„์š” ์ˆœํ™˜์„ ๋ชจ๋‘ ์—†์• ๊ณ  self-attention์ด๋ผ๋Š” ํŠน๋ณ„ํ•œ ํ˜•ํƒœ์˜ attention์— ์˜์ง€ self-attention Attention์„ ์ž๊ธฐ์ž์‹ ์—๊ฒŒ ์ˆ˜ํ–‰ input data ์•ˆ์— ์žˆ๋Š” ๋ฒกํ„ฐ๋“ค ๊ฐ„์˜ similarities๋ฅผ ๊ณ„์‚ฐ BERT (Bidirectional Encoder Representations from Transformers) Encoder๋งŒ ์‚ฌ์šฉ BART (Bidirectional and Auto-Regressive Transformers) Encoder์™€ Decoder ๋ชจ๋‘ ์‚ฌ์šฉ GPT (Generative pre-trained transformer) Decoder๋งŒ ์‚ฌ์šฉ ICL (In-context Learning) ๋ชจ๋ธ์ด ์ฃผ์–ด์ง„ ์˜ˆ์‹œ๋ฅผ ๋ณด๊ณ  ํ•™์Šตํ•˜๋Š” ๊ฒƒ ICL์€ LM์ด ํŒจํ„ด์˜ ์ถ”์ƒํ™” ๋Šฅ๋ ฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์คŒ ์ข…๋ฅ˜ Zero-shot : ์˜ˆ์‹œ ์—†์Œ One-shot : ์˜ˆ์‹œ ํ•˜๋‚˜ Few-shot : ์˜ˆ์‹œ ์—ฌ๋Ÿฌ ๊ฐœ Zero-shot chain-of-thought (์ƒ๊ฐ์˜ ์‚ฌ์Šฌ) “Let’s think step by step"์„ prompt์— ์‚ฝ์ž… -> GPT์˜ ์ถ”๋ก ์„ ์œ ๋„ RAG (Retrieval-Augmented Generation) ๊ฒ€์ƒ‰ ์ฆ๊ฐ• ์ƒ์„ฑ Open Model vs Closed Model Open Model : Llama Closed Model : ChatGPT 5์ฃผ์ฐจ - ๊น€ํ˜•๊ธฐ ๊ต์ˆ˜๋‹˜ - ์ปดํ“จํ„ฐ ๊ทธ๋ž˜ํ”ฝ์Šค ๋ฐ ํ˜ผํ•ฉํ˜„์‹ค ๊ธฐ์ˆ  ์†Œ๊ฐœ ๋ฐ ํ˜„ํ™ฉ ์ปดํ“จํ„ฐ ๊ทธ๋ž˜ํ”ฝ์Šค ๋ Œ๋”๋ง ๋ฐ์ดํ„ฐ๋กœ๋ถ€ํ„ฐ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ธฐ์ˆ  On-line Rendering : ์‹ค์‹œ๊ฐ„(>30fps)์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ธฐ์ˆ  Off-line Rendering : ๋น„์‹ค์‹œ๊ฐ„์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ธฐ์ˆ  On-line Rendering: Rasterization ์ปดํ“จํ„ฐ ๊ทธ๋ž˜ํ”ฝ์—์„œ, ๋ชจ๋“  ๋ฌผ์ฒด๋Š” ์‚ผ๊ฐํ˜•์˜ ์ง‘ํ•ฉ์œผ๋กœ ํ‘œํ˜„๋จ ์ด๋Ÿฌํ•œ ์‚ผ๊ฐํ˜•๋“ค์„ ์ผ๋ จ์˜ ๊ณผ์ •์„ ๊ฑฐ์ณ ํ™”๋ฉด์ƒ ํ”ฝ์…€๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ์‹ Vertex Shader : ์–ด๋””์— ์‚ผ๊ฐํ˜•์ด ์žˆ์„ ๊ฒƒ์ธ๊ฐ€? Fragment Shader : ์‚ผ๊ฐํ˜• ์•ˆ์˜ ํ”ฝ์…€์„ ์–ด๋–ค ์ƒ‰์œผ๋กœ ์น ํ•  ๊ฒƒ์ธ๊ฐ€? ์ˆœ์„œ : vertex shader -> rasterization -> fragment shader -> output merger GPU(Graphics Processing Unit) ๊ฐ„๋‹จํ•œ ๊ณ„์‚ฐ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์ฒ˜๋ฆฌ ์žฅ์น˜ ์ˆ˜์ฒœ-์ˆ˜๋งŒ๊ฐœ๊ฐ€ ๋™์‹œ์— ๋™์‹œ์— ์…ฐ์ด๋”๋ฅผ ์‹คํ–‰ Off-line Rendering: Ray/Path Tracing Ray/Path Tracing ๋น›๊ณผ ๋ฌผ์ฒด์˜ ์ƒํ˜ธ์ž‘์šฉ์„ Rasterization ์ƒ์„ธํžˆ ๊ณ„์‚ฐ ๋ˆˆ์œผ๋กœ ๋“ค์–ด์˜ฌ ๊ด‘์„ ์„ ์—ญ์œผ๋กœ ์ถ”์ ํ•˜์—ฌ ์ƒ‰์ƒ์„ ๊ณ„์‚ฐ RTX Hybrid Rendering Rasterization + Ray Tracing, ๋ณ„๋„์˜ ์ฝ”์–ด ์‚ฌ์šฉ, ๋”ฅ๋Ÿฌ๋‹ ๊ธฐ๋ฐ˜ ๊ธฐ์ˆ  ์ ์šฉ Mixed Reality (ํ˜ผํ•ฉํ˜„์‹ค) ์šฉ์–ด ํ˜„์‹ค(Real Environment) : ์šฐ๋ฆฌ๊ฐ€ ์‚ด๊ณ ์žˆ๋Š”, ๋ฌผ๋ฆฌ์  ์‹ค์ฒด๊ฐ€ ์žˆ๋Š” ํ™˜๊ฒฝ ๊ฐ€์ƒ ํ˜„์‹ค (Virtual Reality) : ๋ฌผ๋ฆฌ์ ์œผ๋กœ ์กด์žฌํ•˜์ง€ ์•Š๋Š”, ๊ฐ€์ƒ์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ํ™˜๊ฒฝ ์ฆ๊ฐ• ํ˜„์‹ค (Augmented Reality) : ๋ฌผ๋ฆฌ์  ํ˜„์‹ค์„ ๋ฐฐ๊ฒฝ์œผ๋กœ ๊ฐ€์ƒ์˜ ๊ฐ์ฒด๋ฅผ ์ฆ๊ฐ•์‹œํ‚จ ํ™˜๊ฒฝ ํ˜ผํ•ฉ ํ˜„์‹ค (Mixed Reality) : ๋ฌผ๋ฆฌ์  ํ˜„์‹ค๊ณผ ๊ฐ€์ƒ์˜ ๊ฐ์ฒด๊ฐ€ ํ˜ผ์žฌ๋˜์–ด ์žˆ๋Š” ํ™˜๊ฒฝ (AR์˜ ํ™•์žฅ ํ˜•ํƒœ) Buzzword ํ™•์žฅ ํ˜„์‹ค(eXtended Reality) : MR์„ VR๊นŒ์ง€ ํ™•์žฅํ•œ ๊ฐœ๋… ๊ณต๊ฐ„ ์ปดํ“จํŒ… (Spatial Computing) : Apple์—์„œ ์ œ์•ˆํ•œ, ๋ฉ”ํƒ€๋ฒ„์Šค์™€ ๋””์ง€ํ„ธ ํŠธ์œˆ๊นŒ์ง€ ํฌํ•จํ•˜๋Š” ๊ฐœ๋… ๊ถ๊ทน์ ์ธ ๋ชฉํ‘œ ์ธ๊ฐ„์˜ ์ฃผ์š” ๊ฐ๊ฐ๋“ค์„ ํ†ตํ•ด ์ง„์งœ์ฒ˜๋Ÿผ ๋А๋ผ๊ฒŒ ํ•˜๋Š” ๊ฒƒ HMD (Head Mounted Display) ์ƒ์—…์ ์œผ๋กœ ๊ฐ€์žฅ ์„ฑ๊ณตํ•œ VR ์žฅ์น˜์˜ ํ˜•ํƒœ XR๋กœ์˜ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์ „๋ฉด๋ถ€์˜ ์นด๋ฉ”๋ผ๋กœ ์ดฌ์˜๋œ ์˜์ƒ์„ ๋‹ค์‹œ ๋””์Šคํ”Œ๋ ˆ์ด์— ํˆฌ์‚ฌ HMD์˜ ์›๋ฆฌ ์ž‘์€ ๊ณ ํ•ด์ƒ๋„ ๋””์Šคํ”Œ๋ ˆ์ด๊ฐ€ ๋ˆˆ ์•ž์— ์žˆ์Œ -> ์ดˆ์ ์„ ๋งž์ถœ ์ˆ˜ ์—†์Œ ๋ Œ์ฆˆ(๋‹๋ณด๊ธฐ)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ ๋ฉ€๋ฆฌ ๋‘๋ฉฐ, ๋†’์€ ์‹œ์•ผ๊ฐ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ ์–‘์•ˆ ์‹œ์ฐจ๋ฅผ ์‚ฌ์šฉํ•ด ๊ฑฐ๋ฆฌ๋ฅผ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋‹น ์žฅ์น˜๋ฅผ ์ œ๊ณต HMD์˜ Tracking Outside-in Tracking : ์™ธ๋ถ€ ์„ผ์„œ๊ฐ€ HMD ์žฅ์น˜๋ฅผ ๊ด€์ฐฐํ•˜์—ฌ ํŠธ๋ž˜ํ‚น Inside-out Tracking : HMD์— ์„ค์น˜๋œ ์„ผ์„œ๋“ค๋กœ ์™ธ๋ถ€๋ฅผ ๊ด€์ฐฐํ•˜์—ฌ ํŠธ๋ž˜ํ‚น XR HMD Optical see-through : ๋ฐ˜ํˆฌ๋ช…ํ•œ ๋””์Šคํ”Œ๋ ˆ์ด ๋‚ด๋ถ€์—์„œ ๋น›์„ ๋ฐ˜์‚ฌํ•˜์—ฌ ์ „๋‹ฌ Video see-through : ์ „๋ฉด๋ถ€์˜ ์นด๋ฉ”๋ผ๋กœ ์ฐ์€ ์ด๋ฏธ์ง€์— ๊ฐ€์ƒ์˜ ๋ฌผ์ฒด๋ฅผ ๋”ํ•ด ๋ Œ๋”๋ง 5์ฃผ์ฐจ - ์–‘ํฌ์ฒ  ๊ต์ˆ˜๋‹˜ - AI/ML ์‹œ์Šคํ…œ ์—ฐ๊ตฌ ๋™ํ–ฅ AI/ML ์‹œ์Šคํ…œ์˜ ํšจ์œจ์„ฑ Distributed Training ํ˜„์‹ค์—์„œ๋Š” hybrid parallelism์„ ์‚ฌ์šฉ Data Parallelism : ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜๋ˆ„์–ด ๊ฐ ๋…ธ๋“œ์—์„œ ํ•™์Šต Model/Pipeline Parallelism : ๋ชจ๋ธ์„ ๋‚˜๋ˆ„์–ด ๊ฐ ๋…ธ๋“œ์—์„œ ํ•™์Šต Tensor parallelism : ํ…์„œ๋ฅผ ๋‚˜๋ˆ„์–ด ๊ฐ ๋…ธ๋“œ์—์„œ ํ•™์Šต Sequence parallelism : ํ† ํฐ์„ ๋‚˜๋ˆ„์–ด ๊ฐ ๋…ธ๋“œ์—์„œ ํ•™์Šต AI/ML ์‹œ์Šคํ…œ์˜ ์‹ ๋ขฐ์„ฑ Data Privacy ํด๋ผ์šฐ๋“œ๋‚˜ ์—ฃ์ง€์—์„œ ํ•™์Šต์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์ถœ๋  ์ˆ˜ ์žˆ์Œ Distributed Learning Federated Learning : ๋ฐ์ดํ„ฐ๋Š” ํด๋ผ์šฐ๋“œ์— ๋‘๊ณ , ๋ชจ๋ธ๋งŒ ์—ฃ์ง€์—์„œ ํ•™์Šต ์„œ๋ฒ„๊ฐ€ ์žฅ์น˜์— ๋ชจ๋ธ์„ ์ „์†ก ์‚ฌ์šฉ์ž์˜ ๋ฐ์ดํ„ฐ๋กœ ์žฅ์น˜์—์„œ ๋ชจ๋ธ์ด ํ•™์Šต ๊ฐ ์žฅ์น˜๊ฐ€ ๋ชจ๋ธ์„ N๋ฒˆ ์—…๋ฐ์ดํŠธ ์—…๋ฐ์ดํŠธ ๋œ ๋ชจ๋ธ์ด ์„œ๋ฒ„์— ์ „์†ก ๋ชจ๋ธ์ด ์„œ๋ฒ„์—์„œ ํ•ฉ์ณ์กŒ๋‹ค๊ฐ€, ๋‹ค์‹œ ์žฅ์น˜์— ์ „์†ก Split Learning Centralized and distributed neural network training Peer-to-peer training for distributed learning Decentralized Learning Swarm learning Gossip Learning Model Fairness ๋ชจ๋ธ์ด ํŠน์ • ์ง‘๋‹จ์— ๋Œ€ํ•ด ํŽธํ–ฅ๋˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฒƒ Reliability Machine Unlearning ๋ชจ๋ธ์ด ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ์žŠ๋„๋ก ํ•˜๋Š” ๊ฒƒ Robustness Model Poisoning์— ๋Œ€ํ•œ ๋ฐฉ์–ด 6์ฃผ์ฐจ - ๋ฐ•์ง€ํ›ˆ ๊ต์ˆ˜๋‹˜ - Edge ์ปดํ“จํŒ… ํ™˜๊ฒฝ ์ธ๊ณต์ง€๋Šฅ ์‘์šฉ ์—ฐ๊ตฌ Edge Computing ์ค‘์•™ ์„œ๋ฒ„ ๋Œ€์‹  Edge ์ปดํ“จํ„ฐ๊ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ณณ ํ˜น์€ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ณณ ๊ทผ์ฒ˜์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐœ๋… Edge Computing์˜ ์žฅ์  ์ง€์—ฐ์‹œ๊ฐ„ ์ ์Œ -> ๋ฐ์ดํ„ฐ๋ฅผ ์ค‘์•™ ์„œ๋ฒ„์— ๋ณด๋‚ผ ํ•„์š” ์—†์Œ, ์ฒ˜๋ฆฌ๋œ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆด ํ•„์š” ์—†์Œ ํ†ต์‹  ์—ฐ๊ฒฐ ๋ถˆํ•„์š” ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ ๊ฐ์†Œ ๋†’์€ ํ™•์žฅ์„ฑ -> ์„ผ์„œ/ํ”Œ๋žซํผ ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๋Š” ๋ถ€๋‹ด์ด ์ ์Œ ๊ฐœ์ธ์ •๋ณด ๋ฐ ๋ณด์•ˆ ๊ฐ•ํ™” -> ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ํ•„์š” ์—†์Œ ์ง€ํ–ฅํ•˜๋Š” ๊ฒƒ ๋ฐ์ดํ„ฐ๋ฅผ ๋” ์ˆ˜์ง‘ํ•˜์ง€ ์•Š๊ณ  ๋™์ผํ•œ ๋ชจ๋ธ์—์„œ ์ •ํ™•๋„๋ฅผ ๋†’์ด๊ณ  ์‹ถ๋‹ค -> ๋ฐ์ดํ„ฐ ์ฆ๊ฐ•/์ƒ์„ฑ ๋™์ผํ•œ ์†๋„, ์„ฑ๋Šฅ์— ๋” ๋†’์€ ์ •ํ™•๋„๋ฅผ ์–ป๊ณ  ์‹ถ๋‹ค -> ๋ชจ๋ธ ๊ตฌ์กฐ ๊ฐœ์„  ์—ฐ๊ตฌ ๊ณผ์ • ๊ฐ€์„ค -> ์‹คํ—˜ ์„ค๊ณ„ -> ์‹คํ—˜ ์ˆ˜ํ–‰ -> ๊ฒฐ๊ณผ ๋ถ„์„ Multitask Learning ํ•˜๋‚˜์˜ ๋ชจ๋ธ์ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ task๋ฅผ ๋™์‹œ์— ํ•™์Šตํ•˜๋Š” ๋ฐฉ๋ฒ• ๊ฐ์ข… ์—ฐ๊ตฌ ๋ฐ์ดํ„ฐ ์ฆ๊ฐ• ๊ธฐ์กด์— ํš๋“๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ์— ๋ณ€ํ˜•์„ ๊ฐ€ํ•˜์—ฌ ๋ชจ๋ธ์˜ ์ผ๋ฐ˜ํ™” ์„ฑ๋Šฅ์„ ๋†’์ด๋Š” ๋ฐฉ๋ฒ• ๊ฐ€์ƒ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ/ํ™œ์šฉ ํ˜„์‹ค๊ณผ ์œ ์‚ฌํ•œ ๊ฐ€์ƒ ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ•™์Šตํ•œ ๋ชจ๋ธ์„ ํ˜„์‹ค์— ์ ์šฉ ์ •๋ณด ์œตํ•ฉ ์–ด๋–ค ์ˆœ๊ฐ„์ ์ธ ์ •๋ณด๋ฅผ ์ž˜ ๋ถ„์„ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋งŒ๋“ฆ ์ด์ƒ ํƒ์ง€ Reconstruction ๊ธฐ๋ฐ˜ : ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐจ์› ์ถ•์†Œ -> ์ฐจ์› ํ™•์žฅํ•˜์—ฌ ๋ณต์› ๊ฐ€๋Šฅ์„ฑ์œผ๋กœ ๋ณต์› ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ/๋ณต์› ๋ฐ์ดํ„ฐ์™€ ์›๋ณธ ์ฐจ์ด๊ฐ€ ํฐ ๊ฒฝ์šฐ ์ด์ƒ์œผ๋กœ ํŒ๋ณ„ Prediction ๊ธฐ๋ฐ˜ : ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฏธ๋ž˜๋ฅผ ์˜ˆ์ธก -> ํ•ด๋‹น ์˜ˆ์ธก๊ณผ ์‹ค์ œ ๊ฐ’์˜ ์ฐจ์ด๊ฐ€ ํฐ ๊ฒฝ์šฐ ์ด์ƒ์œผ๋กœ ํƒ์ง€ Representation ๊ธฐ๋ฐ˜ : ํŠน์ • ํ‘œํ˜„ ๊ณต๊ฐ„์œผ๋กœ ๋ฐ์ดํ„ฐ ๋งตํ•‘ -> ํ‘œํ˜„ ๊ณต๊ฐ„์—์„œ์˜ ๊ฑฐ๋ฆฌ/๋ฐ€๋„ ๊ธฐ๋ฐ˜์œผ๋กœ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๋ฒ—์–ด๋‚œ ๋ฐ์ดํ„ฐ๋ฅผ ์ด์ƒ์œผ๋กœ ํƒ์ง€
new Python์˜ ๋™์ž‘ ์›๋ฆฌ
๐Ÿ Python
ํŒŒ์ด์ฌ์˜ ๊ตฌํ˜„์ฒด CPython ํŒŒ์ด์ฌ์˜ ํ‘œ์ค€ ๊ตฌํ˜„์ฒด์ด์ž ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์—ญํ•  ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ ํŒŒ์ด์ฌ ๋ฐ”์ดํŠธ ์ฝ”๋“œ .pyc ํŒŒ์ผ์— ์ €์žฅ ํ”Œ๋žซํผ์— ๋…๋ฆฝ์  ํŒŒ์ด์ฌ ๊ฐ€์ƒ ๋จธ์‹ (PVM)์—์„œ ์‹คํ–‰ ์˜ˆ์‹œ 4 0 LOAD_GLOBAL 0 (print) 2 LOAD_CONST 1 ('hello world') 4 CALL_FUNCTION 1 6 POP_TOP 5 8 LOAD_CONST 2 (True) 10 RETURN_VALUE Jython ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ์ž๋ฐ” ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜, JVM์—์„œ ์‹คํ–‰ ์žฅ์  : ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ, ์ž๋ฐ” ํด๋ž˜์Šค ์‚ฌ์šฉ ๊ฐ€๋Šฅ, GIL ์—†์Œ ๋‹จ์  : ํŒŒ์ด์ฌ 3.x ์ง€์›ํ•˜์ง€ ์•Š์Œ, CPython ๋Œ€๋น„ ์†๋„๊ฐ€ ๋А๋ฆผ PyPy ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ JIT ์ปดํŒŒ์ผํ•˜์—ฌ ์‹คํ–‰ RPython(Restricted Python)์œผ๋กœ ์ž‘์„ฑ๋œ ํŒŒ์ด์ฌ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ ‘๊ทผ ๋ฐฉ์‹ RPython(์—„๊ฒฉํ•œ ํŒŒ์ด์ฌ)์„ ๋งŒ๋“ค์–ด ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ์ž‘์„ฑ RPython์˜ ํšจ๊ณผ์ ์ธ ์ปดํŒŒ์ผ์„ ์œ„ํ•ด ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ํˆด์ฒด์ธ์„ ์ œ์ž‘ Python ๊ตฌํ˜„์„ RPython ๋ฌธ๋ฒ•์œผ๋กœ ์ž‘์„ฑ 3์—์„œ ๋งŒ๋“  ๊ตฌํ˜„์„ 1, 2๋ฅผ ํ†ตํ•ด ์–ป์€ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋กœ ์ปดํŒŒ์ผ 4์—์„œ ๋งŒ๋“  ํ›„๋ณด๋“ค์˜ ์„ฑ๋Šฅ์„ ์ธก์ •ํ•˜๊ณ , ๊ฐœ์„  5์˜ ์‚ฐ์ถœ๋ฌผ์„ ์ถœ์‹œ, ๋‹ค์‹œ ๋ฐ˜๋ณต ์žฅ๋‹จ์  ์žฅ์  : CPython ๋Œ€๋น„ ๋น ๋ฅธ ์†๋„, ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ ์ง€์› ๋‹จ์  : ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๊ฐ€ ์กด์žฌ, ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ํผ
new JIT ์ปดํŒŒ์ผ๋Ÿฌ์™€ AOT ์ปดํŒŒ์ผ๋Ÿฌ
โ˜• Java
JIT(Just-In-Time) ์ปดํŒŒ์ผ๋Ÿฌ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰ ์ค‘์ผ๋•Œ, ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ์ฃผ์š” ์ž‘์—… Hotspot(์ž์ฃผ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ)์„ ํƒ์ง€ ์ตœ์ ํ™” ์ˆ˜์ค€ ๊ฒฐ์ • ์ตœ์ ํ™” ๋ฐ ์ปดํŒŒ์ผ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ ์ƒ์„ฑ ์บ์‹ฑ : ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋ฅผ ์บ์‹ฑํ•˜์—ฌ ์žฌ์‚ฌ์šฉ AOT(Ahead-Of-Time) ์ปดํŒŒ์ผ๋Ÿฌ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๊ธฐ ์ „์—, ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋ฐฉ์‹ X, ์ปดํŒŒ์ผ ๋ฐฉ์‹ O ์‹คํ–‰ ์†๋„๊ฐ€ ๋น ๋ฆ„ GraalVM์„ ์‚ฌ์šฉํ•˜๋ฉด Java ํ”„๋กœ๊ทธ๋žจ์„ AOT ์ปดํŒŒ์ผ ๊ฐ€๋Šฅ GraalVM ์˜ค๋ผํด์—์„œ ๊ฐœ๋ฐœํ•œ JVM ๊ธฐ๋ฐ˜์˜ ๋‹ค์–‘ํ•œ ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜๋Š” ํ†ตํ•ฉ ์‹คํ–‰ ํ™˜๊ฒฝ (JVM, JDK) ์žฅ์  ๋ฉ€ํ‹ฐ ์–ธ์–ด ์ง€์› AOT ์ปดํŒŒ์ผ ์ง€์› ๋‹จ์  ์ดˆ๊ธฐ ์„ค์ •์ด ๋ณต์žกํ•จ ๋นŒ๋“œ ์†๋„๊ฐ€ ๋А๋ฆผ JIT vs AOT ๊ตฌ๋ถ„ JIT AOT ์ปดํŒŒ์ผ ์‹œ์  ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ค‘ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ „ ์ปดํŒŒ์ผ ๋Œ€์ƒ Hotspot(์ž์ฃผ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ๋งŒ) ์ „์ฒด ์ฝ”๋“œ ์ปดํŒŒ์ผ ์†๋„ ์ƒ๋Œ€์ ์œผ๋กœ ๋А๋ฆผ ์ƒ๋Œ€์ ์œผ๋กœ ๋น ๋ฆ„ ์‹คํ–‰ ์†๋„ ์ดˆ๊ธฐ์—๋Š” ๋А๋ฆผ(์ปดํŒŒ์ผ ์‹œ๊ฐ„ ์†Œ์š”) ์ดˆ๊ธฐ๋ถ€ํ„ฐ ๋น ๋ฆ„ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ƒ๋Œ€์ ์œผ๋กœ ์ ์Œ ๋” ๋งŽ์ด ์†Œ๋ชจ๋  ์ˆ˜ ์žˆ์Œ ์ดˆ๊ธฐ ๋ถ€ํŒ… ์‹œ๊ฐ„ ์ƒ๋Œ€์ ์œผ๋กœ ๋А๋ฆผ ๋น ๋ฆ„
new JVM(Java Virtual Machine)
โ˜• Java
์ž๋ฐ” ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์ƒ ๋จธ์‹  JVM์˜ ๊ตฌ์กฐ ํด๋ž˜์Šค ๋กœ๋” (Class Loader) ๋กœ๋”ฉ (Loading) : .class ํŒŒ์ผ์„ ์ฝ์–ด๋“ค์—ฌ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌ ๋งํฌ (Linking) : ์ ์žฌ๋œ ํด๋ž˜์Šค์˜ ์ฐธ์กฐ๋ฅผ ํ™•์ธํ•˜๊ณ  ์ค€๋น„ ์ดˆ๊ธฐํ™” (Initialization) : static ๋ธ”๋ก๊ณผ static ๋ณ€์ˆ˜ ์ดˆ๊ธฐํ™” ์‹คํ–‰ ์—”์ง„ (Execution Engine) ํด๋ž˜์Šค ๋กœ๋”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌ๋œ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์—ญํ•  ์ธํ„ฐํ”„๋ฆฌํ„ฐ (Interpreter) ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ๋ช…๋ น์–ด ๋‹จ์œ„๋กœ ์ฝ์–ด์„œ ์‹คํ–‰ JIT ์ปดํŒŒ์ผ๋Ÿฌ (Just-In-Time Compiler) Runtime ์‹œ์ ์— ๋ฐ”์ดํŠธ ์ฝ”๋“œ ์ „์ฒด๋ฅผ ์ปดํŒŒ์ผํ•˜์—ฌ ๊ธฐ๊ณ„์–ด๋กœ ๋ณ€๊ฒฝ ํ›„ ์‹คํ–‰ -> ์„ฑ๋Šฅ ํ–ฅ์ƒ GC (Garbage Collector) ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•˜๋Š” ์—ญํ•  ๋Ÿฐํƒ€์ž„ ๋ฐ์ดํ„ฐ ์˜์—ญ (Runtime Data Area) PC(Program Counter) ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋ถ€๋ถ„์˜ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ JVM ์Šคํƒ (JVM Stack) ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ์‹œ๋งˆ๋‹ค ํ”„๋ ˆ์ž„์„ ์ถ”๊ฐ€ํ•˜๊ณ , ๋ฉ”์†Œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ํ•ด๋‹น ํ”„๋ ˆ์ž„์„ ์ œ๊ฑฐ ๊ฐ ํ”„๋ ˆ์ž„์€ ๋กœ์ปฌ ๋ณ€์ˆ˜, ์—ฐ์‚ฐ ์Šคํƒ, ๋ฉ”์†Œ๋“œ ์ˆ˜ํ–‰์ด ๋๋‚˜๋ฉด ์ข…๋ฃŒ๋˜๋Š” ์ •๋ณด๋ฅผ ์ €์žฅ Native ๋ฉ”์†Œ๋“œ ์Šคํƒ JNI(Java Native Interface)๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœ๋˜๋Š” C/C++/Assembly์™€ ๊ฐ™์€ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋ฅผ ์œ„ํ•œ ์Šคํƒ ํž™ (Heap) new ํ‚ค์›Œ๋“œ๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด์™€ ๋ฐฐ์—ด์„ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„ ๋ฉ”์†Œ๋“œ ์˜์—ญ (Method Area) ํด๋ž˜์Šค ์ •๋ณด, ์ƒ์ˆ˜, ์ •์  ๋ณ€์ˆ˜ ๋“ฑ์„ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„ ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๊ณต๊ฐ„ -> ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋”ฉ ์‹œ ๋™๊ธฐํ™” ์ฒ˜๋ฆฌ ํ•„์š”
new DDD(Domain Driven Design)
๐Ÿƒ Spring
๋„๋ฉ”์ธ ํŒจํ„ด์„ ์ค‘์‹ฌ์œผ๋กœ ์„ค๊ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•๋ก  IOC ๊ฐ์ฒด์˜ ์ œ์–ด๊ถŒ์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹Œ ํ”„๋ ˆ์ž„์›Œํฌ ๋˜๋Š” ์™ธ๋ถ€ ์ปจํ…Œ์ด๋„ˆ์—๊ฒŒ ๋„˜๊ธฐ๋Š” ๊ฒƒ ๋ชฉ์  ๊ฐ์ฒด ๊ฐ„ ๊ฒฐํ•ฉ๋„๋ฅผ ๊ฐ์†Œ -> ์œ ์—ฐ์„ฑ, ์žฌ์‚ฌ์šฉ์„ฑ ์ฆ๊ฐ€ ๊ตฌํ˜„ํ•˜๋Š” ๊ธฐ๋ฒ• DI(Dependency Injection) Constructor Injection Setter Injection Field Injection DL(Dependency Lookup) Service Locator Event-based callback DI(Dependency Injection) ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด ๊ด€๊ณ„๋ฅผ ๊ฐ์ฒด ์ž์‹ ์ด ์•„๋‹Œ ์™ธ๋ถ€์—์„œ ์ฃผ์ž…ํ•˜๋Š” ๊ฒƒ ์žฅ์  ๊ฐ์ฒด ๊ฐ„ ๊ฒฐํ•ฉ๋„ ๊ฐ์†Œ ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ ์ฆ๊ฐ€ ๊ฐ์ฒด์˜ ์ฑ…์ž„์ด ๋ช…ํ™•ํ•˜๊ณ  ๋‹จ์ˆœํ•จ ๋‹จ์  ์ดˆ๊ธฐ ์„ค์ •, ๊ตฌํ˜„์ด ๋ณต์žกํ•จ ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ์ ์— ์˜์กด ๊ฐ์ฒด๊ฐ€ ์—†์œผ๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒ DL(Dependency Lookup) ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด ๊ด€๊ณ„๋ฅผ ๊ฐ์ฒด ์ž์‹ ์ด ์•„๋‹Œ ์™ธ๋ถ€์—์„œ ์ฐพ์•„์˜ค๋Š” ๊ฒƒ ์žฅ์  ๊ฐ์ฒด ๊ฐ„ ๊ฒฐํ•ฉ๋„ ๊ฐ์†Œ (DI๋ณด๋‹ค ๋œ ๊ฐ์†Œ) ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ์ ์— ์˜์กด ๊ฐ์ฒด๊ฐ€ ์—†์–ด๋„ ์—๋Ÿฌ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ ๊ตฌํ˜„์ด ๊ฐ„๋‹จํ•จ ๋‹จ์  ๊ฐ์ฒด์˜ ์ฑ…์ž„์ด ๋ถˆ๋ช…ํ™•ํ•ด์ง ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ ๊ฐ์†Œ ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด ๊ด€๊ณ„ ํŒŒ์•…์ด ์–ด๋ ค์›€
new Python์˜ GIL
๐Ÿ Python
GIL(Global Interpreter Lock) ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ ํŒŒ์ด์ฌ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ ํŒŒ์ด์ฌ์˜ ํ‘œ์ค€ ๊ตฌํ˜„์ธ CPython์—์„œ๋งŒ ์กด์žฌ ์žฅ์  Reference Counting ๊ธฐ๋ฐ˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์˜ Race condition ๋ฐฉ์ง€ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ ๋ณด์žฅ : ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ํŒŒ์ด์ฌ ๊ฐ์ฒด๋‚˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ์ž‘์—…์ด ์•ˆ์ „ํ•˜๊ฒŒ ์ˆ˜ํ–‰๋˜๋„๋ก ๋ณด์žฅ ํŒŒ์ด์ฌ Interpreter์˜ ๊ตฌํ˜„์„ ๋‹จ์ˆœํ™” : ๋ณต์žกํ•œ ๋ฝ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ•„์š”์—†์Œ C ํ™•์žฅ ๋ชจ๋“ˆ์ด Thread-Safe ํ•˜์ง€ ์•Š๋”๋ผ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณด์žฅ ํ”Œ๋žซํผ ๋…๋ฆฝ์„ฑ ์œ ์ง€ : CPU ์•„ํ‚คํ…์ฒ˜๋ณ„ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ์˜์กดํ•˜์ง€ ์•Š์Œ ๋‹จ์  ๋ฉ€ํ‹ฐ์ฝ”์–ด CPU ํ™œ์šฉ ์ œํ•œ: ๋‹จ์ผ ์ฝ”์–ด๋งŒ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์˜ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์—†์Œ ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋”ฉ ์„ฑ๋Šฅ ์ €ํ•˜ : ์“ฐ๋ ˆ๋“œ ๊ฐ„ context switching์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒ ๊ณต์ •์„ฑ ๋ฌธ์ œ : ํŠน์ • ์“ฐ๋ ˆ๋“œ๊ฐ€ GIL์„ ์žฅ์‹œ๊ฐ„ ์ ์œ ํ•˜๋ฉด starvation ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ Reference Counting ๊ฐ์ฒด๊ฐ€ ๋ช‡ ๋ฒˆ ์ฐธ์กฐ๋˜๋Š”์ง€๋ฅผ ์„ธ์–ด์„œ 0์ด ๋˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•˜๋Š” ๋ฐฉ์‹ ํŒŒ์ด์ฌ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ฐฉ์‹ ์žฅ์  : ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๊ฐ€ ์ฆ‰์‹œ ์ด๋ฃจ์–ด์ง ๋‹จ์  : Reference Counting์ด ๋ณต์žกํ•œ ๊ฐ์ฒด ์‚ฌ์ด์˜ ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•จ IO Bound Task vs CPU Bound Task IO Bound Task : ํŒŒ์ผ ์ฝ๊ธฐ/์“ฐ๊ธฐ, ๋„คํŠธ์›Œํฌ ํ†ต์‹  ๋“ฑ์˜ ์ž‘์—… CPU Bound Task : ๊ณ„์‚ฐ๋Ÿ‰์ด ๋งŽ์€ ์ž‘์—… GIL์ด ์ฃผ๋Š” ์˜ํ–ฅ IO Bound Task : I/O์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋™์•ˆ GIL์ด ํ•ด์ œ๋˜์–ด ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Œ -> ์˜ํ–ฅ์ด ์ ์Œ CPU Bound Task : GIL์ด ํ•ด์ œ๋˜์ง€ ์•Š์•„ ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋  ์ˆ˜ ์—†์Œ -> ์†ํ•ด๊ฐ€ ๋ฐœ์ƒ ๋Œ€์•ˆ multiprocessing ๋ชจ๋“ˆ ์‚ฌ์šฉ C ํ™•์žฅ ๋ชจ๋“ˆ ์‚ฌ์šฉ Jython, IronPython ๋“ฑ์˜ GIL์ด ์—†๋Š” ํŒŒ์ด์ฌ ๊ตฌํ˜„ ์‚ฌ์šฉ
new ์†Œํ”„ํŠธ์›จ์–ด ํ…Œ์ŠคํŠธ
๐ŸŽธ ๊ธฐํƒ€
๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ๊ณ ๋ คํ•˜๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ฅธ ํ…Œ์ŠคํŠธ์˜ ๋ถ„๋ฅ˜ ๋ธ”๋ž™๋ฐ•์Šค ํ…Œ์ŠคํŠธ ํ™”์ดํŠธ๋ฐ•์Šค ํ…Œ์ŠคํŠธ ๋ชฉ์ ๊ณผ ๋ฒ”์œ„์— ๋”ฐ๋ฅธ ํ…Œ์ŠคํŠธ์˜ ๋ถ„๋ฅ˜ ์ˆ˜ํ–‰ ์ˆœ์„œ์— ๋”ฐ๋ผ ์ž‘์„ฑํ•ด๋ณด์•˜๋‹ค. 1. ๋‹จ์œ„ ํ…Œ์ŠคํŠธ (Unit Test) ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„ ์ˆ˜์ค€(๋ชจ๋“ˆ, ํ•จ์ˆ˜, ํด๋ž˜์Šค)์˜ ํ…Œ์ŠคํŠธ 2. ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ (Integration Test) ๋ชจ๋“ˆ์„ ํ†ตํ•ฉํ•˜๋Š” ๊ณผ์ •์—์„œ, ๊ฐ ๋ชจ๋“ˆ ๊ฐ„์˜ ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ด€๋ จ๋œ ๊ฒฐํ•จ์ด ์žˆ๋Š”์ง€ ํ…Œ์ŠคํŠธ Top-down : ์ƒ์œ„ ๋ชจ๋“ˆ๋ถ€ํ„ฐ ํ•˜์œ„ ๋ชจ๋“ˆ๋กœ ํ†ตํ•ฉํ•˜๋ฉฐ ํ…Œ์ŠคํŠธ Bottom-up : ํ•˜์œ„ ๋ชจ๋“ˆ๋ถ€ํ„ฐ ์ƒ์œ„ ๋ชจ๋“ˆ๋กœ ํ†ตํ•ฉํ•˜๋ฉฐ ํ…Œ์ŠคํŠธ Big-bang : ๋ชจ๋“  ๋ชจ๋“ˆ์„ ํ•œ๋ฒˆ์— ํ†ตํ•ฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ Threads : ์ค‘์š” ๋ชจ๋“ˆ์„ ๋จผ์ € ๊ตฌํ˜„ํ•˜๊ณ  ํ†ตํ•ฉํ•œ ๋’ค, ๋ณด์กฐ์ ์ธ ๋ชจ๋“ˆ์„ ๊ตฌํ˜„ ํ›„ ํ†ตํ•ฉํ•˜๋Š” ๋ฐฉ์‹ 3. ์‹œ์Šคํ…œ ํ…Œ์ŠคํŠธ (System Test) ์ „์ฒด ์‹œ์Šคํ…œ์ด ์š”๊ตฌ์‚ฌํ•ญ์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธ (HW+SW) ์ฃผ์š” ๊ด€์  ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ ๋น„๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ : ์„ฑ๋Šฅ, ์•ˆ์ •์„ฑ, ๋ณด์•ˆ, ์‚ฌ์šฉ์„ฑ ๋“ฑ ๊ธฐํƒ€ ๋น„๊ธฐ๋Šฅ์ ์ธ ์ธก๋ฉด์„ ํ‰๊ฐ€ E2E ํ…Œ์ŠคํŠธ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ ํ˜ธํ™˜์„ฑ ํ…Œ์ŠคํŠธ : ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์—์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธ 4. ์ธ์ˆ˜ ํ…Œ์ŠคํŠธ (Acceptance Test) ์‚ฌ์šฉ์ž ๊ด€์ ์—์„œ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์—ฌ๋ถ€์— ๋”ฐ๋ฅธ ํ…Œ์ŠคํŠธ์˜ ๋ถ„๋ฅ˜ ์ •์  ํ…Œ์ŠคํŠธ ๋™์  ํ…Œ์ŠคํŠธ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ๊ณ ๋ คํ•˜๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ฅธ ํ…Œ์ŠคํŠธ์˜ ๋ถ„๋ฅ˜ ๋ธ”๋ž™๋ฐ•์Šค ํ…Œ์ŠคํŠธ ํ™”์ดํŠธ๋ฐ•์Šค ํ…Œ์ŠคํŠธ ์ •์  ํ…Œ์ŠคํŠธ SW๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ํ…Œ์ŠคํŒ…ํ•˜๋Š” ๊ธฐ๋ฒ• ๋ฆฌ๋ทฐ ์—ฌ๋Ÿฌ ์ „๋ฌธ๊ฐ€๋“ค์ด ๋ชจ์—ฌ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•œ SW ๊ฐœ๋ฐœ ๋ฐ ์‚ฐ์ถœ๋ฌผ์„ ๊ฒ€ํ† ํ•˜๊ณ  ํ…Œ์ŠคํŒ…ํ•˜์—ฌ ๊ฒฐํ•จ์„ ๊ฒ€์ถœํ•˜๋Š” ๋ฐฉ๋ฒ• Inspection ์ „๋ฌธ์ ์ธ inspection team์ด ์ •ํ˜•ํ™”๋œ ๋ฐฉ์‹์œผ๋กœ defect๋ฅผ ์ฐพ๋Š” ๋ฆฌ๋ทฐ ๊ธฐ๋ฒ• Planning -> Overview -> Preparation -> Meeting(Inspection) -> Rework -> Follow-up Peer Review (Technical Review) ๊ฐœ๋ฐœํŒ€์ด ์ฃผ๋„ํ•˜์—ฌ ์ง์ ‘ ๋ชจ์—ฌ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฆฌ๋ทฐ ๊ธฐ๋ฒ• PL ๋˜๋Š” TL์ด ์ฃผ๋„ํ•˜์—ฌ ๋ฆฌ๋ทฐ ๋Œ€์ƒ์„ ์„ ์ •, ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ฆฌ๋ทฐ ์š”์ฒญ Walkthrough Peer Review์™€ ์œ ์‚ฌํ•˜๋‚˜ ๋ฌธ์„œ ์ž‘์„ฑ์ž๊ฐ€ ์ฃผ๋„ํ•˜๋Š” ๊ฐ€๋ฒผ์šด ๋งŒ๋‚จ ํ˜•ํƒœ ์ •์  ๋ถ„์„ (๋ฌด๊ธฐ์ฒด๊ณ„SW ๊ฐœ๋ฐœ ๋ฐ ๊ด€๋ฆฌ ๋งค๋‰ด์–ผ ๊ธฐ์ค€) ์ฝ”๋”ฉ ๊ทœ์น™ MISRA-C MISRA-C++ C# Coding conventions Code conventions for the Java Programming Language CWE(Common Weakness Enumeration) ์ ๊ฒ€ ์ผ๋ฐ˜์ ์ธ SW์™€ HW์˜ ๋ณด์•ˆ ์•ฝ์ ์„ ๋‚˜์—ดํ•œ ๊ณต์‹์ ์ธ ๋ฆฌ์ŠคํŠธ CWE-658 : C์–ธ์–ด CWE-659 : C++ CWE-660 : Java Code Metric ์ ๊ฒ€ Cyclomatic Complexity : ์ œ์–ด ํ๋ฆ„ ๊ทธ๋ž˜ํ”„์˜ ๋ณต์žก๋„ Number of call levels : ์กฐ๊ฑด๋ฌธ ์ค‘์ฒฉ์˜ ๊นŠ์ด Number of function parameters Number of calling function : ํ•จ์ˆ˜๊ฐ€ ๋ช‡ ๋ฒˆ ํ˜ธ์ถœ๋˜๋Š”๊ฐ€ Number of called functions : ํ•จ์ˆ˜๋ฅผ ๋ช‡ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š”๊ฐ€ Number of Executable code lines ๋™์  ํ…Œ์ŠคํŠธ ๋ช…์„ธ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ (๋ธ”๋ž™๋ฐ•์Šค ๊ธฐ๋ฒ•) ๋™๋“ฑ ๋ถ„ํ•  ๊ฒฝ๊ณ„๊ฐ’ ๋ถ„์„ ๊ฒฐ์ • ํ…Œ์ด๋ธ” ํ…Œ์ŠคํŠธ ์ƒํƒœ ์ „์ด ํ…Œ์ŠคํŠธ ๋ถ„๋ฅ˜ ํŠธ๋ฆฌ ๊ธฐ๋ฒ• ์กฐํ•ฉ ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค ํ…Œ์ŠคํŠธ … ๊ตฌ์กฐ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ (ํ™”์ดํŠธ๋ฐ•์Šค ๊ธฐ๋ฒ•) Statement Coverage Decision Coverage (Branch Coverage) Condition Coverage MC/DC Coverage Path Coverage Fuzzing ํ…Œ์ŠคํŠธ ์œ ํšจํ•œ, ์˜ˆ์ƒ์น˜ ์•Š์€ ๊ฐ’๋“ค์„ ๋ฌด์ž‘์œ„๋กœ ๋Œ€์ž…ํ•˜๋Š” ํ…Œ์ŠคํŠธ ๊ธฐ๋ฒ• ๋ณ€ํ˜• ๊ธฐ๋ฐ˜ Fuzzing (Dumb Fuzzing) ์ž…๋ ฅ ์ƒ˜ํ”Œ์„ Fuzzing ๋„๊ตฌ์— ์ œ๊ณต, Fuzzing ๋„๊ตฌ๊ฐ€ ์ด๋ฅผ ๋ณ€ํ˜•์‹œ์ผœ๊ฐ€๋ฉด์„œ ํ…Œ์ŠคํŠธ ์žฅ์  ์‰ฝ๊ณ  ๋น ๋ฅด๊ฒŒ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅ ์ž…๋ ฅ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ๋ถ„์„์„ ํ•˜์ง€ ์•Š์•„๋„ ๋จ ๋‹จ์  ๋ฏธ๋ฆฌ ์ •์˜๋œ ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ์ฒดํฌ์„ฌ์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ์œ ํšจํ•œ ์ž…๋ ฅ์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ ์–ด๋ ค์›€์ด ์กด์žฌ ์ƒ์„ฑ ๊ธฐ๋ฐ˜ Fuzzing (Smart Fuzzing) ๋Œ€์ƒ ์‹œ์Šคํ…œ์— ์ž…๋ ฅ์‹œํ‚ฌ ๋ฐ์ดํ„ฐ๋ฅผ Fuzzing ๋„๊ตฌ๊ฐ€ ์ƒ์„ฑ ์žฅ์  ๋” ๋†’์€ Coverage๋กœ ์ด์–ด์ง€๋Š” ํ…Œ์ŠคํŠธ์ผ€์ด์Šค๋ฅผ ์ƒ์„ฑ ๋‹จ์  ์ž…๋ ฅ ๋ชจ๋ธ์— ๋Œ€ํ•œ ์ดํ•ด๋„๊ฐ€ ์„ ํ–‰๋˜์–ด์•ผ ํ•จ ๊ตฌํ˜„ ๋‚œ์ด๋„๊ฐ€ ๋†’์Œ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ (Regression Test) ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋Š” ์†Œํ”„ํŠธ์›จ์–ด์˜ ์ƒˆ๋กœ์šด ๋ฒ„์ „์—์„œ ๊ธฐ์กด ๊ธฐ๋Šฅ์ด ์†์ƒ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ…Œ์ŠคํŠธ ํšŒ๊ท€ ๋ฒ„๊ทธ(Regression Bug) : ์ด์ „์— ์กด์žฌํ•˜์ง€ ์•Š๋˜ ๋ฒ„๊ทธ๊ฐ€ ๊ธฐ๋Šฅ ์ˆ˜์ •์ด๋‚˜, ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€๋กœ ์ธํ•ด ์ƒˆ๋กœ์šด ๋ฒ„์ „์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฒ„๊ทธ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋Š” ๋ฐ˜๋ณต์ ์ธ ์ž‘์—…์ด ๋งŽ์•„ ์ž๋™ํ™” ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์ด ํšจ์œจ์  ํšŒ๊ท€ ํ…Œ์ŠคํŠธ์˜ ์ข…๋ฅ˜ Retest all ๊ธฐ๋ฒ• : ๊ธฐ์กด์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•˜์—ฌ ์ „์ฒด ์‹œ์Šคํ…œ์„ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ๋ฒ• Selective retest ๊ธฐ๋ฒ• : ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋งŒ ์„ ํƒ์ ์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ• Prirority ๊ธฐ๋ฒ• : ์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ์ค‘์‹ฌ์œผ๋กœ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ •ํ•˜์—ฌ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ• FIRST ์›์น™ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์˜ 5์›์น™ Fast : ํ…Œ์ŠคํŠธ๋Š” ๋นจ๋ผ์•ผ ํ•œ๋‹ค. Independent : ํ…Œ์ŠคํŠธ๋Š” ์„œ๋กœ ๋…๋ฆฝ์ ์ด์–ด์•ผ ํ•œ๋‹ค. Repeatable : ํ…Œ์ŠคํŠธ๋Š” ์–ด๋–ค ํ™˜๊ฒฝ์—์„œ๋„ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค. Self-validating : ํ…Œ์ŠคํŠธ๋Š” ์„ฑ๊ณต ๋˜๋Š” ์‹คํŒจ์—ฌ์•ผ ํ•œ๋‹ค. (bool ๊ฐ’) Timely : ํ…Œ์ŠคํŠธ๋Š” ์ ์‹œ์— ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค. (์‹ค์ œ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— ์ž‘์„ฑ)
new Github Readme Stats - private ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋„ ํฌํ•จํ•˜๊ธฐ
๐ŸŽธ ๊ธฐํƒ€
๋ฐฐ๊ฒฝ github์—์„œ ์ž์‹ ์ด ์–ด๋–ค ์–ธ์–ด๋ฅผ ์ฃผ๋กœ ์“ฐ๋Š”์ง€ ํ†ต๊ณ„๋ฅผ ์ฃผ๋Š” Readme๋ฅผ ๋ณธ ๊ธฐ์–ต์ด ๋‚˜์„œ ๋‚˜๋„ ๋งŒ๋“ค์–ด๋ณด๊ณ  ์‹ถ์—ˆ๋‹ค. anuraghazra/github-readme-stats๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ README.md์— ์ถ”๊ฐ€ํ•˜์˜€๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ preview๋ฅผ ํ•ด๋ณด์•˜์„ ๋•Œ, typescript๊ฐ€ ์ ˆ๋ฐ˜์œผ๋กœ ๋‚˜์˜ค๋Š” ๊ฒƒ์ด๋‹ค. ๋ง์ด ์•ˆ๋˜๋Š” ์ˆ˜์น˜๋ผ์„œ ์•Œ์•„๋ณด๋‹ˆ, public ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋งŒ ํฌํ•จ๋˜์–ด ๊ทธ๋Ÿฐ ๊ฒƒ์ด์—ˆ๋‹ค. private ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋„ ํ†ต๊ณ„์— ํฌํ•จํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๊ฒ ๋‹ค. ๋ฐฉ๋ฒ• maintainer๊ฐ€ ๋ฐฐํฌํ•ด๋†“์€ ์„œ๋น„์Šค๋Š” ๋‚˜์˜ private ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. private repository๋„ ํฌํ•จํ•œ ํ†ต๊ณ„๋ฅผ ๋ณด๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ง์ ‘ ๋ฐฐํฌํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ์ต์ˆ™ํ•œ Github Pages๋กœ ๋ฐฐํฌํ•˜๋ ค๊ณ  ํ–ˆ์œผ๋‚˜, ๋™์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์–ด์„œ Vercel๋กœ ๋ฐฐํฌํ•˜์˜€๋‹ค. 1. Github Token ๋ฐœ๊ธ‰ ๋ฐ›๊ธฐ Github์—์„œ PAT(Personal Access Token)์„ ๋ฐœ๊ธ‰ ๋ฐ›๋Š”๋‹ค. scope๋Š” repo์™€ read:user๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•œ๋‹ค. 2. Vercel๋กœ ๋ฐฐํฌํ•˜๊ธฐ ๋‚˜๋Š” ๋จผ์ € anuraghara๋ผ๋Š” ๋ถ„์ด ๋งŒ๋“ค์–ด๋†“์€ origin ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ forkํ•˜์˜€๋‹ค. Vercel๋กœ ๋กœ๊ทธ์ธํ•œ ํ›„, Github ๊ณ„์ •๊ณผ ์—ฐ๋™ํ•˜์—ฌ forkํ•œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์„ ํƒํ•œ๋‹ค. ํ™˜๊ฒฝ๋ณ€์ˆ˜์— PAT_1์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋ฐœ๊ธ‰๋ฐ›์€ PAT์„ ๋“ฑ๋กํ•œ๋‹ค. ๋ฐฐํฌํ•œ๋‹ค. 3. README.md์— ์ถ”๊ฐ€ํ•˜๊ธฐ ์„œ๋น„์Šค์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ์ง€๋งŒ, ํ•„์ž๋Š” “Top Languages Card"๋งŒ ์ถ”๊ฐ€ํ•  ๊ฒƒ์ด๋‹ค. url์€ ‘{Vercel์—์„œ ๋ฐฐํฌํ•œ URL}/api/top-langs?username={Github ID}‘์ด๋‹ค. ์ด url์„ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ README.md์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค. 1[![Top Langs](https://{Vercel์—์„œ ๋ฐฐํฌํ•œ URL}/api/top-langs?username={Github ID})] ๊ฒฐ๊ณผ private ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋„ ํฌํ•จํ•˜์—ฌ ํ†ต๊ณ„๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.
new Issue - yaml ๋ฌธ์ž์—ด ์† colon(์ฝœ๋ก )
๐ŸŽธ ๊ธฐํƒ€
๋ฌธ์ œ์ƒํ™ฉ TIL ๋ธ”๋กœ๊ทธ ์ž๋™ ๋ฐฐํฌ github action ์ฝ”๋“œ์— yaml ํŒŒ์ผ์— ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค ์ถ”๊ฐ€ํ•˜๋Š” ๋ฌธ์ž์—ด์— ์ฝœ๋ก ์ด ํฌํ•จ๋˜์–ด ์žˆ์–ด์„œ action์—์„œ ์—๋Ÿฌ๋ฅผ ๋„์› ๋‹ค ๋ฌธ์ œ์˜ ์ฝ”๋“œ 1- name: Add google analytics id 2 run: echo -e "\nparams:\n googleAnalytics : \"$GA_TRACKING_ID\"" >> config.yaml ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ์šฐ์—ฌ๊ณก์ ˆ ๋์— ์œ„์™€ ๊ฐ™์ด 2์ค„๋กœ ๋‚˜๋ˆ„์–ด์„œ ํ•ด๊ฒฐํ–ˆ๋‹ค 1 - name: Add google analytics id 2 run: | 3 echo -e "\nparams:" >> config.yaml 4 echo -e " googleAnalytics: \"$GA_TRACKING_ID\"" >> config.yaml
new [๋ชจ๊ฐ์ฝ”24๋™๊ณ„] 01 : ๊ฒฐ๊ณผ
๐Ÿ‘จโ€๐Ÿ’ป ๋ชจ๊ฐ์ฝ”
1. Agile ๋ฐฉ๋ฒ•๋ก  Agile ์„ ์–ธ๋ฌธ ์‚ฌ๋žŒ๊ณผ ์ƒํ˜ธ์ž‘์šฉ > ํ”„๋กœ์„ธ์Šค์™€ ๋„๊ตฌ ์ž‘๋™ํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด > ํฌ๊ด„์ ์ธ ๋ฌธ์„œ ๊ณ ๊ฐ๊ณผ์˜ ํ˜‘๋ ฅ > ๊ณ„์•ฝ ํ˜‘์ƒ ๋ณ€ํ™”์— ๋Œ€ํ•œ ๋Œ€์‘ > ๊ณ„ํš์„ ๋”ฐ๋ฅด๊ธฐ Agile 12๊ฐ€์ง€ ์›์น™ ์ดˆ๊ธฐ๋ถ€ํ„ฐ ์ง€์†์ ์œผ๋กœ ๊ณ ๊ฐ์„ ๋งŒ์กฑ ์š”๊ตฌ์‚ฌํ•ญ ๋ณ€๊ฒฝ ์ˆ˜์šฉ ์งง์€ ๋ฐฐํฌ ์ฃผ๊ธฐ ๊ธฐํš์ž์™€ ๊ฐœ๋ฐœ์ž์˜ ํ˜‘์—… ๋™๊ธฐ๋ถ€์—ฌ๋œ ํŒ€์›๋“ค๋กœ ํŒ€๋นŒ๋”ฉ ์–ผ๊ตด๋ณด๊ณ  ๋Œ€ํ™”ํ•˜๊ธฐ ๋™์ž‘๋˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด๋กœ ์ง„์ฒ™ ์ธก์ • ์ง€์† ๊ฐ€๋Šฅํ•œ ๊ฐœ๋ฐœ ์†๋„ ์œ ์ง€ ์ข‹์€ ๊ธฐ์ˆ ๋กœ ์ข‹์€ ์„ค๊ณ„ํ•˜๊ธฐ ๋‹จ์ˆœ์„ฑ : ํ•„์š”์—†๋Š” ์ผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์ž๊ธฐ์กฐ์งํ™” ํŒ€ ์ •๊ธฐ์ ์œผ๋กœ ํšจ์œจ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ Self-Organizing Team (์ž๊ธฐ์กฐ์งํ™” ํŒ€) ์Šค์Šค๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ ์ง„ํ–‰ ์ƒํ™ฉ์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์Šค์Šค๋กœ ๊ฒฐ์ •ํ•˜๋Š” ํŒ€ 2. Scrum ๋ฐฉ๋ฒ•๋ก  ์—ญํ•  PO(Product Owner) : ์ œํ’ˆ ์ฑ…์ž„์ž, ์ œํ’ˆ ๋ฐฑ๋กœ๊ทธ ๊ด€๋ฆฌ SM(Scrum Master) : ์Šคํฌ๋Ÿผ ๋งˆ์Šคํ„ฐ, ์Šคํฌ๋Ÿผ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ ์šฉํ•˜๊ณ  ์ง€์› Dev(Development Team) : ๊ฐœ๋ฐœํŒ€, ์Šคํ”„๋ฆฐํŠธ ๋ฐฑ๋กœ๊ทธ๋ฅผ ๊ฐœ๋ฐœ Stakeholder : ์ดํ•ด๊ด€๊ณ„์ž, ์ œํ’ˆ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ ์ œ๊ณต ์šฉ์–ด Product Backlog : ์š”๊ตฌ์‚ฌํ•ญ์ธ ์‚ฌ์šฉ์ž ์Šคํ† ๋ฆฌ ์ง‘ํ•ฉ User Story : ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๊ด€์ ์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฐ€์น˜์— ๋Œ€ํ•œ ์„ค๋ช… ์™„๋ฃŒ ๊ธฐ์ค€ (Definition of Done), ์ธ์ˆ˜ ๊ธฐ์ค€ (Acceptance Criteria) : ์‚ฌ์šฉ์ž ์Šคํ† ๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํŒ๋‹จํ•˜๋Š” ๊ธฐ์ค€ Sprint Planning Meeting : sprint ๋ชฉํ‘œ์™€ sprint backlog๋ฅผ ๊ณ„ํšํ•˜๋Š” ํšŒ์˜ Sprint Backlog : sprint ๋™์•ˆ ๊ฐœ๋ฐœํ•  ์ž‘์—… ๋ชฉ๋ก Kanban Board : ์ž‘์—…์„ ์‹œ๊ฐ์ ์œผ๋กœ ์—…๋ฌด ์ƒํƒœ, ํ๋ฆ„์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒŒ์‹œํŒ Backlog To Do In Progress Verify Done Product Backlog Sprint Backlog Sprint Backlog Sprint Backlog Sprint Backlog Daily Scrum : ์–ด์ œ ํ•œ ์ผ, ์˜ค๋Š˜ ํ•  ์ผ, ๋ฌธ์ œ ์š”์†Œ๋ฅผ ๊ณต์œ ํ•˜๋Š” ํšŒ์˜ Sprint Review : ์Šคํ”„๋ฆฐํŠธ ๋งˆ์ง€๋ง‰ ๋‚  ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐœ๋ฐ”ํ•œ ๋‚ด์šฉ์„ Stakeholder, Client, PO์—๊ฒŒ ์‹œ์—ฐํ•˜๊ณ  ๊ฒ€ํ†  Sprint Retrospective (์Šคํ”„๋ฆฐํŠธ ํšŒ๊ณ ) : ์Šคํ”„๋ฆฐํŠธ ๋™์•ˆ ๊ฐœ์„ ํ•  ์ ์„ ์ฐพ๊ณ  ๊ฐœ์„  ๋ฐฉ์•ˆ์„ ์ œ์‹œ ์ง€ํ‘œ Velocity Chart : ์Šคํ”„๋ฆฐํŠธ ๋ณ„๋กœ ์™„๋ฃŒํ•œ ์ž‘์—…๋Ÿ‰์„ ๋ณด์—ฌ์ฃผ๋Š” ์ฐจํŠธ Burndown chart : ์Šคํ”„๋ฆฐํŠธ ๋ณ„๋กœ ๋‚จ์€ ์ž‘์—…๋Ÿ‰์„ ๋ณด์—ฌ์ฃผ๋Š” ์ฐจํŠธ
new Issue - Gihub action ์˜ค๋ฅ˜ - yaml multiline
๐ŸŽธ ๊ธฐํƒ€
๋ฌธ์ œ์ƒํ™ฉ TIL ๋ธ”๋กœ๊ทธ ์ž๋™ ๋ฐฐํฌ github action์ด ์ž˜ ์ž‘๋™ํ•˜๋‹ค๊ฐ€ ์‹คํŒจํ•œ๋‹ค. ์—๋Ÿฌ ๋กœ๊ทธ์—๋Š” python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์„ค์น˜๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๋‚ด์šฉ์ด ์ ํ˜€์žˆ์—ˆ๋‹ค. ๋ฌธ์ œ์˜ yaml ์ฝ”๋“œ 1- name: Install dependencies 2 run: python -m pip install --upgrade pip 3 pip install -r requirements.txt ํ•ด๊ฒฐ๋ฐฉ๋ฒ• fix: github action error - “Could not find a version” ํ•˜๋‹จ์˜ pip install ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์•„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•˜์˜€๋‹ค. literal ๋ฐฉ์‹์œผ๋กœ pipe(|)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘๋ฒˆ์งธ ์ค„์˜ ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ์ˆ˜์ •ํ•˜์˜€๋‹ค. 1- name: Install dependencies 2 run: | 3 python -m pip install --upgrade pip 4 pip install -r requirements.txt 5- name: Run python script ํšŒ๊ณ  github action์—์„œ yamlํŒŒ์ผ์„ ํŒŒ์‹ฑํ•˜๋Š” ๋กœ์ง์ด ๋ฐ”๋€๊ฒƒ์— ๋Œ€ํ•œ ํŒจ์น˜ ๋…ธํŠธ๋Š” ์ฐพ์ง€๋ชปํ•˜์˜€๋‹ค. ๋ชจํ˜ธํ•œ ๋ฌธ๋ฒ•์œผ๋กœ yaml์„ ์ž‘์„ฑํ•˜์—ฌ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์˜€๋‹ค. ์ดํ›„์—๋Š” yaml ๋ฌธ๋ฒ•์„ ๋”์šฑ ๊ผผ๊ผผํžˆ ํ™•์ธํ•˜๊ณ  ์‚ฌ์šฉํ•ด์•ผ๊ฒ ๋‹ค.
new Issue - Gihub action ์˜ค๋ฅ˜ - venv ์ ์šฉ
๐ŸŽธ ๊ธฐํƒ€
๋ฌธ์ œ์ƒํ™ฉ TIL ๋ธ”๋กœ๊ทธ ์ž๋™ ๋ฐฐํฌ github action์ด ์ž˜ ์ž‘๋™ํ•˜๋‹ค๊ฐ€ ์‹คํŒจํ•œ๋‹ค. ์—๋Ÿฌ๋กœ๊ทธ 1error: externally-managed-environment 2 3ร— This environment is externally managed 4โ•ฐโ”€> To install Python packages system-wide, try apt install 5 python3-xyz, where xyz is the package you are trying to 6 install. 7 8 If you wish to install a non-Debian-packaged Python package, 9 create a virtual environment using python3 -m venv path/to/venv. 10 Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make 11 sure you have python3-full installed. 12 13 If you wish to install a non-Debian packaged Python application, 14 it may be easiest to use pipx install xyz, which will manage a 15 virtual environment for you. Make sure you have pipx installed. 16 17 See /usr/share/doc/python3.11/README.venv for more information. ํ•ด๊ฒฐ๋ฐฉ๋ฒ• fix: gh-action error “The environment is externally managed” ๋กœ๊ทธ์— ๋ช…์‹œ๋œ๋Œ€๋กœ venv๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•˜์˜€๋‹ค.
new ๋ฐฑ์ค€ - 20125 : ์ฟ ํ‚ค์˜ ์‹ ์ฒด ์ธก์ • (S4)
๐Ÿง  Algorithm
1#include <bits/stdc++.h> 2using namespace std; 3 4char board[1000][1000] = { NULL }; 5int n; 6 7tuple<int, int, int> getlength(int sx, int sy, int dx, int dy) { 8 int cnt = 0; 9 int x = sx; 10 int y = sy; 11 12 while (true) { 13 x += dx; 14 y += dy; 15 if (y < 0 || y >= n || x < 0 || x >= n || board[x][y] != '*') { 16 return { cnt, x-dx, y-dy }; 17 } 18 cnt++; 19 } 20} 21 22int main() { 23 cin.tie(0)->sync_with_stdio(false); 24 cin >> n; 25 26 pair<int, int> heart = { 0, 0 }; 27 tuple<int, int, int> ass = { 0, 0, 0 }; 28 29 for (int i = 0; i < n; i++) { 30 for (int j = 0; j < n; j++) { 31 cin >> board[i][j]; 32 if (board[i][j] == '*' && heart.first == 0) 33 heart = { j, i + 1 }; 34 } 35 } 36 37 ass = getlength(heart.second, heart.first, 1, 0); 38 39 cout << heart.second+1 << " " << heart.first+1 << "\n"; 40 cout << get<0>(getlength(heart.second, heart.first, 0, -1)) << " " 41 << get<0>(getlength(heart.second, heart.first, 0, 1)) << " " 42 << get<0>(ass) << " " 43 << get<0>(getlength(get<1>(ass), get<2>(ass)-1, 1, 0)) << " " 44 << get<0>(getlength(get<1>(ass), get<2>(ass)+1, 1, 0)); 45 46 return 0; 47} ๋ฌธ์ œ ์ •์‚ฌ๊ฐํ˜• ํŒ์˜ ํฌ๊ธฐ N๊ณผ ์ฟ ํ‚ค์˜ ์‹ ์ฒด ๋ชจ์–‘์ด 2์ฐจ์› ๋ฌธ์ž๋กœ ์ฃผ์–ด์ง„๋‹ค. 1๋ฒˆ์งธ ์ค„์—๋Š” ์‹ฌ์žฅ์˜ ์œ„์น˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. 2๋ฒˆ์งธ ์ค„์—๋Š” ์™ผํŒ”, ์˜ค๋ฅธํŒ”, ํ—ˆ๋ฆฌ, ์™ผ๋‹ค๋ฆฌ, ์˜ค๋ฅธ๋‹ค๋ฆฌ์˜ ๊ธธ์ด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๊ธ€๋กœ ์„ค๋ช…ํ•˜๊ธฐ ์‰ฝ์ง€ ์•Š๋‹ค. ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ์ž…๋ ฅ ๋ฐ›์œผ๋ฉด์„œ ์‹ฌ์žฅ์˜ ์œ„์น˜๋ฅผ ๋”ด๋‹ค. ์‹ฌ์žฅ์˜ ์œ„์น˜๋ฅผ ํ†ตํ•ด ํ—ˆ๋ฆฌ์˜ ๋์„ ๋”ด๋‹ค. ์™ผํŒ”, ์˜ค๋ฅธํŒ”, ํ—ˆ๋ฆฌ์˜ ๊ธธ์ด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ํ—ˆ๋ฆฌ์˜ ๋์„ ์ด์šฉํ•ด ์™ผ๋‹ค๋ฆฌ, ์˜ค๋ฅธ๋‹ค๋ฆฌ์˜ ๊ธธ์ด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. getlength() ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์—ฌ ๊ฐ ๊ธธ์ด๋ฅผ ๊ตฌํ–ˆ๋‹ค. ๋ง‰ํ˜”๋˜ ๋ถ€๋ถ„ x, y๊ฐ€ ํ˜ผ๋™๋˜์–ด์„œ ๊ณ ์น˜๋Š”๋ฐ ์‹œ๊ฐ„์„ ๋งŽ์ด ์žก์•„ ๋จน์ž c++๋กœ 2์ฐจ์› ๋ฐฐ์—ด ๋‹ค๋ฃจ๋Š” ๋ฌธ์ œ๋ฅผ ์—ด์‹ฌํžˆ ํ’€์–ด๋ณด์ž!
new ๋ฐฑ์ค€ - 8979 : ์˜ฌ๋ฆผํ”ฝ (S5)
๐Ÿง  Algorithm
1#include <bits/stdc++.h> 2using namespace std; 3 4struct medal { 5 int number; 6 int gold; 7 int silver; 8 int bronze; 9}; 10bool cmp(medal a, medal b) { 11 if (a.gold != b.gold) return a.gold > b.gold; 12 if (a.silver != b.silver) return a.silver > b.silver; 13 return a.bronze > b.bronze; 14 15} 16int main() { 17 cin.tie(0)->sync_with_stdio(false); 18 int n = 0, target = 0, rank = 0; 19 cin >> n; 20 cin >> target; 21 22 medal* arr = new medal[n]; 23 24 for (int i = 0; i < n; i++) { 25 cin >> arr[i].number >> arr[i].gold >> arr[i].silver >> arr[i].bronze; 26 } 27 sort(arr, arr + n, cmp); 28 29 for (int i = 0; i < n; i++) { 30 if (i == 0 || (arr[i].gold != arr[i - 1].gold || arr[i].silver != arr[i - 1].silver || arr[i].bronze || arr[i - 1].bronze)) { 31 rank = i + 1; 32 } 33 34 if (arr[i].number == target) { 35 cout << rank << "\n"; 36 break; 37 } 38 } 39 40 delete[] arr; 41 return 0; 42} ๋ฌธ์ œ 1๋ฒˆ์งธ ์ค„์— ๊ตญ๊ฐ€๊ฐœ์ˆ˜, ํŠน์ • ๊ตญ๊ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. 2๋ฒˆ์งธ ์ค„์— ๊ตญ๊ฐ€๋ฒˆํ˜ธ, ๊ธˆ๋ฉ”๋‹ฌ ์ˆ˜, ์€๋ฉ”๋‹ฌ ์ˆ˜, ๋™๋ฉ”๋‹ฌ ์ˆ˜๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ํŠน์ • ๊ตญ๊ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋ช‡๋“ฑ์ธ์ง€ ์ถœ๋ ฅํ•ด์•ผํ•œ๋‹ค. ๊ธˆ, ์€, ๋™๋ฉ”๋‹ฌ ์ˆ˜๊ฐ€ ๋ชจ๋‘ ๊ฐ™๋‹ค๋ฉด ๊ฐ™์€ ๋“ฑ์ˆ˜๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค. ๋งŒ์•ฝ ๊ณต๋™ 2๋“ฑ์ธ ๋‚˜๋ผ๊ฐ€ 2๊ฐœ ๋‚˜์˜ค๋Š” ๊ฒฝ์šฐ, 3๋“ฑ์€ ์—†๋‹ค TC input 4 3 1 1 2 0 2 0 1 0 3 0 1 0 4 0 0 1 ouput 2 ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ๊ตฌ์กฐ์ฒด๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตญ๊ฐ€๋ฒˆํ˜ธ, ๊ธˆ, ์€, ๋™๋ฉ”๋‹ฌ ์ˆ˜๋ฅผ ์ €์žฅํ•œ๋‹ค. cmpํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ •๋ ฌํ•œ๋‹ค. ํŠน์ • ๊ตญ๊ฐ€๋ฒˆํ˜ธ๋ฅผ ์ฐพ์•„์„œ ๋“ฑ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๊ฐ™์€ ๋“ฑ์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€์ˆ˜ rank๋ฅผ ํ™œ์šฉํ•˜์˜€๋‹ค.
  • ««
  • «
  • 1
  • 2
  • 3
  • 4
  • 5
  • »
  • »»
๐Ÿง  Algorithm (104) ๐ŸŒŠ C/CPP (2) โ˜• Java (8) ๐ŸŒ Javascript (9) ๐Ÿ Python (9) ๐Ÿƒ Spring (30) ๐Ÿ”จ ๊ฐœ๋ฐœ ๋„๊ตฌ (2) ๐ŸŽธ ๊ธฐํƒ€ (7) ๐Ÿ‘จโ€๐Ÿ’ป ๋ชจ๊ฐ์ฝ” (38) ๐Ÿค– ์ธ๊ณต์ง€๋Šฅ (2) ๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€ (28)
๐Ÿท๏ธ boj (53) ๐Ÿท๏ธ c (5) ๐Ÿท๏ธ c++ (4) ๐Ÿท๏ธ celery (2) ๐Ÿท๏ธ cs (18) ๐Ÿท๏ธ django (3) ๐Ÿท๏ธ docker (2) ๐Ÿท๏ธ docker compose (1) ๐Ÿท๏ธ elk (1) ๐Ÿท๏ธ fastapi (4) ๐Ÿท๏ธ git (2) ๐Ÿท๏ธ github actions (5) ๐Ÿท๏ธ hackerrank (3) ๐Ÿท๏ธ https (2) ๐Ÿท๏ธ java (37) ๐Ÿท๏ธ javascript (2) ๐Ÿท๏ธ jwt (1) ๐Ÿท๏ธ kubernetes (4) ๐Ÿท๏ธ nginx (2) ๐Ÿท๏ธ ocaml (1) ๐Ÿท๏ธ open source (2) ๐Ÿท๏ธ programmers (48) ๐Ÿท๏ธ pytest (1) ๐Ÿท๏ธ python (111) ๐Ÿท๏ธ rabbitmq (2) ๐Ÿท๏ธ rag (3) ๐Ÿท๏ธ react (6) ๐Ÿท๏ธ security (3) ๐Ÿท๏ธ software-engineering (3) ๐Ÿท๏ธ spring (31) ๐Ÿท๏ธ sql (5) ๐Ÿท๏ธ ssl (1) ๐Ÿท๏ธ testing (4) ๐Ÿท๏ธ typescript (1) ๐Ÿท๏ธ vercel (1) ๐Ÿท๏ธ websocket (1)