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 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 ๋ฐฑ์ค€ - 10844 : ์‰ฌ์šด ๊ณ„๋‹จ ์ˆ˜ (S1)
๐Ÿง  Algorithm
์ ‘๊ทผ์ด ์–ด๋ ค์›Œ ์ธํ„ฐ๋„ท์„ ์ฐธ๊ณ ํ–ˆ๋‹ค. ์ฝ”๋“œ๋Š” ๋ณด์ง€ ์•Š์•˜๋‹ค. ์ˆ˜์˜ ๊ธธ์ด๊ฐ€ i์ด๋ฉด์„œ ๋งˆ์ง€๋ง‰ ์ˆซ์ž๊ฐ€ j์ธ ๊ณ„๋‹จ ์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด๋‹ค. ์ ํ™”์‹์€ L[i][j] = L[i-1][j-1]+L[i-1][j+1] ์ด๋‹ค. 1N = int(input()) 2L = [[0]*12 for _ in range(100)] 3L[0] = [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0] 4 5for i in range(1, N): 6 for j in range(1, 11): 7 L[i][j] = L[i-1][j-1]+L[i-1][j+1] 8 9print (sum(L[N-1])%1000000000)
new ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค - ์—ฐ์† ์ˆ˜์—ด ํ•ฉ์˜ ๊ฐœ์ˆ˜ (L2)
๐Ÿง  Algorithm
์ฒซ๋ฒˆ์งธ ํ’€์ด 1def solution(elements): 2 result = set() 3 length = len(elements) 4 elements = elements*2 5 for i in range(length): 6 temp = 0 7 for j in range(length): 8 temp += elements[i+j] 9 result.add(temp) 10 11 return len(result) ๊ฐœ์„ ํ•œ ํ’€์ด 1def solution(elements): 2result = set() 3length = len(elements) 4for i in range(length): 5 temp = 0 6 for j in range(length): 7 temp += elements[(i+j)%length] 8 result.add(temp) 9 10return len(result) ๋ฌธ์ œ ์ฃผ์–ด์ง„ ์ •์ˆ˜ ๋ฐฐ์—ด๋กœ ์›ํ˜• ์ˆ˜์—ด์„ ๋งŒ๋“ ๋‹ค ์›ํ˜• ์ˆ˜์—ด์˜ ์—ฐ์†๋œ ๋ถ€๋ถ„ ์ˆ˜์—ด์˜ ํ•ฉ์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜์—ฌ๋ผ TC input [7,9,1,1,4] ouput 18 ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ์ฒซ๋ฒˆ์งธ ํ’€์ด์—์„œ๋Š” ๋ฐฐ์—ด์„ 2๋ฐฐ๋กœ ๋Š˜๋ ค์„œ ์›ํ˜• ์ˆ˜์—ด์„ ๋งŒ๋“ค์—ˆ๋‹ค ๊ฐœ์„ ํ•œ ํ’€์ด์—์„œ๋Š” mod ์—ฐ์‚ฐ์„ ์ด์šฉํ•ด์„œ ์›ํ˜• ์ˆ˜์—ด์„ ๋งŒ๋“ค์—ˆ๋‹ค set๋ฅผ ์ด์šฉํ•ด์„œ ์ค‘๋ณต์„ ์ œ๊ฑฐํ•˜๊ณ  ์›์†Œ ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜์˜€๋‹ค
new ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค - ์ด๋ชจํ‹ฐ์ฝ˜ ํ• ์ธํ–‰์‚ฌ (L2)
๐Ÿง  Algorithm
1result = [] 2 3def dfs(size, percent, users, emoticons): 4 global result 5 6 if len(percent) == size: 7 temp = [0] * len(users) 8 for i in range(size): 9 for j in range(len(users)): 10 if percent[i]*100 >= users[j][0]: 11 temp[j] += emoticons[i]*(1-percent[i]) 12 serviceNum = 0 13 income = 0 14 for i in range(len(users)): 15 if temp[i] >= users[i][1]: 16 serviceNum += 1 17 else: 18 income += temp[i] 19 result.append ((serviceNum, income)) 20 return 21 22 for i in [0.1, 0.2, 0.3, 0.4]: 23 dfs(size, percent+[i], users, emoticons) 24 25 26def solution(users, emoticons): 27 dfs(len(emoticons), [], users, emoticons) 28 result.sort(reverse=True) 29 return list(result[0]) ๋ฌธ์ œ ์นด์นด์˜คํ†ก ์‚ฌ์šฉ์ž n๋ช…์˜ ๊ตฌ๋งค ๊ธฐ์ค€์„ ๋‹ด์€ 2์ฐจ์› ์ •์ˆ˜ ๋ฐฐ์—ด users, ์ด๋ชจํ‹ฐ์ฝ˜ m๊ฐœ์˜ ์ •๊ฐ€๋ฅผ ๋‹ด์€ 1์ฐจ์› ์ •์ˆ˜ ๋ฐฐ์—ด emoticons๊ฐ€ ์ฃผ์–ด์ง„๋‹ค ๊ฐ ์‚ฌ์šฉ์ž๋Š” ์ผ์ • ๋น„์œจ ์ด์ƒ ํ• ์ธํ•˜๋Š” ์ด๋ชจํ‹ฐ์ฝ˜์„ ๊ตฌ๋งคํ•œ๋‹ค ๊ฐ ์‚ฌ์šฉ์ž๋Š” ๊ตฌ๋งคํ•œ ์ด๋ชจํ‹ฐ์ฝ˜ ๊ฐ€๊ฒฉ์˜ ํ•ฉ์ด ์ผ์ • ๊ธฐ์ค€์„ ๋„˜์œผ๋ฉด ์ด๋ชจํ‹ฐ์ฝ˜ ๊ตฌ๋งค๋ฅผ ๋ชจ๋‘ ์ทจ์†Œํ•˜๊ณ  ์ด๋ชจํ‹ฐ์ฝ˜ ํ”Œ๋Ÿฌ์Šค ์„œ๋น„์Šค์— ๊ฐ€์ž…ํ•œ๋‹ค ํ• ์ธ์œจ์€ 10%, 20%, 30%, 40% ์ค‘ ํ•˜๋‚˜์ด๋‹ค ์ด๋ชจํ‹ฐ์ฝ˜ ํ”Œ๋Ÿฌ์Šค ์„œ๋น„์Šค์— ๊ฐ€์ž…์ž๋ฅผ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ์„ ์ตœ์šฐ์„ ์œผ๋กœ ํ•˜๋ฉฐ, ์ด๋ชจํ‹ฐ์ฝ˜ ํŒ๋งค์•ก์„ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ์„ ๋‘๋ฒˆ์งธ ๋ชฉํ‘œ๋กœ ํ–ˆ์„ ๋•Œ์˜ ์ด๋ชจํ‹ฐ์ฝ˜ ํ”Œ๋Ÿฌ์Šค ์„œ๋น„์Šค ๊ฐ€์ž…์ž ์ˆ˜์™€ ์ด๋ชจํ‹ฐ์ฝ˜ ๋งค์ถœ์•ก์„ 1์ฐจ์› ์ •์ˆ˜ ๋ฐฐ์—ด์— ๋‹ด์•„ ๋ฐ˜ํ™˜ํ•˜๋ผ TC input users: [[40, 10000], [25, 10000]], emoticons: [7000, 9000] ouput [1, 5400] ํ•ด๊ฒฐ๋ฐฉ๋ฒ• dfs๋ฅผ ์ด์šฉํ•ด์„œ ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์™„์ „ ํƒ์ƒ‰ํ•˜์—ฌ ํ•ด๊ฒฐํ•˜์˜€๋‹ค ํ• ์ธ์œจ์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ 4๊ฐ€์ง€ ๋ฐ–์— ์—†์–ด์„œ ๊ฐ€๋Šฅํ–ˆ๋˜ ์ผ์ด๋‹ค
new ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค - ํ• ์ธ ํ–‰์‚ฌ (L2)
๐Ÿง  Algorithm
1from collections import deque 2 3def solution(want, number, discount): 4 want_dict = dict() 5 answer = 0 6 7 for i in range(len(want)): 8 want_dict[want[i]] = number[i] 9 10 for i in discount[:10]: 11 if i in want_dict: 12 want_dict[i] -= 1 13 14 for i in range(0, len(discount)-9): 15 if all(map(lambda x: x <= 0, want_dict.values())): 16 answer += 1 17 18 if discount[i] in want_dict: 19 want_dict[discount[i]] += 1 20 if i+10 < len(discount) and discount[i+10] in want_dict: 21 want_dict[discount[i+10]] -= 1 22 23 return answer ๋ฌธ์ œ XYZ๋งˆํŠธ์—์„œ๋Š” ํšŒ์›์— ๊ฐ€์ž…ํ•˜๋ฉด 10์ผ๋™์•ˆ ํ• ์ธํ˜œํƒ์„ ๋ฐ›๋Š”๋‹ค ํ• ์ธํ•˜๋Š” ์ œํ’ˆ์€ ํ•˜๋ฃจ์— ํ•˜๋‚˜์”ฉ๋งŒ ๊ตฌ๋งคํ•  ์ˆ˜ ์žˆ๋‹ค ์ •ํ˜„์ด๊ฐ€ ์›ํ•˜๋Š” ์ œํ’ˆ ๋ฆฌ์ŠคํŠธ, ์›ํ•˜๋Š” ์ œํ’ˆ์˜ ์ˆ˜๋Ÿ‰ ๋ฆฌ์ŠคํŠธ, ๋งˆํŠธ์—์„œ ํ• ์ธํ•˜๋Š” ์ œํ’ˆ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค ์ •ํ˜„์ด๊ฐ€ ์›ํ•˜๋Š” ์ œํ’ˆ์„ ๋ชจ๋‘ ํ• ์ธ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํšŒ์› ๋“ฑ๋ก ๋‚ ์งœ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•˜๋ผ TC input want: [“banana”, “apple”, “rice”, “pork”, “pot”] number: [3, 2, 2, 2, 1] discount: [“chicken”, “apple”, “apple”, “banana”, “rice”, “apple”, “pork”, “banana”, “pork”, “rice”, “pot”, “banana”, “apple”, “banana”] ouput 5 ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ์›ํ•˜๋Š” ์ œํ’ˆ์„ dict๋กœ ๋งŒ๋“ ๋‹ค (key: ์ œํ’ˆ์ด๋ฆ„, value: ์ˆ˜๋Ÿ‰) ์›ํ•˜๋Š” ์ œํ’ˆ - ์ฒซ๋‚ ์— ๊ฐ€์ž…ํ–ˆ์„ ๋•Œ ํ• ์ธํ•˜๋Š” ์ œํ’ˆ์„ ๊ณ„์‚ฐํ•œ๋‹ค ๋ฐ˜๋ณต๋ฌธ์„ ์ˆœํšŒํ•˜๋ฉด์„œ ํ• ์ธํ•˜๋Š” ์ œํ’ˆ์„ ๋นผ๊ณ , ํ• ์ธํ•˜๋Š” ์ œํ’ˆ์„ ๋”ํ•œ๋‹ค (์ œํ’ˆ์ด ๋” ํ•„์š”ํ•˜๋ฉด ์–‘์ˆ˜, ๋œ ํ•„์š”ํ•˜๋ฉด ์Œ์ˆ˜) 0๋ณด๋‹ค ํฐ ์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉด answer์— 1์„ ๋”ํ•œ๋‹ค
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 [๋ชจ๊ฐ์ฝ”23ํ•˜๊ณ„] 02 : ๊ฒฐ๊ณผ
๐Ÿ‘จโ€๐Ÿ’ป ๋ชจ๊ฐ์ฝ”
1. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ํ•œ ๋ฌธ์ œ ํ’€๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค - ๋‹น๊ตฌ ์—ฐ์Šต (L2) ๐Ÿง  Algorithm <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1</span><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">solution</span>(m, n, startX, startY, balls): </span 2. Java์˜ Testing ๊ณต๋ถ€ํ•˜๊ธฐ Spring ๊ฐœ๋… - Testing ๐Ÿƒ Spring <h2 id="unit-test-๋‹จ์œ„-ํ…Œ์ŠคํŠธ">Unit Test (๋‹จ์œ„ ํ…Œ์ŠคํŠธ)</h2> <blockquote> <p>๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„ (ํด๋ž˜์Šค ๋˜๋Š” ๋ฉ”์†Œ๋“œ)๋ฅผ ๊ณ ๋ฆฝ์‹œ์ผœ์„œ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ์‹</p> </blockquote> <h3 id="๊ด€๋ จ-์šฉ์–ด">๊ด€๋ จ ์šฉ์–ด</h3> <h4 id="sut-sytem-under-test">SUT (Sytem Under Test)</h4> <blockquote> <p>ํ…Œ์ŠคํŠธํ•˜๊ณ ์žํ•˜๋Š” ์ฃผ์š” ๋Œ€์ƒ์ด ๋˜๋Š” Unit</p> </blockquote> <h4 id="doc-depended-on-component">DOC (Depended On Component)</h4> <blockquote> <p>SUT๊ฐ€ ์˜์กดํ•˜๋Š” ๊ฐ์ฒด</p> </blockquote> <h4 id="test-double">Test double</h4> <blockquote> <p>DOC๋ฅผ ๋Œ€์‹ ํ•ด ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด</p> </blockquote> <ul> <li>Test double์˜ ์ข…๋ฅ˜ : Moc
new [๋ชจ๊ฐ์ฝ”23ํ•˜๊ณ„] 02 : ๊ณ„ํš
๐Ÿ‘จโ€๐Ÿ’ป ๋ชจ๊ฐ์ฝ”
์˜ค๋Š˜์˜ ๋ชฉํ‘œ ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ํ•œ ๋ฌธ์ œ ํ’€๊ธฐ Springboot Testing ๊ณต๋ถ€ํ•˜๊ธฐ
new [๋ชจ๊ฐ์ฝ”24ํ•˜๊ณ„] 05 : ๊ณ„ํš
๐Ÿ‘จโ€๐Ÿ’ป ๋ชจ๊ฐ์ฝ”
์˜ค๋Š˜์˜ ๋ชฉํ‘œ Nginx์—์„œ HTTPS ์„ค์ •ํ•˜๊ธฐ
new Fastapi, RabbitMQ, Celery ์—ฐ๋™
๐Ÿ Python
๋ฐฐ๊ฒฝ ํ…Œ์ปค ๋ถ€ํŠธ์บ ํ”„์—์„œ ํŒ€ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ ์ค‘์ด๋‹ค. ์›น์†Œ์ผ“์„ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ gpt๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•˜๊ณ , ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ด๋Š” ์„œ๋น„์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค. ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ์›ํ™œํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ถ„์‚ฐ ๋น„๋™๊ธฐ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ๋ชฉํ‘œ Fastapi, RabbitMQ, Celery๋ฅผ ๊ฐ์ž docker ์ปจํ…Œ์ด๋„ˆ๋กœ ๊ตฌ๋™์‹œํ‚ค๊ณ  ์—ฐ๋™ํ•œ๋‹ค. docker-compose.yml 1version: '3' 2 3services: 4 rabbitmq: 5 image: rabbitmq:3 6 ports: 7 - "5672:5672" # RabbitMQ์˜ AMQP ํฌํŠธ 8 - "15672:15672" # RabbitMQ ๊ด€๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค ํฌํŠธ 9 volumes: 10 - rabbitmq_data:/var/lib/rabbitmq 11 expose: 12 - "5672" 13 - "15672" 14 15 celery_worker: 16 build: 17 context: . 18 dockerfile: Dockerfile.worker 19 command: celery -A utils.celery_worker worker --loglevel=info 20 working_dir: /app 21 volumes: 22 - ./app/utils:/app/utils 23 environment: 24 - CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672// 25 depends_on: 26 - rabbitmq 27 28 celery_beat: 29 image: celery:4 30 command: celery -A celery_beat beat --loglevel=info 31 working_dir: /app 32 environment: 33 - CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672// 34 volumes: 35 - ./app/utils:/app 36 depends_on: 37 - rabbitmq 38 39 web: 40 image: python:slim 41 working_dir: /app 42 # interactive mode 43 stdin_open: true 44 # tty mode 45 tty: true 46 environment: 47 - CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672// 48 volumes: 49 - ./app:/app 50 ports: 51 - "8000:8000" 52 depends_on: 53 - rabbitmq 54 - celery_worker 55 - celery_beat 56 57volumes: 58 rabbitmq_data: Celery worker์—๋งŒ Dockerfile.worker๋ฅผ ์ด๋ฏธ์ง€๋กœ ์‚ฌ์šฉํ•œ ์ด์œ  worker์— ์ถ”๊ฐ€์ ์œผ๋กœ python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ด์•ผํ•จ Celery ๊ณต์‹ ๋„์ปค ์ด๋ฏธ์ง€๊ฐ€ deprecated ๋˜์—ˆ์Œ. Fastapi๋Š” ์‹œ๊ฐ„ ๊ด€๊ณ„์ƒ ๋”ฐ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  python:slim ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. Dockerfile.worker 1FROM python:slim 2 3# ํ•„์š”ํ•œ ํŒจํ‚ค์ง€ ์„ค์น˜ 4# ffmpeg๊ฐ€ ํ•„์š”ํ•ด์„œ ์ถ”๊ฐ€ํ•˜์˜€๋‹ค 5RUN apt-get update && \ 6apt-get install -y --no-install-recommends gcc libpq-dev ffmpeg && \ 7rm -rf /var/lib/apt/lists/* 8 9# ํ•„์š”ํ•œ ํŒŒ์ด์ฌ ํŒจํ‚ค์ง€ ์„ค์น˜ 10COPY requirements_celery_worker.txt ./ 11RUN pip install --no-cache-dir -r requirements_celery_worker.txt celery_worker.py 1import os 2from celery import Celery 3 4broker_url = os.getenv('CELERY_BROKER_URL') 5app = Celery('worker', broker=broker_url, backend="rpc://") 6 7@app.task 8def add(x, y): 9 return x + y broker_url์€ RabbitMQ์˜ AMQP ์ฃผ์†Œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. backend๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•œ ๋ฐฑ์—”๋“œ๋กœ RabbitMQ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. Celery worker ์‚ฌ์šฉ ๋ฐฉ๋ฒ• 1from celery_worker import add 2 3# task๋ฅผ ๋น„๋™๊ธฐ๋กœ ์‹คํ–‰ 4result = add.delay(4, 4) 5 6# apply_async๋Š” delay์™€ ๋™์ผํ•œ ๊ธฐ๋Šฅ ์ˆ˜ํ–‰ 7# delay์™€ ๋‹ฌ๋ฆฌ ์ถ”๊ฐ€๋กœ ์—ฌ๋Ÿฌ ์˜ต์…˜์„ ์„ค์ • ๊ฐ€๋Šฅ 8result = add.apply_async((4, 4)) 9 10# ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•ด get()์„ ์‚ฌ์šฉ, ๋ธ”๋กœํ‚น ํ˜ธ์ถœ 11result.get() 12 13# ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์—… 14result.ready() 15 16# ์ž‘์—…์ด ์‹คํŒจํ–ˆ๋Š”์ง€ ํ™•์ธ 17result.successful() 18# or 19result.failed() 20 21# ์ž‘์—…์˜ ์ƒํƒœ ํ™•์ธ (PENDING, STARTED, SUCCESS, FAILURE) 22result.state()
new ์ธ๊ฐ„-์ปดํ“จํ„ฐ ์ƒํ˜ธ์ž‘์šฉ
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
Design Techniques Contextual Inquiry ์‚ฌ์šฉ์ž์˜ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ์ž์˜ ํ–‰๋™์„ ๊ด€์ฐฐ Design Funnel ์•„์ด๋””์–ด๋ฅผ ํ™•์žฅํ•จ๊ณผ ๋™์‹œ์— ์ถ•์†Œ ์‹œํ‚ด์œผ๋กœ์„œ ๊ฒฐ๊ณผ ๋„์ถœ Double Diamond Discover -> Define -> Develop -> Deliver Storyboarding ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ Prototyping ๋””์ž์ธ์„ ํ‘œํ˜„ํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด๋กœ ๊ตฌํ˜„ ์ข…๋ฅ˜: Low-fidelity(์ถฉ์‹ค๋„๊ฐ€ ๋‚ฎ์Œ), High-fidelity(์ถฉ์‹ค๋„๊ฐ€ ๋†’์Œ) User Testing In-lab vs On-site Moderated vs Unmoderated : Exploratory vs Assessment Presentation & Communication Needfinding (์š”๊ตฌ์‚ฌํ•ญ ๋„์ถœ) ์šฉ์–ด UI (User Interface) ์ œํ’ˆ์˜ ์‹œ๊ฐ์ ์ธ ์š”์†Œ UX (User Experience) ์ œํ’ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋А๋ผ๋Š” ๊ฒฝํ—˜ CX (Customer Experience) ๊ณ ๊ฐ์ด ์ œํ’ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ณผ์ •์—์„œ ๋А๋ผ๋Š” ์ „๋ฐ˜์ ์ธ ๊ฒฝํ—˜, ์ƒํ’ˆ ๋˜๋Š” ์„œ๋น„์Šค์˜ ๊ตฌ๋งค, ์‚ฌ์šฉ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •์ง“๋Š” ์š”์†Œ SD (Service Design) ์„œ๋น„์Šค๋ฅผ ๋””์ž์ธํ•˜๋Š” ๊ฒƒ HCI (Human-Computer Interaction) ์—ฌ๋Ÿฌ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ตœ๊ณ ์˜ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์„ ํƒ, ์ œ์ž‘, ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒƒ SRS (Software Requirement Specification) ์†Œํ”„ํŠธ์›จ์–ด ์š”๊ตฌ์‚ฌํ•ญ ๋ช…์„ธ์„œ User Requirements, Functional Requirements, Interface Requirements, Performance Requirements… SRS๋ฅผ ๋ฌธ์„œํ™”ํ•˜๊ธฐ์ „์— ์‚ฌ์šฉ์ž๋ฅผ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š” ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์ดํ•ด ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ž์˜ ํŠน์„ฑ์„ ์ดํ•ด : ์—ญํ• , ๊ฐœ์„ฑ ์ดํ•ด๊ด€๊ณ„์ž(stakeholders)๋ฅผ ๊ณ ๋ ค First degree : ์ง์ ‘์ ์œผ๋กœ ์ œํ’ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ Second degree : ์ œํ’ˆ์˜ ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ๋ฐ›๋Š” ์‚ฌ๋žŒ Third degree : ์„œ๋น„์Šค๋ฅผ ์„ค์น˜, ๋ฐฐํฌํ•˜๋Š” ์‚ฌ๋žŒ ๋˜๋Š” ๊ธฐ๋ฐ˜ ์‹œ์Šคํ…œ ์‚ฌ์šฉ์ž ๋ชฉ์  ํŒŒ์•… Identify the goals involved in the problem Decompose them into subtasks Abstract into goals Contextual Inquiry (์ƒํ™ฉ์  ์กฐ์‚ฌ) Context : ์‚ฌ์šฉ์ž์˜ ํ™˜๊ฒฝ ๊ด€์ฐฐ, ์ถ”์ƒํ™” ๊ธˆ์ง€ Partnership : ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ณต๊ฐ, ์‚ฌ์šฉ์ž์—๊ฒŒ ํ–‰๋™๊ณผ ๊ทธ ์ด์œ ๋ฅผ ์งˆ๋ฌธ Interpretation : ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ํ•ด์„์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ณต์œ , ์‚ฌ์šฉ์ž์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์Œ Focus : ๋ชฉํ‘œ์— ์ง‘์ค‘ The master-apprentice model (๋„์ œ์‹ ๋ชจ๋ธ) : ์‚ฌ์šฉ์ž(์„ ์ƒ), ๊ด€์ฐฐ์ž(ํ•™์ƒ) Contextual Inquiry๊ฐ€ ์ ์ ˆํ•˜์ง€ ์•Š์„ ๋•Œ Longidual study : ์‚ฌ์šฉ์ž์˜ ํ–‰๋™์„ ์žฅ๊ธฐ๊ฐ„ ๊ด€์ฐฐํ•ด์•ผํ•  ๋•Œ Sporadic behavior : ์‚ฌ์šฉ์ž์˜ ํ–‰๋™์ด ๋ถˆ๊ทœ์น™ํ•  ๋•Œ Large target : ์‚ฌ์šฉ์ž์˜ ๋ฒ”์œ„๊ฐ€ ๊ด‘๋ฒ”์œ„ ํ•  ๋•Œ Diary Study ์‚ฌ์šฉ์ž๊ฐ€ ์ผ์ƒ์ ์œผ๋กœ ํ•˜๋Š” ์ผ์„ ๊ธฐ๋กํ•˜๋Š” ๊ฒƒ ESM (Experience Sampling Method) ์ˆœ๊ฐ„์ ์ธ ํ™œ๋™๊ณผ ๊ฒฝํ—˜์— ์ดˆ์ ์„ ๋งž์ถฐ ๊ธฐ๋ก EMA (Ecological Momentary Assessment) ์‹ฌ๋ฆฌ์  ํ˜„์ƒ์˜ ๊ถค์ , ๋ถ„์‚ฐ, ๋ณ€๋™, ์—ญํ•™์— ์ดˆ์ ์„ ๋งž์ถฐ ๊ธฐ๋ก Survey Participatory Design ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๋””์ž์ธ์— ์ฐธ์—ฌํ•˜๋Š” ๊ฒƒ Affinity Diagram (์œ ์‚ฌ๋„ ๋‹ค์ด์–ด๊ทธ๋žจ) ์ˆ˜์ง‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„๋ฅ˜ํ•˜๋Š” ๊ฒƒ Persona ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€ํ‘œํ•˜๋Š” ๊ฐ€์ƒ์˜ ์ธ๋ฌผ Learnability ์ƒˆ๋กœ์šด UI๋ฅผ ๋ฐฐ์šฐ๋Š” ๋ฐฉ๋ฒ• Learning by Doing Learning by Watching Recognition vs Recall Recognition : ์‹œ๊ฐ์  ์š”์†Œ๋ฅผ ๋ณด๊ณ  ์ธ์ง€ํ•˜๋Š” ๊ฒƒ Recall : ๊ธฐ์–ต์„ ํ†ตํ•ด ์ธ์ง€ํ•˜๋Š” ๊ฒƒ Interaction style Command Language ์ธ๊ณต ์–ธ์–ด์˜ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅ Self Disclosure (์ž๊ธฐ ๊ณต๊ฐœ) : ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ช…๋ น์–ด๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œํ˜„ Menus and Forms Direct Manipulation ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐ˜์‘ ์‹œ๊ฐ์  ํ‘œํ˜„์„ ํ†ตํ•ด ์ƒํ˜ธ์ž‘์šฉ Speech Dialog Mental Model ์‚ฌ๋žŒ๋“ค์ด ์ž๊ธฐ ์ž์‹ , ๋‹ค๋ฅธ ์‚ฌ๋žŒ, ํ™˜๊ฒฝ, ์ž์‹ ์ด ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์‚ฌ๋ฌผ๋“ค์— ๋Œ€ํ•ด ๊ฐ–๋Š” ๋ชจํ˜• ๊ด€์ฐฐ, ์ธํ„ฐ๋ทฐ, ์ž‘์—… ๋ถ„์„์ด ํ•„์š”ํ•˜๋‹ค Conceptual Model ์ œํ’ˆ์ด ์–ด๋– ํ•œ ์›๋ฆฌ๋‚˜ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ดํ•ด Content strategy : ๊ฐ ํŽ˜์ด์ง€์— ๋‚˜ํƒ€๋‚˜๋Š” ๋‚ด์šฉ์˜ ๊ทœ์น™์ด๋‚˜ ๊ฐœ๋…์ด ์กด์žฌํ•˜๋Š”๊ฐ€? Channel starategy : ์ผ๊ด€์ ์ธ ๊ฒฝํ—˜, ์ง€์†์ ์ธ ๊ฒฝํ—˜, ์ƒํ˜ธ ๋ณด์™„์ ์ธ ๊ฒฝํ—˜์„ ๋งŒ๋“ค์–ด๋‚ด๋Š”๊ฐ€? Interaction models : ๋ณดํŽธ์ ์ธ ํŒจํ„ด์„ ์‚ฌ์šฉํ–ˆ๋Š”๊ฐ€?
new ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฐ MSA ํŠน๊ฐ• 1์ผ์ฐจ : ํด๋ผ์šฐ๋“œ ์ปดํ“จํŒ… ๊ฐœ๋… ๋ฐ ์—ญ์‚ฌ
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
ํด๋ผ์šฐ๋“œ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ธฐ ํด๋ผ์šฐ๋“œ๋ž€ ๊ฐœ์ธ์ด ๊ฐ€์ง„ ๋‹จ๋ง๊ธฐ๋ฅผ ํ†ตํ•ด์„œ๋Š” ์ฃผ๋กœ ์ž…/์ถœ๋ ฅ ์ž‘์—…๋งŒ ์ด๋ฃจ์–ด์ง€๊ณ , ์ •๋ณด๋ถ„์„ ๋ฐ ์ฒ˜๋ฆฌ, ์ €์žฅ, ๊ด€๋ฆฌ ์œ ํ†ต ๋“ฑ์˜ ์ž‘์—…์€ ํด๋ผ์šฐ๋“œ๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์ œ3์˜ ๊ณต๊ฐ„์—์„œ ์ด๋ฃจ์–ด์ง€๋Š” ์ปดํ“จํŒ… ์‹œ์Šคํ…œ ํ˜•ํƒœ ํด๋ผ์šฐ๋“œ ์ปดํ“จํŒ…์ด ํ•„์š”ํ•œ ์ด์œ  ๋น„์šฉ์ ˆ๊ฐ ์†๋„ํ–ฅ์ƒ ํ™•์žฅ์„ฑ ์ƒ์‚ฐ์„ฑ ํด๋ผ์šฐ๋“œ ์ปดํ“จํŒ… ์„œ๋น„์Šค๋ชจ๋ธ Infrastructure as a Service (IaaS) : IT๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์œ ์—ฐ์„ฑ๊ณผ ๊ด€๋ฆฌ ์ œ์–ด ๊ธฐ๋Šฅ์„ ์ œ๊ณต GCE, AWS, Azure Platform as a Service (Paas) : ๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ํ™˜๊ฒฝ์ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณต Openshift, Github, docker, kubernetes Software as a a Service (Saas) : ์™„์ „ํ•œ ์ œํ’ˆ ์ œ๊ณต GShift ๋น„๊ต On-site < Iaas < Paas < Saas ์›นํ˜ธ์ŠคํŒ… vs ์„œ๋ฒ„ํ˜ธ์ŠคํŒ… vs ํด๋ผ์šฐ๋“œ ์ฐจ์ด์  ์›นํ˜ธ์ŠคํŒ… : ํ˜ธ์ŠคํŒ… ์—…์ฒด์˜ ์„œ๋ฒ„ ์ค‘ ์ผ๋ถ€๋งŒ ์ž„๋Œ€ํ•˜์—ฌ ์‚ฌ์šฉ ํ™ˆํŽ˜์ด์ง€ ์šด์˜ ์„œ๋ฒ„ํ˜ธ์ŠคํŒ… : ํ˜ธ์ŠคํŒ… ์—…์ฒด์˜ ๋ฌผ๋ฆฌ ์„œ๋ฒ„๋ฅผ ๋‹จ๋…์œผ๋กœ ์ž„๋Œ€/๊ตฌ๋งคํ•˜์—ฌ ์‚ฌ์šฉ ERP, ์ธํŠธ๋ผ๋„ท ๋“ฑ ์šด์˜ ํด๋ผ์šฐ๋“œ ๋‹จ๊ธฐ ์ด๋ฒคํŠธ ๋“ฑ ์œ ๋™์ ์ธ ์„œ๋น„์Šค ์šด์˜ On-premise๋ž€ ์ž์ฒด์ ์œผ๋กœ ๋ณด์œ ํ•œ ์ „์‚ฐ์‹ค์— ์ง์ ‘ ์„ค์น˜ํ•ด ์šด์˜ํ•˜๋Š” ๋ฐฉ์‹ Private, Public, Hybrid Cloud ๋น„๊ต Private cloud ์ธํ”„๋ผ๊ฐ€ ์กฐ์ง ์ „์šฉ์ธ ํด๋ผ์šฐ๋“œ ์ปดํ“จํŒ… ๋ชจ๋ธ ํ•ด๋‹น ์‚ฌ์šฉ์ž ๋˜๋Š” ๊ทธ๋ฃน์˜ ๋ฐฉํ™”๋ฒฝ์œผ๋กœ ๋ณดํ˜ธ๋œ๋‹ค Public cloud ์ตœ์ข… ์‚ฌ์šฉ์ž๊ฐ€ ์†Œ์œ ํ•˜์ง€ ์•Š์€ IT์ธํ”„๋ผ์—์„œ ์ƒ์„ฑ๋˜๋Š” ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ Alibaba Cloud, AWS, GCP, IBM Cloud, Microsft Azure ๋“ฑ์ด ์žˆ๋‹ค Hybrid cloud ๋‹จ์ผ ITํ™˜๊ฒฝ ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ์ด ์—ฐ๊ฒฐ๋œ ํ˜•ํƒœ ์—…์ฒด๋ณ„ ํด๋ผ์šฐ๋“œ ์‹œ์žฅ GCP, Azure, AWS ํด๋ผ์šฐ๋“œ ๊ด€๋ จ ์ง๊ตฐ ํด๋ผ์šฐ๋“œ ์—”์ง€๋‹ˆ์–ด ํด๋ผ์šฐ๋“œ ์‹œ์Šคํ…œ ์—”์ง€๋‹ˆ์–ด ํด๋ผ์šฐ๋“œ ์ธํ”„๋ผ ๋ณด์•ˆ ๋‹ด๋‹น์ž ๋ฐ๋ธŒ์˜ต์Šค ํด๋ผ์šฐ๋“œ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž
new ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฐ MSA ํŠน๊ฐ• 3์ผ์ฐจ : ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ ๊ตฌ์ถ• ์‹ค์Šต (ELK), kubernetes
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ ๊ตฌ์ถ• ์‹ค์Šต (ELK) ELK๋ž€ ELK๋Š” Elasticsearch, Logstash ๋ฐ Kibana : ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœ์ ํŠธ ์„ธ ๊ฐœ์˜ ๋จธ๋ฆฌ๊ธ€ Elasticserach๋Š” ๊ฒ€์ƒ‰ ๋ฐ ๋ถ„์„ ์—”์ง„ Logstash๋Š” ์—ฌ๋Ÿฌ ์†Œ์Šค์—์„œ ๋™์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜์—ฌ ๋ณ€ํ™˜ํ•œ ํ›„ Elasticsearch ๊ฐ™์€ “stash"๋กœ ์ „์†กํ•˜๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ Kibana๋Š” ์‚ฌ์šฉ์ž๊ฐ€ Elasticsearch์—์„œ ์ฐจํŠธ์™€ ๊ทธ๋ž˜ํ”„๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™” Kibana Elasticsearch์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์›น ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ฐ˜์˜ ์‹œ๊ฐํ™” ํ”Œ๋žซํผ Elasticsearch์— ์žˆ๋Š” ์ธ๋ฑ์Šค์˜ ํŒจํ„ด์„ ์ฐพ์•„์„œ, ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•˜๊ฑฐ๋‚˜, ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค Logstash ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘, ๋ณ€ํ™˜, ์ „์†กํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ, Jruby(JVM ๊ธฐ๋ฐ˜ Ruby)๋กœ ๊ฐœ๋ฐœ๋˜์—ˆ๋‹ค ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ณผ์ •์€ input, filter, out์˜ ์„ธ ๋‹จ๊ณ„๋กœ ๊ตฌ์„ฑ๋œ๋‹ค Docker Compose Docker Compose alias ์„ค์ • 1alias dco="docker-compose" 2... Docker-Compose ํŒŒ์ผ docker-compose.yml version:‘3.2’ // docker-compose file format / ๊ฐ ๋ฒ„์ „ ๋ณ„๋กœ ์ œ๊ณต api๊ฐ€ ๋‹ค๋ฅด๋‹ค services: // container ์„œ๋น„์Šค ๊ทธ๋ฃน ports: // ํฌํŠธ ์ง€์ • Host Port : Container Port depends_on: // ์„œ๋น„์Šค๊ฐ„ ์˜์กด๊ด€๊ณ„ ์„ค์ • ELK ์‹ค์Šต docker-compose ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ ๋ฐ ์‹คํ–‰ docker-compose up docker-compose ์ปจํ…Œ์ด๋„ˆ ์ •์ง€ ๋ฐ ์‚ญ์ œ docker-compose down docker-compose ์ปจํ…Œ์ด๋„ˆ ๋ชฉ๋ก ์กฐํšŒ docker-compose ps docker-compose ์ปจํ…Œ์ด๋„ˆ ๋กœ๊ทธ ์กฐํšŒ docker-compose logs ElasticSearch ํ™•์ธ open http://localhost:9200/_cat/indices Kibana ํ™•์ธ http://localhost:5601/app/kibana container ์ ‘์† docker-compose exec logstash sh ์ฐธ๊ณ  : PoC (Proof of Concept) ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๊ฐ€ ์‹ค์ œ๋กœ ์‹คํ˜„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š”๊ฐ€, ํšจ๊ณผ์™€ ํšจ์šฉ, ๊ธฐ์ˆ ์ ์ธ ๊ด€์ ์—์„œ๋ถ€ํ„ฐ ๊ฒ€์ฆ์„ ํ•˜๋Š” ๊ณผ์ • Kubernetes ์ดํ•ดํ•˜๊ธฐ Kubernetes๊ฐ€ ํ•„์š”ํ•œ ์ด์œ  ๋Œ€๋ถ€๋ถ„์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ : ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋˜๋Š” ๋ช‡๊ฐœ์˜ ์„œ๋ฒ„์— ๋ถ„์‚ฐ๋œ ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰๋˜๋Š” ๊ฑฐ๋Œ€ํ•œ ๋ชจ๋†€๋ฆฌ์Šค ์ด๋Ÿฌํ•œ ์‹œ์Šคํ…œ์€ ๋ฆด๋ฆฌ์ฆˆ ์ฃผ๊ธฐ๊ฐ€ ๋А๋ฆฌ๊ณ  ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž์ฃผ ์ผ์–ด๋‚˜์ง€ ์•Š์Œ ๊ฐœ๋ฐœ์ž๋Š” ์ „์ฒด ๋ฆด๋ฆฌ์ฆˆ ์ฃผ๊ธฐ๊ฐ€ ๋๋‚ ๋•Œ ๋งˆ๋‹ค ์ „์ฒด ์‹œ์Šคํ…œ์„ ํŒจํ‚ค์ง•ํ•˜๊ณ  ์šด์˜ํŒ€์€ ์ด๋ฅผ ๋ฐฐํฌํ•˜๊ณ  ๋ชจ๋‹ˆํ„ฐ๋งํ•œ๋‹ค ์šด์˜ํŒ€์€ ํ•˜๋“œ์›จ์–ด ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด๋ฅผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์„œ๋ฒ„๋กœ ์ง์ ‘ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ•œ๋‹ค ๊ฑฐ๋Œ€ํ•œ ๋ชจ๋†€๋ฆฌ์Šค ๋ ˆ๊ฑฐ์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ ์  MSA๋กœ ๋” ์ž‘์€ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์„ธ๋ถ„ํ™” ๋งˆ์ดํฌ๋กœ ์„œ๋น„์Šค๋Š” ์„œ๋กœ ๋ถ„๋ฆฌ๋ผ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ณ„์ ์œผ๋กœ ๊ฐœ๋ฐœ, ๋ฐฐํฌ, ์—…๋ฐ์ดํŠธ, ํ™•์žฅ ๊ฐ€๋Šฅ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ๊ตฌ์„ฑ์š”์†Œ๊ฐ€ ๋งŽ์•„์ง€๊ณ  ๋ฐ์ดํ„ฐ์„ผํ„ฐ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด์„œ ์ „์ฒด ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑ, ๊ด€๋ฆฌ, ์œ ์ง€ํ•˜๊ธฐ๋Š” ์‰ฝ์ง€ ์•Š์€ ์ผ ๋ฆฌ์†Œ์Šค ํ™œ์šฉ์„ ๋†’์ด๊ณ  ํ•˜๋“œ์›จ์–ด ๋น„์šฉ์„ ๋‚ฎ์ถ”๊ณ  ๊ฐ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ๋ฐฐ์น˜ํ•  ์œ„์น˜๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ์— ๋„ˆ๋ฌด ์–ด๋ ค์›€ ์ˆ˜๋™์œผ๋กœ ๋ถˆ๊ฐ€๋Šฅ ์ด๋Ÿฐ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์ž๋™์œผ๋กœ ์Šค์ผ€์ฅด๋งํ•˜๊ณ  ๊ตฌ์„ฑ, ๊ด€๋ฆฌ, ์žฅ์• ์ฒ˜๋ฆฌ๋ฅผ ํฌํ•จํ•˜๋Š” ์ž๋™ํ™”๊ฐ€ ํ•„์š” => ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๊ฐ€ ํ•„์š”ํ•œ ์ด์œ  ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๋ฐฐํฌ ๋‹จ์  ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋งŽ์•„์ง€๋ฉด ๋ฐฐํฌ ์กฐํ•ฉ์˜ ์ˆ˜ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ„์˜ ์ƒํ˜ธ ์ข…์†์„ฑ ์ˆ˜๊ฐ€ ํ›จ์”ฌ ๋งŽ์•„์ง€๋ฏ€๋กœ ๋ฐฐํฌ ๊ด€๋ จ ๊ฒฐ์ •์ด ์–ด๋ ต๋‹ค ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค์™€ ์‹œ์Šคํ…œ์— ๋ถ„์‚ฐ๋ผ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹คํ–‰ ํ˜ธ์ถœ์„ ๋””๋ฒ„๊น…ํ•˜๊ณ  ์ถ”์ ํ•˜๊ธฐ ์–ด๋ ต๋‹ค Kubernetes ๊ฐœ๋… ๊ตฌ๊ธ€์€ Borg๋ผ๋Š” ์‹œ์Šคํ…œ์„ ๊ฐœ๋ฐœํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ž์™€ ์‹œ์Šคํ…œ ๊ด€๋ฆฌ์ž๊ฐ€ ์ˆ˜์ฒœ ๊ฐœ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์„œ๋น„์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๋Š”๋ฐ ๋„์›€์„ ์ค€๋‹ค ๊ตฌ๊ธ€ 10๋…„๊ฐ„ ๊ฒฝํ—˜์„ ๋ฐ”ํƒ•์œผ๋กœ 2014๋…„์— kubernetes ํ”„๋กœ์ ํŠธ๋ฅผ ์˜คํ”ˆ์†Œ์Šคํ™” ํ•œ๋‹ค ๋ณ„๋ช…์€ k8s์ด๋‹ค ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์“ฐ๋Š” ์ด์œ  ๊ฒฝ๋Ÿ‰, ์ด์‹์„ฑ ๋ฐ ํ”Œ๋žซํผ ๋…๋ฆฝ์„ฑ, ์ตœ์‹ ํ˜• ๊ฐœ๋ฐœ ๋ฐ ์•„ํ‚คํ…์ฒ˜ ์ง€์›, ํ™œ์šฉ๋„ ํ–ฅ Kubernetes ์•„ํ‚คํ…์ฒ˜ ๋งˆ์Šคํ„ฐ ๋…ธ๋“œ : ์ „์ฒด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์‹œ์Šคํ…œ์„ ์ œ์–ดํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ปจํŠธ๋กค ํ”Œ๋ ˆ์ธ์„ ์‹คํ–‰ ์›Œ์ปค ๋…ธ๋“œ : ์‹ค์ œ ๋ฐฐํฌ๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ kubernetes ์‹ค์Šต 1 minikube start kubectl run ntest --image=develo0100/node --port 8080 curl localhost:8080 kubernetes pod ์†Œ๊ฐœ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ๊ฐœ๋ณ„ ์ปจํ…Œ์ด๋„ˆ๋“ค์„ ์ง์ ‘ ๋‹ค๋ฃจ์ง€ ์•Š๊ณ , ํ•จ๊ป˜ ๋ฐฐ์น˜๋œ ๋‹ค์ˆ˜์˜ ์ปจํ…Œ์ด๋„ˆ๋ผ๋Š” ๊ฐœ๋…์„ ์‚ฌ์šฉํ•œ๋‹ค kubernetes ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋™์ž‘ ๋„์ปค ๋ฐ๋ชฌ์ด ์‹คํ–‰ ์ค‘์ธ ๋‹ค๋ฅธ ์›Œ์ปค ๋…ธ๋“œ์—์„œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋กœ ์ ‘๊ทผํ•˜๋ ค๋ฉด ๋„์ปคํ—ˆ๋ธŒ์— ์ด๋ฏธ์ง€๊ฐ€ ์˜ฌ๋ ค์ ธ์žˆ์–ด์•ผ ํ•œ๋‹ค kubectl ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API ์„œ๋ฒ„๋กœ kubernetes ์›Œํฌ๋กœ๋“œ ์šฉ์–ด Daemon set Deployment Job Pod Replica set Replication controller
new 08_connect_DB
๐Ÿƒ Spring
DataSource ์„ค์ • AppCtx.java 1 @Bean(destroyMethod = "close") 2 public DataSource dataSource() { 3 DataSource ds = new DataSource(); 4 ds.setDriverClassName("com.mysql.jdbc.Driver"); 5 ds.setUrl("jdbc:mysql://localhost/spring5fs?"+ 6 "enabledTLSProtocols=TLSv1.2&"+ 7 "useSSL=false&"+ 8 "characterEncoding=utf8"); 9 ds.setUsername("spring5"); 10 ds.setPassword("spring5"); 11 ds.setInitialSize(2); 12 ds.setMaxActive(10); 13 ds.setTestWhileIdle(true); 14 ds.setMinEvictableIdleTimeMillis(60000 * 3); 15 ds.setTimeBetweenEvictionRunsMillis(10 * 1000); 16 return ds; 17 } Query ์‹คํ–‰ JdbcTemplate์„ ์ด์šฉํ•œ select 1jdbcTemplate.query( 2"select * from MEMBER where EMAIL = ?", 3new RowMapper<Member>() { 4 @Override 5 public Member mapRow(ResultSet rs, int rowNum) 6 throws SQLException { 7 Member member = new Member( 8 rs.getString("EMAIL"), 9 rs.getString("PASSWORD"), 10 rs.getString("NAME"), 11 rs.getTimestamp("REGDATE").toLocalDateTime()); 12 member.setId(rs.getLong("ID")); 13 return member; 14 } 15 }, 16 email); PreparedStatementCreater๋ฅผ ์ด์šฉํ•œ update 1jdbcTemplate.update(new PreparedStatementCreator() { 2 @Override 3 public PreparedStatement createPreparedStatement(Connection con) 4 throws SQLException { 5 PreparedStatement pstmt = con.prepareStatement( 6 "insert into MEMBER (EMAIL, PASSWORD, NAME, REGDATE) values (?, ?, ?, ?)"); 7 pstmt.setString(1, member.getEmail()); 8 pstmt.setString(2, member.getPassword()); 9 pstmt.setString(3, member.getName()); 10 pstmt.setTimestamp(4, Timestamp.valueOf(member.getRegisterDateTime())); 11 12 return pstmt; 13 } 14}) java.sql.SQLException: Unable to load class: come.mysql.jdbc.Driver from … ์˜ค๋ฅ˜๋ฅผ ์ž˜ ๋ณด์ž… come.mysql… ์˜คํƒ€๋กœ ์ธํ•œ ๋ฌธ์ œ์˜€๋‹ค java.sql.SQLException: Unable to load authentication plugin ‘caching_sha2_password’. mysql ๋น„๋ฐ€๋ฒˆํ˜ธ ์ธ์ฆ ๋ฐฉ์‹์— ๋”ฐ๋ฅธ ์˜ค๋ฅ˜์ด๋‹ค ํ•ด๊ฒฐ๋ฐฉ๋ฒ• : mysql์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ธ์ฆ๋ฐฉ์‹์„ ๋ฐ”๊พธ์ž 1ALTER USER '์‚ฌ์šฉ์ž'@'localhost' IDENTIFIED WITH mysql_native_password BY '๋น„๋ฐ€๋ฒˆํ˜ธ'; javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) url์— enabledTLSProtocols=TLSv1.2๋ฅผ ์ง€์ •ํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค urlํ˜•์‹๋•Œ๋ฌธ์— ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ์กฐ๊ธˆ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ URL ํ˜•์‹์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค ๊ธฐ์–ตํ•˜์ž jdbc:mysql://localhost/spring5fs?์†์„ฑ1=๊ฐ’1&์†์„ฑ2=๊ฐ’2…" Transaction ์ฒ˜๋ฆฌ Transaction ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์˜ ๋‹จ์œ„ ๋ฐฐ๊ฒฝ ์ฟผ๋ฆฌ ๋‘ ๊ฐœ๋ฅผ ์‹คํ–‰ํ•˜๋Š”๋ฐ ๋งŒ์•ฝ 2๋ฒˆ์งธ ์ฟผ๋ฆฌ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„๋•Œ 1๋ฒˆ์งธ ์ฟผ๋ฆฌ ์‹คํ–‰ ์ด์ „ ์ƒํƒœ๋กœ ๋˜๋Œ๋ฆฌ๋Š” (๋กค๋ฐฑ) ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค ์ด์™€ ๊ฐ™์ด ์ฟผ๋ฆฌ ๋‘ ๊ฐœ๋ฅผ ๋ฌถ์–ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์— Transaction์„ ์ด์šฉํ•œ๋‹ค. rollback ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์ง€๋งŒ, Spring์—์„œ๋Š” @Transactional์„ ์ด์šฉํ•ด ๋” ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. AppCtx.java 1@Bean 2public PlatformTransactionManager transactionManager() { 3 DataSourceTransactionManager tm = new DataSourceTransactionManager(); 4 tm.setDataSource(dataSource()); 5 return tm; 6} ChangePasswordService.java 1@Transactional 2public void changePassword(String email, String oldPwd, String newPwd) { 3 Member member = memberDao.selectByEmail(email); 4 5 if (member == null) 6 throw new MemberNotFoundException(); 7 8 member.changePassword(oldPwd, newPwd); 9 memberDao.update(member); 10} ํŠธ๋žœ์žญ์…˜ ๊ด€๋ จ ๋กœ๊ทธ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ logback.xml 1<?xml version="1.0" encoding="UTF-8"> 2 3<configuration> 4 <appender name="stdout" class="chqos.logback.core.ConsoleAppender"> 5 <encoder> 6 <pattern>%d %5p %c{2} - %m%n</pattern> 7 </encoder> 8 </appender> 9 <root level="INFO"> 10 <appender-ref ref="stdout" /> 11 </root> 12 13 <logger name="org.springframework.jdbc" level="DEBUG" /> 14</configuration> ๋กœ๊ทธ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ๋„ ๋ฐฐ์›Œ๋ณด์•˜๋‹ค. Transaction ์ „ํŒŒ 1public class SomeService { 2 private AnyService anyService; 3 4 @Transactional 5 public void some() { 6 anyService.any(); 7 } 8 9 public void setAnyService(AnyService as) { 10 anyService = as; 11 } 12} 13 14public class AnyService { 15 @Transactional 16 public void any() { ... } 17} some๋ฉ”์†Œ๋“œ๊ฐ€ any๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ–ˆ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ๋Š” ๋ฉ”์†Œ๋“œ ๋‘˜ ๋‹ค @Transactional์ด ๋ถ™์–ด์žˆ์ง€๋งŒ ๋งŒ์•ฝ ๋ถ™์–ด์žˆ์ง€ ์•Š์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ์ด๋ ‡๊ฒŒ ๋ฉ”์†Œ๋“œ ๊ฐ„ ํ˜ธ์ถœ์ด ๋ฐœ์ƒํ•  ๋•Œ ํŠธ๋žœ์žญ์…˜์ด ์œ ์ง€๋˜๋Š” ๊ฒƒ์„ ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒ๋ผ๊ณ  ํ•œ๋‹ค. @Transactional annotation์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ ์ค‘ propagation์ด ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒํƒ€์ž…์„ ์ง€์ •ํ•œ๋‹ค. ๊ธฐ๋ณธ๊ฐ’ : REQUIRED : ํ˜„์žฌ ์ง„ํ–‰์ค‘์ธ ํŠธ๋žœ์žญ์…˜์ด ์กด์žฌํ•˜๋ฉด ํ•ด๋‹น ํŠธ๋žœ์žญ์…˜ ์‚ฌ์šฉ, ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑํ•œ๋‹ค
new 09_spring_MVC
๐Ÿƒ Spring
Spring MVC ์‹œ์ž‘ํ•˜๊ธฐ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ์•ž์—์„œ ๋งŒ๋“ค์—ˆ๋˜ ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ๋Š” ์ข€ ๋‹ค๋ฅธ์ ์ด ์žˆ์—ˆ๋‹ค jar์ด ์•„๋‹Œ war์„ ์‚ฌ์šฉํ•˜๋Š” ๋“ฑ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋งŽ์•˜๋Š”๋ฐ ์ผ์ผ์ด ์ ์ง€๋Š” ์•Š์„ ๊ฒƒ์ด๋‹ค Controller 1@Controller 2public class HelloController { 3 @GetMapping("/hello") 4 public String hello(Model model, 5 @RequestParam(value="name", required=false) String name) { 6 model.addAttribute("greeting", "์•ˆ๋…•ํ•˜์„ธ์š”" + name); 7 return "hello"; 8 } 9} JSP 1<%@ page contentType="text/html; charset=utf-8" %> 2<!DOCTYPE html> 3<html> 4 <head> 5 <title>Hello</title> 6 </head> 7 <body> 8 ์ธ์‚ฌ๋ง : ${greeting} 9 </body> 10</html URL์ ‘์†ํ•ด๋„ ํ•ด๋‹น jspํŒŒ์ผ์ด ๋‚˜์˜ค์ง€ ์•Š๋Š” ๋ฌธ์ œ vscode์—์„œ community server connector๋ผ๋Š” extension์„ ํ†ตํ•ด tomcat์„ ๋„์›Œ์„œ ํ• ๋ ค๊ณ  ํ•œ๋‹ค ํŠน์ • jsp๋ฅผ ๊ฐ์ง€ํ–ˆ๋Š”์ง€, servingํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๋กœ๊ทธ๊ฐ€ ์—†์–ด ๋˜๋Š”๊ฑด์ง€ ์•Œ ์ˆ˜๊ฐ€ ์—†๋‹ค web.xml; lineNumber: 1; columnNumber: 37; A pseudo attribute name is expected. // before <?xml version="1.0" encoding="UTF-8"> // after <?xml version="1.0" encoding="UTF-8"?> ๋ฌผ์Œํ‘œ๋ฅผ ๋นผ๋จน์–ด์„œ ์ƒ๊ธฐ๋Š” ์˜ค๋ฅ˜์ด๋‹ค 404: Not Found 1// before 2registry.jsp("/WEB-INF/view", ".jsp"); 3// after 4registry.jsp("/WEB-INF/view/", ".jsp");
new Spring ๊ฐœ๋… - Bean Lifecycle & Scope
๐Ÿƒ Spring
Bean ๊ฐ์ฒด์˜ Lifecycle Bean ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ ๋˜๋Š” ์†Œ๋ฉธ๋ ๋•Œ ํŠน์ • ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. @PostConstruct, @PreDestroy Annotation ์‚ฌ์šฉ 1// Bean ๊ฐ์ฒด ์ƒ์„ฑ๋  ๋•Œ ์‹คํ–‰ 2@PostConstruct 3public void postConstruct() {...} 4 5// Bean ๊ฐ์ฒด ์†Œ๋ฉธ๋  ๋•Œ ์‹คํ–‰ 6@PreDestroy 7public void preDestroy() {...} InitializingBean, DisposableBean ๊ตฌํ˜„ 1public class Client implements InitializingBean, DisposableBean { 2 // Bean ๊ฐ์ฒด ์ƒ์„ฑ๋  ๋•Œ ์‹คํ–‰ 3 @Override 4 public void afterPropertiesSet() throws Exception {...} 5 6 // Bean ๊ฐ์ฒด ์†Œ๋ฉธ๋  ๋•Œ ์‹คํ–‰ 7 @Override 8 public void destroy() throws Exception {...} 9} @Bean Annotation์—์„œ ์„ค์ • 1@Bean(initMethod = "init", destroyMethod="close") 2public class Client2{ 3 // Bean ๊ฐ์ฒด ์ƒ์„ฑ๋  ๋•Œ ์‹คํ–‰ 4 public void init() {...} 5 // Bean ๊ฐ์ฒด ์†Œ๋ฉธ๋  ๋•Œ ์‹คํ–‰ 6 public void close() {...} 7} Bean ๊ฐ์ฒด์˜ Scope ๊ธฐ๋ณธ์ ์œผ๋กœ Bean ๊ฐ์ฒด๋Š” Singleton scope๋ฅผ ๊ฐ–๋Š”๋‹ค ํ•˜์ง€๋งŒ ์ž„์˜๋กœ Prototype scope๋ฅผ ๊ฐ–๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. 1@Configuration 2public class AppCtx { 3 @Bean 4 @Scope("prototype") 5 public Client client() {} 6}
new Spring - Bean Validation : Annotation์œผ๋กœ Validationํ•˜๊ธฐ
๐Ÿƒ Spring
Bean Validation Annotation์„ ๋‹ฌ์•„์„œ Validation์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฃผ๋กœ jakarta.validation๊ณผ hibernate.validator ๋‘ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. Dependency Diagram ๊ตฌ์กฐ spring-boot-starter-validation -> hibernate-validator -> jakarta.validation-api jakarta.validation์—์„œ ์ง€์›ํ•˜๋Š” annotation Annotation Description @NotNull null์ด ์•„๋‹Œ๊ฐ€ ("", " " => ํ†ต๊ณผ) @NotEmpty null์ด ์•„๋‹ˆ๊ณ , size๊ฐ€ 0์ธ๊ฐ€ (" " => ํ†ต๊ณผ) @NotBlank null์ด ์•„๋‹ˆ๊ณ , trimํ•œ ๊ฒฐ๊ณผ๊ฐ€ empty์ธ๊ฐ€ @Size ๋ฌธ์ž์—ด, ๋ฐฐ์—ด์˜ ๊ธธ์ด๊ฐ€ ํ•ด๋‹น ๋ฒ”์œ„์— ์žˆ๋Š”๊ฐ€ @Min ์ˆซ์ž๊ฐ€ ํ•ด๋‹น ๋ฒ”์œ„์— ์žˆ๋Š”๊ฐ€ @Max ์ˆซ์ž๊ฐ€ ํ•ด๋‹น ๋ฒ”์œ„์— ์žˆ๋Š”๊ฐ€ @Email ์ด๋ฉ”์ผ ํ˜•์‹์— ๋งž๋Š”๊ฐ€ @Pattern Regex(์ •๊ทœ์‹)์— ๋งž๋Š”๊ฐ€ @Past ๊ณผ๊ฑฐ์˜ ๋‚ ์งœ์ธ๊ฐ€ @Future ๋ฏธ๋ž˜์˜ ๋‚ ์งœ์ธ๊ฐ€ @Digits ์ •์ˆ˜, ์†Œ์ˆ˜ ์ž๋ฆฟ์ˆ˜๊ฐ€ ํ•ด๋‹น ๋ฒ”์œ„์— ์žˆ๋Š”๊ฐ€ @DecimalMin, @DecimalMax ์ž๋ฆฟ์ˆ˜๊ฐ€ ํ•ด๋‹น ๋ฒ”์œ„์— ์žˆ๋Š”๊ฐ€ (์†Œ์ˆ˜ ์ดํ•˜ ์ž๋ฆฟ์ˆ˜ ํฌํ•จ) @Positive, @PositiveOrZero, @Negative, @NegativeOrZero hibernate.validator์—์„œ ์ง€์›ํ•˜๋Š” annotation Annotation Description @Range ์ˆซ์ž๊ฐ€ ํ•ด๋‹น ๋ฒ”์œ„์— ์žˆ๋Š”๊ฐ€ (์†Œ์ˆ˜ ์ดํ•˜ ์ž๋ฆฟ์ˆ˜ ํฌํ•จ) @Length ๋ฌธ์ž์—ด, ๋ฐฐ์—ด์˜ ๊ธธ์ด๊ฐ€ ํ•ด๋‹น ๋ฒ”์œ„์— ์žˆ๋Š”๊ฐ€ @URL URL ํ˜•์‹์— ๋งž๋Š”๊ฐ€ ์–ธ๊ธ‰ํ•œ Annotation๋ง๊ณ  ๋‹ค๋ฅธ Annotation๋„ ์žˆ๋‹ค. Rest Controller์—์„œ ์‚ฌ์šฉ Controller 1public ResponseEntity<Customer> postCustomer(@RequestBody @Valid CustomerDTO customerDTO) {...} @Valid Annotation์„ ๋ถ™์—ฌ์„œ CustomerDTO ๊ฐ์ฒด์— ๋Œ€ํ•œ Validation์„ ์ˆ˜ํ–‰ํ•œ๋‹ค @Valid Annotation์„ ๋ถ™์ด๋Š” ๊ฒƒ์„ ๊นœ๋นกํ•˜์ง€ ๋ง์ž ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์œ„ ์ฝ”๋“œ์˜ Validation์—์„œ ์‹คํŒจํ•˜๋ฉด, MethodArgumentNotValidException์ด ๋ฐœ์ƒํ•œ๋‹ค ํ•ด๋‹น ์˜ˆ์™ธ๋Š” ํ•„๋“œ๋ณ„ ๋ชจ๋“  ์—๋Ÿฌ๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์—„์ฒญ ๊ธธ๊ธฐ ๋•Œ๋ฌธ์—, ๋ณดํ†ต ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ํ•„์š”ํ•œ ์ •๋ณด๋งŒ ์ถ”์ถœํ•ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค 1processValidationErrors(MethodArgumentNotValidException e) { 2 List<String> errors = e.getBindingResult().getFieldErrors().stream() 3 .map(error -> error.getField() + ": " + error.getDefaultMessage()) 4 .collect(Collectors.toList()); 5 return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); 6} ์ˆ˜๋™ Validation Controller์—์„œ Validation์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ, ์ˆ˜๋™์œผ๋กœ Validation์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค ์ด๋•Œ, Validator ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…๋ฐ›์•„์„œ ์‚ฌ์šฉํ•œ๋‹ค 1import jakarta.validation.Validator; 2... 3@Autowired 4private Validator validator; 5... 6var violations = validator.validate(voucher); 7if (!violations.isEmpty()) 8 throw new IllegalArgumentException(violations.stream().findFirst().get().getMessage()); ์ฝ”๋“œ์—์„œ๋Š” voucher ๊ฐ์ฒด์— ๋Œ€ํ•œ Validation์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๊ฐ€ ์žˆ๋‹ค๋ฉด IllegalArgumentException์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค
new ๋ฐฑ์ค€ - 2502 : ๋–ก ๋จน๋Š” ํ˜ธ๋ž‘์ด (S1)
๐Ÿง  Algorithm
1D, K = map(int, input().split()) 2L = [(1, 0), (0, 1)] 3 4for i in range(2, D): 5 L.append((L[i-2][0]+L[i-1][0], L[i-2][1]+L[i-1][1])) 6 7A = 1 8B = 2 9 10while True: 11 if A*L[D-1][0] + B*L[D-1][1] == K: 12 break 13 14 if A+1 == B: 15 B += 1 16 A = 1 17 else: 18 A += 1 19 20print (A,'\n',B, sep='') ํ•ด๊ฒฐ๋ฐฉ๋ฒ• N๋ฒˆ์งธ๋‚  ๋–ก ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ์ฒซ์งธ๋‚  ๋–ก, ๋‘˜์งธ๋‚  ๋–ก์„ ๊ฐ๊ฐ ๋ช‡๋ฒˆ ๋”ํ•ด์•ผํ•˜๋Š”์ง€ ๋ฆฌ์ŠคํŠธ์— ๊ตฌํ•œ๋‹ค ์ฒซ์งธ, ๋‘˜์งธ ๋‚  ๋–ก์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๋„ฃ์–ด๋ณด๋ฉด์„œ ๋ธŒ๋ฃจํŠธ ํฌ์Šค๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค
new ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค - ์ˆซ์ž ์นด๋“œ ๋‚˜๋ˆ„๊ธฐ (L2)
๐Ÿง  Algorithm
์ฒซ๋ฒˆ์งธ ํ†ต๊ณผํ•œ ํ’€์ด 1import math 2 3def gcd(a, b): 4 while b > 0: 5 a, b = b, a%b 6 return a 7 8def gcdOfArr(l): 9 result = l[0] 10 for i in range(1, len(l)): 11 result = gcd(result, l[i]) 12 return result 13 14def solution(arrayA, arrayB): 15 a1 = gcdOfArr(arrayA) 16 for i in arrayB: 17 if i % a1 == 0: 18 a1 = 0 19 break 20 a2 = gcdOfArr(arrayB) 21 for i in arrayA: 22 if i % a2 == 0: 23 a2 = 0 24 break 25 return max(a1, a2) ๊ฐœ์„ ํ•œ ํ’€์ด 1import math 2from functools import reduce 3 4def gcd(a, b): 5 while b > 0: 6 a, b = b, a%b 7 return a 8 9def solution(arrayA, arrayB): 10 a1 = reduce(gcd, arrayA) 11 a1 = 0 if any(i % a1 == 0 for i in arrayB) else a1 12 a2 = reduce(gcd, arrayB) 13 a2 = 0 if any(i % a2 == 0 for i in arrayA) else a2 14 return max(a1, a2) ๋ฌธ์ œ ์ฒ ์ˆ˜๊ฐ€ ๊ฐ€์ง„ ์ˆซ์ž์˜ ๋ฐฐ์—ด arrayA, ์˜ํฌ๊ฐ€ ๊ฐ€์ง„ ์ˆซ์ž์˜ ๋ฐฐ์—ด arrayB๊ฐ€ ์ฃผ์–ด์ง„๋‹ค ์ฒ ์ˆ˜๊ฐ€ ๊ฐ€์ง„ ์นด๋“œ๋“ค์˜ ๋ชจ๋“  ์ˆซ์ž๋ฅผ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๊ณ , ์˜ํฌ๊ฐ€ ๊ฐ€์ง„ ์ˆซ์ž๋Š” ํ•˜๋‚˜๋„ ๋‚˜๋ˆŒ ์ˆ˜ ์—†๋Š” ์–‘์˜ ์ •์ˆ˜ a ์˜ํฌ๊ฐ€ ๊ฐ€์ง„ ์นด๋“œ๋“ค์˜ ๋ชจ๋“  ์ˆซ์ž๋ฅผ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๊ณ , ์ฒ ์ˆ˜๊ฐ€ ๊ฐ€์ง„ ์ˆซ์ž๋Š” ํ•˜๋‚˜๋„ ๋‚˜๋ˆŒ ์ˆ˜ ์—†๋Š” ์–‘์˜ ์ •์ˆ˜ a ๊ฐ€์žฅ ํฐ ์–‘์˜ ์ •์ˆ˜ a๋ฅผ ๊ตฌํ•˜๋ผ, ์—†๋‹ค๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•˜๋ผ TC input [14, 35, 119] ouput 7 ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์—์„œ ์ง€์›ํ•˜๋Š” ํŒŒ์ด์ฌ์ด 3.8์ด๋ผ์„œ ๋‚ด์žฅํ•จ์ˆ˜ math.gcd(3.9๋ถ€ํ„ฐ ์ง€์›)๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ–ˆ๋‹ค ์œ ํด๋ฆฌ๋“œ ํ˜ธ์ œ๋ฒ• ๊ธฐ์–ต์ด ๋‚˜์ง€ ์•Š์•„์„œ ์•ฝ๊ฐ„์˜ ๊ตฌ๊ธ€๋ง์„ ํ†ตํ•ด ํ•ด๊ฒฐํ•˜์˜€๋‹ค reduce์™€ anyํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ์˜ ๊ธธ์ด๋ฅผ ๋Œ€ํญ ๊ฐ์†Œ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์—ˆ๋‹ค, ์ž์ฃผ ํ™œ์šฉํ•˜์ž
new Express&React ํ”„๋กœ์ ํŠธ์— Recaptcha v3 ์ ์šฉํ•˜๊ธฐ
๐ŸŒ Javascript
์ƒํ™ฉ ์‚ฌ์ด๋“œ ํ”„๋กœ์ ํŠธ “์•Œ๋ก"์„ ๊ฐœ๋ฐœํ•˜๋˜ ์ค‘, ์‚ฌ์šฉ์ž๊ฐ€ ์•…์˜์ ์ธ ๋ชฉ์ ์œผ๋กœ ๋ฐ˜๋ณต์ ์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ๋ง‰์„๊นŒ ๊ณ ๋ฏผํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์กฐ์‚ฌ๋ฅผ ํ†ตํ•ด Google์—์„œ ์ œ๊ณต๋˜๋Š” Recaptcha๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์†์‰ฝ๊ฒŒ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ณต๊ฒฉ์ž์˜ ์ž…์žฅ์—์„œ ์ƒ๊ฐํ–ˆ์„ ๋•Œ, ์ง€๊ธˆ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์žฅ ์ทจ์•ฝํ•œ ๋ถ€๋ถ„์€ ํšŒ์›๊ฐ€์ž…์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ํšŒ์›๊ฐ€์ž…์€ ํšŒ์›์ด ์•„๋‹Œ ์ž๊ฐ€, ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ทœ์น™๋งŒ ๋งŒ์กฑํ•œ๋‹ค๋ฉด ๋ฐ˜๋ณต์ ์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๊ณ , ์ด๋Š” DB์— ๋ฐ”๋กœ ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ํšŒ์›๊ฐ€์ž… ๋ถ€๋ถ„์— Recaptcha๋ฅผ ์ ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค. Recaptcha๋ž€? Recaptcha๋Š” ๊ตฌ๊ธ€์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฌด๋ฃŒ ๋ณด์•ˆ ์„œ๋น„์Šค๋กœ, ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๋ด‡์ด ์•„๋‹˜์„ ์ฆ๋ช…ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์ง€์› ์ข…๋ฃŒ๋œ v1์„ ์ œ์™ธํ•˜๋ฉด v2, v3 ๋‘ ๊ฐ€์ง€ ๋ฒ„์ „์ด ์žˆ๋‹ค. v2๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ‘๋‚˜๋Š” ๋กœ๋ด‡์ด ์•„๋‹™๋‹ˆ๋‹ค’๋ฅผ ํด๋ฆญํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ธ์ฆ์ด ์™„๋ฃŒ๋œ๋‹ค. v3๋Š” ์‚ฌ์šฉ์ž์™€ ์ƒํ˜ธ์ž‘์šฉ ์—†์ด ์ž๋™์œผ๋กœ ์ธ์ฆ์ด ์™„๋ฃŒ๋œ๋‹ค. ํ•„์ž๋Š” ์‚ฌ์šฉ์ž์˜ ๊ฒฝํ—˜๊ณผ ์ด๋ฅผ ํ…Œ์ŠคํŠธํ•  ๋‚˜์˜ ๊ณ ์ƒ์„ ๋œ๊ธฐ ์œ„ํ•ด v3๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค. v3์˜ ์ž‘๋™ ๋ฐฉ์‹ ์‚ฌ์šฉ์ž์˜ ๋งˆ์šฐ์Šค ํด๋ฆญ, ํ‚ค๋ณด๋“œ ์ž…๋ ฅ, ์Šคํฌ๋กค, ์š”์ฒญ ํŒจํ„ด ๋“ฑ์„ ๋ถ„์„ํ•˜์—ฌ ์ ์ˆ˜๋ฅผ ๋งค๊ธด๋‹ค. ์ ์ˆ˜๋Š” 0.0 ~ 1.0 ์‚ฌ์ด์˜ ๊ฐ’์œผ๋กœ, 0.0์€ ๋กœ๋ด‡, 1.0์€ ์‚ฌ๋žŒ์„ ์˜๋ฏธํ•œ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” Recaptcha๊ฐ€ ํ‰๊ฐ€ํ•œ ์ ์ˆ˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์š”์ฒญ์„ ๋ฐ›์•„๋“ค์ผ์ง€ ๋ง์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ์ƒ ์‹œ๋‚˜๋ฆฌ์˜ค ์‚ฌ์šฉ์ž๊ฐ€ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ์ ‘์†ํ•œ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋‹จ์—์„œ Recaptcha ํ‚ค๋ฅผ Recaptcha ํ† ํฐ์„ ๋ฐ›์•„์˜จ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ํšŒ์›๊ฐ€์ž… ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ, Recaptcha ํ† ํฐ์„ ํ•จ๊ป˜ ์ „๋‹ฌํ•œ๋‹ค. ์„œ๋ฒ„์—์„œ Recaptcha ํ† ํฐ์„ ๊ฒ€์ฆํ•˜๊ณ , ์ ์ˆ˜๊ฐ€ 0.5๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด ์š”์ฒญ์„ ๊ฑฐ๋ถ€ํ•œ๋‹ค. ์ ์šฉ ์‚ฌ์ „ ์„ค์ • https://www.google.com/recaptcha/์— ์ ‘์†ํ•˜์—ฌ ๋„๋ฉ”์ธ์„ ๋“ฑ๋กํ•˜๊ณ  ํ‚ค๋ฅผ ๋ฐ›๋Š”๋‹ค. ์ž์„ธํ•œ ๊ณผ์ •์€ ๋‹ค๋ฅธ ๋ธ”๋กœ๊ทธ์—๋„ ์ž˜ ์„ค๋ช…๋˜์–ด ์žˆ์–ด์„œ ์ƒ๋žตํ•œ๋‹ค. Server (Express) user-service.ts 1// ์„œ๋น„์Šค ๋ ˆ์ด์–ด์— ์ถ”๊ฐ€ํ•œ Recaptcha ๊ฒ€์ฆ ํ•จ์ˆ˜ 2static async verifyRecaptcha(token: string): Promise<void> { 3 // Recaptcha ๊ฒ€์ฆ 4 const response = await fetch( 5 // ํ‚ค๋Š” Recaptcha ์‚ฌ์ดํŠธ์—์„œ ๋ฐ›์€ ๊ฒƒ์ด๋ฉฐ, ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌ 6 `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${token}`, 7 { 8 method: "POST", 9 } 10 ); 11 // ๊ฒฐ๊ณผ๋ฅผ JSON์œผ๋กœ ํŒŒ์‹ฑ 12 const verificationReuslt = await response.json(); 13 14 // ์ ์ˆ˜๊ฐ€ 0.5๋ณด๋‹ค ๋‚ฎ์œผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋˜์ง 15 if (verificationReuslt.score <= 0.5) { 16 throw new RecaptchaScoreTooLowError(); 17 } 18 19 // ์„ฑ๊ณต ์—ฌ๋ถ€๊ฐ€ false์ด๋ฉด ์˜ˆ์™ธ๋ฅผ ๋˜์ง (ํ† ํฐ์ด ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ) 20 if (!verificationReuslt.success) { 21 throw new RecaptchaTokenInvalidError(); 22 } 23} user-router.ts 1// ์ปจํŠธ๋กค๋Ÿฌ ๋ถ€๋ถ„์—์„œ ๋ถ€๋ถ„์—์„œ Recaptcha ๊ฒ€์ฆ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ, ๋ฐœ์ƒ์‹œํ‚จ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌ 2try { 3 await UserService.verifyRecaptcha(recaptchaToken); 4 await UserService.createUser(username, password); 5 res.status(201).send("User created successfully"); 6} catch (err: any) { 7 // Recaptcha ์ ์ˆ˜๊ฐ€ ๋‚ฎ์€ ๊ฒฝ์šฐ -> 403 Forbidden 8 if (err instanceof RecaptchaScoreTooLowError) { 9 res.status(403).send(err.message); 10 // Recaptcha ํ† ํฐ์ด ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ -> 400 Bad Request 11 } else if (err instanceof RecaptchaTokenInvalidError) { 12 res.status(400).send(err.message); 13 } else if (err instanceof UserAlreadyExistsError) { 14 res.status(409).send(err.message); 15 } else { 16 console.error(err); 17 res.status(500).send(err.message); 18 } 19} Client (React) App.tsx 1import { GoogleReCaptchaProvider } from "react-google-recaptcha-v3"; 2 3return ( 4 // ์ตœ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์— GoogleReCaptchaProvider๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Recaptcha ํ‚ค๋ฅผ ์ „๋‹ฌ 5 <GoogleReCaptchaProvider 6 reCaptchaKey={process.env.REACT_APP_RECAPTCHA_SITE_KEY || ""} 7 > 8 <Router> 9 {/* ... */} 10 </Router> 11 </GoogleReCaptchaProvider> 12); SignupPage.tsx 1import { useGoogleReCaptcha } from "react-google-recaptcha-v3"; 2 3const SignupPage: React.FC = () => { 4 // useGoogleReCaptcha ํ›…์„ ์‚ฌ์šฉํ•˜์—ฌ Recaptcha ํ† ํฐ์„ ๋ฐ›์•„์˜ด 5 const { executeRecaptcha } = useGoogleReCaptcha(); 6 7 const handleSignup = async () => { 8 // Recaptcha ํ† ํฐ์„ ๋ฐ›์•„์˜ค๊ธฐ๋„ ์ „์— ์‚ฌ์šฉ์ž๊ฐ€ ํšŒ์›๊ฐ€์ž…์„ ์‹œ๋„ํ•˜๋Š” ๊ฒฝ์šฐ 9 if (!executeRecaptcha) { 10 console.log("Execute recaptcha not yet available"); 11 return; 12 } 13 // Recaptcha ํ† ํฐ์„ ๋ฐ›์•„์˜ด (signup์€ action์„ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ ๋ฌธ์ž์—ด) 14 const recaptchaToken = await executeRecaptcha("signup"); 15 16 if (password !== confirmPassword) { 17 alert("๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); 18 return; 19 } 20 21 try { 22 const response = await api.post<SignupResponse>("/users/signup", { 23 username, 24 password, 25 // ์„œ๋ฒ„๋กœ Recaptcha ํ† ํฐ์„ ์ „๋‹ฌ 26 recaptchaToken, 27 }); 28 } catch() { 29 // ... 30 } 31 }; 32}; ๊ฒฐ๊ณผ ๊ด€๋ฆฌ์ž ์ฝ˜์†”์„ ํ†ตํ•ด Recaptcha๋ฅผ ํ†ตํ•ด ๊ฒ€์ฆ๋œ ์š”์ฒญ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
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 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 Github Actions์—์„œ pytest ์‹คํ–‰ํ•˜๊ธฐ
๐Ÿ Python
๋ฐฐ๊ฒฝ ํ…Œ์ปค ๋ถ€ํŠธ์บ ํ”„์—์„œ ํŒ€ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ ์ค‘์ด๋‹ค. ํ˜„์žฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋Œ€์ƒ์œผ๋กœ Unit Test๊ฐ€ ํ•„์š”ํ•˜๋‹ค. Unit Test ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ , Github Actions๋ฅผ ์ด์šฉํ•˜์—ฌ ์ž๋™์œผ๋กœ ํ…Œ์ŠคํŠธ๊ฐ€ ์ˆ˜ํ–‰๋˜๋„๋ก ์„ค์ •ํ•˜๊ณ ์ž ํ•œ๋‹ค. run-pytest.yml 1name: Run pytest 2 3# main ๋˜๋Š” dev ๋ธŒ๋žœ์น˜์— pull request๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์‹คํ–‰ 4on: 5 pull_request: 6 branches: 7 - main 8 - dev 9 10jobs: 11 test: 12 runs-on: ubuntu-latest 13 14 steps: 15 - name: Checkout code 16 uses: actions/checkout@v2 17 18 - name: Set up Python 19 uses: actions/setup-python@v2 20 with: 21 python-version: '3.12' 22 23 - name: Install dependencies 24 run: | 25 python -m pip install --upgrade pip 26 pip install -r requirements.txt 27 28 - name: Run tests 29 run: pytest . ๊ฒฐ๊ณผ Run pytest . ============================= test session starts ============================== platform linux -- Python 3.12.4, pytest-8.2.2, pluggy-1.5.0 rootdir: /home/runner/work/Backend/Backend plugins: anyio-4.4.0 collected 13 items app/tests/test_crud_chatroom.py ... [ 23%] app/tests/test_crud_mentor.py ... [ 46%] app/tests/test_crud_prescription.py ... [ 69%] app/tests/test_crud_user.py .... [100%] ============================== 13 passed in 0.58s ============================== ์ƒ๊ฐ๋ณด๋‹ค ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ 100% ์ฐ๊ณ , CD๊นŒ์ง€ ๊ตฌํ˜„ํ•˜๋ฉด ๋”ํ•  ๋‚˜์œ„ ์—†์„ ๊ฒƒ ๊ฐ™๋‹ค.
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 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 230315 ๊ธฐํ”„๋žฉ Design Thinking ๋ฐฉ๋ฒ•๋ก  - ๊น€์žฌ์ • ๊ต์ˆ˜๋‹˜
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
๋””์ž์ธ ์”ฝํ‚น์ด๋ž€ ๊ณต๊ฐ์˜ ๊ณผ์ •์„ ํ†ตํ•ด ๋ฌธ์ œ์ ์„ ์ฐพ์•„๋‚ด๊ณ , ์•„์ด๋””์–ด๋ฅผ ๋ฐœ์‚ฐํ•˜๊ณ , ํ”„๋กœํ† ํƒ€์ž…์„ ๋งŒ๋“ค์–ด ๊ฒ€์ฆ ๊ณผ์ •์„ ๊ฑฐ์น˜๋Š”, ๋ฐ˜๋ณต์  ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•œ ๋ฐฉ๋ฒ•๋ก  ๋ฐ ์‚ฌ๊ณ ๋ฐฉ์‹ ๋””์ž์ธ ์”ฝํ‚น ํ”„๋กœ์„ธ์Šค ๊ณต๊ฐ - ๋ฌธ์ œ ์ •์˜ - ์•„์ด๋””์–ด ๋„์ถœ - ํ”„๋กœํ† ํƒ€์ดํ•‘ - ํ…Œ์ŠคํŒ… 1. ๊ณต๊ฐ ๊ณต๊ฐ ํ”„๋กœ์„ธ์Šค ๋ฉด๋‹ดํ•˜๊ธฐ ๊ด€์ฐฐํ•˜๊ธฐ ๊ฒฝํ—˜ํ•˜๊ธฐ ๋ฉด๋‹ด์ง€ ์ค€๋น„ํ•˜๊ธฐ ์ˆœ์ฐจ์  ๊ฒฝํ—˜ ์งˆ๋ฌธ : ์–ด๋–ค ์ˆœ์„œ๋กœ ํ–‰๋™ํ•˜๊ณ  ๊ฒฝํ—˜ํ•˜๋Š”์ง€ ๋ฌผ์–ด๋ณด์ž ๊ฐ์ • ์งˆ๋ฌธ ์ด์œ  ์งˆ๋ฌธ : ํ–‰๋™ ๋˜๋Š” ๊ฐ์ •์— ๋Œ€ํ•œ ์ด์œ ๋ฅผ ๋ฌผ์–ด๋ณด์ž ๋˜ ์งˆ๋ฌธ : “๋˜…“๋ผ๋Š” ์งˆ๋ฌธ์„ ๋งŽ์ด ํ•˜์ž ๊ตฌ์ฒดํ™” ์งˆ๋ฌธ ๊ด€์ฐฐํ•˜๊ธฐ | ๋ชจ๋‹ˆํ„ฐ๋ง ํ˜„์žฅ ์ค‘์‹ฌ ๊ด€์ฐฐ : ์„ธ์ƒ์„ ๋„“๊ณ  ๊นŠ๊ฒŒ ๋ฐ”๋ผ๋ณด๊ธฐ ๊ด€์ฐฐํ•˜๊ธฐ | ์‰๋„์ž‰ ์‚ฌ๋žŒ์˜ ์ฒดํ—˜์ด๋‚˜ ํ–‰๋™์„ ๊ทธ์ž๋ฆฌ์—์„œ ๊ด€์ฐฐํ•˜๊ธฐ ๊ด€์ฐฐํ•˜๊ธฐ | ๋งฅ๋ฝ ์งˆ์˜๋ฒ• ํ˜„์žฅ์—์„œ ๊ด€์ฐฐ ๋ฐ ๋ฉด๋‹ด์„ ํ†ตํ•ด ๋Œ€์ƒ์ž์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ• ๋งฅ๋ฝ ์งˆ์˜๋ฒ•์˜ 4๊ฐ€์ง€ ์›์น™ ๋งฅ๋ฝ : ๋Œ€์ƒ์ž์˜ ์ž‘์—…ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ๋””ํ…Œ์ผ์„ ๊ด€์ฐฐํ•˜๋ผ ํŒŒํŠธ๋„ˆ์‹ญ : ๋Œ€์ƒ์ž๋ฅผ ๊ณต๊ฐํ•˜๋ผ ํ•ด์„ : ์—ฐ๊ตฌ์ž๋Š” ๋Œ€์ƒ์ž์—๊ฒŒ ๋ณธ์ธ์˜ ํ•ด์„์„ ๊ณต์œ ํ•˜๋ผ ํฌ์ปค์Šค : ํ•ต์‹ฌ ๋ชฉํ‘œ ์ฃผ์ œ์—์„œ ๋ฒ—์–ด๋‚˜์ง€ ๋งˆ๋ผ ๋งฅ๋ฝ ์งˆ์˜๋ฒ• ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ค€๋น„ํ•˜๊ธฐ, ๊ธฐ๋กํ•˜๊ธฐ ๋„์ œ๊ด€๊ณ„ ๋ชจ๋ธ (Master-apprentice Model) ๋งˆ์Šคํ„ฐ(๋Œ€์ƒ์ž)๊ฐ€ ํ•ด๋‹น ์—…๋ฌดํ™˜๊ฒฝ์—์„œ ์ž์‹ ์˜ ์ƒ๊ฐ๊ณผ ํ–‰๋™์„ ์†Œ๋ฆฌ๋‚ด์–ด ๋งํ•˜๊ฒŒ ํ•œ๋‹ค ์—ฐ๊ตฌ์ž๋Š” ๊ฒฌ์Šต์ƒ์ด ๋˜์–ด ์ค‘๊ฐ„์ค‘๊ฐ„ ๋ฌผ์–ด๋ณด๋ฉด์„œ ํ•™์Šตํ•œ๋‹ค ์†Œ๋ฆฌ๋‚ด์–ด ์ƒ๊ฐํ•˜๊ธฐ (Think Aloud) ๊ธฐ๋ฒ• ๋ณ‘ํ–‰์‹ : ๊ณผ์—…์„ ํ•˜๋Š” ๊ณผ์ •์—์„œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ด์•ผ๊ธฐ ํ•œ๋‹ค ํšŒ๊ณ ์‹ : ๋‹จ๊ณ„๋ณ„ ๊ณผ์—…์„ ๋๋‚ด๊ณ  ์ด์•ผ๊ธฐํ•œ๋‹ค ๋ณ‘ํ–‰+ํšŒ๊ณ  ํ•˜์ด๋ธŒ๋ฆฌ๋“œ 2. ๋ฌธ์ œ์ •์˜ ํŽ˜๋ฅด์†Œ๋‚˜ ๋งŒ๋“ค๋ฌผ ํŽ˜๋ฅด์†Œ๋‚˜ : ํŠน์ • ์ƒํ™ฉ์—์„œ ์–ด๋–ป๊ฒŒ ํ–‰๋™ํ•˜๊ณ  ๋ฐ˜์‘ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“  ๊ฐ€์ƒ์˜ ์ธ๋ฌผ, ์†”๋ฃจ์…˜์˜ ์ˆ˜ํ˜œ์ž POV ์ •์˜ํ•˜๊ธฐ ํŽ˜๋ฅด์†Œ๋‚˜์˜ ๊ด€์ ์—์„œ 1๊ฐœ์˜ POV๋กœ ์••์ถ•ํ•˜์ž POV(Point of View) ํŽ˜๋ฅด์†Œ๋‚˜๋Š” ๋ˆ„๊ตฌ์ธ๊ฐ€? ํŽ˜๋ฅด์†Œ๋‚˜๊ฐ€ ์›ํ•˜๋Š”๊ฒƒ์€ ๋ฌด์—‡์ธ๊ฐ€? ํŽ˜๋ฅด์†Œ๋‚˜์—๊ฒŒ ๊ทธ๊ฒƒ์ด ์ค‘์š”ํ•œ ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€? HMW ์ •์˜ํ•˜๊ธฐ ๊ตฌ์ฒด์ ์ธ ์•„์ด๋””์–ด๋ฅผ ๋‚ด๊ธฐ ์œ„ํ•œ ๋ธŒ๋ ˆ์ธ์Šคํ† ๋ฐ ๊ณผ์ • POV๋กœ ๋ถ€ํ„ฐ ํŒŒ์ƒ๋˜๋ฉฐ “์ˆ˜ํ–‰ ๊ฐ€๋Šฅํ•œ ๋‹จ์œ„"๋กœ ์ •์˜ ํ˜•์‹ : (์šฐ๋ฆฌ๋Š”) ์–ด๋–ป๊ฒŒ ~~~ ํ• ๊ฒƒ ์ธ๊ฐ€ ๊ณ ๊ฐ์—ฌ์ • ์ง€๋„ 3. ์•„์ด๋””์–ด ๋„์ถœ ๋ธŒ๋ ˆ์ธ์Šคํ† ๋ฐ ์˜ค์ฆˆ๋ณธ์˜ 4์›์น™ ๋น„ํŒ๊ธˆ์ง€ ์ž์œ ๋ถ„๋ฐฉ ์งˆ๋ณด๋‹ค ์–‘ Idea ํŽธ์Šน ์–ดํ”ผ๋‹ˆํ‹ฐ ๋‹ค์ด์–ด๊ทธ๋ž˜๋ฐ (์นœํ™”๋„๋ฒ•) ์ˆ˜์ง‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ• ๋ฐ์ดํ„ฐ์—์„œ ๊ณตํ†ต๋œ ์ด์Šˆ/๋ฌธ์ œ/ํ•„์š”์„ฑ ๋“ฑ์„ ๋„์ถœํ•  ์ˆ˜ ์žˆ์Œ ์š”์•ฝํ•˜์—ฌ ํฌ์ŠคํŠธ์ž‡์— ๊ธฐ๋ก, ์œ ์‚ฌํ•œ ํ…Œ๋งˆ, ํ† ํ”ฝ์œผ๋กœ ๊ทธ๋ฃนํ™” ๋‹ค์–‘ํ•œ ์•„์ด๋””์–ด ๋„์ถœ ๋ฐฉ๋ฒ• ์˜์‚ฌ๊ฒฐ์ • ๊ทธ๋ฆฌ๋“œ (๊ธด๊ธ‰๋„, ์ค‘์š”๋„) 10+10 ๋ฐฉ๋ฒ• (10๊ฐœ์˜ ์•„์ด๋””์–ด, 10๊ฐœ์˜ ์†”๋ฃจ์…˜) ์•„์ด๋””์–ด ํ‰๊ฐ€ ํ…Œ์ด๋ธ” (์ ์ˆ˜ ๋งค๊ธฐ๊ธฐ) ์•„์ด๋””์–ด๋ฅผ ์ปจ์…‰์œผ๋กœ ์—ฎ๊ธฐ 4. Prototype ์Šคํ† ๋ฆฌ๋ณด๋“œ ์Šคํ† ๋ฆฌ๋ณด๋“œ๋Š” ์ œํ’ˆ ์‚ฌ์šฉ์˜ ํ™˜๊ฒฝ, ์ ˆ์ฐจ, ๋‹ˆ์ฆˆ ์ถฉ์กฑ ์š”์†Œ๊ฐ€ ํฌํ•จ๋œ๋‹ค ์Šคํ† ๋ฆฌ๋ณด๋”ฉ ์ ˆ์ฐจ ์Šคํ† ๋ฆฌ๋ผ์ธ ๋งŒ๋“ค๊ธฐ ๋ฉ”์ธ ์„ค์ •์ƒท ๊ทธ๋ฆฌ๊ธฐ ํ•ต์‹ฌ ์•„์ด๋””์–ด์˜ ์ „๋‹ฌ์„ ์œ„ํ•œ ์ ์ ˆํ•œ ์นด๋ฉ”๋ผ ๊ตฌ๋„ ์„ค์ • ๋ฐ ๊ทธ๋ฆฌ๊ธฐ ํ–‰๋™๊ณผ ์›€์ง์ž„ ๊ฐ•์กฐ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์‹œ์—ฐ ํ›„ ํ”ผ๋“œ๋ฐฑ ๋ฐ›๊ณ  ์ˆ˜์ •ํ•˜๊ธฐ
new ์ž๋ฃŒ๊ตฌ์กฐ
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
์ œ 1์žฅ : ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๋ฐฐ์šฐ๊ธฐ ์œ„ํ•œ ์ค€๋น„ (230302) ๋ฐฐ์—ด ๋ฐฐ์—ด(Array): ๋™์ผํ•œ ํƒ€์ž…์˜ ์›์†Œ๋“ค์ด ์—ฐ์†์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ํ• ๋‹น๋˜์–ด ์žˆ๋Š” ๊ธฐ์ดˆ์ ์ธ ์ž๋ฃŒ๊ตฌ์กฐ ์ถ”์ƒ๋ฐ์ดํ„ฐ ํƒ€์ž… ์ถ”์ƒ๋ฐ์ดํ„ฐํƒ€์ž…(ADT:Abstract Data Type) : ๋ฐ์ดํ„ฐ์™€ ๊ทธ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ถ”์ƒ์ ์ธ ์—ฐ์‚ฐ๋“ค๋กœ์จ ๊ตฌ์„ฑ ADT =~ ์ž๋ฐ”์˜ interface, ์ž๋ฃŒ๊ตฌ์กฐ =~ ์ž๋ฐ”์˜ class ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ์ถ”์ƒ๋ฐ์ดํ„ฐํƒ€์ž…์„ ๊ตฌ์ฒด์ ์œผ๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ 1-2 ์ˆ˜ํ–‰์‹œ๊ฐ„์˜ ๋ถ„์„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์„ฑ๋Šฅ: ์ˆ˜ํ–‰์‹œ๊ฐ„์„ ๋‚˜ํƒ€๋‚ด๋Š” **์‹œ๊ฐ„๋ณต์žก๋„(Time Complexity)**์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ˆ˜ํ–‰๋˜๋Š” ๋™์•ˆ ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์˜ ํฌ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” **๊ณต๊ฐ„๋ณต์žก๋„(Space Complexity)**์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ๋ถ„์„ ์‹œ๊ฐ„ ๋ณต์žก๋„ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜(์—ฐ์‚ฐ)์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ์— ์‚ฌ์šฉ๋œ ๊ธฐ๋ณธ์ ์ธ ์—ฐ์‚ฐ ํšŸ์ˆ˜๋ฅผ ์ž…๋ ฅ ํฌ๊ธฐ์˜ ํ•จ์ˆ˜๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๊ธฐ๋ณธ ์—ฐ์‚ฐ(Elementary Operation)์ด๋ž€ ๋ฐ์ดํ„ฐ ๊ฐ„ ํฌ๊ธฐ ๋น„๊ต, ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ ๋ฐ ๊ฐฑ์‹ , ์ˆซ์ž ๊ณ„์‚ฐ ๋“ฑ๊ณผ ๊ฐ™์€ ๋‹จ์ˆœํ•œ ์—ฐ์‚ฐ์„ ์˜๋ฏธ 4๊ฐ€์ง€ ์ข…๋ฅ˜์˜ ๋ถ„์„ ์ตœ์•…๊ฒฝ์šฐ ๋ถ„์„(Worst-case Analysis) : ์ƒํ•œ์„ ์˜ ์˜๋ฏธ ํ‰๊ท ๊ฒฝ์šฐ ๋ถ„์„(Average-case Analysis) ์ตœ์„ ๊ฒฝ์šฐ ๋ถ„์„(Best-case Analysis) : ๊ฐ€์žฅ ๋น ๋ฅธ ์ˆ˜ํ–‰์‹œ๊ฐ„ ์ƒ๊ฐ๋ถ„์„(Amortized Analysis) : ์ด ์—ฐ์‚ฐํšŸ์ˆ˜๋ฅผ ํ•ฉํ•˜๊ณ  ์—ฐ์‚ฐ ํšŸ์ˆ˜๋กœ ๋‚˜๋ˆ„์–ด ์ˆ˜ํ–‰์‹œ๊ฐ„์„ ๋ถ„์„ 1-3 ์ˆ˜ํ–‰์‹œ๊ฐ„์˜ ์ ๊ทผํ‘œ๊ธฐ๋ฒ• O (Big-Oh)-ํ‘œ๊ธฐ๋ฒ• ฮฉ (Big-Omega)-ํ‘œ๊ธฐ๋ฒ• ฮ˜ (Theta)-ํ‘œ๊ธฐ๋ฒ• O (Big-Oh) ํ‘œ๊ธฐ๋ฒ• ๋ชจ๋“  N โ‰ฅ N0์— ๋Œ€ํ•ด์„œ f(N) โ‰ค cg(N)์ด ์„ฑ๋ฆฝํ•˜๋Š” ์–‘์˜ ์ƒ์ˆ˜ c์™€N0๊ฐ€ ์กด์žฌํ•˜๋ฉด, f(N) = O(g(N))์ด๋‹ค. ๋ชจ๋“  N โ‰ฅ N0์— ๋Œ€ํ•ด์„œ f(N) โ‰ค cg(N)์ด ์„ฑ๋ฆฝํ•˜๋Š” ์–‘์˜ ์ƒ์ˆ˜ c์™€ N0๊ฐ€ ์กด์žฌํ•˜๋ฉด, f(N) = O(g(N)) f(N) = O(g(N))์€ N0 ๋ณด๋‹ค ํฐ ๋ชจ๋“  N ๋Œ€ํ•ด์„œ f(N)์ด ์–‘์˜ ์ƒ์ˆ˜๋ฅผ ๊ณฑํ•œ g(N)์— ๋ฏธ์น˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๋œป g(N)์€ f(N)์˜ ์ƒํ•œ(Upper Bound) ์ด๋ผ๊ณ  ํ•œ๋‹ค ฮฉ (Big-Omega) ํ‘œ๊ธฐ๋ฒ• ๋ชจ๋“  N โ‰ฅ N0์— ๋Œ€ํ•ด์„œ f(N) โ‰ฅ cg(N)์ด ์„ฑ๋ฆฝํ•˜๋Š” ์–‘์˜ ์ƒ์ˆ˜ c์™€ N0๊ฐ€ ์กด์žฌํ•˜๋ฉด, f(N) = ฮฉ(g(N)) f(N) = ฮฉ(g(N))์€ ์–‘์˜ ์ƒ์ˆ˜๋ฅผ ๊ณฑํ•œ g(N)์ด f(N)์— ๋ฏธ์น˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๋œป g(N)์„ f(N)์˜ ํ•˜ํ•œ(Lower Bound) ์ด๋ผ๊ณ  ํ•œ๋‹ค ฮ˜ (Theta) ํ‘œ๊ธฐ๋ฒ• ๋ชจ๋“  N โ‰ฅ N0์— ๋Œ€ํ•ด์„œ c1g(N) โ‰ฅ f(N) โ‰ฅ c2g(N)์ด ์„ฑ๋ฆฝํ•˜๋Š” ์–‘์˜ ์ƒ์ˆ˜ c1, c2, N0๊ฐ€ ์กด์žฌํ•˜๋ฉด, f(N) = ฮ˜(g(N)) ฮ˜-ํ‘œ๊ธฐ๋Š” ์ˆ˜ํ–‰์‹œ๊ฐ„์˜ O-ํ‘œ๊ธฐ์™€ ฮฉ-ํ‘œ๊ธฐ๊ฐ€ ๋™์ผํ•œ ๊ฒฝ์šฐ์— ์‚ฌ์šฉ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์˜ O-ํ‘œ๊ธฐ์™€ ์ด๋ฆ„ O(1), O(logN), O(N), O(NlogN), O(N2), O(N3), O(2N) 1-5 ์ˆœํ™˜ (Recursion) ์ˆœํ™˜์œผ๋กœ ๊ตฌํ˜„๋œ ๋ฉ”์†Œ๋“œ์˜ ๊ตฌ์„ฑ์š”์†Œ ๊ธฐ๋ณธ(Base) case : ์Šค์Šค๋กœ๋ฅผ ๋” ์ด์ƒ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๋ถ€๋ถ„ ์ˆœํ™˜ case : ์Šค์Šค๋กœ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ถ„ ๊ผฌ๋ฆฌ ์ˆœํ™˜ (Tail Recursion) ๋ฉ”์†Œ๋“œ์˜ ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์—์„œ ์ˆœํ™˜ (ํ˜ธ์ถœ ํ›„ ๋˜๋Œ์•„ ์™”์„๋•Œ ์ˆ˜ํ–‰ํ•  ์—ฐ์‚ฐ์ด ์—†๋Š” ๊ฒฝ์šฐ) ๊ผฌ๋ฆฌ ์ˆœํ™˜์€ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ํšจ์œจ์ ์ด๋‹ค 1public class TailRecursion { 2 public static int factorial(int n, int fact) { 3 if (n==1) 4 return fact; 5 return factorial( ,); 6 } 7} ์ œ 2์žฅ : ๋ฆฌ์ŠคํŠธ ๋ฆฌ์ŠคํŠธ ์ผ๋ จ์˜ ๋™์ผํ•œ ํƒ€์ž…์˜ ํ•ญ๋ชฉ๋“ค์ด ๋‚˜์—ด๋œ ๊ฒƒ ๋ฐฐ์—ด ๋™์ผํ•œ ํƒ€์ž…์˜ ์›์†Œ๋“ค์ด ์—ฐ์†์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ํ• ๋‹น๋˜์–ด ๊ฐ ํ•ญ๋ชฉ์ด ํ•˜๋‚˜์˜ ์›์†Œ์— ์ €์žฅ๋˜๋Š” ๊ธฐ๋ณธ์ ์ธ ์ž๋ฃŒ๊ตฌ์กฐ ์ ‘๊ทผ : O(1), ์‚ฝ์ž…/์‚ญ์ œ : O(n) ๋ฐฐ์—ด๋กœ ๋ฆฌ์ŠคํŠธ ๊ตฌํ˜„ (ArrList) peek, insert, resize, delete ๋‹จ์ˆœ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Singly Linked List) print, search, insertFront, insertAfter ์ž๊ธฐ์ฐธ์กฐ๋ณ€์ˆ˜ 1public class Node <E> { 2 private Node<E> next; // ์ž๊ธฐ ์ฐธ์กฐ ๋ณ€์ˆ˜ 3 ... 4} ์ˆ˜ํ–‰์‹œ๊ฐ„ search : O(n) insert, delete : O(1), p๊ฐ€ ์•ˆ์ฃผ์–ด์ง€๋ฉด O(n) ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ (Doubly Linked List) head, tail, item insertBefore, insertAfter, delete, ์ˆ˜ํ–‰์‹œ๊ฐ„ ์‚ฝ์ž…/์‚ญ์ œ ์—ฐ์‚ฐ : O(1) ํƒ์ƒ‰ ์—ฐ์‚ฐ : O(n) ์›ํ˜• ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Circular Linked List) ์ˆ˜ํ–‰์‹œ๊ฐ„ ์‚ฝ์ž…/์‚ญ์ œ ์—ฐ์‚ฐ : O(1) ํƒ์ƒ‰ ์—ฐ์‚ฐ : O(n) ์ œ 3์žฅ : ์Šคํƒ๊ณผ ํ ์Šคํƒ ๋ฐฐ์—ด๋กœ ๊ตฌํ˜„ / LinkedList๋กœ ๊ตฌํ˜„ ํ›„์œ„ ํ‘œ๊ธฐ <-> ์ค‘์œ„ ํ‘œ๊ธฐ ์ˆ˜ํ–‰์‹œ๊ฐ„ push, pop : O(1) ๋ฐฐ์—ด ํฌ๊ธฐ์˜ ํ™•๋Œ€/์ถ•์†Œ : O(n) ๋‹จ์ˆœ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ pop, push : O(1) ์ œ 4์žฅ : ํŠธ๋ฆฌ ์šฉ์–ด root, parent, child leaf, sibling, ancesto๋ฆฌ(์กฐ์ƒ), descendant(ํ›„์†) subtree(๋…ธ๋“œ ์ž์‹ ๊ณผ ํ›„์†์œผ๋กœ ๊ตฌ์„ฑ๋œ ํŠธ๋ฆฌ) degree(์ฐจ์ˆ˜ : ์ž์‹ ์ˆ˜) level (๊นŠ์ด์™€ ๋™์ผ, 0 ๋˜๋Š” 1๋ถ€ํ„ฐ ์‹œ์ž‘) height (ํŠธ๋ฆฌ์˜ ์ตœ๋Œ€ level) key (ํƒ์ƒ‰์— ์‚ฌ์šฉ๋˜๋Š” ๋…ธ๋“œ์— ์ €์žฅ๋œ ์ •๋ณด) ์™ผ์ชฝ ์ž์‹-์˜ค๋ฅธ์ชฝ ํ˜•์ œ (Left Child-Right Sibling) ํ‘œํ˜„ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ์ž์‹๊ณผ ์˜ค๋ฅธ์ชฝ ํ˜•์ œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” 2๊ฐœ์˜ ๋ ˆํผ๋Ÿฐ์Šค๋งŒ ์‚ฌ์šฉ ์ด์ง„ ํŠธ๋ฆฌ (Binary Tree) ๊ฐ ๋…ธ๋“œ์˜ ์ž์‹ ์ˆ˜๊ฐ€ 2 ์ดํ•˜์ธ ํŠธ๋ฆฌ ํŠน๋ณ„ํ•œ ํ˜•ํƒœ์˜ ์ด์ง„ํŠธ๋ฆฌ ํฌํ™” ์ด์ง„ ํŠธ๋ฆฌ(Perfect Binary Tree) ๊ฐ ๋‚ด๋ถ€ ๋…ธ๋“œ๊ฐ€ 2๊ฐœ์˜ ์ž์‹์„ ๊ฐ€์ง€๊ณ  ๋ชจ๋“  ์ดํŒŒ๋ฆฌ๊ฐ€ ๊ฐ™์€ ์ธต์— ์žˆ๋Š” ํŠธ๋ฆฌ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ(Complete Binary Tree) ๋งˆ์ง€๋ง‰ ๋ ˆ๋ฒจ์„ ์ œ์™ธํ•œ ๊ฐ ๋ ˆ๋ฒจ์ด ๋…ธ๋“œ๋“ค๋กœ ๊ฝ‰ ์ฐจ์žˆ๊ณ , ๋งˆ์ง€๋ง‰ ๋ ˆ๋ฒจ์—๋Š” ๋…ธ๋“œ๋“ค์ด ์™ผ์ชฝ๋ถ€ํ„ฐ ๋น ์ง์—†์ด ์ฑ„์›Œ์ง„ ํŠธ๋ฆฌ ์ด์ง„ ํŠธ๋ฆฌ์˜ ์†์„ฑ ๋ ˆ๋ฒจ k์— ์žˆ๋Š” ์ตœ๋Œ€ ๋…ธ๋“œ ์ˆ˜ = $2^{k-1}$ ๋†’์ด๊ฐ€ h์ธ ํฌํ™” ์ด์ง„ ํŠธ๋ฆฌ์— ์žˆ๋Š” ๋…ธ๋“œ ์ˆ˜ = $2^{h}-1$ n๊ฐœ์˜ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง„ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ์˜ ๋†’์ด = $log_{2}(n+1)$ ๋†’์ด๊ฐ€ h์ธ ์™„์ „ ์ด์ง„ํŠธ๋ฆฌ์— ์กด์žฌํ•  ์ˆ˜ ์žˆ๋Š” ๋…ธ๋“œ ์ˆ˜ n ๋ฐฐ์—ด์— ์ €์žฅ๋œ ์ด์ง„ ํŠธ๋ฆฌ ํŠธ๋ฆฌ 1A 2โ”œโ”€โ”€ B 3โ”‚ โ”œ-โ”€ D 4โ”‚ โ”‚ โ”œโ”€โ”€ H 5โ”‚ โ”‚ โ””โ”€โ”€ I 6โ”‚ โ””-โ”€ E 7โ”‚ โ”œโ”€โ”€ J 8โ”‚ โ””โ”€โ”€ K 9โ””โ”€โ”€ C 10 โ”œโ”€โ”€ F 11 โ””โ”€โ”€ G ์œ„ ํŠธ๋ฆฌ๋ฅผ ๋ฐฐ์—ด์— ์ €์žฅํ•˜๋ฉด (์ธ๋ฑ์Šค 1๋ถ€ํ„ฐ ์‹œ์ž‘) 1A = [A, B, C, D, E, F, G, H, I, J, K] a[i]์˜ ๋ถ€๋ชจ๋Š” a[i/2], ๋‹จ i>1 a[i]์˜ ์™ผ์ชฝ ์ž์‹์€ a[2i], ๋‹จ 2i <= n a[i]์˜ ์˜ค๋ฅธ์ชฝ ์ž์‹์€ a[2i+1], ๋‹จ 2i+1 <= n ํŽธํ–ฅ(skewed) ์ด์ง„ ํŠธ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๊ฐ€ ์‹ฌํ•˜๋‹ค ์ด์ง„ ํŠธ๋ฆฌ์˜ ์ˆœํšŒ preorder ; root - left - right inorder : left - root - right postorder : left - right - root levelorder : left -> right (from top level) ์ˆ˜ํ–‰ ์‹œ๊ฐ„ O(n) ์‹œ๊ฐ„์ด ์†Œ์š” ์ง‘ํ•ฉ์˜ ํ‘œํ˜„ ๋ฐฐ์—ด index 0 1 2 3 4 5 6 7 8 9 value 4 2 7 7 4 4 2 7 7 4 ์ง‘ํ•ฉ 1 17 2โ”œโ”€โ”€ 2 3โ”‚ โ”œ-โ”€ 1 4โ”‚ โ””-โ”€ 6 5โ”œโ”€โ”€ 8 6โ””โ”€โ”€ 3 ์ง‘ํ•ฉ2 14 2โ”œโ”€โ”€ 0 3โ”œโ”€โ”€ 5 4โ””โ”€โ”€ 9 ์ˆ˜ํ–‰ ์‹œ๊ฐ„ union : O(N) find : O(N) ์ œ 5์žฅ : ํƒ์ƒ‰ ํŠธ๋ฆฌ 5.1 ์ด์ง„ํƒ์ƒ‰ํŠธ๋ฆฌ min ํ•จ์ˆ˜ deleteMin ํ•จ์ˆ˜ delete ํ•จ์ˆ˜ CASE 1 : ์‚ญ์ œํ•  ๋…ธ๋“œ์˜ ๋‘ ์ž์‹์ด ๋ชจ๋‘ null CASE 2 : ์‚ญ์ œํ•  ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ์ž์‹๋งŒ null CASE 3 : ์‚ญ์ œํ•  ๋…ธ๋“œ์˜ ์™ผ์ชฝ ์ž์‹๋งŒ null CASE 4 : ์‚ญ์ œํ•  ๋…ธ๋“œ์˜ ์ž์‹์ด ๋‘˜๋‹ค ์กด์žฌ ์‹œ๊ฐ„ ๋ณต์žก๋„ O($logn$) 5.2 AVL ํŠธ๋ฆฌ AVLํŠธ๋ฆฌ์˜ ์ •์˜ ์ž„์˜์˜ ๋…ธ๋“œ x์— ๋Œ€ํ•ด x์˜ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์™€ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋†’์ด ์ฐจ์ด๊ฐ€ 1์„ ๋„˜์ง€ ์•Š๋Š” ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ AVLํŠธ๋ฆฌ์˜ ํšŒ์ „ ์—ฐ์‚ฐ LL ํšŒ์ „ : ์™ผ์ชฝ์œผ๋กœ ์น˜์šฐ์นœ ๊ฒฝ์šฐ rotateRight(n)๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐ RR ํšŒ์ „ : ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์น˜์šฐ์นœ ๊ฒฝ์šฐ rotateLeft(n)๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐ LR ํšŒ์ „ : rotateLeft(n.left) -> rotateRight(n)๋กœ ํ•ด๊ฒฐ RL ํšŒ์ „ : rotateRight(n.right) -> rotateLeft(n)๋กœ ํ•ด๊ฒฐ 4๊ฐ€์ง€ ํšŒ์ „์˜ ๊ณตํ†ต์  ํšŒ์ „ ํ›„์˜ ํŠธ๋ฆฌ๋“ค์ด ๋ชจ๋‘ ๊ฐ™๋‹ค, ๋ชจ๋‘ O(1) AVLํŠธ๋ฆฌ์˜ ์—ฐ์‚ฐ ์‚ฝ์ž… ์—ฐ์‚ฐ ์ด์ง„ ํŠธ๋ฆฌ์˜ ์‚ฝ์ž…๊ณผ ๋™์ผํ•˜๊ฒŒ ์ƒˆ ๋…ธ๋“œ ์‚ฝ์ž… ์ƒˆ ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ๋ฃจํŠธ๋กœ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋ฉฐ ๋ถˆ๊ท ํ˜•์ด ๋ฐœ์ƒํ•˜๋ฉด ์ ์ ˆํ•˜๊ฒŒ ํšŒ์ „ ์—ฐ์‚ฐ ์ˆ˜ํ–‰ ์‚ญ์ œ ์—ฐ์‚ฐ 5.3 2-3 ํŠธ๋ฆฌ 2-3 ํŠธ๋ฆฌ์˜ ์ •์˜ ์ž„์˜์˜ ๋…ธ๋“œ๊ฐ€ 2๊ฐœ ๋˜๋Š” 3๊ฐœ์˜ ์ž์‹์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ํŠธ๋ฆฌ๋กœ, ๋ชจ๋“  ๋ฆฌํ”„ ๋…ธ๋“œ๊ฐ€ ๊ฐ™์€ ๋ ˆ๋ฒจ์— ์žˆ๋‹ค. 2-3 ํŠธ๋ฆฌ์˜ ์—ฐ์‚ฐ ํƒ์ƒ‰ ์—ฐ์‚ฐ ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ์™€ ๋™์ผํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํƒ์ƒ‰ ๋ถ„๋ฆฌ ์—ฐ์‚ฐ ํ‚ค๋ฅผ ๋ถ€๋ชจ๋กœ ์˜ฌ๋ ค ๋ณด๋ƒ„ ๋ถ€๋ชจ๊ฐ€ 3-๋…ธ๋“œ์ด๋ฉด ๋‹ค์‹œ ๋ถ„๋ฆฌ์—ฐ์‚ฐ ์ˆ˜ํ–‰ ๋ฃจํŠธ์—์„œ ์ผ์–ด๋‚˜๋ฉด ํŠธ๋ฆฌ์˜ ๋†’์ด 1 ์ฆ๊ฐ€ ์‚ฝ์ž… ์—ฐ์‚ฐ ์‚ฝ์ž… ํ›„ ๋ถ„๋ฆฌ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ ์‚ญ์ œ ์—ฐ์‚ฐ ์‚ญ์ œํ•  ๋…ธ๋“œ๊ฐ€ ์ดํŒŒ๋ฆฌ ๋…ธ๋“œ์ด๋ฉด ๊ทธ๋ƒฅ ์‚ญ์ œ ์‚ญ์ œํ•œ ๋…ธ๋“œ๊ฐ€ ์ดํŒŒ๋ฆฌ ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๊ตํ™˜ ํ›„ ์‚ญ์ œ ์ด๋™ ์—ฐ์‚ฐ, ํ†ตํ•ฉ ์—ฐ์‚ฐ ์‚ฌ์šฉ ์ด๋™ ์—ฐ์‚ฐ ๋นˆ ์ž๋ฆฌ๋ฅผ ํ˜•์ œ์™€ ๋ฐ”๊พผ๋‹ค ์ด๋™์—ฐ์‚ฐ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉด ํ†ตํ•ฉ ์—ฐ์‚ฐ ์ˆ˜ํ–‰ ํ†ตํ•ฉ ์—ฐ์‚ฐ ์‚ญ์ œํ•œ ๋…ธ๋“œ์˜ ๋ถ€๋ชจ์™€ ํ˜•์ œ๋ฅผ ํ†ตํ•ฉํ•œ๋‹ค 2-3 ํŠธ๋ฆฌ์˜ ์ˆ˜ํ–‰์‹œ๊ฐ„ ํƒ์ƒ‰, ์‚ฝ์ž…, ์‚ญ์ œ ์—ฐ์‚ฐ -> O($logn$) -> ํŠธ๋ฆฌ์˜ ๋†’์ด์— ๋น„๋ก€ ๋ถ„๋ฆฌ ์—ฐ์‚ฐ, ํ†ตํ•ฉ ์—ฐ์‚ฐ -> O(1) 2-3ํŠธ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ๊ฒฝ์šฐ ๋ชจ๋“  ๋…ธ๋‘๊ฐ€ 2-๋…ธ๋“œ์ธ ๊ฒฝ์šฐ ๋†’์ด : $ log_2(n+1) $ 2-3ํŠธ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ๋‚ฎ์€ ๊ฒฝ์šฐ ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ 3-๋…ธ๋“œ์ธ ๊ฒฝ์šฐ ๋†’์ด : $ log_3(n) $ 5.4 2-3-4 ํŠธ๋ฆฌ 2-3ํŠธ๋ฆฌ๋ฅผ ํ™•์žฅํ•œ 2-3-4 ํŠธ๋ฆฌ๋Š” ๋…ธ๋“œ๊ฐ€ ์ž์‹์„ 4๊ฐœ๊นŒ์ง€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์™„์ „๊ท ํ˜•ํŠธ๋ฆฌ ์ด๋ก ์ ์œผ๋กœ๋Š” 2-3ํŠธ๋ฆฌ์™€ ๋™์ผํ•˜๋‹ค ์‹ค์ œ๋กœ๋Š” ๋” ๋น ๋ฆ„ 5.5 B-ํŠธ๋ฆฌ B-ํŠธ๋ฆฌ์˜ ์ •์˜ ๋‹ค์ˆ˜์˜ ํ‚ค๋ฅผ ๊ฐ€์ง„ ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋˜์–ด ๋‹ค๋ฐฉํ–ฅ ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•œ ๊ท ํ˜„ํŠธ๋ฆฌ B-ํŠธ๋ฆฌ์˜ ์—ฐ์‚ฐ ํƒ์ƒ‰ ์—ฐ์‚ฐ ๋ฃจํŠธ ๋ถ€ํ„ฐ ์‹œ์ž‘ ๊ฐ ๋…ธ๋“œ์—์„œ ์ด์ง„ ํƒ์ƒ‰ ์ˆ˜ํ–‰ ์‚ฝ์ž… ์—ฐ์‚ฐ ์ดํŒŒ๋ฆฌ์— ์ƒˆ ํ‚ค๋ฅผ ์ˆ˜์šฉํ•  ๊ณต๊ฐ„์ด ์žˆ๋‹ค๋ฉด, ์ •๋ ฌ๋œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋„๋ก ์‚ฝ์ž… ์ด๋ฏธ M-1๊ฐœ์˜ ํ‚ค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด, ๋ถ„๋ฆฌ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ ์‚ญ์ œ ์—ฐ์‚ฐ ์‚ญ์ œํ•  ๋…ธ๋“œ๊ฐ€ ์ดํŒŒ๋ฆฌ ๋…ธ๋“œ์ด๋ฉด ๊ทธ๋ƒฅ ์‚ญ์ œ ์‚ญ์ œํ•œ ๋…ธ๋“œ๊ฐ€ ์ดํŒŒ๋ฆฌ ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๊ตํ™˜ ํ›„ ์‚ญ์ œ ์ด๋™ ์—ฐ์‚ฐ, ํ†ตํ•ฉ ์—ฐ์‚ฐ ์‚ฌ์šฉ ์ด๋™ ์—ฐ์‚ฐ ํ‚ค์˜ ์ˆ˜๊ฐ€ M/2-1๋ณด๋‹ค ์ž‘์œผ๋ฉด(underflow) ํ˜•์ œ, ๋ถ€๋ชจ๋…ธ๋“œ๋ฅผ ์ด๋Šฅ ์ด๋™ ์—ฐ์‚ฐ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉด ํ†ตํ•ฉ ์—ฐ์‚ฐ ์ˆ˜ํ–‰ ํ†ตํ•ฉ ์—ฐ์‚ฐ ์‚ญ์ œํ•œ ๋…ธ๋“œ์˜ ๋ถ€๋ชจ์™€ ํ˜•์ œ๋ฅผ ํ†ตํ•ฉํ•œ๋‹ค B-ํŠธ๋ฆฌ์˜ ์ˆ˜ํ–‰์‹œ๊ฐ„ ํƒ์ƒ‰, ์‚ฝ์ž…, ์‚ญ์ œ ์—ฐ์‚ฐ -> O($log_{M/2}n$) -> ํŠธ๋ฆฌ์˜ ๋†’์ด์— ๋น„๋ก€ ์ œ 6์žฅ : ํ•ด์‹œ ํ…Œ์ด๋ธ” ๋Œ€ํ‘œ์ ์ธ ํ•ด์‹œ ํ•จ์ˆ˜ ์ค‘๊ฐ„ ์ œ๊ณฑ ํ•จ์ˆ˜ : ํ‚ค๋ฅผ ์ œ๊ณฑํ•œ ํ›„, ์ ์ ˆํ•œ ํฌ๊ธฐ์˜ ์ค‘๊ฐ„ ๋ถ€๋ถ„์„ ์‚ฌ์šฉ ์ ‘๊ธฐ ํ•จ์ˆ˜ : ํ‚ค๋ฅผ ์—ฌ๋Ÿฌ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆˆ ํ›„, ์ด๋“ค์„ ๋”ํ•œ ๊ฐ’์„ ์‚ฌ์šฉ ์ž๋ฐ”์˜ hashCode() 1private int hash(Key k) { 2 return (k.hashCode() & 0x7fffffff) % M; 3} ํ•ด์‹œ ํ…Œ์ด๋ธ”์˜ ์ €์žฅ ๋ฐฉ์‹ ๊ฐœ๋ฐฉ ์ฃผ์†Œ ๋ฐฉ์‹ : ์ถฉ๋Œ๋œ ํ‚ค๋ฅผ ์ผ์ •ํ•œ ๋ฐฉ์‹์— ๋”ฐ๋ผ ์ฐพ์•„๋‚ธ empty์›์†Œ์— ์ €์žฅ ์„ ํ˜• ์กฐ์‚ฌ, ์ด์ฐจ์กฐ์‚ฌ, ์ด์ค‘ํ•ด์‹ฑ ์„ ํ˜• ์กฐ์‚ฌ : ์ถฉ๋Œ์ด ์ผ์–ด๋‚œ ๊ณณ์œผ๋กœ๋ถ€ํ„ฐ ์ˆœ์ฐจ์ ์œผ๋กœ ํƒ์ƒ‰ 1์ฐจ ๊ตฐ์ง‘ํ™” (ํ‚ค๋“ค์ด ๋ญ‰์ณ์ง€๋Š” ํ˜„์ƒ) ๋ฐœ์ƒ ๊ตฐ์ง‘ํ™”๋Š” ๊ตฐ์ง‘๋œ ํ‚ค๋“ค์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐฉ๋ฌธํ•ด์•ผํ•˜๋Š” ๋ฌธ์ œ์ ์„ ์ผ์œผํ‚จ๋‹ค ์ œ 7์žฅ : ์šฐ์„ ์ˆœ์œ„ ํ ์šฐ์„ ์ˆœ์œ„ ํ (Priority Queue) ๊ฐ€์žฅ ๋†’์€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์ง„ ํ•ญ๋ชฉ์— ์ ‘๊ทผ๊ณผ ์‚ญ์ œ, ์ž„์˜์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์ง„ ํ•ญ๋ชฉ์˜ ์‚ฝ์ž…์„ ์ง€์›ํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ ํž™ (Heap) ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ๋กœ์„œ ๋ถ€๋ชจ์˜ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์ž์‹์˜ ์šฐ์„ ์ˆœ์œ„๋ณด๋‹ค ๋†’์€ ์ž๋ฃŒ๊ตฌ์กฐ ์ตœ์†Œ ํž™, ์ตœ๋Œ€ ํž™ ํž™์˜ ์—ฐ์‚ฐ ์ตœ์†Ÿ๊ฐ’ ์‚ญ์ œ ๋ฃจํŠธ ์‚ญ์ œ ํ›„, ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ๋ฃจํŠธ๋กœ ์ด๋™ downheap ์ˆ˜ํ–‰ : ๋ฃจํŠธ๋ถ€ํ„ฐ ๋น„๊ตํ•˜๋ฉด์„œ ๋‚ด๋ ค๊ฐ ์‚ฝ์ž… ๋งˆ์ง€๋ง‰ ํ•ญ๋ชฉ์˜ ๋‹ค์Œ์— ์‚ฝ์ž… upheap ์ˆ˜ํ–‰ : ๋ฃจํŠธ๋กœ ๋น„๊ตํ•˜๋ฉด์„œ ์˜ฌ๋ผ๊ฐ ์ƒํ–ฅ์‹ ํž™ 1public void createHeap() { 2 for (int i = N/2; i>0; i--) { 3 downheap(i); 4 } 5} O(n) ์ˆ˜ํ–‰ ์‹œ๊ฐ„ ์ ‘๊ทผ, ์‚ฝ์ž…, ์‚ญ์ œ : O(logn) ์ œ 8์žฅ : ์ •๋ ฌ ์„ ํƒ ์ •๋ ฌ (Selection Sort) ํ•ญ์ƒ O(n^2) ์‚ฝ์ž… ์ •๋ ฌ (Insertion Sort) ์ตœ์•… : O(n^2) ์ตœ์„  : O(n) : ์ด๋ฏธ ์ •๋ ฌ๋œ ๊ฒฝ์šฐ ํž™ ์ •๋ ฌ (Heap Sort) ํ•ญ์ƒ : O(nlogn) ํ•ฉ๋ณ‘ ์ •๋ ฌ (Merge Sort) ํ•ญ์ƒ : O(nlogn) Stable Sort : ๊ฐ™์€ ๊ฐ’์˜ ํ‚ค๋ฅผ ๊ฐ€์ง„ ๋ ˆ์ฝ”๋“œ์˜ ์ˆœ์„œ๊ฐ€ ์ •๋ ฌ ํ›„์—๋„ ์œ ์ง€๋˜๋Š” ์ •๋ ฌ ํ€ต ์ •๋ ฌ (Quick Sort) ์ตœ์•… : O(n^2) ์ตœ์„  : O(nlogn) ์„ฑ๋Šฅ ํ–ฅ์ƒ ๋ฐฉ๋ฒ• Median of Three : ์ฒซ๋ฒˆ์งธ, ๋งˆ์ง€๋ง‰, ์ค‘๊ฐ„๊ฐ’ ์ค‘์—์„œ ์ค‘๊ฐ„๊ฐ’์„ ํ”ผ๋ฒ—์œผ๋กœ ์„ ํƒ ์ž…๋ ฅ์ด ์ž‘์€ ํฌ๊ธฐ๊ฐ€ ๋˜์—ˆ์„๋•Œ ์‚ฝ์ž… ์ •๋ ฌ์„ ์‚ฌ์šฉ
new ์›น ๋ณด์•ˆ
๐Ÿซ ํ•™๊ณผ ๊ณต๋ถ€
Web Security Model Web ๋ณด์•ˆ์˜ ๋ชฉํ‘œ Integirty : ๋ฌด๊ฒฐ์„ฑ Confidentiality : ๊ธฐ๋ฐ€์„ฑ HTTP URL https:// www.example.edu :80 /lectures ?lec=80 #slides protocol + hostname + port + path + query + fragment Cookies ์„œ๋ฒ„๊ฐ€ ์›น ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ๋ณด๋‚ด๋Š” ์ •๋ณด ์—ญํ•  : ์„ธ์…˜ ๊ด€๋ฆฌ, ์‚ฌ์šฉ์ž ์„ค์ • ์ €์žฅ, ์‚ฌ์šฉ์ž ์ถ”์  ๋“ฑ 1// ์ฟ ํ‚ค ์„ค์ • 2Set-Cookie: name=value; 3// ์ฟ ํ‚ค ์ „์†ก 4Cookie: name=value; Same Origin Policy (SOP) ๊ฐ™์€ Origin์—์„œ๋งŒ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค Origin scheme://domain:port Domain Relaxation ์„œ๋ธŒ ๋„๋ฉ”์ธ ๊ฐ„์˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ  document.domain์„ ์ˆ˜์ •ํ•˜์—ฌ, ์„œ๋ธŒ ๋„๋ฉ”์ธ ๊ฐ„์˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ  ๊ฐ€๋Šฅ ์˜ˆ์‹œ 1a.domain.com -> domain.com ๊ฐ€๋Šฅ 2a.domain.com -> b.domain.com ๋ถˆ๊ฐ€๋Šฅ 3a.domain.com -> com ๋ถˆ๊ฐ€๋Šฅ ์ทจ์•ฝ์  : ์•…์˜์ ์ธ ์‚ฌ์ดํŠธ๊ฐ€ document.domain์„ ์ˆ˜์ •ํ•˜์—ฌ ์ ‘๊ทผ์„ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์Œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ• : Mozilla Public Suffix List (PSL) ์‚ฌ์šฉ BroadcastChannel API ๊ฐ™์€ origin์˜ ๋‹ค๋ฅธ context ๊ฐ„์˜ ํ†ต์‹  ์‚ฌ์šฉ๋ฒ• 1const bc = new BroadcastChannel('channel'); 2bc.postMessage('message'); 3bc.onmessage = (e) => console.log(e.data); XMLHttpRequest (XHR) ์„œ๋ฒ„์™€ ๋น„๋™๊ธฐ ํ†ต์‹ ์„ ์œ„ํ•œ ๊ฐ์ฒด CORS (Cross-Origin Resource Sharing) ๋‹ค๋ฅธ Origin์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•  ๋•Œ, ์„œ๋ฒ„์—์„œ ํ—ˆ์šฉํ•˜๋Š” ์ •์ฑ… Cookie ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋‚ด๋Š” ์ •๋ณด Cookie Scoping Domain ํ•ด๋‹น ๋„๋ฉ”์ธ์€ Subdomain ๋˜๋Š” Parent Domain์— ๋Œ€ํ•ด์„œ๋งŒ ์ฟ ํ‚ค๋ฅผ ์ „์†ก Path ํ•ด๋‹น ๊ฒฝ๋กœ์˜ ํ•˜์œ„ ๊ฒฝ๋กœ๊นŒ์ง€ ์ฟ ํ‚ค๋ฅผ ์ „์†ก Secure Cookies HTTPS ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•  ๋•Œ๋งŒ ์ฟ ํ‚ค๋ฅผ ์ „์†ก 1Set-Cookie: name=value; Secure HTTPOnly Cookies JavaScript์—์„œ ์ฟ ํ‚ค์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก ํ•จ 1Set-Cookie: name=value; HttpOnly CSRF (Cross Site Request Forgery) ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์—์„œ ์š”์ฒญ์„ ์œ„์กฐํ•˜์—ฌ ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• ๋ฐฐ๊ฒฝ ํŠน์ • ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ๋œ ์ƒํƒœ๋ผ๋ฉด, ์‚ฌ์šฉ์ž๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ฟ ํ‚ค์™€ ํ•จ๊ป˜ ์š”์ฒญ์„ ์ „์†ก cross-site์—์„œ๋„ ์ฟ ํ‚ค์™€ ํ•จ๊ป˜ ์š”์ฒญ์„ ๋ณด๋ƒˆ์„๋•Œ, ์„œ๋ฒ„๊ฐ€ same-site์ธ์ง€ cross-site์ธ์ง€ ํ™•์ธ์ด ๋ถˆ๊ฐ€ํ•œ ๊ฒฝ์šฐ CSRF ๊ณต๊ฒฉ ๊ฐ€๋Šฅ ์˜ˆ์ƒ ์‹œ๋‚˜๋ฆฌ์˜ค ํ”ผํ•ด์ž๊ฐ€ ํ˜„์žฌ ๋กœ๊ทธ์ธ๋œ ์ƒํƒœ๋กœ Malicious Site์— ์ ‘์† Malicious site์—์„œ ํ”ผํ•ด์ž ์˜์ง€์™€ ์ƒ๊ด€์—†์ด ์ฟ ํ‚ค์™€ ํ•จ๊ป˜ ์š”์ฒญ์„ ์ „์†ก GET ์˜ˆ์‹œ ์ฝ”๋“œ 1<img src="http://bank.com/transfer?to=attacker&amount=1000" /> POST ์˜ˆ์‹œ ์ฝ”๋“œ 1<form action="http://bank.com/transfer" method="post"> 2 <input type="hidden" name="to" value="attacker" /> 3 <input type="hidden" name="amount" value="1000" /> 4</form> 5<script> 6 document.forms[0].submit(); 7</script> ๋ฐฉ์–ด Referer Header ์š”์ฒญ์„ ๋ณด๋‚ธ ํŽ˜์ด์ง€์˜ ์ฃผ์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” HTTP header๋ฅผ ํ™•์ธํ•˜์—ฌ, ์š”์ฒญ์„ ๋ณด๋‚ธ ํŽ˜์ด์ง€๊ฐ€ ๊ฐ™์€ ์‚ฌ์ดํŠธ์ธ์ง€ ํ™•์ธ 1Referer: http://www.example.com ํ•œ๊ณ„ ํ•ด๋‹น field๋ฅผ ์ด์šฉํ•ด์„œ ์ ‘์† ๊ธฐ๋ก์„ ํ™•์ธ ๊ฐ€๋Šฅ -> ๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ ๋ฌธ์ œ Same-Site Cookies ์„œ๋ฒ„๊ฐ€ ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•  ๋•Œ, SameSite๋ผ๋Š” ์ฟ ํ‚ค ์†์„ฑ๋ฅผ ์ „์†ก, same-site์ธ์ง€ cross-site์ธ์ง€ ํ™•์ธํ•˜์—ฌ, ์„ค์ •๊ฐ’์— ๋”ฐ๋ผ ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•˜์ง€ ์•Š์Œ ์„ค์ • ๊ฐ’ None (๋ชจ๋“  ์š”์ฒญ์— ์ฟ ํ‚ค ์ „์†ก) Strict (cross-site๋Š” ํ•ญ์ƒ ์ฟ ํ‚ค ์ „์†กํ•˜์ง€ ์•Š์Œ) Lax (cross-site๋Š” GET ์š”์ฒญ์‹œ์—๋งŒ ์ฟ ํ‚ค ์ „์†กํ•˜์ง€ ์•Š์Œ) Secret Token ํŠน์ • origin์˜ ์ฒซ ์š”์ฒญ๋•Œ, ํŠน์ •ํ•œ ํ† ํฐ์„ ์ƒ์„ฑ, ์ดํ›„ ์š”์ฒญ์‹œ ํ•ด๋‹น ํ† ํฐ์„ ํ•จ๊ป˜ ์ „์†กํ•˜์—ฌ, ์š”์ฒญ์ด ๊ฐ™์€ Origin์—์„œ ์˜จ ๊ฒƒ์ธ์ง€ ํ™•์ธ Bypassing with Clickjacking ์‚ฌ์šฉ์ž๊ฐ€ ์˜๋„ํ•˜์ง€ ์•Š์€ ํด๋ฆญ์„ ์œ ๋„ํ•˜์—ฌ, CSRF ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ธฐ๋ฒ• ๋ฐฉ์–ด X-Frame-Options Header (๊ฐ’ : DENY, SAMEORIGIN, ALLOW-FROM uri) ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ iframe์œผ๋กœ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ XSS(Cross Site Scripting) Attack Non-persistent (Reflected) XSS Attack ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅํ•˜์—ฌ, ๊ณต๊ฒฉ์ž๊ฐ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜์—ฌ ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• ์˜ˆ์‹œ query string์„ ์‹คํ–‰ํ•˜๋Š” ํŽ˜์ด์ง€๊ฐ€ ์กด์žฌ (innerHTML) ํ”ผํ•ด์ž๊ฐ€ ํ•ด๋‹น ๋งํฌ๋ฅผ ์‹คํ–‰ => http://www.example.com/search?input=<script>alert(โ€œattackโ€);</script> ํ”ผํ•ด์ž์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ alert๊ฐ€ ์‹คํ–‰๋จ Persistent (Stored) XSS Attack ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ๊ฐ’์„ DB์— ์ €์žฅํ•˜์—ฌ, ๊ณต๊ฒฉ์ž๊ฐ€ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜์—ฌ ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• ์˜ˆ์‹œ ๊ฒŒ์‹œํŒ์— ๊ธ€์„ ์ž‘์„ฑํ•˜๋Š” ํŽ˜์ด์ง€๊ฐ€ ์กด์žฌ ํ”ผํ•ด์ž๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜์—ฌ ๊ธ€์„ ์ž‘์„ฑ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ๊ธ€์„ ์ฝ์„ ๋•Œ, ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋จ XSS๋กœ ๋ฐœ์ƒ ๊ฐ€๋Šฅํ•œ ํ”ผํ•ด Web defacing(์›นํŽ˜์ด์ง€ ๋ณ€์กฐ) Spoofing requests(์‚ฌ์šฉ์ž์˜ ์š”์ฒญ ๋ณ€์กฐ) Stealing information(์ •๋ณด ํƒˆ์ทจ) Self-Propagation XSS Worm XSS ๊ณต๊ฒฉ์„ ํ†ตํ•ด, ์ž๋™์œผ๋กœ ๊ณต๊ฒฉ์„ ์ „ํŒŒํ•˜๋Š” ๊ธฐ๋ฒ• 2๊ฐ€์ง€ ์ ‘๊ทผ DOM Approach 1let jsCode = document.getElementById('worm').innerHTML; Link Approach 1let jsCode = `'<script src="http://www.example.com/worm.js"></script>'`; ๋ฐฉ์–ด ์ž…๋ ฅ๊ฐ’ ํ•„ํ„ฐ๋ง : ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ๊ฐ’์„ ํ•„ํ„ฐ๋งํ•˜์—ฌ, ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค Encoding : ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ๊ฐ’์„ ์ถœ๋ ฅํ•  ๋•Œ, HTML Encodingํ•˜์—ฌ, ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค Content Security Policy (CSP) : ์›นํŽ˜์ด์ง€์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ œํ•œํ•˜์—ฌ, XSS ๊ณต๊ฒฉ์„ ๋ฐฉ์–ดํ•œ๋‹ค ์˜ˆ์‹œ (script ํŒŒ์ผ) 1Content-Security-Policy: script-src 'self' example.com ์˜ˆ์‹œ (inline script) 1Content-Security-Policy: script-src 'nonce-2726c7f26c' 2// allowed script 3`<script nonce=2726c7f26c> ... </script>` 4// not allowed script 5`<script nonce=42eh44jhad> ... </script>` SQL Injection SQL ์ฟผ๋ฆฌ๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ, DB์— ๋Œ€ํ•œ ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ธฐ๋ฒ• ์˜ˆ์‹œ EID์— “EID5002’#“์„ ์‚ฝ์ž… -> PASSWORD ๊ฒ€์ฆ์„ ์šฐ์ฆ 1SELECT NAME, SALERY, SSN 2FROM EMPLOYEE 3WHERE EID='EID5002'#' AND PASSWORD='1234'; curl์„ ์ด์šฉํ•ด์„œ SQL Injection ๊ณต๊ฒฉ 1curl 'www.example.com/getdata.php?EID=a' OR 1=1&PASSWORD=' ๋ฐฉ์–ด Filtering and Encoding data SQL Injection์—์„œ ์“ฐ์ด๋Š” ํŠน์ˆ˜๋ฌธ์ž๋ฅผ Filtering, Encoding 1$mysqli->real_escape_string($input); ํ•œ๊ณ„ ํ•„์š”ํ•œ ๋ฌธ์ž์—ด์„ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Œ Prepared Statements SQL ์ฟผ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•˜์—ฌ, ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ๊ฐ’์„ ์‚ฝ์ž…ํ•˜์ง€ ์•Š๊ณ , ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ 1$stmt = $mysqli->prepare("SELECT NAME, SALARY, SSN FROM EMPLOYEE WHERE EID=? AND PASSWORD=?"); 2// ss means "string string" 3$stmt->bind_param("ss", $EID, $PASSWORD); 4$stmt->execute(); Blind SQL Injection SQL Injection ๊ณต๊ฒฉ์„ ํ†ตํ•ด, DB์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํƒˆ์ทจํ•˜๋Š” ๊ธฐ๋ฒ• Conditional Response 1/* Password์˜ ์ฒซ๋ฒˆ์งธ ๋ฌธ์ž๊ฐ€ 'm'๋ณด๋‹ค ํฐ์ง€ ํ™•์ธ */ 2xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm 3/* Password์˜ ์ฒซ๋ฒˆ์งธ ๋ฌธ์ž๊ฐ€ 't'๋ณด๋‹ค ํฐ์ง€ ํ™•์ธ */ 4xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 't SQL Error - Divide by Zero 1/* Password์˜ ์ฒซ๋ฒˆ์งธ ๋ฌธ์ž๊ฐ€ 'm'๋ณด๋‹ค ํฌ๋ฉด ์˜ค๋ฅ˜ ๋ฐœ์ƒ */ 2xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 3'm') THEN 1/0 ELSE 'a' END FROM Users)='a SQL Error - Cast 1/* Password์˜ ์ฒซ๋ฒˆ์งธ ๋ฌธ์ž๊ฐ€ 'm'๋ณด๋‹ค ํฌ๋ฉด ์˜ค๋ฅ˜ ๋ฐœ์ƒ */ 2CAST((SELECT example_column FROM example_table) AS int) Time Delay 1/* Password์˜ ์ฒซ๋ฒˆ์งธ ๋ฌธ์ž๊ฐ€ 'm'๋ณด๋‹ค ํฌ๋ฉด ๋”œ๋ ˆ์ด ๋ฐœ์ƒ */ 2'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND 3SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'- ShellShock Attack bash ์‰˜์˜ ์ทจ์•ฝ์ ์„ ์ด์šฉํ•˜์—ฌ, ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• Set-UID Programs Set-UID root ๊ถŒํ•œ์„ ๊ฐ€์ง„ ํ”„๋กœ๊ทธ๋žจ์ด systemํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• RUID : Real User ID : ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•œ ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ EUID : Effective User ID : ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๋Š” ๊ถŒํ•œ Set-UID Program : ์‚ฌ์šฉ์ž๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์„ root ๊ถŒํ•œ์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ, RUID์™€ EUID๊ฐ€ ๋‹ค๋ฆ„, Set-UID Program์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ• 1$ sudo chown root vul 2$ sudo chmod 4755 vul 3$ ls -l vul 4-rwsr-xr-x 1 root root 1234 Mar 11 12:00 vul # s๊ฐ€ ์กด์žฌ ์ทจ์•ฝํ•œ C ํ”„๋กœ๊ทธ๋žจ (vul : Set-UID program) 1#include <stdio.h> 2void main() { 3 setuid(geteuid()); // root ๊ถŒํ•œ์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž๋กœ ์„ค์ • 4 system("/bin/ls -l"); // ls -l ๋ช…๋ น์–ด ์‹คํ–‰ 5} ๊ณต๊ฒฉ ๋ช…๋ น์–ด 1$ export foo='() { echo "hello"; }; /bin/sh' 2$ ./vul CGI(Common Gateway Interface) Programs ์›น ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉํ•˜๋Š” CGI ํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ์ทจ์•ฝํ•œ CGI ํ”„๋กœ๊ทธ๋žจ (test.cgi) 1#!/bin/bash 2echo "Content-type: text/plain" 3echo 4echo "Hello, World!" ๊ณต๊ฒฉ ๋ช…๋ น์–ด 1$ curl http://10.0.2.69/cgi-bin/test.cgi 2Hello, World! ๊ณต๊ฒฉ์„ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ์„ค์ • ํŒŒ์ผ์— ํ•˜๋“œ์ฝ”๋”ฉ๋œ db password ํƒˆ์ทจ reverse shell ์‹คํ–‰ Environment Variables & Attacks ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์–ป๋Š” ๋ฐฉ๋ฒ• fork() : ์ž์‹์„ ์ƒ์„ฑ, ์ž์‹์ด ๋ถ€๋ชจ์˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ƒ์† execve() : ์ƒˆ๋กœ์šด ํ”„๋กœ๊ทธ๋žจ์„ ์ž์‹์œผ๋กœ ์‹คํ–‰, ์ƒˆ๋กœ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์„ค์ • Attacks via Dynamic Linker ๋งํฌ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ, ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• ์›๋ฆฌ LD_PRELOAD๋Š” ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ชฉ๋ก์„ ์ €์žฅ ํ•จ์ˆ˜๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด, LD_LIBRARY_PATH์—์„œ ์ฐพ์Œ ๋‘ ๋ณ€์ˆ˜๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ ๋งํฌ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์กฐ์ž‘ ์˜ˆ์‹œ 1$ export LD_PRELOAD=/path/to/malicious.so 2$ ./vul Attacks via Execution Program ์‹คํ–‰ ํ”„๋กœ๊ทธ๋žจ์„ ์กฐ์ž‘ํ•˜์—ฌ, ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• ์˜ˆ์‹œ 1$ export PATH=/path/to/malicious:$PATH 2$ ./vul 3# // root shell ์ทจ๋“ Attacks via Library format string ๋“ฑ์˜ ์ทจ์•ฝ์ ์„ ์ด์šฉํ•˜์—ฌ ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• Attacks via Application Code buffer overflow ๋“ฑ์˜ ์ทจ์•ฝ์ ์„ ์ด์šฉํ•˜์—ฌ ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• Set-UID Approach VS Service Approach Clickjacking Attack ์‚ฌ์šฉ์ž์˜ ์˜๋„์™€ ์ƒ๊ด€์—†์ด ํด๋ฆญ์„ ์œ ๋„ํ•˜์—ฌ, ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• 1<iframe id="top" src="http://www.attack.com" style="opacity: 0"></iframe> 2<iframe id="bottom" src="http://www.example.com>" style="opacity: 1"></iframe> ๋ฐฉ์–ด Client-side (Framekiller and Framebuster) javascript๋ฅผ ์ด์šฉํ•˜์—ฌ, ํ•ด๋‹น ํŽ˜์ด์ง€๊ฐ€ iframe์œผ๋กœ ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ 1if (top != self) 2if (top.location != self.location) 3... ํ•œ๊ณ„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ๋งŽ์•„์„œ ๋ถˆ์•ˆ์ • -> ์ž˜ ์“ฐ์ง€ ์•Š๋Š”๋‹ค ์šฐํšŒ Double framing : ๋‘๊ฐœ์˜ iframe์„ ์‚ฌ์šฉํ•˜์—ฌ, ์ฒซ๋ฒˆ์งธ iframe์„ ์ˆจ๊ธฐ๊ณ , ๋‘๋ฒˆ์งธ iframe์„ ๋ณด์—ฌ์คŒ Abusing onBeforeUnload : ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ๋– ๋‚  ๋•Œ, alert์„ ๋„์›Œ์„œ, ์‚ฌ์šฉ์ž์˜ ํด๋ฆญ์„ ์œ ๋„ sandbox attribute : iframe์— sandbox attribute๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ํ•ด๋‹น iframe์—์„œ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๋„๋ก ํ•จ options allow-same-origin allow-scripts allow-forms allow-modals allow-top-navigation ์˜ˆ์‹œ 1<iframe ... sandbox="allow_forms allow-scripts"></iframe> Referrer checking problems Referer๋ฅผ ํ™•์ธํ•˜์—ฌ ํŠน์ • ๋„๋ฉ”์ธ์˜ ์‚ฌ์ดํŠธ๋งŒ iframe์œผ๋กœ ๋ Œ๋”๋ง๋˜์—ˆ๋Š”์ง€ ํ™•์ธ ํ•œ๊ณ„ : Referer๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ ์šฐํšŒ ๊ฐ€๋Šฅ Server-side X-Frame-Options ํŠน์ • ORIGIN ํŽ˜์ด์ง€์—์„œ๋งŒ ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ iframe์œผ๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ ์˜ˆ์‹œ 1X-Frame-Options: DENY // ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ iframe์œผ๋กœ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Œ 2X-Frame-Options: SAMEORIGIN // ๊ฐ™์€ ORIGIN ํŽ˜์ด์ง€์—์„œ๋งŒ ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ iframe์œผ๋กœ ๋ Œ๋”๋ง 3X-Frame-Options: ALLOW-FROM uri // ํŠน์ • uri์—์„œ๋งŒ ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ iframe์œผ๋กœ ๋ Œ๋”๋ง Outdated : CSP ์‚ฌ์šฉ ๊ถŒ์žฅ Content Security Policy (CSP) ์›นํŽ˜์ด์ง€์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ œํ•œ script-src : ์Šคํฌ๋ฆฝํŠธ source๋ฅผ ์ œํ•œ img-src : ์ด๋ฏธ์ง€์˜ source๋ฅผ ์ œํ•œ frame-ancestors : <frame>, <iframe>, <object>, <embed> ๋˜๋Š” <applet> ์š”์†Œ์˜ ๋ถ€๋ชจ๋ฅผ ์ œํ•œ ์˜ˆ์‹œ 1$csp = "Content-Security-Policy: frame-ancestors *"; 2header($csp); Types of Context Integrity Visual Integrity ๋ณด์ด๋Š” ๊ฒƒ๊ณผ ์‹ค์ œ๋กœ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์˜ ์ฐจ์ด์— ๋Œ€ํ•œ ๋ฌด๊ฒฐ์„ฑ ๋ฐฉ์–ด๋ฅผ ์œ„ํ•œ ๋ฐฉ๋ฒ• : User Confirmation, UI Randomization, Visibility Detection on Click Temporary Integrity ์‚ฌ์šฉ์ž ํ™•์ธ ์‹œ์ ๊ณผ ํด๋ฆญ ์‹œ์ž‘ ์‹œ์  ์‚ฌ์ด์˜ UI ์ƒํƒœ ์ฐจ์ด์— ๋Œ€ํ•œ ๋ฌด๊ฒฐ์„ฑ ๋ฐฉ์–ด๋ฅผ ์œ„ํ•œ ๋ฐฉ๋ฒ• : Access Control Gadgets SSRF (Server Side Request Forgery) ์„œ๋ฒ„์—์„œ ๋‹ค๋ฅธ ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ณต๊ฒฉ ๊ธฐ๋ฒ• ๊ณต๊ฒฉ (์„œ๋ฒ„๊ฐ€ ์‹ ๋ขฐ๋œ ์„œ๋ฒ„์—์„œ ์š”์ฒญ์ด ์˜จ ๊ฒƒ์œผ๋กœ ์ฐฉ๊ฐ) 1POST /product/stock HTTP/1.0 2Content-Type: application/www-form-urlencoded 3Content-Length: 30 4 5stockApi=http://localhost/admin ๋ฐฉ์–ด ์ฐจ๋‹จ๋œ ๋ฌธ์ž์—ด์„ URL ์ธ์ฝ”๋”ฉ ๋˜๋Š” ๋Œ€์†Œ๋ฌธ์ž ๋ณ€ํ˜•์„ ํ†ตํ•ด ์ˆจ๊น€ ์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜์—ฌ, ์š”์ฒญ์„ ๋ณด๋ƒ„ using @ 1https://expected-host:fakepassword@evil-host using # 1https://evil-host#expected-host Rogue DNS 1https://expected-host.evil-host Double encoding : # -> %23 -> %2523 XXE (XML eXternal Entity) Injection XML ํŒŒ์‹ฑ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ทจ์•ฝ์ ์„ ์ด์šฉํ•˜์—ฌ, ๊ณต๊ฒฉํ•˜๋Š” ๊ธฐ๋ฒ• XML custom entity XML์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฌธ์ž์—ด์„ ์ •์˜ 1<?xml version="1.0" encoding="UTF-8"?> 2<!DOCTYPE message [<!ENTITY greeting "Hello, ">]> 3<message> 4 <text>&greeting;world!</text> 5</message> Access internal file XML ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ, ์„œ๋ฒ„์˜ ํŒŒ์ผ์„ ์ฝ์–ด์˜ค๋Š” ๊ณต๊ฒฉ 1<?xml version="1.0" encoding="UTF-8"?> 2<!DOCTYPE foo[<!ENTITY xxe SYSTEM "file:///etc/passwd">]> 3<stockCheck><productId>&xxe;</productId></stockCheck> With SSRF SSRF์™€ ๊ฒฐํ•ฉํ•˜์—ฌ, ์™ธ๋ถ€ ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ณต๊ฒฉ 1<!DOCTYPE foo[<!ENTITY xxe SYSTEM "http://localhost/admin">]> ์•”ํ˜ธ๊ธฐ์ˆ  ์ „ํ†ต์ ์ธ ์•”ํ˜ธ๊ธฐ์ˆ  ์•”ํ˜ธ์˜ ์ •์˜ ์•”ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชฉ์  ๊ธฐ๋ฐ€์„ฑ (Confidentiality) : ์ •๋ณด๊ฐ€ ๋…ธ์ถœ๋˜์ง€ ์•Š์•„์•ผํ•จ ์ž๋ฃŒ์˜ ๋ฌด๊ฒฐ์„ฑ (Data Integrity) : ๋ฐ์ดํ„ฐ๊ฐ€ ์œ„๋ณ€์กฐ๋˜๋ฉด ์•ˆ๋จ ์ธ์ฆ (Authentication) : ์ •๋ณด์˜ ์ถœ์ฒ˜๊ฐ€ ์ •๋‹นํ•ด์•ผํ•จ ๋ถ€์ธ๋ฐฉ์ง€ (Non-repudiation) : ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฅผ ๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š์•„์•ผํ•จ ์•”ํ˜ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ธฐ๋ณธ ์กฐ๊ฑด (K : Key, M : Message, C : Cipher Text) ์•”ํ˜ธํ™” : E(K, M) = C ๋ณตํ˜ธํ™” : D(K, C) = C E(K, M)๊ณผ D(K, C)์˜ ๊ณ„์‚ฐ์€ ์‰ฌ์›Œ์•ผ ํ•จ K๋ฅผ ๋ชจ๋ฅผ๋•Œ C์—์„œ M์„ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ค์›Œ์•ผ ํ•จ ์•”ํ˜ธ ํ•ด๋… ๋ฐฉ๋ฒ• Cipher Text Only Attack : ์•”ํ˜ธ๋ฌธ๋งŒ์„ ์ด์šฉํ•˜์—ฌ ํ‰๋ฌธ์„ ์ฐพ๋Š” ๊ณต๊ฒฉ Known Plain Text Attack : ์•”ํ˜ธ๋ฌธ๊ณผ ํ‰๋ฌธ์„ ์ด์šฉํ•˜์—ฌ ํ‚ค๋ฅผ ์ฐพ๋Š” ๊ณต๊ฒฉ Chosen Plain Text Attack : ํ‰๋ฌธ์„ ์„ ํƒํ•˜์—ฌ ์•”ํ˜ธ๋ฌธ์„ ์ฐพ๋Š” ๊ณต๊ฒฉ ์•”ํ˜ธ์˜ ์ข…๋ฅ˜ ๋Œ€์นญํ‚ค(๋น„๋ฐ€ํ‚ค)(๊ด€์šฉํ‚ค) ์•”ํ˜ธ ์•”ํ˜ธํ™”์™€ ๋ณตํ˜ธํ™”์— ๊ฐ™์€ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•”ํ˜ธ ์‚ฌ์šฉ์ž n๋ช…์— ๋”ฐ๋ผ ํ•„์š”ํ•œ ํ‚ค์˜ ๊ฐœ์ˆ˜ : n(n-1)/2 ์•”ํ˜ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ข…๋ฅ˜ ๋ธ”๋ก ์•”ํ˜ธ (DES, IDEA, AES) ํ‰๋ฌธ์„ ๋ธ”๋ก์œผ๋กœ ๋‚˜๋ˆ„์–ด ์•”ํ˜ธํ™”ํ•˜๋Š” ๋ฐฉ์‹ ์ŠคํŠธ๋ฆผ ์•”ํ˜ธ (RC4) ํ‰๋ฌธ๊ณผ ํ‚ค๋ฅผ ๋น„ํŠธ ๋‹จ์œ„๋กœ XORํ•˜์—ฌ ์•”ํ˜ธํ™”ํ•˜๋Š” ๋ฐฉ์‹ ํ•œ๊ตญ์—์„œ ์“ฐ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ข…๋ฅ˜ : NEAT, SEED, NES, ARIA ๊ณต๊ฐœํ‚ค(๋น„๋Œ€์นญํ‚ค) ์•”ํ˜ธ ์•”ํ˜ธํ™”์™€ ๋ณตํ˜ธํ™”์— ๋‹ค๋ฅธ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•”ํ˜ธ ์‚ฌ์šฉ์ž n๋ช…์— ๋”ฐ๋ผ ํ•„์š”ํ•œ ํ‚ค์˜ ๊ฐœ์ˆ˜ : 2n ๊ธฐ๋ฐ€์„ฑ (Confidentiality) : ๊ณต๊ฐœํ‚ค๋กœ ์•”ํ˜ธํ™”, ๊ฐœ์ธํ‚ค๋กœ ๋ณตํ˜ธํ™” ์ธ์ฆ (Authentication) : ๊ฐœ์ธํ‚ค๋กœ ์•”ํ˜ธํ™”, ๊ณต๊ฐœํ‚ค๋กœ ๋ณตํ˜ธํ™” ํ‚ค ์ƒ์„ฑ DH ํ‚ค ๊ตํ™˜ ์•”ํ˜ธ๊ธฐ์ˆ ์˜ ํ™œ์šฉ ๋””์ง€ํ„ธ ์„œ๋ช… ํŠน์„ฑ : ์œ„์กฐ๋ถˆ๊ฐ€, ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€, ์„œ๋ช…์ž ์ธ์ฆ, ์žฌ์‚ฌ์šฉ ๋ถˆ๊ฐ€, ๋ถ€์ธ ๋ฐฉ์ง€ ๋™ํ˜•์•”ํ˜ธ์™€ ์–‘์ž์•”ํ˜ธ ๊ธฐ์ˆ 
new Spring - JPA : getReferenceById vs findById
๐Ÿƒ Spring
๋ฐฐ๊ฒฝ Service layer์—์„œ createPost ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ค‘ ์ด์—ˆ๋‹ค Post entity๋Š” User entity์™€ ManyToOne ๊ด€๊ณ„์ด๋‹ค User entity๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋‘๊ฐ€์ง€ ๋ฐฉ์‹์˜ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ–ˆ๋‹ค ๋‘ ๋ฐฉ์‹์˜ ์žฅ๋‹จ์ ์„ ํŒŒ์•…ํ•ด๋ณด์•˜๋‹ค getReferenceById ์‚ฌ์šฉ 1public Post createPost(PostDTO.Request postDTO, int userId) { 2 // ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค 3 User user = userRepository.getReferenceById(userId); 4 5 Post post = Post.builder() 6 .title(postDTO.getTitle()) 7 .content(postDTO.getContent()) 8 .created_at(LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS)) 9 .author(user) 10 .build(); 11 12 try { 13 return postRepository.save(post); 14 } catch (DataIntegrityViolationException e) { 15 throw new EntityNotFoundException("ํ•ด๋‹น ์œ ์ €๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค."); 16 } 17} ์žฅ์  : ์ฟผ๋ฆฌ ํ•œ๋ฒˆ์œผ๋กœ Post entity๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค ๋‹จ์  : insert ์ฟผ๋ฆฌ ์‹คํ–‰ ์ค‘ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋ฅผ ์žก๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ •์ ์ด์ง€ ์•Š๋‹ค findById ์‚ฌ์šฉ 1public Post createPost(PostDTO.Request postDTO, int userId) { 2 // ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค 3 Optional<User> user = userRepository.findById(userId); 4 5 if (user.isEmpty()) 6 throw new EntityNotFoundException("ํ•ด๋‹น ์œ ์ €๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค."); 7 8 Post post = Post.builder() 9 .title(postDTO.getTitle()) 10 .content(postDTO.getContent()) 11 .created_at(LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS)) 12 .author(user.get()) 13 .build(); 14 15 return postRepository.save(post); 16} ์žฅ์ : insert ์ฟผ๋ฆฌ ์‹คํ–‰ ์ „์— ๋ฏธ๋ฆฌ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ •์ ์ด๋‹ค ๋‹จ์ : ์ฟผ๋ฆฌ ๋‘๋ฒˆ์œผ๋กœ ์ธํ•œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค ๊ฒฐ๋ก  ์ฟผ๋ฆฌ๋ฅผ ๋‘ ๋ฒˆ ๋‚ ๋ฆฌ๋”๋ผ๋„ findById ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ •์ ์ด๋ผ์„œ ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค
new Spring ๊ฐœ๋… - MVC ํŒจํ„ด, Servlet (์„œ๋ธ”๋ฆฟ)
๐Ÿƒ Spring
Servlet ๊ฐœ๋… ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ž๋ฐ” ์›น ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ์ˆ  ์›นํŽ˜์ด์ง€๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค Servlet Conainer์˜ ์—ญํ•  Servlet์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค ์›น์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์ง€์› ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ ์ง€์›, ๊ด€๋ฆฌ ์„ ์–ธ์ ์ธ ๋ณด์•ˆ ๊ด€๋ฆฌ ์˜ˆ์ œ - Servlet ๊ตฌํ˜„ 1public class TestServlet extends HttpServlet { 2 private static final Logger logger = LoggerFactory.getLogger(TestServlet.class); 3 4 @Override 5 public void init() throws ServletException {} 6} doGet, doPost ๋“ฑ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์„œ http ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค Servlet Context๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ• web.xml ์ž‘์„ฑ web.xml web application์˜ ์„ค์ •์„ ์œ„ํ•œ deployment descriptor (๋ฐฐํฌ ์ง€์ •์ž) ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์ด๋‹ค src/webapp/WEB-INF/web.xml์— ์œ„์น˜ํ•œ๋‹ค 1<?xml version="1.0" encoding="UTF-8"?> 2<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 6 <servlet> 7 <servlet-name>myServlet</servlet-name> 8 <servlet-class>org.academy.abc.servlet.MyServlet</servlet-class> 9 </servlet> 10 <servlet-mapping> 11 <servlet-name>myServlet</servlet-name> 12 <url-pattern>/*</url-pattern> 13 </servlet-mapping> 14</web-app> @WebServet ์‚ฌ์šฉ Servlet์„ ์„ ์–ธํ•˜๋ฉด์„œ ์‚ฌ์šฉํ•œ๋‹ค 1@WebServlet(value="/*", loadOnStartup = 1) 2public class TestServlet extends HttpServlet {...} WebApplicationInitializer ๊ตฌํ˜„ 1public class OrderWebApplicationInitializer implements WebApplicationInitializer { 2 @Override 3 public void onStartup(ServletContext servletContext) throws ServletException { 4 var servletRegistration = servletContext.addServlet("test", new TestServlet()); 5 servletRegistration.addMapping("/*"); 6 servletRegistration.setLoadOnStartup(1); 7 } 8} DispatcherServlet HTTP์š”์ฒญ์„ ์ค‘์•™์ง‘์ค‘์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ์ด๋‹ค MVC ํŒจํ„ด DispatcherServlet์ด Handler mapping์„ ํ†ตํ•ด Handler๋ฅผ ์ฐพ๋Š”๋‹ค Handler adapter๊ฐ€ DispatcherServlet๊ณผ handler ์‚ฌ์ด์˜ ์ค‘๊ฐ„๋‹ค๋ฆฌ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค Controller๋Š” business logic์„ ์ฒ˜๋ฆฌํ•˜๊ณ  model๊ณผ view name์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค Dispatcher servlet์€ model์„ view๋กœ ๋„˜๊ฒจ์„œ view ๊ฒฐ๊ณผ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ˜ํ™˜ํ•œ๋‹ค
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) ํด๋ž˜์Šค ์ •๋ณด, ์ƒ์ˆ˜, ์ •์  ๋ณ€์ˆ˜ ๋“ฑ์„ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„ ๋ชจ๋“  ์“ฐ๋ ˆ๋“œ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๊ณต๊ฐ„ -> ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋”ฉ ์‹œ ๋™๊ธฐํ™” ์ฒ˜๋ฆฌ ํ•„์š”
  • ««
  • «
  • 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)