๋ฐฐ๊ฒฝ ํ
์ปค ๋ถํธ์บ ํ์์ ํํ๋ก์ ํธ๋ฅผ ์งํ ์ค์ด๋ค. ์ฐ๋ฆฌ ํ์ ์ฃผ์ ๋ ํน์ ์ธ๋ฌผ์๊ฒ ์๋ด์ ๋ฐ๋ ๊ฒ ๊ฐ์ ๋ํ๋ฅผ ํ ์ ์๋ ์ฑ๋ด์ ๋ง๋๋ ๊ฒ์ด๋ค. ์ด๋ฅผ ์ํด ํน์ ์ธ๋ฌผ์ด ํ๋ ๋ง์ ๋ชจ์ ๋ฐ์ดํฐ์
์ผ๋ก ๋ง๋ค๊ณ ์ด๋ฅผ 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๋ฅผ ์ฌ์ฉํ ๋๋ ํ
์ฌ๋ผ์ ๋ํด ๊ธ์ ์ ์ธ ์ผ๋ก ๋จธ์คํฌ์ ๋๋ต๊ณผ, ์์จ์ฃผํ ๊ธฐ์ ์ ์ธ๊ธํ๋ค๋ ๊ฒ์ ๋ฐ์ํ์ฌ ๋๋ต์ ์์ฑํ์๋ค. ๊ฐ์ ์ปดํจํฐ์ ์ธ๊ฐ์ด ์ํตํ๋ ๋ฐฉ๋ฒ ์ด์
๋ธ๋ฆฌ์ด ์ด์
๋ธ๋ฆฌ์ด์ ๋ฒ์ญ๊ธฐ๋ ์ด์
๋ธ๋ฌ(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์ ๋บ ๊ฒ ์ํฉ ํ
์ปค ๋ถํธ์บ ํ์์ ํํ๋ก์ ํธ๋ฅผ ์งํ ์ค์ด๋ค. ๋จ์ํ
์คํธ ์ฝ๋๋ ์์ฑ์ด ์๋ฃ๋์๊ณ , ํตํฉํ
์คํธ ์ฝ๋๋ฅผ ์์ฑ ์ค์ด๋ค. 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) ์ ๊ทผ์ด ์ด๋ ค์ ์ธํฐ๋ท์ ์ฐธ๊ณ ํ๋ค. ์ฝ๋๋ ๋ณด์ง ์์๋ค. ์์ ๊ธธ์ด๊ฐ 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) 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๊ฐ์ง ๋ฐ์ ์์ด์ ๊ฐ๋ฅํ๋ ์ผ์ด๋ค 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์ ๋ํ๋ค ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๊ณ ๋ คํ๋์ง ์ฌ๋ถ์ ๋ฐ๋ฅธ ํ
์คํธ์ ๋ถ๋ฅ ๋ธ๋๋ฐ์ค ํ
์คํธ ํ์ดํธ๋ฐ์ค ํ
์คํธ ๋ชฉ์ ๊ณผ ๋ฒ์์ ๋ฐ๋ฅธ ํ
์คํธ์ ๋ถ๋ฅ ์ํ ์์์ ๋ฐ๋ผ ์์ฑํด๋ณด์๋ค. 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 : ํ
์คํธ๋ ์ ์์ ์์ฑํด์ผ ํ๋ค. (์ค์ ์ฝ๋๋ฅผ ๊ตฌํํ๊ธฐ ์ ์ ์์ฑ) ๋ฐฐ๊ฒฝ ํ
์ปค ๋ถํธ์บ ํ์์ ํํ๋ก์ ํธ๋ฅผ ์งํ ์ค์ด๋ค. ์น์์ผ์ ํตํด ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ 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() 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 : ๋ณดํธ์ ์ธ ํจํด์ ์ฌ์ฉํ๋๊ฐ? ํด๋ผ์ฐ๋ ์ ๋๋ก ์ดํดํ๊ธฐ ํด๋ผ์ฐ๋๋ ๊ฐ์ธ์ด ๊ฐ์ง ๋จ๋ง๊ธฐ๋ฅผ ํตํด์๋ ์ฃผ๋ก ์
/์ถ๋ ฅ ์์
๋ง ์ด๋ฃจ์ด์ง๊ณ , ์ ๋ณด๋ถ์ ๋ฐ ์ฒ๋ฆฌ, ์ ์ฅ, ๊ด๋ฆฌ ์ ํต ๋ฑ์ ์์
์ ํด๋ผ์ฐ๋๋ผ๊ณ ๋ถ๋ฆฌ๋ ์ 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 ํด๋ผ์ฐ๋ ๊ด๋ จ ์ง๊ตฐ ํด๋ผ์ฐ๋ ์์ง๋์ด ํด๋ผ์ฐ๋ ์์คํ
์์ง๋์ด ํด๋ผ์ฐ๋ ์ธํ๋ผ ๋ณด์ ๋ด๋น์ ๋ฐ๋ธ์ต์ค ํด๋ผ์ฐ๋ ๋ฐฑ์๋ ๊ฐ๋ฐ์ ๋ชจ๋ํฐ๋ง ์์คํ
๊ตฌ์ถ ์ค์ต (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 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 : ํ์ฌ ์งํ์ค์ธ ํธ๋์ญ์
์ด ์กด์ฌํ๋ฉด ํด๋น ํธ๋์ญ์
์ฌ์ฉ, ์กด์ฌํ์ง ์์ผ๋ฉด ์๋ก์ด ํธ๋์ญ์
์ ์์ฑํ๋ค 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์ ๋ฐ์์ํจ๋ค 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๋ฒ์งธ๋ ๋ก ๊ฐ์๋ฅผ ๊ตฌํ๊ธฐ ์ํด ์ฒซ์งธ๋ ๋ก, ๋์งธ๋ ๋ก์ ๊ฐ๊ฐ ๋ช๋ฒ ๋ํด์ผํ๋์ง ๋ฆฌ์คํธ์ ๊ตฌํ๋ค ์ฒซ์งธ, ๋์งธ ๋ ๋ก์ ํ๋ํ๋ ๋ฃ์ด๋ณด๋ฉด์ ๋ธ๋ฃจํธ ํฌ์ค๋ฅผ ์ํํ๋ค ์ฒซ๋ฒ์งธ ํต๊ณผํ ํ์ด
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ํจ์๋ฅผ ํตํด ์ฝ๋์ ๊ธธ์ด๋ฅผ ๋ํญ ๊ฐ์ ์ํฌ ์ ์์๋ค, ์์ฃผ ํ์ฉํ์ ์ํฉ ์ฌ์ด๋ ํ๋ก์ ํธ “์๋ก"์ ๊ฐ๋ฐํ๋ ์ค, ์ฌ์ฉ์๊ฐ ์
์์ ์ธ ๋ชฉ์ ์ผ๋ก ๋ฐ๋ณต์ ์ผ๋ก ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ์ ์ด๋ป๊ฒ ๋ง์๊น ๊ณ ๋ฏผํ๊ฒ ๋์๋ค. ์กฐ์ฌ๋ฅผ ํตํด 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๋ฅผ ํตํด ๊ฒ์ฆ๋ ์์ฒญ์ ํ์ธํ ์ ์๋ค. 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์ ๋ธ๋๋ฆฌ์คํธ์ ์ถ๊ฐํ๋ค. ๋ฐฐ๊ฒฝ ํ
์ปค ๋ถํธ์บ ํ ์ต์ข
๋ฐํ ์ ๋ ์ด๋ค. 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 ๋ฉ์์ง๋ฅผ ๋์น์ง ์๋๋ก ์ฃผ์ํด์ผ๊ฒ ๋ค. ๋์์ธ ์ฝํน์ด๋ ๊ณต๊ฐ์ ๊ณผ์ ์ ํตํด ๋ฌธ์ ์ ์ ์ฐพ์๋ด๊ณ , ์์ด๋์ด๋ฅผ ๋ฐ์ฐํ๊ณ , ํ๋กํ ํ์
์ ๋ง๋ค์ด ๊ฒ์ฆ ๊ณผ์ ์ ๊ฑฐ์น๋, ๋ฐ๋ณต์ ํ๋ก์ธ์ค์ ๋ํ ๋ฐฉ๋ฒ๋ก ๋ฐ ์ฌ๊ณ ๋ฐฉ์ ๋์์ธ ์ฝํน ํ๋ก์ธ์ค ๊ณต๊ฐ - ๋ฌธ์ ์ ์ - ์์ด๋์ด ๋์ถ - ํ๋กํ ํ์ดํ - ํ
์คํ
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 ์คํ ๋ฆฌ๋ณด๋ ์คํ ๋ฆฌ๋ณด๋๋ ์ ํ ์ฌ์ฉ์ ํ๊ฒฝ, ์ ์ฐจ, ๋์ฆ ์ถฉ์กฑ ์์๊ฐ ํฌํจ๋๋ค ์คํ ๋ฆฌ๋ณด๋ฉ ์ ์ฐจ ์คํ ๋ฆฌ๋ผ์ธ ๋ง๋ค๊ธฐ ๋ฉ์ธ ์ค์ ์ท ๊ทธ๋ฆฌ๊ธฐ ํต์ฌ ์์ด๋์ด์ ์ ๋ฌ์ ์ํ ์ ์ ํ ์นด๋ฉ๋ผ ๊ตฌ๋ ์ค์ ๋ฐ ๊ทธ๋ฆฌ๊ธฐ ํ๋๊ณผ ์์ง์ ๊ฐ์กฐ ์ฒ๋ฆฌํ๊ธฐ ์ฌ๋๋ค์๊ฒ ์์ฐ ํ ํผ๋๋ฐฑ ๋ฐ๊ณ ์์ ํ๊ธฐ ์ 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 : ์ฒซ๋ฒ์งธ, ๋ง์ง๋ง, ์ค๊ฐ๊ฐ ์ค์์ ์ค๊ฐ๊ฐ์ ํผ๋ฒ์ผ๋ก ์ ํ ์
๋ ฅ์ด ์์ ํฌ๊ธฐ๊ฐ ๋์์๋ ์ฝ์
์ ๋ ฌ์ ์ฌ์ฉ 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 ํค ๊ตํ ์ํธ๊ธฐ์ ์ ํ์ฉ ๋์งํธ ์๋ช
ํน์ฑ : ์์กฐ๋ถ๊ฐ, ๋ณ๊ฒฝ ๋ถ๊ฐ, ์๋ช
์ ์ธ์ฆ, ์ฌ์ฌ์ฉ ๋ถ๊ฐ, ๋ถ์ธ ๋ฐฉ์ง ๋ํ์ํธ์ ์์์ํธ ๊ธฐ์ 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} 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 }}); ๋งค์ฒด ๋ณํ์ด๋ ์์ค, ํฌ๊ณก, ์, ์ํ ๋ฑ ๊ฐ๊ฐ์ ๋งค์ฒด ํ์์ ๋ค๋ฅธ ์ข
๋ฅ์ ๋งค์ฒด ํ์์ผ๋ก ๋ณํํ๋ ๊ฒ
๋คผ๋ฏธ์๋ฅด ํ์ ์ ์ํด์ ์ํ๊ฐ ๋ฐ๋ช
๋ ํ, 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๋
๋ ์ดํ ์ฒญ์ถ์ ์์ ์ผ๋ก ์ฒญ์ถ์ ํ์ค์ ๋คํฌ๊ณ ์ ํจ <์ด๋ฒ ์์ ์ฒ์์ด๋ผ>, <์, ๋ง์ด์จ์ด>, <์ก๊ณณ> ๋ฑ ๋๋ถ๋ถ ๊ธฐ์ฑ์ธ๋๊ฐ ๋ฐ๋ผ๋ ํ๋ณตํ ์ถ์ ๋ฐฉ์์ ๊ทธ๋๋ก ๋ต์ตํ๋ ๋ฐฉ์์ผ๋ก ๊ทธ๋ ค์ง ๋ํผ์ ์ธ ํํ์ง ์ฃผ๋ก ์ํ๋ก ํํ : ๊ธฐ์กด ๊ฐ์น๊ด์ ์๋ฌธ์ ๋์ง๋ฉฐ ์ถ์ ๋ค์์ฑ์ ๋ชจ์ํ๊ณ ํ์๋์ ๊ณ ๋ฏผ ์ง์ ์ ์ ์ํจ <๋ณ์ฐ>, <๋ฆฌํ ํฌ๋ ์คํธ>, <์๊ณต๋
>, <๋ฒ๋> ๋ฑ ๊ธฐ์ฑ์ธ๋์ ๊ธฐ์ค์์ ๋์ค๋์์ง๋ง, ์์ ๋ง์ ํ๋ณต์ ๊ฟ๊พธ๋ ๋ชจ์ต์ผ๋ก ๊ทธ๋ ค์ง ๊ณต๊ฐ ์ธ์ง์ ๊ณต๊ฐ : ์๋๋ฐฉ์ ์
์ฅ์ ์๋ณด๋ฉฐ ์ ๊ทธ๋ ๊ฒ ์๊ฐํ๊ณ ๋๋ผ๋ ์ง ์ดํดํ๋ ๋ฅ๋ ฅ ์ ์์ ๊ณต๊ฐ : ์๋๋ฐฉ์ด ๋๋ผ๋ ๊ฐ์ ์ ํจ๊ป ๋๋ผ๋ ๋ฅ๋ ฅ ์์ธ ๋ณธ ๋ด์ฉ์ 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); 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๋ง๋ผ์ธ ์ด์ 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 ๊ธฐ๋ฐ : ํน์ ํํ ๊ณต๊ฐ์ผ๋ก ๋ฐ์ดํฐ ๋งตํ -> ํํ ๊ณต๊ฐ์์์ ๊ฑฐ๋ฆฌ/๋ฐ๋ ๊ธฐ๋ฐ์ผ๋ก ํด๋ฌ์คํฐ์์ ๋ฒ์ด๋ ๋ฐ์ดํฐ๋ฅผ ์ด์์ผ๋ก ํ์ง