블로그

Depth

인프런 워밍업 클럽 스터디 2기 - 백엔드 클린코드, 테스트코드 3주차 발자국

 3주차부터 Practical Testing (실용적인 테스트 가이드) 강의로 넘어가게 되었다.  Section1) Intro강의에서 학습하게 될 것1) 테스트 코드가 필요한 이유2) 좋은 테스트 코드란?3) 실제 실무에서 진행하는 방식 그대로 테스트를 작성해가면서 API를 설계하고 개발하는 방법4) 정답은 없지만, 오답은 있다! 구체적인 이유에 근거한 상세한 테스트 작성 팁 Section2) 테스트는 왜 필요할까?1) 테스트는 왜 필요할까?- 테스트 코드를 작성하지 않는다면 코드의 변화가 생기는 매 순간마다 발생할 수 있는 모든 Case를 고려해야 한다..2) 테스트 코드가 병목이 된다면?- 테스트코드 자체가 유지보수하기 어려워진다.- 잘못된 검증이 이루어질 가능성이 생긴다..3) 올바른 테스트 코드는?- 자동화 테스트로 비교적 빠른 시간 안에 버그를 발견할수 있고, 수동 테스트에 드는 비용을 크게 절약할 수 있다. Section3) 단위 테스트Junit5로 테스트하기1) 단위 테스트- 작은 (ex, 클래스 or 메서드) 코드 단위를 독립적으로 검증하는 테스트- 검증속도가 빠르고, 안정적이다.2) Junit5- 단위 테스트를 위한 테스트 프레임워크- XUnit - Kent Back, - Sunit (Samltalk), Junit(Java), NUnit(.NET)- Spring-boot-starter-test 라이브러리를 통해 사용 가능하다..3) AssertJ- 테스트코드 작성을 원활하게 돕는 테스트 라이브러리- 풍부한 API, 메서드 체이닝 지원- Spring-boot-starter-test 라이브러리를 통해 사용 가능하다.테스트 케이스 세분화1) 해피 케이스- 요구사항을 그대로 만족하는 케이스- 경계값 테스트 : 범위 (이상, 이하, 초과, 미만), 구간, 날짜 등이 중요.2) 예외 케이스- 경계값 테스트 : 범위 (이상, 이하, 초과, 미만), 구간, 날짜 등이 중요.테스트하기 어려운 영역 분리하기1) 테스트하기 어려운 영역- 관측할때마다 다른 값에 의존하는 코드→ 현재 날짜/시간, 랜덤 값, 전역변수/함수, 사용자 입력 등- 외부 세계에 영향을 주는 코드→ 표준 출력, 메시지 발송, 데이터베이스에 기록하기 등.2) 순수 함수 - 테스트하기 쉬운 코드- 같은 입력에는 항상 같은 결과- 외부 세상과 단절된 형태- 테스트하기 쉬운 코드  Section4) TDDTDD (Test Driven Development)1) TDD- 프로덕션 코드보다 테스트 코드를 먼저 작성하여 테스트가 구현 과정을 주도하도록 하는 방법론.2) TDD의 핵심 가치-기존) 선 기능 구현, 후 테스트 작성의 문제점→ 테스트 자체의 누락 가능성→ 특정 테스트(==해피 케이스) 케이스만 검증할 가능성→ 잘못된 구현을 다소 늦게 발견할 가능성- TDD) 선 테스트 작성, 후 기능 구현→ 복잡도가 낮은(==유연하며 유지보수가 쉬운), 테스트 가능한 코드로 구현할 수 있게 한다.→ 쉽게 발견하기 어려운 엣지(Edge) 케이스를 놓치지 않게 해준다.→ 구현에 대한 빠른 피드백을 받을 수 있다.→ 과감한 리팩토링이 가능해진다.Section5) 테스트는 [문서]다테스트는 [문서]다1) 테스트 == 문서- 프로덕션 기능을 설명하는 테스트 코드 문서- 다양한 테스트 케이스를 통해 프로덕션 코드를 이해하는 시각과 관점을 보완- 어느 한 사람이 과거에 경험했던 고민의 결과물을 팀 차원으로 승격시켜서, 모두의 자산으로 공유.DisplayName을 섬세하게1) DisplayNamed을 섬세하게 적기- 메서드 자체의 관점보다 도메인 정책 관점으로, 도메인 용어를 사용하여 한층 추상화된 내용을 담기- 테스트의 현상(ex, 성공한다… 실패한다 등)을 중점으로 기술하지 말 것.BDD 스타일로 작성하기1) BDD (Behavior Driven Development)- TDD에서 파생된 개발 방법으로- 함수 단위의 테스트에 집중하기보다, 시나리오에 기반한 테스트케이스(TC) 자체에 집중하여 테스트하는 기법- Given / When / Then 방식 사용→ Given : 시나리오 진행에 필요한 모든 준비 과정 (객체, 값, 상태 등)→ When : 시나리오 행동 진행→ Then : 시나리오 진행에 대한 결과 명시, 검증.Mission 12) 단위 테스트 작성studycafe 프로젝트에서 InputHandler, StudyCafePassOrder, StudyCafeSeatPass 클래스에 대한 테스트 코드를 작성하였다.고민했던 점으로는 Scanner를 통해 사용자 입력을 받는 로직을 테스트하기 위해 Mock을 사용할 수 있지만, Mock 대신 InputStream과 System.setIn()을 통해 입력해주는 방식을 선택했다.작은 메서드 단위로 단위 테스트를 진행하니 코드도 복잡해지지 않고 간결하여 테스트 하기가 수월하였다.Github Code. Section6) Spring & JPA 기반 테스트레이어드 아키텍처(Layered Architecture)1) Layered Architecture- Presentation Layer, Business Layer, Persistence Layer로 구분- 아키텍처를 분리하는 이유 : 관심사의 분리.Spring / JPA 훑어보기 & 기본 엔티티 설계1) Library vs Framework- Library : 외부에서 이미 개발된 코드를 가져온다. (내 코드가 주체가 되어 동작)- Framework : 이미 동작하는 환경이 구성되어 있고, 내 코드는 프레임안에서 수동적으로 동작.2) Spring- IoC (inversion of Control) : 객체의 생성과 의존성 관리를 프레임워크에서 대신 수행- DI (Dependency Injection) : 외부에서 객체 간의 의존성 주입을 통해 결합도를 낮춰줌- AOP (Aspect Oriented Programming) : 공통 관심사를 별도의 로직으로 분리해 코드 중복을 줄여주고 모듈화.3) JPA-Java Persistance API- Java 진영의 ORM 기술 표준- 반복적인 CRUD SQL을 생성 및 실행해주고, 여러 부가 기능들을 제공- Spring 진영에서는 JPA를 한번 더 추상화한 Spring Data JPA 제공- 주로 사용되는 어노테이션들→ @Entity, @Id, @Column→ @ManyToOne, @OneToMany, @OneToOne, @ManyToMany. Layer별 테스트1) Persistence Layer- Data Access의 역할- 비즈니스 가공 로직이 포함되어서는 안됨, Data에 대한 CURD에만 집중한 레이어.2) Business Layer- 비즈니스 로직을 구현하는 역할- Persistence Layer와의 상호작용(Data를 읽고 쓰는 행위)를 통해 비즈니스 로직을 전개- 트랜잭션을 보장.3) Presentation Layer- 외부 세계의 요청을 가장 먼저 받는 계층- 파라미터에 대한 최소한의 검증을 수행.회고- 테스트 코드 작성을 의무적으로 작성 하지 않는 환경에서 일을 해왔는데, 스터디를 진행하면서 단위 테스트 코드 작성의 중요성과 필요성을 깨달았다. 모든 예외 케이스를 조기에 발견해서 대처할 순 없겠지만 내가 작성한 코드 범위내에서 테스트가 필요한 영역들을 분리하여 로직이 의도한 대로 동작하는지 검증하는 작업은 백엔드 개발자의 숙명이라는 생각이 들었다.이제 Mock과 테스트 방법론에 대한 강의가 남아있는데, 마지막 주차도 지금처럼 묵묵히 학습해 나갈 것이다.출처https://inf.run/jsvaAhttps://inf.run/kHiWM      

백엔드워밍업클럽테스트코드2기depthmy

Depth

인프런 워밍업 클럽 스터디 2기 - 백엔드 클린코드, 테스트코드 2주차 발자국

 강의 수강 Section6) 코드 다듬기좋은 주석인란? -우리가 가진 모든 표현 방법을 총동원해 코드에 의도를 녹여냈음에도 불구하고 전달해야할 정보가 남았을때 주석을 사용해야 함. 주석을 사용하면 코드가 아닌 주석에 의존한다는 것을 알아야 함   변수와 메서드의 나열 순서- 변수는 사용하는 순서대로 나열- 메서드는 1순위가 공개 메서드, 2순위가 비공개 메서드 순으로 나열     Intellij IDE 활용- 코드 포맷 정렬 단축키 : Ctrl + ALT + L- Sonarlint : 오류, 버그, 스타일 등을 알려주어 문제점 개선을 도와주는 Plugin- .editorConfig : 확장자마다 스타일을 다르게 줄수 있게 도와주는 설정파일 Section7) 리팩토링 연습리팩토링 포인트- 추상화 레벨 : 중복 제거, 메서드 추출, 객체에 메시지 보내기- 객체의 책임과 응집도 : IO 통합, 일급 컬렉션, display()의 책임, Order 객체- 관점의 차이로 달라지는 추상화 : 구현에 초점을 맞춘 추상화 VS 도메인 개념에 초점을 맞춘 추상화 Section8) 기억하면 좋은 조언들능동적 읽기- 복잡하거나 엉망인 코드를 읽고 이해하려 할때, 리팩토링하면서 읽기-> 공백으로 단락 구분-> 주석으로 이해한 내용 표기하며 읽기-> 메서드와 객체로 추상화 해보기- 핵심 목표는 우리의 도메인 지식을 늘리는 것이고, 이전 작성자의 의도를 파악하는 것.2. 오버 엔지니어링- 필요한 적정 수준보다 더 높은 수준의 엔지니어링을 말함-> ex) 구현체가 하나인 인터페이스 : 구현체를 수정할 때마다 인터페이스도 수정해야 함.-> ex) 너무 이른 추상화 : 정보가 숨겨지기 때문에 복잡도가 높아지고, 후대 개발자들이 선대의 의도를 파악하기가 어려움  3. 은탄환은 없다- 항상 정답인 기술은 없음.- 오버 엔지니어링이 되더라도 한계까지 리팩토링 연습을 해보고, 적정 수준, 적정 시점을 깨닫기가 필요. 회고)2주차까지 쉼 없이 달려왔는데, readable code 강의가 끝난것이 끝이 아니라, 새로운 시작인 것 같다.이 강의를 통해 클린코드로 가는 발검을을 한 발자국 내딛은것 같다. 클린코드 책도 한번 읽어봐야 겠다는 생각도 들었다.3주차부터 Practical Testing 강의가 시작되는데, 테스트 코드 강의도 빠짐없이 수강하여 포기하지 않고 스터디를 끝까지 이어 나갈 것이다. 미션Day7-Mission3) '스터디 카페 이용권 선택 시스템' 프로젝트 리팩토링 리팩토링 진행 내용코드 중복 제거- if문 내에 중복된 지역 범위 코드들을 전역화메서드로 추출- 동일한 맥락의 코드들을 메서드화 NullPointException 방지 - Null 값 처리를 위한 Optional 사용메서드 오버로딩 추가 - Null 매개변수 사용을 외부에 드러내지 않기 위해 메서드를 오버로딩하여 사용Github Code 회고- 추상화 관점에서의 리팩토링을 어느정도 진행하였는데, 객체의 책임과 응집도 관점에서 좀 더 리팩토링을 진행해야 겠다는 생각과 함께 리팩토링에는 끝이 없다는 것을 느끼고 있다. 어쩌면 내가 진행한 readable한 code가 관점에 따라 누군가에게는 그렇지 않을수도 있다는 생각이 든다.  출처https://inf.run/jsvaAhttps://inf.run/kHiWM

백엔드워밍업클럽클린코드2기depthmy

Depth

인프런 워밍업 클럽 스터디 2기 - 백엔드 클린코드, 테스트코드 1주차 발자국

 Section2) 추상Clean Code를 추구해야 하는 이유나를 포함해 다른 개발자가 코드를 읽고 이해하는데 드는 시간이 절약된다.프로그램의 정의프로그램 = (데이터가 담긴) 변수 + (변수를 사용하는) 메서드의 집합추상중요한 정보는가려내어 남기고, 덜 중요한 정보는생략하여 버리는 것적절한 추상화 : 도메인 안에서, 정말 중요한 핵심 개념만 남겨서 표현하는 것이다. 추상화의 가장 대표적인 행위는 이름을 짓는 것이다.(변수) 이름 짓기 Tip1) 단수와 복수 구분- 끝에 '(e)s'를 붙여 구분2) 이름 줄이지 않기- 일반적으로 무엇이든 이름을 줄여서 사용하는 것은 가독성을 제물로 바쳐 효율성을 얻는 것인데,유지보수 관점에서 득보다 실이 크다.- 관용어 처럼 자주 사용하는 것은 줄여도 괜찮다.=> ex, column -> col, latitude -> lat=> count -> cnt (추천X)3) 은어/방언 사용X- 현재의 팀만 아는 용어 사용 금지4) 좋은 코드를 보고 습득하기메서드와 추상화한 메서드는 반드시 한가지 일만 해야 한다.2가지 일을 하게된다면 추상화된 내용(==메서드 선언부)을 보고 구체적인 내용(메서드 구현부)의 유추가 어렵다.추상화 레벨외부 세계(==추상화 레벨이 높은 세게)와 내부세계(==추상화 레벨이 낮은 구체)를 나누었을때 추상화 레벨이 달라지는데, 하나의 세계 안에서 각 로직의 추상화 레벨은 동등해야 한다.매직 넘버, 매직 스트링매직 넘버(스트링) : 의미를 갖고 있으나, 상수로 추출되지 않은 숫자, 문자열 등을 말한다.Mission 1) 생각나는 추상과 구체의 예시Execute Login1) 클라이언트가 서버에 암호화된 ID와 Password를 HTTP Body에 담아 Request를 보낸다.2) 서버는 ID와 Password를 복호화하고 각 필드에 대한 유효성 검사를 한다.3) 유효하다면, 복호화된 ID와 Password를 DB에 보내 가입된 유저인지 확인한다.4) 가입된 유저라면, Session Cookie 혹은 JWT 등에 사용자 정보를 담아 클라이언트에 Response로 보낸다.Section3) 논리, 사고의 흐름뇌 메모리 적게 쓰기최소의 인지적 노력으로 (뇌 메모리를 줄여) 최대의 정보를 제공해야 한다,Early returnelse (if) 대신 return을 사용하는 것을 권장한다,.사고의 Depth 줄이기1) 중첩 반복문을 메서드 혹은 Stream을 통해 개선하면 좋다.2) 사용할 변수는 가깝게 선언하기공백라인도 의미를 가진다.부정어if문에서 부정어(!) 사용시 메서드화하여 분리하기해피케이스와 예외처리1) 예외가 발생할 가능성을 낮추는게 좋다. (ex, 사용자 입력, 객체 생성자, 외부 서버의 요청 등)2) 의도한 예외(ex, Custom Exception)와 예상하지 못한 예외 구분하기3) NullPointException은 항상 발생하지 않게 해야 한다.- 메서드 설계시 return null을 자제하고, Optional 사용을 고려하기 - Optional의 orElse(), orElsGet(), orElseThrow() 메서드의 차이 이해 필요.Section4) 객체지향 패러다임객체 설계1) 새로운 객체 생성시 주의사항- 1개의 관심사로 명확하게 책임이 정의되었는지 확인 필요- 생성자, 정적 팩토리 메서드에서 유효성 검증이 가능함을 인지- setter 사용 자제- getter도 사용 자제하고, 반드시 필요한 경우에만 추가 - 필드의 수는 적을수록 좋다2) 도메인 지식은 만드는 것이 아니라 발견하는 것Mission 2-1) 읽기 좋은 코드로 리팩토링#중요하게 생각한 점1) order 객체 Null 체크 필요2) if-else문들 if문으로 개선3) 부정어구(!) 없애기4) getter 제거 → 객체에 의미가 담긴 메서드를 별도 생성5) 공백라인 사용public boolean validateOrder(Order order) { //1) Null Check if (order == null) { log.info("주문을 확인할 수 없습니다."); return false; } //2) remove (getter) if (order.hasNoItems()) { log.info("주문 항목이 없습니다."); return false; } //3) remove (! + if-else + getter) if (order.isInvalidTotalPrice()) { log.info("올바르지 않은 총 가격입니다."); return false; } //4) remove (! + if-else) if (order.hasNoCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false } return true; } public class Order { private List<Item> items; private double totalPrice; private CustomerInfo customerInfo; public boolean hasNoItems() { return items == null || items.isEmpty(); } public boolean isInvalidTotalPrice() { return totalPrice <= 0; } public boolean hasNoCustomerInfo() { return customerInfo == null; } }Mission 2-2) 자기만의 언어로 정리한 SOLID1) SRP- Single Responsibility Principle (단일 책임의 원칙)- “하나의 클래스에 변경이 발생한다면 그 이유(==책임)는 반드시 하나여야 한다”는 원칙- ex) 프로그램 실행 부와 실제 실행 로직은 나누어져 있어야 한다.- 높은 응집도, 낮은 결합도와 관련 있음.2) OCP- Open-Closed Principle (개방-폐쇄 원칙)- “기존 코드의 변경 없이, 기능을 확장할 수 있어야 한다”는 원칙3) LSP- Liskov Substitution Principle (리스코프 치환 원칙)- 상속 구조에서, “부모 클래스의 인스턴스는 자식 클래스의 인스턴스로 치환될수 있어야 한다”는 원칙 4) ISP- Interrface Segregation Principle (인터페이스 분리 원칙)- ”하나의 구체 클래스는 자신이 사용하지 않는 인터페이스에 의존해서는 안된다”는 원칙(이때는, 인터페이스를 2개로 분리해야 한다) 5) DIP- Dependency Inversion Principle (의존성 역전 법칙)- “레벨이 높은 모듈(ex, Lv2 카페)은 구체 모듈(ex, Lv0 커피)에 바로 의존해서는 안되고 추상화(ex, Lv1 음료)에 의존해야 한다”는 원칙 미션을 통해 SOLID 원칙을 다시 한번 상기시킬수 있었는데, 실제 업무에 활용하기 위해서는 스스로 좀더 깊은 학습이 필요할것 같다. 그리고 클린코드의 방법론을 미션을 통해 적용해 보면서 코드가 좀 더 잘 읽히고 이해하기 쉬워지는 것을 직접 느낄수 있었다.Section5) 객체지향 적용하기상속과 조합상속은 시멘트처럼 굳어지는 구조이기 때문에 수정이 어려우므로, 상속보다 조합을 사용하는게 좋다.Value Object도메인의 어떤 개념을 추상화하여 표현한 값 객체로, 불변성, 동등성, 유효성 검증 등을 보장해야 한다.VO (Value Object)는 내부의 모든 값이 다 같아야 동등한 객체로 취급한다. 이에 반해 Entity는 식별자만 같으면 동등한 객체로 취급한다.일급 컬렉션컬렉션(List, Set, Map 등)을 포장하면서, 컬렉션만을 유일하게 필드로 가지는 객체로, 단 하나의 컬렉션 필드만을 가진다.만약, getter로 컬렉션을 반환할 일이 생긴다면 외부 조작을 피하기 위해 꼭 새로운 컬렉션(List<Object타입>)으로 만들어 반환하는게 좋다. 스터디를 진행하면서, 처음에는 완벽하게 다 이해하려고 생각해 학습에 시간이 오래걸렸는데, 이제는 내가 당장 적용해 볼수 있는 부분들을 Target으로 하여 배워나가야 겠다는 깨달음을 얻었다. 출처https://inf.run/jsvaAhttps://inf.run/pZXb7

백엔드워밍업클럽클린코드2기depthmy

Docker Compose를 활용해 컨테이너 관리하기

Docker Compose를 사용하는 이유Docker Compose란?여러 개의 Docker 컨테이너들을 하나의 서비스로 정의하고 구성해 하나의 묶음으로 관리할 수 있게 도와주는 툴. Docker Compose를 사용하는 이유여러 개의 컨테이너를 관리하는 데 용이복잡한 명령어로 실행시키던 걸 간소화 시킬 수 있음[실습] Docker Compose 전체 흐름 느껴보기 (Nginx 설치 및 실행)Docker CLI로 컨테이너를 실행시킬 때docker run --name webserver -d -p 80:80 nginxDocker Compose로 컨테이너를 실행시킬 때compose.yml 파일 작성하기.services: my-web-server: container_name: webserver image: nginx ports: - 80:80services: my-web-sever: Docekr Compose에서 하나의 컨테이너를 서비스(service)라고 부른다. 이 옵션은 서비스에 이름을 붙이는 기능이다.container_name: webserver컨테이너를 띄울 때 붙이는 별칭이다. CLI에서 --name web-werver역할과 동일하다.image: nginx컨테이너를 실행시킬 때 어떤 이미지를 사용할 지 정의하는 명령어이다. docker run [이미지명]와 동일한 역할이다.ports: 포트 매핑은 어떻게 할 지를 설정하는 옵션이다. CLI에서 -p 80:80역할과 동일하다.compose 파일 실행시키기docker compose up -dcompose 실행 현황 보기docker compose pscompose로 실행된 컨테이너 삭제docker compose down자주 사용하는 Docker Compose CLI 명령어compose 파일 작성services: websever: container_name: webserver image: nginx ports: - 80:80compose.yml에서 정의한 컨테이너 실행docker compose up # 포그라운드에서 실행 docker compose up -d # 백그라운드에서 실행-d: 백그라운드에서 실행Docker Compose로 실행시킨 컨테이너 확인하기# compose.yml에 정의된 컨테이너 중 실행 중인 컨테이너만 보여준다. docker compose ps # compose.yml에 정의된 모든 컨테이너를 보여준다. docker compose ps -aDocker Compose 로그 확인하기# compose.yml에 정의된 모든 컨테이너의 로그를 모아서 출력한다. docker compose logs컨테이너를 실행하기 전에 이미지 재빌드하기 docker compose up --build # 포그라운드에서 실행 docker compose up --build -d # 백그라운드에서 실행compose.yml에서 정의한 이미지 파일에서 코드가 변경 됐을 경우, 이미지를 다시 빌드해서 컨테이너를 실행시켜야 코드 변경된 부분이 적용된다. 그러므로 이럴 때에는 --build옵션을 추가해서 사용해야 한다. 참고: docker compose upvs docker compose up --build -- docker compose up: 이미지가 없을 때만 빌드해서 컨테이너를 실행시킨다. 이미지가 이미 존재하는 경우 이미지를 빌드하지 않고 컨테이너를 실행시킨다. -- docker compose up --build : 이미지가 있건 없건 무조건 빌드를 다시해서 컨테이너를 실행시킨다. 이미지 다운받기 / 업데이트하기docker compose pullcompose.yml에서 정의된 이미지를 다운 받거나 업데이트 한다.로컬 환경에 이미지가 없다면 이미지를 다운 받는다.로컬 환경에 이미 이미지가 있는데, Dockerhub의 이미지와 다른 이미지일 경우 이미지를 업데이트 한다.Docker Compose에서 이용한 컨테이너 종료하기docker compose down[실습] Docker Compose로 Redis 실행시키기compose.ymlservices: my-cache-server: image: redis ports: - 6379:6379 compose 파일 실행 및 확인docker compose up -d docker compose ps docker logs [컨테이너 ID 또는 컨테이너명] docker exec -it [컨테이너 ID 또는 컨테이너명] bash redis-cli 127.0.0.1:6379> set 1 jscode 127.0.0.1:6379> get 1 docker compose down[실습] Docker Compose로 MySQL 실행시키기compose.ymlservices: my-db: image: mysql environment: # -e MYSQL_ROOT_PASSWORD=password 역할 MYSQL_ROOT_PASSWORD: pwd1234 volumes:# v {호스트 경로}:/var/lib/mysql 역할 - ./mysql_data:/var/lib/mysql ports: - 3306:3306environment: ...:CLI에서 -e MYSQL_ROOT_PASSWORD=password 역할과 동일하다.volumes: ...:CLI에서 -v {호스트 경로}:/var/lib/mysql 역할과 동일하다.compose 파일 실행 및 확인docker compose up -d docker compose ps docker compose down[실습] Docker Compose로 백엔드(Spring Boot) 실행시키기AppController@RestController public class AppController { @GetMapping("/") public String home() { return "Hello, World!"; } }DockerfileFROM openjdk:17-jdk COPY build/libs/*SNAPSHOT.jar /app.jar ENTRYPOINT ["java", "-jar", "/app.jar"]Spring Boot 프로젝트 빌드./gradlew clean buildcompose.ymlservices: my-server: #compose.yml이 존재하는 디렉토리(.)에 있는 Dockerfile로 이미지를 생성 build: . ports: - 8080:8080build: .:compose.yml이 존재하는 디렉토리(.)에 있는 Dockerfile로 이미지를 생성해 컨테이너를 띄우겠다는 의미이다.compose 파일 실행 및 확인docker compose up -d --build docker compose ps docker compose down[실습] Docker Compose로 백엔드(Nest.js) 실행시키기Next.js 프로젝트 만들기# Nest CLI 설치 npm i -g @nestjs/cli # nest new {프로젝트명} nest new my-serverDockerfileFROM node WORKDIR /app COPY . . RUN npm install RUN npm run build EXPOSE 3000 ENTRYPOINT [ "node", "dist/main.js" ].dockerignorenode_modulescompose.ymlservices: my-server: build: . ports: - 3000:3000compose 파일 실행 및 확인docker compose up -d --build docker compose ps docker compose down[실습] Docker Compose로 프론트엔드(Next.js) 실행시키기Next.js 프로젝트 만들기npx create-next-app@latestDockerfileFROM node:20-alpine WORKDIR /app COPY . . RUN npm install RUN npm run build EXPOSE 3000 ENTRYPOINT [ "npm", "run", "start" ].dockerignorenode_modulescompose.ymlservices: my-web-server: build: . ports: - 80:3000compose 파일 실행 및 확인docker compose up -d --build docker compose ps docker compose down[실습] Docker Compose로 프론트엔드(HTML, CSS, Nginx) 실행시키기HTML, CSS 파일 만들기index.html<!DOCTYPE html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="style.css"> </head> <body> <h1>My Web Page</h1> </body> </html>style.css* { color: blue; }DockerfileFROM nginx COPY ./ /usr/share/nginx/htmlcompose.ymlservices: my-web-server: build: . ports: - 80:80compose 파일 실행 및 확인docker compose up -d --build docker compose ps docker compose down 

자바스크립트 변수 vs 상수

변수 let변하는 값..이라고 쉽게 얘기하지만 정확하게 얘기하자면, 데이터를 담고 있는 공간을 가리키는 이름임.꼭 선언 후에 값을 할당해야 함. 반대로 할 경우 오류가 남.선언 후 초기화를 해줘야 함, 그래야 예기치 않은 오류가 생기는 것을 방지 할 수 있음.let 롯데리아 = "햄버거";롯데리아, 라는 변수명을 정했고 그 안에 햄버거라는 값을 할당했음. 콘솔에 찍었을 때 햄버거라는 값이 할당 되었음을 확인함.+++ undefined는 선언만 했을 뿐 값이 할당되지 않았음을 얘기하고 있음.상수 const변수와는 달리 하나의 값만 할당할 수 있음. 한번 담으면 바꿀 수 없음. 한번 담고 나면 바꿀 수 없기 때문에 선언과 동시에 초기화를 해야 함.그래서 보통 여러 번 값을 할당할 때 보다는 변하지 않을 값으로 할당할 때 쓰기에 적합함. 선언 후 초기화 하고 나서 호출했을 때 잘 나옴. 반면에 선언 후 할당하려고 하니 오류 남. var이것도 변수 선언 키워드임. 근데 안 씀.보통 변수는 선언을 하고 나서 값을 할당할 수 있는데, 얘는 값을 할당하고 선언을 해도 동작이 되는 미친놈임.console.log(a); // undefined var a = 10; console.log(a); // 10실제로 내부는 이럼.var a; // 선언이 먼저 '끌어올려짐'(hoisting) console.log(a); // 아직 값이 없으니까 undefined a = 10; // 이제 값 할당 console.log(a); // 10선언이 코드의 맨 위로 끌어올려지는 현상 = 호이스팅이라고 함.즉, “호이스팅은 변수 선언만 코드 맨 위로 끌어올려지는 현상이고,var는 그게 적용돼서 ‘선언 전에도 쓸 수 있는 것처럼 보이는’ 애.”= 값이 올라가는 게 아니라, 선언만 올라간다 이거 쓰면 코드 오류 나고, 꼬이고 {} 블럭 스코프 무시함.  그래서 요즘은 안 쓰고 변수는 let, 상수는 const를 쓰는 거임.

프론트엔드자바스크립트

인공지능과 추천 시스템 강의 노트 — 2025. 9. 27. (4/16)

들어가며 가을의 여의도에서는 매 주말 굵직한 일정들이 있는지, 이번 주는 불꽃놀이가 있다 했다. 아침 출근길부터 캠핑 장비 , 야유회 장비들을 들고 여의도로 오는 가족들이 유난히 많아 보이고, 수업이 끝나는 오후 4시부터는 교통 통제와 지하철역 무정차 등의 일들이 있다 하여, 오늘 수업은 중간에 쉬는 시간 없이 2시간 정도를 한 번에 이야기하는 강행군을 진행하게 되었다.  추석 연휴 사이에 있는 두 번의 온라인 강의에 대한 진행에 대해 이야기를 하고, 모이고 있는 중간, 기말 과제들의 내용들에 대한 이야기들을 정리하였다. 서로 이야기가 잘 통해 미리 제출해 준 학생들이 있는가 하면, 아직 내용이 전달이 잘 덜 된 학생들도 있는 듯한데, 시간을 조금 더 들여 이야기를 나누어야 하겠다 싶다. 준비한 내용들 4주) 강의 updateAI 강의 - 4강, 5강추천시스템 - 4. 추천 알고리즘 개요추천시스템 - 7. 평가나눈 이야기들 AI 쪽 이야기는 상대적으로 적었지만, 네이버 파이넨셜과 카카오톡 등의 굵직한 제품들과 관련된 뉴스들이 많이 나오고 있다. 국민 서비스들로 자리잡은 것들이기에 사연이 더 있다 하겠고 호불호 혹은 끼치는 영향이 클텐데, 예전보다 정보들이 쉽게 돌아다니기에 좋다 나쁘다의 의견들이 퍼지는 속도들도 상당하다 하겠다.이번 주에는 AI 에게 “롯데 자이언츠 몇 게임 남았어?” 라는 질문을 하였고, 당시 기준으로 정답은 4게임인데, 꼼꼼하게 날짜 계산해 가며 챙겨야 하는 어려운 질문인지 모든 AI 서비스들이 정답과는 다른 말들을 하였다. 9월 첫 주 기준으로 이야기를 하기도, 대충 얼버무리기도 하기도 하는데, 제품의 입장에서 authoritative contents 가 검색에 안 잡히는 게 그 원인인 듯하다. 상대적으로 미국은 espn 이나 mlb 사이트들이 최신으로 유지되는 것에 비해 그 내용들이 부족한 것이라 하겠다.AI 강의 부분은 책의 뒷부분을 나누었다. AI 가 전방위적으로 도입된 후에 순작용보다는 부작용 혹은 같이 풀어나가야 할 과제들을 여러 시각에서 정부 정책과 함께 고민하는 정도로 나누었고, 이 책을 같이 읽는 건 일단 여기까지로 정리를 했다. 이후에 AI 관련한 내용들은 계속 쏟아질 뉴스들을 따라잡는 것들과 10월 9일에 발표된다는 stateof AI 를 가지고 10월 이야기들을 마무리하게 될 거 같고, 과목 후반기에 필요한 내용들을 더 준비해야 하겠다.2025년 stateof AI report 는 10월 9일에 발표됨.추천 시스템 부분은 교재에서 4장 추천 알고리즘의 개요 와 7장 평가 챕터를 다루었다. 5장부터는 실제 구현이 포함되는, 코딩이 포함되는 내용일 것이라 지표들을 언급해 놓고 시작하는 것이 낫겠다고 생각했는데, 이 부분은 처음 보는 사람들에게는 한없이 어렵고, 쓰던 사람들한테는 별 고민 없이 쓰는 내용들이라 편차가 있겠다. 서비스의 시각, 완제품의 시각에서 접근을 한다고 하지만, 모든 의사판단의 기준에는 데이터가 있어야 하고, 오프라인에서 비교할 수 있는 이 지표들은 필수적으로 알아야 하고, 실제 업무에서 '왜?' 라는 질문을 하고 들을 수 있어야 하겠다. 아래는 한 장으로 요약된 추천 시스템 알고리즘. Collaborative Filtering in Recommender Systems 이후 MovieLens 를 가지고 하는 예제들은 그 자체로 의미가 있지만, 손을 좀 더 보아야 하겠다는 생각인데, 입코딩 혹은 따라서 해 보는 vibe coding 으로 추석 연휴 후에 수업 시간에 한 시간 정도는 따라 가 보아야 하겠고, EDA , random / popular 추천 정도까지만이라도 되면 좋겠는데, 내용을 좀 더 다듬어서 연습을 좀 더 해야 겠다는 생각이다. 환경이 어디까지 지원이 될 수 있을지 모르겠는데, 학교 컴퓨터에 cursor 를 설치할 수 있으면 좀 더 이것저것 해 볼 수 있지 싶다. ps. 다음 두 번의 온라인 녹화 수업까지 해서 이런저런 핑계로 수업 자체가 소홀하게 되는게 아닌가 반성을 잠깐 했다. 한 시간 이르게 끝내어 일산에 부모님 성묘를 다녀올 수 있었고, 이후 조금 더 집중해서 남은 시간들을 챙겨 보려 한다. 질문들Q. ChatGPT 는 왜 계산을 잘 못 하나요 ?A. 요즘에 조금 더 나아졌지만, 가장 큰 문제는 질문을 문자로 받아 들여서 그것을 도서관이나 문헌에서 찾으려 하는 방법에 가깝다 하겠습니다. LLM 에게 한 번 물어 봐서 최대한 그 결과를 이용하려는 방식에서 오는 한계일 텐데요. 요즘은 사용자 질문에 바로 응대하는 것보다 여러 번 LLM 혹은 서비스들에게 필요한 일들을 chain of thought 같은 식으로 질문과 대답들을 내부에서 처리한 후에 이 질문을 이해해서 계산기 혹은 계산 서비스에 필요한 값들을 parameter 로 전달해서 푸는 방식으로들 해결해 나가고 있습니다.

대학 교육 기타

MCP를 이용해서 LLM 서비스 만들기 — 예제와 함께

이 글은 제가 NIA [한국지능정보사회진흥원]의 < 디지털서비스 이슈리포트 > 2025년 9월호에 기고한 글입니다. 원본 글 '2025년 AI 현황 보고서 리뷰'를 이곳에서도 공유합니다.들어가며 - LLM 이후최근 몇 년간 대형 언어 모델(LLM)은 눈부신 발전을 이루며 AI의 패러다임을 바꿔 놓았다. GPT, 클로드, 제미나이와 같은 LLM들은 단순 질의응답을 넘어, 문서 요약, 코드 작성, 창작물 제작 등 복잡한 작업을 능숙하게 처리하고 있으며, 연구실을 넘어 실제 비즈니스와 서비스 현장에서도 핵심적인 역할을 수행한다.하지만 LLM 단독으로는 여전히 한계가 존재한다. 모델 자체는 방대한 학습 데이터를 기반으로 추론하지만, 실시간으로 변화하는 데이터 연동, 최신 정보 반영, 외부 시스템 API 호출과 같은 기능은 직접 수행할 수 없다. 예를 들어 현재 날씨 정보나 특정 기업의 실시간 재무 데이터를 분석하는 작업은 LLM 혼자서 처리하기 어려운데, 이러한 간극을 메우기 위해 새로운 기술적 접근이 필요하게 되었다.이번 글에서는 이에 소개되는 MCP(Model Context Protocol)를 이용해서 어떻게 LLM 기반의 채팅 서비스에 추가적인 기능들을 할 수 있는지 예제와 함께 살펴 보도록 하겠다. MCP의 역할과 확장성그림 1 MCP 이전과 이후의 LLM에서의 서비스 연동( https://www.descope.com/learn/post/mcp )LLM의 한계를 극복하기 위해 등장한 것이 바로 MCP이다. 2024년 앤스로픽에서 처음 소개된 MCP는 LLM이 외부 시스템, API, 데이터베이스 등과 안전하게 연결되도록 돕는 것을 목표로 시작했는데, 이후 오픈AI, 구글 등 다른 주요 AI 기업들이 이를 채택하면서, MCP는 LLM 생태계의 사실상 표준으로 자리 잡고 있다.MCP는 LLM을 독립적인 존재가 아닌, 다양한 기능을 가진 외부 시스템과 연동되는 하나의 핵심 모듈로 만들어 준다. 예를 들어, 날씨 정보를 제공하는 서비스를 구축할 때 LLM은 사용자의 질문을 이해하고, MCP는 이를 외부 날씨 API와 안전하게 연결하여 실시간 데이터를 가져온다. 이 과정에서 모델은 데이터 접근에 직접 관여하지 않으며, MCP가 데이터 전달과 결과 통합을 전담한다. 이러한 접근 방식은 다음과 같은 장점을 가진다.유연성: 다양한 외부 API나 도구를 LLM에 쉽게 연결할 수 있다.효율성: LLM이 불필요한 추론을 줄이고, 필요한 정보만 정확하게 요청하도록 한다.안정성: LLM의 환각(Hallucination) 현상을 줄이고, 신뢰할 수 있는 정보를 기반으로 응답을 생성하도록 돕는다.이러한 MCP는 기업이 특정 LLM에 종속되는 이슈를 완화하면서 서비스의 확장성 및 유연성을 극대화하는 솔루션을 가능하게 한다. MCP를 활용한 서비스 구현: 날씨 서비스MCP의 작동 원리를 이해하기 위해 실제 코드들로 날씨 서비스를 구현해 본다. 이 서비스는 LLM이 사용자의 요청을 분석하여 실제 날씨 정보를 제공하는 외부 API를 호출하고, 그 결과를 바탕으로 응답을 생성한다. 도구(Tool) 정의와 핸들러 구현파이썬으로 구현하는 예제에서는 MCP 프레임워크를 사용한다. 이를 사용하면, 도구의 메타데이터와 실제 로직을 분리하여 관리할 수 있는데, 여기서 도구 메타데이터는 LLM에게 전달되는 정보로, 도구의 이름과 설명, 필요한 매개변수를 정의한다. 자세하게 적을 수록 정확한 때 도구가 불리고, LLM이 이후에 입력 변수들을 채우는 데 쓰인다.그림 2. 날씨 도구의 메타데이터 정의실제 외부 API(OpenWeatherMap)를 호출하여 데이터를 가져오는 함수를 작성한다. 이 함수는 LLM이 직접 호출하는 것이 아니라, 조건이 만족되었을 때 MCP 서버가 호출한다.그림 3. Open Weathermap 을 호출하는 날씨 도구의 구현 예제 McpServer에 도구 등록 및 실행McpServer는 도구의 메타데이터와 핸들러를 연결하고, 사용자 요청부터 최종 응답까지의 전체 과정을 관리하는 역할을 한다.그림 4. McpServer 등록 및 실행 예 각 LLM별 통합 예제McpServer는 내부적으로 각 LLM 공급자의 API에 맞춰 Tool 객체와 핸들러를 변환하는 어댑터 패턴을 사용한다. 개발자는 아래와 같은 내부 구현을 신경 쓸 필요 없이, 동일한 register_tool() 인터페이스를 사용하면 된다. OpenAI LLMOpenAI는 tools 매개변수를 사용해 함수 호출 정보를 받는다. McpServer는 등록된 도구 메타데이터를 오픈AI의 JSON 스키마 형식으로 변환하여 요청에 포함한다.그림 5. 오픈AI에서 호출하는 McpServer 등록 및 실행 예 Anthropic API (Tool Use)앤스로픽은 'Tool Use' 기능을 통해 유사한 스키마를 사용한다. McpServer는 Tool 객체를 클로드 API의 tools 매개변수에 맞는 형식으로 변환한다.그림 6. 앤스로픽에서 호출하는 McpServer 등록 및 실행 예 Gemini API (Function Calling)제미나이는 'Function Calling' 기능을 지원한다. McpServer는 Tool 객체를 gemini.GenerativeModel의 tools 매개변수에 전달할 수 있는 FunctionDeclaration 객체로 변환한다.그림 7. Google Gemini API에서 호출하는 McpServer 등록 및 실행 예 주의할 점들LLM과 MCP를 활용하여 서비스를 개발할 때에는 몇 가지 중요한 고려 사항이 있다. 이 점들을 간과하면 예측하지 못한 오류나 보안 문제가 발생할 수 있다. 아래의 주의사항들을 잘 따르면, LLM과 MCP를 활용한 서비스의 안정성, 신뢰성, 그리고 사용자 만족도를 크게 높일 수 있다.명확한 설명: LLM이 사용자의 의도를 정확히 파악하고 올바른 도구를 선택하도록, 각 도구(함수, API)에 대한 설명(description)을 명확하고 구체적으로 작성해야 한다. 이 설명은 단순히 기능 요약에 그치지 않고, 도구의 목적, 사용 시기, 필요한 변수(arguments)와 그 형식, 그리고 예상되는 반환값까지 상세히 포함해야 한다. .보안 및 제어: LLM이 호출할 수 있는 함수는 신뢰할 수 있는 것으로 제한해야 하며, 접근 제어와 인증을 철저히 해야 한다. 특히, 금융 거래나 개인 정보 접근과 관련된 민감한 함수는 더욱 엄격하게 관리해야 한다. 또한, 외부에 공개된 공용 MCP나 API를 사용할 때는 해당 서비스의 보안 정책과 데이터 처리 방식을 충분히 검토해야 하는 등, LLM이 악의적인 프롬프트에 의해 민감한 함수를 호출하거나, 민감한 정보를 외부에 노출하지 않도록 사용자의 입력과 LLM의 출력에 대한 검증 로직을 반드시 구현해야 한다.오류 처리: 외부 API 호출은 네트워크 문제, 서버 오류 등으로 인해 실패할 수 있으므로, 이에 대한 오류 처리 로직을 견고하게 구현하는 것이 매우 중요하다. LLM에게 단순히 "API 호출 실패"라고 전달하는 것만으로는 부족하다. API 응답 코드(예: 404, 500)에 따라 구체적인 오류 메시지를 생성하고, 이를 LLM에게 전달해 사용자에게 더 유용한 피드백을 제공하도록 해야 한다. 예를 들어, "해당 지역의 날씨 정보를 찾을 수 없습니다." 또는 "일시적인 서버 오류가 발생했습니다. 잠시 후 다시 시도해 주세요."와 같은 안내를 LLM이 생성하도록 유도하는 것이 좋다.지연 시간(Latency): MCP는 외부 API 호출을 통해 응답을 생성하므로, 단순 텍스트 생성보다 응답 시간이 길어질 수 있다. 여러 개의 API를 순차적으로 호출하거나, 복잡한 연산을 수행할 경우 지연 시간이 더욱 늘어난다. 따라서 사용자 경험(UX)을 고려하여 적절한 로딩 메시지를 표시하거나, 비동기 처리를 통해 지연 시간을 최소화하는 설계가 필요하다.비용 관리: 외부 API 사용에는 비용이 발생하는 경우가 많다. LLM이 불필요하게 많은 API를 호출하거나, 반복적인 요청을 보내지 않도록 효율적인 도구 선택과 사용 로직을 설계해야 한다. API 호출 횟수나 비용을 모니터링하고, 특정 임계값을 초과할 경우 경고를 보내거나 호출을 제한하는 시스템을 구축하는 것도 중요하다. 맺으며 - 이후 전망MCP는 LLM을 단순한 텍스트 생성기를 넘어, 현실 세계와 상호작용하는 강력한 자동화 에이전트로 진화시키는 핵심 기술이다. 이 기술은 LLM의 언어 이해 능력에 실시간 데이터 연동, 외부 시스템 제어 같은 실제적인 '행동'을 부여한다. 예를 들어, 사용자의 요청을 받아 회사의 재무 데이터를 분석하고, 특정 조건에 따라 보고서를 자동으로 생성하거나, 복잡한 비즈니스 프로세스를 단계적으로 처리하는 것이 가능해진다.이러한 변화는 비즈니스 자동화, 고객 서비스, 데이터 분석 등 다양한 분야에서 LLM의 능력을 극대화하며, 인간과 기계의 상호작용을 훨씬 더 자연스럽고 효율적으로 만든다. 특히, 이전에 사용되던 RAG(Retrieval-Augmented Generation, 검색 증강 생성) 방식이 MCP에 통합되고 있다는 점은 주목할 만하다. RAG는 외부 지식을 검색해 LLM의 답변 정확도를 높이는 기술로, 초기에는 별도의 프레임워크로 구현되었지만, 이제는 MCP의 핵심적인 기능 중 하나로 자연스럽게 흡수되고 있다. MCP는 단순히 API를 호출하는 것을 넘어, RAG처럼 방대한 데이터베이스에서 필요한 정보를 찾아 LLM에 제공하는 기능까지 포괄하며, LLM이 더 넓은 맥락에서 정확한 정보를 활용하도록 돕는다.결국 MCP는 LLM 기반 애플리케이션의 가능성을 무한히 확장하며, 우리가 직면하게 될 다음 세대 소프트웨어의 근간이 될 것이다. 이 기술 트렌드를 이해하고 활용하는 것이 미래의 경쟁력을 확보하는 중요한 열쇠가 될 것이다.

대학 교육 기타mcp기고

인공지능과 추천 시스템 강의 노트 - 2025. 9. 6. (1/16)

들어가며올해부터는 IFC 16, 17층을 서울 파이낸셜 허브에서 쓰고, 이 곳의 여의도 교육장을 빌려서 강의가 진행되고 있다. 작년과 달라진 환경이지만, 이게 여의치 않았을 경우 홍릉에서 수업이 진행될 뻔 했다고 하는데, 대기하는 공간이 조금 불편해 지긴 했지만, 수업 하는 환경은 그대로 진행하게 되었다. 다만 토요일이라 IFC 로 출입하는 에스컬레이터가 동작을 하지 않는 정도의 사소한 불편함은 감수해야 하겠다.토요일 개강에 일정 조율이 복잡한 사정이 있어서 새벽 4시에 인천공항에 도착을 하였고, 성남에 가서 짐 풀고 정신을 차린 후 오전에 다시 여의도까지 이동을 하였다. 수업이 한 시부터이니 끼니 걱정도, 주말 주변의 식당 사정 등도 조사가 필요했고, 토요일 오전의 여의도는, 특히 출근하는 곳으로서 여의도는 꽤나 독특한 느낌이다.변경 기간 전에 신청한 DFMBA 학생은 38명 정도였는데, 변경 기간에 학생 수가 89명까지 늘어났다. 쉽다고 소문이 난 건지, 토요일 오후가 진입 장벽을 오히려 낮춘 건지, 한 번 들어 보자 생각한 학생들이 있는 건지 등의 생각들이 들었지만, 출석 체크를 조금 더 빡빡하게 하고, 중간 과제가 추가되었다는 이야기들로 인원들이 조절되면 한다. 준비한 내용들1주) 강의 소개 - 인공지능과 추천시스템 2025년 2학기1주) 금융 - 시작하며1주) 인공 지능 - 시작하며1주) 추천 시스템 - 시작하며 나눈 이야기들예년처럼 일단 첫번째 주에는 내 이야기를 하는 것으로 시작하였다. 다른 전문 교수님들께서 전하지 못하는 현업에서의 일들에서의 이야기들을 전하는 게 이 과목의 목표이기도 했고, 작년과 같은 마음으로 변경을 해야 하겠다는 학생들이 있으면 그 기회를 주는 게 맞다고도 생각해서 첫 시간은 내가 했던 역할들, 맡았던 과제들, 풀었던 문제들에 대해 큰 틀에서 이야기를 나누었다. 2025년을 맞이하면서 업계에서 일어나는 여전히 새롭고 많은 내용들을 다듬으며 새로 붙여 보고 있다.한 학기 내내 힘 닿는 대로 세 가지 키워드들 ‘금융', ‘인공 지능', ‘추천 시스템' 에 대해 이야기를 나누는데, 워낙 여러 의미로 쓰이는 단어들인지라 그 차이들, 각각의 영역에서 쌓아 올린 그 무게들에 대해 먼저 이야기들을 했다. 특히 세 키워드 중 나날이 더 유명해 지는 인공지능에 쏠리는 관심들을 어떻게 정리해 나갈 것인가, 어떤 이야기들을 나누어야 할 것인가는 여전히 고민 거리이다.마지막으로 꽤 오랜 시간을 할애해서 각 주별 수업의 구성, 중간 과제와 기말 과제 소개, 조교들과 오피스 아워를 통한 조절 등 한 학기를 준비하는 내용들을 나누었다. 링크드인 연락처를 조금 더 자주 나누고 있는데, 서로 불안한 지금과 어떻게든 새로운 일들이 벌어질 내년을 맞이하며 새로운 인연들이 닿기를 바라는 마음이 많다. ps.수업 후에는 스타필드에서 AWS 와 메가존클라우드가 같이 진행하는 해커쏜 결과 발표를 참관,응원,지원하러 다녀 왔다. 코딩 어시스턴트 영역으로 Q developer, 재미난 아이디어들이 playable 데모로 보이는 등 여러 생각들이 드는 조금 긴 하루였다.  

대학 교육 기타

인공지능과 추천 시스템 강의 노트 — 2025. 9. 20. (3/16)

들어가며오늘도 이슬비가 내리는 흐린 가을날이었지만, 여의도에서는 아침부터 핑크빛 달리기 이벤트로 매우 많은 사람들이 북적이고 있었다. 한국에서는 여러 모로 달리기가 유행이라는데, 이제라도 한 수 배워 보아야 겠다는 생각이 드는 토요일 아침 출근길이었다.몇몇 학생들이 중간 과제용 데이터들을 제안하기도 했고, 나도 시간을 들여서 몇몇 데이터들을 같이 들여다 보았다. Kaggle 이 상대적으로 자유롭게 쓰이고 있는 반면 dacon 은 대회에 참여하는 사람들이 아니면 보기 힘든 벽들이 있어서 이전 자료들로 공부하기에 제약이 꽤 있어 보인다. 그리고 분석할 데이터들 자체로는 공통적으로는 필드의 수가 이정도면 충분할까 싶은 데이터들이 상당수여서 의외의 발견을 하기가 꽤 어렵겠다는 생각이다.다만, 다른 한편으로는 밑도 끝도 없는 EDA 이기에, 분석을 실제로 해 보기 전에는 충분한지 부족한지는 실제 리포트를 써 보기 전에 미리 결론내릴 정도는 아니겠어서, 결과가 마음에 들지 않더라도 채점에 나쁜 영향을 주지 않도록 해야 겠다는 생각이다. 과제로서 가이드를 주기로는 회사에서 상사에게 혹은 조직장에게 어떤 결정을 하기에 도움이 될만한 자료를 만드는 것을 목표로 해 달라고 하고 있고, 데이터에서 끄집어 낼 내용들이 없으면 없다고 이야기를 해 달라고 했는데, 이건 다른 면에서 리포트를 만드는 사람들의 시각에서는 쉽지 않은 판단이겠다 싶다. 준비한 내용들3주) 강의 updateAI 강의 — 2강AI 강의 — 3강추천시스템 — 2추천시스템 — 3 나눈 이야기들지난 주에 나온 페이스북의 스마트안경에 대해, 그리고 살짝 실패한 데모 시연에 대해 이야기를 나누었다. 안경 자체는 꽤 잘 나왔는데, 유독 갈은 배를 찾는 AI 서비스와 이를 wifi 탓으로 돌린 시연자, 이후 유사 DDOS 라고 이야기한 CTO 까지.. 기술 회사가 맞나 싶은 우려와 걱정이 들게 한 내용들이었다. 데모장 환경에서 테스트해보고 하는 건 10년전이나 지금이나 다 진지하게 해야 하는 거 아닌가 ? 안 되면 녹화를 하든지…AI 강의 교재에서는 이 책에서 전하고자 하는 지식 혹은 뉴스들이 커버되었다. ChatGPT 즈음부터 시작된 여러 플레이어들의 등장에 관련된 이야기들을 독서 모임 하듯 같이 읽었고, 여기에 2024–2025년에 새로이 추가되는 내용들도 같이 이야기 나누었다. 지금 기준으로는 벌써 충분히 오래 전의 이야기들을 나누는 셈이어서 어떤 주제들을 얼마나 깊이들 다루고 있어야 하는가 등이 챌린지로 남게 되는 거 같다.추천 시스템 교재에서는 프로젝트로서 추천시스템을 만들거나 개선하고 싶을 때 고려할 내용들을 아우르며 이야기 나누었다. 교재에서는 넓은 의미의 추천으로 과제를 구현해 가는 일반적인 방법이 소개되었고, UI/UX를 이야기하면서는 그 안에서 다양한 주제들 — 사용자 중심의 프로젝트 vs 서비스 제공자 중심의 프로젝트 이야기들과 AARRR 이야기들까자 대략적으로 다루었다. 아래는 이 책에서 제일 좋아하는 요약인 “사용자의 목적에 적합한 UI/UX 사례”.이번 주부터 각종 AI 서비스들에게 여러 질문들을 하면서 얼마나 대답들을 잘 하고 있는지 혹은 잘 하게 하기 위해서 어떻게 질문해야 하는지를 양념처럼 해 보고 있는데, 먼저 “달리기 뻐꾸기” 같은 키워드스러운 단어들의 설명은 전통적인 검색 엔진들이 더 잘 하고 있고, 한글 검색 커버리지가 적어 보이는 몇몇 서비스들은 뻐꾸기에 대한 일반적인 설명들을 하곤 한다.수업 내용 중에 25마리 말 문제가 나온다. 25마리 말 중 가장 빠른 3마리를 찾는데 몇 번의 경주가 필요한가? 말들은 매 경주마다 체력의 저하 없이 같은 속도를 내고, 오직 상대적인 순위들만 가지고 가장 빠른 말들을 찾으라.. 는 꽤 유명한 문제인데, 모든 AI 들이 이 문제는 마치 정답을 본 듯이 잘 풀지만, 문제를 7마리로 바꾸었을 경우 여전히 서로 다른 답들을 보여 주고 있다. 참고로 여기서 정답은 한 경주당 2마리를 제외하는 방식으로 하면 2번의 경주면 되는데, 고쳐 주려 해도 몇몇은 매우 대드는 모습을 보여 주곤 한다. 어려운 일을 시킬 때 교차 검증이 필요하거나 뭘 시켜야 할 지 말아야 할 지 고민하는 등 AI 와 더불어 살기에 더 어려운 일들도 분명 생긴다.7마리 말 경주에 대해 잘못 대답한 AI 서비스들. 질문들Q. 작은 서비스를 만들어 운영할 때에도 이미지의 소유와 관련된 저작권 문제가 신경이 쓰이는데, AI 서비스들은 이들 저작권 문제들은 어떻게 해결하려고들 할까 ?A. 이 문제는 양상도 다양하고 해법들도 여럿이라 법정에서 많은 해결과 조정을 비롯해서 다양한 접근이 이루어지고 있다. 미국은 변호사가 엔지니어보다 역시 나은 직업인 듯… 아래는 예제들.구글 검색으로 대변되는 웹의 세상에는 구글이 site 나 contents 의 authority를 존중하는 형태와, 뉴스 사이트들과의 협업 프로그램들로 진행해 왔음.서비스 제공 회사는 어떻게든 출처를 제품 상으로는 표시하려 함.OpenAI 와 Reddit 은 2024년 5월부터 partnership을 맺고 있음. 하지만, 제휴가 되었지만, 이는 Reddit 사용자들의 동의가 있던 게 아니어서 또다른 논란이 되고 있음.뉴욕타임즈는 Anthropic 과 소송에서 1.5B USD 배상을 받았고, OpenAI 와는 진행 중.

대학 교육 기타인공지능추천금융

제어쟁이

임베디드 SW 분야 정리!

임베디드 SW 분야안녕하세요, 제어쟁이입니다. 전공 3~4학년이 읽어도 이해될 수 있도록, 임베디드 SW의 대표 영역을 줄글로 정리했습니다. 같은 임베디드 SW라도 하는 일이 꽤 다릅니다. 인버터/컨버터와 같은 HW를 제어하기위한 SW, BSW/드라이버는 하드웨어를 소프트웨어로 끌어올리며, RTOS는 여러 일을 시간 안에 정리하고, 리눅스는 시스템 전체를 부팅부터 업데이트까지 관리합니다.관심 있는 분야를 하나 정해서 작은 프로젝트부터 꾸준히 만들어보시길 권합니다. 기록을 남기면 본인이 성장하는 속도가 확실히 다릅니다.과장 없이, 현업에서 실제로 하는 일을 기준으로 적었습니다.1) 인버터/컨버터 제어 SW인버터/컨버터 제어 SW는 모터 구동과 전력 변환을 위한 제어 알고리즘을 MCU에 구현하는 일입니다. BLDC/PMSM을 6‑step이나 FOC로 구동하고, 전류·전압·속도 같은 피드백을 읽어 PI 같은 기본 제어기를 돌립니다. 샘플링 타이밍, PWM 데드타임, ADC 트리거, 인터럽트 우선순위처럼 시간 민감한 요소를 맞추는 게 핵심입니다. 과전류·과전압·과열 보호와 같은 안전 로직을 같이 넣고, 기동 시퀀스나 센서리스 보조 알고리즘을 다루는 경우도 많습니다. 오실로스코프와 전류 프로브로 파형을 확인하고, 로그를 보고 튜닝하는 일이 잦습니다. 기본적으로 전력전자 개념, 모터 제어 수학(d‑q 변환, 파크/클라크), 고정소수점 연산, 필터 설계가 밑바탕이 됩니다.2) BSW(Basic Software)BSW는 보드가 켜졌을 때 가장 먼저 실행되는 초기화 코드부터 각종 주변장치 드라이버까지, 하드웨어를 SW에서 사용할 수 있게 만드는 층입니다. 클럭/전원/리셋 설정, GPIO, 타이머, UART·SPI·I2C·CAN, ADC/DMA, WDT 등을 레지스터 수준에서 설정하고 검증합니다. 부트 시퀀스와 인터럽트 벡터, 링커 스크립트로 메모리 배치를 잡는 것도 포함됩니다. AUTOSAR 환경이라면 MCAL 구성과 같은 표준화된 레이어 작업을 합니다. 데이터시트와 레퍼런스 매뉴얼을 정확히 읽고, 디버거(J‑Link, ST‑Link)로 레지스터 상태를 확인하면서 문제를 좁혀가는 능력이 중요합니다. 코드 자체보다 타이밍과 자원 제약을 맞추는 일이 더 어렵게 느껴질 수 있습니다.3) RTOS(실시간 운영체제)RTOS는 여러 작업을 일정 시간 안에 안정적으로 처리하기 위한 운영체제입니다. 센서 읽기, 통신 송신, 로깅처럼 주기가 다른 일을 태스크로 나누고 우선순위를 정해서 스케줄러가 돌게 합니다. 큐·세마포어·뮤텍스로 태스크 간 데이터를 교환하고 동기화합니다. ISR에서 무엇을 하고 무엇을 하지 말아야 하는지 구분하고, 블로킹 호출로 인해 우선순위 역전이나 데드락이 생기지 않게 구조를 잡아야 합니다. 실행시간 측정과 스택 사용량 모니터링으로 오버런을 찾는 것도 기본 업무입니다. FreeRTOS나 Zephyr 같은 RTOS를 쓰지만, 핵심은 어떤 작업을 어떤 주기로 돌리고, 실패했을 때 어떻게 복구할지를 명확히 정의하는 데 있습니다.4) 임베디드 리눅스임베디드 리눅스는 부트로더(U‑Boot), 커널, 디바이스 트리, 루트파일시스템을 구성해서 제품이 부팅되고 동작하도록 만드는 영역입니다. 하드웨어를 커널이 인식하도록 디바이스 트리를 작성하고, 필요한 커널 옵션을 켭니다. 사용자 공간에서는 데몬이나 서비스 프로그램을 만들어 센서 데이터를 수집하거나 네트워크 통신을 처리합니다. 부팅 시간을 줄이기 위해 불필요한 모듈을 빼고, 서비스 시작 순서를 조정하며, 전력 소비를 줄이기 위해 클록과 전원 관리를 설정합니다. OTA 업데이트와 롤백 같은 배포 방법을 설계하는 일도 포함됩니다. Yocto/Buildroot 같은 빌드 시스템을 쓰지만, 목표는 간단합니다. 필요한 기능만 담긴 이미지로 안정적으로 부팅하고, 현장에서 문제를 재현·수정할 수 있는 구조를 갖추는 것입니다.5) 디바이스 드라이버디바이스 드라이버는 센서, 액추에이터, 통신 모듈을 운영체제나 애플리케이션이 사용할 수 있게 추상화하는 코드입니다. 리눅스에서는 커널 모듈 형태로 작성해 /dev나 sysfs를 통해 접근시키고, RTOS나 베어메탈에서는 HAL 위에 드라이버 레이어를 만들어 API를 제공합니다. 인터럽트로 이벤트를 받고, DMA나 링버퍼로 데이터를 손실 없이 흘려보내며, 에러가 났을 때 재시도나 리셋을 어떻게 할지까지 포함합니다. I2C/SPI/UART/CAN 같은 버스 특성과 타이밍을 이해해야 하고, 로직애널라이저나 오실로스코프로 실제 신호를 확인할 줄 알아야 합니다. 드라이버의 품질은 성능뿐 아니라 예외 상황에서 얼마나 안전하게 복구되는지로 평가되는 경우가 많습니다.

임베디드 · IoT임베디드임베디드SW전기전자

Dockerfile 활용해 이미지 직접 만들기

Dockerfile이란?Docker 이미지를 만들게 해주는 파일. FROM : 베이스 이미지 생성FROM은 베이스 이미지를 생성하는 역할을 한다.Docker 컨테이너를 특정 초기 이미지를 기반으로 추가적인 셋팅을 할 수 있다.여기서 예기한 '특정 초기 이미지'가 곧 베이스 이미지이다. 사용법# 문법 FROM [이미지명] FROM [이미지명]:[태그명] [실습] FROM : 베이스 이미지 생성Dockerfile 만들기# JDK 17 FROM openjdk:17-jdkDockerfile을 기반으로 이미지 만들기docker build -t my-jdk17-server .이미지를 기반으로 컨테이너 띄우기docker run -d my-jdk17-server컨테이너 조회하기docker ps # 실행되고 있는 컨테이너가 없다. docker ps -a # 확인해보니 컨테이너가 종료되어 있다. Docker의 컨테이너는 내부적으로 필요한 명령을 다 수행하면 컨테이너가 저절로 종료된다.컨테이너 내부로 들어가서 jdk가 잘 깔렸는지 확인해보기종료된 컨테이너에 들어가서 디버깅하고 싶을때FROM openjdk:17-jdk ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 500초 동안 시스템을 일시정지 시키는 명령어docker build -t my-jdk17-server . # 이미지 빌드 docker run -d my-jdk17-server # 컨테이너 실행 docker ps # 실행 중인 컨테이너 조회 docker exec -it [컨테이너 ID] bash # 컨테이너 접속 java -version # JDK 설치되어 있는 지 확인 COPY : 파일 복사( 이동 )# 문법 COPY [호스트 컴퓨터에 있는 복사할 파일의 경로] [컨테이너에서 파일이 위치할 경로] # 예시 COPY app.txt /app.txt -- 와일드 카드 사용해보기FROM ubuntu COPY *.txt /text-files/ ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 디버깅용 코드 -- .dockerignore 사용해보기.dockerignorereadme.txt DockerfileFROM ubuntu COPY ./ / ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 디버깅용 코드--> readme.txt만 복사가 안된다. ENTRYPOINT : 컨테이너가 시작할때 실행되는 명령어# 문법 ENTRYPOINT [명령문...] # 예시 ENTRYPOINT ["node", "dist/main.js"]예제FROM ubuntu ENTRYPOINT ["/bin/bash", "-c", "echo hello"] docker build -t my-server . docker run -d my-server docker ps -a docker logs [Container ID] [실습] 백엔드 프로젝트(Spring Boot) 를 Docker로 실행시키기AppController@RestController public class AppController { @GetMapping("/") public String home() { return "Hello, World!"; } }DockerfileFROM openjdk:17-jdk COPY build/libs/*SNAPSHOT.jar app.jar ENTRYPOINT ["java", "-jar", "/app.jar"]# Spring Boot 프로젝트 빌드하기 ./gradlew clean build # Dockerfile을 바탕으로 이미지 빌드하기 docker build -t hello-server . # 이미지가 잘 생성됐는 지 확인하기 docker image ls # 생성한 이미지를 컨테이너로 실행시켜보기 docker run -d -p 8080:8080 hello-server # 컨테이너 잘 실행되고 있는 지 확인하기 docker ps RUN: 이미지를 생성하는 과정에서 사용할 명령문 실행RUN 은 이미지 생성 과정에서 명령어를 실행시켜야 할 때 사용한다.# 문법 RUN [명령문] # 예시 RUN npm install RUN 과 ENTRYPOINTRUN은 '이미지 생성 과정'에서 필요한 명령어를 실행시킬 때 사용하고,ENTRYPOINT는 생성된 이미지를 기반으로 컨테이너를 생성한 직후에 명령어를 실행시킬 때 사용한다. [예제]미니 컴퓨터 환경이 ubuntu로 구성되었으면 좋겠고 git이 깔려있으면 좋겠다고 가정하자. 이런 환경을 구성하기 위해 Dockerfile 을 활용해 ubuntu, git이 깔려있는 이미지를 만들면 된다. DockerfileFROM ubuntu RUN apt update && apt install -y git ENTRYPOINT ["/bin/bash", "-c", "sleep 500"]이미지 빌드 및 컨테이너 실행docker build -t my-server . docker run -d my-server docker exec -it [Container ID] bash git -v # 컨테이너 내에 git이 잘 설치됐는 지 확인 WORKDIR : 작업 디렉토리를 지정작업 디렉토리를 지정해주는 이유는 컨테이너 내부의 폴더를 깔끔하게 관리하기 위해서이며컨테이너도 미니 컴퓨터와 같기 때문에 Dockerfile을 통해 생성되는 파일들을 특정 폴더에 정리해두는 것이 추후에 관리가 쉽다.만약에 WORKDIR을 쓰지 않으면 내부에 존재하는 기존 파일들과 뒤섞여버린다. # 문법 WORKDIR [작업 디렉토리로 사용할 절대 경로] # 예시 WORKDIR /usr/src/app 예제app.txt, src, config.json 파일 만들기Dockerfile 만들어서 이미지 생성 및 컨테이너 실행 - - WORKDIR 을 안 썼을 때 파일이 어떻게 구성되는 지 먼저 확인 DockerfileFROM ubuntu COPY ./ ./ ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] # 디버깅용 코드 docker build -t my-server . docker run -d my-server docker exec -it [Container ID] bash ls -- WORKDIR 을 썼을 때 파일이 어떻게 구성되는 지 확인 DockerfileFROM ubuntu WORKDIR /my-dir COPY ./ ./ ENTRYPOINT ["/bin/bash", "-c", "sleep 500"] docker build -t my-server . docker run -d my-server docker exec -it [Container ID] bash ls EXPOSE : 컨테이너 내부에서 사용 중인 포트를 문서화EXPOSE 는 컨테이너 내부에서 어떤 포트에 프로그램이 실행되는 지를 문서화하는 역할만 한다. # 문법 EXPOSE [포트 번호] # 예시 EXPOSE 3000 [실습]백엔드 프로젝트(Next.js)를 Docker로 실행Next.js 프로젝트 만들기# Nest CLI 설치 npm i -g @nestjs/cli # nest new {프로젝트명} nest new my-serverDockerfile 작성FROM node WORKDIR /app COPY . . RUN npm install RUN npm run build EXPOSE 3000 ENTRYPOINT [ "node", "dist/main.js" ].dockerignore 작성node_modulesDockerfile을 바탕으로 이미지 빌드 및 컨테이너 실행docker build -t my-server . docker image ls docker run -d -p 3000:3000 my-server docker ps 웹 프론트엔드 프로젝트(Next.js)를 Docker로 배포하기Next.js 프로젝트 만들기npx create-next-app@latestDockerfile 작성하기FROM node:20-alpine WORKDIR /app COPY . . RUN npm install RUN npm run build EXPOSE 3000 ENTRYPOINT [ "npm", "run", "start" ].dockerignore 작성node_modulesDockerfile로 이미지 빌드 및 컨테이너 실행docker build -t my-web-server . docker image ls docker run -d -p 80:3000 my-web-server docker ps 웹 프론트엔드 프로젝트(HTML, css, Nginx)를 Docker로 배포하기HTML, css 파일 만들기index.html<!DOCTYPE html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="style.css"> </head> <body> <h1>My Web Page</h1> </body> </html>주의) Nginx의 기본 설정에 의하면 메인 페이지(첫 페이지)의 파일명을 index.html 이라고 지어야 한다.style.css* { color: blue; }Dockerfile 작성FROM nginx COPY ./ /usr/share/nginx/htmlDockerfile로 이미지 빌드 및 컨테이너 실행docker build -t my-web-server . docker image ls docker run -d -p 80:80 my-web-server docker ps  

neo

PPT는 단순한 도구가 아니라, 당신의 상상을 실현하는 무대입니다.

세상은 빠르게 변하지만, 콘텐츠의 본질은 변하지 않습니다.‘전달하고 싶은 메시지를 시각적으로 표현하는 것.’그 핵심에 있는 도구가 바로 파워포인트(PowerPoint)입니다.많은 사람들에게 PPT는 여전히 ‘발표용 슬라이드’의 도구로만 인식됩니다.하지만 지금의 PPT는 더 이상 단순한 프레젠테이션 툴이 아닙니다.영상, 인쇄, 웹, 브랜딩 콘텐츠까지 —피피티 하나로 모든 콘텐츠를 제작할 수 있는 시대가 왔습니다. 🎨 PPT는 가장 강력한 ‘콘텐츠 허브’다•       유튜브 영상 오프닝? 👉 애니메이션과 자막, 배경음악까지 PPT로 완성•       쇼핑몰 상세페이지? 👉 세로로 길게 디자인, 이미지/텍스트 배치, GIF 모션까지 한 번에•       인스타 릴스나 숏폼? 👉 세로형 슬라이드에서 컷 편집으로 완벽한 디자인 숏폼 제작•       리플렛·포스터? 👉 디자인 및 인쇄용 고해상도 PDF로 내보내기•       제안서와 기업 홍보자료? 👉 디자인 일관성과 브랜딩 유지까지 완벽한마디로,PPT는 디자이너와 영상편집자, 마케터를 모두 품은 통합 제작 스튜디오입니다. ⚡ ‘툴의 한계’가 아니라 ‘활용의 한계’다많은 분들이 이렇게 말합니다.“그건 PPT로 못해요.”하지만 제가 매일 보여드리는 건 그 반대입니다.“그것도 PPT로 할 수 있어요.”그 차이는 ‘툴의 한계’가 아니라 ‘활용의 한계’에서 생깁니다.PPT는 생각보다 훨씬 강력합니다.모션 그래픽, 키프레임 애니메이션, 비디오 합성, 반투명 레이어, 색보정, 도형 마스킹 —이 모든 기능이 이미 안에 들어있습니다.이제는 ‘어떤 툴을 쓰느냐’보다 ‘어떻게 활용하느냐’가 승부를 가릅니다. 🧭 NEO(이희정)이 제시하는 방향제가 말하는 ‘PPT 하나로 모든 콘텐츠를 접수하기’는 단순한 슬로건이 아닙니다.이건 콘텐츠 제작의 패러다임을 바꾸는 새로운 관점이에요.•      PPT로 영상 제작까지 확장•      PPT로 브랜드 무드를 표현•      PPT로 교육, 마케팅, 제안서를 통합 관리•      PPT로 1인 크리에이터의 모든 콘텐츠 제작즉, 누구나 크리에이터가 될 수 있는 시대의 실무형 해답이 바로 PPT입니다. 🚀 당신이 PPT 하나로 세상을 접수할 때지금 이 순간에도 수많은 콘텐츠가 만들어지고 사라집니다.하지만 진짜 힘을 가진 크리에이터는 ‘툴’을 아는 사람이 아니라‘표현의 언어’를 아는 사람입니다.PPT는 그 언어를 가장 직관적으로 말할 수 있는 도구입니다.이제 당신의 아이디어, 브랜드, 비전 —모두 PPT 하나로 세상을 향해 표현하세요.NEO 이희정 | 네오프레젠테이션010 2401 7329 PPT는 단순한 도구가 아니라, 당신의 상상을 실현하는 무대입니다. 

커리어 · 자기계발 기타창업영상제작디자인홍보AIppt파워포인트제안서상세페이지

neo 10일 전

[실습] Docker로 Mysql 실행시켜보기

Mysql 이미지를 바탕으로 컨테이너 실행 docker run -e MYSQL_ROOT_PASSWORD=password123 -p 3306:3306 -d mysql컨테이너에 들어가 환경변수 설정이 잘 되었는지 확인docker exec -it [MYSQL 컨테이너 ID] bash echo $MYSQL_ROOT_PASSWORD # MYSQL_ROOT_PASSWORD 라는 환경변수 값 출력 export # 설정되어있는 모든 환경변수 출력 Dbeaver로 연결 확인하기 window 환경의 경우 useSSL=false, allowPublicKeyRetrieval=true 설정해야 연결된다 Docker 볼륨(Volume)을 활용해 MySQL 컨테이너 띄우기MySQL 컨테이너 띄우기Docker Volumecd /Users/LeeHwiro mkdir docker-mysql # MySQL 데이터를 저장하고 싶은 폴더 만들기 # docker -run -e MYSQL_ROOT_PASSWORD=password123 -p 3306:3306 -v {호스트의 절대경로}/mysql-data:/var/lib/mysql -d mysql docker -run -e MYSQL_ROOT_PASSWORD=password123 -p 3306:3306 -v "C:/Users/LeeHwiro/docker-mysql/mysql-data:/var/lib/mysql" -d mysql MySQL 컨테이너 삭제하고 다시 띄워보기#컨테이너 종료 docker stop [MYSQL 컨테이너 ID] docker rm [MYSQL 컨테이너 ID] # 비밀번호 바꿔서 컨테이너 생성 docker -run -e MYSQL_ROOT_PASSWORD=pwd123 -p 3306:3306 -v "C:/Users/LeeHwiro/docker-mysql/mysql-data:/var/lib/mysql" -d mysql docker exec -it [MySQL 컨테이너 ID] bash mysql -u root -p # 접속이 안됨 해결 방법 : 기존 Volume 파일을 제거 후 다시 컨테이너를 생성시킨다. Docker Volume을 활용해 postGresql 띄우기docker run -e POSTGRES_PASSWORD=password123 -p 5432:5432 -v "C:/Users/LeeHwiro/docker-postgresql/postgresql_data:/var/lib/postgresql" -d postgres Docker Volume을 활용해 mongoDB 띄우기docker run -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=password123 -p 27017:27017 -v "C:\Users\LeeHwiro\docker-mongodb/mongodb_data:/data/db" -d mongo       

Depth

인프런 워밍업 클럽 스터디 4기 - CS 전공지식 > 3주차 발자국

◼만들면서 쉽게 배우는 컴퓨터 구조Section8) 제어 장치가 없는 컴퓨터 제어 장치가 없는 컴퓨터명령어 실행시 MI, RI, RO, II, IO, AI, AO, BI, BO, EO, SU 등의 제어 신호를 외부에서 직접 활성화해주는 방식예시RAM의 15번지 값 5를 레지스터 A에 저장 Section9) CPU 만들기: 제어 장치 (Control Unit) 1바이트 기계 명령어상위 4비트(Opcode) + 하위 4비트(주소 또는 값)로 구성종류 (Opcode)NOP (0000), LOADA(0001), ADD(0010), SUB(0011), STOREA(0100), LOADI(0101), JMP(0110), JMPC(0111), JMPZ(1000), OUT(1110), HLT(1111) Program Counter (PC)다음에 실행할 명령어의 주소를 저장하는 레지스터보통 클럭 신호에 맞춰 1씩 증가하며 명령어를 순차적으로 실행하지만, 조건에 따라 특정 주소로 점프(Jump) 하기도 한다. 스텝 카운터(Step Counter)시스템 내에서 현재 동작이 몇 번째 단계(스텝)인지 추적하는 카운터어떤 동작이 여러 단계(Step 0, Step 1, Step 2, ...)로 나뉘어 있을 때, 지금 어느 단계인지 기억하고 다음 단계로 이동하기 위해 사용되는 카운터 제어장치 (Control Unit)NOP, LOADA, ADD, SUB, STOREA, LOADI, JMP, JMPC, JMPZ, OUT, HLT, 출력 레지스터로 구성  Section10) 기계어와 어셈블리 어셈블리어어셈블리어는 기계어(Machine Code)를 사람이 조금 더 이해하기 쉬운 형태로 바꾼 언어예시  어셈블러어셈블리어로 작성된 코드를 컴퓨터가 실행할 수 있는 기계어(이진 코드)로 변환해주는 프로그램   ◼ 그림으로 쉽게 배우는 자료구조와 알고리즘Section7) 트라이와 자동완성 트라이(Trie)문자열을 저장하고 검색하는 데 특화된 트리 자료구조루트부터 리프까지의 경로가 하나의 단어효율적인 자동완성, 사전 검색, 접두사 검색에 사용됨사용 예: 검색창 자동완성, 입력기 등  Section8) 그래프 그래프정점(Vertex)과 간선(Edge)으로 이루어진 자료구조방향 그래프: 간선에 방향이 있음 (ex: A → B)무방향 그래프: 간선에 방향 없음 (ex: A—B)탐색 방법DFS : 한 방향으로 계속 깊이 들어가며 탐색하는 방식 BFS : 가까운 정점부터 차례대로 탐색하는 방식표현 방식인접 행렬: 2차원 배열로 표현인접 리스트: 각 정점이 연결된 정점을 리스트로 표현    Section9) 가중 그래프각 간선(Edge)에 숫자 값(가중치, 비용, 거리 등)이 부여된 그래프예) 도시간 거리 그래프  🗒회고지난 주차에 배웠던 RAM, Register, ALU에 이어 Control Unit도 구현해 보았는데, 난이도가 점점 높아지고 있는 것을 실감했다. 수동으로 제어 신호(MI, RO, AO 등)를 켜서 RAM에서 레지스터로 값을 이동시키는 과정도 경험해 볼수 있었고, 기계어를 사람이 이해하기 쉽게 만든 어셈블리어와, 이를 기계어로 변환하는 어셈블러의 역할까지 학습해 봄으로써 하드웨어 수준의 명령어 실행 과정을 이해할 수 있었다. 🏷출처https://inf.run/y1hhdhttps://inf.run/7mNZ2https://inf.run/uHJ1a 

cs발자국4기

Depth

인프런 워밍업 클럽 스터디 4기 - CS 전공지식 > 2주차 발자국

◼만들면서 쉽게 배우는 컴퓨터 구조Section5) 컴퓨터의 기초가 되는 하드웨어 만들기 MUX (Multiplexer, 멀티플렉서)여러 입력 중 하나를 선택하여 출력으로 내보내는 장치데이터 선택기라고도 불림  1비트 2입력 MUXSelection 입력 값에 따라 A입력 또는 B입력을 선택하여 출력Selection이 0 → 입력 A 선택Selection이 1 → 입력 B 선택   8비트 4입력 MUX4개의 8비트 입력 중 하나를 선택하여 출력 2비트의 Selection 입력 사용 (00₂ ~ 11₂)00₂(0) → IN_0 출력01₂(1) → IN_1 출력10₂(2) → IN_2 출력11₂(3) → IN_3 출력 8비트 8입력 MUX8개의 8비트 입력 중 하나를 선택하여 출력3비트의 Selection 입력 사용 (000₂ ~ 111₂)000₂(0) → IN_0 출력001₂(1) → IN_1 출력010₂(2) → IN_2 출력011₂(3) → IN_3 출력100₂(4) → IN_4 출력101₂(5) → IN_5 출력110₂(6) → IN_6 출력111₂(7) → IN_7 출력 디코더 (Decoder)n비트 입력을 받아 2ⁿ개의 출력 중 하나만 활성화 시키는 장치Enable 입력을 통해 디코더 회로 전체의 작동 여부를 제어Enable이 0이면 모든 출력은 0 (비활성화 상태)Enable이 1일 때에는 입력값에 따라 하나의 출력을 활성화 4비트 디코더 (Decoder)4비트 입력 → 2^4 = 16개 출력 중 하나만 활성화RAM 구현시 활용 컨트롤 버퍼제어 신호에 따라 데이터를 흐르게 하거나 차단하는 버퍼  Section6) CPU 만들기: 산술논리연산장치 (ALU) 폰 노이만 구조 컴퓨터입출력 장치 (I/O Device)중앙 처리 장치 (CPU)제어 유닛 (Control Unit)산술 논리 연산 장치 (ALU)메모리 (RAM) → 위 세 가지 구성 요소로 컴퓨터가 구성됨 반가산기 (Half Adder)두 개의 1비트 입력을 더하여, 합(Sum)과 자리올림(Carry)을 계산하는 조합 논리 회로특징입력: A, B (1비트씩)출력: Sum[XOR로 구현], Carry[AND로 구현] (각 1비트)자리올림(Carry-In)을 처리하지 못함 → 이전 자리의 올림을 고려하지 않음 → '반쪽짜리 가산기’ (반가산기)라 불림 진리표 전가산기 (Full Adder)세 개의 1비트 입력(두 입력 + 이전 자리의 자리올림)을 더하여, 합(Sum)과 자리올림(Carry-Out)을 계산하는 조합 논리 회로.특징:입력: A, B, Carry-In (1비트씩)출력: Sum[반가산기 2개로 구현], Carry-Out[반가산기 2개+OR로 구현] (각 1비트)자리올림을 연속적으로 처리 가능진리표  산술 논리 연산 장치 (ALU: Arithmetic Logic Unit)컴퓨터의 핵심 연산 장치로, 산술 연산과 논리 연산을 수행한다.산술 연산 : 덧셈, 뺄셈, 증가, 감소, 곱셈, 나눗셈논리 연산 : AND, OR, NOT, XOR, NAND, NOR 등비교 연산 : ==, >, <, >=, <=CPU 내부에 포함되어 있으며, 프로세서가 수행하는 계산의 대부분은 이 ALU를 통해 처리음수 표현시 2의 보수 사용  Section7) 메모리 만들기조합 논리 회로 (Combinational Logic Circuit)출력이 현재 입력에만 의존하는 회로상태를 기억하지 않음 (메모리 없음)예시: AND, OR, NOT, Half Adder, Full Adder, Multiplexer, Decoder, ALU 순차 논리 회로 (Sequential Logic Circuit)이전 입력에 대한 출력이 다시 입력으로 들어가는 회로이전 상태를 기억예시: SR Latch, D Latch, JK Latch, Flip-Flop, Register, RAM SR LatchSet(S)과 Reset(R) 입력을 갖는 기본 기억 회로특정 조건에서 출력 Q는 이전 상태를 유지Gated SR Latch는 Enable 신호가 1일 때만 동작 D LatchS, R을 하나의 입력 D로 통합한 형태Enable이 1일 때 D의 값을 Q에 저장  JK LatchSR Latch의 단점 (S=R=1일 때 불안정)을 개선J = Set, K = Reset 의미J=K=1이면 출력이 반전 (Toggle 동작)내부 딜레이가 있어 안정적인 동작 위해 Clock 필요 클럭과 플립플롭Clock : enable을 0과 1로 반복해서 바꿔주는 신호 (Hz 단위로 동작)Trigger클럭 신호 중에서 "입력을 출력으로 반영하는 순간"을 결정하는 방식종류Level Trigger: High/Low 상태에서 작동 → D LatchEdge Trigger: Rising/Falling 순간에 작동 → Flip-Flop  레지스터8비트 저장 장치 여러 개의 Latch 또는 Flip-Flop으로 구성Latch 또는 Flip-Flop : 1비트 저장장치   RAM (Random Access Memory)주소를 통해 원하는 데이터에 접근 가능한 메모리 실행 중의 데이터와 상태를 임시로 저장  Mission2)https://inf.run/iWGzi   ◼ 그림으로 쉽게 배우는 자료구조와 알고리즘Section5) Red-Black 트리 Red-Black 트리이진 탐색 트리의 일종으로,데이터가 삽입되거나 삭제될때 트리의 균형을 자동으로 유지하는 균형 이진트리이다.트리의 높이를 제한해 모든 연산의 최악의 시간복잡도를 O(log n)으로 유지하는 것이 목적조건모든 노드는 빨간색 혹은 검정색루트 노드는 검은색모든 리프 노드는 검은색빨간색 노드의 자식은 검은색모든 리프 노드에서 Black Depth는 같다  Section6) 우선순위 큐와 힙 우선순위 큐데이터의 삽입 순서와는 상관 없이 우선순위가 높은 데이터가 먼저 나오는 큐 힙완전 이진 트리 형태의 자료구조로, 부모 노드가 자식보다 크면 최대 힙, 작으면 최소 힙을 의미   🗒회고MUX, 반가산기, 전가산기, 디코더, ALU 등 조합 논리 회로를 직접 구현해보며 각 장치의 동작 원리와 회로 구성 방식을 직관적으로 이해할 수 있었다.또한 Register와 RAM 같은 순차 논리 회로를 만들며, 클럭과 Enable, 기억 소자의 역할, 메모리 동작 방식도 자연스럽게 배울수 있었다.단순 이론을 넘어서 실제 회로 구조를 만들어 시각화 해보는 경험을 통해 컴퓨터 구조애 대한 이해력이 높아지고 있는것 같다.  🏷출처https://inf.run/y1hhdhttps://inf.run/7mNZ2https://inf.run/uHJ1ahttps://velog.io/@kku64r/rbtreehttps://suyeon96.tistory.com/31     

cs발자국4기

Depth

인프런 워밍업 클럽 스터디 4기 - CS 전공지식 > 컴퓨터 구조 1주차 미션

◼컴퓨터 구조 1. 4입력 AND, OR, NAND, NOR, XOR 연산의 진리표를 작성해보세요.AND : 모든 입력값이 1일때만 결과는 1OR : 입력값중 하나라도 1이라면 결과는 1NAND : AND의 반대, 모든 입력이 1일 때만 0, 나머지는 1NOR : OR의 반대, 모든 입력이 0일 때만 1, 나머지는 0XOR : 입력값 중 1의 개수가 홀수이면 1, 짝수이면 0  2. 다음 불 방정식들을 여러 방법을 이용해 간략화 해보세요.A( (BB)’+ 0A) + (CC)' = (AB’) +C(B’B’) + (AD’ + (CA)’)D = B’ + (DC’) + (DA’)(A’B) + B(B1 + BC) = B B’(1C + BD) + DB = (B’C) + (DB)   3. 다음 2진수를 10진수로 변환해보세요.1101112^5 + 2^4 + 0 + 2^2 + 2^1 + 2^032 + 16 + 4 + 2 + 155100000012^7 + 1 = 129111111000002^10 + 2^9 + 2^8 + 2^7 + 2^6 + 2^5 = 20161010102^5 + 2^3 + 2^5 = 32 + 8 + 2 = 42  4. 다음 10진수를 2진수로 변환해보세요.10 = 1010₂2 |10 2 | 5 - 0 2 | 2 - 1 | 1 - 0 27 = 11011₂2 |27 2 |13 - 1 2 | 6 - 1 2 | 3 - 0 | 1 - 1 86 = 1010110₂2 |86 2 |43 - 0 2 |21 - 1 2 |10 - 1 2 | 5 - 0 2 | 2 - 1 | 1 - 0 516 = 10000001002 |516 2 |258 - 0 2 |129 - 0 2 | 64 - 1 2 | 32 - 0 2 | 16 - 0 2 | 8 - 0 2 | 4 - 0 2 | 2 - 0 | 1 - 0  5. 다음 불 방정식을 logisim을 이용해 회로를 만들어보세요.(B’C) + (DB)B’C : NOT(B) AND C → AND 연산DB : D AND B → AND 연산전체: (B’C) + (DB) → OR 연산(AB’) +C AB’ : A AND NOT(B) → AND 연산+C : 결과와 C를 OR 연산 B’ + (DC’) + (DA’)B’ : NOT(B) → NOTDC’ : D AND NOT(C) → ANDDA’ : D AND NOT(A) → AND전체는 OR 연산         

CS미션4기

Team Gemini

✈️ 대학생 주목! 제미나이 1년 무료 가입하고 제주도 가는 법🍊

Google AI pro for students 가입하고 제주도 가자 ! ✈ 대학(원)생 인증만 하면 Google AI pro 가 1년간 무료 !!지금 바로 첨부된 링크로 가입하고 가입 완료된 화면을 캡처해 인증만 하면,  추첨을 통해 친구 3명과 함께 떠날 수 있는 제주도 항공권부터 ✈애슐리, 배달의민족 상품권까지 푸짐한 선물이 쏟아집니다! ✨ ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ🚀 이벤트 참여 방법1. @teamgemini_ajou 계정 팔로우하기 (필수!) * 하단 ‘Google AI pro for students 가입 링크’로 Google AI pro 가입하기 (⚠ 반드시 이 링크로 가입해야 참여로 인정됩니다!)2. 가입 완료 화면 캡처 하기 3. 하단 링크의 ‘가입 인증 이벤트 폼‘ 작성하면 끝!🌟 지금 바로 아래 링크에서 참여하세요!(반드시 해당 링크로 가입해야 이벤트 참여 가능)➡ 가입 링크: https://gemini.google/students?hl=ko&utm_source=teamgemini&utm_medium=referral&utm_campaign=students_influencer_gemini-students-kr-ajou➡ 가입 인증 이벤트 폼: https://forms.gle/RzYR9UsVMcM75CsA6ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ🏆 1등 ’제주도 항공권‘ 당첨 주의사항!*이벤트 참여 폼에 내 추천으로 가입한 친구의 이름을 모두 적어주세요. (일치 여부 확인 예정)*추천한 친구가 1명 이상일 때 1등 당첨 자격이 주어지며, 많이 추천할수록 당첨 확률이 올라갑니다! 🎁 경품 안내 1등 (2명): 친구들과 함께! 제주도 편도 항공권 4장 2등 (5명): 애슐리퀸즈 주말 2인 식사권 3등 (7명): 배달의민족 30,000원 상품권 🗓 이벤트 기간 * 참여 기간: 2025년 9월 12일 (금) ~ 10월 6일 (월) * 당첨 발표: 10월 10일 (금) 본 계정 스토리 및 개별 연락

AI 업무 활용구글제미나이AIGoogleGemini대학생나노바나나AI영상Veo3

채널톡 아이콘