반응형

돌아온 혼공단 시간~!
1주 차 숙제를 제출하고 나중에 패들릿에 들어가 봤더니
세상에 족장님이 모든 숙제에 하나하나 다 코멘트를 남기고 있었다
혼공단 대상 책이 여러 개라 한두 명이 아닐 텐데 감덩,,,
우수혼공족 선정에 더 감덩,,, 🥹🥹
내 공부하는데 간식까지 챙겨준다?! 혼공단 외 안헤?! 
네트워크 완주하고 여름에 14기로 다시 돌아오게 씁니다 🫡

아무튼 혼자 공부하는 네트워크 2주 차 커리큘럼은 챕터 2입니다.
추가 숙제는 집에 있는 케이블을 찾아서 해석하기예요
흥미로운 걸,,,?

챕터 2는 물리 계층과 데이터 링크 계층이래요.
저번에 OSI 7 계층 공부할 때 하단부에 있던 애들인데
기억나는 사람~!~! 난 아님 🙅🏻‍♀️

<목차>
Chapter 1. 컴퓨터 네트워크 시작하기
Chapter 2. 물리 계층과 데이터 링크 계층
Chapter 3. 네트워크 계층
Chapter 4. 전송 계층
Chapter 5. 응용 계층
Chapter 6. 실습으로 복습하는 네트워크
Chapter 7. 네트워크 심화

그럼 2주 차 공부를 시작해 볼까요

# 이더넷 Ethernet

물리 계층과 데이터 링크 계층은 이더넷이라는 공통된 기술이 사용되어 서로 밀접하게 연관되어 있다. 이더넷은 현대 유선 LAN 환경에서 가장 대중적으로 사용되는 기술이다. 컴퓨터끼리 정보가 오가려면 케이블과 같은 통신 매체가 필요한데, 이더넷 Ethernet은 다양한 통신 매체 규격들과 송수신되는 프레임의 형태, 주고받는 방법 등을 정의한 네트워크 기술이다. 현재 이더넷 관련 기술은 IEEE 802.3이라는 이름으로 표준화가 되어 있다.

# 통신 매체 표기 형태

이더넷 표준 규격에 따라 구현된 통신 매체는 다음과 같은 형태로 표기한다.

전송속도 BASE - 추가 특성
숫자만 표기 = Mbps 속도
숫자+G = Gbps 속도
베이스밴드BASEband의 약자
비트 신호로 변환된 데이터를
통신 매체로 전송하는 방법인
변조 타입을 의미
전송 가능한 최대 거리나
물리 계층 인코딩 방식,
비트를 전송할 레인 수와 같은
통신 매체의 특성 명시
100BASE-T = 100Mbps
10GBASE-T = 10Gbps
이더넷은 대부분 베이스밴드 방식 사용 1000BASE-CX = 물리 계층 인코딩 방식
1000GBASE-LR = 레인(전송로) 수

# 통신 매체의 종류

추가 특성에 적힌 C, T, S, L이라는 글자는 가장 대중적인 통신 매체의 종류이다.

- C = 동축 케이블
- T = 트위스티드 페어 케이블
- S = 단파장 광섬유 케이블
- L = 장파장 광섬유 케이블

출처 : 혼공네트 유튜브 강의 내 장표 캡쳐함

 지금까지 공부한 내용을 토대로 통신 매체 표기 형식을 해석해 본다면,

- 10BASE-T 케이블은 10Mbps 속도를 지원하는 트위스티드 페어 케이블
- 1000BASE-SX 케이블은 1000Mbps 속도를 지원하는 단파장 광섬유 케이블이다.

이더넷 표준과 이를 기반으로 하는 통신 매체를 연결해서 본다면 아래와 같다고 한다.
다만 이더넷 표준과 통신 매체 표기가 항상 일대일 대응은 아니라고 하니 참고만 하자!

표준 규격 통신 매체 해석
IEEE 802.3i 10BASE-T 10Mbps 속도를 지원하는 트위스티드 페어 케이블 (초기 이더넷)
IEEE 802.3u 100BASE-TX 100Mbps 속도를 지원하는 트위스티드 페어 케이블 (고속 이더넷)
IEEE 802.3ab 1000BASE-T 1000Mbps 속도를 지원하는 트위스티드 페어 케이블 (기가비트 이더넷)
IEEE 802.3bz 2.5GBASE-T / 5GBASE-T 2.5Gbps 혹은 5Gbps 속도를 지원하는 트위스티드 페어 케이블
IEEE 802.3an 10GBASE-T 10Gbps 속도를 지원하는 트위스티드 페어 케이블
IEEE 802.3z 1000BASE-SX / 1000BASE-LX 1000Mbps 속도를 지원하는 단파장 혹은 장파장 광섬유 케이블
IEEE 802.3ae
10GBASE-SR / 10GBASE-LR 10Gbps 속도를 지원하는 단파장 혹은 장파장 광섬유 케이블

💡데이터 신호 속도(BPS)
  >> 초당 전송 가능한 비트 수 (Bit Per Second)
  >> 데이터 신호 속도(BPS) = 변조 속도(baud) * 단위 펄스 당 변조된 비트 수
  >> 단위 펄스를 구성하는 bit 수에 따른 이름으로 디비트(2bit), 트리비트(3bit), 쿼드비트(4bit)

# 데이터 링크 계층의 이더넷 프레임

현대 유선 LAN 환경은 대부분 이더넷을 기반으로 구성되어 있다. 호스트가 데이터 링크 계층에서 주고받는 프레임 형식도 정해져 있는데, 이를 이더넷 프레임이라고 한다. 이더넷 프레임은 상위 계층으로부터 받아들인 정보에 헤더와 트레일러를 추가하는 캡슐화 과정을 통해 만들어진다. 반대로 수신지 입장에서는 프레임의 헤더와 트레일러를 제거한 뒤 상위 계층으로 올려 보내는 역캡슐화 과정을 거친다.

이더넷 프레임 헤더는 기본적으로 프리앰블, 송/수신지 MAC 주소, 타입/길이로 구성되고, 페이로드는 데이터, 트레일러는 FCS로 구성된다.

헤더 페이로드 트레일러
프리앰블 수신지 MAC 주소 송신지 MAC 주소 타입/길이 데이터 FCS
8바이트 6바이트 6바이트 2바이트 16~1500바이트 4바이트

# 프리앰블 Preamble = 송수신지 간 동기화를 위해 사용
프리앰블은 이더넷 프레임의 시작을 알리는 8바이트(64비트) 크기의 정보. 프리앰블의 첫 7바이트는 10101010 값을 가지고, 마지막 바이트는 10101011 값을 가진다. 수신지는 프리앰블을 통해 이더넷 프레임이 오고 있음을 알 수 있다.

# 송/수신지 MAC 주소 (aka 물리적 주소) = LAN 내의 송/수신지를 특정
MAC 주소는 네트워크 인터페이스마다 부여되는 6바이트(48비트 - 16진수 12자리) 길이의 주소. 일반적으로 고유하고, 변경되지 않는 주소로써 네트워크 인터페이스마다 부여된다.

# 타입/길이
타입/길이 필드에는 타입 혹은 길이가 올 수 있다. 필드에 명시된 크기가 1500(16진수 0D5C) 이하일 경우에는 프레임의 크기(길이)를 나타내는 데 사용되고, 1536(16진수 0600) 이상일 경우에는 타입을 나타내는데 사용된다.
타입이란 이더넷 프레임이 어떤 정보를 캡슐화했는지 나타내는 정보이다. 대표적으로 상위 계층에서 사용된 프로토콜의 이름을 명시한다. IPv4 프로토콜이라면 0800 타입, IPv6라면 86DD, ARP라면 0806과 같이 표기된다고 한다.

# 데이터
데이터는 상위 계층에서 전달받거나 상위 계층으로 전달해야 할 내용을 담고 있다. 네트워크 계층의 데이터와 헤더를 합친 PDU가 이곳에 포함된다. 크기는 46~1500바이트 사이어야 한다. 만약 그 이하의 데이터라면 크기를 맞추기 위해, 46바이트 이상이 될 때까지 0으로 채우는데, 이를 패딩 Padding 이라고 한다.

# FCS (Frame Check Sequence) = 송수신지 CRC 값을 비교해 오류 검출
FCS는 수신한 이더넷 프레임에 오류가 있는지 확인하기 위한, 오류 검출용 필드이다. 이 필드에는 CRC (Cyclic Redundancy Check) 순환 중복 검사라고 불리는 오류 검출용 값이 들어간다.

송신지는 프리앰블을 제외한 나머지 필드 값들을 바탕으로 CRC 값을 계산한 후, 이 값을 FCS 필드에 명시한다.  수신지는 수신한 프레임에서 프리앰블과 FCS 필드를 제외한 나머지 필드 값들을 바탕으로 CRC 값을 계산하고, 이 값을 FCS 필드 값과 비교한다.
이때 비교 값이 일치하지 않으면 프레임에 오류가 있는 것으로 보고 해당 프레임을 폐기한다.

전에 IEEE 802 표준 관련 문제가 나왔었는데
틀린 기억이 있어서 공부하는 김에 추가로 정리하고 넘어가려고 합니다.
진짜로 혼자 공부하는 지나가는 코너라 접어둘게요

더보기

# IEEE 802 표준

802.2 논리링크제어(LLC) 계층의 이행에 관해 명기한 표준 프로토콜 
802.3 이더넷 표준. CSMA/CD 액세스 제어 방식 사용
802.4 토큰버스 액세스 제어 방식 사용
802.5 토큰 링 액세스 제어 방식 사용
호스트들이 링 형태로 연결되어, 토큰을 가지고 있어야만 네트워크 내 다른 호스트에게 메시지 전송 가능
802.6 도시권 통신망 규격 (MAN)
802.11a 직교 주파수 분할 다중화(OFDM) 방식을 사용하여 최대 54 Mbps의 전송률 제공 / 5 GHz 대역
전파 파장이 짧아 신호 범위가 짧음 = 고속 무선 LAN 구축을 원하는 기업용 네트워크에서 주로 사용

802.11b Wi-Fi. 무선 LAN 규격으로 CSMA/CA 액세스 제어 방식
최대 11 Mbps의 전송률 제공 / 2.4 GHz 대역
802.11g 최대 54 Mbps의 전송률 제공 / 2.4 GHz 대역
OFDM 방식을 사용하여 채널 중첩 문제 해결
802.11i Wi-Fi의 암호화 국제 표준. 802.11의 WEP를 보완한 WPA(Wi-Fi Protected Access) 무선 암호화 방식 사용 
802.11n 최대 600 Mbps의 전송률 제공 / 2.4 & 5 GHz 대역
MIMO 방식을 사용하여 전송 신호를 다중화, 전송 속도 향상
802.11ac Wi-Fi 5. 5 GHz 대역
802.11ax Wi-Fi 6 = HEW(High Efficiency Wireless). 최대 10 Gbps의 속도 지원
다중 사용자-다중 입력 다중 출력(MIMO)
802.15 소규모 무선랜 기술 Wireless PAN
802.15.1 >> 블루투스
802.15.4 >> 지그비 ZigBee
802.16 WiMax. Broadband Wireless Access
802.16e (Mobile) Broadband Wireless Access

 

# NIC와 케이블

# NIC (Network Interface Controller)

호스트와 유무선 통신 매체를 연결하고, MAC 주소가 부여되는 네트워크 장비를 의미. NIC는 통신 매체에 흐르는 신호와 프레임을 상호 변환하는 역할을 한다. 호스트가 네트워크를 통해 송수신하는 정보는 NIC를 거치기에, 네트워크 인터페이스 역할을 수행한다고도 한다. NIC는 MAC 주소를 통해 자신의 주소와, 수신되는 프레임의 수신지 주소를 인식한다. 그래서 어떤 프레임이 도착했을 때 자신과 관련 있는 프레임만 수신할 수 있는 것이다.

# 트위스티드 페어 케이블

구리 선으로 전기 신호를 주고받는 통신 매체. 케이블 본체와 케이블의 연결부인 커넥터로 구성되고, 본체 내부는 케이블 이름처럼 구리 선이 두 가닥씩 꼬여 있다. 구리선에 전기 신호를 왜곡시킬 수 있는 간섭인 노이즈가 생길 수 있어, 구리 선을 철사나 포일로 감싸 보호하는 경우가 많은데 이를 차폐(실드)라고 한다. 세 종류로 구분하는데,

- U : 실드 없이 구리선만
- S : 브레이드 실드로 구리선을 보호
- F : 포일 실드로 구리 선을 보호

실드에 따라 케이블의 종류를 나눠서 표기한다. 보통 __/_TP 형태로 표현한다. 예를 들면,

- S/FTP : 케이블 외부는 브레이드 실드로 보호, 내부의 꼬인 각 구리선 쌍은 포일 실드로 보호
- SF/FTP : 케이블 외부는 브레이드/포일 실드로 보호, 내부의 구리선 쌍은 포일 실드로 보호
- U/UTP : 아무것도 감싸지 않은 케이블을 의미

트위스티드 페어 케이블은 카테고리에 따라서도 구분할 수 있다. 카테고리는 케이블 성능 등급을 구분하는데, 높은 카테고리일수록 성능이 좋다. 아래는 인터넷에서 찾은 표인데 숫자가 올라갈수록 전송 속도나 지원 대역폭이 커지는 것 볼 수 있다.

출처 : www.techyshop.co.ke

# 광섬유 케이블

빛(광신호)을 이용해 정보를 주고받는 케이블. 상대적으로 속도가 빠르고, 노이즈 간섭도 적으며, 먼 거리도 전송이 가능하다. 그래서 대륙 간 네트워크 연결에도 사용된다. 동일하게 케이블 본체와 커넥터로 이루어져 있는데, 커넥터 종류는 LC, SC, FC, ST가 있다.

출처 : 뷰웍스 머신비전 블로그 visionblog.vieworks.com

그리고 케이블 본체 내부는 광섬유로 구성되어 있는데, 광섬유를 확대해서 보면 중심부의 코어 core, 코어를 둘러싸고 빛이 코어 안에서만 흐르도록 가둬 두는 클래딩 cladding, 이 둘을 뒤덮어 수분과 부식으로부터 보호하는 재킷 jacket 의 구조를 가지고 있다.

참고용으로 더 자세한 특징들을 나열하자면,

1) 대용량 전송이 가능
2) 부피가 작고 무게가 가벼워 설치 및 보수가 용이
3) 전송손실이 적고, 전자파 영향이 적어 안정된 통신 및 누화 방지
4) 선로상 전송은 일정 거리마다 신호 재생을 해주는 리피터가 필요함
5) 효율적인 보안이 가능
6) 분기가 어렵고, 접속 부분에서 정보 손실 및 오류 발생 가능성이 높음

광섬유 케이블은 코어의 지름에 따라 싱글 모드 광섬유 케이블(SMF)와 멀티 모드 광섬유 케이블(MMF)로 나뉜다.

싱글 모드 광섬유 케이블은 코어 지름이 8~10μm(마이크로 미터)로 아주 작아 빛의 이동 경로가 하나이며, 장파장의 빛을 사용한다. 신호 손실이 적기에 장거리 전송에 적합하나, 멀티 모드에 비해 비싸다는 단점이 있다. 대표적인 규격으로는 1000BASE-LX, 10GBASE-LR이 있다. (L은 장파장을 의미)

멀티 모드 광섬유 케이블은 코어 지름이 50~63.5μm(마이크로 미터)로 빛이 여러 경로로 이동할 수 있고, 단파장의 빛을 사용한다. 상대적으로 신호 손실이 클 수 있어, 근거리 전송에 주소 사용한다. 대표적인 규격으로는 1000BASE-SX, 10GBASE-SR이 있다. (S은 단파장을 의미)


이제 본격적으로 물리 계층과 데이터 링크 계층에서 사용하는 장비들을 살펴볼 예정이다.
그전에 물리 계층과 데이터 링크 계층에 대해 잠시 복습하고 지나가고자 한다.

계층명 이번 주 포인트 지난 주 복습
데이터 링크 계층 NIC
스위치(전이중 통신+VLAN)
- 네트워크 내 주변장치 간 정보를 올바르게 주고받기 위한 계층
- MAC 주소 체계를 통해 네트워크 내 송수신지를 특정
- 물리적으로 연결된 인접한 개방 시스템들 간 신뢰/효율적 정보 전송을 위해 시스템 간 연결 설정과 유지 및 종료 담당
- 오류 검출 및 회복을 위한 오류 제어, 송수신측 속도 차이 해결을 위한 흐름 제어, 프레임 순서적 전송을 위한 순서 제어 기능을 가짐
- 전송 단위인 프레임에 물리적 주소를 부여함
- 장비로는 랜카드, 브리지, 스위치
- 관련 프로토콜로는 HDLC, LAPB, LLC, MAC, LAPD, PPP, 이더넷 등
물리 계층 트위스티드 페어 케이블
광섬유 케이블
허브(반이중 통신+CSMA/CD)
- OSI 모델 최하단 계층
- 0과 1로 표현되는 비트 신호를 주고 받음 (전송단위가 Bit)
- 통신 케이블로 데이터를 전송하는 물리적 장비에 필요한 기계/전기/기능/절차적 특성에 대한 규칙을 정의
- 장비로는 통신 케이블, 리피터, 허브
- 관련 프로토콜로는 RS-232C, X.21 등

물리 계층에는 주소 개념이 없다.
물리 계층 장비는 송수신 정보에 대한 어떠한 조작(송수신 내용 판단/변경)을 하지 않는다.

반면 데이터 링크 계층에는 MAC 주소 개념이 있다.
그래서 데이터 링크 계층부터의 장비들은 주소를 바탕으로
송수신 정보 내용을 판단하고 조작할 수 있다.

# 허브 Hub

물리 계층의 허브는 여러 대의 호스트를 연결하는 장치이다. 커넥터를 연결할 수 있는 포트를 통해 호스트와 연결된 통신 매체를 연결할 수 있다.

허브는 전달받은 신호를 다른 모든 포트로 다시 내보낸다. 주소 개념이 없기에 전달받은 신호를 송신지를 제외한 모든 포트에 일괄로 다시 내보낸다. 허브를 통해 신호를 받은 호스트가 데이터링크 계층에서 패킷의 MAC 주소를 확인하고 관련 없을 시 폐기한다.

허브는 반이중 모드 half duplex 로 통신한다. 무전기와 같이 송수신을 번갈아 가면서 하는 방식으로, 한쪽에서 메시지를 보내면 다른 쪽은 수신만 가능하다.

만일 다른 호스트가 기다리지 않고 신호를 보내면 충돌(콜리전)이 생기게 된다. 그래서 허브 하나에 같이 연결되어 충돌이 발생할 수 있는 영역을 콜리전 도메인이라고 한다. 콜리전 도메인 범위가 클수록(허브에 호스트가 많이 연결되어 있을수록) 충돌 가능성이 높아진다.

이러한 충돌 문제를 해결하기 위한 프로토콜이 CSMA/CD이다. Carrier Sense Multiple Access with Collision Detection의 약자로,

1) Carrier Sense, 캐리어 감지 : 메시지를 보내기 전 현재 네트워크 상에 전송 중인 것이 있는지를 먼저 확인
2) Multiple Access, 다중 접근 : 복수의 호스트가 네트워크에 접근하려는 상황을 의미
3) Collision Detection, 충돌 검출 : 충돌 발생 시 이를 감지하고 전송 중단, 충돌 발생 사실을 알리는 잼 신호 전송 및 임의 시간 동안 대기로 구성되어 있다.

요약하자면 호스트들은 메시지 전송 전에 1) 현재 네트워크 상태를 확인하고, 2) 아무도 전송하지 않고 있다면 메시지를 전송한다. 3) 부득이하게 다수의 호스트가 전송을 시도해 충돌이 발생했다면 잠시 대기했다가 다시 전송한다. 

# 스위치 Switch

데이터 링크 계층의 네트워크 장비이다. 여러 포트에 호스트를 연결한다는 점은 허브와 유사하다. 하지만 전이중 모드 full duplex 로 통신한다.

스위치는 MAC 주소 학습을 하는데, 포트와 연결된 호스트 MAC 주소 간 연관 관계를 메모리에 표 형태(MAC 주소 테이블)로 기억한다. 그래서 MAC 주소를 이용해, 특정 MAC 주소를 가진 호스트에만 프레임을 전달할 수 있다. MAC 주소 학습은 스위치의 세 가지 기능인 1) 플러딩, 2) 포워딩과 필터링, 3) 에이징 을 통해 이루어진다.

스위치는 처음에는 호스트들의 MAC 주소와 연결된 포트의 연관 관계를 알지 못한다.
호스트 A에서 처음으로 프레임을 보내면, 스위치는 프레임 내 정보를 바탕으로 호스트 A의 MAC 주소와 연결 포트 정보를 저장한다.
그리고 허브처럼 송신지 포트를 제외한 모든 포트로 프레임을 전송하는 플러딩 Flooding을 수행한다.
그럼 프레임을 전달받은 호스트 중 해당하는 호스트(예시로 C)만 다시 응답 프레임을 전송한다. 스위치는 이 정보도 또 기록한다.
스위치는 이제 호스트 A와 C의 정보를 알고 있다. 이제 호스트 A가 C에게 프레임을 전송하면,
스위치는 해당 정보가 호스트 C가 연결된 포트로만 가도록 나머지 포트를 제외하는 필터링 Filtering을 하고, 해당 포트로 프레임을 실제로 내보내는 포워딩 Forwarding을 수행한다.
만약 MAC 주소 테이블에 등록된 특정 포트에서 일정 시간 동안 프레임을 전송받지 못했다면, 해당 항목을 삭제하는 에이징 Aging을 수행하여 테이블을 관리한다.

출처 : 혼공네트 유튜브 강의 내 장표 캡쳐함

스위치는 가상의 LAN을 만드는 VLAN 기능을 지원한다. VLAN을 구성하면 한 대의 물리적 스위치를 가지고, 여러 대의 스위치를 운영하는 것처럼 논리적 단위로 LAN을 구성할 수 있다. VLAN을 구성하는 방법은 포트 기반과 MAC 기반으로 나뉜다.

# 포트 기반 VLAN
스위치의 포트가 VLAN을 결정하는 방식이다. 사전에 특정 포트에 VLAN을 할당하고 해당 포트에 호스트를 연결하여 VLAN에 포함시키는 형태다. 하지만 포트 기반은 포트 수가 부족해질 수 있다는 단점이 있다. 스위치를 계속 추가해서 연결해 확장할 수는 있지만 비효율적이고 한계가 있다.
이를 조금이나마 개선하기 위한 방법이 VLAN 트렁킹이다. 트렁크 포트를 따로 두어 스위치들을 효율적으로 연결하여 확장하는 방식이다. 이 때는 어떤 VLAN에 속하는지 식별하기 위한 정보를 추가한 확장된 이더넷 프레임 802.1Q를 사용한다. 이더넷 프레임 헤더 속에 32비트 크기의 VLAN 태그를 추가한 것이다.

헤더 페이로드 트레일러
프리앰블 수신지 MAC 주소 송신지 MAC 주소 VLAN 태그 타입/길이 데이터 FCS
8바이트 6바이트 6바이트 32비트 2바이트 16~1500바이트 4바이트

# MAC 기반 VLAN
사전에 설정된 MAC 주소를 따라 VLAN을 결정하는 방식이다. 송수신하는 프레임 속 주소를 보고 속할 VLAN에 포함시키는 방식이다.

출처 : 혼공네트 유튜브 강의 내 장표 캡쳐함


이렇게 해서 공부를 마쳐봤습니다
이제 숙제를 해볼까요

# 기본 숙제📚

# (p87) 확인문제 2번 "이더넷 프레임에서 ㄱ, ㄴ, ㄷ에 들어갈 올바른 단어를 보기에서 찾아서 빈칸을 채워보세요"
답 : ㄱ은 프리앰블, ㄴ은 송신지 MAC 주소, ㄷ은 FCS
프리앰블은 이더넷 프레임의 시작을 알리는 정보로 프레임 헤더의 맨 앞에 온다. FCS는 수신한 이더넷 프레임의 오류 여부를 확인하기 위한 오류 검출용 필드다. 자세한 건 위쪽에 표로 정리한 프레임 구조를 다시 참고하시라

# (p111) 확인문제 4번 "CSMA/CD와 관련해 서로 맞는 용어끼리 선으로 이어 보세요"
답 : CS - 캐리어 감지, MA - 다중 접근, CD - 충돌 검출
CSMA/CD의 풀 네임을 제대로 이해하고 있다면 바로 풀 수 있는 문제다. Carrier Sense Multiple Access with Collision Detection인데, Carrier Sense(캐리어 감지) + Multiple Access (다중 접근) with Collision Detection(충돌 검출)로 동작하는 프로토콜이다.

추가 숙제는 집에 케이블이 없는 관계로 생략합니다
예전에 다 정리해서 버렸는지 하나도 없다^^

어쨌든 이번 주도 공부 끝

반응형
반응형

오늘의 문제는 레벨 2에 해당하는 <방문 길이>인데요.
(문제 출처 : 프로그래머스 https://school.programmers.co.kr/learn/courses/30/lessons/76502)

프로그래머스는 블로그 게재 시 문제 여지가 있어
자세한 내용 없이 문제 제목과 링크로 대체합니다.

대괄호, 중괄호, 소괄호로 구성된 문자열이 주어질 때
이 문자열을 왼쪽으로 한 칸씩 옮기면서(회전하면서)
올바른 괄호 문자열이 만들어지는 횟수를 찾는 문제였다.

( ) { } [ ] , ( { } ) [ ] 와 같이
괄호들이 순서대로 잘 닫겨 있다면
올바른 괄호 문자열이다.

옮긴 칸수 문자열 올바른지 여부
0 ( ) { } [ ]
1 ) { } [ ] ( 아니오
2 { } [ ] ( )
3 } [ ] ( ) { 아니오
4 [ ] ( ) { }
5 ] ( ) { } [ 아니오

올바른지 여부에 "네"가 총 3개니까
결과값으로 3을 리턴하면 되는 형태

1) 문자열을 왼쪽으로 하나씩 미는 반복문이 필요하고

2) 문자열 내부를 돌면서 올바른지 여부를 확인하는 반복문도 필요했다
반복문 내부에는 스위치문과 스택을 활용해
2-1) 열린 괄호들이면 push하고
2-2) 닫힌 괄호들이면, 스택이 비지 않았다는 전제 하에
- pop한 열린 괄호가 지금 괄호와 짝인 경우에만
올바른 문자열인지 판단하는 r 값을 true로 바꿔주기로

1) 스택이 비어 있고 r 값이 true라면
올바른 문자열이니까 answer의 값을 하나 올려준다
1) 마지막으로 문자열을 왼쪽으로 미는 로직을 추가했다

코드로 보면 이런 느낌이에요.
중복도 있고 조금 더 예쁘게 짤 수 있을 것 같기는 한데
일단 풀었다에 의의를 두는 코드라죠^^

import java.util.*;

class Solution {
    public int solution(String s) {
        int answer = 0;
        String sc = s;
        int size = sc.length();
        
        for (int i=0; i<size; i++){ // 문자열을 왼쪽으로 미는 반복문
            // System.out.println("현재 문자열은 "+sc);
            
            boolean r = false;
            Stack<Character> stack = new Stack<>();
            
            // 문자열 내부를 검사하는 반복문
            for (int j=0; j<size; j++){
                char c = sc.charAt(j);
                switch (c){
                    case '(':
                        stack.push(c); break;
                    case '{':
                        stack.push(c); break;
                    case '[':
                        stack.push(c); break;
                    case ')':
                        if (stack.isEmpty() == false && stack.pop() == '(') {
                            r = true;}
                        else { r = false;} break;
                    case '}':
                        if (stack.isEmpty() == false && stack.pop() == '{') {
                            r = true; }
                        else { r = false; } break;
                    case ']':
                        if (stack.isEmpty() == false && stack.pop() == '[') {
                            r = true; }
                        else { r = false; } break;
                }
                // System.out.println(j + "번 자리에서 " + r);
            }
            if (stack.isEmpty() == true && r == true) {
                // 스택이 비어있고 true 라면 해당 회차는 올바름
                    answer++;
                // System.out.println(i+"칸 움직인 후에 " + answer);
            }
            if (1<size){
                String temp = sc.substring(1);
                char back = sc.charAt(0);
                sc = temp + String.valueOf(back);
            }
            }
        
        return answer;
    }
}

중간중간 결과물이 어떻게 나올지 궁금해서
온라인 컴파일러를 활용해 출력해봤다.
하다보니 스위치문에서 브레이크/컨티뉴가 헷갈렸거든요
(사실 아직도임 ㅋ)

내 의도대로 올바른 회차에만
answer 변수를 카운트하는 모습까지 확인된다.

정답 코드도 공부하자면

내가 스위치문으로 구성한 올바른 코드 확인 로직을 해쉬맵으로 구현했다.

HashMap<Character, Character> map = new = HashMap<>();
map.put(')', '(');

그리고 문자열을 왼쪽으로 미는 대신에
문자열 2개를 이어 붙이고
시작 인덱스를 하나씩 뒤로 보내는 방법을 택했다.
( ) { } [ ] ( ) { } [ ]

해시맵 안에 인덱스에 해당하는 모양이 없다면
열리는 괄호라는 의미라 스택에 집어 넣는다.

모양이 있고 스택이 비어 있지 않다면
스택에서 꺼낸 결과와 해시맵을 비교해서
짝이 맞지 않으면 다음 문자열을 확인하러 보낸다

위에서 중단하고 넘어가지 않았고
스택도 비어 있다면
올바른 괄호 문자열이다.

처음에는 막막했는데
책 기준 10번 문제 정도 오니까
시간이 조금 오래 걸리고
내 로직이 정답과는 많이 다르긴 해도
하나씩 풀 수는 있다
소소하게 작은 것부터 이뤄나가기👊

반응형
반응형

오늘의 문제는 "코딩 테스트 합격자 되기:자바 편"에 있는
10진수를 2진수로 변환하기 이다.
저자가 직접 출제한 문제라
프로그래머스 같은 곳에 돌려서 결과 확인이 어렵더라.
프로그래머스 아닌 문제도 있었으면 좋겠다 하긴 했는데
이 점은 좀 아쉬움...
하지만 자료구조별로 잘 정리되어 있고
문제마다 분석하는 방법과 푸는 흐름을 잘 설명해 줘서
코테 입문자에게는 따라서 공부하기가 좋다.
추천합니다!

그럼 문제부터 보겠습니다.
10진수를 입력받아 2진수로 변환하는 함수를 구현하라는 문제입니다.
10진수를 2진수로 변환하는 법은 간단하죠
2로 나눠서 남은 나머지들을 뒤에서부터 적으면 된다죠

출처 : 도서 149p

일단 내가 푼 코드는 이렇다. 

import java.util.*;
import java.lang.*;
import java.io.*;

// The main method must be in a class named "Main".
class Main {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        int v = 27;

        while( v > 0 ){
            stack.push(v%2);
            v = v/2;
        }

        while(!stack.isEmpty()){
            System.out.print(stack.pop());
        }
    }
}

따로 검사받을 곳이 없어 온라인 컴파일러에서 작성해서 돌렸다죠
자바 온라인 컴파일러 검색하면 여러 개 나오는데
내가 사용한 건 여기 https://www.mycompiler.io/ko/new/java

 

새 Java 프로그램 만들기 - 마이컴파일러 - myCompiler

실행 코드 코드 저장 기존 코드를 유지하시겠습니까? 에디터에 코드가 있는 동안 언어를 전환하려고 합니다. 이를 유지하려면 “기존 코드 유지”를 선택합니다. 예제로 바꾸려면 “예제로 바

www.mycompiler.io

맨 처음에 while 문에서
v가 1이면 빠져나오게 했었는데
생각해 보니 마지막 1까지 들어가야
제대로 된 2진수라서 그냥 0보다 클 때로 수정

정답은 책에 쓰여 있는 링크나 QR코드 통해
저자의 깃헙에 들어가서 확인할 수 있다.

그냥 컴파일러에 돌려야 하는지라
나는 10진수를 바로 출력해 버리는 형태를 썼는데

책에서는 StringBuilder 연산을 사용한다.
String에서 붙이는 연산을 하면
시간 복잡도 측면에서 성능이 좋지 않다고 하네(참고)

StringBuilder sb = new StringBuilder();

while (스택에 내용이 있을 때){
	sb.append(스택에서 꺼내서 붙이기)
    }
    
return sb.toString();

 

푸는 로직 떠올리는 건 생각보다 금방 하겠는데
그걸 자바의 여러 기능들을 써서 구현하는 건...
내가 너무 오래간만에 코드를 잡아서 아직은 무리 ㅋ
이 책 다 풀면 나아지겠지~
매일은 무리지만 꾸준히 가보자고~

반응형
반응형

세상 바뀌는 속도를 따라가고자
급하게 인공지능 지식 쌓아 올리기 프로젝트를 진행하고 있다.
프로젝트하니까 거창해 보이는데 이번이 두 번째 결과물이다^^
바로 "AI 리터러시: 인공지능 필수 지식부터 완벽 활용까지"

출처 : 네이버 도서 검색

연말에 서점에 들렀다가 신간 코너에서 발견한 책이다.
궁금해서 펼쳐봤는데 시중에 나와 있는 생성형 AI들을
용도별로 구분해서 자세하게 소개해주고 있더라.
챗지피티 알면 다행인 내가 딱 필요로 하던 거잖아...!
그렇게 읽게 되었습니다.

출처 : 도서 표지 후면

참고로 지난번에는 이 책을 읽었는데요.
2024.12.27 - [공부/IT] - [책 리뷰] 비전공자도 이해할 수 있는 AI 지식
혹시 저처럼 인공지능 공부에 관심 있으신 분은
AI 리터러시를 먼저 본 후에 읽는 걸 추천합니다
여기서 간략하게 소개하는 개념을 조금 더 깊게 다루는 느낌입니다

아무튼 각설하고 목차의 대제목만 먼저 살펴볼게요

파트 1: 이제는 모두의 AI 리터러시
파트 2: 누구나 쉽게 이해하는 인공지능 기술
파트 3: AI 리터러시 업그레이드 생성형 AI 서비스 가이드
파트 4: '나' 맞춤 AI 리터러시

이렇게 구성되어 있는데
순서대로 어떤 내용들이 들어 있는지 정리해 볼게요
아래에 이어지는 내용은 책을 보면서 정리한 것임을 미리 밝혀둡니다
(아주 간혹 내 생각이나 추가 공부한 내용 포함될지도)

파트 1: 이제는 모두의 AI 리터러시

AI 리터러시는 “AI 기술을 이해하고, 활용하며, 비판적으로 평가할 수 있는 종합적인 능력”을 의미한다.

- AI 리터러시의 핵심 영역 5가지
1) AI 데이터의 이해 : AI 기본 원리와 작동 방식을 이해하고, AI의 기반인 데이터의 중요성을 인식하며 이를 해석/활용하는 능력
2) 프롬프트 엔지니어링 : AI에게 효과적인 명령어/질문을 제시하여 원하는 결과를 얻어내는 능력
3) AI 활용 문제 해결 : 일상생활과 업무 환경에서의 다양한 문제를 AI 기술을 활용하여 해결하는 능력
4) AI에 대한 비판적 사고 : AI의 한계와 잠재적 편향성을 인식하고, 생성된 결과물을 비판적으로 평가하는 능력
5) AI 윤리와 사회적 영향 : AI 사용에 따른 윤리적 문제와 사회적 영향을 인식하고, 관련 법규와 정책을 이해하는 능력

출처 : 도서 18페이지

프롬프트 엔지니어링은 “AI에게 효과적으로 지시를 내리고 원하는 결과를 얻어내는 기술”이다. 프롬프트에도 어느 정도 공식이 존재하며, 그에 맞게 작성해야 원하는 결과물을 뽑아낼 수 있는 확률이 높아진다. 한두 줄의 너무 짧은 프롬프트 입력으로는 절대 좋은 결과물을 얻을 수 없다.

- 프롬프트 구성시 꼭 포함되어야 하는 필수 요소 3가지
1) 지시사항(Instruction) : AI에게 무엇을 해야 하는지 구체적으로 알려주는 명령
2) 맥락(Context) : AI가 작업을 수행하는데 필요한 배경 정보를 제공
3) 출력형식(Output Format) : AI에게 원하는 출력 형식을 알려주는 지시어

- AI 답변의 품질을 높이는 보조 프롬프트 요소
1) 입력 데이터(Input Data) : AI가 작업을 수행하는 데 필요한 데이터 LIKE 요약할 글, 번역할 문장, 참고해야 할 최신 정보 등
2) 제약조건(Constraints) : AI의 답변에 제한을 두어, 더 구체적이고 집중된 결과를 도출하게 함
3) 예시(Example) : AI에게 어떤 답변을 원하는지 구체적으로 알려줌 

구성요소 예시
지시사항 ㅇㅇ에 관한 에세이를 써주세요.
ㅇㅇ에 대한 토론 주제를 제시해주세요.
맥락 이번 보고서는 ~~에 대한 것으로, 핵심요소는 ~~다.
이 스크립트는 ~~에서 발표될 예정이며, ~~가 주된 내용이다.
출력형식 표 형식으로 정리해주세요.
최근의 사건이 가장 위로 오는 타임라인 형식으로 제시해주세요.
입력 데이터 다음 데이터를 바탕으로 분석 보고서를 작성해주세요(+데이터 파일)
다음 문장을 한국어에서 스페인어로 번역해주세요(+한글 문장)
제약조건 500자 이내로 요약해주세요.
00연도 이후의 자료로만 구성해주세요.
예시 보고서 개요, 레시피, 여행 계획, 그림 등 가능한 한 구체적이고 명확하게 제공

그 외에도 사용되는 프롬프트 엔지니어링 기법들로,

1) 제로샷 프롬프팅 : AI에게 별도 예시를 주지 않은 상태에서 새로운 작업을 하도록 요청. AI가 기존에 학습한 내용을 바탕으로 처음 접하는 작업/질문에 대응하게 함. 전문적인 작업에서는 정확도가 떨어질 수 있으며, AI의 학습 범위를 벗어나는 주제에는 관련 없는 답변을 생성할 수도 있다는 한계 존재
2) 원샷 프롬프팅 : AI에게 딱 1개의 예시만 제공하여 작업을 지시. 최소한의 정보로 최대한의 결과를 얻고자 할 때 사용함. 대표성이 높은 예시를 제공해야 원하는 결과를 얻을 확률이 높아짐
3) 퓨샷 프롬프팅 : AI에게 여러 개의 예시를 제공하여 작업을 지시. 원하는 결과물의 스타일/특징과 가까운 결과를 낼 확률이 높으나, 제공된 예시 간 일관성이 없거나 너무 많은 경우 역효과가 날 수도 있음
4) CoT 프롬프팅(Chain of Thought) : AI에게 문제 해결 과정을 단계별로 설명하도록 유도
5) 역할 할당 프롬프팅 : AI에게 특정 역할이나 관점을 부여하여, 그 역할에 맞는 방식으로 응답을 생성하도록 유도

주의해야 할 문제들로는 1) AI의 환각현상(할루시네이션 Hallucination)은 AI가 실제로 존재하지 않는 정보를 마치 사실인 것처럼 제시하는 현상을 의미. AI가 학습한 데이터를 바탕으로 가장 확률적으로 높은 답변을 생성하는 과정에서, 실제로 존재하지 않는 정보나 잘못된 정보를 사실처럼 제시하는 것. 불완전한 데이터, 생성 방식의 특성, 명확하지 않은 프롬프트 등으로 인해 발생하게 됨. 방지를 위해 팩트 체크를 꼭 해야 함. 다른 플랫폼 등을 활용해 AI 답변의 사실 관계를 확인해야 함

2) AI의 편향성이 있음. AI가 학습하는 데이터들 속에는 이미 세상에 존재하는 수많은 편견들이 반영되어 있음. AI가 이 데이터들을 그대로 학습하면서 편향될 수 있음. 그렇기에 AI의 답변을 무조건 믿기보다는 비판적으로 바라볼 줄 알아야 함.

AI 디바이드란 “AI를 효과적으로 사용할 수 있는 사람과 그렇지 못한 사람 간의 격차”를 의미함. AI 교육 전문가 마르코 누베즈에 따르면, AI 디바이드에는 총 4개 수준이 존재

1) 레벨 1 인식 : AI 접근 불가
2) 레벨 2 사용 : AI 접근 가능하나, AI에 대한 이해는 없음
3) 레벨 3 숙지 : AI에 접근하고 이해하지만, 통찰력 있고 효율적인 사용은 못함
4) 레벨 4 통합 : AI에 접근하고 이해하며, 통찰력 있고 효율적인 사용 가능함 

출처 : 마르코 누베즈 링크드인 포스트

나는 아주 좋게 봐줘야 레벨 2에 속하는 것 같다. 왜냐 얼마 전에 블로그 쓰면서 챗지피티한테 이미지 만들어달라 했는데 이 난리였거든요ㅋ 그래서 빠르게 포기했는데요. 이번에 이 책 자세히 읽으면서 나에게는 프롬프트 엔지니어링 스킬이라는 게 전혀 없다는 사실을 뼈저리게 느꼈다. 예시도 줬는데... 지피티 이 자식... 했는데 잘못은 나에게 있었던 걸로 ㅋㅎ 반성하자 진짜

파트 2: 누구나 쉽게 이해하는 인공지능 기술

여기서는 우리가 실제로 사용하고 있는 서비스들 속에 숨어 있는 AI를 설명해 줘요.
넷플릭스와 유튜브의 추천 알고리즘 속에 녹아 있는 콘텐츠 기반/협업 필터링이라거나,
시리와 같은 AI 비서 속에 숨어 있는 음성 인식, 자연어 처리, 대화 관리, 음성 합성과 같은 기술들입니다.
그리고 AI의 개념과 역사, 주요 적용 분야에 대해 설명하고 있어서 유용해요.
꼭 책을 읽으면서 내용 파악해 보시기를 추천해요.
그리고 조금 더 자세한 내용이 궁금하다면 아까 소개한
"비전공자도 이해할 수 있는 AI 지식"으로 넘어가면 좋을 것 같아요.

이 부분을 읽으면서 이외에도 내 일상에 스며든
AI 기반 서비스들이 뭐가 있을지 고민해 봤는데
유튜브, 넷플릭스, 애플뮤직, 밀리의 서재, 왓챠피디아 같은 서비스들은
다 추천 알고리즘을 기반으로 나를 조종하고 있고,
요즘은 듀오링고와 플랭 같은 AI 기반 언어 공부 앱들로 공부도 하고 있다.
일할 때는 클로바노트로 회의록 쓸 때 도움도 받고 하니까
노션으로 프로젝트 정리도 하고, 내 개인적인 기록도 남기기도 한다.
이렇게 보니 진짜 내 생활의 전부라고 말해도 될 정도다.
이렇게나 AI 속에서 살고 있지만
정작 생성형 AI와는 전혀 친하지가 않은데요.
그래서 이어질 파트에서 깊게 공부해 보겠습니다.

파트 3: AI 리터러시 업그레이드 생성형 AI 서비스 가이드

이번 파트에서는 결과물 종류나 활용 목적에 따라
AI 서비스들을 다섯 가지로 나눈 후
각 서비스들의 개요, 특별한 기능, 간단한 활용법에 대해 소개한다.
[대화형, 이미지 생성형, 동영상 생성형, 특화 기능 생성형, 연구 및 교육용]
여기서부터는 내가 이용해 볼 만한 것들만 추렸다.
자세한 건 책을 직접 찾아보길 추천한다.

[대화형 AI]

인간과 자연스럽게 대화를 나눌 수 있는 인공지능으로
사용자가 입력하는 텍스트에 적절하게 응답하거나 정보를 제공하는 기술이다.
앞서 파트 2장에서 소개한 대규모 언어 모델(LLM)을 기반으로 동작한다.

(1) 챗GPT, ChatGPT, https://chatgpt.com/
- 기본적인 문서 작성부터 정보 검색, 이미지와 파일 분석, DALL-E 모델 기반 고품질 그림 생성
- GPT 모델에 기반한 애드온을 찾을 수 있는 GPT 스토어라는 기능 존재

(2) 클로드, Claude, https://claude.ai/
- 자연스러운 느낌의 글쓰기 제공. 일반적인 질문-답변부터 문서/이미지 분석
- 생성된 결과물을 실시간 편집할 수 있는 작업 공간인 아티팩트 기능을 통해 코드 실행, 그래프 생성, 동적 이미지 제작, 게임 개발까지 가능
- 인터넷에 연결되어 있지 않아 최신 정보를 실시간으로 제공받을 수는 없음

(3) 제미나이, Gemini, https://gemini.google.com/
- 질문 답변, 이미지 및 문서 분석 등 대화형 AI 기본 기능 제공
- 구글 서비스와 호환. 구글 드라이브/지메일 검색 및 정리, 구글 독스 활용 문서 작성 등. 이마젠3 모델 기반 고품질 이미지 생성
- 인터넷 검색을 통한 최신 정보 제공. GPT 스토어와 유사한 Gem이라는 기능 존재

출처 각 서비스 홈페이지

(4) 클로바X, ClovaX, https://clova-x.naver.com/
- 하이퍼클로바X 모델을 기반으로 하여 타 서비스에 비해 한국어/한국 데이터에 특화
- 스킬 기능을 통해 네이버 서비스들과 호환, 에이전트 기능을 통해 전문적인 작업 지원

(5) 노트북LM, NotebookLM, https://notebooklm.google
- 여러 문서를 비교 분석하거나 여러 문서에서 정보를 바로바로 찾아야 할 때 유용
- 문서 형식 자유. 구글 문서/슬라이드, PDF, 텍스트, URL 모두 분석 가능
- 제미나이 1.5 프로 기반 이미지/차트/도형 분석, 출처 인용, 자료 요약 또는 새 목차 작성 등

출처 각 서비스 홈페이지

(6) 퍼플렉시티, Perplexity, https://www.perplexity.ai
- 실시간 웹 검색을 통한 최신 정보 제공과 신뢰할 수 있는 출처 제시로 AI의 환각현상 최소화
- 작성한 문서를 업로드하고 역으로 참고 문헌을 찾아달라고 요청할 수도 있음

(7) 웍스AI, Wrks AI, https://wrks.ai/ko
- 대화형 AI부터 문서 번역, 데이터 분석, 회의록 작성 등 직장인 맞춤형 기능 제공
- 나만의 비서 만들기 기능을 통해 회사 규정을 학습시키거나, 반복 업무를 자동화하는 등 커스텀 가능

[이미지 생성형 AI]

텍스트를 입력받아 원하는 이미지를 만들어주는 인공지능 기술이다.
대규모 이미지 데이터로 학습된 인공지능 모델을 기반으로 작동한다.

(1) 디자이너, Designer, https://designer.microsoft.com/?
- 배경화면, 스티커 등 다양한 이미지 무료 제작 가능
- 생성형 지우기를 사용해 필요 없는 부분, 배경 등 제거도 편리

(2) 파이어플라이, Firefly, https://www.adobe.com/kr/products/firefly.html
- 실사에 가까운 이미지 필요시 사용
- 텍스트 기반 이미지 생성, 생성형 채우기/확장하기 등 기능 제공
- 크리에이티브 클라우드 라이선스 인증을 부여하여 저작권 문제에서 자유로움

출처 각 서비스 홈페이지

이외에도 많이 들어본 미드저니, 이머시티 AI 같은 애들이 있었는데
개인적인 활용도가 낮으리라 예상해 넣지 않았다.
궁금하신 분은 직접 책을 찾아보시길 추천드립니다.

[특화 기능 생성형 AI]

(1) 감마, Gamma, https://gamma.app/ko
- 텍스트/프롬프트/파일/URL 기반 프레젠테이션 생성
- 세세하고 전문적인 디자인 조정은 어려워 짧은 시간 내에 발표자료를 제작해야 할 때 사용

(2) 릴리스AI, Lilys AI, https://lilys.ai
- 유튜브 등 영상/웹사이트/PDF/녹음 요약 기능 제공

출처 각 서비스 홈페이지

[연구 및 교육용 AI]

(1) 사이스페이스, SCISPACE, https://typeset.io
- AI 기반 논문 검색과 추천, 논문 요약 및 핵심 내용 추출, AI 채팅 기능으로 문서 내용 심층 이해
- 오픈 액세스 논문 위주라 원하는 분야별로 접근 가능한 문헌 범위가 상이함

(2) 리서치 래빗, ResearchRabbit, https://www.researchrabbit.ai
- 논문간 관계 파악 및 시각화로 연구 분야의 전반적인 동향/방향성 파악 용이

출처 각 서비스 홈페이지

(3) 딥엘, DeepL, https://www.deepl.com/ko/whydeepl
- 33개 언어 간 번역 지원 및 PDF/워드/파워포인트 등 다양한 형식의 파일 번역
- AI 기반으로 사용자가 작성한 글을 다듬는 편집/개선 도구인 딥엘 라이트 서비스 존재

(4) 냅킨 AI, Napkin AI, https://www.napkin.ai
- 텍스트를 시각적 그래픽으로 변환하는 서비스

출처 각 서비스 홈페이지

파트 4: '나' 맞춤 AI 리터러시

이번 파트에서는 학생, 직장인, 공무원 등 자신의 상황에 따라
맞춤형으로 업무나 일상 속에서 적용할만한 서비스들을
파트 3보다 훨씬 더 자세하게 소개해준다.

풍부한 화면 캡쳐와 함께 서비스 내 각 기능들을 조금씩 보여줘서
내 상황에서는 이렇게 쓸 수 있겠다는 감이 잡히게 해 주더라.
이거쟈나 내가 원했던 거...!

상황 어울리는 서비스
발표자료를 만들 시간이 부족할 때 감마
회의록을 만들어야 할 때 다글로
자료에 들어갈 이미지가 필요할 때 냅킨 AI
데이터를 분석하고 싶을 때 클로드 아티팩트
길이가 긴 보고서나 영상 내용을 파악하고자 할 때 릴리스 AI
보도자료, 축사 등 정형화된 문서를 작성할 때 챗GPT
외국 자료를 참고하거나, 자료를 외국어로 작성해야 할 때 딥엘
연구 논문 검색, 유사 연구 검색 및 관계 분석이 필요할 때 리서치래빗
논문 외에도 연구 보고서, 기타 문헌을 통해 정보를 얻고자 할 때 퍼플렉시티
실사 스타일의 이미지가 필요할 때 파이어플라이

이렇게 해서 AI 리터러시란 무엇인지부터
리터리시 단계를 높이기 위해 활용할만한 서비스들과
그 서비스들을 사용하는 방법에 대해서도 공부할 수 있었다.

하나씩 써 볼 계획을 세우고 있었는데
인스타그램이 나에게 좋은 활동을 하나 추천해 줬다.
바로 네이버 커넥트 부스트코스에서 운영하는
"Generative AI 2025 스터디"다.

출처 : 네이버 부스트코스 메인

4주 기간 동안 생성형 AI를 활용하는 법을 배우는 활동이다.
신청한다고 다 뽑아주는 건 아니지만 일단 접수는 해봤다.
2025년의 트렌드 중 하나가 작은 성취를 이루는 "원포인트업"이라고 누가 그랬는데
오는 2월 나의 원포인트업이 이번 스터디이길~🙏🏻

반응형
반응형

지난번에 냅다 소개 겸 예고글을 올렸던 혼공학습단 13기 활동이 시작되었습니다

2024.12.20 - [공부/IT] - 한빛미디어와 함께 하는 혼공학습단 소개 및 13기 참여 예고

 

한빛미디어와 함께 하는 혼공학습단 소개 및 13기 참여 예고

올 한 해 공부를 너무 하지 않은 죄로...필기를 N번이나 봤는데 전부 필탈 했다죠 실화냐물론 점수차가 동점차(^^)부터 최대 3점까지긴 했지만어찌 되었든 처참한 결과에 충격을 금치 못했고...반

lv27.tistory.com

한빛미디어의 혼자 공부하는 시리즈 중에서
자기가 공부하고 싶은 걸 1권 선택해서
매주 커리큘럼 따라 공부하고 숙제 및 정리 글을 올리면 되는데요.

내가 13기에 신청한 건 "혼자 공부하는 네트워크"

출처 : 한빛미디어 공식 사이트

혼공학습단의 족장(?)님이 내주시는 숙제 커리큘럼은 아래와 같아요.

출처 : 혼공학습단 홈페이지

본격적으로 숙제를 하기 전에!
이번 주가 혼공단의 첫 번째 주니까
앞으로 6주간 공부할 책에 대해서도 잠시 살펴볼게요

책을 펼치면 가장 먼저 "학습 로드맵"이 나와요.
목차보다 먼저 나와서, 이 책을 통해 무엇을 배우게 될지 대략적으로 파악할 수 있어요.
게다가 책을 100% 활용하기 위한 여러 팁도 있는데요.
1. 핵심 개념과 용어를 따로 정리한 PDF 파일인 혼공 용어 노트
2. 혼자 이해 하기가 어렵다면 들을 수 있는 무료 강의
3. 심화 학습에 필요한 파일들을 보고 저자에게 직접 질문도 할 수 있는 깃헙 
마지막으로 4. 의지박약자를 강제로 공부하게 하는 혼공학습단

출처 : 한빛 미디어 공식 사이트 > 미리보기 기능

목차는 대제목만 살펴볼게요.
우리 혼공단 커리큘럼과 순서가 같아요.
매주 해당하는 내용에만 하이라이트를 쳐볼게요

<목차>
Chapter 1. 컴퓨터 네트워크 시작하기
Chapter 2. 물리 계층과 데이터 링크 계층
Chapter 3. 네트워크 계층
Chapter 4. 전송 계층
Chapter 5. 응용 계층
Chapter 6. 실습으로 복습하는 네트워크
Chapter 7. 네트워크 심화

그럼 1주차 공부를 시작해 볼까요

# 컴퓨터 네트워크란
   여러 장치가 연결되어 정보를 주고받을 수 있는 통신망을 의미
   많은 프로그램이 네트워크를 통해 다른 장치와 상호작용하며 실행됨
   >> 프로그램을 개발하거나 유지보수 할 때 네트워크 배경지식을 활용해야 하는 경우가 많기에 공부가 필요

# 네트워크의 기본 구조
   모든 네트워크는 노드, 노드를 연결하는 간선, 노드 간 주고받는 메시지로 구성됨
   노드 : 정보를 주고받을 수 있는 장치. 호스트, 서버, 네트워크 장비 등이 존재
   간선 : 정보를 주고 받을 수 있는 유무선의 통신 매체
   메시지 : 통신 매체로 연결된 노드가 주고받는 정보. 웹 페이지, 파일, 메일 등 다양

출처 : 한빛출판네트워크 홈페이지 > 채널.H

# 범위에 따른 네트워크 분류
   LAN(Local Area Network) : 가까운 지역을 연결한 근거리 통신망. 가정, 학교, 기업과 같이 한정된 공간의 네트워크 
   WAN(Wide Area Network) : 먼 지역을 연결하는 광역 통신망. 멀리 떨어진 LAN을 연결할 수 있는 네트워크로, ISP(Internet Service Provider)라는 인터넷 서비스 업체가 구축하고 관리. 국내에 대표적인 ISP는 3대 통신사가 있음.

더보기

더 세밀하게 나누면 LAN과 WAN 사이에 2개의 개념이 더 존재. 순서를 따지자면,
(넓음) WAN >> MAN >> CAN >> LAN  (좁음)
- MAN은 도시나 대도시 단위로 연결되는 규모의 네트워크를 의미
- CAN은 학교/회사의 여러 건물 단위로 연결되는 규모의 네트워크를 의미

# 메시지 교환 방식에 따른 네트워크 분류
   회선 교환 방식 : 메시지 전송로인 회선(Circuit)을 먼저 설정하고 이를 통해 메시지를 주고받는 방식. 요즘은 안 쓰이지만 전통적인 전화망과 같은 형태. 주어진 시간 동안 전송되는 정보의 양이 비교적 일정하다는 장점이 있으나, 반대로 회선의 이용 효율이 낮아질 수 있다는 단점도 존재. 하단의 왼쪽 그림 내 붉은 선처럼 회선을 먼저 설정해야 이 경로를 통해 메시지가 오갈 수 있음

출처 : 혼공학습단 홈페이지 > 읽을거리

   패킷 교환 방식 : 메시지를 패킷(Packet)이라는 작은 단위로 쪼개어 전송. 회선 교환 방식에 비해 네트워크 이용 효율이 상대적으로 높음. 상단의 오른쪽 그림처럼 패킷들이 회선을 타고 필요한 곳으로 이동하게 됨.
   패킷은 헤더, 페이로드, 트레일러로 구성. 패킷이 택배와 비슷한 개념이라,
   헤더(Header)는 어디로 가야 할지 적힌 택배 송장 같은 개념이고,
   페이로드(Payload)는 전송하고자 하는 데이터가 담겨 있는 택배 안의 내용물,
   트레일러(Trailer)는 부가적인 정보를 표시한 것.

출처 : 혼공학습단 홈페이지 > 읽을거리

# 주소/송수신지 유형에 따른 전송방식
   유니캐스트(Unicast) : 하나의 수신지에 메시지를 전송하는 방식. 1:1 전송 방식 
   브로드캐스트(Broadcast) : 자신을 제외한 네트워크상의 모든 호스트에게 전송하는 방식 
   멀티캐스트(Multicast) : 네트워크 내의 동일 그룹에 속한 호스트에게만 전송하는 방식
   애니캐스트(Anycast) : 네트워크 내 동일 그룹에 속한 호스트 중 가장 가까운 호스트에게만 전송하는 방식

# 프로토콜(Protocol)이란
   노드 간에 정보를 올바르게 주고받기 위해 합의된 규칙이나 방법. 서로 다른 장치들이 정보를 제대로 주고받으려면 필요.
   IP, HTTP, TCP, ARP 등 프로토콜별로 목적과 특징이 모두 다름

# 네트워크 참조 모델이란
   네트워크를 통해 정보를 주고받을 때 정형화된 여러 단계를 거치는데, 이를 계층으로 나눈 구조를 의미. 계층을 나누는 이유는,
   1) 네트워크 구성과 설계가 용이해지기 때문 : 각 계층의 역할이 정해져 있어 그에 맞게 프로토콜과 네트워크 장비를 구성 가능
   2) 네트워크 문제 진단과 해결에 용이 : 문제가 발생 시 계층별로 진단하면서 문제 발생 지점을 쉽게 추측하고 해결 가능

   네트워크 참조 모델은 크게 OSI 모델과 TCP/IP 모델로 나눠짐

여기부터는 심화 공부를 위해 다른 책과 블로그도 참고하며 정리했는데 비슷한/중복되는 개념도 그냥 적었습니다.
사담인데 모 기업에서 계층별로 프로토콜 구분하랬는데 공부 안 해서 틀렸거든요^ㅁ^
아무래도 대학 졸업장 반납해야 할 수준... 그래서 좀 힘줘서 자세히 공부해봤음다
하지만 프로토콜별로는 나중에 따로 정리할게요... 암튼 공부 킵고잉

# OSI 7계층 (낮은 >> 높은 순으로)

(1) 물리 계층 Physical Layer
- OSI 모델 최하단에 있는 계층
- 0과 1로 표현되는 비트 신호를 주고받음
- 주로 전기/기계/기능적 특성을 이용해 통신 케이블로 데이터를 전송하는 물리적인 장비 전송에 필요한,
   두 장치 간의 실제 접속과 전달 등 기계/전기/기능/절차적 특성에 대한 규칙을 정의
- 전송 단위(프로토콜 데이터 단위, PDU)는 비트 Bit
- 장비는 통신 케이블, 리피터, 허브(반이중) 등
- 관련 프로토콜로는 RS-232C, X.21 등

(2) 데이터 링크 계층 Data Link Layer >> 흐름/오류/순서 제어
- 네트워크 내 주변 장치 간의 정보를 올바르게 주고받기 위한 계층
- 물리 계층을 통해 주고받는 정보에 오류가 없는지 확인
- MAC 주소 체계를 통해 네트워크 내 송수신지를 특정
- 전송 과정에서 발생할 수 있는 충돌 문제를 해결하는 계층
- 물리적으로 연결된 인접한 개방 시스템들 간 신뢰성 있고 효율적인 정보 전송을 위해 시스템 간 연결 설정과 유지 및 종료를 담당
- 물리 계층을 통해 송수신되는 정보의 오류의 검출과 회복을 위한 오류제어와,
   송수신 측 속도 차이를 해결하기 위해 흐름을 관리는 흐름 제어
,
   프레임의 순서적 전송을 위한 순서 제어(재전송)
- 전송 단위인 프레임(frame)에 물리적 주소(MAC 주소)를 부여
- 장비는 랜카드, 브리지, 스위치(전이중), 이더넷 등
- 관련 프로토콜로는 HDLC, LAPB, LLC, MAC, LAPD, PPP 등

(3) 네트워크 계층 Network Layer
- 메시지를 다른 네트워크에 속한 수신지까지 전달하는 계층
- 네트워크 간 통신을 통해 인터넷을 가능하게 하는 계층
- IP 주소를 통해 통신하고자 하는 수신지 호스트와 네트워크를 식별하고, 원하는 수신지에 도달하기 위한 최적의 경로 결정(라우팅)
- 개방 시스템들 간 네트워크 연결을 설정/유지/해제하는 관리 기능과 데이터의 교환/중계 기능, 경로 제어, 패킷 교환, 트래픽 제어 등의 기능을 수행
- 라우터를 통해 경로를 선택하고 주소를 정하고(IP), 경로에 따라 패킷을 전달
= 발신지/목적지의 논리 주소가 추가된 패킷을 최종 목적지까지 전달 (IP 헤더 붙음)
- 전송 단위는 패킷
- 장비는 라우터
- 관련 프로토콜로는 IP, ICMP, IGMP, ARP, RARP, X.25 등

더보기

(참고) IP의 특징
- 신뢰성(에러 제어) / 흐름 제어 기능 없음
- 비연결성 / 비신뢰성
- 인터넷 주소 지정과 라우팅
- 패킷 단편화와 재조립
- 데이터그램 기반, 패킷 전송

(4) 전송 계층 Transport Layer
- 신뢰성 있고 안정성 있는 전송을 해야 할 때 필요한 계층
- OSI 7계층 중 하위 3계층과 상위 3계층의 인터페이스 담당
- 패킷의 흐름을 제어하거나 전송 오류를 점검해 신뢰성 있고 안정적인 전송이 이루어지도록 함
   (패킷이 정상적으로 보내졌는지, 중간에 유실은 없었는지, 순서가 뒤바뀌지는 않았는지 확인)
- 논리적 안정과 균일한 데이터 전송 서비스를 제공해 종단 시스템 간(end to end) 투명한 데이터 전송 지원
- 종단 시스템 간(단말기 사이에) 전송 연결 설정, 데이터 전송, 연결 해제 기능
- 주소 설정, 다중화(분할 및 재조립), 오류 제어, 흐름 제어
- 두 지점 간 신뢰성 있는 데이터 송수신을 지원하는 역할, 신호를 분산하고 다시 합치는 과정을 통해 에러와 경로를 제어
- 전송 단위는 세그먼트
- 장비는 게이트웨이
- 관련 프로토콜로는 TCP, UDP
   TCP는 신뢰성, 연결지향적인 프로토콜. 패킷의 전송. 오류/혼잡/흐름 제어
   UDP는 비신뢰성, 비연결성, 실시간성을 가진 프로토콜

(5) 세션 계층 Session Layer
- 통신을 주고받는 호스트의 응용 프로그램 간 연결 상태인 "세션"을 관리하는 계층
- 송수신 측 간의 관련성 유지, 대화제어 담당
- 대화(회화) 구성 및 동기 제어, 데이터 교환 관리 기능
- 송수신측간의 데이터 전송, 연결 해제, 동기 처리 등의 대화를 관리하기 위해 토큰 사용
- 송수신측간의 대화 동기를 위해 전송하는 정보의 일정한 부분에 체크점을 두어 정보의 수신 상태를 체크함 (체크점=동기점)
- 동기점은 오류가 있는 데이터 회복을 위해 사용하는 것
   소동기점 : 하나의 대화 내, 수신 측으로부터 확인 신호 ACK 안 받음
   대동기점 : 전송하는 데이터의 처음/끝, 확인 신호 받음
- API. Socket. TCP/IP 세션 체결. 포트 port 번호 기반 통신 세션

(6) 표현 계층 Presentation Layer
- 서로 다른 표현 형태를 갖는 시스템 간 상호 접속을 위해 필요한 계층 like 번역가
- 코드 변환(사람 언어인 문자를 컴퓨터가 이해 가능한 코드로 변환)
- 데이터 암호화, 데이터 압축, 구문 검색, 정보 형식(포맷) 변환, 문맥 관리 기능

(7) 응용 계층 Application Layer
- OSI 참조 모델 최상단에 있는 계층
- 사용자&사용자가 이용하는 응용 프로그램과 가장 밀접한 계층
- 사용자(응용 프로그램)이 OSI 환경에 접근할 수 있도록 서비스 제공
- HTTP(80), FTP(21), SMTP(25), SNMP, POP3, IMAP, Telnet(23), DNS(53) 
* 세션부터 응용까지 전송 단위는 메시지

정리하자면 아래 그림의 OSI 7계층과 같답니다. 네트워크를 이론적으로 기술하고 이해할 때 사용하는 "이상적 설계" 같은 거래요.
그럼 계속해서 오른쪽의 TCP/IP 모델도 볼까요? 구현에 중점을 두어 실제 사용하기 위한 "실용적 구현" 같은 거라고 하네요.
이런 차이점이 있다는 건 처음 알았다.

출처 : https://www.nossi.dev/06936fc0-eb03-4a53-8e4f-2e5dc71508dd

# TCP/IP 4 계층 (낮은 >> 높은 순으로)

(1) 네트워크 액세스/인터페이스 계층 Network Access/Interface Layer
- OSI 모델에서의 물리와 데이터 링크 계층과 유사   (간혹 데이터 링크 only로 다르게 보는 시선도 있긴 함)
- 실제 데이터(프레임)을 송수신하는 역할
- 에러 검출, 패킷의 프레임화
- 네트워크 접근 방법, 프레임 포맷, 매체에 독립적으로 동작하도록 설계
- 물리적인 주소로 MAC 사용
- LAN, 패킷망 등에 사용됨
- 이더넷, IEEE 802, HDLC, X.25, RS-232C, ARQ 등

(2) 인터넷 계층 Internet Layer
- OSI 모델에서의 네트워크 계층과 유사
- 데이터 전송을 위한 주소 지정(어드레싱), 경로 설정(라우팅), 패키징 기능 제공
- 네트워크 상 최종 목적지까지 정확하게 연결되도록 연결성 제공
- IP, ICMP, IGMP, ARP, RARP

(3) 전송 계층 Transport Layer
- OSI 모델에서의 전송 계층과 유사
- IP와 Port를 이용하여 프로세스와 통신
- 호스트들 간의 신뢰성 있는 통신 제공
- 통신 노드 간 연결 제어
- TCP, UDP, RTCP

(4) 응용 계층 Application Layer
- OSI 모델에서의 세션, 표현, 응용 계층을 합친 것과 유사
- 응용 프로그램 간 데이터 송수신 제공, 프로토콜 정의
- 다른 계층 서비스에 접근할 수 있게 하는 애플리케이션 제공
- HTTP(80), HTTPS, FTP(21), SMTP(25), SNMP, POP3, IMAP, Telnet(23), DNS(53)

책에서는 각 계층을 추후에 자세히 학습할 예정이라고 했다.
나중에 해당 챕터에서 공부하면서 비교하고 조금 더 압축적으로 요약해보고자 한다.

#캡슐화와 역캡슐화
   패킷은 송신 과정에서 캡슐화가, 수신 과정에서 역캡슐화가 이루어짐. 네트워크 참조 모델도 마찬가지
   정보 전송 시 각 계층에서는 상위 계층으로부터 받은 패킷을 페이로드 삼아, 프로토콜에 걸맞은 헤더(or 트레일러)를 덧붙인 후 하위 계층으로 전달하는데 이 과정이 캡슐화(encapsilation)
   역캡슐화는 반대로 메시지를 수신할 때 각 계층에서 헤더를 확인한 뒤 제거하고 상위 계층으로 올려 보내는 과정을 의미

출처 : 한빛출판네트워크 홈페이지 > 채널.H

# 프로토콜 데이터 단위 PDU(Protocol Data Unit)
   각 계층에서 송수신되는 메시지의 단위
   상위 계층에서 전달받은 데이터에 현재 계층의 프로토콜 헤더(및 트레일러)를 추가하면 현재 계층의 PDU

OSI 계층 PDU
응용 데이터 혹은 메시지
표현
세션
전송 세그먼트(TCP), 데이터그램(UDP)
네트워크 패킷 (간혹 IP 데이터그램)
데이터 링크 프레임
물리 비트

 

이렇게 해서 "혼자 공부하는 네트워크"의 챕터 1 컴퓨터 네트워크 시작하기 파트를 공부해 봤는데요.
그냥 가기는 아쉬우니 족장님의 추가 숙제📚를 풀어보겠습니다.

# (p35) 확인문제 2번 "네트워크에 대한 설명으로 옳지 않은 것을 골라 보세요"
   네트워크에 대한 이해는 프로그램을 만드는 과정에 도움을 주기에 1번 선지가 오답
   컴퓨터 네트워크와 인터넷에 대해 설명하면서 프로그램 개발/유지보수 같은 상황에서 네트워크 배경지식을 활용하는 경우가 많다고 언급함

# (p73) 확인문제 2번 "네트워크 참조 모델에 대한 설명으로 옳지 않은 것을 골라 보세요"
   TCP/IP 모델은 네트워크 액세스, 인터넷, 전송, 응용 계층으로 구성된 4계층 모델이라 2번 선지가 오답

그럼 혼공단 13기 혼공네트 1주차 공부 진짜 끝!

 

반응형
반응형

오늘의 문제는 레벨 2에 해당하는 <방문 길이>인데요.
(문제 출처 : 프로그래머스 https://school.programmers.co.kr/learn/courses/30/lessons/49994)

프로그래머스는 블로그 게재 시 문제 여지가 있어
자세한 내용 없이 문제 제목과 링크로 대체합니다. 

게임 캐릭터가 제한된 맵(좌표) 내에서
상하좌우로 움직이는 경로의 길이를 계산하는 문제였다.

내 첫 접근법은
1) 좌표니까 계산하기 쉽게 배열을 쓰고
2) 그 다음에 좌표값에 따라 배열마다 횟수를 저장하면 되겠지 였다.

// 이 코드는 정답이 아닙니다 //
class Solution {
    public int solution(String dirs) {
        int answer = 0;
        
        // 좌표평면 배열
        // 배열[5][5]가 좌표평면 (0.0) = 배열 -5하면 좌표 평면 위치가 나옴
        int[][] path = new int[11][11];
        int x = 5, y = 5; 
        
        for (int i=0; i<dirs.length(); i++){
            char c = dirs.charAt(i);
            
            switch (c){
                case 'U': // 위로 한 칸
                    if (y<10) {y++;} break; 
                case 'D': // 아래로 한 칸
                    if (0<y) {y--;} break;
                case 'R': // 오른쪽으로 한칸
                    if (x<10) {x++;} break;
                case 'L': // 왼쪽으로 한 칸
                    if (0<x) {x--;} break;
            }
            
            // 처음 걸어본 길일 때만
            if (path[x][y] == 0) {
                path[x][y] += 1;
                answer++;
            }
        }
        return answer;
    }
}

 

근데 코드를 돌려 보니 실패!
다시 살펴보니 너무 단순하게 생각해
방향성을 고려하지 않았다.

내 코드대로 라면 (0.0) 에서 U 해서 1이 되면
(2.1) 에서 L로 다시 돌아오는 것도 카운트가 안됨...

그래서 바꾼 게 3차원 배열로 방향성을 추가해 주는 거였다.
하지만 가내수공업으로 U/D 또는 L/R을 다 고려해줘야 했고요...
그래서 이렇게 지저분한 코드가 탄생했지요

import java.util.*;

class Solution {
    public int solution(String dirs) {
        int answer = 0;
        
        // 좌표평면 배열
        // 배열[5][5]가 좌표평면 (0.0) = 배열 -5하면 좌표 평면 위치가 나옴
        // [][][방향] 0 U, 1 D, 2 L, 3 R
        int[][][] path = new int[11][11][4];
        int x = 5, y = 5;

        for (int i=0; i<dirs.length(); i++){
            char c = dirs.charAt(i);
            
            switch (c){
                case 'U': // 위로 한 칸
                    if (y<10) {
                        path[x][y][0] = 1;
                        y++;
                        path[x][y][1] = 1;
                    } break; // 경로마다 방향은 양쪽 + 처음 걸은 1번만 카운트
                case 'D': // 아래로 한 칸
                    if (0<y) {
                        path[x][y][1] = 1;
                        y--;
                        path[x][y][0] = 1;} break;
                case 'R': // 오른쪽으로 한칸
                    if (x<10) {
                        path[x][y][3] = 1;
                        x++;
                        path[x][y][2] = 1;} break;
                case 'L': // 왼쪽으로 한 칸
                    if (0<x) {
                        path[x][y][2] = 1;
                        x--;
                        path[x][y][3] = 1;} break;
            }
        }
        
        for (int i=0; i<path.length; i++){
            for(int j=0; j<path[0].length; j++){
                for(int k=0; k<path[0][0].length; k++){
                    if (path[i][j][k] == 1) {
                        answer++;
                    }
                }
            }
        }
        answer = answer/2; // 양방향이라 /2
        return answer;
    }
}

답안을 보니 이렇게 중복 미포함과 같은 문구가 나올 때는 해시셋을 떠올리라고 하더라
자바의 HashSet은 Set 인터페이스를 구현한 클래스다.
1) 중복된 값을 허용하지 않음
2) 입력한 순서가 보장되지 않음
3) null을 값으로 허용함

대충 로직은 이래서 나랑 비슷하기는 한데...
코드는 훨씬 더 간결하다 심지어 이건 시간복잡도도 N이라서
나중에 다른 문제 풀면서 해시맵/셋을 활용하기 위해 노력해 봐야겠다.

import java.util.*;


private static boolean isValidMove(int nx, int ny){
    return 좌표평면 내인지 체크하는 함수 구현
}

// 다음 좌표 결정을 위한 해시맵 생성
private static final HashMap<Character, int[]> location = new HashMap<>();

private static void initLocation(){
	// put 함수 사용, 상하좌우에 따른 배열을 생성함
}

class Solution {
    public int solution(String dirs) {

        initLocation();
        int x = 5, y = 5;

        // 겹치는 좌표는 1개로 처리
        HashSet<String> answer = new HashSet<>();

        for (int i=0; i<dirs.length(); i++){

            // UDLR을 가지고 매번 새로운 배열 offset을 만든다
            int[] offset = locations.get(dirs.charAt(i));
			// 그리고 좌표값 nx, ny를 계산함
            
            if (!isValideMove(nx,ny)) continue;
            // 범위 벗어나면 패스함

            // A에서 B로 간 경우, B에서 A로 간 경우를 해시셋에 추가
            // 해시셋에 추가하는 메소드는 .add
            // 0 0 >> 0 1
            // 0 1 >> 0 0

            // 좌표 이동 후 x, y를 업데이트
        }

        return answer ;
    }
}

이렇게 해서 "코딩 테스트 합격자 되기:자바 편"의 첫 번째 파트인 "배열"이 끝났다.
마지막에 풀어 보면 좋을 추천 문제도 알려주더라
- 배열의 평균값
- 배열 뒤집기
- 배열 자르기
- 나누어 떨어지는 숫자 배열
앞에 2개는 풀어봤던 거라, 뒤에 2개만 풀어보고 스택으로 넘어갈 예정이다.

반복해서 포스팅하고 있는데,
내가 보면서 공부하고 있는 책은 "코딩 테스트 합격자 되기:자바 편"이다.
가격은 정가 42,000원이다. (밀리의 서재에도 있음)

반응형
반응형

다음 문제는 "실패율"이다.
(문제 출처 : 프로그래머스 https://school.programmers.co.kr/learn/courses/30/lessons/42889)

프로그래머스는 블로그 게재시 문제 여지가 있어
자세한 내용 없이 문제 제목과 링크로 대체합니다.

책에서 권장 시간 60분이랬는데 넘긴 듯
다음에는 시간도 재면서 풀어봐야겠다.

입출력 예시를 보면,
스테이지 수는 5개이고 총 8명의 사용자가 있습니다.
스테이지별로 아직 클리어 하지 못한 사용자와 도전한 사용자 수를 보면

스테이지 번호 클리어 못한 도전한 사용자 실패율
1 1 8 1/8
2 3 7 3/7
3 2 4 2/4
4 1 2 1/2
5 0 1 0/1

스테이지가 올라갈수록 클리어 못한 사용자의 수를 빼야 도전한 사용자의 수가 나온다!
그리고 나중에 출력은 실패율이 높은 스테이지부터 낮은 스테이지 순으로,
만약 실패율이 0으로 같다면 스테이지 번호가 낮은 것부터 높은 순으로 하라고 되어 있다.

헤매긴 했지만 그래도 혼자서 성공해 낸 내 코드 흐름을 보면

1) 스테이지별 실패율 계산을 위해 fail 이라는 배열을 하나 만들었다
실패율 계산에 나누기가 들어가서 실수형 double을 택함
2) 배열 fail의 순서(i+1)가 스테이지의 순서니까,
stages 배열을 돌면서 해당 스테이지를 클리어 못한 사용자를 카운트했다.
if (stages[j] == i+1)  c++;
3) 그리고 실패율을 계산해서(c/u), fail 배열에 저장했다.
만약 클리어 못한 사용자가 없으면 실패율은 0이니까 바로 0으로 저장해 줬다.
4) 그리고 도전한 사용자 수에서 현재 스테이지에 남아있는 사용자 수(u-c)를 빼줬다.

스테이지 번호
fail[i]
클리어 못한 사용자
stages[j]의 수 == i+1
c로 카운트 올림
도전한 사용자
u
실패율
c/u로 계산
fail에 저장

5) 그리고 스테이지 순서대로 실패율을 저장해 놨기 때문에
clone 해서 sort로 내림차순 정렬을 했다.
근데 내가 사용한 배열은 기본 primitive 타입 double 이라서
Collections.reverseOrder()를 쓰기 위해 래퍼 wrapper 타입으로 형 변환을 해줬다.
6) 그리고 기존 배열과 제일 높은 순으로 정렬된 배열을 비교하면서
스테이지 순서를 조건에 맞게 fail_s 배열에 추가해 줬다.

실제로 작성한 코드는 이렇다

import java.util.*;

class Solution {
    public int[] solution(int N, int[] stages) {
        int[] answer = {};
        
        // 스테이지 번호로 멈춘 수를 카운트
        int s = N;
        int u = stages.length; // 유저 모수 계산용
        double[] fail = new double[s]; // 실패율 계산용 배열
        
        // 스테이지별 실패율을 계산하면서, 전체 인원수를 줄여나감
        for (int i=0; i<fail.length; i++){
            int c=0;
            for (int j=0; j<stages.length; j++){
                if (stages[j] == i+1){ // 스테이지는 1번부터라 i+1
                    c++; // 해당 스테이지에 있는 사용자만 세기
                }
            }
            if (c==0) {fail[i]=0;}
            else {fail[i] = (double) c/u;}
            u = u - c;
        }
        
        // 실패율을 비교해서 높은 스테이지 >> 낮은 스테이지. 실패율이 0이면 오름차순으로
        double[] clone = fail.clone();
        Double[] cd = Arrays.stream(clone).boxed().toArray(Double[]::new);
        Arrays.sort(cd, Collections.reverseOrder());
        
        ArrayList<Integer> fail_s = new ArrayList<>();

        for (int i=0; i<cd.length; i++){
            for(int j=0; j<fail.length; j++){
                if (cd[i] == fail[j]){
                    fail_s.add(j+1);
                    fail[j] = -1;
                    break;
                }
            }
        }
        answer = fail_s.stream().mapToInt(Integer::intValue).toArray();
        return answer;
    }
}

이것보다 더 예쁘고 간단하게 코드짤 수 있을 것 같은데... 모르겠다 ㅋ

암튼 이 코드에서 배운 점은
내림차순 정렬은 일단 Arrays.sort(배열명, Collections.reverseOrder())을 사용한다.
하지만 기본 타입 배열에는 적용이 불가능하다.
*기본 타입: byte, char, double, short, long, int, float ...
 
그래서 래퍼 클래스로 만든 다음(boxing) 정렬해야 한다.
*래퍼 클래스: 기본 자료형의 데이터를 인스턴스(객체)로 만들기 위해 사용하는 클래스
Byte, Character, Double, Short, Long, Int, Float ...

 double[] clone = fail.clone();
        Double[] cd = Arrays.stream(clone).boxed().toArray(Double[]::new);

내가 공부 중인 책에서는
스테이지별 도전자 수/실패한 사용자 수를 추출하고,
그리고 해쉬 맵을 사용 해서 풀었더라
대략적인 흐름만 따라가 보자면

// 스테이지별 도전자 수를 구하는 부분
// 0번째 인덱스는 사용하지 않고, 마지막 스테이지까지 클리어한 N+1 고려
    int[] chal = new int[N+2];
    for 문
    
// 스테이지별 실패한 사용자 수 계산
// 해쉬맵의 키는 스테이지 번호, 값은 실패율
    HashMap<Integer, Double> fails = new HashMap<>();
    double total = stages.length;

// 각 스테이지를 순회하며 실패율 계산
    for (int i = 1; i <= N; i++){
        if 도전한 사람이 없는 경우 {fails.put(i, 0.);}
    }
    else{ // 있는 경우에는 실패율 계산
        fails.put(i, chal[i] / total);
        현재 스테이지 인원 빼기
    }

// 실패율이 높은 스테이지부터 내림차순 정렬하기
    return fails.entrySet().stream().sorted((oa, o2)
        -> Double.compare(o2.getValue(), o1.getValue())).mapToInt(HashMap.Entry::getKey).toArray();

자세한 건 책을 직접 확인하세요
책 이름은 "코딩 테스트 합격자 되기: 자바편"입니다.

해쉬맵은
데이터를 추가할 때는 put(key, value)
모든 데이터 삭제할 때는 clear()
remove(key)는 key와 일치하는 기존 데이터 삭제
remove(key, value)는 key와 value가 동시에 일치하는 데이터 삭제
entrySet() : 모든 key-value 매핑 데이터를 가진 set를 반환

자바 스트림 Stream은 Java 8부터 추가된 기술로 람다를 활용해 배열과 컬렉션을 함수형으로 간단하게 처리
최종 연산 전까지 중간 연산을 수행하지 않는다.
작업을 내부 반복으로 처리한다.

.filter() > 스트림 내 요소들을 하나씩 평가해 걸러내는 if문의 역할
.sort() > 스트림 내 요소들을 정렬하는 작업. Comparator 사용
.distinct() > 중복 제거

List<String> list = Arrays.asList("a","b","c");

// filter
Stream<String> stream = list.stream()
	.filter(list -> list.contains("a"));
    // 'a'가 들어간 요소만 선택  [a]

// sort
Stream<String> stream = list.stream()
	.sorted() // [a,b,c] 오름차순 정렬
    .sorted(Comparator.reverseOrder()) // 내림차순
    
List<String> list = Arrays.asList("a","bb","ccc");
Stream<String> stream = list.stream()
	.sorted(Comparator.comparingInt(String::length)) // [ccc,bb,a] 문자열 길이로 정렬

자바가 가능한 곳이 더 많아서 자바로 골랐는데
파이썬 할 걸 그랬나 자바 왜케 낯설어짐 ;;

아무튼 프로그래머스 되게 좋아졌다.
이렇게 내가 푼 문제 기반으로 Problem Solving 평가 리포트도 주더라
갓 시작한 인간이라 5개 밖에 안품...
나중에 성장하는 모습 비교해서 또 포스팅해야지

카테고리/레벨별로 상세하게 알려준다.
꾸준하게 문제 풀이 하면 내가 어디가 취약한지 파악 가능할듯

그리고 데이터 쌓으라고 AI가 문제 추천도 해준다죠
저 하노이의 탑 문제 못풀고 필기 떨한거 어떻게 알았어요? ㅋ

반응형
반응형

오늘의 문제는 <행렬의 곱셈>인데요.
(문제 출처 : 프로그래머스 https://school.programmers.co.kr/learn/courses/30/lessons/12949)

프로그래머스는 블로그 게재시 문제 여지가 있어
자세한 내용 없이 문제 제목과 링크로 대체합니다. 

벌써부터 막혀서 힌트 오조오억번 봤다죠,,ㅠㅠ
이번 문제는 그래서 나중에 다시 풀어볼 예정입니다

행렬의 곱셈은 그냥 손으로 풀면 쉬운데요.
결과 행렬 (i,j)의 성분은 A 행렬 i 행의 값과 B 행렬 j 행의 값을 차례대로 곱하면서 더한 것과 같아요.

예를 들어 행렬 하나를 만들어 예시로 보면
  arr1                                                         arr2                                                               return
[[1, 4], [3, 2], [4, 1]]                                    [[3, 3], [3, 3]]                                    [[15, 15], [15, 15], [15, 15]]

사실은 이렇게 생긴 행렬들이고,
arr1                                                         arr2                                                               return
[[1, 4]                                                       [[3, 3]                                                           [[15, 15]  
[3, 2]                                                        [3, 3]]                                                           ,[15, 15]
[4, 1]]                                                                                                                            ,[15, 15]]

파랑색으로 표시한 return 배열의 151*3 + 4*3 의 결과에요.
arr1                                                         arr2                                                               return
[[1, 4]                                                        [[3, 3]                                                           [[15, 15]  
[3, 2]                                                        [3, 3]]                                                           ,[15, 15]
[4, 1]]                                                                                                                            ,[15, 15]]

이렇게 순서대로 더해 나가는거죠!

출처 : 수학방(mathbang.net/562)

이걸 조금 더 고급지게 정리해보자면
A 행렬의 크기가 (m * k), B 행렬의 크기가 (k * n) 일 때
두 행렬의 곱 연산 결과는 m * n 이 됩니다.
A의 행의 개수 k와 B의 열의 개수 k를 기준으로 곱하기 때문이에요.
그래서 k는 똑같아야 해요.
이번 문제에서는 곱할 수 있는 배열만 주어진다는 조건을 걸어
k가 똑같다는 걸 알려줬는데요.
만약 이런 조건이 없다면 두 k를 비교해 곱하기가 가능한지 고려하는 연산도 추가해야 합니다.

다시 문제로 돌아와서

class Solution {
    public int[][] solution(int[][] arr1, int[][] arr2) {
        int r1 = arr1.length;
        int c1 = arr1[0].length; // arr1의 행과 열 계산 c1 = k
        
        int r2 = arr2.length; // c1 = r2 = k
        int c2 = arr2[0].length; // arr2의 행과 열 계산
        
        // 결과 행렬 크기는 앞쪽 행렬의 행(r1) * 뒷쪽 행렬의 열(c2)
        int[][] answer = new int[r1][c2];
        
        for (int i=0; i<r1; i++){ // arr1의 각 행
            for (int j=0; j<c2; j++){ // arr2의 각 열을 반복하는데
                
                for(int k=0; k<c1; k++){
                	// 두 행렬의 데이터를 곱해야 하는데 k가 반복되어야 함
                   answer[i][j] += arr1[i][k] * arr2[k][j];
                    // [0][0] = [0][0] * [0][0]
                    // [0][0] = [0][1] * [1][0]
                    // [0][1] = [0][0] * [0][1]
                    // [0][1] = [0][1] * [1][1]
                }
            }
        }
        return answer;
    }
}

수학적 사고력이 없는
과거의 수포자 인간이라 힘들었따^^
이 문제는 무조건 나중에 다시 풀어봐야지

 

반응형

+ Recent posts