<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>IT 공부를 위한 블로그</title>
    <link>https://for-it-study.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 26 Jun 2026 09:24:45 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>싯타마</managingEditor>
    <item>
      <title>[네크워크-2] 네트워크 기술 종류(이더넷, 토큰링, FDDI, ATM)</title>
      <link>https://for-it-study.tistory.com/126</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;이더넷(Ethernet)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 개요:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워킹의 한 방식, 네트워크를 만드는 방법 중 하나&lt;/li&gt;
&lt;li&gt;CSMA/CD 프로토콜을 사용하여 통신
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CSMA/CD: &amp;lsquo;Carrier Sense Multiple Access/Collision Detection&amp;rsquo;을 줄여서 부름 -&amp;gt; 대충 알아서 통신하자!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;우리나라에서 사용하고 있는 네트워킹 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워킹 방식은 이더넷 방식 말고도, 토큰링 방식, FDDI 방식, ATM 방식도 있다. 어떤 네트워킹 방식을 사용하느냐에 따라 랜카드를 비롯하여 구입해야 하는 네트워킹 장비들이 다르기 때문에 네트워킹 방식을 꼭 알고 장비를 구매해야함&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;회사나 학교에서 네트워크를 통해 인터넷을 사용하고 있다면 이더넷 방식이 대부분이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;기술적 특징&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전송속도: &lt;/b&gt;이더넷의 일반적인 속도는 100/ 1,000Mbps&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동작방식: CSMA/CD&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CSMA/CD 동작원리:&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;현재 네트워크상에 통신이 일어나고 있는지를 확인(캐리어가 있는지를 감시 - Carrier Sense라고 한다.)&lt;/li&gt;
&lt;li&gt;이때 만약 캐리어(네트워크 신호)가 감지되면 누군가 네트워크 통신을 하고 있는 것임으로 통신이 끝나기를 기다린다.&lt;/li&gt;
&lt;li&gt;그러다가 네트워크 통신이 없으면 데이터를 네트워크상에 실어서 보낸다.&lt;/li&gt;
&lt;li&gt;하지만 2개 이상의 PC나 서버가 동시에 네트워크상에 데이터를 실어 보내는 경우(다중접근-Multiple Access) 충돌이 발생하면 이를 콜리전(Collision)이라고한다.&lt;/li&gt;
&lt;li&gt;따라서 이더넷은 데이터를 네트워크에 실어서 보내고자 할때 콜리전이 발생하지 않았는지 잘 점검해야 한다. 이를 충돌감지라고 한다.(Collision Detection)&lt;/li&gt;
&lt;li&gt;만약 콜리전이 발생한다면 데이터를 전송했던 PC들은 랜덤 한 시간 동안 기다린 후 다시 전송한다. (여기서 랜덤한 시간은 우리가 느끼지 못할정도의 시간)&lt;/li&gt;
&lt;li&gt;하지만 또 콜리전이 발생한다 &amp;rarr; 위의 6번 과정을 콜리전이 일어나지 않을때까지 15번 반복 &amp;rarr; 반복했는데도 충돌이 나면 결국 포기 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;이더넷에서 콜리전은 CSMA/CD 특성상 자연스러운 일이다. 하지만 너무 많은 충돌이 발생하게 되면 통신 자체가 불가능해지는 경우가 생길 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;토큰링(TokenRing)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;개요&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이더넷과 달리 오직 한 PC, 즉 토크늘 가진 PC만이 네트워크에 데이터를 실어 보낼 수 있는 것&lt;/li&gt;
&lt;li&gt;1990년대 초반까지만 해도 이더넷보다 안정된 기술이라는 주장이 나오면서 큰 인기를 끌었지만 이더넷의 발전으로 사라짐&lt;/li&gt;
&lt;li&gt;토큰링 프로토콜은 IBM이 처음 개발했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;기술적 특징:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전송방식&lt;/b&gt;: 데이터를 다보내고 나면 바로옆 PC에 토큰을 건네주게 된다. 만약 전송할 데이터가 없다면 토큰을 다른 PC로 넘긴다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전송속도&lt;/b&gt;: 토큰링의 일반적인 속도는 4Mbps / 16Mbps&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;장점&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;충돌(Collision)이 발생하지 않는다.&lt;/li&gt;
&lt;li&gt;네트워크에 대한 성능을 미리 예측하기도 쉽다.&amp;nbsp;&lt;/li&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;b&gt;단점&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;바로 보내야할 데이터가 있고, 다른 PC들은 보낼 데이터가 없더라도 차례가 올 떄 까지 계속 기다려야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;FDDI (Fiber Distributed Data Interface)&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;개요&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;FDDI는 광섬유(Fiber Optic)를 기반으로 한 고속 네트워크 기술로, LAN(Local Area Network) 및 MAN(Metropolitan Area Network) 환경에서 사용됩니다.&lt;/li&gt;
&lt;li&gt;주로 1980년대와 1990년대 초반에 고속 네트워크 연결을 제공하기 위해 사용되었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기술적 특징&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전송 속도&lt;/b&gt;: 최대 100Mbps.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;매체&lt;/b&gt;: 광섬유 또는 구리 케이블.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;토폴로지&lt;/b&gt;: 이중 링 토폴로지(Dual Ring Topology).
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 개의 링(Primary Ring과 Secondary Ring)으로 구성되어 있으며, 하나는 데이터 전송에 사용되고, 다른 하나는 장애 복구를 위해 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로토콜&lt;/b&gt;: 토큰 패싱(Token Passing) 방식.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 장치가 데이터를 전송하기 위해 토큰을 소유해야 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;높은 안정성과 신뢰성(이중 링 구조로 인해 장애 복구가 용이).&lt;/li&gt;
&lt;li&gt;긴 거리 전송 가능(광섬유 사용).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설치 비용이 높음(광섬유 기반).&lt;/li&gt;
&lt;li&gt;현대 네트워크 기술에 비해 느린 속도.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;용도&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대규모 캠퍼스 네트워크 또는 중형 도시 네트워크.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ATM (Asynchronous Transfer Mode)&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;개요&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ATM은 패킷 교환 방식과 회선 교환 방식의 장점을 결합한 고속 네트워크 기술입니다.&lt;/li&gt;
&lt;li&gt;데이터, 음성, 비디오 등 다양한 유형의 트래픽을 통합적으로 처리할 수 있도록 설계되었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기술적 특징&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전송 속도&lt;/b&gt;: 최대 622Mbps(일반적으로 155Mbps 또는 25 Mbps로 동작).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 단위&lt;/b&gt;: 고정된 크기의 셀(Cell) 단위 사용(53바이트).
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5바이트 헤더 + 48바이트 데이터.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;교환 방식&lt;/b&gt;: 비동기 전송 모드.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 데이터의 전송 간격이 일정하지 않음(동기화 필요 없음).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;QoS (Quality of Service)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 트래픽 유형에 대해 우선순위를 설정하고, 고품질의 서비스 제공 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터, 음성, 비디오를 단일 네트워크에서 처리 가능(멀티미디어 통신에 유리).&lt;/li&gt;
&lt;li&gt;낮은 지연 시간(Latency)과 높은 대역폭 제공.&lt;/li&gt;
&lt;li&gt;QoS 지원으로 안정적인 네트워크 성능 제공.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;고정 크기 셀 사용으로 인해 오버헤드가 발생(작은 데이터 패킷 처리 시 비효율적).&lt;/li&gt;
&lt;li&gt;설치와 운영 비용이 높음.&lt;/li&gt;
&lt;li&gt;TCP/IP 기반 인터넷 기술의 성장으로 도태됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;용도&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초고속 백본 네트워크.&lt;/li&gt;
&lt;li&gt;멀티미디어 통신, 비디오 스트리밍, 음성 통화.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/h3&gt;
&lt;table id=&quot;1834869d-8cd8-809e-a309-e211c213e800&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr id=&quot;1834869d-8cd8-80a1-a8ab-e9b519ed7e1c&quot;&gt;
&lt;td id=&quot;?F&amp;gt;m&quot;&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;m\jS&quot;&gt;&lt;b&gt;FDDI&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;{;Tk&quot;&gt;&lt;b&gt;ATM&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;&amp;lt;f@{&quot;&gt;&lt;b&gt;이더넷&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;rZk^&quot;&gt;&lt;b&gt;토큰링&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1834869d-8cd8-809a-8059-d119ce4349c1&quot;&gt;
&lt;td id=&quot;?F&amp;gt;m&quot;&gt;&lt;b&gt;전송 매체&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;m\jS&quot;&gt;광섬유 또는 구리 케이블&lt;/td&gt;
&lt;td id=&quot;{;Tk&quot;&gt;광섬유 또는 구리 케이블&lt;/td&gt;
&lt;td id=&quot;&amp;lt;f@{&quot;&gt;구리 케이블 또는 광섬유&lt;/td&gt;
&lt;td id=&quot;rZk^&quot;&gt;구리 케이블 또는 광섬유&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1834869d-8cd8-80f1-8faa-e3204da37a39&quot;&gt;
&lt;td id=&quot;?F&amp;gt;m&quot;&gt;&lt;b&gt;전송 속도&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;m\jS&quot;&gt;최대 100Mbps&lt;/td&gt;
&lt;td id=&quot;{;Tk&quot;&gt;최대 622Mbps&lt;/td&gt;
&lt;td id=&quot;&amp;lt;f@{&quot;&gt;10Mbps ~ 400Gbps 이상&lt;/td&gt;
&lt;td id=&quot;rZk^&quot;&gt;최대 16Mbps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1834869d-8cd8-8061-9197-c9ab01b36bf6&quot;&gt;
&lt;td id=&quot;?F&amp;gt;m&quot;&gt;&lt;b&gt;토폴로지&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;m\jS&quot;&gt;이중 링 토폴로지&lt;/td&gt;
&lt;td id=&quot;{;Tk&quot;&gt;네트워크 스위칭(패킷 교환 방식)&lt;/td&gt;
&lt;td id=&quot;&amp;lt;f@{&quot;&gt;버스 또는 스타 토폴로지&lt;/td&gt;
&lt;td id=&quot;rZk^&quot;&gt;링 토폴로지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1834869d-8cd8-801d-99d6-e8c3da380340&quot;&gt;
&lt;td id=&quot;?F&amp;gt;m&quot;&gt;&lt;b&gt;데이터 단위&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;m\jS&quot;&gt;가변 길이 프레임(Frame)&lt;/td&gt;
&lt;td id=&quot;{;Tk&quot;&gt;고정 길이 셀(Cell, 53바이트)&lt;/td&gt;
&lt;td id=&quot;&amp;lt;f@{&quot;&gt;가변 길이 프레임(Frame)&lt;/td&gt;
&lt;td id=&quot;rZk^&quot;&gt;가변 길이 프레임(Frame)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1834869d-8cd8-80fa-9049-f66d39975698&quot;&gt;
&lt;td id=&quot;?F&amp;gt;m&quot;&gt;&lt;b&gt;프로토콜 방식&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;m\jS&quot;&gt;토큰 패싱(Token Passing)&lt;/td&gt;
&lt;td id=&quot;{;Tk&quot;&gt;비동기 전송 모드&lt;/td&gt;
&lt;td id=&quot;&amp;lt;f@{&quot;&gt;CSMA/CD(초기) 또는 Full-Duplex&lt;/td&gt;
&lt;td id=&quot;rZk^&quot;&gt;토큰 패싱(Token Passing)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1834869d-8cd8-8020-87ec-e4d2346d2422&quot;&gt;
&lt;td id=&quot;?F&amp;gt;m&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;m\jS&quot;&gt;안정성, 이중 링 기반 장애 복구 가능&lt;/td&gt;
&lt;td id=&quot;{;Tk&quot;&gt;멀티미디어 통합 처리, QoS 지원&lt;/td&gt;
&lt;td id=&quot;&amp;lt;f@{&quot;&gt;설치 비용 저렴, 쉬운 확장성&lt;/td&gt;
&lt;td id=&quot;rZk^&quot;&gt;충돌 없음, 네트워크 대역폭 보장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1834869d-8cd8-80a1-9d67-ec3f08d98664&quot;&gt;
&lt;td id=&quot;?F&amp;gt;m&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;m\jS&quot;&gt;높은 설치 비용&lt;/td&gt;
&lt;td id=&quot;{;Tk&quot;&gt;오버헤드 발생, 설치 비용 높음&lt;/td&gt;
&lt;td id=&quot;&amp;lt;f@{&quot;&gt;네트워크 충돌 가능성(초기 CSMA/CD)&lt;/td&gt;
&lt;td id=&quot;rZk^&quot;&gt;속도 제한(최대 16Mbps), 복잡한 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr id=&quot;1834869d-8cd8-8017-b076-f383e2935726&quot;&gt;
&lt;td id=&quot;?F&amp;gt;m&quot;&gt;&lt;b&gt;주요 용도&lt;/b&gt;&lt;/td&gt;
&lt;td id=&quot;m\jS&quot;&gt;LAN 및 MAN 네트워크&lt;/td&gt;
&lt;td id=&quot;{;Tk&quot;&gt;백본 네트워크 및 멀티미디어 통신&lt;/td&gt;
&lt;td id=&quot;&amp;lt;f@{&quot;&gt;LAN 네트워크&lt;/td&gt;
&lt;td id=&quot;rZk^&quot;&gt;산업용 네트워크 또는 특수 환경&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>네트워크</category>
      <category>ATM</category>
      <category>Ethernet</category>
      <category>FDDI</category>
      <category>TokenRing</category>
      <category>네트워크</category>
      <category>네트워킹</category>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/126</guid>
      <comments>https://for-it-study.tistory.com/126#entry126comment</comments>
      <pubDate>Thu, 23 Jan 2025 00:50:15 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크-1] 네트워킹, 인터넷, 인트라넷, 엑스트라넷, 이더넷 개념 정리</title>
      <link>https://for-it-study.tistory.com/125</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 네트워킹(Networking)이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서로 연결하고 대화할 수 있는 것을 뜻한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 목적: 정보의 공유, 자원의 공유&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네트워킹의 시작: &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;호스트 장비가 엄청 비싼데 혼자 쓰기는&amp;nbsp; 아까워서 '터미널'이라고 부르는 장비 여러대를 호스트 장비에 붙여서 사용하기 시작하였다&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;- 정의: &lt;b&gt;PC 혹은 네트워크 장비들을 서로 대화가 가능하도록 묶어 주는 것&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;b&gt;2. 인터넷(Internet)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;b&gt;- Inter(인터)는 연결을 의미한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;b&gt;- internet은 '여러 개의 네트워크를 묶었다'라는 의미이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;1 ) WWW(World Wide Web)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;- 인터넷이 거미줄처럼 서로 연결되어 있기 때문에 Web이라는 단어를 쓴다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;- 인터넷&lt;span style=&quot;background-color: #ffffff; color: #202122; text-align: start;&quot;&gt;에 연결된&lt;span&gt;&amp;nbsp;컴퓨터&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122; text-align: start;&quot;&gt;를 통해 사람들이 정보를 공유할 수 있는 전 세계적인 정보 공유 시스템을 말한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 인트라넷(IntraNet)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인트라넷 역시 TCP/IP란 프로토콜을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 단 허용된 범위 내의 사람만 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 회사 인트라넷 -&amp;gt; 회사사람들만 사용 가능하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 이더넷(Ethernet)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네트워킹의 한 방식, 네트워크를 만드는 방법 중 하나이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CSMA/CD 프로토콜을 사용하여 통신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1) CSMA/CD란?&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LAN의 통신 프로토콜의 종류 중 하나이며, 이더넷 환경에서 사용한다.&lt;/li&gt;
&lt;li&gt;CSMA/CD 동작원리
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;현재 네트워크상에 통신이 일어나고 있는지를 확인(캐리어가 있는지를 감시 - Carrier Sense라고 한다.)&lt;/li&gt;
&lt;li&gt;이때 만약 캐리어(네트워크 신호)가 감지되면 누군가 네트워크 통신을 하고 있는 것임으로 통신이 끝나기를 기다린다.&lt;/li&gt;
&lt;li&gt;그러다가 네트워크 통신이 없으면 데이터를 네트워크상에 실어서 보낸다.&lt;/li&gt;
&lt;li&gt;하지만 2개 이상의 PC나 서버가 동시에 네트워크상에 데이터를 실어 보내는 경우(다중접근-Multiple Access) 충돌이 발생하면 이를 콜리전(Collision)이라고 한다.&lt;/li&gt;
&lt;li&gt;따라서 이더넷은 데이터를 네트워크에 실어서 보내고자 할 때 콜리전이 발생하지 않았는지 잘 점검해야 한다. 이를 충돌감지라고 한다.(Collision Detection)&lt;/li&gt;
&lt;li&gt;만약 콜리전이 발생한다면 데이터를 전송했던 PC들은 랜덤 한 시간 동안 기다린 후 다시 전송한다. (여기서 랜덤 한 시간은 우리가 느끼지 못할 정도의 시간)&lt;/li&gt;
&lt;li&gt;하지만 또 콜리전이 발생한다 &amp;rarr; 위의 6번 과정을 콜리전이 일어나지 않을 때까지 15번 반복 &amp;rarr; 반복했는데도 충돌이 나면 결국 포기한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;이더넷에서 콜리전은 CSMA/CD 특성상 자연스러운 일이다. 하지만 너무 많은 충돌이 발생하게 되면 통신 자체가 불가능해지는 경우가 생길 수 있다.&lt;/li&gt;
&lt;li&gt;이더넷의 일반적인 속도는 100/ 1,000 Mbps&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2) LAN(Local Area Network)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한정된 지역에서의 네트워크 구축&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 근거리 통신망이라고도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 네트워크 매체를 이용하여 집, 사무실, 학교 등의 건물과 같은 가까운 지역을 한데 묶는 네트워크이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3) WAN(Wide Area Network)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 멀리 떨어진 지역을 서로 연결하는 경우에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 광역 네트워크라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사무실, 데이터 센터, 클라우드 애플리케이션 및 클라우드 스토지를 서로 연결하는 기술이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나의 건물이나 대규모 캠퍼스를 넘어 특정 지역이나 심지어 전 세계에 분산된 여러 위치까지도 포함하기 때문에 광역 네트워크라고 한다.&lt;/p&gt;</description>
      <category>네트워크</category>
      <category>비</category>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/125</guid>
      <comments>https://for-it-study.tistory.com/125#entry125comment</comments>
      <pubDate>Thu, 16 Jan 2025 22:27:48 +0900</pubDate>
    </item>
    <item>
      <title>[2024.05.02] Today I Learned(Serializer, AWS CloudFront, commit message)</title>
      <link>https://for-it-study.tistory.com/124</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;오늘 배운 것&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Django REST Framework(이하 DRF) Serializer 옵션값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. commit message의 중요성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. AWS CloudFront&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. DRF 옵션값&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 나에게 긴급 이슈 요청이 들어와서 서둘러 일을 처리해야 했다. 전에 작성했던 코드를 수정했어야 했는데 오랜만에 보다 보니 기억이 잘 나지 않았고, 추가로 아직 까지도 Django Restfamework가 익숙하지 않아서 수정하는데 헤매었다 그러던 중 선임님이 이슈를 같이 해결해 주셨고...! 결국 무임승차를 하게 되었다.... 크으 나는 제한된 시간 안에 코드를 짤 때는 빨리해야 된다는 압박감에 머리솟이 하에 지는 것 만 같은데 선임 분이 해주셔서(?) 무사히 끝낼 수 있었다. (정말 멋져....)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 내가 못 찾았던 원인은&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;Django REST Framework의 Serializer 클래스의 옵션값이 설정되어 있었다.&lt;/u&gt;&lt;u&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;Serailizer에서는 클래스의 필드에 옵션값을 설정해서 세밀한 제어를 가능하게 해 준다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 짧게 옵션값들에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. read_only&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- True이면 필드는 직렬화할 때만 사용되고 역직렬화는 허용되지 않는다. (API를 읽을 수는 있지만 수정할 수는 없다.&lt;/p&gt;
&lt;pre id=&quot;code_1714655565564&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from rest_framework import serializers

class UserSerializer(serializers.Serializer):
	user_id = serializers.IntegerField(read_only=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. write_only 옵션&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- True이면 이 필드는 역직렬화할 때만 사용되고 직렬화는 허용하지 않는다. (데이터를 입력받을 때는 사용되지만 출력할 때는 보이지 않는다. ex) 비밀번호 )&lt;/p&gt;
&lt;pre id=&quot;code_1714655614445&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from rest_framework import serializers

class UserSerializer(serializers.Serializer):
	password = serializers.CharField(write_only=True, style={'input_type': 'password'})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. required&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- True이면 필드가 반드시 제공되어야 한다. (기본값은 True)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. default&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 필드값이 제공되지 않을 때 사용할 기본값을 설정한다.&lt;/p&gt;
&lt;pre id=&quot;code_1714655708367&quot; class=&quot;python&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;from rest_framework import serializers

class UserSerializer(serializers.Serializer):
	email = serializers.EmailField(required=True, default=&quot;no-reply@example.com&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- required True라서 email은 필수값이고 없을 땐 default값으로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. allow_null&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- True이면 필드값으로 'null'을 허용한다. (기본값은 False)&lt;/p&gt;
&lt;pre id=&quot;code_1714655863321&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from rest_framework import serializers

class UserSerializer(serializers.Serializer):
    bio = serializers.CharField(allow_null=True, required=False, help_text=&quot;Short biography of the user&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. validators&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 필드에 적용할 추가적인 검증 함수 목록이다. 이를 통해 사용자 정의 검증 로직을 적용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1714655903611&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from rest_framework import serializers

class UserSerializer(serializers.Serializer):
	age = serializers.IntegerField(validators=[lambda value: value &amp;gt;= 18])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7. error_messages&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 필드 유효성 검증 실패 시 표시할 에러 메시지를 사전 형식으로 정의한다.&lt;/p&gt;
&lt;pre id=&quot;code_1714655924844&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from rest_framework import serializers

class UserSerializer(serializers.Serializer):
	username = serializers.CharField(error_messages={'blank': 'Username cannot be empty.'})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8. label&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 필드의 레이블을 지정한다. HTML 폼에서 필드의 설명으로 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;9. help_text&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 필드 사용에 대한 추가적인 도움말을 제공한다. HTML 폼에서 사용된다.&lt;/p&gt;
&lt;pre id=&quot;code_1714655975429&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; from rest_framework import serializers

class UserSerializer(serializers.Serializer):
 	first_name = serializers.CharField(label=&quot;First Name&quot;, help_text=&quot;Enter your first name&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 옵션값들을 extra_kwargs를 통해 한꺼번에 지정하는 방법도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1714656648386&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from rest_framework import serializers


EXTRA_KWARGS = {
    'user_id': {'read_only': True},
    'password': {
        'write_only': True,
        'style': {'input_type': 'password'},
        'help_text': 'Your password must be 8-20 characters long.'
    },
    'email': {
        'required': True,
        'default': 'no-reply@example.com',
        'validators': [lambda value: value.endswith('@example.com')],
        'error_messages': {'invalid': 'This email is not valid.'}
    },
    'first_name': {
        'label': 'First Name',
        'help_text': 'Enter your first name.'
    },
    'last_name': {
        'write_only': True,
        'style': {'template': 'custom_input.html'}
    },
    'bio': {
        'allow_null': True,
        'required': False
    }
}

class UserSerializer(serializers.Serializer):
    user_id = serializers.IntegerField()
    username = serializers.CharField()
    email = serializers.EmailField()
    password = serializers.CharField()
    first_name = serializers.CharField()
    last_name = serializers.CharField()
    bio = serializers.CharField()
    
	extra_kwargs = SALE_EXTRA_KWARGS&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. commit message의 중요성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선임님의 도움을 주던 중 내가 짠 과거 코드에 대해서 물어봤다... 그래서 github의 커밋메시지를 보았는데... 대충&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'정확한 oo데이터 수집을 위한 수정, XX 기능 추가'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 느낌의 메시지였는데 내가 보아도 엉망인 커밋이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;한 번에 두 가지 이슈를 커밋해 버려서&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 짠 코드가 전자에 관한 내요인지 후자에 관한 내용인지 구분을 해야 할 수밖에 없었다....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 짜는 것도 중요하지만 이런 커밋메시지를 정리를 잘하거나 지라 이슈관리를 잘해야 함을 느꼈다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 선임님은 개발 실력도 좋으신데... 정리도 초깔끔하게 핵심내용만 작성을 한다는 것이다...(여러모로 배울 점이 많은 분...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반성을 하게 됐다. 실력이 없으면 정리라도 깔끔하게 잘해야 하는데... 아니 정리를 잘하는 것도 실력인가..! 허허&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대한 커밋메시지라도 잘 쓰려고 노력을 해봐야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋메시지 관련해서는 선임님이 추천해 주신 블로그글을 보고 괜찮다고 느껴졌다.... 남의 글을 함부로 링크를 걸면 안 될 것 같아서..&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;구글에 '커밋메시지 작성 가이드'를 검색하면 좋은 글이 많이 있다. 앞으로 참고하면서 신경 써서 작성을 해봐야겠다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. AWS CloudFront&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 겪은 이슈 중에는 이미지 업로드가 되었음에도 업로드된 이미지로 바뀌지 않고 이전 이미지를 출력하는 현상도 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제도 혼자 했으면.... 몰랐겠지만.... 옆에서 듣고 계시던 CTO님이 해결을 해주셨다...! (도움만 받는 인생..ㅋ 성장해서 은혜를 갚아주마)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 AWS의 CloudFront와 관련이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/Introduction.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/Introduction.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1714656792239&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Amazon CloudFront란 무엇입니까? - Amazon CloudFront&quot; data-og-description=&quot;Amazon CloudFront란 무엇입니까? Amazon CloudFront는 .html, .css, .js 및 이미지 파일과 같은 정적 및 동적 웹 콘텐츠를 사용자에게 더 빨리 배포하도록 지원하는 웹 서비스입니다. CloudFront는 엣지 로케이션&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/Introduction.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/Introduction.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gJ21W/hyVVymU9XV/i3ODVfo3AQOdItRzcLuDG1/img.png?width=598&amp;amp;height=500&amp;amp;face=0_0_598_500&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/Introduction.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/Introduction.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gJ21W/hyVVymU9XV/i3ODVfo3AQOdItRzcLuDG1/img.png?width=598&amp;amp;height=500&amp;amp;face=0_0_598_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Amazon CloudFront란 무엇입니까? - Amazon CloudFront&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Amazon CloudFront란 무엇입니까? Amazon CloudFront는 .html, .css, .js 및 이미지 파일과 같은 정적 및 동적 웹 콘텐츠를 사용자에게 더 빨리 배포하도록 지원하는 웹 서비스입니다. CloudFront는 엣지 로케이션&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마존 홈페이지에서 가이드 내용이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Amazon CloudFront는. html,. css,. js 및 이미지 파일과 같은 정적 및 동적 웹 콘텐츠를 사용자에게 더 빨리 배포하도록 지원하는 웹 서비스입니다. CloudFront는 엣지 로케이션이라고 하는 데이터 센터의 전 세계 네트워크를 통해 콘텐츠를 제공합니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS의 콘텐츠 전송 네트워크(CDN) 서비스라고도 하는데 전 세계에&amp;nbsp; 에지로케이션(Edge Server(Locatcion))을 두고 Client와 가장 가까운 Edge Server를 찾아서 그곳에 캐싱해 두었던 데이터를 가져와서 제공하는 시스템이다. (캐시 되어있고 가까운 서버를 찾아서 가져오므로 속도 up)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Edge Location ?&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CloudFront 서비스가 콘텐츠를 캐싱하고 Client에게 제공하는 지점 혹은 캐시 서버를 의미한다.&amp;nbsp; 전 세계 주요 도시에 300개 이상의 서버가 분포되어 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자가 CloudFront를 통해 서비스하는 콘텐츠를 사용자가 요청하면 지연 시간이 가장 낮은 에지 로케이션으로 라우팅 됨으로 콘텐츠 전송 성능이 뛰어나다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 내가 겪은 이슈는 요런 장점과는 별개로 CloudFront를 사용할 때 &lt;u&gt;&lt;b&gt;이미지 업데이트 후 최신화된 이미지를 보여줘야 하는데 캐시 된 데이터를 보여주게 되는 문제였다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해서 여러 방법이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 캐시데이터 무효화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 요청전송: CloudFront배포에 대한 캐시 무효화 요청하여 Edge Location에 저장되었던 캐시데이터를 삭제한다. 이 과정은 전 세계의 여러 Edge Location에 적용돼야 할 수도 있어서 시간이 좀 걸릴 수 있다. 하지만 최신 버전의 콘텐츠로 바뀌고 나면 다시 캐시데이터를 사용하게 되므로 그 후에 로딩할 때는 이미지가 빠르게 처리된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 캐시 만료 설정변경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CloudFront의 배포설정에 캐시 만료시간(TTL, Time To Live)을 줄이는 방법도 있다. 이는 캐시 된 파일이 더 빨리 만료가 되어 자주 업데이트가 필요한 콘텐츠의 경우 유리 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 콘텐츠 버전관리&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네,&amp;nbsp;맞습니다.&amp;nbsp;당신이&amp;nbsp;겪은&amp;nbsp;이슈는&amp;nbsp;CloudFront를&amp;nbsp;사용할&amp;nbsp;때&amp;nbsp;매우&amp;nbsp;흔히&amp;nbsp;발생하는&amp;nbsp;문제로,&amp;nbsp;캐시된&amp;nbsp;오래된&amp;nbsp;콘텐츠가&amp;nbsp;새로&amp;nbsp;업데이트된&amp;nbsp;콘텐츠&amp;nbsp;대신에&amp;nbsp;계속해서&amp;nbsp;제공되는&amp;nbsp;것입니다.&amp;nbsp;이런&amp;nbsp;현상은&amp;nbsp;캐시된&amp;nbsp;데이터가&amp;nbsp;아직&amp;nbsp;유효하다고&amp;nbsp;판단되어&amp;nbsp;CloudFront가&amp;nbsp;오리진&amp;nbsp;서버에서&amp;nbsp;새로운&amp;nbsp;데이터를&amp;nbsp;가져오지&amp;nbsp;않기&amp;nbsp;때문에&amp;nbsp;발생합니다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. Tag와 Last-Modified 헤더 사용&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 오리진 서버에서 콘텐츠에 `ETag` 또는 `Last-Modified` 헤더를 설정하여 변경 사항을 관리할 수 있습니다. CloudFront는 이 헤더를 기반으로 콘텐츠가 변경되었는지를 판단하고, 필요에 따라 새로운 콘텐츠를 가져옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 CloudFont를 사용하는 이미지가 자주 바꾸지 않는다는 가정으로 이미지를 교체할 때 캐시데이터 무효화 요청을 같이 보내주는 걸로 결정했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 추가로 리전(Region)에 대해서도 배웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;리전(Region)?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특정 지리적 위치에 위치한 물리적 데이터 센터 그롭을 의미한다. 각 리전은 가용영역(Avaliability Zones)으로 구성되며 리전 구조는 높은 가용성과 장애 내성을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 CloudFront 또한 물리적 데이터 센터를 나누어서 분포시켰으므로 리전구조라고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;가용 영역(Availability Zone, AZ)?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 하나의 리전 내에 위치한 여러 개의 물리적 데이터 센터를 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 가용 영역은 일반적으로 지리적으로 가까운 위치에 있지만, 다른 가용 영역과는 독립적으로 운영됩니다. 이들은 서로 다른 전력, 냉각 및 네트워킹 인프라를 사용하여, 하나의 가용 영역에 문제가 발생해도 다른 가용 영역의 리소스가 영향을 받지 않도록 설계되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;느낀 점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 하루도 내가 많이 부족하다고 느껴졌다. 개발 속도도 느리고 아직 모르는 개념들이 너무 많았다. 개발자를 계속할 수 있을까 라는 의심이 들지만... 아직은 좀 더 노력해보고 싶다! 그리고 하루에 꼭 TIL을 해야 되겠다고 마음먹고 한 달 만에 쓰는 TIL이다..ㅋㅋ 반성하자 제발 열심히 좀 살자~&lt;/p&gt;</description>
      <category>TIL</category>
      <category>availablity zone</category>
      <category>AWS</category>
      <category>clourfront</category>
      <category>commit</category>
      <category>djagno</category>
      <category>restframework</category>
      <category>Til</category>
      <category>가용성</category>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/124</guid>
      <comments>https://for-it-study.tistory.com/124#entry124comment</comments>
      <pubDate>Thu, 2 May 2024 23:28:36 +0900</pubDate>
    </item>
    <item>
      <title>[2024.04.01] 성장일기 Today I Learned(TIL)</title>
      <link>https://for-it-study.tistory.com/123</link>
      <description>&lt;h1&gt;서론&lt;/h1&gt;
&lt;p&gt;오늘은 회의시간에서 많은걸 배운것 같다.&lt;/p&gt;
&lt;p&gt;현재 우리 회사는 서비스 범위 확장으로 보다 만은 데이터들을 저장하고 관리해줘야 하는 과제가 주어졌다.&lt;/p&gt;
&lt;p&gt;그래서 대규모 데이터를 효율적으로 사용하고 확장에 용이하게 변경하기 위하여 데이터 분산 방법인 샤딩을 도입할 예정이다.&lt;/p&gt;
&lt;p&gt;그리고 현재 MySql과 Postgres를 동시에 사용중인데 공간정보데이터를 사용하는 Postgres를 더 자주 사용하게 될것이라 생각이들어서&lt;/p&gt;
&lt;p&gt;기존 MySql을 사용중이던 DB들을 Postgres로 전환하고 Postgres만 사용하기로 결정했다.(개발 용이성과 Postgres에서 지원하는 Postgis 등의 기술들을 활용하기 위함)&lt;/p&gt;
&lt;p&gt;또한 우리는 데이터를 자동으로 수집 및 전송하는 여러 q를 개발했고 앞으로도 추가 될것이기 때문에 기존 django Q로 설정해서 순차적으로 실행시키는 방법에서  SNS, SQS, MQ, MQTT, Celery 등의 구조를  사용하기로 결정했다.&lt;/p&gt;
&lt;p&gt;그렇다 본인은 프론트엔드 개발자라 위 용어들이 매우 생소하고 어려웠다. 그래도 팀장님이 친절하게 설명해주셨고..... 모자란 부분을 채우기 위해 오늘의 성장일기를 위내용으로 선정했다. 너무 깊게는 못 팔것 같고 기술들의 간단한 내용정리를 남기고자 한다.&lt;/p&gt;
&lt;h1&gt;본론&lt;/h1&gt;
&lt;h2&gt;Sharding(샤딩)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;샤딩은 데이터베이스 아키텍처의 한 방식으로, 대규모 데이터베이스의 데이터를 수평으로 분할하여 다른 데이터베이스 서버에 분산 저장하는 기술이다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;데이터를 효율적으로 관리하고 &lt;strong&gt;읽기 및 쓰기 요청의 부하를 분산시켜 시스템의 성능과 확장성을 향상 시키는 데 목적이 있다.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;### 샤딩의 장점 &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;확장성(Scalability)&lt;/strong&gt;: 샤딩을 통해 데이터베이스 시스템의 수평 확장이 용이해진다. 데이터가 증가함에 따라 추가 샤드를 구성하여 처리능력을 쉽게 향상 할 수 있다.(여기서 샤드란 각 서버에 저장되는 데이터 분할을 뜻한다.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;2&lt;strong&gt;.성능(Perfomance):&lt;/strong&gt; 데이터가 여러 서버에 분산되어 있기 때문에 &lt;strong&gt;병렬로 데이터를 처리 할 수 있으며,&lt;/strong&gt; 이는 &lt;strong&gt;전체 시스템의 처리량과 응답 속도를 향상&lt;/strong&gt;시킨다.&lt;/p&gt;
&lt;p&gt;3.&lt;strong&gt;고가용성(High Availability)&lt;/strong&gt;: 샤딩은 데이터를 여러 서버에 분산시키므로, 하나의 서버에 장애가 발생해도 시스템 전체의 가용성에 미치는 영향을 최소화할 수 있습니다.&lt;/p&gt;
&lt;h3&gt;샤딩의 단점&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;복잡성(Complexity)&lt;/strong&gt;: 데이터를 여러 샤드에 분산시키기 때문에, 데이터 관리가 복잡해지고 , 샤드 간 데이터 일관성 유지가 어려울 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;조인(Join)의 어려움&lt;/strong&gt; : &lt;strong&gt;서로 다른 샤드에 저장된 데이터를 조인하는 것이 기술적으로 어렵&lt;/strong&gt;거나 성능에 부정적인 영향을 줄 수 있다. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;주관적인 생각: 확실히 장단점이 있지만 우리는 비즈니스를 지역 -&amp;gt; 전국으로 확장하기에 비교적 지역별로 데이터를 관리하면 되서 단점을 줄일 수 있을것 같고 몇백만건의 데이터 덩어리들을 처리하기 위해서는 확장성과 성능 측면에서 확실히 샤딩 도입이 필요하다고 생각이 들었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;여기서 추가로 소소한 지식들을 배울 수 있었는데 우리는 샤딩을 클러스터 하나와 쓰기1개 읽기 2개의 총 3개의 서버를 마스터 - 슬레이브 구조로 개발할 예정이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;여기서 쓰기가 1개인 이유는 우리는 여러 데이터 수집 코드를 사용하여 데이터를 수집하는데 쓰기전용 서버가 여러개다보면 동시에 데이터를 저장하게 된다거나 불가피한 이유로 저장할때 충돌이 발생할 수 있는 확률도 높아지기 때문에 보통 쓰기전용은 1개로 구성을 하였다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;읽기는 데이터를 처리할때 아무래도 쓰기 보다 읽기가 더 빈번하게 일어날 확률이 높기 때문에 2개로 구성을 하기로 결정했다. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;AWS 기능들&lt;/h2&gt;
&lt;h3&gt;SNS (Amazon Simple Notification Service)&lt;/h3&gt;
&lt;p&gt;Amazon SNS는 고도로 확장 가능한, 완전 관리형 메시징 서비스로, 애플리케이션 간 또는 애플리케이션에서 사용자에게 분산된 메시지를 보낼 수 있도록 설계되었습니다. SNS는 푸시 알림, SMS 및 이메일을 포함하여 다양한 메시징 채널을 지원합니다. SNS의 주요 특징 중 하나는 팬아웃 메시징 패턴을 통해 수많은 구독자에게 동시에 메시지를 전송할 수 있다는 점입니다.&lt;/p&gt;
&lt;h3&gt;SQS (Amazon Simple Queue Service)&lt;/h3&gt;
&lt;p&gt;Amazon SQS는 분산 애플리케이션 간의 메시지를 교환하기 위한 완전 관리형 메시지 큐잉 서비스입니다. SQS를 사용하면 컴포넌트가 서로 연결되지 않고 비동기적으로 통신할 수 있으므로, 애플리케이션의 분리와 확장성을 향상시킬 수 있습니다. SQS는 두 가지 유형의 메시지 큐를 제공합니다: 표준 큐(최대 처리량에 최적화)와 FIFO 큐(순서가 보장되고 메시지가 한 번만 전달됨).&lt;/p&gt;
&lt;h3&gt;MQ (Amazon MQ)&lt;/h3&gt;
&lt;p&gt;Amazon MQ는 액티브MQ와 래빗MQ와 같은 인기 있는 오픈 소스 메시지 브로커를 관리형 서비스로 제공합니다. 이 서비스는 기존 애플리케이션의 마이그레이션을 용이하게 하고, 메시지 브로커의 설치, 운영, 유지 관리의 복잡성을 줄여줍니다. Amazon MQ는 표준 JMS, NMS, AMQP, STOMP, MQTT, WebSocket 프로토콜을 지원하여 다양한 메시징 패턴과 애플리케이션과의 통합을 지원합니다.  &lt;/p&gt;
&lt;h3&gt;MQTT (Message Queuing Telemetry Transport)&lt;/h3&gt;
&lt;p&gt;MQTT는 경량의 메시지 프로토콜로, 네트워크 대역폭이 제한적이거나 네트워크 연결이 불안정한 환경에서 IoT 기기와 같은 저전력 장치 간의 메시지를 교환하기 위해 설계되었습니다. MQTT는 게시/구독(pub/sub) 모델을 기반으로 하며, 매우 작은 코드 풋프린트를 요구하므로 임베디드 시스템에 적합합니다.&lt;/p&gt;
&lt;h2&gt;Celery&lt;/h2&gt;
&lt;p&gt;Celery는 Python 작성된 분산 태스크 큐입니다. 비동기적 작업 실행, 실시간 처리 및 스케줄링을 위해 사용되며, 주로 웹 애플리케이션에서 백그라운드 작업을 처리하는 데 사용됩니다. Celery는 브로커(예: RabbitMQ, Redis)를 사용하여 메시지를 전송하며, 다양한 백엔드(예: SQLAlchemy, Django ORM)와의 통합을 지원하여 작업 결과를 저장하고 조회할 수 있습니다.&lt;/p&gt;
&lt;p&gt;-&amp;gt; 우리는 기존 Django Q를 비동기적으로 자동화 하기 위해 Celery를 사용하고 MQTT의 Pub/Sub 모델을 사용하여며 SNS와 SQS를 통해 특정 상황에서 메시지를 분산적으로 보내고 메시지 받는것을 구독(감지)하여 태스크 큐를 MQ에 저장하고 큐를 처리한다.  &lt;/p&gt;</description>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/123</guid>
      <comments>https://for-it-study.tistory.com/123#entry123comment</comments>
      <pubDate>Tue, 2 Apr 2024 01:16:43 +0900</pubDate>
    </item>
    <item>
      <title>[2024.03.25] 오늘의 TIL</title>
      <link>https://for-it-study.tistory.com/122</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;TIL의 첫 시작&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우연히 유튜브를 보다 인프콘에서 연사 하신 지소라 님의 강의를 듣고 나도 TIL을 기록해 보기로 결심했다.&lt;br /&gt;하루 있었던 이슈나, 경험이나 아니면 사소한 이야기든 기록을 할 예정이고, 꼭 하루 마무리를 TIL 작성으로 끝낼 수 있기를 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 인상 깊게본 지소라 님 인프콘 영상 링크이다.&lt;br /&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ifGUz43GjdQ&quot;&gt;https://www.youtube.com/watch?v=ifGUz43GjdQ&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보면서 정말 대단하다고 생각했다...&lt;br /&gt;나는 본체 소심하고 적극적이지 않아서 자신감 있게 발표하는 모습이 정말 멋있게 느껴졌고&lt;br /&gt;유명한 채널인 개발바닥에서 진행한 이력서 피드백 콘텐츠에서&lt;br /&gt;지적받았었던 내용들까지 공개할 수 있는 용기가 배워야 한다고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 모습에 반해서 찾아보니 지소라 님도 유튜브를 하고 계시고 블로그 글도 찾아봤다. 매일은 아니더라도 꾸준히 TIL을 쓰고 되게 열심히 사는 분이라고 느껴졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나도 정말 열심히 노력해서 언젠가 만난다면... 존경하고 덕분에 자극이 잘됐다고 인사할 수 있는 만큼 성자해 있기를!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;경험 이슈&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 api 요청 파라미터를 만들기 위해 input요소의 value값을 수정하고 이 요청에 맞는 응답값을 return 해주는 api 코드를 수정하는 업무를 봤는데&lt;br /&gt;이 과정에서 여러 문제를 겪어서 이외에는 다른 업무를 보지 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 크게 2가지이다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;요청 파라미터 수정 시 발생하는 사이드 이펙트&lt;/li&gt;
&lt;li&gt;django filter 쿼리&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 2번 우리 폴더트리는 django filter.py라는 파일에서 필터가 필요한 쿼리를 작성해 준다. 기존 코드를 참고하여 코드를 작성하고자 했지만 해당 코드에 대한 지식의 부재로 살짝 어려움을 느껴 챗 gpt에게 도움을 청해서 코드를 짜봤다. 다음은 작성한의 일부 코드이다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;def ld_code_filter(self, queryset, name, value):
  ld_codes = value.split(&quot;,&quot;)

  conditions = [
            (
                Q(data__ld_code__value__startswith=ld_code[:-2])
                if ld_code.endswith(&quot;00&quot;)
                else Q(data__ld_code__value__startswith=ld_code)
            )
            for ld_code in ld_codes
        ]

  query = reduce(or_, conditions) if conditions else Q()

  return queryset.filter(query)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간력하게 설명하면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ld_codes를 ',' 기준으로 나는 리스트의 값에서 endswith를 사용해서 끝값을 확인한다.&lt;/li&gt;
&lt;li&gt;true면 &quot;00&quot;으로 끝나는 끝 두 글자를 제외한 값을 data&amp;gt; ld&amp;gt; valu의 처음부터 비교하여 일치하는 값을 쿼리 한다.&lt;/li&gt;
&lt;li&gt;아니면 ld_code 그대로 비교해서 쿼리 한다.&lt;/li&gt;
&lt;li&gt;Q는 장고 model orm으로 where 절에 or문 또는 and문을 추가하고 싶을 때 사용한다.&lt;/li&gt;
&lt;li&gt;or_은 Python의 operator 모듈에서 제공하는 함수로, 두 조건 Q 객체를 OR 연산으로 결합합니다. 결과적으로, 이 reduce 호출은 conditions 리스트에 있는 모든 조건을 하나의 쿼리로 결합한다. 만약 conditions 리스트가 비어있다면, reduce는 사용되지 않으며 대신 빈 Q() 객체를 사용한다. 아래는 내가 요청에 대한 파라미터를 만들기 위해 만든 params이다.&lt;/li&gt;
&lt;li&gt;다음은 1번 요청 파리미터에 수정할 때 생긴 문제였다.&lt;br /&gt;이는 자바스크립트의 &lt;b&gt;참조무결성 문제&lt;/b&gt;였는데,&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;var params = [&quot;ld_code=5011010400&quot;,&quot;sale_type=1&quot;,&quot;ordering=-created_at&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 값에서 ld_code만 ld_name으로 변경한 후 새로 값을 변수를 선언해 줘서 사용하고 싶었다. 그래서 함수를 하나 만들었는데&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;
var params = getSalesParams(tabId)
var ldName = getCheckedLdNames(tabId)
var params_ld_name = modifyLdCodeToLdName(params,ldName);

function modifyLdCodeToLdName(params, ldName) {
  // ld_code 파라미터의 인덱스를 찾습니다.

  var ldCodeIndex = params.findIndex(function(param) {
    return param.startsWith('ld_code=');
  });

  // ld_code 파라미터가 존재한다면, 이를 ld_name으로 수정합니다.
  if (ldCodeIndex !== -1) {
    params[ldCodeIndex] = 'ld_name=' + ldName.join(',');
  }

  return params;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 params에서 ld_code를 ld_name으로 변경하고 반환해 줬다. 나의 목적은&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ld_code가 필요한 곳에는 기존 prams를 사용&lt;/li&gt;
&lt;li&gt;ld_name이 필요한곳에는 변경된 params_ld_name을 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이였다. modifyLdCodeToLdName() 변환해 주는 함수 이후에 params도 ld_name으로 변경돼서 ld_code가 필요한 요청에 에러들이 발생했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 삽질을 한 결과 문제의 원인은 자바스크립트 특징 중 하나인 배열의 &lt;b&gt;참조에 의한 전달(Pass by Reference)로 인한 문제였다.&lt;/b&gt;&lt;br /&gt;JavaScript에서 배열과 객체는 메모리 주소를 통해 전달되므로, 함수 내에서 이들의 내용을 변경하면 호출 지점에서도 원본에도 변경이 반영되는 것이었다. 배열이나 객체를 함수에 전달할 때 원본을 변경하지 않으려면, 함수 내에서 원본의 복사본을 만들어 작업해야 한다. 예를 들어, &lt;b&gt;&lt;code&gt;params.slice()&lt;/code&gt;&lt;/b&gt;를 사용하여 배열의 얕은 복사본을 만들고 이를 수정할 수 있었다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;유데미&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 저녁에는 유데미에서 진행한 연사가 있었는데 까먹고 있다가 오늘 안내 메일을 보내줘서 들을 수 있었다.&lt;br /&gt;강사 해주시는 강사님은 전에 멋사 부트캠프에도 강연을 해주셨던 임동준 개발자님과 이번 기회에 처음 강의를 듣게 된 장현석 강사님이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강의 주제는 &lt;b&gt;'개발자의 똑똑한 학습 방법 - &amp;lsquo;메타인지&amp;rsquo;와 &amp;lsquo;피드백&amp;rsquo;'이었고&lt;/b&gt; 나중에는 이력서 피드백 및 고민에 대한 상담도 진행해 줘서 정말 유익했다.&lt;br /&gt;나만 하던 고민들을 많은 개발자들이 고민하고 있다는 사실에 공감과 이에 대한 이야기를 들을 수 있어서 좋았고, 내가 하는 공부법과 일하는 방식 과연 메타인지를 잘 활용하는 공부법 인가? 에 대해 생각해 보게 되었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;내 문제점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 좀 무식하게 손으로 글을 써가면서 공부를 하는 타입이었다(눈만으로는 잘 안 들어오고 글 쓰는 게 더 잘 외워지는 느낌?) 근데 이런 공부 방식은 오래 하지 못한다. 손도 아프고 지치기 때문에 처음에 열심히 하던 게 끝으로 갈수록 점점.... 대충 하게 되는 경향이 있는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 일할 때도 나는 주변피드백도 그렇고 나 자신도 그렇게 느끼는 게 일 처리가 느리다는 피드백을 받았다. 문제의 원인을 생각해서 이를 해결할 수 있는 방법에 대해 고민해 보는 계기가 되었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해결방안&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;일단 효율적인 공부와 일처리를 위해 타이머를 재야겠다. 나는 평소 느긋한 성격이기 때문에 공부할 때나 코드를 짤 때도 느긋하게 하는 경향이 있는 것 같다. 제한시간이 오늘이 아닌 시간 단위로 쪼개서 해당 시간 안에 꼭 끝내어야겠다는 목표를 세우기로 했다.&lt;/li&gt;
&lt;li&gt;또한 해야 할 것은 시작하기 전에 요구사항을 명확하게 하고 작은 단위로 쪼개서 리스트없한다. 내가 해당 리스트를 처리할 수 있는 능력을 판단하고 80% 완성 화려면 얼마나 걸릴지를 생각해 보고 그거에 맞게 제한시간을 정한 후 제 한 시간 안에 끝내 보려고 한다.&lt;/li&gt;
&lt;li&gt;해당 리스트가 끝날 때마다 정말 짧은 회고를 진행한다. 왜 제한 시간 안에 못 끝냈는지 이를 해결하려면 어떻게 해야 할지 등&lt;br /&gt;위 과정을 반복하다 보면 점점 제한시간안에 내가 할 것을 끝낼 수 있을지 않을까 하는 생각을 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;느낀 점/요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 til이라 길게 썼는데 짧아도 매일 쓰도록 노력하자...&lt;br /&gt;오늘 하루 생각보다 유익하게 보낸듯하다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;참조무결성 문제 잊지 말기&lt;/li&gt;
&lt;li&gt;쿼리 공부 좀 더 하기&lt;/li&gt;
&lt;li&gt;유데미 강의, 인프런 영상 유익했다. 심심하거나 공부하기 싫을 때 찾아서 보면 좋을 것 같다.&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>TIL</category>
      <category>Til</category>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/122</guid>
      <comments>https://for-it-study.tistory.com/122#entry122comment</comments>
      <pubDate>Tue, 26 Mar 2024 08:48:14 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] 자바스크립트의 원시값과 복합객체 이해하기</title>
      <link>https://for-it-study.tistory.com/121</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;자바스크립트는&amp;nbsp;다양한&amp;nbsp;데이터&amp;nbsp;타입을&amp;nbsp;제공하여,&amp;nbsp;개발자가&amp;nbsp;효율적으로&amp;nbsp;프로그래밍할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;환경을&amp;nbsp;만들어&amp;nbsp;줍니다.&amp;nbsp;이&amp;nbsp;포스트에서는&amp;nbsp;자바스크립트의&amp;nbsp;두&amp;nbsp;주요&amp;nbsp;데이터&amp;nbsp;타입인&amp;nbsp;원시값과&amp;nbsp;복합객체에&amp;nbsp;대해&amp;nbsp;깊이&amp;nbsp;있게&amp;nbsp;탐구해보겠습니다.&amp;nbsp;이해의&amp;nbsp;편의를&amp;nbsp;위해&amp;nbsp;정의에서&amp;nbsp;시작하여,&amp;nbsp;저장&amp;nbsp;및&amp;nbsp;복사&amp;nbsp;방법,&amp;nbsp;그리고&amp;nbsp;이들의&amp;nbsp;비교&amp;nbsp;방식에&amp;nbsp;대해&amp;nbsp;자세히&amp;nbsp;설명하겠습니다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;원시값(Primitive&amp;nbsp;Values)&lt;/b&gt;&lt;br /&gt;원시값은&amp;nbsp;변경&amp;nbsp;불가능한&amp;nbsp;가장&amp;nbsp;기본적인&amp;nbsp;데이터&amp;nbsp;타입을&amp;nbsp;말합니다.&amp;nbsp;자바스크립트에서는&amp;nbsp;null,&amp;nbsp;undefined,&amp;nbsp;문자열(string),&amp;nbsp;숫자(number),&amp;nbsp;불리언(boolean),&amp;nbsp;Symbol,&amp;nbsp;BigInt를&amp;nbsp;원시값으로&amp;nbsp;분류합니다.&amp;nbsp;이들의&amp;nbsp;특징은&amp;nbsp;다음과&amp;nbsp;같습니다:&lt;br /&gt;&lt;br /&gt;저장 및 복사: 원시값은 변수에 할당될 때 메모리에 그 값 자체가 저장됩니다. 변수를 다른 변수에 할당하면, 원래의 값이 복사되어 새 변수에 저장됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1709592461111&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let myString = 'hello';
let myStringCopy = myString; // 'hello' 값이 복사됩니다.
myString = 'world';
console.log(myString, myStringCopy); // 'world hello'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;비교: 원시값을 비교할 때는 값 자체를 비교합니다. 따라서 같은 값을 가진 두 변수는 서로 같다고 인식합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1709592481404&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let price1 = 10;
let price2 = 10;
console.log(price1 === price2); // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;&lt;b&gt;복합객체(Composite&amp;nbsp;Objects)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;복합객체는&amp;nbsp;여러&amp;nbsp;값을&amp;nbsp;하나의&amp;nbsp;단위로&amp;nbsp;구성할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;데이터&amp;nbsp;타입입니다.&amp;nbsp;자바스크립트에서는&amp;nbsp;객체(Object),&amp;nbsp;배열(Array),&amp;nbsp;함수(Function),&amp;nbsp;날짜(Date),&amp;nbsp;정규&amp;nbsp;표현식(RegExp)&amp;nbsp;등을&amp;nbsp;복합객체로&amp;nbsp;분류합니다.&amp;nbsp;복합객체의&amp;nbsp;특징은&amp;nbsp;다음과&amp;nbsp;같습니다:&lt;br /&gt;&lt;br /&gt;저장&amp;nbsp;및&amp;nbsp;복사:&amp;nbsp;복합객체는&amp;nbsp;메모리에&amp;nbsp;참조(주소)로&amp;nbsp;저장됩니다.&amp;nbsp;객체를&amp;nbsp;다른&amp;nbsp;변수에&amp;nbsp;할당하면,&amp;nbsp;원본&amp;nbsp;객체의&amp;nbsp;메모리&amp;nbsp;주소가&amp;nbsp;복사되어,&amp;nbsp;두&amp;nbsp;변수가&amp;nbsp;같은&amp;nbsp;객체를&amp;nbsp;가리키게&amp;nbsp;됩니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1709592516957&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let myObject = {name: &quot;John&quot;};
let copyOfMyObject = myObject;
myObject.age = 30;
console.log(myObject, copyOfMyObject); // 두 객체 모두 동일한 속성을 가집니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;비교: 두 복합객체를 비교할 때는 참조(주소)를 비교합니다. 따라서, 구조적으로 동일한 두 객체라 할지라도, 메모리 상에서 다른 위치에 저장되어 있다면 다르다고 평가됩니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1709592543085&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let object1 = {name: &quot;John&quot;};
let object2 = {name: &quot;John&quot;};
console.log(object1 === object2); // false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;예제:&amp;nbsp;원시값과&amp;nbsp;복합객체의&amp;nbsp;동작&amp;nbsp;이해하기&lt;br /&gt;원시값 예제: 문자열 원시값을 다루는 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1709592557603&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var string1 = &quot;foo&quot;;
var string2 = String(&quot;foo&quot;); // 'foo' 문자열 원시값
console.log(string1 === string2); // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;복합객체&amp;nbsp;예제:&amp;nbsp;객체의&amp;nbsp;참조를&amp;nbsp;복사하는&amp;nbsp;예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1709592570702&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var myObject = {name: &quot;John&quot;};
var copyOfMyObject = myObject;
myObject.age = 30;
console.log(copyOfMyObject.age); // 30&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복합 객체를 가리키는 변수들은 변수가 메모리에서 모두 하나의 &amp;ldquo;주소를&amp;rdquo; 가리키고 있을 떄만 서로 같다고 판단합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수를 새로 만들어 이미 존재하던 복합 객체를 가리키더라도 기존 객체를 복사하지는 않습니다.&lt;/p&gt;
&lt;pre class=&quot;livescript&quot;&gt;&lt;code&gt;var objA = {prop:&quot;val&quot;}
var pointer1 = objA;
var pointer2 = ponter1

objA.prop = null;
-&amp;gt; 참조하는 pointer1 과 pointer2가 모두 null로 변경된다.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 정의하고 참조를 만든 후 객체를 갱신하면 해당 객체를 가리키는 모든 참조도 변경 됨으로 동적인 객체 속성도 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* typeof 특이사항&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;null은 object로 출력된다. ( 자바스크립트 처음 설계할때 잘못설계한것으로 알고 있음)&lt;/li&gt;
&lt;li&gt;function은 function으로 출력된다.&lt;/li&gt;
&lt;li&gt;RegExp는 object로 출력된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복합객체는 동적속성으로 이루어져 있다. 따라서 &lt;b&gt;사용자 정의 객체 및 대부분의 네이티브 객체는 수정할수 있는 객체입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 하지만 이런 동작은 주의(네이티브 객체는 수많은 사람들이 사용하는데 기존과 다른 방식으로 동작하는 객체로 변경하는것이기 떄문)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 인스턴스로 만들면 객체/인스턴스에는 constructor라는 속성이 자동으로 추가됩니다.&lt;/p&gt;
&lt;pre class=&quot;delphi&quot;&gt;&lt;code&gt;var foo = {};

console.log(foo.constructor === Object) // Object()가 foo를 만들었음으로 true

console.log(foo.constructor) // Object() 생성자 함수를 가리킨다.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떠한 인스턴스를 다루고 있는데 인스턴스를 만든 생성자 함수를 알 수 없는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 &lt;b&gt;속성을 사용하면 간편하게 생성자 함수를 찾을 수 있습니다. 이를 사용하면 어떤 인스턴스가 배열인지 객체인지 혹은 다른 자료형인지도 확인 할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;var MyNumber = new Number('23');
var MyNumberL = 23;
var MyString = new String(&quot;male&quot;);
var MyStringL = &quot;male&quot;;
var MyBoolean = new Boolean('true');
var myBoolean = true;

myNumber.constructor === Number // true
...
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/HTML, CSS, JavaScript</category>
      <category>Javascript</category>
      <category>복합객체</category>
      <category>원시값</category>
      <category>자바스크립트</category>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/121</guid>
      <comments>https://for-it-study.tistory.com/121#entry121comment</comments>
      <pubDate>Tue, 5 Mar 2024 07:54:41 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScrpit] Iterator pattern</title>
      <link>https://for-it-study.tistory.com/120</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. Iterator pattern(이터레이터 패턴)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ES6에서 도입된 이터레이션 프로토콜(iteration protocol)은 데이터 컬렉션을 순회하기 위한 프로토콜(미리 약속된 규칙)이다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;이터레이션 프로토콜을 준수한 객체는&lt;span style=&quot;color: #409d00;&quot;&gt; &lt;u&gt;for&amp;hellip;of 문으로 순회&lt;/u&gt;&lt;/span&gt;할 수 있고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;a style=&quot;color: #409d00;&quot; href=&quot;https://poiemaweb.com/es6-extended-parameter-handling#3-spread-%EB%AC%B8%EB%B2%95&quot;&gt;Spread 문법&lt;/a&gt;&lt;/span&gt;의 피연산자가 될 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이터레이션 프로토콜에는 이터러블 프로토콜(iterable protocol)과 이터레이터 프로토콜(iterator protocol)이 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이터레이터 패턴은 이터레이터를 사용하여 컬렉션의 요소들에 접근하는 디자인 패턴이다. 여러 가지 자료형의 구조와는 상관없이 이터레이터라는 하나의 인터페이스로 순회가 가능하다는 장점이 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709501890799&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const mp = new Map();

mp.set('b', 2)
mp.set('c', 3)

const st = new Set();

st.add(1)
st.add(2)
st.add(3)

//for..of 문법
for (let a of mp) console.log(a)

for (let a of st) console.log(a)

// Spread 문법
console.log([...st])
console.log(...&quot;javascript&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;11-이터러블&quot; style=&quot;background-color: #ffffff; color: #434b4f; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1.1 이터러블&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이터러블 프로토콜을 준수한 객체를 이터러블이라 한다. 이터러블은&amp;nbsp;&lt;b&gt;Symbol.iterator 메서드를&lt;/b&gt; 구현하거나 프로토타입 체인에 의해 상속한 객체를 말한다. Symbol.iterator 메서드는 이터레이터를 반환한다. 이터러블은 for&amp;hellip;of 문에서 순회할 수 있으며 Spread 문법의 대상으로 사용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;배열은 Symbol.iterator 메서드를 소유한다. 따라서 배열은 이터러블 프로토콜을 준수한 이터러블이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이터레이터 프로토콜 확인 -&amp;gt; Symbol.iterator 메서드를 확인&lt;/p&gt;
&lt;pre id=&quot;code_1709501985469&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const array = [1, 2, 3];

// 배열은 Symbol.iterator 메소드를 소유한다.
// 따라서 배열은 이터러블 프로토콜을 준수한 이터러블이다.
console.log(Symbol.iterator in array); // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 객체는 Symbol.iterator 메소드를 소유하지 않는다. 따라서 &lt;b&gt;일반 객체는 이터러블 프로토콜을 준수한 이터러블이 아니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1709502077787&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const obj = { a: 1, b: 2 };

// 일반 객체는 Symbol.iterator 메소드를 소유하지 않는다.
// 따라서 일반 객체는 이터러블 프로토콜을 준수한 이터러블이 아니다.
console.log(Symbol.iterator in obj); // false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 Symbol.iterator in array를 null로 선언하면 이러터블 프로토콜을 준수하지 않으므로 이터레이터 패턴을 사용할 수 없다&lt;/p&gt;
&lt;pre id=&quot;code_1709502477051&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let arr = [1,2,3]
for(const a of arr) console.log (a) // 정상작동 1,2,3


arr[Symbol.iterator] = null; 
for(const a of arr) console.log (a) // Uncaught TypeError: arr is not iterable&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;12-이터레이터&quot; style=&quot;background-color: #ffffff; color: #434b4f; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1.2 이터레이터&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이터레이터 프로토콜은 next 메소드를 소유하며 next 메소드를 호출하면 이터러블을 순회하며 value, done 프로퍼티를 갖는 이터레이터 리절트 객체를 반환하는 것이다. 이 규약을 준수한 객체가 이터레이터이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이터러블 프로토콜을 준수한 이터러블은 &lt;b&gt;Symbol.iterator 메서드를 소유&lt;/b&gt;한다. &lt;b&gt;이 메소드를 호출하면 이터레이터를 반환한다&lt;/b&gt;. 이터레이터 프로토콜을 준수한 이터레이터는&lt;b&gt;next 메서드를&lt;/b&gt; 갖는다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709502850090&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const array = [2,3,4]

const iterator = array[Symbol.iterator]();

console.log('next' in iterator) // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;next 메서드를 호출하면 value, done 프로퍼티를 갖는 이터레이터 리절트 객체를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709503055523&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const array = [4,5,6]

const iterator = array[Symbol.iterator]();

console.log('next' in iterator)

let iteratorResult = iterator.next();
console.log(iteratorResult); // {value: 1, done: false}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;b&gt;이터레이터의 next 메서드는 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;u&gt;이터러블의 각 요소를 순회하기 위한 포인터의 역할&lt;/u&gt;&lt;/span&gt;한다.&lt;/b&gt; next 메서드를 호출하면 이터러블을 순차적으로 한 단계씩 순회하며 이터레이터 리절트 객체를 반환한다. &lt;b&gt;순회 중&lt;u&gt;&lt;span style=&quot;color: #009a87;&quot;&gt; value에는 현재 순회 중인 이터러블의 값을&lt;/span&gt;&lt;/u&gt; 반환하고, &lt;u&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;done 프로퍼티에는 이터러블의 순회 완료 논리값을 반환&lt;/span&gt;&lt;/u&gt;한다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709503197837&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const array = [4,5,6]

const iterator = array[Symbol.iterator]();

console.log('next' in iterator)

let iteratorResult = iterator.next();

console.log(iterator.next()); // {value: 5, done: false}
console.log(iterator.next()); // {value: 6, done: false}
console.log(iterator.next()); // {value: undefined, done: True}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;4-이터레이션-프로토콜의-필요성&quot; style=&quot;background-color: #ffffff; color: #434b4f; text-align: start;&quot;&gt;2. 이터레이션 프로토콜의 장점&lt;/h1&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;데이터 소비자(Data consumer)인 for&amp;hellip;of 문, spread 문법 등은 아래와 같이 다양한 데이터 소스를 사용한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Array, String, Map, Set, TypedArray(Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array), DOM data structure(NodeList, HTMLCollection), Arguments&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 데이터 소스는 모두 이터레이션 프로토콜을 준수하는 이터러블이다. 즉, 이터러블은 데이터 공급자(Data provider)의 역할을 한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;만약 이처럼 다양한 데이터 소스가 각자의 순회 방식을 갖는다면 데이터 소비자는 다양한 데이터 소스의 순회 방식을 모두 지원해야 한다. 이는 효율적이지 않다. 하지만 다양한 데이터 소스가 &lt;b&gt;이터레이션 프로토콜을 준수하도록 규정하면 데이터 소비자는 이터레이션 프로토콜만을 지원하도록 구현하면 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이터레이션 프로토콜은 다양한 데이터 소스가 하나의 순회 방식을 갖도록 규정하여 데이터 소비자가 효율적으로 다양한 데이터 소스를 사용할 수 있도록&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;데이터 소비자와 데이터 소스를 연결하는 인터페이스의 역할을 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;참고내용:&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;모던 자바스크립트 딥다이브: 자바스크립트의 기본 개념과 동작 원리 - 이웅모&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;면접을 위한 cs 전공지식 노트 - 주홍철&lt;/p&gt;</description>
      <category>프로그래밍/HTML, CSS, JavaScript</category>
      <category>iterable</category>
      <category>iterator</category>
      <category>Javascript</category>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/120</guid>
      <comments>https://for-it-study.tistory.com/120#entry120comment</comments>
      <pubDate>Mon, 4 Mar 2024 07:10:49 +0900</pubDate>
    </item>
    <item>
      <title>Python 리스트(list)와 튜플(tuple) 개념 정리</title>
      <link>https://for-it-study.tistory.com/119</link>
      <description>&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;
&lt;div style=&quot;color: #000000;&quot; data-testid=&quot;conversation-turn-13&quot;&gt;
&lt;div&gt;
&lt;div data-message-id=&quot;65d21b69-f407-4cf3-bf3d-c1bb0db227f9&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;파이썬은 데이터를 저장하고 처리하는 데 필요한 다양한 내장 데이터 타입을 제공합니다. 그 중에서도 리스트(List)와 튜플(Tuple)은 자주 사용되는 타입으로, 데이터의 순서와 집합을 다루는 데 매우 유용합니다.&lt;b&gt; 이 두 타입의 가장 큰 차이점은 '변경 가능성(mutable vs immutable)'입니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 리스트(List) - 유연하고 동적인 컨테이너&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- 리스트는 '변경 가능한(mutable)' 데이터 타입으로, 순서가 있는 요소의 집합입니다. 리스트는 대괄호 [] 또는 list() 함수를 통해 생성할 수 있으며, 다양한 데이터 타입을 포함할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1706196795327&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 빈 리스트 생성
list1 = []

# 숫자로 구성된 리스트
list2 = [1, 2, 3, 4, 5]

# 중첩 리스트
list3 = [1, [2, 3], [&quot;a&quot;, &quot;b&quot;]]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- 리스트는 다음과 같은 방법으로 요소를 추가, 수정, 삭제할 수 있습니다&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1706196845388&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 요소 추가
example_list = [1, 2, 3]
example_list.append(4)  # 결과: [1, 2, 3, 4]
example_list.extend([5, 6])  # 결과: [1, 2, 3, 4, 5, 6]

# 요소 삽입
example_list.insert(2, 'a')  # 결과: [1, 2, 'a', 3, 4, 5, 6]

# 요소 수정
example_list[2] = 'hi'  # 결과: [1, 2, 'hi', 3, 4, 5, 6]

# 요소 삭제
example_list.remove('hi')  # 결과: [1, 2, 3, 4, 5, 6]
del example_list[5]  # 결과: [1, 2, 3, 4, 5]

# 요소 삭제 및 반환
five = example_list.pop()  # 결과: [1, 2, 3, 4], five = 5
one = example_list.pop(0)  # 결과: [2, 3, 4], one = 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 튜플&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;(Tuple) - 변경이 불가능하여 안전성과 무결성 가진 컨테이너&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;튜플은 '변경 불가능한(immutable)' 데이터 타입으로, 한 번 생성되면 그 값이 변경될 수 없습니다. 이는 데이터의 안정성과 무결성을 유지하는 데 유용하고 &lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000; text-align: start;&quot;&gt;주로 데이터를 읽기 전용으로 사용할 때 적합 합니다&lt;/span&gt;. 튜플은 소괄호 () 또는 tuple() 함수를 사용하여 생성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;또한 튜플 언패킹을 통해 여러 변수에 값을 한 번에 할당할 수 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1706196965801&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 튜플 언패킹
f, g, h = (1, 2, 3) # f = 1 , g = 2, h = 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리스트와 튜플은 파이썬 프로그래밍에서 각기 다른 상황에 맞게 사용됩니다. 리스트는 변화가 필요한 데이터 집합에 적합하며, 튜플은 변하지 않는 데이터 집합을 처리할 때 사용되는 것이 일반적입니다. 이 두 타입을 적절히 사용함으로써, 파이썬 프로그래밍의 효율성과 안정성을 높일 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리스트와 튜플은 서로 타입변환이 가능하다&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1706197229779&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 리스트를 튜플로 변환
my_list = [1, 2, 3, 4]
my_tuple = tuple(my_list)
print(my_tuple)  # (1, 2, 3, 4)

# 튜플을 리스트로 변환
my_tuple = (1, 2, 3, 4)
my_list = list(my_tuple)
print(my_list)  # [1, 2, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot; data-state=&quot;closed&quot;&gt;&lt;/span&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot; data-testid=&quot;conversation-turn-15&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-id=&quot;81c2ada0-b467-4ab0-a2e8-f965edca0d59&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 변환은 데이터의 유형을 변경할 필요가 있을 때, 예를 들어 &lt;b&gt;튜플의 요소를 수정하거나, 리스트를 튜플로 변경하여 데이터의 안정성을 높이고 싶을 때 유용&lt;/b&gt;합니다. 데이터의 본질적인 내용은 그대로 유지하면서&lt;b&gt; 컨테이너 타입만 변경&lt;/b&gt;하는 것이므로, &lt;b&gt;데이터 처리에 있어서 유연성을 제공합니다.&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;/span&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot; data-testid=&quot;conversation-turn-16&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>프로그래밍/python</category>
      <category>List</category>
      <category>Python</category>
      <category>tuple</category>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/119</guid>
      <comments>https://for-it-study.tistory.com/119#entry119comment</comments>
      <pubDate>Fri, 26 Jan 2024 00:43:36 +0900</pubDate>
    </item>
    <item>
      <title>웹페이지 렌더링 방식(SSR vs CSR 비교)</title>
      <link>https://for-it-study.tistory.com/118</link>
      <description>&lt;div style=&quot;color: #000000; text-align: start;&quot; data-testid=&quot;conversation-turn-5&quot;&gt;
&lt;div&gt;
&lt;div data-message-id=&quot;dd54ef2c-b0de-4ceb-8c3a-26bf7173f258&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 웹의 기본 원리와 DOM 트리&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;DOM 트리의 중요성&lt;/b&gt;: 웹 페이지의 요소들이 객체 형태로 구성되어 있으며, JavaScript를 통해 이 요소들을 조작할 수 있습니다. 이를 통해 동적인 웹 페이지를 구현합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;CSSOM의 역할&lt;/b&gt;: CSSOM은 CSS 규칙들을 객체 형태로 변환하여, JavaScript를 통한 스타일 조작을 가능하게 합니다. 이는 DOM과 병합되어 최종적인 렌더 트리를 형성하며, 이를 바탕으로 페이지가 화면에 표시됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. 서버 사이드 렌더링(SSR) vs 클라이언트 사이드 렌더링(CSR)&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;SSR의 장점과 단점&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;장점: SEO 최적화, 빠른 첫 페이지 로딩, 초기 렌더링에 필요한 리소스가 적음.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단점: 각 페이지 요청마다 서버 부하 증가, 사용자 인터랙션에 대한 반응 속도가 느릴 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;CSR의 장점과 단점&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;장점: 사용자 인터랙션에 빠르게 반응, 페이지간 전환 시 서버 요청 감소, 풍부한 인터랙티브 경험 제공.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단점: 초기 로딩 시간이 길 수 있음, 검색 엔진 최적화(SEO)에 불리할 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. SPA(Single Page Application)와 MPA(Multi Page Application)&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;SPA의 구현&lt;/b&gt;: JavaScript를 사용하여 클라이언트 측에서 전체 페이지의 내용을 관리하고, 사용자와의 인터랙션에 따라 동적으로 내용을 변경합니다. 예를 들어, React, Angular, Vue.js 같은 현대적인 JavaScript 프레임워크와 라이브러리를 사용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;MPA의 특징&lt;/b&gt;: 각 페이지마다 별도의 HTML 파일을 가지고 있으며, 페이지 전환 시 전체 페이지가 새로 로드됩니다. 전통적인 웹사이트와 웹 애플리케이션에서 널리 사용됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4. React와 Next.js의 선택 기준&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;React 사용 적합 상황&lt;/b&gt;: 대규모의 상호작용이 많은 사용자 인터페이스를 구축할 때 적합합니다. 컴포넌트 기반 개발로 코드 재사용성과 테스트 용이성을 높일 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Next.js 사용 적합 상황&lt;/b&gt;: SEO가 중요하고 초기 로딩 시간을 최소화하고자 할 때 유리합니다. Next.js는 서버 사이드 렌더링을 쉽게 구현할 수 있게 해주며, &lt;b&gt;정적 사이트 생성(Static Site Generation)&lt;/b&gt; 기능도 제공합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;정적 사이트 생성 (Static Site Generation, SSG)&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;정적 사이트 생성은 웹 페이지의 HTML을 빌드 타임에 미리 생성하는 방식입니다. 이 방법은 동적으로 변화하는 데이터가 없는 웹사이트에 적합하며, 다음과 같은 이점을 제공합니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;속도와 성능&lt;/b&gt;: 정적 파일들은 CDN(Contents Delivery Network)을 통해 제공될 수 있으며, 이는 웹사이트의 로딩 속도를 크게 향상시킵니다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;보안&lt;/b&gt;: 서버사이드 코드 실행이 없기 때문에 보안 위험이 감소합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;확장성&lt;/b&gt;: 정적 파일들은 쉽게 복제되어 다양한 서버에 분산될 수 있어, 높은 트래픽에도 안정적으로 서비스를 제공할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;SEO 최적화&lt;/b&gt;: 정적 사이트는 검색 엔진이 쉽게 크롤링할 수 있어 SEO에 유리합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예를 들어, Next.js와 같은 프레임워크는 SSG 기능을&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;지원하여, 프로젝트 빌드 시 정적 HTML 파일들을 생성합니다. 이렇게 생성된 파일들은 서버사이드 프로세스 없이도 서비스될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;5. PWA(Progressive Web Apps)와 Service Worker&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;PWA의 추가적인 이점&lt;/b&gt;: 설치 없이 앱과 유사한 경험을 제공합니다. 홈 화면에 추가, 푸시 알림, 오프라인 지원 등의 기능으로 사용자 경험을 향상시킵니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Service Worker의 추가적인 기능&lt;/b&gt;: 네트워크 요청을 가로채 캐싱, 백그라운드 데이터 동기화, 푸시 알림과 같은 기능을 통해&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;Service Worker는 웹 브라우저가 백그라운드에서 실행하는 스크립트로, 웹 애플리케이션과 네트워크 사이에서 중개자 역할을 합니다. 주로 다음과 같은 기능을 제공합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #374151; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;캐싱&lt;/b&gt;: Service Worker는 방문한 웹사이트의 자산(HTML, CSS, JavaScript 파일 등)을 캐시에 저장할 수 있습니다. 이를 통해 오프라인 상태에서도 웹사이트를 볼 수 있게 하며, 빠른 로딩 시간을 제공합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;백그라운드 데이터 동기화&lt;/b&gt;: 사용자가 오프라인일 때 수행한 작업을 저장하고, 온라인 상태가 되면 서버와 동기화할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;푸시 알림&lt;/b&gt;: 웹 애플리케이션은 Service Worker를 통해 푸시 알림을 보낼 수 있습니다. 이를 통해 사용자가 웹 애플리케이션을 사용하지 않을 때도 사용자와 상호작용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot; data-state=&quot;closed&quot;&gt;&lt;/span&gt;
&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot; data-testid=&quot;conversation-turn-6&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>CS 지식</category>
      <category>CSR</category>
      <category>service worker</category>
      <category>SSG</category>
      <category>SSR</category>
      <category>프론트엔드</category>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/118</guid>
      <comments>https://for-it-study.tistory.com/118#entry118comment</comments>
      <pubDate>Thu, 25 Jan 2024 00:50:37 +0900</pubDate>
    </item>
    <item>
      <title>(JavaScript) eval()를 사용하면 안되는 이유</title>
      <link>https://for-it-study.tistory.com/117</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. eval()?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;eval()는 문자열 수식&amp;nbsp; 또는 문자열로 된 코드를 Javascript로 실행하는 메서드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 매개변수를 string 형식으로 받는다. 자바스크립트 표현식, 명령문, 또는 연속되는 다수의 명령문을 나타내는 문자열. 표현식은 이미 존재하는 객체의 변수나 속성을 포함할 수 있다. 매개변수로 받은 코드를 평가하여 얻은 값을 반환하고, 값이 없다면 undefined를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시)&lt;/p&gt;
&lt;pre id=&quot;code_1699877581730&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var x = 10;
var y = 20;
var result = eval(&quot;x * y&quot;); // 결과: 200
console.log(result);


var jsonStr = '{&quot;name&quot;: &quot;John&quot;, &quot;age&quot;: 30}';
var obj = eval(&quot;(&quot; + jsonStr + &quot;)&quot;);
console.log(obj.name); // 결과: John

var a = 10, b = 20;
var variableName = &quot;a&quot;;
console.log(eval(variableName)); // 결과: 10

var radius = 10;
var area = eval(&quot;Math.PI * radius * radius&quot;);
console.log(area);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 사용금지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1699877454887&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;eval() - JavaScript | MDN&quot; data-og-description=&quot;**eval()**은 문자로 표현된 JavaScript 코드를 실행하는 함수입니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bD3LIx/hyUuURS87B/NdvNheqKAeguoLVrVWhWI1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bD3LIx/hyUuURS87B/NdvNheqKAeguoLVrVWhWI1/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;eval() - JavaScript | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;**eval()**은 문자로 표현된 JavaScript 코드를 실행하는 함수입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. eval()은 인자로 받은 코드를 caller의 권한으로 수행하는 위험한 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 악의적인 영향을 받았을 수 있는 문자열을&lt;span&gt;&amp;nbsp;&lt;/span&gt;eval()로 실행한다면, 당신의 웹페이지나 확장 프로그램의 권한으로 사용자의 기기에서 악의적인 코드를 수행하는 결과를 초래할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 또한, 제삼자 코드가&lt;span&gt;&amp;nbsp;&lt;/span&gt;eval()이 호출된 위치의 스코프를 볼 수 있으며, 이를 이용해 비슷한 함수인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function&quot;&gt;Function&lt;/a&gt;으로는 실현할 수 없는 공격이 가능합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1b1b1b; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4. 또한 최신 JS 엔진에서 여러 코드 구조를 최적화하는 것과 달리&lt;span&gt;&amp;nbsp;&lt;/span&gt;eval()은 JS 인터프리터를 사용해야 하기 때문에 다른 대안들보다 느립니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1b1b1b; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;5. 추가로, 최신 JavaScript 인터프리터는 JavaScript를 기계 코드로 변환한다. 즉, 변수명의 개념이 완전히 없어집니다. 그러나&lt;span&gt;&amp;nbsp;&lt;/span&gt;eval을 사용하면 브라우저는 기계 코드에 해당 변수가 있는지 확인하고 값을 대입하기 위해 길고 무거운 변수명 검색을 수행해야 한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1b1b1b; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;6. 또한&lt;span&gt;&amp;nbsp;&lt;/span&gt;eval()을 통해 자료형 변경 등 변수에 변화가 일어날 수 있으며, 브라우저는 이에 대응하기 위해 기계 코드를 재작성해야 합니다. 그러나, &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function&quot;&gt;window.Function&amp;nbsp; 등&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;eval보다 훨씬 나은 대안이 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1b1b1b; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1b1b1b; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 아래 예시는 eval()는&amp;nbsp; 지역스코프를 벗어나 접근하고 수정을 할 수 있는 모습을 보여주고 , 아래 Function은 스코프 범위를 벗어나는 모습을 보여주지 않는다.&lt;/p&gt;
&lt;pre id=&quot;code_1699879656869&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(function () {
	var a = 1;
	eval('a = 3; console.log(a);'); // 3

	console.log(local); // 3
})();


(function () {
	var a = 1;
	Function('console.log(typeof a);')(); // undefined
})();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 보안문제 예시:&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1699880118038&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var example = &quot;var example = function() {
  while (true) {
    alert('해킹당했습니다!');
    // 루프를 중단하기 위한 조건이나 중단 메커니즘이 없으므로 이 코드는 브라우저를 멈출 수 있습니다.
  }
};&quot;;
eval(example); // 사용자가 입력한 함수를 사용하게 되면서 &quot;해킹당했습니다!&quot;가 무한으로 출력되는 무한루프가 걸린다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Json으로 문자열을 자바스크립트 코드로 변경&lt;/p&gt;
&lt;pre id=&quot;code_1699880220148&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var jsonString = '{&quot;name&quot;: &quot;hun&quot;, &quot;age&quot;: 30}';
var userObject = JSON.parse(jsonString);
console.log(userObject.name); // &quot;hun&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;mdn문서&quot; href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;mdn문서&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/HTML, CSS, JavaScript</category>
      <category>eval 대체</category>
      <category>eval 보안</category>
      <category>eval 사용금지</category>
      <category>eval()</category>
      <category>Javascript</category>
      <author>싯타마</author>
      <guid isPermaLink="true">https://for-it-study.tistory.com/117</guid>
      <comments>https://for-it-study.tistory.com/117#entry117comment</comments>
      <pubDate>Mon, 13 Nov 2023 22:05:38 +0900</pubDate>
    </item>
  </channel>
</rss>